summaryrefslogtreecommitdiff
path: root/Core
diff options
context:
space:
mode:
authorraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
committerraywu <raywu0301@gmail.com>2018-06-15 00:00:50 +0800
commitb7c51c9cf4864df6aabb99a1ae843becd577237c (patch)
treeeebe9b0d0ca03062955223097e57da84dd618b9a /Core
downloadzprj-b7c51c9cf4864df6aabb99a1ae843becd577237c.tar.xz
init. 1AQQW051HEADmaster
Diffstat (limited to 'Core')
-rw-r--r--Core/CORE_DXE/AmiDxeInit.c427
-rw-r--r--Core/CORE_DXE/BDS.c1607
-rw-r--r--Core/CORE_DXE/Bds.unibin0 -> 5908 bytes
-rw-r--r--Core/CORE_DXE/BdsBoard.c1074
-rw-r--r--Core/CORE_DXE/BootOptions.c2842
-rw-r--r--Core/CORE_DXE/CORE_DXE.cif13
-rw-r--r--Core/CORE_DXE/CORE_DXE.mak189
-rw-r--r--Core/CORE_DXE/CORE_DXE.sdl1169
-rw-r--r--Core/CORE_DXE/CORE_DXESrc.cif75
-rw-r--r--Core/CORE_DXE/CORE_DXESrc.mak155
-rw-r--r--Core/CORE_DXE/CORE_DXESrc.sdl57
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplit.c2387
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplit.h553
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplitter.cif12
-rw-r--r--Core/CORE_DXE/ConSplitter/ConSplitter.sdl26
-rw-r--r--Core/CORE_DXE/ConSplitter/In.c1159
-rw-r--r--Core/CORE_DXE/ConSplitter/Out.c1323
-rw-r--r--Core/CORE_DXE/CoreSectionExtraction.c1367
-rw-r--r--Core/CORE_DXE/DataHub.c681
-rw-r--r--Core/CORE_DXE/DebugImageInfo.c262
-rw-r--r--Core/CORE_DXE/DebugImageInfo.h129
-rw-r--r--Core/CORE_DXE/DebugMask.c399
-rw-r--r--Core/CORE_DXE/DebugMask.h122
-rw-r--r--Core/CORE_DXE/DevicePath.h470
-rw-r--r--Core/CORE_DXE/DevicePathFromText.c3310
-rw-r--r--Core/CORE_DXE/DevicePathToText.c2083
-rw-r--r--Core/CORE_DXE/DiskIo.c978
-rw-r--r--Core/CORE_DXE/Dispatcher.c1351
-rw-r--r--Core/CORE_DXE/DriverSupport.c931
-rw-r--r--Core/CORE_DXE/DxeCore.h2542
-rw-r--r--Core/CORE_DXE/DxeMain.c1065
-rw-r--r--Core/CORE_DXE/DxePerf.c813
-rw-r--r--Core/CORE_DXE/DxeProtocolNotify.c334
-rw-r--r--Core/CORE_DXE/EfiPerf.h99
-rw-r--r--Core/CORE_DXE/Ffs.c266
-rw-r--r--Core/CORE_DXE/FrameworkHii/FrameworkHii.cif10
-rw-r--r--Core/CORE_DXE/FrameworkHii/FrameworkHii.sdl15
-rw-r--r--Core/CORE_DXE/FrameworkHii/FrameworkHiiUtils.c369
-rw-r--r--Core/CORE_DXE/FrameworkHii/HIIDB.c3511
-rw-r--r--Core/CORE_DXE/FwVol.c589
-rw-r--r--Core/CORE_DXE/FwVolAttrib.c244
-rw-r--r--Core/CORE_DXE/FwVolBlock.c790
-rw-r--r--Core/CORE_DXE/FwVolBlock.h314
-rw-r--r--Core/CORE_DXE/FwVolDriver.h772
-rw-r--r--Core/CORE_DXE/FwVolRead.c993
-rw-r--r--Core/CORE_DXE/FwVolWrite.c102
-rw-r--r--Core/CORE_DXE/GC.c2249
-rw-r--r--Core/CORE_DXE/GenericSio.c3645
-rw-r--r--Core/CORE_DXE/Image.c1710
-rw-r--r--Core/CORE_DXE/Image.h400
-rw-r--r--Core/CORE_DXE/ImageFile.c639
-rw-r--r--Core/CORE_DXE/InstallConfigurationTable.c230
-rw-r--r--Core/CORE_DXE/Library.c811
-rw-r--r--Core/CORE_DXE/Library.h531
-rw-r--r--Core/CORE_DXE/LinkedList.h1
-rw-r--r--Core/CORE_DXE/Notify.c344
-rw-r--r--Core/CORE_DXE/Page.c1685
-rw-r--r--Core/CORE_DXE/Partition/ElTorito.c470
-rw-r--r--Core/CORE_DXE/Partition/ElTorito.h264
-rw-r--r--Core/CORE_DXE/Partition/Gpt.c606
-rw-r--r--Core/CORE_DXE/Partition/Gpt.h161
-rw-r--r--Core/CORE_DXE/Partition/Mbr.c407
-rw-r--r--Core/CORE_DXE/Partition/Mbr.h171
-rw-r--r--Core/CORE_DXE/Partition/Partition.c1006
-rw-r--r--Core/CORE_DXE/Partition/Partition.cif16
-rw-r--r--Core/CORE_DXE/Partition/Partition.h188
-rw-r--r--Core/CORE_DXE/Partition/Partition.sdl4
-rw-r--r--Core/CORE_DXE/SetWatchdogTimer.c84
-rw-r--r--Core/CORE_DXE/Stall.c79
-rw-r--r--Core/CORE_DXE/USFontPack.c315
-rw-r--r--Core/CORE_DXE/UefiHii/HiAccessConfig.c322
-rw-r--r--Core/CORE_DXE/UefiHii/Hii.chmbin0 -> 60152 bytes
-rw-r--r--Core/CORE_DXE/UefiHii/HiiConfig.c1263
-rw-r--r--Core/CORE_DXE/UefiHii/HiiDatabase.c1814
-rw-r--r--Core/CORE_DXE/UefiHii/HiiFont.c1035
-rw-r--r--Core/CORE_DXE/UefiHii/HiiFontEx.c1332
-rw-r--r--Core/CORE_DXE/UefiHii/HiiPrivate.h885
-rw-r--r--Core/CORE_DXE/UefiHii/HiiString.c1609
-rw-r--r--Core/CORE_DXE/UefiHii/UefiHii.cif18
-rw-r--r--Core/CORE_DXE/UefiHii/UefiHii.sdl15
-rw-r--r--Core/CORE_DXE/UefiHii/UefiHiiUtils.c750
-rw-r--r--Core/CORE_DXE/UefiHii/hii21ExportConfig.c1143
-rw-r--r--Core/CORE_DXE/UnicodeCollation.c637
-rw-r--r--Core/CORE_DXE/dependency.c451
-rw-r--r--Core/CORE_DXE/event.c867
-rw-r--r--Core/CORE_DXE/exec.h209
-rw-r--r--Core/CORE_DXE/execdata.c50
-rw-r--r--Core/CORE_DXE/gcd.c2472
-rw-r--r--Core/CORE_DXE/gcd.h54
-rw-r--r--Core/CORE_DXE/hand.h339
-rw-r--r--Core/CORE_DXE/handle.c1703
-rw-r--r--Core/CORE_DXE/hob.c530
-rw-r--r--Core/CORE_DXE/imem.h214
-rw-r--r--Core/CORE_DXE/locate.c777
-rw-r--r--Core/CORE_DXE/memdata.c41
-rw-r--r--Core/CORE_DXE/pool.c620
-rw-r--r--Core/CORE_DXE/timer.c386
-rw-r--r--Core/CORE_DXE/tpl.c198
-rw-r--r--Core/CORE_PEI/AmiPeiInit.c887
-rw-r--r--Core/CORE_PEI/CORE_PEI.cif9
-rw-r--r--Core/CORE_PEI/CORE_PEI.mak163
-rw-r--r--Core/CORE_PEI/CORE_PEI.sdl97
-rw-r--r--Core/CORE_PEI/CORE_PEISrc.cif17
-rw-r--r--Core/CORE_PEI/CORE_PEISrc.mak103
-rw-r--r--Core/CORE_PEI/CORE_PEISrc.sdl33
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c108
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif21
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c604
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c488
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c198
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c341
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c440
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h1260
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c405
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c673
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c77
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c194
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c102
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c268
-rw-r--r--Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h38
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/BootMode.c107
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif21
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c689
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/FwVol.c782
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Hob.c191
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Image.c932
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c392
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/PeiCore.h1416
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/PeiMain.c404
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Ppi.c687
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Reset.c76
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/Security.c192
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/StatusCode.c94
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/dependency.c265
-rw-r--r--Core/CORE_PEI/CORE_PEI_PI/dependency.h38
-rw-r--r--Core/CORE_PEI/CpuIo.c1158
-rw-r--r--Core/CORE_PEI/DxeIpl.c838
-rw-r--r--Core/CORE_PEI/PciCfg.c491
-rw-r--r--Core/CORE_PEI/PeiPerf.c30
-rw-r--r--Core/CPU/CPU.h443
-rw-r--r--Core/CPU/CPUCore.cif30
-rw-r--r--Core/CPU/CPUCspLib.h333
-rw-r--r--Core/CPU/CpuCspLib.c2461
-rw-r--r--Core/CPU/CpuDxe.c2096
-rw-r--r--Core/CPU/CpuDxe.dxs57
-rw-r--r--Core/CPU/CpuDxe.h158
-rw-r--r--Core/CPU/CpuDxeFuncs.c1101
-rw-r--r--Core/CPU/CpuPei.c936
-rw-r--r--Core/CPU/CpuPei.dxs65
-rw-r--r--Core/CPU/CpuPei.h206
-rw-r--r--Core/CPU/CpuPeiBeforeMem.c1268
-rw-r--r--Core/CPU/CpuPeiFuncs.c1378
-rw-r--r--Core/CPU/CpuSmbios.c734
-rw-r--r--Core/CPU/CpuSpSmi.DXS59
-rw-r--r--Core/CPU/CpuSpSmi.c568
-rw-r--r--Core/CPU/CpuSpSmi.cif12
-rw-r--r--Core/CPU/CpuSpSmi.h118
-rw-r--r--Core/CPU/CpuSpSmi.mak65
-rw-r--r--Core/CPU/CpuSpSmi.sdl56
-rw-r--r--Core/CPU/CpuTools.cif10
-rw-r--r--Core/CPU/CpuTools.sdl13
-rw-r--r--Core/CPU/CreateSecFfs.exebin0 -> 45056 bytes
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.cif12
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.mak67
-rw-r--r--Core/CPU/IA32/AmiIa32Lib.sdl19
-rw-r--r--Core/CPU/IA32/FoundationIa32.cif16
-rw-r--r--Core/CPU/IA32/FoundationIa32.mak69
-rw-r--r--Core/CPU/IA32/FoundationIa32.sdl19
-rw-r--r--Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm143
-rw-r--r--Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm78
-rw-r--r--Core/CPU/IA32/IA32CLib.c1959
-rw-r--r--Core/CPU/IA32/IA32Core.cif9
-rw-r--r--Core/CPU/IA32/IA32Core.sdl33
-rw-r--r--Core/CPU/IA32/IA32rules.mak62
-rw-r--r--Core/CPU/IA32/PeCoffLoaderEx.c93
-rw-r--r--Core/CPU/IA32/PeCoffLoaderEx.h85
-rw-r--r--Core/CPU/IA32/Processor.c140
-rw-r--r--Core/CPU/IA32/Processor.h27
-rw-r--r--Core/CPU/IA32/ProcessorAsms.Asm223
-rw-r--r--Core/CPU/IA32/SwitchCoreStacks.asm104
-rw-r--r--Core/CPU/IA32/efijump.h34
-rw-r--r--Core/CPU/IPF/FoundationIPF.cif24
-rw-r--r--Core/CPU/IPF/FoundationIPF.mak66
-rw-r--r--Core/CPU/IPF/FoundationIPF.sdl19
-rw-r--r--Core/CPU/IPF/IpfCpuCore.i93
-rw-r--r--Core/CPU/IPF/IpfCpuCore.s196
-rw-r--r--Core/CPU/IPF/PeCoffLoaderEx.c268
-rw-r--r--Core/CPU/IPF/PeCoffLoaderEx.h87
-rw-r--r--Core/CPU/IPF/PerformancePrimitives.s61
-rw-r--r--Core/CPU/IPF/Processor.h27
-rw-r--r--Core/CPU/IPF/SwitchStack.s122
-rw-r--r--Core/CPU/IPF/SwitchToCacheMode.c77
-rw-r--r--Core/CPU/IPF/asm.h35
-rw-r--r--Core/CPU/IPF/efijump.h112
-rw-r--r--Core/CPU/IPF/ia_64gen.h214
-rw-r--r--Core/CPU/IPF/pioflush.s106
-rw-r--r--Core/CPU/IPF/processor.c118
-rw-r--r--Core/CPU/IPF/setjmp.s325
-rw-r--r--Core/CPU/MBIOSMAC.MAC512
-rw-r--r--Core/CPU/MicrocodeUpdate/FwhFvb.c140
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c1164
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif13
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs48
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h133
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak58
-rw-r--r--Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl32
-rw-r--r--Core/CPU/ResetVector.asm99
-rw-r--r--Core/CPU/SecFixup.exebin0 -> 45056 bytes
-rw-r--r--Core/CPU/Startup32.asm618
-rw-r--r--Core/CPU/x64/AmiX64Lib.cif52
-rw-r--r--Core/CPU/x64/AmiX64Lib.mak63
-rw-r--r--Core/CPU/x64/AmiX64Lib.sdl19
-rw-r--r--Core/CPU/x64/EfiJump.h42
-rw-r--r--Core/CPU/x64/Foundationx64.cif15
-rw-r--r--Core/CPU/x64/Foundationx64.mak65
-rw-r--r--Core/CPU/x64/Foundationx64.sdl19
-rw-r--r--Core/CPU/x64/MiscLib/Misc.asm124
-rw-r--r--Core/CPU/x64/MiscLib/MiscX64Lib.cif10
-rw-r--r--Core/CPU/x64/MiscLib/MiscX64Lib.mak74
-rw-r--r--Core/CPU/x64/MiscLib/MiscX64Lib.sdl19
-rw-r--r--Core/CPU/x64/PeCoffLoaderEx.c87
-rw-r--r--Core/CPU/x64/PeCoffLoaderEx.h85
-rw-r--r--Core/CPU/x64/Processor.c146
-rw-r--r--Core/CPU/x64/Processor.h27
-rw-r--r--Core/CPU/x64/ProcessorAsms.Asm186
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm80
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm130
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm81
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm81
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_Pause.asm80
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm84
-rw-r--r--Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm84
-rw-r--r--Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/GetCpuTimer.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/GetCsSegment.asm79
-rw-r--r--Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm84
-rw-r--r--Core/CPU/x64/x64AsmLib/HltCpu.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead16.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead32.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead64.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoRead8.asm83
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite16.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite32.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite64.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/IoWrite8.asm87
-rw-r--r--Core/CPU/x64/x64AsmLib/MemCpy.asm178
-rw-r--r--Core/CPU/x64/x64AsmLib/MemCpy32.asm178
-rw-r--r--Core/CPU/x64/x64AsmLib/MemRead32.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/MemReadWrite32.asm93
-rw-r--r--Core/CPU/x64/x64AsmLib/MemSet.asm127
-rw-r--r--Core/CPU/x64/x64AsmLib/ReadCr3.asm79
-rw-r--r--Core/CPU/x64/x64AsmLib/ReadMsr.asm85
-rw-r--r--Core/CPU/x64/x64AsmLib/ReadRtdsc.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm88
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitForever.asm82
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm86
-rw-r--r--Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm86
-rw-r--r--Core/CPU/x64/x64AsmLib/WriteCr3.asm81
-rw-r--r--Core/CPU/x64/x64AsmLib/WriteMsr.asm89
-rw-r--r--Core/CPU/x64/x64AsmLib/checkpoint.asm84
-rw-r--r--Core/CPU/x64/x64CLib.c328
-rw-r--r--Core/CPU/x64/x64Core.cif9
-rw-r--r--Core/CPU/x64/x64Core.sdl112
-rw-r--r--Core/CPU/x64/x64rules.mak86
-rw-r--r--Core/CSPLib/CSP Library.chmbin0 -> 56836 bytes
-rw-r--r--Core/CSPLib/CspLib.CIF20
-rw-r--r--Core/CSPLib/CspLib.mak251
-rw-r--r--Core/CSPLib/CspLib.sdl107
-rw-r--r--Core/CSPLib/CspLibDxe.C104
-rw-r--r--Core/CSPLib/CspLibDxe.Dxs67
-rw-r--r--Core/CSPLib/CspLibGeneric.C399
-rw-r--r--Core/CSPLib/CspLibGeneric.h444
-rw-r--r--Core/CSPLib/CspLibPei.C329
-rw-r--r--Core/CSPLib/FID.c108
-rw-r--r--Core/Core.chmbin0 -> 433167 bytes
-rw-r--r--Core/Core.cif33
-rw-r--r--Core/Core.mak859
-rw-r--r--Core/Core.sdl991
-rw-r--r--Core/CoreSrc.cif20
-rw-r--r--Core/CoreSrc.sdl50
-rw-r--r--Core/EM/ACPI/ACPICORE.CIF23
-rw-r--r--Core/EM/ACPI/AMLUPD.asl163
-rw-r--r--Core/EM/ACPI/ASLCORE.CIF37
-rw-r--r--Core/EM/ACPI/AcpiCore.c4475
-rw-r--r--Core/EM/ACPI/AcpiCore.h573
-rw-r--r--Core/EM/ACPI/AcpiS3.h170
-rw-r--r--Core/EM/ACPI/AcpiSdt.c821
-rw-r--r--Core/EM/ACPI/AcpiSdtPrivate.h798
-rw-r--r--Core/EM/ACPI/Aml.c350
-rw-r--r--Core/EM/ACPI/AmlChild.c326
-rw-r--r--Core/EM/ACPI/AmlNamespace.c659
-rw-r--r--Core/EM/ACPI/AmlOption.c500
-rw-r--r--Core/EM/ACPI/AmlString.c600
-rw-r--r--Core/EM/ACPI/AtadSmi.c254
-rw-r--r--Core/EM/ACPI/AtadSmi.cif12
-rw-r--r--Core/EM/ACPI/AtadSmi.dxs98
-rw-r--r--Core/EM/ACPI/AtadSmi.h91
-rw-r--r--Core/EM/ACPI/AtadSmi.mak82
-rw-r--r--Core/EM/ACPI/AtadSmi.sdl25
-rw-r--r--Core/EM/ACPI/CIR.ASL168
-rw-r--r--Core/EM/ACPI/Fdc.asl150
-rw-r--r--Core/EM/ACPI/GameMpu.asl185
-rw-r--r--Core/EM/ACPI/LM75.ASL179
-rw-r--r--Core/EM/ACPI/Lpte.asl199
-rw-r--r--Core/EM/ACPI/MAX1617L.ASL219
-rw-r--r--Core/EM/ACPI/MAX1617R.ASL222
-rw-r--r--Core/EM/ACPI/Mathco.asl50
-rw-r--r--Core/EM/ACPI/MpPciIrq.asm99
-rw-r--r--Core/EM/ACPI/OSCM.asl124
-rw-r--r--Core/EM/ACPI/PCIEACCESS.ASL170
-rw-r--r--Core/EM/ACPI/PCIEHP.ASL346
-rw-r--r--Core/EM/ACPI/PS2kb.asl121
-rw-r--r--Core/EM/ACPI/PS2ms.asl128
-rw-r--r--Core/EM/ACPI/RbRes.asl501
-rw-r--r--Core/EM/ACPI/SMB_EC.ASL91
-rw-r--r--Core/EM/ACPI/TimeAndAlarm.asl523
-rw-r--r--Core/EM/ACPI/Uart1.asl159
-rw-r--r--Core/EM/ACPI/Uart1ir.asl143
-rw-r--r--Core/EM/ACPI/Uart2.asl137
-rw-r--r--Core/EM/ACPI/Uart2ir.asl467
-rw-r--r--Core/EM/ACPI/Uart3.asl103
-rw-r--r--Core/EM/ACPI/Uart3ir.asl127
-rw-r--r--Core/EM/ACPI/Uart4.asl109
-rw-r--r--Core/EM/ACPI/Uart4ir.asl128
-rw-r--r--Core/EM/ACPI/asllib.asl325
-rw-r--r--Core/EM/ACPI/game.asl101
-rw-r--r--Core/EM/ACPI/irda.asl115
-rw-r--r--Core/EM/ACPI/midi.asl124
-rw-r--r--Core/EM/ACPI/mptable.c1553
-rw-r--r--Core/EM/ACPI/mptable.h593
-rw-r--r--Core/EM/ACPI/rmisc.asl120
-rw-r--r--Core/EM/AMIDebugRx/AMIDebugRx.chmbin0 -> 99141 bytes
-rw-r--r--Core/EM/AMIDebugRx/AMIDebugRx.cif11
-rw-r--r--Core/EM/AMIDebugRx/AMIDebugRx.mak88
-rw-r--r--Core/EM/AMIDebugRx/AMIDebugRx.sd66
-rw-r--r--Core/EM/AMIDebugRx/AMIDebugRx.sdl34
-rw-r--r--Core/EM/AMIDebugRx/AMIDebugRx.unibin0 -> 5718 bytes
-rw-r--r--Core/EM/AMIDebugRx/DebugRx.cif18
-rw-r--r--Core/EM/AMIDebugRx/DebugRx.sdl121
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.cif10
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.mak150
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.sdl9
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/AsmDbgrx64Libs.h202
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.cif11
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.libbin0 -> 12612 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.mak110
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.sdl16
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.cif13
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.libbin0 -> 8834 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.mak133
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.sdl29
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64.libbin0 -> 12232 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64_PI_1_1.libbin0 -> 12222 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib_PI_1_1.libbin0 -> 8830 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.mak287
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.sdl49
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLibBin.cif14
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/DbgrHelp.c260
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/HostConStatus.c213
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodeDxe.objbin0 -> 3181 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodePei.objbin0 -> 1319 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/DummyAmiSerialIO.objbin0 -> 872 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfaceDxe.objbin0 -> 1337 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfacePei.objbin0 -> 657 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/PeiDbgStatusCode.objbin0 -> 2835 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/StsCodeObjsIA32Rx.cif13
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodeDxe.objbin0 -> 5036 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodePei.objbin0 -> 893 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/DummyAmiSerialIO.objbin0 -> 652 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/GetDbgInterfaceDxe.objbin0 -> 1892 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/PeiDbgStatusCode.objbin0 -> 3260 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/StsCodeObjsx64Rx.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/LIBS/UsbCableSelect.c180
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/DbgrHdr.c357
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/mindbgr.objbin0 -> 1690 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/IDT/emptyidt.objbin0 -> 549 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebug.h469
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebugX64.h509
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/EHCI.h244
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/INC.cif11
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/misc.h178
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain.ffsbin0 -> 958 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain_PI_1_1.ffsbin0 -> 926 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.cif18
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.sdl44
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.dxs57
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.mak136
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.sdl22
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.cif11
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.dxs59
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.mak112
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.sdl22
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.cif10
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.sdl55
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.c390
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.dxs60
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.mak176
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.sdl51
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPortUSB.objbin0 -> 1421 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.cif14
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.dxs59
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.mak160
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.sdl32
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/AmiDebugPort.objbin0 -> 1881 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/CopyDbgXPortUsb.objbin0 -> 727 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DbgrHelp.c168
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DebugPortUsb.objbin0 -> 1217 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/EmptyNotify.objbin0 -> 1248 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/Emptyrelocdbgidt.objbin0 -> 1315 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64.objbin0 -> 4231 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64_PI_1_1.objbin0 -> 4315 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.cif23
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.dxs54
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.mak191
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.objbin0 -> 1857 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.sdl24
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport_PI_1_1.objbin0 -> 1781 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/emptyX64idt.objbin0 -> 848 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg.objbin0 -> 5592 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg_PI_1_1.objbin0 -> 5688 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/UsbDebugPort.objbin0 -> 11962 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/transport.objbin0 -> 3723 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_acc.objbin0 -> 1826 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_xp.objbin0 -> 5159 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/xp_layer.objbin0 -> 8805 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportDbgr.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportRedir.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/UsbDebugPort.objbin0 -> 11966 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/transport.objbin0 -> 3683 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_acc.objbin0 -> 1830 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_xp.objbin0 -> 4310 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/xp_layer.objbin0 -> 8290 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/XportHdr.c454
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.cif11
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.dxs60
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.mak125
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.sdl35
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/mindbgr.objbin0 -> 2117 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/UsbDebugPort.objbin0 -> 13845 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/transport.objbin0 -> 2689 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_acc.objbin0 -> 1494 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_xp.objbin0 -> 7235 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/xp_layer.objbin0 -> 11340 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.cif14
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.dxs59
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.mak139
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.sdl34
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportDbgrx64.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportx64Redir.cif12
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/UsbDebugPort.objbin0 -> 13853 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/transport.objbin0 -> 2604 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_acc.objbin0 -> 1502 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_xp.objbin0 -> 6059 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/xp_layer.objbin0 -> 11241 bytes
-rw-r--r--Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/XportHdr.c445
-rw-r--r--Core/EM/AMITSE/AMITSE.chmbin0 -> 390707 bytes
-rw-r--r--Core/EM/AMITSE/AMITSE.cif52
-rw-r--r--Core/EM/AMITSE/AMITSE.mak614
-rw-r--r--Core/EM/AMITSE/AMITSE.sdl3655
-rw-r--r--Core/EM/AMITSE/AmiTSEStr.unibin0 -> 48960 bytes
-rw-r--r--Core/EM/AMITSE/CommonHelper.c6230
-rw-r--r--Core/EM/AMITSE/FakeTokens.c391
-rw-r--r--Core/EM/AMITSE/HookList.c187
-rw-r--r--Core/EM/AMITSE/HpkTool.exebin0 -> 57344 bytes
-rw-r--r--Core/EM/AMITSE/Inc/HiiLib.h127
-rw-r--r--Core/EM/AMITSE/Inc/HookAnchor.h252
-rw-r--r--Core/EM/AMITSE/Inc/LogoLib.h241
-rw-r--r--Core/EM/AMITSE/Inc/PwdLib.h148
-rw-r--r--Core/EM/AMITSE/Inc/TseCommon.h147
-rw-r--r--Core/EM/AMITSE/Inc/TseElinks.h159
-rw-r--r--Core/EM/AMITSE/Inc/boot.h537
-rw-r--r--Core/EM/AMITSE/Inc/mem.h100
-rw-r--r--Core/EM/AMITSE/Inc/setupdata.h421
-rw-r--r--Core/EM/AMITSE/Inc/variable.h251
-rw-r--r--Core/EM/AMITSE/Keymon.c302
-rw-r--r--Core/EM/AMITSE/Keymon.h106
-rw-r--r--Core/EM/AMITSE/OEMLogo.bmpbin0 -> 12918 bytes
-rw-r--r--Core/EM/AMITSE/SmLogo.bmpbin0 -> 20118 bytes
-rw-r--r--Core/EM/AMITSE/TseDrvHealth.h188
-rw-r--r--Core/EM/AMITSE/UefiHpkTool.exebin0 -> 69632 bytes
-rw-r--r--Core/EM/AMITSE/Uefisetup.ini533
-rw-r--r--Core/EM/AMITSE/bootflow.c445
-rw-r--r--Core/EM/AMITSE/bootflow.h207
-rw-r--r--Core/EM/AMITSE/changelog.log1269
-rw-r--r--Core/EM/AMITSE/commonoem.c2654
-rw-r--r--Core/EM/AMITSE/commonoem.h354
-rw-r--r--Core/EM/AMITSE/setup.ini533
-rw-r--r--Core/EM/AMITSE/setupdbg.h51
-rw-r--r--Core/EM/Ahci/AInt13.c1366
-rw-r--r--Core/EM/Ahci/AInt13.dxs37
-rw-r--r--Core/EM/Ahci/AInt13.h395
-rw-r--r--Core/EM/Ahci/AhciBus.c4477
-rw-r--r--Core/EM/Ahci/AhciBus.h919
-rw-r--r--Core/EM/Ahci/AhciComponentName.c314
-rw-r--r--Core/EM/Ahci/AhciController.c3403
-rw-r--r--Core/EM/Ahci/AhciController.h633
-rw-r--r--Core/EM/Ahci/AhciInt13Dxe.c412
-rw-r--r--Core/EM/Ahci/AhciInt13Dxe.dxs51
-rw-r--r--Core/EM/Ahci/AhciInt13Smm.c1157
-rw-r--r--Core/EM/Ahci/AhciInt13Smm.cif15
-rw-r--r--Core/EM/Ahci/AhciInt13Smm.dxs65
-rw-r--r--Core/EM/Ahci/AhciInt13Smm.h155
-rw-r--r--Core/EM/Ahci/AhciInt13Smm.mak72
-rw-r--r--Core/EM/Ahci/AhciInt13Smm.sdl58
-rw-r--r--Core/EM/Ahci/AhciSmm/AhciSmm.c2217
-rw-r--r--Core/EM/Ahci/AhciSmm/AhciSmm.cif14
-rw-r--r--Core/EM/Ahci/AhciSmm/AhciSmm.dxs87
-rw-r--r--Core/EM/Ahci/AhciSmm/AhciSmm.h237
-rw-r--r--Core/EM/Ahci/AhciSmm/AhciSmm.mak82
-rw-r--r--Core/EM/Ahci/AhciSmm/AhciSmm.sdl24
-rw-r--r--Core/EM/Ahci/AhciSources.chmbin0 -> 257910 bytes
-rw-r--r--Core/EM/Ahci/AhciSrc.cif19
-rw-r--r--Core/EM/Ahci/AhciSrc.mak102
-rw-r--r--Core/EM/Ahci/AhciSrc.sdl105
-rw-r--r--Core/EM/Ahci/Aint13.cif18
-rw-r--r--Core/EM/Ahci/Aint13.inf5
-rw-r--r--Core/EM/Ahci/Aint13.mak105
-rw-r--r--Core/EM/Ahci/Aint13.sdl67
-rw-r--r--Core/EM/BoardInfo/AMIBoardInfo.cif15
-rw-r--r--Core/EM/BoardInfo/AmiBoardInfo.c391
-rw-r--r--Core/EM/BoardInfo/AmiBoardInfo.chmbin0 -> 35525 bytes
-rw-r--r--Core/EM/BoardInfo/AmiBoardInfo.dxs55
-rw-r--r--Core/EM/BoardInfo/AmiBoardInfo.mak334
-rw-r--r--Core/EM/BoardInfo/AmiBoardInfo.sdl113
-rw-r--r--Core/EM/BoardInfo/PciBoard.c119
-rw-r--r--Core/EM/BootScriptHide/BootScriptHide.chmbin0 -> 99316 bytes
-rw-r--r--Core/EM/BootScriptHide/BootScriptHide.cif16
-rw-r--r--Core/EM/BootScriptHide/BootScriptHide.mak124
-rw-r--r--Core/EM/BootScriptHide/BootScriptHide.sdl50
-rw-r--r--Core/EM/BootScriptHide/BootScriptHideDxe.c126
-rw-r--r--Core/EM/BootScriptHide/BootScriptHideDxe.dxs33
-rw-r--r--Core/EM/BootScriptHide/BootScriptHidePei.c266
-rw-r--r--Core/EM/BootScriptHide/BootScriptHidePei.dxs35
-rw-r--r--Core/EM/BootScriptHide/BootScriptHideSmm.c388
-rw-r--r--Core/EM/BootScriptHide/BootScriptHideSmm.dxs35
-rw-r--r--Core/EM/CSM/BiosData.h179
-rw-r--r--Core/EM/CSM/CSM.c2926
-rw-r--r--Core/EM/CSM/CSM.dxs62
-rw-r--r--Core/EM/CSM/CSM.h1089
-rw-r--r--Core/EM/CSM/CSM.mak174
-rw-r--r--Core/EM/CSM/CsmBsp.c1295
-rw-r--r--Core/EM/CSM/CsmHwInfo.c2063
-rw-r--r--Core/EM/CSM/CsmLib.c1617
-rw-r--r--Core/EM/CSM/CsmOpROM.c2726
-rw-r--r--Core/EM/CSM/CsmSimpleIn.c604
-rw-r--r--Core/EM/CSM/OemPir.dat227
-rw-r--r--Core/EM/CSM/PciInfo.asm83
-rw-r--r--Core/EM/CSM/PciInterrupts.c1136
-rw-r--r--Core/EM/CSM/csmcore.cif23
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c260
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c1076
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h277
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl25
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmEdd.h407
-rw-r--r--Core/EM/CSM/thunk/BlockIo/CsmInt13.c1525
-rw-r--r--Core/EM/CSM/thunk/BlockIo/biosblkio.dxs46
-rw-r--r--Core/EM/CSM/thunk/BlockIo/biosblkio.mak63
-rw-r--r--Core/EM/CSM/thunk/BlockIo/int13thunk.cif15
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/AmiMapping.c162
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/AmiMapping.h153
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/ComponentName.c324
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif20
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs46
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak66
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl58
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c3886
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h597
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h463
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/VgaClass.c1349
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/VgaClass.h418
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h78
-rw-r--r--Core/EM/CSM/thunk/CsmVideo/pci22.h621
-rw-r--r--Core/EM/CSM/thunk/Snp16/snp16.cif8
-rw-r--r--Core/EM/CSM/thunk/thunk.cif11
-rw-r--r--Core/EM/CSM/thunk/x86/thunk.c793
-rw-r--r--Core/EM/CSM/thunk/x86/x86thunk.asm828
-rw-r--r--Core/EM/CSM/thunk/x86/x86thunk.cif10
-rw-r--r--Core/EM/CSM/thunk/x86/x86thunk.mak67
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0.c870
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0.cif13
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0.h177
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0.mak70
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0.sdl60
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0Bds.c140
-rw-r--r--Core/EM/Capsule2_0/Capsule2_0Runtime.c457
-rw-r--r--Core/EM/CmosManager/CmosAccess.asl131
-rw-r--r--Core/EM/CmosManager/CmosAccess.c2252
-rw-r--r--Core/EM/CmosManager/CmosBoard.c517
-rw-r--r--Core/EM/CmosManager/CmosBoard.h210
-rw-r--r--Core/EM/CmosManager/CmosBoard.sdl905
-rw-r--r--Core/EM/CmosManager/CmosBoard.ssp171
-rw-r--r--Core/EM/CmosManager/CmosManager.c1193
-rw-r--r--Core/EM/CmosManager/CmosManager.chmbin0 -> 682990 bytes
-rw-r--r--Core/EM/CmosManager/CmosManager.cif16
-rw-r--r--Core/EM/CmosManager/CmosManager.h260
-rw-r--r--Core/EM/CmosManager/CmosManager.mak423
-rw-r--r--Core/EM/CmosManager/CmosManager.sdl409
-rw-r--r--Core/EM/CmosManager/CmosManagerBoard.cif15
-rw-r--r--Core/EM/CmosManager/CmosManagerBuild.cif9
-rw-r--r--Core/EM/CmosManager/CmosManagerCore.cif12
-rw-r--r--Core/EM/CmosManager/CmosManagerDxe.c456
-rw-r--r--Core/EM/CmosManager/CmosManagerDxe.cif9
-rw-r--r--Core/EM/CmosManager/CmosManagerDxe.h74
-rw-r--r--Core/EM/CmosManager/CmosManagerHob.c429
-rw-r--r--Core/EM/CmosManager/CmosManagerHob.h139
-rw-r--r--Core/EM/CmosManager/CmosManagerIncludes.cif10
-rw-r--r--Core/EM/CmosManager/CmosManagerMessages.cif11
-rw-r--r--Core/EM/CmosManager/CmosManagerPei.c264
-rw-r--r--Core/EM/CmosManager/CmosManagerPei.cif9
-rw-r--r--Core/EM/CmosManager/CmosManagerPei.h81
-rw-r--r--Core/EM/CmosManager/CmosManagerSec.asm396
-rw-r--r--Core/EM/CmosManager/CmosManagerSec.cif8
-rw-r--r--Core/EM/CmosManager/CmosManagerSmm.c462
-rw-r--r--Core/EM/CmosManager/CmosManagerSmm.cif11
-rw-r--r--Core/EM/CmosManager/CmosManagerSmm.dxs59
-rw-r--r--Core/EM/CmosManager/CmosManagerSmm.h65
-rw-r--r--Core/EM/CmosManager/CmosManagerSource.cif11
-rw-r--r--Core/EM/CmosManager/CmosMessages.c231
-rw-r--r--Core/EM/CmosManager/CmosMessages.mak70
-rw-r--r--Core/EM/CmosManager/CmosMessages.sdl100
-rw-r--r--Core/EM/CmosManager/CmosMessages.unibin0 -> 7102 bytes
-rw-r--r--Core/EM/CmosManager/CmosSetup.sd223
-rw-r--r--Core/EM/CmosManager/CmosSetup.unibin0 -> 6508 bytes
-rw-r--r--Core/EM/CmosManager/CmosTables.c235
-rw-r--r--Core/EM/CmosManager/CmosTypes.h431
-rw-r--r--Core/EM/CmosManager/Template.ssp259
-rw-r--r--Core/EM/CryptoPkg/CryptLib/Cryptlib.cif15
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlib.chmbin0 -> 82444 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlib.libbin0 -> 139706 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlib.sdl36
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlibX64.libbin0 -> 232926 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/cryptlibpei.libbin0 -> 92784 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptLib/license.txt102
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.chmbin0 -> 110686 bytes
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.cif16
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.mak127
-rw-r--r--Core/EM/CryptoPkg/CryptoAPI.sdl95
-rw-r--r--Core/EM/CryptoPkg/CryptoDxe.c1108
-rw-r--r--Core/EM/CryptoPkg/CryptoDxe.dxs53
-rw-r--r--Core/EM/CryptoPkg/CryptoPei.c800
-rw-r--r--Core/EM/CryptoPkg/CryptoPei.dxs54
-rw-r--r--Core/EM/CryptoPkg/CryptoPkg.cif9
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.c1039
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.chmbin0 -> 45928 bytes
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.cif15
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.mak106
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.sd252
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.sdl124
-rw-r--r--Core/EM/CsmOptOut/CsmOptOut.unibin0 -> 10770 bytes
-rw-r--r--Core/EM/CsmOptOut/CsmOptOutRuntime.c168
-rw-r--r--Core/EM/CsmOptOut/CsmOptOutSetup.c430
-rw-r--r--Core/EM/EBC/EBC.cif12
-rw-r--r--Core/EM/EBC/EBC.dxs54
-rw-r--r--Core/EM/EBC/EBC.efibin0 -> 16640 bytes
-rw-r--r--Core/EM/EBC/EBC.mak69
-rw-r--r--Core/EM/EBC/EBC.sdl24
-rw-r--r--Core/EM/EBC/EBCx64.efibin0 -> 14240 bytes
-rw-r--r--Core/EM/EdkIILib/Console.c200
-rw-r--r--Core/EM/EdkIILib/EdkIICommonWrap.c318
-rw-r--r--Core/EM/EdkIILib/EdkIIHiiLib.c1328
-rw-r--r--Core/EM/EdkIILib/EdkIIHiiWrap.c233
-rw-r--r--Core/EM/EdkIILib/EdkIILib.cif15
-rw-r--r--Core/EM/EdkIILib/EdkIILib.mak53
-rw-r--r--Core/EM/EdkIILib/EdkIILib.sdl26
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c603
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chmbin0 -> 88779 bytes
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif14
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak123
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd118
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl286
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.unibin0 -> 6122 bytes
-rw-r--r--Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c1682
-rw-r--r--Core/EM/FastBoot/FastBoot.c4537
-rw-r--r--Core/EM/FastBoot/FastBoot.cif22
-rw-r--r--Core/EM/FastBoot/FastBoot.mak144
-rw-r--r--Core/EM/FastBoot/FastBoot.sd372
-rw-r--r--Core/EM/FastBoot/FastBoot.sdl400
-rw-r--r--Core/EM/FastBoot/FastBoot.unibin0 -> 10480 bytes
-rw-r--r--Core/EM/FastBoot/FastBootDxe.c184
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOption.c433
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOption.cif13
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOption.dxs66
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOption.h96
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOption.mak80
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOption.sdl40
-rw-r--r--Core/EM/FastBoot/FastBootOption/FastBootOptionBds.c274
-rw-r--r--Core/EM/FastBoot/FastBootPei.c180
-rw-r--r--Core/EM/FastBoot/FastBootPei.cif11
-rw-r--r--Core/EM/FastBoot/FastBootPei.dxs56
-rw-r--r--Core/EM/FastBoot/FastBootPei.mak95
-rw-r--r--Core/EM/FastBoot/FastBootRuntime.c526
-rw-r--r--Core/EM/FastBoot/FastBootSMI.c244
-rw-r--r--Core/EM/FastBoot/FastBootSMI.cif12
-rw-r--r--Core/EM/FastBoot/FastBootSMI.dxs64
-rw-r--r--Core/EM/FastBoot/FastBootSMI.mak82
-rw-r--r--Core/EM/FastBoot/FastBootSMI.sdl40
-rw-r--r--Core/EM/FastBoot/FastBootTseHook.c379
-rw-r--r--Core/EM/FastBoot/PTT.chmbin0 -> 490098 bytes
-rw-r--r--Core/EM/FileSystem/DirectoryHandler.c454
-rw-r--r--Core/EM/FileSystem/FileFatHandler.c898
-rw-r--r--Core/EM/FileSystem/FileSYstem.mak75
-rw-r--r--Core/EM/FileSystem/FileSystem.c948
-rw-r--r--Core/EM/FileSystem/FileSystem.chmbin0 -> 118223 bytes
-rw-r--r--Core/EM/FileSystem/FileSystem.cif19
-rw-r--r--Core/EM/FileSystem/FileSystem.h1480
-rw-r--r--Core/EM/FileSystem/FileSystem.sdl49
-rw-r--r--Core/EM/FileSystem/FileSystemComponentName.c271
-rw-r--r--Core/EM/FileSystem/Info.c1313
-rw-r--r--Core/EM/FileSystem/MediaAccess.c1479
-rw-r--r--Core/EM/FileSystem/Open.c2601
-rw-r--r--Core/EM/FileSystem/VolFatHandler.c1419
-rw-r--r--Core/EM/FirmwareManagement/FirmwareManagement.c178
-rw-r--r--Core/EM/FirmwareManagement/FirmwareManagement.cif10
-rw-r--r--Core/EM/FirmwareManagement/FirmwareManagement.mak57
-rw-r--r--Core/EM/FirmwareManagement/FirmwareManagement.sdl25
-rw-r--r--Core/EM/FlashSmi/FlashSmi.c804
-rw-r--r--Core/EM/FlashSmi/FlashSmi.chmbin0 -> 33133 bytes
-rw-r--r--Core/EM/FlashSmi/FlashSmi.cif12
-rw-r--r--Core/EM/FlashSmi/FlashSmi.dxs82
-rw-r--r--Core/EM/FlashSmi/FlashSmi.mak89
-rw-r--r--Core/EM/FlashSmi/FlashSmi.sdl87
-rw-r--r--Core/EM/FloppyCtrl/FloppyCtrl.c2792
-rw-r--r--Core/EM/FloppyCtrl/FloppyCtrl.cif13
-rw-r--r--Core/EM/FloppyCtrl/FloppyCtrl.h441
-rw-r--r--Core/EM/FloppyCtrl/FloppyCtrl.mak94
-rw-r--r--Core/EM/FloppyCtrl/FloppyCtrl.sdl40
-rw-r--r--Core/EM/FloppyCtrl/FloppyCtrlPei.dxs70
-rw-r--r--Core/EM/FloppyCtrl/Names.c240
-rw-r--r--Core/EM/HardwareSignature/HardwareChangeDetect.c1159
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.c1874
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.chmbin0 -> 67032 bytes
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.cif15
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.dxs42
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.mak109
-rw-r--r--Core/EM/HardwareSignature/HardwareSignatureManagement.sdl72
-rw-r--r--Core/EM/HashService/HashService.c277
-rw-r--r--Core/EM/HashService/HashService.cif10
-rw-r--r--Core/EM/HashService/HashService.mak65
-rw-r--r--Core/EM/HashService/HashService.sdl28
-rw-r--r--Core/EM/HddSecurity/Hddpassword/ForceHddPassword.c158
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddPassword.c2631
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddPassword.cif14
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddPassword.h185
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddPassword.mak96
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddPassword.sdl136
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddPassword.unibin0 -> 6918 bytes
-rw-r--r--Core/EM/HddSecurity/Hddpassword/HddSecTokens.c79
-rw-r--r--Core/EM/HddSecurity/IDESMM.DXS84
-rw-r--r--Core/EM/HddSecurity/IDESMM.c1553
-rw-r--r--Core/EM/HddSecurity/IDESMM.cif12
-rw-r--r--Core/EM/HddSecurity/IDESMM.h198
-rw-r--r--Core/EM/HddSecurity/IDESMM.mak95
-rw-r--r--Core/EM/HddSecurity/IDESMM.sdl66
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.c2939
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.chmbin0 -> 220714 bytes
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.cif22
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.dxs86
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.h470
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.mak173
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.sd525
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.sdl240
-rw-r--r--Core/EM/HddSecurity/IdeSecurity.unibin0 -> 12110 bytes
-rw-r--r--Core/EM/HddSecurity/IdeSecurityBdsCall.c261
-rw-r--r--Core/EM/HddSecurity/IdeSecurityCommon.sd653
-rw-r--r--Core/EM/HddSecurity/IdeSecuritySetup.c434
-rw-r--r--Core/EM/HddSmart/IdeSMART.c1665
-rw-r--r--Core/EM/HddSmart/IdeSMART.chmbin0 -> 48555 bytes
-rw-r--r--Core/EM/HddSmart/IdeSMART.cif15
-rw-r--r--Core/EM/HddSmart/IdeSMART.dxs87
-rw-r--r--Core/EM/HddSmart/IdeSMART.h216
-rw-r--r--Core/EM/HddSmart/IdeSMART.mak111
-rw-r--r--Core/EM/HddSmart/IdeSMART.sd126
-rw-r--r--Core/EM/HddSmart/IdeSMART.sdl91
-rw-r--r--Core/EM/HddSmart/IdeSMART.unibin0 -> 6924 bytes
-rw-r--r--Core/EM/IdeBus/Ata.c2986
-rw-r--r--Core/EM/IdeBus/Atapi.c1811
-rw-r--r--Core/EM/IdeBus/IDEBusComponentName.c374
-rw-r--r--Core/EM/IdeBus/IdeBus.c3607
-rw-r--r--Core/EM/IdeBus/IdeBus.chmbin0 -> 151925 bytes
-rw-r--r--Core/EM/IdeBus/IdeBus.cif13
-rw-r--r--Core/EM/IdeBus/IdeBus.h821
-rw-r--r--Core/EM/IdeBus/IdeBus.mak114
-rw-r--r--Core/EM/IdeBus/IdeBus.sdl195
-rw-r--r--Core/EM/IdeBus/IdeBusMaster.c836
-rw-r--r--Core/EM/IdeBus/IdeBusSrc.chmbin0 -> 152056 bytes
-rw-r--r--Core/EM/IdeBus/IdeBusSrc.cif18
-rw-r--r--Core/EM/IdeBus/IdeBusSrc.mak98
-rw-r--r--Core/EM/IdeBus/IdeBusSrc.sdl22
-rw-r--r--Core/EM/IdeBus/IdeHPA.c792
-rw-r--r--Core/EM/IdeBus/IdePowerManagement.c546
-rw-r--r--Core/EM/KbcEmul/Ap4x.c81
-rw-r--r--Core/EM/KbcEmul/Ap4x.h130
-rw-r--r--Core/EM/KbcEmul/Kbc.h195
-rw-r--r--Core/EM/KbcEmul/KbcDevEmul.h193
-rw-r--r--Core/EM/KbcEmul/KbcEmul.c481
-rw-r--r--Core/EM/KbcEmul/KbcEmul.cif31
-rw-r--r--Core/EM/KbcEmul/KbcEmul.dxs71
-rw-r--r--Core/EM/KbcEmul/KbcEmul.h129
-rw-r--r--Core/EM/KbcEmul/KbcEmul.mak197
-rw-r--r--Core/EM/KbcEmul/KbcEmul.sdl102
-rw-r--r--Core/EM/KbcEmul/KbcEmulAcpi.c156
-rw-r--r--Core/EM/KbcEmul/KbcEmulIrq.c178
-rw-r--r--Core/EM/KbcEmul/KbcEmulIrq.cif8
-rw-r--r--Core/EM/KbcEmul/KbcEmulLib.c572
-rw-r--r--Core/EM/KbcEmul/KbcEmulLib.h96
-rw-r--r--Core/EM/KbcEmul/KbcEmulation.chmbin0 -> 181041 bytes
-rw-r--r--Core/EM/KbcEmul/KbcOhci.c1051
-rw-r--r--Core/EM/KbcEmul/KbcOhci.cif9
-rw-r--r--Core/EM/KbcEmul/KbcOhci.h184
-rw-r--r--Core/EM/KbcEmul/KbcUhci.c707
-rw-r--r--Core/EM/KbcEmul/KbcUhci.cif9
-rw-r--r--Core/EM/KbcEmul/KbcUhci.h153
-rw-r--r--Core/EM/KbcEmul/Kbccore.c341
-rw-r--r--Core/EM/KbcEmul/LegacyMouse.c553
-rw-r--r--Core/EM/KbcEmul/Legacykbc.c821
-rw-r--r--Core/EM/KbcEmul/Legacykbd.c479
-rw-r--r--Core/EM/KbcEmul/VirtualKbc.c639
-rw-r--r--Core/EM/KbcEmul/VirtualKbd.c456
-rw-r--r--Core/EM/KbcEmul/VirtualMouse.c553
-rw-r--r--Core/EM/NVRAM/NVRAM.chmbin0 -> 89864 bytes
-rw-r--r--Core/EM/NVRAM/NVRAM.cif14
-rw-r--r--Core/EM/NVRAM/NVRAM.h490
-rw-r--r--Core/EM/NVRAM/NVRAM.mak225
-rw-r--r--Core/EM/NVRAM/NVRAM.sdl65
-rw-r--r--Core/EM/NVRAM/NVRAMDXE.c5719
-rw-r--r--Core/EM/NVRAM/NVRAMPEI.c584
-rw-r--r--Core/EM/NVRAM/NVRAMRead.c1508
-rw-r--r--Core/EM/Nvme/Nvme.chmbin0 -> 100515 bytes
-rw-r--r--Core/EM/Nvme/Nvme.cif24
-rw-r--r--Core/EM/Nvme/Nvme.mak170
-rw-r--r--Core/EM/Nvme/Nvme.sd170
-rw-r--r--Core/EM/Nvme/Nvme.sdl83
-rw-r--r--Core/EM/Nvme/Nvme.unibin0 -> 7390 bytes
-rw-r--r--Core/EM/Nvme/NvmeBus.c2793
-rw-r--r--Core/EM/Nvme/NvmeBus.h539
-rw-r--r--Core/EM/Nvme/NvmeComponentName.c270
-rw-r--r--Core/EM/Nvme/NvmeController.c1446
-rw-r--r--Core/EM/Nvme/NvmeController.cif12
-rw-r--r--Core/EM/Nvme/NvmeController.h235
-rw-r--r--Core/EM/Nvme/NvmeController.mak86
-rw-r--r--Core/EM/Nvme/NvmeController.sdl31
-rw-r--r--Core/EM/Nvme/NvmeIncludes.h120
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.c474
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.cif16
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.dxs71
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.h161
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.inf5
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.mak84
-rw-r--r--Core/EM/Nvme/NvmeInt13/NvmeInt13.sdl48
-rw-r--r--Core/EM/Nvme/NvmePassthru.c619
-rw-r--r--Core/EM/Nvme/NvmePassthru.h107
-rw-r--r--Core/EM/Nvme/NvmeSetup.c473
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeDef.h253
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.c1127
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.cif13
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs89
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.h222
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.mak95
-rw-r--r--Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl35
-rw-r--r--Core/EM/NvramSmi/NvramSmi.c1155
-rw-r--r--Core/EM/NvramSmi/NvramSmi.chmbin0 -> 45701 bytes
-rw-r--r--Core/EM/NvramSmi/NvramSmi.cif14
-rw-r--r--Core/EM/NvramSmi/NvramSmi.dxs79
-rw-r--r--Core/EM/NvramSmi/NvramSmi.mak108
-rw-r--r--Core/EM/NvramSmi/NvramSmi.sdl111
-rw-r--r--Core/EM/NvramSmi/NvramSmiDxe.dxs72
-rw-r--r--Core/EM/NvramSmi/NvramSmiPi1.dxs66
-rw-r--r--Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.c176
-rw-r--r--Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.cif11
-rw-r--r--Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.h64
-rw-r--r--Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.mak68
-rw-r--r--Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.sdl55
-rw-r--r--Core/EM/OFBD/CleanErrorLog/CleanErrorLog.c259
-rw-r--r--Core/EM/OFBD/CleanErrorLog/CleanErrorLog.cif11
-rw-r--r--Core/EM/OFBD/CleanErrorLog/CleanErrorLog.h71
-rw-r--r--Core/EM/OFBD/CleanErrorLog/CleanErrorLog.mak75
-rw-r--r--Core/EM/OFBD/CleanErrorLog/CleanErrorLog.sdl63
-rw-r--r--Core/EM/OFBD/DEFCFG/DefCfg.c269
-rw-r--r--Core/EM/OFBD/DEFCFG/DefCfg.cif11
-rw-r--r--Core/EM/OFBD/DEFCFG/DefCfg.h72
-rw-r--r--Core/EM/OFBD/DEFCFG/DefCfg.mak76
-rw-r--r--Core/EM/OFBD/DEFCFG/DefCfg.sdl56
-rw-r--r--Core/EM/OFBD/MEUD/InitMEUDString.c243
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/AutoUpdate.c519
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/AutoUpdate.cif13
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/AutoUpdate.dxs53
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/AutoUpdate.h98
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/AutoUpdate.mak78
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/AutoUpdate.sdl103
-rw-r--r--Core/EM/OFBD/MEUD/MEAU/MERegion.binbin0 -> 8388608 bytes
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.c746
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.chmbin0 -> 34024 bytes
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.cif19
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.h198
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.mak123
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.sd112
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.sdl121
-rw-r--r--Core/EM/OFBD/MEUD/MEUD.unibin0 -> 6004 bytes
-rw-r--r--Core/EM/OFBD/MEUD/MEUD_MSG.c119
-rw-r--r--Core/EM/OFBD/OEMCMD/OEMCMD.c368
-rw-r--r--Core/EM/OFBD/OEMCMD/OEMCMD.cif11
-rw-r--r--Core/EM/OFBD/OEMCMD/OEMCMD.h72
-rw-r--r--Core/EM/OFBD/OEMCMD/OEMCMD.mak74
-rw-r--r--Core/EM/OFBD/OEMCMD/OEMCMD.sdl56
-rw-r--r--Core/EM/OFBD/OEMOAHandle/OEMOAHandle.c233
-rw-r--r--Core/EM/OFBD/OEMOAHandle/OEMOAHandle.cif11
-rw-r--r--Core/EM/OFBD/OEMOAHandle/OEMOAHandle.h64
-rw-r--r--Core/EM/OFBD/OEMOAHandle/OEMOAHandle.mak68
-rw-r--r--Core/EM/OFBD/OEMOAHandle/OEMOAHandle.sdl56
-rw-r--r--Core/EM/OFBD/OEMPWDCK/OEMPwdCk.c250
-rw-r--r--Core/EM/OFBD/OEMPWDCK/OEMPwdCk.cif11
-rw-r--r--Core/EM/OFBD/OEMPWDCK/OEMPwdCk.h74
-rw-r--r--Core/EM/OFBD/OEMPWDCK/OEMPwdCk.mak76
-rw-r--r--Core/EM/OFBD/OEMPWDCK/OEMPwdCk.sdl65
-rw-r--r--Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.c253
-rw-r--r--Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.cif11
-rw-r--r--Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.h72
-rw-r--r--Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.mak74
-rw-r--r--Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.sdl76
-rw-r--r--Core/EM/OFBD/OEMROMID/OEMROMID.c220
-rw-r--r--Core/EM/OFBD/OEMROMID/OEMROMID.cif11
-rw-r--r--Core/EM/OFBD/OEMROMID/OEMROMID.h74
-rw-r--r--Core/EM/OFBD/OEMROMID/OEMROMID.mak75
-rw-r--r--Core/EM/OFBD/OEMROMID/OEMROMID.sdl102
-rw-r--r--Core/EM/OFBD/OEMSETUP/OEMSETUP.c361
-rw-r--r--Core/EM/OFBD/OEMSETUP/OEMSETUP.cif11
-rw-r--r--Core/EM/OFBD/OEMSETUP/OEMSETUP.h74
-rw-r--r--Core/EM/OFBD/OEMSETUP/OEMSETUP.mak87
-rw-r--r--Core/EM/OFBD/OEMSETUP/OEMSETUP.sdl71
-rw-r--r--Core/EM/OFBD/OFBD.c415
-rw-r--r--Core/EM/OFBD/OFBD.cif24
-rw-r--r--Core/EM/OFBD/OFBD.dxs84
-rw-r--r--Core/EM/OFBD/OFBD.h647
-rw-r--r--Core/EM/OFBD/OFBD.mak111
-rw-r--r--Core/EM/OFBD/OFBD.sdl68
-rw-r--r--Core/EM/OFBD/OFBD_Help.chmbin0 -> 55276 bytes
-rw-r--r--Core/EM/OFBD/SecureFlash/SecureFlash.c343
-rw-r--r--Core/EM/OFBD/SecureFlash/SecureFlash.chmbin0 -> 29136 bytes
-rw-r--r--Core/EM/OFBD/SecureFlash/SecureFlash.cif12
-rw-r--r--Core/EM/OFBD/SecureFlash/SecureFlash.h68
-rw-r--r--Core/EM/OFBD/SecureFlash/SecureFlash.mak76
-rw-r--r--Core/EM/OFBD/SecureFlash/SecureFlash.sdl51
-rw-r--r--Core/EM/OFBD/StdEC/StdEC.c531
-rw-r--r--Core/EM/OFBD/StdEC/StdEC.cif11
-rw-r--r--Core/EM/OFBD/StdEC/StdEC.h102
-rw-r--r--Core/EM/OFBD/StdEC/StdEC.mak75
-rw-r--r--Core/EM/OFBD/StdEC/StdEC.sdl39
-rw-r--r--Core/EM/OemActivation/OemActivation.c505
-rw-r--r--Core/EM/OemActivation/OemActivation.chmbin0 -> 55618 bytes
-rw-r--r--Core/EM/OemActivation/OemActivation.cif16
-rw-r--r--Core/EM/OemActivation/OemActivation.dxs93
-rw-r--r--Core/EM/OemActivation/OemActivation.h194
-rw-r--r--Core/EM/OemActivation/OemActivation.mak159
-rw-r--r--Core/EM/OemActivation/OemActivation.sdl79
-rw-r--r--Core/EM/OemActivation/OemActivationHook.c116
-rw-r--r--Core/EM/OemActivation/SmmOemActivation.c491
-rw-r--r--Core/EM/OemActivation/SmmOemActivation.cif11
-rw-r--r--Core/EM/OemActivation/SmmOemActivation.dxs83
-rw-r--r--Core/EM/OemActivation/SmmOemActivation.mak75
-rw-r--r--Core/EM/OemActivation/SmmOemActivation.sdl32
-rw-r--r--Core/EM/OpalSecurity/AHCIOpalSec.c312
-rw-r--r--Core/EM/OpalSecurity/IDEOpalSec.c321
-rw-r--r--Core/EM/OpalSecurity/OpalSecurity.c553
-rw-r--r--Core/EM/OpalSecurity/OpalSecurity.chmbin0 -> 54923 bytes
-rw-r--r--Core/EM/OpalSecurity/OpalSecurity.cif14
-rw-r--r--Core/EM/OpalSecurity/OpalSecurity.h227
-rw-r--r--Core/EM/OpalSecurity/OpalSecurity.mak66
-rw-r--r--Core/EM/OpalSecurity/OpalSecurity.sdl33
-rw-r--r--Core/EM/PCI/DeviceIo.c696
-rw-r--r--Core/EM/PCI/PciBus.c13734
-rw-r--r--Core/EM/PCI/PciBus.chmbin0 -> 89243 bytes
-rw-r--r--Core/EM/PCI/PciBus.cif19
-rw-r--r--Core/EM/PCI/PciBus.mak152
-rw-r--r--Core/EM/PCI/PciBus.sd1067
-rw-r--r--Core/EM/PCI/PciBus.sdl351
-rw-r--r--Core/EM/PCI/PciBus.unibin0 -> 34772 bytes
-rw-r--r--Core/EM/PCI/PciBusSetup.c97
-rw-r--r--Core/EM/PCI/PciBusSrc.chmbin0 -> 179322 bytes
-rw-r--r--Core/EM/PCI/PciBusSrc.cif13
-rw-r--r--Core/EM/PCI/PciBusSrc.mak82
-rw-r--r--Core/EM/PCI/PciBusSrc.sdl37
-rw-r--r--Core/EM/PCI/PciHostBridge.c3814
-rw-r--r--Core/EM/PCI/PciPort.c926
-rw-r--r--Core/EM/PCI/PciPort.h136
-rw-r--r--Core/EM/PCI/PciRootBridge.dxs67
-rw-r--r--Core/EM/PCI/PciSetup.h155
-rw-r--r--Core/EM/PS2CTL/Names.c269
-rw-r--r--Core/EM/PS2CTL/PS2Ctl.cif19
-rw-r--r--Core/EM/PS2CTL/PS2Ctl.sdl6
-rw-r--r--Core/EM/PS2CTL/Ps2Ctl.chmbin0 -> 138933 bytes
-rw-r--r--Core/EM/PS2CTL/efismplpp.c256
-rw-r--r--Core/EM/PS2CTL/hotkey.c420
-rw-r--r--Core/EM/PS2CTL/kbc.c1495
-rw-r--r--Core/EM/PS2CTL/kbc.h321
-rw-r--r--Core/EM/PS2CTL/mouse.c1215
-rw-r--r--Core/EM/PS2CTL/ps2ctl.h178
-rw-r--r--Core/EM/PS2CTL/ps2kbd.c2888
-rw-r--r--Core/EM/PS2CTL/ps2main.c655
-rw-r--r--Core/EM/PS2CTL/ps2mouse.h178
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.c783
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.chmbin0 -> 33976 bytes
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.cif19
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.dxs66
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.h162
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.mak242
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBoot.sdl196
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBootCacheRdy.c114
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBootCacheRdy.dxs57
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBootDxe.c368
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBootFvHook.c184
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBootHook.c282
-rw-r--r--Core/EM/PeiRamBoot/PeiRamBootOfbd.c185
-rw-r--r--Core/EM/PlatformToDriver/PlatformToDriver.c199
-rw-r--r--Core/EM/PlatformToDriver/PlatformToDriver.cif10
-rw-r--r--Core/EM/PlatformToDriver/PlatformToDriver.mak58
-rw-r--r--Core/EM/PlatformToDriver/PlatformToDriver.sdl31
-rw-r--r--Core/EM/Recovery/CapsuleRecovery.c278
-rw-r--r--Core/EM/Recovery/FsRecovery.c3193
-rw-r--r--Core/EM/Recovery/IdeRecovery.c2172
-rw-r--r--Core/EM/Recovery/ReFlash/Esrt.c415
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.c601
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.cif16
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.dxs72
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.h268
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.mak135
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.sdl135
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.unibin0 -> 13216 bytes
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlash.vfr240
-rw-r--r--Core/EM/Recovery/ReFlash/ReFlashWorker.c720
-rw-r--r--Core/EM/Recovery/Recovery.c720
-rw-r--r--Core/EM/Recovery/Recovery.cif16
-rw-r--r--Core/EM/Recovery/Recovery.dxs57
-rw-r--r--Core/EM/Recovery/Recovery.h113
-rw-r--r--Core/EM/Recovery/Recovery.mak116
-rw-r--r--Core/EM/Recovery/Recovery.sdl235
-rw-r--r--Core/EM/Recovery/RecoveryCsp.h849
-rw-r--r--Core/EM/Recovery/RecoverySrc.cif13
-rw-r--r--Core/EM/Recovery/RecoverySrc.mak81
-rw-r--r--Core/EM/Recovery/RecoverySrc.sdl21
-rw-r--r--Core/EM/Recovery/SerialRecovery.c1047
-rw-r--r--Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.c178
-rw-r--r--Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.chmbin0 -> 34662 bytes
-rw-r--r--Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.cif11
-rw-r--r--Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.mak73
-rw-r--r--Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.sdl39
-rw-r--r--Core/EM/Runtime/CpuIoDxe.c547
-rw-r--r--Core/EM/Runtime/Flash.c1014
-rw-r--r--Core/EM/Runtime/Runtime.c579
-rw-r--r--Core/EM/Runtime/Runtime.cif10
-rw-r--r--Core/EM/Runtime/Runtime.dxs49
-rw-r--r--Core/EM/Runtime/Runtime.mak102
-rw-r--r--Core/EM/Runtime/Runtime.sdl129
-rw-r--r--Core/EM/Runtime/RuntimeSrc.cif13
-rw-r--r--Core/EM/Runtime/RuntimeSrc.mak74
-rw-r--r--Core/EM/Runtime/RuntimeSrc.sdl57
-rw-r--r--Core/EM/Runtime/TimeAndReset.C1191
-rw-r--r--Core/EM/S3/AcpiPeiS3Func.c141
-rw-r--r--Core/EM/S3/AcpiPeiS3Func.h83
-rw-r--r--Core/EM/S3/AcpiS3Save.c468
-rw-r--r--Core/EM/S3/AcpiS3Save.dxs70
-rw-r--r--Core/EM/S3/AcpiS3Wake.asm339
-rw-r--r--Core/EM/S3/BootScriptExecuter.c1053
-rw-r--r--Core/EM/S3/BootScriptPrivate.h732
-rw-r--r--Core/EM/S3/BootScriptSave.c2540
-rw-r--r--Core/EM/S3/S3Restore.cif15
-rw-r--r--Core/EM/S3/S3Restore.mak88
-rw-r--r--Core/EM/S3/S3Restore.sdl25
-rw-r--r--Core/EM/S3/S3Resume.c582
-rw-r--r--Core/EM/S3/S3Resume.dxs85
-rw-r--r--Core/EM/S3/S3Save.cif14
-rw-r--r--Core/EM/S3/S3Save.mak99
-rw-r--r--Core/EM/S3/S3Save.sdl25
-rw-r--r--Core/EM/S3/S3Support.cif12
-rw-r--r--Core/EM/S3/S3Support.sdl9
-rw-r--r--Core/EM/S3/SmmS3Save.dxs70
-rw-r--r--Core/EM/SMBIOS/SMBIOSCore.CIF17
-rw-r--r--Core/EM/SMBIOS/SMBios.c8091
-rw-r--r--Core/EM/SMBIOS/SMBios.dxs142
-rw-r--r--Core/EM/SMBIOS/SMBios.mak99
-rw-r--r--Core/EM/SMBIOS/SMBiosCore.chmbin0 -> 369975 bytes
-rw-r--r--Core/EM/SMBIOS/SMBiosCoreSrc.sdl33
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c792
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif14
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs78
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h377
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak145
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl79
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c4176
-rw-r--r--Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c386
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm67
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif11
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak86
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl37
-rw-r--r--Core/EM/SMBIOS/SmbiosFlashData/pad.txt1
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c497
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif11
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs70
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak82
-rw-r--r--Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl36
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c201
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif11
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs66
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak89
-rw-r--r--Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl32
-rw-r--r--Core/EM/SMIFlash/SMIFlash.c990
-rw-r--r--Core/EM/SMIFlash/SMIFlash.chmbin0 -> 35457 bytes
-rw-r--r--Core/EM/SMIFlash/SMIFlash.cif16
-rw-r--r--Core/EM/SMIFlash/SMIFlash.dxs103
-rw-r--r--Core/EM/SMIFlash/SMIFlash.mak183
-rw-r--r--Core/EM/SMIFlash/SMIFlash.sdl349
-rw-r--r--Core/EM/SMIFlash/SMIFlashDxe.dxs72
-rw-r--r--Core/EM/SMIFlash/SMIFlashLinks.c2227
-rw-r--r--Core/EM/SMM/SMM.cif19
-rw-r--r--Core/EM/SMM/SMM.sdl101
-rw-r--r--Core/EM/SMM/Smm.chmbin0 -> 123054 bytes
-rw-r--r--Core/EM/SMM/SmmBase.c911
-rw-r--r--Core/EM/SMM/SmmBase.cif15
-rw-r--r--Core/EM/SMM/SmmBase.dxs107
-rw-r--r--Core/EM/SMM/SmmBase.mak84
-rw-r--r--Core/EM/SMM/SmmBase.sdl25
-rw-r--r--Core/EM/SMM/SmmBase2.c102
-rw-r--r--Core/EM/SMM/SmmBaseAsm.asm139
-rw-r--r--Core/EM/SMM/SmmCommunicate.c462
-rw-r--r--Core/EM/SMM/SmmCommunicate.cif12
-rw-r--r--Core/EM/SMM/SmmCommunicate.dxs67
-rw-r--r--Core/EM/SMM/SmmCommunicate.mak91
-rw-r--r--Core/EM/SMM/SmmCommunicate.sdl44
-rw-r--r--Core/EM/SMM/SmmDispatcher.c1533
-rw-r--r--Core/EM/SMM/SmmDispatcher.cif17
-rw-r--r--Core/EM/SMM/SmmDispatcher.dxs59
-rw-r--r--Core/EM/SMM/SmmDispatcher.h253
-rw-r--r--Core/EM/SMM/SmmDispatcher.mak127
-rw-r--r--Core/EM/SMM/SmmDispatcher.sdl35
-rw-r--r--Core/EM/SMM/SmmDispatcherAsm.asm196
-rw-r--r--Core/EM/SMM/SmmDriverDispatcher.c1694
-rw-r--r--Core/EM/SMM/SmmDxeCommunicate.dxs69
-rw-r--r--Core/EM/SMM/SmmEntry.asm1041
-rw-r--r--Core/EM/SMM/SmmHdr.equ286
-rw-r--r--Core/EM/SMM/SmmInit.c1319
-rw-r--r--Core/EM/SMM/SmmMemoryManager.c962
-rw-r--r--Core/EM/SMM/SmmPiSmst.c1827
-rw-r--r--Core/EM/SMM/SmmPrivateShared.h392
-rw-r--r--Core/EM/SMM/Smst.c917
-rw-r--r--Core/EM/SecurityPkg/AuthenticatedVariable/Auth2Variable.c869
-rw-r--r--Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.c1729
-rw-r--r--Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.cif12
-rw-r--r--Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.h351
-rw-r--r--Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.mak89
-rw-r--r--Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.sdl44
-rw-r--r--Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.c2431
-rw-r--r--Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.h175
-rw-r--r--Core/EM/SecurityPkg/ImageVerificationLib/EfiImage.h702
-rw-r--r--Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.cif12
-rw-r--r--Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.mak92
-rw-r--r--Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.sdl109
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c325
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs89
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c390
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif17
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak176
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl152
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c276
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs58
-rw-r--r--Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c974
-rw-r--r--Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.c1810
-rw-r--r--Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.cif16
-rw-r--r--Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.dxs67
-rw-r--r--Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.mak108
-rw-r--r--Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.sdl74
-rw-r--r--Core/EM/SecurityPkg/SecSMIFlash/VerifyFwCapsule.c790
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.c2503
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.chmbin0 -> 2097632 bytes
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.cif21
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.dxs51
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.h116
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.mak153
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.sd685
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.sdl277
-rw-r--r--Core/EM/SecurityPkg/SecureBootMod.unibin0 -> 22308 bytes
-rw-r--r--Core/EM/SecurityPkg/SecureMod.chmbin0 -> 1872070 bytes
-rw-r--r--Core/EM/SecurityPkg/SecureMod.cif17
-rw-r--r--Core/EM/SecurityPkg/SecureMod.mak458
-rw-r--r--Core/EM/SecurityPkg/SecureMod.sdl315
-rw-r--r--Core/EM/Sredir/LegacySmmSredir.c474
-rw-r--r--Core/EM/Sredir/LegacySredir.c1422
-rw-r--r--Core/EM/Sredir/LegacySredir.chmbin0 -> 220047 bytes
-rw-r--r--Core/EM/Sredir/LegacySredir.cif19
-rw-r--r--Core/EM/Sredir/LegacySredir.dxs104
-rw-r--r--Core/EM/Sredir/LegacySredir.mak135
-rw-r--r--Core/EM/Sredir/LegacySredir.sdl164
-rw-r--r--Core/EM/Sredir/SerialBootCall.asm180
-rw-r--r--Core/EM/Sredir/SredirBootFail.asm179
-rw-r--r--Core/EM/StatusCode/SerialStatusCode.c358
-rw-r--r--Core/EM/StatusCode/StatusCode.chmbin0 -> 87667 bytes
-rw-r--r--Core/EM/StatusCode/StatusCode.cif17
-rw-r--r--Core/EM/StatusCode/StatusCode.mak200
-rw-r--r--Core/EM/StatusCode/StatusCode.sdl280
-rw-r--r--Core/EM/StatusCode/StatusCodeCommon.c1142
-rw-r--r--Core/EM/StatusCode/StatusCodeDxe.c883
-rw-r--r--Core/EM/StatusCode/StatusCodeInt.h125
-rw-r--r--Core/EM/StatusCode/StatusCodeMap.c278
-rw-r--r--Core/EM/StatusCode/StatusCodePei.c492
-rw-r--r--Core/EM/StatusCode/StatusCodeRuntime.c768
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c171
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif13
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h140
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak87
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl61
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c707
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h170
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h99
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif12
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak52
-rw-r--r--Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl20
-rw-r--r--Core/EM/TCG2/Common/AmiTcgNvflagSample.c580
-rw-r--r--Core/EM/TCG2/Common/AmiTcgNvflagSample.cif12
-rw-r--r--Core/EM/TCG2/Common/AmiTcgNvflagSample.dxs44
-rw-r--r--Core/EM/TCG2/Common/AmiTcgNvflagSample.h199
-rw-r--r--Core/EM/TCG2/Common/AmiTcgNvflagSample.mak75
-rw-r--r--Core/EM/TCG2/Common/AmiTcgNvflagSample.sdl66
-rw-r--r--Core/EM/TCG2/Common/Common.cif21
-rw-r--r--Core/EM/TCG2/Common/CommonHeaders.cif19
-rw-r--r--Core/EM/TCG2/Common/EMpCallBin.asm337
-rw-r--r--Core/EM/TCG2/Common/EMpCallBin32.asm251
-rw-r--r--Core/EM/TCG2/Common/EMpTcmDxe.c482
-rw-r--r--Core/EM/TCG2/Common/EMpTcmPei.c691
-rw-r--r--Core/EM/TCG2/Common/PPI/TcgService/TcgService.c64
-rw-r--r--Core/EM/TCG2/Common/PPI/TcgService/TcgService.h122
-rw-r--r--Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.c73
-rw-r--r--Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.h181
-rw-r--r--Core/EM/TCG2/Common/PPI/TcgService_PPI.cif11
-rw-r--r--Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.c97
-rw-r--r--Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.h179
-rw-r--r--Core/EM/TCG2/Common/PPI/TpmDevice_PPI.cif9
-rw-r--r--Core/EM/TCG2/Common/Protocol/TcgService/TcgService.c66
-rw-r--r--Core/EM/TCG2/Common/Protocol/TcgService/TcgService.h171
-rw-r--r--Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.c75
-rw-r--r--Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.h167
-rw-r--r--Core/EM/TCG2/Common/Protocol/TcgService_Protocol.cif11
-rw-r--r--Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.c60
-rw-r--r--Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.h197
-rw-r--r--Core/EM/TCG2/Common/Protocol/TpmDevice_Protocol.cif9
-rw-r--r--Core/EM/TCG2/Common/TCGMisc.h822
-rw-r--r--Core/EM/TCG2/Common/TCGSmm/TCGSmm.DXS84
-rw-r--r--Core/EM/TCG2/Common/TCGSmm/TCGSmm.c956
-rw-r--r--Core/EM/TCG2/Common/TCGSmm/TCGSmm.cif12
-rw-r--r--Core/EM/TCG2/Common/TCGSmm/TCGSmm.h104
-rw-r--r--Core/EM/TCG2/Common/TCGSmm/TCGSmm.mak101
-rw-r--r--Core/EM/TCG2/Common/TCGSmm/TCGSmm.sdl24
-rw-r--r--Core/EM/TCG2/Common/TcgCRBPei.c537
-rw-r--r--Core/EM/TCG2/Common/TcgDxe.c2187
-rw-r--r--Core/EM/TCG2/Common/TcgDxe.cif17
-rw-r--r--Core/EM/TCG2/Common/TcgDxe.dxs110
-rw-r--r--Core/EM/TCG2/Common/TcgDxe.mak196
-rw-r--r--Core/EM/TCG2/Common/TcgDxe.sdl27
-rw-r--r--Core/EM/TCG2/Common/TcgDxe20.c853
-rw-r--r--Core/EM/TCG2/Common/TcgLegacy.c977
-rw-r--r--Core/EM/TCG2/Common/TcgLegacy.cif12
-rw-r--r--Core/EM/TCG2/Common/TcgLegacy.dxs71
-rw-r--r--Core/EM/TCG2/Common/TcgLegacy.h213
-rw-r--r--Core/EM/TCG2/Common/TcgLegacy.mak104
-rw-r--r--Core/EM/TCG2/Common/TcgLegacy.sdl36
-rw-r--r--Core/EM/TCG2/Common/TcgPei.cif18
-rw-r--r--Core/EM/TCG2/Common/TcgPei.dxs114
-rw-r--r--Core/EM/TCG2/Common/TcgPei.mak123
-rw-r--r--Core/EM/TCG2/Common/TcgPei.sdl34
-rw-r--r--Core/EM/TCG2/Common/TcgPeiAfterMem.c492
-rw-r--r--Core/EM/TCG2/Common/TcgPeiAfterMem.cif11
-rw-r--r--Core/EM/TCG2/Common/TcgPeiAfterMem.mak149
-rw-r--r--Core/EM/TCG2/Common/TcgPrivate.c70
-rw-r--r--Core/EM/TCG2/Common/TcgPrivate.h400
-rw-r--r--Core/EM/TCG2/Common/TcgTcmPei.c476
-rw-r--r--Core/EM/TCG2/Common/TcgTcmPeiAfterMem.c538
-rw-r--r--Core/EM/TCG2/Common/TcgTisPei.c538
-rw-r--r--Core/EM/TCG2/Common/TisPei.c691
-rw-r--r--Core/EM/TCG2/Common/Tpm20Includes/Tpm20.h1917
-rw-r--r--Core/EM/TCG2/Common/Tpm20Includes/Tpm20Includes.cif10
-rw-r--r--Core/EM/TCG2/Common/Tpm20Includes/Tpm20Pei.h32
-rw-r--r--Core/EM/TCG2/Common/Tpm20Includes/TrEEProtocol.h152
-rw-r--r--Core/EM/TCG2/Common/TpmDxe.c545
-rw-r--r--Core/EM/TCG2/Common/xTcgDxe.c1835
-rw-r--r--Core/EM/TCG2/Common/xTcgPei.c317
-rw-r--r--Core/EM/TCG2/Common/xTcgPeiAfterMem.c284
-rw-r--r--Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.cif10
-rw-r--r--Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.libbin0 -> 39300 bytes
-rw-r--r--Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.sdl27
-rw-r--r--Core/EM/TCG2/CommonLibraries/ShaLib/ShaLibPei.libbin0 -> 36454 bytes
-rw-r--r--Core/EM/TCG2/Libraries.cif10
-rw-r--r--Core/EM/TCG2/TCG2.chmbin0 -> 132919 bytes
-rw-r--r--Core/EM/TCG2/Tcg.cif13
-rw-r--r--Core/EM/TCG2/Tcg.sdl646
-rw-r--r--Core/EM/TCG2/TisLib/INTTcgAcpi.h114
-rw-r--r--Core/EM/TCG2/TisLib/TcgCommon.c808
-rw-r--r--Core/EM/TCG2/TisLib/TcgCommon.h305
-rw-r--r--Core/EM/TCG2/TisLib/TcgEFI12.h186
-rw-r--r--Core/EM/TCG2/TisLib/TcgEfiTpm.h220
-rw-r--r--Core/EM/TCG2/TisLib/TcgPc.h311
-rw-r--r--Core/EM/TCG2/TisLib/TcgTpm12.h1973
-rw-r--r--Core/EM/TCG2/TisLib/TcmPc.h153
-rw-r--r--Core/EM/TCG2/TisLib/TisLib.cif23
-rw-r--r--Core/EM/TCG2/TisLib/TisLib.mak116
-rw-r--r--Core/EM/TCG2/TisLib/TisLib.sdl46
-rw-r--r--Core/EM/TCG2/TisLib/TpmLib.c614
-rw-r--r--Core/EM/TCG2/TisLib/TpmLib.h136
-rw-r--r--Core/EM/TCG2/TisLib/ZTEICTcmOrdinals.h203
-rw-r--r--Core/EM/TCG2/TisLib/sha.h122
-rw-r--r--Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.c125
-rw-r--r--Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.cif12
-rw-r--r--Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.dxs68
-rw-r--r--Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.h74
-rw-r--r--Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.mak91
-rw-r--r--Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.sdl71
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.c132
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.cif17
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.dxs75
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.h69
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.mak107
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.sdl41
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackSmiFlash.c160
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c584
-rw-r--r--Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.h198
-rw-r--r--Core/EM/Terminal/InitTerminalStrings.c349
-rw-r--r--Core/EM/Terminal/Terminal.chmbin0 -> 158117 bytes
-rw-r--r--Core/EM/Terminal/Terminal.cif21
-rw-r--r--Core/EM/Terminal/Terminal.libbin0 -> 61392 bytes
-rw-r--r--Core/EM/Terminal/Terminal.mak165
-rw-r--r--Core/EM/Terminal/Terminal.sd1533
-rw-r--r--Core/EM/Terminal/Terminal.sdl796
-rw-r--r--Core/EM/Terminal/Terminal.unibin0 -> 26732 bytes
-rw-r--r--Core/EM/Terminal/TerminalAcpi.c179
-rw-r--r--Core/EM/Terminal/TerminalBoard.h404
-rw-r--r--Core/EM/Terminal/TerminalSetup.c1788
-rw-r--r--Core/EM/Terminal/TerminalSetupVar.h167
-rw-r--r--Core/EM/Terminal/Terminalx64.libbin0 -> 80684 bytes
-rw-r--r--Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.c208
-rw-r--r--Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.chmbin0 -> 31698 bytes
-rw-r--r--Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.cif12
-rw-r--r--Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.h70
-rw-r--r--Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.mak67
-rw-r--r--Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.sdl25
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Arp/Arp.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Arp/Arp.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Arp/Arp.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Arp/ArpDxe.efibin0 -> 12832 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Arp/ArpDxeIa32.efibin0 -> 9664 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxe.efibin0 -> 2176 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxeIa32.efibin0 -> 1504 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxe.efibin0 -> 530112 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxeIa32.efibin0 -> 403072 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxe.efibin0 -> 26496 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxeIa32.efibin0 -> 19328 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.c93
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.cif13
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.h82
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.mak68
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sd246
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sdl38
-rw-r--r--Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.unibin0 -> 7668 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Snp/Snp.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Snp/Snp.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Snp/Snp.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Snp/SnpDxe.efibin0 -> 20960 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Snp/SnpDxeIa32.efibin0 -> 15488 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxe.efibin0 -> 49312 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxeIa32.efibin0 -> 36768 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/UefiCommonNetworkStackII.cif15
-rw-r--r--Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxe.efibin0 -> 57088 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxeIa32.efibin0 -> 41824 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4Dxe.efibin0 -> 30880 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4DxeIa32.efibin0 -> 21216 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4Dxe.efibin0 -> 41824 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4DxeIa32.efibin0 -> 29824 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxe.efibin0 -> 18432 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxeIa32.efibin0 -> 13152 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4Dxe.efibin0 -> 29312 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4DxeIa32.efibin0 -> 20512 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4Dxe.efibin0 -> 27232 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4DxeIa32.efibin0 -> 19296 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.cif14
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.sdl11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6Dxe.efibin0 -> 35168 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6DxeIa32.efibin0 -> 25280 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6Dxe.efibin0 -> 73760 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6DxeIa32.efibin0 -> 53952 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6Dxe.efibin0 -> 29568 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6DxeIa32.efibin0 -> 21760 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.cif11
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.mak59
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.sdl26
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6Dxe.efibin0 -> 26400 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6DxeIa32.efibin0 -> 19136 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.cif13
-rw-r--r--Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.sdl11
-rw-r--r--Core/EM/UEfiNetworkStack/UefiNetworkStackII.chmbin0 -> 50889 bytes
-rw-r--r--Core/EM/UEfiNetworkStack/UefiNetworkStackII.cif13
-rw-r--r--Core/EM/UEfiNetworkStack/UefiNetworkStackII.sdl11
-rw-r--r--Core/EM/UsbRecovery/AmiMapping.h102
-rw-r--r--Core/EM/UsbRecovery/EhciPEI/EhciPei.c1847
-rw-r--r--Core/EM/UsbRecovery/EhciPEI/EhciPei.cif10
-rw-r--r--Core/EM/UsbRecovery/EhciPEI/EhciPei.h592
-rw-r--r--Core/EM/UsbRecovery/EhciPEI/EhciPeiBoard.c108
-rw-r--r--Core/EM/UsbRecovery/HubPeim.h317
-rw-r--r--Core/EM/UsbRecovery/OhciPEI/OhciPei.c1455
-rw-r--r--Core/EM/UsbRecovery/OhciPEI/OhciPei.cif12
-rw-r--r--Core/EM/UsbRecovery/OhciPEI/OhciPei.h909
-rw-r--r--Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c508
-rw-r--r--Core/EM/UsbRecovery/PeiUsbLib.c825
-rw-r--r--Core/EM/UsbRecovery/PeiUsbLib.h171
-rw-r--r--Core/EM/UsbRecovery/USBRecoverySrc.chmbin0 -> 150255 bytes
-rw-r--r--Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.c3575
-rw-r--r--Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.h865
-rw-r--r--Core/EM/UsbRecovery/UhcPeimSrc/UhcPeimSrc.cif11
-rw-r--r--Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.c376
-rw-r--r--Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.cif10
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c482
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h201
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c832
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c726
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif14
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs106
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h362
-rw-r--r--Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h418
-rw-r--r--Core/EM/UsbRecovery/UsbPeim.h244
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c889
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c334
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c1006
-rw-r--r--Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif12
-rw-r--r--Core/EM/UsbRecovery/UsbRecov.mak457
-rw-r--r--Core/EM/UsbRecovery/UsbRecov.sdl237
-rw-r--r--Core/EM/UsbRecovery/UsbRecovery.cif24
-rw-r--r--Core/EM/UsbRecovery/XhciPEI/XhciPei.c2314
-rw-r--r--Core/EM/UsbRecovery/XhciPEI/XhciPei.cif9
-rw-r--r--Core/EM/UsbRecovery/XhciPEI/XhciPei.h1245
-rw-r--r--Core/EM/UsbRecovery/usb.h511
-rw-r--r--Core/EM/usb/AmiUsbLib/AmiUsbLib.cif11
-rw-r--r--Core/EM/usb/AmiUsbLib/AmiUsbLib.sdl20
-rw-r--r--Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.c487
-rw-r--r--Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.cif10
-rw-r--r--Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.mak51
-rw-r--r--Core/EM/usb/AmiUsbLib/Crc32.c117
-rw-r--r--Core/EM/usb/UsbLegacy.cif8
-rw-r--r--Core/EM/usb/amiusbhc.c3330
-rw-r--r--Core/EM/usb/componentname.c331
-rw-r--r--Core/EM/usb/componentname.h117
-rw-r--r--Core/EM/usb/efiusbccid.c1285
-rw-r--r--Core/EM/usb/efiusbhid.c534
-rw-r--r--Core/EM/usb/efiusbkb.c3036
-rw-r--r--Core/EM/usb/efiusbkb.h462
-rw-r--r--Core/EM/usb/efiusbmass.c1235
-rw-r--r--Core/EM/usb/efiusbms.c670
-rw-r--r--Core/EM/usb/efiusbpoint.c500
-rw-r--r--Core/EM/usb/framework.cif16
-rw-r--r--Core/EM/usb/int13/UsbBbs.c87
-rw-r--r--Core/EM/usb/int13/UsbInt13.c995
-rw-r--r--Core/EM/usb/int13/UsbInt13.cif17
-rw-r--r--Core/EM/usb/int13/UsbInt13.dxs39
-rw-r--r--Core/EM/usb/int13/UsbInt13.h178
-rw-r--r--Core/EM/usb/int13/UsbInt13.inf5
-rw-r--r--Core/EM/usb/int13/UsbInt13.mak79
-rw-r--r--Core/EM/usb/int13/UsbInt13.sdl48
-rw-r--r--Core/EM/usb/int13/UsbInt13ComponentName.c195
-rw-r--r--Core/EM/usb/rt/UsbMass.h465
-rw-r--r--Core/EM/usb/rt/amidef.h503
-rw-r--r--Core/EM/usb/rt/amiusb.c3402
-rw-r--r--Core/EM/usb/rt/amiusb.dxs44
-rw-r--r--Core/EM/usb/rt/amiusb.h437
-rw-r--r--Core/EM/usb/rt/amiusbrtCCID.h836
-rw-r--r--Core/EM/usb/rt/debug.c110
-rw-r--r--Core/EM/usb/rt/ehci.c5916
-rw-r--r--Core/EM/usb/rt/ehci.h420
-rw-r--r--Core/EM/usb/rt/elib.c659
-rw-r--r--Core/EM/usb/rt/guids.c147
-rw-r--r--Core/EM/usb/rt/ohci.c3379
-rw-r--r--Core/EM/usb/rt/ohci.h609
-rw-r--r--Core/EM/usb/rt/syskbc.c3225
-rw-r--r--Core/EM/usb/rt/sysnokbc.c1146
-rw-r--r--Core/EM/usb/rt/uhci.c3981
-rw-r--r--Core/EM/usb/rt/uhci.h271
-rw-r--r--Core/EM/usb/rt/usb.c5300
-rw-r--r--Core/EM/usb/rt/usbCCID.c5033
-rw-r--r--Core/EM/usb/rt/usbdef.h2221
-rw-r--r--Core/EM/usb/rt/usbhid.c1474
-rw-r--r--Core/EM/usb/rt/usbhub.c1491
-rw-r--r--Core/EM/usb/rt/usbkbd.c1315
-rw-r--r--Core/EM/usb/rt/usbkbd.h436
-rw-r--r--Core/EM/usb/rt/usbmass.c5506
-rw-r--r--Core/EM/usb/rt/usbms.c774
-rw-r--r--Core/EM/usb/rt/usbpoint.c474
-rw-r--r--Core/EM/usb/rt/usbrt.cif31
-rw-r--r--Core/EM/usb/rt/usbrt.mak241
-rw-r--r--Core/EM/usb/rt/xhci.c4306
-rw-r--r--Core/EM/usb/rt/xhci.h1189
-rw-r--r--Core/EM/usb/setup/usb.sd1256
-rw-r--r--Core/EM/usb/setup/usb.unibin0 -> 19750 bytes
-rw-r--r--Core/EM/usb/setup/usbsetup.c804
-rw-r--r--Core/EM/usb/setup/usbsetup.cif10
-rw-r--r--Core/EM/usb/tree.c374
-rw-r--r--Core/EM/usb/tree.h95
-rw-r--r--Core/EM/usb/uhcd.c2896
-rw-r--r--Core/EM/usb/uhcd.cif24
-rw-r--r--Core/EM/usb/uhcd.dxs42
-rw-r--r--Core/EM/usb/uhcd.h641
-rw-r--r--Core/EM/usb/uhcd.mak128
-rw-r--r--Core/EM/usb/usbbus.c3118
-rw-r--r--Core/EM/usb/usbbus.h310
-rw-r--r--Core/EM/usb/usbmisc.c582
-rw-r--r--Core/EM/usb/usbsrc.sdl368
-rw-r--r--Core/EdkLib.c627
-rw-r--r--Core/EfiCommonLib.h1216
-rw-r--r--Core/EfiDebug.h174
-rw-r--r--Core/EfiDependency.h52
-rw-r--r--Core/EfiFirmwareFileSystem.h49
-rw-r--r--Core/EfiFirmwareVolumeHeader.h88
-rw-r--r--Core/EfiHobLib.h287
-rw-r--r--Core/EfiImage.h742
-rw-r--r--Core/EfiImageFormat.h125
-rw-r--r--Core/FFS.mak393
-rw-r--r--Core/FV.mak215
-rw-r--r--Core/FileSystem.ffsbin0 -> 14697 bytes
-rw-r--r--Core/FileSystemx64.ffsbin0 -> 17500 bytes
-rw-r--r--Core/FloppyCtrl.ffsbin0 -> 5364 bytes
-rw-r--r--Core/Foundation.cif66
-rw-r--r--Core/Foundation.mak126
-rw-r--r--Core/Foundation.sdl19
-rw-r--r--Core/GUID/Apriori.h62
-rw-r--r--Core/GUID/DebugImageInfoTable.h98
-rw-r--r--Core/GUID/DxeServices.h62
-rw-r--r--Core/GUID/EventGroup.h73
-rw-r--r--Core/GUID/EventLegacyBios.h62
-rw-r--r--Core/GUID/FirmwareFileSystem.h64
-rw-r--r--Core/GUID/FirmwareFileSystem2.h33
-rw-r--r--Core/GUID/FrameworkDevicePath.h64
-rw-r--r--Core/GUID/GenericVariable.h65
-rw-r--r--Core/GUID/Hob.h62
-rw-r--r--Core/GUID/MemoryTypeInformation.h71
-rw-r--r--Core/GUID/PeiApriori.h36
-rw-r--r--Core/GUID/PeiFlushInstructionCache.h23
-rw-r--r--Core/GUID/PeiPeCoffLoader.h119
-rw-r--r--Core/GUID/PeiTransferControl.h32
-rw-r--r--Core/GUID/StatusCode.h33
-rw-r--r--Core/GUID/StatusCodeCallerId.h67
-rw-r--r--Core/GUID/StatusCodeDataTypeId.h508
-rw-r--r--Core/InitList.c86
-rw-r--r--Core/Languages.mak109
-rw-r--r--Core/PPI/DxeIpl.h65
-rw-r--r--Core/PPI/FindFv.h80
-rw-r--r--Core/PPI/FirmwareVolume.h99
-rw-r--r--Core/PPI/GuidedSectionExtraction.h42
-rw-r--r--Core/PPI/LoadFile2.h5
-rw-r--r--Core/PPI/MemoryDiscovered.h65
-rw-r--r--Core/PPI/SectionExtraction.h59
-rw-r--r--Core/PPI/Security.h83
-rw-r--r--Core/PPI/Security2.h54
-rw-r--r--Core/PPI/StatusCode.h56
-rw-r--r--Core/PeCoffLoader.c1467
-rw-r--r--Core/PeiApi.h0
-rw-r--r--Core/PeiDebug.h108
-rw-r--r--Core/PeiHob.h34
-rw-r--r--Core/PeiLib.h864
-rw-r--r--Core/Protocol/CustomizedDecompress.h139
-rw-r--r--Core/Protocol/DebugMask.h69
-rw-r--r--Core/Protocol/FileInfo.h36
-rw-r--r--Core/Protocol/FirmwareVolumeDispatch.h36
-rw-r--r--Core/Protocol/SectionExtraction.h83
-rw-r--r--Core/Protocol/TianoDecompress.h139
-rw-r--r--Core/Protocol/VariableWrite.h80
-rw-r--r--Core/Rules.mak868
-rw-r--r--Core/Tiano.h348
-rw-r--r--Core/peihoblib.h315
1617 files changed, 588911 insertions, 0 deletions
diff --git a/Core/CORE_DXE/AmiDxeInit.c b/Core/CORE_DXE/AmiDxeInit.c
new file mode 100644
index 0000000..dbd41b5
--- /dev/null
+++ b/Core/CORE_DXE/AmiDxeInit.c
@@ -0,0 +1,427 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/DxeMain/AmiDxeInit.c 24 5/05/11 3:47p Artems $
+//
+// $Revision: 24 $
+//
+// $Date: 5/05/11 3:47p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/DxeMain/AmiDxeInit.c $
+//
+// 24 5/05/11 3:47p Artems
+// Added DevicePathToText and DevicePathFromText protocols
+//
+// 23 2/05/11 4:09p Artems
+// EDK library functions CopyMem and ZeroMem moved to EdkLib.c
+//
+// 22 9/29/10 8:05a Felixp
+// Enhancement: Initialization of the library TheImageHandle variable is
+// added.
+//
+// 21 4/22/10 10:43p Felixp
+// Install dummy instance of the security protocol when
+// INSTALL_DUMMY_SECURITY_PROTOCOL SDL token is set to "on".
+//
+// 20 2/23/10 10:01p Felixp
+// Updated to use CORE_COMBINED_VERSION token.
+//
+// 19 11/13/09 4:31p Felixp
+// Buffer overflow protection is added (calls to Sprintf replaced with
+// Sprintf_s).
+//
+// 18 7/30/09 4:04p Felixp
+// Bug fix:
+// Symptoms: memory corruption during DXE Core initialization.
+// Details: the corruption was caused by the HOBs created in AmiDxeInit1.
+// The HOB creation moved to an earlier point (before HOB data is used by
+// CoreInitializeMemoryServices).
+//
+// 17 5/04/09 3:10p Felixp
+// Creation of CPU HOB moved from AmiPeiInit.c to AmiDxeInit.c
+//
+// 16 3/05/09 4:39p Oleksiyy
+// EIP 18486: 3 GUID EXTENSION HOBs created.
+// Code clean up performed.
+//
+// 15 4/18/08 6:28p Felixp
+// checkpoint(0x60) removed. Corresponsing status code (DXE_CORE_ENTRY is
+// now reported at the and of DXE IPL using status code infrastructure
+//
+// 14 3/12/08 12:44p Felixp
+// Progress/Error codes reporting added
+//
+// 13 2/21/08 5:05p Felixp
+// FirmwareRevision field of the EFI system table is updated to use
+// CORE_BUILD_NUMBER.
+//
+// 12 9/05/07 4:22p Felixp
+// FirmwareVendor field of the EFI_SYSTEM_TABLE was initialized with a
+// pointer to boot time memory. However, this is a runtime field.
+// File updated to allocate runtime memory for the field.
+//
+// 11 10/12/06 9:43p Felixp
+//
+// 10 10/12/06 6:51p Felixp
+// UEFI2.0 support: DevicePathUtilities protocol added
+//
+// 9 10/07/06 10:24a Felixp
+// UIEFI2.0 support.
+// Updated to EDK 20060904
+//
+// 8 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 7 5/23/06 4:16a Felixp
+//
+// 6 5/22/06 11:57a Felixp
+//
+// 5 5/22/06 12:12a Felixp
+// Vendor & Revision fields of ST initialized
+//
+// 4 5/20/06 9:37p Felixp
+// checkpoint 0x60 added
+// debug message for drivers startting/stopping
+// clean up
+//
+// 3 5/19/06 10:46p Felixp
+// Updated to EDK 03.16.06
+// Cleanup
+//
+// 2 4/30/06 9:41p Felixp
+//
+// 1 3/13/06 2:00a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiDxeInit.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include<EFI.h>
+#include<Protocol/Decompress.h>
+#include<Protocol/DriverBinding.h>
+#include<Protocol/DevicePathUtilities.h>
+#include<Protocol/DevicePathToText.h>
+#include<Protocol/DevicePathFromText.h>
+#include<Protocol/Security.h>
+#include<AmiDxeLib.h>
+#include<AmiHobs.h>
+#include<Token.h>
+#include<Guid/PeiFlushInstructionCache.h>
+#include<Guid/PeiPeCoffLoader.h>
+#include<Guid/PeiTransferControl.h>
+
+
+EFI_GUID gEfiPeiFlushInstructionCacheGuid = EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID;
+EFI_GUID gEfiPeiPeCoffLoaderGuid = EFI_PEI_PE_COFF_LOADER_GUID;
+EFI_GUID gEfiPeiTransferControlGuid = EFI_PEI_TRANSFER_CONTROL_GUID;
+EFI_GUID gEfiStatusCodeSpecificDataGuid = EFI_STATUS_CODE_SPECIFIC_DATA_GUID;
+typedef VOID (*INIT_PARTS)(VOID* p1, VOID*p2);
+VOID InitParts(VOID* p1, VOID*p2);
+extern EFI_SYSTEM_TABLE *gST;
+
+extern EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL EfiDevicePathFromTextProtocol;
+extern EFI_DEVICE_PATH_TO_TEXT_PROTOCOL EfiDevicePathToTextProtocol;
+
+///////////////////////////////////////////////////////////////
+////===================== Print Protocol ==================.
+#define EFI_PRINT_PROTOCOL_GUID \
+ { 0xdf2d868e, 0x32fc, 0x4cf0, 0x8e, 0x6b, 0xff, 0xd9, 0x5d, 0x13, 0x43, 0xd0 }
+
+typedef struct _EFI_PRINT_PROTOCOL EFI_PRINT_PROTOCOL;
+
+typedef UINTN (EFIAPI *EFI_VSPRINT)(
+ OUT CHAR16 *StartOfBuffer, IN UINTN BufferSize,
+ IN CHAR16 *FormatString, IN va_list Marker
+);
+
+struct _EFI_PRINT_PROTOCOL{
+ EFI_VSPRINT VSPrint;
+};
+
+EFI_GUID guidPrint = EFI_PRINT_PROTOCOL_GUID;
+EFI_PRINT_PROTOCOL Print = {&Swprintf_s_va_list};
+
+////===================== Decompress Protocol ==================.
+EFI_GUID guidDecompress = EFI_DECOMPRESS_PROTOCOL_GUID;
+EFI_STATUS DecomprGetInfo (
+ IN VOID *This,
+ IN VOID *Source, IN UINT32 SourceSize,
+ OUT UINT32 *DestinationSize, OUT UINT32 *ScratchSize
+)
+{
+ return GetInfo(Source,SourceSize,DestinationSize,ScratchSize);
+}
+
+EFI_STATUS DecomprDecompress (
+ IN VOID *This,
+ IN VOID* Source, IN UINT32 SourceSize,
+ IN OUT VOID* Destination, IN UINT32 DestinationSize,
+ IN OUT VOID* Scratch, IN UINT32 ScratchSize
+)
+{
+ return Decompress(Source,SourceSize,Destination,DestinationSize,Scratch,ScratchSize);
+}
+
+EFI_DECOMPRESS_PROTOCOL DecompressInterface = {&DecomprGetInfo, &DecomprDecompress};
+EFI_DECOMPRESS_PROTOCOL *pDecompressInterface=&DecompressInterface;
+
+////===================== Device Path Utilities Protocol ==================
+EFI_DEVICE_PATH_UTILITIES_PROTOCOL DevicePathUtilitiesInstance =
+{
+ (EFI_DEVICE_PATH_UTILS_GET_DEVICE_PATH_SIZE)DPLength,
+ (EFI_DEVICE_PATH_UTILS_DUP_DEVICE_PATH)DPCopy,
+ (EFI_DEVICE_PATH_UTILS_APPEND_PATH)DPAdd,
+ (EFI_DEVICE_PATH_UTILS_APPEND_NODE)DPAddNode,
+ (EFI_DEVICE_PATH_UTILS_APPEND_INSTANCE)DPAddInstance,
+ (EFI_DEVICE_PATH_UTILS_GET_NEXT_INSTANCE)DPNextInstance,
+ (EFI_DEVICE_PATH_UTILS_IS_MULTI_INSTANCE)DPIsMultiInstance,
+ (EFI_DEVICE_PATH_UTILS_CREATE_NODE)DPCreateNode
+};
+
+////===================== Security Architectural Protocol =================
+EFI_STATUS FileAuthenticationState(
+ IN EFI_SECURITY_ARCH_PROTOCOL *This,
+ IN UINT32 AuthenticationStatus,
+ IN EFI_DEVICE_PATH_PROTOCOL *File
+)
+{
+ if (File==NULL) return EFI_INVALID_PARAMETER;
+ return EFI_SUCCESS;
+}
+
+EFI_SECURITY_ARCH_PROTOCOL Security = {FileAuthenticationState};
+
+///////////////////////////////////////////////////////////////
+extern EFI_GUID gEfiTianoDecompressProtocolGuid;
+extern VOID *mHobStart;
+extern EFI_HANDLE gDxeCoreImageHandle;
+
+extern EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache;
+extern EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader;
+extern EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl;
+extern BOOLEAN const InstallDummySecurityProtocol;
+
+VOID *CoreAllocateRuntimeCopyPool (
+ IN UINTN AllocationSize, CONST IN VOID *Buffer
+);
+
+typedef struct{
+ EFI_GUID *pGuid;
+ VOID* pInterface;
+} DXE_MAIN_INTERFACES;
+
+DXE_MAIN_INTERFACES DxeMainInterfaces[] =
+{
+ {&gEfiPeiFlushInstructionCacheGuid,&mFlushInstructionCache},
+ {&gEfiPeiPeCoffLoaderGuid,&mPeCoffLoader},
+ {&gEfiPeiTransferControlGuid,&mTransferControl},
+ {NULL,NULL}
+};
+
+EFI_STATUS CreateHob ( IN UINT16 Type, IN UINT16 Length, IN OUT VOID **Hob ){
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+
+ if (mHobStart == NULL) return EFI_NOT_AVAILABLE_YET;
+ if (Hob == NULL) return EFI_INVALID_PARAMETER;
+
+ // first entry in the HOB list is the HOB handoff table
+ HandOffHob = mHobStart;
+ // make sure Hob length is a multiple of 8 bytes.
+ Length = (UINT16)((Length + 0x7) & (~0x7));
+ // calculate the amount of free memory
+ FreeMemory = HandOffHob->EfiFreeMemoryTop
+ - HandOffHob->EfiFreeMemoryBottom;
+ if (FreeMemory < Length) return EFI_OUT_OF_RESOURCES;
+
+ // add a HOB to the end of the HOB list
+ *Hob = (VOID*)(UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;
+
+ // move a new end of the HOB list past the newly created HOB
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ // initialize the new end HOB and update the pointer to the bottom of free memory
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return EFI_SUCCESS;
+}
+
+VOID AmiDxeInit0()
+{
+ DXE_MAIN_INTERFACES *p;
+ EFI_HOB_CPU *CpuHob;
+
+ //Create CPU HOB
+ // NOTE: It is responsibility of CPU and/or NB PEIM to make sure
+ // CPU HOB exists and contains valid data.
+ // The HOB created here is just to prevent system from hanging
+ // in case CPU HOB has not been created.
+ // If CPU HOB already exists, the HOB crated here will be ignored
+ // by DXE Core because it uses only the first instance of the HOB.
+ CreateHob(EFI_HOB_TYPE_CPU, sizeof(EFI_HOB_CPU), &CpuHob);
+ CpuHob->SizeOfMemorySpace=32;
+ CpuHob->SizeOfIoSpace=16;
+ CpuHob->Reserved[0]=0;
+ CpuHob->Reserved[1]=0;
+ CpuHob->Reserved[2]=0;
+ CpuHob->Reserved[3]=0;
+ CpuHob->Reserved[4]=0;
+ CpuHob->Reserved[5]=0;
+
+ // =========== Initialize DxeMain Pointers
+ for(p=DxeMainInterfaces; p->pGuid; p++)
+ {
+ PEIM_HOB *PeimHob;
+ CreateHob(EFI_HOB_TYPE_GUID_EXTENSION, sizeof(PEIM_HOB),&PeimHob);
+ PeimHob->Header.Name = *p->pGuid;
+ PeimHob->DxeEntryPoint= p->pInterface;
+ }
+}
+
+VOID AmiDxeInit1()
+{
+ InitAmiLib(gDxeCoreImageHandle,gST);
+
+ // =========== Initialize System Table Fields
+ gST->FirmwareVendor = CoreAllocateRuntimeCopyPool(
+ sizeof( CONVERT_TO_WSTRING(CORE_VENDOR)), CONVERT_TO_WSTRING(CORE_VENDOR)
+ );
+ gST->FirmwareRevision = CORE_COMBINED_VERSION;
+}
+
+VOID AmiDxeInit2()
+{
+ VOID *p=mHobStart;
+ EFI_HANDLE Handle = NULL;
+
+// TheImageHandle is a library variable, which is initialized in the InitAmiLib library function
+// However, in our case InitAmiLib has been called too early (from AmiDxeInit1), before
+// gDxeCoreImageHandle has beeen initialized. It is initialized now.
+// Let's update TheImageHandle variable.
+ TheImageHandle = gDxeCoreImageHandle;
+ // =========== Initialize modules inherited from PEI ======================= //
+#ifndef EFIx64 //no code sharing between PEI and DXE in x64 mode
+ for(p = mHobStart; !EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION,&p)); )
+ {
+ PEIM_HOB *pHob = (PEIM_HOB*)p;
+ static EFI_GUID guidAmiPeimHob = AMI_PEIM_HOB_GUID;
+ if (guidcmp(&pHob->Header.Name,&guidAmiPeimHob)) continue;
+ pHob->DxeEntryPoint(gDxeCoreImageHandle,gST);
+ }
+#endif
+ // ========================================================================== //
+ gST->BootServices->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &guidDecompress, &DecompressInterface,
+ &gEfiTianoDecompressProtocolGuid, &DecompressInterface,
+ &guidPrint, &Print,
+ &gEfiDevicePathUtilitiesProtocolGuid, &DevicePathUtilitiesInstance,
+ &gEfiDevicePathFromTextProtocolGuid, &EfiDevicePathFromTextProtocol,
+ &gEfiDevicePathToTextProtocolGuid, &EfiDevicePathToTextProtocol,
+ NULL
+ );
+ if (InstallDummySecurityProtocol)
+ gST->BootServices->InstallMultipleProtocolInterfaces(
+ &Handle, &gEfiSecurityArchProtocolGuid, &Security, NULL
+ );
+ InitParts(gDxeCoreImageHandle,gST);
+}
+
+EFI_STATUS AmiResetNotAvailableYet(
+ IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize, IN CHAR16 *ResetData OPTIONAL
+)
+{
+ ERROR_CODE(DXE_RESET_NOT_AVAILABLE,EFI_ERROR_MINOR);
+ return EFI_NOT_AVAILABLE_YET;;
+}
+
+VOID AmiReportArhcProtocolMissingError(){
+ ERROR_CODE(DXE_ARCH_PROTOCOL_NOT_AVAILABLE,EFI_ERROR_MAJOR);
+}
+
+//GUID definitions
+
+/// Library routines
+#ifdef EFI_DEBUG
+#define EFI_D_ERROR 0x80000000 // Error
+#define EFI_DBUG_MASK (EFI_D_ERROR)
+#define EFI_D_LOAD 0x00000004 // Load events
+UINTN gErrorLevel=EFI_DBUG_MASK | EFI_D_LOAD;
+
+VOID
+EfiDebugAssert (
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ )
+ {
+ Trace(TRACE_ALWAYS,"ASSERT in %s on %i: %s\n",FileName, LineNumber, Description);
+ EFI_DEADLOOP()
+ }
+
+VOID
+EfiDebugVPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ IN va_list ArgList
+ )
+ {
+ if (!gST) return;
+#if EFI_SPECIFICATION_VERSION<0x20000
+ if (!(gST->RuntimeServices && gST->RuntimeServices->ReportStatusCode)) return;
+#endif
+ if (!(gErrorLevel & ErrorLevel)) return;
+ PrintDebugMessageVaList(ErrorLevel, Format, ArgList);
+ }
+
+CHAR8* GetDriverName(EFI_DRIVER_BINDING_PROTOCOL *pDriver)
+{
+ static char sName[0x100];
+ if ( !GetImageName(pDriver->DriverBindingHandle,sName)
+ && !GetImageName(pDriver->ImageHandle,sName)
+ ) Sprintf_s(sName,sizeof(sName),"Unknown");
+ return sName;
+}
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/BDS.c b/Core/CORE_DXE/BDS.c
new file mode 100644
index 0000000..f3302c2
--- /dev/null
+++ b/Core/CORE_DXE/BDS.c
@@ -0,0 +1,1607 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/BDS.c 3 7/15/14 9:54p Chienhsieh $
+//
+// $Revision: 3 $
+//
+// $Date: 7/15/14 9:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/BDS.c $
+//
+// 3 7/15/14 9:54p Chienhsieh
+// Update rev.125 for EIP172950, Core updates for UEFI Variable Technical
+// Advisory implement.
+//
+// 125 5/09/14 2:44p Artems
+// [TAG] EIP166565
+// [Category] Improvement
+// [Description] Removed runtime-access attribute from the variables
+// MemoryTypeInformation
+// and PreviousMemoryTypeInformation
+// [Files] BDS.c
+//
+// 2 11/21/12 4:21a Wesleychen
+// Update for SCT test (EIP104956).
+//
+// 117 10/29/12 4:03p Artems
+// [TAG] EIP104956
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UEFI 2.3.1 SCT test failed in Generic\EfiCompliant case.
+// The VariableAttribute of ErrOut is not correct.
+// [RootCause] System variable ErrOut was saved without EFI_NON_VOLATILE
+// attribute
+// [Solution] Added missing attribute
+// [Files] Bds.c
+//
+// 116 10/08/12 6:56p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] build error with message invalid Code page
+// [RootCause] Presence of special characters in debug comment
+// [Solution] Removed special characters
+// [Files] BDS.c
+//
+// 115 7/20/12 10:33a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Improved debug output for SaveMemoryInformation
+// function
+// [Files] BDS.c
+//
+// 114 5/30/12 4:59p Felixp
+// SaveMemoryTypeInformation is updated to never decrease the memory type
+// usage values
+// to workaround Windows 7 and Windows 8 bug.
+//
+// 113 5/30/12 3:12p Felixp
+// [TAG] EIP90941
+// [Category] Bug Fix
+// [Symptom] "System resume from S4 would have problem when iRST
+// setting changed and system did S4.
+// [RootCause] SaveMemoryTypeInformation has been called twice.
+// [Solution] The function is updated to perform processing only during
+// the first call.
+//
+// 112 5/23/12 11:42a Artems
+// [TAG] EIP N/A
+// [Category] Spec Update
+// [Description] Replaced FirmwareVolume protocol with FirmwareVolume2
+// protocol
+// [Files] bootoptions.h BDS.c
+//
+// 111 4/12/12 11:12a Felixp
+// [TAG] EIP85611
+// [Category] Improvement
+// [Description] Memory map is not consistent between
+// second and third boots if system has been reset from the Setup
+// during the very first boot.
+// [Files] Bds.c, CORE_DXE.sdl
+//
+// 110 12/05/11 2:18p Felixp
+// // 109 11/21/11 11:03a Felixp
+// // [TAG] EIP69841
+// // [Category] Improvement
+// // [Description] Improvements in the Memory Type Information
+// processing
+// // to properly handle first boot.
+//
+// 109 11/21/11 11:03a Felixp
+// [TAG] EIP69841
+// [Category] Improvement
+// [Description] Improvements in the Memory Type Information processing
+// to properly handle S4 resume during the fast boot.
+//
+// 108 11/09/11 3:19p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added.
+// [Files] AcpiCore.c, AmiDxeLib.h, BDS.c, DxeMain.c, EfiLib.c,
+// Image.c, S3Resume.c and FirmPerfDataTab.h
+//
+// 107 11/01/11 1:55p Felixp
+// [TAG] EIP 69841 and 71719
+// [Category] Improvement
+// [Description] The AMI customizations are removed from the DXE memory
+// manager.
+// They are replaced with the Memory Type Information HOB used in Tiano
+// projects.
+// This is done to reduces number of descriptors in the memory map
+// and to workaround Windows bug (Windows can't handle memory allocations
+// that happen after the start of the OS loader).
+// [Files] CORE_DXE.sdl, Page.c, BDS.c, DxeIpl.c
+//
+// 106 11/01/11 1:42p Felixp
+// Improvement: Support for logging of the performance information during
+// legacy boot.
+//
+// 105 10/20/11 6:59p Artems
+// Function ConnectConsoles moved to FastBoot module
+//
+// 104 3/16/11 11:41p Felixp
+// Editorial: Several spelling errors in the comments are fixed
+//
+// 103 2/25/11 12:51p Artems
+// EIP 53767 - Velocity boot time above 5 seconds. Added provision to skip
+// USB keyboard initialization
+//
+// 102 2/15/11 6:52p Artems
+// Add possibility to modify ConnectConsoles function list with SDL tokens
+//
+// 101 12/03/10 10:26a Felixp
+//
+// 100 12/03/10 10:23a Felixp
+//
+// 99 12/03/10 10:23a Felixp
+// Bug fix in InitConVars: console-related fields of the systems table
+// were not initialized on headless systems.
+//
+// 98 10/15/10 12:02p Felixp
+// Bug fix in ConnectConsoles function
+//
+// 97 10/01/10 8:02a Felixp
+// ThisImageHandle variabled added (for compatibility with existing
+// modules)
+// Clean up
+//
+// 96 9/29/10 9:21a Felixp
+// Enhancement(EIP 39464) : Implementation of the BdsEntry function is
+// changed.
+// The BdsEntry is now a dispatching function that calls a collection of
+// functions
+// formed by the BDS_CONTROL_FLOW eLink.
+//
+// 95 6/29/10 11:06p Felixp
+// New Boot Options Maintenance Infrastructure.
+// See AMI_Aptio_4.x_Boot_Options_Maintenance_Infrastructure_Porting_Guide
+// _NDA.doc for details.
+//
+// 94 5/07/10 6:00p Felixp
+// Improvement in ConnectDevicePath (EIP 38132): Null pointer check of the
+// input parameter is added
+//
+// 93 3/22/10 10:20a Artems
+// EIP 35562 Fixed boot variable name - hex digits should be in upper case
+//
+// 92 2/03/10 4:34p Oleksiyy
+// Minor bug fix (typecasting)
+//
+// 91 2/02/10 5:45p Felixp
+// Fast Boot related code is removed from BDS. It is now part of the stand
+// alone FastBoot eModule.
+//
+// 90 10/28/09 12:19p Felixp
+// Minor bug fix: check for a NULL pointer is added to the
+// CreateLegacyBootOption function(EIP 28577).
+//
+// 89 10/09/09 6:06p Felixp
+// UEFI 2.1 - related changes (suppot Framework and UEFI HII).
+//
+// 88 10/09/09 11:58a Felixp
+// Code that sets ConOutDev variable is removed. It is not needed. The
+// variable is set by the ConSplitter driver.
+//
+// 87 8/04/09 1:28p Felixp
+// Bug fix: in BuildBootOptionName function.
+// Symptoms: Systems with several boot devices where occasionally handing
+// towards the end of the BDS phase.
+//
+// 86 7/10/09 5:58p Felixp
+// New Boot Option Maintenance Ifrastructure is added
+//
+// 85 7/08/09 8:36a Felixp
+// Bug fix (EIP 23027): Update NVRAM instance of LegacyDevOrder variable
+// when it's modified by the AdjustLegacyDevOrder function.
+//
+// 84 6/26/09 3:08p Felixp
+// ConnectDefaultConOut updated:
+// 1. AGP support is removed
+// 2. Improved on-board device detection logic
+// (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE attribut is used).
+//
+// 83 5/22/09 9:52a Felixp
+// Minor improvements in AdjustLegacyDevOrder function
+//
+// 82 5/21/09 5:20p Felixp
+// Bug fix in BuildBootOptionName function
+//
+// 81 1/20/09 10:57p Felixp
+//
+// 80 1/20/09 3:30p Felixp
+// Bug fix. EIP 16566. Order of legacy devices within BBS group is reset
+// when configuration changes.
+// Symptoms: Order of legacy devices within BBS group is sometimes reset
+// when bootable devices are added (enabled) or removed (disabled).
+// Here is one of the ways to reproduce the problem:
+// 1. Make sure the following bootable devices are plugged into the
+// system:
+// - Bootable network device (onboard or offboard)
+// - USB flash drive emulated as hard drive
+// - IDE or SATA hard drive
+// 2. Boot to setup.
+// 3. Enable PXE boot using "Lunch PXE OpRom" option on the "Advanced"
+// page.
+// 4. Save the settings, reboot the system, and enter the setup.
+// 5. On the "Boot" page, update "Hard Driver BBS Priorities" to set USB
+// drive as a first boot device.
+// 6. Disable PXE boot using "Lunch PXE OpRom" option on the "Advanced"
+// page.
+// 7. Save the settings, reboot the system, and enter the setup.
+// 8. Enter "Hard Driver BBS Priorities" menu on the "Boot" page.
+// USB drive priority has been reset( it is no longer the first boot
+// device).
+// Details: BDS used index within BBS table to match saved priorities with
+// available boot devices.
+// However, when list of boot devices changes, BBS index may also change.
+// For example, when network boot is enabled, boot option for a network
+// device
+// is inserted into the BBS table prior to the USB drive boot option.
+// As a result, index of the USB drive boot option increases by one
+// and matching against saved boor priority fails.
+// BDS code is updated to save more information about legacy boot devices.
+// For every legacy boot device BDS saves
+// checksum of the device name into the NVRAM (along with device index).
+// When index matching fails, BDS uses saved checksum to find updated BBS
+// index
+// of the boot option.
+//
+// 79 1/14/09 3:52p Felixp
+// BDS updated to signal beginning of the driver connection cycle by
+// installing the protocol.
+//
+// 78 1/05/09 3:02p Felixp
+// Bug fix. EIP 17217
+// Problems during video card switching.
+// Symptoms: Some systems were hanging during after replacement
+// of the video card.
+//
+// 77 11/03/08 5:21p Felixp
+// Do no re-create boot option for the built-in Shell, if Shell is not
+// included into the ROM
+//
+// 76 10/29/08 12:52p Felixp
+// RunDrivers updates: ignore non-active driver options; perform reconnect
+// once
+//
+// 74 10/22/08 4:24p Felixp
+//
+// 73 10/22/08 11:35a Felixp
+// 1. Code to recreate deleted boot option for the built-in Shell is
+// added(EIP 15524).
+// 2. Processing of the DriverOrder list is added
+// 3. Clean up
+//
+// 72 10/21/08 5:56p Felixp
+// Multi-language support added to UEFI boot options implementation
+//
+// 71 10/21/08 3:30p Felixp
+// BuildBootOptionName function improvements and bug fixes
+//
+// 70 10/17/08 3:46p Yakovlevs
+// Support for UEFI boot options added
+//
+// 69 10/10/08 4:25p Felixp
+// - Improved handling of console devices
+// - Clean up
+//
+// 68 10/09/08 5:07p Felixp
+// Bug fixes:
+// - Support for systems with no console devices.
+// If no console input or output devices are available,
+// system table is populated with the fake ConIn/ConOut handles
+// and protocol interface pointers.
+// This prevents potential failures caused by the NULL pointers in the
+// system table.
+// - Early Console device initialization during the first boot(EIP 13459).
+// During the very first boot after the firmware update,
+// console devices were initialized towards the end of the boot.
+// The logic has been updated to initialize default console devices
+// at the beginning of the BDS connection cycle.
+// - Serial Redirection could not be enabled, if
+// it was disabled by default(EIP 15565)
+//
+// 67 9/30/08 11:07p Felixp
+// Performance measurement support: callback to publish performance data
+// for OS usage added (the callback is generated by TSE).
+//
+// 66 6/06/08 11:00a Felixp
+// 1. Performance measurement support is added
+// 2. Support for boot with minimal configuration is added
+// 3. Code is reformatted in accordance with the coding standards
+//
+// 65 5/06/08 10:07a Felixp
+//
+// 64 12/17/07 4:07p Felixp
+// Signal protocol event before handing control over to TSE
+//
+// 63 11/08/07 4:51p Felixp
+// Code updated to compile and work without CSM.
+//
+// 62 10/26/07 2:36p Felixp
+// New FW based load file protocl is added.
+// This protocol is used to load FW based EFI applications such as built
+// in Shell.
+//
+// 61 10/17/07 11:28a Felixp
+// Update in InitBbs routine: Delete LegacyDevOrder when no legacy devices
+// are found.
+// This fixes hang in AMITSE when no bootable devices are present.
+//
+// 60 8/31/07 1:55p Felixp
+// Updated to support new location of AMIPostMgr.h. It is moved from
+// Core/em/AMITSE into Include/Protocol
+//
+// 59 8/07/07 2:36p Felixp
+// Additionanal Status Codes added
+//
+// 58 4/10/07 9:34a Felixp
+//
+// 55 3/18/07 2:30p Felixp
+// Initialization of Lang & LangCodes variables removed
+// (it is done in Setup now)
+//
+// 54 2/28/07 7:32p Felixp
+//
+// 52 2/26/07 6:12p Felixp
+// Bug fix in SetBbsPriorities.
+//
+// 51 2/13/07 9:18a Felixp
+// MRE Handshake protocol renamed to AMI POST Manager protocol
+// (MreHandshake.h removed from Core Protocols and added to AMITSE module
+// as AMIPostMgr.h)
+//
+// 50 2/12/07 1:45p Felixp
+// 1. Correct handling of disabled legacy BBS options
+// 2. Name of the legacy device removed from legacy boot option because it
+// is not needed (AMITSE does not use it)
+// 3. Clean up in ConnectDevicePath
+//
+// 49 12/29/06 3:00p Felixp
+// Console initialization logic changed
+//
+// 48 10/30/06 6:03p Felixp
+// Updated to be complient with HII Spec. 0.92 (used to be 0.91)
+//
+// 47 10/13/06 4:43p Felixp
+// Beep when ConIn available
+//
+// 46 10/13/06 9:27a Felixp
+// Patch for disconnected FDD moved to a proper place
+//
+// 45 10/12/06 9:42a Felixp
+// UEFI2.0 compliance: use CreateReadyToBootEvent instead of CreateEvent
+//
+// 44 9/29/06 3:52p Pavell
+// Added processing and dispatching capsule
+//
+// 42 5/23/06 4:17a Felixp
+// Patch for disconnection of the Floppy Controller added
+//
+// 41 5/19/06 10:45p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 40 3/13/06 10:07a Felixp
+//
+// 39 12/22/05 11:25a Felixp
+//
+// 38 11/08/05 4:07a Felixp
+// Support for TSE notifications added
+//
+// 37 11/07/05 10:34a Felixp
+// Boot with minimum configuration suuport
+//
+// 36 9/29/05 4:36p Robert
+//
+// 35 8/25/05 11:47a Felixp
+// Code added to start Standard ConIn devices (PS2, USB) early
+//
+// 34 8/25/05 11:41a Felixp
+//
+// 33 8/22/05 5:29p Felixp
+// Invoke dispatcher before boot
+//
+// 32 7/29/05 6:52p Felixp
+// improvement in InitBbs: correct handling of LegacyDevOrder shorter then
+// 6 bytes
+//
+// 3 7/20/05 8:03p Felixp
+// workaround for password support
+//
+// 28 7/15/05 7:16p Felixp
+// CONSOLE_DEVICES_STARTED_PROTOCOL_GUID added.
+// BDS uses it to notify Splitter that Console Devices have been started.
+// Once Splitter receives notification, it will install ConIn and ConOut
+// in System Table
+//
+// 27 7/14/05 12:10a Felixp
+// BBS support
+//
+// 25 5/24/05 2:55p Felixp
+// Boot menu logic moved to SetupEngine.
+// Now BDS just gives control to MREHandshake
+//
+// 24 4/28/05 1:06p Felixp
+// bug fix in InitConVars
+//
+// 23 4/25/05 12:12p Felixp
+// AddBootOption - loader options can now be passed
+//
+// 21 4/08/05 3:02p Felixp
+// SignalReadyToBoot added
+//
+// 20 4/08/05 7:39a Felixp
+// Boot Menu implemented
+//
+// 19 4/02/05 3:24p Felixp
+//
+// 18 3/28/05 7:03p Felixp
+// DrawBmp function added
+//
+// 15 3/17/05 7:51p Felixp
+// pBootScript->CloseTable commented out
+//
+// 14 3/15/05 2:55p Felixp
+// 1. Code to initialize global EFI variables added
+// 2. Code to Close boot script table and save the address to NVRAM added
+//
+// 13 2/14/05 10:40a Felixp
+// Off-board video started before on-board
+//
+// 12 2/11/05 6:05p Felixp
+// Code optimized by using DPAddNode instead of DPAdd
+// Logic to set video card priorities added(from hi ti lo):
+// AGP->on board PCI ->off board PCI
+//
+// 11 2/07/05 5:21p Felixp
+// function GetEfiVariable moved to AmiDxeLib
+//
+// 10 2/03/05 8:07p Felixp
+// ConnectDevicePath change: now last node connected recursively
+//
+// 9 2/03/05 7:58p Felixp
+//
+// 8 2/03/05 7:45p Felixp
+// Logic to initialize Console variables added
+//
+// 7 2/01/05 4:24p Felixp
+// 1 .ConnectDevicePath fixed (before it didn't connect last node in the
+// device path)
+// 2. REAY to BOOT event signaled
+//
+// 6 1/25/05 3:27p Felixp
+// if GSE absent restart shell if it returns
+//
+// 5 1/19/05 7:01p Felixp
+//
+// 3 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 1/10/05 5:10p Felixp
+// Patches for Intel CSM and Intel Terminal driver disabled
+//
+// 28 12/23/04 9:29a Felixp
+// ArchProtocols moved to Include\Protocols
+//
+// 27 12/21/04 4:53p Markw
+// Modified device path defines for consistency.
+//
+// 26 12/21/04 4:21p Markw
+// Renamed hardware device path definition for consistency.
+//
+// 21 12/01/04 3:24p Felixp
+// GSE support added
+//
+// 20 8/03/04 6:46p Felixp
+// SetVariable for "Lang" and "LangCodes" moved to do it before all
+// drivers are connected
+//
+// 15 7/16/04 3:57p Felixp
+// Changes to support both 7f and ff values for the device path end type
+//
+// 1 3/30/04 3:26p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: BDS.c
+//
+// Description: Implementation of the BDS architectural protocol
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "BootOptions.h"
+#include <Protocol/BDS.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextOut.h >
+#include <Protocol/LoadedImage.h>
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/AMIPostMgr.h>
+#include <Protocol/LoadFile.h>
+#include <DXE.h>
+#include <HOB.h>
+#include <Guid/MemoryTypeInformation.h>
+
+/**************************** TYPES ***********************************/
+
+/***************** FUNCTION DECLARATIONS *****************************/
+//this funciton is created from InitList.c template file during build process
+VOID InitParts2(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
+
+//Local functions
+VOID BdsEntry (IN EFI_BDS_ARCH_PROTOCOL *This);
+
+EFI_STATUS FwLoadFile (
+ IN EFI_LOAD_FILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN BOOLEAN BootPolicy, IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL
+);
+
+/**************************** CONSTANTS *******************************/
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93}
+// {3AA83745-9454-4f7a-A7C0-90DBD02FAB8E}
+#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \
+ { 0x3aa83745, 0x9454, 0x4f7a, { 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e } }
+// {8DB699CC-BC81-41e2-AAC6-D81D5300D759}
+#define PARTITION_VARIABLE_GUID\
+ { 0x8db699cc, 0xbc81, 0x41e2, { 0xaa, 0xc6, 0xd8, 0x1d, 0x53, 0x0, 0xd7, 0x59 } }
+// {5023B95C-DB26-429b-A648-BD47664C8012}
+#define AMI_MEDIA_DEVICE_PATH_GUID \
+ { 0x5023b95c, 0xdb26, 0x429b, { 0xa6, 0x48, 0xbd, 0x47, 0x66, 0x4c, 0x80, 0x12 } }
+
+extern EFI_GUID gEfiBdsArchProtocolGuid; // = EFI_BDS_ARCH_PROTOCOL_GUID;
+extern EFI_GUID gEfiDevicePathProtocolGuid ;//= EFI_DEVICE_PATH_PROTOCOL_GUID;
+extern EFI_GUID gEfiFirmwareVolume2ProtocolGuid; // = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+extern EFI_GUID gEfiLoadedImageProtocolGuid; //=EFI_LOADED_IMAGE_PROTOCOL_GUID;
+extern EFI_GUID gEfiPciIoProtocolGuid; // = EFI_PCI_IO_PROTOCOL_GUID;
+extern EFI_GUID gEfiBlockIoProtocolGuid;
+extern EFI_GUID gEfiLoadFileProtocolGuid;
+extern EFI_GUID gEfiSimpleFileSystemProtocolGuid;
+//defined in BdsBoard.c
+extern EFI_GUID SetupEnterProtocolGuid;
+extern EFI_GUID SecondBootOptionProtocolGuid;
+extern EFI_GUID BeforeBootProtocolGuid;
+extern EFI_GUID BeforeLegacyBootProtocolGuid;
+extern EFI_GUID *DefaultAppFfsGuidPtr;
+
+extern BDS_CONTROL_FLOW_FUNCTION *BdsControlFlowFunctions[];
+extern CHAR8 *BdsControlFlowFunctionNames[];
+
+EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+EFI_GUID AmiPostMgrProtocolGuid=AMI_POST_MANAGER_PROTOCOL_GUID;
+EFI_GUID ConInStartedProtocolGuid = CONSOLE_IN_DEVICES_STARTED_PROTOCOL_GUID;
+EFI_GUID ConOutStartedProtocolGuid = CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID;
+EFI_GUID BdsAllDriversConnectedProtocolGuid = BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID;
+EFI_GUID BdsConnectDriversProtocolGuid = BDS_CONNECT_DRIVERS_PROTOCOL_GUID;
+EFI_GUID PartitionVariableGuid = PARTITION_VARIABLE_GUID;
+
+EFI_BDS_ARCH_PROTOCOL BDS = {&BdsEntry};
+
+/**************************** VARIABLES *******************************/
+//externals defined in BdsBoard.c
+extern UINT16 DefaultTimeout;
+extern BOOLEAN QuietBoot;
+extern STRING_REF StrToken[];
+
+// Global Variables
+EFI_LOAD_FILE_PROTOCOL FwLoadFileInterface = {FwLoadFile};
+
+struct {
+ VENDOR_DEVICE_PATH Media;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} FwLoadFileDp = {
+ {
+ {
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
+ sizeof(VENDOR_DEVICE_PATH)
+ },
+ AMI_MEDIA_DEVICE_PATH_GUID
+ },
+ {
+ END_DEVICE_PATH, END_ENTIRE_SUBTYPE,
+ sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ }
+};
+
+EFI_HANDLE LpcHandle = NULL;
+EFI_DEVICE_PATH_PROTOCOL *LpcDevicePath = NULL;
+
+VOID ConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *pPath)
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+
+ if (pPath == NULL) return;
+ while (TRUE)
+ {
+ EFI_DEVICE_PATH_PROTOCOL *pLastPath=NULL, *pFirstNode = pPath;
+ if (isEndNode(pPath))
+ {
+ if (pPath->SubType == END_ENTIRE_SUBTYPE) break;
+ pPath++;
+ continue;
+ }
+ while(TRUE){
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 SubType;
+
+ pPath = pFirstNode;
+
+ //LocateDevicePath can not work with multi-instance device paths.
+ //Prepare single instance device path and call LocateDevicePath
+ Dp = DPGetEndNode(pPath);
+ SubType = Dp->SubType;
+ Dp->SubType=END_ENTIRE_SUBTYPE;
+ Status = pBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &pPath, &Handle);
+ Dp->SubType=SubType;
+ if (EFI_ERROR(Status)) break;
+
+ if (isEndNode(pPath))
+ {
+ //Last time let's do it recursively
+ pBS->ConnectController(Handle,NULL,NULL,TRUE);
+ break;
+ }
+ if (pPath==pLastPath) break;
+ pLastPath = pPath;
+ if (EFI_ERROR(pBS->ConnectController(Handle,NULL,pPath,FALSE))) break;
+ }
+ while (!isEndNode(pPath))
+ pPath = NEXT_NODE(pPath);
+ }
+}
+
+EFI_DEVICE_PATH_PROTOCOL* AddDevicePath(EFI_DEVICE_PATH_PROTOCOL *pDp1, EFI_DEVICE_PATH_PROTOCOL *pDp2)
+{
+ if (!pDp2) return pDp1;
+ if (!pDp1)
+ {
+ return DPCopy(pDp2);
+ }
+ else
+ {
+ pDp2 = DPAddInstance(pDp1,pDp2);
+ pBS->FreePool(pDp1);
+ return pDp2;
+ }
+}
+
+EFI_STATUS GetPciHandlesByClass(
+ UINT8 Class, UINT8 SubClass, UINTN *NumberOfHandles, EFI_HANDLE **HandleBuffer
+){
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+
+ if (!NumberOfHandles || !HandleBuffer) return EFI_INVALID_PARAMETER;
+ //Get a list of all PCI devices
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciIoProtocolGuid, NULL, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return Status;
+ *NumberOfHandles = 0;
+ for(i=0; i<Number; i++)
+ {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass[4];
+ Status=pBS->HandleProtocol(Handle[i],&gEfiPciIoProtocolGuid,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32, PCI_REV_ID_OFFSET, 1, &PciClass);
+ if( PciClass[3]==Class && PciClass[2]==SubClass)
+ Handle[(*NumberOfHandles)++] = Handle[i];
+ }
+ if (*NumberOfHandles == 0){
+ pBS->FreePool(Handle);
+ return EFI_NOT_FOUND;
+ }
+ *HandleBuffer = Handle;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS InitSystemVariable(
+ IN CHAR16 *NameStr, IN UINTN DataSize, IN VOID *Data
+)
+{
+ UINTN Size = 0;
+ EFI_STATUS Status;
+ Status = pRS->GetVariable(NameStr, &EfiVariableGuid, NULL, &Size, NULL);
+ if (Status==EFI_NOT_FOUND)
+ {
+ return pRS->SetVariable(
+ NameStr, &EfiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize, Data);
+ }
+ return EFI_SUCCESS;
+}
+
+static EFI_HANDLE *RootHandles;
+static UINTN NumberOfHandles;
+VOID ConnectEverything()
+{
+ UINTN i;
+ for(i=0; i<NumberOfHandles; i++) pBS->ConnectController(RootHandles[i],NULL,NULL,TRUE);
+/////////////////////////////////////////
+//TODO: Ugly patch for the Floppy Controller. Find the better place for it!
+// It is necessary to Disconnect Floppy Device Handle when Floppy Drive is not connected.
+// This is necessary to disable Floppy Device in the Super I/O
+// and eliminate BBS Floppy boot option.
+// It was previously done (In Core 4.0) by the Floppy Controller driver.
+// However, EDK DXE Core (DxeMain) crashes during the
+// DisconnectController operation performed from within the Start function.
+// Because of that, the Floppy Controller driver code is commented out
+// and this patch is created.
+// If you remove this code, you should also remove
+// LpcHandle & LpcDevicePath global variables.
+// They are only used to implement this patch.
+ if (LpcDevicePath)
+ {
+ EFI_HANDLE Handle;
+ ACPI_HID_DEVICE_PATH FloppyCtrl = {
+ {ACPI_DEVICE_PATH,ACPI_DP,sizeof(ACPI_HID_DEVICE_PATH)},
+ EISA_PNP_ID(0x0604),0
+ };
+ EFI_DEVICE_PATH_PROTOCOL *ChildDp=DPAddNode(LpcDevicePath, &FloppyCtrl.Header);
+ EFI_STATUS Status=pBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &ChildDp, &Handle);
+ if (!EFI_ERROR(Status) && isEndNode(ChildDp))
+ {
+ VOID* pDummy;
+ Status = pBS->HandleProtocol(Handle,&gEfiBlockIoProtocolGuid,&pDummy);
+ if (EFI_ERROR(Status)) pBS->DisconnectController(LpcHandle,NULL,Handle);
+ }
+ }
+}
+VOID DisconnectEverything()
+{
+ UINTN i;
+ for(i=0; i<NumberOfHandles; i++) pBS->DisconnectController(RootHandles[i],NULL,NULL);
+}
+
+VOID ReadyToBoot(UINT16 OptionNumber)
+{
+ //signal EFI_EVENT_SIGNAL_READY_TO_BOOT
+ EFI_EVENT ReadToBootEvent;
+ EFI_STATUS Status;
+ if (OptionNumber!= (UINT16)-1)
+ pRS->SetVariable(
+ L"BootCurrent", &EfiVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(OptionNumber), &OptionNumber
+ );
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK, NULL, NULL, &ReadToBootEvent
+ );
+ if (!EFI_ERROR(Status)) {
+ pBS->SignalEvent(ReadToBootEvent);
+ pBS->CloseEvent(ReadToBootEvent);
+ }
+}
+
+#if CSM_SUPPORT
+EFI_STATUS BootLegacy(EFI_DEVICE_PATH_PROTOCOL *Dp, UINT16 Number)
+{
+ UINTN i, Old=-1, New, Priority=-1;
+ BBS_BBS_DEVICE_PATH *BbsEntry = (BBS_BBS_DEVICE_PATH*)Dp;
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *HddInfo;
+ BBS_TABLE *BbsTable;
+
+ // Legacy Boot
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ if(EFI_ERROR(Status)) return Status;
+ LegacyBios->GetBbsInfo(LegacyBios, &HddCount, &HddInfo, &BbsCount, &BbsTable);
+ if (!BbsCount) return EFI_NOT_FOUND;
+ for(i=0; i<BbsCount; i++)
+ {
+ if ( // !BbsTable[i].StatusFlags.Enabled
+ /*||*/ BbsTable[i].BootPriority==BBS_IGNORE_ENTRY
+ || BbsTable[i].BootPriority==BBS_DO_NOT_BOOT_FROM
+ ) continue;
+ if (!BbsTable[i].BootPriority && Old==-1) Old=i;
+ if ( BbsTable[i].DeviceType==BbsEntry->DeviceType
+ && BbsTable[i].BootPriority < Priority
+ )
+ {
+ Priority = BbsTable[i].BootPriority;
+ New = i;
+ }
+ }
+ if (Old!=-1) BbsTable[Old].BootPriority=BbsTable[New].BootPriority;
+ BbsTable[New].BootPriority=0;
+ ReadyToBoot(Number);
+ return LegacyBios->LegacyBoot(LegacyBios,(BBS_BBS_DEVICE_PATH*)Dp,0,0);
+}
+#endif
+
+EFI_STATUS BootEfi(EFI_DEVICE_PATH_PROTOCOL *Dp, UINT16 Number, VOID *pOptions, UINT32 Size)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ Status=pBS->LoadImage(TRUE, TheImageHandle, Dp, NULL, 0, &Handle);
+ if (EFI_ERROR(Status)) return Status;
+ Status=pBS->HandleProtocol(Handle,&gEfiLoadedImageProtocolGuid,&Image);
+ if (!EFI_ERROR(Status) && Size)
+ {
+ Image->LoadOptionsSize = Size;
+ Image->LoadOptions = pOptions;
+ }
+ ReadyToBoot(Number);
+ return pBS->StartImage(Handle, NULL, NULL);
+}
+
+EFI_STATUS Boot(EFI_LOAD_OPTION *BootOption, UINT16 Number, UINTN Size)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ Dp = (EFI_DEVICE_PATH_PROTOCOL*)
+ ( //skip the header
+ (UINT8*)(BootOption+1)
+ //skip the string
+ +(Wcslen((CHAR16*)(BootOption+1))+1)*sizeof(CHAR16)
+ );
+ if (Dp->Type!=BBS_DEVICE_PATH)
+ {
+ UINT8 *pOptions = (UINT8*)Dp+BootOption->FilePathListLength;
+ Status=BootEfi(Dp,Number,pOptions, (UINT32)((UINT8*)BootOption+Size-pOptions));
+ }
+#if CSM_SUPPORT
+ else
+ {
+ Status=BootLegacy(Dp,Number);
+ }
+#endif
+ return Status;
+}
+
+VOID RunDrivers(){
+ EFI_LOAD_OPTION *DriverOption = NULL; //buffer for DriverXXX variables
+ UINT16 *DriverOrder = NULL; //old(saved) Driver Order
+ UINTN DriverOrderSize = 0; //size of DriverOrder Variable
+ EFI_STATUS Status;
+ UINTN Size,i;
+ BOOLEAN ReconnectAll = FALSE;
+
+ //================== Init Driver Order buffers ========================//
+ Status = GetEfiVariable(L"DriverOrder", &EfiVariableGuid, NULL, &DriverOrderSize, &DriverOrder);
+ if (EFI_ERROR(Status)) return;
+ //===================================================================//
+ // Start drivers refered to by DriverXXXX //
+ //===================================================================//
+ for(i=0; i<DriverOrderSize/sizeof(UINT16); i++){
+ CHAR16 DriverStr[9];
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_HANDLE Handle;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ UINT32 SizeOfOptions;
+ UINT8 *Options;
+
+ // Get Driver Option
+ Swprintf(DriverStr,L"Driver%04X",DriverOrder[i]);
+ Status=GetEfiVariable(DriverStr, &EfiVariableGuid, NULL, &Size, &DriverOption);
+ if ( EFI_ERROR(Status)
+ || (DriverOption->Attributes & LOAD_OPTION_ACTIVE)==0
+ ) continue;
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL*)
+ ( //skip the header
+ (UINT8*)(DriverOption+1)
+ //skip the string
+ +(Wcslen((CHAR16*)(DriverOption+1))+1)*sizeof(CHAR16)
+ );
+ Status=pBS->LoadImage(
+ TRUE, TheImageHandle, DevicePath, NULL, 0, &Handle
+ );
+ if (EFI_ERROR(Status)) continue;
+ Status=pBS->HandleProtocol(
+ Handle,&gEfiLoadedImageProtocolGuid,&Image
+ );
+ Options = (UINT8*)DevicePath+DriverOption->FilePathListLength;
+ SizeOfOptions=(UINT32)((UINT8*)DriverOption+Size-Options);
+ if (!EFI_ERROR(Status)&& SizeOfOptions!=0){
+ Image->LoadOptionsSize = SizeOfOptions;
+ Image->LoadOptions = Options;
+ }
+ Status=pBS->StartImage(Handle, NULL, NULL);
+ if ( !EFI_ERROR(Status)
+ && (DriverOption->Attributes & LOAD_OPTION_FORCE_RECONNECT)!=0
+ ) ReconnectAll=TRUE;
+ }
+ pBS->FreePool(DriverOption);
+ pBS->FreePool(DriverOrder);
+ if (ReconnectAll){
+ DisconnectEverything();
+ ConnectEverything();
+ }
+}
+
+EFI_DEVICE_PATH_PROTOCOL* DiscoverPartition(
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+){
+ UINTN Count,i;
+ EFI_HANDLE *Handle;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *PartDevicePath=NULL;
+ HARDDRIVE_DEVICE_PATH* BootParitionDevicePath = (HARDDRIVE_DEVICE_PATH*)DevicePath;
+ //get list of available Block I/O devices
+ Status=pBS->LocateHandleBuffer(ByProtocol,&gEfiBlockIoProtocolGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return NULL;
+
+ for(i=0;i<Count;i++){
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDevicePath;
+ HARDDRIVE_DEVICE_PATH* PartitionNode;
+ Status = pBS->HandleProtocol(Handle[i],&gEfiBlockIoProtocolGuid,&BlockIo);
+ if (EFI_ERROR(Status)) continue;
+ // if this is not partition, continue
+ if (!BlockIo->Media->LogicalPartition) continue;
+ Status = pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&PartitionDevicePath);
+ if (EFI_ERROR(Status)) continue;
+ // Get last node of the device path. It should be partition node
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)DPGetLastNode(PartitionDevicePath);
+ //Check if our partition matches Boot partition
+ if ( PartitionNode->Header.Type!=MEDIA_DEVICE_PATH
+ || PartitionNode->Header.SubType!=MEDIA_HARDDRIVE_DP
+ ) continue;
+ if ( PartitionNode->PartitionNumber==BootParitionDevicePath->PartitionNumber
+ && PartitionNode->SignatureType==BootParitionDevicePath->SignatureType
+ && !MemCmp(PartitionNode->Signature,BootParitionDevicePath->Signature,16)
+ ){
+ //Match found
+ PartDevicePath = PartitionDevicePath;
+ break;
+ }
+ }
+ pBS->FreePool(Handle);
+ return PartDevicePath;
+}
+
+EFI_STATUS FwLoadFile (
+ IN EFI_LOAD_FILE_PROTOCOL *This, IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN BOOLEAN BootPolicy, IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL
+){
+ EFI_GUID *FileGuid;
+ UINTN FvCount,i;
+ EFI_HANDLE *FvHandle;
+ EFI_STATUS Status;
+
+ if (!BufferSize || *BufferSize && !Buffer)
+ return EFI_INVALID_PARAMETER;
+ if (!FilePath || isEndNode(FilePath)){
+ if (BootPolicy){
+ if (DefaultAppFfsGuidPtr==NULL) return EFI_UNSUPPORTED;
+ else FileGuid = DefaultAppFfsGuidPtr;
+ }else{
+ return EFI_INVALID_PARAMETER;
+ }
+ }else{
+ if ( FilePath->Type!=MEDIA_DEVICE_PATH
+ || FilePath->SubType!=MEDIA_FV_FILEPATH_DP
+ ) return EFI_INVALID_PARAMETER;
+ FileGuid = &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)FilePath)->NameGuid;
+ }
+ //If Buffer is NULL, ReadSection will allocate the memory.
+ //That's not what we need.
+ //Initialize Buffer with some value.
+ //We don't care what value is that because *BufferSize is 0 anyway,
+ //so nothing will be copied into the buffer.
+ //We know that *BufferSize is always 0 for NULL buffer because we checked that
+ //at the beginning of the routine.
+ if (!Buffer) Buffer = (VOID*)1;
+ Status=pBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvCount, &FvHandle);
+ if (EFI_ERROR(Status)) return Status;
+ Status=EFI_NOT_FOUND;
+ for(i=0; i<FvCount; i++)
+ {
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ UINT32 AuthStatus;
+ Status = pBS->HandleProtocol(FvHandle[i], &gEfiFirmwareVolume2ProtocolGuid, &Fv);
+ if (EFI_ERROR(Status)) continue;
+ Status = Fv->ReadSection(
+ Fv, FileGuid, EFI_SECTION_PE32,
+ 0, &Buffer, BufferSize, &AuthStatus
+ );
+ if (!EFI_ERROR(Status)){
+ if (Status==EFI_WARN_BUFFER_TOO_SMALL) Status=EFI_BUFFER_TOO_SMALL;
+ break;
+ }
+ }
+ pBS->FreePool(FvHandle);
+ return Status;
+}
+
+VOID InstallFwLoadFile(){
+ EFI_HANDLE Handle=NULL;
+ pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiLoadFileProtocolGuid, &FwLoadFileInterface,
+ &gEfiDevicePathProtocolGuid, &FwLoadFileDp,
+ NULL
+ );
+}
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SignalProtocolEvent
+//
+// Description: Internal function that installs/uninstall protocol
+// with a specified GUID and NULL interface.
+// Such protocols can be used as event signaling mechanism.
+//
+// Input: ProtocolGuid Pointer to the protocol GUID
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SignalProtocolEvent(IN EFI_GUID *ProtocolGuid){
+ EFI_HANDLE Handle = NULL;
+ pBS->InstallProtocolInterface (
+ &Handle, ProtocolGuid, EFI_NATIVE_INTERFACE,NULL
+ );
+ pBS->UninstallProtocolInterface (
+ Handle, ProtocolGuid, NULL
+ );
+}
+
+#ifdef EFI_DXE_PERFORMANCE
+VOID SavePerformanceData(IN EFI_EVENT Event, IN VOID *Context){
+ PERF_END (0, BDS_TOK, NULL, 0) ;
+ WriteBootToOsPerformanceData();
+}
+#endif
+
+VOID SaveFpdtDataOnLegacyBoot(IN EFI_EVENT Event, IN VOID *Context){
+ AmiFillFpdt (FillOsLoaderStartImageStart); // Fill OsLoaderStartImageStart field in FPDT
+}
+
+VOID SignalConnectDriversEvent(){
+ PROGRESS_CODE(DXE_BDS_CONNECT_DRIVERS);
+ SignalProtocolEvent(&BdsConnectDriversProtocolGuid);
+}
+
+VOID ConnectRootBridgeHandles(){
+ EFI_HANDLE *Handle;
+ UINTN NumberOfHandles;
+ EFI_STATUS Status;
+ UINTN i;
+
+ //Enumerate PCI Bus and Create handles for all PCI devices
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciRootBridgeIoProtocolGuid, NULL,
+ &NumberOfHandles, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<NumberOfHandles; i++)
+ pBS->ConnectController(Handle[i],NULL,NULL,FALSE);
+ pBS->FreePool(Handle);
+}
+
+VOID ReportConnectConOutProgressCode(){
+ PROGRESS_CODE(DXE_CON_OUT_CONNECT);
+}
+
+VOID ConnectVgaConOut(){
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+ EFI_DEVICE_PATH_PROTOCOL *OnBoard=NULL, *OffBoard=NULL;
+ UINT64 PciAttributes;
+
+ //Get a list of all PCI devices
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciIoProtocolGuid, NULL, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 PciClass;
+ Status=pBS->HandleProtocol(Handle[i],&gEfiPciIoProtocolGuid,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+ if (EFI_ERROR(Status)) continue;
+ if (PciClass!=PCI_CL_DISPLAY) continue;
+ Status=pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&Dp);
+ if (EFI_ERROR(Status)) continue;
+ //We found Display adapter
+ // Check if this is on-board device
+ //(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE is set).
+ Status = PciIo->Attributes(
+ PciIo, EfiPciIoAttributeOperationGet, 0, &PciAttributes
+ );
+ if ( !EFI_ERROR(Status)
+ && (PciAttributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE)
+ ) OnBoard = AddDevicePath(OnBoard,Dp);
+ else OffBoard = AddDevicePath(OffBoard,Dp);
+ }
+ pBS->FreePool(Handle);
+ //Offboard has a higher priority
+ OffBoard = AddDevicePath(OffBoard,OnBoard);
+ if (OffBoard)
+ {
+ ConnectDevicePath(OffBoard);
+ pBS->FreePool(OffBoard);
+ }
+}
+
+VOID ConnecConsoleVariable(CHAR16* ConVar){
+ EFI_DEVICE_PATH_PROTOCOL *ConPath=NULL;
+ UINTN Size = 0;
+
+ if (EFI_ERROR(
+ GetEfiVariable(ConVar, &EfiVariableGuid, NULL, &Size, &ConPath)
+ )) return;
+
+ //Connect all active console devices
+ ConnectDevicePath(ConPath);
+ pBS->FreePool(ConPath);
+}
+
+VOID InstallConsoleStartedProtocol(
+ CHAR16* ConDevVar, EFI_GUID* ProtocolGuid
+){
+ UINTN Size = 0;
+ VOID *Interface;
+
+ //Signal to Console Splitter that all console devices have been started
+ //if at least one console device exists (ConDev variable exists)
+ if (ConDevVar!=NULL && pRS->GetVariable(
+ ConDevVar, &EfiVariableGuid, NULL, &Size, NULL
+ ) == EFI_NOT_FOUND
+ ) return;
+ //if the protocol is already installed, return
+ if (!EFI_ERROR(pBS->LocateProtocol(ProtocolGuid, NULL, &Interface)))
+ return;
+ pBS->InstallProtocolInterface(
+ &TheImageHandle, ProtocolGuid, EFI_NATIVE_INTERFACE, NULL
+ );
+}
+
+VOID ConnectConOutVariable(){
+ ConnecConsoleVariable(L"ConOut");
+}
+
+VOID InstallConOutStartedProtocol(){
+ InstallConsoleStartedProtocol(L"ConOutDev", &ConOutStartedProtocolGuid);
+}
+
+VOID ReportConnectConInProgressCode(){
+ PROGRESS_CODE(DXE_CON_IN_CONNECT);
+}
+
+VOID ConnectPs2ConIn(){
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+
+ //Get a list of all PCI to ISA Bridges
+ Status = GetPciHandlesByClass(
+ PCI_CL_BRIDGE, PCI_CL_BRIDGE_SCL_ISA, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ EFI_DEVICE_PATH_PROTOCOL *Dp, *ChildDp;
+ ACPI_HID_DEVICE_PATH Ps2Kbd = {
+ {ACPI_DEVICE_PATH,ACPI_DP,sizeof(ACPI_HID_DEVICE_PATH)},
+ EISA_PNP_ID(0x303),0
+ };
+ ACPI_HID_DEVICE_PATH Ps2Mouse = {
+ {ACPI_DEVICE_PATH,ACPI_DP,sizeof(ACPI_HID_DEVICE_PATH)},
+ EISA_PNP_ID(0xF03),0
+ };
+ Status=pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&Dp);
+ if (EFI_ERROR(Status)) continue;
+ pBS->ConnectController(Handle[i],NULL,NULL,FALSE);
+ ChildDp=DPAddNode(Dp, &Ps2Kbd.Header);
+ ConnectDevicePath(ChildDp);
+ pBS->FreePool(ChildDp);
+ ChildDp=DPAddNode(Dp, &Ps2Mouse.Header);
+ ConnectDevicePath(ChildDp);
+ pBS->FreePool(ChildDp);
+ LpcHandle = Handle[i];
+ LpcDevicePath = Dp;
+ }
+ pBS->FreePool(Handle);
+
+}
+
+VOID ConnectUsbConIn(){
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+ //Get a list of all USB Controllers
+ Status = GetPciHandlesByClass(
+ PCI_CL_SER_BUS, PCI_CL_SER_BUS_SCL_USB, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+ }
+ pBS->FreePool(Handle);
+}
+
+VOID ConnectConInVariable(){
+ ConnecConsoleVariable(L"ConIn");
+}
+
+VOID InstallConInStartedProtocol(){
+ InstallConsoleStartedProtocol(L"ConInDev", &ConInStartedProtocolGuid);
+}
+
+VOID ConInAvailabilityBeep(){
+ LibReportStatusCode(EFI_PROGRESS_CODE, AMI_STATUS_CODE_BEEP_CLASS|1, 0, NULL, NULL);
+}
+
+VOID InitConVars()
+{
+ UINTN i;
+ UINTN Size = 0;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ConPath=NULL;
+
+ static CHAR16* ConVar[] = {L"ConOut", L"ConIn"};
+ static CHAR16* ConDev[] = {L"ConOutDev", L"ConInDev"};
+
+ // Install Console Stared Protocols
+ // ConSplitter will process notification by populating
+ // corresponding fields of the system table.
+ // At this point the protocol need to be installed
+ // even if no actual console devices are available
+ // to prevent problems on headless systems
+ // caused by NULL console pointers in the system table.
+ // The functions will not install the protocol if it has already been installed
+ InstallConsoleStartedProtocol(NULL, &ConOutStartedProtocolGuid);
+ InstallConsoleStartedProtocol(NULL, &ConInStartedProtocolGuid);
+
+ //Create non-existent ConVar variables for ConIn and ConOut
+ //ErrOut will be treated differently
+ for( i=0; i<2; i++){
+ if (EFI_ERROR(
+ GetEfiVariable(ConDev[i], &EfiVariableGuid, NULL, &Size, &ConPath)
+ )
+ ) continue;
+ //Set ConVar[i] equal to the ConDev[i]
+ pRS->SetVariable(
+ ConVar[i], &EfiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ Size, ConPath
+ );
+ }
+ //Let's take care about ErrOut
+ Status = GetEfiVariable(
+ L"ErrOutDev", &EfiVariableGuid, NULL, &Size, &ConPath
+ );
+ if ( Status == EFI_NOT_FOUND ){
+ Status = GetEfiVariable(
+ L"ConOutDev", &EfiVariableGuid, NULL, &Size, &ConPath
+ );
+ if (!EFI_ERROR(Status))
+ //Set ConErrDev equal to the ConOutDev
+ pRS->SetVariable(
+ L"ErrOutDev", &EfiVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ Size, ConPath
+ );
+ }
+ if (!EFI_ERROR(Status)){
+ //Set ErrOut
+ pRS->SetVariable(
+ L"ErrOut", &EfiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ Size, ConPath
+ );
+ }
+ if (ConPath) pBS->FreePool(ConPath);
+}
+
+#define IsRuntimeMemoryType(MemoryType) \
+ ((MemoryType) == EfiACPIReclaimMemory || \
+ (MemoryType) == EfiACPIMemoryNVS || \
+ (MemoryType) == EfiRuntimeServicesCode || \
+ (MemoryType) == EfiRuntimeServicesData || \
+ (MemoryType) == EfiReservedMemoryType )
+
+VOID SaveMemoryTypeInformation (
+ IN EFI_EVENT Event, IN VOID *Context
+){
+#ifdef EFI_DEBUG
+ CONST CHAR8* EfiMemTypeStr[] = {
+ "Reserved ",
+ "LoaderCode ",
+ "LoaderData ",
+ "BSCode ",
+ "BSData ",
+ "RSCode ",
+ "RSData ",
+ "Free ",
+ "Unusable ",
+ "ACPIReclaim",
+ "ACPINVS ",
+ "MMIO ",
+ "MMIOIOPort ",
+ "PalCode "
+ };
+ struct{
+ UINT32 Previous,Current,Next;
+ } MemoryInfoHistory[EfiMaxMemoryType];
+#endif
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_STATUS Status;
+ EFI_HOB_GUID_TYPE *MemoryInformationHob;
+ EFI_MEMORY_TYPE_INFORMATION *MemoryTypeInformation = NULL;
+ UINTN MemoryTypeInformationSize = 0;
+ BOOLEAN IsFirstBoot = FALSE;
+ EFI_MEMORY_TYPE_INFORMATION *CurrentMemoryTypeInformation;
+ UINTN i, j;
+ BOOLEAN MemoryTypeInformationModified;
+ BOOLEAN RtMemoryQuotasIncreased = FALSE;
+ UINT32 Current, Next;
+
+ static BOOLEAN MemoryTypeInformationIsSaved = FALSE;
+
+ // Make sure the processing is performed only once.
+ // (we are registering callback on multiple events in RegisterMemoryTypeInformationUpdateCallback)
+ if (MemoryTypeInformationIsSaved){
+ pBS->CloseEvent(Event);
+ return;
+ }
+
+ // Get the Memory Type Information settings from Hob if they exist,
+ // PEI is responsible for getting them from variable and building a Hob to save them.
+ MemoryInformationHob = GetEfiConfigurationTable(pST, &HobListGuid);
+ if (MemoryInformationHob == NULL) return;
+ if (EFI_ERROR(
+ FindNextHobByGuid(&gEfiMemoryTypeInformationGuid, &MemoryInformationHob)
+ )) return;
+
+ Status = pRS->GetVariable(
+ L"PreviousMemoryTypeInformation", &gEfiMemoryTypeInformationGuid, NULL,
+ &MemoryTypeInformationSize, NULL
+ );
+ IsFirstBoot = Status==EFI_NOT_FOUND;
+
+ MemoryTypeInformation = (EFI_MEMORY_TYPE_INFORMATION*)(MemoryInformationHob+1);
+ MemoryTypeInformationSize = MemoryInformationHob->Header.HobLength
+ - sizeof (EFI_HOB_GUID_TYPE);
+ // Save memory information for the current boot.
+ // It will be used if next boot is S4 resume.
+ Status = pRS->SetVariable (
+ L"PreviousMemoryTypeInformation", &gEfiMemoryTypeInformationGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ MemoryTypeInformationSize, MemoryTypeInformation
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ // Retrieve the current memory usage statistics. If they are not found, then
+ // no adjustments can be made to the Memory Type Information variable.
+ CurrentMemoryTypeInformation = GetEfiConfigurationTable(
+ pST, &gEfiMemoryTypeInformationGuid
+ );
+ if (CurrentMemoryTypeInformation == NULL) return;
+ MemoryTypeInformationModified = FALSE;
+ TRACE((TRACE_DXE_CORE, "BDS.%s(%X)\n",
+ "SaveMemoryTypeInformation", SaveMemoryTypeInformation
+ ));
+ // Adjust the Memory Type Information for the next boot
+ for (i = 0; MemoryTypeInformation[i].Type != EfiMaxMemoryType; i++) {
+ Current = 0;
+ for (j = 0; CurrentMemoryTypeInformation[j].Type != EfiMaxMemoryType; j++) {
+ if (MemoryTypeInformation[i].Type == CurrentMemoryTypeInformation[j].Type) {
+ Current = CurrentMemoryTypeInformation[j].NumberOfPages;
+ break;
+ }
+ }
+
+ // Set next value to 125% of the current
+ Next = Current + (Current >> 2);
+#ifdef EFI_DEBUG
+ MemoryInfoHistory[i].Previous = MemoryTypeInformation[i].NumberOfPages;
+ MemoryInfoHistory[i].Current = Current;
+ MemoryInfoHistory[i].Next = (Next > MemoryTypeInformation[i].NumberOfPages) ? Next : MemoryTypeInformation[i].NumberOfPages;
+#endif
+ // We are never decreasing the memory type usage values.
+ // It would've been more fair to check for inequality (!=) here to
+ // keep memory type information consistent with the actual memory usage.
+ // We are not doing it to workaround UEFI Windows 7 and Windows 8 bug.
+ // Windows loader can't properly handle (it crashes)
+ // memory map changes that happen after OS load has been launched
+ // and before the ExitBootServices call.
+ // It's very difficult to predict how much memory will be used during
+ // the execution of the Windows loader because in certain cases Windows loader
+ // is pretty active. For example, it sometimes calls
+ // ConnectController for all the devices.
+ // By never decreasing the memory type usage values, we are avoiding the problem
+ // by always assuming the worst case scenario (the heaviest memory usage).
+ // The drawback is, we are stealing more memory than is actually used from the user.
+ if (Next > MemoryTypeInformation[i].NumberOfPages){
+ if ( IsRuntimeMemoryType(MemoryTypeInformation[i].Type) )
+ RtMemoryQuotasIncreased = TRUE;
+ MemoryTypeInformation[i].NumberOfPages = Next;
+ MemoryTypeInformationModified = TRUE;
+ }
+ }
+
+ // If any changes were made to the Memory Type Information settings,
+ // set the new variable value;
+ if ( MemoryTypeInformationModified ){
+ TRACE((TRACE_DXE_CORE, " Memory Previous Current Next \n"));
+ TRACE((TRACE_DXE_CORE, " Type Pages Pages Pages \n"));
+ TRACE((TRACE_DXE_CORE, "=========== ======== ======== ========\n"));
+ for (i = 0; MemoryTypeInformation[i].Type != EfiMaxMemoryType; i++) {
+ TRACE((
+ TRACE_DXE_CORE, "%s %8X %8X %8X\n",
+ EfiMemTypeStr[MemoryTypeInformation[i].Type],
+ MemoryInfoHistory[i].Previous,
+ MemoryInfoHistory[i].Current,
+ MemoryInfoHistory[i].Next
+ ));
+ }
+ Status = pRS->SetVariable(
+ EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME, &gEfiMemoryTypeInformationGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ MemoryTypeInformationSize, MemoryTypeInformation
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (IsFirstBoot && RtMemoryQuotasIncreased){
+ TRACE((
+ TRACE_DXE_CORE,
+ "Default RT memory quotas have been increased. Resetting the system...\n"
+ ));
+ pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+ }
+ pBS->CloseEvent(Event);
+ MemoryTypeInformationIsSaved = TRUE;
+}
+
+VOID RegisterMemoryTypeInformationUpdateCallback(){
+ EFI_EVENT Event;
+ VOID *Registration;
+
+ EFI_BOOT_MODE BootMode = GetBootMode();
+ if ( BootMode == BOOT_ON_S4_RESUME
+ || BootMode == BOOT_ON_FLASH_UPDATE
+ || BootMode == BOOT_IN_RECOVERY_MODE
+ ) return;
+
+ // We really want to get control.
+ // That's why we are registering callbacks for multiple boot events hoping that
+ // at least one of them will be triggered.
+ // If multiple events are signaled, only the first one is handled
+ RegisterProtocolCallback(
+ &BeforeBootProtocolGuid,
+ SaveMemoryTypeInformation,
+ NULL, &Event, &Registration
+ );
+ RegisterProtocolCallback(
+ &BeforeLegacyBootProtocolGuid,
+ SaveMemoryTypeInformation,
+ NULL, &Event, &Registration
+ );
+ CreateLegacyBootEvent(TPL_CALLBACK, &SaveMemoryTypeInformation, NULL, &Event);
+ pBS->CreateEvent(
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,TPL_CALLBACK,
+ &SaveMemoryTypeInformation, NULL, &Event
+ );
+}
+
+VOID CallTheDispatcher(){
+ DXE_SERVICES *pDxe;
+
+ if (EFI_ERROR(LibGetDxeSvcTbl(&pDxe)))
+ return;
+ if (pDxe) pDxe->Dispatch();
+}
+
+VOID SignalAllDriversConnectedEvent(){
+ SignalProtocolEvent(&BdsAllDriversConnectedProtocolGuid);
+}
+
+VOID HandoffToTse(){
+ AMI_POST_MANAGER_PROTOCOL *AmiPostMgr=NULL;
+
+ if (!EFI_ERROR(pBS->LocateProtocol(
+ &AmiPostMgrProtocolGuid, NULL, &AmiPostMgr
+ ))) AmiPostMgr->Handshake();
+
+}
+
+VOID BdsEntry (IN EFI_BDS_ARCH_PROTOCOL *This)
+{
+
+ UINTN i;
+
+ PERF_END(0, DXE_TOK, NULL, 0);
+ PERF_START(0, BDS_TOK, NULL, 0);
+ InitParts2(TheImageHandle, pST);
+ //Lang & LangCodes are initialized by Setup driver
+ InitSystemVariable(L"Timeout", sizeof(UINT16), &DefaultTimeout);
+
+{
+ EFI_EVENT Event;
+ VOID *Registration;
+#ifdef EFI_DXE_PERFORMANCE
+ RegisterProtocolCallback(
+ &BeforeBootProtocolGuid,
+ SavePerformanceData,
+ NULL, &Event, &Registration
+ );
+ RegisterProtocolCallback(
+ &BeforeLegacyBootProtocolGuid,
+ SavePerformanceData,
+ NULL, &Event, &Registration
+ );
+
+#endif
+ RegisterProtocolCallback(
+ &BeforeLegacyBootProtocolGuid,
+ SaveFpdtDataOnLegacyBoot,
+ NULL, &Event, &Registration
+ );
+
+}
+ pBS->LocateHandleBuffer(AllHandles, NULL, NULL, &NumberOfHandles, &RootHandles);
+
+ for(i=0; BdsControlFlowFunctions[i]!=NULL; i++){
+ TRACE((TRACE_DXE_CORE, "BDS.%s(%X)\n",
+ BdsControlFlowFunctionNames[i], BdsControlFlowFunctions[i]
+ ));
+ BdsControlFlowFunctions[i]();
+ }
+}
+
+// Deprecated Variable.
+// Use TheImageHandle instead.
+EFI_HANDLE ThisImageHandle = NULL;
+
+EFI_STATUS BdsInit (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_HANDLE Handle = NULL;
+ InitAmiLib(ImageHandle, SystemTable);
+ ThisImageHandle = ImageHandle;
+ return pBS->InstallProtocolInterface(&Handle, &gEfiBdsArchProtocolGuid, EFI_NATIVE_INTERFACE, &BDS);
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Bds.uni b/Core/CORE_DXE/Bds.uni
new file mode 100644
index 0000000..dd24315
--- /dev/null
+++ b/Core/CORE_DXE/Bds.uni
Binary files differ
diff --git a/Core/CORE_DXE/BdsBoard.c b/Core/CORE_DXE/BdsBoard.c
new file mode 100644
index 0000000..ea5ee36
--- /dev/null
+++ b/Core/CORE_DXE/BdsBoard.c
@@ -0,0 +1,1074 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/BdsBoard.c 2 10/30/13 6:54a Ireneyang $
+//
+// $Revision: 2 $
+//
+// $Date: 10/30/13 6:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/BdsBoard.c $
+//
+// 2 10/30/13 6:54a Ireneyang
+// - Fix Setup menu erroneously shows multiple instances of
+// the same bootable device for EIP139412
+//
+// 65 5/20/13 4:37p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Implement ORPHAN_BOOT_POLICY_KEEP for legacy groups
+// [Files] BootOptions.h BootOptions.c BdsBoard.c
+//
+// 64 5/24/12 3:24p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Graphics console tokens moved from BdsBoard.c into
+// Tokens.c
+// [Files] BdsBoard.c Tokens.c
+//
+// 1 8/25/12 4:39a Wesleychen
+// Update to rev.63 for EIP85762.
+//
+// 63 4/09/12 5:41p Artems
+// Implementation of NON_FW_BOOT_OPTION_HIDE functionality
+//
+// 62 11/01/11 1:41p Felixp
+// Definition of the BeforeLegacyBootProtocolGuid variable is added.
+//
+// 61 10/28/11 2:52p Artems
+// Moved function ConnectConsoles to FastBoot module
+//
+// 60 3/28/11 3:49p Felixp
+// Bug fix: Cloning of BOOT_OPTION_NAME_PREFIX_FUNCTION,
+// BOOT_OPTION_NAME_SUFFIX_FUNCTION, or
+// BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION caused an unknown
+// identifier error because
+// "extern" declaration for the cloned function was missing.
+//
+// 59 3/09/11 5:47p Artems
+// For ConnectPS2ConIn function added #ifdef from PS2Ctl_SUPPORT
+//
+// 58 2/25/11 12:30p Artems
+// EIP 53767 - Velocity boot time above 5 seconds. Added provision to skip
+// USB keyboard initialization
+//
+// 57 2/15/11 6:50p Artems
+//
+// 56 1/24/11 3:51p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Modified to allow external f AutodetectKbdMousePortsPtr()
+// function.
+// [Files] - BdsBaord.c, CORE_DXE.C, and in PS2CTL module - kbc.c,
+// ps2ctl.h, ps2ctl.sdl, and ps2main.c
+// NOTE: Implementation of this change requires changes to the PS2CTL
+// module.
+//
+// 55 11/18/10 3:33p Felixp
+// Clean up
+//
+// 54 11/17/10 4:45p Felixp
+// Minor bug fix in SetBootOptionPriorities
+//
+// 53 11/15/10 5:23p Felixp
+// Default values of the orphan policy macros are updated to
+// match with the setting of the corresponding SDL tokens.
+// ApplyOrphanBootOptionsPolicy renamed to ApplyOrphanBootOptionPolicy
+// Some debug messages are removed
+//
+// 52 10/07/10 1:35p Felixp
+// Make sure code compiles without CSM
+//
+// 51 10/07/10 1:21p Felixp
+// Support for BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION SDL token is
+// added.
+//
+// 50 10/01/10 8:11a Felixp
+// Boot option normalization is moved from PreProcessBootOptions
+// to a separate function NormalizeBootOptions.
+//
+// 49 9/29/10 9:19a Felixp
+// Enhancement(EIP 39464) : Implementation of the BdsEntry function is
+// changed.
+// The BdsEntry is now a dispatching function that calls a collection of
+// functions
+// formed by the BDS_CONTROL_FLOW eLink.
+//
+// 48 9/21/10 3:31p Felixp
+// Boot Option Infrastructure Improvements:
+// - NORMALIZE_BOOT_OPTIONS SDL token is replaced with
+// NORMALIZE_BOOT_OPTION_NAME and NORMALIZE_BOOT_OPTION_DEVICE_PATH
+// - MATCH_BOOT_OPTION_BY_LOCATION and MATCH_BOOT_OPTION_BY_DEVICE
+// SDL tokens and the supporting code are added.
+//
+// 47 9/02/10 11:47a Felixp
+//
+// 46 8/27/10 9:33a Felixp
+// Bug fix in the implementation of the eLink-based hooks.
+// Function headers added.
+//
+// 45 8/20/10 4:10p Felixp
+// Bug fin in LZMA support ( InstallLzmaDecompressProtocol was called too
+// late).
+//
+// 44 8/20/10 3:25p Felixp
+//
+// 43 8/20/10 3:12p Felixp
+// LZMA compression support
+//
+// 42 6/30/10 11:11a Felixp
+// Clean up
+//
+// 41 6/29/10 11:03p Felixp
+// New Boot Options Maintenance Infrastructure.
+// See AMI_Aptio_4.x_Boot_Options_Maintenance_Infrastructure_Porting_Guide
+// _NDA.doc for details.
+//
+// 40 5/07/10 6:03p Felixp
+// Improvement in CreateLegacyBootOption (EIP 38132): Protection against
+// BootOrder buffer overrun is added
+//
+// 39 4/22/10 10:44p Felixp
+// INSTALL_DUMMY_SECURITY_PROTOCOL SDL token is created.
+//
+// 38 2/24/10 8:23a Felixp
+//
+// 37 2/24/10 8:22a Felixp
+// IsFastBoot function removed (it is part of the FastBoot eModule).
+//
+// 36 2/03/10 3:40p Oleksiyy
+// Minor bug fix
+//
+// 35 2/02/10 5:46p Felixp
+// Fast Boot related code is removed from BDS. It is now part of the stand
+// alone FastBoot eModule.
+//
+// 34 10/28/09 12:23p Felixp
+// Minor improvement of the CreateDefaultBootOptions function: compiler
+// dependent code is removed(EIP 28577).
+//
+// 33 10/09/09 6:18p Felixp
+// UGA pixel type replaced with GOP type (UEFI 2.1 compatibility)
+//
+// 32 3/06/09 2:12p Felixp
+// Bug fix in IsFastBoot function (SetupData pointer was used after memory
+// had been freed).
+//
+// 31 1/16/09 3:00p Felixp
+// Iso9660FileSystemSupportEnabled global constant is added.
+// The constant is used to enable/disable ISO96660 partition support in
+// the partition driver.
+//
+// 30 11/03/08 5:21p Felixp
+// Do no re-create boot option for the built-in Shell, if Shell is not
+// included into the ROM
+//
+// 29 10/22/08 10:58a Felixp
+// Code to recreate deleted boot option for the built-in Shell is
+// added(EIP 15524).
+// Processing of the DriverOrder list is added.
+//
+// 28 10/21/08 5:56p Felixp
+// Multi-language support added to UEFI boot options implementation
+//
+// 27 10/17/08 3:47p Yakovlevs
+// Support for UEFI boot options added
+//
+// 26 9/30/08 11:08p Felixp
+// BeforeBootProtocolGuid is added
+//
+// 25 6/06/08 10:52a Felixp
+// Support for boot with minimal configuration added
+//
+// 24 11/08/07 4:52p Felixp
+// Code updated to compile and work without CSM.
+//
+// 23 10/26/07 2:38p Felixp
+// New FW based load file protocl is added.
+// This protocol is used to load FW based EFI applications such as built
+// in Shell.
+//
+// 22 10/19/07 9:20a Felixp
+// - SDL tokens are added in CORE_DXE.sdl to customize list of text
+// modes.
+// - SDL tokens are added in CORE_DXE.sdl to customize color values(EIP:
+// 9854).
+// BdsBoard updated with the graphic console tables
+//
+// 21 4/10/07 9:36a Felixp
+//
+// 19 2/12/07 1:46p Felixp
+// 1. Correct handling of disabled legacy BBS options
+// 2. Name of the legacy device removed from legacy boot option because it
+// is not needed (AMITSE does not use it)
+// 3. Clean up in ConnectDevicePath
+//
+// 18 1/31/07 11:57a Yakovlevs
+// Fixed EIP 8888. BIOS build w/o SIO_SUPPORT
+//
+// 17 12/29/06 2:39p Felixp
+//
+// 16 10/12/06 9:39a Felixp
+// Default boot order changed (from HD, CD to CD,HD)
+//
+// 15 6/08/06 7:12p Sivagarn
+// - Included function headers
+// - Updated file header
+// - Fixed EIP 7580 issue. Search for (EIP7580) for changes
+//
+// 14 3/13/06 1:44a Felixp
+//
+// 13 1/12/06 7:00p Felixp
+// Do nor create Shell boot option if Shell module is not in the project
+// or disabled.
+//
+// 12 12/12/05 9:46a Felixp
+// Default boot order changed.
+//
+// 11 11/08/05 4:07a Felixp
+// Setup notification GUIDs added
+//
+// 10 11/07/05 10:26a Felixp
+// 1. Support for Boot with Minimum Configuration
+// 2. Support for customization of default boot options and their order
+// 3. Support for Shell residing at any FV
+//
+// 7 5/24/05 2:52p Felixp
+// Boot menu moved to SetupEngine
+//
+// 2 4/08/05 3:02p Felixp
+// Improved responce for the QuietBoot
+//
+// 1 4/08/05 7:39a Felixp
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: BdsBoard.C
+//
+// Description: This file contains BDS/CORE_DXE related OEM code. There are
+// variables defined in this file that might change for each
+// OEM project
+////---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//---------------------------------------------------------------------------
+// Include Files
+//---------------------------------------------------------------------------
+#include "BootOptions.h"
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/Decompress.h>
+#include <CORE_DXEStrTokens.h>
+#include <Setup.h>
+#include <GenericSio.h>
+#include <BootOptioneLinks.h>
+#ifdef CSM_SUPPORT
+#include <Protocol/LegacyBiosExt.h>
+#endif
+
+//---------------------------------------------------------------------------
+// MACRO Constants
+//---------------------------------------------------------------------------
+#define _AND_ & // (EIP7580)+
+
+#ifndef FW_ORPHAN_BOOT_OPTIONS_POLICY
+#define FW_ORPHAN_BOOT_OPTIONS_POLICY ORPHAN_BOOT_OPTIONS_POLICY_DELETE
+#endif
+#ifndef NON_FW_ORPHAN_BOOT_OPTIONS_POLICY
+#define NON_FW_ORPHAN_BOOT_OPTIONS_POLICY ORPHAN_BOOT_OPTIONS_POLICY_KEEP
+#endif
+#ifndef ORPHAN_GROUP_HEADERS_POLICY
+#define ORPHAN_GROUP_HEADERS_POLICY ORPHAN_BOOT_OPTIONS_POLICY_DELETE
+#endif
+
+//---------------------------------------------------------------------------
+// Type definitions
+//---------------------------------------------------------------------------
+typedef enum{
+// BoTagLegacyXxx
+// BoTagUefiXxx
+// BoTagXxx
+ BoTagLegacyFloppy,
+ BoTagLegacyHardDisk,
+ BoTagLegacyCdrom,
+ BoTagLegacyPcmcia,
+ BoTagLegacyUsb,
+ BoTagLegacyEmbedNetwork,
+ BoTagLegacyBevDevice,
+ BoTagUefi,
+ BoTagEmbeddedShell
+} BOOT_OPTION_TAG;
+
+//---------------------------------------------------------------------------
+// Constant and Variables declarations
+//---------------------------------------------------------------------------
+const UINT16 DefaultTimeout = DEFAULT_BOOT_TIMEOUT;
+
+STRING_REF BbsDevTypeNameToken[] = {
+ STRING_TOKEN(STR_FD),
+ STRING_TOKEN(STR_HD),
+ STRING_TOKEN(STR_CD),
+ STRING_TOKEN(STR_PCMCIA),
+ STRING_TOKEN(STR_USB),
+ STRING_TOKEN(STR_NET),
+ STRING_TOKEN(STR_BEV),
+ STRING_TOKEN(STR_UNKNOWN)
+};
+
+struct{
+ UINT8 Type;
+ UINT8 SubType;
+ STRING_REF StrToken;
+} DpStrings[] = {
+ {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, STRING_TOKEN(STR_ATAPI)},
+ {MESSAGING_DEVICE_PATH, MSG_SCSI_DP, STRING_TOKEN(STR_SCSI)},
+ {MESSAGING_DEVICE_PATH, MSG_USB_DP, STRING_TOKEN(STR_USB)},
+ {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, STRING_TOKEN(STR_NET)},
+ {MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, STRING_TOKEN(STR_HD)},
+ {MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, STRING_TOKEN(STR_CD)}
+};
+
+//these GUIDs are used by BDS.c
+EFI_GUID SetupEnterProtocolGuid=AMITSE_SETUP_ENTER_GUID;
+EFI_GUID SecondBootOptionProtocolGuid=AMITSE_AFTER_FIRST_BOOT_OPTION_GUID;
+EFI_GUID BeforeBootProtocolGuid = AMITSE_EVENT_BEFORE_BOOT_GUID;
+#ifndef EFI_AMI_LEGACYBOOT_PROTOCOL_GUID
+#define EFI_AMI_LEGACYBOOT_PROTOCOL_GUID \
+ {0x120d28aa, 0x6630, 0x46f0, 0x81, 0x57, 0xc0, 0xad, 0xc2, 0x38, 0x3b, 0xf5}
+#endif
+EFI_GUID BeforeLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+EFI_GUID ShellFfsFileNameGuid = SHELL_GUID;
+#if Shell_SUPPORT
+EFI_GUID *DefaultAppFfsGuidPtr = &ShellFfsFileNameGuid;
+#else
+EFI_GUID *DefaultAppFfsGuidPtr = NULL;
+#endif
+
+EFI_GUID SetupVariableGuid = SETUP_GUID;
+
+struct {
+ VENDOR_DEVICE_PATH media;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH ffs;
+ EFI_DEVICE_PATH_PROTOCOL end;
+} ShellDp = {
+ {
+ {
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
+ sizeof(VENDOR_DEVICE_PATH)
+ },
+ AMI_MEDIA_DEVICE_PATH_GUID
+ },
+ {
+ {
+ MEDIA_DEVICE_PATH, MEDIA_FV_FILEPATH_DP,
+ sizeof(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+ },
+ SHELL_GUID
+ },
+ {
+ END_DEVICE_PATH, END_ENTIRE_SUBTYPE,
+ sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ }
+};
+
+const STRING_REF UnknownDeviceToken = STRING_TOKEN(STR_UNKNOWN);
+
+BOOT_OPTION_TAG LegacyBootOptionTags[] = {
+ BoTagLegacyFloppy,
+ BoTagLegacyHardDisk,
+ BoTagLegacyCdrom,
+ BoTagLegacyPcmcia,
+ BoTagLegacyUsb,
+ BoTagLegacyEmbedNetwork,
+ BoTagLegacyBevDevice,
+ UNASSIGNED_HIGHEST_TAG
+};
+
+BOOT_OPTION_TAG BootOptionTagPriorities[] = {
+ BOOT_OPTION_TAG_PRIORITIES,
+ UNASSIGNED_HIGHEST_TAG
+};
+
+BOOLEAN NormalizeBootOptionName = NORMALIZE_BOOT_OPTION_NAME;
+BOOLEAN NormalizeBootOptionDevicePath = NORMALIZE_BOOT_OPTION_DEVICE_PATH;
+
+//---------------------------------------------------------------------------
+// External variables
+//---------------------------------------------------------------------------
+extern EFI_GUID EfiVariableGuid;
+
+#if SIO_SUPPORT // (EIP8888)+
+extern SPIO_LIST_ITEM SIO_DEVICE_LIST EndOfList; // (EIP7580)+
+#endif // (EIP8888)-
+//---------------------------------------------------------------------------
+// Variables
+//---------------------------------------------------------------------------
+
+#if SIO_SUPPORT // (EIP8888)+
+SPIO_LIST_ITEM *gSpioList[] = {SIO_DEVICE_PTR_LIST NULL}; // (EIP7580)+
+#endif // (EIP8888)-
+
+//---------------------------------------------------------------------------
+// Function Prototypes
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Function Implementations
+//---------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DevicePathNodeToStrRef
+//
+// Description: This function converts node from the device path to a string.
+// Once the whole device path is converted the string is used as
+// as a boot opton name.
+// This function is only used is component name protocol does not report device name.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *Dp - pointer to the device path node
+//
+// Output: STRING_REF - string token (-1, if the string token is not available)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+STRING_REF DevicePathNodeToStrRef(EFI_DEVICE_PATH_PROTOCOL *Dp){
+ UINTN i;
+ //Built in Shell is a special case
+ if ( NODE_LENGTH(Dp)==NODE_LENGTH(&ShellDp.media.Header)
+ && MemCmp(Dp,&ShellDp.media.Header,NODE_LENGTH(Dp))==0
+ ) return STRING_TOKEN(STR_SHELL);
+ //BBS device path is another special case
+#ifdef CSM_SUPPORT
+ if ( Dp->Type==BBS_DEVICE_PATH ){
+ return BbsDevTypeNameToken[BBS_DEVICE_TYPE_TO_INDEX(((BBS_BBS_DEVICE_PATH*)Dp)->DeviceType)];
+ }
+#endif
+ for (i=0; i < sizeof(DpStrings)/sizeof(DpStrings[0]); i++){
+ if ((Dp->Type==DpStrings[i].Type) && (Dp->SubType==DpStrings[i].SubType)){
+ return DpStrings[i].StrToken;
+ }
+ }//for i
+
+ return INVALID_STR_TOKEN;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBbsEntryDeviceTypeDefault
+//
+// Description: Using the passed BBS_TABLE entry pointer, determine the device
+// type of the associated device
+//
+// Input: BBS_TABLE *BbsEntry - pointer to a BBS_TABLE entry
+//
+// Output: UINT16 - device type of the BBS entry, see LegacyBios.h for actual values
+// BBS_FLOPPY
+// BBS_HARDDISK
+// BBS_CDROM
+// BBS_PCMCIA
+// BBS_USB
+// BBS_EMBED_NETWORK
+// BBS_BEV_DEVICE
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetBbsEntryDeviceTypeDefault(BBS_TABLE *BbsEntry){
+#ifdef CSM_SUPPORT
+ UINT16 DeviceType = BbsEntry->DeviceType;
+#if BBS_USB_DEVICE_TYPE_SUPPORT
+ if ( BbsEntry->Class == PCI_CL_SER_BUS
+ && BbsEntry->SubClass == PCI_CL_SER_BUS_SCL_USB
+ ) return BBS_USB;
+#endif
+#if BBS_NETWORK_DEVICE_TYPE_SUPPORT
+ if ( BbsEntry->Class == PCI_CL_NETWORK
+ && BbsEntry->DeviceType == BBS_BEV_DEVICE
+ ) return BBS_EMBED_NETWORK;
+#endif
+ return DeviceType;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLegacyDevOrderType
+//
+// Description: Using the passed BOOT_OPTION structure, which should correspond to
+// a legacy device entry, determine the device type
+//
+// Input: BOOT_OPTION *Option - pointer to the BOOT_OPTION structure for the
+// device in question
+//
+// Output: UINT16 - device type of the BOOT_OPTION item, see LegacyBios.h for actual values
+// BBS_FLOPPY
+// BBS_HARDDISK
+// BBS_CDROM
+// BBS_PCMCIA
+// BBS_USB
+// BBS_EMBED_NETWORK
+// BBS_BEV_DEVICE
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetLegacyDevOrderType(BOOT_OPTION *Option){
+ return ((BBS_BBS_DEVICE_PATH*)Option->FilePathList)->DeviceType;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindTagPriority
+//
+// Description: For the passed Tag entry, return the correct boot priority based on
+// the BootOptionTagPriorities global variable that is filled out
+// based on the SDL Token BOOT_OPTION_TAG_PRIORITIES.
+//
+// Input: UINT16 Tag - one of the following items of the BOOT_OPTION_TAG enum:
+// BoTagLegacyFloppy
+// BoTagLegacyHardDisk
+// BoTagLegacyCdrom
+// BoTagLegacyPcmcia
+// BoTagLegacyUsb
+// BoTagLegacyEmbedNetwork
+// BoTagLegacyBevDevice
+// BoTagUefi
+// BoTagEmbeddedShell
+//
+// Output: The index of this item in the BootOptionTagPriorities structure, which
+// also corresponds to the boot priority that should be assigned to this
+// class of device
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 FindTagPriority(UINT16 Tag){
+ UINT32 i;
+ for(i=0; BootOptionTagPriorities[i]!=UNASSIGNED_HIGHEST_TAG; i++)
+ if (Tag==BootOptionTagPriorities[i]) return i;
+ return UNASSIGNED_HIGHEST_TAG;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsShellBootOption
+//
+// Description: Determine if the passed BOOT_OPTION is the built in EFI Shell
+//
+// Input: BOOT_OPTION *Option - the boot option in question
+//
+// Output: BOOLEAN - TRUE - this boot option represent the built in EFI Shell
+// FALSE - this is not the built in EFI Shell
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsShellBootOption(BOOT_OPTION *Option){
+ EFI_DEVICE_PATH_PROTOCOL *Dp = Option->FilePathList;
+
+ if (Dp==NULL) return FALSE;
+ if ( NODE_LENGTH(Dp)==NODE_LENGTH(&ShellDp.media.Header)
+ && MemCmp(Dp,&ShellDp.media.Header,NODE_LENGTH(Dp))==0
+ ) return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetBootOptionTags
+//
+// Description: Go through the entire boot option list and Apply priorities for
+// each entry in the list.
+//
+// Input: DLIST *BootOptionList - the entire Boot Option List
+//
+// Output: none
+//
+// Note: To change boot order priorities, do not modify this function,
+// modify the SDL Token BootOptionTagPriorities.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetBootOptionTags(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ UINT32 UefiBootOptionsInc = 0x100;
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ UINT32 TagPriority;
+ UINT32 BaseTag = UNASSIGNED_HIGHEST_TAG;
+#ifdef CSM_SUPPORT
+ if (IsLegacyBootOption(Option)){
+ UINT16 DeviceType;
+ DeviceType = ((BBS_BBS_DEVICE_PATH*)Option->FilePathList)->DeviceType;
+ BaseTag = LegacyBootOptionTags[BBS_DEVICE_TYPE_TO_INDEX(DeviceType)];
+ }else
+#endif
+ if (IsShellBootOption(Option)) BaseTag = BoTagEmbeddedShell;
+ else BaseTag = BoTagUefi;
+ if (BaseTag == UNASSIGNED_HIGHEST_TAG) continue;
+ TagPriority = FindTagPriority(BaseTag);
+ //UEFI boot options must have unique tags, otherwise then will be groupped when
+ //GROUP_BOOT_OPTIONS_BY_TAG tokens is enabled
+ if (BaseTag == BoTagUefi) BaseTag += UefiBootOptionsInc++;
+ Option->Tag = BootOptionTag(BaseTag, TagPriority);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateGroupHeader
+//
+// Description: Create a Group Header Entry for the passed BOOT_OPTION and add the
+// group header to the master boot options list
+//
+// Input: DLIST *BootOptionList - the master boot options list to add the newly
+// created group item
+// BOOT_OPTION *FirstGroupOption - the boot option which needs linked to a
+// group item
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateGroupHeader(DLIST *BootOptionList, BOOT_OPTION *FirstGroupOption){
+#ifdef CSM_SUPPORT
+ static struct {
+ BBS_BBS_DEVICE_PATH bbs;
+ EFI_DEVICE_PATH_PROTOCOL end;
+ } BbsDpTemplate = {
+ {
+ {BBS_DEVICE_PATH,BBS_BBS_DP,sizeof(BBS_BBS_DEVICE_PATH)},
+ BBS_HARDDISK,0,0
+ },
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,sizeof(EFI_DEVICE_PATH_PROTOCOL)}
+ };
+
+ BOOT_OPTION *Option;
+
+ if (!IsLegacyBootOption(FirstGroupOption)) return;
+ Option = CreateBootOption(BootOptionList);
+ Option->BootOptionNumber = FirstGroupOption->BootOptionNumber;
+ Option->Priority = FirstGroupOption->Priority;
+ Option->Tag = FirstGroupOption->Tag;
+ Option->FwBootOption = TRUE;
+ Option->GroupHeader = TRUE;
+ BbsDpTemplate.bbs.DeviceType=GetBbsEntryDeviceType(FirstGroupOption->BbsEntry);
+ Option->FilePathList = DPCopy(&BbsDpTemplate.bbs.Header);
+ Option->FilePathListLength = DPLength(Option->FilePathList);
+ ConstructBootOptionName(Option);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetBootOptionPriorities
+//
+// Description: Go through the boot option list and set the priorities of each
+// group of devices
+//
+// Input: DLIST *BootOptionList - the master list of boot options
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetBootOptionPriorities(){
+ DLINK *Link;
+ UINT16 PreviousBootOptionNumber = INVALID_BOOT_OPTION_NUMBER;
+ UINT32 PreviousTag = UNASSIGNED_HIGHEST_TAG;
+ UINT32 PreviousPriority=0;
+ BOOT_OPTION *Option;
+ UINT16 NextOptionNumber;
+
+ //Detect first unused boot option number
+ NextOptionNumber = 0;
+ if (!DListEmpty(BootOptionList)){
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ if ( Option->BootOptionNumber != INVALID_BOOT_OPTION_NUMBER
+ && Option->BootOptionNumber > NextOptionNumber
+ ) NextOptionNumber = Option->BootOptionNumber;
+ }
+ NextOptionNumber++;
+ }
+
+ SortList(BootOptionList, CompareTagThenPriority);
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+#if GROUP_BOOT_OPTIONS_BY_TAG
+ if (Option->BootOptionNumber==INVALID_BOOT_OPTION_NUMBER){
+ if ( PreviousTag != Option->Tag
+ || Option->Tag==UNASSIGNED_LOWEST_TAG
+ || Option->Tag==UNASSIGNED_HIGHEST_TAG
+ ) PreviousBootOptionNumber=NextOptionNumber++;
+ Option->BootOptionNumber=PreviousBootOptionNumber;
+ Option->Priority=++PreviousPriority;
+ }else{
+ PreviousBootOptionNumber = Option->BootOptionNumber;
+ PreviousPriority = Option->Priority;
+ }
+ PreviousTag = Option->Tag;
+#else
+ if (Option->BootOptionNumber==INVALID_BOOT_OPTION_NUMBER){
+ Option->BootOptionNumber=(NextOptionNumber)++;
+ Option->Priority=++PreviousPriority;
+ }else{
+ PreviousPriority = Option->Priority;
+ }
+#endif
+ }
+ DUMP_BOOT_OPTION_LIST(BootOptionList,"After Setting Priorities");
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateGroupHeaders
+//
+// Description: Go throuhg the the boot option list and
+//
+// Input:
+//
+// Output:
+//
+// Note: This function assums that the BootOptionList is already sorted by tag and
+// then by priority. failure to adhere to those assumptions will cause
+// undesired behavoir
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateGroupHeaders(DLIST *BootOptionList){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ UINT32 PreviousTag = UNASSIGNED_LOWEST_TAG;
+
+ //PRECONDITION: Boot Option List is sorted by tag then by priority
+
+ DUMP_BOOT_OPTION_LIST(BootOptionList,"Before Adding Group Headers");
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ if (PreviousTag == Option->Tag) continue;
+ PreviousTag = Option->Tag;
+ if ( Option->Tag==UNASSIGNED_LOWEST_TAG
+ || Option->Tag==UNASSIGNED_HIGHEST_TAG
+ ) continue;
+ if (!Option->GroupHeader) CreateGroupHeader(BootOptionList,Option);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ApplyOrphanBootOptionPolicy
+//
+// Description: Apply the correct policy to the passed orphaned boot iptions
+//
+// Input: DLIST *BootOptionList - the master boot option list
+// BOOT_OPTION *Option - The orphaned boot option
+// UINTN Policy - the policy to follow, valid values are
+// ORPHAN_BOOT_OPTIONS_POLICY_DELETE
+// ORPHAN_BOOT_OPTIONS_POLICY_DISABLE
+// ORPHAN_BOOT_OPTIONS_POLICY_KEEP
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ApplyOrphanBootOptionPolicy(
+ DLIST *BootOptionList, BOOT_OPTION *Option, const int Policy
+){
+ if (Policy==ORPHAN_BOOT_OPTIONS_POLICY_DELETE){
+ if (Option->BootOptionNumber!=INVALID_BOOT_OPTION_NUMBER){
+ CHAR16 BootStr[9];
+ Swprintf(BootStr,L"Boot%04X",Option->BootOptionNumber);
+ pRS->SetVariable(
+ BootStr, &EfiVariableGuid, 0, 0, NULL
+ );
+ }
+ DeleteBootOption(BootOptionList, Option);
+ }else if (Policy==ORPHAN_BOOT_OPTIONS_POLICY_DISABLE){
+ Option->Attributes &= ~LOAD_OPTION_ACTIVE;
+ }else if (Policy==ORPHAN_BOOT_OPTIONS_POLICY_HIDE){
+ if(!IsLegacyBootOption(Option) || Option->GroupHeader)
+ Option->Attributes |= LOAD_OPTION_HIDDEN;
+ MaskFilePathList(Option);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PreProcessBootOptions
+//
+// Description: Attempts to find stale boot options in the master boot option
+// list, and apply the specified policy to them.
+//
+// Policy is based on SDL tokens: FW_ORPHAN_BOOT_OPTIONS_POLICY and
+// NON_FW_ORPHAN_BOOT_OPTIONS_POLICY
+//
+// Input: DLIST *BootOptionList - master boot option list
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PreProcessBootOptions(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ // Process boot options not associated with the particular boot device.
+ // We can't process group headers just yet because groups that
+ // are non-empty now, can become empty at the end of this loop
+ // once their orphan members are deleted.
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ //skip group headers for now; we'll process them later
+ //in the PostProcessBootOptions
+ if (Option->GroupHeader || IsBootOptionWithDevice(Option))
+ continue;
+ if (Option->FwBootOption)
+ ApplyOrphanBootOptionPolicy(
+ BootOptionList, Option, FW_ORPHAN_BOOT_OPTIONS_POLICY
+ );
+ else
+ ApplyOrphanBootOptionPolicy(
+ BootOptionList, Option, NON_FW_ORPHAN_BOOT_OPTIONS_POLICY
+ );
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PostProcessBootOptions
+//
+// Description: Go through the master boot option list and apply orphan boot option
+// policy to the boot option groups
+//
+// Input: DLIST *BootOptionList - the master boot option list
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PostProcessBootOptions(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ SortList(BootOptionList, CompareTagThenPriority);
+ //Now we are ready for the processing of orphan group headers.
+ //process empty groups ( groups with just the header)
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ if (!Option->GroupHeader) continue;
+ if (IsGroupOrphan(Option))
+ ApplyOrphanBootOptionPolicy(BootOptionList, Option, ORPHAN_GROUP_HEADERS_POLICY);
+ }
+
+#if GROUP_BOOT_OPTIONS_BY_TAG
+ CreateGroupHeaders(BootOptionList);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNamePrefixDefault
+//
+// Description: Based on the passed boot option, determine if a prefix
+// needs prepended to the front of the boot option name. If return
+// value is non-zero, then the returned number of CHAR16s from the
+// Name buffer should prepended to the front of the boot option name
+//
+// Input: BOOT_OPTION *Option - boot option in question
+// CHAR16 *Name - pointer to the buffer in which to return the prefix
+// UINTN NameSize - size of the buffer being passed
+//
+// Output: UINTN - size of the string being returned
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionNamePrefixDefault(BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize){
+ if (IsLegacyBootOption(Option)) return 0;
+ //TODO: use string token
+ return Swprintf(Name, L"UEFI: ");
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNameSuffixDefault
+//
+// Description: Based on the passed boot option, determine if anything needs appended
+// to the boot option name string. If return value is not zero, then the
+// returned number of characers should be appended to the end of the name
+// string buffer.
+//
+// Input: BOOT_OPTION *Option - the boot option in question
+// CHAR16 *Name - pointer to the buffer to returne the append string
+// UINTN NameSize - the size of the buffer being passed
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionNameSuffixDefault(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ return 0;
+}
+
+extern DEVICE_PATH_TO_DEVICE_MATCH_TEST BOOT_OPTION_DP_MATCHING_FUNCTIONS EndOfDpMatchingFunctions;
+DEVICE_PATH_TO_DEVICE_MATCH_TEST *DpMatchingFunction[] = {
+ BOOT_OPTION_DP_MATCHING_FUNCTIONS NULL
+};
+
+extern BOOT_OPTION_TO_DEVICE_MATCH_TEST BOOT_OPTION_MATCHING_FUNCTIONS EndOfMatchingFunctions;
+BOOT_OPTION_TO_DEVICE_MATCH_TEST *MatchingFunction[] = {
+ BOOT_OPTION_MATCHING_FUNCTIONS NULL
+};
+
+extern FILTER_BOOT_DEVICE_TEST BOOT_OPTION_BOOT_DEVICE_FILTERING_FUNCTIONS EndOfFilteringFunctions;
+FILTER_BOOT_DEVICE_TEST *FilteringFunction[] = {
+ BOOT_OPTION_BOOT_DEVICE_FILTERING_FUNCTIONS NULL
+};
+
+extern CONSTRUCT_BOOT_OPTION_NAME BOOT_OPTION_BUILD_NAME_FUNCTIONS EndOfBuildNameFunctions;
+CONSTRUCT_BOOT_OPTION_NAME *BuildNameFunctions[] = {
+ BOOT_OPTION_BUILD_NAME_FUNCTIONS NULL
+};
+
+extern BUILD_BOOT_OPTION_FILE_PATH_LIST BOOT_OPTION_BUILD_FILE_PATH_FUNCTIONS EndOfBuildFilePathFunctions;
+BUILD_BOOT_OPTION_FILE_PATH_LIST *BuildFilePathFunctions[] = {
+ BOOT_OPTION_BUILD_FILE_PATH_FUNCTIONS NULL
+};
+
+extern CONSTRUCT_BOOT_OPTION_NAME BOOT_OPTION_NAME_PREFIX_FUNCTION;
+CONSTRUCT_BOOT_OPTION_NAME *ConstructBootOptionNamePrefix = BOOT_OPTION_NAME_PREFIX_FUNCTION;
+
+extern CONSTRUCT_BOOT_OPTION_NAME BOOT_OPTION_NAME_SUFFIX_FUNCTION;
+CONSTRUCT_BOOT_OPTION_NAME *ConstructBootOptionNameSuffix = BOOT_OPTION_NAME_SUFFIX_FUNCTION;
+
+#ifndef BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION
+#define BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION GetBbsEntryDeviceTypeDefault
+#endif
+extern GET_BBS_ENTRY_DEVICE_TYPE BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION;
+GET_BBS_ENTRY_DEVICE_TYPE *GetBbsEntryDeviceType = BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION;
+
+#if FAST_BOOT_SUPPORT
+VOID FastBoot();
+BOOLEAN IsFastBoot();
+
+VOID FastBootHook(){
+ if(IsFastBoot()) FastBoot();
+}
+#endif
+
+#if CAPSULE_SUPPORT
+EFI_STATUS CapsuleDispatch(IN DXE_SERVICES *DxeServices);
+VOID CapsuleHook(){
+ DXE_SERVICES *pDxe;
+
+ if (EFI_ERROR(LibGetDxeSvcTbl(&pDxe)))
+ return;
+ // Process capsule
+ CapsuleDispatch(pDxe);
+}
+#endif
+//==========================================================
+//Graphic Console Tables
+//==========================================================
+const EFI_GRAPHICS_OUTPUT_BLT_PIXEL ColorArray[] = {
+ { GC_COLOR_BLACK , 0}, // case EFI_BLACK: // case EFI_BACKGROUND_BLACK >> 4
+ { GC_COLOR_BLUE , 0}, // case EFI_BLUE : // case EFI_BACKGROUND_BLUE >> 4
+ { GC_COLOR_GREEN , 0}, // case EFI_GREEN : // case EFI_BACKGROUND_GREEN >> 4
+ { GC_COLOR_CYAN , 0}, // case EFI_CYAN : // case EFI_BACKGROUND_CYAN >> 4
+ { GC_COLOR_RED , 0}, // case EFI_RED : // case EFI_BACKGROUND_RED >> 4
+ { GC_COLOR_MAGENTA , 0}, // case EFI_MAGENTA : // case EFI_BACKGROUND_MAGENTA >> 4
+ { GC_COLOR_BROWN , 0}, // case EFI_BROWN : // case EFI_BACKGROUND_BROWN >> 4
+ { GC_COLOR_LIGHTGRAY , 0}, // case EFI_LIGHTGRAY : // case EFI_BACKGROUND_LIGHTGRAY >> 4
+ { GC_COLOR_DARKGRAY , 0}, // case EFI_DARKGRAY :
+ { GC_COLOR_LIGHTBLUE , 0}, // case EFI_LIGHTBLUE :
+ { GC_COLOR_LIGHTGREEN , 0}, // case EFI_LIGHTGREEN :
+ { GC_COLOR_LIGHTCYAN , 0}, // case EFI_LIGHTCYAN :
+ { GC_COLOR_LIGHTRED , 0}, // case EFI_LIGHTRED :
+ { GC_COLOR_LIGHTMAGENTA, 0}, // case EFI_LIGHTMAGENTA :
+ { GC_COLOR_YELLOW , 0}, // case EFI_YELLOW :
+ { GC_COLOR_WHITE , 0} // case EFI_WHITE :
+};
+
+const BOOLEAN Iso9660FileSystemSupportEnabled =
+#ifdef FsIso9660_SUPPORT
+ (FsIso9660_SUPPORT==1)
+#else
+ FALSE
+#endif
+ ;
+
+BOOLEAN const InstallDummySecurityProtocol = INSTALL_DUMMY_SECURITY_PROTOCOL;
+
+//==========================================================
+// LZMA Compression Support
+//==========================================================
+#if LZMA_SUPPORT
+
+//LZMA Decompress protocol
+#define EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID \
+ { 0x9a44198e, 0xa4a2, 0x44e6, 0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f }
+
+EFI_STATUS LzmaDecomprGetInfo (
+ IN VOID *This,
+ IN VOID *Source, IN UINT32 SourceSize,
+ OUT UINT32 *DestinationSize, OUT UINT32 *ScratchSize
+){
+ return LzmaGetInfo(Source,SourceSize,DestinationSize,ScratchSize);
+}
+
+EFI_STATUS LzmaDecomprDecompress (
+ IN VOID *This,
+ IN VOID* Source, IN UINT32 SourceSize,
+ IN OUT VOID* Destination, IN UINT32 DestinationSize,
+ IN OUT VOID* Scratch, IN UINT32 ScratchSize
+){
+ return LzmaDecompress(Source,SourceSize,Destination,DestinationSize,Scratch,ScratchSize);
+}
+
+VOID InstallLzmaDecompressProtocol(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+){
+static const EFI_DECOMPRESS_PROTOCOL LzmaDecompressInterface = {
+ &LzmaDecomprGetInfo, &LzmaDecomprDecompress
+};
+static const EFI_GUID CustomizedDecompressProtocolGuid = EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID;
+ EFI_HANDLE Handle = NULL;
+ SystemTable->BootServices->InstallProtocolInterface(
+ &Handle,(EFI_GUID*)&CustomizedDecompressProtocolGuid,
+ EFI_NATIVE_INTERFACE, (VOID*)&LzmaDecompressInterface
+ );
+}
+#endif
+
+extern BDS_CONTROL_FLOW_FUNCTION BDS_CONTROL_FLOW EndOfBdsControlFlowFunctions;
+BDS_CONTROL_FLOW_FUNCTION *BdsControlFlowFunctions[] = {
+ BDS_CONTROL_FLOW NULL
+};
+CHAR8 *BdsControlFlowFunctionNames[] = {
+ BDS_CONTROL_FLOW_NAMES NULL
+};
+
+VOID* AutodetectKbdMousePortsPtr=
+#if KBC_AUTODETECT_PORTS_FUNCTION
+ KBC_AUTODETECT_PORTS_FUNCTION
+#else
+ NULL
+#endif
+ ;
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/BootOptions.c b/Core/CORE_DXE/BootOptions.c
new file mode 100644
index 0000000..8cbe3b7
--- /dev/null
+++ b/Core/CORE_DXE/BootOptions.c
@@ -0,0 +1,2842 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/BootOptions.c 7 7/08/15 4:30a Chienhsieh $
+//
+// $Revision: 7 $
+//
+// $Date: 7/08/15 4:30a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/BootOptions.c $
+//
+// 7 7/08/15 4:30a Chienhsieh
+// [EIP210170] Improved BootOption DevicePath match algorithm.
+//
+// 6 7/15/14 9:55p Chienhsieh
+// Update to rev.39 for EIP172950, Core updates for UEFI Variable
+// Technical Advisory implement.
+//
+// 39 6/03/14 5:11p Artems
+// [TAG] EIP166565
+// [Category] Improvement
+// [Description] Runtime attribute for LegacyDevOrder variable is
+// modified depending on
+// token value, to support SCE tool
+// [Files] BootOptions.c
+//
+// 38 5/12/14 5:12p Artems
+// [TAG] EIP166565
+// [Category] Improvement
+// [Description] Variables LegacyDevOrder and OldLegacyDevOrder removed
+// runtime access attribute
+// [Files] BootOptions.c
+//
+// 5 10/30/13 6:53a Ireneyang
+// - Fix Setup menu erroneously shows multiple instances of
+// the same bootable device for EIP139412
+//
+// 36 6/21/13 2:54p Felixp
+// Bug fix(EIP 124559):
+// Symptom: When MATCH_BOOT_OPTION_BY_LOCATION was zero, off-board
+// legacy mass storage device
+// was mistakenly matched with on-board legacy boot options.
+// Root cause: DeviceTypeDevicePathTest was matching unrelated device
+// paths.
+// Solution: DeviceTypeDevicePathTest function is updated to return
+// FALSE (no-match) when
+// device interface type is unknown.
+// MatchBootOptionsToDevices is updated disable multiple boot option
+// matching for legacy devices.
+// Legacy device can't be matched with more than one boot option.
+// Files: BootOptions.c
+//
+// 35 5/20/13 4:33p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Implement ORPHAN_BOOT_POLICY_KEEP for legacy groups
+// [Files] BootOptions.h BootOptions.c BdsBoard.c
+//
+// 4 9/17/13 10:11p Thomaschen
+// Add EIP 134220 solution to fix boot option doesn't change
+// in special test step.
+//
+// 34 4/26/13 2:32p Felixp
+// [TAG] EIP109955
+// [Category] Improvement
+// [Description] Support USB device identification by serial number.
+//
+// 33 2/18/13 10:54a Felixp
+// Minor improvements:
+// - ConstructBootOptionName: unused variable is removed.
+// - BuildNameFilePath: check for out-of-memory condiftion.
+//
+// 32 2/18/13 10:52a Felixp
+// Improvement(EIP 115148): ReadBootOptions is updated to delete
+// ill-formed boot option variables.
+//
+// 31 2/07/13 2:18p Artems
+// [TAG] EIP111307
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] After insert two floppies into system and change Boot Mode
+// from ''UEFI'' to ''Legacy'' in BIOS setup utility, check it will show
+// two Floppy Drive BBS Priorites in BIOS Setup Utility
+// [RootCause] UEFI boot option was mistakingly matched to legacy boot
+// device
+// [Solution] Added specific matching function to eliminate mistaken
+// matches
+// [Files] BootOptions.c Core_Dxe.sdl
+//
+// 30 11/28/12 4:53p Felixp
+// Bug fix: The Bds was not building when CSM was not in the project.
+// Root cause: the MaskFilePathList function, which is used in BdsBoard.c,
+// was declared in BootOptions.c under #ifdef CSM_SUPPORT.
+// Solution: The definition of MaskFilePathList is moved outside of #ifdef
+// CSM_SUPPORT.
+//
+// 29 11/09/12 4:37p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ill-formed bootoption can get control
+// [RootCause] Function ValidateBootOption was returning BOOLEAN value,
+// while ReadBootOption was checked EFI_STATUS value
+// [Solution] Replaced function ValidateBootOption with
+// IsBootOptionValid function
+// Updated ReadBootOption function to perform correct check
+// [Files] BootOptions.c
+//
+// 28 7/19/12 6:28p Felixp
+// Enhacement:
+// Validate boot option NVRAM variables before processing (make sure all
+// the fields contain valid data).
+// The validation is performed by the new ValidateBootOption function.
+//
+// 27 7/19/12 4:29p Felixp
+// Enhacement:
+// The implementation of the MatchBootOptionsToDevices function is
+// changed.
+// The old implementation was always matching boot device to a single boot
+// option.
+// The new implementation allows matching of multiple boot options to the
+// same boot device.
+//
+// 26 7/02/12 4:40p Felixp
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] The implementation from previous check in is updated to
+// use BootOptionDpMatchingFunctions eLinks instead of
+// BootOptionMatchingFunctions.
+// It is more appropriate as this is a device path test.
+// MatchUsbClassOptionToUsbDevice is renamed to UsbClassDevicePathTest.
+// [Files] Core_Dxe.sdl, BootOptions.c
+//
+// 25 6/21/12 4:58p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] Added function to match existing UEFI boot option with
+// USB class to available USB boot device
+// [Files] Core_Dxe.sdl BootOptions.c
+//
+// 24 6/01/12 3:59p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Dump boot options doesn't print "hidden" attribute
+// [RootCause] Incorrect bit check
+// [Solution] Corrected bit check
+// [Files] BootOptions.c
+//
+// 23 4/12/12 6:12p Felixp
+// [TAG] EIP84716
+// [Category] Improvement
+// [Description] PXE boot item doesn't show particular IPV4 / IPV6 in
+// boot menu
+//
+// 22 4/09/12 5:56p Artems
+// Implementation of NON_FW_BOOT_OPTION_HIDE functionality
+//
+// 21 12/05/11 3:58p Felixp
+// [TAG] EIP72485
+// [Category] Improvement
+// [Description] Handling of the UEFI HDD boot devices has changed.
+// Old implementation: UEFI HDD boot devices were filtered out using
+// IsUefiHddBootDevice filter function prior to the boot option matching.
+// New implementation: UEFI HDD boot devices participate in the boot
+// option matching. Unmatched UEFI HDD devices are deleted by the
+// DeleteUnmatchedUefiHddBootDevices function.
+// The problems with the implementation is that UEFI HDD boot options have
+// always been orphan boot options,
+// which caused customer's confusion and side effects in the custom boot
+// option maintenance code.
+//
+// [Files] BootOptions.c
+// CORE_DXE.sdl
+//
+// 20 10/31/11 10:10a Felixp
+// Follow up to previous check in(EIP 69507): Bug fix
+// GetPhysicalNetworkCardHandle:
+// wrong pointer was passed to pBS->FreePool
+//
+// 19 10/24/11 5:45p Felixp
+// [TAG] EIP69507
+// [Category] Improvement
+// Improvement is the handling of the boot options associated with
+// the network devices in ConstructBootOptionNameByHandle function .
+// The name is now constructed using physical network card handle
+// (as opposed to a handle associated with the IP connection).
+//
+// 18 10/19/11 12:54p Felixp
+// [TAG] EIP71102
+// [Category] Improvement
+// SaveBootOptions is updated to validate the boot option before saving
+// it.
+// The boot option can be invalid due to:
+// - a hot plug boot device disconnected in the middle of the BDS
+// processing
+// - bug in the boot option processing eLink function from other eModule
+//
+// 17 9/20/11 12:39p Felixp
+// [TAG] EIP70093
+// [Category] Improvement
+// [Description] BuildLegacyDevOrderBuffer is updated.
+// The code that creates a dummy LegacyDevOrder variable
+// containing just a header when no legacy devices are found is removed.
+// The code was required to support old versions of TSE.
+// It is no longer required.
+//
+// 16 9/20/11 12:28p Felixp
+// DumpBootOptionList function that prints debug messages is updated to
+// print hidden attribute.
+//
+// 15 6/16/11 8:55a Felixp
+// Bug fix in FindLegacyDeviceGroupByBbsIndex to prevent premature
+// matching of a BBS index
+// to the Type of the next group in the LegacyDevOrder structure.
+//
+// 14 11/18/10 3:31p Felixp
+// Clean up
+//
+// 13 11/18/10 8:11a Felixp
+// Masking of legacy devices is added.
+//
+// 12 11/15/10 5:15p Felixp
+// LocateDevicePathTest: function is updated to perform a full device path
+// match
+// (earlier implementation could match boot option with the handle of the
+// parent device)
+// DeviceTypeDevicePathTest: code that handles removable device without a
+// media is removed
+// (it may have unintended consequences)
+// NormalizeBootOptions: the order of normalization is changed to
+// normalize device path
+// prior to the name (to make sure name reflects updated device path)
+//
+// 11 10/07/10 1:35p Felixp
+// Make sure code compiles without CSM.
+//
+// 10 10/07/10 12:58p Felixp
+// BuildLegacyDevOrderBuffer function is added
+//
+// 9 10/06/10 5:33p Felixp
+// Bug fix in DeviceTypeDevicePathTest function.
+//
+// 8 10/01/10 8:07a Felixp
+// NormalizeBootOptions function is added.
+//
+// 7 9/29/10 9:23a Felixp
+// 1. Enhancement(EIP 39464) : Implementation of the BdsEntry function is
+// changed.
+// The BdsEntry is now a dispatching function that calls a collection of
+// functions
+// formed by the BDS_CONTROL_FLOW eLink.
+// 2. Minor Imrpvement in ConstructBootOptionName function.
+//
+// 6 9/22/10 12:41p Felixp
+// Bug fix in AdjustLegacyBootOptionPriorities: the disabled boot option
+// was not enabled based on LagacyDevOrder status
+//
+// 5 9/21/10 3:33p Felixp
+// Boot Option Infrastructure Improvements:
+// - NORMALIZE_BOOT_OPTIONS SDL token is replaced with
+// NORMALIZE_BOOT_OPTION_NAME and NORMALIZE_BOOT_OPTION_DEVICE_PATH
+// - MATCH_BOOT_OPTION_BY_LOCATION and MATCH_BOOT_OPTION_BY_DEVICE
+// SDL tokens and the supporting code are added.
+//
+// 4 8/27/10 9:32a Felixp
+// Function headers added
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: BootOptions.c
+//
+// Description: Contains the code for dealing with boot options and their maintance
+//
+////---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include "BootOptions.h"
+#include <Protocol/PDiskInfo.h>
+#include <Protocol/UsbIo.h>
+
+EFI_HII_HANDLE HiiHandle=0;
+EFI_GUID AmiBbsDevicePathGuid = AMI_BBS_DEVICE_PATH_GUID;
+EFI_GUID AmiMaskedDevicePathGuid = AMI_MASKED_DEVICE_PATH_GUID;
+EFI_GUID AmiDeviceNameDevicePathGuid = AMI_DEVICE_NAME_DEVICE_PATH_GUID;
+#ifdef CSM_SUPPORT
+EFI_GUID LegacyDevOrderGuid = LEGACY_DEV_ORDER_GUID;
+#endif
+
+DLIST BootOptionListStructure;
+DLIST BootDeviceListStructure;
+DLIST *BootOptionList = &BootOptionListStructure;
+DLIST *BootDeviceList = &BootDeviceListStructure;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SortList
+//
+// Description: Sort the list of DLIST items using the passed COMPARE_FUNCTION to
+// determine the correct ordering of items
+//
+// Input: DLIST *List - list of items to sort
+// COMPARE_FUNCTION Compare - function to use to to sort the list
+//
+// Output: DLIST *List
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SortList(DLIST *List, COMPARE_FUNCTION Compare){
+ DLIST MergeList;
+ DLINK *p, *q, *e;
+ UINTN pSize, qSize, inSize;
+ UINT32 NoMerges;
+ UINTN i;
+
+ if(List->Size <= 1) //nothing to sort
+ return;
+
+ inSize = 1;
+ MergeList = *List;
+
+ while(1)
+ {
+ p = MergeList.pHead;
+ DListInit(&MergeList); //clear list
+ NoMerges = 0;
+
+ while(p != NULL)
+ {
+ NoMerges++;
+ q = p;
+ for(i = 0, pSize = 0; i < inSize; i++)
+ {
+ pSize++;
+ q = q->pNext;
+ if(q == NULL)
+ break;
+ }
+
+ qSize = inSize;
+ while(pSize > 0 || (qSize > 0 && q != NULL))
+ {
+ if(pSize == 0)
+ {
+ e = q;
+ q = q->pNext;
+ DListAdd(&MergeList, e);
+ qSize--;
+ }
+ else if(qSize == 0 || q == NULL)
+ {
+ e = p;
+ p = p->pNext;
+ DListAdd(&MergeList, e);
+ pSize--;
+ }
+ else if(Compare(p, q) > 0)
+ {
+ e = q;
+ q = q->pNext;
+ DListAdd(&MergeList, e);
+ qSize--;
+ }
+ else
+ {
+ e = p;
+ p = p->pNext;
+ DListAdd(&MergeList, e);
+ pSize--;
+ }
+ }
+ p = q;
+ }
+ if(NoMerges <= 1)
+ break;
+ inSize *= 2;
+ }
+ *List = MergeList;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CompareTagThenPriority
+//
+// Description: Compare the two boot options passed and determine the priority of
+// the first parameter in relation to the second parameter
+// Try to compare based on the following parameters in order,
+// Tag, then Group Header, then Priority
+//
+// Input: DLINK *Link1 - boot option 1
+// DLINK *Link2 - boot option 2
+//
+// Output: INT32 - the comparison result
+// Less than zero - Boot option 1 is lower priority than boot option 2
+// zero - boot option 1 is same priority as boot option 2
+// greater than zero - boot option 1 is a higher priority than boot option 2
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INT32 CompareTagThenPriority(DLINK *Link1, DLINK *Link2){
+ BOOT_OPTION *Option1 = (BOOT_OPTION*)Link1;
+ BOOT_OPTION *Option2 = (BOOT_OPTION*)Link2;
+ if (Option1->Tag < Option2->Tag) return -1;
+ else if (Option1->Tag > Option2->Tag) return 1;
+ if (Option1->GroupHeader != Option2->GroupHeader)
+ return (Option1->GroupHeader) ? -1 : 1;
+ if (Option1->Priority < Option2->Priority) return -1;
+ else if (Option1->Priority > Option2->Priority) return 1;
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ComparePriorityThenBootOptionNumber
+//
+// Description: Compare the two passed boot options first by their priority
+// if their priorities are equal, compare them based on their
+// boot option number
+//
+// Input: DLINK *Link1 - boot option 1
+// DLINK *Link2 - boot option 2
+//
+// Output: INT32 - the comparison result
+// Less than zero - Boot option 1 is lower priority than boot option 2
+// zero - boot option 1 is same priority as boot option 2
+// greater than zero - boot option 1 is a higher priority than boot option 2
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INT32 ComparePriorityThenBootOptionNumber(DLINK *Link1, DLINK *Link2){
+ BOOT_OPTION *Option1 = (BOOT_OPTION*)Link1;
+ BOOT_OPTION *Option2 = (BOOT_OPTION*)Link2;
+ if (Option1->Priority < Option2->Priority) return -1;
+ else if (Option1->Priority > Option2->Priority) return 1;
+ if (Option1->BootOptionNumber < Option2->BootOptionNumber) return -1;
+ else if (Option1->BootOptionNumber > Option2->BootOptionNumber) return 1;
+ if (Option1->GroupHeader != Option2->GroupHeader)
+ return (Option1->GroupHeader) ? -1 : 1;
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateBootOption
+//
+// Description: Create a BOOT_OPTION for the first entry in the passed BootOptionList
+//
+// Input: DLIST *BootOptionList - the list entry that needs a BOOT_OPTION
+// structure created
+//
+// Output: BOOT_OPTION * - pointer to the created BOOT_OPTION
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOT_OPTION* CreateBootOption(DLIST *BootOptionList){
+ static BOOT_OPTION BootOptionTemplate = {
+ {NULL,NULL}, LOAD_OPTION_ACTIVE, NULL, NULL, 0, NULL, 0,
+ INVALID_BOOT_OPTION_NUMBER, LOWEST_BOOT_OPTION_PRIORITY,
+ UNASSIGNED_HIGHEST_TAG,
+ INVALID_HANDLE, INVALID_BBS_INDEX, NULL, FALSE, FALSE
+ };
+
+ BOOT_OPTION *Option = Malloc(sizeof(BOOT_OPTION));
+ ASSERT(Option!=NULL);
+ *Option = BootOptionTemplate;
+ DListAdd(BootOptionList, &Option->Link);
+ return Option;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteBootOption
+//
+// Description: Delete the passed BOOT_OPTION from the BootOptionList
+//
+// Input: DLIST *BootOptionList - the master boot option list
+// BOOT_OPTION *Option - the option that should be deleted from the
+// master boot option list
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteBootOption(DLIST *BootOptionList, BOOT_OPTION *Option){
+ DListDelete(BootOptionList,&Option->Link);
+ if (Option->Description!=NULL) pBS->FreePool(Option->Description);
+ if (Option->FilePathList!=NULL) pBS->FreePool(Option->FilePathList);
+ if (Option->OptionalDataSize!=0) pBS->FreePool(Option->OptionalData);
+ pBS->FreePool(Option);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateBootDevice
+//
+// Description: Create a boot device entry and add it to the BootDeviceList
+// fill the entry with the information from the passed parameters
+//
+// Input: DLIST *BootDeviceList - The master boot device list to add the
+// new boot device entry
+// EFI_HANDLE DeviceHandle - the handle of the device
+// UINT16 BbsIndex - the index in the bbs table of the device
+// BBS_TABLE *BbsEntry - the entire bbs table
+//
+// Output: BOOT_DEVICE * - the new boot device
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOT_DEVICE* CreateBootDevice(
+ DLIST *BootDeviceList, EFI_HANDLE DeviceHandle,
+ UINT16 BbsIndex, BBS_TABLE *BbsEntry
+){
+ BOOT_DEVICE *Device = Malloc(sizeof(BOOT_DEVICE));
+ ASSERT(Device!=NULL);
+ Device->BbsEntry = BbsEntry;
+ Device->BbsIndex = BbsIndex;
+ Device->DeviceHandle = DeviceHandle;
+ DListAdd(BootDeviceList, &Device->Link);
+ return Device;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteBootDevice
+//
+// Description: Delete the boot device out of the master boot device list
+//
+// Input: DLIST *BootDeviceList - the master boot device list
+// BOOT_DEVICE *Device - the boot device to delete from the master
+// boot device list
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteBootDevice(DLIST *BootDeviceList, BOOT_DEVICE* Device){
+ DListDelete(BootDeviceList, &Device->Link);
+ pBS->FreePool(Device);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateBootOptionWithBootDeviceInfo
+//
+// Description: Update the boot option with the information from the passed
+// boot device information
+//
+// Input: BOOT_OPTION *Option - the boot option that needs updated
+// BOOT_DEVICE *Device - the boot device that contains the information
+// that the boot option needs updated with
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateBootOptionWithBootDeviceInfo(
+ BOOT_OPTION *Option, BOOT_DEVICE* Device
+){
+ Option->BbsEntry = Device->BbsEntry;
+ Option->BbsIndex = Device->BbsIndex;
+ Option->DeviceHandle = Device->DeviceHandle;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateBootOptionsFromNvramOption
+//
+// Description: Create a boot option using the nvram information
+//
+// Input: DLIST *BootOptionList - the master boot option list
+// UINT16 BootOptionNumber - the XXXX of the BootXXXX boot option
+// EFI_LOAD_OPTION NvramOption - the associated EFI_LOAD_OPTION
+// UINTN NvramOptionSize - the sizeof the nvram option
+// UINT32 Priority - the priority of the boot option
+//
+// Output: BOOT_OPTION * - the created boot option
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOT_OPTION* CreateBootOptionsFromNvramOption(
+ DLIST *BootOptionList, UINT16 BootOptionNumber,
+ EFI_LOAD_OPTION *NvramOption, UINTN NvramOptionSize,
+ UINT32 *Priority
+){
+ BOOT_OPTION *Option;
+ UINTN DescriptionSize;
+ UINT32 *OptionalData;
+ UINT8 *FilePathList;
+ UINTN OptionalDataSize;
+
+ Option = CreateBootOption(BootOptionList);
+ Option->Attributes=NvramOption->Attributes;
+ DescriptionSize = (Wcslen((CHAR16*)(NvramOption+1))+1)*sizeof(CHAR16);
+ Option->Description = Malloc(DescriptionSize);
+ MemCpy(Option->Description, NvramOption+1, DescriptionSize);
+
+ FilePathList = (UINT8*)(NvramOption+1)+DescriptionSize;
+ Option->FilePathListLength = NvramOption->FilePathListLength;
+ Option->FilePathList = Malloc(Option->FilePathListLength);
+ MemCpy(
+ Option->FilePathList, FilePathList, Option->FilePathListLength
+ );
+
+ OptionalData = (UINT32*)(FilePathList + NvramOption->FilePathListLength);
+ OptionalDataSize = (UINT8*)NvramOption
+ + NvramOptionSize
+ - (UINT8*)OptionalData;
+ Option->BootOptionNumber = BootOptionNumber;
+ Option->Priority = *Priority;
+ *Priority = GetNextBootOptionPriority(*Priority);
+ if ( OptionalDataSize >= sizeof(UINT32) ){
+ if (*OptionalData==AMI_SIMPLE_BOOT_OPTION_SIGNATURE){
+ OptionalDataSize -= sizeof(UINT32);
+ OptionalData++;
+ Option->FwBootOption = TRUE;
+ }else if (*OptionalData==AMI_GROUP_BOOT_OPTION_SIGNATURE){
+ Option->FwBootOption = TRUE;
+ Option->GroupHeader = TRUE;
+ OptionalDataSize -= sizeof(UINT32);
+ OptionalData++;
+ while ( OptionalDataSize > AMI_NESTED_BOOT_OPTION_HEADER_SIZE){
+ NESTED_BOOT_OPTION *NestedBootOption = (NESTED_BOOT_OPTION*)OptionalData;
+ if ( NestedBootOption->Signature != AMI_NESTED_BOOT_OPTION_SIGNATURE
+ || NestedBootOption->Size > OptionalDataSize
+ ) break;
+ CreateBootOptionsFromNvramOption(
+ BootOptionList, BootOptionNumber, &NestedBootOption->Option,
+ NestedBootOption->Size-AMI_NESTED_BOOT_OPTION_HEADER_SIZE,
+ Priority
+ );
+ OptionalDataSize -= NestedBootOption->Size;
+ OptionalData = (UINT32*)((UINT8*)OptionalData+NestedBootOption->Size);
+ }
+ }
+ }
+
+ if (OptionalDataSize==0){
+ Option->OptionalData = NULL;
+ Option->OptionalDataSize = 0;
+ }else{
+ Option->OptionalData = Malloc(OptionalDataSize);
+ MemCpy(
+ Option->OptionalData, OptionalData, OptionalDataSize
+ );
+ Option->OptionalDataSize = OptionalDataSize;
+ }
+ return Option;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsBootOptionValid
+//
+// Description: The function checks if boot option is well-formed
+//
+// Input: EFI_LOAD_OPTION NvramOption, UINTN NvramOptionSize
+//
+// Output: TRUE - boot option is valid, FALSE otherwise
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsBootOptionValid(EFI_LOAD_OPTION *NvramOption, UINTN NvramOptionSize){
+ CHAR16 *Char;
+ CHAR16 *EndOfDescription;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINTN DevicePathSize;
+
+ // The boot option must have at least the header,
+ // an empty (just the NULL-terminator) description,
+ // and an empty device path (End-of-Device-Path node).
+ if (NvramOption->FilePathListLength<sizeof(EFI_DEVICE_PATH_PROTOCOL)) return FALSE;
+ if (NvramOptionSize < sizeof(*NvramOption)+sizeof(CHAR16)) return FALSE;
+ NvramOptionSize -= sizeof(*NvramOption);
+
+ if ( NvramOption->FilePathListLength >= NvramOptionSize ) return FALSE;
+ NvramOptionSize -= NvramOption->FilePathListLength;
+
+ // The description must include at least the NULL-terminator
+ if (NvramOptionSize < sizeof(CHAR16)) return FALSE;
+
+ // The description must be NULL-terminated
+ Char = (CHAR16*)(NvramOption+1);
+ EndOfDescription = (CHAR16*)((CHAR8*)Char+NvramOptionSize);
+ while( *Char && Char < EndOfDescription) Char++;
+ if (Char==EndOfDescription) return FALSE;
+
+ // Validate the device path;
+ Dp = (EFI_DEVICE_PATH_PROTOCOL*)(Char+1); // skip the terminating zero.
+ if (EFI_ERROR(IsValidDevicePath(Dp))) return FALSE;
+ // NvramOption->FilePathListLength can't be zero.
+ // We checked that at the start of the funciton.
+ DevicePathSize = NvramOption->FilePathListLength;
+ while (TRUE) {
+ UINTN Length = NODE_LENGTH(Dp);
+ if (Length>DevicePathSize) return FALSE;
+ // We are not making sure that Length is not equal to zero.
+ // This has already been verified by the IsValidDevicePath above.
+ DevicePathSize -= Length;
+ if (DevicePathSize < sizeof(EFI_DEVICE_PATH_PROTOCOL)){
+ if (DevicePathSize != 0 ) return FALSE;
+ //The last node must be an End-of-Device-Path node.
+ return
+ isEndNode(Dp)
+ && Dp->SubType == END_ENTIRE_SUBTYPE
+ && Length == sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ ;
+ }
+ Dp = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)Dp+Length);
+ }
+ //Should never reach this point.
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadBootOption
+//
+// Description: Read the boot options from NVRAM and create associated
+// boot options in the master boot option list for each valid
+// option
+//
+// Input: DLIST *BootOptionList - the list to update with the nvram options
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ReadBootOptions(){
+ UINT16 *BootOrder = NULL;
+ UINTN BootOrderSize = 0;
+ EFI_STATUS Status;
+ UINTN i;
+ EFI_LOAD_OPTION *NvramOption = NULL;
+ UINT32 Priority=IndexToBootPriority(0);
+ UINTN NvramOptionSize;
+ UINT16 MaxBootOptionNumber=0;
+
+ Status=GetEfiVariable(
+ L"BootOrder", &EfiVariableGuid, NULL, &BootOrderSize, &BootOrder
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<BootOrderSize/sizeof(UINT16); i++){
+ CHAR16 BootStr[9];
+
+ // Get Boot Option
+ Swprintf(BootStr,L"Boot%04X",BootOrder[i]);
+ Status=GetEfiVariable(
+ BootStr, &EfiVariableGuid, NULL, &NvramOptionSize, &NvramOption
+ );
+ if (EFI_ERROR(Status)) continue;
+ //Let's verify if boot option is well-formed
+ if (!IsBootOptionValid(NvramOption, NvramOptionSize)){
+ TRACE((TRACE_DXE_CORE,"The boot option Boot%04X is ill-formed. Deleting...\n",
+ BootOrder[i]
+ ));
+ pRS->SetVariable(BootStr, &EfiVariableGuid, 0, 0, NULL);
+ continue;
+ }
+ CreateBootOptionsFromNvramOption(
+ BootOptionList, BootOrder[i], NvramOption, NvramOptionSize, &Priority
+ );
+ if (BootOrder[i] > MaxBootOptionNumber)
+ MaxBootOptionNumber = BootOrder[i];
+ }
+ pBS->FreePool(NvramOption);
+ pBS->FreePool(BootOrder);
+}
+
+VOID MaskFilePathList(BOOT_OPTION *Option){
+ static struct {
+ VENDOR_DEVICE_PATH vendor;
+ EFI_DEVICE_PATH_PROTOCOL end;
+ } MaskedDp = {
+ {
+ {HARDWARE_DEVICE_PATH, HW_VENDOR_DP, {sizeof(VENDOR_DEVICE_PATH), 0}},
+ AMI_MASKED_DEVICE_PATH_GUID
+ },
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,sizeof(EFI_DEVICE_PATH_PROTOCOL)}
+ };
+ static MaskedDpLength = sizeof(MaskedDp);
+ UINT8 *NewDp;
+
+ NewDp = Malloc(Option->FilePathListLength + MaskedDpLength);
+ if (NewDp==NULL) return;
+ MemCpy(NewDp, &MaskedDp, MaskedDpLength);
+ MemCpy(
+ NewDp+MaskedDpLength, Option->FilePathList,
+ Option->FilePathListLength
+ );
+ pBS->FreePool(Option->FilePathList);
+ Option->FilePathList = (EFI_DEVICE_PATH_PROTOCOL*)NewDp;
+ Option->FilePathListLength += MaskedDpLength;
+}
+
+#ifdef CSM_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBbsIndexByPositionInTheGroup
+//
+// Description: Using the passed position, return the BBS index from the legacy dev
+// order group
+//
+// Input: LEGACY_DEVICE_ORDER *Group - The legacy device order
+// UINT16 Position - the index into the legacy dev order to return
+//
+// Output: UINT32 - the bbs index from the the legacy dev order
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetBbsIndexByPositionInTheGroup(
+ LEGACY_DEVICE_ORDER *Group, UINT16 Position
+){
+ UINT16* EndOfGroup = (UINT16*)(
+ (UINT8*)Group + Group->Length + sizeof(UINT32)
+ );
+ UINT16 *IndexPtr = &Group->Device[0];
+ UINT32 Counter = 0;
+
+ while(IndexPtr<EndOfGroup){
+ if (Counter == Position)
+ return *IndexPtr;
+ IndexPtr++;
+ Counter++;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindPositionInTheGroupByBbsIndex
+//
+// Description: Get the corresponding device index in the LEGACY_DEV_ORDER based on
+// the bbs index number. Legacy dev order organizes the boot priorities
+// of a class of devices (Cdrom, hdd, bev, etc) and the individual indexes
+// of the device are the relative priorities in which they should be used
+// to attempt a legacy boot.
+//
+// Input: LEGACY_DEVICE_ORDER *Group - pointer to the legacy dev order group
+// UINT16 BbsIndex - index of the device trying to be matched
+//
+// Output: UINT32 - the index of the device inside of the LEGACY_DEV_ORDER
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 FindPositionInTheGroupByBbsIndex(
+ LEGACY_DEVICE_ORDER *Group, UINT16 BbsIndex
+){
+ UINT16* EndOfGroup = (UINT16*)(
+ (UINT8*)Group + Group->Length + sizeof(UINT32)
+ );
+ UINT16 *IndexPtr = &Group->Device[0];
+ UINT32 Counter = 0;
+
+ while(IndexPtr<EndOfGroup){
+ if (*(UINT8*)IndexPtr == *(UINT8*)&BbsIndex)
+ return Counter;
+ IndexPtr++;
+ Counter++;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindLegacyDeviceGroupByBbsIndex
+//
+// Description: Go through the legacy device order structure and find the legacy dev order
+// index that matches the bss index.
+//
+// Input: LEGACY_DEVICE_ORDER *DevOrder - pointer to the legacy device order
+// UINTN DevOrderSize - size of the legacy dev order structure
+// UINT16 BbsIndex - index of the bbs device to match
+//
+// Output: LEGACY_DEVICE_ORDER *
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+LEGACY_DEVICE_ORDER* FindLegacyDeviceGroupByBbsIndex(
+ LEGACY_DEVICE_ORDER *DevOrder, UINTN DevOrderSize, UINT16 BbsIndex
+){
+ UINT16 *EndOfDevOrder = (UINT16*)((UINT8*)DevOrder+DevOrderSize);
+ LEGACY_DEVICE_ORDER* EndOfGroup = DevOrder;
+ LEGACY_DEVICE_ORDER* GroupStart = DevOrder;
+ UINT16 *IndexPtr = (UINT16*)EndOfGroup;
+
+ while(IndexPtr<EndOfDevOrder){
+ if (IndexPtr==(UINT16*)EndOfGroup){
+ IndexPtr = &EndOfGroup->Device[0];
+ GroupStart = EndOfGroup;
+ EndOfGroup = (LEGACY_DEVICE_ORDER*)(
+ (UINT8*)EndOfGroup + EndOfGroup->Length + sizeof(UINT32)
+ );
+ }
+ if (*(UINT8*)IndexPtr == *(UINT8*)&BbsIndex) return GroupStart;
+ IndexPtr++;
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustLegacyBootOptionPriorities
+//
+// Description: Go through the legacy dev order structure and adjust it ot match the
+// current boot priorities
+//
+// Input: DLIST *BootOptionList - the master boot option list
+//
+// Output: none
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AdjustLegacyBootOptionPriorities(){
+ EFI_STATUS Status;
+ UINTN DevOrderSize, OldDevOrderSize;
+ LEGACY_DEVICE_ORDER *DevOrder=NULL, *OldDevOrder=NULL;
+ DLINK *Link;
+ UINT16 BootOptionNumber;
+ UINT16 *IndexPtr;
+ UINT16 *EndOfDeviceList;
+ BOOT_OPTION *Option;
+ UINT16 GroupSize=0;
+ INT32 IndexInTheGroup=0;
+ LEGACY_DEVICE_ORDER *CurrentGroup;
+
+ Status = GetEfiVariable(
+ L"LegacyDevOrder", &LegacyDevOrderGuid, NULL,
+ &DevOrderSize, &DevOrder
+ );
+ if(EFI_ERROR(Status) || DevOrderSize < sizeof(LEGACY_DEVICE_ORDER)) return ;
+ Status = GetEfiVariable(
+ L"OldLegacyDevOrder", &LegacyDevOrderGuid, NULL,
+ &OldDevOrderSize, &OldDevOrder
+ );
+ if( EFI_ERROR(Status)
+ || OldDevOrderSize!=DevOrderSize
+ || MemCmp(DevOrder,OldDevOrder, DevOrderSize)==0
+ ){
+ pBS->FreePool(DevOrder);
+ if (!EFI_ERROR(Status)) pBS->FreePool(OldDevOrder);
+ return ;
+ }
+
+ BootOptionNumber = INVALID_BOOT_OPTION_NUMBER;
+ IndexPtr = (UINT16*)DevOrder;
+ EndOfDeviceList = (UINT16*)((UINT8*)IndexPtr+DevOrderSize);
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ INT32 NewIndexInTheGroup;
+ LEGACY_DEVICE_ORDER *OldGroup;
+ UINT16 BbsIndex;
+
+ if ( !IsLegacyBootOption(Option) || Option->GroupHeader) continue;
+ // this should never happen during the normal course of operation
+ if (IndexPtr>=EndOfDeviceList) break;
+ // during the normal course of operation both conditions should
+ // happen simultaneously
+ if (BootOptionNumber != Option->BootOptionNumber || GroupSize==0){
+ BootOptionNumber = Option->BootOptionNumber;
+ IndexPtr += GroupSize;
+ CurrentGroup = (LEGACY_DEVICE_ORDER*)IndexPtr;
+ GroupSize = (CurrentGroup->Length)/sizeof(UINT16)-1;
+ IndexPtr = &CurrentGroup->Device[0];
+ IndexInTheGroup = 0;
+ }
+ OldGroup = FindLegacyDeviceGroupByBbsIndex(OldDevOrder,DevOrderSize,*IndexPtr);
+ BbsIndex = GetBbsIndexByPositionInTheGroup(OldGroup,IndexInTheGroup);
+ NewIndexInTheGroup = FindPositionInTheGroupByBbsIndex(CurrentGroup,BbsIndex);
+
+ Option->Priority +=
+ (NewIndexInTheGroup-IndexInTheGroup)*DEFAULT_PRIORITY_INCREMENT;
+ if ((CurrentGroup->Device[NewIndexInTheGroup] & 0xff00)!=0)
+ Option->Attributes &= ~LOAD_OPTION_ACTIVE;
+ else
+ Option->Attributes |= LOAD_OPTION_ACTIVE;
+ IndexPtr++;
+ GroupSize--;
+ IndexInTheGroup++;
+ }
+ pBS->FreePool(DevOrder);
+ pBS->FreePool(OldDevOrder);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UnmaskOrphanDevices
+//
+// Description: This function unmasks orphan devices.
+// The orphan legacy devices are masked by the MaskOrphanDevices function.
+// TSE does not like legacy boot options for devices that are not in the system.
+// To trick TSE we we are camouflaging such boot options by adding GUIDed device path.
+// The device path is added by MaskOrphanDevices function rigth before saving
+// and removed by UnmaskOrphanDevices right after reading
+//
+//
+// Input: DLIST *BootOptionList - the master boot option list
+//
+// Output: none
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UnmaskOrphanDevices(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ VENDOR_DEVICE_PATH *MaskedDp;
+ UINTN MaskedDpLength;
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ MaskedDp = (VENDOR_DEVICE_PATH*)Option->FilePathList;
+ if ( MaskedDp->Header.Type != HARDWARE_DEVICE_PATH
+ || MaskedDp->Header.SubType != HW_VENDOR_DP
+ || guidcmp(&AmiMaskedDevicePathGuid, &MaskedDp->Guid) != 0
+ ) continue;
+ MaskedDpLength = DPLength(&MaskedDp->Header);
+ if (Option->FilePathListLength <= MaskedDpLength) continue;
+ Option->FilePathListLength -=MaskedDpLength;
+ MemCpy(
+ Option->FilePathList, (UINT8*)Option->FilePathList+MaskedDpLength,
+ Option->FilePathListLength
+ );
+ if(!IsLegacyBootOption(Option) || Option->GroupHeader)
+ Option->Attributes &= ~LOAD_OPTION_HIDDEN;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLegacyDevOrderBuffer
+//
+// Description: Go through the master boot option list and create
+// memory representation of the legacy dev order variable
+//
+// Input: DLIST *BootOptionList - the master boot option list
+//
+// Output: none
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BuildLegacyDevOrderBuffer(
+ LEGACY_DEVICE_ORDER **DevOrderBuffer, UINTN *BufferSize
+){
+ UINTN DevOrderSize;
+ LEGACY_DEVICE_ORDER *DevOrder, *GroupPtr;
+ UINT16 *DevPtr;
+ DLINK *Link;
+ UINT16 BootOptionNumber = INVALID_BOOT_OPTION_NUMBER;
+ BOOT_OPTION *Option;
+
+ if (DevOrderBuffer == NULL || BufferSize == NULL) return;
+ if (BootOptionList->Size == 0)
+ DevOrder = Malloc(sizeof(LEGACY_DEVICE_ORDER));
+ else
+ DevOrder = Malloc(BootOptionList->Size*sizeof(LEGACY_DEVICE_ORDER));
+ GroupPtr = DevOrder;
+ DevPtr = (UINT16*)DevOrder;
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ if ( !IsLegacyBootOption(Option) || Option->GroupHeader) continue;
+ if (Option->BootOptionNumber!=BootOptionNumber){
+ GroupPtr->Length = (UINT16)((UINT8*)DevPtr - (UINT8*)&GroupPtr->Length);
+ GroupPtr = (LEGACY_DEVICE_ORDER*)DevPtr;
+ BootOptionNumber = Option->BootOptionNumber;
+ GroupPtr->Type = GetLegacyDevOrderType(Option);
+ DevPtr = GroupPtr->Device;
+ }
+ if ((Option->Attributes&LOAD_OPTION_ACTIVE)==0)
+ *DevPtr = Option->BbsIndex | 0xff00;
+ else
+ *DevPtr = Option->BbsIndex;
+ DevPtr++;
+ }
+ GroupPtr->Length = (UINT16)((UINT8*)DevPtr - (UINT8*)&GroupPtr->Length);
+ DevOrderSize = (UINT8*)DevPtr - (UINT8*)DevOrder;
+
+ *DevOrderBuffer = DevOrder;
+ *BufferSize = DevOrderSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MaskOrphanDevices
+//
+// Description: This function masks orphan devices before saving them.
+// TSE does not like legacy boot options for devices that are not in the system.
+// To trick TSE we we are camouflaging such boot options by adding GUIDed device path.
+// The device path is added by MaskOrphanDevices function rigth before saving
+// and removed by UnmaskOrphanDevices right after reading
+//
+//
+// Input: DLIST *BootOptionList - the master boot option list
+//
+// Output: none
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MaskOrphanDevices(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ BOOT_OPTION *GroupHeader = NULL;
+
+ SortList(BootOptionList, ComparePriorityThenBootOptionNumber);
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ if (!IsLegacyBootOption(Option))
+ continue;
+ if (Option->GroupHeader){
+ if (GroupHeader!=NULL) MaskFilePathList(GroupHeader);
+ GroupHeader=Option;
+ continue;
+ }
+ if (IsBootOptionWithDevice(Option)){
+ if (Option->BootOptionNumber==GroupHeader->BootOptionNumber)
+ GroupHeader=NULL;
+ continue;
+ }
+ MaskFilePathList(Option);
+ }
+ if (GroupHeader!=NULL) MaskFilePathList(GroupHeader);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveLegacyDevOrder
+//
+// Description: Go through the master boot option list and use it to update the
+// legacy dev order variable
+//
+// Input: DLIST *BootOptionList - the master boot option list
+//
+// Output: none
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SaveLegacyDevOrder(){
+ UINTN DevOrderSize;
+ LEGACY_DEVICE_ORDER *DevOrder;
+
+ SortList(BootOptionList, ComparePriorityThenBootOptionNumber);
+ BuildLegacyDevOrderBuffer(&DevOrder, &DevOrderSize);
+ pRS->SetVariable(
+ L"LegacyDevOrder",
+ &LegacyDevOrderGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+#if RT_ACCESS_SUPPORT_IN_HPKTOOL
+ EFI_VARIABLE_RUNTIME_ACCESS |
+#endif
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DevOrderSize,
+ DevOrder
+ );
+ pRS->SetVariable(
+ L"OldLegacyDevOrder",
+ &LegacyDevOrderGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DevOrderSize,
+ DevOrder
+ );
+ pBS->FreePool(DevOrder);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectBbsDevice
+//
+// Description: Go through the bbs table and create a entry in the master boot order
+// list for each bbs table entry
+//
+// Input: DLIST *BootDeviceList - the master boot list
+//
+// Output: none
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CollectBbsDevices(DLIST *BootDeviceList){
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *HddInfo;
+ BBS_TABLE *BbsTable;
+ UINT16 i;
+
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ if(EFI_ERROR(Status)) return ;
+ LegacyBios->ShadowAllLegacyOproms(LegacyBios);
+ LegacyBios->GetBbsInfo(LegacyBios, &HddCount, &HddInfo, &BbsCount, &BbsTable);
+
+ for(i = 0; i < BbsCount; i++){
+ if(BbsTable[i].BootPriority == 0xffff) continue;
+ CreateBootDevice(
+ BootDeviceList,
+ (EFI_HANDLE)*(UINTN*)&BbsTable[i].IBV1,
+ i,&BbsTable[i]
+ );
+ }
+}
+
+#endif //#ifdef CSM_SUPPORT
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectProtocolDevices
+//
+// Description: Collect a list of all handles with a particular protocol installed
+// on them and create a boot device for each handle.
+//
+// Input: DLIST *BootDeviceList - the master boot list that needs boot devices
+// added to it.
+// EFI_GUID *ProtocolGuid - the protocol to use when getting a list of
+// device handles
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CollectProtocolDevices(DLIST *BootDeviceList, EFI_GUID *ProtocolGuid){
+ EFI_HANDLE *Devices;
+ UINTN NumberOfDevices;
+ EFI_STATUS Status;
+ UINTN i;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,ProtocolGuid, NULL,
+ &NumberOfDevices, &Devices
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<NumberOfDevices; i++){
+ CreateBootDevice(BootDeviceList,Devices[i],INVALID_BBS_INDEX,NULL);
+ }
+ pBS->FreePool(Devices);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectBootDevices
+//
+// Description: Helper function to generate a master boot list based on the
+// load file protocol, the simple file system protocol and, if
+// CSM support is enabled, the legacy bbs table
+//
+// Input: DLIST *BootDeviceList
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CollectBootDevices(){
+ CollectProtocolDevices(BootDeviceList,&gEfiLoadFileProtocolGuid);
+ CollectProtocolDevices(BootDeviceList,&gEfiSimpleFileSystemProtocolGuid);
+#ifdef CSM_SUPPORT
+ CollectBbsDevices(BootDeviceList);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsUefiHddBootDevice
+//
+// Description: Determine if this boot device is a UEFI HDD
+//
+// Input: BOOT_DEVICE *Device - the device in question
+//
+// Output: BOOLEAN - TRUE - Device is a UEFI HDD Boot Device and it should
+// be removed from the boot order list
+// FALSE - Device is not a UEFI hdd and it should be left
+// in the boot order
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsUefiHddBootDevice(BOOT_DEVICE *Device){
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_STATUS Status;
+
+ if ( Device->DeviceHandle == INVALID_HANDLE
+ || Device->BbsEntry != NULL
+ ) return FALSE;
+
+
+ Status=pBS->HandleProtocol(
+ Device->DeviceHandle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if (EFI_ERROR(Status)) return FALSE;
+ return !BlkIo->Media->RemovableMedia;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FilterBootDeviceList
+//
+// Description: Master filter handler. Function will call all ELINK functions
+// linked into the BootOptionBootDeviceFilteringFunctions list.
+// If any ELINK function returns FALSE, the device will be removed
+// from the function list
+//
+// Input: DLIST *BootDeviceList - the full boot order list
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FilterBootDeviceList(){
+// Filter Devices
+ BOOT_DEVICE *Device;
+ DLINK *Link;
+
+ FOR_EACH_BOOT_DEVICE(BootDeviceList, Link, Device){
+ UINT32 i;
+ for(i=0; FilteringFunction[i]!=NULL; i++)
+ if (FilteringFunction[i](Device)){
+ DeleteBootDevice(BootDeviceList, Device);
+ break;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateDevicePathTest
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *OptionalDevicePath -
+// BOOT_DEVICE *Device - the device
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN LocateDevicePathTest(EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath, BOOT_DEVICE *Device){
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ if (Device->DeviceHandle==INVALID_HANDLE) return FALSE;
+ Status=pBS->LocateDevicePath(
+ &gEfiDevicePathProtocolGuid, &OptionDevicePath, &Handle
+ );
+ if (EFI_ERROR(Status)) return FALSE;
+ if (Handle != Device->DeviceHandle) return FALSE;
+ if (isEndNode(OptionDevicePath)) return TRUE;
+ if (OptionDevicePath->Type != MEDIA_DEVICE_PATH) return FALSE;
+ return OptionDevicePath->SubType==MEDIA_FILEPATH_DP
+ || OptionDevicePath->SubType==MEDIA_FV_FILEPATH_DP;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PartitionDevicePathtest
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath -
+// BOOT_DEVICE *Device -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN PartitionDevicePathTest(
+ EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath, BOOT_DEVICE *Device
+){
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDevicePath;
+ HARDDRIVE_DEVICE_PATH* BootParitionDevicePath;
+ HARDDRIVE_DEVICE_PATH* PartitionNode;
+
+ if (Device->DeviceHandle==INVALID_HANDLE) return FALSE;
+ if ( OptionDevicePath->Type!=MEDIA_DEVICE_PATH
+ || OptionDevicePath->SubType!=MEDIA_HARDDRIVE_DP
+ ) return FALSE;
+ BootParitionDevicePath = (HARDDRIVE_DEVICE_PATH*)OptionDevicePath;
+ Status = pBS->HandleProtocol(
+ Device->DeviceHandle,&gEfiBlockIoProtocolGuid,&BlockIo
+ );
+ if (EFI_ERROR(Status)) return FALSE;
+ // if this is not partition, continue
+ if (!BlockIo->Media->LogicalPartition) return FALSE;
+ Status = pBS->HandleProtocol(
+ Device->DeviceHandle,&gEfiDevicePathProtocolGuid,&PartitionDevicePath
+ );
+ if (EFI_ERROR(Status)) return FALSE;
+ // Get last node of the device path. It should be partition node
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)DPGetLastNode(PartitionDevicePath);
+ //Check if our partition matches Boot partition
+ if ( PartitionNode->Header.Type!=MEDIA_DEVICE_PATH
+ || PartitionNode->Header.SubType!=MEDIA_HARDDRIVE_DP
+ ) return FALSE;
+ if ( PartitionNode->PartitionNumber==BootParitionDevicePath->PartitionNumber
+ && PartitionNode->SignatureType==BootParitionDevicePath->SignatureType
+ && !MemCmp(PartitionNode->Signature,BootParitionDevicePath->Signature,16)
+ ){
+ return TRUE;
+ }
+ return FALSE;
+}
+
+UINT8 GetDevicePathSubtype(EFI_DEVICE_PATH_PROTOCOL *Dp, UINT8 Type){
+ UINT8 SubType;
+
+ if (Dp == NULL) return 0;
+ SubType = 0;
+
+ for( ; !(isEndNode(Dp)); Dp=NEXT_NODE(Dp))
+ if (Dp->Type == Type) SubType = Dp->SubType;
+ return SubType;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeviceTypeDevicePathTest
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *Dp - The device path to search
+// Type Device - The type of node to search for
+//
+// Output: EFI_DEVICE_PATH_PROTOCOL*
+// NULL - No node was found
+// Non-null - A node was found, and the pointer was returned
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_DEVICE_PATH_PROTOCOL* GetDevicePathNodeOfType(EFI_DEVICE_PATH_PROTOCOL *Dp, UINT8 Type){
+ EFI_DEVICE_PATH_PROTOCOL *Node = NULL;
+
+ if (Dp == NULL) return NULL;
+
+ for( ; !(isEndNode(Dp)); Dp=NEXT_NODE(Dp))
+ if (Dp->Type == Type) Node = Dp;
+ return Node;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeviceTypeDevicePathTest
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *OptionalDevicePath -
+// BOOT_DEVICE *Device - the device
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN DeviceTypeDevicePathTest(EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath, BOOT_DEVICE *Device){
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 DeviceInterface, OptionInterface;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceMedia, *OptionMedia;
+
+ if (Device->DeviceHandle==INVALID_HANDLE) return FALSE;
+
+ Status=pBS->HandleProtocol(
+ Device->DeviceHandle, &gEfiDevicePathProtocolGuid, &Dp
+ );
+ if (EFI_ERROR(Status)) return FALSE;
+
+ DeviceInterface = GetDevicePathSubtype(
+ Dp, MESSAGING_DEVICE_PATH
+ );
+ //If DeviceInterface is 0, the interface type is unknown.
+ //Can't do the matching.
+ if (DeviceInterface == 0) return FALSE;
+ if (DeviceInterface == MSG_SATA_DP)
+ DeviceInterface = MSG_ATAPI_DP;
+ OptionInterface = GetDevicePathSubtype(
+ OptionDevicePath, MESSAGING_DEVICE_PATH
+ );
+ if (OptionInterface == MSG_SATA_DP)
+ OptionInterface = MSG_ATAPI_DP;
+ if (DeviceInterface != OptionInterface) return FALSE;
+
+ DeviceMedia = GetDevicePathNodeOfType(Dp,MEDIA_DEVICE_PATH);
+ OptionMedia = GetDevicePathNodeOfType(OptionDevicePath,MEDIA_DEVICE_PATH);
+ if ( DeviceMedia != NULL && OptionMedia != NULL
+ && NODE_LENGTH(DeviceMedia) == NODE_LENGTH(OptionMedia)
+ && MemCmp(DeviceMedia,OptionMedia,NODE_LENGTH(DeviceMedia)) == 0
+ ){
+ NormalizeBootOptionDevicePath = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+#define MSG_USB_DP_PRESENT 0x1
+#define MSG_USB_CLASS_DP_PRESENT 0x2
+#define MSG_USB_WWID_CLASS_DP_PRESENT 0x4
+
+BOOLEAN IsUsbDp(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp,
+ OUT UINT32 *AvailableNodes OPTIONAL
+)
+{
+ UINT32 Flags = 0;
+
+ for( ; !(isEndNode(Dp)); Dp = NEXT_NODE(Dp)) {
+ if(Dp->Type == MESSAGING_DEVICE_PATH) {
+ if(Dp->SubType == MSG_USB_DP) {
+ Flags |= MSG_USB_DP_PRESENT;
+ continue;
+ }
+ if(Dp->SubType == MSG_USB_CLASS_DP) {
+ Flags |= MSG_USB_CLASS_DP_PRESENT;
+ continue;
+ }
+ if(Dp->SubType == MSG_USB_WWID_CLASS_DP) {
+ Flags |= MSG_USB_WWID_CLASS_DP_PRESENT;
+ }
+ }
+ }
+ if(AvailableNodes != NULL)
+ *AvailableNodes = Flags;
+
+ return (Flags != 0) ? TRUE : FALSE;
+}
+
+BOOLEAN UsbClassDevicePathTest(
+ IN EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath,
+ IN BOOT_DEVICE *Device
+)
+{
+ EFI_STATUS Status;
+ USB_CLASS_DEVICE_PATH *UsbDp;
+ EFI_DEVICE_PATH_PROTOCOL *DevDp;
+ UINT32 AvailableNodes;
+
+ if(OptionDevicePath->Type != MESSAGING_DEVICE_PATH ||
+ OptionDevicePath->SubType != MSG_USB_CLASS_DP)
+ return FALSE; //boot option is not USB class boot option
+
+ Status = pBS->HandleProtocol(Device->DeviceHandle, &gEfiDevicePathProtocolGuid, &DevDp);
+ if(EFI_ERROR(Status))
+ return FALSE; //device doesn't support EFI_DEVICE_PATH protocol
+
+ if(!IsUsbDp(DevDp, &AvailableNodes))
+ return FALSE; //device is not a USB device
+
+ UsbDp = (USB_CLASS_DEVICE_PATH *)OptionDevicePath;
+ return (UsbDp->VendorId == 0xffff &&
+ UsbDp->ProductId == 0xffff &&
+ UsbDp->DeviceClass == 0xff &&
+ UsbDp->DeviceSubClass == 0xff &&
+ UsbDp->DeviceProtocol == 0xff) ? TRUE : FALSE;
+
+//TODO
+//add USB class specific comparison, once USB driver produces required device path node
+}
+
+#ifdef CSM_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BbsDevicePathTest
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath -
+// BOOT_DEVICE *Device -
+//
+// Output:
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BbsDevicePathTest(
+ EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath, BOOT_DEVICE *Device
+){
+ BBS_BBS_DEVICE_PATH *BbsDp;
+ if (OptionDevicePath->Type!=BBS_DEVICE_PATH) return FALSE;
+ if (Device->BbsEntry==NULL) return FALSE;
+ BbsDp = (BBS_BBS_DEVICE_PATH*)OptionDevicePath;
+ return BbsDp->DeviceType == GetBbsEntryDeviceType(Device->BbsEntry);
+
+}
+
+UINT8 GetBbsDeviceInstance( UINT16 BbsIndex, BBS_TABLE *BbsEntry){
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 Class;
+ UINT8 SubClass;
+ UINT16 Index;
+
+ if (BbsIndex==0) return 0;
+ Bus = BbsEntry->Bus;
+ Device = BbsEntry->Device;
+ Function = BbsEntry->Function;
+ Class = BbsEntry->Class;
+ SubClass = BbsEntry->SubClass;
+ BbsEntry -= BbsIndex;
+
+ for( Index = BbsIndex-1
+ ; Index != 0xFFFF
+ ; Index--
+ ){
+ if( Bus != BbsEntry[Index].Bus
+ || Device != BbsEntry[Index].Device
+ || Function != BbsEntry[Index].Function
+ || Class != BbsEntry[Index].Class
+ || SubClass != BbsEntry[Index].SubClass
+ ) return BbsIndex - 1 - Index;
+ }
+ return BbsIndex - 1 - Index;
+}
+
+BOOLEAN AmiBbsDevicePathTest(
+ EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath, BOOT_DEVICE *Device
+){
+ AMI_BBS_DEVICE_PATH *AmiBbsDp;
+
+ if (Device->BbsEntry==NULL) return FALSE;
+ AmiBbsDp = (AMI_BBS_DEVICE_PATH*)OptionDevicePath;
+ return AmiBbsDp->Header.Header.Type == HARDWARE_DEVICE_PATH
+ && AmiBbsDp->Header.Header.SubType == HW_VENDOR_DP
+ && guidcmp(&AmiBbsDevicePathGuid, &AmiBbsDp->Header.Guid) == 0
+ && AmiBbsDp->Bus == Device->BbsEntry->Bus
+ && AmiBbsDp->Device == Device->BbsEntry->Device
+ && AmiBbsDp->Function == Device->BbsEntry->Function
+ && AmiBbsDp->Class == Device->BbsEntry->Class
+ && AmiBbsDp->SubClass == Device->BbsEntry->SubClass
+ && AmiBbsDp->Instance == GetBbsDeviceInstance(Device->BbsIndex,Device->BbsEntry);
+ ;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchDevicePathToDevice
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *OptionDp -
+// BOOT_DEVICE *Device -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchDevicePathToDevice(EFI_DEVICE_PATH_PROTOCOL *OptionDp, BOOT_DEVICE *Device){
+ UINT32 i;
+ for(i=0; DpMatchingFunction[i]!=NULL; i++)
+ if (DpMatchingFunction[i](OptionDp,Device)) return TRUE;
+ return FALSE;
+}
+
+BOOLEAN MatchUefiFloppyDrive(BOOT_OPTION *Option, BOOT_DEVICE *Device){
+ // This function makes sure that UEFI boot option is not matched
+ // with the legacy boot device.
+ // A legacy boot device is a device with a valid BbsIndex.
+ // A UEFI boot option is a boot option with FilePathList does not start
+ // with the BBS device path.
+ // When this funciton returns FALSE, the matching process fails.
+ // The function is executed via the BootOptionMatchingFunctions eLink.
+ return Device->BbsIndex==INVALID_BBS_INDEX || IsLegacyBootOption(Option);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure:
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchBootOpionToDevice(BOOT_OPTION *Option, BOOT_DEVICE *Device){
+ UINT32 i;
+ //all the functions have to return TRUE
+ for(i=0; MatchingFunction[i]!=NULL; i++)
+ if (!MatchingFunction[i](Option,Device)) return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchBootOptionsToDevices
+//
+// Description:
+//
+// Input: DLIST *BootOptionList -
+// DLIST *BootDeviceList -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MatchBootOptionsToDevices(){
+ DLINK *OptionLink, *DeviceLink;
+ BOOT_OPTION *Option;
+ BOOT_DEVICE *Device;
+
+ FOR_EACH_BOOT_DEVICE(BootDeviceList,DeviceLink,Device){
+ BOOLEAN DeviceIsMatched = FALSE;
+ FOR_EACH_BOOT_OPTION(BootOptionList,OptionLink,Option){
+ EFI_DEVICE_PATH_PROTOCOL *OptionDp = Option->FilePathList;
+ EFI_DEVICE_PATH_PROTOCOL *DpInstance;
+ //Skip the group headers and the options that have already been matched.
+ if (Option->GroupHeader || IsBootOptionWithDevice(Option)) continue;
+ do {
+ EFI_DEVICE_PATH_PROTOCOL *TmpDp = OptionDp;
+ while( (DpInstance = DPNextInstance(&TmpDp,NULL))!=NULL
+ && MatchDevicePathToDevice(DpInstance,Device)
+ ) pBS->FreePool(DpInstance);
+
+ OptionDp = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)OptionDp+DPLength(OptionDp));
+ } while( Option->FwBootOption && DpInstance==NULL
+ && (UINT8*)OptionDp<(UINT8*)Option->FilePathList+Option->FilePathListLength
+ );
+ if (DpInstance == NULL && MatchBootOpionToDevice(Option,Device)){
+ UpdateBootOptionWithBootDeviceInfo(Option,Device);
+ DeviceIsMatched = TRUE;
+ // Legacy device can't be matched with more than one boot option.
+ if (IsLegacyBootOption(Option)) break;
+ }else{
+ if (DpInstance!=NULL) pBS->FreePool(DpInstance);
+ }
+ }
+ if (DeviceIsMatched) DeleteBootDevice(BootDeviceList, Device);
+ }
+}
+
+VOID DeleteUnmatchedUefiHddBootDevices(){
+ BOOT_DEVICE *Device;
+ DLINK *Link;
+
+ FOR_EACH_BOOT_DEVICE(BootDeviceList, Link, Device){
+ if (IsUefiHddBootDevice(Device)){
+ DeleteBootDevice(BootDeviceList, Device);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPhysicalBlockIoHandle
+//
+// Description:
+//
+// Input: EFI_HANDLE *BlockIoHandle -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_HANDLE GetPhysicalBlockIoHandle(EFI_HANDLE BlockIoHandle){
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath, *Dp;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = BlockIoHandle;
+
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ if (!BlkIo->Media->LogicalPartition) return Handle;
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiDevicePathProtocolGuid, &DevicePath
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ Dp=DevicePath;
+ while(BlkIo->Media->LogicalPartition){
+ EFI_DEVICE_PATH_PROTOCOL *PrevDp=Dp;
+ //We need to cut Devicepath node to get Phisycal Partition
+ Dp=DPCut(PrevDp);
+ if (PrevDp!=DevicePath) pBS->FreePool(PrevDp);
+ if (Dp == NULL) break;
+ PrevDp=Dp;
+ Status=pBS->LocateDevicePath(
+ &gEfiBlockIoProtocolGuid,&PrevDp,&Handle
+ );
+ if(EFI_ERROR(Status)) break;
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if(EFI_ERROR(Status)) break;
+ }
+ if (Dp!=NULL && Dp!=DevicePath) pBS->FreePool(Dp);
+ //if physical Block I/O handle is not found, return original handle
+ return (BlkIo->Media->LogicalPartition) ? BlockIoHandle : Handle;
+}
+
+EFI_HANDLE GetPhysicalNetworkCardHandle(EFI_HANDLE Handle, UINT8 *IpType){
+ EFI_LOAD_FILE_PROTOCOL *LoadFile;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath, *Dp;
+ EFI_STATUS Status;
+
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiLoadFileProtocolGuid, &LoadFile
+ );
+ if (EFI_ERROR(Status)) return Handle;
+
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiDevicePathProtocolGuid, &DevicePath
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ for(Dp=DevicePath; !(isEndNode(Dp)); Dp=NEXT_NODE(Dp)){
+ if (Dp->Type == MESSAGING_DEVICE_PATH && Dp->SubType == MSG_MAC_ADDR_DP){
+ EFI_HANDLE NewHandle;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath, *TmpDp;
+
+ Dp=NEXT_NODE(Dp);
+ if (isEndNode(Dp)) break;
+ if ( IpType != NULL) *IpType = GetDevicePathSubtype(Dp, MESSAGING_DEVICE_PATH);
+ TmpDevicePath = TmpDp = DPCopy(DevicePath);
+ Dp = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)Dp - (UINT8*)DevicePath + (UINT8*)TmpDp);
+ Dp->Type = END_DEVICE_PATH;
+ Dp->SubType = END_ENTIRE_SUBTYPE;
+ SET_NODE_LENGTH(Dp,sizeof(*Dp));
+ Status = pBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, &TmpDp, &NewHandle);
+ if (!EFI_ERROR(Status) && TmpDp==Dp) Handle = NewHandle;
+ pBS->FreePool(TmpDevicePath);
+ break;
+ }
+ }
+ return Handle;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveTrailingSpaces
+//
+// Description:
+//
+// Input: CHAR16 *Name -
+// UINTN NumberOfCharacters -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN RemoveTrailingSpaces(CHAR16 *Name, UINTN NumberOfCharacters){
+ //remove trailing spaces
+ while(NumberOfCharacters>0 && Name[NumberOfCharacters-1]==L' ')
+ NumberOfCharacters--;
+ Name[NumberOfCharacters]=0;
+ return NumberOfCharacters;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNameByHandle
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionNameByHandle(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ EFI_HANDLE Handle;
+ CHAR16 *ControllerName;
+ CHAR16 *Prefix = L"";
+ UINTN NumberOfCharacters;
+ UINT8 IpType;
+
+ if (Option->DeviceHandle == INVALID_HANDLE) return 0;
+
+ //Name from Controller Handle
+ Handle = GetPhysicalBlockIoHandle(Option->DeviceHandle);
+ if (Handle==Option->DeviceHandle){
+ EFI_HANDLE OldHandle = Handle;
+ Handle = GetPhysicalNetworkCardHandle(Option->DeviceHandle,&IpType);
+ if (Handle != OldHandle) {
+ //TODO: use string token
+ if (IpType == MSG_IPv4_DP) Prefix=L"IP4 ";
+ else if (IpType == MSG_IPv6_DP) Prefix=L"IP6 ";
+ }
+ }
+ if (!GetControllerName(Handle, &ControllerName)) return 0;
+ NumberOfCharacters = Swprintf_s(Name, NameSize, L"%s%s",Prefix,ControllerName);
+ return RemoveTrailingSpaces(Name, NumberOfCharacters);
+}
+
+#ifdef CSM_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNameByBbsDescription
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionNameByBbsDescription(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ CHAR8 *AsciiNameStr;
+ UINTN NumberOfCharacters;
+
+ if (Option->BbsEntry == NULL) return 0;
+
+ //Name from BBS table
+ AsciiNameStr = (CHAR8*)(UINTN)(
+ (Option->BbsEntry->DescStringSegment<<4)
+ + Option->BbsEntry->DescStringOffset
+ );
+ if (AsciiNameStr == NULL) return 0;
+ for( NumberOfCharacters = 0
+ ; NumberOfCharacters < NameSize-1
+ ; NumberOfCharacters++
+ ){
+ if (!AsciiNameStr[NumberOfCharacters]) break;
+ Name[NumberOfCharacters] = AsciiNameStr[NumberOfCharacters];
+ }
+ Name[NumberOfCharacters]=0;
+ return RemoveTrailingSpaces(Name, NumberOfCharacters);
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DevicePathToNameString
+//
+// Description:
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *DevicePath -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN DevicePathToNameString(
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath, CHAR16 *Name, UINTN NameSize
+){
+ STRING_REF StrToken;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINTN BufferSize;
+ UINTN NumberOfCharacters = 0;
+
+ for( Dp = DevicePath; !(isEndNode(Dp)); Dp=NEXT_NODE(Dp)){
+ StrToken = DevicePathNodeToStrRef(Dp);
+ BufferSize = (NameSize-NumberOfCharacters)*sizeof(CHAR16);
+ if ( StrToken!= INVALID_STR_TOKEN
+ && !EFI_ERROR(HiiLibGetString(
+ HiiHandle,StrToken,&BufferSize, &Name[NumberOfCharacters]
+ ))
+ && BufferSize != 0
+ ){
+ NumberOfCharacters += (BufferSize-1)/sizeof(CHAR16);
+ if (NumberOfCharacters < NameSize - 1){
+ Name[NumberOfCharacters++]=L' ';
+ }
+ }
+ }//for ;
+ if (NumberOfCharacters !=0 ) Name[NumberOfCharacters]=0;
+ return NumberOfCharacters;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNameByHandleDevicePath
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionNameByHandleDevicePath(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (Option->DeviceHandle == INVALID_HANDLE) return 0;
+ //Name from Device Path
+
+ if (!EFI_ERROR(pBS->HandleProtocol(
+ Option->DeviceHandle, &gEfiDevicePathProtocolGuid, &DevicePath
+ ))) return DevicePathToNameString(DevicePath, Name, NameSize);
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNameByFilePathList
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionNameByFilePathList(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ if (Option->FilePathList == NULL) return 0;
+ return DevicePathToNameString(Option->FilePathList, Name, NameSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionBaseName
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionBaseName(BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize){
+ UINTN NumberOfCharacters;
+ UINT32 i;
+
+ for(i=0; BuildNameFunctions[i]!=NULL; i++){
+ NumberOfCharacters = BuildNameFunctions[i](Option, Name, NameSize);
+ if ( NumberOfCharacters!=0 ) return NumberOfCharacters;
+ }
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionName
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructBootOptionName(BOOT_OPTION *Option){
+ CHAR16 Name[1024];
+ UINTN Length = sizeof(Name)/sizeof(CHAR16);
+ UINTN NumberOfCharacters, BaseNameLength;
+
+ NumberOfCharacters = ConstructBootOptionNamePrefix(Option,Name,Length);
+ Length -= NumberOfCharacters;
+ BaseNameLength = ConstructBootOptionBaseName(
+ Option, &Name[NumberOfCharacters], Length
+ );
+ NumberOfCharacters += BaseNameLength;
+ if (BaseNameLength==0){
+ //Unknown Device
+ UINTN BufferSize = Length*sizeof(CHAR16);
+ if (EFI_ERROR(
+ HiiLibGetString(
+ HiiHandle, UnknownDeviceToken, &BufferSize, &Name[NumberOfCharacters]
+ )
+ )){
+ NumberOfCharacters += Swprintf_s(
+ &Name[NumberOfCharacters], Length, L"Unknown Device"
+ );
+ }else{
+ NumberOfCharacters += (BufferSize-1)/sizeof(CHAR16);
+ }
+ Length -= NumberOfCharacters;
+ }
+ NumberOfCharacters += ConstructBootOptionNameSuffix(
+ Option, &Name[NumberOfCharacters], Length
+ );
+ //convert number of characters into string buffer size
+ Length = (NumberOfCharacters+1)*sizeof(CHAR16);
+ Option->Description = Malloc(Length);
+ MemCpy(Option->Description,Name,Length);
+ return NumberOfCharacters;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructBootOptionNameBySerialNumber
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructAtaBootOptionNameBySerialNumber(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ static EFI_GUID DiskInfoGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_HANDLE Handle;
+ UINTN NumberOfCharacters;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ EFI_STATUS Status;
+ UINT16 IdentifyData[256];
+ UINT32 Size;
+ CHAR8 SerialNumber[21];
+
+ if (Option->DeviceHandle == INVALID_HANDLE) return 0;
+
+ Handle = GetPhysicalBlockIoHandle(Option->DeviceHandle);
+ Status = pBS->HandleProtocol(
+ Handle, &DiskInfoGuid, &DiskInfo
+ );
+ if (EFI_ERROR(Status)) return 0;
+ Size = sizeof(IdentifyData);
+ Status = DiskInfo->Identify ( DiskInfo, IdentifyData, &Size );
+ if (EFI_ERROR(Status)) return 0;
+ MemCpy(SerialNumber, IdentifyData+10, 20);
+ SerialNumber[20] = 0;
+ NumberOfCharacters = Swprintf_s(Name, NameSize, L"%S", SerialNumber);
+ return NumberOfCharacters;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructUsbBootOptionNameBySerialNumber
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// CHAR16 *Name -
+// UINTN NameSize -
+//
+// Output:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructUsbBootOptionNameBySerialNumber(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+
+ EFI_HANDLE Handle;
+ UINTN NumberOfCharacters;
+ EFI_STATUS Status;
+
+ EFI_USB_IO_PROTOCOL *UsbIo = NULL;
+ EFI_USB_DEVICE_DESCRIPTOR DevDesc = {0};
+ CHAR16 *UsbSerialNumber=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath=NULL;
+
+ if (Option->DeviceHandle == INVALID_HANDLE) return 0;
+
+ Handle = GetPhysicalBlockIoHandle(Option->DeviceHandle);
+
+ Status = pBS->HandleProtocol(Handle, &gEfiUsbIoProtocolGuid, &UsbIo);
+ if(EFI_ERROR(Status)) return 0;
+ Status = UsbIo->UsbGetDeviceDescriptor(UsbIo, &DevDesc);
+ if(EFI_ERROR(Status)) return 0;
+
+ if (DevDesc.StrSerialNumber) {
+ Status = UsbIo->UsbGetStringDescriptor(UsbIo, 0x0409, DevDesc.StrSerialNumber, &UsbSerialNumber);
+ if(EFI_ERROR(Status)) return 0;
+ pBS->CopyMem( Name, UsbSerialNumber, (Wcslen(UsbSerialNumber)+1)*2 );
+ NumberOfCharacters = Wcslen(UsbSerialNumber);
+ return NumberOfCharacters;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructInternalBootOptionName
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructInternalBootOptionName(
+ BOOT_OPTION *Option, CHAR16 *Name, UINTN NameSize
+){
+ static CONSTRUCT_BOOT_OPTION_NAME *IntBuildNameFunctions[] = {
+ ConstructAtaBootOptionNameBySerialNumber,
+ ConstructUsbBootOptionNameBySerialNumber,
+ ConstructBootOptionNameByHandle,
+#ifdef CSM_SUPPORT
+ ConstructBootOptionNameByBbsDescription,
+#endif
+ NULL
+ };
+ UINTN NumberOfCharacters;
+ UINT32 i;
+
+ for(i=0; IntBuildNameFunctions[i]!=NULL; i++){
+ NumberOfCharacters = IntBuildNameFunctions[i](Option, Name, NameSize);
+ if ( NumberOfCharacters!=0 ) return NumberOfCharacters;
+ }
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructInternalDeviceName
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN ConstructInternalDeviceName(
+ BOOT_DEVICE *Device, CHAR16 *Name, UINTN NameSize
+){
+ static BOOT_OPTION BootOption = {
+ {NULL,NULL}, LOAD_OPTION_ACTIVE, NULL, NULL, 0, NULL, 0,
+ INVALID_BOOT_OPTION_NUMBER, LOWEST_BOOT_OPTION_PRIORITY,
+ UNASSIGNED_HIGHEST_TAG,
+ INVALID_HANDLE, INVALID_BBS_INDEX, NULL, TRUE, FALSE
+ };
+ UpdateBootOptionWithBootDeviceInfo(&BootOption,Device);
+ return ConstructInternalBootOptionName(&BootOption, Name, NameSize);
+}
+
+BOOLEAN AmiDeviceNameDevicePathTest(
+ EFI_DEVICE_PATH_PROTOCOL *OptionDevicePath, BOOT_DEVICE *Device
+){
+ AMI_DEVICE_NAME_DEVICE_PATH *NameDp;
+ CHAR16 Name[1024];
+ UINTN Size = sizeof(Name)/sizeof(CHAR16);
+ UINTN NumberOfCharacters;
+
+ NameDp = (AMI_DEVICE_NAME_DEVICE_PATH*)OptionDevicePath;
+ if( NameDp->Header.Header.Type != HARDWARE_DEVICE_PATH
+ || NameDp->Header.Header.SubType != HW_VENDOR_DP
+ || guidcmp(
+ &AmiDeviceNameDevicePathGuid,
+ &NameDp->Header.Guid
+ ) != 0
+ ) return FALSE;
+
+ NumberOfCharacters = ConstructInternalDeviceName(
+ Device, Name, Size
+ );
+ if (NumberOfCharacters==0) return FALSE;
+ //convert number of charcters into string buffer size
+ Size = (NumberOfCharacters+1)*sizeof(CHAR16);
+ return
+ Size == NODE_LENGTH(&NameDp->Header.Header)-sizeof(*NameDp)
+ && !MemCmp(Name,NameDp+1,Size);
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: AddDevicePathToFilePathList
+//
+// Description:
+// Adds another device path to an array of boot option device paths
+//
+// Input:
+// IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePathListPtr
+// On input, pointer to the current boot option FilePathList
+// On output, pointer to the new FilePathList. Memory used by original FilePathList is deallocated.
+//
+// IN OUT UINTN *FilePathListLength,
+// On input, pointer to the length of the current FilePathList
+// On output, pointer to the length of the new FilePathList
+//
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+// Device path to add to the FilePathList
+//
+// Output:
+// VOID
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID AddDevicePathToFilePathList(
+ EFI_DEVICE_PATH_PROTOCOL **FilePathListPtr, UINTN *FilePathListLength,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ UINTN DevicePathLength;
+ EFI_DEVICE_PATH_PROTOCOL *NewFilePathList;
+
+ if ( FilePathListPtr == NULL
+ || FilePathListLength == NULL
+ || DevicePath == NULL
+ ) return;
+
+ DevicePathLength = DPLength(DevicePath);
+ if (*FilePathListPtr == NULL) *FilePathListLength = 0;
+
+ NewFilePathList = Malloc(*FilePathListLength + DevicePathLength);
+ if ( *FilePathListPtr != NULL ){
+ MemCpy(NewFilePathList, *FilePathListPtr, *FilePathListLength);
+ pBS->FreePool(*FilePathListPtr);
+ }
+ MemCpy(
+ (UINT8*)NewFilePathList+*FilePathListLength,
+ DevicePath, DevicePathLength
+ );
+ *FilePathListLength += DevicePathLength;
+ *FilePathListPtr = NewFilePathList;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildEfiFilePath
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BuildEfiFilePath(BOOT_OPTION *Option){
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ EFI_STATUS Status;
+
+ if ( Option->FilePathList!=NULL
+ || Option->BbsEntry != NULL
+ || Option->DeviceHandle == INVALID_HANDLE
+ ) return FALSE;
+ Status = pBS->HandleProtocol(Option->DeviceHandle, &gEfiDevicePathProtocolGuid, &Dp);
+ if (EFI_ERROR(Status)) return FALSE;
+ Option->FilePathList = DPCopy(Dp);
+ Option->FilePathListLength = DPLength(Dp);
+ return TRUE;
+}
+
+#ifdef CSM_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLegacyFilePath
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BuildLegacyFilePath(BOOT_OPTION *Option){
+ static struct {
+ BBS_BBS_DEVICE_PATH bbs;
+ EFI_DEVICE_PATH_PROTOCOL end;
+ } BbsDpTemplate = {
+ {
+ {BBS_DEVICE_PATH,BBS_BBS_DP,sizeof(BBS_BBS_DEVICE_PATH)},
+ BBS_HARDDISK,0,0
+ },
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,sizeof(EFI_DEVICE_PATH_PROTOCOL)}
+ };
+
+ if (Option->FilePathList!=NULL || Option->BbsEntry == NULL) return FALSE;
+ BbsDpTemplate.bbs.DeviceType=GetBbsEntryDeviceType(Option->BbsEntry);
+ Option->FilePathList = DPCopy(&BbsDpTemplate.bbs.Header);
+ Option->FilePathListLength = DPLength(Option->FilePathList);
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLegacyLocationFilePath
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+// Note: function only available, and used, if CSM_SUPPORT token is defined and enabled
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BuildLegacyLocationFilePath(BOOT_OPTION *Option){
+ static struct {
+ AMI_BBS_DEVICE_PATH amibbs;
+ EFI_DEVICE_PATH_PROTOCOL end;
+ } AmiBbsDpTemplate = {
+ {
+ {
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof(AMI_BBS_DEVICE_PATH) },
+ AMI_BBS_DEVICE_PATH_GUID
+ },
+ 0, 0, 0, 0, 0, 0
+ },
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,sizeof(EFI_DEVICE_PATH_PROTOCOL)}
+ };
+
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+
+ if (Option->BbsEntry == NULL) return FALSE;
+ if ( Option->DeviceHandle == INVALID_HANDLE
+ || EFI_ERROR(pBS->HandleProtocol(Option->DeviceHandle, &gEfiDevicePathProtocolGuid, &Dp))
+ ){
+ Dp = &AmiBbsDpTemplate.amibbs.Header.Header;
+ AmiBbsDpTemplate.amibbs.Bus = (UINT8)Option->BbsEntry->Bus;
+ AmiBbsDpTemplate.amibbs.Device = (UINT8)Option->BbsEntry->Device;
+ AmiBbsDpTemplate.amibbs.Function = (UINT8)Option->BbsEntry->Function;
+ AmiBbsDpTemplate.amibbs.Class = (UINT8)Option->BbsEntry->Class;
+ AmiBbsDpTemplate.amibbs.SubClass = (UINT8)Option->BbsEntry->SubClass;
+ AmiBbsDpTemplate.amibbs.Instance = GetBbsDeviceInstance(Option->BbsIndex,Option->BbsEntry);
+ }
+ AddDevicePathToFilePathList(
+ &Option->FilePathList, &Option->FilePathListLength, Dp
+ );
+ return TRUE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildNameFilePath
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BuildNameFilePath(BOOT_OPTION *Option){
+ static AMI_DEVICE_NAME_DEVICE_PATH AmiNameDpTemplate = {
+ {
+ { HARDWARE_DEVICE_PATH, HW_VENDOR_DP, sizeof(AMI_DEVICE_NAME_DEVICE_PATH) },
+ AMI_DEVICE_NAME_DEVICE_PATH_GUID
+ }
+ };
+ static EFI_DEVICE_PATH_PROTOCOL EndOfDevicePathNode = {
+ END_DEVICE_PATH, END_ENTIRE_SUBTYPE,
+ {sizeof(EFI_DEVICE_PATH_PROTOCOL),0}
+ };
+
+ CHAR16 Name[1024];
+ UINTN Size = sizeof(Name)/sizeof(CHAR16);
+ UINTN NumberOfCharacters;
+ AMI_DEVICE_NAME_DEVICE_PATH *NameDp;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+
+ NumberOfCharacters = ConstructInternalBootOptionName(
+ Option, Name, Size
+ );
+ if (NumberOfCharacters==0) return FALSE;
+ //convert number of charcters into string buffer size
+ Size = (NumberOfCharacters+1)*sizeof(CHAR16);
+
+ Dp = Malloc(sizeof(AmiNameDpTemplate)+Size+sizeof(EndOfDevicePathNode));
+ ASSERT(Dp!=NULL)
+ if (Dp==NULL) return FALSE;
+ NameDp = (AMI_DEVICE_NAME_DEVICE_PATH*)Dp;
+
+ *NameDp = AmiNameDpTemplate;
+ SET_NODE_LENGTH(Dp,(UINT16)(sizeof(AmiNameDpTemplate)+Size));
+ MemCpy(NameDp+1, Name, Size);
+ MemCpy(NEXT_NODE(Dp), &EndOfDevicePathNode, sizeof(EndOfDevicePathNode));
+ AddDevicePathToFilePathList(
+ &Option->FilePathList, &Option->FilePathListLength, Dp
+ );
+ pBS->FreePool(Dp);
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildBootOptionFilePath
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BuildBootOptionFilePath(BOOT_OPTION *Option){
+ UINT32 i;
+ BOOLEAN FilePathCreated = FALSE;
+
+ for(i=0; BuildFilePathFunctions[i]!=NULL; i++){
+ FilePathCreated |= BuildFilePathFunctions[i](Option);
+ }
+ return FilePathCreated;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateBootOptionsForNewBootDevices
+//
+// Description:
+//
+// Input: DLIST *BootOptionList -
+// DLIST *BootDeviceList -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateBootOptionsForNewBootDevices(){
+ DLINK *Link;
+ BOOT_DEVICE *Device;
+
+ FOR_EACH_BOOT_DEVICE(BootDeviceList,Link,Device){
+ BOOT_OPTION *Option = CreateBootOption(BootOptionList);
+ UpdateBootOptionWithBootDeviceInfo(Option,Device);
+ DeleteBootDevice(BootDeviceList, Device);
+ Option->FwBootOption = TRUE;
+ ConstructBootOptionName(Option);
+ if (!BuildBootOptionFilePath(Option)){
+ Option->FilePathList=NULL;
+ Option->FilePathListLength=0;
+ }
+ }
+ DUMP_BOOT_OPTION_LIST(BootOptionList,"Before Processing");
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NormalizeBootOptions
+//
+// Description: If normalization is enabled, regenerates all the description strings
+// and/or file path lists
+//
+// Input: none
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NormalizeBootOptions(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ // Normalize boot options
+ //(regenerate the description string and the file path list)
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ if ( !Option->FwBootOption || !IsBootOptionWithDevice(Option)
+ || Option->BootOptionNumber == INVALID_BOOT_OPTION_NUMBER
+ ) continue;
+ if (NormalizeBootOptionDevicePath){
+ EFI_DEVICE_PATH_PROTOCOL *OldFilePathList = Option->FilePathList;
+ UINTN OldFilePathListLength = Option->FilePathListLength;
+ Option->FilePathList = NULL;
+ Option->FilePathListLength = 0;
+ BuildBootOptionFilePath(Option);
+ if (Option->FilePathList == NULL){
+ Option->FilePathList = OldFilePathList;
+ Option->FilePathListLength = OldFilePathListLength;
+ }else if (OldFilePathList != NULL){
+ pBS->FreePool(OldFilePathList);
+ }
+ }
+ if (NormalizeBootOptionName){
+ CHAR16 *OldDescription = Option->Description;
+ Option->Description = NULL;
+ ConstructBootOptionName(Option);
+ if (Option->Description == NULL)
+ Option->Description = OldDescription;
+ else if (OldDescription != NULL)
+ pBS->FreePool(OldDescription);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DumpBootOptionList
+//
+// Description:
+//
+// Input: DLIST *BootOptionList -
+// CHAR8 *ListCaption -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DumpBootOptionList(DLIST *BootOptionList, CHAR8 *ListCaption){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ if (ListCaption!=NULL)
+ TRACE((TRACE_DXE_CORE,"%s:\n",ListCaption));
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ CHAR8 *Details1, *Details2, *Details3;
+ if (Option->GroupHeader) Details1="(group header)";
+ else if (!IsBootOptionWithDevice(Option)) Details1 ="(orphan)";
+ else Details1="";
+ if ((Option->Attributes&LOAD_OPTION_ACTIVE)!=LOAD_OPTION_ACTIVE) Details2="(disabled)";
+ else Details2="";
+ if ((Option->Attributes&LOAD_OPTION_HIDDEN)==LOAD_OPTION_HIDDEN) Details3="(hidden)";
+ else Details3="";
+ TRACE((TRACE_DXE_CORE,
+ "%X(%X/%X).%S%s%s%s\n",
+ Option->BootOptionNumber,Option->Priority,Option->Tag,Option->Description,
+ Details1,Details2,Details3
+ ));
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBootOptionPackedSize
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN GetBootOptionPackedSize(BOOT_OPTION *Option){
+ return
+ sizeof(EFI_LOAD_OPTION)
+ + (Wcslen(Option->Description)+1)*sizeof(CHAR16)
+ + Option->FilePathListLength
+ + Option->OptionalDataSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PackBootOption
+//
+// Description:
+//
+// Input: BOOT_OPTION *Option -
+// EFI_LOAD_OPTION *NvramOption -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* PackBootOption(BOOT_OPTION *Option, EFI_LOAD_OPTION *NvramOption){
+ UINTN DescriptionSize;
+ UINT8 *Ptr;
+
+ DescriptionSize = (Wcslen(Option->Description)+1)*sizeof(CHAR16);
+ NvramOption->Attributes = Option->Attributes;
+ NvramOption->FilePathListLength = (UINT16)Option->FilePathListLength;
+ MemCpy(NvramOption+1,Option->Description,DescriptionSize);
+ Ptr = (UINT8*)(NvramOption+1)+DescriptionSize;
+ MemCpy(Ptr, Option->FilePathList, Option->FilePathListLength);
+ Ptr += Option->FilePathListLength;
+ return Ptr;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveBootOptions
+//
+// Description:
+//
+// Input: DLIST *BootOptionList -
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SaveBootOptions(){
+ UINTN BootOrderSize;
+ UINT16 *BootOrder;
+ DLINK *Link;
+ UINTN BootOrderIndex = 0;
+ BOOT_OPTION *Option;
+
+ //PRECONDITION: All Boot Option Numbers are set
+ SortList(BootOptionList, ComparePriorityThenBootOptionNumber);
+ DUMP_BOOT_OPTION_LIST(BootOptionList, "Before Saving");
+ BootOrderSize = BootOptionList->Size*sizeof(UINT16);
+ if (BootOrderSize==0) return;
+ BootOrder = Malloc(BootOrderSize);
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ EFI_LOAD_OPTION *NvramOption;
+ BOOT_OPTION *NestedOption;
+ DLINK *TmpLink;
+ UINTN NvramOptionSize;
+ UINT8 *Ptr;
+ CHAR16 BootStr[9];
+ EFI_STATUS Status;
+ BOOLEAN HasNestedOptions = FALSE;
+
+ //Meke sure the boot option is well-formed
+ if( Option->FilePathListLength == 0
+ || Option->FilePathList == NULL
+ || Option->BootOptionNumber == INVALID_BOOT_OPTION_NUMBER
+ ){
+ TRACE((TRACE_DXE_CORE,
+ "SaveBootOptions: skipping invalid boot option '%X.%S'\n",
+ Option->BootOptionNumber,Option->Description
+ ));
+ continue;
+ }
+
+ NvramOptionSize = GetBootOptionPackedSize(Option);
+ if (Option->FwBootOption){
+ NvramOptionSize += sizeof(UINT32); //signature
+ //TRACE((-1,"(%X) before size loop: size=%X\n",Option->BootOptionNumber,NvramOptionSize));
+ FOR_EACH_LIST_ELEMENT(Option->Link.pNext, TmpLink, NestedOption, BOOT_OPTION){
+ if (Option->BootOptionNumber != NestedOption->BootOptionNumber)
+ break;
+ NvramOptionSize += AMI_NESTED_BOOT_OPTION_HEADER_SIZE +
+ + GetBootOptionPackedSize(NestedOption)
+ + sizeof(UINT32); //signature;
+ //TRACE((-1,"Nested(%X) size loop: size=%X\n",Option->BootOptionNumber,NvramOptionSize));
+ HasNestedOptions = TRUE;
+ }
+ }
+ NvramOption = Malloc(NvramOptionSize);
+ Ptr = PackBootOption(Option,NvramOption);
+ if (Option->FwBootOption){
+ if (HasNestedOptions)
+ *(UINT32*)Ptr = AMI_GROUP_BOOT_OPTION_SIGNATURE;
+ else
+ *(UINT32*)Ptr = AMI_SIMPLE_BOOT_OPTION_SIGNATURE;
+ Ptr += sizeof(UINT32);
+ //TRACE((-1,"(%X) before save loop: size=%X\n",Option->BootOptionNumber,Ptr-(UINT8*)NvramOption));
+ if (HasNestedOptions){
+ FOR_EACH_LIST_ELEMENT(Option->Link.pNext, TmpLink, NestedOption, BOOT_OPTION){
+ NESTED_BOOT_OPTION *NestedPackedOption;
+
+ if (Option->BootOptionNumber != NestedOption->BootOptionNumber)
+ break;
+ NestedPackedOption = (NESTED_BOOT_OPTION*)Ptr;
+ NestedPackedOption->Signature = AMI_NESTED_BOOT_OPTION_SIGNATURE;
+ Ptr = PackBootOption(NestedOption,&NestedPackedOption->Option);
+ *(UINT32*)Ptr = AMI_SIMPLE_BOOT_OPTION_SIGNATURE;
+ Ptr += sizeof(UINT32);
+ if (NestedOption->OptionalDataSize!=0){
+ MemCpy(
+ Ptr, NestedOption->OptionalData, NestedOption->OptionalDataSize
+ );
+ Ptr += NestedOption->OptionalDataSize;
+ }
+ NestedPackedOption->Size = (UINT32)(Ptr - (UINT8*)NestedPackedOption);
+ //delete nested option
+ DeleteBootOption(BootOptionList,NestedOption);
+ //TRACE((-1,"Nested(%X) save loop: size=%X\n",Option->BootOptionNumber,Ptr-(UINT8*)NvramOption));
+ }
+ }
+ }
+ if (Option->OptionalDataSize!=0){
+ MemCpy(
+ Ptr, Option->OptionalData, Option->OptionalDataSize
+ );
+ }
+ //TRACE((-1,"Saving %d: %X; %X; ods=%d\n",Option->BootOptionNumber,Ptr+Option->OptionalDataSize,(UINT8*)NvramOption+NvramOptionSize,Option->OptionalDataSize));
+ ASSERT(Ptr+Option->OptionalDataSize == (UINT8*)NvramOption+NvramOptionSize)
+ Swprintf(BootStr,L"Boot%04X",Option->BootOptionNumber);
+ Status = pRS->SetVariable(
+ BootStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, NvramOptionSize, NvramOption
+ );
+ BootOrder[BootOrderIndex]=Option->BootOptionNumber;
+ Link = Option->Link.pNext;
+ DeleteBootOption(BootOptionList,Option);
+ pBS->FreePool(NvramOption);
+ if (EFI_ERROR(Status)) continue;
+ BootOrderIndex++;
+ }
+ pRS->SetVariable(
+ L"BootOrder", &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, BootOrderIndex*sizeof(UINT16), BootOrder
+ );
+ pBS->FreePool(BootOrder);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateBootOptionVariables
+//
+// Description: This function initializes the global variables.
+// Must be called before any other boot option processing function can be used.
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateBootOptionVariables(){
+ LoadStrings(TheImageHandle, &HiiHandle);
+ DListInit(BootOptionList);
+ DListInit(BootDeviceList);
+}
+
+BOOLEAN IsGroupOrphan(BOOT_OPTION *Option)
+{
+ BOOT_OPTION *Current;
+
+ Current = (BOOT_OPTION *)BootOptionList->pHead;
+ while(Current != NULL) {
+ if(Current == Option)
+ break;
+ Current = (BOOT_OPTION *)Current->Link.pNext;
+ }
+
+ if(Current == NULL) //shouldn't be here - input parameter is not found in boot options
+ return TRUE;
+
+ Current = (BOOT_OPTION *)Current->Link.pNext; //get next boot option
+ if(Current == NULL || Current->Tag != Option->Tag) //group option is alone (next either NULL or different tag)
+ return TRUE;
+
+ while(Current != NULL && Current->Tag == Option->Tag) {
+ if(IsBootOptionWithDevice(Current)) //one of physical boot options in group has device
+ return FALSE;
+ Current = (BOOT_OPTION *)Current->Link.pNext;
+ }
+ return TRUE;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/CORE_DXE.cif b/Core/CORE_DXE/CORE_DXE.cif
new file mode 100644
index 0000000..d67cf9e
--- /dev/null
+++ b/Core/CORE_DXE/CORE_DXE.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "CORE_DXE"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\"
+ RefName = "CORE_DXE"
+[files]
+"CORE_DXE.sdl"
+"CORE_DXE.mak"
+"Bds.uni"
+"BdsBoard.c"
+[parts]
+"ArchProtocol"
+<endComponent>
diff --git a/Core/CORE_DXE/CORE_DXE.mak b/Core/CORE_DXE/CORE_DXE.mak
new file mode 100644
index 0000000..a765462
--- /dev/null
+++ b/Core/CORE_DXE/CORE_DXE.mak
@@ -0,0 +1,189 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/CORE_DXE/CORE_DXE.mak 14 9/29/10 9:19a Felixp $
+#
+# $Revision: 14 $
+#
+# $Date: 9/29/10 9:19a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/CORE_DXE/CORE_DXE.mak $
+#
+# 14 9/29/10 9:19a Felixp
+# Enhancement(EIP 39464) : Implementation of the BdsEntry function is
+# changed.
+# The BdsEntry is now a dispatching function that calls a collection of
+# functions
+# formed by the BDS_CONTROL_FLOW eLink.
+#
+# 13 8/26/10 12:52p Felixp
+# Spelling error in one of the identifiers in BootOptioneLinks.h
+#
+# 12 6/29/10 11:03p Felixp
+# New Boot Options Maintenance Infrastructure.
+# See AMI_Aptio_4.x_Boot_Options_Maintenance_Infrastructure_Porting_Guide
+# _NDA.doc for details.
+#
+# 11 2/23/10 9:19p Felixp
+# Support of the BDS String Override via BDS_SDBS eLink (EIP 32696).
+#
+# 10 11/19/09 12:55p Felixp
+# Entry point name has changed (from DxeCoreEntry to DxeMain).
+#
+# 9 6/08/06 7:13p Sivagarn
+# - Updated file header
+# - Fixed EIP 7580 issue. Search for (EIP7580) for changes
+#
+# 8 3/13/06 1:44a Felixp
+# BdsInitialize eLink created
+#
+# 7 12/02/05 11:16a Felixp
+# @set INCLUDE=%%INCLUDE%% removed since it's not needed.
+#
+# 6 6/20/05 12:01p Felixp
+#
+# 5 5/24/05 2:48p Felixp
+# support for SUPPORTED_LANGUAGES
+#
+# 4 4/12/05 2:59p Felixp
+#
+# 3 4/08/05 7:39a Felixp
+# Boot Menu implemented
+#
+# 2 2/11/05 5:46p Felixp
+# Binary files organization improved:
+# - extra layer of sub-component removed
+# - macros initialization moved to SDL tokens to eliminate undefined
+# macros situation
+# - debug and release binaries have different names now (workaround for
+# VeB limitation)
+#
+# 1 1/28/05 12:44p Felixp
+#
+# 4 1/25/05 3:27p Felixp
+# compression enabled;
+# dependency from token.h added
+#
+# 3 1/21/05 12:01p Felixp
+# BootScriptSave moved to CORE_DXE
+#
+# 2 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 5 11/10/04 5:18p Felixp
+# reference to EfiDriverLib.lib removed
+#
+# 25 4/07/04 12:46a Felixp
+# REAL PLATFORM DEBUGGING (lots of bug fixes)
+#
+# 20 3/28/04 2:11p Felixp
+# 1. PE Loader and some other commonly used code moved to the Library
+# 2. Warnings fixed (from now on warning will be treated as error)
+#
+# 19 3/27/04 9:23a Felixp
+#
+# 18 3/25/04 3:47p Robert
+# added Misc.obj to and removed reset.obj from the MAK file
+#
+# 8 2/06/04 2:46a Felixp
+# - Support for VC6 tools
+# - bug fixes
+# - component AddOn added
+#
+# 7 2/04/04 6:50p Yakovlevs
+#
+# 6 1/20/04 11:32a Felixp
+# Memory Services added (at the moment they are non-buildable)
+#
+# 5 1/18/04 8:33a Felixp
+# From now on, OBJ files are created in a component specific subdirectory
+# of $(BUILD_DIR)
+#
+# 2 1/05/04 6:09p Robert
+#
+# 1 12/05/03 4:15p Felixp
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+# Name: CORE_DXE.MAK
+#
+# Description: This NMAKE script file builds the CORE_DXE driver
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+all : CORE_DXE
+
+CORE_DXE : $(BUILD_DIR)\CORE_DXE.mak $(BUILD_DIR)\BootOptioneLinks.h CORE_DXEBin
+
+$(BUILD_DIR)\CORE_DXE.mak : $(CORE_DXE_DIR)\$(@B).cif $(CORE_DXE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CORE_DXE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CORE_DXEBin : $(AMIDXELIB) $(CORE_DXE_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CORE_DXE.mak all\
+ GUID=5AE3F37E-4EAE-41ae-8240-35465B5E81EB \
+ ENTRY_POINT=DxeMain \
+ TYPE=DXE_CORE LIBRARIES= \
+ "CFLAGS=$(CFLAGS) /D\"SUPPORTED_LANGUAGES=$(SUPPORTED_LANGUAGES: =)\" /D\"SIO_DEVICE_LIST=$(DxeSioList)\" /D\"SIO_DEVICE_PTR_LIST=_AND_ $(DxeSioList: =_AND_ )\" "\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h $(BUILD_DIR)\BootOptioneLinks.h"\
+ HAS_RESOURCES=1 COMPRESS=1\
+ "INIT_LIST=$(DxeCoreInitialize)"\
+ "INIT_LIST2=$(BdsEntryInitialize)"\
+!IF "$(BDS_SDBS: =)"==""
+ "STRGATHER_FLAGS=-db $(BUILD_DIR)\$(CORE_DXE_DIR)\Bds.sdb"\
+!ELSE
+ "STRGATHER_FLAGS=-db $(BUILD_DIR)\$(CORE_DXE_DIR)\Bds.sdb -db $(BDS_SDBS: = -db )"\
+!ENDIF
+
+# We are trying to convert a list of comma separated functions to a list of comma
+# separated function name strings.
+# The original list of function may contain C comment blocks /* */
+BDS_CONTROL_FLOW0 = $(BDS_CONTROL_FLOW: =) # remove the spaces
+BDS_CONTROL_FLOW1 = $(BDS_CONTROL_FLOW0:*/,=*/) # remove commas after the comments
+BDS_CONTROL_FLOW2 = $(BDS_CONTROL_FLOW1:*//*=) # merge the adjacent comments
+BDS_CONTROL_FLOW3 = $(BDS_CONTROL_FLOW2:*/=*/") # add quote after the comment to begin the next string
+BDS_CONTROL_FLOW4 = "$(BDS_CONTROL_FLOW3:,=",")", # add quotes before and after the commas
+BDS_CONTROL_FLOW_STRINGS = $(BDS_CONTROL_FLOW4:"/*=/*) # remove quote before the comments
+
+$(BUILD_DIR)\BootOptioneLinks.h : $(BUILD_DIR)\Token.h $(CORE_DXE_DIR)\CORE_DXE.mak
+ $(SILENT)type << >$(BUILD_DIR)\BootOptioneLinks.h
+#define BOOT_OPTION_DP_MATCHING_FUNCTIONS $(BootOptionDpMatchingFunctions)
+#define BOOT_OPTION_MATCHING_FUNCTIONS $(BootOptionMatchingFunctions)
+#define BOOT_OPTION_BUILD_NAME_FUNCTIONS $(BootOptionBuildNameFunctions)
+#define BOOT_OPTION_BUILD_FILE_PATH_FUNCTIONS $(BootOptionBuildFilePathFunctions)
+#define BOOT_OPTION_BOOT_DEVICE_FILTERING_FUNCTIONS $(BootOptionBootDeviceFilteringFunctions)
+
+#define BDS_CONTROL_FLOW $(BDS_CONTROL_FLOW)
+#define BDS_CONTROL_FLOW_NAMES $(BDS_CONTROL_FLOW_STRINGS)
+<<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/CORE_DXE.sdl b/Core/CORE_DXE/CORE_DXE.sdl
new file mode 100644
index 0000000..37a52e0
--- /dev/null
+++ b/Core/CORE_DXE/CORE_DXE.sdl
@@ -0,0 +1,1169 @@
+TOKEN
+ Name = "CORE_DXE_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CORE_DXE support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "ConSplitter_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable ConSplitter support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "Partition_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Partition support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "PS2Ctl_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PS2 Controller support in the project."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "KBC_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "GC_COLOR_BLACK"
+ Value = "0,0,0"
+ Help = "Definition of the black color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_BLUE"
+ Value = "0x98,0,0"
+ Help = "Definition of the blue color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_GREEN"
+ Value = "0,0x98,0"
+ Help = "Definition of the green color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_CYAN"
+ Value = "0x98,0x98,0"
+ Help = "Definition of the cyan color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_RED"
+ Value = "0,0,0x98"
+ Help = "Definition of the red color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_MAGENTA"
+ Value = "0x98,0,0x98"
+ Help = "Definition of the magenta color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_BROWN"
+ Value = "0x0,0x40,0x80"
+ Help = "Definition of the brown color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_LIGHTGRAY"
+ Value = "0x98,0x98,0x98"
+ Help = "Definition of the light gray color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_DARKGRAY"
+ Value = "0x10,0x10,0x10"
+ Help = "Definition of the dark gray color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_LIGHTBLUE"
+ Value = "0xFF,0x10,0x10"
+ Help = "Definition of the light blue color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_LIGHTGREEN"
+ Value = "0x10,0xFF,0x10"
+ Help = "Definition of the light green color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_LIGHTCYAN"
+ Value = "0xFF,0xFF,0xE0"
+ Help = "Definition of the light cyan color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_LIGHTRED"
+ Value = "0x10,0x10,0xFF "
+ Help = "Definition of the light red color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_LIGHTMAGENTA"
+ Value = "0xF0,0x10,0xFF"
+ Help = "Definition of the light magenta color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_YELLOW"
+ Value = "0x10,0xFF,0xFF"
+ Help = "Definition of the yellow color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_COLOR_WHITE"
+ Value = "0xFF,0xFF,0xFF"
+ Help = "Definition of the white color used by the graphic console\Format: <Blue>,<Green>,<Red>"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "<0-255>,<0-255>,<0-255>"
+End
+
+TOKEN
+ Name = "GC_MODE0"
+ Value = "{ 0, 80, 25, 800, 600 }"
+ Help = "Parameters of the graphica console text mode 0.\NOTE: Text resolution of the mode 0 must be 80 by 25\Format: {ModeNumber, TextColomns,TextRows, HorizontalPixels,VerticalPixels}"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "GC_MODE1"
+ Value = "{ 1, 80, 50, 1280, 1024 }"
+ Help = "Parameters of the graphica console text mode 1.\NOTE: Text resolution of the mode 0 must be 80 by 50\Format: {ModeNumber, TextColomns,TextRows, HorizontalPixels,VerticalPixels}"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "GC_MODE2"
+ Value = "{ 2, 100, 31, 800, 600 }"
+ Help = "Parameters of the graphica console text mode 2.\Format: {ModeNumber, TextColomns,TextRows, HorizontalPixels,VerticalPixels}"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "GC_MODE3"
+ Value = "{ 3, 0, 0, 0, 0 }"
+ Help = "Parameters of the graphica console text mode 3.\Format: {ModeNumber, TextColomns,TextRows, HorizontalPixels,VerticalPixels}"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "GC_MODE_LIST"
+ Value = "$(GC_MODE0), $(GC_MODE1), $(GC_MODE2), $(GC_MODE3)"
+ Help = "List of text modes supported by graphic console.\NOTE: Mode numbers defined by GC_MODEx tokens must be in ascending order."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "START_IN_NATIVE_RESOLUTION"
+ Value = "1"
+ Help = "When this token is 'on', Graphics console will start in native resolution if available"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INSTALL_DUMMY_SECURITY_PROTOCOL"
+ Value = "1"
+ Help = "When this token is 'on', the Core publishes dummy instance of the security protocol.\The security protocol is one of the architectural protocols and as such must be available.\The default value is 'on'. \Set to 'off' if project includes driver that publishes the security protocol.\"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PS2MOUSE_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "PS2Ctl_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PS2KBD_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "PS2Ctl_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "KBC_AUTODETECT_PORTS"
+ Value = "0"
+ Help = "Auto detection of KB/MS using AMI KB-5. This switch will enable/disable the connector swap of Keyboard and PS2 Mouse i.e. keyboard\can be connected to PS2 Mouse connector and vice-versa."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "KBC_AUTODETECT_PORTS_FUNCTION"
+ Value = "AutodetectKbdMousePorts"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "KBC_AUTODETECT_PORTS" "=" "1"
+End
+
+TOKEN
+ Name = "BLOCK_KBC_PIN_22_23_BIT"
+ Value = "1"
+ Help = "Turn this switch On or Off to block or unblock KBC lines P22 and P23.\If unblocked - KBC will be able to change lines P22 and P23 from high to low and back using D1 command.\If blocked - KBC will not be able to change the state of P22 and P23 lines."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "LEDS_AT_STARTUP"
+ Value = "2"
+ Help = "Keyboard LEDs after startup:\Bit0: ScrlLock is on/off;\Bit1: NumLock is on/off;\Bit2: CapsLock is on/off."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_HOTKEYS"
+ Value = "20"
+ Help = "Number of hot keys."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INIT_DEFAULT_HOTKEYS"
+ Value = "1"
+ Help = "Initialize default hot keys (perform system soft reset on Ctrl+Alt+Del combination)."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "KBC_BASIC_ASSURANCE_TEST"
+ Value = "1"
+ Help = "1 - Perform KBC Basic Assurance Test. 0 - Do not peform KBC Basic Assurance Test."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DETECT_PS2_KEYBOARD"
+ Value = "0"
+ Help = "1 - Perform PS2 Keyboard Detection. 0 - Do not perform PS2 Keybaord Detection."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DETECT_PS2_MOUSE"
+ Value = "0"
+ Help = "1 - Perform PS2 Mouse Detection. 0 - Do not perform PS2 Mouse Detection."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INSTALL_KEYBOARD_MOUSE_ALWAYS"
+ Value = "1"
+ Help = "1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always, 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if the device is present at the time of detection."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RETURN_CURRENT_KEY_STATE"
+ Value = "0"
+ Help = "0 - return key shift and toggle states captured during a keypress, 1 - return current shift and toggle state."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "KB_IRQ_SUPPORT"
+ Value = "0"
+ Help = "When this token is ON mouse will operate using interrupt, when OFF polling will be used"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MS_IRQ_SUPPORT"
+ Value = "0"
+ Help = "When this token is ON mouse will operate using interrupt, when OFF polling will be used"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "KBD_READ_BEFORE_INSTALL"
+ Value = "0"
+ Help = "This token will be used to save the key codes if keys are pressed before installing keyboard driver"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "KB_IRQ_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "IBFREE_TIMEOUT"
+ Value = "300"
+ Help = "Timeout (in miliseconds) used for the function IbFreeTimeout()"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CLEAR_PS2KB_BUFFER_AT_READYTOBOOT"
+ Value = "0"
+ Help = "ON -> PS2 KB Buffer will be cleared at ReadyToBoot.\OFF -> PS2 KB Buffer will not be cleared at ReadyToBoot."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CHECK_BDA_KEYBOARD_BUFFER"
+ Value = "1"
+ Help = "ON -> BDA KBD Buffer will be checked for any key whenever there is no key is found in ReadKeyStroke().\OFF -> BDA KBD Buffer will not be checked."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CLEAR_PENDING_KEYS_IN_PS2"
+ Value = "0"
+ Help = "ON -> Resets the keyboard before PS2 Driver is started and Clears OBF on every Kbd Reset as some Notbook KBC has some pending keys even after disabling and enabling Scanning."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BBS_USB_DEVICE_TYPE_SUPPORT"
+ Value = "0"
+ Help = "Treat USB devices as a separate BBS device type"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BBS_NETWORK_DEVICE_TYPE_SUPPORT"
+ Value = "0"
+ Help = "Treat network devices as a separate BBS device type"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "GROUP_BOOT_OPTIONS_BY_TAG"
+ Value = "1"
+ Help = "When this token is on, the boot options are grouped by tag.\When this token is off, the boot list is flat (a.k.a. flex boot)."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FW_ORPHAN_BOOT_OPTIONS_POLICY"
+ Value = "ORPHAN_BOOT_OPTIONS_POLICY_DELETE"
+ Help = "Defines handling of the firmware boot options not associated with the device.\The supported policies are: \ORPHAN_BOOT_OPTIONS_POLICY_KEEP\ORPHAN_BOOT_OPTIONS_POLICY_DELETE\ORPHAN_BOOT_OPTIONS_POLICY_DISABLE\"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NON_FW_ORPHAN_BOOT_OPTIONS_POLICY"
+ Value = "ORPHAN_BOOT_OPTIONS_POLICY_HIDE"
+ Help = "Defines handling of the non-firmware (third party) boot options not associated with the device.\The supported policies are: \ORPHAN_BOOT_OPTIONS_POLICY_KEEP\ORPHAN_BOOT_OPTIONS_POLICY_DELETE\ORPHAN_BOOT_OPTIONS_POLICY_DISABLE\ORPHAN_BOOT_OPTIONS_POLICY_HIDE\"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "ORPHAN_BOOT_OPTIONS_POLICY_KEEP"
+End
+
+TOKEN
+ Name = "ORPHAN_GROUP_HEADERS_POLICY"
+ Value = "ORPHAN_BOOT_OPTIONS_POLICY_DELETE"
+ Help = "Defines handling of the non-firmware (third party) boot options not associated with the device.\The supported policies are: \ORPHAN_BOOT_OPTIONS_POLICY_KEEP\ORPHAN_BOOT_OPTIONS_POLICY_DELETE\ORPHAN_BOOT_OPTIONS_POLICY_DISABLE\"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "ORPHAN_BOOT_OPTIONS_POLICY_KEEP"
+End
+
+TOKEN
+ Name = "NORMALIZE_BOOT_OPTION_NAME"
+ Value = "1"
+ Help = "When the token is on, the Description of the existing boot options is regenerated during the boot option processing.\It is possible to override built time Description normalization policy using NormalizeBootOptionName variable."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NORMALIZE_BOOT_OPTION_DEVICE_PATH"
+ Value = "1"
+ Help = "When the token is on, the FilePathList of the existing boot options is regenerated during the boot option processing.\It is possible to override built time FilePathList normalization policy using NormalizeBootOptionDevicePath variable."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_OPTION_TAG_PRIORITIES"
+ Value = "BoTagUefi, BoTagLegacyCdrom, BoTagLegacyHardDisk, BoTagLegacyFloppy, BoTagLegacyEmbedNetwork, BoTagEmbeddedShell"
+ Help = "List of value of type BOOT_OPTION_TAG that define priorities of the boot option tags.\BOOT_OPTION_TAG is defined in BdsBoard.c\"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "DEBUG_MODE" "=" "0"
+End
+
+TOKEN
+ Name = "BOOT_OPTION_TAG_PRIORITIES"
+ Value = "BoTagEmbeddedShell, BoTagUefi, BoTagLegacyCdrom, BoTagLegacyHardDisk, BoTagLegacyFloppy, BoTagLegacyEmbedNetwork"
+ Help = "List of value of type BOOT_OPTION_TAG that define priorities of the boot option tags.\BOOT_OPTION_TAG is defined in BdsBoard.c\"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "DEBUG_MODE" "!=" "0"
+End
+
+TOKEN
+ Name = "BOOT_OPTION_NAME_PREFIX_FUNCTION"
+ Value = "ConstructBootOptionNamePrefixDefault"
+ Help = "Name of the function of type CONSTRUCT_BOOT_OPTION_NAME.\The function is used to create boot option name prefix."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_OPTION_NAME_SUFFIX_FUNCTION"
+ Value = "ConstructBootOptionNameSuffixDefault"
+ Help = "Name of the function of type CONSTRUCT_BOOT_OPTION_NAME.\The function is used to create boot option name suffix."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_OPTION_GET_BBS_ENTRY_DEVICE_TYPE_FUNCTION"
+ Value = "GetBbsEntryDeviceTypeDefault"
+ Help = "Name of the function of type GET_BBS_ENTRY_DEVICE_TYPE.\The function is used to convert device type stored in the BBS table to a legacy device type that will be stored in the NVRAM.\The default implementation(GetBbsEntryDeviceTypeDefault) provides support for BBS_USB_DEVICE_TYPE_SUPPORT and BBS_NETWORK_DEVICE_TYPE_SUPPORT SDL tokens."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "MATCH_BOOT_OPTION_BY_LOCATION"
+ Value = "1"
+ Help = "When this option is on, the boot option is matched to the boot device using device location information. The device location is a specific connection point that the device is attached to. \For example: SATA Controller 1 Port 0, IDE Primary Master, USB Controller 1 Port 3\"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MATCH_BOOT_OPTION_BY_DEVICE"
+ Value = "1"
+ Help = "When this option is on, the boot option is matched to the boot device using device information such as device name, device serial number or other information that uniquely identifies the device."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BDS_CONNECT_CONSOLE_DEVICES"
+ Value = "1"
+ Help = "Enables/Disables execution of the BDS Control Flow \functions from the 'Connect Console Devices' group"
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "BDS_FULL_SYSTEM_INITIALIZATION"
+ Value = "1"
+ Help = "Enables/Disables execution of the BDS Control Flow(BDS_CONTROL_FLOW) \functions from the 'Full System Initialization' group"
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "BDS_CONNECT_CON_OUT_DEVICES"
+ Value = "1"
+ Help = "Enables/Disables execution of the BDS Control Flow(BDS_CONTROL_FLOW) \functions from the 'Connect ConOut Devices' group"
+ TokenType = Boolean
+ Token = "BDS_CONNECT_CONSOLE_DEVICES" "=" "1"
+End
+
+TOKEN
+ Name = "BDS_CONNECT_CON_IN_DEVICES"
+ Value = "1"
+ Help = "Enables/Disables execution of the BDS Control Flow(BDS_CONTROL_FLOW) \functions from the 'Connect ConIn Devices' group"
+ TokenType = Boolean
+ Token = "BDS_CONNECT_CONSOLE_DEVICES" "=" "1"
+End
+
+TOKEN
+ Name = "BDS_UPDATE_BOOT_OPTION_VARIABLES"
+ Value = "1"
+ Help = "Enables/Disables execution of the BDS Control Flow(BDS_CONTROL_FLOW) \functions from the 'UpdateBootOptionVariables,' group"
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "BDS_PROCESS_BOOT_OPTION_LIST"
+ Value = "1"
+ Help = "Enables/Disables execution of the BDS Control Flow(BDS_CONTROL_FLOW) \functions from the '/*Process Boot Option List*/' group"
+ TokenType = Boolean
+ Token = "BDS_UPDATE_BOOT_OPTION_VARIABLES" "=" "1"
+End
+
+TOKEN
+ Name = "ATAPI_BUSY_CLEAR_TIMEOUT"
+ Value = "16000"
+ Help = "Timeout value for ATAPI busy clear. Set to 16 sec."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "S3_BUSY_CLEAR_TIMEOUT"
+ Value = "10000"
+ Help = "Timeout value for S3 busy clear. Set to 10 sec."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DMA_ATA_COMMAND_COMPLETE_TIMEOUT"
+ Value = "5000"
+ Help = "Timeout value for completion of DMA ATA command. Set to 5 Sec."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT"
+ Value = "16000"
+ Help = "Timeout value for completion of DMA ATAPI command. Set to 16 Sec."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ATAPI_RESET_COMMAND_TIMEOUT"
+ Value = "5000"
+ Help = "Timeout Value for ATAPI reset command. Set to 5 sec."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "POWERON_BUSY_CLEAR_TIMEOUT"
+ Value = "10000"
+ Help = "The Poweron busy clear timeout value. Set to 10 sec."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "CORE_DXE_DIR"
+End
+
+MODULE
+ Help = "Includes CORE_DXE.mak to Project"
+ File = "CORE_DXE.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CORE_DXE.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DxeCoreInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BdsInit,"
+ Parent = "DxeCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "GenericSioEntryPoint,"
+ Parent = "DxeCoreInitialize"
+ Token = "SIO_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InitDataHub,"
+ Parent = "DxeCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "UnicodeCollationEntryPoint,"
+ Parent = "DxeCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BDS_CONTROL_FLOW"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "HiiBdsEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DiskIoEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "GCEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CSEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ Token = "ConSplitter_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PartitionEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ Token = "Partition_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CORE_DXE_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(CORE_DXE_DIR)\CORE_DXE$(ARCH)$(DBG).lib"
+ Parent = "CORE_DXE_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BdsEntryInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "DxeSioList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PS2CtlEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ Token = "PS2Ctl_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "FloppyCtrlEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ Token = "x64_BUILD" "=" "1"
+ Token = "FLOPPY_CTRL_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HiiDbEntryPoint,"
+ Parent = "DxeCoreInitialize"
+ Token = "EFI_SPECIFICATION_VERSION" "<=" "0x20000"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HiiDriverEntryPoint,"
+ Parent = "DxeCoreInitialize"
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BDS_SDBS"
+ Help = "List of SDB files with the string overrides for the BDS component."
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BootOptionDpMatchingFunctions"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BootOptionMatchingFunctions"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BootOptionBootDeviceFilteringFunctions"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BootOptionBuildNameFunctions"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BootOptionBuildFilePathFunctions"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "LocateDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PartitionDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "UsbClassDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BbsDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AmiBbsDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConstructBootOptionNameByHandle,"
+ Parent = "BootOptionBuildNameFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConstructBootOptionNameByBbsDescription,"
+ Parent = "BootOptionBuildNameFunctions"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConstructBootOptionNameByHandleDevicePath,"
+ Parent = "BootOptionBuildNameFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConstructBootOptionNameByFilePathList,"
+ Parent = "BootOptionBuildNameFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallLzmaDecompressProtocol,"
+ Parent = "DxeCoreInitialize"
+ Token = "LZMA_SUPPORT" "=" "1"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "BuildLegacyLocationFilePath,"
+ Parent = "BootOptionBuildFilePathFunctions"
+ Token = "CSM_SUPPORT" "=" "1"
+ Token = "MATCH_BOOT_OPTION_BY_LOCATION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BuildNameFilePath,"
+ Parent = "BootOptionBuildFilePathFunctions"
+ Token = "MATCH_BOOT_OPTION_BY_DEVICE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BuildLegacyFilePath,"
+ Parent = "BootOptionBuildFilePathFunctions"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "BuildEfiFilePath,"
+ Parent = "BootOptionBuildFilePathFunctions"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "AmiDeviceNameDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DeviceTypeDevicePathTest,"
+ Parent = "BootOptionDpMatchingFunctions"
+ Token = "MATCH_BOOT_OPTION_BY_LOCATION" "=" "0"
+ Token = "MATCH_BOOT_OPTION_BY_DEVICE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SignalConnectDriversEvent,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectRootBridgeHandles,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RegisterMemoryTypeInformationUpdateCallback,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "FastBootHook,"
+ Parent = "BDS_CONTROL_FLOW"
+ Token = "FAST_BOOT_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/* Connect Console Devices */"
+ Parent = "BDS_CONTROL_FLOW"
+ Token = "BDS_CONNECT_CONSOLE_DEVICES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/* Full System Initialization */"
+ Parent = "BDS_CONTROL_FLOW"
+ Token = "BDS_CONNECT_CONSOLE_DEVICES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/* Connect ConOut Devices */"
+ Parent = "/* Connect Console Devices */"
+ Token = "BDS_CONNECT_CON_OUT_DEVICES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/* Connect ConIn Devices */"
+ Parent = "/* Connect Console Devices */"
+ Token = "BDS_CONNECT_CON_IN_DEVICES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ReportConnectConOutProgressCode,"
+ Parent = "/* Connect ConOut Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectVgaConOut,"
+ Parent = "/* Connect ConOut Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectConOutVariable,"
+ Parent = "/* Connect ConOut Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallConOutStartedProtocol,"
+ Parent = "/* Connect ConOut Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ReportConnectConInProgressCode,"
+ Parent = "/* Connect ConIn Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectPs2ConIn,"
+ Parent = "/* Connect ConIn Devices */"
+ Token = "PS2Ctl_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectUsbConIn,"
+ Parent = "/* Connect ConIn Devices */"
+ Token = "AMIUSB_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectConInVariable,"
+ Parent = "/* Connect ConIn Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallConInStartedProtocol,"
+ Parent = "/* Connect ConIn Devices */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConInAvailabilityBeep,"
+ Parent = "/* Connect ConIn Devices */"
+ Token = "BEEP_ENABLE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ConnectEverything,"
+ Parent = "/* Full System Initialization */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RunDrivers,"
+ Parent = "/* Full System Initialization */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InitConVars,"
+ Parent = "/* Full System Initialization */"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallFwLoadFile,"
+ Parent = "/* Full System Initialization */"
+ Token = "Shell_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "UpdateBootOptionVariables,"
+ Parent = "/* Full System Initialization */"
+ Token = "BDS_UPDATE_BOOT_OPTION_VARIABLES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CallTheDispatcher,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CapsuleHook,"
+ Parent = "BDS_CONTROL_FLOW"
+ Token = "CAPSULE_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SignalAllDriversConnectedEvent,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HandoffToTse,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ReadBootOptions,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustLegacyBootOptionPriorities,"
+ Parent = "UpdateBootOptionVariables,"
+ Token = "CSM_SUPPORT" "=" "1"
+ Token = "GROUP_BOOT_OPTIONS_BY_TAG" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "UnmaskOrphanDevices,"
+ Parent = "UpdateBootOptionVariables,"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CollectBootDevices,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "FilterBootDeviceList,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MatchBootOptionsToDevices,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DeleteUnmatchedUefiHddBootDevices,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CreateBootOptionsForNewBootDevices,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/*Process Boot Option List*/"
+ Parent = "UpdateBootOptionVariables,"
+ Token = "BDS_PROCESS_BOOT_OPTION_LIST" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MaskOrphanDevices,"
+ Parent = "UpdateBootOptionVariables,"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SaveLegacyDevOrder,"
+ Parent = "UpdateBootOptionVariables,"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SaveBootOptions,"
+ Parent = "UpdateBootOptionVariables,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SetBootOptionTags,"
+ Parent = "/*Process Boot Option List*/"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "NormalizeBootOptions,"
+ Parent = "/*Process Boot Option List*/"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreProcessBootOptions,"
+ Parent = "/*Process Boot Option List*/"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SetBootOptionPriorities,"
+ Parent = "/*Process Boot Option List*/"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PostProcessBootOptions,"
+ Parent = "/*Process Boot Option List*/"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CORE_DXE/CORE_DXESrc.cif b/Core/CORE_DXE/CORE_DXESrc.cif
new file mode 100644
index 0000000..7a2e3d0
--- /dev/null
+++ b/Core/CORE_DXE/CORE_DXESrc.cif
@@ -0,0 +1,75 @@
+<component>
+ name = "CORE_DXE Sources(EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\"
+ RefName = "CORE_DXESrc_EDK"
+[files]
+"CORE_DXESrc.sdl"
+"CORE_DXESrc.mak"
+"CoreSectionExtraction.c"
+"DebugImageInfo.c"
+"DebugImageInfo.h"
+"DebugMask.c"
+"DebugMask.h"
+"dependency.c"
+"Dispatcher.c"
+"DriverSupport.c"
+"DxeCore.h"
+"DxeMain.c"
+"DxeProtocolNotify.c"
+"event.c"
+"exec.h"
+"execdata.c"
+"Ffs.c"
+"FwVol.c"
+"FwVolAttrib.c"
+"FwVolBlock.c"
+"FwVolBlock.h"
+"FwVolDriver.h"
+"FwVolRead.c"
+"FwVolWrite.c"
+"gcd.c"
+"gcd.h"
+"hand.h"
+"handle.c"
+"Image.c"
+"Image.h"
+"ImageFile.c"
+"imem.h"
+"InstallConfigurationTable.c"
+"Library.c"
+"Library.h"
+"locate.c"
+"memdata.c"
+"Notify.c"
+"Page.c"
+"pool.c"
+"SetWatchdogTimer.c"
+"Stall.c"
+"timer.c"
+"tpl.c"
+"hob.c"
+"AmiDxeInit.c"
+"BDS.c"
+"DataHub.c"
+"UnicodeCollation.c"
+"USFontPack.c"
+"DiskIo.c"
+"GC.c"
+"GenericSio.c"
+"EfiPerf.h"
+"LinkedList.h"
+"DxePerf.c"
+"BootOptions.c"
+"DevicePathToText.c"
+"DevicePathFromText.c"
+"DevicePath.h"
+[parts]
+"ConSplitter"
+"Partition"
+"PS2CTL"
+"FrameworkHii"
+"UefiHii"
+"FirmwareManagement"
+"HashService"
+<endComponent>
diff --git a/Core/CORE_DXE/CORE_DXESrc.mak b/Core/CORE_DXE/CORE_DXESrc.mak
new file mode 100644
index 0000000..e60aca0
--- /dev/null
+++ b/Core/CORE_DXE/CORE_DXESrc.mak
@@ -0,0 +1,155 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/DxeMain/CORE_DXESrc.mak 20 10/20/11 7:00p Artems $
+#
+# $Revision: 20 $
+#
+# $Date: 10/20/11 7:00p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/DxeMain/CORE_DXESrc.mak $
+#
+# 20 10/20/11 7:00p Artems
+# File BootOptions.h moved to Include folder - removed reference to its
+# old place
+#
+# 19 5/05/11 3:45p Artems
+# Added EDKII compatibility library for EDKII code embedded into Core
+#
+# 18 6/29/10 11:06p Felixp
+# New Boot Options Maintenance Infrastructure.
+# See AMI_Aptio_4.x_Boot_Options_Maintenance_Infrastructure_Porting_Guide
+# _NDA.doc for details.
+#
+# 17 11/13/09 3:56p Felixp
+# MM_LEGACY_RESERVE_MEM constant in Page.c is converted to SDL token.
+#
+# 16 10/09/09 6:06p Felixp
+# UEFI 2.1 - related changes (suppot Framework and UEFI HII).
+#
+# 15 3/05/09 1:08p Felixp
+# Minor improvements:
+# - Unconditional optimization (despite debug flag settings) is removed
+# - Headers updated
+#
+# 14 8/31/07 1:55p Felixp
+# Updated to support new location of AMIPostMgr.h. It is moved from
+# Core/em/AMITSE into Include/Protocol
+#
+# 13 4/23/07 1:28p Felixp
+# BootScriptSave removed from CORE_DXE(moved into AcpiS3Save driver)
+#
+# 12 3/13/07 2:04a Felixp
+#
+# 11 2/13/07 12:01p Felixp
+#
+# 10 2/13/07 9:18a Felixp
+# MRE Handshake protocol renamed to AMI POST Manager protocol
+# (MreHandshake.h removed from Core Protocols and added to AMITSE module
+# as AMIPostMgr.h)
+#
+# 9 12/05/06 12:34p Felixp
+#
+# 8 8/24/06 10:11a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 7 5/20/06 12:38a Felixp
+#
+# 6 5/19/06 10:46p Felixp
+# Updated to EDK 03.16.06
+# Cleanup
+#
+# 5 4/14/06 2:21p Felixp
+#
+# 4 4/03/06 3:52p Felixp
+# Major changes in PCI and Super I/O:
+# PCI - Root Bridge Resource Allocation Sepcification support
+# Super I/O - multiple Super I/O support; SIO Setup page added;
+#
+# 3 3/17/06 4:28p Felixp
+#
+# 2 3/13/06 5:25p Felixp
+#
+# 1 3/13/06 2:00a Felixp
+#
+# 4 12/02/05 11:20a Felixp
+#
+# 3 3/24/05 3:35p Felixp
+# FloppyCtrl moved into a separate component
+#
+# 2 2/01/05 1:16a Felixp
+# Floppy and PS2 modules added to the CORE_DXE
+#
+# 1 1/28/05 12:45p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CORE_DXESrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CORE_DXE_LIB
+
+$(CORE_DXE_LIB) : CORE_DXE_LIB
+
+CORE_DXE_LIB : $(BUILD_DIR)\CORE_DXESrc.mak CORE_DXE_LIBBin
+
+CORE_DXE_CIFS=\
+$(CORE_DXE_SRC_DIR)\$(@B).cif\
+!IF "$(Partition_SUPPORT)"=="1"
+$(PARTITION_DIR)\Partition.cif\
+!ENDIF
+!IF "$(ConSplitter_SUPPORT)"=="1"
+$(CONSOLE_SPLITTER_DIR)\ConSplitter.cif\
+!ENDIF
+!IF "$(PS2Ctl_SUPPORT)"=="1"
+$(PS2Ctl_DIR)\PS2Ctl.cif\
+!ENDIF
+!IF $(EFI_SPECIFICATION_VERSION)>0x20000
+$(UefiHii_DIR)\UefiHii.cif\
+!ELSE
+$(FrameworkHii_DIR)\FrameworkHii.cif\
+!ENDIF
+
+$(BUILD_DIR)\CORE_DXESrc.mak : $(CORE_DXE_SRC_DIR)\$(@B).mak $(BUILD_RULES) $(CORE_DXE_CIFS)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(CORE_DXE_CIFS)
+
+CORE_DXE_LIBBin : $(BUILD_DIR)\Foundation.lib $(EDK_II_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CORE_DXESrc.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(CORE_DXE_LIB)\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h $(FoundationCpu_DIR)\Processor.h"\
+ "MY_INCLUDES=/I$(CORE_PEI_DIR) /I$(Foundation_DIR) /I$(FoundationCpu_DIR)"\
+ "MY_DEFINES=/DMM_LEGACY_RESERVE_MEM=$(MM_LEGACY_RESERVE_MEM)"\
+ NAME=CORE_DXESrc
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/CORE_DXE/CORE_DXESrc.sdl b/Core/CORE_DXE/CORE_DXESrc.sdl
new file mode 100644
index 0000000..3fc6362
--- /dev/null
+++ b/Core/CORE_DXE/CORE_DXESrc.sdl
@@ -0,0 +1,57 @@
+TOKEN
+ Name = "CORE_DXESrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CORE_DXESrc support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "TRACE_START"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_MODE" "!=" "0"
+End
+
+TOKEN
+ Name = "TRACE_STOP"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_MODE" "!=" "0"
+End
+
+TOKEN
+ Name = "CURSOR_BLINK_ENABLE"
+ Value = "0"
+ Help = "Enables and Disables the functionality to make the cursor blink"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MM_LEGACY_RESERVE_MEM"
+ Value = "0x1000000"
+ Help = "DXE memory manager will try to keep memory in the range 0 - MM_LEGACY_RESERVE_MEM unallocated. \The memory in the range may still get allocated if the addresses in the range are specifically requested by \the AllocatePages calls, or if there is not enough free memory outside of the region to satisfy the request.\"
+ TokenType = Integer
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "CORE_DXE_SRC_DIR"
+End
+
+MODULE
+ Help = "Includes CORE_DXESrc.mak to Project"
+ File = "CORE_DXESrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CORE_DXE.lib"
+ Parent = "$(CORE_DXE_DIR)\CORE_DXE$(ARCH)$(DBG).lib"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/CORE_DXE/ConSplitter/ConSplit.c b/Core/CORE_DXE/ConSplitter/ConSplit.c
new file mode 100644
index 0000000..6963438
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplit.c
@@ -0,0 +1,2387 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.c 7 8/28/13 10:44p Thomaschen $
+//
+// $Revision: 7 $
+//
+// $Date: 8/28/13 10:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.c $
+//
+// 7 8/28/13 10:44p Thomaschen
+// Fixed for EIP133747.
+//
+// 6 8/01/13 2:32a Thomaschen
+// Add for EIP109384.
+// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c.
+//
+// 5 6/26/13 3:09a Thomaschen
+// Remove EIP109384.
+//
+// 3 6/04/13 1:55a Thomaschen
+// Fixed for EIP118202.
+//
+// 2 11/15/12 9:53p Wesleychen
+// Update to rev.55 for EIP103887.
+//
+// 55 10/29/12 3:44p Artems
+// [TAG] EIP103887
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Upgrade Serial Redirection to 4.6.3_Terminal_51 with Core
+// 4654, system will hang 0x06.
+// [RootCause] Uninitialized variable was used
+// [Solution] Initialize DeviceModeNumber variable before using
+// [Files] ConSplit.c
+//
+// 54 10/25/12 2:31a Deepthins
+// [TAG] EIP99475
+// [Category] Improvement
+// [Description] Multi language module Support in the console splitter
+// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h
+//
+// 53 10/08/12 4:28p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] system boots in wrong text mode
+// [RootCause] Incorrect restore of graphics mode after legacy OPROM
+// execution
+// [Solution] Added code for correct restoration of system state after
+// execution of Consplit.stop function
+// [Files] Consplit.c
+//
+// 52 8/13/12 3:39p Artems
+// [TAG] EIP95607
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Execute nsh script and redirect output to file, then exit
+// from shell, setup screen will crash
+// [RootCause] Console splitter maintains global pool of supportedmodes.
+// It's getting adjusted every time new SimpleTextOut (STO) is installed
+// If new STO doesn't support particular mode it is getting marked as
+// unsupported in global pool
+// However once this STO is uninstalled global pool isn't updated, so mode
+// is still marked as unsupported,
+// though system can support it
+// [Solution] Do not connect simpleTextOut driver if it doesn'tsupport
+// mode splitter is in
+// [Files] Consplit.c
+//
+// 51 8/02/12 12:13p Artems
+// [TAG] EIP95607
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Execute nsh script and redirect output to file, then exit
+// from shell, setup screen will crash
+// [RootCause] Console splitter maintains global pool of supported
+// modes.
+// It's getting adjusted every time new SimpleTextOut (STO) is installed
+// If new STO doesn't support particular mode it is getting marked as
+// unsupported in global pool
+// However once this STO is uninstalled global pool isn't updated, so mode
+// is still marked as unsupported,
+// though system can support it
+// [Solution] Added reinitilization of global pool of supported modes on
+// STO uninstall event
+// [Files] Consplit.h Consplit.c
+//
+// 50 7/06/12 11:28a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Support for monitor native resolution
+// [Files] GC.c, Consplit.c, Out.c, Core_Dxe.sdl
+//
+// 49 12/15/11 12:15p Felixp
+// [TAG] EIP73410
+// [Category] Improvement
+// [Description] InstallSimplePointerDevice function is updated to
+// initialize
+// LeftButton and RightButton fields of the
+// EFI_SIMPLE_POINTER_MODE structure exposed by
+// the splitter based on capabilities of the available mouse devices.
+//
+// 48 8/12/11 12:19p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 47 7/11/11 10:10a Felixp
+// Improvement (EIP 64049):
+// REPORT_NO_CON_OUT_ERROR and REPORT_NO_CON_IN_ERROR SDL tokens are added
+// to enable/disable reporting of the console errors.
+//
+// 46 5/13/11 3:37p Felixp
+// Minor improvement in CSStop: the screen is now saved after closing the
+// protocol
+//
+// 45 5/05/11 3:52p Artems
+// Added multi-language keyboard support
+//
+// 44 2/25/11 12:33p Artems
+// EIP 53767 - disable reporting keyboard absence on fast boot path
+//
+// 43 11/15/10 4:59p Felixp
+//
+// 41 9/24/10 3:38p Felixp
+// Enhancement(EIP 43535):
+// The pST->ConOut pointer used to be initialized once all ConOut
+// device are connected. The Console Splitter driver is updated
+// to initialize ConOut-related fields of the systems table
+// early (in the entry point) to workaround bugs in some of the
+// UEFI OpROM drivers that are using pST->ConOut without NULL checking.
+//
+// 40 9/24/10 7:39a Felixp
+// Additional checks for DXE_NO_CON_OUT and DXE_NO_CON_IN errors are
+// added.
+// The errors are now reported when no console devices with device path
+// available.
+//
+// 39 8/10/10 2:31p Vyacheslava
+// Simple Pointer Protocol bug fixes. (EIP#41832)
+//
+// 38 6/23/10 3:02p Felixp
+// SimplePointer splitter support is added.
+//
+// 37 2/19/10 9:58a Artems
+// Merged previous changes
+//
+// 36 2/12/10 6:13p Artems
+// EIP 34632 Added modification of MasterMode.MaxMode value if one of
+// children does not support Mode 2 or higher
+//
+// 34 8/28/09 9:07a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 33 7/08/09 4:42p Artems
+// Added missing functions headers
+//
+// 32 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 31 6/16/09 5:50p Artems
+// EIP 21415 Fixed error with CursorVisible variable
+//
+// 30 1/16/09 5:27p Felixp
+// Bug fix.
+// Headless systems hanging(EIP 18165).
+// Symptoms: Systems with no console output devices were hanging towards
+// the end of the boot process (prior to OS handoff).
+// Details: Some of the global variables used by console splitter
+// implementation
+// of TxtOut were only initialized once first physical console output
+// device is detected,
+// which was never happenning of a headless system.
+// The conosle splitter is updated to properly initialize the globals
+// when no actual console output devices are available.
+// UpdateSystemTableConOut function is updated.
+//
+// 29 1/05/09 3:11p Felixp
+// Minor update of UpdateSystemTableConOut.
+// Callback event is closed at the end of the function
+// (system table needs to be populated only once).
+//
+// 28 10/09/08 2:50p Felixp
+// StdErr and StandardErrorHandle initialization added
+//
+// 27 1/31/08 12:00p Olegi
+// Numlock bootup state made setup driven.
+//
+// 26 10/23/07 4:07p Olegi
+// Added a call to syncronize LEDs of ConIn devices during Start.
+//
+// 25 10/23/07 10:12a Felixp
+// Bug fix: after boot to Shell big part of the small AMI logo stayed on
+// the screen.
+// It was only happenning when two conditions were met: serial redirection
+// was turned off and plug in card with the option ROM was connected to
+// the system.
+//
+// 24 9/17/07 4:04p Olegi
+// Added support for AMI_EFIKEYCODE_PROTOCOL and
+// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+//
+// 23 9/05/07 5:43p Felixp
+// Report errors when no ConIn and ConOut devices are not available.
+//
+// 22 9/05/07 11:13a Felixp
+// SimpleTextInEx support removed. It causes problems. Support will add
+// again after Core labeling.
+//
+// 20 1/05/07 5:32p Artems
+//
+// 19 12/29/06 3:01p Felixp
+// 1. Support for GraphicsOutput protocol added
+// 2. Support for more then one text mode added
+//
+// 18 9/27/06 7:42p Felixp
+// SetMode funciton of the ConsoleControl protocol is updated to restore
+// default UGA mode when switching from grphics to text.
+//
+// 17 9/13/06 6:16p Felixp
+// pST->ConOut initialization logic changed: it is now initialized
+// immediately after the first ConOut device has been connected
+//
+// 16 3/13/06 2:37a Felixp
+//
+// 15 12/12/05 8:36p Felixp
+// RestoreTheScreen update: Restore Cursor Status
+//
+// 14 12/12/05 9:32a Felixp
+// Support for synchronization of console devices
+// (now screen is restored after legacy OpROM execution).
+//
+// 13 11/07/05 10:37a Felixp
+// LockStdIn function of ConsoleControl protocol implemented
+//
+// 12 7/15/05 7:17p Felixp
+// CONSOLE_DEVICES_STARTED_PROTOCOL_GUID added.
+// BDS uses it to notify Splitter that Console Devices have been started.
+// Once Splitter receives notification, it will install ConIn and ConOut
+// in System Table
+//
+// 11 5/27/05 12:16p Felixp
+//
+// 10 5/27/05 12:47a Felixp
+// Support for ConsoleControl protocol added
+//
+// 9 4/08/05 7:40a Felixp
+// fix: from now on when new device added, others not cleared
+//
+// 8 3/04/05 9:17a Mandal
+//
+// 7 2/24/05 5:30p Felixp
+// 1. Coded added to Start/Stop functions to open processed handles in
+// BY_CHILD_CONTROLLER mode
+// 2. GetControllerName implemented
+//
+// 6 2/11/05 6:11p Felixp
+// Logic to update ConDev variables
+//
+// 5 2/02/05 4:20p Felixp
+//
+// 3 2/02/05 2:32p Felixp
+// Splitter opens TxtIn and TxtOut in BY_DRIVER mode (used to be
+// GET_PROTOCOL)
+//
+// 2 2/01/05 1:17a Felixp
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 3 1/04/05 5:15p Robert
+// Changed component name to be more consistent with the other drivers
+// that have been developed
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ConSplit.c
+//
+// Description: Console Splitter driver that creates a cetralized input and
+// output console so that the correct data is going to and coming
+// from the correct devices
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+
+#include "ConSplit.h"
+#include <Protocol/DevicePath.h>
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/HiiDataBase.h>
+#include <Setup.h>
+#include <Dxe.h>
+#include <Hob.h>
+#include <Token.h>
+
+//----------------------------------------------------------------------------
+
+EFI_HANDLE ConSplitHandle = NULL;
+
+DLIST ConInList;
+DLIST ConOutList;
+DLIST ConPointerList;
+DLIST ConInKeyNotifyList;
+
+EFI_KEY_TOGGLE_STATE mCSToggleState = TOGGLE_STATE_VALID;
+BOOLEAN NumLockSet = FALSE;
+static BOOLEAN InitModesTableCalled = FALSE;
+
+static EFI_GUID gSimpleTextOutGuid = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
+static EFI_GUID gSimpleInGuid = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
+static EFI_GUID gSimpleInExGuid = EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL_GUID;
+static EFI_GUID gAmiEfiKeycodeGuid = AMI_EFIKEYCODE_PROTOCOL_GUID;
+static EFI_GUID gSimplePointerGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
+static EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static EFI_GUID gAmiMultiLangSupportGuid = AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID;
+
+extern SIMPLE_TEXT_OUTPUT_MODE MasterMode;
+
+
+EFI_STATUS InstallConOutDevice(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS InstallConInDevice(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn,
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx,
+ IN AMI_EFIKEYCODE_PROTOCOL *KeycodeIn,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS InstallSimplePointerDevice(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS ConOutHandleCheck(
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS ConInHandleCheck(
+ IN EFI_HANDLE Handle
+ );
+
+VOID CSSetKbLayoutNotifyFn(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_HII_DATABASE_PROTOCOL *HiiDatabase = NULL;
+EFI_HII_KEYBOARD_LAYOUT *gKeyDescriptorList = NULL;
+UINT16 KeyDescriptorListSize = 0;
+static EFI_GUID SetKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;
+
+EFI_STATUS ConSimplePointerHandleCheck( IN EFI_HANDLE Handle );
+
+EFI_DRIVER_BINDING_PROTOCOL gConSplitterDriverBindingProtocol = {
+ CSSupported,
+ CSStart,
+ CSStop,
+ 0x10,
+ NULL,
+ NULL
+ };
+AMI_MULTI_LANG_SUPPORT_PROTOCOL gMultiLangSupportProtocol = {
+ KeyboardLayoutMap
+};
+
+#ifdef EFI_DEBUG
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+static CHAR16 *gDriverName=L"AMI Console Splitter Driver";
+static CHAR16 *gControllerName=L"AMI Console Splitter";
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ComponentNameGetControllerName
+//
+// Description:
+// EFI_COMPONENT_NAME_PROTOCOL GetControllerName function
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL* This - pointer to protocol instance
+// IN EFI_HANDLE Controller - controller handle
+// IN EFI_HANDLE ChildHandle - child handle
+// IN CHAR8* Language - pointer to language description
+// OUT CHAR16** ControllerName - pointer to store pointer to controller name
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - controller name returned
+// EFI_INVALID_PARAMETER - language undefined
+// EFI_UNSUPPORTED - given language not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+ //Supports only English
+ if(!Language || !ControllerName)
+ return EFI_INVALID_PARAMETER;
+
+ if ( ChildHandle!=ConSplitHandle
+ || !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)
+ ) return EFI_UNSUPPORTED;
+
+ *ControllerName=gControllerName;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ComponentNameGetDriverName
+//
+// Description:
+// EFI_COMPONENT_NAME_PROTOCOL GetDriverName function
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL* This - pointer to protocol instance
+// IN CHAR8* Language - pointer to language description
+// OUT CHAR16** DriverName - pointer to store pointer to driver name
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver name returned
+// EFI_INVALID_PARAMETER - language undefined
+// EFI_UNSUPPORTED - given language not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS ComponentNameGetDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ //Supports only English
+ if(!Language || !DriverName)
+ return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//Component Name Protocol
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName = {
+ ComponentNameGetDriverName,
+ ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+#endif
+
+EFI_CONSOLE_CONTROL_SCREEN_MODE ScreenMode = EfiConsoleControlScreenText;
+BOOLEAN CursorVisible = TRUE;
+BOOLEAN StdInLocked = FALSE;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetMode
+//
+// Description:
+// This function returns current console mode
+//
+// Input:
+// IN EFI_CONSOLE_CONTROL_PROTOCOL *This - pointer to console protocol
+// OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode - placeholder for mode to return
+// OUT OPTIONAL BOOLEAN *UgaExists - if not NULL on return will have current UGA present state
+// OUT OPTIONAL BOOLEAN *StdInLocked - if not NULL on return will have value of STD_IN_LOCKED state
+//
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function returns correct values
+//
+// Modified:
+//
+// Referrals:
+// ScreenMode
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS GetMode(
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ OUT EFI_CONSOLE_CONTROL_SCREEN_MODE *Mode,
+ OUT BOOLEAN *UgaExists OPTIONAL,
+ OUT BOOLEAN *StdInLocked OPTIONAL
+)
+{
+ if (Mode) *Mode = ScreenMode;
+ if (UgaExists) *UgaExists = TRUE;
+ if (StdInLocked) *StdInLocked = FALSE;
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetMode
+//
+// Description:
+// This function sets current console mode
+//
+// Input:
+// IN EFI_CONSOLE_CONTROL_PROTOCOL *This - pointer to console protocol
+// IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode - mode to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - mode set successfully
+// EFI_INVALID_PARAMETER - incorrect mode given
+//
+// Modified:
+// ScreenMode
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS SetMode(
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN EFI_CONSOLE_CONTROL_SCREEN_MODE Mode
+)
+{
+ if (ScreenMode != Mode)
+ {
+ ScreenMode = Mode;
+ if (ScreenMode == EfiConsoleControlScreenText)
+ {
+ //Restore UGA mode when switching from graphics to text
+ DLINK *ListPtr = ConOutList.pHead;
+ CON_SPLIT_OUT *SimpleOut;
+ while ( ListPtr != NULL)
+ {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ RestoreUgaMode(SimpleOut->Handle);
+ ListPtr = ListPtr->pNext;
+ }
+
+ if (CursorVisible)
+ mCSOutProtocol.EnableCursor(&mCSOutProtocol,TRUE);
+ }
+ else if (ScreenMode == EfiConsoleControlScreenGraphics)
+ {
+ DLINK *ListPtr = ConOutList.pHead;
+ CON_SPLIT_OUT *SimpleOut;
+ CursorVisible = MasterMode.CursorVisible;
+ if (CursorVisible)
+ mCSOutProtocol.EnableCursor(&mCSOutProtocol,FALSE);
+ //Save UGA mode when switching from text to graphics
+ while ( ListPtr != NULL)
+ {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ SaveUgaMode(SimpleOut->Handle);
+ ListPtr = ListPtr->pNext;
+ }
+
+ }
+ else return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: LockStdIn
+//
+// Description:
+// This function toggles STD_IN_LOCKED state
+//
+// Input:
+// IN EFI_CONSOLE_CONTROL_PROTOCOL *This - pointer to console protocol
+// IN CHAR16 *Password - pointer to password string
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+// StdInLocked
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS LockStdIn(
+ IN EFI_CONSOLE_CONTROL_PROTOCOL *This,
+ IN CHAR16 *Password
+)
+{
+ //TODO: add support for the password
+ StdInLocked = !StdInLocked;
+ return EFI_SUCCESS;
+};
+
+EFI_GUID gConsoleControlProtocolGuid = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+
+EFI_CONSOLE_CONTROL_PROTOCOL gConsoleControlProtocol = {
+ GetMode,
+ SetMode,
+ LockStdIn
+};
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateSystemTableConOut
+//
+// Description:
+// This function updates system table ConOut pointer
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateSystemTableConOut()
+{
+ UINT32 CRC32 = 0;
+
+ if( ConOutList.Size==0 ){
+ //Initialize all the global variables used by
+ //splitter implementation of TxtOut.
+ //When physical ConOut devices are available, the initialization is performed
+ //within InitModesTable routine.
+ VERIFY_EFI_ERROR(ResizeSplitterBuffer(0));
+ VERIFY_EFI_ERROR(pBS->AllocatePool(EfiBootServicesData, sizeof(SUPPORT_RES), &SupportedModes));
+ SupportedModes[0].Rows = 25;
+ SupportedModes[0].Columns = 80;
+ SupportedModes[0].AllDevices = TRUE;
+ }
+
+ pST->ConOut = &mCSOutProtocol;
+ pST->ConsoleOutHandle = ConSplitHandle;
+ // We want to initialize ConOut-related fields of the systems table early
+ // to workaround bugs in some of the UEFI OpROM drivers
+ // that are using pST->ConOut without NULL checking.
+ // We are not installing the instance of SimpleTextOut on ConSplitHandle though,
+ // because it confuses the logic of TSE notification callbacks.
+ // The protocol is installed once all ConOut devices are connected
+ // in ReportNoConOutError.
+ if (pST->StdErr==NULL){
+ pST->StdErr = pST->ConOut;
+ pST->StandardErrorHandle = pST->ConsoleOutHandle;
+ }
+
+ // Now calculate the CRC32 value
+ pST->Hdr.CRC32 = 0;
+ pST->BootServices->CalculateCrc32(pST, sizeof(EFI_SYSTEM_TABLE), &CRC32);
+ pST->Hdr.CRC32 = CRC32;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ReportNoConOutError
+//
+// Description:
+// This function checks if physical ConOut devices are available.
+// If not, DXE_NO_CON_OUT error is reported.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ReportNoConOutError(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+#if REPORT_NO_CON_OUT_ERROR
+ DLINK *Link;
+ EFI_STATUS Status;
+
+ //Report error if no ConOut devices available or
+ // all console devices are fake devices (without device path).
+ for(Link = ConOutList.pHead; Link!=NULL; Link=Link->pNext){
+ CON_SPLIT_OUT *SimpleOut = OUTTER(Link, Link, CON_SPLIT_OUT);
+ VOID *Dp;
+
+ Status = pBS->HandleProtocol(
+ SimpleOut->Handle, &gEfiDevicePathProtocolGuid, &Dp
+ );
+ if (!EFI_ERROR(Status)) break; // Got one device path
+ }
+ //Report error if no ConOut devices with device path exists
+ if( ConOutList.Size==0 || EFI_ERROR(Status) )
+ ERROR_CODE(DXE_NO_CON_OUT, EFI_ERROR_MAJOR);
+#endif
+ pBS->InstallMultipleProtocolInterfaces (
+ &ConSplitHandle, &gSimpleTextOutGuid, &mCSOutProtocol,
+ &gConsoleControlProtocolGuid, &gConsoleControlProtocol,
+ NULL
+ );
+ pBS->CloseEvent(Event);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateSystemTableConIn
+//
+// Description:
+// This function updates system table ConIn pointer
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateSystemTableConIn(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ UINT32 CRC32 = 0;
+
+#if REPORT_NO_CON_IN_ERROR
+ DLINK *Link;
+ EFI_STATUS Status;
+
+ EFI_HOB_HANDOFF_INFO_TABLE *pHit;
+ static EFI_GUID guidHob = HOB_LIST_GUID;
+
+ //Report error if no ConIn devices available or
+ // all console devices are fake devices (without device path).
+ for(Link = ConInList.pHead; Link!=NULL; Link=Link->pNext){
+ CON_SPLIT_IN *SimpleIn = OUTTER(Link, Link, CON_SPLIT_IN);
+ VOID *Dp;
+
+ Status = pBS->HandleProtocol(
+ SimpleIn->Handle, &gEfiDevicePathProtocolGuid, &Dp
+ );
+ if (!EFI_ERROR(Status)) break; // Got one device path
+ }
+
+ pHit = GetEfiConfigurationTable(pST, &guidHob);
+ //Report error if no ConIn devices with device path exists
+ if( (ConInList.Size == 0 || EFI_ERROR(Status)) && (pHit->BootMode == BOOT_WITH_FULL_CONFIGURATION))
+ ERROR_CODE(DXE_NO_CON_IN, EFI_ERROR_MAJOR);
+#endif
+ pST->ConIn = &mCSSimpleInProtocol;
+
+ pBS->InstallMultipleProtocolInterfaces (
+ &ConSplitHandle,
+ &gSimpleInGuid, &mCSSimpleInProtocol,
+ &gSimpleInExGuid, &mCSSimpleInExProtocol,
+ &gAmiEfiKeycodeGuid, &mCSKeycodeInProtocol,
+ &gEfiSimplePointerProtocolGuid, &mCSSimplePointerProtocol,
+ NULL
+ );
+
+ pST->ConsoleInHandle = ConSplitHandle;
+
+ // Now calculate the CRC32 value
+ pST->Hdr.CRC32 = 0;
+ pST->BootServices->CalculateCrc32(pST, sizeof(EFI_SYSTEM_TABLE), &CRC32);
+ pST->Hdr.CRC32 = CRC32;
+
+ pBS->CloseEvent(Event);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSEntryPoint
+//
+// Description:
+// This function is Console splitter driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - image handle of Console splitter driver
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver installed successfully
+// EFI_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ static EFI_GUID guidConInStarted = CONSOLE_IN_DEVICES_STARTED_PROTOCOL_GUID;
+ static EFI_GUID guidConOutStarted = CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID;
+ // {8FF925F1-8624-4d38-9ED2-F8F5AA94F84A}
+ static EFI_GUID gDummyProtocolGuid =
+ { 0x8ff925f1, 0x8624, 0x4d38, { 0x9e, 0xd2, 0xf8, 0xf5, 0xaa, 0x94, 0xf8, 0x4a } };
+
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+ VOID *pRegistration;
+ SETUP_DATA *SetupData = NULL;
+ UINTN VariableSize = 0;
+ EFI_GUID SetupGuid = SETUP_GUID;
+
+ // initialize AMI library
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gConSplitterDriverBindingProtocol.DriverBindingHandle = NULL;
+ gConSplitterDriverBindingProtocol.ImageHandle = ImageHandle;
+
+ // Install driver binding protocol here
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &gConSplitterDriverBindingProtocol.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gConSplitterDriverBindingProtocol,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid, &gComponentName,
+#endif
+ &gAmiMultiLangSupportGuid, &gMultiLangSupportProtocol,
+ NULL);
+
+ // Create and event for the Simple In Interface
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_WAIT, TPL_NOTIFY,
+ CSWaitForKey, &mCSSimpleInProtocol,
+ &mCSSimpleInProtocol.WaitForKey
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Create and event for the SimpleInEx Interface
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_WAIT, TPL_NOTIFY,
+ CSWaitForKey, &mCSSimpleInExProtocol,
+ &mCSSimpleInExProtocol.WaitForKeyEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ // Create and event for the KeycodeIn Interface
+ Status = pBS->CreateEvent (EFI_EVENT_NOTIFY_WAIT, TPL_NOTIFY,
+ CSWaitForKey, &mCSKeycodeInProtocol,
+ &mCSKeycodeInProtocol.WaitForKeyEx
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Create an event for the SimplePointer Interface
+ Status = pBS->CreateEvent(
+ EFI_EVENT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ ConSplitterSimplePointerWaitForInput,
+ &mCSSimplePointerProtocol,
+ &mCSSimplePointerProtocol.WaitForInput
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ // Initialize the global lists here
+ DListInit(&ConInList);
+ DListInit(&ConOutList);
+ DListInit(&ConPointerList);
+ DListInit(&ConInKeyNotifyList);
+
+ // Register Protocol Notification to expose
+ // Console Splitter interface only after all consoles initialized
+ RegisterProtocolCallback(
+ &guidConOutStarted, ReportNoConOutError,
+ NULL, &Event,&pRegistration
+ );
+ RegisterProtocolCallback(
+ &guidConInStarted, UpdateSystemTableConIn,
+ NULL, &Event,&pRegistration
+ );
+
+ //We need a valid handle
+ //The only way to create it is to install a protocol
+ //Let's install a dummy protocol
+ pBS->InstallMultipleProtocolInterfaces (
+ &ConSplitHandle,
+ &gDummyProtocolGuid, NULL,
+ NULL
+ );
+
+ //install pST->ConOut
+ UpdateSystemTableConOut();
+
+//multi keyboard layout support
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ CSSetKbLayoutNotifyFn,
+ NULL,
+ &SetKeyboardLayoutEventGuid,
+ &Event);
+ CSSetKbLayoutNotifyFn(NULL, NULL);
+
+ // Lighten up the keyboard(s) lights
+ if(NumLockSet == FALSE) {
+ Status = GetEfiVariable(L"Setup", &SetupGuid, NULL, &VariableSize, &SetupData);
+ if (!EFI_ERROR(Status)) {
+ if (SetupData->Numlock) {
+ mCSToggleState |= NUM_LOCK_ACTIVE;
+ }
+ pBS->FreePool(SetupData);
+ }
+ NumLockSet=TRUE;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSupported
+//
+// Description:
+// This function is Console splitter driver Supported function for driver
+// binding protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver supports given controller
+// EFI_UNSUPPORTED - driver doesn't support given controller
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn = NULL;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx = NULL;
+ AMI_EFIKEYCODE_PROTOCOL *KeycodeIn = NULL;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut = NULL;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer = NULL;
+ EFI_STATUS SimplePointerStatus;
+ EFI_STATUS OutStatus;
+ EFI_STATUS InStatus;
+ EFI_STATUS InExStatus;
+ EFI_STATUS KeycodeInStatus;
+ INT32 Dummy;
+
+ if (ControllerHandle == ConSplitHandle)
+ return EFI_UNSUPPORTED;
+
+ // check to see if this device has a simple text out protocol installed on it
+ OutStatus = pBS->OpenProtocol ( ControllerHandle, &gSimpleTextOutGuid,
+ &SimpleOut, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if(!EFI_ERROR(OutStatus)) {
+ OutStatus = IsModeSupported(SimpleOut, MasterMode.Mode, &Dummy);
+ if(EFI_ERROR(OutStatus)) {
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ControllerHandle);
+ }
+ }
+
+
+ // check to see if this device has a simple input protocol installed on it
+ InStatus = pBS->OpenProtocol ( ControllerHandle, &gSimpleInGuid,
+ &SimpleIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ InExStatus = pBS->OpenProtocol ( ControllerHandle, &gSimpleInExGuid,
+ &SimpleInEx, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ KeycodeInStatus = pBS->OpenProtocol ( ControllerHandle, &gAmiEfiKeycodeGuid,
+ &KeycodeIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ // check if device has simple pointer protocol installed on it
+ SimplePointerStatus = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ &SimplePointer,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR(SimplePointerStatus))
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ if (!EFI_ERROR(OutStatus))
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if (!EFI_ERROR(InStatus))
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if (!EFI_ERROR(InExStatus))
+ pBS->CloseProtocol(ControllerHandle, &gAmiEfiKeycodeGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if (!EFI_ERROR(KeycodeInStatus))
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInExGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ if ( EFI_ERROR(SimplePointerStatus) &&
+ EFI_ERROR(OutStatus) &&
+ EFI_ERROR(InStatus) &&
+ EFI_ERROR(InExStatus) &&
+ EFI_ERROR(KeycodeInStatus) )
+ return EFI_UNSUPPORTED;
+
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSStart
+//
+// Description:
+// This function is Console splitter driver Start function for driver
+// binding protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver started successfully
+// EFI_UNSUPPORTED - driver didn't start
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSStart(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn = NULL;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx = NULL;
+ AMI_EFIKEYCODE_PROTOCOL *KeycodeIn = NULL;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut = NULL;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer = NULL;
+ EFI_STATUS Status;
+ EFI_STATUS OutStatus;
+ EFI_STATUS InStatus;
+ EFI_STATUS InExStatus;
+ EFI_STATUS KeycodeInStatus;
+
+ // grab the pointers for the ConIn, ConOut, and StdErr from the System Table
+ // install the current handles for these devices.
+
+ // if Simple In, add the Con In device to the list and
+ InStatus = pBS->OpenProtocol(ControllerHandle, &gSimpleInGuid,
+ &SimpleIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ InExStatus = pBS->OpenProtocol(ControllerHandle, &gSimpleInExGuid,
+ &SimpleInEx, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ KeycodeInStatus = pBS->OpenProtocol(ControllerHandle, &gAmiEfiKeycodeGuid,
+ &KeycodeIn, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (!EFI_ERROR(InStatus) || !EFI_ERROR(InExStatus) || !EFI_ERROR(KeycodeInStatus))
+ {
+ InStatus = InstallConInDevice(SimpleIn, SimpleInEx, KeycodeIn, ControllerHandle);
+ if (InStatus == EFI_OUT_OF_RESOURCES)
+ return InStatus;
+
+ if (!EFI_ERROR(InStatus))
+ pBS->OpenProtocol(ControllerHandle, &gSimpleInGuid,
+ &SimpleIn, This->DriverBindingHandle,
+ ConSplitHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+ }
+
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ &SimplePointer,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (!EFI_ERROR(Status)) {
+ Status = InstallSimplePointerDevice( SimplePointer, ControllerHandle );
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ &SimplePointer,
+ This->DriverBindingHandle,
+ ConSplitHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ } else if (Status == EFI_OUT_OF_RESOURCES)
+ return Status;
+ }
+
+ // if it has a simple text out add the Con Out device to the list and
+ OutStatus = pBS->OpenProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ &SimpleOut, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (!EFI_ERROR(OutStatus) )
+ {
+ OutStatus = InstallConOutDevice(SimpleOut, ControllerHandle);
+ if (OutStatus == EFI_OUT_OF_RESOURCES)
+ return OutStatus;
+
+ if (!EFI_ERROR(OutStatus))
+ {
+ RestoreTheScreen(ControllerHandle,SimpleOut);
+ pBS->OpenProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ &SimpleOut, This->DriverBindingHandle,
+ ConSplitHandle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+ }
+ }
+
+ // If no devices were installed, then Houston we have a problem
+ if ( EFI_ERROR(OutStatus) && EFI_ERROR(InStatus) && EFI_ERROR(Status) )
+ return EFI_UNSUPPORTED;
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSStop
+//
+// Description:
+// This function is Console splitter driver Stop function for driver
+// binding protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN UINTN NumberOfChildren - number of childs on this handle
+// IN OPTIONAL EFI_HANDLE *ChildHandleBuffer - pointer to child handles array
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver stopped successfully
+// EFI_INVALID_PARAMETER - invalid values passed for NumberOfChildren or
+// ChildHandleBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ DLINK *ListPtr;
+ CON_SPLIT_IN *SimpleIn;
+ CON_SPLIT_OUT *SimpleOut;
+ CON_SPLIT_SIMPLE_POINTER *SimplePointer = NULL;
+ BOOLEAN Stopped = FALSE;
+ DLINK *HandleLink = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (NumberOfChildren == 0)
+ return EFI_SUCCESS;
+
+ if ( NumberOfChildren != 1 ||
+ ChildHandleBuffer == NULL ||
+ *ChildHandleBuffer!= ConSplitHandle )
+ return EFI_INVALID_PARAMETER;
+
+ // remove simple text out, simple in, simple pointer
+ ListPtr = ConOutList.pHead;
+ while ( ListPtr != NULL)
+ {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ if ( SimpleOut->Handle == ControllerHandle)
+ {
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleTextOutGuid,
+ This->DriverBindingHandle, ConSplitHandle);
+ DListDelete(&ConOutList, ListPtr);
+ Stopped = TRUE;
+ SaveTheScreen(ControllerHandle, SimpleOut->SimpleOut);
+ Status = pBS->FreePool(SimpleOut);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ //If we already populated pST->ConOut preserve
+ //screen buffer and list of supported modes
+ //to keep using it when ConOut devices are connected
+ if(ConOutList.Size == 0 && !pST->ConOut) //all devices stops
+ {
+ if(SupportedModes != NULL)
+ {
+ pBS->FreePool(SupportedModes);
+ SupportedModes = NULL;
+ }
+
+ if(ScreenBuffer != NULL)
+ {
+ pBS->FreePool(ScreenBuffer);
+ ScreenBuffer = NULL;
+ }
+
+ if(AttributeBuffer != NULL)
+ {
+ pBS->FreePool(AttributeBuffer);
+ AttributeBuffer = NULL;
+ }
+
+ MasterMode.Mode=0;
+ } else {
+ if(Stopped && ConOutList.Size > 0) //re-initialize supported modes buffer if at least one child was stopped
+ AdjustSupportedModes();
+ }
+
+ ListPtr = ConInList.pHead;
+ while ( ListPtr != NULL)
+ {
+ SimpleIn = OUTTER(ListPtr, Link, CON_SPLIT_IN);
+ if ( SimpleIn->Handle == ControllerHandle)
+ {
+ DListDelete(&ConInList, ListPtr);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInExGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gAmiEfiKeycodeGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ pBS->CloseProtocol(ControllerHandle, &gSimpleInGuid,
+ This->DriverBindingHandle, ConSplitHandle);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ if (ListPtr != NULL && SimpleIn->SimpleInEx != NULL) {
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ for (HandleLink = CsInKeyNotify->NotifyHandleList.pHead; HandleLink != NULL;
+ HandleLink = HandleLink->pNext) {
+ CsInNotifyHandle = OUTTER(HandleLink, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE);
+
+ if (SimpleIn->SimpleInEx != CsInNotifyHandle->SimpleInEx) {
+ continue;
+ }
+
+ Status = SimpleIn->SimpleInEx->UnregisterKeyNotify(
+ SimpleIn->SimpleInEx, CsInNotifyHandle->NotifyHandle);
+
+ DListDelete(&(CsInKeyNotify->NotifyHandleList), HandleLink);
+ Status = pBS->FreePool(CsInNotifyHandle);
+ }
+ }
+ Status = pBS->FreePool(SimpleIn);
+ }
+
+ ListPtr = ConPointerList.pHead;
+ while (ListPtr != NULL) {
+ SimplePointer = OUTTER(ListPtr, Link, CON_SPLIT_SIMPLE_POINTER);
+ if ( SimplePointer->Handle == ControllerHandle ) {
+ DListDelete(&ConPointerList, ListPtr);
+
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiSimplePointerProtocolGuid,
+ This->DriverBindingHandle,
+ ConSplitHandle
+ );
+ Status = pBS->FreePool(SimplePointer);
+ break;
+ }
+ ListPtr = ListPtr->pNext;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateConVar
+//
+// Description:
+// This function stores device path of given controller in EFI variable with
+// name sVarName
+//
+// Input:
+// IN EFI_HANDLE Controller - controller, which device path to store
+// IN CHAR16 *sVarName - name of EFI variable to store device path under
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateConVar(
+ IN EFI_HANDLE Controller,
+ IN CHAR16 *sVarName
+)
+{
+ static EFI_GUID guidDevicePath = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ static EFI_GUID guidEfiVar = EFI_GLOBAL_VARIABLE;
+ EFI_DEVICE_PATH_PROTOCOL *pDevicePath, *pConDev = NULL;
+ EFI_STATUS Status;
+ UINTN DataSize=0;
+ UINT32 Attributes;
+
+ Status = pBS->HandleProtocol(Controller,&guidDevicePath, &pDevicePath);
+ if (EFI_ERROR(Status))
+ return;
+
+ Status = GetEfiVariable(sVarName, &guidEfiVar, &Attributes, &DataSize, &pConDev);
+ if (EFI_ERROR(Status))
+ {
+ if (Status!=EFI_NOT_FOUND)
+ return;
+
+ DataSize = DPLength(pDevicePath);
+ pRS->SetVariable(sVarName, &guidEfiVar,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ DataSize, pDevicePath);
+ return;
+ }
+
+ if (!DPIsOneOf(pConDev, pDevicePath, FALSE))
+ {
+ EFI_DEVICE_PATH_PROTOCOL *pNewConDev = DPAddInstance(pConDev, pDevicePath);
+ DataSize = DPLength(pNewConDev);
+ pRS->SetVariable(sVarName, &guidEfiVar, Attributes, DataSize, pNewConDev);
+ pBS->FreePool(pNewConDev);
+ }
+
+ pBS->FreePool(pConDev);
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallSimplePointerDevice
+//
+// Description:
+// This function adds another ConIn device to splitter
+//
+// Input:
+// *SimpleIn - pointer to new protocol
+// *SimpleInEx - pointer to new extended protocol
+// *KeycodeIn - pointer to AMI key code protocol
+// Handle - handle of new device
+//
+// Output:
+// EFI_SUCCESS - device added successfully
+// EFI_UNSUPPORTED - device not supported
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InstallSimplePointerDevice(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer,
+ IN EFI_HANDLE Handle )
+{
+ EFI_STATUS Status;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+
+ if (EFI_ERROR(ConSimplePointerHandleCheck(Handle)))
+ return EFI_UNSUPPORTED;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CON_SPLIT_SIMPLE_POINTER),
+ &ConSimplePointer
+ );
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ ConSimplePointer->SimplePointer = SimplePointer;
+ ConSimplePointer->Handle = Handle;
+ mCSSimplePointerProtocol.Mode->LeftButton |= SimplePointer->Mode->LeftButton;
+ mCSSimplePointerProtocol.Mode->RightButton |= SimplePointer->Mode->RightButton;
+ DListAdd(&ConPointerList, &ConSimplePointer->Link);
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallConOutDevice
+//
+// Description:
+// This function adds another ConOut device to splitter
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut - pointer to new protocol
+// IN EFI_HANDLE Handle - handle of new device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device added successfully
+// EFI_UNSUPPORTED - device not supported
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InstallConOutDevice(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut,
+ IN EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+ CON_SPLIT_OUT *ConOut;
+ INT32 DeviceModeNumber = 0;
+ BOOLEAN FirstChild = FALSE;
+
+ if (EFI_ERROR(ConOutHandleCheck(Handle)))
+ return EFI_UNSUPPORTED;
+
+ if(MasterMode.Mode != 0) //already in extended mode
+ if (EFI_ERROR(IsModeSupported(SimpleOut, MasterMode.Mode, &DeviceModeNumber)))
+ return EFI_UNSUPPORTED; //device doesn't support current mode - do not include into list
+
+
+ if (ConOutList.Size==0 && !InitModesTableCalled) //this is first call
+ {
+ FirstChild = TRUE;
+ Status = InitModesTable(SimpleOut, Handle);
+ if(EFI_ERROR(Status)) //first device becomes master
+ return Status;
+ }
+ else
+ UpdateModesTable(SimpleOut, Handle); //all next devices
+
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(CON_SPLIT_OUT), &ConOut);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ ConOut->SimpleOut = SimpleOut;
+
+ ConOut->Handle = Handle;
+
+ DListAdd(&ConOutList, &(ConOut->Link));
+
+ if(!FirstChild) {
+ // set child display to a current master mode
+ SimpleOut->SetMode(SimpleOut, DeviceModeNumber);
+ SimpleOut->EnableCursor(SimpleOut, MasterMode.CursorVisible);
+ }
+ UpdateConVar(Handle, L"ConOutDev");
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallConInDevice
+//
+// Description:
+// This function adds another ConIn device to splitter
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn - pointer to new protocol
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx - pointer to new extended
+// protocol
+// IN AMI_EFIKEYCODE_PROTOCOL *KeycodeIn - pointer to AMI key code protocol
+// IN EFI_HANDLE Handle - handle of new device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device added successfully
+// EFI_UNSUPPORTED - device not supported
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InstallConInDevice(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn,
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx,
+ IN AMI_EFIKEYCODE_PROTOCOL *KeycodeIn,
+ IN EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+ CON_SPLIT_IN *ConIn;
+ DLINK *ListPtr;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (EFI_ERROR(ConInHandleCheck(Handle)))
+ return EFI_UNSUPPORTED;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(CON_SPLIT_IN), &ConIn);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ ConIn->SimpleIn = SimpleIn;
+ ConIn->SimpleInEx = SimpleInEx;
+ ConIn->KeycodeInEx = KeycodeIn;
+
+ ConIn->Handle = Handle;
+
+ DListAdd(&ConInList, &(ConIn->Link));
+
+ UpdateConVar(Handle, L"ConInDev");
+
+ if (SimpleInEx == NULL) {
+ return EFI_SUCCESS;
+ }
+
+ SimpleInEx->SetState(SimpleInEx, &mCSToggleState);
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CON_SPLIT_IN_KEY_NOTIFY_HANDLE), &CsInNotifyHandle);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ CsInNotifyHandle->SimpleInEx = SimpleInEx;
+
+ Status = SimpleInEx->RegisterKeyNotify(SimpleInEx, &CsInKeyNotify->KeyData,
+ CsInKeyNotify->KeyNotificationFunction, &(CsInNotifyHandle->NotifyHandle));
+ if (EFI_ERROR(Status)) {
+ Status = pBS->FreePool(CsInNotifyHandle);
+ continue;
+ }
+
+ DListAdd(&(CsInKeyNotify->NotifyHandleList), &(CsInNotifyHandle->Link));
+ }
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConOutHandleCheck
+//
+// Description:
+// This function checks if ConOut device already present in Splitter
+//
+// Input:
+// IN EFI_HANDLE Handle - handle of device to check
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device not present
+// EFI_UNSUPPORTED - device already present
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConOutHandleCheck(
+ IN EFI_HANDLE Handle
+)
+{
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ // if the list is empty return the status that was passed in
+ if (SimpleOut == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( SimpleOut != NULL)
+ {
+ // check the handle
+ if (SimpleOut->Handle == Handle)
+ return EFI_UNSUPPORTED;
+ // go to the next element in the list
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConInHandleCheck
+//
+// Description:
+// This function checks if ConIn device already present in Splitter
+//
+// Input:
+// IN EFI_HANDLE Handle - handle of device to check
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device not present
+// EFI_UNSUPPORTED - device already present
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConInHandleCheck(
+ IN EFI_HANDLE Handle
+)
+{
+ CON_SPLIT_IN *SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // if the list is empty return the status that was passed in
+ if (SimpleIn == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( SimpleIn != NULL)
+ {
+ // check the handle
+ if (SimpleIn->Handle == Handle)
+ return EFI_UNSUPPORTED;
+ // go to the next element in the list
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSimplePointerHandleCheck
+//
+// Description:
+// This function checks if ConIn device already present in Splitter.
+//
+// Input: Handle - handle of device to check
+//
+// Output:
+// EFI_SUCCESS - device not present
+// EFI_UNSUPPORTED - device already present
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConSimplePointerHandleCheck( IN EFI_HANDLE Handle )
+{
+ CON_SPLIT_SIMPLE_POINTER *SimplePointer;
+
+ SimplePointer = OUTTER(ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER);
+
+ // if the list is empty return the status that was passed in
+ if (SimplePointer == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( SimplePointer != NULL) {
+
+ // check the handle
+ if (SimplePointer->Handle == Handle)
+ return EFI_UNSUPPORTED;
+
+ // go to the next element in the list
+ SimplePointer = OUTTER(SimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InitModesTable
+//
+// Description:
+// This function fills the SupportedModes table with modes supported by first
+// simple text out device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol
+// IN EFI_HANDLE Handle - handle of first ConOut device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - table filled successfully
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified: SupportedModes, MasterMode
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS InitModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+)
+{
+ INT32 MaxMode;
+ INT32 CurrentMode;
+ UINTN Rows, Columns;
+ INT32 i;
+ EFI_STATUS Status;
+
+ if(Handle == ConSplitHandle)
+ return EFI_SUCCESS;
+
+ InitModesTableCalled = TRUE;
+
+ MaxMode = This->Mode->MaxMode;
+ CurrentMode = This->Mode->Mode;
+
+ //The SupportedModes structure
+ //may have already been initialized in UpdateSystemTableConOut.
+ //If this is the case, free the memory before reinitialization.
+ if (SupportedModes!=NULL){
+ //If SupportedModes is not NULL,
+ //ResizeSplitterBuffer(0) has already been called
+ pBS->FreePool(SupportedModes);
+ SupportedModes = NULL;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SUPPORT_RES)* MaxMode,
+ &SupportedModes);
+ if(EFI_ERROR(Status))
+ {
+ MasterMode.MaxMode = 1;
+ return EFI_SUCCESS;
+ }
+
+ MasterMode.MaxMode = MaxMode; //modify default value
+
+ for(i = 0; i < MaxMode; i++)
+ {
+ Status = This->QueryMode(This, i, &Columns, &Rows);
+ SupportedModes[i].Rows = (INT32)Rows;
+ SupportedModes[i].Columns = (INT32)Columns;
+ SupportedModes[i].AllDevices = EFI_ERROR(Status) ? FALSE : TRUE;
+ }
+
+//Make sure MasterMode.Mode <> CurrentMode, otherwise ResizeSplitterBuffer won't do anything
+ MasterMode.Mode = CurrentMode + 1;
+ Status = ResizeSplitterBuffer(CurrentMode);
+ MasterMode.Mode = CurrentMode;
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IsModeSupported
+//
+// Description:
+// This function determines if mode, specified by ModeNum supported by
+// simple text out device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol to check
+// IN UINTN ModeNum - mode to check
+// OUT INT32 *DeviceModeNumber - device mode number correspondent to ModeNum
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - mode supported by device
+// EFI_UNSUPPORTED - mode not supported by device
+//
+// Modified:
+//
+// Referrals: SupportedModes
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS IsModeSupported(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT INT32 *DeviceModeNumber)
+{
+ INT32 MaxMode;
+ UINTN Rows, Columns;
+ INT32 i;
+ EFI_STATUS Status;
+
+ MaxMode = This->Mode->MaxMode;
+ for(i = 0; i < MaxMode; i++)
+ {
+ Status = This->QueryMode(This, i , &Columns, &Rows);
+ if (!EFI_ERROR(Status) && \
+ SupportedModes[ModeNum].Rows == (INT32)Rows && \
+ SupportedModes[ModeNum].Columns == (INT32)Columns)
+ {
+ *DeviceModeNumber = i;
+ return EFI_SUCCESS;
+ }
+
+ }
+ return EFI_UNSUPPORTED;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateModesTable
+//
+// Description:
+// This function updates supported modes table when new devices started don't
+// support some of this modes
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol to check
+// IN EFI_HANDLE Handle - handle of device
+//
+// Output:
+// VOID
+//
+// Modified: SupportedModes
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+)
+{
+ INT32 i, ModeNumber;
+ EFI_STATUS Status;
+
+ if(Handle == ConSplitHandle)
+ return;
+
+
+ for(i = 0; i < MasterMode.MaxMode; i++) {
+ if(SupportedModes[i].AllDevices == FALSE) continue;
+ Status = IsModeSupported(This, i, &ModeNumber);
+ SupportedModes[i].AllDevices = EFI_ERROR(Status) ? FALSE : TRUE;
+ }
+
+//update MasterMode.MaxMode value based on modes supported by different devices
+//lookup for the first mode above 1 not supported by all devices - this will be
+//new MaxMode value
+ for(i = 2; i < MasterMode.MaxMode; i++) {
+ if(SupportedModes[i].AllDevices == FALSE) {
+ MasterMode.MaxMode = i;
+ break;
+ }
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ResizeSplitterBuffer
+//
+// Description:
+// This function allocates new buffers when mode changed
+//
+// Input:
+// IN INT32 ModeNum - new mode
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - new buffers allocated
+// EFI_OUT_OF_RESOURCES - not enough resources to perform operation
+//
+// Modified: ScreenBuffer, EndOfTheScreen,AttributeBuffer
+//
+// Referrals: SupportedModes, MasterMode
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ResizeSplitterBuffer(
+ IN INT32 ModeNum
+)
+{
+ INT32 Row, Col;
+ CHAR16 *NewCharBuffer;
+ INT32 *NewAttributeBuffer;
+ EFI_STATUS Status;
+
+ if(ModeNum != MasterMode.Mode || SupportedModes == NULL) //check if it is first init
+ {
+
+ if(SupportedModes == NULL)
+ {
+ Row = 25;
+ Col = 80;
+ }
+ else
+ {
+ Row = SupportedModes[ModeNum].Rows;
+ Col = SupportedModes[ModeNum].Columns;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CHAR16) * Row * Col,
+ &NewCharBuffer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(INT32) * Row * Col,
+ &NewAttributeBuffer);
+ if(EFI_ERROR(Status))
+ {
+ pBS->FreePool(NewCharBuffer);
+ return Status;
+ }
+
+ if(ScreenBuffer != NULL)
+ pBS->FreePool(ScreenBuffer);
+ ScreenBuffer = NewCharBuffer;
+ EndOfTheScreen = ScreenBuffer + (Row * Col);
+
+ if(AttributeBuffer != NULL)
+ pBS->FreePool(AttributeBuffer);
+ AttributeBuffer = NewAttributeBuffer;
+ Columns = Col;
+ }
+ MemClearScreen();
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetKbLayoutNotifyFn
+//
+// Description:
+// This function stores a pointer to the current keyboard layout
+//
+// Input:
+// IN EFI_EVENT Event - event that caused this function to be called
+// IN VOID *Context - context of the event
+//
+// Output:
+// VOID
+//
+// Modified:
+// gKeyDescriptorList - changed to point to the current EFI_HII_KEYBOARD_LAYOUT
+// or, NULL if no layout currently set
+// LayoutLength - set to the size of the current keyboard layout
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID CSSetKbLayoutNotifyFn(
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ EFI_STATUS Status;
+
+ if(HiiDatabase == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase);
+ if(EFI_ERROR(Status))
+ return;
+ }
+
+ Status = HiiDatabase->GetKeyboardLayout(HiiDatabase, NULL, &KeyDescriptorListSize, gKeyDescriptorList);
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ if(gKeyDescriptorList != NULL)
+ pBS->FreePool(gKeyDescriptorList);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, KeyDescriptorListSize, &gKeyDescriptorList);
+ if(EFI_ERROR(Status)) {
+ KeyDescriptorListSize = 0;
+ gKeyDescriptorList = NULL;
+ } else {
+ HiiDatabase->GetKeyboardLayout(HiiDatabase, NULL, &KeyDescriptorListSize, gKeyDescriptorList);
+ }
+ } else if(Status == EFI_NOT_FOUND) {
+ if(gKeyDescriptorList != NULL) {
+ pBS->FreePool(gKeyDescriptorList);
+ KeyDescriptorListSize = 0;
+ gKeyDescriptorList = NULL;
+ }
+ }
+}
+
+VOID AdjustSupportedModes(
+ VOID
+)
+{
+ DLINK *ListPtr;
+ CON_SPLIT_OUT *SimpleOut;
+ EFI_STATUS Status;
+ INT32 i;
+ UINTN Columns;
+ UINTN Rows;
+
+ ListPtr = ConOutList.pHead;
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+
+//re-initialize supported modes buffer
+ if(MasterMode.MaxMode < SimpleOut->SimpleOut->Mode->MaxMode) {
+ if (SupportedModes != NULL)
+ pBS->FreePool(SupportedModes);
+ Status = pBS->AllocatePool(EfiBootServicesData, SimpleOut->SimpleOut->Mode->MaxMode * sizeof(SUPPORT_RES), &SupportedModes);
+ if(EFI_ERROR(Status))
+ return;
+ }
+ MasterMode.MaxMode = SimpleOut->SimpleOut->Mode->MaxMode;
+ for(i = 0; i < MasterMode.MaxMode; i++) {
+ Status = SimpleOut->SimpleOut->QueryMode(SimpleOut->SimpleOut, i, &Columns, &Rows);
+ SupportedModes[i].Rows = (INT32)Rows;
+ SupportedModes[i].Columns = (INT32)Columns;
+ SupportedModes[i].AllDevices = EFI_ERROR(Status) ? FALSE : TRUE;
+ }
+
+//update supported modes buffer
+ ListPtr = ListPtr->pNext;
+ while(ListPtr != NULL) {
+ SimpleOut = OUTTER(ListPtr, Link, CON_SPLIT_OUT);
+ UpdateModesTable(SimpleOut->SimpleOut, SimpleOut->Handle);
+ ListPtr = ListPtr->pNext;
+ }
+}
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: KeyboardLayoutMap
+//
+// Description:
+// This function maps an EFI_KEY to a Unicode character, based on the current
+// keyboard layout
+//
+// Input:
+// IN AMI_EFI_KEY_DATA *KeyData - pointer to the key data returned by a device
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - key was mapped successfully
+// EFI_NOT_FOUND - the key was not found in the keyboard layout
+// EFI_INVALID_PARAMETER - KeyData is NULL
+//
+// Modified:
+// AMI_EFI_KEY_DATA *KeyData - KeyData->Key.UnicodeChar is changed to match
+// the character found in the keyboard layout
+//
+// Referrals:
+// EFI_HII_KEYBOARD_LAYOUT* gKeyDescriptorList - Pointer to the current
+// keyboard layout
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS KeyboardLayoutMap(
+ IN AMI_MULTI_LANG_SUPPORT_PROTOCOL *This,
+ IN OUT AMI_EFI_KEY_DATA *KeyData)
+{
+ EFI_STATUS Status;
+ EFI_KEY_DESCRIPTOR *KeyDescriptor;
+
+ BOOLEAN AltState = FALSE;
+ BOOLEAN ShiftKeyState = FALSE;
+ BOOLEAN ShiftState = ShiftKeyState;
+
+ static UINT16 ModifierIndex = 0xFFFF;
+ static CHAR16 ModifierUnicodeChar = 0x0000;
+
+ UINT16 i = 0;
+
+ if(gKeyDescriptorList== NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ KeyDescriptor = (EFI_KEY_DESCRIPTOR*)&(gKeyDescriptorList->Descriptors);
+
+ // check alt status (left alt or right alt)
+ if( ((KeyData->KeyState.KeyShiftState)&(RIGHT_ALT_PRESSED|LEFT_ALT_PRESSED)) != 0 )
+ AltState = TRUE;
+
+ if( ((KeyData->KeyState.KeyShiftState)&(RIGHT_SHIFT_PRESSED|LEFT_SHIFT_PRESSED)) != 0 )
+ ShiftKeyState = TRUE;
+
+ Status = EFI_NOT_FOUND;
+ if ( (ModifierIndex != 0xFFFF) && (KeyDescriptor[ModifierIndex].Modifier == EFI_NS_KEY_MODIFIER) ) {
+ // Previous key had a modifier, we need to find out what to do
+ // for now, only handle EFI_NS_KEY_MODIFIER
+ for (i = ModifierIndex+1; KeyDescriptor[i].Modifier == EFI_NS_KEY_DEPENDENCY_MODIFIER && i < gKeyDescriptorList->DescriptorCount; i++) {
+ if(KeyDescriptor[i].Key == KeyData->EfiKey) {
+ if ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_STANDARD_SHIFT) != 0)
+ ShiftState = ShiftKeyState;
+ else
+ ShiftState = FALSE;
+ // account for cAPS lOCK, only applicable if the affected attribute is set
+ if (!AltState && ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_CAPS_LOCK) != 0) && ((KeyData->KeyState.KeyToggleState&CAPS_LOCK_ACTIVE) != 0))
+ ShiftState = !ShiftState;
+
+ if (AltState && ShiftState && (KeyDescriptor[i].ShiftedAltGrUnicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedAltGrUnicode;
+ Status = EFI_SUCCESS;
+ }
+ else if (AltState && !ShiftState && (KeyDescriptor[i].AltGrUnicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].AltGrUnicode;
+ Status = EFI_SUCCESS;
+ }
+ else if (!AltState && ShiftState && (KeyDescriptor[i].ShiftedUnicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedUnicode;
+ Status = EFI_SUCCESS;
+ }
+ else if (!AltState && !ShiftState && (KeyDescriptor[i].Unicode != 0x0000)) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].Unicode;
+ Status = EFI_SUCCESS;
+ }
+ break;
+ }
+ }
+
+ if (EFI_ERROR(Status))
+ // No match found, just return the deadkey's character
+ KeyData->Key.UnicodeChar = ModifierUnicodeChar;
+ ModifierIndex = 0xFFFF;
+ ModifierUnicodeChar = 0x0000;
+ return EFI_SUCCESS;
+ }
+
+ // Search the KeyDescriptorList for a matching key
+ for(i = 0; i < gKeyDescriptorList->DescriptorCount; i++)
+ {
+ if(KeyDescriptor[i].Key == KeyData->EfiKey || (KeyDescriptor[i].Key == 0xA5A5 && KeyData->PS2ScanCode == 0x73)) {
+ if ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_STANDARD_SHIFT) != 0)
+ ShiftState = ShiftKeyState;
+ else
+ ShiftState = FALSE;
+ // account for cAPS lOCK, only applicable if the affected attribute is set
+ if (!AltState && ((KeyDescriptor[i].AffectedAttribute&EFI_AFFECTED_BY_CAPS_LOCK) != 0) && ((KeyData->KeyState.KeyToggleState&CAPS_LOCK_ACTIVE) != 0))
+ ShiftState = !ShiftState;
+
+ switch (KeyDescriptor[i].Modifier) {
+ case EFI_NULL_MODIFIER:
+ Status = EFI_SUCCESS;
+ if (AltState && ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedAltGrUnicode;
+ }
+ else if (AltState && !ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].AltGrUnicode;
+ }
+ else if (!AltState && ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].ShiftedUnicode;
+ }
+ else if (!AltState && !ShiftState) {
+ KeyData->Key.UnicodeChar = KeyDescriptor[i].Unicode;
+ }
+ break;
+ case EFI_NS_KEY_MODIFIER:
+ Status = EFI_SUCCESS;
+ if (AltState && ShiftState && (KeyDescriptor[i].ShiftedAltGrUnicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].ShiftedAltGrUnicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ else if (AltState && !ShiftState && (KeyDescriptor[i].AltGrUnicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].AltGrUnicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ else if (!AltState && ShiftState && (KeyDescriptor[i].ShiftedUnicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].ShiftedUnicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ else if (!AltState && !ShiftState && (KeyDescriptor[i].Unicode != 0x0000)) {
+ ModifierIndex = i;
+ ModifierUnicodeChar = KeyDescriptor[i].Unicode;
+ KeyData->Key.UnicodeChar = 0x0000; // don't return a character yet, the next keypress will determine the correct character
+ }
+ default:
+ case EFI_NS_KEY_DEPENDENCY_MODIFIER:
+ // skip deadkey-dependent modifiers and unknown modifiers
+ break;
+ } // switch (KeyDescriptor[i].Modifier)
+
+ if (!EFI_ERROR(Status) && (KeyData->Key.UnicodeChar != 0x0000 || ModifierUnicodeChar != 0x0000))
+ break; // successfully mapped a key, break for(...) loop
+ }
+ }
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/ConSplitter/ConSplit.h b/Core/CORE_DXE/ConSplitter/ConSplit.h
new file mode 100644
index 0000000..f64cad5
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplit.h
@@ -0,0 +1,553 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.h 4 8/02/13 4:27a Thomaschen $
+//
+// $Revision: 4 $
+//
+// $Date: 8/02/13 4:27a $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/ConSplit.h $
+//
+// 4 8/02/13 4:27a Thomaschen
+// Add for EIP109384.
+// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c.
+//
+// 3 6/26/13 3:10a Thomaschen
+// Remove EIP109384.
+//
+// 1 6/04/13 1:53a Thomaschen
+// Fixed for EIP118202.
+//
+// 16 10/25/12 2:32a Deepthins
+// [TAG] EIP99475
+// [Category] Improvement
+// [Description] Multi language module Support in the console splitter
+// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h
+//
+// 15 8/02/12 12:14p Artems
+// [TAG] EIP95607
+// [Category] Bug Fix
+// [Symptom] Execute nsh script and redirect output to file, then exit
+// from shell, setup screen will crash
+// [RootCause] Console splitter maintains global pool of supported
+// modes.
+// It's getting adjusted every time new SimpleTextOut (STO) is installed
+// If new STO doesn't support particular mode it is getting marked as
+// unsupported in global pool
+// However once this STO is uninstalled global pool isn't updated, so mode
+// is still marked as unsupported,
+// though system can support it
+// [Solution] Added reinitilization of global pool of supported modes on
+// STO uninstall event
+// [Files] Consplit.h Consplit.c
+//
+// 14 8/12/11 12:17p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 13 5/05/11 3:52p Artems
+// Added multi-language keyboard support
+//
+// 12 6/23/10 3:02p Felixp
+// SimplePointer splitter support is added.
+//
+// 11 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 10 9/17/07 4:04p Olegi
+// Added support for AMI_EFIKEYCODE_PROTOCOL and
+// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+//
+// 9 9/05/07 11:13a Felixp
+// SimpleTextInEx support removed. It causes problems. Support will add
+// again after Core labeling.
+//
+// 8 9/04/07 2:55p Olegi
+// Added EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL support.
+//
+// 7 1/05/07 4:23p Artems
+//
+// 6 12/29/06 3:01p Felixp
+// 1. Support for GraphicsOutput protocol added
+// 2. Support for more then one text mode added
+//
+// 5 9/27/06 7:42p Felixp
+// SetMode funciton of the ConsoleControl protocol is updated to restore
+// default UGA mode when switching from grphics to text.
+//
+// 4 3/13/06 2:37a Felixp
+//
+// 3 12/12/05 9:32a Felixp
+// Support for synchronization of console devices
+// (now screen is restored after legacy OpROM execution).
+//
+// 2 11/07/05 10:37a Felixp
+// LockStdIn function of ConsoleControl protocol implemented
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 3 1/04/05 5:15p Robert
+// Changed component name to be more consistent with the other drivers
+// that have been developed
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ConSplit.h
+//
+// Description: This file contains the structure and function prototypes needed
+// for the Console Splitter driver
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+#ifndef __CONSOLE_SPLITTER_H__
+#define __CONSOLE_SPLITTER_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//--------------------------------------------------------------------------------
+
+#include <EFI.h>
+#include <Protocol\SimpleTextOut.h >
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\amikeycode.h>
+#include <Protocol\SimplePointer.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\ComponentName2.h>
+#include <AmiDxeLib.h>
+
+//--------------------------------------------------------------------------------
+
+#pragma pack (1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_SIMPLE_POINTER
+//
+// Description:
+// This structure represents Splitter Simple Pointer devices linked list.
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Link DLINK Linked list pointer
+// SimplePointer EFI_SIMPLE_POINTER_PROTOCOL* Protocol pointer
+// Handle EFI_HANDLE Device handle
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT_SIMPLE_POINTER {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePointer;
+ EFI_HANDLE Handle;
+} CON_SPLIT_SIMPLE_POINTER;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_OUT
+//
+// Description:
+// This structure represents Splitter ConOut devices linked list
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Link DLINK Linked list pointer
+// SimpleOut EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL* Protocol pointer
+// Handle EFI_HANDLE Device handle
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT_OUT
+ {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut;
+ EFI_HANDLE Handle;
+ } CON_SPLIT_OUT;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_IN_KEY_NOTIFY
+//
+// Description:
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_KEY_DATA KeyData;
+ EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction;
+ DLIST NotifyHandleList;
+} CON_SPLIT_IN_KEY_NOTIFY;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_IN_KEY_NOTIFY
+//
+// Description:
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx;
+ EFI_HANDLE NotifyHandle;
+} CON_SPLIT_IN_KEY_NOTIFY_HANDLE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT_IN
+//
+// Description:
+// This structure represents Splitter ConIn devices linked list
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Link DLINK Linked list pointer
+// SimpleIn EFI_SIMPLE_TEXT_INPUT_PROTOCOL* Protocol pointer
+// SimpleInEx EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL* Protocol pointer
+// KeycodeInEx AMI_EFIKEYCODE_PROTOCOL* Protocol pointer
+// Handle EFI_HANDLE Device handle
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT_IN
+ {
+ DLINK Link; //MUST BE THE FIRST FIELD
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *SimpleInEx;
+ AMI_EFIKEYCODE_PROTOCOL *KeycodeInEx;
+ EFI_HANDLE Handle;
+ } CON_SPLIT_IN;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CON_SPLIT
+//
+// Description:
+// This structure represents Splitter devices structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Input CON_SPLIT_IN Input devices linked list
+// Output CON_SPLIT_OUT Output devices linked list
+// StdErr CON_SPLIT_OUT Error output devices linked list
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CON_SPLIT
+ {
+ CON_SPLIT_IN Input;
+ CON_SPLIT_OUT Output;
+ CON_SPLIT_OUT StdErr;
+ } CON_SPLIT;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SUPPORT_RES
+//
+// Description:
+// This structure represents Splitter supported resolutions database
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Columns INT32 Max number of text columns
+// Rows INT32 Max number of text rows
+// AllDevices BOOLEAN Flag if all devices support given resolution
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct __SUPPORT_RES
+ {
+ INT32 Columns;
+ INT32 Rows;
+ BOOLEAN AllDevices;
+ } SUPPORT_RES;
+
+#pragma pack()
+
+//-----------------------------------------------------------------------------------
+
+SUPPORT_RES *SupportedModes;
+
+//virtual splitter output buffer
+CHAR16 *ScreenBuffer;
+CHAR16 *EndOfTheScreen;
+INT32 *AttributeBuffer;
+INT32 Columns;
+
+extern SIMPLE_TEXT_OUTPUT_MODE MasterMode;
+extern EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mCSOutProtocol;
+extern EFI_SIMPLE_TEXT_INPUT_PROTOCOL mCSSimpleInProtocol;
+extern EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL mCSSimpleInExProtocol;
+extern AMI_EFIKEYCODE_PROTOCOL mCSKeycodeInProtocol;
+extern DLIST ConInList;
+extern DLIST ConOutList;
+extern DLIST ConPointerList;
+extern DLIST ConInKeyNotifyList;
+extern BOOLEAN StdInLocked;
+extern EFI_SIMPLE_POINTER_PROTOCOL mCSSimplePointerProtocol;
+
+//-----------------------------------------------------------------------------------
+
+EFI_STATUS ConSplitterSimplePointerReset(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification );
+
+EFI_STATUS ConSplitterSimplePointerGetState(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State );
+
+VOID ConSplitterSimplePointerWaitForInput(
+ IN EFI_EVENT Event,
+ IN VOID *Context );
+
+EFI_STATUS CSSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS CSStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS CSStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+EFI_STATUS CSReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+EFI_STATUS CSOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ );
+
+EFI_STATUS CSTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+ );
+
+EFI_STATUS CSQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row
+ );
+
+EFI_STATUS CSSetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum
+ );
+
+EFI_STATUS CSSetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+ );
+
+EFI_STATUS CSClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+ );
+
+EFI_STATUS CSSetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ );
+
+EFI_STATUS CSEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible
+ );
+
+EFI_STATUS CSInReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+ );
+
+EFI_STATUS CSReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+VOID CSWaitForKey(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS CSInResetEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN EV
+ );
+
+EFI_STATUS CSReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ );
+
+EFI_STATUS
+CSReadEfiKey (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+ );
+
+EFI_STATUS CSInSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+);
+
+EFI_STATUS CSInRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS CSInUnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+VOID RestoreTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut
+ );
+
+VOID SaveTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut
+ );
+
+EFI_STATUS MemClearScreen(
+ VOID
+ );
+
+VOID SaveUgaMode(
+ IN EFI_HANDLE ControllerHandle
+ );
+
+VOID RestoreUgaMode(
+ IN EFI_HANDLE ControllerHandle
+ );
+
+EFI_STATUS InitModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+ );
+
+VOID UpdateModesTable(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN EFI_HANDLE Handle
+ );
+
+EFI_STATUS IsModeSupported(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT INT32 *DeviceModeNumber
+ );
+
+EFI_STATUS ResizeSplitterBuffer(
+ IN INT32 ModeNum
+ );
+
+VOID UpdateMasterMode(
+ IN SIMPLE_TEXT_OUTPUT_MODE *Mode
+ );
+
+EFI_STATUS CSInKeyboardLayoutMap(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+ );
+
+VOID AdjustSupportedModes(
+ VOID
+ );
+
+EFI_STATUS KeyboardLayoutMap(
+ IN AMI_MULTI_LANG_SUPPORT_PROTOCOL *This,
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+ );
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/ConSplitter/ConSplitter.cif b/Core/CORE_DXE/ConSplitter/ConSplitter.cif
new file mode 100644
index 0000000..ff3fc94
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplitter.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "ConSplitter"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\ConSplitter\"
+ RefName = "ConSplitter"
+[files]
+"\ConSplitter.sdl"
+"\ConSplit.c"
+"\ConSplit.h"
+"\Out.c"
+"\In.c"
+<endComponent>
diff --git a/Core/CORE_DXE/ConSplitter/ConSplitter.sdl b/Core/CORE_DXE/ConSplitter/ConSplitter.sdl
new file mode 100644
index 0000000..730b34e
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/ConSplitter.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "PAUSEKEY_SUPPORT"
+ Value = "0"
+ Help = "Pause key support. ON - Pause key causes pause during POST. OFF - Pause key ignored."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REPORT_NO_CON_OUT_ERROR"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REPORT_NO_CON_IN_ERROR"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "CONSOLE_SPLITTER_DIR"
+End
+
diff --git a/Core/CORE_DXE/ConSplitter/In.c b/Core/CORE_DXE/ConSplitter/In.c
new file mode 100644
index 0000000..9d8d561
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/In.c
@@ -0,0 +1,1159 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/In.c 5 7/08/15 4:32a Chienhsieh $
+//
+// $Revision: 5 $
+//
+// $Date: 7/08/15 4:32a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/ConSplitter/In.c $
+//
+// 5 7/08/15 4:32a Chienhsieh
+// Update for eip217417.
+//
+// 4 8/02/13 4:26a Thomaschen
+// Add for EIP109384.
+// [Files] ConSplit.c, ConSplit.h, In.c, CsmSimpleIn.c.
+//
+// 3 6/26/13 3:11a Thomaschen
+// Remove EIP109384.
+//
+// 1 6/04/13 1:52a Thomaschen
+// Fixed for EIP118202.
+//
+// 32 10/25/12 2:33a Deepthins
+// [TAG] EIP99475
+// [Category] Improvement
+// [Description] Multi language module Support in the console splitter
+//
+// [Files] ConSplit.c, ConSplit.h , In.c and AmiKeycode.h
+//
+// 31 7/20/12 10:38a Artems
+// [TAG] EIP93929
+// [Description] Implement support to initialize the Keyboard in first
+// call of readkeystoke in fast boot case
+// [Files] In.c
+//
+// 30 4/11/12 5:35p Artems
+// [TAG] EIPN/A
+// [Category] Bug Fix
+// [Symptom] Function SetState was not broadcasted to third party
+// drivers
+// [RootCause] Splitter uses AMI proprietary protocol to broadcast
+// SetState function
+// which is not installed by third party drivers
+// [Solution] Modified splitter to broadcast SetState function via
+// SimpleTextInEx protocol
+// [Files] in.c
+//
+// 29 3/21/12 12:53p Artems
+// EIP 83358: Fixed bug in SimplePointerGetState function, where
+// EFI_SUCCESS was lost if ohter device returns DEVICE_ERROR
+//
+// 28 9/22/11 6:29a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h
+//
+// 27 7/21/11 3:41p Aaronp
+// // [TAG] EIP65187
+// // [Category] Bug Fix
+// // [Severity] Minor
+// // [Symptom] unicode character was not returned when english selected
+// // and alt key pressed
+// // [RootCause] The EFI_HII_KEYBOARD_LAYOUT table provides the
+// AltGraphic
+// // and Shifted AltGraphic unicode definitions for key combinations, and
+// // there are NULL values for undefined key combinations.
+// // [Solution] Changed how the EFI_HII_KEYBOARD_LAYOUT table is
+// consumed
+// // so that the current unicode character in the AMI_EFI_KEY_DATA
+// structure
+// // will not be overwritten when the EFI_HII_KEYBOARD_LAYOUT has a NULL
+// // value in the matching table entry.
+// // [Files] In.c
+//
+// 25 5/05/11 4:53p Artems
+// Removed unnecessary checks
+//
+// 24 5/05/11 3:54p Artems
+// Added multi-language keyboard support
+//
+// 23 8/10/10 2:29p Vyacheslava
+// Initialized default value of Status in the
+// ConSplitterSimplePointerReset function.
+//
+// 22 6/23/10 3:02p Felixp
+// SimplePointer splitter support is added.
+//
+// 21 1/18/10 3:40a Rameshr
+// NumLock,Capslock,Scroll Lock LED's synced properly between Keyboard
+// connect and disconnect.
+// EIP 27917
+//
+// 20 10/09/09 12:15p Felixp
+// SetState function is updated to process all the physical devices
+// despite the errors returned by some of them.
+//
+// 19 8/13/09 3:04p Rameshr
+// When item "num-lock status" set off, Num-lock will keep open until in
+// DOS.
+// EIP:21757
+//
+// 18 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 17 4/30/09 5:45p Felixp
+// Minor improvements on the pause key implementation.
+//
+// 16 3/30/09 10:24a Pats
+// Issue: EIP 19547 - Pause key support needed in Aptio
+// Solution: Function CsReadEfiKey modified to enter pause loop when pause
+// key detected. Requires mod in Ps2Kbd.c and efiusbkb.c.
+//
+// 15 1/23/09 9:55a Rameshr
+// Symptom:SCT failure in ReadKeystrokeEx function.
+// Solution: Validated the Input parameters Keydata for the
+// ReadKeystrokeEx Function.
+// Eip: 19039
+//
+// 14 11/17/08 10:22a Rameshraju
+// Problem:SCT failure on RegisterKeyNotify, SetState and
+// UnregisterKeyNotify.
+// Fix : Validated the input parameters for RegisterKeyNotify, SetState
+// and UnregisterKeyNotify.
+// EIP:17578
+//
+// 13 10/08/08 4:27p Olegi
+// Implemented the Register/Unregister key notofocation function in
+// SimpletextinEx protocol.
+//
+// 12 3/17/08 4:49p Rameshraju
+// ReadEfiKey doesnt not return correct key value randomly.
+//
+// 11 1/31/08 12:00p Olegi
+// Numlock bootup state made setup driven.
+//
+// 10 11/16/07 4:05p Olegi
+// Modifications in CSReadKeyStroke function.
+//
+// 9 10/23/07 4:14p Olegi
+// Modifications in CSInSetState that allow the sync between the Input
+// Devices' LEDs.
+//
+// 8 10/16/07 10:47a Olegi
+// Modification in CSReadEfiKey().
+//
+// 7 9/17/07 4:04p Olegi
+// Added support for AMI_EFIKEYCODE_PROTOCOL and
+// EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL.
+//
+// 6 9/05/07 11:13a Felixp
+// SimpleTextInEx support removed. It causes problems. Support will add
+// again after Core labeling.
+//
+// 3 3/13/06 2:37a Felixp
+//
+// 2 11/07/05 10:37a Felixp
+// LockStdIn function of ConsoleControl protocol implemented
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Out.c
+//
+// Description: File contains the Simple Text Output functionality for the
+// Console Splitter Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+
+#include "ConSplit.h"
+#include "token.h"
+#include <Protocol/SimplePointer.h>
+
+//----------------------------------------------------------------------------
+extern EFI_HII_KEYBOARD_LAYOUT *gKeyDescriptorList;
+extern EFI_KEY_TOGGLE_STATE mCSToggleState;
+EFI_SIMPLE_POINTER_MODE gSimplePointerMode = {
+ 0x10000,
+ 0x10000,
+ 0x10000,
+ FALSE,
+ FALSE
+};
+
+VOID ConnectInputDevices(
+ VOID
+);
+
+//----------------------------------------------------------------------------
+
+EFI_SIMPLE_TEXT_INPUT_PROTOCOL mCSSimpleInProtocol = {
+ CSInReset,
+ CSReadKeyStroke,
+ NULL
+ } ;
+
+EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL mCSSimpleInExProtocol = {
+ CSInResetEx,
+ CSReadKeyStrokeEx,
+ NULL,
+ CSInSetState,
+ CSInRegisterKeyNotify,
+ CSInUnRegisterKeyNotify
+ } ;
+
+AMI_EFIKEYCODE_PROTOCOL mCSKeycodeInProtocol = {
+ CSInResetEx,
+ CSReadEfiKey,
+ NULL,
+ CSInSetState,
+ CSInRegisterKeyNotify,
+ CSInUnRegisterKeyNotify
+ } ;
+
+EFI_SIMPLE_POINTER_PROTOCOL mCSSimplePointerProtocol = {
+ ConSplitterSimplePointerReset,
+ ConSplitterSimplePointerGetState,
+ ConSplitterSimplePointerWaitForInput,
+ &gSimplePointerMode
+};
+
+//----------------------------------------------------------------------------
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSplitterSimplePointerReset
+//
+// Description: Resets the pointer device hardware.
+//
+// Input:
+// *This - pointer to protocol instance.
+// ExtendedVerification - Driver may perform diagnostics on reset.
+//
+// Output:
+// EFI_SUCCESS - device was reset successfully
+// EFI_ERROR - some of devices returned error
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConSplitterSimplePointerReset (
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS TestStatus;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+
+ if (StdInLocked)
+ return EFI_ACCESS_DENIED;
+
+ if (ConPointerList.pHead == NULL)
+ return EFI_DEVICE_ERROR;
+
+ ConSimplePointer = OUTTER(ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER);
+
+ // we need to loop through all the registered simple pointer devices
+ // and call each of their Reset function
+ while (ConSimplePointer != NULL) {
+ TestStatus = ConSimplePointer->SimplePointer->Reset(ConSimplePointer->SimplePointer, ExtendedVerification);
+ ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ return Status;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSplitterSimplePointerGetState
+//
+// Description: Retrieves the current state of a pointer device.
+// Reads the next keystroke from the input device. The WaitForKey Event can
+// be used to test for existance of a keystroke via WaitForEvent () call.
+// If the ConIn is password locked make it look like no keystroke is availible
+//
+// Input:
+// This - Protocol instance pointer.
+// State - A pointer to the state information on the pointer device.
+//
+// Output:
+// EFI_SUCCESS - The keystroke information was returned.
+// EFI_NOT_READY - There was no keystroke data availiable.
+// EFI_DEVICE_ERROR - The keydtroke information was not returned due to
+// hardware errors.
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ConSplitterSimplePointerGetState(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN OUT EFI_SIMPLE_POINTER_STATE *State )
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_POINTER_STATE CurrentState;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+ BOOLEAN EfiSuccessDetected = FALSE;
+ BOOLEAN EfiDeviceErrorDetected = FALSE;
+ BOOLEAN EfiNotReadyDetected = FALSE;
+
+ if (StdInLocked)
+ return EFI_ACCESS_DENIED;
+
+ if (ConPointerList.pHead == NULL)
+ return EFI_DEVICE_ERROR;
+
+ ConSimplePointer = OUTTER( ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ State->RelativeMovementX = 0;
+ State->RelativeMovementY = 0;
+ State->RelativeMovementZ = 0;
+ State->LeftButton = FALSE;
+ State->RightButton = FALSE;
+
+ // we need to loop through all the registered simple pointer devices
+ while (ConSimplePointer != NULL) {
+
+ Status = ConSimplePointer->SimplePointer->GetState(ConSimplePointer->SimplePointer, &CurrentState);
+
+ if (!EFI_ERROR(Status)) {
+
+ EfiSuccessDetected = TRUE;
+
+ if (CurrentState.LeftButton)
+ State->LeftButton = TRUE;
+
+ if (CurrentState.RightButton)
+ State->RightButton = TRUE;
+
+ if ( CurrentState.RelativeMovementX != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionX != 0 )
+ State->RelativeMovementX +=
+ (CurrentState.RelativeMovementX * (INT32)gSimplePointerMode.ResolutionX) /
+ (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionX;
+
+ if ( CurrentState.RelativeMovementY != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionY != 0 )
+ State->RelativeMovementY +=
+ (CurrentState.RelativeMovementY * (INT32)gSimplePointerMode.ResolutionY) /
+ (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionY;
+
+ if ( CurrentState.RelativeMovementZ != 0 && ConSimplePointer->SimplePointer->Mode->ResolutionZ != 0 )
+ State->RelativeMovementZ +=
+ (CurrentState.RelativeMovementZ * (INT32)gSimplePointerMode.ResolutionZ) /
+ (INT32)ConSimplePointer->SimplePointer->Mode->ResolutionZ;
+
+ } else if (Status == EFI_DEVICE_ERROR) {
+ EfiDeviceErrorDetected = TRUE;
+ } else {
+ EfiNotReadyDetected = TRUE;
+ }
+
+ ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER );
+ }
+
+ return (EfiSuccessDetected) ? EFI_SUCCESS : (EfiDeviceErrorDetected) ? EFI_DEVICE_ERROR : EFI_NOT_READY;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConSplitterSimplePointerWaitForInput
+//
+// Description: This is callback function for WaitForInputEvent to use with
+// WaitForEvent() to wait for input from the pointer device.
+//
+// Input:
+// Event - The Event assoicated with callback.
+// Context - Context registered when Event was created.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ConSplitterSimplePointerWaitForInput(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS TestStatus;
+ CON_SPLIT_SIMPLE_POINTER *ConSimplePointer = NULL;
+
+ if (StdInLocked)
+ return;
+
+ if (ConPointerList.pHead == NULL)
+ return;
+
+ ConSimplePointer = OUTTER( ConPointerList.pHead, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ // loop through simple pointer events and check their events
+ // if one event has been signaled, signal my event and exit.
+ // we need to loop through all the registered simple pointer devices
+ while (ConSimplePointer != NULL) {
+ TestStatus = pBS->CheckEvent(ConSimplePointer->SimplePointer->WaitForInput);
+ ConSimplePointer = OUTTER( ConSimplePointer->Link.pNext, Link, CON_SPLIT_SIMPLE_POINTER );
+
+ if (!EFI_ERROR(TestStatus))
+ pBS->SignalEvent(Event);
+ }
+
+ return;
+}
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInReset
+//
+// Description:
+// This function resets the input device hardware. This routine is a part
+// of SimpleTextIn protocol implementation.
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN EV - flag if Extended verification has to be performed
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device was reset successfully
+// EFI_ERROR - some of devices returned error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (ConInList.pHead == NULL)
+ return EFI_SUCCESS;
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their Reset function
+ while ( SimpleIn != NULL)
+ {
+ TestStatus = SimpleIn->SimpleIn->Reset(SimpleIn->SimpleIn, EV);
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ return Status;
+
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReadKeyStroke
+//
+// Description:
+// This function reads the next keystroke from the input device. This
+// routine is a part of SimpleTextIn protocol implementation
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This - pointer to protocol instance
+// OUT EFI_INPUT_KEY *Key - key pressed information
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_NOT_READY - There was no keystroke data available
+// EFI_DEVICE_ERROR - The keystroke information was not returned
+// due to hardware error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReadKeyStroke(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+)
+{
+ EFI_STATUS Status;
+ AMI_EFI_KEY_DATA EfiKeyData;
+
+ Status = CSReadEfiKey ( (AMI_EFIKEYCODE_PROTOCOL*) This, &EfiKeyData );
+ if (Status == EFI_SUCCESS) {
+ //
+ // Check for the Partial Key. If found, SimpleTextIn ReadKeyStroke
+ // Should not return that Key has bee found.
+ //
+ if(EfiKeyData.Key.ScanCode == 00 && EfiKeyData.Key.UnicodeChar == 0 &&
+ (EfiKeyData.KeyState.KeyToggleState & KEY_STATE_EXPOSED )) {
+ return EFI_NOT_READY;
+ }
+ *Key = EfiKeyData.Key;
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSWaitForKey
+//
+// Description:
+// This function is a callback for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey event
+// Checks whether the new key is available and if so - signals the event
+//
+// Input:
+// IN EFI_EVENT Event - event to signal
+// IN VOID *Context - pointer to event specific context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID CSWaitForKey(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return ;
+ if (ConInList.pHead == NULL) return;
+
+// loop through simple in events and check their events
+// if one event has been signaled, signal my event and exit
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their Reset function
+ while ( SimpleIn != NULL)
+ {
+ TestStatus = pBS->CheckEvent(SimpleIn->SimpleIn->WaitForKey);
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+
+ if (!EFI_ERROR(TestStatus))
+ pBS->SignalEvent (Event);
+ }
+
+ return;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInResetEx
+//
+// Description:
+// This function resets the input device hardware. This routine is a part
+// of SimpleTextInEx protocol implementation
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN ExtendedVerification - flag if Extended verification has to be performed
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device was reset successfully
+// EFI_ERROR - some of devices returned error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInResetEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ return CSInReset(0, ExtendedVerification);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReadKeyStrokeEx
+//
+// Description:
+// This function reads the next keystroke from the input device. This
+// routine is a part of SimpleTextInEx protocol implementation
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// OUT EFI_KEY_DATA *KeyData - key pressed information
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_NOT_READY - There was no keystroke data available
+// EFI_DEVICE_ERROR - The keystroke information was not returned
+// due to hardware error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ AMI_EFI_KEY_DATA EfiKeyData;
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = CSReadEfiKey ( (AMI_EFIKEYCODE_PROTOCOL*) This, &EfiKeyData );
+ if (Status == EFI_SUCCESS) {
+ KeyData->Key = EfiKeyData.Key;
+ KeyData->KeyState = EfiKeyData.KeyState;
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReadEfiKey
+//
+// Description:
+// This function reads the next keystroke from the input device. This
+// routine is a part of AmiKeyCode protocol implementation
+//
+// Input:
+// IN AMI_EFIKEYCODE_PROTOCOL *This - pointer to protocol instance
+// OUT AMI_EFI_KEY_DATA *KeyData - key pressed information
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_NOT_READY - There was no keystroke data available
+// EFI_DEVICE_ERROR - The keystroke information was not returned
+// due to hardware error
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReadEfiKey (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ AMI_EFI_KEY_DATA TempKey;
+ EFI_STATUS Status = EFI_NOT_READY;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ ConnectInputDevices();
+
+ if (ConInList.pHead == NULL) return EFI_NOT_READY;
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ pBS->SetMem(KeyData, sizeof(AMI_EFI_KEY_DATA), 0);
+
+ // we need to loop through all the registered EfiKey, SimpleInEx and
+ // SimpleIn devices and call each of their ReadKeyStroke function
+ while (SimpleIn != NULL)
+ {
+ if (SimpleIn->KeycodeInEx) {
+ Status = SimpleIn->KeycodeInEx->ReadEfikey(SimpleIn->KeycodeInEx, &TempKey);
+ } else if(SimpleIn->SimpleInEx != NULL) {
+ Status = SimpleIn->SimpleInEx->ReadKeyStrokeEx(
+ SimpleIn->SimpleInEx, (EFI_KEY_DATA*)&TempKey);
+ } else if(SimpleIn->SimpleIn != NULL) {
+ Status = SimpleIn->SimpleIn->ReadKeyStroke(
+ SimpleIn->SimpleIn, (EFI_INPUT_KEY*)&TempKey);
+ }
+
+ // Check for the Toggle State change
+ if (!EFI_ERROR(Status) && (TempKey.KeyState.KeyToggleState & TOGGLE_STATE_VALID)) {
+ if ((TempKey.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED ) != mCSToggleState) {
+ mCSToggleState = (TempKey.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED);
+ CSInSetState ( (EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL*) This,
+ &mCSToggleState );
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ *KeyData = TempKey;
+ break;
+ }
+
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+ }
+#if PAUSEKEY_SUPPORT
+ if (!EFI_ERROR(Status) && TempKey.EfiKey == EfiKeyPause) {
+ while(TRUE) {
+ Status = CSReadEfiKey ( This, &TempKey );
+ if ((!EFI_ERROR(Status)) && (TempKey.EfiKey != EfiKeyPause) && (TempKey.EfiKey != 0x55)) {
+ break;
+ }
+ }
+ *KeyData = TempKey;
+ }
+#endif
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInSetState
+//
+// Description:
+// This function sets certain state for input device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN EFI_KEY_TOGGLE_STATE *KeyToggleState - pointer to state to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Keystroke data successfully retrieved
+// EFI_UNSUPPORTED - Given state not supported
+// EFI_INVALID_PARAMETER - KeyToggleState is NULL
+// EFI_DEVICE_ERROR - input device not found
+// EFI_ACCESS_DENIED - input device is busy
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ CON_SPLIT_IN *SimpleIn;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (ConInList.pHead == NULL)
+ return EFI_UNSUPPORTED;
+
+ if(KeyToggleState == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(*KeyToggleState & TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED |
+ SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ mCSToggleState = *KeyToggleState; // Update global toggle state
+
+ SimpleIn = OUTTER(ConInList.pHead, Link, CON_SPLIT_IN);
+
+ // we need to loop through all the registered KeycodeInEx devices
+ // and call each of their SetState function
+ while ( SimpleIn != NULL )
+ {
+ if (SimpleIn->SimpleInEx) {
+ SimpleIn->SimpleInEx->SetState(SimpleIn->SimpleInEx, KeyToggleState);
+ }
+ SimpleIn = OUTTER(SimpleIn->Link.pNext, Link, CON_SPLIT_IN);
+ }
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInKeyNotificationFunction
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+CSInKeyNotificationFunction(
+ IN EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DLINK *ListPtr;
+ UINTN Index = 0;
+ UINTN Count = 0;
+ EFI_KEY_NOTIFY_FUNCTION *NotifyFunctionList = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (ConInKeyNotifyList.pHead == NULL) return EFI_DEVICE_ERROR;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ ConInKeyNotifyList.Size * sizeof(EFI_KEY_NOTIFY_FUNCTION),
+ (VOID**)&NotifyFunctionList);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ if (!MemCmp(&(CsInKeyNotify->KeyData), KeyData, sizeof(CsInKeyNotify->KeyData))) {
+ NotifyFunctionList[Count++] = CsInKeyNotify->KeyNotificationFunction;
+ }
+ }
+
+ for (Index = 0; Index < Count; Index++) {
+ NotifyFunctionList[Index](&(CsInKeyNotify->KeyData));
+ }
+
+ pBS->FreePool(NotifyFunctionList);
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInRegisterKeyNotify
+//
+// Description:
+// This function registers a notification function for a particular
+// keystroke of the input device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN EFI_KEY_DATA *KeyData - key value
+// IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction - notification function
+// OUT EFI_HANDLE *NotifyHandle - returned registered handle
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - notification function registered successfully
+// EFI_INVALID_PARAMETER - KeyData/KeyNotificationFunction/NotifyHandle is NULL
+// EFI_DEVICE_ERROR - input device not found
+// EFI_ACCESS_DENIED - input device is busy
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DLINK *ListPtr = NULL;
+ CON_SPLIT_IN *ConIn = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if(KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ if ((!MemCmp(&CsInKeyNotify->KeyData, KeyData, sizeof(CsInKeyNotify->KeyData))) &&
+ (CsInKeyNotify->KeyNotificationFunction == KeyNotificationFunction)) {
+ *NotifyHandle = (EFI_HANDLE)&(CsInKeyNotify->Link);
+ return EFI_SUCCESS;
+ }
+
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CON_SPLIT_IN_KEY_NOTIFY), &CsInKeyNotify);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MemCpy(&(CsInKeyNotify->KeyData), KeyData, sizeof(CsInKeyNotify->KeyData));
+ CsInKeyNotify->KeyNotificationFunction = KeyNotificationFunction;
+ DListAdd(&ConInKeyNotifyList, &(CsInKeyNotify->Link));
+ DListInit(&(CsInKeyNotify->NotifyHandleList));
+ // we need to loop through all the registered SimpleInEx
+ // and call each of their ReadKeyStroke function
+ for (ListPtr = ConInList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ ConIn = OUTTER(ListPtr, Link, CON_SPLIT_IN);
+
+ if (ConIn->SimpleInEx == NULL) {
+ continue;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(CON_SPLIT_IN_KEY_NOTIFY_HANDLE), &CsInNotifyHandle);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ CsInNotifyHandle->SimpleInEx = ConIn->SimpleInEx;
+ DListAdd(&(CsInKeyNotify->NotifyHandleList), &(CsInNotifyHandle->Link));
+
+ Status = ConIn->SimpleInEx->RegisterKeyNotify(ConIn->SimpleInEx,
+ KeyData, CSInKeyNotificationFunction, &(CsInNotifyHandle->NotifyHandle));
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ for (ListPtr = CsInKeyNotify->NotifyHandleList.pHead;
+ ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInNotifyHandle = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE);
+
+ CsInNotifyHandle->SimpleInEx->UnregisterKeyNotify(
+ CsInNotifyHandle->SimpleInEx, CsInNotifyHandle->NotifyHandle);
+
+ DListDelete(&(CsInKeyNotify->NotifyHandleList), ListPtr);
+ pBS->FreePool(CsInNotifyHandle);
+ }
+
+ pBS->FreePool(CsInKeyNotify);
+
+ return Status;
+ }
+
+ *NotifyHandle = (EFI_HANDLE)&(CsInKeyNotify->Link);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSInUnRegisterKeyNotify
+//
+// Description:
+// This function unregisters a notification function with given handle
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This - pointer to protocol instance
+// IN EFI_HANDLE NotificationHandle - handle to unregister
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - notification function unregistered successfully
+// EFI_INVALID_PARAMETER - NotificationHandle is NULL
+// EFI_DEVICE_ERROR - input device not found
+// EFI_ACCESS_DENIED - input device is busy
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSInUnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DLINK *ListPtr = NULL;
+ DLINK *HandleLink = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY *CsInKeyNotify = NULL;
+ CON_SPLIT_IN_KEY_NOTIFY_HANDLE *CsInNotifyHandle = NULL;
+
+ if (StdInLocked) return EFI_ACCESS_DENIED;
+
+ if (NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (ListPtr = ConInKeyNotifyList.pHead; ListPtr != NULL; ListPtr = ListPtr->pNext) {
+ CsInKeyNotify = OUTTER(ListPtr, Link, CON_SPLIT_IN_KEY_NOTIFY);
+
+ if (NotificationHandle == (EFI_HANDLE)&(CsInKeyNotify->Link)) {
+ DListDelete(&ConInKeyNotifyList, ListPtr);
+ break;
+ }
+ }
+
+ if (ListPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // we need to loop through all the registered SimpleInEx
+ // and call each of their ReadKeyStroke function
+
+ for (HandleLink = CsInKeyNotify->NotifyHandleList.pHead; HandleLink != NULL;
+ HandleLink = HandleLink->pNext) {
+ CsInNotifyHandle = OUTTER(HandleLink, Link, CON_SPLIT_IN_KEY_NOTIFY_HANDLE);
+
+ Status = CsInNotifyHandle->SimpleInEx->UnregisterKeyNotify(
+ CsInNotifyHandle->SimpleInEx, CsInNotifyHandle->NotifyHandle);
+
+ DListDelete(&(CsInKeyNotify->NotifyHandleList), HandleLink);
+ Status = pBS->FreePool(CsInNotifyHandle);
+ }
+
+ Status = pBS->FreePool(CsInKeyNotify);
+
+ return Status;
+}
+
+
+#if FAST_BOOT_SUPPORT
+#include <Protocol/FastBootProtocol.h>
+static AMI_FAST_BOOT_PROTOCOL *AmiFbProtocol = NULL;
+
+VOID ConnectInputDevices(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ static Executed = FALSE;
+
+ if(Executed)
+ return;
+
+ if(AmiFbProtocol == NULL) {
+ Status = pBS->LocateProtocol(&AmiFastBootProtocolGuid, NULL, &AmiFbProtocol);
+ if(EFI_ERROR(Status)) {
+ AmiFbProtocol = NULL;
+ return;
+ }
+ }
+
+ if(AmiFbProtocol->IsRuntime()) {
+ AmiFbProtocol->ConnectInputDevices();
+ Executed = TRUE;
+ }
+}
+
+#else //#if FAST_BOOT_SUPPORT
+VOID ConnectInputDevices(
+ VOID
+){return;}
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/ConSplitter/Out.c b/Core/CORE_DXE/ConSplitter/Out.c
new file mode 100644
index 0000000..d11ebc8
--- /dev/null
+++ b/Core/CORE_DXE/ConSplitter/Out.c
@@ -0,0 +1,1323 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/ConSplitter/Out.c 19 7/06/12 11:31a Artems $
+//
+// $Revision: 19 $
+//
+// $Date: 7/06/12 11:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/ConSplitter/Out.c $
+//
+// 19 7/06/12 11:31a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Support for monitor native resolution
+// [Files] Gc.c, Consplit.c, Out.c, Core_Dxe.sdl
+//
+// 18 10/27/11 12:50p Felixp
+// [TAG] EIP65867
+// [Category] Improvement
+// [Description] Screen content that was printed in a timer callback was
+// not getting restored after OpROM
+// execution.
+// The previous check-in didn't address all the issue.
+// This is a more sophisticated solution.
+//
+// 17 8/03/11 3:27p Felixp
+// [TAG] EIP65867
+// [Category] Improvement
+// [Description] Screen content that was printed in a timer callback was
+// not getting restored after OpROM execution.
+// RestoreTheScreen function is updated.
+//
+// 16 10/09/09 6:15p Felixp
+// UGA constant replaced with GOP constant (UEFI 2.1 compatibility)
+//
+// 15 7/07/09 3:35p Artems
+// Added functions headers according to code standard
+//
+// 14 6/16/09 5:49p Artems
+// EIP 21415 Fixed error with CursorVisible variable
+//
+// 11 10/23/07 10:13a Felixp
+// Bug fix: System was hanging in SCT during Simple Text Output protocol
+// testing
+// when "Enable Screen Ouput" SCT option was enabled.
+//
+// 10 7/20/07 12:16p Felixp
+// Clear the screen when switching from graphics screen to text screen
+// without mode switching
+//
+// 9 1/05/07 6:01p Artems
+//
+// 8 12/29/06 3:01p Felixp
+// 1. Support for GraphicsOutput protocol added
+// 2. Support for more then one text mode added
+//
+// 7 9/27/06 7:42p Felixp
+// SetMode funciton of the ConsoleControl protocol is updated to restore
+// default UGA mode when switching from grphics to text.
+//
+// 6 3/13/06 2:37a Felixp
+//
+// 5 12/12/05 8:36p Felixp
+// RestoreTheScreen update: Restore Cursor Status
+//
+// 4 12/12/05 9:32a Felixp
+// Support for synchronization of console devices
+// (now screen is restored after legacy OpROM execution).
+//
+// 3 7/21/05 5:12p Robert
+//
+// 2 1/31/05 11:31a Robert
+//
+// 1 1/28/05 1:16p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/07/05 11:57a Felixp
+//
+// 2 1/03/05 5:47p Robert
+// Working beta version of the consplitter
+//
+// 1 12/30/04 9:47a Robert
+// Initial check in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Out.c
+//
+// Description: File contains the Simple Text Output functionality for the
+// Console Splitter Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------------
+
+#include "ConSplit.h"
+#include <Protocol/GraphicsOutput.h>
+
+//----------------------------------------------------------------------------
+
+#define DefaultAttribute 0x0F
+#define DefaultCursorVisible TRUE
+
+SUPPORT_RES *SupportedModes = NULL;
+
+SIMPLE_TEXT_OUTPUT_MODE MasterMode =
+ {
+ 1, // MaxMode
+ 0, // Current Mode
+ 0x0F, // Attribute
+ 0, // Column
+ 0, // Row
+ 1 // CursorVisible
+ };
+
+
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mCSOutProtocol =
+ {
+ CSReset,
+ CSOutputString,
+ CSTestString,
+ CSQueryMode,
+ CSSetMode,
+ CSSetAttribute,
+ CSClearScreen,
+ CSSetCursorPosition,
+ CSEnableCursor,
+ &MasterMode
+ };
+
+//****************************** Virtual ConOut **********************//
+CHAR16 *ScreenBuffer = NULL;
+CHAR16 *SaveScreenBuffer = NULL;
+CHAR16 *EndOfTheScreen = NULL;
+INT32 *AttributeBuffer = NULL;
+INT32 *SaveAttributeBuffer = NULL;
+INT32 Columns = 0;
+BOOLEAN BlankScreen = TRUE;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ScrollScreen
+//
+// Description:
+// This function scrolls internal splitter buffer
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ScrollScreen(
+ VOID
+)
+{
+ INT32 i;
+ CHAR16 *pChar = EndOfTheScreen - Columns;
+ INT32 *pAttr = AttributeBuffer + (pChar-ScreenBuffer);
+
+ pBS->CopyMem(
+ ScreenBuffer+Columns, ScreenBuffer,
+ sizeof(CHAR16)* (EndOfTheScreen - pChar)
+ );
+
+ for(i=0; i<Columns; i++)
+ {
+ *pChar++ = ' ';
+ *pAttr++ = MasterMode.Attribute;
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MemOutputString
+//
+// Description:
+// This function puts string into internal splitter buffer
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN CHAR16 *String - pointer to string
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS MemOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ INT32 Col = MasterMode.CursorColumn;
+ UINTN Offset = MasterMode.CursorRow * Columns;
+ CHAR16 *pChar = ScreenBuffer + Offset + Col;
+ INT32 *pAttr = AttributeBuffer + Offset + Col;
+ BlankScreen = FALSE;
+
+ while(TRUE){
+ switch(*String){
+ case 0:
+ return EFI_SUCCESS;
+ case '\n':
+ if ((pChar + Columns) >= EndOfTheScreen)
+ ScrollScreen();
+ else
+ {
+ pChar += Columns;
+ pAttr += Columns;
+ }
+ break;
+ case '\r':
+ pChar -= Col;
+ pAttr -= Col;
+ Col = 0;
+ break;
+ case '\b':
+ if (Col)
+ {
+ pChar--;
+ pAttr--;
+ Col--;
+ }
+ break;
+ default:
+ if ((pChar + 1) == EndOfTheScreen)
+ {
+ ScrollScreen();
+ pChar -= Col;
+ pAttr -= Col;
+ Col = 0;
+ }
+ else
+ {
+ *pChar++ = *String;
+ *pAttr++ = MasterMode.Attribute;
+ Col++;
+ if (Col >= Columns)
+ Col = 0;
+ }
+ break;
+ }
+ String++;
+ }
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreTextScreen
+//
+// Description:
+// This function restores screen after switching mode
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreen - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreTextScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreen
+)
+{
+ CHAR16 *pChar = ScreenBuffer, *pStr = ScreenBuffer;
+ INT32 Col = 0, *pAttr = AttributeBuffer, Attr;
+ CHAR16 c;
+
+ if (BlankScreen)
+ return;
+
+ Attr = *pAttr;
+ pScreen->SetCursorPosition(pScreen,0,0);
+ pScreen->SetAttribute(pScreen,Attr);
+
+ for(; pChar<EndOfTheScreen; pChar++, pAttr++)
+ {
+ if (Col == Columns || *pAttr != Attr)
+ {
+ c = *pChar;
+ *pChar = 0;
+ pScreen->OutputString(pScreen, pStr);
+ *pChar = c;
+ pStr = pChar;
+ if (*pAttr != Attr)
+ {
+ Attr = *pAttr;
+ pScreen->SetAttribute(pScreen, Attr);
+ }
+ else
+ {
+ Col=1;
+ continue;
+ }
+ }
+ Col++;
+ }
+ //print last row
+ c = *--pChar;
+ *pChar = 0;
+ pScreen->OutputString(pScreen, pStr);
+ *pChar = c;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MemClearScreen
+//
+// Description:
+// This function clears internal splitter buffer
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS MemClearScreen(
+ VOID
+)
+{
+ CHAR16 *pChar;
+ INT32 *pAttr;
+ for( pChar = ScreenBuffer, pAttr = AttributeBuffer
+ ; pChar < EndOfTheScreen
+ ; pChar++, pAttr++ )
+ {
+ *pChar = ' ';
+ *pAttr = MasterMode.Attribute;
+ }
+ BlankScreen = TRUE;
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MemReset
+//
+// Description:
+// This function resets internal splitter buffer
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN EV - extended verification flag
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS MemReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ return MemClearScreen();
+}
+
+///////////////// Uga Save/Restore
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL *PixelBuffer = NULL;
+UINT32 GraphicsMode, TextMode = 0;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreUgaScreen
+//
+// Description:
+// This function restores screen after switching from text to graphics mode
+//
+// Input:
+// IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreUgaScreen(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
+)
+{
+ if (PixelBuffer){
+ EFI_STATUS Status;
+ Status = Gop->SetMode(Gop, GraphicsMode);
+ if (!EFI_ERROR(Status))
+ Gop->Blt(
+ Gop, PixelBuffer, EfiBltBufferToVideo, 0, 0, 0, 0,
+ Gop->Mode->Info->HorizontalResolution,
+ Gop->Mode->Info->VerticalResolution, 0
+ );
+ pBS->FreePool(PixelBuffer);
+ PixelBuffer = NULL;
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveUgaScreen
+//
+// Description:
+// This function saves graphics screen before switching to text mode
+//
+// Input:
+// IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID SaveUgaScreen(
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop
+)
+{
+ if (PixelBuffer)
+ pBS->FreePool(PixelBuffer);
+
+ GraphicsMode=Gop->Mode->Mode;
+ PixelBuffer = Malloc(
+ Gop->Mode->Info->VerticalResolution*
+ Gop->Mode->Info->HorizontalResolution*
+ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ if (PixelBuffer)
+ {
+ EFI_STATUS Status=Gop->Blt(
+ Gop, PixelBuffer, EfiBltVideoToBltBuffer, 0, 0, 0, 0,
+ Gop->Mode->Info->HorizontalResolution,
+ Gop->Mode->Info->VerticalResolution, 0);
+
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(PixelBuffer);
+ PixelBuffer = NULL;
+ }
+ }
+}
+
+static EFI_GUID guidGop = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreTextScreenDelta
+//
+// Description:
+// This function checks to see if anything has changed on the screen since the
+// graphics output device was disabled. If something has changed, then it will
+// add that to the display.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreTextScreenDelta(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *pScreen
+)
+{
+ UINT32 i;
+ CHAR16 StrBuffer[2] = {0, 0};
+ CONST UINT32 SizeOfScreen = (UINT32)((UINT8*)EndOfTheScreen-(UINT8*)ScreenBuffer) / sizeof(CHAR16);
+
+
+ // Check for differences from the old state, one by one
+ // If anything is different, update the screen with Simple Out protocol
+ for(i = 0; i < SizeOfScreen; i++)
+ {
+ if( (*(SaveScreenBuffer+i) != *(ScreenBuffer + i)) ||
+ (*(SaveAttributeBuffer+i) != *(AttributeBuffer + i)) )
+ {
+ StrBuffer[0] = *(ScreenBuffer + i);
+ pScreen->SetCursorPosition(pScreen, i % Columns, i / Columns);
+ pScreen->SetAttribute(pScreen, (UINT8)*(AttributeBuffer + i) );
+ pScreen->OutputString(pScreen, StrBuffer );
+ }
+ }
+
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreTheScreen
+//
+// Description:
+// This function restores screen of the output device after switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to restore
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut
+)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ if (EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ RestoreTextScreen(SimpleOut);
+ else
+ {
+ RestoreUgaScreen(Gop);
+ if(SaveScreenBuffer != NULL)
+ {
+ RestoreTextScreenDelta(SimpleOut);
+ pBS->FreePool(SaveScreenBuffer);
+ pBS->FreePool(SaveAttributeBuffer);
+ }
+ }
+ SimpleOut->SetAttribute(SimpleOut,MasterMode.Attribute);
+ SimpleOut->EnableCursor(SimpleOut,MasterMode.CursorVisible);
+ SimpleOut->SetCursorPosition(SimpleOut,MasterMode.CursorColumn,MasterMode.CursorRow);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveTheScreen
+//
+// Description:
+// This function saves the screen of the output device before switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to save
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut - pointer to protocol instance
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID SaveTheScreen(
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleOut)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+ UINT32 SizeOfScreen, SizeOfAttribute;
+ EFI_TPL OldTpl;
+
+ if (!EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ {
+
+ SizeOfScreen = (UINT32)((UINT8*)EndOfTheScreen-(UINT8*)ScreenBuffer);
+ SizeOfAttribute = (UINT32)SizeOfScreen*(sizeof(INT32)/sizeof(CHAR16));
+
+ // Allocate memory for saving the screen state, error out if not enough memory
+ SaveScreenBuffer=Malloc(SizeOfScreen);
+ if(SaveScreenBuffer==NULL) return;
+ SaveAttributeBuffer=Malloc(SizeOfAttribute);
+ if(SaveAttributeBuffer==NULL){
+ pBS->FreePool(SaveScreenBuffer);
+ return;
+ }
+ // Make this high priority so that the saved text screen is exactly
+ // the same as graphics screen
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ // Perform using MemCpy (instead of pBS->MemCopy) to prevent TPL assert
+ MemCpy(SaveScreenBuffer, ScreenBuffer, SizeOfScreen);
+ MemCpy(SaveAttributeBuffer, AttributeBuffer, SizeOfAttribute);
+
+ pBS->RestoreTPL(OldTpl);
+ SaveUgaScreen(Gop);
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveUgaMode
+//
+// Description:
+// This function saves the graphics mode of the output device before switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to save
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID SaveUgaMode(
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ if (EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ return;
+
+ TextMode=Gop->Mode->Mode;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: RestoreUgaMode
+//
+// Description:
+// This function restores the graphics mode of the output device after switching modes
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of output device to restore
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID RestoreUgaMode(
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Gop;
+
+ if (EFI_ERROR(pBS->HandleProtocol(ControllerHandle, &guidGop, &Gop)))
+ return;
+
+ if (TextMode!=Gop->Mode->Mode)
+ {
+ Gop->SetMode(Gop,TextMode);
+ }
+ else
+ {//Just clear the screen
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Buffer = {0,0,0,0};
+ Gop->Blt( Gop, &Buffer, EfiBltVideoFill,0,0,0,0,
+ Gop->Mode->Info->HorizontalResolution,
+ Gop->Mode->Info->VerticalResolution,
+ 0
+ );
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSReset
+//
+// Description:
+// This function resets the text output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN EV - extended verification flag
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - all devices, handled by splitter were reset successfully
+// EFI_DEVICE_ERROR - error occured during resetting the device
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their Reset function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->Reset(SimpleOut->SimpleOut, EV);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ MemReset(This,EV);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSOutputString
+//
+// Description:
+// This function writes a string to the output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN CHAR16 *String - pointer to string to write
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during output string
+// EFI_WARN_UNKNOWN_GLYPH - some of characters were skipped during output
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ MemOutputString(This,String);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their OutputString function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->OutputString(SimpleOut->SimpleOut, String);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSTestString
+//
+// Description:
+// This function tests whether all characters in String can be drawn on device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN CHAR16 *String - pointer to string to test
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - all characters can be drawn
+// EFI_UNSUPPORTED - there are characters that cannot be drawn
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their TestString function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->TestString(SimpleOut->SimpleOut, String);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSQueryMode
+//
+// Description:
+// This function returns information about text mode referred by ModeNum
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN ModeNum - mode number to obtain information about
+// OUT UINTN *Col - max number of columns supported in this mode
+// OUT UINTN *Row - max number of rows supported in this mode
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_UNSUPPORTED - given mode unsupported
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row
+)
+{
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if((ModeNum >= (UINTN)MasterMode.MaxMode) || (!SupportedModes[ModeNum].AllDevices))
+ return EFI_UNSUPPORTED;
+
+ if (SimpleOut == NULL)
+ {
+ // since we use a default text mode, return that value
+ *Col = 80;
+ *Row = 25;
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ *Col = SupportedModes[ModeNum].Columns;
+ *Row = SupportedModes[ModeNum].Rows;
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetMode
+//
+// Description:
+// This function sets text mode referred by ModeNumber
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN ModeNum - mode number to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_UNSUPPORTED - given mode unsupported
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ INT32 DeviceMode;
+
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if((ModeNum >= (UINTN)MasterMode.MaxMode) || (!SupportedModes[ModeNum].AllDevices))
+ return EFI_UNSUPPORTED;
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ TestStatus = ResizeSplitterBuffer((INT32)ModeNum);
+ if (EFI_ERROR(TestStatus))
+ return TestStatus;
+
+ MasterMode.Mode = (INT32)ModeNum;
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetMode function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = IsModeSupported(SimpleOut->SimpleOut, ModeNum, &DeviceMode);
+
+ TestStatus = SimpleOut->SimpleOut->SetMode(SimpleOut->SimpleOut, DeviceMode);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return EFI_ERROR(Status);
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetAttribute
+//
+// Description:
+// This function sets the foreground color and background color for the screen
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN Attribute - attribute to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - attribute was changed successfully
+// EFI_DEVICE_ERROR - device had an error
+// EFI_UNSUPPORTED - attribute is not supported
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetAttribute function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->SetAttribute(SimpleOut->SimpleOut, Attribute);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSClearScreen
+//
+// Description:
+// This function clears screen of output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their ClearScreen function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->ClearScreen(SimpleOut->SimpleOut);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ MemClearScreen();
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSSetCursorPosition
+//
+// Description:
+// This function sets cursor position of output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN UINTN Column - column position
+// IN UINTN Row - row position
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during execution
+// EFI_UNSUPPORTED - given position cannot be set
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSSetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetCursorPosition function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->SetCursorPosition(SimpleOut->SimpleOut, Column, Row);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ UpdateMasterMode(SimpleOut->SimpleOut->Mode);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CSEnableCursor
+//
+// Description:
+// This function enables / disables cursor on the screen
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to protocol instance
+// IN BOOLEAN Visible - if TRUE cursor will be visible, FALSE - not visible
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_DEVICE_ERROR - error occured during execution
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS CSEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible )
+{
+ EFI_STATUS Status = EFI_SUCCESS, TestStatus;
+ CON_SPLIT_OUT *SimpleOut = OUTTER(ConOutList.pHead, Link, CON_SPLIT_OUT);
+
+ if (SimpleOut == NULL)
+ return EFI_DEVICE_ERROR;
+
+ // we need to loop through all the registered simple text out devices
+ // and call each of their SetCursorPosition function
+ while ( SimpleOut != NULL)
+ {
+ TestStatus = SimpleOut->SimpleOut->EnableCursor(SimpleOut->SimpleOut, Visible);
+ SimpleOut = OUTTER(SimpleOut->Link.pNext, Link, CON_SPLIT_OUT);
+
+ if (EFI_ERROR(TestStatus))
+ Status = TestStatus;
+ }
+
+ MasterMode.CursorVisible = Visible;
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateMasterMode
+//
+// Description:
+// This function updates splitter mode to values referred by Mode
+//
+// Input:
+// IN SIMPLE_TEXT_OUTPUT_MODE *Mode - pointer to values to be set
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID UpdateMasterMode(
+ SIMPLE_TEXT_OUTPUT_MODE *Mode)
+{
+ MasterMode.Attribute = Mode->Attribute;
+ MasterMode.CursorColumn = Mode->CursorColumn;
+ MasterMode.CursorRow = Mode->CursorRow;
+ while(MasterMode.CursorColumn>=SupportedModes[MasterMode.Mode].Columns){
+ MasterMode.CursorColumn-=SupportedModes[MasterMode.Mode].Columns;
+ MasterMode.CursorRow++;
+ };
+ if (MasterMode.CursorRow>=SupportedModes[MasterMode.Mode].Rows)
+ MasterMode.CursorRow=SupportedModes[MasterMode.Mode].Rows-1;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/CoreSectionExtraction.c b/Core/CORE_DXE/CoreSectionExtraction.c
new file mode 100644
index 0000000..98f501c
--- /dev/null
+++ b/Core/CORE_DXE/CoreSectionExtraction.c
@@ -0,0 +1,1367 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ CoreSectionExtraction.c
+
+Abstract:
+
+ Section Extraction Protocol implementation.
+
+ Stream database is implemented as a linked list of section streams,
+ where each stream contains a linked list of children, which may be leaves or
+ encapsulations.
+
+ Children that are encapsulations generate new stream entries
+ when they are created. Streams can also be created by calls to
+ SEP->OpenSectionStream().
+
+ The database is only created far enough to return the requested data from
+ any given stream, or to determine that the requested data is not found.
+
+ If a GUIDed encapsulation is encountered, there are three possiblilites.
+
+ 1) A support protocol is found, in which the stream is simply processed with
+ the support protocol.
+
+ 2) A support protocol is not found, but the data is available to be read
+ without processing. In this case, the database is built up through the
+ recursions to return the data, and a RPN event is set that will enable
+ the stream in question to be refreshed if and when the required section
+ extraction protocol is published.This insures the AuthenticationStatus
+ does not become stale in the cache.
+
+ 3) A support protocol is not found, and the data is not available to be read
+ without it. This results in EFI_PROTOCOL_ERROR.
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "EfiFirmwareFileSystem.h"
+
+//
+// Comsumed protocol
+//
+#include EFI_PROTOCOL_DEFINITION (TianoDecompress)
+#include EFI_PROTOCOL_DEFINITION (GuidedSectionExtraction)
+
+//
+// Produced protocol
+//
+#include EFI_PROTOCOL_DEFINITION (SectionExtraction)
+
+//
+// Local defines and typedefs
+//
+#define CORE_SECTION_CHILD_SIGNATURE EFI_SIGNATURE_32('S','X','C','S')
+#define CHILD_SECTION_NODE_FROM_LINK(Node) \
+ CR (Node, CORE_SECTION_CHILD_NODE, Link, CORE_SECTION_CHILD_SIGNATURE)
+
+typedef struct {
+ UINT32 Signature;
+ EFI_LIST_ENTRY Link;
+ UINT32 Type;
+ UINT32 Size;
+ //
+ // StreamBase + OffsetInStream == pointer to section header in stream. The
+ // stream base is always known when walking the sections within.
+ //
+ UINT32 OffsetInStream;
+ //
+ // Then EncapsulatedStreamHandle below is always 0 if the section is NOT an
+ // encapsulating section. Otherwise, it contains the stream handle
+ // of the encapsulated stream. This handle is ALWAYS produced any time an
+ // encapsulating child is encountered, irrespective of whether the
+ // encapsulated stream is processed further.
+ //
+ UINTN EncapsulatedStreamHandle;
+ EFI_GUID *EncapsulationGuid;
+} CORE_SECTION_CHILD_NODE;
+
+#define CORE_SECTION_STREAM_SIGNATURE EFI_SIGNATURE_32('S','X','S','S')
+#define STREAM_NODE_FROM_LINK(Node) \
+ CR (Node, CORE_SECTION_STREAM_NODE, Link, CORE_SECTION_STREAM_SIGNATURE)
+
+typedef struct {
+ UINT32 Signature;
+ EFI_LIST_ENTRY Link;
+ UINTN StreamHandle;
+ UINT8 *StreamBuffer;
+ UINTN StreamLength;
+ EFI_LIST Children;
+ //
+ // Authentication status is from GUIDed encapsulations.
+ //
+ UINT32 AuthenticationStatus;
+} CORE_SECTION_STREAM_NODE;
+
+#define NULL_STREAM_HANDLE 0
+
+typedef struct {
+ CORE_SECTION_CHILD_NODE *ChildNode;
+ CORE_SECTION_STREAM_NODE *ParentStream;
+ VOID *Registration;
+ EFI_EVENT Event;
+} RPN_EVENT_CONTEXT;
+
+
+
+//
+// Local prototypes
+//
+
+STATIC
+BOOLEAN
+ChildIsType (
+ IN CORE_SECTION_STREAM_NODE *Stream,
+ IN CORE_SECTION_CHILD_NODE *Child,
+ IN EFI_SECTION_TYPE SearchType,
+ IN EFI_GUID *SectionDefinitionGuid
+ );
+
+STATIC
+VOID
+EFIAPI
+NotifyGuidedExtraction (
+ IN EFI_EVENT Event,
+ IN VOID *RpnContext
+ );
+
+STATIC
+VOID
+CreateGuidedExtractionRpnEvent (
+ IN CORE_SECTION_STREAM_NODE *ParentStream,
+ IN CORE_SECTION_CHILD_NODE *ChildNode
+ );
+
+EFI_STATUS
+EFIAPI
+OpenSectionStream (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL *This,
+ IN UINTN SectionStreamLength,
+ IN VOID *SectionStream,
+ OUT UINTN *SectionStreamHandle
+ );
+
+EFI_STATUS
+EFIAPI
+GetSection (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL *This,
+ IN UINTN SectionStreamHandle,
+ IN EFI_SECTION_TYPE *SectionType,
+ IN EFI_GUID *SectionDefinitionGuid,
+ IN UINTN SectionInstance,
+ IN VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ );
+
+EFI_STATUS
+EFIAPI
+CloseSectionStream (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL *This,
+ IN UINTN StreamHandleToClose
+ );
+
+STATIC
+EFI_STATUS
+FindStreamNode (
+ IN UINTN SearchHandle,
+ OUT CORE_SECTION_STREAM_NODE **FoundStream
+ );
+
+STATIC
+EFI_STATUS
+FindChildNode (
+ IN CORE_SECTION_STREAM_NODE *SourceStream,
+ IN EFI_SECTION_TYPE SearchType,
+ IN UINTN *SectionInstance,
+ IN EFI_GUID *SectionDefinitionGuid,
+ OUT CORE_SECTION_CHILD_NODE **FoundChild,
+ OUT CORE_SECTION_STREAM_NODE **FoundStream,
+ OUT UINT32 *AuthenticationStatus
+ );
+
+STATIC
+EFI_STATUS
+CreateChildNode (
+ IN CORE_SECTION_STREAM_NODE *Stream,
+ IN UINT32 ChildOffset,
+ OUT CORE_SECTION_CHILD_NODE **ChildNode
+ );
+
+STATIC
+VOID
+FreeChildNode (
+ IN CORE_SECTION_CHILD_NODE *ChildNode
+ );
+
+STATIC
+EFI_STATUS
+OpenSectionStreamEx (
+ IN UINTN SectionStreamLength,
+ IN VOID *SectionStream,
+ IN BOOLEAN AllocateBuffer,
+ IN UINT32 AuthenticationStatus,
+ OUT UINTN *SectionStreamHandle
+ );
+
+STATIC
+BOOLEAN
+IsValidSectionStream (
+ IN VOID *SectionStream,
+ IN UINTN SectionStreamLength
+ );
+
+//
+// Module globals
+//
+EFI_LIST mStreamRoot = INITIALIZE_LIST_HEAD_VARIABLE (mStreamRoot);
+
+EFI_HANDLE mSectionExtractionHandle = NULL;
+
+EFI_SECTION_EXTRACTION_PROTOCOL mSectionExtraction = {
+ OpenSectionStream,
+ GetSection,
+ CloseSectionStream
+};
+
+
+EFI_STATUS
+EFIAPI
+InitializeSectionExtraction (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ Entry point of the section extraction code. Initializes an instance of the
+ section extraction interface and installs it on a new handle.
+
+Arguments:
+ ImageHandle EFI_HANDLE: A handle for the image that is initializing this driver
+ SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table
+
+Returns:
+ EFI_SUCCESS: Driver initialized successfully
+ EFI_OUT_OF_RESOURCES: Could not allocate needed resources
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Install SEP to a new handle
+ //
+ Status = CoreInstallProtocolInterface (
+ &mSectionExtractionHandle,
+ &gEfiSectionExtractionProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSectionExtraction
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+OpenSectionStream (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL *This,
+ IN UINTN SectionStreamLength,
+ IN VOID *SectionStream,
+ OUT UINTN *SectionStreamHandle
+ )
+/*++
+
+Routine Description:
+ SEP member function. This function creates and returns a new section stream
+ handle to represent the new section stream.
+
+Arguments:
+ This - Indicates the calling context.
+ SectionStreamLength - Size in bytes of the section stream.
+ SectionStream - Buffer containing the new section stream.
+ SectionStreamHandle - A pointer to a caller allocated UINTN that on output
+ contains the new section stream handle.
+
+Returns:
+ EFI_SUCCESS
+ EFI_OUT_OF_RESOURCES - memory allocation failed.
+ EFI_INVALID_PARAMETER - section stream does not end concident with end of
+ last section.
+
+--*/
+{
+ //
+ // Check to see section stream looks good...
+ //
+ if (!IsValidSectionStream (SectionStream, SectionStreamLength)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return OpenSectionStreamEx (
+ SectionStreamLength,
+ SectionStream,
+ TRUE,
+ 0,
+ SectionStreamHandle
+ );
+}
+
+
+EFI_STATUS
+EFIAPI
+GetSection (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL *This,
+ IN UINTN SectionStreamHandle,
+ IN EFI_SECTION_TYPE *SectionType,
+ IN EFI_GUID *SectionDefinitionGuid,
+ IN UINTN SectionInstance,
+ IN VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+ SEP member function. Retrieves requested section from section stream.
+
+Arguments:
+ This: Pointer to SEP instance.
+ SectionStreamHandle: The section stream from which to extract the requested
+ section.
+ SectionType: A pointer to the type of section to search for.
+ SectionDefinitionGuid: If the section type is EFI_SECTION_GUID_DEFINED, then
+ SectionDefinitionGuid indicates which of these types
+ of sections to search for.
+ SectionInstance: Indicates which instance of the requested section to
+ return.
+ Buffer: Double indirection to buffer. If *Buffer is non-null on
+ input, then the buffer is caller allocated. If
+ *Buffer is NULL, then the buffer is callee allocated.
+ In either case, the requried buffer size is returned
+ in *BufferSize.
+ BufferSize: On input, indicates the size of *Buffer if *Buffer is
+ non-null on input. On output, indicates the required
+ size (allocated size if callee allocated) of *Buffer.
+ AuthenticationStatus: Indicates the authentication status of the retrieved
+ section.
+
+Returns:
+ EFI_SUCCESS: Section was retrieved successfully
+ EFI_PROTOCOL_ERROR: A GUID defined section was encountered in the section
+ stream with its EFI_GUIDED_SECTION_PROCESSING_REQUIRED
+ bit set, but there was no corresponding GUIDed Section
+ Extraction Protocol in the handle database. *Buffer is
+ unmodified.
+ EFI_NOT_FOUND: An error was encountered when parsing the SectionStream.
+ This indicates the SectionStream is not correctly
+ formatted.
+ EFI_NOT_FOUND: The requested section does not exist.
+ EFI_OUT_OF_RESOURCES: The system has insufficient resources to process the
+ request.
+ EFI_INVALID_PARAMETER: The SectionStreamHandle does not exist.
+ EFI_WARN_TOO_SMALL: The size of the caller allocated input buffer is
+ insufficient to contain the requested section. The
+ input buffer is filled and contents are section contents
+ are truncated.
+
+--*/
+{
+ CORE_SECTION_STREAM_NODE *StreamNode;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ CORE_SECTION_CHILD_NODE *ChildNode;
+ CORE_SECTION_STREAM_NODE *ChildStreamNode;
+ UINTN CopySize;
+ UINT32 ExtractedAuthenticationStatus;
+ UINTN Instance;
+ UINT8 *CopyBuffer;
+ UINTN SectionSize;
+
+
+ OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);
+ Instance = SectionInstance + 1;
+
+ //
+ // Locate target stream
+ //
+ Status = FindStreamNode (SectionStreamHandle, &StreamNode);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto GetSection_Done;
+ }
+
+ //
+ // Found the stream, now locate and return the appropriate section
+ //
+ if (SectionType == NULL) {
+ //
+ // SectionType == NULL means return the WHOLE section stream...
+ //
+ CopySize = StreamNode->StreamLength;
+ CopyBuffer = StreamNode->StreamBuffer;
+ *AuthenticationStatus = StreamNode->AuthenticationStatus;
+ } else {
+ //
+ // There's a requested section type, so go find it and return it...
+ //
+ Status = FindChildNode (
+ StreamNode,
+ *SectionType,
+ &Instance,
+ SectionDefinitionGuid,
+ &ChildNode,
+ &ChildStreamNode,
+ &ExtractedAuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ goto GetSection_Done;
+ }
+ CopySize = ChildNode->Size - sizeof (EFI_COMMON_SECTION_HEADER);
+ CopyBuffer = ChildStreamNode->StreamBuffer + ChildNode->OffsetInStream + sizeof (EFI_COMMON_SECTION_HEADER);
+ *AuthenticationStatus = ExtractedAuthenticationStatus;
+ }
+
+ SectionSize = CopySize;
+ if (*Buffer != NULL) {
+ //
+ // Caller allocated buffer. Fill to size and return required size...
+ //
+ if (*BufferSize < CopySize) {
+ Status = EFI_WARN_BUFFER_TOO_SMALL;
+ CopySize = *BufferSize;
+ }
+ } else {
+ //
+ // Callee allocated buffer. Allocate buffer and return size.
+ //
+ *Buffer = CoreAllocateBootServicesPool (CopySize);
+ if (*Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto GetSection_Done;
+ }
+ }
+ EfiCommonLibCopyMem (*Buffer, CopyBuffer, CopySize);
+ *BufferSize = SectionSize;
+
+GetSection_Done:
+ CoreRestoreTpl (OldTpl);
+ return Status;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+CloseSectionStream (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL *This,
+ IN UINTN StreamHandleToClose
+ )
+/*++
+
+Routine Description:
+ SEP member function. Deletes an existing section stream
+
+Arguments:
+ This - Indicates the calling context.
+ StreamHandleToClose - Indicates the stream to close
+
+Returns:
+ EFI_SUCCESS
+ EFI_OUT_OF_RESOURCES - memory allocation failed.
+ EFI_INVALID_PARAMETER - section stream does not end concident with end of
+ last section.
+
+--*/
+{
+ CORE_SECTION_STREAM_NODE *StreamNode;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+ EFI_LIST *Link;
+ CORE_SECTION_CHILD_NODE *ChildNode;
+
+ OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);
+
+ //
+ // Locate target stream
+ //
+ Status = FindStreamNode (StreamHandleToClose, &StreamNode);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Found the stream, so close it
+ //
+ RemoveEntryList (&StreamNode->Link);
+ while (!IsListEmpty (&StreamNode->Children)) {
+ Link = GetFirstNode (&StreamNode->Children);
+ ChildNode = CHILD_SECTION_NODE_FROM_LINK (Link);
+ FreeChildNode (ChildNode);
+ }
+ CoreFreePool (StreamNode->StreamBuffer);
+ CoreFreePool (StreamNode);
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ CoreRestoreTpl (OldTpl);
+ return Status;
+}
+
+
+STATIC
+BOOLEAN
+ChildIsType (
+ IN CORE_SECTION_STREAM_NODE *Stream,
+ IN CORE_SECTION_CHILD_NODE *Child,
+ IN EFI_SECTION_TYPE SearchType,
+ IN EFI_GUID *SectionDefinitionGuid
+ )
+/*++
+
+Routine Description:
+ Worker function. Determine if the input stream:child matches the input type.
+
+Arguments:
+ Stream - Indicates the section stream associated with the child
+ Child - Indicates the child to check
+ SearchType - Indicates the type of section to check against for
+ SectionDefinitionGuid - Indicates the GUID to check against if the type is
+ EFI_SECTION_GUID_DEFINED
+Returns:
+ TRUE - The child matches
+ FALSE - The child doesn't match
+
+--*/
+{
+ EFI_GUID_DEFINED_SECTION *GuidedSection;
+
+ if (SearchType == EFI_SECTION_ALL) {
+ return TRUE;
+ }
+ if (Child->Type != SearchType) {
+ return FALSE;
+ }
+//*** AMI PORTING BEGIN ***//
+// Bug fix: ReadSection function of the FV protocol (FvReadFileSection)
+// didn't work for GUID defined sections (always returned EFI_NOT_FOUND).
+// When this function is called from FvReadFileSection, SectionDefinitionGuid is always NULL.
+// If SectionDefinitionGuid is NULL, return TRUE (the section type matches).
+// if (SearchType != EFI_SECTION_GUID_DEFINED) {
+ if (SearchType != EFI_SECTION_GUID_DEFINED || SectionDefinitionGuid == NULL) {
+//*** AMI PORTING END *****//
+ return TRUE;
+ }
+ GuidedSection = (EFI_GUID_DEFINED_SECTION * )(Stream->StreamBuffer + Child->OffsetInStream);
+ return EfiCompareGuid (&GuidedSection->SectionDefinitionGuid, SectionDefinitionGuid);
+}
+
+
+STATIC
+EFI_STATUS
+FindChildNode (
+ IN CORE_SECTION_STREAM_NODE *SourceStream,
+ IN EFI_SECTION_TYPE SearchType,
+ IN OUT UINTN *SectionInstance,
+ IN EFI_GUID *SectionDefinitionGuid,
+ OUT CORE_SECTION_CHILD_NODE **FoundChild,
+ OUT CORE_SECTION_STREAM_NODE **FoundStream,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+ Worker function Recursively searches / builds section stream database
+ looking for requested section.
+
+Arguments:
+ SourceStream - Indicates the section stream in which to do the search.
+ SearchType - Indicates the type of section to search for.
+ SectionInstance - Indicates which instance of section to find. This is
+ an in/out parameter to deal with recursions.
+ SectionDefinitionGuid - Guid of section definition
+ FoundChild - Output indicating the child node that is found.
+ FoundStream - Output indicating which section stream the child was
+ found in. If this stream was generated as a result of
+ an encapsulation section, the streamhandle is visible
+ within the SEP driver only.
+ AuthenticationStatus- Indicates the authentication status of the found section.
+
+Returns:
+ EFI_SUCCESS - Child node was found and returned.
+ EFI_OUT_OF_RESOURCES- Memory allocation failed.
+ EFI_NOT_FOUND - Requested child node does not exist.
+ EFI_PROTOCOL_ERROR - a required GUIDED section extraction protocol does not
+ exist
+
+--*/
+{
+ CORE_SECTION_CHILD_NODE *CurrentChildNode;
+ CORE_SECTION_CHILD_NODE *RecursedChildNode;
+ CORE_SECTION_STREAM_NODE *RecursedFoundStream;
+ UINT32 NextChildOffset;
+ EFI_STATUS ErrorStatus;
+ EFI_STATUS Status;
+
+ CurrentChildNode = NULL;
+ ErrorStatus = EFI_NOT_FOUND;
+
+ if (SourceStream->StreamLength == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (IsListEmpty (&SourceStream->Children) &&
+ SourceStream->StreamLength > sizeof (EFI_COMMON_SECTION_HEADER)) {
+ //
+ // This occurs when a section stream exists, but no child sections
+ // have been parsed out yet. Therefore, extract the first child and add it
+ // to the list of children so we can get started.
+ //
+ Status = CreateChildNode (SourceStream, 0, &CurrentChildNode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // At least one child has been parsed out of the section stream. So, walk
+ // through the sections that have already been parsed out looking for the
+ // requested section, if necessary, continue parsing section stream and
+ // adding children until either the requested section is found, or we run
+ // out of data
+ //
+ CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetFirstNode(&SourceStream->Children));
+
+ for (;;) {
+ if (ChildIsType (SourceStream, CurrentChildNode, SearchType, SectionDefinitionGuid)) {
+ //
+ // The type matches, so check the instance count to see if it's the one we want
+ //
+ (*SectionInstance)--;
+ if (*SectionInstance == 0) {
+ //
+ // Got it!
+ //
+ *FoundChild = CurrentChildNode;
+ *FoundStream = SourceStream;
+ *AuthenticationStatus = SourceStream->AuthenticationStatus;
+ return EFI_SUCCESS;
+ }
+ }
+
+ if (CurrentChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
+ //
+ // If the current node is an encapsulating node, recurse into it...
+ //
+ Status = FindChildNode (
+ (CORE_SECTION_STREAM_NODE *)CurrentChildNode->EncapsulatedStreamHandle,
+ SearchType,
+ SectionInstance,
+ SectionDefinitionGuid,
+ &RecursedChildNode,
+ &RecursedFoundStream,
+ AuthenticationStatus
+ );
+ //
+ // If the status is not EFI_SUCCESS, just save the error code and continue
+ // to find the request child node in the rest stream.
+ //
+ if (*SectionInstance == 0) {
+ ASSERT_EFI_ERROR (Status);
+ *FoundChild = RecursedChildNode;
+ *FoundStream = RecursedFoundStream;
+ return EFI_SUCCESS;
+ } else {
+ ErrorStatus = Status;
+ }
+ }
+
+ if (!IsNodeAtEnd (&SourceStream->Children, &CurrentChildNode->Link)) {
+ //
+ // We haven't found the child node we're interested in yet, but there's
+ // still more nodes that have already been parsed so get the next one
+ // and continue searching..
+ //
+ CurrentChildNode = CHILD_SECTION_NODE_FROM_LINK (GetNextNode (&SourceStream->Children, &CurrentChildNode->Link));
+ } else {
+ //
+ // We've exhausted children that have already been parsed, so see if
+ // there's any more data and continue parsing out more children if there
+ // is.
+ //
+ NextChildOffset = CurrentChildNode->OffsetInStream + CurrentChildNode->Size;
+ //
+ // Round up to 4 byte boundary
+ //
+ NextChildOffset += 3;
+ NextChildOffset &= ~(UINTN)3;
+ if (NextChildOffset <= SourceStream->StreamLength - sizeof (EFI_COMMON_SECTION_HEADER)) {
+ //
+ // There's an unparsed child remaining in the stream, so create a new child node
+ //
+ Status = CreateChildNode (SourceStream, NextChildOffset, &CurrentChildNode);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ } else {
+ ASSERT (EFI_ERROR (ErrorStatus));
+ return ErrorStatus;
+ }
+ }
+ }
+}
+
+
+STATIC
+EFI_STATUS
+CreateChildNode (
+ IN CORE_SECTION_STREAM_NODE *Stream,
+ IN UINT32 ChildOffset,
+ OUT CORE_SECTION_CHILD_NODE **ChildNode
+ )
+/*++
+
+Routine Description:
+ Worker function. Constructor for new child nodes.
+
+Arguments:
+ Stream - Indicates the section stream in which to add the child.
+ ChildOffset - Indicates the offset in Stream that is the beginning
+ of the child section.
+ ChildNode - Indicates the Callee allocated and initialized child.
+
+Returns:
+ EFI_SUCCESS - Child node was found and returned.
+ EFI_OUT_OF_RESOURCES- Memory allocation failed.
+ EFI_PROTOCOL_ERROR - Encapsulation sections produce new stream handles when
+ the child node is created. If the section type is GUID
+ defined, and the extraction GUID does not exist, and
+ producing the stream requires the GUID, then a protocol
+ error is generated and no child is produced.
+ Values returned by OpenSectionStreamEx.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_COMMON_SECTION_HEADER *SectionHeader;
+ EFI_COMPRESSION_SECTION *CompressionHeader;
+ EFI_GUID_DEFINED_SECTION *GuidedHeader;
+ EFI_TIANO_DECOMPRESS_PROTOCOL *Decompress;
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction;
+ VOID *NewStreamBuffer;
+ VOID *ScratchBuffer;
+ UINT32 ScratchSize;
+ UINTN NewStreamBufferSize;
+ UINT32 AuthenticationStatus;
+ UINT32 SectionLength;
+
+ CORE_SECTION_CHILD_NODE *Node;
+
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *) (Stream->StreamBuffer + ChildOffset);
+
+ //
+ // Allocate a new node
+ //
+ *ChildNode = CoreAllocateBootServicesPool (sizeof (CORE_SECTION_CHILD_NODE));
+ Node = *ChildNode;
+ if (Node == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Now initialize it
+ //
+ Node->Signature = CORE_SECTION_CHILD_SIGNATURE;
+ Node->Type = SectionHeader->Type;
+ Node->Size = SECTION_SIZE (SectionHeader);
+ Node->OffsetInStream = ChildOffset;
+ Node->EncapsulatedStreamHandle = NULL_STREAM_HANDLE;
+ Node->EncapsulationGuid = NULL;
+
+ //
+ // If it's an encapsulating section, then create the new section stream also
+ //
+ switch (Node->Type) {
+ case EFI_SECTION_COMPRESSION:
+ //
+ // Get the CompressionSectionHeader
+ //
+ ASSERT (Node->Size >= sizeof (EFI_COMPRESSION_SECTION));
+
+ CompressionHeader = (EFI_COMPRESSION_SECTION *) SectionHeader;
+
+ //
+ // Allocate space for the new stream
+ //
+ if (CompressionHeader->UncompressedLength > 0) {
+ NewStreamBufferSize = CompressionHeader->UncompressedLength;
+ NewStreamBuffer = CoreAllocateBootServicesPool (NewStreamBufferSize);
+ if (NewStreamBuffer == NULL) {
+ CoreFreePool (Node);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (CompressionHeader->CompressionType == EFI_NOT_COMPRESSED) {
+ //
+ // stream is not actually compressed, just encapsulated. So just copy it.
+ //
+ EfiCommonLibCopyMem (NewStreamBuffer, CompressionHeader + 1, NewStreamBufferSize);
+ } else if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION ||
+ CompressionHeader->CompressionType == EFI_CUSTOMIZED_COMPRESSION) {
+ //
+ // Decompress the stream
+ //
+ if (CompressionHeader->CompressionType == EFI_STANDARD_COMPRESSION) {
+ Status = CoreLocateProtocol (&gEfiTianoDecompressProtocolGuid, NULL, &Decompress);
+ } else {
+ Status = CoreLocateProtocol (&gEfiCustomizedDecompressProtocolGuid, NULL, &Decompress);
+ }
+
+ ASSERT_EFI_ERROR (Status);
+//*** AMI PORTING BEGIN ***//
+// Bug fix: What if the protocol has not been found?
+ if (EFI_ERROR (Status)) {
+ CoreFreePool (Node);
+ CoreFreePool (NewStreamBuffer);
+ return EFI_PROTOCOL_ERROR;
+ }
+//*** AMI PORTING END *****//
+
+ Status = Decompress->GetInfo (
+ Decompress,
+ CompressionHeader + 1,
+ Node->Size - sizeof (EFI_COMPRESSION_SECTION),
+ (UINT32 *)&NewStreamBufferSize,
+ &ScratchSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (NewStreamBufferSize == CompressionHeader->UncompressedLength);
+
+ ScratchBuffer = CoreAllocateBootServicesPool (ScratchSize);
+ if (ScratchBuffer == NULL) {
+ CoreFreePool (Node);
+ CoreFreePool (NewStreamBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = Decompress->Decompress (
+ Decompress,
+ CompressionHeader + 1,
+ Node->Size - sizeof (EFI_COMPRESSION_SECTION),
+ NewStreamBuffer,
+ (UINT32)NewStreamBufferSize,
+ ScratchBuffer,
+ ScratchSize
+ );
+ ASSERT_EFI_ERROR (Status);
+ CoreFreePool (ScratchBuffer);
+ }
+ } else {
+ NewStreamBuffer = NULL;
+ NewStreamBufferSize = 0;
+ }
+
+ Status = OpenSectionStreamEx (
+ NewStreamBufferSize,
+ NewStreamBuffer,
+ FALSE,
+ Stream->AuthenticationStatus,
+ &Node->EncapsulatedStreamHandle
+ );
+ if (EFI_ERROR (Status)) {
+ CoreFreePool (Node);
+ CoreFreePool (NewStreamBuffer);
+ return Status;
+ }
+ break;
+
+ case EFI_SECTION_GUID_DEFINED:
+ GuidedHeader = (EFI_GUID_DEFINED_SECTION *) SectionHeader;
+ Node->EncapsulationGuid = &GuidedHeader->SectionDefinitionGuid;
+ Status = CoreLocateProtocol (Node->EncapsulationGuid, NULL, &GuidedExtraction);
+ if (!EFI_ERROR (Status)) {
+ //
+ // NewStreamBuffer is always allocated by ExtractSection... No caller
+ // allocation here.
+ //
+ Status = GuidedExtraction->ExtractSection (
+ GuidedExtraction,
+ GuidedHeader,
+ &NewStreamBuffer,
+ &NewStreamBufferSize,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ CoreFreePool (*ChildNode);
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ //
+ // Make sure we initialize the new stream with the correct
+ // authentication status for both aggregate and local status fields.
+ //
+ if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
+ //
+ // OR in the parent stream's aggregate status.
+ //
+ AuthenticationStatus |= Stream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;
+ } else {
+ //
+ // since there's no authentication data contributed by the section,
+ // just inherit the full value from our immediate parent.
+ //
+ AuthenticationStatus = Stream->AuthenticationStatus;
+ }
+
+ Status = OpenSectionStreamEx (
+ NewStreamBufferSize,
+ NewStreamBuffer,
+ FALSE,
+ AuthenticationStatus,
+ &Node->EncapsulatedStreamHandle
+ );
+ if (EFI_ERROR (Status)) {
+ CoreFreePool (*ChildNode);
+ CoreFreePool (NewStreamBuffer);
+ return Status;
+ }
+ } else {
+ //
+ // There's no GUIDed section extraction protocol available.
+ //
+ if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_PROCESSING_REQUIRED) {
+ //
+ // If the section REQUIRES an extraction protocol, then we're toast
+ //
+ CoreFreePool (*ChildNode);
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ //
+ // Figure out the proper authentication status
+ //
+ AuthenticationStatus = Stream->AuthenticationStatus;
+ if (GuidedHeader->Attributes & EFI_GUIDED_SECTION_AUTH_STATUS_VALID) {
+ //
+ // The local status of the new stream is contained in
+ // AuthenticaionStatus. This value needs to be ORed into the
+ // Aggregate bits also...
+ //
+
+ //
+ // Clear out and initialize the local status
+ //
+ AuthenticationStatus &= ~EFI_LOCAL_AUTH_STATUS_ALL;
+ AuthenticationStatus |= EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED;
+ //
+ // OR local status into aggregate status
+ //
+ AuthenticationStatus |= AuthenticationStatus >> 16;
+ }
+
+ SectionLength = SECTION_SIZE (GuidedHeader);
+ Status = OpenSectionStreamEx (
+ SectionLength - GuidedHeader->DataOffset,
+ (UINT8 *) GuidedHeader + GuidedHeader->DataOffset,
+ TRUE,
+ AuthenticationStatus,
+ &Node->EncapsulatedStreamHandle
+ );
+ if (EFI_ERROR (Status)) {
+ CoreFreePool (Node);
+ return Status;
+ }
+ }
+
+ if ((AuthenticationStatus & EFI_LOCAL_AUTH_STATUS_ALL) ==
+ (EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED | EFI_LOCAL_AUTH_STATUS_NOT_TESTED)) {
+ //
+ // Need to register for RPN for when the required GUIDed extraction
+ // protocol becomes available. This will enable us to refresh the
+ // AuthenticationStatus cached in the Stream if it's ever requested
+ // again.
+ //
+ CreateGuidedExtractionRpnEvent (Stream, Node);
+ }
+
+ break;
+
+ default:
+
+ //
+ // Nothing to do if it's a leaf
+ //
+ break;
+ }
+
+ //
+ // Last, add the new child node to the stream
+ //
+ InsertTailList (&Stream->Children, &Node->Link);
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+VOID
+CreateGuidedExtractionRpnEvent (
+ IN CORE_SECTION_STREAM_NODE *ParentStream,
+ IN CORE_SECTION_CHILD_NODE *ChildNode
+ )
+/*++
+
+Routine Description:
+ Worker function. Constructor for RPN event if needed to keep AuthenticationStatus
+ cache correct when a missing GUIDED_SECTION_EXTRACTION_PROTOCOL appears...
+
+Arguments:
+ ParentStream - Indicates the parent of the ecnapsulation section (child)
+ ChildNode - Indicates the child node that is the encapsulation section.
+
+Returns:
+ None
+
+--*/
+{
+ RPN_EVENT_CONTEXT *Context;
+
+ //
+ // Allocate new event structure and context
+ //
+ Context = CoreAllocateBootServicesPool (sizeof (RPN_EVENT_CONTEXT));
+ ASSERT (Context != NULL);
+
+ Context->ChildNode = ChildNode;
+ Context->ParentStream = ParentStream;
+
+ Context->Event = CoreCreateProtocolNotifyEvent (
+ Context->ChildNode->EncapsulationGuid,
+ EFI_TPL_NOTIFY,
+ NotifyGuidedExtraction,
+ Context,
+ &Context->Registration,
+ FALSE
+ );
+}
+
+
+STATIC
+VOID
+EFIAPI
+NotifyGuidedExtraction (
+ IN EFI_EVENT Event,
+ IN VOID *RpnContext
+ )
+/*++
+
+Routine Description:
+ RPN callback function. Removes a stale section stream and re-initializes it
+ with an updated AuthenticationStatus.
+
+Arguments:
+ Event - The event that fired
+ RpnContext - A pointer to the context that allows us to identify
+ the relevent encapsulation...
+
+Returns:
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_GUID_DEFINED_SECTION *GuidedHeader;
+ EFI_GUIDED_SECTION_EXTRACTION_PROTOCOL *GuidedExtraction;
+ VOID *NewStreamBuffer;
+ UINTN NewStreamBufferSize;
+ UINT32 AuthenticationStatus;
+ RPN_EVENT_CONTEXT *Context;
+
+ Context = RpnContext;
+
+ Status = CloseSectionStream (&mSectionExtraction, Context->ChildNode->EncapsulatedStreamHandle);
+ if (!EFI_ERROR (Status)) {
+ //
+ // The stream closed successfully, so re-open the stream with correct AuthenticationStatus
+ //
+
+ GuidedHeader = (EFI_GUID_DEFINED_SECTION *)
+ (Context->ParentStream->StreamBuffer + Context->ChildNode->OffsetInStream);
+ ASSERT (GuidedHeader->CommonHeader.Type == EFI_SECTION_GUID_DEFINED);
+
+ Status = CoreLocateProtocol (Context->ChildNode->EncapsulationGuid, NULL, &GuidedExtraction);
+ ASSERT_EFI_ERROR (Status);
+
+
+ Status = GuidedExtraction->ExtractSection (
+ GuidedExtraction,
+ GuidedHeader,
+ &NewStreamBuffer,
+ &NewStreamBufferSize,
+ &AuthenticationStatus
+ );
+ ASSERT_EFI_ERROR (Status);
+ //
+ // OR in the parent stream's aggregagate status.
+ //
+ AuthenticationStatus |= Context->ParentStream->AuthenticationStatus & EFI_AGGREGATE_AUTH_STATUS_ALL;
+ Status = OpenSectionStreamEx (
+ NewStreamBufferSize,
+ NewStreamBuffer,
+ FALSE,
+ AuthenticationStatus,
+ &Context->ChildNode->EncapsulatedStreamHandle
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // If above, the stream did not close successfully, it indicates it's
+ // alread been closed by someone, so just destroy the event and be done with
+ // it.
+ //
+
+ CoreCloseEvent (Event);
+ CoreFreePool (Context);
+}
+
+
+STATIC
+VOID
+FreeChildNode (
+ IN CORE_SECTION_CHILD_NODE *ChildNode
+ )
+/*++
+
+Routine Description:
+ Worker function. Destructor for child nodes.
+
+Arguments:
+ ChildNode - Indicates the node to destroy
+
+Returns:
+ none
+
+--*/
+{
+ ASSERT (ChildNode->Signature == CORE_SECTION_CHILD_SIGNATURE);
+ //
+ // Remove the child from it's list
+ //
+ RemoveEntryList (&ChildNode->Link);
+
+ if (ChildNode->EncapsulatedStreamHandle != NULL_STREAM_HANDLE) {
+ //
+ // If it's an encapsulating section, we close the resulting section stream.
+ // CloseSectionStream will free all memory associated with the stream.
+ //
+ CloseSectionStream (&mSectionExtraction, ChildNode->EncapsulatedStreamHandle);
+ }
+ //
+ // Last, free the child node itself
+ //
+ CoreFreePool (ChildNode);
+}
+
+
+STATIC
+EFI_STATUS
+OpenSectionStreamEx (
+ IN UINTN SectionStreamLength,
+ IN VOID *SectionStream,
+ IN BOOLEAN AllocateBuffer,
+ IN UINT32 AuthenticationStatus,
+ OUT UINTN *SectionStreamHandle
+ )
+/*++
+
+ Routine Description:
+ Worker function. Constructor for section streams.
+
+ Arguments:
+ SectionStreamLength - Size in bytes of the section stream.
+ SectionStream - Buffer containing the new section stream.
+ AllocateBuffer - Indicates whether the stream buffer is to be copied
+ or the input buffer is to be used in place.
+ AuthenticationStatus- Indicates the default authentication status for the
+ new stream.
+ SectionStreamHandle - A pointer to a caller allocated section stream handle.
+
+ Returns:
+ EFI_SUCCESS - Stream was added to stream database.
+ EFI_OUT_OF_RESOURCES - memory allocation failed.
+
+--*/
+{
+ CORE_SECTION_STREAM_NODE *NewStream;
+ EFI_TPL OldTpl;
+
+ //
+ // Allocate a new stream
+ //
+ NewStream = CoreAllocateBootServicesPool (sizeof (CORE_SECTION_STREAM_NODE));
+ if (NewStream == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (AllocateBuffer) {
+ //
+ // if we're here, we're double buffering, allocate the buffer and copy the
+ // data in
+ //
+ if (SectionStreamLength > 0) {
+ NewStream->StreamBuffer = CoreAllocateBootServicesPool (SectionStreamLength);
+ if (NewStream->StreamBuffer == NULL) {
+ CoreFreePool (NewStream);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Copy in stream data
+ //
+ EfiCommonLibCopyMem (NewStream->StreamBuffer, SectionStream, SectionStreamLength);
+ } else {
+ //
+ // It's possible to have a zero length section stream.
+ //
+ NewStream->StreamBuffer = NULL;
+ }
+ } else {
+ //
+ // If were here, the caller has supplied the buffer (it's an internal call)
+ // so just assign the buffer. This happens when we open section streams
+ // as a result of expanding an encapsulating section.
+ //
+ NewStream->StreamBuffer = SectionStream;
+ }
+
+ //
+ // Initialize the rest of the section stream
+ //
+ NewStream->Signature = CORE_SECTION_STREAM_SIGNATURE;
+ NewStream->StreamHandle = (UINTN) NewStream;
+ NewStream->StreamLength = SectionStreamLength;
+ InitializeListHead (&NewStream->Children);
+ NewStream->AuthenticationStatus = AuthenticationStatus;
+
+ //
+ // Add new stream to stream list
+ //
+ OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);
+ InsertTailList (&mStreamRoot, &NewStream->Link);
+ CoreRestoreTpl (OldTpl);
+
+ *SectionStreamHandle = NewStream->StreamHandle;
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS
+FindStreamNode (
+ IN UINTN SearchHandle,
+ OUT CORE_SECTION_STREAM_NODE **FoundStream
+ )
+/*++
+
+ Routine Description:
+ Worker function. Search stream database for requested stream handle.
+
+ Arguments:
+ SearchHandle - Indicates which stream to look for.
+ FoundStream - Output pointer to the found stream.
+
+ Returns:
+ EFI_SUCCESS - StreamHandle was found and *FoundStream contains
+ the stream node.
+ EFI_NOT_FOUND - SearchHandle was not found in the stream database.
+
+--*/
+{
+ CORE_SECTION_STREAM_NODE *StreamNode;
+
+ if (!IsListEmpty (&mStreamRoot)) {
+ StreamNode = STREAM_NODE_FROM_LINK (GetFirstNode (&mStreamRoot));
+ for (;;) {
+ if (StreamNode->StreamHandle == SearchHandle) {
+ *FoundStream = StreamNode;
+ return EFI_SUCCESS;
+ } else if (IsNodeAtEnd (&mStreamRoot, &StreamNode->Link)) {
+ break;
+ } else {
+ StreamNode = STREAM_NODE_FROM_LINK (GetNextNode (&mStreamRoot, &StreamNode->Link));
+ }
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+STATIC
+BOOLEAN
+IsValidSectionStream (
+ IN VOID *SectionStream,
+ IN UINTN SectionStreamLength
+ )
+/*++
+
+Routine Description:
+ Check if a stream is valid.
+
+Arguments:
+ SectionStream - The section stream to be checked
+ SectionStreamLength - The length of section stream
+
+Returns:
+ TRUE
+ FALSE
+
+--*/
+{
+ UINTN TotalLength;
+ UINTN SectionLength;
+ EFI_COMMON_SECTION_HEADER *SectionHeader;
+ EFI_COMMON_SECTION_HEADER *NextSectionHeader;
+
+ TotalLength = 0;
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *)SectionStream;
+
+ while (TotalLength < SectionStreamLength) {
+ SectionLength = SECTION_SIZE (SectionHeader);
+ TotalLength += SectionLength;
+
+ if (TotalLength == SectionStreamLength) {
+ return TRUE;
+ }
+
+ //
+ // Move to the next byte following the section...
+ //
+ SectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINT8 *) SectionHeader + SectionLength);
+
+ //
+ // Figure out where the next section begins
+ //
+ NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) SectionHeader + 3);
+ NextSectionHeader = (EFI_COMMON_SECTION_HEADER *) ((UINTN) NextSectionHeader & ~(UINTN)3);
+ TotalLength += (UINTN) NextSectionHeader - (UINTN) SectionHeader;
+ SectionHeader = NextSectionHeader;
+ }
+
+ ASSERT (FALSE);
+ return FALSE;
+}
diff --git a/Core/CORE_DXE/DataHub.c b/Core/CORE_DXE/DataHub.c
new file mode 100644
index 0000000..c2aa760
--- /dev/null
+++ b/Core/CORE_DXE/DataHub.c
@@ -0,0 +1,681 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/DataHub.c 5 7/08/09 5:54p Vyacheslava $
+//
+// $Revision: 5 $
+//
+// $Date: 7/08/09 5:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/DataHub.c $
+//
+// 5 7/08/09 5:54p Vyacheslava
+// Updated according to the coding standards.
+//
+// 4 12/16/08 1:32a Iminglin
+// The function value of FindNextFiltermatch for compliance.
+//
+// 3 11/07/07 12:13p Felixp
+// Bug fixes in record filtering logic.
+// Old code was treating FilterClass parameter passed into
+// RegisterFilterDriver routine as requested class value.
+// However, data hub specification defines this parameter as a bit map of
+// requested data classes.
+//
+// 2 9/05/07 5:51p Felixp
+// 1. LogData routine is updated.
+// Core that initializes RecordSize field of the data hub record
+// header is updated to include header size (the header size was excluded
+// in the previous Core verions).<br />
+// DataHub specification is vague regarding the RecordSize field.
+// It says RecordSize is "Size of the data in the record in
+// bytes".
+// It's not clear if it should include or exclude the header size.
+// In EDK DataHub implenetation RecordSize includes the header.
+// Aptio implementation is updated to comply with EDK
+// implementation.
+// 2. When time is not available initialize time fields with default
+// values
+//
+// 1 1/28/05 12:45p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 6 11/12/04 3:13p Markw
+// Added signal event, to get previously logged data.
+//
+// 5 4/17/04 4:23p Felixp
+//
+// 4 3/24/04 10:17a Markw
+// Using AmiDxeLib instead AmiLib.
+//
+// 3 3/23/04 5:45p Markw
+// Added function and table headers (comments) to the file.
+//
+// 2 3/20/04 10:46a Felixp
+//
+// 1 3/16/04 2:38p Markw
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DataHub_c
+//
+// Description: Log data to be retrieved by functions or call events
+// for data matching filter.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Protocol\DataHub.h>
+
+EFI_GUID gDataHubProtocolGuid = EFI_DATA_HUB_PROTOCOL_GUID;
+
+//**********************************************************************
+//<AMI_THDR_START>
+//
+// Name: DATA_RECORD
+//
+// Description: This structure describes the Data Record header and data.
+//
+// Fields:
+// Name Type Description
+// ------------------------------------------------------------
+// Link DATA_RECORD* Next link
+// RecordHeader EFI_DATA_RECORD_HEADER Log Record Header
+///
+// Directly following Header (&RecordHeader + 1) is the data.
+//
+//<AMI_THDR_END>
+//**********************************************************************
+
+typedef struct _DATA_RECORD DATA_RECORD;
+struct _DATA_RECORD {
+ DATA_RECORD *Link;
+ EFI_DATA_RECORD_HEADER RecordHeader;
+};
+
+//**********************************************************************
+//<AMI_THDR_START>
+//
+// Name: FILTER
+//
+// Description: This structure describes the filter link.
+//
+// Fields:
+// Name Type Description
+// ------------------------------------------------------------
+// Link FILTER* Next link
+// Event EFI_EVENT Event
+// Class UINT64 Class (0 if no class filtering)
+// DataRecordGuid EFI_GUID Guid (undefined in no guid filtering)
+// isGuid BOOLEAN TRUE if guid filtering.
+// LastRead DATA_RECORD* Last read record for the filter.
+//
+//<AMI_THDR_END>
+//**********************************************************************
+
+typedef struct _FILTER FILTER;
+struct _FILTER {
+ FILTER *Link;
+ EFI_EVENT Event;
+ UINT64 Class;
+ EFI_GUID DataRecordGuid;
+ BOOLEAN isGuid;
+ DATA_RECORD *LastRead;
+};
+
+
+FILTER *gFilHead = 0; //Filter Head
+DATA_RECORD *gHead = 0; //Data Record Head
+DATA_RECORD *gTail = 0; //Data Record Count
+UINT64 gLogCount = 0; //Unique log count.
+DATA_RECORD *gCache = 0; //Last reocrd cache.
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FindNextFilterMatch
+//
+// Description: Search log to find next record that matches filter.
+//
+// Input:
+// DATA_RECORD *Record
+// FILTER *Filter
+//
+// Output: DATA_RECORD*
+//
+// Referrals: guidcmp
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Starting at the current record for filter matching.
+// 2. If Class and Class doesn't match continue at step 1 for next record.
+// 3. If guid and DataRecordGuid doesn't match continue at step 1 for next record.
+// 4. Match, return record.
+// 5. If Steps 1-4, doesn't find any matching filter, return 0.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+DATA_RECORD* FindNextFilterMatch(
+ DATA_RECORD *Record,
+ FILTER *Filter)
+{
+ for (; Record; Record=Record->Link) {
+ if ( Filter->Class &&
+ !(Filter->Class & Record->RecordHeader.DataRecordClass) )
+ continue;
+
+ if ( Filter->isGuid &&
+ guidcmp(&Filter->DataRecordGuid,&Record->RecordHeader.DataRecordGuid) != 0 )
+ continue;
+
+ return Record;
+ }
+
+ return NULL;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: LogData
+//
+// Description: Log the record. If matching event, signal it.
+//
+// Input:
+// IN EFI_DATA_HUB_PROTOCOL *This
+// IN EFI_GUID *DataRecordGuid
+// IN EFI_GUID *ProducerName
+// IN UINT64 DataRecordClass
+// IN VOID *RawData
+// IN UINT32 RawDataSize
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Event logged.
+// * EFI_OUT_OF_RESOUCES - Not enough resources to log data.
+//
+// Modified: gHead gTail
+//
+// Referrals: AllocatePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Allocate memory enough for data record. If not enough memory, return EFI_OUT_OF_RESOURCES.
+// 2. Fill data record header and increase log count.
+// 3. Fill data to log.
+// 4. Add record to log.
+// 5. Check for a matching filter.
+// 6. If matching filter, signal event.
+// 7. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS LogData(
+ IN EFI_DATA_HUB_PROTOCOL *This,
+ IN EFI_GUID *DataRecordGuid,
+ IN EFI_GUID *ProducerName,
+ IN UINT64 DataRecordClass,
+ IN VOID *RawData,
+ IN UINT32 RawDataSize
+)
+{
+ EFI_DATA_RECORD_HEADER *RcdHdr;
+ DATA_RECORD *Record;
+ FILTER *Filter;
+ UINT8 *Data;
+ EFI_STATUS Status;
+
+ //16 dummy bytes to make sure struct alignment isn't an issue in platform.
+ if ( pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(DATA_RECORD) + RawDataSize + 16,
+ &Record ) != EFI_SUCCESS )
+ return EFI_OUT_OF_RESOURCES;
+
+ RcdHdr = &Record->RecordHeader;
+
+ Record->Link = 0;
+ RcdHdr->Version = EFI_DATA_RECORD_HEADER_VERSION;
+ RcdHdr->HeaderSize = sizeof(EFI_DATA_RECORD_HEADER);
+//DataHub specification is vague regarding the RecordSize field.
+//It says RecordSize is "Size of the data in the record in bytes".
+//It's not clear if it should include or exclude the header size.
+//It's sounds more like it should not, however,
+//in EDK DataHub implenetation RecordSize includes the header.
+//For the sake of compatibility let's do the same.
+ RcdHdr->RecordSize = RawDataSize+sizeof(EFI_DATA_RECORD_HEADER);
+ RcdHdr->DataRecordGuid = *DataRecordGuid;
+ RcdHdr->ProducerName = *ProducerName;
+ RcdHdr->DataRecordClass = DataRecordClass;
+ RcdHdr->LogMonotonicCount = ++gLogCount; //Each log count must be unique.
+ Status = pRS->GetTime(&(RcdHdr->LogTime),NULL);
+
+ if (EFI_ERROR(Status)) { //time not available, set default values
+ RcdHdr->LogTime.Year = 0;
+ RcdHdr->LogTime.Month = 1;
+ RcdHdr->LogTime.Day = 1;
+ RcdHdr->LogTime.Hour = 0;
+ RcdHdr->LogTime.Minute = 0;
+ RcdHdr->LogTime.Second = 0;
+ }
+
+ //Store data to be logged.
+ Data = (UINT8*)(RcdHdr + 1);
+ MemCpy(
+ Data,
+ RawData,
+ RawDataSize
+ );
+
+ //Add record to log.
+ if (!gHead)
+ gHead = Record;
+ else
+ gTail->Link = Record;
+
+ gTail = Record;
+
+ //Check for matching filter.
+ for (Filter = gFilHead; Filter; Filter = Filter->Link) {
+ if ( Filter->Class &&
+ !(Filter->Class & DataRecordClass) )
+ continue;
+
+ if ( Filter->isGuid &&
+ guidcmp(&Filter->DataRecordGuid, DataRecordGuid) != 0 )
+ continue;
+
+ pBS->SignalEvent(Filter->Event);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetNextDataRecord
+//
+// Description: Search log to find next record that matches Count or filter.
+// Return next record or if Filter, next record matching filter.
+//
+// Input:
+// IN EFI_DATA_HUB_PROTOCOL *This
+// IN OUT UINT64 *MonotonicCount
+// IN EFI_EVENT *FilterDriver OPTIONAL
+// OUT EFI_DATA_RECORD_HEADER **Record
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - If Data Record returned.
+// * EFI_NOT_FOUND - Data Record not found.
+// * EFI_INVALID_PARAMETER - *FilterDriver doesn't match registered filters.
+//
+// Modified: gCache
+//
+// Referrals: FindNextFilterMatch
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If no logged records, return EFI_NOT_FOUND.
+// 2. If using FilterDriver, find filter. If filter not found, return EFI_INVALID_PARAMETER;
+// 3. If *MonotonicCount != 0, go to step 14.
+// ---*MonotonicCount = 0---
+// 4. If no filter driver, set *MonotonicCount = 1, go to step 14.
+// ---Filter Driver---
+// 5. If no last read, start at Head.
+// 6. If last read, start at the next. If no next, return EFI_NOT_FOUND.
+// 7. Find record matching filter.
+// 8. If no match, set last read to tail, and return EFI_NOT_FOUND.
+// 9. Set *Record to found record, and set LastRead to record.
+// 10. Find next match, to get *MonotonicCount.
+// 11. If not found, set *MonotonicCount = 0.
+// 12. Set cache to link.
+// 13. Return EFI_SUCCESS.
+// ---MontonicCount exists---
+// 14. Get starting link. If after cache, use cache, otherwise use head.
+// 15. Search until log count is found, regardless of filter.
+// 16. If not found, return EFI_NOT_FOUND.
+// 17. If filter set LastRead.
+// 18. If last link, *MontonicCount = 0. Go to step 21.
+// ---If not last link,---
+// 19. If FilterDriver, find next match for *MonotonicCounter.
+// 20. If no next match, set *MonotonicCounter = 0.
+// -------
+// 21. Set cache. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS GetNextDataRecord(
+ IN EFI_DATA_HUB_PROTOCOL *This,
+ IN OUT UINT64 *MonotonicCount,
+ IN EFI_EVENT *FilterDriver OPTIONAL,
+ OUT EFI_DATA_RECORD_HEADER **Record
+)
+{
+ DATA_RECORD *Link;
+ FILTER *Filter;
+
+ if (!gHead)
+ return EFI_NOT_FOUND; //Any records logged?
+
+ //Find Matching filter
+ if (FilterDriver) {
+ //In future, binary search may be more efficient, or some caching.
+ for (Filter = gFilHead; Filter && Filter->Event != *FilterDriver; Filter = Filter->Link)
+ ; //Find matching Filter for Event.
+
+ if (!Filter)
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //If monotonic count is zero?
+ if (!*MonotonicCount) {
+ //If filter driver, get first unread record matching filter.
+ if (!FilterDriver) {
+ *MonotonicCount = 1; //If not filter driver, get first record.
+
+ } else {
+ //Get the record after the last read record. If not, get the first record.
+ if (Filter->LastRead)
+ Link = Filter->LastRead->Link;
+ else
+ Link = gHead;
+
+ if (!Link)
+ return EFI_NOT_FOUND; //If record doesn't exist, return EFI_NOT_FOUND.
+
+ if ( !(Link = FindNextFilterMatch(Link, Filter)) ) { //Get record matching filter, zero if no match.
+ //No matching record. Set LastRead to tail, and return EFI_NOT_FOUND.
+ Filter->LastRead = gTail;
+ return EFI_NOT_FOUND;
+ }
+
+ //Save pointer to matching record, and last read record.
+ *Record = &Link->RecordHeader;
+ Filter->LastRead = Link;
+
+ //Find the next matching record to return the next Monotonic Count.
+ if ( Link = FindNextFilterMatch(Link->Link, Filter) ) //zero if no match.
+ *MonotonicCount = Link->RecordHeader.LogMonotonicCount;
+ else
+ *MonotonicCount = 0; //If no matching record, set last read to end.
+
+ gCache = Link; //Set cache to find the next record.
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Find a specific MonotonicCount.
+ //If Count is same or after cache, start with cache. Otherwise start at beginning.
+ if (gCache && gCache->RecordHeader.LogMonotonicCount <= *MonotonicCount)
+ Link = gCache;
+ else
+ Link = gHead;
+
+ //Search for Log.
+ for (; Link; Link = Link->Link) {
+ if (Link->RecordHeader.LogMonotonicCount == *MonotonicCount) {
+ *Record = &Link->RecordHeader; //Save pointer to matching record.
+
+ if (Link == gTail) { //If last log, Count = 0.
+ *MonotonicCount = 0;
+
+ if (FilterDriver)
+ Filter->LastRead = Link; //If filter, store last read.
+
+ } else { //If not last log.
+ if (FilterDriver) {
+ Filter->LastRead = Link; //Set last read.
+
+ if ( Link = FindNextFilterMatch(Link->Link, Filter) )
+ *MonotonicCount = Link->RecordHeader.LogMonotonicCount; //Get count of next matching record.
+ else
+ *MonotonicCount = 0; //If no more matching record, set count to 0.
+
+ } else
+ ++*MonotonicCount; //If not filter driver, increase count.
+ }
+
+ gCache = Link; //Set cache.
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND; //Record does't exist.
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RegisterFilterDriver
+//
+// Description: Register new filter driver.
+//
+// Input:
+// IN EFI_DATA_HUB_PROTOCOL *This
+// IN EFI_EVENT FilterEvent
+// IN EFI_TPL FilterTpl
+// IN UINT64 FilterClass
+// IN EFI_GUID *FilterDataRecordGuid OPTIONAL
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Filter driver registered.
+// * EFI_ALREADY_STARTED - Filter driver was already registered.
+// * EFI_OUT_OF_RESOURCES - Not enough resources to allocate Link.
+//
+// Modified: gFilHead
+//
+// Referrals: AllocatePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Search filters for matching Event. If Event return return EFI_ALREADY_STARTED.
+// 2. Allocate Link for filter. If out of resources, return EFI_OUT_OF_RESOURCES.
+// 3. Fill in filter data.
+// 4. Add link to end.
+// 5. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS RegisterFilterDriver(
+ IN EFI_DATA_HUB_PROTOCOL *This,
+ IN EFI_EVENT FilterEvent,
+ IN EFI_TPL FilterTpl,
+ IN UINT64 FilterClass,
+ IN EFI_GUID *FilterDataRecordGuid OPTIONAL
+)
+{
+ FILTER *Filter;
+ FILTER *Link, *PLink;
+ FILTER **Ptr;
+
+ if (gFilHead) {
+ for (Link = gFilHead; Link; Link = Link->Link) {
+ if (Link->Event == FilterEvent)
+ return EFI_ALREADY_STARTED;
+
+ PLink = Link;
+ }
+
+ Ptr = &PLink->Link;
+
+ } else
+ Ptr = &gFilHead;
+
+ if ( pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(FILTER),
+ &Filter) != EFI_SUCCESS )
+ return EFI_OUT_OF_RESOURCES;
+
+ Filter->Link = 0;
+ Filter->Event = FilterEvent;
+ Filter->Class = FilterClass;
+ Filter->LastRead = NULL;
+
+ if (FilterDataRecordGuid) { //Guid is optional. isGuid, determines if to test Guid.
+ Filter->DataRecordGuid = *FilterDataRecordGuid;
+ Filter->isGuid = TRUE;
+
+ } else
+ Filter->isGuid = FALSE;
+
+ *Ptr = Filter;
+
+ // Signal the Filter driver to get all the previous logged data. Otherwise,
+ // One must wait until the next signal to get the previous logged data.
+ pBS->SignalEvent(FilterEvent);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: UnregisterFilterDriver
+//
+// Description: Unregister a filter driver.
+//
+// Input:
+// IN EFI_DATA_HUB_PROTOCOL *This
+// IN EFI_EVENT FilterEvent
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Filter driver removed.
+// * EFI_NOT_FOUND - Filter driver not found.
+//
+// Modified: gFilHead
+//
+// Referrals: FreePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If no filter drivers, return EFI_NOT_FOUND.
+// 2. If filter stored in Filter Driver Head, free filter driver
+// and set Head to next link.
+// 3. Find filter driver.
+// 4. If found, remove link, then free link. Return EFI_SUCCESS.
+// 5. If not found, return EFI_NOT_FOUND.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS UnregisterFilterDriver(
+ IN EFI_DATA_HUB_PROTOCOL *This,
+ IN EFI_EVENT FilterEvent
+)
+{
+ FILTER *Link, *PLink;
+
+ PLink = gFilHead;
+
+ if (!gFilHead)
+ return EFI_NOT_FOUND;
+
+ if (gFilHead->Event == FilterEvent) {
+ gFilHead = gFilHead->Link;
+ pBS->FreePool(PLink);
+ return EFI_SUCCESS;
+ }
+
+ for (Link = gFilHead->Link; Link; Link = Link->Link) {
+ if (Link->Event == FilterEvent) {
+ PLink->Link = Link->Link;
+ pBS->FreePool(Link);
+ return EFI_SUCCESS;
+ }
+
+ PLink = Link;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_DATA_HUB_PROTOCOL gDataHub = {
+ LogData,
+ GetNextDataRecord,
+ RegisterFilterDriver,
+ UnregisterFilterDriver
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitDataHub
+//
+// Description: Install Data Hub Protocol.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Referrals: InstallMultipleProtocolInterfaces
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Install Data Hub Protocol.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS InitDataHub(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+
+ return pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gDataHubProtocolGuid,
+ &gDataHub,
+ NULL
+ );
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/DebugImageInfo.c b/Core/CORE_DXE/DebugImageInfo.c
new file mode 100644
index 0000000..c1a81a3
--- /dev/null
+++ b/Core/CORE_DXE/DebugImageInfo.c
@@ -0,0 +1,262 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DebugImageInfo.c
+
+Abstract:
+
+ Support functions for managing debug image info table when loading and unloading
+ images.
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "DebugImageInfo.h"
+
+
+static EFI_DEBUG_IMAGE_INFO_TABLE_HEADER mDebugInfoTableHeader = {
+ 0, // volatile UINT32 UpdateStatus;
+ 0, // UINT32 TableSize;
+ NULL // EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
+};
+
+static EFI_SYSTEM_TABLE_POINTER *mDebugTable = NULL;
+
+
+VOID
+CoreInitializeDebugImageInfoTable (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Creates and initializes the DebugImageInfo Table. Also creates the configuration
+ table and registers it into the system table.
+
+Arguments:
+ None
+
+Returns:
+ NA
+
+Notes:
+ This function allocates memory, frees it, and then allocates memory at an
+ address within the initial allocation. Since this function is called early
+ in DXE core initialization (before drivers are dispatched), this should not
+ be a problem.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Mem;
+ UINTN NumberOfPages;
+
+ //
+ // Allocate boot services memory for the structure. It's required to be aligned on
+ // a 4M boundary, so allocate a 4M block (plus what we require), free it up, calculate
+ // a 4M aligned address within the memory we just freed, and then allocate memory at that
+ // address for our initial structure.
+ //
+ NumberOfPages = FOUR_MEG_PAGES + EFI_SIZE_TO_PAGES(sizeof (EFI_SYSTEM_TABLE_POINTER));
+
+ Status = CoreAllocatePages (AllocateAnyPages, EfiBootServicesData, NumberOfPages , &Mem);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ Status = CoreFreePages (Mem, NumberOfPages);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ //
+ // Now get a 4M aligned address within the memory range we were given.
+ // Then allocate memory at that address
+ //
+ Mem = (Mem + FOUR_MEG_MASK) & (~FOUR_MEG_MASK);
+
+ Status = CoreAllocatePages (AllocateAddress, EfiBootServicesData, NumberOfPages - FOUR_MEG_PAGES, &Mem);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ //
+ // We now have a 4M aligned page allocated, so fill in the data structure.
+ // Ideally we would update the CRC now as well, but the service may not yet be available.
+ // See comments in the CoreUpdateDebugTableCrc32() function below for details.
+ //
+ mDebugTable = (EFI_SYSTEM_TABLE_POINTER *)(UINTN)Mem;
+ mDebugTable->Signature = EFI_SYSTEM_TABLE_SIGNATURE;
+ mDebugTable->EfiSystemTableBase = (EFI_PHYSICAL_ADDRESS) (UINTN) gST;
+ mDebugTable->Crc32 = 0;
+ Status = CoreInstallConfigurationTable (&gEfiDebugImageInfoTableGuid, &mDebugInfoTableHeader);
+ ASSERT_EFI_ERROR (Status);
+}
+
+VOID
+CoreUpdateDebugTableCrc32 (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Update the CRC32 in the Debug Table.
+ Since the CRC32 service is made available by the Runtime driver, we have to
+ wait for the Runtime Driver to be installed before the CRC32 can be computed.
+ This function is called elsewhere by the core when the runtime architectural
+ protocol is produced.
+
+Arguments:
+ None
+
+Returns:
+ NA
+
+--*/
+{
+ ASSERT(mDebugTable != NULL);
+ mDebugTable->Crc32 = 0;
+ gBS->CalculateCrc32 ((VOID *)mDebugTable, sizeof (EFI_SYSTEM_TABLE_POINTER), &mDebugTable->Crc32);
+}
+
+VOID
+CoreNewDebugImageInfoEntry (
+ IN UINT32 ImageInfoType,
+ IN EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
+ the table if it's not large enough to accomidate another entry.
+
+Arguments:
+
+ ImageInfoType - type of debug image information
+ LoadedImage - pointer to the loaded image protocol for the image being loaded
+ ImageHandle - image handle for the image being loaded
+
+Returns:
+ NA
+
+--*/
+{
+ EFI_DEBUG_IMAGE_INFO *Table;
+ EFI_DEBUG_IMAGE_INFO *NewTable;
+ UINTN Index;
+ UINTN MaxTableIndex;
+ UINTN TableSize;
+
+ //
+ // Set the flag indicating that we're in the process of updating the table.
+ //
+ mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
+ MaxTableIndex = mDebugInfoTableHeader.TableSize;
+
+ for (Index = 0; Index < MaxTableIndex; Index++) {
+ if (Table[Index].NormalImage == NULL) {
+ //
+ // We have found a free entry so exit the loop
+ //
+ break;
+ }
+ }
+ if (Index == MaxTableIndex) {
+ //
+ // Table is full, so re-allocate another page for a larger table...
+ //
+ TableSize = MaxTableIndex * EFI_DEBUG_TABLE_ENTRY_SIZE;
+ NewTable = CoreAllocateZeroBootServicesPool (TableSize + EFI_PAGE_SIZE);
+ if (NewTable == NULL) {
+ mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+ return;
+ }
+ //
+ // Copy the old table into the new one
+ //
+ EfiCommonLibCopyMem (NewTable, Table, TableSize);
+ //
+ // Free the old table
+ //
+ CoreFreePool (Table);
+ //
+ // Update the table header
+ //
+ Table = NewTable;
+ mDebugInfoTableHeader.EfiDebugImageInfoTable = NewTable;
+ mDebugInfoTableHeader.TableSize += EFI_PAGE_SIZE / EFI_DEBUG_TABLE_ENTRY_SIZE;
+ }
+ //
+ // Allocate data for new entry
+ //
+ Table[Index].NormalImage = CoreAllocateZeroBootServicesPool (sizeof (EFI_DEBUG_IMAGE_INFO_NORMAL));
+ if (Table[Index].NormalImage != NULL) {
+ //
+ // Update the entry
+ //
+ Table[Index].NormalImage->ImageInfoType = ImageInfoType;
+ Table[Index].NormalImage->LoadedImageProtocolInstance = LoadedImage;
+ Table[Index].NormalImage->ImageHandle = ImageHandle;
+ }
+ mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+}
+
+
+VOID
+CoreRemoveDebugImageInfoEntry (
+ EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Removes and frees an entry from the DebugImageInfo Table.
+
+Arguments:
+
+ ImageHandle - image handle for the image being unloaded
+
+Returns:
+
+ NA
+
+--*/
+{
+ EFI_DEBUG_IMAGE_INFO *Table;
+ UINTN Index;
+
+ mDebugInfoTableHeader.UpdateStatus |= EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+
+ Table = mDebugInfoTableHeader.EfiDebugImageInfoTable;
+
+ for (Index = 0; Index < mDebugInfoTableHeader.TableSize; Index++) {
+ if (Table[Index].NormalImage != NULL && Table[Index].NormalImage->ImageHandle == ImageHandle) {
+ //
+ // Found a match. Free up the record, then NULL the pointer to indicate the slot
+ // is free.
+ //
+ CoreFreePool (Table[Index].NormalImage);
+ Table[Index].NormalImage = NULL;
+ break;
+ }
+ }
+ mDebugInfoTableHeader.UpdateStatus &= ~EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS;
+}
+
diff --git a/Core/CORE_DXE/DebugImageInfo.h b/Core/CORE_DXE/DebugImageInfo.h
new file mode 100644
index 0000000..a4e86e7
--- /dev/null
+++ b/Core/CORE_DXE/DebugImageInfo.h
@@ -0,0 +1,129 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DebugImageInfo.h
+
+Abstract:
+
+ Support functions for managing debug image info table when loading and unloading
+ images.
+
+--*/
+
+#ifndef __DEBUG_IMAGE_INFO_H__
+#define __DEBUG_IMAGE_INFO_H__
+
+#include EFI_PROTOCOL_DEFINITION(LoadedImage)
+#include EFI_GUID_DEFINITION(DebugImageInfoTable)
+
+#define FOUR_MEG_PAGES 0x400
+#define FOUR_MEG_MASK ((FOUR_MEG_PAGES * EFI_PAGE_SIZE) - 1)
+
+#define EFI_DEBUG_TABLE_ENTRY_SIZE (sizeof (VOID *))
+
+VOID
+CoreInitializeDebugImageInfoTable (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Creates and initializes the DebugImageInfo Table. Also creates the configuration
+ table and registers it into the system table.
+
+Arguments:
+ None
+
+Returns:
+ NA
+
+Notes:
+ This function allocates memory, frees it, and then allocates memory at an
+ address within the initial allocation. Since this function is called early
+ in DXE core initialization (before drivers are dispatched), this should not
+ be a problem.
+
+--*/
+;
+
+VOID
+CoreUpdateDebugTableCrc32 (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Update the CRC32 in the Debug Table.
+ Since the CRC32 service is made available by the Runtime driver, we have to
+ wait for the Runtime Driver to be installed before the CRC32 can be computed.
+ This function is called elsewhere by the core when the runtime architectural
+ protocol is produced.
+
+Arguments:
+ None
+
+Returns:
+ NA
+
+--*/
+;
+
+VOID
+CoreNewDebugImageInfoEntry (
+ UINT32 ImageInfoType,
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage,
+ EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Adds a new DebugImageInfo structure to the DebugImageInfo Table. Re-Allocates
+ the table if it's not large enough to accomidate another entry.
+
+Arguments:
+
+ ImageInfoType - type of debug image information
+ LoadedImage - pointer to the loaded image protocol for the image being loaded
+ ImageHandle - image handle for the image being loaded
+
+Returns:
+ NA
+
+--*/
+;
+
+VOID
+CoreRemoveDebugImageInfoEntry (
+ EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Removes and frees an entry from the DebugImageInfo Table.
+
+Arguments:
+
+ ImageHandle - image handle for the image being unloaded
+
+Returns:
+
+ NA
+
+--*/
+;
+
+#endif
diff --git a/Core/CORE_DXE/DebugMask.c b/Core/CORE_DXE/DebugMask.c
new file mode 100644
index 0000000..f9b0cf4
--- /dev/null
+++ b/Core/CORE_DXE/DebugMask.c
@@ -0,0 +1,399 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DebugMask.c
+
+Abstract:
+
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "DebugMask.h"
+#include EFI_GUID_DEFINITION (GenericVariable)
+
+extern UINTN mErrorLevel;
+static VOID *mVariableReadyNotify;
+
+VOID
+EFIAPI
+UpdateDebugMask (
+ EFI_EVENT Event,
+ VOID *Context
+ );
+
+EFI_STATUS
+EFIAPI
+GetDebugMask (
+ IN EFI_DEBUG_MASK_PROTOCOL *This, // Calling context
+ IN OUT UINTN *CurrentDebugMask // Ptr to store current debug mask
+ )
+/*++
+
+Routine Description:
+ DebugMask protocol member function.
+ Gets the current debug mask for an image, on which this protocol has been installed.
+
+Arguments:
+
+ This - Indicates calling context
+ CurrentDebugMask - Ptr to store current debug mask
+
+Returns:
+ EFI_SUCCESS - Debug mask is retrieved successfully
+ EFI_INVALID_PARAMETER - CurrentDebugMask is NULL.
+ EFI_UNSUPPORTED - The handle on which this protocol is installed is not an image handle.
+
+--*/
+{
+ DEBUG_MASK_PRIVATE_DATA *Private;
+ //
+ // Check Parameter
+ //
+ if (CurrentDebugMask == NULL){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Get Private Data
+ //
+ Private = DEBUG_MASK_PRIVATE_DATA_FROM_THIS(This);
+ *CurrentDebugMask = Private->ImageDebugMask;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+SetDebugMask (
+ IN EFI_DEBUG_MASK_PROTOCOL *This, // Calling context
+ IN UINTN NewDebugMask // New Debug Mask value to set
+ )
+/*++
+
+Routine Description:
+ DebugMask protocol member function.
+ Updates the current debug mask for an image, on which this protocol has been installed.
+
+Arguments:
+
+ This - Calling context
+ NewDebugMask - New Debug Mask value to set
+
+Returns:
+ EFI_SUCCESS - Debug mask is updated with the new value successfully
+ EFI_UNSUPPORTED - The handle on which this protocol is installed is not an image handle.
+
+--*/
+{
+ DEBUG_MASK_PRIVATE_DATA *Private;
+ //
+ // Set Private Data
+ //
+ Private = DEBUG_MASK_PRIVATE_DATA_FROM_THIS(This);
+ Private->ImageDebugMask = NewDebugMask;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+SetCoreDebugMask (
+ IN EFI_DEBUG_MASK_PROTOCOL *This, // Calling context
+ IN UINTN NewDebugMask // New Debug Mask value to set
+ )
+/*++
+
+Routine Description:
+ DebugMask protocol member function.
+ Updates the current debug mask for core.
+
+Arguments:
+
+ This - Calling context
+ NewDebugMask - New Debug Mask value to set
+
+Returns:
+ EFI_SUCCESS - Debug mask is updated with the new value successfully
+ EFI_UNSUPPORTED - The handle on which this protocol is installed is not an image handle.
+
+--*/
+{
+ mErrorLevel = NewDebugMask;
+ return SetDebugMask(This, NewDebugMask);
+}
+
+EFI_STATUS
+InstallDebugMaskProtocol(
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Install debug mask protocol on an image handle.
+
+Arguments:
+
+ ImageHandle - Image handle which debug mask protocol will install on
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid image handle
+
+ EFI_OUT_OF_RESOURCES - No enough buffer could be allocated
+
+ EFI_SUCCESS - Debug mask protocol successfully installed
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadImageInterface;
+ DEBUG_MASK_PRIVATE_DATA *DebugMaskPrivate;
+
+ if (ImageHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Check Image Handle
+ //
+ Status = CoreHandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID*)&LoadImageInterface
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Create Pool for Private Data
+ //
+ DebugMaskPrivate = CoreAllocateZeroBootServicesPool (sizeof (DEBUG_MASK_PRIVATE_DATA));
+
+ if (DebugMaskPrivate == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Fill in private data structure
+ //
+ DebugMaskPrivate->Signature = DEBUGMASK_PRIVATE_DATA_SIGNATURE;
+ DebugMaskPrivate->ImageDebugMask = mErrorLevel;
+ DebugMaskPrivate->DebugMaskInterface.Revision = EFI_DEBUG_MASK_REVISION;
+ DebugMaskPrivate->DebugMaskInterface.GetDebugMask = GetDebugMask;
+ DebugMaskPrivate->DebugMaskInterface.SetDebugMask = SetDebugMask;
+ //
+ // Install Debug Mask Protocol in Image Handle
+ //
+ Status = CoreInstallProtocolInterface (
+ &ImageHandle,
+ &gEfiDebugMaskProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(DebugMaskPrivate->DebugMaskInterface)
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+UninstallDebugMaskProtocol(
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Uninstall debug mask protocol on an image handle.
+
+Arguments:
+
+ ImageHandle - Image handle which debug mask protocol will uninstall on
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid image handle
+
+ EFI_SUCCESS - Debug mask protocol successfully uninstalled
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEBUG_MASK_PROTOCOL *DebugMaskInterface;
+ DEBUG_MASK_PRIVATE_DATA *DebugMaskPrivate;
+
+ if (ImageHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Get Protocol from ImageHandle
+ //
+ Status = CoreHandleProtocol (
+ ImageHandle,
+ &gEfiDebugMaskProtocolGuid,
+ (VOID*)&DebugMaskInterface
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DebugMaskPrivate = DEBUG_MASK_PRIVATE_DATA_FROM_THIS(DebugMaskInterface);
+ //
+ // Remove Protocol from ImageHandle
+ //
+ Status = CoreUninstallProtocolInterface (
+ ImageHandle,
+ &gEfiDebugMaskProtocolGuid,
+ (VOID*)DebugMaskInterface
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Free Private Data Pool
+ //
+ Status = CoreFreePool(DebugMaskPrivate);
+ return Status;
+}
+
+EFI_STATUS
+InstallCoreDebugMaskProtocol(
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Install debug mask protocol on core.
+
+Arguments:
+
+ ImageHandle - Core handle
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid image handle
+
+ EFI_OUT_OF_RESOURCES - No enough buffer could be allocated
+
+ EFI_SUCCESS - Debug mask protocol successfully installed
+
+--*/
+{
+ EFI_DEBUG_MASK_PROTOCOL *DebugMaskInterface;
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ if (ImageHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = InstallDebugMaskProtocol(ImageHandle);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Check Image Handle
+ //
+ CoreHandleProtocol (
+ ImageHandle,
+ &gEfiDebugMaskProtocolGuid,
+ (VOID*)&DebugMaskInterface
+ );
+ DebugMaskInterface->SetDebugMask = SetCoreDebugMask;
+
+ Status = CoreCreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ UpdateDebugMask,
+ mVariableReadyNotify,
+ &Event
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = CoreRegisterProtocolNotify (
+ &gEfiVariableArchProtocolGuid,
+ Event,
+ &mVariableReadyNotify
+ );
+ }
+
+ return Status;
+}
+
+VOID
+EFIAPI
+UpdateDebugMask (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Event callback function to update the debug mask when the variable service is ready.
+
+Arguments:
+
+ Event - The Event
+ Context - The event's context
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN NoHandles;
+ EFI_STATUS Status;
+ UINTN DebugMask;
+ UINTN Index;
+ UINTN DataSize;
+ EFI_HANDLE *Buffer;
+ EFI_DEBUG_MASK_PROTOCOL *DebugMaskProtocol;
+
+ DataSize = sizeof(UINTN);
+ Status = gRT->GetVariable(
+ L"EFIDebug",
+ &gEfiGenericVariableGuid,
+ NULL,
+ &DataSize,
+ &DebugMask
+ );
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ Status = CoreLocateHandleBuffer (
+ AllHandles,
+ &gEfiDebugMaskProtocolGuid,
+ NULL,
+ &NoHandles,
+ &Buffer
+ );
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ for (Index = 0; Index < NoHandles; Index ++) {
+ Status = CoreHandleProtocol (
+ Buffer[Index],
+ &gEfiDebugMaskProtocolGuid,
+ &DebugMaskProtocol
+ );
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+ DebugMaskProtocol->SetDebugMask(DebugMaskProtocol, DebugMask);
+ }
+ CoreFreePool(Buffer);
+}
diff --git a/Core/CORE_DXE/DebugMask.h b/Core/CORE_DXE/DebugMask.h
new file mode 100644
index 0000000..18dbef5
--- /dev/null
+++ b/Core/CORE_DXE/DebugMask.h
@@ -0,0 +1,122 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DebugMask.h
+
+Abstract:
+
+
+--*/
+
+#ifndef __DEBUG_MASK_INFO_H__
+#define __DEBUG_MASK_INFO_H__
+
+#include EFI_PROTOCOL_CONSUMER (DebugMask)
+
+//
+// local type definitions
+//
+#define DEBUGMASK_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32('D','M','S','K')
+
+//
+// Private structure used by driver
+//
+typedef struct {
+ UINT32 Signature;
+ UINTN ImageDebugMask;
+ EFI_DEBUG_MASK_PROTOCOL DebugMaskInterface;
+}DEBUG_MASK_PRIVATE_DATA;
+
+#define DEBUG_MASK_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, DEBUG_MASK_PRIVATE_DATA, DebugMaskInterface, DEBUGMASK_PRIVATE_DATA_SIGNATURE)
+
+//
+// Internal DebugMask Procotol Install/Uninstall Function
+//
+EFI_STATUS
+InstallDebugMaskProtocol (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Install debug mask protocol on an image handle.
+
+Arguments:
+
+ ImageHandle - Image handle which debug mask protocol will install on
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid image handle
+
+ EFI_OUT_OF_RESOURCES - No enough buffer could be allocated
+
+ EFI_SUCCESS - Debug mask protocol successfully installed
+
+--*/
+;
+
+//
+// Internal DebugMask Procotol Install/Uninstall Function
+//
+EFI_STATUS
+InstallCoreDebugMaskProtocol (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Install debug mask protocol on Dxe Core.
+
+Arguments:
+
+ ImageHandle - Image handle which debug mask protocol will install on
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid image handle
+
+ EFI_OUT_OF_RESOURCES - No enough buffer could be allocated
+
+ EFI_SUCCESS - Debug mask protocol successfully installed
+
+--*/
+;
+
+EFI_STATUS
+UninstallDebugMaskProtocol (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Uninstall debug mask protocol on an image handle.
+
+Arguments:
+
+ ImageHandle - Image handle which debug mask protocol will uninstall on
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid image handle
+
+ EFI_SUCCESS - Debug mask protocol successfully uninstalled
+
+--*/
+;
+
+#endif
diff --git a/Core/CORE_DXE/DevicePath.h b/Core/CORE_DXE/DevicePath.h
new file mode 100644
index 0000000..1f0afcc
--- /dev/null
+++ b/Core/CORE_DXE/DevicePath.h
@@ -0,0 +1,470 @@
+/** @file
+ Definition for Device Path Utilities driver
+
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef _DEVICE_PATH_DRIVER_H_
+#define _DEVICE_PATH_DRIVER_H_
+
+#include <Tiano.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePathFromText.h>
+
+
+#define MAX_CHAR 480
+
+#define IS_COMMA(a) ((a) == L',')
+#define IS_HYPHEN(a) ((a) == L'-')
+#define IS_DOT(a) ((a) == L'.')
+#define IS_LEFT_PARENTH(a) ((a) == L'(')
+#define IS_RIGHT_PARENTH(a) ((a) == L')')
+#define IS_SLASH(a) ((a) == L'/')
+#define IS_NULL(a) ((a) == L'\0')
+
+
+#define SET_DEVICE_PATH_INSTANCE_END_NODE(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof (EFI_DEVICE_PATH_PROTOCOL); \
+ (a)->Length[1] = 0; \
+ }
+
+#define BBS_TYPE_FLOPPY 0x01
+#define BBS_TYPE_HARDDRIVE 0x02
+#define BBS_TYPE_CDROM 0x03
+#define BBS_TYPE_PCMCIA 0x04
+#define BBS_TYPE_USB 0x05
+#define BBS_TYPE_EMBEDDED_NETWORK 0x06
+#define BBS_TYPE_BEV 0x80
+#define BBS_TYPE_UNKNOWN 0xFF
+
+#pragma pack (push, 1)
+
+typedef struct {
+ UINT8 Addr[4];
+} EFI_IPV4_ADDRESS;
+
+typedef struct{
+ UINT8 Addr[16];
+} EFI_IPV6_ADDRESS;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_IPV4_ADDRESS LocalIpAddress;
+ EFI_IPV4_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ BOOLEAN StaticIpAddress;
+ EFI_IPV4_ADDRESS GatewayIpAddress;
+ EFI_IPV4_ADDRESS SubnetMask;
+} IPV4_DEVICE_PATH;
+
+//Messaging Device Path Type
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_IPV6_ADDRESS LocalIpAddress;
+ EFI_IPV6_ADDRESS RemoteIpAddress;
+ UINT16 LocalPort;
+ UINT16 RemotePort;
+ UINT16 Protocol;
+ UINT8 IpAddressOrigin;
+ UINT8 PrefixLength;
+ EFI_IPV6_ADDRESS GatewayIpAddress;
+} IPV6_DEVICE_PATH;
+
+#pragma pack (pop)
+
+//
+// Private Data structure
+//
+typedef struct {
+ CHAR16 *Str;
+ UINTN Len;
+ UINTN MaxLen;
+} POOL_PRINT;
+
+typedef
+EFI_DEVICE_PATH_PROTOCOL *
+(*DUMP_NODE) (
+ IN CHAR16 *DeviceNodeStr
+ );
+
+typedef
+VOID
+(*DEVICE_PATH_TO_TEXT_FUNC) (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+typedef struct {
+ UINT8 Type;
+ UINT8 SubType;
+ DEVICE_PATH_TO_TEXT_FUNC Function;
+} DEVICE_PATH_TO_TEXT_TABLE;
+
+typedef struct {
+ CHAR16 *DevicePathNodeText;
+ DUMP_NODE Function;
+} DEVICE_PATH_FROM_TEXT_TABLE;
+
+typedef struct {
+ BOOLEAN ClassExist;
+ UINT8 Class;
+ BOOLEAN SubClassExist;
+ UINT8 SubClass;
+} USB_CLASS_TEXT;
+
+#define USB_CLASS_AUDIO 1
+#define USB_CLASS_CDCCONTROL 2
+#define USB_CLASS_HID 3
+#define USB_CLASS_IMAGE 6
+#define USB_CLASS_PRINTER 7
+#define USB_CLASS_MASS_STORAGE 8
+#define USB_CLASS_HUB 9
+#define USB_CLASS_CDCDATA 10
+#define USB_CLASS_SMART_CARD 11
+#define USB_CLASS_VIDEO 14
+#define USB_CLASS_DIAGNOSTIC 220
+#define USB_CLASS_WIRELESS 224
+
+#define USB_CLASS_RESERVE 254
+#define USB_SUBCLASS_FW_UPDATE 1
+#define USB_SUBCLASS_IRDA_BRIDGE 2
+#define USB_SUBCLASS_TEST 3
+
+#define RFC_1700_UDP_PROTOCOL 17
+#define RFC_1700_TCP_PROTOCOL 6
+
+#pragma pack(1)
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_HARDWARE_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MESSAGING_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEFINED_MEDIA_DEVICE_PATH;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Hid;
+ UINT32 Uid;
+ UINT32 Cid;
+ CHAR8 HidUidCidStr[3];
+} ACPI_EXTENDED_HID_DEVICE_PATH_WITH_STR;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT16 NetworkProtocol;
+ UINT16 LoginOption;
+ UINT64 Lun;
+ UINT16 TargetPortalGroupTag;
+ CHAR8 TargetName[1];
+} ISCSI_DEVICE_PATH_WITH_NAME;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ EFI_GUID Guid;
+ UINT8 VendorDefinedData[1];
+} VENDOR_DEVICE_PATH_WITH_DATA;
+
+#pragma pack()
+
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ );
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ );
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure specified by
+ DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @return The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+GetDevicePathSizeProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath. If
+ DevicePath is NULL, then NULL is returned. If the memory is successfully allocated, then the
+ contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer
+ is returned. Otherwise, NULL is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @return A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DuplicateDevicePathProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath to a copy of
+ FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from
+ SecondDevicePath is retained. The newly created device path is returned.
+ If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned.
+ If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned.
+ If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is
+ returned.
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory. It is the
+ responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
+ );
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node specified by
+ DevicePathNode to a copy of the device path specified by DevicePath in an allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device path device
+ node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path device node
+ is returned.
+ If there is not enough memory to allocate space for the new device path, then NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+ free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDeviceNodeProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+ );
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path instance specified
+ by DevicePathInstance to a copy of the device path specified by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device path instance
+ and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+ free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathInstanceProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates DevicePath to
+ point to the next device path instance in the device path (or NULL if no more) and updates Size
+ to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+ free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current device path
+ instance. On output, this holds the pointer to the next device
+ path instance or NULL if there are no more device path
+ instances in the device path pointer to a device path data
+ structure.
+ @param Size On output, this holds the size of the device path instance, in
+ bytes or zero, if DevicePath is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+GetNextDevicePathInstanceProtocolInterface (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT UINTN *Size
+ );
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is multi-instance.
+ Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance or DevicePath is NULL.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathMultiInstanceProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a new device node in a newly allocated buffer of size NodeLength and
+ initializes the device path node header with NodeType and NodeSubType. The new device path node
+ is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
+ free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+CreateDeviceNodeProtocolInterface (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ );
+
+#endif
diff --git a/Core/CORE_DXE/DevicePathFromText.c b/Core/CORE_DXE/DevicePathFromText.c
new file mode 100644
index 0000000..5f4e4d1
--- /dev/null
+++ b/Core/CORE_DXE/DevicePathFromText.c
@@ -0,0 +1,3310 @@
+/** @file
+ DevicePathFromText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "DevicePath.h"
+#include "EdkIICommon.h"
+
+
+UINT64
+LShiftU64 (
+ IN UINT64 Operand,
+ IN UINTN Count
+ );
+
+VOID*
+DPCreateNode (
+ IN UINT8 Type,
+ IN UINT8 SubType,
+ IN UINT16 Length
+ );
+
+VOID*
+DPAddNode (
+ IN EFI_DEVICE_PATH_PROTOCOL *pDp1,
+ IN EFI_DEVICE_PATH_PROTOCOL *pDp2
+ );
+
+EFI_STATUS
+HexStringToBuf (
+ IN OUT UINT8 *Buf,
+ IN OUT UINTN *Len,
+ IN CHAR16 *Str,
+ OUT UINTN *ConvertedStrLen OPTIONAL
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ IN UINT8 Type,
+ IN UINT8 SubType,
+ IN UINT16 Length
+ )
+{
+ return (EFI_DEVICE_PATH_PROTOCOL *) DPCreateNode(Type, SubType, Length);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNodeProtocolInterface (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+ )
+{
+ return (EFI_DEVICE_PATH_PROTOCOL *) DPAddNode (
+ (EFI_DEVICE_PATH_PROTOCOL *)DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)DevicePathNode );
+}
+
+
+/**
+
+ Duplicates a string.
+
+ @param Src Source string.
+
+ @return The duplicated string.
+
+**/
+CHAR16 *
+StrDuplicate (
+ IN CONST CHAR16 *Src
+ )
+{
+ return AllocateCopyPool (StrSize ((CHAR16 *)Src), Src);
+}
+
+/**
+
+ Get parameter in a pair of parentheses follow the given node name.
+ For example, given the "Pci(0,1)" and NodeName "Pci", it returns "0,1".
+
+ @param Str Device Path Text.
+ @param NodeName Name of the node.
+
+ @return Parameter text for the node.
+
+**/
+CHAR16 *
+GetParamByNodeName (
+ IN CHAR16 *Str,
+ IN CHAR16 *NodeName
+ )
+{
+ CHAR16 *ParamStr;
+ CHAR16 *StrPointer;
+ UINTN NodeNameLength;
+ UINTN ParameterLength;
+
+ //
+ // Check whether the node name matchs
+ //
+ NodeNameLength = StrLen (NodeName);
+ if (CompareMem (Str, NodeName, NodeNameLength * sizeof (CHAR16)) != 0) {
+ return NULL;
+ }
+
+ ParamStr = Str + NodeNameLength;
+ if (!IS_LEFT_PARENTH (*ParamStr)) {
+ return NULL;
+ }
+
+ //
+ // Skip the found '(' and find first occurrence of ')'
+ //
+ ParamStr++;
+ ParameterLength = 0;
+ StrPointer = ParamStr;
+ while (!IS_NULL (*StrPointer)) {
+ if (IS_RIGHT_PARENTH (*StrPointer)) {
+ break;
+ }
+ StrPointer++;
+ ParameterLength++;
+ }
+ if (IS_NULL (*StrPointer)) {
+ //
+ // ')' not found
+ //
+ return NULL;
+ }
+
+ ParamStr = AllocateCopyPool ((ParameterLength + 1) * sizeof (CHAR16), ParamStr);
+ if (ParamStr == NULL) {
+ return NULL;
+ }
+ //
+ // Terminate the parameter string
+ //
+ ParamStr[ParameterLength] = L'\0';
+
+ return ParamStr;
+}
+
+/**
+ Gets current sub-string from a string list, before return
+ the list header is moved to next sub-string. The sub-string is separated
+ by the specified character. For example, the separator is ',', the string
+ list is "2,0,3", it returns "2", the remain list move to "0,3"
+
+ @param List A string list separated by the specified separator
+ @param Separator The separator character
+
+ @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+SplitStr (
+ IN OUT CHAR16 **List,
+ IN CHAR16 Separator
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+
+ Str = *List;
+ ReturnStr = Str;
+
+ if (IS_NULL (*Str)) {
+ return ReturnStr;
+ }
+
+ //
+ // Find first occurrence of the separator
+ //
+ while (!IS_NULL (*Str)) {
+ if (*Str == Separator) {
+ break;
+ }
+ Str++;
+ }
+
+ if (*Str == Separator) {
+ //
+ // Find a sub-string, terminate it
+ //
+ *Str = L'\0';
+ Str++;
+ }
+
+ //
+ // Move to next sub-string
+ //
+ *List = Str;
+
+ return ReturnStr;
+}
+
+/**
+ Gets the next parameter string from the list.
+
+ @param List A string list separated by the specified separator
+
+ @return A pointer to the current sub-string
+
+**/
+CHAR16 *
+GetNextParamStr (
+ IN OUT CHAR16 **List
+ )
+{
+ //
+ // The separator is comma
+ //
+ return SplitStr (List, L',');
+}
+
+/**
+ Get one device node from entire device path text.
+
+ @param DevicePath On input, the current Device Path node; on output, the next device path node
+ @param IsInstanceEnd This node is the end of a device path instance
+
+ @return A device node text or NULL if no more device node available
+
+**/
+CHAR16 *
+GetNextDeviceNodeStr (
+ IN OUT CHAR16 **DevicePath,
+ OUT BOOLEAN *IsInstanceEnd
+ )
+{
+ CHAR16 *Str;
+ CHAR16 *ReturnStr;
+ UINTN ParenthesesStack;
+
+ Str = *DevicePath;
+ if (IS_NULL (*Str)) {
+ return NULL;
+ }
+
+ //
+ // Skip the leading '/', '(', ')' and ','
+ //
+ while (!IS_NULL (*Str)) {
+ if (!IS_SLASH (*Str) &&
+ !IS_COMMA (*Str) &&
+ !IS_LEFT_PARENTH (*Str) &&
+ !IS_RIGHT_PARENTH (*Str)) {
+ break;
+ }
+ Str++;
+ }
+
+ ReturnStr = Str;
+
+ //
+ // Scan for the separator of this device node, '/' or ','
+ //
+ ParenthesesStack = 0;
+ while (!IS_NULL (*Str)) {
+ if ((IS_COMMA (*Str) || IS_SLASH (*Str)) && (ParenthesesStack == 0)) {
+ break;
+ }
+
+ if (IS_LEFT_PARENTH (*Str)) {
+ ParenthesesStack++;
+ } else if (IS_RIGHT_PARENTH (*Str)) {
+ ParenthesesStack--;
+ }
+
+ Str++;
+ }
+
+ if (ParenthesesStack != 0) {
+ //
+ // The '(' doesn't pair with ')', invalid device path text
+ //
+ return NULL;
+ }
+
+ if (IS_COMMA (*Str)) {
+ *IsInstanceEnd = TRUE;
+ *Str = L'\0';
+ Str++;
+ } else {
+ *IsInstanceEnd = FALSE;
+ if (!IS_NULL (*Str)) {
+ *Str = L'\0';
+ Str++;
+ }
+ }
+
+ *DevicePath = Str;
+
+ return ReturnStr;
+}
+
+
+/**
+ Skip the leading white space and '0x' or '0X' of a integer string
+
+ @param Str The integer string
+ @param IsHex TRUE: Hex string, FALSE: Decimal string
+
+ @return The trimmed Hex string.
+
+**/
+CHAR16 *
+TrimHexStr (
+ IN CHAR16 *Str,
+ OUT BOOLEAN *IsHex
+ )
+{
+ *IsHex = FALSE;
+
+ //
+ // skip preceeding white space
+ //
+ while ((*Str != 0) && *Str == ' ') {
+ Str += 1;
+ }
+ //
+ // skip preceeding zeros
+ //
+ while ((*Str != 0) && *Str == '0') {
+ Str += 1;
+ }
+ //
+ // skip preceeding character 'x' or 'X'
+ //
+ if ((*Str != 0) && (*Str == 'x' || *Str == 'X')) {
+ Str += 1;
+ *IsHex = TRUE;
+ }
+
+ return Str;
+}
+
+/**
+
+ Convert hex string to uint.
+
+ @param Str The hex string
+
+ @return A UINTN value represented by Str
+
+**/
+UINTN
+Xtoi (
+ IN CHAR16 *Str
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINTN Result = 0;
+ UINTN Length = sizeof(UINTN);
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*Str == L' ') || (*Str == L'\t')) {
+ Str++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*Str == L'0') {
+ Str++;
+ }
+
+ if ((*Str == L'X') || (*Str == L'x')) {
+ if (*(Str - 1) != L'0') {
+ return 0;
+ }
+ //
+ // Skip the 'X'
+ //
+ Str++;
+ }
+
+ Buffer = (UINT8 *)&Result;
+ Status = HexStringToBuf(Buffer, &Length, Str, NULL);
+ if(EFI_ERROR(Status))
+ return ~0;
+
+ return Result;
+}
+
+/**
+
+ Convert hex string to 64 bit data.
+
+ @param Str The hex string
+ @param Data A pointer to the UINT64 value represented by Str
+
+**/
+VOID
+Xtoi64 (
+ IN CHAR16 *Str,
+ OUT UINT64 *Data
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ UINT64 Result = 0;
+ UINTN Length = 8;
+
+ //
+ // Ignore the pad spaces (space or tab)
+ //
+ while ((*Str == L' ') || (*Str == L'\t')) {
+ Str++;
+ }
+
+ //
+ // Ignore leading Zeros after the spaces
+ //
+ while (*Str == L'0') {
+ Str++;
+ }
+
+ if ((*Str == L'X') || (*Str == L'x')) {
+ if (*(Str - 1) != L'0') {
+ *Data = 0;
+ return;
+ }
+ //
+ // Skip the 'X'
+ //
+ Str++;
+ }
+
+ Buffer = (UINT8 *)&Result;
+ Status = HexStringToBuf(Buffer, &Length, Str, NULL);
+
+ *Data = (EFI_ERROR(Status)) ? ~0 : Result;
+}
+
+/**
+
+ Convert decimal string to uint.
+
+ @param Str The decimal string
+
+ @return A UINTN value represented by Str
+
+**/
+UINTN
+Dtoi (
+ IN CHAR16 *Str
+ )
+{
+ UINTN Rvalue;
+ CHAR16 Char;
+ UINTN High;
+ UINTN Low;
+
+ ASSERT (Str != NULL);
+
+ High = (UINTN) -1 / 10;
+ Low = (UINTN) -1 % 10;
+ //
+ // skip preceeding white space
+ //
+ while ((*Str != 0) && *Str == ' ') {
+ Str += 1;
+ }
+ //
+ // convert digits
+ //
+ Rvalue = 0;
+ Char = *(Str++);
+ while (Char != 0) {
+ if (Char >= '0' && Char <= '9') {
+ if ((Rvalue > High || Rvalue == High) && (Char - '0' > (INTN) Low)) {
+ return (UINTN) -1;
+ }
+
+ Rvalue = (Rvalue * 10) + Char - '0';
+ } else {
+ break;
+ }
+
+ Char = *(Str++);
+ }
+
+ return Rvalue;
+}
+
+/**
+
+ Convert decimal string to uint.
+
+ @param Str The decimal string
+ @param Data A pointer to the UINT64 value represented by Str
+
+**/
+VOID
+Dtoi64 (
+ IN CHAR16 *Str,
+ OUT UINT64 *Data
+ )
+{
+ UINT64 Rvalue;
+ CHAR16 Char;
+ UINT64 High;
+ UINT64 Low;
+
+ ASSERT (Str != NULL);
+ ASSERT (Data != NULL);
+
+ //
+ // skip preceeding white space
+ //
+ while ((*Str != 0) && *Str == ' ') {
+ Str += 1;
+ }
+ //
+ // convert digits
+ //
+ Rvalue = 0;
+ Char = *(Str++);
+ while (Char != 0) {
+ if (Char >= '0' && Char <= '9') {
+ High = LShiftU64 (Rvalue, 3);
+ Low = LShiftU64 (Rvalue, 1);
+ Rvalue = High + Low + Char - '0';
+ } else {
+ break;
+ }
+
+ Char = *(Str++);
+ }
+
+ *Data = Rvalue;
+}
+
+/**
+
+ Convert integer string to uint.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+
+ @return A UINTN value represented by Str
+
+**/
+UINTN
+Strtoi (
+ IN CHAR16 *Str
+ )
+{
+ BOOLEAN IsHex;
+
+ Str = TrimHexStr (Str, &IsHex);
+
+ if (IsHex) {
+ return Xtoi (Str);
+ } else {
+ return Dtoi (Str);
+ }
+}
+
+/**
+
+ Convert integer string to 64 bit data.
+
+ @param Str The integer string. If leading with "0x" or "0X", it's hexadecimal.
+ @param Data A pointer to the UINT64 value represented by Str
+
+**/
+VOID
+Strtoi64 (
+ IN CHAR16 *Str,
+ OUT UINT64 *Data
+ )
+{
+ BOOLEAN IsHex;
+
+ Str = TrimHexStr (Str, &IsHex);
+
+ if (IsHex) {
+ Xtoi64 (Str, Data);
+ } else {
+ Dtoi64 (Str, Data);
+ }
+}
+
+/**
+ Converts a list of string to a specified buffer.
+
+ @param Buf The output buffer that contains the string.
+ @param BufferLength The length of the buffer
+ @param Str The input string that contains the hex number
+
+ @retval EFI_SUCCESS The string was successfully converted to the buffer.
+
+**/
+EFI_STATUS
+StrToBuf (
+ OUT UINT8 *Buf,
+ IN UINTN BufferLength,
+ IN CHAR16 *Str
+ )
+{
+ UINTN Index;
+ UINTN StrLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ Digit = 0;
+
+ //
+ // Two hex char make up one byte
+ //
+ StrLength = BufferLength * sizeof (CHAR16);
+
+ for(Index = 0; Index < StrLength; Index++, Str++) {
+
+ if ((*Str >= L'a') && (*Str <= L'f')) {
+ Digit = (UINT8) (*Str - L'a' + 0x0A);
+ } else if ((*Str >= L'A') && (*Str <= L'F')) {
+ Digit = (UINT8) (*Str - L'A' + 0x0A);
+ } else if ((*Str >= L'0') && (*Str <= L'9')) {
+ Digit = (UINT8) (*Str - L'0');
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // For odd characters, write the upper nibble for each buffer byte,
+ // and for even characters, the lower nibble.
+ //
+ if ((Index & 1) == 0) {
+ Byte = (UINT8) (Digit << 4);
+ } else {
+ Byte = Buf[Index / 2];
+ Byte &= 0xF0;
+ Byte = (UINT8) (Byte | Digit);
+ }
+
+ Buf[Index / 2] = Byte;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Converts a string to GUID value.
+ Guid Format is xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
+
+ @param Str The registry format GUID string that contains the GUID value.
+ @param Guid A pointer to the converted GUID value.
+
+ @retval EFI_SUCCESS The GUID string was successfully converted to the GUID value.
+ @retval EFI_UNSUPPORTED The input string is not in registry format.
+ @return others Some error occurred when converting part of GUID value.
+
+**/
+EFI_STATUS
+StrToGuid (
+ IN CHAR16 *Str,
+ OUT EFI_GUID *Guid
+ )
+{
+ //
+ // Get the first UINT32 data
+ //
+ Guid->Data1 = (UINT32) Xtoi (Str);
+ while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
+ Str ++;
+ }
+
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get the second UINT16 data
+ //
+ Guid->Data2 = (UINT16) Xtoi (Str);
+ while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
+ Str ++;
+ }
+
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get the third UINT16 data
+ //
+ Guid->Data3 = (UINT16) Xtoi (Str);
+ while (!IS_HYPHEN (*Str) && !IS_NULL (*Str)) {
+ Str ++;
+ }
+
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Get the following 8 bytes data
+ //
+ StrToBuf (&Guid->Data4[0], 2, Str);
+ //
+ // Skip 2 byte hex chars
+ //
+ Str += 2 * 2;
+
+ if (IS_HYPHEN (*Str)) {
+ Str++;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ StrToBuf (&Guid->Data4[2], 6, Str);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Converts a string to IPv4 address
+
+ @param Str A string representation of IPv4 address.
+ @param IPv4Addr A pointer to the converted IPv4 address.
+
+**/
+VOID
+StrToIPv4Addr (
+ IN OUT CHAR16 **Str,
+ OUT EFI_IPV4_ADDRESS *IPv4Addr
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < 4; Index++) {
+ IPv4Addr->Addr[Index] = (UINT8) Dtoi (SplitStr (Str, L'.'));
+ }
+}
+
+/**
+ Converts a string to IPv4 address
+
+ @param Str A string representation of IPv6 address.
+ @param IPv6Addr A pointer to the converted IPv6 address.
+
+**/
+VOID
+StrToIPv6Addr (
+ IN OUT CHAR16 **Str,
+ OUT EFI_IPV6_ADDRESS *IPv6Addr
+ )
+{
+ UINTN Index;
+ UINT16 Data;
+
+ for (Index = 0; Index < 8; Index++) {
+ Data = (UINT16) Xtoi (SplitStr (Str, L':'));
+ IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);
+ IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);
+ }
+}
+
+/**
+ Converts a Unicode string to ASCII string.
+
+ @param Str The equivalent Unicode string
+ @param AsciiStr On input, it points to destination ASCII string buffer; on output, it points
+ to the next ASCII string next to it
+
+**/
+VOID
+StrToAscii (
+ IN CHAR16 *Str,
+ IN OUT CHAR8 **AsciiStr
+ )
+{
+ CHAR8 *Dest;
+
+ Dest = *AsciiStr;
+ while (!IS_NULL (*Str)) {
+ *(Dest++) = (CHAR8) *(Str++);
+ }
+ *Dest = 0;
+
+ //
+ // Return the string next to it
+ //
+ *AsciiStr = Dest + 1;
+}
+
+/**
+ Swaps the byte order in given input
+
+ @param Input Byte order to swap
+
+ @return UINT64 value with swapped bytes
+
+**/
+UINT64
+SwapBytes64 (
+ IN UINT64 Input
+ )
+{
+ UINT64 Output = 0;
+ UINT8 *Inp;
+ UINT8 *Outp;
+
+ Inp = (UINT8 *) &Input;
+ Outp = (UINT8 *) &Output;
+
+ Outp[0] = Inp[7];
+ Outp[1] = Inp[6];
+ Outp[2] = Inp[5];
+ Outp[3] = Inp[4];
+ Outp[4] = Inp[3];
+ Outp[5] = Inp[2];
+ Outp[6] = Inp[1];
+ Outp[7] = Inp[0];
+
+ return Output;
+}
+
+/**
+ Converts a text device path node to Hardware PCI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PCI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPci (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionStr;
+ CHAR16 *DeviceStr;
+ PCI_DEVICE_PATH *Pci;
+
+ DeviceStr = GetNextParamStr (&TextDeviceNode);
+ FunctionStr = GetNextParamStr (&TextDeviceNode);
+ Pci = (PCI_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCI_DP,
+ sizeof (PCI_DEVICE_PATH)
+ );
+
+ Pci->Function = (UINT8) Strtoi (FunctionStr);
+ Pci->Device = (UINT8) Strtoi (DeviceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pci;
+}
+
+/**
+ Converts a text device path node to Hardware PC card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware PC card device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcCard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FunctionNumberStr;
+ PCCARD_DEVICE_PATH *Pccard;
+
+ FunctionNumberStr = GetNextParamStr (&TextDeviceNode);
+ Pccard = (PCCARD_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_PCCARD_DP,
+ sizeof (PCCARD_DEVICE_PATH)
+ );
+
+ Pccard->Function = (UINT8) Strtoi (FunctionNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Pccard;
+}
+
+/**
+ Converts a text device path node to Hardware memory map device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to Hardware memory map device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMemoryMapped (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *MemoryTypeStr;
+ CHAR16 *StartingAddressStr;
+ CHAR16 *EndingAddressStr;
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemoryTypeStr = GetNextParamStr (&TextDeviceNode);
+ StartingAddressStr = GetNextParamStr (&TextDeviceNode);
+ EndingAddressStr = GetNextParamStr (&TextDeviceNode);
+ MemMap = (MEMMAP_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ sizeof (MEMMAP_DEVICE_PATH)
+ );
+
+ MemMap->MemoryType = (UINT32) Strtoi (MemoryTypeStr);
+ Strtoi64 (StartingAddressStr, &MemMap->StartingAddress);
+ Strtoi64 (EndingAddressStr, &MemMap->EndingAddress);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MemMap;
+}
+
+/**
+ Converts a text device path node to Vendor device path structure based on the input Type
+ and SubType.
+
+ @param TextDeviceNode The input Text device path node.
+ @param Type The type of device path node.
+ @param SubType The subtype of device path node.
+
+ @return A pointer to the newly-created Vendor device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextVendor (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT8 Type,
+ IN UINT8 SubType
+ )
+{
+ CHAR16 *GuidStr;
+ CHAR16 *DataStr;
+ UINTN Length;
+ VENDOR_DEVICE_PATH *Vendor;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+
+ DataStr = GetNextParamStr (&TextDeviceNode);
+ Length = StrLen (DataStr);
+ //
+ // Two hex characters make up 1 buffer byte
+ //
+ Length = (Length + 1) / 2;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ Type,
+ SubType,
+ (UINT16) (sizeof (VENDOR_DEVICE_PATH) + Length)
+ );
+
+ StrToGuid (GuidStr, &Vendor->Guid);
+ StrToBuf (((UINT8 *) Vendor) + sizeof (VENDOR_DEVICE_PATH), Length, DataStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor Hardware device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor Hardware device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenHw (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Hardware Controller device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Hardware Controller device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCtrl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ControllerStr;
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ ControllerStr = GetNextParamStr (&TextDeviceNode);
+ Controller = (CONTROLLER_DEVICE_PATH *) CreateDeviceNode (
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ sizeof (CONTROLLER_DEVICE_PATH)
+ );
+ Controller->Controller = (UINT32) Strtoi (ControllerStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Controller;
+}
+
+/**
+ Converts a string to EisaId.
+
+ @param Text The input string.
+ @param EisaId A pointer to the output EisaId.
+
+**/
+VOID
+EisaIdFromText (
+ IN CHAR16 *Text,
+ OUT UINT32 *EisaId
+ )
+{
+ UINTN PnpId;
+
+ PnpId = Xtoi (Text + 3);
+ *EisaId = (((Text[0] - '@') & 0x1f) << 10) +
+ (((Text[1] - '@') & 0x1f) << 5) +
+ ((Text[2] - '@') & 0x1f) +
+ (UINT32) (PnpId << 16);
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ EisaIdFromText (HIDStr, &Acpi->HID);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to ACPI HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param PnPId The input plug and play identification.
+
+ @return A pointer to the newly-created ACPI HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextAcpi (
+ IN CHAR16 *TextDeviceNode,
+ IN UINT32 PnPId
+ )
+{
+ CHAR16 *UIDStr;
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ Acpi = (ACPI_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_DP,
+ sizeof (ACPI_HID_DEVICE_PATH)
+ );
+
+ Acpi->HID = EFI_PNP_ID (PnPId);
+ Acpi->UID = (UINT32) Strtoi (UIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
+}
+
+/**
+ Converts a text device path node to PCI root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCI root device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPciRoot (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a03);
+}
+
+/**
+ Converts a text device path node to PCIE root device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created PCIE root device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextPcieRoot (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0a08);
+}
+
+/**
+ Converts a text device path node to Floppy device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Floppy device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFloppy (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0604);
+}
+
+/**
+ Converts a text device path node to Keyboard device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Keyboard device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextKeyboard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0301);
+}
+
+/**
+ Converts a text device path node to Serial device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSerial (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0501);
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextParallelPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextAcpi (TextDeviceNode, 0x0401);
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDStr;
+ CHAR16 *HIDSTRStr;
+ CHAR16 *CIDSTRStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDStr = GetNextParamStr (&TextDeviceNode);
+ HIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ CIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (HIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (UIDSTRStr) + 1);
+ Length = (UINT16) (Length + StrLen (CIDSTRStr) + 1);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ EisaIdFromText (HIDStr, &AcpiEx->HID);
+ EisaIdFromText (CIDStr, &AcpiEx->CID);
+ AcpiEx->UID = (UINT32) Strtoi (UIDStr);
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ StrToAscii (HIDSTRStr, &AsciiStr);
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ StrToAscii (CIDSTRStr, &AsciiStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI extension device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI extension device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiExp (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *HIDStr;
+ CHAR16 *CIDStr;
+ CHAR16 *UIDSTRStr;
+ CHAR8 *AsciiStr;
+ UINT16 Length;
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+
+ HIDStr = GetNextParamStr (&TextDeviceNode);
+ CIDStr = GetNextParamStr (&TextDeviceNode);
+ UIDSTRStr = GetNextParamStr (&TextDeviceNode);
+ Length = (UINT16) (sizeof (ACPI_EXTENDED_HID_DEVICE_PATH) + StrLen (UIDSTRStr) + 3);
+ AcpiEx = (ACPI_EXTENDED_HID_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_EXTENDED_DP,
+ Length
+ );
+
+ EisaIdFromText (HIDStr, &AcpiEx->HID);
+ EisaIdFromText (CIDStr, &AcpiEx->CID);
+ AcpiEx->UID = 0;
+
+ AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ //
+ // HID string is NULL
+ //
+ *AsciiStr = '\0';
+ //
+ // Convert UID string
+ //
+ AsciiStr++;
+ StrToAscii (UIDSTRStr, &AsciiStr);
+ //
+ // CID string is NULL
+ //
+ *AsciiStr = '\0';
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiEx;
+}
+
+/**
+ Converts a text device path node to ACPI _ADR device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created ACPI _ADR device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAcpiAdr (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *DisplayDeviceStr;
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+ UINTN Index;
+ UINTN Length;
+
+ AcpiAdr = (ACPI_ADR_DEVICE_PATH *) CreateDeviceNode (
+ ACPI_DEVICE_PATH,
+ ACPI_ADR_DP,
+ (UINT16) sizeof (ACPI_ADR_DEVICE_PATH)
+ );
+ ASSERT (AcpiAdr != NULL);
+
+ for (Index = 0; ; Index++) {
+ DisplayDeviceStr = GetNextParamStr (&TextDeviceNode);
+ if (IS_NULL (*DisplayDeviceStr)) {
+ break;
+ }
+ if (Index > 0) {
+ Length = DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *)AcpiAdr);
+ AcpiAdr = ReallocatePool (
+ Length,
+ Length + sizeof (UINT32),
+ AcpiAdr
+ );
+ ASSERT (AcpiAdr != NULL);
+ SetDevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *)AcpiAdr, Length + sizeof (UINT32));
+ }
+
+ (&AcpiAdr->ADR)[Index] = (UINT32) Strtoi (DisplayDeviceStr);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr;
+}
+
+/**
+ Converts a text device path node to Parallel Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Parallel Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextAta (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PrimarySecondaryStr;
+ CHAR16 *SlaveMasterStr;
+ CHAR16 *LunStr;
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = (ATAPI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ATAPI_DP,
+ sizeof (ATAPI_DEVICE_PATH)
+ );
+
+ PrimarySecondaryStr = GetNextParamStr (&TextDeviceNode);
+ SlaveMasterStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+
+ Atapi->PrimarySecondary = (UINT8) ((StrCmp (PrimarySecondaryStr, L"Primary") == 0) ? 0 : 1);
+ Atapi->SlaveMaster = (UINT8) ((StrCmp (SlaveMasterStr, L"Master") == 0) ? 0 : 1);
+ Atapi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Atapi;
+}
+
+/**
+ Converts a text device path node to SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextScsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PunStr;
+ CHAR16 *LunStr;
+ SCSI_DEVICE_PATH *Scsi;
+
+ PunStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Scsi = (SCSI_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SCSI_DP,
+ sizeof (SCSI_DEVICE_PATH)
+ );
+
+ Scsi->Pun = (UINT16) Strtoi (PunStr);
+ Scsi->Lun = (UINT16) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Scsi;
+}
+
+/**
+ Converts a text device path node to Fibre device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Fibre device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibre (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ Fibre = (FIBRECHANNEL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNEL_DP,
+ sizeof (FIBRECHANNEL_DEVICE_PATH)
+ );
+
+ Fibre->Reserved = 0;
+ Strtoi64 (WWNStr, &Fibre->WWN);
+ Strtoi64 (LunStr, &Fibre->Lun);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fibre;
+}
+
+/**
+ Converts a text device path node to FibreEx device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created FibreEx device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFibreEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *WWNStr;
+ CHAR16 *LunStr;
+ FIBRECHANNELEX_DEVICE_PATH *FibreEx;
+
+ WWNStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ FibreEx = (FIBRECHANNELEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_FIBRECHANNELEX_DP,
+ (UINT16) sizeof (FIBRECHANNELEX_DEVICE_PATH)
+ );
+
+ FibreEx->Reserved = 0;
+ Strtoi64 (WWNStr, (UINT64 *) (&FibreEx->WWN));
+ Strtoi64 (LunStr, (UINT64 *) (&FibreEx->Lun));
+
+ *(UINT64 *) (&FibreEx->WWN) = SwapBytes64 (*(UINT64 *) (&FibreEx->WWN));
+ *(UINT64 *) (&FibreEx->Lun) = SwapBytes64 (*(UINT64 *) (&FibreEx->Lun));
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FibreEx;
+}
+
+/**
+ Converts a text device path node to 1394 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created 1394 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromText1394 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ F1394_DEVICE_PATH *F1394DevPath;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ F1394DevPath = (F1394_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_1394_DP,
+ sizeof (F1394_DEVICE_PATH)
+ );
+
+ F1394DevPath->Reserved = 0;
+ Xtoi64 (GuidStr, &F1394DevPath->Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
+}
+
+/**
+ Converts a text device path node to USB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsb (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PortStr;
+ CHAR16 *InterfaceStr;
+ USB_DEVICE_PATH *Usb;
+
+ PortStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceStr = GetNextParamStr (&TextDeviceNode);
+ Usb = (USB_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_DP,
+ sizeof (USB_DEVICE_PATH)
+ );
+
+ Usb->ParentPortNumber = (UINT8) Strtoi (PortStr);
+ Usb->InterfaceNumber = (UINT8) Strtoi (InterfaceStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Usb;
+}
+
+/**
+ Converts a text device path node to I20 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created I20 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextI2O (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TIDStr;
+ I20_DEVICE_PATH *I2ODevPath;
+
+ TIDStr = GetNextParamStr (&TextDeviceNode);
+ I2ODevPath = (I20_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_I2O_DP,
+ sizeof (I20_DEVICE_PATH)
+ );
+
+ I2ODevPath->Tid = (UINT32) Strtoi (TIDStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) I2ODevPath;
+}
+
+/**
+ Converts a text device path node to Infini Band device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Infini Band device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextInfiniband (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *FlagsStr;
+ CHAR16 *GuidStr;
+ CHAR16 *SidStr;
+ CHAR16 *TidStr;
+ CHAR16 *DidStr;
+ EFI_GUID PortGid;
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ SidStr = GetNextParamStr (&TextDeviceNode);
+ TidStr = GetNextParamStr (&TextDeviceNode);
+ DidStr = GetNextParamStr (&TextDeviceNode);
+ InfiniBand = (INFINIBAND_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_INFINIBAND_DP,
+ sizeof (INFINIBAND_DEVICE_PATH)
+ );
+
+ InfiniBand->ResourceFlags = (UINT32) Strtoi (FlagsStr);
+ StrToGuid (GuidStr, &PortGid);
+ CopyMem (InfiniBand->PortGid, &PortGid, sizeof (EFI_GUID));
+ Strtoi64 (SidStr, &InfiniBand->ServiceId);
+ Strtoi64 (TidStr, &InfiniBand->TargetPortId);
+ Strtoi64 (DidStr, &InfiniBand->DeviceId);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) InfiniBand;
+}
+
+/**
+ Converts a text device path node to Vendor-Defined Messaging device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-Defined Messaging device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMsg (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to Vendor defined PC-ANSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined PC-ANSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenPcAnsi (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiPcAnsiGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined VT100 Plus device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined VT100 Plus device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenVt100Plus (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVT100PlusGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to Vendor defined UTF8 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor defined UTF8 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenUtf8 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+
+ Vendor = (VENDOR_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEVICE_PATH));
+ CopyGuid (&Vendor->Guid, &gEfiVTUTF8Guid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vendor;
+}
+
+/**
+ Converts a text device path node to UART Flow Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART Flow Control device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUartFlowCtrl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *ValueStr;
+ UART_FLOW_CONTROL_DEVICE_PATH *UartFlowControl;
+
+ ValueStr = GetNextParamStr (&TextDeviceNode);
+ UartFlowControl = (UART_FLOW_CONTROL_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (UART_FLOW_CONTROL_DEVICE_PATH)
+ );
+
+ CopyGuid (&UartFlowControl->Guid, &gEfiUartDevicePathGuid);
+ if (StrCmp (ValueStr, L"XonXoff") == 0) {
+ UartFlowControl->FlowControlMap = 2;
+ } else if (StrCmp (ValueStr, L"Hardware") == 0) {
+ UartFlowControl->FlowControlMap = 1;
+ } else {
+ UartFlowControl->FlowControlMap = 0;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UartFlowControl;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSAS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ CHAR16 *ReservedStr;
+ UINT16 Info;
+ SAS_DEVICE_PATH *Sas;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ ReservedStr = GetNextParamStr (&TextDeviceNode);
+ Info = 0x0000;
+ Sas = (SAS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (SAS_DEVICE_PATH)
+ );
+
+ CopyGuid (&Sas->Guid, &gEfiSasDevicePathGuid);
+ Strtoi64 (AddressStr, &Sas->SasAddress);
+ Strtoi64 (LunStr, &Sas->Lun);
+ Sas->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+ if (StrCmp (SASSATAStr, L"NoTopology") != 0) {
+ if (StrCmp (DriveBayStr, L"0") == 0) {
+ Info |= 0x0001;
+ } else {
+ Info |= 0x0002;
+ Info = (UINT16) (Info | (Strtoi (DriveBayStr) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= 0x0010;
+ }
+
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Info |= 0x0020;
+ }
+
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Info |= 0x0040;
+ }
+ }
+
+ Sas->DeviceTopology = Info;
+ Sas->Reserved = (UINT32) Strtoi (ReservedStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sas;
+}
+
+/**
+ Converts a text device path node to Serial Attached SCSI Ex device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Serial Attached SCSI Ex device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSasEx (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *LunStr;
+ CHAR16 *RTPStr;
+ CHAR16 *SASSATAStr;
+ CHAR16 *LocationStr;
+ CHAR16 *ConnectStr;
+ CHAR16 *DriveBayStr;
+ UINT16 Info;
+ SASEX_DEVICE_PATH *SasEx;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ RTPStr = GetNextParamStr (&TextDeviceNode);
+ SASSATAStr = GetNextParamStr (&TextDeviceNode);
+ LocationStr = GetNextParamStr (&TextDeviceNode);
+ ConnectStr = GetNextParamStr (&TextDeviceNode);
+ DriveBayStr = GetNextParamStr (&TextDeviceNode);
+ Info = 0x0000;
+ SasEx = (SASEX_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SASEX_DP,
+ (UINT16) sizeof (SASEX_DEVICE_PATH)
+ );
+
+ Strtoi64 (AddressStr, (UINT64 *) &SasEx->SasAddress);
+ Strtoi64 (LunStr, (UINT64 *) &SasEx->Lun);
+ *(UINT64 *) &SasEx->SasAddress = SwapBytes64 (*(UINT64 *) &SasEx->SasAddress);
+ *(UINT64 *) &SasEx->Lun = SwapBytes64 (*(UINT64 *) &SasEx->Lun);
+ SasEx->RelativeTargetPort = (UINT16) Strtoi (RTPStr);
+ if (StrCmp (SASSATAStr, L"NoTopology") != 0) {
+ if (StrCmp (DriveBayStr, L"0") == 0) {
+ Info |= 0x0001;
+ } else {
+ Info |= 0x0002;
+ Info = (UINT16) (Info | (Strtoi (DriveBayStr) << 8));
+ }
+
+ if (StrCmp (SASSATAStr, L"SATA") == 0) {
+ Info |= 0x0010;
+ }
+
+ if (StrCmp (LocationStr, L"External") == 0) {
+ Info |= 0x0020;
+ }
+
+ if (StrCmp (ConnectStr, L"Expanded") == 0) {
+ Info |= 0x0040;
+ }
+ }
+
+ SasEx->DeviceTopology = Info;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) SasEx;
+}
+
+/**
+ Converts a text device path node to Debug Port device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Debug Port device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextDebugPort (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ VENDOR_DEFINED_MESSAGING_DEVICE_PATH *Vend;
+
+ Vend = (VENDOR_DEFINED_MESSAGING_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VENDOR_DP,
+ sizeof (VENDOR_DEFINED_MESSAGING_DEVICE_PATH)
+ );
+
+ CopyGuid (&Vend->Guid, &gEfiDebugPortProtocolGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vend;
+}
+
+/**
+ Converts a text device path node to MAC device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created MAC device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMAC (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *AddressStr;
+ CHAR16 *IfTypeStr;
+ UINTN Length;
+ MAC_ADDRESS_DEVICE_PATH *MACDevPath;
+
+ AddressStr = GetNextParamStr (&TextDeviceNode);
+ IfTypeStr = GetNextParamStr (&TextDeviceNode);
+ MACDevPath = (MAC_ADDRESS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_MAC_ADDR_DP,
+ sizeof (MAC_ADDRESS_DEVICE_PATH)
+ );
+
+ MACDevPath->IfType = (UINT8) Strtoi (IfTypeStr);
+
+ Length = sizeof (EFI_MAC_ADDRESS);
+ StrToBuf (&MACDevPath->MacAddr.mac[0], Length, AddressStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) MACDevPath;
+}
+
+
+/**
+ Converts a text format to the network protocol ID.
+
+ @param Text String of protocol field.
+
+ @return Network protocol ID .
+
+**/
+UINTN
+NetworkProtocolFromText (
+ IN CHAR16 *Text
+ )
+{
+ if (StrCmp (Text, L"UDP") == 0) {
+ return RFC_1700_UDP_PROTOCOL;
+ }
+
+ if (StrCmp (Text, L"TCP") == 0) {
+ return RFC_1700_TCP_PROTOCOL;
+ }
+
+ return Strtoi (Text);
+}
+
+
+/**
+ Converts a text device path node to IPV4 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV4 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv4 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *SubnetMaskStr;
+ IPV4_DEVICE_PATH *IPv4;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ SubnetMaskStr = GetNextParamStr (&TextDeviceNode);
+ IPv4 = (IPV4_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv4_DP,
+ sizeof (IPV4_DEVICE_PATH)
+ );
+
+ StrToIPv4Addr (&RemoteIPStr, &IPv4->RemoteIpAddress);
+ IPv4->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv4->StaticIpAddress = TRUE;
+ } else {
+ IPv4->StaticIpAddress = FALSE;
+ }
+
+ StrToIPv4Addr (&LocalIPStr, &IPv4->LocalIpAddress);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*SubnetMaskStr)) {
+ StrToIPv4Addr (&GatewayIPStr, &IPv4->GatewayIpAddress);
+ StrToIPv4Addr (&SubnetMaskStr, &IPv4->SubnetMask);
+ } else {
+ ZeroMem (&IPv4->GatewayIpAddress, sizeof (IPv4->GatewayIpAddress));
+ ZeroMem (&IPv4->SubnetMask, sizeof (IPv4->SubnetMask));
+ }
+
+ IPv4->LocalPort = 0;
+ IPv4->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv4;
+}
+
+/**
+ Converts a text device path node to IPV6 device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created IPV6 device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextIPv6 (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *RemoteIPStr;
+ CHAR16 *ProtocolStr;
+ CHAR16 *TypeStr;
+ CHAR16 *LocalIPStr;
+ CHAR16 *GatewayIPStr;
+ CHAR16 *PrefixLengthStr;
+ IPV6_DEVICE_PATH *IPv6;
+
+ RemoteIPStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ LocalIPStr = GetNextParamStr (&TextDeviceNode);
+ PrefixLengthStr = GetNextParamStr (&TextDeviceNode);
+ GatewayIPStr = GetNextParamStr (&TextDeviceNode);
+ IPv6 = (IPV6_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_IPv6_DP,
+ sizeof (IPV6_DEVICE_PATH)
+ );
+
+ StrToIPv6Addr (&RemoteIPStr, &IPv6->RemoteIpAddress);
+ IPv6->Protocol = (UINT16) NetworkProtocolFromText (ProtocolStr);
+ if (StrCmp (TypeStr, L"Static") == 0) {
+ IPv6->IpAddressOrigin = 0;
+ } else if (StrCmp (TypeStr, L"StatelessAutoConfigure") == 0) {
+ IPv6->IpAddressOrigin = 1;
+ } else {
+ IPv6->IpAddressOrigin = 2;
+ }
+
+ StrToIPv6Addr (&LocalIPStr, &IPv6->LocalIpAddress);
+ if (!IS_NULL (*GatewayIPStr) && !IS_NULL (*PrefixLengthStr)) {
+ StrToIPv6Addr (&GatewayIPStr, &IPv6->GatewayIpAddress);
+ IPv6->PrefixLength = (UINT8) Strtoi (PrefixLengthStr);
+ } else {
+ ZeroMem (&IPv6->GatewayIpAddress, sizeof (IPv6->GatewayIpAddress));
+ IPv6->PrefixLength = 0;
+ }
+
+ IPv6->LocalPort = 0;
+ IPv6->RemotePort = 0;
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) IPv6;
+}
+
+/**
+ Converts a text device path node to UART device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created UART device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUart (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *BaudStr;
+ CHAR16 *DataBitsStr;
+ CHAR16 *ParityStr;
+ CHAR16 *StopBitsStr;
+ UART_DEVICE_PATH *Uart;
+
+ BaudStr = GetNextParamStr (&TextDeviceNode);
+ DataBitsStr = GetNextParamStr (&TextDeviceNode);
+ ParityStr = GetNextParamStr (&TextDeviceNode);
+ StopBitsStr = GetNextParamStr (&TextDeviceNode);
+ Uart = (UART_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_UART_DP,
+ sizeof (UART_DEVICE_PATH)
+ );
+
+ Uart->BaudRate = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : Dtoi (BaudStr);
+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Dtoi (DataBitsStr));
+ switch (*ParityStr) {
+ case L'D':
+ Uart->Parity = 0;
+ break;
+
+ case L'N':
+ Uart->Parity = 1;
+ break;
+
+ case L'E':
+ Uart->Parity = 2;
+ break;
+
+ case L'O':
+ Uart->Parity = 3;
+ break;
+
+ case L'M':
+ Uart->Parity = 4;
+ break;
+
+ case L'S':
+ Uart->Parity = 5;
+
+ default:
+ Uart->Parity = 0xff;
+ }
+
+ if (StrCmp (StopBitsStr, L"D") == 0) {
+ Uart->StopBits = (UINT8) 0;
+ } else if (StrCmp (StopBitsStr, L"1") == 0) {
+ Uart->StopBits = (UINT8) 1;
+ } else if (StrCmp (StopBitsStr, L"1.5") == 0) {
+ Uart->StopBits = (UINT8) 2;
+ } else if (StrCmp (StopBitsStr, L"2") == 0) {
+ Uart->StopBits = (UINT8) 3;
+ } else {
+ Uart->StopBits = 0xff;
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Uart;
+}
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+ @param UsbClassText A pointer to USB_CLASS_TEXT structure to be integrated to USB Class Text.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+ConvertFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode,
+ IN USB_CLASS_TEXT *UsbClassText
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *ClassStr;
+ CHAR16 *SubClassStr;
+ CHAR16 *ProtocolStr;
+ USB_CLASS_DEVICE_PATH *UsbClass;
+
+ UsbClass = (USB_CLASS_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_CLASS_DP,
+ sizeof (USB_CLASS_DEVICE_PATH)
+ );
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ if (UsbClassText->ClassExist) {
+ ClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceClass = (UINT8) Strtoi (ClassStr);
+ } else {
+ UsbClass->DeviceClass = UsbClassText->Class;
+ }
+ if (UsbClassText->SubClassExist) {
+ SubClassStr = GetNextParamStr (&TextDeviceNode);
+ UsbClass->DeviceSubClass = (UINT8) Strtoi (SubClassStr);
+ } else {
+ UsbClass->DeviceSubClass = UsbClassText->SubClass;
+ }
+
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+
+ UsbClass->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbClass->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbClass->DeviceProtocol = (UINT8) Strtoi (ProtocolStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbClass;
+}
+
+
+/**
+ Converts a text device path node to USB class device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB class device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbClass (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = TRUE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB audio device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB audio device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbAudio (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_AUDIO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC Control device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC Control device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCControl (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCCONTROL;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHID (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HID;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Image device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Image device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbImage (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_IMAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB Print device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB Print device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbPrinter (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_PRINTER;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB mass storage device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB mass storage device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbMassStorage (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_MASS_STORAGE;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB HUB device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB HUB device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbHub (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_HUB;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB CDC data device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB CDC data device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbCDCData (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_CDCDATA;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB smart card device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB smart card device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbSmartCard (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_SMART_CARD;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB video device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB video device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbVideo (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_VIDEO;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB diagnostic device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB diagnostic device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDiagnostic (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_DIAGNOSTIC;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB wireless device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB wireless device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWireless (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_WIRELESS;
+ UsbClassText.SubClassExist = TRUE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB device firmware update device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB device firmware update device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbDeviceFirmwareUpdate (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_FW_UPDATE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB IRDA bridge device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB IRDA bridge device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbIrdaBridge (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_IRDA_BRIDGE;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB text and measurement device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB text and measurement device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbTestAndMeasurement (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ USB_CLASS_TEXT UsbClassText;
+
+ UsbClassText.ClassExist = FALSE;
+ UsbClassText.Class = USB_CLASS_RESERVE;
+ UsbClassText.SubClassExist = FALSE;
+ UsbClassText.SubClass = USB_SUBCLASS_TEST;
+
+ return ConvertFromTextUsbClass (TextDeviceNode, &UsbClassText);
+}
+
+/**
+ Converts a text device path node to USB WWID device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created USB WWID device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUsbWwid (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VIDStr;
+ CHAR16 *PIDStr;
+ CHAR16 *InterfaceNumStr;
+ CHAR16 *SerialNumberStr;
+ USB_WWID_DEVICE_PATH *UsbWwid;
+
+ VIDStr = GetNextParamStr (&TextDeviceNode);
+ PIDStr = GetNextParamStr (&TextDeviceNode);
+ InterfaceNumStr = GetNextParamStr (&TextDeviceNode);
+ SerialNumberStr = GetNextParamStr (&TextDeviceNode);
+ UsbWwid = (USB_WWID_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_WWID_CLASS_DP,
+ (UINT16) (sizeof (USB_WWID_DEVICE_PATH) + StrSize (SerialNumberStr))
+ );
+
+ UsbWwid->VendorId = (UINT16) Strtoi (VIDStr);
+ UsbWwid->ProductId = (UINT16) Strtoi (PIDStr);
+ UsbWwid->InterfaceNumber = (UINT16) Strtoi (InterfaceNumStr);
+ StrCpy ((CHAR16 *) ((UINT8 *) UsbWwid + sizeof (USB_WWID_DEVICE_PATH)), SerialNumberStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) UsbWwid;
+}
+
+/**
+ Converts a text device path node to Logic Unit device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Logic Unit device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextUnit (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *LunStr;
+ LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ LogicalUnit = (LOGICAL_UNIT_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_USB_LOGICAL_UNIT_CLASS_DP,
+ (UINT16) sizeof (LOGICAL_UNIT_DEVICE_PATH)
+ );
+
+ LogicalUnit->Lun = (UINT8) Strtoi (LunStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) LogicalUnit;
+}
+
+/**
+ Converts a text device path node to iSCSI device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created iSCSI device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextiSCSI (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ UINT16 Options;
+ CHAR16 *NameStr;
+ CHAR16 *PortalGroupStr;
+ CHAR16 *LunStr;
+ CHAR16 *HeaderDigestStr;
+ CHAR16 *DataDigestStr;
+ CHAR16 *AuthenticationStr;
+ CHAR16 *ProtocolStr;
+ CHAR8 *AsciiStr;
+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+
+ NameStr = GetNextParamStr (&TextDeviceNode);
+ PortalGroupStr = GetNextParamStr (&TextDeviceNode);
+ LunStr = GetNextParamStr (&TextDeviceNode);
+ HeaderDigestStr = GetNextParamStr (&TextDeviceNode);
+ DataDigestStr = GetNextParamStr (&TextDeviceNode);
+ AuthenticationStr = GetNextParamStr (&TextDeviceNode);
+ ProtocolStr = GetNextParamStr (&TextDeviceNode);
+ ISCSIDevPath = (ISCSI_DEVICE_PATH_WITH_NAME *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_ISCSI_DP,
+ (UINT16) (sizeof (ISCSI_DEVICE_PATH_WITH_NAME) + StrLen (NameStr))
+ );
+
+ AsciiStr = ISCSIDevPath->TargetName;
+ StrToAscii (NameStr, &AsciiStr);
+
+ ISCSIDevPath->TargetPortalGroupTag = (UINT16) Strtoi (PortalGroupStr);
+ Strtoi64 (LunStr, &ISCSIDevPath->Lun);
+
+ Options = 0x0000;
+ if (StrCmp (HeaderDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0002;
+ }
+
+ if (StrCmp (DataDigestStr, L"CRC32C") == 0) {
+ Options |= 0x0008;
+ }
+
+ if (StrCmp (AuthenticationStr, L"None") == 0) {
+ Options |= 0x0800;
+ }
+
+ if (StrCmp (AuthenticationStr, L"CHAP_UNI") == 0) {
+ Options |= 0x1000;
+ }
+
+ ISCSIDevPath->LoginOption = (UINT16) Options;
+
+ ISCSIDevPath->NetworkProtocol = (UINT16) StrCmp (ProtocolStr, L"TCP");
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) ISCSIDevPath;
+}
+
+/**
+ Converts a text device path node to VLAN device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created VLAN device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVlan (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *VlanStr;
+ VLAN_DEVICE_PATH *Vlan;
+
+ VlanStr = GetNextParamStr (&TextDeviceNode);
+ Vlan = (VLAN_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_VLAN_DP,
+ sizeof (VLAN_DEVICE_PATH)
+ );
+
+ Vlan->VlanId = (UINT16) Strtoi (VlanStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Vlan;
+}
+
+/**
+ Converts a text device path node to HD device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created HD device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextHD (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *PartitionStr;
+ CHAR16 *TypeStr;
+ CHAR16 *SignatureStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ UINT32 Signature32;
+ EFI_GUID SignatureGuid;
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ PartitionStr = GetNextParamStr (&TextDeviceNode);
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ SignatureStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ Hd = (HARDDRIVE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_HARDDRIVE_DP,
+ sizeof (HARDDRIVE_DEVICE_PATH)
+ );
+
+ Hd->PartitionNumber = (UINT32) Dtoi (PartitionStr);
+
+ ZeroMem (Hd->Signature, 16);
+ Hd->MBRType = (UINT8) 0;
+
+ if (StrCmp (TypeStr, L"MBR") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_MBR;
+ Hd->MBRType = 0x01;
+
+ Signature32 = (UINT32) Strtoi (SignatureStr);
+ CopyMem (Hd->Signature, &Signature32, sizeof (UINT32));
+ } else if (StrCmp (TypeStr, L"GPT") == 0) {
+ Hd->SignatureType = SIGNATURE_TYPE_GUID;
+ Hd->MBRType = 0x02;
+
+ StrToGuid (SignatureStr, &SignatureGuid);
+ CopyMem (Hd->Signature, &SignatureGuid, sizeof (EFI_GUID));
+ } else {
+ Hd->SignatureType = (UINT8) Strtoi (TypeStr);
+ }
+
+ Strtoi64 (StartStr, &Hd->PartitionStart);
+ Strtoi64 (SizeStr, &Hd->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Hd;
+}
+
+/**
+ Converts a text device path node to CDROM device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created CDROM device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextCDROM (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *EntryStr;
+ CHAR16 *StartStr;
+ CHAR16 *SizeStr;
+ CDROM_DEVICE_PATH *CDROMDevPath;
+
+ EntryStr = GetNextParamStr (&TextDeviceNode);
+ StartStr = GetNextParamStr (&TextDeviceNode);
+ SizeStr = GetNextParamStr (&TextDeviceNode);
+ CDROMDevPath = (CDROM_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_CDROM_DP,
+ sizeof (CDROM_DEVICE_PATH)
+ );
+
+ CDROMDevPath->BootEntry = (UINT32) Strtoi (EntryStr);
+ Strtoi64 (StartStr, &CDROMDevPath->PartitionStart);
+ Strtoi64 (SizeStr, &CDROMDevPath->PartitionSize);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) CDROMDevPath;
+}
+
+/**
+ Converts a text device path node to Vendor-defined media device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Vendor-defined media device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextVenMEDIA (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ return ConvertFromTextVendor (
+ TextDeviceNode,
+ MEDIA_DEVICE_PATH,
+ MEDIA_VENDOR_DP
+ );
+}
+
+/**
+ Converts a text device path node to File device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created File device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFilePath (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ FILEPATH_DEVICE_PATH *File;
+
+ File = (FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+ (UINT16) (sizeof (FILEPATH_DEVICE_PATH) + StrLen (TextDeviceNode) * 2)
+ );
+
+ StrCpy (File->PathName, TextDeviceNode);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) File;
+}
+
+/**
+ Converts a text device path node to Media protocol device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Media protocol device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextMedia (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ PROTOCOL_DEVICE_PATH *Media;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Media = (PROTOCOL_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_PROTOCOL_DP,
+ sizeof (PROTOCOL_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Media->ProtocolGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Media;
+}
+
+/**
+ Converts a text device path node to firmware volume device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware volume device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFv (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *Fv;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ Fv = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FV_DP,
+ sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &Fv->NameGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Fv;
+}
+
+/**
+ Converts a text device path node to firmware file device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created firmware file device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextFvFile (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *GuidStr;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
+
+ GuidStr = GetNextParamStr (&TextDeviceNode);
+ FvFile = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_FV_FILEPATH_DP,
+ sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH)
+ );
+
+ StrToGuid (GuidStr, &FvFile->NameGuid);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) FvFile;
+}
+
+/**
+ Converts a text device path node to text relative offset device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created Text device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextRelativeOffsetRange (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *StartingOffsetStr;
+ CHAR16 *EndingOffsetStr;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ StartingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ EndingOffsetStr = GetNextParamStr (&TextDeviceNode);
+ Offset = (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *) CreateDeviceNode (
+ MEDIA_DEVICE_PATH,
+ MEDIA_RELATIVE_OFFSET_RANGE_DP,
+ sizeof (MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH)
+ );
+
+ Strtoi64 (StartingOffsetStr, &Offset->StartingOffset);
+ Strtoi64 (EndingOffsetStr, &Offset->EndingOffset);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Offset;
+}
+
+/**
+ Converts a text device path node to BIOS Boot Specification device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created BIOS Boot Specification device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextBBS (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ CHAR16 *TypeStr;
+ CHAR16 *IdStr;
+ CHAR16 *FlagsStr;
+ CHAR8 *AsciiStr;
+ BBS_BBS_DEVICE_PATH *Bbs;
+
+ TypeStr = GetNextParamStr (&TextDeviceNode);
+ IdStr = GetNextParamStr (&TextDeviceNode);
+ FlagsStr = GetNextParamStr (&TextDeviceNode);
+ Bbs = (BBS_BBS_DEVICE_PATH *) CreateDeviceNode (
+ BBS_DEVICE_PATH,
+ BBS_BBS_DP,
+ (UINT16) (sizeof (BBS_BBS_DEVICE_PATH) + StrLen (IdStr))
+ );
+
+ if (StrCmp (TypeStr, L"Floppy") == 0) {
+ Bbs->DeviceType = BBS_TYPE_FLOPPY;
+ } else if (StrCmp (TypeStr, L"HD") == 0) {
+ Bbs->DeviceType = BBS_TYPE_HARDDRIVE;
+ } else if (StrCmp (TypeStr, L"CDROM") == 0) {
+ Bbs->DeviceType = BBS_TYPE_CDROM;
+ } else if (StrCmp (TypeStr, L"PCMCIA") == 0) {
+ Bbs->DeviceType = BBS_TYPE_PCMCIA;
+ } else if (StrCmp (TypeStr, L"USB") == 0) {
+ Bbs->DeviceType = BBS_TYPE_USB;
+ } else if (StrCmp (TypeStr, L"Network") == 0) {
+ Bbs->DeviceType = BBS_TYPE_EMBEDDED_NETWORK;
+ } else {
+ Bbs->DeviceType = (UINT16) Strtoi (TypeStr);
+ }
+
+ AsciiStr = Bbs->String;
+ StrToAscii (IdStr, &AsciiStr);
+
+ Bbs->StatusFlag = (UINT16) Strtoi (FlagsStr);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Bbs;
+}
+
+/**
+ Converts a text device path node to SATA device path structure.
+
+ @param TextDeviceNode The input Text device path node.
+
+ @return A pointer to the newly-created SATA device path structure.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+DevPathFromTextSata (
+ IN CHAR16 *TextDeviceNode
+ )
+{
+ SATA_DEVICE_PATH *Sata;
+ CHAR16 *Param1;
+ CHAR16 *Param2;
+ CHAR16 *Param3;
+
+ //
+ // The PMPN is optional.
+ //
+ Param1 = GetNextParamStr (&TextDeviceNode);
+ Param2 = GetNextParamStr (&TextDeviceNode);
+ Param3 = NULL;
+ if (!IS_NULL (TextDeviceNode)) {
+ Param3 = GetNextParamStr (&TextDeviceNode);
+ }
+
+ Sata = (SATA_DEVICE_PATH *) CreateDeviceNode (
+ MESSAGING_DEVICE_PATH,
+ MSG_SATA_DP,
+ sizeof (SATA_DEVICE_PATH)
+ );
+ Sata->PortNumber = (UINT16) Xtoi (Param1);
+ if (Param3 != NULL) {
+ Sata->MultiplierPortNumber = (UINT16) Xtoi (Param2);
+ Param2 = Param3;
+ } else {
+ Sata->MultiplierPortNumber = SATA_HBA_DIRECT_CONNECT_FLAG;
+ }
+ Sata->LogicalUnitNumber = (UINT16) Xtoi (Param2);
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE DevPathFromTextTable[] = {
+ {L"Pci", DevPathFromTextPci},
+ {L"PcCard", DevPathFromTextPcCard},
+ {L"MemoryMapped", DevPathFromTextMemoryMapped},
+ {L"VenHw", DevPathFromTextVenHw},
+ {L"Ctrl", DevPathFromTextCtrl},
+ {L"Acpi", DevPathFromTextAcpi},
+ {L"PciRoot", DevPathFromTextPciRoot},
+ {L"PcieRoot", DevPathFromTextPcieRoot},
+ {L"Floppy", DevPathFromTextFloppy},
+ {L"Keyboard", DevPathFromTextKeyboard},
+ {L"Serial", DevPathFromTextSerial},
+ {L"ParallelPort", DevPathFromTextParallelPort},
+ {L"AcpiEx", DevPathFromTextAcpiEx},
+ {L"AcpiExp", DevPathFromTextAcpiExp},
+ {L"AcpiAdr", DevPathFromTextAcpiAdr},
+ {L"Ata", DevPathFromTextAta},
+ {L"Scsi", DevPathFromTextScsi},
+ {L"Fibre", DevPathFromTextFibre},
+ {L"FibreEx", DevPathFromTextFibreEx},
+ {L"I1394", DevPathFromText1394},
+ {L"USB", DevPathFromTextUsb},
+ {L"I2O", DevPathFromTextI2O},
+ {L"Infiniband", DevPathFromTextInfiniband},
+ {L"VenMsg", DevPathFromTextVenMsg},
+ {L"VenPcAnsi", DevPathFromTextVenPcAnsi},
+ {L"VenVt100", DevPathFromTextVenVt100},
+ {L"VenVt100Plus", DevPathFromTextVenVt100Plus},
+ {L"VenUtf8", DevPathFromTextVenUtf8},
+ {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl},
+ {L"SAS", DevPathFromTextSAS},
+ {L"SasEx", DevPathFromTextSasEx},
+ {L"DebugPort", DevPathFromTextDebugPort},
+ {L"MAC", DevPathFromTextMAC},
+ {L"IPv4", DevPathFromTextIPv4},
+ {L"IPv6", DevPathFromTextIPv6},
+ {L"Uart", DevPathFromTextUart},
+ {L"UsbClass", DevPathFromTextUsbClass},
+ {L"UsbAudio", DevPathFromTextUsbAudio},
+ {L"UsbCDCControl", DevPathFromTextUsbCDCControl},
+ {L"UsbHID", DevPathFromTextUsbHID},
+ {L"UsbImage", DevPathFromTextUsbImage},
+ {L"UsbPrinter", DevPathFromTextUsbPrinter},
+ {L"UsbMassStorage", DevPathFromTextUsbMassStorage},
+ {L"UsbHub", DevPathFromTextUsbHub},
+ {L"UsbCDCData", DevPathFromTextUsbCDCData},
+ {L"UsbSmartCard", DevPathFromTextUsbSmartCard},
+ {L"UsbVideo", DevPathFromTextUsbVideo},
+ {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic},
+ {L"UsbWireless", DevPathFromTextUsbWireless},
+ {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate},
+ {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge},
+ {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement},
+ {L"UsbWwid", DevPathFromTextUsbWwid},
+ {L"Unit", DevPathFromTextUnit},
+ {L"iSCSI", DevPathFromTextiSCSI},
+ {L"Vlan", DevPathFromTextVlan},
+ {L"HD", DevPathFromTextHD},
+ {L"CDROM", DevPathFromTextCDROM},
+ {L"VenMEDIA", DevPathFromTextVenMEDIA},
+ {L"Media", DevPathFromTextMedia},
+ {L"Fv", DevPathFromTextFv},
+ {L"FvFile", DevPathFromTextFvFile},
+ {L"Offset", DevPathFromTextRelativeOffsetRange},
+ {L"BBS", DevPathFromTextBBS},
+ {L"Sata", DevPathFromTextSata},
+ {NULL, NULL}
+};
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+{
+ DUMP_NODE DumpNode;
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ CHAR16 *DeviceNodeStr;
+ UINTN Index;
+
+ if ((TextDeviceNode == NULL) || (IS_NULL (*TextDeviceNode))) {
+ return NULL;
+ }
+
+ ParamStr = NULL;
+ DumpNode = NULL;
+ DeviceNodeStr = StrDuplicate (TextDeviceNode);
+ ASSERT (DeviceNodeStr != NULL);
+
+ for (Index = 0; DevPathFromTextTable[Index].Function != NULL; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ DumpNode = DevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (DumpNode == NULL) {
+ //
+ // A file path
+ //
+ DumpNode = DevPathFromTextFilePath;
+ DeviceNode = DumpNode (DeviceNodeStr);
+ } else {
+ DeviceNode = DumpNode (ParamStr);
+ FreePool (ParamStr);
+ }
+
+ FreePool (DeviceNodeStr);
+
+ return DeviceNode;
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+{
+ DUMP_NODE DumpNode;
+ CHAR16 *ParamStr;
+ EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
+ UINTN Index;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ CHAR16 *DevicePathStr;
+ CHAR16 *Str;
+ CHAR16 *DeviceNodeStr;
+ UINT8 IsInstanceEnd;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
+ return NULL;
+ }
+
+ DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DevicePath != NULL);
+ SetDevicePathEndNode (DevicePath);
+
+ ParamStr = NULL;
+ DeviceNodeStr = NULL;
+ DevicePathStr = StrDuplicate (TextDevicePath);
+
+ Str = DevicePathStr;
+ while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
+ DumpNode = NULL;
+ for (Index = 0; DevPathFromTextTable[Index].Function != NULL; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ if (ParamStr != NULL) {
+ DumpNode = DevPathFromTextTable[Index].Function;
+ break;
+ }
+ }
+
+ if (DumpNode == NULL) {
+ //
+ // A file path
+ //
+ DumpNode = DevPathFromTextFilePath;
+ DeviceNode = DumpNode (DeviceNodeStr);
+ } else {
+ DeviceNode = DumpNode (ParamStr);
+ FreePool (ParamStr);
+ }
+
+ NewDevicePath = AppendDeviceNodeProtocolInterface (DevicePath, DeviceNode);
+ FreePool (DevicePath);
+ FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+
+ if (IsInstanceEnd != 0) {
+ DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
+ ASSERT (DeviceNode != NULL);
+ SET_DEVICE_PATH_INSTANCE_END_NODE (DeviceNode);
+
+ NewDevicePath = AppendDeviceNodeProtocolInterface (DevicePath, DeviceNode);
+ FreePool (DevicePath);
+ FreePool (DeviceNode);
+ DevicePath = NewDevicePath;
+ }
+ }
+
+ FreePool (DevicePathStr);
+ return DevicePath;
+}
+
+EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL EfiDevicePathFromTextProtocol = {
+ ConvertTextToDeviceNode,
+ ConvertTextToDevicePath
+};
diff --git a/Core/CORE_DXE/DevicePathToText.c b/Core/CORE_DXE/DevicePathToText.c
new file mode 100644
index 0000000..48642c9
--- /dev/null
+++ b/Core/CORE_DXE/DevicePathToText.c
@@ -0,0 +1,2083 @@
+/** @file
+ DevicePathToText protocol as defined in the UEFI 2.0 specification.
+
+Copyright (c) 2006 - 2010, Intel Corporation. <BR>
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "DevicePath.h"
+#include "EdkIICommon.h"
+
+/**
+ Concatenates a formatted unicode string to allocated pool. The caller must
+ free the resulting buffer.
+
+ @param Str Tracks the allocated pool, size in use, and
+ amount of pool allocated.
+ @param Fmt The format string
+ @param ... Variable arguments based on the format string.
+
+ @return Allocated buffer with the formatted string printed in it.
+ The caller must free the allocated buffer. The buffer
+ allocation is not packed.
+
+**/
+CHAR16 *
+CatPrint (
+ IN OUT POOL_PRINT *Str,
+ IN CHAR16 *Fmt,
+ ...
+ )
+{
+ UINT16 *AppendStr;
+ VA_LIST Args;
+ UINTN Size;
+
+ AppendStr = AllocateZeroPool (0x1000);
+ if (AppendStr == NULL) {
+ return Str->Str;
+ }
+
+ VA_START (Args, Fmt);
+ UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
+ VA_END (Args);
+ if (NULL == Str->Str) {
+ Size = StrSize (AppendStr);
+ Str->Str = AllocateZeroPool (Size);
+ ASSERT (Str->Str != NULL);
+ } else {
+ Size = StrSize (AppendStr) - sizeof (UINT16);
+ Size = Size + StrSize (Str->Str);
+ Str->Str = ReallocatePool (
+ StrSize (Str->Str),
+ Size,
+ Str->Str
+ );
+ ASSERT (Str->Str != NULL);
+ }
+
+ Str->MaxLen = MAX_CHAR * sizeof (UINT16);
+ if (Size < Str->MaxLen) {
+ StrCat (Str->Str, AppendStr);
+ Str->Len = Size - sizeof (UINT16);
+ }
+
+ FreePool (AppendStr);
+ return Str->Str;
+}
+
+/**
+ Converts a PCI device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextPci (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCI_DEVICE_PATH *Pci;
+
+ Pci = DevPath;
+ CatPrint (Str, L"Pci(0x%x,0x%x)", (UINTN) Pci->Device, (UINTN) Pci->Function);
+}
+
+/**
+ Converts a PC Card device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextPccard (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PCCARD_DEVICE_PATH *Pccard;
+
+ Pccard = DevPath;
+ CatPrint (Str, L"PcCard(0x%x)", (UINTN) Pccard->Function);
+}
+
+/**
+ Converts a Memory Map device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextMemMap (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEMMAP_DEVICE_PATH *MemMap;
+
+ MemMap = DevPath;
+ CatPrint (
+ Str,
+ L"MemoryMapped(0x%x,0x%lx,0x%lx)",
+ (UINTN) MemMap->MemoryType,
+ MemMap->StartingAddress,
+ MemMap->EndingAddress
+ );
+}
+
+/**
+ Converts a Vendor device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextVendor (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ VENDOR_DEVICE_PATH *Vendor;
+ CHAR16 *Type;
+ UINTN Index;
+ UINTN DataLength;
+ UINT32 FlowControlMap;
+ UINT16 Info;
+
+ Vendor = (VENDOR_DEVICE_PATH *) DevPath;
+ switch (DevicePathType (&Vendor->Header)) {
+ case HARDWARE_DEVICE_PATH:
+ Type = L"Hw";
+ break;
+
+ case MESSAGING_DEVICE_PATH:
+ Type = L"Msg";
+ if (AllowShortcuts) {
+ if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
+ CatPrint (Str, L"VenPcAnsi()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
+ CatPrint (Str, L"VenVt100()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
+ CatPrint (Str, L"VenVt100Plus()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
+ CatPrint (Str, L"VenUft8()");
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
+ FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
+ switch (FlowControlMap & 0x00000003) {
+ case 0:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
+ break;
+
+ case 1:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
+ break;
+
+ case 2:
+ CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
+ break;
+
+ default:
+ break;
+ }
+
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
+ CatPrint (
+ Str,
+ L"SAS(0x%lx,0x%lx,0x%x,",
+ ((SAS_DEVICE_PATH *) Vendor)->SasAddress,
+ ((SAS_DEVICE_PATH *) Vendor)->Lun,
+ (UINTN) ((SAS_DEVICE_PATH *) Vendor)->RelativeTargetPort
+ );
+ Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
+ if ((Info & 0x0f) == 0) {
+ CatPrint (Str, L"NoTopology,0,0,0,");
+ } else if (((Info & 0x0f) == 1) || ((Info & 0x0f) == 2)) {
+ CatPrint (
+ Str,
+ L"%s,%s,%s,",
+ ((Info & (0x1 << 4)) != 0) ? L"SATA" : L"SAS",
+ ((Info & (0x1 << 5)) != 0) ? L"External" : L"Internal",
+ ((Info & (0x1 << 6)) != 0) ? L"Expanded" : L"Direct"
+ );
+ if ((Info & 0x0f) == 1) {
+ CatPrint (Str, L"0,");
+ } else {
+ CatPrint (Str, L"0x%x,",(UINTN) (Info >> 8) & 0xff);
+ }
+ } else {
+ CatPrint (Str, L"0,0,0,0,");
+ }
+
+ CatPrint (Str, L"0x%x)", (UINTN) ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+ return ;
+ } else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
+ CatPrint (Str, L"DebugPort()");
+ return ;
+ }
+ }
+ break;
+
+ case MEDIA_DEVICE_PATH:
+ Type = L"Media";
+ break;
+
+ default:
+ Type = L"?";
+ break;
+ }
+
+ DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
+ CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
+ if (DataLength != 0) {
+ CatPrint (Str, L",");
+ for (Index = 0; Index < DataLength; Index++) {
+ CatPrint (Str, L"%02x", (UINTN) ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+ }
+ }
+
+ CatPrint (Str, L")");
+}
+
+/**
+ Converts a Controller device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextController (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CONTROLLER_DEVICE_PATH *Controller;
+
+ Controller = DevPath;
+ CatPrint (
+ Str,
+ L"Ctrl(0x%x)",
+ (UINTN) Controller->Controller
+ );
+}
+
+/**
+ Converts a ACPI device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextAcpi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_HID_DEVICE_PATH *Acpi;
+
+ Acpi = DevPath;
+ if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
+ switch (EISA_ID_TO_NUM (Acpi->HID)) {
+ case 0x0a03:
+ CatPrint (Str, L"PciRoot(0x%x)", (UINTN) Acpi->UID);
+ break;
+
+ case 0x0a08:
+ CatPrint (Str, L"PcieRoot(0x%x)", (UINTN) Acpi->UID);
+ break;
+
+ case 0x0604:
+ CatPrint (Str, L"Floppy(0x%x)", (UINTN) Acpi->UID);
+ break;
+
+ case 0x0301:
+ CatPrint (Str, L"Keyboard(0x%x)", (UINTN) Acpi->UID);
+ break;
+
+ case 0x0501:
+ CatPrint (Str, L"Serial(0x%x)", (UINTN) Acpi->UID);
+ break;
+
+ case 0x0401:
+ CatPrint (Str, L"ParallelPort(0x%x)", (UINTN) Acpi->UID);
+ break;
+
+ default:
+ CatPrint (Str, L"Acpi(PNP%04x,0x%x)", (UINTN) EISA_ID_TO_NUM (Acpi->HID), (UINTN) Acpi->UID);
+ break;
+ }
+ } else {
+ CatPrint (Str, L"Acpi(0x%08x,0x%x)", (UINTN) Acpi->HID, (UINTN) Acpi->UID);
+ }
+}
+
+/**
+ Converts EISA identification to string.
+
+ @param EisaId The input EISA identification.
+ @param Text A pointer to the output string.
+
+**/
+VOID
+EisaIdToText (
+ IN UINT32 EisaId,
+ IN OUT CHAR16 *Text
+ )
+{
+ CHAR16 PnpIdStr[17];
+
+ //
+ //UnicodeSPrint ("%X", 0x0a03) => "0000000000000A03"
+ //
+ UnicodeSPrint (PnpIdStr, 17 * 2, L"%16X", EisaId >> 16);
+
+ UnicodeSPrint (
+ Text,
+ sizeof (CHAR16) + sizeof (CHAR16) + sizeof (CHAR16) + sizeof (PnpIdStr),
+ L"%c%c%c%s",
+ '@' + ((EisaId >> 10) & 0x1f),
+ '@' + ((EisaId >> 5) & 0x1f),
+ '@' + ((EisaId >> 0) & 0x1f),
+ PnpIdStr + (16 - 4)
+ );
+}
+
+/**
+ Converts a ACPI extended HID device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextAcpiEx (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_EXTENDED_HID_DEVICE_PATH *AcpiEx;
+ CHAR8 *HIDStr;
+ CHAR8 *UIDStr;
+ CHAR8 *CIDStr;
+ CHAR16 HIDText[11];
+ CHAR16 CIDText[11];
+
+ AcpiEx = DevPath;
+ HIDStr = (CHAR8 *) (((UINT8 *) AcpiEx) + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
+ UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;
+ CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;
+
+ EisaIdToText (AcpiEx->HID, HIDText);
+ EisaIdToText (AcpiEx->CID, CIDText);
+
+ if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {
+ //
+ // use AcpiExp()
+ //
+ CatPrint (
+ Str,
+ L"AcpiExp(%s,%s,%a)",
+ HIDText,
+ CIDText,
+ UIDStr
+ );
+ } else {
+ if (AllowShortcuts) {
+ //
+ // display only
+ //
+ if (AcpiEx->HID == 0) {
+ CatPrint (Str, L"AcpiEx(%a,", HIDStr);
+ } else {
+ CatPrint (Str, L"AcpiEx(%s,", HIDText);
+ }
+
+ if (AcpiEx->UID == 0) {
+ CatPrint (Str, L"%a,", UIDStr);
+ } else {
+ CatPrint (Str, L"0x%x,", (UINTN) AcpiEx->UID);
+ }
+
+ if (AcpiEx->CID == 0) {
+ CatPrint (Str, L"%a)", CIDStr);
+ } else {
+ CatPrint (Str, L"%s)", CIDText);
+ }
+ } else {
+ CatPrint (
+ Str,
+ L"AcpiEx(%s,%s,0x%x,%a,%a,%a)",
+ HIDText,
+ CIDText,
+ (UINTN) AcpiEx->UID,
+ HIDStr,
+ CIDStr,
+ UIDStr
+ );
+ }
+ }
+}
+
+/**
+ Converts a ACPI address device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextAcpiAdr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ACPI_ADR_DEVICE_PATH *AcpiAdr;
+ UINT16 Index;
+ UINT16 Length;
+ UINT16 AdditionalAdrCount;
+
+ AcpiAdr = DevPath;
+ Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
+ AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
+
+ CatPrint (Str, L"AcpiAdr(0x%x", (UINTN) AcpiAdr->ADR);
+ for (Index = 0; Index < AdditionalAdrCount; Index++) {
+ CatPrint (Str, L",0x%x", (UINTN) *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
+ }
+ CatPrint (Str, L")");
+}
+
+/**
+ Converts a ATAPI device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextAtapi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ATAPI_DEVICE_PATH *Atapi;
+
+ Atapi = DevPath;
+
+ if (DisplayOnly) {
+ CatPrint (Str, L"Ata(0x%x)", (UINTN) Atapi->Lun);
+ } else {
+ CatPrint (
+ Str,
+ L"Ata(%s,%s,0x%x)",
+ (Atapi->PrimarySecondary == 1) ? L"Secondary" : L"Primary",
+ (Atapi->SlaveMaster == 1) ? L"Slave" : L"Master",
+ (UINTN) Atapi->Lun
+ );
+ }
+}
+
+/**
+ Converts a SCSI device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextScsi (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SCSI_DEVICE_PATH *Scsi;
+
+ Scsi = DevPath;
+ CatPrint (Str, L"Scsi(0x%x,0x%x)", (UINTN) Scsi->Pun, (UINTN) Scsi->Lun);
+}
+
+/**
+ Converts a Fibre device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextFibre (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FIBRECHANNEL_DEVICE_PATH *Fibre;
+
+ Fibre = DevPath;
+ CatPrint (Str, L"Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
+}
+
+/**
+ Converts a FibreEx device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextFibreEx (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FIBRECHANNELEX_DEVICE_PATH *FibreEx;
+ UINTN Index;
+
+ FibreEx = DevPath;
+ CatPrint (Str, L"FibreEx(0x");
+ for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
+ CatPrint (Str, L"%02x", FibreEx->WWN[Index]);
+ }
+ CatPrint (Str, L",0x");
+ for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
+ CatPrint (Str, L"%02x", FibreEx->Lun[Index]);
+ }
+ CatPrint (Str, L")");
+}
+
+/**
+ Converts a Sas Ex device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextSasEx (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SASEX_DEVICE_PATH *SasEx;
+ UINTN Index;
+
+ SasEx = DevPath;
+ CatPrint (Str, L"SasEx(0x");
+
+ for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
+ CatPrint (Str, L"%02x", SasEx->SasAddress[Index]);
+ }
+ CatPrint (Str, L",0x");
+ for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
+ CatPrint (Str, L"%02x", SasEx->Lun[Index]);
+ }
+ CatPrint (Str, L",0x%x,", SasEx->RelativeTargetPort);
+
+ if ((SasEx->DeviceTopology & 0x0f) == 0) {
+ CatPrint (Str, L"NoTopology,0,0,0");
+ } else if (((SasEx->DeviceTopology & 0x0f) == 1) || ((SasEx->DeviceTopology & 0x0f) == 2)) {
+ CatPrint (
+ Str,
+ L"%s,%s,%s,",
+ ((SasEx->DeviceTopology & (0x1 << 4)) != 0) ? L"SATA" : L"SAS",
+ ((SasEx->DeviceTopology & (0x1 << 5)) != 0) ? L"External" : L"Internal",
+ ((SasEx->DeviceTopology & (0x1 << 6)) != 0) ? L"Expanded" : L"Direct"
+ );
+ if ((SasEx->DeviceTopology & 0x0f) == 1) {
+ CatPrint (Str, L"0");
+ } else {
+ CatPrint (Str, L"0x%x", (SasEx->DeviceTopology >> 8) & 0xff);
+ }
+ } else {
+ CatPrint (Str, L"0,0,0,0");
+ }
+
+ CatPrint (Str, L")");
+ return ;
+
+}
+
+/**
+ Converts a 1394 device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToText1394 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ F1394_DEVICE_PATH *F1394DevPath;
+
+ F1394DevPath = DevPath;
+ //
+ // Guid has format of IEEE-EUI64
+ //
+ CatPrint (Str, L"I1394(%016lx)", F1394DevPath->Guid);
+}
+
+/**
+ Converts a USB device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextUsb (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_DEVICE_PATH *Usb;
+
+ Usb = DevPath;
+ CatPrint (Str, L"USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+}
+
+/**
+ Converts a USB WWID device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextUsbWWID (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_WWID_DEVICE_PATH *UsbWWId;
+ CHAR16 *SerialNumberStr;
+ CHAR16 *NewStr;
+ UINT16 Length;
+
+ UsbWWId = DevPath;
+
+ SerialNumberStr = (CHAR16 *) ((UINT8 *) UsbWWId + sizeof (USB_WWID_DEVICE_PATH));
+ Length = (UINT16) ((DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) UsbWWId) - sizeof (USB_WWID_DEVICE_PATH)) / sizeof (CHAR16));
+ if (SerialNumberStr [Length - 1] != 0) {
+ //
+ // In case no NULL terminator in SerialNumber, create a new one with NULL terminator
+ //
+ NewStr = AllocateCopyPool ((Length + 1) * sizeof (CHAR16), SerialNumberStr);
+ ASSERT (NewStr != NULL);
+ NewStr [Length] = 0;
+ SerialNumberStr = NewStr;
+ }
+
+ CatPrint (
+ Str,
+ L"UsbWwid(0x%x,0x%x,0x%x,\"%s\")",
+ (UINTN) UsbWWId->VendorId,
+ (UINTN) UsbWWId->ProductId,
+ (UINTN) UsbWWId->InterfaceNumber,
+ SerialNumberStr
+ );
+}
+
+/**
+ Converts a Logic Unit device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextLogicalUnit (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
+
+ LogicalUnit = DevPath;
+ CatPrint (Str, L"Unit(0x%x)", (UINTN) LogicalUnit->Lun);
+}
+
+/**
+ Converts a USB class device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextUsbClass (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ USB_CLASS_DEVICE_PATH *UsbClass;
+ BOOLEAN IsKnownSubClass;
+
+
+ UsbClass = DevPath;
+
+ IsKnownSubClass = TRUE;
+ switch (UsbClass->DeviceClass) {
+ case USB_CLASS_AUDIO:
+ CatPrint (Str, L"UsbAudio");
+ break;
+
+ case USB_CLASS_CDCCONTROL:
+ CatPrint (Str, L"UsbCDCControl");
+ break;
+
+ case USB_CLASS_HID:
+ CatPrint (Str, L"UsbHID");
+ break;
+
+ case USB_CLASS_IMAGE:
+ CatPrint (Str, L"UsbImage");
+ break;
+
+ case USB_CLASS_PRINTER:
+ CatPrint (Str, L"UsbPrinter");
+ break;
+
+ case USB_CLASS_MASS_STORAGE:
+ CatPrint (Str, L"UsbMassStorage");
+ break;
+
+ case USB_CLASS_HUB:
+ CatPrint (Str, L"UsbHub");
+ break;
+
+ case USB_CLASS_CDCDATA:
+ CatPrint (Str, L"UsbCDCData");
+ break;
+
+ case USB_CLASS_SMART_CARD:
+ CatPrint (Str, L"UsbSmartCard");
+ break;
+
+ case USB_CLASS_VIDEO:
+ CatPrint (Str, L"UsbVideo");
+ break;
+
+ case USB_CLASS_DIAGNOSTIC:
+ CatPrint (Str, L"UsbDiagnostic");
+ break;
+
+ case USB_CLASS_WIRELESS:
+ CatPrint (Str, L"UsbWireless");
+ break;
+
+ default:
+ IsKnownSubClass = FALSE;
+ break;
+ }
+
+ if (IsKnownSubClass) {
+ CatPrint (
+ Str,
+ L"(0x%x,0x%x,0x%x,0x%x)",
+ (UINTN) UsbClass->VendorId,
+ (UINTN) UsbClass->ProductId,
+ (UINTN) UsbClass->DeviceSubClass,
+ (UINTN) UsbClass->DeviceProtocol
+ );
+ return;
+ }
+
+ if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {
+ if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {
+ CatPrint (
+ Str,
+ L"UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",
+ (UINTN) UsbClass->VendorId,
+ (UINTN) UsbClass->ProductId,
+ (UINTN) UsbClass->DeviceProtocol
+ );
+ return;
+ } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {
+ CatPrint (
+ Str,
+ L"UsbIrdaBridge(0x%x,0x%x,0x%x)",
+ (UINTN) UsbClass->VendorId,
+ (UINTN) UsbClass->ProductId,
+ (UINTN) UsbClass->DeviceProtocol
+ );
+ return;
+ } else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {
+ CatPrint (
+ Str,
+ L"UsbTestAndMeasurement(0x%x,0x%x,0x%x)",
+ (UINTN) UsbClass->VendorId,
+ (UINTN) UsbClass->ProductId,
+ (UINTN) UsbClass->DeviceProtocol
+ );
+ return;
+ }
+ }
+
+ CatPrint (
+ Str,
+ L"UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
+ (UINTN) UsbClass->VendorId,
+ (UINTN) UsbClass->ProductId,
+ (UINTN) UsbClass->DeviceClass,
+ (UINTN) UsbClass->DeviceSubClass,
+ (UINTN) UsbClass->DeviceProtocol
+ );
+}
+
+/**
+ Converts a SATA device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextSata (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ SATA_DEVICE_PATH *Sata;
+
+ Sata = DevPath;
+ if ((Sata->MultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) != 0) {
+ CatPrint (
+ Str,
+ L"Sata(0x%x,0x%x)",
+ (UINTN) Sata->PortNumber,
+ (UINTN) Sata->LogicalUnitNumber
+ );
+ } else {
+ CatPrint (
+ Str,
+ L"Sata(0x%x,0x%x,0x%x)",
+ (UINTN) Sata->PortNumber,
+ (UINTN) Sata->MultiplierPortNumber,
+ (UINTN) Sata->LogicalUnitNumber
+ );
+ }
+}
+
+/**
+ Converts a I20 device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextI2O (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ I20_DEVICE_PATH *I2ODevPath;
+
+ I2ODevPath = DevPath;
+ CatPrint (Str, L"I2O(0x%x)", (UINTN) I2ODevPath->Tid);
+}
+
+/**
+ Converts a MAC address device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextMacAddr (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MAC_ADDRESS_DEVICE_PATH *MacDevPath;
+ UINTN HwAddressSize;
+ UINTN Index;
+
+ MacDevPath = DevPath;
+
+ HwAddressSize = sizeof (EFI_MAC_ADDRESS);
+ if (MacDevPath->IfType == 0x01 || MacDevPath->IfType == 0x00) {
+ HwAddressSize = 6;
+ }
+
+ CatPrint (Str, L"MAC(");
+
+ for (Index = 0; Index < HwAddressSize; Index++) {
+ CatPrint (Str, L"%02x", (UINTN) MacDevPath->MacAddr.mac[Index]);
+ }
+
+ CatPrint (Str, L",0x%x)", (UINTN) MacDevPath->IfType);
+}
+
+/**
+ Converts network protocol string to its text representation.
+
+ @param Str The string representative of input device.
+ @param Protocol The network protocol ID.
+
+**/
+VOID
+CatNetworkProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN UINT16 Protocol
+ )
+{
+ if (Protocol == RFC_1700_TCP_PROTOCOL) {
+ CatPrint (Str, L"TCP");
+ } else if (Protocol == RFC_1700_UDP_PROTOCOL) {
+ CatPrint (Str, L"UDP");
+ } else {
+ CatPrint (Str, L"0x%x", Protocol);
+ }
+}
+
+/**
+ Converts a IPv4 device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextIPv4 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPV4_DEVICE_PATH *IPDevPath;
+
+ IPDevPath = DevPath;
+ if (DisplayOnly) {
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d)",
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[0],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[1],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[2],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[3]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv4(%d.%d.%d.%d,",
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[0],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[1],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[2],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[3]
+ );
+
+ CatNetworkProtocol (
+ Str,
+ IPDevPath->Protocol
+ );
+
+ CatPrint (
+ Str,
+ L",%s,%d.%d.%d.%d",
+ IPDevPath->StaticIpAddress ? L"Static" : L"DHCP",
+ (UINTN) IPDevPath->LocalIpAddress.Addr[0],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[1],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[2],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[3]
+ );
+ if (DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *)IPDevPath) == sizeof (IPV4_DEVICE_PATH)) {
+ CatPrint (
+ Str,
+ L",%d.%d.%d.%d,%d.%d.%d.%d",
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[0],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[1],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[2],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[3],
+ (UINTN) IPDevPath->SubnetMask.Addr[0],
+ (UINTN) IPDevPath->SubnetMask.Addr[1],
+ (UINTN) IPDevPath->SubnetMask.Addr[2],
+ (UINTN) IPDevPath->SubnetMask.Addr[3]
+ );
+ }
+ CatPrint (Str, L")");
+}
+
+/**
+ Converts a IPv6 device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextIPv6 (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ IPV6_DEVICE_PATH *IPDevPath;
+
+ IPDevPath = DevPath;
+ if (DisplayOnly) {
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[0],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[1],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[2],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[3],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[4],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[5],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[6],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[7],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[8],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[9],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[10],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[11],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[12],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[13],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[14],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[15]
+ );
+ return ;
+ }
+
+ CatPrint (
+ Str,
+ L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x,",
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[0],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[1],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[2],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[3],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[4],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[5],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[6],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[7],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[8],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[9],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[10],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[11],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[12],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[13],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[14],
+ (UINTN) IPDevPath->RemoteIpAddress.Addr[15]
+ );
+
+ CatNetworkProtocol (
+ Str,
+ IPDevPath->Protocol
+ );
+
+ switch (IPDevPath->IpAddressOrigin) {
+ case 0:
+ CatPrint (Str, L",Static");
+ break;
+ case 1:
+ CatPrint (Str, L",StatelessAutoConfigure");
+ break;
+ default:
+ CatPrint (Str, L",StatefulAutoConfigure");
+ break;
+ }
+
+ CatPrint (
+ Str,
+ L",%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ (UINTN) IPDevPath->LocalIpAddress.Addr[0],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[1],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[2],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[3],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[4],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[5],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[6],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[7],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[8],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[9],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[10],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[11],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[12],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[13],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[14],
+ (UINTN) IPDevPath->LocalIpAddress.Addr[15]
+ );
+
+ if (DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *)IPDevPath) == sizeof (IPV6_DEVICE_PATH)) {
+ CatPrint (
+ Str,
+ L",0x%x,%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ IPDevPath->PrefixLength,
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[0],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[1],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[2],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[3],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[4],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[5],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[6],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[7],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[8],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[9],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[10],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[11],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[12],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[13],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[14],
+ (UINTN) IPDevPath->GatewayIpAddress.Addr[15]
+ );
+ }
+ CatPrint (Str, L")");
+}
+
+/**
+ Converts an Infini Band device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextInfiniBand (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ INFINIBAND_DEVICE_PATH *InfiniBand;
+
+ InfiniBand = DevPath;
+ CatPrint (
+ Str,
+ L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)",
+ (UINTN) InfiniBand->ResourceFlags,
+ InfiniBand->PortGid,
+ InfiniBand->ServiceId,
+ InfiniBand->TargetPortId,
+ InfiniBand->DeviceId
+ );
+}
+
+/**
+ Converts a UART device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextUart (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ UART_DEVICE_PATH *Uart;
+ CHAR8 Parity;
+
+ Uart = DevPath;
+ switch (Uart->Parity) {
+ case 0:
+ Parity = 'D';
+ break;
+
+ case 1:
+ Parity = 'N';
+ break;
+
+ case 2:
+ Parity = 'E';
+ break;
+
+ case 3:
+ Parity = 'O';
+ break;
+
+ case 4:
+ Parity = 'M';
+ break;
+
+ case 5:
+ Parity = 'S';
+ break;
+
+ default:
+ Parity = 'x';
+ break;
+ }
+
+ if (Uart->BaudRate == 0) {
+ CatPrint (Str, L"Uart(DEFAULT,");
+ } else {
+ CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);
+ }
+
+ if (Uart->DataBits == 0) {
+ CatPrint (Str, L"DEFAULT,");
+ } else {
+ CatPrint (Str, L"%d,", (UINTN) Uart->DataBits);
+ }
+
+ CatPrint (Str, L"%c,", Parity);
+
+ switch (Uart->StopBits) {
+ case 0:
+ CatPrint (Str, L"D)");
+ break;
+
+ case 1:
+ CatPrint (Str, L"1)");
+ break;
+
+ case 2:
+ CatPrint (Str, L"1.5)");
+ break;
+
+ case 3:
+ CatPrint (Str, L"2)");
+ break;
+
+ default:
+ CatPrint (Str, L"x)");
+ break;
+ }
+}
+
+/**
+ Converts an iSCSI device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextiSCSI (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ ISCSI_DEVICE_PATH_WITH_NAME *ISCSIDevPath;
+ UINT16 Options;
+
+ ISCSIDevPath = DevPath;
+ CatPrint (
+ Str,
+ L"iSCSI(%a,0x%x,0x%lx,",
+ ISCSIDevPath->TargetName,
+ (UINTN) ISCSIDevPath->TargetPortalGroupTag,
+ ISCSIDevPath->Lun
+ );
+
+ Options = ISCSIDevPath->LoginOption;
+ CatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");
+ CatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");
+ if (((Options >> 11) & 0x0001) != 0) {
+ CatPrint (Str, L"%s,", L"None");
+ } else if (((Options >> 12) & 0x0001) != 0) {
+ CatPrint (Str, L"%s,", L"CHAP_UNI");
+ } else {
+ CatPrint (Str, L"%s,", L"CHAP_BI");
+
+ }
+
+ CatPrint (Str, L"%s)", (ISCSIDevPath->NetworkProtocol == 0) ? L"TCP" : L"reserved");
+}
+
+/**
+ Converts a VLAN device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextVlan (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ VLAN_DEVICE_PATH *Vlan;
+
+ Vlan = DevPath;
+ CatPrint (Str, L"Vlan(%d)", (UINTN) Vlan->VlanId);
+}
+
+/**
+ Converts a Hard drive device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextHardDrive (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ HARDDRIVE_DEVICE_PATH *Hd;
+
+ Hd = DevPath;
+ switch (Hd->SignatureType) {
+ case SIGNATURE_TYPE_MBR:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,0x%08x,",
+ (UINTN) Hd->PartitionNumber,
+ L"MBR",
+ (UINTN) *((UINT32 *) (&(Hd->Signature[0])))
+ );
+ break;
+
+ case SIGNATURE_TYPE_GUID:
+ CatPrint (
+ Str,
+ L"HD(%d,%s,%g,",
+ (UINTN) Hd->PartitionNumber,
+ L"GPT",
+ (EFI_GUID *) &(Hd->Signature[0])
+ );
+ break;
+
+ default:
+ CatPrint (
+ Str,
+ L"HD(%d,%d,0,",
+ (UINTN) Hd->PartitionNumber,
+ (UINTN) Hd->SignatureType
+ );
+ break;
+ }
+
+ CatPrint (Str, L"0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
+}
+
+/**
+ Converts a CDROM device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextCDROM (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CDROM_DEVICE_PATH *Cd;
+
+ Cd = DevPath;
+ if (DisplayOnly) {
+ CatPrint (Str, L"CDROM(0x%x)", (UINTN) Cd->BootEntry);
+ return ;
+ }
+
+ CatPrint (Str, L"CDROM(0x%x,0x%lx,0x%lx)", (UINTN) Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+}
+
+/**
+ Converts a File device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextFilePath (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ FILEPATH_DEVICE_PATH *Fp;
+
+ Fp = DevPath;
+ CatPrint (Str, L"%s", Fp->PathName);
+}
+
+/**
+ Converts a Media protocol device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextMediaProtocol (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ PROTOCOL_DEVICE_PATH *MediaProt;
+
+ MediaProt = DevPath;
+ CatPrint (Str, L"Media(%g)", &MediaProt->ProtocolGuid);
+}
+
+/**
+ Converts a Firmware Volume device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextFv (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *Fv;
+
+ Fv = DevPath;
+ CatPrint (Str, L"Fv(%g)", &Fv->NameGuid);
+}
+
+/**
+ Converts a Firmware Volume File device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextFvFile (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
+
+ FvFile = DevPath;
+ CatPrint (Str, L"FvFile(%g)", &FvFile->NameGuid);
+}
+
+/**
+ Converts a Relative Offset device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathRelativeOffsetRange (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
+
+ Offset = DevPath;
+ CatPrint (
+ Str,
+ L"Offset(0x%lx,0x%lx)",
+ Offset->StartingOffset,
+ Offset->EndingOffset
+ );
+}
+
+/**
+ Converts a BIOS Boot Specification device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextBBS (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ BBS_BBS_DEVICE_PATH *Bbs;
+ CHAR16 *Type;
+
+ Bbs = DevPath;
+ switch (Bbs->DeviceType) {
+ case BBS_TYPE_FLOPPY:
+ Type = L"Floppy";
+ break;
+
+ case BBS_TYPE_HARDDRIVE:
+ Type = L"HD";
+ break;
+
+ case BBS_TYPE_CDROM:
+ Type = L"CDROM";
+ break;
+
+ case BBS_TYPE_PCMCIA:
+ Type = L"PCMCIA";
+ break;
+
+ case BBS_TYPE_USB:
+ Type = L"USB";
+ break;
+
+ case BBS_TYPE_EMBEDDED_NETWORK:
+ Type = L"Network";
+ break;
+
+ default:
+ Type = NULL;
+ break;
+ }
+
+ if (Type != NULL) {
+ CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);
+ } else {
+ CatPrint (Str, L"BBS(0x%x,%a", (UINTN) Bbs->DeviceType, Bbs->String);
+ }
+
+ if (DisplayOnly) {
+ CatPrint (Str, L")");
+ return ;
+ }
+
+ CatPrint (Str, L",0x%x)", (UINTN) Bbs->StatusFlag);
+}
+
+/**
+ Converts an End-of-Device-Path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextEndInstance (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L",");
+}
+
+/**
+ Converts an unknown device path structure to its string representative.
+
+ @param Str The string representative of input device.
+ @param DevPath The input device path structure.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+**/
+VOID
+DevPathToTextNodeUnknown (
+ IN OUT POOL_PRINT *Str,
+ IN VOID *DevPath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ CatPrint (Str, L"?");
+}
+
+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {
+ {HARDWARE_DEVICE_PATH, HW_PCI_DP, DevPathToTextPci},
+ {HARDWARE_DEVICE_PATH, HW_PCCARD_DP, DevPathToTextPccard},
+ {HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, DevPathToTextMemMap},
+ {HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DevPathToTextVendor},
+ {HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, DevPathToTextController},
+ {ACPI_DEVICE_PATH, ACPI_DP, DevPathToTextAcpi},
+ {ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, DevPathToTextAcpiEx},
+ {ACPI_DEVICE_PATH, ACPI_ADR_DP, DevPathToTextAcpiAdr},
+ {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, DevPathToTextAtapi},
+ {MESSAGING_DEVICE_PATH, MSG_SCSI_DP, DevPathToTextScsi},
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, DevPathToTextFibre},
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP, DevPathToTextFibreEx},
+ {MESSAGING_DEVICE_PATH, MSG_SASEX_DP, DevPathToTextSasEx},
+ {MESSAGING_DEVICE_PATH, MSG_1394_DP, DevPathToText1394},
+ {MESSAGING_DEVICE_PATH, MSG_USB_DP, DevPathToTextUsb},
+ {MESSAGING_DEVICE_PATH, MSG_USB_WWID_CLASS_DP, DevPathToTextUsbWWID},
+ {MESSAGING_DEVICE_PATH, MSG_USB_LOGICAL_UNIT_CLASS_DP, DevPathToTextLogicalUnit},
+ {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DevPathToTextUsbClass},
+ {MESSAGING_DEVICE_PATH, MSG_SATA_DP, DevPathToTextSata},
+ {MESSAGING_DEVICE_PATH, MSG_I2O_DP, DevPathToTextI2O},
+ {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, DevPathToTextMacAddr},
+ {MESSAGING_DEVICE_PATH, MSG_IPv4_DP, DevPathToTextIPv4},
+ {MESSAGING_DEVICE_PATH, MSG_IPv6_DP, DevPathToTextIPv6},
+ {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, DevPathToTextInfiniBand},
+ {MESSAGING_DEVICE_PATH, MSG_UART_DP, DevPathToTextUart},
+ {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DevPathToTextVendor},
+ {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP, DevPathToTextiSCSI},
+ {MESSAGING_DEVICE_PATH, MSG_VLAN_DP, DevPathToTextVlan},
+ {MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, DevPathToTextHardDrive},
+ {MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, DevPathToTextCDROM},
+ {MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, DevPathToTextVendor},
+ {MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, DevPathToTextMediaProtocol},
+ {MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath},
+ {MEDIA_DEVICE_PATH, MEDIA_FV_DP, DevPathToTextFv},
+ {MEDIA_DEVICE_PATH, MEDIA_FV_FILEPATH_DP, DevPathToTextFvFile},
+ {MEDIA_DEVICE_PATH, MEDIA_RELATIVE_OFFSET_RANGE_DP, DevPathRelativeOffsetRange},
+ {BBS_DEVICE_PATH, BBS_BBS_DP, DevPathToTextBBS},
+ {END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance},
+ {0, 0, NULL}
+};
+
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ POOL_PRINT Str;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DeviceNode == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process the device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {
+ if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (DumpNode == NULL) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+
+ //
+ // Print this node
+ //
+ DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+
+ //
+ // Shrink pool used for string allocation
+ //
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (NewSize, NewSize, Str.Str);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
+
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ EFI_DEVICE_PATH_PROTOCOL *AlignedDevPathNode;
+ UINTN Index;
+ UINTN NewSize;
+ VOID (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ ZeroMem (&Str, sizeof (Str));
+
+ //
+ // Process each device path node
+ //
+ DevPathNode = (EFI_DEVICE_PATH_PROTOCOL *) DevicePath;
+ while (!IsDevicePathEnd (DevPathNode)) {
+ //
+ // Find the handler to dump this device path node
+ //
+ DumpNode = NULL;
+ for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index += 1) {
+
+ if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&
+ DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType
+ ) {
+ DumpNode = DevPathToTextTable[Index].Function;
+ break;
+ }
+ }
+ //
+ // If not found, use a generic function
+ //
+ if (!DumpNode) {
+ DumpNode = DevPathToTextNodeUnknown;
+ }
+ //
+ // Put a path separator in if needed
+ //
+ if ((Str.Len != 0) && DumpNode != DevPathToTextEndInstance) {
+ if (*(Str.Str + Str.Len / sizeof (CHAR16) - 1) != L',') {
+ CatPrint (&Str, L"/");
+ }
+ }
+
+ AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength (DevPathNode), DevPathNode);
+ //
+ // Print this node of the device path
+ //
+ DumpNode (&Str, AlignedDevPathNode, DisplayOnly, AllowShortcuts);
+ FreePool (AlignedDevPathNode);
+
+ //
+ // Next device path node
+ //
+ DevPathNode = NextDevicePathNode (DevPathNode);
+ }
+
+ NewSize = (Str.Len + 1) * sizeof (CHAR16);
+ Str.Str = ReallocatePool (NewSize, NewSize, Str.Str);
+ ASSERT (Str.Str != NULL);
+ Str.Str[Str.Len] = 0;
+ return Str.Str;
+}
+
+EFI_DEVICE_PATH_TO_TEXT_PROTOCOL EfiDevicePathToTextProtocol = {
+ ConvertDeviceNodeToText,
+ ConvertDevicePathToText
+}; \ No newline at end of file
diff --git a/Core/CORE_DXE/DiskIo.c b/Core/CORE_DXE/DiskIo.c
new file mode 100644
index 0000000..a9476cd
--- /dev/null
+++ b/Core/CORE_DXE/DiskIo.c
@@ -0,0 +1,978 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/DxeMain/DiskIo.c 27 8/12/11 12:23p Artems $
+//
+// $Revision: 27 $
+//
+// $Date: 8/12/11 12:23p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/DxeMain/DiskIo.c $
+//
+// 27 8/12/11 12:23p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 26 2/05/11 4:10p Artems
+// Removed previous check-in changes
+//
+// 25 1/06/11 5:52p Oleksiyy
+// [TAG] EIP28607
+// [Category] Improvement
+// [Description] System was hanging for some time if Floppy Media
+// removed while writing in meda in progress.
+// EFI_TPL_CALLBACK priority level rised during media related calls.
+// [Files] DiskIo.c, Info.c, MediaAccess.c, Open.c, Partition.c
+//
+// 24 8/27/09 5:21p Felixp
+//
+// 23 8/27/09 4:40p Felixp
+//
+// 20 8/21/09 4:29p Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 19 7/08/09 5:54p Vyacheslava
+// Updated according to the coding standards.
+//
+// 18 4/24/07 4:10p Robert
+// Updated headers to be compliant with the CHM Help Builder
+//
+// 17 4/19/07 12:57p Felixp
+// Minor bug fix in handling of media not present in ReadDiskIo (along
+// with IdeBus.c changes resolves SCT failure)
+//
+// 15 4/16/07 6:29p Felixp
+// Fix: proper handling of media not present in ReadDiskIo
+//
+// 14 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 11 10/28/05 9:03p Felixp
+// bug fix in CalcAlignmentValues
+//
+// 10 10/28/05 2:03p Felixp
+// bug fix in WriteDiskIo for the case when AboveAlign is not zero.
+//
+
+// 5 2/14/05 4:10p Felixp
+// Small bug fix in ReadDiskIo (success returned in case of error)
+//
+// 4 2/11/05 6:09p Felixp
+// - optimizations (both code size and speed)
+// - SCT failure fixed
+//
+// 2 2/07/05 6:05p Felixp
+// Small bug fix in ReadDiskIo and WriteDiskIo
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Disko.c
+//
+// Description: EFI Disk Io Generic Driver.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+#include <Protocol/DiskIo.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/ComponentName2.h>
+#include <AmiDxeLib.h>
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+//----------------------------------------------------------------------------
+// Function Prototypes
+EFI_STATUS EFIAPI DiskIoSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS EFIAPI DiskIoStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS EFIAPI DiskIoStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+);
+
+EFI_STATUS ReadDiskIo (
+ IN EFI_DISK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS WriteDiskIo (
+ IN EFI_DISK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+);
+
+//----------------------------------------------------------------------------
+// Data types
+typedef struct _DISK_IO_DATA {
+ EFI_DISK_IO_PROTOCOL DiskIo;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+} DISK_IO_DATA;
+
+//----------------------------------------------------------------------------
+// GUID Definitions
+static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+static EFI_GUID gEfiDiskIoProtocolGuid = EFI_DISK_IO_PROTOCOL_GUID;
+static EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+
+//----------------------------------------------------------------------------
+// Module Scope Glo=bal Variables
+
+EFI_DRIVER_BINDING_PROTOCOL gDiskIoDriverBindingProtocol = {
+ DiskIoSupported,
+ DiskIoStart,
+ DiskIoStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+DISK_IO_DATA gDiskIoData = {
+ {
+ EFI_DISK_IO_PROTOCOL_REVISION,
+ ReadDiskIo,
+ WriteDiskIo
+ },
+ NULL
+};
+
+static EFI_BOOT_SERVICES *gBS = NULL;
+
+//----------------------------------------------------------------------------
+//Driver Name
+
+#ifdef EFI_DEBUG
+static UINT16 *gDriverName = L"AMI Disk I/O Driver";
+
+//----------------------------------------------------------------------------
+// Function Definitions
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+//
+// Procedure: ComponentNameGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Input:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL
+// instance.
+// ControllerHandle - The handle of a controller that the driver specified
+// by This is managing. This handle specifies the controller whose
+// name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It will be
+// NULL for device drivers. It will also be NULL for a bus drivers
+// that wish to retrieve the name of the bus controller. It will
+// not be NULL for a bus driver that wishes to retrieve the name of
+// a child controller.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the controller name that that the caller
+// is requesting, and it must match one of the languages specified
+// in Supported Languages. The number of languages supported by a
+// driver is up to the driver writer.
+//
+// Output:
+// ControllerName - A pointer to the Unicode string to return. This
+// Unicode string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language specified by
+// Language from the point of view of thedriver specified by This.
+//
+// RETURNS:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver specified by This
+// was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by ControllerHandle and
+// ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: ComponentNameGetDriverName
+//
+// Description: Returns the Driver Name if the language is supported
+//
+// Input:
+// This - Pointer to the instance of this driver
+// Language - Current operating language
+// DriverName - return parameter that will contain the Driver's Name
+//
+// Output: DriverName - return parameter that will contain the Driver's Name
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// EFI_INVALID_PARAMETER - If the Language or DriverName variable is
+// not defined
+// EFI_UNSUPPORTED - If the current laungage is not supported
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS ComponentNameGetDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName )
+{
+ //Supports only English
+ if (!Language || !DriverName)
+ return EFI_INVALID_PARAMETER;
+
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) )
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName = gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//Component Name Protocol
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName = {
+ ComponentNameGetDriverName,
+ ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DiskIoEntryPoint
+//
+// Description: Installs the Driver Binding Protocol for the Disk
+// I/O Driver
+//
+// Input:
+// ImageHandle - Identification Handle for the Disk I/O driver
+// *SystemTable - Pointer to the EFI System Handle
+//
+// Output:
+// EFI_SUCCESS - if the Binding Protocol is installed
+//
+//
+// Modified:
+//
+// Referrals: InstallMultipleProtocolInterfaces
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DiskIoEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ // Initialize global variable for use in this driver
+ gBS = SystemTable->BootServices;
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gDiskIoDriverBindingProtocol.DriverBindingHandle = NULL;
+ gDiskIoDriverBindingProtocol.ImageHandle = ImageHandle;
+
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &gDiskIoDriverBindingProtocol.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gDiskIoDriverBindingProtocol,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid,
+ &gComponentName,
+#endif
+ NULL
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DiskIoSupported
+//
+// Description: Checks whether Block I/O protocol is installed on the
+// Controller
+//
+// Input:
+// *This - pointer to the Briver Binding instance of the
+// Disk I/O Protocol
+// Controller - The Controller that is looking for drivers that
+// operate on it
+// *RemainingDevicePath -
+//
+// Output:
+// EFI_SUCCESS - Driver supports the Controller that is passed in
+// EFI_UNSUPPORTED - The Driver Does not support the Controller
+// that is passed in
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Check whether Block I/O driver is installed and not being used
+// by another driver
+// 2. Return EFI_SUCCESS or EFI_UNSUPPORTED
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI DiskIoSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ // Check to see if the BlockIo Protocol in installed on the ControllerHandle
+ // if so, CloseProtocol and return success, otherwise exit with an error
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&BlockIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ return gBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DiskIoStart
+//
+// Description: Installs DiskIo Protocol on the Controller
+//
+// Input:
+// *This - Pointer to an instance of the Disk I/O protocol
+// Controller - The controller being operated on
+// *RemainingDevicePath -
+//
+// Output:
+// EFI_SUCCESS - if Driver was installed properly
+// Errors - Returns any error that would cause the protocol not
+// to be installed
+//
+// Referrals: OpenProtocol CloseProtocol InstallProtocolInterface
+// AllocatePool CopyMem FreePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Open the Block I/O protocol BY_DRIVER
+// 2. Allocate memory for the new instance of the Disk I/O Data Structure
+// 3. Copy the Default Data into the newly allocated memory
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI DiskIoStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_STATUS Status;
+ DISK_IO_DATA *DiskIo;
+
+ // make sure that the controller handle has the BlockIo Protocol installed on it
+ Status = gBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&gDiskIoData.BlockIo,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ // If not error out
+ if (EFI_ERROR (Status))
+ return Status;
+
+ // Allocate memory for the private data structure for the instance of the driver
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(DISK_IO_DATA),
+ &DiskIo
+ );
+
+ // if no memory is available, exit with error
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // copy the corrct data into it
+ gBS->CopyMem(
+ DiskIo,
+ &gDiskIoData,
+ sizeof(DISK_IO_DATA)
+ );
+
+ // Install the Protocol on the handle if it has a BlockIo Protocol alread installed
+ Status = gBS->InstallProtocolInterface(
+ &ControllerHandle,
+ &gEfiDiskIoProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &DiskIo->DiskIo
+ );
+
+ // If there is an error when installing the protocol, reverse everything that was done
+ if (EFI_ERROR(Status)) {
+ gBS->FreePool(DiskIo);
+ gBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DiskIoStop
+//
+// Description: Uninstalls DiskIo Protocol on the Controller
+//
+// Input:
+// *This - Pointer to an instance of the Disk I/O protocol
+// Controller - The controller being operated on
+// *RemainingDevicePath -
+//
+// Output:
+// EFI_SUCCESS - if Driver was Uninstalled properly
+// EFI_UNSUPPORTED - Disk I/O was not installed on the Controller
+// Errors - Returns any error that would cause the protocol not
+// to be installed
+//
+// Referrals: OpenProtocol CloseProtocol UnInstallProtocolInterface
+// FreePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Open the Disk I/O protocol by GET_DERIVER
+// 2. Uninstall the protocol
+// 3. Free the allocated Memory
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI DiskIoStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+ EFI_STATUS Status;
+ EFI_DISK_IO_PROTOCOL *DiskIoProtocol;
+ DISK_IO_DATA *DiskIo;
+
+ // Unistall all protocols installed installed in DriverBindingStart
+ // open the disk Io protocol
+ Status = gBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiDiskIoProtocolGuid,
+ (VOID**)&DiskIoProtocol,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status))
+ return EFI_UNSUPPORTED;
+
+ // Find the pointer to the parent structure
+ // in this case, DiskIo is the first element in the data structure
+ DiskIo = (DISK_IO_DATA*)DiskIoProtocol;
+
+ // Uninstall the protocol interface
+ Status = gBS->UninstallProtocolInterface(
+ ControllerHandle,
+ &gEfiDiskIoProtocolGuid,
+ &DiskIo->DiskIo
+ );
+
+ // if the interface is uninstalled then close the protocol
+ if (!EFI_ERROR (Status)) {
+ Status = gBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle
+ );
+ }
+
+ // if the protocol is closed, then free the data structure
+ if (!EFI_ERROR (Status))
+ Status = gBS->FreePool(DiskIo);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CalcAlignmentValues
+//
+// Description: Calculates FirstBlock, Numblocks, and the amount
+// of data above and below an alignment value
+//
+// Input:
+// *Media - pointer to the media data structure that is being
+// operated on
+// Offset - byte value that is the offset into the media that
+// indicates where the buffer starts
+// BufferSize - Size of the entire buffer to read
+//
+// Output:
+// *BelowAlign - Number of bytes below an aligned value where
+// the Buffer starts
+// *AboveAlign - Number of bytes above an aligned value where
+// the Buffer ends
+// *FirstBlock - First block that needs to be read to get the
+// entire buffer
+// *NumBlocks - number of blocks to be read
+//
+// Return: VOID
+//
+// Referrals: Div64
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Calculate the first block of the media to read
+// 2. calculate the number of blocks to read
+// 3. Check for any data area that is ablove the final aligned block
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CalcAlignmentValues(
+ IN EFI_BLOCK_IO_MEDIA *Media,
+ IN UINT64 Offset,
+ IN UINT64 BufferSize,
+ OUT UINTN *BelowAlign,
+ OUT UINTN *AboveAlign,
+ OUT UINT64 *FirstBlock,
+ OUT UINT64 *NumBlocks
+)
+{
+ UINT64 Temp;
+
+ // Find out if the Offset is aligned and the remainder if it is not
+ // use 64 bit division function
+ *FirstBlock = Div64(
+ Offset,
+ Media->BlockSize,
+ BelowAlign
+ );
+
+ // Find out if the ending point is aligned and the remainder if it is not
+ // use 64 bit division function
+ Temp = Div64(
+ Offset + BufferSize,
+ Media->BlockSize,
+ AboveAlign
+ );
+
+ // Calculate the total number of blocks to be read/written
+ *NumBlocks = Temp - *FirstBlock;
+
+ if (*AboveAlign)
+ (*NumBlocks)++;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadDiskIo
+//
+// Description: Reads the data from the media specified by the parameters
+// that are passed in
+//
+// Input:
+// *This - Pointer to the Disk I/O protocol instance
+// MediaId - media ID of the device to read from
+// Offset - byte offset where to start reading
+// BufferSize - amount of data to read
+//
+// Output:
+// *Buffer - location to store the data read from the media
+//
+// Return:
+// EFI_SUCCESS - Function Read the Buffer properly or BufferSize = 0
+// EFI_MEDIA_CHANGED - Media changed since last operation
+// EFI_INVALID_PARAMETER - Buffer does not fit within the Media
+//
+// Referrals: Mul64 AllocatePool CalcAlignmentValues CopyMem
+// FreePool BlockIo->ReadBlock
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadDiskIo (
+ IN EFI_DISK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+)
+{
+ DISK_IO_DATA *Container;
+ UINT64 StartBlock = 0;
+ UINT64 NumBlocks = 0;
+ UINTN BelowAlign = 0;
+ UINTN AboveAlign = 0;
+ UINT32 IoAlign;
+ UINTN Temp;
+ UINT8 *DataBuffer, *AlignDataBuffer;
+ UINT32 BlockSize;
+ EFI_STATUS Status;
+
+ // Get the pointer to the Container Structure
+ // DiskIo is the first element of the Data Structure
+ // also define some variables for easier access
+ Container = (DISK_IO_DATA*)This;
+ BlockSize = Container->BlockIo->Media->BlockSize;
+ IoAlign = Container->BlockIo->Media->IoAlign;
+
+ // Error Check values here
+ if (Container->BlockIo->Media->MediaPresent) {
+ if (Container->BlockIo->Media->MediaId != MediaId)
+ return EFI_MEDIA_CHANGED;
+
+ if ( Offset + BufferSize > Mul64(Container->BlockIo->Media->LastBlock + 1, BlockSize) )
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!BufferSize)
+ return EFI_SUCCESS;
+
+ if (!BlockSize)
+ return EFI_INVALID_PARAMETER;
+
+ // find the needed data
+ CalcAlignmentValues(
+ Container->BlockIo->Media,
+ Offset,
+ BufferSize,
+ &BelowAlign,
+ &AboveAlign,
+ &StartBlock,
+ &NumBlocks
+ );
+
+ // Allocate a buffer for use in pulling data out of selected blocks
+ // Size is generated by total number of blocks to be read plus the IoAlignment
+ // value so that the buffer will have plenty of space in it if needed
+ Temp = BlockSize * (UINTN)NumBlocks;
+
+ if ( Temp>BufferSize || IoAlign && ( (UINTN)Buffer & (IoAlign - 1) ) ) {
+ if (IoAlign > 1)
+ Temp += IoAlign;
+
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ Temp,
+ &DataBuffer
+ );
+
+ // No buffer allocated: exit, no need to free the memory
+ if (Status != EFI_SUCCESS)
+ return EFI_OUT_OF_RESOURCES;
+
+ AlignDataBuffer = (IoAlign <= 1) ?
+ DataBuffer : DataBuffer + IoAlign - ( (UINTN)DataBuffer & (IoAlign - 1) );
+
+ } else
+ AlignDataBuffer = Buffer;
+
+ Status = Container->BlockIo->ReadBlocks(
+ Container->BlockIo,
+ MediaId,
+ StartBlock,
+ BlockSize * (UINTN)NumBlocks,
+ AlignDataBuffer
+ );
+
+ if (AlignDataBuffer != Buffer) {
+ gBS->CopyMem(
+ Buffer,
+ AlignDataBuffer + BelowAlign,
+ BufferSize
+ );
+ gBS->FreePool(DataBuffer);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteDiskIo
+//
+// Description: Writes the data to the media specified by the parameters
+// that are passed in
+//
+// Input:
+// *This - Pointer to the Disk I/O protocol instance
+// MediaId - media ID of the device to write to
+// Offset - byte offset where to start wrtiing
+// BufferSize - amount of data to write
+//
+// Output:
+// *Buffer - location of data that should be written to the media
+//
+// Return:
+// EFI_SUCCESS - Function wrote the Buffer properly or BufferSize = 0
+// EFI_MEDIA_CHANGED - Media changed since last operation
+// EFI_INVALID_PARAMETER - Buffer does not fit within the Media
+//
+// Referrals: Mul64 AllocatePool CalcAlignmentValues CopyMem
+// FreePool BlockIo->ReadBlocks BlockIo->WriteBlocks
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS WriteDiskIo (
+ IN EFI_DISK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Offset,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+)
+{
+ DISK_IO_DATA *Container;
+ UINT64 StartBlock = 0;
+ UINT64 NumBlocks = 0;
+ UINTN BelowAlign = 0;
+ UINTN AboveAlign = 0;
+ UINTN IoAlign;
+ UINT8 *DataBuffer, *AlignDataBuffer;
+ UINT32 BlockSize;
+ EFI_STATUS Status;
+ UINTN Temp;
+
+ // Get the pointer to the Container Structure
+ // DiskIo is the first element of the Data Structure
+ // also define some variables for easier access
+ Container = (DISK_IO_DATA*)This;
+ BlockSize = Container->BlockIo->Media->BlockSize;
+ IoAlign = Container->BlockIo->Media->IoAlign;
+
+ // Error Check values here
+ if (Container->BlockIo->Media->MediaId != MediaId)
+ return EFI_MEDIA_CHANGED;
+
+ if ( Offset + BufferSize > Mul64(Container->BlockIo->Media->LastBlock + 1, BlockSize) )
+ return EFI_INVALID_PARAMETER;
+
+ if (!BufferSize)
+ return EFI_SUCCESS;
+
+ // find the needed data
+ CalcAlignmentValues(
+ Container->BlockIo->Media,
+ Offset,
+ BufferSize,
+ &BelowAlign,
+ &AboveAlign,
+ &StartBlock,
+ &NumBlocks
+ );
+
+ // Allocate a buffer for use in pulling data out of selected blocks
+ // Size is generated by total number of blocks to be read plus the IoAlignment
+ // value so that the buffer will have plenty of space in it if needed
+ Temp = BlockSize * (UINTN)NumBlocks;
+
+ if ( Temp>BufferSize || IoAlign && ( (UINTN)Buffer & (IoAlign - 1) ) ) {
+ if (IoAlign > 1)
+ Temp += IoAlign;
+
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ Temp,
+ &DataBuffer
+ );
+
+ // No buffer allocated: exit, no need to free the memory
+ if (Status != EFI_SUCCESS)
+ return EFI_OUT_OF_RESOURCES;
+
+ AlignDataBuffer = (IoAlign <= 1) ?
+ DataBuffer : DataBuffer + IoAlign - ( (UINTN)DataBuffer & (IoAlign - 1) );
+
+ } else {
+
+ Status = Container->BlockIo->WriteBlocks(
+ Container->BlockIo,
+ MediaId,
+ StartBlock,
+ BufferSize,
+ Buffer
+ );
+ return Status;
+ }
+
+ if ( AboveAlign && (NumBlocks > 1 || !BelowAlign) ) {
+ // Read the block that contains the data at the beginning of the block
+ Status = Container->BlockIo->ReadBlocks(
+ Container->BlockIo,
+ MediaId,
+ StartBlock + NumBlocks - 1,
+ BlockSize,
+ AlignDataBuffer
+ );
+
+ // Check to see if the BlockIo protocol reported an error
+ if (Status != EFI_SUCCESS) {
+ gBS->FreePool(DataBuffer);
+ return Status;
+ }
+
+ // just copy the data above the alignment address, not the complete block
+ gBS->CopyMem(
+ AlignDataBuffer + (UINTN)(NumBlocks - 1) * BlockSize + AboveAlign,
+ AlignDataBuffer + AboveAlign,
+ BlockSize - AboveAlign
+ );
+ }
+
+ // see if we need to only pull the data from the end of a block
+ if (BelowAlign) {
+ // read the block that contains the data at the end of the block
+ // Advance StartBlock to the next block after reading the current block
+ Status = Container->BlockIo->ReadBlocks(
+ Container->BlockIo,
+ MediaId,
+ StartBlock,
+ BlockSize,
+ AlignDataBuffer
+ );
+
+
+ // Check to see if the BlockIo protocol reported an error
+ if (Status != EFI_SUCCESS) {
+ gBS->FreePool(DataBuffer);
+ return Status;
+ }
+ }
+
+ // Copy that data to allocated memory
+ gBS->CopyMem(
+ AlignDataBuffer + BelowAlign,
+ Buffer,
+ BufferSize
+ );
+
+ // Write full blocks of data from the block I/O driver
+ Status = Container->BlockIo->WriteBlocks(
+ Container->BlockIo,
+ MediaId,
+ StartBlock,
+ (UINTN)NumBlocks * BlockSize,
+ AlignDataBuffer
+ );
+
+ // Free allocated memory
+ gBS->FreePool(DataBuffer);
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CORE_DXE/Dispatcher.c b/Core/CORE_DXE/Dispatcher.c
new file mode 100644
index 0000000..751a9dd
--- /dev/null
+++ b/Core/CORE_DXE/Dispatcher.c
@@ -0,0 +1,1351 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Dispatcher.c
+
+Abstract:
+
+ Tiano DXE Dispatcher.
+
+ Step #1 - When a FV protocol is added to the system every driver in the FV
+ is added to the mDiscoveredList. The SOR, Before, and After Depex are
+ pre-processed as drivers are added to the mDiscoveredList. If an Apriori
+ file exists in the FV those drivers are addeded to the
+ mScheduledQueue. The mFvHandleList is used to make sure a
+ FV is only processed once.
+
+ Step #2 - Dispatch. Remove driver from the mScheduledQueue and load and
+ start it. After mScheduledQueue is drained check the
+ mDiscoveredList to see if any item has a Depex that is ready to
+ be placed on the mScheduledQueue.
+
+ Step #3 - Adding to the mScheduledQueue requires that you process Before
+ and After dependencies. This is done recursively as the call to add
+ to the mScheduledQueue checks for Before and recursively adds
+ all Befores. It then addes the item that was passed in and then
+ processess the After dependecies by recursively calling the routine.
+
+ Dispatcher Rules:
+ The rules for the dispatcher are in chapter 10 of the DXE CIS. Figure 10-3
+ is the state diagram for the DXE dispatcher
+
+ Depex - Dependency Expresion.
+ SOR - Schedule On Request - Don't schedule if this bit is set.
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "FwVolBlock.h"
+#include EFI_GUID_DEFINITION (Apriori)
+
+//
+// The Driver List contains one copy of every driver that has been discovered.
+// Items are never removed from the driver list. List of EFI_CORE_DRIVER_ENTRY
+//
+EFI_LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
+
+//
+// Queue of drivers that are ready to dispatch. This queue is a subset of the
+// mDiscoveredList.list of EFI_CORE_DRIVER_ENTRY.
+//
+EFI_LIST_ENTRY mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);
+
+//
+// List of handles who's Fv's have been parsed and added to the mFwDriverList.
+//
+EFI_LIST_ENTRY mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList); // list of KNOWN_HANDLE
+
+//
+// Lock for mDiscoveredList, mScheduledQueue, mDispatcherRunning.
+//
+EFI_LOCK mDispatcherLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);
+
+
+//
+// Flag for the DXE Dispacher. TRUE if dispatcher is execuing.
+//
+BOOLEAN mDispatcherRunning = FALSE;
+
+//
+// Module globals to manage the FwVol registration notification event
+//
+EFI_EVENT mFwVolEvent;
+VOID *mFwVolEventRegistration;
+
+//
+// List of file types supported by dispatcher
+//
+static EFI_FV_FILETYPE mDxeFileTypes[] = {
+ EFI_FV_FILETYPE_DRIVER,
+ EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER,
+ EFI_FV_FILETYPE_DXE_CORE,
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
+//*** AMI PORTING BEGIN ***//
+#if PI_SPECIFICATION_VERSION >= 0x0001000A
+ ,EFI_FV_FILETYPE_COMBINED_SMM_DXE
+#endif
+//*** AMI PORTING END *****//
+};
+
+typedef struct {
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH File;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} FV_FILEPATH_DEVICE_PATH;
+
+FV_FILEPATH_DEVICE_PATH mFvDevicePath;
+//
+// Function Prototypes
+//
+VOID
+CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
+ IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry
+ );
+
+VOID
+EFIAPI
+CoreFwVolEventProtocolNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+CoreFvToDevicePath (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
+#else
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+#endif
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+ );
+
+STATIC
+EFI_STATUS
+CoreAddToDriverList (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
+#else
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+#endif
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+ );
+
+STATIC
+EFI_STATUS
+CoreProcessFvImageFile (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
+#else
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+#endif
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+ );
+
+
+VOID
+CoreAcquireDispatcherLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Enter critical section by gaining lock on mDispatcherLock
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+
+{
+ CoreAcquireLock (&mDispatcherLock);
+}
+
+VOID
+CoreReleaseDispatcherLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Exit critical section by releasing lock on mDispatcherLock
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreReleaseLock (&mDispatcherLock);
+}
+
+
+EFI_STATUS
+CoreGetDepexSectionAndPreProccess (
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry
+ )
+/*++
+
+Routine Description:
+
+ Read Depex and pre-process the Depex for Before and After. If Section Extraction
+ protocol returns an error via ReadSection defer the reading of the Depex.
+
+Arguments:
+
+ DriverEntry - Driver to work on.
+
+Returns:
+
+ EFI_SUCCESS - Depex read and preprossesed
+
+ EFI_PROTOCOL_ERROR - The section extraction protocol returned an error and
+ Depex reading needs to be retried.
+
+ Other Error - DEPEX not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_SECTION_TYPE SectionType;
+ UINT32 AuthenticationStatus;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+
+ Fv = DriverEntry->Fv;
+
+ //
+ // Grab Depex info, it will never be free'ed.
+ //
+ SectionType = EFI_SECTION_DXE_DEPEX;
+ Status = Fv->ReadSection (
+ DriverEntry->Fv,
+ &DriverEntry->FileName,
+ SectionType,
+ 0,
+ &DriverEntry->Depex,
+ (UINTN *)&DriverEntry->DepexSize,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_PROTOCOL_ERROR) {
+ //
+ // The section extraction protocol failed so set protocol error flag
+ //
+ DriverEntry->DepexProtocolError = TRUE;
+ } else {
+ //
+ // If no Depex assume EFI 1.1 driver model
+ //
+ DriverEntry->Depex = NULL;
+ DriverEntry->Dependent = TRUE;
+ DriverEntry->DepexProtocolError = FALSE;
+ }
+ } else {
+ //
+ // Set Before, After, and Unrequested state information based on Depex
+ // Driver will be put in Dependent or Unrequested state
+ //
+ CorePreProcessDepex (DriverEntry);
+ DriverEntry->DepexProtocolError = FALSE;
+ }
+
+ return Status;
+}
+
+EFI_DXESERVICE
+EFI_STATUS
+EFIAPI
+CoreSchedule (
+ IN EFI_HANDLE FirmwareVolumeHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Check every driver and locate a matching one. If the driver is found, the Unrequested
+ state flag is cleared.
+
+Arguments:
+
+ FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
+ file specified by DriverName.
+
+ DriverName - The Driver name to put in the Dependent state.
+
+Returns:
+
+ EFI_SUCCESS - The DriverName was found and it's SOR bit was cleared
+
+ EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+
+ //
+ // Check every driver
+ //
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
+ DriverEntry->Unrequested &&
+ EfiCompareGuid (DriverName, &DriverEntry->FileName)) {
+ //
+ // Move the driver from the Unrequested to the Dependent state
+ //
+ CoreAcquireDispatcherLock ();
+ DriverEntry->Unrequested = FALSE;
+ DriverEntry->Dependent = TRUE;
+ CoreReleaseDispatcherLock ();
+
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_DXESERVICE
+EFI_STATUS
+EFIAPI
+CoreTrust (
+ IN EFI_HANDLE FirmwareVolumeHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Convert a driver from the Untrused back to the Scheduled state
+
+Arguments:
+
+ FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
+ file specified by DriverName.
+
+ DriverName - The Driver name to put in the Scheduled state
+
+Returns:
+
+ EFI_SUCCESS - The file was found in the untrusted state, and it was promoted
+ to the trusted state.
+
+ EFI_NOT_FOUND - The file was not found in the untrusted state.
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+
+ //
+ // Check every driver
+ //
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->FvHandle == FirmwareVolumeHandle &&
+ DriverEntry->Untrusted &&
+ EfiCompareGuid (DriverName, &DriverEntry->FileName)) {
+ //
+ // Transition driver from Untrusted to Scheduled state.
+ //
+ CoreAcquireDispatcherLock ();
+ DriverEntry->Untrusted = FALSE;
+ DriverEntry->Scheduled = TRUE;
+ InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
+ CoreReleaseDispatcherLock ();
+
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+//*** AMI PORTING BEGIN ***//
+//PI 1.1 ++
+#if PI_SPECIFICATION_VERSION >= 0x0001000A
+/**
+ An empty function to pass error checking of CreateEventEx ().
+
+ @param Event Event whose notification function is being invoked.
+ @param Context Pointer to the notification function's context,
+ which is implementation-dependent.
+
+**/
+VOID
+EFIAPI
+EmptyFuntion (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ return;
+}
+#endif
+//PI 1.1 --
+//*** AMI PORTING END *****//
+
+EFI_DXESERVICE
+EFI_STATUS
+EFIAPI
+CoreDispatcher (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This is the main Dispatcher for DXE and it exits when there are no more
+ drivers to run. Drain the mScheduledQueue and load and start a PE
+ image for each driver. Search the mDiscoveredList to see if any driver can
+ be placed on the mScheduledQueue. If no drivers are placed on the
+ mScheduledQueue exit the function. On exit it is assumed the Bds()
+ will be called, and when the Bds() exits the Dispatcher will be called
+ again.
+
+Arguments:
+
+ NONE
+
+Returns:
+
+ EFI_ALREADY_STARTED - The DXE Dispatcher is already running
+
+ EFI_NOT_FOUND - No DXE Drivers were dispatched
+
+ EFI_SUCCESS - One or more DXE Drivers were dispatched
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ EFI_LIST_ENTRY *Link;
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+ BOOLEAN ReadyToRun;
+ UINT8 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+ EFI_STATUS_CODE_DATA *StatusCodeData;
+ EFI_DEVICE_HANDLE_EXTENDED_DATA *DeviceHandleExtData;
+//*** AMI PORTING BEGIN ***//
+//PI 1.1 ++
+#if PI_SPECIFICATION_VERSION >= 0x0001000A
+ EFI_EVENT DxeDispatchEvent;
+//---------------------------------------
+
+ Status = CoreCreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ EmptyFuntion,
+ NULL,
+ &gEfiEventDxeDispatchGuid,
+ &DxeDispatchEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+//PI 1.1 --
+//*** AMI PORTING END *****//
+
+ DeviceHandleExtData = (EFI_DEVICE_HANDLE_EXTENDED_DATA *) Buffer;
+ StatusCodeData = (EFI_STATUS_CODE_DATA *) Buffer;
+ DeviceHandleExtData->DataHeader.HeaderSize = sizeof (EFI_STATUS_CODE_DATA);
+ DeviceHandleExtData->DataHeader.Size =
+ sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) -
+ sizeof (EFI_STATUS_CODE_DATA);
+
+ EfiCommonLibCopyMem (
+ &DeviceHandleExtData->DataHeader.Type,
+ &gEfiStatusCodeSpecificDataGuid,
+ sizeof (EFI_GUID)
+ );
+
+ if (mDispatcherRunning) {
+ //
+ // If the dispatcher is running don't let it be restarted.
+ //
+ return EFI_ALREADY_STARTED;
+ }
+
+ mDispatcherRunning = TRUE;
+
+
+ ReturnStatus = EFI_NOT_FOUND;
+ do {
+ //
+ // Drain the Scheduled Queue
+ //
+ while (!IsListEmpty (&mScheduledQueue)) {
+ DriverEntry = CR (
+ mScheduledQueue.ForwardLink,
+ EFI_CORE_DRIVER_ENTRY,
+ ScheduledLink,
+ EFI_CORE_DRIVER_ENTRY_SIGNATURE
+ );
+
+ //
+ // Load the DXE Driver image into memory. If the Driver was transitioned from
+ // Untrused to Scheduled it would have already been loaded so we may need to
+ // skip the LoadImage
+ //
+ if (DriverEntry->ImageHandle == NULL) {
+ Status = CoreLoadImage (
+ FALSE,
+ gDxeCoreImageHandle,
+ DriverEntry->FvFileDevicePath,
+ NULL,
+ 0,
+ &DriverEntry->ImageHandle
+ );
+
+ //
+ // Update the driver state to reflect that it's been loaded
+ //
+ if (EFI_ERROR (Status)) {
+ CoreAcquireDispatcherLock ();
+
+ if (Status == EFI_SECURITY_VIOLATION) {
+ //
+ // Take driver from Scheduled to Untrused state
+ //
+ DriverEntry->Untrusted = TRUE;
+ } else {
+ //
+ // The DXE Driver could not be loaded, and do not attempt to load or start it again.
+ // Take driver from Scheduled to Initialized.
+ //
+ // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
+ //
+ DriverEntry->Initialized = TRUE;
+ }
+
+ DriverEntry->Scheduled = FALSE;
+ RemoveEntryList (&DriverEntry->ScheduledLink);
+
+ CoreReleaseDispatcherLock ();
+
+ //
+ // If it's an error don't try the StartImage
+ //
+ continue;
+ }
+ }
+
+ CoreAcquireDispatcherLock ();
+
+ DriverEntry->Scheduled = FALSE;
+ DriverEntry->Initialized = TRUE;
+ RemoveEntryList (&DriverEntry->ScheduledLink);
+
+ CoreReleaseDispatcherLock ();
+
+ //
+ // Report Status Code here to notify drivers has
+ // been initialized (INIT_BEGIN)
+ //
+ EfiCommonLibCopyMem (
+ &DeviceHandleExtData->Handle,
+ &DriverEntry->ImageHandle,
+ sizeof (EFI_HANDLE)
+ );
+
+ CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN, DriverEntry->ImageHandle);
+
+ Status = CoreStartImage (DriverEntry->ImageHandle, NULL, NULL);
+
+ CoreReportProgressCodeSpecific (EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END, DriverEntry->ImageHandle);
+
+ ReturnStatus = EFI_SUCCESS;
+ }
+
+ //
+ // Search DriverList for items to place on Scheduled Queue
+ //
+ ReadyToRun = FALSE;
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR (Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+
+ if (DriverEntry->DepexProtocolError){
+ //
+ // If Section Extraction Protocol did not let the Depex be read before retry the read
+ //
+ Status = CoreGetDepexSectionAndPreProccess (DriverEntry);
+ }
+
+ if (DriverEntry->Dependent) {
+ if (CoreIsSchedulable (DriverEntry)) {
+ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ ReadyToRun = TRUE;
+ }
+ }
+ }
+//*** AMI PORTING BEGIN ***//
+//PI 1.1 ++
+#if PI_SPECIFICATION_VERSION >= 0x0001000A
+ //
+ // Now DXE Dispatcher finished one round of dispatch, signal an event group
+ // so that SMM Dispatcher get chance to dispatch SMM Drivers which depend
+ // on UEFI protocols
+ //
+ if (!EFI_ERROR (ReturnStatus)) {
+ CoreSignalEvent (DxeDispatchEvent);
+ }
+#endif
+//PI 1.1 --
+//*** AMI PORTING END *****//
+ } while (ReadyToRun);
+
+ mDispatcherRunning = FALSE;
+
+ return ReturnStatus;
+}
+
+
+VOID
+CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
+ IN EFI_CORE_DRIVER_ENTRY *InsertedDriverEntry
+ )
+/*++
+
+Routine Description:
+
+ Insert InsertedDriverEntry onto the mScheduledQueue. To do this you
+ must add any driver with a before dependency on InsertedDriverEntry first.
+ You do this by recursively calling this routine. After all the Befores are
+ processed you can add InsertedDriverEntry to the mScheduledQueue.
+ Then you can add any driver with an After dependency on InsertedDriverEntry
+ by recursively calling this routine.
+
+Arguments:
+
+ InsertedDriverEntry - The driver to insert on the ScheduledLink Queue
+
+Returns:
+
+ NONE
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+
+ //
+ // Process Before Dependency
+ //
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->Before && DriverEntry->Dependent) {
+ if (EfiCompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
+ //
+ // Recursively process BEFORE
+ //
+ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ }
+ }
+ }
+
+ //
+ // Convert driver from Dependent to Scheduled state
+ //
+ CoreAcquireDispatcherLock ();
+
+ InsertedDriverEntry->Dependent = FALSE;
+ InsertedDriverEntry->Scheduled = TRUE;
+ InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
+
+ CoreReleaseDispatcherLock ();
+
+ //
+ // Process After Dependency
+ //
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->After && DriverEntry->Dependent) {
+ if (EfiCompareGuid (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
+ //
+ // Recursively process AFTER
+ //
+ CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ }
+ }
+ }
+}
+
+#if (PI_SPECIFICATION_VERSION >= 0x00010000)
+EFI_STATUS
+FileHasBeenProcessed (
+ IN EFI_GUID *FileNameGuid
+ )
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ EFI_STATUS HobStatus;
+ EFI_GUID FileName;
+ //
+ // First walk hobs and create appropriate FVs.
+ //
+ Status = CoreGetConfigTable (&gEfiHobListGuid, &HobList);
+ //
+ // Core Needs Firmware Volumes to function
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ BaseAddress = 0;
+ Length = 0;
+ HobStatus = GetNextFirmwareVolume2Hob (
+ &HobList,
+ &BaseAddress,
+ &Length,
+ &FileName
+ );
+ while (!EFI_ERROR (HobStatus)) {
+ //
+ // Check if the file has been processed.
+ //
+ if (EfiCompareGuid (FileNameGuid, &FileName)) {
+ return EFI_SUCCESS;
+ }
+ HobStatus = GetNextFirmwareVolume2Hob (
+ &HobList,
+ &BaseAddress,
+ &Length,
+ &FileName
+ );
+ }
+
+ return EFI_NOT_FOUND;
+
+}
+
+#endif
+
+BOOLEAN
+FvHasBeenProcessed (
+ IN EFI_HANDLE FvHandle
+ )
+/*++
+
+Routine Description:
+
+ Return TRUE if the Fv has been processed, FALSE if not.
+
+Arguments:
+
+ FvHandle - The handle of a FV that's being tested
+
+Returns:
+
+ TRUE - Fv protocol on FvHandle has been processed
+
+ FALSE - Fv protocol on FvHandle has not yet been processed
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ KNOWN_HANDLE *KnownHandle;
+
+ for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
+ KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
+ if (KnownHandle->Handle == FvHandle) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+VOID
+FvIsBeingProcesssed (
+ IN EFI_HANDLE FvHandle
+ )
+/*++
+
+Routine Description:
+
+ Remember that Fv protocol on FvHandle has had it's drivers placed on the
+ mDiscoveredList. This fucntion adds entries on the mFvHandleList. Items are
+ never removed/freed from the mFvHandleList.
+
+Arguments:
+
+ FvHandle - The handle of a FV that has been processed
+
+Returns:
+
+ None
+
+--*/
+{
+ KNOWN_HANDLE *KnownHandle;
+
+ KnownHandle = CoreAllocateBootServicesPool (sizeof (KNOWN_HANDLE));
+ ASSERT (KnownHandle != NULL);
+
+ KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
+ KnownHandle->Handle = FvHandle;
+ InsertTailList (&mFvHandleList, &KnownHandle->Link);
+}
+
+
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+CoreFvToDevicePath (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
+#else
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+#endif
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Convert FvHandle and DriverName into an EFI device path
+
+Arguments:
+
+ Fv - Fv protocol, needed to read Depex info out of FLASH.
+
+ FvHandle - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the
+ PE image can be read out of the FV at a later time.
+
+ DriverName - Name of driver to add to mDiscoveredList.
+
+Returns:
+
+ Pointer to device path constructed from FvHandle and DriverName
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FileNameDevicePath;
+
+ //
+ // Remember the device path of the FV
+ //
+ Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, &FvDevicePath);
+ if (EFI_ERROR (Status)) {
+ FileNameDevicePath = NULL;
+ } else {
+ //
+ // Build a device path to the file in the FV to pass into gBS->LoadImage
+ //
+ CoreInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
+ mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;
+ mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));
+ FileNameDevicePath = CoreAppendDevicePath (
+ FvDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
+ );
+ }
+
+ return FileNameDevicePath;
+}
+
+
+
+EFI_STATUS
+CoreAddToDriverList (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
+#else
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+#endif
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Add an entry to the mDiscoveredList. Allocate memory to store the DriverEntry,
+ and initilize any state variables. Read the Depex from the FV and store it
+ in DriverEntry. Pre-process the Depex to set the SOR, Before and After state.
+ The Discovered list is never free'ed and contains booleans that represent the
+ other possible DXE driver states.
+
+Arguments:
+
+ Fv - Fv protocol, needed to read Depex info out of FLASH.
+
+ FvHandle - Handle for Fv, needed in the EFI_CORE_DRIVER_ENTRY so that the
+ PE image can be read out of the FV at a later time.
+
+ DriverName - Name of driver to add to mDiscoveredList.
+
+Returns:
+
+ EFI_SUCCESS - If driver was added to the mDiscoveredList.
+
+ EFI_ALREADY_STARTED - The driver has already been started. Only one DriverName
+ may be active in the system at any one time.
+
+--*/
+{
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+
+
+ //
+ // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
+ // NULL or FALSE.
+ //
+ DriverEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_CORE_DRIVER_ENTRY));
+ ASSERT (DriverEntry != NULL);
+
+ DriverEntry->Signature = EFI_CORE_DRIVER_ENTRY_SIGNATURE;
+ EfiCommonLibCopyMem (&DriverEntry->FileName, DriverName, sizeof (EFI_GUID));
+ DriverEntry->FvHandle = FvHandle;
+ DriverEntry->Fv = Fv;
+ DriverEntry->FvFileDevicePath = CoreFvToDevicePath (Fv, FvHandle, DriverName);
+
+ CoreGetDepexSectionAndPreProccess (DriverEntry);
+
+ CoreAcquireDispatcherLock ();
+
+ InsertTailList (&mDiscoveredList, &DriverEntry->Link);
+
+ CoreReleaseDispatcherLock ();
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+CoreProcessFvImageFile (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *Fv,
+#else
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+#endif
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Get the driver from the FV through driver name, and produce a FVB protocol on FvHandle.
+
+Arguments:
+
+ Fv - The FIRMWARE_VOLUME protocol installed on the FV.
+ FvHandle - The handle which FVB protocol installed on.
+ DriverName - The driver guid specified.
+
+Returns:
+
+ EFI_OUT_OF_RESOURCES - No enough memory or other resource.
+
+ EFI_VOLUME_CORRUPTED - Corrupted volume.
+
+ EFI_SUCCESS - Function successfully returned.
+
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_SECTION_TYPE SectionType;
+ UINT32 AuthenticationStatus;
+ VOID *Buffer;
+ UINTN BufferSize;
+
+ //
+ // Read the first (and only the first) firmware volume section
+ //
+ SectionType = EFI_SECTION_FIRMWARE_VOLUME_IMAGE;
+ Buffer = NULL;
+ BufferSize = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ DriverName,
+ SectionType,
+ 0,
+ &Buffer,
+ &BufferSize,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Produce a FVB protocol for the file
+ //
+ Status = ProduceFVBProtocolOnBuffer (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) Buffer,
+ (UINT64)BufferSize,
+ FvHandle,
+ NULL
+ );
+ }
+
+ if (EFI_ERROR (Status) && (Buffer != NULL)) {
+ //
+ // ReadSection or Produce FVB failed, Free data buffer
+ //
+ gBS->FreePool (Buffer);
+
+ }
+
+ return Status;
+}
+
+
+VOID
+EFIAPI
+CoreFwVolEventProtocolNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Event notification that is fired every time a FV dispatch protocol is added.
+ More than one protocol may have been added when this event is fired, so you
+ must loop on CoreLocateHandle () to see how many protocols were added and
+ do the following to each FV:
+
+ If the Fv has already been processed, skip it. If the Fv has not been
+ processed then mark it as being processed, as we are about to process it.
+
+ Read the Fv and add any driver in the Fv to the mDiscoveredList.The
+ mDiscoveredList is never free'ed and contains variables that define
+ the other states the DXE driver transitions to..
+
+ While you are at it read the A Priori file into memory.
+ Place drivers in the A Priori list onto the mScheduledQueue.
+
+Arguments:
+
+ Event - The Event that is being processed, not used.
+
+ Context - Event Context, not used.
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_STATUS GetNextFileStatus;
+ EFI_STATUS SecurityStatus;
+ EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
+ EFI_HANDLE FvHandle;
+ UINTN BufferSize;
+ EFI_GUID NameGuid;
+ UINTN Key;
+ EFI_FV_FILETYPE Type;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+ EFI_GUID *AprioriFile;
+ UINTN AprioriEntryCount;
+ UINTN Index;
+ EFI_LIST_ENTRY *Link;
+ UINT32 AuthenticationStatus;
+ UINTN SizeOfBuffer;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+
+
+ while (TRUE) {
+ BufferSize = sizeof (EFI_HANDLE);
+ Status = CoreLocateHandle (
+ ByRegisterNotify,
+ NULL,
+ mFwVolEventRegistration,
+ &BufferSize,
+ &FvHandle
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If no more notification events exit
+ //
+ return;
+ }
+
+ if (FvHasBeenProcessed (FvHandle)) {
+ //
+ // This Fv has already been processed so lets skip it!
+ //
+ continue;
+ }
+
+ Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeDispatchProtocolGuid, &Fv);
+ if (EFI_ERROR (Status)) {
+ //
+ // If no dispatch protocol then skip, but do not marked as being processed as it
+ // may show up later.
+ //
+ continue;
+ }
+
+ //
+ // Since we are about to process this Fv mark it as processed.
+ //
+ FvIsBeingProcesssed (FvHandle);
+
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolumeProtocolGuid, &Fv);
+ #else
+ Status = CoreHandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, &Fv);
+ #endif
+ if (EFI_ERROR (Status)) {
+ //
+ // The Handle has a FirmwareVolumeDispatch protocol and should also contiain
+ // a FirmwareVolume protocol thus we should never get here.
+ //
+ ASSERT (FALSE);
+ continue;
+ }
+
+ Status = CoreHandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, &FvDevicePath);
+ if (EFI_ERROR (Status)) {
+ //
+ // The Firmware volume doesn't have device path, can't be dispatched.
+ //
+ continue;
+ }
+
+ //
+ // Evaluate the authentication status of the Firmware Volume through
+ // Security Architectural Protocol
+ //
+ if (gSecurity != NULL) {
+ SecurityStatus = gSecurity->FileAuthenticationState (
+ gSecurity,
+ 0,
+ FvDevicePath
+ );
+ if (SecurityStatus != EFI_SUCCESS) {
+ //
+ // Security check failed. The firmware volume should not be used for any purpose.
+ //
+ continue;
+ }
+ }
+
+ //
+ // Discover Drivers in FV and add them to the Discovered Driver List.
+ // Process EFI_FV_FILETYPE_DRIVER type and then EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
+ // EFI_FV_FILETYPE_DXE_CORE is processed to produce a Loaded Image protocol for the core
+ // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE is processed to create a Fvb
+ //
+ for (Index = 0; Index < sizeof (mDxeFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {
+ //
+ // Initialize the search key
+ //
+ Key = 0;
+ do {
+ Type = mDxeFileTypes[Index];
+ GetNextFileStatus = Fv->GetNextFile (
+ Fv,
+ &Key,
+ &Type,
+ &NameGuid,
+ &Attributes,
+ &Size
+ );
+ if (!EFI_ERROR (GetNextFileStatus)) {
+ if (Type == EFI_FV_FILETYPE_DXE_CORE) {
+ //
+ // If this is the DXE core fill in it's DevicePath & DeviceHandle
+ //
+ if (gDxeCoreLoadedImage->FilePath == NULL) {
+ if (EfiCompareGuid (&NameGuid, gDxeCoreFileName)) {
+ CoreInitializeFwVolDevicepathNode (&mFvDevicePath.File, &NameGuid);
+ mFvDevicePath.End.Type = EFI_END_ENTIRE_DEVICE_PATH;
+ mFvDevicePath.End.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ SetDevicePathNodeLength (&mFvDevicePath.End, sizeof (EFI_DEVICE_PATH_PROTOCOL));
+
+ gDxeCoreLoadedImage->FilePath = CoreDuplicateDevicePath (
+ (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
+ );
+ gDxeCoreLoadedImage->DeviceHandle = FvHandle;
+ }
+ }
+ } else if (Type == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
+
+ #if (PI_SPECIFICATION_VERSION >= 0x00010000)
+ if (FileHasBeenProcessed (&NameGuid) == EFI_SUCCESS) {
+ //
+ // Skip over the file which has been processed.
+ //
+ continue;
+ }
+
+ #endif
+ //
+ // Found a firmware volume image. Produce a firmware volume block
+ // protocol for it so it gets dispatched from. This is usually a
+ // capsule.
+ //
+ CoreProcessFvImageFile (Fv, FvHandle, &NameGuid);
+ } else {
+ //
+ // Transition driver from Undiscovered to Discovered state
+ //
+ CoreAddToDriverList (Fv, FvHandle, &NameGuid);
+ }
+ }
+ } while (!EFI_ERROR (GetNextFileStatus));
+ }
+
+ //
+ // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
+ //
+ AprioriFile = NULL;
+ Status = Fv->ReadSection (
+ Fv,
+ &gAprioriGuid,
+ EFI_SECTION_RAW,
+ 0,
+ &AprioriFile,
+ &SizeOfBuffer,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
+ } else {
+ AprioriEntryCount = 0;
+ }
+
+ //
+ // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
+ // drivers not in the current FV and these must be skipped since the a priori list
+ // is only valid for the FV that it resided in.
+ //
+ CoreAcquireDispatcherLock ();
+
+ for (Index = 0; Index < AprioriEntryCount; Index++) {
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+ if (EfiCompareGuid (&DriverEntry->FileName, &AprioriFile[Index]) &&
+ (FvHandle == DriverEntry->FvHandle)) {
+ DriverEntry->Dependent = FALSE;
+ DriverEntry->Scheduled = TRUE;
+ InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
+ break;
+ }
+ }
+ }
+
+ CoreReleaseDispatcherLock ();
+
+ //
+ // Free data allocated by Fv->ReadSection ()
+ //
+ gBS->FreePool (AprioriFile);
+ }
+}
+
+
+VOID
+CoreInitializeDispatcher (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize the dispatcher. Initialize the notification function that runs when
+ a FV protocol is added to the system.
+
+Arguments:
+
+ NONE
+
+Returns:
+
+ NONE
+
+--*/
+{
+ mFwVolEvent = CoreCreateProtocolNotifyEvent (
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+ #else
+ &gEfiFirmwareVolume2ProtocolGuid,
+ #endif
+ EFI_TPL_CALLBACK,
+ CoreFwVolEventProtocolNotify,
+ NULL,
+ &mFwVolEventRegistration,
+ TRUE
+ );
+}
+
+//
+// Function only used in debug buils
+//
+DEBUG_CODE (
+VOID
+CoreDisplayDiscoveredNotDispatched (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Traverse the discovered list for any drivers that were discovered but not loaded
+ because the dependency experessions evaluated to false
+
+Arguments:
+
+ NONE
+
+Returns:
+
+ NONE
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_CORE_DRIVER_ENTRY *DriverEntry;
+
+ for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_CORE_DRIVER_ENTRY, Link, EFI_CORE_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->Dependent) {
+ DEBUG ((EFI_D_LOAD, "Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
+ }
+ }
+}
+)
diff --git a/Core/CORE_DXE/DriverSupport.c b/Core/CORE_DXE/DriverSupport.c
new file mode 100644
index 0000000..029bf5d
--- /dev/null
+++ b/Core/CORE_DXE/DriverSupport.c
@@ -0,0 +1,931 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DriverSupport.c
+
+Abstract:
+
+ EFI Driver Support Protocol
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "hand.h"
+#include "EfiPerf.h"
+
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION(DriverBinding)
+#include EFI_PROTOCOL_DEFINITION(PlatformDriverOverride)
+#include EFI_PROTOCOL_DEFINITION(BusSpecificDriverOverride)
+//*** AMI PORTING BEGIN ***//
+//Print Name of the driver to be started
+#ifdef EFI_DEBUG
+#include <Token.h>
+CHAR8* GetDriverName(EFI_DRIVER_BINDING_PROTOCOL *pDriver);
+VOID Trace(UINTN /* Level*/, CHAR8 * /*sFormat*/,...);
+#endif
+//*** AMI PORTING END *****//
+
+
+//
+// Driver Support Function Prototypes
+//
+STATIC
+EFI_STATUS
+CoreConnectSingleController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ );
+
+//
+// Driver Support Functions
+//
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreConnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive
+ )
+/*++
+
+Routine Description:
+
+ Connects one or more drivers to a controller.
+
+Arguments:
+
+ ControllerHandle - Handle of the controller to be connected.
+
+ DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.
+
+ RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the
+ controller specified by ControllerHandle.
+
+ Recursive - Whether the function would be called recursively or not.
+
+Returns:
+
+ Status code.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ IHANDLE *Handle;
+ PROTOCOL_INTERFACE *Prot;
+ EFI_LIST_ENTRY *Link;
+ EFI_LIST_ENTRY *ProtLink;
+ OPEN_PROTOCOL_DATA *OpenData;
+ EFI_DEVICE_PATH_PROTOCOL *AlignedRemainingDevicePath;
+ EFI_HANDLE *ChildHandleBuffer;
+ UINTN ChildHandleCount;
+ UINTN Index;
+
+ //
+ // Make sure ControllerHandle is valid
+ //
+ Status = CoreValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Handle = ControllerHandle;
+
+ //
+ // Make a copy of RemainingDevicePath to guanatee it is aligned
+ //
+ AlignedRemainingDevicePath = NULL;
+ if (RemainingDevicePath != NULL) {
+ AlignedRemainingDevicePath = CoreDuplicateDevicePath (RemainingDevicePath);
+ }
+
+ //
+ // Connect all drivers to ControllerHandle
+ // If CoreConnectSingleController returns EFI_NOT_READY, then the number of
+ // Driver Binding Protocols in the handle database has increased during the call
+ // so the connect operation must be restarted
+ //
+ do {
+ ReturnStatus = CoreConnectSingleController (
+ ControllerHandle,
+ DriverImageHandle,
+ AlignedRemainingDevicePath
+ );
+ } while (ReturnStatus == EFI_NOT_READY);
+
+ //
+ // Free the aligned copy of RemainingDevicePath
+ //
+ if (AlignedRemainingDevicePath != NULL) {
+ CoreFreePool (AlignedRemainingDevicePath);
+ }
+
+ //
+ // If recursive, then connect all drivers to all of ControllerHandle's children
+ //
+ if (Recursive) {
+ //
+ // Acquire the protocol lock on the handle database so the child handles can be collected
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Make sure the DriverBindingHandle is valid
+ //
+ Status = CoreValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // Release the protocol lock on the handle database
+ //
+ CoreReleaseProtocolLock ();
+
+ return ReturnStatus;
+ }
+
+
+ //
+ // Count ControllerHandle's children
+ //
+ for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ for (ProtLink = Prot->OpenList.ForwardLink;
+ ProtLink != &Prot->OpenList;
+ ProtLink = ProtLink->ForwardLink) {
+ OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+ ChildHandleCount++;
+ }
+ }
+ }
+
+ //
+ // Allocate a handle buffer for ControllerHandle's children
+ //
+ ChildHandleBuffer = CoreAllocateBootServicesPool (ChildHandleCount * sizeof(EFI_HANDLE));
+
+ //
+ // Fill in a handle buffer with ControllerHandle's children
+ //
+ for (Link = Handle->Protocols.ForwardLink, ChildHandleCount = 0; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ for (ProtLink = Prot->OpenList.ForwardLink;
+ ProtLink != &Prot->OpenList;
+ ProtLink = ProtLink->ForwardLink) {
+ OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+ ChildHandleBuffer[ChildHandleCount] = OpenData->ControllerHandle;
+ ChildHandleCount++;
+ }
+ }
+ }
+
+ //
+ // Release the protocol lock on the handle database
+ //
+ CoreReleaseProtocolLock ();
+
+ //
+ // Recursively connect each child handle
+ //
+ for (Index = 0; Index < ChildHandleCount; Index++) {
+ CoreConnectController (
+ ChildHandleBuffer[Index],
+ NULL,
+ NULL,
+ TRUE
+ );
+ }
+
+ //
+ // Free the handle buffer of ControllerHandle's children
+ //
+ CoreFreePool (ChildHandleBuffer);
+ }
+
+ return ReturnStatus;
+}
+
+VOID
+AddSortedDriverBindingProtocol (
+ IN EFI_HANDLE DriverBindingHandle,
+ IN OUT UINTN *NumberOfSortedDriverBindingProtocols,
+ IN OUT EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols,
+ IN UINTN DriverBindingHandleCount,
+ IN OUT EFI_HANDLE *DriverBindingHandleBuffer,
+ IN BOOLEAN IsImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Add Driver Binding Protocols from Context Driver Image Handles to sorted
+ Driver Binding Protocol list.
+
+Arguments:
+
+ DriverBindingHandle - Handle of the driver binding protocol.
+
+ NumberOfSortedDriverBindingProtocols - Number Of sorted driver binding protocols
+
+ SortedDriverBindingProtocols - The sorted protocol list.
+
+ DriverBindingHandleCount - Driver Binding Handle Count.
+
+ DriverBindingHandleBuffer - The buffer of driver binding protocol to be modified.
+
+ IsImageHandle - Indicate whether DriverBindingHandle is an image handle
+
+Returns:
+
+ None.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+ UINTN Index;
+
+ //
+ // Make sure the DriverBindingHandle is valid
+ //
+ Status = CoreValidateHandle (DriverBindingHandle);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ //
+ // If IsImageHandle is TRUE, then DriverBindingHandle is an image handle
+ // Find all the DriverBindingHandles associated with that image handle and add them to the sorted list
+ //
+ if (IsImageHandle) {
+ //
+ // Loop through all the Driver Binding Handles
+ //
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {
+ //
+ // Retrieve the Driver Binding Protocol associated with each Driver Binding Handle
+ //
+ Status = CoreHandleProtocol (
+ DriverBindingHandleBuffer[Index],
+ &gEfiDriverBindingProtocolGuid,
+ &DriverBinding
+ );
+ if (EFI_ERROR(Status) || DriverBinding == NULL) {
+ continue;
+ }
+ //
+ // If the ImageHandle associated with DriverBinding matches DriverBindingHandle,
+ // then add the DriverBindingProtocol[Index] to the sorted list
+ //
+ if (DriverBinding->ImageHandle == DriverBindingHandle) {
+ AddSortedDriverBindingProtocol (
+ DriverBindingHandleBuffer[Index],
+ NumberOfSortedDriverBindingProtocols,
+ SortedDriverBindingProtocols,
+ DriverBindingHandleCount,
+ DriverBindingHandleBuffer,
+ FALSE
+ );
+ }
+ }
+ return;
+ }
+
+ //
+ // Retrieve the Driver Binding Protocol from DriverBindingHandle
+ //
+ Status = CoreHandleProtocol(
+ DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &DriverBinding
+ );
+ //
+ // If DriverBindingHandle does not support the Driver Binding Protocol then return
+ //
+ if (EFI_ERROR (Status) || DriverBinding == NULL) {
+ return;
+ }
+
+ //
+ // See if DriverBinding is already in the sorted list
+ //
+ for (Index = 0; Index < *NumberOfSortedDriverBindingProtocols && Index < DriverBindingHandleCount; Index++) {
+ if (DriverBinding == SortedDriverBindingProtocols[Index]) {
+ return;
+ }
+ }
+
+ //
+ // Add DriverBinding to the end of the list
+ //
+ if (*NumberOfSortedDriverBindingProtocols < DriverBindingHandleCount) {
+ SortedDriverBindingProtocols[*NumberOfSortedDriverBindingProtocols] = DriverBinding;
+ }
+ *NumberOfSortedDriverBindingProtocols = *NumberOfSortedDriverBindingProtocols + 1;
+
+ //
+ // Mark the cooresponding handle in DriverBindingHandleBuffer as used
+ //
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {
+ if (DriverBindingHandleBuffer[Index] == DriverBindingHandle) {
+ DriverBindingHandleBuffer[Index] = NULL;
+ }
+ }
+}
+
+STATIC
+EFI_STATUS
+CoreConnectSingleController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *ContextDriverImageHandles OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Connects a controller to a driver.
+
+Arguments:
+
+ ControllerHandle - Handle of the controller to be connected.
+ ContextDriverImageHandles - DriverImageHandle A pointer to an ordered list of driver image handles.
+ RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child
+ of the controller specified by ControllerHandle.
+
+Returns:
+
+ EFI_SUCCESS - One or more drivers were connected to ControllerHandle.
+ EFI_OUT_OF_RESOURCES - No enough system resources to complete the request.
+ EFI_NOT_FOUND - No drivers were connected to ControllerHandle.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_HANDLE DriverImageHandle;
+ EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *PlatformDriverOverride;
+ EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecificDriverOverride;
+ UINTN DriverBindingHandleCount;
+ EFI_HANDLE *DriverBindingHandleBuffer;
+ UINTN NewDriverBindingHandleCount;
+ EFI_HANDLE *NewDriverBindingHandleBuffer;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+ UINTN NumberOfSortedDriverBindingProtocols;
+ EFI_DRIVER_BINDING_PROTOCOL **SortedDriverBindingProtocols;
+ UINT32 HighestVersion;
+ UINTN HighestIndex;
+ UINTN SortIndex;
+ BOOLEAN OneStarted;
+ BOOLEAN DriverFound;
+
+ //
+ // Initialize local variables
+ //
+ DriverBindingHandleCount = 0;
+ DriverBindingHandleBuffer = NULL;
+ NumberOfSortedDriverBindingProtocols = 0;
+ SortedDriverBindingProtocols = NULL;
+
+ //
+ // Get list of all Driver Binding Protocol Instances
+ //
+ Status = CoreLocateHandleBuffer (
+ ByProtocol,
+ &gEfiDriverBindingProtocolGuid,
+ NULL,
+ &DriverBindingHandleCount,
+ &DriverBindingHandleBuffer
+ );
+ if (EFI_ERROR (Status) || (DriverBindingHandleCount == 0)) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Allocate a duplicate array for the sorted Driver Binding Protocol Instances
+ //
+ SortedDriverBindingProtocols = CoreAllocateBootServicesPool (sizeof (VOID *) * DriverBindingHandleCount);
+ if (SortedDriverBindingProtocols == NULL) {
+ CoreFreePool (DriverBindingHandleBuffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Add Driver Binding Protocols from Context Driver Image Handles first
+ //
+ if (ContextDriverImageHandles != NULL) {
+ for (Index = 0; ContextDriverImageHandles[Index] != NULL; Index++) {
+ AddSortedDriverBindingProtocol (
+ ContextDriverImageHandles[Index],
+ &NumberOfSortedDriverBindingProtocols,
+ SortedDriverBindingProtocols,
+ DriverBindingHandleCount,
+ DriverBindingHandleBuffer,
+ FALSE
+ );
+ }
+ }
+
+ //
+ // Add the Platform Driver Override Protocol drivers for ControllerHandle next
+ //
+ Status = CoreLocateProtocol (
+ &gEfiPlatformDriverOverrideProtocolGuid,
+ NULL,
+ &PlatformDriverOverride
+ );
+ if (!EFI_ERROR (Status) && (PlatformDriverOverride != NULL)) {
+ DriverImageHandle = NULL;
+ do {
+ Status = PlatformDriverOverride->GetDriver (
+ PlatformDriverOverride,
+ ControllerHandle,
+ &DriverImageHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ AddSortedDriverBindingProtocol (
+ DriverImageHandle,
+ &NumberOfSortedDriverBindingProtocols,
+ SortedDriverBindingProtocols,
+ DriverBindingHandleCount,
+ DriverBindingHandleBuffer,
+ TRUE
+ );
+ }
+ } while (!EFI_ERROR (Status));
+ }
+
+ //
+ // Get the Bus Specific Driver Override Protocol instance on the Controller Handle
+ //
+ Status = CoreHandleProtocol(
+ ControllerHandle,
+ &gEfiBusSpecificDriverOverrideProtocolGuid,
+ &BusSpecificDriverOverride
+ );
+ if (!EFI_ERROR (Status) && (BusSpecificDriverOverride != NULL)) {
+ DriverImageHandle = NULL;
+ do {
+ Status = BusSpecificDriverOverride->GetDriver (
+ BusSpecificDriverOverride,
+ &DriverImageHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ AddSortedDriverBindingProtocol (
+ DriverImageHandle,
+ &NumberOfSortedDriverBindingProtocols,
+ SortedDriverBindingProtocols,
+ DriverBindingHandleCount,
+ DriverBindingHandleBuffer,
+ TRUE
+ );
+ }
+ } while (!EFI_ERROR (Status));
+ }
+
+ //
+ // Then add all the remaining Driver Binding Protocols
+ //
+ SortIndex = NumberOfSortedDriverBindingProtocols;
+ for (Index = 0; Index < DriverBindingHandleCount; Index++) {
+ AddSortedDriverBindingProtocol (
+ DriverBindingHandleBuffer[Index],
+ &NumberOfSortedDriverBindingProtocols,
+ SortedDriverBindingProtocols,
+ DriverBindingHandleCount,
+ DriverBindingHandleBuffer,
+ FALSE
+ );
+ }
+
+ //
+ // Free the Driver Binding Handle Buffer
+ //
+ CoreFreePool (DriverBindingHandleBuffer);
+
+ //
+ // If the number of Driver Binding Protocols has increased since this function started, then return
+ // EFI_NOT_READY, so it will be restarted
+ //
+ Status = CoreLocateHandleBuffer (
+ ByProtocol,
+ &gEfiDriverBindingProtocolGuid,
+ NULL,
+ &NewDriverBindingHandleCount,
+ &NewDriverBindingHandleBuffer
+ );
+ CoreFreePool (NewDriverBindingHandleBuffer);
+ if (NewDriverBindingHandleCount > DriverBindingHandleCount) {
+ //
+ // Free any buffers that were allocated with AllocatePool()
+ //
+ CoreFreePool (SortedDriverBindingProtocols);
+
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Sort the remaining DriverBinding Protocol based on their Version field from
+ // highest to lowest.
+ //
+ for ( ; SortIndex < NumberOfSortedDriverBindingProtocols; SortIndex++) {
+ HighestVersion = SortedDriverBindingProtocols[SortIndex]->Version;
+ HighestIndex = SortIndex;
+ for (Index = SortIndex + 1; Index < NumberOfSortedDriverBindingProtocols; Index++) {
+ if (SortedDriverBindingProtocols[Index]->Version > HighestVersion) {
+ HighestVersion = SortedDriverBindingProtocols[Index]->Version;
+ HighestIndex = Index;
+ }
+ }
+ if (SortIndex != HighestIndex) {
+ DriverBinding = SortedDriverBindingProtocols[SortIndex];
+ SortedDriverBindingProtocols[SortIndex] = SortedDriverBindingProtocols[HighestIndex];
+ SortedDriverBindingProtocols[HighestIndex] = DriverBinding;
+ }
+ }
+
+ //
+ // Loop until no more drivers can be started on ControllerHandle
+ //
+ OneStarted = FALSE;
+ do {
+
+ //
+ // Loop through the sorted Driver Binding Protocol Instances in order, and see if
+ // any of the Driver Binding Protocols support the controller specified by
+ // ControllerHandle.
+ //
+ DriverBinding = NULL;
+ DriverFound = FALSE;
+ for (Index = 0; (Index < NumberOfSortedDriverBindingProtocols) && !DriverFound; Index++) {
+ if (SortedDriverBindingProtocols[Index] != NULL) {
+ DriverBinding = SortedDriverBindingProtocols[Index];
+ Status = DriverBinding->Supported(
+ DriverBinding,
+ ControllerHandle,
+ RemainingDevicePath
+ );
+ if (!EFI_ERROR (Status)) {
+ SortedDriverBindingProtocols[Index] = NULL;
+ DriverFound = TRUE;
+
+//*** AMI PORTING BEGIN ***//
+//Print Name of the driver to be started
+#if defined(EFI_DEBUG) && defined(TRACE_START) && TRACE_START==1
+ Trace(-1, "%s.Start(%X)=", GetDriverName(DriverBinding), DriverBinding->Start);
+#endif
+//*** AMI PORTING END *****//
+ //
+ // A driver was found that supports ControllerHandle, so attempt to start the driver
+ // on ControllerHandle.
+ //
+ PERF_START (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
+ Status = DriverBinding->Start (
+ DriverBinding,
+ ControllerHandle,
+ RemainingDevicePath
+ );
+ PERF_END (DriverBinding->DriverBindingHandle, DRIVERBINDING_START_TOK, NULL, 0);
+//*** AMI PORTING BEGIN ***//
+//Print Name of the driver to be started
+#if defined(EFI_DEBUG) && defined(TRACE_START) && TRACE_START==1
+ Trace(-1, "%r\n", Status);
+#endif
+//*** AMI PORTING END *****//
+ if (!EFI_ERROR (Status)) {
+ //
+ // The driver was successfully started on ControllerHandle, so set a flag
+ //
+ OneStarted = TRUE;
+ }
+ }
+ }
+ }
+ } while (DriverFound);
+
+ //
+ // Free any buffers that were allocated with AllocatePool()
+ //
+ CoreFreePool (SortedDriverBindingProtocols);
+
+ //
+ // If at least one driver was started on ControllerHandle, then return EFI_SUCCESS.
+ //
+ if (OneStarted) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If no drivers started and RemainingDevicePath is an End Device Path Node, then return EFI_SUCCESS
+ //
+ if (RemainingDevicePath != NULL) {
+ if (IsDevicePathEnd (RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Otherwise, no drivers were started on ControllerHandle, so return EFI_NOT_FOUND
+ //
+ return EFI_NOT_FOUND;
+}
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreDisconnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle OPTIONAL,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Disonnects a controller from a driver
+
+Arguments:
+
+ ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
+ are to be disconnected.
+ DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
+ ChildHandle - ChildHandle The handle of the child to destroy.
+
+Returns:
+
+ EFI_SUCCESS - One or more drivers were disconnected from the controller.
+ EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
+ EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
+ EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
+ EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
+
+--*/
+{
+ EFI_STATUS Status;
+ IHANDLE *Handle;
+ EFI_HANDLE *DriverImageHandleBuffer;
+ EFI_HANDLE *ChildBuffer;
+ UINTN Index;
+ UINTN HandleIndex;
+ UINTN DriverImageHandleCount;
+ UINTN ChildrenToStop;
+ UINTN ChildBufferCount;
+ UINTN StopCount;
+ BOOLEAN Duplicate;
+ BOOLEAN ChildHandleValid;
+ BOOLEAN DriverImageHandleValid;
+ EFI_LIST_ENTRY *Link;
+ EFI_LIST_ENTRY *ProtLink;
+ OPEN_PROTOCOL_DATA *OpenData;
+ PROTOCOL_INTERFACE *Prot;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+
+ //
+ // Make sure ControllerHandle is valid
+ //
+ Status = CoreValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure ChildHandle is valid if it is not NULL
+ //
+ if (ChildHandle != NULL) {
+ Status = CoreValidateHandle (ChildHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ Handle = ControllerHandle;
+
+ //
+ // Get list of drivers that are currently managing ControllerHandle
+ //
+ DriverImageHandleBuffer = NULL;
+ DriverImageHandleCount = 1;
+
+ if (DriverImageHandle == NULL) {
+ //
+ // Look at each protocol interface for a match
+ //
+ DriverImageHandleCount = 0;
+
+ CoreAcquireProtocolLock ();
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ for (ProtLink = Prot->OpenList.ForwardLink;
+ ProtLink != &Prot->OpenList;
+ ProtLink = ProtLink->ForwardLink) {
+ OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
+ DriverImageHandleCount++;
+ }
+ }
+ }
+ CoreReleaseProtocolLock ();
+
+ //
+ // If there are no drivers managing this controller, then return EFI_SUCCESS
+ //
+ if (DriverImageHandleCount == 0) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ DriverImageHandleBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * DriverImageHandleCount);
+ if (DriverImageHandleBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ DriverImageHandleCount = 0;
+
+ CoreAcquireProtocolLock ();
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ for (ProtLink = Prot->OpenList.ForwardLink;
+ ProtLink != &Prot->OpenList;
+ ProtLink = ProtLink->ForwardLink) {
+ OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
+ Duplicate = FALSE;
+ for (Index = 0; Index< DriverImageHandleCount; Index++) {
+ if (DriverImageHandleBuffer[Index] == OpenData->AgentHandle) {
+ Duplicate = TRUE;
+ break;
+ }
+ }
+ if (!Duplicate) {
+ DriverImageHandleBuffer[DriverImageHandleCount] = OpenData->AgentHandle;
+ DriverImageHandleCount++;
+ }
+ }
+ }
+ }
+ CoreReleaseProtocolLock ();
+ }
+
+ StopCount = 0;
+ for (HandleIndex = 0; HandleIndex < DriverImageHandleCount; HandleIndex++) {
+
+ if (DriverImageHandleBuffer != NULL) {
+ DriverImageHandle = DriverImageHandleBuffer[HandleIndex];
+ }
+
+ //
+ // Get the Driver Binding Protocol of the driver that is managing this controller
+ //
+ Status = CoreHandleProtocol (
+ DriverImageHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &DriverBinding
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Look at each protocol interface for a match
+ //
+ DriverImageHandleValid = FALSE;
+ ChildBufferCount = 0;
+
+ CoreAcquireProtocolLock ();
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ for (ProtLink = Prot->OpenList.ForwardLink;
+ ProtLink != &Prot->OpenList;
+ ProtLink = ProtLink->ForwardLink) {
+ OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if (OpenData->AgentHandle == DriverImageHandle) {
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+ ChildBufferCount++;
+ }
+ if ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) != 0) {
+ DriverImageHandleValid = TRUE;
+ }
+ }
+ }
+ }
+ CoreReleaseProtocolLock ();
+
+ if (DriverImageHandleValid) {
+ ChildHandleValid = FALSE;
+ ChildBuffer = NULL;
+ if (ChildBufferCount != 0) {
+ ChildBuffer = CoreAllocateBootServicesPool (sizeof (EFI_HANDLE) * ChildBufferCount);
+ if (ChildBuffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ ChildBufferCount = 0;
+
+ CoreAcquireProtocolLock ();
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ for (ProtLink = Prot->OpenList.ForwardLink;
+ ProtLink != &Prot->OpenList;
+ ProtLink = ProtLink->ForwardLink) {
+ OpenData = CR (ProtLink, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if ((OpenData->AgentHandle == DriverImageHandle) &&
+ ((OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0)) {
+ Duplicate = FALSE;
+ for (Index = 0; Index < ChildBufferCount; Index++) {
+ if (ChildBuffer[Index] == OpenData->ControllerHandle) {
+ Duplicate = TRUE;
+ break;
+ }
+ }
+ if (!Duplicate) {
+ ChildBuffer[ChildBufferCount] = OpenData->ControllerHandle;
+ if (ChildHandle == ChildBuffer[ChildBufferCount]) {
+ ChildHandleValid = TRUE;
+ }
+ ChildBufferCount++;
+ }
+ }
+ }
+ }
+ CoreReleaseProtocolLock ();
+ }
+
+ if (ChildHandle == NULL || ChildHandleValid) {
+ ChildrenToStop = 0;
+ Status = EFI_SUCCESS;
+//*** AMI PORTING BEGIN ***//
+//Print Name of the driver to be stopped
+#if defined(EFI_DEBUG) && defined(TRACE_STOP) && TRACE_STOP==1
+ Trace(-1, "%s.Stop=", GetDriverName(DriverBinding));
+#endif
+//*** AMI PORTING END *****//
+ if (ChildBufferCount > 0) {
+ if (ChildHandle != NULL) {
+ ChildrenToStop = 1;
+ Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, &ChildHandle);
+ } else {
+ ChildrenToStop = ChildBufferCount;
+ Status = DriverBinding->Stop (DriverBinding, ControllerHandle, ChildrenToStop, ChildBuffer);
+ }
+ }
+ if (!EFI_ERROR (Status) && ((ChildHandle == NULL) || (ChildBufferCount == ChildrenToStop))) {
+ Status = DriverBinding->Stop (DriverBinding, ControllerHandle, 0, NULL);
+ }
+//*** AMI PORTING BEGIN ***//
+//Print Name of the driver to be stopped
+#if defined(EFI_DEBUG) && defined(TRACE_STOP) && TRACE_STOP==1
+ Trace(-1, "%r\n", Status);
+#endif
+//*** AMI PORTING END *****//
+
+ if (!EFI_ERROR (Status)) {
+ StopCount++;
+ }
+ }
+
+ if (ChildBuffer != NULL) {
+ CoreFreePool (ChildBuffer);
+ }
+ }
+ }
+
+ if (StopCount > 0) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_NOT_FOUND;
+ }
+
+Done:
+
+ if (DriverImageHandleBuffer != NULL) {
+ CoreFreePool (DriverImageHandleBuffer);
+ }
+
+ return Status;
+}
diff --git a/Core/CORE_DXE/DxeCore.h b/Core/CORE_DXE/DxeCore.h
new file mode 100644
index 0000000..0fb2611
--- /dev/null
+++ b/Core/CORE_DXE/DxeCore.h
@@ -0,0 +1,2542 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DxeCore.h
+
+Abstract:
+
+Revision History
+
+--*/
+
+#ifndef _DXECORE_H_
+#define _DXECORE_H_
+
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+#include EFI_GUID_DEFINITION (Hob)
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+#include EFI_GUID_DEFINITION (DxeServices)
+#include EFI_GUID_DEFINITION (MemoryTypeInformation)
+#include EFI_GUID_DEFINITION (StatusCodeCallerId)
+#include EFI_GUID_DEFINITION (EventGroup)
+#include EFI_GUID_DEFINITION (EventLegacyBios)
+#include EFI_GUID_DEFINITION (FrameworkDevicePath)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Cpu)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Metronome)
+#include EFI_ARCH_PROTOCOL_DEFINITION (MonotonicCounter)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Timer)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Bds)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Reset)
+#include EFI_ARCH_PROTOCOL_DEFINITION (RealTimeClock)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Variable)
+#include EFI_ARCH_PROTOCOL_DEFINITION (VariableWrite)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Capsule)
+#include EFI_ARCH_PROTOCOL_DEFINITION (WatchdogTimer)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Runtime)
+#include EFI_ARCH_PROTOCOL_DEFINITION (StatusCode)
+#include EFI_ARCH_PROTOCOL_DEFINITION (Security)
+//*** AMI PORTING BEGIN ***//
+#include EFI_ARCH_PROTOCOL_DEFINITION (Security2)
+//*** AMI PORTING END ***//
+#include EFI_PROTOCOL_DEFINITION (Decompress)
+#include EFI_PROTOCOL_DEFINITION (TianoDecompress)
+#include EFI_PROTOCOL_DEFINITION (CustomizedDecompress)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume2)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolumeDispatch)
+#include EFI_PROTOCOL_DEFINITION (LoadedImage)
+#include EFI_PROTOCOL_DEFINITION (TcgService)
+#include "LinkedList.h"
+#include "DebugImageInfo.h"
+#include "EfiCommonLib.h"
+#include "Library.h"
+#include "Peihob.h"
+#include "EfiHobLib.h"
+#include "DebugMask.h"
+
+
+typedef struct {
+ EFI_GUID *ProtocolGuid;
+ VOID **Protocol;
+ EFI_EVENT Event;
+ VOID *Registration;
+ BOOLEAN Present;
+} ARCHITECTURAL_PROTOCOL_ENTRY;
+
+
+//
+// DXE Dispatcher Data structures
+//
+
+#define KNOWN_HANDLE_SIGNATURE EFI_SIGNATURE_32('k','n','o','w')
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY Link; // mFvHandleList
+ EFI_HANDLE Handle;
+} KNOWN_HANDLE;
+
+
+#define EFI_CORE_DRIVER_ENTRY_SIGNATURE EFI_SIGNATURE_32('d','r','v','r')
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY Link; // mDriverList
+
+ EFI_LIST_ENTRY ScheduledLink; // mScheduledQueue
+
+ EFI_HANDLE FvHandle;
+ EFI_GUID FileName;
+ EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+ VOID *Depex;
+ UINTN DepexSize;
+
+ BOOLEAN Before;
+ BOOLEAN After;
+ EFI_GUID BeforeAfterGuid;
+
+ BOOLEAN Dependent;
+ BOOLEAN Unrequested;
+ BOOLEAN Scheduled;
+ BOOLEAN Untrusted;
+ BOOLEAN Initialized;
+ BOOLEAN DepexProtocolError;
+
+ EFI_HANDLE ImageHandle;
+
+} EFI_CORE_DRIVER_ENTRY;
+
+//
+//The data structure of GCD memory map entry
+//
+#define EFI_GCD_MAP_SIGNATURE EFI_SIGNATURE_32('g','c','d','m')
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY Link;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 EndAddress;
+ UINT64 Capabilities;
+ UINT64 Attributes;
+ EFI_GCD_MEMORY_TYPE GcdMemoryType;
+ EFI_GCD_IO_TYPE GcdIoType;
+ EFI_HANDLE ImageHandle;
+ EFI_HANDLE DeviceHandle;
+} EFI_GCD_MAP_ENTRY;
+
+//
+// DXE Core Global Variables
+//
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_RUNTIME_SERVICES *gRT;
+extern EFI_DXE_SERVICES *gDS;
+extern EFI_HANDLE gDxeCoreImageHandle;
+
+extern EFI_DECOMPRESS_PROTOCOL *gEfiDecompress;
+extern EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *gEfiPeiFlushInstructionCache;
+extern EFI_PEI_PE_COFF_LOADER_PROTOCOL *gEfiPeiPeCoffLoader;
+extern EFI_PEI_TRANSFER_CONTROL_PROTOCOL *gEfiPeiTransferControl;
+
+extern EFI_RUNTIME_ARCH_PROTOCOL *gRuntime;
+extern EFI_CPU_ARCH_PROTOCOL *gCpu;
+extern EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer;
+extern EFI_METRONOME_ARCH_PROTOCOL *gMetronome;
+extern EFI_TIMER_ARCH_PROTOCOL *gTimer;
+extern EFI_SECURITY_ARCH_PROTOCOL *gSecurity;
+//*** AMI PORTING BEGIN ***//
+extern EFI_SECURITY2_ARCH_PROTOCOL *gSecurity2;
+//*** AMI PORTING END ***//
+extern EFI_BDS_ARCH_PROTOCOL *gBds;
+extern EFI_STATUS_CODE_PROTOCOL *gStatusCode;
+
+extern EFI_TPL gEfiCurrentTpl;
+
+extern EFI_GUID *gDxeCoreFileName;
+extern EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage;
+
+extern EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1];
+
+extern EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate;
+
+//
+// Service Initialization Functions
+//
+
+
+VOID
+CoreInitializePool (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Called to initialize the pool.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CoreAddMemoryDescriptor (
+ IN EFI_MEMORY_TYPE Type,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 NumberOfPages,
+ IN UINT64 Attribute
+ )
+/*++
+
+Routine Description:
+
+ Called to initialize the memory map and add descriptors to
+ the current descriptor list.
+
+ N.B. The first descriptor that is added must be general usable
+ memory as the addition allocates heap.
+
+Arguments:
+
+ Type - The type of memory to add
+
+ Start - The starting address in the memory range
+ Must be page aligned
+
+ NumberOfPages - The number of pages in the range
+
+ Attribute - Attributes of the memory to add
+
+Returns:
+
+ None. The range is added to the memory map
+
+--*/
+;
+
+VOID
+CoreReleaseGcdMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Release memory lock on mGcdMemorySpaceLock
+
+Arguments:
+ None
+
+Returns:
+ None
+
+--*/
+;
+
+VOID
+CoreAcquireGcdMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Acquire memory lock on mGcdMemorySpaceLock
+
+Arguments:
+ None
+
+Returns:
+ None
+
+--*/
+;
+
+EFI_STATUS
+CoreInitializeMemoryServices (
+ IN VOID **HobStart,
+ IN EFI_PHYSICAL_ADDRESS *MemoryBaseAddress,
+ IN UINT64 *MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ External function. Initializes the GCD and memory services based on the memory
+ descriptor HOBs. This function is responsible for priming the GCD map and the
+ memory map, so memory allocations and resource allocations can be made. The first
+ part of this function can not depend on any memory services until at least one
+ memory descriptor is provided to the memory services. Then the memory services
+ can be used to intialize the GCD map.
+
+Arguments:
+
+ HobStart - The start address of the HOB.
+
+ MemoryBaseAddress - Start address of memory region found to init DXE core.
+
+ MemoryLength - Length of memory region found to init DXE core.
+
+Returns:
+
+ EFI_SUCCESS - Memory services successfully initialized.
+
+--*/
+;
+
+
+EFI_STATUS
+CoreInitializeGcdServices (
+ IN OUT VOID **HobStart,
+ IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ External function. Initializes the GCD and memory services based on the memory
+ descriptor HOBs. This function is responsible for priming the GCD map and the
+ memory map, so memory allocations and resource allocations can be made. The first
+ part of this function can not depend on any memory services until at least one
+ memory descriptor is provided to the memory services. Then the memory services
+ can be used to intialize the GCD map. The HobStart will be relocated to a pool
+ buffer.
+
+Arguments:
+
+ HobStart - The start address of the HOB
+
+ MemoryBaseAddress - Start address of memory region found to init DXE core.
+
+ MemoryLength - Length of memory region found to init DXE core.
+
+
+Returns:
+
+ EFI_SUCCESS - GCD services successfully initialized.
+
+--*/
+;
+
+EFI_STATUS
+CoreInitializeEventServices (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initializes "event" support and populates parts of the System and Runtime Table.
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS - Always return success
+
+--*/
+;
+
+EFI_STATUS
+CoreInitializeImageServices (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Add the Image Services to EFI Boot Services Table and install the protocol
+ interfaces for this image.
+
+Arguments:
+
+ HobStart - The HOB to initialize
+
+Returns:
+
+ Status code.
+
+--*/
+;
+
+VOID
+CoreNotifyOnArchProtocolInstallation (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Creates an event that is fired everytime a Protocol of a specific type is installed
+
+Arguments:
+ NONE
+
+Returns:
+ NONE
+
+--*/
+;
+
+EFI_STATUS
+CoreAllEfiServicesAvailable (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Return TRUE if all AP services are availible.
+
+Arguments:
+ NONE
+
+Returns:
+ EFI_SUCCESS - All AP services are available
+ EFI_NOT_FOUND - At least one AP service is not available
+
+--*/
+;
+
+VOID
+CalculateEfiHdrCrc (
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+/*++
+
+Routine Description:
+
+ Calcualte the 32-bit CRC in a EFI table using the service provided by the
+ gRuntime service.
+
+Arguments:
+
+ Hdr - Pointer to an EFI standard header
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EFIAPI
+CoreTimerTick (
+ IN UINT64 Duration
+ )
+/*++
+
+Routine Description:
+
+ Called by the platform code to process a tick.
+
+Arguments:
+
+ Duration - The number of 100ns elasped since the last call to TimerTick
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CoreInitializeDispatcher (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initialize the dispatcher. Initialize the notification function that runs when
+ a FV protocol is added to the system.
+
+Arguments:
+
+ NONE
+
+Returns:
+
+ NONE
+
+--*/
+;
+
+BOOLEAN
+CoreIsSchedulable (
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. This code does
+ not need to handle Before or After, as it is not valid to call this
+ routine in this case. The SOR is just ignored and is a nop in the grammer.
+
+ POSTFIX means all the math is done on top of the stack.
+
+Arguments:
+
+ DriverEntry - DriverEntry element to update
+
+Returns:
+
+ TRUE - If driver is ready to run.
+
+ FALSE - If driver is not ready to run or some fatal error was found.
+
+--*/
+;
+
+EFI_STATUS
+CorePreProcessDepex (
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry
+ )
+/*++
+
+Routine Description:
+
+ Preprocess dependency expression and update DriverEntry to reflect the
+ state of Before, After, and SOR dependencies. If DriverEntry->Before
+ or DriverEntry->After is set it will never be cleared. If SOR is set
+ it will be cleared by CoreSchedule(), and then the driver can be
+ dispatched.
+
+Arguments:
+
+ DriverEntry - DriverEntry element to update
+
+Returns:
+
+ EFI_SUCCESS - It always works.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreExitBootServices (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+ )
+/*++
+
+Routine Description:
+
+ EFI 1.0 API to terminate Boot Services
+
+Arguments:
+
+ ImageHandle - Handle that represents the identity of the calling image
+
+ MapKey -Key to the latest memory map.
+
+Returns:
+
+ EFI_SUCCESS - Boot Services terminated
+ EFI_INVALID_PARAMETER - MapKey is incorrect.
+
+--*/
+;
+
+EFI_STATUS
+CoreTerminateMemoryMap (
+ IN UINTN MapKey
+ )
+/*++
+
+Routine Description:
+
+ Make sure the memory map is following all the construction rules,
+ it is the last time to check memory map error before exit boot services.
+
+Arguments:
+
+ MapKey - Memory map key
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Memory map not consistent with construction rules.
+
+ EFI_SUCCESS - Valid memory map.
+
+--*/
+;
+
+VOID
+CoreNotifySignalList (
+ IN EFI_GUID *EventGroup
+ )
+/*++
+
+Routine Description:
+
+ Signals all events on the requested list
+
+Arguments:
+
+ SignalType - The list to signal
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreInstallConfigurationTable (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ )
+/*++
+
+Routine Description:
+
+ Boot Service called to add, modify, or remove a system configuration table from
+ the EFI System Table.
+
+Arguments:
+
+ Guid: Pointer to the GUID for the entry to add, update, or remove
+ Table: Pointer to the configuration table for the entry to add, update, or
+ remove, may be NULL.
+
+Returns:
+
+ EFI_SUCCESS Guid, Table pair added, updated, or removed.
+ EFI_INVALID_PARAMETER Input GUID not valid.
+ EFI_NOT_FOUND Attempted to delete non-existant entry
+ EFI_OUT_OF_RESOURCES Not enough memory available
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_TPL
+EFIAPI
+CoreRaiseTpl (
+ IN EFI_TPL NewTpl
+ )
+/*++
+
+Routine Description:
+
+ Raise the task priority level to the new level.
+ High level is implemented by disabling processor interrupts.
+
+Arguments:
+
+ NewTpl - New task priority level
+
+Returns:
+
+ The previous task priority level
+
+--*/
+;
+
+EFI_BOOTSERVICE
+VOID
+EFIAPI
+CoreRestoreTpl (
+ IN EFI_TPL NewTpl
+ )
+/*++
+
+Routine Description:
+
+ Lowers the task priority to the previous value. If the new
+ priority unmasks events at a higher priority, they are dispatched.
+
+Arguments:
+
+ NewTpl - New, lower, task priority
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreStall (
+ IN UINTN Microseconds
+ )
+/*++
+
+Routine Description:
+
+ Introduces a fine-grained stall.
+
+Arguments:
+
+ Microseconds The number of microseconds to stall execution
+
+Returns:
+
+ EFI_SUCCESS - Execution was stalled for at least the requested amount
+ of microseconds.
+
+ EFI_NOT_AVAILABLE_YET - gMetronome is not available yet
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreSetWatchdogTimer (
+ IN UINTN Timeout,
+ IN UINT64 WatchdogCode,
+ IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Sets the system's watchdog timer.
+
+Arguments:
+
+ Timeout The number of seconds. Zero disables the timer.
+
+ ///////following three parameters are left for platform specific using
+
+ WatchdogCode The numberic code to log. 0x0 to 0xffff are firmware
+ DataSize Size of the optional data
+ WatchdogData Optional Null terminated unicode string followed by binary
+ data.
+
+Returns:
+
+ EFI_SUCCESS Timeout has been set
+ EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
+ EFI_UNSUPPORTED System does not have a timer (currently not used)
+ EFI_DEVICE_ERROR Could not complete due to hardware error
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreInstallProtocolInterface (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which
+ Calls the private one which contains a BOOLEAN parameter for notifications
+
+Arguments:
+
+ UserHandle - The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+
+ Protocol - The protocol to add to the handle
+
+ InterfaceType - Indicates whether Interface is supplied in native form.
+
+ Interface - The interface for the protocol being added
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+CoreInstallProtocolInterfaceNotify (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface,
+ IN BOOLEAN Notify
+ )
+/*++
+
+Routine Description:
+
+ Installs a protocol interface into the boot services environment.
+
+Arguments:
+
+ UserHandle - The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+
+ Protocol - The protocol to add to the handle
+
+ InterfaceType - Indicates whether Interface is supplied in native form.
+
+ Interface - The interface for the protocol being added
+
+ Notify - Whether to notify the notification list for this protocol
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Protocol interface successfully installed
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreInstallMultipleProtocolInterfaces (
+ IN OUT EFI_HANDLE *Handle,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Installs a list of protocol interface into the boot services environment.
+ This function calls InstallProtocolInterface() in a loop. If any error
+ occures all the protocols added by this function are removed. This is
+ basically a lib function to save space.
+
+Arguments:
+
+ Handle - The handle to install the protocol handlers on,
+ or NULL if a new handle is to be allocated
+ ... - EFI_GUID followed by protocol instance. A NULL terminates the
+ list. The pairs are the arguments to InstallProtocolInterface().
+ All the protocols are added to Handle.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Handle is NULL.
+
+ EFI_SUCCESS - Protocol interfaces successfully installed.
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreUninstallMultipleProtocolInterfaces (
+ IN EFI_HANDLE Handle,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Uninstalls a list of protocol interface in the boot services environment.
+ This function calls UnisatllProtocolInterface() in a loop. This is
+ basically a lib function to save space.
+
+Arguments:
+
+ Handle - The handle to uninstall the protocol
+
+ ... - EFI_GUID followed by protocol instance. A NULL terminates the
+ list. The pairs are the arguments to UninstallProtocolInterface().
+ All the protocols are added to Handle.
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreReinstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *OldInterface,
+ IN VOID *NewInterface
+ )
+/*++
+
+Routine Description:
+
+ Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
+
+Arguments:
+
+ UserHandle - Handle on which the interface is to be reinstalled
+ Protocol - The numeric ID of the interface
+ OldInterface - A pointer to the old interface
+ NewInterface - A pointer to the new interface
+
+
+Returns:
+
+ Status code.
+
+ On EFI_SUCCESS The protocol interface was installed
+ On EFI_NOT_FOUND The OldInterface on the handle was not found
+ On EFI_INVALID_PARAMETER One of the parameters has an invalid value
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreUninstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Uninstalls all instances of a protocol:interfacer from a handle.
+ If the last protocol interface is remove from the handle, the
+ handle is freed.
+
+Arguments:
+
+ UserHandle - The handle to remove the protocol handler from
+
+ Protocol - The protocol, of protocol:interface, to remove
+
+ Interface - The interface, of protocol:interface, to remove
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Protocol is NULL.
+
+ EFI_SUCCESS - Protocol interface successfully uninstalled.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreHandleProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Queries a handle to determine if it supports a specified protocol.
+
+Arguments:
+
+ UserHandle - The handle being queried.
+
+ Protocol - The published unique identifier of the protocol.
+
+ Interface - Supplies the address where a pointer to the corresponding Protocol
+ Interface is returned.
+
+Returns:
+
+ The requested protocol interface for the handle
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreOpenProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface OPTIONAL,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT32 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Locates the installed protocol handler for the handle, and
+ invokes it to obtain the protocol interface. Usage information
+ is registered in the protocol data base.
+
+Arguments:
+
+ UserHandle - The handle to obtain the protocol interface on
+
+ Protocol - The ID of the protocol
+
+ Interface - The location to return the protocol interface
+
+ ImageHandle - The handle of the Image that is opening the protocol interface
+ specified by Protocol and Interface.
+
+ ControllerHandle - The controller handle that is requiring this interface.
+
+ Attributes - The open mode of the protocol interface specified by Handle
+ and Protocol.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Protocol is NULL.
+
+ EFI_SUCCESS - Get the protocol interface.
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreOpenProtocolInformation (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+ )
+/*++
+
+Routine Description:
+
+ Return information about Opened protocols in the system
+
+Arguments:
+
+ UserHandle - The handle to close the protocol interface on
+
+ Protocol - The ID of the protocol
+
+ EntryBuffer - A pointer to a buffer of open protocol information in the form of
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
+
+ EntryCount - Number of EntryBuffer entries
+
+Returns:
+
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreCloseProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle
+ )
+/*++
+
+Routine Description:
+
+ Close Protocol
+
+Arguments:
+
+ UserHandle - The handle to close the protocol interface on
+
+ Protocol - The ID of the protocol
+
+ ImageHandle - The user of the protocol to close
+
+ ControllerHandle - The user of the protocol to close
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Protocol is NULL.
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreProtocolsPerHandle (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
+ from pool.
+
+Arguments:
+
+ UserHandle - The handle from which to retrieve the list of protocol interface
+ GUIDs.
+
+ ProtocolBuffer - A pointer to the list of protocol interface GUID pointers that are
+ installed on Handle.
+
+ ProtocolBufferCount - A pointer to the number of GUID pointers present in
+ ProtocolBuffer.
+
+Returns:
+ EFI_SUCCESS - The list of protocol interface GUIDs installed on Handle was returned in
+ ProtocolBuffer. The number of protocol interface GUIDs was
+ returned in ProtocolBufferCount.
+ EFI_INVALID_PARAMETER - Handle is NULL.
+ EFI_INVALID_PARAMETER - Handle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ProtocolBuffer is NULL.
+ EFI_INVALID_PARAMETER - ProtocolBufferCount is NULL.
+ EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the results.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreRegisterProtocolNotify (
+ IN EFI_GUID *Protocol,
+ IN EFI_EVENT Event,
+ OUT VOID **Registration
+ )
+/*++
+
+Routine Description:
+
+ Add a new protocol notification record for the request protocol.
+
+Arguments:
+
+ Protocol - The requested protocol to add the notify registration
+
+ Event - The event to signal
+
+ Registration - Returns the registration record
+
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_SUCCESS - Successfully returned the registration record that has been added
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreLocateHandle (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Locates the requested handle(s) and returns them in Buffer.
+
+Arguments:
+
+ SearchType - The type of search to perform to locate the handles
+
+ Protocol - The protocol to search for
+
+ SearchKey - Dependant on SearchType
+
+ BufferSize - On input the size of Buffer. On output the
+ size of data returned.
+
+ Buffer - The buffer to return the results in
+
+
+Returns:
+
+ EFI_BUFFER_TOO_SMALL - Buffer too small, required buffer size is returned in BufferSize.
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_SUCCESS - Successfully found the requested handle(s) and returns them in Buffer.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreLocateDevicePath (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT EFI_HANDLE *Device
+ )
+/*++
+
+Routine Description:
+
+ Locates the handle to a device on the device path that supports the specified protocol.
+
+Arguments:
+
+ Protocol - The protocol to search for.
+ FilePath - On input, a pointer to a pointer to the device path. On output, the device
+ path pointer is modified to point to the remaining part of the devicepath.
+ Device - A pointer to the returned device handle.
+
+Returns:
+
+ EFI_SUCCESS - The resulting handle was returned.
+ EFI_NOT_FOUND - No handles matched the search.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreLocateHandleBuffer (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Function returns an array of handles that support the requested protocol
+ in a buffer allocated from pool. This is a version of CoreLocateHandle()
+ that allocates a buffer for the caller.
+
+Arguments:
+
+ SearchType - Specifies which handle(s) are to be returned.
+ Protocol - Provides the protocol to search by.
+ This parameter is only valid for SearchType ByProtocol.
+ SearchKey - Supplies the search key depending on the SearchType.
+ NumberHandles - The number of handles returned in Buffer.
+ Buffer - A pointer to the buffer to return the requested array of
+ handles that support Protocol.
+
+Returns:
+
+ EFI_SUCCESS - The result array of handles was returned.
+ EFI_NOT_FOUND - No handles match the search.
+ EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the matching results.
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreLocateProtocol (
+ IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Return the first Protocol Interface that matches the Protocol GUID. If
+ Registration is pasased in return a Protocol Instance that was just add
+ to the system. If Retistration is NULL return the first Protocol Interface
+ you find.
+
+Arguments:
+
+ Protocol - The protocol to search for
+
+ Registration - Optional Registration Key returned from RegisterProtocolNotify()
+
+ Interface - Return the Protocol interface (instance).
+
+Returns:
+
+ EFI_SUCCESS - If a valid Interface is returned
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_NOT_FOUND - Protocol interface not found
+
+--*/
+;
+
+UINT64
+CoreGetHandleDatabaseKey (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ return handle database key.
+
+Arguments:
+
+ None
+
+Returns:
+
+ Handle database key.
+
+--*/
+;
+
+VOID
+CoreConnectHandlesByKey (
+ UINT64 Key
+ )
+/*++
+
+Routine Description:
+
+ Go connect any handles that were created or modified while a image executed.
+
+Arguments:
+
+ Key - The Key to show that the handle has been created/modified
+
+Returns:
+
+ None
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreConnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE *DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive
+ )
+/*++
+
+Routine Description:
+
+ Connects one or more drivers to a controller.
+
+Arguments:
+
+ ControllerHandle - Handle of the controller to be connected.
+
+ DriverImageHandle - DriverImageHandle A pointer to an ordered list of driver image handles.
+
+ RemainingDevicePath - RemainingDevicePath A pointer to the device path that specifies a child of the
+ controller specified by ControllerHandle.
+
+ Recursive - - Whether the function would be called recursively or not.
+
+Returns:
+
+ Status code.
+
+--*/
+;
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreDisconnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle OPTIONAL,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Disonnects a controller from a driver
+
+Arguments:
+
+ ControllerHandle - ControllerHandle The handle of the controller from which driver(s)
+ are to be disconnected.
+ DriverImageHandle - DriverImageHandle The driver to disconnect from ControllerHandle.
+ ChildHandle - ChildHandle The handle of the child to destroy.
+
+Returns:
+
+ EFI_SUCCESS - One or more drivers were disconnected from the controller.
+ EFI_SUCCESS - On entry, no drivers are managing ControllerHandle.
+ EFI_SUCCESS - DriverImageHandle is not NULL, and on entry DriverImageHandle is not managing ControllerHandle.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - DriverImageHandle is not NULL, and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL, and it is not a valid EFI_HANDLE.
+ EFI_OUT_OF_RESOURCES - There are not enough resources available to disconnect any drivers from ControllerHandle.
+ EFI_DEVICE_ERROR - The controller could not be disconnected because of a device error.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreAllocatePages (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Allocates pages from the memory map.
+
+Arguments:
+
+ Type - The type of allocation to perform
+
+ MemoryType - The type of memory to turn the allocated pages into
+
+ NumberOfPages - The number of pages to allocate
+
+ Memory - A pointer to receive the base allocated memory address
+
+Returns:
+
+ Status. On success, Memory is filled in with the base address allocated
+
+ EFI_INVALID_PARAMETER - Parameters violate checking rules defined in spec.
+
+ EFI_NOT_FOUND - Could not allocate pages match the requirement.
+
+ EFI_OUT_OF_RESOURCES - No enough pages to allocate.
+
+ EFI_SUCCESS - Pages successfully allocated.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreFreePages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+/*++
+
+Routine Description:
+
+ Frees previous allocated pages.
+
+Arguments:
+
+ Memory - Base address of memory being freed
+
+ NumberOfPages - The number of pages to free
+
+Returns:
+
+ EFI_NOT_FOUND - Could not find the entry that covers the range
+
+ EFI_INVALID_PARAMETER - Address not aligned
+
+ EFI_SUCCESS -Pages successfully freed.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreGetMemoryMap (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *Desc,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ )
+/*++
+
+Routine Description:
+
+ Returns the current memory map.
+
+Arguments:
+
+ MemoryMapSize - On input the buffer size of MemoryMap allocated by caller
+ On output the required buffer size to contain the memory map
+
+ Desc - The buffer to return the current memory map
+
+ MapKey - The address to return the current map key
+
+ DescriptorSize - The size in bytes for an individual EFI_MEMORY_DESCRIPTOR
+
+ DescriptorVersion - The version number associated with the EFI_MEMORY_DESCRIPTOR
+
+Returns:
+
+ EFI_SUCCESS The current memory map was returned successfully
+
+ EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small
+
+ EFI_INVALID_PARAMETER One of the parameters has an invalid value
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreAllocatePool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of a particular type.
+
+Arguments:
+
+ PoolType - Type of pool to allocate
+
+ Size - The amount of pool to allocate
+
+ Buffer - The address to return a pointer to the allocated pool
+
+Returns:
+
+ EFI_INVALID_PARAMETER - PoolType not valid
+
+ EFI_OUT_OF_RESOURCES - Size exceeds max pool size or allocation failed.
+
+ EFI_SUCCESS - Pool successfully allocated.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreFreePool (
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Frees pool.
+
+Arguments:
+
+ Buffer - The allocated pool entry to free
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Buffer is not a valid value.
+
+ EFI_SUCCESS - Pool successfully freed.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreLoadImage (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Loads an EFI image into memory and returns a handle to the image.
+
+Arguments:
+
+ BootPolicy - If TRUE, indicates that the request originates from the boot manager,
+ and that the boot manager is attempting to load FilePath as a boot selection.
+ ParentImageHandle - The caller's image handle.
+ FilePath - The specific file path from which the image is loaded.
+ SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
+ the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ ImageHandle - Pointer to the returned image handle that is created when the image
+ is successfully loaded.
+
+Returns:
+
+ EFI_SUCCESS - The image was loaded into memory.
+ EFI_NOT_FOUND - The FilePath was not found.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
+ parsed to locate the proper protocol for loading the file.
+ EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreUnloadImage (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Unload the specified image.
+
+Arguments:
+
+ ImageHandle - The specified image handle.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Image handle is NULL.
+
+ EFI_UNSUPPORTED - Attempt to unload an unsupported image.
+
+ EFI_SUCCESS - Image successfully unloaded.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreStartImage (
+ IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Transfer control to a loaded image's entry point.
+
+Arguments:
+
+ ImageHandle - Handle of image to be started.
+
+ ExitDataSize - Pointer of the size to ExitData
+
+ ExitData - Pointer to a pointer to a data buffer that includes a Null-terminated
+ Unicode string, optionally followed by additional binary data. The string
+ is a description that the caller may use to further indicate the reason for
+ the image's exit.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Successfully transfer control to the image's entry point.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreExit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS Status,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Terminates the currently loaded EFI image and returns control to boot services.
+
+Arguments:
+
+ ImageHandle - Handle that identifies the image. This parameter is passed to the image
+ on entry.
+ Status - The image's exit code.
+ ExitDataSize - The size, in bytes, of ExitData. Ignored if ExitStatus is
+ EFI_SUCCESS.
+ ExitData - Pointer to a data buffer that includes a Null-terminated Unicode string,
+ optionally followed by additional binary data. The string is a
+ description that the caller may use to further indicate the reason for
+ the image's exit.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Image handle is NULL or it is not current image.
+
+ EFI_SUCCESS - Successfully terminates the currently loaded EFI image.
+
+ EFI_ACCESS_DENIED - Should never reach there.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCreateEvent (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ OUT EFI_EVENT *pEvent
+ )
+/*++
+
+Routine Description:
+
+ Creates a general-purpose event structure
+
+Arguments:
+
+ Type - The type of event to create and its mode and attributes
+ NotifyTpl - The task priority level of event notifications
+ NotifyFunction - Pointer to the event's notification function
+ NotifyContext - Pointer to the notification function's context; corresponds to
+ parameter "Context" in the notification function
+ pEvent - Pointer to the newly created event if the call succeeds; undefined otherwise
+
+Returns:
+
+ EFI_SUCCESS - The event structure was created
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value
+ EFI_OUT_OF_RESOURCES - The event could not be allocated
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCreateEventEx (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ IN CONST EFI_GUID *EventGroup, OPTIONAL
+ OUT EFI_EVENT *Event
+ )
+/*++
+
+Routine Description:
+ Creates a general-purpose event structure
+
+Arguments:
+ Type - The type of event to create and its mode and attributes
+ NotifyTpl - The task priority level of event notifications
+ NotifyFunction - Pointer to the events notification function
+ NotifyContext - Pointer to the notification functions context; corresponds to
+ parameter "Context" in the notification function
+ EventGrout - GUID for EventGroup if NULL act the same as gBS->CreateEvent().
+ Event - Pointer to the newly created event if the call succeeds; undefined otherwise
+
+Returns:
+ EFI_SUCCESS - The event structure was created
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value
+ EFI_OUT_OF_RESOURCES - The event could not be allocated
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreSetTimer (
+ IN EFI_EVENT Event,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime
+ )
+/*++
+
+Routine Description:
+
+ Sets the type of timer and the trigger time for a timer event.
+
+Arguments:
+
+ UserEvent - The timer event that is to be signaled at the specified time
+ Type - The type of time that is specified in TriggerTime
+ TriggerTime - The number of 100ns units until the timer expires
+
+Returns:
+
+ EFI_SUCCESS - The event has been set to be signaled at the requested time
+ EFI_INVALID_PARAMETER - Event or Type is not valid
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreSignalEvent (
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ Signals the event. Queues the event to be notified if needed
+
+Arguments:
+
+ Event - The event to signal
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Parameters are not valid.
+
+ EFI_SUCCESS - The event was signaled.
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreWaitForEvent (
+ IN UINTN NumberOfEvents,
+ IN EFI_EVENT *UserEvents,
+ OUT UINTN *UserIndex
+ )
+/*++
+
+Routine Description:
+
+ Stops execution until an event is signaled.
+
+Arguments:
+
+ NumberOfEvents - The number of events in the UserEvents array
+ UserEvents - An array of EFI_EVENT
+ UserIndex - Pointer to the index of the event which satisfied the wait condition
+
+Returns:
+
+ EFI_SUCCESS - The event indicated by Index was signaled.
+ EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or
+ Event was not a valid type
+ EFI_UNSUPPORTED - The current TPL is not TPL_APPLICATION
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCloseEvent (
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ Closes an event and frees the event structure.
+
+Arguments:
+
+ UserEvent - Event to close
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Parameters are not valid.
+
+ EFI_SUCCESS - The event has been closed
+
+--*/
+;
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCheckEvent (
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ Check the status of an event
+
+Arguments:
+
+ UserEvent - The event to check
+
+Returns:
+
+ EFI_SUCCESS - The event is in the signaled state
+ EFI_NOT_READY - The event is not in the signaled state
+ EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL
+
+--*/
+;
+
+EFI_STATUS
+CoreAddMemorySpace (
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Capabilities
+ )
+/*++
+
+Routine Description:
+
+ Add a segment of memory space to GCD map and add all available pages in this segment
+ as memory descriptors.
+
+Arguments:
+
+ GcdMemoryType - Memory type of the segment.
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+ Capabilities - alterable attributes of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Merged this segment into GCD map.
+
+--*/
+;
+
+EFI_STATUS
+CoreAllocateMemorySpace (
+ IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN UINTN Alignment,
+ IN UINT64 Length,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Allocate memory space on GCD map.
+
+Arguments:
+
+ GcdAllocateType - The type of allocate operation
+
+ GcdMemoryType - The desired memory type
+
+ Alignment - Align with 2^Alignment
+
+ Length - Length to allocate
+
+ BaseAddress - Base address to allocate
+
+ ImageHandle - The image handle consume the allocated space.
+
+ DeviceHandle - The device handle consume the allocated space.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+ EFI_NOT_FOUND - No descriptor contains the desired space.
+
+ EFI_SUCCESS - Memory space successfully allocated.
+
+--*/
+;
+
+EFI_STATUS
+CoreFreeMemorySpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:Routine Description:
+
+ Free a segment of memory space in GCD map.
+
+Arguments:
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Space successfully freed.
+
+--*/
+;
+
+EFI_STATUS
+CoreRemoveMemorySpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:Routine Description:
+
+ Remove a segment of memory space in GCD map.
+
+Arguments:
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Successfully a segment of memory space.
+
+--*/
+;
+
+EFI_STATUS
+CoreGetMemorySpaceDescriptor (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor
+ )
+/*++
+
+Routine Description:
+
+ Search all entries in GCD map which contains specified segment and build it to a descriptor.
+
+Arguments:
+
+ BaseAddress - Specified start address
+
+ Descriptor - Specified length
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_SUCCESS - Successfully get memory space descriptor.
+
+--*/
+;
+
+EFI_STATUS
+CoreSetMemorySpaceAttributes (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Set memory space with specified attributes.
+
+Arguments:
+
+ BaseAddress - Specified start address
+
+ Length - Specified length
+
+ Attributes - Specified attributes
+
+Returns:
+
+ EFI_SUCCESS - Successfully set attribute of a segment of memory space.
+
+--*/
+;
+
+EFI_STATUS
+CoreGetMemorySpaceMap (
+ OUT UINTN *NumberOfDescriptors,
+ OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap
+ )
+/*++
+
+Routine Description:
+
+ Transer all entries of GCD memory map into memory descriptors and pass to caller.
+
+Arguments:
+
+ NumberOfDescriptors - Number of descriptors.
+
+ MemorySpaceMap - Descriptor array
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Successfully get memory space map.
+
+--*/
+;
+
+EFI_STATUS
+CoreAddIoSpace (
+ IN EFI_GCD_IO_TYPE GcdIoType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Add a segment of IO space to GCD map.
+
+Arguments:
+
+ GcdIoType - IO type of the segment.
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Merged this segment into GCD map.
+
+--*/
+;
+
+EFI_STATUS
+CoreAllocateIoSpace (
+ IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
+ IN EFI_GCD_IO_TYPE GcdIoType,
+ IN UINTN Alignment,
+ IN UINT64 Length,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Allocate IO space on GCD map.
+
+Arguments:
+
+ GcdAllocateType - The type of allocate operation
+
+ GcdIoType - The desired IO type
+
+ Alignment - Align with 2^Alignment
+
+ Length - Length to allocate
+
+ BaseAddress - Base address to allocate
+
+ ImageHandle - The image handle consume the allocated space.
+
+ DeviceHandle - The device handle consume the allocated space.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+ EFI_NOT_FOUND - No descriptor contains the desired space.
+
+ EFI_SUCCESS - IO space successfully allocated.
+
+--*/
+;
+
+EFI_STATUS
+CoreFreeIoSpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:Routine Description:
+
+ Free a segment of IO space in GCD map.
+
+Arguments:
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Space successfully freed.
+
+--*/
+;
+
+EFI_STATUS
+CoreRemoveIoSpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:Routine Description:
+
+ Remove a segment of IO space in GCD map.
+
+Arguments:
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Successfully removed a segment of IO space.
+
+--*/
+;
+
+EFI_STATUS
+CoreGetIoSpaceDescriptor (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ OUT EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor
+ )
+/*++
+
+Routine Description:
+
+ Search all entries in GCD map which contains specified segment and build it to a descriptor.
+
+Arguments:
+
+ BaseAddress - Specified start address
+
+ Descriptor - Specified length
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Descriptor is NULL.
+
+ EFI_SUCCESS - Successfully get the IO space descriptor.
+
+--*/
+;
+
+EFI_STATUS
+CoreGetIoSpaceMap (
+ OUT UINTN *NumberOfDescriptors,
+ OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap
+ )
+/*++
+
+Routine Description:
+
+ Transer all entries of GCD IO map into IO descriptors and pass to caller.
+
+Arguments:
+
+ NumberOfDescriptors - Number of descriptors.
+
+ IoSpaceMap - Descriptor array
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Successfully get IO space map.
+
+--*/
+;
+
+EFI_DXESERVICE
+EFI_STATUS
+EFIAPI
+CoreDispatcher (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ This is the main Dispatcher for DXE and it exits when there are no more
+ drivers to run. Drain the mScheduledQueue and load and start a PE
+ image for each driver. Search the mDiscoveredList to see if any driver can
+ be placed on the mScheduledQueue. If no drivers are placed on the
+ mScheduledQueue exit the function. On exit it is assumed the Bds()
+ will be called, and when the Bds() exits the Dispatcher will be called
+ again.
+
+Arguments:
+
+ NONE
+
+Returns:
+
+ EFI_ALREADY_STARTED - The DXE Dispatcher is already running
+
+ EFI_NOT_FOUND - No DXE Drivers were dispatched
+
+ EFI_SUCCESS - One or more DXE Drivers were dispatched
+
+--*/
+;
+EFI_DXESERVICE
+EFI_STATUS
+EFIAPI
+CoreSchedule (
+ IN EFI_HANDLE FirmwareVolumeHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Check every driver and locate a matching one. If the driver is found, the Unrequested
+ state flag is cleared.
+
+Arguments:
+
+ FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
+ file specified by DriverName.
+
+ DriverName - The Driver name to put in the Dependent state.
+
+Returns:
+
+ EFI_SUCCESS - The DriverName was found and it's SOR bit was cleared
+
+ EFI_NOT_FOUND - The DriverName does not exist or it's SOR bit was not set.
+
+--*/
+;
+
+EFI_DXESERVICE
+EFI_STATUS
+EFIAPI
+CoreTrust (
+ IN EFI_HANDLE FirmwareVolumeHandle,
+ IN EFI_GUID *DriverName
+ )
+/*++
+
+Routine Description:
+
+ Convert a driver from the Untrused back to the Scheduled state
+
+Arguments:
+
+ FirmwareVolumeHandle - The handle of the Firmware Volume that contains the firmware
+ file specified by DriverName.
+
+ DriverName - The Driver name to put in the Scheduled state
+
+Returns:
+
+ EFI_SUCCESS - The file was found in the untrusted state, and it was promoted
+ to the trusted state.
+
+ EFI_NOT_FOUND - The file was not found in the untrusted state.
+
+--*/
+;
+
+BOOLEAN
+CoreGrowBuffer (
+ IN OUT EFI_STATUS *Status,
+ IN OUT VOID **Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+
+ Helper function called as part of the code needed
+ to allocate the proper sized buffer for various
+ EFI interfaces.
+
+Arguments:
+
+ Status - Current status
+
+ Buffer - Current allocated buffer, or NULL
+
+ BufferSize - Current buffer size needed
+
+Returns:
+
+ TRUE - if the buffer was reallocated and the caller
+ should try the API again.
+
+ FALSE - buffer could not be allocated and the caller
+ should not try the API again.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FwVolDriverInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This routine is the driver initialization entry point. It initializes the
+ libraries, and registers two notification functions. These notification
+ functions are responsible for building the FV stack dynamically.
+
+Arguments:
+ ImageHandle - The image handle.
+ SystemTable - The system table.
+
+Returns:
+ EFI_SUCCESS - Function successfully returned.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+InitializeSectionExtraction (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ Entry point of the section extraction code. Initializes an instance of the
+ section extraction interface and installs it on a new handle.
+
+Arguments:
+ ImageHandle EFI_HANDLE: A handle for the image that is initializing this driver
+ SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table
+
+Returns:
+ EFI_SUCCESS: Driver initialized successfully
+ EFI_OUT_OF_RESOURCES: Could not allocate needed resources
+
+--*/
+;
+
+EFI_STATUS
+CoreProcessFirmwareVolume (
+ IN VOID *FvHeader,
+ IN UINTN Size,
+ OUT EFI_HANDLE *FVProtocolHandle
+ )
+/*++
+
+Routine Description:
+ This DXE service routine is used to process a firmware volume. In
+ particular, it can be called by BDS to process a single firmware
+ volume found in a capsule.
+
+Arguments:
+ FvHeader - pointer to a firmware volume header
+ Size - the size of the buffer pointed to by FvHeader
+ FVProtocolHandle - the handle on which a firmware volume protocol
+ was produced for the firmware volume passed in.
+
+Returns:
+ EFI_OUT_OF_RESOURCES - if an FVB could not be produced due to lack of
+ system resources
+ EFI_VOLUME_CORRUPTED - if the volume was corrupted
+ EFI_SUCCESS - a firmware volume protocol was produced for the
+ firmware volume
+
+--*/
+;
+
+//
+//Functions used during debug buils
+//
+DEBUG_CODE (
+ VOID
+ CoreDisplayMissingArchProtocols (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+ Displays Architectural protocols that were not loaded and are required for DXE core to function
+ Only used in Debug Builds
+
+ Arguments:
+ NONE
+
+ Returns:
+ NONE
+
+ --*/;
+
+ VOID
+ CoreDisplayDiscoveredNotDispatched (
+ VOID
+ )
+ /*++
+
+ Routine Description:
+
+ Traverse the discovered list for any drivers that were discovered but not loaded
+ because the dependency experessions evaluated to false
+
+ Arguments:
+
+ NONE
+
+ Returns:
+
+ NONE
+
+ --*/;
+)
+#endif
diff --git a/Core/CORE_DXE/DxeMain.c b/Core/CORE_DXE/DxeMain.c
new file mode 100644
index 0000000..8c38168
--- /dev/null
+++ b/Core/CORE_DXE/DxeMain.c
@@ -0,0 +1,1065 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DxeMain.c
+
+Abstract:
+
+ DXE Core Main Entry Point
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "EfiHobLib.h"
+#include "EfiPerf.h"
+#include "FwVolBlock.h"
+
+
+VOID
+EFIAPI
+DxeMain (
+ IN VOID *HobStart
+ );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg0 (
+ VOID
+ );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg1 (
+ UINTN Arg1
+ );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg2 (
+ UINTN Arg1,
+ UINTN Arg2
+ );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg3 (
+ UINTN Arg1,
+ UINTN Arg2,
+ UINTN Arg3
+ );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg4 (
+ UINTN Arg1,
+ UINTN Arg2,
+ UINTN Arg3,
+ UINTN Arg4
+ );
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg5 (
+ UINTN Arg1,
+ UINTN Arg2,
+ UINTN Arg3,
+ UINTN Arg4,
+ UINTN Arg5
+ );
+
+EFI_STATUS
+CoreGetPeiProtocol (
+ IN EFI_GUID *ProtocolGuid,
+ IN VOID **Interface
+ );
+
+PERF_CODE (
+ EFI_STATUS
+ GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+)
+
+//*** AMI PORTING BEGIN ***//
+VOID AmiDxeInit0();
+VOID AmiDxeInit1();
+VOID AmiDxeInit2();
+VOID checkpoint(UINT8);
+EFI_STATUS AmiResetNotAvailableYet(
+ IN EFI_RESET_TYPE ResetType, IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize, IN CHAR16 *ResetData OPTIONAL
+);
+VOID AmiReportArhcProtocolMissingError();
+//*** AMI PORTING END *****//
+
+//
+// DXE Core Global Variables for Protocols from PEI
+//
+EFI_DECOMPRESS_PROTOCOL *gEfiDecompress = NULL;
+EFI_TIANO_DECOMPRESS_PROTOCOL *gEfiTianoDecompress = NULL;
+EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL *gEfiCustomizedDecompress = NULL;
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *gEfiPeiFlushInstructionCache = NULL;
+EFI_PEI_PE_COFF_LOADER_PROTOCOL *gEfiPeiPeCoffLoader = NULL;
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL *gEfiPeiTransferControl = NULL;
+
+//
+// DXE Core globals for Architecture Protocols
+//
+EFI_SECURITY_ARCH_PROTOCOL *gSecurity = NULL;
+//*** AMI PORTING BEGIN ***//
+EFI_SECURITY2_ARCH_PROTOCOL *gSecurity2 = NULL;
+//*** AMI PORTING END ***//
+EFI_CPU_ARCH_PROTOCOL *gCpu = NULL;
+EFI_METRONOME_ARCH_PROTOCOL *gMetronome = NULL;
+EFI_TIMER_ARCH_PROTOCOL *gTimer = NULL;
+EFI_BDS_ARCH_PROTOCOL *gBds = NULL;
+EFI_WATCHDOG_TIMER_ARCH_PROTOCOL *gWatchdogTimer = NULL;
+
+//
+// DXE Core Global used to update core loaded image protocol handle
+//
+EFI_GUID *gDxeCoreFileName;
+EFI_LOADED_IMAGE_PROTOCOL *gDxeCoreLoadedImage;
+
+//
+// BugBug: I'n not runtime, but is the PPI?
+//
+EFI_STATUS_CODE_PROTOCOL gStatusCodeInstance = {
+ NULL
+};
+
+EFI_STATUS_CODE_PROTOCOL *gStatusCode = &gStatusCodeInstance;
+
+//
+// DXE Core Module Variables
+//
+
+EFI_BOOT_SERVICES mBootServices = {
+ {
+ EFI_BOOT_SERVICES_SIGNATURE, // Signature
+ EFI_BOOT_SERVICES_REVISION, // Revision
+ sizeof (EFI_BOOT_SERVICES), // HeaderSize
+ 0, // CRC32
+ 0 // Reserved
+ },
+ (EFI_RAISE_TPL) CoreRaiseTpl, // RaiseTPL
+ (EFI_RESTORE_TPL) CoreRestoreTpl, // RestoreTPL
+ (EFI_ALLOCATE_PAGES) CoreAllocatePages, // AllocatePages
+ (EFI_FREE_PAGES) CoreFreePages, // FreePages
+ (EFI_GET_MEMORY_MAP) CoreGetMemoryMap, // GetMemoryMap
+ (EFI_ALLOCATE_POOL) CoreAllocatePool, // AllocatePool
+ (EFI_FREE_POOL) CoreFreePool, // FreePool
+ (EFI_CREATE_EVENT) CoreCreateEvent, // CreateEvent
+ (EFI_SET_TIMER) CoreSetTimer, // SetTimer
+ (EFI_WAIT_FOR_EVENT) CoreWaitForEvent, // WaitForEvent
+ (EFI_SIGNAL_EVENT) CoreSignalEvent, // SignalEvent
+ (EFI_CLOSE_EVENT) CoreCloseEvent, // CloseEvent
+ (EFI_CHECK_EVENT) CoreCheckEvent, // CheckEvent
+ (EFI_INSTALL_PROTOCOL_INTERFACE) CoreInstallProtocolInterface, // InstallProtocolInterface
+ (EFI_REINSTALL_PROTOCOL_INTERFACE) CoreReinstallProtocolInterface, // ReinstallProtocolInterface
+ (EFI_UNINSTALL_PROTOCOL_INTERFACE) CoreUninstallProtocolInterface, // UninstallProtocolInterface
+ (EFI_HANDLE_PROTOCOL) CoreHandleProtocol, // HandleProtocol
+ (VOID *) NULL, // Reserved
+ (EFI_REGISTER_PROTOCOL_NOTIFY) CoreRegisterProtocolNotify, // RegisterProtocolNotify
+ (EFI_LOCATE_HANDLE) CoreLocateHandle, // LocateHandle
+ (EFI_LOCATE_DEVICE_PATH) CoreLocateDevicePath, // LocateDevicePath
+ (EFI_INSTALL_CONFIGURATION_TABLE) CoreInstallConfigurationTable, // InstallConfigurationTable
+ (EFI_IMAGE_LOAD) CoreLoadImage, // LoadImage
+ (EFI_IMAGE_START) CoreStartImage, // StartImage
+ (EFI_EXIT) CoreExit, // Exit
+ (EFI_IMAGE_UNLOAD) CoreUnloadImage, // UnloadImage
+ (EFI_EXIT_BOOT_SERVICES) CoreExitBootServices, // ExitBootServices
+ (EFI_GET_NEXT_MONOTONIC_COUNT) CoreEfiNotAvailableYetArg1, // GetNextMonotonicCount
+ (EFI_STALL) CoreStall, // Stall
+ (EFI_SET_WATCHDOG_TIMER) CoreSetWatchdogTimer, // SetWatchdogTimer
+ (EFI_CONNECT_CONTROLLER) CoreConnectController, // ConnectController
+ (EFI_DISCONNECT_CONTROLLER) CoreDisconnectController, // DisconnectController
+ (EFI_OPEN_PROTOCOL) CoreOpenProtocol, // OpenProtocol
+ (EFI_CLOSE_PROTOCOL) CoreCloseProtocol, // CloseProtocol
+ (EFI_OPEN_PROTOCOL_INFORMATION) CoreOpenProtocolInformation, // OpenProtocolInformation
+ (EFI_PROTOCOLS_PER_HANDLE) CoreProtocolsPerHandle, // ProtocolsPerHandle
+ (EFI_LOCATE_HANDLE_BUFFER) CoreLocateHandleBuffer, // LocateHandleBuffer
+ (EFI_LOCATE_PROTOCOL) CoreLocateProtocol, // LocateProtocol
+ (EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreInstallMultipleProtocolInterfaces, // InstallMultipleProtocolInterfaces
+ (EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES) CoreUninstallMultipleProtocolInterfaces, // UninstallMultipleProtocolInterfaces
+ (EFI_CALCULATE_CRC32) CoreEfiNotAvailableYetArg3, // CalculateCrc32
+ (EFI_COPY_MEM) EfiCommonLibCopyMem, // CopyMem
+ (EFI_SET_MEM) EfiCommonLibSetMem // SetMem
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ ,
+ //
+ // UEFI 2.0 Extension to the table
+ //
+ (EFI_CREATE_EVENT_EX) CoreCreateEventEx
+#endif
+};
+
+EFI_DXE_SERVICES mDxeServices = {
+ {
+ EFI_DXE_SERVICES_SIGNATURE, // Signature
+ EFI_DXE_SERVICES_REVISION, // Revision
+ sizeof (EFI_DXE_SERVICES), // HeaderSize
+ 0, // CRC32
+ 0 // Reserved
+ },
+ (EFI_ADD_MEMORY_SPACE) CoreAddMemorySpace, // AddMemorySpace
+ (EFI_ALLOCATE_MEMORY_SPACE) CoreAllocateMemorySpace, // AllocateMemorySpace
+ (EFI_FREE_MEMORY_SPACE) CoreFreeMemorySpace, // FreeMemorySpace
+ (EFI_REMOVE_MEMORY_SPACE) CoreRemoveMemorySpace, // RemoveMemorySpace
+ (EFI_GET_MEMORY_SPACE_DESCRIPTOR) CoreGetMemorySpaceDescriptor, // GetMemorySpaceDescriptor
+ (EFI_SET_MEMORY_SPACE_ATTRIBUTES) CoreSetMemorySpaceAttributes, // SetMemorySpaceAttributes
+ (EFI_GET_MEMORY_SPACE_MAP) CoreGetMemorySpaceMap, // GetMemorySpaceMap
+ (EFI_ADD_IO_SPACE) CoreAddIoSpace, // AddIoSpace
+ (EFI_ALLOCATE_IO_SPACE) CoreAllocateIoSpace, // AllocateIoSpace
+ (EFI_FREE_IO_SPACE) CoreFreeIoSpace, // FreeIoSpace
+ (EFI_REMOVE_IO_SPACE) CoreRemoveIoSpace, // RemoveIoSpace
+ (EFI_GET_IO_SPACE_DESCRIPTOR) CoreGetIoSpaceDescriptor, // GetIoSpaceDescriptor
+ (EFI_GET_IO_SPACE_MAP) CoreGetIoSpaceMap, // GetIoSpaceMap
+ (EFI_DISPATCH) CoreDispatcher, // Dispatch
+ (EFI_SCHEDULE) CoreSchedule, // Schedule
+ (EFI_TRUST) CoreTrust, // Trust
+ (EFI_PROCESS_FIRMWARE_VOLUME) CoreProcessFirmwareVolume, // ProcessFirmwareVolume
+};
+
+EFI_SYSTEM_TABLE mEfiSystemTableTemplate = {
+ {
+ EFI_SYSTEM_TABLE_SIGNATURE, // Signature
+ EFI_SYSTEM_TABLE_REVISION, // Revision
+ sizeof (EFI_SYSTEM_TABLE), // HeaderSize
+ 0, // CRC32
+ 0 // Reserved
+ },
+ NULL, // FirmwareVendor
+ 0, // FirmwareRevision
+ NULL, // ConsoleInHandle
+ NULL, // ConIn
+ NULL, // ConsoleOutHandle
+ NULL, // ConOut
+ NULL, // StandardErrorHandle
+ NULL, // StdErr
+ NULL, // RuntimeServices
+ &mBootServices, // BootServices
+ 0, // NumberOfConfigurationTableEntries
+ NULL // ConfigurationTable
+};
+
+EFI_RUNTIME_SERVICES mEfiRuntimeServicesTableTemplate = {
+ {
+ EFI_RUNTIME_SERVICES_SIGNATURE, // Signature
+ EFI_RUNTIME_SERVICES_REVISION, // Revision
+ sizeof (EFI_RUNTIME_SERVICES), // HeaderSize
+ 0, // CRC32
+ 0 // Reserved
+ },
+ (EFI_GET_TIME) CoreEfiNotAvailableYetArg2, // GetTime
+ (EFI_SET_TIME) CoreEfiNotAvailableYetArg1, // SetTime
+ (EFI_GET_WAKEUP_TIME) CoreEfiNotAvailableYetArg3, // GetWakeupTime
+ (EFI_SET_WAKEUP_TIME) CoreEfiNotAvailableYetArg2, // SetWakeupTime
+ (EFI_SET_VIRTUAL_ADDRESS_MAP) CoreEfiNotAvailableYetArg4, // SetVirtualAddressMap
+ (EFI_CONVERT_POINTER) CoreEfiNotAvailableYetArg2, // ConvertPointer
+ (EFI_GET_VARIABLE) CoreEfiNotAvailableYetArg5, // GetVariable
+ (EFI_GET_NEXT_VARIABLE_NAME) CoreEfiNotAvailableYetArg3, // GetNextVariableName
+ (EFI_SET_VARIABLE) CoreEfiNotAvailableYetArg5, // SetVariable
+ (EFI_GET_NEXT_HIGH_MONO_COUNT) CoreEfiNotAvailableYetArg1, // GetNextHighMonotonicCount
+//*** AMI PORTING BEGIN ***//
+// Replace standard dummy routine with a customized one,
+// which reports error code when called
+// (EFI_RESET_SYSTEM) CoreEfiNotAvailableYetArg4, // ResetSystem
+ (EFI_RESET_SYSTEM) AmiResetNotAvailableYet, // ResetSystem
+//*** AMI PORTING END *****//
+#if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ (EFI_UPDATE_CAPSULE) CoreEfiNotAvailableYetArg3, // UpdateCapsule
+ (EFI_QUERY_CAPSULE_CAPABILITIES) CoreEfiNotAvailableYetArg4, // QueryCapsuleCapabilities
+ (EFI_QUERY_VARIABLE_INFO) CoreEfiNotAvailableYetArg4 // QueryVariableInfo
+#elif (TIANO_RELEASE_VERSION != 0)
+ (EFI_REPORT_STATUS_CODE) CoreEfiNotAvailableYetArg5 // ReportStatusCode
+#endif
+};
+
+EFI_RUNTIME_ARCH_PROTOCOL gRuntimeTemplate = {
+ INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.ImageHead),
+ INITIALIZE_LIST_HEAD_VARIABLE (gRuntimeTemplate.EventHead),
+
+ //
+ // Make sure Size != sizeof (EFI_MEMORY_DESCRIPTOR). This will
+ // prevent people from having pointer math bugs in their code.
+ // now you have to use *DescriptorSize to make things work.
+ //
+ sizeof (EFI_MEMORY_DESCRIPTOR) + sizeof (UINT64) - (sizeof (EFI_MEMORY_DESCRIPTOR) % sizeof (UINT64)),
+ EFI_MEMORY_DESCRIPTOR_VERSION,
+ 0,
+ NULL,
+ NULL,
+ FALSE,
+ FALSE
+};
+
+EFI_RUNTIME_ARCH_PROTOCOL *gRuntime = &gRuntimeTemplate;
+
+//
+// DXE Core Global Variables for the EFI System Table, Boot Services Table,
+// DXE Services Table, and Runtime Services Table
+//
+EFI_BOOT_SERVICES *gBS = &mBootServices;
+EFI_DXE_SERVICES *gDS = &mDxeServices;
+EFI_SYSTEM_TABLE *gST = NULL;
+
+//
+// For debug initialize gRT to template. gRT must be allocated from RT memory
+// but gRT is used for ASSERT () and DEBUG () type macros so lets give it
+// a value that will not cause debug infrastructure to crash early on.
+//
+EFI_RUNTIME_SERVICES *gRT = &mEfiRuntimeServicesTableTemplate;
+EFI_HANDLE gDxeCoreImageHandle;
+
+VOID *mHobStart;
+
+//
+// Main entry point to the DXE Core
+//
+EFI_DXE_ENTRY_POINT (DxeMain)
+
+VOID
+EFIAPI
+DxeMain (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to DXE Core.
+
+Arguments:
+
+ HobStart - Pointer to the beginning of the HOB List from PEI
+
+Returns:
+
+ This function should never return
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DecompressHandle;
+ EFI_PHYSICAL_ADDRESS MemoryBaseAddress;
+ UINT64 MemoryLength;
+
+#ifdef EFI_DXE_PERFORMANCE
+ UINT64 Tick;
+
+ GetTimerValue (&Tick);
+#endif
+
+
+ mHobStart = HobStart;
+//*** AMI PORTING BEGIN ***//
+ AmiDxeInit0();
+//*** AMI PORTING END *****//
+ //
+ // Initialize Memory Services
+ //
+ CoreInitializeMemoryServices (&HobStart, &MemoryBaseAddress, &MemoryLength);
+
+ //
+ // Allocate the EFI System Table and EFI Runtime Service Table from EfiRuntimeServicesData
+ // Use the templates to initialize the contents of the EFI System Table and EFI Runtime Services Table
+ //
+ gST = CoreAllocateRuntimeCopyPool (sizeof (EFI_SYSTEM_TABLE), &mEfiSystemTableTemplate);
+ ASSERT (gST != NULL);
+
+ gRT = CoreAllocateRuntimeCopyPool (sizeof (EFI_RUNTIME_SERVICES), &mEfiRuntimeServicesTableTemplate);
+ ASSERT (gRT != NULL);
+
+ gST->RuntimeServices = gRT;
+
+//*** AMI PORTING BEGIN ***//
+ AmiDxeInit1();
+//*** AMI PORTING END *****//
+
+ //
+ // Start the Image Services.
+ //
+ Status = CoreInitializeImageServices (HobStart);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize the Global Coherency Domain Services
+ //
+ Status = CoreInitializeGcdServices (&HobStart, MemoryBaseAddress, MemoryLength);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // The HobStart is relocated in gcd service init. Sync mHobStart variable.
+ //
+ mHobStart = HobStart;
+
+ //
+ // Install the DXE Services Table into the EFI System Tables's Configuration Table
+ //
+ Status = CoreInstallConfigurationTable (&gEfiDxeServicesTableGuid, gDS);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install the HOB List into the EFI System Tables's Configuration Table
+ //
+ Status = CoreInstallConfigurationTable (&gEfiHobListGuid, HobStart);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install Memory Type Information Table into the EFI System Tables's Configuration Table
+ //
+ Status = CoreInstallConfigurationTable (&gEfiMemoryTypeInformationGuid, &gMemoryTypeInformation);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize the ReportStatusCode with PEI version, if availible
+ //
+ CoreGetPeiProtocol (&gEfiStatusCodeRuntimeProtocolGuid, (VOID **)&gStatusCode->ReportStatusCode);
+#if ((TIANO_RELEASE_VERSION != 0) && (EFI_SPECIFICATION_VERSION < 0x00020000))
+ if (gStatusCode->ReportStatusCode != NULL) {
+ gRT->ReportStatusCode = gStatusCode->ReportStatusCode;
+ }
+#endif
+
+ //
+ // Report Status Code here for DXE_ENTRY_POINT once it is available
+ //
+ CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_ENTRY_POINT));
+
+ //
+ // Create the aligned system table pointer structure that is used by external
+ // debuggers to locate the system table... Also, install debug image info
+ // configuration table.
+ //
+ CoreInitializeDebugImageInfoTable ();
+ CoreNewDebugImageInfoEntry (
+ EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL,
+ gDxeCoreLoadedImage,
+ gDxeCoreImageHandle
+ );
+
+ DEBUG_CODE (
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "HOBLIST address in DXE = 0x%x\n", HobStart));
+ )
+ //
+ // Initialize the Event Services
+ //
+ Status = CoreInitializeEventServices ();
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Get the Protocols that were passed in from PEI to DXE through GUIDed HOBs
+ //
+ // These Protocols are not architectural. This implementation is sharing code between
+ // PEI and DXE in order to save FLASH space. These Protocols could also be implemented
+ // as part of the DXE Core. However, that would also require the DXE Core to be ported
+ // each time a different CPU is used, a different Decompression algorithm is used, or a
+ // different Image type is used. By placing these Protocols in PEI, the DXE Core remains
+ // generic, and only PEI and the Arch Protocols need to be ported from Platform to Platform,
+ // and from CPU to CPU.
+ //
+
+ Status = CoreGetPeiProtocol (&gEfiDecompressProtocolGuid, &gEfiDecompress);
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Publish the EFI Decompress protocol for use by other DXE components
+ //
+
+ DecompressHandle = NULL;
+ Status = CoreInstallProtocolInterface (
+ &DecompressHandle,
+ &gEfiDecompressProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gEfiDecompress
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = CoreGetPeiProtocol (&gEfiTianoDecompressProtocolGuid, &gEfiTianoDecompress);
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Publish the Tiano Decompress protocol for use by other DXE components
+ //
+
+ DecompressHandle = NULL;
+ Status = CoreInstallProtocolInterface (
+ &DecompressHandle,
+ &gEfiTianoDecompressProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gEfiTianoDecompress
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ Status = CoreGetPeiProtocol (&gEfiCustomizedDecompressProtocolGuid, &gEfiCustomizedDecompress);
+ if (!EFI_ERROR (Status)) {
+
+ //
+ // Publish the Tiano Decompress protocol for use by other DXE components
+ //
+ DecompressHandle = NULL;
+ Status = CoreInstallProtocolInterface (
+ &DecompressHandle,
+ &gEfiCustomizedDecompressProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gEfiCustomizedDecompress
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ CoreGetPeiProtocol (&gEfiPeiFlushInstructionCacheGuid, &gEfiPeiFlushInstructionCache);
+
+ CoreGetPeiProtocol (&gEfiPeiPeCoffLoaderGuid, &gEfiPeiPeCoffLoader);
+
+ CoreGetPeiProtocol (&gEfiPeiTransferControlGuid, &gEfiPeiTransferControl);
+
+
+ //
+ // Register for the GUIDs of the Architectural Protocols, so the rest of the
+ // EFI Boot Services and EFI Runtime Services tables can be filled in.
+ //
+ CoreNotifyOnArchProtocolInstallation ();
+
+ //
+ // Produce Firmware Volume Protocols, one for each FV in the HOB list.
+ //
+ Status = FwVolBlockDriverInit (gDxeCoreImageHandle, gST);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = FwVolDriverInit (gDxeCoreImageHandle, gST);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Produce the Section Extraction Protocol
+ //
+ Status = InitializeSectionExtraction (gDxeCoreImageHandle, gST);
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Initialize Performance monitoring if enabled in build
+ //
+ PERF_ENABLE (0, gST, Tick);
+
+ PERF_START (0,DXE_TOK, NULL, Tick) ;
+
+//*** AMI PORTING BEGIN ***//
+ AmiDxeInit2();
+//*** AMI PORTING END *****//
+
+ //
+ // Initialize the DXE Dispatcher
+ //
+ PERF_START (0,L"CoreInitializeDispatcher", L"DxeMain", 0) ;
+ CoreInitializeDispatcher ();
+ PERF_END (0,L"CoreInitializeDispatcher", L"DxeMain", 0) ;
+
+ //
+ // Invoke the DXE Dispatcher
+ //
+ PERF_START (0, L"CoreDispatcher", L"DxeMain", 0);
+ CoreDispatcher ();
+ PERF_END (0, L"CoreDispatcher", L"DxeMain", 0);
+
+ //
+ // Display Architectural protocols that were not loaded if this is DEBUG build
+ //
+ DEBUG_CODE (
+ CoreDisplayMissingArchProtocols ();
+ )
+
+ //
+ // Assert if the Architectural Protocols are not present.
+ //
+//*** AMI PORTING BEGIN ***//
+//Report "Architectural Protocol Missing" error
+ //ASSERT_EFI_ERROR (CoreAllEfiServicesAvailable ());
+ Status = CoreAllEfiServicesAvailable ();
+ if (EFI_ERROR (Status)) AmiReportArhcProtocolMissingError();
+ ASSERT_EFI_ERROR (Status);
+//*** AMI PORTING END *****//
+
+
+ //
+ // Report Status code before transfer control to BDS
+ //
+ CoreReportProgressCode ((EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT));
+
+ //
+ // Display any drivers that were not dispatched because dependency expression
+ // evaluated to false if this is a debug build
+ //
+ DEBUG_CODE (
+ CoreDisplayDiscoveredNotDispatched ();
+ )
+
+ //
+ // Transfer control to the BDS Architectural Protocol
+ //
+ gBds->Entry (gBds);
+
+ //
+ // BDS should never return
+ //
+ ASSERT (FALSE);
+ EFI_DEADLOOP ();
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg0 (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+ //
+ // This function should never be executed. If it does, then the architectural protocols
+ // have not been designed correctly. The EFI_BREAKPOINT() is commented out for now until the
+ // DXE Core and all the Architectural Protocols are complete.
+ //
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg1 (
+ UINTN Arg1
+ )
+/*++
+
+Routine Description:
+
+ Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+ Arg1 - Undefined
+
+Returns:
+
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+ //
+ // This function should never be executed. If it does, then the architectural protocols
+ // have not been designed correctly. The EFI_BREAKPOINT() is commented out for now until the
+ // DXE Core and all the Architectural Protocols are complete.
+ //
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg2 (
+ UINTN Arg1,
+ UINTN Arg2
+ )
+/*++
+
+Routine Description:
+
+ Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+ Arg1 - Undefined
+
+ Arg2 - Undefined
+
+Returns:
+
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+ //
+ // This function should never be executed. If it does, then the architectural protocols
+ // have not been designed correctly. The EFI_BREAKPOINT() is commented out for now until the
+ // DXE Core and all the Architectural Protocols are complete.
+ //
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg3 (
+ UINTN Arg1,
+ UINTN Arg2,
+ UINTN Arg3
+ )
+/*++
+
+Routine Description:
+
+ Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+ Arg1 - Undefined
+
+ Arg2 - Undefined
+
+ Arg3 - Undefined
+
+Returns:
+
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+ //
+ // This function should never be executed. If it does, then the architectural protocols
+ // have not been designed correctly. The EFI_BREAKPOINT() is commented out for now until the
+ // DXE Core and all the Architectural Protocols are complete.
+ //
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg4 (
+ UINTN Arg1,
+ UINTN Arg2,
+ UINTN Arg3,
+ UINTN Arg4
+ )
+/*++
+
+Routine Description:
+
+ Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+ Arg1 - Undefined
+
+ Arg2 - Undefined
+
+ Arg3 - Undefined
+
+ Arg4 - Undefined
+
+Returns:
+
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+ //
+ // This function should never be executed. If it does, then the architectural protocols
+ // have not been designed correctly. The EFI_BREAKPOINT() is commented out for now until the
+ // DXE Core and all the Architectural Protocols are complete.
+ //
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+EFI_STATUS
+EFIAPI
+CoreEfiNotAvailableYetArg5 (
+ UINTN Arg1,
+ UINTN Arg2,
+ UINTN Arg3,
+ UINTN Arg4,
+ UINTN Arg5
+ )
+/*++
+
+Routine Description:
+
+ Place holder function until all the Boot Services and Runtime Services are available
+
+Arguments:
+
+ Arg1 - Undefined
+
+ Arg2 - Undefined
+
+ Arg3 - Undefined
+
+ Arg4 - Undefined
+
+ Arg5 - Undefined
+
+Returns:
+
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+{
+ //
+ // This function should never be executed. If it does, then the architectural protocols
+ // have not been designed correctly. The EFI_BREAKPOINT() is commented out for now until the
+ // DXE Core and all the Architectural Protocols are complete.
+ //
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+EFI_STATUS
+CoreGetPeiProtocol (
+ IN EFI_GUID *ProtocolGuid,
+ IN VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Searches for a Protocol Interface passed from PEI through a HOB
+
+Arguments:
+
+ ProtocolGuid - The Protocol GUID to search for in the HOB List
+
+ Interface - A pointer to the interface for the Protocol GUID
+
+Returns:
+
+ EFI_SUCCESS - The Protocol GUID was found and its interface is returned in Interface
+
+ EFI_NOT_FOUND - The Protocol GUID was not found in the HOB List
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ VOID *Buffer;
+
+ HobList = mHobStart;
+ Status = GetNextGuidHob (&HobList, ProtocolGuid, &Buffer, NULL);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ASSERT (Buffer != NULL);
+
+ *Interface = (VOID *)(*(UINTN *)(Buffer));
+
+ return Status;
+}
+
+
+VOID
+CalculateEfiHdrCrc (
+ IN OUT EFI_TABLE_HEADER *Hdr
+ )
+/*++
+
+Routine Description:
+
+ Calcualte the 32-bit CRC in a EFI table using the service provided by the
+ gRuntime service.
+
+Arguments:
+
+ Hdr - Pointer to an EFI standard header
+
+Returns:
+
+ None
+
+--*/
+{
+ UINT32 Crc;
+
+ Hdr->CRC32 = 0;
+
+ //
+ // If gBS->CalculateCrce32 () == CoreEfiNotAvailableYet () then
+ // Crc will come back as zero if we set it to zero here
+ //
+ Crc = 0;
+ gBS->CalculateCrc32 ((UINT8 *)Hdr, Hdr->HeaderSize, &Crc);
+ Hdr->CRC32 = Crc;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreExitBootServices (
+ IN EFI_HANDLE ImageHandle,
+ IN UINTN MapKey
+ )
+/*++
+
+Routine Description:
+
+ Terminates all boot services.
+
+Arguments:
+
+ ImageHandle - Handle that identifies the exiting image.
+ MapKey - Key to the latest memory map.
+
+Returns:
+
+ EFI_SUCCESS - Boot services have been terminated.
+ EFI_INVALID_PARAMETER - MapKey is incorrect.
+
+--*/
+{
+ EFI_STATUS Status, Status2;
+ EFI_TCG_PLATFORM_PROTOCOL *TcgPlatformProtocol;
+//*** AMI PORTING BEGIN ***//
+// EIP 58707: Updated to reflect changes introduced in UEFI spec v2.3.1 section 6.4.
+// 1. The callback functions are to be called once
+// (even if ExitBootServices is called more than once).
+// 2. The memory map must be validated after the execution of the callback functions
+// (CoreTerminateMemoryMap call).
+ static BOOLEAN FirstCall = TRUE;
+//*** AMI PORTING END ***//
+
+ //
+ // Measure invocation of ExitBootServices,
+ // which is defined by TCG_EFI_Platform_1_20_Final Specification
+ //
+ TcgPlatformProtocol = NULL;
+ Status = CoreLocateProtocol (
+ &gEfiTcgPlatformProtocolGuid,
+ NULL,
+ &TcgPlatformProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = TcgPlatformProtocol->MeasureAction (EFI_EXIT_BOOT_SERVICES_INVOCATION);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+//*** AMI PORTING BEGIN ***//
+// See comments at the beginning of the function.
+ if (FirstCall) {
+
+ AmiFillFpdt (FillExitBootServicesEntry); // Fill ExitBootServicesEntry field in FPDT
+ //
+ // Disable Timer
+ //
+ gTimer->SetTimerPeriod (gTimer, 0);
+
+ //
+ // Notify other drivers that we are exiting boot services.
+ //
+ CoreNotifySignalList (&gEfiEventExitBootServicesGuid);
+
+ FirstCall = FALSE;
+ }
+//*** AMI PORTING END ***//
+
+ //
+ // Terminate memory services if the MapKey matches
+ //
+ Status = CoreTerminateMemoryMap (MapKey);
+ if (EFI_ERROR (Status)) {
+ //
+ // Measure failure of ExitBootServices
+ //
+ if (TcgPlatformProtocol != NULL) {
+ Status2 = TcgPlatformProtocol->MeasureAction (EFI_EXIT_BOOT_SERVICES_FAILED);
+ ASSERT_EFI_ERROR (Status2);
+ }
+
+ return Status;
+ }
+//*** AMI PORTING BEGIN ***//
+// These two calls have been moved above.
+// See comments at the beginning of the function.
+ //
+ // Disable Timer
+ //
+// gTimer->SetTimerPeriod (gTimer, 0);
+
+
+ //
+ // Notify other drivers that we are exiting boot services.
+ //
+// CoreNotifySignalList (&gEfiEventExitBootServicesGuid);
+//*** AMI PORTING END ***//
+
+
+ //
+ // Disable CPU Interrupts
+ //
+ gCpu->DisableInterrupt (gCpu);
+
+ //
+ // Report that ExitBootServices() has been called
+ //
+ // We are using gEfiDxeServicesTableGuid as the caller ID for Dxe Core
+ //
+ CoreReportProgressCode ((EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES));
+
+ //
+ // Clear the non-runtime values of the EFI System Table
+ //
+ gST->BootServices = NULL;
+ gST->ConIn = NULL;
+ gST->ConsoleInHandle = NULL;
+ gST->ConOut = NULL;
+ gST->ConsoleOutHandle = NULL;
+ gST->StdErr = NULL;
+ gST->StandardErrorHandle = NULL;
+
+ //
+ // Recompute the 32-bit CRC of the EFI System Table
+ //
+ CalculateEfiHdrCrc (&gST->Hdr);
+
+ //
+ // Update the AtRuntime field in Runtiem AP.
+ //
+ gRuntime->AtRuntime = TRUE;
+
+ //
+ // Measure success of ExitBootServices
+ //
+ if (TcgPlatformProtocol != NULL) {
+ Status2 = TcgPlatformProtocol->MeasureAction (EFI_EXIT_BOOT_SERVICES_SUCCEEDED);
+ ASSERT_EFI_ERROR (Status2);
+ }
+
+ //
+ // Zero out the Boot Service Table
+ //
+ EfiCommonLibSetMem (gBS, sizeof (EFI_BOOT_SERVICES), 0);
+ gBS = NULL;
+//*** AMI PORTING BEGIN ***//
+ AmiFillFpdt (FillExitBootServicesExit); // Fill ExitBootServicesExit field in FPDT
+//*** AMI PORTING END ***//
+
+ return Status;
+}
diff --git a/Core/CORE_DXE/DxePerf.c b/Core/CORE_DXE/DxePerf.c
new file mode 100644
index 0000000..6e744f4
--- /dev/null
+++ b/Core/CORE_DXE/DxePerf.c
@@ -0,0 +1,813 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Perf.c
+
+Abstract:
+
+ Support for Performance primatives.
+
+--*/
+
+
+#include <Efi.h>
+#include <Tiano.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Dxe.h>
+#include <Hob.h>
+#include <EfiHobLib.h>
+#include <EfiCommonLib.h>
+#include <EfiImage.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\Cpu.h>
+#include <AmiHobs.h>
+#include "EfiPerf.h"
+#include "linkedlist.h"
+
+#define EFI_NULL_GUID \
+ { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
+
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ )
+{
+ *TimerValue = GetCpuTimer();
+ return EFI_SUCCESS;
+}
+
+
+#define EFI_PERF_PEI_ENTRY_MAX_NUM 50
+
+typedef struct {
+ CHAR8 Token[EFI_PERF_PDBFILENAME_LENGTH];
+ UINT32 Duration;
+} EFI_PERF_DATA;
+
+typedef struct {
+ UINT64 BootToOs;
+ UINT64 S3Resume;
+ UINT32 S3EntryNum;
+ EFI_PERF_DATA S3Entry[EFI_PERF_PEI_ENTRY_MAX_NUM];
+ UINT64 CpuFreq;
+ UINT64 BDSRaw;
+ UINT32 Count;
+ UINT32 Signiture;
+} EFI_PERF_HEADER;
+
+EFI_STATUS
+GetPeiPerformance (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ );
+
+#define EFI_PERFORMANCE_DATA_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'D', 'A')
+
+typedef struct {
+ UINT32 Signature;
+ EFI_LIST_ENTRY Link;
+ EFI_GAUGE_DATA GaugeData;
+} EFI_PERF_DATA_LIST;
+
+#define GAUGE_DATA_FROM_LINK(_link) \
+ CR(_link, EFI_PERF_DATA_LIST, Link, EFI_PERFORMANCE_DATA_SIGNATURE)
+
+#define GAUGE_DATA_FROM_GAUGE(_GaugeData) \
+ CR(_GaugeData, EFI_PERF_DATA_LIST, GaugeData, EFI_PERFORMANCE_DATA_SIGNATURE)
+
+#define EFI_PERFORMANCE_SIGNATURE EFI_SIGNATURE_32 ('P', 'E', 'R', 'F')
+
+//
+// Performance protocol instance data structure
+//
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_PERFORMANCE_PROTOCOL Perf;
+ UINT8 Phase;
+} EFI_PERFORMANCE_INSTANCE;
+
+//
+// Performace protocol instance containing record macro
+//
+
+#define EFI_PERFORMANCE_FROM_THIS(a) \
+ CR(a, EFI_PERFORMANCE_INSTANCE, Perf, EFI_PERFORMANCE_SIGNATURE)
+
+EFI_LIST_ENTRY mPerfDataHead = INITIALIZE_LIST_HEAD_VARIABLE(mPerfDataHead);
+
+BOOLEAN GetImageName(EFI_HANDLE ImageHandle, CHAR8 *sName);
+
+STATIC
+VOID
+GetShortPdbFileName (
+ CHAR8 *PdbFileName,
+ CHAR8 *GaugeString
+ )
+/*++
+
+Routine Description:
+
+Arguments:
+
+Returns:
+
+--*/
+{
+ UINTN Index;
+ UINTN Index1;
+ UINTN StartIndex;
+ UINTN EndIndex;
+
+ if (PdbFileName == NULL) {
+ EfiAsciiStrCpy (GaugeString, " ");
+ } else {
+ StartIndex = 0;
+ for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)
+ ;
+
+ for (Index = 0; PdbFileName[Index] != 0; Index++) {
+ if (PdbFileName[Index] == '\\') {
+ StartIndex = Index + 1;
+ }
+
+ if (PdbFileName[Index] == '.') {
+ EndIndex = Index;
+ }
+ }
+
+ Index1 = 0;
+ for (Index = StartIndex; Index < EndIndex; Index++) {
+ GaugeString[Index1] = PdbFileName[Index];
+ Index1++;
+ if (Index1 == EFI_PERF_PDBFILENAME_LENGTH - 1) {
+ break;
+ }
+ }
+
+ GaugeString[Index1] = 0;
+ }
+
+ return ;
+}
+
+STATIC
+CHAR8 *
+GetPdbPath (
+ VOID *ImageBase
+ )
+/*++
+
+Routine Description:
+
+ Located PDB path name in PE image
+
+Arguments:
+
+ ImageBase - base of PE to search
+
+Returns:
+
+ Pointer into image at offset of PDB file name if PDB file name is found,
+ Otherwise a pointer to an empty string.
+
+--*/
+{
+ CHAR8 *PdbPath;
+ UINT32 DirCount;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_IMAGE_NT_HEADERS *NtHdr;
+ EFI_IMAGE_OPTIONAL_HEADER *OptionalHdr;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ VOID *CodeViewEntryPointer;
+
+ CodeViewEntryPointer = NULL;
+ PdbPath = NULL;
+ DosHdr = ImageBase;
+
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ NtHdr = (EFI_IMAGE_NT_HEADERS *) ((UINT8 *) DosHdr + DosHdr->e_lfanew);
+ OptionalHdr = (VOID *) &NtHdr->OptionalHeader;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(OptionalHdr->DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ if (DirectoryEntry->VirtualAddress != 0) {
+ for (DirCount = 0;
+ (DirCount < DirectoryEntry->Size / sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY)) && CodeViewEntryPointer == NULL;
+ DirCount++
+ ) {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) (DirectoryEntry->VirtualAddress + (UINTN) ImageBase + DirCount * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageBase);
+ switch (*(UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ PdbPath = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ return PdbPath;
+}
+
+STATIC
+VOID
+GetNameFromHandle (
+ IN EFI_HANDLE Handle,
+ OUT CHAR8 *GaugeString
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ CHAR8 *PdbFileName;
+ EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
+
+ EfiAsciiStrCpy (GaugeString, " ");
+
+ //
+ // Get handle name from image protocol
+ //
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID**)&Image
+ );
+
+ if (EFI_ERROR (Status)) {
+ Status = pBS->OpenProtocol (
+ Handle,
+ &gEfiDriverBindingProtocolGuid,
+ (VOID **) &DriverBinding,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+ //
+ // Get handle name from image protocol
+ //
+ Status = pBS->HandleProtocol (
+ DriverBinding->ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ (VOID**)&Image
+ );
+ }
+
+ PdbFileName = GetPdbPath (Image->ImageBase);
+
+ if (PdbFileName != NULL) {
+ GetShortPdbFileName (PdbFileName, GaugeString);
+ }
+
+ return ;
+}
+
+EFI_PERF_DATA_LIST *
+CreateDataNode (
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host
+ )
+/*++
+
+Routine Description:
+
+ Create a EFI_PERF_DATA_LIST data node.
+
+Arguments:
+
+ Handle - Handle of gauge data
+ Token - Token of gauge data
+ Host - Host of gauge data
+
+Returns:
+
+ Pointer to a data node created.
+
+--*/
+{
+ EFI_PERF_DATA_LIST *Node;
+
+ //
+ // Al\ a new image structure
+ //
+
+ Node = MallocZ (sizeof (EFI_PERF_DATA_LIST));
+
+ if (Node != NULL) {
+
+ Node->Signature = EFI_PERFORMANCE_DATA_SIGNATURE;
+
+ Node->GaugeData.Handle = Handle;
+
+ if (Token != NULL) {
+ EfiStrCpy ((Node->GaugeData).Token, Token);
+ }
+
+ if (Host != NULL) {
+ EfiStrCpy ((Node->GaugeData).Host, Host);
+ }
+
+ if (Handle != NULL) {
+ GetImageName (Handle, Node->GaugeData.PdbFileName);
+ }
+ }
+
+ return Node;
+}
+
+
+EFI_PERF_DATA_LIST *
+GetDataNode (
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN EFI_GUID *GuidName,
+ IN EFI_GAUGE_DATA *PrevGauge
+ )
+/*++
+
+Routine Description:
+
+ Search gauge node list to find one node with matched handle, token, host and Guid name.
+
+Arguments:
+
+ Handle - Handle to match
+ Token - Token to match
+ Host - Host to match
+ GuidName - Guid name to match
+ PrevGauge - Start node, start from list head if NULL
+
+Returns:
+
+ Return pointer to the node found, NULL if not found.
+
+--*/
+{
+ EFI_PERF_DATA_LIST *Node;
+ EFI_PERF_DATA_LIST *Temp;
+ EFI_PERF_DATA_LIST *Temp2;
+ EFI_LIST_ENTRY *CurrentLink;
+ EFI_GUID NullGuid = EFI_NULL_GUID;
+
+ Node = NULL;
+ Temp = NULL;
+ Temp2 = NULL;
+
+ if (PrevGauge == NULL) {
+ CurrentLink = mPerfDataHead.ForwardLink;
+ } else {
+ Temp2 = GAUGE_DATA_FROM_GAUGE (PrevGauge);
+ CurrentLink = (Temp2->Link).ForwardLink;
+ }
+
+ while (CurrentLink && CurrentLink != &mPerfDataHead) {
+ Node = GAUGE_DATA_FROM_LINK (CurrentLink);
+
+ if (Handle == 0 && Token == NULL && Host == NULL && GuidName == NULL) {
+ return Node;
+ }
+
+ if (Handle != (Node->GaugeData).Handle) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (GuidName == NULL && !EfiCompareGuid (&((Node->GaugeData).GuidName), &NullGuid)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (GuidName && !EfiCompareGuid (&((Node->GaugeData).GuidName), GuidName)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Token == NULL && EfiStrCmp (Node->GaugeData.Token, L"")) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Token && EfiStrCmp (Node->GaugeData.Token, Token)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Host == NULL && EfiStrCmp (Node->GaugeData.Host, L"")) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ if (Host && EfiStrCmp (Node->GaugeData.Host, Host)) {
+ CurrentLink = CurrentLink->ForwardLink;
+ continue;
+ }
+
+ Temp = Node;
+ break;
+ }
+
+ return Temp;
+}
+
+
+EFI_STATUS
+EFIAPI
+StartGauge (
+ IN EFI_PERFORMANCE_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Create a guage data node and initialized it.
+
+Arguments:
+
+ This - Calling context
+ Handle - Handle of gauge data
+ Token - Token of gauge data
+ Host - Host of gauge data
+ Ticker - Set gauge data's StartTick. If 0, StartTick is current timer.
+
+Returns:
+
+ EFI_SUCCESS - Successfully create and initialized a guage data node.
+ EFI_OUT_OF_RESOURCES - No enough resource to create a guage data node.
+
+--*/
+{
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+ EFI_PERF_DATA_LIST *Node;
+ UINT64 TimerValue;
+
+ TimerValue = 0;
+ PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
+
+ Node = CreateDataNode (Handle, Token, Host);
+ if (!Node) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (Ticker != 0) {
+ TimerValue = Ticker;
+ } else {
+// GetTimerValue (&TimerValue);
+ TimerValue = GetCpuTimer();
+ }
+
+ Node->GaugeData.StartTick = TimerValue;
+
+ if (!EfiStrCmp (Token, DXE_TOK)) {
+ PerfInstance->Phase = DXE_PHASE;
+ }
+
+ if (!EfiStrCmp (Token, SHELL_TOK)) {
+ PerfInstance->Phase = SHELL_PHASE;
+ }
+
+ Node->GaugeData.Phase = PerfInstance->Phase;
+
+ InsertTailList (&mPerfDataHead, &(Node->Link));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+EndGauge (
+ IN EFI_PERFORMANCE_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ End all unfinished gauge data node that match specified handle, token and host.
+
+Arguments:
+
+ This - Calling context
+ Handle - Handle to stop
+ Token - Token to stop
+ Host - Host to stop
+ Ticker - End tick, if 0 then get current timer
+
+Returns:
+
+ EFI_NOT_FOUND - Node not found
+ EFI_SUCCESS - Gauge data node successfully ended.
+
+--*/
+{
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+ EFI_PERF_DATA_LIST *Node;
+ UINT64 TimerValue;
+
+ TimerValue = 0;
+ PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
+
+ Node = GetDataNode (Handle, Token, Host, NULL, NULL);
+ if (!Node) {
+ return EFI_NOT_FOUND;
+ }
+
+ while (Node->GaugeData.EndTick != 0) {
+ Node = GetDataNode (Handle, Token, Host, NULL, &(Node->GaugeData));
+ if (!Node) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ if (Ticker != 0) {
+ TimerValue = Ticker;
+ } else {
+// GetTimerValue (&TimerValue);
+ TimerValue = GetCpuTimer();
+ }
+
+ Node->GaugeData.EndTick = TimerValue;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_GAUGE_DATA *
+EFIAPI
+GetGauge (
+ IN EFI_PERFORMANCE_PROTOCOL *This,
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN EFI_GAUGE_DATA *PrevGauge
+ )
+/*++
+
+Routine Description:
+ Get gauge.
+
+Arguments:
+ This - A pointer to the EFI_PERFORMANCE_PROTOCOL.
+ Handle - A pointer of a efi handle.
+ Token - A pointer to the token.
+ Host - A pointer to the host.
+ PrevGauge - A pointer to the EFI_GAUGE_DATA structure.
+
+
+Returns:
+ Status code.
+
+--*/
+{
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+ EFI_PERF_DATA_LIST *Node;
+
+ PerfInstance = EFI_PERFORMANCE_FROM_THIS (This);
+
+ Node = GetDataNode (Handle, Token, Host, NULL, PrevGauge);
+ if (Node != NULL) {
+ return &(Node->GaugeData);
+ } else {
+ return NULL;
+ }
+}
+
+//
+// Driver entry point
+//
+EFI_STATUS
+InitializePerformanceInfrastructure (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Install gEfiPerformanceProtocolGuid protocol and transfer PEI performance to gauge data nodes.
+
+Arguments:
+
+ ImageHandle - Standard driver entry point parameter
+ SystemTable - Standard driver entry point parameter
+ Ticker - End tick for PEI performance
+
+Returns:
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+ EFI_SUCCESS - Protocol installed.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PERFORMANCE_INSTANCE *PerfInstance;
+
+ //
+ // Allocate a new image structure
+ //
+ PerfInstance = MallocZ (sizeof (EFI_PERFORMANCE_INSTANCE));
+ if (PerfInstance == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PerfInstance->Signature = EFI_PERFORMANCE_SIGNATURE;
+ PerfInstance->Perf.StartGauge = StartGauge;
+ PerfInstance->Perf.EndGauge = EndGauge;
+ PerfInstance->Perf.GetGauge = GetGauge;
+
+ //
+ // Install the protocol interfaces
+ //
+ Status = pBS->InstallProtocolInterface (
+ &PerfInstance->Handle,
+ &gEfiPerformanceProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &PerfInstance->Perf
+ );
+
+ if (!EFI_ERROR (Status)) {
+ GetPeiPerformance (ImageHandle, SystemTable, Ticker);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_STATUS
+GetPeiPerformance (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ )
+/*++
+
+Routine Description:
+
+ Transfer PEI performance data to gauge data node.
+
+Arguments:
+
+ ImageHandle - Standard entry point parameter
+ SystemTable - Standard entry point parameter
+ Ticker - Start tick
+
+Returns:
+
+ EFI_OUT_OF_RESOURCES - No enough resource to create data node.
+ EFI_SUCCESS - Transfer done successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ EFI_HOB_GUID_DATA_PERFORMANCE_LOG *LogHob;
+ PEI_PERFORMANCE_MEASURE_LOG_ENTRY *LogEntry;
+ UINT32 Index;
+ EFI_PERF_DATA_LIST *Node;
+ UINT64 TimerValue;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID PerformanceHobGuid = EFI_PEI_PERFORMANCE_HOB_GUID;
+
+ Node = CreateDataNode (0, PEI_TOK, NULL);
+ if (!Node) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (Ticker != 0) {
+ TimerValue = Ticker;
+ } else {
+// GetTimerValue (&TimerValue);
+ TimerValue = GetCpuTimer();
+ }
+ (Node->GaugeData).EndTick = TimerValue;
+
+ InsertTailList (&mPerfDataHead, &(Node->Link));
+
+// EfiLibGetSystemConfigurationTable (&gEfiHobListGuid, &HobList);
+ HobList = GetEfiConfigurationTable(pST, &HobListGuid);
+ if(HobList == NULL)
+ return EFI_NOT_FOUND;
+
+ do {
+ Status = GetNextGuidHob (&HobList, &PerformanceHobGuid, (VOID **) &LogHob, NULL);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ for (Index = 0; Index < LogHob->NumberOfEntries; Index++) {
+ LogEntry = &(LogHob->Log[Index]);
+ Node = CreateDataNode (0, LogEntry->DescriptionString, NULL);
+ if (!Node) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ (Node->GaugeData).StartTick = LogEntry->StartTimeCount;
+
+ MemCpy (&(Node->GaugeData.GuidName), &LogEntry->Name, sizeof (EFI_GUID));
+
+ InsertTailList (&mPerfDataHead, &(Node->Link));
+
+ (Node->GaugeData).EndTick = LogEntry->StopTimeCount;
+ }
+ } while (!EFI_ERROR (Status));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+UpdateMeasure (
+ EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ EFI_HANDLE HandleNew,
+ IN UINT16 *TokenNew,
+ IN UINT16 *HostNew
+ )
+/*++
+
+Routine Description:
+ Update measure.
+
+Arguments:
+ Handle - A pointer of an efi handle.
+ Token - A pointer to the token.
+ Host - A pointer to the host.
+ HandleNew - A pointer of an new efi handle.
+ TokenNew - A pointer to the new token.
+ HostNew - A pointer to the new host.
+
+Returns:
+ Status code.
+
+ EFI_NOT_FOUND - The speicified gauge data node not found.
+
+ EFI_SUCCESS - Update successfully.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_GAUGE_DATA *GaugeData;
+ EFI_PERFORMANCE_PROTOCOL *Perf;
+
+ Status = pBS->LocateProtocol (&gEfiPerformanceProtocolGuid, NULL, (VOID **) &Perf);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ GaugeData = Perf->GetGauge (Perf, Handle, Token, Host, NULL);
+ if (!GaugeData) {
+ return EFI_NOT_FOUND;
+ }
+
+ GaugeData->Handle = HandleNew;
+ if (HostNew != NULL) {
+ Wcscpy (GaugeData->Host, HostNew);
+ } else {
+ Wcscpy (GaugeData->Host, L"");
+ }
+
+ if (TokenNew != NULL) {
+ Wcscpy (GaugeData->Token, TokenNew);
+ } else {
+ Wcscpy (GaugeData->Token, L"");
+ }
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CORE_DXE/DxeProtocolNotify.c b/Core/CORE_DXE/DxeProtocolNotify.c
new file mode 100644
index 0000000..5d9288d
--- /dev/null
+++ b/Core/CORE_DXE/DxeProtocolNotify.c
@@ -0,0 +1,334 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DxeProtocolNotify.c
+
+Abstract:
+
+ This file deals with Architecture Protocol (AP) registration in
+ the Dxe Core. The mArchProtocols[] array represents a list of
+ events that represent the Architectural Protocols.
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+
+//
+// DXE Core Global Variables for all of the Architectural Protocols.
+// If a protocol is installed mArchProtocols[].Present will be TRUE.
+//
+// CoreNotifyOnArchProtocolInstallation () fills in mArchProtocols[].Event
+// and mArchProtocols[].Registration as it creates events for every array
+// entry.
+//
+
+ARCHITECTURAL_PROTOCOL_ENTRY mArchProtocols[] = {
+ { &gEfiSecurityArchProtocolGuid, &gSecurity, NULL, NULL, FALSE},
+ { &gEfiCpuArchProtocolGuid, &gCpu, NULL, NULL, FALSE},
+ { &gEfiMetronomeArchProtocolGuid, &gMetronome, NULL, NULL, FALSE},
+ { &gEfiTimerArchProtocolGuid, &gTimer, NULL, NULL, FALSE},
+ { &gEfiBdsArchProtocolGuid, &gBds, NULL, NULL, FALSE},
+ { &gEfiWatchdogTimerArchProtocolGuid, &gWatchdogTimer, NULL, NULL, FALSE},
+ { &gEfiRuntimeArchProtocolGuid, &gRuntime, NULL, NULL, FALSE},
+ { &gEfiVariableArchProtocolGuid, NULL, NULL, NULL, FALSE},
+ { &gEfiVariableWriteArchProtocolGuid, NULL, NULL, NULL, FALSE},
+ #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+//*** AMI PORTING BEGIN ***//
+// Make Security support optional.
+// { &gEfiCapsuleArchProtocolGuid, NULL, NULL, NULL, FALSE},
+//*** AMI PORTING END *****//
+ #endif
+ { &gEfiMonotonicCounterArchProtocolGuid, NULL, NULL, NULL, FALSE},
+ { &gEfiResetArchProtocolGuid, NULL, NULL, NULL, FALSE},
+ { &gEfiStatusCodeRuntimeProtocolGuid, NULL, NULL, NULL, FALSE},
+ { &gEfiRealTimeClockArchProtocolGuid, NULL, NULL, NULL, FALSE},
+ NULL
+};
+
+
+EFI_STATUS
+CoreAllEfiServicesAvailable (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Return TRUE if all AP services are availible.
+
+Arguments:
+ NONE
+
+Returns:
+ EFI_SUCCESS - All AP services are available
+ EFI_NOT_FOUND - At least one AP service is not available
+
+--*/
+{
+ ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
+
+ for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
+ if (!Entry->Present) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+EFIAPI
+GenericArchProtocolNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+ Notification event handler registered by CoreNotifyOnArchProtocolInstallation ().
+ This notify function is registered for every architectural protocol. This handler
+ updates mArchProtocol[] array entry with protocol instance data and sets it's
+ present flag to TRUE. If any constructor is required it is executed. The EFI
+ System Table headers are updated.
+
+Arguments:
+
+ Event - The Event that is being processed, not used.
+
+ Context - Event Context, not used.
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
+ VOID *Protocol;
+ BOOLEAN Found;
+ EFI_LIST_ENTRY *Link;
+ EFI_LIST_ENTRY TempLinkNode;
+
+ Found = FALSE;
+ for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
+
+ Status = CoreLocateProtocol (Entry->ProtocolGuid, Entry->Registration, &Protocol);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ Found = TRUE;
+ Entry->Present = TRUE;
+
+ //
+ // Update protocol global variable if one exists. Entry->Protocol points to a global variable
+ // if one exists in the DXE core for this Architectural Protocol
+ //
+ if (Entry->Protocol != NULL) {
+ *(Entry->Protocol) = Protocol;
+ }
+
+ if (EfiCompareGuid (Entry->ProtocolGuid, &gEfiTimerArchProtocolGuid)) {
+ //
+ // Register the Core timer tick handler with the Timer AP
+ //
+ gTimer->RegisterHandler (gTimer, CoreTimerTick);
+ }
+
+ if (EfiCompareGuid (Entry->ProtocolGuid, &gEfiRuntimeArchProtocolGuid)) {
+ //
+ // When runtime architectural protocol is available, updates CRC32 in the Debug Table
+ //
+ CoreUpdateDebugTableCrc32 ();
+
+ //
+ // Update the Runtime Architectural protocol with the template that the core was
+ // using so there would not need to be a dependency on the Runtime AP
+ //
+
+ //
+ // Copy all the registered Image to new gRuntime protocol
+ //
+ for (Link = gRuntimeTemplate.ImageHead.ForwardLink; Link != &gRuntimeTemplate.ImageHead; Link = TempLinkNode.ForwardLink) {
+ EfiCommonLibCopyMem (&TempLinkNode, Link, sizeof(EFI_LIST_ENTRY));
+ InsertTailList (&gRuntime->ImageHead, Link);
+ }
+ //
+ // Copy all the registered Event to new gRuntime protocol
+ //
+ for (Link = gRuntimeTemplate.EventHead.ForwardLink; Link != &gRuntimeTemplate.EventHead; Link = TempLinkNode.ForwardLink) {
+ EfiCommonLibCopyMem (&TempLinkNode, Link, sizeof(EFI_LIST_ENTRY));
+ InsertTailList (&gRuntime->EventHead, Link);
+ }
+
+ //
+ // Clean up gRuntimeTemplate
+ //
+ gRuntimeTemplate.ImageHead.ForwardLink = &gRuntimeTemplate.ImageHead;
+ gRuntimeTemplate.ImageHead.BackLink = &gRuntimeTemplate.ImageHead;
+ gRuntimeTemplate.EventHead.ForwardLink = &gRuntimeTemplate.EventHead;
+ gRuntimeTemplate.EventHead.BackLink = &gRuntimeTemplate.EventHead;
+ }
+
+ if (EfiCompareGuid (Entry->ProtocolGuid, &gEfiStatusCodeRuntimeProtocolGuid)) {
+ //
+ // Update StatusCode instance used by DXE core
+ //
+ gStatusCode = (EFI_STATUS_CODE_PROTOCOL *) Protocol;
+ }
+//*** AMI PORTING BEGIN ***//
+ if (EfiCompareGuid (Entry->ProtocolGuid, &gEfiSecurityArchProtocolGuid)) {
+ //
+ // Security2 Arch protocol should be available at this time
+ //
+ Status = CoreLocateProtocol (&gEfiSecurity2ArchProtocolGuid, NULL, &gSecurity2);
+ }
+//*** AMI PORTING END ***//
+ }
+
+ //
+ // It's over kill to do them all every time, but it saves a lot of code.
+ //
+ if (Found) {
+ CalculateEfiHdrCrc (&gRT->Hdr);
+ CalculateEfiHdrCrc (&gBS->Hdr);
+ CalculateEfiHdrCrc (&gST->Hdr);
+ CalculateEfiHdrCrc (&gDS->Hdr);
+ }
+}
+
+
+
+VOID
+CoreNotifyOnArchProtocolInstallation (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Creates an event that is fired everytime a Protocol of a specific type is installed
+
+Arguments:
+ NONE
+
+Returns:
+ NONE
+
+--*/
+{
+ EFI_STATUS Status;
+ ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
+
+ for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
+
+ //
+ // Create the event
+ //
+ Status = CoreCreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK,
+ GenericArchProtocolNotify,
+ NULL,
+ &Entry->Event
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Register for protocol notifactions on this event
+ //
+ Status = CoreRegisterProtocolNotify (
+ Entry->ProtocolGuid,
+ Entry->Event,
+ &Entry->Registration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ }
+}
+
+#ifdef EFI_DEBUG
+//
+// Following is needed to display missing architectural protocols in debug builds
+//
+typedef struct {
+ EFI_GUID *ProtocolGuid;
+ CHAR16 *GuidString;
+} GUID_TO_STRING_PROTOCOL_ENTRY;
+
+GUID_TO_STRING_PROTOCOL_ENTRY MissingProtocols[] = {
+ { &gEfiSecurityArchProtocolGuid, L"Security" },
+ { &gEfiCpuArchProtocolGuid, L"CPU" },
+ { &gEfiMetronomeArchProtocolGuid, L"Metronome" },
+ { &gEfiTimerArchProtocolGuid, L"Timer" },
+ { &gEfiBdsArchProtocolGuid, L"Bds" },
+ { &gEfiWatchdogTimerArchProtocolGuid, L"Watchdog Timer" },
+ { &gEfiRuntimeArchProtocolGuid, L"Runtime" },
+ { &gEfiVariableArchProtocolGuid, L"Variable" },
+ { &gEfiVariableWriteArchProtocolGuid, L"Variable Write" },
+ #if (EFI_SPECIFICATION_VERSION >= 0x00020000)
+ { &gEfiCapsuleArchProtocolGuid, L"Capsule" },
+ #endif
+ { &gEfiMonotonicCounterArchProtocolGuid, L"Monotonic Counter" },
+ { &gEfiResetArchProtocolGuid, L"Reset" },
+ { &gEfiStatusCodeRuntimeProtocolGuid, L"Status Code" },
+ { &gEfiRealTimeClockArchProtocolGuid, L"Real Time Clock" }
+};
+#endif
+
+DEBUG_CODE (
+VOID
+CoreDisplayMissingArchProtocols (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Displays Architectural protocols that were not loaded and are required for DXE core to function
+ Only used in Debug Builds
+
+Arguments:
+ NONE
+
+Returns:
+ NONE
+
+--*/
+{
+
+
+ GUID_TO_STRING_PROTOCOL_ENTRY *MissingEntry;
+
+ ARCHITECTURAL_PROTOCOL_ENTRY *Entry;
+
+
+ for (Entry = mArchProtocols; Entry->ProtocolGuid != NULL; Entry++) {
+ if (!Entry->Present) {
+ MissingEntry = MissingProtocols;
+ for (MissingEntry = MissingProtocols; TRUE ; MissingEntry++) {
+ if (EfiCompareGuid (Entry->ProtocolGuid, MissingEntry->ProtocolGuid)) {
+//*** AMI PORTING BEGIN ***//
+// MissingEntry->GuidString is a Unicode string, which in Aptio require a "%S" format specifier.
+// DEBUG ((EFI_D_ERROR, "\n%s Arch Protocol not present!!\n", MissingEntry->GuidString));
+ DEBUG ((EFI_D_ERROR, "\n%S Arch Protocol not present!!\n", MissingEntry->GuidString));
+//*** AMI PORTING END *****//
+ break;
+ }
+ }
+ }
+
+ }
+}
+)
diff --git a/Core/CORE_DXE/EfiPerf.h b/Core/CORE_DXE/EfiPerf.h
new file mode 100644
index 0000000..c5d1637
--- /dev/null
+++ b/Core/CORE_DXE/EfiPerf.h
@@ -0,0 +1,99 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/DxeMain/EfiPerf.h 3 5/06/08 10:07a Felixp $
+//
+// $Revision: 3 $
+//
+// $Date: 5/06/08 10:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/DxeMain/EfiPerf.h $
+//
+// 3 5/06/08 10:07a Felixp
+//
+// 2 5/05/08 4:12p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiPerf.h
+//
+// Description: This file provides performance API definitions used by DXE Core.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_PERF_H_
+#define _EFI_PERF_H_
+
+#include <AmiDxeLib.h>
+#include <Protocol/Performance.h>
+
+#define DXE_PHASE 0
+#define SHELL_PHASE 1
+#define PEI_PHASE 2
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+EFI_STATUS
+InitializePerformanceInfrastructure (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT64 Ticker
+ );
+
+EFI_STATUS
+UpdateMeasure (
+ IN EFI_HANDLE Handle,
+ IN UINT16 *Token,
+ IN UINT16 *Host,
+ IN EFI_HANDLE HandleNew,
+ IN UINT16 *TokenNew,
+ IN UINT16 *HostNew
+ );
+
+#ifdef EFI_DXE_PERFORMANCE
+#define PERF_ENABLE(handle, table, ticker) InitializePerformanceInfrastructure (handle, table, ticker)
+#define PERF_UPDATE(handle, token, host, handlenew, tokennew, hostnew) \
+ UpdateMeasure (handle, \
+ token, \
+ host, \
+ handlenew, \
+ tokennew, \
+ hostnew \
+ )
+#else
+#define PERF_ENABLE(handle, table, ticker)
+#define PERF_UPDATE(handle, token, host, handlenew, tokennew, hostnew)
+#endif
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Ffs.c b/Core/CORE_DXE/Ffs.c
new file mode 100644
index 0000000..3361ce2
--- /dev/null
+++ b/Core/CORE_DXE/Ffs.c
@@ -0,0 +1,266 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ffs.c
+
+Abstract:
+
+ FFS file access utilities.
+
+--*/
+
+
+#include "FwVolDriver.h"
+
+#define PHYSICAL_ADDRESS_TO_POINTER(Address) ((VOID *)((UINTN)(Address)))
+
+
+EFI_FFS_FILE_STATE
+GetFileState (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+ Get the FFS file state by checking the highest bit set in the header's state field
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ FfsHeader - Points to the FFS file header
+
+Returns:
+ FFS File state
+
+--*/
+{
+ EFI_FFS_FILE_STATE FileState;
+ UINT8 HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && ((HighestBit & FileState) == 0)) {
+ HighestBit >>= 1;
+ }
+
+ return (EFI_FFS_FILE_STATE)HighestBit;
+}
+
+
+BOOLEAN
+IsBufferErased (
+ IN UINT8 ErasePolarity,
+ IN VOID *InBuffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+ Check if a block of buffer is erased
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ InBuffer - The buffer to be checked
+ BufferSize - Size of the buffer in bytes
+
+Returns:
+ TRUE - The block of buffer is erased
+ FALSE - The block of buffer is not erased
+
+--*/
+{
+ UINTN Count;
+ UINT8 EraseByte;
+ UINT8 *Buffer;
+
+ if(ErasePolarity == 1) {
+ EraseByte = 0xFF;
+ } else {
+ EraseByte = 0;
+ }
+
+ Buffer = InBuffer;
+ for (Count = 0; Count < BufferSize; Count++) {
+ if (Buffer[Count] != EraseByte) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+VerifyFvHeaderChecksum (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+/*++
+
+Routine Description:
+ Verify checksum of the firmware volume header
+
+Arguments:
+ FvHeader - Points to the firmware volume header to be checked
+
+Returns:
+ TRUE - Checksum verification passed
+ FALSE - Checksum verification failed
+
+--*/
+{
+ UINT32 Index;
+ UINT32 HeaderLength;
+ UINT16 Checksum;
+ UINT16 *ptr;
+
+ HeaderLength = FvHeader->HeaderLength;
+ ptr = (UINT16 *)FvHeader;
+ Checksum = 0;
+
+ for (Index = 0; Index < HeaderLength / sizeof (UINT16); Index++) {
+ Checksum = (UINT16)(Checksum + ptr[Index]);
+ }
+
+ if (Checksum == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+BOOLEAN
+VerifyHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+ Verify checksum of the FFS file header
+
+Arguments:
+ FfsHeader - Points to the FFS file header to be checked
+
+Returns:
+ TRUE - Checksum verification passed
+ FALSE - Checksum verification failed
+
+--*/
+{
+ UINT32 Index;
+ UINT8 *ptr;
+ UINT8 HeaderChecksum;
+
+ ptr = (UINT8 *)FfsHeader;
+ HeaderChecksum = 0;
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ HeaderChecksum = (UINT8)(HeaderChecksum + ptr[Index]);
+ }
+
+ HeaderChecksum = HeaderChecksum - FfsHeader->State - FfsHeader->IntegrityCheck.Checksum.File;
+
+ if (HeaderChecksum == 0) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+
+BOOLEAN
+IsValidFfsHeader (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ OUT EFI_FFS_FILE_STATE *FileState
+ )
+/*++
+
+Routine Description:
+ Check if it's a valid FFS file header
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ FfsHeader - Points to the FFS file header to be checked
+ FileState - FFS file state to be returned
+
+Returns:
+ TRUE - Valid FFS file header
+ FALSE - Invalid FFS file header
+
+--*/
+{
+ *FileState = GetFileState (ErasePolarity, FfsHeader);
+
+ switch (*FileState) {
+ case EFI_FILE_HEADER_VALID:
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ case EFI_FILE_DELETED:
+ //
+ // Here we need to verify header checksum
+ //
+ return VerifyHeaderChecksum (FfsHeader);
+
+ case EFI_FILE_HEADER_CONSTRUCTION:
+ case EFI_FILE_HEADER_INVALID:
+ default:
+ return FALSE;
+ }
+}
+
+
+BOOLEAN
+IsValidFfsFile (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+ Check if it's a valid FFS file.
+ Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ FfsHeader - Points to the FFS file to be checked
+
+Returns:
+ TRUE - Valid FFS file
+ FALSE - Invalid FFS file
+
+--*/
+{
+ EFI_FFS_FILE_STATE FileState;
+
+ FileState = GetFileState (ErasePolarity, FfsHeader);
+ switch (FileState) {
+
+ case EFI_FILE_DELETED:
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ //
+ // Some other vliadation like file content checksum might be done here.
+ // For performance issue, Tiano only do FileState check.
+ //
+ return TRUE;
+
+ default:
+ return FALSE;
+ }
+}
+
diff --git a/Core/CORE_DXE/FrameworkHii/FrameworkHii.cif b/Core/CORE_DXE/FrameworkHii/FrameworkHii.cif
new file mode 100644
index 0000000..f5ece83
--- /dev/null
+++ b/Core/CORE_DXE/FrameworkHii/FrameworkHii.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "FrameworkHii"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\FrameworkHii\"
+ RefName = "FrameworkHii"
+[files]
+"FrameworkHii.sdl"
+"HIIDB.c"
+"FrameworkHiiUtils.c"
+<endComponent>
diff --git a/Core/CORE_DXE/FrameworkHii/FrameworkHii.sdl b/Core/CORE_DXE/FrameworkHii/FrameworkHii.sdl
new file mode 100644
index 0000000..e10b1d4
--- /dev/null
+++ b/Core/CORE_DXE/FrameworkHii/FrameworkHii.sdl
@@ -0,0 +1,15 @@
+TOKEN
+ Name = "FrameworkHii_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FrameworkHii support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FrameworkHii_DIR"
+ Help = "Path to FrameworkHii Module in Project"
+End
+
diff --git a/Core/CORE_DXE/FrameworkHii/FrameworkHiiUtils.c b/Core/CORE_DXE/FrameworkHii/FrameworkHiiUtils.c
new file mode 100644
index 0000000..c0ec1b8
--- /dev/null
+++ b/Core/CORE_DXE/FrameworkHii/FrameworkHiiUtils.c
@@ -0,0 +1,369 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/FrameworkHii/FrameworkHiiUtils.c 3 2/23/10 10:17p Felixp $
+//
+// $Revision: 3 $
+//
+// $Date: 2/23/10 10:17p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/FrameworkHii/FrameworkHiiUtils.c $
+//
+// 3 2/23/10 10:17p Felixp
+// SetBrowserData function is added
+//
+// 2 11/24/09 10:40a Felixp
+//
+// 1 10/09/09 6:10p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: UefiHiiUtils.c
+//
+// Description: Framework HII 0.91 HII Utilities Protocol Implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Protocol/HiiUtilities.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DevicePath.h>
+
+static EFI_HII_PROTOCOL *Hii=NULL;
+static EFI_GUID HiiResourcesFfsSectionGuid= HII_RESOURCES_FFS_SECTION_GUID;
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: SetCallback
+//
+// Description:
+// EFI_STATUS SetCallback(EFI_HII_IFR_PACK *pIfr,
+// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo,
+// CALLBACK_INFO **CallBackFound)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS SetCallback(
+ EFI_LOADED_IMAGE_PROTOCOL *Image,
+ EFI_IFR_FORM_SET *FormSet, UINTN NumberOfCallbacks,
+ CALLBACK_INFO *CallbackInfo, CALLBACK_INFO **CallBackFound,
+ EFI_HANDLE *CallbackHandle
+)
+{
+ UINTN i;
+ EFI_STATUS Status;
+ for(i=0; i<NumberOfCallbacks; i++)
+ {
+ if (
+ FormSet->Class==CallbackInfo[i].Class
+ && FormSet->SubClass==CallbackInfo[i].SubClass
+ && (!CallbackInfo[i].pGuid || !guidcmp(&FormSet->Guid,CallbackInfo[i].pGuid))
+ )
+ {
+ if (CallbackInfo[i].pFormCallback)
+ {
+ EFI_HANDLE Handle=NULL;
+ Status=pBS->InstallProtocolInterface(&Handle, &gEfiFormCallbackProtocolGuid, EFI_NATIVE_INTERFACE, CallbackInfo[i].pFormCallback);
+ if (EFI_ERROR(Status)) return Status;
+ FormSet->CallbackHandle=(EFI_PHYSICAL_ADDRESS)Handle;
+ if (CallbackHandle) *CallbackHandle=Handle;
+ }
+ if (CallBackFound) *CallBackFound=&CallbackInfo[i];
+ return EFI_SUCCESS;
+ }
+ }
+ if (CallBackFound) *CallBackFound=NULL;
+ return EFI_NOT_FOUND;
+}
+
+static EFI_STATUS PublishPackages(
+ IN VOID *PackagePointers, IN UINTN NumberOfPackages,
+ IN EFI_GUID *PackageGuid, IN EFI_HANDLE DriverHandle OPTIONAL,
+ OUT EFI_HII_HANDLE *HiiHandle
+){
+ EFI_STATUS Status;
+ EFI_HII_PACKAGES *PackageList;
+ EFI_HII_PACK_HEADER **Packages = PackagePointers;
+
+ if ( !Hii
+ && EFI_ERROR(Status=pBS->LocateProtocol(
+ &gEfiHiiProtocolGuid, NULL, &Hii
+ ))
+ ) return Status;
+
+ PackageList = Malloc(
+ sizeof(EFI_HII_PACKAGES)+sizeof(EFI_HII_PACK_HEADER*)*NumberOfPackages
+ );
+ if(PackageList==NULL) return EFI_OUT_OF_RESOURCES;
+ PackageList->NumberOfPackages=NumberOfPackages;
+ PackageList->GuidId = PackageGuid;
+ pBS->CopyMem(
+ PackageList+1, Packages, sizeof(EFI_HII_PACK_HEADER*)*NumberOfPackages
+ );
+ Status = Hii->NewPack(Hii, PackageList, HiiHandle);
+ pBS->FreePool(PackageList);
+ return Status;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: LoadStrings
+//
+// Description:
+// EFI_STATUS LoadStrings(EFI_HANDLE ImageHandle,
+// EFI_HII_HANDLE *HiiHandle)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS LoadStrings(
+ EFI_HANDLE ImageHandle, EFI_HII_HANDLE *HiiHandle
+)
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ HII_RESOURCE_SECTION_HEADER *pSection;
+ UINTN SectionSize;
+ EFI_HII_PACK_HEADER *pPack;
+
+ if (EFI_ERROR(Status=pBS->HandleProtocol(
+ ImageHandle, &gEfiLoadedImageProtocolGuid, &Image
+ ))
+ ) return Status;
+#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1
+{
+#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_
+ UINT8 *pData;
+ pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize);
+ if (!pData) return EFI_NOT_FOUND;
+ pSection = Malloc(SectionSize);
+ pBS->CopyMem(pSection,pData,SectionSize);
+ Status = EFI_SUCCESS;
+}
+#else
+{
+ Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize);
+ if (EFI_ERROR(Status)) return Status;
+}
+#endif
+ pPack = (EFI_HII_PACK_HEADER*)(pSection+1);
+ if (pPack->Type == EFI_HII_STRING){
+ Status = PublishPackages(
+ &pPack, 1,
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid,
+ NULL, HiiHandle
+ );
+ }else{
+ Status = EFI_INVALID_PARAMETER;
+ }
+ pBS->FreePool(pSection);
+ return Status;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: LoadResources
+//
+// Description:
+// EFI_STATUS LoadResources(EFI_HANDLE ImageHandle,
+// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo,
+// INIT_HII_PACK InitFunction)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS LoadResources(
+ EFI_HANDLE ImageHandle, UINTN NumberOfCallbacks,
+ CALLBACK_INFO *CallbackInfo, INIT_HII_PACK InitFunction
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ HII_RESOURCE_SECTION_HEADER *pSection;
+ UINTN SectionSize;
+ CALLBACK_INFO *pCallBackFound;
+ if (EFI_ERROR(Status=pBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, &Image))) return Status;
+#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1
+{
+#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_
+ UINT8 *pData;
+ pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize);
+ if (!pData) return EFI_NOT_FOUND;
+ pSection = Malloc(SectionSize);
+ pBS->CopyMem(pSection,pData,SectionSize);
+}
+#else
+{
+ Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize);
+ if (EFI_ERROR(Status)) return Status;
+}
+#endif
+{
+ EFI_HII_PACK_HEADER **IfrPackagPtr, **GlobalPackagPtr, **SharedPackagPtr;
+ UINTN NumberOfIfrPackages, NumberOfGlobalPackages, NumberOfSharedPackages, i;
+ UINT8 *PackagePtrBuffer;
+ EFI_HII_PACK_HEADER *PackagePtr;
+
+ PackagePtrBuffer = Malloc(3*pSection->NumberOfPackages*sizeof(EFI_HII_PACK_HEADER*));
+ IfrPackagPtr = (EFI_HII_PACK_HEADER**)PackagePtrBuffer;
+ GlobalPackagPtr = IfrPackagPtr+pSection->NumberOfPackages;
+ SharedPackagPtr = GlobalPackagPtr+pSection->NumberOfPackages;
+ NumberOfIfrPackages = 0;
+ NumberOfGlobalPackages = 0;
+ NumberOfSharedPackages = 0;
+
+ PackagePtr = (EFI_HII_PACK_HEADER*)(pSection+1);
+ while(PackagePtr < (EFI_HII_PACK_HEADER*)((UINT8*)pSection+SectionSize)){
+ switch(PackagePtr->Type){
+ case EFI_HII_IFR:
+ IfrPackagPtr[NumberOfIfrPackages++]=PackagePtr;
+ break;
+ case EFI_HII_FONT: case EFI_HII_KEYBOARD:
+ GlobalPackagPtr[NumberOfGlobalPackages++]=PackagePtr;
+ break;
+ default:
+ SharedPackagPtr[NumberOfSharedPackages++]=PackagePtr;
+ if (PackagePtr->Type==EFI_HII_STRING){
+ while(PackagePtr->Length)
+ PackagePtr = (EFI_HII_PACK_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length);
+ PackagePtr = (EFI_HII_PACK_HEADER*)((UINT8*)PackagePtr+sizeof(EFI_HII_STRING_PACK));
+ continue;
+ }
+ break;
+ }
+ PackagePtr = (EFI_HII_PACK_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length);
+ }
+ Status = PublishPackages(
+ GlobalPackagPtr, NumberOfGlobalPackages,
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid,
+ NULL, &HiiHandle
+ );
+ for(i=0; i<NumberOfIfrPackages; i++){
+ EFI_HANDLE CallbackHandle;
+
+ SharedPackagPtr[NumberOfSharedPackages]=IfrPackagPtr[i];
+ SetCallback(
+ Image, (EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1),
+ NumberOfCallbacks,CallbackInfo,&pCallBackFound,&CallbackHandle
+ );
+ Status = PublishPackages(
+ SharedPackagPtr, NumberOfSharedPackages+1,
+ &((EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1))->Guid,
+ CallbackHandle, &HiiHandle
+ );
+ if (pCallBackFound) pCallBackFound->HiiHandle=HiiHandle;
+ if (InitFunction) InitFunction(HiiHandle,pCallBackFound);
+ pCallBackFound=NULL;
+ }
+ pBS->FreePool(PackagePtrBuffer);
+ pBS->FreePool(pSection);
+}
+ return EFI_SUCCESS;
+}
+
+//TODO: header
+static EFI_STATUS GetString(
+ IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId,
+ IN OUT UINTN *StringSize, OUT EFI_STRING String
+){
+ if ( !Hii
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiProtocolGuid, NULL, &Hii))
+ ) return EFI_NOT_FOUND;
+ return Hii->GetString(
+ Hii, HiiHandle, StringId, TRUE, NULL, StringSize, String
+ );
+}
+
+//TODO header
+static EFI_STATUS SetString(
+ IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId, IN EFI_STRING String
+){
+ if ( !Hii
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiProtocolGuid, NULL, &Hii))
+ ) return EFI_NOT_FOUND;
+ return Hii->NewString(
+ Hii, L" ", HiiHandle, &StringId, String
+ );
+}
+
+static EFI_STATUS GetBrowserData(
+ IN UINTN *BufferSize, OUT VOID *Buffer,
+ IN CONST EFI_GUID *VarStoreGuid, OPTIONAL
+ IN CONST CHAR16 *VarStoreName OPTIONAL
+){
+ return EFI_UNSUPPORTED;
+}
+
+static EFI_STATUS SetBrowserData(
+ IN UINTN BufferSize, IN VOID *Buffer,
+ IN CONST EFI_GUID *VarStoreGuid, OPTIONAL
+ IN CONST CHAR16 *VarStoreName OPTIONAL
+){
+ return EFI_UNSUPPORTED;
+}
+
+HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol = {
+ LoadResources, LoadStrings, PublishPackages,
+ GetBrowserData, SetBrowserData, GetString, SetString
+};
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/FrameworkHii/HIIDB.c b/Core/CORE_DXE/FrameworkHii/HIIDB.c
new file mode 100644
index 0000000..b4bfbfc
--- /dev/null
+++ b/Core/CORE_DXE/FrameworkHii/HIIDB.c
@@ -0,0 +1,3511 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/FrameworkHii/HIIDB.c 5 2/10/10 5:08p Felixp $
+//
+// $Revision: 5 $
+//
+// $Date: 2/10/10 5:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/FrameworkHii/HIIDB.c $
+//
+// 5 2/10/10 5:08p Felixp
+// Bug fix in HiiExtGetFormInfo function.
+//
+// 4 2/10/10 3:43p Felixp
+// x64 compiler warnings are fixed.
+//
+// 3 12/29/09 2:38p Yakovlevs
+// Fixed issue with hanging in TSE big number of setup questions.
+// Changed size of Length fields in some HII internal structures from
+// UIN16 to UINTN.
+// Code clenup (removed not used variables changes to compile with W4)
+//
+// 2 12/04/09 2:16p Yakovlevs
+// 1.Fixed potential NULL pointer use in function NewFontPack()
+// 2.Fixed inconsistancy in VarStore management (requires updated HiiDb.h)
+//
+// 1 10/09/09 6:10p Felixp
+//
+// 45 6/03/09 10:58a Yakovlevs
+// if Hii->RemovePack is called reset global pointers to NULL since they
+// might pointing at data that was freed.
+//
+// 44 10/01/08 1:01p Yakovlevs
+// fixed bug in HiiExtGetFormLabels() function.
+//
+// 43 1/09/08 10:49a Yakovlevs
+//
+// 42 9/05/07 9:18p Felixp
+//
+// 41 9/05/07 5:59p Yakovlevs
+// Bug fixes in UpdateForm and RemovePack routines.
+//
+// 2 6/28/07 5:16p Yakovlevs
+// Fixed FormUpdate Protocol Function, and some other minor bug fixes.
+//
+// 39 5/23/07 4:32p Pavell
+// Reindexing formsets
+//
+// 38 3/18/07 3:10p Felixp
+// GetSecondaryLanguages fix: return EFI_NOT_FOUND when no languages found
+//
+// 37 3/12/07 6:06p Yakovlevs
+// Fixed NewKbPack function.
+//
+// 36 3/12/07 1:46p Yakovlevs
+// Handled a situation when there are no Keyboard Layout data in HII
+// Database.
+//
+// 35 3/07/07 8:21p Yakovlevs
+// Added GetKeyboardLayout function implamentation.
+//
+// 34 1/23/07 12:23p Yakovlevs
+//
+// 33 12/21/06 1:57p Felixp
+//
+// 32 12/20/06 10:37a Felixp
+//
+// 31 12/18/06 5:42p Pavell
+// Added a fix for variable size determination
+// 30 11/15/06 5:55p Yakovlevs
+//
+// 29 11/02/06 6:45p Yakovlevs
+// Fixed HiiTestString NON_SPACING attribute handling
+//
+// 27 10/31/06 11:15a Yakovlevs
+// HiiTestString fixed to skip none spacing characters.
+//
+// 25 10/30/06 6:09p Yakovlevs
+// HII Spec v 0.92 updates
+//
+// 24 9/27/06 7:44p Felixp
+// Improvement in GetHiiString:
+// If string is not found for the current system language language, try
+// with the package primary language.
+//
+// 23 9/26/06 9:03a Felixp
+// Multilanguage Support. Do not use hard-coded glyphs. Load font file
+// instead.
+//
+// 22 9/18/06 6:23p Felixp
+// Bug fix in HiiGetString: buffer overrun when Raw is FALSE
+//
+// 21 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 20 8/04/06 5:18p Felixp
+// Bug fix in NewFontPack function (wide glyph handling).
+//
+// 19 7/24/06 11:46a Yakovlevs
+// Hii->ExportDatabase support added.
+//
+// 18 3/13/06 5:30p Felixp
+//
+// 17 10/03/05 2:47p Markw
+// Fixed uninitialized variables.
+//
+// 16 7/20/05 6:43p Felixp
+// GlyphToBlt modifed to support wide characters
+//
+// 15 7/19/05 8:17p Felixp
+// NewString modified to support update for all languages when three
+// spaces Language provided
+//
+// 13 7/13/05 9:46p Felixp
+//
+// 12 6/24/05 2:03p Yakovlevs
+//
+// 11 6/23/05 5:43p Yakovlevs
+// Fixed "Missing String" message
+//
+// 10 5/27/05 12:16p Felixp
+// bug fix in HiiGetString
+//
+// 9 2/28/05 6:21p Yakovlevs
+// Fixed DateTime and Object Conditions issue;
+//
+// 8 3/17/05 1:57p Felixp
+// implementation of HiiNewPackNew updated
+//
+// 7 3/04/05 12:52p Felixp
+//
+// 6 3/04/05 9:23a Mandal
+//
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <This File Name>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//
+// Module Name: HIIDB.C
+//
+// Abstract: This file contains implementation of HII Database Protocol.
+//
+#include <HiiDb.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/HiiUtilities.h>
+extern UINT8 *UsStdNarrowGlyphData;
+extern HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol;
+
+//==================================================================================
+// Some globals we need
+//==================================================================================
+
+//------------------------------------------
+//Prototypes
+EFI_STATUS InitPrivateData(EFI_HANDLE MyImgHandle);
+EFI_STATUS CreateLabelObjects(HII_LABEL *Label);
+//EFI_STATUS HiiNewPack (IN EFI_HII_PROTOCOL *This,
+// IN EFI_HII_PACK_LIST *Package,
+// OUT EFI_HII_HANDLE *Handle);
+
+//------------------------------------------
+//GUIDs
+EFI_GUID gEfiHiiProtocolGuidOld = EFI_HII_OLD_PROTOCOL_GUID;
+EFI_GUID gEfiHiiProtocolGuidNew = EFI_HII_NEW_PROTOCOL_GUID;
+static EFI_GUID gEfiExtHiiProtocolGuid = EFI_HII_EXT_PROTOCOL_GUID;
+//------------------------------------------
+//Data Vars
+
+//Define String Database Key fields
+#define STR_KEY 0
+#define STR_KEY_CNT 1
+//it is going to be combined key
+//Token->size16;LangIdx->size32;Handle->size16; total = 8 byte->UINT64
+//Token->Least Segnificant Field Handle Most Significant Field
+//the resulting Index for StringToken->23, LangIndex->2, Hii Handle=1 will be
+// Handle|LangIdx |Token
+// 0x0001|00000002|0023 -> easy to sort easy to find
+static DBE_OFFSET_KEY_CONTEXT gStrOffsetInfo = {EFI_FIELD_OFFSET(HII_STR ,Token), 8 };
+static DBE_KEY_FIELD gStrKey=OFFSET_KEY(gStrOffsetInfo);
+
+//Any Language Printable string
+static UINT16 gAnyLang[]=L"Any Language";
+//HII DATABASE global var
+static HII_DB gHiiDb;
+
+///////////////////////////////////////////////////////////////////
+//in order to save some time when LocateHandle routine been called
+//I have decide to save Current HandleInfo structure pionter
+//here rather than locate it every time
+static HII_HANDLE *mCurHnd=NULL;
+static HII_LANG *mCurLang=NULL;
+static UINTN mCurHid=0, mCurLid=0;
+
+///////////////////////////////////////////////////////////////////
+//in order to save some time when HiiGetLine routine been called
+//I have decide to save Current StringInfo structure pionter
+//here rather than locate it every time HiiGetLine been called
+static HII_STR *mCurStr=NULL;
+
+///////////////////////////////////////////////////////////////////
+// save the varstore context based on the formset
+static UINT16 CurrentVarId = 0;
+
+//==================================================================================
+// Entry Point
+//==================================================================================
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: HiiDbEntryPoint()
+//
+// Description: Initialize HII Database (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+//
+// Input: EFI_HANDLE ImageHandle This Driver Image Handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI System Table
+//
+// Output: EFI_STATUS EFI_SUCCESS - Driver Loadded.
+// Other - Driver Error
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS HiiDbEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable){
+ EFI_STATUS Status=0;
+ UINTN hCnt;
+ EFI_HANDLE *hBuf;
+//-----------------------------------
+ InitAmiLib(ImageHandle, SystemTable);
+
+ //Only one HII Driver has to be in the system
+ Status=pBS->LocateHandleBuffer(ByProtocol, &gEfiHiiProtocolGuidOld, NULL, &hCnt, &hBuf);
+
+ //If there was no error, report that we has been already started
+ if (!EFI_ERROR(Status)) {
+ if (!hBuf)pBS->FreePool(hBuf); //Don't forget to free the memory
+ return EFI_ALREADY_STARTED;
+ }
+
+ Status=InitPrivateData(ImageHandle);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(&gHiiDb.HiiHandle,
+ &gEfiHiiProtocolGuidOld,&gHiiDb.HiiProtocolOld,
+ &gEfiHiiProtocolGuidNew,&gHiiDb.HiiProtocolNew,
+ &gEfiExtHiiProtocolGuid,&gHiiDb.HiiExtProtocol,
+ &gHiiUtilitiesProtocolGuid, &HiiUtilitiesProtocol,
+ NULL);
+ return Status;
+}
+
+///////////////////////////////////////////////////////////////////
+// Common Worker Functions
+///////////////////////////////////////////////////////////////////
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: GetDefaultLang
+//
+// Description:
+// EFI_STATUS GetDefaultLang(OUT CHAR16 *DefaultLang) returns the default
+// system language in the string specified by DefaultLang.
+//
+// Input:
+// OUT CHAR16 *DefaultLang
+// Pointer to the null-terminated Unicode string.
+//
+// Output:
+// EFI_NOT_FOUND, if the default language could not be found.
+// Otherwise, EFI_SUCCESS.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+//Get System Default Language
+EFI_STATUS GetDefaultLang(CHAR16 *DefaultLang){
+ EFI_GUID EfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_STATUS Status=0;
+ UINT8 al[3];
+ UINTN i=sizeof(al);
+//-----------------------
+ Status=pRS->GetVariable(L"Lang",&EfiGlobalVariableGuid,NULL,&i,al);
+ if (EFI_ERROR(Status)) return Status;
+
+ for(i=0; i<sizeof(al) ;i++) DefaultLang[i]=al[i];
+ DefaultLang[sizeof(al)]=0;
+ return Status;
+}
+
+//-----------------------------------------------------------------
+//This Function will look in Item List and try to find mutch for Item of Size.
+//if it finds it will return Pointer to the matching Item and update Index if not - NULL
+EFI_STATUS LocateItem(T_ITEM_LIST *ItemLst, VOID *Item, UINTN Size, OUT UINTN *Index){
+ UINTN i;
+//-----------------
+ for(i=0; i<ItemLst->ItemCount; i++){
+ if(!MemCmp(ItemLst->Items[i],Item,Size)) {
+ if(Index)*Index=i;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+///////////////////////////////////////////////////////////////////
+//Will return Lenth of the screen representation of Str with respect
+//of wide narrow and non spacing glyphs it using
+//Len excluding '0' char (\n)
+UINT16 GetScrLen(CHAR16 *Str, UINT16 Len){
+ UINTN i;
+ UINT16 u,sl=0;
+ HII_N_FONT *fnt;
+//--------------------------------------
+ for(i=0;i<Len;i++){
+ u=Str[i];
+ if(u<0x20 || u>=0xfff0)continue;
+ fnt=gHiiDb.FontDb[u];
+ if(fnt){
+ if(fnt->Attr & GLYPH_NON_SPACING) continue;
+ if(fnt->Attr & GLYPH_WIDE) sl+=2;
+ else sl++;
+ } else sl++; //we will print empty rect for non existent glyph
+ }
+ return sl;
+}
+
+///////////////////////////////////////////////////////////////////
+//Will allocate Mem for the length of the string and Copy "Str" there
+UINT16* StrAlloc(UINT16 *Str,UINT16 *StrLen OPTIONAL, UINT16 *ScrLen OPTIONAL){
+ UINT16 len;
+ UINT16 *str;
+//-------------------------------------
+ len=(UINT16)Wcslen(Str);//terminator not included
+ str=(UINT16*)Malloc((len+1)*sizeof(UINT16));
+ if(!str)return NULL;
+ Wcscpy(str,Str);
+ if(StrLen)*StrLen=len+1;
+ if(ScrLen)*ScrLen=GetScrLen(Str,len);
+ return str;
+}
+
+///////////////////////////////////////////////////////////////////
+//This will Change Language Attributes
+//VOID SetLangAttr(UINTN Index, UINT32 Attr){
+// HII_LANG *lang;
+//--------------------
+// lang=(HII_LANG*)gHiiDb.LangDb.ResDsc[Index];
+// lang->Attr=Attr;
+//}
+
+///////////////////////////////////////////////////////////////////
+//this will find and return HII_LANG "Index",
+//if "Language" is stored In Hii Handle Database
+HII_LANG* LocateLang(UINT16 *Language, UINTN *Index){
+ EFI_STATUS Status;
+ UINTN idx;
+//------------------------
+ if( !mCurLang || MemCmp(&mCurLang->sName[0],Language,sizeof(mCurLang->sName)) )
+ {
+ Status=LocateItem(&gHiiDb.LangDb,Language,sizeof(UINT16)*4,&idx);
+ if(EFI_ERROR(Status)){
+ mCurLang=NULL; //flush Language Cache
+ mCurLid=0; //make index to generate exception if used
+ } else {
+ mCurLang=gHiiDb.LangDb.Items[idx];
+ mCurLid=idx;
+ }
+ }
+ if(mCurLang && Index)*Index=mCurLid;
+ return mCurLang;
+}
+
+HII_HANDLE *LocateHandleGuid(EFI_GUID *Guid, UINTN *Index){
+ HII_HANDLE *phnd=NULL;
+ UINTN i;
+//-------------------------------
+ for(i=0; i<gHiiDb.HandleDb.ItemCount; i++){
+ phnd=gHiiDb.HandleDb.Items[i];
+ if(!MemCmp(&phnd->Guid,Guid,sizeof(EFI_GUID)))break;
+ else phnd=NULL;
+ }
+ if(phnd && Index)*Index=i;
+ return phnd;
+}
+
+///////////////////////////////////////////////////////////////////
+//This function will Locate another Handle with the same Guid as
+//passed Handle.
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//This function is Obsolete but I need it for compliance with Intel's
+//Setup because they using same guid more than once per Ifr and Strings pare.
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+VOID LocateSameGuidHandle(UINTN CurIdx, UINTN *IdxBuffer, UINTN *IdxCount){
+ HII_HANDLE *phnd=NULL,*chnd=gHiiDb.HandleDb.Items[CurIdx];
+ UINTN i, c=0;
+//----------------------------
+ for(i=0; i<gHiiDb.HandleDb.ItemCount; i++){
+ if(i==CurIdx) continue;
+ phnd=gHiiDb.HandleDb.Items[i];
+ if(!MemCmp(&phnd->Guid,&chnd->Guid,sizeof(EFI_GUID))){
+ IdxBuffer[c]=i;
+ c++;
+ }else phnd=NULL;
+ }
+ *IdxCount=c;
+}
+
+///////////////////////////////////////////////////////////////////
+//if on passed handle in any string function there are no
+//strings associated with we need to find another handle with
+//the same guid having strings on it
+HII_HANDLE *LocateStrHandleGuid(UINTN CurIdx, UINTN *Index){
+ HII_HANDLE *phnd=NULL,*chnd=gHiiDb.HandleDb.Items[CurIdx];
+ UINTN i;
+//----------------------------
+ for(i=0; i<gHiiDb.HandleDb.ItemCount; i++){
+ if(i==CurIdx) continue;
+ phnd=gHiiDb.HandleDb.Items[i];
+ if(!MemCmp(&phnd->Guid,&chnd->Guid,sizeof(EFI_GUID)) && phnd->HasStr){
+ if(Index)*Index=i;
+ break;
+ }else phnd=NULL;
+ }
+ return phnd;
+}
+
+///////////////////////////////////////////////////////////////////
+//this will find and return HII_HANDLE "Index",
+//if "Handle" is stored In Hii Handle Database
+static HII_HANDLE* LocateHandle(EFI_HII_HANDLE Handle, UINTN *Index){
+ EFI_STATUS Status;
+ UINTN idx;
+//------------------------
+ if((!mCurHnd) || (mCurHnd->Handle!=Handle)){
+ Status=LocateItem(&gHiiDb.HandleDb,&Handle,sizeof(EFI_HII_HANDLE),&idx);
+ if(EFI_ERROR(Status)){
+ mCurHnd=NULL; //flush Handle Cache
+ mCurHid=-1; //make index to generate exception if used
+ } else {
+ mCurHnd=gHiiDb.HandleDb.Items[idx];
+ mCurHid=idx;
+ }
+ }
+ if(mCurHnd && Index)*Index=mCurHid;
+ return mCurHnd;
+}
+
+///////////////////////////////////////////////////////////////////
+//this will find and return HII_HANDLE "Index",
+//if "Handle" is stored in Handle Database
+//or Append Handle Database with this Handle if not and return a new "Index"
+EFI_STATUS LocateHandleAdd(EFI_HII_HANDLE Handle, EFI_GUID *GuidId, UINTN *Index){
+ EFI_STATUS Status=0;
+ HII_HANDLE *phnd;
+//----------------
+ phnd=LocateHandle(Handle,Index);
+ if(!phnd){
+ phnd=MallocZ(sizeof(HII_HANDLE));
+ if(!phnd)return EFI_OUT_OF_RESOURCES;
+ pBS->CopyMem(&phnd->Guid,GuidId,sizeof(EFI_GUID));
+ phnd->Handle=Handle;
+ Status=AppendItemLst(&gHiiDb.HandleDb,phnd);
+ if(EFI_ERROR(Status)) return Status;
+ *Index=gHiiDb.HandleDb.ItemCount-1;
+ }
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+//this will find and return HII_LANG "Index",
+//if "Language" is stored in Handle Database
+//or Append Handle Database with this Handle if not and return a new "Index"
+EFI_STATUS LocateLangAdd(UINT16 *Language, UINT16 *PrintLanguage, UINTN *Index){
+ EFI_STATUS Status;
+ HII_LANG *lang;
+//------------------
+ //Check if we have the Language installed already
+ lang=LocateLang(Language,Index);
+ if(!lang){
+ lang=MallocZ(sizeof(HII_LANG));
+ if(!lang)return EFI_OUT_OF_RESOURCES;
+ pBS->CopyMem(&lang->sName,Language,sizeof(UINT16)*4);
+ if(PrintLanguage){
+ lang->lName=StrAlloc(PrintLanguage,NULL,NULL);
+ if(!lang->lName) return EFI_OUT_OF_RESOURCES;
+ }
+ Status=AppendItemLst(&gHiiDb.LangDb,lang);
+ if(EFI_ERROR(Status)) return Status;
+ if(Index)*Index=gHiiDb.LangDb.ItemCount-1;
+ }
+ return EFI_SUCCESS;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//This will check if Lang Index is present in Secondary Lang List
+//on this Handle
+///////////////////////////////////////////////////////////////////
+EFI_STATUS LocateSecLangAdd(HII_HANDLE *Hnd, UINTN *SecLangIdx, BOOLEAN AddIt){
+ UINTN i;
+//------------------------------
+ for(i=0; i<Hnd->SecLang.ItemCount; i++){
+ if(*SecLangIdx==(UINTN)(Hnd->SecLang.Items[i])) return EFI_SUCCESS;
+ }
+ if(AddIt)return AppendItemLst(&Hnd->SecLang,(VOID*)(*SecLangIdx));
+ else return EFI_NOT_FOUND;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//=================================================================
+//HII Database Protocol Functions
+//=================================================================
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+// Font related
+///////////////////////////////////////////////////////////////////
+EFI_STATUS NewFontPack(IN EFI_HII_FONT_PACK *Package)
+{
+ UINTN i;
+ UINT16 u;
+ EFI_NARROW_GLYPH *ng;
+ EFI_WIDE_GLYPH *wg;
+//--------------------------
+
+ //Set Pointer to the beginning of Package Data.
+ ng=(EFI_NARROW_GLYPH*)(Package+1);
+
+ if(Package->NumberOfNarrowGlyphs){
+ HII_N_FONT *fnt;
+ //---------------------------
+ //Allocate Space for Number of Narrow Glyphs
+ fnt=(HII_N_FONT*)Malloc(sizeof(HII_N_FONT)*Package->NumberOfNarrowGlyphs);
+ if(!fnt)return EFI_OUT_OF_RESOURCES;
+
+ for(i=0; i<Package->NumberOfNarrowGlyphs; i++){
+ u=ng[i].UnicodeWeight;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ //we will populate only empty spots in FontD or oposite
+//made SDL token for that
+ if(!gHiiDb.FontDb[u]){
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ //fnt=(HII_FONT*)Malloc(sizeof(HII_FONT));
+ pBS->CopyMem((VOID*)&fnt[i], &ng[i].Attributes,sizeof(HII_N_FONT));
+ gHiiDb.FontDb[u]=&fnt[i];
+ }
+ }
+ }
+
+
+ if(Package->NumberOfWideGlyphs){
+ UINTN j,k;
+ HII_W_FONT *fnt;
+ //---------------
+ //Allocate Space for Number of Wide Glyphs
+ wg=(EFI_WIDE_GLYPH*)(ng+Package->NumberOfNarrowGlyphs);
+ fnt=(HII_W_FONT*)Malloc((sizeof(HII_W_FONT))*Package->NumberOfWideGlyphs);
+ if(!fnt)return EFI_OUT_OF_RESOURCES;
+
+ for(i=0; i<Package->NumberOfWideGlyphs; i++){
+ u=wg[i].UnicodeWeight;
+ if(!gHiiDb.FontDb[u]){
+ fnt[i].Attr=wg[i].Attributes;
+ for(j=0,k=0; j<NG_SIZE;j++, k+=2){
+ fnt[i].GlData[k]=wg[i].GlyphCol1[j];
+ fnt[i].GlData[k+1]=wg[i].GlyphCol2[j];
+ }
+ gHiiDb.FontDb[u]=(HII_N_FONT*)&fnt[i];
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiTestString(IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *StringToTest,
+ IN OUT UINT32 *FirstMissing,
+ OUT UINT32 *GlyphBufferSize)
+{
+ EFI_STATUS Status=0;
+ UINT32 i;
+ UINT32 bs=0;
+ HII_N_FONT *fnt;
+//------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+ if ((!FirstMissing)||(!StringToTest)||(!GlyphBufferSize)) return EFI_INVALID_PARAMETER;
+
+ i=*FirstMissing;
+ while (StringToTest[i]!=0){
+ fnt=gHiiDb.FontDb[ StringToTest[i] ];
+ if(fnt){
+ if(fnt->Attr& GLYPH_NON_SPACING ){
+ i++;
+ continue;
+ }
+ if(fnt->Attr&GLYPH_WIDE) bs+=WG_SIZE;
+ else bs+=NG_SIZE;
+ i++;
+ } else {
+ Status=EFI_NOT_FOUND;
+ break;
+ }
+ }
+ *FirstMissing=i;
+ *GlyphBufferSize=bs;
+ return Status;
+}
+
+static UINT8 gGE[NG_SIZE]=
+ {0x00,0x00,0x00,0x7E,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x7E,0x00,0x00,0x00};// \
+// 0x00,0x00,0x00,0x7E,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x7E,0x00,0x00,0x00};
+
+static EFI_WIDE_GLYPH gGB;
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetGlyph(IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Source,
+ IN OUT UINT16 *Index,
+ OUT UINT8 **GlyphBuffer,
+ OUT UINT16 *BitWidth,
+ IN OUT UINT32 *InternalStatus)
+{
+ UINTN i, bs=NG_SIZE;
+ HII_N_FONT *fnt;//=gHiiDb.FontDb[Source[j]];
+// HII_GL_COL *gc1=NULL, *gc2=NULL;
+// BOOLEAN w=FALSE;
+//------------------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ if((!GlyphBuffer)||(!Index)||(!Source)||(!BitWidth)) return EFI_INVALID_PARAMETER;
+ fnt=gHiiDb.FontDb[Source[*Index]];
+
+ if(!fnt) {
+ if(InternalStatus)*InternalStatus=(UINT32)-1;
+ //If after calling TestString somebody will call us with invalid Unicode Char
+ pBS->CopyMem(&gGB.GlyphCol1[0],&gGE, NG_SIZE);
+ *BitWidth=GLYPH_W;
+ *GlyphBuffer=(UINT8*)&gGB;
+ (*Index)++;
+ return EFI_NOT_FOUND;
+ }
+
+ //first char must not be the non-spacing character
+ if(fnt->Attr&GLYPH_NON_SPACING) return EFI_INVALID_PARAMETER;
+
+ if(fnt->Attr&GLYPH_WIDE){
+ *BitWidth=GLYPH_W*2;
+ bs=WG_SIZE;
+ } else *BitWidth=GLYPH_W;
+
+ pBS->SetMem(&gGB,sizeof(EFI_WIDE_GLYPH),0);
+ do{
+ fnt=gHiiDb.FontDb[Source[*Index]];
+ for(i=0;i<bs;i++) gGB.GlyphCol1[i]|=fnt->GlData[i];
+ (*Index)++;
+ } while(fnt->Attr&GLYPH_NON_SPACING);
+ *GlyphBuffer=(UINT8*)&gGB;
+ if(InternalStatus)*InternalStatus=0;
+
+ return EFI_SUCCESS;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//!!!! this function suppose to take care of thing with mixed size gpyphs
+EFI_STATUS HiiGlyphToBlt(IN EFI_HII_PROTOCOL *This,
+ IN UINT8 *GlyphBuffer,
+ IN EFI_UGA_PIXEL Foreground,
+ IN EFI_UGA_PIXEL Background,
+ IN UINTN Count,//Number of NARROW Glyps left in BltBuffer
+ //or count from the end of the buffer in terms of NARROW glyphs
+ IN UINTN Width,
+ IN UINTN Height,
+ IN OUT EFI_UGA_PIXEL *BltBuffer)
+{
+// UINTN x,y;//,i,o;
+// UINT8 k = Width > GLYPH_W ? 2 : 1;
+//------------------------------------
+// if(!This) return EFI_INVALID_PARAMETER;
+// if( !(Width==GLYPH_W || Width==(GLYPH_W*2)) || Height!=GLYPH_H )return EFI_INVALID_PARAMETER;
+/* for (y=0,o=0; y<Height; y++){
+ for(i=0; i<Width/GLYPH_W; i++){
+ for (x=0; x<GLYPH_W; x++){
+ if ( GlyphBuffer[y*k+i] & (0x80 >> x)) BltBuffer[y*GLYPH_W*Count+x+o]=Foreground;
+ else BltBuffer[y*GLYPH_W*Count+x+o]=Background;
+ }
+ o=GLYPH_W;
+ }
+ }
+
+ return EFI_SUCCESS;
+ UINTN X;
+ UINTN Y;
+*/
+ UINT8 Mask;
+ UINTN Index, Line, Part;
+ UINTN TotalParts = Width/GLYPH_W;
+ EFI_NARROW_GLYPH *Glyph = (EFI_NARROW_GLYPH *)GlyphBuffer;
+ if(!This) return EFI_INVALID_PARAMETER;
+ if( !(Width==GLYPH_W || Width==GLYPH_W*2) || Height!=GLYPH_H || Count<TotalParts)return EFI_INVALID_PARAMETER;
+ for (Line = 0, Index=0; Line < Height; Line++, Index+=GLYPH_W * (Count-TotalParts)) {
+ for(Part=0; Part<TotalParts; Part++){
+ for (Mask = 0x80; Mask > 0; Mask>>=1, Index++) {
+ if (Glyph->GlyphCol1[Line*TotalParts+Part] & Mask)
+ BltBuffer[Index] = Foreground;
+ else
+ BltBuffer[Index] = Background;
+ }
+ }
+ }
+/*///
+ BltBuffer[Index] = (Glyph->GlyphCol1[y] & (1 << x)) ? Foreground : Background;
+ if (Width > GLYPH_W)
+ BltBuffer[Index+GLYPH_W] = (Glyph->GlyphCol1[GLYPH_H+y] & (1 << x)) ? Foreground : Background;
+///
+ EFI_NARROW_GLYPH *Glyph = (EFI_NARROW_GLYPH *)GlyphBuffer;
+ for (y = 0; y < Height; y++) {
+ for (x = 0; x < GLYPH_W; x++) {
+ UINTN Index = y * GLYPH_W * Count + (GLYPH_W - x - 1);
+ for(i=0; i<Width/GLYPH_W; i++)
+ if ((Glyph->GlyphCol1[i*GLYPH_H+y] & (1 << x)) != 0)
+ BltBuffer[Index+GLYPH_W*i] = Foreground;
+ else
+ BltBuffer[Index+GLYPH_W*i] = Background;
+ }
+ }*/
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+// String related
+///////////////////////////////////////////////////////////////////
+HII_STR *LocateString(HII_HANDLE *PHnd, UINTN LangIdx, STRING_REF Token/*, UINTN HandleIdx OPTIONAL*/){
+ UINTN li=LangIdx, j;
+ HII_STR sd = {0,0,0,0,NULL};
+ INT8 v;
+ VOID **cs;
+//-----------------
+ //if CurrentString must be refreshed
+ if(!mCurStr || mCurStr->LangIdx!=LangIdx || mCurStr->Token!=Token || mCurStr->Handle!=PHnd->Handle)
+ {
+
+ //---------------------
+ do {
+ sd.Handle=PHnd->Handle;
+ sd.LangIdx=(UINT32)li;
+ sd.Token=Token;
+
+ DbeLocateKey(&gHiiDb.StringDb,STR_KEY,(VOID*)&sd,(VOID**)&cs,&v,&j);
+
+ if(v)mCurStr=NULL;
+ else {
+ mCurStr=(HII_STR*)(*cs);
+ break;
+ }
+
+ //if we were looking for any language and failed
+ //just get Primary Package Language
+ if(!li)li=PHnd->PriLang;
+ else break;
+ } while(v);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this patch was made to keep compatibility with Intel's implemntation
+//of BDS - DevicerManagerVfrBin and FrontPageVfrBin uses the same Guid
+//and Same String Pack expecting valid strings on from one StringPack
+//when passing different GUIDs?????????
+/* if(!mCurStr){
+ HII_HANDLE *phnd;
+ UINTN i,sgib[10]={0,0,0,0,0,0,0,0,0,0};//same GUID index Buffer
+ //----------------------------------
+ LocateSameGuidHandle(HandleIdx,&sgib[0],&c);
+ for(i=0; i<c;i++){
+ li=LangIdx;
+ phnd=gHiiDb.HandleDb.Items[sgib[i]];
+ do {
+ sd.Handle=phnd->Handle;
+ sd.LangIdx=(UINT32)li;
+ sd.Token=Token;
+
+ DbeLocateKey(&gHiiDb.StringDb,STR_KEY,(VOID*)&sd,(VOID**)&cs,&v,&j);
+
+ if(v)mCurStr=NULL;
+ else {
+ mCurStr=(HII_STR*)(*cs);
+ break;
+ }
+ //if we were looking for any language and faild
+ //just get Primary Package Language
+ if(!li)li=PHnd->PriLang;
+ else break;
+ } while(v);
+ if(mCurStr)break;
+ }
+ }
+*/
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ }
+ return mCurStr;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS ReplaceString(HII_STR *StrData, UINT16 *Replacement)
+{
+ UINT16 *str;
+ UINT16 len,slen;
+//-----------------------------
+ str=StrAlloc(Replacement, &len, &slen);
+ if(!str)return EFI_OUT_OF_RESOURCES;
+
+ if(StrData->NewStr.StrPtr)pBS->FreePool(StrData->NewStr.StrPtr);
+
+ StrData->NewStr.StrLen=len;
+ StrData->NewStr.ScrLen=slen;
+ StrData->NewStr.StrPtr=str;
+
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS AddString(UINTN LangIdx, HII_HANDLE *PHandle, UINT16 *String, BOOLEAN Initial, STRING_REF *Token)
+{
+ HII_STR *str;
+//-------------------------------------
+ str=MallocZ(sizeof(HII_STR));
+ if(!str) return EFI_OUT_OF_RESOURCES;
+
+ if(Initial){
+ str->String.StrPtr=StrAlloc(String,&str->String.StrLen,&str->String.ScrLen);
+ if(!(str->String.StrPtr))return EFI_OUT_OF_RESOURCES;
+ } else {
+ str->NewStr.StrPtr=StrAlloc(String,&str->NewStr.StrLen, &str->NewStr.ScrLen);
+ if(!(str->NewStr.StrPtr))return EFI_OUT_OF_RESOURCES;
+ }
+
+ str->LangIdx=(UINT32)LangIdx;
+ //if Token is provided, use it. Otherwise assign new one.
+ if (Token && *Token) str->Token=*Token;
+ else
+ {
+ str->Token=PHandle->NextStrToken;
+ PHandle->NextStrToken++;
+ if (Token) *Token = str->Token;
+ }
+ str->Handle=PHandle->Handle;
+
+ return DbeInsert(&gHiiDb.StringDb,(VOID*)str);
+}
+
+EFI_STATUS UpdateString(IN UINTN li,
+ IN HII_HANDLE *phnd,
+ IN STRING_REF *Reference,
+ IN CHAR16 *NewString)
+{
+ EFI_STATUS Status;
+ //Check if String with this Token# already present in String Db
+ if((*Reference)==0){
+ Status=AddString(li,phnd,NewString,FALSE,Reference);
+ if(EFI_ERROR(Status)) return Status;
+ } else {
+ HII_STR *str;
+ if (*Reference >= phnd->NextStrToken) return EFI_INVALID_PARAMETER;
+ str=LocateString(phnd,li,*Reference);
+ //if str is NULL, it means that string with this token has been created
+ //for a different language
+ Status= (str) ? ReplaceString(str,NewString) : AddString(li,phnd,NewString,FALSE,Reference);
+ }
+ return Status;
+
+}
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiNewString(IN EFI_HII_PROTOCOL *This,
+ IN CHAR16 *Language,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF *Reference,
+ IN CHAR16 *NewString)
+{
+ UINTN li=0, hi=0;
+ HII_LANG *lang;
+ HII_HANDLE *phnd;
+ EFI_STATUS Status=0;
+ UINT16 dl[4]={0x20,0x20,0x20,0}, *pdl;//Any Lang
+//-------------------------------
+ if(!This || !Reference || !NewString) return EFI_INVALID_PARAMETER;
+ //first Check if the Handle is valid.
+ phnd=LocateHandle(Handle,&hi);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+
+ if(!phnd->HasStr){
+ phnd=LocateStrHandleGuid(hi,&hi);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+ }
+
+ if(!Language){
+ pdl=&dl[0];
+ if(EFI_ERROR( GetDefaultLang(pdl))){
+ pdl=(UINT16*)gHiiDb.LangDb.Items[phnd->PriLang];
+ }
+ } else pdl=Language;
+
+ //dl has a language string "xxx"
+ lang=LocateLang(pdl,&li);
+
+ if (!li)
+ {//language index 0 referes to language " ", which means we have to update
+ //string for all languages
+ //update string for primary language
+ Status = UpdateString(phnd->PriLang,phnd,Reference,NewString);
+ //update string for all secondary languages
+ for(li=0; !EFI_ERROR(Status) && li<phnd->SecLang.ItemCount; li++)
+ Status = UpdateString((UINTN)phnd->SecLang.Items[li],phnd,Reference,NewString);
+ return Status;
+ }
+
+ if(!lang) return EFI_INVALID_PARAMETER;
+
+ //If language is valid but not mutch Pack PriLang
+ if(phnd->PriLang!=li){
+ Status=LocateSecLangAdd(phnd,&li,FALSE);
+ if(EFI_ERROR(Status))li=phnd->PriLang;
+ //lang=(HII_LANG*)gHiiDb.LangDb.Items[li];
+ }
+ return UpdateString(li,phnd,Reference,NewString);
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS GetLanguageFromPack(EFI_HII_STRING_PACK *Pack, UINTN *LangIndex){
+ UINT16 *sn, *ln;
+ UINT8 *ofs=(UINT8*)Pack;//(Pack+1);
+//-------------------------
+ sn=(UINT16*)(ofs+Pack->LanguageNameString);
+ ln=(UINT16*)(ofs+Pack->PrintableLanguageName);
+ return LocateLangAdd(sn,ln,LangIndex);
+}
+
+///////////////////////////////////////////////////////////////////
+BOOLEAN IsLastStrPack(EFI_HII_STRING_PACK *Pack){
+ if(Pack->Header.Type==EFI_HII_STRING &&
+ Pack->Header.Length == 0 && Pack->Attributes == 0 &&
+ Pack->LanguageNameString == 0 && Pack->NumStringPointers == 0 &&
+ Pack->PrintableLanguageName == 0 ) return TRUE;
+ return FALSE;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetPrimaryLanguage(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ OUT EFI_STRING *LanguageString)
+{
+ HII_HANDLE *phnd;
+ HII_LANG *lang;
+ UINTN hi;
+ UINT16 *ls,*bp;
+//----------------------
+ if(!This || !LanguageString) return EFI_INVALID_PARAMETER;
+
+ phnd=LocateHandle(Handle,&hi);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+ if(!phnd->HasStr){
+ phnd=LocateStrHandleGuid(hi,&hi);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+ }
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//???????????????????????????????????????
+ //if for some reson Somebody submit just IFR vith no Strings
+ //there are no way to determine language so I just put there 0 -Any Language
+ //but Intel's code expect me to return something like "eng"
+ //so I will return Default System Lang.
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ ls=Malloc(sizeof(UINT16)*3*(phnd->SecLang.ItemCount+1)+1); //4 characters
+ if(!ls) return EFI_OUT_OF_RESOURCES;
+
+ bp=ls;
+ lang=gHiiDb.LangDb.Items[phnd->PriLang];
+ pBS->CopyMem(ls,&lang->sName,sizeof(UINT16)*3);
+ bp+=3;
+
+ for(hi=0;hi<phnd->SecLang.ItemCount; hi++){
+ lang=gHiiDb.LangDb.Items[(UINTN)phnd->SecLang.Items[hi]];
+ pBS->CopyMem(bp,&lang->sName,sizeof(UINT16)*3);
+ bp+=3;
+ }
+ *bp=0;
+ *LanguageString=ls;
+
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+//
+EFI_STATUS HiiGetSecondaryLanguages(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CHAR16 *PrimaryLanguage,
+ OUT EFI_STRING *LanguageString)
+{
+ UINTN id,i;
+ HII_HANDLE *phnd;
+ HII_LANG *lang;
+ UINT16 *ls;
+//----------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ phnd=LocateHandle(Handle,NULL);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+
+ //Some how caller managed to scrue up with parameters.
+ lang=LocateLang(PrimaryLanguage,&id);//Lang provided does not mutch with what we've recorded
+ if( !lang || phnd->PriLang!=id ) return EFI_INVALID_PARAMETER;
+
+ if(phnd->SecLang.ItemCount>0){
+ UINT16 *l;
+ //----------------
+ ls=Malloc(sizeof(UINT16)*3*phnd->SecLang.ItemCount+1);
+ if(!ls) return EFI_OUT_OF_RESOURCES;
+ l=ls;
+ for(i=0; i<phnd->SecLang.ItemCount; i++){
+ //we are not returning Any Language str " "
+ //And Any Lang String has index 0 upon initialization
+ if((UINTN)(phnd->SecLang.Items[i])){
+ lang=(HII_LANG*)gHiiDb.LangDb.Items[(UINTN)(phnd->SecLang.Items[i])];
+ pBS->CopyMem(l,&lang->sName[0],sizeof(UINT16)*3);//4 unicode chars;
+ l+=3;
+ }
+ }//resulting string will be consist of N*3xUINT16+TERMINATOR
+ *l=0x0000; //put terminator at the end of set of sec lang
+ *LanguageString=ls;
+ }else { *LanguageString=NULL; return EFI_NOT_FOUND;}
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+//This is a worker function to avoid dubliceted code in HiiGetString,
+//HiiGetLine and ExtHiiGetStrInfo
+HII_STR *GetHiiString(EFI_HII_HANDLE Handle, UINT16 *Lang, STRING_REF Token){
+ UINTN li,hi;
+ UINT16 dl[4]={0x20,0x20,0x20,0}, *pdl;
+ HII_HANDLE *phnd;
+ HII_STR *str;
+//------------------------------
+ phnd=LocateHandle(Handle,&hi);
+ if(!phnd) return NULL;
+
+ if(!phnd->HasStr){
+ phnd=LocateStrHandleGuid(hi,&hi);
+ if(!phnd) return NULL;
+ }
+
+ if(!Lang){
+ pdl=&dl[0];
+ if(EFI_ERROR(GetDefaultLang(pdl)))pdl=(UINT16*)gHiiDb.LangDb.Items[phnd->PriLang];
+ } else pdl=Lang;
+
+ //dl has a language string it " " or "xxx"
+ //lang=LocateLang(pdl,&li);
+ if(!LocateLang(pdl,&li)) return NULL;
+ str=LocateString(phnd,li,Token);
+
+ // If String is not found and language is not specified,
+ // let's try with the primary package language.
+ if (!str && !Lang) str=LocateString(phnd,0,Token);
+
+ return str;
+}
+
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetStringNew(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN BOOLEAN Raw,
+ IN CHAR16 *LanguageString,
+ IN OUT UINTN *BufferLength, //in units of UINT16
+ OUT EFI_STRING StringBuffer)
+{
+ HII_STR *str;
+ UINTN j,i;
+ UINT16 *ps, sl;
+//--------------------------
+
+ if( !This || !BufferLength || *BufferLength && !StringBuffer ) return EFI_INVALID_PARAMETER;
+
+ str=GetHiiString(Handle,LanguageString,Token);
+ if(!str) return EFI_INVALID_PARAMETER;
+
+ if(str->NewStr.StrPtr){
+ ps=str->NewStr.StrPtr;
+ sl=str->NewStr.StrLen;
+ } else {
+ ps=str->String.StrPtr;
+ sl=str->String.StrLen;
+ }
+ //str->StrLen in UINT16 units
+ if(*BufferLength<sl*sizeof(UINT16)) {
+ *BufferLength=sl*sizeof(UINT16);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if(Raw){
+ pBS->CopyMem(&StringBuffer[0],ps,sl*sizeof(UINT16));
+ *BufferLength=sl*sizeof(UINT16);
+ } else {
+ for(i=0,j=0;i<(UINTN)(sl-1);i++){
+ //replace <CR> with <Space>
+ //if(ps[i]==0x0013)
+ // StringBuffer[j]=0x0020;
+ //else {
+ //skip all Special and Control Characters.
+ if((ps[i]>=0xFFF0 && ps[i]<=0xFFFF))
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//It is amazing how Intel's engineers not in compliance with
+//their own Specs.
+//"If (Raw) TRUE, the string is returned unedited in the internal storage format described
+//above. If FALSE, the string returned is edited by replacing !!<cr>!! with <space> and by
+//removing special characters such as the ??<wide>?? prefix."
+// ||(ps[i]>=0x0000 && ps[i]<=0x001F))
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ continue;
+ //Copy the rest of chars
+ else StringBuffer[j]=ps[i];
+ //}
+ j++;
+ }
+ StringBuffer[j]=0;//Terminate String!!
+ *BufferLength=(UINT16)((j+1)*sizeof(UINT16));
+ }
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetStringOld(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN BOOLEAN Raw,
+ IN CHAR16 *LanguageString,
+ IN OUT UINT16 *BufferLength, //in units of UINT16
+ OUT EFI_STRING StringBuffer)
+{
+ EFI_STATUS Status;
+ UINTN bl;
+//-----------------
+ if(BufferLength==NULL) return EFI_INVALID_PARAMETER;
+
+ bl=(UINTN)(*BufferLength);
+ Status=HiiGetStringNew(This,Handle,Token,Raw,LanguageString,&bl,StringBuffer);
+ (*BufferLength)=(UINT16)bl;
+
+ if((Status==EFI_BUFFER_TOO_SMALL) && (bl > 0xFFFF)) Status=EFI_INVALID_PARAMETER;
+
+ return Status;
+}
+
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetLine(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN OUT UINT16 *Index,
+ IN UINT16 LineWidth,
+ IN CHAR16 *LanguageString,
+ IN OUT UINT16 *BufferLength,
+ OUT EFI_STRING StringBuffer)
+{
+ HII_STR *str;
+ UINTN j,i;
+ UINT16 *ps, sl;
+ BOOLEAN cr=FALSE;
+//--------------------------
+
+ if( !This || !BufferLength || !StringBuffer ) return EFI_INVALID_PARAMETER;
+
+ str=GetHiiString(Handle,LanguageString,Token);
+ if(!str) return EFI_INVALID_PARAMETER;
+
+ if(str->NewStr.StrPtr){
+ ps=str->NewStr.StrPtr;
+ sl=str->NewStr.StrLen;
+ } else {
+ ps=str->String.StrPtr;
+ sl=str->String.StrLen;
+ }
+
+ //I don't know should I remove a special chars or not
+ // So I will for now
+ for(j=0,i=*Index; (i<sl || i<LineWidth); i++ ){
+ //replace <CR> with <Space>
+ if(ps[i]==0x0013){
+ if(cr) { //if <CR> hit second time in a row - terminate string
+ StringBuffer[j]=0x0000;
+ *Index=(UINT16)i;
+ break;
+ } else { //else replece it with space an set "cr" flag
+ StringBuffer[j]=0x0020;
+ cr=TRUE;
+ }
+ }else{
+ cr=FALSE; //if we here - reset "cr" flarg
+ //skip all Special and Control Characters.
+ if((ps[i]>=0xFFF0 && ps[i]<=0xFFFF)||(ps[i]<=0x001F))
+ continue; //will not increase "j" the buffer index
+ //Copy the rest of chars into the Buffer
+ else
+ StringBuffer[j]=ps[i];
+ }
+ j++;
+ }
+ StringBuffer[j]=0;//Terminate String!!
+ *BufferLength=(UINT16)((j+1)*sizeof(UINT16));
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiResetStrings(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle)
+{
+ HII_STR *str;
+ UINTN i,hi;//,j,gbi[10],gc=0;
+ HII_HANDLE *phnd;
+//------------------------
+
+ if(!This) return EFI_INVALID_PARAMETER;
+ phnd=LocateHandle(Handle,&hi);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+
+ if(!phnd->HasStr){
+ phnd=LocateStrHandleGuid(hi,&hi);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+ }
+ //LocateSameGuidHandle(hi, &gbi[0], &gc);
+
+ //for(j=0; j<=gc; j++){
+ for(i=0; i<gHiiDb.StringDb.RecordCount;i++){
+ //if(!phnd->HasStr) break;
+ DbeGoToIndex(&gHiiDb.StringDb,STR_KEY,i,&str);
+ if(str->Handle==phnd->Handle){
+ if(str->NewStr.StrPtr){
+ pBS->FreePool(str->NewStr.StrPtr);
+ str->NewStr.StrPtr=NULL;
+ str->NewStr.StrLen=0;
+ str->NewStr.ScrLen=0;
+ //Cleanup Dtabase from RECORDS which was addes
+ //after initial Package
+ if(!str->String.StrPtr){
+ DbeDelete(&gHiiDb.StringDb, str, TRUE);
+ i--;//we ned to step on the same data index
+ continue;
+ //since we have delited current one
+ //phnd->NextStrToken--;
+ }
+
+ }
+ }
+ if(str->Handle>phnd->Handle) break;
+ }
+ phnd->NextStrToken=phnd->StrCount;
+
+ // if(j<gc)phnd=gHiiDb.HandleDb.Items[gbi[j]];
+ //}
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS NewStringPack(IN EFI_HII_STRING_PACK *Package,
+ UINTN HandleId)
+{
+ UINTN i,lid;
+ UINT8 *ofs;
+ UINT16 *str;
+ RELOFST *ps;//string pointer
+ EFI_HII_STRING_PACK *cp=Package;
+ EFI_STATUS Status=0;
+ BOOLEAN f=TRUE;
+ HII_HANDLE *phnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[HandleId];
+//--------------------------------
+ while(!IsLastStrPack(cp)){
+ ps=(RELOFST*)(cp+1);
+ ofs=(UINT8*)cp;
+ //Check if Language exists already
+ Status=GetLanguageFromPack(cp,&lid);
+ if(EFI_ERROR(Status)) return Status;
+ if(f){//if this is first string pack make this lang Primary
+ phnd->PriLang=(UINT32)lid;
+ f=FALSE;
+ } else {
+ //All other languages if any will be Secondary languages
+ Status=LocateSecLangAdd(phnd,&lid,TRUE);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ for(i=0; i<Package->NumStringPointers; i++){
+ phnd->NextStrToken=(STRING_REF)i;
+ if(!ps[i]) continue;
+ str=(UINT16*)(ofs+ps[i]);
+ Status=AddString(lid,phnd,str,TRUE,NULL);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+
+ cp=(EFI_HII_STRING_PACK*)((UINT8*)cp+cp->Header.Length);
+ }
+ phnd->StrCount=(STRING_REF)Package->NumStringPointers;
+ phnd->HasStr=TRUE;
+ return Status;
+}
+
+
+///////////////////////////////////////////////////////////////////
+// IFR Releated Functions
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+//this one will calculate length in bytes for the buffer designed
+//to receive a copy of form instance
+//UINT16 GetFormLen(HII_FORM *Form){
+// HII_LABEL *lbl;
+// UINTN i;
+// UINT16 len=Form->BufferLength;
+//------------------------
+// for(i=0; i<Form->Labels.ItemCount; i++){
+// lbl=Form->Labels.Items[i];
+// if(lbl->Erased) len-=lbl->OrgDataLength;
+// len+=lbl->UpdDataLength;
+// }
+// return len;
+//}
+
+///////////////////////////////////////////////////////////////////
+//this one will calculate length in bytes for the buffer designed
+//to receive a copy of FormSet instance
+//UINT16 GetFormSetLen(HII_FORMSET *FormSet){
+// UINT16 len=0;
+// UINTN i;
+// HII_FORM *frm;
+//------------------
+// for(i=0; i<FormSet->Forms.ItemCount; i++){
+// frm=FormSet->Forms.Items[i];
+// len+=GetFormLen(frm);
+// }
+// return len+FormSet->FormSetData->Header.Length+FormSet->EndFormSet->Header.Length;
+//}
+
+UINTN GetDataLen( UINT8 *OpCode, UINTN *Count, BOOLEAN Remove){
+ UINTN i;
+ UINTN len=0;
+ UINT8 *p=OpCode;
+//------------------------
+ for(i=0; i<*Count; i++){
+// if( !Remove &&
+// ( (*p)==EFI_IFR_END_FORM_OP || (*p)==EFI_IFR_LABEL_OP )
+// ){
+// i=i;
+// }
+ if( ( Remove && ( (*p)==EFI_IFR_END_FORM_OP || (*p)==EFI_IFR_LABEL_OP )
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ //when adding data I expect that caller knows what he is doing and
+ //passes me correct Data Count. Guess what? This is not TRUE in Intel's Setup.
+ //Intel uses Zeroed buffer to fill with desired Opcodes, set Data count to 0xFF and here we go.
+ //In this case if in buffer we will found junk which satisfy conditions below
+ //we can seriousely scrue up!!!!!
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ || ((*p)==0 || (*p)>EFI_IFR_VARSTORE_SELECT_PAIR_OP ))){
+ *Count=i;
+ break;
+ }
+ len = len + ((EFI_IFR_OP_HEADER*)p)->Length;
+ p=OpCode+len;
+ }
+ return len;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//this will copy form from HII DB private storage to decignated Buffer
+VOID CopyForm(UINT8* Buffer, HII_FORM *Form, UINTN *BytesCnt){
+ UINTN i,cnt=0;
+ HII_LABEL *lbl=NULL;
+ UINT8 *bp=Buffer;
+//----------------
+
+ //Now First Label has data starting from opcode next to FORM_OP
+ //and lbl->Label of very first label in the list actualy FORM_OP
+ //so don't need following code
+
+ //if(Form->Labels.ItemCount)lbl=(HII_LABEL*)Form->Labels.Items[0];
+ //1. copy form till first label (including LABEL OPCODE)
+ //if(lbl)//Total Bufferlength including EOF opcode
+ // cnt=(UINT8*)(lbl->Label)-(UINT8*)Form->FormData;
+ //else
+ // cnt=Form->BufferLength-Form->EndForm->Header.Length;
+
+ //pBS->CopyMem(bp,Form->FormData,For);
+ //bp+=cnt; //Advance buffer pointer;
+ //(*BytesCnt)=cnt;
+ (*BytesCnt)=0;
+ //Keep circling trough Labels copying corresponded data
+ for(i=0;i<Form->Labels.ItemCount;i++){
+ lbl=(HII_LABEL*)Form->Labels.Items[i];
+ //copy Label OpCode
+ pBS->CopyMem(bp,lbl->Label,lbl->Label->Header.Length);
+ bp+=lbl->Label->Header.Length;
+ (*BytesCnt)+=lbl->Label->Header.Length;
+
+ //if Label was updated copy Update data first...
+ if(lbl->LabelData){
+ pBS->CopyMem(bp,lbl->LabelData,lbl->DataLength);
+ bp+=lbl->DataLength;
+ (*BytesCnt)+=lbl->DataLength;
+ }
+ }
+ //Copy EOF opcode
+ cnt=Form->EndForm->Header.Length;
+ pBS->CopyMem(bp,Form->EndForm,cnt);
+ (*BytesCnt)+=cnt;
+ return;
+}
+
+///////////////////////////////////////////////////////////////////
+//will copy entire formset data excluding Pcakage Header
+VOID CopyFormSet(UINT8* Buffer, HII_FORMSET *FormSet, UINTN *BytesCnt){
+ UINTN i;
+ UINT8 *bp=Buffer,*pp;
+ UINTN cnt;
+ HII_FORM *frm;
+//----------------
+ bp=Buffer;
+ //Copy Formset OpCode...
+ pBS->CopyMem(bp,FormSet->FormSetData,FormSet->FormSetData->Header.Length);
+ bp+=FormSet->FormSetData->Header.Length;
+ *BytesCnt=FormSet->FormSetData->Header.Length;
+ //Copy any information that we might have from end of FormSet Opcode
+ //to the befinning of FOrm OpCode VARSTORE for example.
+ if(FormSet->Forms.ItemCount){
+ pp=(UINT8*)FormSet->FormSetData+FormSet->FormSetData->Header.Length;
+ frm=FormSet->Forms.Items[0];
+ cnt=(UINTN)((UINT8*)frm->FormData-pp);
+ pBS->CopyMem(bp,pp,cnt);
+ bp+=cnt;
+ *BytesCnt+=cnt;
+ }
+
+ for(i=0; i<FormSet->Forms.ItemCount; i++){
+ frm=FormSet->Forms.Items[i];
+ CopyForm(bp,frm,&cnt);
+ bp+=cnt;
+ *BytesCnt+=cnt;
+ }
+ //copy END_OF_FORM_SET OP here
+ cnt=FormSet->EndFormSet->Header.Length;
+ pBS->CopyMem(bp,&FormSet->EndFormSet->Header.OpCode,cnt);
+ *BytesCnt+=cnt;
+ return;
+}
+
+
+
+///////////////////////////////////////////////////////////////////
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// Cache Form and Formset
+HII_FORM *LocateForm(HII_FORMSET *FormSet, EFI_FORM_ID FormId){
+ EFI_STATUS Status=0;
+ UINTN fid;
+//----------------------------------------------
+ Status=LocateItem(&FormSet->Forms,&FormId,sizeof(EFI_FORM_ID),&fid);
+ if(EFI_ERROR(Status)) return NULL;
+
+ return (HII_FORM*)FormSet->Forms.Items[fid];
+}
+
+///////////////////////////////////////////////////////////////////
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// Cache Form and Formset
+HII_FORMSET *LocateFormSet(UINTN HandleIdx, UINTN* FormSetIdx){
+ EFI_STATUS Status=0;
+ UINTN fsid;
+//--------------------------
+ Status=LocateItem(&gHiiDb.IfrDb,&((UINT32)HandleIdx),sizeof(UINT32),&fsid);
+ if(EFI_ERROR(Status)) return NULL;
+ if(FormSetIdx!=NULL)*FormSetIdx=fsid;
+ return (HII_FORMSET*)gHiiDb.IfrDb.Items[fsid];
+}
+
+
+HII_LABEL *LocateFormLabel(HII_FORM *Form, EFI_FORM_LABEL LabelId, UINTN *LabelIdx){
+ EFI_STATUS Status=0;
+ UINTN lid;
+//----------------------------------------------
+ Status=LocateItem(&Form->Labels,&LabelId, sizeof(EFI_FORM_LABEL),&lid);
+ if(EFI_ERROR(Status)) return NULL;
+
+ *LabelIdx=lid;
+ return (HII_LABEL*)Form->Labels.Items[lid];
+}
+
+HII_LABEL *LocateFormSetLabel(HII_FORMSET *FormSet, EFI_FORM_LABEL LabelId, UINTN *LabelIdx){
+ EFI_STATUS Status=0;
+ UINTN lid;
+//----------------------------------------------
+ Status=LocateItem(&FormSet->Labels,&LabelId, sizeof(EFI_FORM_LABEL),&lid);
+ if(EFI_ERROR(Status)) return NULL;
+
+ if(LabelIdx)*LabelIdx=lid;
+ return (HII_LABEL*)FormSet->Labels.Items[lid];
+}
+
+
+///////////////////////////////////////////////////////////////////
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//This MUST be here to make Shell working
+static UINT8 gDummyVfr[] = {
+ //Header
+ 0x2c, 0x00, 0x00, 0x00, //Actual Length of Data Buffer
+ 0x03, 0x00, //Type;
+ // start of IFR data
+ /*O*/ 0x0E, //Opcode=EFI_IFR_FORM_SET_OP
+ /*L*/ 0x24, //Length
+ //Offset=8
+ /*G*/ 0xBC, 0x30, 0x0C, 0x9E, 0x06, 0x3F, 0xA6, 0x4B, 0x82, 0x88, 0x09, 0x17, 0x9B, 0x85, 0x5D, 0xBE, //GUID
+ /*S*/ 0x02, 0x00, //FormSet Title
+ /*S*/ 0x00, 0x00, //Help
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,//Callback
+ 0x00, 0x00, //Class
+ 0x00, 0x00, //SubClass
+ 0x00, 0x00, //NvDataSize
+ /*O*/ 0x0D, //OpCOde=EFI_IFR_END_FORM_SET_OP
+ /*L*/ 0x02,
+};
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+///////////////////////////////////////////////////////////////////
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetFormsNew(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormId,
+ IN OUT UINTN *BufferLength,
+ OUT UINT8 *Buffer)
+{
+ UINTN hid;
+ HII_FORMSET *fs;
+ HII_FORM *frm;
+ HII_HANDLE *phnd;
+ UINTN len;
+//--------------------------------------
+ if(This==NULL && BufferLength==NULL) return EFI_INVALID_PARAMETER;
+ //phnd=LocateHandle(Handle, &hid);
+ //TODO: Felix: by the HII Spec. we should return EFI_INVALID_PARAMETER
+ //However, Intel Device Manager expects EFI_NOT_FOUND
+ //(it hangs if it is something else)
+ phnd=LocateHandle(Handle, &hid);
+ if(!phnd) return EFI_NOT_FOUND;
+
+ fs=LocateFormSet(hid, NULL);
+ if(!fs){
+ if(!FormId){
+ //Technically I must Return NOT_FOUND ERROR but...
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this patch was made to keep Shell working. Shell and HII coexistance is
+//based on assumption that "It must be some IFR pack associated with String pack"
+//If this statement FALSE Shell will hang in INFINITE LOOP!!!!
+////////////////////////////////////////////////////////////////////////
+//this comments I took from Intel's HII Database Driver
+// "If someone is passing in a string only, create a dummy IfrPack with a Guid
+// to enable future searching of this data."
+////////////////////////////////////////////////////////////////////////
+ if(*BufferLength< sizeof(gDummyVfr)) {
+ *BufferLength=sizeof(gDummyVfr);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *BufferLength=sizeof(gDummyVfr);
+ pBS->CopyMem(Buffer,&gDummyVfr[0],sizeof(gDummyVfr));
+ //copy handle guid here Shell expect it to mutch with some standart guids
+ pBS->CopyMem((VOID*)(Buffer+8),(VOID*)&(phnd->Guid),sizeof(EFI_GUID));
+ return EFI_SUCCESS;
+ } else return EFI_NOT_FOUND;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ }
+
+ if(!FormId){//we must return whole FormSet
+ //STUPID SHELL expect me to return formset with EFI_HII_PACK_HEADER
+ // why? I don't know!
+ len=fs->BufferLength+sizeof(EFI_HII_PACK_HEADER);
+ } else {
+ frm=LocateForm(fs,FormId);
+ if(!frm) return EFI_NOT_FOUND;
+ len=frm->BufferLength;
+ }
+
+ if(*BufferLength<len){
+ *BufferLength=len;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *BufferLength=len;
+
+ //If "FormId" we must return whole FormSet
+ if(!FormId){
+ //STUPID SHELL expect me to return formset with EFI_HII_PACK_HEADER
+ //Create it
+ *((UINT32*)Buffer)=(UINT32)len;
+ *((UINT16*)(Buffer+4))=3;//IFR Type
+ CopyFormSet(Buffer+6,fs,&hid);
+ }
+ else
+ CopyForm(Buffer,frm,&hid);
+
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiGetFormsOld(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormId,
+ IN OUT UINT16 *BufferLength,
+ OUT UINT8 *Buffer)
+{
+ EFI_STATUS Status=0;
+ UINTN bl;
+//--------------------------------
+ if(BufferLength==NULL) return EFI_INVALID_PARAMETER;
+
+ bl=(UINTN)(*BufferLength);
+ Status=HiiGetFormsNew(This,Handle,FormId,&bl,Buffer);
+ (*BufferLength)=(UINT16)bl;
+
+ if((Status==EFI_BUFFER_TOO_SMALL) && (bl > 0xFFFF)) Status=EFI_INVALID_PARAMETER;
+ return Status;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//Will free all memory blocks associated with Label->Objects structures
+VOID DeleteLabelObjects(HII_LABEL *Label){
+ UINTN i;
+ HII_OBJECT *obj;
+//------------------
+ for(i=0;i<Label->Objects.ItemCount; i++){
+ obj=Label->Objects.Items[i];
+ ClearItemLst(&obj->Conditions,FALSE);
+ ClearItemLst(&obj->Options,FALSE);
+ }
+ ClearItemLst(&Label->Objects,TRUE);
+}
+
+
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiUpdateForm(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_LABEL Label,
+ IN BOOLEAN AddData,
+ IN EFI_HII_UPDATE_DATA *Data)
+{
+ EFI_STATUS Status=0;
+ UINTN hid,lid;
+ HII_FORMSET *fs;
+ HII_FORM *frm;
+ HII_LABEL *lbl;
+ UINTN len,cnt;
+ UINT8 *ub;
+ EFI_IFR_OP_HEADER *op;
+//-------------------------
+ if(!This || !Data ) return EFI_INVALID_PARAMETER;
+
+ if(!LocateHandle(Handle, &hid)) return EFI_INVALID_PARAMETER;
+
+ //Find Formset
+ fs=LocateFormSet(hid, NULL);
+ if(!fs) return EFI_INVALID_PARAMETER;
+
+ //Find Label
+ //FormUpdate= TRUE means just change Form Title!!!
+ if(Data->FormUpdate){
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//In Intel's HII implementation Data->FormValue field is missing
+ //Find Form using UPDATE Data
+// frm=LocateForm(fs,Data->FormValue);
+// if(!frm) return EFI_NOT_FOUND;
+ //Update Form Title
+// frm->FormData->FormTitle=Data->FormTitle;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ }
+
+ //
+ if(Data->DataCount){
+ //Find Label
+ lbl=LocateFormSetLabel(fs, Label, &lid);
+ if(!lbl) return EFI_NOT_FOUND;
+ frm=lbl->OwnerForm;
+ cnt=Data->DataCount;
+ if(AddData){
+ op=(EFI_IFR_OP_HEADER*)&Data->Data;
+ if(!op->OpCode || !op->Length) return EFI_INVALID_PARAMETER;
+ //Calculate size of UPDATE data
+ len=GetDataLen((UINT8*)op,&cnt,FALSE);
+ ub=Malloc(len+lbl->DataLength);
+ if(!ub) return EFI_OUT_OF_RESOURCES;
+
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ //Copy Update Data in Private Buffer
+ pBS->CopyMem(ub,op,len);
+ //Copy Old Data in same Private Buffer
+ if(lbl->LabelData)pBS->CopyMem((VOID*)(ub+len),lbl->LabelData,lbl->DataLength);
+//for coimpatibility with Intel's setup I've change order in which the chanks of opcodes
+// been copied in a new label buffer - New data will be added after the old data
+ //if(lbl->LabelData)pBS->CopyMem(ub,lbl->LabelData,lbl->DataLength);
+ //pBS->CopyMem((VOID*)(ub+lbl->DataLength),op,len);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+
+ //Update Buffer parameters in every structure affected by update
+ lbl->DataLength = lbl->DataLength + len;
+ lbl->DataCount = lbl->DataCount + Data->DataCount;
+ if(lbl->Updated && lbl->LabelData)pBS->FreePool(lbl->LabelData);
+ lbl->LabelData=(EFI_IFR_OP_HEADER*)ub;
+ fs->BufferLength = fs->BufferLength + len;
+ frm->BufferLength = frm->BufferLength + len;
+ //Delete Old Data
+ DeleteLabelObjects(lbl);
+ }else{
+ //we will not erase an empty Label!
+ if(lbl->LabelData){
+ op=lbl->LabelData;
+ if(Data->DataCount>=lbl->DataCount){
+ cnt=lbl->DataCount;
+ len=lbl->DataLength;
+ } else len=GetDataLen((UINT8*)op,&cnt,TRUE);
+
+ //if after erasing no data has left, no need to allocate new buffer
+ if((INTN)(lbl->DataLength-len)>0){
+ ub=Malloc(lbl->DataLength-len);
+ if(!ub)
+ return EFI_OUT_OF_RESOURCES;
+ //Copy rest of Old Data in Private Buffer
+ pBS->CopyMem(ub,(UINT8*)lbl->LabelData+len,lbl->DataLength-len);
+ } else ub=NULL;
+
+ //Update Buffer parameters in every structure affected by update
+ lbl->DataLength = lbl->DataLength - len;
+ lbl->DataCount = lbl->DataCount - cnt;
+ if(lbl->Updated && lbl->LabelData)pBS->FreePool(lbl->LabelData);
+ lbl->LabelData=(EFI_IFR_OP_HEADER*)ub;
+ fs->BufferLength = fs->BufferLength - len;
+ frm->BufferLength = frm->BufferLength - len;
+ DeleteLabelObjects(lbl);
+ }
+ }
+ //Populate pointers on Label Objects from Label Dtat Buffer
+ if(lbl->LabelData!=NULL)Status=CreateLabelObjects(lbl);
+ if(EFI_ERROR(Status))return Status;
+ lbl->Updated=TRUE;
+
+ if(lbl->UpdateCallBack) lbl->UpdateCallBack(Label, Handle,AddData);
+ }
+
+ if(Data->FormSetUpdate){
+ fs->FormSetData->CallbackHandle=Data->FormCallbackHandle;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS InitDefStorage(HII_FORMSET *FormSet){
+ EFI_STATUS Status;
+ HII_STORE *st;
+ static CHAR8 *ss="Setup";//{'S','e','t','u','p',0};
+ CHAR8 *pn;//pointer to var name;
+//------------------------------------------------
+ st=MallocZ(sizeof(HII_STORE));
+ if(!st)return EFI_OUT_OF_RESOURCES;
+
+ Status=AppendItemLst(&FormSet->Storages,st);
+
+ st->VarStore=MallocZ(sizeof(EFI_IFR_VARSTORE)+6);
+ if(!st->VarStore)return EFI_OUT_OF_RESOURCES;
+
+ //Init Default VarStore Structure VarId is Always 0x0000
+ st->VarStore->Header.Length=sizeof(EFI_IFR_VARSTORE)+6;
+ st->VarStore->Header.OpCode=EFI_IFR_VARSTORE_OP;
+ st->VarStore->Size=FormSet->FormSetData->NvDataSize;
+
+ //Copy formset GUID here
+ pBS->CopyMem(&st->VarStore->Guid,&FormSet->FormSetData->Guid,sizeof(EFI_GUID));
+
+ pn=(CHAR8*)st->VarStore;
+ pn+=sizeof(EFI_IFR_VARSTORE);
+ pBS->CopyMem(pn,ss,6);
+
+ return EFI_SUCCESS;
+}
+
+//Selects Var Store Object
+HII_STORE *LocateStorage(HII_FORMSET *FormSet, UINT16 VarId, UINTN *StoreId OPTIONAL){
+ UINTN i;
+ HII_STORE *st;
+//---------------------
+ for(i=0; i<FormSet->Storages.ItemCount; i++){
+ st=(HII_STORE*)FormSet->Storages.Items[i];
+ if(st->VarStore->VarId==VarId) {
+ if(StoreId)*StoreId=i;
+ return st;
+ }
+ }
+ return NULL;
+}
+
+
+EFI_STATUS CreateLabelObjects(HII_LABEL *Label)
+{
+ EFI_IFR_OP_HEADER *op;
+ UINTN i,j=0, k;
+ HII_OBJECT *obj=NULL;
+ HII_STORE *st1=NULL, *st2=NULL;
+ static T_ITEM_LIST clst={0,0,NULL},olst={0,0,NULL}; //temp conditions and objects list list
+ static T_ITEM_LIST supprstores = {0, 0, NULL};
+ EFI_STATUS Status;
+ BOOLEAN cf=FALSE; //conditions flag
+ BOOLEAN Suppress = FALSE;
+//-------------------------------------------
+ op=Label->LabelData;
+
+ obj=NULL;
+ //st1=(HII_STORE*)Label->OwnerForm->Owner->Storages.Items[0];
+ st1 = LocateStorage(Label->OwnerForm->Owner, CurrentVarId, NULL);
+ if(!st1) { st1=(HII_STORE*)Label->OwnerForm->Owner->Storages.Items[0]; CurrentVarId = 0; }
+ st2=NULL;
+ for(i=0;i<Label->DataCount;i++){
+ //Select Default Storage so Store1
+ switch(op->OpCode){
+ //Storage Select Opcodes
+ case EFI_IFR_VARSTORE_SELECT_OP:
+ {
+ EFI_IFR_VARSTORE_SELECT *vs=(EFI_IFR_VARSTORE_SELECT*)op;
+ HII_STORE *st=LocateStorage(Label->OwnerForm->Owner,vs->VarId,NULL);
+ // preserve the varstore selection - to be reset only by the next varstore select
+ // or a new formset
+ //------------------------
+ if(st) { st1=st; CurrentVarId = vs->VarId; }
+ }
+ break;
+ case EFI_IFR_VARSTORE_SELECT_PAIR_OP:
+ {
+ EFI_IFR_VARSTORE_SELECT_PAIR *v2=(EFI_IFR_VARSTORE_SELECT_PAIR*)op;
+ HII_STORE *s1=LocateStorage(Label->OwnerForm->Owner,v2->VarId,NULL);
+ HII_STORE *s2=LocateStorage(Label->OwnerForm->Owner,v2->SecondaryVarId,NULL);
+ //------------------------
+ if(s1) { st1=s1; CurrentVarId = v2->VarId; }
+ if(s2) st2=s2;
+ }
+ break;
+ //Condition OpCodes
+ case EFI_IFR_GRAYOUT_IF_OP:
+ case EFI_IFR_SUPPRESS_IF_OP:
+ case EFI_IFR_INCONSISTENT_IF_OP:
+ //if we found some logical expression and local ovject list(olst) has some objects
+ //we must add this objects with no conditions to the Label->Objects list
+ //and clear local object list to start fill it with objects who has conditions.
+ if(!cf){
+ for(j=0;j<olst.ItemCount;j++){
+ obj=olst.Items[j];
+ Status=AppendItemLst(&Label->Objects,obj);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ }
+ ClearItemLst(&olst,FALSE);
+ obj=NULL;
+ }
+ cf=TRUE;
+ if( op->OpCode == EFI_IFR_SUPPRESS_IF_OP) Suppress = TRUE;
+ else Suppress = FALSE;
+ ///////////////////////////////////////////////////////////////////////
+ //Do not add break instruction here it is not present for a reason!!!!
+ ///////////////////////////////////////////////////////////////////////
+ case EFI_IFR_AND_OP:
+ case EFI_IFR_OR_OP:
+ case EFI_IFR_NOT_OP:
+ case EFI_IFR_EQ_ID_VAL_OP:
+ case EFI_IFR_EQ_ID_ID_OP:
+ case EFI_IFR_EQ_ID_LIST_OP:
+ case EFI_IFR_EQ_VAR_VAL_OP:
+ //Add Opcode to the temp Condition list;
+ Status=AppendItemLst(&clst,op);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;//out of resources
+
+ if(op->OpCode == EFI_IFR_EQ_ID_VAL_OP && Suppress)
+ {
+ Status = AppendItemLst(&supprstores, st1);
+ ASSERT(!EFI_ERROR(Status));
+ }
+ break;
+ //end of conditions OpCode
+ case EFI_IFR_END_IF_OP:
+ //this is definetely end of object presentation,
+ //but some times it might be no object to add conditions info to
+ if(!olst.ItemCount){
+ for(j=0; j<clst.ItemCount;j++) {
+ Status=AppendItemLst(&Label->Conditions,clst.Items[j]);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }
+ for(j=0;j<olst.ItemCount;j++){
+ obj=olst.Items[j];
+ //I'm trying to allocate exactly as mutch memory as I need for Conditions.Items[] array.
+ //If you initialize ItemList.InitialCount with some specific value>0, then next call to
+ //Append ItemLst function will allocate this number of entries for ItemList.Items[] Array.
+ obj->Conditions.InitialCount=clst.ItemCount;
+ Status=AppendItemLst(&obj->Conditions,clst.Items[0]);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ pBS->CopyMem(&obj->Conditions.Items[1],&clst.Items[1],sizeof(VOID*)*(clst.ItemCount-1));
+ obj->Conditions.ItemCount=clst.ItemCount;
+ for(k = 0; k < supprstores.ItemCount; k++)
+ {
+ Status=AppendItemLst(&obj->SuppressStores,supprstores.Items[k]);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ Status=AppendItemLst(&Label->Objects,obj);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ }
+ ClearItemLst(&clst,FALSE); //don't need to free data - it's VFR pointers!
+ ClearItemLst(&olst,FALSE);
+ ClearItemLst(&supprstores,FALSE);
+ obj=NULL;
+ cf=FALSE;
+ Suppress = FALSE;
+ break;
+ //visual opcodes
+ case EFI_IFR_SUBTITLE_OP:
+ case EFI_IFR_TEXT_OP:
+ case EFI_IFR_INVENTORY_OP:
+ case EFI_IFR_GRAPHIC_OP:
+ case EFI_IFR_CHECKBOX_OP:
+ case EFI_IFR_NUMERIC_OP:
+ case EFI_IFR_PASSWORD_OP:
+ case EFI_IFR_REF_OP:
+ case EFI_IFR_DATE_OP:
+ case EFI_IFR_TIME_OP:
+ case EFI_IFR_STRING_OP:
+ case EFI_IFR_SAVE_DEFAULTS_OP:
+ case EFI_IFR_RESTORE_DEFAULTS_OP:
+ case EFI_IFR_HIDDEN_OP:
+ //continiouse
+ case EFI_IFR_ONE_OF_OP:
+ case EFI_IFR_ORDERED_LIST_OP:
+ ASSERT(!obj); //obj pointer must be cleared when we enter there
+ if(obj)return EFI_INVALID_PARAMETER;
+ obj=MallocZ(sizeof(HII_OBJECT));
+ ASSERT(obj);//Allocation Problems!
+ if(!obj) return EFI_OUT_OF_RESOURCES;
+ obj->ObjectCode=op;
+ obj->Store1=st1;
+ obj->Store2=st2;
+ Status=AppendItemLst(&olst,obj);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ //in case of DATE or Time opcode advance by 2 opcodes
+ if(op->OpCode==EFI_IFR_TIME_OP || op->OpCode==EFI_IFR_DATE_OP){
+ op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length);
+ op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length);
+ i+=2;
+ }
+ obj=NULL;
+ break;
+ case EFI_IFR_ONE_OF_OPTION_OP:
+ ASSERT(olst.ItemCount);
+ if(!olst.ItemCount) return EFI_INVALID_PARAMETER;
+ obj=(HII_OBJECT*)olst.Items[olst.ItemCount-1];
+ if(!obj) return EFI_INVALID_PARAMETER; //obj must be allocated!
+ Status=AppendItemLst(&obj->Options,op);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;//out of resources
+ break;
+ case EFI_IFR_END_ONE_OF_OP:
+ obj=NULL;
+ break;
+
+ }//end switch;
+ //Advance to next opcode
+ op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length);
+ }
+ //If there were no any Condition Opcodes contents of the ObjectList(olst) was not copied to the Label.Objects
+ for(j=0;j<olst.ItemCount;j++){
+ obj=olst.Items[j];
+ Status=AppendItemLst(&Label->Objects,obj);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status)) return Status;
+ }
+ ClearItemLst(&olst,FALSE);
+ return EFI_SUCCESS;
+}
+
+//This Routine is called to parse FormVfr and Create Objects which must be shown on the screen;
+EFI_STATUS CreateFormObjects(HII_FORM *Form){
+ UINTN i;
+ EFI_STATUS Status = EFI_SUCCESS;
+//---------------------------------
+
+ for(i=0; i<Form->Labels.ItemCount; i++){
+ Status=CreateLabelObjects((HII_LABEL*)Form->Labels.Items[i]);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status))return Status;
+ }
+ return Status;
+}
+
+EFI_STATUS NewKbdPack(EFI_HII_KEYBOARD_PACK *Package,
+ UINTN HandleId)
+{
+ EFI_STATUS Status;
+ HII_KB_LAYOUT_DATA *kbld;
+//--------------------
+ //Get Some Memory to accomodate Kb Layout Buffer
+ kbld=Malloc(sizeof(EFI_KEY_DESCRIPTOR)*Package->DescriptorCount+sizeof(HII_KB_LAYOUT_DATA));
+ ASSERT(kbld);
+ if(kbld==NULL) return EFI_OUT_OF_RESOURCES;
+
+ kbld->HandleIndex=HandleId; //just in case to find HII_HANDLE structure assotiated with this PACK
+ kbld->KeyDscCount=Package->DescriptorCount;
+ //We will store KB Layout Data right after the HII_KB_LAYOUT_DATA structure itself
+ kbld->KeyDsc=(EFI_KEY_DESCRIPTOR*)(kbld+1);
+ MemCpy((VOID*)kbld->KeyDsc, (VOID*)Package->Descriptor, sizeof(EFI_KEY_DESCRIPTOR)*kbld->KeyDscCount);
+
+ //Add saved KB Layout Data to the HII DB
+ Status=AppendItemLst((T_ITEM_LIST*)&gHiiDb.KeybdDb.KblInitCount,(VOID*)kbld);
+ ASSERT_EFI_ERROR(Status);
+
+ //Set recently submitted KB Layout as the current one
+ gHiiDb.KeybdDb.ActiveLayout=gHiiDb.KeybdDb.KblCount-1;
+
+ return Status;
+}
+
+EFI_STATUS NewIfrPack(EFI_HII_IFR_PACK *Package,
+ UINTN HandleId)
+{
+ EFI_STATUS Status;
+ EFI_IFR_OP_HEADER *op;
+// INT32 id=0;
+ HII_FORM *cf=NULL;
+ HII_FORMSET *cfs=NULL;
+ HII_LABEL *cl=NULL;
+ HII_STORE *st=NULL;
+ HII_HANDLE *phnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[HandleId];
+ UINT8 *p;
+ BOOLEAN la=FALSE;//label active flag - helps count OPCODES and Label.dLength
+//---------------------------------------------
+ //Copy Data to a new Storage =(EFI_IFR_OP_HEADER*)(Package+1);
+ p=Malloc(Package->Header.Length);
+ if(!p) return EFI_OUT_OF_RESOURCES;
+ pBS->CopyMem(p,Package,Package->Header.Length);
+
+ op=(EFI_IFR_OP_HEADER*)(p+sizeof(EFI_HII_PACK_HEADER));
+ //Parse IFR and crete Working set of data
+ //Every IFR Pack must start from FORM_SET_OP
+ while(/*(op->OpCode!=EFI_IFR_END_FORM_SET_OP)||*/((UINTN)op<((UINTN)p)+Package->Header.Length)){
+ switch (op->OpCode){
+ //Take care of Forms Sets
+ case EFI_IFR_FORM_SET_OP:
+ CurrentVarId = 0;
+ cfs=MallocZ(sizeof(HII_FORMSET));
+ if(!cfs) return EFI_OUT_OF_RESOURCES;
+ //cfs->BufferLength=0; it is 0
+ cfs->FormSetData=(EFI_IFR_FORM_SET*)op;
+ cfs->HandleId=(UINT32)HandleId;
+ cfs->Handle=phnd->Handle;
+ //Setup Initial Storage var
+ Status=InitDefStorage(cfs);
+ if(EFI_ERROR(Status)) return Status;
+ break;
+ case EFI_IFR_VARSTORE_OP:
+ if(!cfs) return EFI_INVALID_PARAMETER;
+ st=MallocZ(sizeof(HII_STORE));
+ if(!st) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&cfs->Storages,st);
+ st->VarStore=(EFI_IFR_VARSTORE*)op;
+ break;
+ case EFI_IFR_END_FORM_SET_OP:
+ if(!cfs)return EFI_INVALID_PARAMETER; //found EFI_IFR_END_FORM_SET_OP without EFI_IFR_FORM_SET_OP
+ //cfs->BufferLength=(UINT16)((UINT8*)op+op->Length-(UINT8*)cfs->FormSetData);
+ CurrentVarId = 0;
+ cfs->EndFormSet=(EFI_IFR_END_FORM_SET*)op;
+ cfs->HandleId=(UINT32)HandleId;
+ cfs->BufferLength = cfs->BufferLength + op->Length;
+ Status=AppendItemLst(&gHiiDb.IfrDb,(VOID*)cfs);
+ if(EFI_ERROR(Status)) return Status;
+ cfs=NULL;
+ break;
+ //Take care of Forms and Labels
+ case EFI_IFR_FORM_OP:
+ case EFI_IFR_LABEL_OP:
+ {
+ EFI_IFR_OP_HEADER *nxt;
+ //----------------------------
+ if(op->OpCode==EFI_IFR_FORM_OP){
+ //it must be some FORM_SET OpCode before we met FORM OpCode
+ if(!cfs) return EFI_INVALID_PARAMETER;
+ cf=MallocZ(sizeof(HII_FORM));
+ if(!cf) return EFI_OUT_OF_RESOURCES;
+ //cf->BufferLength=0;
+ cf->FormData=(EFI_IFR_FORM*)op;
+ cf->FormId=cf->FormData->FormId;
+ cf->Owner=cfs;
+ }
+ if(!cf && !cfs )return EFI_INVALID_PARAMETER; //Form mus be present
+ cl=MallocZ(sizeof(HII_LABEL));
+ if(!cl) return EFI_OUT_OF_RESOURCES;
+
+ cl->OwnerForm=cf;
+ cl->Label=(EFI_IFR_LABEL*)op;
+ //it must be a valid opcode next...
+ nxt=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length);
+ if(nxt->OpCode!=EFI_IFR_END_FORM_OP && nxt->OpCode!=EFI_IFR_LABEL_OP)cl->LabelData=nxt;
+
+ if(op->OpCode==EFI_IFR_FORM_OP){
+ cl->LabelId=0xFACE; //Fake LabelID
+ } else {
+ cl->LabelId=cl->Label->LabelId;
+ Status=AppendItemLst(&cfs->Labels,cl);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ Status=AppendItemLst(&cf->Labels,cl);
+ if(EFI_ERROR(Status)) return Status;
+
+ la=TRUE;
+ }
+ break;
+ case EFI_IFR_END_FORM_OP:
+ if(!cf)return EFI_INVALID_PARAMETER; //found EFI_IFR_END_FORM_OP without EFI_IFR_FORM_OP
+ //cf->BufferLength=(UINT16)((UINT8*)op+op->Length-(UINT8*)cf->FormData);
+ cf->EndForm=(EFI_IFR_END_FORM*)op;
+ cf->BufferLength = cf->BufferLength + op->Length;
+ Status=AppendItemLst(&cfs->Forms,cf);
+ if(EFI_ERROR(Status)) return Status;
+ Status=CreateFormObjects(cf);
+ cf=NULL;
+ la=FALSE;
+ break;
+ //Labels Has Left
+ /*case EFI_IFR_LABEL_OP:{
+ EFI_IFR_OP_HEADER *nxt;
+ //---------------------------
+ if(!cf && !cfs )return EFI_INVALID_PARAMETER; //Form mus be present
+ cl=MallocZ(sizeof(HII_LABEL));
+ if(!cl) return EFI_OUT_OF_RESOURCES;
+
+ cl->Label=(EFI_IFR_LABEL*)op;
+ cl->LabelId=cl->Label->LabelId;
+ cl->OwnerForm=cf;
+ nxt=(EFI_IFR_OP_HEADER*)(cl->Label+1);
+ //it must be a valid opcode next...
+ if(nxt->OpCode!=EFI_IFR_END_FORM_OP && nxt->OpCode!=EFI_IFR_LABEL_OP)cl->LabelData=nxt;
+
+ Status=AppendItemLst(&cf->Labels,cl);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=AppendItemLst(&cfs->Labels,cl);
+ if(EFI_ERROR(Status)) return Status;
+ la=TRUE;
+ break;
+ }
+ */
+ default :
+ if(la){
+ cl->DataCount++;
+ cl->DataLength = cl->DataLength + op->Length;
+ }
+ } //Switch
+ if(cfs)cfs->BufferLength = cfs->BufferLength + op->Length;
+ if(cf)cf->BufferLength = cf->BufferLength + op->Length;
+ op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length);
+ }
+ phnd->Ifr=p;
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+// Common Interface functions
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiNewPackNew(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACKAGES *Packages,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ UINTN i;
+ EFI_HII_PACK_HEADER *hdr, **hdrptr;
+ EFI_STATUS Status=0;
+ UINTN c=0,hid=0;
+ HII_HANDLE *phnd=NULL;
+ BOOLEAN sp=0,vp=0,hp=0;
+//-----------------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ hdrptr=(EFI_HII_PACK_HEADER**)(Packages+1);
+ for(i=0; i<Packages->NumberOfPackages; i++){
+ hdr=hdrptr[i];
+ switch(hdr->Type){
+ case EFI_HII_FONT:
+ Status=NewFontPack((EFI_HII_FONT_PACK*)hdr);
+ if(EFI_ERROR(Status)) return Status;
+ break;
+ case EFI_HII_STRING:
+ if(sp)return EFI_INVALID_PARAMETER;
+ phnd=LocateHandleGuid(Packages->GuidId,&hid);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this is wrong !!!
+ //here we are trying to check if somebody using passed GuidId registered Ifr with us
+ //it should not be like this but Intel's Setup Browser uses same GuidId sor 2 different
+ //Ifr instances. To maintain compatibility I'll try to patch code...
+ if(!phnd || phnd->HasStr){
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Packages->GuidId,&hid);
+ if(Status) return Status;
+ else c++;
+ phnd=gHiiDb.HandleDb.Items[hid];
+ }
+ Status=NewStringPack((EFI_HII_STRING_PACK*)hdr, hid);
+ if(EFI_ERROR(Status)) return Status;
+ sp=TRUE;
+ break;
+ case EFI_HII_IFR:
+ if(vp)return EFI_INVALID_PARAMETER;
+ phnd=LocateHandleGuid(Packages->GuidId,&hid);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this is wrong !!!//same goes gor IFR
+ if(!phnd || phnd->Ifr){
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Packages->GuidId,&hid);
+ if(Status) return Status;
+ else c++;
+ phnd=gHiiDb.HandleDb.Items[hid];
+ }
+
+ Status=NewIfrPack((EFI_HII_IFR_PACK*)hdr, hid);
+ if(EFI_ERROR(Status)) return Status;
+ vp=TRUE;
+ break;
+ case EFI_HII_KEYBOARD:
+ Status=NewKbdPack((EFI_HII_KEYBOARD_PACK*)hdr, hid);
+ break;
+ case EFI_HII_HANDLES:
+ if(hp)return EFI_INVALID_PARAMETER;
+//TODO
+ hp=TRUE;
+ break;
+ case EFI_HII_VARIABLE:
+//TODO
+ break;
+ case EFI_HII_DEVICE_PATH:
+//TODO
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }//switch
+ }
+ if(c)gHiiDb.NextHiiHandle++;
+
+ if(phnd)*Handle=phnd->Handle;
+ else *Handle=0;
+
+ return Status;
+}
+
+EFI_STATUS HiiNewPackOld (IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_PACK_LIST *Package,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ EFI_STATUS Status=0;
+ UINTN c=0,hid;
+ HII_HANDLE *phnd=NULL;
+//----------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ //Check if we have this GUID ib GuidDb already
+ //For Font and Keyboadr Data HAndle is allways = 0
+ if(Package->FontPack) Status=NewFontPack(Package->FontPack);
+ if(EFI_ERROR(Status)) return Status;
+
+ if(Package->StringPack){
+ phnd=LocateHandleGuid(Package->GuidId,&hid);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this is wrong !!!
+ //here we are trying to check if somebody using passed GuidId registered Ifr with us
+ //it should not be like this but Intel's Setup Browser uses same GuidId sor 2 different
+ //Ifr instances. To maintain compatibility I'll try to patch code...
+ if(!phnd || phnd->HasStr){
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// if(!phnd){
+ Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Package->GuidId,&hid);
+ if(Status) return Status;
+ else c++;
+ phnd=gHiiDb.HandleDb.Items[hid];
+ }
+
+ //if(phnd->HasStr) return EFI_INVALID_PARAMETER;
+ Status=NewStringPack(Package->StringPack, hid);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ if(Package->IfrPack){
+ phnd=LocateHandleGuid(Package->GuidId,&hid);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this is wrong !!!
+ //here we are trying to check if somebody using passed GuidId registered Ifr with us
+ //it should not be like this but Intel's Setup Browser uses same GuidId sor 2 different
+ //Ifr instances. To maintain compatibility I'll try to patch code...
+ if(!phnd || phnd->Ifr){
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// if(!phnd){
+ Status=LocateHandleAdd(gHiiDb.NextHiiHandle,Package->GuidId,&hid);
+ if(Status) return Status;
+ else c++;
+ phnd=gHiiDb.HandleDb.Items[hid];
+ }
+
+ //if(phnd->HasIfr) return EFI_INVALID_PARAMETER;
+ Status=NewIfrPack(Package->IfrPack, hid);
+ if(EFI_ERROR(Status)) return Status;
+ }
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//nothing is done for keyboard layout functions
+//this is empty spot in spec!
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ if(c)gHiiDb.NextHiiHandle++;
+
+ if(phnd)*Handle=phnd->Handle;
+ else *Handle=0;
+
+ return Status;
+}
+
+///////////////////////////////////////////////////////////////////
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//this function even not in spec yet so UNSUPPORT it!!!
+// here is an explanation I've got from Initial's Source
+// "This function allows to extract the NV Image
+// that represents the default storage image"
+//Still Unclear what to do with it
+EFI_STATUS HiiGetDefaultImageOld(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN UINTN DefaultMask,
+ IN OUT UINT16 *BufferLength,
+ IN OUT UINT8 *Buffer)
+{
+ HII_HANDLE *phnd;
+ HII_FORMSET *fs;
+ EFI_IFR_OP_HEADER *op;
+ UINTN hi,fsi,i,t=0,cv=0;
+ UINT8 *fsb;//formset buffer
+ BOOLEAN ol=FALSE;
+ EFI_STATUS Status;
+//---------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ phnd=LocateHandle(Handle,&hi);
+ if(!phnd || !phnd->Ifr) return EFI_INVALID_PARAMETER;
+
+ fs=LocateFormSet(hi,&fsi);
+ if(!fs) return EFI_INVALID_PARAMETER;
+
+ if(*BufferLength<fs->FormSetData->NvDataSize){
+ *BufferLength=fs->FormSetData->NvDataSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *BufferLength=fs->FormSetData->NvDataSize;
+ i=*BufferLength;
+
+ if (DefaultMask & EFI_IFR_FLAG_DEFAULT)
+ Status=pRS->GetVariable(L"SetupDefaultOverride",&phnd->Guid,NULL,&i,Buffer);
+ else {
+ if (DefaultMask & EFI_IFR_FLAG_MANUFACTURING)
+ Status=pRS->GetVariable(L"SetupManufacturingOverride",&phnd->Guid,NULL,&i,Buffer);
+ else {
+ DefaultMask = DefaultMask | EFI_IFR_FLAG_DEFAULT;
+ Status=pRS->GetVariable(L"Setup",&phnd->Guid,NULL,&i,Buffer);
+ }
+ }
+
+ fsb=Malloc(fs->BufferLength);
+ if(!fsb) return EFI_OUT_OF_RESOURCES;
+ CopyFormSet(fsb,fs,&i);
+
+ op=(EFI_IFR_OP_HEADER*)fsb;
+ while(op->OpCode!=EFI_IFR_END_FORM_SET_OP){
+ switch(op->OpCode){
+ case EFI_IFR_ORDERED_LIST_OP:
+ ol=TRUE;
+ i=((EFI_IFR_ONE_OF*)op)->QuestionId;
+ t=((EFI_IFR_ONE_OF*)op)->Width;
+ break;
+ case EFI_IFR_ONE_OF_OP:
+ ol=FALSE;
+ i=((EFI_IFR_ONE_OF*)op)->QuestionId;
+ t=((EFI_IFR_ONE_OF*)op)->Width;
+ break;
+ case EFI_IFR_ONE_OF_OPTION_OP:{
+ EFI_IFR_ONE_OF_OPTION *ifro=(EFI_IFR_ONE_OF_OPTION*)op;
+ //-----------------
+ if(!cv){
+ if(ol){
+ //pBS->CopyMem(&Buffer[i],&((EFI_IFR_ONE_OF_OPTION*)op)->Value, 1);
+ pBS->CopyMem(&Buffer[i],&ifro->Value, 1);
+ i++;
+ } else {
+ //if (((EFI_IFR_ONE_OF_OPTION*)op)->Flags & DefaultMask)
+ // pBS->CopyMem(&Buffer[i],&((EFI_IFR_ONE_OF_OPTION*)op)->Value,t);
+ if (ifro->Flags & DefaultMask)
+ pBS->CopyMem(&Buffer[i],&ifro->Value,t);
+ }
+ }
+ } break;
+ case EFI_IFR_END_OP:
+ t=0;
+ break;
+ case EFI_IFR_CHECKBOX_OP:{
+ EFI_IFR_CHECK_BOX *ifrc=(EFI_IFR_CHECK_BOX*)op;
+ //--------------------
+ if(!cv){
+ //if(((EFI_IFR_CHECK_BOX*)op)->Flags & DefaultMask)
+ // Buffer[((EFI_IFR_CHECK_BOX*)op)->QuestionId] = 1;
+ //else
+ // Buffer[((EFI_IFR_CHECK_BOX*)op)->QuestionId] = 0;
+ if(ifrc->Flags & DefaultMask)
+ Buffer[ifrc->QuestionId] = 1;
+ else
+ Buffer[ifrc->QuestionId] = 0;
+ }
+ } break;
+ case EFI_IFR_NUMERIC_OP:{
+ EFI_IFR_NUMERIC *ifrn=(EFI_IFR_NUMERIC*)op;
+ //--------------------------
+ //if (!cv)pBS->CopyMem(&Buffer[((EFI_IFR_NUMERIC*)op)->QuestionId],
+ // &((EFI_IFR_NUMERIC*)op)->Default,((EFI_IFR_NUMERIC*)op)->Width);
+ if (!cv){
+ pBS->CopyMem(&Buffer[ifrn->QuestionId], &ifrn->Default,ifrn->Width);
+ }
+ } break;
+
+ case EFI_IFR_VARSTORE_SELECT_OP:
+ case EFI_IFR_VARSTORE_SELECT_PAIR_OP:
+ cv=((EFI_IFR_VARSTORE_SELECT*)op)->VarId;
+ break;
+ }
+ op=(EFI_IFR_OP_HEADER*)((UINT8*)op+op->Length);
+ }
+ pBS->FreePool(fsb);
+ return EFI_SUCCESS;
+}
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiFindHandles(IN EFI_HII_PROTOCOL *This,
+ //spec not says in what units assume, for now, it is in EFI_HII_HANDLE
+ IN OUT UINT16 *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ UINTN i;
+ HII_HANDLE *hnd;
+//-------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ if(*HandleBufferLength<gHiiDb.HandleDb.ItemCount*sizeof(EFI_HII_HANDLE)){
+ *HandleBufferLength = (UINT16)gHiiDb.HandleDb.ItemCount*sizeof(EFI_HII_HANDLE);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ *HandleBufferLength = (UINT16)gHiiDb.HandleDb.ItemCount*sizeof(EFI_HII_HANDLE);
+ for (i=0; i<gHiiDb.HandleDb.ItemCount; i++){
+ hnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[i];
+ Handle[i]=hnd->Handle;
+ }
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+// Will remove all stuff associated with form set on particular handle
+// including all Update Data and Free all memory used to store private data
+// This function assumes "HandleIdx" is valid.
+VOID RemoveFormSet(UINTN HandleIdx){
+ HII_FORMSET *fst;
+ HII_FORM *frm;
+ HII_LABEL *lbl;
+ UINTN i,j,fsi;
+//--------------------------------
+ while(TRUE) { //it might be more then one formset with the same Handle
+ fst=LocateFormSet(HandleIdx, &fsi);
+ if(!fst) return; //Not a single form set was registred with this Handle
+
+ for(i=0;i<fst->Forms.ItemCount;i++){
+ frm=(HII_FORM*)fst->Forms.Items[i];
+ for(j=0;j<frm->Labels.ItemCount;j++){
+ lbl=frm->Labels.Items[j];
+ DeleteLabelObjects(lbl);
+ if(lbl->LabelData && lbl->Updated) pBS->FreePool(lbl->LabelData);
+ }
+ ClearItemLst(&frm->Labels,TRUE);
+ }
+ ClearItemLst(&fst->Labels,FALSE);
+ ClearItemLst(&fst->Forms,TRUE);
+ DeleteItemLst(&gHiiDb.IfrDb,fsi,TRUE);
+ }
+}
+
+///////////////////////////////////////////////////////////////////
+// Will remove all String records associated with "HandleIdx" for
+// all languages. This function assumes "HandleIdx" is valid.
+VOID RemoveStrings(UINTN HandleIdx){
+ HII_HANDLE *hnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[HandleIdx];
+ HII_STR *str;
+ INTN i;
+//-----------------------
+ for(i=0; (UINTN)i<gHiiDb.StringDb.RecordCount; i++){
+ DbeGoToIndex(&gHiiDb.StringDb,STR_KEY,(UINTN)i,&str);
+ if(str->Handle==hnd->Handle){
+ if(str->String.StrPtr)pBS->FreePool(str->String.StrPtr);
+ if(str->NewStr.StrPtr)pBS->FreePool(str->NewStr.StrPtr);
+ DbeDelete(&gHiiDb.StringDb,str,TRUE);
+ i--;
+ continue;
+ }
+ if(str->Handle>hnd->Handle) break;
+ }
+}
+
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiRemovePack(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle)
+
+{
+ UINTN hid;
+ HII_HANDLE *phnd;
+ HII_FORMSET *fs;
+ UINTN i;
+//--------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ //Here we will try to remove Pack from DB
+ phnd=LocateHandle(Handle,&hid);
+ if(!phnd) return EFI_INVALID_PARAMETER;
+
+ //So we found requested Handle, now remove all stuff associated with it.
+ //Remove IFRs
+ if(phnd->Ifr){
+ RemoveFormSet(hid);
+ pBS->FreePool(phnd->Ifr);
+ }
+ //Remove Strings
+ if(phnd->HasStr)RemoveStrings(hid);
+
+ //Free Items[] buffer if it was allocated
+ //if no Secondary Languages installed for this HII_HANDLE nothing has to be done
+ if(phnd->SecLang.ItemCount)ClearItemLst(&phnd->SecLang,FALSE);
+
+ //reindexing remaining formsets to take care of
+ //removed HII_HANDLE record from HiiDB.HandleDb[]
+ for(i=0; i<gHiiDb.IfrDb.ItemCount; i++) {
+ fs=gHiiDb.IfrDb.Items[i];
+ if(fs->HandleId>hid) fs->HandleId--;
+ }
+
+ DeleteItemLst(&gHiiDb.HandleDb, hid, TRUE);
+
+ //The current saved handle might be pointing on the one been removed.
+ //so reset them to initial values.
+ mCurHnd=NULL;
+ mCurLang=NULL;
+ mCurHid=0;
+ mCurLid=0;
+ mCurStr=NULL;
+
+ return EFI_SUCCESS;
+}
+
+///////////////////////////////////////////////////////////////////
+//HelperFunction to calculate size needed to dump the database
+//excluding EFI_HII_DATA_TABLE header
+UINTN GetHandleExpBuffSize(HII_HANDLE *HiiHandle, UINTN HndIndex){
+ UINTN sz=0, i, li=(UINTN)-1;
+ HII_FORMSET *fs=NULL;
+ HII_STR *str=NULL;
+ HII_STORE *st=NULL;
+//-------------------------------------
+
+ //This is an order of data structures as provided in Intel's implementation
+ //DevPath Data stuff Dummy so far just reserve space for DP_PACK and END_OF_DP
+ sz+=sizeof(EFI_HII_DEVICE_PATH_PACK)+sizeof(EFI_DEVICE_PATH_PROTOCOL);
+
+ //Find Formset we are working with
+ fs=LocateFormSet(HndIndex, NULL);
+
+ if(!fs) sz+= sizeof(gDummyVfr); //no formset no VAR data just Dummy Formset
+ else {
+ //Variable data
+ for(i=0; i<fs->Storages.ItemCount; i++){
+ //--------------------
+ st=fs->Storages.Items[i];
+ if(st->VarStore->Size){
+ UINT8 *p;
+ UINTN ind = 0, vsize = 0;
+ UINT16 VarName[256] = {0};
+ //---------------------
+ sz+=sizeof(EFI_HII_VARIABLE_PACK);
+ //sz+=st->VarStore->Size;
+ p=(UINT8*)(st->VarStore+1);
+ while(*p){
+ p++;
+ vsize+=sizeof(UINT16);
+ }
+ vsize+=sizeof(UINT16);//NULL terminator
+ sz+=vsize;
+
+ p=(UINT8*)(st->VarStore+1);
+ while(*p && ind < sizeof(VarName)){
+ VarName[ind] = (CHAR16)*p;
+ p++; ind++;
+ }
+ vsize=0;
+ pRS->GetVariable(VarName,&st->VarStore->Guid,NULL,&vsize,NULL);
+ if(vsize)
+ sz+=vsize;
+ else
+ sz += st->VarStore->Size;
+ }
+ }
+ if(fs->Storages.ItemCount > 0)
+ sz+=sizeof(EFI_HII_VARIABLE_PACK); // !! added dummy VARIABLE PACK
+
+ //formset data size
+ sz+=fs->BufferLength+sizeof(EFI_HII_PACK_HEADER);// !! changed to +=
+ }
+
+ //string data size
+ if(HiiHandle->HasStr){
+ for(i=0; i<gHiiDb.StringDb.RecordCount; i++){
+ DbeGoToIndex(&gHiiDb.StringDb,STR_KEY,(UINTN)i,&str);
+ if(str->Handle==HiiHandle->Handle){
+ if((li==-1)||(li!=str->LangIdx)){
+ li=str->LangIdx;
+ sz+=sizeof(EFI_HII_STRING_PACK); //new pack for new language
+ }
+ //the StrLen stored in UNICODECHAR units
+ if(str->NewStr.StrPtr)sz+=str->NewStr.StrLen*sizeof(CHAR16)+sizeof(RELOFST);
+ else sz+=str->String.StrLen*sizeof(CHAR16)+sizeof(RELOFST);
+ }
+ if((str->Handle>HiiHandle->Handle)||(i==gHiiDb.StringDb.RecordCount-1)){
+ sz+=sizeof(EFI_HII_STRING_PACK);//terminator pack
+ break;
+ }
+ }
+ }
+ return sz;
+}
+
+
+UINT32 CountStrOfLang(HII_HANDLE *HiiHandle, UINTN StartIdx, UINTN LangIdx ){
+ UINTN i;
+ UINT32 cnt=0;
+ HII_STR *str;
+//----------------------
+ for (i=StartIdx; i<gHiiDb.StringDb.RecordCount;i++){
+ DbeGoToIndex(&gHiiDb.StringDb,STR_KEY,i,&str);
+ if(str->Handle==HiiHandle->Handle){
+ if(str->LangIdx==LangIdx)cnt++;
+ else break;
+ } else break;
+ }
+ return cnt;
+}
+
+
+VOID ExportHandleData(IN HII_HANDLE *HiiHandle, IN UINTN HndIndex,
+ IN EFI_HII_DATA_TABLE *DataTbl, IN OUT UINT8 **BufferPointer)
+{
+ UINTN sz=0, i;
+ HII_FORMSET *fs;
+ HII_STR *str;
+ HII_STORE *st;
+ UINT8 *p1=*BufferPointer, *p2;
+ EFI_STATUS Status;
+//-------------------------------------
+
+ //This is an order of data structures as provided in Intel's implementation
+ //DevPath Data stuff Dummy so far END_OF_DP
+ DataTbl->DevicePathOffset=(UINT32)(p1-(UINT8*)DataTbl);
+
+ ((EFI_HII_DEVICE_PATH_PACK*)p1)->Header.Type=EFI_HII_DEVICE_PATH;
+
+ //points to the space after EFI_HII_DEVICE_PATH_PACK structure
+ p2=(p1+sizeof(EFI_HII_DEVICE_PATH_PACK));
+
+ ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Type=0xFF;
+ ((EFI_DEVICE_PATH_PROTOCOL*)p2)->SubType=0xFF;
+// ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Length=0;
+ ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Length[0]=0;
+ ((EFI_DEVICE_PATH_PROTOCOL*)p2)->Length[1]=0;
+ ((EFI_HII_DEVICE_PATH_PACK*)p1)->Header.Length=(UINT32)(p2-p1+sizeof(EFI_DEVICE_PATH_PROTOCOL));
+
+ p1=p2+sizeof(EFI_DEVICE_PATH_PROTOCOL);
+
+ //Find Formset we are working with
+ fs=LocateFormSet(HndIndex, NULL);
+ if(!fs) {
+ //No formset no VAR data
+ DataTbl->VariableDataOffset=0;
+
+ //Copy a Dummy formset to be compatible with Intel
+ DataTbl->IfrDataOffset=(UINT32)(p1-(UINT8*)DataTbl);
+
+ pBS->CopyMem(p1,&gDummyVfr[0],sizeof(gDummyVfr));
+ //copy handle guid here Shell expect it to mutch with some standart guids
+ pBS->CopyMem((VOID*)(p1+8),(VOID*)&HiiHandle->Guid,sizeof(EFI_GUID));
+ //Adjust the pointer
+ p1+=sizeof(gDummyVfr);
+ } else {
+ //Variable data
+ DataTbl->VariableDataOffset=(UINT32)(p1-(UINT8*)DataTbl);
+ for(i=0; i<fs->Storages.ItemCount; i++){
+ //--------------------
+ st=fs->Storages.Items[i];
+ if(st->VarStore->Size){
+ UINT8 *p;
+ //---------------------
+ p2=p1+sizeof(EFI_HII_VARIABLE_PACK);
+ ((EFI_HII_VARIABLE_PACK*)p1)->Header.Type=EFI_HII_VARIABLE;
+ //pBS->CopyMem((VOID*)&(((EFI_HII_VARIABLE_PACK*)p1)->VariableGuid),
+ // &st->VarStore.Guid, sizeof(EFI_GUID));
+
+ ((EFI_HII_VARIABLE_PACK*)p1)->VariableGuid=st->VarStore->Guid;
+ ((EFI_HII_VARIABLE_PACK*)p1)->VariableId=st->VarStore->VarId;
+
+ p=(UINT8*)(st->VarStore+1);
+ while(*p){
+ *p2=*p;
+ p++;
+ p2+=sizeof(UINT16);
+ //per spec VariableLength goes in Bytes
+ ((EFI_HII_VARIABLE_PACK*)p1)->VariableNameLength+=sizeof(UINT16);
+ }
+ p2+=sizeof(UINT16); //Null terminaterd
+ ((EFI_HII_VARIABLE_PACK*)p1)->VariableNameLength+=sizeof(UINT16);
+ //Copy contents of the variable at present p2
+ p=p1+sizeof(EFI_HII_VARIABLE_PACK);
+ sz=st->VarStore->Size;
+ Status=pRS->GetVariable((UINT16*)p,&st->VarStore->Guid,NULL,&sz,p2);
+
+ DataTbl->NumberOfVariableData++;
+ //don't forget to update size of Var Data in Pack Header
+ ((EFI_HII_VARIABLE_PACK*)p1)->Header.Length=(UINT32)(p2+sz-p1);
+
+ p1=p2+sz;
+ }
+ }
+ if(!DataTbl->NumberOfVariableData)DataTbl->VariableDataOffset=0;
+ else { // !! Add zero-terminating EFI HII variable
+ ((EFI_HII_VARIABLE_PACK*)p1)->Header.Type=EFI_HII_VARIABLE;
+ ((EFI_HII_VARIABLE_PACK*)p1)->Header.Length = sizeof(EFI_HII_VARIABLE_PACK);
+ p1 += sizeof(EFI_HII_VARIABLE_PACK);
+ }
+ //Formset goes data here
+ DataTbl->IfrDataOffset=(UINT32)(p1-(UINT8*)DataTbl);
+ p2=p1+sizeof(EFI_HII_PACK_HEADER);
+ ((EFI_HII_PACK_HEADER*)p1)->Length=(UINT32)fs->BufferLength+sizeof(EFI_HII_PACK_HEADER);
+ ((EFI_HII_PACK_HEADER*)p1)->Type=EFI_HII_IFR;
+
+ i=0;
+ CopyFormSet(p2,fs,&i);
+ p1=p2+i;
+ }
+ //If HIIHandle Data don't have Strings make p2==p1 since we are returning p2 value
+ p2=p1;
+ //string data goes here
+ if(HiiHandle->HasStr){
+ UINT8 *p=p1;
+ UINT32 li=(UINTN)-1;
+ //-----------------
+ DataTbl->StringDataOffset=(UINT32)(p1-(UINT8*)DataTbl);
+ for(i=0; i<gHiiDb.StringDb.RecordCount; i++){
+ DbeGoToIndex(&gHiiDb.StringDb,STR_KEY,(UINTN)i,&str);
+ if(str->Handle==HiiHandle->Handle){
+
+ if((li==-1)||(li!=str->LangIdx)){
+ //p1 points on the EFI_HII_STRING_PACK
+ p1=p;
+ ((EFI_HII_STRING_PACK*)p1)->Header.Type=EFI_HII_STRING;
+ DataTbl->NumberOfLanguages++;
+ //p2 points on the RELOFS array
+ p2=p1+sizeof(EFI_HII_STRING_PACK);
+
+ li=str->LangIdx;
+
+ ((EFI_HII_STRING_PACK*)p1)->NumStringPointers=CountStrOfLang(HiiHandle,i,li);
+ //p points on the UnicodeString;
+ p=p2+((EFI_HII_STRING_PACK*)p1)->NumStringPointers*sizeof(UINT32);
+ ((EFI_HII_STRING_PACK*)p1)->LanguageNameString=(UINT32)((UINTN)p-(UINTN)p1);
+ ((EFI_HII_STRING_PACK*)p1)->PrintableLanguageName=((EFI_HII_STRING_PACK*)p1)->LanguageNameString
+ +4*sizeof(CHAR16);
+ ((EFI_HII_STRING_PACK*)p1)->Header.Length=sizeof(EFI_HII_STRING_PACK)+
+ ((EFI_HII_STRING_PACK*)p1)->NumStringPointers*sizeof(UINT32);
+
+ }
+ //update offset table
+ *((UINT32*)p2)=(UINT32)((UINTN)p-(UINTN)p1);
+ //the StrLen stored in UNICODECHAR units including NULL CHAR16
+ if(str->NewStr.StrPtr){
+ pBS->CopyMem(p, str->NewStr.StrPtr, str->NewStr.StrLen*sizeof(CHAR16));
+ p+=str->NewStr.StrLen*sizeof(CHAR16);
+ ((EFI_HII_STRING_PACK*)p1)->Header.Length+=str->NewStr.StrLen*sizeof(CHAR16);
+ } else {
+ pBS->CopyMem(p, str->String.StrPtr, str->String.StrLen*sizeof(CHAR16));
+ p+=str->String.StrLen*sizeof(CHAR16);
+ ((EFI_HII_STRING_PACK*)p1)->Header.Length+=str->String.StrLen*sizeof(CHAR16);
+ }
+ p2+=sizeof(UINT32);
+ }
+ //don't forget to put terminator pack at the very end of the string data
+ if((str->Handle > HiiHandle->Handle) || (i==gHiiDb.StringDb.RecordCount-1)){
+ //Create a terminator pack
+ p1=p;
+ ((EFI_HII_STRING_PACK*)p1)->Header.Type=EFI_HII_STRING;
+ p2=p1+sizeof(EFI_HII_STRING_PACK);
+ break;
+ }
+ }
+ }
+
+ *BufferPointer=p2;
+
+}
+
+
+
+///////////////////////////////////////////////////////////////////
+EFI_STATUS HiiExport(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer )
+{
+ UINTN sz, i;
+ HII_HANDLE *phnd=NULL;
+ EFI_HII_EXPORT_TABLE *expt=NULL;
+ EFI_HII_DATA_TABLE *cdt=NULL;
+ UINT8 *bp=NULL;
+//----------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ sz=sizeof(EFI_HII_EXPORT_TABLE);
+
+ //Calculate buffer Size
+ for(i=0; i<gHiiDb.HandleDb.ItemCount; i++){
+ phnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[i];
+ if(Handle && Handle!=phnd->Handle) continue;
+ sz+=GetHandleExpBuffSize(phnd,i) + sizeof(EFI_HII_DATA_TABLE);
+ }
+ //Check the buffer size provided
+ if(sz > *BufferSize){
+ *BufferSize=sz;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ pBS->SetMem(Buffer, sz, 0);
+ //Export Table
+ expt=(EFI_HII_EXPORT_TABLE*)Buffer;
+ if((UINTN)This == (UINTN)&gHiiDb.HiiProtocolOld) expt->Revision=gEfiHiiProtocolGuidOld;
+ else expt->Revision=gEfiHiiProtocolGuidNew;
+
+ bp=(UINT8*)(expt+1);
+
+ //Start dumping the data
+ for(i=0 ; i<gHiiDb.HandleDb.ItemCount; i++){
+
+ phnd=(HII_HANDLE*)gHiiDb.HandleDb.Items[i];
+ if(Handle && Handle!=phnd->Handle) continue;
+ //CurrentDataTable
+ cdt=(EFI_HII_DATA_TABLE*)bp;
+ bp+=sizeof(EFI_HII_DATA_TABLE);
+
+ sz=GetHandleExpBuffSize(phnd,i);
+
+ cdt->HiiHandle=phnd->Handle;
+ cdt->PackageGuid=phnd->Guid;
+ cdt->DataTableSize=(UINT32)(sz+sizeof(EFI_HII_DATA_TABLE));
+
+ ExportHandleData(phnd, i, cdt, &bp);
+//debug+ just to test how bp gets incremented
+ ASSERT((UINTN)cdt+sizeof(EFI_HII_DATA_TABLE)+sz==(UINTN)bp);
+//debug-
+ expt->NumberOfHiiDataTables++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GetVarStoreData(HII_FORMSET *FormSet, HII_STORE *VarData, UINT8* Buffer, UINTN DefaultMask){
+ HII_LABEL *lbl;
+ HII_OBJECT *obj;
+ HII_FORM *frm;
+ EFI_IFR_OP_HEADER *op;
+ UINTN i,x,j,k,offs,len;
+//------------------
+
+ for(i=0; i<FormSet->Forms.ItemCount; i++){
+ frm=FormSet->Forms.Items[i];
+ for(x=0; x< frm->Labels.ItemCount; x++){
+ //iterate trough the Labels to get each HII_OBJECT
+ lbl=frm->Labels.Items[x];
+ for(j=0; j<lbl->Objects.ItemCount; j++){
+ //iterate trough the Objects to see if
+ obj=lbl->Objects.Items[j];
+
+ if( VarData->VarStore->VarId!=obj->Store1->VarStore->VarId ||
+ MemCmp(&VarData->VarStore->Guid, &obj->Store1->VarStore->Guid, sizeof(EFI_GUID))
+ ) continue;
+
+ //we focused at the Object which has the same VarStore Properies as passed "VarData"
+ //So parse the object to see if it has any default flags set
+ op=obj->ObjectCode;
+ switch(op->OpCode){
+
+ //ONE_OF and ORDERED_LIST has almost the same encoding
+ case EFI_IFR_ORDERED_LIST_OP:
+ case EFI_IFR_ONE_OF_OP:
+ {
+ EFI_IFR_ONE_OF_OPTION *opt;
+ //-----------------------
+ offs=((EFI_IFR_ONE_OF*)op)->QuestionId;
+ len=((EFI_IFR_ONE_OF*)op)->Width;
+
+//DEBUG CODE to check if update runs out of bound
+ if(offs>=VarData->VarStore->Size) {
+ ASSERT_EFI_ERROR(EFI_BUFFER_TOO_SMALL);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+//DEBUG CODE to check if update runs out of bound
+
+ for(k=0; k<obj->Options.ItemCount; k++){
+ opt=(EFI_IFR_ONE_OF_OPTION*)obj->Options.Items[k];
+ //for ORDERED_LIST it would not be any Defaults
+ if(op->OpCode==EFI_IFR_ORDERED_LIST_OP){
+ pBS->CopyMem(&Buffer[offs],&opt->Value, 1);
+ offs++;
+
+//DEBUG CODE to check if update runs out of bound
+ if(offs>=VarData->VarStore->Size) return EFI_BUFFER_TOO_SMALL;
+//DEBUG CODE to check if update runs out of bound
+
+ } else {
+ UINTN f=(UINTN)opt->Flags;
+ //------------------
+ if (f & DefaultMask) {
+ pBS->CopyMem(&Buffer[offs],&opt->Value,len);
+ break;
+ }
+ }
+ }
+ }break;
+
+ case EFI_IFR_CHECKBOX_OP:
+ {
+ EFI_IFR_CHECK_BOX *cb=(EFI_IFR_CHECK_BOX*)obj->ObjectCode;
+ UINTN f=(UINTN)cb->Flags;
+ //--------------------
+ offs=cb->QuestionId;
+
+//DEBUG CODE to check if update runs out of bound
+ if(offs>=VarData->VarStore->Size) return EFI_BUFFER_TOO_SMALL;
+//DEBUG CODE to check if update runs out of bound
+
+ if(f & DefaultMask) Buffer[offs] = 1;
+ else Buffer[offs] = 0;
+
+ } break;
+
+ case EFI_IFR_NUMERIC_OP:
+ {
+ EFI_IFR_NUMERIC *num =(EFI_IFR_NUMERIC*)obj->ObjectCode;
+ //--------------------------
+ offs=num->QuestionId;
+ len=num->Width;
+
+//DEBUG CODE to check if update runs out of bound
+ if(offs>=VarData->VarStore->Size) return EFI_BUFFER_TOO_SMALL;
+//DEBUG CODE to check if update runs out of bound
+
+ pBS->CopyMem(&Buffer[offs],&num->Default,len);
+ } break;
+
+ } //switch(obj->ObjectCode->Opcode)
+
+ } //for(j) loop
+ }//for(x) loop
+ } //for(i) loop
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS HiiGetDefaultImageNew(IN EFI_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN UINTN DefaultMask,
+ OUT EFI_HII_VARIABLE_PACK_LIST **VariablePackList)
+{
+ EFI_STATUS Status=EFI_NOT_FOUND;
+ UINTN i, j, k, hidx, vnl=0, tbsz=0;
+ HII_HANDLE *phnd;
+ EFI_HII_VARIABLE_PACK_LIST *vpl, *fvpl=NULL, *pvpl=NULL;
+ HII_FORMSET *fs;
+ HII_STORE *st;
+ UINT8 *pdb, *pnb;
+//----------------------------------
+
+ //Check Parameters
+ if(This==NULL || VariablePackList==NULL || !Handle ) return EFI_INVALID_PARAMETER;
+
+ //Find the handle
+ phnd=LocateHandle(Handle, &hidx);
+ if(phnd==NULL) return EFI_NOT_FOUND;
+
+ //If no VarStores associated with passed Handle will return NULL
+ *VariablePackList=NULL;
+
+ //If Handle Exists then find a FormSet associated with this Handle
+ fs=LocateFormSet(hidx, NULL);
+ //No formset found => no IFR data
+ if(fs==NULL) return EFI_NOT_FOUND;
+
+ //Collect the Variable data
+ for(i=0, hidx=0; i<fs->Storages.ItemCount; i++){
+ st=fs->Storages.Items[i];
+ if(!st->VarStore->Size) continue;
+
+ Status=EFI_SUCCESS;
+ hidx++;
+ //get the variable name length in bytes(ASCII)
+ vnl=st->VarStore->Header.Length-sizeof(EFI_IFR_VARSTORE);
+ //determine how much memory we need to accomodate
+ //EFI_VARIABLE_PACK_LIST + EFI_VARIABLE_PACK + VarName + VarData
+ vpl=MallocZ(sizeof(EFI_HII_VARIABLE_PACK_LIST)+ //EFI_VARIABLE_PACK_LIST
+ sizeof(EFI_HII_VARIABLE_PACK)+ //EFI_VARIABLE_PACK
+ (vnl*sizeof(UINT16))+ //EFI_VARIABLE_PACK has VarName in UINT16
+ st->VarStore->Size); //Size of actual NV Var Data
+
+ tbsz+=(sizeof(EFI_HII_VARIABLE_PACK_LIST)+ //EFI_VARIABLE_PACK_LIST
+ sizeof(EFI_HII_VARIABLE_PACK)+ //EFI_VARIABLE_PACK
+ (vnl*sizeof(UINT16))+ //EFI_VARIABLE_PACK has VarName in UINT16
+ st->VarStore->Size); //Size of actual NV Var Data
+
+ if(!vpl) return EFI_OUT_OF_RESOURCES;
+
+ //determine where in VPL buffer Actual VAriable data suppose to start
+ pdb=(UINT8*)vpl+sizeof(EFI_HII_VARIABLE_PACK_LIST)+sizeof(EFI_HII_VARIABLE_PACK)+(vnl*sizeof(UINT16));
+
+ GetVarStoreData(fs,st,pdb,DefaultMask);
+
+ //if this is the first structure in the list remember it we must return it's address
+ if(fvpl==NULL)fvpl=vpl;
+ //if PreviouseVariablePackList ptr was initialized update pointer to next VPL with current VPL
+ if(pvpl!=NULL)pvpl->NextVariablePack=vpl;
+ //reinitialize PreviouseVariablePackList ptr with current VPL pointer
+ pvpl=vpl;
+
+ //Update context of the VariablePack pointer to the next data byte afer itself(per .92 spec)
+ vpl->VariablePack = (EFI_HII_VARIABLE_PACK*)(vpl+1);
+
+ //Now fill out fields of HII_VARIABLE_PACK structure
+ vpl->VariablePack->Header.Type=EFI_HII_VARIABLE;
+ vpl->VariablePack->Header.Length=(UINT32)(sizeof(EFI_HII_VARIABLE_PACK)+(vnl*sizeof(UINT16))+st->VarStore->Size);
+ vpl->VariablePack->VariableId=st->VarStore->VarId;
+ vpl->VariablePack->VariableNameLength=(UINT32)(vnl*sizeof(UINT16)); // per spec length in bytes.
+ pBS->CopyMem(&vpl->VariablePack->VariableGuid, &st->VarStore->Guid, sizeof(EFI_GUID));
+ //now copy Variable name "pdb" points at the befinning of VarName buffer
+ pdb=(UINT8*)vpl+sizeof(EFI_HII_VARIABLE_PACK_LIST)+sizeof(EFI_HII_VARIABLE_PACK);
+ pnb=(UINT8*)(st->VarStore+1);
+ //since in VARIABLE_PACKAGE VAR NAME is UNICODE simple MemCpy wouldn't do.
+ for(j=0,k=0; j<vnl; j++, k+=2) {
+ pdb[k]=pnb[j];
+ }
+ }
+
+ //Per Spec we have to dump all data in single buffer.
+ //Update the IN/OUT parameter
+ if(tbsz) {
+ *VariablePackList=Malloc(tbsz);
+ if(*VariablePackList==NULL) return EFI_OUT_OF_RESOURCES;
+ } else *VariablePackList=NULL;
+ vpl=fvpl;
+ pdb=(UINT8*)(*VariablePackList);
+ while (vpl){
+ //copy Var_PACK_LIST + VARPACK to the Common Buffer
+ pBS->CopyMem(pdb,vpl,sizeof(EFI_HII_VARIABLE_PACK_LIST)+vpl->VariablePack->Header.Length);
+ pvpl=(EFI_HII_VARIABLE_PACK_LIST*)pdb;
+ pvpl->VariablePack=(EFI_HII_VARIABLE_PACK*)(pdb+sizeof(EFI_HII_VARIABLE_PACK_LIST));
+
+ pdb+=(sizeof(EFI_HII_VARIABLE_PACK_LIST)+vpl->VariablePack->Header.Length);
+ if(vpl->NextVariablePack!=NULL)pvpl->NextVariablePack=(EFI_HII_VARIABLE_PACK_LIST*)pdb;
+
+ pvpl=vpl;
+ vpl=vpl->NextVariablePack;
+
+ pBS->FreePool(pvpl);
+ }
+
+ return Status;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//Keyboard
+EFI_STATUS HiiGetKeyboardLayout(IN EFI_HII_PROTOCOL *This,
+ OUT UINT16 *DescriptorCount,
+ OUT EFI_KEY_DESCRIPTOR *Descriptor)
+{
+ HII_KB_LAYOUT_DATA *kbld;
+//-------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ if(!gHiiDb.KeybdDb.KblCount) return EFI_NOT_FOUND;
+
+ kbld=gHiiDb.KeybdDb.KbLayout[gHiiDb.KeybdDb.ActiveLayout];
+
+ //we got small buffer
+ if(*DescriptorCount<kbld->KeyDscCount) {
+ *DescriptorCount=kbld->KeyDscCount;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ MemCpy((VOID*)Descriptor, (VOID*)kbld->KeyDsc, sizeof(EFI_KEY_DESCRIPTOR)*kbld->KeyDscCount);
+
+ return EFI_SUCCESS;
+}
+
+
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+//EXTENDED HII INTERFACE
+////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////
+EFI_STATUS HiiExtGetStringInfo(
+ IN EXT_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN STRING_REF Token,
+ IN CHAR16 *Lang,
+ OUT EXT_STR_INFO **ExtStrInfo)
+{
+ HII_STR *str;
+//-----------------------------------------
+ if(!This || !ExtStrInfo ) return EFI_INVALID_PARAMETER;
+
+ str=GetHiiString(Handle,Lang,Token);
+ if(!str) return EFI_NOT_FOUND;
+
+ if(str->NewStr.StrPtr)*ExtStrInfo=&str->NewStr;
+ else *ExtStrInfo=&str->String;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS HiiExtGetFormInfo(IN EXT_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormId,
+ OUT HII_FORM **ExtFormInfo)
+{
+ HII_FORM *frm;
+ UINTN hi;
+ HII_HANDLE *phnd;
+ HII_FORMSET *fs;
+//-----------------------------------------
+ if(!This || !ExtFormInfo ) return EFI_INVALID_PARAMETER;
+
+ phnd=LocateHandle(Handle,&hi);
+ ASSERT(phnd);
+ if(!phnd)return EFI_NOT_FOUND;
+
+ fs=LocateFormSet(hi,NULL);
+ ASSERT(fs);
+ if(!fs)return EFI_NOT_FOUND;
+
+ frm=LocateForm(fs,FormId);
+ ASSERT(frm);
+ if(!frm)return EFI_NOT_FOUND;
+ *ExtFormInfo=frm;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS HiiExtRegisterLabelUpdateCallback(IN EXT_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_LABEL LabelId,
+ IN HII_LABEL_UPDATE_CALLBACK CallBack)
+{
+ UINTN hi;
+ HII_LABEL *lbl;
+ HII_FORMSET *fs;
+//----------------------------------
+ if(!This || !CallBack ) return EFI_INVALID_PARAMETER;
+
+ if(!LocateHandle(Handle, &hi)) return EFI_INVALID_PARAMETER;
+
+ //Find Formset
+ fs=LocateFormSet(hi, NULL);
+ if(!fs) return EFI_INVALID_PARAMETER;
+
+ lbl=LocateFormSetLabel(fs,LabelId,NULL);
+ if(!lbl) return EFI_NOT_FOUND;
+
+ lbl->UpdateCallBack=CallBack;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiExtUnregisterLabelUpdateCallback(IN EXT_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_LABEL LabelId)
+{
+ UINTN hi;
+ HII_LABEL *lbl;
+ HII_FORMSET *fs;
+//----------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+
+ if(!LocateHandle(Handle, &hi)) return EFI_INVALID_PARAMETER;
+
+ //Find Formset
+ fs=LocateFormSet(hi, NULL);
+ if(!fs) return EFI_INVALID_PARAMETER;
+
+ lbl=LocateFormSetLabel(fs,LabelId,NULL);
+ if(!lbl) return EFI_NOT_FOUND;
+
+ lbl->UpdateCallBack=NULL;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiExtGetFormSetInfo(IN EXT_HII_PROTOCOL *This,
+ IN UINT16 ClassMask, //if ==0xFFFF all Classes
+ IN UINT16 SubClass, //if ==0xFFFF all SubClasses
+ OUT T_ITEM_LIST *FormSetList)
+{
+ UINTN i;
+ HII_FORMSET *fs;
+//------------------------------
+ if(!This || !FormSetList) return EFI_INVALID_PARAMETER;
+
+ //Make sure the list is empty
+ ClearItemLst(FormSetList,FALSE);
+ for(i=0; i<gHiiDb.IfrDb.ItemCount;i++){
+ fs=gHiiDb.IfrDb.Items[i];
+ if(SubClass!=0xFFFF && SubClass!=fs->FormSetData->SubClass) continue;
+ if((fs->FormSetData->Class & ClassMask)==fs->FormSetData->Class) AppendItemLst(FormSetList,fs);
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiExtGetFormLabels(IN EXT_HII_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_FORM_ID FormID,
+ OUT T_ITEM_LIST *LabelList)
+{
+ UINTN i;
+ HII_FORMSET *fs;
+ HII_FORM *frm;
+ HII_LABEL *lbl;
+ EFI_STATUS Status;
+//-----------------------------------------
+ if(!This || !LabelList ) return EFI_INVALID_PARAMETER;
+
+ if(!LocateHandle(Handle,&i)) return EFI_INVALID_PARAMETER;;
+
+ fs=LocateFormSet(i,NULL);
+ ASSERT(fs);
+ if(!fs)return EFI_NOT_FOUND;
+
+ frm=LocateForm(fs,FormID);
+ ASSERT(frm);
+ if(!frm)return EFI_NOT_FOUND;
+
+ ClearItemLst(LabelList,FALSE);
+ for(i=1;i<frm->Labels.ItemCount;i++){
+ lbl=frm->Labels.Items[i];
+ Status=AppendItemLst(LabelList,lbl);
+ ASSERT(!EFI_ERROR(Status));
+ if(EFI_ERROR(Status))return Status;
+ }
+ return EFI_SUCCESS;
+}
+
+
+///////////////////////////////////////////////////////////////////
+//Init All Private Data
+EFI_STATUS InitPrivateData(EFI_HANDLE MyImgHandle){
+ EFI_STATUS Status=0;
+ //HII_LANG *al;//any lang
+//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST
+ EFI_HII_PACK_LIST *pl=Malloc(sizeof(EFI_HII_PACK_LIST));
+ // {BB2F3C9D-C7A1-4283-8AE2-4F4362990E2E}
+ static EFI_GUID pguid={ 0xbb2f3c9d, 0xc7a1, 0x4283, 0x8a, 0xe2, 0x4f, 0x43, 0x62, 0x99, 0x0e, 0x2e };
+ EFI_HII_HANDLE fph;//,sth;
+// UINT16 bl;
+// UINT8 *fsb;
+//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST
+//-----------------------------
+ pBS->SetMem(&gHiiDb, sizeof(HII_DB),0 );
+
+ gHiiDb.ImageHandle=MyImgHandle;
+ gHiiDb.NextHiiHandle=1; //Zero Handle is Invalid it must be 1 based
+
+ //Create Any Langguage Entry - empty string L" "
+ Status=LocateLangAdd(L" ",L"Any Language",NULL);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Create and Initialize String Database
+ gHiiDb.StringDb.KeyCount=STR_KEY_CNT;
+ gHiiDb.StringDb.InitialCount=STRING_DB_MAX_COUNT;
+ gHiiDb.StringDb.KeyField=&gStrKey;
+ gHiiDb.StringDb.MemoryType=EfiBootServicesData;
+ gHiiDb.StringDb.RecordCount=0;
+ gHiiDb.StringDb.IndexArray=MallocZ(sizeof(VOID*)*gHiiDb.StringDb.InitialCount*gHiiDb.StringDb.KeyCount);
+ if(!gHiiDb.StringDb.IndexArray) return EFI_OUT_OF_RESOURCES;
+
+ //Init Protocol Instance here
+ gHiiDb.HiiProtocolOld.NewPack=HiiNewPackOld;
+ gHiiDb.HiiProtocolNew.NewPack=HiiNewPackNew;
+
+ gHiiDb.HiiProtocolOld.RemovePack=HiiRemovePack;
+ gHiiDb.HiiProtocolNew.RemovePack=HiiRemovePack;
+
+ gHiiDb.HiiProtocolOld.FindHandles=HiiFindHandles;
+ gHiiDb.HiiProtocolNew.FindHandles=HiiFindHandles;
+
+ gHiiDb.HiiProtocolOld.GetDefaultImage=HiiGetDefaultImageOld;
+ gHiiDb.HiiProtocolNew.GetDefaultImage=HiiGetDefaultImageNew;
+
+ gHiiDb.HiiProtocolOld.TestString=HiiTestString;
+ gHiiDb.HiiProtocolNew.TestString=HiiTestString;
+
+ gHiiDb.HiiProtocolOld.GetGlyph=HiiGetGlyph;
+ gHiiDb.HiiProtocolNew.GetGlyph=HiiGetGlyph;
+
+ gHiiDb.HiiProtocolOld.GlyphToBlt=HiiGlyphToBlt;
+ gHiiDb.HiiProtocolNew.GlyphToBlt=HiiGlyphToBlt;
+
+ gHiiDb.HiiProtocolOld.NewString=HiiNewString;
+ gHiiDb.HiiProtocolNew.NewString=HiiNewString;
+
+ gHiiDb.HiiProtocolOld.GetPrimaryLanguages=HiiGetPrimaryLanguage;
+ gHiiDb.HiiProtocolNew.GetPrimaryLanguages=HiiGetPrimaryLanguage;
+
+ gHiiDb.HiiProtocolOld.GetSecondaryLanguages=HiiGetSecondaryLanguages;
+ gHiiDb.HiiProtocolNew.GetSecondaryLanguages=HiiGetSecondaryLanguages;
+
+ gHiiDb.HiiProtocolOld.GetString=HiiGetStringOld;
+ gHiiDb.HiiProtocolNew.GetString=HiiGetStringNew;
+
+ gHiiDb.HiiProtocolOld.GetLine=HiiGetLine;
+ gHiiDb.HiiProtocolNew.GetLine=HiiGetLine;
+
+ gHiiDb.HiiProtocolOld.GetForms=HiiGetFormsOld;
+ gHiiDb.HiiProtocolNew.GetForms=HiiGetFormsNew;
+
+ gHiiDb.HiiProtocolOld.UpdateForm=HiiUpdateForm;
+ gHiiDb.HiiProtocolNew.UpdateForm=HiiUpdateForm;
+
+ gHiiDb.HiiProtocolOld.GetKeyboardLayout=HiiGetKeyboardLayout;
+ gHiiDb.HiiProtocolNew.GetKeyboardLayout=HiiGetKeyboardLayout;
+
+ gHiiDb.HiiProtocolOld.ResetStrings=HiiResetStrings;
+ gHiiDb.HiiProtocolNew.ResetStrings=HiiResetStrings;
+
+ gHiiDb.HiiProtocolOld.ExportDatabase=HiiExport;
+ gHiiDb.HiiProtocolNew.ExportDatabase=HiiExport;
+
+ //Now do Extended Hii Interface
+ gHiiDb.HiiExtProtocol.ExtGetStringInfo=HiiExtGetStringInfo;
+ gHiiDb.HiiExtProtocol.ExtGetFormInfo=HiiExtGetFormInfo;
+ gHiiDb.HiiExtProtocol.ExtGetFormsetInfo=HiiExtGetFormSetInfo;
+ gHiiDb.HiiExtProtocol.ExtRegLblCallBack=HiiExtRegisterLabelUpdateCallback;
+ gHiiDb.HiiExtProtocol.ExtUnregLblCallBack=HiiExtUnregisterLabelUpdateCallback;
+ gHiiDb.HiiExtProtocol.ExtGetFormLabels=HiiExtGetFormLabels;
+
+ //------------------------------------
+ //init Font Data
+ pl->FontPack=(EFI_HII_FONT_PACK*)&UsStdNarrowGlyphData;
+ pl->GuidId=&pguid;
+ pl->IfrPack=NULL;//(EFI_HII_IFR_PACK*)&FrontPageVfrBin;
+ pl->KeyboardPack=NULL;
+ pl->StringPack=NULL;//(EFI_HII_STRING_PACK*)&FrontPageStrings;
+///// Load Font Pack
+{
+#define FONT_FFS_FILE_GUID { 0xdac2b117, 0xb5fb, 0x4964, { 0xa3, 0x12, 0xd, 0xcc, 0x77, 0x6, 0x1b, 0x9b } }
+static EFI_GUID guidFontFile = FONT_FFS_FILE_GUID;
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *pFV;
+ UINTN DataSize;
+ EFI_GUID *pSectionGuid = NULL;
+ UINT32 Authentication;
+ EFI_HANDLE *pHandle;
+ UINTN Number,i;
+ Status = pBS->LocateHandleBuffer(ByProtocol,&guidFV, NULL, &Number, &pHandle);
+ for(i=0;i<Number; i++)
+ {
+ Status=pBS->HandleProtocol(pHandle[i], &guidFV, &pFV);
+ if (EFI_ERROR(Status)) continue;
+ pSectionGuid=NULL;
+ DataSize=0;
+ Status=pFV->ReadSection (
+ pFV,&guidFontFile,
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,0, &pSectionGuid, &DataSize,
+ &Authentication
+ );
+ if (!EFI_ERROR(Status))
+ {
+ pl->FontPack=(EFI_HII_FONT_PACK*)((UINT32*)(pSectionGuid+1)+1);
+ break;
+ }
+ }
+ Status=HiiNewPackOld((EFI_HII_PROTOCOL*)&gHiiDb.HiiProtocolOld,pl,&fph);
+ pBS->FreePool(pSectionGuid);
+}
+////////////////////
+ if(EFI_ERROR(Status)) return Status;
+
+//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST
+/* pl->FontPack=NULL;
+ pl->IfrPack=NULL;
+ pl->KeyboardPack=NULL;
+ pl->StringPack=(EFI_HII_STRING_PACK*)&SetupStrings;
+
+ Status=HiiNewPack(&gHiiDb.HiiProtocol,pl,&sth);
+ if(EFI_ERROR(Status)) return Status;
+
+ fsb=NULL;
+ bl=0;
+ Status=HiiGetForms(&gHiiDb.HiiProtocol,fph,0,&bl,fsb);
+ if(Status==EFI_BUFFER_TOO_SMALL);
+ else if(EFI_ERROR(Status)) return Status;
+ fsb=Malloc(bl);
+ if(!fsb) return EFI_OUT_OF_RESOURCES;
+ Status=HiiGetForms(&gHiiDb.HiiProtocol,fph,0,&bl,fsb);
+
+ //Now, I'll try to ges some strings from FrontPageDb
+ {
+ UINT16 mystr[81];
+ EFI_STRING plan, slan;
+ EFI_IFR_FORM_SET *fs=(EFI_IFR_FORM_SET*)fsb;
+ UINT32 gb,i=0;
+ //-----------------------------------
+
+ Status=HiiGetPrimaryLanguage(&gHiiDb.HiiProtocol,fph,&plan);
+ //it might be more than 1 Sec Lang.
+ Status=HiiGetSecondaryLanguages(&gHiiDb.HiiProtocol,fph,plan,&slan);
+
+
+ bl=80;
+
+ Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->FormSetTitle,TRUE,slan,&bl,&mystr[0]);
+
+ Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->FormSetTitle,TRUE,plan,&bl,&mystr[0]);
+
+ Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->Help,TRUE,slan,&bl,&mystr[0]);
+
+ Status=HiiGetString(&gHiiDb.HiiProtocol,fph,fs->Help,TRUE,plan,&bl,&mystr[0]);
+
+ Status=HiiTestString(&gHiiDb.HiiProtocol,&mystr[0],&i,&gb);
+
+ }
+
+*/
+//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST//TEST
+ pBS->FreePool(pl);
+//
+// return pBS->InstallMultipleProtocolInterfaces( gHiiDb.ImageHandle,
+// &gEfiHiiProtocolGuid,&gHiiDb.HiiProtocol,NULL,NULL);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/FwVol.c b/Core/CORE_DXE/FwVol.c
new file mode 100644
index 0000000..47057a2
--- /dev/null
+++ b/Core/CORE_DXE/FwVol.c
@@ -0,0 +1,589 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVol.c
+
+Abstract:
+
+ Firmware File System driver that produce Firmware Volume protocol.
+ Layers on top of Firmware Block protocol to produce a file abstraction
+ of FV based files.
+
+--*/
+
+#include "FwVolDriver.h"
+#include "DxeCore.h"
+
+
+#define KEYSIZE sizeof (UINTN)
+
+//
+// Protocol notify related globals
+//
+VOID *gEfiFwVolBlockNotifyReg;
+EFI_EVENT gEfiFwVolBlockEvent;
+
+FV_DEVICE mFvDevice = {
+ FV_DEVICE_SIGNATURE,
+ NULL,
+ NULL,
+ {
+ FvGetVolumeAttributes,
+ FvSetVolumeAttributes,
+ FvReadFile,
+ FvReadFileSection,
+ FvWriteFile,
+ FvGetNextFile,
+ KEYSIZE,
+ NULL
+ #if (PI_SPECIFICATION_VERSION >= 0x00010000)
+ ,
+ FvGetVolumeInfo,
+ FvSetVolumeInfo
+ #endif
+ },
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ { NULL, NULL },
+ 0
+};
+
+
+//
+// FFS helper functions
+//
+
+EFI_STATUS
+GetFwVolHeader (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
+ )
+/*++
+
+Routine Description:
+ given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
+ copy the volume header into it.
+
+Arguments:
+ Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume
+ header
+ FwVolHeader - Pointer to pointer to allocated buffer in which the volume
+ header is returned.
+
+Returns:
+ EFI_OUT_OF_RESOURCES - No enough buffer could be allocated.
+ EFI_SUCCESS - Successfully read volume header to the allocated buffer.
+
+--*/
+
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER TempFvh;
+ UINTN FvhLength;
+ UINT8 *Buffer;
+
+
+ //
+ //Determine the real length of FV header
+ //
+ FvhLength = sizeof (EFI_FIRMWARE_VOLUME_HEADER);
+ Status = Fvb->Read (Fvb, 0, 0, &FvhLength, (UINT8 *)&TempFvh);
+
+ //
+ // Allocate a buffer for the caller
+ //
+ *FwVolHeader = CoreAllocateBootServicesPool (TempFvh.HeaderLength);
+ if (*FwVolHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Copy the standard header into the buffer
+ //
+ EfiCommonLibCopyMem (*FwVolHeader, &TempFvh, sizeof (EFI_FIRMWARE_VOLUME_HEADER));
+
+ //
+ // Read the rest of the header
+ //
+ FvhLength = TempFvh.HeaderLength - sizeof (EFI_FIRMWARE_VOLUME_HEADER);
+ Buffer = (UINT8 *)*FwVolHeader + sizeof (EFI_FIRMWARE_VOLUME_HEADER);
+ Status = Fvb->Read (Fvb, 0, sizeof (EFI_FIRMWARE_VOLUME_HEADER), &FvhLength, Buffer);
+ if (EFI_ERROR (Status)) {
+ //
+ // Read failed so free buffer
+ //
+ CoreFreePool (*FwVolHeader);
+ }
+
+ return Status;
+}
+
+
+STATIC
+VOID
+FreeFvDeviceResource (
+ IN FV_DEVICE *FvDevice
+ )
+/*++
+
+Routine Description:
+ Free FvDevice resource when error happens
+
+Arguments:
+ FvDevice - pointer to the FvDevice to be freed.
+
+Returns:
+ None.
+
+--*/
+{
+ FFS_FILE_LIST_ENTRY *FfsFileEntry;
+ EFI_LIST_ENTRY *NextEntry;
+
+ //
+ // Free File List Entry
+ //
+ FfsFileEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->FfsFileListHeader.ForwardLink;
+ while (&FfsFileEntry->Link != &FvDevice->FfsFileListHeader) {
+ NextEntry = (&FfsFileEntry->Link)->ForwardLink;
+
+ if (FfsFileEntry->StreamHandle != 0) {
+ //
+ // Close stream and free resources from SEP
+ //
+ FfsFileEntry->Sep->CloseSectionStream (FfsFileEntry->Sep, FfsFileEntry->StreamHandle);
+ }
+
+ CoreFreePool (FfsFileEntry);
+
+ FfsFileEntry = (FFS_FILE_LIST_ENTRY *)NextEntry;
+ }
+
+
+ //
+ // Free the cache
+ //
+ CoreFreePool (FvDevice->CachedFv);
+
+ //
+ // Free Volume Header
+ //
+ CoreFreePool (FvDevice->FwVolHeader);
+
+ return;
+}
+
+
+EFI_STATUS
+FvCheck (
+ IN OUT FV_DEVICE *FvDevice
+ )
+/*++
+
+Routine Description:
+ Check if a FV is consistent and allocate cache
+
+Arguments:
+ FvDevice - pointer to the FvDevice to be checked.
+
+Returns:
+ EFI_OUT_OF_RESOURCES - No enough buffer could be allocated.
+ EFI_SUCCESS - FV is consistent and cache is allocated.
+ EFI_VOLUME_CORRUPTED - File system is corrupted.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FVB_ATTRIBUTES FvbAttributes;
+ EFI_FV_BLOCK_MAP_ENTRY *BlockMap;
+ FFS_FILE_LIST_ENTRY *FfsFileEntry;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINT8 *CacheLocation;
+ UINTN LbaOffset;
+ UINTN Index;
+ EFI_LBA LbaIndex;
+ UINTN Size;
+ UINTN FileLength;
+ EFI_FFS_FILE_STATE FileState;
+ UINT8 *TopFvAddress;
+ UINTN TestLength;
+
+
+ Fvb = FvDevice->Fvb;
+ FwVolHeader = FvDevice->FwVolHeader;
+
+//*** AMI PORTING BEGIN ***//
+//Update function name to match the spec
+// Status = Fvb->GetVolumeAttributes (Fvb, &FvbAttributes);
+ Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
+//*** AMI PORTING END *****//
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Size is the size of the FV minus the head. We have already allocated
+ // the header to check to make sure the volume is valid
+ //
+ Size = (UINTN)(FwVolHeader->FvLength - FwVolHeader->HeaderLength);
+ FvDevice->CachedFv = CoreAllocateZeroBootServicesPool (Size);
+ if (FvDevice->CachedFv == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Remember a pointer to the end fo the CachedFv
+ //
+ FvDevice->EndOfCachedFv = FvDevice->CachedFv + Size;
+
+ //
+ // Copy FV minus header into memory using the block map we have all ready
+ // read into memory.
+ //
+ BlockMap = FwVolHeader->FvBlockMap;
+ CacheLocation = FvDevice->CachedFv;
+ LbaIndex = 0;
+ LbaOffset = FwVolHeader->HeaderLength;
+ while ((BlockMap->NumBlocks != 0) || (BlockMap->BlockLength != 0)) {
+
+ for (Index = 0; Index < BlockMap->NumBlocks; Index ++) {
+
+ Size = BlockMap->BlockLength;
+ if (Index == 0) {
+ //
+ // Cache does not include FV Header
+ //
+ Size -= LbaOffset;
+ }
+ Status = Fvb->Read (Fvb,
+ LbaIndex,
+ LbaOffset,
+ &Size,
+ CacheLocation
+ );
+ //
+ // Not check EFI_BAD_BUFFER_SIZE, for Size = BlockMap->BlockLength
+ //
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // After we skip Fv Header always read from start of block
+ //
+ LbaOffset = 0;
+
+ LbaIndex++;
+ CacheLocation += Size;
+ }
+ BlockMap++;
+ }
+
+ //
+ // Scan to check the free space & File list
+ //
+ if (FvbAttributes & EFI_FVB_ERASE_POLARITY) {
+ FvDevice->ErasePolarity = 1;
+ } else {
+ FvDevice->ErasePolarity = 0;
+ }
+
+
+ //
+ // go through the whole FV cache, check the consistence of the FV.
+ // Make a linked list off all the Ffs file headers
+ //
+ Status = EFI_SUCCESS;
+ InitializeListHead (&FvDevice->FfsFileListHeader);
+
+ //
+ // Build FFS list
+ //
+ FfsHeader = (EFI_FFS_FILE_HEADER *)FvDevice->CachedFv;
+ TopFvAddress = FvDevice->EndOfCachedFv;
+ while ((UINT8 *)FfsHeader < TopFvAddress) {
+
+ TestLength = TopFvAddress - ((UINT8 *)FfsHeader);
+ if (TestLength > sizeof (EFI_FFS_FILE_HEADER)) {
+ TestLength = sizeof (EFI_FFS_FILE_HEADER);
+ }
+
+ if (IsBufferErased (FvDevice->ErasePolarity, FfsHeader, TestLength)) {
+ //
+ // We have found the free space so we are done!
+ //
+ goto Done;
+ }
+
+ if (!IsValidFfsHeader (FvDevice->ErasePolarity, FfsHeader, &FileState)) {
+ if ((FileState == EFI_FILE_HEADER_INVALID) ||
+ (FileState == EFI_FILE_HEADER_CONSTRUCTION)) {
+ FfsHeader++;
+
+ continue;
+
+ } else {
+ //
+ // File system is corrputed
+ //
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Done;
+ }
+ }
+
+ if (!IsValidFfsFile (FvDevice->ErasePolarity, FfsHeader)) {
+ //
+ // File system is corrupted
+ //
+ Status = EFI_VOLUME_CORRUPTED;
+ goto Done;
+ }
+
+ //
+ // Size[3] is a three byte array, read 4 bytes and throw one away
+ //
+ FileLength = *(UINT32 *)&FfsHeader->Size[0] & 0x00FFFFFF;
+
+ FileState = GetFileState (FvDevice->ErasePolarity, FfsHeader);
+
+ //
+ // check for non-deleted file
+ //
+ if (FileState != EFI_FILE_DELETED) {
+ //
+ // Create a FFS list entry for each non-deleted file
+ //
+ FfsFileEntry = CoreAllocateZeroBootServicesPool (sizeof (FFS_FILE_LIST_ENTRY));
+ if (FfsFileEntry == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ FfsFileEntry->FfsHeader = FfsHeader;
+ InsertTailList (&FvDevice->FfsFileListHeader, &FfsFileEntry->Link);
+ }
+
+ FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FfsHeader) + FileLength);
+
+ //
+ // Adjust pointer to the next 8-byte aligned boundry.
+ //
+ FfsHeader = (EFI_FFS_FILE_HEADER *)(((UINTN)FfsHeader + 7) & ~0x07);
+
+ }
+
+Done:
+ if (EFI_ERROR (Status)) {
+ FreeFvDeviceResource (FvDevice);
+ }
+
+ return Status;
+}
+
+
+STATIC
+VOID
+EFIAPI
+NotifyFwVolBlock (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+ This notification function is invoked when an instance of the
+ EFI_FW_VOLUME_BLOCK_PROTOCOL is produced. It layers an instance of the
+ EFI_FIRMWARE_VOLUME_PROTOCOL on the same handle. This is the function where
+ the actual initialization of the EFI_FIRMWARE_VOLUME_PROTOCOL is done.
+
+Arguments:
+ Event - The event that occured
+ Context - For EFI compatiblity. Not used.
+
+Returns:
+
+ None.
+
+--*/
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINTN BufferSize;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ FV_DEVICE *FvDevice;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+
+ //
+ // Examine all new handles
+ //
+ for (;;) {
+ //
+ // Get the next handle
+ //
+ BufferSize = sizeof (Handle);
+ Status = CoreLocateHandle (
+ ByRegisterNotify,
+ NULL,
+ gEfiFwVolBlockNotifyReg,
+ &BufferSize,
+ &Handle
+ );
+
+ //
+ // If not found, we're done
+ //
+ if (EFI_NOT_FOUND == Status) {
+ break;
+ }
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Get the FirmwareVolumeBlock protocol on that handle
+ //
+ Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeBlockProtocolGuid, &Fvb);
+ ASSERT_EFI_ERROR (Status);
+
+
+ //
+ // Make sure the Fv Header is O.K.
+ //
+ Status = GetFwVolHeader (Fvb, &FwVolHeader);
+ if (EFI_ERROR (Status)) {
+ return;
+ }
+
+ if (!VerifyFvHeaderChecksum (FwVolHeader)) {
+ CoreFreePool (FwVolHeader);
+ continue;
+ }
+
+
+ //
+ // Check to see that the file system is indeed formatted in a way we can
+ // understand it...
+ //
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ if (!EfiCompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystemGuid)) {
+#else
+ if (!EfiCompareGuid (&FwVolHeader->FileSystemGuid, &gEfiFirmwareFileSystem2Guid)) {
+#endif
+ continue;
+ }
+
+ //
+ // Check if there is an FV protocol already installed in that handle
+ //
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolumeProtocolGuid, &Fv);
+ #else
+ Status = CoreHandleProtocol (Handle, &gEfiFirmwareVolume2ProtocolGuid, &Fv);
+ #endif
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Update Fv to use a new Fvb
+ //
+ FvDevice = _CR (Fv, FV_DEVICE, Fv);
+ if (FvDevice->Signature == FV_DEVICE_SIGNATURE) {
+ //
+ // Only write into our device structure if it's our device structure
+ //
+ FvDevice->Fvb = Fvb;
+ }
+
+ } else {
+ //
+ // No FwVol protocol on the handle so create a new one
+ //
+ FvDevice = CoreAllocateCopyPool (sizeof (FV_DEVICE), &mFvDevice);
+ if (FvDevice == NULL) {
+ return;
+ }
+
+ FvDevice->Fvb = Fvb;
+ FvDevice->Handle = Handle;
+ FvDevice->FwVolHeader = FwVolHeader;
+ FvDevice->Fv.ParentHandle = Fvb->ParentHandle;
+
+ //
+ // Install an New FV protocol on the existing handle
+ //
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ Status = CoreInstallProtocolInterface (
+ &Handle,
+ &gEfiFirmwareVolumeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &FvDevice->Fv
+ );
+ #else
+ Status = CoreInstallProtocolInterface (
+ &Handle,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &FvDevice->Fv
+ );
+
+ #endif
+ ASSERT_EFI_ERROR (Status);
+ }
+ }
+
+ return;
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolDriverInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This routine is the driver initialization entry point. It initializes the
+ libraries, and registers two notification functions. These notification
+ functions are responsible for building the FV stack dynamically.
+
+Arguments:
+ ImageHandle - The image handle.
+ SystemTable - The system table.
+
+Returns:
+ EFI_SUCCESS - Function successfully returned.
+
+--*/
+{
+ gEfiFwVolBlockEvent = CoreCreateProtocolNotifyEvent (
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ EFI_TPL_CALLBACK,
+ NotifyFwVolBlock,
+ NULL,
+ &gEfiFwVolBlockNotifyReg,
+ TRUE
+ );
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CORE_DXE/FwVolAttrib.c b/Core/CORE_DXE/FwVolAttrib.c
new file mode 100644
index 0000000..ab156df
--- /dev/null
+++ b/Core/CORE_DXE/FwVolAttrib.c
@@ -0,0 +1,244 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVolAttrib.c
+
+Abstract:
+
+ Implements get/set firmware volume attributes
+
+--*/
+
+#include "FwVolDriver.h"
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+
+EFI_STATUS
+EFIAPI
+FvGetVolumeAttributes (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully got volume attributes
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ EFI_FVB_ATTRIBUTES FvbAttributes;
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+ Fvb = FvDevice->Fvb;
+
+ if (FvDevice->CachedFv == NULL) {
+ Status = FvCheck (FvDevice);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // First get the Firmware Volume Block Attributes
+ //
+ Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
+
+ //
+ // Mask out Fvb bits that are not defined in FV
+ //
+ FvbAttributes &= 0xfffff0ff;
+
+ *Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes;
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+FvSetVolumeAttributes (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets current attributes for volume
+
+Arguments:
+ This - Calling context
+ Attributes - At input, contains attributes to be set. At output contains
+ new value of FV
+
+Returns:
+ EFI_UNSUPPORTED - Could not be set.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+#else
+
+EFI_STATUS
+EFIAPI
+FvGetVolumeAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully got volume attributes
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ EFI_FVB_ATTRIBUTES FvbAttributes;
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+ Fvb = FvDevice->Fvb;
+
+ if (FvDevice->CachedFv == NULL) {
+ Status = FvCheck (FvDevice);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // First get the Firmware Volume Block Attributes
+ //
+//*** AMI PORTING BEGIN ***//
+//Update function name to match the spec
+// Status = Fvb->GetVolumeAttributes (Fvb, &FvbAttributes);
+ Status = Fvb->GetAttributes (Fvb, &FvbAttributes);
+//*** AMI PORTING END *****//
+
+ //
+ // Mask out Fvb bits that are not defined in FV
+ //
+ FvbAttributes &= 0xfffff0ff;
+
+ *Attributes = (EFI_FV_ATTRIBUTES)FvbAttributes;
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvSetVolumeAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets current attributes for volume
+
+Arguments:
+ This - Calling context
+ Attributes - At input, contains attributes to be set. At output contains
+ new value of FV
+
+Returns:
+ EFI_UNSUPPORTED - Could not be set.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+FvGetVolumeInfo (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+ Return information of type InformationType for the requested firmware
+ volume.
+
+Arguments:
+ This - Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL.
+ InformationType - InformationType for requested.
+ BufferSize - On input, size of Buffer.On output, the amount of
+ data returned in Buffer.
+ Buffer - A poniter to the data buffer to return.
+Returns:
+ EFI_SUCCESS - Successfully got volume Information.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+FvSetVolumeInfo (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN CONST VOID *Buffer
+ )
+/*++
+
+Routine Description:
+ Set information of type InformationType for the requested firmware
+ volume.
+
+Arguments:
+ This - Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL.
+ InformationType - InformationType for requested.
+ BufferSize - On input, size of Buffer.On output, the amount of
+ data returned in Buffer.
+ Buffer - A poniter to the data buffer to return.
+Returns:
+ EFI_SUCCESS - Successfully set volume Information.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+#endif
+
diff --git a/Core/CORE_DXE/FwVolBlock.c b/Core/CORE_DXE/FwVolBlock.c
new file mode 100644
index 0000000..9f409ff
--- /dev/null
+++ b/Core/CORE_DXE/FwVolBlock.c
@@ -0,0 +1,790 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVolBlock.c
+
+Abstract:
+
+ Firmware Volume Block protocol.. Consumes FV hobs and creates
+ appropriate block protocols.
+
+ Also consumes NT_NON_MM_FV envinronment variable and produces appropriate
+ block protocols fro them also... (this is TBD)
+
+--*/
+
+#include "Tiano.h"
+#include "FwVolBlock.h"
+//*** AMI PORTING BEGIN ***//
+// This header contains FFS definitions that do not exist in in FFS.h and other Aptio4 headers
+#include "EfiFirmwareVolumeHeader.h"
+#include <Protocol/FlashProtocol.h>
+//*** AMI PORTING END *****//
+
+EFI_FW_VOL_BLOCK_DEVICE mFwVolBlock = {
+ FVB_DEVICE_SIGNATURE,
+ NULL,
+ {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_MEMMAP_DP,
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH)),
+ (UINT8)(sizeof (MEMMAP_DEVICE_PATH) >> 8),
+ EfiMemoryMappedIO,
+ (EFI_PHYSICAL_ADDRESS)0,
+ (EFI_PHYSICAL_ADDRESS)0,
+ },
+ {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ END_DEVICE_PATH_LENGTH,
+ 0
+ },
+ },
+ {
+ FwVolBlockGetAttributes,
+ (EFI_FVB_SET_ATTRIBUTES)FwVolBlockSetAttributes,
+ FwVolBlockGetPhysicalAddress,
+ FwVolBlockGetBlockSize,
+ FwVolBlockReadBlock,
+ (EFI_FVB_WRITE)FwVolBlockWriteBlock,
+ (EFI_FVB_ERASE_BLOCKS)FwVolBlockEraseBlock,
+ NULL
+ },
+ 0,
+ NULL,
+ 0,
+ 0
+};
+
+
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockGetAttributes (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - The firmware volume attributes were returned.
+
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ //
+ // Since we are read only, it's safe to get attributes data from our in-memory copy.
+ //
+ *Attributes = FvbDevice->FvbAttributes;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockSetAttributes (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_FVB_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Modifies the current settings of the firmware volume according to the input parameter.
+
+Arguments:
+ This - Calling context
+ Attributes - input buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - The firmware volume attributes were returned.
+ EFI_INVALID_PARAMETER - The attributes requested are in conflict with the capabilities as
+ declared in the firmware volume header.
+ EFI_UNSUPPORTED - Not supported.
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockEraseBlock (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+/*++
+
+Routine Description:
+ The EraseBlock() function erases one or more blocks as denoted by the
+variable argument list. The entire parameter list of blocks must be verified
+prior to erasing any blocks. If a block is requested that does not exist
+within the associated firmware volume (it has a larger index than the last
+block of the firmware volume), the EraseBlock() function must return
+EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+Arguments:
+ This - Calling context
+ ... - Starting LBA followed by Number of Lba to erase. a -1 to terminate
+ the list.
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed.
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and could not be
+ written. The firmware device may have been partially erased.
+ EFI_INVALID_PARAMETER - One or more of the LBAs listed in the variable argument list do
+ EFI_UNSUPPORTED - Not supported.
+
+--*/
+{
+//*** AMI PORTING BEGIN ***//
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ FLASH_PROTOCOL *FlashProtocol;
+ EFI_STATUS Status;
+ VA_LIST Marker;
+ EFI_LBA StartLba;
+ UINTN NumOfLba;
+ UINT64 i;
+ UINT8 *EraseAddress;
+ UINTN EraseSize;
+
+ Status = CoreLocateProtocol(&gFlashProtocolGuid, NULL, &FlashProtocol);
+ if(EFI_ERROR(Status))
+ return EFI_UNSUPPORTED;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+ //
+ // Check if This FW can be erased
+ //
+ if ((FvbDevice->FvbAttributes & EFI_FVB_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ VA_START(Marker, This);
+ do {
+ StartLba = VA_ARG(Marker, EFI_LBA);
+ if(StartLba == EFI_LBA_LIST_TERMINATOR)
+ break;
+
+ NumOfLba = VA_ARG(Marker, UINTN);
+ if(NumOfLba == 0)
+ return EFI_INVALID_PARAMETER;
+
+ for(i = StartLba; i < StartLba + NumOfLba; i++) {
+ if(i >= FvbDevice->NumBlocks)
+ return EFI_INVALID_PARAMETER;
+
+ EraseAddress = (UINT8 *)((UINTN)FvbDevice->BaseAddress + FvbDevice->LbaCache[(UINT32)i].Base);
+ EraseSize = FvbDevice->LbaCache[(UINT32)i].Length;
+ Status = FlashProtocol->Erase(EraseAddress, EraseSize);
+ if(EFI_ERROR(Status))
+ return EFI_DEVICE_ERROR;
+ }
+ } while(Status == EFI_SUCCESS);
+ VA_END(Marker);
+ return Status;
+//*** AMI PORTING END ***//
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockReadBlock (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+ Read the specified number of bytes from the block to the input buffer.
+
+Arguments:
+ This - Indicates the calling context.
+ Lba - The starting logical block index to read.
+ Offset - Offset into the block at which to begin reading.
+ NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
+ total size of the buffer. At exit, *NumBytes contains the
+ total number of bytes actually read.
+ Buffer - Pinter to a caller-allocated buffer that contains the destine
+ for the read.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully.
+ EFI_BAD_BUFFER_SIZE - The read was attempted across an LBA boundary.
+ EFI_ACCESS_DENIED - Access denied.
+ EFI_DEVICE_ERROR - The block device is malfunctioning and could not be read.
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ UINT8 *LbaOffset;
+ UINTN LbaStart;
+ UINTN NumOfBytesRead;
+ UINTN LbaIndex;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ //
+ // Check if This FW can be read
+ //
+ if ((FvbDevice->FvbAttributes & EFI_FVB_READ_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ LbaIndex = (UINTN)Lba;
+ if (LbaIndex >= FvbDevice->NumBlocks) {
+ //
+ // Invalid Lba, read nothing.
+ //
+ *NumBytes = 0;
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {
+ //
+ // all exceed boundry, read nothing.
+ //
+ *NumBytes = 0;
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NumOfBytesRead = *NumBytes;
+ if (Offset + NumOfBytesRead > FvbDevice->LbaCache[LbaIndex].Length) {
+ //
+ // partial exceed boundry, read data from current postion to end.
+ //
+ NumOfBytesRead = FvbDevice->LbaCache[LbaIndex].Length - Offset;
+ }
+
+ LbaStart = FvbDevice->LbaCache[LbaIndex].Base;
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);
+ LbaOffset = (UINT8 *)FwVolHeader + LbaStart + Offset;
+
+ //
+ // Perform read operation
+ //
+ EfiCommonLibCopyMem (Buffer, LbaOffset, NumOfBytesRead);
+
+ if (NumOfBytesRead == *NumBytes) {
+ return EFI_SUCCESS;
+ }
+
+ *NumBytes = NumOfBytesRead;
+ return EFI_BAD_BUFFER_SIZE;
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockWriteBlock (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+ Writes the specified number of bytes from the input buffer to the block.
+
+Arguments:
+ This - Indicates the calling context.
+ Lba - The starting logical block index to write to.
+ Offset - Offset into the block at which to begin writing.
+ NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
+ total size of the buffer. At exit, *NumBytes contains the
+ total number of bytes actually written.
+ Buffer - Pinter to a caller-allocated buffer that contains the source
+ for the write.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully.
+ EFI_BAD_BUFFER_SIZE - The write was attempted across an LBA boundary. On output,
+ NumBytes contains the total number of bytes actually written.
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
+ EFI_DEVICE_ERROR - The block device is malfunctioning and could not be written.
+ EFI_UNSUPPORTED - Not supported.
+--*/
+{
+//*** AMI PORTING BEGIN ***//
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ UINT8 *LbaOffset;
+ UINTN LbaStart;
+ UINTN NumOfBytesWritten;
+ UINTN LbaIndex;
+ EFI_STATUS Status;
+ FLASH_PROTOCOL *FlashProtocol;
+
+ Status = CoreLocateProtocol(&gFlashProtocolGuid, NULL, &FlashProtocol);
+ if(EFI_ERROR(Status))
+ return EFI_UNSUPPORTED;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ //
+ // Check if This FW can be written
+ //
+ if ((FvbDevice->FvbAttributes & EFI_FVB_WRITE_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ LbaIndex = (UINTN)Lba;
+ if (LbaIndex >= FvbDevice->NumBlocks) {
+ //
+ // Invalid Lba, write nothing.
+ //
+ *NumBytes = 0;
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (Offset > FvbDevice->LbaCache[LbaIndex].Length) {
+ //
+ // all exceed boundry, write nothing.
+ //
+ *NumBytes = 0;
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ NumOfBytesWritten = *NumBytes;
+ if (Offset + NumOfBytesWritten > FvbDevice->LbaCache[LbaIndex].Length) {
+ //
+ // partial exceed boundry, write data from current postion to end.
+ //
+ NumOfBytesWritten = FvbDevice->LbaCache[LbaIndex].Length - Offset;
+ }
+
+ LbaStart = FvbDevice->LbaCache[LbaIndex].Base;
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);
+ LbaOffset = (UINT8 *)FwVolHeader + LbaStart + Offset;
+
+ //
+ // Perform write operation
+ //
+ Status = FlashProtocol->Write(LbaOffset, NumOfBytesWritten, Buffer);
+ if(EFI_ERROR(Status))
+ return EFI_DEVICE_ERROR;
+
+ if (NumOfBytesWritten == *NumBytes) {
+ return EFI_SUCCESS;
+ }
+
+ *NumBytes = NumOfBytesWritten;
+ return EFI_BAD_BUFFER_SIZE;
+//*** AMI PORTING END ***//
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockGetPhysicalAddress (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+/*++
+
+Routine Description:
+ Get Fvb's base address.
+
+Arguments:
+ This - Indicates the calling context.
+ Address - Fvb device base address.
+
+Returns:
+ EFI_SUCCESS - Successfully got Fvb's base address.
+ EFI_UNSUPPORTED - Not supported.
+--*/
+{
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ if (FvbDevice->FvbAttributes & EFI_FVB_MEMORY_MAPPED) {
+ *Address = FvbDevice->BaseAddress;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockGetBlockSize (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumberOfBlocks
+ )
+/*++
+
+Routine Description:
+ Retrieves the size in bytes of a specific block within a firmware volume.
+
+Arguments:
+ This - Indicates the calling context.
+ Lba - Indicates the block for which to return the size.
+ BlockSize - Pointer to a caller-allocated UINTN in which the size of the
+ block is returned.
+ NumberOfBlocks - Pointer to a caller-allocated UINTN in which the number of
+ consecutive blocks starting with Lba is returned. All blocks
+ in this range have a size of BlockSize.
+Returns:
+ EFI_SUCCESS - The firmware volume base address is returned.
+ EFI_INVALID_PARAMETER - The requested LBA is out of range.
+--*/
+{
+ UINTN TotalBlocks;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ FvbDevice = FVB_DEVICE_FROM_THIS (This);
+
+ //
+ // Do parameter checking
+ //
+ if (Lba >= FvbDevice->NumBlocks) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)FvbDevice->BaseAddress);
+
+ PtrBlockMapEntry = FwVolHeader->FvBlockMap;
+
+ //
+ // Search the block map for the given block
+ //
+ TotalBlocks = 0;
+ while ((PtrBlockMapEntry->NumBlocks != 0) || (PtrBlockMapEntry->BlockLength !=0 )) {
+ TotalBlocks += PtrBlockMapEntry->NumBlocks;
+ if (Lba < TotalBlocks) {
+ //
+ // We find the range
+ //
+ break;
+ }
+
+ PtrBlockMapEntry++;
+ }
+
+ *BlockSize = PtrBlockMapEntry->BlockLength;
+ *NumberOfBlocks = TotalBlocks - (UINTN)Lba;
+
+ return EFI_SUCCESS;
+}
+
+
+#define SANE_MAX_FW_VOL_SIZE 0x40000000 //1GB
+#define SANE_MAX_FW_VOL_NO_BLOCKS SANE_MAX_FW_VOL_SIZE / sizeof(LBA_CACHE)
+
+
+EFI_STATUS
+ProduceFVBProtocolOnBuffer (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_HANDLE ParentHandle,
+ OUT EFI_HANDLE *FvProtocol OPTIONAL
+ )
+/*++
+
+Routine Description:
+ This routine produces a firmware volume block protocol on a given
+ buffer.
+
+Arguments:
+ BaseAddress - base address of the firmware volume image
+ Length - length of the firmware volume image
+ ParentHandle - handle of parent firmware volume, if this
+ image came from an FV image file in another
+ firmware volume (ala capsules)
+ FvProtocol - Firmware volume block protocol produced.
+
+Returns:
+ EFI_VOLUME_CORRUPTED - Volume corrupted.
+ EFI_OUT_OF_RESOURCES - No enough buffer to be allocated.
+ EFI_SUCCESS - Successfully produced a FVB protocol on given buffer.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDev;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ UINTN BlockIndex;
+ UINTN BlockIndex2;
+ UINTN LinearOffset;
+ EFI_FV_BLOCK_MAP_ENTRY *PtrBlockMapEntry;
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)BaseAddress;
+ //
+ // Validate FV Header, if not as expected, return
+ //
+ if (FwVolHeader->Signature != EFI_FVH_SIGNATURE || FwVolHeader->FvLength > SANE_MAX_FW_VOL_SIZE) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+ //
+ // Allocate EFI_FW_VOL_BLOCK_DEVICE
+ //
+ FvbDev = CoreAllocateCopyPool (sizeof (EFI_FW_VOL_BLOCK_DEVICE), &mFwVolBlock);
+ if (FvbDev == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FvbDev->BaseAddress = BaseAddress;
+ FvbDev->FvbAttributes = FwVolHeader->Attributes;
+ FvbDev->FwVolBlockInstance.ParentHandle = ParentHandle;
+
+ //
+ // Init the block caching fields of the device
+ // First, count the number of blocks
+ //
+ FvbDev->NumBlocks = 0;
+ for (PtrBlockMapEntry = FwVolHeader->FvBlockMap;
+ PtrBlockMapEntry->NumBlocks != 0;
+ PtrBlockMapEntry++) {
+ if(PtrBlockMapEntry->NumBlocks < SANE_MAX_FW_VOL_NO_BLOCKS - FvbDev->NumBlocks)
+ FvbDev->NumBlocks += PtrBlockMapEntry->NumBlocks;
+ else {
+ CoreFreePool (FvbDev);
+ return EFI_VOLUME_CORRUPTED;
+ }
+ }
+ //
+ // Second, allocate the cache
+ //
+ FvbDev->LbaCache = CoreAllocateBootServicesPool (FvbDev->NumBlocks * sizeof (LBA_CACHE));
+ if (FvbDev->LbaCache == NULL) {
+ CoreFreePool (FvbDev);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Last, fill in the cache with the linear address of the blocks
+ //
+ BlockIndex = 0;
+ LinearOffset = 0;
+ for (PtrBlockMapEntry = FwVolHeader->FvBlockMap;
+ PtrBlockMapEntry->NumBlocks != 0; PtrBlockMapEntry++) {
+ for (BlockIndex2 = 0; BlockIndex2 < PtrBlockMapEntry->NumBlocks; BlockIndex2++) {
+ FvbDev->LbaCache[BlockIndex].Base = LinearOffset;
+ FvbDev->LbaCache[BlockIndex].Length = PtrBlockMapEntry->BlockLength;
+ if(PtrBlockMapEntry->BlockLength <= FwVolHeader->FvLength - LinearOffset) {
+ LinearOffset += PtrBlockMapEntry->BlockLength;
+ BlockIndex++;
+ } else {
+ CoreFreePool (FvbDev->LbaCache);
+ CoreFreePool (FvbDev);
+ return EFI_VOLUME_CORRUPTED;
+ }
+ }
+ }
+
+ //
+ // Set up the devicepath
+ //
+ FvbDev->DevicePath.MemMapDevPath.StartingAddress = BaseAddress;
+ FvbDev->DevicePath.MemMapDevPath.EndingAddress = BaseAddress + FwVolHeader->FvLength - 1;
+
+ //
+ //
+ // Attach FvVolBlock Protocol to new handle
+ //
+ Status = CoreInstallMultipleProtocolInterfaces (
+ &FvbDev->Handle,
+ &gEfiFirmwareVolumeBlockProtocolGuid, &FvbDev->FwVolBlockInstance,
+ &gEfiDevicePathProtocolGuid, &FvbDev->DevicePath,
+ &gEfiFirmwareVolumeDispatchProtocolGuid, NULL,
+ NULL
+ );
+
+ //
+ // If they want the handle back, set it.
+ //
+ if (FvProtocol != NULL) {
+ *FvProtocol = FvbDev->Handle;
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockDriverInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This routine is the driver initialization entry point. It initializes the
+ libraries, consumes FV hobs and NT_NON_MM_FV environment variable and
+ produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.
+Arguments:
+ ImageHandle - The image handle.
+ SystemTable - The system table.
+Returns:
+ EFI_SUCCESS - Successfully initialized firmware volume block driver.
+--*/
+{
+ EFI_STATUS Status;
+ VOID *HobList;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ EFI_STATUS HobStatus;
+#if (PI_SPECIFICATION_VERSION >= 0x00010000)
+ EFI_GUID FileName;
+#endif
+ //
+ // First walk hobs and create appropriate FVs.
+ //
+ Status = CoreGetConfigTable (&gEfiHobListGuid, &HobList);
+ //
+ // Core Needs Firmware Volumes to function
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ BaseAddress = 0;
+ Length = 0;
+ HobStatus = GetNextFirmwareVolumeHob (
+ &HobList,
+ &BaseAddress,
+ &Length
+ );
+ while (!EFI_ERROR (HobStatus)) {
+ //
+ // Produce an FVB protocol for it
+ //
+ ProduceFVBProtocolOnBuffer (BaseAddress, Length, NULL, NULL);
+ HobStatus = GetNextFirmwareVolumeHob (
+ &HobList,
+ &BaseAddress,
+ &Length
+ );
+ }
+
+#if (PI_SPECIFICATION_VERSION >= 0x00010000)
+ //
+ // First walk hobs and create appropriate FVs.
+ //
+ Status = CoreGetConfigTable (&gEfiHobListGuid, &HobList);
+ //
+ // Core Needs Firmware Volumes to function
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ BaseAddress = 0;
+ Length = 0;
+
+ HobStatus = GetNextFirmwareVolume2Hob (
+ &HobList,
+ &BaseAddress,
+ &Length,
+ &FileName
+ );
+ while (!EFI_ERROR (HobStatus)) {
+ //
+ // Produce an FVB protocol for it
+ //
+ ProduceFVBProtocolOnBuffer (BaseAddress, Length, NULL, NULL);
+ HobStatus = GetNextFirmwareVolume2Hob (
+ &HobList,
+ &BaseAddress,
+ &Length,
+ &FileName
+ );
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+CoreProcessFirmwareVolume (
+ IN VOID *FvHeader,
+ IN UINTN Size,
+ OUT EFI_HANDLE *FVProtocolHandle
+ )
+/*++
+
+Routine Description:
+ This DXE service routine is used to process a firmware volume. In
+ particular, it can be called by BDS to process a single firmware
+ volume found in a capsule.
+
+Arguments:
+ FvHeader - pointer to a firmware volume header
+ Size - the size of the buffer pointed to by FvHeader
+ FVProtocolHandle - the handle on which a firmware volume protocol
+ was produced for the firmware volume passed in.
+
+Returns:
+ EFI_OUT_OF_RESOURCES - if an FVB could not be produced due to lack of
+ system resources
+ EFI_VOLUME_CORRUPTED - if the volume was corrupted
+ EFI_SUCCESS - a firmware volume protocol was produced for the
+ firmware volume
+
+--*/
+{
+ VOID *Ptr;
+ EFI_STATUS Status;
+
+ *FVProtocolHandle = NULL;
+ Status = ProduceFVBProtocolOnBuffer (
+ (EFI_PHYSICAL_ADDRESS) (UINTN) FvHeader,
+ (UINT64)Size,
+ NULL,
+ FVProtocolHandle
+ );
+ //
+ // Since in our implementation we use register-protocol-notify to put a
+ // FV protocol on the FVB protocol handle, we can't directly verify that
+ // the FV protocol was produced. Therefore here we will check the handle
+ // and make sure an FV protocol is on it. This indicates that all went
+ // well. Otherwise we have to assume that the volume was corrupted
+ // somehow.
+ //
+ if (!EFI_ERROR(Status)) {
+ Ptr = NULL;
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolumeProtocolGuid, &Ptr);
+ #else
+ Status = CoreHandleProtocol (*FVProtocolHandle, &gEfiFirmwareVolume2ProtocolGuid, &Ptr);
+ #endif
+ if (EFI_ERROR(Status) || (Ptr == NULL)) {
+ return EFI_VOLUME_CORRUPTED;
+ }
+ return EFI_SUCCESS;
+ }
+ return Status;
+}
+
+
diff --git a/Core/CORE_DXE/FwVolBlock.h b/Core/CORE_DXE/FwVolBlock.h
new file mode 100644
index 0000000..b3f26b7
--- /dev/null
+++ b/Core/CORE_DXE/FwVolBlock.h
@@ -0,0 +1,314 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVolBlock.h
+
+Abstract:
+
+ Firmware Volume Block protocol.. Consumes FV hobs and creates
+ appropriate block protocols.
+
+ Also consumes NT_NON_MM_FV envinronment variable and produces appropriate
+ block protocols fro them also... (this is TBD)
+
+--*/
+
+#ifndef _FWVOL_BLOCK_H_
+#define _FWVOL_BLOCK_H_
+
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
+#include EFI_PROTOCOL_DEFINITION (DevicePath)
+#include "Peihob.h"
+#include "EfiHobLib.h"
+#include "DxeCore.h"
+
+#include EFI_GUID_DEFINITION (Hob)
+
+
+
+#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32('_','F','V','B')
+
+typedef struct {
+ UINTN Base;
+ UINTN Length;
+} LBA_CACHE;
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_DEVICE_PATH;
+
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ FV_DEVICE_PATH DevicePath;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
+ UINTN NumBlocks;
+ LBA_CACHE *LbaCache;
+ UINT32 FvbAttributes;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+#define FVB_DEVICE_FROM_THIS(a) \
+ CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockDriverInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+Routine Description:
+ This routine is the driver initialization entry point. It initializes the
+ libraries, consumes FV hobs and NT_NON_MM_FV environment variable and
+ produces instances of FW_VOL_BLOCK_PROTOCOL as appropriate.
+Arguments:
+ ImageHandle - The image handle.
+ SystemTable - The system table.
+Returns:
+ EFI_SUCCESS - Successfully initialized firmware volume block driver.
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockGetAttributes (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves Volume attributes. No polarity translations are done.
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - The firmware volume attributes were returned.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockSetAttributes (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_FVB_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Modifies the current settings of the firmware volume according to the input parameter.
+
+Arguments:
+ This - Calling context
+ Attributes - input buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - The firmware volume attributes were returned.
+ EFI_INVALID_PARAMETER - The attributes requested are in conflict with the capabilities as
+ declared in the firmware volume header.
+ EFI_UNSUPPORTED - Not supported.
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockEraseBlock (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ ...
+ )
+/*++
+
+Routine Description:
+ The EraseBlock() function erases one or more blocks as denoted by the
+variable argument list. The entire parameter list of blocks must be verified
+prior to erasing any blocks. If a block is requested that does not exist
+within the associated firmware volume (it has a larger index than the last
+block of the firmware volume), the EraseBlock() function must return
+EFI_INVALID_PARAMETER without modifying the contents of the firmware volume.
+
+Arguments:
+ This - Calling context
+ ... - Starting LBA followed by Number of Lba to erase. a -1 to terminate
+ the list.
+
+Returns:
+ EFI_SUCCESS - The erase request was successfully completed.
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
+ EFI_DEVICE_ERROR - The block device is not functioning correctly and could not be
+ written. The firmware device may have been partially erased.
+ EFI_INVALID_PARAMETER - One or more of the LBAs listed in the variable argument list do
+ EFI_UNSUPPORTED - Not supported.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockReadBlock (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+ Read the specified number of bytes from the block to the input buffer.
+
+Arguments:
+ This - Indicates the calling context.
+ Lba - The starting logical block index to read.
+ Offset - Offset into the block at which to begin reading.
+ NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
+ total size of the buffer. At exit, *NumBytes contains the
+ total number of bytes actually read.
+ Buffer - Pinter to a caller-allocated buffer that contains the destine
+ for the read.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was read successfully.
+ EFI_BAD_BUFFER_SIZE - The read was attempted across an LBA boundary.
+ EFI_ACCESS_DENIED - Access denied.
+ EFI_DEVICE_ERROR - The block device is malfunctioning and could not be read.
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockWriteBlock (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ IN UINTN Offset,
+ IN OUT UINTN *NumBytes,
+ IN UINT8 *Buffer
+ )
+/*++
+
+Routine Description:
+ Writes the specified number of bytes from the input buffer to the block.
+
+Arguments:
+ This - Indicates the calling context.
+ Lba - The starting logical block index to write to.
+ Offset - Offset into the block at which to begin writing.
+ NumBytes - Pointer to a UINT32. At entry, *NumBytes contains the
+ total size of the buffer. At exit, *NumBytes contains the
+ total number of bytes actually written.
+ Buffer - Pinter to a caller-allocated buffer that contains the source
+ for the write.
+
+Returns:
+ EFI_SUCCESS - The firmware volume was written successfully.
+ EFI_BAD_BUFFER_SIZE - The write was attempted across an LBA boundary. On output,
+ NumBytes contains the total number of bytes actually written.
+ EFI_ACCESS_DENIED - The firmware volume is in the WriteDisabled state.
+ EFI_DEVICE_ERROR - The block device is malfunctioning and could not be written.
+ EFI_UNSUPPORTED - Not supported.
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockGetPhysicalAddress (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+/*++
+
+Routine Description:
+ Get Fvb's base address.
+
+Arguments:
+ This - Indicates the calling context.
+ Address - Fvb device base address.
+
+Returns:
+ EFI_SUCCESS - Successfully got Fvb's base address.
+ EFI_UNSUPPORTED - Not supported.
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FwVolBlockGetBlockSize (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *This,
+ IN EFI_LBA Lba,
+ OUT UINTN *BlockSize,
+ OUT UINTN *NumberOfBlocks
+ )
+/*++
+
+Routine Description:
+ Retrieves the size in bytes of a specific block within a firmware volume.
+
+Arguments:
+ This - Indicates the calling context.
+ Lba - Indicates the block for which to return the size.
+ BlockSize - Pointer to a caller-allocated UINTN in which the size of the
+ block is returned.
+ NumberOfBlocks - Pointer to a caller-allocated UINTN in which the number of
+ consecutive blocks starting with Lba is returned. All blocks
+ in this range have a size of BlockSize.
+Returns:
+ EFI_SUCCESS - The firmware volume base address is returned.
+ EFI_INVALID_PARAMETER - The requested LBA is out of range.
+--*/
+;
+
+EFI_STATUS
+ProduceFVBProtocolOnBuffer (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_HANDLE ParentHandle,
+ OUT EFI_HANDLE *FvProtocolHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+ This routine produces a firmware volume block protocol on a given
+ buffer.
+
+Arguments:
+ BaseAddress - base address of the firmware volume image
+ Length - length of the firmware volume image
+ ParentHandle - handle of parent firmware volume, if this
+ image came from an FV image file in another
+ firmware volume (ala capsules)
+ FvProtocolHandle - Firmware volume block protocol produced.
+
+Returns:
+ EFI_VOLUME_CORRUPTED - Volume corrupted.
+ EFI_OUT_OF_RESOURCES - No enough buffer to be allocated.
+ EFI_SUCCESS - Successfully produced a FVB protocol on given buffer.
+
+--*/
+;
+
+#endif
diff --git a/Core/CORE_DXE/FwVolDriver.h b/Core/CORE_DXE/FwVolDriver.h
new file mode 100644
index 0000000..6404e3b
--- /dev/null
+++ b/Core/CORE_DXE/FwVolDriver.h
@@ -0,0 +1,772 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVolDriver.h
+
+Abstract:
+
+ Firmware File System protocol. Layers on top of Firmware
+ Block protocol to produce a file abstraction of FV based files.
+
+--*/
+
+#ifndef __FWVOL_H
+#define __FWVOL_H
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "EfiFirmwareFileSystem.h"
+#include "EfiFirmwareVolumeHeader.h"
+
+//
+// Consumed protocol
+//
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolumeBlock)
+#include EFI_PROTOCOL_DEFINITION (SectionExtraction)
+
+//
+// Consumed GUID & Produced protocol
+//
+#include EFI_GUID_DEFINITION (FirmwareFileSystem)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume)
+#include EFI_GUID_DEFINITION (FirmwareFileSystem2)
+#include EFI_PROTOCOL_DEFINITION (FirmwareVolume2)
+
+
+//
+// Used to track all non-deleted files
+//
+typedef struct {
+ EFI_LIST_ENTRY Link;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINTN StreamHandle;
+ EFI_SECTION_EXTRACTION_PROTOCOL *Sep;
+} FFS_FILE_LIST_ENTRY;
+
+typedef struct {
+ UINTN Signature;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb;
+ EFI_HANDLE Handle;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL Fv;
+#endif
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ UINT8 *CachedFv;
+ UINT8 *EndOfCachedFv;
+
+ FFS_FILE_LIST_ENTRY *LastKey;
+
+ EFI_LIST_ENTRY FfsFileListHeader;
+
+ UINT8 ErasePolarity;
+} FV_DEVICE;
+
+#define FV_DEVICE_FROM_THIS(a) CR(a, FV_DEVICE, Fv, FV_DEVICE_SIGNATURE)
+
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+
+EFI_STATUS
+EFIAPI
+FvGetVolumeAttributes (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully got volume attributes
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvSetVolumeAttributes (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets current attributes for volume
+
+Arguments:
+ This - Calling context
+ Attributes - At input, contains attributes to be set. At output contains
+ new value of FV
+
+Returns:
+ EFI_UNSUPPORTED - Could not be set.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvGetNextFile (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN OUT VOID *Key,
+ IN OUT EFI_FV_FILETYPE *FileType,
+ OUT EFI_GUID *NameGuid,
+ OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
+ OUT UINTN *Size
+ )
+/*++
+
+Routine Description:
+ Given the input key, search for the next matching file in the volume.
+
+Arguments:
+ This - Indicates the calling context.
+ FileType - FileType is a pointer to a caller allocated
+ EFI_FV_FILETYPE. The GetNextFile() API can filter it's
+ search for files based on the value of *FileType input.
+ A *FileType input of 0 causes GetNextFile() to search for
+ files of all types. If a file is found, the file's type
+ is returned in *FileType. *FileType is not modified if
+ no file is found.
+ Key - Key is a pointer to a caller allocated buffer that
+ contains implementation specific data that is used to
+ track where to begin the search for the next file.
+ The size of the buffer must be at least This->KeySize
+ bytes long. To reinitialize the search and begin from
+ the beginning of the firmware volume, the entire buffer
+ must be cleared to zero. Other than clearing the buffer
+ to initiate a new search, the caller must not modify the
+ data in the buffer between calls to GetNextFile().
+ NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
+ If a file is found, the file's name is returned in
+ *NameGuid. *NameGuid is not modified if no file is
+ found.
+ Attributes - Attributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
+ attributes are returned in *Attributes. *Attributes is
+ not modified if no file is found.
+ Size - Size is a pointer to a caller allocated UINTN.
+ If a file is found, the file's size is returned in *Size.
+ *Size is not modified if no file is found.
+
+Returns:
+ EFI_SUCCESS - Successfully find the file.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Fv could not read.
+ EFI_NOT_FOUND - No matching file found.
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FvReadFile (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FV_FILETYPE *FoundType,
+ OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+ Locates a file in the firmware volume and
+ copies it to the supplied buffer.
+
+Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ Buffer - Buffer is a pointer to pointer to a buffer in
+ which the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated
+ UINTN. On input *BufferSize indicates the size
+ in bytes of the memory region pointed to by
+ Buffer. On output, *BufferSize contains the number
+ of bytes required to read the file.
+ FoundType - FoundType is a pointer to a caller allocated
+ EFI_FV_FILETYPE that on successful return from Read()
+ contains the type of file read. This output reflects
+ the file type irrespective of the value of the
+ SectionType input.
+ FileAttributes - FileAttributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. On successful return from
+ Read(), *FileAttributes contains the attributes of
+ the file read.
+ AuthenticationStatus - AuthenticationStatus is a pointer to a caller
+ allocated UINTN in which the authentication status
+ is returned.
+Returns:
+ EFI_SUCCESS - Successfully read to memory buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvReadFileSection (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+ Routine Description:
+ Locates a section in a given FFS File and
+ copies it to the supplied buffer (not including section header).
+
+ Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ SectionType - Indicates the section type to return.
+ SectionInstance - Indicates which instance of sections with a type of
+ SectionType to return.
+ Buffer - Buffer is a pointer to pointer to a buffer in which
+ the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated UINTN.
+ AuthenticationStatus -AuthenticationStatus is a pointer to a caller
+ allocated UINT32 in which the authentication status
+ is returned.
+
+ Returns:
+ EFI_SUCCESS - Successfully read the file section into buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Section not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvWriteFile (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN UINT32 NumberOfFiles,
+ IN EFI_FV_WRITE_POLICY WritePolicy,
+ IN EFI_FV_WRITE_FILE_DATA *FileData
+ )
+/*++
+
+ Routine Description:
+ Writes one or more files to the firmware volume.
+
+ Arguments:
+ This - Indicates the calling context.
+ WritePolicy - WritePolicy indicates the level of reliability for
+ the write in the event of a power failure or other
+ system failure during the write operation.
+ FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
+ Each element of FileData[] represents a file to be written.
+
+ Returns:
+ EFI_SUCCESS - Files successfully written to firmware volume
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_WRITE_PROTECTED - Write protected.
+ EFI_NOT_FOUND - Not found.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_UNSUPPORTED - This function not supported.
+
+--*/
+;
+
+#else
+
+EFI_STATUS
+EFIAPI
+FvGetVolumeAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Retrieves attributes, insures positive polarity of attribute bits, returns
+ resulting attributes in output parameter
+
+Arguments:
+ This - Calling context
+ Attributes - output buffer which contains attributes
+
+Returns:
+ EFI_SUCCESS - Successfully got volume attributes
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvSetVolumeAttributes (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN OUT EFI_FV_ATTRIBUTES *Attributes
+ )
+/*++
+
+Routine Description:
+ Sets current attributes for volume
+
+Arguments:
+ This - Calling context
+ Attributes - At input, contains attributes to be set. At output contains
+ new value of FV
+
+Returns:
+ EFI_UNSUPPORTED - Could not be set.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvGetNextFile (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN OUT VOID *Key,
+ IN OUT EFI_FV_FILETYPE *FileType,
+ OUT EFI_GUID *NameGuid,
+ OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
+ OUT UINTN *Size
+ )
+/*++
+
+Routine Description:
+ Given the input key, search for the next matching file in the volume.
+
+Arguments:
+ This - Indicates the calling context.
+ FileType - FileType is a pointer to a caller allocated
+ EFI_FV_FILETYPE. The GetNextFile() API can filter it's
+ search for files based on the value of *FileType input.
+ A *FileType input of 0 causes GetNextFile() to search for
+ files of all types. If a file is found, the file's type
+ is returned in *FileType. *FileType is not modified if
+ no file is found.
+ Key - Key is a pointer to a caller allocated buffer that
+ contains implementation specific data that is used to
+ track where to begin the search for the next file.
+ The size of the buffer must be at least This->KeySize
+ bytes long. To reinitialize the search and begin from
+ the beginning of the firmware volume, the entire buffer
+ must be cleared to zero. Other than clearing the buffer
+ to initiate a new search, the caller must not modify the
+ data in the buffer between calls to GetNextFile().
+ NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
+ If a file is found, the file's name is returned in
+ *NameGuid. *NameGuid is not modified if no file is
+ found.
+ Attributes - Attributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
+ attributes are returned in *Attributes. *Attributes is
+ not modified if no file is found.
+ Size - Size is a pointer to a caller allocated UINTN.
+ If a file is found, the file's size is returned in *Size.
+ *Size is not modified if no file is found.
+
+Returns:
+ EFI_SUCCESS - Successfully find the file.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Fv could not read.
+ EFI_NOT_FOUND - No matching file found.
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FvReadFile (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FV_FILETYPE *FoundType,
+ OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+ Locates a file in the firmware volume and
+ copies it to the supplied buffer.
+
+Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ Buffer - Buffer is a pointer to pointer to a buffer in
+ which the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated
+ UINTN. On input *BufferSize indicates the size
+ in bytes of the memory region pointed to by
+ Buffer. On output, *BufferSize contains the number
+ of bytes required to read the file.
+ FoundType - FoundType is a pointer to a caller allocated
+ EFI_FV_FILETYPE that on successful return from Read()
+ contains the type of file read. This output reflects
+ the file type irrespective of the value of the
+ SectionType input.
+ FileAttributes - FileAttributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. On successful return from
+ Read(), *FileAttributes contains the attributes of
+ the file read.
+ AuthenticationStatus - AuthenticationStatus is a pointer to a caller
+ allocated UINTN in which the authentication status
+ is returned.
+Returns:
+ EFI_SUCCESS - Successfully read to memory buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvReadFileSection (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+ Routine Description:
+ Locates a section in a given FFS File and
+ copies it to the supplied buffer (not including section header).
+
+ Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ SectionType - Indicates the section type to return.
+ SectionInstance - Indicates which instance of sections with a type of
+ SectionType to return.
+ Buffer - Buffer is a pointer to pointer to a buffer in which
+ the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated UINTN.
+ AuthenticationStatus -AuthenticationStatus is a pointer to a caller
+ allocated UINT32 in which the authentication status
+ is returned.
+
+ Returns:
+ EFI_SUCCESS - Successfully read the file section into buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Section not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+FvWriteFile (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN UINT32 NumberOfFiles,
+ IN EFI_FV_WRITE_POLICY WritePolicy,
+ IN EFI_FV_WRITE_FILE_DATA *FileData
+ )
+/*++
+
+ Routine Description:
+ Writes one or more files to the firmware volume.
+
+ Arguments:
+ This - Indicates the calling context.
+ WritePolicy - WritePolicy indicates the level of reliability for
+ the write in the event of a power failure or other
+ system failure during the write operation.
+ FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
+ Each element of FileData[] represents a file to be written.
+
+ Returns:
+ EFI_SUCCESS - Files successfully written to firmware volume
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_WRITE_PROTECTED - Write protected.
+ EFI_NOT_FOUND - Not found.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_UNSUPPORTED - This function not supported.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FvGetVolumeInfo (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+ Return information of type InformationType for the requested firmware
+ volume.
+
+Arguments:
+ This - Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL.
+ InformationType - InformationType for requested.
+ BufferSize - On input, size of Buffer.On output, the amount of
+ data returned in Buffer.
+ Buffer - A poniter to the data buffer to return.
+Returns:
+ EFI_SUCCESS - Successfully got volume Information.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FvSetVolumeInfo (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN CONST VOID *Buffer
+ )
+/*++
+
+Routine Description:
+ Set information of type InformationType for the requested firmware
+ volume.
+
+Arguments:
+ This - Pointer to EFI_FIRMWARE_VOLUME2_PROTOCOL.
+ InformationType - InformationType for requested.
+ BufferSize - On input, size of Buffer.On output, the amount of
+ data returned in Buffer.
+ Buffer - A poniter to the data buffer to return.
+Returns:
+ EFI_SUCCESS - Successfully set volume Information.
+
+--*/
+;
+
+
+#endif
+
+
+//
+//Internal functions
+//
+typedef enum {
+ EfiCheckSumUint8 = 0,
+ EfiCheckSumUint16 = 1,
+ EfiCheckSumUint32 = 2,
+ EfiCheckSumUint64 = 3,
+ EfiCheckSumMaximum = 4
+} EFI_CHECKSUM_TYPE;
+
+
+BOOLEAN
+IsBufferErased (
+ IN UINT8 ErasePolarity,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+ Check if a block of buffer is erased
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ Buffer - The buffer to be checked
+ BufferSize - Size of the buffer in bytes
+
+Returns:
+ TRUE - The block of buffer is erased
+ FALSE - The block of buffer is not erased
+
+--*/
+;
+
+EFI_FFS_FILE_STATE
+GetFileState (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+ Get the FFS file state by checking the highest bit set in the header's state field
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ FfsHeader - Points to the FFS file header
+
+Returns:
+ FFS File state
+
+--*/
+;
+
+VOID
+SetFileState (
+ IN UINT8 State,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+ Set the FFS file state.
+
+Arguments:
+ State - The state to be set.
+ FfsHeader - Points to the FFS file header
+
+Returns:
+ None.
+
+--*/
+;
+
+BOOLEAN
+VerifyFvHeaderChecksum (
+ IN EFI_FIRMWARE_VOLUME_HEADER *FvHeader
+ )
+/*++
+
+Routine Description:
+ Verify checksum of the firmware volume header
+
+Arguments:
+ FvHeader - Points to the firmware volume header to be checked
+
+Returns:
+ TRUE - Checksum verification passed
+ FALSE - Checksum verification failed
+
+--*/
+;
+
+BOOLEAN
+IsValidFfsHeader (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ OUT EFI_FFS_FILE_STATE *FileState
+ )
+/*++
+
+Routine Description:
+ Check if it's a valid FFS file header
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ FfsHeader - Points to the FFS file header to be checked
+ FileState - FFS file state to be returned
+
+Returns:
+ TRUE - Valid FFS file header
+ FALSE - Invalid FFS file header
+
+--*/
+;
+
+BOOLEAN
+IsValidFfsFile (
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+ Check if it's a valid FFS file.
+ Here we are sure that it has a valid FFS file header since we must call IsValidFfsHeader() first.
+
+Arguments:
+ ErasePolarity - Erase polarity attribute of the firmware volume
+ FfsHeader - Points to the FFS file to be checked
+
+Returns:
+ TRUE - Valid FFS file
+ FALSE - Invalid FFS file
+
+--*/
+;
+
+EFI_STATUS
+GetFwVolHeader (
+ IN EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *Fvb,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
+ )
+/*++
+
+Routine Description:
+ given the supplied FW_VOL_BLOCK_PROTOCOL, allocate a buffer for output and
+ copy the volume header into it.
+
+Arguments:
+ Fvb - The FW_VOL_BLOCK_PROTOCOL instance from which to read the volume
+ header
+ FwVolHeader - Pointer to pointer to allocated buffer in which the volume
+ header is returned.
+
+Returns:
+ Status code.
+
+--*/
+;
+
+
+EFI_STATUS
+FvCheck (
+ IN OUT FV_DEVICE *FvDevice
+ )
+/*++
+
+Routine Description:
+ Check if a FV is consistent and allocate cache
+
+Arguments:
+ FvDevice - pointer to the FvDevice to be checked.
+
+Returns:
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+ EFI_SUCCESS - FV is consistent and cache is allocated.
+ EFI_VOLUME_CORRUPTED - File system is corrupted.
+
+--*/
+;
+
+#endif
diff --git a/Core/CORE_DXE/FwVolRead.c b/Core/CORE_DXE/FwVolRead.c
new file mode 100644
index 0000000..dced47f
--- /dev/null
+++ b/Core/CORE_DXE/FwVolRead.c
@@ -0,0 +1,993 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVolRead.c
+
+Abstract:
+
+ Implements read firmware file
+
+--*/
+
+#include "FwVolDriver.h"
+#include "DxeCore.h"
+
+/*++
+
+Required Alignment Alignment Value in FFS Alignment Value in
+(bytes) Attributes Field Firmware Volume Interfaces
+1 0 0
+2 0 1
+4 0 2
+8 0 3
+16 1 4
+128 2 7
+512 3 9
+1 KB 4 10
+4 KB 5 12
+32 KB 6 15
+64 KB 7 16
+
+--*/
+
+UINT8 mFvAttributes[] = {0, 4, 7, 9, 10, 12, 15, 16};
+
+
+STATIC
+EFI_FV_FILE_ATTRIBUTES
+FfsAttributes2FvFileAttributes (
+ IN EFI_FFS_FILE_ATTRIBUTES FfsAttributes
+ )
+/*++
+
+ Routine Description:
+ Convert the FFS File Attributes to FV File Attributes
+
+ Arguments:
+ FfsAttributes - The attributes of UINT8 type.
+
+ Returns:
+ The attributes of EFI_FV_FILE_ATTRIBUTES
+
+--*/
+{
+ FfsAttributes = (EFI_FFS_FILE_ATTRIBUTES)((FfsAttributes & FFS_ATTRIB_DATA_ALIGNMENT) >> 3);
+ ASSERT (FfsAttributes < 8);
+
+ return (EFI_FV_FILE_ATTRIBUTES) mFvAttributes[FfsAttributes];
+}
+
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+
+EFI_STATUS
+EFIAPI
+FvGetNextFile (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN OUT VOID *Key,
+ IN OUT EFI_FV_FILETYPE *FileType,
+ OUT EFI_GUID *NameGuid,
+ OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
+ OUT UINTN *Size
+ )
+/*++
+
+Routine Description:
+ Given the input key, search for the next matching file in the volume.
+
+Arguments:
+ This - Indicates the calling context.
+ FileType - FileType is a pointer to a caller allocated
+ EFI_FV_FILETYPE. The GetNextFile() API can filter it's
+ search for files based on the value of *FileType input.
+ A *FileType input of 0 causes GetNextFile() to search for
+ files of all types. If a file is found, the file's type
+ is returned in *FileType. *FileType is not modified if
+ no file is found.
+ Key - Key is a pointer to a caller allocated buffer that
+ contains implementation specific data that is used to
+ track where to begin the search for the next file.
+ The size of the buffer must be at least This->KeySize
+ bytes long. To reinitialize the search and begin from
+ the beginning of the firmware volume, the entire buffer
+ must be cleared to zero. Other than clearing the buffer
+ to initiate a new search, the caller must not modify the
+ data in the buffer between calls to GetNextFile().
+ NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
+ If a file is found, the file's name is returned in
+ *NameGuid. *NameGuid is not modified if no file is
+ found.
+ Attributes - Attributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
+ attributes are returned in *Attributes. *Attributes is
+ not modified if no file is found.
+ Size - Size is a pointer to a caller allocated UINTN.
+ If a file is found, the file's size is returned in *Size.
+ *Size is not modified if no file is found.
+
+Returns:
+ EFI_SUCCESS - Successfully find the file.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Fv could not read.
+ EFI_NOT_FOUND - No matching file found.
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FV_ATTRIBUTES FvAttributes;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINTN *KeyValue;
+ EFI_LIST_ENTRY *Link;
+ FFS_FILE_LIST_ENTRY *FfsFileEntry;
+ UINTN FileLength;
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+
+ Status = FvGetVolumeAttributes (This, &FvAttributes);
+ if (EFI_ERROR (Status)){
+ return Status;
+ }
+
+ //
+ // Check if read operation is enabled
+ //
+ if ((FvAttributes & EFI_FV_READ_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//PI 1.1 ++
+#if PI_SPECIFICATION_VERSION >= 0x0001000A
+ if (*FileType > EFI_FV_FILETYPE_SMM_CORE) {
+#else
+ if (*FileType > EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
+#endif
+//PI 1.1 --
+//*** AMI PORTING END *****//
+ //
+ // File type needs to be in 0 - 0x0B
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ KeyValue = (UINTN *)Key;
+ for (;;) {
+ if (*KeyValue == 0) {
+ //
+ // Search for 1st matching file
+ //
+ Link = &FvDevice->FfsFileListHeader;
+ } else {
+ //
+ // Key is pointer to FFsFileEntry, so get next one
+ //
+ Link = (EFI_LIST_ENTRY *)(*KeyValue);
+ }
+
+ if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {
+ //
+ // Next is end of list so we did not find data
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
+
+ //
+ // remember the key
+ //
+ *KeyValue = (UINTN)FfsFileEntry;
+
+ if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {
+ //
+ // we ignore pad files
+ //
+ continue;
+ }
+
+ if (*FileType == 0) {
+ //
+ // Process all file types so we have a match
+ //
+ break;
+ }
+
+ if (*FileType == FfsFileHeader->Type) {
+ //
+ // Found a matching file type
+ //
+ break;
+ }
+
+ }
+
+ //
+ // Return FileType, NameGuid, and Attributes
+ //
+ *FileType = FfsFileHeader->Type;
+ EfiCommonLibCopyMem (NameGuid, &FfsFileHeader->Name, sizeof (EFI_GUID));
+ *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
+
+ //
+ // Read four bytes out of the 3 byte array and throw out extra data
+ //
+ FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;
+
+ //
+ // we need to substract the header size
+ //
+ *Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);
+
+ if (FfsFileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
+ //
+ // If tail is present substract it's size;
+ //
+ *Size -= sizeof(EFI_FFS_FILE_TAIL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+FvReadFile (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FV_FILETYPE *FoundType,
+ OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+ Locates a file in the firmware volume and
+ copies it to the supplied buffer.
+
+Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ Buffer - Buffer is a pointer to pointer to a buffer in
+ which the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated
+ UINTN. On input *BufferSize indicates the size
+ in bytes of the memory region pointed to by
+ Buffer. On output, *BufferSize contains the number
+ of bytes required to read the file.
+ FoundType - FoundType is a pointer to a caller allocated
+ EFI_FV_FILETYPE that on successful return from Read()
+ contains the type of file read. This output reflects
+ the file type irrespective of the value of the
+ SectionType input.
+ FileAttributes - FileAttributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. On successful return from
+ Read(), *FileAttributes contains the attributes of
+ the file read.
+ AuthenticationStatus - AuthenticationStatus is a pointer to a caller
+ allocated UINTN in which the authentication status
+ is returned.
+Returns:
+ EFI_SUCCESS - Successfully read to memory buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_GUID SearchNameGuid;
+ EFI_FV_FILETYPE LocalFoundType;
+ EFI_FV_FILE_ATTRIBUTES LocalAttributes;
+ UINTN FileSize;
+ UINT8 *SrcPtr;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINTN InputBufferSize;
+
+ if (NULL == NameGuid) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+
+
+ //
+ // Keep looking until we find the matching NameGuid.
+ // The Key is really an FfsFileEntry
+ //
+ FvDevice->LastKey = 0;
+ do {
+ LocalFoundType = 0;
+ Status = FvGetNextFile (
+ This,
+ &FvDevice->LastKey,
+ &LocalFoundType,
+ &SearchNameGuid,
+ &LocalAttributes,
+ &FileSize
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+ } while (!EfiCompareGuid (&SearchNameGuid, NameGuid));
+
+ //
+ // Get a pointer to the header
+ //
+ FfsHeader = FvDevice->LastKey->FfsHeader;
+
+ //
+ // Remember callers buffer size
+ //
+ InputBufferSize = *BufferSize;
+
+ //
+ // Calculate return values
+ //
+ *FoundType = FfsHeader->Type;
+ *FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
+ *AuthenticationStatus = 0;
+ *BufferSize = FileSize;
+
+ if (Buffer == NULL) {
+ //
+ // If Buffer is NULL, we only want to get the information colected so far
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Skip over file header
+ //
+ SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
+
+ Status = EFI_SUCCESS;
+ if (*Buffer == NULL) {
+ //
+ // Caller passed in a pointer so allocate buffer for them
+ //
+ *Buffer = CoreAllocateBootServicesPool (FileSize);
+ if (*Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (FileSize > InputBufferSize) {
+ //
+ // Callers buffer was not big enough
+ //
+ Status = EFI_WARN_BUFFER_TOO_SMALL;
+ FileSize = InputBufferSize;
+ }
+
+ //
+ // Copy data into callers buffer
+ //
+ EfiCommonLibCopyMem (*Buffer, SrcPtr, FileSize);
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+FvReadFileSection (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+ Routine Description:
+ Locates a section in a given FFS File and
+ copies it to the supplied buffer (not including section header).
+
+ Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ SectionType - Indicates the section type to return.
+ SectionInstance - Indicates which instance of sections with a type of
+ SectionType to return.
+ Buffer - Buffer is a pointer to pointer to a buffer in which
+ the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated UINTN.
+ AuthenticationStatus -AuthenticationStatus is a pointer to a caller
+ allocated UINT32 in which the authentication status
+ is returned.
+
+ Returns:
+ EFI_SUCCESS - Successfully read the file section into buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Section not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINTN FileSize;
+ UINT8 *FileBuffer;
+ EFI_SECTION_EXTRACTION_PROTOCOL *Sep;
+ FFS_FILE_LIST_ENTRY *FfsEntry;
+
+ if (NULL == NameGuid || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+
+ //
+ // Read the whole file into buffer
+ //
+ FileBuffer = NULL;
+ Status = FvReadFile (
+ This,
+ NameGuid,
+ &FileBuffer,
+ &FileSize,
+ &FileType,
+ &FileAttributes,
+ AuthenticationStatus
+ );
+ //
+ // Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
+ //
+ FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check to see that the file actually HAS sections before we go any further.
+ //
+ if (FileType == EFI_FV_FILETYPE_RAW) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Use FfsEntry to cache Section Extraction Protocol Inforomation
+ //
+ if (FfsEntry->StreamHandle == 0) {
+ //
+ // Located the protocol
+ //
+ Status = CoreLocateProtocol (&gEfiSectionExtractionProtocolGuid, NULL, &Sep);
+ //
+ // Section Extraction Protocol is part of Dxe Core so this should never fail
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ Status = Sep->OpenSectionStream (
+ Sep,
+ FileSize,
+ FileBuffer,
+ &FfsEntry->StreamHandle
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ FfsEntry->Sep = Sep;
+ } else {
+ //
+ // Get cached copy of Sep
+ //
+ Sep = FfsEntry->Sep;
+ }
+
+ //
+ // If SectionType == 0 We need the whole section stream
+ //
+ Status = Sep->GetSection (
+ Sep,
+ FfsEntry->StreamHandle,
+ (SectionType == 0) ? NULL : &SectionType,
+ NULL,
+ (SectionType == 0) ? 0 : SectionInstance,
+ Buffer,
+ BufferSize,
+ AuthenticationStatus
+ );
+
+ //
+ // Close of stream defered to close of FfsHeader list to allow SEP to cache data
+ //
+
+Done:
+ CoreFreePool (FileBuffer);
+
+ return Status;
+}
+
+#else
+
+EFI_STATUS
+EFIAPI
+FvGetNextFile (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN OUT VOID *Key,
+ IN OUT EFI_FV_FILETYPE *FileType,
+ OUT EFI_GUID *NameGuid,
+ OUT EFI_FV_FILE_ATTRIBUTES *Attributes,
+ OUT UINTN *Size
+ )
+/*++
+
+Routine Description:
+ Given the input key, search for the next matching file in the volume.
+
+Arguments:
+ This - Indicates the calling context.
+ FileType - FileType is a pointer to a caller allocated
+ EFI_FV_FILETYPE. The GetNextFile() API can filter it's
+ search for files based on the value of *FileType input.
+ A *FileType input of 0 causes GetNextFile() to search for
+ files of all types. If a file is found, the file's type
+ is returned in *FileType. *FileType is not modified if
+ no file is found.
+ Key - Key is a pointer to a caller allocated buffer that
+ contains implementation specific data that is used to
+ track where to begin the search for the next file.
+ The size of the buffer must be at least This->KeySize
+ bytes long. To reinitialize the search and begin from
+ the beginning of the firmware volume, the entire buffer
+ must be cleared to zero. Other than clearing the buffer
+ to initiate a new search, the caller must not modify the
+ data in the buffer between calls to GetNextFile().
+ NameGuid - NameGuid is a pointer to a caller allocated EFI_GUID.
+ If a file is found, the file's name is returned in
+ *NameGuid. *NameGuid is not modified if no file is
+ found.
+ Attributes - Attributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. If a file is found, the file's
+ attributes are returned in *Attributes. *Attributes is
+ not modified if no file is found.
+ Size - Size is a pointer to a caller allocated UINTN.
+ If a file is found, the file's size is returned in *Size.
+ *Size is not modified if no file is found.
+
+Returns:
+ EFI_SUCCESS - Successfully find the file.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Fv could not read.
+ EFI_NOT_FOUND - No matching file found.
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FV_ATTRIBUTES FvAttributes;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINTN *KeyValue;
+ EFI_LIST_ENTRY *Link;
+ FFS_FILE_LIST_ENTRY *FfsFileEntry;
+ UINTN FileLength;
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+
+ Status = FvGetVolumeAttributes (This, &FvAttributes);
+ if (EFI_ERROR (Status)){
+ return Status;
+ }
+
+ //
+ // Check if read operation is enabled
+ //
+ if ((FvAttributes & EFI_FV2_READ_STATUS) == 0) {
+ return EFI_ACCESS_DENIED;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//PI 1.1 ++
+#if PI_SPECIFICATION_VERSION >= 0x0001000A
+ if (*FileType > EFI_FV_FILETYPE_SMM_CORE) {
+#else
+ if (*FileType > EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
+#endif
+//PI 1.1 --
+//*** AMI PORTING END *****//
+ //
+ // File type needs to be in 0 - 0x0B
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ KeyValue = (UINTN *)Key;
+ for (;;) {
+ if (*KeyValue == 0) {
+ //
+ // Search for 1st matching file
+ //
+ Link = &FvDevice->FfsFileListHeader;
+ } else {
+ //
+ // Key is pointer to FFsFileEntry, so get next one
+ //
+ Link = (EFI_LIST_ENTRY *)(*KeyValue);
+ }
+
+ if (Link->ForwardLink == &FvDevice->FfsFileListHeader) {
+ //
+ // Next is end of list so we did not find data
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ FfsFileEntry = (FFS_FILE_LIST_ENTRY *)Link->ForwardLink;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)FfsFileEntry->FfsHeader;
+
+ //
+ // remember the key
+ //
+ *KeyValue = (UINTN)FfsFileEntry;
+
+ if (FfsFileHeader->Type == EFI_FV_FILETYPE_FFS_PAD) {
+ //
+ // we ignore pad files
+ //
+ continue;
+ }
+
+ if (*FileType == 0) {
+ //
+ // Process all file types so we have a match
+ //
+ break;
+ }
+
+ if (*FileType == FfsFileHeader->Type) {
+ //
+ // Found a matching file type
+ //
+ break;
+ }
+
+ }
+
+ //
+ // Return FileType, NameGuid, and Attributes
+ //
+ *FileType = FfsFileHeader->Type;
+ EfiCommonLibCopyMem (NameGuid, &FfsFileHeader->Name, sizeof (EFI_GUID));
+ *Attributes = FfsAttributes2FvFileAttributes (FfsFileHeader->Attributes);
+
+ //
+ // Read four bytes out of the 3 byte array and throw out extra data
+ //
+ FileLength = *(UINT32 *)&FfsFileHeader->Size[0] & 0x00FFFFFF;
+
+ //
+ // we need to substract the header size
+ //
+ *Size = FileLength - sizeof(EFI_FFS_FILE_HEADER);
+
+//*** AMI PORTING BEGIN ***//
+//Bug fix: FFS_ATTRIB_TAIL_PRESENT attribute dies not exist in PI Specification.
+#if PI_SPECIFICATION_VERSION < 0x00010000
+//*** AMI PORTING END *****//
+ if (FfsFileHeader->Attributes & FFS_ATTRIB_TAIL_PRESENT) {
+ //
+ // If tail is present substract it's size;
+ //
+ *Size -= sizeof(EFI_FFS_FILE_TAIL);
+ }
+//*** AMI PORTING BEGIN ***//
+//see comments above
+#endif //#if PI_SPECIFICATION_VERSION < 0x00010000
+//*** AMI PORTING END *****//
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+FvReadFile (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FV_FILETYPE *FoundType,
+ OUT EFI_FV_FILE_ATTRIBUTES *FileAttributes,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+ Locates a file in the firmware volume and
+ copies it to the supplied buffer.
+
+Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ Buffer - Buffer is a pointer to pointer to a buffer in
+ which the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated
+ UINTN. On input *BufferSize indicates the size
+ in bytes of the memory region pointed to by
+ Buffer. On output, *BufferSize contains the number
+ of bytes required to read the file.
+ FoundType - FoundType is a pointer to a caller allocated
+ EFI_FV_FILETYPE that on successful return from Read()
+ contains the type of file read. This output reflects
+ the file type irrespective of the value of the
+ SectionType input.
+ FileAttributes - FileAttributes is a pointer to a caller allocated
+ EFI_FV_FILE_ATTRIBUTES. On successful return from
+ Read(), *FileAttributes contains the attributes of
+ the file read.
+ AuthenticationStatus - AuthenticationStatus is a pointer to a caller
+ allocated UINTN in which the authentication status
+ is returned.
+Returns:
+ EFI_SUCCESS - Successfully read to memory buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_GUID SearchNameGuid;
+ EFI_FV_FILETYPE LocalFoundType;
+ EFI_FV_FILE_ATTRIBUTES LocalAttributes;
+ UINTN FileSize;
+ UINT8 *SrcPtr;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+ UINTN InputBufferSize;
+
+ if (NULL == NameGuid) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+
+
+ //
+ // Keep looking until we find the matching NameGuid.
+ // The Key is really an FfsFileEntry
+ //
+ FvDevice->LastKey = 0;
+ do {
+ LocalFoundType = 0;
+ Status = FvGetNextFile (
+ This,
+ &FvDevice->LastKey,
+ &LocalFoundType,
+ &SearchNameGuid,
+ &LocalAttributes,
+ &FileSize
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+ } while (!EfiCompareGuid (&SearchNameGuid, (EFI_GUID*)NameGuid));
+
+ //
+ // Get a pointer to the header
+ //
+ FfsHeader = FvDevice->LastKey->FfsHeader;
+
+ //
+ // Remember callers buffer size
+ //
+ InputBufferSize = *BufferSize;
+
+ //
+ // Calculate return values
+ //
+ *FoundType = FfsHeader->Type;
+ *FileAttributes = FfsAttributes2FvFileAttributes (FfsHeader->Attributes);
+ *AuthenticationStatus = 0;
+ *BufferSize = FileSize;
+
+ if (Buffer == NULL) {
+ //
+ // If Buffer is NULL, we only want to get the information colected so far
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Skip over file header
+ //
+ SrcPtr = ((UINT8 *)FfsHeader) + sizeof (EFI_FFS_FILE_HEADER);
+
+ Status = EFI_SUCCESS;
+ if (*Buffer == NULL) {
+ //
+ // Caller passed in a pointer so allocate buffer for them
+ //
+ *Buffer = CoreAllocateBootServicesPool (FileSize);
+ if (*Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else if (FileSize > InputBufferSize) {
+ //
+ // Callers buffer was not big enough
+ //
+ Status = EFI_WARN_BUFFER_TOO_SMALL;
+ FileSize = InputBufferSize;
+ }
+
+ //
+ // Copy data into callers buffer
+ //
+ EfiCommonLibCopyMem (*Buffer, SrcPtr, FileSize);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+FvReadFileSection (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN CONST EFI_GUID *NameGuid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN UINTN SectionInstance,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+ Routine Description:
+ Locates a section in a given FFS File and
+ copies it to the supplied buffer (not including section header).
+
+ Arguments:
+ This - Indicates the calling context.
+ NameGuid - Pointer to an EFI_GUID, which is the filename.
+ SectionType - Indicates the section type to return.
+ SectionInstance - Indicates which instance of sections with a type of
+ SectionType to return.
+ Buffer - Buffer is a pointer to pointer to a buffer in which
+ the file or section contents or are returned.
+ BufferSize - BufferSize is a pointer to caller allocated UINTN.
+ AuthenticationStatus -AuthenticationStatus is a pointer to a caller
+ allocated UINT32 in which the authentication status
+ is returned.
+
+ Returns:
+ EFI_SUCCESS - Successfully read the file section into buffer.
+ EFI_WARN_BUFFER_TOO_SMALL - Buffer too small.
+ EFI_NOT_FOUND - Section not found.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_ACCESS_DENIED - Could not read.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+--*/
+{
+ EFI_STATUS Status;
+ FV_DEVICE *FvDevice;
+ EFI_FV_FILETYPE FileType;
+ EFI_FV_FILE_ATTRIBUTES FileAttributes;
+ UINTN FileSize;
+ UINT8 *FileBuffer;
+ EFI_SECTION_EXTRACTION_PROTOCOL *Sep;
+ FFS_FILE_LIST_ENTRY *FfsEntry;
+
+ if (NULL == NameGuid || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FvDevice = FV_DEVICE_FROM_THIS (This);
+
+ //
+ // Read the whole file into buffer
+ //
+ FileBuffer = NULL;
+ Status = FvReadFile (
+ This,
+ NameGuid,
+ &FileBuffer,
+ &FileSize,
+ &FileType,
+ &FileAttributes,
+ AuthenticationStatus
+ );
+ //
+ // Get the last key used by our call to FvReadFile as it is the FfsEntry for this file.
+ //
+ FfsEntry = (FFS_FILE_LIST_ENTRY *)FvDevice->LastKey;
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check to see that the file actually HAS sections before we go any further.
+ //
+ if (FileType == EFI_FV_FILETYPE_RAW) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Use FfsEntry to cache Section Extraction Protocol Inforomation
+ //
+ if (FfsEntry->StreamHandle == 0) {
+ //
+ // Located the protocol
+ //
+ Status = CoreLocateProtocol (&gEfiSectionExtractionProtocolGuid, NULL, &Sep);
+ //
+ // Section Extraction Protocol is part of Dxe Core so this should never fail
+ //
+ ASSERT_EFI_ERROR (Status);
+
+ Status = Sep->OpenSectionStream (
+ Sep,
+ FileSize,
+ FileBuffer,
+ &FfsEntry->StreamHandle
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ FfsEntry->Sep = Sep;
+ } else {
+ //
+ // Get cached copy of Sep
+ //
+ Sep = FfsEntry->Sep;
+ }
+
+ //
+ // If SectionType == 0 We need the whole section stream
+ //
+ Status = Sep->GetSection (
+ Sep,
+ FfsEntry->StreamHandle,
+ (SectionType == 0) ? NULL : &SectionType,
+ NULL,
+ (SectionType == 0) ? 0 : SectionInstance,
+ Buffer,
+ BufferSize,
+ AuthenticationStatus
+ );
+
+ //
+ // Close of stream defered to close of FfsHeader list to allow SEP to cache data
+ //
+
+Done:
+ CoreFreePool (FileBuffer);
+
+ return Status;
+}
+
+
+#endif
+
diff --git a/Core/CORE_DXE/FwVolWrite.c b/Core/CORE_DXE/FwVolWrite.c
new file mode 100644
index 0000000..3822f1e
--- /dev/null
+++ b/Core/CORE_DXE/FwVolWrite.c
@@ -0,0 +1,102 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVolWrite.c
+
+Abstract:
+
+ Implements write firmware file
+
+--*/
+
+#include "FwVolDriver.h"
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+
+EFI_STATUS
+EFIAPI
+FvWriteFile (
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL *This,
+ IN UINT32 NumberOfFiles,
+ IN EFI_FV_WRITE_POLICY WritePolicy,
+ IN EFI_FV_WRITE_FILE_DATA *FileData
+ )
+/*++
+
+ Routine Description:
+ Writes one or more files to the firmware volume.
+
+ Arguments:
+ This - Indicates the calling context.
+ NumberOfFiles - Number of files.
+ WritePolicy - WritePolicy indicates the level of reliability for
+ the write in the event of a power failure or other
+ system failure during the write operation.
+ FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
+ Each element of FileData[] represents a file to be written.
+
+ Returns:
+ EFI_SUCCESS - Files successfully written to firmware volume
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_WRITE_PROTECTED - Write protected.
+ EFI_NOT_FOUND - Not found.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_UNSUPPORTED - This function not supported.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+#else
+
+EFI_STATUS
+EFIAPI
+FvWriteFile (
+ IN CONST EFI_FIRMWARE_VOLUME2_PROTOCOL *This,
+ IN UINT32 NumberOfFiles,
+ IN EFI_FV_WRITE_POLICY WritePolicy,
+ IN EFI_FV_WRITE_FILE_DATA *FileData
+ )
+/*++
+
+ Routine Description:
+ Writes one or more files to the firmware volume.
+
+ Arguments:
+ This - Indicates the calling context.
+ NumberOfFiles - Number of files.
+ WritePolicy - WritePolicy indicates the level of reliability for
+ the write in the event of a power failure or other
+ system failure during the write operation.
+ FileData - FileData is an pointer to an array of EFI_FV_WRITE_DATA.
+ Each element of FileData[] represents a file to be written.
+
+ Returns:
+ EFI_SUCCESS - Files successfully written to firmware volume
+ EFI_OUT_OF_RESOURCES - Not enough buffer to be allocated.
+ EFI_DEVICE_ERROR - Device error.
+ EFI_WRITE_PROTECTED - Write protected.
+ EFI_NOT_FOUND - Not found.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_UNSUPPORTED - This function not supported.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+#endif
+
diff --git a/Core/CORE_DXE/GC.c b/Core/CORE_DXE/GC.c
new file mode 100644
index 0000000..c045bda
--- /dev/null
+++ b/Core/CORE_DXE/GC.c
@@ -0,0 +1,2249 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/GC.c 1 11/21/12 4:07a Wesleychen $
+//
+// $Revision: 1 $
+//
+// $Date: 11/21/12 4:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/GC.c $
+//
+// 1 11/21/12 4:07a Wesleychen
+// Update rev.45 for EIP105534.
+//
+// 45 11/14/12 5:57p Artems
+// [TAG] EIP105534
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] system hangs during SCT execution
+// [RootCause] Incorrect handling of FORM_FEED escape character in
+// StringToImage function
+// [Solution] Graphics console - added flag to ignore line breaks
+// HiiFont - fixed multiline drawing logic
+// [Files] Gc.c HiiFont.c HiiFontEx.c
+//
+// 44 7/06/12 11:19a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Removed unnecessary traces
+// [Files] Gc.c
+//
+// 43 7/06/12 11:11a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Support for monitor native resolution
+// [Files] GC.c, ConSplit.c, Out.c, Core_Dxe.sdl
+//
+// 42 6/19/12 3:43p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] GC.c file gives build error
+// [RootCause] incorrect pointer used
+// [Solution] changed pointer
+// [Files] gc.c
+//
+// 41 6/19/12 10:36a Artems
+// [TAG] EIP89430
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Cursor position wasn't 0:0 after call to SetMode
+// [RootCause] When console SetMode involved changing of screen
+// resolution
+// screen was cleared by graphics driver, however cursol position wasn't
+// reset
+// [Solution] Added code to resent cursor position when changing screen
+// resolution
+// [Files] Gc.c
+//
+// 40 5/21/12 10:46a Artems
+// [TAG] EIP N/A
+// [Category] New Feature
+// [Description] Added text mode for full screen in native resolution
+// [Files] GC.c
+//
+// 39 4/30/12 3:55p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Modified GraphicsConsole driver to output whole string
+// instead of symbol-by-symbol output
+// [Files] Gc.c, AmiDxeLib.h, EfiLib.c, UefiHiiUtils.c
+//
+// 38 8/12/11 12:22p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 37 8/12/11 11:54a Artems
+// Bug fix: avoid using uninitialized data fields of GC_DATA structure
+//
+// 36 4/12/10 3:25p Artems
+// Fixed bug of drawing cursor when window position is undefined
+//
+// 35 12/17/09 10:22a Artems
+// EIP 29311 added automatic discovering of graphics mode for text mode 0
+//
+// 34 12/03/09 3:13p Felixp
+// TestString is implemented for UEFI 2.1 case.
+//
+// 33 10/09/09 6:06p Felixp
+// UEFI 2.1 - related changes (suppot Framework and UEFI HII).
+//
+// 32 8/28/09 10:25a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 31 7/10/09 6:26p Felixp
+//
+// 30 7/08/09 5:01p Artems
+// Added missing function headers
+//
+// 29 5/22/09 7:27p Felixp
+//
+// 27 10/19/07 9:19a Felixp
+// - Graphic Console driver is updated to support different graphical
+// resolutions (used to be only 800 by 600).
+// - SDL tokens are added in CORE_DXE.sdl to customize list of text
+// modes.
+// - SDL tokens are added in CORE_DXE.sdl to customize color values(EIP:
+// 9854).
+//
+// 26 4/13/07 2:45p Robert
+// Updates for Coding Standard
+//
+// 25 3/30/07 6:13p Felixp
+//
+// 24 3/29/07 10:22a Felixp
+//
+// 23 3/28/07 5:39p Artems
+// Fixed errors reported by SCT test
+//
+// 22 3/13/07 1:48p Artems
+// Fixed bug in 100 x 31 mode
+//
+// 21 3/13/07 10:42a Artems
+//
+// 20 3/09/07 1:40p Artems
+// Clear screen function changed to clear only affected part of screen,
+// not
+// entire screen
+//
+// 19 1/04/07 6:19p Artems
+//
+// 18 12/20/06 10:38a Felixp
+// Graphics Output Protocol support added
+//
+// 17 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 16 8/04/06 4:07p Robert
+//
+// 15 3/13/06 10:07a Felixp
+//
+// 14 9/29/05 2:52p Robert
+// Initialization of Global Variables
+//
+// 13 7/22/05 11:29a Felixp
+// enable cursor in reset function
+//
+// 12 7/20/05 6:50p Felixp
+//
+// 11 7/20/05 6:24p Robert
+// Added check for trying to print a wide character at position 79. This
+// should produce a line feed instead
+//
+// 10 7/20/05 5:31p Robert
+// Data structure for temporary storage of cursor position was only big
+// enough for narrow glyph not for wide glyph
+//
+// 7 3/03/05 12:16p Felixp
+// HII New protocol is default now
+//
+// 6 2/25/05 11:27a Robert
+// Cleared current p[osition buffer before clearing the screen and moving
+// the cursor
+//
+// 5 2/25/05 10:52a Robert
+// Clear screen procedure would leave a block on the screen where the
+// cursor was.
+// We changed the order of the operation so that the cursor moved first
+// and the screen was cleared afterward
+//
+// 4 2/24/05 5:27p Felixp
+// bug fix in DriverBindingStop (Cursor blinking timer was not getting
+// stopped)
+//
+// 3 2/07/05 4:04p Yakovlevs
+//
+// 2 2/04/05 1:47p Felixp
+// warning fixed
+//
+// 1 1/28/05 12:45p Felixp
+//
+// 3 1/06/05 11:22a Robert
+//
+// 2 1/06/05 10:09a Robert
+// Added Blinking Cursor support
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 9 12/16/04 3:40p Felixp
+//
+// 8 12/16/04 2:14p Robert
+// Added TempBlt Buffer init for printing of default string. was
+// forgetting to re-init
+// buffer pointer when doing a carriage return line feed
+//
+// 7 12/16/04 11:39a Robert
+// code optimization for color selection
+//
+// 6 12/15/04 4:02p Robert
+// added checks for memory allocation
+//
+// 5 12/14/04 6:02p Robert
+// added component name support
+//
+// 4 12/14/04 5:28p Robert
+//
+// 3 12/14/04 4:28p Robert
+//
+// 2 11/11/04 5:09p Robert
+//
+// 1 11/11/04 3:28p Robert
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: GC.h
+//
+// Description: Graphics console driver that produces the Simple Text Out
+// interface
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//-----------------------------------------------------------------------------
+
+#include <AmiDxeLib.h>
+#include <Protocol/UgaDraw.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/HiiFont.h>
+#include <Protocol/SimpleTextOut.h >
+#include <Protocol/DevicePath.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/ComponentName2.h>
+#include <Protocol/EdidActive.h>
+#include <Token.h>
+
+//-----------------------------------------------------------------------------
+
+#define GLYPH_HEIGHT 19
+#define NARROW_GLYPH_WIDTH 8
+#define WIDE_GLYPH_WIDTH 16
+
+#define MODE_ZERO_MIN_HOR_RES NARROW_GLYPH_WIDTH * 80
+#define MODE_ZERO_MIN_VER_RES GLYPH_HEIGHT * 25
+
+#define CURSOR_THICKNESS 3
+#define CURSOR_OFFSET 15 //base line of simple narrow font
+
+#define NULL_CHAR 0x0000
+#define BACKSPACE 0x0008
+#define LINE_FEED 0x000A
+#define FORM_FEED 0x000C
+#define CARRIAGE_RETURN 0x000D
+
+//-----------------------------------------------------------------------------
+// Data Structures
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TEXT_MODE
+//
+// Description:
+// This structure represents text mode internal information structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// ModeNum INT32 Mode number
+// Col INT32 Max number of columns
+// Row INT32 Max number of rows
+// VideoCol UINT32 Horizontal screen resolution
+// VideoRow UINT32 Vertical screen resolution
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _TEXT_MODE {
+ INT32 ModeNum;
+ INT32 Col;
+ INT32 Row;
+ UINT32 VideoCol; // horizontal pixels
+ UINT32 VideoRow; // vertical pixels
+} TEXT_MODE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: GC_TEXT_MODE
+//
+// Description:
+// This structure represents text mode extended internal information structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// ModeNum INT32 Mode number
+// Col INT32 Max number of columns
+// Row INT32 Max number of rows
+// VideoCol UINT32 Horizontal screen resolution
+// VideoRow UINT32 Vertical screen resolution
+// Supported BOOLEAN Flag if this mode supported
+// GraphicsMode UINT32 Correspondent graphics mode
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _GC_TEXT_MODE {
+ INT32 ModeNum;
+ INT32 Col;
+ INT32 Row;
+ UINT32 VideoCol; // horizontal pixels
+ UINT32 VideoRow; // vertical pixels
+ BOOLEAN Supported;
+ UINT32 GraphicsMode;
+} GC_TEXT_MODE;
+
+typedef struct _GC_DATA GC_DATA;
+
+typedef VOID (* AGC_UPDATE_BLT_BUFFER ) (
+ IN GC_DATA *This,
+ IN UINT32 Width,
+ IN UINT32 Height,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
+ );
+
+typedef VOID (* AGC_CLEAR_SCREEN) (
+ IN OUT GC_DATA *This
+ );
+
+typedef VOID (* AGC_SCROLL_UP) (
+ IN GC_DATA *This
+ );
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: GC_DATA
+//
+// Description:
+// This structure represents internal information structure for Graphics console
+// driver
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// SimpleTextOut EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL Protocol structure
+// Signature UINT32 Unique signature
+// GraphicsOutput EFI_GRAPHICS_OUTPUT_PROTOCOL* Pointer to Gop driver
+// Hii EFI_HII_PROTOCOL* Pointer to HII driver
+// SupportedModes GC_TEXT_MODE* Pointer to supported modes array
+// MaxRows UINT32 Max rows in current mode
+// MaxColumns UINT32 Max columns in current mode
+// DeltaX UINT32 Horizontal indent of text window on screen in pixels
+// DeltaY UINT32 Vertical indent of text window on screen in pixels
+// Cursor EFI_GRAPHICS_OUTPUT_BLT_PIXEL Array for saving cursor image
+// BlinkVisible BOOLEAN Current state of cursor in blinking mode
+// CursorEvent EFI_EVENT Event generated to blink cursor
+// OemUpdateBltBuffer AGC_UPDATE_BLT_BUFFER Custom porting hook
+// OemClearScreen AGC_CLEAR_SCREEN Custom porting hook
+// OemScrollUp AGC_SCROLL_UP Custom porting hook
+//
+// Notes:
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+struct _GC_DATA{
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL SimpleTextOut;
+ UINT32 Signature; //signature (must be 0x54445348 ('GRCS') )
+ UINT32 Version;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_HII_FONT_PROTOCOL *HiiFont;
+ GC_TEXT_MODE *SupportedModes;
+ UINT32 MaxRows; //max number of rows in current mode
+ UINT32 MaxColumns; //max number of columns in current mode
+ UINT32 DeltaX; //horizontal offset in pixels for current text mode
+ UINT32 DeltaY; //vertical offset in pixels for current text mode
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Cursor[NARROW_GLYPH_WIDTH * 3]; //Save cursor image
+ BOOLEAN BlinkVisible; //if true cursor is visible, otherwise - invisible
+ EFI_EVENT CursorEvent;
+ AGC_UPDATE_BLT_BUFFER OemUpdateBltBuffer; //pointer to custom hook
+ AGC_CLEAR_SCREEN OemClearScreen; //pointer to custom hook
+ AGC_SCROLL_UP OemScrollUp; //pointer to custom hook
+};
+#pragma pack()
+
+//-----------------------------------------------------------------------------
+// Function Prototypes
+
+EFI_STATUS DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer);
+
+//******************** Simple Text Output protocol functions prototypes ***********
+
+EFI_STATUS GCReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification);
+
+EFI_STATUS GCOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String);
+
+EFI_STATUS GCTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String);
+
+EFI_STATUS GCQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row);
+
+EFI_STATUS GCSetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum);
+
+EFI_STATUS GCSetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute);
+
+EFI_STATUS GCClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This);
+
+EFI_STATUS GCSetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row);
+
+EFI_STATUS GCEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible);
+
+//******************** Service functions prototypes ********************************
+
+EFI_STATUS GetColorFromAttribute(
+ IN UINT32 Attribute,
+ OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
+ OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background);
+
+EFI_STATUS GetGraphicsModeNumber (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
+ IN UINT32 HorRes,
+ IN UINT32 VerRes,
+ OUT UINT32 *ModeNum,
+ IN BOOLEAN ExactMatch,
+ OUT UINT32 *ActualHorRes OPTIONAL,
+ OUT UINT32 *ActualVerRes OPTIONAL );
+
+EFI_STATUS SetupGraphicsDevice(
+ IN GC_DATA *GcData);
+
+VOID EFIAPI BlinkCursorEvent ( IN EFI_EVENT Event, IN VOID *Context );
+
+VOID DrawCursor(
+ IN GC_DATA *GcData,
+ IN BOOLEAN Visible);
+
+VOID ScrollUp(
+ IN GC_DATA *GcData);
+
+VOID SaveCursorImage(
+ IN GC_DATA *GcData);
+
+VOID ShiftCursor(
+ IN GC_DATA *GcData,
+ IN UINT16 Step);
+
+VOID AddChar(
+ IN GC_DATA *GcData,
+ IN CHAR16 Char,
+ IN UINT16 Width
+);
+
+VOID FlushString(
+ IN GC_DATA *GcData
+);
+
+//********************** Hooks prototypes ******************************************
+
+VOID GcUpdateBltBuffer (
+ IN GC_DATA *This, //pointer to internal structure
+ IN UINT32 Width, //width of the buffer in pixels
+ IN UINT32 Height, //height of the buffer in pixels
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer //pointer to BLT buffer to update
+ );
+
+VOID GcInternalClearScreen (
+ IN OUT GC_DATA *This
+ );
+
+//-----------------------------------------------------------------------------
+// Globals
+extern const TEXT_MODE TextModeArray[];
+extern const MaxTextMode;
+extern const EFI_GRAPHICS_OUTPUT_BLT_PIXEL ColorArray[];
+static CHAR16 *TextBuffer = NULL;
+static UINT32 TextBufferSize;
+static UINT32 Position;
+static UINT32 StringWidth;
+static EFI_HANDLE GopHandle;
+
+//-----------------------------------------------------------------------------
+// Protocol implementation
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL mGCProtocol =
+ {
+ GCReset,
+ GCOutputString,
+ GCTestString,
+ GCQueryMode,
+ GCSetMode,
+ GCSetAttribute,
+ GCClearScreen,
+ GCSetCursorPosition,
+ GCEnableCursor,
+ NULL
+ };
+
+
+//-----------------------------------------------------------------------------
+// Driver Binding Protocol
+
+EFI_DRIVER_BINDING_PROTOCOL gGraphicsConsoleDriverBindingProtocol = {
+ DriverBindingSupported,
+ DriverBindingStart,
+ DriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+ };
+
+
+//-----------------------------------------------------------------------------
+// Function Definitions
+#ifdef EFI_DEBUG
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+//Driver Name
+static UINT16 *gDriverName=L"AMI Graphic Console Driver";
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GraphicsConsoleGetControllerName
+//
+// Description:
+// EFI_COMPONENT_NAME_PROTOCOL GetControllerName function
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL* This - pointer to protocol instance
+// IN EFI_HANDLE Controller - controller handle
+// IN EFI_HANDLE ChildHandle - child handle
+// IN CHAR8* Language - pointer to language description
+// OUT CHAR16** ControllerName - pointer to store pointer to controller name
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - controller name returned
+// EFI_INVALID_PARAMETER - language undefined
+// EFI_UNSUPPORTED - given language not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS GraphicsConsoleGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GraphicsConsoleGetDriverName
+//
+// Description:
+// EFI_COMPONENT_NAME_PROTOCOL GetDriverName function
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL* This - pointer to protocol instance
+// IN CHAR8* Language - pointer to language description
+// OUT CHAR16** DriverName - pointer to store pointer to driver name
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver name returned
+// EFI_INVALID_PARAMETER - language undefined
+// EFI_UNSUPPORTED - given language not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS GraphicsConsoleGetDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ //Supports only English
+ if(!Language || !DriverName)
+ return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//Component Name Protocol
+static EFI_COMPONENT_NAME2_PROTOCOL gGraphicsConsole = {
+ GraphicsConsoleGetDriverName,
+ GraphicsConsoleGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+#endif
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCEntryPoint
+//
+// Description:
+// Installs gGraphicsConsoleDriverBindingProtocol protocol
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - driver image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Driver binding protocol was installed
+//
+// Modified:
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces
+//
+// Notes:
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gGraphicsConsoleDriverBindingProtocol.DriverBindingHandle = NULL;
+ gGraphicsConsoleDriverBindingProtocol.ImageHandle = ImageHandle;
+
+ // Install driver binding protocol here
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &gGraphicsConsoleDriverBindingProtocol.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gGraphicsConsoleDriverBindingProtocol,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid, &gGraphicsConsole,
+#endif
+ NULL);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: DriverBindingSupported
+//
+// Description:
+// Checks to see if this driver can be used
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to protocol instance
+// IN EFI_HANDLE Controller - handle of controller to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Driver supports the Device
+// EFI_NOT_SUPPORTED - Driver cannot support the Device
+//
+// Notes:
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput = NULL;
+ EFI_HII_FONT_PROTOCOL *HiiFont;
+
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &GraphicsOutput,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+ if (EFI_ERROR(Status))
+ return Status;
+ else
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle);
+
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = pBS->LocateProtocol ( &gEfiHiiFontProtocolGuid, NULL, &HiiFont);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: DriverBindingStart
+//
+// Description:
+// This function grabs needed protocols and initializes the supported text modes
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to protocol instance
+// IN EFI_HANDLE Controller - handle of controller to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - SimpleTextOut Protocol installed
+// EFI_NOT_SUPPORTED - SimpleTextOut Protocol not installed
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_STATUS Status;
+ INT32 StartMode;
+
+#if (CURSOR_BLINK_ENABLE != 0)
+ EFI_STATUS EventStatus;
+#endif
+ GC_DATA *GcData = NULL;
+
+ // Create private data structure and fill with proper data
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(GC_DATA), &GcData);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ pBS->CopyMem( &(GcData->SimpleTextOut),
+ &mGCProtocol,
+ sizeof(EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL) );
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(SIMPLE_TEXT_OUTPUT_MODE),
+ &(GcData->SimpleTextOut.Mode));
+ if(EFI_ERROR(Status))
+ {
+ pBS->FreePool(GcData);
+ return Status;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(GC_TEXT_MODE) * MaxTextMode,
+ &(GcData->SupportedModes));
+ if(EFI_ERROR(Status))
+ {
+ pBS->FreePool(GcData->SimpleTextOut.Mode);
+ pBS->FreePool(GcData);
+ return Status;
+ }
+
+ Status = pBS->OpenProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &(GcData->GraphicsOutput),
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(GcData->SupportedModes);
+ pBS->FreePool(GcData->SimpleTextOut.Mode);
+ pBS->FreePool(GcData);
+ return Status;
+ }
+
+ // Find the Hii Protocol and attach it to the datastructure
+ Status = pBS->LocateProtocol ( &gEfiHiiFontProtocolGuid, NULL, &(GcData->HiiFont));
+
+ if (EFI_ERROR(Status))
+ {
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle);
+ pBS->FreePool(GcData->SupportedModes);
+ pBS->FreePool(GcData->SimpleTextOut.Mode);
+ pBS->FreePool(GcData);
+ return EFI_UNSUPPORTED;
+ }
+
+ GopHandle = ControllerHandle;
+ Status = SetupGraphicsDevice(GcData);
+ if(EFI_ERROR(Status))
+ {
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle);
+ pBS->FreePool(GcData->SupportedModes);
+ pBS->FreePool(GcData->SimpleTextOut.Mode);
+ pBS->FreePool(GcData);
+ return EFI_UNSUPPORTED;
+ }
+
+ //initialize porting hooks and signature
+ GcData->Signature = 0x54445348;
+ GcData->Version = 1;
+ GcData->OemUpdateBltBuffer = GcUpdateBltBuffer;
+ GcData->OemClearScreen = GcInternalClearScreen;
+ GcData->OemScrollUp = NULL;
+ GcData->DeltaX = 0;
+ GcData->DeltaY = 0;
+ GcData->MaxColumns = 0;
+ GcData->MaxRows = 0;
+
+ // Default the cursor blink to the show cursor state
+ GcData->BlinkVisible = TRUE;
+
+
+ (GcData->SimpleTextOut.Mode)->CursorVisible = FALSE; //since initial position of window is undefined we cannot draw cursor yet
+ Status = GCSetAttribute(&(GcData->SimpleTextOut), EFI_BACKGROUND_BLACK | EFI_WHITE); //set default attributes
+ StartMode = ((GcData->SimpleTextOut.Mode)->MaxMode > 3 && START_IN_NATIVE_RESOLUTION) ? 3 : 0;
+ Status = GCSetMode(&(GcData->SimpleTextOut), StartMode);
+ Status = GCEnableCursor(&(GcData->SimpleTextOut), TRUE); //enable cursor
+
+ // install the simple text out protocol
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ &GcData->SimpleTextOut,
+ NULL);
+
+ if (EFI_ERROR(Status))
+ {
+ // close protocols and free allocated memory
+ pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle);
+
+ pBS->FreePool(GcData->SupportedModes);
+ pBS->FreePool(GcData->SimpleTextOut.Mode);
+ pBS->FreePool(GcData);
+ return EFI_UNSUPPORTED;
+ }
+
+#if (CURSOR_BLINK_ENABLE != 0)
+ EventStatus = pBS->CreateEvent (
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ BlinkCursorEvent,
+ &(GcData->SimpleTextOut),
+ &(GcData->CursorEvent)
+ );
+ if (!EFI_ERROR(EventStatus))
+ {
+ pBS->SetTimer(GcData->CursorEvent, TimerPeriodic, 5000000);
+ }
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: DriverBindingStop
+//
+// Description:
+// Uninstalls the driver from given ControllerHandle
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to protocol instance
+// IN EFI_HANDLE ControllerHandle - controller handle to uninstall driver from
+// IN UINTN NumberOfChildren - number of children supported by this driver
+// IN EFI_HANDLE *ChildHandleBuffer - pointer to child handles buffer
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver uninstalled from controller
+// EFI_NOT_STARTED - driver was not started
+//
+// Notes:
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+ EFI_STATUS Status;
+ GC_DATA *GcData = NULL;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut = NULL;
+
+ Status = pBS->OpenProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ &SimpleTextOut,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR (Status))
+ return EFI_NOT_STARTED;
+
+ Status = pBS->CloseProtocol (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle);
+
+ GcData = (GC_DATA *) SimpleTextOut;
+
+ // uninstall the simple text out protocol
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ControllerHandle,
+ &gEfiSimpleTextOutProtocolGuid,
+ &GcData->SimpleTextOut,
+ NULL);
+ if (EFI_ERROR (Status))
+ return Status;
+
+#if (CURSOR_BLINK_ENABLE != 0)
+ pBS->SetTimer(GcData->CursorEvent, TimerCancel, 0);
+ pBS->CloseEvent(GcData->CursorEvent);
+#endif
+
+ Status = pBS->CloseProtocol(
+ ControllerHandle,
+ &gEfiGraphicsOutputProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle);
+
+ pBS->FreePool(GcData->SupportedModes);
+ pBS->FreePool(GcData->SimpleTextOut.Mode);
+ pBS->FreePool(GcData);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCReset
+//
+// Description:
+// Resets the text output device
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN BOOLEAN ExtendedVerification - indicates that the driver should preform more
+// exhausted verification of the device during reset
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device reset properly
+// EFI_DEVICE_ERROR - Device is not functioning properly
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ // Set mode clears the screen and sets the cursor back to (0,0) So before
+ // we do that, set the Attribute colors to default
+ This->SetAttribute(This, EFI_BACKGROUND_BLACK | EFI_WHITE);
+// This->SetMode(This, 0);
+ This->ClearScreen(This);
+ This->EnableCursor(This, TRUE);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCOutputString
+//
+// Description:
+// Writes a string to the output device and advances the cursor
+// as necessary.
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN CHAR16 *String - pointer to string to be displayed to the screen
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device reset properly
+// EFI_DEVICE_ERROR - Device reported an Error while outputting a string
+// EFI_UNSUPPORTED - The output device's mode is not currently in a defined state
+// EFI_WARN_UNKNOWN_GLYPH - This warning code indicates that some of the
+// characters in the unicode string could not be rendered and were skipped
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ EFI_STATUS Status;
+ GC_DATA *GcData;
+ BOOLEAN UnknownGlyph = FALSE;
+ BOOLEAN CursorVisible;
+ EFI_FONT_DISPLAY_INFO FontInfo;
+ EFI_IMAGE_OUTPUT *Glyph = NULL;
+ UINT16 GlyphWidth;
+
+ // find private data structure
+ GcData = (GC_DATA *) This;
+
+ CursorVisible = (GcData->SimpleTextOut.Mode)->CursorVisible;
+ if (CursorVisible)
+ This->EnableCursor(This, FALSE);
+
+ // now loop through the string and display it to the output device
+ while (*String != 0)
+ {
+ switch (*String)
+ {
+ case CARRIAGE_RETURN:
+ FlushString(GcData);
+ This->SetCursorPosition(
+ This,
+ 0,
+ (GcData->SimpleTextOut.Mode)->CursorRow);
+ break;
+
+ case LINE_FEED:
+ case FORM_FEED:
+ FlushString(GcData);
+ if((GcData->SimpleTextOut.Mode)->CursorRow == (GcData->MaxRows - 1))
+ {
+ ScrollUp(GcData);
+ //cursor position not changed, but image under it does - save new image
+ SaveCursorImage(GcData);
+ }
+ else
+ This->SetCursorPosition(
+ This,
+ (GcData->SimpleTextOut.Mode)->CursorColumn,
+ (GcData->SimpleTextOut.Mode)->CursorRow + 1);
+ break;
+
+ case BACKSPACE:
+ FlushString(GcData);
+ if((GcData->SimpleTextOut.Mode)->CursorColumn != 0)
+ This->SetCursorPosition(
+ This,
+ (GcData->SimpleTextOut.Mode)->CursorColumn - 1,
+ (GcData->SimpleTextOut.Mode)->CursorRow);
+ break;
+
+ default:
+ Status = HiiLibGetGlyphWidth(*String, &GlyphWidth);
+ if(Status == EFI_UNSUPPORTED) {
+ Status = GcData->HiiFont->GetGlyph(
+ GcData->HiiFont,
+ *String,
+ &FontInfo,
+ &Glyph,
+ 0);
+ if(EFI_ERROR(Status))
+ return Status;
+ GlyphWidth = Glyph->Width;
+ }
+
+ if(Status == EFI_WARN_UNKNOWN_GLYPH)
+ UnknownGlyph = TRUE;
+
+ AddChar(GcData, *String, GlyphWidth / 8);
+
+ if(Glyph != NULL) {
+ pBS->FreePool(Glyph->Image.Bitmap);
+ pBS->FreePool(Glyph);
+ Glyph = NULL;
+ }
+
+ break; // end of default case
+ }
+
+ String++;
+ }
+ FlushString(GcData);
+ if (CursorVisible)
+ This->EnableCursor(This, TRUE);
+
+ return (UnknownGlyph) ? EFI_WARN_UNKNOWN_GLYPH : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCTestString
+//
+// Description:
+// Tests to see if the String has the glyphs that correspond to
+// each character in the string
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN CHAR16 *String - pointer to a string that needs to be tested
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - all characters can be drawn
+// EFI_UNSUPPORTED - there are characters that cannot be drawn
+//
+// Notes:
+// Uses the HII function TestString
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ GC_DATA *GcData;
+ EFI_STATUS Status;
+ EFI_IMAGE_OUTPUT *Glyph = NULL;
+
+ // find private data structure
+ GcData = (GC_DATA *) This;
+
+ // now loop through the string and display it to the output device
+ while (*String != 0)
+ {
+ switch (*String)
+ {
+ case CARRIAGE_RETURN: case LINE_FEED: case BACKSPACE:
+ break;
+ default:
+ Status = GcData->HiiFont->GetGlyph(
+ GcData->HiiFont,
+ *String,
+ NULL,
+ &Glyph,
+ 0);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ pBS->FreePool(Glyph->Image.Bitmap);
+ pBS->FreePool(Glyph);
+ if(Status == EFI_WARN_UNKNOWN_GLYPH)
+ return EFI_UNSUPPORTED;
+ Glyph = NULL;
+ break;
+ }
+ String++;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCQueryMode
+//
+// Description:
+// Returns information for an available text mode that the output
+// device supports
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN UINTN ModeNum - The mode to return information on
+// OUT UINTN *Col - the number of columns supported
+// OUT UINTN *Row - the number of rows supported
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - device reset properly
+// EFI_DEVICE_ERROR - Device reported an Error while outputting a string
+// EFI_UNSUPPORTED - The ModeNumber is not supported
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row
+)
+{
+ GC_DATA *GcData;
+ UINT32 i = 0;
+
+ GcData = (GC_DATA *) This;
+
+ if(ModeNum >= (UINTN)(GcData->SimpleTextOut.Mode)->MaxMode)
+ return EFI_UNSUPPORTED;
+
+ while(GcData->SupportedModes[i].ModeNum != ModeNum)
+ i++;
+
+ if(!GcData->SupportedModes[i].Supported)
+ return EFI_UNSUPPORTED;
+
+ // if the mode is a valid mode, return the data from the array of
+ // for the height and width
+ *Col = GcData->SupportedModes[i].Col;
+ *Row = GcData->SupportedModes[i].Row;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCSetMode
+//
+// Description:
+// Sets the text mode to the requested mode. It checks to see if
+// it is a valid mode
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN UINTN ModeNum - mode number to change to
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - the new mode is valid and has been set
+// EFI_UNSUPPORTED - the new mode is not valid
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GCSetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum
+)
+{
+ EFI_STATUS Status;
+ GC_DATA *GcData;
+ BOOLEAN CursorVisible;
+ UINT32 i = 0;
+ UINT32 DeltaX, DeltaY;
+ UINT32 SaveX, SaveY;
+
+ GcData = (GC_DATA *) This;
+
+ if(ModeNum >= (UINTN)(GcData->SimpleTextOut.Mode)->MaxMode)
+ return EFI_UNSUPPORTED;
+
+ while(GcData->SupportedModes[i].ModeNum != ModeNum)
+ i++;
+
+ if(!GcData->SupportedModes[i].Supported)
+ return EFI_UNSUPPORTED;
+
+ SaveX = GcData->DeltaX;
+ SaveY = GcData->DeltaY;
+
+ DeltaX = (GcData->SupportedModes[i].VideoCol -
+ GcData->SupportedModes[i].Col * NARROW_GLYPH_WIDTH) / 2;
+ DeltaY = (GcData->SupportedModes[i].VideoRow -
+ GcData->SupportedModes[i].Row * GLYPH_HEIGHT) / 2;
+
+ //save cursor status and hide it if nesessary
+ CursorVisible = (GcData->SimpleTextOut.Mode)->CursorVisible;
+ if (CursorVisible)
+ This->EnableCursor(This, FALSE);
+
+ if(GcData->GraphicsOutput->Mode->Mode != GcData->SupportedModes[i].GraphicsMode)
+ {
+ Status = GcData->GraphicsOutput->SetMode(GcData->GraphicsOutput,
+ GcData->SupportedModes[i].GraphicsMode);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(GcData->OemClearScreen != GcInternalClearScreen) { //we have porting hook installed - call it
+ This->ClearScreen(This);
+ } else {
+ /* the screen is cleared by graphics driver when changed graphics mode
+ we just need to reset cursor position */
+ This->Mode->CursorColumn = 0;
+ This->Mode->CursorRow = 0;
+ }
+ }
+ else
+ This->ClearScreen(This); //call clear screen with old values
+
+ if(GcData->DeltaX == SaveX && GcData->DeltaY == SaveY)
+ { //initial position was not changed by porting hook inside C
+ //ClearScreen function
+ GcData->DeltaX = DeltaX;
+ GcData->DeltaY = DeltaY;
+ }
+
+ GcData->MaxColumns = GcData->SupportedModes[i].Col;
+ GcData->MaxRows = GcData->SupportedModes[i].Row;
+ (GcData->SimpleTextOut.Mode)->Mode = GcData->SupportedModes[i].ModeNum;
+
+ // restore cursor at new position
+ if (CursorVisible)
+ This->EnableCursor(This, TRUE);
+
+ if(TextBuffer == NULL || TextBufferSize < GcData->MaxColumns) {
+ if(TextBuffer)
+ pBS->FreePool(TextBuffer);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, (GcData->MaxColumns + 1) * sizeof(CHAR16), &TextBuffer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ TextBufferSize = GcData->MaxColumns + 1; //additional space for null-terminator
+ Position = 0;
+ StringWidth = 0;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCSetAttribute
+//
+// Description:
+// Sets the foreground color and background color for the screen
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN UINTN Attribute - the attributes to set
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - the attribute was changed successfully
+// EFI_DEVICE_ERROR - The device had an error
+// EFI_UNSUPPORTED - The attribute is not supported
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCSetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+)
+{
+ GC_DATA *GcData;
+
+ GcData = (GC_DATA *) This;
+
+ (GcData->SimpleTextOut.Mode)->Attribute = (INT32) Attribute;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCClearScreen
+//
+// Description:
+// Clears the text screen
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - the screen was cleared
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+)
+{
+ GC_DATA *GcData;
+
+ GcData = (GC_DATA *) This;
+
+ GcData->OemClearScreen(GcData);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCSetCursorPosition
+//
+// Description:
+// This function sets the position of the cursor
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN UINTN Column - the new column
+// IN UINTN Row - The new row
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - the cursor position was changed
+// EFI_DEVICE_ERROR - The device had an error
+// EFI_UNSUPPORTED - The device is not in a valid text mode or the
+// cursor position is not valid
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GCSetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+)
+{
+ GC_DATA *GcData;
+ BOOLEAN CursorVisible;
+
+ GcData = (GC_DATA *) This;
+
+ // check for a valid text mode and check for a valid position
+ // on the screen
+
+ if ( ((UINT32)Column >= GcData->MaxColumns) ||
+ ((UINT32)Row >= GcData->MaxRows) )
+ return EFI_UNSUPPORTED;
+
+
+ //save cursor status and hide it if nesessary
+ CursorVisible = (GcData->SimpleTextOut.Mode)->CursorVisible;
+ if (CursorVisible)
+ This->EnableCursor(This, FALSE);
+
+ (GcData->SimpleTextOut.Mode)->CursorColumn = (INT32)Column;
+ (GcData->SimpleTextOut.Mode)->CursorRow = (INT32)Row;
+
+
+ // restore cursor at new position
+ if (CursorVisible)
+ This->EnableCursor(This, TRUE);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GCEnableCursor
+//
+// Description:
+// Makes cursor invisible or visible
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This - pointer to the protocol instance
+// IN BOOLEAN Visible - a boolean that if TRUE the cursor will be visible
+// if FALSE the cursor will be invisible
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - the cursor visibility was set correctly
+// EFI_DEVICE_ERROR - The device had an error
+// EFI_UNSUPPORTED - The device does not support visibilty control
+// for the cursor
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GCEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible
+)
+{
+ GC_DATA *GcData;
+
+ GcData = (GC_DATA *) This;
+
+ // check to see if the we are already set to the same cursor visibility mode
+ if (Visible != (GcData->SimpleTextOut.Mode)->CursorVisible)
+ {
+ (GcData->SimpleTextOut.Mode)->CursorVisible = Visible;
+//if we put cursor back we have to update image under it in order it contains older data
+ if(Visible)
+ SaveCursorImage(GcData);
+
+ DrawCursor(GcData, Visible);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GetColorFromAttribute
+//
+// Description:
+// Turns color attributes into Pixel values
+//
+// Input:
+// IN UINT32 Attribute - The color to set
+// OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground - foreground color
+// OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background - background color
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - valid colors returned
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetColorFromAttribute(
+ IN UINT32 Attribute,
+ OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Foreground,
+ OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Background
+)
+{
+ UINT8 IndexF;
+ UINT8 IndexB;
+
+ if ((Attribute & 0x80) != 0)
+ return EFI_UNSUPPORTED;
+
+ IndexF = (UINT8)(Attribute & 0x0f);
+ IndexB = (UINT8)((Attribute >> 4) & 0x0f);
+
+ *Foreground = ColorArray[IndexF];
+ *Background = ColorArray[IndexB];
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: DrawCursor
+//
+// Description:
+// This function draws /hides the cursor in the current cursor position
+//
+// Input:
+// IN GC_DATA * GcData - Private data structure for SimpleTextOut interface
+// IN BOOLEAN Visible - if TRUE - draws cursor, if FALSE - hides cursor
+//
+// Output:
+// VOID
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DrawCursor(
+ IN GC_DATA *GcData,
+ IN BOOLEAN Visible
+)
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;
+
+ if(Visible)
+ {
+ Fill = ColorArray[((GcData->SimpleTextOut.Mode)->Attribute & 0x0f)]; //get foreground color
+ GcData->GraphicsOutput->Blt(
+ GcData->GraphicsOutput,
+ &Fill,
+ EfiBltVideoFill,
+ 0,
+ 0,
+ GcData->DeltaX + (GcData->SimpleTextOut.Mode)->CursorColumn * NARROW_GLYPH_WIDTH,
+ GcData->DeltaY + (GcData->SimpleTextOut.Mode)->CursorRow * GLYPH_HEIGHT + CURSOR_OFFSET,
+ NARROW_GLYPH_WIDTH,
+ CURSOR_THICKNESS,
+ 0);
+ }
+ else
+ {
+ GcData->GraphicsOutput->Blt(
+ GcData->GraphicsOutput,
+ GcData->Cursor,
+ EfiBltBufferToVideo,
+ 0,
+ 0,
+ GcData->DeltaX + (GcData->SimpleTextOut.Mode)->CursorColumn * NARROW_GLYPH_WIDTH,
+ GcData->DeltaY + (GcData->SimpleTextOut.Mode)->CursorRow * GLYPH_HEIGHT + CURSOR_OFFSET,
+ NARROW_GLYPH_WIDTH,
+ CURSOR_THICKNESS,
+ NARROW_GLYPH_WIDTH * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: BlinkCursorEvent
+//
+// Description:
+// This is the function that makes the cursor blink. A timer event
+// is created that will cause this function to be called
+//
+// Input:
+// IN EFI_EVENT Event - event that was triggered
+// IN VOID *Context - pointer to the event context
+//
+// Output:
+// VOID
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EFIAPI BlinkCursorEvent(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ GC_DATA *GcData;
+
+ GcData = (GC_DATA *) Context;
+
+ if (!(GcData->SimpleTextOut.Mode)->CursorVisible)
+ return;
+
+ if (GcData->BlinkVisible)
+ {
+ // remove the cursor from the screen
+ DrawCursor(GcData, FALSE);
+ GcData->BlinkVisible = FALSE;
+ }
+ else
+ {
+ // put cursor back
+ DrawCursor(GcData, TRUE);
+ GcData->BlinkVisible = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GetGraphicsModeNumber
+//
+// Description:
+// This function returns graphics mode number, correspondend with given
+// horizontal and vertical resolution
+//
+// Input:
+// IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput - pointer to Gop driver
+// IN UINT32 HorRes - required horizontal resolution
+// IN UINT32 VerRes - required vertical resolution
+// OUT UINT32 *ModeNum - returned graphics mode number
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - correct mode number returned
+// EFI_NOT_FOUND - mode number not found for given resolution
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetGraphicsModeNumber (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
+ IN UINT32 HorRes,
+ IN UINT32 VerRes,
+ OUT UINT32 *ModeNum,
+ IN BOOLEAN ExactMatch,
+ OUT UINT32 *ActualHorRes OPTIONAL,
+ OUT UINT32 *ActualVerRes OPTIONAL
+)
+{
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION Info;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *pInfo = &Info;
+ EFI_STATUS Status;
+ UINTN SizeOfInfo;
+ UINT32 i;
+
+ for(i = 0; i < GraphicsOutput->Mode->MaxMode; i++) {
+ Status = GraphicsOutput->QueryMode(GraphicsOutput, i, &SizeOfInfo, &pInfo);
+
+ if (!EFI_ERROR(Status)) {
+ if (ExactMatch && pInfo->HorizontalResolution == HorRes && pInfo->VerticalResolution == VerRes ) {
+ *ModeNum = i;
+ return Status;
+ }
+ if(!ExactMatch && pInfo->HorizontalResolution >= HorRes && pInfo->VerticalResolution >= VerRes ) {
+ *ModeNum = i;
+ *ActualHorRes = pInfo->HorizontalResolution;
+ *ActualVerRes = pInfo->VerticalResolution;
+ return Status;
+ }
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS GetNativeResolution (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput,
+ OUT UINT32 *ModeNum,
+ OUT UINT32 *ActualHorRes,
+ OUT UINT32 *ActualVerRes
+)
+{
+ EFI_STATUS Status;
+ EFI_EDID_ACTIVE_PROTOCOL *EdidActive;
+ UINT32 HorRes;
+ UINT32 VerRes;
+
+ Status = pBS->HandleProtocol(GopHandle, &gEfiEdidActiveProtocolGuid, &EdidActive);
+ if(EFI_ERROR(Status) || EdidActive->SizeOfEdid == 0)
+ return EFI_UNSUPPORTED;
+
+ if(!((EdidActive->Edid)[24] & BIT01))
+ /* native resolution not supported */
+ return EFI_UNSUPPORTED;
+
+ HorRes = ((((EdidActive->Edid)[0x36 + 4]) & 0xF0) << 4) + (EdidActive->Edid)[0x36 + 2];
+ VerRes = ((((EdidActive->Edid)[0x36 + 7]) & 0xF0) << 4) + (EdidActive->Edid)[0x36 + 5];
+
+ Status = GetGraphicsModeNumber(GraphicsOutput, HorRes, VerRes, ModeNum, TRUE, NULL, NULL);
+ if(!EFI_ERROR(Status)) {
+ *ActualHorRes = HorRes;
+ *ActualVerRes = VerRes;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: SetupGraphicsDevice
+//
+// Description:
+// This function fills array of supported text modes
+//
+// Input:
+// IN GC_DATA *Data - pointer to private protocol data structure
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - function executed successfully
+// EFI_UNSUPPORTED - no supported modes found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetupGraphicsDevice(
+ IN GC_DATA *GcData
+)
+{
+ EFI_STATUS Status;
+ INT32 i;
+ UINT32 GraphicsModeNumber;
+ INT32 MaxSupportedModes = 1;
+ BOOLEAN DefaultModeNotSupported = FALSE;
+ INT32 ModeZeroIndex;
+ UINT32 HorRes;
+ UINT32 VerRes;
+
+ for(i = 0; i < MaxTextMode; i++) {
+ HorRes = TextModeArray[i].VideoCol;
+ VerRes = TextModeArray[i].VideoRow;
+ if(HorRes == 0 && VerRes == 0) {
+ Status = GetNativeResolution(GcData->GraphicsOutput, &GraphicsModeNumber, &HorRes, &VerRes);
+ } else {
+ /* get mode number with exact resolution */
+ Status = GetGraphicsModeNumber(GcData->GraphicsOutput,
+ HorRes,
+ VerRes,
+ &GraphicsModeNumber,
+ TRUE, NULL, NULL);
+ }
+
+ if(!EFI_ERROR(Status)) {
+ GcData->SupportedModes[i].Supported = TRUE;
+ GcData->SupportedModes[i].GraphicsMode = GraphicsModeNumber;
+ GcData->SupportedModes[i].ModeNum = TextModeArray[i].ModeNum;
+
+ if(TextModeArray[i].Col == 0)
+ GcData->SupportedModes[i].Col = HorRes / NARROW_GLYPH_WIDTH;
+ else
+ GcData->SupportedModes[i].Col = TextModeArray[i].Col;
+
+ if(TextModeArray[i].Row == 0)
+ GcData->SupportedModes[i].Row = VerRes / GLYPH_HEIGHT;
+ else
+ GcData->SupportedModes[i].Row = TextModeArray[i].Row;
+
+ GcData->SupportedModes[i].VideoCol = HorRes;
+ GcData->SupportedModes[i].VideoRow = VerRes;
+
+ MaxSupportedModes = (TextModeArray[i].ModeNum >= MaxSupportedModes) ?
+ TextModeArray[i].ModeNum + 1 : MaxSupportedModes;
+ } else {
+ GcData->SupportedModes[i].Supported = FALSE;
+ GcData->SupportedModes[i].ModeNum = TextModeArray[i].ModeNum;
+
+ if(TextModeArray[i].ModeNum == 0) {
+ ModeZeroIndex = i;
+ DefaultModeNotSupported = TRUE;
+ }
+ }
+ }
+
+ if(DefaultModeNotSupported) {
+ Status = GetGraphicsModeNumber(GcData->GraphicsOutput,
+ MODE_ZERO_MIN_HOR_RES,
+ MODE_ZERO_MIN_VER_RES,
+ &GraphicsModeNumber,
+ FALSE,
+ &(GcData->SupportedModes[ModeZeroIndex].VideoCol),
+ &(GcData->SupportedModes[ModeZeroIndex].VideoRow));
+ if(EFI_ERROR(Status)) {
+ (GcData->SimpleTextOut.Mode)->MaxMode = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ GcData->SupportedModes[ModeZeroIndex].Supported = TRUE;
+ GcData->SupportedModes[ModeZeroIndex].GraphicsMode = GraphicsModeNumber;
+ GcData->SupportedModes[ModeZeroIndex].Row = 25;
+ GcData->SupportedModes[ModeZeroIndex].Col = 80;
+ }
+
+ (GcData->SimpleTextOut.Mode)->MaxMode = MaxSupportedModes;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: ScrollUp
+//
+// Description:
+// This function scrolls screen one row up and clears bottom row
+//
+// Input:
+// IN GC_DATA *GcData - pointer to private protocol data structure
+//
+// Output:
+// VOID
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ScrollUp(
+ IN GC_DATA *GcData
+)
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;
+
+ GcData->GraphicsOutput->Blt(GcData->GraphicsOutput,
+ &Fill,
+ EfiBltVideoToVideo,
+ GcData->DeltaX,
+ GcData->DeltaY + GLYPH_HEIGHT,
+ GcData->DeltaX,
+ GcData->DeltaY,
+ GcData->MaxColumns * NARROW_GLYPH_WIDTH,
+ (GcData->MaxRows - 1) * GLYPH_HEIGHT,
+ 0);
+//clear bottom line
+ Fill = ColorArray[(((GcData->SimpleTextOut.Mode)->Attribute >> 4) & 0xf)];
+ GcData->GraphicsOutput->Blt(GcData->GraphicsOutput,
+ &Fill,
+ EfiBltVideoFill,
+ 0,
+ 0,
+ GcData->DeltaX,
+ GcData->DeltaY + (GcData->MaxRows - 1) * GLYPH_HEIGHT,
+ GcData->MaxColumns * NARROW_GLYPH_WIDTH,
+ GLYPH_HEIGHT,
+ 0);
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: SaveCursorImage
+//
+// Description:
+// This function saves image under cursor to restore, when cursor moves
+//
+// Input:
+// IN GC_DATA *GcData - pointer to private protocol data structure
+//
+// Output:
+// VOID
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SaveCursorImage(
+ IN GC_DATA *GcData
+)
+{
+ GcData->GraphicsOutput->Blt(
+ GcData->GraphicsOutput,
+ GcData->Cursor,
+ EfiBltVideoToBltBuffer,
+ GcData->DeltaX + (GcData->SimpleTextOut.Mode)->CursorColumn * NARROW_GLYPH_WIDTH,
+ GcData->DeltaY + (GcData->SimpleTextOut.Mode)->CursorRow * GLYPH_HEIGHT + CURSOR_OFFSET,
+ 0,
+ 0,
+ NARROW_GLYPH_WIDTH,
+ CURSOR_THICKNESS,
+ NARROW_GLYPH_WIDTH * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: ShiftCursor
+//
+// Description:
+// This function shifts cursor right to number of columns defined in Step
+// If cursor reaches right edge of the screen it moves one line down, scrolling screen
+// if nesessary
+//
+// Input:
+// IN GC_DATA *GcData - pointer to private protocol data structure
+// IN UINT16 Step - number of columns to shift cursor right
+//
+// Output:
+// VOID
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ShiftCursor(
+ IN GC_DATA *GcData,
+ IN UINT16 Step
+)
+{
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This = (EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *)GcData;
+
+ if(((GcData->SimpleTextOut.Mode)->CursorColumn + Step) >= (INT32)GcData->MaxColumns)
+ {
+ if((GcData->SimpleTextOut.Mode)->CursorRow == GcData->MaxRows - 1)
+ {
+ ScrollUp(GcData);
+ This->SetCursorPosition(
+ This,
+ 0,
+ (GcData->SimpleTextOut.Mode)->CursorRow);
+ }
+ else
+ {
+ This->SetCursorPosition(
+ This,
+ 0,
+ (GcData->SimpleTextOut.Mode)->CursorRow + 1);
+ }
+ }
+ else
+ {
+ This->SetCursorPosition(
+ This,
+ (GcData->SimpleTextOut.Mode)->CursorColumn + Step,
+ (GcData->SimpleTextOut.Mode)->CursorRow);
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GcUpdateBltBuffer
+//
+// Description:
+// This function is a porting hook to implement specific action on
+// Blt buffer before put it on screen
+//
+// Input:
+// IN GC_DATA *GcData - pointer to internal structure
+// IN UINT32 Width - width of passed buffer in pixels
+// IN UINT32 Height - height of passed buffer in pixels
+// IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer - pointer to Blt buffer
+// to perform action upon
+//
+// Output:
+// VOID
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID GcUpdateBltBuffer (
+ IN GC_DATA *This,
+ IN UINT32 Width,
+ IN UINT32 Height,
+ IN OUT EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
+)
+{
+ return;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: GcInternalClearScreen
+//
+// Description:
+// This function is a porting hook to implement specific action when
+// clear screen operation is needed
+//
+// Input:
+// IN GC_DATA *This - pointer to private protocol data structure
+//
+// Output:
+// VOID
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID GcInternalClearScreen (
+ IN OUT GC_DATA *This
+)
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fill;
+ EFI_STATUS Status;
+ UINT32 StartX;
+ UINT32 StartY;
+ UINT32 SizeX;
+ UINT32 SizeY;
+
+ if(This->MaxColumns == 0 || This->MaxRows == 0) { //this is the first invocation
+ StartX = 0;
+ StartY = 0;
+ SizeX = This->GraphicsOutput->Mode->Info->HorizontalResolution;
+ SizeY = This->GraphicsOutput->Mode->Info->VerticalResolution;
+ } else {
+ StartX = This->DeltaX;
+ StartY = This->DeltaY;
+ SizeX = This->MaxColumns * NARROW_GLYPH_WIDTH;
+ SizeY = This->MaxRows * GLYPH_HEIGHT;
+ }
+
+ Fill = ColorArray[(((This->SimpleTextOut.Mode)->Attribute >> 4) & 0xf)];
+ This->GraphicsOutput->Blt(This->GraphicsOutput,
+ &Fill,
+ EfiBltVideoFill,
+ 0,
+ 0,
+ StartX,
+ StartY,
+ SizeX,
+ SizeY,
+ 0);
+
+ Status = This->SimpleTextOut.SetCursorPosition(&(This->SimpleTextOut), 0, 0);
+ if(EFI_ERROR(Status)) { //on first invocation this failed because MaxRows = MaxCols = 0
+ (This->SimpleTextOut.Mode)->CursorColumn = 0;
+ (This->SimpleTextOut.Mode)->CursorRow = 0;
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: AddChar
+//
+// Description:
+// This function adds character to internal buffer of ready-to-print string
+//
+// Input:
+// IN GC_DATA *This - pointer to private protocol data structure
+// IN CHAR16 Char - character to add
+// IN UINT16 Width - character width in system font symbols
+//
+// Output:
+// VOID
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AddChar(
+ IN GC_DATA *GcData,
+ IN CHAR16 Char,
+ IN UINT16 Width
+)
+{
+ UINT32 CurrentWidth;
+
+ CurrentWidth = (GcData->SimpleTextOut.Mode)->CursorColumn + StringWidth;
+ if((CurrentWidth + Width) > GcData->MaxColumns) {
+ FlushString(GcData);
+
+ if(Width == 2)
+ ShiftCursor(GcData, 1);
+ }
+
+ TextBuffer[Position] = Char;
+ Position++;
+ StringWidth += Width;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: FlushString
+//
+// Description:
+// This function flushes string from internal buffer to screen
+//
+// Input:
+// IN GC_DATA *This - pointer to private protocol data structure
+//
+// Output:
+// VOID
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FlushString(
+ IN GC_DATA *GcData
+)
+{
+ EFI_STATUS Status;
+ EFI_FONT_DISPLAY_INFO FontInfo;
+ EFI_IMAGE_OUTPUT *Image = NULL;
+
+ if(Position == 0)
+ return;
+
+//retreive colors
+ GetColorFromAttribute(
+ (GcData->SimpleTextOut.Mode)->Attribute,
+ &FontInfo.ForegroundColor,
+ &FontInfo.BackgroundColor);
+//use system font
+ FontInfo.FontInfoMask = EFI_FONT_INFO_SYS_FONT
+ | EFI_FONT_INFO_SYS_SIZE
+ | EFI_FONT_INFO_SYS_STYLE;
+
+/* put NULL-terminator */
+ TextBuffer[Position] = 0;
+
+ Status = GcData->HiiFont->StringToImage(GcData->HiiFont,
+ EFI_HII_IGNORE_LINE_BREAK,
+ TextBuffer,
+ &FontInfo,
+ &Image,
+ 0, 0, NULL, NULL, NULL);
+
+ GcData->OemUpdateBltBuffer(GcData, Image->Width, Image->Height, Image->Image.Bitmap);
+
+ GcData->GraphicsOutput->Blt(
+ GcData->GraphicsOutput,
+ Image->Image.Bitmap,
+ EfiBltBufferToVideo,
+ 0,
+ 0,
+ GcData->DeltaX + (GcData->SimpleTextOut.Mode)->CursorColumn * NARROW_GLYPH_WIDTH,
+ GcData->DeltaY + (GcData->SimpleTextOut.Mode)->CursorRow * GLYPH_HEIGHT,
+ Image->Width,
+ Image->Height,
+ Image->Width * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+
+ ShiftCursor(GcData, (Image->Width / 8));
+
+ pBS->FreePool(Image->Image.Bitmap);
+ pBS->FreePool(Image);
+
+ Position = 0;
+ StringWidth = 0;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/GenericSio.c b/Core/CORE_DXE/GenericSio.c
new file mode 100644
index 0000000..af2c433
--- /dev/null
+++ b/Core/CORE_DXE/GenericSio.c
@@ -0,0 +1,3645 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/GenericSio.c 1 7/15/14 9:53p Chienhsieh $
+//
+// $Revision: 1 $Date: 4/04/05 4:37p $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/GenericSio.c $
+//
+// 1 7/15/14 9:53p Chienhsieh
+// Update rev.83 for EIP172950, Core updates for UEFI Variable Technical
+// Advisory implement.
+//
+// 83 6/26/14 6:27p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Removed Runtime-Access attribute from internal SIO
+// variables
+// [Files] GenericSio.c
+//
+// 82 2/13/13 5:29p Yakovlevs
+// [TAG] EIP109638
+// [Category] Improvement
+// [Description] Unpexetced behavior in AmiSioStart().
+// Keep calling InitSio instead of breking the execution.
+// [Files] GenericSio.c
+//
+// 81 7/20/12 2:42p Yakovlevs
+// Fixing Reconnect issue in case of multiple SIO.
+//
+// 80 2/09/12 12:40p Yakovlevs
+// [TAG] EIP82016
+// [Category] Bug Fix
+// [RootCause] incorrect _ALG handling in ApplyIoRes() function.
+// [Solution] Change expression in "if" statement to correctly reflect
+// _ALG operation.
+// [Files] GenericSio.c
+//
+// 79 11/08/11 11:15a Yakovlevs
+// [TAG] EIP72716
+// [Category] Improvement
+// [Description] Added Messages, Fixed issues in proposed by AMI China
+// solution.
+// [Files] GenericSio.c
+//
+// 78 10/28/11 6:18p Yakovlevs
+// [TAG] EIP72716
+// [Category] Improvement
+// [Description] Improvement for GenericSio.c
+// [Files] GenericSio.c
+//
+// 77 8/12/11 12:20p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 76 5/06/11 5:08p Yakovlevs
+// Made depencency on PI_SPECIFICATIO_VERSION tolen
+//
+// 75 5/04/11 6:03p Yakovlevs
+// [TAG] EIP 56527
+// [Category] New Feature
+// [Description] AMI_SIO_PROTOCOL was the source for PI 1.2 spec
+// proposal. Will require some minor modification of the interface plus
+// adding EFI_SIO_PROTOCOL Modify() function.
+// [Files] GenericSio.h; GenericSio.c.
+//
+// 74 4/20/11 4:38p Yakovlevs
+// Fixed potential issue in Stop function
+//
+// 73 2/25/11 3:17p Artems
+// EIP 54041: Renamed function AmiSioEntryPoint to GenericSioEntryPoint
+// to avoid dependency from SIO module
+//
+// 72 2/05/11 4:13p Artems
+// Fixed bug with ellow exclamation mark in Windows when keyboard not
+// present
+//
+// 71 2/02/11 12:09p Yakovlevs
+// [TAG] EIPNA
+// [Category] Improvement
+// [Description] Removed printing Remaining Device Path since it can
+// hung the system
+//
+// 67 8/23/10 3:35p Felixp
+// Enhancement(EIP 29307): Part of Runtime Trace support.
+// Code is updated to disable serial port 0 based on valueo f the
+// HideComPort variable.
+//
+// 66 2/04/10 11:51a Oleksiyy
+// Minor Fix
+//
+// 65 1/26/10 11:17a Yakovlevs
+// Bug fix EIP 32086: can't share IRQ when SIO logical devices' IRQ are in
+// share mode.
+//
+// 64 11/09/09 11:10a Krishnakumarg
+// EIP#30571: CloseEvent funtion should be used to kill events in callback
+// function.
+//
+// 63 10/09/09 5:28p Yakovlevs
+// Added Check for NULL pointer returned.
+//
+// 62 10/06/09 6:33p Yakovlevs
+// 1.Fixed some minor issues with the Status returned when Starting
+// Devices.
+// 2. Added Debug Messages Printing Remaining Device Path.
+//
+// 61 8/28/09 10:25a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 60 8/25/09 6:35p Yakovlevs
+// Fixed issue when NONE AUTO IRQ allocation method was used same IRQ may
+// be assigned to the different devices.
+//
+// 59 12/01/08 10:37a Yakovlevs
+// Added isAfterBootScript support. Now SIO initialization routine could
+// save
+// Runtime registers using isAfterBootScript initialization Step.
+//
+// 58 10/31/08 6:11p Yakovlevs
+// Fixed AmiSioStop routine
+//
+// 57 10/13/08 4:50p Yakovlevs
+// Fixed EIP 16394: ACPI removal causes infinite loop in GenericSio.c
+//
+// 56 10/07/08 10:49a Yakovlevs
+// Fixed potential issue when GenericSio build with ACPI_SUPPORT == 0
+//
+// 55 7/03/08 6:34p Yakovlevs
+// Fixed issue when SIO don't have a config mode and Pointers in GSPIO
+// structure were initialized with NULLs, it might hung in infinite loop.
+//
+// 4 6/06/08 10:29a Yakovlevs
+// Take care if SIO_STATUS_VAR might be created by some other drivers
+// Don't break if resources used by SIO IDX/DATA reg can not be clamed.
+//
+// 54 3/25/08 6:10p Yakovlevs
+// Code that creates device's NVRAM variables was acidentally removed.
+// Restoring it.
+//
+// 53 3/12/08 12:44p Felixp
+// Progress/Error codes reporting added
+//
+// 52 2/15/08 5:24p Felixp
+//
+// 51 2/06/08 5:59p Yakovlevs
+//
+// 50 2/06/08 5:19p Yakovlevs
+// Added detection if SIO device is actualy present or not.
+//
+// 48 10/23/07 10:20a Felixp
+// Minor bug fix in AmiSioSupported routine.
+//
+// 47 8/16/07 5:48p Yakovlevs
+//
+// 46 8/16/07 4:50p Yakovlevs
+// Chenges to fix BUILD issues when ACPI_SUPPORT is disabled
+//
+// 45 6/12/07 12:07a Yakovlevs
+// Fixed issue with SIO device with n o resources.
+//
+// 44 5/14/07 7:04p Yakovlevs
+// Changes to support SIO Setup Data Override.
+// Usefull if SIO uses none standard Setup Screens and Data Storage.
+//
+// 42 3/28/07 7:43p Yakovlevs
+// Changes to make use of LibGetDsdt() function
+//
+// 41 1/29/07 4:57p Yakovlevs
+// Fixed bug with IRQ reservation. Devices with no IRQ requests were
+// wrongfully flaged as "Assigned"
+//
+// 40 12/28/06 7:18p Yakovlevs
+//
+// 39 12/26/06 3:16p Yakovlevs
+// Dynamic IRQ Assignment final fix.
+//
+// 38 12/22/06 9:42p Yakovlevs
+// Fixed Dynamic ISA IRQ Allocation
+//
+// 37 11/27/06 3:56a Yakovlevs
+// Set up Notification on VariableWrite protocol to update ISA_IRQ_MASK
+// variable
+//
+// 36 11/27/06 2:20a Yakovlevs
+//
+// 35 11/27/06 12:06a Yakovlevs
+// Changes to sinchronize ISA IRQ allocation here and in CSM
+// NOTE will require to change ISA_IRQ_MASK token HAVE free IRQs as 0
+//
+// 34 10/12/06 9:42a Felixp
+// UEFI2.0 compliance: use CreateReadyToBootEvent instead of CreateEvent
+//
+// 33 9/11/06 11:10a Yakovlevs
+//
+// 32 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 31 8/04/06 6:10p Yakovlevs
+// Another fix for x64 SioDevStatusVarAttributes changet to UINT32
+//
+// 30 8/04/06 4:06p Yakovlevs
+// Fixed data types for x64 from UINN to UINT32 where needed.
+//
+// 26 5/24/06 11:39a Yakovlevs
+// Fixes to handle shared resources
+//
+// 25 5/23/06 5:08a Felixp
+// converted to the latest ACPI type definitions
+//
+// 24 5/23/06 4:26a Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 23 4/13/06 7:25p Yakovlevs
+// ACPI Disable Support added
+//
+// 22 4/10/06 5:29p Yakovlevs
+// ACPI NO ACPI mode fix.
+// Added Setting LPT device _PRS in NONE ACPI mode based on current LPT
+// MODE (SPP/EPP/ECP) SetLptPrs function.
+// Made Set???Prs functions Public(declared in GenericSio.H).
+//
+// 21 4/10/06 10:47a Yakovlevs
+// Fixed "IsaVenDevId" and "IsaSubVenId" mask usage.
+//
+// 20 4/03/06 3:52p Felixp
+// Major changes in PCI and Super I/O:
+// PCI - Root Bridge Resource Allocation Sepcification support
+// Super I/O - multiple Super I/O support; SIO Setup page added;
+//
+// 19 3/13/06 10:07a Felixp
+//
+// 17 11/23/05 11:26a Felixp
+// dev_status renamed to DEV_STATUS.
+//
+// 16 11/18/05 4:27p Ambikas
+// Creates/modifies SioDevStatusVar (formerly IOST).
+// Dev->Assigned = TRUE/FALSE moved from AssignResources to
+// ApplyResources.
+//
+// 14 11/07/05 3:06p Felixp
+// Unused references to Setup are removed
+//
+// 13 11/07/05 11:54a Ambikas
+//
+// 12 10/26/05 5:00p Ambikas
+//
+// 11 9/29/05 2:51p Robert
+// Initialization of Global Variables
+//
+// 10 5/18/05 11:02a Yakovlevs
+// Changes to Support Generic IO ranges for SIO GPIO, PME and HHM
+//
+// 9 5/12/05 9:34a Yakovlevs
+//
+// 8 5/11/05 3:05p Yakovlevs
+//
+// 7 4/22/05 2:42p Markw
+// Only save boot script once.
+//
+// 6 4/13/05 6:22p Sivagarn
+// - Included proper file header
+// - Fixed the bug in programming SIO config space
+//
+//
+//*****************************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: GenericSio.c
+//
+// Description: Generic Implementation of the AMI SIO Protocol.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+
+#if SIO_SUPPORT
+//==================================================================================
+
+#include <Efi.h>
+#include <pci.h>
+#include <Protocol\AmiSio.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\ComponentName2.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\VariableWrite.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <GenericSio.h>
+#include <AcpiRes.h>
+
+#if ACPI_SUPPORT
+//include this if ACPI is Supported
+#include <Acpi20.h>
+#include <Protocol\AcpiSupport.h>
+
+//
+//Some variables we need if ACPI mode is SUPPORTED
+//
+ACPI_HDR *gPDsdt=NULL;
+EFI_EVENT mAcpiEvent=NULL;
+VOID *mAcpiReg;
+EFI_GUID gAcpiSupportGuid=EFI_ACPI_SUPPORT_GUID;
+
+#endif
+
+#define _AND_ &
+#define SIO_MAX_REG 0xFF
+
+//==================================================================================
+//Global Variables
+//==================================================================================
+//extern SPIO_LIST_ITEM SIO_DEVICE_LIST EndOfList; // (EIP7580)-
+//SPIO_LIST_ITEM *gSpioList[] = {SIO_DEVICE_PTR_LIST NULL}; // (EIP7580)-
+BOOLEAN mVarWrite=FALSE;
+extern SPIO_LIST_ITEM *gSpioList[]; // (EIP7580)+
+extern const BOOLEAN HideComPort;
+UINTN gSpioCount=0;
+//global SPIO structure
+GSPIO *gSpio;
+EFI_EVENT mIsaEvent=NULL;
+VOID *mIsaReg;
+
+//--------------------------------------------------------
+
+static EFI_GUID gEfiAmiSioProtocolGuid = EFI_AMI_SIO_PROTOCOL_GUID;
+static EFI_GUID gDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+static EFI_GUID gPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+static EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+static EFI_GUID gDxeSvcTblGuid = DXE_SERVICES_TABLE_GUID;
+static EFI_GUID gSioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+static EFI_GUID gVariableWriteProtocolGuid = EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID;
+
+//DxeServices table Pointer to get access to the GCD Services
+static DXE_SERVICES *gDxeSvcTbl=NULL;
+//Driver Name
+static UINT16 *gDriverName=L"AMI Generic LPC Super I/O Driver";
+//ISA IRQ Mask tells which interrupts we can use for SIO devices
+static UINT16 gAvailableIsaIrq=0;//=ISA_IRQ_MASK;
+// Global variable to report which IRQs are being used in the SIO
+static UINT16 gUsedSioIrq=0;
+// Global variable to report which IRQs are requested/reserved in the SIO
+static UINT16 gReservedIrq=0;
+//ISA DMA Chanal Mask tells which DMA Chanals we can use for SIO devices
+static UINT8 gAvailableDmaChnl=0;//=ISA_DMA_MASK;//0xEF;
+
+static EFI_EVENT gEvtReadyToBoot = NULL;
+
+//==================================================================================
+//Some Function Prototypes to place Entry point at the beginning of this file
+//==================================================================================
+#ifdef EFI_DEBUG
+EFI_STATUS DevicePathToStr(EFI_DEVICE_PATH_PROTOCOL *Path,CHAR8 **Str);
+#endif
+EFI_STATUS EnumerateAll(GSPIO *Spio);
+
+SPIO_DEV* NewDev(SPIO_DEV_LST *SioDevInfo, GSPIO *Owner);
+EFI_STATUS SioSetupData(SPIO_DEV *Dev, BOOLEAN Get);
+
+//==================================================================================
+//Function Prototypes for Driver Binding Protocol Interface
+//==================================================================================
+EFI_STATUS AmiSioSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS AmiSioStart(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS AmiSioStop(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer);
+
+EFI_STATUS AmiSioComponentNameGetControllerName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName );
+
+EFI_STATUS AmiSioComponentNameGetDriverName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName);
+
+
+EFI_STATUS AmiSioRegister(IN AMI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value);
+
+
+EFI_STATUS AmiSioCRS(IN AMI_SIO_PROTOCOL *This,
+ IN BOOLEAN Set,
+ IN OUT T_ITEM_LIST **Resources);
+
+EFI_STATUS AmiSioPRS(IN AMI_SIO_PROTOCOL *This,
+ IN BOOLEAN Set,
+ IN OUT T_ITEM_LIST **Resources);
+
+EFI_STATUS ReserveIrq(SPIO_DEV *Dev, UINTN Index);
+
+static VOID CallbackReadyToBoot(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+
+
+
+EFI_STATUS CreateSioDevStatusVar();
+EFI_STATUS DisableDevInSioDevStatusVar(SPIO_DEV *Dev);
+VOID SaveSioRegs(GSPIO *Sio, SPIO_DEV *Dev, UINT8* InclRegList, UINTN InclRegCount, UINT8 *Buffer);
+VOID DevSelect(SPIO_DEV *Dev);
+
+#if ACPI_SUPPORT
+VOID GetDsdt(IN EFI_EVENT Event, IN VOID *Context);
+#endif
+VOID UpdateIsaMask(IN EFI_EVENT Event, IN VOID *Context);
+//==================================================================================
+//Driver binding protocol instance for AmiSio Driver
+EFI_DRIVER_BINDING_PROTOCOL gAmiSioDriverBinding = {
+ AmiSioSupported, //Supported
+ AmiSioStart, //PciBusDrvStart,
+ AmiSioStop, //PciBusDrvStop,
+ 0x10, //Version,
+ NULL, //Image Handle,
+ NULL //DriverBindingHandle,
+};
+
+//==================================================================================
+//Component Name Protocol Instance
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+EFI_COMPONENT_NAME2_PROTOCOL gAmiSioComponentName = {
+ AmiSioComponentNameGetDriverName,
+ AmiSioComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+//==================================================================================
+//Ami SIO Protocol instance
+AMI_SIO_PROTOCOL gAmiSioProtocol = {
+ AmiSioRegister,
+ AmiSioCRS,
+ AmiSioPRS,
+};
+
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+//EFI_SUPERIO_PROTOCOL Functions Forward declaration.
+EFI_STATUS EfiSioRegisterAccess(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value);
+
+
+EFI_STATUS EfiSioGetResourcces(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceList
+);
+
+EFI_STATUS EfiSioSetResources(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN ACPI_RESOURCE_HEADER_PTR ResourceList
+);
+
+EFI_STATUS EfiSioPossibleResources(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection
+);
+
+EFI_STATUS EfiSioModify(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN CONST EFI_SIO_REGISTER_MODIFY *Command,
+ IN UINTN NumberOfCommands
+);
+
+
+EFI_SIO_PROTOCOL gEfiSioProtocol = {
+ EfiSioRegisterAccess,
+ EfiSioGetResourcces,
+ EfiSioSetResources,
+ EfiSioPossibleResources,
+ EfiSioModify,
+};
+#endif
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: UpdateIsaMask
+//
+// Description:
+// This function will update gAvailableIsaIrq &gAvailableDmaChnl value
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID UpdateIsaMask(IN EFI_EVENT Event, IN VOID *Context){
+ EFI_STATUS Status;
+#if ACPI_SUPPORT
+ SPIO_DEV *dev;
+ UINTN j;
+#endif
+ UINTN i;
+//-------------------------
+
+ SIO_TRACE((TRACE_SIO,"GSIO: Variable Write Available!\n"));
+ Status = AmiIsaIrqMask(&gAvailableIsaIrq, TRUE);
+ if(Status==EFI_NOT_FOUND){
+ gAvailableIsaIrq=ISA_IRQ_MASK;
+ SIO_TRACE((TRACE_SIO,"GSIO: Get ISA_IRQ_MASK Status=%r Updating with DEFAULT %X\n",Status, gAvailableIsaIrq));
+ Status = AmiIsaIrqMask(&gAvailableIsaIrq, FALSE);
+ }
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO,"GSIO: ERROR Updating ISA_IRQ_MASK Status=%r\n",Status));
+ gAvailableIsaIrq=ISA_IRQ_MASK;
+ }
+
+ Status = AmiIsaDmaMask(&gAvailableDmaChnl, TRUE);
+ if(Status==EFI_NOT_FOUND){
+ gAvailableDmaChnl=ISA_DMA_MASK;
+ SIO_TRACE((TRACE_SIO,"GSIO: Get ISA_DMA_MASK Status=%r Updating with DEFAULT %X\n",Status, gAvailableDmaChnl));
+ Status=AmiIsaDmaMask(&gAvailableDmaChnl, FALSE);
+ }
+
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO,"GSIO: ERROR Updating ISA_DMA_MASK Status=%r\n",Status));
+ gAvailableDmaChnl=ISA_DMA_MASK;
+ }
+
+ mVarWrite=TRUE;
+
+ //ACPI Support was Installed Before VariableWrite Protocol
+ //So we have collected SIOs _PRS info but did not reserve IRQs yet!
+ SIO_TRACE((TRACE_SIO,"=================================================\n"));
+#if ACPI_SUPPORT
+ if(gPDsdt!=NULL){
+ for(i=0;i<gSpioCount;i++){
+ SIO_TRACE((TRACE_SIO,"GSIO: (ACPI Mode) Enumerate SIO Chip # %d >>>>> \n",i));
+ for(j=0; j<gSpio[i].DeviceCount; j++){
+ dev=gSpio[i].DeviceList[j];
+ if(dev->DeviceInfo->HasSetup) {
+ Status=SioSetupData(dev,TRUE);
+ SIO_TRACE((TRACE_SIO,"GSIO: Get SIO Setup Data. Status=%r\n",Status));
+ ASSERT_EFI_ERROR(Status);
+ }
+ //Taking care of issue 1 in EIP72716
+ if(!dev->DeviceInfo->Implemented) continue;
+ //For Irq reservation it might be a disabled by setup device that shares it's resources
+ //It appears to be a resource owner in such case it will have field Resource consumer filled.
+ if(!dev->NvData.DevEnable) if(dev->ResConsumer==NULL) continue;
+ Status=ReserveIrq(dev, j);
+ SIO_TRACE((TRACE_SIO,"GSIO: Reserve IRQ for SIO[%d].Device[%d] - Status=%r\n",i,j,Status));
+ }
+ SIO_TRACE((TRACE_SIO,"GSIO: (ACPI Mode) EnumerateAll for SIO Chip # %d -> Status=%r\n\n",i, Status));
+ }
+ }
+#else
+ //Set the Possible Resources for each implemented device
+ for(i=0;i<gSpioCount;i++){
+
+ SIO_TRACE((TRACE_SIO,"GSIO: (NO ACPI Mode) Enumerate SIO Chip # %d >>>>> \n",i));
+ Status=EnumerateAll(&gSpio[i]);
+ SIO_TRACE((TRACE_SIO,"GSIO: (NO ACPI Mode) EnumerateAll for SIO Chip # %d -> Status=%r\n\n",i, Status));
+ }
+ //install driver binding protocol here ....
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gAmiSioDriverBinding.DriverBindingHandle,
+ &gDriverBindingProtocolGuid,&gAmiSioDriverBinding,
+ &gEfiComponentName2ProtocolGuid, &gAmiSioComponentName,
+ NULL,NULL);
+
+#endif
+ if(Event) {
+ Status=pBS->CloseEvent(Event);
+ Event=NULL;
+ }
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: GenericSioEntryPoint
+//
+// Description:
+// This is Dxe init Entrypoint
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS AmiSioEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GenericSioEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status=0;
+ UINTN i,j;
+ SPIO_DEV *ro=NULL, *dev;//resource owner
+ SPIO_LIST_ITEM *sioli;
+ GSPIO *gspio;
+//--------------------------------------------------------------------
+ InitAmiLib(ImageHandle, SystemTable);
+
+ gDxeSvcTbl=(DXE_SERVICES*)GetEfiConfigurationTable(SystemTable,&gDxeSvcTblGuid);
+
+ //Fill ImgHandle Field in Driver Binding Protocol Structure
+ gAmiSioDriverBinding.ImageHandle=ImageHandle;
+ gAmiSioDriverBinding.DriverBindingHandle=NULL;
+
+
+ //Here we try to find a Variable for IRQ and DMA mask
+ Status = AmiIsaIrqMask(&gAvailableIsaIrq, TRUE);
+ //if Variable does not exists we create one
+ if(EFI_ERROR(Status)){
+ if(Status==EFI_NOT_FOUND) {
+ gAvailableIsaIrq=ISA_IRQ_MASK;
+ Status=AmiIsaIrqMask(&gAvailableIsaIrq, FALSE);
+ if(EFI_ERROR(Status))SIO_TRACE((TRACE_SIO, "GSIO: Unexpected Error while creating Var ISA_IRQ_MASK. STATUS = %r\n", Status));
+ else mVarWrite=TRUE;
+ } else SIO_TRACE((TRACE_SIO, "GSIO: Unexpected Error while getting var ISA_IRQ_MASK. STATUS = %r\n", Status));
+ } else mVarWrite=TRUE;
+
+ Status = AmiIsaDmaMask(&gAvailableDmaChnl, TRUE);
+ //if Variable does not exists we create one
+ if(EFI_ERROR(Status)){
+ if(Status==EFI_NOT_FOUND) {
+ gAvailableDmaChnl=ISA_DMA_MASK;
+ Status=AmiIsaDmaMask(&gAvailableDmaChnl, FALSE);
+ if(EFI_ERROR(Status))SIO_TRACE((TRACE_SIO, "GSIO: Unexpected Error while creating Var ISA_DMA_MASK. STATUS = %r\n", Status));
+ } else SIO_TRACE((TRACE_SIO, "GSIO: Unexpected Error while getting var ISA_DMA_MASK. STATUS = %r\n", Status));
+ }
+
+ //count number of SPIO_LIST_ITEMs in the system
+ for(i=0; ;i++){
+ sioli=gSpioList[i];
+ if(!sioli)break;
+ gSpioCount++;
+ };
+
+
+ gSpio=MallocZ(sizeof(GSPIO)*gSpioCount);
+ ASSERT(gSpio);
+ if(!gSpio) return EFI_OUT_OF_RESOURCES;
+ //init basic GSPIO structure and collect information about spio devices
+ //gSpio.Indx=SIO_CONFIG_INDEX;
+ //gSpio.Data=SIO_CONFIG_DATA;
+ for(j=0; j<gSpioCount; j++){
+ sioli=gSpioList[j];
+ gspio=&gSpio[j];
+
+ //gspio->ImageHandle=ImageHandle;
+ gspio->InCfgMode=FALSE;
+ gspio->SpioInfo=sioli;
+
+ gspio->GlobalCfgDump=MallocZ(sioli->GlobalInclRegCount);
+ ASSERT(gspio->GlobalCfgDump);
+ if(!gspio->GlobalCfgDump) return EFI_OUT_OF_RESOURCES;
+
+ //Save Initial (PowerOn after PEI Init) state of SIO Global registers (reg 0.. 2F usually)
+ SaveSioRegs(gspio, NULL, gspio->SpioInfo->GlobalIncludeReg,sioli->GlobalInclRegCount,gspio->GlobalCfgDump);
+
+ gspio->DeviceList=MallocZ(sizeof(VOID*)*sioli->DevCount);
+ ASSERT(gspio->DeviceList);
+ if(!gspio->DeviceList)return EFI_OUT_OF_RESOURCES;
+
+ for(i=0;i<sioli->DevCount;i++){
+ dev=NewDev(&sioli->SioDevList[i],gspio);
+ ASSERT(dev);
+ if(!dev) return EFI_OUT_OF_RESOURCES;
+ gspio->DeviceList[i]=dev;
+
+ if(dev->DeviceInfo->Flags && ro){
+ dev->ResOwner=ro;
+ ro->ResConsumer=dev;
+ }
+ //very first device in a list can't be a device with shared resources
+ if(!i && dev->DeviceInfo->Flags) return EFI_INVALID_PARAMETER;
+ ro=dev;
+ }
+ }
+#if ACPI_SUPPORT
+ GetDsdt(NULL,NULL);
+ //if no ACPISupport Protocol Available yet - install Notify Event
+ if(!gPDsdt) {
+ Status=RegisterProtocolCallback(&gAcpiSupportGuid,GetDsdt,NULL,&mAcpiEvent,&mAcpiReg);
+ SIO_TRACE((TRACE_SIO,"GSIO: Locate ACPISupport FAILURE. Installing Callback (%r)\n", Status));
+ } else SIO_TRACE((TRACE_SIO,"GSIO: Locate ACPISupport SUCCESS \n"));
+
+#endif
+ //Set the Callback for Variable Write
+ if(!mVarWrite){
+ Status=RegisterProtocolCallback(&gVariableWriteProtocolGuid,UpdateIsaMask,NULL,&mIsaEvent,&mIsaReg);
+ SIO_TRACE((TRACE_SIO,"GSIO: Variable Write FAILURE. Installing Callback (%r)\n", Status));
+ }
+
+
+ //Create event for boot script
+ Status = CreateReadyToBootEvent(
+ TPL_NOTIFY,
+ CallbackReadyToBoot,
+ NULL,
+ &gEvtReadyToBoot
+ );
+ ASSERT_EFI_ERROR(Status);
+
+
+ //Here we can set up notification events if needed
+
+
+
+ //------------------------------------
+ return Status;
+
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: GetDsdt
+//
+// Description:
+// This function will get gPDsdt address
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+#if ACPI_SUPPORT
+VOID GetDsdt(IN EFI_EVENT Event, IN VOID *Context){
+ UINTN i;
+ EFI_STATUS Status=0;
+ EFI_PHYSICAL_ADDRESS dsdtaddr=0;
+//-----------------------------
+
+ Status=LibGetDsdt(&dsdtaddr,EFI_ACPI_TABLE_VERSION_ALL);
+ if(EFI_ERROR(Status)) return;
+ else gPDsdt=(ACPI_HDR*)dsdtaddr;
+
+ if(!gPDsdt) SIO_TRACE((TRACE_SIO,"GSIO: FAIL to locate DSDT Table -> %r\n", Status));
+ else {
+ for(i=0;i<gSpioCount;i++){
+ Status=EnumerateAll(&gSpio[i]);
+ SIO_TRACE((TRACE_SIO,"GSIO: EnumerateAll (ACPI Mode) for SIO Chip # %d returned %r\n",i, Status));
+ }
+ //install driver binding protocol here ....
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gAmiSioDriverBinding.DriverBindingHandle,
+ &gDriverBindingProtocolGuid,&gAmiSioDriverBinding,
+ &gEfiComponentName2ProtocolGuid, &gAmiSioComponentName,
+ NULL,NULL);
+ }
+
+ if(Event) Status=pBS->CloseEvent(Event);
+}
+#endif
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: SioSetupData
+//
+// Description:
+//This Function will get NonVolatile SioDevice Setup Var if it is not present it will create it
+//or set Volatile SioDevice Setup Var parameter Get is the Action Selector
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS SioSetupData(SPIO_DEV *Dev, BOOLEAN Get){
+ EFI_STATUS Status=0,s2=0;
+ EFI_GUID ssg={0x560bf58a, 0x1e0d, 0x4d7e, 0x95, 0x3f, 0x29, 0x80, 0xa2, 0x61, 0xe0, 0x31};
+ UINT16 *vname;
+ UINTN vs;
+//---------------------------------
+ vname=MallocZ(sizeof(UINT16)*14);
+ ASSERT(vname);
+ if(!vname)return EFI_OUT_OF_RESOURCES;
+
+ if(Get){
+ //Get Non Volatile Variable for this Device
+ //the variable name is spels as "PNP"+Dev->PnpId+'_'+Dev_Uid"
+ Swprintf(&vname[0],L"PNP%04X_%X_NV",Dev->DeviceInfo->PnpId,Dev->DeviceInfo->UID);
+ vs=sizeof(SIO_DEV_NV_DATA);
+ Status = pRS->GetVariable(vname, &ssg, NULL, &vs, &Dev->NvData);
+ //upon creation Dev->NvData Dev->VlData was initialized with '0'
+ if(EFI_ERROR(Status)){
+ if(Status!=EFI_NOT_FOUND) return Status;
+ Dev->NvData.DevEnable=1; //Default is Enabled
+ }
+ //If SIO setup screens NOT using Generic SIO Setup Screens
+ //we need to get setup options from the global SETUP_DATA var.
+ if (Dev->DeviceInfo->InitRoutine!=NULL) Status=Dev->DeviceInfo->InitRoutine(&Dev->AmiSio,NULL,isGetSetupData);
+ } else {
+ //Set Volatile var
+ Swprintf(&vname[0],L"PNP%04X_%X_VV",Dev->DeviceInfo->PnpId,Dev->DeviceInfo->UID);
+ vs=sizeof(SIO_DEV_V_DATA);
+ s2 = pRS->SetVariable(vname, &ssg, EFI_VARIABLE_BOOTSERVICE_ACCESS, vs, &Dev->VlData);
+ //Set NonVolatile var
+ Swprintf(&vname[0],L"PNP%04X_%X_NV",Dev->DeviceInfo->PnpId,Dev->DeviceInfo->UID);
+ vs=sizeof(SIO_DEV_NV_DATA);
+ Status = pRS->SetVariable(vname, &ssg, EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE, vs, &Dev->NvData);
+ }
+ return (s2|Status);
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: NewDev
+//
+// Description:
+//Allocates memory for SPIO device Instance and init basic fields
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+SPIO_DEV* NewDev(SPIO_DEV_LST *SioDevInfo, GSPIO *Owner/*, UINTN BufferSize*/){
+ SPIO_DEV *dev;
+//---------------------------
+ dev=MallocZ(sizeof(SPIO_DEV));
+ if(!dev) return NULL;
+
+ //Fill out SPIO_DEV struct;
+ dev->Owner=Owner;
+ dev->DeviceInfo=SioDevInfo;
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+ dev->EfiSioData.Owner=dev;
+#endif
+
+ //dev->Type=SioDevInfo->Type;
+ //dev->LDN=SioDevInfo->LDN;
+ dev->EisaId.UID=SioDevInfo->UID;
+ dev->EisaId.HID=PNP_HID(SioDevInfo->PnpId);
+
+ //Get Device Setup Data Volatile and NonVolatile
+ //Can't use variable services now because it is NOT_AVAILABLE_YET
+ dev->VlData.DevImplemented=SioDevInfo->Implemented;
+ dev->NvData.DevEnable=SioDevInfo->Implemented;
+ //dev->Implemented=
+ //dev->Flags=SioDevInfo->Flags;
+ //dev->InitRoutine=SioDevInfo->InitRoutine;
+ dev->LocalCfgDump=MallocZ(Owner->SpioInfo->LocalInclRegCount);
+ if(!dev->LocalCfgDump){
+ pBS->FreePool(dev);
+ dev=NULL;
+ } else {
+ SaveSioRegs(Owner, dev, Owner->SpioInfo->LocalIncludeReg, Owner->SpioInfo->LocalInclRegCount, dev->LocalCfgDump);
+ Owner->DeviceCount++;
+ }
+ return dev;
+}
+
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: SioCfgMode
+//
+// Description:
+//Routine to transit Sio in/from Config Mode.
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID SioCfgMode(GSPIO *Sio, BOOLEAN Enter)
+{
+ UINTN i;
+ SPIO_SCRIPT_LST *sl;
+//---------------------------------
+ if(Enter)sl=Sio->SpioInfo->EnterCfgMode;
+ else sl=Sio->SpioInfo->ExitCfgMode;
+
+ if(sl==NULL) return;
+
+ for (i=0; i<sl->InstrCount; i++){
+ switch (sl->OpType){
+ case cfgNone:
+ break;
+ case cfgByteSeq:
+ {
+ SPIO_SCRIPT *Instr = (SPIO_SCRIPT*) sl->Instruction[0];
+ SPIO_SCRIPT *cmd = &Instr[i];
+ UINT16 reg;
+ UINT8 dat;
+ //------------------------
+ if(cmd->IdxDat)reg=Sio->SpioInfo->SioIndex;
+ else reg=Sio->SpioInfo->SioData;
+
+ if (cmd->WrRd) IoWrite8(reg,cmd->Value);
+ else {
+ UINTN c=100000;
+ dat=IoRead8(reg);
+ while( c && dat!=cmd->Value ) {
+ dat=IoRead8(reg);
+ c--;
+ }
+ }
+ break;
+ }
+ case cfgRoutine:
+ {
+ SPIO_ROUTINE rt=(SPIO_ROUTINE)sl->Instruction[i];
+ rt;
+ }
+ break;
+ default: return;
+ }//switch
+ }//for
+ Sio->InCfgMode=Enter;
+ return;
+}
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: SaveSioRegs
+//
+// Description:
+//Save Sio reg contents in the buffer
+//if Dev is NULL it did not selects the device
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID SaveSioRegs(GSPIO *Sio, SPIO_DEV *Dev, UINT8 *InclRegsList, UINTN InclRegCount, UINT8 *Buffer){
+ UINTN i;
+ UINT8 r;
+//------------------------
+ if(!Sio->InCfgMode) SioCfgMode(Sio, TRUE);
+ if(Dev)DevSelect(Dev);
+ for(i=0; i<InclRegCount; i++){
+ r=InclRegsList[i];
+ IoWrite8(Sio->SpioInfo->SioIndex,r);
+ Buffer[i]=IoRead8(Sio->SpioInfo->SioData);
+ }
+ SioCfgMode(Sio, FALSE);
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: GetPrsFromTable
+//
+// Description:
+//This function will get _PRS from mSpioDeviceList[] table
+//"Index" is the entry # in mSpioDeviceList[]
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS GetPrsFromTable(SPIO_DEV* Dev, UINTN Index){
+ SPIO_DEV_LST *de=Dev->DeviceInfo;//device entry
+ //IO1 IO2 IRQ1 IRQ2 DMA1 DMA2
+ VOID* *rl[6]= {NULL,NULL,NULL,NULL,NULL,NULL}; //resource list
+ UINT16 i=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+ SIO_TRACE((TRACE_SIO,"Dev[%d]: PRS Tbl=> \n", Index));
+
+ if (Dev->DeviceInfo->Flags==SIO_NO_RES){
+ SIO_TRACE((TRACE_SIO," Device NOT USING Resources FLAGS=0x%X\n", Dev->DeviceInfo->Flags));
+ return EFI_SUCCESS;
+ }
+
+ i = de->ResLen[0] | de->ResLen[1] | de->IrqMask[0] | de->IrqMask[1] | de->DmaMask[0] | de->DmaMask[1];
+ if(!i){
+ SIO_TRACE((TRACE_SIO,"Entry is Empty! Check 'YourSioName_DevLst' table.\n"));
+ return EFI_NOT_FOUND;
+ }
+ //Resource base and length 1
+ rl[0]=ASLM_FixedIO(de->ResBase[0],de->ResLen[0]);
+ if(!rl[0]) return EFI_OUT_OF_RESOURCES;
+ SIO_TRACE((TRACE_SIO,"IO1.B=%X; IO1.L=%X; ",de->ResBase[0],de->ResLen[0]));
+
+ //Resource base and length 2
+ rl[1]=ASLM_FixedIO(de->ResBase[1],de->ResLen[1]);
+ if(!rl[1]) return EFI_OUT_OF_RESOURCES;
+ SIO_TRACE((TRACE_SIO,"IO2.B=%X IO2.L=%X; ",de->ResBase[1],de->ResLen[1]));
+
+ //IRQ settings 1
+ rl[2]=ASLM_IRQNoFlags(1,0);
+ if(!rl[2]) return EFI_OUT_OF_RESOURCES;
+ ((ASLR_IRQNoFlags*)rl[2])->_INT=de->IrqMask[0];
+ SIO_TRACE((TRACE_SIO,"IRQ1=%X; ",de->IrqMask[0]));
+
+ //IRQ settings 2
+
+ rl[3]=ASLM_IRQNoFlags(1,0);
+ if(!rl[3]) return EFI_OUT_OF_RESOURCES;
+ ((ASLR_IRQNoFlags*)rl[3])->_INT=de->IrqMask[1];
+ SIO_TRACE((TRACE_SIO,"IRQ2=%X; ",de->IrqMask[1]));
+ //DMA settings 1
+ rl[4]=ASLM_DMA(1,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 0);
+ if(!rl[4]) return EFI_OUT_OF_RESOURCES;
+ ((ASLR_DMA*)rl[4])->_DMA=de->DmaMask[0];
+ SIO_TRACE((TRACE_SIO,"DMA1=%X; ",de->DmaMask[0]));
+ //DMA settings 2
+ rl[5]=ASLM_DMA(1,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 0);
+ if(!rl[5]) return EFI_OUT_OF_RESOURCES;
+ ((ASLR_DMA*)rl[5])->_DMA=de->DmaMask[1];
+ SIO_TRACE((TRACE_SIO,"DMA2=%X;",de->DmaMask[1]));
+
+ SIO_TRACE((TRACE_SIO,"\n"));
+
+ //Now Create _PRS Object for this device with best priorities
+ dl=ASLM_StartDependentFn(6,0,0,rl[0],rl[1],rl[2],rl[3],rl[4],rl[5]);
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+
+ SIO_TRACE((TRACE_SIO,"DepFn=%X,ItemCount=%d; ",(EFI_ASL_DepFn*)dl,((EFI_ASL_DepFn*)dl)->DepRes.ItemCount));
+ for(i=0;i<6;i++) {
+ SIO_TRACE((TRACE_SIO,"Item[%d]=%X ",i,((EFI_ASL_DepFn*)dl)->DepRes.Items[i]));
+ }
+ SIO_TRACE((TRACE_SIO,"\n <= Dev[%d]: PRS Tbl End \n",Index));
+ return AppendItemLst(&Dev->PRS, dl);
+}
+
+
+#if (! ACPI_SUPPORT)
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: Set***Prs
+//
+// Description:
+//These functions will collect _PRS from legacy concept,it is not support ACPI
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+//Create Possible Resource Settings Buffer for FDC
+EFI_STATUS SetFdcPrs(SPIO_DEV *Dev)
+{
+ EFI_STATUS Status;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+// StartDependentFn(0, 0) {
+// IO(Decode16, 0x3F0, 0x3F0, 1, 8)
+// IRQNoFlags() {6}
+// DMA(Compatibility, NotBusMaster, Transfer8) {2}
+// } //Same as
+// sdc_cnt,pComp,pPerf
+ dl=ASLM_StartDependentFn(4, 0, 0,
+ ASLM_FixedIO(0x3F0, 6), //0x3F6 port reserved for Legacy IDE
+ ASLM_FixedIO(0x3F7, 1),
+ ASLM_IRQNoFlags(1,6),
+ ASLM_DMA(1,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 2)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+// StartDependentFnNoPri() {
+// IO(Decode16, 0x3F0, 0x3F0, 1, 6)
+// IRQNoFlags() {3,4,5,6,7,10,11,12}
+// DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+// } same as
+ dl=ASLM_StartDependentFnNoPri(4,
+ ASLM_FixedIO(0x3F0,6), //0x3F6 port reserved for Legacy IDE
+ ASLM_FixedIO(0x3F7,1),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12),
+ ASLM_DMA(4,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8,0,1,2,3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri( 3,
+ ASLM_FixedIO(0x370, 6), //0x376 port reserved for Legacy IDE
+ ASLM_FixedIO(0x377, 1),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12),
+ ASLM_DMA(4,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8,0,1,2,3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+
+ Status=AppendItemLst(&Dev->PRS, dl);
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: Set***Prs
+//
+// Description:
+//These functions will collect _PRS from legacy concept,it is not support ACPI
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+//Create Possible Resource Settings Buffer for PS2 Keyboard
+EFI_STATUS SetPs2kPrs(SPIO_DEV *Dev)
+{
+ EFI_STATUS Status=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+ if(Dev->DeviceInfo->Type==dsPS2CM){
+ //Just in case overwrite porting settings
+ //Dev->DeviceInfo->Flags=SIO_SHR_ALL;
+ dl=ASLM_StartDependentFnNoPri( 4,
+ ASLM_FixedIO(0x60, 1),
+ ASLM_FixedIO(0x64, 1),
+ ASLM_IRQNoFlags(1, 1),
+ ASLM_IRQNoFlags(1, 12) );
+ } else {
+ Dev->DeviceInfo->Flags=SIO_SHR_IO;
+ dl=ASLM_StartDependentFnNoPri( 3,
+ ASLM_FixedIO(0x60, 1),
+ ASLM_FixedIO(0x64, 1),
+ ASLM_IRQNoFlags(1, 1) );
+ }
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+
+ Status=AppendItemLst(&Dev->PRS, dl);
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: Set***Prs
+//
+// Description:
+//These functions will collect _PRS from legacy concept,it is not support ACPI
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+//Create Possible Resource Settings Buffer for PS2 mouse
+EFI_STATUS SetPs2mPrs(SPIO_DEV *Dev)
+{
+ EFI_STATUS Status=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+ if(Dev->DeviceInfo->Type==dsPS2CM){
+ //Just in case overwrite porting settings
+ //Dev->DeviceInfo->Flags=SIO_SHR_ALL;
+ dl=ASLM_StartDependentFnNoPri( 4,
+ ASLM_FixedIO(0x60, 1),
+ ASLM_FixedIO(0x64, 1),
+ ASLM_IRQNoFlags(1, 1),
+ ASLM_IRQNoFlags(1, 12) );
+ } else {
+ Dev->DeviceInfo->Flags=SIO_SHR_IO;
+ dl=ASLM_StartDependentFnNoPri( 3,
+ ASLM_FixedIO(0x60, 1),
+ ASLM_FixedIO(0x64, 1),
+ ASLM_IRQNoFlags(1, 12) );
+ }
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+
+ Status=AppendItemLst(&Dev->PRS, dl);
+ return Status;
+}
+
+EFI_STATUS SetUartPrs(SPIO_DEV *Dev){
+ EFI_STATUS Status=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+ switch(Dev->EisaId.UID){
+ case 0 : //priority for Com 1;
+ dl=ASLM_StartDependentFn(2, 0,0,
+ ASLM_FixedIO(0x3F8, 8),
+ ASLM_IRQNoFlags(1,4)
+ );
+ break;
+ case 1 : //priority for Com 2;
+ dl=ASLM_StartDependentFn(2, 0,0,
+ ASLM_FixedIO(0x2F8, 8),
+ ASLM_IRQNoFlags(1,3)
+ );
+ break;
+ case 2 : //priority for Com 3;
+ dl=ASLM_StartDependentFn(2, 0,0,
+ ASLM_FixedIO(0x3E8, 8),
+ ASLM_IRQNoFlags(1,11)
+ );
+ break;
+
+ case 3 : //priority for Com 4;
+ dl=ASLM_StartDependentFn(2, 0,0,
+ ASLM_FixedIO(0x2E8, 8),
+ ASLM_IRQNoFlags(1,10)
+ );
+ break;
+ }
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ //the rest of resource combinations will go with No Priority
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x3F8, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x2F8, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x3E8, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x2E8, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: Set***Prs
+//
+// Description:
+//These functions will collect _PRS from legacy concept,it is not support ACPI
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS SetLptPrs(SPIO_DEV *Dev, BOOLEAN UseDma){
+ EFI_STATUS Status=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+
+ switch(Dev->EisaId.UID){
+ case 0 : //priority for LPT 1;
+ if(UseDma){
+ dl=ASLM_StartDependentFn(4, 0,0,
+ ASLM_FixedIO(0x378, 8),
+ ASLM_FixedIO(0x778, 8),
+ ASLM_IRQNoFlags(1,7),
+ ASLM_DMA(1,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 3)
+ );
+ } else {
+ dl=ASLM_StartDependentFn(2, 0,0,
+ ASLM_FixedIO(0x378, 8),
+ ASLM_IRQNoFlags(1,7)
+ );
+ }
+ break;
+ case 1 : //priority for LPT 2;
+ if(UseDma){
+ dl=ASLM_StartDependentFn(4, 0,0,
+ ASLM_FixedIO(0x278, 8),
+ ASLM_FixedIO(0x678, 8),
+ ASLM_IRQNoFlags(1,5),
+ ASLM_DMA(1,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1)
+ );
+ } else {
+ dl=ASLM_StartDependentFn(2, 0,0,
+ ASLM_FixedIO(0x278, 8),
+ ASLM_IRQNoFlags(1,5)
+ );
+ }
+ break;
+ }
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ //the rest of resource combinations will go with No Priority
+ if(UseDma){
+ //IRQ
+ dl=ASLM_StartDependentFnNoPri(4,
+ ASLM_FixedIO(0x378, 8),
+ ASLM_FixedIO(0x778, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12),
+ ASLM_DMA(2,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1, 3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(4,
+ ASLM_FixedIO(0x278, 8),
+ ASLM_FixedIO(0x678, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12),
+ ASLM_DMA(2,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1, 3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(4,
+ ASLM_FixedIO(0x3BC, 4),
+ ASLM_FixedIO(0x7BC, 4),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12),
+ ASLM_DMA(2,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1, 3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+ //No IRQ
+ dl=ASLM_StartDependentFnNoPri(3,
+ ASLM_FixedIO(0x378, 8),
+ ASLM_FixedIO(0x778, 8),
+ ASLM_DMA(2,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1, 3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(3,
+ ASLM_FixedIO(0x278, 8),
+ ASLM_FixedIO(0x678, 8),
+ ASLM_DMA(2,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1, 3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(3,
+ ASLM_FixedIO(0x3BC, 4),
+ ASLM_FixedIO(0x7BC, 4),
+ ASLM_DMA(2,ASLV_Compatibility, ASLV_NotBusMaster, ASLV_Transfer8, 1, 3)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+
+ } else { //No DMA MODE
+ //IRQ
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x378, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x278, 8),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x3BC, 4),
+ ASLM_IRQNoFlags(7, 3,4,5,6,10,11,12)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+ //No IRQ
+ dl=ASLM_StartDependentFnNoPri(1,
+ ASLM_FixedIO(0x378, 8)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(1,
+ ASLM_FixedIO(0x278, 8)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(1,
+ ASLM_FixedIO(0x3BC, 4)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ }
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+// Procedure: Set***Prs
+//
+// Description:
+//These functions will collect _PRS from legacy concept,it is not support ACPI
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS SetGamePrs(SPIO_DEV *Dev){
+ EFI_STATUS Status=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+
+ dl=ASLM_StartDependentFnNoPri(1,
+ ASLM_FixedIO(0x200, 8)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+
+ return Status;
+}
+
+EFI_STATUS SetMpu401Prs(SPIO_DEV *Dev){
+ EFI_STATUS Status=0;
+ T_ITEM_LIST *dl;
+//-----------------------------------
+
+
+ //the rest of resource combinations will go with No Priority
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x300, 2),
+ ASLM_IRQNoFlags(5, 5,7,9,10,11)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ if(EFI_ERROR(Status)) return Status;
+
+ dl=ASLM_StartDependentFnNoPri(2,
+ ASLM_FixedIO(0x330, 2),
+ ASLM_IRQNoFlags(5, 5,7,9,10,11)
+ );
+ if(!dl) return EFI_OUT_OF_RESOURCES;
+ Status=AppendItemLst(&Dev->PRS, dl);
+ return Status;
+}
+
+#else
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: GetPrsFromAml
+//
+// Description:
+//These function will collect _PRS from Aml code which support ACPI
+//"Index" is the entry # in mSpioDeviceList[]
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS GetPrsFromAml(SPIO_DEV* Dev, UINT8 *PrsName ,UINTN Index){
+ EFI_STATUS Status=0;
+ SPIO_DEV_LST *de=Dev->DeviceInfo;
+ ASL_OBJ_INFO obj={0}, prs={0};
+ UINT8 bc, *p, *prsb;
+ UINTN pl, bl;
+ ASLRF_S_HDR *rd;
+ EFI_ASL_DepFn *pdf=NULL;
+//---------------------------
+ if(de->AslName[0]==0) return GetPrsFromTable(Dev, Index);
+
+ Status=GetAslObj((UINT8*)gPDsdt+sizeof(ACPI_HDR),gPDsdt->Length-sizeof(ACPI_HDR)-1,&de->AslName[0],otDevice,&obj);
+ if(EFI_ERROR(Status)) {
+ SIO_TRACE((TRACE_SIO,"SIO[%d]: Aml=> Failed to Locate ASL Object %s in DSDT at %08X\n",Index,&de->AslName[0], gPDsdt));
+ return GetPrsFromTable(Dev, Index);
+ }
+
+ //it must be _PRS name Object there
+ if(!PrsName) Status = GetAslObj(obj.DataStart,obj.Length,"_PRS",otName,&prs);
+ else Status = GetAslObj(obj.DataStart,obj.Length,PrsName,otName,&prs);
+ if(EFI_ERROR(Status)) {
+ SIO_TRACE((TRACE_SIO,"SIO[%d]: Aml=> Failed to Locate _PRS Object in %s Object Scope at %08X\n",Index, &de->AslName[0], obj.Object));
+ return GetPrsFromTable(Dev, Index);
+ }
+
+ p=prs.DataStart;
+ if(*p==AML_OP_BUFFER){
+ pl=GetPackageLen((AML_PACKAGE_LBYTE*)(p+1),&bc);
+ //_PRS Name must be a "Buffer"
+ //DefBuffer := BufferOp PkgLength BufferSize ByteList
+ //BufferSize := TermArg=>Integer
+ //DataObject := (in our case ComputationalData) | DefPackage | DefVarPackage
+ p+=bc+2;
+ switch(*p){
+ case AML_PR_BYTE:
+ bl=*(p+1);
+ prsb=p+2;
+ break;
+ case AML_PR_WORD:
+ bl=*((UINT16*)(p+1));
+ prsb=p+3;
+ break;
+ case AML_PR_DWORD:
+ bl=*((UINT32*)(p+1));
+ prsb=p+5;
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ //Now Copy _PRS Buffer into new location and fill SIO.PRS T_ITEM_LIST
+ p=Malloc(bl);
+ if(!p) return EFI_OUT_OF_RESOURCES;
+ MemCpy(p,prsb,bl);
+ //Parse AML _PRS Buffer
+ rd=(ASLRF_S_HDR*)p;
+ prsb=p;
+ while(rd->Name!=ASLV_SR_EndTag){
+ //------------------------------
+ if(rd->Name==ASLV_RT_StartDependentFn){
+ //Add this item to device PRS list
+ pdf=MallocZ(sizeof(EFI_ASL_DepFn));
+ if(!pdf) return EFI_OUT_OF_RESOURCES;
+ pdf->DepFn=rd;
+ Status=AppendItemLst(&Dev->PRS, (VOID*)pdf);
+ if(EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ } else {
+ Status=AppendItemLst(&pdf->DepRes,rd);
+ if(EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ }
+ //advance to the next descriptor in _PRS ResourceTemplate
+ p+=sizeof(ASLRF_S_HDR)+rd->Length; //rd->Length => Byte length excluding length of the header
+ //It could be only IO, FixedIO, IRQ and DMA types of resources so it is small resource descriptor type
+ if((prsb+bl)<p){ //check if we still inside _PRS buffer or went out..
+ SIO_TRACE((TRACE_SIO,"SIO[%d]: Aml=> Failed to Locate EndDepFn in _PRS buffer of %s Object at %08X\n",Index ,&de->AslName[0],prs.Object));
+ return GetPrsFromTable(Dev, Index);
+ }
+ rd=(ASLRF_S_HDR*)p;
+ if(rd->Name==ASLV_RT_EndDependentFn) break;
+ } //while
+ if(!Dev->PRS.ItemCount){
+ SIO_TRACE((TRACE_SIO,"SIO[%d]: Aml=> Failed to Locate StartDepFn in _PRS buffer of %s Object at %08X\n",Index,&de->AslName[0],prs.Object));
+ return GetPrsFromTable(Dev, Index);
+ }
+ SIO_TRACE((TRACE_SIO,"SIO[%d]: Aml=> Collected %d DepFunc Items of %s Object \n",Index,Dev->PRS.ItemCount,&de->AslName[0]));
+ } else {
+ SIO_TRACE((TRACE_SIO,"SIO[%d]: Aml=> _PRS Object of %s Object is not a Buffer Type at %08X\n",Index,&de->AslName[0],prs.Object));
+ return GetPrsFromTable(Dev, Index);
+ }
+ return Status;
+}
+
+#endif
+
+
+// <AMI_PHDR_START>
+//-------------------------------------------------------------------------
+//
+// Procedure: EnumerateAll
+//
+// Description:
+//This Routine fill PRS property of the Implemented devices
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//-------------------------------------------------------------------------
+// <AMI_PHDR_END>
+static EFI_STATUS EnumerateAll(GSPIO *Spio){
+ UINTN i;
+ SPIO_DEV *dev;
+ EFI_STATUS Status=0;
+//-------------------
+ for(i=0; i<Spio->DeviceCount; i++){
+ dev=Spio->DeviceList[i];
+ SIO_TRACE((TRACE_SIO,"=================================================\n"));
+ SIO_TRACE((TRACE_SIO,"+> SIO[%d]; Implemented=%d; FLAGS=%X;", i, dev->DeviceInfo->Implemented, dev->DeviceInfo->Flags));
+ //Taking care of issue 1 in EIP72716
+ if (!dev->DeviceInfo->Implemented){
+ SIO_TRACE((TRACE_SIO,"<-\n"));
+ continue;
+ }
+ if(dev->DeviceInfo->HasSetup)Status=SioSetupData(dev,TRUE);
+ //For Irq reservation it might be a disabled by setup device that shares it's resources
+ //It appears to be a resource owner in such case it will have field Resource consumer filled.
+ SIO_TRACE((TRACE_SIO," Enabled=%d; SHR_RES=%d. <-\n",dev->NvData.DevEnable, (dev->ResConsumer!=NULL)));
+ if(!dev->NvData.DevEnable) if(dev->ResConsumer==NULL) continue;
+//if we don't have any ACPI support we still have to prowide _PRS for SIO devices
+//#ifndef rather DEBUG
+#if (!ACPI_SUPPORT)
+ switch (dev->DeviceInfo->Type){
+ case dsFDC: Status=SetFdcPrs(dev);
+ break;
+ case dsPS2CK:
+ case dsPS2K: Status=SetPs2kPrs(dev);
+ break;
+ case dsPS2CM:
+ case dsPS2M: Status=SetPs2mPrs(dev);
+ break;
+ case dsUART: Status=SetUartPrs(dev);
+ break;
+ case dsLPT: Status=SetLptPrs(dev,FALSE);
+ break;
+ case dsGAME: Status=SetGamePrs(dev);
+ break;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ case dsSB16: //Status=SetSb16Prs(dev);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ break;
+ case dsMPU401: Status=SetMpu401Prs(dev);
+ break;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ case dsFmSynth: //fill this
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ break;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ case dsCIR:
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ break;
+// case dsGPIO: Status=SetGpioPrs(dev);
+// break;
+// case dsHwMon: Status=SetHhmPrs(dev);
+// break;
+// case dsPME: Status=SetPmePrs(dev);
+// break;
+// case dsACPI:
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// break;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// Add to SIO_DEV_TYPE devices which may reside in SIO
+// Fill this switch with implementatio for missed SIO_DEV_TYPE
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ default : Status=GetPrsFromTable(dev, i);
+ }//switch
+#else
+ Status=GetPrsFromAml(dev,NULL,i);
+#endif
+ //if ACPI Support was Installed after VariableWrite Protocol
+ //we will reserve ISA IRQs now!
+ //if not we will do it when VariableWrite Event signalled.
+ if(EFI_ERROR(Status)) {
+ //check if device has a custom routine to get PRS settings.
+ if(dev->DeviceInfo->InitRoutine){
+ Status=dev->DeviceInfo->InitRoutine(&dev->AmiSio,NULL,isPrsSelect);
+ SIO_TRACE((TRACE_SIO,"GSIO: DevInitRoutine(isPrsSelect) - Status=%r.\n", Status));
+ }
+ Status=EFI_SUCCESS;
+ }
+ if(mVarWrite){
+ Status=ReserveIrq(dev, i);
+ SIO_TRACE((TRACE_SIO,"GSIO: Reserve IRQ for SIO.Device[%d] - Status=%r\n",i,Status));
+ }
+ SIO_TRACE((TRACE_SIO,"-------------------------------------------------\n\n"));
+ }//for
+
+ return Status;
+}
+
+
+
+//==================================================================================
+//Functions for Driver Binding Protocol Interface
+//==================================================================================
+EFI_STATUS AmiSioComponentNameGetControllerName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS AmiSioComponentNameGetDriverName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName)
+{
+ //Supports only English
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+
+//==============================================================================
+EFI_STATUS CheckSioDevicePath(EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ // Check if the RemainingDevicePath is valid
+ if (DevicePath->Type!=ACPI_DEVICE_PATH ||
+ DevicePath->SubType!= ACPI_DP ||
+ NODE_LENGTH(DevicePath) != ACPI_DEVICE_PATH_LENGTH )
+ return EFI_UNSUPPORTED;
+ else return EFI_SUCCESS;
+}
+
+
+//==================================================================================
+//Functions for Driver Binding Protocol Interface
+//==================================================================================
+EFI_STATUS AmiSioSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ UINT8 cc[4];
+ UINTN sn,bn,dn,fn,i;
+ UINT32 sid, id;
+ BOOLEAN AlreadyStarted = FALSE, m;
+ GSPIO *spio;
+//---------------------------------------------------------
+ //Check if it is valid Device Path
+ if(RemainingDevicePath){
+ Status=CheckSioDevicePath(RemainingDevicePath);
+ if(EFI_ERROR(Status))return Status;
+ }
+
+ //Check if it is real hardware or some virtual driver faking hardware
+ //the real hardware has to have DevPath Protocol on it's HAndle
+ Status=pBS->OpenProtocol( Controller, &gDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if ( EFI_ERROR(Status) && Status!= EFI_ALREADY_STARTED) return Status;
+
+ pBS->CloseProtocol(Controller,&gDevicePathProtocolGuid,This->DriverBindingHandle, Controller);
+
+ //This is real hardware we are dealing with but it has to be PCI2LPC/ISA bridge
+ //So check if it has PCI IO Protocol on its Handle
+ Status=pBS->OpenProtocol( Controller,&gPciIoProtocolGuid,(VOID **)&PciIo,
+ This->DriverBindingHandle,Controller,EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if(Status==EFI_ALREADY_STARTED){
+ AlreadyStarted = TRUE;
+ Status=pBS->OpenProtocol(Controller,&gPciIoProtocolGuid,(VOID **)&PciIo,
+ This->DriverBindingHandle,Controller,EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ }
+
+ if(EFI_ERROR(Status))return Status;
+
+ //PciIo Protocol present.
+ //Read PCI Class Code Reg to find out which Device is that
+ Status=PciIo->Pci.Read(PciIo,EfiPciIoWidthUint32,PCI_REV_ID_OFFSET,1,&cc);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ //VendorID DevId
+ Status=PciIo->Pci.Read(PciIo,EfiPciIoWidthUint32,0,1,&id);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ //Subsystem VendorID
+ Status=PciIo->Pci.Read(PciIo,EfiPciIoWidthUint32,0x2c,1,&sid);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ //Controller PCI Location
+ Status=PciIo->GetLocation(PciIo,&sn, &bn, &dn, &fn);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //try to select right SIO device bridge for this sio
+ Status=EFI_UNSUPPORTED;
+ for(i=0; i<gSpioCount; i++){
+ spio=&gSpio[i];
+
+ //if(spio->SpioInfo->IsaVenDevId==-1)m=TRUE;
+ //else
+ m=((spio->SpioInfo->IsaVenDevId & id) == id );
+ if(!m) continue;
+
+ //if(spio->SpioInfo->IsaSubVenId==-1)m=TRUE;
+ //else
+ m=((spio->SpioInfo->IsaSubVenId & sid) == sid);
+ if(!m) continue;
+
+ if(spio->SpioInfo->IsaBusNo==(UINT8)-1)m=TRUE;
+ else m=(spio->SpioInfo->IsaBusNo==bn);
+ if(!m) continue;
+
+ if(spio->SpioInfo->IsaDevNo==(UINT8)-1)m=TRUE;
+ else m=(spio->SpioInfo->IsaDevNo==dn);
+ if(!m) continue;
+
+ if(spio->SpioInfo->IsaFuncNo==(UINT8)-1)m=TRUE;
+ else m=(spio->SpioInfo->IsaFuncNo==fn);
+ if(!m) continue;
+
+ //if we are here: The controller PCi properties matched the SPIO_LIST ITEM table
+ spio->SupportedHandle=Controller;
+ Status=EFI_SUCCESS;
+ }
+ //Check it has to be LPC/ISA bridge who hosts SIO
+ //byte0=RevId;byte1=BaseClassCode;byte2=SubClassCode;byte3=ProgrInterface
+ if( Status && ( cc[3]==PCI_CL_BRIDGE && cc[2]==PCI_CL_BRIDGE_SCL_ISA && cc[1]==0 )) Status=EFI_SUCCESS;
+
+ if (!AlreadyStarted) pBS->CloseProtocol(Controller,&gPciIoProtocolGuid,This->DriverBindingHandle,Controller);
+
+ return Status;
+}
+
+
+//==============================================================================================
+//This Function Assumes SIO in Config Mode and LD has been selected
+VOID SioRegister(SPIO_DEV *Dev, BOOLEAN Write, UINT8 Reg, UINT8 *Val){
+ IoWrite8(Dev->Owner->SpioInfo->SioIndex,Reg);
+ if(Write)IoWrite8(Dev->Owner->SpioInfo->SioData,*Val);
+ else *Val=IoRead8(Dev->Owner->SpioInfo->SioData);
+}
+
+//==============================================================================================
+//this Function Assumes SIO is in Config Mode
+VOID DevSelect(SPIO_DEV *Dev){
+//----------------
+ IoWrite8(Dev->Owner->SpioInfo->SioIndex,Dev->Owner->SpioInfo->DevSel);
+ IoWrite8(Dev->Owner->SpioInfo->SioData,Dev->DeviceInfo->LDN);
+}
+
+
+//==============================================================================================
+//this function will probe SIO device if something "alive" there.
+//this Function Assumes SIO is in Config Mode
+EFI_STATUS CheckDevicePresent(SPIO_DEV *Dev){
+ UINT8 val;
+//---------------
+ DevSelect(Dev);
+ val=IoRead8(Dev->Owner->SpioInfo->SioData);
+ //it must read Device's LDN
+ if(Dev->DeviceInfo->LDN!=val) return EFI_NO_RESPONSE;
+ else return EFI_SUCCESS;
+}
+
+//==============================================================================================
+//this Function Assumes SIO is in Config Mode
+VOID DevEnable(SPIO_DEV *Dev, BOOLEAN Enable){
+ UINT8 v = Enable ? Dev->Owner->SpioInfo->ActivVal : Dev->Owner->SpioInfo->DeactVal;
+//----------------
+ DevSelect(Dev);
+ IoWrite8(Dev->Owner->SpioInfo->SioIndex,Dev->Owner->SpioInfo->Activate);
+ IoWrite8(Dev->Owner->SpioInfo->SioData,v);
+// Dev->Active=Enable;
+}
+
+
+//selects resource by number
+T_ITEM_LIST *GetNumResources(T_ITEM_LIST *DfLst, UINT8 *num ){
+// ASLRF_S_HDR *hdr;
+ EFI_ASL_DepFn *df=NULL;//*dfnp,*dfwp;
+//-------------------------------------
+
+ if(*num<DfLst->ItemCount){
+// hdr=(ASLRF_S_HDR*)DfLst->Items[*num];
+// if(hdr->Length==1) {
+// dfwp=(EFI_ASL_DepFn*)hdr;
+ df=(EFI_ASL_DepFn*)DfLst->Items[*num];
+ return &df->DepRes;
+// }
+// if(hdr->Length==0) {
+// dfnp=(EFI_ASL_DepFnNoPri*)hdr;
+// return &dfnp->DepRes;
+// }
+// *num=(UINT8)DfLst->ItemCount;
+// return NULL;
+ } else *num=(UINT8)DfLst->ItemCount;
+ return NULL;
+}
+
+
+//Selects Resources by Priotity settings.
+//UINT8 *num number of descriptors in Dependency list;
+T_ITEM_LIST *GetPriResources(T_ITEM_LIST *DfLst, UINT8 cmp, UINT8 prf){
+ UINTN i;
+ ASLRF_S_HDR *hdr;
+ EFI_ASL_DepFn *df;
+//-------------------------------------
+ for(i=0; i<DfLst->ItemCount; i++){
+ df=DfLst->Items[i];
+ hdr=(ASLRF_S_HDR*)df->DepFn;
+ if(hdr->Length==1) {
+ if(((ASLR_StartDependentFn*)df->DepFn)->_PRI._CMP==cmp ||
+ ((ASLR_StartDependentFn*)df->DepFn)->_PRI._PRF==prf)
+ return &df->DepRes;
+ }
+ }
+ return NULL;
+}
+
+
+//Implement Function which(like GCD) will controll DMA resource assignment
+BOOLEAN AssignDma(UINT8 ChNo, ASLRF_DFLAGS *Flags){
+ UINT16 dma;
+ UINTN sz=sizeof(gAvailableIsaIrq);
+ EFI_STATUS Status;
+//------------------------
+ Status=AmiIsaDmaMask(&gAvailableDmaChnl, TRUE);
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO, "Unexpected Error while refreshing Var ISA_DMA_MASK. STATUS = %r\n", Status));
+ return FALSE;
+ }
+
+ SIO_TRACE((TRACE_SIO, "Updating ISA_DMA_MASK = 0x%X", gAvailableIsaIrq));
+
+ dma=(1<<ChNo);
+ if((~gAvailableDmaChnl) & dma){
+ gAvailableDmaChnl |= dma;
+ Status=AmiIsaDmaMask(&gAvailableDmaChnl,FALSE);
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO, "Unexpected Error. STATUS = %r\n", Status));
+ return FALSE;
+ }
+ SIO_TRACE((TRACE_SIO, " with 0x%X for Chnl %d\n", dma, ChNo ));
+ return TRUE;
+ } else return FALSE;
+}
+
+//Implement Function which(like GCD) will controll IRQ resource assignment
+BOOLEAN AssignIrq(UINT8 IrqNo, ASLRF_IFLAGS *Flags){
+ UINT16 irq;
+ EFI_STATUS Status;
+//------------------------
+
+ Status=AmiIsaIrqMask(&gAvailableIsaIrq, TRUE);
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO, "Unexpected Error while refreshing Var ISA_IRQ_MASK. STATUS = %r\n", Status));
+ return FALSE;
+ }
+
+ SIO_TRACE((TRACE_SIO, "Updating ISA_IRQ_MASK = 0x%X", gAvailableIsaIrq));
+
+ irq=(1<<IrqNo);
+ if((~gAvailableIsaIrq) & irq){
+ gAvailableIsaIrq |= irq;
+ gReservedIrq |= irq;
+ Status=AmiIsaIrqMask(&gAvailableIsaIrq,FALSE);
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO, "Unexpected Error. STATUS = %r\n", Status));
+ return FALSE;
+ }
+ SIO_TRACE((TRACE_SIO, " with 0x%X for IRQ# %d ISA_IRQ_MASK=%X gReservedIrq=%X\n", irq, IrqNo,gAvailableIsaIrq, gReservedIrq));
+ return TRUE;
+ } else return FALSE;
+}
+
+BOOLEAN AssignIo(UINT16 *Base, UINT8 Len, UINT8 Aln){
+ EFI_PHYSICAL_ADDRESS addr=*Base;
+ EFI_STATUS Status;
+//------------------------------------
+
+ if(!gDxeSvcTbl) return FALSE;
+ Status=gDxeSvcTbl->AllocateIoSpace(EfiGcdAllocateAddress,//IN EFI_GCD_ALLOCATE_TYPE AllocateType,
+ EfiGcdIoTypeIo,//IN EFI_GCD_IO_TYPE GcdIoType,
+ Aln,//IN UINTN Alignment,
+ Len, //IN UINT64 Length,
+ &addr,//IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ gAmiSioDriverBinding.ImageHandle,// IN EFI_HANDLE ImageHandle,
+ NULL //IN EFI_HANDLE DeviceHandle OPTIONAL
+ );
+ SIO_TRACE((TRACE_SIO,"AssignIo Status=%r,*Base=%x, addr=%x, Len=%x, Aln=%x\n",Status,*Base,addr,Len,Aln));
+ if(EFI_ERROR(Status)||((*Base)!=(UINT16)addr))return FALSE;
+ *Base=(UINT16)addr;
+ return TRUE;
+}
+
+
+
+VOID *ApplyDmaRes(ASLRF_S_HDR* Hdr, SPIO_DEV* Dev,UINT8 ResNo ){
+ UINT8 dmac=0;
+ UINT8 i;
+ BOOLEAN a=FALSE;
+ ASLR_DMA *dmar=(ASLR_DMA*)Hdr, *rd=NULL;
+//--------------------------
+
+ rd=ASLM_DMA(1,dmar->Flags._TYP,dmar->Flags._BM, dmar->Flags._SIZ,0);
+ if(rd==NULL) return rd;
+
+ rd->_DMA=0;
+
+ //Don't need to run all this if we got an empty descriptor
+ if(!dmar->_DMA) return rd;
+
+ for(i=0; i<8; i++){
+ dmac=dmar->_DMA&(1<<i);
+ if(dmac){
+ if((Dev->DeviceInfo->Flags&SIO_SHR_DMA2) && ResNo ) a=TRUE;
+ else {
+ if((Dev->DeviceInfo->Flags&SIO_SHR_DMA1) && !ResNo) a=TRUE;
+ else a=AssignDma(i, &dmar->Flags);
+ }
+ if(a){
+ UINT8 r;
+ //---------------------
+ if(ResNo){
+ r=Dev->Owner->SpioInfo->Dma2;
+ Dev->VlData.DevDma2=i;
+ } else {
+ r=Dev->Owner->SpioInfo->Dma1;
+ Dev->VlData.DevDma1=i;
+ }
+ SioRegister(Dev,TRUE,r,&i);
+
+ rd->_DMA=i;
+ return rd;
+ }
+ }
+ } //for
+ if(rd)pBS->FreePool(rd);
+ return NULL;
+}
+
+
+
+VOID *ApplyIrqRes(ASLRF_S_HDR* Hdr, SPIO_DEV* Dev, UINT8 ResNo, BOOLEAN IrqReserve){
+ UINT16 irqm=0;
+ UINT8 i;
+ BOOLEAN a=FALSE;
+ ASLR_IRQ *irqr=(ASLR_IRQ*)Hdr, *rd=NULL;
+//--------------------------
+
+ SIO_TRACE((TRACE_SIO,"GSIO: Device's IRQ_MSK=%X; ",irqr->_INT));
+
+ //Create Irq resource descriptors based on request
+ if(!IrqReserve){
+ if(irqr->Hdr.Length==3) rd=ASLM_IRQ(1,irqr->Flags._LL,irqr->Flags._HE, irqr->Flags._SHR,0);
+ else rd=ASLM_IRQNoFlags(1,0);
+ rd->_INT=0;
+ }
+
+ //Don't need to run all this if we got an empty descriptor
+ if(!irqr->_INT) {
+ SIO_TRACE((TRACE_SIO," - Device's has empty IRQ descriptor.rd=NULL\n"));
+ return rd;
+ }
+
+
+ for(i=0; i<16; i++){
+ irqm=irqr->_INT&(1<<i);
+ if(irqm ){
+ //if we hit IRQ that was used already by some other SIO device, just skip it.
+ if((IrqReserve == FALSE) && ((irqm & gUsedSioIrq ) && (!(Dev->DeviceInfo->Flags & SIO_SHR_IRQ)) ) ) continue;
+
+ if((Dev->DeviceInfo->Flags&SIO_SHR_IRQ2) && ResNo ) a=TRUE;
+ else {
+ if((Dev->DeviceInfo->Flags&SIO_SHR_IRQ1) && !ResNo) a=TRUE;
+ else {
+ if(!Dev->IrqReserved) a=AssignIrq(i, &irqr->Flags);
+ else a=TRUE;
+ }
+ }
+ if(a){
+ UINT8 r;
+ //---------------------
+ if(IrqReserve) {
+ Dev->IrqReserved=TRUE;
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyIrq - IrqReserve=%d. Returning NULL!",IrqReserve));
+ return NULL;
+ }
+ //Special Case for PS2C (PS2K and PS2M in the same LD)
+ if(Dev->DeviceInfo->Type==dsPS2CM) ResNo=1;
+ if(ResNo){
+ r=Dev->Owner->SpioInfo->Irq2;
+ Dev->VlData.DevIrq2=i;
+ } else {
+ r=Dev->Owner->SpioInfo->Irq1;
+ Dev->VlData.DevIrq1=i;
+ }
+ gUsedSioIrq |= irqm;
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyIrq - dsPS2CM=%d; Register=0x%X; Value=0x%X; gUsedSioIrq=0x%X.",
+ (Dev->DeviceInfo->Type==dsPS2CM), r, i, gUsedSioIrq));
+ SioRegister(Dev,TRUE,r,&i);
+ rd->_INT=i;
+ return rd;
+ }
+ }
+ }
+ if(rd)pBS->FreePool(rd);
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyIrq - can't find resources. Returning NULL!"));
+ return NULL;
+}
+
+VOID *ApplyFixedIoRes(ASLRF_S_HDR* Hdr, SPIO_DEV* Dev, UINT8 ResNo){
+ BOOLEAN a=FALSE;
+ ASLR_FixedIO *iord=(ASLR_FixedIO*)Hdr, *rd=NULL;
+//--------------------------
+ rd=ASLM_FixedIO(iord->_BAS, iord->_LEN);
+
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyFixedIO BAS=%x, LEN=%x, rd=%x; ",iord->_BAS,iord->_LEN,rd));
+
+ //Don't need to run all this if we got an empty descriptor
+ if(!iord->_LEN) {
+ SIO_TRACE((TRACE_SIO,"Empty Descriptor\n"));
+ return rd;
+ }
+
+ if((Dev->DeviceInfo->Flags&SIO_SHR_IO2) && ResNo ) a=TRUE;
+ else {
+ if((Dev->DeviceInfo->Flags&SIO_SHR_IO1) && !ResNo) a=TRUE;
+ else a=AssignIo(&rd->_BAS, rd->_LEN, 0);
+ }
+
+ if(a){
+ UINT8 r, *b;
+ //---------------------
+ b=(UINT8*)&iord->_BAS;
+
+ if(ResNo){
+ r=Dev->Owner->SpioInfo->Base2Hi;
+ Dev->VlData.DevBase2=iord->_BAS;
+ } else {
+ r=Dev->Owner->SpioInfo->Base1Hi;
+ Dev->VlData.DevBase1=iord->_BAS;
+ }
+ SioRegister(Dev,TRUE,r,&b[1]);
+
+ if(ResNo)r=Dev->Owner->SpioInfo->Base2Lo;
+ else r=Dev->Owner->SpioInfo->Base1Lo;
+ SioRegister(Dev,TRUE,r,&b[0]);
+
+ SIO_TRACE((TRACE_SIO,"r=%x,b[0]=%x,b[1]=%x\n",r,b[0],b[1]));
+
+ return rd;
+ }
+ if(rd)pBS->FreePool(rd);
+ SIO_TRACE((TRACE_SIO,"returning NULL\n"));
+ return NULL;
+}
+
+VOID *ApplyIoRes(ASLRF_S_HDR* Hdr, SPIO_DEV* Dev, UINT8 ResNo){
+ BOOLEAN a=FALSE;
+ ASLR_IO *iord=(ASLR_IO*)Hdr,*rd;
+ UINT8 aln=0;
+//--------------------------
+ rd=ASLM_IO(iord->_DEC,iord->_MIN,iord->_MAX,iord->_ALN,iord->_LEN);
+
+ //Don't need to run all this if we got an empty descriptor
+ if(!iord->_LEN) return rd;
+
+ if((Dev->DeviceInfo->Flags&SIO_SHR_IO2) && ResNo ) a=TRUE;
+ else {
+ if((Dev->DeviceInfo->Flags&SIO_SHR_IO1) && !ResNo) a=TRUE;
+ else {
+ if((rd->_ALN) != 0)aln=rd->_ALN-1;
+ a=AssignIo(&rd->_MIN, rd->_LEN,aln);
+ }
+ }
+
+ if(a){
+ UINT8 r, *b;
+ //---------------------
+ b=(UINT8*)&iord->_MIN;
+
+ //Special Case for FDC (second resource request 0x3F7 don't have a corresponded register)
+ if((Dev->DeviceInfo->Type==dsFDC) && (ResNo==1)) return rd;
+
+ if(ResNo){
+ r=Dev->Owner->SpioInfo->Base2Hi;
+ Dev->VlData.DevBase2=iord->_MIN;
+ } else {
+ r=Dev->Owner->SpioInfo->Base1Hi;
+ Dev->VlData.DevBase1=iord->_MIN;
+ }
+ SioRegister(Dev,TRUE,r,&b[1]);
+
+ if(ResNo)r=Dev->Owner->SpioInfo->Base2Lo;
+ else r=Dev->Owner->SpioInfo->Base1Lo;
+ SioRegister(Dev,TRUE,r,&b[0]);
+
+ return rd;
+ }
+ if(rd)pBS->FreePool(rd);
+ return NULL;
+}
+
+VOID FreeIrq(SPIO_DEV *dev, ASLR_IRQ *dsc)
+{
+ if ((gAvailableIsaIrq & dsc->_INT) == 0) {
+ gAvailableIsaIrq &= dsc->_INT;
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Irq1, 0);
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Irq2, 0);
+ }
+}
+
+VOID FreeDma(SPIO_DEV *dev, ASLR_DMA *dsc)
+{
+ if ((gAvailableDmaChnl & dsc->_DMA) == 0) {
+ gAvailableDmaChnl &= dsc->_DMA;
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Dma1, 0);
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Dma2, 0);
+ }
+}
+
+VOID FreeIo(SPIO_DEV *dev, ASLRF_S_HDR *dsc){
+
+ if(dsc->Name==ASLV_RT_FixedIO){
+ gDxeSvcTbl->FreeIoSpace( ((ASLR_FixedIO*)dsc)->_BAS, ((ASLR_FixedIO*)dsc)->_LEN);
+ } else {
+ gDxeSvcTbl->FreeIoSpace( ((ASLR_IO*)dsc)->_MIN, ((ASLR_IO*)dsc)->_LEN);
+ }
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Base1Hi, 0);
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Base1Lo, 0);
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Base2Hi, 0);
+ SioRegister(dev, TRUE, dev->Owner->SpioInfo->Base2Lo, 0);
+}
+
+//Free GCD resources if Tesource Tamplete Allocation failed
+VOID FreeResources(SPIO_DEV *dev, T_ITEM_LIST *Res){
+ UINTN i;
+ ASLRF_S_HDR *hdr;
+ UINTN bas,irq,dma;
+//---------------------
+ for(i=0, bas=0,irq=0,dma=0; i<Res->ItemCount; i++){
+ hdr=(ASLRF_S_HDR*)Res->Items[i];
+
+ switch(hdr->Name){
+
+ case ASLV_RT_IO:
+ case ASLV_RT_FixedIO:
+ bas++;
+ if( (!(dev->DeviceInfo->Flags & SIO_SHR_IO1)) && (bas==1))FreeIo(dev,hdr);
+ if( (!(dev->DeviceInfo->Flags & SIO_SHR_IO2)) && (bas==2))FreeIo(dev,hdr);
+ break;
+ case ASLV_RT_IRQ:
+ irq++;
+ if( (!(dev->DeviceInfo->Flags & SIO_SHR_IRQ1)) && (irq==1))FreeIrq(dev, (ASLR_IRQ*)hdr);
+ if( (!(dev->DeviceInfo->Flags & SIO_SHR_IRQ2)) && (irq==2))FreeIrq(dev, (ASLR_IRQ*)hdr);
+ break;
+
+ case ASLV_RT_DMA:
+ dma++;
+ if( (!(dev->DeviceInfo->Flags & SIO_SHR_DMA1)) && (dma==1))FreeDma(dev, (ASLR_DMA*)hdr);
+ if( (!(dev->DeviceInfo->Flags & SIO_SHR_DMA2)) && (dma==2))FreeDma(dev, (ASLR_DMA*)hdr);
+ break;
+ }
+ }
+ dev->Assigned=FALSE;
+}
+
+
+EFI_STATUS ApplyResources(SPIO_DEV *Dev, T_ITEM_LIST *ResLst, BOOLEAN IrqReserve){
+ UINTN i;
+ ASLRF_S_HDR *hdr;
+ EFI_STATUS Status = IrqReserve ? EFI_UNSUPPORTED : EFI_SUCCESS;
+ VOID *rd;
+ UINT8 irqc=0, basc=0, dmac=0;
+//--------------------------------
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyResources "));
+ //if device shares all resources we'll copy Resource Owner's CRS
+ if(Dev->Assigned){
+ SIO_TRACE((TRACE_SIO,"- Assigned Already\n"));
+ return EFI_SUCCESS;
+ }
+
+ if(Dev->DeviceInfo->Flags & SIO_NO_RES){
+ SIO_TRACE((TRACE_SIO,"- NO RSESOURCES USED\n"));
+ return EFI_SUCCESS;
+ }
+
+ if( (Dev->DeviceInfo->Flags & SIO_SHR_ALL )==SIO_SHR_ALL &&
+ Dev->ResOwner->DeviceInfo->LDN==Dev->DeviceInfo->LDN &&
+ (!IrqReserve))
+ {
+ SIO_TRACE((TRACE_SIO,"- Same LDN Share ALL Resources\n"));
+ Dev->CRS.ItemCount=Dev->ResOwner->CRS.ItemCount;
+ Dev->CRS.Items=Dev->ResOwner->CRS.Items;
+ Dev->Assigned=TRUE;
+ return EFI_SUCCESS;
+ }
+
+ for(i=0; i<ResLst->ItemCount; i++){
+ rd=NULL;
+ hdr=(ASLRF_S_HDR*)ResLst->Items[i];
+ if (hdr->Type==ASLV_SMALL_RES){ //SIO mast have only small resources types
+ //-------------------------
+ switch(hdr->Name){
+ case ASLV_RT_IRQ:
+ SIO_TRACE((TRACE_SIO,"- IRQ%d; IrqReserve=%d\n",irqc+1, IrqReserve));
+
+ rd=ApplyIrqRes(hdr,Dev,irqc,IrqReserve);
+ irqc++;
+ break;
+
+ case ASLV_RT_DMA:
+ if(!IrqReserve){
+ SIO_TRACE((TRACE_SIO,"- DMA%d >>",dmac+1));
+ rd=ApplyDmaRes(hdr, Dev, dmac);
+ dmac++;
+ } else continue;
+ break;
+
+ case ASLV_RT_IO:
+ if(!IrqReserve){
+ SIO_TRACE((TRACE_SIO," IO%d >>",basc+1));
+ rd=ApplyIoRes(hdr, Dev, basc);
+ basc++;
+ } else continue;
+ break;
+
+ case ASLV_RT_FixedIO:
+ if(!IrqReserve){
+ SIO_TRACE((TRACE_SIO,"Fixed IO%d >>",basc+1));
+ rd=ApplyFixedIoRes(hdr, Dev, basc);
+ basc++;
+ } else continue;
+ break;
+ }
+
+ if(IrqReserve) continue;
+
+ SIO_TRACE((TRACE_SIO,"rd=%x \n",rd));
+ if(rd) Status=AppendItemLst(&Dev->CRS, rd);
+ else Status=EFI_UNSUPPORTED;
+ } else Status=EFI_UNSUPPORTED; //the SIO - doesn't supports LARGE RESOURCES
+ if (EFI_ERROR(Status)) break;
+ }
+ SIO_TRACE((TRACE_SIO,"\n"));
+
+ //If Irq Reservation we no need to add any res descriptors yet
+ if(IrqReserve && (Status==EFI_UNSUPPORTED)){
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyResources(IrqReserve=%d) Status=EFI_SUCCESS\n",IrqReserve));
+ return EFI_SUCCESS;
+ }
+ //clear resource tamplete if we fail to assign one of the members of ResLst
+ if (EFI_ERROR(Status)){
+ FreeResources(Dev, &Dev->CRS);
+ ClearItemLst(&Dev->CRS, TRUE);
+ Dev->Assigned=FALSE;
+ } else Dev->Assigned=TRUE;
+ SIO_TRACE((TRACE_SIO,"GSIO: ApplyResources(IrqReserve=%d) Dev->CRS count=%d; Status=%r\n",IrqReserve, Dev->CRS.ItemCount, Status));
+ return Status;
+}
+
+EFI_STATUS AssignSharedResources(SPIO_DEV *Dev){
+ EFI_STATUS Status;
+ UINTN i, bas,irq,dma;
+ T_ITEM_LIST *crs=&Dev->ResOwner->CRS;
+ ASLRF_S_HDR *hdr;
+ BOOLEAN app;
+//----------------------------
+ for(i=0,bas=0,irq=0,dma=0,app=FALSE; i<crs->ItemCount; i++,app=FALSE){
+ hdr=crs->Items[i];
+ switch(hdr->Name){
+ //IO resource type
+ case ASLV_RT_FixedIO:
+ case ASLV_RT_IO:
+ bas++;
+ if( (Dev->DeviceInfo->Flags&SIO_SHR_IO1)&& (bas==1)) app=TRUE;
+ if( (Dev->DeviceInfo->Flags&SIO_SHR_IO2)&& (bas==2)) app=TRUE;
+ break;
+ //IRQ resource
+ case ASLV_RT_IRQ :
+ irq++;
+ if( (Dev->DeviceInfo->Flags&SIO_SHR_IRQ1)&& (irq==1)) app=TRUE;
+ if( (Dev->DeviceInfo->Flags&SIO_SHR_IRQ2)&& (irq==2)) app=TRUE;
+ break;
+ //DMA Resource
+ case ASLV_RT_DMA:
+ dma++;
+ if( (Dev->DeviceInfo->Flags&SIO_SHR_DMA1)&& (dma==1)) app=TRUE;
+ if( (Dev->DeviceInfo->Flags&SIO_SHR_DMA2)&& (dma==2)) app=TRUE;
+ break;
+ } //switch
+ if(app){
+ Status=AppendItemLst(&Dev->CRS,(VOID*)hdr);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }
+ return Status;
+}
+
+//this Function Assumes SIO is in Config Mode
+//and device has been selected in LDN reg
+EFI_STATUS AssignResources(SPIO_DEV *Dev){
+ T_ITEM_LIST *dl, *rl;
+ UINT8 p=0,c=0, n=0;
+ EFI_STATUS Status;
+//------------------------------------
+ SIO_TRACE((TRACE_SIO,"GSIO: AssignResources "));
+ if(gDxeSvcTbl==NULL) {
+ SIO_TRACE((TRACE_SIO,"- Dxe Sevice Table NOT_FOUND, returning EFI_UNSUPPORTED\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ if(Dev->Assigned) {
+ SIO_TRACE((TRACE_SIO,"- Device has Resourcs Assigned, returning EFI_SUCCESS\n"));
+ return EFI_SUCCESS;
+ }
+
+ //Take care about shared resources if any
+ if(Dev->DeviceInfo->Flags & SIO_SHR_ALL){
+ SIO_TRACE((TRACE_SIO,"- SHARED Flags=0x%X, Status=",Dev->DeviceInfo->Flags));
+ Status=AssignSharedResources(Dev);
+ if(Dev->DeviceInfo->Flags==SIO_SHR_ALL) {
+ Dev->Assigned=TRUE;
+ Status=EFI_SUCCESS;
+ SIO_TRACE((TRACE_SIO,"%r\n",Status));
+ return Status;
+ }
+ SIO_TRACE((TRACE_SIO,"%r\n",Status));
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ dl=&Dev->PRS;
+
+ if(Dev->NvData.DevPrsId){
+ n=Dev->NvData.DevPrsId-1;
+ if(n<dl->ItemCount){
+ rl=GetNumResources(dl,&n);
+ if(rl){
+ Status=ApplyResources(Dev,rl,FALSE);
+ SIO_TRACE((TRACE_SIO,"- By PrsId(%x),get DepFn(%X) Status=%r\n",Dev->NvData.DevPrsId,rl,Status));
+ if(!EFI_ERROR(Status)) return Status;
+ }
+ }
+ SIO_TRACE((TRACE_SIO,"GSIO: AssignResources Fail to reserve By PrsId,%d DepFn in Count %d is %X \n",n,dl->ItemCount,rl));
+ //if we can't apply selected resources reset it to "auto" again
+ Dev->NvData.DevPrsId=0;
+ }
+ //use Auto Resource settings
+ //try to get Prioritized resources
+ while( c < 3 || p < 3 ){
+ rl=GetPriResources(dl,c,p);
+ if(rl) {
+ Status=ApplyResources(Dev,rl,FALSE);
+ if(!Status) return EFI_SUCCESS;
+ }
+ c++; p++;
+ }
+ //Fail to get Dependent Function with Priority
+ //try by number
+ while( n < dl->ItemCount){
+ rl=GetNumResources(dl,&n);
+ if(rl) {
+ Status=ApplyResources(Dev,rl,FALSE);
+ SIO_TRACE((TRACE_SIO,"- By PRS Num(n=%d),get DepFn(%X) Status=%r\n",n,rl,Status));
+ if(!Status) return EFI_SUCCESS;
+ }
+ n++;
+ }
+ SIO_TRACE((TRACE_SIO,"\n"));
+ return EFI_NOT_FOUND;
+}
+
+////////////////////////////////////////////////////////////////////
+EFI_STATUS StartSioChildDevice(EFI_HANDLE CtrlHandle, SPIO_DEV *Dev){
+ EFI_STATUS Status=0;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+//----------------------------------
+ if(Dev->Started) return EFI_ALREADY_STARTED;
+ //Now Install All protocols
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &Dev->Handle,
+ &gEfiAmiSioProtocolGuid, &Dev->AmiSio,
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+
+ &gEfiSioProtocolGuid, &Dev->EfiSioData.EfiSio,
+#endif
+ &gDevicePathProtocolGuid, Dev->DevicePath, //DevPath GUID - I/F pare
+ NULL, NULL );
+
+ SIO_TRACE((TRACE_SIO,"InstallProt()=%r.", Status));
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status))return Status;
+
+ Dev->Started=TRUE;
+
+ //Open Protocol BY_CHILD_CONTROLLER to notify core we may produce CHILDS
+ Status=pBS->OpenProtocol( CtrlHandle, &gPciIoProtocolGuid, &PciIo,
+ gAmiSioDriverBinding.DriverBindingHandle, Dev->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+
+ SIO_TRACE((TRACE_SIO,"Open(PciIo)=%r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+EFI_STATUS ReserveIrq(SPIO_DEV *Dev, UINTN Index){
+ EFI_STATUS Status;
+ T_ITEM_LIST *dl, *rl;
+ UINT8 p=0,c=0, n=0;
+//------------------------------------
+ if(gDxeSvcTbl==NULL) return EFI_UNSUPPORTED;
+
+ if(Dev->IrqReserved) return EFI_SUCCESS;
+
+ if(Dev->DeviceInfo->Flags & SIO_NO_RES){
+ SIO_TRACE((TRACE_SIO,"- NO RSESOURCES USED\n"));
+ return EFI_SUCCESS;
+ }
+
+
+ //Take care about shared resources if any
+ if((Dev->DeviceInfo->Flags & SIO_SHR_IRQ) == SIO_SHR_IRQ) return EFI_SUCCESS;
+
+ dl=&Dev->PRS;
+
+ if(Dev->NvData.DevPrsId){
+ n=Dev->NvData.DevPrsId-1; //Very first Option is AUTO Select
+ if(n<dl->ItemCount){
+ rl=GetNumResources(dl,&n);
+ if(rl){
+ Status=ApplyResources(Dev,rl,TRUE); //Reserve Interrupts
+ if(!EFI_ERROR(Status)) return Status;
+ }
+ }
+ //if we can't apply selected resources reset it to "auto" again
+ Dev->NvData.DevPrsId=0;
+ }
+ //use Auto Resource settings
+ //try to get Prioritized resources
+ while( c < 3 || p < 3 ){
+ rl=GetPriResources(dl,c,p);
+ if(rl) {
+ Status=ApplyResources(Dev,rl,TRUE);
+ SIO_TRACE((TRACE_SIO,"GSIO: ReserveIrq by PRI, Status=%r\n",Status));
+ if(!Status) return EFI_SUCCESS;
+ }
+ c++; p++;
+ }
+ //Fail to get Dependent Function with Priority
+ //try by number
+ while( n < dl->ItemCount){
+ rl=GetNumResources(dl,&n);
+ if(rl) {
+ Status=ApplyResources(Dev,rl,TRUE);
+ SIO_TRACE((TRACE_SIO,"GSIO: ReserveIrq PRS[%d], Status==%r\n",n,Status));
+ if(!Status) return EFI_SUCCESS;
+ }
+ n++;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+
+EFI_STATUS InitSioDevice(SPIO_DEV *Dev){
+ EFI_STATUS Status=0;
+ BOOLEAN Dis_Flag=TRUE;
+// EFI_PCI_IO_PROTOCOL *PciIo;
+ //SPIO_DEV *ro=NULL;//rtesource owner in case of shared resources
+//-------------------------
+
+ if (Dev->Started||Dev->Initialized) {
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() Device was Started=%d Initialized=%d - returning EFI_SUCCESS\n",
+ Dev->Started, Dev->Initialized));
+ return EFI_SUCCESS;
+ }
+
+ if(!Dev->Owner->InCfgMode) SioCfgMode(Dev->Owner, TRUE);
+
+ //See if there actual SIO there or just empty space
+ Status=CheckDevicePresent(Dev);
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - CheckDevicePresent() Status=%r",Status));
+ if(Status==EFI_NO_RESPONSE) Dev->DeviceInfo->Implemented=FALSE;
+ SIO_TRACE((TRACE_SIO," Implemented=%d \n",Dev->DeviceInfo->Implemented));
+
+ if(!EFI_ERROR(Status)) {
+ if(Dev->DeviceInfo->Type == dsPS2CM) Dis_Flag=FALSE; //if ps2 mouse &ps2 keyboard in same logical device,not disable it
+ if(Dis_Flag){
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() Disabling Device\n"));
+ DevEnable(Dev,FALSE);//disable all devices before programing
+ }
+ }
+
+ if(Dev->DeviceInfo->Implemented && Dev->NvData.DevEnable){
+ //if we are Initializing device with shared resources
+ //make sure resource owner has it's resources Allocated!
+ if((Dev->DeviceInfo->Flags & SIO_SHR_ALL) && Dev->ResOwner){
+ //we don't care about the irq share case
+ if(!(Dev->DeviceInfo->Flags & SIO_SHR_IRQ)) {
+ DevSelect(Dev->ResOwner);
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() AssignResources(Dev->ResOwner) -"));
+ Status=AssignResources(Dev->ResOwner);
+ SIO_TRACE((TRACE_SIO," Status=%r; FLAGS=0x%X\n",Status, Dev->DeviceInfo->Flags));
+ if(EFI_ERROR(Status)) return Status;
+
+ }//if
+ }//if
+
+ DevSelect(Dev);
+ if(Dev->DeviceInfo->Flags & SIO_NO_RES) {
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Device has NO Resourcs\n"));
+ Dev->Assigned=TRUE;
+ }else{
+ SIO_TRACE((TRACE_SIO,"SIO InitSioDevice() AssignResources(Dev) -"));
+ Status=AssignResources(Dev); //Assigned Flag is changed inside AssignResources
+ SIO_TRACE((TRACE_SIO," Status=%r\n",Status));
+ }
+
+ if(!EFI_ERROR(Status)){
+ pBS->CopyMem(&Dev->AmiSio,&gAmiSioProtocol, sizeof(AMI_SIO_PROTOCOL));
+
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+ pBS->CopyMem(&Dev->EfiSioData.EfiSio, &gEfiSioProtocol, sizeof(EFI_SIO_PROTOCOL));
+#endif
+
+ if(!Dev->DevicePath){
+ ACPI_HID_DEVICE_PATH siodp;
+ //--------------------------
+ siodp.Header.Type=ACPI_DEVICE_PATH;
+ siodp.Header.SubType=ACPI_DP;
+ SET_NODE_LENGTH(&siodp.Header,ACPI_DEVICE_PATH_LENGTH);
+ siodp.HID=Dev->EisaId.HID;
+ siodp.UID=Dev->EisaId.UID;
+ Dev->DevicePath = DPAddNode(Dev->Owner->CntrDevPath,&siodp.Header);
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Set DevicePath=%X\n",Dev->DevicePath));
+ }
+ //Call Init BeforeActivate
+ //if device is not implemented it might be needed to do some initialization
+ // even for disabled devices if so here we are
+ if(Dev->DeviceInfo->InitRoutine){
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Device InitRoutine(isBeforeActivate)"));
+ Status=Dev->DeviceInfo->InitRoutine(&Dev->AmiSio,Dev->Owner->IsaBrgPciIo, isBeforeActivate);
+ SIO_TRACE((TRACE_SIO," Status=%r\n"));
+ if(EFI_ERROR(Status))return Status;
+
+ }
+ //In config routine we might exit config mode
+ if(!Dev->Owner->InCfgMode) SioCfgMode(Dev->Owner, TRUE);
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Enabling Device\n"));
+ DevEnable(Dev,TRUE);
+ //Call Init AfterActivate
+ if(Dev->DeviceInfo->InitRoutine){
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Calling InitRoutine(isAfterActivate)"));
+ Status=Dev->DeviceInfo->InitRoutine(&Dev->AmiSio,Dev->Owner->IsaBrgPciIo, isAfterActivate);
+ SIO_TRACE((TRACE_SIO," Status=%r\n", Status));
+ if(EFI_ERROR(Status)) return Status;
+
+ }
+ } else {
+ //Fail to assign device resource - so disable the device
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Fail to Assign Resources, Disable Device!\n"));
+ Dev->Started=TRUE;
+ Dev->Assigned=TRUE;
+ Dev->VlData.DevImplemented=FALSE;
+ }
+ } else { //if device was not Implemented on the board or was disabled by setup
+ //set Flags in not implemented devices to avoid creating handles on them
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Not Implemented or Disabled by Setup, Disable Device\n"));
+ Dev->Started=TRUE;
+ Dev->Assigned=TRUE;
+ }
+
+ Dev->Initialized=TRUE;
+
+ if(Dev->Owner->InCfgMode) SioCfgMode(Dev->Owner, FALSE);
+
+ if(Dev->DeviceInfo->HasSetup) Status=SioSetupData(Dev, FALSE);
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Set Device VlData(DevImplemented=%x,DevBase1=%x,DevBase2=%x,DevIrq1=%x,DevIrq2=%x,DevDma1=%x,DevDma2=%x);\n",Dev->VlData.DevImplemented,Dev->VlData.DevBase1,Dev->VlData.DevBase2,Dev->VlData.DevIrq1,Dev->VlData.DevIrq2,Dev->VlData.DevDma1,Dev->VlData.DevDma2));
+ SIO_TRACE((TRACE_SIO,"GSIO: InitSioDevice() - Set Device NvData(DevEnable=%x,DevPrsId=%x,DevMode=%x)\n",Dev->NvData.DevEnable,Dev->NvData.DevPrsId,Dev->NvData.DevMode));
+ return Status;
+}
+
+EFI_STATUS AmiSioStart(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status=EFI_SUCCESS,StatusRdp=EFI_SUCCESS;
+ INTN i;
+ UINTN j,k;
+ SPIO_DEV *dev;
+ ACPI_HID_DEVICE_PATH *dp=NULL;
+ GSPIO *spio;
+ BOOLEAN AllStarted=TRUE;
+ BOOLEAN GcdIndex=TRUE;
+ BOOLEAN Init_Flag=FALSE;
+#ifdef EFI_DEBUG
+ CHAR8 *DpString=NULL;
+#endif
+//--------------------------------
+#if ACPI_SUPPORT
+ if(!gPDsdt) return EFI_DEVICE_ERROR;
+#endif
+ PROGRESS_CODE(DXE_SIO_INIT);
+ SIO_TRACE((TRACE_SIO,"GSIO: AmiSioStart() - gSpio=%x,gSpioCount=%x\n",gSpio,gSpioCount));
+ for(j=0; j<gSpioCount; j++){
+ spio=&gSpio[j];
+ SIO_TRACE((TRACE_SIO,"\nSIO: AmiSioStart() - SIO[%d] SupportController=%X, This Controller=%X\n",j,spio->SupportedHandle,Controller));
+ if(spio->SupportedHandle!=Controller) continue;
+ if(!spio->CntrDevPath){
+ Status=pBS->OpenProtocol( Controller, &gDevicePathProtocolGuid,
+ (VOID **)&dp,This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if(EFI_ERROR(Status) && Status!= EFI_ALREADY_STARTED) return Status;
+ spio->CntrDevPath=DPCopy((EFI_DEVICE_PATH_PROTOCOL*)dp);
+ pBS->CloseProtocol(Controller,&gDevicePathProtocolGuid,This->DriverBindingHandle, Controller);
+ spio->CntrHandle=Controller;
+ //To Create a chain of childs
+ Status=pBS->OpenProtocol( Controller,&gPciIoProtocolGuid,(VOID **)&PciIo,
+ This->DriverBindingHandle,Controller,EFI_OPEN_PROTOCOL_BY_DRIVER);
+ //if there are 2 or more SIO on the same LPC Bridge it should return something like that
+ if(EFI_ERROR(Status)) {
+ if(Status!=EFI_ALREADY_STARTED) return Status;
+ //Try to scan back and find opend PciIoProtocol for the previouse SIO
+ SIO_TRACE((TRACE_SIO,"GSIO: AmiSioStart() - The BindingDriver has been opened PciIo protocol for formor SIO chip=%X\n"));
+ for (i=j-1; i>=0; i--)if(gSpio[i].CntrHandle==Controller) spio->IsaBrgPciIo=gSpio[i].IsaBrgPciIo;
+ if(!spio->IsaBrgPciIo) return EFI_DEVICE_ERROR;
+ } else spio->IsaBrgPciIo=PciIo;
+ //Reserve SIO Index/Data port in GCD
+ SIO_TRACE((TRACE_SIO,"GSIO: AmiSioStart() - SIO[%d] =>Assign cfg Index=%X\n",j,spio->SpioInfo->SioIndex));
+ //it is not first sio index and it is different with former index.
+
+ if(j) {
+ for (i=j-1; i>=0; i--)
+ if( (gSpio[i].SpioInfo)->SioIndex==spio->SpioInfo->SioIndex ) {
+ GcdIndex=FALSE;
+ break;
+ }
+ }
+ //Reserve SIO Index/Data port in GCD when it is first io index or the index is different with other
+ if(GcdIndex) {
+ if(!AssignIo(&spio->SpioInfo->SioIndex, 1, 0)) continue;
+ if(!AssignIo(&spio->SpioInfo->SioData, 1, 0)) continue;
+ }
+ } //if(!spio->CntrDevPath)
+
+ dp=(ACPI_HID_DEVICE_PATH*)RemainingDevicePath;
+
+ SIO_TRACE((TRACE_SIO,"\nGSIO: Starting ... RDP= %X\n",(UINTN)RemainingDevicePath));
+
+ for(k=0;k<2;k++){
+ //Locate Right SIO Device
+ for (i=0; (UINTN)i<spio->DeviceCount; i++){
+ Status=EFI_SUCCESS;
+ dev=spio->DeviceList[i];
+ if((k==0)&&(dev->DeviceInfo->Type==dsUART)&&(dev->NvData.DevPrsId!=0)){
+ SIO_TRACE((TRACE_SIO,"\nSIO[%d]Dev[%d] InitSio Starting: first time=>\n",j,i));
+ Init_Flag=TRUE;
+ }
+ if((k==1)&&((dev->DeviceInfo->Type!=dsUART)||(dev->NvData.DevPrsId==0))){
+ SIO_TRACE((TRACE_SIO,"\nSIO[%d]Dev[%d] InitSio Starting: second time=>\n",j,i));
+ Init_Flag=TRUE;
+ }
+ if(Init_Flag) {
+ Status=InitSioDevice(dev);
+ Init_Flag=FALSE;
+ }
+ else continue;
+
+ SIO_TRACE((TRACE_SIO,"InitSioDevice()=%r;\n ", Status));
+ if(EFI_ERROR(Status)){
+ if (Status == EFI_NO_RESPONSE) {
+ SIO_TRACE((TRACE_SIO,"Device check EFI_NO_RESPONSE,Continue next device...\n",j,i));
+ continue;
+ }else {
+ SIO_TRACE((TRACE_SIO,"=>ERROR,Stop AmiSioStart...<=\n",j,i));
+ return Status;}
+ }
+
+ if(RemainingDevicePath==NULL){
+ SIO_TRACE((TRACE_SIO,"Start SIO[%d]Dev[%d] ChildDevice:",j,i));
+ Status=StartSioChildDevice(Controller,dev);
+ SIO_TRACE((TRACE_SIO,"StartSioDev()=%r; Hnd=%X;\n", Status, dev->Handle));
+
+ if(EFI_ERROR(Status)){
+ if(Status!=EFI_ALREADY_STARTED){
+ return Status;
+ } else Status=EFI_SUCCESS;
+ } else AllStarted=FALSE;
+ SIO_TRACE((TRACE_SIO,"AllStarted=%X;\n", AllStarted));
+ } else {
+ SIO_TRACE((TRACE_SIO,"RemainingDevicePath is not Null,HID(%x)_UID(%x)\n",dp->HID,dp->UID));
+ StatusRdp=EFI_NOT_FOUND;
+ if(dp->HID==dev->EisaId.HID && dp->UID==dev->EisaId.UID){
+ StatusRdp=StartSioChildDevice(Controller,dev);
+ SIO_TRACE((TRACE_SIO,"RDP; StartSioDev()=%r; Hnd=%X;\n", StatusRdp, dev->Handle));
+ //break; //return Status;
+ }
+ }
+ SIO_TRACE((TRACE_SIO,"\n"));
+ }//for i
+ }//for j
+ }// for k
+ //if(AllStarted && RemainingDevicePath==NULL) CreateSioDevStatusVar();
+ CreateSioDevStatusVar();
+
+ if(RemainingDevicePath!=NULL) {
+ SIO_TRACE((TRACE_SIO,"\nSIO: AmiSioStart() - returning RdpStatus = %r\n", StatusRdp));
+ return StatusRdp;
+ }
+
+ if(AllStarted) Status=EFI_ALREADY_STARTED;
+ else Status=EFI_SUCCESS;
+ SIO_TRACE((TRACE_SIO,"\nSIO: AmiSioStart() - AllStarted=%d, returning %r\n", AllStarted, Status));
+ return Status;
+
+}
+
+
+EFI_STATUS StopSioDevice(SPIO_DEV *Dev,EFI_HANDLE Controller)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+//--------------------------------------------------------------------
+
+ if(Dev->DeviceInfo->Implemented==FALSE || Dev->VlData.DevImplemented==FALSE){
+ SIO_TRACE((TRACE_SIO,"GSIO: StopSioDevice - Device is NOT Implemented, returning EFI_SUCCESS\n"));
+ return Status;
+ }
+
+ if(Dev->Started==FALSE) return Status;
+
+ Status=pBS->CloseProtocol(Controller,&gPciIoProtocolGuid,
+ gAmiSioDriverBinding.DriverBindingHandle, Dev->Handle);
+
+
+ SIO_TRACE((TRACE_SIO,"GSIO: Closing(PciIo)=%r; ", Status));
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status))return Status;
+
+
+ Status=pBS->UninstallMultipleProtocolInterfaces(
+ Dev->Handle,
+ &gEfiAmiSioProtocolGuid,&Dev->AmiSio,
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+ &gEfiSioProtocolGuid, &Dev->EfiSioData.EfiSio,
+#endif
+ &gDevicePathProtocolGuid,Dev->DevicePath,
+ NULL, NULL );
+ SIO_TRACE((TRACE_SIO,"Uninstalling(AmiSio;"));
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+ SIO_TRACE((TRACE_SIO," EfiSio;"));
+#endif
+ SIO_TRACE((TRACE_SIO," DevPath)=%r;\n", Status));
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //don't need to free and clear the device path buffer of the device
+ //- it not going to change any way. Just care not to create it over again
+ //when Start function will be called
+ Dev->Handle=NULL;
+ Dev->Started=FALSE;
+ DevEnable(Dev, FALSE);
+
+ Status = DisableDevInSioDevStatusVar(Dev);
+
+ if(EFI_ERROR(Status))SIO_TRACE((TRACE_SIO,"GSIO: Stop=> %r - Update SioDevStatusVar.\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+
+EFI_STATUS AmiSioStop(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer)
+{
+ EFI_STATUS Status;
+ UINTN i,j,k,cnt=0;
+ SPIO_DEV *dev;
+ GSPIO *spio;
+//------------------------
+ SIO_TRACE((TRACE_SIO,"\nGenericSIOStop: gSpioCount=%d, NumberOfChildren=0x%X, Controller=0x%X\n",
+ gSpioCount, NumberOfChildren, Controller));
+
+ for(k=0,j=0; k<gSpioCount; k++){
+ spio=&gSpio[k];
+ if(spio->CntrHandle!=Controller) continue;
+
+ if (!NumberOfChildren) {
+ for(i=0; i<spio->DeviceCount; i++){
+ SIO_TRACE((TRACE_SIO,"SIO[%d] Stopping: ", i));
+ dev=spio->DeviceList[i];
+ if(dev->Started) Status=StopSioDevice(spio->DeviceList[i], Controller);
+ SIO_TRACE((TRACE_SIO,"%r.\n", Status));
+ if(EFI_ERROR(Status)) return Status;
+ }
+ //If everything OK we should close PciIo Protocol that we opened BY_DRIVER
+ //In case of multiple SIO on the same LPC Bridge this code can cause ERROR_STATUS.
+ Status=pBS->CloseProtocol(Controller,&gPciIoProtocolGuid,This->DriverBindingHandle,Controller);
+ if(EFI_ERROR(Status)){
+ SIO_TRACE((TRACE_SIO, "\nAttempt to Close LpcBrg PCI_IO was UNSUCCESSFUL %r!\n", Status));
+ Status=EFI_SUCCESS;// clear error status Status.
+ }
+ } else {
+ for( ;j<NumberOfChildren; j++){
+
+ for(i=0; i<spio->DeviceCount; i++){
+ dev=spio->DeviceList[i];
+
+ if(dev->Handle==ChildHandleBuffer[j]){
+ SIO_TRACE((TRACE_SIO,"SIO[%d] Stopping: ", i));
+ Status=StopSioDevice(dev,Controller);
+ SIO_TRACE((TRACE_SIO,"%r.\n", Status));
+ if(EFI_ERROR(Status)) return Status;
+ cnt++;
+ break;
+ }
+ } //for i
+ } //for j
+ } //else
+ spio->CntrDevPath=NULL;
+ }//for k
+
+ if(NumberOfChildren && (!cnt)) Status=EFI_NOT_FOUND;
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+
+//AmiSIO Protocol Functions Implementation
+EFI_STATUS AmiSioRegister(IN AMI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value)
+{
+ SPIO_DEV *dev=(SPIO_DEV*)This;
+//-----------------------------------
+ if(!This || !Value || Register>SIO_MAX_REG ) return EFI_INVALID_PARAMETER;
+
+ if(!dev->Owner->InCfgMode) SioCfgMode(dev->Owner, TRUE);
+
+ DevSelect(dev);
+ SioRegister(dev, Write, Register, Value);
+
+ if(ExitCfgMode) {
+ if(dev->Owner->InCfgMode) SioCfgMode(dev->Owner, FALSE);
+ }
+ return EFI_SUCCESS;
+
+}
+
+EFI_STATUS AmiSioCRS(IN AMI_SIO_PROTOCOL *This,
+ IN BOOLEAN Set,
+ IN OUT T_ITEM_LIST **Resources)
+{
+ EFI_STATUS Status;
+ SPIO_DEV *dev=(SPIO_DEV*)This;
+//-----------------------------------
+ if (!This || !Resources) return EFI_INVALID_PARAMETER;
+
+ if (Set) {
+ FreeResources(dev, &dev->CRS);
+// ClearResLst(&dev->CRS);
+ ClearItemLst(&dev->CRS, TRUE);
+ Status = ApplyResources(dev, *Resources, FALSE);
+// ProgramResources(dev);
+ } else {
+ CopyItemLst(&dev->CRS, Resources);
+// *Resources=&dev->CRS;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+#if ((defined PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014))
+
+EFI_STATUS EfiSioRegisterAccess(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN BOOLEAN Write,
+ IN BOOLEAN ExitCfgMode,
+ IN UINT8 Register,
+ IN OUT UINT8 *Value)
+{
+ EFI_SIO_DATA *EfiSioData=(EFI_SIO_DATA*)This;
+//---------------------
+ if(This==NULL) return EFI_INVALID_PARAMETER;
+
+ return AmiSioRegister(&EfiSioData->Owner->AmiSio,Write,ExitCfgMode,Register,Value);
+
+}
+
+EFI_STATUS EfiSioGetRes(T_ITEM_LIST *AmiResLst, ACPI_RESOURCE_HEADER_PTR *EfiResLst){
+ UINTN i, sz=0;
+ ASLRF_S_HDR *pRes;
+ VOID *EfiSioRes=NULL;
+ UINT8 *p8;
+//----------------
+ for(i=0; i<AmiResLst->ItemCount; i++){
+ pRes=(ASLRF_S_HDR*)AmiResLst->Items[i];
+ if(pRes->Type==ASLV_SMALL_RES) sz+=(UINTN)pRes->Length;
+ else sz+=((ASLRF_L_HDR*)pRes)->Length;
+ }
+
+ EfiSioRes=Malloc(sz+sizeof(ASLR_EndTag));
+ if(EfiSioRes==NULL) return EFI_OUT_OF_RESOURCES;
+
+ for(i=0,p8=EfiSioRes; i<AmiResLst->ItemCount; i++){
+ pRes=(ASLRF_S_HDR*)AmiResLst->Items[i];
+ if(pRes->Type==ASLV_SMALL_RES) sz=(UINTN)pRes->Length;
+ else sz=(UINTN)((ASLRF_L_HDR*)pRes)->Length;
+
+ MemCpy(p8,(VOID*)pRes, sz);
+ p8+=sz;
+ }
+
+ ((ASLR_EndTag*)p8)->Hdr.HDR=ASLV_END_TAG_HDR;
+ ((ASLR_EndTag*)p8)->Chsum=0;
+
+ EfiResLst->SmallHeader=EfiSioRes;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS EfiSioGetResourcces(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceList)
+{
+ EFI_STATUS Status;
+ EFI_SIO_DATA *EfiSioData=(EFI_SIO_DATA*)This;
+ T_ITEM_LIST *ResLst=NULL; //if NULL new Buffer will be allocated...
+ UINTN EfiSioBuffSize=0;
+//---------------------
+ if(This==NULL || ResourceList==NULL) return EFI_INVALID_PARAMETER;
+
+ //Get resources in AMI SIO format...
+ Status=AmiSioCRS(&EfiSioData->Owner->AmiSio, FALSE, &ResLst);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Convert it to EFI_SUPER_IO format.
+ Status=EfiSioGetRes(ResLst, ResourceList);
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+
+EFI_STATUS EfiSioSetRes(T_ITEM_LIST *AmiResLst, ACPI_RESOURCE_HEADER_PTR EfiResLst){
+ UINTN sz=0;
+ UINT8 *p8;
+ EFI_STATUS Status;
+//----------------
+ p8=(UINT8*)EfiResLst.SmallHeader;
+
+ //Convert resources to AMI_SIO format.
+ while( ((ASLR_EndTag*)p8)->Hdr.HDR!=ASLV_END_TAG_HDR ){
+ if( ((ASLRF_S_HDR*)p8)->Type==ASLV_SMALL_RES )sz=(UINTN)((ASLRF_S_HDR*)p8)->Length;
+ else sz=(UINTN)((ASLRF_L_HDR*)p8)->Length;
+
+ Status=AppendItemLst(AmiResLst, p8);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ p8+=sz;
+ }
+ return Status;
+}
+
+EFI_STATUS EfiSioSetResources(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN ACPI_RESOURCE_HEADER_PTR ResourceList)
+{
+ EFI_STATUS Status;
+ EFI_SIO_DATA *EfiSioData=(EFI_SIO_DATA*)This;
+ T_ITEM_LIST *ResLst=NULL; //if NULL new Buffer will be allocated...
+ UINTN EfiSioBuffSize=0;
+//---------------------
+ if(This==NULL || ResourceList.SmallHeader==NULL) return EFI_INVALID_PARAMETER;
+
+ //Get Bubber for T_ITEM_LIST object...
+ ResLst=(T_ITEM_LIST*)MallocZ(sizeof(T_ITEM_LIST));
+ if(ResLst==NULL) return EFI_OUT_OF_RESOURCES;
+
+ //Convert resources to AMI_SIO format.
+ Status=EfiSioSetRes(ResLst, ResourceList);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Submit converted resources.
+ return AmiSioCRS(&EfiSioData->Owner->AmiSio, TRUE, &ResLst);
+}
+
+
+EFI_STATUS EfiSioPrs(T_ITEM_LIST *AmiPrsLst, ACPI_RESOURCE_HEADER_PTR *EfiResLst){
+ UINTN i,j, sz=0;
+ ASLRF_S_HDR *pRes;
+ EFI_ASL_DepFn *pPrs;
+ VOID *EfiSioPrs=NULL;
+ UINT8 *p8;
+//----------------
+ for(i=0; i<AmiPrsLst->ItemCount; i++){
+ pPrs=(EFI_ASL_DepFn*)AmiPrsLst->Items[i];
+ pRes=pPrs->DepFn;
+ sz+=pRes->Length;
+
+ for(j=0; j<pPrs->DepRes.ItemCount; j++){
+ pRes=(ASLRF_S_HDR*)pPrs->DepRes.Items[j];
+ if(pRes->Type==ASLV_SMALL_RES) sz+=(UINTN)pRes->Length;
+ else sz+=((ASLRF_L_HDR*)pRes)->Length;
+ }
+ }
+
+ //Allocate Buffer including EndDepFn object + Resource EndTag
+ EfiSioPrs=Malloc(sz+sizeof(ASLR_EndTag)+sizeof(ASLV_RT_EndDependentFn));
+ if(EfiSioPrs==NULL) return EFI_OUT_OF_RESOURCES;
+
+ //Dump everything in buffer.
+ for(i=0,p8=EfiSioPrs; i<AmiPrsLst->ItemCount; i++){
+ pPrs=(EFI_ASL_DepFn*)AmiPrsLst->Items[i];
+ //Copy StartDepFn Object...
+ pRes=pPrs->DepFn;
+ sz=pRes->Length;
+ MemCpy(p8,(VOID*)pRes, sz);
+ p8+=sz;
+
+ for(j=0; j<pPrs->DepRes.ItemCount; j++){
+ pRes=(ASLRF_S_HDR*)pPrs->DepRes.Items[j];
+
+ if(pRes->Type==ASLV_SMALL_RES) sz=(UINTN)pRes->Length;
+ else sz=(UINTN)((ASLRF_L_HDR*)pRes)->Length;
+
+ MemCpy(p8,(VOID*)pRes, sz);
+ p8+=sz;
+ }
+ }
+
+ ((ASLRF_S_HDR*)p8)->Name=ASLV_RT_EndDependentFn;
+ ((ASLRF_S_HDR*)p8)->Type=ASLV_SMALL_RES;
+ ((ASLRF_S_HDR*)p8)->Length=sizeof(ASLV_RT_EndDependentFn);
+ p8+=sizeof(ASLRF_S_HDR);
+
+ ((ASLR_EndTag*)p8)->Hdr.HDR=ASLV_END_TAG_HDR;
+ ((ASLR_EndTag*)p8)->Chsum=0;
+
+ EfiResLst->SmallHeader=EfiSioPrs;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS EfiSioPossibleResources(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ OUT ACPI_RESOURCE_HEADER_PTR *ResourceCollection)
+{
+ EFI_STATUS Status;
+ EFI_SIO_DATA *EfiSioData=(EFI_SIO_DATA*)This;
+ T_ITEM_LIST *ResLst=NULL; //if NULL new Buffer will be allocated...
+//----------------------------------
+ if(This==NULL || ResourceCollection==NULL) return EFI_INVALID_PARAMETER;
+
+ //Get PRS in AMI SIO format...
+ Status=AmiSioPRS(&EfiSioData->Owner->AmiSio, FALSE, &ResLst);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Convert it to EFI_SUPER_IO format.
+ Status=EfiSioPrs(ResLst, ResourceCollection);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+EFI_STATUS EfiSioModify(
+ IN CONST EFI_SIO_PROTOCOL *This,
+ IN CONST EFI_SIO_REGISTER_MODIFY *Command,
+ IN UINTN NumberOfCommands)
+{
+ EFI_STATUS Status;
+ EFI_SIO_DATA *EfiSioData=(EFI_SIO_DATA*)This;
+ UINTN i;
+ UINT8 val;
+ BOOLEAN ExitCfg;
+//----------------------------------
+ if(This==NULL || Command==NULL) return EFI_INVALID_PARAMETER;
+
+ if(NumberOfCommands==0) return EFI_SUCCESS;
+
+ for(i=0; i<NumberOfCommands; i++){
+ if(i<NumberOfCommands-1)ExitCfg=FALSE;
+ else ExitCfg=TRUE;
+
+ //Read Register
+ Status=AmiSioRegister(&EfiSioData->Owner->AmiSio, FALSE, ExitCfg,
+ Command->Register, &val);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ val&=Command->AndMask;
+ val|=Command->OrMask;
+
+ Status=AmiSioRegister(&EfiSioData->Owner->AmiSio, TRUE, ExitCfg,
+ Command->Register, &val);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ }
+ return Status;
+}
+#endif
+
+
+EFI_STATUS AmiSioPRS(IN AMI_SIO_PROTOCOL *This,
+ IN BOOLEAN Set,
+ IN OUT T_ITEM_LIST **Resources)
+{
+ SPIO_DEV *dev=(SPIO_DEV*)This;
+//---------------------------------------
+ if(Set) return EFI_UNSUPPORTED;
+ CopyItemLst(&dev->PRS, Resources);
+// *Resources=&dev->PRS;
+ return EFI_SUCCESS;
+}
+
+//Routine to transit Sio in/from Config Mode.
+static VOID BootScriptSioCfgMode(GSPIO *Sio, BOOLEAN Enter, EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave)
+{
+ UINTN i;
+ SPIO_SCRIPT_LST *sl;
+
+//---------------------------------
+ if(Enter)sl=Sio->SpioInfo->EnterCfgMode;
+ else sl=Sio->SpioInfo->ExitCfgMode;
+
+ if(sl==NULL) return;
+
+ for (i=0; i<sl->InstrCount; i++){
+ switch (sl->OpType){
+ case cfgNone:
+ break;
+ case cfgByteSeq:
+ {
+ SPIO_SCRIPT *Instr = (SPIO_SCRIPT*) sl->Instruction[0];
+ SPIO_SCRIPT *cmd = &Instr[i];
+ UINT16 reg;
+ //------------------------
+ if(cmd->IdxDat)reg=Sio->SpioInfo->SioIndex;
+ else reg=Sio->SpioInfo->SioData;
+
+ if (cmd->WrRd) {
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(BootScriptSave,
+ EfiBootScriptWidthUint8,
+ reg, 1, &cmd->Value
+ );
+ } else {
+ //This waits until SIO provides a specific value.
+ //This unsupported by boot script Io read/writes.
+
+ //<markw>I know of no SIO that needs this.
+ //If needed, SIO S3 resume must be implemented differently
+ // than the normal boot script.
+ SIO_TRACE((TRACE_SIO,"GSIO: Reading Index/Data SIO registers not supported entering/exit in for S3 resume.\n"));
+ ASSERT_EFI_ERROR(EFI_UNSUPPORTED);
+ }
+ break;
+ }
+ case cfgRoutine:
+ {
+ //Implementing a generic routine like this is difficult using boot scripts in this
+ //SIO implementation.
+ //Use cfgByteSeq.
+ SIO_TRACE((TRACE_SIO,"GSIO: cfgRoutine in SIO not supported for S3 resume. Use cfgByteSeq for enter/exit config space in IOx.c.\n"));
+ ASSERT_EFI_ERROR(EFI_UNSUPPORTED);
+ }
+ break;
+ default: return;
+ }//switch
+ }//for
+ Sio->InCfgMode=Enter;
+ return;
+}
+
+VOID BootScriptSioDevSelect(SPIO_DEV *Dev, EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave){
+
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(BootScriptSave,
+ EfiBootScriptWidthUint8,
+ Dev->Owner->SpioInfo->SioIndex, 1, &Dev->Owner->SpioInfo->DevSel);
+
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(BootScriptSave,
+ EfiBootScriptWidthUint8,
+ Dev->Owner->SpioInfo->SioData, 1, &Dev->DeviceInfo->LDN );
+}
+
+static VOID CallbackReadyToBoot(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL *bss;
+ EFI_STATUS Status;
+ UINTN i, j, s, ari;//, cnt1,cnt2;
+ UINT8 b,r;
+ BOOLEAN devsel, devact, cfgmod;
+ SPIO_DEV *dev;
+ GSPIO *spio;
+//----------------------------------
+
+ Status = pBS->LocateProtocol(&gEfiBootScriptSaveGuid,NULL,&bss);
+ if (EFI_ERROR(Status)) {
+ SIO_TRACE((TRACE_SIO,"GSIO: FAIL to locate EfiBootScriptSaveProtocol %r",Status));
+ return;
+ }
+
+ for(s=0;s<gSpioCount;s++){
+ cfgmod=FALSE;
+ spio=&gSpio[s];
+ if(!spio->InCfgMode) SioCfgMode(spio, TRUE);
+ spio->BootScript=bss;
+
+ //first Check if something changed in Global Config regs programming
+ for(i=0; i<spio->SpioInfo->GlobalInclRegCount; i++){
+ //if we got DevSel register just skip it
+ r=spio->SpioInfo->GlobalIncludeReg[i];
+ if((r==spio->SpioInfo->Activate)||(r==spio->SpioInfo->DevSel)) continue;
+ //select register
+ IoWrite8(spio->SpioInfo->SioIndex,r);
+ //read actual data
+ b=IoRead8(spio->SpioInfo->SioData);
+ //if nothing has changed just skip it
+ if(b==spio->GlobalCfgDump[i]) continue;
+
+ //enter config mode only if we really need it
+ if(!cfgmod){
+ BootScriptSioCfgMode(spio,TRUE,bss);
+ cfgmod=TRUE;
+ }
+ //if this reg was different before the initialization of SIO - record that into boot script
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioIndex, 1, &r);
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioData, 1, &b);
+ }
+
+ //Found out Activate register index in spio->SpioInfo->LocalIncludeReg[] buffer
+ //it must be in LocalIncludeReg[] Buffer
+ for(ari=0; ari<spio->SpioInfo->LocalInclRegCount; ari++)
+ if(spio->SpioInfo->LocalIncludeReg[ari]==spio->SpioInfo->Activate)break;
+
+ //Now check Local registers - unique for each device
+ for (j=0; j<spio->DeviceCount; j++) {
+
+ //---------------------
+ devsel=FALSE;
+ dev=spio->DeviceList[j];
+ //found out if device was active after PEI phase before DXE SIO Intialization
+ devact=(dev->LocalCfgDump[ari]==spio->SpioInfo->ActivVal);
+ DevSelect(dev);
+
+ //check current device active status
+ IoWrite8(spio->SpioInfo->SioIndex,spio->SpioInfo->Activate);
+ b=IoRead8(spio->SpioInfo->SioData);
+
+ //if device is NOT active now and was NOT active before just skip it
+ if( (b==spio->SpioInfo->DeactVal) && (dev->LocalCfgDump[ari]==spio->SpioInfo->DeactVal)) continue;
+
+ //if before and after device was ACTIVE that means - nothing has changed
+ //in Device Active Status. We need not to add this device in boot script
+ if((b==spio->SpioInfo->ActivVal)&&(dev->LocalCfgDump[ari]==spio->SpioInfo->ActivVal));
+ else{
+ //before and after SIO Init Activate register values does not mutch
+ //we need to enter config mode if not in config mode yet and select the device
+ if(!cfgmod){ //if still not in config mode
+ BootScriptSioCfgMode(spio,TRUE,bss);
+ cfgmod=TRUE;
+ }
+ if(!devsel){//device has not been selected
+ BootScriptSioDevSelect(dev, bss);
+ devsel=TRUE;
+ }
+ //Device was Active after PEI phase, but now it is NOT
+ if(devact){
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioIndex, 1, &spio->SpioInfo->Activate);
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioData, 1, &spio->SpioInfo->DeactVal);
+ devact=FALSE;
+ }
+ if(b==spio->SpioInfo->DeactVal)continue;
+ }
+
+ //if we are here that means - Device is active after DXE initialization
+ //and we must check if something gets changed in Generic register programming
+ for(i=0; i<spio->SpioInfo->LocalInclRegCount; i++) {
+ r=spio->SpioInfo->LocalIncludeReg[i];
+ //We took care about activate register erlier
+ if((r==spio->SpioInfo->Activate)||(r==spio->SpioInfo->DevSel)) continue;
+
+ //select register
+ IoWrite8(spio->SpioInfo->SioIndex,r);
+ //read actual data
+ b=IoRead8(spio->SpioInfo->SioData);
+ //if nothing has changed just skip it
+ if(b==dev->LocalCfgDump[i]) continue;
+
+ //enter config mode only if we really need it
+ if(!cfgmod){
+ BootScriptSioCfgMode(spio, TRUE, bss);
+ cfgmod=TRUE;
+ }
+ //device has not been selected
+ if(!devsel){
+ BootScriptSioDevSelect(dev, bss);
+ devsel=TRUE;
+ }
+ //Deactivate the device before changing registers
+ if(devact){
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioIndex, 1, &spio->SpioInfo->Activate);
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioData, 1, &spio->SpioInfo->DeactVal);
+ devact=FALSE;
+ }
+ //if this reg was different before the DXE initialization of SIO - record that into boot script
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioIndex, 1, &r);
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioData, 1, &b);
+
+ } //reg dump compare loop
+
+ //if we are here we have checked the device registers
+ if(!devact){ // we must Activate device now if we have deactivated it erlear
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioIndex, 1, &spio->SpioInfo->Activate);
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(bss,EfiBootScriptWidthUint8,spio->SpioInfo->SioData, 1, &spio->SpioInfo->ActivVal);
+ }
+
+ //Now if device has programmed some registers mapped through LD Decoded registers
+ //we need so save them aswell. We will not do this automatically, but call Porting function to do so...
+ if(dev->DeviceInfo->InitRoutine!=NULL)
+ Status=dev->DeviceInfo->InitRoutine(&dev->AmiSio,dev->Owner->IsaBrgPciIo,isAfterBootScript);
+
+ } //end device loop
+ if(cfgmod)BootScriptSioCfgMode(spio, FALSE, bss);
+ SioCfgMode(spio, FALSE);
+ }//for s
+
+ //
+ //Kill the Event
+ //
+ pBS->CloseEvent(Event);
+
+}
+
+
+EFI_STATUS CreateSioDevStatusVar()
+{
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ UINT32 SioDevStatusVarAttributes = 0;
+ SIO_DEV_STATUS SioDevStatusVar;
+ UINTN i,j;
+ BOOLEAN Implemented;
+ UINT32 UID=0;
+ EFI_STATUS Status = EFI_SUCCESS;
+ GSPIO *spio;
+// SPIO_DEV *dev;
+//--------------------------------------
+ Status = pRS->GetVariable(SIO_DEV_STATUS_VAR_NAME, &gSioDevStatusVarGuid,
+ &SioDevStatusVarAttributes,
+ &SioDevStatusVarSize, &SioDevStatusVar.DEV_STATUS);
+ if (EFI_ERROR(Status)) {
+ SioDevStatusVar.DEV_STATUS = 0;
+ SioDevStatusVarAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ }
+
+ for (i = 0; i < gSpioCount; i++) {
+ spio=&gSpio[i];
+ for(j=0;j<spio->DeviceCount;j++){
+ Implemented = (spio->DeviceList[j]->DeviceInfo->Implemented && spio->DeviceList[j]->NvData.DevEnable);
+ UID = spio->DeviceList[j]->DeviceInfo->UID;
+ switch (spio->DeviceList[j]->DeviceInfo->Type){
+ case dsFDC: SioDevStatusVar.Fdd = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] FDC is Implemented=%d\n",i,j,Implemented));
+ break;
+ case dsPS2CK:
+ case dsPS2K: SioDevStatusVar.Key60_64 = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] PS2K is Implemented=%d\n",i,j,Implemented));
+ break;
+ case dsPS2CM:
+ case dsPS2M: SioDevStatusVar.Ps2Mouse = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] PS2M is Implemented=%d\n",i,j,Implemented));
+ break;
+ case dsUART:
+ if (UID == 0) SioDevStatusVar.SerialA = Implemented;
+ else
+ if (UID == 1) SioDevStatusVar.SerialB = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] UART(UID=%x) is Implemented=%d\n",i,j,UID,Implemented));
+ break;
+ case dsLPT: SioDevStatusVar.Lpt = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] LPT is Implemented=%d\n",i,j,Implemented));
+ break;
+ case dsGAME:
+ if (UID == 0)SioDevStatusVar.Game1 = Implemented;
+ else
+ if (UID == 1)SioDevStatusVar.Game2 = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] GAME(UID=%x) is Implemented=%d\n",i,j,UID,Implemented));
+ break;
+ case dsSB16: SioDevStatusVar.Sb16 = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] SB16 is Implemented=%d\n",i,j,Implemented));
+ break;
+ case dsFmSynth: SioDevStatusVar.FmSynth = Implemented;
+ SIO_TRACE((TRACE_SIO,"SIO[%d]Dev[%d] FmSynth is Implemented=%d\n",i,j,Implemented));
+ break;
+ case dsMPU401:
+ case dsCIR:
+ case dsGPIO:
+ case dsHwMon:
+ case dsPME:
+ case dsACPI:
+ break;
+ }//switch
+ } //for j
+ }//for i
+ Status = pRS->SetVariable(SIO_DEV_STATUS_VAR_NAME, &gSioDevStatusVarGuid,
+ SioDevStatusVarAttributes,
+ SioDevStatusVarSize, &SioDevStatusVar);
+ SIO_TRACE((TRACE_SIO,"GSIO: DevStatusVar=%X Status=%r\n",SioDevStatusVar.DEV_STATUS,Status));
+ return Status;
+}
+
+
+EFI_STATUS DisableDevInSioDevStatusVar(SPIO_DEV *Dev)
+{
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ UINT32 SioDevStatusVarAttributes = 0;
+ SIO_DEV_STATUS SioDevStatusVar;
+ EFI_STATUS Status = EFI_SUCCESS;
+ SIO_DEV_TYPE Type = Dev->DeviceInfo->Type;
+ SIO_DEV_TYPE UID = Dev->EisaId.UID;
+//----------------------
+ Status = pRS->GetVariable(SIO_DEV_STATUS_VAR_NAME, &gSioDevStatusVarGuid,
+ &SioDevStatusVarAttributes,
+ &SioDevStatusVarSize, &SioDevStatusVar.DEV_STATUS);
+ if (!EFI_ERROR(Status)) {
+ switch (Type) {
+ case dsFDC: SioDevStatusVar.Fdd = 0;
+ break;
+ case dsPS2CK:
+ case dsPS2K: SioDevStatusVar.Key60_64 = 0;
+ break;
+ case dsPS2CM:
+ case dsPS2M: SioDevStatusVar.Ps2Mouse = 0;
+ break;
+ case dsUART: if (UID == 0) {
+ SioDevStatusVar.SerialA = 0;
+ } else if (UID == 1) {
+ SioDevStatusVar.SerialB = 0;
+ }
+ break;
+ case dsLPT: SioDevStatusVar.Lpt = 0;
+ break;
+ case dsGAME: if (UID == 0) {
+ SioDevStatusVar.Game1 = 0;
+ } else if (UID == 1) {
+ SioDevStatusVar.Game2 = 0;
+ }
+ break;
+ case dsSB16: SioDevStatusVar.Sb16 = 0;
+ break;
+ case dsFmSynth: SioDevStatusVar.FmSynth = 0;
+ break;
+ case dsMPU401: case dsCIR: case dsGPIO:
+ case dsHwMon: case dsPME: case dsACPI: break;
+
+ } //switch
+
+ Status = pRS->SetVariable(SIO_DEV_STATUS_VAR_NAME, &gSioDevStatusVarGuid,
+ SioDevStatusVarAttributes,
+ SioDevStatusVarSize, &SioDevStatusVar);
+ }
+ SIO_TRACE((TRACE_SIO,"GSIO: DevStatusVar=%X\n",SioDevStatusVar.DEV_STATUS));
+ return Status;
+}
+
+#endif //#if SIO_SUPPORT
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/CORE_DXE/Image.c b/Core/CORE_DXE/Image.c
new file mode 100644
index 0000000..b98e31b
--- /dev/null
+++ b/Core/CORE_DXE/Image.c
@@ -0,0 +1,1710 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Image.c
+
+Abstract:
+
+ Core image handling services
+
+--*/
+
+#include "Image.h"
+#include "EfiHobLib.h"
+#include "EfiPerf.h"
+//*** AMI PORTING BEGIN ***//
+BOOLEAN gFillFpdt = FALSE;
+EFI_STATUS IsValidDevicePath(
+ IN EFI_DEVICE_PATH_PROTOCOL *pDp
+);
+//*** AMI PORTING END ***//
+//
+// Module Globals
+//
+
+LOADED_IMAGE_PRIVATE_DATA *mCurrentImage = NULL;
+
+LOAD_PE32_IMAGE_PRIVATE_DATA mLoadPe32PrivateData = {
+ LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE,
+ NULL,
+ CoreLoadImageEx,
+ CoreUnloadImageEx
+};
+
+
+//
+// This code is needed to build the Image handle for the DXE Core
+//
+LOADED_IMAGE_PRIVATE_DATA mCorePrivateImage = {
+ LOADED_IMAGE_PRIVATE_DATA_SIGNATURE, // Signature
+ NULL, // Image handle
+ EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER, // Image type
+ TRUE, // If entrypoint has been called
+ NULL, // EntryPoint
+ {
+ EFI_LOADED_IMAGE_INFORMATION_REVISION, // Revision
+ NULL, // Parent handle
+ NULL, // System handle
+
+ NULL, // Device handle
+ NULL, // File path
+ NULL, // Reserved
+
+ 0, // LoadOptionsSize
+ NULL, // LoadOptions
+
+ NULL, // ImageBase
+ 0, // ImageSize
+ EfiBootServicesCode, // ImageCodeType
+ EfiBootServicesData // ImageDataType
+ },
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ NULL, // Loaded Image Device Path
+#endif
+ (EFI_PHYSICAL_ADDRESS)0, // ImageBasePage
+ 0, // NumberOfPages
+ NULL, // FixupData
+ 0, // Tpl
+ EFI_SUCCESS, // Status
+ 0, // ExitDataSize
+ NULL, // ExitData
+ NULL, // JumpContext
+ 0, // Machine
+ NULL, // Ebc
+ NULL, // RuntimeData
+};
+
+
+STATIC
+EFI_STATUS
+EFIAPI
+CoreFlushICache (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+
+
+EFI_STATUS
+CoreInitializeImageServices (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Add the Image Services to EFI Boot Services Table and install the protocol
+ interfaces for this image.
+
+Arguments:
+
+ HobStart - The HOB to initialize
+
+Returns:
+
+ Status code.
+
+--*/
+{
+ EFI_STATUS Status;
+ LOADED_IMAGE_PRIVATE_DATA *Image;
+ EFI_PHYSICAL_ADDRESS DxeCoreImageBaseAddress;
+ UINT64 DxeCoreImageLength;
+ VOID *DxeCoreEntryPoint;
+//*** AMI PORTING BEGIN ***//
+//Bug fix: see comments below
+static EFI_GUID gDxeCoreFileNameBuffer;
+//*** AMI PORTING END *****//
+
+ //
+ // Searching for image hob
+ //
+ Status = GetDxeCoreHobInfo (
+ HobStart,
+ &DxeCoreImageBaseAddress,
+ &DxeCoreImageLength,
+ &DxeCoreEntryPoint,
+ &gDxeCoreFileName
+ );
+ ASSERT_EFI_ERROR (Status);
+//*** AMI PORTING BEGIN ***//
+//Bug fix: gDxeCoreFileName points to a data somewhere in the HOB list.
+//However, later on HOB list will be reallocated, which will make gDxeCoreFileName pointer invalid.
+//This is a patch. Copy DXE Core file name to a static variable and
+//update gDxeCoreFileName to point to it.
+ gDxeCoreFileNameBuffer = *gDxeCoreFileName;
+ gDxeCoreFileName=&gDxeCoreFileNameBuffer;
+//*** AMI PORTING END *****//
+
+ //
+ // Initialize the fields for an internal driver
+ //
+ Image = &mCorePrivateImage;
+
+ Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT)(UINTN)DxeCoreEntryPoint;
+ Image->ImageBasePage = DxeCoreImageBaseAddress;
+ Image->NumberOfPages = (UINTN)(EFI_SIZE_TO_PAGES((UINTN)(DxeCoreImageLength)));
+ Image->Tpl = gEfiCurrentTpl;
+ Image->Info.SystemTable = gST;
+ Image->Info.ImageBase = (VOID *)(UINTN)DxeCoreImageBaseAddress;
+ Image->Info.ImageSize = DxeCoreImageLength;
+
+ //
+ // Install the protocol interfaces for this image
+ //
+ Status = CoreInstallProtocolInterface (
+ &Image->Handle,
+ &gEfiLoadedImageProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &Image->Info
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Install Debug Mask Protocol
+ //
+ DEBUG_CODE (
+ if (!EFI_ERROR (Status)) {
+ Status = InstallCoreDebugMaskProtocol(Image->Handle);
+ ASSERT_EFI_ERROR (Status);
+ }
+ )
+
+ mCurrentImage = Image;
+
+ //
+ // Fill in DXE globals
+ //
+ gDxeCoreImageHandle = Image->Handle;
+ gDxeCoreLoadedImage = &Image->Info;
+
+ //
+ // Export DXE Core PE Loader functionality
+ //
+ return CoreInstallProtocolInterface (
+ &mLoadPe32PrivateData.Handle,
+ &gEfiLoadPeImageGuid,
+ EFI_NATIVE_INTERFACE,
+ &mLoadPe32PrivateData.Pe32Image
+ );
+}
+
+
+STATIC
+EFI_STATUS
+CoreLoadPeImage (
+ IN BOOLEAN BootPolicy,
+ IN VOID *Pe32Handle,
+ IN LOADED_IMAGE_PRIVATE_DATA *Image,
+ IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
+ IN UINT32 Attribute,
+ IN BOOLEAN CrossLoad
+ )
+/*++
+
+Routine Description:
+
+ Loads, relocates, and invokes a PE/COFF image.
+
+Arguments:
+
+ Pe32Handle - The handle of PE32 image.
+ Image - PE image to be loaded.
+ DstBuffer - The buffer to store the image.
+ EntryPoint - A pointer to the entry point.
+ Attribute - The bit mask of attributes to set for the load PE image.
+ CrossLoad - Whether expect to support cross architecture loading.
+
+Returns:
+
+ EFI_SUCCESS - The file was loaded, relocated, and invoked.
+ EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file.
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_BUFFER_TOO_SMALL - Buffer for image is too small.
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN DstBufAlocated;
+ UINTN Size;
+ EFI_IMAGE_NT_HEADERS64 *PeHdr;
+ EFI_TCG_PLATFORM_PROTOCOL *TcgPlatformProtocol;
+ IMAGE_FILE_HANDLE *FHandle;
+ BOOLEAN NeedAllocateAddress;
+#ifdef EFI_LOAD_DRIVER_AT_FIXED_OFFSET
+ BOOLEAN OffsetMode;
+ STATIC BOOLEAN PrintTopAddress = TRUE;
+#endif
+
+ DEBUG_CODE (
+ UINTN Index;
+ UINTN StartIndex;
+ CHAR8 EfiFileName[256];
+ )
+
+ EfiCommonLibZeroMem (&(Image->ImageContext), sizeof (Image->ImageContext));
+
+ Image->ImageContext.Handle = Pe32Handle;
+ Image->ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) CoreReadImageFile;
+
+ //
+ // Get information about the image being loaded.
+ //
+ Status = gEfiPeiPeCoffLoader->GetImageInfo (gEfiPeiPeCoffLoader, &(Image->ImageContext));
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check the processor architecture of the image
+ //
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) {
+ if (CrossLoad) {
+ if (!EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (Image->ImageContext.Machine)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ //
+ // Allocate memory of the correct memory type aligned on the required image boundary.
+ //
+ DstBufAlocated = FALSE;
+ if (DstBuffer == 0) {
+ //
+ // Allocate Destination Buffer as caller did not pass it in.
+ //
+
+ if (Image->ImageContext.SectionAlignment > EFI_PAGE_SIZE) {
+ Size = (UINTN) Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment;
+ } else {
+ Size = (UINTN) Image->ImageContext.ImageSize;
+ }
+
+ Image->NumberOfPages = EFI_SIZE_TO_PAGES (Size);
+ //
+ // Following code is to support load a PE image at fixed offset relative to TOLM
+ //
+#ifdef EFI_LOAD_DRIVER_AT_FIXED_OFFSET
+ {
+ typedef struct {
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ EFI_PHYSICAL_ADDRESS MaximumAddress;
+ UINT64 CurrentNumberOfPages;
+ UINT64 NumberOfPages;
+ UINTN InformationIndex;
+ BOOLEAN Special;
+ BOOLEAN Runtime;
+ } EFI_MEMORY_TYPE_STAISTICS;
+
+
+ extern EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1];
+ INT32 Offset;
+ UINTN ReadSize = sizeof (UINT32);
+
+ if (PrintTopAddress) {
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Runtime code top address: %lX\n", mMemoryTypeStatistics[EfiRuntimeServicesCode].MaximumAddress + 1));
+ DEBUG ((EFI_D_INFO | EFI_D_LOAD, "Boot time code top address: %lX\n", mMemoryTypeStatistics[EfiBootServicesCode].MaximumAddress + 1));
+ PrintTopAddress = FALSE;
+ }
+ OffsetMode = FALSE;
+ Status = Image->ImageContext.ImageRead (
+ Image->ImageContext.Handle,
+ Image->ImageContext.PeCoffHeaderOffset + 12,
+ &ReadSize,
+ &Offset
+ );
+ if (!EFI_ERROR (Status) && Offset != 0 &&
+ Image->ImageContext.ImageCodeMemoryType != EfiLoaderCode) {
+ OffsetMode = TRUE;
+ Image->ImageContext.ImageAddress = mMemoryTypeStatistics[Image->ImageContext.ImageCodeMemoryType].MaximumAddress + 1 - Offset;
+ }
+ }
+#endif
+
+ //
+ // If the image relocations are stripped, or fixed address/offset feature is valid,
+ // try to load the image to the specified address first.
+ // Otherwise try to load the image at any page if image relocations are available.
+ //
+ NeedAllocateAddress = FALSE;
+ if (Image->ImageContext.RelocationsStripped) {
+ NeedAllocateAddress = TRUE;
+ }
+#ifdef EFI_LOAD_DRIVER_AT_FIXED_ADDRESS
+ NeedAllocateAddress = TRUE;
+#endif
+#ifdef EFI_LOAD_DRIVER_AT_FIXED_OFFSET
+ if (OffsetMode) {
+ NeedAllocateAddress = TRUE;
+ }
+#endif
+ Status = EFI_OUT_OF_RESOURCES;
+ if (NeedAllocateAddress) {
+ Status = CoreAllocatePages (
+ AllocateAddress,
+ Image->ImageContext.ImageCodeMemoryType,
+ Image->NumberOfPages,
+ &Image->ImageContext.ImageAddress
+ );
+#ifdef EFI_LOAD_DRIVER_AT_FIXED_OFFSET
+ if (EFI_ERROR (Status) && OffsetMode) {
+ DEBUG((EFI_D_ERROR, "\nOffset mode load failure!"));
+ }
+#endif
+ }
+ if (EFI_ERROR (Status) && !Image->ImageContext.RelocationsStripped) {
+ Status = CoreAllocatePages (
+ AllocateAnyPages,
+ Image->ImageContext.ImageCodeMemoryType,
+ Image->NumberOfPages,
+ &Image->ImageContext.ImageAddress
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ DstBufAlocated = TRUE;
+ } else {
+ //
+ // Caller provided the destination buffer.
+ //
+
+ if (Image->ImageContext.RelocationsStripped && (Image->ImageContext.ImageAddress != DstBuffer)) {
+ //
+ // If the image relocations were stripped, and the caller provided a
+ // destination buffer address that does not match the address that the
+ // image is linked at, then the image cannot be loaded.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Size = EFI_SIZE_TO_PAGES ((UINTN) Image->ImageContext.ImageSize + Image->ImageContext.SectionAlignment);
+
+ if ((Image->NumberOfPages != 0) && (Image->NumberOfPages < Size)) {
+ Image->NumberOfPages = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Image->NumberOfPages = Size;
+ Image->ImageContext.ImageAddress = DstBuffer;
+ }
+
+ Image->ImageBasePage = Image->ImageContext.ImageAddress;
+ Image->ImageContext.ImageAddress =
+ (Image->ImageContext.ImageAddress + Image->ImageContext.SectionAlignment - 1) &
+ ~((UINTN) Image->ImageContext.SectionAlignment - 1);
+
+ //
+ // Load the image from the file into the allocated memory
+ //
+ Status = gEfiPeiPeCoffLoader->LoadImage (gEfiPeiPeCoffLoader, &(Image->ImageContext));
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // If this is a Runtime Driver, then allocate memory for the FixupData that
+ // is used to relocate the image when SetVirtualAddressMap() is called. The
+ // relocation is done by the Runtime AP.
+ //
+ if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) {
+ if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER &&
+ EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) {
+ Image->ImageContext.FixupData = CoreAllocateRuntimePool ((UINTN)(Image->ImageContext.FixupDataSize));
+ if (Image->ImageContext.FixupData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ }
+ }
+
+ //
+ // Measure the image before applying fixup
+ //
+ Status = CoreLocateProtocol (
+ &gEfiTcgPlatformProtocolGuid,
+ NULL,
+ &TcgPlatformProtocol
+ );
+ if (!EFI_ERROR (Status)) {
+ PeHdr = (EFI_IMAGE_NT_HEADERS64 *)(UINTN) (
+ Image->ImageContext.ImageAddress +
+ Image->ImageContext.PeCoffHeaderOffset
+ );
+ FHandle = (IMAGE_FILE_HANDLE *)Image->ImageContext.Handle;
+
+ Status = TcgPlatformProtocol->MeasurePeImage (
+ BootPolicy,
+ (EFI_PHYSICAL_ADDRESS)FHandle->Source,
+ FHandle->SourceSize,
+ (UINTN) PeHdr->OptionalHeader.ImageBase,
+ Image->ImageContext.ImageType,
+ Image->Info.DeviceHandle,
+ Image->Info.FilePath
+ );
+
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Relocate the image in memory
+ //
+ Status = gEfiPeiPeCoffLoader->RelocateImage (gEfiPeiPeCoffLoader, &(Image->ImageContext));
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Flush the Instruction Cache
+ //
+ Status = CoreFlushICache (Image->ImageContext.ImageAddress, Image->ImageContext.ImageSize);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Get the image entry point. If it's an EBC image, then call into the
+ // interpreter to create a thunk for the entry point and use the returned
+ // value for the entry point.
+ //
+ Image->EntryPoint = (EFI_IMAGE_ENTRY_POINT) (UINTN) Image->ImageContext.EntryPoint;
+
+ //
+ // Copy the machine type from the context to the image private data. This
+ // is needed during image unload to know if we should call an EBC protocol
+ // to unload the image.
+ //
+ Image->Machine = Image->ImageContext.Machine;
+ if (Image->ImageContext.Machine == EFI_IMAGE_MACHINE_EBC) {
+ //
+ // Locate the EBC interpreter protocol
+ //
+ Status = CoreLocateProtocol (&gEfiEbcProtocolGuid, NULL, &Image->Ebc);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Register a callback for flushing the instruction cache so that created
+ // thunks can be flushed.
+ //
+ Status = Image->Ebc->RegisterICacheFlush (Image->Ebc, CoreFlushICache);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Create a thunk for the image's entry point. This will be the new
+ // entry point for the image.
+ //
+ Status = Image->Ebc->CreateThunk (
+ Image->Ebc,
+ Image->Handle,
+ (VOID *)(UINTN)Image->ImageContext.EntryPoint,
+ (VOID **)&Image->EntryPoint
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+
+ //
+ // Fill in the image information for the Loaded Image Protocol
+ //
+ Image->Type = Image->ImageContext.ImageType;
+ Image->Info.ImageBase = (VOID *) (UINTN) Image->ImageContext.ImageAddress;
+ Image->Info.ImageSize = Image->ImageContext.ImageSize;
+ Image->Info.ImageCodeType = Image->ImageContext.ImageCodeMemoryType;
+ Image->Info.ImageDataType = Image->ImageContext.ImageDataMemoryType;
+
+ if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION) {
+ if (Image->ImageContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
+ //
+ // Make a list off all the RT images so we can let the RT AP know about them.
+ //
+ Image->RuntimeData = CoreAllocateRuntimePool (sizeof(EFI_RUNTIME_IMAGE_ENTRY));
+ if (Image->RuntimeData == NULL) {
+ goto Done;
+ }
+ Image->RuntimeData->ImageBase = Image->Info.ImageBase;
+ Image->RuntimeData->ImageSize = (UINT64) (Image->Info.ImageSize);
+ Image->RuntimeData->RelocationData = Image->ImageContext.FixupData;
+ Image->RuntimeData->Handle = Image->Handle;
+ InsertTailList (&gRuntime->ImageHead, &Image->RuntimeData->Link);
+ }
+ }
+
+ //
+ // Fill in the entry point of the image if it is available
+ //
+ if (EntryPoint != NULL) {
+ *EntryPoint = Image->ImageContext.EntryPoint;
+ }
+
+ //
+ // Print the load address and the PDB file name if it is available
+ //
+
+ DEBUG_CODE (
+ {
+//*** AMI PORTING BEGIN ***//
+//The message is printed in CoreStartImage. Disable this one.
+/*
+ DEBUG ((
+ EFI_D_INFO | EFI_D_LOAD,
+ "Loading driver at 0x%x EntryPoint=0x%x ",
+ (UINTN) Image->ImageContext.ImageAddress,
+ (UINTN) Image->ImageContext.EntryPoint
+ ));
+*/
+//*** AMI PORTING END *****//
+ if (Image->ImageContext.PdbPointer != NULL) {
+ StartIndex = 0;
+ for (Index = 0; Image->ImageContext.PdbPointer[Index] != 0; Index++) {
+ if (Image->ImageContext.PdbPointer[Index] == '\\') {
+ StartIndex = Index + 1;
+ }
+ }
+ //
+ // Copy the PDB file name to our temporary string, and replace .pdb with .efi
+ //
+ for (Index = 0; Index < sizeof (EfiFileName); Index++) {
+ EfiFileName[Index] = Image->ImageContext.PdbPointer[Index + StartIndex];
+ if (EfiFileName[Index] == 0) {
+ EfiFileName[Index] = '.';
+ }
+ if (EfiFileName[Index] == '.') {
+ EfiFileName[Index + 1] = 'e';
+ EfiFileName[Index + 2] = 'f';
+ EfiFileName[Index + 3] = 'i';
+ EfiFileName[Index + 4] = 0;
+ break;
+ }
+ }
+//*** AMI PORTING BEGIN ***//
+//The message is printed in CoreStartImage. Disable this one.
+// DEBUG ((EFI_D_INFO | EFI_D_LOAD, "%a", EfiFileName));
+//*** AMI PORTING END *****//
+
+ }
+//*** AMI PORTING BEGIN ***//
+//The message is printed in CoreStartImage. Disable this one.
+// DEBUG ((EFI_D_INFO | EFI_D_LOAD, "\n"));
+//*** AMI PORTING END *****//
+
+ }
+ );
+
+ return EFI_SUCCESS;
+
+Done:
+
+ //
+ // Free memory.
+ //
+
+ if (DstBufAlocated) {
+ CoreFreePages (Image->ImageContext.ImageAddress, Image->NumberOfPages);
+ }
+
+ if (Image->ImageContext.FixupData != NULL) {
+ CoreFreePool (Image->ImageContext.FixupData);
+ }
+
+ return Status;
+}
+
+
+LOADED_IMAGE_PRIVATE_DATA *
+CoreLoadedImageInfo (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Get the image's private data from its handle.
+
+Arguments:
+
+ ImageHandle - The image handle
+
+Returns:
+
+ Return the image private data associated with ImageHandle.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ LOADED_IMAGE_PRIVATE_DATA *Image;
+
+ Status = CoreHandleProtocol (
+ ImageHandle,
+ &gEfiLoadedImageProtocolGuid,
+ &LoadedImage
+ );
+ if (!EFI_ERROR (Status)) {
+ Image = LOADED_IMAGE_PRIVATE_DATA_FROM_THIS (LoadedImage);
+ } else {
+ DEBUG ((EFI_D_LOAD, "CoreLoadedImageInfo: Not an ImageHandle %x\n", ImageHandle));
+ Image = NULL;
+ }
+
+ return Image;
+}
+
+
+EFI_STATUS
+CoreLoadImageCommon (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
+ IN OUT UINTN *NumberOfPages OPTIONAL,
+ OUT EFI_HANDLE *ImageHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
+ IN UINT32 Attribute,
+ IN BOOLEAN CrossLoad
+ )
+/*++
+
+Routine Description:
+
+ Loads an EFI image into memory and returns a handle to the image.
+
+Arguments:
+
+ BootPolicy - If TRUE, indicates that the request originates from the boot manager,
+ and that the boot manager is attempting to load FilePath as a boot selection.
+ ParentImageHandle - The caller's image handle.
+ FilePath - The specific file path from which the image is loaded.
+ SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
+ the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ DstBuffer - The buffer to store the image
+ NumberOfPages - If not NULL, on input a pointer to the page number of DstBuffer and on
+ output a pointer to the page number of the image. If this number of DstBuffer
+ is not enough, return EFI_BUFFER_TOO_SMALL and this parameter contain
+ the required number.
+ ImageHandle - Pointer to the returned image handle that is created when the image
+ is successfully loaded.
+ EntryPoint - A pointer to the entry point
+ Attribute - The bit mask of attributes to set for the load PE image
+ CrossLoad - Whether expect to support cross architecture loading
+
+Returns:
+
+ EFI_SUCCESS - The image was loaded into memory.
+ EFI_NOT_FOUND - The FilePath was not found.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_BUFFER_TOO_SMALL - The buffer is too small
+ EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
+ parsed to locate the proper protocol for loading the file.
+ EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
+--*/
+{
+ LOADED_IMAGE_PRIVATE_DATA *Image;
+ LOADED_IMAGE_PRIVATE_DATA *ParentImage;
+ IMAGE_FILE_HANDLE FHand;
+ EFI_STATUS Status;
+ EFI_STATUS SecurityStatus;
+ EFI_HANDLE DeviceHandle;
+ UINT32 AuthenticationStatus;
+ EFI_DEVICE_PATH_PROTOCOL *OriginalFilePath;
+ EFI_DEVICE_PATH_PROTOCOL *HandleFilePath;
+ UINTN FilePathSize;
+
+ SecurityStatus = EFI_SUCCESS;
+
+ ASSERT (gEfiCurrentTpl < EFI_TPL_NOTIFY);
+ ParentImage = NULL;
+
+ //
+ // The caller must pass in a valid ParentImageHandle
+ //
+ if (ImageHandle == NULL || ParentImageHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ParentImage = CoreLoadedImageInfo (ParentImageHandle);
+ if (ParentImage == NULL) {
+ DEBUG((EFI_D_LOAD|EFI_D_ERROR, "LoadImageEx: Parent handle not an image handle\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Get simple read access to the source file
+ //
+ OriginalFilePath = FilePath;
+ Status = CoreOpenImageFile (
+ BootPolicy,
+ SourceBuffer,
+ SourceSize,
+ &FilePath,
+ &DeviceHandle,
+ &FHand,
+ &AuthenticationStatus
+ );
+ if (Status == EFI_ALREADY_STARTED) {
+ Image = NULL;
+ goto Done;
+ } else if (EFI_ERROR (Status)) {
+ return Status;
+ }
+//*** AMI PORTING BEGIN ***//
+ //
+ // Verify the Authentication Status through the Security2 Architectural Protocol
+ //
+ if ((gSecurity2 != NULL) && (OriginalFilePath != NULL)) {
+ SecurityStatus = gSecurity2->FileAuthentication (
+ gSecurity2,
+ OriginalFilePath,
+ FHand.Source,
+ FHand.SourceSize,
+ BootPolicy
+ );
+ if (EFI_ERROR (SecurityStatus) && SecurityStatus != EFI_SECURITY_VIOLATION) {
+ Status = SecurityStatus;
+ Image = NULL;
+ goto Done;
+ }
+ }
+//*** AMI PORTING END ***//
+
+ //
+ // Allocate a new image structure
+ //
+ Image = CoreAllocateZeroBootServicesPool (sizeof(LOADED_IMAGE_PRIVATE_DATA));
+ if (Image == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Pull out just the file portion of the DevicePath for the LoadedImage FilePath
+ //
+ FilePath = OriginalFilePath;
+ Status = CoreHandleProtocol (DeviceHandle, &gEfiDevicePathProtocolGuid, &HandleFilePath);
+ if (!EFI_ERROR (Status)) {
+ FilePathSize = CoreDevicePathSize (HandleFilePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
+ FilePath = (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *)FilePath) + FilePathSize );
+ }
+
+ //
+ // Initialize the fields for an internal driver
+ //
+ Image->Signature = LOADED_IMAGE_PRIVATE_DATA_SIGNATURE;
+ Image->Info.SystemTable = gST;
+ Image->Info.DeviceHandle = DeviceHandle;
+ Image->Info.Revision = EFI_LOADED_IMAGE_INFORMATION_REVISION;
+ Image->Info.FilePath = CoreDuplicateDevicePath (FilePath);
+ Image->Info.ParentHandle = ParentImageHandle;
+
+ if (NumberOfPages != NULL) {
+ Image->NumberOfPages = *NumberOfPages ;
+ } else {
+ Image->NumberOfPages = 0 ;
+ }
+
+ //
+ // Install the protocol interfaces for this image
+ // don't fire notifications yet
+ //
+ Status = CoreInstallProtocolInterfaceNotify (
+ &Image->Handle,
+ &gEfiLoadedImageProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &Image->Info,
+ FALSE
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Install Debug Mask Protocol
+ //
+ DEBUG_CODE (
+ Status = InstallDebugMaskProtocol(Image->Handle);
+ ASSERT_EFI_ERROR (Status);
+ )
+
+ //
+ // Load the image. If EntryPoint is Null, it will not be set.
+ //
+ Status = CoreLoadPeImage (BootPolicy, &FHand, Image, DstBuffer, EntryPoint, Attribute, CrossLoad);
+ if (EFI_ERROR (Status)) {
+ if ((Status == EFI_BUFFER_TOO_SMALL) || (Status == EFI_OUT_OF_RESOURCES)) {
+ if (NumberOfPages != NULL) {
+ *NumberOfPages = Image->NumberOfPages;
+ }
+ }
+ goto Done;
+ }
+ if (NumberOfPages != NULL) {
+ *NumberOfPages = Image->NumberOfPages;
+ }
+
+ //
+ // Register the image in the Debug Image Info Table if the attribute is set
+ //
+ if (Attribute & EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION) {
+ CoreNewDebugImageInfoEntry (EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL, &Image->Info, Image->Handle);
+ }
+
+ //
+ //Reinstall loaded image protocol to fire any notifications
+ //
+ Status = CoreReinstallProtocolInterface (
+ Image->Handle,
+ &gEfiLoadedImageProtocolGuid,
+ &Image->Info,
+ &Image->Info
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // If DevicePath parameter to the LoadImage() is not NULL, then make a copy of DevicePath,
+ // otherwise Loaded Image Device Path Protocol is installed with a NULL interface pointer.
+ //
+ if (OriginalFilePath != NULL) {
+ Image->LoadedImageDevicePath = CoreDuplicateDevicePath (OriginalFilePath);
+ }
+
+ //
+ // Install Loaded Image Device Path Protocol onto the image handle of a PE/COFE image
+ //
+ Status = CoreInstallProtocolInterface (
+ &Image->Handle,
+ &gEfiLoadedImageDevicePathProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ Image->LoadedImageDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Install HII Package List Protocol onto the image handle
+ //
+ if (Image->ImageContext.HiiResourceData != 0) {
+ Status = CoreInstallProtocolInterface (
+ &Image->Handle,
+ &gEfiHiiPackageListProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (VOID *) (UINTN) Image->ImageContext.HiiResourceData
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+#endif
+
+ //
+ // Success. Return the image handle
+ //
+ *ImageHandle = Image->Handle;
+
+Done:
+ //
+ // All done accessing the source file
+ // If we allocated the Source buffer, free it
+ //
+ if (FHand.FreeBuffer) {
+ CoreFreePool (FHand.Source);
+ }
+
+ //
+ // There was an error. If there's an Image structure, free it
+ //
+ if (EFI_ERROR (Status)) {
+ if (Image != NULL) {
+ CoreUnloadAndCloseImage (Image, (BOOLEAN)(DstBuffer == 0));
+ *ImageHandle = NULL;
+ }
+ } else if (EFI_ERROR (SecurityStatus)) {
+ Status = SecurityStatus;
+ }
+
+ return Status;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreLoadImage (
+ IN BOOLEAN BootPolicy,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Loads an EFI image into memory and returns a handle to the image.
+
+Arguments:
+
+ BootPolicy - If TRUE, indicates that the request originates from the boot manager,
+ and that the boot manager is attempting to load FilePath as a boot selection.
+ ParentImageHandle - The caller's image handle.
+ FilePath - The specific file path from which the image is loaded.
+ SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
+ the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ ImageHandle - Pointer to the returned image handle that is created when the image
+ is successfully loaded.
+
+Returns:
+
+ EFI_SUCCESS - The image was loaded into memory.
+ EFI_NOT_FOUND - The FilePath was not found.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
+ parsed to locate the proper protocol for loading the file.
+ EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
+--*/
+{
+ EFI_STATUS Status;
+//*** AMI PORTING BEGIN ***//
+//Verify that device path is sane
+ if(FilePath != NULL) {
+ Status = IsValidDevicePath(FilePath);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ if (BootPolicy){
+ AmiFillFpdt (FillOsLoaderLoadImageStart); // Fill OsLoaderLoadImageStart field in FPDT
+ gFillFpdt = TRUE;
+ }
+//*** AMI PORTING END ***//
+ PERF_START (NULL, L"LoadImage", NULL, 0);
+
+ Status = CoreLoadImageCommon (
+ BootPolicy,
+ ParentImageHandle,
+ FilePath,
+ SourceBuffer,
+ SourceSize,
+ (EFI_PHYSICAL_ADDRESS)NULL,
+ NULL,
+ ImageHandle,
+ NULL,
+ EFI_LOAD_PE_IMAGE_ATTRIBUTE_RUNTIME_REGISTRATION | EFI_LOAD_PE_IMAGE_ATTRIBUTE_DEBUG_IMAGE_INFO_TABLE_REGISTRATION,
+ FALSE
+ );
+
+ if (!EFI_ERROR (Status)) {
+ PERF_UPDATE (0, L"LoadImage", NULL, *ImageHandle, L"LoadImage", NULL);
+ PERF_END (*ImageHandle, L"LoadImage", NULL, 0);
+ } else {
+ PERF_UPDATE (0, L"LoadImage", NULL, 0, L"Load Failed", L"CoreLoadImage");
+ PERF_END (0, L"Load Failed", L"CoreLoadImage", 0);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreLoadImageEx (
+ IN EFI_PE32_IMAGE_PROTOCOL *This,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
+ OUT UINTN *NumberOfPages OPTIONAL,
+ OUT EFI_HANDLE *ImageHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
+ IN UINT32 Attribute
+ )
+/*++
+
+Routine Description:
+
+ Loads an EFI image into memory and returns a handle to the image with extended parameters.
+
+Arguments:
+
+ This - Calling context
+ ParentImageHandle - The caller's image handle.
+ FilePath - The specific file path from which the image is loaded.
+ SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
+ the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ DstBuffer - The buffer to store the image.
+ NumberOfPages - For input, specifies the space size of the image by caller if not NULL.
+ For output, specifies the actual space size needed.
+ ImageHandle - Image handle for output.
+ EntryPoint - Image entry point for output.
+ Attribute - The bit mask of attributes to set for the load PE image.
+
+Returns:
+
+ EFI_SUCCESS - The image was loaded into memory.
+ EFI_NOT_FOUND - The FilePath was not found.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
+ parsed to locate the proper protocol for loading the file.
+ EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
+--*/
+{
+ return CoreLoadImageCommon (
+ FALSE,
+ ParentImageHandle,
+ FilePath,
+ SourceBuffer,
+ SourceSize,
+ DstBuffer,
+ NumberOfPages,
+ ImageHandle,
+ EntryPoint,
+ Attribute,
+ TRUE
+ );
+}
+
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreStartImage (
+ IN EFI_HANDLE ImageHandle,
+ OUT UINTN *ExitDataSize,
+ OUT CHAR16 **ExitData OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Transfer control to a loaded image's entry point.
+
+Arguments:
+
+ ImageHandle - Handle of image to be started.
+
+ ExitDataSize - Pointer of the size to ExitData
+
+ ExitData - Pointer to a pointer to a data buffer that includes a Null-terminated
+ Unicode string, optionally followed by additional binary data. The string
+ is a description that the caller may use to further indicate the reason for
+ the image's exit.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Successfully transfer control to the image's entry point.
+
+--*/
+{
+ EFI_STATUS Status;
+ LOADED_IMAGE_PRIVATE_DATA *Image;
+ LOADED_IMAGE_PRIVATE_DATA *LastImage;
+ UINT64 HandleDatabaseKey;
+
+ Image = CoreLoadedImageInfo (ImageHandle);
+ if (Image == NULL_HANDLE || Image->Started) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Cannot start image of an unsupported processor architecture
+ //
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (Image->ImageContext.Machine)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Don't profile Objects or invalid start requests
+ //
+//*** AMI PORTING BEGIN ***//
+ if (gFillFpdt)
+ {
+ AmiFillFpdt (FillOsLoaderStartImageStart); // Fill OsLoaderStartImageStart field in FPDT
+ gFillFpdt = FALSE;
+ }
+//*** AMI PORTING END ***//
+ PERF_START (ImageHandle, START_IMAGE_TOK, NULL, 0);
+
+ //
+ // Push the current start image context, and
+ // link the current image to the head. This is the
+ // only image that can call Exit()
+ //
+ HandleDatabaseKey = CoreGetHandleDatabaseKey();
+ LastImage = mCurrentImage;
+ mCurrentImage = Image;
+ Image->Tpl = gEfiCurrentTpl;
+
+ //
+ // Set long jump for Exit() support
+ //
+ Image->JumpContext = CoreAllocateBootServicesPool (gEfiPeiTransferControl->JumpContextSize);
+ if (Image->JumpContext == NULL) {
+ PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gEfiPeiTransferControl->SetJump (gEfiPeiTransferControl, Image->JumpContext);
+ //
+ // The SetJump returns EFI_SUCCESS when LongJump Buffer has been armed
+ // SetJump returns EFI_WARN_RETURN_FROM_LONG_JUMP as a result of the LongJump
+ // All other return values for SetJump are undefined.
+ //
+ if (Status == EFI_SUCCESS) {
+
+ //
+ // Call the image's entry point
+ //
+ Image->Started = TRUE;
+//*** AMI PORTING BEGIN ***//
+#ifdef EFI_DEBUG
+{
+//Debug message: name/entry point of the module being started
+BOOLEAN GetImageName(EFI_HANDLE ImageHandle, CHAR8 *sName);
+VOID Trace(UINTN Level, CHAR8 *sFormat,...);
+CHAR8 sName[0x100];
+
+ GetImageName(ImageHandle,sName);
+ Trace(-1, "%s.Entry(%X)\n", sName, Image->EntryPoint);
+#endif
+{ // Report Status Code
+ static EFI_DEVICE_HANDLE_EXTENDED_DATA DeviceHandleExtData = {
+ {
+ sizeof(EFI_STATUS_CODE_DATA),
+ sizeof(EFI_DEVICE_HANDLE_EXTENDED_DATA) - sizeof(EFI_STATUS_CODE_DATA),
+ EFI_STATUS_CODE_SPECIFIC_DATA_GUID
+ },
+ 0
+ };
+
+ DeviceHandleExtData.Handle = ImageHandle;
+ LibReportStatusCode(
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_BEGIN,
+ 0,
+ &gEfiDxeServicesTableGuid,
+ &DeviceHandleExtData.DataHeader
+ );
+}
+//*** AMI PORTING END *****//
+ Image->Status = Image->EntryPoint (ImageHandle, Image->Info.SystemTable);
+//*** AMI PORTING BEGIN ***//
+#ifdef EFI_DEBUG
+ if (EFI_ERROR(Image->Status)&&Image->Status!=EFI_UNLOAD_IMAGE) Trace(-1, "ERROR: %s.Entry(%X)=%r\n", sName, Image->EntryPoint, Image->Status);
+}
+#endif
+
+ //
+ // Add some debug information if the image returned with error.
+ // This make the user aware and check if the driver image have already released
+ // all the resource in this situation.
+ //
+/* Comment out original message.
+ DEBUG_CODE (
+ if (EFI_ERROR (Image->Status)) {
+ DEBUG ((EFI_D_ERROR, "Error: Image at %08X start failed: %x\n", Image->Info.ImageBase, Image->Status));
+ }
+ )
+*/
+//*** AMI PORTING END *****//
+ //
+ // If the image returns, exit it through Exit()
+ //
+ CoreExit (ImageHandle, Image->Status, 0, NULL);
+ }
+
+ //
+ // Image has completed. Verify the tpl is the same
+ //
+ ASSERT (Image->Tpl == gEfiCurrentTpl);
+ CoreRestoreTpl (Image->Tpl);
+
+ CoreFreePool (Image->JumpContext);
+
+ //
+ // Pop the current start image context
+ //
+ mCurrentImage = LastImage;
+
+ //
+ // Go connect any handles that were created or modified while the image executed.
+ //
+ CoreConnectHandlesByKey (HandleDatabaseKey);
+
+ //
+ // Handle the image's returned ExitData
+ //
+ DEBUG_CODE (
+ if (Image->ExitDataSize != 0 || Image->ExitData != NULL) {
+
+ DEBUG (
+ (EFI_D_LOAD,
+ "StartImage: ExitDataSize %d, ExitData %x",
+ Image->ExitDataSize,
+ Image->ExitData)
+ );
+ if (Image->ExitData != NULL) {
+ DEBUG ((EFI_D_LOAD, " (%hs)", Image->ExitData));
+ }
+ DEBUG ((EFI_D_LOAD, "\n"));
+ }
+ )
+
+ //
+ // Return the exit data to the caller
+ //
+ if (ExitData != NULL && ExitDataSize != NULL) {
+ *ExitDataSize = Image->ExitDataSize;
+ *ExitData = Image->ExitData;
+ } else {
+ //
+ // Caller doesn't want the exit data, free it
+ //
+ CoreFreePool (Image->ExitData);
+ Image->ExitData = NULL;
+ }
+
+ //
+ // Save the Status because Image will get destroyed if it is unloaded.
+ //
+ Status = Image->Status;
+
+ //
+ // If the image returned an error, or if the image is an application
+ // unload it
+ //
+ if (EFI_ERROR (Image->Status) || Image->Type == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {
+ CoreUnloadAndCloseImage (Image, TRUE);
+ }
+
+ //
+ // Done
+ //
+ PERF_END (ImageHandle, START_IMAGE_TOK, NULL, 0);
+ return Status;
+}
+
+
+VOID
+CoreUnloadAndCloseImage (
+ IN LOADED_IMAGE_PRIVATE_DATA *Image,
+ IN BOOLEAN FreePage
+ )
+/*++
+
+Routine Description:
+
+ Unloads EFI image from memory.
+
+Arguments:
+
+ Image - EFI image
+ FreePage - Free allocated pages
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleIndex;
+ EFI_GUID **ProtocolGuidArray;
+ UINTN ArrayCount;
+ UINTN ProtocolIndex;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN OpenInfoIndex;
+
+ if (Image->Ebc != NULL) {
+ //
+ // If EBC protocol exists we must perform cleanups for this image.
+ //
+ Image->Ebc->UnloadImage (Image->Ebc, Image->Handle);
+ }
+
+ //
+ // Unload image, free Image->ImageContext->ModHandle
+ //
+ gEfiPeiPeCoffLoader->UnloadImage (&Image->ImageContext);
+
+ //
+ // Free our references to the image handle
+ //
+ if (Image->Handle != NULL_HANDLE) {
+
+ Status = CoreLocateHandleBuffer (
+ AllHandles,
+ NULL,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (!EFI_ERROR (Status)) {
+ for (HandleIndex = 0; HandleIndex < HandleCount; HandleIndex++) {
+ Status = CoreProtocolsPerHandle (
+ HandleBuffer[HandleIndex],
+ &ProtocolGuidArray,
+ &ArrayCount
+ );
+ if (!EFI_ERROR (Status)) {
+ for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {
+ Status = CoreOpenProtocolInformation (
+ HandleBuffer[HandleIndex],
+ ProtocolGuidArray[ProtocolIndex],
+ &OpenInfo,
+ &OpenInfoCount
+ );
+ if (!EFI_ERROR (Status)) {
+ for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {
+ if (OpenInfo[OpenInfoIndex].AgentHandle == Image->Handle) {
+ Status = CoreCloseProtocol (
+ HandleBuffer[HandleIndex],
+ ProtocolGuidArray[ProtocolIndex],
+ Image->Handle,
+ OpenInfo[OpenInfoIndex].ControllerHandle
+ );
+ }
+ }
+ if (OpenInfo != NULL) {
+ CoreFreePool(OpenInfo);
+ }
+ }
+ }
+ if (ProtocolGuidArray != NULL) {
+ CoreFreePool(ProtocolGuidArray);
+ }
+ }
+ }
+ if (HandleBuffer != NULL) {
+ CoreFreePool (HandleBuffer);
+ }
+ }
+
+ CoreRemoveDebugImageInfoEntry (Image->Handle);
+
+ Status = CoreUninstallProtocolInterface (
+ Image->Handle,
+ &gEfiLoadedImageProtocolGuid,
+ &Image->Info
+ );
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ Status = CoreUninstallProtocolInterface (
+ Image->Handle,
+ &gEfiLoadedImageDevicePathProtocolGuid,
+ Image->LoadedImageDevicePath
+ );
+
+ if (Image->LoadedImageDevicePath != NULL) {
+ CoreFreePool (Image->LoadedImageDevicePath);
+ }
+
+ if (Image->ImageContext.HiiResourceData != 0) {
+ Status = CoreUninstallProtocolInterface (
+ Image->Handle,
+ &gEfiHiiPackageListProtocolGuid,
+ (VOID *) (UINTN) Image->ImageContext.HiiResourceData
+ );
+ }
+#endif
+
+ //
+ // Uninstall Debug Mask Protocol
+ //
+ DEBUG_CODE (
+ Status = UninstallDebugMaskProtocol(Image->Handle);
+ ASSERT_EFI_ERROR (Status);
+ )
+
+ }
+
+ if (Image->RuntimeData != NULL) {
+ if (Image->RuntimeData->Link.ForwardLink != NULL) {
+ //
+ // Remove the Image from the Runtime Image list as we are about to Free it!
+ //
+ RemoveEntryList (&Image->RuntimeData->Link);
+ }
+ CoreFreePool (Image->RuntimeData);
+ }
+
+ //
+ // Free the Image from memory
+ //
+ if ((Image->ImageBasePage != 0) && FreePage) {
+ CoreFreePages (Image->ImageBasePage, Image->NumberOfPages);
+ }
+
+ //
+ // Done with the Image structure
+ //
+ if (Image->Info.FilePath != NULL) {
+ CoreFreePool (Image->Info.FilePath);
+ }
+
+ if (Image->FixupData != NULL) {
+ CoreFreePool (Image->FixupData);
+ }
+
+ CoreFreePool (Image);
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreExit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_STATUS Status,
+ IN UINTN ExitDataSize,
+ IN CHAR16 *ExitData OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Terminates the currently loaded EFI image and returns control to boot services.
+
+Arguments:
+
+ ImageHandle - Handle that identifies the image. This parameter is passed to the image
+ on entry.
+ Status - The image's exit code.
+ ExitDataSize - The size, in bytes, of ExitData. Ignored if ExitStatus is
+ EFI_SUCCESS.
+ ExitData - Pointer to a data buffer that includes a Null-terminated Unicode string,
+ optionally followed by additional binary data. The string is a
+ description that the caller may use to further indicate the reason for
+ the image's exit.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Image handle is NULL or it is not current image.
+
+ EFI_SUCCESS - Successfully terminates the currently loaded EFI image.
+
+ EFI_ACCESS_DENIED - Should never reach there.
+
+ EFI_OUT_OF_RESOURCES - Could not allocate pool
+
+--*/
+{
+ LOADED_IMAGE_PRIVATE_DATA *Image;
+
+ Image = CoreLoadedImageInfo (ImageHandle);
+ if (Image == NULL_HANDLE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!Image->Started) {
+ //
+ // The image has not been started so just free its resources
+ //
+ CoreUnloadAndCloseImage (Image, TRUE);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Image has been started, verify this image can exit
+ //
+ if (Image != mCurrentImage) {
+ DEBUG ((EFI_D_LOAD|EFI_D_ERROR, "Exit: Image is not exitable image\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Set status
+ //
+ Image->Status = Status;
+
+ //
+ // If there's ExitData info, move it
+ //
+ if (ExitData != NULL) {
+ Image->ExitDataSize = ExitDataSize;
+ Image->ExitData = CoreAllocateBootServicesPool (Image->ExitDataSize);
+ if (Image->ExitData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ EfiCommonLibCopyMem (Image->ExitData, ExitData, Image->ExitDataSize);
+ }
+
+ //
+ // return to StartImage
+ //
+ Status = gEfiPeiTransferControl->LongJump (gEfiPeiTransferControl, Image->JumpContext);
+
+ //
+ // If we return from LongJump, then it is an error
+ //
+ ASSERT (FALSE);
+ return EFI_ACCESS_DENIED;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreUnloadImage (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Unloads an image.
+
+Arguments:
+
+ ImageHandle - Handle that identifies the image to be unloaded.
+
+Returns:
+
+ EFI_SUCCESS - The image has been unloaded.
+ EFI_UNSUPPORTED - The image has been sarted, and does not support unload.
+ EFI_INVALID_PARAMPETER - ImageHandle is not a valid image handle.
+
+--*/
+{
+ EFI_STATUS Status;
+ LOADED_IMAGE_PRIVATE_DATA *Image;
+
+ Image = CoreLoadedImageInfo (ImageHandle);
+ if (Image == NULL ) {
+ //
+ // The image handle is not valid
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Image->Started) {
+ //
+ // The image has been started, request it to unload.
+ //
+ Status = EFI_UNSUPPORTED;
+ if (Image->Info.Unload != NULL) {
+ Status = Image->Info.Unload (ImageHandle);
+ }
+
+ } else {
+ //
+ // This Image hasn't been started, thus it can be unloaded
+ //
+ Status = EFI_SUCCESS;
+ }
+
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // if the Image was not started or Unloaded O.K. then clean up
+ //
+ CoreUnloadAndCloseImage (Image, TRUE);
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+CoreUnloadImageEx (
+ IN EFI_PE32_IMAGE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Unload the specified image.
+
+Arguments:
+
+ This - Indicates the calling context.
+
+ ImageHandle - The specified image handle.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Image handle is NULL.
+
+ EFI_UNSUPPORTED - Attempt to unload an unsupported image.
+
+ EFI_SUCCESS - Image successfully unloaded.
+
+--*/
+{
+ return CoreUnloadImage (ImageHandle);
+}
+
+
+
+//
+// This callback function is used by the EBC interpreter driver to flush the
+// processor instruction cache after creating thunks. We're simply hiding
+// the "this" pointer that must be passed into the real flush function.
+//
+STATIC
+EFI_STATUS
+EFIAPI
+CoreFlushICache (
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ flush the processor instruction cache.
+
+Arguments:
+
+ Start - Start adddress in memory to flush.
+
+ Length - Length of memory to flush.
+
+Returns:
+
+--*/
+{
+ return gEfiPeiFlushInstructionCache->Flush (
+ gEfiPeiFlushInstructionCache,
+ Start,
+ Length
+ );
+}
+
+
diff --git a/Core/CORE_DXE/Image.h b/Core/CORE_DXE/Image.h
new file mode 100644
index 0000000..9679e1b
--- /dev/null
+++ b/Core/CORE_DXE/Image.h
@@ -0,0 +1,400 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Image.h
+
+Abstract:
+
+ EFI image loader
+
+--*/
+
+
+#ifndef _IMAGE_H_
+#define _IMAGE_H_
+
+
+#include "Tiano.h"
+#include "LinkedList.h"
+#include "DxeCore.h"
+
+#include EFI_PROTOCOL_PRODUCER (LoadedImage)
+#include EFI_PROTOCOL_PRODUCER (LoadPe32Image)
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+#include EFI_PROTOCOL_PRODUCER (LoadedImageDevicePath)
+#include EFI_PROTOCOL_CONSUMER (LoadFile2)
+#include EFI_PROTOCOL_PRODUCER (HiiPackageList)
+#endif
+
+#include EFI_PROTOCOL_CONSUMER (Ebc)
+#include EFI_PROTOCOL_CONSUMER (SimpleFileSystem)
+#include EFI_PROTOCOL_CONSUMER (FileInfo)
+#include EFI_PROTOCOL_CONSUMER (LoadFile)
+#include EFI_PROTOCOL_CONSUMER (FirmwareVolume)
+#include EFI_PROTOCOL_CONSUMER (FirmwareVolume2)
+
+#define LOADED_IMAGE_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32('l','d','r','i')
+
+typedef struct {
+ UINTN Signature; // Data Signature
+ EFI_HANDLE Handle; // Image handle
+ UINTN Type; // Image type
+
+ BOOLEAN Started; // If entrypoint has been called
+
+ EFI_IMAGE_ENTRY_POINT EntryPoint; // The image's entry point
+ EFI_LOADED_IMAGE_PROTOCOL Info; // loaded image protocol
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ EFI_DEVICE_PATH_PROTOCOL *LoadedImageDevicePath; // Loaded Image Device Path Protocl pointer
+#endif
+
+ EFI_PHYSICAL_ADDRESS ImageBasePage; // Location in memory
+ UINTN NumberOfPages; // Number of pages
+
+ CHAR8 *FixupData; // Original fixup data
+
+ EFI_TPL Tpl; // Tpl of started image
+ EFI_STATUS Status; // Status returned by started image
+
+ UINTN ExitDataSize; // Size of ExitData from started image
+ VOID *ExitData; // Pointer to exit data from started image
+ VOID *JumpContext; // Pointer to buffer for context save/retore
+ UINT16 Machine; // Machine type from PE image
+
+ EFI_EBC_PROTOCOL *Ebc; // EBC Protocol pointer
+
+ EFI_RUNTIME_IMAGE_ENTRY *RuntimeData; // Runtime image list
+
+ EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext; // PeCoffLoader ImageContext
+} LOADED_IMAGE_PRIVATE_DATA;
+
+#define LOADED_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, LOADED_IMAGE_PRIVATE_DATA, Info, LOADED_IMAGE_PRIVATE_DATA_SIGNATURE)
+
+
+#define LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE EFI_SIGNATURE_32('l','p','e','i')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_PE32_IMAGE_PROTOCOL Pe32Image;
+} LOAD_PE32_IMAGE_PRIVATE_DATA;
+
+#define LOAD_PE32_IMAGE_PRIVATE_DATA_FROM_THIS(a) \
+ CR(a, LOAD_PE32_IMAGE_PRIVATE_DATA, Pe32Image, LOAD_PE32_IMAGE_PRIVATE_DATA_SIGNATURE)
+
+//
+// Private Data Types
+//
+#define IMAGE_FILE_HANDLE_SIGNATURE EFI_SIGNATURE_32('i','m','g','f')
+typedef struct {
+ UINTN Signature;
+ BOOLEAN FreeBuffer;
+ VOID *Source;
+ UINTN SourceSize;
+} IMAGE_FILE_HANDLE;
+
+
+//
+// Abstractions for reading image contents
+//
+
+EFI_STATUS
+CoreOpenImageFile (
+ IN BOOLEAN BootPolicy,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT EFI_HANDLE *DeviceHandle,
+ IN IMAGE_FILE_HANDLE *ImageFileHandle,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+
+ Opens a file for (simple) reading. The simple read abstraction
+ will access the file either from a memory copy, from a file
+ system interface, or from the load file interface.
+
+Arguments:
+
+ BootPolicy - Policy for Open Image File.
+ SourceBuffer - Pointer to the memory location containing copy
+ of the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ FilePath - The specific file path from which the image is loaded
+ DeviceHandle - Pointer to the return device handle.
+ ImageFileHandle - Pointer to the image file handle.
+ AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned.
+
+Returns:
+
+ A handle to access the file
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+CoreReadImageFile (
+ IN VOID *UserHandle,
+ IN UINTN Offset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Read image file (specified by UserHandle) into user specified buffer with specified offset
+ and length.
+
+Arguments:
+
+ UserHandle - Image file handle
+
+ Offset - Offset to the source file
+
+ ReadSize - For input, pointer of size to read;
+ For output, pointer of size actually read.
+
+ Buffer - Buffer to write into
+
+Returns:
+
+ EFI_SUCCESS - Successfully read the specified part of file into buffer.
+
+--*/
+;
+
+VOID
+EFIAPI
+CoreCloseImageFile (
+ IN IMAGE_FILE_HANDLE *ImageFileHandle
+ )
+/*++
+
+Routine Description:
+
+ A function out of date, should be removed.
+
+Arguments:
+
+ ImageFileHandle - Handle of the file to close
+
+Returns:
+
+ None
+
+--*/
+;
+
+//
+// Image processing worker functions
+//
+EFI_STATUS
+CoreDevicePathToInterface (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT VOID **Interface,
+ OUT EFI_HANDLE *Handle
+ )
+/*++
+
+Routine Description:
+
+ Search a handle to a device on a specified device path that supports a specified protocol,
+ interface of that protocol on that handle is another output.
+
+Arguments:
+
+ Protocol - The protocol to search for
+
+ FilePath - The specified device path
+
+ Interface - Interface of the protocol on the handle
+
+ Handle - The handle to the device on the specified device path that supports the protocol.
+
+Returns:
+
+ Status code.
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+CoreLoadPeImage (
+ IN BOOLEAN BootPolicy,
+ IN VOID *Pe32Handle,
+ IN LOADED_IMAGE_PRIVATE_DATA *Image,
+ IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
+ IN UINT32 Attribute,
+ IN BOOLEAN CrossLoad
+ )
+/*++
+
+Routine Description:
+
+ Loads, relocates, and invokes a PE/COFF image
+
+Arguments:
+
+ Pe32Handle - The handle of PE32 image
+ Image - PE image to be loaded
+ DstBuffer - The buffer to store the image
+ EntryPoint - A pointer to the entry point
+ Attribute - The bit mask of attributes to set for the load PE image
+ CrossLoad - Whether expect to support cross architecture loading
+
+Returns:
+
+ EFI_SUCCESS - The file was loaded, relocated, and invoked
+
+ EFI_OUT_OF_RESOURCES - There was not enough memory to load and relocate the PE/COFF file
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_BUFFER_TOO_SMALL - Buffer for image is too small
+
+--*/
+;
+
+LOADED_IMAGE_PRIVATE_DATA *
+CoreLoadedImageInfo (
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ TODO: Add function description
+
+Arguments:
+
+ ImageHandle - TODO: add argument description
+
+Returns:
+
+ TODO: add return values
+
+--*/
+;
+
+VOID
+CoreUnloadAndCloseImage (
+ IN LOADED_IMAGE_PRIVATE_DATA *Image,
+ IN BOOLEAN FreePage
+ )
+/*++
+
+Routine Description:
+
+ Unloads EFI image from memory.
+
+Arguments:
+
+ Image - EFI image
+ FreePage - Free allocated pages
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+//
+// Exported Image functions
+//
+
+EFI_STATUS
+EFIAPI
+CoreLoadImageEx (
+ IN EFI_PE32_IMAGE_PROTOCOL *This,
+ IN EFI_HANDLE ParentImageHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ IN EFI_PHYSICAL_ADDRESS DstBuffer OPTIONAL,
+ OUT UINTN *NumberOfPages OPTIONAL,
+ OUT EFI_HANDLE *ImageHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint OPTIONAL,
+ IN UINT32 Attribute
+ )
+/*++
+
+Routine Description:
+
+ Loads an EFI image into memory and returns a handle to the image with extended parameters.
+
+Arguments:
+
+ ParentImageHandle - The caller's image handle.
+ FilePath - The specific file path from which the image is loaded.
+ SourceBuffer - If not NULL, a pointer to the memory location containing a copy of
+ the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ DstBuffer - The buffer to store the image.
+ NumberOfPages - For input, specifies the space size of the image by caller if not NULL.
+ For output, specifies the actual space size needed.
+ ImageHandle - Image handle for output.
+ EntryPoint - Image entry point for output.
+ Attribute - The bit mask of attributes to set for the load PE image.
+
+Returns:
+
+ EFI_SUCCESS - The image was loaded into memory.
+ EFI_NOT_FOUND - The FilePath was not found.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+ EFI_UNSUPPORTED - The image type is not supported, or the device path cannot be
+ parsed to locate the proper protocol for loading the file.
+ EFI_OUT_OF_RESOURCES - Image was not loaded due to insufficient resources.
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+CoreUnloadImageEx (
+ IN EFI_PE32_IMAGE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle
+ )
+/*++
+
+Routine Description:
+
+ Unload the specified image.
+
+Arguments:
+
+ This - Indicates the calling context.
+
+ ImageHandle - The specified image handle.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Image handle is NULL.
+
+ EFI_UNSUPPORTED - Attempt to unload an unsupported image.
+
+ EFI_SUCCESS - Image successfully unloaded.
+
+--*/
+;
+#endif
diff --git a/Core/CORE_DXE/ImageFile.c b/Core/CORE_DXE/ImageFile.c
new file mode 100644
index 0000000..0d36b7e
--- /dev/null
+++ b/Core/CORE_DXE/ImageFile.c
@@ -0,0 +1,639 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ ImageFile.c
+
+
+Abstract:
+
+
+
+
+Revision History
+
+--*/
+
+#include "Image.h"
+#include "DxeCore.h"
+
+
+VOID
+CoreDevicePathToFileName (
+ IN FILEPATH_DEVICE_PATH *FilePath,
+ OUT CHAR16 **String
+ );
+
+
+
+EFI_STATUS
+CoreOpenImageFile (
+ IN BOOLEAN BootPolicy,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT EFI_HANDLE *DeviceHandle,
+ IN IMAGE_FILE_HANDLE *ImageFileHandle,
+ OUT UINT32 *AuthenticationStatus
+ )
+/*++
+
+Routine Description:
+
+ Opens a file for (simple) reading. The simple read abstraction
+ will access the file either from a memory copy, from a file
+ system interface, or from the load file interface.
+
+Arguments:
+
+ BootPolicy - Policy for Open Image File.
+ SourceBuffer - Pointer to the memory location containing copy
+ of the image to be loaded.
+ SourceSize - The size in bytes of SourceBuffer.
+ FilePath - The specific file path from which the image is loaded
+ DeviceHandle - Pointer to the return device handle.
+ ImageFileHandle - Pointer to the image file handle.
+ AuthenticationStatus - Pointer to a caller-allocated UINT32 in which the authentication status is returned.
+
+Returns:
+
+ EFI_SUCCESS - Image file successfully opened.
+
+ EFI_LOAD_ERROR - If the caller passed a copy of the file, and SourceSize is 0.
+
+ EFI_INVALID_PARAMETER - File path is not valid.
+
+ EFI_NOT_FOUND - File not found.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *TempFilePath;
+ FILEPATH_DEVICE_PATH *FilePathNode;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FwVolFilePathNode;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
+ EFI_FILE_HANDLE FileHandle;
+ EFI_FILE_HANDLE LastHandle;
+ EFI_LOAD_FILE_PROTOCOL *LoadFile;
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ EFI_LOAD_FILE2_PROTOCOL *LoadFile2;
+#endif
+ EFI_SECTION_TYPE SectionType;
+ UINT8 *Pe32Buffer;
+ UINTN Pe32BufferSize;
+ EFI_FV_FILETYPE Type;
+ EFI_FV_FILE_ATTRIBUTES Attrib;
+ EFI_FILE_INFO *FileInfo;
+ UINTN FileInfoSize;
+ EFI_GUID *NameGuid;
+ FILEPATH_DEVICE_PATH *OriginalFilePathNode;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVol;
+#endif
+
+ *AuthenticationStatus = 0;
+ EfiCommonLibZeroMem (ImageFileHandle, sizeof (IMAGE_FILE_HANDLE));
+ ImageFileHandle->Signature = IMAGE_FILE_HANDLE_SIGNATURE;
+
+ //
+ // If the caller passed a copy of the file, then just use it
+ //
+ if (SourceBuffer != NULL) {
+ ImageFileHandle->Source = SourceBuffer;
+ ImageFileHandle->SourceSize = SourceSize;
+ *DeviceHandle = NULL;
+ CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, FilePath, DeviceHandle);
+ if (SourceSize > 0) {
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_LOAD_ERROR;
+ }
+ goto Done;
+ }
+
+ //
+ // Make sure FilePath is valid
+ //
+ if (*FilePath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check to see if it's in a Firmware Volume
+ //
+ FwVolFilePathNode = (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) *FilePath;
+ Status = CoreDevicePathToInterface (
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+ #else
+ &gEfiFirmwareVolume2ProtocolGuid,
+ #endif
+ (EFI_DEVICE_PATH_PROTOCOL **)&FwVolFilePathNode,
+ (VOID*)&FwVol,
+ DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // For FwVol File system there is only a single file name that is a GUID.
+ //
+ NameGuid = CoreGetNameGuidFromFwVolDevicePathNode (FwVolFilePathNode);
+ if (NameGuid != NULL) {
+
+ SectionType = EFI_SECTION_PE32;
+ Pe32Buffer = NULL;
+ Status = FwVol->ReadSection (
+ FwVol,
+ &FwVolFilePathNode->NameGuid,
+ SectionType,
+ 0,
+ &Pe32Buffer,
+ &Pe32BufferSize,
+ AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Try a raw file, since a PE32 SECTION does not exist
+ //
+ if (Pe32Buffer != NULL) {
+ CoreFreePool (Pe32Buffer);
+ *AuthenticationStatus = 0;
+ }
+ Pe32Buffer = NULL;
+ Status = FwVol->ReadFile (
+ FwVol,
+ &FwVolFilePathNode->NameGuid,
+ &Pe32Buffer,
+ &Pe32BufferSize,
+ &Type,
+ &Attrib,
+ AuthenticationStatus
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // One of the reads passed so we are done
+ //
+ ImageFileHandle->Source = Pe32Buffer;
+ ImageFileHandle->SourceSize = Pe32BufferSize;
+ ImageFileHandle->FreeBuffer = TRUE;
+ goto Done;
+ }
+ }
+ }
+
+ //
+ // Attempt to access the file via a file system interface
+ //
+ FilePathNode = (FILEPATH_DEVICE_PATH *) *FilePath;
+ Status = CoreDevicePathToInterface (
+ &gEfiSimpleFileSystemProtocolGuid,
+ (EFI_DEVICE_PATH_PROTOCOL **)&FilePathNode,
+ (VOID*)&Volume,
+ DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Open the Volume to get the File System handle
+ //
+ Status = Volume->OpenVolume (Volume, &FileHandle);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Duplicate the device path to avoid the access to unaligned device path node.
+ // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
+ // nodes, It assures the fields in device path nodes are 2 byte aligned.
+ //
+ FilePathNode = (FILEPATH_DEVICE_PATH *) CoreDuplicateDevicePath(
+ (EFI_DEVICE_PATH_PROTOCOL *)(UINTN)FilePathNode
+ );
+ if (FilePathNode == NULL) {
+ FileHandle->Close (FileHandle);
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ OriginalFilePathNode = FilePathNode;
+ //
+ // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
+ // directory information and filename can be seperate. The goal is to inch
+ // our way down each device path node and close the previous node
+ //
+ while (!IsDevicePathEnd (&FilePathNode->Header)) {
+ if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {
+ Status = EFI_UNSUPPORTED;
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Exit loop on Error
+ //
+ break;
+ }
+
+ LastHandle = FileHandle;
+ FileHandle = NULL;
+ Status = LastHandle->Open (
+ LastHandle,
+ &FileHandle,
+ FilePathNode->PathName,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+
+ //
+ // Close the previous node
+ //
+ LastHandle->Close (LastHandle);
+
+ FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
+ }
+ //
+ // Free the allocated memory pool
+ //
+ CoreFreePool (OriginalFilePathNode);
+ }
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // We have found the file. Now we need to read it. Before we can read the file we need to
+ // figure out how big the file is.
+ //
+ FileInfo = NULL;
+ FileInfoSize = sizeof (EFI_FILE_INFO);
+ while (CoreGrowBuffer (&Status, &FileInfo, FileInfoSize)) {
+ //
+ // Automatically allocate buffer of the correct size and make the call
+ //
+ Status = FileHandle->GetInfo (
+ FileHandle,
+ &gEfiFileInfoGuid,
+ &FileInfoSize,
+ FileInfo
+ );
+ }
+ if (!EFI_ERROR (Status)) {
+ //
+ // Allocate space for the file
+ //
+ ImageFileHandle->Source = CoreAllocateBootServicesPool ((UINTN)FileInfo->FileSize);
+ if (ImageFileHandle->Source != NULL) {
+ //
+ // Read the file into the buffer we allocated
+ //
+ ImageFileHandle->SourceSize = (UINTN)FileInfo->FileSize;
+ ImageFileHandle->FreeBuffer = TRUE;
+ Status = FileHandle->Read (FileHandle, &ImageFileHandle->SourceSize, ImageFileHandle->Source);
+
+ //
+ // Close the file since we are done
+ //
+ FileHandle->Close (FileHandle);
+ } else {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+
+ goto Done;
+ }
+ }
+ }
+ }
+
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // Try LoadFile2 style
+ //
+ if (!BootPolicy) {
+ TempFilePath = *FilePath;
+ Status = CoreDevicePathToInterface (
+ &gEfiLoadFile2ProtocolGuid,
+ &TempFilePath,
+ (VOID*)&LoadFile2,
+ DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Call LoadFile2 with the correct buffer size
+ //
+ while (CoreGrowBuffer (&Status, &ImageFileHandle->Source, ImageFileHandle->SourceSize)) {
+ Status = LoadFile2->LoadFile (
+ LoadFile2,
+ TempFilePath,
+ BootPolicy,
+ &ImageFileHandle->SourceSize,
+ ImageFileHandle->Source
+ );
+ //
+ // If success or other error happens, stop loop
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ break;
+ }
+ }
+
+ if (!EFI_ERROR (Status)) {
+ ImageFileHandle->FreeBuffer = TRUE;
+ goto Done;
+ }
+ }
+ }
+#endif
+
+ //
+ // Try LoadFile style
+ //
+ TempFilePath = *FilePath;
+ Status = CoreDevicePathToInterface (
+ &gEfiLoadFileProtocolGuid,
+ &TempFilePath,
+ (VOID*)&LoadFile,
+ DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Call LoadFile with the correct buffer size
+ //
+ while (CoreGrowBuffer (&Status, &ImageFileHandle->Source, ImageFileHandle->SourceSize)) {
+ Status = LoadFile->LoadFile (
+ LoadFile,
+ TempFilePath,
+ BootPolicy,
+ &ImageFileHandle->SourceSize,
+ ImageFileHandle->Source
+ );
+ //
+ // If success or other error happens, stop loop
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ break;
+ }
+ }
+
+ if (!EFI_ERROR (Status) || Status == EFI_ALREADY_STARTED) {
+ ImageFileHandle->FreeBuffer = TRUE;
+ goto Done;
+ }
+ }
+
+ //
+ // Nothing else to try
+ //
+ DEBUG ((EFI_D_LOAD|EFI_D_WARN, "CoreOpenImageFile: Device did not support a known load protocol\n"));
+ Status = EFI_NOT_FOUND;
+
+Done:
+
+ //
+ // If the file was not accessed, clean up
+ //
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ if (ImageFileHandle->FreeBuffer) {
+ //
+ // Free the source buffer if we allocated it
+ //
+ CoreFreePool (ImageFileHandle->Source);
+ }
+ }
+
+ return Status;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+CoreReadImageFile (
+ IN VOID *UserHandle,
+ IN UINTN Offset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Read image file (specified by UserHandle) into user specified buffer with specified offset
+ and length.
+
+Arguments:
+
+ UserHandle - Image file handle
+
+ Offset - Offset to the source file
+
+ ReadSize - For input, pointer of size to read;
+ For output, pointer of size actually read.
+
+ Buffer - Buffer to write into
+
+Returns:
+
+ EFI_SUCCESS - Successfully read the specified part of file into buffer.
+
+--*/
+{
+ UINTN EndPosition;
+ IMAGE_FILE_HANDLE *FHand;
+
+ FHand = (IMAGE_FILE_HANDLE *)UserHandle;
+ ASSERT (FHand->Signature == IMAGE_FILE_HANDLE_SIGNATURE);
+
+ //
+ // Move data from our local copy of the file
+ //
+ EndPosition = Offset + *ReadSize;
+ if (EndPosition > FHand->SourceSize) {
+ *ReadSize = (UINT32)(FHand->SourceSize - Offset);
+ }
+ if (Offset >= FHand->SourceSize) {
+ *ReadSize = 0;
+ }
+
+ EfiCommonLibCopyMem (Buffer, (CHAR8 *)FHand->Source + Offset, *ReadSize);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreDevicePathToInterface (
+ IN EFI_GUID *Protocol,
+ IN EFI_DEVICE_PATH_PROTOCOL **FilePath,
+ OUT VOID **Interface,
+ OUT EFI_HANDLE *Handle
+ )
+/*++
+
+Routine Description:
+
+ Search a handle to a device on a specified device path that supports a specified protocol,
+ interface of that protocol on that handle is another output.
+
+Arguments:
+
+ Protocol - The protocol to search for
+
+ FilePath - The specified device path
+
+ Interface - Interface of the protocol on the handle
+
+ Handle - The handle to the device on the specified device path that supports the protocol.
+
+Returns:
+
+ Status code.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = CoreLocateDevicePath (Protocol, FilePath, Handle);
+ if (!EFI_ERROR (Status)) {
+ Status = CoreHandleProtocol (*Handle, Protocol, Interface);
+ }
+ return Status;
+}
+
+
+VOID
+CoreDevicePathToFileName (
+ IN FILEPATH_DEVICE_PATH *FilePath,
+ OUT CHAR16 **String
+ )
+/*++
+
+Routine Description:
+
+ Transfer a device's full path a string.
+
+Arguments:
+
+ FilePath - Device path
+
+ String - The string represent the device's full path
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN StringSize;
+ FILEPATH_DEVICE_PATH *FilePathNode;
+ CHAR16 *Str;
+
+ *String = NULL;
+ StringSize = 0;
+ FilePathNode = FilePath;
+ while (!IsDevicePathEnd (&FilePathNode->Header)) {
+
+ //
+ // For filesystem access each node should be a filepath component
+ //
+ if (DevicePathType (&FilePathNode->Header) != MEDIA_DEVICE_PATH ||
+ DevicePathSubType (&FilePathNode->Header) != MEDIA_FILEPATH_DP) {
+
+ return;
+ }
+
+ StringSize += EfiStrLen (FilePathNode->PathName);
+
+ FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
+ }
+
+ *String = CoreAllocateBootServicesPool (StringSize);
+ if (*String == NULL) {
+ return;
+ }
+
+ FilePathNode = FilePath;
+ Str = *String;
+ while (!IsDevicePathEnd (&FilePathNode->Header)) {
+ EfiStrCat (Str, FilePathNode->PathName);
+ FilePathNode = (FILEPATH_DEVICE_PATH *) NextDevicePathNode (&FilePathNode->Header);
+ }
+}
+
+
+BOOLEAN
+CoreGrowBuffer (
+ IN OUT EFI_STATUS *Status,
+ IN OUT VOID **Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+
+ Helper function called as part of the code needed
+ to allocate the proper sized buffer for various
+ EFI interfaces.
+
+Arguments:
+
+ Status - Current status
+
+ Buffer - Current allocated buffer, or NULL
+
+ BufferSize - Current buffer size needed
+
+Returns:
+
+ TRUE - if the buffer was reallocated and the caller
+ should try the API again.
+
+ FALSE - buffer could not be allocated and the caller
+ should not try the API again.
+
+--*/
+{
+ BOOLEAN TryAgain;
+
+ TryAgain = FALSE;
+ //
+ // If this is an initial request, buffer will be null with a new buffer size
+ //
+ if (*Buffer == NULL) {
+ *Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (BufferSize == 0) {
+ return TRUE;
+ }
+
+ //
+ // If the status code is "buffer too small", resize the buffer
+ //
+
+ if (*Status == EFI_BUFFER_TOO_SMALL) {
+ if (*Buffer != NULL) {
+ CoreFreePool (*Buffer);
+ }
+
+ *Buffer = CoreAllocateBootServicesPool (BufferSize);
+ if (*Buffer != NULL) {
+ TryAgain = TRUE;
+ } else {
+ *Status = EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ //
+ // If there's an error, free the buffer
+ //
+ if ((!TryAgain) && (EFI_ERROR (*Status)) && (*Buffer)) {
+ CoreFreePool (*Buffer);
+ *Buffer = NULL;
+ }
+
+ return TryAgain;
+}
+
diff --git a/Core/CORE_DXE/InstallConfigurationTable.c b/Core/CORE_DXE/InstallConfigurationTable.c
new file mode 100644
index 0000000..8aea9bc
--- /dev/null
+++ b/Core/CORE_DXE/InstallConfigurationTable.c
@@ -0,0 +1,230 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ InstallConfigurationTable.c
+
+
+Abstract:
+
+ Tiano Miscellaneous Services InstallConfigurationTable service
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+#define CONFIG_TABLE_SIZE_INCREASED 0x10
+
+UINTN mSystemTableAllocateSize = 0;
+
+
+EFI_STATUS
+CoreGetConfigTable (
+ IN EFI_GUID *Guid,
+ OUT VOID **Table
+ )
+/*++
+
+Routine Description:
+
+ Find a config table by name in system table's ConfigurationTable.
+
+Arguments:
+
+ Guid - The table name to look for
+
+ Table - Pointer of the config table
+
+Returns:
+
+ EFI_NOT_FOUND - Could not find the table in system table's ConfigurationTable.
+
+ EFI_SUCCESS - Table successfully found.
+
+--*/
+{
+ UINTN Index;
+
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (EfiCompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ *Table = gST->ConfigurationTable[Index].VendorTable;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreInstallConfigurationTable (
+ IN EFI_GUID *Guid,
+ IN VOID *Table
+ )
+/*++
+
+Routine Description:
+
+ Boot Service called to add, modify, or remove a system configuration table from
+ the EFI System Table.
+
+Arguments:
+
+ Guid - Pointer to the GUID for the entry to add, update, or remove
+ Table - Pointer to the configuration table for the entry to add, update, or
+ remove, may be NULL.
+
+Returns:
+
+ EFI_SUCCESS Guid, Table pair added, updated, or removed.
+ EFI_INVALID_PARAMETER Input GUID not valid.
+ EFI_NOT_FOUND Attempted to delete non-existant entry
+ EFI_OUT_OF_RESOURCES Not enough memory available
+
+--*/
+{
+ UINTN Index;
+ EFI_CONFIGURATION_TABLE *EfiConfigurationTable;
+
+ //
+ // If Guid is NULL, then this operation cannot be performed
+ //
+ if (Guid == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ EfiConfigurationTable = gST->ConfigurationTable;
+
+ //
+ // Search all the table for an entry that matches Guid
+ //
+ for (Index = 0; Index < gST->NumberOfTableEntries; Index++) {
+ if (EfiCompareGuid (Guid, &(gST->ConfigurationTable[Index].VendorGuid))) {
+ break;
+ }
+ }
+
+ if (Index < gST->NumberOfTableEntries) {
+ //
+ // A match was found, so this is either a modify or a delete operation
+ //
+ if (Table != NULL) {
+ //
+ // If Table is not NULL, then this is a modify operation.
+ // Modify the table enty and return.
+ //
+ gST->ConfigurationTable[Index].VendorTable = Table;
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // Signal Configuration Table change
+ //
+ CoreNotifySignalList (Guid);
+#endif
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // A match was found and Table is NULL, so this is a delete operation.
+ //
+ gST->NumberOfTableEntries--;
+
+ //
+ // Copy over deleted entry
+ //
+ EfiCommonLibCopyMem (
+ &(EfiConfigurationTable[Index]),
+ &(gST->ConfigurationTable[Index + 1]),
+ (gST->NumberOfTableEntries - Index) * sizeof (EFI_CONFIGURATION_TABLE)
+ );
+
+ } else {
+
+ //
+ // No matching GUIDs were found, so this is an add operation.
+ //
+
+ if (Table == NULL) {
+ //
+ // If Table is NULL on an add operation, then return an error.
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Assume that Index == gST->NumberOfTableEntries
+ //
+ if ((Index * sizeof (EFI_CONFIGURATION_TABLE)) >= mSystemTableAllocateSize) {
+ //
+ // Allocate a table with one additional entry.
+ //
+ mSystemTableAllocateSize += (CONFIG_TABLE_SIZE_INCREASED * sizeof (EFI_CONFIGURATION_TABLE));
+ EfiConfigurationTable = CoreAllocateRuntimePool (mSystemTableAllocateSize);
+ if (EfiConfigurationTable == NULL) {
+ //
+ // If a new table could not be allocated, then return an error.
+ //
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (gST->ConfigurationTable != NULL) {
+ //
+ // Copy the old table to the new table.
+ //
+ EfiCommonLibCopyMem (
+ EfiConfigurationTable,
+ gST->ConfigurationTable,
+ Index * sizeof (EFI_CONFIGURATION_TABLE)
+ );
+
+ //
+ // Free Old Table
+ //
+ CoreFreePool (gST->ConfigurationTable);
+ }
+
+ //
+ // Update System Table
+ //
+ gST->ConfigurationTable = EfiConfigurationTable;
+ }
+
+ //
+ // Fill in the new entry
+ //
+ EfiConfigurationTable[Index].VendorGuid = *Guid;
+ EfiConfigurationTable[Index].VendorTable = Table;
+
+ //
+ // This is an add operation, so increment the number of table entries
+ //
+ gST->NumberOfTableEntries++;
+ }
+
+ //
+ // Fix up the CRC-32 in the EFI System Table
+ //
+ CalculateEfiHdrCrc (&gST->Hdr);
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // Signal Configuration Table change
+ //
+ CoreNotifySignalList (Guid);
+#endif
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/Library.c b/Core/CORE_DXE/Library.c
new file mode 100644
index 0000000..1f939ed
--- /dev/null
+++ b/Core/CORE_DXE/Library.c
@@ -0,0 +1,811 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Library.c
+
+Abstract:
+
+ DXE Core library services.
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "EfiCommonLib.h"
+
+DEBUG_CODE (
+ UINTN mErrorLevel = EFI_DBUG_MASK | EFI_D_LOAD;
+)
+
+EFI_DEVICE_HANDLE_EXTENDED_DATA mStatusCodeData = {
+ sizeof (EFI_STATUS_CODE_DATA),
+ sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - sizeof (EFI_STATUS_CODE_DATA),
+ EFI_STATUS_CODE_SPECIFIC_DATA_GUID,
+ NULL
+};
+
+VOID
+CoreReportProgressCodeSpecific (
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid,
+ with a handle as additional information.
+
+Arguments:
+
+ Value - Describes the class/subclass/operation of the hardware or software entity
+ that the Status Code relates to.
+
+ Handle - Additional information.
+
+Returns:
+
+ None
+
+--*/
+{
+ mStatusCodeData.DataHeader.Size = sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - sizeof (EFI_STATUS_CODE_DATA);
+ mStatusCodeData.Handle = Handle;
+
+ if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {
+ gStatusCode->ReportStatusCode (
+ EFI_PROGRESS_CODE,
+ Value,
+ 0,
+ &gEfiDxeServicesTableGuid,
+ (EFI_STATUS_CODE_DATA *) &mStatusCodeData
+ );
+ }
+}
+
+VOID
+CoreReportProgressCode (
+ IN EFI_STATUS_CODE_VALUE Value
+ )
+/*++
+
+Routine Description:
+
+ Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid.
+
+Arguments:
+
+ Value - Describes the class/subclass/operation of the hardware or software entity
+ that the Status Code relates to.
+
+Returns:
+
+ None
+
+--*/
+{
+ if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {
+ gStatusCode->ReportStatusCode (
+ EFI_PROGRESS_CODE,
+ Value,
+ 0,
+ &gEfiDxeServicesTableGuid,
+ NULL
+ );
+ }
+}
+
+
+VOID *
+CoreAllocateBootServicesPool (
+ IN UINTN AllocationSize
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+{
+ VOID *Memory;
+
+ CoreAllocatePool (EfiBootServicesData, AllocationSize, &Memory);
+ return Memory;
+}
+
+
+VOID *
+CoreAllocateZeroBootServicesPool (
+ IN UINTN AllocationSize
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+{
+ VOID *Memory;
+
+ Memory = CoreAllocateBootServicesPool (AllocationSize);
+ EfiCommonLibSetMem (Memory, (Memory == NULL) ? 0 : AllocationSize, 0);
+ return Memory;
+}
+
+
+VOID *
+CoreAllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+ Buffer - Specified buffer that will be copy to the allocated pool
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+{
+ VOID *Memory;
+
+ Memory = CoreAllocateBootServicesPool (AllocationSize);
+ EfiCommonLibCopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);
+
+ return Memory;
+}
+
+
+
+VOID *
+CoreAllocateRuntimePool (
+ IN UINTN AllocationSize
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+{
+ VOID *Memory;
+
+ CoreAllocatePool (EfiRuntimeServicesData, AllocationSize, &Memory);
+ return Memory;
+}
+
+VOID *
+CoreAllocateRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+ Buffer - Specified buffer that will be copy to the allocated pool
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+
+{
+ VOID *Memory;
+
+ Memory = CoreAllocateRuntimePool (AllocationSize);
+ EfiCommonLibCopyMem (Memory, Buffer, (Memory == NULL) ? 0 : AllocationSize);
+
+ return Memory;
+}
+
+
+
+//
+// Lock Stuff
+//
+
+
+
+EFI_STATUS
+CoreAcquireLockOrFail (
+ IN EFI_LOCK *Lock
+ )
+/*++
+
+Routine Description:
+
+ Initialize a basic mutual exclusion lock. Each lock
+ provides mutual exclusion access at it's task priority
+ level. Since there is no-premption (at any TPL) or
+ multiprocessor support, acquiring the lock only consists
+ of raising to the locks TPL.
+
+Arguments:
+
+ Lock - The EFI_LOCK structure to initialize
+
+Returns:
+
+ EFI_SUCCESS - Lock Owned.
+ EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned.
+
+--*/
+{
+ if (Lock->Lock != 0) {
+ //
+ // Lock is already owned, so bail out
+ //
+ return EFI_ACCESS_DENIED;
+ }
+
+ Lock->OwnerTpl = CoreRaiseTpl (Lock->Tpl);
+ Lock->Lock += 1;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+CoreAcquireLock (
+ IN EFI_LOCK *Lock
+ )
+/*++
+
+Routine Description:
+
+ Raising to the task priority level of the mutual exclusion
+ lock, and then acquires ownership of the lock.
+
+Arguments:
+
+ Lock - The lock to acquire
+
+Returns:
+
+ Lock owned
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = CoreAcquireLockOrFail (Lock);
+
+ //
+ // Lock was already locked.
+ //
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+VOID
+CoreReleaseLock (
+ IN EFI_LOCK *Lock
+ )
+/*++
+
+Routine Description:
+
+ Releases ownership of the mutual exclusion lock, and
+ restores the previous task priority level.
+
+Arguments:
+
+ Lock - The lock to release
+
+Returns:
+
+ Lock unowned
+
+--*/
+{
+ EFI_TPL Tpl;
+
+ Tpl = Lock->OwnerTpl;
+
+ ASSERT (Lock->Lock == 1);
+ Lock->Lock -= 1;
+
+ CoreRestoreTpl (Tpl);
+}
+
+
+UINTN
+CoreDevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+
+ Calculate the size of a whole device path.
+
+Arguments:
+
+ DevicePath - The pointer to the device path data.
+
+Returns:
+
+ Size of device path data structure..
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!EfiIsDevicePathEnd (DevicePath)) {
+ DevicePath = EfiNextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);
+}
+
+
+BOOLEAN
+CoreIsDevicePathMultiInstance (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Return TRUE is this is a multi instance device path.
+
+Arguments:
+ DevicePath - A pointer to a device path data structure.
+
+
+Returns:
+ TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi
+ instance.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!EfiIsDevicePathEnd (Node)) {
+ if (EfiIsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+ Node = EfiNextDevicePathNode (Node);
+ }
+ return FALSE;
+}
+
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+CoreDuplicateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Duplicate a new device path data structure from the old one.
+
+Arguments:
+ DevicePath - A pointer to a device path data structure.
+
+Returns:
+ A pointer to the new allocated device path data.
+ Caller must free the memory used by DevicePath if it is no longer needed.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN Size;
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ //
+ // Compute the size
+ //
+ Size = CoreDevicePathSize (DevicePath);
+
+ //
+ // Allocate space for duplicate device path
+ //
+ NewDevicePath = CoreAllocateCopyPool (Size, DevicePath);
+
+ return NewDevicePath;
+}
+
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+CoreAppendDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+/*++
+
+Routine Description:
+ Function is used to append a Src1 and Src2 together.
+
+Arguments:
+ Src1 - A pointer to a device path data structure.
+
+ Src2 - A pointer to a device path data structure.
+
+Returns:
+
+ A pointer to the new device path is returned.
+ NULL is returned if space for the new device path could not be allocated from pool.
+ It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.
+
+--*/
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;
+
+ if (Src1 == NULL && Src2 == NULL) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL
+ //
+ Size1 = CoreDevicePathSize (Src1);
+ Size2 = CoreDevicePathSize (Src2);
+ Size = Size1 + Size2 - sizeof(EFI_DEVICE_PATH_PROTOCOL);
+
+ NewDevicePath = CoreAllocateCopyPool (Size, Src1);
+ if (NewDevicePath != NULL) {
+
+ //
+ // Over write Src1 EndNode and do the copy
+ //
+ SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((CHAR8 *)NewDevicePath + (Size1 - sizeof(EFI_DEVICE_PATH_PROTOCOL)));
+ EfiCommonLibCopyMem (SecondDevicePath, Src2, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+
+
+EFI_EVENT
+CoreCreateProtocolNotifyEvent (
+ IN EFI_GUID *ProtocolGuid,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ OUT VOID **Registration,
+ IN BOOLEAN SignalFlag
+ )
+/*++
+
+Routine Description:
+
+ Create a protocol notification event and return it.
+
+Arguments:
+
+ ProtocolGuid - Protocol to register notification event on.
+
+ NotifyTpl - Maximum TPL to signal the NotifyFunction.
+
+ NotifyFuncition - EFI notification routine.
+
+ NotifyContext - Context passed into Event when it is created.
+
+ Registration - Registration key returned from RegisterProtocolNotify().
+
+ SignalFlag - Boolean value to decide whether kick the event after register or not.
+
+Returns:
+
+ The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
+ is added to the system.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ //
+ // Create the event
+ //
+
+ Status = CoreCreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ NotifyTpl,
+ NotifyFunction,
+ NotifyContext,
+ &Event
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Register for protocol notifactions on this event
+ //
+
+ Status = CoreRegisterProtocolNotify (
+ ProtocolGuid,
+ Event,
+ Registration
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ if (SignalFlag) {
+ //
+ // Kick the event so we will perform an initial pass of
+ // current installed drivers
+ //
+ CoreSignalEvent (Event);
+ }
+
+ return Event;
+}
+
+VOID
+EFIAPI
+CoreInitializeFwVolDevicepathNode (
+ IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode,
+ IN EFI_GUID *NameGuid
+ )
+/*++
+Routine Description:
+
+ Initialize a Firmware Volume (FV) Media Device Path node.
+
+Arguments:
+
+ FvDevicePathNode - Pointer to a FV device path node to initialize
+ NameGuid - FV file name to use in FvDevicePathNode
+
+--*/
+{
+ FvDevicePathNode->Header.Type = MEDIA_DEVICE_PATH;
+ FvDevicePathNode->Header.SubType = MEDIA_FV_FILEPATH_DP;
+ SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
+
+ EfiCommonLibCopyMem (&FvDevicePathNode->NameGuid, NameGuid, sizeof(EFI_GUID));
+}
+
+EFI_GUID *
+EFIAPI
+CoreGetNameGuidFromFwVolDevicePathNode (
+ IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode
+ )
+/*++
+
+Routine Description:
+
+ Check to see if the Firmware Volume (FV) Media Device Path is valid.
+
+Arguments:
+
+ FvDevicePathNode - Pointer to FV device path to check
+
+Returns:
+
+ NULL - FvDevicePathNode is not valid.
+ Other - FvDevicePathNode is valid and pointer to NameGuid was returned.
+
+--*/
+{
+ if (DevicePathType (&FvDevicePathNode->Header) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (&FvDevicePathNode->Header) == MEDIA_FV_FILEPATH_DP) {
+ return &FvDevicePathNode->NameGuid;
+ }
+
+ return NULL;
+}
+
+DEBUG_CODE (
+//*** AMI PORTING BEGIN ***//
+/* Defined in AmiDxeInit.c
+VOID
+EfiDebugAssert (
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ )
+*/
+/*++
+
+Routine Description:
+
+ Worker function for ASSERT(). If Error Logging hub is loaded, log DEBUG
+ information; If not, do BREAKPOINT().
+
+ We use UINT64 buffers due to IPF alignment concerns.
+
+Arguments:
+
+ FileName - File name of failing routine.
+
+ LineNumber - Line number of failing ASSERT().
+
+ Description - Descritption, usally the assertion string.
+
+Returns:
+
+ None
+
+--*/
+/*{
+ UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+
+ EfiDebugAssertWorker (FileName, LineNumber,Description, sizeof (Buffer), Buffer);
+
+ //
+ // Check if our pointers are valid. Can't assert because that would recurse.
+ //
+ if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {
+ gStatusCode->ReportStatusCode (
+ (EFI_ERROR_CODE | EFI_ERROR_UNRECOVERED),
+ (EFI_SOFTWARE_DXE_CORE | EFI_SW_EC_ILLEGAL_SOFTWARE_STATE),
+ 0,
+ &gEfiDxeServicesTableGuid,
+ (EFI_STATUS_CODE_DATA *)Buffer
+ );
+ }
+
+ //
+ // Put break point in module that contained the error.
+ //
+ EFI_BREAKPOINT ();
+}*/
+
+/* Defined in AmiDxeInit.c
+VOID
+EfiDebugVPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ IN VA_LIST Marker
+ )*/
+/*++
+
+Routine Description:
+
+ Worker function for DEBUG(). If Error Logging hub is loaded, DEBUG
+ information will be logged. If Error Logging hub is not loaded, do nothing.
+
+ We use UINT64 buffers due to IPF alignment concerns.
+
+Arguments:
+
+ ErrorLevel - If error level is set do the debug print.
+
+ Format - String to use for the print, followed by Print arguments.
+
+ Marker - VarArgs
+
+Returns:
+
+ None
+
+--*/
+/*{
+ UINT64 Buffer[EFI_STATUS_CODE_DATA_MAX_SIZE];
+
+ if (!(mErrorLevel & ErrorLevel)) {
+ return;
+ }
+
+ EfiDebugVPrintWorker (ErrorLevel, Format, Marker, sizeof (Buffer), Buffer);
+
+ //
+ // Check if our pointers are valid. Can't assert because that would recurse.
+ //
+ if ((gStatusCode != NULL) && (gStatusCode->ReportStatusCode != NULL) ) {
+ gStatusCode->ReportStatusCode (
+ EFI_DEBUG_CODE,
+ (EFI_SOFTWARE_DXE_CORE | EFI_DC_UNSPECIFIED),
+ (UINT32) ErrorLevel,
+ &gEfiDxeServicesTableGuid,
+ (EFI_STATUS_CODE_DATA *)Buffer
+ );
+ }
+}*/
+//*** AMI PORTING END *****//
+
+
+VOID
+EfiDebugPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Wrapper for EfiDebugVPrint ()
+
+Arguments:
+
+ ErrorLevel - If error level is set do the debug print.
+
+ Format - String to use for the print, followed by Print arguments.
+
+ ... - Print arguments.
+
+Returns:
+
+ None
+
+--*/
+{
+ VA_LIST Marker;
+
+ VA_START (Marker, Format);
+ EfiDebugVPrint (ErrorLevel, Format, Marker);
+ VA_END (Marker);
+}
+)
diff --git a/Core/CORE_DXE/Library.h b/Core/CORE_DXE/Library.h
new file mode 100644
index 0000000..8bac924
--- /dev/null
+++ b/Core/CORE_DXE/Library.h
@@ -0,0 +1,531 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Library.h
+
+Abstract:
+
+Revision History
+
+--*/
+
+#ifndef _DXE_LIBRARY_H_
+#define _DXE_LIBRARY_H_
+
+typedef struct {
+ EFI_TPL Tpl;
+ EFI_TPL OwnerTpl;
+ UINTN Lock;
+} EFI_LOCK;
+
+
+//
+// Macro to initialize the state of a lock when a lock variable is declared
+//
+#define EFI_INITIALIZE_LOCK_VARIABLE(Tpl) {Tpl,0,0}
+
+VOID
+CoreReportProgressCode (
+ IN EFI_STATUS_CODE_VALUE Value
+ )
+/*++
+
+Routine Description:
+
+ Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid.
+
+Arguments:
+
+ Value - Describes the class/subclass/operation of the hardware or software entity
+ that the Status Code relates to.
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CoreReportProgressCodeSpecific (
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ Report status code of type EFI_PROGRESS_CODE by caller ID gEfiDxeServicesTableGuid,
+ with a handle as additional information.
+
+Arguments:
+
+ Value - Describes the class/subclass/operation of the hardware or software entity
+ that the Status Code relates to.
+
+ Handle - Additional information.
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CoreAcquireLock (
+ IN EFI_LOCK *Lock
+ )
+/*++
+
+Routine Description:
+
+ Raising to the task priority level of the mutual exclusion
+ lock, and then acquires ownership of the lock.
+
+Arguments:
+
+ Lock - The lock to acquire
+
+Returns:
+
+ Lock owned
+
+--*/
+;
+
+EFI_STATUS
+CoreAcquireLockOrFail (
+ IN EFI_LOCK *Lock
+ )
+/*++
+
+Routine Description:
+
+ Initialize a basic mutual exclusion lock. Each lock
+ provides mutual exclusion access at it's task priority
+ level. Since there is no-premption (at any TPL) or
+ multiprocessor support, acquiring the lock only consists
+ of raising to the locks TPL.
+
+Arguments:
+
+ Lock - The EFI_LOCK structure to initialize
+
+Returns:
+
+ EFI_SUCCESS - Lock Owned.
+ EFI_ACCESS_DENIED - Reentrant Lock Acquisition, Lock not Owned.
+
+--*/
+;
+
+VOID
+CoreReleaseLock (
+ IN EFI_LOCK *Lock
+ )
+/*++
+
+Routine Description:
+
+ Releases ownership of the mutual exclusion lock, and
+ restores the previous task priority level.
+
+Arguments:
+
+ Lock - The lock to release
+
+Returns:
+
+ Lock unowned
+
+--*/
+;
+
+//
+// Device Path functions
+//
+
+UINTN
+CoreDevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+
+ Calculate the size of a whole device path.
+
+Arguments:
+
+ DevicePath - The pointer to the device path data.
+
+Returns:
+
+ Size of device path data structure..
+
+--*/
+;
+
+BOOLEAN
+CoreIsDevicePathMultiInstance (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Return TRUE is this is a multi instance device path.
+
+Arguments:
+ DevicePath - A pointer to a device path data structure.
+
+
+Returns:
+ TRUE - If DevicePath is multi instance. FALSE - If DevicePath is not multi
+ instance.
+
+--*/
+;
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+CoreDuplicateDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+Routine Description:
+ Duplicate a new device path data structure from the old one.
+
+Arguments:
+ DevicePath - A pointer to a device path data structure.
+
+Returns:
+ A pointer to the new allocated device path data.
+ Caller must free the memory used by DevicePath if it is no longer needed.
+
+--*/
+;
+
+EFI_DEVICE_PATH_PROTOCOL *
+CoreAppendDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN EFI_DEVICE_PATH_PROTOCOL *Node
+ )
+/*++
+
+Routine Description:
+ Function is used to append a Src1 and Src2 together.
+
+Arguments:
+ Src1 - A pointer to a device path data structure.
+
+ Node - A pointer to a device path data structure.
+
+Returns:
+
+ A pointer to the new device path is returned.
+ NULL is returned if space for the new device path could not be allocated from pool.
+ It is up to the caller to free the memory used by Src1 and Src2 if they are no longer needed.
+
+--*/
+;
+
+VOID *
+CoreAllocateBootServicesPool (
+ IN UINTN AllocationSize
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of type EfiBootServicesData, the size is specified with AllocationSize.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+;
+
+VOID *
+CoreAllocateZeroBootServicesPool (
+ IN UINTN AllocationSize
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of type EfiBootServicesData and zero it, the size is specified with AllocationSize.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+;
+
+EFI_STATUS
+CoreGetConfigTable (
+ IN EFI_GUID *Guid,
+ IN OUT VOID **Table
+ )
+/*++
+
+Routine Description:
+
+ Find a config table by name in system table's ConfigurationTable.
+
+Arguments:
+
+ Guid - The table name to look for
+
+ Table - Pointer of the config table
+
+Returns:
+
+ EFI_NOT_FOUND - Could not find the table in system table's ConfigurationTable.
+
+ EFI_SUCCESS - Table successfully found.
+
+--*/
+;
+
+VOID *
+CoreAllocateRuntimeCopyPool (
+ IN UINTN AllocationSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of specified size with EfiRuntimeServicesData type, and copy specified buffer to this pool.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+ Buffer - Specified buffer that will be copy to the allocated pool
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+;
+
+VOID *
+CoreAllocateRuntimePool (
+ IN UINTN AllocationSize
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of type EfiRuntimeServicesData, the size is specified with AllocationSize.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+;
+
+VOID *
+CoreAllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of specified size with EfiBootServicesData type, and copy specified buffer to this pool.
+
+Arguments:
+
+ AllocationSize - Size to allocate.
+
+ Buffer - Specified buffer that will be copy to the allocated pool
+
+Returns:
+
+ Pointer of the allocated pool.
+
+--*/
+;
+
+VOID
+EfiDebugAssert (
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ )
+/*++
+
+Routine Description:
+
+ Worker function for ASSERT(). If Error Logging hub is loaded, log DEBUG
+ information; If not, do BREAKPOINT().
+
+Arguments:
+
+ FileName - File name of failing routine.
+
+ LineNumber - Line number of failing ASSERT().
+
+ Description - Descritption, usally the assertion string.
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EfiDebugPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Wrapper for EfiDebugVPrint ()
+
+Arguments:
+
+ ErrorLevel - If error level is set do the debug print.
+
+ Format - String to use for the print, followed by Print arguments.
+
+ ... - Print arguments.
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_EVENT
+CoreCreateProtocolNotifyEvent (
+ IN EFI_GUID *ProtocolGuid,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ OUT VOID **Registration,
+ IN BOOLEAN SignalFlag
+ )
+/*++
+
+Routine Description:
+
+ Create a protocol notification event and return it.
+
+Arguments:
+
+ ProtocolGuid - Protocol to register notification event on.
+
+ NotifyTpl - Maximum TPL to signal the NotifyFunction.
+
+ NotifyFuncition - EFI notification routine.
+
+ NotifyContext - Context passed into Event when it is created.
+
+ Registration - Registration key returned from RegisterProtocolNotify().
+
+ SignalFlag - Boolean value to decide whether kick the event after register or not.
+
+Returns:
+
+ The EFI_EVENT that has been registered to be signaled when a ProtocolGuid
+ is added to the system.
+
+--*/
+;
+
+VOID
+EFIAPI
+CoreInitializeFwVolDevicepathNode (
+ IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode,
+ IN EFI_GUID *NameGuid
+ )
+/*++
+
+Routine Description:
+
+ Initialize a Firmware Volume (FV) Media Device Path node.
+
+Arguments:
+
+ FvDevicePathNode - Pointer to a FV device path node to initialize
+ NameGuid - FV file name to use in FvDevicePathNode
+
+--*/
+;
+
+EFI_GUID *
+EFIAPI
+CoreGetNameGuidFromFwVolDevicePathNode (
+ IN MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode
+ )
+/*++
+
+Routine Description:
+
+ Check to see if the Firmware Volume (FV) Media Device Path is valid.
+
+Arguments:
+
+ FvDevicePathNode Pointer to FV device path to check
+
+Returns:
+
+ NULL - FvDevicePathNode is not valid.
+ Other - FvDevicePathNode is valid and pointer to NameGuid was returned.
+
+--*/
+;
+
+//*** AMI PORTING BEGIN ***//
+//PI 1.1 ++
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+EFI_STATUS
+GetNextFirmwareVolume2Hob (
+ IN OUT VOID **HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length,
+ OUT EFI_GUID *FileName
+ )
+;
+#endif
+//PI 1.1 --
+//*** AMI PORTING END *****//
+
+#endif
diff --git a/Core/CORE_DXE/LinkedList.h b/Core/CORE_DXE/LinkedList.h
new file mode 100644
index 0000000..b9611b9
--- /dev/null
+++ b/Core/CORE_DXE/LinkedList.h
@@ -0,0 +1 @@
+#include<AmiLib.h>
diff --git a/Core/CORE_DXE/Notify.c b/Core/CORE_DXE/Notify.c
new file mode 100644
index 0000000..ea8e0fd
--- /dev/null
+++ b/Core/CORE_DXE/Notify.c
@@ -0,0 +1,344 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ notify.c
+
+Abstract:
+
+ EFI notify infrastructure
+
+
+
+Revision History
+
+--*/
+
+#include "hand.h"
+
+
+
+VOID
+CoreNotifyProtocolEntry (
+ IN PROTOCOL_ENTRY *ProtEntry
+ )
+/*++
+
+Routine Description:
+
+ Signal event for every protocol in protocol entry.
+
+Arguments:
+
+ ProtEntry - Protocol entry
+
+Returns:
+
+--*/
+{
+ PROTOCOL_NOTIFY *ProtNotify;
+ EFI_LIST_ENTRY *Link;
+
+ ASSERT_LOCKED (&gProtocolDatabaseLock);
+//*** AMI PORTING BEGIN ***//
+//Bug fix:
+// CoreSignalEvent may lead to immediate call of the event notification function,
+// which may call CloseEvent, which invalidates current ProtNotify.
+// As a result, Link=Link->ForwardLink after the loop body ends up
+// with an invalid pointer (Link is part of the invalid ProtNotify).
+// The code is updated to get pointer to the next element before CoreSignalEvent.
+// for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
+ for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify;) {
+ ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
+ Link=Link->ForwardLink;
+//*** AMI PORTING END *****//
+ CoreSignalEvent (ProtNotify->Event);
+ }
+}
+
+
+PROTOCOL_INTERFACE *
+CoreRemoveInterfaceFromProtocol (
+ IN IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Removes Protocol from the protocol list (but not the handle list).
+
+Arguments:
+
+ Handle - The handle to remove protocol on.
+
+ Protocol - GUID of the protocol to be moved
+
+ Interface - The interface of the protocol
+
+Returns:
+
+ Protocol Entry
+
+--*/
+{
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_NOTIFY *ProtNotify;
+ PROTOCOL_ENTRY *ProtEntry;
+ EFI_LIST_ENTRY *Link;
+
+ ASSERT_LOCKED (&gProtocolDatabaseLock);
+
+ Prot = CoreFindProtocolInterface (Handle, Protocol, Interface);
+ if (Prot != NULL) {
+
+ ProtEntry = Prot->Protocol;
+
+ //
+ // If there's a protocol notify location pointing to this entry, back it up one
+ //
+
+ for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
+ ProtNotify = CR(Link, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
+
+ if (ProtNotify->Position == &Prot->ByProtocol) {
+ ProtNotify->Position = Prot->ByProtocol.BackLink;
+ }
+ }
+
+ //
+ // Remove the protocol interface entry
+ //
+
+ RemoveEntryList (&Prot->ByProtocol);
+ }
+
+ return Prot;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreRegisterProtocolNotify (
+ IN EFI_GUID *Protocol,
+ IN EFI_EVENT Event,
+ OUT VOID **Registration
+ )
+/*++
+
+Routine Description:
+
+ Add a new protocol notification record for the request protocol.
+
+Arguments:
+
+ Protocol - The requested protocol to add the notify registration
+
+ Event - The event to signal
+
+ Registration - Returns the registration record
+
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_SUCCESS - Successfully returned the registration record that has been added
+
+--*/
+{
+ PROTOCOL_ENTRY *ProtEntry;
+ PROTOCOL_NOTIFY *ProtNotify;
+ EFI_STATUS Status;
+
+ if ((Protocol == NULL) || (Event == NULL) || (Registration == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireProtocolLock ();
+
+ ProtNotify = NULL;
+
+ //
+ // Get the protocol entry to add the notification too
+ //
+
+ ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);
+ if (ProtEntry != NULL) {
+
+ //
+ // Allocate a new notification record
+ //
+
+ ProtNotify = CoreAllocateBootServicesPool (sizeof(PROTOCOL_NOTIFY));
+
+ if (ProtNotify != NULL) {
+
+ ProtNotify->Signature = PROTOCOL_NOTIFY_SIGNATURE;
+ ProtNotify->Protocol = ProtEntry;
+ ProtNotify->Event = Event;
+ //
+ // start at the begining
+ //
+ ProtNotify->Position = &ProtEntry->Protocols;
+
+ InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);
+ }
+ }
+
+ CoreReleaseProtocolLock ();
+
+ //
+ // Done. If we have a protocol notify entry, then return it.
+ // Otherwise, we must have run out of resources trying to add one
+ //
+
+ Status = EFI_OUT_OF_RESOURCES;
+ if (ProtNotify != NULL) {
+ *Registration = ProtNotify;
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreReinstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *OldInterface,
+ IN VOID *NewInterface
+ )
+/*++
+
+Routine Description:
+
+ Reinstall a protocol interface on a device handle. The OldInterface for Protocol is replaced by the NewInterface.
+
+Arguments:
+
+ UserHandle - Handle on which the interface is to be reinstalled
+ Protocol - The numeric ID of the interface
+ OldInterface - A pointer to the old interface
+ NewInterface - A pointer to the new interface
+
+
+Returns:
+
+ Status code.
+
+ On EFI_SUCCESS The protocol interface was installed
+ On EFI_NOT_FOUND The OldInterface on the handle was not found
+ On EFI_INVALID_PARAMETER One of the parameters has an invalid value
+
+--*/
+{
+ EFI_STATUS Status;
+ IHANDLE *Handle;
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_ENTRY *ProtEntry;
+
+ Status = CoreValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Handle = (IHANDLE *) UserHandle;
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
+ //
+ Prot = CoreFindProtocolInterface (UserHandle, Protocol, OldInterface);
+ if (Prot == NULL) {
+ CoreReleaseProtocolLock ();
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Attempt to disconnect all drivers that are using the protocol interface that is about to be reinstalled
+ //
+ Status = CoreDisconnectControllersUsingProtocolInterface (
+ UserHandle,
+ Prot
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // One or more drivers refused to release, so return the error
+ //
+ CoreReleaseProtocolLock ();
+ return Status;
+ }
+
+ //
+ // Remove the protocol interface from the protocol
+ //
+ Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, OldInterface);
+
+ if (Prot == NULL) {
+ CoreReleaseProtocolLock ();
+ return EFI_NOT_FOUND;
+ }
+
+ ProtEntry = Prot->Protocol;
+
+ //
+ // Update the interface on the protocol
+ //
+ Prot->Interface = NewInterface;
+
+ //
+ // Add this protocol interface to the tail of the
+ // protocol entry
+ //
+ InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
+
+ //
+ // Update the Key to show that the handle has been created/modified
+ //
+ gHandleDatabaseKey++;
+ Handle->Key = gHandleDatabaseKey;
+
+ //
+ // Release the lock and connect all drivers to UserHandle
+ //
+ CoreReleaseProtocolLock ();
+ Status = CoreConnectController (
+ UserHandle,
+ NULL,
+ NULL,
+ TRUE
+ );
+ CoreAcquireProtocolLock ();
+
+ //
+ // Notify the notification list for this protocol
+ //
+ CoreNotifyProtocolEntry (ProtEntry);
+
+ CoreReleaseProtocolLock ();
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/Page.c b/Core/CORE_DXE/Page.c
new file mode 100644
index 0000000..523bf02
--- /dev/null
+++ b/Core/CORE_DXE/Page.c
@@ -0,0 +1,1685 @@
+/*++
+
+Copyright (c) 2007 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ page.c
+
+Abstract:
+
+ EFI Memory page management
+
+
+Revision History
+
+--*/
+
+#include "imem.h"
+
+#define EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
+
+//
+// Entry for tracking the memory regions for each memory type to help coalesce like memory types
+//
+typedef struct {
+ EFI_PHYSICAL_ADDRESS BaseAddress; // Base address of the coalesce bin if NumberOfPages is not 0, or 0 otherwise
+ EFI_PHYSICAL_ADDRESS MaximumAddress; // Top address of the coalesce bin if NumberOfPages is not 0, or the top address below all bin ranges
+ UINT64 CurrentNumberOfPages; // CurrentNumberOfPages allocated for this memory type
+ UINT64 NumberOfPages; // Number of pages specified in gMemoryTypeInformation
+ UINTN InformationIndex; // Index into gMemoryTypeInformation
+ BOOLEAN Special; // If this type of coalesce bin needs to be filled in memory map
+ BOOLEAN Runtime; // If this type is runtime available
+} EFI_MEMORY_TYPE_STAISTICS;
+
+//
+// MemoryMap - The current memory map
+//
+UINTN mMemoryMapKey = 0;
+
+//
+// mMapStack - space to use as temp storage to build new map descriptors
+// mMapDepth - depth of new descriptor stack
+//
+
+#define MAX_MAP_DEPTH 6
+UINTN mMapDepth = 0;
+MEMORY_MAP mMapStack[MAX_MAP_DEPTH];
+UINTN mFreeMapStack = 0;
+//
+// This list maintain the free memory map list
+//
+EFI_LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList);
+BOOLEAN mMemoryTypeInformationInitialized = FALSE;
+
+EFI_MEMORY_TYPE_STAISTICS mMemoryTypeStatistics[EfiMaxMemoryType + 1] = {
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiReservedMemoryType
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderCode
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiLoaderData
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesCode
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiBootServicesData
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesCode
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiRuntimeServicesData
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiConventionalMemory
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiUnusableMemory
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIReclaimMemory
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, FALSE }, // EfiACPIMemoryNVS
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIO
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE }, // EfiMemoryMappedIOPortSpace
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, TRUE, TRUE }, // EfiPalCode
+ { 0, EFI_MAX_ADDRESS, 0, 0, EfiMaxMemoryType, FALSE, FALSE } // EfiMaxMemoryType
+};
+
+EFI_PHYSICAL_ADDRESS mDefaultMaximumAddress = EFI_MAX_ADDRESS;
+
+EFI_MEMORY_TYPE_INFORMATION gMemoryTypeInformation[EfiMaxMemoryType + 1] = {
+ { EfiReservedMemoryType, 0 },
+ { EfiLoaderCode, 0 },
+ { EfiLoaderData, 0 },
+ { EfiBootServicesCode, 0 },
+ { EfiBootServicesData, 0 },
+ { EfiRuntimeServicesCode, 0 },
+ { EfiRuntimeServicesData, 0 },
+ { EfiConventionalMemory, 0 },
+ { EfiUnusableMemory, 0 },
+ { EfiACPIReclaimMemory, 0 },
+ { EfiACPIMemoryNVS, 0 },
+ { EfiMemoryMappedIO, 0 },
+ { EfiMemoryMappedIOPortSpace, 0 },
+ { EfiPalCode, 0 },
+ { EfiMaxMemoryType, 0 }
+};
+
+//
+// Internal prototypes
+//
+VOID
+PromoteMemoryResource (
+ VOID
+);
+
+STATIC
+VOID
+CoreAddRange (
+ IN EFI_MEMORY_TYPE Type,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN EFI_PHYSICAL_ADDRESS End,
+ IN UINT64 Attribute
+ );
+
+STATIC
+VOID
+CoreFreeMemoryMapStack (
+ VOID
+ );
+
+STATIC
+EFI_STATUS
+CoreConvertPages (
+ IN UINT64 Start,
+ IN UINT64 NumberOfPages,
+ IN EFI_MEMORY_TYPE NewType
+ );
+
+STATIC
+VOID
+RemoveMemoryMapEntry (
+ MEMORY_MAP *Entry
+ );
+
+
+MEMORY_MAP *
+AllocateMemoryMapEntry (
+ );
+
+VOID
+CoreAcquireMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Enter critical section by gaining lock on gMemoryLock
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreAcquireLock (&gMemoryLock);
+}
+
+
+VOID
+CoreReleaseMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Exit critical section by releasing lock on gMemoryLock
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreReleaseLock (&gMemoryLock);
+}
+
+VOID
+PromoteMemoryResource (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Find untested but initialized memory regions in GCD map and convert them to be DXE allocatable.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_GCD_MAP_ENTRY *Entry;
+
+ DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "Promote the memory resource\n"));
+
+ CoreAcquireGcdMemoryLock ();
+
+ Link = mGcdMemorySpaceMap.ForwardLink;
+ while (Link != &mGcdMemorySpaceMap) {
+
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+
+ if (Entry->GcdMemoryType == EfiGcdMemoryTypeReserved &&
+ Entry->EndAddress < EFI_MAX_ADDRESS &&
+ (Entry->Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==
+ (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)) {
+ //
+ // Update the GCD map
+ //
+ Entry->GcdMemoryType = EfiGcdMemoryTypeSystemMemory;
+ Entry->Capabilities |= EFI_MEMORY_TESTED;
+ Entry->ImageHandle = gDxeCoreImageHandle;
+ Entry->DeviceHandle = NULL;
+
+ //
+ // Add to allocable system memory resource
+ //
+
+ CoreAddRange (
+ EfiConventionalMemory,
+ Entry->BaseAddress,
+ Entry->EndAddress,
+ Entry->Capabilities & ~(EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED | EFI_MEMORY_RUNTIME)
+ );
+ mMemoryTypeStatistics[EfiConventionalMemory].CurrentNumberOfPages += RShiftU64 ((Entry->EndAddress - Entry->BaseAddress + 1), EFI_PAGE_SHIFT);
+ CoreFreeMemoryMapStack ();
+
+ }
+
+ Link = Link->ForwardLink;
+ }
+
+ CoreReleaseGcdMemoryLock ();
+
+ return;
+}
+
+VOID
+CoreAddMemoryDescriptor (
+ IN EFI_MEMORY_TYPE Type,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 NumberOfPages,
+ IN UINT64 Attribute
+ )
+/*++
+
+Routine Description:
+
+ Called to initialize the memory map and add descriptors to
+ the current descriptor list.
+
+ N.B. The first descriptor that is added must be general usable
+ memory as the addition allocates heap.
+
+Arguments:
+
+ Type - The type of memory to add
+
+ Start - The starting address in the memory range
+ Must be page aligned
+
+ NumberOfPages - The number of pages in the range
+
+ Attribute - Attributes of the memory to add
+
+Returns:
+
+ None. The range is added to the memory map
+
+--*/
+{
+ EFI_PHYSICAL_ADDRESS End;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN FreeIndex;
+
+ if ((Start & EFI_PAGE_MASK) != 0) {
+ return;
+ }
+
+ if (Type >= EfiMaxMemoryType && Type <= 0x7fffffff) {
+ return;
+ }
+
+ CoreAcquireMemoryLock ();
+ End = Start + LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT) - 1;
+ CoreAddRange (Type, Start, End, Attribute);
+ mMemoryTypeStatistics[Type].CurrentNumberOfPages += NumberOfPages;
+ CoreFreeMemoryMapStack ();
+ CoreReleaseMemoryLock ();
+
+ //
+ // Check to see if the statistics for the different memory types have already been established
+ //
+ if (mMemoryTypeInformationInitialized) {
+ return;
+ }
+
+ //
+ // Loop through each memory type in the order specified by the gMemoryTypeInformation[] array
+ //
+ for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
+ //
+ // Make sure the memory type in the gMemoryTypeInformation[] array is valid
+ //
+ Type = gMemoryTypeInformation[Index].Type;
+ if (Type < 0 || Type > EfiMaxMemoryType) {
+ continue;
+ }
+
+ if (gMemoryTypeInformation[Index].NumberOfPages != 0) {
+ //
+ // Allocate pages for the current memory type from the top of available memory
+ //
+ Status = CoreAllocatePages (
+ AllocateAnyPages,
+ Type,
+ gMemoryTypeInformation[Index].NumberOfPages,
+ &mMemoryTypeStatistics[Type].BaseAddress
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // If an error occurs allocating the pages for the current memory type, then
+ // free all the pages allocates for the previous memory types and return. This
+ // operation with be retied when/if more memory is added to the system
+ //
+ for (FreeIndex = 0; FreeIndex < Index; FreeIndex++) {
+ //
+ // Make sure the memory type in the gMemoryTypeInformation[] array is valid
+ //
+ Type = gMemoryTypeInformation[FreeIndex].Type;
+ if (Type < 0 || Type > EfiMaxMemoryType) {
+ continue;
+ }
+
+ if (gMemoryTypeInformation[FreeIndex].NumberOfPages != 0) {
+ CoreFreePages (
+ mMemoryTypeStatistics[Type].BaseAddress,
+ gMemoryTypeInformation[FreeIndex].NumberOfPages
+ );
+ mMemoryTypeStatistics[Type].BaseAddress = 0;
+ mMemoryTypeStatistics[Type].MaximumAddress = EFI_MAX_ADDRESS;
+ }
+ }
+ return;
+ }
+
+ //
+ // Compute the address at the top of the current statistics
+ //
+ mMemoryTypeStatistics[Type].MaximumAddress =
+ mMemoryTypeStatistics[Type].BaseAddress +
+ LShiftU64 (gMemoryTypeInformation[Index].NumberOfPages, EFI_PAGE_SHIFT) - 1;
+
+ //
+ // If the current base address is the lowest address so far, then update the default
+ // maximum address
+ //
+ if (mMemoryTypeStatistics[Type].BaseAddress < mDefaultMaximumAddress) {
+ mDefaultMaximumAddress = mMemoryTypeStatistics[Type].BaseAddress - 1;
+ }
+ }
+ }
+
+ //
+ // There was enough system memory for all the the memory types were allocated. So,
+ // those memory areas can be freed for future allocations, and all future memory
+ // allocations can occur within their respective bins
+ //
+ for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
+ //
+ // Make sure the memory type in the gMemoryTypeInformation[] array is valid
+ //
+ Type = gMemoryTypeInformation[Index].Type;
+ if (Type < 0 || Type > EfiMaxMemoryType) {
+ continue;
+ }
+
+ if (gMemoryTypeInformation[Index].NumberOfPages != 0) {
+ CoreFreePages (
+ mMemoryTypeStatistics[Type].BaseAddress,
+ gMemoryTypeInformation[Index].NumberOfPages
+ );
+ mMemoryTypeStatistics[Type].NumberOfPages = gMemoryTypeInformation[Index].NumberOfPages;
+ gMemoryTypeInformation[Index].NumberOfPages = 0;
+ }
+ }
+
+ //
+ // If the number of pages reserved for a memory type is 0, then all allocations for that type
+ // should be in the default range.
+ //
+ for (Type = 0; Type < EfiMaxMemoryType; Type++) {
+ for (Index = 0; gMemoryTypeInformation[Index].Type != EfiMaxMemoryType; Index++) {
+ if (Type == (EFI_MEMORY_TYPE)gMemoryTypeInformation[Index].Type) {
+ mMemoryTypeStatistics[Type].InformationIndex = Index;
+ }
+ }
+ if (mMemoryTypeStatistics[Type].MaximumAddress == EFI_MAX_ADDRESS) {
+ mMemoryTypeStatistics[Type].MaximumAddress = mDefaultMaximumAddress;
+ }
+ }
+
+ mMemoryTypeInformationInitialized = TRUE;
+}
+
+
+STATIC
+VOID
+CoreAddRange (
+ IN EFI_MEMORY_TYPE Type,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN EFI_PHYSICAL_ADDRESS End,
+ IN UINT64 Attribute
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Adds a ranges to the memory map.
+ The range must not already exist in the map.
+
+Arguments:
+
+ Type - The type of memory range to add
+
+ Start - The starting address in the memory range
+ Must be paged aligned
+
+ End - The last address in the range
+ Must be the last byte of a page
+
+ Attribute - The attributes of the memory range to add
+
+Returns:
+
+ None. The range is added to the memory map
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+
+ ASSERT ((Start & EFI_PAGE_MASK) == 0);
+ ASSERT (End > Start) ;
+
+ ASSERT_LOCKED (&gMemoryLock);
+
+ DEBUG ((EFI_D_PAGE, "AddRange: %lx-%lx to %d\n", Start, End, (UINTN)Type));
+
+ //
+ // Memory map being altered
+ //
+
+ mMemoryMapKey += 1;
+
+ //
+ // Look for adjoining memory descriptor
+ //
+
+ // Two memory descriptors can only be merged if they have the same Type
+ // and the same Attribute
+ //
+
+ Link = gMemoryMap.ForwardLink;
+ while (Link != &gMemoryMap) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ Link = Link->ForwardLink;
+
+ if (Entry->Type != Type) {
+ continue;
+ }
+
+ if (Entry->Attribute != Attribute) {
+ continue;
+ }
+
+ if (Entry->End + 1 == Start) {
+
+ Start = Entry->Start;
+ RemoveMemoryMapEntry (Entry);
+
+ } else if (Entry->Start == End + 1) {
+
+ End = Entry->End;
+ RemoveMemoryMapEntry (Entry);
+ }
+ }
+
+ //
+ // Add descriptor
+ //
+
+ mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;
+ mMapStack[mMapDepth].FromPages = FALSE;
+ mMapStack[mMapDepth].Type = Type;
+ mMapStack[mMapDepth].Start = Start;
+ mMapStack[mMapDepth].End = End;
+ mMapStack[mMapDepth].VirtualStart = 0;
+ mMapStack[mMapDepth].Attribute = Attribute;
+ InsertTailList (&gMemoryMap, &mMapStack[mMapDepth].Link);
+
+ mMapDepth += 1;
+ ASSERT (mMapDepth < MAX_MAP_DEPTH);
+ return ;
+}
+
+STATIC
+VOID
+CoreFreeMemoryMapStack (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Moves any memory descriptors that are on the
+ temporary descriptor stack to heap.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ MEMORY_MAP *Entry;
+ MEMORY_MAP *Entry2;
+ EFI_LIST_ENTRY *Link2;
+
+ ASSERT_LOCKED (&gMemoryLock);
+
+ //
+ // If already freeing the map stack, then return
+ //
+ if (mFreeMapStack) {
+ return ;
+ }
+
+ //
+ // Move the temporary memory descriptor stack into pool
+ //
+ mFreeMapStack += 1;
+
+ while (mMapDepth) {
+ //
+ // Deque an memory map entry from mFreeMemoryMapEntryList
+ //
+ Entry = AllocateMemoryMapEntry ();
+
+ ASSERT (Entry);
+
+ //
+ // Update to proper entry
+ //
+ mMapDepth -= 1;
+
+ if (mMapStack[mMapDepth].Link.ForwardLink != NULL) {
+
+ //
+ // Move this entry to general memory
+ //
+ RemoveEntryList (&mMapStack[mMapDepth].Link);
+ mMapStack[mMapDepth].Link.ForwardLink = NULL;
+
+ *Entry = mMapStack[mMapDepth];
+ Entry->FromPages = TRUE;
+
+ //
+ // Find insertion location
+ //
+ for (Link2 = gMemoryMap.ForwardLink; Link2 != &gMemoryMap; Link2 = Link2->ForwardLink) {
+ Entry2 = CR (Link2, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ if (Entry2->FromPages && Entry2->Start > Entry->Start) {
+ break;
+ }
+ }
+
+ InsertTailList (Link2, &Entry->Link);
+
+ } else {
+ //
+ // This item of mMapStack[mMapDepth] has already been dequeued from gMemoryMap list,
+ // so here no need to move it to memory.
+ //
+ InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);
+ }
+ }
+
+ mFreeMapStack -= 1;
+}
+
+STATIC
+VOID
+RemoveMemoryMapEntry (
+ MEMORY_MAP *Entry
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Removes a descriptor entry.
+
+Arguments:
+
+ Entry - The entry to remove
+
+Returns:
+
+ None
+
+--*/
+{
+ RemoveEntryList (&Entry->Link);
+ Entry->Link.ForwardLink = NULL;
+
+ if (Entry->FromPages) {
+ //
+ // Insert the free memory map descriptor to the end of mFreeMemoryMapEntryList
+ //
+ InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link);
+ }
+}
+
+MEMORY_MAP *
+AllocateMemoryMapEntry (
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList.
+ If the list is emtry, then allocate a new page to refuel the list.
+ Please Note this algorithm to allocate the memory map descriptor has a property
+ that the memory allocated for memory entries always grows, and will never really be freed
+ For example, if the current boot uses 2000 memory map entries at the maximum point, but
+ ends up with only 50 at the time the OS is booted, then the memory associated with the 1950
+ memory map entries is still allocated from EfiBootServicesMemory.
+
+Arguments:
+
+ NONE
+
+Returns:
+
+ The Memory map descriptor dequed from the mFreeMemoryMapEntryList
+
+--*/
+{
+ MEMORY_MAP* FreeDescriptorEntries;
+ MEMORY_MAP* Entry;
+ UINTN Index;
+
+ if (IsListEmpty (&mFreeMemoryMapEntryList)) {
+ //
+ // The list is empty, to allocate one page to refuel the list
+ //
+ FreeDescriptorEntries = CoreAllocatePoolPages (EfiBootServicesData, EFI_SIZE_TO_PAGES(DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);
+ if(FreeDescriptorEntries != NULL) {
+ //
+ // Enque the free memmory map entries into the list
+ //
+ for (Index = 0; Index< DEFAULT_PAGE_ALLOCATION / sizeof(MEMORY_MAP); Index++) {
+ FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE;
+ InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link);
+ }
+ } else {
+ return NULL;
+ }
+ }
+ //
+ // dequeue the first descriptor from the list
+ //
+ Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ RemoveEntryList (&Entry->Link);
+
+ return Entry;
+}
+
+STATIC
+EFI_STATUS
+CoreConvertPages (
+ IN UINT64 Start,
+ IN UINT64 NumberOfPages,
+ IN EFI_MEMORY_TYPE NewType
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Converts a memory range to the specified type.
+ The range must exist in the memory map.
+
+Arguments:
+
+ Start - The first address of the range
+ Must be page aligned
+
+ NumberOfPages - The number of pages to convert
+
+ NewType - The new type for the memory range
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_NOT_FOUND - Could not find a descriptor cover the specified range
+ or convertion not allowed.
+
+ EFI_SUCCESS - Successfully converts the memory range to the specified type.
+
+--*/
+{
+
+ UINT64 NumberOfBytes;
+ UINT64 End;
+ UINT64 RangeEnd;
+ UINT64 Attribute;
+ EFI_LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+ UINT64 NumberOfRangePages;
+
+ Entry = NULL;
+ NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);
+ End = Start + NumberOfBytes - 1;
+
+ ASSERT (NumberOfPages);
+ ASSERT ((Start & EFI_PAGE_MASK) == 0);
+ ASSERT (End > Start) ;
+ ASSERT_LOCKED (&gMemoryLock);
+
+ if (NumberOfPages == 0 || (Start & EFI_PAGE_MASK ) || (Start > (Start + NumberOfBytes))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert the entire range
+ //
+
+ while (Start < End) {
+
+ //
+ // Find the entry that the covers the range
+ //
+ for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+
+ if (Entry->Start <= Start && Entry->End > Start) {
+ break;
+ }
+ }
+
+ if (Link == &gMemoryMap) {
+ DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "ConvertPages: failed to find range %lx - %lx\n", Start, End));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Convert range to the end, or to the end of the descriptor
+ // if that's all we've got
+ //
+ RangeEnd = End;
+ if (Entry->End < End) {
+ RangeEnd = Entry->End;
+ }
+
+ DEBUG ((EFI_D_PAGE, "ConvertRange: %lx-%lx to %d\n", Start, RangeEnd, (UINTN)NewType));
+
+ //
+ // Debug code - verify conversion is allowed
+ //
+ if (!(NewType == EfiConventionalMemory ? 1 : 0) ^ (Entry->Type == EfiConventionalMemory ? 1 : 0)) {
+ DEBUG ((EFI_D_ERROR , "ConvertPages: Incompatible memory types\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Update counters for the number of pages allocated to each memory type
+ //
+ NumberOfRangePages = RShiftU64 (RangeEnd - Start + 1, EFI_PAGE_SHIFT);
+ if (Entry->Type >= 0 && Entry->Type < EfiMaxMemoryType) {
+ ASSERT (NumberOfRangePages <= mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages);
+ mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages -= NumberOfRangePages;
+ gMemoryTypeInformation[mMemoryTypeStatistics[Entry->Type].InformationIndex].NumberOfPages = (UINT32)mMemoryTypeStatistics[Entry->Type].CurrentNumberOfPages;
+ }
+
+ if (NewType >= 0 && NewType < EfiMaxMemoryType) {
+ mMemoryTypeStatistics[NewType].CurrentNumberOfPages += NumberOfRangePages;
+ gMemoryTypeInformation[mMemoryTypeStatistics[NewType].InformationIndex].NumberOfPages = (UINT32)mMemoryTypeStatistics[NewType].CurrentNumberOfPages;
+ }
+
+ //
+ // Pull range out of descriptor
+ //
+ if (Entry->Start == Start) {
+
+ //
+ // Clip start
+ //
+ Entry->Start = RangeEnd + 1;
+
+ } else if (Entry->End == RangeEnd) {
+
+ //
+ // Clip end
+ //
+ Entry->End = Start - 1;
+
+ } else {
+
+ //
+ // Pull it out of the center, clip current
+ //
+
+ //
+ // Add a new one
+ //
+ mMapStack[mMapDepth].Signature = MEMORY_MAP_SIGNATURE;
+ mMapStack[mMapDepth].FromPages = FALSE;
+ mMapStack[mMapDepth].Type = Entry->Type;
+ mMapStack[mMapDepth].Start = RangeEnd+1;
+ mMapStack[mMapDepth].End = Entry->End;
+
+ //
+ // Inherit Attribute from the Memory Descriptor that is being clipped
+ //
+ mMapStack[mMapDepth].Attribute = Entry->Attribute;
+
+ Entry->End = Start - 1;
+ ASSERT (Entry->Start < Entry->End);
+
+ Entry = &mMapStack[mMapDepth];
+ InsertTailList (&gMemoryMap, &Entry->Link);
+
+ mMapDepth += 1;
+ ASSERT (mMapDepth < MAX_MAP_DEPTH);
+ }
+
+ //
+ // The new range inherits the same Attribute as the Entry
+ //it is being cut out of
+ //
+ Attribute = Entry->Attribute;
+
+ //
+ // If the descriptor is empty, then remove it from the map
+ //
+ if (Entry->Start == Entry->End + 1) {
+ RemoveMemoryMapEntry (Entry);
+ Entry = NULL;
+ }
+
+ //
+ // Add our new range in
+ //
+ CoreAddRange (NewType, Start, RangeEnd, Attribute);
+
+ //
+ // Move any map descriptor stack to general pool
+ //
+ CoreFreeMemoryMapStack ();
+
+ //
+ // Bump the starting address, and convert the next range
+ //
+ Start = RangeEnd + 1;
+ }
+
+ //
+ // Converted the whole range, done
+ //
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+UINT64
+CoreFindFreePagesI (
+ IN UINT64 MaxAddress,
+ IN UINT64 NumberOfPages,
+ IN EFI_MEMORY_TYPE NewType,
+ IN UINTN Alignment
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Finds a consecutive free page range below
+ the requested address.
+
+Arguments:
+
+ MaxAddress - The address that the range must be below
+
+ NumberOfPages - Number of pages needed
+
+ NewType - The type of memory the range is going to be turned into
+
+ Alignment - Bits to align with
+
+Returns:
+
+ The base address of the range, or 0 if the range was not found
+
+--*/
+{
+ UINT64 NumberOfBytes;
+ UINT64 Target;
+ UINT64 DescStart;
+ UINT64 DescEnd;
+ UINT64 DescNumberOfBytes;
+ EFI_LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+
+ if ((MaxAddress < EFI_PAGE_MASK) ||(NumberOfPages == 0)) {
+ return 0;
+ }
+
+ if ((MaxAddress & EFI_PAGE_MASK) != EFI_PAGE_MASK) {
+
+ //
+ // If MaxAddress is not aligned to the end of a page
+ //
+
+ //
+ // Change MaxAddress to be 1 page lower
+ //
+ MaxAddress -= (EFI_PAGE_MASK + 1);
+
+ //
+ // Set MaxAddress to a page boundary
+ //
+ MaxAddress &= ~EFI_PAGE_MASK;
+
+ //
+ // Set MaxAddress to end of the page
+ //
+ MaxAddress |= EFI_PAGE_MASK;
+ }
+
+ NumberOfBytes = LShiftU64 (NumberOfPages, EFI_PAGE_SHIFT);
+ Target = 0;
+
+ for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+
+ //
+ // If it's not a free entry, don't bother with it
+ //
+ if (Entry->Type != EfiConventionalMemory) {
+ continue;
+ }
+
+ DescStart = Entry->Start;
+ DescEnd = Entry->End;
+
+ //
+ // If desc is past max allowed address, skip it
+ //
+ if (DescStart >= MaxAddress) {
+ continue;
+ }
+
+ //
+ // If desc ends past max allowed address, clip the end
+ //
+ if (DescEnd >= MaxAddress) {
+ DescEnd = MaxAddress;
+ }
+
+ DescEnd = ((DescEnd + 1) & (~(Alignment - 1))) - 1;
+
+ //
+ // Compute the number of bytes we can used from this
+ // descriptor, and see it's enough to satisfy the request
+ //
+ DescNumberOfBytes = DescEnd - DescStart + 1;
+
+ if (DescNumberOfBytes >= NumberOfBytes) {
+
+ //
+ // If this is the best match so far remember it
+ //
+ if (DescEnd > Target) {
+ Target = DescEnd;
+ }
+ }
+ }
+
+ //
+ // If this is a grow down, adjust target to be the allocation base
+ //
+ Target -= NumberOfBytes - 1;
+
+ //
+ // If we didn't find a match, return 0
+ //
+ if ((Target & EFI_PAGE_MASK) != 0) {
+ return 0;
+ }
+
+ return Target;
+}
+
+STATIC
+UINT64
+FindFreePages (
+ IN UINT64 MaxAddress,
+ IN UINT64 NoPages,
+ IN EFI_MEMORY_TYPE NewType,
+ IN UINTN Alignment
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Finds a consecutive free page range below
+ the requested address
+
+Arguments:
+
+ MaxAddress - The address that the range must be below
+
+ NoPages - Number of pages needed
+
+ NewType - The type of memory the range is going to be turned into
+
+ Alignment - Bits to align with
+
+Returns:
+
+ The base address of the range, or 0 if the range was not found.
+
+--*/
+{
+ UINT64 NewMaxAddress;
+ UINT64 Start;
+
+ NewMaxAddress = MaxAddress;
+
+ if (NewType >= 0 && NewType < EfiMaxMemoryType && NewMaxAddress >= mMemoryTypeStatistics[NewType].MaximumAddress) {
+ NewMaxAddress = mMemoryTypeStatistics[NewType].MaximumAddress;
+ } else {
+ if (NewMaxAddress > mDefaultMaximumAddress) {
+ NewMaxAddress = mDefaultMaximumAddress;
+ }
+ }
+
+ Start = CoreFindFreePagesI (NewMaxAddress, NoPages, NewType, Alignment);
+ if (!Start) {
+ Start = CoreFindFreePagesI (MaxAddress, NoPages, NewType, Alignment);
+ if (!Start) {
+ //
+ // Here means there may be no enough memory to use, so try to go through
+ // all the memory descript to promote the untested memory directly
+ //
+ PromoteMemoryResource ();
+
+ //
+ // Allocate memory again after the memory resource re-arranged
+ //
+ Start = CoreFindFreePagesI (MaxAddress, NoPages, NewType, Alignment);
+ }
+ }
+
+ return Start;
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreAllocatePages (
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Allocates pages from the memory map.
+
+Arguments:
+
+ Type - The type of allocation to perform
+
+ MemoryType - The type of memory to turn the allocated pages into
+
+ NumberOfPages - The number of pages to allocate
+
+ Memory - A pointer to receive the base allocated memory address
+
+Returns:
+
+ Status. On success, Memory is filled in with the base address allocated
+
+ EFI_INVALID_PARAMETER - Parameters violate checking rules defined in spec.
+
+ EFI_NOT_FOUND - Could not allocate pages match the requirement.
+
+ EFI_OUT_OF_RESOURCES - No enough pages to allocate.
+
+ EFI_SUCCESS - Pages successfully allocated.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT64 Start;
+ UINT64 MaxAddress;
+ UINTN Alignment;
+
+ if (Type < AllocateAnyPages || Type >= (UINTN) MaxAllocateType) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((MemoryType >= EfiMaxMemoryType && MemoryType <= 0x7fffffff) ||
+ MemoryType == EfiConventionalMemory) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;
+
+ if (MemoryType == EfiACPIReclaimMemory ||
+ MemoryType == EfiACPIMemoryNVS ||
+ MemoryType == EfiRuntimeServicesCode ||
+ MemoryType == EfiRuntimeServicesData) {
+
+ Alignment = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Bug fix(EIP 82751): original code was accessing *Memory without
+// checking for a NULL pointer.
+// This caused problems with the WHCK AllocatePages Compliance Test
+ if (Memory == NULL) return EFI_INVALID_PARAMETER;
+//*** AMI PORTING END *****//
+
+ if (Type == AllocateAddress) {
+ if ((*Memory & (Alignment - 1)) != 0) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1;
+ NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1);
+
+ //
+ // If this is for below a particular address, then
+ //
+ Start = *Memory;
+
+ //
+ // The max address is the max natively addressable address for the processor
+ //
+ MaxAddress = EFI_MAX_ADDRESS;
+
+ if (Type == AllocateMaxAddress) {
+ MaxAddress = Start;
+ }
+
+ CoreAcquireMemoryLock ();
+
+ //
+ // If not a specific address, then find an address to allocate
+ //
+ if (Type != AllocateAddress) {
+ Start = FindFreePages (MaxAddress, NumberOfPages, MemoryType, Alignment);
+ if (Start == 0) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+ }
+
+ //
+ // Convert pages from FreeMemory to the requested type
+ //
+ Status = CoreConvertPages (Start, NumberOfPages, MemoryType);
+
+Done:
+ CoreReleaseMemoryLock ();
+
+ if (!EFI_ERROR (Status)) {
+ *Memory = Start;
+ }
+
+ return Status;
+}
+
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreFreePages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+/*++
+
+Routine Description:
+
+ Frees previous allocated pages.
+
+Arguments:
+
+ Memory - Base address of memory being freed
+
+ NumberOfPages - The number of pages to free
+
+Returns:
+
+ EFI_NOT_FOUND - Could not find the entry that covers the range
+
+ EFI_INVALID_PARAMETER - Address not aligned
+
+ EFI_SUCCESS -Pages successfully freed.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+ UINTN Alignment;
+
+ //
+ // Free the range
+ //
+ CoreAcquireMemoryLock ();
+
+ //
+ // Find the entry that the covers the range
+ //
+ Entry = NULL;
+ for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+ Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ if (Entry->Start <= Memory && Entry->End > Memory) {
+ break;
+ }
+ }
+ if (Link == &gMemoryMap) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ Alignment = EFI_DEFAULT_PAGE_ALLOCATION_ALIGNMENT;
+
+ if (Entry->Type == EfiACPIReclaimMemory ||
+ Entry->Type == EfiACPIMemoryNVS ||
+ Entry->Type == EfiRuntimeServicesCode ||
+ Entry->Type == EfiRuntimeServicesData) {
+
+ Alignment = EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT;
+
+ }
+
+ if ((Memory & (Alignment - 1)) != 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ NumberOfPages += EFI_SIZE_TO_PAGES (Alignment) - 1;
+ NumberOfPages &= ~(EFI_SIZE_TO_PAGES (Alignment) - 1);
+
+ Status = CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Destroy the contents
+ //
+ if (Memory < EFI_MAX_ADDRESS) {
+ DEBUG_SET_MEMORY ((VOID *)(UINTN)Memory, NumberOfPages << EFI_PAGE_SHIFT);
+ }
+
+ Done:
+ CoreReleaseMemoryLock ();
+
+ return Status;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreGetMemoryMap (
+ IN OUT UINTN *MemoryMapSize,
+ IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap,
+ OUT UINTN *MapKey,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *DescriptorVersion
+ )
+/*++
+
+Routine Description:
+
+ This function returns a copy of the current memory map. The map is an array of
+ memory descriptors, each of which describes a contiguous block of memory.
+
+Arguments:
+
+ MemoryMapSize - A pointer to the size, in bytes, of the MemoryMap buffer. On
+ input, this is the size of the buffer allocated by the caller.
+ On output, it is the size of the buffer returned by the firmware
+ if the buffer was large enough, or the size of the buffer needed
+ to contain the map if the buffer was too small.
+ MemoryMap - A pointer to the buffer in which firmware places the current memory map.
+ MapKey - A pointer to the location in which firmware returns the key for the
+ current memory map.
+ DescriptorSize - A pointer to the location in which firmware returns the size, in
+ bytes, of an individual EFI_MEMORY_DESCRIPTOR.
+ DescriptorVersion - A pointer to the location in which firmware returns the version
+ number associated with the EFI_MEMORY_DESCRIPTOR.
+
+Returns:
+
+ EFI_SUCCESS - The memory map was returned in the MemoryMap buffer.
+ EFI_BUFFER_TOO_SMALL - The MemoryMap buffer was too small. The current buffer size
+ needed to hold the memory map is returned in MemoryMapSize.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN BufferSize;
+ UINTN NumberOfRuntimeEntries;
+ EFI_LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+ EFI_GCD_MAP_ENTRY *GcdMapEntry;
+ EFI_MEMORY_TYPE Type;
+
+ //
+ // Make sure the parameters are valid
+ //
+ if (MemoryMapSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireGcdMemoryLock ();
+
+ //
+ // Count the number of Reserved and MMIO entries that are marked for runtime use
+ //
+ NumberOfRuntimeEntries = 0;
+ for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {
+ GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||
+ (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
+ if ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
+ NumberOfRuntimeEntries++;
+ }
+ }
+ }
+
+ Size = sizeof (EFI_MEMORY_DESCRIPTOR);
+
+ //
+ // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will
+ // prevent people from having pointer math bugs in their code.
+ // now you have to use *DescriptorSize to make things work.
+ //
+ Size += sizeof(UINT64) - (Size % sizeof (UINT64));
+
+ if (DescriptorSize != NULL) {
+ *DescriptorSize = Size;
+ }
+
+ if (DescriptorVersion != NULL) {
+ *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION;
+ }
+
+ CoreAcquireMemoryLock ();
+
+ //
+ // Compute the buffer size needed to fit the entire map
+ //
+ BufferSize = Size * NumberOfRuntimeEntries;
+ for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+ BufferSize += Size;
+ }
+
+ if (*MemoryMapSize < BufferSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Done;
+ }
+
+ if (MemoryMap == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ //
+ // Build the map
+ //
+ EfiCommonLibZeroMem (MemoryMap, BufferSize);
+ for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+ Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ ASSERT (Entry->VirtualStart == 0);
+
+ //
+ // Convert internal map into an EFI_MEMORY_DESCRIPTOR
+ //
+ MemoryMap->Type = Entry->Type;
+ MemoryMap->PhysicalStart = Entry->Start;
+ MemoryMap->VirtualStart = Entry->VirtualStart;
+ MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT);
+ //
+ // If the memory type is EfiConventionalMemory, then determine if the range is part of a
+ // memory type bin and needs to be converted to the same memory type as the rest of the
+ // memory type bin in order to minimize EFI Memory Map changes across reboots. This
+ // improves the chances for a successful S4 resume in the presence of minor page allocation
+ // differences across reboots.
+ //
+ if (MemoryMap->Type == EfiConventionalMemory) {
+ for (Type = (EFI_MEMORY_TYPE) 0; Type < EfiMaxMemoryType; Type++) {
+ if (mMemoryTypeStatistics[Type].Special &&
+ mMemoryTypeStatistics[Type].NumberOfPages > 0 &&
+ Entry->Start >= mMemoryTypeStatistics[Type].BaseAddress &&
+ Entry->End <= mMemoryTypeStatistics[Type].MaximumAddress ) {
+ MemoryMap->Type = Type;
+ }
+ }
+ }
+ MemoryMap->Attribute = Entry->Attribute;
+ if (mMemoryTypeStatistics[MemoryMap->Type].Runtime) {
+ MemoryMap->Attribute |= EFI_MEMORY_RUNTIME;
+ }
+
+ MemoryMap = NextMemoryDescriptor (MemoryMap, Size);
+ }
+
+ for (Link = mGcdMemorySpaceMap.ForwardLink; Link != &mGcdMemorySpaceMap; Link = Link->ForwardLink) {
+ GcdMapEntry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ if ((GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) ||
+ (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo)) {
+ if ((GcdMapEntry->Attributes & EFI_MEMORY_RUNTIME) == EFI_MEMORY_RUNTIME) {
+
+ MemoryMap->PhysicalStart = GcdMapEntry->BaseAddress;
+ MemoryMap->VirtualStart = 0;
+ MemoryMap->NumberOfPages = RShiftU64 ((GcdMapEntry->EndAddress - GcdMapEntry->BaseAddress + 1), EFI_PAGE_SHIFT);
+ MemoryMap->Attribute = GcdMapEntry->Attributes & ~EFI_MEMORY_PORT_IO;
+
+ if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeReserved) {
+ MemoryMap->Type = EfiReservedMemoryType;
+//*** AMI PORTING BEGIN ***//
+/*
+Enhancement (EIP 83128): Windows 8 compatibility test suite reports an error
+on memory map entries of type EfiReserverdMemoryType with the EFI_MEMORY_RUNTIME attribute set.
+This is a workaround.
+
+In a pure UEFI world there should be no such entries:
+If the region requires virtual address mapping (this is implied by the EFI_MEMORY_RUNTIME attribute),
+it should be of EfiRuntimeServicesData or EfiRuntimeServicesCode type.
+If no virtual address mapping is required, there should be no EFI_MEMORY_RUNTIME attribute.
+
+Our reality is more complicated than a pure UEFI world.
+Most of the EfiReserverdMemoryType entries are imported from the GCD memory map.
+The PI specification does not define how to reflect GCD memory maps entries
+in the UEFI memory map, which makes it up to implementation.
+The EDK implementation ignores all non-runtime GCD entries.
+So, the only way to report GCD entry to OS (which only deals with UEFI memory map),
+is to set a runtime attribute.
+
+Our workaround is to reset EFI_MEMORY_RUNTIME attribute during import of the memory map entry from GCD to UEFI.
+
+A real solution is update the PI specification to define clear rules on how to
+reflect GCD memory maps entries in the UEFI memory map.
+AMI initiated the process with the PI working group, but it may take a while.
+*/
+ MemoryMap->Attribute &= ~EFI_MEMORY_RUNTIME;
+//*** AMI PORTING END *****//
+ } else if (GcdMapEntry->GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
+ if ((GcdMapEntry->Attributes & EFI_MEMORY_PORT_IO) == EFI_MEMORY_PORT_IO) {
+ MemoryMap->Type = EfiMemoryMappedIOPortSpace;
+ } else {
+ MemoryMap->Type = EfiMemoryMappedIO;
+ }
+ }
+
+ MemoryMap = NextMemoryDescriptor (MemoryMap, Size);
+ }
+ }
+ }
+
+ Status = EFI_SUCCESS;
+
+Done:
+
+ CoreReleaseMemoryLock ();
+
+ CoreReleaseGcdMemoryLock ();
+
+ //
+ // Update the map key finally
+ //
+ if (MapKey != NULL) {
+ *MapKey = mMemoryMapKey;
+ }
+
+ *MemoryMapSize = BufferSize;
+
+ return Status;
+}
+
+VOID *
+CoreAllocatePoolPages (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN NumberOfPages,
+ IN UINTN Alignment
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Used by the pool functions to allocate pages
+ to back pool allocation requests.
+
+Arguments:
+
+ PoolType - The type of memory for the new pool pages
+
+ NumberOfPages - No of pages to allocate
+
+ Alignment - Bits to align.
+
+Returns:
+
+ The allocated memory, or NULL
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT64 Start;
+
+ //
+ // Find the pages to convert
+ //
+ Start = FindFreePages (EFI_MAX_ADDRESS, NumberOfPages, PoolType, Alignment);
+
+ //
+ // Convert it to boot services data
+ //
+ if (Start == 0) {
+ DEBUG ((EFI_D_ERROR | EFI_D_PAGE, "AllocatePoolPages: failed to allocate %d pages\n", NumberOfPages));
+ } else {
+ Status = CoreConvertPages (Start, NumberOfPages, PoolType);
+ }
+
+ return (VOID *)(UINTN)Start;
+}
+
+VOID
+CoreFreePoolPages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Frees pool pages allocated via AllocatePoolPages ()
+
+Arguments:
+
+ Memory - The base address to free
+
+ NumberOfPages - The number of pages to free
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreConvertPages (Memory, NumberOfPages, EfiConventionalMemory);
+}
+
+
+EFI_STATUS
+CoreTerminateMemoryMap (
+ IN UINTN MapKey
+ )
+/*++
+
+Routine Description:
+
+ Make sure the memory map is following all the construction rules,
+ it is the last time to check memory map error before exit boot services.
+
+Arguments:
+
+ MapKey - Memory map key
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Memory map not consistent with construction rules.
+
+ EFI_SUCCESS - Valid memory map.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *Link;
+ MEMORY_MAP *Entry;
+
+ Status = EFI_SUCCESS;
+
+ CoreAcquireMemoryLock ();
+
+ if (MapKey == mMemoryMapKey) {
+
+ //
+ // Make sure the memory map is following all the construction rules
+ // This is the last chance we will be able to display any messages on
+ // the console devices.
+ //
+
+ for (Link = gMemoryMap.ForwardLink; Link != &gMemoryMap; Link = Link->ForwardLink) {
+ Entry = CR(Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE);
+ if (Entry->Attribute & EFI_MEMORY_RUNTIME) {
+ if (Entry->Type == EfiACPIReclaimMemory || Entry->Type == EfiACPIMemoryNVS) {
+ DEBUG((EFI_D_ERROR, "ExitBootServices: ACPI memory entry has RUNTIME attribute set.\n"));
+ CoreReleaseMemoryLock ();
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Entry->Start & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) {
+ DEBUG((EFI_D_ERROR, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));
+ CoreReleaseMemoryLock ();
+ return EFI_INVALID_PARAMETER;
+ }
+ if ((Entry->End + 1) & (EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT - 1)) {
+ DEBUG((EFI_D_ERROR, "ExitBootServices: A RUNTIME memory entry is not on a proper alignment.\n"));
+ CoreReleaseMemoryLock ();
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ //
+ // The map key they gave us matches what we expect. Fall through and
+ // return success. In an ideal world we would clear out all of
+ // EfiBootServicesCode and EfiBootServicesData. However this function
+ // is not the last one called by ExitBootServices(), so we have to
+ // preserve the memory contents.
+ //
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ CoreReleaseMemoryLock ();
+
+ return Status;
+}
+
+
+
+
+
+
+
+
diff --git a/Core/CORE_DXE/Partition/ElTorito.c b/Core/CORE_DXE/Partition/ElTorito.c
new file mode 100644
index 0000000..749ba74
--- /dev/null
+++ b/Core/CORE_DXE/Partition/ElTorito.c
@@ -0,0 +1,470 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.c 21 8/28/12 3:14p Pats $
+//
+// $Revision: 21 $
+//
+// $Date: 8/28/12 3:14p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.c $
+//
+// 21 8/28/12 3:14p Pats
+// [TAG] EIP99287
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Problem booting certain HDD emulation ElTorito CD/DVD's.
+// [RootCause] If the CD has ElTorito and ISO9660 partitions, the block
+// sizeread will be the ISO9660 block size, but the ElTorito partition
+// needs the HDD block size
+// [Solution] Set block size to HDD block size if HDD emulation detected.
+// [Files] Eltorito.c
+//
+// 20 5/10/12 5:54a Rameshr
+// [TAG] EIP88924
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] UEFI 2.3.1 SCT block io read test fail
+// [RootCause] If the CD has two Boot image , two blockio will be
+// installed by Partition driver. But the second blockIo , LastBlock value
+// is wrong
+// [Solution] 2nd logical blockIO LastBlock size calculation corrected.
+// [Files] Eltorito.c
+//
+// 19 9/27/11 7:43p Yul
+// [TAG] EIP69053
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System cannot boot to WINPE from CD/DVD.
+// [RootCause] Blocksize change
+// [Solution] Blocksize change
+// [Files] EIOorito.c
+//
+// 18 5/10/11 11:21a Pats
+// [TAG] - EIP 57859
+// [Category]- BUG FIX
+// [Severity]- Normal
+// [Symptom] - On EFI shell, though CD media is recognized as a Block
+// device, is not recognized as a File system.
+// [RootCause] - Blocksize change from EIP 30719.
+// [Solution] - Removed change from EIP 30719.
+// [Files] - ElTorito.c
+//
+// 17 4/16/10 4:24p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 16 10/20/09 5:02p Felixp
+// Check for a block I/O device errors is added in
+// ElToritoCreateChildHandle function.
+//
+// 14 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 13 4/23/09 11:54a Oleksiyy
+// Memory free error fix
+//
+// 12 2/19/09 1:02p Artems
+// EIP 19052 Minor improvement to support CD burned with Windows Explorer
+//
+// 11 1/16/09 3:02p Felixp
+// New Feature:
+// CD-ROM handling code is updated to create additional logical instance
+// of the Bock I/O protocol
+// based on primary volume descriptor of the CR-ROM.
+// The instance is used by the ISO 9660 file systems driver
+// (separate eModule. Not part of the Core) to implement file system
+// protocol.
+// The new parittion driver funcionality is only enabled when ISO 9660
+// file systems driver
+// ($/Source/Modules/FsIso9660) is included into the project.
+//
+// 10 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 9 4/24/07 5:31p Robert
+// Updated Headers to compile with CHM creation
+//
+// 8 3/22/07 5:39p Robert
+// Updated Files for coding standard
+//
+// 7 8/24/06 12:34p Felixp
+// x64 support (fixes for warnings/errors)
+//
+// 5 5/19/06 10:47p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 3 5/05/05 5:07p Robert
+// When reading the data for the Volume Descriptor. There was no check
+// for the Status of the Read Blocks call. If this returned an error then it
+// was continuing on. Now it exits when an error is found
+//
+// 2 2/11/05 6:13p Felixp
+// Code optimized by using DPAddNode instead of DPAdd
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 3 12/21/04 4:53p Markw
+// Modified device path defines for consistency.
+//
+// 2 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ElTorito.c
+//
+// Description: EFI El Torito Partition Support Functions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//=============================================================================
+// Includes
+#include "Partition.h"
+#include "ElTorito.h"
+#include "mbr.h"
+
+extern BOOLEAN Iso9660FileSystemSupportEnabled;
+EFI_GUID VendorDpGuid = AMI_ISO9660_MEDIA_GUID;
+
+//=============================================================================
+// Local Variables
+
+//=============================================================================
+// Function Definitions
+
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: ElToritoCreateChildHandle
+//
+// Description: Searches CDROM disk for El Torito bootable partitions
+// and creates a child handle for each one found
+//
+// Input:
+// *This - Pointer to the instance of this blockIo protocol
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *DiskIo - Pointer to the parent DiskIo protocol
+// *DevicePath - Pointer to the Parent's device path
+// ControllerHandle - the parent's controller handle
+//
+// Output:
+//
+// Returns:
+// EFI_SUCCESS - Partition found
+// EFI_INVALID_MEDIA - a parameter passed in or in the data structure
+// is invalid
+// EFI_NO_MEDIA - No partitions found
+// EFI_OUT_OF RESOURCES - Not enough resources to allocate memory
+//
+// Referrals: ReadBlocks AllocatePool MemCmp FreePool Div64 SetMem
+// CreateChildHandle DPAddNode SET_NODE_LENGTH
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS ElToritoCreateChildHandle (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ PARTITION_DATA PData, DData;
+ EFI_STATUS Status;
+ EFI_LBA Lba;
+ BOOT_RECORD_DESC *VolDesc = NULL;
+ EL_TORITO_ENTRIES *Entry = NULL, *StartEntry = NULL;
+ CDROM_DEVICE_PATH CdDp;
+ UINT32 BlockSize;
+ UINT16 Checksum;
+ UINT16 *Temp = NULL;
+ UINTN Idx;
+ UINT32 VolSize;
+ UINT32 Sectors;
+ UINTN BootEntry;
+ UINTN Dummy;
+
+ AMI_ISO9660_DEVICE_PATH VendorDp;
+ PRIMARY_VOLUME_DESC_HEADER *PrimVolDesc;
+
+
+// TODO: The El Torito spec says that the Boot Record Volume only exists on the last session
+// we need to find the last session on the CD
+
+ // Verify that the CDROM is using the correct block size
+ if (BlockIo->Media->BlockSize != CDROM_BLOCK_SIZE)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Allocate memory for the Boot Record Volume
+ Status = gBS->AllocatePool(EfiBootServicesData, BlockIo->Media->BlockSize, &VolDesc);
+
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ // CDROM Spec says sector 16 contains the Primary Volume descriptor
+ Lba = CDROM_BOOT_PRI_VOL_DESCRIPTOR_SECTOR;
+
+ Status = BlockIo->ReadBlocks( BlockIo, BlockIo->Media->MediaId, Lba,
+ BlockIo->Media->BlockSize, VolDesc );
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(VolDesc);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check for valid volume descriptor signature
+ if (MemCmp (VolDesc->IsoId, "CD001", 5))
+ {
+ gBS->FreePool(VolDesc);
+ return EFI_INVALID_PARAMETER;
+ }
+
+//***********************************************************************
+// Add Logical partition for ISO 9660 support
+//***********************************************************************
+ PrimVolDesc = (PRIMARY_VOLUME_DESC_HEADER *)VolDesc;
+ BlockSize = CDROM_BLOCK_SIZE;
+
+ //Set Vendor device path
+ VendorDp.Dp.Header.Type = MEDIA_DEVICE_PATH;
+ VendorDp.Dp.Header.SubType = MEDIA_VENDOR_DP;
+ VendorDp.Dp.Guid = VendorDpGuid;
+ VendorDp.VolumeSize = PrimVolDesc->VolSpaceSize;
+ VendorDp.Root = PrimVolDesc->Root;
+ MemCpy(VendorDp.VolumeLabel, PrimVolDesc->VolId, 32);
+ SET_NODE_LENGTH(&VendorDp.Dp.Header,sizeof(AMI_ISO9660_DEVICE_PATH));
+
+
+ // clear the data structure
+ gBS->SetMem(&DData, sizeof(PARTITION_DATA), 0);
+
+ // create new device path
+ DData.DevPath = DPAddNode(DevicePath, &(VendorDp.Dp.Header));
+
+ // save pertinent info
+ DData.Handle = NULL;
+ DData.ParentBlockIo = BlockIo;
+ DData.ParentDiskIo = DiskIo;
+ DData.StartingLba = 0;
+ DData.EndingLba = BlockIo->Media->LastBlock;
+
+ // Store Parent Handle
+ DData.ParentHandle = ControllerHandle;
+
+//***********************************************************************
+// End of ISO 9660 support
+//***********************************************************************
+
+ // Get the Volume Space Size from Primary Volume Descriptor,
+ // the 32-bit numerical value is stored in Both-Little and Big Endian
+ VolSize = VolDesc->VolSpaceSize[0];
+
+
+ // El Torito Spec says sector 17 contains the Boot Record
+ // Volume: Read and verify the data
+ Lba = CDROM_BOOT_REC_VOL_DESCRIPTOR_SECTOR;
+
+ Status = BlockIo->ReadBlocks( BlockIo, BlockIo->Media->MediaId, Lba,
+ BlockIo->Media->BlockSize, VolDesc );
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ goto EndOfEltorito;
+ }
+
+ // Validate the info in the Boot Record
+ if ((VolDesc->BootIndicator != 0) || ( MemCmp (VolDesc->IsoId, "CD001", 5)) ||
+ (VolDesc->Version != 1) || (MemCmp(VolDesc->Identifier, EL_TORITO_SPEC, 23) ) )
+ {
+ // not a valid boot Record
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ goto EndOfEltorito;
+ }
+
+ // There is a valid boot record. move on to the Boot catalog
+ Lba = VolDesc->BootCatalog;
+
+ Status = gBS->AllocatePool(EfiBootServicesData, BlockIo->Media->BlockSize, &StartEntry);
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ goto EndOfEltorito;
+ }
+
+ // Now load the Boot Catalog and find all the partitions
+ BlockIo->ReadBlocks( BlockIo, BlockIo->Media->MediaId, Lba,
+ BlockIo->Media->BlockSize, StartEntry );
+
+ // get pointer to the first entry in the Boot Record
+ Entry = (EL_TORITO_ENTRIES *)StartEntry;
+
+ if ((Entry->ValEntry.HeaderId != 1) || (Entry->ValEntry.Sig != 0xaa55))
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ gBS->FreePool(StartEntry);
+ StartEntry = NULL;
+ goto EndOfEltorito;
+ }
+
+ // Now Calculate checksum
+ Checksum = 0;
+ Temp = (UINT16 *)Entry;
+
+ for (Idx = 0; Idx < 16; Idx++)
+ Checksum += Temp[Idx];
+
+ // if the checksum is not 0 then the Boot catalog is considered invalid
+ if (Checksum)
+ {
+ gBS->FreePool(VolDesc);
+ VolDesc = NULL;
+ gBS->FreePool(StartEntry);
+ StartEntry = NULL;
+ goto EndOfEltorito;
+ }
+
+ // The checksum is zero so here we go
+
+ // Find and install the Boot entries
+ // loop through the boot catalog looking for bootable entries
+ // start at the second entry in the boot catalog,
+ // the first is the validation entry
+ Entry++;
+
+ for ( Idx = 0, BootEntry = 0; Idx < ((CDROM_BLOCK_SIZE/ sizeof(EL_TORITO_ENTRIES)) - 1);
+ Idx++, Entry++)
+ {
+ // if it isn't bootable, get next entry
+ if (Entry->DefaultEntry.BootId != CDROM_BOOTABLE)
+ continue;
+
+
+ BlockSize = BlockIo->Media->BlockSize;
+ if( (BlockSize == 0) || (BlockSize == 0xFFFFFFFF) ) {
+ BlockSize = 512;
+ }
+ TRACE((TRACE_DXE_CORE, "BlockSize is %d, MediaID is %d\n", BlockSize, BlockIo->Media->MediaId));
+
+ Sectors = Entry->DefaultEntry.SectorCount;
+ TRACE((TRACE_DXE_CORE, "Sector count is %d\n", Sectors));
+ TRACE((TRACE_DXE_CORE, "Media Type is %d\n", Entry->DefaultEntry.MediaType));
+
+ // use this switch to set the Partition Size
+ switch (Entry->DefaultEntry.MediaType)
+ {
+ case FLOPPY_144:
+ Sectors = FLOPPY_144_SIZE_LBA;
+ break;
+ case FLOPPY_288:
+ Sectors = FLOPPY_288_SIZE_LBA;
+ break;
+ case FLOPPY_12:
+ Sectors = FLOPPY_12_SIZE_LBA;
+ break;
+
+ case NO_EMULATION:
+ BlockSize = CDROM_BLOCK_SIZE;
+ break;
+
+ case HARD_DRIVE:
+ BlockSize = 512;
+ break;
+ default:
+ continue;
+ }
+
+
+ if ((Idx != 0) && (BootEntry == 0))
+ BootEntry++;
+
+ CdDp.BootEntry = (UINT32) BootEntry++;
+
+ CdDp.PartitionStart = Entry->DefaultEntry.LoadLba;
+
+ if (Sectors < 2)
+ CdDp.PartitionSize = (VolSize > BlockIo->Media->LastBlock + 1) ?
+ (UINT32)(BlockIo->Media->LastBlock - CdDp.PartitionStart + 1) :
+ (UINT32)(VolSize - CdDp.PartitionStart);
+
+ else
+ CdDp.PartitionSize = Div64(Sectors* BlockSize + BlockIo->Media->BlockSize - 1,
+ BlockIo->Media->BlockSize, &Dummy );
+
+ // set up the device path for the partition
+ CdDp.Header.Type = MEDIA_DEVICE_PATH;
+ CdDp.Header.SubType = MEDIA_CDROM_DP;
+ SET_NODE_LENGTH(&CdDp.Header,sizeof(CDROM_DEVICE_PATH));
+
+ // clear the data structure
+ gBS->SetMem(&PData, sizeof(PARTITION_DATA), 0);
+
+ // create new device path
+ PData.DevPath = DPAddNode(DevicePath, &CdDp.Header);
+
+ // save pertinent info
+ PData.Handle = NULL;
+ PData.ParentBlockIo = BlockIo;
+ PData.ParentDiskIo = DiskIo;
+ PData.StartingLba = CdDp.PartitionStart;
+ PData.EndingLba = CdDp.PartitionStart + CdDp.PartitionSize - 1;
+
+ // Store Parent Handle
+ PData.ParentHandle = ControllerHandle;
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockSize);
+ }
+
+EndOfEltorito:
+
+ if (VolDesc != NULL) gBS->FreePool(VolDesc);
+
+ if (StartEntry != NULL) gBS->FreePool(StartEntry);
+
+ if (Iso9660FileSystemSupportEnabled)
+ {
+ Status = CreateChildHandle(This, &DData, CDROM_BLOCK_SIZE);
+ }
+
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/ElTorito.h b/Core/CORE_DXE/Partition/ElTorito.h
new file mode 100644
index 0000000..ebbd7ba
--- /dev/null
+++ b/Core/CORE_DXE/Partition/ElTorito.h
@@ -0,0 +1,264 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.h 5 7/09/09 5:01p Oleksiyy $
+//
+// $Revision: 5 $
+//
+// $Date: 7/09/09 5:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/ElTorito.h $
+//
+// 5 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 4 1/16/09 3:02p Felixp
+// New Feature:
+// CD-ROM handling code is updated to create additional logical instance
+// of the Bock I/O protocol
+// based on primary volume descriptor of the CR-ROM.
+// The instance is used by the ISO 9660 file systems driver
+// (separate eModule. Not part of the Core) to implement file system
+// protocol.
+// The new parittion driver funcionality is only enabled when ISO 9660
+// file systems driver
+// ($/Source/Modules/FsIso9660) is included into the project.
+//
+// 2 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <ElTorito.h>
+//
+// Description: EFI El Torito Partition Generic Driver Header.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EL_TORITO_H__
+#define __EL_TORITO_H__
+
+#define CDROM_BOOT_PRI_VOL_DESCRIPTOR_SECTOR 16
+#define CDROM_BOOT_REC_VOL_DESCRIPTOR_SECTOR 17
+
+#define CDROM_BLOCK_SIZE 2048
+
+#define CDROM_BOOTABLE 0x88
+
+
+#define NO_EMULATION 0x00
+#define FLOPPY_12 0x01
+#define FLOPPY_144 0x02
+#define FLOPPY_288 0x03
+#define HARD_DRIVE 0x04
+
+
+#define HD_BLOCK_SIZE 512
+#define FLOPPY_144_SIZE_LBA 720
+#define FLOPPY_288_SIZE_LBA 1440
+#define FLOPPY_12_SIZE_LBA 615
+
+#define EL_TORITO_SPEC "EL TORITO SPECIFICATION"
+
+// {BA7C46D1-9C5E-4fc8-943D-1A491F23FE01}
+#define AMI_ISO9660_MEDIA_GUID \
+ { 0xba7c46d1, 0x9c5e, 0x4fc8, 0x94, 0x3d, 0x1a, 0x49, 0x1f, 0x23, 0xfe, 0x1 }
+
+
+//<AMI_GHDR_START>
+//------------------------------------------------------------------
+// Name: Data_Structures
+//
+// Description:
+// Data Structures needed for El Torito
+//
+// BOOT_RECORD - Data Structure definition of a boot record
+// that is contained within an El Torito Disk
+//
+// EL_TORITO_ENTRIES - A union of possible structs that could be
+// contained within an entry on the disk
+//
+//------------------------------------------------------------------
+//<AMI_GHDR_END>
+#pragma pack(1)
+
+typedef struct _BOOT_RECORD
+{
+ UINT8 BootIndicator;
+ CHAR8 IsoId[5];
+ UINT8 Version;
+ CHAR8 Identifier[32];
+ UINT8 Unused[32];
+ UINT32 BootCatalog;
+ UINT8 Unused2[5];
+ UINT32 VolSpaceSize[2];
+} BOOT_RECORD_DESC;
+
+
+
+typedef union
+{
+ struct
+ {
+ UINT8 HeaderId;
+ UINT8 PlatformId;
+ UINT16 Res0;
+ CHAR8 Id[24];
+ UINT16 Checksum;
+ UINT16 Sig;
+ } ValEntry;
+
+
+ struct
+ {
+ UINT8 BootId;
+ UINT8 MediaType;
+ UINT16 LoadSegment;
+ UINT8 SystemType;
+ UINT8 Unused;
+ UINT16 SectorCount;
+ UINT32 LoadLba;
+ } DefaultEntry;
+
+
+ struct
+ {
+ UINT8 HeaderId;
+ UINT8 PlatformId;
+ UINT16 NumSectionEntries;
+ CHAR8 IdString[28];
+ } SecHeader;
+
+
+ struct
+ {
+ UINT8 BootId;
+ UINT8 MediaType;
+ UINT16 LoadSegment;
+ UINT8 SystemType;
+ UINT8 Unused;
+ UINT16 SectorCount;
+ UINT32 LoadLba;
+ UINT8 SelectionType;
+ UINT8 Criteria[19];
+ } SecEntry;
+
+} EL_TORITO_ENTRIES;
+
+typedef struct
+{
+ UINT8 VolDescType;
+ CHAR8 StdId[5];
+ UINT8 VolDescVer;
+} VOLUME_DESCRIPTOR_HEADER;
+
+typedef struct
+{
+ UINT32 Year;
+ UINT16 Month;
+ UINT16 Day;
+ UINT16 Hour;
+ UINT16 Minute;
+ UINT16 Second;
+ UINT16 HSecond;
+ INT8 Offset;
+} CD_DATE_TIME;
+
+typedef struct
+{
+ UINT8 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+ INT8 Offset;
+} FILE_DATE_TIME;
+
+typedef struct
+{
+ UINT8 RecordLength;
+ UINT8 ExtAttrRecLength;
+ UINT64 StartLba;
+ UINT64 DataLength;
+ FILE_DATE_TIME RecTime;
+ UINT8 Flags;
+ UINT8 FileUnitSize;
+ UINT8 InterleaveGap;
+ UINT32 VolSeqNum;
+ UINT8 FileIdLength;
+ UINT8 FileId[1];
+} ROOT_DIR_HEADER;
+
+typedef struct
+{
+ VOLUME_DESCRIPTOR_HEADER Header;
+ UINT8 Flags;
+ CHAR8 SysId[32];
+ CHAR8 VolId[32];
+ UINT64 Unused;
+ UINT64 VolSpaceSize;
+ CHAR8 EscSeq[32];
+ UINT32 VolSetSize;
+ UINT32 VolSeqNum;
+ UINT32 LBlockSize;
+ UINT64 PathTblSize;
+ UINT32 LPathTbl1;
+ UINT32 LPathTbl2;
+ UINT32 MPathTbl1;
+ UINT32 MPathTbl2;
+ ROOT_DIR_HEADER Root;
+ CHAR8 VolSetId[128];
+ CHAR8 PublisherId[128];
+ CHAR8 DataPrepId[128];
+ CHAR8 ApplicationId[128];
+ CHAR8 CopyrightFileId[37];
+ CHAR8 AbstractFileId[37];
+ CHAR8 BiblioFileId[37];
+ CD_DATE_TIME CreationTime;
+ CD_DATE_TIME ModifyTime;
+ CD_DATE_TIME ExpireTime;
+ CD_DATE_TIME EffectiveTime;
+ UINT8 FileStrucVer;
+ UINT8 Unused1;
+} PRIMARY_VOLUME_DESC_HEADER;
+
+typedef struct
+{
+ VENDOR_DEVICE_PATH Dp;
+ UINT64 VolumeSize;
+ ROOT_DIR_HEADER Root;
+ CHAR8 VolumeLabel[32];
+} AMI_ISO9660_DEVICE_PATH;
+
+#pragma pack()
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Gpt.c b/Core/CORE_DXE/Partition/Gpt.c
new file mode 100644
index 0000000..3a1fe92
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Gpt.c
@@ -0,0 +1,606 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.c 16 7/19/12 10:26a Artems $
+//
+// $Revision: 16 $
+//
+// $Date: 7/19/12 10:26a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.c $
+//
+// 16 7/19/12 10:26a Artems
+// [TAG] EIP94126
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] GPT system recovery can't work and backup GPT partition
+// will also be destroyed after GPT recovery.
+// [RootCause] Incorrect LBA used to restore GPT partition
+// [Solution] Use correct LBA
+// [Files] Gpt.c
+//
+// 15 5/02/11 5:57p Artems
+// EIP 59571: New partition driver functionality as per UEFI spec v.2.3.1
+//
+// 14 11/23/10 4:43p Vyacheslava
+// [TAG] EIP45145
+// [Category] New Feature
+// [Description] A new feature has done by Cire Lin: We're did the code
+// for repairing GPT table. If CRC checking fails then it will run
+// CopyGpt() to repair GPT table.
+//
+// 13 4/16/10 4:24p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 12 2/04/10 2:07p Oleksiyy
+// Minor fixes
+//
+// 11 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 10 4/03/09 5:24p Oleksiyy
+// EIP 20879: Linux GPT discovering logic improvement.
+//
+// 9 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 8 4/24/07 6:07p Robert
+// Update for CHM compliance
+//
+// 7 4/12/07 7:04p Robert
+// Coding Standard Updates
+//
+// 6 3/22/07 5:39p Robert
+// Updated Files for coding standard
+//
+// 5 10/10/06 3:22p Yakovlevs
+// Bug fixes. The GPT Partition Driver working now.
+//
+// 4 5/19/06 10:47p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 3 2/11/05 6:14p Felixp
+// - Code optimized by using DPAddNode instead of DPAdd
+// - bug fixes
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Gpt.c
+//
+// Description: EFI GPT Partition Generic Driver.
+// This file detects whether or not the system has a GPT format
+// for the drive and sets up all partitions on the drive
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//-----------------------------------------------------------------------------
+// Includes
+#include "Partition.h"
+#include "Gpt.h"
+#include "Mbr.h"
+
+//-----------------------------------------------------------------------------
+// global variables
+
+
+//-----------------------------------------------------------------------------
+// Function Definitions
+
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+// Procedure: AdjustBufferSize
+//
+// Description: Calculates correct Buffer size for BlockIO trasfer
+//
+// Input: EFI_BLOCK_IO_PROTOCOL *BlockIo BlockIo Protocol Interface
+// UINTN *BufferSize Pointer To the Size Needed
+//
+// Output: Modifies Buffer Size to reflect correct number of bytes
+//
+// Returns: Nothing
+//
+// Referrals:
+//
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+VOID AdjustBufferSize(IN EFI_BLOCK_IO_PROTOCOL *BlockIo, IN OUT UINTN *BufferSize)
+{
+ UINTN sz;
+
+ // Calculate the size of trazaction
+ sz=BlockIo->Media->BlockSize * (*BufferSize/BlockIo->Media->BlockSize);
+
+ if (*BufferSize % BlockIo->Media->BlockSize) sz+=BlockIo->Media->BlockSize;
+
+ *BufferSize=sz;
+}
+
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: CopyGpt
+//
+// Description: Copies a valid GPT to the location of an invalid one
+//
+// Input:
+// BlockIo - pointer to the BlockIo partition so we can read and write
+// to the Block Device
+// DiskIo - Unused at this time
+// Destination - Pointer to where the valid GPT will be copied
+// Source - Pointer to a valid GPT
+//
+// Output: None - A valid GPT will be written to the Destination address
+//
+// Returns: None
+//
+// Referrals: CopyMem ReadBlocks CalculateCrc32 AllocatePool AdjustBufferSize
+// WriteBlocks FreePool
+//
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+VOID CopyGpt(
+ EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ EFI_DISK_IO_PROTOCOL *DiskIo,
+ GPT_HEADER *Destination,
+ GPT_HEADER *Source
+)
+{
+ EFI_STATUS Status;
+ UINT8 *EntryArray;
+ EFI_LBA EntryLba;
+ UINTN Size;
+ UINT32 Crc32;
+
+ // Calculate Buffer Size for Enrty array
+ Size = Source->NumberOfPartitionEntries * Source->SizeOfPartitionEntry;
+ AdjustBufferSize(BlockIo, &Size);
+
+ if (Source->MyLba == 1)
+ EntryLba = Source->LastUsableLba + 1;
+ else
+ EntryLba = Source->AlternateLba + 1;
+
+ // Copy the GPT Header
+ gBS->CopyMem( Destination, Source, sizeof(GPT_HEADER) );
+
+ Destination->MyLba = Source->AlternateLba;
+ Destination->AlternateLba = Source->MyLba;
+ Destination->PartitionEntryLba = EntryLba;
+ Destination->Crc32 = 0;
+ Destination->Header.CRC32 = 0;
+
+ // Allocate Memory for Source Patrition Table Array
+ Status = gBS->AllocatePool( EfiBootServicesData, Size, &EntryArray );
+
+ // Zero it out
+ gBS->SetMem( EntryArray, Size, 0 );
+
+ // Read Source's Partition Table Entry Array to the buffer
+ Status = BlockIo->ReadBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ Source->PartitionEntryLba,
+ Size,
+ EntryArray
+ );
+
+ // Calculate CRC32 of GIUID Partition Table Entry Array
+ gBS->CalculateCrc32(
+ (UINT8*)EntryArray,
+ Source->NumberOfPartitionEntries * Source->SizeOfPartitionEntry,
+ &Crc32
+ );
+ Destination->Crc32 = Crc32;
+
+ gBS->CalculateCrc32(
+ (UINT8*)Destination,
+ sizeof(GPT_HEADER),
+ &Crc32
+ );
+ Destination->Header.CRC32 = Crc32;
+
+
+ // Write to Destination Partition Header Block
+ Status = BlockIo->WriteBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ Destination->MyLba,
+ BlockIo->Media->BlockSize,
+ Destination
+ );
+
+ // Write Destination Partition Table Entry Array
+ Status = BlockIo->WriteBlocks(
+ BlockIo,
+ BlockIo->Media->MediaId,
+ Destination->PartitionEntryLba,
+ Size,
+ EntryArray
+ );
+
+ gBS->FreePool(EntryArray);
+}
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: ValidateGptHeader
+//
+// Description: Checks if the GPT table is valid
+//
+// Input:
+// BlockIo - Pointer to the Parent BlockIo instance
+// GptHeader - Pointer to a memory area that contains the GPT header
+// to validate
+// HdrLoc - Header location
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - GPT is valid
+// EFI_INVALID_PARAMETER - checks to see if the CRC, signature, and Header
+// Location are vlaid
+// EFI_OUT_OF_RESOURCES - Not enough free memory to allocate to read the
+// GPT entry table
+//
+// Referrals: CalculateCrc32 MemCmp AdjustBufferSize AllocatePool ReadBlocks
+// FreePool
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS ValidateGptHeader(
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN GPT_HEADER *GptHeader,
+ IN EFI_LBA HdrLoc
+)
+{
+ EFI_STATUS Status;
+ UINT32 Crc;
+ UINT32 Temp32;
+ UINTN Size;
+ PARTITION_ENTRY *GptEntryTable;
+
+
+ // Get CRC of the Partition Header
+ Temp32 = GptHeader->Header.CRC32;
+ GptHeader->Header.CRC32 = 0;
+
+ gBS->CalculateCrc32((UINT8*)GptHeader, sizeof(GPT_HEADER), &Crc);
+ GptHeader->Header.CRC32 = Crc;
+
+ // Check calculated CRC
+ // Check signature
+ // Check that MyLBA parameter points to the location of the current Header
+ if (MemCmp(EFI_GPT_HEADER_ID, &GptHeader->Header.Signature, sizeof(UINT64))
+ || (Temp32 != Crc)
+ || (GptHeader->MyLba != HdrLoc) )
+ return EFI_INVALID_PARAMETER;
+
+ // Calculate the size of trasaction
+ Size = GptHeader->NumberOfPartitionEntries *
+ GptHeader->SizeOfPartitionEntry;
+ AdjustBufferSize(BlockIo,&Size);
+
+ // allocate memory for the Entry array
+ Status = gBS->AllocatePool( EfiBootServicesData, Size, &GptEntryTable);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ // get the data from the entry array
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId,
+ GptHeader->PartitionEntryLba,
+ Size, GptEntryTable);
+
+ // calculate the CRC value for the entry array
+ gBS->CalculateCrc32((UINT8*)GptEntryTable,
+ GptHeader->NumberOfPartitionEntries*
+ GptHeader->SizeOfPartitionEntry, &Crc);
+
+ // the the allocated memory
+ if (GptEntryTable != NULL ) gBS->FreePool(GptEntryTable);
+
+ // check if the CRC that was calculated matches the value that was stored
+ if (Crc != GptHeader->Crc32) return EFI_INVALID_PARAMETER;
+
+ // All checks passed, the GPT is valid
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: VerifyPartionTables
+//
+// Description: Check if either GPT is valid. if only one is then fix the other
+// if both are bad, then it is not a valid GPT system. return error
+//
+// Input:
+// BlockIo - pointer to the BlockIo partition so we can read and write
+// to the Block Device
+// DiskIo - Unused at this time
+//
+// Output:
+// GPT - pointer to a memory space for one GPT
+//
+// Returns: EFI_SUCCESS - If a valid GPT is found
+// EFI_UNSUPPORTED - if no valid GPT is found
+// EFI_OUT_OF_RESOURCES - not enough allocateable memory is available
+//
+// Referrals: AllocatePool ReadBlocks FreePool AdjustBufferSize
+// ValidateGPTHeader CopyGPT CopyMem
+//
+// Notes
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS VerifyPartionTables(
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ OUT GPT_HEADER *Gpt
+)
+{
+ EFI_STATUS Status;
+ GPT_HEADER *Primary = NULL;
+ GPT_HEADER *Secondary = NULL;
+ MASTER_BOOT_RECORD *Pmbr = NULL;
+ UINTN Size;
+ UINT8 i, FoundPP = 0;
+
+ // Allocate a buffer for the Protective MBR
+ Status = gBS->AllocatePool(EfiBootServicesData, BlockIo->Media->BlockSize, &Pmbr);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ // Read the Protective MBR from LBA #0
+ Status = BlockIo->ReadBlocks (BlockIo, BlockIo->Media->MediaId, 0,
+ BlockIo->Media->BlockSize, Pmbr);
+
+ if (EFI_ERROR (Status))
+ {
+ gBS->FreePool(Pmbr);
+ return Status;
+ }
+
+ for (i=0; i < 4; i++)
+
+ // See if Protective MBR is valid and if not free allocated memory and return EFI_UNSUPPORTED
+ if ((Pmbr->PartRec[i].BootIndicator == 0x00) && (Pmbr->PartRec[i].OSType == 0xee) &&
+ (Pmbr->PartRec[i].StartingLba == 1)) FoundPP++;
+
+ if (FoundPP == 0)
+ {
+ gBS->FreePool(Pmbr);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Allocate memory to hold the data for the Primary and Secondary GPT headers
+ // Allocate Primary
+ Size=sizeof(GPT_HEADER);
+ AdjustBufferSize(BlockIo, &Size);
+
+ Status = gBS->AllocatePool(EfiBootServicesData, Size, &Primary);
+
+ // if error is returned, exit with No resources available
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Pmbr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Allocate for secondary header
+ Status = gBS->AllocatePool(EfiBootServicesData, Size, &Secondary);
+
+ // if error, free memory allocated for primary and then exit with no resources available
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Pmbr);
+ gBS->FreePool(Primary);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Read primary and backup table
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 1, Size, Primary);
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, BlockIo->Media->LastBlock, Size, Secondary);
+
+ // read primary header from the block device and verify if it is valid
+ if (EFI_ERROR(ValidateGptHeader(BlockIo, Primary, 1)))
+ {
+ // if primary is not valid, check secondary to see if it is valid
+ if (EFI_ERROR(ValidateGptHeader(BlockIo, Secondary, BlockIo->Media->LastBlock)))
+ {
+ gBS->FreePool(Pmbr);
+ gBS->FreePool(Primary);
+ gBS->FreePool(Secondary);
+ return EFI_UNSUPPORTED;
+ }
+
+ // if secondary table is good, copy to primary
+ else
+ {
+ CopyGpt(BlockIo, DiskIo, Primary, Secondary);
+ }
+ }
+
+ // if primary is good, check secondary
+ else
+ {
+ // if secondary is bad, copy primary to secondary
+ if (EFI_ERROR(ValidateGptHeader(BlockIo, Secondary, BlockIo->Media->LastBlock)))
+ {
+ CopyGpt(BlockIo, DiskIo, Secondary, Primary);
+ }
+ }
+
+ // now that both tables are fixed, copy to GPT output variable and exit
+ gBS->CopyMem(Gpt, Primary, sizeof(GPT_HEADER));
+
+ // before we exit free all memory allocation and exit with success
+ gBS->FreePool(Pmbr);
+ gBS->FreePool(Primary);
+ gBS->FreePool(Secondary);
+
+ return EFI_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//=============================================================================
+// Procedure: GPTDiscoverPartitions
+//
+// Description: Searches GPT Table for partitions
+//
+// Input:
+// *This - Pointer to the instance of this blockIo protocol
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *DiskIo - Pointer to the parent DiskIo protocol
+// *DevicePath - Pointer to the Parent's device path
+// ControllerHandle - the parent's controller handle
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// other - Driver not loaded
+//
+// Referrals: AllocatePool FreePool VerifyPartionTables AdjustBufferSize
+// MemCmp SetMem CopyMem CreateChildHandle SET_NODE_LENGTH
+//
+//=============================================================================
+//<AMI_PHDR_END>
+EFI_STATUS GptDiscoverPartitions (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_STATUS Status;
+ GPT_HEADER *Gpt = NULL;
+ UINT8 *EntryArray = NULL;
+ PARTITION_ENTRY *PartEntry=NULL;
+ HARDDRIVE_DEVICE_PATH HdDp;
+ PARTITION_DATA PData;
+ UINTN Idx;
+ UINTN Size;
+
+
+ // Allocate memory for a valid GPT partiton header
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(GPT_HEADER), &Gpt);
+
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+// EFI_DEADLOOP();
+ // verify that the GPT headers on this BlockIo device are valid
+ if (EFI_ERROR(VerifyPartionTables(BlockIo, DiskIo, Gpt )) )
+ {
+ gBS->FreePool(Gpt);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // If this gets executed, then the Headers are valid and the Entry array
+ // has the correct CRC value
+ // Now parse through the Entry Array and create instances for each
+ // partition on the media
+ // Check Entry Table Crc
+ Size = Gpt->NumberOfPartitionEntries * Gpt->SizeOfPartitionEntry;
+ AdjustBufferSize(BlockIo, &Size);
+
+ Status = gBS->AllocatePool(EfiBootServicesData, Size, &EntryArray);
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Gpt);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId,
+ Gpt->PartitionEntryLba, Size, EntryArray);
+
+ for (Idx = 0; Idx < Gpt->NumberOfPartitionEntries; Idx++)
+ {
+ PartEntry = (PARTITION_ENTRY *)(EntryArray + Idx * Gpt->SizeOfPartitionEntry);
+
+ // Check to see if this is an unused partition
+ if (!(MemCmp(&PartEntry->PartitionTypeGuid, &gUnusedPartitionGuid, sizeof(EFI_GUID))))
+ continue; // This is an unused partition
+
+ if(PartEntry->Attributes & 0x2) //bit 1 of Attributes set?
+ continue; //no BlockIo for this partition - UEFI spec 2.3.1 p.5.3.3 table 19
+
+ // clear the data structure
+ gBS->SetMem(&PData, sizeof(PARTITION_DATA), 0);
+
+ // set up the device path for the partition
+ HdDp.Header.Type = MEDIA_DEVICE_PATH;
+ HdDp.Header.SubType = MEDIA_HARDDRIVE_DP;
+ SET_NODE_LENGTH(&HdDp.Header,sizeof(HARDDRIVE_DEVICE_PATH));
+
+ // Idx is 0 based so add one so that partitionNumber is 1 based
+ HdDp.PartitionNumber = (UINT32) Idx + 1;
+ HdDp.PartitionStart = PartEntry->StartingLba;
+ HdDp.PartitionSize = PartEntry->EndingLba - PartEntry->StartingLba + 1;
+ gBS->CopyMem(&HdDp.Signature, &PartEntry->UniquePartitionGuid,
+ sizeof(EFI_GUID));
+ HdDp.MBRType = MBR_TYPE_EFI_PARTITION_TABLE_HEADER;
+ HdDp.SignatureType = SIGNATURE_TYPE_GUID;
+
+ PData.DevPath = DPAddNode(DevicePath, &HdDp.Header);
+
+ // save pertinent info
+ PData.Handle = NULL;
+ PData.ParentHandle = ControllerHandle;
+ PData.ParentBlockIo = BlockIo;
+ PData.ParentDiskIo = DiskIo;
+ PData.StartingLba = PartEntry->StartingLba;
+ PData.EndingLba = PartEntry->EndingLba;
+ gBS->CopyMem(&PData.PartGuid, &PartEntry->PartitionTypeGuid,
+ sizeof (EFI_GUID));
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockIo->Media->BlockSize);
+
+ }
+
+ gBS->FreePool(Gpt);
+ gBS->FreePool(EntryArray);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Gpt.h b/Core/CORE_DXE/Partition/Gpt.h
new file mode 100644
index 0000000..120b90a
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Gpt.h
@@ -0,0 +1,161 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.h 6 7/09/09 5:01p Oleksiyy $
+//
+// $Revision: 6 $
+//
+// $Date: 7/09/09 5:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Gpt.h $
+//
+// 6 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 5 1/08/08 4:37p Robert
+//
+// 4 1/08/08 4:00p Robert
+//
+// 3 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 2 4/24/07 6:06p Robert
+// Update for CHM compliance
+//
+// 1 1/28/05 1:17p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 2 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <GPT.h>
+//
+// Description: EFI GPT Partition Generic Driver Header.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _GPT_H_
+#define _GPT_H_
+
+#pragma pack(1)
+
+#define EFI_GPT_HEADER_ID "EFI PART"
+
+// GUID Partition Table Header
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: GPT_HEADER
+//
+// Description: Data Structure definition of the GPT table
+//
+// Fields:
+// Header - EFI_TABLE_HEADER - defines generic EFI header information
+// MyLba - EFI_LBA - The LBA that contains this GPT data structure
+// AlternateLba - EFI_LBA - The LBA that contains the alternative GPT
+// data structure
+// FirstUsableLba - EFI_LBA - the first logical block that can be used
+// in a partition that is defined by the GPT
+// LastUsableLba - EFI_LBA - the last logical block that can be used
+// in a partition that is defined by the GPT
+// DiskGuid - EFI_GUID - Unique GUID to identify this hard drive
+// PartitionEntryLba - EFI_LBA - the starting LBA of the GUID Partition
+// Entry Array
+// NumberOfPartitionEntries - UINT32 - the number of partition entries
+// in the Array
+// SizeOfPartitionEntry - UINT32 - the size of each partition entry
+// Crc32 - UINT32 - crc value of the entire GPT block
+//
+// Referral:
+// EFI_TABLE_HEADER EFI_LBA EFI_GUID
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct
+{
+ EFI_TABLE_HEADER Header;
+ EFI_LBA MyLba;
+ EFI_LBA AlternateLba;
+ EFI_LBA FirstUsableLba;
+ EFI_LBA LastUsableLba;
+ EFI_GUID DiskGuid;
+ EFI_LBA PartitionEntryLba;
+ UINT32 NumberOfPartitionEntries;
+ UINT32 SizeOfPartitionEntry;
+ UINT32 Crc32;
+} GPT_HEADER;
+
+// GPT Partition Entry
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: PARTITION_ENTRY
+//
+// Description: Data Structure definition of a partion entry in the GPT table
+//
+// Fields:
+// PartitionTypeGuid - EFI_GUID - contains GUID that defines that type
+// of GUID
+// UniquePartitionGuid - EFI_GUID - contains unique GUID for each
+// partition
+// StartingLba - EFI_LBA - first LBA of the partition
+// EndingLba - EFI_LBA - last logical block address
+// Attributes - UINT64 - UEFI defined attributes
+// Bit 0 - Partition is required for platform to function
+// Bits 1 - 47 - undefined
+// Bits 48 - 64 - reserved for GUID specific use
+// PartitionName[36] - CHAR16 - unicode string containing the name of
+// the partition
+//
+// Referral:
+// EFI_LBA
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct
+{
+ EFI_GUID PartitionTypeGuid;
+ EFI_GUID UniquePartitionGuid;
+ EFI_LBA StartingLba;
+ EFI_LBA EndingLba;
+ UINT64 Attributes;
+ CHAR16 PartitionName[36];
+} PARTITION_ENTRY;
+
+
+#pragma pack()
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Mbr.c b/Core/CORE_DXE/Partition/Mbr.c
new file mode 100644
index 0000000..7ccdae8
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Mbr.c
@@ -0,0 +1,407 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.c 12 4/16/10 4:24p Pats $
+//
+// $Revision: 12 $
+//
+// $Date: 4/16/10 4:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.c $
+//
+// 12 4/16/10 4:24p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 11 2/04/10 3:03p Oleksiyy
+// EIP 31633 Minor Fix
+//
+// 10 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 9 11/13/08 6:10p Felixp
+// Bug fix in MbrCreateChildHandle: unsed part of the signature (12 bytes)
+// in hard driver device path was never initialized.
+//
+// 8 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 7 4/25/07 11:52a Robert
+// Updated for CHM and coding standard commpliance
+//
+// 5 5/19/06 10:47p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 3 7/12/05 5:01p Robert
+// The Free BSD operating system created a partition that referenced
+// itself. This was not checked for in the partition driver so an
+// infinite loop was created.
+// this reference now causes an error condition..
+//
+// 2 2/11/05 6:13p Felixp
+// Code optimized by using DPAddNode instead of DPAdd
+//
+// 6 12/21/04 4:54p Markw
+// Modified device path defines for consistency.
+//
+// 5 12/02/04 5:54p Robert
+// Partition driver version works
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Mbr.c
+//
+// Description: EFI Mbr Partition Generic Driver. This file finds all
+// the partitions defined in the MBR found on a Device
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//-----------------------------------------------------------------------------
+// Includes
+#include "partition.h"
+#include "mbr.h"
+
+
+//-----------------------------------------------------------------------------
+// Global Variables
+EFI_GUID gMbrPartition = EFI_PART_TYPE_LEGACY_MBR_GUID;
+
+
+
+//-----------------------------------------------------------------------------
+// Function Prototypes
+
+
+
+//-----------------------------------------------------------------------------
+// Function Definitions
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+// Procedure: CheckValidMbr
+//
+// Description: Makes sure the Master Boot Record has valid partitions
+//
+// Input:
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *Mbr - pointer to a data structure that contains the MBR for
+// the current drive
+//
+// Output: None
+//
+// Returns:
+// TRUE - MBR is valid
+// FALSE - MBR is invalid
+//
+// Referrals: ReadBlocks
+//
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+BOOLEAN CheckValidMbr(
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN MASTER_BOOT_RECORD *Mbr
+)
+{
+ EFI_STATUS Status;
+ EFI_LBA EndLba;
+ UINT8 PartitionFound = 0;
+ UINT8 Idx;
+ UINT8 Loop2;
+
+ // read the first block of the Harddrive
+ Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId, 0,
+ BlockIo->Media->BlockSize, Mbr);
+
+ if (Mbr->Sig != MBR_SIGNATURE)
+ return FALSE;
+
+ // check for valid LBA range for all the partitions
+ for (Idx = 0; Idx < NUM_MBR_PARTITIONS; Idx++)
+ {
+ // ignore partitions whose OSType or Size is zero
+ if ((Mbr->PartRec[Idx].OSType == 0)
+ || (Mbr->PartRec[Idx].SizeInLba == 0))
+ continue;
+
+ if (Mbr->PartRec[Idx].StartingLba == 0)
+ continue;
+
+ PartitionFound++;
+
+ EndLba = Mbr->PartRec[Idx].StartingLba
+ + Mbr->PartRec[Idx].SizeInLba - 1;
+
+ // check to make sure the partition does not exceed the length
+ // of the disk
+ if (EndLba > BlockIo->Media->LastBlock)
+ return FALSE;
+
+ // Now loop through all partitions to make sure they don't overlap
+ for (Loop2 = Idx+1; Loop2 < NUM_MBR_PARTITIONS; Loop2++)
+ {
+ // ignore partitions whose OSType or Size is zero
+ if ((Mbr->PartRec[Loop2].OSType == 0)
+ || (Mbr->PartRec[Loop2].SizeInLba == 0))
+ continue;
+
+ // check for overlapping partitions
+ if ( EndLba >= Mbr->PartRec[Loop2].StartingLba )
+ return FALSE;
+ }
+ }
+
+ if (PartitionFound)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+// Procedure: MbrCreateChildHandle
+//
+// Description: Searches Master Boot Record for partitions
+//
+// Input:
+// *This - Pointer to the instance of this blockIo protocol
+// *BlockIo - Pointer to the parent blockIo Protocol
+// *DiskIo - Pointer to the parent DiskIo protocol
+// *DevicePath - Pointer to the Parent's device path
+// ControllerHandle - the parent's controller handle
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// other - Driver not loaded
+//
+// Referrals: AllocatePool FreePool CheckValidMbr SetMem ReadBlocks
+// CopyMem CreateChildHandle SET_NODE_LENGTH
+//<AMI_PHDR_END>
+//-----------------------------------------------------------------------------
+
+EFI_STATUS MbrCreateChildHandle(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+)
+{
+ EFI_STATUS Status;
+ MASTER_BOOT_RECORD *Mbr = NULL;
+ MASTER_BOOT_RECORD *ExtPart = NULL;
+ UINT8 Idx;
+ UINT32 PartitionExists = 0;
+ PARTITION_DATA PData;
+ EFI_GUID *PartType = NULL;
+ EFI_LBA Lba;
+ HARDDRIVE_DEVICE_PATH HdDp;
+
+
+ // allocate memory for the MBR and then read the data from the disk
+ Status = gBS->AllocatePool( EfiBootServicesData,
+ BlockIo->Media->BlockSize, &Mbr);
+
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ // check to see if the current drive has a valid MBR and a valid
+ // partition on the drive
+ if (CheckValidMbr(BlockIo, Mbr) == FALSE)
+ {
+ gBS->FreePool(Mbr);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // To get here there is a valid partition
+ // create a handle for the partitions
+
+ // set up the device path header for the partition
+ HdDp.Header.Type = MEDIA_DEVICE_PATH;
+ HdDp.Header.SubType = MEDIA_HARDDRIVE_DP;
+ SET_NODE_LENGTH(&HdDp.Header,sizeof(HARDDRIVE_DEVICE_PATH));
+
+ // Loop through the partitions
+ for (Idx=0; Idx < NUM_MBR_PARTITIONS; Idx++)
+ {
+ // skip over empty partitions
+ if ((Mbr->PartRec[Idx].OSType == 0)
+ || (Mbr->PartRec[Idx].SizeInLba == 0))
+ continue;
+
+ // Take care of repetative data assignment
+ // clear the data structure
+ gBS->SetMem(&PData, sizeof(PARTITION_DATA), 0);
+
+ // set up the device path for the partition
+ HdDp.MBRType = MBR_TYPE_MASTER_BOOT_RECORD;
+ HdDp.SignatureType = SIGNATURE_TYPE_MBR;
+ pBS->SetMem(&HdDp.Signature,sizeof(HdDp.Signature),0);
+ PData.Handle = NULL;
+ PData.ParentBlockIo = BlockIo;
+ PData.ParentDiskIo = DiskIo;
+
+
+ // Now that a valid partition is found process it
+ // TODO: are there any other types of extended partitions
+ // if so, add them to this if statement
+ if ((Mbr->PartRec[Idx].OSType == EXTENDED_PARTITION) ||
+ (Mbr->PartRec[Idx].OSType == WIN95_EXTENDED_PARTITION))
+ {
+ // process the logical partitions that may or may not exist
+ Status = gBS->AllocatePool( EfiBootServicesData,
+ BlockIo->Media->BlockSize, &ExtPart);
+
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Mbr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // defines where to start reading the next MBR/partition
+ // table from
+ Lba = Mbr->PartRec[Idx].StartingLba;
+
+ // loop through logical partitions: any number of
+ // possible partitions
+ while (TRUE)
+ {
+ // if the table points back to itself, exit
+ if ( Lba == 0)
+ break;
+
+ // get Partition table from the first block of the device
+ Status = BlockIo->ReadBlocks(BlockIo, BlockIo->Media->MediaId,
+ Lba, BlockIo->Media->BlockSize, ExtPart);
+
+ // check to see if the disk was read
+ // Also check for All logical partitions having an OSType
+ // of 0x05 or EXTENDED_PARTITION
+ if (EFI_ERROR(Status))
+ {
+ gBS->FreePool(Mbr);
+ gBS->FreePool(ExtPart);
+ return Status;
+ }
+
+ // make sure this is a valid partition
+ if (ExtPart->PartRec[0].OSType == NO_PARTITION)
+ break;
+
+ // check for problems that make the partition invalid
+ if ((Lba + ExtPart->PartRec[0].SizeInLba) >
+ (Mbr->PartRec[Idx].StartingLba
+ + Mbr->PartRec[Idx].SizeInLba))
+ break;
+
+ // register the Partition
+ HdDp.PartitionNumber = ++PartitionExists;
+
+ // notice that the start of the partition is after the
+ // partition table
+ HdDp.PartitionStart = ExtPart->PartRec[0].StartingLba + Lba;
+ HdDp.PartitionSize = ExtPart->PartRec[0].SizeInLba;
+ gBS->CopyMem(&HdDp.Signature, &ExtPart->UniqueMbrSig,
+ sizeof(UINT32));
+ PData.StartingLba = HdDp.PartitionStart;
+ PData.EndingLba = HdDp.PartitionStart
+ + ExtPart->PartRec[0].SizeInLba - 1;
+
+ // create device path
+ PData.DevPath = DPAddNode(DevicePath, &HdDp.Header);
+
+ // Store Parent Handle
+ PData.ParentHandle = ControllerHandle;
+
+ // if the OSType member is 0xEF this variable set.
+ // otherwise it is left as 0
+ if (ExtPart->PartRec[0].OSType == EFI_SYSTEM_PARTITION)
+ gBS->CopyMem(&PData.PartGuid, &gMbrPartition,
+ sizeof (EFI_GUID));
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockIo->Media->BlockSize);
+
+ // check to see if the next partition is an extended partition
+ if ((ExtPart->PartRec[1].OSType != EXTENDED_PARTITION) &&
+ (ExtPart->PartRec[1].OSType != WIN95_EXTENDED_PARTITION) )
+ break;
+
+ // get set up for the next partition. The Starting Lba
+ // address is a relative address inside the extended
+ // partition add the starting address of the extended
+ // partition to get the actual LBA where it starts
+ Lba = ExtPart->PartRec[1].StartingLba
+ + Mbr->PartRec[Idx].StartingLba;
+ }
+ }
+
+ else // process primary partition
+ {
+ // set up the device path for the partition
+ HdDp.PartitionNumber = ++PartitionExists;
+ HdDp.PartitionStart = Mbr->PartRec[Idx].StartingLba;
+ HdDp.PartitionSize = Mbr->PartRec[Idx].SizeInLba;
+ gBS->CopyMem(HdDp.Signature, &Mbr->UniqueMbrSig, sizeof(UINT32));
+
+ // create device path
+ PData.DevPath = DPAddNode(DevicePath, &HdDp.Header);
+
+ // save pertinent info
+ PData.StartingLba = Mbr->PartRec[Idx].StartingLba;
+ PData.EndingLba = Mbr->PartRec[Idx].StartingLba
+ + Mbr->PartRec[Idx].SizeInLba - 1;
+
+ // Store Parent Handle
+ PData.ParentHandle = ControllerHandle;
+
+ // if the OSType member is 0xEF is this variable set.
+ // otherwise it is left as 0
+ if (Mbr->PartRec[Idx].OSType == 0xEF)
+ gBS->CopyMem(&PData.PartGuid, &gMbrPartition,
+ sizeof (EFI_GUID));
+
+ // This is a valid GPT partition: Add a child instance
+ Status = CreateChildHandle(This, &PData, BlockIo->Media->BlockSize);
+
+ }
+ }
+
+ gBS->FreePool(Mbr);
+ gBS->FreePool(ExtPart);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Mbr.h b/Core/CORE_DXE/Partition/Mbr.h
new file mode 100644
index 0000000..2aa5123
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Mbr.h
@@ -0,0 +1,171 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.h 7 7/09/09 5:01p Oleksiyy $
+//
+// $Revision: 7 $
+//
+// $Date: 7/09/09 5:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Mbr.h $
+//
+// 7 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 6 1/08/08 3:10p Robert
+//
+// 5 1/08/08 3:08p Robert
+//
+// 4 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 3 4/25/07 11:53a Robert
+// Updated for CHM and Coding Standard Compliance
+//
+// 2 4/24/05 12:45a Felixp
+// Definitions of SIGNATURE_TYPE_xxx macroses removed since they are
+// already defined in DevicePath.h
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <Mbr.h>
+//
+// Description: EFI Mbr Partition Generic Driver Header. This header
+// contains Data structures and Definitions needed to recognize
+// partitions in an MBR
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _MBR_H
+#define _MBR_H
+
+#define MBR_SIGNATURE 0xaa55
+#define NUM_MBR_PARTITIONS 4
+
+// Type definitions for the Hard drive device path
+#define MBR_TYPE_MASTER_BOOT_RECORD 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+// Needed Partition Type definitions for MBR
+#define NO_PARTITION 0x0
+#define EXTENDED_PARTITION 0x05
+#define WIN95_EXTENDED_PARTITION 0x0f
+
+
+//<AMI_GHDR_START>
+//------------------------------------------------------------------
+// Name: Data_Structures
+//
+// Description:
+// Data Structures needed for MBR
+//
+// MASTER_BOOT_RECORD - Data Structure definition of the
+// MBR located in the first block on an MBR drive
+//
+// MBR_PARTITION - Data Structure definition for each
+// partition in the MBR
+//
+//------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+#pragma pack(1)
+
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: MBR_PARTITION
+//
+// Description: Data Structure that defines a partition within the MBR
+//
+// Fields:
+// BootIndicator - UINT8 - indicates whether this partition is bootable
+// StartHead - UINT8 - unused in EFI
+// StartSector - UINT8 - unused in EFI
+// StartTrack - UINT8 - unused in EFI
+// OSType - UINT8 - defines type of the partition
+// EndHead - UINT8 - unused in EFI
+// EndSector - UINT8 - unused in EFI
+// EndTrack - UINT8 - unused in EFI
+// StartingLba - UINT32 - LBA where the partiton starts on the hard drive
+// SizeInLba - UINT32 - LBA where the partiton ends on the hard drive
+//
+// Referral:
+// None
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct _MBR_PARTITION
+{
+ UINT8 BootIndicator;
+ UINT8 StartHead;
+ UINT8 StartSector;
+ UINT8 StartTrack;
+ UINT8 OSType;
+ UINT8 EndHead;
+ UINT8 EndSector;
+ UINT8 EndTrack;
+ UINT32 StartingLba;
+ UINT32 SizeInLba;
+} MBR_PARTITION;
+
+
+// MBR Partition table
+//============================================================================
+// Structure: MASTER_BOOT_RECORD
+//
+// Description: Data Structure that mimicks the structure of a Master Boot
+// Record on a hard drive
+//
+// Fields:
+// BootCode[440] - UINT8 - executable code in the first 440 bytes of a
+// hard drive
+// UniqueMbrSig - UINT32 - Uniques signature associated with the hard
+// drive
+// Unknown - UINT16 - an unknown portion of the data structure
+// PartRec[4] - MBR_PARTITION - an array of partition entries that
+// define the partitions that exist on the hard drive
+// Sig - UINT16 - 0xaa55 - value that indicates this is an MBR
+//
+// Referral:
+// MBR_PARTITION
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct _MASTER_BOOT_RECORD
+{
+ UINT8 BootCode[440];
+ UINT32 UniqueMbrSig;
+ UINT16 Unknown;
+ MBR_PARTITION PartRec[4];
+ UINT16 Sig;
+} MASTER_BOOT_RECORD;
+
+
+#pragma pack()
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Partition.c b/Core/CORE_DXE/Partition/Partition.c
new file mode 100644
index 0000000..78cbb10
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.c
@@ -0,0 +1,1006 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.c 21 10/27/11 3:57p Artems $
+//
+// $Revision: 21 $
+//
+// $Date: 10/27/11 3:57p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.c $
+//
+// 21 10/27/11 3:57p Artems
+// EIP 73250: Verified DriverBinding Stop function frees all resources
+// allocated by Start function
+//
+// 20 10/25/11 12:01p Artems
+// EIP 70530: Fixed bugs reported by SCT 2.3.1
+//
+// 19 8/12/11 12:16p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 18 5/02/11 5:58p Artems
+// EIP 59571: Extended partition driver functionality - support of BlockIO
+// protocol version 3
+//
+// 17 2/05/11 3:52p Artems
+// Removed previous check-in changes
+//
+// 16 1/06/11 5:59p Oleksiyy
+// [TAG] EIP28607
+// [Category] Improvement
+// [Description] System was hanging for some time if Floppy Media
+// removed while writing in meda in progress.
+// EFI_TPL_CALLBACK priority level rised during media related calls.
+// [Files] DiskIo.c, Info.c, MediaAccess.c, Open.c, Partition.c
+//
+// 15 2/04/10 3:06p Oleksiyy
+// EIP 31633 Minor fixes. OpenProtocol error status handling added to
+// DriverBindingStop function.
+//
+// 14 8/28/09 9:10a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 13 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 12 1/16/09 11:25a Felixp
+// Bug fix in the DriverBindingStop function.
+// The stop function was unconditionally closing disk I/O protocol.
+// The protocol should only be closed when no child devices exist.
+//
+// 11 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 10 4/26/07 9:32a Robert
+// Updated for CHM and Coding Standard compliance
+//
+// 8 3/23/07 5:13p Robert
+// More coding standard changes and updated the copyright date
+//
+// 7 3/22/07 5:39p Robert
+// Updated Files for coding standard
+//
+// 6 10/10/06 3:43p Yakovlevs
+// Uncommented GPT Partition discovery
+//
+// 5 8/24/06 12:34p Felixp
+// x64 support (fixes for warnings/errors)
+//
+// 3 10/28/05 8:36p Felixp
+// DriverBindingSupported: Device Path test changed from BY_DRIVER to
+// TEST_PROTOCOL
+//
+// 2 2/08/05 12:50p Felixp
+// Bug fix in ReadBlocks and WriteBlocks: attemp to read/write
+// Last LBA on the partition returned EFI_INVALID_PARAMETER
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Partition.c
+//
+// Description: EFI Partition Generic Driver. Provides the Driver
+// Binding protocol and a Block I/O protocol for Partition detection
+// and interaction
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//;-------------------------------------------------------------------------
+// Includes
+#include "partition.h"
+
+
+//;-------------------------------------------------------------------------
+// Global Variables
+EFI_BOOT_SERVICES *gBS;
+EFI_GUID gUnusedPartitionGuid = EFI_PART_TYPE_UNUSED_GUID;
+static EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+
+EFI_STATUS gDevicePathStatus = EFI_SUCCESS;
+EFI_STATUS gDiskIoStatus = EFI_SUCCESS;
+
+//;-------------------------------------------------------------------------
+//GUID Variables
+static EFI_GUID gDevicePathGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+EFI_GUID gBlockIoGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+EFI_GUID gDiskIoGuid = EFI_DISK_IO_PROTOCOL_GUID;
+
+//;-------------------------------------------------------------------------
+// Function Prototypes
+EFI_STATUS DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS EFIAPI DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS EFIAPI DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer);
+
+EFI_STATUS Reset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification);
+
+EFI_STATUS ReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS WriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS FlushBlocks ( IN EFI_BLOCK_IO_PROTOCOL *PartBlockIo);
+
+//;-------------------------------------------------------------------------
+// Protocol Definition
+EFI_BLOCK_IO_PROTOCOL mPartitionBlockIo =
+{
+ EFI_BLOCK_IO_PROTOCOL_REVISION3,
+ NULL,
+ Reset,
+ ReadBlocks,
+ WriteBlocks,
+ FlushBlocks
+};
+
+
+//;-------------------------------------------------------------------------
+// Partition Driver Binding Procol
+EFI_DRIVER_BINDING_PROTOCOL gPartitionDriverBinding =
+{
+ DriverBindingSupported,
+ DriverBindingStart,
+ DriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+
+//;-------------------------------------------------------------------------
+// Function Definitions
+#ifdef EFI_DEBUG
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+//Driver Name
+static UINT16 *gDriverName=L"AMI Partition Driver";
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+//
+// Procedure: ComponentNameGetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Input:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL
+// instance.
+// ControllerHandle - The handle of a controller that the driver specified
+// by This is managing. This handle specifies the controller whose
+// name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It will be
+// NULL for device drivers. It will also be NULL for a bus drivers
+// that wish to retrieve the name of the bus controller. It will
+// not be NULL for a bus driver that wishes to retrieve the name of
+// a child controller.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the controller name that that the caller
+// is requesting, and it must match one of the languages specified
+// in Supported Languages. The number of languages supported by a
+// driver is up to the driver writer.
+//
+// Output:
+// ControllerName - A pointer to the Unicode string to return. This
+// Unicode string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language specified by
+// Language from the point of view of thedriver specified by This.
+//
+// Returns:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver specified by This
+// was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by ControllerHandle and
+// ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+// Referrals:
+//
+// Notes:
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: ComponentNameGetDriverName
+//
+// Description: Returns the Driver Name if the language is supported
+//
+// Input:
+// This - Pointer to the instance of this driver
+// Language - Current operating language
+// DriverName - return parameter that will contain the Driver's Name
+//
+// Output: DriverName - return parameter that will contain the Driver's Name
+//
+// Returns:
+// EFI_SUCCESS - Driver loaded
+// EFI_INVALID_PARAMETER - If the Language or DriverName variable is
+// not defined
+// EFI_UNSUPPORTED - If the current laungage is not supported
+//
+// Referrals:
+//
+// Notes:
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS ComponentNameGetDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName)
+{
+ //Supports only English
+ if (!Language || !DriverName) return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//Component Name Protocol
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName =
+{
+ ComponentNameGetDriverName,
+ ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+#endif
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: PartitionEntryPoint
+//
+// Description: Register Driver Binding protocol for this driver.
+//
+// Input:
+// ImageHandle - Identification Handle for the Partition
+// Block I/O driver
+// *SystemTable - Pointer to the EFI System Table
+//
+// Returns:
+// EFI_SUCCESS - Driver Binding Protocol Loaded
+// other - Driver Binding Protocol not loaded
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PartitionEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ gBS = SystemTable->BootServices;
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gPartitionDriverBinding.DriverBindingHandle = NULL;
+ gPartitionDriverBinding.ImageHandle = ImageHandle;
+
+ // Install driver binding protocol here
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &gPartitionDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gPartitionDriverBinding,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid, &gComponentName,
+#endif
+ NULL);
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: DriverBindingSupported
+//
+// Description: Test to see if this driver supports ControllerHandle. Any
+// ControllerHandle than contains a BlockIo and DiskIo protocol can be
+// supported.
+//
+// Input:
+// This - Protocol instance pointer.
+// ControllerHandle - Handle of device to test
+// RemainingDevicePath - Not used
+//
+// Output: None
+//
+// Returns:
+// EFI_SUCCESS - This driver supports this device
+// EFI_ALREADY_STARTED - This driver is already running on this device
+// other - This driver does not support this device
+//
+// Referrals: OpenProtocol CloseProtocol
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_STATUS Status;
+
+ // see if the DevicePath is installed on controllerHandle
+ Status = gBS->OpenProtocol(ControllerHandle, &gDevicePathGuid,
+ NULL, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Close the Device Path Protocol once the tests have been done
+ gBS->CloseProtocol(ControllerHandle, &gDevicePathGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ // see if the DiskIo has already been started on controllerHandle
+ Status = gBS->OpenProtocol(ControllerHandle, &gDiskIoGuid,
+ &DiskIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Close the DiskIo protocol once the tests have been done
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ // Now check for BlockIo Protocol
+ Status = gBS->OpenProtocol(ControllerHandle, &gBlockIoGuid,
+ NULL, This->DriverBindingHandle, ControllerHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ // return the status of finding the BlockIo protocol.
+ // if it gets this far the driver supports this device
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: DriverBindingStart
+//
+// Description: Start this driver on ControllerHandle by opening a Block IO and
+// Disk IO protocol, reading Device Path, and creating a child handle with
+// a Disk IO and device path protocol.
+//
+// Input:
+// This - Protocol instance pointer.
+// ControllerHandle - Handle of device to bind driver to
+// RemainingDevicePath - Not used
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - This driver is added to DeviceHandle
+// other - This driver does not support this device
+//
+// Referrals: OpenProtocol CloseProtocol GptDiscoverPartitions
+// ElToritoCreateChildHandle MbrCreateChildHandle
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS EFIAPI DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+
+ // Open the BlockIo protocol first because we are opening it by
+ // GET_PROTOCOL, if this fails it does not need to be closed. It is
+ // opened by GET_PROTOCOL because DiskIo already opens it BY_DRIVER
+ Status = gBS->OpenProtocol(ControllerHandle, &gBlockIoGuid,
+ &BlockIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status))
+ return Status;
+
+ Status = gBS->OpenProtocol(ControllerHandle, &gDevicePathGuid,
+ &ParentDevicePath, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status))
+ return Status;
+
+ // Check to see if the Controller has already been started by
+ // another driver
+ // Now open the DiskIo protocol for the controller
+ Status = gBS->OpenProtocol(ControllerHandle, &gDiskIoGuid,
+ &DiskIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if (EFI_ERROR (Status))
+ {
+ // if there is an error, close all opened protocols, only close
+ // this one if
+ // Close the Device Path protocol once the tests have been done
+ gBS->CloseProtocol(ControllerHandle, &gDevicePathGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ return Status;
+ }
+
+
+ // parse the devices and create the child handles
+ if (BlockIo->Media->MediaPresent == TRUE)
+ {
+ Status = EFI_NOT_FOUND;
+
+ // search for the children
+ Status = GptDiscoverPartitions(This, BlockIo, DiskIo,
+ ParentDevicePath, ControllerHandle);
+
+ if (EFI_ERROR(Status))
+ Status = ElToritoCreateChildHandle(This, BlockIo, DiskIo,
+ ParentDevicePath, ControllerHandle);
+
+ if (EFI_ERROR(Status))
+ Status = MbrCreateChildHandle(This, BlockIo, DiskIo,
+ ParentDevicePath, ControllerHandle);
+ }
+
+ else
+ Status = EFI_NO_MEDIA;
+
+
+ // Now close all protocols That were not already started
+ if (EFI_ERROR(Status) )
+ {
+ gBS->CloseProtocol(ControllerHandle, &gDevicePathGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ControllerHandle);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: DriverBindingStop
+//
+// Description: Stop this driver on ControllerHandle. Support stoping
+// any child handles created by this driver.
+//
+// Input:
+// This - Protocol instance pointer.
+// DeviceHandle - Handle of device to stop driver on
+// NumberOfChildren - Number of Children in the ChildHandleBuffer
+// ChildHandleBuffer - List of handles for the children we need to stop.
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - This driver is removed DeviceHandle
+// other - This driver was not removed from this device
+//
+// Referrals: CloseProtocol OpenProtocol FlushBlocks MemCmp FreePool
+// UninstallMultipleProtocolInterfaces
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS EFIAPI DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+
+ EFI_HANDLE Handle = *ChildHandleBuffer;
+ PARTITION_DATA *Child = NULL;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_GUID *PartType = NULL;
+ BOOLEAN ChildrenLeft = FALSE;
+ EFI_STATUS Status;
+ UINTN Idx = 0;
+
+
+ // Close these protocols if there are no children left
+ if (NumberOfChildren == 0)
+ {
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ControllerHandle);
+
+ return EFI_SUCCESS;
+ }
+
+ // There are children, uninstall protocols and uninstall interfaces,
+ // and free memory
+ while (Idx < NumberOfChildren)
+ {
+ Status = gBS->OpenProtocol(ChildHandleBuffer[Idx], &gBlockIoGuid,
+ (VOID **)&BlockIo, This->DriverBindingHandle,
+ ControllerHandle, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(Status))
+ {
+ Idx++;
+ continue;
+ }
+
+ Child = (PARTITION_DATA *)BlockIo;
+
+ // clear all buffers for the current device
+ BlockIo->FlushBlocks(BlockIo);
+
+ // now close all handles
+ gBS->CloseProtocol(ControllerHandle, &gDiskIoGuid,
+ This->DriverBindingHandle, ChildHandleBuffer[Idx]);
+
+ // look for a non 0 Partition type GUID
+ // if non zero, set the point to the address, otherwise leave pointer
+ // as zero
+ if (MemCmp(&Child->PartGuid, &gUnusedPartitionGuid, sizeof(EFI_GUID)))
+ PartType = &Child->PartGuid;
+
+ // Create the new handle for the child device
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Idx],
+ &gDevicePathGuid, Child->DevPath,
+ &gBlockIoGuid, &Child->BlockIo,
+ PartType, NULL,
+ NULL );
+
+ if (EFI_ERROR(Status))
+ ChildrenLeft = TRUE;
+
+ // free the memory that was allocated for The Child handle and the
+ // device path for the child handle
+
+
+ if (Child->DevPath != NULL)
+ gBS->FreePool(Child->DevPath);
+
+ if (Child->BlockIo.Media != NULL)
+ gBS->FreePool(Child->BlockIo.Media);
+
+ gBS->FreePool(Child);
+
+
+ // Increment Child Handle Pointer
+ Idx++;
+
+ // clear PartGuid pointer for the next child
+ PartType = NULL;
+ }
+
+ // if there are childrem left, exit with error
+ if (ChildrenLeft == TRUE)
+ return EFI_DEVICE_ERROR;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: Reset
+//
+// Description: Reset the parent Block Device.
+//
+// Input:
+// This - Protocol instance pointer.
+// ExtendedVerification - Driver may perform diagnostics on reset.
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - The device was reset.
+// EFI_DEVICE_ERROR - The device is not functioning properly and could
+// not be reset.
+//
+// Referrals: ParentBlockIo->Reset
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Reset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ PARTITION_DATA *PartData;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Find the parent's BlockIo Protocol
+ PartData = (PARTITION_DATA *) This;
+
+ return PartData->ParentBlockIo->Reset(PartData->ParentBlockIo,
+ ExtendedVerification);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: ReadBlocks
+//
+// Description: Reads blocks from the parent device
+//
+// Input:
+// This - Protocol instance pointer.
+// MediaId - Id of the media, changes every time the media is replaced.
+// Lba - The starting Logical Block Address to read from
+// BufferSize - Size of Buffer, must be a multiple of device block size.
+//
+// Output:
+// Buffer - Buffer containing read data
+//
+// Return:
+// EFI_SUCCESS - The data was read correctly from the device.
+// EFI_DEVICE_ERROR - The device reported an error while performing the read.
+// EFI_NO_MEDIA - There is no media in the device.
+// EFI_MEDIA_CHANGED - The MediaId does not match the current device.
+// EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
+// device.
+// EFI_INVALID_PARAMETER - The read request contains device addresses that are not
+// valid for the device.
+//
+// Referrals: Mul64 ReadDisk
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadBlocks ( IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ PARTITION_DATA *PartData;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINT64 Start;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Find the parent BlockIo Protocol
+ PartData = (PARTITION_DATA *) This;
+
+ if(MediaId != PartData->BlockIo.Media->MediaId)
+ return EFI_MEDIA_CHANGED;
+
+ if(BufferSize == 0)
+ return EFI_SUCCESS;
+
+ if (BufferSize % PartData->BlockIo.Media->BlockSize != 0)
+ return EFI_BAD_BUFFER_SIZE;
+
+ // calculate the byte from which to start the read
+ Start = (Mul64(PartData->StartingLba,
+ PartData->ParentBlockIo->Media->BlockSize) +
+ Mul64(Lba, This->Media->BlockSize));
+
+ // check to see if the read will go beyond the end of the
+ // current partition
+ if ( ((Start + BufferSize - 1) >=
+ Mul64(PartData->EndingLba+1,
+ PartData->ParentBlockIo->Media->BlockSize)) ||
+ (Buffer == NULL))
+ return EFI_INVALID_PARAMETER;
+
+
+ // Make call directly to DiskIo of the device
+
+ DiskIo = PartData->ParentDiskIo;
+
+ return DiskIo->ReadDisk(DiskIo, MediaId, Start, BufferSize, Buffer);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: WriteBlocks
+//
+// Description: Write blocks to the parent device
+//
+// Input:
+// This - Protocol instance pointer.
+// MediaId - Id of the media, changes every time the media is replaced.
+// Lba - The starting Logical Block Address to read from
+// BufferSize - Size of Buffer, must be a multiple of device block size.
+// Buffer - Buffer containing read data
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - The data was written correctly to the device.
+// EFI_WRITE_PROTECTED - The device can not be written to.
+// EFI_DEVICE_ERROR - The device reported an error while performing the write.
+// EFI_NO_MEDIA - There is no media in the device.
+// EFI_MEDIA_CHANGED - The MediaId does not match the current device.
+// EFI_BAD_BUFFER_SIZE - The Buffer was not a multiple of the block size of the
+// device.
+// EFI_INVALID_PARAMETER - The write request contains a LBA that is not
+// valid for the device.
+//
+// Referrals: Mul64 WriteDisk
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+)
+{
+ PARTITION_DATA *PartData;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ UINT64 Start;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Find the parent BlockIo Protocol
+ PartData = (PARTITION_DATA *) This;
+
+ if(MediaId != PartData->BlockIo.Media->MediaId)
+ return EFI_MEDIA_CHANGED;
+
+ if (BufferSize % PartData->BlockIo.Media->BlockSize != 0)
+ return EFI_BAD_BUFFER_SIZE;
+
+ // calculated the start address of the write command
+ Start = Mul64(PartData->StartingLba,
+ PartData->ParentBlockIo->Media->BlockSize) +
+ Mul64(Lba, This->Media->BlockSize);
+
+ if ( ((Start + BufferSize - 1) >=
+ Mul64(PartData->EndingLba+1,
+ PartData->ParentBlockIo->Media->BlockSize)) ||
+ (Buffer == NULL))
+ return EFI_INVALID_PARAMETER;
+
+ DiskIo = PartData->ParentDiskIo;
+
+ return DiskIo->WriteDisk(DiskIo, MediaId, Start, BufferSize, Buffer);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: FlushBlocks
+//
+// Description: Flush the parent Block Device.
+//
+// Input: This - Protocol instance pointer.
+//
+// Output: None
+//
+// Return:
+// EFI_SUCCESS - All outstanding data was written to the device
+// EFI_DEVICE_ERROR - The device reported an error while writing back
+// the data
+// EFI_NO_MEDIA - There is no media in the device.
+//
+// Referrals: ParentBlockIo->FlushBlocks
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+)
+{
+ PARTITION_DATA *PartData;
+
+ if (This == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ PartData = (PARTITION_DATA *) This;
+
+ // return the same value that the device specific BlockIo instance returns
+ return PartData->ParentBlockIo->FlushBlocks(PartData->ParentBlockIo);
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+// Procedure: CreateChildHandle
+//
+// Description: Generic create child handle for the partition driver. This
+// should work for GPT, MBR, and El Torito.
+//
+// Input:
+// *This - Pointer to the current instance of the blockIo protocol
+// *PData - a pointer to the start of the private data structure for
+// the partition
+// BlockSize - the blocksize for the partition
+//
+// Output:
+//
+// Return:
+// EFI_SUCCESS - Child created
+// other - no child created
+//
+// Referrals: AllocatePool FreePool CopyMem MemCmp Div64 OpenProtocol
+// InstallMultipleProtocolInterfaces UninstallMultipleProtocolInterfaces
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateChildHandle(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN PARTITION_DATA *PData,
+ IN UINT32 BlockSize
+)
+{
+ PARTITION_DATA *Child;
+ EFI_BLOCK_IO_MEDIA *Media;
+ EFI_STATUS Status;
+ EFI_GUID *PartType = NULL;
+ UINTN Temp;
+
+
+ // allocate memory for the Child handle
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(PARTITION_DATA), &Child);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ Status = gBS->AllocatePool(EfiBootServicesData, sizeof(EFI_BLOCK_IO_MEDIA), &Media);
+ if (EFI_ERROR(Status)) {
+ gBS->FreePool(Child);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Copy the data from one location to the other,
+ gBS->CopyMem(Child, PData, sizeof(PARTITION_DATA));
+
+ // get the BlockIo protocol for the partition driver and the
+ // media information from the parent device
+ gBS->CopyMem(&Child->BlockIo, &mPartitionBlockIo, sizeof(EFI_BLOCK_IO_PROTOCOL));
+
+ // just point to the media info for the device, that way we don't have to
+ // worry about changing values
+ Child->BlockIo.Media = Media;
+
+ gBS->CopyMem(Media, PData->ParentBlockIo->Media, sizeof(EFI_BLOCK_IO_MEDIA));
+
+ Media->LogicalPartition = TRUE;
+ Media->BlockSize = BlockSize;
+ Media->IoAlign = 1; //no alignment requirements
+ Media->LowestAlignedLba = 0; //added in Revision 2
+ Media->LogicalBlocksPerPhysicalBlock = 0; //added in Revision 2
+ Media->OptimalTransferLengthGranularity = 0; //added in Revision 3
+
+ // Calculate the last block of the partition
+ Media->LastBlock = Div64( Mul64(PData->EndingLba - PData->StartingLba + 1,
+ Child->ParentBlockIo->Media->BlockSize),
+ BlockSize, &Temp) - 1;
+
+ // look for a non 0 Partition type GUID
+ // if non zero, set the point to the address, otherwise leave
+ // pointer as zero
+ if (MemCmp(&Child->PartGuid, &gUnusedPartitionGuid, sizeof(EFI_GUID)))
+ PartType = &Child->PartGuid;
+
+ // Create the new handle for the child device
+ Child->Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Child->Handle,
+ &gDevicePathGuid, Child->DevPath,
+ &gBlockIoGuid, &Child->BlockIo,
+ PartType, NULL,
+ NULL );
+
+ // Now open the diskIo protocol for the child, if the install multiple
+ // protocol interface returns SUCCESS
+ if (!EFI_ERROR(Status)) {
+ Status = gBS->OpenProtocol ( Child->ParentHandle,
+ &gDiskIoGuid,
+ &Child->ParentDiskIo,
+ This->DriverBindingHandle,
+ Child->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+ if (EFI_ERROR(Status)) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ &Child->Handle,
+ &gDevicePathGuid, Child->DevPath,
+ &gBlockIoGuid, &Child->BlockIo,
+ PartType, NULL,
+ NULL );
+ //free all resources
+ gBS->FreePool(Child->DevPath);
+ gBS->FreePool(Media);
+ gBS->FreePool(Child);
+ }
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Partition.cif b/Core/CORE_DXE/Partition/Partition.cif
new file mode 100644
index 0000000..feaa5cb
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Partition"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\Partition\"
+ RefName = "Partition"
+[files]
+"Partition.sdl"
+"ElTorito.c"
+"ElTorito.h"
+"Gpt.c"
+"Gpt.h"
+"Mbr.c"
+"Mbr.h"
+"Partition.c"
+"Partition.h"
+<endComponent>
diff --git a/Core/CORE_DXE/Partition/Partition.h b/Core/CORE_DXE/Partition/Partition.h
new file mode 100644
index 0000000..047cfc8
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.h
@@ -0,0 +1,188 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.h 10 8/12/11 12:16p Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 8/12/11 12:16p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/Partition/Partition.h $
+//
+// 10 8/12/11 12:16p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 9 7/09/09 5:01p Oleksiyy
+// Files clean-up
+//
+// 8 1/08/08 2:47p Robert
+//
+// 7 1/08/08 2:47p Robert
+//
+// 6 1/07/08 4:21p Robert
+// Updated for coding standard
+//
+// 5 4/25/07 12:44p Robert
+// updates for CHM and Coding Standard Compliance
+//
+// 3 4/24/05 12:45a Felixp
+// Definitions of SIGNATURE_TYPE_xxx macroses removed since they are
+// already defined in DevicePath.h
+//
+// 6 12/14/04 6:14p Robert
+// Added component name protocol support
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Partition.h
+//
+// Description: EFI Partition Generic Driver Header. This file
+// contains the GUIDs used by this driver. It also contains
+// Definitions and Data Structures needed by the generic portion of
+// the Partition driver.
+//
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _PARTITION_H
+#define _PARTITION_H
+
+
+#include <AmiDxeLib.h>
+
+// protocols consumed
+#include <protocol\BlockIo.h>
+#include <protocol\DiskIo.h>
+#include <protocol\DevicePath.h>
+#include <protocol\DriverBinding.h>
+#include <Protocol\ComponentName2.h>
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_GUID gUnusedPartitionGuid;
+
+//=============================================================================
+// GUID Definitions
+
+#define EFI_PART_TYPE_UNUSED_GUID \
+ { 0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+#define EFI_PART_TYPE_EFI_SYSTEM_PART_GUID \
+ { 0xc12a7328, 0xf81f, 0x11d2, 0xba, 0x4b, 0x00, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b}
+
+#define EFI_PART_TYPE_LEGACY_MBR_GUID \
+ { 0x024dee41, 0x33e7, 0x11d3, 0x9d, 0x69, 0x00, 0x08, 0xc7, 0x81, 0xf3, 0x9f}
+
+
+
+#define MBR_TYPE_PCAT 0x01
+#define MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+#define EFI_SYSTEM_PARTITION 0xef
+
+
+//=============================================================================
+// Structure definitions
+
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: OPCODE_CMD
+//
+// Description: Data Structure definition of the Private data for each instance
+// of the Partition Block I/O driver
+//
+// Fields:
+// BlockIo - EFI_BLOCK_IO_PROTOCOL - Pointer to the EFI_BLOCK_IO_PROTOCOL
+// protocol for this partition
+// Handle - EFI_HANDLE - child handle for this partition
+// ParentBlockIo - EFI_BLOCK_IO_PROTOCOL * - pointer to the
+// EFI_BLOCK_IO_PROTOCOL of the parent device
+// ParentDiskIo - EFI_DISK_IO_PROTOCOL * - pointer to the
+// EFI_DISK_IO_PROTOCOL of the parent device
+// DevPath - EFI_DEVICE_PATH_PROTOCOL * - pointer to the device path
+// for this device
+// StartingLba - EFI_LBA - The starting Lba of the current partition
+// EndingLba - EFI_LBA - The ending Lba of the current partition
+// PartGuid - EFI_GUID - The GUID assigned to the partition
+// ParentHandle - EFI_HANDLE - the handle assigned to the parent device
+//
+// Referral:
+// None
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct _PARTITION_DATA
+{
+ EFI_BLOCK_IO_PROTOCOL BlockIo;
+ EFI_HANDLE Handle;
+ EFI_BLOCK_IO_PROTOCOL *ParentBlockIo;
+ EFI_DISK_IO_PROTOCOL *ParentDiskIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+
+ EFI_LBA StartingLba;
+ EFI_LBA EndingLba;
+ EFI_GUID PartGuid;
+
+ EFI_HANDLE ParentHandle;
+} PARTITION_DATA;
+
+
+//=============================================================================
+// Function Prototypes
+EFI_STATUS CreateChildHandle(EFI_DRIVER_BINDING_PROTOCOL *This, PARTITION_DATA *PData,
+ UINT32 BlockSize);
+
+EFI_STATUS GptDiscoverPartitions (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+);
+
+EFI_STATUS ElToritoCreateChildHandle (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+);
+
+EFI_STATUS MbrCreateChildHandle(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_BLOCK_IO_PROTOCOL *BlockIo,
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_HANDLE ControllerHandle
+);
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/Partition/Partition.sdl b/Core/CORE_DXE/Partition/Partition.sdl
new file mode 100644
index 0000000..a846251
--- /dev/null
+++ b/Core/CORE_DXE/Partition/Partition.sdl
@@ -0,0 +1,4 @@
+PATH
+ Name = "PARTITION_DIR"
+End
+
diff --git a/Core/CORE_DXE/SetWatchdogTimer.c b/Core/CORE_DXE/SetWatchdogTimer.c
new file mode 100644
index 0000000..2146137
--- /dev/null
+++ b/Core/CORE_DXE/SetWatchdogTimer.c
@@ -0,0 +1,84 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ SetWatchdogTimer.c
+
+Abstract:
+
+ Tiano Miscellaneous Services SetWatchdogTimer service implementation
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+#define WATCHDOG_TIMER_CALIBRATE_PER_SECOND 10000000
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreSetWatchdogTimer (
+ IN UINTN Timeout,
+ IN UINT64 WatchdogCode,
+ IN UINTN DataSize,
+ IN CHAR16 *WatchdogData OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Sets the system's watchdog timer.
+
+Arguments:
+
+ Timeout The number of seconds. Zero disables the timer.
+
+ ///////following three parameters are left for platform specific using
+
+ WatchdogCode The numberic code to log. 0x0 to 0xffff are firmware
+ DataSize Size of the optional data
+ WatchdogData Optional Null terminated unicode string followed by binary
+ data.
+
+Returns:
+
+ EFI_SUCCESS Timeout has been set
+ EFI_NOT_AVAILABLE_YET WatchdogTimer is not available yet
+ EFI_UNSUPPORTED System does not have a timer (currently not used)
+ EFI_DEVICE_ERROR Could not complete due to hardware error
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Check our architectural protocol
+ //
+ if (gWatchdogTimer == NULL) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ //
+ // Attempt to set the timeout
+ //
+ Status = gWatchdogTimer->SetTimerPeriod (gWatchdogTimer, MultU64x32 (Timeout, WATCHDOG_TIMER_CALIBRATE_PER_SECOND));
+
+ //
+ // Check for errors
+ //
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/Stall.c b/Core/CORE_DXE/Stall.c
new file mode 100644
index 0000000..a87f894
--- /dev/null
+++ b/Core/CORE_DXE/Stall.c
@@ -0,0 +1,79 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Stall.c
+
+Abstract:
+
+ Tiano Miscellaneous Services Stall service implementation
+
+--*/
+
+//
+// Include statements
+//
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreStall (
+ IN UINTN Microseconds
+ )
+/*++
+
+Routine Description:
+
+ Introduces a fine-grained stall.
+
+Arguments:
+
+ Microseconds The number of microseconds to stall execution
+
+Returns:
+
+ EFI_SUCCESS - Execution was stalled for at least the requested amount
+ of microseconds.
+
+ EFI_NOT_AVAILABLE_YET - gMetronome is not available yet
+
+--*/
+{
+ UINT32 Counter;
+ UINTN Remainder;
+
+ if (gMetronome == NULL) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ //
+ // Calculate the number of ticks by dividing the number of microseconds by
+ // the TickPeriod.
+ // Calcullation is based on 100ns unit.
+ //
+ Counter = (UINT32) DivU64x32 ((Microseconds * 10), (UINTN) gMetronome->TickPeriod, &Remainder);
+
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Remainder != 0) {
+ Counter++;
+ }
+
+ gMetronome->WaitForTick (gMetronome, Counter);
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/USFontPack.c b/Core/CORE_DXE/USFontPack.c
new file mode 100644
index 0000000..e4d86a0
--- /dev/null
+++ b/Core/CORE_DXE/USFontPack.c
@@ -0,0 +1,315 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/DxeMain/USFontPack.c 4 4/11/12 5:13p Artems $
+//
+// $Revision: 4 $
+//
+// $Date: 4/11/12 5:13p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/DxeMain/USFontPack.c $
+//
+// 4 4/11/12 5:13p Artems
+// [TAG] EIP81654
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Right arrow (>) is shown as junk in Bios setup when
+// Font.ffs is not used
+// [RootCause] Size of default font package was incorrect
+// [Solution] Changed value for size of font package
+// [Files] usfontpack.c
+//
+// 3 7/11/05 4:52p Felixp
+// minor bug fix: number of characters was invalid so the last character
+// was ignored
+//
+// 2 3/04/05 9:30a Mandal
+//
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <This File Name>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//Package for US Latin Glyps + Box Draw and Arrows
+unsigned char UsStdNarrowGlyphData[] = {
+ 0xc0, 0x14, 0x00, 0x00,//Header.Length
+ 0x01, 0x00, //Header.Type 1=Font
+ 0xf1, 0x00, //Number of Narrow Glyphs
+ 0x00, 0x00, //Number of Wide Glyphs
+ // Unicode glyphs from 0x20 to 0x7e are the same as ASCII characters 0x20 to 0x7e
+ 0x20, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x21, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x3C,0x3C,0x3C,0x18,0x18,0x18,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0x22, 0x00, 0x00, 0x00,0x00,0x00,0x6C,0x6C,0x6C,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x23, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0xFE,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,
+ 0x24, 0x00, 0x00, 0x00,0x00,0x18,0x18,0x7C,0xC6,0xC6,0x60,0x38,0x0C,0x06,0xC6,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00,
+ 0x25, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x60,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x26, 0x00, 0x00, 0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0x78,0x76,0xDC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0x27, 0x00, 0x00, 0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x28, 0x00, 0x00, 0x00,0x00,0x00,0x06,0x0C,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x0C,0x0C,0x06,0x00,0x00,0x00,0x00,
+ 0x29, 0x00, 0x00, 0x00,0x00,0x00,0xC0,0x60,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0x60,0xC0,0x00,0x00,0x00,0x00,
+ 0x2a, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x38,0xFE,0x38,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x2b, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x2c, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
+ 0x2d, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x2e, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+ 0x2f, 0x00, 0x00, 0x00,0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x60,0xC0,0xC0,0x00,0x00,0x00,0x00,
+ 0x30, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xD6,0xD6,0xC6,0xC6,0xC6,0x6C,0x38,0x00,0x00,0x00,0x00,
+ 0x31, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00,0x00,
+ 0x32, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x0C,0x18,0x30,0x60,0xC0,0xC2,0xFE,0x00,0x00,0x00,0x00,
+ 0x33, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0x06,0x06,0x06,0x3C,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x34, 0x00, 0x00, 0x00,0x00,0x00,0x1C,0x1C,0x3C,0x3C,0x6C,0x6C,0xCC,0xFE,0x0C,0x0C,0x0C,0x1E,0x00,0x00,0x00,0x00,
+ 0x35, 0x00, 0x00, 0x00,0x00,0x00,0xFE,0xC0,0xC0,0xC0,0xC0,0xFC,0x06,0x06,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x36, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x60,0xC0,0xC0,0xC0,0xFC,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x37, 0x00, 0x00, 0x00,0x00,0x00,0xFE,0xC6,0x06,0x06,0x06,0x0C,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0x38, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x39, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x06,0x06,0x06,0x0C,0x78,0x00,0x00,0x00,0x00,
+ 0x3a, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+ 0x3b, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x30,0x00,0x00,0x00,0x00,
+ 0x3c, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x60,0xC0,0x60,0x30,0x18,0x0C,0x06,0x00,0x00,0x00,0x00,
+ 0x3d, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x3e, 0x00, 0x00, 0x00,0x00,0x00,0x00,0xC0,0x60,0x30,0x18,0x0C,0x06,0x0C,0x18,0x30,0x60,0xC0,0x00,0x00,0x00,0x00,
+ 0x3f, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0xC6,0x0C,0x0C,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0x40, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xDE,0xDE,0xDE,0xDC,0xC0,0xC0,0x7E,0x00,0x00,0x00,0x00,
+ 0x41, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x42, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x66,0x66,0x66,0x66,0x66,0xFC,0x00,0x00,0x00,0x00,
+ 0x43, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x00,0x00,0x00,0x00,
+ 0x44, 0x00, 0x00, 0x00,0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
+ 0x45, 0x00, 0x00, 0x00,0x00,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+ 0x46, 0x00, 0x00, 0x00,0x00,0x00,0xFE,0x66,0x62,0x60,0x64,0x7C,0x64,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+ 0x47, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xDE,0xC6,0xC6,0xC6,0x66,0x3C,0x00,0x00,0x00,0x00,
+ 0x48, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x49, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xFC,0x00,0x00,0x00,0x00,
+ 0x4a, 0x00, 0x00, 0x00,0x00,0x00,0x1E,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xCC,0xCC,0x78,0x00,0x00,0x00,0x00,
+ 0x4b, 0x00, 0x00, 0x00,0x00,0x00,0xE6,0x66,0x6C,0x6C,0x78,0x70,0x78,0x6C,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+ 0x4c, 0x00, 0x00, 0x00,0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+ 0x4d, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xEE,0xEE,0xFE,0xFE,0xD6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x4e, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xE6,0xF6,0xF6,0xF6,0xDE,0xCE,0xCE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x4f, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x50, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+ 0x51, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0x7C,0x1C,0x0E,0x00,0x00,
+ 0x52, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0x66,0x66,0x66,0x66,0x7C,0x78,0x6C,0x6C,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+ 0x53, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0x60,0x38,0x0C,0x06,0x06,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x54, 0x00, 0x00, 0x00,0x00,0x00,0xFC,0xFC,0xB4,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00,
+ 0x55, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x56, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x6C,0x38,0x10,0x00,0x00,0x00,0x00,
+ 0x57, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xD6,0xD6,0xD6,0xFE,0x6C,0x6C,0x00,0x00,0x00,0x00,
+ 0x58, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0xC6,0x6C,0x6C,0x38,0x6C,0x6C,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x59, 0x00, 0x00, 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00,
+ 0x5a, 0x00, 0x00, 0x00,0x00,0x00,0xFE,0xC6,0x86,0x0C,0x0C,0x18,0x30,0x60,0xC0,0xC2,0xC6,0xFE,0x00,0x00,0x00,0x00,
+ 0x5b, 0x00, 0x00, 0x00,0x00,0x00,0x1E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1E,0x00,0x00,0x00,0x00,
+ 0x5c, 0x00, 0x00, 0x00,0x00,0x00,0xC0,0xC0,0x60,0x60,0x30,0x30,0x18,0x18,0x0C,0x0C,0x06,0x06,0x00,0x00,0x00,0x00,
+ 0x5d, 0x00, 0x00, 0x00,0x00,0x00,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0x00,0x00,0x00,0x00,
+ 0x5e, 0x00, 0x00, 0x00,0x00,0x10,0x38,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5f, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,
+ 0x60, 0x00, 0x00, 0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x61, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0x62, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00,0x00,0x00,
+ 0x63, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x64, 0x00, 0x00, 0x00,0x00,0x00,0x1C,0x0C,0x0C,0x0C,0x3C,0x6C,0xCC,0xCC,0xCC,0xCC,0xCC,0x7E,0x00,0x00,0x00,0x00,
+ 0x65, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x66, 0x00, 0x00, 0x00,0x00,0x00,0x1E,0x33,0x30,0x30,0x30,0x78,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00,
+ 0x67, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0xCC,0x78,0x00,
+ 0x68, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x76,0x66,0x66,0x66,0x66,0x66,0xE6,0x00,0x00,0x00,0x00,
+ 0x69, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0x6a, 0x00, 0x00, 0x00,0x00,0x00,0x0C,0x0C,0x0C,0x00,0x1C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x6C,0x38,0x00,
+ 0x6b, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x60,0x60,0x66,0x6C,0x78,0x70,0x78,0x6C,0x6C,0x66,0xE6,0x00,0x00,0x00,0x00,
+ 0x6c, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0x6d, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0xEE,0xFE,0xD6,0xD6,0xD6,0xD6,0xD6,0x00,0x00,0x00,0x00,
+ 0x6e, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+ 0x6f, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x70, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
+ 0x71, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x7C,0x0C,0x0C,0x1E,0x00,
+ 0x72, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDC,0x66,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00,0x00,0x00,
+ 0x73, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0x7C,0x06,0x06,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0x74, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x30,0x30,0x30,0xFC,0x30,0x30,0x30,0x30,0x30,0x36,0x1C,0x00,0x00,0x00,0x00,
+ 0x75, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0x76, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x30,0x00,0x00,0x00,0x00,
+ 0x77, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xD6,0xD6,0xFE,0xEE,0x6C,0x00,0x00,0x00,0x00,
+ 0x78, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0x79, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
+ 0x7a, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x86,0x0C,0x18,0x30,0x60,0xC0,0xFE,0x00,0x00,0x00,0x00,
+ 0x7b, 0x00, 0x00, 0x00,0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x30,0x18,0x18,0x18,0x18,0x18,0x0E,0x00,0x00,0x00,0x00,
+ 0x7c, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0x7d, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x30,0x30,0x30,0x30,0x18,0x30,0x30,0x30,0x30,0x30,0xE0,0x00,0x00,0x00,0x00,
+ 0x7e, 0x00, 0x00, 0x00,0x00,0x00,0x76,0xDC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xa0, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xa1, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x18,0x00,0x18,0x18,0x18,0x18,0x18,0x3C,0x3C,0x3C,0x18,0x00,0x00,0x00,0x00,
+ 0xa2, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x18,0x18,0x7C,0xC6,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0xa3, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x6C,0x64,0x60,0x60,0xF0,0x60,0x60,0x60,0x60,0xE6,0xFC,0x00,0x00,0x00,0x00,
+ 0xa4, 0x00, 0x00, 0x00,0x00,0x18,0x00,0x00,0x00,0xC6,0x7C,0xC6,0xC6,0xC6,0xC6,0x7C,0xC6,0x00,0x00,0x00,0x00,0x00,
+ 0xa5, 0x00, 0x00, 0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x18,0x7E,0x18,0x7E,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0xa6, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,
+ 0xa7, 0x00, 0x00, 0x00,0x00,0x18,0x7C,0xC6,0x60,0x38,0x6C,0xC6,0xC6,0x6C,0x38,0x0C,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xa8, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xa9, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x7C,0x82,0x9A,0xA2,0xA2,0xA2,0x9A,0x82,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xaa, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x3C,0x6C,0x6C,0x6C,0x3E,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xab, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x6C,0xD8,0x6C,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xac, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0x06,0x06,0x06,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xad, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xae, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x7C,0x82,0xB2,0xAA,0xAA,0xB2,0xAA,0xAA,0x82,0x7C,0x00,0x00,0x00,0x00,0x00,
+ 0xaf, 0x00, 0x00, 0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xb0, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x6C,0x6C,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xb1, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x7E,0x18,0x18,0x00,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,
+ 0xb2, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x66,0x0C,0x18,0x32,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xb3, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0x06,0x3C,0x06,0x06,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xb4, 0x00, 0x00, 0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xb5, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xC0,0x00,
+ 0xb6, 0x00, 0x00, 0x00,0x00,0x00,0x7F,0xDB,0xDB,0xDB,0xDB,0x7B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x00,0x00,0x00,0x00,
+ 0xb7, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xb8, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x0C,0x78,0x00,0x00,0x00,
+ 0xb9, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xba, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x38,0x6C,0x6C,0x6C,0x38,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xbb, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD8,0x6C,0x36,0x6C,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xbc, 0x00, 0x00, 0x00,0x00,0x00,0x60,0xE0,0x62,0x66,0x6C,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x06,0x00,0x00,0x00,
+ 0xbd, 0x00, 0x00, 0x00,0x00,0x00,0x60,0xE0,0x62,0x66,0x6C,0x18,0x30,0x60,0xDC,0x86,0x0C,0x18,0x3E,0x00,0x00,0x00,
+ 0xbe, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x30,0x62,0x36,0xEC,0x18,0x30,0x66,0xCE,0x9A,0x3F,0x06,0x06,0x00,0x00,0x00,
+ 0xbf, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x30,0x30,0x60,0x60,0xC0,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xc0, 0x00, 0x00, 0x60,0x30,0x18,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xc1, 0x00, 0x00, 0x18,0x30,0x60,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xc2, 0x00, 0x00, 0x10,0x38,0x6C,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xc3, 0x00, 0x00, 0x76,0xDC,0x00,0x00,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xc4, 0x00, 0x00, 0xCC,0xCC,0x00,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xc5, 0x00, 0x00, 0x38,0x6C,0x38,0x00,0x10,0x38,0x6C,0xC6,0xC6,0xC6,0xFE,0xC6,0xC6,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xc6, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x3E,0x6C,0xCC,0xCC,0xCC,0xFE,0xCC,0xCC,0xCC,0xCC,0xCE,0x00,0x00,0x00,0x00,
+ 0xc7, 0x00, 0x00, 0x00,0x00,0x00,0x3C,0x66,0xC2,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC2,0x66,0x3C,0x18,0x70,0x00,0x00,
+ 0xc8, 0x00, 0x00, 0x60,0x30,0x18,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+ 0xc9, 0x00, 0x00, 0x18,0x30,0x60,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+ 0xca, 0x00, 0x00, 0x10,0x38,0x6C,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+ 0xcb, 0x00, 0x00, 0xCC,0xCC,0x00,0x00,0xFE,0x66,0x62,0x60,0x68,0x78,0x68,0x60,0x62,0x66,0xFE,0x00,0x00,0x00,0x00,
+ 0xcc, 0x00, 0x00, 0x60,0x30,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xcd, 0x00, 0x00, 0x18,0x30,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xce, 0x00, 0x00, 0x10,0x38,0x6C,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xcf, 0x00, 0x00, 0xCC,0xCC,0x00,0x00,0x3C,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xd0, 0x00, 0x00, 0x00,0x00,0x00,0xF8,0x6C,0x66,0x66,0x66,0xF6,0x66,0x66,0x66,0x66,0x6C,0xF8,0x00,0x00,0x00,0x00,
+ 0xd1, 0x00, 0x00, 0x76,0xDC,0x00,0x00,0xC6,0xE6,0xE6,0xF6,0xF6,0xDE,0xDE,0xCE,0xCE,0xC6,0xC6,0x00,0x00,0x00,0x00,
+ 0xd2, 0x00, 0x00, 0x60,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xd3, 0x00, 0x00, 0x18,0x30,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xd4, 0x00, 0x00, 0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xd5, 0x00, 0x00, 0x76,0xDC,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xd6, 0x00, 0x00, 0xCC,0xCC,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xd7, 0x00, 0x00, 0x10,0x28,0x00,0x00,0x00,0x00,0x00,0xC6,0x6C,0x38,0x38,0x6C,0x6C,0xC6,0x00,0x00,0x00,0x00,0x00,
+ 0xd8, 0x00, 0x00, 0x00,0x00,0x00,0x7C,0xCE,0xCE,0xDE,0xD6,0xD6,0xD6,0xD6,0xF6,0xE6,0xE6,0x7C,0x40,0x00,0x00,0x00,
+ 0xd9, 0x00, 0x00, 0x60,0x30,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xda, 0x00, 0x00, 0x18,0x30,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xdb, 0x00, 0x00, 0x10,0x38,0x6C,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xdc, 0x00, 0x00, 0xCC,0xCC,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xdd, 0x00, 0x00, 0x18,0x30,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3C,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xde, 0x00, 0x00, 0x00,0x00,0x10,0x00,0xF0,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0xF0,0x00,0x00,0x00,0x00,
+ 0xdf, 0x00, 0x00, 0x00,0x00,0x00,0x78,0xCC,0xCC,0xCC,0xCC,0xD8,0xCC,0xC6,0xC6,0xC6,0xC6,0xCC,0x00,0x00,0x00,0x00,
+ 0xe0, 0x00, 0x00, 0x00,0x30,0x30,0x60,0x30,0x18,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xe1, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x30,0x60,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xe2, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xe3, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xe4, 0x00, 0x00, 0x00,0x00,0x00,0xCC,0xCC,0x00,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xe5, 0x00, 0x00, 0x00,0x00,0x00,0x38,0x6C,0x38,0x00,0x78,0x0C,0x0C,0x7C,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xe6, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xEC,0x36,0x36,0x7E,0xD8,0xD8,0xD8,0x6E,0x00,0x00,0x00,0x00,
+ 0xe7, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xC6,0xC0,0xC0,0xC0,0xC0,0xC6,0x7C,0x18,0x70,0x00,0x00,
+ 0xe8, 0x00, 0x00, 0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xe9, 0x00, 0x00, 0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xea, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xeb, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xFE,0xC0,0xC0,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xec, 0x00, 0x00, 0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xed, 0x00, 0x00, 0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xee, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x3C,0x66,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xef, 0x00, 0x00, 0x00,0x00,0x00,0x66,0x66,0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00,0x00,0x00,
+ 0xf0, 0x00, 0x00, 0x00,0x00,0x00,0x34,0x18,0x2C,0x0C,0x06,0x3E,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00,0x00,0x00,
+ 0xf1, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0xDC,0x66,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+ 0xf2, 0x00, 0x00, 0x00,0x00,0x00,0x60,0x30,0x18,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xf3, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x30,0x60,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xf4, 0x00, 0x00, 0x00,0x00,0x00,0x10,0x38,0x6C,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xf5, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x76,0xDC,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xf6, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xf7, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x7E,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xf8, 0x00, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0xCE,0xDE,0xD6,0xF6,0xE6,0xC6,0x7C,0x00,0x00,0x00,0x00,
+ 0xf9, 0x00, 0x00, 0x00,0x00,0x00,0x60,0x30,0x18,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xfa, 0x00, 0x00, 0x00,0x00,0x00,0x18,0x30,0x60,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xfb, 0x00, 0x00, 0x00,0x00,0x00,0x30,0x78,0xCC,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xfc, 0x00, 0x00, 0x00,0x00,0x00,0xCC,0xCC,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x76,0x00,0x00,0x00,0x00,
+ 0xfd, 0x00, 0x00, 0x00,0x00,0x00,0x0C,0x18,0x30,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0xF8,0x00,
+ 0xfe, 0x00, 0x00, 0x00,0x00,0x00,0xE0,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60,0xF0,0x00,
+ 0xff, 0x00, 0x00, 0x00,0x00,0x00,0xC6,0xC6,0x00,0x00,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0xC6,0x7E,0x06,0x0C,0x78,0x00,
+ 0x00, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x02, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x0c, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x10, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x14, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x18, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x1c, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x24, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x2c, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x34, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x3c, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x50, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x51, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x52, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x53, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x54, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x55, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x56, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x57, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x58, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x59, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5a, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5b, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5c, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5d, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x5e, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1F,0x18,0x1F,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x5f, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x60, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x37,0x30,0x37,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x61, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF8,0x18,0xF8,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x62, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x63, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF6,0x06,0xF6,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x64, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x65, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x66, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x67, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x68, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x69, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x6a, 0x25, 0x00, 0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xFF,0x18,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
+ 0x6b, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xFF,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x6c, 0x25, 0x00, 0x36,0x36,0x36,0x36,0x36,0x36,0x36,0xF7,0x00,0xF7,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,0x36,
+ 0x88, 0x25, 0x00, 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
+ 0x91, 0x25, 0x00, 0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,0x88,0x22,
+ 0xba, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0xC0,0xE0,0xF0,0xF8,0xFE,0xF8,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x00,
+ 0xc4, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x06,0x0E,0x1E,0x3E,0xFE,0x3E,0x1E,0x0E,0x06,0x00,0x00,0x00,0x00,0x00,
+ 0xb2, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x38,0x38,0x7C,0x7C,0xFE,0xFE,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0xbc, 0x25, 0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,0x7C,0x7C,0x38,0x38,0x10,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x91, 0x21, 0x00, 0x00,0x00,0x00,0x18,0x3C,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,
+ 0x93, 0x21, 0x00, 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,
+ 0x90, 0x21, 0x00, 0x00,0x00,0x00,0x00,0x00,0x20,0x60,0x60,0xFE,0xFE,0x60,0x60,0x20,0x00,0x00,0x00,0x00,0x00,0x00,
+ 0x92, 0x21, 0x00, 0x00,0x00,0x00,0x00,0x00,0x08,0x0C,0x0C,0xFE,0xFE,0x0C,0x0C,0x08,0x00,0x00,0x00,0x00,0x00,0x00
+};
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiAccessConfig.c b/Core/CORE_DXE/UefiHii/HiAccessConfig.c
new file mode 100644
index 0000000..d165a1e
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiAccessConfig.c
@@ -0,0 +1,322 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiAccessConfig.c 7 5/04/11 12:08p Artems $
+//
+// $Revision: 7 $
+//
+// $Date: 5/04/11 12:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiAccessConfig.c $
+//
+// 7 5/04/11 12:08p Artems
+// Bug fix: when variable is absent attribute state was undefined
+//
+// 6 1/25/11 4:03p Artems
+// EIP 51298: Fixed corruption in buffer size after passing it to
+// ConfigToBlock function
+// Added check for correct syntax of request string in ExtractConfig
+// function
+//
+// 5 9/30/10 6:12p Artems
+// Removed unnecessary service functions
+//
+// 3 2/19/10 4:01p Felixp
+// Debug messages are removed.
+//
+// 2 11/25/09 11:25a Felixp
+// Action parameter of the Callback function is updated based on UEFI
+// errata
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HiiAccessConfig.c
+//
+// Description: Hii Config Access protocol implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include <Protocol/HiiConfigAccess.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#include "HiiPrivate.h"
+
+extern const NAME_PATTERN GuidPattern;
+extern const NAME_PATTERN NamePattern;
+extern const NAME_PATTERN PathPattern;
+extern const NAME_PATTERN AltCfgPattern;
+extern const NAME_PATTERN OffsetPattern;
+extern const NAME_PATTERN WidthPattern;
+extern const NAME_PATTERN ValuePattern;
+extern const CHAR16 HexDigit[];
+
+UINTN EfiStrLen (IN CHAR16 *String);
+UINTN EfiStrSize (IN CHAR16 *String);
+VOID EfiStrCat (IN CHAR16 *Destination, IN CHAR16 *Source);
+
+//**************************** Protocol functions implementation ***************************
+
+
+EFI_STATUS HiiAccessExtractConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ EFI_GUID Guid;
+ CHAR16 Name[80];
+ CHAR16 *Pointer = Request;
+ UINT8 *Var = NULL;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
+ CHAR16 *ErrorMarker;
+
+ if(Request == NULL) {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &ConfigRouting);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//check syntax for guid
+ if(!CheckPattern(Request, &GuidPattern)) {
+ *Progress = Request;
+ return EFI_INVALID_PARAMETER;
+ }
+//extract guid
+ ErrorMarker = Pointer;
+ Pointer += 5; //skip "GUID=" pattern
+ Length = 32; //length of guid in symbols
+ StringToBlock(Pointer, Length, (UINT8 *)&Guid);
+ Pointer += Length;
+ if(*Pointer != L'&') {
+ TRACE((TRACE_DXE_CORE, "HII Extract Config: Guid extraction failed\n"));
+ *Progress = ErrorMarker;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//check syntax for name
+ if(!CheckPattern(Pointer + 1, &NamePattern)) {
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+//extract name
+ ErrorMarker = Pointer;
+ Pointer += 6; //skip '&NAME=' pattern
+ Length = 80;
+ StringToChar16(Pointer, &Length, Name);
+ Pointer += (Length * 4);
+ if(*Pointer != L'&') {
+ TRACE((TRACE_DXE_CORE, "HII Extract Config: Name extraction failed\n"));
+ *Progress = ErrorMarker;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//get variable by name and guid from nvram
+
+ Length = 0;
+ Status = GetEfiVariable(Name, &Guid, NULL, &Length, &Var);
+ if(EFI_ERROR(Status)) {
+ *Progress = Request;
+ return Status;
+ }
+
+//find start of OFFSET/WIDTH/VALUE block
+ Pointer++; //skip '&'
+ while((*Pointer != L'&') && (*Pointer != 0)) //skip PATH
+ Pointer++;
+
+ if(*Pointer == 0) { //OFFSET/WIDTH blocks are missed
+ UINTN TempSize;
+ CHAR16 *TempString;
+ CHAR16 *TempString2;
+
+ TempSize = (EfiStrLen(L"&OFFSET=0&WIDTH=") + sizeof(Length) + 1) * sizeof(CHAR16);
+ TempString = MallocZ(TempSize);
+ if(TempString == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ Swprintf_s(TempString, TempSize, L"&OFFSET=0&WIDTH=%x", Length);
+
+ TempSize += EfiStrSize(Request);
+ TempString2 = MallocZ(TempSize);
+ if(TempString2 == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ EfiStrCat(TempString2, Request);
+ EfiStrCat(TempString2, TempString);
+
+ Status = ConfigRouting->BlockToConfig(ConfigRouting, TempString2, Var, Length, Results, Progress);
+ *Progress = Request + EfiStrLen(Request); //set Progress to end of ConfigHdr
+ pBS->FreePool(TempString);
+ pBS->FreePool(TempString2);
+ } else { //OFFSET/WIDTH block found, let's check if it's correct
+ if(!CheckPattern(Pointer + 1, &OffsetPattern)) {
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = ConfigRouting->BlockToConfig(ConfigRouting, Request, Var, Length, Results, Progress);
+ }
+
+ pBS->FreePool(Var);
+
+ return Status;
+}
+
+EFI_STATUS HiiAccessRouteConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ UINTN VarSize;
+ EFI_GUID Guid;
+ CHAR16 Name[80];
+ CHAR16 *Pointer = Configuration;
+ UINT8 *Var = NULL;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
+ EFI_HANDLE Handle;
+ UINT32 Attributes;
+
+ if(Configuration == NULL)
+ {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &ConfigRouting);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//check syntax for guid
+ if(!CheckPattern(Configuration, &GuidPattern))
+ {
+ *Progress = Configuration;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//check proper device path
+ Status = FindDeviceHandle(Configuration, &Handle);
+ if(EFI_ERROR(Status))
+ return EFI_NOT_FOUND;
+
+//extract guid
+ Pointer += 5; //skip "GUID=" pattern
+ Length = 32; //length of guid in bytes
+ StringToBlock(Pointer, Length, (UINT8 *)&Guid);
+ Pointer += Length;
+ if(*Pointer != L'&')
+ {
+ TRACE((TRACE_DXE_CORE, "HII Route Config: Guid extraction failed\n"));
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//check syntax for name
+ if(!CheckPattern(Pointer + 1, &NamePattern))
+ {
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+//extract name
+ Pointer += 6; //skip '&NAME=' pattern
+ Length = 80;
+ StringToChar16(Pointer, &Length, Name);
+ Pointer += (Length * 4);
+ if(*Pointer != L'&')
+ {
+ TRACE((TRACE_DXE_CORE, "HII Route Config: Name extraction failed\n"));
+ *Progress = Pointer;
+ return EFI_INVALID_PARAMETER;
+ }
+
+//get variable by name and guid from nvram
+
+ Length = 0;
+ Status = GetEfiVariable(Name, &Guid, &Attributes, &Length, &Var);
+ if(EFI_ERROR(Status)) //requested variable not found
+ {
+ Var = NULL;
+ Length = 0;
+ Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ }
+ VarSize = Length;
+
+ Status = ConfigRouting->ConfigToBlock(ConfigRouting, Configuration, Var, &Length, Progress);
+ while(Status == EFI_DEVICE_ERROR) //block not large enough
+ {
+ if(Var != NULL)
+ pBS->FreePool(Var);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, Length, &Var);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ VarSize = Length;
+ Status = ConfigRouting->ConfigToBlock(ConfigRouting, Configuration, Var, &Length, Progress);
+ }
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ pRS->SetVariable(Name, &Guid, Attributes, VarSize, Var);
+
+ pBS->FreePool(Var);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiAccessFormCallback(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/Hii.chm b/Core/CORE_DXE/UefiHii/Hii.chm
new file mode 100644
index 0000000..b2affb3
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/Hii.chm
Binary files differ
diff --git a/Core/CORE_DXE/UefiHii/HiiConfig.c b/Core/CORE_DXE/UefiHii/HiiConfig.c
new file mode 100644
index 0000000..8a8b10a
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiConfig.c
@@ -0,0 +1,1263 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiConfig.c 10 6/16/11 12:52p Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 6/16/11 12:52p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiConfig.c $
+//
+// 10 6/16/11 12:52p Artems
+// Bugfix: Handle situation when string passed to BlockToConfig function
+// doesn't have standard header
+//
+// 9 5/13/11 5:17p Artems
+// Function CompareGuid (native EdkII) renamed to HiiCompareGuid to avoid
+// collusion
+//
+// 8 5/09/11 6:40p Artems
+// Bugfix: Handle situation when config string passed to ConfigToBlock
+// function doesn't have standard header
+//
+// 7 1/25/11 3:26p Artems
+// EIP 47960 : Added functionality for ExportConfig function
+//
+// 6 11/05/10 5:17p Artems
+// EIP 46880: Fixed bug, where two functions referred to the same global
+// pointer
+//
+// 4 10/01/10 4:36p Artems
+// Added service function StripValuePattern
+//
+// 2 12/03/09 6:02p Artems
+// SCT test bug fix
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HiiConfig.c
+//
+// Description: Hii Config Routing protocol implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+
+const NAME_PATTERN GuidPattern = { 10, L"GUID=" };
+const NAME_PATTERN NamePattern = { 10, L"NAME=" };
+const NAME_PATTERN PathPattern = { 10, L"PATH=" };
+const NAME_PATTERN AltCfgPattern = { 14, L"ALTCFG=" };
+const NAME_PATTERN OffsetPattern = { 14, L"OFFSET=" };
+const NAME_PATTERN WidthPattern = { 12, L"WIDTH=" };
+const NAME_PATTERN ValuePattern = { 12, L"VALUE=" };
+
+const CHAR16 HexDigit[] = { L'0', L'1', L'2', L'3', L'4', L'5', L'6', L'7',
+ L'8', L'9', L'a', L'b', L'c', L'd', L'e', L'f' };
+
+EFI_GUID HiiConfigAccessProtocolGuid = EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID;
+
+#define INITIAL_RESULT_STRING_SIZE 0x1000
+
+
+
+//**************************** Protocol functions implementation ***************************
+
+EFI_STATUS HiiExtractConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Request1,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+)
+{
+ EFI_STRING ConfigString;
+ EFI_STRING ErrorPointer;
+ EFI_STRING ResultPointer;
+ BOOLEAN LastString = FALSE;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ UINTN ProgressMarker = 0;
+ UINTN Gap;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_STRING Request = Request1;
+ RESULT_BLOCK Result;
+
+ if(Progress == NULL || Results == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(Request == NULL)
+ {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(!CheckPattern(Request, &GuidPattern))
+ {
+ *Progress = Request;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = InitResultBlock(&Result);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ do
+ {
+ Status = ExtractConfigString(Request, &Index, &ConfigString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(ConfigString != NULL)
+ {
+ Status = FindDeviceHandle(ConfigString, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Request[ProgressMarker];
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Request[ProgressMarker];
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = ConfigAccess->ExtractConfig(ConfigAccess, ConfigString,
+ &ErrorPointer, &ResultPointer);
+ if(EFI_ERROR(Status))
+ {
+ Gap = (UINTN)(ErrorPointer - ConfigString); //determine offset of error
+ pBS->FreePool(ConfigString);
+ *Progress = &Request[ProgressMarker + Gap];
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ ProgressMarker += Index; //shift to next config string
+ Request += Index;
+ pBS->FreePool(ConfigString);
+ Status = CollectResults(ResultPointer, 0, &Result);
+ if (EFI_ERROR(Status))
+ return Status;
+ pBS->FreePool(ResultPointer);
+ }
+ else //now we process last request
+ {
+ LastString = TRUE;
+ Status = FindDeviceHandle(Request, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ *Progress = Request;
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ *Progress = Request;
+ *Results = Result.ResultString;
+ return Status;
+ }
+
+ Status = ConfigAccess->ExtractConfig(ConfigAccess, Request,
+ &ErrorPointer, &ResultPointer);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = ErrorPointer;
+ *Results = Result.ResultString;
+ return Status;
+ }
+ Status = CollectResults(ResultPointer, 0, &Result);
+ if (EFI_ERROR(Status))
+ return Status;
+ pBS->FreePool(ResultPointer);
+ }
+ } while(!LastString);
+
+ *Results = Result.ResultString;
+
+//set Progress to null-terminator
+ Index = StrSize16(Request) / 2;
+ *Progress = &Request[Index - 1];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS Hii21ExportConfigHelper (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+);
+
+EFI_STATUS HiiExportConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+)
+{
+ if(Results == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ return Hii21ExportConfigHelper (This, Results);
+}
+
+EFI_STATUS HiiRouteConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration1,
+ OUT EFI_STRING *Progress
+)
+{
+ EFI_STRING ConfigString;
+ EFI_STRING ErrorPointer;
+ BOOLEAN LastString = FALSE;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_HANDLE Handle;
+ UINTN ProgressMarker = 0;
+ UINTN Gap;
+ EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
+ EFI_STRING Configuration = Configuration1;
+
+ if(Progress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(Configuration == NULL)
+ {
+ *Progress = NULL;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(!CheckPattern(Configuration, &GuidPattern))
+ {
+ *Progress = Configuration;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do
+ {
+ Status = ExtractConfigString(Configuration, &Index, &ConfigString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(ConfigString != NULL)
+ {
+ Status = FindDeviceHandle(ConfigString, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Configuration[ProgressMarker];
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ pBS->FreePool(ConfigString);
+ *Progress = &Configuration[ProgressMarker];
+ return Status;
+ }
+
+ Status = ConfigAccess->RouteConfig(ConfigAccess, ConfigString, &ErrorPointer);
+ if(EFI_ERROR(Status))
+ {
+ Gap = (UINTN)(ErrorPointer - ConfigString); //determine offset of error
+ pBS->FreePool(ConfigString);
+ *Progress = &Configuration[ProgressMarker + Gap];
+ return Status;
+ }
+
+ ProgressMarker += Index; //shift to next config string
+ Configuration += Index;
+ pBS->FreePool(ConfigString);
+ }
+ else //now we process last cofiguration
+ {
+ LastString = TRUE;
+ Status = FindDeviceHandle(Configuration, &Handle);
+ if(EFI_ERROR(Status)) //we failed to find corresponding driver handle
+ {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(Handle, &HiiConfigAccessProtocolGuid, &ConfigAccess);
+ if(EFI_ERROR(Status)) //we failed to find corresponding protocol
+ {
+ *Progress = Configuration;
+ return Status;
+ }
+
+ Status = ConfigAccess->RouteConfig(ConfigAccess, Configuration, &ErrorPointer);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = ErrorPointer;
+ return Status;
+ }
+ }
+ } while(!LastString);
+
+//set Progress to null-terminator
+ Index = StrSize16(Configuration) / 2;
+ *Progress = &Configuration[Index - 1];
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiBlockToConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigRequest,
+ IN CONST UINT8 *Block,
+ IN CONST UINTN BlockSize,
+ OUT EFI_STRING *Config,
+ OUT EFI_STRING *Progress
+)
+{
+ UINTN ProgressMarker;
+ UINTN i = 0;
+ UINTN Start;
+ UINT32 Offset;
+ UINT32 Width;
+ UINT32 ConfigStringSize;
+ EFI_STATUS Status;
+ RESULT_BLOCK Result;
+
+ if(Progress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ConfigRequest == NULL || Block == NULL || Config == NULL )
+ {
+ *Progress = ConfigRequest;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConfigStringSize = StrSize16(ConfigRequest) / 2;
+
+//Prepare result buffer for output
+ Status = InitResultBlock(&Result);
+ if (EFI_ERROR(Status))
+ return Status;
+
+//find start of OFFSET/WIDTH/VALUE block
+ if(!CheckPattern(ConfigRequest, &OffsetPattern)) { //for BlockToConfig function ConfigResp is allowed not to have standard header GUID=...NAME=.
+ do
+ {
+ while((ConfigRequest[i] != L'&') && (ConfigRequest[i] != 0))
+ i++;
+
+ if(ConfigRequest[i] == 0)
+ {
+ *Progress = ConfigRequest;
+ pBS->FreePool(Result.ResultString);
+ return EFI_NOT_FOUND;
+ }
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigRequest[i], &OffsetPattern))
+ break;
+ } while(1);
+ }
+
+ Status = CollectResults(ConfigRequest, i, &Result); //copy header
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+
+ do
+ {
+ ProgressMarker = i - 1; //set ProgressMarker to '&'
+
+ Start = i;
+ Status = GetPatternValue(ConfigRequest, &i, &OffsetPattern, &Offset);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigRequest[ProgressMarker];
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ else
+ {
+ Status = CollectResults(&ConfigRequest[Start], i - Start, &Result); //copy header
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ }
+
+ Start = i;
+ Status = GetPatternValue(ConfigRequest, &i, &WidthPattern, &Width);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigRequest[ProgressMarker];
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ else
+ {
+ Status = CollectResults(&ConfigRequest[Start], i - Start, &Result); //copy header
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+ }
+
+ if(BlockSize < (Offset + Width))
+ {
+ pBS->FreePool(Result.ResultString);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = CollectValueResults(&Block[Offset], Width, &Result);
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Result.ResultString);
+ return Status;
+ }
+
+ } while(i < ConfigStringSize);
+
+ *Progress = &ConfigRequest[ConfigStringSize - 1]; //set Progress to null-terminator
+ *Config = Result.ResultString;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiConfigToBlock (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN OUT CONST UINT8 *Block,
+ IN OUT UINTN *BlockSize,
+ OUT EFI_STRING *Progress
+)
+{
+ UINTN ProgressMarker;
+ UINTN i = 0;
+ UINT32 Offset;
+ UINT32 Width;
+ UINT32 ConfigStringSize;
+ EFI_STATUS Status;
+
+ if(Progress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ConfigResp == NULL || BlockSize == NULL )
+ {
+ *Progress = ConfigResp;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(Block == NULL && *BlockSize != NULL )
+ {
+ *Progress = ConfigResp;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ConfigStringSize = StrSize16(ConfigResp) / 2;
+
+//find start of OFFSET/WIDTH/VALUE block
+ if(!CheckPattern(ConfigResp, &OffsetPattern)) { //for ConfigToBlock function ConfigResp is allowed not to have standard header GUID=...NAME=.
+ do {
+ while((ConfigResp[i] != L'&') && (ConfigResp[i] != 0))
+ i++;
+
+ if(ConfigResp[i] == 0) {
+//TODO: should it be like this???
+//Intel's style - if there is no OFFSET/WIDTH/VALUE blocks - return EFI_SUCCESS
+/*
+ *Progress = ConfigResp;
+ return EFI_NOT_FOUND;
+*/
+ *Progress = &ConfigResp[i];
+ return EFI_SUCCESS;
+ }
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigResp[i], &OffsetPattern))
+ break;
+ } while(1);
+ }
+
+ do
+ {
+ ProgressMarker = i - 1; //set ProgressMarker to '&'
+
+ Status = GetPatternValue(ConfigResp, &i, &OffsetPattern, &Offset);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigResp[ProgressMarker];
+ return Status;
+ }
+
+ Status = GetPatternValue(ConfigResp, &i, &WidthPattern, &Width);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigResp[ProgressMarker];
+ return Status;
+ }
+
+//provided block is too small to accumulate value
+ if(*BlockSize < (Offset + Width))
+ {
+ *BlockSize = Offset + Width;
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = GetStringValue(ConfigResp, &i, &Block[Offset], Width);
+ if(EFI_ERROR(Status))
+ {
+ *Progress = &ConfigResp[ProgressMarker];
+ return Status;
+ }
+
+ } while(i < ConfigStringSize);
+
+ *BlockSize = Offset + Width - 1; //set index of last updated byte
+ *Progress = &ConfigResp[ConfigStringSize - 1]; //set Progress to null-terminator
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HiiGetAltConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId,
+ OUT EFI_STRING *AltCfgResp
+)
+{
+ BOOLEAN LastString = FALSE;
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN StrSize;
+ EFI_STRING ConfigString = ConfigResp;
+
+
+ if(ConfigResp == NULL || AltCfgResp == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(!CheckPattern(ConfigString, &GuidPattern))
+ return EFI_INVALID_PARAMETER;
+
+ do {
+ Status = ExtractConfigString(ConfigString, &Index, AltCfgResp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(*AltCfgResp != NULL) {
+ Status = CheckAltCfg(*AltCfgResp, Guid, Name, DevicePath, AltCfgId);
+ if(!EFI_ERROR(Status))
+ return Status;
+
+ ConfigString += Index;
+ pBS->FreePool(*AltCfgResp);
+ } else {
+ LastString = TRUE;
+ StrSize = StrSize16(ConfigString);
+ Status = pBS->AllocatePool(EfiBootServicesData, StrSize, AltCfgResp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(*AltCfgResp, ConfigString, StrSize);
+ Status = CheckAltCfg(*AltCfgResp, Guid, Name, DevicePath, AltCfgId);
+ if(EFI_ERROR(Status))
+ pBS->FreePool(*AltCfgResp);
+
+ return Status;
+
+ }
+ } while(!LastString);
+
+ return EFI_NOT_FOUND;
+}
+
+// *************************** Service functions (not for public use) **********************
+
+VOID StringToBlock(
+ IN CHAR16 *String,
+ IN UINTN StringSize,
+ OUT UINT8 *Block)
+{
+ UINT8 LowNibble, HiNibble;
+ UINTN i, j;
+
+ j = 0;
+
+ for(i = 0; i < StringSize; i += 2)
+ {
+ if(i == StringSize - 1) { //odd number need to fill with zeroes
+ HiNibble = 0;
+ LowNibble = HexValue((UINT8)String[i]);
+ } else {
+ HiNibble = HexValue((UINT8)String[i]);
+ LowNibble = HexValue((UINT8)String[i + 1]);
+ }
+ Block[j] = (HiNibble << 4) | LowNibble;
+ j++;
+ }
+}
+
+BOOLEAN CheckIfHexDigit(CHAR16 Char)
+{
+ if(Char < 0x30 || Char > 0x66)
+ return FALSE;
+
+ if(Char > 0x39 && Char < 0x41)
+ return FALSE;
+
+ if(Char > 0x46 && Char < 0x61)
+ return FALSE;
+
+ return TRUE;
+}
+
+UINT8 HexValue(CHAR8 Char)
+{
+ if(Char >= 0x30 && Char <= 0x39) //symbols 0...9
+ return Char - 0x30;
+
+ if(Char >= 0x41 && Char <= 0x46) //symbols A...F
+ return Char - 0x37;
+
+ return Char - 0x57; //symbols a...f
+}
+
+
+UINT32 GetValue(CHAR16 *String, UINTN Start, UINTN End)
+{
+ UINT32 Result = 0;
+ UINTN i;
+ UINT8 Nibble;
+ UINT8 NibbleCount = 0;
+
+ for(i = Start; i < End; i++)
+ {
+ Nibble = HexValue((UINT8) String[i]);
+ if(Nibble == 0 && NibbleCount == 0) //skip leading zeros
+ continue;
+
+ if(NibbleCount >= 8) //provided value exceed 4 bytes
+ return 0xffffffff;
+
+ Result <<= 4;
+ Result |= Nibble;
+ NibbleCount++;
+ }
+ return Result;
+}
+
+EFI_STATUS GetStringValue(
+ CHAR16 *String,
+ UINTN *Index,
+ UINT8 *Output,
+ UINT32 Width)
+{
+ EFI_STATUS Status;
+ UINTN Start;
+ UINTN i;
+ UINT8 *Result;
+ UINTN HexSymbolsCount;
+ UINT8 SmallBuffer[20];
+ UINTN ResultBufferSize = 20;
+
+ Start = *Index;
+
+ if(!CheckPattern(&String[Start], &ValuePattern))
+ return EFI_INVALID_PARAMETER;
+
+ Start += ValuePattern.Length / 2;
+ i = Start;
+
+ while((String[i] != L'&') && (String[i] != 0)) {
+ if(!CheckIfHexDigit(String[i]))
+ return EFI_INVALID_PARAMETER;
+ i++;
+ }
+
+ HexSymbolsCount = i - Start;
+
+ if(Width > 20) {
+ Status = pBS->AllocatePool(EfiBootServicesData, Width, &Result);
+ if(EFI_ERROR(Status))
+ return Status;
+ ResultBufferSize = Width;
+ } else {
+ Result = SmallBuffer;
+ }
+
+ MemSet(Result, ResultBufferSize, 0);
+ StringToBlock(&String[Start], HexSymbolsCount, Result);
+
+//now write the result swapped(INTEL's style)
+ if(Width > 1)
+ WriteSwappedBuffer(Output, Result, Width);
+ else
+ *Output = *Result;
+
+ if(Width > 20)
+ pBS->FreePool(Result);
+
+ i++; //skip delimiter
+
+ *Index = i;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GetPatternValue(
+ CHAR16 *String,
+ UINTN *Index,
+ NAME_PATTERN *Pattern,
+ UINT32 *Value)
+{
+ UINT32 Result;
+ UINTN Start;
+ UINTN i;
+ BOOLEAN EndPattern = FALSE;
+
+ if(Pattern->Tag[0] == L'V' || Pattern->Tag[0] == L'W')
+ EndPattern = TRUE;
+
+ Start = *Index;
+
+ if(!CheckPattern(&String[Start], Pattern))
+ return EFI_INVALID_PARAMETER;
+
+ Start += Pattern->Length / 2;
+ i = Start;
+
+ while((String[i] != L'&') && (String[i] != 0))
+ {
+ if(!CheckIfHexDigit(String[i]))
+ return EFI_INVALID_PARAMETER;
+ i++;
+ }
+
+ if(String[i] == 0 && !EndPattern) //unexpected end of string
+ return EFI_INVALID_PARAMETER;
+
+ Result = GetValue(String, Start, i);
+ i++; //skip delimiter
+
+ *Value = Result;
+ *Index = i;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS FindDeviceHandle(
+ IN CHAR16 *ConfigString,
+ OUT EFI_HANDLE *Handle)
+{
+ UINTN i = 0;
+ UINTN DpLength;
+ UINT8 *DevicePath;
+ EFI_STATUS Status;
+
+//scan config string to find PATH pattern
+ do
+ {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0)
+ return EFI_NOT_FOUND;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &PathPattern))
+ break;
+ } while(1);
+
+//if we get here, we have pointer set on PATH pattern
+ Status = ExtractDevicePath(&ConfigString[i], &DevicePath, &DpLength);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = SearchDevicePath(DevicePath, DpLength, Handle);
+ pBS->FreePool(DevicePath);
+
+ return Status;
+}
+
+EFI_STATUS ExtractDevicePath(CHAR16 *ConfigString, UINT8 **DevicePath, UINTN *DpLength)
+{
+ EFI_STATUS Status;
+ UINTN Length = 0;
+ UINTN i = 5; //set pointer to skip first four symbols "PATH="
+
+ while(CheckIfHexDigit(ConfigString[i])) //determine device path length in characters
+ {
+ Length++;
+ i++;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ (Length / 2),
+ DevicePath);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ StringToBlock(&ConfigString[5], Length, *DevicePath);
+ *DpLength = Length / 2;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS SearchDevicePath(UINT8 *DevicePath, UINTN DpLength, EFI_HANDLE *Handle)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) PrivateData.PackList.pHead;
+ PACKAGE_LINK *PackageLink;
+
+ while(Record != NULL)
+ {
+ PackageLink = (PACKAGE_LINK *) Record->PackageList.pHead;
+ while(PackageLink != NULL)
+ {
+ if(PackageLink->Package.Type == EFI_HII_PACKAGE_DEVICE_PATH)
+ {
+ if(CheckDevicePath(DevicePath, DpLength, &PackageLink->Package))
+ {
+ *Handle = Record->DriverHandle;
+ return EFI_SUCCESS;
+ }
+ }
+ PackageLink = (PACKAGE_LINK *)PackageLink->Link.pNext;
+ }
+ Record = (PACKAGE_LIST_RECORD *)Record->Link.pNext;
+ }
+ return EFI_NOT_FOUND;
+}
+
+static BOOLEAN CheckDevicePath(
+ IN UINT8 *DevicePath,
+ IN UINTN DpLength,
+ IN EFI_HII_PACKAGE_HEADER *Package)
+{
+ UINTN Length;
+ UINT8 *Dp = (UINT8 *)Package;
+
+ Dp += sizeof(EFI_HII_PACKAGE_HEADER);
+
+ Length = Package->Length - sizeof(EFI_HII_PACKAGE_HEADER);
+ if(Length != DpLength)
+ return FALSE;
+ if(MemCmp(DevicePath, Dp, Length))
+ return FALSE;
+
+ return TRUE;
+}
+
+
+EFI_STATUS ExtractConfigString(CHAR16 *String, UINTN *NextIndex, CHAR16 **NewString)
+{
+ EFI_STATUS Status;
+ UINTN i = 0;
+ CHAR16 *Eos;
+
+//scan config string to find next GUID pattern
+ do
+ {
+ while((String[i] != L'&') && (String[i] != 0))
+ i++;
+
+ if(String[i] == 0)
+ {
+ *NewString = NULL; //config string contains only one string
+ return EFI_SUCCESS;
+ }
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&String[i], &GuidPattern))
+ break;
+ } while(1);
+
+//as we are here i points to next config string
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * i,
+ NewString);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(*NewString, String, (i - 1) * 2);
+ Eos = *NewString;
+ Eos[i - 1] = 0; //put null terminator
+
+ *NextIndex = i;
+ return EFI_SUCCESS;
+}
+
+BOOLEAN CheckPattern(CHAR16 *String, NAME_PATTERN *Pattern)
+{
+ if(MemCmp(String, Pattern->Tag, Pattern->Length))
+ return FALSE;
+ else
+ return TRUE;
+}
+
+EFI_STATUS CollectResults(CHAR16 *Result, UINTN Symbols, RESULT_BLOCK *ResultBlock)
+{
+ EFI_STATUS Status;
+ UINTN StrSize;
+ CHAR16 *Helper;
+
+ StrSize = (Symbols != 0) ? Symbols : StrSize16(Result) / 2; //we need size in CHAR16, not bytes
+
+ if(ResultBlock->MaxResultStringSize < (StrSize + ResultBlock->CurrentSize))
+ {
+ Status = ReallocResultString((StrSize + ResultBlock->CurrentSize) * 2, ResultBlock);
+ if (EFI_ERROR(Status))
+ return Status;
+ }
+
+ Helper = ResultBlock->ResultString;
+ if(ResultBlock->CurrentSize != 0) //we have to change null-terminator to '&' symbol
+ Helper[ResultBlock->CurrentSize - 1] = L'&';
+
+ MemCpy(&Helper[ResultBlock->CurrentSize], Result, StrSize * sizeof(CHAR16));
+ ResultBlock->CurrentSize += StrSize;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS ReallocResultString(UINTN NewSize, RESULT_BLOCK *ResultBlock)
+{
+ CHAR16 *Pointer;
+ EFI_STATUS Status;
+
+ ResultBlock->MaxResultStringSize = NewSize;
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * ResultBlock->MaxResultStringSize,
+ &Pointer);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(Pointer, ResultBlock->ResultString, ResultBlock->CurrentSize * sizeof(CHAR16));
+ pBS->FreePool(ResultBlock->ResultString);
+ ResultBlock->ResultString = Pointer;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS CollectValueResults(UINT8* Value, UINT32 Width, RESULT_BLOCK *ResultBlock)
+{
+ CHAR16 ValueHeader[] = L"VALUE=";
+ UINT32 i;
+ UINT8 Nibble;
+ EFI_STATUS Status;
+ CHAR16 *ValueString;
+ CHAR16 *Ptr;
+ UINTN StringSize;
+
+//first determine necessary string size, including null-terminator in CHAR16 symbols
+ StringSize = Width * 2 + 6 + 1; //each byte requires two symbols plus &VALUE= size plus null terminator
+
+ Status = pBS->AllocatePool(EfiBootServicesData, StringSize * 2, &ValueString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//copy header
+ MemCpy(ValueString, ValueHeader, 12);
+ Ptr = ValueString + 6;
+
+//write value in reversed order
+ for(i = 0; i < Width; i++)
+ {
+ Nibble = Value[Width - i - 1] >> 4;
+ *Ptr++ = HexDigit[Nibble];
+ Nibble = Value[Width - i - 1] & 0xf;
+ *Ptr++ = HexDigit[Nibble];
+ }
+
+//set null-terminator
+ *Ptr = 0;
+ Status = CollectResults(ValueString, 0, ResultBlock);
+ pBS->FreePool(ValueString);
+ return Status;
+}
+
+VOID WriteSwappedBuffer(
+ OUT UINT8 *Output,
+ IN UINT8 *Input,
+ IN UINTN Size)
+{
+ UINTN i;
+
+ for(i = 0; i < Size; i++)
+ Output[i] = Input[Size - i - 1];
+}
+
+EFI_STATUS CheckAltCfg (
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId
+)
+{
+ EFI_STATUS Status;
+ UINTN i = 0;
+ UINTN j;
+ UINT32 Size;
+ UINT32 CfgId;
+
+//scan config string to find ALTCFG pattern
+ do {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0) //ALTCFG pattern not found
+ break;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &AltCfgPattern))
+ break;
+ } while(1);
+
+ if(ConfigString[i] == 0 && AltCfgId != NULL) //we have current config but needed alt one
+ return EFI_NOT_FOUND;
+
+ if(ConfigString[i] != 0 && AltCfgId == NULL) //we have alt config but needed current one
+ return EFI_NOT_FOUND;
+
+ if(ConfigString[i] != 0 && AltCfgId != NULL) {
+ j = i;
+ Status = GetPatternValue(ConfigString, &j, &AltCfgPattern, &CfgId);
+ if(EFI_ERROR(Status) || *AltCfgId != (UINT16)CfgId)
+ return EFI_NOT_FOUND; //we have alt config, but it's not matched
+
+//if we're here alt config is matched
+//we need to remove "ALTCFG=XXXX" from string as per spec but SCT expects "ALTCFG=" pattern in output string
+
+ //j already points to the next pattern
+ Size = StrSize16(&ConfigString[j]);
+ MemCpy(&ConfigString[i], &ConfigString[j], Size);
+
+ }
+
+ if(Guid != NULL && !HiiCompareGuid(ConfigString, Guid))
+ return EFI_NOT_FOUND; //guid not matched
+
+ if(Name != NULL && !CompareName(ConfigString, Name))
+ return EFI_NOT_FOUND; //name not matched
+
+ if(DevicePath != NULL && !CompareDevicePath(ConfigString, DevicePath))
+ return EFI_NOT_FOUND; //DevicePath not matched
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN HiiCompareGuid(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid
+)
+{
+ CHAR16 *Pointer = ConfigString;
+ UINTN Length;
+ EFI_GUID AltGuid;
+ EFI_GUID *VarGuid = Guid;
+
+ if(!CheckPattern(ConfigString, &GuidPattern))
+ return FALSE;
+
+ Pointer += 5; //skip "GUID=" pattern
+ Length = 32; //length of guid in symbols
+ StringToBlock(Pointer, Length, (UINT8 *)&AltGuid);
+
+ return !guidcmp(VarGuid, &AltGuid);
+}
+
+BOOLEAN CompareName(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_STRING Name
+)
+{
+ CHAR16 *Pointer = ConfigString;
+ UINTN Length;
+ CHAR16 AltName[80];
+ EFI_STRING VarName = Name;
+ UINTN i = 0;
+
+ do {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0) //NAME pattern not found
+ return FALSE;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &NamePattern))
+ break;
+ } while(1);
+
+ Pointer = &ConfigString[i];
+ Pointer += 5; //skip "NAME=" pattern
+ Length = 80; //length of name buffer
+ StringToChar16(Pointer, &Length, AltName);
+
+ return !StrCmp16(VarName, AltName);
+}
+
+BOOLEAN CompareDevicePath(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ UINTN Length;
+ EFI_DEVICE_PATH_PROTOCOL *AltDevicePath;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *VarDp = DevicePath;
+ BOOLEAN Result;
+ UINTN i = 0;
+
+ do {
+ while((ConfigString[i] != L'&') && (ConfigString[i] != 0))
+ i++;
+
+ if(ConfigString[i] == 0) //PATH pattern not found
+ return FALSE;
+
+ i++; //shift pointer to next symbol
+ if(CheckPattern(&ConfigString[i], &PathPattern))
+ break;
+ } while(1);
+
+ Status = ExtractDevicePath(&ConfigString[i], (UINT8 **)&AltDevicePath, &Length);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ Result = !DPCmp(VarDp, AltDevicePath);
+ pBS->FreePool(AltDevicePath);
+ return Result;
+}
+
+VOID StringToChar16(
+ IN CHAR16 *String,
+ IN OUT UINTN *Size,
+ OUT CHAR16 *Block
+)
+{
+ UINTN i, j;
+
+ i = 0;
+ j = 0;
+
+ while( CheckIfHexDigit(String[i]) && CheckIfHexDigit(String[i + 1]) &&
+ CheckIfHexDigit(String[i + 2]) && CheckIfHexDigit(String[i + 3]) &&
+ j < *Size - 1 )
+ {
+ Block[j] = HexValue((UINT8)String[i]) & 0x000f;
+ Block[j] <<= 4;
+ Block[j] |= HexValue((UINT8)String[i + 1]);
+ Block[j] <<= 4;
+ Block[j] |= HexValue((UINT8)String[i + 2]);
+ Block[j] <<= 4;
+ Block[j] |= HexValue((UINT8)String[i + 3]);
+
+ i += 4;
+ j++;
+ }
+ *Size = j; //number of words processed
+ Block[j] = 0; //put null-terminator
+}
+
+VOID StripValuePattern(
+ IN OUT EFI_STRING String,
+ IN UINTN Size
+)
+{
+ EFI_STATUS Status;
+ EFI_STRING NewString;
+ UINTN i = 0;
+ UINTN j = 0;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &NewString);
+
+ while(String[i] != 0) {
+ if(String[i] == L'&') {
+ if(CheckPattern(&String[i + 1], &ValuePattern)) {
+ i++;
+ while((String[i] != L'&') && (String[i] != 0))
+ i++;
+ if(String[i] == 0)
+ break;
+ }
+ }
+
+ NewString[j++] = String[i++];
+ }
+
+ NewString[j] = 0;
+ MemCpy(String, NewString, (j + 1) * 2);
+ pBS->FreePool(NewString);
+}
+
+EFI_STATUS InitResultBlock(
+ IN OUT RESULT_BLOCK *ResultBlock
+)
+{
+ EFI_STATUS Status;
+ ResultBlock->MaxResultStringSize = INITIAL_RESULT_STRING_SIZE;
+ ResultBlock->CurrentSize = 0;
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * ResultBlock->MaxResultStringSize,
+ &(ResultBlock->ResultString));
+ return Status;
+}
+
+#pragma warning (default : 4090)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/UefiHii/HiiDatabase.c b/Core/CORE_DXE/UefiHii/HiiDatabase.c
new file mode 100644
index 0000000..fef10c6
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiDatabase.c
@@ -0,0 +1,1814 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiDatabase.c 14 5/21/12 4:55p Artems $
+//
+// $Revision: 14 $
+//
+// $Date: 5/21/12 4:55p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiDatabase.c $
+//
+// 14 5/21/12 4:55p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+//
+// 13 1/05/12 5:05p Artems
+// EIP 76735: Font FFS file is not loaded in framework mode, when in
+// nested FV
+//
+// 12 5/13/11 6:14p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 11 5/05/11 4:13p Artems
+// Add signal "layout changed" event if current layout is deleted
+//
+// 10 1/05/11 12:41p Artems
+// EIP 50995: Added checking of driver handle before adding packages to
+// HII database
+//
+// 9 6/23/10 5:06p Artems
+// Restored fix killed by previous check-in
+//
+// 8 6/10/10 4:35p Artems
+// EIP 39692 fix - call notification after adding package
+//
+// 7 3/09/10 6:41p Artems
+// EIP 35698: Removed DeleteSimpleFonts call
+//
+// 6 2/03/10 10:28a Artems
+// Fixed bug in HiiExportPacks function
+//
+// 5 1/29/10 5:43p Artems
+// EIP 34553 Updated function ExportPackageLists to support NULL pointer
+// as input
+//
+// 4 1/07/10 12:29p Felixp
+// Code updated to use library instances of the Protocol GUID variables.
+//
+// 3 12/04/09 11:16a Artems
+// Remove keyboard layout functionality added
+//
+// 2 11/09/09 11:51a Felixp
+// New package list function is updated to report error when package list
+// with existing GUID is passed.
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiDatabase.c
+//
+// Description: Hii database protocol functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+#include <Protocol/DevicePath.h>
+#include <Protocol/HiiUtilities.h>
+
+extern HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol;
+extern DBE_KEY_FIELD StringDbKeyField;
+
+EFI_GUID NullGuid = NULL_GUID;
+
+SIMPLE_FONT DefaultFont[0x10000];
+
+HII_DATABASE_PRIVATE_DATA PrivateData =
+{
+//Database protocol members
+ {
+ HiiNewPack,
+ HiiRemovePack,
+ HiiUpdatePack,
+ HiiListPacks,
+ HiiExportPacks,
+ HiiRegisterNotify,
+ HiiUnregisterNotify,
+ HiiFindKeyboardLayouts,
+ HiiGetKeyboardLayout,
+ HiiSetKeyboardLayout,
+ HiiGetPackageListHandle
+ },
+//String protocol members
+ {
+ HiiNewString,
+ AmiHiiGetString, //EdkII compatibility library already has function HiiGetString
+ AmiHiiSetString, //EdkII compatibility library already has function HiiSetString
+ HiiGetLanguages,
+ HiiGetSecondLanguages
+ },
+//Font protocol members
+ {
+ HiiStringToImage,
+ HiiStringIdToImage,
+ HiiGetGlyph,
+ HiiGetFontInfo
+ },
+//Config Routing protocol members
+ {
+ HiiExtractConfig,
+ HiiExportConfig,
+ HiiRouteConfig,
+ HiiBlockToConfig,
+ HiiConfigToBlock,
+ HiiGetAltConfig
+ },
+// Linked list of package lists
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Linked list of notify functions
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Linked list of keyboard layouts
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Linked list of global fonts
+ {
+ 0,
+ NULL,
+ NULL
+ },
+//Current KeyLayout
+ NULL
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiDatabaseEntryPoint
+//
+// Description:
+// This function is HII driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, HII protocols installed
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE HiiHandle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ pBS = SystemTable->BootServices;
+
+ //install HII Protocols
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &HiiHandle,
+ &gEfiHiiDatabaseProtocolGuid,
+ &(PrivateData.DatabaseProtocol),
+ &gEfiHiiStringProtocolGuid,
+ &(PrivateData.StringProtocol),
+ &gEfiHiiFontProtocolGuid,
+ &(PrivateData.FontProtocol),
+ &gEfiHiiConfigRoutingProtocolGuid,
+ &(PrivateData.ConfigRoutingProtocol),
+ &gHiiUtilitiesProtocolGuid,
+ &HiiUtilitiesProtocol,
+ NULL);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiBdsEntryPoint
+//
+// Description:
+// This function is HII driver BDS entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, system font is loaded
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiBdsEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE HiiHandle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+ Status = LoadSystemFont();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetPackHandle
+//
+// Description:
+// This function is HII Database protocol function GetPackageHandle implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageListHandle - PackageList handle
+// OUT EFI_HANDLE *DriverHandle - Pointer, where to store found Driver handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - PackageListHandle is invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetPackageListHandle (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageListHandle,
+ OUT EFI_HANDLE *DriverHandle)
+{
+ PACKAGE_LIST_RECORD *Record;
+
+ Record = (PACKAGE_LIST_RECORD *) PackageListHandle;
+
+ if (DriverHandle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_INVALID_PARAMETER;
+
+ *DriverHandle = Record->DriverHandle;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiRegisterNotify
+//
+// Description:
+// This function is HII Database protocol function RegisterPackageNotify implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN UINT8 PackageType - Package type
+// IN EFI_GUID *PackageGuid - Pointer to Package guid
+// IN EFI_HII_DATABASE_NOTIFY PackageNotifyFn - Function to be called
+// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - Notify type
+// OUT EFI_HANDLE *NotifyHandle - Pointer, where to store created Notify handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - PackageGuid is not NULL and PackageType is not Guid package
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiRegisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
+ OUT EFI_HANDLE *NotifyHandle)
+{
+ NOTIFY_RECORD *NewRecord;
+
+ if (NotifyHandle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
+ (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL))
+ return EFI_INVALID_PARAMETER;
+
+ NewRecord = NewNotifyRecord();
+ if (NewRecord == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ if(PackageType == EFI_HII_PACKAGE_TYPE_GUID)
+ NewRecord->PackageGuid = *PackageGuid;
+ else
+ NewRecord->PackageGuid = NullGuid;
+
+ NewRecord->PackageType = PackageType;
+ NewRecord->NotifyType = NotifyType;
+ NewRecord->PackageNotifyFn = PackageNotifyFn;
+
+ DListAdd(&(PrivateData.NotifyList), (DLINK *) NewRecord);
+
+ if(NotifyHandle != NULL)
+ *NotifyHandle = NewRecord;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiUnregisterNotify
+//
+// Description:
+// This function is HII Database protocol function UnregisterPackageNotify implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HANDLE NotificationHandle - Notify handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - NotificationHandle is not valid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiUnregisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle)
+{
+ NOTIFY_RECORD *Record;
+
+ Record = (NOTIFY_RECORD *) NotificationHandle;
+
+ if (Record->Signature != NOTIFY_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ DListDelete(&(PrivateData.NotifyList), (DLINK *) Record);
+ Record->Signature = 0xffffffff; //invalidate signature to avoid future use of this memory
+ pBS->FreePool(Record);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiRemovePack
+//
+// Description:
+// This function is HII Database protocol function RemovePackageList implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE Handle - Handle of package list to be removed from database
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle is not valid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiRemovePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ PACKAGE_LINK *Package;
+ PACKAGE_LINK *Link;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ Package = (PACKAGE_LINK *) Record->PackageList.pHead;
+
+ while(Package != NULL)
+ {
+ Link = Package;
+ Package = (PACKAGE_LINK *) Package->Link.pNext;
+ RemovePackage(Handle, Link);
+ }
+
+ DListDelete(&(PrivateData.PackList), (DLINK *) Record);
+ Record->Signature = 0xffffffff; //invalidate signature to avoid future collisions
+ pBS->FreePool(Record);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiNewPack
+//
+// Description:
+// This function is HII Database protocol function NewPackageList implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_PACKAGE_LIST_HEADER *PackageList - Pointer to package list to be added to database
+// IN EFI_HANDLE DriverHandle - Driver handle
+// OUT EFI_HII_HANDLE *Handle - Pointer to EFI_HII_HANDLE where to store created handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle or PackageList is NULL
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiNewPack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ IN CONST EFI_HANDLE DriverHandle,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ PACKAGE_LIST_RECORD *NewRecord;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DpProtocol;
+ UINT32 DpPackageSize;
+ EFI_HII_PACKAGE_HEADER *Buffer;
+
+ if((PackageList == NULL) || (Handle == NULL))
+ return EFI_INVALID_PARAMETER;
+
+ // Check the Package list GUID and DriverHandle to guarantee this GUID is unique in database.
+ if(CheckIfPresent(&(PackageList->PackageListGuid), DriverHandle))
+ return EFI_ALREADY_STARTED; //package list already present
+
+ NewRecord = NewPackageListRecord();
+ if(NewRecord == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ NewRecord->DriverHandle = DriverHandle;
+ NewRecord->Guid = PackageList->PackageListGuid;
+
+ Status = AddPackages((EFI_HII_HANDLE)NewRecord, PackageList, FALSE);
+ if(EFI_ERROR(Status) && (NewRecord->PackageList.Size != 0))
+ {
+ DeleteList(&(NewRecord->PackageList));
+ pBS->FreePool(NewRecord);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+
+ Status = pBS->HandleProtocol(DriverHandle, &gEfiDevicePathProtocolGuid, &DpProtocol);
+ if(!EFI_ERROR(Status))
+ {
+ DpPackageSize = (UINT32)DPLength(DpProtocol);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ DpPackageSize + sizeof(EFI_HII_PACKAGE_HEADER),
+ &Buffer);
+ if (EFI_ERROR(Status))
+ {
+ DeleteList(&(NewRecord->PackageList));
+ pBS->FreePool(NewRecord);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Buffer->Type = EFI_HII_PACKAGE_DEVICE_PATH;
+ Buffer->Length = DpPackageSize + sizeof(EFI_HII_PACKAGE_HEADER);
+
+ (UINT8 *)Buffer += sizeof(EFI_HII_PACKAGE_HEADER);
+ MemCpy(Buffer, DpProtocol, DpPackageSize);
+ (UINT8 *)Buffer -= sizeof(EFI_HII_PACKAGE_HEADER);
+
+ Status = AddPackage((EFI_HII_HANDLE)NewRecord, Buffer, EFI_HII_DATABASE_NOTIFY_NEW_PACK);
+ if (EFI_ERROR(Status))
+ {
+ DeleteList(&(NewRecord->PackageList));
+ pBS->FreePool(NewRecord);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ pBS->FreePool(Buffer);
+ }
+
+ DListAdd(&(PrivateData.PackList), (DLINK *)NewRecord);
+ *Handle = NewRecord;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiListPacks
+//
+// Description:
+// This function is HII Database protocol function ListPackageLists implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN UINT8 PackageType - Package type
+// IN EFI_GUID *PackageGuid - Pointer to package guid
+// IN OUT UINTN *HandleBufferLength - Pointer to allocated buffer size value
+// OUT EFI_HII_HANDLE *Handle - Pointer to EFI_HII_HANDLE buffer where to store found handles
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - HandleBufferLength is NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+// EFI_NOT_FOUND - No handles found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiListPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN OUT UINTN *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle)
+{
+ UINTN RequiredSize = 0;
+ UINT32 i, Count = 0;
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *List;
+ BOOLEAN InternalBuffer = TRUE;
+ BOOLEAN Found;
+ EFI_HII_HANDLE *MatchedHandles;
+
+ if(HandleBufferLength == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (*HandleBufferLength > 0 && Handle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if ((PackageType == EFI_HII_PACKAGE_TYPE_GUID && PackageGuid == NULL) ||
+ (PackageType != EFI_HII_PACKAGE_TYPE_GUID && PackageGuid != NULL))
+ return EFI_INVALID_PARAMETER;
+
+ List = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ if(PackageType == EFI_HII_PACKAGE_TYPE_ALL)
+ {
+ RequiredSize = sizeof(EFI_HII_HANDLE) * PrivateData.PackList.Size;
+
+ if(*HandleBufferLength < RequiredSize)
+ {
+ *HandleBufferLength = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ for(i = 0; i < PrivateData.PackList.Size; i++)
+ {
+ Handle[i] = List;
+ List = (PACKAGE_LIST_RECORD *)List->Link.pNext;
+ }
+ }
+ else
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_HII_HANDLE) * PrivateData.PackList.Size,
+ (VOID **)&MatchedHandles);
+ if(EFI_ERROR(Status))
+ InternalBuffer = FALSE;
+
+ //parsing package lists to find matches. If internal buffer present found handles will be
+ //stored to avoid repeat parsing
+ for(i = 0; i < PrivateData.PackList.Size; i++)
+ {
+ Found = FindAndRemovePackages(
+ (EFI_HII_HANDLE)List,
+ PackageType,
+ PackageGuid,
+ TRUE);
+ if(Found)
+ {
+ if(InternalBuffer)
+ MatchedHandles[Count] = (EFI_HII_HANDLE)List;
+ Count++;
+ }
+ List = (PACKAGE_LIST_RECORD *) List->Link.pNext;
+ }
+
+ if(Count == 0)
+ return EFI_NOT_FOUND;
+
+ RequiredSize = Count * sizeof(EFI_HII_HANDLE);
+
+ if(*HandleBufferLength < RequiredSize)
+ {
+ *HandleBufferLength = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if(InternalBuffer)
+ {
+ for(i = 0; i < Count; i++)
+ Handle[i] = MatchedHandles[i];
+ pBS->FreePool(MatchedHandles);
+ }
+ else
+ {
+ Count = 0;
+ for(i = 0; i < PrivateData.PackList.Size; i++)
+ {
+ Found = FindAndRemovePackages(
+ (EFI_HII_HANDLE)List,
+ PackageType,
+ PackageGuid,
+ TRUE);
+ if(Found)
+ {
+ Handle[Count] = (EFI_HII_HANDLE)List;
+ Count++;
+ }
+ List = (PACKAGE_LIST_RECORD *) List->Link.pNext;
+ }
+ }
+ }
+
+ *HandleBufferLength = RequiredSize;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiUpdatePack
+//
+// Description:
+// This function is HII Database protocol function UpdatePackageList implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE Handle - Handle of package list to be updated
+// IN EFI_HII_PACKAGE_LIST_HEADER *PackageList - Pointer to new Package list
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle is invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiUpdatePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ EFI_STATUS Status;
+
+ if (PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ Status = AddPackages(Handle, PackageList, TRUE);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiExportPacks
+//
+// Description:
+// This function is HII Database protocol function ExportPackageLists implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_HII_HANDLE Handle - Handle of package list to be exported
+// IN OUT UINTN *BufferSize - Pointer to export buffer size value
+// OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer - Pointer to buffer where to export package lists
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Handle is invalid
+// EFI_BUFFER_TOO_SMALL - Export buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiExportPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer)
+{
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ UINT32 Size = 0;
+ UINTN PackageListSize;
+ UINTN RequiredSize = 0;
+ UINTN MaxPackageListSize = 0;
+ VOID *IntBuffer;
+
+//Conformance check, as required by SCT
+ if (BufferSize == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (*BufferSize > 0 && Buffer == NULL)
+ return EFI_INVALID_PARAMETER;
+//End of conformace check
+
+ if (Record != NULL) //we need to export only specific package list
+ return ExportPack(Handle, BufferSize, Buffer, TRUE);
+
+//we need to return all package lists
+ Record = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ while(Record != NULL) {
+ //first determine required buffer size
+ PackageListSize = 0;
+ Status = ExportPack((EFI_HII_HANDLE)Record, &PackageListSize, NULL, TRUE);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ RequiredSize += PackageListSize;
+ MaxPackageListSize = (MaxPackageListSize > PackageListSize) ? MaxPackageListSize : PackageListSize;
+ }
+ Record = (PACKAGE_LIST_RECORD *)(Record->Link.pNext);
+ }
+
+ if(*BufferSize < RequiredSize) {
+ *BufferSize = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData, MaxPackageListSize, &IntBuffer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Record = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ while(Record != NULL) {
+ //export all package lists one by one
+ PackageListSize = MaxPackageListSize;
+ Status = ExportPack((EFI_HII_HANDLE)Record, &PackageListSize, IntBuffer, FALSE);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(Buffer, IntBuffer, PackageListSize);
+ (UINT8 *)Buffer += PackageListSize;
+ }
+ Record = (PACKAGE_LIST_RECORD *)(Record->Link.pNext);
+ }
+
+ pBS->FreePool(IntBuffer);
+ *BufferSize = RequiredSize;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiFindKeyboardLayouts
+//
+// Description:
+// This function is HII Database protocol function FindKeyboardLayouts implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN OUT UINT16 *KeyGuidBufferLength - Pointer to allocated buffer size value
+// OUT EFI_GUID *KeyGuidBuffer - Pointer to EFI_GUID buffer where to store found layouts
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - KeyGuidBufferLength or KeyGuidBuffer is NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+// EFI_NOT_FOUND - No layouts found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiFindKeyboardLayouts (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_GUID *KeyGuidBuffer)
+{
+ UINT16 RequiredSize;
+ KEY_LAYOUT_LINK *Link;
+ UINT16 i;
+
+ if(KeyGuidBufferLength == NULL || KeyGuidBuffer == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(PrivateData.KeyLayoutList.Size == 0)
+ return EFI_NOT_FOUND;
+
+ RequiredSize = (UINT16) PrivateData.KeyLayoutList.Size * sizeof(EFI_GUID);
+ if(RequiredSize > *KeyGuidBufferLength)
+ {
+ *KeyGuidBufferLength = RequiredSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Link = (KEY_LAYOUT_LINK *)PrivateData.KeyLayoutList.pHead;
+ for(i = 0; i < PrivateData.KeyLayoutList.Size; i++)
+ {
+ KeyGuidBuffer[i] = Link->Layout.Guid;
+ Link = (KEY_LAYOUT_LINK *) Link->Link.pNext;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiSetKeyboardLayout
+//
+// Description:
+// This function is HII Database protocol function SetKeyboardLayout implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_GUID *KeyGuid - Pointer to EFI_GUID of layout to set
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - KeyGuid is NULL
+// EFI_NOT_FOUND - Given layout not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+//dummy function for signal event procedure
+VOID SetKbLayoutNotifyFn(IN EFI_EVENT Event, IN VOID *Context) {}
+
+EFI_STATUS HiiSetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid)
+{
+ EFI_HII_KEYBOARD_LAYOUT* Layout;
+ EFI_STATUS Status;
+
+ if(KeyGuid == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Layout = FindLayoutByGuid(KeyGuid);
+ if(Layout == NULL)
+ return EFI_NOT_FOUND;
+
+ PrivateData.CurrentLayout = Layout;
+ Status = SignalKbLayoutChangedEvent();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetKeyboardLayout
+//
+// Description:
+// This function is HII Database protocol function GetKeyboardLayout implementation
+//
+// Input:
+// IN EFI_HII_DATABASE_PROTOCOL *This - Pointer to EFI_HII_DATABASE_PROTOCOL structure
+// IN EFI_GUID *KeyGuid - Pointer to EFI_GUID of layout to set
+// IN OUT UINT16 *KeyGuidBufferLength - Pointer to allocated buffer size value
+// OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout - Pointer to EFI_HII_KEYBOARD_LAYOUT where to store layout
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - KeyboardLayout or KeyGuidBufferLength is NULL
+// EFI_NOT_FOUND - Given layout not found
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout)
+{
+ EFI_HII_KEYBOARD_LAYOUT *Layout;
+
+ if(KeyGuidBufferLength == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(*KeyGuidBufferLength != 0 && KeyboardLayout == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(KeyGuid == NULL)
+ Layout = PrivateData.CurrentLayout;
+ else
+ Layout = FindLayoutByGuid(KeyGuid);
+
+ if(Layout == NULL)
+ return EFI_NOT_FOUND;
+
+ if(Layout->LayoutLength > *KeyGuidBufferLength)
+ {
+ *KeyGuidBufferLength = Layout->LayoutLength;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ MemCpy(KeyboardLayout, Layout, Layout->LayoutLength);
+ return EFI_SUCCESS;
+}
+
+//********************** Service functions implementation ***************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddPackages
+//
+// Description:
+// This function adds packages from PackageList to package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to add packages
+// IN EFI_HII_PACKAGE_LIST_HEADER *PackageList - Pointer to package list which packages to add
+// IN BOOLEAN Update - Flag which defines packages should be added or updated
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+// Notes:
+// If Update is TRUE control flow goes as described in UpdatePackageList function definition (see UEFI
+// specification v2.1) Otherwise control flow goes as described in NewPackageList function definition
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddPackages(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ BOOLEAN Update)
+{
+ UINT8 Passes;
+ EFI_GUID *Guid;
+ UINT8 PackageType;
+ EFI_STATUS Status;
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType;
+ EFI_HII_PACKAGE_LIST_HEADER *SavePointer;
+ UINT32 ControlSize;
+
+ SavePointer = PackageList;
+ ControlSize = PackageList->PackageLength;
+
+ if(Update)
+ {
+ Passes = 2; //set number of passes
+ NotifyType = EFI_HII_DATABASE_NOTIFY_ADD_PACK;
+ }
+ else
+ {
+ Passes = 1; //set number of passes
+ NotifyType = EFI_HII_DATABASE_NOTIFY_NEW_PACK;
+ }
+
+ while(Passes--)
+ {
+ (UINT8 *)PackageList += sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+ ControlSize -= sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ while(((EFI_HII_PACKAGE_HEADER *)PackageList)->Type != EFI_HII_PACKAGE_END && ControlSize > 0)
+ {
+ if(Update)
+ {
+ PackageType = ((EFI_HII_PACKAGE_HEADER *)PackageList)->Type;
+ if(PackageType == EFI_HII_PACKAGE_TYPE_GUID)
+ Guid = (EFI_GUID *) &(((EFI_HII_GUID_PACKAGE_HDR *)PackageList)->Guid);
+ else
+ Guid = NULL;
+ FindAndRemovePackages(Handle, PackageType, Guid, FALSE);
+ }
+ else
+ {
+ Status = AddPackage(Handle, (EFI_HII_PACKAGE_HEADER *)PackageList, NotifyType);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ ControlSize -= ((EFI_HII_PACKAGE_HEADER *)PackageList)->Length;
+ (UINT8 *)PackageList += ((EFI_HII_PACKAGE_HEADER *)PackageList)->Length;
+ }
+ Update = FALSE;
+ PackageList = SavePointer;
+ ControlSize = PackageList->PackageLength;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddPackage
+//
+// Description:
+// This function adds package to package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to add package
+// IN EFI_HII_PACKAGE_HEADER *Package - Pointer to package to add
+// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - Notify type to be signalled
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddPackage(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType)
+{
+ PACKAGE_LINK *NewLink;
+ UINT32 Size;
+ DLIST *PackageList;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+
+ Size = Package->Length;
+ NewLink = (PACKAGE_LINK *) CreateNewLink(Size);
+ if(NewLink == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ MemCpy(&(NewLink->Package), Package, Size);
+
+ switch(Package->Type)
+ {
+ case EFI_HII_PACKAGE_STRINGS:
+ Status = ParseStringsPackage(
+ (PACKAGE_LIST_RECORD *)Handle,
+ (EFI_HII_STRING_PACKAGE_HDR *)Package);
+ break;
+ case EFI_HII_PACKAGE_SIMPLE_FONTS:
+ Status = ParseSimpleFontsPackage((EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)Package);
+ break;
+ case EFI_HII_PACKAGE_FONTS:
+ Status = ParseFontsPackage((EFI_HII_FONT_PACKAGE_HDR *)Package);
+ break;
+ case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
+ Status = ParseKeyLayoutPackage((EFI_HII_KEYBOARD_PACKAGE_HDR *)Package);
+ break;
+ default:
+ break;
+ }
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ DListAdd(PackageList, (DLINK *)NewLink);
+
+ if(PrivateData.NotifyList.Size > 0)
+ InvokeRegisteredNotify(Package, Handle, NotifyType);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindAndRemovePackages
+//
+// Description:
+// This function finds or removes packages from package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to find package
+// IN UINT8 PackageType - Package type to find
+// IN EFI_GUID *PackageGuid - Pointer to package guid to find
+// IN BOOLEAN FindOnly - Flag, which determines should package be found or removed
+//
+// Output:
+// TRUE - Package of given type found
+//
+// Notes:
+// If FindOnly is TRUE, function returns TRUE when first package of given type is found. Otherwise
+// function removes all packages of given type from package list and returns FALSE
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FindAndRemovePackages (
+ IN EFI_HII_HANDLE Handle,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN BOOLEAN FindOnly )
+{
+ DLIST *PackageList;
+ PACKAGE_LINK *Link;
+ PACKAGE_LINK *FoundLink;
+
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+ Link = (PACKAGE_LINK *)(PackageList->pHead);
+
+ while(Link != NULL)
+ {
+ if(MatchPackage(PackageType, PackageGuid, &(Link->Package)))
+ {
+ if(FindOnly)
+ return TRUE;
+ else
+ {
+ FoundLink = Link;
+ Link = (PACKAGE_LINK *)Link->Link.pPrev;
+ RemovePackage(Handle, FoundLink);
+ }
+ }
+ if(Link == NULL) //we removed first element from list
+ Link = (PACKAGE_LINK *)(PackageList->pHead);
+ else
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemovePackage
+//
+// Description:
+// This function removes package from package list with given handle
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list where to add package
+// IN PACKAGE_LINK *Package - Pointer to package to remove
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RemovePackage (
+ IN EFI_HII_HANDLE Handle,
+ IN PACKAGE_LINK *Package )
+{
+ DLIST *PackageList;
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+
+ if(PrivateData.NotifyList.Size > 0)
+ InvokeRegisteredNotify(&(Package->Package), Handle, EFI_HII_DATABASE_NOTIFY_REMOVE_PACK);
+
+ switch(Package->Package.Type)
+ {
+ case EFI_HII_PACKAGE_STRINGS:
+ DeleteStringsFromDatabase(&(((PACKAGE_LIST_RECORD *)Handle)->StringDb));
+ DeleteList(&(((PACKAGE_LIST_RECORD *)Handle)->LanguageList));
+ break;
+ case EFI_HII_PACKAGE_SIMPLE_FONTS:
+// DeleteSimpleFonts((EFI_HII_SIMPLE_FONT_PACKAGE_HDR *)&(Package->Package));
+ break;
+ case EFI_HII_PACKAGE_FONTS:
+// DeleteFonts((EFI_HII_FONT_PACKAGE_HDR *)&(Package->Package));
+ break;
+ case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
+ DeleteKeyboardLayout((EFI_HII_KEYBOARD_PACKAGE_HDR *)&(Package->Package));
+ break;
+ default:
+ break;
+ }
+ DListDelete(PackageList, (DLINK *)Package);
+ pBS->FreePool(Package);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InvokeRegisteredNotify
+//
+// Description:
+// This function invokes registered notify function if package types match
+//
+// Input:
+// IN EFI_HII_PACKAGE_HEADER *Package - Pointer to package to match
+// IN EFI_HII_HANDLE Handle - Handle of package list to whom given package belongs
+// IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType - Notification type
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InvokeRegisteredNotify (
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType)
+{
+ NOTIFY_RECORD *Record;
+
+ Record = (NOTIFY_RECORD *)(PrivateData.NotifyList.pHead);
+
+ while(Record != NULL)
+ {
+ if(MatchPackage(Record->PackageType, &(Record->PackageGuid), Package) &&
+ (NotifyType & Record->NotifyType))
+ Record->PackageNotifyFn(Record->PackageType,
+ &(Record->PackageGuid),
+ Package,
+ Handle,
+ NotifyType);
+ Record = (NOTIFY_RECORD *)(Record->Link.pNext);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NewPackageListRecord
+//
+// Description:
+// This function creates new PACKAGE_LIST_RECORD structure and returns pointer to it
+//
+// Input:
+// None
+//
+// Output:
+// PACKAGE_LIST_RECORD* - pointer to newly created structure
+// NULL - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PACKAGE_LIST_RECORD* NewPackageListRecord( VOID )
+{
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *Record;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(PACKAGE_LIST_RECORD),
+ &Record);
+ if (EFI_ERROR(Status))
+ return NULL;
+
+ Record->Signature = PACKAGE_LIST_RECORD_SIGNATURE;
+
+ DListInit(&(Record->PackageList));
+ DListInit(&(Record->LanguageList));
+ DListInit(&(Record->StringFontList));
+
+ Record->StringDb.InitialCount = 20;
+ Record->StringDb.RecordCount = 0;
+ Record->StringDb.KeyField = &StringDbKeyField;
+ Record->StringDb.MemoryType = EfiBootServicesData;
+ Record->StringDb.KeyCount = 1;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(VOID *) * 20,
+ &(Record->StringDb.IndexArray));
+
+ if (EFI_ERROR(Status))
+ {
+ pBS->FreePool(Record);
+ return NULL;
+ }
+
+ return Record;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NewNotifyRecord
+//
+// Description:
+// This function creates new NOTIFY_RECORD structure and returns pointer to it
+//
+// Input:
+// None
+//
+// Output:
+// NOTIFY_RECORD* - pointer to newly created structure
+// NULL - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NOTIFY_RECORD* NewNotifyRecord( VOID )
+{
+ EFI_STATUS Status;
+ NOTIFY_RECORD *Record;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(NOTIFY_RECORD),
+ &Record);
+ if (EFI_ERROR(Status))
+ return NULL;
+
+ Record->Signature = NOTIFY_LIST_RECORD_SIGNATURE;
+
+ return Record;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateNewLink
+//
+// Description:
+// This function creates new link structure for linked list and returns pointer to it
+//
+// Input:
+// IN UINT32 Size - size of the link stucture in bytes
+//
+// Output:
+// VOID* - pointer to newly created structure
+// NULL - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* CreateNewLink(UINT32 Size)
+{
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Size + sizeof(DLINK),
+ &Buffer);
+ if (EFI_ERROR(Status))
+ return NULL;
+
+ return Buffer;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteList
+//
+// Description:
+// This function deletes linked list and frees allocated memory
+//
+// Input:
+// IN DLIST *List - Pointer to linked list to be deleted
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteList(DLIST *List)
+{
+ DLINK *Current;
+ DLINK *Next;
+
+ Current = List->pHead;
+
+ while(Current != NULL)
+ {
+ Next = Current->pNext;
+ pBS->FreePool(Current);
+ Current = Next;
+ }
+
+ List->pHead = NULL;
+ List->pTail = NULL;
+ List->Size = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchPackage
+//
+// Description:
+// This function checks if given package matches given type and guid
+//
+// Input:
+// IN UINT8 PackageType - Package type to match
+// IN EFI_GUID *PackageGuid - Pointer to package guid to match
+// IN EFI_HII_PACKAGE_HEADER *Package - Pointer to package to check
+//
+// Output:
+// TRUE - package matches given type and guid
+// FALSE - package don't match
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchPackage(
+ IN UINT8 PackageType,
+ IN EFI_GUID *PackageGuid,
+ IN EFI_HII_PACKAGE_HEADER *Package)
+{
+ if(PackageType != Package->Type)
+ return FALSE;
+
+ if(PackageType == EFI_HII_PACKAGE_TYPE_GUID)
+ {
+ if(guidcmp(PackageGuid, &(((EFI_HII_GUID_PACKAGE_HDR *)Package)->Guid)))
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckIfPresent
+//
+// Description:
+// This function checks if package list with given guid already in database
+//
+// Input:
+// IN EFI_GUID *Guid - Pointer to package list guid to check
+// IN EFI_HANDLE DriverHandle - Driver handle
+//
+// Output:
+// TRUE - package list already present in database
+// FALSE - package list with given guid not found in database
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckIfPresent(
+ IN EFI_GUID *Guid,
+ IN EFI_HANDLE DriverHandle)
+{
+ PACKAGE_LIST_RECORD *Record;
+
+ Record = (PACKAGE_LIST_RECORD *)(PrivateData.PackList.pHead);
+
+ while(Record != NULL)
+ {
+ if((!guidcmp(Guid, &(Record->Guid))) && (DriverHandle == Record->DriverHandle))
+ return TRUE;
+ Record = (PACKAGE_LIST_RECORD *)(Record->Link.pNext);
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseKeyLayoutPackage
+//
+// Description:
+// This function extracts keyboard layout from package and saves it in private area
+//
+// Input:
+// IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package - Pointer to keyboard layout package
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseKeyLayoutPackage(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package)
+{
+ KEY_LAYOUT_LINK *Link;
+ UINT16 i;
+ UINT8 *Pointer;
+ UINT32 Size;
+
+ Pointer = (UINT8 *)Package;
+ Pointer += sizeof(EFI_HII_KEYBOARD_PACKAGE_HDR);
+
+ for(i = 0; i < Package->LayoutCount; i++)
+ {
+ Size = ((EFI_HII_KEYBOARD_LAYOUT *)Pointer)->LayoutLength;
+ Link = (KEY_LAYOUT_LINK *) CreateNewLink(Size);
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ MemCpy(&(Link->Layout), Pointer, Size);
+ DListAdd(&(PrivateData.KeyLayoutList), (DLINK *)Link);
+ Pointer += Size;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteKeyboardLayout
+//
+// Description:
+// This function removes keyboard layouts existing in package from HII database
+//
+// Input:
+// IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package - Pointer to keyboard layout package
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DeleteKeyboardLayout(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package)
+{
+ KEY_LAYOUT_LINK *Link;
+ UINT16 i;
+ UINT8 *Pointer;
+ UINT32 Size;
+
+ Pointer = (UINT8 *)Package;
+ Pointer += sizeof(EFI_HII_KEYBOARD_PACKAGE_HDR);
+
+ for(i = 0; i < Package->LayoutCount; i++)
+ {
+ Size = ((EFI_HII_KEYBOARD_LAYOUT *)Pointer)->LayoutLength;
+ Link = (KEY_LAYOUT_LINK *)PrivateData.KeyLayoutList.pHead;
+ while(Link != NULL)
+ {
+ if(!guidcmp(&(((EFI_HII_KEYBOARD_LAYOUT *)Pointer)->Guid), &(Link->Layout.Guid)))
+ break;
+ Link = (KEY_LAYOUT_LINK *)Link->Link.pNext;
+ }
+
+ if(Link != NULL) {
+ if(PrivateData.CurrentLayout == &(Link->Layout)) {
+ PrivateData.CurrentLayout = NULL;
+ SignalKbLayoutChangedEvent();
+ }
+
+ DListDelete(&(PrivateData.KeyLayoutList), (DLINK *)Link);
+ }
+ Pointer += Size;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindLayoutByGuid
+//
+// Description:
+// This function finds keyboard layout in private area by given guid
+//
+// Input:
+// IN EFI_GUID *Guid - Pointer to guid of keyboard layout
+//
+// Output:
+// EFI_HII_KEYBOARD_LAYOUT* - Pointer to found layout
+// NULL - layout not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_HII_KEYBOARD_LAYOUT* FindLayoutByGuid(
+ IN EFI_GUID *Guid)
+{
+ KEY_LAYOUT_LINK *Link;
+
+ Link = (KEY_LAYOUT_LINK *)PrivateData.KeyLayoutList.pHead;
+ while(Link != NULL)
+ {
+ if(!guidcmp(Guid, &(Link->Layout.Guid)))
+ return &(Link->Layout);
+ Link = (KEY_LAYOUT_LINK *)Link->Link.pNext;
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseSimpleFontsPackage
+//
+// Description:
+// This function extracts simple fonts from package and saves in private area
+//
+// Input:
+// IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package - Pointer to simple font package
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseSimpleFontsPackage(
+ IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package)
+{
+ EFI_STATUS Status;
+ UINT16 i;
+ UINT16 Symbol;
+ EFI_NARROW_GLYPH *NGlyph;
+ EFI_WIDE_GLYPH *WGlyph;
+
+ NGlyph = Package->NarrowGlyphs;
+ WGlyph = (EFI_WIDE_GLYPH *)NGlyph;
+ (UINT8 *)WGlyph += Package->NumberOfNarrowGlyphs * sizeof(EFI_NARROW_GLYPH);
+
+ for(i = 0; i < Package->NumberOfNarrowGlyphs; i++)
+ {
+ Symbol = NGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].NarrowGlyph == NULL)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_NARROW_GLYPH),
+ &(DefaultFont[Symbol].NarrowGlyph));
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ DefaultFont[Symbol].NarrowGlyph[0] = NGlyph[i];
+ }
+ }
+
+ for(i = 0; i < Package->NumberOfWideGlyphs; i++)
+ {
+ Symbol = WGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].WideGlyph == NULL)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_WIDE_GLYPH),
+ &(DefaultFont[Symbol].WideGlyph));
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+ DefaultFont[Symbol].WideGlyph[0] = WGlyph[i];
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStringsFromDatabase
+//
+// Description:
+// This function removes HII strings from private storage and frees allocated memory
+//
+// Input:
+// IN DBE_DATABASE *Database - Pointer to private strings storage
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteStringsFromDatabase(DBE_DATABASE *Database)
+{
+ VOID *FreeLink;
+ UINTN *Pointer;
+ UINTN i;
+
+ if(Database->RecordCount == 0)
+ return;
+
+ Pointer = (UINTN *)(Database->IndexArray);
+
+ for(i = 0; i < Database->RecordCount; i++)
+ {
+ FreeLink = (VOID *)(UINTN)(*Pointer);
+ pBS->FreePool(FreeLink);
+ Pointer++;
+ }
+
+ MemSet(Database->IndexArray, Database->RecordCount * Database->KeyCount, 0);
+ Database->RecordCount = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteSimpleFonts
+//
+// Description:
+// This function removes simple fonts from private area and frees allocated memory
+//
+// Input:
+// IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package - Pointer to simple font package which fonts
+// should be removed
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DeleteSimpleFonts(IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package)
+{
+ UINT16 i;
+ UINT16 Symbol;
+ EFI_NARROW_GLYPH *NGlyph;
+ EFI_WIDE_GLYPH *WGlyph;
+
+ NGlyph = Package->NarrowGlyphs;
+ WGlyph = (EFI_WIDE_GLYPH *)NGlyph;
+ (UINT8 *)WGlyph += Package->NumberOfNarrowGlyphs * sizeof(EFI_NARROW_GLYPH);
+
+ for(i = 0; i < Package->NumberOfNarrowGlyphs; i++)
+ {
+ Symbol = NGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].NarrowGlyph != NULL)
+ {
+ pBS->FreePool(DefaultFont[Symbol].NarrowGlyph);
+ DefaultFont[Symbol].NarrowGlyph = NULL;
+ }
+ }
+
+ for(i = 0; i < Package->NumberOfWideGlyphs; i++)
+ {
+ Symbol = WGlyph[i].UnicodeWeight;
+ if(DefaultFont[Symbol].WideGlyph != NULL)
+ {
+ pBS->FreePool(DefaultFont[Symbol].WideGlyph);
+ DefaultFont[Symbol].WideGlyph = NULL;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExportPack
+//
+// Description:
+// This function exports the package list with given handle into provided buffer
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list to be exported
+// IN OUT UINTN *BufferSize - Pointer to export buffer size value
+// OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer - Pointer to buffer where to export package lists
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_BUFFER_TOO_SMALL - Export buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ExportPack (
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer,
+ IN BOOLEAN FirstCall )
+{
+ EFI_STATUS Status;
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *) Handle;
+ PACKAGE_LINK *Link;
+ UINT32 Size = 0;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE) //handle is not valid, return NOT FOUND as SCT requirement
+ return EFI_NOT_FOUND;
+
+ if(FirstCall) {
+ //on the subsequent call we don't need to update string packages again
+ Status = UpdateStringPackages(Handle);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ Link = (PACKAGE_LINK *)Record->PackageList.pHead;
+ while(Link != NULL)
+ {
+ Size += Link->Package.Length;
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+
+ Size += sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ if(Size > *BufferSize)
+ {
+ *BufferSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = Size;
+ Buffer->PackageListGuid = Record->Guid;
+ Buffer->PackageLength = Size;
+ (UINT8 *)Buffer += sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ Link = (PACKAGE_LINK *)Record->PackageList.pHead;
+ while(Link != NULL)
+ {
+ Size = Link->Package.Length;
+ MemCpy(Buffer, &(Link->Package), Size);
+ (UINT8 *)Buffer += Size;
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS SignalKbLayoutChangedEvent(
+ VOID)
+{
+ EFI_EVENT Event;
+ EFI_GUID SetKeyboardLayoutEventGuid = EFI_HII_SET_KEYBOARD_LAYOUT_EVENT_GUID;
+ EFI_STATUS Status;
+
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ SetKbLayoutNotifyFn,
+ NULL,
+ &SetKeyboardLayoutEventGuid,
+ &Event);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ pBS->SignalEvent(Event);
+ pBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+
+#pragma warning (default : 4090)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiiFont.c b/Core/CORE_DXE/UefiHii/HiiFont.c
new file mode 100644
index 0000000..739520c
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiFont.c
@@ -0,0 +1,1035 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFont.c 3 3/18/13 8:31a Thomaschen $
+//
+// $Revision: 3 $
+//
+// $Date: 3/18/13 8:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFont.c $
+//
+// 3 3/18/13 8:31a Thomaschen
+// Update to rev.16.
+//
+// 16 3/11/13 4:40p Artems
+// [TAG] EIP110240
+// [Category] Improvement
+// [Description] Raise the TPL of StringToImage function to TPL_NOTIFY
+// to protect internal global data
+// [Files] HiiFont.c
+//
+// 15 1/24/13 11:12a Artems
+// [TAG] EIP112874
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System displays output in wrong colors
+// [RootCause] If system failed to find font, described in passed font
+// info structure it also ignored passed colors
+// [Solution] Preserve passed colors even if font not found
+// [Files] HiiFont.c
+//
+// 14 12/26/12 1:40p Artems
+// [TAG] EIP109050
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Memory leal in call to GetGlyph function
+// [RootCause] GetGlyph function called GetFontInfo function to obtain
+// proper font and didn't release font info buffer
+// [Solution] Fixed GetGlyph function
+// [Files] HiiFont.c
+//
+// 13 11/14/12 5:58p Artems
+// [TAG] EIP105534
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] system hangs during SCT execution
+// [RootCause] Incorrect handling of FORM_FEED escape character in
+// StringToImage function
+// [Solution] Graphics console - added flag to ignore line breaks
+// HiiFont - fixed multiline drawing logic
+// [Files] Gc.c HiiFont.c HiiFontEx.c
+//
+// 12 9/25/12 5:46p Artems
+// [TAG] EIP101224
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System freezes
+// [RootCause] Memory leak in StringToImage function. When called many
+// times may lead to memory exhaustion
+// [Solution] Fixed memory leak
+// [Files] HiiFont.c
+//
+// 11 6/27/12 4:16p Artems
+// [TAG] EIP93526
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Aptio 4 - Proportional Font EFI_HII_OUT_FLAG_WRAP issue
+// [RootCause] Passed drawing flags contained both Clip and Wrap. Clip
+// gets analyzed first so clipping control flow was enacted
+// [Solution] Changed order of drawind flags analysis
+// [Files] HiiFont.c
+//
+// 10 6/15/12 12:19p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] project doesn't build in 32-bit mode
+// [RootCause] Signed/Unsigned mismatch reported by 32-bit compiler
+// [Solution] typecasted one parameter to signed
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 9 6/14/12 6:31p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio fixed SCT reported
+// bugs
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 8 5/24/12 2:58p Artems
+// [TAG] EIP83593
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] No symbols are shown in GSE
+// [RootCause] Incorrect BaseLineOffset was set. Transparent drawing was
+// not supported
+// [Solution] Set correct BaseLineOffset. Add check for transparency
+// flag
+// [Files] HiiFont.c
+//
+// 7 5/22/12 4:14p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio. Removed unused
+// functions
+// [Files] HiiFont.c
+//
+// 6 5/21/12 6:28p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+//
+// 5 10/25/11 7:04p Artems
+// EIP 70530: Fixed bugs reported by SCT 2.3.1
+//
+// 4 5/17/11 4:05p Artems
+// EIP 59787: Bug fix - when drawing multi-line string X position wasn't
+// updated to start of new line
+//
+// 3 5/13/11 6:14p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 2 12/03/09 6:04p Artems
+// SCT bug fix
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiFont.c
+//
+// Description: Hii font protocol functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+const EFI_GRAPHICS_OUTPUT_BLT_PIXEL Black = { 0, 0, 0, 0 };
+const EFI_GRAPHICS_OUTPUT_BLT_PIXEL White = { 0xff, 0xff, 0xff, 0 };
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+extern SIMPLE_FONT DefaultFont[0x10000];
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefForegroundColor;
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefBackgroundColor;
+
+static UINTN TextStartX;
+static UINTN TextStartY;
+static EFI_GRAPHICS_OUTPUT_BLT_PIXEL *ImageBlt; //buffer, where to draw
+
+EFI_FONT_HANDLE CurFont; //font to use
+CHAR16 *DrawString; //string to draw
+EFI_HII_OUT_FLAGS DrawFlags = 0;
+DLIST DrawLines = {0, NULL, NULL};
+UINTN ImageWidth;
+UINTN ImageHeight;
+
+#pragma optimize( "", off )
+EFI_STATUS CheckParameters(VOID *One, VOID *Two)
+{
+ return (One == NULL || Two == NULL) ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
+}
+#pragma optimize( "", on )
+
+//**************************** Protocol functions implementation ***************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiStringToImage
+//
+// Description:
+// This function is HII Font protocol function StringToImage implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN EFI_HII_OUT_FLAGS Flags - Drawing flags
+// IN EFI_STRING String - String to draw
+// IN EFI_FONT_DISPLAY_INFO *StringInfo - Pointer to display info
+// IN OUT EFI_IMAGE_OUTPUT **Blt - Pointer to output buffer
+// IN UINTN BltX - start horizontal position
+// IN UINTN BltY - start vertical position
+// OUT EFI_HII_ROW_INFO **RowInfoArray - Pointer to returned row info array
+// OUT UINTN *RowInfoArraySize - Pointer to store row info array size
+// OUT UINTN *ColumnInfoArray - Pointer to returned column info array
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiStringToImage(
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL)
+{
+ EFI_STATUS Status;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *NewBlt = NULL;
+ EFI_IMAGE_OUTPUT *Io = *Blt;
+ EFI_HII_ROW_INFO *RowInfo;
+ UINTN i, j;
+ UINTN Offset;
+ DRAW_LINE *Link;
+ UINTN Delta = 0;
+ EFI_FONT_DISPLAY_INFO *Info = NULL;
+ EFI_TPL OldTpl;
+
+ Status = CheckParameters(String, Blt);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if (Io == NULL) {
+ //
+ // These two flag cannot be used if Blt is NULL upon entry.
+ //
+ if ((Flags & EFI_HII_OUT_FLAG_TRANSPARENT) == EFI_HII_OUT_FLAG_TRANSPARENT)
+ return EFI_INVALID_PARAMETER;
+
+ if ((Flags & EFI_HII_OUT_FLAG_CLIP) == EFI_HII_OUT_FLAG_CLIP)
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // These two flags require that EFI_HII_OUT_FLAG_CLIP be also set.
+ //
+ if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_X)
+ return EFI_INVALID_PARAMETER;
+
+ if ((Flags & (EFI_HII_OUT_FLAG_CLIP | EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)) == EFI_HII_OUT_FLAG_CLIP_CLEAN_Y)
+ return EFI_INVALID_PARAMETER;
+ //
+ // This flag cannot be used with EFI_HII_OUT_FLAG_CLIP_CLEAN_X.
+ //
+ if ((Flags & (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X)) == (EFI_HII_OUT_FLAG_WRAP | EFI_HII_OUT_FLAG_CLIP_CLEAN_X))
+ return EFI_INVALID_PARAMETER;
+
+//check string size - if two bytes - means empty string - do nothing
+ i = StrSize16(String);
+
+ if(i <= 2)
+ return EFI_SUCCESS;
+
+ OldTpl = pBS->RaiseTPL(TPL_NOTIFY);
+
+//first initialize global variables and split string
+/* SCT assumes that EFI_HII_OUT_FLAG_CLIP flag is implied when direct to screen output is performed
+ unless EFI_HII_OUT_FLAG_WRAP flag is set */
+ DrawFlags = Flags;
+ if(Flags & EFI_HII_IGNORE_LINE_BREAK ||
+ (Flags & EFI_HII_DIRECT_TO_SCREEN && !(Flags & EFI_HII_OUT_FLAG_WRAP)))
+ DrawFlags |= EFI_HII_OUT_FLAG_CLIP;
+
+ DrawString = String;
+ TextStartX = BltX;
+ TextStartY = BltY;
+ CurFont = NULL;
+ Status = HiiGetFontInfo(This, &CurFont, StringInfo, &Info, NULL);
+ if(EFI_ERROR(Status)) {
+ CurFont = (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE;
+ Info = NULL;
+ }
+
+ if (Info != NULL) {
+ DefForegroundColor = Info->ForegroundColor;
+ DefBackgroundColor = Info->BackgroundColor;
+ pBS->FreePool(Info); //it's no longer needed
+ } else {
+ if(StringInfo != NULL) { //even though correct font not found we preserve passed colors if any
+ DefForegroundColor = StringInfo->ForegroundColor;
+ DefBackgroundColor = StringInfo->BackgroundColor;
+ } else {
+ DefForegroundColor = White;
+ DefBackgroundColor = Black;
+ }
+ }
+
+ Status = SplitByLineBreaks(DrawString);
+ if(EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if(Io != NULL) {
+ if(!(Flags & EFI_HII_DIRECT_TO_SCREEN)) {
+ //if we're drawing on given bitmap - take its size
+ ImageWidth = Io->Width;
+ ImageHeight = Io->Height;
+ NewBlt = Io->Image.Bitmap;
+ } else {
+ //make sure we fit in screen resolution
+ ImageWidth = Io->Width - BltX;
+ ImageHeight = Io->Height - BltY;
+
+ //clear TextStartX and TextStartY
+ TextStartX = 0;
+ TextStartY = 0;
+ }
+ /* since bitmap size is fixed we have to adjust text to fit in */
+ Status = AdjustLineSize();
+ if(EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ } else {
+ //calculate size of the image
+ GetDrawImageSize(&ImageWidth, &ImageHeight);
+ //add to required image size initial offset
+ ImageWidth += BltX;
+ ImageHeight += BltY;
+ }
+
+ if(NewBlt == NULL) {
+ /* buffer not initialized because of DirectToScreen flag or Io == NULL */
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ImageWidth * ImageHeight,
+ &NewBlt);
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemSet(NewBlt, sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * ImageWidth * ImageHeight, 0);
+ }
+
+ ImageBlt = NewBlt;
+ Draw();
+
+ if(Flags & EFI_HII_DIRECT_TO_SCREEN)
+ {
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *Screen;
+
+ if(ImageWidth < Io->Width) //we need to draw a subrectange, calculate Delta
+ Delta = ImageWidth * sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+
+ Screen = (EFI_GRAPHICS_OUTPUT_PROTOCOL *)(Io->Image.Screen);
+ Status = Screen->Blt(Screen, ImageBlt, EfiBltBufferToVideo,
+ 0, 0, BltX, BltY, ImageWidth, ImageHeight, Delta);
+ pBS->FreePool(ImageBlt);
+ }
+
+//Prepare return info if needed
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ if(RowInfoArray != NULL && Link->LineHeight != 0) {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_HII_ROW_INFO) * DrawLines.Size,
+ &RowInfo);
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ i = 0;
+ while(Link != NULL) {
+ RowInfo[i].BaselineOffset = 0; //I'm still confused with this one, but SCT is happy
+ RowInfo[i].EndIndex = Link->EndIndex;
+ RowInfo[i].LineHeight = Link->LineHeight;
+ RowInfo[i].LineWidth = Link->LineWidth;
+ RowInfo[i].StartIndex = Link->StartIndex;
+
+ i++;
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ *RowInfoArray = RowInfo;
+ if(RowInfoArraySize != NULL)
+ *RowInfoArraySize = DrawLines.Size;
+ } else {
+ if(RowInfoArray != NULL)
+ *RowInfoArray = NULL;
+ if(RowInfoArraySize != NULL)
+ *RowInfoArraySize = 0;
+ }
+
+ if(Io == NULL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_IMAGE_OUTPUT), &Io);
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(OldTpl);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Io->Height = (UINT16)ImageHeight;
+ Io->Width = (UINT16)ImageWidth;
+ Io->Image.Bitmap = NewBlt;
+
+ *Blt = Io;
+ }
+
+ if(ColumnInfoArray != NULL) {
+ i = 0;
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL)
+ {
+ Offset = TextStartX;
+ for(j = Link->StartIndex; j <= Link->EndIndex; j++)
+ {
+ BOOLEAN Dummy;
+ EFI_HII_GLYPH_INFO Cell;
+ ColumnInfoArray[i] = Offset;
+ IntGetGlyph(CurFont, DrawString[j], &Cell, NULL, &Dummy);
+ i++;
+ Offset += Cell.AdvanceX;
+ }
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ }
+
+//clean up
+ DeleteList(&DrawLines);
+ pBS->RestoreTPL(OldTpl);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiStringIdToImage
+//
+// Description:
+// This function is HII Font protocol function StringIdToImage implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN EFI_HII_OUT_FLAGS Flags - Drawing flags
+// IN EFI_HII_HANDLE PackageList - Handle of package list where string resides
+// IN EFI_STRING_ID StringId - String Id
+// IN CHAR8 *Language - Language Id
+// IN EFI_FONT_DISPLAY_INFO *StringInfo - Pointer to display info
+// IN OUT EFI_IMAGE_OUTPUT **Blt - Pointer to output buffer
+// IN UINTN BltX - start horizontal position
+// IN UINTN BltY - start vertical position
+// OUT EFI_HII_ROW_INFO **RowInfoArray - Pointer to returned row info array
+// OUT UINTN *RowInfoArraySize - Pointer to store row info array size
+// OUT UINTN *ColumnInfoArray - Pointer to returned column info array
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiStringIdToImage (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8* Language,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL)
+{
+ CHAR16 String[0x100];
+ UINTN StringSize = 0x100;
+ EFI_STATUS Status;
+
+ Status = AmiHiiGetString(NULL, Language, PackageList, StringId, String, &StringSize, NULL);
+
+ if(EFI_ERROR(Status))
+ {
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * StringSize,
+ (VOID **)&String);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+ }
+ else
+ return Status;
+
+ Status = AmiHiiGetString(NULL, Language, PackageList, StringId, String, &StringSize, NULL);
+ }
+
+ Status = HiiStringToImage(This, Flags, String, StringInfo, Blt, BltX, BltY,
+ RowInfoArray, RowInfoArraySize, ColumnInfoArray);
+
+ if(StringSize > 0x100)
+ pBS->FreePool(String);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetGlyph
+//
+// Description:
+// This function is HII Font protocol function GetGlyph implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN CHAR16 Char - Symbol, which glyph to return
+// IN EFI_FONT_DISPLAY_INFO *StringInfo - Pointer to display info
+// IN OUT EFI_IMAGE_OUTPUT **Blt - Pointer to output buffer
+// OUT UINTN *Baseline - Pointer to baseline placeholder
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetGlyph (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN CHAR16 Char,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
+ OUT EFI_IMAGE_OUTPUT **Blt,
+ OUT UINTN *Baseline OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN GlyphNotFound = FALSE;
+ EFI_IMAGE_OUTPUT *Output;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Bitmap;
+ EFI_FONT_HANDLE Font;
+ EFI_FONT_DISPLAY_INFO *Info = NULL;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 *GlyphBlock;
+ BOOLEAN Free;
+
+ if(Blt == NULL || *Blt != NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Font = NULL;
+ Status = HiiGetFontInfo(This, &Font, StringInfo, &Info, NULL);
+ if(EFI_ERROR(Status)) {
+ Font = (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE;
+ Info = NULL;
+ }
+
+//prepare global data values, used in drawing
+ if(Info != NULL) {
+ DefForegroundColor = Info->ForegroundColor;
+ DefBackgroundColor = Info->BackgroundColor;
+ pBS->FreePool(Info);
+ } else {
+ if(StringInfo != NULL) {
+ DefForegroundColor = StringInfo->ForegroundColor;
+ DefBackgroundColor = StringInfo->BackgroundColor;
+ } else {
+ DefForegroundColor = White;
+ DefBackgroundColor = Black;
+ }
+ }
+
+ Status = IntGetGlyph(Font, Char, &Cell, &GlyphBlock, &Free);
+ if(EFI_ERROR(Status))
+ return Status;
+ if(Status == EFI_WARN_UNKNOWN_GLYPH)
+ GlyphNotFound = TRUE;
+
+//allocate memory for output bitmap
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_GRAPHICS_OUTPUT_BLT_PIXEL) * Cell.Width * Cell.Height,
+ &Bitmap);
+ if (EFI_ERROR(Status))
+ return EFI_OUT_OF_RESOURCES;
+
+//allocate memory for output data
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_IMAGE_OUTPUT),
+ &Output);
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(Bitmap);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Output->Width = Cell.Width;
+ Output->Height = Cell.Height;
+ Output->Image.Bitmap = Bitmap;
+
+ ImageWidth = Output->Width;
+ ImageHeight = Output->Height;
+
+//now we are ready to draw the glyph
+ DrawGlyph(0, 0, ImageWidth, ImageHeight, GlyphBlock, FALSE, Bitmap, Cell.Width);
+ if(Free)
+ pBS->FreePool(GlyphBlock);
+
+ *Blt = Output;
+
+ if(Baseline != NULL) {
+ if((UINTN)Font == DEFAULT_FONT_HANDLE)
+ *Baseline = (Cell.Width == EFI_GLYPH_WIDTH) ? 4 : 5; //fixed value for system font
+ else
+ *Baseline = (Cell.OffsetY < 0) ? -(Cell.OffsetY) : 0;
+ }
+
+ return (GlyphNotFound) ? EFI_WARN_UNKNOWN_GLYPH : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetFontInfo
+//
+// Description:
+// This function is HII Font protocol function GetFontInfo implementation
+//
+// Input:
+// IN EFI_HII_FONT_PROTOCOL *This - Pointer to EFI_HII_FONT_PROTOCOL structure
+// IN OUT EFI_FONT_HANDLE *FontHandle - Pointer to font handle
+// IN EFI_FONT_DISPLAY_INFO *StringInfoIn - Pointer to display info
+// OUT EFI_FONT_DISPLAY_INFO *StringInfoOut - Pointer to output display info
+// IN EFI_STRING *String - Pointer to string to test
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetFontInfo (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
+ IN CONST EFI_STRING String OPTIONAL
+)
+{
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Fg;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL Bg;
+ EFI_HII_FONT_STYLE FStyle;
+ UINT16 FSize;
+ CHAR16 *FName;
+ FONT_MATCH_MASK Fm;
+ EFI_STATUS Status;
+ EFI_FONT_DISPLAY_INFO FdInfo;
+
+ if (StringInfoIn == NULL) {
+ /* use default values */
+ FdInfo.FontInfoMask = EFI_FONT_INFO_SYS_FONT |
+ EFI_FONT_INFO_SYS_SIZE |
+ EFI_FONT_INFO_SYS_STYLE |
+ EFI_FONT_INFO_SYS_FORE_COLOR |
+ EFI_FONT_INFO_SYS_BACK_COLOR;
+ } else {
+ FdInfo = *StringInfoIn;
+ FName = (CHAR16 *)StringInfoIn->FontInfo.FontName;
+ }
+ //
+ // Check the font information mask to make sure it is valid.
+ //
+ if (((FdInfo.FontInfoMask & (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ==
+ (EFI_FONT_INFO_SYS_FONT | EFI_FONT_INFO_ANY_FONT)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ==
+ (EFI_FONT_INFO_SYS_SIZE | EFI_FONT_INFO_ANY_SIZE)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ==
+ (EFI_FONT_INFO_SYS_STYLE | EFI_FONT_INFO_ANY_STYLE)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ==
+ (EFI_FONT_INFO_RESIZE | EFI_FONT_INFO_ANY_SIZE)) ||
+ ((FdInfo.FontInfoMask & (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)) ==
+ (EFI_FONT_INFO_RESTYLE | EFI_FONT_INFO_ANY_STYLE)))
+ return EFI_INVALID_PARAMETER;
+
+/* first deal with color attributes */
+ Fg = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_FORE_COLOR) ? White : StringInfoIn->ForegroundColor;
+ Bg = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_BACK_COLOR) ? Black : StringInfoIn->BackgroundColor;
+
+/* retrieve supplied information */
+ FStyle = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_STYLE) ? EFI_HII_FONT_STYLE_NORMAL : StringInfoIn->FontInfo.FontStyle;
+ FSize = (FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_SIZE) ? EFI_GLYPH_HEIGHT : StringInfoIn->FontInfo.FontSize;
+
+ if(FdInfo.FontInfoMask & EFI_FONT_INFO_SYS_FONT) {
+ if(*FontHandle == (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE) {
+ /* we already returned system font, so no other matches for system font present */
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+ /* return system font information and handle */
+ *FontHandle = (EFI_FONT_HANDLE)(UINTN)DEFAULT_FONT_HANDLE;
+ if(StringInfoOut != NULL) {
+ Status = FillFontInfo(*FontHandle, StringInfoOut);
+ if(EFI_ERROR(Status))
+ return Status;
+ (*StringInfoOut)->ForegroundColor = Fg;
+ (*StringInfoOut)->BackgroundColor = Bg;
+ (*StringInfoOut)->FontInfoMask = FdInfo.FontInfoMask;
+ }
+ return EFI_SUCCESS;
+ }
+
+ Fm.MatchName = (FdInfo.FontInfoMask & EFI_FONT_INFO_ANY_FONT) ? MATCH_INGNORE : MATCH_STRICT;
+ Fm.MatchStyle = (FdInfo.FontInfoMask & EFI_FONT_INFO_ANY_STYLE) ? MATCH_INGNORE :
+ (FdInfo.FontInfoMask & EFI_FONT_INFO_RESTYLE) ? MATCH_LOOSE : MATCH_STRICT;
+ Fm.MatchSize = (FdInfo.FontInfoMask & EFI_FONT_INFO_ANY_SIZE) ? MATCH_INGNORE :
+ (FdInfo.FontInfoMask & EFI_FONT_INFO_RESIZE) ? MATCH_LOOSE : MATCH_STRICT;
+
+ Status = FindFont(FontHandle, FName, FStyle, FSize, Fm, String);
+ if(!EFI_ERROR(Status) && (StringInfoOut != NULL)) {
+ /* font found, prepare font info */
+ Status = FillFontInfo(*FontHandle, StringInfoOut);
+ if(EFI_ERROR(Status))
+ return Status;
+ (*StringInfoOut)->ForegroundColor = Fg;
+ (*StringInfoOut)->BackgroundColor = Bg;
+ (*StringInfoOut)->FontInfoMask = FdInfo.FontInfoMask;
+ }
+
+ return Status;
+}
+
+
+
+// *************************** Service functions (not for public use) **********************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsLineBreak
+//
+// Description:
+// This function checks if given symbol is a line break
+//
+// Input:
+// IN CHAR16 Char - Symbol to test
+//
+// Output:
+// TRUE - Symbol is a linebreak
+// FALSE - Symbol is not a linebreak
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLineBreak(CHAR16 Char)
+{
+ switch(Char)
+ {
+ case 0x000c:
+ case 0x000d:
+ case 0x2028:
+ case 0x2029:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsLineBreakOpp
+//
+// Description:
+// This function checks if given symbol is a line break opportunity
+//
+// Input:
+// IN CHAR16 Char - Symbol to test
+//
+// Output:
+// TRUE - Symbol is a linebreak opportunity
+// FALSE - Symbol is not a linebreak opportunity
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLineBreakOpp(CHAR16 Char)
+{
+ if(IsLineBreak(Char))
+ return TRUE;
+
+ if(Char >= 0x2000 && Char <= 0x200a)
+ return TRUE;
+
+ switch (Char)
+ {
+ case 0x0020:
+ case 0x1680:
+ case 0x2013:
+ case 0x205f:
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SplitByLineBreaks
+//
+// Description:
+// This function splits given string into lines on linebreaks
+//
+// Input:
+// IN EFI_STRING String - string to split
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SplitByLineBreaks(EFI_STRING String)
+{
+ UINT32 Size;
+ UINT32 i;
+ DRAW_LINE *Link;
+
+ Size = StrSize16(String) / 2; //size in symbols
+ Link = (DRAW_LINE *)CreateNewLink(sizeof(UINTN) * 5);
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ Link->StartIndex = 0;
+ if(DrawFlags & EFI_HII_IGNORE_LINE_BREAK)
+ {
+ Link->EndIndex = Size - 2; //ignore null terminator
+ UpdateLineSize(Link);
+ DListAdd(&DrawLines, (DLINK *)Link);
+ return EFI_SUCCESS;
+ }
+
+ for(i = 0; i < (Size - 1); i++)
+ {
+ if(IsLineBreak(String[i]))
+ {
+ Link->EndIndex = i;
+ UpdateLineSize(Link);
+ DListAdd(&DrawLines, (DLINK *)Link);
+ Link = (DRAW_LINE *)CreateNewLink(sizeof(UINTN) * 5);
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ i++;
+ Link->StartIndex = i;
+ }
+ }
+ Link->EndIndex = Size - 2;
+ UpdateLineSize(Link);
+ DListAdd(&DrawLines, (DLINK *)Link);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustLineSize
+//
+// Description:
+// This function analyzes lines of the string and makes them fit into drawing area size
+//
+// Input:
+// None
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AdjustLineSize(VOID)
+{
+ DRAW_LINE *Link;
+ UINTN TextHeight = ImageHeight - TextStartY;
+ UINTN TextWidth = ImageWidth - TextStartX;
+ EFI_STATUS Status;
+
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL) {
+//first detect line height
+ if(TextHeight >= Link->LineHeight) {
+ /* line is visible entirely */
+ TextHeight -= Link->LineHeight;
+ } else {
+ /* line is visible partially */
+ if(DrawFlags & EFI_HII_OUT_FLAG_CLIP_CLEAN_Y || TextHeight == 0) {
+ Link->LineHeight = 0; //mark line as invisible and stop adjusting - all subsequent lines will be invisible
+ return EFI_SUCCESS;
+ } else {
+ Link->LineHeight = TextHeight;
+ TextHeight = 0;
+ }
+ }
+
+//second detect line width
+ if(Link->LineWidth > TextWidth) {
+ /* line needs clipping of wrapping */
+ if(DrawFlags & EFI_HII_OUT_FLAG_WRAP) {
+ /* wrapping mode */
+ Status = WrapLine(Link, TextWidth);
+ if(EFI_ERROR(Status))
+ return Status;
+ } else {
+ /* clipping mode */
+ ClipLine(Link, TextWidth, ((DrawFlags & EFI_HII_OUT_FLAG_CLIP_CLEAN_X) ? TRUE : FALSE));
+ }
+ }
+//proceed to next line
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Draw
+//
+// Description:
+// This function draws lines of the string
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Draw(VOID)
+{
+ DRAW_LINE *Link;
+ UINTN i;
+ CHAR16 CurrentSymbol;
+ BOOLEAN Transparent = FALSE;
+ EFI_STATUS Status;
+
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 *GlyphBlock;
+ BOOLEAN Free;
+
+ POINT_COORD gl_st;
+ POINT_COORD gl_size;
+ RECT_COORD glyph;
+
+ POINT_COORD ln_st;
+ POINT_COORD ln_size;
+ RECT_COORD line;
+
+ POINT_COORD origin;
+
+ glyph.st = &gl_st;
+ glyph.size = &gl_size;
+
+ line.st = &ln_st;
+ line.size = &ln_size;
+ ln_st.y = TextStartY; //line start coordinate Y
+
+ if(DrawFlags & EFI_HII_OUT_FLAG_TRANSPARENT)
+ Transparent = TRUE;
+
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL && Link->LineHeight != 0) //loop by strings
+ {
+ /* init line rectangle */
+ ln_st.x = TextStartX; //line start coordinate X
+ ln_size.x = Link->LineWidth; //line width
+ ln_size.y = Link->LineHeight; //line height
+
+ origin.x = ln_st.x;
+ origin.y = ln_st.y + Link->BaseLineOffset;
+
+ for(i = Link->StartIndex; i <= Link->EndIndex; i++)
+ {
+ CurrentSymbol = DrawString[i];
+ if((DrawFlags & EFI_HII_IGNORE_LINE_BREAK) && IsLineBreak(CurrentSymbol))
+ continue;
+
+ Status = IntGetGlyph(CurFont, CurrentSymbol, &Cell, &GlyphBlock, &Free);
+ if(EFI_ERROR(Status))
+ return;
+
+ if(Status == EFI_WARN_UNKNOWN_GLYPH && (DrawFlags & EFI_HII_IGNORE_IF_NO_GLYPH)) {
+ if(Free)
+ pBS->FreePool(GlyphBlock);
+ continue;
+ }
+ /* init glyph rectangle */
+ gl_st.x = origin.x + Cell.OffsetX;
+ gl_st.y = origin.y - (Cell.Height + Cell.OffsetY);
+ gl_size.x = Cell.Width;
+ gl_size.y = Cell.Height;
+
+ if(CheckVisible(&glyph, &line)) {
+ /* symbol is visible at least partially */
+ /* at this point symbol rect coordinates were adjusted to fit visible area */
+ DrawGlyph(gl_st.x, gl_st.y, gl_size.x, gl_size.y, GlyphBlock, Transparent, ImageBlt, Cell.Width);
+ }
+
+ ln_st.x += Cell.AdvanceX;
+ ln_size.x = ((INTN)ln_size.x <= Cell.AdvanceX) ? 0 : ln_size.x - Cell.AdvanceX;
+ origin.x += Cell.AdvanceX;
+
+ if(Free)
+ pBS->FreePool(GlyphBlock);
+ } //end of drawing line
+
+ ln_st.y += ln_size.y;
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiiFontEx.c b/Core/CORE_DXE/UefiHii/HiiFontEx.c
new file mode 100644
index 0000000..32557da
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiFontEx.c
@@ -0,0 +1,1332 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFontEx.c 2 9/17/13 10:19p Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/17/13 10:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiFontEx.c $
+//
+// 2 9/17/13 10:19p Thomaschen
+// Update for EIP105534 and EIP126176.
+//
+// 1 11/21/12 4:08a Wesleychen
+// Update rev.6 for EIP105534.
+// 11 5/16/13 5:01p Artems
+// [TAG] EIP123904
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] HiiFont and HiiConfig SCT tests are failed
+// [RootCause] Regression bugs when implementing new features or spec
+// updates
+// [Solution] Fixed code logic
+// [Files] HiiConfig.c HiiFontEx.c
+//
+// 10 5/02/13 1:52p Artems
+// [TAG] EIP121673
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Incorrect line width returned by function StringToImage
+// [RootCause] When determine line width function ignored flag
+// "IGNORE_IF_NO_GLYPH"
+// so line width was bigger if some glyphs were absent
+// [Solution] Modified code logic to not count width of absent glyphs
+// [Files] HiiFontEx.c
+//
+// 9 5/02/13 1:43p Artems
+// [TAG] EIP113105
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Wording for proportional font display was vague. After
+// clarification
+// code logic was slightly changed
+// [Files] HiiFontEx.c HiiPrivate.h
+//
+// 8 3/26/13 3:18p Artems
+// [TAG] EIP119250
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang on Setup entry
+// [RootCause] Incorrect boundaries checking in HiiFontEx.c function
+// CheckVisible()
+// [Solution] Changed checking condition
+// [Files] HiiFontEx.c
+//
+// 7 2/25/13 4:44p Artems
+// [TAG] EIP101673
+// [Category] New Feature
+// [Description] Add support for AMI custom large fixed font
+// [Files] HiiDatabase.c HiiFontEx.c HiiPrivate.h UefiHiiUtils.c GC.c
+// new LargeFont Core modulePart
+//
+// 6 11/14/12 6:03p Artems
+// [TAG] EIP105534
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] system hangs during SCT execution
+// [RootCause] Incorrect handling of FORM_FEED escape character in
+// StringToImage function
+// [Solution] Graphics console - added flag to ignore line breaks
+// HiiFont - fixed multiline drawing logic
+// [Files] Gc.c HiiFont.c HiiFontEx.c
+//
+// 5 8/24/12 5:34p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] One character is not displayed properly
+// [RootCause] Never accounted for the case, where character is
+// completely below base line
+// [Solution] added check that character height is less than OffsetY
+// [Files] HiiFontEx.c
+//
+// 4 6/15/12 12:21p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] doesn't build in 32-bit mode
+// [RootCause] Signed/Unsigned mismatch reported by 32-bit compiler
+// [Solution] typecasted one parameter to INTN
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 3 6/14/12 6:32p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio fixed SCT reported
+// bugs
+// [Files] HiiFont.c HiiFontEx.c
+//
+// 2 5/24/12 3:00p Artems
+// [TAG] EIP83593
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] system dead loops in HiiGetFontInfo function
+// [RootCause] When loop through linked list of installed fonts pointer
+// was not updated
+// [Solution] Added pointer update
+// [Files] HiiFontEx.c
+//
+// 1 5/22/12 3:29p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support
+// [Files] HiiFontEx.c HiiFont.c HiiDatabase.c HiiString.c HiiPrivate.h
+// UefiHii.h
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiFontEx.c
+//
+// Description: Proportional font support
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <UefiHii.h>
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+#define LOOSE_SIZE_MARGIN 4
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+extern SIMPLE_FONT DefaultFont[];
+extern EFI_FONT_HANDLE CurFont; //font to use
+extern CHAR16 *DrawString; //string to draw
+extern EFI_HII_OUT_FLAGS DrawFlags;
+extern DLIST DrawLines;
+extern UINTN ImageWidth;
+extern UINTN ImageHeight;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefForegroundColor;
+extern EFI_GRAPHICS_OUTPUT_BLT_PIXEL DefBackgroundColor;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DuplicateGlyph
+//
+// Description:
+// This function duplicates glyph from Origin and assigns it to the Char
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+// IN CHAR16 Char - character to assign glyph to
+// IN CHAR16 Origin - character to assign glyph from
+//
+// Output:
+// EFI_NOT_FOUND - glyph for Origin character not found
+// EFI_SUCCESS - glyph created successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to duplicate glyph
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DuplicateGlyph(
+ IN OUT FONT_LINK *Font,
+ IN CHAR16 Char,
+ IN CHAR16 Origin
+)
+{
+ EFI_STATUS Status;
+ GLYPH_LINK *Link = (GLYPH_LINK *)Font->Glyphs.pHead;
+ GLYPH_LINK *New;
+
+ while(Link != NULL) {
+ if(Link->Char == Origin)
+ break;
+ Link = (GLYPH_LINK *) Link->Link.pNext;
+ }
+
+ if(Link == NULL)
+ return EFI_NOT_FOUND;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(GLYPH_LINK), &New);
+ if(!EFI_ERROR(Status)) {
+ New->Char = Char;
+ New->Cell = Link->Cell;
+ New->GlyphBlock = Link->GlyphBlock;
+ DListAdd(&(Font->Glyphs), (DLINK *)New);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddGlyphs
+//
+// Description:
+// This function adds glyphs to specified font
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+// IN EFI_HII_GLYPH_INFO Cell - variable that contains font dimensions
+// IN UINT8 *GlyphBlock - pointer to glyph block
+// IN UINT16 Count - number of glyphs to add
+// IN CHAR16 Char - first character to assign glyph to
+// OUT UINTN *BytesProcessed - number of bytes from glyph block that were assigned
+//
+// Output:
+// EFI_SUCCESS - glyph created successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to add glyphs
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddGlyphs(
+ IN OUT FONT_LINK *Font,
+ IN EFI_HII_GLYPH_INFO Cell,
+ IN UINT8 *GlyphBlock,
+ IN UINT16 Count,
+ IN CHAR16 Char,
+ OUT UINTN *BytesProcessed
+)
+{
+ EFI_STATUS Status;
+ GLYPH_LINK *Glyph;
+ UINTN Bytes = ((Cell.Width + 7) / 8) * Cell.Height;
+ UINTN i;
+
+ for(i = 0; i < Count; i++) {
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(GLYPH_LINK), &Glyph);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Glyph->Cell = Cell;
+ Glyph->Char = Char;
+ Char++;
+ Glyph->GlyphBlock = GlyphBlock;
+ GlyphBlock += Bytes;
+ DListAdd(&(Font->Glyphs), (DLINK *)Glyph);
+ }
+
+ *BytesProcessed = Bytes * Count;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseGlyphs
+//
+// Description:
+// This function parses packed glyphs and creates glyphs for characters
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseGlyphs(
+ IN OUT FONT_LINK *Font
+)
+{
+ EFI_STATUS Status;
+ CHAR16 Current = 1;
+ EFI_HII_GLYPH_INFO Default = Font->FontPackage->Cell;
+ EFI_HII_GLYPH_INFO CurCell;
+ UINT8 *Walker = (UINT8 *)Font->FontPackage;
+ UINT8 *EndMarker;
+ UINTN Bytes;
+ UINT16 CurCount;
+ static const EFI_HII_GLYPH_INFO ZeroCell = { 0, 0, 0, 0, 0 };
+ EFI_HII_GLYPH_INFO ChangeCell;
+ UINTN BelowBaseLine;
+ UINTN AboveBaseLine;
+ UINTN MaxBelowBaseLine = 0;
+ UINTN MaxAboveBaseLine = 0;
+
+ EndMarker = Walker + Font->FontPackage->Header.Length;
+ Walker += Font->FontPackage->GlyphBlockOffset;
+ ChangeCell = Default;
+
+ do {
+ switch (*Walker) {
+ case EFI_HII_GIBT_SKIP1:
+ Current += ((EFI_HII_GIBT_SKIP1_BLOCK *)Walker)->SkipCount;
+ Walker += sizeof(EFI_HII_GIBT_SKIP1_BLOCK);
+ break;
+ case EFI_HII_GIBT_SKIP2:
+ Current += ((EFI_HII_GIBT_SKIP2_BLOCK *)Walker)->SkipCount;
+ Walker += sizeof(EFI_HII_GIBT_SKIP2_BLOCK);
+ break;
+ case EFI_HII_GIBT_EXT1:
+ Walker += sizeof(EFI_HII_GIBT_EXT1_BLOCK);
+ break;
+ case EFI_HII_GIBT_EXT2:
+ Walker += sizeof(EFI_HII_GIBT_EXT2_BLOCK);
+ break;
+ case EFI_HII_GIBT_EXT4:
+ Walker += sizeof(EFI_HII_GIBT_EXT4_BLOCK);
+ break;
+ case EFI_HII_GIBT_DEFAULTS:
+ Default = ((EFI_HII_GIBT_DEFAULTS_BLOCK *)Walker)->Cell;
+ ChangeCell = Default;
+ Walker += sizeof(EFI_HII_GIBT_DEFAULTS_BLOCK);
+ break;
+ case EFI_HII_GIBT_END:
+ break;
+ case EFI_HII_GIBT_GLYPH:
+ CurCell = ((EFI_HII_GIBT_GLYPH_BLOCK *)Walker)->Cell;
+ ChangeCell = CurCell;
+ Walker += sizeof(EFI_HII_GIBT_GLYPH_BLOCK);
+ Status = AddGlyphs(Font, CurCell, Walker, 1, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current++;
+ break;
+ case EFI_HII_GIBT_GLYPH_DEFAULT:
+ Walker += sizeof(EFI_HII_GIBT_GLYPH_DEFAULT_BLOCK);
+ Status = AddGlyphs(Font, Default, Walker, 1, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current++;
+ break;
+ case EFI_HII_GIBT_GLYPHS:
+ CurCell = ((EFI_HII_GIBT_GLYPHS_BLOCK *)Walker)->Cell;
+ CurCount = ((EFI_HII_GIBT_GLYPHS_BLOCK *)Walker)->Count;
+ ChangeCell = CurCell;
+ Walker += sizeof(EFI_HII_GIBT_GLYPHS_BLOCK);
+ Status = AddGlyphs(Font, CurCell, Walker, CurCount, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current += CurCount;
+ break;
+ case EFI_HII_GIBT_GLYPHS_DEFAULT:
+ CurCount = ((EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK *)Walker)->Count;
+ Walker += sizeof(EFI_HII_GIBT_GLYPHS_DEFAULT_BLOCK);
+ Status = AddGlyphs(Font, Default, Walker, CurCount, Current, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += Bytes;
+ Current += CurCount;
+ break;
+ case EFI_HII_GIBT_DUPLICATE:
+ Status = DuplicateGlyph(Font, Current, ((EFI_HII_GIBT_DUPLICATE_BLOCK *)Walker)->CharValue);
+ if(EFI_ERROR(Status))
+ return Status;
+ Walker += sizeof(EFI_HII_GIBT_DUPLICATE_BLOCK);
+ Current++;
+ break;
+ default:
+ return EFI_NOT_FOUND;
+ }
+
+ if(MemCmp(&ChangeCell, (VOID *)&ZeroCell, sizeof(EFI_HII_GLYPH_INFO))) {
+ if(ChangeCell.OffsetY < 0) {
+ BelowBaseLine = (UINTN)(0 - ChangeCell.OffsetY);
+ AboveBaseLine = (ChangeCell.Height > BelowBaseLine) ? (ChangeCell.Height - BelowBaseLine) : 0;
+ } else {
+ AboveBaseLine = ChangeCell.Height + ChangeCell.OffsetY;
+ BelowBaseLine = 0;
+ }
+ MaxBelowBaseLine = (MaxBelowBaseLine >= BelowBaseLine) ? MaxBelowBaseLine : BelowBaseLine;
+ MaxAboveBaseLine = (MaxAboveBaseLine >= AboveBaseLine) ? MaxAboveBaseLine : AboveBaseLine;
+ ChangeCell = ZeroCell;
+ }
+
+ } while(*Walker != 0 && Walker <= EndMarker);
+
+ Font->FontHeight = MaxBelowBaseLine + MaxAboveBaseLine;
+ Font->FontBaseLine = MaxAboveBaseLine;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RepackGlyphBlock
+//
+// Description:
+// This function repacks glyph block of AMI custom font package to be similar
+// to proportional font glyph block for easier processing
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RepackGlyphBlock(
+ IN UINT8 *GlyphBlock,
+ IN UINT16 Width,
+ IN UINT16 Height
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT8 *Tmp;
+ UINT16 Line;
+ UINT16 i, j, k = 0;
+
+ Line = (Width + 7) / 8; //how many bytes describe one line of glyph
+ Size = Line * Height;
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &Tmp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < Height; i++) {
+ for(j = 0; j < Line; j++) {
+ Tmp[k] = GlyphBlock[i + j * Height];
+ k++;
+ }
+ }
+ MemCpy(GlyphBlock, Tmp, Size);
+ pBS->FreePool(Tmp);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseAmiGlyphs
+//
+// Description:
+// This function parses custom AMI packed glyphs and creates glyphs for characters
+//
+// Input:
+// IN OUT FONT_LINK *Font - pointer to current font
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseAmiGlyphs(
+ IN OUT FONT_LINK *Font
+)
+{
+ EFI_STATUS Status;
+ EFI_NARROW_GLYPH *Walker;
+ EFI_HII_GLYPH_INFO CurCell;
+ AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *AmiHdr;
+ UINT16 i;
+ UINTN Bytes;
+
+ AmiHdr = (AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *)Font->FontPackage;
+ CurCell.Width = AmiHdr->Width;
+ CurCell.Height = AmiHdr->Height;
+ CurCell.OffsetX = 0;
+ CurCell.OffsetY = 0;
+ Walker = (EFI_NARROW_GLYPH *)(AmiHdr + 1);
+ for(i = 0; i < AmiHdr->NumberOfNarrowGlyphs; i++) {
+ CurCell.AdvanceX = (Walker->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : CurCell.Width;
+ Status = RepackGlyphBlock(Walker->GlyphCol1, CurCell.Width, CurCell.Height);
+ if(EFI_ERROR(Status))
+ return Status;
+ Status = AddGlyphs(Font, CurCell, Walker->GlyphCol1, 1, Walker->UnicodeWeight, &Bytes);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Walker = (EFI_NARROW_GLYPH *)(Walker->GlyphCol1 + Bytes);
+ }
+
+ Font->FontHeight = AmiHdr->Height;
+ Font->FontBaseLine = AmiHdr->Height;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseFontsPackage
+//
+// Description:
+// This function parses font package
+//
+// Input:
+// IN EFI_HII_FONT_PACKAGE_HDR *Package - pointer to font package
+//
+// Output:
+// EFI_ERROR - some error was encountered during parsing
+// EFI_SUCCESS - glyph created successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseFontsPackage(
+ IN EFI_HII_FONT_PACKAGE_HDR *Package
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_FONT_PACKAGE_HDR *Copy;
+ FONT_LINK *Font;
+
+/* first make global copy of the package */
+ Status = pBS->AllocatePool(EfiBootServicesData, Package->Header.Length, &Copy);
+ if(EFI_ERROR(Status))
+ return Status;
+ MemCpy(Copy, Package, Package->Header.Length);
+
+/* create Font link */
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(FONT_LINK), &Font);
+ if(EFI_ERROR(Status))
+ return Status;
+
+/* initialize font link */
+ Font->FontPackage = Copy;
+ DListInit(&(Font->Glyphs));
+
+ if(Package->Header.Type == AMI_HII_PACKAGE_FONTS)
+ Status = ParseAmiGlyphs(Font);
+ else
+ Status = ParseGlyphs(Font);
+
+ if(!EFI_ERROR(Status))
+ DListAdd(&(PrivateData.FontList), (DLINK *)Font);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchName
+//
+// Description:
+// This function checks whether passed name matches name of the passed font
+//
+// Input:
+// IN FONT_LINK *Font - pointer to font
+// IN CHAR16 *FontName - pointer to font name to match with
+// IN FONT_MATCH_MASK Mask - matching rules
+//
+// Output:
+// TRUE - names are matched
+// FALSE - names are not matched
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchName(
+ IN FONT_LINK *Font,
+ IN CHAR16 *FontName,
+ IN FONT_MATCH_MASK Mask
+)
+{
+ UINT8 *Walker;
+
+ if(Mask.MatchName == MATCH_INGNORE)
+ return TRUE;
+
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS &&
+ !Wcscmp(FontName, L"Ami font"))
+ return TRUE;
+
+ Walker = (UINT8 *)Font->FontPackage;
+ Walker += sizeof(EFI_HII_FONT_PACKAGE_HDR);
+ /* now Walker points to font name */
+ if(Wcscmp(FontName, (CHAR16 *)Walker))
+ return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchStyle
+//
+// Description:
+// This function checks whether passed style matches style of the passed font
+//
+// Input:
+// IN FONT_LINK *Font - pointer to font
+// IN EFI_HII_FONT_STYLE FontStyle - font style to match with
+// IN FONT_MATCH_MASK Mask - matching rules
+//
+// Output:
+// TRUE - styles are matched
+// FALSE - styles are not matched
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchStyle(
+ IN FONT_LINK *Font,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN FONT_MATCH_MASK Mask
+)
+{
+ EFI_HII_FONT_STYLE Cur;
+
+ if(Mask.MatchStyle == MATCH_INGNORE)
+ return TRUE;
+
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS)
+ Cur = EFI_HII_FONT_STYLE_NORMAL;
+ else
+ Cur = Font->FontPackage->FontStyle;
+
+ if(FontStyle == Cur)
+ return TRUE;
+
+/* when restyle is ordered we support interchange between Normal, Bold and Italic styles */
+ if(Mask.MatchStyle == MATCH_LOOSE &&
+ FontStyle <= 3 &&
+ Cur <= 3)
+ return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchSize
+//
+// Description:
+// This function checks whether passed size matches size of the passed font
+//
+// Input:
+// IN FONT_LINK *Font - pointer to font
+// IN UINT16 FontSize - font size to match with
+// IN FONT_MATCH_MASK Mask - matching rules
+//
+// Output:
+// TRUE - sizes are matched
+// FALSE - sizes are not matched
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchSize(
+ IN FONT_LINK *Font,
+ IN UINT16 FontSize,
+ IN FONT_MATCH_MASK Mask
+)
+{
+ UINT16 Cur;
+
+ if(Mask.MatchSize == MATCH_INGNORE)
+ return TRUE;
+
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS)
+ Cur = ((AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *)Font->FontPackage)->Height;
+ else
+ Cur = Font->FontPackage->Cell.Height;
+
+ if(FontSize == Cur)
+ return TRUE;
+
+/* when resize is ordered we support interchange sizes within +/- LOOSE_SIZE_MARGIN from given size */
+ if(Mask.MatchSize == MATCH_LOOSE &&
+ Cur <= FontSize + LOOSE_SIZE_MARGIN &&
+ Cur >= FontSize - LOOSE_SIZE_MARGIN)
+ return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindGlyph
+//
+// Description:
+// This function checks whether glyph for passed character is present, and returns it
+// if necessary
+//
+// Input:
+// IN DLIST Glyphs - linked list of glyphs to search within
+// IN CHAR16 Char - character value to return glyph for
+// OUT GLYPH_LINK **Match OPTIONAL - pointer to store returned glyph
+//
+// Output:
+// TRUE - glyph found
+// FALSE - glyph not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FindGlyph(
+ IN DLIST Glyphs,
+ IN CHAR16 Char,
+ OUT GLYPH_LINK **Match OPTIONAL
+)
+{
+ GLYPH_LINK *Link = (GLYPH_LINK *)Glyphs.pHead;
+
+ while(Link != NULL) {
+ if(Link->Char == Char) {
+ if(Match != NULL)
+ *Match = Link;
+ return TRUE;
+ }
+ Link = (GLYPH_LINK *)Link->Link.pNext;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MatchString
+//
+// Description:
+// This function checks whether all character glyphs are present for given string
+//
+// Input:
+// IN FONT_LINK *Font - pointer to the font
+// IN CONST EFI_STRING String - pointer to the string to check
+//
+// Output:
+// TRUE - all glyphs are present
+// FALSE - some glyphs are missing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MatchString(
+ IN FONT_LINK *Font,
+ IN CONST EFI_STRING String
+)
+{
+ CHAR16 *Tst;
+
+ if(String == NULL)
+ return TRUE;
+
+ Tst = String;
+
+ while(*Tst != 0) {
+ if(!FindGlyph(Font->Glyphs, *Tst, NULL))
+ return FALSE;
+ Tst++;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFont
+//
+// Description:
+// This function tries to find font in database, that meets the criteria
+//
+// Input:
+// IN OUT EFI_FONT_HANDLE *FontHandle - handle in database to start search from
+// IN CHAR16 *FontName - pointer to the font name
+// IN EFI_HII_FONT_STYLE FontStyle - font style
+// IN UINT16 FontSize - font size
+// IN FONT_MATCH_MASK Mask - matching rules
+// IN CONST EFI_STRING String - pointer to string to verify glyphs presence
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindFont(
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CHAR16 *FontName,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN UINT16 FontSize,
+ IN FONT_MATCH_MASK Mask,
+ IN CONST EFI_STRING String
+)
+{
+ FONT_LINK *Font;
+
+ if(PrivateData.FontList.Size == 0)
+ /* no fonts in database */
+ return EFI_NOT_FOUND;
+
+ Font = (FONT_LINK *)PrivateData.FontList.pHead;
+
+/* check if handle passed is not NULL or dummy default font handle */
+ if((UINTN)(*FontHandle) != NULL && (UINTN)(*FontHandle) != DEFAULT_FONT_HANDLE) {
+ while(Font != NULL) {
+ if((VOID *)Font == *FontHandle)
+ break;
+ Font = (FONT_LINK *)Font->Link.pNext;
+ }
+ if(Font == NULL) {
+ /* end of font list - no matches */
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ /* match found, it was last returned font, move to the next */
+ Font = (FONT_LINK *)Font->Link.pNext;
+ if(Font == NULL) {
+ /* end of font list, last returned font was last indeed */
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ while(Font != NULL) {
+ /* loop through font list to find the match */
+ if(MatchName(Font, FontName, Mask) &&
+ MatchStyle(Font, FontStyle, Mask) &&
+ MatchSize(Font, FontSize, Mask) &&
+ MatchString(Font, String)) {
+ /* match is found */
+ *FontHandle = (EFI_FONT_HANDLE)Font;
+ return EFI_SUCCESS;
+ }
+ Font = (FONT_LINK *)Font->Link.pNext;
+ }
+ *FontHandle = NULL;
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillFontInfo
+//
+// Description:
+// This function returns EFI_FONT_DISPLAY_INFO data for given font
+//
+// Input:
+// IN EFI_FONT_HANDLE FontHandle - font handle to return info about
+// OUT EFI_FONT_DISPLAY_INFO **StringInfoOut - pointer where to store returned info
+//
+// Output:
+// EFI_SUCCESS - info returned
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FillFontInfo(
+ IN EFI_FONT_HANDLE FontHandle,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut
+)
+{
+ UINTN NameSize;
+ EFI_FONT_DISPLAY_INFO *Ret;
+ FONT_LINK *Font;
+ UINT8 *Walker;
+ EFI_STATUS Status;
+ static CHAR16 DefaultFontName[] = L"System font";
+
+ Font = (FONT_LINK *)FontHandle;
+ if((UINTN)Font != DEFAULT_FONT_HANDLE) {
+ Walker = (UINT8 *)Font->FontPackage;
+ Walker += sizeof(EFI_HII_FONT_PACKAGE_HDR);
+ } else {
+ Walker = (UINT8 *)DefaultFontName;
+ }
+
+ NameSize = Wcslen((CHAR16 *)Walker) * sizeof(CHAR16);
+
+/* font display info structure includes font info structure, where one CHAR16 already reserved
+ that's why Wcslen used instead fo Wcssize - null-terminator already accounted for */
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_FONT_DISPLAY_INFO) + NameSize, &Ret);
+ if(!EFI_ERROR(Status)) {
+ if((UINTN)Font != DEFAULT_FONT_HANDLE) {
+ if(Font->FontPackage->Header.Type == AMI_HII_PACKAGE_FONTS) {
+ Ret->FontInfo.FontStyle = EFI_HII_FONT_STYLE_NORMAL;
+ Ret->FontInfo.FontSize = ((AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR *)Font->FontPackage)->Height;
+ } else {
+ Ret->FontInfo.FontStyle = Font->FontPackage->FontStyle;
+ Ret->FontInfo.FontSize = Font->FontPackage->Cell.Height;
+ }
+ } else {
+ Ret->FontInfo.FontStyle = EFI_HII_FONT_STYLE_NORMAL;
+ Ret->FontInfo.FontSize = EFI_GLYPH_HEIGHT;
+ }
+ Wcscpy(Ret->FontInfo.FontName, (CHAR16 *)Walker);
+ *StringInfoOut = Ret;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IntGetGlyph
+//
+// Description:
+// This function returns glyph for given charactef from given font
+//
+// Input:
+// IN EFI_FONT_HANDLE FontHandle - font handle of the desired font
+// IN CHAR16 Char - character to return glyph for
+// OUT EFI_HII_GLYPH_INFO *Cell - pointer to store info about glyph dimensions
+// OUT UINT8 **GlyphBlock OPTIONAL - pointer to store glyph
+// OUT BOOLEAN *Free - pointer to return flag was memory allocated for glyph and
+// should be freed by caller
+//
+// Output:
+// EFI_SUCCESS - glyph returned
+// EFI_NOT_FOUND - glyph not found
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IntGetGlyph(
+ IN EFI_FONT_HANDLE FontHandle,
+ IN CHAR16 Char,
+ OUT EFI_HII_GLYPH_INFO *Cell,
+ OUT UINT8 **GlyphBlock OPTIONAL,
+ OUT BOOLEAN *Free
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS AllocStatus;
+ FONT_LINK *Font;
+ GLYPH_LINK *GlyphLink;
+ BOOLEAN Found;
+ SIMPLE_FONT Glyph;
+ UINT8 *WideGlyphBlock;
+ UINTN i;
+
+ *Free = FALSE;
+ Font = (FONT_LINK *)FontHandle;
+
+ if((UINTN)Font != DEFAULT_FONT_HANDLE) {
+ Found = FindGlyph(Font->Glyphs, Char, &GlyphLink);
+ if(!Found) {
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ Found = FindGlyph(Font->Glyphs, 0xfffd, &GlyphLink);
+ }
+ if(Found) {
+ *Cell = GlyphLink->Cell;
+ if(GlyphBlock)
+ *GlyphBlock = GlyphLink->GlyphBlock;
+ return Status;
+ }
+ Glyph = DefaultFont[0xfffd];
+ } else {
+ /* Default font requested */
+ Glyph = DefaultFont[(UINTN)Char];
+ if(Glyph.NarrowGlyph == NULL && Glyph.WideGlyph == NULL) {
+ Glyph = DefaultFont[0xfffd];
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ }
+ }
+/* if we're here we use system font - either because it was requested, or
+because supplied font doesn't have requested character or 0xfffd character
+!!!! It is assumed that system font always have 0xfffd character font */
+ Cell->Height = EFI_GLYPH_HEIGHT;
+ Cell->OffsetX = 0;
+ Cell->OffsetY = 0;
+ if(Glyph.NarrowGlyph != NULL) {
+ Cell->Width = EFI_GLYPH_WIDTH;
+ Cell->AdvanceX = ((Glyph.NarrowGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDTH;
+ if(GlyphBlock)
+ *GlyphBlock = (Glyph.NarrowGlyph)->GlyphCol1;
+ } else if(Glyph.WideGlyph != NULL) {
+ Cell->Width = EFI_GLYPH_WIDE_WIDTH;
+ Cell->AdvanceX = ((Glyph.WideGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDE_WIDTH;
+ if(GlyphBlock) {
+ AllocStatus = pBS->AllocatePool(EfiBootServicesData, sizeof(UINT8) * 2 * EFI_GLYPH_HEIGHT, &WideGlyphBlock);
+ if(EFI_ERROR(AllocStatus))
+ return AllocStatus;
+ for(i = 0; i < EFI_GLYPH_HEIGHT; i++) {
+ WideGlyphBlock[2 * i] = (Glyph.WideGlyph)->GlyphCol1[i];
+ WideGlyphBlock[2 * i + 1] = (Glyph.WideGlyph)->GlyphCol2[i];
+ }
+ *GlyphBlock = WideGlyphBlock;
+ *Free = TRUE;
+ }
+ } else {
+ Cell->AdvanceX = 0;
+ return EFI_NOT_FOUND;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateLineSize
+//
+// Description:
+// This function updates dimensions in pixels of given line based on glyphs of current font
+//
+// Input:
+// IN OUT DRAW_LINE *Line - pointer to the line structure
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateLineSize(
+ IN OUT DRAW_LINE *Line
+)
+{
+ EFI_STATUS Status;
+ UINTN Width = 0;
+ UINTN i;
+ EFI_HII_GLYPH_INFO Cell;
+ BOOLEAN Dummy;
+
+ for(i = Line->StartIndex; i <= Line->EndIndex; i++) {
+ if((DrawFlags & EFI_HII_IGNORE_LINE_BREAK) && IsLineBreak(DrawString[i]))
+ continue;
+
+ Status = IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if(Status == EFI_WARN_UNKNOWN_GLYPH && (DrawFlags & EFI_HII_IGNORE_IF_NO_GLYPH))
+ continue;
+
+ Width = (Cell.AdvanceX < 0) ? Width : Width + (UINT16)Cell.AdvanceX;
+ }
+ Line->LineWidth = Width;
+ Line->LineHeight = ((UINTN)CurFont == DEFAULT_FONT_HANDLE) ? Cell.Height : ((FONT_LINK *)CurFont)->FontHeight;
+ Line->BaseLineOffset = ((UINTN)CurFont == DEFAULT_FONT_HANDLE) ? Cell.Height : ((FONT_LINK *)CurFont)->FontBaseLine;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ClipLine
+//
+// Description:
+// This function updates dimensions in pixels of given line to fit given width
+//
+// Input:
+// IN OUT DRAW_LINE *Line - pointer to the line structure
+// IN UINTN Width - width to fit
+// IN BOOLEAN ClipClean - clipping mode
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ClipLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width,
+ IN BOOLEAN ClipClean
+)
+{
+ UINTN Excess;
+ UINTN i;
+ EFI_HII_GLYPH_INFO Cell;
+ BOOLEAN Dummy;
+
+ Excess = Line->LineWidth - Width;
+
+ for(i = Line->EndIndex; i >= Line->StartIndex; i--) {
+ IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if ((INTN)Excess <= Cell.AdvanceX)
+ break;
+ Excess -= Cell.AdvanceX;
+ Line->LineWidth -= Cell.AdvanceX;
+ }
+
+ if(Excess == Cell.AdvanceX || ClipClean) {
+ /* remove excess character */
+ i--;
+ Line->LineWidth -= Cell.AdvanceX;
+ IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if(Cell.AdvanceX == 0)
+ /* the previous character is non-spacing -remove it also */
+ i--;
+ } else {
+ /* perform partial clipping */
+ Line->LineWidth -= Excess;
+ }
+ Line->EndIndex = i;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WrapLine
+//
+// Description:
+// This function updates dimensions in pixels of given line to fit given width
+// and creates additional line if necessary
+//
+// Input:
+// IN OUT DRAW_LINE *Line - pointer to the line structure
+// IN UINTN Width - width to fit
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WrapLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width
+)
+{
+ UINTN Excess;
+ UINTN i;
+ UINTN NewEnd;
+ UINTN NewStart;
+ DRAW_LINE *NewLine;
+ EFI_HII_GLYPH_INFO Cell;
+ BOOLEAN Dummy;
+ UINTN Save;
+
+ Excess = Line->LineWidth - Width;
+
+ for(i = Line->EndIndex; (i >= Line->StartIndex && i != 0); i--) {
+ IntGetGlyph(CurFont, DrawString[i], &Cell, NULL, &Dummy);
+ if ((INTN)Excess <= Cell.AdvanceX)
+ break;
+ Excess -= Cell.AdvanceX;
+ }
+ if(i == 0 || i == Line->StartIndex) {
+ Line->EndIndex = i;
+ Line->LineWidth = 0;
+ return EFI_SUCCESS;
+ } else {
+ Save = i; //save index of first excess character
+ } //we will you it if no break opp arises for clip_clean operation
+
+/* we skipped excessed characters - start search for line break opp */
+ for(; (i >= Line->StartIndex && i != 0); i--) {
+ if(IsLineBreakOpp(DrawString[i])) {
+ /* we found line break opportunity */
+ NewEnd = Line->EndIndex;
+ NewStart = i + 1;
+ Line->EndIndex = i;
+ UpdateLineSize(Line);
+ if(Line->LineWidth > Width)
+ /* case when line-break opp character is partially visible - skip it */
+ Line->EndIndex--;
+ /* add a new line */
+ NewLine = (DRAW_LINE *)CreateNewLink(sizeof(UINTN) * 5);
+ if(NewLine == NULL)
+ return EFI_OUT_OF_RESOURCES;
+ NewLine->StartIndex = NewStart;
+ NewLine->EndIndex = NewEnd;
+ UpdateLineSize(NewLine);
+ DListInsert(&DrawLines, (DLINK *)NewLine, (DLINK *)Line);
+ return EFI_SUCCESS;
+ }
+ }
+/* if we're here, no line break opp present, use clip clean */
+ Line->EndIndex = Save - 1;
+ UpdateLineSize(Line);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDrawImageSize
+//
+// Description:
+// This function returns size of image necessary to fit processing string
+// including all wraps and clips
+//
+// Input:
+// OUT UINTN *Width - pointer to store required width
+// OUT UINTN *Height - pointer to store required height
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetDrawImageSize(
+ OUT UINTN *Width,
+ OUT UINTN *Height
+)
+{
+ DRAW_LINE *Link;
+ UINTN MaxWidth = 0;
+ UINTN MaxHeight = 0;
+
+ Link = (DRAW_LINE *)(DrawLines.pHead);
+ while(Link != NULL)
+ {
+ MaxWidth = (MaxWidth < Link->LineWidth) ? Link->LineWidth : MaxWidth;
+ MaxHeight += Link->LineHeight;
+ Link = (DRAW_LINE *)Link->Link.pNext;
+ }
+ *Width = MaxWidth;
+ *Height = MaxHeight;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PixelSet
+//
+// Description:
+// This function checks whether pixel with given coordinates is set in given glyph
+//
+// Input:
+// IN UINTN PosX - X coordinate of pixel
+// IN UINTN PosY - Y coordinate of pixel
+// IN UINT8 *GlyphBlock - pointer to glyph array
+// IN UINT16 CharWidth - width of character described by glyph
+//
+// Output:
+// TRUE - pixel is set
+// FALSE - pixel is not set
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN PixelSet(
+ IN UINTN PosX,
+ IN UINTN PosY,
+ IN UINT8 *GlyphBlock,
+ IN UINT16 CharWidth
+)
+{
+ UINTN Step;
+ UINTN Index;
+ UINT8 Bit;
+
+ Step = (CharWidth + 7) / 8;
+ Index = (PosY * Step) + (PosX / 8);
+
+ Bit = (0x80 >> (PosX % 8));
+
+ return (Bit & GlyphBlock[Index]);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DrawGlyph
+//
+// Description:
+// This function draws given glyph on given bitmap
+//
+// Input:
+// IN UINTN StartX - start X coordinate of glyph
+// IN UINTN StartY - start Y coordinate of glyph
+// IN UINTN SizeX - width of glyph
+// IN UINTN SizeY - height of glyph
+// IN UINT8 *GlyphBlock - pointer to glyph array
+// IN BOOLEAN Transparent - flag if image should be transparent
+// IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt - bitmap to draw on
+// IN UINT16 CharWidth - width of character described by glyph
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DrawGlyph(
+ IN UINTN StartX,
+ IN UINTN StartY,
+ IN UINTN SizeX,
+ IN UINTN SizeY,
+ IN UINT8 *GlyphBlock,
+ IN BOOLEAN Transparent,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt,
+ IN UINT16 CharWidth
+)
+{
+ UINTN i;
+ UINTN j;
+ UINTN Index;
+ UINTN Base;
+
+ Base = StartX + StartY * ImageWidth;
+ for(i = 0; i < SizeY; i++ ) {
+ for(j = 0; j < SizeX; j++) {
+ Index = Base + i * ImageWidth + j;
+ if(PixelSet(j, i, GlyphBlock, CharWidth)) {
+ Blt[Index] = DefForegroundColor;
+ } else if (!Transparent) {
+ Blt[Index] = DefBackgroundColor;
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckVisible
+//
+// Description:
+// This function checks whether glyph is withing given image rectangle,
+// and clips glyph rectangle if necessary
+//
+// Input:
+// IN OUT RECT_COORD *Glyph - pointer to glyph rectangle
+// IN RECT_COORD *Image - pointer to image rectangle
+//
+// Output:
+// TRUE - glyph is visible (at least partially)
+// FALSE - glyph is out of image boundaries
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckVisible(
+ IN OUT RECT_COORD *Glyph,
+ IN RECT_COORD *Image
+)
+{
+ UINTN delta_x;
+ UINTN delta_y;
+
+/* check whether glyph within given image rectangle */
+ if(Glyph->st->x >= (Image->st->x + Image->size->x) ||
+ Glyph->st->y >= (Image->st->y + Image->size->y))
+ return FALSE;
+
+/* clip glyph size if necessary */
+ delta_x = (Image->st->x < Glyph->st->x) ? Glyph->st->x - Image->st->x : 0;
+ delta_y = (Image->st->y < Glyph->st->y) ? Glyph->st->y - Image->st->y : 0;
+
+ if(Glyph->size->x > (Image->size->x - delta_x))
+ Glyph->size->x = Image->size->x - delta_x;
+
+ if(Glyph->size->y > (Image->size->y - delta_y))
+ Glyph->size->y = Image->size->y - delta_y;
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/HiiPrivate.h b/Core/CORE_DXE/UefiHii/HiiPrivate.h
new file mode 100644
index 0000000..9023189
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiPrivate.h
@@ -0,0 +1,885 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiPrivate.h 2 9/18/13 1:41a Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/18/13 1:41a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_DXE/UefiHii/HiiPrivate.h $
+//
+// 2 9/18/13 1:41a Thomaschen
+// Update for EIP126176.
+//
+// 16 5/02/13 1:48p Artems
+// [TAG] EIP113105
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Wording for proportional font display was vague. After
+// clarification
+// code logic was slightly changed
+// [Files] HiiFontEx.c HiiPrivate.h
+//
+// 14 2/25/13 4:45p Artems
+// [TAG] EIP101673
+// [Category] New Feature
+// [Description] Add support for AMI custom large fixed font
+// [Files] HiiDatabase.c HiiFontEx.c HiiPrivate.h UefiHiiUtils.c GC.c
+// new LargeFont Core modulePart
+//
+// 13 8/15/12 3:36p Artems
+// [TAG] EIP96755
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Strings in new language added at runtime lost during export
+// [RootCause] Every language represented by its own string package.
+// When
+// strings of new language added at runtime, they're added to database,
+// but not to the list of packages. Export function is working with
+// list of packages, so new language strings will be missed
+// [Solution] Added code to create new string package at runtime when
+// new string
+// of new language is added to database
+// [Files] HiiPrivate.h HiiString.c
+//
+// 12 5/22/12 4:16p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+// UefiHii.h
+//
+// 11 1/05/12 5:05p Artems
+// EIP 76735: Font FFS file is not loaded in framework mode, when in
+// nested FV
+//
+// 10 5/13/11 6:14p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 9 5/13/11 5:17p Artems
+// Function CompareGuid (native EdkII) renamed to HiiCompareGuid to avoid
+// collusion
+//
+// 8 5/05/11 4:14p Artems
+// Add signal "layout changed" event if current layout is deleted
+//
+// 7 1/05/11 12:41p Artems
+// EIP 50995: Added checking of driver handle before adding packages to
+// HII database
+//
+// 6 11/05/10 5:17p Artems
+// EIP 46880: Fixed bug, where two functions referred to the same global
+// pointer
+//
+// 5 9/30/10 6:11p Artems
+// EIP 44657 Added GetAltConfig functionality
+//
+// 4 1/29/10 5:43p Artems
+// EIP 34553 Updated function ExportPackageLists to support NULL pointer
+// as input
+//
+// 3 12/04/09 11:16a Artems
+// Remove keyboard layout functionality added
+//
+// 2 12/03/09 6:04p Artems
+// SCT bug fix
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HiiPrivate.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __HII_PRIVATE__H__
+#define __HII_PRIVATE__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <AmiDxeLib.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/HiiFont.h>
+#include <Protocol/HiiConfigRouting.h>
+
+#define NULL_GUID \
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
+
+#define PACKAGE_LIST_RECORD_SIGNATURE 0x53524c80 //"PLRS"
+#define NOTIFY_LIST_RECORD_SIGNATURE 0x53524c4e //"NLRS"
+
+#define DEFAULT_FONT_HANDLE 0xDEADF000
+#define AMI_HII_PACKAGE_FONTS 0xE1
+
+#pragma pack (push,1)
+
+typedef struct _PACKAGE_LIST_RECORD {
+ DLINK Link;
+ UINT32 Signature;
+ EFI_GUID Guid;
+ EFI_HANDLE DriverHandle;
+ DLIST PackageList;
+ DLIST LanguageList;
+ DLIST StringFontList;
+ DBE_DATABASE StringDb;
+} PACKAGE_LIST_RECORD;
+
+typedef struct _NOTIFY_RECORD {
+ DLINK Link;
+ UINT32 Signature;
+ UINT8 PackageType;
+ EFI_GUID PackageGuid;
+ EFI_HII_DATABASE_NOTIFY PackageNotifyFn;
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType;
+} NOTIFY_RECORD;
+
+typedef struct _HII_DATABASE_PRIVATE_DATA {
+ EFI_HII_DATABASE_PROTOCOL DatabaseProtocol;
+ EFI_HII_STRING_PROTOCOL StringProtocol;
+ EFI_HII_FONT_PROTOCOL FontProtocol;
+ EFI_HII_CONFIG_ROUTING_PROTOCOL ConfigRoutingProtocol;
+ DLIST PackList;
+ DLIST NotifyList;
+ DLIST KeyLayoutList;
+ DLIST FontList;
+ EFI_HII_KEYBOARD_LAYOUT *CurrentLayout;
+} HII_DATABASE_PRIVATE_DATA;
+
+typedef struct _PACKAGE_LINK {
+ DLINK Link;
+ EFI_HII_PACKAGE_HEADER Package;
+} PACKAGE_LINK;
+
+typedef struct _KEY_LAYOUT_LINK {
+ DLINK Link;
+ EFI_HII_KEYBOARD_LAYOUT Layout;
+} KEY_LAYOUT_LINK;
+
+typedef struct _SIMPLE_FONT {
+ EFI_NARROW_GLYPH *NarrowGlyph;
+ EFI_WIDE_GLYPH *WideGlyph;
+} SIMPLE_FONT;
+
+typedef struct _FONT_LINK {
+ DLINK Link;
+ EFI_HII_FONT_PACKAGE_HDR *FontPackage;
+ UINTN FontHeight;
+ UINTN FontBaseLine;
+ DLIST Glyphs;
+} FONT_LINK;
+
+typedef struct _STRING_FONT_LINK {
+ DLINK Link;
+ UINT16 FontId;
+ UINT32 FontInfoSize;
+// EFI_FONT_INFO FontInfo;
+} STRING_FONT_LINK;
+
+typedef struct _GLYPH_LINK {
+ DLINK Link;
+ CHAR16 Char;
+ EFI_HII_GLYPH_INFO Cell;
+ UINT8 *GlyphBlock;
+} GLYPH_LINK;
+
+typedef struct _LANGUAGE_LINK {
+ DLINK Link;
+ UINT16 LastStringId;
+ CHAR8 Language[1];
+} LANGUAGE_LINK;
+
+typedef struct _STRING_RECORD {
+ UINT16 StringId;
+ UINT16 LanguageId;
+ UINT16 FontId;
+ CHAR16 String[1];
+} STRING_RECORD;
+
+typedef struct _DRAW_LINE {
+ DLINK Link;
+ UINTN StartIndex;
+ UINTN EndIndex;
+ UINTN LineHeight;
+ UINTN LineWidth;
+ UINTN BaseLineOffset;
+} DRAW_LINE;
+
+typedef struct _NAME_PATTERN
+{
+ UINTN Length;
+ CHAR16 *Tag;
+} NAME_PATTERN;
+
+typedef struct {
+ CHAR16 *ResultString;
+ UINTN MaxResultStringSize;
+ UINTN CurrentSize;
+} RESULT_BLOCK;
+
+#define MATCH_INGNORE 0
+#define MATCH_STRICT 1
+#define MATCH_LOOSE 2
+
+typedef struct {
+ UINT32 MatchName : 1;
+ UINT32 MatchSize : 2;
+ UINT32 MatchStyle : 2;
+ UINT32 Reserved : 1;
+} FONT_MATCH_MASK;
+
+typedef struct {
+ UINTN x;
+ UINTN y;
+} POINT_COORD;
+
+typedef struct {
+ POINT_COORD *st;
+ POINT_COORD *size;
+} RECT_COORD;
+
+typedef struct {
+ EFI_HII_PACKAGE_HEADER Header;
+ UINT16 NumberOfNarrowGlyphs;
+ UINT8 Height;
+ UINT8 Width;
+// EFI_NARROW_GLYPH NarrowGlyphs[]; //based on height and width given
+} AMICUSTOM_SIMPLE_FONT_PACKAGE_HDR;
+
+#pragma pack (pop)
+
+//************ Database Protocol functions definition **************************
+
+EFI_STATUS HiiNewPack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ IN CONST EFI_HANDLE DriverHandle,
+ OUT EFI_HII_HANDLE *Handle
+);
+
+EFI_STATUS HiiRemovePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle
+);
+
+EFI_STATUS HiiUpdatePack (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN CONST EFI_HII_PACKAGE_LIST_HEADER *PackageList
+);
+
+EFI_STATUS HiiListPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN OUT UINTN *HandleBufferLength,
+ OUT EFI_HII_HANDLE *Handle
+);
+
+EFI_STATUS HiiExportPacks (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer
+);
+
+EFI_STATUS HiiRegisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN CONST EFI_HII_DATABASE_NOTIFY PackageNotifyFn,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS HiiUnregisterNotify (
+ IN CONST EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+EFI_STATUS HiiFindKeyboardLayouts (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_GUID *KeyGuidBuffer
+);
+
+EFI_STATUS HiiGetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid,
+ IN OUT UINT16 *KeyGuidBufferLength,
+ OUT EFI_HII_KEYBOARD_LAYOUT *KeyboardLayout
+);
+
+EFI_STATUS HiiSetKeyboardLayout (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_GUID *KeyGuid
+);
+
+EFI_STATUS HiiGetPackageListHandle (
+ IN EFI_HII_DATABASE_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageListHandle,
+ OUT EFI_HANDLE *DriverHandle
+);
+
+//************************* String protocol functions definition **********
+
+EFI_STATUS HiiNewString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ OUT EFI_STRING_ID *StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST CHAR16 *LanguageName OPTIONAL,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo
+);
+
+EFI_STATUS AmiHiiGetString(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN CONST CHAR8 *Language,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING String,
+ IN OUT UINTN *StringSize,
+ OUT EFI_FONT_INFO **StringFontInfo OPTIONAL
+);
+
+EFI_STATUS AmiHiiSetString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL
+);
+
+EFI_STATUS HiiGetLanguages (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN OUT CHAR8 *Languages,
+ IN OUT UINTN *LanguagesSize
+);
+
+EFI_STATUS HiiGetSecondLanguages(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN CONST CHAR8* FirstLanguage,
+ IN OUT CHAR8 *SecondLanguages,
+ IN OUT UINTN *SecondLanguagesSize
+);
+
+//************************* Font protocol functions definition ****************
+
+EFI_STATUS HiiStringToImage(
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL
+);
+
+EFI_STATUS HiiStringIdToImage (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN EFI_HII_OUT_FLAGS Flags,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8* Language,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo OPTIONAL,
+ IN OUT EFI_IMAGE_OUTPUT **Blt,
+ IN UINTN BltX,
+ IN UINTN BltY,
+ OUT EFI_HII_ROW_INFO **RowInfoArray OPTIONAL,
+ OUT UINTN *RowInfoArraySize OPTIONAL,
+ OUT UINTN *ColumnInfoArray OPTIONAL
+);
+
+EFI_STATUS HiiGetGlyph (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN CHAR16 Char,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfo,
+ OUT EFI_IMAGE_OUTPUT **Blt,
+ OUT UINTN *Baseline OPTIONAL
+);
+
+EFI_STATUS HiiGetFontInfo (
+ IN CONST EFI_HII_FONT_PROTOCOL *This,
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CONST EFI_FONT_DISPLAY_INFO *StringInfoIn,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut,
+ IN CONST EFI_STRING String OPTIONAL
+);
+
+//************************* Config Routing protocol functions definition ******
+
+EFI_STATUS HiiExtractConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+);
+
+EFI_STATUS HiiExportConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+);
+
+EFI_STATUS HiiRouteConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+);
+
+EFI_STATUS HiiBlockToConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigRequest,
+ IN CONST UINT8 *Block,
+ IN CONST UINTN BlockSize,
+ OUT EFI_STRING *Config,
+ OUT EFI_STRING *Progress
+);
+
+EFI_STATUS HiiConfigToBlock (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN OUT CONST UINT8 *Block,
+ IN OUT UINTN *BlockSize,
+ OUT EFI_STRING *Progress
+);
+
+EFI_STATUS HiiGetAltConfig (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ IN CONST EFI_STRING ConfigResp,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId,
+ OUT EFI_STRING *AltCfgResp
+);
+
+//*************************Service functions (not for public use)**************
+
+VOID InvokeRegisteredNotify (
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+);
+
+BOOLEAN FindAndRemovePackages (
+ IN EFI_HII_HANDLE Handle,
+ IN UINT8 PackageType,
+ IN CONST EFI_GUID *PackageGuid,
+ IN BOOLEAN FindOnly
+);
+
+VOID RemovePackage (
+ IN EFI_HII_HANDLE Handle,
+ IN PACKAGE_LINK *Package
+);
+
+EFI_STATUS AddPackage(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ EFI_HII_DATABASE_NOTIFY_TYPE NotifyType
+);
+
+EFI_STATUS AddPackages(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_HII_PACKAGE_LIST_HEADER *PackageList,
+ BOOLEAN Update
+);
+
+EFI_STATUS UpdateStringPackages(
+ IN EFI_HII_HANDLE Handle
+);
+
+UINTN GetStringBlockSize(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language
+);
+
+VOID GetStringBlock(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language,
+ IN UINT8 *Buffer
+);
+
+BOOLEAN MatchPackage(
+ IN UINT8 PackageType,
+ IN EFI_GUID *PackageGuid,
+ IN EFI_HII_PACKAGE_HEADER *Package
+);
+
+BOOLEAN CheckIfPresent(
+ IN EFI_GUID *Guid,
+ IN EFI_HANDLE DriverHandle
+);
+
+EFI_HII_KEYBOARD_LAYOUT* FindLayoutByGuid(
+ IN EFI_GUID *Guid
+);
+
+EFI_STATUS ParseKeyLayoutPackage(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package
+);
+
+EFI_STATUS DeleteKeyboardLayout(
+ IN EFI_HII_KEYBOARD_PACKAGE_HDR *Package
+);
+
+EFI_STATUS ParseSimpleFontsPackage(
+ IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package
+);
+
+EFI_STATUS ParseFontsPackage(
+ IN EFI_HII_FONT_PACKAGE_HDR *Package
+);
+
+EFI_STATUS ParseStringsPackage(
+ PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_HII_STRING_PACKAGE_HDR *Package
+);
+
+PACKAGE_LIST_RECORD* NewPackageListRecord(
+ VOID
+);
+
+NOTIFY_RECORD* NewNotifyRecord(
+ VOID
+);
+
+VOID* CreateNewLink(
+ UINT32 Size
+);
+
+VOID DeleteList(
+ DLIST *List
+);
+
+VOID DeleteStringsFromDatabase(DBE_DATABASE *Database);
+VOID DeleteSimpleFonts(IN EFI_HII_SIMPLE_FONT_PACKAGE_HDR *Package);
+
+UINT32 StrSize8(CHAR8 *String);
+
+UINT32 StrSize16(CHAR16 *String);
+
+VOID StrCpy8(CHAR8 *Dest, CHAR8 *Src);
+
+VOID StrCpy16(CHAR16 *Dest, CHAR16 *Src);
+
+INTN StrCmp8(CHAR8 *Dest, CHAR8 *Src);
+
+INTN StrCmp16(CHAR16 *Dest, CHAR16 *Src);
+
+EFI_STATUS AddLanguage(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ CHAR16* LanguageName,
+ UINT16 LastStringId
+);
+
+EFI_STATUS GetLanguageId(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ UINT16 *LanguageId,
+ LANGUAGE_LINK **Found
+);
+
+EFI_STATUS AddString(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 StringId,
+ UINT16 FontId,
+ EFI_STRING String
+);
+
+EFI_STATUS ExtractStrings(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 *StringId,
+ UINT16 FontId,
+ UINT16 StringCount,
+ BOOLEAN Compressed,
+ VOID *StringBlock
+);
+
+BOOLEAN IsLineBreak(CHAR16 Char);
+
+BOOLEAN IsLineBreakOpp(CHAR16 Char);
+
+UINTN GetGlyphWidth(CHAR16 Char);
+
+UINTN GetLineLength(UINTN StartIndex, UINTN EndIndex);
+
+UINTN GetClipLineLength(
+ UINTN StartIndex,
+ UINTN MaxLength,
+ BOOLEAN ClipClean,
+ UINTN *EndIndex
+);
+
+UINTN GetWrapIndex(
+ UINTN StartIndex,
+ UINTN MaxLength,
+ UINTN *EndIndex,
+ UINTN *StartIndex2
+);
+
+UINTN GetMaxLineLength(VOID);
+
+EFI_STATUS SplitByLineBreaks(EFI_STRING String);
+
+EFI_STATUS AdjustLineSize(VOID);
+
+VOID DrawNarrowGlyph(
+ UINTN StartX,
+ UINTN StartY,
+ UINTN SizeX,
+ UINTN SizeY,
+ CHAR16 Char,
+ BOOLEAN Transparent,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt
+);
+
+VOID DrawWideGlyph(
+ UINTN StartX,
+ UINTN StartY,
+ UINTN SizeX,
+ UINTN SizeY,
+ CHAR16 Char,
+ BOOLEAN Transparent,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt
+);
+
+VOID Draw(VOID);
+
+BOOLEAN CheckPattern(CHAR16 *String, NAME_PATTERN *Pattern);
+
+EFI_STATUS ExtractConfigString(CHAR16 *String, UINTN *NextIndex, CHAR16 **NewString);
+
+BOOLEAN CheckDevicePath(
+ IN UINT8 *DevicePath,
+ IN UINTN DeviceLength,
+ IN EFI_HII_PACKAGE_HEADER *Package);
+
+EFI_STATUS SearchDevicePath(UINT8 *DevicePach, UINTN DpLength, EFI_HANDLE *Handle);
+
+EFI_STATUS ExtractDevicePath(CHAR16 *ConfigString, UINT8 **DevicePath, UINTN *DpLength);
+
+EFI_STATUS FindDeviceHandle(
+ IN CHAR16 *ConfigString,
+ OUT EFI_HANDLE *Handle);
+
+BOOLEAN IsHexDigit(CHAR16 Char);
+UINT8 HexValue(CHAR8 Char);
+
+VOID StringToBlock(
+ IN CHAR16 *String,
+ IN UINTN StringSize,
+ OUT UINT8 *Block);
+
+EFI_STATUS CollectResults(CHAR16 *Result, UINTN Symbols, RESULT_BLOCK *ResultBlock);
+
+UINT32 GetValue(CHAR16 *String, UINTN Start, UINTN End);
+
+EFI_STATUS GetPatternValue(
+ CHAR16 *String,
+ UINTN *Index,
+ NAME_PATTERN *Pattern,
+ UINT32 *Value);
+
+EFI_STATUS GetStringValue(
+ CHAR16 *String,
+ UINTN *Index,
+ UINT8 *Output,
+ UINT32 Width);
+
+EFI_STATUS ReallocResultString(UINTN NewSize, RESULT_BLOCK *ResultBlock);
+
+EFI_STATUS CollectValueResults(UINT8 *Value, UINT32 Width, RESULT_BLOCK *ResultBlock);
+
+EFI_STATUS InitResultBlock(RESULT_BLOCK *ResultBlock);
+
+VOID WriteSwappedBuffer(
+ OUT UINT8 *Output,
+ IN UINT8 *Input,
+ IN UINTN Size);
+
+EFI_STATUS LoadSystemFont();
+
+EFI_STATUS ExportPack(
+ IN EFI_HII_HANDLE Handle,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HII_PACKAGE_LIST_HEADER *Buffer,
+ IN BOOLEAN FirstCall
+);
+
+VOID StringToChar16(
+ IN CHAR16 *String,
+ IN OUT UINTN *Size,
+ OUT CHAR16 *Block
+);
+
+BOOLEAN CompareDevicePath(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+BOOLEAN CompareName(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_STRING Name
+);
+
+BOOLEAN HiiCompareGuid(
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid
+);
+
+EFI_STATUS CheckAltCfg (
+ IN EFI_STRING ConfigString,
+ IN CONST EFI_GUID *Guid,
+ IN CONST EFI_STRING Name,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_STRING AltCfgId
+);
+
+EFI_STATUS SignalKbLayoutChangedEvent(
+ VOID
+);
+
+EFI_STATUS FillFontInfo(
+ IN EFI_FONT_HANDLE FontHandle,
+ OUT EFI_FONT_DISPLAY_INFO **StringInfoOut
+);
+
+EFI_STATUS FindFont(
+ IN OUT EFI_FONT_HANDLE *FontHandle,
+ IN CHAR16 *FontName,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN UINT16 FontSize,
+ IN FONT_MATCH_MASK Mask,
+ IN CONST EFI_STRING String
+);
+
+EFI_STATUS IntGetGlyph(
+ IN EFI_FONT_HANDLE Font,
+ IN CHAR16 Char,
+ OUT EFI_HII_GLYPH_INFO *Cell,
+ OUT UINT8 **GlyphBlock OPTIONAL,
+ OUT BOOLEAN *Free
+);
+
+VOID UpdateLineSize(
+ IN OUT DRAW_LINE *Line
+);
+
+VOID ClipLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width,
+ IN BOOLEAN ClipClean
+);
+
+BOOLEAN CheckVisible(
+ IN OUT RECT_COORD *Glyph,
+ IN RECT_COORD *Image
+);
+
+VOID DrawGlyph(
+ IN UINTN StartX,
+ IN UINTN StartY,
+ IN UINTN SizeX,
+ IN UINTN SizeY,
+ IN UINT8 *GlyphBlock,
+ IN BOOLEAN Transparent,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt,
+ IN UINT16 CharWidth
+);
+
+VOID GetDrawImageSize(
+ OUT UINTN *Width,
+ OUT UINTN *Height
+);
+
+EFI_STATUS WrapLine(
+ IN OUT DRAW_LINE *Line,
+ IN UINTN Width
+);
+
+EFI_STATUS AddStringFont(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ IN UINT16 FontSize,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN CHAR16 *FontName,
+ OUT UINT16 *NewFontId OPTIONAL
+);
+
+UINT16 GetAvailableFontId(
+ IN PACKAGE_LIST_RECORD *PackageList
+);
+
+EFI_STATUS FindStringFontInfoByTemplate(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_FONT_INFO *Template,
+ OUT UINT16 *FontId
+);
+
+EFI_STATUS FindStingFontInfoById(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ OUT EFI_FONT_INFO **Info
+);
+
+VOID CreateLanguageName(
+ IN CHAR8 *RfcName,
+ OUT CHAR16* OutName,
+ UINTN MaxSize
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/CORE_DXE/UefiHii/HiiString.c b/Core/CORE_DXE/UefiHii/HiiString.c
new file mode 100644
index 0000000..91f2708
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/HiiString.c
@@ -0,0 +1,1609 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiString.c 7 8/15/12 3:45p Artems $
+//
+// $Revision: 7 $
+//
+// $Date: 8/15/12 3:45p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/HiiString.c $
+//
+// 7 8/15/12 3:45p Artems
+// [TAG] EIP96755
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Strings in new language added at runtime lost during export
+// [RootCause] Every language represented by its own string package.
+// When
+// strings of new language added at runtime, they're added to database,
+// but not to the list of packages. Export function is working with
+// list of packages, so new language strings will be missed
+// [Solution] Added code to create new string package at runtime when
+// new string
+// of new language is added to database
+// [Files] HiiPrivate.h HiiString.c
+//
+// 6 5/22/12 4:34p Artems
+// [TAG] EIP83593
+// [Category] New Feature
+// [Description] Proportional font support for Aptio
+// [Files] HiiDatabase.c HiiFont.c HiiFontEx.c HiiPrivate.h HiiString.c
+// UefiHii.h
+//
+//
+// 5 10/24/11 5:40p Artems
+// EIP 70530: Bug reported by SCT 2.3.1. Languages shold be compared
+// ignoring case
+//
+// 4 5/13/11 6:15p Artems
+// Renamed functions HiiGetString and HiiSetString to AmiHiiGetString and
+// AmiHiiSetString
+// to avoid collusion with EdkII native library functions
+//
+// 3 12/03/09 12:02p Aaronp
+// Fix for SCT GetSecondLanguages failures.
+//
+// 2 11/23/09 7:38p Felixp
+// HiiGetLanguages is updated to accept NULL language buffer when
+// *LanguagesSize is zero.
+//
+// 1 10/09/09 6:12p Felixp
+//
+// 1 2/27/09 3:55p Artems
+// Initial check-in
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HiiString.c
+//
+// Description: Hii string protocol functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#pragma warning (disable : 4090)
+
+#include <AmiDxeLib.h>
+#include "HiiPrivate.h"
+
+#define DEFAULT_FONT 0x100
+#define INVALID_FONT_ID 0xFEFE
+
+extern HII_DATABASE_PRIVATE_DATA PrivateData;
+
+DBE_OFFSET_KEY_CONTEXT StringDbKeyContext = {EFI_FIELD_OFFSET(STRING_RECORD ,StringId), 4 };
+DBE_KEY_FIELD StringDbKeyField = OFFSET_KEY(StringDbKeyContext);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AmiHiiGetString
+//
+// Description:
+// This function is HII String protocol function GetString implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN CHAR8 *Language - Language definition
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN EFI_STRING_ID StringId - String Id
+// OUT EFI_STRING String - Pointer to output string
+// IN OUT UINTN *StringSize - Pointer to string size value
+// OUT EFI_FONT_INFO *StringFontInfo - Pointer to returned string font info
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - String or StringSize or Language is NULL
+// EFI_NOT_FOUND - String not found
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiHiiGetString(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN CONST CHAR8 *Language,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ OUT EFI_STRING String,
+ IN OUT UINTN *StringSize,
+ OUT EFI_FONT_INFO **StringFontInfo OPTIONAL)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ UINT32 Size;
+ EFI_STATUS Status;
+ LANGUAGE_LINK *Ptr;
+ UINT32 i;
+ UINT16 SaveLanguage;
+
+ if (Language == NULL || StringId < 1 || StringSize == NULL || PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (String == NULL && *StringSize != 0)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ DbKey.StringId = StringId;
+ Status = GetLanguageId(Record, Language, &(DbKey.LanguageId), &Ptr);
+ if(EFI_ERROR(Status))
+ return EFI_INVALID_LANGUAGE;
+
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(EFI_ERROR(Status))
+ {
+ //string not found in database, try different languages
+ SaveLanguage = DbKey.LanguageId;
+ for(i = 0; i < Record->LanguageList.Size; i++)
+ {
+ if (i == SaveLanguage)
+ continue;
+ DbKey.LanguageId = (UINT16)i;
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ return EFI_INVALID_LANGUAGE; //string exists but with different language
+ }
+
+ return EFI_NOT_FOUND;
+ }
+
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+
+ Size = StrSize16(Found->String);
+
+ if(Size > *StringSize)
+ {
+ *StringSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ StrCpy16(String, Found->String);
+ *StringSize = Size;
+
+ if(StringFontInfo != NULL)
+ Status = FindStingFontInfoById(Record, Found->FontId, StringFontInfo);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AmiHiiSetString
+//
+// Description:
+// This function is HII String protocol function SetString implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN EFI_STRING_ID StringId - String Id
+// IN CHAR8 *Language - Language definition
+// IN EFI_STRING String - String to set
+// IN EFI_FONT_INFO *StringFontInfo - Pointer to string font info
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - String or Language is NULL
+// EFI_NOT_FOUND - String not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiHiiSetString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo OPTIONAL)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ UINT32 i;
+ UINT16 SaveLanguage;
+ LANGUAGE_LINK *Ptr;
+ EFI_STATUS Status;
+
+ if(String == NULL || Language == NULL || PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ DbKey.StringId = StringId;
+ Status = GetLanguageId(Record, Language, &(DbKey.LanguageId), &Ptr);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ { //updated string found in database - retreive font info
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ DbKey.FontId = Found->FontId;
+ DbeDelete(&(Record->StringDb), Found, TRUE);
+ }
+ else //try same StringId with different languages
+ {
+ SaveLanguage = DbKey.LanguageId;
+ for(i = 0; i < Record->LanguageList.Size; i++)
+ {
+ if (i == SaveLanguage)
+ continue;
+ DbKey.LanguageId = i;
+ Status = DbeLocateKey(&(Record->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ break;
+ }
+ if(i == Record->LanguageList.Size)
+ return EFI_NOT_FOUND;
+
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ DbKey.FontId = Found->FontId;
+ DbKey.LanguageId = SaveLanguage;
+ }
+
+ if(StringFontInfo != NULL) {
+ Status = FindStringFontInfoByTemplate(Record, StringFontInfo, &DbKey.FontId);
+ if(EFI_ERROR(Status)) {
+ Status = AddStringFont(Record, INVALID_FONT_ID, StringFontInfo->FontSize,
+ StringFontInfo->FontStyle, StringFontInfo->FontName, &DbKey.FontId);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ }
+
+ Status = AddString(Record, DbKey.LanguageId, DbKey.StringId, DbKey.FontId, String);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiNewString
+//
+// Description:
+// This function is HII String protocol function NewString implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// OUT EFI_STRING_ID *StringId - Pointer to returned string Id
+// IN CHAR8 *Language - Language definition
+// IN CHAR16 *LanguageName - Language human readable name
+// IN EFI_STRING String - String to set
+// IN EFI_FONT_INFO *StringFontInfo - Pointer to string font info
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - String or Language or StringId is NULL
+// EFI_NOT_FOUND - Package list handle is invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiNewString (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ OUT EFI_STRING_ID *StringId,
+ IN CONST CHAR8 *Language,
+ IN CONST CHAR16 *LanguageName OPTIONAL,
+ IN CONST EFI_STRING String,
+ IN CONST EFI_FONT_INFO *StringFontInfo)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+ EFI_STATUS Status;
+ UINT16 LanguageId;
+ LANGUAGE_LINK *Link;
+ UINT16 FontId;
+ CHAR16 DefaultName[80];
+
+ if(String == NULL || StringId == NULL || Language == NULL || PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ Status = GetLanguageId(Record, Language, &LanguageId, &Link);
+ if(EFI_ERROR(Status))
+ {
+ Status = AddLanguage(Record, Language, LanguageName, 0);
+ if(EFI_ERROR(Status))
+ return Status;
+ Status = GetLanguageId(Record, Language, &LanguageId, &Link);
+ //language added, now add language name string to database
+ if(LanguageName == NULL) {
+ CreateLanguageName(Language, DefaultName, 80 * sizeof(CHAR16));
+ LanguageName = DefaultName;
+ }
+ //at this point LastStringId has value LanguageName + 1
+ Status = AmiHiiSetString(This, PackageList, Link->LastStringId - 1, Language, LanguageName, NULL);
+ }
+
+ if(StringFontInfo != NULL) {
+ Status = FindStringFontInfoByTemplate(Record, StringFontInfo, &FontId);
+ if(EFI_ERROR(Status)) {
+ Status = AddStringFont(Record, INVALID_FONT_ID, StringFontInfo->FontSize,
+ StringFontInfo->FontStyle, StringFontInfo->FontName, &FontId);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ } else {
+ FontId = DEFAULT_FONT;
+ }
+
+ Status = AddString(Record, LanguageId, Link->LastStringId, FontId, String);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ *StringId = Link->LastStringId;
+
+ Link->LastStringId++;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetLanguages
+//
+// Description:
+// This function is HII String protocol function GetLanguages implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN OUT CHAR8 *Languages - Pointer to returned language buffer
+// IN OUT UINTN *LanguagesSize - Pointer to language buffer size
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - LanguagesSize or Languages is NULL
+// EFI_NOT_FOUND - Package list handle is invalid or NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetLanguages (
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN OUT CHAR8 *Languages,
+ IN OUT UINTN *LanguagesSize
+)
+{
+ PACKAGE_LIST_RECORD *Record = (PACKAGE_LIST_RECORD *)PackageList;
+// EFI_STATUS Status;
+ LANGUAGE_LINK *Link;
+ UINTN Size = 0;
+
+ if(PackageList == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (Record->Signature != PACKAGE_LIST_RECORD_SIGNATURE)
+ return EFI_NOT_FOUND;
+
+ if(LanguagesSize == NULL || Languages == NULL && *LanguagesSize != 0)
+ return EFI_INVALID_PARAMETER;
+
+ if(Record->LanguageList.Size == 0)
+ {
+ *LanguagesSize = 0;
+ *Languages = 0;
+ return EFI_SUCCESS;
+ }
+
+ Link = (LANGUAGE_LINK *)Record->LanguageList.pHead;
+ while(Link != NULL)
+ {
+ Size += StrSize8(Link->Language);
+ Link = (LANGUAGE_LINK *)Link->Link.pNext;
+ }
+
+ if(Size > *LanguagesSize)
+ {
+ *LanguagesSize = Size;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *LanguagesSize = Size;
+
+ Link = (LANGUAGE_LINK *)Record->LanguageList.pHead;
+ while(Link != NULL)
+ {
+ Size = StrSize8(Link->Language);
+ Size--; //skip NULL-terminator
+ MemCpy(Languages, Link->Language, Size);
+ Languages += Size; //shift pointer
+ *Languages = ';'; //add delimiter
+ Languages++;
+ Link = (LANGUAGE_LINK *)Link->Link.pNext;
+ }
+
+ Languages--; //change delimiter to NULL-terminator
+ *Languages = 0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetSecondLanguages
+//
+// Description:
+// This function is HII String protocol function GetSecondaryLanguages implementation
+//
+// Input:
+// IN EFI_HII_STRING_PROTOCOL *This - Pointer to EFI_HII_STRING_PROTOCOL structure
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN CHAR8 *FirstLanguage - First language definition
+// IN OUT CHAR8 *Languages - Pointer to returned language buffer
+// IN OUT UINTN *LanguagesSize - Pointer to language buffer size
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - LanguagesSize or Languages is NULL
+// EFI_NOT_FOUND - Package list handle is invalid or NULL
+// EFI_BUFFER_TOO_SMALL - Allocated buffer too small
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HiiGetSecondLanguages(
+ IN CONST EFI_HII_STRING_PROTOCOL *This,
+ IN EFI_HII_HANDLE PackageList,
+ IN CONST CHAR8 *FirstLanguage,
+ IN OUT CHAR8 *SecondLanguages,
+ IN OUT UINTN *SecondLanguagesSize
+)
+{
+ EFI_STATUS Status;
+ UINTN Size = 0;
+ UINTN i = 0;
+
+ CHAR8 *Langs = NULL;
+
+ if(FirstLanguage == NULL || SecondLanguages == NULL || SecondLanguagesSize == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ // Get the size of all the languages in the Hii Package
+ Status = HiiGetLanguages(This, PackageList, NULL, &Size);
+
+ if(EFI_ERROR(Status) && Status != EFI_BUFFER_TOO_SMALL)
+ return Status;
+
+ // Allocate space for the languages
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &Langs);
+
+ if(!EFI_ERROR(Status))
+ // Get the langues into the temp buffer
+ Status = HiiGetLanguages(This, PackageList, Langs, &Size);
+
+ // find and remove the primary language from the string
+ if(!EFI_ERROR(Status))
+ {
+ Status = EFI_INVALID_LANGUAGE;
+
+ for(; i < Size; i++)
+ {
+ // check if the current offset matches the first language
+ if(MemCmp(Langs+i,FirstLanguage,StrSize8(FirstLanguage)-1) == 0)
+ {
+ Status = EFI_SUCCESS;
+
+ // copy the rest of the string on top of the primary strings location
+ pBS->CopyMem(Langs+i,Langs+i+StrSize8(FirstLanguage),StrSize8(Langs)-i-StrSize8(FirstLanguage));
+ break;
+ }
+ }
+ }
+
+ if(!EFI_ERROR(Status))
+ {
+ Status = EFI_BUFFER_TOO_SMALL;
+
+ // Check if the buffer is large enough to fit the secondary langues
+ if(*SecondLanguagesSize >= StrSize8(Langs))
+ {
+ Status = EFI_SUCCESS;
+ MemCpy(SecondLanguages, Langs, StrSize8(Langs));
+ }
+
+ // fill in the size of the secondary langauges
+ *SecondLanguagesSize = StrSize8(Langs);
+ }
+
+ if(Langs != NULL)
+ pBS->FreePool(Langs);
+
+ return Status;
+}
+
+// *************************** Service functions (not for public use) ************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateLanguageName
+//
+// Description:
+// This function creates human-readable language name from RFC name
+//
+// Input:
+// IN CHAR8 *RfcName - pointer to RFC name
+// OUT CHAR16* OutName - pointer where to store human-readable name
+// UINTN MaxSize - max size of output buffer in bytes
+//
+// Output:
+// UINT16 - number of strings in package
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateLanguageName(
+ IN CHAR8 *RfcName,
+ OUT CHAR16* OutName,
+ UINTN MaxSize)
+{
+ UINTN i;
+
+ for(i = 0; (RfcName[i] != 0 && i < (MaxSize / 2 - 1)); i++)
+ OutName[i] = RfcName[i];
+ OutName[i] = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringPackage
+//
+// Description:
+// This function creates string package for language not existed in package list
+// at the time of submission to database
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where language belongs
+// IN CHAR8 *Language - Language RFC name
+//
+// Output:
+// UINT16 - number of strings in package
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 AddStringPackage(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language)
+{
+ UINT32 Size;
+ PACKAGE_LINK *Template;
+ PACKAGE_LINK *NewLink;
+ DLIST *PackList;
+ UINT16 LanguageStringId;
+ UINT32 i;
+ EFI_HII_STRING_PACKAGE_HDR *Hdr;
+ EFI_HII_STRING_PACKAGE_HDR *NewHdr;
+
+ PackList = &(PackageList->PackageList);
+ Template = (PACKAGE_LINK *)PackList->pHead;
+ while(Template != NULL) {
+ if(Template->Package.Type == EFI_HII_PACKAGE_STRINGS)
+ break;
+ Template = (PACKAGE_LINK *)Template->Link.pNext;
+ }
+
+ if(Template == NULL) {//no string packages in this package list
+ LanguageStringId = 1;
+ } else {
+ Hdr = (EFI_HII_STRING_PACKAGE_HDR *)&(Template->Package);
+ LanguageStringId = Hdr->LanguageName;
+ }
+
+ Size = sizeof(EFI_HII_STRING_PACKAGE_HDR) - 1;
+ Size += StrSize8(Language);
+
+ NewLink = (PACKAGE_LINK *) CreateNewLink(Size);
+ if(NewLink == NULL)
+ return 0;
+
+ NewLink->Package.Type = EFI_HII_PACKAGE_STRINGS;
+ NewLink->Package.Length = Size; //this is technically incorrect, but it will be updated upon export
+ NewHdr = (EFI_HII_STRING_PACKAGE_HDR *)&(NewLink->Package);
+ NewHdr->HdrSize = Size;
+ NewHdr->StringInfoOffset = Size;
+ if(Template == NULL) {
+ for(i = 0; i < 16; i++)
+ NewHdr->LanguageWindow[i] = 0;
+ } else {
+ for(i = 0; i < 16; i++)
+ NewHdr->LanguageWindow[i] = Hdr->LanguageWindow[i];
+ }
+ NewHdr->LanguageName = LanguageStringId;
+ StrCpy8(NewHdr->Language, Language);
+ DListAdd(PackList, (DLINK *)NewLink);
+ return LanguageStringId + 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddLanguage
+//
+// Description:
+// This function adds language to private HII database
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where language belongs
+// IN EFI_HII_HANDLE PackageList - Handle of package list
+// IN CHAR8 *Language - Language Id
+// IN CHAR16 *LanguageName - Pointer to human readable language name
+// IN UINT16 LastStringId - Last string Id on this language
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddLanguage(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ CHAR16* LanguageName,
+ UINT16 LastStringId)
+{
+ UINT32 Size1, Size2 = 0;
+ LANGUAGE_LINK *Link;
+ CHAR16 DefaultName[80];
+ UINT8 *Ptr;
+
+ Size1 = StrSize8(Language);
+
+ if(LanguageName == NULL) {
+ CreateLanguageName(Language, DefaultName, 80 * sizeof(CHAR16));
+ LanguageName = DefaultName;
+ }
+
+ Size2 = StrSize16(LanguageName);
+
+ Link = (LANGUAGE_LINK *)CreateNewLink(Size1 + Size2 + sizeof(UINT32));
+ if(Link == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ if(LastStringId != 0) {
+ Link->LastStringId = LastStringId;
+ } else {
+ //we're adding language, that wasn't in package list from the start
+ Link->LastStringId = AddStringPackage(PackageList, Language);
+ if(Link->LastStringId == 0)
+ return EFI_OUT_OF_RESOURCES;
+ }
+ StrCpy8(Link->Language, Language);
+
+ Ptr = (UINT8 *)Link->Language;
+ Ptr += Size1;
+ StrCpy16((CHAR16 *)Ptr, LanguageName);
+
+ DListAdd(&(PackageList->LanguageList), (DLINK *)Link);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLanguageId
+//
+// Description:
+// This function returns language private Id which corresponds with given language Id
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where language belongs
+// IN CHAR8 *Language - Language Id
+// OUT UINT16 *LanguageId - Pointer where to return private Id
+// OUT LANGUAGE_LINK **Found - Pointer where to return found language private data
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_NOT_FOUND - language not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetLanguageId(
+ PACKAGE_LIST_RECORD *PackageList,
+ CHAR8 *Language,
+ UINT16 *LanguageId,
+ LANGUAGE_LINK **Found OPTIONAL)
+{
+ LANGUAGE_LINK *Link = (LANGUAGE_LINK *)PackageList->LanguageList.pHead;
+ UINT8 Id;
+
+ Id = 0;
+ while(Link != NULL)
+ {
+ if(LanguageCodesEqual(Language, Link->Language))
+ {
+ *LanguageId = Id;
+
+ if(Found)
+ *Found = Link;
+
+ return EFI_SUCCESS;
+ }
+ Link = (LANGUAGE_LINK *)Link->Link.pNext;
+ Id++;
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddString
+//
+// Description:
+// This function adds string to private storage
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where string belongs
+// IN UINT16 LanguageId - Private language Id of the string
+// IN UINT16 StringId - Private string Id of the string
+// IN UINT16 FontId - Private font Id of the string
+// IN EFI_STRING String - String to add
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddString(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 StringId,
+ UINT16 FontId,
+ EFI_STRING String)
+{
+ STRING_RECORD *Record;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+ Size = StrSize16(String);
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Size + 6,
+ &Record);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Record->FontId = FontId;
+ Record->LanguageId = LanguageId;
+ Record->StringId = StringId;
+ StrCpy16(Record->String, String);
+
+ DbeInsert(&(PackageList->StringDb), Record);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseStringsPackage
+//
+// Description:
+// This function parses string package
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where string package belongs
+// IN EFI_HII_STRING_PACKAGE_HDR *Package - Pointer to package to parse
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseStringsPackage(
+ PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_HII_STRING_PACKAGE_HDR *Package)
+{
+ EFI_STATUS Status;
+ LANGUAGE_LINK *Link;
+ UINT16 LanguageId;
+ UINT16 StringId;
+ UINT16 FontId;
+ EFI_HII_STRING_BLOCK *ParsePointer;
+ UINT16 StringCount;
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ BOOLEAN NewLanguage = FALSE;
+ CHAR16 *FontName;
+
+ ParsePointer = (EFI_HII_STRING_BLOCK *)Package;
+ (UINT8 *)ParsePointer += Package->StringInfoOffset;
+
+ Status = GetLanguageId(PackageList, Package->Language, &LanguageId, &Link);
+ if(EFI_ERROR(Status))
+ {
+ LanguageId = (UINT16)PackageList->LanguageList.Size;
+ StringId = 1;
+ NewLanguage = TRUE;
+ }
+ else
+ StringId = Link->LastStringId;
+
+ while(ParsePointer->BlockType != EFI_HII_SIBT_END)
+ {
+ switch(ParsePointer->BlockType)
+ {
+ case EFI_HII_SIBT_SKIP1:
+ StringId += ((EFI_HII_SIBT_SKIP1_BLOCK *)ParsePointer)->SkipCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_SKIP1_BLOCK);
+ break;
+ case EFI_HII_SIBT_SKIP2:
+ StringId += ((EFI_HII_SIBT_SKIP2_BLOCK *)ParsePointer)->SkipCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ break;
+ case EFI_HII_SIBT_EXT1:
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_EXT1_BLOCK *)ParsePointer)->Length;
+ break;
+ case EFI_HII_SIBT_EXT2:
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_EXT2_BLOCK *)ParsePointer)->Length;
+ break;
+ case EFI_HII_SIBT_EXT4:
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_EXT4_BLOCK *)ParsePointer)->Length;
+ break;
+ case EFI_HII_SIBT_FONT:
+ FontName = (CHAR16 *)((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer + 1);
+ Status = AddStringFont(PackageList,
+ ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->FontId,
+ ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->FontSize,
+ ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->FontStyle,
+ FontName, NULL);
+ if(EFI_ERROR(Status))
+ return Status;
+ (UINT8 *)ParsePointer += ((EFI_HII_SIBT_FONT_BLOCK *)ParsePointer)->Header.Length;
+ break;
+ case EFI_HII_SIBT_STRING_SCSU:
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_SCSU_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ 1, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRING_SCSU_FONT:
+ FontId = ((EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_SCSU_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ 1, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_SCSU:
+ StringCount = ((EFI_HII_SIBT_STRINGS_SCSU_BLOCK *)ParsePointer)->StringCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_SCSU_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ StringCount, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_SCSU_FONT:
+ StringCount = ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ParsePointer)->StringCount;
+ FontId = ((EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_SCSU_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ StringCount, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ case EFI_HII_SIBT_STRING_UCS2:
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ 1, FALSE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRING_UCS2_FONT:
+ FontId = ((EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRING_UCS2_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ 1, FALSE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_UCS2:
+ StringCount = ((EFI_HII_SIBT_STRINGS_UCS2_BLOCK *)ParsePointer)->StringCount;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_UCS2_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, DEFAULT_FONT,
+ StringCount, FALSE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ break;
+ case EFI_HII_SIBT_STRINGS_UCS2_FONT:
+ StringCount = ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *)ParsePointer)->StringCount;
+ FontId = ((EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK *)ParsePointer)->FontIdentifier;
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_STRINGS_UCS2_FONT_BLOCK);
+ Status = ExtractStrings(PackageList, LanguageId, &StringId, FontId,
+ StringCount, TRUE, &ParsePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+ case EFI_HII_SIBT_DUPLICATE:
+ DbKey.LanguageId = LanguageId;
+ DbKey.StringId = ((EFI_HII_SIBT_DUPLICATE_BLOCK *)ParsePointer)->StringId;
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+ if(!EFI_ERROR(Status))
+ {
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ Status = AddString(PackageList, Found->LanguageId, StringId, Found->FontId, Found->String);
+ if(EFI_ERROR(Status))
+ return Status;
+ StringId++;
+ }
+ (UINT8 *)ParsePointer += sizeof(EFI_HII_SIBT_DUPLICATE_BLOCK);
+ break;
+ default:
+ break;
+ }
+ }
+
+//Reconstruct full language name
+
+ if(NewLanguage)
+ {
+ DbKey.LanguageId = LanguageId;
+ DbKey.StringId = Package->LanguageName;
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, NULL);
+
+ if(!EFI_ERROR(Status))
+ {
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ Status = AddLanguage(PackageList, Package->Language, Found->String, StringId);
+ }
+ else
+ Status = AddLanguage(PackageList, Package->Language, NULL, StringId);
+
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+ else
+ Link->LastStringId = StringId;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExtractStrings
+//
+// Description:
+// This function extracts strings from given block of strings
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where strings belong
+// IN UINT16 LanguageId - Private language Id
+// IN OUT UINT16 *StringId - Pointer to string Id
+// IN UINT16 FontId - Font Id
+// IN UINT16 StringCount - Number of strings to extract
+// IN BOOLEAN Compressed - Flag, that determines whether string is compressed or not
+// IN OUT VOID **StringBlock - Pointer to block of strings to extract
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ExtractStrings(
+ PACKAGE_LIST_RECORD *PackageList,
+ UINT16 LanguageId,
+ UINT16 *StringId,
+ UINT16 FontId,
+ UINT16 StringCount,
+ BOOLEAN Compressed,
+ VOID **StringBlock
+)
+{
+ UINT16 i;
+ EFI_STATUS Status;
+ UINT32 StringSize;
+ UINT32 MaxSize = 0x100;
+ CHAR16 *String = NULL;
+ VOID *Pointer = *StringBlock;
+
+ if(Compressed)
+ {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * MaxSize,
+ &String);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ for(i = 0; i < StringCount; i++)
+ {
+ if(Compressed)
+ {
+ StringSize = StrSize8((CHAR8 *)Pointer);
+ if(StringSize > MaxSize)
+ {
+ MaxSize = StringSize;
+ pBS->FreePool(String);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CHAR16) * MaxSize,
+ &String);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+// UncompressString(String, (CHAR8 *)Pointer);
+ Status = AddString(PackageList, LanguageId, *StringId, FontId, String);
+ }
+ else
+ {
+ StringSize = StrSize16(Pointer);
+ Status = AddString(PackageList, LanguageId, *StringId, FontId, (EFI_STRING)Pointer);
+ }
+
+ if(EFI_ERROR(Status))
+ return Status;
+ (*StringId)++;
+ (UINT8 *)Pointer += StringSize;
+ }
+ *StringBlock = Pointer;
+ if(String != NULL)
+ pBS->FreePool(String);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringBlockSize
+//
+// Description:
+// This function determines block size needed to pack strings into string package
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where strings belong
+// IN CHAR8 *Language - Language Id
+//
+// Output:
+// UINTN - String block size in bytes
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN GetStringBlockSize(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language)
+{
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ EFI_STATUS Status;
+ UINTN RecordIndex;
+ DBE_DATABASE *Database = &(PackageList->StringDb);
+ UINT16 StringCounter = 0;
+ UINT16 SkipBlock = 0; //number of skip blocks to add to string block
+ UINT16 CurrentStringId;
+ UINTN Size = 0;
+ UINTN i;
+
+ Status = GetLanguageId(PackageList, Language, &(DbKey.LanguageId), NULL);
+ if(EFI_ERROR(Status))
+ return 0;
+
+ DbKey.StringId = 1; //find first string with given language
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, &RecordIndex);
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ if(EFI_ERROR(Status))
+ { //there isn't string with string id = 1
+ if(Found->LanguageId != DbKey.LanguageId) //we got string from previous language
+ {
+ RecordIndex++;
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, RecordIndex, &Found);
+ }
+ SkipBlock++; //at least one skip block should be added as far as we don't have string with id=1
+ }
+ CurrentStringId = Found->StringId;
+ Size += StrSize16(Found->String);
+ StringCounter++;
+
+ for(i = RecordIndex + 1;
+ (i < PackageList->StringDb.RecordCount) && (Found->LanguageId == DbKey.LanguageId);
+ i++)
+ {
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, i, &Found);
+ Size += StrSize16(Found->String);
+ StringCounter++;
+ if(Found->StringId > (CurrentStringId + 1))
+ SkipBlock++;
+ CurrentStringId = Found->StringId;
+ }
+
+ Size += SkipBlock * sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ Size += StringCounter * sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Size += sizeof(EFI_HII_SIBT_END_BLOCK);
+
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringBlock
+//
+// Description:
+// This function packs strings from private storage into string package format
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - Pointer to package list where strings belong
+// IN CHAR8 *Language - Language Id
+// OUT UINT8 *Buffer - Pointer to output buffer
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetStringBlock(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN CHAR8 *Language,
+ IN UINT8 *Buffer)
+{
+ STRING_RECORD DbKey;
+ INT8 Vicinity;
+ STRING_RECORD *Found;
+ UINTN *FindRecord;
+ EFI_STATUS Status;
+ UINTN RecordIndex;
+ DBE_DATABASE *Database = &(PackageList->StringDb);
+ UINT16 StringCounter = 0;
+ UINT16 SkipBlock = 0; //number of skip blocks to add to string block
+ UINT16 CurrentStringId = 1;
+ UINTN Size = 0;
+ UINTN i;
+
+ Status = GetLanguageId(PackageList, Language, &(DbKey.LanguageId), NULL);
+
+ DbKey.StringId = 1; //find first string with given language
+ Status = DbeLocateKey(&(PackageList->StringDb), 0, &DbKey, &FindRecord, &Vicinity, &RecordIndex);
+ Found = (STRING_RECORD *)(UINTN)(*FindRecord);
+ if(EFI_ERROR(Status))
+ { //there isn't string with string id = 1
+ if(Found->LanguageId != DbKey.LanguageId) //we got string from previous language
+ {
+ RecordIndex++;
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, RecordIndex, &Found);
+ }
+
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->SkipCount = Found->StringId - CurrentStringId - 1;
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_SKIP2;
+ Buffer += sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ }
+ CurrentStringId = Found->StringId;
+ ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_STRING_UCS2;
+ Buffer += sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Size = StrSize16(Found->String);
+ StrCpy16((CHAR16 *)Buffer, Found->String);
+ Buffer += Size;
+
+ for(i = RecordIndex + 1;
+ (i < PackageList->StringDb.RecordCount) && (Found->LanguageId == DbKey.LanguageId);
+ i++)
+ {
+ Status = DbeGoToIndex(&(PackageList->StringDb), 0, i, &Found);
+
+ if(Found->StringId > (CurrentStringId + 1)) //add skip block
+ {
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->SkipCount = Found->StringId - CurrentStringId - 1;
+ ((EFI_HII_SIBT_SKIP2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_SKIP2;
+ Buffer += sizeof(EFI_HII_SIBT_SKIP2_BLOCK);
+ }
+
+ ((EFI_HII_SIBT_STRING_UCS2_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_STRING_UCS2;
+ Buffer += sizeof(EFI_HII_SIBT_STRING_UCS2_BLOCK);
+ Size = StrSize16(Found->String);
+ StrCpy16((CHAR16 *)Buffer, Found->String);
+ Buffer += Size;
+ CurrentStringId = Found->StringId;
+ }
+ ((EFI_HII_SIBT_END_BLOCK *)Buffer)->Header.BlockType = EFI_HII_SIBT_END;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStringPackages
+//
+// Description:
+// This function updates string package with strings contained in private storage
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - Handle of package list to update
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - Not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateStringPackages(EFI_HII_HANDLE Handle)
+{
+ DLIST *PackageList;
+ PACKAGE_LINK *Link;
+ PACKAGE_LINK *NewLink;
+ EFI_HII_STRING_PACKAGE_HDR *StringPackage;
+ UINT8 *Buffer;
+ UINTN Size;
+
+ PackageList = &(((PACKAGE_LIST_RECORD *)Handle)->PackageList);
+ Link = (PACKAGE_LINK *)(PackageList->pHead);
+
+ while(Link != NULL)
+ {
+ if(Link->Package.Type == EFI_HII_PACKAGE_STRINGS)
+ {
+ StringPackage = (EFI_HII_STRING_PACKAGE_HDR *) &(Link->Package);
+ Size = GetStringBlockSize((PACKAGE_LIST_RECORD *)Handle, StringPackage->Language);
+
+ if(Size != 0)
+ {
+ Size += StringPackage->HdrSize;
+ NewLink = (PACKAGE_LINK *) CreateNewLink((UINT32)Size);
+ if(NewLink == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ MemCpy((VOID *) &(NewLink->Package),
+ (VOID *) &(Link->Package),
+ StringPackage->HdrSize);
+ NewLink->Package.Length = (UINT32)Size;
+ Buffer = (UINT8 *) &(NewLink->Package);
+ Buffer += StringPackage->HdrSize;
+
+ GetStringBlock((PACKAGE_LIST_RECORD *)Handle, StringPackage->Language, Buffer);
+
+ DListInsert(PackageList, (DLINK *)NewLink, (DLINK *)Link);
+ DListDelete(PackageList, (DLINK *)Link);
+ pBS->FreePool(Link);
+ Link = NewLink;
+ }
+ }
+ Link = (PACKAGE_LINK *)Link->Link.pNext;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrSize8
+//
+// Description:
+// This function returns ASCII string size in bytes
+//
+// Input:
+// IN CHAR8 *String - Pointer to string
+//
+// Output:
+// UINT32 - Size of string in bytes including nul-terminator
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 StrSize8(CHAR8 *String)
+{
+ UINT32 Size = 1;
+ while(*String++)
+ Size++;
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrSize16
+//
+// Description:
+// This function returns UNICODE string size in bytes
+//
+// Input:
+// IN CHAR16 *String - Pointer to string
+//
+// Output:
+// UINT32 - Size of string in bytes including nul-terminator
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 StrSize16(CHAR16 *String)
+{
+ UINT32 Size = 2;
+ while(*String++)
+ Size += 2;
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCpy8
+//
+// Description:
+// This function copies one ASCII string into another
+//
+// Input:
+// IN CHAR8 *Dest - Pointer to destination string
+// IN CHAR8 *Src - Pointer to source string
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StrCpy8(CHAR8 *Dest, CHAR8 *Src)
+{
+ MemCpy(Dest, Src, StrSize8(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCpy16
+//
+// Description:
+// This function copies one UNICODE string into another
+//
+// Input:
+// IN CHAR16 *Dest - Pointer to destination string
+// IN CHAR16 *Src - Pointer to source string
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StrCpy16(CHAR16 *Dest, CHAR16 *Src)
+{
+ MemCpy(Dest, Src, StrSize16(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCmp8
+//
+// Description:
+// This function compares two ASCII strings
+//
+// Input:
+// IN CHAR8 *Dest - Pointer to destination string
+// IN CHAR8 *Src - Pointer to source string
+//
+// Output:
+// INTN - Zero if strings are equal, non-zero otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN StrCmp8(CHAR8 *Dest, CHAR8 *Src)
+{
+ return MemCmp(Dest, Src, StrSize8(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCmp16
+//
+// Description:
+// This function compares two UNICODE strings
+//
+// Input:
+// IN CHAR16 *Dest - Pointer to destination string
+// IN CHAR16 *Src - Pointer to source string
+//
+// Output:
+// INTN - Zero if strings are equal, non-zero otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN StrCmp16(CHAR16 *Dest, CHAR16 *Src)
+{
+ return MemCmp(Dest, Src, StrSize16(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAvailableFontId
+//
+// Description:
+// This function returns available font ID number
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+//
+// Output:
+// UINT16 - font ID number
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetAvailableFontId(
+ IN PACKAGE_LIST_RECORD *PackageList
+)
+{
+ UINT16 Id = 0;
+ STRING_FONT_LINK *Link = (STRING_FONT_LINK *)PackageList->StringFontList.pHead;
+ while(Link != NULL) {
+ Id = (Link->FontId > Id) ? Link->FontId : Id;
+ Link = (STRING_FONT_LINK *)Link->Link.pNext;
+ }
+ return Id + 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStringFontInfoByTemplate
+//
+// Description:
+// This function searches available fonts and returns font ID if match found
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+// IN EFI_FONT_INFO *Template - pointer to font description
+// OUT UINT16 *FontId - pointer where to return font ID
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindStringFontInfoByTemplate(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN EFI_FONT_INFO *Template,
+ OUT UINT16 *FontId
+)
+{
+ STRING_FONT_LINK *Link = (STRING_FONT_LINK *)PackageList->StringFontList.pHead;
+ EFI_FONT_INFO *Info;
+
+ while(Link != NULL) {
+ Info = (EFI_FONT_INFO *)(Link + 1);
+ if(!MemCmp(Info, Template, Link->FontInfoSize)) {
+ *FontId = Link->FontId;
+ return EFI_SUCCESS;
+ }
+ Link = (STRING_FONT_LINK *)Link->Link.pNext;
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStingFontInfoById
+//
+// Description:
+// This function searches available fonts and returns font description if match found
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+// IN UINT16 FontId - font ID to find
+// OUT EFI_FONT_INFO **Info - pointer where to store pointer to font description
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindStingFontInfoById(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ OUT EFI_FONT_INFO **Info
+)
+{
+ static CHAR16 DefaultFontName[] = L"System font";
+ STRING_FONT_LINK *Link = (STRING_FONT_LINK *)PackageList->StringFontList.pHead;
+ UINTN StrSize;
+ EFI_STATUS Status;
+
+ while(Link != NULL) {
+ if(Link->FontId == FontId) {
+ Status = pBS->AllocatePool(EfiBootServicesData, Link->FontInfoSize, Info);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ MemCpy(*Info, (VOID *)(Link + 1), Link->FontInfoSize);
+ return EFI_SUCCESS;
+ }
+ Link = (STRING_FONT_LINK *)Link->Link.pNext;
+ }
+//font not found, return default font
+ StrSize = Wcslen(DefaultFontName) * sizeof(CHAR16);
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_FONT_INFO) + StrSize, Info);
+ if(!EFI_ERROR(Status)) {
+ (*Info)->FontSize = EFI_GLYPH_HEIGHT;
+ (*Info)->FontStyle = EFI_HII_FONT_STYLE_NORMAL;
+ Wcscpy((*Info)->FontName, DefaultFontName);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringFont
+//
+// Description:
+// This function adds font to font database and assigns font ID if latter was
+// not supplied
+//
+// Input:
+// IN PACKAGE_LIST_RECORD *PackageList - pointer to package list were font belongs
+// IN UINT16 FontId - font ID
+// IN UINT16 FontSize - font size
+// IN EFI_HII_FONT_STYLE FontStyle - font style
+// IN CHAR16 *FontName - pointer to font name
+// OUT UINT16 *NewFontId OPTIONAL - pointer where to store assigned font ID
+//
+// Output:
+// EFI_SUCCESS - font found
+// EFI_NOT_FOUND - font not found
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddStringFont(
+ IN PACKAGE_LIST_RECORD *PackageList,
+ IN UINT16 FontId,
+ IN UINT16 FontSize,
+ IN EFI_HII_FONT_STYLE FontStyle,
+ IN CHAR16 *FontName,
+ OUT UINT16 *NewFontId OPTIONAL
+)
+{
+ UINT16 Fid;
+ UINT32 FontNameSize;
+ STRING_FONT_LINK *AddLink;
+ EFI_FONT_INFO *FontInfo;
+
+ Fid = (FontId == INVALID_FONT_ID) ? GetAvailableFontId(PackageList) : FontId;
+
+ FontNameSize = (UINT32)((Wcslen(FontName)) * sizeof(CHAR16)); //null-terminator already accounted for in EFI_FONT_INFO structure
+ AddLink = CreateNewLink((UINT32)(sizeof(STRING_FONT_LINK) + sizeof(EFI_FONT_INFO)) + FontNameSize);
+ if(AddLink == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ AddLink->FontId = Fid;
+ AddLink->FontInfoSize = (UINT32)sizeof(EFI_FONT_INFO) + FontNameSize;
+ FontInfo = (EFI_FONT_INFO *)(AddLink + 1);
+ FontInfo->FontSize = FontSize;
+ FontInfo->FontStyle = FontStyle;
+ Wcscpy(FontInfo->FontName, FontName);
+ DListAdd(&(PackageList->StringFontList), (DLINK *)AddLink);
+ if(NewFontId)
+ *NewFontId = Fid;
+ return EFI_SUCCESS;
+}
+
+#pragma warning (default : 4090)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_DXE/UefiHii/UefiHii.cif b/Core/CORE_DXE/UefiHii/UefiHii.cif
new file mode 100644
index 0000000..4e82128
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/UefiHii.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "UefiHii"
+ category = ModulePart
+ LocalRoot = "Core\CORE_DXE\UefiHii\"
+ RefName = "UefiHii"
+[files]
+"UefiHii.sdl"
+"HiiConfig.c"
+"HiiDatabase.c"
+"HiiFont.c"
+"HiiFontEx.c"
+"HiiPrivate.h"
+"HiiString.c"
+"Hii.chm"
+"UefiHiiUtils.c"
+"HiAccessConfig.c"
+"hii21ExportConfig.c"
+<endComponent>
diff --git a/Core/CORE_DXE/UefiHii/UefiHii.sdl b/Core/CORE_DXE/UefiHii/UefiHii.sdl
new file mode 100644
index 0000000..9bdae97
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/UefiHii.sdl
@@ -0,0 +1,15 @@
+TOKEN
+ Name = "UefiHii_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UefiHii support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "UefiHii_DIR"
+ Help = "Path to UefiHii Module in Project"
+End
+
diff --git a/Core/CORE_DXE/UefiHii/UefiHiiUtils.c b/Core/CORE_DXE/UefiHii/UefiHiiUtils.c
new file mode 100644
index 0000000..d58aed3
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/UefiHiiUtils.c
@@ -0,0 +1,750 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/UefiHiiUtils.c 16 5/22/12 4:38p Artems $
+//
+// $Revision: 16 $
+//
+// $Date: 5/22/12 4:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/UefiHiiUtils.c $
+//
+// 16 5/22/12 4:38p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] In certain cases system font is absent
+// [RootCause] When font FFS file is not found system doesn't publish
+// system font
+// [Solution] If font FFS file is not found, publish font supplied with
+// Core
+// [Files] UefiHiiUtils.c
+//
+// 15 4/30/12 3:52p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Modified GraphicsConsole driver to output whole string
+// instead of symbol-by-symbol output
+// [Files] Gc.c, AmiDxeLib.h, EfiLib.c, UefiHiiUtils.c
+//
+// 14 1/05/12 5:05p Artems
+// EIP 76735: Font FFS file is not loaded in framework mode, when in
+// nested FV
+//
+// 13 1/05/11 12:12p Artems
+// EIP 51298: BufferSize value gets corrupted after call to ConfigToBlock
+// function - fixed
+//
+// 12 10/07/10 12:18p Felixp
+// Minor bug fix in LoadSystemFont: don't call FreePool if font section
+// has not been read.
+//
+// 11 10/01/10 4:44p Artems
+// Added implementation of function SetBrowserData
+//
+// 10 3/22/10 3:25p Felixp
+// SetCallback bug fix (the bug introduced during previous check in).
+//
+// 9 3/12/10 2:21p Felixp
+// Enhencement: LoadResources is updated to properly publish the packages
+// when NumberOfCallbacks is zero.
+//
+// 7 2/23/10 10:30p Felixp
+// SetBrowserData function is added.
+//
+// 6 2/19/10 4:15p Felixp
+// GetString function is updated: if the string is not defined for the
+// PlatformLang , try with the default language.
+// If still no luck, try English.
+//
+// 5 2/12/10 5:47p Felixp
+// Bug fix in LoadResources and LoadString functions
+// (memory corruption in projects with more than one supported language).
+//
+// 4 11/25/09 11:27a Felixp
+// Action parameter of the Callback function is updated based on UEFI
+// errata
+//
+// 3 11/24/09 4:39p Felixp
+//
+// 2 11/24/09 11:27a Felixp
+// GetString udpated: if PlatformLang variable does not exist use default
+// language instead of English.
+//
+// 1 10/09/09 6:12p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: UefiHiiUtils.c
+//
+// Description: UEFI 2.1 HII Utilities Protocol Implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Protocol/HiiUtilities.h>
+#include <Protocol/HiiDatabase.h>
+#include <Protocol/HiiString.h>
+#include <Protocol/FormBrowser2.h>
+#include <Protocol/HiiConfigRouting.h>
+#include <Protocol/LoadedImage.h>
+#include <Protocol/DevicePath.h>
+#include "HiiPrivate.h"
+
+EFI_STATUS HiiAccessExtractConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Request,
+ OUT EFI_STRING *Progress,
+ OUT EFI_STRING *Results
+);
+EFI_STATUS HiiAccessRouteConfig(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN CONST EFI_STRING Configuration,
+ OUT EFI_STRING *Progress
+);
+EFI_STATUS HiiAccessFormCallback(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID QuestionId,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+);
+
+VOID StripValuePattern(
+ IN OUT EFI_STRING String,
+ IN UINTN Size
+);
+
+UINT32 StrSize16(
+ IN CHAR16 *String
+);
+
+static EFI_HII_DATABASE_PROTOCOL *HiiDatabase=NULL;
+static EFI_HII_STRING_PROTOCOL *HiiString=NULL;
+static EFI_FORM_BROWSER2_PROTOCOL *FormBrowser = NULL;
+static EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting = NULL;
+
+static EFI_GUID HiiResourcesFfsSectionGuid= HII_RESOURCES_FFS_SECTION_GUID;
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+static CHAR8 *PlatformLang = NULL;
+
+extern const char *DefaultLanguageCode;
+extern SIMPLE_FONT DefaultFont[];
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: SetCallback
+//
+// Description:
+// EFI_STATUS SetCallback(EFI_HII_IFR_PACK *pIfr,
+// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo,
+// CALLBACK_INFO **CallBackFound)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS SetCallback(
+ EFI_LOADED_IMAGE_PROTOCOL *Image,
+ EFI_IFR_FORM_SET *FormSet, UINTN NumberOfCallbacks,
+ CALLBACK_INFO *CallbackInfo, CALLBACK_INFO **CallBackFound,
+ EFI_HANDLE *CallbackHandle
+)
+{
+ UINTN i;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *pPath, *pPath2;
+ CALLBACK_INFO *CallbackInfoPtr;
+
+ static EFI_HII_CONFIG_ACCESS_PROTOCOL DefaultConfigAccess = {
+ HiiAccessExtractConfig, HiiAccessRouteConfig, HiiAccessFormCallback
+ };
+ static CALLBACK_INFO DefaultCallbackInfo = {
+ NULL,&DefaultConfigAccess, 0, 0, NULL
+ };
+ static VENDOR_DEVICE_PATH FormSetDevicePathNode = {
+ {
+ MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP,
+ sizeof(VENDOR_DEVICE_PATH)
+ },
+ {0}
+ };
+
+ for( i=0
+ ; i<NumberOfCallbacks
+ && ( CallbackInfo[i].pGuid == NULL
+ || guidcmp(&FormSet->Guid,CallbackInfo[i].pGuid) != 0
+ )
+ ; i++
+ );
+ if (i==NumberOfCallbacks){
+ CallbackInfoPtr = &DefaultCallbackInfo;
+ }else{
+ CallbackInfoPtr = &CallbackInfo[i];
+ if (CallbackInfoPtr->pFormCallback == NULL){
+ CallbackInfoPtr->pFormCallback = &DefaultConfigAccess;
+ }else{
+ if (CallbackInfoPtr->pFormCallback->ExtractConfig==NULL)
+ CallbackInfoPtr->pFormCallback->ExtractConfig =
+ HiiAccessExtractConfig;
+ if (CallbackInfoPtr->pFormCallback->RouteConfig==NULL)
+ CallbackInfoPtr->pFormCallback->RouteConfig =
+ HiiAccessRouteConfig;
+ if (CallbackInfoPtr->pFormCallback->Callback==NULL)
+ CallbackInfoPtr->pFormCallback->Callback =
+ HiiAccessFormCallback;
+ }
+ }
+ Status=pBS->HandleProtocol(Image->DeviceHandle, &guidDevicePath, &pPath);
+ if (EFI_ERROR(Status)) pPath=NULL;
+ pPath = DPAddNode(pPath, Image->FilePath);
+ FormSetDevicePathNode.Guid = FormSet->Guid;
+ pPath2 = DPAddNode(pPath, &FormSetDevicePathNode.Header);
+ pBS->FreePool(pPath);
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &guidDevicePath, pPath2,
+ &gEfiHiiConfigAccessProtocolGuid, CallbackInfoPtr->pFormCallback,
+ NULL
+ );
+ if (EFI_ERROR(Status)) return Status;
+ if (CallbackHandle) *CallbackHandle=Handle;
+ if (CallBackFound){
+ *CallBackFound= (CallbackInfoPtr == &DefaultCallbackInfo)
+ ? NULL
+ : CallbackInfoPtr;
+ }
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS PublishPackages(
+ IN VOID *PackagePointers, IN UINTN NumberOfPackages,
+ IN EFI_GUID *PackageGuid, IN EFI_HANDLE DriverHandle OPTIONAL,
+ OUT EFI_HII_HANDLE *HiiHandle
+){
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *PackageList;
+ UINTN i;
+ UINT32 PackageLength;
+ UINT8 *PackagePtr;
+ EFI_HII_PACKAGE_HEADER **Packages = PackagePointers;
+ if (NumberOfPackages==0) return EFI_SUCCESS;
+ if ( !HiiDatabase
+ && EFI_ERROR(Status=pBS->LocateProtocol(
+ &gEfiHiiDatabaseProtocolGuid, NULL, &HiiDatabase
+ ))
+ ) return Status;
+ //calculate the package list length
+ PackageLength = sizeof(EFI_HII_PACKAGE_LIST_HEADER)
+ + sizeof(EFI_HII_PACKAGE_HEADER); //package list terminator
+ for(i=0; i<NumberOfPackages; i++){
+ PackageLength += Packages[i]->Length;
+ }
+ PackageList = Malloc(PackageLength);
+ if(PackageList==NULL) return EFI_OUT_OF_RESOURCES;
+ PackageList->PackageListGuid = *PackageGuid;
+ PackageList->PackageLength = PackageLength;
+
+ PackagePtr = (UINT8*)(PackageList+1);
+ for( i=0; i<NumberOfPackages; i++){
+ pBS->CopyMem(PackagePtr, Packages[i], Packages[i]->Length);
+ PackagePtr += Packages[i]->Length;
+ }
+ ((EFI_HII_PACKAGE_HEADER *)PackagePtr)->Length = sizeof(EFI_HII_PACKAGE_HEADER);
+ ((EFI_HII_PACKAGE_HEADER *)PackagePtr)->Type = EFI_HII_PACKAGE_END;
+
+ Status = HiiDatabase->NewPackageList(
+ HiiDatabase, PackageList, DriverHandle, HiiHandle
+ );
+ pBS->FreePool(PackageList);
+ return Status;
+}
+
+UINT32 GetNumerOfResourcePackages(
+ HII_RESOURCE_SECTION_HEADER *pSection, UINTN SectionSize
+){
+ EFI_HII_PACKAGE_HEADER *PackagePtr;
+ UINT32 NumberOfPackages = 0;
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)(pSection+1);
+ while(PackagePtr < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length);
+ NumberOfPackages++;
+ }
+ return NumberOfPackages;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: LoadStrings
+//
+// Description:
+// EFI_STATUS LoadStrings(EFI_HANDLE ImageHandle,
+// EFI_HII_HANDLE *HiiHandle)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS LoadStrings(
+ EFI_HANDLE ImageHandle, EFI_HII_HANDLE *HiiHandle
+)
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ HII_RESOURCE_SECTION_HEADER *pSection;
+ UINTN SectionSize;
+ EFI_HII_PACKAGE_HEADER *pPack;
+ EFI_HII_PACKAGE_HEADER **StringPackagPtr;
+ UINTN NumberOfStringPackages;
+ if (EFI_ERROR(Status=pBS->HandleProtocol(
+ ImageHandle, &gEfiLoadedImageProtocolGuid, &Image
+ ))
+ ) return Status;
+#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1
+{
+#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_
+ UINT8 *pData;
+ pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize);
+ if (!pData) return EFI_NOT_FOUND;
+ pSection = Malloc(SectionSize);
+ pBS->CopyMem(pSection,pData,SectionSize);
+ Status = EFI_SUCCESS;
+}
+#else
+{
+ Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize);
+ if (EFI_ERROR(Status)) return Status;
+}
+#endif
+ //Calculate number of packages.
+ //Original value of pSection->NumberOfPackages treats string packages
+ //for multiple languages as a single package. We need the real number of packages.
+ pSection->NumberOfPackages = GetNumerOfResourcePackages(pSection,SectionSize);
+
+ pPack = (EFI_HII_PACKAGE_HEADER *)(pSection + 1);
+
+ StringPackagPtr = Malloc(pSection->NumberOfPackages*sizeof(EFI_HII_PACKAGE_HEADER*));
+ NumberOfStringPackages=0;
+ while(pPack < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){
+ if (pPack->Type != EFI_HII_PACKAGE_STRINGS){
+ Status=EFI_INVALID_PARAMETER;
+ break;
+ }
+ StringPackagPtr[NumberOfStringPackages++]=pPack;
+ pPack = (EFI_HII_PACKAGE_HEADER*)((UINT8*)pPack+pPack->Length);
+ }
+ Status = PublishPackages(
+ StringPackagPtr, NumberOfStringPackages,
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid,
+ NULL, HiiHandle
+ );
+ pBS->FreePool(StringPackagPtr);
+ pBS->FreePool(pSection);
+ return Status;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: LoadResources
+//
+// Description:
+// EFI_STATUS LoadResources(EFI_HANDLE ImageHandle,
+// UINTN NumberOfCallbacks, CALLBACK_INFO *CallbackInfo,
+// INIT_HII_PACK InitFunction)
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+static EFI_STATUS LoadResources(
+ EFI_HANDLE ImageHandle, UINTN NumberOfCallbacks,
+ CALLBACK_INFO *CallbackInfo, INIT_HII_PACK InitFunction
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+ HII_RESOURCE_SECTION_HEADER *pSection;
+ UINTN SectionSize;
+ CALLBACK_INFO *pCallBackFound;
+ if (EFI_ERROR(Status=pBS->HandleProtocol(ImageHandle, &gEfiLoadedImageProtocolGuid, &Image))) return Status;
+#if defined(EMBEDDED_RESOURCES) && EMBEDDED_RESOURCES==1
+{
+#define AMIRC_PESECTION_NAME 0x5f534552494d415f//_AMIRES_
+ UINT8 *pData;
+ pData = FindPeSection(Image->ImageBase, AMIRC_PESECTION_NAME, &SectionSize);
+ if (!pData) return EFI_NOT_FOUND;
+ pSection = Malloc(SectionSize);
+ pBS->CopyMem(pSection,pData,SectionSize);
+}
+#else
+{
+ Status=ReadImageResource(ImageHandle,&HiiResourcesFfsSectionGuid,&pSection,&SectionSize);
+ if (EFI_ERROR(Status)) return Status;
+}
+#endif
+{
+ EFI_HII_PACKAGE_HEADER **IfrPackagPtr, **GlobalPackagPtr, **SharedPackagPtr;
+ UINTN NumberOfIfrPackages, NumberOfGlobalPackages, NumberOfSharedPackages, i;
+ UINT8 *PackagePtrBuffer;
+ EFI_HII_PACKAGE_HEADER *PackagePtr;
+
+ //Calculate number of packages.
+ //Original value of pSection->NumberOfPackages treats string packages
+ //for multiple languages as a single package. We need the real number of packages.
+ pSection->NumberOfPackages = GetNumerOfResourcePackages(pSection,SectionSize);
+
+ PackagePtrBuffer = Malloc(3*pSection->NumberOfPackages*sizeof(EFI_HII_PACKAGE_HEADER*));
+ IfrPackagPtr = (EFI_HII_PACKAGE_HEADER**)PackagePtrBuffer;
+ GlobalPackagPtr = IfrPackagPtr+pSection->NumberOfPackages;
+ SharedPackagPtr = GlobalPackagPtr+pSection->NumberOfPackages;
+ NumberOfIfrPackages = 0;
+ NumberOfGlobalPackages = 0;
+ NumberOfSharedPackages = 0;
+
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)(pSection+1);
+ while(PackagePtr < (EFI_HII_PACKAGE_HEADER*)((UINT8*)pSection+SectionSize)){
+ switch(PackagePtr->Type){
+ case EFI_HII_PACKAGE_FORMS:
+ IfrPackagPtr[NumberOfIfrPackages++]=PackagePtr;
+ break;
+ case EFI_HII_PACKAGE_FONTS: case EFI_HII_PACKAGE_KEYBOARD_LAYOUT:
+ GlobalPackagPtr[NumberOfGlobalPackages++]=PackagePtr;
+ break;
+ default:
+ SharedPackagPtr[NumberOfSharedPackages++]=PackagePtr;
+ break;
+ }
+ PackagePtr = (EFI_HII_PACKAGE_HEADER*)((UINT8*)PackagePtr+PackagePtr->Length);
+ }
+ Status = PublishPackages(
+ GlobalPackagPtr, NumberOfGlobalPackages,
+ &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(Image->FilePath))->NameGuid,
+ NULL, &HiiHandle
+ );
+ for(i=0; i<NumberOfIfrPackages; i++){
+ EFI_HANDLE CallbackHandle;
+
+ SharedPackagPtr[NumberOfSharedPackages]=IfrPackagPtr[i];
+ SetCallback(
+ Image, (EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1),
+ NumberOfCallbacks,CallbackInfo,&pCallBackFound,&CallbackHandle
+ );
+ Status = PublishPackages(
+ SharedPackagPtr, NumberOfSharedPackages+1,
+ &((EFI_IFR_FORM_SET*)(IfrPackagPtr[i]+1))->Guid,
+ CallbackHandle, &HiiHandle
+ );
+ if (pCallBackFound) pCallBackFound->HiiHandle=HiiHandle;
+ if (InitFunction) InitFunction(HiiHandle,pCallBackFound);
+ pCallBackFound=NULL;
+ }
+ pBS->FreePool(PackagePtrBuffer);
+ pBS->FreePool(pSection);
+}
+ return EFI_SUCCESS;
+}
+
+//TODO: header
+static EFI_STATUS GetString(
+ IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId,
+ IN OUT UINTN *StringSize, OUT EFI_STRING String
+){
+ EFI_STATUS Status;
+
+ if ( !HiiString
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString))
+ ) return EFI_NOT_FOUND;
+ if (PlatformLang==NULL){
+ UINTN Size;
+ if (EFI_ERROR(GetEfiVariable(
+ L"PlatformLang", &EfiVariableGuid, NULL, &Size, &PlatformLang
+ ))) PlatformLang = (CHAR8*)DefaultLanguageCode;
+ }
+ Status = HiiString->GetString(
+ HiiString, PlatformLang, HiiHandle,StringId, String, StringSize, NULL
+ );
+ // If the string representation for the PlatformLang is not defined,
+ // try with the default language.
+ // If still no luck, try English
+ if (Status==EFI_INVALID_LANGUAGE){
+ Status = HiiString->GetString(
+ HiiString, (CHAR8*)DefaultLanguageCode, HiiHandle,
+ StringId, String, StringSize, NULL
+ );
+ if (Status==EFI_INVALID_LANGUAGE)
+ Status = HiiString->GetString(
+ HiiString, LANGUAGE_CODE_ENGLISH, HiiHandle,
+ StringId, String, StringSize, NULL
+ );
+ }
+ return Status;
+}
+
+//TODO header
+static EFI_STATUS SetString(
+ IN EFI_HII_HANDLE HiiHandle, IN STRING_REF StringId, IN EFI_STRING String
+){
+ CHAR8 *LanguageList = NULL;
+ UINTN Size = 0;
+ EFI_STATUS Status;
+
+ if ( !HiiString
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString))
+ ) return EFI_NOT_FOUND;
+
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, LanguageList, &Size);
+ if (Status!=EFI_BUFFER_TOO_SMALL) return Status;
+ LanguageList = Malloc(Size);
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, LanguageList, &Size);
+ if (!EFI_ERROR(Status)){
+ CHAR8 *CurrentLang, *EndOfCurrentLang;
+ EndOfCurrentLang = LanguageList;
+ while(EndOfCurrentLang < LanguageList+Size){
+ CHAR8 OriginalChar;
+ CurrentLang = EndOfCurrentLang;
+ while(*EndOfCurrentLang!=';'&&*EndOfCurrentLang!=0) EndOfCurrentLang++;
+ OriginalChar = *EndOfCurrentLang;
+ *EndOfCurrentLang = 0;
+ Status = HiiString->SetString(
+ HiiString, HiiHandle, StringId, CurrentLang, String, NULL
+ );
+ if (EFI_ERROR(Status)) break;
+ *EndOfCurrentLang = OriginalChar;
+ EndOfCurrentLang++;
+ }
+ }
+ pBS->FreePool(LanguageList);
+ return Status;
+}
+
+static EFI_STATUS GetBrowserData(
+ IN UINTN *BufferSize, OUT VOID *Buffer,
+ IN CONST EFI_GUID *VarStoreGuid, OPTIONAL
+ IN CONST CHAR16 *VarStoreName OPTIONAL
+){
+ UINTN StringDataSize = 0;
+ CHAR16 *StringData = NULL;
+ EFI_STATUS Status;
+ EFI_STRING Progress;
+
+ if ( !FormBrowser
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser))
+ ) return EFI_NOT_FOUND;
+ if ( !HiiConfigRouting
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting))
+ ) return EFI_NOT_FOUND;
+
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (Status!=EFI_BUFFER_TOO_SMALL) return Status;
+ StringData = Malloc(StringDataSize);
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (!EFI_ERROR(Status)){
+ StringDataSize = *BufferSize; //preserve passed buffer size value, as
+ //ConfigToBlock may change it as per UEFI 2.1 spec
+ //it will contain index of last updated byte
+ Status = HiiConfigRouting->ConfigToBlock(
+ HiiConfigRouting, StringData, Buffer, BufferSize, &Progress
+ );
+ *BufferSize = StringDataSize; //restore original value
+ }
+ pBS->FreePool(StringData);
+ return Status;
+}
+
+static EFI_STATUS SetBrowserData(
+ IN UINTN BufferSize, IN VOID *Buffer,
+ IN CONST EFI_GUID *VarStoreGuid, OPTIONAL //TODO: Can it be optional???
+ IN CONST CHAR16 *VarStoreName OPTIONAL
+)
+{
+ UINTN StringDataSize = 0;
+ CHAR16 *StringData = NULL;
+ EFI_STATUS Status;
+ EFI_STRING Config;
+ EFI_STRING Progress;
+
+ if ( !FormBrowser
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiFormBrowser2ProtocolGuid, NULL, &FormBrowser))
+ ) return EFI_NOT_FOUND;
+ if ( !HiiConfigRouting
+ && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiConfigRoutingProtocolGuid, NULL, &HiiConfigRouting))
+ ) return EFI_NOT_FOUND;
+
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (Status!=EFI_BUFFER_TOO_SMALL) return Status;
+ StringData = Malloc(StringDataSize);
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, StringData, TRUE,
+ VarStoreGuid, VarStoreName
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+//we have StringData in format &OFFSET=XXXX&WIDTH=XXXX&VALUE=XXXX&OFFSET=...
+//in order for function BlockToConfig to work we need to modify StringData as follows:
+//&OFFSET=XXXX&WIDTH=XXXX&OFFSET=... (i.e. remove all &VALUE=XXX patterns)
+
+ StripValuePattern(StringData, StringDataSize);
+
+ Status = HiiConfigRouting->BlockToConfig(
+ HiiConfigRouting, StringData, Buffer, BufferSize,
+ &Config, &Progress
+ );
+
+ if(!EFI_ERROR(Status)) {
+ StringDataSize = StrSize16(Config);
+ Status = FormBrowser->BrowserCallback(
+ FormBrowser, &StringDataSize, Config, FALSE,
+ VarStoreGuid, VarStoreName
+ );
+ pBS->FreePool(Config);
+ }
+
+ pBS->FreePool(StringData);
+ return Status;
+}
+
+EFI_STATUS LoadSystemFont(){
+///// Load Font Pack
+#define FONT_FFS_FILE_GUID { 0xdac2b117, 0xb5fb, 0x4964, { 0xa3, 0x12, 0xd, 0xcc, 0x77, 0x6, 0x1b, 0x9b } }
+static EFI_GUID FontFfsFileGuid = FONT_FFS_FILE_GUID;
+extern UINT8 UsStdNarrowGlyphData[];
+ EFI_FIRMWARE_VOLUME_PROTOCOL *pFV;
+ UINTN DataSize;
+ EFI_GUID *pSectionGuid = NULL;
+ UINT32 Authentication;
+ EFI_HANDLE *pHandle;
+ UINTN Number,i;
+ EFI_STATUS FontStatus;
+ EFI_HII_PACKAGE_HEADER *FontPackage;
+ EFI_HII_HANDLE HiiFontHandle;
+
+ FontPackage = (EFI_HII_PACKAGE_HEADER*)&UsStdNarrowGlyphData;
+ FontStatus = pBS->LocateHandleBuffer(ByProtocol,&guidFV, NULL, &Number, &pHandle);
+ for(i=0;i<Number; i++)
+ {
+ FontStatus=pBS->HandleProtocol(pHandle[i], &guidFV, &pFV);
+ if (EFI_ERROR(FontStatus)) continue;
+ pSectionGuid=NULL;
+ DataSize=0;
+ FontStatus=pFV->ReadSection (
+ pFV,&FontFfsFileGuid,
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,0, &pSectionGuid, &DataSize,
+ &Authentication
+ );
+ if (!EFI_ERROR(FontStatus))
+ {
+ FontPackage=(EFI_HII_PACKAGE_HEADER*)((UINT32*)(pSectionGuid+1)+1);
+ break;
+ }
+ }
+
+ if (FontPackage->Type!=EFI_HII_PACKAGE_SIMPLE_FONTS){
+ //The font package is in the Framework HII format
+ //Convert the header to the UEFI HII format
+ DataSize=FontPackage->Length;
+ FontPackage = (EFI_HII_PACKAGE_HEADER*)((UINT8*)FontPackage+2);
+ FontPackage->Type=EFI_HII_PACKAGE_SIMPLE_FONTS;
+ FontPackage->Length=(UINT32)DataSize;
+ }
+ FontStatus = PublishPackages(&FontPackage, 1, &FontFfsFileGuid, NULL, &HiiFontHandle);
+ if (pSectionGuid!=NULL) pBS->FreePool(pSectionGuid);
+ return FontStatus;
+}
+
+static EFI_STATUS UtilGetGlyphWidth(
+ IN CHAR16 Char,
+ OUT UINT16 *Width
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(DefaultFont[(UINTN)Char].NarrowGlyph != NULL) {
+ *Width = ((DefaultFont[(UINTN)Char].NarrowGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDTH;
+ } else if(DefaultFont[(UINTN)Char].WideGlyph != NULL) {
+ *Width = ((DefaultFont[(UINTN)Char].WideGlyph)->Attributes & EFI_GLYPH_NON_SPACING) ? 0 : EFI_GLYPH_WIDE_WIDTH;
+ } else if(DefaultFont[0xfffd].NarrowGlyph != NULL) {
+ *Width = EFI_GLYPH_WIDTH;
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ } else if(DefaultFont[0xfffd].WideGlyph != NULL) {
+ *Width = EFI_GLYPH_WIDE_WIDTH;
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ } else {
+ *Width = 0;
+ Status = EFI_WARN_UNKNOWN_GLYPH;
+ }
+ return Status;
+}
+
+HII_UTILITIES_PROTOCOL HiiUtilitiesProtocol = {
+ LoadResources, LoadStrings, PublishPackages,
+ GetBrowserData, SetBrowserData, GetString, SetString, UtilGetGlyphWidth
+};
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_DXE/UefiHii/hii21ExportConfig.c b/Core/CORE_DXE/UefiHii/hii21ExportConfig.c
new file mode 100644
index 0000000..91480c0
--- /dev/null
+++ b/Core/CORE_DXE/UefiHii/hii21ExportConfig.c
@@ -0,0 +1,1143 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/hii21ExportConfig.c $
+//
+// $Author: Artems $
+//
+// $Revision: 1 $
+//
+// $Date: 1/25/11 3:20p $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/UefiHii/hii21ExportConfig.c $
+//
+// 1 1/25/11 3:20p Artems
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: hii21ExportConfig.c
+//
+// Description: This file contains code to perform the ExportConfig Operation of Config
+// roughting protocol.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "token.h"
+#include "efi.h"
+//#include "devicepath.h"
+#include <AmiDxeLib.h>
+
+#ifndef EFI_PROTOCOL_DEFINITION
+#define TSE_STRINGIZE(a) #a
+#define EFI_PROTOCOL_DEFINITION(a) TSE_STRINGIZE(Protocol/a.h)
+#endif
+
+#include EFI_PROTOCOL_DEFINITION(HiiDatabase)
+#include EFI_PROTOCOL_DEFINITION(HiiConfigRouting)
+#include EFI_PROTOCOL_DEFINITION(devicepath)
+
+typedef struct _VARSTORE_INFO
+{
+ EFI_GUID VariableGuid; //Varies EFI_GUID for the NVRAM variable store for this data
+ VOID* VariableHandle; //Varies HII Handle to the formset that contains this VarStore
+ UINT16 VariableSize; //Varies The size of Buffer Varstore
+ struct _VARSTORE_INFO *Next;
+ char *VariableName; //Varies Variable store name
+}VARSTORE_INFO;
+
+
+// Helper Functions
+EFI_HII_DATABASE_PROTOCOL *gHiiDatabase;
+EFI_BOOT_SERVICES *gBS;
+EFI_HII_CONFIG_ROUTING_PROTOCOL * gHiiConfigRouting;
+
+VARSTORE_INFO *gVarInfoHead = NULL;
+VARSTORE_INFO *gpVarInfo;
+
+EFI_HII_HANDLE *HiiGetHandles(UINT16 *NumberOfHiiHandles);
+VOID * _HiiGetForm( EFI_HII_HANDLE Handle, UINTN *Length );
+VOID _HiiGetVariable(EFI_HII_HANDLE Handle, UINT8 * buff);
+EFI_STATUS GetVarStoreConfig(VARSTORE_INFO *VarInfo, EFI_STRING *result);
+EFI_STATUS GetConfigHeader(VARSTORE_INFO *VarInfo, EFI_STRING *Configuration, UINTN *Length);
+EFI_STATUS GetBlockName(EFI_STRING *Configuration, UINTN *Length, UINTN Size);
+EFI_STATUS _VerifyResponseString(EFI_STRING Configuration, BOOLEAN NameValue);
+EFI_STATUS _ConstructConfigHdr (
+ IN OUT CHAR16 *ConfigHdr,
+ IN OUT UINTN *StrBufferLen,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name, OPTIONAL
+ IN EFI_HANDLE *DriverHandle
+ );
+
+EFI_STATUS
+BufferToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ );
+EFI_STATUS
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ );
+VOID
+SwapBuffer (
+ IN OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ );
+EFI_STATUS
+BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ );
+CHAR16
+NibbleToHexChar (
+ IN UINT8 Nibble
+ );
+VOID
+ToLower (
+ IN OUT CHAR16 *Str
+ );
+VOID StrCpy8(CHAR8 *dest, CHAR8 *src);
+VOID
+EfiStrCpy (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ );
+
+VOID
+EfiStrCat (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ );
+
+
+//=== HELPER Functions ====================//
+VOID *
+EfiLibAllocatePool (
+ IN UINTN AllocationSize
+ )
+{
+ return Malloc(AllocationSize);
+}
+
+VOID *
+EfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ return MallocZ(AllocationSize);
+}
+
+UINTN
+EfiStrLen (
+ IN CHAR16 *String
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemFreePointer
+//
+// Description: function to free the pointers
+//
+// Input: VOID **ptr
+//
+// Output: void
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MemFreePointer( VOID **ptr )
+{
+ if ( ( ptr == NULL ) || ( *ptr == NULL ) )
+ return;
+
+ gBS->FreePool( *ptr );
+ *ptr = NULL;
+}
+
+UINTN StrLen8(CHAR8 *string)
+{
+ UINTN i=0;
+ while(string[i])
+ i++;
+
+ return i;
+}
+
+
+CHAR8 *StrDup8( CHAR8 *string )
+{
+ CHAR8 *text;
+
+ text = EfiLibAllocateZeroPool(1 + StrLen8( string ));
+ if ( text != NULL )
+ StrCpy8( text, string );
+
+ return text;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemCopy
+//
+// Description: function to copy a memory
+//
+// Input: VOID *dest, VOID *src, UINTN size
+//
+// Output: void
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MemCopy( VOID *dest, VOID *src, UINTN size )
+{
+ gBS->CopyMem( dest, src, size );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemReallocateZeroPool
+//
+// Description: function to reuse a allocated buffer
+//
+// Input: VOID *oldBuffer, UINTN oldSize, UINTN newSize
+//
+// Output: void
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *MemReallocateZeroPool( VOID *oldBuffer, UINTN oldSize, UINTN newSize )
+{
+ VOID *buffer;
+
+ buffer = EfiLibAllocateZeroPool( newSize );
+ if ( buffer == NULL )
+ return buffer;
+
+ if ( newSize < oldSize )
+ oldSize = newSize;
+
+ if ( oldBuffer != NULL )
+ MemCopy( buffer, oldBuffer, oldSize );
+
+ MemFreePointer( (VOID **)&oldBuffer );
+
+ return buffer;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+//
+// Name: StrDup8to16
+//
+// Description: Duplicates a String from CHAR8 to CHAR16
+//
+// Input: CHAR8* string
+//
+// Output: CHAR16 *
+//
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR16 *StrDup8to16( CHAR8 *string )
+{
+ CHAR16 *text;
+ UINTN i;
+
+ text = EfiLibAllocatePool( (1 + StrLen8( string )) * sizeof(CHAR16));
+ if ( text != NULL )
+ {
+ i=0;
+ while(text[i] = (CHAR16)string[i])
+ i++;
+ }
+
+ return text;
+}
+
+
+INTN
+EfiStrnCmp (
+ IN CHAR16 *String,
+ IN CHAR16 *String2,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+ This function compares the Unicode string String to the Unicode
+ string String2 for len characters. If the first len characters
+ of String is identical to the first len characters of String2,
+ then 0 is returned. If substring of String sorts lexicographically
+ after String2, the function returns a number greater than 0. If
+ substring of String sorts lexicographically before String2, the
+ function returns a number less than 0.
+
+Arguments:
+ String - Compare to String2
+ String2 - Compare to String
+ Length - Number of Unicode characters to compare
+
+Returns:
+ 0 - The substring of String and String2 is identical.
+ > 0 - The substring of String sorts lexicographically after String2
+ < 0 - The substring of String sorts lexicographically before String2
+
+--*/
+{
+ while (*String && Length != 0) {
+ if (*String != *String2) {
+ break;
+ }
+ String += 1;
+ String2 += 1;
+ Length -= 1;
+ }
+ return Length > 0 ? *String - *String2 : 0;
+}
+
+UINTN
+EfiDevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ return DPLength(DevicePath);
+}
+
+
+VOID InitGlobels(VOID)
+{
+ gBS=pBS;
+ gBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, &gHiiDatabase);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Hii21ExportConfigHelper
+//
+// Description: Helper function to perform ExportConfig Operation of Config
+// roughting protocol.
+//
+// Parameter: EFI_HII_CONFIG_ROUTING_PROTOCOL *This, IN EFI_HII_DATABASE_PROTOCOL *HiiDatabase,
+// OUT EFI_STRING *Results
+//
+// Return value: Status
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Hii21ExportConfigHelper (
+ IN CONST EFI_HII_CONFIG_ROUTING_PROTOCOL *This,
+ OUT EFI_STRING *Results
+)
+{
+ EFI_HII_HANDLE *HiiHandleList;
+ UINT16 NumberOfHiiHandles = 0;
+ UINTN i;
+ UINT8 *FormSet;
+ UINT8 *ifrData;
+ UINTN Length;
+ EFI_STRING result=NULL;
+ UINTN OldSize,NewSize;
+
+ if(Results == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *Results = NULL;
+ InitGlobels();
+ gHiiConfigRouting = (EFI_HII_CONFIG_ROUTING_PROTOCOL*)This;
+
+ // To get the All the Valid Hii Handles.
+ HiiHandleList = HiiGetHandles(&NumberOfHiiHandles);
+ gpVarInfo = gVarInfoHead = NULL;
+
+ for(i=0;i<NumberOfHiiHandles;i++)
+ {
+ Length = 0;
+ // To get the FormPackage
+ FormSet = _HiiGetForm( HiiHandleList[i], &Length);
+ // donot contain valid package.
+ if(FormSet == NULL)
+ continue;
+ ifrData = (UINT8*)(FormSet + sizeof(EFI_HII_PACKAGE_HEADER));
+ _HiiGetVariable(HiiHandleList[i], ifrData);
+
+ // Free the FormPackage
+ MemFreePointer(&FormSet);
+ }
+
+
+ gpVarInfo = gVarInfoHead;
+ OldSize = NewSize = 0;
+ while( gpVarInfo != NULL )
+ {
+ VARSTORE_INFO *tmpVarInfo;
+ EFI_STATUS Status;
+
+ Status = GetVarStoreConfig(gpVarInfo, &result);
+ if(!EFI_ERROR(Status))
+ {
+ NewSize = OldSize + (EfiStrLen(result)*2)+10;
+ *Results = MemReallocateZeroPool(*Results, OldSize, NewSize);
+ if(OldSize)
+ EfiStrCat(*Results,L"&");
+ EfiStrCat(*Results,result);
+ MemFreePointer(&result);
+ OldSize = NewSize;
+ }
+
+ MemFreePointer(&gpVarInfo->VariableName);
+ tmpVarInfo = gpVarInfo;
+ gpVarInfo = gpVarInfo->Next;
+ MemFreePointer(&tmpVarInfo);
+ }
+
+ // free the Hii Handles
+ MemFreePointer((VOID**)&HiiHandleList);
+ return EFI_SUCCESS;
+}
+
+
+BOOLEAN IsVarStoreFound(EFI_HII_HANDLE Handle, EFI_IFR_VARSTORE *varstore)
+{
+ VARSTORE_INFO * VarInfo;
+// EFI_GUID SetupGuid = SETUP_GUID;
+
+ VarInfo = gVarInfoHead;
+ while( VarInfo != NULL )
+ {
+ if( MemCmp( (UINT8*)&VarInfo->VariableGuid,(UINT8*) &(varstore->Guid) , sizeof(EFI_GUID)) == 0)
+ if(Strcmp(VarInfo->VariableName, (char*)varstore->Name) ==0)
+ {
+// In Aptio, There are many Variables used in multiple Vfr.
+
+/*
+// Setup Variable even if it differ handle the variable info is same.
+ if( (MemCmp( (UINT8*)&VarInfo->VariableGuid,(UINT8*) &SetupGuid , sizeof(EFI_GUID)) == 0) &&
+ (Strcmp(VarInfo->VariableName, "Setup") == 0) )
+ return TRUE;
+// For not SETUP_DATA if the Handle is different it can be different Variable
+ else if(VarInfo->VariableHandle == Handle)
+*/
+ return TRUE;
+
+ }
+ VarInfo = VarInfo->Next;
+ }
+ return FALSE;
+}
+
+VOID _HiiGetVariable(EFI_HII_HANDLE Handle, UINT8 * buff)
+{
+ EFI_IFR_OP_HEADER *Header;
+ UINTN ScopeCount = 0;
+ EFI_IFR_VARSTORE *varstore;
+
+ //go thru the forms get the variables.
+ do
+ {
+ Header = (EFI_IFR_OP_HEADER*)(buff);
+ switch(Header->OpCode )
+ {
+ case EFI_IFR_END_OP:
+ ScopeCount--;
+ break;
+
+ case EFI_IFR_VARSTORE_OP:
+ if(!IsVarStoreFound(Handle, (EFI_IFR_VARSTORE *)buff))
+ {
+ if( gVarInfoHead == NULL)
+ {
+ gVarInfoHead = EfiLibAllocateZeroPool(sizeof(VARSTORE_INFO));
+ gVarInfoHead->Next = NULL;
+ gpVarInfo = gVarInfoHead;
+ }
+ else
+ {
+ gpVarInfo->Next = EfiLibAllocateZeroPool(sizeof(VARSTORE_INFO));
+ gpVarInfo = gpVarInfo->Next;
+ gpVarInfo->Next = NULL;
+ }
+
+ varstore = (EFI_IFR_VARSTORE*)buff;
+
+ MemCopy(&gpVarInfo->VariableGuid, &(varstore->Guid), sizeof(EFI_GUID));
+ gpVarInfo->VariableHandle = (VOID*)Handle;
+ gpVarInfo->VariableSize = varstore->Size;
+ gpVarInfo->VariableName = StrDup8((char*)varstore->Name);
+ }
+ default:
+ if(Header->Scope)
+ {
+ ScopeCount++;
+ }
+ break;
+
+ }
+ buff += Header->Length;
+ }while(ScopeCount != 0);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: _HiiGetForm
+//
+// Description:
+//
+// Parameter:
+//
+// Return value:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *_HiiGetForm( EFI_HII_HANDLE Handle, UINTN *Length )
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_HII_PACKAGE_HEADER *pkgHdr;
+ EFI_IFR_OP_HEADER *opHeader = NULL;
+ VOID *hiiFormPackage=NULL;
+ UINT8 *formPkBuffer = NULL;
+ UINT8 *pkgOffset;
+ UINT8 end = 0;
+ UINT32 offset = 0;
+ UINTN len=10;
+ //SETUP_LINK DummySetupLink;
+
+ if(Length == NULL)
+ Length = &len;
+
+ hiiFormPackage = EfiLibAllocateZeroPool(*Length);
+
+ status = gHiiDatabase->ExportPackageLists(gHiiDatabase, Handle, Length, hiiFormPackage);
+ if(status == EFI_BUFFER_TOO_SMALL)
+ {
+ MemFreePointer(&hiiFormPackage);
+ //
+ // Allocate space for retrieval of IFR data
+ //
+ hiiFormPackage = EfiLibAllocateZeroPool(*Length);
+
+ if (hiiFormPackage == NULL)
+ {
+ hiiFormPackage = NULL;
+ goto DONE;
+ }
+ //
+ // Get all the packages associated with this HiiHandle
+ //
+ status = gHiiDatabase->ExportPackageLists (gHiiDatabase, Handle, Length, hiiFormPackage);
+ if(EFI_ERROR(status))
+ {
+ MemFreePointer(&hiiFormPackage);
+ hiiFormPackage = NULL;
+ goto DONE;
+ }
+ }else if(EFI_ERROR(status))
+ {
+ hiiFormPackage = NULL;
+ goto DONE;
+ }
+
+ offset = sizeof(EFI_HII_PACKAGE_LIST_HEADER);
+
+ while(offset < ((EFI_HII_PACKAGE_LIST_HEADER*)hiiFormPackage)->PackageLength)
+ {
+ pkgOffset = ((UINT8*)hiiFormPackage) + offset;
+ pkgHdr = (EFI_HII_PACKAGE_HEADER*)pkgOffset;
+ switch(pkgHdr->Type)
+ {
+ case EFI_HII_PACKAGE_FORMS:
+ formPkBuffer = (UINT8*)EfiLibAllocateZeroPool(pkgHdr->Length);
+ if(formPkBuffer == NULL)
+ {
+ goto DONE;
+ }
+
+ MemCopy(formPkBuffer, pkgHdr, pkgHdr->Length);
+
+ opHeader = (EFI_IFR_OP_HEADER*)((UINT8*)formPkBuffer + sizeof(EFI_HII_PACKAGE_HEADER));
+ if(opHeader->OpCode != EFI_IFR_FORM_SET_OP)
+ {
+ MemFreePointer(&formPkBuffer);
+ formPkBuffer = NULL;
+ *Length = 0;
+ goto DONE;
+ }
+
+ end = 1;
+ break;
+ case EFI_HII_PACKAGE_END:
+ end = 1;
+ break;
+ default:
+ break;
+ }
+ if(end)
+ {
+ break;
+ }
+ offset += pkgHdr->Length;
+ }
+
+ MemFreePointer(&hiiFormPackage);
+
+DONE:
+ return formPkBuffer;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: HiiGetHandles
+//
+// Description: gets all the HII handles
+//
+// Parameter: No of handles
+//
+// Return value: EFI_HII_HANDLE *
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_HII_HANDLE *HiiGetHandles(UINT16 *NumberOfHiiHandles)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_HII_HANDLE *hiiHandleBuffer = NULL;
+ UINTN handleBufferLength = sizeof(EFI_HII_HANDLE);
+
+ hiiHandleBuffer = EfiLibAllocatePool(handleBufferLength);
+
+ status = gHiiDatabase->ListPackageLists (gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL, NULL,
+ &handleBufferLength, hiiHandleBuffer);
+ if (status == EFI_BUFFER_TOO_SMALL)
+ {
+ //
+ // Free the old pool
+ //
+ MemFreePointer ((VOID**)&hiiHandleBuffer);
+ //
+ // Allocate new pool with correct value
+ //
+ hiiHandleBuffer = EfiLibAllocatePool(handleBufferLength);
+
+ //
+ // Get the Handles of the packages that were registered with Hii
+ //
+ gBS->SetMem(hiiHandleBuffer,handleBufferLength,0);
+ status = gHiiDatabase->ListPackageLists (gHiiDatabase, EFI_HII_PACKAGE_TYPE_ALL,
+ NULL, &handleBufferLength, hiiHandleBuffer);
+
+ if (EFI_ERROR (status))
+ {
+ MemFreePointer((VOID**)&hiiHandleBuffer);
+ hiiHandleBuffer = NULL;
+ goto DONE;
+ }
+ }else if(EFI_ERROR(status))
+ {
+ MemFreePointer((VOID**)&hiiHandleBuffer);
+ hiiHandleBuffer = NULL;
+ goto DONE;
+ }
+
+ *NumberOfHiiHandles = (UINT16)(handleBufferLength / sizeof(EFI_HII_HANDLE));
+
+DONE:
+ return hiiHandleBuffer;
+}
+
+
+
+
+EFI_STATUS GetVarStoreConfig(VARSTORE_INFO *VarInfo, EFI_STRING *result)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_STRING configuration = NULL;
+ EFI_STRING progress = NULL;
+ //EFI_STRING result = NULL;
+ //EFI_STRING stringPtr = NULL;
+ UINTN length = 1;
+ //UINT8 *buffer = NULL;
+
+ configuration = EfiLibAllocateZeroPool(length);
+ if(configuration == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ //
+ // Construct the Configuration Header String
+ //
+ status = GetConfigHeader(VarInfo, &configuration, &length);
+ if(EFI_ERROR(status))
+ {
+ //TSE_DEBUG ( (TSE_DBG_LEVEL, "\nGetConfigHeader FAIL\n" ));
+ goto DONE;
+ }
+
+/* if(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)
+ {
+ }else
+*/
+ {
+ status = GetBlockName(&configuration, &length, VarInfo->VariableSize);
+ if(EFI_ERROR(status))
+ {
+ //TSE_DEBUG ( (TSE_DBG_LEVEL, "\n GetBlockname FAIL\n" ));
+ goto DONE;
+ }
+ }
+
+ // Invoke Config Routing Route Config
+ status = gHiiConfigRouting->ExtractConfig(gHiiConfigRouting, configuration, &progress, result);
+
+ if(EFI_ERROR(status))
+ *result = NULL;
+
+ status = _VerifyResponseString(*result, /*(VariableInfo->ExtendedAttibutes & VARIABLE_ATTRIBUTE_NAMEVALUE)? TRUE :*/ FALSE);
+
+DONE:
+ if(configuration)
+ {
+ MemFreePointer(&configuration);
+ }
+
+ return status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: _VerifyResponseString
+//
+// Description: Verifies Correctness of Response String. This is to prevent
+// crashing if the result pointer is pointing to an invalid location.
+//
+// Parameter: EFI_STRING *Configuration
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS _VerifyResponseString(EFI_STRING Configuration, BOOLEAN NameValue)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_STRING config = Configuration;
+ CHAR16 *keyWord[] = {L"GUID=", L"&NAME=", L"&PATH=", L"&OFFSET=0&WIDTH=", L"&VALUE="};
+ UINT32 i = 0;
+ UINT32 count = NameValue? 3 : 5; // If Name Value Check only upto &Path else check until &Value.
+
+ if(EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0)
+ {
+ status = EFI_NOT_FOUND;
+ goto DONE;
+ }
+
+ for(i = 1; i < count; i++)
+ {
+ for(;EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0 && (config != (Configuration + EfiStrLen(Configuration))); config++)
+ ;
+ if(EfiStrnCmp(config, keyWord[i], EfiStrLen(keyWord[i])) != 0)
+ {
+ status = EFI_NOT_FOUND;
+ goto DONE;
+ }
+ }
+
+DONE:
+ return status;
+}
+
+
+
+EFI_STATUS GetConfigHeader(VARSTORE_INFO *VarInfo, EFI_STRING *Configuration, UINTN *Length)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ EFI_STRING configuration = NULL;
+ EFI_HANDLE driverHandle;
+ UINTN length = 0;
+ CHAR16 *VarName=NULL;
+
+ //
+ // Retrieve the Device Path from Handle
+ //
+ status = gHiiDatabase->GetPackageListHandle(gHiiDatabase, VarInfo->VariableHandle, &driverHandle);
+ if(EFI_ERROR(status))
+ {
+ goto DONE;
+ }
+
+ //
+ // Construct the Configuration Header String
+ //
+ VarName = StrDup8to16(VarInfo->VariableName);
+ status = _ConstructConfigHdr(configuration, &length, &VarInfo->VariableGuid, VarName, driverHandle);
+ if(EFI_ERROR(status))
+ {
+ if(status == EFI_BUFFER_TOO_SMALL)
+ {
+ MemFreePointer(&configuration);
+ configuration = (UINT16*)EfiLibAllocateZeroPool(length);
+ if(configuration == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ status = _ConstructConfigHdr(configuration, &length, &VarInfo->VariableGuid, VarName, driverHandle);
+ }
+ }
+
+ if(EFI_ERROR(status))
+ {
+ goto DONE;
+ }
+
+ if(*Configuration)
+ {
+ MemFreePointer(Configuration);
+ }
+ *Configuration = configuration;
+ *Length = length;
+
+DONE:
+ MemFreePointer(&VarName);
+ return status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: _ConstructConfigHdr
+//
+// Description: Construct <ConfigHdr> using routing information GUID/NAME/PATH.
+//
+// Parameter: IN OUT CHAR16 *ConfigHdr,
+// IN OUT UINTN *StrBufferLen,
+// IN EFI_GUID *Guid,
+// IN CHAR16 *Name, OPTIONAL
+// IN EFI_HANDLE *DriverHandle
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS _ConstructConfigHdr (
+ IN OUT CHAR16 *ConfigHdr,
+ IN OUT UINTN *StrBufferLen,
+ IN EFI_GUID *Guid,
+ IN CHAR16 *Name, OPTIONAL
+ IN EFI_HANDLE *DriverHandle
+ )
+{
+ EFI_STATUS Status;
+ UINTN NameStrLen;
+ UINTN DevicePathSize;
+ UINTN BufferSize;
+ CHAR16 *StrPtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (Name == NULL)
+ {
+ //
+ // There will be no "NAME" in <ConfigHdr> for Name/Value storage
+ //
+ NameStrLen = 0;
+ } else
+ {
+ //
+ // For buffer storage
+ //
+ NameStrLen = EfiStrLen (Name);
+ }
+
+ //
+ // Retrieve DevicePath Protocol associated with this HiiPackageList
+ //
+ Status = gBS->HandleProtocol (
+ DriverHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status))
+ {
+ return Status;
+ }
+
+ DevicePathSize = EfiDevicePathSize (DevicePath);
+
+ //
+ // GUID=<HexCh>32&NAME=<Char>NameStrLen&PATH=<HexChar>DevicePathStrLen <NULL>
+ // | 5 | 32 | 6 | NameStrLen*4 | 6 | DevicePathStrLen | 1 |
+ //
+ BufferSize = (5 + 32 + 6 + NameStrLen * 4 + 6 + DevicePathSize * 2 + 1) * sizeof (CHAR16);
+ if (*StrBufferLen < BufferSize)
+ {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+
+ StrPtr = ConfigHdr;
+
+ EfiStrCpy (StrPtr, L"GUID=");
+ StrPtr += 5;
+ BufferToHexString (StrPtr, (UINT8 *) Guid, sizeof (EFI_GUID));
+ StrPtr += 32;
+
+ //
+ // Convert name string, e.g. name "ABCD" => "&NAME=0041004200430044"
+ //
+ EfiStrCpy (StrPtr, L"&NAME=");
+ StrPtr += 6;
+ if (Name != NULL)
+ {
+ BufferSize = (NameStrLen * 4 + 1) * sizeof (CHAR16);
+ UnicodeToConfigString (StrPtr, &BufferSize, Name);
+ StrPtr += (NameStrLen * 4);
+ }
+
+ EfiStrCpy (StrPtr, L"&PATH=");
+ StrPtr += 6;
+ BufferToHexString (StrPtr, (UINT8 *) DevicePath, DevicePathSize);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBlockName
+//
+// Description:
+//
+// Parameter: EFI_STRING *Configuration, UINTN *Length, UINTN Size
+//
+// Return value: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetBlockName(EFI_STRING *Configuration, UINTN *Length, UINTN Size)
+{
+ EFI_STATUS status = EFI_SUCCESS;
+ UINTN length = 0;
+ UINTN finalLen = 0;
+ CHAR16 *tempBuffer = NULL;
+
+ length = (EfiStrLen(L"&OFFSET=0&WIDTH=") + sizeof(Size) + 1) * sizeof(CHAR16);
+ tempBuffer = (CHAR16*)EfiLibAllocateZeroPool(length);
+ if(tempBuffer == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ Swprintf_s(tempBuffer, length, L"&OFFSET=0&WIDTH=%x", Size);
+
+ length = EfiStrLen(*Configuration) * sizeof(CHAR16);
+ finalLen = (EfiStrLen(*Configuration) + EfiStrLen(tempBuffer) + 1) * sizeof(CHAR16);
+ *Configuration = MemReallocateZeroPool(*Configuration, length, finalLen);
+ if(*Configuration == NULL)
+ {
+ status = EFI_OUT_OF_RESOURCES;
+ goto DONE;
+ }
+
+ EfiStrCat(*Configuration, tempBuffer);
+
+ MemFreePointer(&tempBuffer);
+ *Length = finalLen;
+
+DONE:
+ return status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BufferToHexString
+//
+// Description: Converts binary buffer to Unicode string in reversed byte order from BufToHexString().
+//
+// Input: Str - String for output
+// Buffer - Binary buffer.
+// BufferSize - Size of the buffer in bytes.
+//
+// Output: EFI_SUCCESS - The function completed successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BufferToHexString (
+ IN OUT CHAR16 *Str,
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *NewBuffer;
+ UINTN StrBufferLen;
+
+ NewBuffer = EfiLibAllocatePool (BufferSize);
+ MemCopy(NewBuffer, Buffer, BufferSize);
+
+ SwapBuffer (NewBuffer, BufferSize);
+
+ StrBufferLen = BufferSize * 2 + 1;
+ Status = BufToHexString (Str, &StrBufferLen, NewBuffer, BufferSize);
+
+ gBS->FreePool (NewBuffer);
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (Str);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UnicodeToConfigString
+//
+// Description: Convert Unicode string to binary representation Config string, e.g.
+// "ABCD" => "0041004200430044". Config string appears in <ConfigHdr> (i.e.
+// "&NAME=<string>"), or Name/Value pair in <ConfigBody> (i.e. "label=<string>").
+//
+// Input: ConfigString - Binary representation of Unicode String, <string> := (<HexCh>4)+
+// StrBufferLen - On input: Length in bytes of buffer to hold the Unicode string.
+// Includes tailing '\0' character.
+// On output:
+// If return EFI_SUCCESS, containing length of Unicode string buffer.
+// If return EFI_BUFFER_TOO_SMALL, containg length of string buffer desired.
+// UnicodeString - Original Unicode string.
+//
+// Output: EFI_SUCCESS - Routine success.
+// EFI_BUFFER_TOO_SMALL - The string buffer is too small.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UnicodeToConfigString (
+ IN OUT CHAR16 *ConfigString,
+ IN OUT UINTN *StrBufferLen,
+ IN CHAR16 *UnicodeString
+ )
+{
+ UINTN Index;
+ UINTN Len;
+ UINTN BufferSize;
+ CHAR16 *String;
+
+ Len = EfiStrLen (UnicodeString);
+ BufferSize = (Len * 4 + 1) * sizeof (CHAR16);
+
+ if (*StrBufferLen < BufferSize) {
+ *StrBufferLen = BufferSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *StrBufferLen = BufferSize;
+ String = ConfigString;
+
+ for (Index = 0; Index < Len; Index++) {
+ BufToHexString (ConfigString, &BufferSize, (UINT8 *) UnicodeString, 2);
+
+ ConfigString += 4;
+ UnicodeString += 1;
+ }
+
+ //
+ // Add tailing '\0' character
+ //
+ *ConfigString = L'\0';
+
+ //
+ // Convert the uppercase to lowercase since <HexAf> is defined in lowercase format.
+ //
+ ToLower (String);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ToLower
+//
+// Description: Converts the unicode character of the string from uppercase to lowercase.
+//
+// Input: Str - String to be converted
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ToLower (
+ IN OUT CHAR16 *Str
+ )
+{
+ CHAR16 *Ptr;
+
+ for (Ptr = Str; *Ptr != L'\0'; Ptr++) {
+ if (*Ptr >= L'A' && *Ptr <= L'Z') {
+ *Ptr = (CHAR16) (*Ptr - L'A' + L'a');
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SwapBuffer
+//
+// Description: Swap bytes in the buffer.
+//
+// Input: Buffer - Binary buffer.
+// BufferSize - Size of the buffer in bytes.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SwapBuffer (
+ IN OUT UINT8 *Buffer,
+ IN UINTN BufferSize
+ )
+{
+ UINTN Index;
+ UINT8 Temp;
+ UINTN SwapCount;
+
+ SwapCount = BufferSize / 2;
+ for (Index = 0; Index < SwapCount; Index++) {
+ Temp = Buffer[Index];
+ Buffer[Index] = Buffer[BufferSize - 1 - Index];
+ Buffer[BufferSize - 1 - Index] = Temp;
+ }
+}
+
diff --git a/Core/CORE_DXE/UnicodeCollation.c b/Core/CORE_DXE/UnicodeCollation.c
new file mode 100644
index 0000000..d283af2
--- /dev/null
+++ b/Core/CORE_DXE/UnicodeCollation.c
@@ -0,0 +1,637 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/DxeMain/UnicodeCollation.c 14 8/28/09 1:21p Felixp $
+//
+// $Revision: 14 $
+//
+// $Date: 8/28/09 1:21p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/DxeMain/UnicodeCollation.c $
+//
+// 14 8/28/09 1:21p Felixp
+//
+// 13 8/28/09 12:26p Felixp
+// Support for both UnicodeCollation and UnicodeCollation2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 12 7/08/09 5:53p Vyacheslava
+// Updated according to the coding standards.
+//
+// 11 3/05/09 9:53a Felixp
+// Minor big fix: Invalid return type in the StriColl funcation
+// declaration.
+//
+// 10 12/16/08 1:36a Iminglin
+// The function value of Is_valid_char for compliance.
+//
+// 9 4/24/07 5:18p Robert
+// Updated headers for CHM compatibility and coding standard compliance
+//
+// 8 10/30/06 6:34p Felixp
+// Language list is extended to fix
+// FAT driver failure when non-European
+// language is selected as a primary language.
+//
+// 3 2/15/05 5:01p Felixp
+// SpecialChars moved here from protocol header
+//
+// 2 2/03/05 4:01p Felixp
+// small bug fix in StrToFat
+//
+// 1 1/28/05 12:45p Felixp
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 12/23/04 6:25p Felixp
+// bug fix in StrToFat
+//
+// 7 12/22/04 9:33a Radhikav
+// proper comments added
+//
+// 6 12/20/04 4:00p Radhikav
+// made changes to strtofat and metaimatch.
+//
+// 5 12/08/04 1:22p Radhikav
+// made some changes to StrtoFat function.
+//
+// 4 11/11/04 11:18a Felixp
+//
+// 3 10/18/04 1:30p Radhikav
+// modified metaimatch routine.
+//
+// 2 10/08/04 3:57p Radhikav
+// modified strlwr and strupper routines.
+//
+// 1 10/05/04 2:47p Radhikav
+// Initial check in.
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Unicode Collation.c
+//
+// Description: Provides Unicode String functions
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+#include <Protocol/UnicodeCollation.h>
+#include <AmiDxeLib.h>
+
+//----------------------------------------------------------------------
+// functions prototype
+
+INTN StriColl (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN CHAR16 *S1,
+ IN CHAR16 *S2
+
+);
+BOOLEAN MetaiMatch (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN CHAR16 *String,
+ IN CHAR16 *Patern
+
+);
+BOOLEAN StrToFat (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN CHAR16 *String,
+ IN UINTN FatSize,
+ OUT CHAR8 *Fat
+);
+VOID FatToStr (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN UINTN FatSize,
+ IN CHAR8 *Fat,
+ OUT CHAR16 *String
+);
+VOID StrLwr (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN OUT CHAR16 *String
+);
+VOID EFIAPI StrUpr (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN OUT CHAR16 *String
+);
+BOOLEAN is_valid_char(CHAR16 valid);
+CHAR16 toupper(CHAR16 Data);
+CHAR16 tolower(CHAR16 Value);
+
+//----------------------------------------------------------------------
+// Protocol Definitions
+EFI_UNICODE_COLLATION_PROTOCOL UnicodeCollationProtocol = {
+ StriColl,
+ MetaiMatch,
+ StrLwr,
+ StrUpr,
+ FatToStr,
+ StrToFat,
+ LANGUAGE_CODE_ENGLISH
+};
+
+CHAR8 SpecialChars[] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ '\\', '.', '_', '^', '$', '~', '!', '#', '%', '&',
+ '-', '{', '}', '(', ')', '@', '`', '\'', '\0'
+};
+
+//----------------------------------------------------------------------
+// Function Defintions
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: UnicodeCollationDriverEntryPoint
+//
+// Description: Initializes the Unicode Collation Driver
+//
+// Input:
+// ImageHandle - EFI Handle for the Unicode Collation Protocol
+// *SystemTable - Pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+// Referrals: InstallProtocolInterface
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+EFI_STATUS UnicodeCollationEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ Status = SystemTable->BootServices->InstallProtocolInterface(
+ &Handle,
+ &gEfiUnicodeCollation2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &UnicodeCollationProtocol
+ );
+ return Status;
+}
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: Stricoll
+//
+// Description: Performs a case-insensitive comparison of two
+// Null-terminated unicode strings.
+//
+// Input:
+// *This - pointer to the Unicode Collatioon Protocol
+// *s1 - string one
+// *s2 - string two
+//
+// Output: None
+//
+// Return:
+// 0 - if strings are equal
+// negative value - if s1 is less than s2
+// positive value - if s2 is less than s2
+//
+// Modified: None
+//
+// Referrals: tolower
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+INTN EFIAPI StriColl (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN CHAR16 *s1,
+ IN CHAR16 *s2
+)
+{
+ INTN result;
+
+ do {
+ result = tolower(*s1) - tolower(*s2);
+
+ if (result)
+ break;
+ } while ( (*s1++) && (*s2++) );
+
+ return result;
+}
+
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: StrLwr
+//
+// Description: Converts all the unicode charecters in a
+// Null-terminated string to lowercase unicode.
+//
+// Input:
+// *This - pointer to the UnicodeCollation Protocol
+// *String - String to convert to lower case
+//
+// Output: *String - String now in lower case
+//
+// Modified: *String
+//
+// Referrals: tolower
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+VOID EFIAPI StrLwr (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN OUT CHAR16 *String
+)
+{
+ CHAR16 *s = String;
+
+ while (*s != L'\0') {
+ *s = tolower(*s);
+ s++;
+ };
+
+}
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: StrUpr
+//
+// Description: Converts all the unicodecharecters in a Null terminated
+// unicode string to a uppercase unicode charecters.
+//
+// Input:
+// *This - pointer to the UnicodeCollation Protocol
+// *String - String to convert to upper case
+//
+// Output: *String - String now in lower case
+//
+// Modified: *String
+//
+// Referrals: toupper
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+VOID EFIAPI StrUpr (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN OUT CHAR16 *String
+)
+{
+ CHAR16 *s = String;
+
+ while (*s != L'\0') {
+ *s = toupper(*s);
+ s++ ;
+ };
+}
+
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: MetaiMatch
+//
+// Description: Performs a case insensitive comparision of a
+// Null-terminated unicode pattern string and a null terminated
+// unicode String Converts all the unicodecharecters in a Null terminated
+// unicode string.
+//
+// Input:
+// *This - pointer to the UnicodeCollation Protocol
+// *String - String to convert to upper case
+// *Pattern
+// Output:
+// TRUE - Pattern was found in String.
+// FALSE - Pattern was not found in String.
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+BOOLEAN EFIAPI MetaiMatch (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN CHAR16 *String,
+ IN CHAR16 *Pattern
+)
+{
+ CHAR16 ch1, ch, temp;
+ UINTN len1, len2;
+
+ for (; ;) {
+ len1 = Wcslen(String);
+ len2 = Wcslen(Pattern);
+
+ if (!len1) {
+ if (!len2)
+ return TRUE;
+ else
+ return FALSE;
+ }
+
+ ch1 = *Pattern;
+ Pattern ++;
+
+ switch (ch1) {
+
+ if (*String)
+ return FALSE;
+ else
+ return TRUE ;
+
+ case '*':
+ while (*String) {
+ if (MetaiMatch(This, String, Pattern))
+ return TRUE;
+
+ String ++;
+ }
+
+ return MetaiMatch(This, String, Pattern);
+
+ case '?':
+ if (!*String)
+ return FALSE;
+
+ String ++;
+ break;
+
+ case '[':
+ ch = *String;
+
+ if (!ch)
+ return FALSE;
+
+ temp = 0;
+ ch1 = *Pattern++;
+
+ while ( ch1 ) {
+ if (ch1 == ']')
+ return FALSE;
+
+ if (ch1 == '-') {
+ ch1 = *Pattern;
+
+ if ( ch1 == 0 || ch1 == ']' )
+ return FALSE;
+
+ if ( toupper(ch) >= toupper(temp) &&
+ toupper(ch) <= toupper(ch1) )
+ break;
+ }
+
+ temp = ch1;
+
+ if ( toupper(ch) == toupper(ch1) ) //any charecter
+ break;
+
+ ch1 = *Pattern++;
+ }
+
+ while (ch1 && ch1 != ']') {
+ ch1 = *Pattern;
+ Pattern ++;
+ }
+
+ String ++;
+ break;
+
+ default:
+ ch = *String;
+
+ if ( toupper(ch) != toupper(ch1) )
+ return FALSE;
+
+ String ++;
+ break;
+ }
+ }
+}
+
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: FatToString
+//
+// Description: Converts an 8.3 FAT file name in an OEM charecter set
+// to a Null-terminated Unicode string.
+//
+// Input:
+// *This - Pointer to the Unicode Collation Protocol
+// *FatSize - size of the FAT string
+// *Fat - 8.3 FAT ascii string
+// Output:
+// *String - Null terminated Unicode String
+//
+// Return: VOID
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+VOID EFIAPI FatToStr (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN UINTN FatSize,
+ IN CHAR8 *Fat,
+ OUT CHAR16 *String
+)
+{
+ for (; (*Fat && FatSize) != 0; String++, Fat++, FatSize --)
+ *String = *Fat;
+
+ *String = 0;
+}
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: StrtoFat
+//
+// Description: Converts a Null-terminated unicode string to legal
+// characters in a FAT file using an OEM charecter set. Converts all
+// the unicodecharecters in a Null terminated unicode string.
+//
+// Input:
+// *This - Pointer to the Unicode Collation Protocol
+// *FatSize - size of the FAT string
+// *String - Null terminated Unicode String
+// Output:
+// *Fat - 8.3 FAT ascii string
+//
+// Return:
+// TRUE - Pattern was found in String.
+// FALSE - Pattern was not found in String.
+//
+// Referrals: toupper
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+BOOLEAN StrToFat (
+ IN EFI_UNICODE_COLLATION_PROTOCOL *This,
+ IN CHAR16 *String,
+ IN UINTN FatSize,
+ OUT CHAR8 *Fat
+)
+{
+ BOOLEAN InvalidChar;
+ int i = 0, j = 0;
+
+ InvalidChar = FALSE;
+
+ while (String[i] && FatSize) {
+
+ if ( String[i] != 0x002E &&
+ String[i] != 0x0020 ) {
+
+ if ( is_valid_char(String[i]) == 1 ) {
+ Fat[j] = (CHAR8)toupper(String[i]);
+ j++;
+
+ } else {
+ Fat[j] = '_';
+ InvalidChar = TRUE;
+ j++;
+ }
+
+ FatSize --;
+ }
+
+ i++;
+ }
+
+ return(InvalidChar);
+}
+
+//----------------------------------------------------------------------
+//Local functions
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: is_valid_char
+//
+// Description: Checks to see if the character passed in is a valid.
+// ASCII Character
+//
+// Input: valid - character to check
+//
+// Return:
+// TRUE - Character is valid
+// FALSE - Character is invalid
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+BOOLEAN is_valid_char(CHAR16 valid)
+{
+ UINT16 i;
+ CHAR16 tempval;
+
+ if ( (valid >= 0x0061 && valid <= 0x007a) ||
+ (valid >= 0x00E0 && valid <= 0x00F6) ||
+ (valid >= 0x00F8 && valid <= 0x00Fe) )
+ return TRUE;
+
+ else if ( (valid >= 0x0041 && valid <= 0x005a) ||
+ (valid >= 0x00C0 && valid <= 0x00D6) ||
+ (valid >= 0x00D8 && valid <= 0x00DE) )
+ return TRUE;
+
+ else {
+ tempval = (CHAR16)valid;
+
+ for ( i=0; SpecialChars[i]; i++ ) {
+ if (tempval == SpecialChars[i])
+ return TRUE;
+ }
+ }
+
+ return (FALSE);
+}
+
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: tolower
+//
+// Description: Converts Unicode standard European characters to lower case
+//
+// Input: Data - character to convert
+//
+// Return: the Unicode character in lower case Unicode format
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+CHAR16 tolower( CHAR16 Data )
+{
+ if ( ('A' <= Data && Data <= 'Z') ||
+ (Data >= 0xC0 && Data <= 0xD6) ||
+ (Data >= 0xD8 && Data <= 0xDE) )
+ return (CHAR16)(Data + 0x20);
+ else
+ return Data;
+}
+
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Procedure: toupper
+//
+// Description: Converts Unicode standard Europeancharacters to upper case
+//
+// Input: Value - character to convert
+//
+// Return: the character in upper case Unicode format
+//
+//<AMI_PHDR_END>
+//----------------------------------------------------------------------
+
+CHAR16 toupper( CHAR16 Value )
+{
+ if ( ('a' <= Value && Value <= 'z') ||
+ (Value >= 0xE0 && Value <= 0xF6) ||
+ (Value >= 0xF8 && Value <= 0xFE) )
+ return (CHAR16)(Value - 0x20);
+ else
+ return Value;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CORE_DXE/dependency.c b/Core/CORE_DXE/dependency.c
new file mode 100644
index 0000000..b08c5bf
--- /dev/null
+++ b/Core/CORE_DXE/dependency.c
@@ -0,0 +1,451 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ dependency.c
+
+Abstract:
+
+ DXE Dispatcher Dependency Evaluator
+
+ This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine
+ if a driver can be scheduled for execution. The criteria for
+ schedulability is that the dependency expression is satisfied.
+
+--*/
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "EfiDependency.h"
+
+//
+// Global stack used to evaluate dependency expressions
+//
+BOOLEAN *mDepexEvaluationStack = NULL;
+BOOLEAN *mDepexEvaluationStackEnd = NULL;
+BOOLEAN *mDepexEvaluationStackPointer = NULL;
+
+//
+// Worker functions
+//
+
+STATIC
+EFI_STATUS
+GrowDepexStack (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Grow size of the Depex stack
+
+Arguments:
+
+ Stack - Old stack on the way in and new stack on the way out
+
+ StackSize - New size of the stack
+
+Returns:
+
+ EFI_SUCCESS - Stack successfully growed.
+
+ EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.
+
+
+
+--*/
+{
+ BOOLEAN *NewStack;
+ UINTN Size;
+
+ Size = DEPEX_STACK_SIZE_INCREMENT;
+ if (mDepexEvaluationStack != NULL) {
+ Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);
+ }
+
+ NewStack = CoreAllocateBootServicesPool (Size * sizeof (BOOLEAN));
+ if (NewStack == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (mDepexEvaluationStack != NULL) {
+ //
+ // Copy to Old Stack to the New Stack
+ //
+ EfiCommonLibCopyMem (
+ NewStack,
+ mDepexEvaluationStack,
+ (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN)
+ );
+
+ //
+ // Free The Old Stack
+ //
+ CoreFreePool (mDepexEvaluationStack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack);
+ mDepexEvaluationStack = NewStack;
+ mDepexEvaluationStackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS
+PushBool (
+ IN BOOLEAN Value
+ )
+/*++
+
+Routine Description:
+
+ Push an element onto the Boolean Stack
+
+Arguments:
+
+ Value - BOOLEAN to push.
+
+Returns:
+
+ EFI_SUCCESS - The value was pushed onto the stack.
+
+ EFI_OUT_OF_RESOURCES - There is not enough system memory to grow the stack.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowDepexStack ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ *mDepexEvaluationStackPointer = Value;
+ mDepexEvaluationStackPointer++;
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS
+PopBool (
+ OUT BOOLEAN *Value
+ )
+/*++
+
+Routine Description:
+
+ Pop an element from the Boolean stack.
+
+Arguments:
+
+ Value - BOOLEAN to pop.
+
+Returns:
+
+ EFI_SUCCESS - The value was popped onto the stack.
+
+ EFI_ACCESS_DENIED - The pop operation underflowed the stack
+
+--*/
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (mDepexEvaluationStackPointer == mDepexEvaluationStack) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ mDepexEvaluationStackPointer--;
+ *Value = *mDepexEvaluationStackPointer;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+CorePreProcessDepex (
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry
+ )
+/*++
+
+Routine Description:
+
+ Preprocess dependency expression and update DriverEntry to reflect the
+ state of Before, After, and SOR dependencies. If DriverEntry->Before
+ or DriverEntry->After is set it will never be cleared. If SOR is set
+ it will be cleared by CoreSchedule(), and then the driver can be
+ dispatched.
+
+Arguments:
+
+ DriverEntry - DriverEntry element to update
+
+Returns:
+
+ EFI_SUCCESS - It always works.
+
+--*/
+{
+ UINT8 *Iterator;
+
+ Iterator = DriverEntry->Depex;
+ if (*Iterator == EFI_DEP_SOR) {
+ DriverEntry->Unrequested = TRUE;
+ } else {
+ DriverEntry->Dependent = TRUE;
+ }
+
+ if (*Iterator == EFI_DEP_BEFORE) {
+ DriverEntry->Before = TRUE;
+ } else if (*Iterator == EFI_DEP_AFTER) {
+ DriverEntry->After = TRUE;
+ }
+
+ if (DriverEntry->Before || DriverEntry->After) {
+ EfiCommonLibCopyMem (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+BOOLEAN
+CoreIsSchedulable (
+ IN EFI_CORE_DRIVER_ENTRY *DriverEntry
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. This code does
+ not need to handle Before or After, as it is not valid to call this
+ routine in this case. The SOR is just ignored and is a nop in the grammer.
+
+ POSTFIX means all the math is done on top of the stack.
+
+Arguments:
+
+ DriverEntry - DriverEntry element to update
+
+Returns:
+
+ TRUE - If driver is ready to run.
+ FALSE - If driver is not ready to run or some fatal error was found.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT8 *Iterator;
+ BOOLEAN Operator;
+ BOOLEAN Operator2;
+ EFI_GUID DriverGuid;
+ VOID *Interface;
+
+ if (DriverEntry->After || DriverEntry->Before) {
+ //
+ // If Before or After Depex skip as CoreInsertOnScheduledQueueWhileProcessingBeforeAndAfter ()
+ // processes them.
+ //
+ return FALSE;
+ }
+
+ if (DriverEntry->Depex == NULL) {
+ //
+ // A NULL Depex means treat the driver like an EFI 1.0 thing.
+ //
+ Status = CoreAllEfiServicesAvailable ();
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+
+ //
+ // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by
+ // incorrectly formed DEPEX expressions
+ //
+ mDepexEvaluationStackPointer = mDepexEvaluationStack;
+
+
+ Iterator = DriverEntry->Depex;
+
+ while (TRUE) {
+ //
+ // Check to see if we are attempting to fetch dependency expression instructions
+ // past the end of the dependency expression.
+ //
+ if (((UINTN) Iterator - (UINTN) DriverEntry->Depex) >= DriverEntry->DepexSize) {
+ return FALSE;
+ }
+
+ //
+ // Look at the opcode of the dependency expression instruction.
+ //
+ switch (*Iterator) {
+ case EFI_DEP_BEFORE:
+ case EFI_DEP_AFTER:
+ //
+ // For a well-formed Dependency Expression, the code should never get here.
+ // The BEFORE and AFTER are processed prior to this routine's invocation.
+ // If the code flow arrives at this point, there was a BEFORE or AFTER
+ // that were not the first opcodes.
+ //
+ ASSERT (FALSE);
+ case EFI_DEP_SOR:
+ //
+ // These opcodes can only appear once as the first opcode. If it is found
+ // at any other location, then the dependency expression evaluates to FALSE
+ //
+ if (Iterator != DriverEntry->Depex) {
+ return FALSE;
+ }
+ //
+ // Otherwise, it is the first opcode and should be treated as a NOP.
+ //
+ break;
+
+ case EFI_DEP_PUSH:
+ //
+ // Push operator is followed by a GUID. Test to see if the GUID protocol
+ // is installed and push the boolean result on the stack.
+ //
+ EfiCommonLibCopyMem (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));
+
+ Status = CoreLocateProtocol (&DriverGuid, NULL, &Interface);
+
+ if (EFI_ERROR (Status)) {
+ Status = PushBool (FALSE);
+ } else {
+ *Iterator = EFI_DEP_REPLACE_TRUE;
+ Status = PushBool (TRUE);
+ }
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Iterator += sizeof (EFI_GUID);
+ break;
+
+ case EFI_DEP_AND:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PopBool (&Operator2);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PushBool ((BOOLEAN) (Operator && Operator2));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+
+ case EFI_DEP_OR:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PopBool (&Operator2);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PushBool ((BOOLEAN) (Operator || Operator2));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+
+ case EFI_DEP_NOT:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PushBool ((BOOLEAN) (!Operator));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+
+ case EFI_DEP_TRUE:
+ Status = PushBool (TRUE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+
+ case EFI_DEP_FALSE:
+ Status = PushBool (FALSE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+
+ case EFI_DEP_END:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return Operator;
+
+ case EFI_DEP_REPLACE_TRUE:
+ Status = PushBool (TRUE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Iterator += sizeof (EFI_GUID);
+ break;
+
+ default:
+ return FALSE;
+ }
+
+ //
+ // Skip over the Dependency Op Code we just processed in the switch.
+ // The math is done out of order, but it should not matter. That is
+ // we may add in the sizeof (EFI_GUID) before we account for the OP Code.
+ // This is not an issue, since we just need the correct end result. You
+ // need to be careful using Iterator in the loop as it's intermediate value
+ // may be strange.
+ //
+ Iterator++;
+ }
+ return FALSE;
+}
+
diff --git a/Core/CORE_DXE/event.c b/Core/CORE_DXE/event.c
new file mode 100644
index 0000000..1f61db3
--- /dev/null
+++ b/Core/CORE_DXE/event.c
@@ -0,0 +1,867 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ event.c
+
+Abstract:
+
+ EFI Event support.
+
+--*/
+
+#include "exec.h"
+#include "hand.h"
+
+//
+// Enumerate the valid types
+//
+UINT32 mEventTable[] = {
+ //
+ // 0x80000200 Timer event with a notification function that is
+ // queue when the event is signaled with SignalEvent()
+ //
+ EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ //
+ // 0x80000000 Timer event without a notification function. It can be
+ // signaled with SignalEvent() and checked with CheckEvent() or WaitForEvent().
+ //
+ EFI_EVENT_TIMER,
+ //
+ // 0x00000100 Generic event with a notification function that
+ // can be waited on with CheckEvent() or WaitForEvent()
+ //
+ EFI_EVENT_NOTIFY_WAIT,
+ //
+ // 0x00000200 Generic event with a notification function that
+ // is queue when the event is signaled with SignalEvent()
+ //
+ EFI_EVENT_NOTIFY_SIGNAL,
+ //
+ // 0x00000201 ExitBootServicesEvent.
+ //
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ //
+ // 0x60000202 SetVirtualAddressMapEvent.
+ //
+ EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+ //
+ // 0x00000203 ReadyToBootEvent.
+ //
+ EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ //
+ // 0x00000204 LegacyBootEvent.
+ //
+ EFI_EVENT_SIGNAL_LEGACY_BOOT,
+ //
+ // 0x00000603 Signal all ReadyToBootEvents.
+ //
+ EFI_EVENT_NOTIFY_SIGNAL_ALL | EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ //
+ // 0x00000604 Signal all LegacyBootEvents.
+ //
+ EFI_EVENT_NOTIFY_SIGNAL_ALL | EFI_EVENT_SIGNAL_LEGACY_BOOT,
+#endif
+ //
+ // 0x00000000 Generic event without a notification function.
+ // It can be signaled with SignalEvent() and checked with CheckEvent()
+ // or WaitForEvent().
+ //
+ 0x00000000,
+ //
+ // 0x80000100 Timer event with a notification function that can be
+ // waited on with CheckEvent() or WaitForEvent()
+ //
+ EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_WAIT,
+};
+
+
+VOID
+CoreAcquireEventLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Enter critical section by acquiring the lock on gEventQueueLock.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreAcquireLock (&gEventQueueLock);
+}
+
+
+VOID
+CoreReleaseEventLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Exit critical section by releasing the lock on gEventQueueLock.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreReleaseLock (&gEventQueueLock);
+}
+
+
+EFI_STATUS
+CoreInitializeEventServices (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initializes "event" support and populates parts of the System and Runtime Table.
+
+Arguments:
+
+ None
+
+Returns:
+
+ EFI_SUCCESS - Always return success
+
+--*/
+{
+ UINTN Index;
+
+ for (Index=0; Index <= EFI_TPL_HIGH_LEVEL; Index ++) {
+ InitializeListHead (&gEventQueue[Index]);
+ }
+
+ CoreInitializeTimer ();
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+CoreDispatchEventNotifies (
+ IN EFI_TPL Priority
+ )
+/*++
+
+Routine Description:
+
+ Dispatches all pending events.
+
+Arguments:
+
+ Priority - The task priority level of event notifications to dispatch
+
+Returns:
+
+ None
+
+--*/
+{
+ IEVENT *Event;
+ EFI_LIST_ENTRY *Head;
+
+ CoreAcquireEventLock ();
+ ASSERT (gEventQueueLock.OwnerTpl == Priority);
+ Head = &gEventQueue[Priority];
+
+ //
+ // Dispatch all the pending notifications
+ //
+ while (!IsListEmpty (Head)) {
+
+ Event = CR (Head->ForwardLink, IEVENT, NotifyLink, EVENT_SIGNATURE);
+ RemoveEntryList (&Event->NotifyLink);
+
+ Event->NotifyLink.ForwardLink = NULL;
+
+ //
+ // Only clear the SIGNAL status if it is a SIGNAL type event.
+ // WAIT type events are only cleared in CheckEvent()
+ //
+ if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
+ Event->SignalCount = 0;
+ }
+
+ CoreReleaseEventLock ();
+
+ //
+ // Notify this event
+ //
+ Event->NotifyFunction (Event, Event->NotifyContext);
+
+ //
+ // Check for next pending event
+ //
+ CoreAcquireEventLock ();
+ }
+
+ gEventPending &= ~(1 << Priority);
+ CoreReleaseEventLock ();
+}
+
+
+VOID
+STATIC
+CoreNotifyEvent (
+ IN IEVENT *Event
+ )
+/*++
+
+Routine Description:
+
+ Queues the event's notification function to fire
+
+Arguments:
+
+ Event - The Event to notify
+
+Returns:
+
+ None
+
+--*/
+{
+
+ //
+ // Event database must be locked
+ //
+ ASSERT_LOCKED (&gEventQueueLock);
+
+ //
+ // If the event is queued somewhere, remove it
+ //
+
+ if (Event->NotifyLink.ForwardLink != NULL) {
+ RemoveEntryList (&Event->NotifyLink);
+ Event->NotifyLink.ForwardLink = NULL;
+ }
+
+ //
+ // Queue the event to the pending notification list
+ //
+
+ InsertTailList (&gEventQueue[Event->NotifyTpl], &Event->NotifyLink);
+ gEventPending |= (UINTN)1 << Event->NotifyTpl;
+}
+
+
+
+VOID
+CoreNotifySignalList (
+ IN EFI_GUID *EventGroup
+ )
+/*++
+
+Routine Description:
+
+ Signals all events on the requested list
+
+Arguments:
+
+ SignalType - The list to signal
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_LIST_ENTRY *Head;
+ IEVENT *Event;
+
+ CoreAcquireEventLock ();
+
+ Head = &gEventSignalQueue;
+ for (Link = Head->ForwardLink; Link != Head; Link = Link->ForwardLink) {
+ Event = CR (Link, IEVENT, SignalLink, EVENT_SIGNATURE);
+ if ((Event->ExFlag) && EfiCompareGuid (&Event->EventGroup, EventGroup)) {
+ CoreNotifyEvent (Event);
+ }
+ }
+
+ CoreReleaseEventLock ();
+}
+
+//*** AMI PORTING BEGIN ***//
+// UEFI 2.0 handling of Ready to Boot and Legacy Boot events is not
+// backward compatible.
+// It can break customer's code
+// Let's make the Core backward compatible
+#if 1
+//#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+//*** AMI PORTING END *****//
+
+static
+VOID
+EFIAPI
+EventNotifySignalAllNullEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ //
+ // This null event is a size efficent way to enusre that
+ // EFI_EVENT_NOTIFY_SIGNAL_ALL is error checked correctly.
+ // EFI_EVENT_NOTIFY_SIGNAL_ALL is now mapped into
+ // CreateEventEx() and this function is used to make the
+ // old error checking in CreateEvent() for Tiano extensions
+ // function.
+ //
+ return;
+}
+
+#endif
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCreateEvent (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ OUT EFI_EVENT *Event
+ )
+/*++
+
+Routine Description:
+
+ Creates a general-purpose event structure
+
+Arguments:
+
+ Type - The type of event to create and its mode and attributes
+ NotifyTpl - The task priority level of event notifications
+ NotifyFunction - Pointer to the events notification function
+ NotifyContext - Pointer to the notification functions context; corresponds to
+ parameter "Context" in the notification function
+ Event - Pointer to the newly created event if the call succeeds; undefined otherwise
+
+Returns:
+
+ EFI_SUCCESS - The event structure was created
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value
+ EFI_OUT_OF_RESOURCES - The event could not be allocated
+
+--*/
+{
+ EFI_GUID *GuidPtr;
+ EFI_EVENT_NOTIFY Function;
+
+ GuidPtr = NULL;
+ Function = NotifyFunction;
+
+//*** AMI PORTING BEGIN ***//
+// To make even handling backward compatible.
+// See also comments above.
+#if 1
+//#if (EFI_SPECIFICATION_VERSION < 0x00020000)
+//*** AMI PORTING END *****//
+ //
+ // Clear EFI_EVENT_NOFITY_SIGNAL_ALL (Tiano extension) as all events in the
+ // EventGroup now have this property. So we need to filter it out.
+ //
+ if (Type & EFI_EVENT_NOTIFY_SIGNAL_ALL) {
+ Type &= ~EFI_EVENT_NOTIFY_SIGNAL_ALL;
+ Function = EventNotifySignalAllNullEvent;
+ }
+
+ //
+ // Map the Tiano extensions Events to CreateEventEx form
+ //
+ if (Type == EFI_EVENT_SIGNAL_READY_TO_BOOT) {
+ GuidPtr = &gEfiEventReadyToBootGuid;
+//*** AMI PORTING BEGIN ***//
+// To make even handling backward compatible.
+// See also comments above.
+ Type = EFI_EVENT_NOTIFY_SIGNAL;
+//*** AMI PORTING END *****//
+ } else if (Type == EFI_EVENT_SIGNAL_LEGACY_BOOT) {
+ GuidPtr = &gEfiEventLegacyBootGuid;
+//*** AMI PORTING BEGIN ***//
+// To make even handling backward compatible.
+// See also comments above.
+ Type = EFI_EVENT_NOTIFY_SIGNAL;
+//*** AMI PORTING END *****//
+ }
+#endif
+
+ //
+ // Convert EFI 1.10 Events to thier UEFI 2.0 CreateEventEx mapping
+ //
+ if (Type == EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES) {
+ Type = 0;
+ GuidPtr = &gEfiEventExitBootServicesGuid;
+ } else if (Type == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE) {
+ Type = 0;
+ GuidPtr = &gEfiEventVirtualAddressChangeGuid;
+ }
+
+ return CoreCreateEventEx (Type, NotifyTpl, Function, NotifyContext, GuidPtr, Event);
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCreateEventEx (
+ IN UINT32 Type,
+ IN EFI_TPL NotifyTpl,
+ IN EFI_EVENT_NOTIFY NotifyFunction,
+ IN VOID *NotifyContext,
+ IN CONST EFI_GUID *EventGroup, OPTIONAL
+ OUT EFI_EVENT *Event
+ )
+/*++
+
+Routine Description:
+ Creates a general-purpose event structure
+
+Arguments:
+ Type - The type of event to create and its mode and attributes
+ NotifyTpl - The task priority level of event notifications
+ NotifyFunction - Pointer to the events notification function
+ NotifyContext - Pointer to the notification functions context; corresponds to
+ parameter "Context" in the notification function
+ EventGroup - GUID for EventGroup if NULL act the same as gBS->CreateEvent().
+ Event - Pointer to the newly created event if the call succeeds; undefined otherwise
+
+Returns:
+ EFI_SUCCESS - The event structure was created
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value
+ EFI_OUT_OF_RESOURCES - The event could not be allocated
+
+--*/
+{
+ EFI_STATUS Status;
+ IEVENT *IEvent;
+ INTN Index;
+
+
+ if ((Event == NULL) || (NotifyTpl == EFI_TPL_APPLICATION)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // For event group, type EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES and EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE
+ // are not valid
+ //
+ if (EventGroup != NULL) {
+ if ((Type == EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES) || (Type == EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Check to make sure no reserved flags are set
+ //
+ Status = EFI_INVALID_PARAMETER;
+ for (Index = 0; Index < (sizeof (mEventTable) / sizeof (UINT32)); Index++) {
+ if (Type == mEventTable[Index]) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ if(EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Convert Event type for pre-defined Event groups
+ //
+ if (EventGroup != NULL) {
+ if (EfiCompareGuid ((VOID *) EventGroup, &gEfiEventExitBootServicesGuid)) {
+ Type = EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES;
+ } else if (EfiCompareGuid ((VOID *) EventGroup, &gEfiEventVirtualAddressChangeGuid)) {
+ Type = EFI_EVENT_SIGNAL_VIRTUAL_ADDRESS_CHANGE;
+ }
+ }
+
+ //
+ // If it's a notify type of event, check its parameters
+ //
+ if ((Type & (EFI_EVENT_NOTIFY_WAIT | EFI_EVENT_NOTIFY_SIGNAL))) {
+ //
+ // Check for an invalid NotifyFunction or NotifyTpl
+ //
+ if ((NotifyFunction == NULL) ||
+ (NotifyTpl < EFI_TPL_APPLICATION) ||
+ (NotifyTpl >= EFI_TPL_HIGH_LEVEL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ } else {
+ //
+ // No notification needed, zero ignored values
+ //
+ NotifyTpl = 0;
+ NotifyFunction = NULL;
+ NotifyContext = NULL;
+ }
+
+ //
+ // Allcoate and initialize a new event structure.
+ //
+ Status = CoreAllocatePool (
+ (Type & EFI_EVENT_RUNTIME) ? EfiRuntimeServicesData: EfiBootServicesData,
+ sizeof (IEVENT),
+ (VOID **)&IEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EfiCommonLibSetMem (IEvent, sizeof (IEVENT), 0);
+
+ IEvent->Signature = EVENT_SIGNATURE;
+ IEvent->Type = Type;
+ IEvent->NotifyTpl = NotifyTpl;
+ IEvent->NotifyFunction = NotifyFunction;
+ IEvent->NotifyContext = (VOID *)NotifyContext;
+ if (EventGroup != NULL) {
+ EfiCommonLibCopyMem (&IEvent->EventGroup, (VOID*)EventGroup, sizeof (EFI_GUID));
+ IEvent->ExFlag = TRUE;
+ }
+
+ *Event = IEvent;
+
+ if (Type & EFI_EVENT_RUNTIME) {
+ //
+ // Keep a list of all RT events so we can tell the RT AP.
+ //
+ IEvent->RuntimeData.Type = Type;
+ IEvent->RuntimeData.NotifyTpl = NotifyTpl;
+ IEvent->RuntimeData.NotifyFunction = NotifyFunction;
+ IEvent->RuntimeData.NotifyContext = NotifyContext;
+ IEvent->RuntimeData.Event = (EFI_EVENT *) IEvent;
+ InsertTailList (&gRuntime->EventHead, &IEvent->RuntimeData.Link);
+ }
+
+ CoreAcquireEventLock ();
+
+ if ((Type & EFI_EVENT_NOTIFY_SIGNAL) != 0x00000000) {
+ //
+ // The Event's NotifyFunction must be queued whenever the event is signaled
+ //
+ InsertHeadList (&gEventSignalQueue, &IEvent->SignalLink);
+ }
+
+ CoreReleaseEventLock ();
+
+ //
+ // Done
+ //
+ return EFI_SUCCESS;
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreSignalEvent (
+ IN EFI_EVENT UserEvent
+ )
+/*++
+
+Routine Description:
+
+ Signals the event. Queues the event to be notified if needed
+
+Arguments:
+
+ UserEvent - The event to signal
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Parameters are not valid.
+
+ EFI_SUCCESS - The event was signaled.
+
+--*/
+{
+ IEVENT *Event;
+
+ Event = UserEvent;
+
+ if (Event == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Event->Signature != EVENT_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireEventLock ();
+
+ //
+ // If the event is not already signalled, do so
+ //
+
+ if (Event->SignalCount == 0x00000000) {
+ Event->SignalCount ++;
+
+ //
+ // If signalling type is a notify function, queue it
+ //
+ if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
+ if (Event->ExFlag) {
+ //
+ // The CreateEventEx() style requires all members of the Event Group
+ // to be signaled.
+ //
+ CoreReleaseEventLock ();
+ CoreNotifySignalList (&Event->EventGroup);
+ CoreAcquireEventLock ();
+ } else {
+ CoreNotifyEvent (Event);
+ }
+ }
+ }
+
+ CoreReleaseEventLock ();
+ return EFI_SUCCESS;
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCheckEvent (
+ IN EFI_EVENT UserEvent
+ )
+/*++
+
+Routine Description:
+
+ Check the status of an event
+
+Arguments:
+
+ UserEvent - The event to check
+
+Returns:
+
+ EFI_SUCCESS - The event is in the signaled state
+ EFI_NOT_READY - The event is not in the signaled state
+ EFI_INVALID_PARAMETER - Event is of type EVT_NOTIFY_SIGNAL
+
+--*/
+
+{
+ IEVENT *Event;
+ EFI_STATUS Status;
+
+ Event = UserEvent;
+
+ if (Event == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Event->Signature != EVENT_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Event->Type & EFI_EVENT_NOTIFY_SIGNAL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = EFI_NOT_READY;
+
+ if (!Event->SignalCount && (Event->Type & EFI_EVENT_NOTIFY_WAIT)) {
+
+ //
+ // Queue the wait notify function
+ //
+
+ CoreAcquireEventLock ();
+ if (!Event->SignalCount) {
+ CoreNotifyEvent (Event);
+ }
+ CoreReleaseEventLock ();
+ }
+
+ //
+ // If the even looks signalled, get the lock and clear it
+ //
+
+ if (Event->SignalCount) {
+ CoreAcquireEventLock ();
+
+ if (Event->SignalCount) {
+ Event->SignalCount = 0;
+ Status = EFI_SUCCESS;
+ }
+
+ CoreReleaseEventLock ();
+ }
+
+ return Status;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreWaitForEvent (
+ IN UINTN NumberOfEvents,
+ IN EFI_EVENT *UserEvents,
+ OUT UINTN *UserIndex
+ )
+/*++
+
+Routine Description:
+
+ Stops execution until an event is signaled.
+
+Arguments:
+
+ NumberOfEvents - The number of events in the UserEvents array
+ UserEvents - An array of EFI_EVENT
+ UserIndex - Pointer to the index of the event which satisfied the wait condition
+
+Returns:
+
+ EFI_SUCCESS - The event indicated by Index was signaled.
+ EFI_INVALID_PARAMETER - The event indicated by Index has a notification function or
+ Event was not a valid type
+ EFI_UNSUPPORTED - The current TPL is not TPL_APPLICATION
+
+--*/
+
+{
+ EFI_STATUS Status;
+ UINTN Index;
+
+ //
+ // Can only WaitForEvent at TPL_APPLICATION
+ //
+ if (gEfiCurrentTpl != EFI_TPL_APPLICATION) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for(;;) {
+
+ for(Index = 0; Index < NumberOfEvents; Index++) {
+
+ Status = CoreCheckEvent (UserEvents[Index]);
+
+ //
+ // provide index of event that caused problem
+ //
+ if (Status != EFI_NOT_READY) {
+ *UserIndex = Index;
+ return Status;
+ }
+ }
+
+ //
+ // This was the location of the Idle loop callback in EFI 1.x reference
+ // code. We don't have that concept in this base at this point.
+ //
+ }
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreCloseEvent (
+ IN EFI_EVENT UserEvent
+ )
+/*++
+
+Routine Description:
+
+ Closes an event and frees the event structure.
+
+Arguments:
+
+ UserEvent - Event to close
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Parameters are not valid.
+
+ EFI_SUCCESS - The event has been closed
+
+--*/
+
+{
+ EFI_STATUS Status;
+ IEVENT *Event;
+
+ Event = UserEvent;
+
+ if (Event == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Event->Signature != EVENT_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If it's a timer event, make sure it's not pending
+ //
+ if (Event->Type & EFI_EVENT_TIMER) {
+ CoreSetTimer (Event, TimerCancel, 0);
+ }
+
+ CoreAcquireEventLock ();
+
+ //
+ // If the event is queued somewhere, remove it
+ //
+
+ if (Event->RuntimeData.Link.ForwardLink != NULL) {
+ RemoveEntryList (&Event->RuntimeData.Link);
+ }
+
+ if (Event->NotifyLink.ForwardLink != NULL) {
+ RemoveEntryList (&Event->NotifyLink);
+ }
+
+ if (Event->SignalLink.ForwardLink != NULL) {
+ RemoveEntryList (&Event->SignalLink);
+ }
+
+ CoreReleaseEventLock ();
+
+ //
+ // If the event is registered on a protocol notify,
+ // then remove it from the protocol database
+ //
+ CoreUnregisterProtocolNotify (Event);
+
+ Status = CoreFreePool (Event);
+ ASSERT_EFI_ERROR (Status);
+
+ return Status;
+}
diff --git a/Core/CORE_DXE/exec.h b/Core/CORE_DXE/exec.h
new file mode 100644
index 0000000..2abdc90
--- /dev/null
+++ b/Core/CORE_DXE/exec.h
@@ -0,0 +1,209 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ exec.h
+
+Abstract:
+
+ EFI Event support
+
+--*/
+
+#ifndef _EXEC_H_
+#define _EXEC_H_
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+#define VALID_TPL(a) ((a) <= EFI_TPL_HIGH_LEVEL)
+
+//
+// EFI_EVENT
+//
+
+#define EVENT_SIGNATURE EFI_SIGNATURE_32('e','v','n','t')
+typedef struct {
+ UINTN Signature;
+ UINT32 Type;
+ UINT32 SignalCount;
+
+ //
+ // Entry if the event is registered to be signalled
+ //
+
+ EFI_LIST_ENTRY SignalLink;
+
+ //
+ // Notification information for this event
+ //
+
+ EFI_TPL NotifyTpl;
+ EFI_EVENT_NOTIFY NotifyFunction;
+ VOID *NotifyContext;
+ EFI_GUID EventGroup;
+ EFI_LIST_ENTRY NotifyLink;
+ BOOLEAN ExFlag;
+
+ //
+ // A list of all runtime events
+ //
+ EFI_RUNTIME_EVENT_ENTRY RuntimeData;
+
+ //
+ // Information by event type
+ //
+
+ union {
+ //
+ // For timer events
+ //
+ struct {
+ EFI_LIST_ENTRY Link;
+ UINT64 TriggerTime;
+ UINT64 Period;
+ } Timer;
+ } u;
+
+} IEVENT;
+
+//
+// Internal prototypes
+//
+
+VOID
+CoreDispatchEventNotifies (
+ IN EFI_TPL Priority
+ )
+/*++
+
+Routine Description:
+
+ Dispatches all pending events.
+
+Arguments:
+
+ Priority - The task priority level of event notifications to dispatch
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+UINTN
+CoreHighestSetBit (
+ IN UINTN Number
+ )
+/*++
+
+Routine Description:
+
+ Return the highest set bit
+
+Arguments:
+
+ Number - The value to check
+
+Returns:
+
+ Bit position of the highest set bit
+
+--*/
+;
+
+
+BOOLEAN
+GetInterruptState (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Disables CPU interrupts.
+
+Arguments:
+
+ This - Protocol instance structure
+
+ State - Pointer to the CPU's current interrupt state
+
+Returns:
+
+ EFI_SUCCESS - If interrupts were disabled in the CPU.
+
+ EFI_INVALID_PARAMETER - State is NULL.
+
+--*/
+;
+
+//
+// Exported functions
+//
+
+VOID
+CoreEventVirtualAddressFixup (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ A function out of date, should be removed.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+VOID
+CoreInitializeTimer (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initializes timer support
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+//
+// extern data declarations
+//
+
+extern EFI_LOCK gEventQueueLock;
+extern UINTN gEventPending;
+extern EFI_LIST_ENTRY gEventQueue[];
+extern EFI_LIST_ENTRY gEventSignalQueue;
+extern UINT8 gHSB[];
+
+#endif
diff --git a/Core/CORE_DXE/execdata.c b/Core/CORE_DXE/execdata.c
new file mode 100644
index 0000000..284b89b
--- /dev/null
+++ b/Core/CORE_DXE/execdata.c
@@ -0,0 +1,50 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ execdata.c
+
+Abstract:
+
+
+
+
+Revision History
+
+--*/
+
+#include "exec.h"
+
+
+//
+// gTpl - Task priority level
+//
+EFI_TPL gEfiCurrentTpl = EFI_TPL_DRIVER;
+
+
+//
+// gEventQueueLock - Protects the event queus
+//
+EFI_LOCK gEventQueueLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);
+
+//
+// gEventQueue - A list of event's to notify for each priority level
+// gEventPending - A bitmask of the EventQueues that are pending
+//
+EFI_LIST_ENTRY gEventQueue[EFI_TPL_HIGH_LEVEL + 1];
+UINTN gEventPending = 0;
+
+//
+// gEventSignalQueue - A list of events to signal when the EFI operation occurs
+//
+EFI_LIST_ENTRY gEventSignalQueue = INITIALIZE_LIST_HEAD_VARIABLE (gEventSignalQueue);
+
diff --git a/Core/CORE_DXE/gcd.c b/Core/CORE_DXE/gcd.c
new file mode 100644
index 0000000..4080672
--- /dev/null
+++ b/Core/CORE_DXE/gcd.c
@@ -0,0 +1,2472 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ gcd.c
+
+Abstract:
+
+ The file contains the GCD related services in the EFI Boot Services Table.
+ The GCD services are used to manage the memory and I/O regions that
+ are accessible to the CPU that is executing the DXE core.
+
+--*/
+
+#include "gcd.h"
+
+#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000
+
+#define MEMORY_ATTRIBUTE_MASK (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+ EFI_RESOURCE_ATTRIBUTE_TESTED | \
+ EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED | \
+ EFI_RESOURCE_ATTRIBUTE_16_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_32_BIT_IO | \
+ EFI_RESOURCE_ATTRIBUTE_64_BIT_IO )
+
+#define TESTED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED | \
+ EFI_RESOURCE_ATTRIBUTE_TESTED )
+
+#define INITIALIZED_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT | \
+ EFI_RESOURCE_ATTRIBUTE_INITIALIZED )
+
+#define PRESENT_MEMORY_ATTRIBUTES (EFI_RESOURCE_ATTRIBUTE_PRESENT)
+
+#define INVALID_CPU_ARCH_ATTRIBUTES 0xffffffff
+
+//
+// Module Variables
+//
+EFI_LOCK mGcdMemorySpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);
+EFI_LOCK mGcdIoSpaceLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);
+EFI_LIST_ENTRY mGcdMemorySpaceMap = INITIALIZE_LIST_HEAD_VARIABLE (mGcdMemorySpaceMap);
+EFI_LIST_ENTRY mGcdIoSpaceMap = INITIALIZE_LIST_HEAD_VARIABLE (mGcdIoSpaceMap);
+
+EFI_GCD_MAP_ENTRY mGcdMemorySpaceMapEntryTemplate = {
+ EFI_GCD_MAP_SIGNATURE,
+ { NULL, NULL },
+ 0,
+ 0,
+ 0,
+ 0,
+ EfiGcdMemoryTypeNonExistent,
+ 0,
+ NULL,
+ NULL
+};
+
+EFI_GCD_MAP_ENTRY mGcdIoSpaceMapEntryTemplate = {
+ EFI_GCD_MAP_SIGNATURE,
+ { NULL, NULL },
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ EfiGcdIoTypeNonExistent,
+ NULL,
+ NULL
+};
+
+GCD_ATTRIBUTE_CONVERSION_ENTRY mAttributeConversionTable[] = {
+ { EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE, EFI_MEMORY_UC, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_UNCACHED_EXPORTED, EFI_MEMORY_UCE, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE, EFI_MEMORY_WC, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE, EFI_MEMORY_WT, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE, EFI_MEMORY_WB, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_READ_PROTECTED, EFI_MEMORY_RP, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_WRITE_PROTECTED, EFI_MEMORY_WP, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_EXECUTION_PROTECTED, EFI_MEMORY_XP, TRUE },
+ { EFI_RESOURCE_ATTRIBUTE_PRESENT, EFI_MEMORY_PRESENT, FALSE },
+ { EFI_RESOURCE_ATTRIBUTE_INITIALIZED, EFI_MEMORY_INITIALIZED, FALSE },
+ { EFI_RESOURCE_ATTRIBUTE_TESTED, EFI_MEMORY_TESTED, FALSE },
+ { 0, 0, FALSE }
+};
+
+VOID
+CoreAcquireGcdMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Acquire memory lock on mGcdMemorySpaceLock
+
+Arguments:
+ None
+
+Returns:
+ None
+
+--*/
+{
+ CoreAcquireLock (&mGcdMemorySpaceLock);
+}
+
+
+VOID
+CoreReleaseGcdMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Release memory lock on mGcdMemorySpaceLock
+
+Arguments:
+ None
+
+Returns:
+ None
+
+--*/
+{
+ CoreReleaseLock (&mGcdMemorySpaceLock);
+}
+
+
+
+VOID
+CoreAcquireGcdIoLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Acquire memory lock on mGcdIoSpaceLock
+
+Arguments:
+ None
+
+Returns:
+ None
+
+--*/
+{
+ CoreAcquireLock (&mGcdIoSpaceLock);
+}
+
+
+VOID
+CoreReleaseGcdIoLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+ Release memory lock on mGcdIoSpaceLock
+
+Arguments:
+ None
+
+Returns:
+ None
+
+--*/
+{
+ CoreReleaseLock (&mGcdIoSpaceLock);
+}
+
+
+
+//
+// GCD Initialization Worker Functions
+//
+UINT64
+AlignValue (
+ IN UINT64 Value,
+ IN UINTN Alignment,
+ IN BOOLEAN RoundUp
+ )
+/*++
+
+Routine Description:
+
+ Aligns a value to the specified boundary.
+
+Arguments:
+
+ Value - 64 bit value to align
+ Alignment - Log base 2 of the boundary to align Value to
+ RoundUp - TRUE if Value is to be rounded up to the nearest aligned boundary.
+ FALSE is Value is to be rounded down to the nearest aligned boundary.
+
+Returns:
+
+ A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.
+
+--*/
+{
+ UINT64 AlignmentMask;
+
+ AlignmentMask = LShiftU64 (1, Alignment) - 1;
+ if (RoundUp) {
+ Value += AlignmentMask;
+ }
+ return Value & (~AlignmentMask);
+}
+
+UINT64
+PageAlignAddress (
+ IN UINT64 Value
+ )
+/*++
+
+Routine Description:
+
+ Aligns address to the page boundary.
+
+Arguments:
+
+ Value - 64 bit address to align
+
+Returns:
+
+ A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.
+
+--*/
+{
+ return AlignValue (Value, EFI_PAGE_SHIFT, TRUE);
+}
+
+UINT64
+PageAlignLength (
+ IN UINT64 Value
+ )
+/*++
+
+Routine Description:
+
+ Aligns length to the page boundary.
+
+Arguments:
+
+ Value - 64 bit length to align
+
+Returns:
+
+ A 64 bit value is the aligned to the value nearest Value with an alignment by Alignment.
+
+--*/
+{
+ return AlignValue (Value, EFI_PAGE_SHIFT, FALSE);
+}
+
+//
+// GCD Memory Space Worker Functions
+//
+EFI_STATUS
+CoreAllocateGcdMapEntry (
+ IN OUT EFI_GCD_MAP_ENTRY **TopEntry,
+ IN OUT EFI_GCD_MAP_ENTRY **BottomEntry
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool for two entries.
+
+Arguments:
+
+ TopEntry - An entry of GCD map
+ BottomEntry - An entry of GCD map
+
+Returns:
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to be allocated.
+ EFI_SUCCESS - Both entries successfully allocated.
+
+--*/
+{
+ *TopEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_GCD_MAP_ENTRY));
+ if (*TopEntry == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *BottomEntry = CoreAllocateZeroBootServicesPool (sizeof (EFI_GCD_MAP_ENTRY));
+ if (*BottomEntry == NULL) {
+ CoreFreePool (*TopEntry);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreInsertGcdMapEntry (
+ IN EFI_LIST_ENTRY *Link,
+ IN EFI_GCD_MAP_ENTRY *Entry,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_GCD_MAP_ENTRY *TopEntry,
+ IN EFI_GCD_MAP_ENTRY *BottomEntry
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Inserts a new descriptor into a sorted list
+
+Arguments:
+
+ Link - The linked list to insert the range BaseAddress and Length into
+
+ Entry - A pointer to the entry that is inserted
+
+ BaseAddress - The base address of the new range
+
+ Length - The length of the new range in bytes
+
+ TopEntry - Top pad entry to insert if needed.
+
+ BottomEntry - Bottom pad entry to insert if needed.
+
+Returns:
+
+ EFI_SUCCESS - The new range was inserted into the linked list
+
+--*/
+{
+ ASSERT (Length != 0);
+
+ if (BaseAddress > Entry->BaseAddress) {
+ ASSERT (BottomEntry->Signature == 0);
+ EfiCommonLibCopyMem (BottomEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));
+ Entry->BaseAddress = BaseAddress;
+ BottomEntry->EndAddress = BaseAddress - 1;
+ InsertTailList (Link, &BottomEntry->Link);
+ }
+
+ if ((BaseAddress + Length - 1) < Entry->EndAddress) {
+ ASSERT (TopEntry->Signature == 0);
+ EfiCommonLibCopyMem (TopEntry, Entry, sizeof (EFI_GCD_MAP_ENTRY));
+ TopEntry->BaseAddress = BaseAddress + Length;
+ Entry->EndAddress = BaseAddress + Length - 1;
+ InsertHeadList (Link, &TopEntry->Link);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreMergeGcdMapEntry (
+ IN EFI_LIST_ENTRY *Link,
+ IN BOOLEAN Forward,
+ IN EFI_LIST_ENTRY *Map
+ )
+/*++
+
+Routine Description:
+
+ Merge the Gcd region specified by Link and its adjacent entry
+
+Arguments:
+
+ Link - Specify the entry to be merged (with its adjacent entry).
+
+ Forward - Direction (forward or backward).
+
+ Map - Boundary.
+
+Returns:
+
+ EFI_SUCCESS - Successfully returned.
+
+ EFI_UNSUPPORTED - These adjacent regions could not merge.
+
+--*/
+{
+ EFI_LIST_ENTRY *AdjacentLink;
+ EFI_GCD_MAP_ENTRY *Entry;
+ EFI_GCD_MAP_ENTRY *AdjacentEntry;
+
+ //
+ // Get adjacent entry
+ //
+ if (Forward) {
+ AdjacentLink = Link->ForwardLink;
+ } else {
+ AdjacentLink = Link->BackLink;
+ }
+
+ //
+ // If AdjacentLink is the head of the list, then no merge can be performed
+ //
+ if (AdjacentLink == Map) {
+ return EFI_SUCCESS;
+ }
+
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ AdjacentEntry = CR (AdjacentLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+
+ if (Entry->Capabilities != AdjacentEntry->Capabilities) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Entry->Attributes != AdjacentEntry->Attributes) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Entry->GcdMemoryType != AdjacentEntry->GcdMemoryType) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Entry->GcdIoType != AdjacentEntry->GcdIoType) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Entry->ImageHandle != AdjacentEntry->ImageHandle) {
+ return EFI_UNSUPPORTED;
+ }
+ if (Entry->DeviceHandle != AdjacentEntry->DeviceHandle) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Forward) {
+ Entry->EndAddress = AdjacentEntry->EndAddress;
+ } else {
+ Entry->BaseAddress = AdjacentEntry->BaseAddress;
+ }
+ RemoveEntryList (AdjacentLink);
+ CoreFreePool (AdjacentEntry);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreCleanupGcdMapEntry (
+ IN EFI_GCD_MAP_ENTRY *TopEntry,
+ IN EFI_GCD_MAP_ENTRY *BottomEntry,
+ IN EFI_LIST_ENTRY *StartLink,
+ IN EFI_LIST_ENTRY *EndLink,
+ IN EFI_LIST_ENTRY *Map
+ )
+/*++
+
+Routine Description:
+
+ Merge adjacent entries on total chain.
+
+Arguments:
+
+ TopEntry - Top entry of GCD map.
+
+ BottomEntry - Bottom entry of GCD map.
+
+ StartLink - Start link of the list for this loop.
+
+ EndLink - End link of the list for this loop.
+
+ Map - Boundary.
+
+Returns:
+
+ EFI_SUCCESS - GCD map successfully cleaned up.
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+
+ if (TopEntry->Signature == 0) {
+ CoreFreePool (TopEntry);
+ }
+ if (BottomEntry->Signature == 0) {
+ CoreFreePool (BottomEntry);
+ }
+
+ Link = StartLink;
+ while (Link != EndLink->ForwardLink) {
+ CoreMergeGcdMapEntry (Link, FALSE, Map);
+ Link = Link->ForwardLink;
+ }
+ CoreMergeGcdMapEntry (EndLink, TRUE, Map);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreSearchGcdMapEntry (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ OUT EFI_LIST_ENTRY **StartLink,
+ OUT EFI_LIST_ENTRY **EndLink,
+ IN EFI_LIST_ENTRY *Map
+ )
+/*++
+
+Routine Description:
+
+ Search a segment of memory space in GCD map. The result is a range of GCD entry list.
+
+Arguments:
+
+ BaseAddress - The start address of the segment.
+
+ Length - The length of the segment.
+
+ StartLink - The first GCD entry involves this segment of memory space.
+
+ EndLink - The first GCD entry involves this segment of memory space.
+
+ Map - Points to the start entry to search.
+
+Returns:
+
+ EFI_SUCCESS - Successfully found the entry.
+
+ EFI_NOT_FOUND - Not found.
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ EFI_GCD_MAP_ENTRY *Entry;
+
+ ASSERT (Length != 0);
+
+ *StartLink = NULL;
+ *EndLink = NULL;
+
+ Link = Map->ForwardLink;
+ while (Link != Map) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ if (BaseAddress >= Entry->BaseAddress && BaseAddress <= Entry->EndAddress) {
+ *StartLink = Link;
+ }
+ if (*StartLink != NULL) {
+ if ((BaseAddress + Length - 1) >= Entry->BaseAddress &&
+ (BaseAddress + Length - 1) <= Entry->EndAddress ) {
+ *EndLink = Link;
+ return EFI_SUCCESS;
+ }
+ }
+ Link = Link->ForwardLink;
+ }
+ return EFI_NOT_FOUND;
+}
+
+UINTN
+CoreCountGcdMapEntry (
+ IN EFI_LIST_ENTRY *Map
+ )
+/*++
+
+Routine Description:
+
+ Count the amount of GCD map entries.
+
+Arguments:
+
+ Map - Points to the start entry to do the count loop.
+
+Returns:
+
+ The count.
+
+--*/
+{
+ UINTN Count;
+ EFI_LIST_ENTRY *Link;
+
+ Count = 0;
+ Link = Map->ForwardLink;
+ while (Link != Map) {
+ Count++;
+ Link = Link->ForwardLink;
+ }
+ return Count;
+}
+
+UINT64
+ConverToCpuArchAttributes (
+ UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Return the memory attribute specified by Attributes
+
+Arguments:
+
+ Attributes - A num with some attribute bits on.
+
+Returns:
+
+ The enum value of memory attribute.
+
+--*/
+{
+ if ( (Attributes & EFI_MEMORY_UC) == EFI_MEMORY_UC) {
+ return EFI_MEMORY_UC;
+ }
+
+ if ( (Attributes & EFI_MEMORY_WC ) == EFI_MEMORY_WC) {
+ return EFI_MEMORY_WC;
+ }
+
+ if ( (Attributes & EFI_MEMORY_WT ) == EFI_MEMORY_WT) {
+ return EFI_MEMORY_WT;
+ }
+
+ if ( (Attributes & EFI_MEMORY_WB) == EFI_MEMORY_WB) {
+ return EFI_MEMORY_WB;
+ }
+
+ if ( (Attributes & EFI_MEMORY_WP) == EFI_MEMORY_WP) {
+ return EFI_MEMORY_WP;
+ }
+
+ return INVALID_CPU_ARCH_ATTRIBUTES;
+
+}
+
+
+EFI_STATUS
+CoreConvertSpace (
+ IN UINTN Operation,
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN EFI_GCD_IO_TYPE GcdIoType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Capabilities,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Do operation on a segment of memory space specified (add, free, remove, change attribute ...).
+
+Arguments:
+
+ Operation - The type of the operation
+
+ GcdMemoryType - Additional information for the operation
+
+ GcdIoType - Additional information for the operation
+
+ BaseAddress - Start address of the segment
+
+ Length - length of the segment
+
+ Capabilities - The alterable attributes of a newly added entry
+
+ Attributes - The attributes needs to be set
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Length is 0 or address (length) not aligned when setting attribute.
+
+ EFI_SUCCESS - Action successfully done.
+
+ EFI_UNSUPPORTED - Could not find the proper descriptor on this segment or
+ set an upsupported attribute.
+
+ EFI_ACCESS_DENIED - Operate on an space non-exist or is used for an image.
+
+ EFI_NOT_FOUND - Free a non-using space or remove a non-exist space, and so on.
+
+ EFI_OUT_OF_RESOURCES - No buffer could be allocated.
+
+Returns:
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *Map;
+ EFI_LIST_ENTRY *Link;
+ EFI_GCD_MAP_ENTRY *Entry;
+ EFI_GCD_MAP_ENTRY *TopEntry;
+ EFI_GCD_MAP_ENTRY *BottomEntry;
+ EFI_LIST_ENTRY *StartLink;
+ EFI_LIST_ENTRY *EndLink;
+
+ EFI_CPU_ARCH_PROTOCOL *CpuArch;
+ UINT64 CpuArchAttributes;
+
+ if (Length == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Map = NULL;
+ if (Operation & GCD_MEMORY_SPACE_OPERATION) {
+ CoreAcquireGcdMemoryLock ();
+ Map = &mGcdMemorySpaceMap;
+ }
+ if (Operation & GCD_IO_SPACE_OPERATION) {
+ CoreAcquireGcdIoLock ();
+ Map = &mGcdIoSpaceMap;
+ }
+
+ //
+ // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
+ //
+ Status = CoreSearchGcdMapEntry (BaseAddress, Length, &StartLink, &EndLink, Map);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_UNSUPPORTED;
+
+ goto Done;
+ }
+
+ //
+ // Verify that the list of descriptors are unallocated non-existent memory.
+ //
+ Link = StartLink;
+ while (Link != EndLink->ForwardLink) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ switch (Operation) {
+ //
+ // Add operations
+ //
+ case GCD_ADD_MEMORY_OPERATION:
+ if (Entry->GcdMemoryType != EfiGcdMemoryTypeNonExistent ||
+ Entry->ImageHandle != NULL ) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ break;
+ case GCD_ADD_IO_OPERATION:
+ if (Entry->GcdIoType != EfiGcdIoTypeNonExistent ||
+ Entry->ImageHandle != NULL ) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ break;
+ //
+ // Free operations
+ //
+ case GCD_FREE_MEMORY_OPERATION:
+ case GCD_FREE_IO_OPERATION:
+ if (Entry->ImageHandle == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ break;
+ //
+ // Remove operations
+ //
+ case GCD_REMOVE_MEMORY_OPERATION:
+ if (Entry->GcdMemoryType == EfiGcdMemoryTypeNonExistent) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ if (Entry->ImageHandle != NULL) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ break;
+ case GCD_REMOVE_IO_OPERATION:
+ if (Entry->GcdIoType == EfiGcdIoTypeNonExistent) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ if (Entry->ImageHandle != NULL) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ break;
+ //
+ // Set attribute operations
+ //
+ case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:
+ if (Attributes & EFI_MEMORY_RUNTIME) {
+ if ((BaseAddress & EFI_PAGE_MASK) != 0 || (Length & EFI_PAGE_MASK) != 0) {
+ Status = EFI_INVALID_PARAMETER;
+
+ goto Done;
+ }
+ }
+ if ((Entry->Capabilities & Attributes) != Attributes) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+ break;
+ }
+ Link = Link->ForwardLink;
+ }
+
+ //
+ // Allocate work space to perform this operation
+ //
+ Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ if (Operation == GCD_SET_ATTRIBUTES_MEMORY_OPERATION) {
+ //
+ // Call CPU Arch Protocol to attempt to set attributes on the range
+ //
+ CpuArchAttributes = ConverToCpuArchAttributes (Attributes);
+ if ( CpuArchAttributes != INVALID_CPU_ARCH_ATTRIBUTES ) {
+ Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, &CpuArch);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+
+ Status = CpuArch->SetMemoryAttributes (
+ CpuArch,
+ BaseAddress,
+ Length,
+ CpuArchAttributes
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+
+ }
+
+ //
+ // Convert/Insert the list of descriptors from StartLink to EndLink
+ //
+ Link = StartLink;
+ while (Link != EndLink->ForwardLink) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ CoreInsertGcdMapEntry (Link, Entry, BaseAddress, Length, TopEntry, BottomEntry);
+ switch (Operation) {
+ //
+ // Add operations
+ //
+ case GCD_ADD_MEMORY_OPERATION:
+ Entry->GcdMemoryType = GcdMemoryType;
+ if (GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) {
+ Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME | EFI_MEMORY_PORT_IO;
+ } else {
+ Entry->Capabilities = Capabilities | EFI_MEMORY_RUNTIME;
+ }
+ break;
+ case GCD_ADD_IO_OPERATION:
+ Entry->GcdIoType = GcdIoType;
+ break;
+ //
+ // Free operations
+ //
+ case GCD_FREE_MEMORY_OPERATION:
+ case GCD_FREE_IO_OPERATION:
+ Entry->ImageHandle = NULL;
+ Entry->DeviceHandle = NULL;
+ break;
+ //
+ // Remove operations
+ //
+ case GCD_REMOVE_MEMORY_OPERATION:
+ Entry->GcdMemoryType = EfiGcdMemoryTypeNonExistent;
+ Entry->Capabilities = 0;
+ break;
+ case GCD_REMOVE_IO_OPERATION:
+ Entry->GcdIoType = EfiGcdIoTypeNonExistent;
+ break;
+ //
+ // Set attribute operations
+ //
+ case GCD_SET_ATTRIBUTES_MEMORY_OPERATION:
+ Entry->Attributes = Attributes;
+ break;
+ }
+ Link = Link->ForwardLink;
+ }
+
+ //
+ // Cleanup
+ //
+ Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);
+
+Done:
+ if (Operation & GCD_MEMORY_SPACE_OPERATION) {
+ CoreReleaseGcdMemoryLock ();
+ }
+ if (Operation & GCD_IO_SPACE_OPERATION) {
+ CoreReleaseGcdIoLock ();
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+CoreAllocateSpaceCheckEntry (
+ IN UINTN Operation,
+ IN EFI_GCD_MAP_ENTRY *Entry,
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN EFI_GCD_IO_TYPE GcdIoType
+ )
+/*++
+
+Routine Description:
+
+ Check whether an entry could be used to allocate space.
+
+Arguments:
+
+ Operation - Allocate memory or IO
+
+ Entry - The entry to be tested
+
+ GcdMemoryType - The desired memory type
+
+ GcdIoType - The desired IO type
+
+Returns:
+
+ EFI_NOT_FOUND - The memory type does not match or there's an image handle on the entry.
+
+ EFI_UNSUPPORTED - The operation unsupported.
+
+ EFI_SUCCESS - It's ok for this entry to be used to allocate space.
+
+--*/
+{
+ if (Entry->ImageHandle != NULL) {
+ return EFI_NOT_FOUND;
+ }
+ switch (Operation) {
+ case GCD_ALLOCATE_MEMORY_OPERATION:
+ if (Entry->GcdMemoryType != GcdMemoryType) {
+ return EFI_NOT_FOUND;
+ }
+ break;
+ case GCD_ALLOCATE_IO_OPERATION:
+ if (Entry->GcdIoType != GcdIoType) {
+ return EFI_NOT_FOUND;
+ }
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreAllocateSpace (
+ IN UINTN Operation,
+ IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN EFI_GCD_IO_TYPE GcdIoType,
+ IN UINTN Alignment,
+ IN UINT64 Length,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Allocate space on specified address and length.
+
+Arguments:
+
+ Operation - The type of operation (memory or IO)
+ GcdAllocateType - The type of allocate operation
+ GcdMemoryType - The desired memory type
+ GcdIoType - The desired IO type
+ Alignment - Align with 2^Alignment
+ Length - Length to allocate
+ BaseAddress - Base address to allocate
+ ImageHandle - The image handle consume the allocated space.
+ DeviceHandle - The device handle consume the allocated space.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter.
+ EFI_NOT_FOUND - No descriptor for the desired space exists.
+ EFI_SUCCESS - Space successfully allocated.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS AlignmentMask;
+ EFI_PHYSICAL_ADDRESS MaxAddress;
+ EFI_LIST_ENTRY *Map;
+ EFI_LIST_ENTRY *Link;
+ EFI_LIST_ENTRY *SubLink;
+ EFI_GCD_MAP_ENTRY *Entry;
+ EFI_GCD_MAP_ENTRY *TopEntry;
+ EFI_GCD_MAP_ENTRY *BottomEntry;
+ EFI_LIST_ENTRY *StartLink;
+ EFI_LIST_ENTRY *EndLink;
+ BOOLEAN Found;
+
+ //
+ // Make sure parameters are valid
+ //
+ if (GcdAllocateType < 0 || GcdAllocateType >= EfiGcdMaxAllocateType) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (GcdMemoryType < 0 || GcdMemoryType >= EfiGcdMemoryTypeMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (GcdIoType < 0 || GcdIoType >= EfiGcdIoTypeMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (BaseAddress == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (ImageHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Alignment >= 64) {
+ return EFI_NOT_FOUND;
+ }
+ if (Length == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Map = NULL;
+ if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
+ CoreAcquireGcdMemoryLock ();
+ Map = &mGcdMemorySpaceMap;
+ }
+ if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
+ CoreAcquireGcdIoLock ();
+ Map = &mGcdIoSpaceMap;
+ }
+
+ Found = FALSE;
+ StartLink = NULL;
+ EndLink = NULL;
+ //
+ // Compute alignment bit mask
+ //
+ AlignmentMask = LShiftU64 (1, Alignment) - 1;
+
+ if (GcdAllocateType == EfiGcdAllocateAddress) {
+ //
+ // Verify that the BaseAddress passed in is aligned correctly
+ //
+ if ((*BaseAddress & AlignmentMask) != 0) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
+ //
+ Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
+ //
+ Link = StartLink;
+ while (Link != EndLink->ForwardLink) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ Link = Link->ForwardLink;
+ Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+ Found = TRUE;
+ } else {
+
+ Entry = CR (Map->BackLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+
+ //
+ // Compute the maximum address to use in the search algorithm
+ //
+ if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchBottomUp ||
+ GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown) {
+ MaxAddress = *BaseAddress;
+ } else {
+ MaxAddress = Entry->EndAddress;
+ }
+
+ //
+ // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
+ //
+ if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||
+ GcdAllocateType == EfiGcdAllocateAnySearchTopDown) {
+ Link = Map->BackLink;
+ } else {
+ Link = Map->ForwardLink;
+ }
+ while (Link != Map) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+
+ if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||
+ GcdAllocateType == EfiGcdAllocateAnySearchTopDown) {
+ Link = Link->BackLink;
+ } else {
+ Link = Link->ForwardLink;
+ }
+
+ Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ if (GcdAllocateType == EfiGcdAllocateMaxAddressSearchTopDown ||
+ GcdAllocateType == EfiGcdAllocateAnySearchTopDown) {
+ if (Entry->BaseAddress > MaxAddress) {
+ continue;
+ }
+ if (Length > (Entry->EndAddress + 1)) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ if (Entry->EndAddress > MaxAddress) {
+ *BaseAddress = MaxAddress;
+ } else {
+ *BaseAddress = Entry->EndAddress;
+ }
+ *BaseAddress = (*BaseAddress + 1 - Length) & (~AlignmentMask);
+ } else {
+ *BaseAddress = (Entry->BaseAddress + AlignmentMask) & (~AlignmentMask);
+ if ((*BaseAddress + Length - 1) > MaxAddress) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ }
+
+ //
+ // Search for the list of descriptors that cover the range BaseAddress to BaseAddress+Length
+ //
+ Status = CoreSearchGcdMapEntry (*BaseAddress, Length, &StartLink, &EndLink, Map);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ Link = StartLink;
+ //
+ // Verify that the list of descriptors are unallocated memory matching GcdMemoryType.
+ //
+ Found = TRUE;
+ SubLink = StartLink;
+ while (SubLink != EndLink->ForwardLink) {
+ Entry = CR (SubLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ Status = CoreAllocateSpaceCheckEntry (Operation, Entry, GcdMemoryType, GcdIoType);
+ if (EFI_ERROR (Status)) {
+ Link = SubLink;
+ Found = FALSE;
+ break;
+ }
+ SubLink = SubLink->ForwardLink;
+ }
+ if (Found) {
+ break;
+ }
+ }
+ }
+ if (!Found) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Allocate work space to perform this operation
+ //
+ Status = CoreAllocateGcdMapEntry (&TopEntry, &BottomEntry);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Convert/Insert the list of descriptors from StartLink to EndLink
+ //
+ Link = StartLink;
+ while (Link != EndLink->ForwardLink) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ CoreInsertGcdMapEntry (Link, Entry, *BaseAddress, Length, TopEntry, BottomEntry);
+ Entry->ImageHandle = ImageHandle;
+ Entry->DeviceHandle = DeviceHandle;
+ Link = Link->ForwardLink;
+ }
+
+ //
+ // Cleanup
+ //
+ Status = CoreCleanupGcdMapEntry (TopEntry, BottomEntry, StartLink, EndLink, Map);
+
+Done:
+ if ((Operation & GCD_MEMORY_SPACE_OPERATION) != 0) {
+ CoreReleaseGcdMemoryLock ();
+ }
+ if ((Operation & GCD_IO_SPACE_OPERATION) != 0) {
+ CoreReleaseGcdIoLock ();
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+CoreInternalAddMemorySpace (
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Capabilities
+ )
+/*++
+
+Routine Description:
+
+ Add a segment of memory to GCD map.
+
+Arguments:
+
+ GcdMemoryType - Memory type of the segment.
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+ Capabilities - alterable attributes of the segment.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameters.
+
+ EFI_SUCCESS - Successfully add a segment of memory space.
+
+--*/
+{
+ //
+ // Make sure parameters are valid
+ //
+ if (GcdMemoryType <= EfiGcdMemoryTypeNonExistent || GcdMemoryType >= EfiGcdMemoryTypeMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return CoreConvertSpace (GCD_ADD_MEMORY_OPERATION, GcdMemoryType, 0, BaseAddress, Length, Capabilities, 0);
+}
+
+//
+// GCD Core Services
+//
+EFI_STATUS
+CoreAllocateMemorySpace (
+ IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN UINTN Alignment,
+ IN UINT64 Length,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Allocates nonexistent memory, reserved memory, system memory, or memorymapped
+I/O resources from the global coherency domain of the processor.
+
+Arguments:
+
+ GcdAllocateType - The type of allocate operation
+
+ GcdMemoryType - The desired memory type
+
+ Alignment - Align with 2^Alignment
+
+ Length - Length to allocate
+
+ BaseAddress - Base address to allocate
+
+ ImageHandle - The image handle consume the allocated space.
+
+ DeviceHandle - The device handle consume the allocated space.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+ EFI_NOT_FOUND - No descriptor contains the desired space.
+
+ EFI_SUCCESS - Memory space successfully allocated.
+
+--*/
+{
+ return CoreAllocateSpace (
+ GCD_ALLOCATE_MEMORY_OPERATION,
+ GcdAllocateType,
+ GcdMemoryType,
+ 0,
+ Alignment,
+ Length,
+ BaseAddress,
+ ImageHandle,
+ DeviceHandle
+ );
+}
+
+EFI_STATUS
+CoreAddMemorySpace (
+ IN EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Capabilities
+ )
+/*++
+
+Routine Description:
+
+ Adds reserved memory, system memory, or memory-mapped I/O resources to the
+global coherency domain of the processor.
+
+Arguments:
+
+ GcdMemoryType - Memory type of the memory space.
+
+ BaseAddress - Base address of the memory space.
+
+ Length - Length of the memory space.
+
+ Capabilities - alterable attributes of the memory space.
+
+Returns:
+
+ EFI_SUCCESS - Merged this memory space into GCD map.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS PageBaseAddress;
+ UINT64 PageLength;
+
+ Status = CoreInternalAddMemorySpace (GcdMemoryType, BaseAddress, Length, Capabilities);
+
+ if (!EFI_ERROR (Status) && GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {
+
+ PageBaseAddress = PageAlignLength (BaseAddress);
+ PageLength = PageAlignLength (BaseAddress + Length - PageBaseAddress);
+
+ Status = CoreAllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ GcdMemoryType,
+ EFI_PAGE_SHIFT,
+ PageLength,
+ &PageBaseAddress,
+ gDxeCoreImageHandle,
+ NULL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ CoreAddMemoryDescriptor (
+ EfiConventionalMemory,
+ PageBaseAddress,
+ RShiftU64 (PageLength, EFI_PAGE_SHIFT),
+ Capabilities
+ );
+ } else {
+ for (; PageLength != 0; PageLength -= EFI_PAGE_SIZE, PageBaseAddress += EFI_PAGE_SIZE) {
+ Status = CoreAllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ GcdMemoryType,
+ EFI_PAGE_SHIFT,
+ EFI_PAGE_SIZE,
+ &PageBaseAddress,
+ gDxeCoreImageHandle,
+ NULL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ CoreAddMemoryDescriptor (
+ EfiConventionalMemory,
+ PageBaseAddress,
+ 1,
+ Capabilities
+ );
+ }
+ }
+ }
+ }
+ return Status;
+}
+
+EFI_STATUS
+CoreFreeMemorySpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Frees nonexistent memory, reserved memory, system memory, or memory-mapped
+I/O resources from the global coherency domain of the processor.
+
+Arguments:
+
+ BaseAddress - Base address of the memory space.
+
+ Length - Length of the memory space.
+
+Returns:
+
+ EFI_SUCCESS - Space successfully freed.
+
+--*/
+{
+ return CoreConvertSpace (GCD_FREE_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, 0);
+}
+
+EFI_STATUS
+CoreRemoveMemorySpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Removes reserved memory, system memory, or memory-mapped I/O resources from
+the global coherency domain of the processor.
+
+Arguments:
+
+ BaseAddress - Base address of the memory space.
+
+ Length - Length of the memory space.
+
+Returns:
+
+ EFI_SUCCESS - Successfully remove a segment of memory space.
+
+--*/
+{
+ return CoreConvertSpace (GCD_REMOVE_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, 0);
+}
+
+VOID
+BuildMemoryDescriptor (
+ IN OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor,
+ IN EFI_GCD_MAP_ENTRY *Entry
+ )
+/*++
+
+Routine Description:
+
+ Build a memory descriptor according to an entry.
+
+Arguments:
+
+ Descriptor - The descriptor to be built
+
+ Entry - According to this entry
+
+Returns:
+
+ None
+
+--*/
+{
+ Descriptor->BaseAddress = Entry->BaseAddress;
+ Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1;
+ Descriptor->Capabilities = Entry->Capabilities;
+ Descriptor->Attributes = Entry->Attributes;
+ Descriptor->GcdMemoryType = Entry->GcdMemoryType;
+ Descriptor->ImageHandle = Entry->ImageHandle;
+ Descriptor->DeviceHandle = Entry->DeviceHandle;
+}
+
+EFI_STATUS
+CoreGetMemorySpaceDescriptor (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the descriptor for a memory region containing a specified address.
+
+Arguments:
+
+ BaseAddress - Specified start address
+
+ Descriptor - Specified length
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_SUCCESS - Successfully get memory space descriptor.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *StartLink;
+ EFI_LIST_ENTRY *EndLink;
+ EFI_GCD_MAP_ENTRY *Entry;
+
+ //
+ // Make sure parameters are valid
+ //
+ if (Descriptor == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireGcdMemoryLock ();
+
+ //
+ // Search for the list of descriptors that contain BaseAddress
+ //
+ Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdMemorySpaceMap);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Copy the contents of the found descriptor into Descriptor
+ //
+ Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ BuildMemoryDescriptor (Descriptor, Entry);
+ }
+
+ CoreReleaseGcdMemoryLock ();
+
+ return Status;
+}
+
+EFI_STATUS
+CoreSetMemorySpaceAttributes (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Modifies the attributes for a memory region in the global coherency domain of the
+processor.
+
+Arguments:
+
+ BaseAddress - Specified start address
+
+ Length - Specified length
+
+ Attributes - Specified attributes
+
+Returns:
+
+ EFI_SUCCESS - Successfully set attribute of a segment of memory space.
+
+--*/
+{
+ return CoreConvertSpace (GCD_SET_ATTRIBUTES_MEMORY_OPERATION, 0, 0, BaseAddress, Length, 0, Attributes);
+}
+
+EFI_STATUS
+CoreGetMemorySpaceMap (
+ OUT UINTN *NumberOfDescriptors,
+ OUT EFI_GCD_MEMORY_SPACE_DESCRIPTOR **MemorySpaceMap
+ )
+/*++
+
+Routine Description:
+
+ Returns a map of the memory resources in the global coherency domain of the
+processor.
+
+Arguments:
+
+ NumberOfDescriptors - Number of descriptors.
+
+ MemorySpaceMap - Descriptor array
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Successfully get memory space map.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *Link;
+ EFI_GCD_MAP_ENTRY *Entry;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *Descriptor;
+
+ //
+ // Make sure parameters are valid
+ //
+ if (NumberOfDescriptors == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (MemorySpaceMap == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireGcdMemoryLock ();
+
+ //
+ // Count the number of descriptors
+ //
+ *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdMemorySpaceMap);
+
+ //
+ // Allocate the MemorySpaceMap
+ //
+ *MemorySpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));
+ if (*MemorySpaceMap == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Fill in the MemorySpaceMap
+ //
+ Descriptor = *MemorySpaceMap;
+ Link = mGcdMemorySpaceMap.ForwardLink;
+ while (Link != &mGcdMemorySpaceMap) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ BuildMemoryDescriptor (Descriptor, Entry);
+ Descriptor++;
+ Link = Link->ForwardLink;
+ }
+ Status = EFI_SUCCESS;
+
+Done:
+ CoreReleaseGcdMemoryLock ();
+ return Status;
+}
+
+EFI_STATUS
+CoreAddIoSpace (
+ IN EFI_GCD_IO_TYPE GcdIoType,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Adds reserved I/O or I/O resources to the global coherency domain of the processor.
+
+Arguments:
+
+ GcdIoType - IO type of the segment.
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Merged this segment into GCD map.
+ EFI_INVALID_PARAMETER - Parameter not valid
+
+--*/
+{
+ //
+ // Make sure parameters are valid
+ //
+ if (GcdIoType <= EfiGcdIoTypeNonExistent || GcdIoType >= EfiGcdIoTypeMaximum) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return CoreConvertSpace (GCD_ADD_IO_OPERATION, 0, GcdIoType, BaseAddress, Length, 0, 0);
+}
+
+EFI_STATUS
+CoreAllocateIoSpace (
+ IN EFI_GCD_ALLOCATE_TYPE GcdAllocateType,
+ IN EFI_GCD_IO_TYPE GcdIoType,
+ IN UINTN Alignment,
+ IN UINT64 Length,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Allocates nonexistent I/O, reserved I/O, or I/O resources from the global coherency
+domain of the processor.
+
+Arguments:
+
+ GcdAllocateType - The type of allocate operation
+
+ GcdIoType - The desired IO type
+
+ Alignment - Align with 2^Alignment
+
+ Length - Length to allocate
+
+ BaseAddress - Base address to allocate
+
+ ImageHandle - The image handle consume the allocated space.
+
+ DeviceHandle - The device handle consume the allocated space.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter.
+
+ EFI_NOT_FOUND - No descriptor contains the desired space.
+
+ EFI_SUCCESS - IO space successfully allocated.
+
+--*/
+{
+ return CoreAllocateSpace (
+ GCD_ALLOCATE_IO_OPERATION,
+ GcdAllocateType,
+ 0,
+ GcdIoType,
+ Alignment,
+ Length,
+ BaseAddress,
+ ImageHandle,
+ DeviceHandle
+ );
+}
+
+EFI_STATUS
+CoreFreeIoSpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Frees nonexistent I/O, reserved I/O, or I/O resources from the global coherency
+domain of the processor.
+
+Arguments:
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Space successfully freed.
+
+--*/
+{
+ return CoreConvertSpace (GCD_FREE_IO_OPERATION, 0, 0, BaseAddress, Length, 0, 0);
+}
+
+EFI_STATUS
+CoreRemoveIoSpace (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Removes reserved I/O or I/O resources from the global coherency domain of the
+processor.
+
+Arguments:
+
+ BaseAddress - Base address of the segment.
+
+ Length - Length of the segment.
+
+Returns:
+
+ EFI_SUCCESS - Successfully removed a segment of IO space.
+
+--*/
+{
+ return CoreConvertSpace (GCD_REMOVE_IO_OPERATION, 0, 0, BaseAddress, Length, 0, 0);
+}
+
+VOID
+BuildIoDescriptor (
+ IN EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor,
+ IN EFI_GCD_MAP_ENTRY *Entry
+ )
+/*++
+
+Routine Description:
+
+ Build a IO descriptor according to an entry.
+
+Arguments:
+
+ Descriptor - The descriptor to be built
+
+ Entry - According to this entry
+
+Returns:
+
+ None
+
+--*/
+{
+ Descriptor->BaseAddress = Entry->BaseAddress;
+ Descriptor->Length = Entry->EndAddress - Entry->BaseAddress + 1;
+ Descriptor->GcdIoType = Entry->GcdIoType;
+ Descriptor->ImageHandle = Entry->ImageHandle;
+ Descriptor->DeviceHandle = Entry->DeviceHandle;
+}
+
+EFI_STATUS
+CoreGetIoSpaceDescriptor (
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ OUT EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the descriptor for an I/O region containing a specified address.
+
+Arguments:
+
+ BaseAddress - Specified start address
+
+ Descriptor - Specified length
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Descriptor is NULL.
+
+ EFI_SUCCESS - Successfully get the IO space descriptor.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *StartLink;
+ EFI_LIST_ENTRY *EndLink;
+ EFI_GCD_MAP_ENTRY *Entry;
+
+ //
+ // Make sure parameters are valid
+ //
+ if (Descriptor == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireGcdIoLock ();
+
+ //
+ // Search for the list of descriptors that contain BaseAddress
+ //
+ Status = CoreSearchGcdMapEntry (BaseAddress, 1, &StartLink, &EndLink, &mGcdIoSpaceMap);
+ if (EFI_ERROR (Status)) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Copy the contents of the found descriptor into Descriptor
+ //
+ Entry = CR (StartLink, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ BuildIoDescriptor (Descriptor, Entry);
+ }
+
+ CoreReleaseGcdIoLock ();
+
+ return Status;
+}
+
+EFI_STATUS
+CoreGetIoSpaceMap (
+ OUT UINTN *NumberOfDescriptors,
+ OUT EFI_GCD_IO_SPACE_DESCRIPTOR **IoSpaceMap
+ )
+/*++
+
+Routine Description:
+
+ Returns a map of the I/O resources in the global coherency domain of the processor.
+
+Arguments:
+
+ NumberOfDescriptors - Number of descriptors.
+
+ IoSpaceMap - Descriptor array
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Successfully get IO space map.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LIST_ENTRY *Link;
+ EFI_GCD_MAP_ENTRY *Entry;
+ EFI_GCD_IO_SPACE_DESCRIPTOR *Descriptor;
+
+ //
+ // Make sure parameters are valid
+ //
+ if (NumberOfDescriptors == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (IoSpaceMap == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireGcdIoLock ();
+
+ //
+ // Count the number of descriptors
+ //
+ *NumberOfDescriptors = CoreCountGcdMapEntry (&mGcdIoSpaceMap);
+
+ //
+ // Allocate the IoSpaceMap
+ //
+ *IoSpaceMap = CoreAllocateBootServicesPool (*NumberOfDescriptors * sizeof (EFI_GCD_IO_SPACE_DESCRIPTOR));
+ if (*IoSpaceMap == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Fill in the IoSpaceMap
+ //
+ Descriptor = *IoSpaceMap;
+ Link = mGcdIoSpaceMap.ForwardLink;
+ while (Link != &mGcdIoSpaceMap) {
+ Entry = CR (Link, EFI_GCD_MAP_ENTRY, Link, EFI_GCD_MAP_SIGNATURE);
+ BuildIoDescriptor (Descriptor, Entry);
+ Descriptor++;
+ Link = Link->ForwardLink;
+ }
+ Status = EFI_SUCCESS;
+
+Done:
+ CoreReleaseGcdIoLock ();
+ return Status;
+}
+
+UINT64
+CoreConvertResourceDescriptorHobAttributesToCapabilities (
+ EFI_GCD_MEMORY_TYPE GcdMemoryType,
+ UINT64 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Converts a Resource Descriptor HOB attributes mask to an EFI Memory Descriptor
+ capabilities mask
+
+Arguments:
+
+ GcdMemoryType - Type of resource in the GCD memory map.
+ Attributes - The attribute mask in the Resource Descriptor HOB.
+
+Returns:
+
+ The capabilities mask for an EFI Memory Descriptor.
+
+--*/
+{
+ UINT64 Capabilities;
+ GCD_ATTRIBUTE_CONVERSION_ENTRY *Conversion;
+
+ //
+ // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
+ //
+ for (Capabilities = 0, Conversion = mAttributeConversionTable; Conversion->Attribute != 0; Conversion++) {
+ if (Conversion->Memory || (GcdMemoryType != EfiGcdMemoryTypeSystemMemory)) {
+ if (Attributes & Conversion->Attribute) {
+ Capabilities |= Conversion->Capability;
+ }
+ }
+ }
+
+ return Capabilities;
+}
+
+EFI_STATUS
+CoreInitializeMemoryServices (
+ IN VOID **HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *MemoryBaseAddress,
+ OUT UINT64 *MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ External function. Initializes the GCD and memory services based on the memory
+ descriptor HOBs. This function is responsible for priming the GCD map and the
+ memory map, so memory allocations and resource allocations can be made. The first
+ part of this function can not depend on any memory services until at least one
+ memory descriptor is provided to the memory services. Then the memory services
+ can be used to intialize the GCD map.
+
+Arguments:
+
+ HobStart - The start address of the HOB.
+ MemoryBaseAddress - Start address of memory region found to init DXE core.
+ MemoryLength - Length of memory region found to init DXE core.
+
+Returns:
+
+ EFI_SUCCESS - Memory services successfully initialized.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_MEMORY_TYPE_INFORMATION *EfiMemoryTypeInformation;
+ UINTN DataSize;
+ BOOLEAN Found;
+ EFI_HOB_HANDOFF_INFO_TABLE *PhitHob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ EFI_HOB_RESOURCE_DESCRIPTOR *PhitResourceHob;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ UINT64 Attributes;
+ UINT64 Capabilities;
+ EFI_PHYSICAL_ADDRESS MaxMemoryBaseAddress;
+ UINT64 MaxMemoryLength;
+ UINT64 MaxMemoryAttributes;
+ EFI_PHYSICAL_ADDRESS MaxAddress;
+ EFI_PHYSICAL_ADDRESS HighAddress;
+ EFI_HOB_RESOURCE_DESCRIPTOR *MaxResourceHob;
+
+ //
+ // Point at the first HOB. This must be the PHIT HOB.
+ //
+ Hob.Raw = *HobStart;
+ ASSERT (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_HANDOFF);
+
+ //
+ // Initialize the spin locks and maps in the memory services.
+ // Also fill in the memory services into the EFI Boot Services Table
+ //
+ CoreInitializePool ();
+
+ //
+ // Initialize Local Variables
+ //
+ PhitResourceHob = NULL;
+ MaxResourceHob = NULL;
+ ResourceHob = NULL;
+ BaseAddress = 0;
+ Length = 0;
+ Attributes = 0;
+ MaxMemoryBaseAddress = 0;
+ MaxMemoryLength = 0;
+ MaxMemoryAttributes = 0;
+
+ //
+ // Cache the PHIT HOB for later use
+ //
+ PhitHob = Hob.HandoffInformationTable;
+
+ //
+ // See if a Memory Type Information HOB is available
+ //
+ Status = GetNextGuidHob (&Hob.Raw, &gEfiMemoryTypeInformationGuid, &EfiMemoryTypeInformation, &DataSize);
+ if (!EFI_ERROR (Status) &&
+ EfiMemoryTypeInformation != NULL &&
+ DataSize > 0 &&
+ DataSize <= (EfiMaxMemoryType + 1) * sizeof (EFI_MEMORY_TYPE_INFORMATION)) {
+ gBS->CopyMem (&gMemoryTypeInformation, EfiMemoryTypeInformation, DataSize);
+ }
+
+ //
+ // Find the Resource Descriptor HOB that contains range FreeMemoryBaseAddress..FreeMemoryLength
+ //
+ Length = 0;
+ Found = FALSE;
+ for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+
+ ResourceHob = Hob.ResourceDescriptor;
+
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
+ (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES ) {
+
+ if (PhitHob->EfiFreeMemoryBottom >= ResourceHob->PhysicalStart &&
+ PhitHob->EfiFreeMemoryTop <= (ResourceHob->PhysicalStart + ResourceHob->ResourceLength) ) {
+
+ //
+ // Cache the resource descriptor HOB for the memory region described by the PHIT HOB
+ //
+ PhitResourceHob = ResourceHob;
+ Found = TRUE;
+
+ Attributes = PhitResourceHob->ResourceAttribute;
+ BaseAddress = PageAlignAddress (PhitHob->EfiMemoryTop);
+ Length = PageAlignLength (ResourceHob->PhysicalStart + ResourceHob->ResourceLength - BaseAddress);
+ if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
+ BaseAddress = PageAlignAddress (PhitHob->EfiFreeMemoryBottom);
+ Length = PageAlignLength (PhitHob->EfiFreeMemoryTop - BaseAddress);
+ if (Length < MINIMUM_INITIAL_MEMORY_SIZE) {
+ BaseAddress = PageAlignAddress (ResourceHob->PhysicalStart);
+ Length = PageAlignLength ((UINT64)*HobStart - BaseAddress);
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+
+ //
+ // Assert if a resource descriptor HOB for the memory region described by the PHIT was not found
+ //
+ ASSERT (Found);
+
+ //
+ // Search all the resource descriptor HOBs from the highest possible addresses down for a memory
+ // region that is big enough to initialize the DXE core. Always skip the PHIT Resource HOB.
+ // The max address must be within the physically addressible range for the processor.
+ //
+ MaxMemoryLength = 0;
+ MaxAddress = EFI_MAX_ADDRESS;
+ do {
+ HighAddress = 0;
+ Found = FALSE;
+ //
+ // Search for a tested memory region that is below MaxAddress
+ //
+ for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+
+ //
+ // See if this is a resource descriptor HOB that does not contain the PHIT.
+ //
+ if (Hob.ResourceDescriptor != PhitResourceHob && GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+
+ ResourceHob = Hob.ResourceDescriptor;
+ //
+ // See if this resource descrior HOB describes tested system memory below MaxAddress
+ //
+ if (ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY &&
+ (ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES &&
+ ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MaxAddress ) {
+
+ //
+ // See if this is the highest tested system memory region below MaxAddress
+ //
+ if (ResourceHob->PhysicalStart > HighAddress) {
+
+ MaxResourceHob = ResourceHob;
+ HighAddress = MaxResourceHob->PhysicalStart;
+ Found = TRUE;
+ }
+ }
+ }
+ }
+ if (Found) {
+ //
+ // Compute the size of the tested memory region below MaxAddrees
+ //
+ MaxMemoryBaseAddress = PageAlignAddress (MaxResourceHob->PhysicalStart);
+ MaxMemoryLength = PageAlignLength (MaxResourceHob->PhysicalStart + MaxResourceHob->ResourceLength - MaxMemoryBaseAddress);
+ MaxMemoryAttributes = MaxResourceHob->ResourceAttribute;
+ }
+ MaxAddress = ResourceHob->PhysicalStart;
+ } while (Found && MaxMemoryLength < MINIMUM_INITIAL_MEMORY_SIZE);
+
+ //
+ //
+ //
+ if ((Length < MINIMUM_INITIAL_MEMORY_SIZE) ||
+ (MaxMemoryBaseAddress > BaseAddress && MaxMemoryLength >= MINIMUM_INITIAL_MEMORY_SIZE) ) {
+ BaseAddress = MaxMemoryBaseAddress;
+ Length = MaxMemoryLength;
+ Attributes = MaxMemoryAttributes;
+ }
+
+ //
+ // If no memory regions are found that are big enough to initialize the DXE core, then ASSERT().
+ //
+ ASSERT (Length >= MINIMUM_INITIAL_MEMORY_SIZE);
+
+ //
+ // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
+ //
+ Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (EfiGcdMemoryTypeSystemMemory, Attributes);
+
+ //
+ // Declare the very first memory region, so the EFI Memory Services are available.
+ //
+ CoreAddMemoryDescriptor (
+ EfiConventionalMemory,
+ BaseAddress,
+ RShiftU64 (Length, EFI_PAGE_SHIFT),
+ Capabilities
+ );
+
+ *MemoryBaseAddress = BaseAddress;
+ *MemoryLength = Length;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CoreInitializeGcdServices (
+ IN OUT VOID **HobStart,
+ IN EFI_PHYSICAL_ADDRESS MemoryBaseAddress,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ External function. Initializes the GCD and memory services based on the memory
+ descriptor HOBs. This function is responsible for priming the GCD map and the
+ memory map, so memory allocations and resource allocations can be made. The first
+ part of this function can not depend on any memory services until at least one
+ memory descriptor is provided to the memory services. Then the memory services
+ can be used to intialize the GCD map. The HobStart will be relocated to a pool
+ buffer.
+
+Arguments:
+
+ HobStart - The start address of the HOB
+
+ MemoryBaseAddress - Start address of memory region found to init DXE core.
+
+ MemoryLength - Length of memory region found to init DXE core.
+
+
+Returns:
+
+ EFI_SUCCESS - GCD services successfully initialized.
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ VOID *NewHobList;
+ EFI_HOB_HANDOFF_INFO_TABLE *PhitHob;
+ UINT8 SizeOfMemorySpace;
+ UINT8 SizeOfIoSpace;
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT64 Length;
+ EFI_STATUS Status;
+ EFI_GCD_MAP_ENTRY *Entry;
+ EFI_GCD_MEMORY_TYPE GcdMemoryType;
+ EFI_GCD_IO_TYPE GcdIoType;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR Descriptor;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
+ EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
+ UINTN NumberOfDescriptors;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap;
+ UINTN Index;
+ UINT64 Capabilities;
+
+ //
+ // Cache the PHIT HOB for later use
+ //
+ PhitHob = (EFI_HOB_HANDOFF_INFO_TABLE *)(*HobStart);
+
+ //
+ // Get the number of address lines in the I/O and Memory space for the CPU
+ //
+ Status = GetCpuHobInfo (*HobStart, &SizeOfMemorySpace, &SizeOfIoSpace);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Initialize the GCD Memory Space Map
+ //
+ Entry = CoreAllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdMemorySpaceMapEntryTemplate);
+ ASSERT (Entry != NULL);
+
+ Entry->EndAddress = LShiftU64 (1, SizeOfMemorySpace) - 1;
+
+ InsertHeadList (&mGcdMemorySpaceMap, &Entry->Link);
+
+ //
+ // Initialize the GCD I/O Space Map
+ //
+ Entry = CoreAllocateCopyPool (sizeof (EFI_GCD_MAP_ENTRY), &mGcdIoSpaceMapEntryTemplate);
+ ASSERT (Entry != NULL);
+
+ Entry->EndAddress = LShiftU64 (1, SizeOfIoSpace) - 1;
+
+ InsertHeadList (&mGcdIoSpaceMap, &Entry->Link);
+
+ //
+ // Walk the HOB list and add all resource descriptors to the GCD
+ //
+ for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+
+ GcdMemoryType = EfiGcdMemoryTypeNonExistent;
+ GcdIoType = EfiGcdIoTypeNonExistent;
+
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+
+ ResourceHob = Hob.ResourceDescriptor;
+
+ switch (ResourceHob->ResourceType) {
+ case EFI_RESOURCE_SYSTEM_MEMORY:
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == TESTED_MEMORY_ATTRIBUTES) {
+ GcdMemoryType = EfiGcdMemoryTypeSystemMemory;
+ }
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == INITIALIZED_MEMORY_ATTRIBUTES) {
+//*** AMI PORTING BEGIN ***//
+// TODO: MRC reports most of the memory as untested. As a result it is marked as Reserved.
+// GcdMemoryType = EfiGcdMemoryTypeReserved;
+ GcdMemoryType = EfiGcdMemoryTypeSystemMemory;
+//*** AMI PORTING END *****//
+ }
+ if ((ResourceHob->ResourceAttribute & MEMORY_ATTRIBUTE_MASK) == PRESENT_MEMORY_ATTRIBUTES) {
+ GcdMemoryType = EfiGcdMemoryTypeReserved;
+ }
+ break;
+ case EFI_RESOURCE_MEMORY_MAPPED_IO:
+ case EFI_RESOURCE_FIRMWARE_DEVICE:
+ GcdMemoryType = EfiGcdMemoryTypeMemoryMappedIo;
+ break;
+ case EFI_RESOURCE_MEMORY_MAPPED_IO_PORT:
+ case EFI_RESOURCE_MEMORY_RESERVED:
+ GcdMemoryType = EfiGcdMemoryTypeReserved;
+ break;
+ case EFI_RESOURCE_IO:
+ GcdIoType = EfiGcdIoTypeIo;
+ break;
+ case EFI_RESOURCE_IO_RESERVED:
+ GcdIoType = EfiGcdIoTypeReserved;
+ break;
+ }
+
+ if (GcdMemoryType != EfiGcdMemoryTypeNonExistent) {
+
+ //
+ // Convert the Resource HOB Attributes to an EFI Memory Capabilities mask
+ //
+ Capabilities = CoreConvertResourceDescriptorHobAttributesToCapabilities (
+ GcdMemoryType,
+ ResourceHob->ResourceAttribute
+ );
+
+ Status = CoreInternalAddMemorySpace (
+ GcdMemoryType,
+ ResourceHob->PhysicalStart,
+ ResourceHob->ResourceLength,
+ Capabilities
+ );
+ }
+
+ if (GcdIoType != EfiGcdIoTypeNonExistent) {
+ Status = CoreAddIoSpace (
+ GcdIoType,
+ ResourceHob->PhysicalStart,
+ ResourceHob->ResourceLength
+ );
+ }
+ }
+ }
+
+ //
+ // Allocate first memory region from the GCD by the DXE core
+ //
+ Status = CoreAllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeSystemMemory,
+ 0,
+ MemoryLength,
+ &MemoryBaseAddress,
+ gDxeCoreImageHandle,
+ NULL
+ );
+
+ //
+ // Walk the HOB list and allocate all memory space that is consumed by memory allocation HOBs,
+ // and Firmware Volume HOBs. Also update the EFI Memory Map with the memory allocation HOBs.
+ //
+ for (Hob.Raw = *HobStart; !END_OF_HOB_LIST(Hob); Hob.Raw = GET_NEXT_HOB(Hob)) {
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+ MemoryHob = Hob.MemoryAllocation;
+ BaseAddress = MemoryHob->AllocDescriptor.MemoryBaseAddress;
+ Status = CoreGetMemorySpaceDescriptor (BaseAddress, &Descriptor);
+ if (!EFI_ERROR (Status)) {
+ Status = CoreAllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ Descriptor.GcdMemoryType,
+ 0,
+ MemoryHob->AllocDescriptor.MemoryLength,
+ &BaseAddress,
+ gDxeCoreImageHandle,
+ NULL
+ );
+ if (!EFI_ERROR (Status) && Descriptor.GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {
+ CoreAddMemoryDescriptor (
+ MemoryHob->AllocDescriptor.MemoryType,
+ MemoryHob->AllocDescriptor.MemoryBaseAddress,
+ RShiftU64 (MemoryHob->AllocDescriptor.MemoryLength, EFI_PAGE_SHIFT),
+ Descriptor.Capabilities & (~EFI_MEMORY_RUNTIME)
+ );
+ }
+ }
+ }
+
+ if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
+ FirmwareVolumeHob = Hob.FirmwareVolume;
+ BaseAddress = FirmwareVolumeHob->BaseAddress;
+ Status = CoreAllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 0,
+ FirmwareVolumeHob->Length,
+ &BaseAddress,
+ gDxeCoreImageHandle,
+ NULL
+ );
+ }
+ }
+
+ //
+ // Relocate HOB List to an allocated pool buffer.
+ //
+ NewHobList = CoreAllocateCopyPool (
+ (UINTN)PhitHob->EfiFreeMemoryBottom - (UINTN)(*HobStart),
+ *HobStart
+ );
+ ASSERT (NewHobList != NULL);
+
+ *HobStart = NewHobList;
+
+ //
+ // Add and allocate the remaining unallocated system memory to the memory services.
+ //
+ Status = CoreGetMemorySpaceMap (&NumberOfDescriptors, &MemorySpaceMap);
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {
+ if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeSystemMemory) {
+ if (MemorySpaceMap[Index].ImageHandle == NULL) {
+ BaseAddress = PageAlignAddress (MemorySpaceMap[Index].BaseAddress);
+ Length = PageAlignLength (MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length - BaseAddress);
+ if (Length == 0 || MemorySpaceMap[Index].BaseAddress + MemorySpaceMap[Index].Length < BaseAddress) {
+ continue;
+ }
+ CoreAddMemoryDescriptor (
+ EfiConventionalMemory,
+ BaseAddress,
+ RShiftU64 (Length, EFI_PAGE_SHIFT),
+ MemorySpaceMap[Index].Capabilities & (~EFI_MEMORY_RUNTIME)
+ );
+ Status = CoreAllocateMemorySpace (
+ EfiGcdAllocateAddress,
+ EfiGcdMemoryTypeSystemMemory,
+ 0,
+ Length,
+ &BaseAddress,
+ gDxeCoreImageHandle,
+ NULL
+ );
+ }
+ }
+ }
+ CoreFreePool (MemorySpaceMap);
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/gcd.h b/Core/CORE_DXE/gcd.h
new file mode 100644
index 0000000..13d448d
--- /dev/null
+++ b/Core/CORE_DXE/gcd.h
@@ -0,0 +1,54 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ gcd.h
+
+Abstract:
+
+Revision History
+
+--*/
+
+#ifndef _GCD_H
+#define _GCD_H
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+//
+// GCD Operations
+//
+#define GCD_MEMORY_SPACE_OPERATION 0x20
+#define GCD_IO_SPACE_OPERATION 0x40
+
+#define GCD_ADD_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 0)
+#define GCD_ALLOCATE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 1)
+#define GCD_FREE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 2)
+#define GCD_REMOVE_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 3)
+#define GCD_SET_ATTRIBUTES_MEMORY_OPERATION (GCD_MEMORY_SPACE_OPERATION | 4)
+
+#define GCD_ADD_IO_OPERATION (GCD_IO_SPACE_OPERATION | 0)
+#define GCD_ALLOCATE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 1)
+#define GCD_FREE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 2)
+#define GCD_REMOVE_IO_OPERATION (GCD_IO_SPACE_OPERATION | 3)
+
+//
+// The data structure used to convert from GCD attributes to EFI Memory Map attributes
+//
+typedef struct {
+ UINT64 Attribute;
+ UINT64 Capability;
+ BOOLEAN Memory;
+} GCD_ATTRIBUTE_CONVERSION_ENTRY;
+
+#endif
diff --git a/Core/CORE_DXE/hand.h b/Core/CORE_DXE/hand.h
new file mode 100644
index 0000000..d048073
--- /dev/null
+++ b/Core/CORE_DXE/hand.h
@@ -0,0 +1,339 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ hand.h
+
+Abstract:
+
+ EFI internal protocol definitions
+
+
+
+Revision History
+
+--*/
+
+#ifndef _HAND_H_
+#define _HAND_H_
+
+#include "Tiano.h"
+#include "DxeCore.h"
+
+//
+// IHANDLE - contains a list of protocol handles
+//
+
+#define EFI_HANDLE_SIGNATURE EFI_SIGNATURE_32('h','n','d','l')
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY AllHandles; // All handles list of IHANDLE
+ EFI_LIST_ENTRY Protocols; // List of PROTOCOL_INTERFACE's for this handle
+ UINTN LocateRequest; //
+ UINT64 Key; // The Handle Database Key value when this handle was last created or modified
+} IHANDLE;
+
+#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)
+
+
+//
+// PROTOCOL_ENTRY - each different protocol has 1 entry in the protocol
+// database. Each handler that supports this protocol is listed, along
+// with a list of registered notifies.
+//
+
+#define PROTOCOL_ENTRY_SIGNATURE EFI_SIGNATURE_32('p','r','t','e')
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY AllEntries; // All entries
+ EFI_GUID ProtocolID; // ID of the protocol
+ EFI_LIST_ENTRY Protocols; // All protocol interfaces
+ EFI_LIST_ENTRY Notify; // Registerd notification handlers
+} PROTOCOL_ENTRY;
+
+//
+// PROTOCOL_INTERFACE - each protocol installed on a handle is tracked
+// with a protocol interface structure
+//
+
+#define PROTOCOL_INTERFACE_SIGNATURE EFI_SIGNATURE_32('p','i','f','c')
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle; // Back pointer
+ EFI_LIST_ENTRY Link; // Link on IHANDLE.Protocols
+ EFI_LIST_ENTRY ByProtocol; // Link on PROTOCOL_ENTRY.Protocols
+ PROTOCOL_ENTRY *Protocol; // The protocol ID
+ VOID *Interface; // The interface value
+
+ EFI_LIST_ENTRY OpenList; // OPEN_PROTOCOL_DATA list.
+ UINTN OpenListCount;
+
+ EFI_HANDLE ControllerHandle;
+
+} PROTOCOL_INTERFACE;
+
+#define OPEN_PROTOCOL_DATA_SIGNATURE EFI_SIGNATURE_32('p','o','d','l')
+
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY Link;
+
+ EFI_HANDLE AgentHandle;
+ EFI_HANDLE ControllerHandle;
+ UINT32 Attributes;
+ UINT32 OpenCount;
+} OPEN_PROTOCOL_DATA;
+
+
+//
+// PROTOCOL_NOTIFY - used for each register notification for a protocol
+//
+
+#define PROTOCOL_NOTIFY_SIGNATURE EFI_SIGNATURE_32('p','r','t','n')
+typedef struct {
+ UINTN Signature;
+ PROTOCOL_ENTRY *Protocol;
+ EFI_LIST_ENTRY Link; // All notifications for this protocol
+ EFI_EVENT Event; // Event to notify
+ EFI_LIST_ENTRY *Position; // Last position notified
+} PROTOCOL_NOTIFY;
+
+//
+// Internal prototypes
+//
+
+
+PROTOCOL_ENTRY *
+CoreFindProtocolEntry (
+ IN EFI_GUID *Protocol,
+ IN BOOLEAN Create
+ )
+/*++
+
+Routine Description:
+
+ Finds the protocol entry for the requested protocol.
+
+ N.B. The gProtocolDatabaseLock must be owned
+
+Arguments:
+
+ Protocol - The ID of the protocol
+
+ Create - Create a new entry if not found
+
+Returns:
+
+ Protocol entry
+
+--*/
+;
+
+VOID
+CoreNotifyProtocolEntry (
+ IN PROTOCOL_ENTRY *ProtEntry
+ )
+/*++
+
+Routine Description:
+
+ Signal event for every protocol in protocol entry.
+
+Arguments:
+
+ ProtEntry - Protocol entry
+
+Returns:
+
+--*/
+;
+
+PROTOCOL_INTERFACE *
+CoreFindProtocolInterface (
+ IN IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Finds the protocol instance for the requested handle and protocol.
+
+ Note: This function doesn't do parameters checking, it's caller's responsibility
+ to pass in valid parameters.
+
+Arguments:
+
+ Handle - The handle to search the protocol on
+
+ Protocol - GUID of the protocol
+
+ Interface - The interface for the protocol being searched
+
+Returns:
+
+ Protocol instance (NULL: Not found)
+
+--*/
+;
+
+PROTOCOL_INTERFACE *
+CoreRemoveInterfaceFromProtocol (
+ IN IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Removes Protocol from the protocol list (but not the handle list).
+
+Arguments:
+
+ Handle - The handle to remove protocol on.
+
+ Protocol - GUID of the protocol to be moved
+
+ Interface - The interface of the protocol
+
+Returns:
+
+ Protocol Entry
+
+--*/
+;
+
+EFI_STATUS
+CoreUnregisterProtocolNotify (
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ Removes all the events in the protocol database that match Event.
+
+Arguments:
+
+ Event - The event to search for in the protocol database.
+
+Returns:
+
+ EFI_SUCCESS when done searching the entire database.
+
+--*/
+;
+
+EFI_STATUS
+CoreDisconnectControllersUsingProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN PROTOCOL_INTERFACE *Prot
+ )
+/*++
+
+Routine Description:
+
+ Attempts to disconnect all drivers that are using the protocol interface being queried.
+ If failed, reconnect all drivers disconnected.
+
+ Note: This function doesn't do parameters checking, it's caller's responsibility
+ to pass in valid parameters.
+
+Arguments:
+
+ UserHandle - The handle on which the protocol is installed
+ Prot - The protocol to disconnect drivers from
+
+Returns:
+
+ EFI_SUCCESS - Drivers using the protocol interface are all disconnected
+ EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers
+
+--*/
+;
+
+VOID
+CoreAcquireProtocolLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Acquire lock on gProtocolDatabaseLock.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CoreReleaseProtocolLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Release lock on gProtocolDatabaseLock.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+CoreValidateHandle (
+ IN EFI_HANDLE UserHandle
+ )
+/*++
+
+Routine Description:
+
+ Check whether a handle is a valid EFI_HANDLE
+
+Arguments:
+
+ UserHandle - The handle to check
+
+Returns:
+
+ EFI_INVALID_PARAMETER - The handle is NULL or not a valid EFI_HANDLE.
+
+ EFI_SUCCESS - The handle is valid EFI_HANDLE.
+
+--*/
+;
+
+//
+// Externs
+//
+
+extern EFI_LOCK gProtocolDatabaseLock;
+extern EFI_LIST_ENTRY gHandleList;
+extern UINT64 gHandleDatabaseKey;
+
+#endif
diff --git a/Core/CORE_DXE/handle.c b/Core/CORE_DXE/handle.c
new file mode 100644
index 0000000..0def8d1
--- /dev/null
+++ b/Core/CORE_DXE/handle.c
@@ -0,0 +1,1703 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ handle.c
+
+Abstract:
+
+ EFI handle & protocol handling
+
+
+
+Revision History
+
+--*/
+
+#include "hand.h"
+#include EFI_PROTOCOL_DEFINITION (DevicePath)
+
+
+//
+// mProtocolDatabase - A list of all protocols in the system. (simple list for now)
+// gHandleList - A list of all the handles in the system
+// gProtocolDatabaseLock - Lock to protect the mProtocolDatabase
+// gHandleDatabaseKey - The Key to show that the handle has been created/modified
+//
+static EFI_LIST_ENTRY mProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (mProtocolDatabase);
+EFI_LIST_ENTRY gHandleList = INITIALIZE_LIST_HEAD_VARIABLE (gHandleList);
+EFI_LOCK gProtocolDatabaseLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);
+UINT64 gHandleDatabaseKey = 0;
+
+
+VOID
+CoreAcquireProtocolLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Acquire lock on gProtocolDatabaseLock.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreAcquireLock (&gProtocolDatabaseLock);
+}
+
+
+VOID
+CoreReleaseProtocolLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Release lock on gProtocolDatabaseLock.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ CoreReleaseLock (&gProtocolDatabaseLock);
+}
+
+
+EFI_STATUS
+CoreValidateHandle (
+ IN EFI_HANDLE UserHandle
+ )
+/*++
+
+Routine Description:
+
+ Check whether a handle is a valid EFI_HANDLE
+
+Arguments:
+
+ UserHandle - The handle to check
+
+Returns:
+
+ EFI_INVALID_PARAMETER - The handle is NULL or not a valid EFI_HANDLE.
+
+ EFI_SUCCESS - The handle is valid EFI_HANDLE.
+
+--*/
+{
+ IHANDLE *Handle;
+
+ Handle = (IHANDLE *)UserHandle;
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Handle->Signature != EFI_HANDLE_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+
+PROTOCOL_ENTRY *
+CoreFindProtocolEntry (
+ IN EFI_GUID *Protocol,
+ IN BOOLEAN Create
+ )
+/*++
+
+Routine Description:
+
+ Finds the protocol entry for the requested protocol.
+
+ N.B. The gProtocolDatabaseLock must be owned
+
+Arguments:
+
+ Protocol - The ID of the protocol
+
+ Create - Create a new entry if not found
+
+Returns:
+
+ Protocol entry
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ PROTOCOL_ENTRY *Item;
+ PROTOCOL_ENTRY *ProtEntry;
+
+ ASSERT_LOCKED(&gProtocolDatabaseLock);
+
+ //
+ // Search the database for the matching GUID
+ //
+
+ ProtEntry = NULL;
+ for (Link = mProtocolDatabase.ForwardLink;
+ Link != &mProtocolDatabase;
+ Link = Link->ForwardLink) {
+
+ Item = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
+ if (EfiCompareGuid (&Item->ProtocolID, Protocol)) {
+
+ //
+ // This is the protocol entry
+ //
+
+ ProtEntry = Item;
+ break;
+ }
+ }
+
+ //
+ // If the protocol entry was not found and Create is TRUE, then
+ // allocate a new entry
+ //
+ if ((ProtEntry == NULL) && Create) {
+ ProtEntry = CoreAllocateBootServicesPool (sizeof(PROTOCOL_ENTRY));
+
+ if (ProtEntry != NULL) {
+ //
+ // Initialize new protocol entry structure
+ //
+ ProtEntry->Signature = PROTOCOL_ENTRY_SIGNATURE;
+ ProtEntry->ProtocolID = *Protocol;
+ InitializeListHead (&ProtEntry->Protocols);
+ InitializeListHead (&ProtEntry->Notify);
+
+ //
+ // Add it to protocol database
+ //
+ InsertTailList (&mProtocolDatabase, &ProtEntry->AllEntries);
+ }
+ }
+
+ return ProtEntry;
+}
+
+
+PROTOCOL_INTERFACE *
+CoreFindProtocolInterface (
+ IN IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Finds the protocol instance for the requested handle and protocol.
+
+ Note: This function doesn't do parameters checking, it's caller's responsibility
+ to pass in valid parameters.
+
+Arguments:
+
+ Handle - The handle to search the protocol on
+
+ Protocol - GUID of the protocol
+
+ Interface - The interface for the protocol being searched
+
+Returns:
+
+ Protocol instance (NULL: Not found)
+
+--*/
+{
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_ENTRY *ProtEntry;
+ EFI_LIST_ENTRY *Link;
+
+ ASSERT_LOCKED(&gProtocolDatabaseLock);
+ Prot = NULL;
+
+ //
+ // Lookup the protocol entry for this protocol ID
+ //
+
+ ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
+ if (ProtEntry != NULL) {
+
+ //
+ // Look at each protocol interface for any matches
+ //
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) {
+
+ //
+ // If this protocol interface matches, remove it
+ //
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) {
+ break;
+ }
+
+ Prot = NULL;
+ }
+ }
+
+ return Prot;
+}
+
+STATIC
+EFI_STATUS
+CoreUnregisterProtocolNotifyEvent (
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ Removes an event from a register protocol notify list on a protocol.
+
+Arguments:
+
+ Event - The event to search for in the protocol database.
+
+Returns:
+
+ EFI_SUCCESS if the event was found and removed.
+ EFI_NOT_FOUND if the event was not found in the protocl database.
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ PROTOCOL_ENTRY *ProtEntry;
+ EFI_LIST_ENTRY *NotifyLink;
+ PROTOCOL_NOTIFY *ProtNotify;
+
+ CoreAcquireProtocolLock ();
+
+ for ( Link = mProtocolDatabase.ForwardLink;
+ Link != &mProtocolDatabase;
+ Link = Link->ForwardLink) {
+
+ ProtEntry = CR(Link, PROTOCOL_ENTRY, AllEntries, PROTOCOL_ENTRY_SIGNATURE);
+
+ for ( NotifyLink = ProtEntry->Notify.ForwardLink;
+ NotifyLink != &ProtEntry->Notify;
+ NotifyLink = NotifyLink->ForwardLink) {
+
+ ProtNotify = CR(NotifyLink, PROTOCOL_NOTIFY, Link, PROTOCOL_NOTIFY_SIGNATURE);
+
+ if (ProtNotify->Event == Event) {
+ RemoveEntryList(&ProtNotify->Link);
+ CoreFreePool(ProtNotify);
+ CoreReleaseProtocolLock ();
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ CoreReleaseProtocolLock ();
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+CoreUnregisterProtocolNotify (
+ IN EFI_EVENT Event
+ )
+/*++
+
+Routine Description:
+
+ Removes all the events in the protocol database that match Event.
+
+Arguments:
+
+ Event - The event to search for in the protocol database.
+
+Returns:
+
+ EFI_SUCCESS when done searching the entire database.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ do {
+ Status = CoreUnregisterProtocolNotifyEvent (Event);
+ } while (!EFI_ERROR (Status));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreInstallProtocolInterface (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Wrapper function to CoreInstallProtocolInterfaceNotify. This is the public API which
+ Calls the private one which contains a BOOLEAN parameter for notifications
+
+Arguments:
+
+ UserHandle - The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+
+ Protocol - The protocol to add to the handle
+
+ InterfaceType - Indicates whether Interface is supplied in native form.
+
+ Interface - The interface for the protocol being added
+
+Returns:
+
+ Status code
+
+--*/
+{
+ return CoreInstallProtocolInterfaceNotify (
+ UserHandle,
+ Protocol,
+ InterfaceType,
+ Interface,
+ TRUE
+ );
+}
+
+EFI_STATUS
+CoreInstallProtocolInterfaceNotify (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface,
+ IN BOOLEAN Notify
+ )
+/*++
+
+Routine Description:
+
+ Installs a protocol interface into the boot services environment.
+
+Arguments:
+
+ UserHandle - The handle to install the protocol handler on,
+ or NULL if a new handle is to be allocated
+
+ Protocol - The protocol to add to the handle
+
+ InterfaceType - Indicates whether Interface is supplied in native form.
+
+ Interface - The interface for the protocol being added
+
+ Notify - indicates whether notify the notification list
+ for this protocol
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+
+ EFI_SUCCESS - Protocol interface successfully installed
+
+--*/
+{
+ PROTOCOL_INTERFACE *Prot;
+ PROTOCOL_ENTRY *ProtEntry;
+ IHANDLE *Handle;
+ EFI_STATUS Status;
+ VOID *ExistingInterface;
+
+ //
+ // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
+ // Also added check for invalid UserHandle and Protocol pointers.
+ //
+ if (UserHandle == NULL || Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (InterfaceType != EFI_NATIVE_INTERFACE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Print debug message
+ //
+//*** AMI PORTING BEGIN ***//
+//Disable Protocol debug message
+// DEBUG((EFI_D_ERROR | EFI_D_INFO, "InstallProtocolInterface: %g %x\n", Protocol, Interface));
+//*** AMI PORTING END *****//
+
+ Status = EFI_OUT_OF_RESOURCES;
+ Prot = NULL;
+ Handle = NULL;
+
+ ASSERT (NULL != gBS);
+
+ if (*UserHandle != NULL_HANDLE) {
+ Status = CoreHandleProtocol (*UserHandle, Protocol, (VOID **)&ExistingInterface);
+ if (!EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Lookup the Protocol Entry for the requested protocol
+ //
+ ProtEntry = CoreFindProtocolEntry (Protocol, TRUE);
+ if (ProtEntry == NULL) {
+ goto Done;
+ }
+
+ //
+ // Allocate a new protocol interface structure
+ //
+ Prot = CoreAllocateZeroBootServicesPool (sizeof(PROTOCOL_INTERFACE));
+ if (Prot == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // If caller didn't supply a handle, allocate a new one
+ //
+ Handle = (IHANDLE *)*UserHandle;
+ if (Handle == NULL) {
+ Handle = CoreAllocateZeroBootServicesPool (sizeof(IHANDLE));
+ if (Handle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Initialize new handler structure
+ //
+ Handle->Signature = EFI_HANDLE_SIGNATURE;
+ InitializeListHead (&Handle->Protocols);
+
+ //
+ // Initialize the Key to show that the handle has been created/modified
+ //
+ gHandleDatabaseKey++;
+ Handle->Key = gHandleDatabaseKey;
+
+ //
+ // Add this handle to the list global list of all handles
+ // in the system
+ //
+ InsertTailList (&gHandleList, &Handle->AllHandles);
+ }
+
+ Status = CoreValidateHandle (Handle);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Each interface that is added must be unique
+ //
+ ASSERT (CoreFindProtocolInterface (Handle, Protocol, Interface) == NULL);
+
+ //
+ // Initialize the protocol interface structure
+ //
+ Prot->Signature = PROTOCOL_INTERFACE_SIGNATURE;
+ Prot->Handle = Handle;
+ Prot->Protocol = ProtEntry;
+ Prot->Interface = Interface;
+
+ //
+ // Initalize OpenProtocol Data base
+ //
+ InitializeListHead (&Prot->OpenList);
+ Prot->OpenListCount = 0;
+
+ //
+ // Add this protocol interface to the head of the supported
+ // protocol list for this handle
+ //
+ InsertHeadList (&Handle->Protocols, &Prot->Link);
+
+ //
+ // Add this protocol interface to the tail of the
+ // protocol entry
+ //
+ InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
+
+ //
+ // Notify the notification list for this protocol
+ //
+ if (Notify) {
+ CoreNotifyProtocolEntry (ProtEntry);
+ }
+ Status = EFI_SUCCESS;
+
+Done:
+ //
+ // Done, unlock the database and return
+ //
+ CoreReleaseProtocolLock ();
+ if (!EFI_ERROR (Status)) {
+ //
+ // Return the new handle back to the caller
+ //
+ *UserHandle = Handle;
+ } else {
+ //
+ // There was an error, clean up
+ //
+ if (Prot != NULL) {
+ CoreFreePool (Prot);
+ }
+ }
+
+ return Status;
+}
+
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreInstallMultipleProtocolInterfaces (
+ IN OUT EFI_HANDLE *Handle,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Installs a list of protocol interface into the boot services environment.
+ This function calls InstallProtocolInterface() in a loop. If any error
+ occures all the protocols added by this function are removed. This is
+ basically a lib function to save space.
+
+Arguments:
+
+ Handle - The handle to install the protocol handlers on,
+ or NULL if a new handle is to be allocated
+ ... - EFI_GUID followed by protocol instance. A NULL terminates the
+ list. The pairs are the arguments to InstallProtocolInterface().
+ All the protocols are added to Handle.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Handle is NULL.
+
+ EFI_SUCCESS - Protocol interfaces successfully installed.
+
+--*/
+{
+ VA_LIST args;
+ EFI_STATUS Status;
+ EFI_GUID *Protocol;
+ VOID *Interface;
+ EFI_TPL OldTpl;
+ UINTN Index;
+ EFI_HANDLE OldHandle;
+ EFI_HANDLE DeviceHandle;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Syncronize with notifcations.
+ //
+ OldTpl = CoreRaiseTpl (EFI_TPL_NOTIFY);
+ OldHandle = *Handle;
+
+ //
+ // Check for duplicate device path and install the protocol interfaces
+ //
+ VA_START (args, Handle);
+ for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
+ //
+ // If protocol is NULL, then it's the end of the list
+ //
+ Protocol = VA_ARG (args, EFI_GUID *);
+ if (Protocol == NULL) {
+ break;
+ }
+
+ Interface = VA_ARG (args, VOID *);
+
+ //
+ // Make sure you are installing on top a device path that has already been added.
+ //
+ if (EfiCompareGuid (Protocol, &gEfiDevicePathProtocolGuid)) {
+ DeviceHandle = NULL;
+ DevicePath = Interface;
+ Status = CoreLocateDevicePath (&gEfiDevicePathProtocolGuid, &DevicePath, &DeviceHandle);
+ if (!EFI_ERROR (Status) && (DeviceHandle != NULL_HANDLE) && IsDevicePathEnd(DevicePath)) {
+ Status = EFI_ALREADY_STARTED;
+ continue;
+ }
+ }
+
+ //
+ // Install it
+ //
+ Status = CoreInstallProtocolInterface (Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
+ }
+
+ //
+ // If there was an error, remove all the interfaces that were installed without any errors
+ //
+ if (EFI_ERROR (Status)) {
+ //
+ // Reset the va_arg back to the first argument.
+ //
+ VA_START (args, Handle);
+ for (; Index > 1; Index--) {
+ Protocol = VA_ARG (args, EFI_GUID *);
+ Interface = VA_ARG (args, VOID *);
+ CoreUninstallProtocolInterface (*Handle, Protocol, Interface);
+ }
+ *Handle = OldHandle;
+ }
+
+ //
+ // Done
+ //
+ CoreRestoreTpl (OldTpl);
+ return Status;
+}
+
+EFI_STATUS
+CoreDisconnectControllersUsingProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN PROTOCOL_INTERFACE *Prot
+ )
+/*++
+
+Routine Description:
+
+ Attempts to disconnect all drivers that are using the protocol interface being queried.
+ If failed, reconnect all drivers disconnected.
+
+ Note: This function doesn't do parameters checking, it's caller's responsibility
+ to pass in valid parameters.
+
+Arguments:
+
+ UserHandle - The handle on which the protocol is installed
+ Prot - The protocol to disconnect drivers from
+
+Returns:
+
+ EFI_SUCCESS - Drivers using the protocol interface are all disconnected
+ EFI_ACCESS_DENIED - Failed to disconnect one or all of the drivers
+
+--*/
+{
+ EFI_STATUS Status;
+ BOOLEAN ItemFound;
+ EFI_LIST_ENTRY *Link;
+ OPEN_PROTOCOL_DATA *OpenData;
+
+ Status = EFI_SUCCESS;
+
+ //
+ // Attempt to disconnect all drivers from this protocol interface
+ //
+ do {
+ ItemFound = FALSE;
+ for ( Link = Prot->OpenList.ForwardLink;
+ (Link != &Prot->OpenList) && !ItemFound;
+ Link = Link->ForwardLink ) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ ItemFound = TRUE;
+ CoreReleaseProtocolLock ();
+ Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
+ CoreAcquireProtocolLock ();
+ if (EFI_ERROR (Status)) {
+ ItemFound = FALSE;
+ break;
+ }
+ }
+ }
+ } while (ItemFound);
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Attempt to remove BY_HANDLE_PROTOOCL and GET_PROTOCOL and TEST_PROTOCOL Open List items
+ //
+ do {
+ ItemFound = FALSE;
+ for ( Link = Prot->OpenList.ForwardLink;
+ (Link != &Prot->OpenList) && !ItemFound;
+ Link = Link->ForwardLink ) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if (OpenData->Attributes &
+ (EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL | EFI_OPEN_PROTOCOL_GET_PROTOCOL | EFI_OPEN_PROTOCOL_TEST_PROTOCOL)) {
+ ItemFound = TRUE;
+ RemoveEntryList (&OpenData->Link);
+ Prot->OpenListCount--;
+ CoreFreePool (OpenData);
+ }
+ }
+ } while (ItemFound);
+ }
+
+ //
+ // If there are errors or still has open items in the list, then reconnect all the drivers and return an error
+ //
+ if (EFI_ERROR (Status) || (Prot->OpenListCount > 0)) {
+ CoreReleaseProtocolLock ();
+ CoreConnectController (UserHandle, NULL, NULL, TRUE);
+ CoreAcquireProtocolLock ();
+ Status = EFI_ACCESS_DENIED;
+ }
+
+ return Status;
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreUninstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+/*++
+
+Routine Description:
+
+ Uninstalls all instances of a protocol:interfacer from a handle.
+ If the last protocol interface is remove from the handle, the
+ handle is freed.
+
+Arguments:
+
+ UserHandle - The handle to remove the protocol handler from
+
+ Protocol - The protocol, of protocol:interface, to remove
+
+ Interface - The interface, of protocol:interface, to remove
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Protocol is NULL.
+
+ EFI_SUCCESS - Protocol interface successfully uninstalled.
+
+--*/
+{
+ EFI_STATUS Status;
+ IHANDLE *Handle;
+ PROTOCOL_INTERFACE *Prot;
+
+ //
+ // Check that Protocol is valid
+ //
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check that UserHandle is a valid handle
+ //
+ Status = CoreValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
+ //
+ Prot = CoreFindProtocolInterface (UserHandle, Protocol, Interface);
+ if (Prot == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+
+ //
+ // Attempt to disconnect all drivers that are using the protocol interface that is about to be removed
+ //
+ Status = CoreDisconnectControllersUsingProtocolInterface (
+ UserHandle,
+ Prot
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // One or more drivers refused to release, so return the error
+ //
+ goto Done;
+ }
+
+ //
+ // Remove the protocol interface from the protocol
+ //
+ Status = EFI_NOT_FOUND;
+ Handle = (IHANDLE *)UserHandle;
+ Prot = CoreRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
+
+ if (Prot != NULL) {
+ //
+ // Update the Key to show that the handle has been created/modified
+ //
+ gHandleDatabaseKey++;
+ Handle->Key = gHandleDatabaseKey;
+
+ //
+ // Remove the protocol interface from the handle
+ //
+ RemoveEntryList (&Prot->Link);
+
+ //
+ // Free the memory
+ //
+ Prot->Signature = 0;
+ CoreFreePool (Prot);
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // If there are no more handlers for the handle, free the handle
+ //
+ if (IsListEmpty (&Handle->Protocols)) {
+ Handle->Signature = 0;
+ RemoveEntryList (&Handle->AllHandles);
+ CoreFreePool (Handle);
+ }
+
+Done:
+ //
+ // Done, unlock the database and return
+ //
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreUninstallMultipleProtocolInterfaces (
+ IN EFI_HANDLE Handle,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Uninstalls a list of protocol interface in the boot services environment.
+ This function calls UnisatllProtocolInterface() in a loop. This is
+ basically a lib function to save space.
+
+Arguments:
+
+ Handle - The handle to uninstall the protocol
+
+ ... - EFI_GUID followed by protocol instance. A NULL terminates the
+ list. The pairs are the arguments to UninstallProtocolInterface().
+ All the protocols are added to Handle.
+
+Returns:
+
+ Status code
+
+--*/
+{
+ EFI_STATUS Status;
+ VA_LIST args;
+ EFI_GUID *Protocol;
+ VOID *Interface;
+ UINTN Index;
+
+ VA_START (args, Handle);
+ for (Index = 0, Status = EFI_SUCCESS; !EFI_ERROR (Status); Index++) {
+ //
+ // If protocol is NULL, then it's the end of the list
+ //
+ Protocol = VA_ARG (args, EFI_GUID *);
+ if (Protocol == NULL) {
+ break;
+ }
+
+ Interface = VA_ARG (args, VOID *);
+
+ //
+ // Uninstall it
+ //
+ Status = CoreUninstallProtocolInterface (Handle, Protocol, Interface);
+ }
+
+ //
+ // If there was an error, add all the interfaces that were
+ // uninstalled without any errors
+ //
+ if (EFI_ERROR (Status)) {
+ //
+ // Reset the va_arg back to the first argument.
+ //
+ VA_START (args, Handle);
+ for (; Index > 1; Index--) {
+ Protocol = VA_ARG(args, EFI_GUID *);
+ Interface = VA_ARG(args, VOID *);
+ CoreInstallProtocolInterface (&Handle, Protocol, EFI_NATIVE_INTERFACE, Interface);
+ }
+ }
+
+ return Status;
+}
+
+PROTOCOL_INTERFACE *
+CoreGetProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol
+ )
+/*++
+
+Routine Description:
+
+ Locate a certain GUID protocol interface in a Handle's protocols.
+
+Arguments:
+
+ UserHandle - The handle to obtain the protocol interface on
+
+ Protocol - The GUID of the protocol
+
+Returns:
+
+ The requested protocol interface for the handle
+
+--*/
+{
+ EFI_STATUS Status;
+ PROTOCOL_ENTRY *ProtEntry;
+ PROTOCOL_INTERFACE *Prot;
+ IHANDLE *Handle;
+ EFI_LIST_ENTRY *Link;
+
+ Status = CoreValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Handle = (IHANDLE *)UserHandle;
+
+ //
+ // Look at each protocol interface for a match
+ //
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ ProtEntry = Prot->Protocol;
+ if (EfiCompareGuid (&ProtEntry->ProtocolID, Protocol)) {
+ return Prot;
+ }
+ }
+ return NULL;
+}
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreHandleProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Queries a handle to determine if it supports a specified protocol.
+
+Arguments:
+
+ UserHandle - The handle being queried.
+
+ Protocol - The published unique identifier of the protocol.
+
+ Interface - Supplies the address where a pointer to the corresponding Protocol
+ Interface is returned.
+
+Returns:
+
+ The requested protocol interface for the handle
+
+--*/
+{
+ return CoreOpenProtocol (
+ UserHandle,
+ Protocol,
+ Interface,
+ gDxeCoreImageHandle,
+ NULL,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL
+ );
+}
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreOpenProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface OPTIONAL,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINT32 Attributes
+ )
+/*++
+
+Routine Description:
+
+ Locates the installed protocol handler for the handle, and
+ invokes it to obtain the protocol interface. Usage information
+ is registered in the protocol data base.
+
+Arguments:
+
+ UserHandle - The handle to obtain the protocol interface on
+
+ Protocol - The ID of the protocol
+
+ Interface - The location to return the protocol interface
+
+ ImageHandle - The handle of the Image that is opening the protocol interface
+ specified by Protocol and Interface.
+
+ ControllerHandle - The controller handle that is requiring this interface.
+
+ Attributes - The open mode of the protocol interface specified by Handle
+ and Protocol.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Protocol is NULL.
+
+ EFI_SUCCESS - Get the protocol interface.
+
+--*/
+{
+ EFI_STATUS Status;
+ PROTOCOL_INTERFACE *Prot;
+ EFI_LIST_ENTRY *Link;
+ OPEN_PROTOCOL_DATA *OpenData;
+ BOOLEAN ByDriver;
+ BOOLEAN Exclusive;
+ BOOLEAN Disconnect;
+ BOOLEAN ExactMatch;
+
+ //
+ // Check for invalid Protocol
+ //
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for invalid Interface
+ //
+ if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
+ if (Interface == NULL) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ *Interface = NULL;
+ }
+ }
+
+ //
+ // Check for invalid UserHandle
+ //
+ Status = CoreValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check for invalid Attributes
+ //
+ switch (Attributes) {
+ case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :
+ Status = CoreValidateHandle (ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = CoreValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (UserHandle == ControllerHandle) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_DRIVER :
+ case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ Status = CoreValidateHandle (ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = CoreValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ Status = CoreValidateHandle (ImageHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_GET_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Look at each protocol interface for a match
+ //
+ Prot = CoreGetProtocolInterface (UserHandle, Protocol);
+ if (Prot == NULL) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ //
+ // This is the protocol interface entry for this protocol
+ //
+ if (Attributes != EFI_OPEN_PROTOCOL_TEST_PROTOCOL) {
+ *Interface = Prot->Interface;
+ }
+ Status = EFI_SUCCESS;
+
+ ByDriver = FALSE;
+ Exclusive = FALSE;
+ for ( Link = Prot->OpenList.ForwardLink; Link != &Prot->OpenList; Link = Link->ForwardLink) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ ExactMatch = (BOOLEAN)((OpenData->AgentHandle == ImageHandle) &&
+ (OpenData->Attributes == Attributes) &&
+ (OpenData->ControllerHandle == ControllerHandle));
+ if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ ByDriver = TRUE;
+ if (ExactMatch) {
+ Status = EFI_ALREADY_STARTED;
+ goto Done;
+ }
+ }
+ if (OpenData->Attributes & EFI_OPEN_PROTOCOL_EXCLUSIVE) {
+ Exclusive = TRUE;
+ } else if (ExactMatch) {
+ OpenData->OpenCount++;
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+ }
+
+ //
+ // ByDriver TRUE -> A driver is managing (UserHandle, Protocol)
+ // ByDriver FALSE -> There are no drivers managing (UserHandle, Protocol)
+ // Exclusive TRUE -> Something has exclusive access to (UserHandle, Protocol)
+ // Exclusive FALSE -> Nothing has exclusive access to (UserHandle, Protocol)
+ //
+
+ switch (Attributes) {
+ case EFI_OPEN_PROTOCOL_BY_DRIVER :
+ if (Exclusive || ByDriver) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_DRIVER | EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ case EFI_OPEN_PROTOCOL_EXCLUSIVE :
+ if (Exclusive) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ if (ByDriver) {
+ do {
+ Disconnect = FALSE;
+ for ( Link = Prot->OpenList.ForwardLink; (Link != &Prot->OpenList) && (!Disconnect); Link = Link->ForwardLink) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ if (OpenData->Attributes & EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ Disconnect = TRUE;
+ CoreReleaseProtocolLock ();
+ Status = CoreDisconnectController (UserHandle, OpenData->AgentHandle, NULL);
+ CoreAcquireProtocolLock ();
+ if (EFI_ERROR (Status)) {
+ Status = EFI_ACCESS_DENIED;
+ goto Done;
+ }
+ }
+ }
+ } while (Disconnect);
+ }
+ break;
+ case EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER :
+ case EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_GET_PROTOCOL :
+ case EFI_OPEN_PROTOCOL_TEST_PROTOCOL :
+ break;
+ }
+
+ if (ImageHandle == NULL) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+ //
+ // Create new entry
+ //
+ OpenData = CoreAllocateBootServicesPool (sizeof(OPEN_PROTOCOL_DATA));
+ if (OpenData == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ } else {
+ OpenData->Signature = OPEN_PROTOCOL_DATA_SIGNATURE;
+ OpenData->AgentHandle = ImageHandle;
+ OpenData->ControllerHandle = ControllerHandle;
+ OpenData->Attributes = Attributes;
+ OpenData->OpenCount = 1;
+ InsertTailList (&Prot->OpenList, &OpenData->Link);
+ Prot->OpenListCount++;
+ Status = EFI_SUCCESS;
+ }
+
+Done:
+ //
+ // Done. Release the database lock are return
+ //
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreCloseProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_HANDLE AgentHandle,
+ IN EFI_HANDLE ControllerHandle
+ )
+/*++
+
+Routine Description:
+
+ Closes a protocol on a handle that was opened using OpenProtocol().
+
+Arguments:
+
+ UserHandle - The handle for the protocol interface that was previously opened
+ with OpenProtocol(), and is now being closed.
+ Protocol - The published unique identifier of the protocol. It is the caller's
+ responsibility to pass in a valid GUID.
+ AgentHandle - The handle of the agent that is closing the protocol interface.
+ ControllerHandle - If the agent that opened a protocol is a driver that follows the
+ EFI Driver Model, then this parameter is the controller handle
+ that required the protocol interface. If the agent does not follow
+ the EFI Driver Model, then this parameter is optional and may be NULL.
+
+Returns:
+
+ EFI_SUCCESS - The protocol instance was closed.
+ EFI_INVALID_PARAMETER - Handle, AgentHandle or ControllerHandle is not a valid EFI_HANDLE.
+ EFI_NOT_FOUND - Can not find the specified protocol or AgentHandle.
+
+--*/
+{
+ EFI_STATUS Status;
+ PROTOCOL_INTERFACE *ProtocolInterface;
+ EFI_LIST_ENTRY *Link;
+ OPEN_PROTOCOL_DATA *OpenData;
+
+ //
+ // Check for invalid parameters
+ //
+ Status = CoreValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ Status = CoreValidateHandle (AgentHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ if (ControllerHandle != NULL_HANDLE) {
+ Status = CoreValidateHandle (ControllerHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Look at each protocol interface for a match
+ //
+ Status = EFI_NOT_FOUND;
+ ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol);
+ if (ProtocolInterface == NULL) {
+ goto Done;
+ }
+
+ //
+ // Walk the Open data base looking for AgentHandle
+ //
+ Link = ProtocolInterface->OpenList.ForwardLink;
+ while (Link != &ProtocolInterface->OpenList) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+ Link = Link->ForwardLink;
+ if ((OpenData->AgentHandle == AgentHandle) && (OpenData->ControllerHandle == ControllerHandle)) {
+ RemoveEntryList (&OpenData->Link);
+ ProtocolInterface->OpenListCount--;
+ CoreFreePool (OpenData);
+ Status = EFI_SUCCESS;
+ }
+ }
+
+Done:
+ //
+ // Done. Release the database lock and return.
+ //
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreOpenProtocolInformation (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT EFI_OPEN_PROTOCOL_INFORMATION_ENTRY **EntryBuffer,
+ OUT UINTN *EntryCount
+ )
+/*++
+
+Routine Description:
+
+ Return information about Opened protocols in the system
+
+Arguments:
+
+ UserHandle - The handle to close the protocol interface on
+
+ Protocol - The ID of the protocol
+
+ EntryBuffer - A pointer to a buffer of open protocol information in the form of
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY structures.
+
+ EntryCount - Number of EntryBuffer entries
+
+Returns:
+
+
+--*/
+{
+ EFI_STATUS Status;
+ PROTOCOL_INTERFACE *ProtocolInterface;
+ EFI_LIST_ENTRY *Link;
+ OPEN_PROTOCOL_DATA *OpenData;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Buffer;
+ UINTN Count;
+ UINTN Size;
+
+ *EntryBuffer = NULL;
+ *EntryCount = 0;
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ //
+ // Look at each protocol interface for a match
+ //
+ Status = EFI_NOT_FOUND;
+ ProtocolInterface = CoreGetProtocolInterface (UserHandle, Protocol);
+ if (ProtocolInterface == NULL) {
+ goto Done;
+ }
+
+ //
+ // Count the number of Open Entries
+ //
+ for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0;
+ (Link != &ProtocolInterface->OpenList) ;
+ Link = Link->ForwardLink ) {
+ Count++;
+ }
+
+ ASSERT (Count == ProtocolInterface->OpenListCount);
+
+ if (Count == 0) {
+ Size = sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);
+ } else {
+ Size = Count * sizeof(EFI_OPEN_PROTOCOL_INFORMATION_ENTRY);
+ }
+
+ Buffer = CoreAllocateBootServicesPool (Size);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ Status = EFI_SUCCESS;
+ for ( Link = ProtocolInterface->OpenList.ForwardLink, Count = 0;
+ (Link != &ProtocolInterface->OpenList);
+ Link = Link->ForwardLink, Count++ ) {
+ OpenData = CR (Link, OPEN_PROTOCOL_DATA, Link, OPEN_PROTOCOL_DATA_SIGNATURE);
+
+ Buffer[Count].AgentHandle = OpenData->AgentHandle;
+ Buffer[Count].ControllerHandle = OpenData->ControllerHandle;
+ Buffer[Count].Attributes = OpenData->Attributes;
+ Buffer[Count].OpenCount = OpenData->OpenCount;
+ }
+
+ *EntryBuffer = Buffer;
+ *EntryCount = Count;
+
+Done:
+ //
+ // Done. Release the database lock are return
+ //
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreProtocolsPerHandle (
+ IN EFI_HANDLE UserHandle,
+ OUT EFI_GUID ***ProtocolBuffer,
+ OUT UINTN *ProtocolBufferCount
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the list of protocol interface GUIDs that are installed on a handle in a buffer allocated
+ from pool.
+
+Arguments:
+
+ UserHandle - The handle from which to retrieve the list of protocol interface
+ GUIDs.
+
+ ProtocolBuffer - A pointer to the list of protocol interface GUID pointers that are
+ installed on Handle.
+
+ ProtocolBufferCount - A pointer to the number of GUID pointers present in
+ ProtocolBuffer.
+
+Returns:
+ EFI_SUCCESS - The list of protocol interface GUIDs installed on Handle was returned in
+ ProtocolBuffer. The number of protocol interface GUIDs was
+ returned in ProtocolBufferCount.
+ EFI_INVALID_PARAMETER - Handle is NULL.
+ EFI_INVALID_PARAMETER - Handle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ProtocolBuffer is NULL.
+ EFI_INVALID_PARAMETER - ProtocolBufferCount is NULL.
+ EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the results.
+
+--*/
+{
+ EFI_STATUS Status;
+ IHANDLE *Handle;
+ PROTOCOL_INTERFACE *Prot;
+ EFI_LIST_ENTRY *Link;
+ UINTN ProtocolCount;
+ EFI_GUID **Buffer;
+
+ Status = CoreValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Handle = (IHANDLE *)UserHandle;
+
+ if (ProtocolBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ProtocolBufferCount == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ProtocolBufferCount = 0;
+
+ ProtocolCount = 0;
+
+ CoreAcquireProtocolLock ();
+
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ ProtocolCount++;
+ }
+
+ //
+ // If there are no protocol interfaces installed on Handle, then Handle is not a valid EFI_HANDLE
+ //
+ if (ProtocolCount == 0) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ Buffer = CoreAllocateBootServicesPool (sizeof (EFI_GUID *) * ProtocolCount);
+ if (Buffer == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ *ProtocolBuffer = Buffer;
+ *ProtocolBufferCount = ProtocolCount;
+
+ for ( Link = Handle->Protocols.ForwardLink, ProtocolCount = 0;
+ Link != &Handle->Protocols;
+ Link = Link->ForwardLink, ProtocolCount++) {
+ Prot = CR(Link, PROTOCOL_INTERFACE, Link, PROTOCOL_INTERFACE_SIGNATURE);
+ Buffer[ProtocolCount] = &(Prot->Protocol->ProtocolID);
+ }
+ Status = EFI_SUCCESS;
+
+Done:
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+
+UINT64
+CoreGetHandleDatabaseKey (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ return handle database key.
+
+Arguments:
+
+ None
+
+Returns:
+
+ Handle database key.
+
+--*/
+{
+ return gHandleDatabaseKey;
+}
+
+
+VOID
+CoreConnectHandlesByKey (
+ UINT64 Key
+ )
+/*++
+
+Routine Description:
+
+ Go connect any handles that were created or modified while a image executed.
+
+Arguments:
+
+ Key - The Key to show that the handle has been created/modified
+
+Returns:
+
+ None
+--*/
+{
+ UINTN Count;
+ EFI_LIST_ENTRY *Link;
+ EFI_HANDLE *HandleBuffer;
+ IHANDLE *Handle;
+ UINTN Index;
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) {
+ Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
+ if (Handle->Key > Key) {
+ Count++;
+ }
+ }
+
+ HandleBuffer = CoreAllocateBootServicesPool (Count * sizeof (EFI_HANDLE));
+ if (HandleBuffer == NULL) {
+ CoreReleaseProtocolLock ();
+ return;
+ }
+
+ for (Link = gHandleList.ForwardLink, Count = 0; Link != &gHandleList; Link = Link->ForwardLink) {
+ Handle = CR (Link, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
+ if (Handle->Key > Key) {
+ HandleBuffer[Count++] = Handle;
+ }
+ }
+
+ //
+ // Unlock the protocol database
+ //
+ CoreReleaseProtocolLock ();
+
+ //
+ // Connect all handles whose Key value is greater than Key
+ //
+ for (Index = 0; Index < Count; Index++) {
+ CoreConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
+ }
+
+ CoreFreePool(HandleBuffer);
+}
diff --git a/Core/CORE_DXE/hob.c b/Core/CORE_DXE/hob.c
new file mode 100644
index 0000000..7c96c69
--- /dev/null
+++ b/Core/CORE_DXE/hob.c
@@ -0,0 +1,530 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ hob.c
+
+Abstract:
+
+ Support for hob operation
+
+--*/
+
+#include "Tiano.h"
+#include "EfiCommonLib.h"
+//#include "EfiDriverLib.h"
+#include "PeiHob.h"
+//#include EFI_GUID_DEFINITION (IoBaseHob)
+//#include EFI_GUID_DEFINITION (MemoryAllocationHob)
+
+VOID *
+GetHob (
+ IN UINT16 Type,
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ This function returns the first instance of a HOB type in a HOB list.
+
+Arguments:
+
+ Type The HOB type to return.
+ HobStart The first HOB in the HOB list.
+
+Returns:
+
+ HobStart There were no HOBs found with the requested type.
+ else Returns the first HOB with the matching type.
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = HobStart;
+ //
+ // Return input if not found
+ //
+ if (HobStart == NULL) {
+ return HobStart;
+ }
+
+ //
+ // Parse the HOB list, stop if end of list or matching type found.
+ //
+ while (!END_OF_HOB_LIST (Hob)) {
+
+ if (Hob.Header->HobType == Type) {
+ break;
+ }
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+
+ //
+ // Return input if not found
+ //
+ if (END_OF_HOB_LIST (Hob)) {
+ return HobStart;
+ }
+
+ return (VOID *) (Hob.Raw);
+}
+
+UINTN
+GetHobListSize (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Get size of hob list.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+Returns:
+
+ Size of hob list.
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN Size;
+
+ Hob.Raw = HobStart;
+ Size = 0;
+
+ while (Hob.Header->HobType != EFI_HOB_TYPE_END_OF_HOB_LIST) {
+ Size += Hob.Header->HobLength;
+ Hob.Raw += Hob.Header->HobLength;
+ }
+
+ Size += Hob.Header->HobLength;
+
+ return Size;
+}
+
+UINT32
+GetHobVersion (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Get hob version.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+Returns:
+
+ Hob version.
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = HobStart;
+ return Hob.HandoffInformationTable->Version;
+}
+
+EFI_STATUS
+GetHobBootMode (
+ IN VOID *HobStart,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ Get current boot mode.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BootMode - Current boot mode recorded in PHIT hob
+
+Returns:
+
+ EFI_NOT_FOUND - Invalid hob header
+
+ EFI_SUCCESS - Boot mode found
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = HobStart;
+ if (Hob.Header->HobType != EFI_HOB_TYPE_HANDOFF) {
+ return EFI_NOT_FOUND;
+ }
+
+ *BootMode = Hob.HandoffInformationTable->BootMode;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetCpuHobInfo (
+ IN VOID *HobStart,
+ OUT UINT8 *SizeOfMemorySpace,
+ OUT UINT8 *SizeOfIoSpace
+ )
+/*++
+
+Routine Description:
+
+ Get information recorded in CPU hob (Memory space size, Io space size)
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ SizeOfMemorySpace - Size of memory size
+
+ SizeOfIoSpace - Size of IO size
+
+Returns:
+
+ EFI_NOT_FOUND - CPU hob not found
+
+ EFI_SUCCESS - CPU hob found and information got.
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS CpuHob;
+
+ CpuHob.Raw = HobStart;
+ CpuHob.Raw = GetHob (EFI_HOB_TYPE_CPU, CpuHob.Raw);
+ if (CpuHob.Header->HobType != EFI_HOB_TYPE_CPU) {
+ return EFI_NOT_FOUND;
+ }
+
+ *SizeOfMemorySpace = CpuHob.Cpu->SizeOfMemorySpace;
+ *SizeOfIoSpace = CpuHob.Cpu->SizeOfIoSpace;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetDxeCoreHobInfo (
+ IN VOID *HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length,
+ OUT VOID **EntryPoint,
+ OUT EFI_GUID **FileName
+ )
+/*++
+
+Routine Description:
+
+ Get memory allocation hob created for DXE core and extract its information
+
+Arguments:
+
+ HobStart - Start pointer of the hob list
+
+ BaseAddress - Start address of memory allocated for DXE core
+
+ Length - Length of memory allocated for DXE core
+
+ EntryPoint - DXE core file name
+
+Returns:
+
+ EFI_NOT_FOUND - DxeCoreHob not found
+
+ EFI_SUCCESS - DxeCoreHob found and information got
+
+ FileName - FileName
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS DxeCoreHob;
+#define EFI_HOB_MEMORY_ALLOC_MODULE_GUID \
+ {0xf8e21975, 0x899, 0x4f58, 0xa4, 0xbe, 0x55, 0x25, 0xa9, 0xc6,0xd7, 0x7a}
+ static EFI_GUID gEfiHobMemeryAllocModuleGuid=EFI_HOB_MEMORY_ALLOC_MODULE_GUID;
+ DxeCoreHob.Raw = HobStart;
+ DxeCoreHob.Raw = GetHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw);
+ while(!END_OF_HOB_LIST(DxeCoreHob) &&
+ !EfiCompareGuid (&DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.Name, &gEfiHobMemeryAllocModuleGuid)) {
+
+ DxeCoreHob.Raw = GET_NEXT_HOB (DxeCoreHob);
+ DxeCoreHob.Raw = GetHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, DxeCoreHob.Raw);
+
+ }
+
+ if (END_OF_HOB_LIST (DxeCoreHob)) {
+ return EFI_NOT_FOUND;
+ }
+
+ *BaseAddress = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryBaseAddress;
+ *Length = DxeCoreHob.MemoryAllocationModule->MemoryAllocationHeader.MemoryLength;
+ *EntryPoint = (VOID *) (UINTN) DxeCoreHob.MemoryAllocationModule->EntryPoint;
+ *FileName = &DxeCoreHob.MemoryAllocationModule->ModuleName;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetNextFirmwareVolumeHob (
+ IN OUT VOID **HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length
+ )
+/*++
+
+Routine Description:
+
+ Get next firmware volume hob from HobStart
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - Start address of next firmware volume
+
+ Length - Length of next firmware volume
+
+Returns:
+
+ EFI_NOT_FOUND - Next firmware volume not found
+
+ EFI_SUCCESS - Next firmware volume found with address information
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS FirmwareVolumeHob;
+
+ FirmwareVolumeHob.Raw = *HobStart;
+ if (END_OF_HOB_LIST (FirmwareVolumeHob)) {
+ return EFI_NOT_FOUND;
+ }
+
+ FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV, *HobStart);
+ if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV) {
+ return EFI_NOT_FOUND;
+ }
+
+ *BaseAddress = FirmwareVolumeHob.FirmwareVolume->BaseAddress;
+ *Length = FirmwareVolumeHob.FirmwareVolume->Length;
+
+ *HobStart = GET_NEXT_HOB (FirmwareVolumeHob);
+
+ return EFI_SUCCESS;
+}
+
+//PI 1.1 ++
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+EFI_STATUS
+GetNextFirmwareVolume2Hob (
+ IN OUT VOID **HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length,
+ OUT EFI_GUID *FileName
+ )
+/*++
+
+Routine Description:
+
+ Get next firmware volume2 hob from HobStart
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - Start address of next firmware volume
+
+ Length - Length of next firmware volume
+
+Returns:
+
+ EFI_NOT_FOUND - Next firmware volume not found
+
+ EFI_SUCCESS - Next firmware volume found with address information
+
+--*/
+{
+ EFI_PEI_HOB_POINTERS FirmwareVolumeHob;
+
+ FirmwareVolumeHob.Raw = *HobStart;
+ if (END_OF_HOB_LIST (FirmwareVolumeHob)) {
+ return EFI_NOT_FOUND;
+ }
+
+ FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV2, *HobStart);
+ if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV2) {
+ return EFI_NOT_FOUND;
+ }
+
+ *BaseAddress = FirmwareVolumeHob.FirmwareVolume2->BaseAddress;
+ *Length = FirmwareVolumeHob.FirmwareVolume2->Length;
+ EfiCommonLibCopyMem(FileName,&FirmwareVolumeHob.FirmwareVolume2->FileName,sizeof(EFI_GUID));
+
+ *HobStart = GET_NEXT_HOB (FirmwareVolumeHob);
+
+ return EFI_SUCCESS;
+}
+#endif
+//PI 1.1 --
+
+EFI_STATUS
+GetNextGuidHob (
+ IN OUT VOID **HobStart,
+ IN EFI_GUID * Guid,
+ OUT VOID **Buffer,
+ OUT UINTN *BufferSize OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Get the next guid hob.
+
+Arguments:
+ HobStart A pointer to the start hob.
+ Guid A pointer to a guid.
+ Buffer A pointer to the buffer.
+ BufferSize Buffer size.
+
+Returns:
+ Status code.
+
+ EFI_NOT_FOUND - Next Guid hob not found
+
+ EFI_SUCCESS - Next Guid hob found and data for this Guid got
+
+ EFI_INVALID_PARAMETER - invalid parameter
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS GuidHob;
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) {
+
+ GuidHob.Raw = *HobStart;
+ if (END_OF_HOB_LIST (GuidHob)) {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHob.Raw = GetHob (EFI_HOB_TYPE_GUID_EXTENSION, *HobStart);
+ if (GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION) {
+ if (EfiCompareGuid (Guid, &GuidHob.Guid->Name)) {
+ Status = EFI_SUCCESS;
+ *Buffer = (VOID *) ((UINT8 *) (&GuidHob.Guid->Name) + sizeof (EFI_GUID));
+ if (BufferSize != NULL) {
+ *BufferSize = GuidHob.Header->HobLength - sizeof (EFI_HOB_GUID_TYPE);
+ }
+ }
+ }
+
+ *HobStart = GET_NEXT_HOB (GuidHob);
+ }
+
+ return Status;
+}
+
+
+#define PAL_ENTRY_HOB {0xe53cb8cc, 0xd62c, 0x4f74, 0xbd, 0xda, 0x31, 0xe5, 0x8d, 0xe5, 0x3e, 0x2}
+EFI_GUID gPalEntryHob = PAL_ENTRY_HOB;
+
+EFI_STATUS
+GetPalEntryHobInfo (
+ IN VOID *HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *PalEntry
+ )
+/*++
+
+Routine Description:
+
+ Get PAL entry from PalEntryHob
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ PalEntry - Pointer to PAL entry
+
+Returns:
+
+ Status code.
+
+--*/
+{
+ VOID *Buffer;
+ UINTN BufferSize;
+ EFI_STATUS Status;
+ VOID *HobStart2;
+
+ HobStart2 = HobStart;
+ Status = GetNextGuidHob (
+ &HobStart2,
+ &gPalEntryHob,
+ &Buffer,
+ &BufferSize
+ );
+
+ *PalEntry = *((EFI_PHYSICAL_ADDRESS *) Buffer);
+ return Status;
+}
+
+
+EFI_STATUS
+GetIoPortSpaceAddressHobInfo (
+ IN VOID *HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *IoPortSpaceAddress
+ )
+/*++
+
+Routine Description:
+
+ Get IO port space address from IoBaseHob.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ IoPortSpaceAddress - IO port space address
+
+Returns:
+
+ Status code
+
+--*/
+{
+/*
+ VOID *Buffer;
+ UINTN BufferSize;
+ EFI_STATUS Status;
+ VOID *HobStart2;
+
+ HobStart2 = HobStart;
+ Status = GetNextGuidHob (
+ &HobStart2,
+ &gEfiIoBaseHobGuid,
+ &Buffer,
+ &BufferSize
+ );
+
+ *IoPortSpaceAddress = *((EFI_PHYSICAL_ADDRESS *) Buffer);
+ return Status;*/
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/imem.h b/Core/CORE_DXE/imem.h
new file mode 100644
index 0000000..d9029c5
--- /dev/null
+++ b/Core/CORE_DXE/imem.h
@@ -0,0 +1,214 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ imem.h
+
+Abstract:
+
+ Head file to imem.h
+
+
+Revision History
+
+--*/
+
+#ifndef _IMEM_H_
+#define _IMEM_H_
+
+#include "Tiano.h"
+#include "DxeCore.h"
+#include "Processor.h"
+
+//
+// MEMORY_MAP_ENTRY
+//
+
+#define MEMORY_MAP_SIGNATURE EFI_SIGNATURE_32('m','m','a','p')
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY Link;
+ BOOLEAN FromPages;
+
+ EFI_MEMORY_TYPE Type;
+ UINT64 Start;
+ UINT64 End;
+
+ UINT64 VirtualStart;
+ UINT64 Attribute;
+} MEMORY_MAP;
+
+//
+// Internal prototypes
+//
+
+VOID *
+CoreAllocatePoolPages (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN NumberOfPages,
+ IN UINTN Alignment
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Used by the pool functions to allocate pages
+ to back pool allocation requests.
+
+Arguments:
+
+ PoolType - The type of memory for the new pool pages
+
+ NumberOfPages - No of pages to allocate
+
+ Alignment - Bits to align.
+
+Returns:
+
+ The allocated memory, or NULL
+
+--*/
+;
+
+
+VOID
+CoreFreePoolPages (
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+/*++
+
+Routine Description:
+
+ Internal function. Frees pool pages allocated via AllocatePoolPages ()
+
+Arguments:
+
+ Memory - The base address to free
+
+ NumberOfPages - The number of pages to free
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+VOID *
+CoreAllocatePoolI (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ Internal function to allocate pool of a particular type.
+
+ N.B. Caller must have the memory lock held
+
+
+Arguments:
+
+ PoolType - Type of pool to allocate
+
+ Size - The amount of pool to allocate
+
+Returns:
+
+ The allocate pool, or NULL
+
+--*/
+;
+
+
+EFI_STATUS
+CoreFreePoolI (
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Internal function to free a pool entry.
+
+ N.B. Caller must have the memory lock held
+
+
+Arguments:
+
+ Buffer - The allocated pool entry to free
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Buffer not valid
+
+ EFI_SUCCESS - Buffer successfully freed.
+
+--*/
+;
+
+
+VOID
+CoreAcquireMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Enter critical section by gaining lock on gMemoryLock
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CoreReleaseMemoryLock (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Exit critical section by releasing lock on gMemoryLock
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+//
+// Internal Global data
+//
+
+extern EFI_LOCK gMemoryLock;
+extern EFI_LIST_ENTRY gMemoryMap;
+extern MEMORY_MAP *gMemoryLastConvert;
+extern EFI_LIST_ENTRY mGcdMemorySpaceMap;
+#endif
diff --git a/Core/CORE_DXE/locate.c b/Core/CORE_DXE/locate.c
new file mode 100644
index 0000000..413e671
--- /dev/null
+++ b/Core/CORE_DXE/locate.c
@@ -0,0 +1,777 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ locate.c
+
+Abstract:
+
+ Locate handle functions
+
+Revision History
+
+--*/
+
+#include "hand.h"
+
+//
+// ProtocolRequest - Last LocateHandle request ID
+//
+UINTN mEfiLocateHandleRequest = 0;
+
+//
+// Internal prototypes
+//
+
+typedef struct {
+ EFI_GUID *Protocol;
+ VOID *SearchKey;
+ EFI_LIST_ENTRY *Position;
+ PROTOCOL_ENTRY *ProtEntry;
+} LOCATE_POSITION;
+
+typedef
+IHANDLE *
+(* CORE_GET_NEXT) (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ );
+
+STATIC
+IHANDLE *
+CoreGetNextLocateAllHandles (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ );
+
+STATIC
+IHANDLE *
+CoreGetNextLocateByRegisterNotify (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ );
+
+STATIC
+IHANDLE *
+CoreGetNextLocateByProtocol (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ );
+
+//
+//
+//
+
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreLocateHandle (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Locates the requested handle(s) and returns them in Buffer.
+
+Arguments:
+
+ SearchType - The type of search to perform to locate the handles
+
+ Protocol - The protocol to search for
+
+ SearchKey - Dependant on SearchType
+
+ BufferSize - On input the size of Buffer. On output the
+ size of data returned.
+
+ Buffer - The buffer to return the results in
+
+
+Returns:
+
+ EFI_BUFFER_TOO_SMALL - Buffer too small, required buffer size is returned in BufferSize.
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_SUCCESS - Successfully found the requested handle(s) and returns them in Buffer.
+
+--*/
+{
+ EFI_STATUS Status;
+ LOCATE_POSITION Position;
+ PROTOCOL_NOTIFY *ProtNotify;
+ CORE_GET_NEXT GetNext;
+ UINTN ResultSize;
+ IHANDLE *Handle;
+ IHANDLE **ResultBuffer;
+ VOID *Interface;
+
+//*** AMI PORTING BEGIN *****//
+ BOOLEAN ZeroSizeBuffer = FALSE;
+//*** AMI PORTING END *****//
+
+ if (BufferSize == NULL) {
+//*** AMI PORTING BEGIN ***//
+//Bug fix(EIP 82756): original code was just setting Status to EFI_INVALID_PARAMETER
+// and acessing *BufferSize right below.
+// This caused problems with the WHCK AllocateHandle test
+// Status = EFI_INVALID_PARAMETER;
+ ZeroSizeBuffer = TRUE;
+ } else {
+ if ((*BufferSize > 0) && (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+//*** AMI PORTING END *****//
+
+ GetNext = NULL;
+ //
+ // Set initial position
+ //
+
+ Position.Protocol = Protocol;
+ Position.SearchKey = SearchKey;
+ Position.Position = &gHandleList;
+
+ ResultSize = 0;
+ ResultBuffer = (IHANDLE **) Buffer;
+ Status = EFI_SUCCESS;
+
+ //
+ // Lock the protocol database
+ //
+
+ CoreAcquireProtocolLock ();
+
+ //
+ // Get the search function based on type
+ //
+ switch (SearchType) {
+ case AllHandles:
+ GetNext = CoreGetNextLocateAllHandles;
+ break;
+
+ case ByRegisterNotify:
+ //
+ // Must have SearchKey for locate ByRegisterNotify
+ //
+ if (SearchKey == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ GetNext = CoreGetNextLocateByRegisterNotify;
+ break;
+
+ case ByProtocol:
+ GetNext = CoreGetNextLocateByProtocol;
+ if (Protocol == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ //
+ // Look up the protocol entry and set the head pointer
+ //
+ Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
+ if (Position.ProtEntry == NULL) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+ Position.Position = &Position.ProtEntry->Protocols;
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR(Status)) {
+ CoreReleaseProtocolLock ();
+ return Status;
+ }
+
+//*** AMI PORTING BEGIN *****//
+/* If we're here, some handles are found.
+ We should return INVALID_PARAMETER if buffer size pointer is zero
+*/
+ if(ZeroSizeBuffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+//*** AMI PORTING END *****//
+
+ //
+ // Enumerate out the matching handles
+ //
+ mEfiLocateHandleRequest += 1;
+ for (; ;) {
+ //
+ // Get the next handle. If no more handles, stop
+ //
+ Handle = GetNext (&Position, &Interface);
+ if (NULL == Handle) {
+ break;
+ }
+
+ //
+ // Increase the resulting buffer size, and if this handle
+ // fits return it
+ //
+ ResultSize += sizeof(Handle);
+ if (ResultSize <= *BufferSize) {
+ *ResultBuffer = Handle;
+ ResultBuffer += 1;
+ }
+ }
+
+ //
+ // If the result is a zero length buffer, then there were no
+ // matching handles
+ //
+ if (ResultSize == 0) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Return the resulting buffer size. If it's larger than what
+ // was passed, then set the error code
+ //
+ if (ResultSize > *BufferSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+
+ if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {
+ //
+ // If this is a search by register notify and a handle was
+ // returned, update the register notification position
+ //
+ ProtNotify = SearchKey;
+ ProtNotify->Position = ProtNotify->Position->ForwardLink;
+ }
+ }
+
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+
+STATIC
+IHANDLE *
+CoreGetNextLocateAllHandles (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Routine to get the next Handle, when you are searching for all handles.
+
+Arguments:
+
+ Position - Information about which Handle to seach for.
+
+ Interface - Return the interface structure for the matching protocol.
+
+Returns:
+ IHANDLE - An IHANDLE is returned if the next Position is not the end of the
+ list. A NULL_HANDLE is returned if it's the end of the list.
+
+--*/
+{
+ IHANDLE *Handle;
+
+ //
+ // Next handle
+ //
+ Position->Position = Position->Position->ForwardLink;
+
+ //
+ // If not at the end of the list, get the handle
+ //
+ Handle = NULL_HANDLE;
+ *Interface = NULL;
+ if (Position->Position != &gHandleList) {
+ Handle = CR (Position->Position, IHANDLE, AllHandles, EFI_HANDLE_SIGNATURE);
+ }
+
+ return Handle;
+}
+
+
+STATIC
+IHANDLE *
+CoreGetNextLocateByRegisterNotify (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Routine to get the next Handle, when you are searching for register protocol
+ notifies.
+
+Arguments:
+
+ Position - Information about which Handle to seach for.
+
+ Interface - Return the interface structure for the matching protocol.
+
+Returns:
+ IHANDLE - An IHANDLE is returned if the next Position is not the end of the
+ list. A NULL_HANDLE is returned if it's the end of the list.
+
+--*/
+{
+ IHANDLE *Handle;
+ PROTOCOL_NOTIFY *ProtNotify;
+ PROTOCOL_INTERFACE *Prot;
+ EFI_LIST_ENTRY *Link;
+
+ Handle = NULL_HANDLE;
+ *Interface = NULL;
+ ProtNotify = Position->SearchKey;
+
+ //
+ // If this is the first request, get the next handle
+ //
+ if (ProtNotify != NULL) {
+ ASSERT(ProtNotify->Signature == PROTOCOL_NOTIFY_SIGNATURE);
+ Position->SearchKey = NULL;
+
+ //
+ // If not at the end of the list, get the next handle
+ //
+ Link = ProtNotify->Position->ForwardLink;
+ if (Link != &ProtNotify->Protocol->Protocols) {
+ Prot = CR (Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
+ Handle = (IHANDLE *) Prot->Handle;
+ *Interface = Prot->Interface;
+ }
+ }
+
+ return Handle;
+}
+
+
+STATIC
+IHANDLE *
+CoreGetNextLocateByProtocol (
+ IN OUT LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Routine to get the next Handle, when you are searching for a given protocol.
+
+Arguments:
+
+ Position - Information about which Handle to seach for.
+
+ Interface - Return the interface structure for the matching protocol.
+
+Returns:
+ IHANDLE - An IHANDLE is returned if the next Position is not the end of the
+ list. A NULL_HANDLE is returned if it's the end of the list.
+
+--*/
+{
+ IHANDLE *Handle;
+ EFI_LIST_ENTRY *Link;
+ PROTOCOL_INTERFACE *Prot;
+
+ Handle = NULL_HANDLE;
+ *Interface = NULL;
+ for (; ;) {
+ //
+ // Next entry
+ //
+ Link = Position->Position->ForwardLink;
+ Position->Position = Link;
+
+ //
+ // If not at the end, return the handle
+ //
+ if (Link == &Position->ProtEntry->Protocols) {
+ Handle = NULL_HANDLE;
+ break;
+ }
+
+ //
+ // Get the handle
+ //
+ Prot = CR(Link, PROTOCOL_INTERFACE, ByProtocol, PROTOCOL_INTERFACE_SIGNATURE);
+ Handle = (IHANDLE *) Prot->Handle;
+ *Interface = Prot->Interface;
+
+ //
+ // If this handle has not been returned this request, then
+ // return it now
+ //
+ if (Handle->LocateRequest != mEfiLocateHandleRequest) {
+ Handle->LocateRequest = mEfiLocateHandleRequest;
+ break;
+ }
+ }
+
+ return Handle;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreLocateDevicePath (
+ IN EFI_GUID *Protocol,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT EFI_HANDLE *Device
+ )
+/*++
+
+Routine Description:
+
+ Locates the handle to a device on the device path that best matches the specified protocol.
+
+Arguments:
+
+ Protocol - The protocol to search for.
+ DevicePath - On input, a pointer to a pointer to the device path. On output, the device
+ path pointer is modified to point to the remaining part of the devicepath.
+ Device - A pointer to the returned device handle.
+
+Returns:
+
+ EFI_SUCCESS - The resulting handle was returned.
+ EFI_NOT_FOUND - No handles matched the search.
+ EFI_INVALID_PARAMETER - One of the parameters has an invalid value.
+
+--*/
+{
+ INTN SourceSize;
+ INTN Size;
+ INTN BestMatch;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_STATUS Status;
+ EFI_HANDLE *Handles;
+ EFI_HANDLE Handle;
+ EFI_DEVICE_PATH_PROTOCOL *SourcePath;
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;
+
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((DevicePath == NULL) || (*DevicePath == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Modified to pass SCT test
+ //
+ // Get a list of all handles that support the requested protocol
+ //
+ Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);
+ if (EFI_ERROR (Status) || HandleCount == 0) {
+ return EFI_NOT_FOUND;
+ }
+//*** AMI PORTING END *****//
+
+ if (Device == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Device = NULL_HANDLE;
+ SourcePath = *DevicePath;
+ TmpDevicePath = SourcePath;
+ while (!EfiIsDevicePathEnd (TmpDevicePath)) {
+ if (EfiIsDevicePathEndInstance (TmpDevicePath)) {
+ //
+ // If DevicePath is a multi-instance device path,
+ // the function will operate on the first instance
+ //
+ break;
+ }
+ TmpDevicePath = NextDevicePathNode (TmpDevicePath);
+ }
+
+ SourceSize = (UINTN) TmpDevicePath - (UINTN) SourcePath;
+
+//*** AMI PORTING BEGIN ***//
+//Modified to pass SCT test
+//Commented code moved to be executed before checking if passed Handle is NULL
+/*
+ //
+ // Get a list of all handles that support the requested protocol
+ //
+ Status = CoreLocateHandleBuffer (ByProtocol, Protocol, NULL, &HandleCount, &Handles);
+ if (EFI_ERROR (Status) || HandleCount == 0) {
+ return EFI_NOT_FOUND;
+ }
+*/
+//*** AMI PORTING END *****//
+
+ BestMatch = -1;
+ for(Index = 0; Index < HandleCount; Index += 1) {
+ Handle = Handles[Index];
+ Status = CoreHandleProtocol (Handle, &gEfiDevicePathProtocolGuid, &TmpDevicePath);
+ if (EFI_ERROR (Status)) {
+ //
+ // If this handle doesn't support device path, then skip it
+ //
+ continue;
+ }
+
+ //
+ // Check if DevicePath is first part of SourcePath
+ //
+ Size = CoreDevicePathSize (TmpDevicePath) - sizeof(EFI_DEVICE_PATH_PROTOCOL);
+ if ((Size <= SourceSize) && EfiCompareMem (SourcePath, TmpDevicePath, Size) == 0) {
+ //
+ // If the size is equal to the best match, then we
+ // have a duplice device path for 2 different device
+ // handles
+ //
+ ASSERT (Size != BestMatch);
+
+ //
+ // We've got a match, see if it's the best match so far
+ //
+ if (Size > BestMatch) {
+ BestMatch = Size;
+ *Device = Handle;
+ }
+ }
+ }
+
+ CoreFreePool (Handles);
+
+ //
+ // If there wasn't any match, then no parts of the device path was found.
+ // Which is strange since there is likely a "root level" device path in the system.
+ //
+ if (BestMatch == -1) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Return the remaining part of the device path
+ //
+ *DevicePath = (EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) SourcePath) + BestMatch);
+ return EFI_SUCCESS;
+}
+
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreLocateProtocol (
+ IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface
+ )
+/*++
+
+Routine Description:
+
+ Return the first Protocol Interface that matches the Protocol GUID. If
+ Registration is pasased in return a Protocol Instance that was just add
+ to the system. If Retistration is NULL return the first Protocol Interface
+ you find.
+
+Arguments:
+
+ Protocol - The protocol to search for
+
+ Registration - Optional Registration Key returned from RegisterProtocolNotify()
+
+ Interface - Return the Protocol interface (instance).
+
+Returns:
+
+ EFI_SUCCESS - If a valid Interface is returned
+
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+ EFI_NOT_FOUND - Protocol interface not found
+
+--*/
+{
+ EFI_STATUS Status;
+ LOCATE_POSITION Position;
+ PROTOCOL_NOTIFY *ProtNotify;
+ IHANDLE *Handle;
+
+ if (Interface == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Protocol == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ *Interface = NULL;
+ Status = EFI_SUCCESS;
+
+ //
+ // Set initial position
+ //
+ Position.Protocol = Protocol;
+ Position.SearchKey = Registration;
+ Position.Position = &gHandleList;
+
+ //
+ // Lock the protocol database
+ //
+ CoreAcquireProtocolLock ();
+
+ mEfiLocateHandleRequest += 1;
+
+ if (NULL == Registration) {
+ //
+ // Look up the protocol entry and set the head pointer
+ //
+ Position.ProtEntry = CoreFindProtocolEntry (Protocol, FALSE);
+ if (Position.ProtEntry == NULL) {
+ Status = EFI_NOT_FOUND;
+ goto Done;
+ }
+ Position.Position = &Position.ProtEntry->Protocols;
+
+ Handle = CoreGetNextLocateByProtocol (&Position, Interface);
+ } else {
+ Handle = CoreGetNextLocateByRegisterNotify (&Position, Interface);
+ }
+
+ if (NULL == Handle) {
+ Status = EFI_NOT_FOUND;
+ } else if (NULL != Registration) {
+ //
+ // If this is a search by register notify and a handle was
+ // returned, update the register notification position
+ //
+ ProtNotify = Registration;
+ ProtNotify->Position = ProtNotify->Position->ForwardLink;
+ }
+
+Done:
+ CoreReleaseProtocolLock ();
+ return Status;
+}
+
+
+EFI_BOOTSERVICE11
+EFI_STATUS
+EFIAPI
+CoreLocateHandleBuffer (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *NumberHandles,
+ OUT EFI_HANDLE **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Function returns an array of handles that support the requested protocol
+ in a buffer allocated from pool. This is a version of CoreLocateHandle()
+ that allocates a buffer for the caller.
+
+Arguments:
+
+ SearchType - Specifies which handle(s) are to be returned.
+ Protocol - Provides the protocol to search by.
+ This parameter is only valid for SearchType ByProtocol.
+ SearchKey - Supplies the search key depending on the SearchType.
+ NumberHandles - The number of handles returned in Buffer.
+ Buffer - A pointer to the buffer to return the requested array of
+ handles that support Protocol.
+
+Returns:
+
+ EFI_SUCCESS - The result array of handles was returned.
+ EFI_NOT_FOUND - No handles match the search.
+ EFI_OUT_OF_RESOURCES - There is not enough pool memory to store the matching results.
+ EFI_INVALID_PARAMETER - Invalid parameter
+
+--*/
+{
+ EFI_STATUS Status;
+ UINTN BufferSize;
+
+ if (NumberHandles == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BufferSize = 0;
+ *NumberHandles = 0;
+ *Buffer = NULL;
+ Status = CoreLocateHandle (
+ SearchType,
+ Protocol,
+ SearchKey,
+ &BufferSize,
+ *Buffer
+ );
+ //
+ // LocateHandleBuffer() returns incorrect status code if SearchType is
+ // invalid.
+ //
+ // Add code to correctly handle expected errors from CoreLocateHandle().
+ //
+ if (EFI_ERROR(Status)) {
+ switch (Status) {
+ case EFI_BUFFER_TOO_SMALL:
+ break;
+ case EFI_INVALID_PARAMETER:
+ return Status;
+ default:
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ *Buffer = CoreAllocateBootServicesPool (BufferSize);
+ if (*Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = CoreLocateHandle (
+ SearchType,
+ Protocol,
+ SearchKey,
+ &BufferSize,
+ *Buffer
+ );
+
+ *NumberHandles = BufferSize/sizeof(EFI_HANDLE);
+ if (EFI_ERROR(Status)) {
+ *NumberHandles = 0;
+ }
+
+ return Status;
+}
+
+
diff --git a/Core/CORE_DXE/memdata.c b/Core/CORE_DXE/memdata.c
new file mode 100644
index 0000000..580b0bd
--- /dev/null
+++ b/Core/CORE_DXE/memdata.c
@@ -0,0 +1,41 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ memdata.c
+
+Abstract:
+
+ Global data used in memory service
+
+
+Revision History
+
+--*/
+
+#include "imem.h"
+
+
+//
+// MemoryLock - synchronizes access to the memory map and pool lists
+//
+EFI_LOCK gMemoryLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_NOTIFY);
+
+//
+// MemoryMap - the current memory map
+//
+EFI_LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap);
+
+//
+// MemoryLastConvert - the last memory descriptor used for a conversion request
+//
+MEMORY_MAP *gMemoryLastConvert;
diff --git a/Core/CORE_DXE/pool.c b/Core/CORE_DXE/pool.c
new file mode 100644
index 0000000..359c46c
--- /dev/null
+++ b/Core/CORE_DXE/pool.c
@@ -0,0 +1,620 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ pool.c
+
+Abstract:
+
+ EFI Memory pool management
+
+Revision History
+
+--*/
+
+#include "imem.h"
+
+#define POOL_FREE_SIGNATURE EFI_SIGNATURE_32('p','f','r','0')
+typedef struct {
+ UINT32 Signature;
+ UINT32 Index;
+ EFI_LIST_ENTRY Link;
+} POOL_FREE;
+
+
+#define POOL_HEAD_SIGNATURE EFI_SIGNATURE_32('p','h','d','0')
+typedef struct {
+ UINT32 Signature;
+ UINT32 Size;
+ EFI_MEMORY_TYPE Type;
+ UINTN Reserved;
+ CHAR8 Data[1];
+} POOL_HEAD;
+
+#define SIZE_OF_POOL_HEAD EFI_FIELD_OFFSET(POOL_HEAD,Data)
+
+#define POOL_TAIL_SIGNATURE EFI_SIGNATURE_32('p','t','a','l')
+typedef struct {
+ UINT32 Signature;
+ UINT32 Size;
+} POOL_TAIL;
+
+
+#define POOL_SHIFT 7
+
+#define POOL_OVERHEAD (SIZE_OF_POOL_HEAD + sizeof(POOL_TAIL))
+
+#define HEAD_TO_TAIL(a) \
+ ((POOL_TAIL *) (((CHAR8 *) (a)) + (a)->Size - sizeof(POOL_TAIL)));
+
+
+#define SIZE_TO_LIST(a) ((a) >> POOL_SHIFT)
+#define LIST_TO_SIZE(a) ((a+1) << POOL_SHIFT)
+
+#define MAX_POOL_LIST SIZE_TO_LIST(DEFAULT_PAGE_ALLOCATION)
+#define MAX_POOL_SIZE (EFI_MAX_ADDRESS - POOL_OVERHEAD)
+
+//
+// Globals
+//
+
+#define POOL_SIGNATURE EFI_SIGNATURE_32('p','l','s','t')
+typedef struct {
+ INTN Signature;
+ UINTN Used;
+ EFI_MEMORY_TYPE MemoryType;
+ EFI_LIST_ENTRY FreeList[MAX_POOL_LIST];
+ EFI_LIST_ENTRY Link;
+} POOL;
+
+
+POOL PoolHead[EfiMaxMemoryType];
+EFI_LIST_ENTRY PoolHeadList;
+
+//
+//
+//
+
+VOID
+CoreInitializePool (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Called to initialize the pool.
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN Type;
+ UINTN Index;
+
+ for (Type=0; Type < EfiMaxMemoryType; Type++) {
+ PoolHead[Type].Signature = 0;
+ PoolHead[Type].Used = 0;
+ PoolHead[Type].MemoryType = Type;
+ for (Index=0; Index < MAX_POOL_LIST; Index++) {
+ InitializeListHead (&PoolHead[Type].FreeList[Index]);
+ }
+ }
+ InitializeListHead (&PoolHeadList);
+}
+
+
+POOL *
+LookupPoolHead (
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Look up pool head for specified memory type.
+
+Arguments:
+
+ MemoryType - Memory type of which pool head is looked for
+
+Returns:
+
+ Pointer of Corresponding pool head.
+
+--*/
+{
+ EFI_LIST_ENTRY *Link;
+ POOL *Pool;
+ UINTN Index;
+
+ if (MemoryType >= 0 && MemoryType < EfiMaxMemoryType) {
+ return &PoolHead[MemoryType];
+ }
+
+ if (MemoryType < 0) {
+
+ for (Link = PoolHeadList.ForwardLink; Link != &PoolHeadList; Link = Link->ForwardLink) {
+ Pool = CR(Link, POOL, Link, POOL_SIGNATURE);
+ if (Pool->MemoryType == MemoryType) {
+ return Pool;
+ }
+ }
+
+ Pool = CoreAllocatePoolI (EfiBootServicesData, sizeof (POOL));
+ if (Pool == NULL) {
+ return NULL;
+ }
+
+ Pool->Signature = POOL_SIGNATURE;
+ Pool->Used = 0;
+ Pool->MemoryType = MemoryType;
+ for (Index=0; Index < MAX_POOL_LIST; Index++) {
+ InitializeListHead (&Pool->FreeList[Index]);
+ }
+
+ InsertHeadList (&PoolHeadList, &Pool->Link);
+
+ return Pool;
+ }
+
+ return NULL;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreAllocatePool (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Allocate pool of a particular type.
+
+Arguments:
+
+ PoolType - Type of pool to allocate
+
+ Size - The amount of pool to allocate
+
+ Buffer - The address to return a pointer to the allocated pool
+
+Returns:
+
+ EFI_INVALID_PARAMETER - PoolType not valid
+
+ EFI_OUT_OF_RESOURCES - Size exceeds max pool size or allocation failed.
+
+ EFI_SUCCESS - Pool successfully allocated.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ //
+ // If it's not a valid type, fail it
+ //
+ if ((PoolType >= EfiMaxMemoryType && PoolType <= 0x7fffffff) ||
+ PoolType == EfiConventionalMemory) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+//*** AMI PORTING BEGIN ***//
+// UEFI spec update - return EFI_INVALID_PARAMETER if Buffer is NULL
+ if (Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+//*** AMI PORTING END *****//
+
+ *Buffer = NULL;
+ //
+ // As we need to reserve memory for other resources, we can't expect to allocate
+ // all memory( EFI_MAX_ADDRESS - POOL_OVERHEAD + 1) using this function,
+ // the following check operation is only used to make sure the allocated pool size will
+ // not rool over from a very large number to a very small number.
+ //
+ if (Size > MAX_POOL_SIZE) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Acquire the memory lock and make the allocation
+ //
+ Status = CoreAcquireLockOrFail (&gMemoryLock);
+ if (EFI_ERROR (Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Buffer = CoreAllocatePoolI (PoolType, Size);
+ CoreReleaseMemoryLock ();
+ return (*Buffer != NULL) ? EFI_SUCCESS : EFI_OUT_OF_RESOURCES;
+}
+
+
+VOID *
+CoreAllocatePoolI (
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ Internal function to allocate pool of a particular type.
+
+ N.B. Caller must have the memory lock held
+
+
+Arguments:
+
+ PoolType - Type of pool to allocate
+
+ Size - The amount of pool to allocate
+
+Returns:
+
+ The allocate pool, or NULL
+
+--*/
+{
+ POOL *Pool;
+ POOL_FREE *Free;
+ POOL_HEAD *Head;
+ POOL_TAIL *Tail;
+ CHAR8 *NewPage;
+ VOID *Buffer;
+ UINTN Index;
+ UINTN FSize;
+ UINTN offset;
+ UINTN Adjustment;
+ UINTN NoPages;
+
+ ASSERT_LOCKED (&gMemoryLock);
+
+ //
+ // Adjust the size by the pool header & tail overhead
+ //
+
+ //
+ // Adjusting the Size to be of proper alignment so that
+ // we don't get an unaligned access fault later when
+ // pool_Tail is being initialized
+ //
+ ALIGN_VARIABLE (Size, Adjustment);
+
+ Size += POOL_OVERHEAD;
+ Index = SIZE_TO_LIST(Size);
+ Pool = LookupPoolHead (PoolType);
+ if (Pool== NULL) {
+ return NULL;
+ }
+ Head = NULL;
+
+ //
+ // If allocation is over max size, just allocate pages for the request
+ // (slow)
+ //
+ if (Index >= MAX_POOL_LIST) {
+ NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
+ NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
+ Head = CoreAllocatePoolPages (PoolType, NoPages, DEFAULT_PAGE_ALLOCATION);
+ goto Done;
+ }
+
+ //
+ // If there's no free pool in the proper list size, go get some more pages
+ //
+ if (IsListEmpty (&Pool->FreeList[Index])) {
+
+ //
+ // Get another page
+ //
+ NewPage = CoreAllocatePoolPages(PoolType, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION), DEFAULT_PAGE_ALLOCATION);
+ if (NewPage == NULL) {
+ goto Done;
+ }
+
+ //
+ // Carve up new page into free pool blocks
+ //
+ offset = 0;
+ while (offset < DEFAULT_PAGE_ALLOCATION) {
+ ASSERT (Index < MAX_POOL_LIST);
+ FSize = LIST_TO_SIZE(Index);
+
+ while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
+ Free = (POOL_FREE *) &NewPage[offset];
+ Free->Signature = POOL_FREE_SIGNATURE;
+ Free->Index = (UINT32)Index;
+ InsertHeadList (&Pool->FreeList[Index], &Free->Link);
+ offset += FSize;
+ }
+
+ Index -= 1;
+ }
+
+ ASSERT (offset == DEFAULT_PAGE_ALLOCATION);
+ Index = SIZE_TO_LIST(Size);
+ }
+
+ //
+ // Remove entry from free pool list
+ //
+ Free = CR (Pool->FreeList[Index].ForwardLink, POOL_FREE, Link, POOL_FREE_SIGNATURE);
+ RemoveEntryList (&Free->Link);
+
+ Head = (POOL_HEAD *) Free;
+
+Done:
+ Buffer = NULL;
+
+ if (Head != NULL) {
+
+ //
+ // If we have a pool buffer, fill in the header & tail info
+ //
+ Head->Signature = POOL_HEAD_SIGNATURE;
+ Head->Size = (UINT32) Size;
+ Head->Type = (EFI_MEMORY_TYPE) PoolType;
+ Tail = HEAD_TO_TAIL (Head);
+ Tail->Signature = POOL_TAIL_SIGNATURE;
+ Tail->Size = (UINT32) Size;
+ Buffer = Head->Data;
+ DEBUG_SET_MEMORY (Buffer, Size - POOL_OVERHEAD);
+
+ DEBUG (
+ (EFI_D_POOL,
+ "AllocatePool: Type %x, Addr %x (len %x) %,d\n",
+ (UINTN)PoolType,
+ Buffer,
+ Size - POOL_OVERHEAD,
+ Pool->Used)
+ );
+
+ //
+ // Account the allocation
+ //
+ Pool->Used += Size;
+
+ } else {
+ DEBUG ((EFI_D_ERROR | EFI_D_POOL, "AllocatePool: failed to allocate %d bytes\n", Size));
+ }
+
+ return Buffer;
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreFreePool (
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Frees pool.
+
+Arguments:
+
+ Buffer - The allocated pool entry to free
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Buffer is not a valid value.
+
+ EFI_SUCCESS - Pool successfully freed.
+
+--*/
+{
+ EFI_STATUS Status;
+
+ if (NULL == Buffer) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireMemoryLock ();
+ Status = CoreFreePoolI (Buffer);
+ CoreReleaseMemoryLock ();
+ return Status;
+}
+
+
+EFI_STATUS
+CoreFreePoolI (
+ IN VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Internal function to free a pool entry.
+
+ N.B. Caller must have the memory lock held
+
+
+Arguments:
+
+ Buffer - The allocated pool entry to free
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Buffer not valid
+
+ EFI_SUCCESS - Buffer successfully freed.
+
+--*/
+{
+ POOL *Pool;
+ POOL_HEAD *Head;
+ POOL_TAIL *Tail;
+ POOL_FREE *Free;
+ UINTN Index;
+ UINTN NoPages;
+ UINTN Size;
+ CHAR8 *NewPage;
+ UINTN FSize;
+ UINTN offset;
+ BOOLEAN AllFree;
+
+ ASSERT(NULL != Buffer);
+ //
+ // Get the head & tail of the pool entry
+ //
+ Head = CR (Buffer, POOL_HEAD, Data, POOL_HEAD_SIGNATURE);
+ ASSERT(NULL != Head);
+
+ if (Head->Signature != POOL_HEAD_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Tail = HEAD_TO_TAIL (Head);
+ ASSERT(NULL != Tail);
+
+ //
+ // Debug
+ //
+ ASSERT (Tail->Signature == POOL_TAIL_SIGNATURE);
+ ASSERT (Head->Size == Tail->Size);
+ ASSERT_LOCKED (&gMemoryLock);
+
+ if (Tail->Signature != POOL_TAIL_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Head->Size != Tail->Size) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Determine the pool type and account for it
+ //
+ Size = Head->Size;
+ Pool = LookupPoolHead (Head->Type);
+ if (Pool == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Pool->Used -= Size;
+ DEBUG ((EFI_D_POOL, "FreePool: %x (len %x) %,d\n", Head->Data, (UINTN)Head->Size - POOL_OVERHEAD, Pool->Used));
+
+ //
+ // Determine the pool list
+ //
+ Index = SIZE_TO_LIST(Size);
+ DEBUG_SET_MEMORY (Head, Size);
+
+ //
+ // If it's not on the list, it must be pool pages
+ //
+ if (Index >= MAX_POOL_LIST) {
+
+ //
+ // Return the memory pages back to free memory
+ //
+ NoPages = EFI_SIZE_TO_PAGES(Size) + EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1;
+ NoPages &= ~(EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION) - 1);
+ CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN) Head, NoPages);
+
+ } else {
+
+ //
+ // Put the pool entry onto the free pool list
+ //
+ Free = (POOL_FREE *) Head;
+ ASSERT(NULL != Free);
+ Free->Signature = POOL_FREE_SIGNATURE;
+ Free->Index = (UINT32)Index;
+ InsertHeadList (&Pool->FreeList[Index], &Free->Link);
+
+ //
+ // See if all the pool entries in the same page as Free are freed pool
+ // entries
+ //
+ NewPage = (CHAR8 *)((UINTN)Free & ~((DEFAULT_PAGE_ALLOCATION) -1));
+ Free = (POOL_FREE *) &NewPage[0];
+ ASSERT(NULL != Free);
+
+ if (Free->Signature == POOL_FREE_SIGNATURE) {
+
+ Index = Free->Index;
+
+ AllFree = TRUE;
+ offset = 0;
+
+ while ((offset < DEFAULT_PAGE_ALLOCATION) && (AllFree)) {
+ FSize = LIST_TO_SIZE(Index);
+ while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
+ Free = (POOL_FREE *) &NewPage[offset];
+ ASSERT(NULL != Free);
+ if (Free->Signature != POOL_FREE_SIGNATURE) {
+ AllFree = FALSE;
+ }
+ offset += FSize;
+ }
+ Index -= 1;
+ }
+
+ if (AllFree) {
+
+ //
+ // All of the pool entries in the same page as Free are free pool
+ // entries
+ // Remove all of these pool entries from the free loop lists.
+ //
+ Free = (POOL_FREE *) &NewPage[0];
+ ASSERT(NULL != Free);
+ Index = Free->Index;
+ offset = 0;
+
+ while (offset < DEFAULT_PAGE_ALLOCATION) {
+ FSize = LIST_TO_SIZE(Index);
+ while (offset + FSize <= DEFAULT_PAGE_ALLOCATION) {
+ Free = (POOL_FREE *) &NewPage[offset];
+ ASSERT(NULL != Free);
+ RemoveEntryList (&Free->Link);
+ offset += FSize;
+ }
+ Index -= 1;
+ }
+
+ //
+ // Free the page
+ //
+ CoreFreePoolPages ((EFI_PHYSICAL_ADDRESS) (UINTN)NewPage, EFI_SIZE_TO_PAGES (DEFAULT_PAGE_ALLOCATION));
+ }
+ }
+ }
+
+ //
+ // If this is an OS specific memory type, then check to see if the last
+ // portion of that memory type has been freed. If it has, then free the
+ // list entry for that memory type
+ //
+ if (Pool->MemoryType < 0 && Pool->Used == 0) {
+ RemoveEntryList (&Pool->Link);
+ CoreFreePoolI (Pool);
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/timer.c b/Core/CORE_DXE/timer.c
new file mode 100644
index 0000000..28ce124
--- /dev/null
+++ b/Core/CORE_DXE/timer.c
@@ -0,0 +1,386 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ timer.c
+
+Abstract:
+
+ EFI Event support
+
+Revision History
+
+--*/
+
+
+#include "exec.h"
+
+//
+// Internal prototypes
+//
+STATIC
+UINT64
+CoreCurrentSystemTime (
+ VOID
+ );
+
+VOID
+EFIAPI
+CoreCheckTimers (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+STATIC
+VOID
+CoreInsertEventTimer (
+ IN IEVENT *Event
+ );
+
+//
+// Internal data
+//
+
+static EFI_LIST_ENTRY mEfiTimerList = INITIALIZE_LIST_HEAD_VARIABLE (mEfiTimerList);
+static EFI_LOCK mEfiTimerLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL - 1);
+static EFI_EVENT mEfiCheckTimerEvent;
+
+static EFI_LOCK mEfiSystemTimeLock = EFI_INITIALIZE_LOCK_VARIABLE (EFI_TPL_HIGH_LEVEL);
+static UINT64 mEfiSystemTime = 0;
+
+//
+// Timer functions
+//
+
+VOID
+CoreInitializeTimer (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Initializes timer support
+
+Arguments:
+
+ None
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = CoreCreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_HIGH_LEVEL - 1,
+ CoreCheckTimers,
+ NULL,
+ &mEfiCheckTimerEvent
+ );
+ ASSERT_EFI_ERROR (Status);
+}
+
+STATIC
+UINT64
+CoreCurrentSystemTime (
+ VOID
+ )
+/*++
+
+Routine Description:
+
+ Returns the current system time
+
+Arguments:
+
+ None
+
+Returns:
+
+ Returns the current system time
+
+--*/
+{
+ UINT64 SystemTime;
+
+ CoreAcquireLock (&mEfiSystemTimeLock);
+ SystemTime = mEfiSystemTime;
+ CoreReleaseLock (&mEfiSystemTimeLock);
+ return SystemTime;
+}
+
+VOID
+EFIAPI
+CoreTimerTick (
+ IN UINT64 Duration
+ )
+/*++
+
+Routine Description:
+
+ Called by the platform code to process a tick.
+
+Arguments:
+
+ Duration - The number of 100ns elasped since the last call to TimerTick
+
+Returns:
+
+ None
+
+--*/
+{
+ IEVENT *Event;
+
+ //
+ // Check runtiem flag in case there are ticks while exiting boot services
+ //
+
+ CoreAcquireLock (&mEfiSystemTimeLock);
+
+ //
+ // Update the system time
+ //
+
+ mEfiSystemTime += Duration;
+
+ //
+ // If the head of the list is expired, fire the timer event
+ // to process it
+ //
+
+ if (!IsListEmpty (&mEfiTimerList)) {
+ Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);
+
+ if (Event->u.Timer.TriggerTime <= mEfiSystemTime) {
+ CoreSignalEvent (mEfiCheckTimerEvent);
+ }
+ }
+
+ CoreReleaseLock (&mEfiSystemTimeLock);
+}
+
+VOID
+EFIAPI
+CoreCheckTimers (
+ IN EFI_EVENT CheckEvent,
+ IN VOID *Context
+ )
+/*++
+
+Routine Description:
+
+ Checks the sorted timer list against the current system time.
+ Signals any expired event timer.
+
+Arguments:
+
+ CheckEvent - Not used
+
+ Context - Not used
+
+Returns:
+
+ None
+
+--*/
+{
+ UINT64 SystemTime;
+ IEVENT *Event;
+
+ //
+ // Check the timer database for expired timers
+ //
+
+ CoreAcquireLock (&mEfiTimerLock);
+ SystemTime = CoreCurrentSystemTime ();
+
+ while (!IsListEmpty (&mEfiTimerList)) {
+ Event = CR (mEfiTimerList.ForwardLink, IEVENT, u.Timer.Link, EVENT_SIGNATURE);
+
+ //
+ // If this timer is not expired, then we're done
+ //
+
+ if (Event->u.Timer.TriggerTime > SystemTime) {
+ break;
+ }
+
+ //
+ // Remove this timer from the timer queue
+ //
+
+ RemoveEntryList (&Event->u.Timer.Link);
+ Event->u.Timer.Link.ForwardLink = NULL;
+
+ //
+ // Signal it
+ //
+ CoreSignalEvent (Event);
+
+ //
+ // If this is a periodic timer, set it
+ //
+ if (Event->u.Timer.Period) {
+
+ //
+ // Compute the timers new trigger time
+ //
+
+ Event->u.Timer.TriggerTime = Event->u.Timer.TriggerTime + Event->u.Timer.Period;
+
+ //
+ // If that's before now, then reset the timer to start from now
+ //
+ if (Event->u.Timer.TriggerTime <= SystemTime) {
+ Event->u.Timer.TriggerTime = SystemTime;
+ CoreSignalEvent (mEfiCheckTimerEvent);
+ }
+
+ //
+ // Add the timer
+ //
+
+ CoreInsertEventTimer (Event);
+ }
+ }
+
+ CoreReleaseLock (&mEfiTimerLock);
+}
+
+STATIC
+VOID
+CoreInsertEventTimer (
+ IN IEVENT *Event
+ )
+/*++
+
+Routine Description:
+
+ Inserts the timer event
+
+Arguments:
+
+ Event - Points to the internal structure of timer event to be installed
+
+Returns:
+
+ None
+
+--*/
+{
+ UINT64 TriggerTime;
+ EFI_LIST_ENTRY *Link;
+ IEVENT *Event2;
+
+ ASSERT_LOCKED (&mEfiTimerLock);
+
+ //
+ // Get the timer's trigger time
+ //
+
+ TriggerTime = Event->u.Timer.TriggerTime;
+
+ //
+ // Insert the timer into the timer database in assending sorted order
+ //
+
+ for (Link = mEfiTimerList.ForwardLink; Link != &mEfiTimerList; Link = Link->ForwardLink) {
+ Event2 = CR (Link, IEVENT, u.Timer.Link, EVENT_SIGNATURE);
+
+ if (Event2->u.Timer.TriggerTime > TriggerTime) {
+ break;
+ }
+ }
+
+ InsertTailList (Link, &Event->u.Timer.Link);
+}
+
+
+EFI_BOOTSERVICE
+EFI_STATUS
+EFIAPI
+CoreSetTimer (
+ IN EFI_EVENT UserEvent,
+ IN EFI_TIMER_DELAY Type,
+ IN UINT64 TriggerTime
+ )
+/*++
+
+Routine Description:
+
+ Sets the type of timer and the trigger time for a timer event.
+
+Arguments:
+
+ UserEvent - The timer event that is to be signaled at the specified time
+ Type - The type of time that is specified in TriggerTime
+ TriggerTime - The number of 100ns units until the timer expires
+
+Returns:
+
+ EFI_SUCCESS - The event has been set to be signaled at the requested time
+ EFI_INVALID_PARAMETER - Event or Type is not valid
+
+--*/
+{
+ IEVENT *Event;
+
+ Event = UserEvent;
+
+ if (Event == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Event->Signature != EVENT_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Type < 0 || Type >= TimerTypeMax || !(Event->Type & EFI_EVENT_TIMER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CoreAcquireLock (&mEfiTimerLock);
+
+ //
+ // If the timer is queued to the timer database, remove it
+ //
+
+ if (Event->u.Timer.Link.ForwardLink != NULL) {
+ RemoveEntryList (&Event->u.Timer.Link);
+ Event->u.Timer.Link.ForwardLink = NULL;
+ }
+
+ Event->u.Timer.TriggerTime = 0;
+ Event->u.Timer.Period = 0;
+
+ if (Type != TimerCancel) {
+
+ if (Type == TimerPeriodic) {
+ Event->u.Timer.Period = TriggerTime;
+ }
+
+ Event->u.Timer.TriggerTime = CoreCurrentSystemTime () + TriggerTime;
+ CoreInsertEventTimer (Event);
+
+ if (TriggerTime == 0) {
+ CoreSignalEvent (mEfiCheckTimerEvent);
+ }
+ }
+
+ CoreReleaseLock (&mEfiTimerLock);
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_DXE/tpl.c b/Core/CORE_DXE/tpl.c
new file mode 100644
index 0000000..3ac99fc
--- /dev/null
+++ b/Core/CORE_DXE/tpl.c
@@ -0,0 +1,198 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ tpl.c
+
+Abstract:
+
+ Task priority function
+
+--*/
+
+#include "exec.h"
+
+STATIC
+VOID
+CoreSetInterruptState (
+ IN BOOLEAN Enable
+ )
+/*++
+
+Routine Description:
+
+ Set Interrupt State
+
+Arguments:
+
+ Enable - The state of enable or disable interrupt
+
+Returns:
+
+ None
+
+--*/
+
+{
+ if (gCpu != NULL) {
+ if (Enable) {
+ gCpu->EnableInterrupt(gCpu);
+ } else {
+ gCpu->DisableInterrupt(gCpu);
+ }
+ }
+}
+
+//
+// Return the highest set bit
+//
+UINTN
+CoreHighestSetBit (
+ IN UINTN Number
+ )
+/*++
+
+Routine Description:
+
+ Return the highest set bit
+
+Arguments:
+
+ Number - The value to check
+
+Returns:
+
+ Bit position of the highest set bit
+
+--*/
+{
+ UINTN msb;
+
+ msb = 31;
+ while ((msb > 0) && ((Number & ((UINTN)1 << msb)) == 0)) {
+ msb--;
+ }
+
+ return msb;
+}
+
+
+EFI_BOOTSERVICE
+EFI_TPL
+EFIAPI
+CoreRaiseTpl (
+ IN EFI_TPL NewTpl
+ )
+/*++
+
+Routine Description:
+
+ Raise the task priority level to the new level.
+ High level is implemented by disabling processor interrupts.
+
+Arguments:
+
+ NewTpl - New task priority level
+
+Returns:
+
+ The previous task priority level
+
+--*/
+{
+ EFI_TPL OldTpl;
+
+ OldTpl = gEfiCurrentTpl;
+ ASSERT (OldTpl <= NewTpl);
+ ASSERT (VALID_TPL (NewTpl));
+
+ //
+ // If raising to high level, disable interrupts
+ //
+ if (NewTpl >= EFI_TPL_HIGH_LEVEL && OldTpl < EFI_TPL_HIGH_LEVEL) {
+ CoreSetInterruptState (FALSE);
+ }
+
+ //
+ // Set the new value
+ //
+ gEfiCurrentTpl = NewTpl;
+
+ return OldTpl;
+}
+
+
+EFI_BOOTSERVICE
+VOID
+EFIAPI
+CoreRestoreTpl (
+ IN EFI_TPL NewTpl
+ )
+/*++
+
+Routine Description:
+
+ Lowers the task priority to the previous value. If the new
+ priority unmasks events at a higher priority, they are dispatched.
+
+Arguments:
+
+ NewTpl - New, lower, task priority
+
+Returns:
+
+ None
+
+--*/
+{
+ EFI_TPL OldTpl;
+
+ OldTpl = gEfiCurrentTpl;
+ ASSERT (NewTpl <= OldTpl);
+ ASSERT (VALID_TPL (NewTpl));
+
+ //
+ // If lowering below HIGH_LEVEL, make sure
+ // interrupts are enabled
+ //
+
+ if (OldTpl >= EFI_TPL_HIGH_LEVEL && NewTpl < EFI_TPL_HIGH_LEVEL) {
+ gEfiCurrentTpl = EFI_TPL_HIGH_LEVEL;
+ }
+
+ //
+ // Dispatch any pending events
+ //
+
+ while ((-2 << NewTpl) & gEventPending) {
+ gEfiCurrentTpl = CoreHighestSetBit (gEventPending);
+ if (gEfiCurrentTpl < EFI_TPL_HIGH_LEVEL) {
+ CoreSetInterruptState (TRUE);
+ }
+ CoreDispatchEventNotifies (gEfiCurrentTpl);
+ }
+
+ //
+ // Set the new value
+ //
+
+ gEfiCurrentTpl = NewTpl;
+
+ //
+ // If lowering below HIGH_LEVEL, make sure
+ // interrupts are enabled
+ //
+ if (gEfiCurrentTpl < EFI_TPL_HIGH_LEVEL) {
+ CoreSetInterruptState (TRUE);
+ }
+
+}
diff --git a/Core/CORE_PEI/AmiPeiInit.c b/Core/CORE_PEI/AmiPeiInit.c
new file mode 100644
index 0000000..33931ae
--- /dev/null
+++ b/Core/CORE_PEI/AmiPeiInit.c
@@ -0,0 +1,887 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PeiMain/AmiPeiInit.c 24 5/13/11 5:10p Artems $
+//
+// $Revision: 24 $
+//
+// $Date: 5/13/11 5:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PeiMain/AmiPeiInit.c $
+//
+// 24 5/13/11 5:10p Artems
+// Added functions CopyMem and ZeroMem for PEI build
+//
+// 23 3/22/11 5:20p Felixp
+// LOAD_HOB processing and AmiInitParts-related code has been restructured
+// to achieve the following goals:
+// - Support LOAD_HOB in PI mode
+// - Reduce amount of PI version specific code
+// - Minimize number of patches in the EDK portion of code
+// - Eliminate global variables
+// - Simplify the implementation
+//
+// 22 3/09/11 5:53p Artems
+// Removed usage of global pointer InitFunction. Fixed bug in
+// MigrateIdtTable with wrong IdtBase
+//
+// 21 3/08/11 10:22a Artems
+// Fixed bug in MigrateIdtTable, where IdtBase assigned wrong address
+//
+// 20 3/04/11 4:06p Artems
+// Modified FindPPI function to work with both FV hob types
+//
+// 19 2/05/11 3:42p Artems
+// Added PI 1.0 support
+//
+// 18 9/22/10 7:13p Felixp
+// Imrpovement: gEfiStatusCodeSpecificDataGuid variable is added. Used by
+// PEI Core to report status codes.
+//
+// 17 8/20/10 3:26p Felixp
+// LZMA compression support: ReadSection function updated.
+//
+// 16 8/28/09 3:08p Felixp
+// More generic FindFv PPI implementation. Old implementation was assuming
+// that boot FV is described by the first FV HOB.
+//
+// 15 8/27/09 1:58p Felixp
+// AmiInitParts is updated to call InitFunction once when AmiInitParts is
+// called multiple times.
+//
+// 14 7/30/09 4:46p Vyacheslava
+// Fixed comments.
+//
+// 13 7/28/09 4:56p Vyacheslava
+// Minor bug fix. EIP#24453: Synopsis: CPU exception when printing long
+// debug messages.
+//
+// 12 5/04/09 3:09p Felixp
+// Creation of CPU HOB moved from AmiPeiInit.c to AmiDxeInit.c
+//
+// 11 8/07/07 2:24p Felixp
+// Additional Status Codes added
+//
+// 10 3/12/07 10:26a Felixp
+// LoadedImage PPI support added (defined in PI 1.0; used by AmiDebugger)
+//
+// 8 10/18/06 11:30a Felixp
+// LoadFile updated to return EFI_LOAD_ERROR when image format is invalid
+//
+// 7 8/24/06 9:43a Felixp
+// Preliminary x64 support (work in progress)
+// DXE Core interfaces are no longer passed from PEI Core.
+// They are linked directly with DXE Core
+//
+// 6 6/04/06 9:20p Ambikas
+//
+// 5 5/30/06 7:06p Yakovlevs
+// Fixed STACK HOB memory type from ConventionalMemory to EfiLoaderData.
+//
+// 4 5/20/06 12:58a Felixp
+//
+// 3 5/20/06 12:36a Felixp
+// checkpoints added
+//
+// 2 5/19/06 10:38p Felixp
+// Clean up
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiPeiInit.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiHobs.h>
+#include <AmiPeiLib.h>
+#include <PPI/LoadFile.h>
+#include <PPI/LoadedImagePpi.h>
+#include <PPI/Decompress.h>
+#include <StatusCodes.h>
+
+typedef VOID (*INIT_PARTS)(VOID* p1, VOID*p2);
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitParts2(VOID* p1, VOID*p2);
+
+EFI_GUID gEfiStatusCodeSpecificDataGuid = EFI_STATUS_CODE_SPECIFIC_DATA_GUID;
+
+//defined in PeiMain.c
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+);
+////////////// from PeiCore.c
+#if PI_SPECIFICATION_VERSION<0x00010000
+EFI_PEI_SERVICES **ppPS = NULL;
+#endif
+
+VOID InitPartsMem(VOID* p1, VOID*p2)
+{
+#if PI_SPECIFICATION_VERSION<0x00010000
+ ppPS = (EFI_PEI_SERVICES**)p2;
+#endif
+ InitParts2(p1,p2);
+}
+
+#if PI_SPECIFICATION_VERSION<0x00010000
+EFI_STATUS FvLoadFile(
+ IN EFI_PEI_FV_FILE_LOADER_PPI *This,
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
+ OUT UINT64 *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+);
+
+// PPIs
+EFI_PEI_FV_FILE_LOADER_PPI FileLoader = {FvLoadFile};
+
+// PPI to be installed
+EFI_GUID gPeiLoadFilePpiGuid = EFI_PEI_FV_FILE_LOADER_GUID;
+static EFI_PEI_PPI_DESCRIPTOR FileLoaderPpi[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiLoadFilePpiGuid, &FileLoader
+ }
+};
+
+EFI_STATUS ReadSection(
+ EFI_PEI_SERVICES **ppPS, IN EFI_SECTION_TYPE SectionType,
+ IN EFI_FFS_FILE_HEADER *pFile, OUT VOID **ppData
+)
+{
+ EFI_STATUS Status;
+ UINT32 SrcSize, DstSize, TmpSize;
+ VOID *pSrc;
+ EFI_PHYSICAL_ADDRESS DstAddress;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHob;
+ EFI_COMPRESSION_SECTION_HEADER *pCompressionSection;
+ if (!ppData) return EFI_INVALID_PARAMETER;
+ //TODO: Support for GUIDed sections
+ Status = (*ppPS)->FfsFindSectionData(
+ ppPS, SectionType, pFile, &pSrc
+ );
+ if (!EFI_ERROR(Status)){*ppData=pSrc; return Status; }
+ Status = (*ppPS)->FfsFindSectionData(
+ ppPS, EFI_SECTION_COMPRESSION,
+ pFile, &pCompressionSection
+ );
+ if (EFI_ERROR(Status)) return Status;
+ SrcSize = FVSECTION_SIZE(pCompressionSection) - sizeof(EFI_COMPRESSION_SECTION_HEADER);
+ pSrc = pCompressionSection + 1;
+ if (pCompressionSection->CompressionType!=EFI_NOT_COMPRESSED){
+ GET_INFO GetInfoPtr;
+ DECOMPRESS DecompressPtr;
+ BOOLEAN KnownCompressionType = GetDecompressInterface(
+ pCompressionSection->CompressionType,
+ &GetInfoPtr, &DecompressPtr
+ );
+ if (!KnownCompressionType) return EFI_UNSUPPORTED;
+ Status = GetInfoPtr(pSrc, SrcSize, &DstSize, &TmpSize);
+ if (EFI_ERROR(Status)) return Status;
+ //No FreePool, so the memory is never freed
+ Status = (*ppPS)->AllocatePages(
+ ppPS,EfiBootServicesCode,(DstSize>>12)+1,&DstAddress
+ );
+ if (EFI_ERROR(Status)) return Status;
+ (*ppPS)->GetHobList(ppPS,&pHob);
+ if (pHob->EfiFreeMemoryTop - pHob->EfiFreeMemoryBottom < TmpSize)
+ return EFI_OUT_OF_RESOURCES;
+ Status = DecompressPtr(
+ pSrc, SrcSize, (VOID*)DstAddress, DstSize,
+ (VOID*)pHob->EfiFreeMemoryBottom, TmpSize
+ );
+ if (EFI_ERROR(Status)) return Status;
+ pSrc = (VOID*)(UINTN)DstAddress;
+ }
+ do {
+ if (((EFI_COMMON_SECTION_HEADER*)pSrc)->Type==SectionType){
+ *ppData = (EFI_COMMON_SECTION_HEADER*)pSrc+1;
+ return EFI_SUCCESS;
+ }
+ TmpSize = FVSECTION_SIZE(pSrc);
+ TmpSize += (4 - (TmpSize & 3)) & 3;
+ if (TmpSize>=DstSize) return EFI_NOT_FOUND;
+ DstSize -= TmpSize;
+ pSrc = (UINT8*)pSrc + TmpSize;
+ }while(TRUE);
+}
+
+EFI_STATUS LoadFile(
+ EFI_PEI_SERVICES **ppPS,
+ IN EFI_FFS_FILE_HEADER *pFfsHeader,
+ OUT VOID **ppFfsImageAddress,
+ OUT EFI_PHYSICAL_ADDRESS *pImageAddress,
+ OUT UINT64 *pImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *pEntryPoint
+)
+{
+ VOID *pData;
+ EFI_STATUS Status;
+ UINTN Size;
+ if (!pEntryPoint || !pImageAddress) return EFI_INVALID_PARAMETER;
+ Status = ReadSection(ppPS, EFI_SECTION_PE32, pFfsHeader, &pData);
+ //TODO: add TE support ???
+ if (EFI_ERROR(Status)) return Status;
+ Size = GetImageSize(pData);
+ if (EFI_ERROR((*ppPS)->AllocatePages(
+ ppPS, EfiBootServicesCode,
+ (Size >> 12)+1, pImageAddress)
+ )
+ ) return EFI_OUT_OF_RESOURCES;
+
+ *pEntryPoint = (EFI_PHYSICAL_ADDRESS)LoadPeImage(pData,(UINT8*)*pImageAddress);
+ if (!*pEntryPoint) return EFI_LOAD_ERROR;
+ if (pImageSize) *pImageSize = Size;
+ if (ppFfsImageAddress) *ppFfsImageAddress = pData;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS FvLoadFile(
+ IN EFI_PEI_FV_FILE_LOADER_PPI *This,
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddress,
+ OUT UINT64 *ImageSize,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint
+)
+{
+ return LoadFile(ppPS,FfsHeader,NULL,ImageAddress,ImageSize,EntryPoint);
+}
+
+typedef VOID (*PEICORE_INMEM_ENTRY_POINT)(
+ EFI_PHYSICAL_ADDRESS Delta,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+);
+
+VOID SwitchCoreStacks(
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1,
+ IN UINTN Parameter2,
+ IN VOID *NewStack
+);
+
+VOID PeiCoreMemEntry(
+ EFI_PHYSICAL_ADDRESS Delta,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+)
+{
+ ppPS = PeiServices;
+ if (Delta)
+ {
+ PEI_TRACE((TRACE_PEICORE,PeiServices,"PEI core reallocated to memory\n"));
+ // intall file loader
+ (*ppPS)->InstallPpi(ppPS, FileLoaderPpi);
+ }
+ SwitchCoreStacks(
+ (UINT8*)PeiCoreEntryPoint+(UINTN)Delta,Parameter1,Parameter2,NewStack
+ );
+}
+
+VOID AmiSwitchToMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *PeiCoreEntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+)
+{
+ //reallocate ourself to memory
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+ EFI_PHYSICAL_ADDRESS NewAddress, EntryPoint;
+ VOID *pOldAddress;
+ UINT64 Size;
+ EFI_FFS_FILE_HEADER* pFile=NULL;
+ PEI_PROGRESS_CODE(PeiServices,PEI_MEMORY_INSTALLED);
+ // if we already in memory just call memory routine
+ //TODO: if (pData->pLoader) PeiCoreInMem(pData, 0);
+ //find our FFS file header
+ //PEI Core must be in boot FV.
+ //Boot FV must be the first one returned by FfsFindNextVolume
+ (*PeiServices)->FfsFindNextVolume (PeiServices, 0, &pFV);
+ //No error checking. Since if we are here, the file is in the FV, so we should be able to find it.
+ (*PeiServices)->FfsFindNextFile (PeiServices, EFI_FV_FILETYPE_PEI_CORE, pFV, &pFile);
+ if (EFI_ERROR(LoadFile(PeiServices,pFile,&pOldAddress,&NewAddress,&Size,&EntryPoint))){
+ //if we don't have enough memory, don't install FileLoader PPI
+ PeiCoreMemEntry(0,PeiServices,PeiCoreEntryPoint,Parameter1,Parameter2,NewStack);
+ }else{
+ //Update LoadedImage PPI information
+ UpdatedLoadedImagePpi(PeiServices,NewAddress,Size,pFile);
+ ((PEICORE_INMEM_ENTRY_POINT)(
+ (UINT8*)PeiCoreMemEntry-(UINT8*)pOldAddress+(UINT8*)NewAddress
+ ))(NewAddress-(UINT64)(UINTN)pOldAddress,PeiServices,PeiCoreEntryPoint,Parameter1,Parameter2,NewStack);
+ }
+}
+
+typedef struct {
+ UINTN BootFirmwareVolume;
+ UINTN SizeOfCacheAsRam;
+ EFI_PEI_PPI_DESCRIPTOR *DispatchTable;
+} EFI_PEI_STARTUP_DESCRIPTOR;
+
+EFI_STATUS EFIAPI PeiMain(
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+);
+
+VOID PeiCoreEntry(
+ EFI_PEI_STARTUP_DESCRIPTOR StartUpDescriptor
+)
+{
+ checkpoint(0x10);
+ PeiMain(&StartUpDescriptor);
+}
+
+#include <PPI/FindFv.h>
+
+EFI_STATUS FindFv(
+ IN EFI_FIND_FV_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ UINT8 *FvNumber,
+ EFI_FIRMWARE_VOLUME_HEADER **FVAddress
+)
+{
+ UINT8 Instance;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFv;
+ EFI_HOB_GENERIC_HEADER *HobPointer;
+ EFI_STATUS Status;
+
+ if (!FVAddress || !FvNumber)
+ return EFI_INVALID_PARAMETER;
+
+ Status = (*PeiServices)->FfsFindNextVolume(PeiServices, 0, &BootFv);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if (*FvNumber == 0) { //0 is always Boot FV
+ *FVAddress = BootFv;
+ (*FvNumber)++;
+ return Status;
+ }
+
+ Instance = *FvNumber;
+ Status = (*PeiServices)->GetHobList(PeiServices, &HobPointer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ while(HobPointer->HobType != EFI_HOB_TYPE_END_OF_HOB_LIST) {
+ if(HobPointer->HobType == EFI_HOB_TYPE_FV || HobPointer->HobType == EFI_HOB_TYPE_FV2) {
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER *)((EFI_HOB_FIRMWARE_VOLUME *)HobPointer)->BaseAddress;
+ if (Fv == BootFv) {
+ HobPointer = NextHob(HobPointer, EFI_HOB_GENERIC_HEADER);
+ continue;
+ }
+
+ if (Instance == 1) {
+ *FVAddress = Fv;
+ (*FvNumber)++;
+ return EFI_SUCCESS;
+ }
+ Instance--;
+ }
+ HobPointer = NextHob(HobPointer, EFI_HOB_GENERIC_HEADER);
+ }
+ return EFI_OUT_OF_RESOURCES; //EFI_NOT_FOUND;
+}
+
+EFI_GUID gPeiFindFvPpiGuid = EFI_FIND_FV_PPI_GUID;
+
+// PPIs
+EFI_FIND_FV_PPI FindFvPpi = {FindFv};
+
+// PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR FindFvPpiDescriptor[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiFindFvPpiGuid, &FindFvPpi
+ }
+};
+
+EFI_STATUS EFIAPI InstallFindFv(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices,FindFvPpiDescriptor);
+}
+#else //#if PI_SPECIFICATION_VERSION<0x00010000
+
+EFI_STATUS DecompressPpiDecompress(
+ IN CONST EFI_PEI_DECOMPRESS_PPI *This,
+ IN CONST EFI_COMPRESSION_SECTION *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize
+){
+ EFI_STATUS Status;
+ UINT32 SrcSize, DstSize, TmpSize;
+ VOID *pSrc;
+ EFI_PHYSICAL_ADDRESS DstAddress;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHob;
+ EFI_COMPRESSION_SECTION_HEADER *pCompressionSection;
+
+ if (!OutputBuffer || !OutputSize) return EFI_INVALID_PARAMETER;
+
+ pCompressionSection = (EFI_COMPRESSION_SECTION_HEADER*)&InputSection->UncompressedLength;
+ SrcSize = FVSECTION_SIZE(pCompressionSection) - sizeof(EFI_COMPRESSION_SECTION_HEADER);
+ pSrc = pCompressionSection + 1;
+ if (pCompressionSection->CompressionType!=EFI_NOT_COMPRESSED){
+ GET_INFO GetInfoPtr;
+ DECOMPRESS DecompressPtr;
+ EFI_PEI_SERVICES **ppPS = GetPeiServicesTablePointer();
+ BOOLEAN KnownCompressionType = GetDecompressInterface(
+ pCompressionSection->CompressionType,
+ &GetInfoPtr, &DecompressPtr
+ );
+ if (!KnownCompressionType) return EFI_UNSUPPORTED;
+ Status = GetInfoPtr(pSrc, SrcSize, &DstSize, &TmpSize);
+ if (EFI_ERROR(Status)) return Status;
+ //No FreePool, so the memory is never freed
+ Status = (*ppPS)->AllocatePages(
+ ppPS,EfiBootServicesCode,(DstSize>>12)+1,&DstAddress
+ );
+ if (EFI_ERROR(Status)) return Status;
+ (*ppPS)->GetHobList(ppPS,&pHob);
+ if (pHob->EfiFreeMemoryTop - pHob->EfiFreeMemoryBottom < TmpSize)
+ return EFI_OUT_OF_RESOURCES;
+ Status = DecompressPtr(
+ pSrc, SrcSize, (VOID*)DstAddress, DstSize,
+ (VOID*)pHob->EfiFreeMemoryBottom, TmpSize
+ );
+ if (EFI_ERROR(Status)) return Status;
+ *OutputBuffer = (VOID*)(UINTN)DstAddress;
+ *OutputSize = DstSize;
+ }else{
+ *OutputBuffer = pSrc;
+ *OutputSize = SrcSize;
+ }
+ return EFI_SUCCESS;
+}
+
+// PPI to be installed
+EFI_PEI_DECOMPRESS_PPI DecomppressInterface = {DecompressPpiDecompress};
+static EFI_PEI_PPI_DESCRIPTOR DecompressPpi[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiDecompressPpiGuid, &DecomppressInterface
+ }
+};
+
+
+EFI_STATUS EFIAPI InstallDecompressionPpi(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices, DecompressPpi);
+}
+
+EFI_STATUS PeiMain(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList);
+
+VOID PeiCoreEntry(
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList)
+{
+ checkpoint(0x10);
+ PeiMain(SecCoreData,PpList);
+}
+#endif //#else branch of #if PI_SPECIFICATION_VERSION<0x00010000
+
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, INIT_PARTS InitFunctionPtr)
+{
+ if (InitFunctionPtr == NULL)
+ return;
+
+ (InitFunctionPtr)(NULL, PeiServices);
+}
+
+VOID ProcessLoadHob(IN EFI_PEI_SERVICES **PeiServices)
+{
+ static EFI_GUID LoadHobGuid = AMI_PEIM_LOAD_HOB_GUID;
+ PEIM_LOAD_HOB *LoadHob;
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->GetHobList(PeiServices,&LoadHob);
+ if (EFI_ERROR(Status)) return;
+ // Load PEIMs
+ while(!EFI_ERROR(FindNextHobByGuid(&LoadHobGuid, &LoadHob)))
+ {
+ EFI_PHYSICAL_ADDRESS Address,EntryPoint, ModuleDelta;
+ UINT64 Size;
+ // if file header is NULL, the entry is in the PEI Core binary
+ if (LoadHob->pFfsHeader == NULL) continue;
+ Status = PeiLoadFile(
+ PeiServices,LoadHob->pFfsHeader,&Address,&Size,&EntryPoint
+ );
+ if (EFI_ERROR(Status)) continue;
+ ModuleDelta = EntryPoint - (UINT64)LoadHob->EntryPoint;
+ if (ModuleDelta==0) continue; // the module was not loaded
+#ifdef EFI_DEBUG
+{
+ char sName[0x100];
+ EFI_FFS_FILE_HEADER *PeimFileHeader = LoadHob->pFfsHeader;
+
+ if (!GetName((VOID*)(UINTN)Address,sName))
+ Sprintf_s(sName,sizeof(sName),"[%G]",&PeimFileHeader->Name);
+ PeiTrace(
+ TRACE_PEICORE, PeiServices, "%s.InMemEntry(%X)\n", sName,
+ (UINT64)LoadHob->InMemEntryPoint+ModuleDelta
+ );
+}
+#endif
+ ((EFI_PEIM_ENTRY_POINT)(
+ (UINT64)LoadHob->InMemEntryPoint+ModuleDelta
+ ))(LoadHob->pFfsHeader, PeiServices);
+ }
+}
+
+EFI_STATUS
+PeiBuildHobStack (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the Stack
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the Stack
+
+ Length - The length of the stack in bytes
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_ALLOCATION_STACK *Hob;
+ static EFI_GUID gEfiHobMemeryAllocStackGuid=EFI_HOB_MEMORY_ALLOC_STACK_GUID;
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_MEMORY_ALLOCATION,
+ sizeof (EFI_HOB_MEMORY_ALLOCATION_STACK),
+ &Hob
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Hob->AllocDescriptor.Name = gEfiHobMemeryAllocStackGuid;
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = EfiLoaderData;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PeiBuildHobMemoryAllocation (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_GUID *Name,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the memory allocation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the memory
+
+ Length - The length of the memory allocation in bytes
+
+ Name - Name for Hob
+
+ MemoryType - Memory type
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_ALLOCATION *Hob;
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_MEMORY_ALLOCATION,
+ sizeof (EFI_HOB_MEMORY_ALLOCATION),
+ &Hob
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Name != NULL) {
+ Hob->AllocDescriptor.Name = *Name;
+ } else {
+ (*PeiServices)->SetMem(&(Hob->AllocDescriptor.Name), sizeof (EFI_GUID), 0);
+ }
+
+ Hob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
+ Hob->AllocDescriptor.MemoryLength = Length;
+ Hob->AllocDescriptor.MemoryType = MemoryType;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+PeiBuildHobGuid (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN DataLength,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Builds a custom HOB that is tagged with a GUID for identification
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Guid - The GUID of the custome HOB type
+
+ DataLength - The size of the data payload for the GUIDed HOB
+
+ Hob - Pointer to the Hob
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->CreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ (UINT16) (sizeof (EFI_HOB_GUID_TYPE) + DataLength),
+ Hob
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ((EFI_HOB_GUID_TYPE *)(*Hob))->Name = *Guid;
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN CompareGuid (IN EFI_GUID *Guid1,IN EFI_GUID *Guid2)
+{
+ return !MemCmp(Guid1,Guid2,sizeof(EFI_GUID));
+}
+
+VOID CopyMem (
+ IN VOID *Destination, IN VOID *Source, IN UINTN Length
+)
+{
+ MemCpy (Destination, Source, Length);
+}
+
+VOID ZeroMem(IN VOID *Buffer, IN UINTN Size)
+{
+ MemSet(Buffer,Size,0);
+}
+
+#ifdef EFI_DEBUG
+ VOID
+ PeiDebugAssert (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ )
+ {
+ PeiTrace(TRACE_ALWAYS,PeiServices,"ASSERT in %s on %i: %s\n",FileName, LineNumber, Description);
+ EFI_DEADLOOP()
+ }
+
+ VOID
+ PeiDebugPrint (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ )
+ {
+ CHAR8 Buffer[256];
+ va_list ArgList = va_start(ArgList,Format);
+ PrepareStatusCodeString( Buffer, sizeof(Buffer), Format, ArgList );
+ (*PeiServices)->ReportStatusCode (
+ (EFI_PEI_SERVICES**)PeiServices, EFI_DEBUG_CODE,
+ EFI_SOFTWARE_UNSPECIFIED, 0, NULL,
+ (EFI_STATUS_CODE_DATA *)Buffer
+ );
+ va_end(ArgList);
+ }
+#endif
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+#pragma pack (1)
+typedef struct {
+ UINT16 Limit;
+ UINTN Base;
+} DESCRIPTOR_TABLE;
+#pragma pack()
+
+VOID CPULib_LoadIdt(DESCRIPTOR_TABLE *Idt);
+VOID CPULib_SaveIdt(DESCRIPTOR_TABLE *Idt);
+
+/*++
+
+Routine Description:
+
+ Invalidates a range of instruction cache lines in the cache coherency domain
+ of the calling CPU.
+
+ Invalidates the instruction cache lines specified by Address and Length. If
+ Address is not aligned on a cache line boundary, then entire instruction
+ cache line containing Address is invalidated. If Address + Length is not
+ aligned on a cache line boundary, then the entire instruction cache line
+ containing Address + Length -1 is invalidated. This function may choose to
+ invalidate the entire instruction cache if that is more efficient than
+ invalidating the specified range. If Length is 0, the no instruction cache
+ lines are invalidated. Address is returned.
+
+ If Length is greater than (EFI_MAX_ADDRESS - Address + 1), then ASSERT().
+
+Arguments:
+
+ Address - The base address of the instruction cache lines to
+ invalidate. If the CPU is in a physical addressing mode, then
+ Address is a physical address. If the CPU is in a virtual
+ addressing mode, then Address is a virtual address.
+
+ Length - The number of bytes to invalidate from the instruction cache.
+
+ Returns:
+ Address
+
+**/
+VOID MigrateIdtTable (IN EFI_PEI_SERVICES **PeiServices){
+ UINTN Size;
+ VOID *NewIdtBase;
+ EFI_STATUS Status;
+ DESCRIPTOR_TABLE IdtDescriptor;
+
+ CPULib_SaveIdt(&IdtDescriptor);
+
+ Size = sizeof(EFI_PEI_SERVICES**) + (IdtDescriptor.Limit + 1);
+ Status = (*PeiServices)->AllocatePool (PeiServices, Size, &NewIdtBase);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ (*PeiServices)->CopyMem (
+ (VOID*)((UINTN)NewIdtBase + sizeof(EFI_PEI_SERVICES**)),
+ (VOID*)IdtDescriptor.Base, (IdtDescriptor.Limit + 1)
+ );
+
+ IdtDescriptor.Base = (UINTN)NewIdtBase + sizeof(EFI_PEI_SERVICES**);
+ CPULib_LoadIdt(&IdtDescriptor);
+ SetPeiServicesTablePointer(PeiServices);
+}
+/**
+Routine Description:
+
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches target the buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT().
+
+Arguments:
+
+ Buffer - Pointer to the target buffer to scan.
+ Length - Number of bytes in Buffer to scan.
+ Guid - Value to search for in the target buffer.
+
+Returns:
+ A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+**/
+VOID *ScanGuid (IN VOID *Buffer, IN UINTN Length, IN EFI_GUID *Guid){
+ EFI_GUID *GuidPtr;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer();
+ PEI_ASSERT(PeiServices, (((UINTN)Buffer & (sizeof (Guid->Data1) - 1)) == 0));
+ PEI_ASSERT(PeiServices, (Length <= (0xFFFFFFFF - (UINTN)Buffer + 1)));
+ PEI_ASSERT(PeiServices, ((Length & (sizeof (*GuidPtr) - 1)) == 0));
+
+ GuidPtr = (EFI_GUID*)Buffer;
+ Buffer = GuidPtr + Length / sizeof (*GuidPtr);
+ while (GuidPtr < (EFI_GUID*)Buffer) {
+ if (!guidcmp (GuidPtr, Guid)) {
+ return (VOID*)GuidPtr;
+ }
+ GuidPtr++;
+ }
+ return NULL;
+}
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEI.cif b/Core/CORE_PEI/CORE_PEI.cif
new file mode 100644
index 0000000..fb412a8
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CORE_PEI"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\"
+ RefName = "CORE_PEI"
+[files]
+"CORE_PEI.sdl"
+"CORE_PEI.mak"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEI.mak b/Core/CORE_PEI/CORE_PEI.mak
new file mode 100644
index 0000000..fa25508
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI.mak
@@ -0,0 +1,163 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/CORE_PEI/CORE_PEI.mak 6 5/01/09 6:12p Felixp $
+#
+# $Revision: 6 $
+#
+# $Date: 5/01/09 6:12p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/CORE_PEI/CORE_PEI.mak $
+#
+# 6 5/01/09 6:12p Felixp
+# Bug fix(EIP 19816). $(AMICSPLib) is linked with CORE_PEI module
+# (Used to be linked with NVRAM library that caused problems on systems
+# without Core Sources).
+#
+# 5 8/24/06 9:17a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 4 12/02/05 11:15a Felixp
+# @set INCLUDE=%%INCLUDE%% removed since it's not needed.
+#
+# 3 6/16/05 10:47a Felixp
+# 1. variables from NVRAMTokens.c moved to Tokens.c
+# 2. PeiCoreMemoryInstalled initialization list added
+#
+# 2 2/11/05 5:46p Felixp
+# Binary files organization improved:
+# - extra layer of sub-component removed
+# - macros initialization moved to SDL tokens to eliminate undefined
+# macros situation
+# - debug and release binaries have different names now (workaround for
+# VeB limitation)
+#
+# 1 1/28/05 12:44p Felixp
+#
+# 3 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 1 12/23/04 9:42a Felixp
+#
+# 2 11/01/04 8:06a Felixp
+#
+# 1 7/12/04 6:33p Felixp
+#
+# 24 3/29/04 2:32a Felixp
+#
+# 23 3/28/04 2:11p Felixp
+# 1. PE Loader and some other commonly used code moved to the Library
+# 2. Warnings fixed (from now on warning will be treated as error)
+#
+# 22 3/23/04 4:56p Felixp
+#
+# 21 3/20/04 12:03p Felixp
+#
+# 20 3/19/04 11:12a Robert
+#
+# 19 2/19/04 10:08a Felixp
+# Debugging code removed.
+#
+# 18 2/10/04 1:24p Felixp
+#
+# 17 2/06/04 2:46a Felixp
+# - Support for VC6 tools
+# - bug fixes
+# - component AddOn added
+#
+# 16 2/04/04 2:04a Felixp
+# work in progress...
+#
+# 15 1/28/04 3:24a Felixp
+#
+# 14 1/22/04 12:47p Felixp
+#
+# 13 1/19/04 4:23p Felixp
+# work in progress...
+#
+# 12 1/18/04 8:34a Felixp
+# 1. From now on, OBJ files are created in a component specific
+# subdirectory of $(BUILD_DIR)
+# 2. New files added
+#
+# 11 1/15/04 11:05a Felixp
+# hob.c and ffs.c files added
+#
+# 10 1/06/04 5:28p Yakovlevs
+#
+# 9 1/06/04 4:03p Felixp
+#
+# 8 1/06/04 11:26a Felixp
+#
+# 7 1/02/04 5:39p Robert
+#
+# 6 12/30/03 5:54p Robert
+#
+# 5 12/23/03 9:34a Felixp
+# dependency from the makefile added
+#
+# 4 12/12/03 12:23p Felixp
+#
+# 3 12/12/03 12:07p Robert
+# Added Pci Cfg and Cpu Io obj references to the mak file
+#
+# 2 12/12/03 11:29a Felixp
+# PEICORE_OBJECTS and PEICORE_HEADERS variables created
+#
+# 1 12/05/03 4:15p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Pei.mak
+#
+# Description: PeiCore makefile:
+# -Builds EXE File
+# -Invokes FFS.Mak to build PeiCore.FFS
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CORE_PEI
+
+CORE_PEI : $(BUILD_DIR)\CORE_PEI.mak CORE_PEIBin
+
+$(BUILD_DIR)\CORE_PEI.mak : $(CORE_PEI_DIR)\$(@B).cif $(CORE_PEI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CORE_PEI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CORE_PEIBin : $(AMIPEILIB) $(CORE_PEI_LIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CORE_PEI.mak all\
+ GUID=92685943-D810-47ff-A112-CC8490776A1F \
+ ENTRY_POINT=PeiCoreEntry \
+ TYPE=PEI_CORE LIBRARIES= \
+ COMPRESS=0\
+ EXT_HEADERS=$(BUILD_DIR)\token.h\
+ "INIT_LIST=$(PeiCoreInitialize)"\
+ "INIT_LIST2=$(PeiCoreMemoryInstalled)"\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEI.sdl b/Core/CORE_PEI/CORE_PEI.sdl
new file mode 100644
index 0000000..9177b10
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI.sdl
@@ -0,0 +1,97 @@
+TOKEN
+ Name = "CORE_PEI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CORE_PEI support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "CORE_PEI_DIR"
+End
+
+MODULE
+ Help = "Includes CORE_PEI.mak to Project"
+ File = "CORE_PEI.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CORE_PEI.ffs"
+ Parent = "FV_BB"
+ Help = "PEI Core"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiCoreInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CpuIoInit,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PciCfgInit,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiInitDxeIpl,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CORE_PEI_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(CORE_PEI_DIR)\CORE_PEI$(ARCH)$(DBG).lib"
+ Parent = "CORE_PEI_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiCoreMemoryInstalled"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiInitNV,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallFindFv,"
+ Parent = "PeiCoreInitialize"
+ Token = "PI_SPECIFICATION_VERSION" "<" "0x10000"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InstallDecompressionPpi,"
+ Parent = "PeiCoreMemoryInstalled"
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x10000"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CpuIoMemInit,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PciCfgMemInit,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CORE_PEI/CORE_PEISrc.cif b/Core/CORE_PEI/CORE_PEISrc.cif
new file mode 100644
index 0000000..c9f5317
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEISrc.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "CORE_PEI Source(EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\"
+ RefName = "CORE_PEISrc_EDK"
+[files]
+"CORE_PEISrc.sdl"
+"CORE_PEISrc.mak"
+"AmiPeiInit.c"
+"CpuIo.c"
+"PciCfg.c"
+"DxeIpl.c"
+"PeiPerf.c"
+[parts]
+"CORE_PEISrcFramework_EDK"
+"CORE_PEISrcPI_EDK"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEISrc.mak b/Core/CORE_PEI/CORE_PEISrc.mak
new file mode 100644
index 0000000..32036c2
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEISrc.mak
@@ -0,0 +1,103 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/PeiMain/CORE_PEISrc.mak 11 2/05/11 3:41p Artems $
+#
+# $Revision: 11 $
+#
+# $Date: 2/05/11 3:41p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/PeiMain/CORE_PEISrc.mak $
+#
+# 11 2/05/11 3:41p Artems
+# Added support to build source in PI 0.91 or PI 1.0 mode
+#
+# 10 3/05/09 1:07p Felixp
+# Minor improvements:
+# - Unconditional optimization (despite debug flag settings) is removed
+# - Headers updated
+#
+# 9 8/25/06 10:58a Felixp
+#
+# 8 8/25/06 10:57a Felixp
+#
+# 7 8/25/06 10:56a Felixp
+#
+# 6 8/24/06 9:43a Felixp
+# Preliminary x64 support (work in progress)
+# DXE Core interfaces are no longer passed from PEI Core.
+# They are linked directly with DXE Core
+#
+# 5 5/20/06 12:34a Felixp
+# Optimization is always on
+#
+# 4 5/19/06 10:37p Felixp
+#
+# 3 3/17/06 4:28p Felixp
+#
+# 2 3/13/06 5:25p Felixp
+#
+# 1 3/13/06 1:57a Felixp
+#
+# 2 12/02/05 11:19a Felixp
+#
+# 1 1/28/05 12:44p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CORE_PEISrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CORE_PEI_LIB
+
+$(CORE_PEI_LIB) : CORE_PEI_LIB
+
+CORE_PEI_LIB : $(BUILD_DIR)\CORE_PEISrc.mak CORE_PEI_LIBBin
+
+$(BUILD_DIR)\CORE_PEISrc.mak : $(CORE_PEI_SRC_DIR)\$(@B).cif $(CORE_PEI_SRC_DIR)\$(@B).mak $(BUILD_RULES)
+!IF $(PI_SPECIFICATION_VERSION)>=0x00010000
+ $(CIF2MAK) $(CORE_PEI_SRC_DIR)\$(@B).cif $(CORE_PEI_SRC_DIR)\CORE_PEI_PI\$(@B)Pi.cif $(CIF2MAK_DEFAULTS)
+!ELSE
+ $(CIF2MAK) $(CORE_PEI_SRC_DIR)\$(@B).cif $(CORE_PEI_SRC_DIR)\CORE_PEI_FRAMEWORK\$(@B)Framework.cif $(CIF2MAK_DEFAULTS)
+!ENDIF
+
+CORE_PEI_LIBBin : $(BUILD_DIR)\FoundationPei.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CORE_PEISrc.mak all\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(CORE_PEI_LIB)\
+ "MY_INCLUDES=/I$(Foundation_DIR)"\
+!IF "$(x64_BUILD)"=="1"
+ "MY_DEFINES=/Dx64_BUILD_SUPPORT"\
+!ENDIF
+ EXT_HEADERS=$(BUILD_DIR)\token.h NAME=CORE_PEISrc
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEISrc.sdl b/Core/CORE_PEI/CORE_PEISrc.sdl
new file mode 100644
index 0000000..1c62c64
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEISrc.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "DXE_STACK_SIZE"
+ Value = "0x100000"
+ Help = "Size of DXE Stack"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CORE_PEISrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CORE_PEI Source support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "CORE_PEI_SRC_DIR"
+End
+
+MODULE
+ Help = "Includes CORE_PEISrc.mak to Project"
+ File = "CORE_PEISrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CORE_PEI.lib"
+ Parent = "$(CORE_PEI_DIR)\CORE_PEI$(ARCH)$(DBG).lib"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c
new file mode 100644
index 0000000..782950a
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/BootMode.c
@@ -0,0 +1,108 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ BootMode.c
+
+Abstract:
+
+ EFI PEI Core Boot Mode services
+
+
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ if (BootMode == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ *BootMode = HandOffHob->BootMode;
+
+
+ return EFI_SUCCESS;
+};
+
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ HandOffHob->BootMode = BootMode;
+
+
+ return EFI_SUCCESS;
+};
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif
new file mode 100644
index 0000000..9c5a51e
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/CORE_PEISrcFramework.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "CORE_PEI Source Framework (EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\CORE_PEI_FRAMEWORK"
+ RefName = "CORE_PEISrcFramework_EDK"
+[files]
+"BootMode.c"
+"dependency.c"
+"dependency.h"
+"Dispatcher.c"
+"FwVol.c"
+"Hob.c"
+"Image.c"
+"MemoryServices.c"
+"PeiCore.h"
+"PeiMain.c"
+"Ppi.c"
+"Reset.c"
+"Security.c"
+"StatusCode.c"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c
new file mode 100644
index 0000000..c82752f
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Dispatcher.c
@@ -0,0 +1,604 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Dispatcher.c
+
+Abstract:
+
+ EFI PEI Core dispatch services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+
+EFI_STATUS
+TransferOldDataToNewDataRange (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ OUT UINTN *PrivateDataInMem
+ );
+
+EFI_GUID gEfiPeiCorePrivateGuid = EFI_PEI_CORE_PRIVATE_GUID;
+//*** AMI PORTING BEGIN ***//
+VOID AmiSwitchToMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *EntryPoint,
+ IN UINTN Parameter1, IN UINTN Parameter2,
+ IN VOID *NewStack
+);
+//*** AMI PORTING END *****//
+
+EFI_STATUS
+PeiDispatcher (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_DISPATCH_DATA *DispatchData
+ )
+
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
+ PrivateData - Pointer to the private data passed in from caller
+ DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_CORE_TEMP_POINTERS TempPtr;
+ UINTN PrivateDataInMem;
+ BOOLEAN NextFvFound;
+ EFI_FIRMWARE_VOLUME_HEADER *NextFvAddress;
+ EFI_FIRMWARE_VOLUME_HEADER *DefaultFvAddress;
+
+ //
+ // Debug data for uninstalled Peim list
+ //
+ PEI_DEBUG_CODE (
+
+ UINT64 DebugNotDispatchedBitmap;
+ EFI_GUID DebugFoundPeimList[64];
+ UINT8 DebugFoundPeimPoint;
+
+ )
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
+
+ ExtendedData.DataHeader.HeaderSize = (UINT16)sizeof (EFI_STATUS_CODE_DATA);
+ ExtendedData.DataHeader.Size = (UINT16)(sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - ExtendedData.DataHeader.HeaderSize);
+
+ PeiCoreCopyMem (
+ &ExtendedData.DataHeader.Type,
+ &gEfiStatusCodeSpecificDataGuid,
+ sizeof (EFI_GUID)
+ );
+ )
+ //
+ // save the Current FV Address so that we will not process it again if FindFv returns it later
+ //
+ DefaultFvAddress = DispatchData->BootFvAddress;
+
+ //
+ // This is the main dispatch loop. It will search known FVs for PEIMs and
+ // attempt to dispatch them. If any PEIM gets dispatched through a single
+ // pass of the dispatcher, it will start over from the Bfv again to see
+ // if any new PEIMs dependencies got satisfied. With a well ordered
+ // FV where PEIMs are found in the order their dependencies are also
+ // satisfied, this dipatcher should run only once.
+ //
+ for (;;) {
+ //
+ // This is the PEIM search loop. It will scan through all PEIMs it can find
+ // looking for PEIMs to dispatch, and will dipatch them if they have not
+ // already been dispatched and all of their dependencies are met.
+ // If no more PEIMs can be found in this pass through all known FVs,
+ // then it will break out of this loop.
+ //
+ for (;;) {
+
+ Status = FindNextPeim (
+ &PrivateData->PS,
+ DispatchData->CurrentFvAddress,
+ &DispatchData->CurrentPeimAddress
+ );
+
+ //
+ // If we found a PEIM, check if it is dispatched. If so, go to the
+ // next PEIM. If not, dispatch it if its dependencies are satisfied.
+ // If its dependencies are not satisfied, go to the next PEIM.
+ //
+ if (Status == EFI_SUCCESS) {
+
+ PEI_DEBUG_CODE (
+
+ //
+ // Fill list of found Peims for later list of those not installed
+ //
+ PeiCoreCopyMem (
+ &DebugFoundPeimList[DispatchData->CurrentPeim],
+ &DispatchData->CurrentPeimAddress->Name,
+ sizeof (EFI_GUID)
+ );
+
+ )
+
+ if (!Dispatched (
+ DispatchData->CurrentPeim,
+ DispatchData->DispatchedPeimBitMap
+ )) {
+ if (DepexSatisfied (&PrivateData->PS, DispatchData->CurrentPeimAddress)) {
+ Status = PeiLoadImage (
+ &PrivateData->PS,
+ DispatchData->CurrentPeimAddress,
+ &TempPtr.Raw
+ );
+ if (Status == EFI_SUCCESS) {
+
+ //
+ // The PEIM has its dependencies satisfied, and its entry point
+ // has been found, so invoke it.
+ //
+ PEI_PERF_START (
+ &PrivateData->PS,
+ L"PEIM",
+ (EFI_FFS_FILE_HEADER *)(DispatchData->CurrentPeimAddress),
+ 0
+ );
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ ExtendedData.Handle = (EFI_HANDLE)DispatchData->CurrentPeimAddress;
+
+ )
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ PeiReportStatusCode (
+ &(PrivateData->PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+
+ )
+
+ //
+ // Is this a authentic image
+ //
+ Status = VerifyPeim (
+ &PrivateData->PS,
+ DispatchData->CurrentPeimAddress
+ );
+
+ if (Status != EFI_SECURITY_VIOLATION) {
+
+ Status = TempPtr.PeimEntry (
+ DispatchData->CurrentPeimAddress,
+ &PrivateData->PS
+ );
+ }
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ PeiReportStatusCode (
+ &(PrivateData->PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+
+ )
+ PEI_PERF_END (&PrivateData->PS, L"PEIM", (EFI_FFS_FILE_HEADER *)(DispatchData->CurrentPeimAddress), 0);
+
+ //
+ // Mark the PEIM as dispatched so we don't attempt to run it again
+ //
+ SetDispatched (
+ &PrivateData->PS,
+ DispatchData->CurrentPeim,
+ &DispatchData->DispatchedPeimBitMap
+ );
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (&PrivateData->PS);
+
+ //
+ // If real system memory was discovered and installed by this
+ // PEIM, switch the stacks to the new memory. Since we are
+ // at dispatch level, only the Core's private data is preserved,
+ // nobody else should have any data on the stack.
+ //
+ if (PrivateData->SwitchStackSignal) {
+ TempPtr.PeiCore = PeiCore;
+ Status = TransferOldDataToNewDataRange (
+ PrivateData,
+ &PrivateDataInMem
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ //Subtract 0x10 from the 4th parameter indicating the new stack base,
+ //in order to provide buffer protection against possible illegal stack
+ //access that might corrupt the stack.
+ //
+//*** AMI PORTING BEGIN ***//
+ AmiSwitchToMemory (
+ &((PEI_CORE_INSTANCE*)PrivateDataInMem)->PS,
+ //SwitchCoreStacks (
+//*** AMI PORTING END *****//
+ TempPtr.Raw,
+ (UINTN)PeiStartupDescriptor,
+ PrivateDataInMem,
+ (VOID *)((UINTN)PrivateData->StackBase + (UINTN)PrivateData->StackSize - 0x10)
+ );
+ }
+ }
+ }
+ }
+ DispatchData->CurrentPeim++;
+ continue;
+
+ } else {
+
+ //
+ // If we could not find another PEIM in the current FV, go try
+ // the FindFv PPI to look in other FVs for more PEIMs. If we can
+ // not locate the FindFv PPI, or if the FindFv PPI can not find
+ // anymore FVs, then exit the PEIM search loop.
+ //
+ if (DispatchData->FindFv == NULL) {
+ Status = PeiLocatePpi (
+ &PrivateData->PS,
+ &gEfiFindFvPpiGuid,
+ 0,
+ NULL,
+ &DispatchData->FindFv
+ );
+ if (Status != EFI_SUCCESS) {
+ break;
+ }
+ }
+ NextFvFound = FALSE;
+ while (!NextFvFound) {
+ Status = DispatchData->FindFv->FindFv (
+ DispatchData->FindFv,
+ &PrivateData->PS,
+ &DispatchData->CurrentFv,
+ &NextFvAddress
+ );
+ //
+ // if there is no next fv, get out of this loop of finding FVs
+ //
+ if (Status != EFI_SUCCESS) {
+ break;
+ }
+ //
+ // don't process the default Fv again. (we don't know the order in which the hobs were created)
+ //
+ if ((NextFvAddress != DefaultFvAddress) &&
+ (NextFvAddress != DispatchData->CurrentFvAddress)) {
+
+ //
+ // VerifyFv() is currently returns SUCCESS all the time, add code to it to
+ // actually verify the given FV
+ //
+ Status = VerifyFv (NextFvAddress);
+ if (Status == EFI_SUCCESS) {
+ NextFvFound = TRUE;
+ DispatchData->CurrentFvAddress = NextFvAddress;
+ DispatchData->CurrentPeimAddress = NULL;
+ //
+ // current PRIM number (CurrentPeim) must continue as is, don't reset it here
+ //
+ }
+ }
+ }
+ //
+ // if there is no next fv, get out of this loop of dispatching PEIMs
+ //
+ if (!NextFvFound) {
+ break;
+ }
+ //
+ // continue in the inner for(;;) loop with a new FV;
+ //
+ }
+ }
+
+ //
+ // If all the PEIMs that we have found have been dispatched, then
+ // there is nothing left to dispatch and we don't need to go search
+ // through all PEIMs again.
+ //
+ if ((~(DispatchData->DispatchedPeimBitMap) &
+ (LShiftU64 (1, DispatchData->CurrentPeim)-1)) == 0) {
+ break;
+ }
+
+ //
+ // Check if no more PEIMs that depex was satisfied
+ //
+ if (DispatchData->DispatchedPeimBitMap == DispatchData->PreviousPeimBitMap) {
+ break;
+ }
+
+ //
+ // Case when Depex is not satisfied and has to traverse the list again
+ //
+ DispatchData->CurrentPeim = 0;
+ DispatchData->CurrentPeimAddress = 0;
+ DispatchData->PreviousPeimBitMap = DispatchData->DispatchedPeimBitMap;
+
+ //
+ // don't go back to the loop without making sure that the CurrentFvAddress is the
+ // same as the 1st (or default) FV we started with. otherwise we will interpret the bimap wrongly and
+ // mess it up, always start processing the PEIMs from the default FV just like in the first time around.
+ //
+ DispatchData->CurrentFv = 0;
+ DispatchData->CurrentFvAddress = DefaultFvAddress;
+ }
+
+ PEI_DEBUG_CODE (
+
+ DebugFoundPeimPoint = 0;
+ //
+ // Get bitmap of Peims that were not dispatched,
+ //
+
+ DebugNotDispatchedBitmap = ((DispatchData->DispatchedPeimBitMap) ^ (LShiftU64 (1, DispatchData->CurrentPeim)-1));
+ //
+ // Scan bitmap of Peims not installed and print GUIDS
+ //
+ while (DebugNotDispatchedBitmap != 0) {
+ if ((DebugNotDispatchedBitmap & 1) != 0) {
+ PEI_DEBUG (
+ (&PrivateData->PS, EFI_D_INFO,
+ "WARNING -> PEIM Not Dispatched: %g\n",
+ &DebugFoundPeimList[DebugFoundPeimPoint])
+ );
+ }
+ DebugFoundPeimPoint++;
+ DebugNotDispatchedBitmap = RShiftU64 (DebugNotDispatchedBitmap, 1);
+ }
+
+ )
+
+ return EFI_NOT_FOUND;
+}
+
+VOID
+InitializeDispatcherData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+Returns:
+
+ None.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ if (OldCoreData == NULL) {
+ PrivateData->DispatchData.CurrentFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;
+ PrivateData->DispatchData.BootFvAddress = (EFI_FIRMWARE_VOLUME_HEADER *) PeiStartupDescriptor->BootFirmwareVolume;
+ } else {
+
+ //
+ // Current peim has been dispatched, but not count
+ //
+ PrivateData->DispatchData.CurrentPeim = (UINT8)(OldCoreData->DispatchData.CurrentPeim + 1);
+ }
+
+ return;
+}
+
+
+BOOLEAN
+Dispatched (
+ IN UINT8 CurrentPeim,
+ IN UINT64 DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine checks to see if a particular PEIM has been dispatched during
+ the PEI core dispatch.
+
+Arguments:
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ TRUE - PEIM already dispatched
+ FALSE - Otherwise
+
+--*/
+{
+ return (BOOLEAN)((DispatchedPeimBitMap & LShiftU64 (1, CurrentPeim)) != 0);
+}
+
+VOID
+SetDispatched (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CurrentPeim,
+ OUT UINT64 *DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine sets a PEIM as having been dispatched once its entry
+ point has been invoked.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ None
+
+--*/
+{
+ //
+ // Check if the total number of PEIMs exceed the bitmap.
+ // CurrentPeim is 0-based
+ //
+PEI_DEBUG_CODE (
+ if (CurrentPeim > (sizeof (*DispatchedPeimBitMap) * 8 - 1)) {
+ ASSERT_PEI_ERROR (PeiServices, EFI_OUT_OF_RESOURCES);
+ }
+)
+ *DispatchedPeimBitMap |= LShiftU64 (1, CurrentPeim);
+ return;
+}
+
+BOOLEAN
+DepexSatisfied (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+ PeiServices - The PEI Service Table
+ CurrentPeimAddress - Address of the PEIM Firmware File under investigation
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+{
+ EFI_STATUS Status;
+ INT8 *DepexData;
+ BOOLEAN Runnable;
+
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_PEI_DEPEX,
+ CurrentPeimAddress,
+ &DepexData
+ );
+ //
+ // If there is no DEPEX, assume the module can be executed
+ //
+ if (EFI_ERROR (Status)) {
+ return TRUE;
+ }
+
+ //
+ // Evaluate a given DEPEX
+ //
+ Status = PeimDispatchReadiness (
+ PeiServices,
+ DepexData,
+ &Runnable
+ );
+
+ return Runnable;
+}
+
+
+EFI_STATUS
+TransferOldDataToNewDataRange (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ OUT UINTN *PrivateDataInMem
+ )
+/*++
+
+Routine Description:
+
+ This routine transfers the contents of the pre-permanent memory
+ PEI Core private data to a post-permanent memory data location.
+
+Arguments:
+ PrivateData - Pointer to the current PEI Core private data pre-permanent memory
+ PrivateDataInMem - Pointer to the PrivateData once the private data has been transferred
+ to permanent memory
+
+Returns:
+ EFI_SUCCESS - Successfully transfered
+ EFI_ERROR - Fail to transfer
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = PeiBuildHobGuid (
+ &(PrivateData->PS),
+ &gEfiPeiCorePrivateGuid,
+ sizeof (PEI_CORE_INSTANCE),
+ (VOID*)PrivateDataInMem
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ (*PrivateDataInMem) += sizeof (EFI_HOB_GUID_TYPE);
+ PrivateData->PS->CopyMem (
+ (VOID*)(*PrivateDataInMem),
+ (VOID*)PrivateData,
+ sizeof (PEI_CORE_INSTANCE)
+ );
+
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c
new file mode 100644
index 0000000..14eb90c
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/FwVol.c
@@ -0,0 +1,488 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVol.c
+
+Abstract:
+
+ Pei Core Firmware File System service routines.
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImageFormat.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#define GETOCCUPIEDSIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState(
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Returns the highest bit set of the State field
+
+Arguments:
+
+ ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
+ in the Attributes field.
+ FfsHeader - Pointer to FFS File Header.
+
+Returns:
+ Returns the highest bit in the State field
+
+--*/
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+/*++
+
+Routine Description:
+
+ Calculates the checksum of the header of a file.
+
+Arguments:
+
+ FileHeader - Pointer to FFS File Header.
+
+Returns:
+ Checksum of the header.
+
+ The header is zero byte checksum.
+ - Zero means the header is good.
+ - Non-zero means the header is bad.
+
+
+Bugbug: For PEI performance reason, we comments this code at this time.
+--*/
+{
+ UINT8 *ptr;
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+ ptr = (UINT8 *)FileHeader;
+
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ Sum = (UINT8)(Sum + ptr[Index+1]);
+ Sum = (UINT8)(Sum + ptr[Index+2]);
+ Sum = (UINT8)(Sum + ptr[Index+3]);
+ }
+
+ for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ }
+
+ //
+ // State field (since this indicates the different state of file).
+ //
+ Sum = (UINT8)(Sum - FileHeader->State);
+ //
+ // Checksum field of the file is not part of the header checksum.
+ //
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+STATIC
+EFI_STATUS
+PeiFfsFindNextFileEx (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **FileHeader,
+ IN BOOLEAN Flag
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+ Flag - Indicator for if this is for PEI Dispath search
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+ UINT32 FileOffset;
+ UINT64 FvLength;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+
+
+ FvLength = FwVolHeader->FvLength;
+ if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // If FileHeader is not specified (NULL) start with the first file in the
+ // firmware volume. Otherwise, start from the FileHeader.
+ //
+ if (*FileHeader == NULL) {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ } else {
+ //
+ // Length is 24 bits wide so mask upper 8 bits
+ // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
+ }
+
+ FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
+ PEI_ASSERT (PeiServices, (FileOffset <= 0xFFFFFFFF));
+
+ while (FileOffset < (FvLength - sizeof(EFI_FFS_FILE_HEADER))) {
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) == 0) {
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
+ if (Flag) {
+ if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
+
+ *FileHeader = FfsFileHeader;
+
+
+ return EFI_SUCCESS;
+ }
+ } else {
+ if ((SearchType == FfsFileHeader->Type) ||
+ (SearchType == EFI_FV_FILETYPE_ALL)) {
+
+ *FileHeader = FfsFileHeader;
+
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ } else {
+//*** AMI PORTING BEGIN ***//
+// Skip the assert to support a more sophisiticated
+// FV corruption handling outside of the Core.
+// PEI_ASSERT (PeiServices, (0));
+//*** AMI PORTING END *****//
+ return EFI_NOT_FOUND;
+ }
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GETOCCUPIEDSIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ return EFI_NOT_FOUND;
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,
+ IN OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FfsFileHeader - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+ UINT32 SectionLength;
+ UINT32 ParsedLength;
+
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // Does not include FfsFileHeader header size
+ // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
+ FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileSize -= sizeof(EFI_FFS_FILE_HEADER);
+
+ *SectionData = NULL;
+ ParsedLength = 0;
+ while (ParsedLength < FileSize) {
+ if (Section->Type == SectionType) {
+ *SectionData = (VOID *)(Section + 1);
+
+
+ return EFI_SUCCESS;
+ }
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GETOCCUPIEDSIZE (SectionLength, 4);
+ PEI_ASSERT (PeiServices, SectionLength != 0);
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+EFI_STATUS
+FindNextPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ PeimFileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ return PeiFfsFindNextFileEx (
+ PeiServices,
+ 0,
+ FwVolHeader,
+ PeimFileHeader,
+ TRUE
+ );
+}
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **FileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ return PeiFfsFindNextFileEx (
+ PeiServices,
+ SearchType,
+ FwVolHeader,
+ FileHeader,
+ FALSE
+ );
+}
+
+EFI_STATUS
+EFIAPI
+PeiFvFindNextVolume (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
+ )
+/*++
+
+Routine Description:
+
+ Return the Firmware Volume instance requested
+
+ BugBug -- Move this to the location of this code to where the
+ other FV and FFS support code lives.
+ Also, update to use FindFV for instances #'s >= 1.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Instance - Instance of FV to find
+ FwVolHeader - Pointer to contain the data to return
+
+Returns:
+ Pointer to the Firmware Volume instance requested
+
+ EFI_INVALID_PARAMETER - FwVolHeader is NULL
+
+ EFI_SUCCESS - Firmware volume instance successfully found.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_STATUS Status;
+ EFI_FIND_FV_PPI *FindFvPpi;
+ UINT8 LocalInstance;
+
+
+ LocalInstance = (UINT8) Instance;
+
+ Status = EFI_SUCCESS;
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ if (FwVolHeader == NULL) {
+
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Instance == 0) {
+ //
+ // If instance is 0, the first firmware volume must be BFV.
+ //
+ *FwVolHeader = PrivateData->DispatchData.BootFvAddress;
+
+
+ return Status;
+ } else {
+ //
+ // Locate all instances of FindFV
+ // Alternately, could use FV HOBs, but the PPI is cleaner
+ //
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gEfiFindFvPpiGuid,
+ 0,
+ NULL,
+ &FindFvPpi
+ );
+
+ if (Status != EFI_SUCCESS) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ Status = FindFvPpi->FindFv (
+ FindFvPpi,
+ PeiServices,
+ &LocalInstance,
+ FwVolHeader
+ );
+
+ }
+ }
+ return Status;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c
new file mode 100644
index 0000000..cffbf6c
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Hob.c
@@ -0,0 +1,198 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Hob.c
+
+Abstract:
+
+ EFI PEI Core HOB services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+
+ //
+ // Only check this parameter in debug mode
+ //
+
+ PEI_DEBUG_CODE (
+ if (HobList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ )
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ *HobList = PrivateData->HobList.Raw;
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+
+
+ Status = PeiGetHobList (PeiServices, Hob);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ HandOffHob = *Hob;
+
+ Length = (UINT16)((Length + 0x7) & (~0x7));
+
+ FreeMemory = HandOffHob->EfiFreeMemoryTop -
+ HandOffHob->EfiFreeMemoryBottom;
+
+ if (FreeMemory < Length) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;
+
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+
+ Hob = (VOID *)(UINTN)MemoryBegin;
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
+ Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+ Hob->Header.Reserved = 0;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ Hob->BootMode = BootMode;
+
+ Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiMemoryBottom = MemoryBegin;
+ Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c
new file mode 100644
index 0000000..8ccbd68
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Image.c
@@ -0,0 +1,341 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Image.c
+
+Abstract:
+
+ Pei Core Load Image Support
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (LoadFile)
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *PeimFileHeader,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Routine for loading file image.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeimFileHeader - Pointer to the FFS file header of the image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+{
+ EFI_STATUS Status;
+ VOID *Pe32Data;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_PEI_FV_FILE_LOADER_PPI *FvLoadFilePpi;
+#ifdef EFI_NT_EMULATOR
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ NT_PEI_LOAD_FILE_PPI *PeiNtService;
+ EFI_PHYSICAL_ADDRESS NtEntryPoint;
+#endif
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ EFI_PHYSICAL_ADDRESS ImageEntryPoint;
+ EFI_TE_IMAGE_HEADER *TEImageHeader;
+ UINT16 Machine;
+
+ PEI_DEBUG_CODE (ImageAddress = 0;)
+
+ *EntryPoint = NULL;
+ TEImageHeader = NULL;
+ PeHdr = NULL;
+ //
+ // Try to find a PE32 section.
+ //
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_PE32,
+ PeimFileHeader,
+ &Pe32Data
+ );
+ //
+ // If we didn't find a PE32 section, try to find a TE section.
+ //
+ if (Status != EFI_SUCCESS) {
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_TE,
+ PeimFileHeader,
+ (VOID **) &TEImageHeader
+ );
+ Pe32Data = (VOID *) TEImageHeader;
+ }
+ if (Status == EFI_SUCCESS) {
+ if (TEImageHeader == NULL) {
+ if (((EFI_IMAGE_DOS_HEADER *) Pe32Data)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) Pe32Data)->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+ }
+ Machine = PeHdr->FileHeader.Machine;
+//*** AMI PORTING BEGIN ***//
+//This is needed to enable execution of the PEIMS
+//from the firmware volumes in memory.
+ if ( PeHdr->OptionalHeader.ImageBase
+ !=(UINTN)Pe32Data
+ ) Status=EFI_NOT_FOUND;
+//Init ImageSize for to pass into UpdatedLoadedImagePpi
+ ImageSize = PeHdr->OptionalHeader.SizeOfImage;
+//*** AMI PORTING END *****//
+ } else {
+//*** AMI PORTING BEGIN ***//
+ Machine = TEImageHeader->Machine;
+//This is needed to enable execution of the PEIMS
+//from the firmware volumes in memory.
+//The following two lines are not needed because
+//we don't support reallocation of TE image into memory.
+// if ( TEImageHeader->ImageBase!=(UINTN)(TEImageHeader))
+// Status=EFI_NOT_FOUND;
+
+//Init ImageSize for to pass into UpdatedLoadedImagePpi.
+//Let's get size from the FFS section header
+ ImageSize = FVSECTION_SIZE(TEImageHeader);
+//*** AMI PORTING END *****//
+ }
+ //
+ // Check PEIM image machine. A PEIM image for different processor architecture
+ // from the host can't be started.
+ //
+ if (Machine != EFI_IMAGE_MACHINE_TYPE) {
+ return EFI_UNSUPPORTED;
+ }
+
+#ifdef EFI_NT_EMULATOR
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gNtPeiLoadFileGuid,
+ 0,
+ &PpiDescriptor,
+ &PeiNtService
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PeiNtService->PeiLoadFileService (
+ Pe32Data,
+ &ImageAddress,
+ &ImageSize,
+ &NtEntryPoint
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (TEImageHeader != NULL) {
+ *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ }
+ } else {
+ *EntryPoint = (VOID *) (UINTN) NtEntryPoint;
+ }
+
+#else
+ ImageAddress = (EFI_PHYSICAL_ADDRESS) (UINTN) Pe32Data;
+ if (TEImageHeader != NULL) {
+ *EntryPoint = (VOID *)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ }
+#endif
+//*** AMI PORTING BEGIN ***//
+// } else {
+ }
+ if (Status!=EFI_SUCCESS){
+//*** AMI PORTING END *****//
+ //
+ // There was not a PE32 section, so assume that it's a Compressed section
+ // and use the LoadFile
+ //
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiFvFileLoaderPpiGuid,
+ 0,
+ NULL,
+ &FvLoadFilePpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = FvLoadFilePpi->FvLoadFile (
+ FvLoadFilePpi,
+ PeimFileHeader,
+ &ImageAddress,
+ &ImageSize,
+ &ImageEntryPoint
+ );
+
+ if (!EFI_ERROR (Status)) {
+ *EntryPoint = (VOID *) ((UINTN) ImageEntryPoint);
+ if (((EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress)->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ TEImageHeader = (EFI_TE_IMAGE_HEADER *) (UINTN) ImageAddress;
+ Machine = TEImageHeader->Machine;
+ } else {
+ if (((EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress)->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) ImageAddress + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) (UINTN) ImageAddress)->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) (UINTN) ImageAddress;
+ }
+ Machine = PeHdr->FileHeader.Machine;
+ }
+ //
+ // Check PEIM image machine. A PEIM image for different processor architecture
+ // from the host can't be started.
+ //
+ if (Machine != EFI_IMAGE_MACHINE_TYPE) {
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+ }
+//*** AMI PORTING BEGIN ***//
+//Message is printed later. Disable this one
+/*
+ PEI_DEBUG_CODE (
+ {
+ EFI_IMAGE_DATA_DIRECTORY * DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY * DebugEntry;
+ UINTN DirCount;
+ UINTN Index;
+ UINTN Index1;
+ BOOLEAN FileNameFound;
+ CHAR8 *AsciiString;
+ CHAR8 AsciiBuffer[512];
+ VOID *CodeViewEntryPointer;
+ INTN TEImageAdjust;
+
+ if (Status == EFI_SUCCESS) {
+ //
+ // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
+ //
+ PEI_DEBUG ((PeiServices, EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", (UINTN) ImageAddress, *EntryPoint));
+
+ //
+ // Find the codeview info in the image and display the file name
+ // being loaded.
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ DebugEntry = NULL;
+ DirectoryEntry = NULL;
+ TEImageAdjust = 0;
+ if (TEImageHeader == NULL) {
+ if (PeHdr->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHdr->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);
+ }
+ } else {
+ if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+ DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +
+ TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
+ TEImageAdjust);
+ }
+ }
+
+ if (DebugEntry != NULL && DirectoryEntry != NULL) {
+ for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ if (DebugEntry->SizeOfData > 0) {
+ CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ default:
+ AsciiString = NULL;
+ break;
+ }
+ if (AsciiString != NULL) {
+ FileNameFound = FALSE;
+ for (Index = 0, Index1 = 0; AsciiString[Index] != 0; Index++) {
+ if (AsciiString[Index] == '\\') {
+ Index1 = Index;
+ FileNameFound = TRUE;
+ }
+ }
+
+ if (FileNameFound) {
+ for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {
+ AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];
+ }
+ AsciiBuffer[Index - (Index1 + 1)] = 0;
+ PEI_DEBUG ((PeiServices, EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ PEI_DEBUG ((PeiServices, EFI_D_INFO | EFI_D_LOAD, "\n"));
+ }
+ }
+ )
+*/
+#ifdef EFI_DEBUG
+if (!EFI_ERROR (Status)){
+ char sName[0x100];
+ if (!GetName((VOID*)(UINTN)ImageAddress,sName)) Sprintf_s(sName,sizeof(sName),"[%G]",&PeimFileHeader->Name);
+ PeiTrace(TRACE_PEICORE, PeiServices, "%s.Entry(%X)\n", sName, *EntryPoint);
+}
+else PeiTrace(TRACE_PEICORE, PeiServices, "ERROR: attempt to load FFS file [%G] has failed\n", &PeimFileHeader->Name);
+#endif
+//New image is loaded and is about to be launched
+//Update LoadedImage PPI information
+if (!EFI_ERROR (Status))
+ UpdatedLoadedImagePpi(PeiServices,ImageAddress,ImageSize,PeimFileHeader);
+//*** AMI PORTING END *****//
+ return Status;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c
new file mode 100644
index 0000000..9566e02
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/MemoryServices.c
@@ -0,0 +1,440 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ MemoryServices.c
+
+Abstract:
+
+ EFI PEI Core memory services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiApi.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+//*** AMI PORTING BEGIN ***//
+//use SDL token 'DXE_STACK_SIZE' to define stack size
+#include <Token.h>
+#undef PEI_STACK_SIZE
+#define PEI_STACK_SIZE DXE_STACK_SIZE
+//*** AMI PORTING END *****//
+
+VOID
+InitializeMemoryServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT64 SizeOfCarHeap;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+ PrivateData->SwitchStackSignal = FALSE;
+
+ if (OldCoreData == NULL) {
+
+ PrivateData->PeiMemoryInstalled = FALSE;
+
+//*** AMI PORTING BEGIN ***//
+//The original method of getting CAR top and bootom addresses assumes that CAR base address is aligned
+//on CAR size boundary, which is not always the case.
+//Make the algorithm more flexible
+//Comment out the old code:
+// PrivateData->BottomOfCarHeap = (VOID *) (((UINTN)(VOID *)(&PrivateData))
+// & (~((PeiStartupDescriptor->SizeOfCacheAsRam) - 1)));
+// PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + PeiStartupDescriptor->SizeOfCacheAsRam);
+//New code:
+// Private data is located towards the top of the stack.
+// The stack is located at the top of the CAR.
+// We assume that:
+// 1) CAR address and size are at least 1K aligned.
+// 2) Not more than 1K of Stack is used by SEC phase.
+// The top of the CAR should be the next 1K boundary
+//NOTE: New PI 1.0 spec provides a better solution.
+//It expends SEC to PI hand off structure to explicitly pass CAR address
+//This code will be changed once PI support is added.
+#define CAR_ADDRESS_AND_SIZE_ALIGNMENT 0x400
+ PrivateData->TopOfCarHeap = (VOID *)(
+ (((UINTN)(VOID *)(&PrivateData))+CAR_ADDRESS_AND_SIZE_ALIGNMENT)
+ & (~(CAR_ADDRESS_AND_SIZE_ALIGNMENT-1))
+ );
+ PrivateData->BottomOfCarHeap = (VOID *)(
+ (UINTN)(PrivateData->TopOfCarHeap)
+ - PeiStartupDescriptor->SizeOfCacheAsRam
+ );
+//*** AMI PORTING END *****//
+ //
+ // SizeOfCarHeap is 1/2 (arbitrary) of CacheAsRam Size.
+ //
+ SizeOfCarHeap = (UINT64) PeiStartupDescriptor->SizeOfCacheAsRam;
+ SizeOfCarHeap = RShiftU64 (SizeOfCarHeap, 1);
+
+ PEI_DEBUG_CODE (
+ {
+ PrivateData->SizeOfCacheAsRam = PeiStartupDescriptor->SizeOfCacheAsRam;
+ PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) SizeOfCarHeap);
+ }
+ )
+
+ PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
+
+ PeiCoreBuildHobHandoffInfoTable (
+ BOOT_WITH_FULL_CONFIGURATION,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
+ (UINTN) SizeOfCarHeap
+ );
+ //
+ // Copy PeiServices from ROM to Cache in PrivateData
+ //
+ PeiCoreCopyMem (&(PrivateData->ServiceTableShadow), *PeiServices, sizeof (EFI_PEI_SERVICES));
+
+ //
+ // Set PS to point to ServiceTableShadow in Cache
+ //
+ PrivateData->PS = &(PrivateData->ServiceTableShadow);
+ } else {
+ //
+ // Set PS to point to ServiceTableShadow in Cache one time after the
+ // stack switched to main memory
+ //
+ PrivateData->PS = &(PrivateData->ServiceTableShadow);
+}
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
+ EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
+ UINT64 PeiStackSize;
+ UINT64 EfiFreeMemorySize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+//*** AMI PORTING BEGIN ***//
+ if (PrivateData->PeiMemoryInstalled) {
+ //This function should be called once. Report error if this is the second call
+ PEI_ERROR_CODE(PeiServices, PEI_MEMORY_INSTALLED_TWICE, EFI_ERROR_MINOR);
+ }else {
+ //Debug message
+ PEI_TRACE((TRACE_PEICORE, PeiServices, "Memory Installed: Address=%lX; Length=%lX\n",MemoryBegin,MemoryLength));
+ }
+//*** AMI PORTING END *****//
+
+ PrivateData->SwitchStackSignal = TRUE;
+ PrivateData->PeiMemoryInstalled = TRUE;
+
+ PrivateData->StackBase = MemoryBegin;
+
+ PeiStackSize = RShiftU64 (MemoryLength, 1);
+ if (PEI_STACK_SIZE > PeiStackSize) {
+ PrivateData->StackSize = PeiStackSize;
+ } else {
+ PrivateData->StackSize = PEI_STACK_SIZE;
+ }
+
+ OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
+
+ PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));
+ NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
+ PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
+
+ EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
+
+ PeiCoreCopyMem (
+ NewHandOffHob,
+ OldHandOffHob,
+ (UINTN)EfiFreeMemorySize
+ );
+
+ NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
+ NewHandOffHob->EfiMemoryBottom = MemoryBegin;
+
+ NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
+
+ NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
+ (OldHandOffHob->EfiEndOfHobList -
+ PhysicalAddressOfOldHob);
+
+ ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
+
+ PeiBuildHobStack (PeiServices, PrivateData->StackBase, PrivateData->StackSize);
+//*** AMI PORTING BEGIN ***//
+//Update LoadedImage pointers
+PrivateData->LoadedImage = (EFI_PEI_PPI_DESCRIPTOR*)
+ ( (UINTN)PrivateData->LoadedImage + ((UINTN)NewHandOffHob - (UINTN)OldHandOffHob) );
+//*** AMI PORTING END *****//
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));
+ }
+ )
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS Offset;
+ EFI_STATUS Status;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Check if Hob already available
+ //
+ if (!PrivateData->PeiMemoryInstalled) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ Hob.Raw = PrivateData->HobList.Raw;
+
+ //
+ // Check to see if on 4k boundary
+ //
+ Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
+
+ //
+ // If not aligned, make the allocation aligned.
+ //
+ if (Offset != 0) {
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
+ }
+
+ //
+ // Verify that there is sufficient memory to satisfy the allocation
+ //
+ if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
+ Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiAllocatePages fail: Pages - 0x%08x\n", Pages));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Update the PHIT to reflect the memory usage
+ //
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+
+ //
+ // Update the value for the caller
+ //
+ *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
+
+ //
+ // Create a memory allocation HOB.
+ //
+ Status = PeiBuildHobMemoryAllocation (
+ PeiServices,
+ Hob.HandoffInformationTable->EfiFreeMemoryTop,
+ Pages * EFI_PAGE_SIZE + Offset,
+ NULL,
+ MemoryType
+ );
+
+ return Status;
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_POOL *Hob;
+
+
+ Status = PeiCreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_PEI_MEMORY_POOL,
+ (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
+ &Hob
+ );
+ *Buffer = Hob+1;
+
+
+ return Status;
+}
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibCopyMem (Destination, Source, Length);
+}
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibSetMem (Buffer, Size, Value);
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h
new file mode 100644
index 0000000..24130e5
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiCore.h
@@ -0,0 +1,1260 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiCore.h
+
+Abstract:
+
+ Definition of Pei Core Structures and Services
+
+Revision History
+
+--*/
+
+#ifndef _PEICORE_H_
+#define _PEICORE_H_
+
+#include "EfiImage.h"
+#include "Pei.h"
+#include "PeiHob.h"
+
+#ifdef EFI64
+#include "SalApi.h"
+#endif
+
+#include "EfiCommonLib.h"
+
+#include EFI_PPI_DEFINITION (FindFv)
+#include EFI_PPI_DEFINITION (DxeIpl)
+#include EFI_PPI_DEFINITION (StatusCode)
+#include EFI_PPI_DEFINITION (Security)
+
+
+#ifdef EFI_NT_EMULATOR
+#include EFI_PPI_DEFINITION (NtPeiLoadFile)
+#endif
+
+//*** AMI PORTING BEGIN ***//
+#include <PPI/LoadedImagePpi.h>
+//*** AMI PORTING END *****//
+
+//
+//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range
+//
+#define EFI_PEI_CORE_PRIVATE_GUID \
+ {0xd641a0f5, 0xcb7c, 0x4846, 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9}
+
+//
+// Pei Core private data structures
+//
+typedef union _PEI_PPI_LIST_POINTERS {
+ EFI_PEI_PPI_DESCRIPTOR *Ppi;
+ EFI_PEI_NOTIFY_DESCRIPTOR *Notify;
+ VOID *Raw;
+} PEI_PPI_LIST_POINTERS;
+
+#define PEI_STACK_SIZE 0x20000
+
+#define MAX_PPI_DESCRIPTORS 128
+
+typedef struct {
+ INTN PpiListEnd;
+ INTN NotifyListEnd;
+ INTN DispatchListEnd;
+ INTN LastDispatchedInstall;
+ INTN LastDispatchedNotify;
+ PEI_PPI_LIST_POINTERS PpiListPtrs[MAX_PPI_DESCRIPTORS];
+} PEI_PPI_DATABASE;
+
+typedef struct {
+ UINT8 CurrentPeim;
+ UINT8 CurrentFv;
+ UINT64 DispatchedPeimBitMap;
+ UINT64 PreviousPeimBitMap;
+ EFI_FFS_FILE_HEADER *CurrentPeimAddress;
+ EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress;
+ EFI_FIRMWARE_VOLUME_HEADER *BootFvAddress;
+ EFI_FIND_FV_PPI *FindFv;
+} PEI_CORE_DISPATCH_DATA;
+
+
+//
+// Pei Core private data structure instance
+//
+
+#define PEI_CORE_HANDLE_SIGNATURE EFI_SIGNATURE_32('P','e','i','C')
+
+typedef struct{
+ UINTN Signature;
+ EFI_PEI_SERVICES *PS; // Point to ServiceTableShadow
+ PEI_PPI_DATABASE PpiData;
+ PEI_CORE_DISPATCH_DATA DispatchData;
+ EFI_PEI_HOB_POINTERS HobList;
+ BOOLEAN SwitchStackSignal;
+ BOOLEAN PeiMemoryInstalled;
+ EFI_PHYSICAL_ADDRESS StackBase;
+ UINT64 StackSize;
+ VOID *BottomOfCarHeap;
+ VOID *TopOfCarHeap;
+ VOID *CpuIo;
+ PEI_SECURITY_PPI *PrivateSecurityPpi;
+ EFI_PEI_SERVICES ServiceTableShadow;
+//*** AMI PORTING BEGIN ***//
+ EFI_PEI_PPI_DESCRIPTOR *LoadedImage;
+ EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+//*** AMI PORTING END *****//
+ PEI_DEBUG_CODE (
+ UINTN SizeOfCacheAsRam;
+ VOID *MaxTopOfCarHeap;
+ )
+} PEI_CORE_INSTANCE;
+
+//
+// Pei Core Instance Data Macros
+//
+
+#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \
+ PEI_CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE)
+
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CORE_ENTRY_POINT) (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ );
+
+//
+// Union of temporarily used function pointers (to save stack space)
+//
+typedef union {
+ PEI_CORE_ENTRY_POINT PeiCore;
+ EFI_PEIM_ENTRY_POINT PeimEntry;
+ EFI_PEIM_NOTIFY_ENTRY_POINT PeimNotifyEntry;
+ EFI_DXE_IPL_PPI *DxeIpl;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
+ VOID *Raw;
+} PEI_CORE_TEMP_POINTERS;
+
+
+//
+// Main PEI entry
+//
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+//
+// Dispatcher support functions
+//
+
+EFI_STATUS
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression,
+ IN OUT BOOLEAN *Runnable
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+;
+
+
+EFI_STATUS
+PeiDispatcher (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_DISPATCH_DATA *DispatchData
+ )
+
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ PeiStartupDescriptor - Pointer to IN EFI_PEI_STARTUP_DESCRIPTOR
+ PrivateData - Pointer to the private data passed in from caller
+ DispatchData - Pointer to PEI_CORE_DISPATCH_DATA data.
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+;
+
+
+VOID
+InitializeDispatcherData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+EFI_STATUS
+FindNextPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ PeimFileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+BOOLEAN
+Dispatched (
+ IN UINT8 CurrentPeim,
+ IN UINT64 DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine checks to see if a particular PEIM has been dispatched during
+ the PEI core dispatch.
+
+Arguments:
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ TRUE if PEIM already dispatched
+ FALSE if not
+
+--*/
+;
+
+VOID
+SetDispatched (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CurrentPeim,
+ OUT UINT64 *DispatchedPeimBitMap
+ )
+/*++
+
+Routine Description:
+
+ This routine sets a PEIM as having been dispatched once its entry
+ point has been invoked.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeim - The PEIM/FV in the bit array to check.
+ DispatchedPeimBitMap - Bit array, each bit corresponds to a PEIM/FV.
+
+Returns:
+ None
+
+--*/
+;
+
+BOOLEAN
+DepexSatisfied (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+ PeiServices - The PEI Service Table
+ CurrentPeimAddress - Address of the PEIM Firmware File under investigation
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+;
+
+VOID
+SwitchCoreStacks (
+ IN VOID *EntryPoint,
+ IN UINTN Parameter1,
+ IN UINTN Parameter2,
+ IN VOID *NewStack
+ )
+/*++
+
+Routine Description:
+
+ Routine for PEI switching stacks.
+
+Arguments:
+
+ EntryPoint - Entry point with new stack.
+ Parameter1 - First parameter for entry point.
+ Parameter2 - Second parameter for entry point.
+ NewStack - Pointer to new stack.
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+#ifdef EFI64
+ //
+ // In Ipf we should make special changes for the PHIT pointers to support
+ // recovery boot in cache mode.
+ //
+#define SWITCH_TO_CACHE_MODE(CoreData) SwitchToCacheMode(CoreData)
+#define CACHE_MODE_ADDRESS_MASK 0x7FFFFFFFFFFFFFFF
+VOID
+SwitchToCacheMode (
+ IN PEI_CORE_INSTANCE *CoreData
+)
+/*++
+
+Routine Description:
+
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
+
+Arguments:
+
+ CoreData - The PEI core Private Data
+
+Returns:
+
+--*/
+;
+
+#else
+
+#define SWITCH_TO_CACHE_MODE(CoreData)
+
+#endif
+
+//
+// PPI support functions
+//
+VOID
+InitializePpiServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+;
+
+VOID
+ConvertPpiPointers (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Migrate the Hob list from the CAR stack to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *OldPpi,
+ IN EFI_PEI_PPI_DESCRIPTOR *NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+;
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+;
+
+VOID
+DispatchNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+;
+
+//
+// Boot mode support functions
+//
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+;
+
+//
+// Security support functions
+//
+VOID
+InitializeSecurityServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the OEM FV verification service.
+
+Arguments:
+
+ CurrentFvAddress - Pointer to the FV under investigation.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+
+EFI_STATUS
+VerifyPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+;
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
+
+
+//
+// FFS Fw Volume support functions
+//
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 SearchType,
+ IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
+ IN OUT EFI_FFS_FILE_HEADER **FileHeader
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,
+ IN OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FfsFileHeader - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFvFindNextVolume (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **FwVolHeader
+ )
+/*++
+
+Routine Description:
+
+ Return the BFV location
+
+ BugBug -- Move this to the location of this code to where the
+ other FV and FFS support code lives.
+ Also, update to use FindFV for instances #'s >= 1.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Instance - Instance of FV to find
+ FwVolHeader - Pointer to contain the data to return
+
+Returns:
+ Pointer to the Firmware Volume instance requested
+
+ EFI_INVALID_PARAMETER - FwVolHeader is NULL
+
+ EFI_SUCCESS - Firmware volume instance successfully found.
+
+--*/
+;
+
+//
+// Memory support functions
+//
+VOID
+InitializeMemoryServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of allocation.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *PeimFileHeader,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Get entry point of a Peim file.
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ PeimFileHeader - Peim file's header.
+
+ EntryPoint - Entry point of that Peim file.
+
+Returns:
+
+ Status code.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ CodeType - Type of Status Code.
+
+ Value - Value to output for Status Code.
+
+ Instance - Instance Number of this status code.
+
+ CallerId - ID of the caller of this status code.
+
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiCoreResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+;
+//*** AMI PORTING BEGIN ***//
+//This function is used to update LoadedImage PPI information
+//LoadedImage PPI is defined in PI 1.0 specification
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+);
+
+#include <AmiPeiLib.h>
+//*** AMI PORTING END *****//
+#endif
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c
new file mode 100644
index 0000000..bfcdbe4
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/PeiMain.c
@@ -0,0 +1,405 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiMain.c
+
+Abstract:
+
+ Pei Core Main Entry Point
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (MemoryDiscovered)
+#include EFI_PPI_DEFINITION (FindFv)
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+#include EFI_GUID_DEFINITION (StatusCode)
+
+//
+//CAR is filled with this initial value during SEC phase
+//
+#define INIT_CAR_VALUE 0x5AA55AA5
+
+#ifdef EFI_PEI_PERFORMANCE
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+#endif
+
+//*** AMI PORTING BEGIN ***//
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitPartsMem(VOID* p1, VOID*p2);
+VOID ProcessLoadHob(EFI_PEI_SERVICES **PeiServices);
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, VOID* InitFunction);
+//*** AMI PORTING END *****//
+
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiMemoryDiscoveredPpiGuid,
+ NULL
+};
+
+//
+// Pei Core Module Variables
+//
+//
+static EFI_PEI_SERVICES mPS = {
+ {
+ PEI_SERVICES_SIGNATURE,
+ PEI_SERVICES_REVISION,
+ sizeof (EFI_PEI_SERVICES),
+ 0,
+ 0
+ },
+ PeiInstallPpi,
+ PeiReInstallPpi,
+ PeiLocatePpi,
+ PeiNotifyPpi,
+
+ PeiGetBootMode,
+ PeiSetBootMode,
+
+ PeiGetHobList,
+ PeiCreateHob,
+
+ PeiFvFindNextVolume,
+ PeiFfsFindNextFile,
+ PeiFfsFindSectionData,
+
+ PeiInstallPeiMemory,
+ PeiAllocatePages,
+ PeiAllocatePool,
+ PeiCoreCopyMem,
+ PeiCoreSetMem,
+
+ PeiReportStatusCode,
+
+//*** AMI PORTING BEGIN ***//
+// This is a bug fix.
+// In accordance with PEI CIS 0.91
+// this structure has been extended with two more pointers.
+// PeiCoreResetSystem
+ PeiCoreResetSystem,
+ NULL,
+ NULL
+//*** AMI PORTING END *****//
+};
+
+VOID
+EFIAPI
+AsmWriteMm7 (
+ IN UINT64 Value
+ );
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ );
+
+//
+// Main entry point to the PEI Core
+//
+EFI_PEI_CORE_ENTRY_POINT (PeiMain)
+
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+
+Returns:
+
+ This function never returns
+
+--*/
+{
+ return PeiCore (PeiStartupDescriptor, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN EFI_PEI_STARTUP_DESCRIPTOR *PeiStartupDescriptor,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+ EFI_NOT_FOUND - Never reach
+
+--*/
+{
+ PEI_CORE_INSTANCE PrivateData;
+ EFI_STATUS Status;
+ PEI_CORE_TEMP_POINTERS TempPtr;
+ PEI_CORE_DISPATCH_DATA *DispatchData;
+
+
+#ifdef EFI_PEI_PERFORMANCE
+ UINT64 mTick;
+
+ mTick = 0;
+ if (OldCoreData == NULL) {
+ GetTimerValue (&mTick);
+ }
+#endif
+
+
+ //
+ // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
+ // the 63-bit of address is set to 1.
+ //
+ SWITCH_TO_CACHE_MODE (OldCoreData);
+
+ if (OldCoreData != NULL) {
+ PeiCoreCopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
+ } else {
+ PeiCoreSetMem (&PrivateData, sizeof (PEI_CORE_INSTANCE), 0);
+ }
+
+ PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
+ PrivateData.PS = &mPS;
+
+ //
+ // Mm7 stored PeiServicesTablePointer in EdkII Glue Library
+ // Update Mm7 now
+ //
+//*** AMI PORTING BEGIN ***//
+//#if (defined(EFI32)) || (defined(EFIX64))
+#ifndef EFI64
+//*** AMI PORTING END *****//
+ AsmWriteMm7 ((UINT64)(UINTN)(&PrivateData.PS));
+#endif
+
+ InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);
+
+ InitializePpiServices (&PrivateData.PS, OldCoreData);
+
+ InitializeSecurityServices (&PrivateData.PS, OldCoreData);
+
+ InitializeDispatcherData (&PrivateData.PS, OldCoreData, PeiStartupDescriptor);
+
+ if (OldCoreData != NULL) {
+
+ PEI_PERF_END (&PrivateData.PS,L"PreMem", NULL, 0);
+ PEI_PERF_START (&PrivateData.PS,L"PostMem", NULL, 0);
+
+ //
+ // The following code dumps out interesting cache as RAM usage information
+ // so we can keep tabs on how the cache as RAM is being utilized. The
+ // PEI_DEBUG_CODE macro is used to prevent this code from being compiled
+ // on a debug build.
+ //
+ PEI_DEBUG_CODE (
+ {
+ UINTN *StackPointer;
+ UINTN StackValue;
+
+ StackValue = INIT_CAR_VALUE;
+ for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;
+ ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
+ && StackValue == INIT_CAR_VALUE;
+ StackPointer++) {
+ StackValue = *StackPointer;
+ }
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
+ ((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)
+ )
+ );
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR heap used: %d bytes.\n",
+ ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
+ (UINTN) OldCoreData->HobList.Raw)
+ )
+ );
+ }
+ )
+
+//*** AMI PORTING BEGIN ***//
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+//*** AMI PORTING END *****//
+
+ //
+ // Alert any listeners that there is permanent memory available
+ //
+ PEI_PERF_START (&PrivateData.PS,L"DisMem", NULL, 0);
+ Status = PeiInstallPpi (&PrivateData.PS, &mMemoryDiscoveredPpi);
+ PEI_PERF_END (&PrivateData.PS,L"DisMem", NULL, 0);
+
+ } else {
+
+ //
+ // Report Status Code EFI_SW_PC_INIT
+ //
+ PEI_REPORT_STATUS_CODE (
+ &(PrivateData.PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT,
+ 0,
+ NULL,
+ NULL
+ );
+
+ //
+ // If first pass, start performance measurement.
+ //
+ PEI_PERF_START (&PrivateData.PS,L"PreMem", NULL, mTick);
+
+ //
+ // If SEC provided any PPI services to PEI, install them.
+ //
+ if (PeiStartupDescriptor->DispatchTable != NULL) {
+ Status = PeiInstallPpi (&PrivateData.PS, PeiStartupDescriptor->DispatchTable);
+
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ }
+//*** AMI PORTING BEGIN ***//
+{
+ static EFI_GUID gEfiPeiLoadedImagePpiGuid = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+ static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiLoadedImagePpiGuid, NULL
+ };
+ PeiAllocatePool(&PrivateData.PS,sizeof(EFI_PEI_PPI_DESCRIPTOR),&PrivateData.LoadedImage);
+ *PrivateData.LoadedImage = LoadedImagePpiDesc;
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+ PeiInstallPpi (&PrivateData.PS, PrivateData.LoadedImage);
+}
+//*** AMI PORTING END *****//
+ }
+
+ DispatchData = &PrivateData.DispatchData;
+
+ //
+ // Call PEIM dispatcher
+ //
+//*** AMI PORTING BEGIN ***//
+ if (OldCoreData != NULL) {
+ AmiInitParts(&PrivateData.PS, InitPartsMem);
+ ProcessLoadHob(&PrivateData.PS);
+ } else {
+ AmiInitParts(&PrivateData.PS, InitParts);
+ }
+//*** AMI PORTING END *****//
+ PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
+
+ //
+ // Check if InstallPeiMemory service was called.
+ //
+//*** AMI PORTING BEGIN ***//
+ //report MEMORY_NOT_INSTALLED error
+ if (!PrivateData.PeiMemoryInstalled)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_MEMORY_NOT_INSTALLED, EFI_ERROR_MAJOR);
+// PEI_ASSERT(&PrivateData.PS, PrivateData.PeiMemoryInstalled == TRUE);
+//*** AMI PORTING END *****//
+
+ PEI_PERF_END (&PrivateData.PS, L"PostMem", NULL, 0);
+
+ Status = PeiLocatePpi (
+ &PrivateData.PS,
+ &gEfiDxeIplPpiGuid,
+ 0,
+ NULL,
+ &TempPtr.DxeIpl
+ );
+//*** AMI PORTING BEGIN ***//
+ //report DXEIPL_NOT_FOUND error
+ if (EFI_ERROR(Status))
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_DXEIPL_NOT_FOUND, EFI_ERROR_MAJOR);
+// ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+//*** AMI PORTING END *****//
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "DXE IPL Entry(%X)\n",TempPtr.DxeIpl->Entry));
+ Status = TempPtr.DxeIpl->Entry (
+ TempPtr.DxeIpl,
+ &PrivateData.PS,
+//*** AMI PORTING BEGIN ***//
+// PEI CIS defines parameter as EFI_PEI_HOB_POINTERS, but
+// EFI_PEI_HOB_POINTERS is not defined in PEI CIS.
+// Until this is fixed PEI.h defines this parameter as VOID*
+// PrivateData.HobList
+ PrivateData.HobList.Raw
+//*** AMI PORTING END *****//
+ );
+//*** AMI PORTING BEGIN ***//
+ // If DXE IPL returned control, let's call dispatcher again
+ // DXE IPL might have dicovered new FV or have changed a boot mode
+
+ // reset previous bitmap so that the dispatcher will attempt to execute any new PEIMs
+ DispatchData->PreviousPeimBitMap = 0;
+ // dispatch
+ PeiDispatcher (PeiStartupDescriptor, &PrivateData, DispatchData);
+ // DXE IPL
+ Status = TempPtr.DxeIpl->Entry (
+ TempPtr.DxeIpl,
+ &PrivateData.PS,
+ PrivateData.HobList.Raw
+ );
+//*** AMI PORTING END *****//
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ return EFI_NOT_FOUND;
+}
+
+//*** AMI PORTING BEGIN ***//
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+)
+{
+ PEI_CORE_INSTANCE *Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ Private->LoadedImagePpi.ImageAddress = ImageAddress;
+ Private->LoadedImagePpi.ImageSize = ImageSize;
+ Private->LoadedImagePpi.FileHandle = FileHandle;
+ PeiReInstallPpi(PeiServices,Private->LoadedImage,Private->LoadedImage);
+}
+//*** AMI PORTING END *****// \ No newline at end of file
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c
new file mode 100644
index 0000000..62077e3
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Ppi.c
@@ -0,0 +1,673 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ppi.c
+
+Abstract:
+
+ EFI PEI Core PPI services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+VOID
+InitializePpiServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ if (OldCoreData == NULL) {
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
+ }
+
+ return;
+}
+
+VOID
+ConvertPpiPointers (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Convert PPI pointers after the Hob list was migrated from the CAR stack
+ to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+
+ None.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT8 Index;
+ PEI_PPI_LIST_POINTERS *PpiPointer;
+ UINTN Fixup;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
+
+ for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
+ if (Index < PrivateData->PpiData.PpiListEnd ||
+ Index > PrivateData->PpiData.NotifyListEnd) {
+ PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
+
+ if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the PEIM descriptor from the old HOB heap
+ // to the relocated HOB heap.
+ //
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);
+
+ //
+ // Only when the PEIM descriptor is in the old HOB should it be necessary
+ // to try to convert the pointers in the PEIM descriptor
+ //
+
+ if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);
+ }
+
+ //
+ // Assume that no code is located in the temporary memory, so the pointer to
+ // the notification function in the NOTIFY descriptor needs not be converted.
+ //
+ if (Index < PrivateData->PpiData.PpiListEnd &&
+ (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
+ (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
+ //
+ // Convert the pointer to the PPI interface structure in the PPI descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
+ }
+ }
+ }
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN LastCallbackInstall;
+
+
+ if (PpiList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Index = PrivateData->PpiData.PpiListEnd;
+ LastCallbackInstall = Index;
+
+ //
+ // This is loop installs all PPI descriptors in the PpiList. It is terminated
+ // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_PPI_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the NotifyList
+ //
+ if (Index == PrivateData->PpiData.NotifyListEnd + 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Check if it is a valid PPI.
+ // If not, rollback list to exclude all in this list.
+ // Try to indicate which item failed.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ PrivateData->PpiData.PpiListEnd = LastCallbackInstall;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));
+ return EFI_INVALID_PARAMETER;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
+//*** AMI PORTING END *****//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = PpiList;
+ PrivateData->PpiData.PpiListEnd++;
+
+ //
+ // Continue until the end of the PPI List.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ PpiList++;
+ Index++;
+ }
+
+ //
+ // Dispatch any callback level notifies for newly installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ LastCallbackInstall,
+ PrivateData->PpiData.PpiListEnd,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PPI_DESCRIPTOR *OldPpi,
+ IN EFI_PEI_PPI_DESCRIPTOR *NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+
+
+ if ((OldPpi == NULL) || (NewPpi == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Find the old PPI instance in the database. If we can not find it,
+ // return the EFI_NOT_FOUND error.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {
+ break;
+ }
+ }
+ if (Index == PrivateData->PpiData.PpiListEnd) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Remove the old PPI from the database, add the new one.
+ //
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
+//*** AMI PORTING END *****//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = NewPpi;
+
+ //
+ // Dispatch any callback level notifies for the newly installed PPI.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ Index,
+ Index+1,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_PPI_DESCRIPTOR *TempPtr;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Search the data base for the matching instance of the GUIDed PPI.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;
+ CheckGuid = TempPtr->Guid;
+
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {
+ if (Instance == 0) {
+
+ if (PpiDescriptor != NULL) {
+ *PpiDescriptor = TempPtr;
+ }
+
+ if (Ppi != NULL) {
+ *Ppi = TempPtr->Ppi;
+ }
+
+
+ return EFI_SUCCESS;
+ }
+ Instance--;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN NotifyIndex;
+ INTN LastCallbackNotify;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr;
+ UINTN NotifyDispatchCount;
+
+
+ NotifyDispatchCount = 0;
+
+ if (NotifyList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Index = PrivateData->PpiData.NotifyListEnd;
+ LastCallbackNotify = Index;
+
+ //
+ // This is loop installs all Notify descriptors in the NotifyList. It is
+ // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the PpiList
+ //
+ if (Index == PrivateData->PpiData.PpiListEnd - 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // If some of the PPI data is invalid restore original Notify PPI database value
+ //
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
+ PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyDispatchCount ++;
+ }
+
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyList;
+
+ PrivateData->PpiData.NotifyListEnd--;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ //
+ // Go the next descriptor. Remember the NotifyList moves down.
+ //
+ NotifyList++;
+ Index--;
+ }
+
+ //
+ // If there is Dispatch Notify PPI installed put them on the bottom
+ //
+ if (NotifyDispatchCount > 0) {
+ for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
+ if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
+
+ for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
+ }
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
+ PrivateData->PpiData.DispatchListEnd--;
+ }
+ }
+
+ LastCallbackNotify -= NotifyDispatchCount;
+ }
+
+ //
+ // Dispatch any callback level notifies for all previously installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ 0,
+ PrivateData->PpiData.PpiListEnd,
+ LastCallbackNotify,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN TempValue;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+
+ while (TRUE) {
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // Notifies getting installed. If so, go process any dispatch
+ // level Notifies that match the previouly installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
+ TempValue = PrivateData->PpiData.DispatchListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ 0,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.LastDispatchedNotify,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedNotify = TempValue;
+ }
+
+
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // PPIs getting installed. If so, go process any dispatch
+ // level Notifies that match the installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // PpiListEnd (with InstallPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
+ TempValue = PrivateData->PpiData.PpiListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.PpiListEnd,
+ MAX_PPI_DESCRIPTORS-1,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedInstall = TempValue;
+ }
+
+ if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
+ break;
+ }
+ }
+ return;
+}
+
+VOID
+DispatchNotify (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index1;
+ INTN Index2;
+ EFI_GUID *SearchGuid;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Remember that Installs moves up and Notifies moves down.
+ //
+ for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {
+ NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;
+
+ CheckGuid = NotifyDescriptor->Guid;
+
+ for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
+ SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {
+ PEI_DEBUG (
+ (
+ PeiServices,
+ EFI_D_INFO,
+ "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
+ SearchGuid,
+ NotifyDescriptor->Notify
+ )
+ );
+ NotifyDescriptor->Notify (
+ PeiServices,
+ NotifyDescriptor,
+ (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
+ );
+ }
+ }
+ }
+
+ return;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c
new file mode 100644
index 0000000..bbfd4a9
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Reset.c
@@ -0,0 +1,77 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Reset.c
+
+Abstract:
+
+ Pei Core Reset System Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (Reset)
+
+EFI_STATUS
+EFIAPI
+PeiCoreResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_RESET_PPI *ResetPpi;
+
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiResetPpiGuid,
+ 0,
+ NULL,
+ &ResetPpi
+ );
+
+ //
+ // LocatePpi returns EFI_NOT_FOUND on error
+ //
+ if (!EFI_ERROR (Status)) {
+ return ResetPpi->ResetSystem (PeiServices);
+ }
+//*** AMI PORTING BEGIN ***//
+ //Report error
+ PEI_ERROR_CODE(PeiServices,PEI_RESET_NOT_AVAILABLE,EFI_ERROR_MINOR);
+//*** AMI PORTING END *****//
+ return EFI_NOT_AVAILABLE_YET;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c
new file mode 100644
index 0000000..928e21a
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/Security.c
@@ -0,0 +1,194 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Security.c
+
+Abstract:
+
+ EFI PEI Core Security services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include EFI_PPI_DEFINITION (Security)
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiSecurityPpiGuid,
+ SecurityPpiNotifyCallback
+};
+
+VOID
+InitializeSecurityServices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PeiNotifyPpi (PeiServices, &mNotifyList);
+ }
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Provide a callback for when the security PPI is installed.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ NotifyDescriptor - The descriptor for the notification event.
+ Ppi - Pointer to the PPI in question.
+
+Returns:
+
+ EFI_SUCCESS - The function is successfully processed.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ //
+ // Get PEI Core private data
+ //
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // If there isn't a security PPI installed, use the one from notification
+ //
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ PrivateData->PrivateSecurityPpi = (PEI_SECURITY_PPI *)Ppi;
+ }
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+VerifyPeim (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *CurrentPeimAddress
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_STATUS Status;
+ UINT32 AuthenticationStatus;
+ BOOLEAN StartCrisisRecovery;
+
+ //
+ // Set a default authentication state
+ //
+ AuthenticationStatus = 0;
+
+ //
+ // get security PPI instance from PEI private data
+ //
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Check to see if the image is OK
+ //
+ Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
+ PeiServices,
+ PrivateData->PrivateSecurityPpi,
+ AuthenticationStatus,
+ CurrentPeimAddress,
+ &StartCrisisRecovery
+ );
+ if (StartCrisisRecovery) {
+ Status = EFI_SECURITY_VIOLATION;
+ }
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_FIRMWARE_VOLUME_HEADER *CurrentFvAddress
+ )
+/*++
+
+Routine Description:
+
+ Verify a Firmware volume
+
+Arguments:
+
+ CurrentFvAddress - Pointer to the current Firmware Volume under consideration
+
+Returns:
+
+ EFI_SUCCESS - Firmware Volume is legal
+ EFI_SECURITY_VIOLATION - Firmware Volume fails integrity test
+
+--*/
+{
+ //
+ // Right now just pass the test. Future can authenticate and/or check the
+ // FV-header or other metric for goodness of binary.
+ //
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c
new file mode 100644
index 0000000..26cac94
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/StatusCode.c
@@ -0,0 +1,102 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ StatusCode.c
+
+Abstract:
+
+ Pei Core Status Code Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (StatusCode)
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ CodeType - Type of Status Code.
+
+ Value - Value to output for Status Code.
+
+ Instance - Instance Number of this status code.
+
+ CallerId - ID of the caller of this status code.
+
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_STATUS_CODE_PPI *StatusCodePpi;
+
+
+ //
+ //Locate StatusCode Ppi.
+ //
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiStatusCodePpiGuid,
+ 0,
+ NULL,
+ &StatusCodePpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = StatusCodePpi->ReportStatusCode (
+ PeiServices,
+ CodeType,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+
+
+ return Status;
+
+ }
+
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c
new file mode 100644
index 0000000..ff3b2e4
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.c
@@ -0,0 +1,268 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ dependency.c
+
+Abstract:
+
+ PEI Dispatcher Dependency Evaluator
+
+ This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine
+ if a driver can be scheduled for execution. The criteria for
+ schedulability is that the dependency expression is satisfied.
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include "EfiDependency.h"
+#include "Dependency.h"
+
+STATIC
+BOOLEAN
+IsPpiInstalled (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EVAL_STACK_ENTRY *Stack
+ )
+/*++
+
+Routine Description:
+
+ This routine determines if a PPI has been installed.
+ The truth value of a GUID is determined by if the PPI has
+ been published and can be queried from the PPI database.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Stack - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check
+
+Returns:
+
+ True if the PPI is already installed.
+ False if the PPI has yet to be installed.
+
+--*/
+{
+ VOID *PeiInstance;
+ EFI_STATUS Status;
+ EFI_GUID PpiGuid;
+
+ //
+ // If there is no GUID to evaluate, just return current result on stack.
+ //
+ if (Stack->Operator == NULL) {
+ return Stack->Result;
+ }
+
+ //
+ // Copy the Guid into a locale variable so that there are no
+ // possibilities of alignment faults for cross-compilation
+ // environments such as Intel?Itanium(TM).
+ //
+ PeiCoreCopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));
+
+ //
+ // Check if the PPI is installed.
+ //
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiInstance // PPI
+ );
+
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+EFI_STATUS
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression,
+ OUT BOOLEAN *Runnable
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+{
+ EFI_STATUS Status;
+ DEPENDENCY_EXPRESSION_OPERAND *Iterator;
+ EVAL_STACK_ENTRY *StackPtr;
+ EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
+
+ Status = EFI_SUCCESS;
+ Iterator = DependencyExpression;
+ *Runnable = FALSE;
+
+ StackPtr = &EvalStack[0];
+
+ while (TRUE) {
+
+ switch (*(Iterator++)) {
+
+ //
+ // For performance reason we put the frequently used items in front of
+ // the rarely used items
+ //
+
+ case (EFI_DEP_PUSH):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)
+ // We will evaluate if the PPI is insalled on the POP operation.
+ //
+ StackPtr->Operator = (VOID *) Iterator;
+ Iterator = Iterator + sizeof (EFI_GUID);
+ StackPtr++;
+ break;
+
+ case (EFI_DEP_AND):
+ case (EFI_DEP_OR):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the two POPs for the AND operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did two POPs.
+ //
+ if (StackPtr < &EvalStack[2]) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Evaluate the first POPed operator only. If the operand is
+ // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the
+ // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,
+ // we don't need to check the second operator, and the result will be
+ // evaluation of the POPed operator. Otherwise, don't POP the second
+ // operator since it will now evaluate to the final result on the
+ // next operand that causes a POP.
+ //
+ StackPtr--;
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_AND) {
+ if (!(IsPpiInstalled (PeiServices, StackPtr))) {
+ (StackPtr-1)->Result = FALSE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ } else {
+ if (IsPpiInstalled (PeiServices, StackPtr)) {
+ (StackPtr-1)->Result = TRUE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ }
+ break;
+
+ case (EFI_DEP_END):
+ StackPtr--;
+ //
+ // Check to make sure EvalStack is balanced. If not, then there is
+ // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
+ //
+ if (StackPtr != &EvalStack[0]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *Runnable = IsPpiInstalled (PeiServices, StackPtr);
+ return EFI_SUCCESS;
+ break;
+
+ case (EFI_DEP_NOT):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the POP for the NOT operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did a POP.
+ //
+ if (StackPtr < &EvalStack[1]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
+ (StackPtr-1)->Operator = NULL;
+ break;
+
+ case (EFI_DEP_TRUE):
+ case (EFI_DEP_FALSE):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_TRUE) {
+ StackPtr->Result = TRUE;
+ } else {
+ StackPtr->Result = FALSE;
+ }
+ StackPtr->Operator = NULL;
+ StackPtr++;
+ break;
+
+ default:
+ //
+ // The grammar should never arrive here
+ //
+ return EFI_INVALID_PARAMETER;
+ break;
+ }
+ }
+}
diff --git a/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h
new file mode 100644
index 0000000..9df008b
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_FRAMEWORK/dependency.h
@@ -0,0 +1,38 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ dependency.h
+
+Abstract:
+
+ This module contains data specific to dependency expressions
+ and local function prototypes.
+
+--*/
+
+#ifndef _PEI_DEPENDENCY_H_
+#define _PEI_DEPENDENCY_H_
+
+#define MAX_GRAMMAR_SIZE 256
+
+//
+// type definitions
+//
+typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;
+
+typedef struct {
+ BOOLEAN Result;
+ VOID *Operator;
+} EVAL_STACK_ENTRY;
+
+#endif
diff --git a/Core/CORE_PEI/CORE_PEI_PI/BootMode.c b/Core/CORE_PEI/CORE_PEI_PI/BootMode.c
new file mode 100644
index 0000000..2c5845a
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/BootMode.c
@@ -0,0 +1,107 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ BootMode.c
+
+Abstract:
+
+ EFI PEI Core Boot Mode services
+
+
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ if (BootMode == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ *BootMode = HandOffHob->BootMode;
+
+
+ return EFI_SUCCESS;
+};
+
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ HandOffHob = (PrivateData->HobList.HandoffInformationTable);
+
+ HandOffHob->BootMode = BootMode;
+
+ return EFI_SUCCESS;
+};
diff --git a/Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif b/Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif
new file mode 100644
index 0000000..62d8649
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/CORE_PEISrcPI.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "CORE_PEI Source PI (EDK)"
+ category = ModulePart
+ LocalRoot = "Core\CORE_PEI\CORE_PEI_PI"
+ RefName = "CORE_PEISrcPI_EDK"
+[files]
+"BootMode.c"
+"dependency.c"
+"dependency.h"
+"Dispatcher.c"
+"FwVol.c"
+"Hob.c"
+"Image.c"
+"MemoryServices.c"
+"PeiCore.h"
+"PeiMain.c"
+"Ppi.c"
+"Reset.c"
+"Security.c"
+"StatusCode.c"
+<endComponent>
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c b/Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c
new file mode 100644
index 0000000..91e8821
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Dispatcher.c
@@ -0,0 +1,689 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Dispatcher.c
+
+Abstract:
+
+ EFI PEI Core dispatch services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+
+//*** AMI PORTING BEGIN ***//
+VOID PeiCoreEntry(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList);
+//*** AMI PORTING END *****//
+VOID
+DiscoverPeimsAndOrderWithApriori (
+ IN PEI_CORE_INSTANCE *Private,
+ IN EFI_PEI_FV_HANDLE VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Discover all Peims and optional Apriori file in one FV. There is at most one
+ Apriori file in one FV.
+
+Arguments:
+
+ Private - Pointer to the private data passed in from caller
+ VolumeHandle - Fv handle.
+Returns:
+
+ NONE
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PEI_FV_HANDLE FileHandle;
+ EFI_PEI_FILE_HANDLE AprioriFileHandle;
+ EFI_GUID *Apriori;
+ UINTN Index;
+ UINTN Index2;
+ UINTN PeimIndex;
+ UINTN PeimCount;
+ EFI_GUID *Guid;
+ EFI_PEI_FV_HANDLE TempFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
+ EFI_GUID FileGuid[PEI_CORE_MAX_PEIM_PER_FV];
+
+ //
+ // Walk the FV and find all the PEIMs and the Apriori file.
+ //
+ AprioriFileHandle = NULL;
+ Private->CurrentFvFileHandles[0] = NULL;
+ Guid = NULL;
+ FileHandle = NULL;
+
+ //
+ // If the current Fv has been scanned, directly get its cachable record.
+ //
+ if (Private->Fv[Private->CurrentPeimFvCount].ScanFv) {
+ PeiCoreCopyMem (Private->CurrentFvFileHandles, Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, sizeof (Private->CurrentFvFileHandles));
+ return;
+ }
+
+ //
+ // Go ahead to scan this Fv, and cache FileHandles within it.
+ //
+ for (PeimCount = 0; PeimCount < PEI_CORE_MAX_PEIM_PER_FV; PeimCount++) {
+ Status = PeiFindFileEx (
+ VolumeHandle,
+ NULL,
+ PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
+ &FileHandle,
+ &AprioriFileHandle
+ );
+ if (Status != EFI_SUCCESS) {
+ break;
+ }
+
+ Private->CurrentFvFileHandles[PeimCount] = FileHandle;
+ }
+
+ Private->AprioriCount = 0;
+ if (AprioriFileHandle != NULL) {
+ //
+ // Read the Apriori file
+ //
+ Status = PeiFfsFindSectionData (&Private->PS, EFI_SECTION_RAW, AprioriFileHandle, &Apriori);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Calculate the number of PEIMs in the A Priori list
+ //
+ Private->AprioriCount = *(UINT32 *)(((EFI_FFS_FILE_HEADER *)AprioriFileHandle)->Size) & 0x00FFFFFF;
+ Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);
+ Private->AprioriCount /= sizeof (EFI_GUID);
+
+ PeiCoreSetMem (FileGuid, sizeof (FileGuid), 0);
+ for (Index = 0; Index < PeimCount; Index++) {
+ //
+ // Make an array of file name guids that matches the FileHandle array so we can convert
+ // quickly from file name to file handle
+ //
+ PeiCoreCopyMem (&FileGuid[Index], &((EFI_FFS_FILE_HEADER *)Private->CurrentFvFileHandles[Index])->Name,sizeof(EFI_GUID));
+ }
+
+ //
+ // Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
+ // Add avalible PEIMs in Apriori file into TempFileHandles array at first.
+ //
+ Index2 = 0;
+ for (Index = 0; Index2 < Private->AprioriCount; Index++) {
+ while (Index2 < Private->AprioriCount) {
+ Guid = ScanGuid (FileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2++]);
+ if (Guid != NULL) {
+ break;
+ }
+ }
+ if (Guid == NULL) {
+ break;
+ }
+ PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID);
+ TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex];
+
+ //
+ // Since we have copied the file handle we can remove it from this list.
+ //
+ Private->CurrentFvFileHandles[PeimIndex] = NULL;
+ }
+
+ //
+ // Update valid Aprioricount
+ //
+ Private->AprioriCount = Index;
+
+ //
+ // Add in any PEIMs not in the Apriori file
+ //
+ for (;Index < PeimCount; Index++) {
+ for (Index2 = 0; Index2 < PeimCount; Index2++) {
+ if (Private->CurrentFvFileHandles[Index2] != NULL) {
+ TempFileHandles[Index] = Private->CurrentFvFileHandles[Index2];
+ Private->CurrentFvFileHandles[Index2] = NULL;
+ break;
+ }
+ }
+ }
+ //
+ //Index the end of array contains re-range Pei moudle.
+ //
+ TempFileHandles[Index] = NULL;
+
+ //
+ // Private->CurrentFvFileHandles is currently in PEIM in the FV order.
+ // We need to update it to start with files in the A Priori list and
+ // then the remaining files in PEIM order.
+ //
+ PeiCoreCopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (Private->CurrentFvFileHandles));
+ }
+ }
+ //
+ // Cache the current Fv File Handle. So that we don't have to scan the Fv again.
+ // Instead, we can retrieve the file handles within this Fv from cachable data.
+ //
+ Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE;
+ PeiCoreCopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles));
+
+}
+
+
+VOID
+PeiDispatcher (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *Private
+ )
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ Private - Pointer to the private data passed in from caller
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 Index1;
+ UINT32 Index2;
+ EFI_PEI_SERVICES **PeiServices;
+ VOID *PrivateInMem;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
+ EFI_PEI_FILE_HANDLE PeimFileHandle;
+ UINTN FvCount;
+ UINTN PeimCount;
+ UINT32 AuthenticationState;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ EFI_PEIM_ENTRY_POINT PeimEntryPoint;
+ VOID* PeiCoreReentryPoint;
+ UINTN SaveCurrentPeimCount;
+ UINTN SaveCurrentFvCount;
+ EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
+
+ PEI_REPORT_STATUS_CODE_CODE (
+
+ EFI_DEVICE_HANDLE_EXTENDED_DATA ExtendedData;
+
+ ExtendedData.DataHeader.HeaderSize = (UINT16)sizeof (EFI_STATUS_CODE_DATA);
+ ExtendedData.DataHeader.Size = (UINT16)(sizeof (EFI_DEVICE_HANDLE_EXTENDED_DATA) - ExtendedData.DataHeader.HeaderSize);
+
+ PeiCoreCopyMem (
+ &ExtendedData.DataHeader.Type,
+ &gEfiStatusCodeSpecificDataGuid,
+ sizeof (EFI_GUID)
+ );
+ )
+
+ PeiServices = &Private->PS;
+ PeimEntryPoint = NULL;
+ PeimFileHandle = NULL;
+
+ if ((Private->PeiMemoryInstalled) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ //
+ // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
+ // update the modules' status from PEIM_STATE_REGISITER_FOR_SHADOW to PEIM_STATE_DONE.
+ //
+ SaveCurrentPeimCount = Private->CurrentPeimCount;
+ SaveCurrentFvCount = Private->CurrentPeimFvCount;
+ SaveCurrentFileHandle = Private->CurrentFileHandle;
+
+ for (Index1 = 0;Index1 <= SaveCurrentFvCount; Index1++) {
+ for (Index2 = 0; (Index2 < PEI_CORE_MAX_PEIM_PER_FV) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
+ if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
+ PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
+ Status = PeiLoadImage (
+ &Private->PS,
+ PeimFileHandle,
+ &EntryPoint,
+ &AuthenticationState
+ );
+ if (Status == EFI_SUCCESS) {
+ //
+ // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
+ //
+ Private->Fv[Index1].PeimState[Index2]++;
+ Private->CurrentFileHandle = PeimFileHandle;
+ Private->CurrentPeimFvCount = Index1;
+ Private->CurrentPeimCount = Index2;
+
+ //
+ // Call the PEIM entry point
+ //
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
+
+ PEI_PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
+ PeimEntryPoint(PeimFileHandle, &Private->PS);
+ PEI_PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
+ }
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (&Private->PS);
+ }
+ }
+ }
+ Private->CurrentFileHandle = SaveCurrentFileHandle;
+ Private->CurrentPeimFvCount = SaveCurrentFvCount;
+ Private->CurrentPeimCount = SaveCurrentPeimCount;
+ }
+
+ //
+ // This is the main dispatch loop. It will search known FVs for PEIMs and
+ // attempt to dispatch them. If any PEIM gets dispatched through a single
+ // pass of the dispatcher, it will start over from the Bfv again to see
+ // if any new PEIMs dependencies got satisfied. With a well ordered
+ // FV where PEIMs are found in the order their dependencies are also
+ // satisfied, this dipatcher should run only once.
+ //
+ do {
+ //
+ // In case that reenter PeiCore happens, the last pass record is still available.
+ //
+ if (!Private->PeimDispatcherReenter) {
+ Private->PeimNeedingDispatch = FALSE;
+ Private->PeimDispatchOnThisPass = FALSE;
+ } else {
+ Private->PeimDispatcherReenter = FALSE;
+ }
+ for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
+ Private->CurrentPeimFvCount = FvCount;
+ VolumeHandle = Private->Fv[FvCount].FvHeader;
+
+ if (Private->CurrentPeimCount == 0) {
+ //
+ // When going through each FV, at first, search Apriori file to
+ // reorder all PEIMs to ensure the PEIMs in Apriori file to get
+ // dispatch at first.
+ //
+ DiscoverPeimsAndOrderWithApriori (Private, VolumeHandle);
+ }
+
+ //
+ // Start to dispatch all modules within the current Fv.
+ //
+ for (PeimCount = Private->CurrentPeimCount;
+ (PeimCount < PEI_CORE_MAX_PEIM_PER_FV) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
+ PeimCount++) {
+ Private->CurrentPeimCount = PeimCount;
+ PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
+
+ if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
+ if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
+ Private->PeimNeedingDispatch = TRUE;
+ } else {
+ Status = PeiLoadImage (
+ PeiServices,
+ PeimFileHandle,
+ &EntryPoint,
+ &AuthenticationState
+ );
+ if ((Status == EFI_SUCCESS)) {
+ //
+ // The PEIM has its dependencies satisfied, and its entry point
+ // has been found, so invoke it.
+ //
+ PEI_PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
+
+ PEI_REPORT_STATUS_CODE_CODE (
+ ExtendedData.Handle = PeimFileHandle;
+ )
+
+ PEI_REPORT_STATUS_CODE_CODE (
+ PeiReportStatusCode (
+ PeiServices,
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+ )
+
+ Status = VerifyPeim (Private, VolumeHandle, PeimFileHandle);
+ if (Status != EFI_SECURITY_VIOLATION && (AuthenticationState == 0)) {
+ //
+ // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
+ //
+ Private->Fv[FvCount].PeimState[PeimCount]++;
+
+ //
+ // Call the PEIM entry point
+ //
+ PeimEntryPoint = (EFI_PEIM_ENTRY_POINT)(UINTN)EntryPoint;
+ PeimEntryPoint (PeimFileHandle, PeiServices);
+ Private->PeimDispatchOnThisPass = TRUE;
+ }
+
+ PEI_REPORT_STATUS_CODE_CODE (
+ PeiReportStatusCode (
+ PeiServices,
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END,
+ 0,
+ NULL,
+ (EFI_STATUS_CODE_DATA *)(&ExtendedData)
+ );
+ )
+ PEI_PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
+ }
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (PeiServices);
+
+ //
+ // If permanent memory was discovered and installed by this
+ // PEIM, shadow PEI Core and switch the stacks to the new memory.
+ //
+ if (Private->SwitchStackSignal) {
+
+ //
+ // Make sure we don't retry the same PEIM that added memory
+ //
+ Private->CurrentPeimCount++;
+
+ //
+ // Indicate that PeiCore reenter
+ //
+ Private->PeimDispatcherReenter = TRUE;
+ //
+ // Migrate IDT from CAR into real memory, so after stack switches to
+ // the new memory, the caller can get memory version PeiServiceTable.
+ //
+ MigrateIdtTable (PeiServices);
+ //
+ // Since we are at dispatch level, only the Core's private data
+ // is preserved, nobody else should have any data on the stack.
+ // So we need to copy PEI core instance data to memory.
+ //
+ Status = PeiAllocatePool (PeiServices, sizeof (PEI_CORE_INSTANCE), &PrivateInMem);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ PeiCoreCopyMem (PrivateInMem, Private, sizeof (PEI_CORE_INSTANCE));
+
+ //
+ // Shadow PEI Core. When permanent memory is avaiable, shadow
+ // PEI Core and PEIMs to get high performance.
+ //
+ PeiCoreFileHandle = NULL;
+ //
+ // Find the PEI Core in the BFV
+ //
+ Status = PeiFindFileEx (
+ (EFI_PEI_FV_HANDLE)Private->Fv[0].FvHeader,
+ NULL,
+ EFI_FV_FILETYPE_PEI_CORE,
+ &PeiCoreFileHandle,
+ NULL
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //
+ // Shadow PEI Core into memory so it will run faster
+ //
+ Status = PeiLoadImage (PeiServices, PeiCoreFileHandle, &EntryPoint, &AuthenticationState);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //
+ // The 2nd time around we need to call PeiCore passing in a non
+ // NULL value to OldCoreData. We can not call the PE COFF entry
+ // point (_EntryPoint) as it had codes a NULL into OldCoreData.
+ // We calculate the memory (shadowed) address of PeiCore by
+ // figuring out the offset from _EntryPoint to PeiCore and then
+ // adding that value to the new memory based entry point.
+ //
+ PeiCoreReentryPoint = (VOID*)(UINTN)(EntryPoint +
+//*** AMI PORTING BEGIN ***//
+// (((UINT8 *)(UINTN)PeiCore) - (UINT8 *)(UINTN)PeiMain));
+ (((UINT8 *)(UINTN)PeiCore) - (UINT8 *)(UINTN)PeiCoreEntry));
+//*** AMI PORTING END ***//
+
+
+ //
+ // Switch to memory based stack and reenter PEI Core that has been
+ // shadowed to memory.
+ //
+ SwitchCoreStacks (
+ PeiCoreReentryPoint,
+ (UINTN)SecCoreData,
+ (UINTN)NULL,
+ (UINTN)PrivateInMem,
+ (VOID*)((UINTN)Private->StackBase + (UINTN)Private->StackSize - 0x10)
+ );
+ }
+
+ if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
+ //
+ // If memory is availble we shadow images by default for performance reasons.
+ // We call the entry point a 2nd time so the module knows it's shadowed.
+ //
+ PEI_PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
+ PeimEntryPoint (PeimFileHandle, PeiServices);
+ PEI_PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
+
+ //
+ // PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
+ //
+ Private->Fv[FvCount].PeimState[PeimCount]++;
+
+ //
+ // Process the Notify list and dispatch any notifies for
+ // newly installed PPIs.
+ //
+ ProcessNotifyList (PeiServices);
+ }
+ }
+ }
+ }
+
+ //
+ // We set to NULL here to optimize the 2nd entry to this routine after
+ // memory is found. This reprevents rescanning of the FV. We set to
+ // NULL here so we start at the begining of the next FV
+ //
+ Private->CurrentFileHandle = NULL;
+ Private->CurrentPeimCount = 0;
+ //
+ // Before walking through the next FV,Private->CurrentFvFileHandles[]should set to NULL
+ //
+ PeiCoreSetMem (Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles), 0);
+ }
+
+ //
+ // Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
+ // through all the FV.
+ //
+ Private->CurrentPeimFvCount = 0;
+
+ //
+ // PeimNeedingDispatch being TRUE means we found a PEIM that did not get
+ // dispatched. So we need to make another pass
+ //
+ // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
+ // pass. If we did not dispatch a PEIM there is no point in trying again
+ // as it will fail the next time too (nothing has changed).
+ //
+ } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass);
+
+//*** AMI PORTING BEGIN ***//
+ // Print out a list of the PEIMs that were not dispatched
+ PEI_DEBUG_CODE
+ (
+ {
+ UINTN i = 0;
+ UINTN j = 0;
+
+ for(i = 0; i < PEI_CORE_MAX_FV_SUPPORTED; i++)
+ {
+ for(j = 0; j < PEI_CORE_MAX_PEIM_PER_FV; j++)
+ {
+ if( Private->Fv[i].FvFileHandles[j] == NULL) continue;
+
+ if(Private->Fv[i].PeimState[j] == PEIM_STATE_NOT_DISPATCHED)
+ PEI_DEBUG((&Private->PS, -1, "WARNING -> PEIM Not Dispatched: %g\n", &((EFI_FFS_FILE_HEADER*)(Private->Fv[i].FvFileHandles[j]))->Name ));
+ }
+ }
+ }
+ )
+//*** AMI PORTING END *****//
+}
+
+
+VOID
+InitializeDispatcherData (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ SecCoreData - Information and services provided by SEC phase.
+
+Returns:
+
+ None.
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PeiInitializeFv (PrivateData, SecCoreData);
+ }
+
+ return;
+}
+
+
+BOOLEAN
+DepexSatisfied (
+ IN PEI_CORE_INSTANCE *Private,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN UINTN PeimCount
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+
+ Private - Pointer to the private data passed in from caller.
+ FileHandle - File handle of PEIM.
+ PeimCount - The PEIM sequence in one FV.
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+{
+ EFI_STATUS Status;
+ INT8 *DepexData;
+
+ if (PeimCount < Private->AprioriCount) {
+ //
+ // If its in the A priori file then we set Depex to TRUE
+ //
+ return TRUE;
+ }
+
+ Status = PeiFfsFindSectionData (&Private->PS, EFI_SECTION_PEI_DEPEX, FileHandle, &DepexData);
+ if (EFI_ERROR (Status)) {
+ //
+ // If there is no DEPEX, assume the module can be executed
+ //
+ return TRUE;
+ }
+
+ //
+ // Evaluate a given DEPEX
+ //
+ return PeimDispatchReadiness (&Private->PS, DepexData);
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiRegisterForShadow (
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ This routine enable a PEIM to register itself to shadow when PEI Foundation
+ discovery permanent memory.
+
+Arguments:
+ FileHandle - File handle of a PEIM.
+
+Returns:
+ EFI_NOT_FOUND - The file handle doesn't point to PEIM itself.
+ EFI_ALREADY_STARTED - Indicate that the PEIM has been registered itself.
+ EFI_SUCCESS - Successfully to register itself.
+
+--*/
+{
+ PEI_CORE_INSTANCE *Private;
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
+
+ if (Private->CurrentFileHandle != FileHandle) {
+ //
+ // The FileHandle must be for the current PEIM
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ if (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] >= PEIM_STATE_REGISITER_FOR_SHADOW) {
+ //
+ // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
+ //
+ return EFI_ALREADY_STARTED;
+ }
+
+ Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] = PEIM_STATE_REGISITER_FOR_SHADOW;
+
+ return EFI_SUCCESS;
+}
+
+
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/FwVol.c b/Core/CORE_PEI/CORE_PEI_PI/FwVol.c
new file mode 100644
index 0000000..2ecf88e
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/FwVol.c
@@ -0,0 +1,782 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FwVol.c
+
+Abstract:
+
+ Pei Core Firmware File System service routines.
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImageFormat.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#define GET_OCCUPIED_SIZE(ActualSize, Alignment) \
+ (ActualSize) + (((Alignment) - ((ActualSize) & ((Alignment) - 1))) & ((Alignment) - 1))
+
+
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiFirmwareVolumeInfoPpiGuid,
+ FirmwareVolmeInfoPpiNotifyCallback
+};
+
+
+
+
+STATIC
+EFI_FFS_FILE_STATE
+GetFileState(
+ IN UINT8 ErasePolarity,
+ IN EFI_FFS_FILE_HEADER *FfsHeader
+ )
+/*++
+
+Routine Description:
+
+ Returns the highest bit set of the State field
+
+Arguments:
+
+ ErasePolarity - Erase Polarity as defined by EFI_FVB_ERASE_POLARITY
+ in the Attributes field.
+ FfsHeader - Pointer to FFS File Header.
+
+Returns:
+ Returns the highest bit in the State field
+
+--*/
+{
+ EFI_FFS_FILE_STATE FileState;
+ EFI_FFS_FILE_STATE HighestBit;
+
+ FileState = FfsHeader->State;
+
+ if (ErasePolarity != 0) {
+ FileState = (EFI_FFS_FILE_STATE)~FileState;
+ }
+
+ HighestBit = 0x80;
+ while (HighestBit != 0 && (HighestBit & FileState) == 0) {
+ HighestBit >>= 1;
+ }
+
+ return HighestBit;
+}
+
+STATIC
+UINT8
+CalculateHeaderChecksum (
+ IN EFI_FFS_FILE_HEADER *FileHeader
+ )
+/*++
+
+Routine Description:
+
+ Calculates the checksum of the header of a file.
+
+Arguments:
+
+ FileHeader - Pointer to FFS File Header.
+
+Returns:
+ Checksum of the header.
+
+ The header is zero byte checksum.
+ - Zero means the header is good.
+ - Non-zero means the header is bad.
+
+
+Bugbug: For PEI performance reason, we comments this code at this time.
+--*/
+{
+ UINT8 *ptr;
+ UINTN Index;
+ UINT8 Sum;
+
+ Sum = 0;
+ ptr = (UINT8 *)FileHeader;
+
+ for (Index = 0; Index < sizeof(EFI_FFS_FILE_HEADER) - 3; Index += 4) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ Sum = (UINT8)(Sum + ptr[Index+1]);
+ Sum = (UINT8)(Sum + ptr[Index+2]);
+ Sum = (UINT8)(Sum + ptr[Index+3]);
+ }
+
+ for (; Index < sizeof(EFI_FFS_FILE_HEADER); Index++) {
+ Sum = (UINT8)(Sum + ptr[Index]);
+ }
+
+ //
+ // State field (since this indicates the different state of file).
+ //
+ Sum = (UINT8)(Sum - FileHeader->State);
+ //
+ // Checksum field of the file is not part of the header checksum.
+ //
+ Sum = (UINT8)(Sum - FileHeader->IntegrityCheck.Checksum.File);
+
+ return Sum;
+}
+
+STATIC
+BOOLEAN
+EFIAPI
+PeiFileHandleToVolume (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+{
+ UINTN Index;
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (GetPeiServicesTablePointer ());
+ for (Index = 0; Index < PrivateData->FvCount; Index++) {
+ FwVolHeader = PrivateData->Fv[Index].FvHeader;
+ if (((UINTN)FileHandle > (UINTN)FwVolHeader ) && \
+ ((UINTN)FileHandle < ((UINTN)FwVolHeader + (UINTN)FwVolHeader->FvLength))) {
+ *VolumeHandle = (EFI_PEI_FV_HANDLE)FwVolHeader;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+EFI_STATUS
+PeiFindFileEx (
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN CONST EFI_GUID *FileName, OPTIONAL
+ IN EFI_FV_FILETYPE SearchType,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *AprioriFile OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+ Flag - Indicator for if this is for PEI Dispath search
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FFS_FILE_HEADER **FileHeader;
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+ UINT32 FileLength;
+ UINT32 FileOccupiedSize;
+ UINT32 FileOffset;
+ UINT64 FvLength;
+ UINT8 ErasePolarity;
+ UINT8 FileState;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer();
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)FvHandle;
+ FileHeader = (EFI_FFS_FILE_HEADER **)FileHandle;
+
+ FvLength = FwVolHeader->FvLength;
+ if (FwVolHeader->Attributes & EFI_FVB_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // If FileHeader is not specified (NULL) or FileName is not NULL,
+ // start with the first file in the firmware volume. Otherwise,
+ // start from the FileHeader.
+ //
+ if ((*FileHeader == NULL) || (FileName != NULL)) {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FwVolHeader + FwVolHeader->HeaderLength);
+ if (FwVolHeader->ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER *)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(((UINT8 *)FwVolExHeaderInfo) + FwVolExHeaderInfo->ExtHeaderSize);
+ }
+ } else {
+ //
+ // Length is 24 bits wide so mask upper 8 bits
+ // FileLength is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ FileLength = *(UINT32 *)(*FileHeader)->Size & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE (FileLength, 8);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)*FileHeader + FileOccupiedSize);
+ }
+
+ FileOffset = (UINT32) ((UINT8 *)FfsFileHeader - (UINT8 *)FwVolHeader);
+ PEI_ASSERT (PeiServices,(FileOffset <= 0xFFFFFFFF));
+
+ while (FileOffset < (FvLength - sizeof (EFI_FFS_FILE_HEADER))) {
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, FfsFileHeader);
+ switch (FileState) {
+
+ case EFI_FILE_HEADER_INVALID:
+ FileOffset += sizeof(EFI_FFS_FILE_HEADER);
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + sizeof(EFI_FFS_FILE_HEADER));
+ break;
+
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ if (CalculateHeaderChecksum (FfsFileHeader) != 0) {
+//*** AMI PORTING BEGIN ***//
+// Skip the assert to support a more sophisiticated
+// FV corruption handling outside of the Core.
+// PEI_ASSERT (PeiServices,FALSE);
+//*** AMI PORTING END *****//
+ return EFI_NOT_FOUND;
+ }
+
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+
+ if (FileName != NULL) {
+ if (CompareGuid (&FfsFileHeader->Name, (EFI_GUID*)FileName)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+ } else if (SearchType == PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE) {
+ if ((FfsFileHeader->Type == EFI_FV_FILETYPE_PEIM) ||
+ (FfsFileHeader->Type == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER)) {
+
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ } else if (AprioriFile != NULL) {
+ if (FfsFileHeader->Type == EFI_FV_FILETYPE_FREEFORM) {
+ if (CompareGuid (&FfsFileHeader->Name, &gEfiPeiAprioriGuid)) {
+ *AprioriFile = FfsFileHeader;
+ }
+ }
+ }
+ } else if ((SearchType == FfsFileHeader->Type) || (SearchType == EFI_FV_FILETYPE_ALL)) {
+ *FileHeader = FfsFileHeader;
+ return EFI_SUCCESS;
+ }
+
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ case EFI_FILE_DELETED:
+ FileLength = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileOccupiedSize = GET_OCCUPIED_SIZE(FileLength, 8);
+ FileOffset += FileOccupiedSize;
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)((UINT8 *)FfsFileHeader + FileOccupiedSize);
+ break;
+
+ default:
+ return EFI_NOT_FOUND;
+
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+VOID
+PeiInitializeFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PeiCore Fv List.
+
+Arguments:
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
+
+Returns:
+ NONE
+
+--*/
+{
+ EFI_STATUS Status;
+ //
+ // The BFV must be the first entry. The Core FV support is stateless
+ // The AllFV list has a single entry per FV in PEI.
+ // The Fv list only includes FV that PEIMs will be dispatched from and
+ // its File System Format is PI 1.0 definition.
+ //
+ PrivateData->FvCount = 1;
+ PrivateData->Fv[0].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)SecCoreData->BootFirmwareVolumeBase;
+
+ PrivateData->AllFvCount = 1;
+ PrivateData->AllFv[0] = (EFI_PEI_FV_HANDLE)PrivateData->Fv[0].FvHeader;
+
+
+ //
+ // Post a call-back for the FvInfoPPI services to expose
+ // additional Fvs to PeiCore.
+ //
+ Status = (PrivateData->PS)->NotifyPpi (&PrivateData->PS, &mNotifyList);
+ ASSERT_PEI_ERROR (&PrivateData->PS, Status);
+
+}
+
+
+
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Process Firmware Volum Information once FvInfoPPI install.
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+ Status - EFI_SUCCESS if the interface could be successfully
+ installed
+
+--*/
+{
+ UINT8 FvCount;
+ EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *Fv;
+ PEI_CORE_INSTANCE *PrivateData;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ if (PrivateData->FvCount >= PEI_CORE_MAX_FV_SUPPORTED) {
+ PEI_ASSERT (GetPeiServicesTablePointer(),FALSE);
+ }
+
+ Fv = (EFI_PEI_FIRMWARE_VOLUME_INFO_PPI *)Ppi;
+
+ if (CompareGuid (&Fv->FvFormat, &gEfiFirmwareFileSystem2Guid)) {
+ for (FvCount = 0; FvCount < PrivateData->FvCount; FvCount ++) {
+ if ((UINTN)PrivateData->Fv[FvCount].FvHeader == (UINTN)Fv->FvInfo) {
+ return EFI_SUCCESS;
+ }
+ }
+ PrivateData->Fv[PrivateData->FvCount++].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Fv->FvInfo;
+ }
+
+ //
+ // Allways add to the All list
+ //
+ PrivateData->AllFv[PrivateData->AllFvCount++] = (EFI_PEI_FV_HANDLE)Fv->FvInfo;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextVolume (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Search the next FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ Instance - The Fv Volume Instance.
+ VolumeHandle - Pointer to the current Fv Volume to search.
+
+Returns:
+ EFI_INVALID_PARAMETER - VolumeHandle is NULL.
+ EFI_NOT_FOUND - No FV Volume is found.
+ EFI_SUCCESS - The next FV Volume is found.
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *Private;
+
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+ if (VolumeHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Instance >= Private->AllFvCount) {
+ VolumeHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ *VolumeHandle = Private->AllFv[Instance];
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input FvHandle, search for the next matching type file in the FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only file of this type.
+ FvHandle - Pointer to the current FV to search.
+ FileHandle - Pointer to the file matching SearchType in FwVolHeader.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ return PeiFindFileEx (FvHandle, NULL, SearchType, FileHandle, NULL);
+}
+
+EFI_STATUS
+PeiFfsProcessSection (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_COMMON_SECTION_HEADER *Section,
+ IN UINTN SectionSize,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *Authentication
+ )
+/*++
+
+Routine Description:
+
+ Go through the file to search SectionType section,
+ when meeting an encapsuled section, search recursively.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only section of this type.
+ Section - From where to search.
+ SectionSize - The file size to search.
+ OutputBuffer - Pointer to the section to search.
+ OutputSize - The size of the section to search.
+ Authentication - Authenticate the section.
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 SectionLength;
+ UINT32 ParsedLength;
+ EFI_GUID_DEFINED_SECTION *GuidSection;
+ EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *GuidSectionPpi;
+ EFI_COMPRESSION_SECTION *CompressionSection;
+ EFI_PEI_DECOMPRESS_PPI *DecompressPpi;
+ VOID *PpiOutput;
+ UINTN PpiOutputSize;
+
+ *OutputBuffer = NULL;
+ ParsedLength = 0;
+ while (ParsedLength < SectionSize) {
+ if (Section->Type == SectionType) {
+ *OutputBuffer = (VOID *)(Section + 1);
+ return EFI_SUCCESS;
+ } else if (Section->Type == EFI_SECTION_GUID_DEFINED) {
+ GuidSection = (EFI_GUID_DEFINED_SECTION *)Section;
+ GuidSectionPpi = PeiReturnPpi (PeiServices, &GuidSection->SectionDefinitionGuid);
+ if (GuidSectionPpi != NULL) {
+ Status = GuidSectionPpi->ExtractSection (
+ GuidSectionPpi,
+ Section,
+ &PpiOutput,
+ &PpiOutputSize,
+ Authentication
+ );
+ if (!EFI_ERROR (Status)) {
+ return PeiFfsProcessSection (
+ PeiServices,
+ SectionType,
+ PpiOutput,
+ PpiOutputSize,
+ OutputBuffer,
+ OutputSize,
+ Authentication
+ );
+ }
+ }
+ } else if (Section->Type == EFI_SECTION_COMPRESSION) {
+ CompressionSection = (EFI_COMPRESSION_SECTION *)Section;
+ DecompressPpi = PeiReturnPpi (PeiServices, &gEfiPeiDecompressPpiGuid);
+ if (DecompressPpi != NULL) {
+ Status = DecompressPpi->Decompress (
+ DecompressPpi,
+ CompressionSection,
+ &PpiOutput,
+ &PpiOutputSize
+ );
+ if (!EFI_ERROR (Status)) {
+ return PeiFfsProcessSection (
+ PeiServices, SectionType, PpiOutput, PpiOutputSize, OutputBuffer, OutputSize, Authentication
+ );
+ }
+ }
+ }
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // SectionLength is adjusted it is 4 byte aligned.
+ // Go to the next section
+ //
+ SectionLength = *(UINT32 *)Section->Size & 0x00FFFFFF;
+ SectionLength = GET_OCCUPIED_SIZE (SectionLength, 4);
+ PEI_ASSERT (PeiServices, (SectionLength != 0));
+ ParsedLength += SectionLength;
+ Section = (EFI_COMMON_SECTION_HEADER *)((UINT8 *)Section + SectionLength);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FileHandle - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ UINT32 FileSize;
+ EFI_COMMON_SECTION_HEADER *Section;
+ UINTN OutputSize;
+ UINT32 AuthenticationStatus;
+
+
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
+
+ //
+ // Size is 24 bits wide so mask upper 8 bits.
+ // Does not include FfsFileHeader header size
+ // FileSize is adjusted to FileOccupiedSize as it is 8 byte aligned.
+ //
+ Section = (EFI_COMMON_SECTION_HEADER *)(FfsFileHeader + 1);
+ FileSize = *(UINT32 *)(FfsFileHeader->Size) & 0x00FFFFFF;
+ FileSize -= sizeof (EFI_FFS_FILE_HEADER);
+
+ return PeiFfsProcessSection (
+ PeiServices,
+ SectionType,
+ Section,
+ FileSize,
+ SectionData,
+ &OutputSize,
+ &AuthenticationStatus
+ );
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindFileByName (
+ IN CONST EFI_GUID *FileName,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input VolumeHandle, search for the next matching name file.
+
+Arguments:
+
+ FileName - File name to search.
+ VolumeHandle - The current FV to search.
+ FileHandle - Pointer to the file matching name in VolumeHandle.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ if ((VolumeHandle == NULL) || (FileName == NULL) || (FileHandle == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = PeiFindFileEx (VolumeHandle, FileName, 0, FileHandle, NULL);
+ if (Status == EFI_NOT_FOUND) {
+ *FileHandle = NULL;
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetFileInfo (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given file.
+
+Arguments:
+ FileHandle - The handle to file.
+ FileInfo - Pointer to the file information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ UINT8 FileState;
+ UINT8 ErasePolarity;
+ EFI_FFS_FILE_HEADER *FileHeader;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+
+ if ((FileHandle == NULL) || (FileInfo == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Retrieve the FirmwareVolume which the file resides in.
+ //
+ if (!PeiFileHandleToVolume(FileHandle, &VolumeHandle)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((EFI_FIRMWARE_VOLUME_HEADER*)VolumeHandle)->Attributes & EFI_FVB_ERASE_POLARITY) {
+ ErasePolarity = 1;
+ } else {
+ ErasePolarity = 0;
+ }
+
+ //
+ // Get FileState which is the highest bit of the State
+ //
+ FileState = GetFileState (ErasePolarity, (EFI_FFS_FILE_HEADER*)FileHandle);
+
+ switch (FileState) {
+ case EFI_FILE_DATA_VALID:
+ case EFI_FILE_MARKED_FOR_UPDATE:
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
+ CopyMem (&FileInfo->FileName, &FileHeader->Name, sizeof(EFI_GUID));
+ FileInfo->FileType = FileHeader->Type;
+ FileInfo->FileAttributes = FileHeader->Attributes;
+ FileInfo->BufferSize = ((*(UINT32 *)FileHeader->Size) & 0x00FFFFFF) - sizeof (EFI_FFS_FILE_HEADER);
+ FileInfo->Buffer = (FileHeader + 1);
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given Fv Volume.
+
+Arguments:
+ VolumeHandle - The handle to Fv Volume.
+ VolumeInfo - The pointer to volume information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+{
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+ EFI_FIRMWARE_VOLUME_EXT_HEADER *FwVolExHeaderInfo;
+
+ if (VolumeInfo == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)VolumeHandle;
+ VolumeInfo->FvAttributes = FwVolHeader->Attributes;
+ VolumeInfo->FvStart = FwVolHeader;
+ VolumeInfo->FvSize = FwVolHeader->FvLength;
+ CopyMem (&VolumeInfo->FvFormat, &FwVolHeader->FileSystemGuid,sizeof(EFI_GUID));
+
+ if (FwVolHeader->ExtHeaderOffset != 0) {
+ FwVolExHeaderInfo = (EFI_FIRMWARE_VOLUME_EXT_HEADER*)(((UINT8 *)FwVolHeader) + FwVolHeader->ExtHeaderOffset);
+ CopyMem (&VolumeInfo->FvName, &FwVolExHeaderInfo->FvName, sizeof(EFI_GUID));
+ }
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Hob.c b/Core/CORE_PEI/CORE_PEI_PI/Hob.c
new file mode 100644
index 0000000..30b7b3f
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Hob.c
@@ -0,0 +1,191 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Hob.c
+
+Abstract:
+
+ EFI PEI Core HOB services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+{
+ //
+ // Only check this parameter in debug mode
+ //
+
+ PEI_DEBUG_CODE (
+ if (HobList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ )
+
+ *HobList = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices)->HobList.Raw;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_HANDOFF_INFO_TABLE *HandOffHob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+ EFI_PHYSICAL_ADDRESS FreeMemory;
+
+
+ Status = PeiGetHobList (PeiServices, Hob);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ HandOffHob = *Hob;
+
+ Length = (UINT16)((Length + 0x7) & (~0x7));
+
+ FreeMemory = HandOffHob->EfiFreeMemoryTop -
+ HandOffHob->EfiFreeMemoryBottom;
+
+ if (FreeMemory < Length) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiCreateHob fail: Length - 0x%08x\n", (UINTN)Length));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)HandOffHob->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ *Hob = (VOID*) (UINTN) HandOffHob->EfiEndOfHobList;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobType = Type;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->HobLength = Length;
+ ((EFI_HOB_GENERIC_HEADER*) *Hob)->Reserved = 0;
+
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) ((UINTN) *Hob + Length);
+ HandOffHob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+ HobEnd++;
+ HandOffHob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Hob;
+ EFI_HOB_GENERIC_HEADER *HobEnd;
+
+ Hob = (VOID *)(UINTN)MemoryBegin;
+ HobEnd = (EFI_HOB_GENERIC_HEADER*) (Hob+1);
+ Hob->Header.HobType = EFI_HOB_TYPE_HANDOFF;
+ Hob->Header.HobLength = sizeof(EFI_HOB_HANDOFF_INFO_TABLE);
+ Hob->Header.Reserved = 0;
+
+ HobEnd->HobType = EFI_HOB_TYPE_END_OF_HOB_LIST;
+ HobEnd->HobLength = sizeof(EFI_HOB_GENERIC_HEADER);
+ HobEnd->Reserved = 0;
+
+ Hob->Version = EFI_HOB_HANDOFF_TABLE_VERSION;
+ Hob->BootMode = BootMode;
+
+ Hob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiMemoryBottom = MemoryBegin;
+ Hob->EfiFreeMemoryTop = MemoryBegin + MemoryLength;
+ Hob->EfiFreeMemoryBottom = (EFI_PHYSICAL_ADDRESS) (UINTN) (HobEnd+1);
+ Hob->EfiEndOfHobList = (EFI_PHYSICAL_ADDRESS) (UINTN) HobEnd;
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Image.c b/Core/CORE_PEI/CORE_PEI_PI/Image.c
new file mode 100644
index 0000000..a6967e0
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Image.c
@@ -0,0 +1,932 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Image.c
+
+Abstract:
+
+ Pei Core Load Image Support
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include "PeiApi.h"
+#include "EfiImage.h"
+#include EFI_PROTOCOL_DEFINITION (CustomizedDecompress)
+
+#include EFI_PPI_DEFINITION (LoadFile2)
+#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
+#include EFI_PPI_DEFINITION (SectionExtraction)
+
+
+EFI_STATUS
+EFIAPI
+PeiImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+ FileOffset - The offset, in bytes, into the file to read
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+ Buffer - A pointer to the buffer to read the data into.
+
+Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+--*/
+;
+
+EFI_STATUS
+PeiLoadImageLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for loading file image.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiLoadImageLoadImageWrapper (
+ IN CONST EFI_PEI_LOAD_FILE_PPI *This,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ The wrapper function of PeiLoadImageLoadImage().
+
+Arguments:
+
+ This - Pointer to EFI_PEI_LOAD_FILE_PPI.
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ EFI_STATUS.
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetEntryPoint (
+ IN VOID *Pe32Data,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image entry point.
+
+Arguments:
+
+ Pe32Data - Pointer to PE image.
+ EntryPoint - Pointer to entry point of PE image.
+
+Returns:
+
+ EFI_SUCCESS.
+
+--*/
+;
+
+EFI_IMAGE_NT_HEADERS*
+EFIAPI
+GetPeHeader (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Pe32Data
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image header.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Pe32Data - Pointer to PE image.
+
+Returns:
+
+ Pointer to PE header.
+
+--*/
+;
+
+static EFI_PEI_LOAD_FILE_PPI mPeiLoadImagePpi = {
+ PeiLoadImageLoadImageWrapper
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiLoadFile2PpiGuid,
+ &mPeiLoadImagePpi
+};
+
+EFI_STATUS
+EFIAPI
+PeiImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Support routine for the PE/COFF Loader that reads a buffer from a PE/COFF file
+
+Arguments:
+
+ FileHandle - The handle to the PE/COFF file
+ FileOffset - The offset, in bytes, into the file to read
+ ReadSize - The number of bytes to read from the file starting at FileOffset
+ Buffer - A pointer to the buffer to read the data into.
+
+Returns:
+
+ EFI_SUCCESS - ReadSize bytes of data were read into Buffer from the PE/COFF file starting at FileOffset
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+ UINTN Length;
+
+ Destination8 = Buffer;
+ Source8 = (CHAR8 *) ((UINTN) FileHandle + FileOffset);
+ Length = *ReadSize;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+GetImageReadFunction (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Support routine to return the Image Read
+
+Arguments:
+
+ PeiServices - PEI Services Table
+
+ ImageContext - The context of the image being loaded
+
+Returns:
+
+ EFI_SUCCESS - If Image function location is found
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemoryBuffer;
+
+ Status = (*PeiServices)->AllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ 0x400 / EFI_PAGE_SIZE + 1,
+ &MemoryBuffer
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ (*PeiServices)->CopyMem (
+ (VOID *) (UINTN) MemoryBuffer,
+ (VOID *) (UINTN) PeiImageRead,
+ 0x400
+ );
+
+ ImageContext->ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) (UINTN) MemoryBuffer;
+
+ return Status;
+}
+
+EFI_STATUS
+PeiLoadImageLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for loading file image.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_CORE_INSTANCE *Private;
+ VOID *Pe32Data;
+ EFI_TE_IMAGE_HEADER *TEImageHeader;
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeCoffLoader;
+
+#ifdef EFI_NT_EMULATOR
+ EFI_PEI_PPI_DESCRIPTOR *PpiDescriptor;
+ NT_PEI_LOAD_FILE_PPI *PeiNtService;
+#else
+ VOID *EntryPointPtr;
+#endif
+//*** AMI PORTING BEGIN ***//
+//This is needed to enable execution of compressed PEIMS
+//and PEIMS from the firmware volumes in memory (see below).
+ BOOLEAN FixupRequired = FALSE;
+//*** AMI PORTING END *****//
+
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ *EntryPoint = 0;
+ *AuthenticationState = 0;
+ ImageAddress = 0;
+ ImageSize = 0;
+ PeHdr = NULL;
+
+ //
+ // Try to find a TE or PE32 section.
+ //
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_TE,
+ FileHandle,
+ (VOID **)&TEImageHeader
+ );
+ Pe32Data = TEImageHeader;
+ if (EFI_ERROR (Status)) {
+ Status = PeiFfsFindSectionData (
+ PeiServices,
+ EFI_SECTION_PE32,
+ FileHandle,
+ &Pe32Data
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ //
+ // NO image types we support so exit.
+ //
+ return Status;
+ }
+
+ //
+ // Check image header machine type. If not supported, skip it.
+ //
+ if (TEImageHeader != NULL) {
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (TEImageHeader->Machine) &&
+ !EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (TEImageHeader->Machine)) {
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ //
+ // Get PE32 Header to check machine type.
+ //
+ PeHdr = GetPeHeader(PeiServices, Pe32Data);
+ if (!EFI_IMAGE_MACHINE_TYPE_SUPPORTED (PeHdr->FileHeader.Machine) &&
+ !EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED (PeHdr->FileHeader.Machine)) {
+ return EFI_UNSUPPORTED;
+ }
+//*** AMI PORTING BEGIN ***//
+//This is needed to enable execution of compressed PEIMS
+//and PEIMS from the firmware volumes in memory.
+ if (PeHdr->OptionalHeader.ImageBase != (UINTN)Pe32Data)
+ FixupRequired = TRUE;
+//*** AMI PORTING END *****//
+ }
+
+ if (Private->PeiMemoryInstalled &&
+ (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME || FixupRequired)) {
+ //
+ // Load, relocate, and run image in memory
+ //
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+ ImageContext.Handle = Pe32Data;
+ if (Private->ImageReadFile == NULL) {
+ GetImageReadFunction (PeiServices, &ImageContext);
+ Private->ImageReadFile = ImageContext.ImageRead;
+ } else {
+ ImageContext.ImageRead = Private->ImageReadFile;
+ }
+ PeCoffLoader = Private->PeCoffLoader;
+ Status = PeCoffLoader->GetImageInfo (PeCoffLoader, &ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Allocate Memory for the image
+ //
+ Status = PeiAllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES ((UINT32) ImageContext.ImageSize),
+ &ImageContext.ImageAddress
+ );
+ ASSERT_PEI_ERROR (PeiServices,Status);
+
+ if (ImageContext.IsTeImage &&
+ TEImageHeader->Machine == EFI_IMAGE_MACHINE_IA64) {
+ ImageContext.ImageAddress = ImageContext.ImageAddress +
+ TEImageHeader->StrippedSize -
+ sizeof (EFI_TE_IMAGE_HEADER);
+ }
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoader->LoadImage (PeCoffLoader, &ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoader->RelocateImage (PeCoffLoader, &ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Flush the instruction cache so the image data is written before we execute it
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+
+ ImageAddress = ImageContext.ImageAddress;
+ ImageSize = ImageContext.ImageSize;
+ *EntryPoint = ImageContext.EntryPoint;
+ }
+#ifndef EFI_NT_EMULATOR
+ else if (TEImageHeader != NULL) {
+ //
+ // Get entry point from the TE image header
+ //
+ ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)TEImageHeader;
+//*** AMI PORTING BEGIN ***//
+//Bug fix: the function must return a valid image size
+// The original implmentation always returns NULL for XIP images.
+ ImageSize = FVSECTION_SIZE(TEImageHeader);
+// ImageSize = 0;
+//*** AMI PORTING END ***//
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ //
+ // Retrieve the entry point from the PE/COFF image header
+ //
+ ImageAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Pe32Data;
+//*** AMI PORTING BEGIN ***//
+//Bug fix: the function must return a valid image size
+// The original implmentation always returns NULL for XIP images.
+ ImageSize = PeHdr->OptionalHeader.SizeOfImage;
+// ImageSize = 0;
+//*** AMI PORTING END ***//
+ Status = PeCoffLoaderGetEntryPoint (Pe32Data, &EntryPointPtr);
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPointPtr;
+ if (EFI_ERROR (Status)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+#else
+ else {
+ if (TEImageHeader == NULL) {
+ PeHdr = GetPeHeader(PeiServices,Pe32Data);
+ }
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gNtPeiLoadFileGuid,
+ 0,
+ &PpiDescriptor,
+ &PeiNtService
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = PeiNtService->PeiLoadFileService (
+ Pe32Data,
+ &ImageAddress,
+ &ImageSize,
+ EntryPoint
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (TEImageHeader != NULL) {
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS)((UINTN) TEImageHeader + sizeof (EFI_TE_IMAGE_HEADER) +
+ TEImageHeader->AddressOfEntryPoint - TEImageHeader->StrippedSize);
+ } else {
+ *EntryPoint = (EFI_PHYSICAL_ADDRESS) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ }
+ }
+ }
+#endif
+
+
+ if (ImageAddressArg != NULL) {
+ *ImageAddressArg = ImageAddress;
+ }
+
+ if (ImageSizeArg != NULL) {
+ *ImageSizeArg = ImageSize;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Message is printed later. Disable this one
+/*
+ //
+ // Print debug message: Loading PEIM at 0x12345678 EntryPoint=0x12345688 Driver.efi
+ //
+ PEI_DEBUG ((PeiServices,EFI_D_INFO | EFI_D_LOAD, "Loading PEIM at 0x%08x EntryPoint=0x%08x ", Pe32Data, *EntryPoint));
+ PEI_DEBUG_CODE (
+ {
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN DirCount;
+ UINTN Index;
+ UINTN Index1;
+ BOOLEAN FileNameFound;
+ CHAR8 *AsciiString;
+ CHAR8 AsciiBuffer[512];
+ VOID *CodeViewEntryPointer;
+ INTN TEImageAdjust;
+ EFI_IMAGE_DOS_HEADER *DosHeader;
+ EFI_IMAGE_NT_HEADERS *PeHeader;
+
+ DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header
+ //
+ PeHeader = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((DosHeader->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base
+ //
+ PeHeader = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+ }
+
+ //
+ // Find the codeview info in the image and display the file name
+ // being loaded.
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ DebugEntry = NULL;
+ DirectoryEntry = NULL;
+ TEImageAdjust = 0;
+ if (TEImageHeader == NULL) {
+ if (PeHeader->OptionalHeader.NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *) &(PeHeader->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *) ((UINTN) ImageAddress + DirectoryEntry->VirtualAddress);
+ }
+ } else {
+ if (TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress != 0) {
+ DirectoryEntry = &TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG];
+ TEImageAdjust = sizeof (EFI_TE_IMAGE_HEADER) - TEImageHeader->StrippedSize;
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)((UINTN) TEImageHeader +
+ TEImageHeader->DataDirectory[EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG].VirtualAddress +
+ TEImageAdjust);
+ }
+ }
+
+ if (DebugEntry != NULL && DirectoryEntry != NULL) {
+ for (DirCount = 0; DirCount < DirectoryEntry->Size; DirCount++, DebugEntry++) {
+ if (DebugEntry->Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ if (DebugEntry->SizeOfData > 0) {
+ CodeViewEntryPointer = (VOID *) ((UINTN) DebugEntry->RVA + (UINTN) ImageAddress + (UINTN)TEImageAdjust);
+ switch (* (UINT32 *) CodeViewEntryPointer) {
+ case CODEVIEW_SIGNATURE_NB10:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ AsciiString = (CHAR8 *) CodeViewEntryPointer + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ default:
+ AsciiString = NULL;
+ break;
+ }
+ if (AsciiString != NULL) {
+ FileNameFound = FALSE;
+ for (Index = 0, Index1 = 0; AsciiString[Index] != 0; Index++) {
+ if (AsciiString[Index] == '\\') {
+ Index1 = Index;
+ FileNameFound = TRUE;
+ }
+ }
+
+ if (FileNameFound) {
+ for (Index = Index1 + 1; AsciiString[Index] != '.'; Index++) {
+ AsciiBuffer[Index - (Index1 + 1)] = AsciiString[Index];
+ }
+ AsciiBuffer[Index - (Index1 + 1)] = 0;
+ PEI_DEBUG ((PeiServices,EFI_D_INFO | EFI_D_LOAD, "%a.efi", AsciiBuffer));
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ )
+
+ PEI_DEBUG ((PeiServices,EFI_D_INFO | EFI_D_LOAD, "\n"));
+*/
+//*** AMI PORTING END ***//
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiLoadImageLoadImageWrapper (
+ IN CONST EFI_PEI_LOAD_FILE_PPI *This,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *ImageAddressArg, OPTIONAL
+ OUT UINT64 *ImageSizeArg, OPTIONAL
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ The wrapper function of PeiLoadImageLoadImage().
+
+Arguments:
+
+ This - Pointer to EFI_PEI_LOAD_FILE_PPI.
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ ImageAddressArg - Pointer to PE/TE image.
+ ImageSizeArg - Size of PE/TE image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ EFI_STATUS.
+
+--*/
+{
+ return PeiLoadImageLoadImage (
+ GetPeiServicesTablePointer (),
+ FileHandle,
+ ImageAddressArg,
+ ImageSizeArg,
+ EntryPoint,
+ AuthenticationState
+ );
+}
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for load image file.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+{
+ EFI_STATUS PpiStatus;
+ EFI_STATUS Status;
+ UINTN Index;
+ EFI_PEI_LOAD_FILE_PPI *LoadFile;
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ UINT16 Magic;
+ UINT16 Machine;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_TE_IMAGE_HEADER *TeHdr;
+
+ //
+ // If any instances of PEI_LOAD_FILE_PPI are installed, they are called.
+ // one at a time, until one reports EFI_SUCCESS.
+ //
+ Index = 0;
+ do {
+ PpiStatus = PeiLocatePpi (
+ PeiServices,
+ &gEfiLoadFile2PpiGuid,
+ Index,
+ NULL,
+ (VOID **)&LoadFile
+ );
+ if (!EFI_ERROR (PpiStatus)) {
+ Status = LoadFile->LoadFile (
+ LoadFile,
+ FileHandle,
+ &ImageAddress,
+ &ImageSize,
+ EntryPoint,
+ AuthenticationState
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Only support image machine type that is the same as PEI core.
+ // Get the image's machine type to check if supported.
+ //
+ Magic = *(UINT16 *)(UINTN) ImageAddress;
+ if (Magic == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ TeHdr = (EFI_TE_IMAGE_HEADER *)(UINTN) ImageAddress;
+ Machine = TeHdr->Machine;
+ } else {
+ if (Magic == EFI_IMAGE_DOS_SIGNATURE) {
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)((UINTN) ImageAddress + (UINTN) ((((EFI_IMAGE_DOS_HEADER *)(UINTN) ImageAddress)->e_lfanew) & 0x0ffff));
+ } else {
+ PeHdr = (EFI_IMAGE_NT_HEADERS *)(UINTN) ImageAddress;
+ }
+ Machine = PeHdr->FileHeader.Machine;
+ }
+ if (Machine == EFI_IMAGE_MACHINE_TYPE) {
+//*** AMI PORTING BEGIN ***//
+//break from the loop to print debug message (see below)
+// return EFI_SUCCESS;
+ PpiStatus=EFI_SUCCESS;
+ break;
+//*** AMI PORTING END *****//
+ } else {
+//*** AMI PORTING BEGIN ***//
+//break from the loop to print debug message (see below)
+// return EFI_UNSUPPORTED;
+ PpiStatus=EFI_SUCCESS;
+ break;
+//*** AMI PORTING END *****//
+ }
+ }
+ }
+ Index++;
+ } while (!EFI_ERROR (PpiStatus));
+//*** AMI PORTING BEGIN ***//
+//Print debug message
+#ifdef EFI_DEBUG
+{
+ EFI_FFS_FILE_HEADER *PeimFileHeader = (EFI_FFS_FILE_HEADER*)FileHandle;
+ if(!EFI_ERROR(PpiStatus))
+ {
+ char sName[0x100];
+ if (!GetName((VOID*)(UINTN)ImageAddress,sName))
+ Sprintf_s(sName,sizeof(sName),"[%G]",&PeimFileHeader->Name);
+ PeiTrace(TRACE_PEICORE, PeiServices, "%s.Entry(%X)\n", sName, *EntryPoint);
+ }
+ else
+ {
+ PeiTrace(
+ TRACE_PEICORE, PeiServices,
+ "ERROR: attempt to load FFS file [%G] has failed\n",
+ &PeimFileHeader->Name
+ );
+ }
+}
+#endif
+//New image is loaded and is about to be launched
+//Update LoadedImage PPI information
+ if(!EFI_ERROR(PpiStatus))
+ UpdatedLoadedImagePpi(PeiServices,ImageAddress,ImageSize,FileHandle);
+//*** AMI PORTING END *****//
+ return PpiStatus;
+}
+
+
+VOID
+InitializeImageServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Regitser PeCoffLoader to PeiCore PrivateData. And install
+ Pei Load File PPI.
+
+Arguments:
+
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ OldCoreData - Pointer to PEI_CORE_INSTANCE.
+
+Returns:
+
+ NONE.
+
+--*/
+{
+ EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeiEfiPeiPeCoffLoader;
+
+ InstallEfiPeiPeCoffLoader (&PrivateData->PS, &PeiEfiPeiPeCoffLoader, NULL);
+ PrivateData->PeCoffLoader = PeiEfiPeiPeCoffLoader;
+
+ if (OldCoreData == NULL) {
+ //
+ // The first time we are XIP (running from FLASH). We need to remember the
+ // FLASH address so we can reinstall the memory version that runs faster
+ //
+ PrivateData->XipLoadFile = &gPpiLoadFilePpiList;
+ PeiInstallPpi (&PrivateData->PS, PrivateData->XipLoadFile);
+ } else {
+ //
+ // 2nd time we are running from memory so replace the XIP version with the
+ // new memory version.
+ //
+ PeiReInstallPpi (&PrivateData->PS, PrivateData->XipLoadFile, &gPpiLoadFilePpiList);
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetEntryPoint (
+ IN VOID *Pe32Data,
+ OUT VOID **EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image entry point.
+
+Arguments:
+
+ Pe32Data - Pointer to PE image.
+ EntryPoint - Pointer to entry point of PE image.
+
+Returns:
+
+ EFI_SUCCESS.
+
+--*/
+{
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeHdr = NULL;
+ PeiServices = GetPeiServicesTablePointer();
+
+ PEI_ASSERT (PeiServices, (Pe32Data != NULL));
+ PEI_ASSERT (PeiServices,(EntryPoint != NULL));
+
+ PeHdr = GetPeHeader(PeiServices, Pe32Data);
+
+ //
+ // Calculate the entry point relative to the start of the image.
+ // AddressOfEntryPoint is common for PE32 & PE32+
+ //
+ *EntryPoint = (VOID *) ((UINTN) Pe32Data + (UINTN) (PeHdr->OptionalHeader.AddressOfEntryPoint & 0x0ffffffff));
+ return EFI_SUCCESS;
+}
+
+EFI_IMAGE_NT_HEADERS*
+EFIAPI
+GetPeHeader (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Pe32Data
+ )
+/*++
+
+Routine Description:
+
+ Routine for get PE image header.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Pe32Data - Pointer to PE image.
+
+Returns:
+
+ Pointer to PE header.
+
+--*/
+{
+ EFI_IMAGE_DOS_HEADER *DosHeader;
+ EFI_IMAGE_NT_HEADERS *PeHdr;
+
+ PeHdr = NULL;
+ PEI_ASSERT (PeiServices, (Pe32Data != NULL));
+
+ DosHeader = (EFI_IMAGE_DOS_HEADER *)Pe32Data;
+ if (DosHeader->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image header.
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) ((UINTN) Pe32Data + (UINTN) ((((EFI_IMAGE_DOS_HEADER *) Pe32Data)->e_lfanew) & 0x0ffff));
+ } else {
+ //
+ // DOS image header is not present, so PE header is at the image base.
+ //
+ PeHdr = (EFI_IMAGE_NT_HEADERS *) Pe32Data;
+ }
+ return PeHdr;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c b/Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c
new file mode 100644
index 0000000..05a0ff3
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/MemoryServices.c
@@ -0,0 +1,392 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ MemoryServices.c
+
+Abstract:
+
+ EFI PEI Core memory services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiApi.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+//*** AMI PORTING BEGIN ***//
+//use SDL token 'DXE_STACK_SIZE' to define stack size
+#include <Token.h>
+#undef PEI_STACK_SIZE
+#define PEI_STACK_SIZE DXE_STACK_SIZE
+//*** AMI PORTING END *****//
+
+VOID
+InitializeMemoryServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+{
+ PrivateData->SwitchStackSignal = FALSE;
+
+ if (OldCoreData == NULL) {
+ //
+ // 1st time through we are using Temp memory
+ //
+ PrivateData->PeiMemoryInstalled = FALSE;
+ PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase;
+ PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);
+
+ PEI_DEBUG_CODE (
+ {
+ PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;
+ PrivateData->MaxTopOfCarHeap = (VOID*)((UINTN)PrivateData->BottomOfCarHeap + PrivateData->SizeOfCacheAsRam);
+ }
+ )
+
+ PrivateData->HobList.Raw = PrivateData->BottomOfCarHeap;
+
+ PeiCoreBuildHobHandoffInfoTable (
+ BOOT_WITH_FULL_CONFIGURATION,
+ (EFI_PHYSICAL_ADDRESS) (UINTN) PrivateData->BottomOfCarHeap,
+ (UINTN) SecCoreData->PeiTemporaryRamSize
+ );
+ }
+
+ return;
+}
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
+ EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
+ UINT64 PeiStackSize;
+ UINT64 EfiFreeMemorySize;
+ EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+//*** AMI PORTING BEGIN ***//
+ if (PrivateData->PeiMemoryInstalled) {
+ //This function should be called once. Report error if this is the second call
+ PEI_ERROR_CODE(PeiServices, PEI_MEMORY_INSTALLED_TWICE, EFI_ERROR_MINOR);
+ }else {
+ //Debug message
+ PEI_TRACE((TRACE_PEICORE, PeiServices, "Memory Installed: Address=%lX; Length=%lX\n",MemoryBegin,MemoryLength));
+ }
+//*** AMI PORTING END *****//
+
+ PrivateData->SwitchStackSignal = TRUE;
+ PrivateData->PeiMemoryInstalled = TRUE;
+
+ PrivateData->StackBase = MemoryBegin;
+
+ PeiStackSize = RShiftU64 (MemoryLength, 1);
+ if (PEI_STACK_SIZE > PeiStackSize) {
+ PrivateData->StackSize = PeiStackSize;
+ } else {
+ PrivateData->StackSize = PEI_STACK_SIZE;
+ }
+
+ OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
+
+ PrivateData->HobList.Raw = (VOID *)((UINTN)(MemoryBegin + PrivateData->StackSize));
+ NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
+ PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
+
+ EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
+
+ PeiCoreCopyMem (
+ NewHandOffHob,
+ OldHandOffHob,
+ (UINTN)EfiFreeMemorySize
+ );
+
+ NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
+ NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
+ NewHandOffHob->EfiMemoryBottom = MemoryBegin;
+
+ NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
+
+ NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
+ (OldHandOffHob->EfiEndOfHobList -
+ PhysicalAddressOfOldHob);
+
+ ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
+
+ PeiBuildHobStack ((EFI_PEI_SERVICES**)PeiServices, PrivateData->StackBase, PrivateData->StackSize);
+
+//*** AMI PORTING BEGIN ***//
+//Update LoadedImage pointers
+PrivateData->LoadedImage = (EFI_PEI_PPI_DESCRIPTOR*)
+ ( (UINTN)PrivateData->LoadedImage + ((UINTN)NewHandOffHob - (UINTN)OldHandOffHob) );
+//*** AMI PORTING END *****//
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address before memory init = 0x%08x\n", OldHandOffHob));
+ PEI_DEBUG ((PeiServices, EFI_D_INFO, "HOBLIST address after memory init = 0x%08x\n", NewHandOffHob));
+ }
+ )
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PHYSICAL_ADDRESS Offset;
+ EFI_STATUS Status;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Check if Hob already available
+ //
+ if (!PrivateData->PeiMemoryInstalled) {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+
+ Hob.Raw = PrivateData->HobList.Raw;
+
+ //
+ // Check to see if on 4k boundary
+ //
+ Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
+
+ //
+ // If not aligned, make the allocation aligned.
+ //
+ if (Offset != 0) {
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
+ }
+
+ //
+ // Verify that there is sufficient memory to satisfy the allocation
+ //
+ if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
+ Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
+ PEI_DEBUG_CODE (
+ {
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, "PeiAllocatePages fail: Pages - 0x%08x\n", Pages));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryTop - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop));
+ PEI_DEBUG ((PeiServices, EFI_D_ERROR, " FreeMemoryBottom - 0x%08x\n", (UINTN)Hob.HandoffInformationTable->EfiFreeMemoryBottom));
+ }
+ )
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ //
+ // Update the PHIT to reflect the memory usage
+ //
+ Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
+
+ //
+ // Update the value for the caller
+ //
+ *Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
+
+ //
+ // Create a memory allocation HOB.
+ //
+ Status = PeiBuildHobMemoryAllocation (
+ (EFI_PEI_SERVICES**)PeiServices,
+ Hob.HandoffInformationTable->EfiFreeMemoryTop,
+ Pages * EFI_PAGE_SIZE + Offset,
+ NULL,
+ MemoryType
+ );
+
+ return Status;
+ }
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_HOB_MEMORY_POOL *Hob;
+
+
+ Status = PeiCreateHob (
+ PeiServices,
+ EFI_HOB_TYPE_PEI_MEMORY_POOL,
+ (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
+ &Hob
+ );
+ *Buffer = Hob+1;
+
+
+ return Status;
+}
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibCopyMem (Destination, Source, Length);
+}
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+{
+ EfiCommonLibSetMem (Buffer, Size, Value);
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/PeiCore.h b/Core/CORE_PEI/CORE_PEI_PI/PeiCore.h
new file mode 100644
index 0000000..2913deb
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/PeiCore.h
@@ -0,0 +1,1416 @@
+/*++
+
+Copyright (c) 2004 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiCore.h
+
+Abstract:
+
+ Definition of Pei Core Structures and Services
+
+Revision History
+
+--*/
+
+#ifndef _PEICORE_H_
+#define _PEICORE_H_
+
+#include "EfiImage.h"
+#include "Pei.h"
+#include "PeiLib.h"
+#include "PeiApi.h"
+#include "PeiHob.h"
+#include "PeiDebug.h"
+#include "EfiFirmwareFileSystem.h"
+#include "EfiFirmwareVolumeHeader.h"
+#ifdef EFI64
+#include "SalApi.h"
+#endif
+
+#include "EfiCommonLib.h"
+#include EFI_GUID_DEFINITION (FirmwareFileSystem2)
+#include EFI_GUID_DEFINITION (PeiApriori)
+#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
+#include EFI_PPI_DEFINITION (Reset)
+#include EFI_PPI_DEFINITION (DxeIpl)
+#include EFI_PPI_DEFINITION (StatusCode)
+#include EFI_PPI_DEFINITION (Security2)
+#include EFI_PPI_DEFINITION (Decompress)
+#include EFI_PPI_DEFINITION (FirmwareVolumeInfo)
+#include EFI_PPI_DEFINITION (LoadFile2)
+#include EFI_PPI_DEFINITION (FirmwareVolume)
+#include EFI_PPI_DEFINITION (GuidedSectionExtraction)
+
+
+#ifdef EFI_NT_EMULATOR
+#include EFI_PPI_DEFINITION (NtPeiLoadFile)
+#endif
+
+//*** AMI PORTING BEGIN ***//
+#include <PPI/LoadedImagePpi.h>
+//*** AMI PORTING END *****//
+
+//
+//Build private HOB to PEI core to transfer old NEM-range data to new NEM-range
+//
+#define EFI_PEI_CORE_PRIVATE_GUID \
+ {0xd641a0f5, 0xcb7c, 0x4846, 0xa3, 0x80, 0x1d, 0x01, 0xb4, 0xd9, 0xe3, 0xb9}
+
+#define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE 0xff
+
+//
+// Pei Core private data structures
+//
+typedef union {
+ EFI_PEI_PPI_DESCRIPTOR *Ppi;
+ EFI_PEI_NOTIFY_DESCRIPTOR *Notify;
+ VOID *Raw;
+} PEI_PPI_LIST_POINTERS;
+
+
+#define PEI_STACK_SIZE 0x20000
+#define MAX_PPI_DESCRIPTORS 128
+
+typedef struct {
+ INTN PpiListEnd;
+ INTN NotifyListEnd;
+ INTN DispatchListEnd;
+ INTN LastDispatchedInstall;
+ INTN LastDispatchedNotify;
+ PEI_PPI_LIST_POINTERS PpiListPtrs[MAX_PPI_DESCRIPTORS];
+} PEI_PPI_DATABASE;
+
+
+#define PEI_CORE_MAX_FV_SUPPORTED 8
+#define PEI_CORE_MAX_PEIM_PER_FV 64
+
+//
+// PEI_CORE_FV_HANDE.PeimState
+// Do not change these values as there is code doing math to change states.
+// Look for Private->Fv[FvCount].PeimState[PeimCount]++;
+//
+#define PEIM_STATE_NOT_DISPATCHED 0x00
+#define PEIM_STATE_DISPATCHED 0x01
+#define PEIM_STATE_REGISITER_FOR_SHADOW 0x02
+#define PEIM_STATE_DONE 0x03
+
+typedef struct {
+ EFI_FIRMWARE_VOLUME_HEADER *FvHeader;
+ UINT8 PeimState[PEI_CORE_MAX_PEIM_PER_FV];
+ EFI_PEI_FILE_HANDLE FvFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
+ BOOLEAN ScanFv;
+} PEI_CORE_FV_HANDLE;
+
+//
+// Pei Core private data structure instance
+//
+#define PEI_CORE_HANDLE_SIGNATURE EFI_SIGNATURE_32('P','e','i','C')
+
+typedef struct{
+ UINTN Signature;
+ EFI_PEI_SERVICES *PS;
+ PEI_PPI_DATABASE PpiData;
+ UINTN FvCount;
+ PEI_CORE_FV_HANDLE Fv[PEI_CORE_MAX_FV_SUPPORTED];
+ EFI_PEI_FILE_HANDLE CurrentFvFileHandles[PEI_CORE_MAX_PEIM_PER_FV];
+ UINTN AprioriCount;
+ UINTN CurrentPeimFvCount;
+ UINTN CurrentPeimCount;
+ EFI_PEI_FILE_HANDLE CurrentFileHandle;
+ BOOLEAN PeimNeedingDispatch;
+ BOOLEAN PeimDispatchOnThisPass;
+ BOOLEAN PeimDispatcherReenter;
+ UINTN AllFvCount;
+ EFI_PEI_FV_HANDLE AllFv[PEI_CORE_MAX_FV_SUPPORTED];
+ EFI_PEI_HOB_POINTERS HobList;
+ BOOLEAN SwitchStackSignal;
+ BOOLEAN PeiMemoryInstalled;
+ EFI_PHYSICAL_ADDRESS StackBase;
+ UINT64 StackSize;
+ VOID *BottomOfCarHeap;
+ VOID *TopOfCarHeap;
+ VOID *CpuIo;
+ EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi;
+ EFI_PEI_SERVICES ServiceTableShadow;
+ UINTN SizeOfCacheAsRam;
+ VOID *MaxTopOfCarHeap;
+ EFI_PEI_PPI_DESCRIPTOR *XipLoadFile;
+ EFI_PEI_PE_COFF_LOADER_PROTOCOL *PeCoffLoader;
+ EFI_PEI_PE_COFF_LOADER_READ_FILE ImageReadFile;
+//*** AMI PORTING BEGIN ***//
+ EFI_PEI_PPI_DESCRIPTOR *LoadedImage;
+ EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+//*** AMI PORTING END *****//
+} PEI_CORE_INSTANCE;
+
+
+//
+// Pei Core Instance Data Macros
+//
+
+#define PEI_CORE_INSTANCE_FROM_PS_THIS(a) \
+ (PEI_CR(a, PEI_CORE_INSTANCE, PS, PEI_CORE_HANDLE_SIGNATURE))
+
+
+typedef
+EFI_STATUS
+(EFIAPI *PEI_CORE_ENTRY_POINT) (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ );
+
+
+VOID
+SwitchCoreStacks (
+ IN VOID *EntryPoint,
+ IN UINTN Parameter1,
+ IN UINTN Parameter2,
+ IN UINTN Parameter3,
+ IN VOID *NewStack
+ )
+/*++
+
+Routine Description:
+
+ Routine for PEI switching stacks.
+
+Arguments:
+
+ EntryPoint - Entry point with new stack.
+ Parameter1 - First parameter for entry point.
+ Parameter2 - Second parameter for entry point.
+ NewStack - Pointer to new stack.
+
+Returns:
+
+ None
+
+--*/
+;
+extern EFI_PEI_PPI_DESCRIPTOR gPpiLoadFilePpiList;
+
+
+typedef
+VOID
+(EFIAPI *SWITCH_STACK_ENTRY_POINT) (
+ IN VOID *Context1, OPTIONAL
+ IN VOID *Context2 OPTIONAL
+ );
+
+
+
+//
+// Main PEI entry
+//
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+
+--*/
+;
+
+
+//
+// Dispatcher support functions
+//
+
+BOOLEAN
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+;
+
+
+VOID
+PeiDispatcher (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *Private
+ )
+
+/*++
+
+Routine Description:
+
+ Conduct PEIM dispatch.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ Private - Pointer to the private data passed in from caller
+
+Returns:
+
+ EFI_SUCCESS - Successfully dispatched PEIM.
+ EFI_NOT_FOUND - The dispatch failed.
+
+--*/
+;
+
+
+VOID
+InitializeDispatcherData (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the Dispatcher's data members
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to old core data (before switching stack).
+ NULL if being run in non-permament memory mode.
+ SecCoreData - Information and services provided by SEC phase.
+
+
+Returns:
+
+ None
+
+--*/
+;
+
+
+BOOLEAN
+DepexSatisfied (
+ IN PEI_CORE_INSTANCE *Private,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN UINTN PeimCount
+ )
+/*++
+
+Routine Description:
+
+ This routine parses the Dependency Expression, if available, and
+ decides if the module can be executed.
+
+Arguments:
+
+ Private - Pointer to the private data passed in from caller.
+ FileHandle - File handle of PEIM.
+ PeimCount - The PEIM sequence in one FV.
+
+Returns:
+ TRUE - Can be dispatched
+ FALSE - Cannot be dispatched
+
+--*/
+;
+
+#ifdef EFI64
+ //
+ // In Ipf we should make special changes for the PHIT pointers to support
+ // recovery boot in cache mode.
+ //
+#define SWITCH_TO_CACHE_MODE(CoreData) SwitchToCacheMode(CoreData)
+#define CACHE_MODE_ADDRESS_MASK 0x7FFFFFFFFFFFFFFFULL
+VOID
+SwitchToCacheMode (
+ IN PEI_CORE_INSTANCE *CoreData
+)
+/*++
+
+Routine Description:
+
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
+
+Arguments:
+
+ CoreData - The PEI core Private Data
+
+Returns:
+
+--*/
+;
+
+#else
+
+#define SWITCH_TO_CACHE_MODE(CoreData)
+
+#endif
+
+//
+// PPI support functions
+//
+VOID
+InitializePpiServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+;
+
+VOID
+ConvertPpiPointers (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Migrate the Hob list from the CAR stack to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR * PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR * OldPpi,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR * NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID * Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor OPTIONAL,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+;
+
+
+VOID *
+PeiReturnPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID *Guid
+ );
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_NOTIFY_DESCRIPTOR * NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+;
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+;
+
+VOID
+DispatchNotify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+;
+
+//
+// Boot mode support functions
+//
+EFI_STATUS
+EFIAPI
+PeiGetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to ascertain the present value of the boot mode.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - A pointer to contain the value of the boot mode.
+
+Returns:
+
+ EFI_SUCCESS - The boot mode was returned successfully.
+ EFI_INVALID_PARAMETER - BootMode is NULL.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiSetBootMode (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+ )
+/*++
+
+Routine Description:
+
+ This service enables PEIMs to update the boot mode variable.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ BootMode - The value of the boot mode to set.
+
+Returns:
+
+ EFI_SUCCESS - The value was successfully updated
+
+--*/
+;
+
+//
+// Security support functions
+//
+VOID
+InitializeSecurityServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_PEI_FV_HANDLE VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the OEM FV verification service.
+
+Arguments:
+
+ VolumeHandle - Pointer to the FV under investigation.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+
+EFI_STATUS
+VerifyPeim (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiGetHobList (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **HobList
+ )
+/*++
+
+Routine Description:
+
+ Gets the pointer to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ HobList - Pointer to the HOB List.
+
+Returns:
+
+ EFI_SUCCESS - Get the pointer of HOB List
+ EFI_NOT_AVAILABLE_YET - the HOB List is not yet published
+ EFI_INVALID_PARAMETER - HobList is NULL (in debug mode)
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiCreateHob (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 Type,
+ IN UINT16 Length,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Add a new HOB to the HOB List.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of the new HOB.
+ Length - Length of the new HOB to allocate.
+ Hob - Pointer to the new HOB.
+
+Returns:
+
+ Status - EFI_SUCCESS
+ - EFI_INVALID_PARAMETER if Hob is NULL
+ - EFI_NOT_AVAILABLE_YET if HobList is still not available.
+ - EFI_OUT_OF_RESOURCES if there is no more memory to grow the Hoblist.
+
+--*/
+;
+
+EFI_STATUS
+PeiCoreBuildHobHandoffInfoTable (
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a Handoff Information Table HOB
+
+Arguments:
+
+ BootMode - Current Bootmode
+ MemoryBegin - Start Memory Address.
+ MemoryLength - Length of Memory.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
+
+
+//
+// FFS Fw Volume support functions
+//
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextVolume (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_FV_HANDLE *VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Search the next FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ Instance - The Fv Volume Instance.
+ VolumeHandle - Pointer to the current Fv Volume to search.
+
+Returns:
+ EFI_INVALID_PARAMETER - VolumeHandle is NULL.
+ EFI_NOT_FOUND - No FV Volume is found.
+ EFI_SUCCESS - The next FV Volume is found.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindNextFile (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FV_FILETYPE SearchType,
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input FvHandle, search for the next matching type file in the FV Volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only file of this type.
+ FvHandle - Pointer to the current FV to search.
+ FileHandle - Pointer to the file matching SearchType in FwVolHeader.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindSectionData (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_SECTION_TYPE SectionType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching section in the
+ FFS volume.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only sections of this type.
+ FileHandle - Pointer to the current file to search.
+ SectionData - Pointer to the Section matching SectionType in FfsFileHeader.
+ - NULL if section not found
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+//
+// Memory support functions
+//
+VOID
+InitializeMemoryServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the memory services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ PeiStartupDescriptor - Information and services provided by SEC phase.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiInstallPeiMemory (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS MemoryBegin,
+ IN UINT64 MemoryLength
+ )
+/*++
+
+Routine Description:
+
+ Install the permanent memory is now available.
+ Creates HOB (PHIT and Stack).
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ MemoryBegin - Start of memory address.
+ MemoryLength - Length of memory.
+
+Returns:
+
+ Status - EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePages (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS * Memory
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on permanent memory,
+ not usable prior to the memory installation.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ Type - Type of allocation.
+ MemoryType - Type of memory to allocate.
+ Pages - Number of pages to allocate.
+ Memory - Pointer of memory allocated.
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_INVALID_PARAMETER Only AllocateAnyAddress is supported.
+ EFI_NOT_AVAILABLE_YET Called with permanent memory not available
+ EFI_OUT_OF_RESOURCES There is not enough HOB heap to satisfy the requirement
+ to allocate the number of pages.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiAllocatePool (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+/*++
+
+Routine Description:
+
+ Memory allocation service on the CAR.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Size - Amount of memory required
+
+ Buffer - Address of pointer to the buffer
+
+Returns:
+
+ Status - EFI_SUCCESS The allocation was successful
+ EFI_OUT_OF_RESOURCES There is not enough heap to satisfy the requirement
+ to allocate the requested size.
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EFIAPI
+PeiCoreSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Size bytes at Buffer address with Value
+
+Arguments:
+
+ Buffer - Target of set
+
+ Size - Amount of memory to set
+
+ Value - Value to place in memory
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+PeiLoadImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_PHYSICAL_ADDRESS *EntryPoint,
+ OUT UINT32 *AuthenticationState
+ )
+/*++
+
+Routine Description:
+
+ Routine for load image file.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ FileHandle - Pointer to the FFS file header of the image.
+ EntryPoint - Pointer to entry point of specified image file for output.
+ AuthenticationState - Pointer to attestation authentication state of image.
+
+Returns:
+
+ Status - EFI_SUCCESS - Image is successfully loaded.
+ EFI_NOT_FOUND - Fail to locate necessary PPI
+ Others - Fail to load file.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID * CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA * Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ CodeType - Type of Status Code.
+
+ Value - Value to output for Status Code.
+
+ Instance - Instance Number of this status code.
+
+ CallerId - ID of the caller of this status code.
+
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+;
+
+
+VOID
+PeiInitializeFv (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PeiCore Fv List.
+
+Arguments:
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ SecCoreData - Pointer to EFI_SEC_PEI_HAND_OFF.
+
+Returns:
+ NONE
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+FirmwareVolmeInfoPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Process Firmware Volum Information once FvInfoPPI install.
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM.
+
+Returns:
+
+ Status - EFI_SUCCESS if the interface could be successfully
+ installed
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsFindFileByName (
+ IN CONST EFI_GUID *FileName,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Given the input VolumeHandle, search for the next matching name file.
+
+Arguments:
+
+ FileName - File name to search.
+ VolumeHandle - The current FV to search.
+ FileHandle - Pointer to the file matching name in VolumeHandle.
+ - NULL if file not found
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetFileInfo (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given file.
+
+Arguments:
+ FileHandle - The handle to file.
+ FileInfo - Pointer to the file information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+PeiFfsGetVolumeInfo (
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ )
+/*++
+
+Routine Description:
+
+ Collect information of given Fv Volume.
+
+Arguments:
+ VolumeHandle - The handle to Fv Volume.
+ VolumeInfo - The pointer to volume information.
+
+Returns:
+ EFI_STATUS
+
+--*/
+;
+
+
+EFI_STATUS
+EFIAPI
+PeiRegisterForShadow (
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ This routine enable a PEIM to register itself to shadow when PEI Foundation
+ discovery permanent memory.
+
+Arguments:
+ FileHandle - File handle of a PEIM.
+
+Returns:
+ EFI_NOT_FOUND - The file handle doesn't point to PEIM itself.
+ EFI_ALREADY_STARTED - Indicate that the PEIM has been registered itself.
+ EFI_SUCCESS - Successfully to register itself.
+
+--*/
+;
+
+
+EFI_STATUS
+PeiFindFileEx (
+ IN CONST EFI_PEI_FV_HANDLE FvHandle,
+ IN CONST EFI_GUID *FileName, OPTIONAL
+ IN EFI_FV_FILETYPE SearchType,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle,
+ IN OUT EFI_PEI_FV_HANDLE *AprioriFile OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Given the input file pointer, search for the next matching file in the
+ FFS volume as defined by SearchType. The search starts from FileHeader inside
+ the Firmware Volume defined by FwVolHeader.
+
+Arguments:
+ PeiServices - Pointer to the PEI Core Services Table.
+ SearchType - Filter to find only files of this type.
+ Type EFI_FV_FILETYPE_ALL causes no filtering to be done.
+ FwVolHeader - Pointer to the FV header of the volume to search.
+ This parameter must point to a valid FFS volume.
+ FileHeader - Pointer to the current file from which to begin searching.
+ This pointer will be updated upon return to reflect the file found.
+ Flag - Indicator for if this is for PEI Dispath search
+
+Returns:
+ EFI_NOT_FOUND - No files matching the search criteria were found
+ EFI_SUCCESS
+
+--*/
+;
+
+VOID
+InitializeImageServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Regitser PeCoffLoader to PeiCore PrivateData. And install
+ Pei Load File PPI.
+
+Arguments:
+
+ PrivateData - Pointer to PEI_CORE_INSTANCE.
+ OldCoreData - Pointer to PEI_CORE_INSTANCE.
+
+Returns:
+
+ NONE.
+
+--*/
+;
+
+//*** AMI PORTING BEGIN ***//
+//This function is used to update LoadedImage PPI information
+//LoadedImage PPI is defined in PI 1.0 specification
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+);
+
+#include <AmiPeiLib.h>
+//*** AMI PORTING END *****//
+#endif
diff --git a/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c b/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
new file mode 100644
index 0000000..31c5db1
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/PeiMain.c
@@ -0,0 +1,404 @@
+/*++
+
+Copyright (c) 2006 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiMain.c
+
+Abstract:
+
+ Pei Core Main Entry Point
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include EFI_PPI_DEFINITION (MemoryDiscovered)
+#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+#include EFI_GUID_DEFINITION (StatusCode)
+
+//
+// CAR is filled with this initial value during SEC phase
+//
+#define INIT_CAR_VALUE 0x5AA55AA5
+
+#ifdef EFI_PEI_PERFORMANCE
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ );
+
+#endif
+
+//*** AMI PORTING BEGIN ***//
+VOID InitParts(VOID* p1, VOID*p2);
+VOID InitPartsMem(VOID* p1, VOID*p2);
+VOID ProcessLoadHob(EFI_PEI_SERVICES **PeiServices);
+VOID AmiInitParts(IN EFI_PEI_SERVICES **PeiServices, VOID* InitFunction);
+//*** AMI PORTING END *****//
+
+//
+// PPI that represents memory being discoverd in PEI.
+//
+static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiMemoryDiscoveredPpiGuid,
+ NULL
+};
+
+static EFI_PEI_SERVICES mPS = {
+ {
+ PEI_SERVICES_SIGNATURE,
+ PEI_SERVICES_REVISION,
+ sizeof (EFI_PEI_SERVICES),
+ 0,
+ 0
+ },
+ PeiInstallPpi,
+ PeiReInstallPpi,
+ PeiLocatePpi,
+ PeiNotifyPpi,
+
+ PeiGetBootMode,
+ PeiSetBootMode,
+
+ PeiGetHobList,
+ PeiCreateHob,
+
+ PeiFfsFindNextVolume,
+ PeiFfsFindNextFile,
+ PeiFfsFindSectionData,
+
+ PeiInstallPeiMemory,
+ PeiAllocatePages,
+ PeiAllocatePool,
+ PeiCoreCopyMem,
+ PeiCoreSetMem,
+
+ PeiReportStatusCode,
+ PeiResetSystem,
+
+ NULL,
+ NULL,
+
+ PeiFfsFindFileByName,
+ PeiFfsGetFileInfo,
+ PeiFfsGetVolumeInfo,
+ PeiRegisterForShadow
+};
+
+
+//
+// Main entry point to the PEI Core
+//
+EFI_PEI_CORE_ENTRY_POINT (PeiMain)
+
+EFI_STATUS
+EFIAPI
+PeiMain (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList
+ )
+/*++
+
+Routine Description:
+
+ Main entry point to Pei Core.
+
+Arguments:
+
+ SecCoreData - Information about the PEI core's operating environment.
+ PpList - Points to a list of one or more PPI descriptors to be
+ installed initially by the PEI core.
+
+Returns:
+
+ This function never returns
+
+--*/
+{
+ return PeiCore (SecCoreData,PpList, NULL);
+}
+
+EFI_STATUS
+EFIAPI
+PeiCore (
+ IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpList,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ The entry routine to Pei Core, invoked by PeiMain during transition
+ from SEC to PEI. After switching stack in the PEI core, it will restart
+ with the old core data.
+
+Arguments:
+
+ SecCoreData - Information and services provided by SEC phase.
+ PpList - Pointer to Ppi list provided by SEC phase.
+ OldCoreData - Pointer to old core data that is used to initialize the
+ core's data areas.
+
+Returns:
+
+ This function never returns
+ EFI_NOT_FOUND - Never reach
+
+--*/
+{
+ PEI_CORE_INSTANCE PrivateData;
+ EFI_PEI_SERVICES **PeiServices;
+ EFI_STATUS Status;
+ EFI_DXE_IPL_PPI *DxeIpl;
+ EFI_PEI_CPU_IO_PPI *CpuIo;
+ EFI_PEI_PCI_CFG2_PPI *PciCfg;
+
+#ifdef EFI_PEI_PERFORMANCE
+ UINT64 mTick;
+
+ mTick = 0;
+ if (OldCoreData == NULL) {
+ GetTimerValue (&mTick);
+ }
+#endif
+
+
+ //
+ // For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
+ // the 63-bit of address is set to 1.
+ //
+ SWITCH_TO_CACHE_MODE (OldCoreData);
+
+ if (OldCoreData != NULL) {
+
+ //
+ // 2nd time through we are using System Memory and we restore a previous
+ // state by copying the OldCoreData into PrivateData. A lot of the
+ // init code will note initialize PrivateData on the 2nd pass.
+ //
+ PeiCoreCopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
+
+ //
+ // 2nd time through Pei Core has been shadowed. To Pei Services,
+ // CpuIo and PciCfg services may have been updated by some Pei Modules. So before
+ // update PrivateData.ServiceTableShadow with memory version, save the CpuIo
+ // PciCfg and restore them then.
+ //
+ CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
+ PciCfg = (VOID*)PrivateData.ServiceTableShadow.PciCfg;
+ PeiCoreCopyMem (&(PrivateData.ServiceTableShadow), &mPS, sizeof (EFI_PEI_SERVICES));
+ PrivateData.ServiceTableShadow.CpuIo = CpuIo;
+ PrivateData.ServiceTableShadow.PciCfg = PciCfg;
+ } else {
+
+ //
+ // 1st time through we are using Temp memory
+ //
+ PeiCoreSetMem (&PrivateData, sizeof (PEI_CORE_INSTANCE),0);
+ PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
+
+ //
+ // Copy PeiServices from ROM to Temp memory in PrivateData
+ //
+ PeiCoreCopyMem (&(PrivateData.ServiceTableShadow), &mPS, sizeof (EFI_PEI_SERVICES));
+ }
+
+ PrivateData.PS = &PrivateData.ServiceTableShadow;
+ PeiServices = &PrivateData.PS;
+
+ InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData);
+
+ InitializePpiServices (&PrivateData, OldCoreData);
+
+ //
+ // Save PeiServicePointer so that it can be retrieved anywhere.
+ //
+ SetPeiServicesTablePointer(PeiServices);
+
+ if (OldCoreData != NULL) {
+
+ PEI_PERF_END (&PrivateData.PS,L"PreMem", NULL, 0);
+ PEI_PERF_START (&PrivateData.PS,L"PostMem", NULL, 0);
+
+ //
+ // The following code dumps out interesting cache as RAM usage information
+ // so we can keep tabs on how the cache as RAM is being utilized. The
+ // PEI_DEBUG_CODE macro is used to prevent this code from being compiled
+ // on a debug build.
+ //
+ PEI_DEBUG_CODE (
+ {
+ UINTN *StackPointer;
+ UINTN StackValue;
+
+ StackValue = INIT_CAR_VALUE;
+ for (StackPointer = (UINTN *) OldCoreData->TopOfCarHeap;
+ ((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
+ && StackValue == INIT_CAR_VALUE;
+ StackPointer++) {
+ StackValue = *StackPointer;
+ }
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
+ ((UINTN) OldCoreData->MaxTopOfCarHeap - (UINTN) StackPointer)
+ )
+ );
+ PEI_DEBUG (
+ (
+ &PrivateData.PS, EFI_D_INFO, " CAR heap used: %d bytes.\n",
+ ((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
+ (UINTN) OldCoreData->HobList.Raw)
+ )
+ );
+ }
+ )
+
+//*** AMI PORTING BEGIN ***//
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+//*** AMI PORTING END *****//
+
+ //
+ // Alert any listeners that there is permanent memory available
+ //
+ PEI_PERF_START (&PrivateData.PS,L"DisMem", NULL, 0);
+ Status = PeiInstallPpi (&PrivateData.PS, &mMemoryDiscoveredPpi);
+ PEI_PERF_END (&PrivateData.PS,L"DisMem", NULL, 0);
+
+ } else {
+
+ //
+ // Report Status Code EFI_SW_PC_INIT
+ //
+ PEI_REPORT_STATUS_CODE (
+ &(PrivateData.PS),
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT,
+ 0,
+ NULL,
+ NULL
+ );
+
+ //
+ // If first pass, start performance measurement.
+ //
+ PEI_PERF_START (&PrivateData.PS,L"PreMem", NULL, mTick);
+
+ //
+ // If SEC provided any PPI services to PEI, install them.
+ //
+ if (PpList != NULL) {
+ Status = PeiInstallPpi (&PrivateData.PS, PpList);
+ ASSERT_PEI_ERROR (&PrivateData.PS, Status);
+ }
+//*** AMI PORTING BEGIN ***//
+{
+ static EFI_GUID gEfiPeiLoadedImagePpiGuid = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+ static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc =
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiLoadedImagePpiGuid, NULL
+ };
+ PeiAllocatePool(&PrivateData.PS,sizeof(EFI_PEI_PPI_DESCRIPTOR),&PrivateData.LoadedImage);
+ *PrivateData.LoadedImage = LoadedImagePpiDesc;
+ PrivateData.LoadedImage->Ppi = &PrivateData.LoadedImagePpi;
+ PeiInstallPpi (&PrivateData.PS, PrivateData.LoadedImage);
+}
+//*** AMI PORTING END *****//
+ }
+
+ InitializeSecurityServices (&PrivateData, OldCoreData);
+
+ InitializeDispatcherData (&PrivateData, OldCoreData, SecCoreData);
+
+ //
+ // Install Pei Load File PPI.
+ //
+ InitializeImageServices (&PrivateData, OldCoreData);
+
+ //
+ // Call PEIM dispatcher
+ //
+//*** AMI PORTING BEGIN ***//
+ if (OldCoreData != NULL) {
+ AmiInitParts(PeiServices, InitPartsMem);
+ ProcessLoadHob(PeiServices);
+ } else {
+ AmiInitParts(PeiServices, InitParts);
+ }
+//*** AMI PORTING END *****//
+ PeiDispatcher (SecCoreData, &PrivateData);
+
+ //
+ // Check if InstallPeiMemory service was called.
+ //
+//*** AMI PORTING BEGIN ***//
+ //report MEMORY_NOT_INSTALLED error
+ if (!PrivateData.PeiMemoryInstalled)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_MEMORY_NOT_INSTALLED, EFI_ERROR_MAJOR);
+// PEI_ASSERT(&PrivateData.PS, PrivateData.PeiMemoryInstalled == TRUE);
+//*** AMI PORTING END *****//
+
+ PEI_PERF_END (&PrivateData.PS, L"PostMem", NULL, 0);
+
+ DxeIpl = PeiReturnPpi (&PrivateData.PS, &gEfiDxeIplPpiGuid);
+//*** AMI PORTING BEGIN ***//
+ //report DXEIPL_NOT_FOUND error
+ if (DxeIpl==NULL)
+ PEI_ERROR_CODE(&PrivateData.PS, PEI_DXEIPL_NOT_FOUND, EFI_ERROR_MAJOR);
+// PEI_ASSERT (&PrivateData.PS, DxeIpl != NULL);
+//*** AMI PORTING END *****//
+
+ PEI_DEBUG ((&PrivateData.PS, EFI_D_INFO, "DXE IPL Entry\n"));
+
+//*** AMI PORTING BEGIN ***//
+ //DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList);
+ DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList.Raw);
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+ // If DXE IPL returned control, let's call dispatcher again
+ // DXE IPL might have dicovered new FV or have changed a boot mode
+
+ // reset previous bitmap so that the dispatcher will attempt to execute any new PEIMs
+ // dispatch
+ PeiDispatcher (SecCoreData, &PrivateData);
+ // DXE IPL
+ DxeIpl->Entry (DxeIpl, &PrivateData.PS, PrivateData.HobList.Raw);
+//*** AMI PORTING END *****//
+ PEI_ASSERT (&PrivateData.PS,FALSE);
+ return EFI_NOT_FOUND;
+
+}
+
+//*** AMI PORTING BEGIN ***//
+VOID UpdatedLoadedImagePpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PHYSICAL_ADDRESS ImageAddress,
+ UINT64 ImageSize,
+ EFI_PEI_FILE_HANDLE FileHandle
+)
+{
+ PEI_CORE_INSTANCE *Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ Private->LoadedImagePpi.ImageAddress = ImageAddress;
+ Private->LoadedImagePpi.ImageSize = ImageSize;
+ Private->LoadedImagePpi.FileHandle = FileHandle;
+ PeiReInstallPpi(PeiServices,Private->LoadedImage,Private->LoadedImage);
+}
+//*** AMI PORTING END *****//
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Ppi.c b/Core/CORE_PEI/CORE_PEI_PI/Ppi.c
new file mode 100644
index 0000000..01236e7
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Ppi.c
@@ -0,0 +1,687 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Ppi.c
+
+Abstract:
+
+ EFI PEI Core PPI services
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+VOID
+InitializePpiServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize PPI services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the PEI Core data.
+ NULL if being run in non-permament memory mode.
+
+Returns:
+ Nothing
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PrivateData->PpiData.NotifyListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
+ PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
+ }
+
+ return;
+}
+
+VOID
+ConvertPpiPointers (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
+ )
+/*++
+
+Routine Description:
+
+ Convert PPI pointers after the Hob list was migrated from the temporary memory
+ to PEI installed memory.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldHandOffHob - The old handoff HOB list.
+ NewHandOffHob - The new handoff HOB list.
+
+Returns:
+ None
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ UINT8 Index;
+ PEI_PPI_LIST_POINTERS *PpiPointer;
+ UINTN Fixup;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
+
+ for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
+ if (Index < PrivateData->PpiData.PpiListEnd ||
+ Index > PrivateData->PpiData.NotifyListEnd) {
+ PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
+
+ if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the PEIM descriptor from the old HOB heap
+ // to the relocated HOB heap.
+ //
+ PpiPointer->Raw = (VOID *) ((UINTN)PpiPointer->Raw + Fixup);
+
+ //
+ // Only when the PEIM descriptor is in the old HOB should it be necessary
+ // to try to convert the pointers in the PEIM descriptor
+ //
+
+ if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
+ ((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
+ //
+ // Convert the pointer to the GUID in the PPI or NOTIFY descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Guid = (VOID *) ((UINTN)PpiPointer->Ppi->Guid + Fixup);
+ }
+
+ //
+ // Assume that no code is located in the temporary memory, so the pointer to
+ // the notification function in the NOTIFY descriptor needs not be converted.
+ //
+ if (Index < PrivateData->PpiData.PpiListEnd &&
+ (UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
+ (UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
+ //
+ // Convert the pointer to the PPI interface structure in the PPI descriptor
+ // from the old HOB heap to the relocated HOB heap.
+ //
+ PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
+ }
+ }
+ }
+ }
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList
+ )
+/*++
+
+Routine Description:
+
+ Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ PpiList - Pointer to a list of PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if all PPIs in PpiList are successfully installed.
+ EFI_INVALID_PARAMETER - if PpiList is NULL pointer
+ EFI_INVALID_PARAMETER - if any PPI in PpiList is not valid
+ EFI_OUT_OF_RESOURCES - if there is no more memory resource to install PPI
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN LastCallbackInstall;
+
+
+ if (PpiList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Index = PrivateData->PpiData.PpiListEnd;
+ LastCallbackInstall = Index;
+
+ //
+ // This is loop installs all PPI descriptors in the PpiList. It is terminated
+ // by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_PPI_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the NotifyList
+ //
+ if (Index == PrivateData->PpiData.NotifyListEnd + 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Check if it is a valid PPI.
+ // If not, rollback list to exclude all in this list.
+ // Try to indicate which item failed.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ PrivateData->PpiData.PpiListEnd = LastCallbackInstall;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallPpi: %g %x\n", PpiList->Guid, PpiList->Ppi));
+ return EFI_INVALID_PARAMETER;
+ }
+
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
+//*** AMI PORTING END ***//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*)PpiList;
+ PrivateData->PpiData.PpiListEnd++;
+
+ //
+ // Continue until the end of the PPI List.
+ //
+ if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ PpiList++;
+ Index++;
+ }
+
+ //
+ // Dispatch any callback level notifies for newly installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ LastCallbackInstall,
+ PrivateData->PpiData.PpiListEnd,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiReInstallPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *OldPpi,
+ IN CONST EFI_PEI_PPI_DESCRIPTOR *NewPpi
+ )
+/*++
+
+Routine Description:
+
+ Re-Install PPI services.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ OldPpi - Pointer to the old PEI PPI Descriptors.
+ NewPpi - Pointer to the new PEI PPI Descriptors.
+
+Returns:
+
+ EFI_SUCCESS - if the operation was successful
+ EFI_INVALID_PARAMETER - if OldPpi or NewPpi is NULL
+ EFI_INVALID_PARAMETER - if NewPpi is not valid
+ EFI_NOT_FOUND - if the PPI was not in the database
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+
+
+ if ((OldPpi == NULL) || (NewPpi == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NewPpi->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // Find the old PPI instance in the database. If we can not find it,
+ // return the EFI_NOT_FOUND error.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) {
+ break;
+ }
+ }
+ if (Index == PrivateData->PpiData.PpiListEnd) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Remove the old PPI from the database, add the new one.
+ //
+//*** AMI PORTING BEGIN ***//
+//Disable PPI messages
+// PEI_DEBUG((PeiServices, EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
+//*** AMI PORTING END ***//
+ PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*)NewPpi;
+
+ //
+ // Dispatch any callback level notifies for the newly installed PPI.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ Index,
+ Index+1,
+ PrivateData->PpiData.DispatchListEnd,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+PeiLocatePpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID *Guid,
+ IN UINTN Instance,
+ IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor OPTIONAL,
+ IN OUT VOID **Ppi
+ )
+/*++
+
+Routine Description:
+
+ Locate a given named PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ Guid - Pointer to GUID of the PPI.
+ Instance - Instance Number to discover.
+ PpiDescriptor - Pointer to reference the found descriptor. If not NULL,
+ returns a pointer to the descriptor (includes flags, etc)
+ Ppi - Pointer to reference the found PPI
+
+Returns:
+
+ Status - EFI_SUCCESS if the PPI is in the database
+ EFI_NOT_FOUND if the PPI is not in the database
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_PPI_DESCRIPTOR *TempPtr;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Search the data base for the matching instance of the GUIDed PPI.
+ //
+ for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) {
+ TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi;
+ CheckGuid = TempPtr->Guid;
+
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)Guid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)Guid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)Guid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)Guid)[3] == ((INT32 *)CheckGuid)[3])) {
+ if (Instance == 0) {
+
+ if (PpiDescriptor != NULL) {
+ *PpiDescriptor = TempPtr;
+ }
+
+ if (Ppi != NULL) {
+ *Ppi = TempPtr->Ppi;
+ }
+
+
+ return EFI_SUCCESS;
+ }
+ Instance--;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+
+VOID *
+PeiReturnPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_GUID *Guid
+ )
+{
+ EFI_STATUS Status;
+ VOID *Ppi;
+
+ Status = PeiLocatePpi (PeiServices, Guid, 0, NULL, &Ppi);
+
+ return (EFI_ERROR (Status)) ? NULL : Ppi;
+}
+
+
+
+EFI_STATUS
+EFIAPI
+PeiNotifyPpi (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList
+ )
+/*++
+
+Routine Description:
+
+ Install a notification for a given PPI.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyList - Pointer to list of Descriptors to notify upon.
+
+Returns:
+
+ Status - EFI_SUCCESS if successful
+ EFI_OUT_OF_RESOURCES if no space in the database
+ EFI_INVALID_PARAMETER if not a good decriptor
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index;
+ INTN NotifyIndex;
+ INTN LastCallbackNotify;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr;
+ UINTN NotifyDispatchCount;
+
+
+ NotifyDispatchCount = 0;
+
+ if (NotifyList == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ Index = PrivateData->PpiData.NotifyListEnd;
+ LastCallbackNotify = Index;
+
+ //
+ // This is loop installs all Notify descriptors in the NotifyList. It is
+ // terminated by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
+ // EFI_PEI_NOTIFY_DESCRIPTOR in the list.
+ //
+
+ for (;;) {
+ //
+ // Since PpiData is used for NotifyList and InstallList, max resource
+ // is reached if the Install reaches the PpiList
+ //
+ if (Index == PrivateData->PpiData.PpiListEnd - 1) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // If some of the PPI data is invalid restore original Notify PPI database value
+ //
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) {
+ PrivateData->PpiData.NotifyListEnd = LastCallbackNotify;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyDispatchCount ++;
+ }
+
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR*)NotifyList;
+
+ PrivateData->PpiData.NotifyListEnd--;
+ PEI_DEBUG((PeiServices, EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
+ if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
+ break;
+ }
+ //
+ // Go the next descriptor. Remember the NotifyList moves down.
+ //
+ NotifyList++;
+ Index--;
+ }
+
+ //
+ // If there is Dispatch Notify PPI installed put them on the bottom
+ //
+ if (NotifyDispatchCount > 0) {
+ for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
+ if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
+ NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
+
+ for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
+ }
+ PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
+ PrivateData->PpiData.DispatchListEnd--;
+ }
+ }
+
+ LastCallbackNotify -= NotifyDispatchCount;
+ }
+
+ //
+ // Dispatch any callback level notifies for all previously installed PPIs.
+ //
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
+ 0,
+ PrivateData->PpiData.PpiListEnd,
+ LastCallbackNotify,
+ PrivateData->PpiData.NotifyListEnd
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+
+VOID
+ProcessNotifyList (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Process the Notify List at dispatch level.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+
+Returns:
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN TempValue;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+
+ while (TRUE) {
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // Notifies getting installed. If so, go process any dispatch
+ // level Notifies that match the previouly installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
+ TempValue = PrivateData->PpiData.DispatchListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ 0,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.LastDispatchedNotify,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedNotify = TempValue;
+ }
+
+
+ //
+ // Check if the PEIM that was just dispatched resulted in any
+ // PPIs getting installed. If so, go process any dispatch
+ // level Notifies that match the installed PPIs.
+ // Use "while" instead of "if" since DispatchNotify can modify
+ // PpiListEnd (with InstallPpi) so we have to iterate until the same.
+ //
+ while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
+ TempValue = PrivateData->PpiData.PpiListEnd;
+ DispatchNotify (
+ PeiServices,
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH,
+ PrivateData->PpiData.LastDispatchedInstall,
+ PrivateData->PpiData.PpiListEnd,
+ MAX_PPI_DESCRIPTORS-1,
+ PrivateData->PpiData.DispatchListEnd
+ );
+ PrivateData->PpiData.LastDispatchedInstall = TempValue;
+ }
+
+ if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
+ break;
+ }
+ }
+ return;
+}
+
+VOID
+DispatchNotify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NotifyType,
+ IN INTN InstallStartIndex,
+ IN INTN InstallStopIndex,
+ IN INTN NotifyStartIndex,
+ IN INTN NotifyStopIndex
+ )
+/*++
+
+Routine Description:
+
+ Dispatch notifications.
+
+Arguments:
+
+ PeiServices - Pointer to the PEI Service Table
+ NotifyType - Type of notify to fire.
+ InstallStartIndex - Install Beginning index.
+ InstallStopIndex - Install Ending index.
+ NotifyStartIndex - Notify Beginning index.
+ NotifyStopIndex - Notify Ending index.
+
+Returns: None
+
+--*/
+
+{
+ PEI_CORE_INSTANCE *PrivateData;
+ INTN Index1;
+ INTN Index2;
+ EFI_GUID *SearchGuid;
+ EFI_GUID *CheckGuid;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor;
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+
+ //
+ // Remember that Installs moves up and Notifies moves down.
+ //
+ for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) {
+ NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify;
+
+ CheckGuid = NotifyDescriptor->Guid;
+
+ for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) {
+ SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid;
+ //
+ // Don't use CompareGuid function here for performance reasons.
+ // Instead we compare the GUID as INT32 at a time and branch
+ // on the first failed comparison.
+ //
+ if ((((INT32 *)SearchGuid)[0] == ((INT32 *)CheckGuid)[0]) &&
+ (((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
+ (((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
+ (((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {
+ PEI_DEBUG (
+ (
+ PeiServices,
+ EFI_D_INFO,
+ "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
+ SearchGuid,
+ NotifyDescriptor->Notify
+ )
+ );
+ NotifyDescriptor->Notify (
+ (EFI_PEI_SERVICES**)PeiServices,
+ NotifyDescriptor,
+ (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi
+ );
+ }
+ }
+ }
+
+ return;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Reset.c b/Core/CORE_PEI/CORE_PEI_PI/Reset.c
new file mode 100644
index 0000000..eb824f3
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Reset.c
@@ -0,0 +1,76 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Reset.c
+
+Abstract:
+
+ Pei Core Reset System Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (Reset)
+EFI_STATUS
+EFIAPI
+PeiResetSystem (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Reset System
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+Returns:
+
+ Status - EFI_NOT_AVAILABLE_YET. PPI not available yet.
+ - EFI_DEVICE_ERROR. Did not reset system.
+
+ Otherwise, resets the system.
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_RESET_PPI *ResetPpi;
+
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiResetPpiGuid,
+ 0,
+ NULL,
+ (VOID **)&ResetPpi
+ );
+
+ //
+ // LocatePpi returns EFI_NOT_FOUND on error
+ //
+ if (!EFI_ERROR (Status)) {
+ return ResetPpi->ResetSystem (PeiServices);
+ }
+//*** AMI PORTING BEGIN ***//
+ //Report error
+ PEI_ERROR_CODE(PeiServices,PEI_RESET_NOT_AVAILABLE,EFI_ERROR_MINOR);
+//*** AMI PORTING END *****//
+ return EFI_NOT_AVAILABLE_YET;
+}
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/Security.c b/Core/CORE_PEI/CORE_PEI_PI/Security.c
new file mode 100644
index 0000000..8d85b86
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/Security.c
@@ -0,0 +1,192 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Security.c
+
+Abstract:
+
+ EFI PEI Core Security services
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include EFI_PPI_DEFINITION (Security2)
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ );
+
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiSecurity2PpiGuid,
+ SecurityPpiNotifyCallback
+};
+
+VOID
+InitializeSecurityServices (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN PEI_CORE_INSTANCE *OldCoreData
+ )
+/*++
+
+Routine Description:
+
+ Initialize the security services.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ OldCoreData - Pointer to the old core data.
+ NULL if being run in non-permament memory mode.
+Returns:
+
+ None
+
+--*/
+{
+ if (OldCoreData == NULL) {
+ PeiNotifyPpi (&PrivateData->PS, &mNotifyList);
+ }
+ return;
+}
+
+
+EFI_STATUS
+EFIAPI
+SecurityPpiNotifyCallback (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+ )
+/*++
+
+Routine Description:
+
+ Provide a callback for when the security PPI is installed.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ NotifyDescriptor - The descriptor for the notification event.
+ Ppi - Pointer to the PPI in question.
+
+Returns:
+
+ EFI_SUCCESS - The function is successfully processed.
+
+--*/
+{
+ PEI_CORE_INSTANCE *PrivateData;
+
+ //
+ // Get PEI Core private data
+ //
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+
+ //
+ // If there isn't a security PPI installed, use the one from notification
+ //
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ PrivateData->PrivateSecurityPpi = (EFI_PEI_SECURITY2_PPI *)Ppi;
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+VerifyPeim (
+ IN PEI_CORE_INSTANCE *PrivateData,
+ IN EFI_PEI_FV_HANDLE VolumeHandle,
+ IN EFI_PEI_FILE_HANDLE FileHandle
+ )
+/*++
+
+Routine Description:
+
+ Provide a callout to the security verification service.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CurrentPeimAddress - Pointer to the Firmware File under investigation.
+
+Returns:
+
+ EFI_SUCCESS - Image is OK
+ EFI_SECURITY_VIOLATION - Image is illegal
+
+--*/
+{
+ EFI_STATUS Status;
+ UINT32 AuthenticationStatus;
+ BOOLEAN DeferExection;
+
+ //
+ // Set a default authentication state
+ //
+ AuthenticationStatus = 0;
+
+ if (PrivateData->PrivateSecurityPpi == NULL) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Check to see if the image is OK
+ //
+ Status = PrivateData->PrivateSecurityPpi->AuthenticationState (
+ &PrivateData->PS,
+ PrivateData->PrivateSecurityPpi,
+ AuthenticationStatus,
+ VolumeHandle,
+ FileHandle,
+ &DeferExection
+ );
+ if (DeferExection) {
+ Status = EFI_SECURITY_VIOLATION;
+ }
+ }
+ return Status;
+}
+
+
+EFI_STATUS
+VerifyFv (
+ IN EFI_PEI_FV_HANDLE VolumeHandle
+ )
+/*++
+
+Routine Description:
+
+ Verify a Firmware volume
+
+Arguments:
+
+ CurrentFvAddress - Pointer to the current Firmware Volume under consideration
+
+Returns:
+
+ EFI_SUCCESS - Firmware Volume is legal
+ EFI_SECURITY_VIOLATION - Firmware Volume fails integrity test
+
+--*/
+{
+ //
+ // Right now just pass the test. Future can authenticate and/or check the
+ // FV-header or other metric for goodness of binary.
+ //
+ return EFI_SUCCESS;
+}
diff --git a/Core/CORE_PEI/CORE_PEI_PI/StatusCode.c b/Core/CORE_PEI/CORE_PEI_PI/StatusCode.c
new file mode 100644
index 0000000..8df4058
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/StatusCode.c
@@ -0,0 +1,94 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ StatusCode.c
+
+Abstract:
+
+ Pei Core Status Code Support
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+
+#include EFI_PPI_DEFINITION (StatusCode)
+
+EFI_STATUS
+EFIAPI
+PeiReportStatusCode (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Core version of the Status Code reporter
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ CodeType - Type of Status Code.
+ Value - Value to output for Status Code.
+ Instance - Instance Number of this status code.
+ CallerId - ID of the caller of this status code.
+ Data - Optional data associated with this status code.
+
+Returns:
+
+ Status - EFI_SUCCESS if status code is successfully reported
+ - EFI_NOT_AVAILABLE_YET if StatusCodePpi has not been installed
+
+--*/
+{
+ EFI_STATUS Status;
+ PEI_STATUS_CODE_PPI *StatusCodePpi;
+
+
+ //
+ //Locate StatusCode Ppi.
+ //
+ Status = PeiLocatePpi (
+ PeiServices,
+ &gPeiStatusCodePpiGuid,
+ 0,
+ NULL,
+ (VOID **)&StatusCodePpi
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = StatusCodePpi->ReportStatusCode (
+ PeiServices,
+ Type,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+ return Status;
+ }
+
+
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
diff --git a/Core/CORE_PEI/CORE_PEI_PI/dependency.c b/Core/CORE_PEI/CORE_PEI_PI/dependency.c
new file mode 100644
index 0000000..f890a42
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/dependency.c
@@ -0,0 +1,265 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ dependency.c
+
+Abstract:
+
+ PEI Dispatcher Dependency Evaluator
+
+ This routine evaluates a dependency expression (DEPENDENCY_EXPRESSION) to determine
+ if a driver can be scheduled for execution. The criteria for
+ schedulability is that the dependency expression is satisfied.
+
+--*/
+
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "PeiLib.h"
+#include "EfiDependency.h"
+#include "Dependency.h"
+
+STATIC
+BOOLEAN
+IsPpiInstalled (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EVAL_STACK_ENTRY *Stack
+ )
+/*++
+
+Routine Description:
+
+ This routine determines if a PPI has been installed.
+ The truth value of a GUID is determined by if the PPI has
+ been published and can be queried from the PPI database.
+
+Arguments:
+ PeiServices - The PEI core services table.
+ Stack - Reference to EVAL_STACK_ENTRY that contains PPI GUID to check
+
+Returns:
+
+ True if the PPI is already installed.
+ False if the PPI has yet to be installed.
+
+--*/
+{
+ VOID *PeiInstance;
+ EFI_STATUS Status;
+ EFI_GUID PpiGuid;
+
+ //
+ // If there is no GUID to evaluate, just return current result on stack.
+ //
+ if (Stack->Operator == NULL) {
+ return Stack->Result;
+ }
+
+ //
+ // Copy the Guid into a locale variable so that there are no
+ // possibilities of alignment faults for cross-compilation
+ // environments such as Intel?Itanium(TM).
+ //
+ PeiCoreCopyMem(&PpiGuid, Stack->Operator, sizeof(EFI_GUID));
+
+ //
+ // Check if the PPI is installed.
+ //
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &PpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiInstance // PPI
+ );
+
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+BOOLEAN
+PeimDispatchReadiness (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *DependencyExpression
+ )
+/*++
+
+Routine Description:
+
+ This is the POSTFIX version of the dependency evaluator. When a
+ PUSH [PPI GUID] is encountered, a pointer to the GUID is stored on
+ the evaluation stack. When that entry is poped from the evaluation
+ stack, the PPI is checked if it is installed. This method allows
+ some time savings as not all PPIs must be checked for certain
+ operation types (AND, OR).
+
+Arguments:
+
+ PeiServices - Calling context.
+
+ DependencyExpression - Pointer to a dependency expression. The Grammar adheres to
+ the BNF described above and is stored in postfix notation.
+ Runnable - is True if the driver can be scheduled and False if the driver
+ cannot be scheduled. This is the value that the schedulers
+ should use for deciding the state of the driver.
+
+Returns:
+
+ Status = EFI_SUCCESS if it is a well-formed Grammar
+ EFI_INVALID_PARAMETER if the dependency expression overflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression underflows
+ the evaluation stack
+ EFI_INVALID_PARAMETER if the dependency expression is not a
+ well-formed Grammar.
+--*/
+{
+ EFI_STATUS Status;
+ DEPENDENCY_EXPRESSION_OPERAND *Iterator;
+ EVAL_STACK_ENTRY *StackPtr;
+ EVAL_STACK_ENTRY EvalStack[MAX_GRAMMAR_SIZE];
+
+ Status = EFI_SUCCESS;
+ Iterator = DependencyExpression;
+
+ StackPtr = &EvalStack[0];
+
+ while (TRUE) {
+
+ switch (*(Iterator++)) {
+
+ //
+ // For performance reason we put the frequently used items in front of
+ // the rarely used items
+ //
+
+ case (EFI_DEP_PUSH):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return FALSE;
+ }
+
+ //
+ // Push the pointer to the PUSH opcode operator (pointer to PPI GUID)
+ // We will evaluate if the PPI is insalled on the POP operation.
+ //
+ StackPtr->Operator = (VOID *) Iterator;
+ Iterator = Iterator + sizeof (EFI_GUID);
+ StackPtr++;
+ break;
+
+ case (EFI_DEP_AND):
+ case (EFI_DEP_OR):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the two POPs for the AND operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did two POPs.
+ //
+ if (StackPtr < &EvalStack[2]) {
+ return FALSE;
+ }
+
+ //
+ // Evaluate the first POPed operator only. If the operand is
+ // EFI_DEP_AND and the POPed operator evaluates to FALSE, or the
+ // operand is EFI_DEP_OR and the POPed operator evaluates to TRUE,
+ // we don't need to check the second operator, and the result will be
+ // evaluation of the POPed operator. Otherwise, don't POP the second
+ // operator since it will now evaluate to the final result on the
+ // next operand that causes a POP.
+ //
+ StackPtr--;
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_AND) {
+ if (!(IsPpiInstalled (PeiServices, StackPtr))) {
+ (StackPtr-1)->Result = FALSE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ } else {
+ if (IsPpiInstalled (PeiServices, StackPtr)) {
+ (StackPtr-1)->Result = TRUE;
+ (StackPtr-1)->Operator = NULL;
+ }
+ }
+ break;
+
+ case (EFI_DEP_END):
+ StackPtr--;
+ //
+ // Check to make sure EvalStack is balanced. If not, then there is
+ // an error in the dependency grammar, so return EFI_INVALID_PARAMETER.
+ //
+ if (StackPtr != &EvalStack[0]) {
+ return FALSE;
+ }
+ return IsPpiInstalled (PeiServices, StackPtr);
+ break;
+
+ case (EFI_DEP_NOT):
+ //
+ // Check to make sure the dependency grammar doesn't underflow the
+ // EvalStack on the POP for the NOT operation. Don't need to
+ // check for the overflow on PUSHing the result since we already
+ // did a POP.
+ //
+ if (StackPtr < &EvalStack[1]) {
+ return FALSE;
+ }
+ (StackPtr-1)->Result = (BOOLEAN) !IsPpiInstalled (PeiServices, (StackPtr-1));
+ (StackPtr-1)->Operator = NULL;
+ break;
+
+ case (EFI_DEP_TRUE):
+ case (EFI_DEP_FALSE):
+ //
+ // Check to make sure the dependency grammar doesn't overflow the
+ // EvalStack on the push
+ //
+ if (StackPtr > &EvalStack[MAX_GRAMMAR_SIZE-1]) {
+ return FALSE;
+ }
+ //
+ // Iterator has increased by 1 after we retrieve the operand, so here we
+ // should get the value pointed by (Iterator - 1), in order to obtain the
+ // same operand.
+ //
+ if (*(Iterator - 1) == EFI_DEP_TRUE) {
+ StackPtr->Result = TRUE;
+ } else {
+ StackPtr->Result = FALSE;
+ }
+ StackPtr->Operator = NULL;
+ StackPtr++;
+ break;
+
+ default:
+ //
+ // The grammar should never arrive here
+ //
+ return FALSE;
+ break;
+ }
+ }
+}
diff --git a/Core/CORE_PEI/CORE_PEI_PI/dependency.h b/Core/CORE_PEI/CORE_PEI_PI/dependency.h
new file mode 100644
index 0000000..413c068
--- /dev/null
+++ b/Core/CORE_PEI/CORE_PEI_PI/dependency.h
@@ -0,0 +1,38 @@
+/*++
+
+Copyright (c) 2004 - 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ dependency.h
+
+Abstract:
+
+ This module contains data specific to dependency expressions
+ and local function prototypes.
+
+--*/
+
+#ifndef _PEI_DEPENDENCY_H_
+#define _PEI_DEPENDENCY_H_
+
+#define MAX_GRAMMAR_SIZE 256
+
+//
+// type definitions
+//
+typedef UINT8 DEPENDENCY_EXPRESSION_OPERAND;
+
+typedef struct {
+ BOOLEAN Result;
+ VOID *Operator;
+} EVAL_STACK_ENTRY;
+
+#endif
diff --git a/Core/CORE_PEI/CpuIo.c b/Core/CORE_PEI/CpuIo.c
new file mode 100644
index 0000000..634f676
--- /dev/null
+++ b/Core/CORE_PEI/CpuIo.c
@@ -0,0 +1,1158 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PeiMain/CpuIo.c 13 3/22/11 5:14p Felixp $
+//
+// $Revision: 13 $
+//
+// $Date: 3/22/11 5:14p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PeiMain/CpuIo.c $
+//
+// 13 3/22/11 5:14p Felixp
+// Method of invocation of the in-memory entry point has changed
+// from LOAD_HOB to eLink registered under PeiCoreMemoryInstalled.
+// This is more efficient.
+//
+// 12 2/05/11 3:43p Artems
+// Changed functions calling interface (added CONST qualifiers) as
+// required by PI 1.0 specification
+//
+// 11 11/05/09 4:59p Oleksiyy
+// EIP 27821 Support for 64 bit operations in IoRead and IoWrite added. To
+// use this functions IA32CLib.c, x64AsmLib.asm files should be updated
+// also.
+//
+// 10 7/08/09 5:53p Vyacheslava
+// Updated according to the coding standards.
+//
+// 9 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 8 6/10/05 5:49p Felixp
+// Bug fixes in MemRead, MemWrite, IoRead, IoWrite
+//
+// 7 6/06/05 7:48p Felixp
+//
+// 6 6/06/05 1:25p Felixp
+//
+// 5 6/03/05 3:45p Felixp
+// Updated to support changes introduced in PEI CIS 0.91
+//
+// 4 3/04/05 9:38a Mandal
+//
+// 3 2/01/05 2:35a Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 7 1/27/04 3:58a Felixp
+// Bug fixes and improvements as a part of PEI CORE integration
+//
+// 6 12/29/03 5:25p Felixp
+// preffix 'EFI_' added to the names of the PEIM descriptor structures and
+// flags
+//
+// 5 12/15/03 4:35p Robert
+//
+// 4 12/15/03 4:25p Robert
+//
+// 3 12/15/03 12:40p Robert
+// changed position of GUID definition below PPI include
+//
+// 2 12/15/03 11:49a Robert
+// updated PPI definitions and removed entry point definitions
+//
+// 1 12/11/03 5:34p Robert
+// Initial Check In
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CpuIo.c
+//
+// Description: This file contains the implementation of the CPU I/O
+// specification. For questions about the specification refer to the
+// PEI CIS specification chapter 9
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+// Module specific Includes
+#include <AmiPeiLib.h>
+#include <AmiHobs.h>
+// Produced PPIs
+#include <PPI/CpuIo.h>
+
+// Function Prototypes
+static EFI_STATUS LocalMemRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static EFI_STATUS LocalMemWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static EFI_STATUS LocalIoRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static EFI_STATUS LocalIoWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+static UINT8 LocalIoRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT16 LocalIoRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT32 LocalIoRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT64 LocalIoRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static VOID LocalIoWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+);
+
+static VOID LocalIoWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+);
+
+static VOID LocalIoWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+);
+
+static VOID LocalIoWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+);
+
+static UINT8 MemRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT16 MemRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT32 MemRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static UINT64 MemRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+);
+
+static VOID MemWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Data
+);
+
+static VOID MemWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Data
+);
+
+static VOID MemWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Data
+);
+
+static VOID MemWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Data
+);
+
+// PPI interface definition
+static EFI_PEI_CPU_IO_PPI mCpuIoPpi = {
+ {LocalMemRead, LocalMemWrite},
+ {LocalIoRead, LocalIoWrite},
+ LocalIoRead8, LocalIoRead16, LocalIoRead32, LocalIoRead64,
+ LocalIoWrite8, LocalIoWrite16, LocalIoWrite32, LocalIoWrite64,
+ MemRead8, MemRead16, MemRead32, MemRead64,
+ MemWrite8, MemWrite16, MemWrite32, MemWrite64
+};
+
+// PPI that are installed
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiCpuIoPpiInServiceTableGuid,
+ NULL
+ }
+};
+
+// Function Definitions
+EFI_STATUS EFIAPI CpuIoMemInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ // Update the CpuIo pointer
+ (*PeiServices)->CpuIo = &mCpuIoPpi;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: CpuIoInit
+//
+// Description: This function installs the CPU I/O PPI and exits
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system
+// **PeiServices - pointer to the Pei Services function and data structure
+//
+// Output: always returns EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI CpuIoInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ // Install the CpuIo Ppi
+ (*PeiServices)->CpuIo = &mCpuIoPpi;
+ Status = (*PeiServices)->InstallPpi( PeiServices, mPpiList );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: CalcAddrChanges
+//
+// Description: This function determines which addresses need to be changed
+// as data is read or written.
+//
+// Input:
+// Width - Contains the width and type of memory or I/O read that is needed
+//
+// Output:
+// *In - The number of bytes to increment the input buffer address after
+// every read or write access
+// *Out - The number of bytes to increment the output buffer address after
+// every read or write access
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+VOID CalcAddrChanges(
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ OUT UINTN *In,
+ OUT UINTN *Out
+)
+{
+ // get the number of bytes per read or write access and the turn that into
+ // an Hex Address Incrementing value
+ *In = *Out = 1 << (Width % 4);
+
+ if ( (Width >= EfiPeiCpuIoWidthFifoUint8) &&
+ (Width <= EfiPeiCpuIoWidthFifoUint64) )
+ *Out = 0;
+
+ else if ( (Width >= EfiPeiCpuIoWidthFillUint8) &&
+ (Width <= EfiPeiCpuIoWidthFillUint64) )
+ *In = 0;
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead8
+//
+// Description: This function is called to read a byte from the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT8 - This is the value read from the I/O space specified by the
+// value passed in by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT8 LocalIoRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead8 ((UINT16) Address);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead16
+//
+// Description: This function is called to read a word from the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT16 - This is the value read from the I/O space specified by the
+// by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT16 LocalIoRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead16 ((UINT16) Address);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead32
+//
+// Description: This function is called to read a dword from the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT32 - This is the value read from the I/O space specified by the
+// value passed in by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT32 LocalIoRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead32 ((UINT16) Address);
+}
+
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead64
+//
+// Description: This function is called to read a qword from the I/O space
+// This function is not available in a 32bit system so we just return 0 if
+// it is called. We cannot remove this function because it is part of the
+// specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT64 - This is the value read from the I/O space specified by the
+// value passed in by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+static UINT64 LocalIoRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return IoRead64 ((UINT16) Address);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoWrite8
+//
+// Description: This function is called to write a byte to the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer8 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Buffer8
+)
+{
+ IoWrite8 ((UINT16) Address, Buffer8);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocaIoWrite16
+//
+// Description: This function is called to write a word to the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer16 - The value to be written to location specified by Address
+//
+// Output: VOID
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Buffer16
+)
+{
+ IoWrite16 ((UINT16) Address, Buffer16);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocaIoWrite32
+//
+// Description: This function is called to write a dword to the I/O space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer32 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Buffer32
+)
+{
+ IoWrite32 ((UINT16) Address, Buffer32);
+}
+
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocaIoWrite64
+//
+// Description: This function is called to write a qword to the I/O space
+// This function is not available in a 32bit system so we just do nothing
+// if it is called. We cannot remove this function because it is part of
+// the specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer64 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID LocalIoWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Buffer64
+)
+{
+ IoWrite64 ((UINT16) Address, Buffer64);
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead8
+//
+// Description: This function is called to read a byte from the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT8 - This is the value read from the Memory space specified by
+// the input variable Address
+//
+// Referrals:
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT8 MemRead8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT8*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead16
+//
+// Description: This function is called to read a word from the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT16 - This is the value read from the Memory space specified
+// by the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT16 MemRead16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT16*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead32
+//
+// Description: This function is called to read a dword from the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT32 - This is the value read from the Memory space specified by
+// the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT32 MemRead32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT32*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemRead64
+//
+// Description: This function is called to read a qword from the Memory space
+// This function is not available in a 32bit system so we just return 0 if
+// it is called. We cannot remove this function because it is part of the
+// specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be read from
+//
+// Output: UINT64 - This is the value read from the Memory space specified by
+// the input variable Address
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static UINT64 MemRead64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address
+)
+{
+ return *(volatile UINT64*) Address;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite8
+//
+// Description: This function is called to write a byte to the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer8 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite8 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT8 Buffer8
+)
+{
+ *(volatile UINT8*) Address = Buffer8;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite16
+//
+// Description: This function is called to write a word to the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer16 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite16 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT16 Buffer16
+)
+{
+ *(volatile UINT16*) Address = Buffer16;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite32
+//
+// Description: This function is called to write a dword to the Memory space
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer32 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite32 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT32 Buffer32
+)
+{
+ *(volatile UINT32*) Address = Buffer32;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: MemWrite64
+//
+// Description: This function is called to write a qword to the Memory space
+// This function is not available in a 32bit system so we just do nothing
+// if it is called. We cannot remove this function because it is part of
+// the specification
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Address - A 64 bit address that points to the location to be written to
+// Buffer64 - The value to be written to location specified by Address
+//
+// Output: None
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static VOID MemWrite64 (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN UINT64 Address,
+ IN UINT64 Buffer
+)
+{
+ *(volatile UINT64*) Address = Buffer;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalMemWrite
+//
+// Description: This function is called to do multiple writes to the memory
+// space. It also is capable of doing a memory space fill of a single value
+// or a serial write from a buffer depending on the Width type being passed
+// in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the I/O space that is to be written
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to write
+// *Buffer - Data to be written to the I/O space
+//
+// Output: always returns EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalMemWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ MemWrite8(
+ PeiServices,
+ This,
+ Address,
+ *(UINT8*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ MemWrite16(
+ PeiServices,
+ This,
+ Address,
+ *(UINT16*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ MemWrite32(
+ PeiServices,
+ This,
+ Address,
+ *(UINT32*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ MemWrite64(
+ PeiServices,
+ This,
+ Address,
+ *(UINT64*)Buffer
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalMemRead
+//
+// Description: This function is called to do multiple reads from the Memory
+// space. It also is capable of doing an read of an I/O space area to a
+// single byte or a serial read into a buffer depending on the Width type
+// being passed in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the Memory space that is to be read each time
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to read
+//
+// Output: always returns EFI_SUCCESS
+// *Buffer - Data to be read from the Memory space
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalMemRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST struct _EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ *(UINT8*)Buffer = MemRead8(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ *(UINT16*)Buffer = MemRead16(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ *(UINT32*)Buffer = MemRead32(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ *(UINT64*)Buffer = MemRead64(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoRead
+//
+// Description: This function is called to do multiple reads from the I/O space
+// It also is capable of doing an read of an I/O space area to a single byte
+// or a serial read into a buffer depending on the Width type being passed in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the I/O space that is to be read
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to read
+//
+// Output: always returns EFI_SUCCESS
+// *Buffer - Data to be read from the I/O space
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalIoRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer )
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ *(UINT8*)Buffer = LocalIoRead8(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ *(UINT16*)Buffer = LocalIoRead16(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ *(UINT32*)Buffer = LocalIoRead32(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ *(UINT64*)Buffer = LocalIoRead64(
+ PeiServices,
+ This,
+ Address
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: LocalIoWrite
+//
+// Description: This function is called to do multiple writes to the I/O space
+// It also is capable of doing an I/O space fill of a single value or a
+// serial write from a buffer depending on the Width type being passed in.
+//
+// Input:
+// **PeiServices - pointer to the Pei Services function and data structure
+// *This - Pointer to the instance of the CPU I/O PPI structure
+// Width - Size of the I/O space that is to be written
+// Address - A 64 bit address that points to the location to be read from
+// Count - Number of times to write
+// *Buffer - Data to be written to the I/O space
+//
+// Output: always returns EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+static EFI_STATUS LocalIoWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_CPU_IO_PPI *This,
+ IN EFI_PEI_CPU_IO_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer )
+{
+ UINTN Idx;
+ UINTN OutputInc, InputInc; // Input and Output counters
+
+ CalcAddrChanges(
+ Width,
+ &InputInc,
+ &OutputInc
+ );
+
+ for ( Idx = 0; Idx < Count; Idx++, Address += OutputInc, Buffer = (UINT8*)Buffer + InputInc ) {
+ switch (Width) {
+ case EfiPeiCpuIoWidthUint8:
+ case EfiPeiCpuIoWidthFifoUint8:
+ case EfiPeiCpuIoWidthFillUint8:
+ LocalIoWrite8(
+ PeiServices,
+ This,
+ Address,
+ *(UINT8*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint16:
+ case EfiPeiCpuIoWidthFifoUint16:
+ case EfiPeiCpuIoWidthFillUint16:
+ LocalIoWrite16(
+ PeiServices,
+ This,
+ Address,
+ *(UINT16*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint32:
+ case EfiPeiCpuIoWidthFifoUint32:
+ case EfiPeiCpuIoWidthFillUint32:
+ LocalIoWrite32(
+ PeiServices,
+ This,
+ Address,
+ *(UINT32*)Buffer
+ );
+ break;
+
+ case EfiPeiCpuIoWidthUint64:
+ case EfiPeiCpuIoWidthFifoUint64:
+ case EfiPeiCpuIoWidthFillUint64:
+ LocalIoWrite64(
+ PeiServices,
+ This,
+ Address,
+ *(UINT64*)Buffer
+ );
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CORE_PEI/DxeIpl.c b/Core/CORE_PEI/DxeIpl.c
new file mode 100644
index 0000000..8a1a129
--- /dev/null
+++ b/Core/CORE_PEI/DxeIpl.c
@@ -0,0 +1,838 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_PEI/DxeIpl.c 4 10/25/12 8:50a Wesleychen $
+//
+// $Revision: 4 $
+//
+// $Date: 10/25/12 8:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/CORE_PEI/DxeIpl.c $
+//
+// 4 10/25/12 8:50a Wesleychen
+// - Update Core to 4.6.5.4.
+// - Fixed system hang at CKP 0x4F during S3 resume if HT is disabled.
+//
+// 45 5/21/12 10:42a Artems
+// [TAG] EIP87678
+// [Category] Improvement
+// [Description] Select ROM image to use on BOOT_ON_FLASH_UPDATE path
+// We have two images - one already in flash (old) and one in reflash
+// capsule
+// We can use either one to boot
+// [Files] DxeIpl.c
+//
+// 44 4/20/12 2:23p Artems
+// [TAG] EIP87678
+// [Category] New Feature
+// [Description] Select image to boot from on flash update boot path -
+// either old one (currently in flash) or new one (in recovery capsule)
+// [Files] Recovery.c DxeIpl.c Core.sdl Tokens.c
+//
+// 43 11/01/11 1:57p Felixp
+// [TAG] EIP 69841 and 71719
+// [Category] Improvement
+// [Description] The AMI customizations are removed from the DXE memory
+// manager.
+// They are replaced with the Memory Type Information HOB used in Tiano
+// projects.
+// This is done to reduces number of descriptors in the memory map
+// and to workaround Windows bug (Windows can't handle memory allocations
+// that happen after the start of the OS loader).
+// [Files] CORE_DXE.sdl, Page.c, BDS.c, DxeIpl.c
+//
+// 42 7/19/11 11:29a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 41 6/02/11 4:49p Artems
+//
+// 40 5/13/11 5:12p Artems
+// Preserved boot mode when recovery/flash update failed for error
+// reporting
+//
+// 39 5/05/11 3:44p Artems
+// Bugfix: different FV count for PI 0.9 and PI 1.0 specification
+//
+// 38 2/15/11 12:35p Artems
+// Added workaround so in recovery DXE_CORE ffs will be picked from right
+// FV
+//
+// 37 2/05/11 3:48p Artems
+// Added new ROM layout infrastructure support
+// Replaced call to FFS PPI with library function to work both in PI 0.91
+// and 1.0 modes
+//
+// 36 10/01/10 4:33p Felixp
+// Debug message with DXE Core addres is moved to after the instalaltion
+// of the END of PEI PPI
+//
+// 35 11/13/09 4:32p Felixp
+// Buffer overflow protection is added (calls to Sprintf replaced with
+// Sprintf_s).
+//
+// 34 7/10/09 4:32p Artems
+// Added function headers
+//
+// 33 5/21/09 5:19p Felixp
+// RomLayout support. Call to ReportFvDxeIpl is added.
+//
+// 32 5/07/08 12:23p Felixp
+// Converted to use new Performance API
+//
+// 31 4/18/08 6:27p Felixp
+// DXE_CORE_STARTED reported at the very end of PEI phase
+//
+// 30 4/20/07 5:10p Felixp
+// Status codes added
+//
+// 29 4/19/07 1:03p Felixp
+//
+// 27 4/17/07 9:07a Felixp
+// S3 & Recovery Status Codes removed. They are reported by the S3 &
+// Recovery PEIM
+//
+// 26 3/13/07 1:46a Felixp
+// Error reporting updated to use new PEI_ERROR_CODE macro
+//
+// 25 3/12/07 10:26a Felixp
+// LoadedImage PPI support added (defined in PI 1.0; used by AmiDebugger)
+//
+// 23 11/02/06 10:25p Felixp
+// Install EFI_PEI_END_OF_PEI_PHASE_PPI_GUID right before launching DXE
+// Core
+//
+// 22 8/25/06 10:58a Felixp
+//
+// 21 8/24/06 9:43a Felixp
+// Preliminary x64 support (work in progress)
+// DXE Core interfaces are no longer passed from PEI Core.
+// They are linked directly with DXE Core
+//
+// 20 6/04/06 10:50p Ambikas
+//
+// 19 5/22/06 12:14a Felixp
+// More status/error codes added
+//
+// 18 3/13/06 9:51a Felixp
+//
+// 17 12/01/05 9:52a Felixp
+// Recovery Logic changed: RecoveryModule PPI is used. Capsule processing
+// is moved to Recovery.c
+//
+// 16 10/09/05 11:25a Felixp
+// Performance measurements added.
+//
+// 15 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 14 6/06/05 1:25p Felixp
+// Type parameter removed from AllocatePages to match PEI CIS 0.91
+//
+// 13 3/25/05 5:47p Felixp
+// 1. S3 boot path: call of S3RestoreConfig added
+// 3. Recovery boot path: trace messages added
+//
+// 12 3/24/05 6:48p Felixp
+//
+// 11 3/22/05 10:03p Felixp
+// Recovery Support
+//
+// 10 3/17/05 1:54p Felixp
+// implementation of S3Resume boot path started
+//
+// 9 3/17/05 1:45p Felixp
+// Bug fix in memory installed callback (status was not checked)
+//
+// 8 3/04/05 9:39a Mandal
+//
+// 7 1/25/05 3:37p Felixp
+//
+// 6 1/25/05 3:26p Felixp
+// Once memory is available DxeIpl realocates itself to memory and
+// installs
+// LoadFile PPI
+//
+// 5 1/22/05 12:29p Felixp
+// Bug fix:
+// Last parameter to AllocatePages was VOID* instead of
+// EFI_PHYSICAL_ADDRESS, which
+// resulted in a stack corruption.
+//
+// 4 1/22/05 11:29a Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 19 12/20/04 5:10p Felixp
+//
+// 18 12/20/04 4:54p Felixp
+//
+// 17 12/17/04 6:59p Felixp
+// PEI_DEBUG_MSG renamed to PEI_TRACE
+//
+// 16 11/24/04 9:38a Felixp
+// format of debug message changed
+//
+// 15 11/19/04 1:23a Felixp
+//
+// 14 11/10/04 5:18p Felixp
+// Debug message added
+//
+// 13 10/21/04 2:47p Felixp
+// Support for DXE Core compression added
+//
+// 12 7/13/04 10:42a Felixp
+//
+// 11 4/11/04 2:49p Felixp
+//
+// 10 4/07/04 12:46a Felixp
+// REAL PLATFORM DEBUGGING (lots of bug fixes)
+//
+// 9 3/29/04 6:06p Felixp
+//
+// 8 3/29/04 5:40p Felixp
+//
+// 7 3/28/04 2:11p Felixp
+// 1. PE Loader and some other commonly used code moved to the Library
+// 2. Warnings fixed (from now on warning will be treated as error)
+//
+// 6 3/20/04 12:03p Felixp
+//
+// 5 2/19/04 10:08a Felixp
+// Debugging code removed.
+//
+// 4 2/11/04 12:29a Felixp
+//
+// 3 2/10/04 4:02p Felixp
+//
+// 2 2/04/04 2:04a Felixp
+// work in progress...
+//
+// 1 1/28/04 3:23a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DxeIpl.c
+//
+// Description: DXE Core Loader
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//-----------------------------------------------------------------------------
+
+#include <PEI.h>
+#include <HOB.h>
+#include <AmiHobs.h>
+#include <AmiPeiLib.h>
+#include <PPI/RecoveryModule.h>
+#include <PPI/S3Resume2.h>
+#include <PPI/S3Resume.h>
+#include <PPI/LoadedImagePpi.h>
+#include <Guid/MemoryTypeInformation.h>
+#include <token.h>
+#include <AmiHobs.h>
+#include "Core/CPU/CPU.h"
+#include "Core/CPU/CpuCspLib.h"
+
+#define SMM_ASM_FIXUP_SMM_BASE 0x38002
+#define SMM_ASM_FIXUP_IED_ZERO_MEM 0x38029
+#define SMM_ASM_BASE_CHANGE_FLAG 0x3808f
+#define APIC_SMI (2 << 8)
+#define APIC_LEVEL_ASSERT (1 << 14)
+#define APIC_NO_SHORT_HAND (0 << 18)
+
+//-----------------------------------------------------------------------------
+
+//****************************************************************************/
+// TYPE DECLARATIONS
+//****************************************************************************/
+typedef VOID (EFIAPI *DXE_ENTRY_POINT)(
+ IN VOID *HobStart
+);
+
+//****************************************************************************/
+// FUNCTION DECLARATIONS
+//****************************************************************************/
+EFI_STATUS EFIAPI Entry(
+ IN EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *HobList
+);
+
+#ifdef x64_BUILD_SUPPORT
+VOID InitLongMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1
+);
+#endif
+
+//****************************************************************************/
+// VARIABLE DECLARATIONS
+//****************************************************************************/
+// PPIs
+EFI_DXE_IPL_PPI DxeIplPpi = { Entry };
+EFI_GUID guidDxeIpl = EFI_DXE_IPL_PPI_GUID;
+EFI_GUID guidEndOfPei = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+
+// PPI to be installed
+static EFI_PEI_PPI_DESCRIPTOR PpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidDxeIpl, &DxeIplPpi
+ }
+};
+
+static EFI_PEI_PPI_DESCRIPTOR EndOfPpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidEndOfPei, NULL
+ }
+};
+
+EFI_PEI_LOADED_IMAGE_PPI LoadedImagePpi;
+EFI_GUID guidLoadedImage = EFI_PEI_LOADED_IMAGE_PPI_GUID;
+static EFI_PEI_PPI_DESCRIPTOR LoadedImagePpiDesc[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidLoadedImage, &LoadedImagePpi
+ }
+};
+
+// The order of elements in this array is important.
+// It defines the order of memory types in the DXE memory map.
+// The first array element corresponds to the type with the largest address.
+// Keeping boot time memory types at the bottom of the list improves
+// stability of the runtime portions of the memory map
+// which is important during S4 resume.
+CONST EFI_MEMORY_TYPE_INFORMATION DefaultMemoryTypeInformation[] = {
+ { EfiRuntimeServicesCode, 0x30 },
+ { EfiRuntimeServicesData, 0x20 },
+ { EfiACPIMemoryNVS, 0x60 },
+ { EfiACPIReclaimMemory, 0x10 },
+ { EfiReservedMemoryType, 0x30 },
+ { EfiBootServicesCode, 0x600 },
+ { EfiBootServicesData, 0x1500 },
+ { EfiMaxMemoryType, 0 } // indicates the end of the table
+};
+
+//****************************************************************************/
+// IMPLEMENTATION
+//****************************************************************************/
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: LoadDxeCore
+//
+// Description:
+// Loads DXE core file into memory
+//
+// Input:
+// IN EFI_PEI_SERVICES **ppPS - pointer to PEI services structure
+// IN EFI_FIRMWARE_VOLUME_HEADER *pFV - pointer to firmware volume header
+// OUT EFI_FFS_FILE_HEADER **ppFile - pointer to returned FFS file header
+// OUT EFI_PHYSICAL_ADDRESS *pAddress - pointer to returned address where file loaded
+// OUT UINT64 *pSize - pointer to returned file size
+// OUT EFI_PHYSICAL_ADDRESS *pEntry - pointer to returned address of entry point
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - DXE core loaded successfully
+// EFI_ERROR - DXE core file not found or cannot be loaded
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LoadDxeCore(
+ IN EFI_PEI_SERVICES **ppPS,
+ IN EFI_FIRMWARE_VOLUME_HEADER *pFV,
+ OUT EFI_FFS_FILE_HEADER **ppFile,
+ OUT EFI_PHYSICAL_ADDRESS *pAddress,
+ OUT UINT64 *pSize,
+ OUT EFI_PHYSICAL_ADDRESS *pEntry
+)
+{
+ EFI_STATUS Status;
+ *ppFile = NULL;
+ // loop via all files
+ while(TRUE)
+ {
+ Status = (*ppPS)->FfsFindNextFile(ppPS, EFI_FV_FILETYPE_DXE_CORE, pFV, ppFile);
+ if( EFI_ERROR(Status) ) return Status;
+ Status = PeiLoadFile(ppPS,*ppFile,pAddress,pSize,pEntry);
+ if( !EFI_ERROR(Status) ) return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: S3Resume
+//
+// Description:
+// Implementation of S3 wake boot path
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - S3 resume boot path is failed or cannot be found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS S3Resume(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_S3_RESUME2_PPI *pS32;
+ EFI_PEI_S3_RESUME_PPI *pS3;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ EFI_STATUS Status;
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "S3Resume\n"));
+ Status = (*PeiServices)->LocatePpi(PeiServices,&gEfiPeiS3Resume2PpiGuid,0,&pDummy,&pS32);
+ if (EFI_ERROR(Status))
+ {
+ Status = (*PeiServices)->LocatePpi(PeiServices,&gPeiS3ResumePpiGuid,0,&pDummy,&pS3);
+ if (EFI_ERROR(Status))
+ {
+ PEI_ERROR_CODE(PeiServices,PEI_S3_RESUME_PPI_NOT_FOUND,EFI_ERROR_MAJOR);
+ return Status;
+ }
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Calling S3RestoreConfig\n"));
+ return pS3->S3RestoreConfig(PeiServices);
+ }
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Calling S3RestoreConfig2\n"));
+ return pS32->S3RestoreConfig2(pS32);
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: Recovery
+//
+// Description:
+// Implementation of recovery boot path
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - recovery capsule not found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS Recovery(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ static EFI_GUID guidRecoveryModule = EFI_PEI_RECOVERY_MODULE_PPI_GUID;
+ EFI_PEI_RECOVERY_MODULE_PPI *pRecovery;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ EFI_STATUS Status = (*PeiServices)->LocatePpi(PeiServices,&guidRecoveryModule,0,&pDummy,&pRecovery);
+ if (EFI_ERROR(Status)){
+ PEI_ERROR_CODE(PeiServices,PEI_RECOVERY_PPI_NOT_FOUND,EFI_ERROR_MAJOR);
+ return Status;
+ }
+ return pRecovery->LoadRecoveryCapsule(PeiServices,pRecovery);
+}
+
+//defined in ReportFv2.c
+EFI_STATUS ReportFV2Dxe(
+ IN VOID* RecoveryCapsule OPTIONAL,
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: FindRecoveryBuffer
+//
+// Description:
+// Searches for recovery capsule address in HOB
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// OUT VOID **Buffer - pointer where to store found address
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - recovery capsule not found
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindRecoveryBuffer(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT VOID **Buffer
+)
+{
+ EFI_STATUS Status;
+ RECOVERY_IMAGE_HOB *RecoveryHob;
+ static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &RecoveryHob);
+ if(EFI_ERROR(Status))
+ return Status; //we are not on recovery boot path
+
+ Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob);
+ if(EFI_ERROR(Status))
+ return Status; //we are not on recovery boot path
+
+ if(RecoveryHob->Status == EFI_SUCCESS && RecoveryHob->Address != NULL) {
+ *Buffer = (VOID *)(UINTN)RecoveryHob->Address;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+extern const BOOLEAN UseNewImage;
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: PublishDxeFv
+//
+// Description:
+// Publishes Firmware volumes required for DXE phase
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// IN EFI_BOOT_MODE BootMode - current boot mode
+//
+// Output:
+// UINTN - Number of next firmware volume to start search for DXE_CORE from
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN PublishDxeFv(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+ EFI_STATUS Status;
+ UINTN FvNum = 0;
+ VOID *RecoveryBuffer = NULL;
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+
+/* first check for recovery/flashupdate capsule
+BOOT_IN_RECOVERY_MODE - actual recovery or flash update via recovery capsule on disk (in latter case
+boot mode will be changed to BOOT_ON_FLASH_UPDATE after call to Recovery() function)
+BOOT_ON_FLASH_UPDATE - flash update via recovery capsule in memory
+*/
+ if (BootMode == BOOT_IN_RECOVERY_MODE || BootMode == BOOT_ON_FLASH_UPDATE) {
+ Status = Recovery(PeiServices);
+ if (!EFI_ERROR(Status)) {
+ Status = FindRecoveryBuffer(PeiServices, &RecoveryBuffer);
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode); //check if boot mode changed
+ }
+
+ if(EFI_ERROR(Status)) {
+ /* we can't find recovery capsule, report error */
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_FAILED, EFI_ERROR_MAJOR);
+ }
+ }
+
+ if(RecoveryBuffer != NULL) {
+ if(BootMode == BOOT_IN_RECOVERY_MODE || UseNewImage) {
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+ /* when we're in recovery we publish DXE Fv from recovery buffer, instead of flash */
+ while( !EFI_ERROR((*PeiServices)->FfsFindNextVolume(PeiServices, FvNum, &pFV)))
+ FvNum++; //determine how many FVs published already
+#endif
+ Status = ReportFV2Dxe(RecoveryBuffer, PeiServices);
+ if(!EFI_ERROR(Status)) {
+ return FvNum;
+ } else {
+ /* we can't publish recovery capsule, report error */
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_FAILED, EFI_ERROR_MAJOR);
+ }
+ }
+ }
+
+ Status = ReportFV2Dxe(NULL, PeiServices);
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: Entry
+//
+// Description:
+// Implementation of EFI_DXE_IPL_PPI Entry function
+//
+// Input:
+// IN EFI_DXE_IPL_PPI *This - pointer to PPI instance
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+// IN EFI_HOB_HANDOFF_INFO_TABLE *HobList - pointer to HOB list
+//
+// Output:
+// EFI_STATUS
+// EFI_ERROR - Boot failed
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI Entry(
+ IN EFI_DXE_IPL_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_HOB_HANDOFF_INFO_TABLE *HobList
+)
+{
+ EFI_FIRMWARE_VOLUME_HEADER* pFV;
+ UINTN FvNum;
+ EFI_PHYSICAL_ADDRESS DxeCoreAddress, DxeCoreEntry;
+ UINT64 DxeCoreSize;
+ EFI_STATUS Status;
+ EFI_FFS_FILE_HEADER* pFile;
+ EFI_BOOT_MODE BootMode=(EFI_BOOT_MODE)-1; //set it to invalid value
+ EFI_PEI_LOADED_IMAGE_PPI *OldLoadedImagePpi;
+ EFI_PEI_PPI_DESCRIPTOR *OldLoadedImageDesc;
+#ifdef EFI_DEBUG
+ CHAR8 sName[0x100];
+#endif
+ EFI_MEMORY_TYPE_INFORMATION MemoryInformationBuffer[EfiMaxMemoryType + 1];
+ EFI_MEMORY_TYPE_INFORMATION *MemoryInformationPtr = NULL;
+ UINTN MemoryInformationSize;
+ EFI_HOB_GUID_TYPE *MemoryInformationHob;
+
+ PEI_PERF_START(PeiServices,DXEIPL_TOK, NULL,0);
+ PEI_PROGRESS_CODE(PeiServices,PEI_DXE_IPL_STARTED);
+
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ if (BootMode == BOOT_ON_S3_RESUME) {
+#ifndef AMI_CPU_S3_PEI_SUPPORT
+#define AMI_CPU_S3_PEI_SUPPORT 0
+#endif
+#if AMI_CPU_S3_PEI_SUPPORT == 0
+ {
+ VOID *FirstHob;
+ SMM_HOB *SmmHob;
+ EFI_GUID gSmmHobGuid = SMM_HOB_GUID;
+ VOID *SaveBuffer;
+ UINT8 ApicId;
+ UINT8 i,j;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ SmmHob = (SMM_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &SmmHob)))
+ {
+ if (guidcmp(&SmmHob->EfiHobGuidType.Name, &gSmmHobGuid) == 0)
+ break;
+ }
+ if (!EFI_ERROR(Status))
+ {
+ //Allocate memory for temporarly perserve the 3000:8000 data.
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ SmmGetBaseSaveBufferSize(),
+ &SaveBuffer
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ SmmSetupDefaultHandler(SaveBuffer, SmmHob);
+
+ for (i = 0, j = 0; i < SmmHob->NumCpus; ++i)
+ {
+ *(UINT32*)SMM_ASM_FIXUP_SMM_BASE = (UINT32)SmmHob->SmmBase[i];
+ *(UINT8*)SMM_ASM_BASE_CHANGE_FLAG = 0; //Initialize Flag
+
+ ApicId = j;
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER), ApicId << 24, 0x00ffffff);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER), APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI, 0);
+
+ while (!(*(volatile UINT8*)SMM_ASM_BASE_CHANGE_FLAG))
+ {
+ CPULib_Pause(); //Wait on Flag
+ }
+ ++*(UINT16*)SMM_ASM_FIXUP_IED_ZERO_MEM; //Only 0, for first thread to clear IED memory.
+
+ if (IsHtEnabled())
+ {
+ j++;
+ }
+ else
+ {
+ j += 2;
+ }
+ }
+
+ SmmRemoveDefaultHandler(SaveBuffer);
+ }
+ }
+#endif
+ PEI_PERF_END(PeiServices, DXEIPL_TOK, NULL, 0);
+ S3Resume(PeiServices);
+ //if S3 Resume failed, report error and reset system
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_FAILED, EFI_ERROR_MAJOR);
+ (*PeiServices)->ResetSystem(PeiServices);
+ } else {
+ FvNum = PublishDxeFv(PeiServices, BootMode);
+ }
+
+ while( !EFI_ERROR ((*PeiServices)->FfsFindNextVolume (PeiServices, FvNum++, &pFV) )
+ && EFI_ERROR(Status=LoadDxeCore(PeiServices,pFV,&pFile,&DxeCoreAddress,&DxeCoreSize,&DxeCoreEntry))
+ );
+ if (EFI_ERROR(Status))
+ {
+ PEI_ERROR_CODE(PeiServices,PEI_DXE_CORE_NOT_FOUND,EFI_ERROR_MAJOR);
+ PEI_PERF_END(PeiServices,DXEIPL_TOK, NULL,0);
+ return Status;
+ }
+ //Create module allocation HOB for DXE Core
+ CreateHobMemoryAllocationModule(
+ PeiServices, DxeCoreAddress, DxeCoreSize,
+ EfiBootServicesCode, &pFile->Name,
+ DxeCoreEntry
+ );
+
+ // Create a MemoryTypeInformation HOB (used by DXE memory manager)
+
+ // There can only be a single memory type information HOB.
+ // Invalidate other HOB instances (if any).
+ Status = (*PeiServices)->GetHobList(PeiServices, &MemoryInformationHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ while (!EFI_ERROR(
+ FindNextHobByGuid(&gEfiMemoryTypeInformationGuid, &MemoryInformationHob)
+ )) MemoryInformationHob->Header.HobType = EFI_HOB_TYPE_UNUSED;
+
+ MemoryInformationSize = sizeof(MemoryInformationBuffer);
+
+ // In case of S4 resume, use memory type information
+ // from the last full boot (S5 resume).
+ // This preserves the memory map across sessions.
+ Status = PeiGetVariable (
+ PeiServices,
+ (BootMode == BOOT_ON_S4_RESUME)
+ ? L"PreviousMemoryTypeInformation"
+ : EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME,
+ &gEfiMemoryTypeInformationGuid,
+ NULL, &MemoryInformationSize, MemoryInformationBuffer
+ );
+ if (EFI_ERROR(Status)){
+ MemoryInformationPtr = (EFI_MEMORY_TYPE_INFORMATION*)DefaultMemoryTypeInformation;
+ MemoryInformationSize = sizeof(DefaultMemoryTypeInformation);
+ }else{
+ MemoryInformationPtr=MemoryInformationBuffer;
+ }
+ Status = (*PeiServices)->CreateHob (
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(EFI_HOB_GUID_TYPE) + MemoryInformationSize,
+ &MemoryInformationHob
+ );
+ if (!EFI_ERROR(Status)) {
+ MemoryInformationHob->Name = gEfiMemoryTypeInformationGuid;
+ MemCpy( MemoryInformationHob+1, MemoryInformationPtr, MemoryInformationSize);
+ }
+
+
+ //Update LoadedImage PPI information
+ LoadedImagePpi.ImageAddress = DxeCoreAddress;
+ LoadedImagePpi.ImageSize = DxeCoreSize;
+ LoadedImagePpi.FileHandle = pFile;
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices, &guidLoadedImage,
+ 0, &OldLoadedImageDesc, &OldLoadedImagePpi
+ );
+ if (!(EFI_ERROR(Status))) { // if Loaded Image PPI was located
+ Status = (*PeiServices)->ReInstallPpi (
+ PeiServices, OldLoadedImageDesc, LoadedImagePpiDesc
+ );
+ } else {
+ // Loaded Image PPI not found, try installing it again.
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices,LoadedImagePpiDesc
+ );
+ }
+ PEI_PERF_END(PeiServices,DXEIPL_TOK, NULL,0);
+ (*PeiServices)->InstallPpi(PeiServices,EndOfPpiList);
+#ifdef EFI_DEBUG
+ if (!GetName((VOID*)DxeCoreAddress,sName)) Sprintf_s(sName,sizeof(sName),"DXE-Core");
+ PeiTrace(TRACE_DXEIPL, PeiServices, "%s.Entry(%X)\n", sName, DxeCoreEntry);
+#endif
+ PEI_PROGRESS_CODE(PeiServices,DXE_CORE_STARTED);
+#ifdef x64_BUILD_SUPPORT
+ InitLongMode(
+ PeiServices, (VOID*)(UINTN)DxeCoreEntry, HobList
+ );
+#else
+ ((DXE_ENTRY_POINT )DxeCoreEntry)(HobList);
+#endif
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Name: PeiInitDxeIpl
+//
+// Description:
+// DXE loader entry point
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader - pointer to FFS file header
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services structure
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - EFI_DXE_IPL_PPI installed successfully
+// EFI_ERROR - error occured during execution
+//
+// Notes:
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiInitDxeIpl (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ return (*PeiServices)->InstallPpi(PeiServices,PpiList);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CORE_PEI/PciCfg.c b/Core/CORE_PEI/PciCfg.c
new file mode 100644
index 0000000..c831953
--- /dev/null
+++ b/Core/CORE_PEI/PciCfg.c
@@ -0,0 +1,491 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PeiMain/PciCfg.c 12 8/12/11 12:24p Artems $
+//
+// $Revision: 12 $
+//
+// $Date: 8/12/11 12:24p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PeiMain/PciCfg.c $
+//
+// 12 8/12/11 12:24p Artems
+// EIP 64107: Added changes for module to be compliant with PI
+// specification v 1.2
+//
+// 11 3/22/11 5:15p Felixp
+// Method of invocation of the in-memory entry point has changed
+// from LOAD_HOB to eLink registered under PeiCoreMemoryInstalled.
+// This is more efficient.
+//
+// 10 2/05/11 3:44p Artems
+// Changed functions calling interfaces to meet PI 1.0 specification
+// requirements
+//
+// 9 11/05/09 5:01p Oleksiyy
+// EIP 27821 Support for 64 bit operations in PciRead and PciWrite added.
+// To use this functions CpuIo.c, IA32CLib.c, x64AsmLib.asm files should
+// be updated also.
+//
+// 8 7/08/09 5:53p Vyacheslava
+// Updated according to the coding standards.
+//
+// 7 6/16/05 10:56a Felixp
+// 1. Once memory is available, PEI Core PEIMs that created PEIM_LOAD_HOB
+// are reallocated to memory.
+// 2. ImagePei.c removed
+// 3. FileLoader moved from DxeIpl to PEI Core
+//
+// 6 6/06/05 7:49p Felixp
+//
+// 5 6/06/05 1:25p Felixp
+//
+// 4 6/03/05 3:45p Felixp
+// Updated to support changes introduced in PEI CIS 0.91
+//
+// 3 3/04/05 9:43a Mandal
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 8 1/28/04 3:24a Felixp
+//
+// 7 1/27/04 3:58a Felixp
+// Bug fixes and improvements as a part of PEI CORE integration
+//
+// 6 12/29/03 5:25p Felixp
+// preffix 'EFI_' added to the names of the PEIM descriptor structures and
+// flags
+//
+// 5 12/15/03 4:35p Robert
+//
+// 4 12/15/03 4:25p Robert
+//
+// 3 12/15/03 12:41p Robert
+// changed position of GUID definition below PPI include
+//
+// 2 12/15/03 11:54a Robert
+// Updated the definitions of PPI includes and removed the entry point
+// definitions
+//
+// 1 12/11/03 5:34p Robert
+// Initial Check in
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciCfg.c
+//
+// Description: This file contains the implementation of the PCI Cfg I/O
+// specification. For questions about the specification refer to the
+// PEI CIS specification chapter 9
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+// Module specific Includes
+#include <AmiPeiLib.h>
+// PPI Produced
+#include <PPI/PciCfg2.h>
+
+// Module specific macros
+// Make a PCI Access address out of the value that is passed in. Clear the lowest 2 bits
+// PCI accesses are always 4 byte aligned
+#define GET_PCI_ADDRESS(x) \
+(0x080000000 | (((UINTN)x & 0x0FF000000) >> 8) | (((UINTN)x & 0x0FF0000)>> 5) | (x & 0x0700) | (x & 0x0FC))
+
+// Function Prototypes
+EFI_STATUS PciRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS PciWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS PciModify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+#if PI_SPECIFICATION_VERSION<0x00010000
+ IN UINTN SetBits,
+ IN UINTN ClearBits
+#else
+ IN VOID *SetBits,
+ IN VOID *ClearBits
+#endif
+);
+
+
+// Local Definitions
+EFI_PEI_PCI_CFG2_PPI mPciCfgPpi = {
+ PciRead,
+ PciWrite,
+ PciModify
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPciCfg2PpiGuid,
+ &mPciCfgPpi
+ }
+};
+
+// Function Definitions
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciCfgMemInit
+//
+// Description: This function installs the PCI Configuration PPI and exits
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system
+// **PeiServices - pointer to the Pei Services function and data structure
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI PciCfgMemInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ // update PCI Config pointer
+ (*PeiServices)->PciCfg = &mPciCfgPpi;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciCfgInit
+//
+// Description: This function installs the PCI Configuration PPI and exits
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system
+// **PeiServices - pointer to the Pei Services function and data structure
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI PciCfgInit (
+ IN EFI_PEI_FILE_HANDLE FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ // Install the PCI Config Ppi
+ (*PeiServices)->PciCfg = &mPciCfgPpi;
+ Status = (*PeiServices)->InstallPpi( PeiServices, mPpiList );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciRead
+//
+// Description: This function Reads a value from the PCI Config space and
+// returns that value in Buffer.
+//
+// Input:
+// **PeiServices - Pointer to the PEI Core data Structure
+// *This - Pointer to the instance of the PCI Config PPI
+// Width - Size of the data to be read from the configuration space
+// Address - PCI address of the register to be read(Bus/Dev/Func/Reg)
+// *Buffer - The data read from the requested PCI Configuration register
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS PciRead (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+)
+{
+ UINT64 IoAddr;
+ UINT32 PciAddr;
+ EFI_PEI_CPU_IO_PPI *CpuIo = (*PeiServices)->CpuIo;
+ EFI_PEI_PCI_CFG_PPI_WIDTH TmpWidth;
+ UINT8 *Buffer8=(UINT8*)Buffer;
+
+ if (((Width & 3) == EfiPeiPciCfgWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiPeiPciCfgWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+ // Make a usable PCI address out of the Address passed in
+ PciAddr = (UINT32)GET_PCI_ADDRESS(Address);
+
+ // Access 0xCF8 and use corrected address to enable the read to PCI
+ IoAddr = 0x0CF8;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+
+ // Access 0xCFC to get the data requested. Increment IoAddr to
+ // read the correct register from the PCI Config space
+ IoAddr = 0x0CFC + (Address & 0x03);
+
+ TmpWidth=Width;
+
+ if ((Width & 3) > EfiPeiPciCfgWidthUint32)TmpWidth=Width-1;
+ // Read the register requested. Use the passed in Width value to
+ // indicate the number of bytes to read. If Width = 8 bytes - split into two reads
+ CpuIo->Io.Read(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)Buffer8
+ );
+ // no formatting should be needed on the output data. Read the correct
+ // register and the correct width should format the data properly
+
+ if (Width == TmpWidth) return EFI_SUCCESS;
+
+ IoAddr = 0x0CF8;
+ PciAddr = PciAddr + 4;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+ // Read the next 4 bytes
+ IoAddr = 0x0CFC;
+ CpuIo->Io.Read(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)(Buffer8+4)
+ );
+
+
+
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciWrite
+//
+// Description: This function writes a value to the PCI Config space
+//
+// Input:
+// **PeiServices - Pointer to the PEI Core data Structure
+// *This - Pointer to the instance of the PCI Config PPI
+// Width - Size of the data to write to the configuration space
+// Address - PCI address of the register to write to (Bus/Dev/Func/Reg)
+// *Buffer - The data to write to the requested PCI Configuration register
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS PciWrite (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN OUT VOID *Buffer
+)
+{
+ UINT64 IoAddr;
+ UINT32 PciAddr;
+ EFI_PEI_CPU_IO_PPI *CpuIo = (*PeiServices)->CpuIo;
+ EFI_PEI_PCI_CFG_PPI_WIDTH TmpWidth;
+ UINT8 *Buffer8=(UINT8*)Buffer;
+ if (((Width & 3) == EfiPeiPciCfgWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiPeiPciCfgWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ // Make a usable PCI address out of the Address passed in
+ PciAddr = (UINT32)GET_PCI_ADDRESS(Address);
+
+ // Access 0xCF8 and use corrected address to enable the read to PCI
+ IoAddr = 0x0CF8;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+
+ // Access 0xCFC to get the data requested. Increment IoAddr to
+ // read the correct register from the PCI Config space
+ IoAddr = 0x0CFC + (Address & 0x03);
+
+ TmpWidth=Width;
+
+ if ((Width & 3) > EfiPeiPciCfgWidthUint32) TmpWidth = Width - 1;
+ // Write the register requested. Use the passed in Width value to
+ // indicate the number of bytes to read. If Width = 8 bytes - split into two writes
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)Buffer8
+ );
+
+
+ if (Width == TmpWidth) return EFI_SUCCESS;
+
+ // Access 0xCF8 and use next 4 bytes address to enable the read to PCI
+ IoAddr = 0x0CF8;
+ PciAddr = PciAddr + 4;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ EfiPeiCpuIoWidthUint32,
+ IoAddr,
+ 1,
+ (VOID*)(&PciAddr)
+ );
+
+ // Write the next 4 bytes
+ IoAddr = 0x0CFC;
+ CpuIo->Io.Write(
+ PeiServices,
+ CpuIo,
+ TmpWidth,
+ IoAddr,
+ 1,
+ (VOID*)(Buffer8+4)
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//============================================================================
+// Procedure: PciModify
+//
+// Description: This function modifies a value in the PCI Config space.
+// This function uses the SetBits and ClearBits values to modify the
+// register. First the ClearBits value is used to clear the unwanted bits
+// then the SetBits value is used to set the wanted bits.
+//
+// Input:
+// **PeiServices - Pointer to the PEI Core data Structure
+// *This - Pointer to the instance of the PCI Config PPI
+// Width - Size of the data to write to the configuration space
+// Address - PCI address of the register to write to (Bus/Dev/Func/Reg)
+// SetBits - The bits in the register that need to be set
+// ClearBits - The bits in the register that should be cleared
+//
+// Output: EFI_SUCCESS
+//
+//============================================================================
+//<AMI_PHDR_END>
+
+EFI_STATUS PciModify (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_PCI_CFG2_PPI *This,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+#if PI_SPECIFICATION_VERSION<0x00010000
+ IN UINTN SetBits,
+ IN UINTN ClearBits
+#else
+ IN VOID *SetBits,
+ IN VOID *ClearBits
+#endif
+)
+{
+ EFI_STATUS Status;
+ UINTN Data;
+ if (((Width & 3) == EfiPeiPciCfgWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiPeiPciCfgWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ Status = PciRead (
+ PeiServices,
+ This,
+ Width,
+ Address,
+ &Data
+ );
+#if PI_SPECIFICATION_VERSION<0x00010000
+ Data = SetBits | (Data & (~ClearBits));
+#else
+ Data = *(UINTN*)SetBits | (Data & (~*(UINTN*)ClearBits));
+#endif
+ Status = PciWrite (
+ PeiServices,
+ This,
+ Width,
+ Address,
+ &Data
+ );
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CORE_PEI/PeiPerf.c b/Core/CORE_PEI/PeiPerf.c
new file mode 100644
index 0000000..4922163
--- /dev/null
+++ b/Core/CORE_PEI/PeiPerf.c
@@ -0,0 +1,30 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Perf.c
+
+Abstract:
+
+ Support for performance primitives.
+
+--*/
+#include <AmiLib.h>
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ )
+{
+ *TimerValue = GetCpuTimer();
+ return EFI_SUCCESS;
+}
diff --git a/Core/CPU/CPU.h b/Core/CPU/CPU.h
new file mode 100644
index 0000000..8795524
--- /dev/null
+++ b/Core/CPU/CPU.h
@@ -0,0 +1,443 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPU.h 3 10/17/12 2:20a Davidhsieh $
+//
+// $Revision: 3 $
+//
+//
+// $Date: 10/17/12 2:20a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPU.h $
+//
+// 3 10/17/12 2:20a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Setup items CTDP BIOS, C8, C9 and C10 created
+//
+// 2 9/26/12 10:53a Davidhsieh
+// [TAG] None
+// [Description] Add CPU APIC ID data variable for S3 resume
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: Cpu.h
+//
+// Description: Common header for the CPU.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPU_H__
+#define __CPU_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <efi.h>
+
+#ifdef PEI_COMPILE //In PEI, this must be defined before including this file.
+#include <pei.h>
+#include <Ppi/Stall.h>
+#endif
+
+#define MP_CPU_APIC_ID_DATA_GUID \
+ {0x1456cc6e, 0x22ac, 0x5289, 0x33, 0xba, 0x2e, 0x13, 0xbb, 0xda, 0xba, 0xee}
+
+// Define the equates here
+//CPU APIC includes
+#define APIC_ALL_EXCLUDING_SELF (3 << 18)
+#define APIC_SIPI (6 << 8)
+#define APIC_INIT (5 << 8)
+#define APIC_SMI (2 << 8)
+#define APIC_DELIVERY_STATUS (1 << 12)
+#define APIC_LEVEL_ASSERT (1 << 14)
+#define APIC_LEVEL_DEASSERT (0 << 14)
+#define APIC_NO_SHORT_HAND (0 << 18)
+
+
+#define MSR_XAPIC_BASE 0x1B
+#define XAPIC_BASE_BSP_BIT 8
+#define XAPIC_X2APIC_ENABLE_BIT 10
+#define XAPIC_GLOBAL_ENABLE_BIT 11
+
+
+#define XAPIC_ENABLE_BIT 8 // SVR SW APIC Enable/Disable Bit
+#define APIC_PRESENT_BIT 9 // APIC Present bit in Feature Flags
+
+#define MASK_ICR_CLEAR 0xFFF33000 // AND mask for ICR reserved bit
+#define OR_MASK_INIT_IPI 0x00004500 // OR mask to send INIT IPI
+#define OR_MASK_USE_DEST_FIELD 0x00000000 // OR mask to set dest field = "Dest Field"
+
+//Cstate
+#define C1_SUB_STATES_MASK 0x000000f0
+#define C3_SUB_STATES_MASK 0x00000f00
+#define C6_SUB_STATES_MASK 0x0000f000
+#define C7_SUB_STATES_MASK 0x000f0000
+#define C8_SUB_STATES_MASK 0x00f00000
+#define C9_SUB_STATES_MASK 0x0f000000
+#define C10_SUB_STATES_MASK 0xf0000000
+
+//-----------------------------------------------------------------------------
+// Local APIC Register Equates
+//-----------------------------------------------------------------------------
+#define LOCAL_APIC_ID 0x20
+#define LOCAL_APIC_VERSION 0x30
+#define LOCAL_APIC_TASK_PRI 0x80
+#define LOCAL_APIC_ARB_PRI 0x90
+#define LOCAL_APIC_PROC_PRI 0xa0
+#define LOCAL_APIC_EOI 0xb0
+#define LOCAL_APIC_LDR 0xd0
+#define LOCAL_APIC_DEST_FORMAT 0xe0
+#define LOCAL_APIC_SVR 0xf0
+#define LOCAL_APIC_ISR0 0x100
+#define LOCAL_APIC_TMR0 0x180
+#define LOCAL_APIC_IRR0 0x200
+#define LOCAL_APIC_ERR_STAT 0x280
+#define LOCAL_APIC_ICR_LO 0x300
+#define LOCAL_APIC_ICR_HI 0x310
+#define LOCAL_APIC_LVT 0x320
+#define LOCAL_APIC_PERF 0x340
+#define LOCAL_APIC_LVT_LINT0 0x350
+#define LOCAL_APIC_LVT_LINT1 0x360
+#define LOCAL_APIC_LVT_ERR 0x370
+#define LOCAL_APIC_ITC 0x380
+#define LOCAL_APIC_TIMER 0x390
+#define LOCAL_APIC_TMR_DIV 0x3e0
+
+#define PSD_SW_ALL 0xfc
+#define PSD_SW_ANY 0xfd
+#define PSD_HW_ALL 0xfe
+
+#define TSD_HW_ALL 0xfe
+
+#define MSR_IA32_PLATFORM_ID 0x17
+#define MSR_CHL_CONTROLS 0x2d
+ #define B_FORWARD_CODE_DISABLE (1<<9)
+#define MSR_IA32_CR_PIC_MSG_CONTROL 0x2e
+#define MSR_CORE_THREAD_COUNT 0x35
+#define MSR_IA32_FEATURE_CONTROL 0x3a
+ #define SMRR_LOCK_BIT 0x1
+ #define SMRR_ENABLE_BIT 0x3
+ #define SMRR_ENABLE_MASK (1<<3)
+#define MSR_SMM_SAVE_CONTROL 0x3e
+#define MSR_IA32_BIOS_UPDT_TRIG 0x79
+#define MSR_IA32_BIOS_SIGN_ID 0x8b
+#define MSR_PMG_CST_CONFIG_CONTROL 0xe2
+#define MSR_PMG_IO_CAPTURE_ADDR 0xe4
+#define MSR_PLATFORM_INFO 0xce
+ #define TCC_ACTIVE_OFFSET_PROGRAMMABLE_BIT 30
+ #define XE_TDP_TDC_PROGRAMMABLE_BIT 29
+ #define XE_CORE_RATIO_PROGRAMMABLE_BIT 28
+ #define SMM_SAVE_CONTROL_BIT 16
+ #define MAX_NON_TURBO_RATIO_OFFSET 8
+ #define MAX_NON_TURBO_RATIO_MASK 0xff
+#define MSR_FEATURE_CONFIG 0x13c
+ #define MSR_FEATURE_CONFIG_LOCK 1
+#define MSR_IA32_MCG_CAP 0x179
+#define MSR_IA32_MCG_CTL 0x17b
+#define MSR_FLEX_RATIO 0x194
+#define MSR_IA32_PERF_STATUS 0x198
+#define MSR_IA32_PERF_CTL 0x199
+#define MSR_IA32_CLOCK_MODULATION 0x19a
+ #define CLK_MOD_ENABLE 0x10
+#define MSR_IA32_MISC_ENABLE 0x1a0
+ #define TURBO_DISABLE_MASK ((UINT64)1 << 38)
+ #define TURBO_MODE_DISABLE_BIT 38
+#define MSR_MISC_FEATURE_CONTROL 0x1a4
+ #define DATA_REUSE_OPT 0x40
+ #define DCU_IP_PREFETCHER 0x8
+ #define DCU_STREAMER_PREFETCHER 0x4
+ #define MLC_SPATIAL_PREFETCHER 0x2
+ #define MLC_STREAMER_PREFETCHER 0x1
+#define MSR_MISC_PWR_MGMT 0x1aa
+ #define EIST_HW_COORD_DIS_BIT 0
+ #define ENG_PERF_BIAS_EN_BIT 1
+ #define LOCK_TM_INT_BIT 22
+#define MSR_TURBO_POWER_CURRENT_LIMIT 0x1ac
+ #define TDC_LIMIT_OVERRIDE_ENABLE_BIT 31
+ #define TDC_LIMIT_MASK 0x7FFF0000
+ #define TDC_LIMIT_OFFSET 16
+ #define TDP_LIMIT_OVERRIDE_ENABLE_BIT 15
+ #define TDP_LIMIT_MASK 0x7FFF
+ #define TDP_LIMIT_OFFSET 0
+#define MSR_TURBO_RATIO_LIMIT 0x1ad
+ #define MAX_RATIO_LIMIT_8C_OFFSET 56
+ #define MAX_RATIO_LIMIT_7C_OFFSET 48
+ #define MAX_RATIO_LIMIT_6C_OFFSET 40
+ #define MAX_RATIO_LIMIT_5C_OFFSET 32
+ #define MAX_RATIO_LIMIT_4C_OFFSET 24
+ #define MAX_RATIO_LIMIT_3C_OFFSET 16
+ #define MAX_RATIO_LIMIT_2C_OFFSET 8
+ #define MAX_RATIO_LIMIT_1C_OFFSET 0
+ #define MAX_RATIO_LIMIT_MASK 0xff
+#define MSR_IA32_ENERGY_PERF_BIAS 0x1b0
+#define MSR_FERR_CAPABILITY 0x1f1
+#define MSR_EMRR_PHYSBASE 0x1f4
+#define MSR_EMRR_PHYSMASK 0x1f5
+#define B_EMRR_VALID (1 << 11)
+#define MSR_IA32_PLATFORM_DCA_CAP 0x1f8
+#define MSR_IA32_DCA_CAP 0x1f9
+#define MSR_IA32_DCA_0_CAP 0x1fa
+#define MSR_POWER_CTL 0x1fc
+#define MSR_IA32_MC0_CTL 0x400
+#define MSR_IA32_MC0_STATUS 0x401
+
+// Generic MTRR equates
+#define MTRR_ATTRIB_WB 6
+
+#define MSR_IA32_MTRR_CAP 0xfe
+ #define SMRR_SUPPORT_BIT 11
+ #define SMRR_SUPPORT_MASK (1 << 11)
+ #define EMRR_SUPPORT_MASK (1 << 12)
+#define MTRR_PHYS_BASE_0 0x200
+#define MTRR_PHYS_MASK_0 0x201
+#define MTRR_PHYS_BASE_1 0x202
+#define MTRR_PHYS_MASK_1 0x203
+#define MTRR_PHYS_BASE_2 0x204
+#define MTRR_PHYS_MASK_2 0x205
+#define MTRR_PHYS_BASE_3 0x206
+#define MTRR_PHYS_MASK_3 0x207
+#define MTRR_PHYS_BASE_4 0x208
+#define MTRR_PHYS_MASK_4 0x209
+#define MTRR_PHYS_BASE_5 0x20a
+#define MTRR_PHYS_MASK_5 0x20b
+#define MTRR_PHYS_BASE_6 0x20c
+#define MTRR_PHYS_MASK_6 0x20d
+#define MTRR_PHYS_BASE_7 0x20e
+#define MTRR_PHYS_MASK_7 0x20f
+#define MTRR_FIX_64K_00000 0x250
+#define MTRR_FIX_16K_80000 0x258
+#define MTRR_FIX_16K_A0000 0x259
+#define MTRR_FIX_4K_C0000 0x268
+#define MTRR_FIX_4K_C8000 0x269
+#define MTRR_FIX_4K_D0000 0x26a
+#define MTRR_FIX_4K_D8000 0x26b
+#define MTRR_FIX_4K_E0000 0x26c
+#define MTRR_FIX_4K_E8000 0x26d
+#define MTRR_FIX_4K_F0000 0x26e
+#define MTRR_FIX_4K_F8000 0x26f
+#define MSR_IA32_MC8_CTL2 0x288
+#define MTRR_DEF_TYPE 0x2ff
+#define MSR_NO_EVICT_MODE 0x2e0
+#define B_MSR_NO_EVICT_MODE_SETUP 1
+#define B_MSR_NO_EVICT_MODE_RUN 2
+#define MSR_UNCORE_CR_MEMLOCK_COMMANDS 0x2e2
+
+#define MSR_PP0_CURRENT_CONFIG 0x601
+#define MSR_PP1_CURRENT_CONFIG 0x602
+#define MSR_PACKAGE_POWER_SKU_LIMIT 0x606
+#define MSR_PKGC3_IRTL 0x60a
+#define MSR_PKGC6_IRTL 0x60b
+#define MSR_PKGC7_IRTL 0x60c
+#define MSR_TURBO_POWER_LIMIT 0x610
+ #define POWER_LIMIT_1_MASK 0x7fff
+ #define POWER_LIMIT_1_TIME_MASK 0xfe0000
+ #define POWER_LIMIT_2_MASK (UINT64)0x7fff00000000
+#define MSR_PACKAGE_POWER_SKU 0x614
+#define MSR_PP0_POWER_LIMIT 0x638
+#define MSR_PP1_POWER_LIMIT 0x640
+
+#define MSR_EXT_XAPIC_LOGICAL_APIC_ID 0x802
+#define MSR_EXT_XAPIC_VERSION 0x803
+#define MSR_EXT_XAPIC_SVR 0x80f
+#define B_MSR_XAPIC_SVR_SOFTWARE_ENABLE (1 << 8)
+#define MSR_EXT_XAPIC_ICR 0x830
+#define MSR_EXT_XAPIC_LVT_LINT0 0x835
+#define MSR_EXT_XAPIC_LVT_LINT1 0x836
+
+#define GAINESTOWN 0x106a0
+#define WESTMERE 0x206c0
+#define NEHALEM_EX 0x206e0
+#define WESTMERE_EX 0x206f0
+#define SANDY_BRIDGE 0x206a0
+#define JAKETOWN 0x206d0
+#define IVY_BRIDGE 0x306a0
+
+#define NUM_OF_FIXED_MTRRS 11
+
+VOID LockInc32(UINT32 *);
+
+typedef struct {
+ UINT32 SmrrSupport:1;
+ UINT32 DcaSupport:1;
+ UINT32 Rsv1:30;
+ UINT32 Rsv2:32;
+} BOARD_ADDITIONAL_FEATURE_FLAGS;
+
+typedef struct {
+ UINT32 FeatureEcx;
+ UINT32 FeatureEdx;
+ UINT32 ExtFeatureEax;
+ UINT32 ExtFeatureEbx;
+ UINT32 ExtFeatureEcx;
+ UINT32 ExtFeatureEdx;
+ BOARD_ADDITIONAL_FEATURE_FLAGS Flags;
+} BOARD_CPU_FEATURES;
+
+UINT32 GetMinCpuFeatures(
+ IN UINT8 NumCpus,
+ IN VOID *MpData,
+ IN BOARD_CPU_FEATURES *AllFeatures,
+ OUT BOARD_CPU_FEATURES *Feature
+);
+
+
+#pragma pack (1)
+typedef struct {
+ UINT16 Limit;
+ UINTN Base; //This shared between 32 bit and 64 bit.
+} DESCRIPTOR_TABLE;
+
+typedef struct _MP_CPU_APICID_DATA {
+ UINT8 NumberOfCpu;
+ UINT8 ApicId[32];
+} MP_CPU_APICID_DATA;
+#pragma pack()
+
+#define MP_AP_ONLY 0
+#define MP_BSP_AP 1
+
+#define MP_PARALLEL 0
+#define MP_SERIALIZE 1
+
+#define MP_FREERUN 0
+#define MP_WAIT 1
+UINT32 StartCpus(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ IN VOID *ApGlobalData OPTIONAL,
+ IN BOOLEAN AllCpus,
+ IN UINT32 ApicId, //If only 1 cpu
+ IN VOID *Address
+);
+
+VOID StartAllAps(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ OUT VOID **MpData
+);
+VOID PrepareApsForNormalExec(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+#endif
+ IN VOID *MpData
+);
+VOID EarlyExecuteFunctionOnRunningCpus(
+ IN VOID *MpData,
+ IN VOID (*Function)(UINT32, VOID *Context), //First parameters will always be 0.
+ IN VOID *Context
+);
+VOID RestartAp(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ IN VOID *MpData,
+ IN UINT32 Cpu
+);
+
+VOID SetHaltFunction(
+ IN VOID *MpData,
+ IN VOID *Function
+);
+
+UINT32 GetNumCpus(VOID *MpData);
+VOID ExecuteFunctionOnRunningCpus(
+ IN VOID *MpData,
+ IN BOOLEAN ExecuteOnBsp,
+ IN BOOLEAN Serialize,
+ IN BOOLEAN Block,
+ IN VOID (*Function)(UINT32 Cpu, VOID *Context),
+ IN VOID *Context
+);
+BOOLEAN ExecuteFunctionOnCpu(
+ IN VOID *MpData,
+ IN UINT32 Cpu,
+ IN BOOLEAN Block,
+ IN VOID (*Function)(UINT32 Cpu, VOID *Context),
+ IN VOID *Context
+);
+VOID HaltAllAps(
+ IN VOID *MpData,
+ IN BOOLEAN WaitUntilHalted
+);
+VOID HaltCpu(
+ IN VOID *MpData,
+ IN UINT32 Cpu,
+ IN BOOLEAN WaitUntilHalted
+);
+BOOLEAN IsCpuHalted(
+ IN VOID *MpData,
+ IN UINT32 Cpu
+);
+
+BOOLEAN IsCpuIdle(
+ IN VOID *MpData,
+ IN UINT32 Cpu
+);
+
+BOOLEAN AreCpusIdle(
+ IN VOID *MpData
+);
+
+UINT32 WhoIsBsp(VOID *MpData);
+
+UINT32 GetCpuBist(IN VOID *MpData, IN UINT32 Cpu);
+UINT32 GetCpuNumByApicId(VOID *MpData, UINT32 ApicId);
+
+VOID SwitchBsp(
+#ifdef PEI_COMPILE
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_STALL_PPI *PeiStall,
+#endif
+ IN VOID *MpData,
+ IN UINT32 NewBsp
+);
+
+VOID ProgramLocalApic(IN UINT32 Cpu, IN VOID *Context);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CPUCore.cif b/Core/CPU/CPUCore.cif
new file mode 100644
index 0000000..6e1b63d
--- /dev/null
+++ b/Core/CPU/CPUCore.cif
@@ -0,0 +1,30 @@
+<component>
+ name = "CPU Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU"
+ RefName = "CPU Core"
+[files]
+"CPU.h"
+"CpuCspLib.c"
+"CPUCspLib.h"
+"CpuDxe.c"
+"CpuDxe.dxs"
+"CpuDxe.h"
+"CpuPei.c"
+"CpuPei.dxs"
+"CpuPei.h"
+"CpuPeiFuncs.c"
+"CpuDxeFuncs.c"
+"CpuPeiBeforeMem.c"
+"CpuSmbios.c"
+"MBIOSMAC.MAC"
+"ResetVector.asm"
+"Startup32.asm"
+[parts]
+"CPU Hobs"
+"CpuPPIs"
+"CpuProtocols"
+"MicrocodeUpdate"
+"CpuTools"
+"MiscX64Lib"
+<endComponent>
diff --git a/Core/CPU/CPUCspLib.h b/Core/CPU/CPUCspLib.h
new file mode 100644
index 0000000..94f282a
--- /dev/null
+++ b/Core/CPU/CPUCspLib.h
@@ -0,0 +1,333 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPUCspLib.h 5 2/07/13 3:57a Hsingyingchung $
+//
+// $Revision: 5 $
+//
+// $Date: 2/07/13 3:57a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CPUCspLib.h $
+//
+// 5 2/07/13 3:57a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+//
+// 4 12/20/12 10:27a Hsingyingchung
+// [TAG] EIP108128
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] "Max non-turbo ratio" can't show in BIOS setup when first
+// boot after flashing BIOS
+// [RootCause] Doesn't initialize max non-turbo ratio value when first
+// boot after flashing BIOS.
+// [Solution] Add initialize code for max non-turbo ratio.
+//
+// 3 11/23/12 2:08a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 2 5/17/12 9:40p Davidhsieh
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuCspLib.h
+//
+// Description: Header file for Cpu Csp Lib.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPULIB_H__
+#define __CPULIB_H__
+
+#include <efi.h>
+#include <pei.h>
+#include "amihobs.h"
+#include "smm.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Bist;
+} AMI_STATUS_CODE_CPU_BIST_DATA;
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 HeaderVersion;
+ UINT32 UpdateRevision;
+ UINT32 Date;
+ UINT32 CpuSignature;
+ UINT32 Checksum;
+ UINT32 LoaderRevison;
+ UINT32 Flags:8;
+ UINT32 RV3:24;
+ UINT32 DataSize;
+ UINT32 TotalSize;
+ UINT32 RV4[3];
+} MICROCODE_HEADER;
+
+typedef struct {
+ UINT32 CpuSignature;
+ UINT32 Flags;
+ UINT32 Checksum;
+} PROC_SIG;
+
+typedef struct {
+ UINT32 Count;
+ UINT32 Checksum;
+ UINT8 Rsv[12];
+ PROC_SIG ProcSig[1];
+} MICROCODE_EXT_PROC_SIG_TABLE;
+
+#pragma pack(pop)
+
+// {CD541D77-6699-4b36-A31E-1AA4C5D5B946}
+#define AMI_STATUS_CODE_CPU_BIST_DATA_GUID \
+ {0xcd541d77, 0x6699, 0x4b36, 0xa3, 0x1e, 0x1a, 0xa4, 0xc5, 0xd5, 0xb9, 0x46}
+
+UINT64 ReadMsr (UINT32 Msr);
+VOID WriteMsr(UINT32 Msr, UINT64 Value);
+VOID ReadWriteMsr(UINT32 Msr, UINT64 Value, UINT64 Mask);
+VOID CPULib_CpuID(UINT32 CpuIDIndex, UINT32 * RegEAX, UINT32 * RegEBX,
+ UINT32 * RegECX, UINT32 * RegEDX);
+UINT32 GetCpuSignature();
+UINT32 GetCpuFamily(UINT32 CpuSignature);
+UINT32 GetCpuModel(UINT32 CpuSignature);
+UINT32 GetCpuPlatformId();
+UINT32 GetSmrrBaseMsr();
+UINT8 NumSupportedThreadsPerCore();
+UINT8 NumSupportedCpuCores();
+UINT8 NumCpuCores();
+UINT8 NumLogicalCpus();
+BOOLEAN IsHtEnabled();
+BOOLEAN IsHt0();
+BOOLEAN IsCore0();
+BOOLEAN isXDSupported(CPU_FEATURES *Features);
+BOOLEAN isTurboModeSupported();
+BOOLEAN isFullUnlockCpuSuuported();
+BOOLEAN isXETdcTdpLimitSupported();
+BOOLEAN isXECoreRatioLimitSupported();
+BOOLEAN isLimitCpuidSupported();
+BOOLEAN IsMachineCheckSupported(CPU_FEATURES *Features);
+BOOLEAN IsEnergyPerfBiasSupported();
+BOOLEAN IsCxInterruptFilteringSupported();
+BOOLEAN IsVmxSupported(CPU_FEATURES *Features);
+BOOLEAN IsSmxSupported(CPU_FEATURES *Features);
+BOOLEAN IsSmrrSupported(CPU_FEATURES *Features);
+BOOLEAN IsX64Supported(CPU_FEATURES *Features);
+
+BOOLEAN CPULib_IsVmxEnabled();
+BOOLEAN CPULib_IsSmxEnabled();
+BOOLEAN CPULib_IsSmrrEnabled();
+BOOLEAN CPULib_IsLocalX2ApicEnabled();
+BOOLEAN CPULib_IsFeatureControlLocked();
+UINT32 NumberOfCpuSocketsPopulated();
+VOID DisableCacheInCR0();
+VOID EnableCacheInCR0();
+VOID CPULib_DisableInterrupt();
+VOID CPULib_EnableInterrupt();
+BOOLEAN CPULib_GetInterruptState();
+VOID* CPULIB_GetPageTable();
+VOID CPULib_Pause();
+UINT16 GetCsSegment();
+UINT64 ReadRtdsc();
+VOID WaitForever();
+VOID HltCpu();
+VOID WaitForSemaphore(volatile VOID*);
+VOID WaitUntilZero8(volatile VOID*);
+VOID WaitUntilZero32(volatile VOID*);
+UINT16 GetCsSegment();
+UINT32 CPULIB_GetCstateLatency(IN UINT8 Cstate);
+UINT32 CPULIB_GetCstatePower(IN UINT8 Cstate);
+VOID* CPULib_FindMicrocode();
+UINT32 CPULib_GetMicrocodeVer();
+VOID ClearDirectionFlag();
+
+UINT32 SmmGetBaseSaveBufferSize();
+VOID SmmSetupDefaultHandler(IN VOID *SmmBaseSaveBuffer, IN SMM_HOB *SmmHob);
+VOID SmmRemoveDefaultHandler(IN VOID *SmmBaseSaveBuffer);
+VOID SmmBaseChangeOnCpu(VOID *SmmBase);
+
+VOID CPU_GetSaveState (
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState);
+
+VOID CPU_RestoreSaveState(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState);
+
+VOID CPU_SmmMemoryInit(IN SMM_HOB *SmmHob);
+
+typedef struct {
+ UINT8 ClkModEn; //> 0 if Clk Mod En.
+} CPU_LIB_SMM_SAVE_RESTORE_DATA;
+
+VOID CpuLib_SmmSaveCpuState(IN OUT CPU_LIB_SMM_SAVE_RESTORE_DATA*);
+VOID CpuLib_SmmRestoreCpuState(IN CPU_LIB_SMM_SAVE_RESTORE_DATA*);
+
+BOOLEAN IsSwSmiTrigger(UINT8 *SmmBase, UINT16 SwSmiPort);
+
+EFI_STATUS CPULib_SmmReadSaveState(
+ UINT8 *SmmBase,
+ UINT8 *SstSaveState,
+ BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+);
+EFI_STATUS CpuLib_SmmReadSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+);
+EFI_STATUS CPULib_SmmWriteSaveState(
+ UINT8 *SmmBase,
+ UINT8 *SstSaveState,
+ BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT CONST VOID *Buffer
+);
+EFI_STATUS CpuLib_SmmWriteSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS CPUProgramPAMRegisters(
+ EFI_BOOT_SERVICES *gBS, EFI_RUNTIME_SERVICES *gRS,
+ UINT32 StartAddress, UINT32 Length, UINT8 Setting, UINT32 *Granularity
+);
+
+VOID EnableMachineCheck();
+
+VOID CPULib_LockByteInc(UINT8* ptr);
+VOID CPULib_LockByteDec(UINT8* ptr);
+VOID CPULib_LoadGdt(VOID *ptr);
+VOID CPULib_SaveGdt(VOID *ptr);
+VOID CPULib_LoadIdt(VOID *ptr);
+VOID CPULib_SaveIdt(VOID *ptr);
+
+UINT32 MemRead32(UINT32 *Address);
+VOID MemReadWrite32(UINT32 *Address, UINT32 Value, UINT32 Mask);
+
+UINT8 IsPowerCycle();
+BOOLEAN isBCLKRatioSuuported();
+EFI_STATUS GetOcCapability(IN UINT8 DomainID, OUT UINT64 *MsrBuf);
+EFI_STATUS GetSVIDConfig(OUT UINT64 *MsrBuf);
+EFI_STATUS GetVoltFreq(IN UINT8 DomainID, OUT UINT64 *MsrBuf);
+EFI_STATUS GetFIVRConfig(OUT UINT64 *MsrBuf);
+
+
+#ifdef PERF_TUNE_SUPPORT
+#if PERF_TUNE_SUPPORT == 1
+
+#define AMI_OVERCLOCK_CONFIG_HOB_GUID \
+ {0x27a29ef7, 0x90e7, 0x4592, 0x99, 0xbe, 0xa3, 0xae, 0x97, 0xca, 0xdb, 0x2a}
+
+#define AMI_INTERNAL_CPU_RATIO_LIMIT \
+ {0xdf2982fa, 0xaa6c, 0x4b8d, 0x8a, 0x82, 0x85, 0xf8, 0x1e, 0xe8, 0x72, 0x19}
+
+#pragma pack(1)
+//Domain ID define
+#define DOMAIN_MAX_NUM 6
+#define IA 0
+#define GT 1
+#define RING 2
+#define SA 3
+#define IOD 4
+#define IOA 5
+
+typedef struct {
+ UINT8 MaxOcRatioLimit;
+ BOOLEAN RatioOcSupported;
+ BOOLEAN VoltageOverridesSupported;
+ BOOLEAN VoltageOffsetSupported;
+} OC_CAP_ITEM; //overclocking capability
+
+typedef struct {
+ UINT8 MaxOcRatio;
+ BOOLEAN VoltageTargetMode; // 0: Adaptive, 1: Override
+ UINT16 VoltageTarget;
+ INT16 VoltageOffset;
+} VOLT_FREQ_DEF_ITEM;
+
+typedef struct {
+ OC_CAP_ITEM OCCap[DOMAIN_MAX_NUM];
+ VOLT_FREQ_DEF_ITEM VFDef[DOMAIN_MAX_NUM];
+ BOOLEAN SvidDisable; // 0: Disable, 1: Enable
+ UINT16 SvidVoltageOverride; // External VR voltage override
+ BOOLEAN FivrFaultsDisable; // 0: Disable, 1: Enable
+ BOOLEAN FivrEfficiencyDisable; // 0: Disable, 1: Enable
+ BOOLEAN OcSupport;
+ UINT8 IsPowerCycle; // 0: Not power cycle, 1: power cycle
+ UINT8 IsCpuRunDefault; // 0: Not run default, 1: Cpu Change, 2:Watch Dog timeout
+} OVERCLOCKING_CONFIG_DATA;
+
+typedef struct _OVERCLOCKING_CONFIG_HOB {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ OVERCLOCKING_CONFIG_DATA OverclockData;
+} OVERCLOCKING_CONFIG_HOB;
+
+typedef struct {
+ UINT8 MaxNonTurboRatio;
+} CPU_RATIO_LIMIT_DATA;
+
+typedef struct _CPU_RATIO_LIMIT_HOB {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ CPU_RATIO_LIMIT_DATA CpuRatioLimitData;
+ BOOLEAN IsChangeCpu;
+} CPU_RATIO_LIMIT_HOB;
+
+#pragma pack()
+
+#endif //end of #if PERF_TUNE_SUPPORT == 1
+#endif //end of #ifdef PERF_TUNE_SUPPORT == 1
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-20113, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuCspLib.c b/Core/CPU/CpuCspLib.c
new file mode 100644
index 0000000..549d979
--- /dev/null
+++ b/Core/CPU/CpuCspLib.c
@@ -0,0 +1,2461 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuCspLib.c 6 5/22/15 6:07a Crystallee $
+//
+// $Revision: 6 $
+//
+// $Date: 5/22/15 6:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuCspLib.c $
+//
+// 6 5/22/15 6:07a Crystallee
+// [TAG] EIP219394
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Static code analysis issues found in Aptio4 Intel Haswell
+// module
+// [RootCause] Didn't update register content.
+// [Solution] Update register content.
+//
+// 5 8/14/13 4:55a Davidhsieh
+// [TAG] EIP131295
+// [Category] Improvement
+// [Description] Add token to force turbo mode is not supported for i3
+// Cpu
+//
+// 4 2/07/13 3:56a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description] add IsPowerCycle function.
+//
+// 3 11/23/12 2:08a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 2 8/21/12 11:28p Davidhsieh
+// [TAG] None
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] EFI_SMM_CPU_PROTOCOL-> ReadSaveState can't get CR4 value
+// [RootCause] The index for CR4 is incorrect.
+//
+// [Solution] Correct the index value
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuCspLib.c
+//
+// Description:
+// Contains the CPU library related functions. These functions can be linked
+// with various components in the project.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <efi.h>
+#include <token.h>
+#include <AmiDxeLib.h>
+#include <smm.h>
+#include <Pcie.h>
+
+#include "Cpu.h"
+#include "CpuCspLib.h"
+#include "AmiCspLibInc.h"
+
+#ifndef FV_MICROCODE_BASE
+#define FV_MICROCODE_BASE FV_MAIN_BASE
+#endif
+
+#define MAX_NR_BUS ((PCIEX_LENGTH/0x100000)-1)
+
+static EFI_GUID gMicrocodeFfsGuid =
+ {0x17088572, 0x377F, 0x44ef, 0x8F, 0x4E, 0xB0, 0x9F, 0xFF, 0x46, 0xA0, 0x70};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsPowerCycle
+//
+// Description: If Power Cycle is or not.
+//
+// Input:
+// NULL
+//
+// Output:
+// UINT8 , 0 - Not Power Cycle
+// 1 - Power Cycle
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 IsPowerCycle(){
+ //
+ // This is the sample code for Sharkbay with Lynx Point(ver0.7.0 spec.)
+ // Please program properly for your platform
+ //
+ UINT16 Buff16;
+ Buff16 = READ_PCI16_SB(0xA2);
+
+ if (((Buff16 & BIT5) != 0) /*&& ((Buff16 & BIT7) != 0)*/)
+ {
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PchPmTimerStall
+//
+// Description: Delay N*Usec
+//
+// Input: UINTN Usec
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PchPmTimerStall (IN UINTN Usec)
+{
+ UINTN Counter = Usec * 3;
+ UINTN i;
+ UINT32 Data32;
+ UINT32 PrevData;
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData=Data32;
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PollMailboxReady
+//
+// Description: Return OC Mailbox is ready or busy.
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: UINT8 (1: busy, 0: ready)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 PollMailboxReady()
+{
+ UINT64 MsrData;
+ UINT32 WaitTime = 1000;
+
+ do{
+ MsrData = ReadMsr(0x150); //Overclock Mailbox: 0x150
+ if(!(Shr64(MsrData,63) & 0x1)) break;
+ //gStallPpi->Stall(gPeiServices, gStallPpi, 1000); //delay 1ms
+ PchPmTimerStall(1000); //delay 1ms
+ WaitTime--;
+ }while((Shr64(MsrData,63) & 0x1) && WaitTime>0); //check run/busy bit, 1 is busy
+
+ if((Shr64(MsrData,63) & 1) && WaitTime == 0)
+ return 1; //busy
+ else
+ return 0; //ready
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadMSR150
+//
+// Description: Return Msr0x150 data
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadMSR150(OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ UINT64 MsrDataVerify;
+
+ MsrData = ReadMsr(0x150);
+
+ //gStallPpi->Stall(gPeiServices, gStallPpi, 10000); //wait 10ms
+ PchPmTimerStall(10000); //delay 1ms
+
+ MsrDataVerify = ReadMsr(0x150);
+
+ if((UINT32)MsrData != (UINT32)MsrDataVerify) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetOcCapability
+//
+// Description: Get the overclocking capabilities for a given CPU Domain
+// by reading/writing MSR 0x150
+//
+// Input: UINT8 DomainID (0:IA, 1:GT, 2:Ring, 3:SA, 4:IOD, 5:IOA)
+// UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetOcCapability(IN UINT8 DomainID, OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(DomainID,40); //Param1
+ MsrData |= Shl64(0x01,32); //Command, Overclocking Capability
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSVIDConfig
+//
+// Description: Get the SVID Configuration information
+// by reading/writing MSR 0x150
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetSVIDConfig(OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(0,40); //Param1, 0 = IVR input
+ MsrData |= Shl64(0x12,32); //Command, Read SVID Config
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetVoltFreq
+//
+// Description: Gets the Voltage and Frequency information for a given CPU domain
+// by reading/writing MSR 0x150
+//
+// Input: UINT8 DomainID (0:IA, 1:GT, 2:Ring)
+// UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetVoltFreq(IN UINT8 DomainID, OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(DomainID,40); //Param1, 0 = IVR input
+ MsrData |= Shl64(0x10,32); //Command, Read Voltage/Frequency
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFIVRConfig
+//
+// Description: Get the FIVR Configuration information
+// by reading/writing MSR 0x150
+//
+// Input: UINT64 *MsrBuf
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFIVRConfig(OUT UINT64 *MsrBuf)
+{
+ UINT64 MsrData;
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ MsrData = 0;
+ MsrData |= Shl64(0x0,40); //Param1
+ MsrData |= Shl64(0x14,32); //Command, Read Misc Global Config
+ MsrData |= Shl64(0x01,63); //run/busy bit
+
+ WriteMsr(0x150,MsrData); //Overclock Mailbox: 0x150
+
+ if(PollMailboxReady()) return EFI_DEVICE_ERROR;
+
+ if(ReadMSR150(&MsrData)) return EFI_DEVICE_ERROR;
+
+ *MsrBuf = MsrData;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isBCLKRatioSuuported
+//
+// Description: Determine if CPU supports BCLK coarse ratio support.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isBCLKRatioSuuported()
+{
+ UINT32 PciAddress;
+
+// PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x0) << 11) | ((0x0) << 8) | 0xE4;
+ PciAddress = (0x1) << 31 | 0xE4;
+ IoWrite32(0x0cf8,PciAddress);
+ if ( IoRead32(0x0cfc) & BIT18 ){
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuSignature
+//
+// Description: Get the cpu signature.
+//
+// Input: VOID
+//
+// Output: Cpu Signature
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetCpuSignature()
+{
+ UINT32 CpuSignature, CpuIdEBX, CpuIdECX, CpuIdEDX;
+ CPULib_CpuID(1, &CpuSignature, &CpuIdEBX, &CpuIdECX, &CpuIdEDX);
+ return CpuSignature;
+}
+
+typedef struct {
+ UINT32 Stepping:4;
+ UINT32 Model:4;
+ UINT32 Family:4;
+ UINT32 Type:2;
+ UINT32 RV:2;
+ UINT32 ExtModel:4;
+ UINT32 ExtFamily:8;
+} CPU_SIGNATURE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuFamily
+//
+// Description: Get the cpu family from signature.
+//
+// Input: UINT32 CpuSignature
+//
+// Output: UINT32 - Cpu Family
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetCpuFamily(UINT32 CpuSignature)
+{
+ CPU_SIGNATURE *Signature = (CPU_SIGNATURE*)&CpuSignature;
+ return Signature->ExtFamily + Signature->Family;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuModel
+//
+// Description: Get the cpu model from signature.
+//
+// Input: UINT32 CpuSignature
+//
+// Output: UINT32 - Cpu Model
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetCpuModel(UINT32 CpuSignature)
+{
+ CPU_SIGNATURE *Signature = (CPU_SIGNATURE*)&CpuSignature;
+ return (Signature->ExtModel << 4) + Signature->Model;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuPlatformId
+//
+// Description: Get the cpu platform Id.
+//
+// Input: VOID
+//
+// Output: Cpu Platform Id
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetCpuPlatformId(VOID)
+{
+ return (UINT32)Shr64(ReadMsr(0x17), 50) & 7;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmrrBaseMsr
+//
+// Description: Return the Smrr Base Msr
+//
+// Input: VOID
+//
+// Output: SMRR Base
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetSmrrBaseMsr()
+{
+ return 0x1f2;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadWriteMsr
+//
+// Description: This function writes the CPU MSR with the value provided.
+//
+// Input:
+// Msr 32bit MSR index
+// Value 64bit OR Value
+// Mask 64Bit AND Mask Value
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ReadWriteMsr(UINT32 Msr, UINT64 Value, UINT64 Mask)
+{
+ UINT64 OrigData = ReadMsr(Msr);
+ UINT64 WriteData = (OrigData & Mask) | Value;
+ WriteMsr(Msr, WriteData);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumSupportedThreadsPerCore
+//
+// Description: Get number of supported threads per core.
+//
+// Input: VOID
+//
+// Output: UINT8 Number of Threads per core.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumSupportedThreadsPerCore()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ RegEcx = 0;
+ CPULib_CpuID(0xb, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ return (UINT8)RegEbx;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumSupportedCpuCores
+//
+// Description: Get number of supported Cpu Cores per package.
+//
+// Input: VOID
+//
+// Output: UINT8 Number of supported Cpu Cores per package.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumSupportedCpuCores()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 TotLogicalCpus;
+ UINT8 LogicalCpusPerCore;
+
+ RegEcx = 1;
+ CPULib_CpuID(0xb, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ TotLogicalCpus = (UINT8)RegEbx;
+
+ RegEcx = 0;
+ CPULib_CpuID(0xb, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ LogicalCpusPerCore = (UINT8)RegEbx;
+
+ return TotLogicalCpus / LogicalCpusPerCore;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumLogicalCpus
+//
+// Description: Get number of logical CPUs.
+//
+// Input: VOID
+//
+// Output: UINT8 Number of logical CPUs.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumLogicalCpus()
+{
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ return (UINT8)MsrData;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsHtEnabled
+//
+// Description: Determine if CPU is HT.
+//
+// Input: VOID
+//
+// Output: True if HT CPU.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsHtEnabled()
+{
+ UINT8 NumLogCPUs, NumCpuCores;
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ UINT32 CpuSignature = GetCpuSignature() & 0xfffffff0;
+
+ NumCpuCores = (UINT8)((UINT32)MsrData >> 16);
+
+ // Westmere work around
+ if (CpuSignature == WESTMERE) NumCpuCores &= 0xf;
+
+ NumLogCPUs = (UINT8)MsrData;
+
+ if ((NumLogCPUs / NumCpuCores) <= 1) return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumCpuCores
+//
+// Description: Returns number of CPU Cores
+//
+// Input: VOID
+//
+// Output: Number of CPU Cores.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumCpuCores()
+{
+ UINT32 CpuSignature = GetCpuSignature() & 0xfffffff0;
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ UINT8 NumCpuCores = (UINT8)((UINT32)MsrData >> 16);
+
+ // Westmere work around
+ if (CpuSignature == WESTMERE) NumCpuCores &= 0xf;
+
+ return NumCpuCores;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsHt0
+//
+// Description: Determine if CPU thread is logical CPU 0 executing.
+//
+// Input: VOID
+//
+// Output: True if logical CPU 0.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsHt0()
+{
+ UINT32 ApicMask;
+ UINT32 ApicId;
+ UINT8 ThreadsPerCore = NumSupportedThreadsPerCore();
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ if (ThreadsPerCore < 2) return TRUE; //Check if Ht Capable.
+ ApicMask = ThreadsPerCore - 1;
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ ApicId = RegEbx >> 24;
+
+ //Use APIC ID to determine if logical CPU.
+ if ((ApicId & ApicMask) == 0) return TRUE; //All logical CPU0 will have bit 0 clear.
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsCore0
+//
+// Description: Determine if CPU thread is CPU Core 0 executing.
+//
+// Input: VOID
+//
+// Output: True if logical CPU 0.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsCore0()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 MaxThreadsPackage;
+ UINT32 ApicMask;
+ UINT32 ApicId;
+
+ ApicMask = ~(NumSupportedThreadsPerCore() - 1);
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ MaxThreadsPackage = (UINT8)(RegEbx >> 16);
+
+ ApicMask &= MaxThreadsPackage - 1;
+ ApicId = RegEbx >> 24;
+
+ //Use APIC ID to determine if logical CPU.
+ if ((ApicId & ApicMask) == 0) return TRUE;
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsX64Supported
+//
+// Description: Determine if CPU supports X64.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsX64Supported(CPU_FEATURES *Features)
+{
+ return ((Features->ExtFeatureEdx) >> 29) & 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isXDSupported
+//
+// Description: Determine if CPU supports Execute Disable.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN isXDSupported(CPU_FEATURES *Features)
+{
+ return !!(Features->ExtFeatureEdx & (1 << 20));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isTurboModeSupported
+//
+// Description: Determine if CPU supports Turbo mode.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isTurboModeSupported()
+{
+ BOOLEAN ret;
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ UINT64 MsrData = ReadMsr(MSR_IA32_MISC_ENABLE);
+
+#if defined(I3_CPU_NON_TURBO) && (I3_CPU_NON_TURBO == 1)
+{
+ CHAR8 BrandStrBuff[49];
+ CHAR8 *BrandString = BrandStrBuff;
+
+ CPULib_CpuID(0x80000002, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ *(UINT32*)BrandString = RegEax; BrandString +=4;
+ *(UINT32*)BrandString = RegEbx; BrandString +=4;
+ *(UINT32*)BrandString = RegEcx; BrandString +=4;
+ *(UINT32*)BrandString = RegEdx; BrandString +=4;
+
+
+ CPULib_CpuID(0x80000003, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ *(UINT32*)BrandString = RegEax; BrandString +=4;
+ *(UINT32*)BrandString = RegEbx; BrandString +=4;
+ *(UINT32*)BrandString = RegEcx; BrandString +=4;
+ *(UINT32*)BrandString = RegEdx; BrandString +=4;
+
+ CPULib_CpuID(0x80000004, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ *(UINT32*)BrandString = RegEax; BrandString +=4;
+ *(UINT32*)BrandString = RegEbx; BrandString +=4;
+ *(UINT32*)BrandString = RegEcx; BrandString +=4;
+ *(UINT32*)BrandString = RegEdx; BrandString +=4;
+ *BrandString = '\0';
+
+ BrandString = BrandStrBuff;
+
+ while(*BrandString) {
+ if (MemCmp(BrandString, "i3", 2) == 0) return FALSE;
+ ++BrandString;
+ }
+}
+#endif
+ CPULib_CpuID(6, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ ret = ((RegEax >> 1) & 1) | (UINT32) (Shr64(MsrData,TURBO_MODE_DISABLE_BIT) & 1);
+ return ret;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isFullUnlockCpuSuuported
+//
+// Description: Determine if CPU supports Full unlock.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isFullUnlockCpuSuuported()
+{
+ UINT64 MsrData = ReadMsr(MSR_FLEX_RATIO);
+
+ if((UINT32)(Shr64(MsrData, 17)) == 0x7) return TRUE;
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isXETdcTdpLimitSupported
+//
+// Description: Determine if CPU supports Programmable TDC/TDP Limit for the Turbo mode.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN isXETdcTdpLimitSupported()
+{
+
+ BOOLEAN ret;
+ UINT64 MsrData = ReadMsr(MSR_PLATFORM_INFO);
+ ret = (UINT32) (MsrData & (1 << XE_TDP_TDC_PROGRAMMABLE_BIT)) ? 1:0;
+ return ret;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isXECoreRatioLimitSupported
+//
+// Description: Determine if CPU supports Programmable Core Ratio Limit for the Turbo mode.
+//
+// Input: None
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+ BOOLEAN isXECoreRatioLimitSupported()
+ {
+
+ BOOLEAN ret;
+ UINT64 MsrData = ReadMsr(MSR_PLATFORM_INFO);
+ ret = (UINT32) (MsrData & (1 << XE_CORE_RATIO_PROGRAMMABLE_BIT)) ? 1:0;
+ return ret;
+ }
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isLimitCpuidSupported
+//
+// Description: Determine if CPU supports limiting CpuId to 3.
+//
+// Input: VOID
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN isLimitCpuidSupported()
+{
+ UINT32 RegEbx, RegEcx, RegEdx;
+ UINT32 LargestCPUIDFunc;
+ CPULib_CpuID(0, &LargestCPUIDFunc, &RegEbx, &RegEcx, &RegEdx);
+ return LargestCPUIDFunc > 3;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isMachineCheckSupported
+//
+// Description: Determine if CPU supports machine check.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsMachineCheckSupported(CPU_FEATURES *Features)
+{
+ //Check if MCE and MCA supported.
+ return ((Features->FeatureEdx & ((1 << 7) + (1 << 14))) == ((1 << 7) + (1 << 14)));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsVmxSupported
+//
+// Description: Determine if CPU supports VT extensions Vmx.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if Vmx supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsVmxSupported(CPU_FEATURES *Features)
+{
+ return Features->FeatureEcx & (1 << 5);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSmxSupported
+//
+// Description: Determine if CPU supports VT extensions Smx.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if Smx supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSmxSupported(CPU_FEATURES *Features)
+{
+ return Features->FeatureEcx & (1 << 6);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_IsSmrrSupported
+//
+// Description: Determine if CPU supports Smrr.
+//
+// Input: CPU_FEATURES *Features
+//
+// Output: True if Smx supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSmrrSupported(CPU_FEATURES *Features)
+{
+ return (BOOLEAN)Features->Flags.SmrrSupport;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsEnergyPerfBiasSupported
+//
+// Description: Determine if Energy Performance Bias supported.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if Energy Performance Bias supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+// BOOLEAN IsEnergyPerfBiasSupported()
+// {
+// UINT32 RegEax;
+// UINT32 RegEbx;
+// UINT32 RegEcx;
+// UINT32 RegEdx;
+//
+// UINT32 CpuSignature = GetCpuSignature();
+// UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+// UINT32 CpuVer = CpuSignature & 0xf;
+//
+// BOOLEAN Support = FALSE;
+//
+// //This is also used to control setup question. No recommendation in BWG.
+// //Thus, for now Sandy Bridge Energy Bias Support is coded separately from previous CPUs.
+// //if (CpuSigNoVer == SANDY_BRIDGE && CpuVer >= 3)
+// // return TRUE;
+//
+// if (CpuSigNoVer == NEHALEM_EX && CpuVer >= 5) Support = TRUE;
+// else if (CpuSigNoVer == WESTMERE) Support = TRUE;
+// else if (CpuSigNoVer == WESTMERE_EX) Support = TRUE;
+//
+// if (!Support) return FALSE;
+// ReadWriteMsr(MSR_MISC_PWR_MGMT, (1 << ENG_PERF_BIAS_EN_BIT), (UINT64)-1); //Energy Performance Bias Enable
+//
+// CPULib_CpuID(6, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+// return !!(RegEcx & BIT3);
+// }
+//
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsCxInterruptFilteringSupported
+//
+// Description: Determine if C-state interrupting state supported.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if C-state interrupting supported.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+// BOOLEAN IsCxInterruptFilteringSupported()
+// {
+// return FALSE;
+//
+// //Not supported until this is used on a project that can test this functionality.
+// //DEBUG UINT32 CpuSignature = GetCpuSignature();
+// //DEBUG if (CpuSignature != 0x00020652) return FALSE;
+// //DEBUG if ((INT32)Shr64(ReadMsr(MSR_IA32_BIOS_SIGN_ID), 32) < 3) return FALSE;
+// //DEBUG return TRUE;
+// }
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsVmxEnabled
+//
+// Description: Determine if Vmx is enabled.
+//
+// Input: VOID
+//
+// Output: True if Vmx enabled.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsVmxEnabled()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 Msr;
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if (!(RegEcx & (1 << 5))) return FALSE;
+
+ Msr = (UINT8)ReadMsr(MSR_IA32_FEATURE_CONTROL);
+ return !!(Msr & (1 << 2));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsSmxEnabled
+//
+// Description: Determine if Smx is enabled.
+//
+// Input: VOID
+//
+// Output: True if Smx enabled.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsSmxEnabled()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 Msr;
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if (!(RegEcx & BIT6)) return FALSE;
+
+ Msr = (UINT8)ReadMsr(MSR_IA32_FEATURE_CONTROL);
+ return !!(Msr & BIT1);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsSmrrEnabled
+//
+// Description: Determine if Smrr is enabled.
+//
+// Input: BOOLEAN
+//
+// Output: True if Smrr is enabled.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsSmrrEnabled()
+{
+ //Once SMRR is enabled, the opened SMM Area can't be read outside of SMM.
+#if SMM_CACHE_SUPPORT == 0
+ return FALSE;
+#else
+ //Some CPUs, SMRR has an enable bit. Nehalem only has a capability bit.
+ UINT32 MtrrCap = (UINT32)ReadMsr(MSR_IA32_MTRR_CAP);
+ return !!(MtrrCap & SMRR_SUPPORT_MASK);
+#endif
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULIB_IsLocalX2ApicEnabled
+//
+// Description: Get C-state latency.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if enabled
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CPULib_IsLocalX2ApicEnabled()
+{
+ UINT32 Msr = (UINT32)ReadMsr(MSR_XAPIC_BASE);
+ return !!(Msr & (1 << XAPIC_X2APIC_ENABLE_BIT));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_IsFeatureControlLocked
+//
+// Description: Check to see if the MSR_IA32_FEATURE_CONTROL is locked.
+//
+// Input: VOID
+//
+// Output: BOOLEAN - True if MSR_IA32_FEATURE_CONTROL is locked.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CPULib_IsFeatureControlLocked() {
+ UINT8 Ia32FeatureCntrl = (UINT8)ReadMsr(MSR_IA32_FEATURE_CONTROL);
+ return Ia32FeatureCntrl & 1;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumberOfCpuSocketsPopulated
+//
+// Description: Returns number of CPU sockets are populated.
+//
+// Input: VOID
+//
+// Output: UINT32 - Number of CPU sockets populated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 NumberOfCpuSocketsPopulated()
+{
+#if NUMBER_CPU_SOCKETS > 1
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ UINT32 NumCpuSockets = 0;
+ UINT32 i;
+ UINT32 BusNum;
+
+ //Sandy Bridge Server.
+ if (CpuSigNoVer == JAKETOWN) {
+ UINT32 *PciAddress = (UINT32*)PCIE_CFG_ADDR(0, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#if NUMBER_CPU_SOCKETS >= 4
+ PciAddress = (UINT32*)PCIE_CFG_ADDR(0x40, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#endif
+ PciAddress = (UINT32*)PCIE_CFG_ADDR(0x80, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#if NUMBER_CPU_SOCKETS >= 4
+ PciAddress = (UINT32*)PCIE_CFG_ADDR(0xc0, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+#endif
+ return NumCpuSockets;
+ }
+ for (i = 0, BusNum = MAX_NR_BUS; i < NUMBER_CPU_SOCKETS; ++i, --BusNum) {
+ UINT32 *PciAddress = (UINT32*)PCIE_CFG_ADDR(BusNum, 0, 0, 0);
+ if (*PciAddress != 0xffffffff) ++NumCpuSockets;
+ }
+ return NumCpuSockets;
+#else
+ return 1;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULIB_GetCstateLatency
+//
+// Description: Get C-state latency.
+//
+// Input: IN UINT8 Cstate
+//
+// Output: UINT32 - C-state latentcy in uS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CPULIB_GetCstateLatency(IN UINT8 Cstate)
+{
+ UINT32 CpuSigNoVer = GetCpuSignature() & 0xfffffff0;
+ BOOLEAN IsSandyBridge = CpuSigNoVer == SANDY_BRIDGE || CpuSigNoVer == JAKETOWN || CpuSigNoVer == IVY_BRIDGE;
+
+ if (IsSandyBridge) {
+ switch(Cstate) {
+ case 1: return 1;
+ case 3: return 80;
+ case 6: return 104;
+ case 7: return 109;
+ }
+ }
+
+ switch(Cstate) {
+ case 1: return 3;
+ case 3: return 205;
+ case 6: return 245;
+ case 7: return 245;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULIB_GetCstatePower
+//
+// Description: Get C-state power.
+//
+// Input: IN UINT8 Cstate
+//
+// Output: UINT32 - C-state power in mW.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CPULIB_GetCstatePower(IN UINT8 Cstate)
+{
+ switch(Cstate) {
+ case 1: return 1000;
+ case 3: return 500;
+ case 6: return 350;
+ case 7: return 200;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_FindMicrocodeInFv
+//
+// Description: Find the microcode address for the CPU calling this in specific firmware volume.
+//
+// Input: VOID *Fv -- Firmware Volume
+//
+// Output: VOID * -- 0 if not found or the Microcode Address.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * CPULib_FindMicrocodeInFv(VOID *Fv)
+{
+ UINT8 *pEndOfFv = (UINT8*)Fv + ((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->FvLength - 1;
+ UINT8 *pFfs = (UINT8*)Fv + ((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->HeaderLength;
+ UINT8 *pEndOfFfs;
+ UINT32 FfsSize;
+
+ MICROCODE_HEADER *pUc;
+ UINT32 UcSize;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT8 CpuFlags = (UINT8)(Shr64(ReadMsr(0x17), 50)) & 7;
+ UINT8 UcFlag = 1 << CpuFlags;
+
+ //Check for corrupt firmware volume.
+ if (((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->Signature != 'HVF_') return 0;
+ if (pEndOfFv <= pFfs) return 0;
+
+ while(TRUE) {
+ if (*(UINT32*)pFfs == 0xffffffff) return 0;
+ if (pFfs >= pEndOfFv) return 0;
+
+ FfsSize = *(UINT32*)&((EFI_FFS_FILE_HEADER*)pFfs)->Size & 0xffffff;
+
+ //Find Microcode file
+ if (guidcmp(&((EFI_FFS_FILE_HEADER*)pFfs)->Name, &gMicrocodeFfsGuid) == 0)
+ break;
+ if ((pFfs + FfsSize) <= pFfs) return 0; //Corruption?
+ pFfs += FfsSize; //Next file.
+ pFfs = (UINT8*)(((UINT32)pFfs + 7) & ~7); //Align on 8 byte boundary.
+ }
+
+ pEndOfFfs = pFfs + FfsSize;
+#if MPDTable_CREATED
+ pEndOfFfs -= *(UINT16*)(pEndOfFfs - 2); //Last 2 bytes is MPDT Length. Don't look in the MPDT for uC.
+#endif
+
+ //Find Microcode
+ pUc = (MICROCODE_HEADER*)(pFfs + sizeof(EFI_FFS_FILE_HEADER));
+
+ while(TRUE) {
+ if (pUc->HeaderVersion != 1) return 0; //End of microcode or corrupt.
+ UcSize = pUc->DataSize ? pUc->TotalSize : 2048;
+
+ if (pUc->CpuSignature == CpuSignature && (pUc->Flags & UcFlag))
+ break;
+
+ if (pUc->TotalSize > (pUc->DataSize + 48)) { //Extended signature count.
+ MICROCODE_EXT_PROC_SIG_TABLE *SigTable = (MICROCODE_EXT_PROC_SIG_TABLE*)((UINT8*)pUc + pUc->DataSize + 48);
+ UINT32 ExtSigCount = SigTable->Count;
+ UINT8 i;
+
+ if (ExtSigCount >= 20) return 0; //Corrupt microcode.
+
+ for (i = 0; i < ExtSigCount; ++i) {
+ if (SigTable->ProcSig[i].CpuSignature == CpuSignature && (SigTable->ProcSig[i].Flags & UcFlag)) break;
+ }
+ }
+
+#if PACK_MICROCODE
+ UcSize = (UcSize + (16 - 1)) & ~(16 - 1);
+#else
+ UcSize = (UcSize + (MICROCODE_BLOCK_SIZE - 1)) & ~(MICROCODE_BLOCK_SIZE - 1);
+#endif
+ if (((UINT64)(UINTN)pUc + UcSize) >= (UINT64)(UINTN)pEndOfFfs) return 0; //End of uc or corrupt
+
+ pUc = (MICROCODE_HEADER*)((UINT8*)pUc + UcSize);
+ }
+ return pUc;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_FindMicrocode
+//
+// Description: Find the microcode address for the CPU calling this.
+//
+// Input: VOID
+//
+// Output: VOID * -- 0 if not found or the Microcode Address.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * CPULib_FindMicrocode()
+{
+ VOID *Microcode;
+#if MICROCODE_SPLIT_BB_UPDATE
+ Microcode = CPULib_FindMicrocodeInFv((VOID*)FV_MICROCODE_UPDATE_BASE);
+ if (Microcode == NULL) Microcode = CPULib_FindMicrocodeInFv((VOID*)FV_MICROCODE_BASE);
+#else
+ Microcode = CPULib_FindMicrocodeInFv((VOID*)FV_MICROCODE_BASE);
+#endif
+ return Microcode;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_GetMicrocodeVer
+//
+// Description: Get Microcode Version
+//
+// Input: VOID
+//
+// Output: UINT32 - Microcode Version
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CPULib_GetMicrocodeVer()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ //Clear IA32_BIOS_SIGN_ID of microcode loaded.
+ WriteMsr(MSR_IA32_BIOS_SIGN_ID, 0);
+
+ //Reading CPU ID 1, updates the MSR to the microcode revision.
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ return (UINT32)Shr64(ReadMsr(MSR_IA32_BIOS_SIGN_ID), 32);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmBaseChangeCopy
+//
+// Description: This is SMM code copied to 3000:8000 to set the SmmBase and IED.
+//
+// Input: None
+//
+// Output: None
+//
+// Notes:
+// This is in real mode. To generate 16-bit code opcodes, use a small asm
+// file to generate a listing.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//TODO: Move this array into assembly file. It is getting too big.
+UINT8 SmmBaseChangeCopy[] =
+{ //cs = 0x3000
+ 0x66, 0xb8, 0x00, 0x00, 0x00, 0x00, //0x8000 mov eax, SMM_BASE
+ 0xbb, 0x00, 0x00, //0x8006 mov bx, 0 ;Location SM BASE OFFSET
+ 0x66, 0x2e, 0x89, 0x07, //0x8009 mov cs:[bx], eax
+
+ 0x66, 0xbb, 0x01, 0x00, 0x00, 0x00, //0x800d mov ebx, 1
+ 0x67, 0x66, 0x89, 0x98, 4,0x80,0,0, //0x8013 mov [eax + 8004h], ebx ;Set SMM initialization
+ 0x66, 0xb8, 0xff, 0xff, 0xff, 0xff, //0x801b mov eax, IED_BASE
+ 0xbb, 0x00, 0x00, //0x8021 mov bx, 0 ;Location of IED_SAVESTATE_OFFSET
+ 0x66, 0x2e, 0x89, 0x07, //0x8024 mov cs:[bx], eax
+
+ 0xbb, 0x00, 0x00, //0x8028 mov bx, 0
+ 0x0b, 0xdb, //0x802b or bx, bx
+ 0x75, 0x32, //0x802d jnz FirstIedInit
+
+ 0x66, 0x89, 0xc3, //0x802f mov ebx, eax
+ 0x66, 0x8b, 0xf8, //0x8032 mov edi, eax
+ 0x66, 0x81, 0xc7, 0x0, 0, 0x10, 0, //0x8035 add edi, 0x10 0000
+ 0x66, 0xb9, 0x00, 0x20, 0x00, 0x00, //0x803c mov ecx, 32 * 1024 /4
+ 0x66, 0x33, 0xc0, //0x8042 xor eax, eax
+//@@:
+ 0x66, 0x67, 0xab, //0x8045 stosd //clear IED 32k
+ 0x67, 0xe2, 0xfa, //0x8048 loop @b
+
+ 0x66, 0x89, 0xdf, //0x804b mov edi, ebx
+ 0x66, 0x81, 0xc7, 0x0, 0, 0x20, 0, //0x804e add edi, 0x20 0000
+ 0x66, 0xb9, 0x00, 0x00, 0x08, 0x00, //0x8055 mov ecx, 0x200000 / 4
+//@@:
+ 0x66, 0x67, 0xab, //0x805b stosd //clear IED 2MB
+ 0x67, 0xe2, 0xfa, //0x805e loop @b
+
+//FirstIedInit:
+
+ 0xeb, 0x24, //0x8061 jmp NO_SMRR ;If SMRR, this will be changed to NOPs.
+//SMRR:
+ 0x66, 0xb9, 0x00, 0x00, 0x00, 0x00, //0x8063 mov ecx, 0 ;MSR_SMRR_PHYS_BASE will be updated after copy.
+ 0x66, 0xb8, 0x00, 0x00, 0x00, 0x00, //0x8069 mov eax, 0 ;This will be updated after copy.
+ 0x66, 0xba, 0x00, 0x00, 0x00, 0x00, //0x806f mov edx, 0 ;This will be updated after copy.
+ 0x0f, 0x30, //0x8075 wrmsr
+ 0x66, 0x41, //0x8077 inc ecx ;MSR_SMRR_PHYS_MASK
+ 0x66, 0xb8, 0x00, 0x00, 0x00, 0x00, //0x8079 mov eax, 0 ;This will be updated after copy.
+ 0x66, 0xba, 0x00, 0x00, 0x00, 0x00, //0x807f mov edx, 0 ;This will be updated after copy.
+ 0x0f, 0x30, //0x8085 wrmsr
+//NO_SMRR:
+ 0xb0, 0x01, //0x8087 mov al, 1
+ 0x2e, 0xa2, 0x8f, 0x80, //0x8089 mov cs:[0x8076], al ;set flag
+ 0x0f, 0xaa, //0x808d rsm
+ 0x00 //0x808f SmmBaseChangeFlag label byte
+};
+
+#define SMM_ASM_FIXUP_SMM_BASE 0x38002
+#define SMM_ASM_FIXUP_SMM_BASE_SAVESTATE_OFFSET 0x38007
+#define SMM_ASM_FIXUP_IED_BASE 0x3801d
+#define SMM_ASM_FIXUP_IED_SAVESTATE_OFFSET 0x38022
+#define SMM_ASM_FIXUP_IED_ZERO_MEM 0x38029
+#define SMM_ASM_FIXUP_USE_SMRR 0x38061
+#define SMM_ASM_FIXUP_MSR_SMRR_BASE 0x38065
+#define SMM_ASM_FIXUP_SMRR_BASE_EAX 0x3806b
+#define SMM_ASM_FIXUP_SMRR_BASE_EDX 0x38071
+#define SMM_ASM_FIXUP_SMRR_MASK_EAX 0x3807b
+#define SMM_ASM_FIXUP_SMRR_MASK_EDX 0x38081
+#define SMM_ASM_BASE_CHANGE_FLAG 0x3808f
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmGetBaseSaveBufferSize
+//
+// Description: Return about of memory required for the SMM handler change.
+//
+// Input: VOID
+//
+// Output:
+// UINT32 Amount of memory required for SMM handler change.
+//
+// Notes:
+// The memory will need to be allocated to use in SmmSetupDefaultHandler.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 SmmGetBaseSaveBufferSize()
+{
+ return sizeof(SmmBaseChangeCopy) + MAX_SMM_SAVE_STATE_SIZE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmSetupDefaultHandler
+//
+// Description: Save original memory, and copy SMM default handler.
+//
+// Input:
+// IN VOID *SmmBaseSaveBuffer
+// IN SMM_HOB *SmmHob
+//
+// Output:
+// VOID
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmSetupDefaultHandler(IN VOID *SmmBaseSaveBuffer, IN SMM_HOB *SmmHob)
+{
+ //Perserve 3000:8000 used by SMM. It will be overwritten.
+ MemCpy(SmmBaseSaveBuffer, (VOID*)0x38000, sizeof(SmmBaseChangeCopy));
+
+ MemCpy((UINT8*)SmmBaseSaveBuffer + sizeof(SmmBaseChangeCopy), (UINT8*)0x40000 - MAX_SMM_SAVE_STATE_SIZE, MAX_SMM_SAVE_STATE_SIZE);
+ MemCpy((VOID*)0x38000, SmmBaseChangeCopy, sizeof(SmmBaseChangeCopy));
+
+ *(UINT16*)SMM_ASM_FIXUP_SMM_BASE_SAVESTATE_OFFSET = SMM_BASE_SAVE_STATE_OFFSET;
+ *(UINT16*)SMM_ASM_FIXUP_IED_SAVESTATE_OFFSET = IED_SAVESTATE_OFFSET;
+ *(UINT32*)SMM_ASM_FIXUP_IED_BASE = SmmHob->IedStart; //IED Start
+
+ //Initialize SMRR
+ if(CPULib_IsSmrrEnabled()) { //Could be disabled. Reset may not clear lock.
+ UINT64 TsegMask = (0xfffffffff & (~(SmmHob->TsegLength - 1))) | (1 << 11);
+ *(UINT16*)SMM_ASM_FIXUP_USE_SMRR = 0x9090; //Jmp changed to NOPs.
+ //Update SMRR MSR.
+ *(UINT32*)SMM_ASM_FIXUP_MSR_SMRR_BASE = GetSmrrBaseMsr();
+ //Update SMRR Base
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_BASE_EAX = (UINT32)SmmHob->Tseg | 6; //Lower 32-bits. 6 = WB.
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_BASE_EDX = 0; //Upper 32-bits.
+ //Update SMRR Mask
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_MASK_EAX = (UINT32)TsegMask; //Lower 32-bits.
+ *(UINT32*)SMM_ASM_FIXUP_SMRR_MASK_EDX = 0; //Upper 32-bits. SMRR Mask Reserved bits.
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmBaseChangeOnCpu
+//
+// Description: Execute on each CPU to change its own base.
+//
+// Input:
+// VOID *SmmBase
+//
+// Output:
+// VOID
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmBaseChangeOnCpu(IN VOID *SmmBase)
+{
+ *(UINT32*)SMM_ASM_FIXUP_SMM_BASE = (UINT32)SmmBase;
+ *(UINT8*)SMM_ASM_BASE_CHANGE_FLAG = 0; //Initialize Flag
+
+ //Send SMM IPI
+ if (CPULib_IsLocalX2ApicEnabled()) {
+ UINT32 ApicId = (UINT32) ReadMsr(MSR_EXT_XAPIC_LOGICAL_APIC_ID);
+ ReadWriteMsr(MSR_EXT_XAPIC_ICR,
+ Shl64(ApicId, 32) + APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI,
+ 0xfff32000
+ );
+ } else {
+ UINT8 ApicId = (UINT8)(*(UINT32*)(LOCAL_APIC_BASE + APIC_ID_REGISTER) >> 24);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER), ApicId << 24, 0x00ffffff);
+ MemReadWrite32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER), APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI, 0);
+ }
+
+ while (!(*(volatile UINT8*)SMM_ASM_BASE_CHANGE_FLAG)) CPULib_Pause(); //Wait on Flag
+ ++*(UINT16*)SMM_ASM_FIXUP_IED_ZERO_MEM; //Only 0, for first thread to clear IED memory.
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmRemoveDefaultHandler
+//
+// Description: Remove default SMM Handler from memory and restore original data.
+//
+// Input:
+// IN VOID *SmmBaseSaveBuffer
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmRemoveDefaultHandler(IN VOID *SmmBaseSaveBuffer)
+{
+ //Restore 3000:8000 overwritten for SMM
+ MemCpy((VOID*)0x38000, SmmBaseSaveBuffer, sizeof(SmmBaseChangeCopy));
+ MemCpy((UINT8*)0x40000 - MAX_SMM_SAVE_STATE_SIZE, (UINT8*)SmmBaseSaveBuffer + sizeof(SmmBaseChangeCopy), MAX_SMM_SAVE_STATE_SIZE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPUProgramPAMRegisters
+//
+// Description: Program 0xc0000 - 0xfffff regions to Lock/Unlock.
+//
+// Input:
+// UINT32 StartAddress
+// UINT32 Length
+// UINT8 Setting
+// UINT32 *Granularity
+//
+// Output: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CPUProgramPAMRegisters(
+ EFI_BOOT_SERVICES *gBS,
+ EFI_RUNTIME_SERVICES *gRS,
+ UINT32 StartAddress,
+ UINT32 Length,
+ UINT8 Setting,
+ UINT32 *Granularity
+)
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SaveCpuState
+//
+// Description: Save CPU state in SMM.
+//
+// Input:
+// IN OUT CPU_LIB_SMM_SAVE_RESTORE_DATA *State - Track CPU state.
+//
+// Output: VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuLib_SmmSaveCpuState(IN OUT CPU_LIB_SMM_SAVE_RESTORE_DATA* State)
+{
+ UINT64 ClkMod = ReadMsr(MSR_IA32_CLOCK_MODULATION);
+
+ State->ClkModEn = (UINT8)ClkMod & CLK_MOD_ENABLE;
+ ClkMod &= ~(UINT64)CLK_MOD_ENABLE;
+ WriteMsr(MSR_IA32_CLOCK_MODULATION, ClkMod);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SmmRestoreCpuState
+//
+// Description: Restore CPU state in SMM.
+//
+// Input:
+// IN CPU_LIB_SMM_SAVE_RESTORE_DATA *State - Track CPU state.
+//
+// Output: VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuLib_SmmRestoreCpuState(IN CPU_LIB_SMM_SAVE_RESTORE_DATA* State)
+{
+ if (State->ClkModEn) ReadWriteMsr(MSR_IA32_CLOCK_MODULATION, CLK_MOD_ENABLE, (UINT64)-1);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_GetSaveStateId30006
+//
+// Description:
+// This routines saves the necessary values from Revison 3006
+// SMM save state area.
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CPU_GetSaveStateId30006(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState,
+ UINT32 SmmRevision
+)
+{
+ SstSaveState->SMBASE = *(UINT32*)(SmmBase + 0xfef8);
+ SstSaveState->SMMRevId = *(UINT32*)(SmmBase + 0xfefc);
+#if (((CORE_MAJOR_VERSION << 16) + (CORE_MINOR_VERSION << 8) + CORE_REVISION) > 0x040603)
+ SstSaveState->GDTBase = *(UINT32*)(SmmBase + 0xfe8c);
+ SstSaveState->IDTBase = *(UINT32*)(SmmBase + 0xfe94);
+ SstSaveState->CR4 = *(UINT32*)(SmmBase + 0xfe40);
+#endif
+ SstSaveState->ES = *(UINT16*)(SmmBase + 0xffa8);
+ SstSaveState->CS = *(UINT16*)(SmmBase + 0xffac);
+ SstSaveState->SS = *(UINT16*)(SmmBase + 0xffb0);
+ SstSaveState->DS = *(UINT16*)(SmmBase + 0xffb4);
+ SstSaveState->FS = *(UINT16*)(SmmBase + 0xffb8);
+ SstSaveState->GS = *(UINT16*)(SmmBase + 0xffbc);
+ SstSaveState->LDTBase = *(UINT32*)(SmmBase + 0xfe9c);
+ SstSaveState->TR = *(UINT32*)(SmmBase + 0xffc4);
+ SstSaveState->DR7 = *(UINT32*)(SmmBase + 0xffc8);
+ SstSaveState->DR6 = *(UINT32*)(SmmBase + 0xffd0);
+ SstSaveState->EAX = *(UINT32*)(SmmBase + 0xff5c);
+ SstSaveState->ECX = *(UINT32*)(SmmBase + 0xff64);
+ SstSaveState->EDX = *(UINT32*)(SmmBase + 0xff6c);
+ SstSaveState->EBX = *(UINT32*)(SmmBase + 0xff74);
+ SstSaveState->ESP = *(UINT32*)(SmmBase + 0xff7c);
+ SstSaveState->EBP = *(UINT32*)(SmmBase + 0xff84);
+ SstSaveState->ESI = *(UINT32*)(SmmBase + 0xff8c);
+ SstSaveState->EDI = *(UINT32*)(SmmBase + 0xff94);
+ SstSaveState->EIP = *(UINT32*)(SmmBase + 0xffd8);
+ SstSaveState->EFLAGS = *(UINT32*)(SmmBase + 0xffe8);
+ SstSaveState->CR3 = *(UINT32*)(SmmBase + 0xfff0);
+ SstSaveState->CR0 = *(UINT32*)(SmmBase + 0xfff8);
+
+ if (SmmRevision < 0x30100) {
+ SstSaveState->IORestart = *(UINT16*)(SmmBase + 0xff02);
+ SstSaveState->AutoHALTRestart = *(UINT16*)(SmmBase + 0xff00);
+ } else {
+ SstSaveState->AutoHALTRestart = *(UINT16*)(SmmBase + 0xff02);
+ SstSaveState->IORestart = *(UINT16*)(SmmBase + 0xff00);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_RestoreSaveStateId30006
+//
+// Description:
+// This routines restores the necessary values from Revision 3006
+// SMM save state area.
+//
+// Input:
+// SmmBase Pointer to SMM save state
+// SstSaveState Standard SMM save state
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CPU_RestoreSaveStateId30006(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState,
+ UINT32 SmmRevision
+)
+{
+ *(UINT16*)(SmmBase + 0xffa8) = SstSaveState->ES;
+ *(UINT16*)(SmmBase + 0xffac) = SstSaveState->CS;
+ *(UINT16*)(SmmBase + 0xffb0) = SstSaveState->SS;
+ *(UINT16*)(SmmBase + 0xffb4) = SstSaveState->DS;
+ *(UINT16*)(SmmBase + 0xffb8) = SstSaveState->FS;
+ *(UINT16*)(SmmBase + 0xffbc) = SstSaveState->GS;
+ *(UINT32*)(SmmBase + 0xff5c) = SstSaveState->EAX;
+ *(UINT32*)(SmmBase + 0xff64) = SstSaveState->ECX;
+ *(UINT32*)(SmmBase + 0xff6c) = SstSaveState->EDX;
+ *(UINT32*)(SmmBase + 0xff74) = SstSaveState->EBX;
+ *(UINT32*)(SmmBase + 0xff7c) = SstSaveState->ESP;
+ *(UINT32*)(SmmBase + 0xff84) = SstSaveState->EBP;
+ *(UINT32*)(SmmBase + 0xff8c) = SstSaveState->ESI;
+ *(UINT32*)(SmmBase + 0xff94) = SstSaveState->EDI;
+ *(UINT32*)(SmmBase + 0xffd8) = SstSaveState->EIP;
+ *(UINT32*)(SmmBase + 0xffe8) = SstSaveState->EFLAGS;
+
+ if (SmmRevision < 0x30100) {
+ *(UINT16*)(SmmBase + 0xff02) = SstSaveState->IORestart;
+ *(UINT16*)(SmmBase + 0xff00) = SstSaveState->AutoHALTRestart;
+ } else {
+ *(UINT16*)(SmmBase + 0xff02) = SstSaveState->AutoHALTRestart;
+ *(UINT16*)(SmmBase + 0xff00) = SstSaveState->IORestart;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_RestoreDefaultSaveState
+//
+// Description:
+// This routines copies the necessary values from standard
+// SMM save state area to version 0x30003 SMM save state area.
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CPU_RestoreDefaultSaveState
+(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState
+)
+{
+ EFI_SMI_CPU_SAVE_STATE *SmmSave = (EFI_SMI_CPU_SAVE_STATE*) SmmBase;
+
+ SmmSave->EFLAGS = SstSaveState->EFLAGS;
+ SmmSave->EIP = SstSaveState->EIP;
+ SmmSave->EDI = SstSaveState->EDI;
+ SmmSave->ESI = SstSaveState->ESI;
+ SmmSave->EBP = SstSaveState->EBP;
+ SmmSave->ESP = SstSaveState->ESP;
+ SmmSave->EBX = SstSaveState->EBX;
+ SmmSave->EDX = SstSaveState->EDX;
+ SmmSave->ECX = SstSaveState->ECX;
+ SmmSave->EAX = SstSaveState->EAX;
+ SmmSave->AutoHALTRestart = SstSaveState->AutoHALTRestart;
+ SmmSave->IORestart = SstSaveState->IORestart;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_GetSaveState
+//
+// Description:
+// This routine is the generic routine used to copy the CPU specific SMM
+// save state to standard save state.
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CPU_GetSaveState
+(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState
+)
+{
+ UINT32 SmmRevision = *(UINT32*)(SmmBase + 0xfefc);
+
+ //Porting Required. PERFORM CPU SPECIFIC save state handling
+ if (SmmRevision >= 0x30006) {
+ CPU_GetSaveStateId30006(SmmBase, SstSaveState, SmmRevision);
+ } else {
+ UINTN Index;
+ //Copy save state area.
+ for (Index = 0;
+ Index < (sizeof(EFI_SMI_CPU_SAVE_STATE) / sizeof(UINT32));
+ Index ++) {
+ *( ((UINT32 *)SstSaveState) + Index)
+ = *( (UINT32 *)(SmmBase + 0xfe00) + Index);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPU_RestoreSaveState
+//
+// Description:
+// This routine is the generic routine used to copy the standard
+// SMM save state from CPU specific save state. This routine
+// should make sure it does not change read only areas
+//
+// Input:
+// SmmBase Pointer to CPU SMM save state.
+// SstSaveState Pointer to copied SMM save state
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CPU_RestoreSaveState
+(
+ UINT8 *SmmBase,
+ EFI_SMI_CPU_SAVE_STATE *SstSaveState
+)
+{
+ UINT32 SmmRevision = *(UINT32*)(SmmBase + 0xfefc);
+
+ //Porting Required. PERFORM CPU SPECIFIC save state handling
+ if (SmmRevision >= 0x30006) {
+ CPU_RestoreSaveStateId30006(SmmBase, SstSaveState, SmmRevision);
+ } else {
+ CPU_RestoreDefaultSaveState(SmmBase + 0xfe00, SstSaveState);
+ }
+}
+
+typedef struct {
+ UINT16 SaveStateOffset;
+ UINT16 SaveStateWidth;
+ UINT16 FrameworkOffset;
+ UINT16 FrameworkWidth;
+} INTEL_X64_FORMAT;
+
+INTEL_X64_FORMAT gIntelX64Format[] = {
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_GDTBASE = 4
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_IDTBASE = 5
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_LDTBASE = 6
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_GDTLIMIT = 7 No Save State
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_IDTLIMIT = 8 No Save State
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_LDTLIMIT = 9 No Save State
+ //Treat special case - EFI_SMM_SAVE_STATE_REGISTER_LDTINFO = 10 No Save State
+ 0xffa8, 2, 0x01a8, 2, //EFI_SMM_SAVE_STATE_REGISTER_ES = 20
+ 0xffac, 2, 0x01ac, 2, //EFI_SMM_SAVE_STATE_REGISTER_CS = 21
+ 0xffb0, 2, 0x01b0, 2, //EFI_SMM_SAVE_STATE_REGISTER_SS = 22
+ 0xffb4, 2, 0x01b4, 2, //EFI_SMM_SAVE_STATE_REGISTER_DS = 23
+ 0xffb8, 2, 0x01b8, 2, //EFI_SMM_SAVE_STATE_REGISTER_FS = 24
+ 0xffbc, 2, 0x01bc, 2, //EFI_SMM_SAVE_STATE_REGISTER_GS = 25
+ 0xffc0, 2, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_LDTR_SEL = 26
+ 0xffc4, 2, 0x01c4, 2, //EFI_SMM_SAVE_STATE_REGISTER_TR_SEL = 27
+ 0xffc8, 8, 0x01c8, 4, //EFI_SMM_SAVE_STATE_REGISTER_DR7 = 28
+ 0xffd0, 8, 0x01fc, 4, //EFI_SMM_SAVE_STATE_REGISTER_DR6 = 29
+ 0xff54, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R8 = 30
+ 0xff4c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R9 = 31
+ 0xff44, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R10 = 32
+ 0xff3c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R11 = 33
+ 0xff34, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R12 = 34
+ 0xff2c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R13 = 35
+ 0xff24, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R14 = 36
+ 0xff1c, 8, 0xffff, 0xff, //EFI_SMM_SAVE_STATE_REGISTER_R15 = 37
+ 0xff5c, 8, 0x01d0, 4, //EFI_SMM_SAVE_STATE_REGISTER_RAX = 38
+ 0xff74, 8, 0x01dc, 4, //EFI_SMM_SAVE_STATE_REGISTER_RBX = 39
+ 0xff64, 8, 0x01d4, 4, //EFI_SMM_SAVE_STATE_REGISTER_RCX = 40
+ 0xff6c, 8, 0x01d8, 4, //EFI_SMM_SAVE_STATE_REGISTER_RDX = 41
+ 0xff64, 8, 0x01e0, 4, //EFI_SMM_SAVE_STATE_REGISTER_RSP = 42
+ 0xff84, 8, 0x01e4, 4, //EFI_SMM_SAVE_STATE_REGISTER_RBP = 43
+ 0xff8c, 8, 0x01e8, 4, //EFI_SMM_SAVE_STATE_REGISTER_RSI = 44
+ 0xff94, 8, 0x01ec, 4, //EFI_SMM_SAVE_STATE_REGISTER_RDI = 45
+ 0xffd8, 8, 0x01f0, 4, //EFI_SMM_SAVE_STATE_REGISTER_RIP = 46
+ 0xffe8, 8, 0x01f4, 4, //EFI_SMM_SAVE_STATE_REGISTER_RFLAGS = 51
+ 0xfff8, 8, 0x01fc, 4, //EFI_SMM_SAVE_STATE_REGISTER_CR0 = 52
+ 0xfff0, 8, 0x01f8, 4, //EFI_SMM_SAVE_STATE_REGISTER_CR3 = 53
+ 0xfe40, 8, 0x00f0, 4, //EFI_SMM_SAVE_STATE_REGISTER_CR4 = 54
+
+ //Supported in XMM Save/restore function
+ //EFI_SMM_SAVE_STATE_REGISTER_FCW = 256
+ //EFI_SMM_SAVE_STATE_REGISTER_FSW = 257
+ //EFI_SMM_SAVE_STATE_REGISTER_FTW = 258
+ //EFI_SMM_SAVE_STATE_REGISTER_OPCODE = 259
+ //EFI_SMM_SAVE_STATE_REGISTER_FP_EIP = 260
+ //EFI_SMM_SAVE_STATE_REGISTER_FP_CS = 261
+ //EFI_SMM_SAVE_STATE_REGISTER_DATAOFFSET = 262
+ //EFI_SMM_SAVE_STATE_REGISTER_FP_DS = 263
+ //EFI_SMM_SAVE_STATE_REGISTER_MM0 = 264
+ //EFI_SMM_SAVE_STATE_REGISTER_MM1 = 265
+ //EFI_SMM_SAVE_STATE_REGISTER_MM2 = 266
+ //EFI_SMM_SAVE_STATE_REGISTER_MM3 = 267
+ //EFI_SMM_SAVE_STATE_REGISTER_MM4 = 268
+ //EFI_SMM_SAVE_STATE_REGISTER_MM5 = 269
+ //EFI_SMM_SAVE_STATE_REGISTER_MM6 = 270
+ //EFI_SMM_SAVE_STATE_REGISTER_MM7 = 271
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM0 = 272
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM1 = 273
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM2 = 274
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM3 = 275
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM4 = 276
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM5 = 277
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM6 = 278
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM7 = 279
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM8 = 280
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM9 = 281
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM10 = 282
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM11 = 283
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM12 = 284
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM13 = 285
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM14 = 286
+ //EFI_SMM_SAVE_STATE_REGISTER_XMM15 = 287
+ //
+ // Pseudo-Registers
+ //
+ //EFI_SMM_SAVE_STATE_REGISTER_IO = 512
+ //EFI_SMM_SAVE_STATE_REGISTER_LMA = 513
+};
+
+typedef enum {
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT8 = 0,
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT16 = 1,
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT32 = 2,
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH_UINT64 = 3
+} CPULIB_SMM_SAVE_STATE_IO_WIDTH;
+
+typedef enum {
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_INPUT = 1,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_OUTPUT = 2,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_STRING = 4,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX = 8
+} CPULIB_SMM_SAVE_STATE_IO_TYPE;
+
+typedef struct {
+ UINT64 IoData;
+ UINT16 IoPort;
+ CPULIB_SMM_SAVE_STATE_IO_WIDTH IoWidth;
+ CPULIB_SMM_SAVE_STATE_IO_TYPE IoType;
+} CPULIB_SMM_SAVE_STATE_IO_INFO;
+
+UINT8 IOTypeToEMSSIT[] = {
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_OUTPUT,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_INPUT,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_STRING,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_STRING,
+ 0,
+ 0,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_REP_PREFIX,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_OUTPUT,
+ CPULIB_SMM_SAVE_STATE_IO_TYPE_INPUT
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_SmmReadSaveState
+//
+// Description: Read SMM Save state from combination of SMM save state and copy.
+// If frame copy exists, use its data instead from actual save state.
+// A different function gets information for floating point and XMM.
+//
+// Input:
+// IN UINT8 *SmmBase - SmmBase of CPU to read Save State.
+// IN UINT8 *SstSaveState - SMM Save state copy for Framework.
+// IN BOOLEAN UseSstSaveState - True if Save state copy exists.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// OUT VOID *Buffer - Read register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CPULib_SmmReadSaveState(
+ IN UINT8 *SmmBase,
+ IN UINT8 *SstSaveState,
+ IN BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+)
+{
+ UINT32 Index = 0xffffffff;
+ UINTN Offset;
+
+ if (Register >= 20 && Register <= 46) Index = Register - 20;
+ if (Register >= 51 && Register <= 54) Index = Register - 20 - (51-47);
+
+ if (Index != 0xffffffff) {
+ if (Width > gIntelX64Format[Index].SaveStateWidth) return EFI_INVALID_PARAMETER;
+ switch(Width) {
+ case 1:
+ //Use SMM framework buffer if available, because copy may be updated by Framework driver, and copy will overwrite actual save state at end.
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT8*)Buffer = *(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ else *(UINT8*)Buffer = *(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ return EFI_SUCCESS;
+ case 2:
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT16*)Buffer = *(UINT16*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ else *(UINT16*)Buffer = *(UINT16*)(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ return EFI_SUCCESS;
+ case 4:
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ else *(UINT32*)Buffer = *(UINT32*)(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ return EFI_SUCCESS;
+ case 8:
+ *(UINT64*)Buffer = *(UINT64*)(SmmBase + gIntelX64Format[Index].SaveStateOffset);
+ //Use copy if available, because copy may be updated by Framework driver, and copy will overwrite actual save state at end. Copy doesn't support upper bits.
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset);
+ return EFI_SUCCESS;
+ }
+ }
+ if (Register == 4) { //GDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *((UINT32*)Buffer + 1) = *(UINT32*)(SmmBase + 0xffd0);
+ //Use copy for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + 0x188);
+ return EFI_SUCCESS;
+ }
+ if (Register == 5) { //IDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *((UINT32*)Buffer + 1) = *(UINT32*)(SmmBase + 0xfdd8);
+ //Use copy for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + 0x194);
+ return EFI_SUCCESS;
+ }
+ if (Register == 6) { //LDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *((UINT32*)Buffer + 1) = *(UINT32*)(SmmBase + 0xfdd4);
+ //Use copy for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)Buffer = *(UINT32*)(SstSaveState + 0x1c0);
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 513) {
+ UINT16 Efer;
+ if (Width != 1) return EFI_INVALID_PARAMETER;
+ Efer = *(UINT16*)(SmmBase + 0xffe0);
+ *(UINT8*)Buffer = (Efer & BIT10) == BIT10 ? 64 : 32;
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 512) {
+ UINT32 IoMisc = *(UINT32*)(SmmBase + 0xffa4);
+ UINT8 Width = 0;
+
+ if (!(IoMisc & 1)) return EFI_NOT_FOUND;
+
+ switch((IoMisc >> 1) & 7) {
+ case 1: Width = 0; break;
+ case 2: Width = 1; break;
+ case 3: Width = 2; break;
+ default: return EFI_NOT_FOUND;
+ };
+
+ //Get the I/O address.
+ switch ((IoMisc >> 4) & 0xF) {
+ case 0:
+ case 1:
+ case 8:
+ case 9:
+ Offset = 0xff5c; //Reg RAX has the value
+ break;
+ case 2:
+ case 3:
+ case 6:
+ case 7:
+ Offset = 0xff9c; //IO_MEM_ADDRESS has the value
+ break;
+ default:
+ return EFI_NOT_FOUND;
+ }
+
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoPort = (UINT16)(IoMisc >> 16);
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoWidth = Width;
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoType = IOTypeToEMSSIT[(IoMisc >> 4) & 0xf];
+
+ switch (Width) {
+ case 0:
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoData = *(UINT8 *)(SmmBase + Offset);
+ break;
+ case 1:
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoData = *(UINT16 *)(SmmBase + Offset);
+ break;
+ case 2:
+ ((CPULIB_SMM_SAVE_STATE_IO_INFO*)Buffer)->IoData = *(UINT32 *)(SmmBase + Offset);
+ break;
+ default:
+ return EFI_NOT_FOUND;
+ }
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED; //Register not supported.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SmmReadSaveStateFxSave
+//
+// Description: Read SMM Save state for floating point and XMM.
+//
+// Input:
+// IN UINT8 *FxSave - FxSave buffer.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// OUT VOID *Buffer - Read register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuLib_SmmReadSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ OUT VOID *Buffer
+)
+{
+ if (Register == 256) { //FCW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)FxSave;
+ return EFI_SUCCESS;
+ }
+ if (Register == 257) { //FSW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 2);
+ return EFI_SUCCESS;
+ }
+ if (Register == 258) { //FTW
+ if (Width != 1) return EFI_INVALID_PARAMETER;
+ *(UINT8*)Buffer = *(UINT8*)(FxSave + 4);
+ return EFI_SUCCESS;
+ }
+ if (Register == 259) { //FOP
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 6);
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 260) { //FPU IP
+ if (Width == 4) {
+ MemCpy(Buffer, FxSave + 8, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(Buffer, FxSave + 8, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 261) { //CS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 12);
+ }
+#endif
+
+ if (Register == 262) { //FPU DP (DataOffset)
+ if (Width == 4) {
+ MemCpy(Buffer, FxSave + 16, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(Buffer, FxSave + 16, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 263) { //DS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)Buffer = *(UINT16*)(FxSave + 20);
+ }
+#endif
+
+ if (Register >= 264 && Register <= 271) { //MM0 - MM7
+ if (Width != 10) return EFI_INVALID_PARAMETER;
+ MemCpy(Buffer, FxSave + 32 + 16 * (Register - 264), 10);
+ return EFI_SUCCESS;
+ }
+ if (Register >= 272 && Register <= 287) { //XMM0 - XMM15
+ if (Width != 16) return EFI_INVALID_PARAMETER;
+ MemCpy(Buffer, FxSave + 160 + 16 * (Register - 272), 16);
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CPULib_SmmWriteSaveState
+//
+// Description: Write SMM Save state from combination of SMM save state and copy.
+// If frame copy exists, use its data instead from actual save state.
+// A different function gets information for floating point and XMM.
+//
+// Input:
+// IN UINT8 *SmmBase - SmmBase of CPU to read Save State.
+// IN UINT8 *SstSaveState - SMM Save state copy for Framework.
+// IN BOOLEAN UseSstSaveState - True if Save state copy exists.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// IN VOID *Buffer - Write register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CPULib_SmmWriteSaveState(
+ IN OUT UINT8 *SmmBase,
+ IN OUT UINT8 *SstSaveState,
+ IN BOOLEAN UseSstSaveState,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ IN VOID *Buffer
+)
+{
+ UINT32 Index = 0xffffffff;
+
+ if (Register >= 20 && Register <= 46) Index = Register - 20;
+ if (Register >= 51 && Register <= 54) Index = Register - 20 - (51-47); //No tokens assigned 47-50.
+
+ if (Index != 0xffffffff) {
+ if (Width > gIntelX64Format[Index].SaveStateWidth) return EFI_INVALID_PARAMETER;
+ switch(Width) {
+ case 1:
+ *(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT8*)Buffer;
+ //Copy to save state buffer for SMM framework.
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT8*)Buffer;
+ return EFI_SUCCESS;
+ case 2:
+ *(UINT16*)(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT16*)Buffer;
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT16*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ case 4:
+ *(UINT32*)(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT32*)Buffer;
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ case 8:
+ *(UINT64*)(SmmBase + gIntelX64Format[Index].SaveStateOffset) = *(UINT64*)Buffer;
+ if (UseSstSaveState && gIntelX64Format[Index].FrameworkWidth != 0xff) *(UINT32*)(SstSaveState + gIntelX64Format[Index].FrameworkOffset) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ }
+ if (Register == 4) { //GDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *(UINT32*)(SmmBase + 0xffd0) = *((UINT32*)Buffer + 1);
+ *(UINT32*)(SmmBase + 0xfe8c) = *(UINT32*)Buffer;
+ //Copy to framework buffer for lower 32-bits
+ if (UseSstSaveState) *(UINT32*)(SstSaveState + 0x188) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 5) { //IDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *(UINT32*)(SmmBase + 0xfdd8) = *((UINT32*)Buffer + 1);
+ *(UINT32*)(SmmBase + 0xfe94) = *(UINT32*)Buffer;
+ if (UseSstSaveState) *(UINT32*)(SstSaveState + 0x194) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 6) { //LDT
+ if (Width != 4 && Width != 8) return EFI_INVALID_PARAMETER;
+ if (Width == 8) *(UINT32*)(SmmBase + 0xfdd4) = *((UINT32*)Buffer + 1);
+ *(UINT32*)(SmmBase + 0xfe9c) = *(UINT32*)Buffer;
+ if (UseSstSaveState) *(UINT32*)(SstSaveState + 0x1c0) = *(UINT32*)Buffer;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuLib_SmmWriteSaveStateFxSave
+//
+// Description: Write SMM Save state for floating point and XMM.
+//
+// Input:
+// IN UINT8 *FxSave - FxSave buffer.
+// IN UINT8 Width - Width in Bytes of register.
+// IN UINT32 Register - Register Token in PI SMM.
+// IN VOID *Buffer - Write register into this buffer.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuLib_SmmWriteSaveStateFxSave(
+ IN UINT8 *FxSave,
+ IN UINT8 Width,
+ IN UINT32 Register,
+ IN VOID *Buffer
+)
+{
+ if (Register == 256) { //FCW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)FxSave = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 257) { //FSW
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 2) = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 258) { //FTW
+ if (Width != 1) return EFI_INVALID_PARAMETER;
+ *(UINT8*)(FxSave + 4) = *(UINT8*)Buffer;
+ return EFI_SUCCESS;
+ }
+ if (Register == 259) { //FOP
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 6) = *(UINT16*)Buffer;
+ return EFI_SUCCESS;
+ }
+
+ if (Register == 260) { //FPU IP
+ if (Width == 4) {
+ MemCpy(FxSave + 8, Buffer, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(FxSave + 8, Buffer, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 261) { //CS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 12) = *(UINT16*)Buffer;
+ }
+#endif
+
+ if (Register == 262) { //FPU DP (DataOffset)
+ if (Width == 4) {
+ MemCpy(FxSave + 16, Buffer, 4);
+ return EFI_SUCCESS;
+ }
+#if x64_BUILD
+ if (Width == 8) {
+ MemCpy(FxSave + 16, Buffer, 8);
+ return EFI_SUCCESS;
+ }
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if x64_BUILD == 0
+ if (Register == 263) { //DS
+ if (Width != 2) return EFI_INVALID_PARAMETER;
+ *(UINT16*)(FxSave + 20) = *(UINT16*)Buffer ;
+ }
+#endif
+
+ if (Register >= 264 && Register <= 271) { //MM0 - MM7
+ if (Width != 10) return EFI_INVALID_PARAMETER;
+ MemCpy(FxSave + 32 + 16 * (Register - 264), Buffer, 10);
+ return EFI_SUCCESS;
+ }
+ if (Register >= 272 && Register <= 287) { //XMM0 - XMM15
+ if (Width != 16) return EFI_INVALID_PARAMETER;
+ MemCpy(FxSave + 160 + 16 * (Register - 272), Buffer, 16);
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+static UINT8 CpuIedSig[] = {'I','N','T','E','L',' ','R','S','V','D'};
+
+VOID CPU_SmmMemoryInit(IN SMM_HOB *SmmHob)
+{
+ UINT8 *IedStart;
+ UINT32 IedSize;
+
+ if (!SmmHob->IedStart) return;
+
+ IedStart = (UINT8*)SmmHob->IedStart;
+ IedSize = SmmHob->IedSize;
+
+ MemCpy(IedStart, CpuIedSig, sizeof(CpuIedSig));
+ *(UINT32*)(IedStart + 10) = IedSize;
+
+ *(UINT16*)(IedStart + 14) = 0; //Reserved
+ *(UINT64*)(IedStart + 16) = 0; //Trace memory for Nehalem-EX.
+
+ MemSet(IedStart + 24, 24, 0); //Reserved
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSwSmiTrigger
+//
+// Description: This routine checks to see if the cpu caused an software smi.
+//
+// Input:
+// UINT8 *SmmBase
+// UINT16 SwSmiPort
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSwSmiTrigger(UINT8 *SmmBase, UINT16 SwSmiPort)
+{
+ UINT32 IO_MISC_INFO = *(UINT32*)(SmmBase + 0xffa4);
+ if (!(IO_MISC_INFO & 1)) return FALSE; //For valid data, this should be 1.
+ return (*((UINT16*)&IO_MISC_INFO + 1) == SwSmiPort); //[31:16]
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+
diff --git a/Core/CPU/CpuDxe.c b/Core/CPU/CpuDxe.c
new file mode 100644
index 0000000..9bd4f52
--- /dev/null
+++ b/Core/CPU/CpuDxe.c
@@ -0,0 +1,2096 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.c 21 6/11/15 10:33p Crystallee $
+//
+// $Revision: 21 $
+//
+// $Date: 6/11/15 10:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.c $
+//
+// 21 6/11/15 10:33p Crystallee
+// [TAG] EIP207854
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Txt test fail with TCG2 module
+// [RootCause] Tokne TCG_SUPPORT was removed.
+// [Solution] Add TCG2Support token.
+//
+// 20 5/24/15 11:36p Davidhsieh
+// [TAG] EIP215675
+// [Category] New Feature
+// [Description] Smm Access Check feautre support
+// [Files] Cpu.sdl, CpuDxe.c, CpuSpSmi.sdl, CpuSpsmi.c
+//
+// 19 8/28/13 6:00a Crystallee
+// [TAG] EIP134339
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] [Sharkbay]Build error after update Haswell Cpu module
+// [RootCause] If token TCG_SUPPORT is disabled, TpmSupport setup data
+// will not define, then cause built error.
+// [Solution] Add token TCG_SUPPORT condition when use TpmSupport setup
+// data.
+//
+// 18 7/23/13 7:45a Crystallee
+// [TAG] EIP128089
+// [Category] Improvement
+// [Description] TXT will be disabled and grayed out in Setup when TPM
+// Support is disabled.
+//
+// 17 3/20/13 2:49a Crystallee
+// [TAG] EIP118478
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AES-NI setup item disappear after set ASN-NI to disable.
+// [RootCause] We determine AES support from the ASE support bit in
+// CPUID function 1, but it will change with AES MSR.
+// [Solution] Determine AES support before CPU RC DXE initialize.
+//
+// 16 2/27/13 5:00a Crystallee
+// [TAG] EIP115822
+// [Category] Improvement
+// [Description] Add SMBIOS type7 information for L4 cache if CPU
+// supported
+// And create a token to control this.
+//
+// 15 2/22/13 2:07a Crystallee
+// [TAG] EIP112238
+// [Category] Improvement
+// [Description] Refer Intel BIOS and provide setup items for Intel
+// Haswell RC policy.
+//
+// 14 12/18/12 7:09a Davidhsieh
+// [TAG] EIP93180
+// [Category] Improvement
+// [Description] Do not create timer callback to clear
+// direction flag, clear direction flag operation is in interrupt entry.
+//
+// 13 11/23/12 4:19a Davidhsieh
+// [TAG] None
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Ctdp setup item is not displayed in setup menu
+// [RootCause] The cTDPAvailable value is not initialzied
+// [Solution] Initial cTDPAvailable value
+//
+// 12 11/08/12 6:18a Davidhsieh
+// [TAG] EIP105401
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] CpuSignature and FeatureFlags of MPS table are incorrect
+// [RootCause] Cpu Signature and FeatureFlags in CpuInfo are
+// not initialized
+// [Solution] Initialize Cpu Signature and FeatureFlags in
+// CpuInfo
+//
+// 11 11/07/12 4:36a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] L4 Cache support improve
+//
+// 10 10/17/12 2:20a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Setup items CTDP BIOS, C8, C9 and C10 created
+//
+// 9 10/17/12 1:58a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] L4 cache support
+//
+// 8 9/26/12 10:53a Davidhsieh
+// [TAG] None
+// [Description] Add CPU APIC ID data variable for S3 resume
+//
+// 7 7/10/12 2:48a Davidhsieh
+// [TAG] EIP93180
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The "Event Kernel-Power 137" error event log shows while
+// resumed from HS3/S3 in Windows8 (not-UEFI boot mode)
+// [RootCause] The save MTRRs action is too early, the saved value is
+// differnet from the value in OS
+// [Solution] Move the MTRR save action to AMI_LEGACYBOOT event
+//
+// 6 5/20/12 11:38p Davidhsieh
+// [TAG] EIP89382
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hangs when booting to UEFI Red Hat Linux OS with
+// Network cable plugged in
+// [RootCause] Red Hat Linux OS sets ¡§Direction Flag¡¨ and clears it
+// immediately after few instructions. But before it has been cleared,
+// Timer interrupt has been generated and MemSet () has function has been
+// called inside UEFINetworkStack Timer callback handler. As the
+// "Direction flag" is set ¡§MemSet¡¨ function stores data in reverse
+// direction which results in data corruption.
+// [Solution] Timer Callback function has been created with Higher
+// priority level (TPL_NOTIFY + 14) and "direction flag" has been cleared
+// inside the callback function.
+//
+// 5 5/17/12 9:34p Davidhsieh
+// [TAG] EIP89591
+// [Category] Improvement
+// [Description] Make the CPU wakup buffer locatioin depends on token
+// PMM_EBDA_LOMEM_SIZE
+//
+// 4 3/20/12 3:22a Davidhsieh
+// Create SMBIOS type4 and type7 in AMI CPU module part
+//
+// 3 3/16/12 3:11a Davidhsieh
+// Setup items create for CPU RC policy
+//
+// 2 2/23/12 2:06a Davidhsieh
+// [TAG] EIP72056
+// [Category] Improvement
+// [Description] Change EFI_MP_PROC_CONTEXT to follow Intel CPU driver
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuDxe.c
+//
+// Description:
+// Installs CPU Architectural Protocol.
+// processor interrupt vector table. The CPU Architectural
+// Protocol enables/disables/get state of interrupts, set
+// memory range cache type, and installs/uninstalls
+// interrupt handlers.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <token.h>
+#include <AmiCspLib.h>
+#include <Protocol\AmiCpuInfo.h>
+#include <Protocol\DxeSmmReadyToLock.h>
+#include "CpuDxe.h"
+#include "PlatformCpuLib.h"
+
+#ifdef CSM_SUPPORT
+#include <Protocol\LegacyBiosExt.h>
+EFI_GUID gAmiLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+#endif
+
+#if AMI_PEI_DEBUG_SUPPORT
+#include "PeiDbgDxeCpuLib.h"
+
+#define AMI_DEBUGGER_CPU_PROTOCOL_GUID \
+ { 0xab21acc3, 0xba33, 0xee2c, 0x66, 0xbc, 0x12, 0x56, 0x77, 0x11, 0x1a, 0xb2 }
+
+typedef struct _AMI_DEBUGGER_CPU_PROTOCOL AMI_DEBUGGER_CPU_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_GET_APTIO_INT_HANDLER) (
+ IN OUT UINT32* InterruptHandlerHaltAddr
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_FIXUP_PEI_EXCEPTION_HANDLER) (
+ IN IDTEntry_T* IdtEntry,
+ IN UINT32 i
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_SETUP_EXCEPTION_HANDLER) (VOID);
+
+typedef
+EFI_STATUS
+(EFIAPI *DEBUGGER_IS_DEBUGGER_IRQ_HANDLER) (
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
+ );
+
+typedef struct _AMI_DEBUGGER_CPU_PROTOCOL {
+ DEBUGGER_GET_APTIO_INT_HANDLER DebuggerGetAptioIntHandler;
+ DEBUGGER_FIXUP_PEI_EXCEPTION_HANDLER DebuggerFixUpPEIExceptionHandlers;
+ DEBUGGER_SETUP_EXCEPTION_HANDLER DebuggerSetupExceptionHandler;
+ DEBUGGER_IS_DEBUGGER_IRQ_HANDLER DebuggerIsDebuggerIrqHadler;
+};
+
+
+#endif
+
+#define DELAY_CALCULATE_CPU_PERIOD 200 //uS
+
+#if CPU_MODULE_CREATE_SMBIOS_TABLES == 1
+VOID CpuSmbios();
+#endif
+
+#define AMI_BEFORE_CPU_RC_PROTOCOL_GUID \
+ { 0x1d26adc3, 0xb011, 0xee2c, 0x21, 0x77, 0x89, 0xbb, 0xaa, 0xcc, 0x33, 0x92 }
+
+// Add EFI_MP_PROC_CONTEXT_FROM_RC relavant structures
+typedef struct {
+ UINT32 ApicID;
+ BOOLEAN Enabled;
+ EFI_CPU_DESIGNATION Designation;
+ EFI_MP_HEALTH Health;
+ UINTN PackageNumber;
+ UINTN NumberOfCores;
+ UINTN NumberOfThreads;
+ UINT64 ProcessorPALCompatibilityFlags;
+ UINT64 ProcessorTestMask;
+} EFI_MP_PROC_CONTEXT_FROM_RC;
+
+UINT32 *FindPtrToPrivCpuInfoPkg(
+ IN UINT32 Package
+);
+
+EFI_GUID gHobListGuid = HOB_LIST_GUID;
+EFI_GUID gEfiMpServicesProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+EFI_GUID gAmiCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID;
+EFI_GUID gAmiCpuInfoProtocolGuid = AMI_CPU_INFO_PROTOCOL_GUID;
+EFI_GUID gAmiCpuInfo2ProtocolGuid = AMI_CPU_INFO_2_PROTOCOL_GUID;
+EFI_GUID gAmiBeforeCpuRcProtocolGuid = AMI_BEFORE_CPU_RC_PROTOCOL_GUID;
+EFI_GUID gMpCpuApicIdDataGuid = MP_CPU_APIC_ID_DATA_GUID;
+#if AMI_PEI_DEBUG_SUPPORT
+EFI_GUID gAmiDebuggerCpuProtocolGuid = AMI_DEBUGGER_CPU_PROTOCOL_GUID;
+#endif
+EFI_MP_SERVICES_PROTOCOL *gEfiMpServicesProtocol;
+EFI_MP_PROC_CONTEXT_FROM_RC *gEfiMpProcContext;
+
+UINTN gNumOfCpus;
+UINTN gMaximumNumberOfCPUs;
+UINTN gNumberOfEnabledCPUs;
+UINTN gRendezvousIntNumber;
+UINTN gRendezvousProcLength;
+
+UINT32 gNumOfCpuCores;
+UINT32 gNumOfThreads;
+
+UINT32 gRegEax, gRegEbx, gRegEcx, gRegEdx;
+
+EFI_EVENT gAmiMpEvent;
+VOID *gAmiMpEventRegistration = 0;
+
+EFI_EVENT gSmmFeaEnEvent;
+VOID *gSmmFeaEnReg = 0;
+
+static VOID *gAcpiData;
+static UINT32 gAcpiDataNumEntries;
+
+static CHAR8 gProcObjPath = '\0';
+
+CPUINFO_HOB *gCpuInfoHob;
+AMI_CPU_INFO *gAmiCpuInfo;
+VOID *gSetupHandle;
+CPU_FEATURES gCpuFeatures;
+EFI_PHYSICAL_ADDRESS gTempBuffer;
+BOOLEAN IsFreeMemBelow1MB;
+
+VOID CreatePrivateAmiCpuInfo2();
+UINT32 * GetPtrToPrivateAmiCpuInfo2Entry(
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread
+);
+
+#if AMI_PEI_DEBUG_SUPPORT
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InterruptHandlerHalt
+//
+// Description: Default CPU Exception. Halts CPU.
+//
+// Input:
+// IN EFI_EXCEPTION_TYPE Exception
+// IN EFI_SYSTEM_CONTEXT Context
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InterruptHandlerHalt(EFI_EXCEPTION_TYPE Exception,EFI_SYSTEM_CONTEXT Context)
+{
+ ERROR_CODE(EFI_SOFTWARE_IA32_EXCEPTION | (UINT32)Exception, EFI_ERROR_MAJOR);
+ checkpoint((UINT8)Exception);
+ TRACE((TRACE_DXE_CPU,"ERROR: CPU Exception %X\n",Exception));
+ EFI_DEADLOOP();
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerGetAptioInterruptHandlerHalt
+//
+// Description:
+//
+// Input:
+//
+//
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerGetAptioInterruptHandlerHalt(
+ IN OUT UINT32* InterruptHandlerHaltAddr
+)
+{
+
+ *InterruptHandlerHaltAddr = (UINT32)InterruptHandlerHalt;
+ TRACE((TRACE_DXE_CPU,"InterruptHandlerHalt = %X\n",InterruptHandlerHalt));
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerIsItPEIDebugIRQHandlerToHookup
+//
+// Description:
+//
+// Input:
+//
+//
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerFixUpPEIDebuggerExceptionHandlers(
+ IN IDTEntry_T* IdtEntry,
+ IN UINT32 i
+)
+{
+
+ FixUpPEIDebuggerExceptionHandlers((IDTEntry_T*)IdtEntry,i);
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerSetupPEIDebuggerExceptionHandlers
+//
+// Description:
+//
+// Input:
+//
+//
+// Output:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerSetupPEIDebuggerExceptionHandlers(VOID)
+{
+
+ SetupPEIDebuggerExceptionHandlers( );
+ return EFI_SUCCESS;
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DebuggerIsItPEIDebugIRQHandlerToHookup
+//
+// Description:
+//
+// Input:
+//
+//
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DebuggerIsItPEIDebugIRQHandlerToHookup(
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler)
+{
+
+ IsItPEIDebugIRQHandlerToHookup(InterruptType,InterruptHandler);
+ return EFI_SUCCESS;
+
+}
+#endif
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateTimerPeriod
+//
+// Description: Calculate CPU time period.
+//
+// Input: VOID
+//
+// Output:
+// UINT64 Timer Period
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT64 CalculateTimerPeriod()
+{
+ UINT64 Timer1;
+ UINT64 Timer2;
+
+ EFI_TPL OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ Timer1 = ReadRtdsc();
+
+ pBS->Stall(DELAY_CALCULATE_CPU_PERIOD);
+
+ Timer2 = ReadRtdsc();
+
+ pBS->RestoreTPL(OldTpl);
+
+ return Div64(DELAY_CALCULATE_CPU_PERIOD * (UINT64)1000000000, (UINT32)(Timer2-Timer1),NULL); //50us * 10E15 femtosec;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCpuInfo
+//
+// Description: Protocol function to get Cpu Info.
+//
+// Input:
+// IN AMI_CPU_INFO_PROTOCOL *This
+// IN UINTN Cpu
+// OUT AMI_CPU_INFO **Info
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetCpuInfo(
+ IN AMI_CPU_INFO_PROTOCOL *This,
+ IN UINTN Cpu,
+ OUT AMI_CPU_INFO **Info
+)
+{
+ if (Cpu >= gNumOfCpus) return EFI_INVALID_PARAMETER;
+ *Info = &gAmiCpuInfo[Cpu];
+ return EFI_SUCCESS;
+}
+
+AMI_CPU_INFO_PROTOCOL gAmiCpuInfoProtocol = {GetCpuInfo};
+
+static CACHE_DESCRIPTOR_INFO gZeroCacheDesc = {0, 0, 0, 0, 0};
+
+typedef struct {
+ UINT32 NumCores; //Number of cores in Package.
+ UINT32 NumEntries; //Each cache descriptor should have same number of entries, max of 4.
+ AMI_CPU_INFO_2_CACHE_DESCR PkgCacheDesc[4]; //Total of the cores
+ AMI_CPU_INFO_2_CACHE_DESCR CoreCacheDesc[4]; //Internal implementation assumes symmetry among cores.
+ //If this every changes, internal implementation will be updated.
+} PKG_CACHE_DESCR;
+
+static PKG_CACHE_DESCR *gPkgCacheDesc; //Array of Package Cache Descriptions.
+
+
+typedef struct {
+ UINT32 CacheType:5;
+ UINT32 CacheLevel:3;
+ UINT32 NotUsed:24;
+} CPUID4_EAX_CACHE_INFO;
+
+typedef struct {
+ UINT32 LineSize:12;
+ UINT32 Partitions:10;
+ UINT32 Ways:10;
+} CPUID4_EBX_CACHE_INFO;
+
+#define MAX_NUM_CACHE_DESC 8
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindPtrToPrivCpuInfoPkg
+//
+// Description: Pointer to internal Package information.
+//
+// Input:
+// IN UINT32 PkgPtr -- Internal package information.
+//
+// Output: UINT32 * -- Internal Core information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 *FindPtrToPrivCpuInfoPkg(
+ IN UINT32 Package
+)
+{
+ UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+ UINT32 i;
+
+ if (Package >= *p) return (UINT32*)-1; //Package does not exist.
+ p++; //now p = Num cores of package 0.
+
+ //Skip entries for previous packages.
+ for (i = 0; i < Package; ++i) {
+ UINT32 NumCores = *p++; //p = now number of threads
+ UINT32 j;
+ for (j = 0; j < NumCores; ++j) {
+ UINT32 NumThreads = *p++;
+ p += NumThreads * PRIVATE_INFO_NUM_OF_CPU_DATA;
+ }
+ }
+ return p;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindPtrToPrivCpuInfoCore
+//
+// Description: Pointer to internal Core information.
+//
+// Input:
+// IN UINT32* PkgPtr -- Internal package information.
+// IN UINT32 Core
+//
+// Output: UINT32 * -- Internal Core information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 *FindPtrToPrivCpuInfoCore(
+ IN UINT32 *PkgPtr,
+ IN UINT32 Core
+)
+{
+ UINT32 *p = PkgPtr;
+ UINT32 NumCores = *p++;
+ UINT32 i;
+ if (Core >= NumCores) return (UINT32*)-1; //Core does not exist.
+
+ //Skip previous cores.
+ for (i = 0; i < Core; ++i) {
+ UINT32 NumThreads = *p++;
+ p += NumThreads * PRIVATE_INFO_NUM_OF_CPU_DATA;
+ }
+ return p;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindPtrToPrivCpuInfoThread
+//
+// Description: Pointer to internal Core information.
+//
+// Input:
+// IN UINT32* CorePtr -- Internal core information.
+// IN UINT32 Thread
+//
+// Output: UINT32 * -- Internal thread information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 *FindPtrToPrivCpuInfoThread(
+ IN UINT32 *CorePtr,
+ IN UINT32 Thread
+)
+{
+ UINT32 *p = CorePtr;
+ UINT32 NumThreads = *p++;
+ if (Thread >= NumThreads) return (UINT32*)-1; //Thread does not exist.
+ p += Thread * PRIVATE_INFO_NUM_OF_CPU_DATA;
+ return p;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetBoardSocketNumber
+//
+// Description: Get socket number from Apic ID.
+//
+// Input:
+// IN UINT32 ApicId
+//
+// Output: UINT32 - Physical Socket Id
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetBoardSocketNumber(IN UINT32 ApicId)
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 MaxThreadsPackage;
+
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+
+ MaxThreadsPackage = (UINT8)(RegEbx >> 16);
+
+ return ApicId / MaxThreadsPackage;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNumPackages
+//
+// Description: Get the number of packages populated and sockets.
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// OUT UINT32 *NumPopulatedPackages
+// OUT UINT32 *NumBoardSockets OPTIONAL
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNumPackages(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ OUT UINT32 *NumPopulatedPackages,
+ OUT UINT32 *NumBoardSockets OPTIONAL
+)
+{
+ //First entry after protocol functions is number of discovered packages.
+ /*UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+
+ *NumPopulatedPackages = *p;
+ //NUMBER_CPU_SOCKETS must be ported if more than 1 socket.
+ ASSERT(*NumPopulatedPackages <= NUMBER_CPU_SOCKETS);
+ if (NumBoardSockets) {
+ *NumBoardSockets = NUMBER_CPU_SOCKETS;
+
+ //In case of porting error, Board sockets can never be less than Populated packages.
+ if (*NumPopulatedPackages > *NumBoardSockets) *NumBoardSockets = *NumPopulatedPackages;
+ }*/
+
+ if(NumPopulatedPackages == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *NumPopulatedPackages = 1;
+
+ if (NumBoardSockets)
+ *NumBoardSockets = 1;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNumCoresThreads
+//
+// Description: Get the number of Cores
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This,
+// IN UINT32 Package
+// OUT UINT32 *NumEnabledCores
+// OUT UINT32 *NumEnabledThreads - This value is total for package.
+// OUT UINT32 *NumDisabledCores OPTIONAL -- Flag must be set in Protocol.
+// OUT UINT32 *NumEnabledThreads OPTIONAL -- Flag must be set in Protocol.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNumCoresThreads(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ OUT UINT32 *NumEnabledCores,
+ OUT UINT32 *NumEnabledThreads,
+ OUT UINT32 *NumDisabledCores OPTIONAL,
+ OUT UINT32 *NumDisabledThreads OPTIONAL
+)
+{
+ UINT32 *p = FindPtrToPrivCpuInfoPkg(Package);
+ UINT32 TotNumCores;
+ UINT32 TotNumThreads = 0;
+ UINT32 i;
+
+ if (NumEnabledCores == NULL || NumEnabledThreads == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ //After package is number of cores.
+ TotNumCores = *p++;
+ for (i = 0; i < TotNumCores; ++i) {
+ UINT32 NumThreads = *p++; //After core is Number of Threads
+ TotNumThreads += NumThreads;
+ p += NumThreads * PRIVATE_INFO_NUM_OF_CPU_DATA; //APIC ID and CPU NUM;
+ }
+
+ *NumEnabledCores = TotNumCores;
+ *NumEnabledThreads = TotNumThreads;
+
+ if (NumDisabledCores) *NumDisabledCores = 0; //Flag not set in Protocol.
+ if (NumDisabledThreads) *NumDisabledThreads = 0; //Flag not set in Protocol.*/
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNumThreads
+//
+// Description: Get the number of Threads
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package
+// IN UINT32 Core
+// OUT UINT32 *NumEnabledThreads
+// OUT UINT32 *NumDisabledThreads OPTIONAL -- Flag must be set if valid
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNumThreads(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ OUT UINT32 *NumEnabledThreads,
+ OUT UINT32 *NumDisabledThreads OPTIONAL
+)
+{
+ UINT32 *p = FindPtrToPrivCpuInfoPkg(Package);
+
+ if (NumEnabledThreads == NULL) return EFI_INVALID_PARAMETER;
+
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ p = FindPtrToPrivCpuInfoCore(p, Core);
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ *NumEnabledThreads = *p;
+ if (NumDisabledThreads) *NumDisabledThreads = 0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetSbsp
+//
+// Description: Get SBSP
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// OUT UINT32 *Package
+// OUT UINT32 *Core
+// OUT UINT32 *Thread
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetSbsp(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ OUT UINT32 *Package,
+ OUT UINT32 *Core,
+ OUT UINT32 *Thread
+)
+{
+ //Desktop system, it must be package0, core0, thread0
+ if (Package == NULL || Core == NULL || Thread == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *Package = 0;
+ *Core = 0;
+ *Thread = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetApicInfo
+//
+// Description: Get Apic Number and Version
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package
+// IN UINT32 Core
+// IN UINT32 Thread
+// OUT UINT32 *ApicId
+// OUT UINT32 *ApicVer OPTIONAL
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetApicInfo(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread,
+ OUT UINT32 *ApicId,
+ OUT UINT32 *ApicVer OPTIONAL
+)
+{
+ UINT32 *p = GetPtrToPrivateAmiCpuInfo2Entry(
+ Package, Core, Thread);
+ UINT32 CpuNum;
+
+ if (ApicId == NULL) return EFI_INVALID_PARAMETER;
+
+ if (p == (UINT32*) -1) return EFI_INVALID_PARAMETER;
+
+ //p points to 32-bit APIC ID and 32-bit CPU Num for internal structures.
+
+ *ApicId = *p++;
+
+ if (ApicVer) {
+ CpuNum = *p;
+ *ApicVer = (UINT8)MemRead32((UINT32*)(UINTN)(LOCAL_APIC_BASE + APIC_VERSION_REGISTER));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetAcpiInfo
+//
+// Description: Get Cpu ACPI information.
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// OUT VOID **AcpiData - ACPI Data
+// OUT UINT32 *NumEntries - Number of Entries in data.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetAcpiInfo(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ OUT VOID **AcpiData,
+ OUT UINT32 *NumEntries
+)
+{
+ if (AcpiData == NULL || NumEntries == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *AcpiData = gAcpiData;
+ *NumEntries = gAcpiDataNumEntries;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetPackageCacheDescr
+//
+// Description: Get the package Cache Information
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package - Socket number. Intenal socket number (continous)
+// OUT AMI_CPU_INFO_2_CACHE_DESCR **Description - Updates pointer to pointer with pointer to Cache information.
+// OUT UINT32 *NumEntries - Number of AMI_CPU_INFO_2_CACHE_DESCR Entries.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetPackageCacheDescr(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ OUT AMI_CPU_INFO_2_CACHE_DESCR **Description,
+ OUT UINT32 *NumEntries
+)
+{
+ PKG_CACHE_DESCR *PkgCacheDesc;
+
+ if (Package >= NumberOfCpuSocketsPopulated()) return EFI_INVALID_PARAMETER;
+
+ if (Description == NULL || NumEntries == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ PkgCacheDesc = &gPkgCacheDesc[Package];
+ *Description = &PkgCacheDesc->PkgCacheDesc[0];
+ *NumEntries = PkgCacheDesc->NumEntries;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCoreCacheDescr
+//
+// Description: Get the Core Cache Information
+//
+// Input:
+// IN AMI_CPU_INFO_2_PROTOCOL *This
+// IN UINT32 Package - Socket number. Internal socket number (continous)
+// IN UINT32 Core - Core number. Internal core number (continous)
+// OUT AMI_CPU_INFO_2_CACHE_DESCR **Description - Updates pointer to pointer with pointer to Cache information.
+// OUT UINT32 *NumEntries - Number of AMI_CPU_INFO_2_CACHE_DESCR Entries.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetCoreCacheDescr(
+ IN AMI_CPU_INFO_2_PROTOCOL *This,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ OUT AMI_CPU_INFO_2_CACHE_DESCR **Description,
+ OUT UINT32 *NumEntries
+)
+{
+ PKG_CACHE_DESCR *PkgCacheDesc;
+
+ if (Package >= NumberOfCpuSocketsPopulated()) return EFI_INVALID_PARAMETER;
+
+ if (Description == NULL || NumEntries == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ PkgCacheDesc = &gPkgCacheDesc[Package];
+
+ if (Core >= PkgCacheDesc->NumCores) return EFI_INVALID_PARAMETER;
+
+ *Description = &PkgCacheDesc->CoreCacheDesc[0];
+ *NumEntries = PkgCacheDesc->NumEntries;
+ return EFI_SUCCESS;
+}
+
+PRIVATE_AMI_CPU_INFO_2_PROTOCOL PrivateAmiCpuInfo2Init = {
+ {
+ 1, //ProtocolVer
+ 0, //Flags
+ GetNumPackages,
+ GetNumCoresThreads,
+ GetNumThreads,
+ GetSbsp,
+ GetApicInfo,
+ GetAcpiInfo,
+ GetPackageCacheDescr,
+ GetCoreCacheDescr
+ }
+ //Additional information will allocated.
+};
+
+PRIVATE_AMI_CPU_INFO_2_PROTOCOL *gPrivateAmiCpuInfo2;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SizeOfPrivateAmiCpuInfo2
+//
+// Description: Size of Private Ami Cpu Info 2 structure to be allocated.
+//
+// Input: VOID
+//
+// Output: UINT32 -- Size
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 SizeOfPrivateAmiCpuInfo2()
+{
+ //See PRIVATE_AMI_CPU_INFO_2_PROTOCOL defintion for comments on internal CPU information.
+
+ UINT32 Size = sizeof(AMI_CPU_INFO_2_PROTOCOL);
+ UINT32 NumSockets = 1;
+ UINT32 CpuNum = 0;
+ UINT32 j;
+
+ Size += sizeof(UINT32); //Number of populated sockets entry.
+ Size += sizeof(UINT32); //Number of cores for socket;
+ for (j = 0; j < gNumOfCpuCores; ++j) {
+ Size += sizeof(UINT32); //Number of thread per core.
+ Size += gNumOfThreads * sizeof(UINT32) * PRIVATE_INFO_NUM_OF_CPU_DATA; //APIC ID and CPU NUM;
+ CpuNum += gNumOfThreads;
+ ASSERT(CpuNum <= gNumOfCpus);
+ }
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FillPrivateAmiCpuInfo2
+//
+// Description: Fill CPU information in Private Ami Cpu Info structure.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillPrivateAmiCpuInfo2()
+{
+ //See PRIVATE_AMI_CPU_INFO_2_PROTOCOL defintion for comments on internal CPU information.
+
+ UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+ UINT32 NumSockets = 1;
+ UINT32 CpuNum = 0;
+ UINT32 i;
+ UINT32 j;
+ UINT32 k;
+
+ *gPrivateAmiCpuInfo2 = PrivateAmiCpuInfo2Init;
+ *p++ = NumSockets;
+ for (i = 0; i < NumSockets; ++i) {
+ *p++ = gNumOfCpuCores;
+ for (j = 0; j < gNumOfCpuCores; ++j) {
+ *p++ = gNumOfThreads;
+ for (k = 0; k < gNumOfThreads; ++k) {
+ *p++ = gEfiMpProcContext[CpuNum].ApicID;
+ *p++ = CpuNum;
+ ++CpuNum;
+ ASSERT(CpuNum <= gNumOfCpus);
+ }
+ }
+ }
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetPtrToPrivateAmiCpuInfo2Entry
+//
+// Description: Get pointer to APIC/Cpu Num
+//
+// Input:
+// IN UINT32 Package
+// IN UINT32 Core
+// IN UINT32 Thread
+//
+// Output: UINT32 *
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 * GetPtrToPrivateAmiCpuInfo2Entry(
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread
+)
+{
+ UINT32 *p;
+
+ p = FindPtrToPrivCpuInfoPkg(Package);
+ if (p == (UINT32*) -1) return (UINT32*)-1; //Package does not exist.
+
+ p = FindPtrToPrivCpuInfoCore(p, Core);
+ if (p == (UINT32*) -1) return (UINT32*)-1; //Core does not exist.
+
+ p = FindPtrToPrivCpuInfoThread(p, Thread);
+ return p;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCpuPkgCoreThrdByNum
+//
+// Description: Get CPU Package/Core/Thread by CPU Number. Number sequencial to APIC ID.
+//
+// Input:
+// IN UINT32 CpuNum
+// OUT UINT32 *Package
+// OUT UINT32 *Core
+// OUT UINT32 *Thread
+//
+// Output: BOOLEAN -- If found, return TRUE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN GetCpuPkgCoreThrdByNum(
+ IN UINT32 CpuNum,
+ OUT UINT32 *Package,
+ OUT UINT32 *Core,
+ OUT UINT32 *Thread
+)
+{
+ UINT32 *p = (UINT32*)(gPrivateAmiCpuInfo2 + 1);
+ UINT32 NumPkgs = *p++;
+ UINT32 Pkg;
+
+ for (Pkg = 0; Pkg < NumPkgs; ++Pkg) {
+ UINT32 NumCores = *p++;
+ UINT32 Cor;
+ for (Cor = 0; Cor < NumCores; ++Cor) {
+ UINT32 NumThrds = *p++;
+ UINT32 Thrd;
+ for (Thrd = 0; Thrd < NumThrds; ++Thrd) {
+ ++p; //Skip ApicId;
+ if (*p++ == CpuNum) {
+ *Package = Pkg;
+ *Core = Cor;
+ *Thread = Thrd;
+ return TRUE;
+ }
+ }
+ }
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FillAcpiData
+//
+// Description: Fill ACPI Data structure
+//
+// Input:
+// IN ACPI_PROCESSOR_INFO *AcpiProcData
+// IN UINT32 Package
+// IN UINT32 Core
+// IN UINT32 Thread
+// IN BOOLEAN Bsp
+//
+// Output: BOOLEAN -- If filled, return TRUE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN FillAcpiData(
+ OUT ACPI_PROCESSOR_INFO *AcpiProcData,
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread,
+ IN BOOLEAN Bsp
+)
+{
+ UINT32 ApicId;
+ UINT32 CpuNum;
+ UINT32 CpuSignature, CpuIdEBX, CpuIdECX, FeatureFlags;
+
+ static UINT32 ProcId = 1;
+
+ UINT32 *ptr = GetPtrToPrivateAmiCpuInfo2Entry(Package, Core, Thread);
+ if (ptr == (UINT32*) -1) return FALSE;
+ //ptr points to 32-bit APIC ID and 32-bit CPU Num for internal structures.
+
+ ApicId = *ptr++;
+ CpuNum = *ptr;
+ CPULib_CpuID(1, &CpuSignature, &CpuIdEBX, &CpuIdECX, &FeatureFlags);
+
+ AcpiProcData->Type = ACPI_PROCESSOR_INFO_TYPE; //0
+ AcpiProcData->Length = sizeof(ACPI_PROCESSOR_INFO);
+ AcpiProcData->Enable = 1;
+ AcpiProcData->Bsp = Bsp;
+ AcpiProcData->Package = Package;
+ AcpiProcData->Core = Core;
+ AcpiProcData->Thread = Thread;
+ AcpiProcData->ApicId = ApicId; //LAPIC number for processor.
+ //AcpiProcData->ApicVer = gCpuInfoHob->Cpuinfo[CpuNum].ApicVer;
+ AcpiProcData->ApicVer = (UINT8)MemRead32((UINT32*)(UINTN)(LOCAL_APIC_BASE + APIC_VERSION_REGISTER));
+ AcpiProcData->CpuSignature = CpuSignature;
+ AcpiProcData->FeatureFlags = FeatureFlags & (BIT0 | BIT7 | BIT8 | BIT9);
+ AcpiProcData->ProcId = ProcId; //ASL processor object ID.
+ //AcpiProcData->ProcObjPath = (EFI_PHYSICAL_ADDRESS)(UINTN)&gProcObjPath; //ASL processor object ID.
+ AcpiProcData->LocalApicType = FALSE; //All processors will either be xAPIC or x2APIC Mode not mixed.
+ ++ProcId;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AddLocalApicCoreEntries
+//
+// Description: Create Private Ami Cpu Info2 Acpi Data.
+//
+// Input:
+// IN UINT32 Package - Processor package
+// IN UINT32 Thread - Processor thread (usually either 0 or 1 for HT)
+//
+// Output: BOOLEAN - TRUE if any entries added.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN AddLocalApicCoreEntries(
+ IN UINT32 Package,
+ IN UINT32 Thread,
+ IN BOOLEAN Bsp,
+ IN UINT32 BspCore
+){
+ UINT32 NumEnabledCores;
+ UINT32 NumEnabledThreads;
+ UINT32 Core;
+ BOOLEAN ValidEntry;
+ AMI_CPU_INFO_2_PROTOCOL *AmiCpu2Info = (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2;
+ ACPI_PROCESSOR_INFO *AcpiProcData = (ACPI_PROCESSOR_INFO *)gAcpiData;
+ static UINT32 Entry = 0;
+
+ AmiCpu2Info->GetNumCoresThreads(AmiCpu2Info, Package, &NumEnabledCores, &NumEnabledThreads, NULL, NULL);
+ NumEnabledThreads = NumEnabledThreads / NumEnabledCores;
+
+ if (Thread >= NumEnabledThreads) return FALSE; //Different packages could have different numbers of threads;
+
+ ValidEntry = FillAcpiData(
+ &AcpiProcData[Entry],
+ Package,
+ BspCore,
+ Thread,
+ Bsp && Thread == 0
+ );
+ if (ValidEntry) ++Entry;
+
+ for (Core = 0; Core < NumEnabledCores; ++Core) {
+ if (Core == BspCore) continue;
+ ValidEntry = FillAcpiData(
+ &AcpiProcData[Entry],
+ Package,
+ Core,
+ Thread,
+ FALSE
+ );
+ if (ValidEntry) ++Entry;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateAcpiData
+//
+// Description: Create Private Ami Cpu Info2 Acpi Data.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateAcpiData()
+{
+ EFI_STATUS Status;
+ UINT32 Package;
+ UINT32 Thread;
+ UINT32 BspPackage;
+ UINT32 BspCore;
+ UINT32 BspThread;
+ UINT32 MaxPackages;
+ BOOLEAN ProcessedEntries;
+ AMI_CPU_INFO_2_PROTOCOL *AmiCpu2Info = (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2;
+
+ gAcpiDataNumEntries = (UINT32)gNumOfCpus;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(ACPI_PROCESSOR_INFO) * gNumOfCpus, &gAcpiData);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = AmiCpu2Info->GetSbsp(
+ AmiCpu2Info,
+ &BspPackage,
+ &BspCore,
+ &BspThread
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = AmiCpu2Info->GetNumPackages(AmiCpu2Info, &MaxPackages, NULL);
+ ASSERT_EFI_ERROR(Status);
+ Thread = 0; //Thread count for a core.
+
+ do { //Thread
+ ProcessedEntries = FALSE;
+
+ //Bsp is always first entry.
+ if (AddLocalApicCoreEntries(BspPackage, Thread, TRUE, BspCore))
+ ProcessedEntries = TRUE;
+
+ for (Package = 0; Package < MaxPackages; ++Package) {
+ if (Package == BspPackage) continue;
+ if (AddLocalApicCoreEntries(Package, Thread, FALSE, BspCore))
+ ProcessedEntries = TRUE;
+ }
+ ++Thread;
+ } while (ProcessedEntries); //No more threads
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCacheSharedThreads
+//
+// Description: Return number of shared threads for a Information.
+//
+// Input: IN UINT8 Level - Cache level
+//
+// Output: UINT8 - Number of shared threads.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 GetCacheSharedThreads(IN UINT8 Level)
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT32 i = 0;
+
+ for(;;) {
+ RegEcx = i;
+ CPULib_CpuID(4, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ if ((RegEax & 0x1f) == 0) break;
+ if (((RegEax >> 5) & 7) == Level) return 1 + ((RegEax >> 14)& 0xfff);
+ ++i;
+ }
+ return 0;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateCacheData
+//
+// Description: Get Cache information.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateCacheData()
+{
+ AMI_CPU_INFO_2_PROTOCOL *AmiCpu2Info = (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2;
+ UINT32 NumPackages;
+ UINT32 Package;
+ UINT32 CpuNum;
+ EFI_STATUS Status;
+
+ BOOLEAN IsLxSharedByPackage[5];
+
+ //Assume between CPUs on the board, similar cache sharing. Only like CPUs can power the board.
+ IsLxSharedByPackage[1] = GetCacheSharedThreads(1) > 2 ? TRUE: FALSE;
+ IsLxSharedByPackage[2] = GetCacheSharedThreads(2) > 2 ? TRUE: FALSE;
+ IsLxSharedByPackage[3] = GetCacheSharedThreads(3) > 2 ? TRUE: FALSE;
+ IsLxSharedByPackage[4] = GetCacheSharedThreads(4) > 2 ? TRUE: FALSE;
+
+ Status = AmiCpu2Info->GetNumPackages(AmiCpu2Info, &NumPackages, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(PKG_CACHE_DESCR) * NumPackages, &gPkgCacheDesc);
+ ASSERT_EFI_ERROR(Status);
+
+ MemSet(gPkgCacheDesc, sizeof(PKG_CACHE_DESCR) * NumPackages, 0);
+
+ //Assume symmetry between the cores in a package. This never likely to change.
+ for(Package = 0, CpuNum = 0; CpuNum < gNumOfCpus; ++Package) {
+ AMI_CPU_INFO *AmiCpuInfo = &gAmiCpuInfo[CpuNum];
+ PKG_CACHE_DESCR *PkgDesc = &gPkgCacheDesc[Package];
+ CACHE_DESCRIPTOR_INFO *CacheInfo = AmiCpuInfo->CacheInfo;
+ UINT32 NumCores = AmiCpuInfo->NumCores;
+ UINT32 Entry = 0;
+
+ ASSERT (Package < NumPackages);
+
+ PkgDesc->NumCores = NumCores;
+
+ while(CacheInfo->Desc != 0) {
+ AMI_CPU_INFO_2_CACHE_DESCR *PkgCacheDesc = &PkgDesc->PkgCacheDesc[Entry];
+ AMI_CPU_INFO_2_CACHE_DESCR *CoreCacheDesc = &PkgDesc->CoreCacheDesc[Entry];
+
+ ASSERT(Entry < MAX_NUM_CACHE_DESC);
+ ASSERT(CacheInfo->Level < 5);
+
+ CoreCacheDesc->LengthDesc = sizeof(AMI_CPU_INFO_2_CACHE_DESCR);
+ CoreCacheDesc->Level = CacheInfo->Level;
+ CoreCacheDesc->Type = CacheInfo->Type;
+ CoreCacheDesc->Size = CacheInfo->Size;
+ CoreCacheDesc->Associativity = CacheInfo->Associativity;
+ CoreCacheDesc->Shared = IsLxSharedByPackage[CacheInfo->Level] + 1;
+
+ if (CoreCacheDesc->Type == 3) {
+ CoreCacheDesc->Type = 2; //Translate type from AMI CPU INFO 1 to AMI CPU INFO 2.
+ }
+
+ MemCpy(PkgCacheDesc, CoreCacheDesc, sizeof(AMI_CPU_INFO_2_CACHE_DESCR));
+
+ PkgCacheDesc->Size *= !IsLxSharedByPackage[CacheInfo->Level] ? NumCores : 1;
+
+ ++Entry;
+ ++CacheInfo;
+ }
+ CpuNum += NumCores * (AmiCpuInfo->NumHts ? 2 : 1) ;
+ PkgDesc->NumEntries = Entry;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreatePrivateAmiCpuInfo2
+//
+// Description: Create Private Ami Cpu Info2 structure.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreatePrivateAmiCpuInfo2()
+{
+ EFI_STATUS Status;
+
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ SizeOfPrivateAmiCpuInfo2(),
+ &gPrivateAmiCpuInfo2
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ FillPrivateAmiCpuInfo2();
+
+ CreateAcpiData();
+
+ CreateCacheData();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillCacheDesc
+//
+// Description: Update cache information with CPUID 4.
+//
+// Input:
+// CACHE_DESCRIPTOR_INFO * CacheInfo - Array to be filled of cache info structures.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillCacheDesc(CACHE_DESCRIPTOR_INFO * CacheInfo)
+{
+ CPUID4_EAX_CACHE_INFO EaxInfo;
+ CPUID4_EBX_CACHE_INFO EbxInfo;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINT32 CacheCount;
+
+ for (CacheCount = 0; CacheCount < (MAX_NUM_CACHE_DESC - 1); ++CacheCount) {
+ RegEcx = CacheCount;
+ CPULib_CpuID(4, (UINT32*)&EaxInfo, (UINT32*)&EbxInfo, &RegEcx, &RegEdx);
+ if (EaxInfo.CacheType == 0) break; //No more cache.
+
+ CacheInfo[CacheCount].Desc = 0xff; //Unused.
+ CacheInfo[CacheCount].Level = EaxInfo.CacheLevel;
+ switch (EaxInfo.CacheType) {
+ case 1: CacheInfo[CacheCount].Type = 0; break;
+ case 2: CacheInfo[CacheCount].Type = 1; break;
+ case 3: CacheInfo[CacheCount].Type = 3; break;
+ }
+
+ CacheInfo[CacheCount].Size =
+ (EbxInfo.Ways + 1) * (EbxInfo.Partitions + 1) * (EbxInfo.LineSize + 1) * (RegEcx + 1) /
+ 1024;
+ CacheInfo[CacheCount].Associativity = EbxInfo.Ways + 1;
+ }
+ CacheInfo[CacheCount] = gZeroCacheDesc;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreatePrivateAmiCpuInfo1
+//
+// Description: Create Private Ami Cpu Info1 structure.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreatePrivateAmiCpuInfo1()
+{
+ EFI_STATUS Status;
+ AMI_CPU_INFO *AmiCpuInfo;
+ UINT64 MicroCodeVersion;
+ UINT32 CpuSignature;
+ UINT32 i;
+ UINT32 Bclk;
+ UINT32 RegEAX, RegEBX, RegECX, RegEDX;
+ UINT32 FeatureEcx, FeatureEdx;
+ UINT32 ExtFeatureEdx;
+ CHAR8 *BrandString;
+ CHAR8 *BrandString1;
+ UINT64 TimerPeriod;
+ UINT8 *pos1;
+ BOOLEAN Ht0 = IsHt0(); //True, if not hyper-threaded CPU.
+ //AMI_CPU_INFO *AmiCpuInfo = &gAmiCpuInfo[Cpu];
+
+
+ //Allocate memory for AMI_CPU_INFO. This will be filled by CPU initialization.
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(AMI_CPU_INFO) * gNumOfCpus,
+ &gAmiCpuInfo
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //Get Cpu Signature
+ CpuSignature = GetCpuSignature();
+
+ //Use 100 for bclk for Sandy Bridge and Ivy Bridge
+ Bclk = 100;
+
+ //Allocate memory for Brand string
+ Status = pBS->AllocatePool(EfiBootServicesData, 49, &BrandString);
+ ASSERT_EFI_ERROR(Status);
+ BrandString1 = BrandString;
+ //Get Brand string
+ CPULib_CpuID(0x80000002, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ *(UINT32*)BrandString = RegEAX; BrandString +=4;
+ *(UINT32*)BrandString = RegEBX; BrandString +=4;
+ *(UINT32*)BrandString = RegECX; BrandString +=4;
+ *(UINT32*)BrandString = RegEDX; BrandString +=4;
+
+ CPULib_CpuID(0x80000003, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ *(UINT32*)BrandString = RegEAX; BrandString +=4;
+ *(UINT32*)BrandString = RegEBX; BrandString +=4;
+ *(UINT32*)BrandString = RegECX; BrandString +=4;
+ *(UINT32*)BrandString = RegEDX; BrandString +=4;
+
+ CPULib_CpuID(0x80000004, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ *(UINT32*)BrandString = RegEAX; BrandString +=4;
+ *(UINT32*)BrandString = RegEBX; BrandString +=4;
+ *(UINT32*)BrandString = RegECX; BrandString +=4;
+ *(UINT32*)BrandString = RegEDX; BrandString +=4;
+ *BrandString = '\0';
+
+ BrandString = BrandString1;
+
+ //Using CPUID to get related feature
+ CPULib_CpuID(1, &RegEAX, &RegEBX, &FeatureEcx, &FeatureEdx);
+ CPULib_CpuID(0x80000001, &RegEAX, &RegEBX, &RegECX, &ExtFeatureEdx);
+
+ //Get loaded Microcode version, MSR 0x8b [EDX] = Microcode version
+ MicroCodeVersion = ReadMsr(0x8b);
+ MicroCodeVersion = *((UINT32*)&MicroCodeVersion + 1); //ignore upper 32-bits.
+
+ TimerPeriod = CalculateTimerPeriod(); //10^-15 s.
+
+ for(i = 0; i < gNumOfCpus; i++ )
+ {
+
+ AmiCpuInfo = &gAmiCpuInfo[i];
+
+
+ Status = pBS->AllocatePool(EfiBootServicesData, MAX_NUM_CACHE_DESC * sizeof(CACHE_DESCRIPTOR_INFO), &AmiCpuInfo->CacheInfo);
+ ASSERT_EFI_ERROR(Status);
+
+ FillCacheDesc(AmiCpuInfo->CacheInfo); //Get Cache Information.
+ //Remove leading spaces. After removing leading spaces, the Brand String can not be
+ //freed. However, it should never be freed.
+
+ AmiCpuInfo->BrandString = BrandString;
+
+ while (*AmiCpuInfo->BrandString == ' ') ++AmiCpuInfo->BrandString;
+
+ //Remove extra spaces in middle.
+ pos1 = AmiCpuInfo->BrandString;
+
+ for(;;) {
+ UINT8 *pos2;
+ UINT8 *pos3;
+ while (*pos1 != ' ' && *pos1 != '\0') ++pos1; //Find next space.
+ if (*pos1 == '\0') break; //If found terminator, break.
+ if (*++pos1 != ' ') continue; //If not second space, continue scanning.
+ pos2 = pos1; //Found 2 spaces.
+ while(*++pos2 == ' '); //Skip spaces.
+ pos3 = pos1;
+ while(*pos2 != '\0') *pos3++ = *pos2++; //copy string
+ *pos3++ = '\0'; //Add terminator.
+ }
+
+ AmiCpuInfo->Version = CpuSignature;
+ AmiCpuInfo->X64Supported = (ExtFeatureEdx >> 29) & 1;
+ AmiCpuInfo->Ht0 = Ht0;
+ AmiCpuInfo->Features = Shl64(FeatureEcx, 32) + FeatureEdx;
+ AmiCpuInfo->NumCores = gNumOfCpuCores;
+ AmiCpuInfo->NumHts = IsHtEnabled() * 2; //Either 2 or 0.
+ AmiCpuInfo->FSBFreq = Bclk;
+ AmiCpuInfo->Voltage = 0; //Voltage is variable, and no information os available.
+ AmiCpuInfo->MicroCodeVers = (UINT32)MicroCodeVersion;
+ AmiCpuInfo->IntendedFreq = ((UINT32)ReadMsr(0x198) >> 8) * Bclk;
+ AmiCpuInfo->ActualFreq = 1000000000/(UINT32)TimerPeriod;
+ }
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GlobalDataInitialize
+//
+// Description: Cpu Dxe Entrypoint.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle -- Handle assigned to this driver.
+// IN EFI_SYSTEM_TABLE *SystemTable -- Efi System table.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GlobalDataInitialize(VOID)
+{
+
+ EFI_STATUS Status;
+ UINT64 MsrData = ReadMsr(MSR_CORE_THREAD_COUNT);
+ EFI_MP_PROC_CONTEXT_FROM_RC *ptr;
+ UINT32 i;
+ UINTN BufferSize;
+
+ gNumOfCpuCores = ((UINT32)(MsrData >> 16 & 0xff));
+ //Locate MP services protocol provided by CPU RC
+ Status = pBS->LocateProtocol(&gEfiMpServicesProtocolGuid, NULL, &gEfiMpServicesProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ if (!EFI_ERROR(Status)){
+ //Get number of Cpus on system
+ gEfiMpServicesProtocol->GetGeneralMPInfo(
+ gEfiMpServicesProtocol,
+ &gNumOfCpus,
+ &gMaximumNumberOfCPUs,
+ &gNumberOfEnabledCPUs,
+ &gRendezvousIntNumber,
+ &gRendezvousProcLength
+ );
+
+ }else{
+ return Status;
+ }
+
+ gNumOfThreads = (UINT32)(gNumOfCpus / gNumOfCpuCores);
+ //TRACE((-1, "Cpu MP service cpus = %x cores %x threads %x\n", gNumOfCpus, gNumOfCpuCores, gNumOfThreads));
+
+ //Get MP processor context of each CPU
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(EFI_MP_PROC_CONTEXT_FROM_RC) * gNumOfCpus,
+ &gEfiMpProcContext
+ );
+
+ ptr = gEfiMpProcContext;
+ BufferSize = sizeof(EFI_MP_PROC_CONTEXT_FROM_RC);
+ for(i = 0; i < gNumOfCpus; i++ , ptr++)
+ {
+ gEfiMpServicesProtocol->GetProcessorContext(
+ gEfiMpServicesProtocol,
+ i,
+ &BufferSize,
+ ptr
+ );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrepareToBoot
+//
+// Description: Handler executed before OS.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PrepareToBoot(IN EFI_EVENT Event, IN VOID *Context)
+{
+ //Trigger SWSMI to save CPU fixed & varible MTRRs
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_SAVE_MSR);
+
+}
+#if CPU_SETUP_SET_BOOT_RATIO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuSetBootRatio
+//
+// Description: Adjust CPU boot ratio base on setup item
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CpuSetBootRatio(VOID)
+{
+
+ UINT8 MaxRatio = Shr64(ReadMsr(MSR_PLATFORM_INFO),8) & 0xff;
+ UINT8 MinRatio = Shr64(ReadMsr(MSR_PLATFORM_INFO),40) & 0xff;
+ UINT8 DesireRatio = (UINT8)GetPlatformCpuBootRatio(gSetupHandle);
+
+ if (DesireRatio == 0 || DesireRatio == 0xff)
+ return;
+
+ if (DesireRatio < MinRatio || DesireRatio > MaxRatio)
+ DesireRatio = MaxRatio;
+
+ ReadWriteMsr(MSR_IA32_MISC_ENABLE, BIT16, (UINT64)-1);
+ WriteMsr(0x199, DesireRatio << 8);
+
+
+}
+#endif
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AmiCpuMpServiceCallback
+//
+// Description: Cpu Dxe Entrypoint.
+//
+// Input:
+// IN EFI_EVENT Event --
+// IN VOID * Context --
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID AmiCpuMpServiceCallback(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle=0;
+ EFI_EVENT BootEvent;
+ VOID *FirstHob;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+ UINT8 CpuVer = CpuSignature & 0xf;
+ BOOLEAN X2ApicEnabled = CPULib_IsLocalX2ApicEnabled();
+ UINT32 NumSocketsPop = NumberOfCpuSocketsPopulated();
+ UINT32 i;
+ BOOLEAN IsSandyBridge = (CpuSigNoVer == SANDY_BRIDGE || CpuSigNoVer == JAKETOWN);
+ BOOLEAN IsIvyBridge = (CpuSigNoVer == IVY_BRIDGE);
+ VOID *pRegistration = NULL;
+ MP_CPU_APICID_DATA MpCpuApicIdData;
+ UINT8 *TpmBaseAddr = (UINT8*)0xfed40000;
+
+
+ //MSR 0xCE[28] Programmable Ratio Limits for Turbo Mode Supported
+ BOOLEAN IsXeCoreRatioLimitSupport = ReadMsr(MSR_PLATFORM_INFO) & 0x10000000 ? 1:0;
+ //MSR 0xCE[29] Programmable Ratio Limits for Turbo Mode Supported
+ BOOLEAN IsPwrLimitConfigSupport = ReadMsr(MSR_PLATFORM_INFO) & 0x20000000 ? 1:0;
+ //MSR 0xCE[30] Programmable TCC Acivation Offset Supported
+ BOOLEAN IsTccAcitveOffsetSupport = ReadMsr(MSR_PLATFORM_INFO) & 0x40000000 ? 1:0;
+ //MSR 0xCE[33:34] Programmable TCC Acivation Offset Supported
+ BOOLEAN IsCtdpSupport = Shr64(ReadMsr(MSR_PLATFORM_INFO), 33) & 0x3 ? 1:0;
+ //InitAmiLib(ImageHandle,SystemTable);
+
+ PROGRESS_CODE(DXE_CPU_INIT);
+
+ //Free the memory
+ if (IsFreeMemBelow1MB)
+ pBS->FreePages(gTempBuffer, EFI_SIZE_TO_PAGES(PMM_EBDA_LOMEM_SIZE) - 1);
+
+ //Init global data for later usage
+ Status = GlobalDataInitialize();
+
+ //Create AMI private CpuInfo1 and CpuInfo2 for AMI other module usage
+ CreatePrivateAmiCpuInfo1();
+ CreatePrivateAmiCpuInfo2();
+
+ Status = pBS->InstallProtocolInterface(
+ &TheImageHandle,
+ &gAmiCpuInfo2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gPrivateAmiCpuInfo2
+ );
+
+ Status = pBS->InstallProtocolInterface(
+ &TheImageHandle,
+ &gAmiCpuInfoProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gAmiCpuInfoProtocol
+ );
+
+ // Get CPU feature & set SetupCpuFeatures variable to hide unsupported setup items
+ DxeInitPlatformCpuLib(pBS, pRS, &gSetupHandle);
+
+ FirstHob = GetEfiConfigurationTable(pST,&gHobListGuid);
+ if (!FirstHob) return;
+
+ //Fill CpuInfoHob
+ gCpuInfoHob = (CPUINFO_HOB*)FirstHob;
+
+ //Find CpuInfo Hob & Update it
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION,&gCpuInfoHob))) {
+ if (guidcmp(&gCpuInfoHob->EfiHobGuidType.Name,&gAmiCpuinfoHobGuid) == 0) break;
+ }
+ if (EFI_ERROR(Status)) return;
+
+ for (i = 0; i < gNumOfCpuCores; ++i) {
+ gCpuInfoHob->Cpuinfo[i].ApicId = gEfiMpProcContext[i].ApicID;
+ }
+
+ MpCpuApicIdData.NumberOfCpu = (UINT8)gNumOfCpus;
+ for (i = 0; i < gNumOfCpus; ++i) {
+ MpCpuApicIdData.ApicId[i] = (UINT8)(gEfiMpProcContext[i].ApicID);
+ }
+ Status = pRS->SetVariable(
+ L"CPUS3APICID",
+ &gMpCpuApicIdDataGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ sizeof(MP_CPU_APICID_DATA),
+ &MpCpuApicIdData );
+
+
+ gCpuFeatures = gCpuInfoHob->CpuFeatures;
+
+ //Init setup feature data
+#if TCG_SUPPORT || TCG2Support
+ PlatformCpuSmxSupport(gSetupHandle, IsSmxSupported(&gCpuFeatures));
+#else
+ PlatformCpuSmxSupport(gSetupHandle, FALSE);
+#endif
+ PlatformCpuXdSupport(gSetupHandle, isXDSupported(&gCpuFeatures));
+ PlatformCpuLimitCpuidSupport(gSetupHandle, isLimitCpuidSupported());
+ PlatformCpuVtSupport(gSetupHandle, IsVmxSupported(&gCpuFeatures));
+ PlatformCpuHtSupport(gSetupHandle, NumSupportedThreadsPerCore() > 1);
+ PlatformCpuMultiCoreSupport(gSetupHandle, NumSupportedCpuCores() > 1);
+ PlatformCpuMultiSocketSupport(gSetupHandle, NUMBER_CPU_SOCKETS > 1);
+ PlatformCpuMultiSocketPopulated(gSetupHandle, NumberOfCpuSocketsPopulated() > 1);
+ PlatformCpuSocketSetPopulated(gSetupHandle, 0, TRUE);
+ PlatformCpuTccActiveOffsetSupport(gSetupHandle, IsTccAcitveOffsetSupport);
+ PlatformCpuXeCoreRatioLimitSupport(gSetupHandle, IsXeCoreRatioLimitSupport);
+ //All CPU should support Current Limit Programming
+ PlatformCpuCurrentLimitSupport(gSetupHandle, TRUE);
+ PlatformCpuPwrLimitConfigSupport(gSetupHandle, IsPwrLimitConfigSupport);
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ PlatformCpuEistSupport(gSetupHandle, !!(RegEcx & (1 << 7)));
+ PlatformCpuAesSupport(gSetupHandle, !!(gRegEcx & (1 << 25)));
+ PlatformCpuPkgCStateDemotionSupport(gSetupHandle, (RegEax > 0x0306C1));
+ PlatformCpuTurboModeSupport(gSetupHandle, isTurboModeSupported());
+ CPULib_CpuID(5, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ PlatformCpuC3Support(gSetupHandle, !!(RegEdx & C3_SUB_STATES_MASK));
+ PlatformCpuC6Support(gSetupHandle, !!(RegEdx & C6_SUB_STATES_MASK));
+ PlatformCpuC7Support(gSetupHandle, !!(RegEdx & C7_SUB_STATES_MASK));
+ PlatformCpuC8Support(gSetupHandle, !!(RegEdx & C8_SUB_STATES_MASK));
+ PlatformCpuC9Support(gSetupHandle, !!(RegEdx & C9_SUB_STATES_MASK));
+ PlatformCpuC10Support(gSetupHandle, !!(RegEdx & C10_SUB_STATES_MASK));
+ PlatformCpuCtdpSupport(gSetupHandle, IsCtdpSupport);
+ PlatformTpmDevicePresent(gSetupHandle, (*TpmBaseAddr != 0xff));
+
+ Status = DxePlatformCpuSaveSupportedData(pRS);
+ ASSERT_EFI_ERROR(Status);
+
+#if CPU_SETUP_SET_BOOT_RATIO
+ CpuSetBootRatio();
+#endif
+
+#if CPU_MODULE_CREATE_SMBIOS_TABLES == 1
+ CpuSmbios();
+#endif
+
+ Status = pBS->CreateEvent(
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ PrepareToBoot,
+ (VOID*)TRUE,
+ &BootEvent
+ );
+ ASSERT_EFI_ERROR(Status);
+
+#ifdef CSM_SUPPORT
+
+ Status = RegisterProtocolCallback(
+ &gAmiLegacyBootProtocolGuid,
+ PrepareToBoot,
+ NULL,
+ &BootEvent,
+ &pRegistration );
+
+#endif
+
+ CpuDxeMiscFuncs();
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AmiCpuSmmFeatureEnCallbacks
+//
+// Description: Callback for trigger SMI to enable Cpu SMM feature in SMM
+//
+// Input:
+// IN EFI_EVENT Event --
+// IN VOID * Context --
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AmiCpuSmmFeatureEnCallbacks(IN EFI_EVENT Event, IN VOID *Context)
+{
+
+#ifdef SW_SMI_ENABLE_SMM_FEATURE
+ pBS->CloseEvent(Event);
+#if SMM_ACCESS_CHECK_ENABLE
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_ENABLE_SMM_FEATURE);
+#endif
+#endif
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DxeInitializeCpu
+//
+// Description: Cpu Dxe Entrypoint.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle -- Handle assigned to this driver.
+// IN EFI_SYSTEM_TABLE *SystemTable -- Efi System table.
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeInitializeCpu(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status;
+ AMI_BEFORE_CPU_RC_PROTOCOL *AmiBeforeCpuRcProtocol;
+
+#if AMI_PEI_DEBUG_SUPPORT
+ AMI_DEBUGGER_CPU_PROTOCOL *AmiDebuggerCpuProtocol;
+#endif
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ // Get CPU support feature before CPU RC DXE initialize
+ CPULib_CpuID(1, &gRegEax, &gRegEbx, &gRegEcx, &gRegEdx);
+
+ Status = RegisterProtocolCallback(
+ &gEfiMpServicesProtocolGuid,
+ AmiCpuMpServiceCallback,
+ NULL,
+ &gAmiMpEvent,
+ &gAmiMpEventRegistration
+ );
+
+ Status = RegisterProtocolCallback(
+ &gEfiDxeSmmReadyToLockProtocolGuid,
+ AmiCpuSmmFeatureEnCallbacks,
+ NULL,
+ &gSmmFeaEnEvent,
+ &gSmmFeaEnReg
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(AMI_BEFORE_CPU_RC_PROTOCOL),
+ (VOID**)&AmiBeforeCpuRcProtocol );
+
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gAmiBeforeCpuRcProtocolGuid, AmiBeforeCpuRcProtocol,
+ NULL );
+#if AMI_PEI_DEBUG_SUPPORT
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(AMI_DEBUGGER_CPU_PROTOCOL),
+ (VOID**)&AmiDebuggerCpuProtocol );
+
+ AmiDebuggerCpuProtocol->DebuggerGetAptioIntHandler = DebuggerGetAptioInterruptHandlerHalt;
+ AmiDebuggerCpuProtocol->DebuggerFixUpPEIExceptionHandlers = DebuggerFixUpPEIDebuggerExceptionHandlers;
+ AmiDebuggerCpuProtocol->DebuggerSetupExceptionHandler = DebuggerSetupPEIDebuggerExceptionHandlers;
+ AmiDebuggerCpuProtocol->DebuggerIsDebuggerIrqHadler = DebuggerIsItPEIDebugIRQHandlerToHookup;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gAmiDebuggerCpuProtocolGuid, AmiDebuggerCpuProtocol,
+ NULL );
+#endif
+
+ gTempBuffer = 0xA0000 - PMM_EBDA_LOMEM_SIZE;
+ IsFreeMemBelow1MB = FALSE;
+ Status = pBS->AllocatePages (
+ AllocateAddress,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(PMM_EBDA_LOMEM_SIZE) - 1,
+ &gTempBuffer
+ );
+
+ if (!EFI_ERROR(Status))
+ IsFreeMemBelow1MB = TRUE;
+
+ return EFI_SUCCESS;
+
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuDxe.dxs b/Core/CPU/CpuDxe.dxs
new file mode 100644
index 0000000..e6d6ced
--- /dev/null
+++ b/Core/CPU/CpuDxe.dxs
@@ -0,0 +1,57 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.dxs 1 2/07/12 3:58a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:58a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.dxs $
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CPUDXE.dxs
+//
+// Description: Dependency expression for Cpu Dxe.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuDxe.h b/Core/CPU/CpuDxe.h
new file mode 100644
index 0000000..aeb5015
--- /dev/null
+++ b/Core/CPU/CpuDxe.h
@@ -0,0 +1,158 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.h 2 1/14/13 1:54a Crystallee $
+//
+// $Revision: 2 $
+//
+// $Date: 1/14/13 1:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxe.h $
+//
+// 2 1/14/13 1:54a Crystallee
+// [TAG] EIP111199
+// [Category] Improvement
+// [Description] Provide variable data which constains number of P
+// states support.
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuDxe.h
+//
+// Description: Cpu Dxe header file.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPU_DXE_H__
+#define __CPU_DXE_H__
+
+#include <AmiHobs.h>
+#include <Protocol\Cpu.h>
+#include <Protocol\MpService\MpService.h>
+#include <Protocol\AmiCpuInfo2.h>
+#include "Cpu.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// Define structures used and referenced in this file
+typedef struct{
+ UINT16 NumberOfPStates;
+} P_STATES_DATA;
+
+typedef struct{
+ UINT32 MemAddress, MemLength;
+} system_memory_struc;
+
+EFI_STATUS EfiCpuFlushDataCache (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length,
+ IN EFI_CPU_FLUSH_TYPE FlushType);
+
+EFI_STATUS EfiCpuSetMemoryAttributes (
+ IN EFI_CPU_ARCH_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN UINT64 Attributes);
+
+extern EFI_MP_SERVICES_PROTOCOL *gEfiMpServicesProtocol;
+
+//APIC ID
+//CPU NUM
+#define PRIVATE_INFO_NUM_OF_CPU_DATA 2
+
+typedef struct {
+ AMI_CPU_INFO_2_PROTOCOL AmiCpuInfo2;
+//??? Determine max structure size of UINT32s
+ // UINT32 # of populated Sockets 0
+ // ---------------------
+ // ---------------------
+ // ---Socket #0---
+ // UINT32 # of Cores
+ // ---Core #0---
+ // UINT32 # of Threads
+ // ---Thread #0---
+ // UINT32 APIC ID
+ // UINT32 CPU Num
+ // ---Thread #1---
+ // UINT32 APIC ID
+ // UINT32 CPU Num
+ // ---Core #1---
+ // ....
+ // ---------------------
+ // ---------------------
+ // ---Socket #1---
+ // UINT32 # of Cores
+ // ---Core # 0---
+ // UINT32 # of Threads
+ // ---Thread #0---
+ // ....
+} PRIVATE_AMI_CPU_INFO_2_PROTOCOL;
+
+extern PRIVATE_AMI_CPU_INFO_2_PROTOCOL *gPrivateAmiCpuInfo2;
+
+typedef struct _AMI_BEFORE_CPU_RC_PROTOCOL AMI_BEFORE_CPU_RC_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI *PLATFORM_CPU_DXE_POLICY_OVERWRITE) (
+ IN AMI_BEFORE_CPU_RC_PROTOCOL *This
+
+ );
+
+typedef struct _AMI_BEFORE_CPU_RC_PROTOCOL {
+ PLATFORM_CPU_DXE_POLICY_OVERWRITE PlatformCpuDxePolicyOverwrite;
+};
+
+VOID CpuDxeMiscFuncs(VOID);
+
+#if PERF_TUNE_SUPPORT == 1
+
+EFI_STATUS IntelXtuFillCpuDataCallBack(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+#endif
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuDxeFuncs.c b/Core/CPU/CpuDxeFuncs.c
new file mode 100644
index 0000000..dea230d
--- /dev/null
+++ b/Core/CPU/CpuDxeFuncs.c
@@ -0,0 +1,1101 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxeFuncs.c 10 5/06/14 12:03a Hsingyingchung $
+//
+// $Revision: 10 $
+//
+// $Date: 5/06/14 12:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuDxeFuncs.c $
+//
+// 10 5/06/14 12:03a Hsingyingchung
+// [TAG] EIP167029
+// [Category] Improvement
+// [Description] 1. keep the original attribute of "Setup" variable when
+// use SetVariable().
+// 2. remove the runtime attribute of variables that no access requirement
+// in runtime.
+//
+// 9 6/03/13 12:12a Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description]
+// 1. Change PLL defatul value to LCPLL
+// 2. Modify IA core ratio minimun value. Use "max non turbo ratio(MSR
+// CEh)" instead of "power on turbo default value".
+// 3. Remove write MSR 620h due to RC have implemented (EIP123446).
+//
+// 8 4/07/13 11:58p Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description] Keep ring ratio default value in ACPI table when one
+// core ratio has changed.
+//
+// 7 3/05/13 1:10a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Use OcSetupData for EIST and Turbo status when
+// PerformanceTunning enable
+//
+// 6 2/07/13 4:08a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description]
+// Add:
+// 1. Support IA core and Ring voltage offset negative in OC mailbox.
+// 2. Add Filter PLL function, please change
+// "HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT" token if need to use this
+// function.
+//
+// Fixed:
+// 1. TDP Time Window is now programmed to 8 seconds by default.
+// 2. When cold reset, re-enabling FIVR faults and SVID control.
+// 3. Assign max ring ratio in msr 0x620 with ring ratio max value
+// support.
+//
+// 5 1/14/13 1:54a Crystallee
+// [TAG] EIP111199
+// [Category] Improvement
+// [Description] Provide variable data which constains number of P
+// states support.
+//
+// 4 12/20/12 10:25a Hsingyingchung
+//
+// 3 12/20/12 10:21a Hsingyingchung
+// [TAG] EIP108128
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] "Max non-turbo ratio" can't show in BIOS setup when first
+// boot after flashing BIOS
+// [RootCause] Doesn't initialize max non-turbo ratio value when first
+// boot after flashing BIOS.
+// [Solution] Add initialize code for max non-turbo ratio.
+//
+// 2 11/23/12 2:09a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuDxeFuncs.c
+//
+// Description:
+// Installs CPU Architectural Protocol.
+// processor interrupt vector table. The CPU Architectural
+// Protocol enables/disables/get state of interrupts, set
+// memory range cache type, and installs/uninstalls
+// interrupt handlers.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Setup.h>
+#include <token.h>
+#include <AmiCspLib.h>
+#include <Protocol\AmiCpuInfo.h>
+#include "CpuDxe.h"
+
+extern EFI_SYSTEM_TABLE *pST;
+extern EFI_BOOT_SERVICES *pBS;
+extern EFI_RUNTIME_SERVICES *pRS;
+
+extern EFI_GUID gHobListGuid;
+
+#if PERF_TUNE_SUPPORT == 1
+#include <Protocol\PerfTuneProtocol.h>
+#include "Board\EM\PerfTune\PerfTuneCpuSetup.h"
+
+static EFI_GUID gAmiInternalFactoryTdcTdpHobGuid = AMI_INTERNAL_FACTORY_TDC_TDP_HOB_GUID;
+static EFI_GUID gAmiCpuRatioLimitHobGuid = AMI_INTERNAL_CPU_RATIO_LIMIT;
+
+AMI_INTERNAL_FACTORY_TDC_TDP_HOB *gTdcTdpHob = NULL;
+CPU_RATIO_LIMIT_DATA *gCpuRatioLimitData = NULL;
+
+OVERCLOCKING_CONFIG_DATA *gOcConfigData;
+EFI_GUID InternalWdtGuid = PERF_TUNE_WDT_PROTOCOL_GUID;
+
+#if !defined(EDK_RELEASE_VERSION) || (EDK_RELEASE_VERSION < 0x00020000)
+#define EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID \
+ { \
+ 0xd71db106, 0xe32d, 0x4225, 0xbf, 0xf4, 0xde, 0x6d, 0x77, 0x87, 0x17, 0x61 \
+ }
+
+#else
+#define EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID \
+ { \
+ 0xd71db106, 0xe32d, 0x4225, \
+ { \
+ 0xbf, 0xf4, 0xde, 0x6d, 0x77, 0x87, 0x17, 0x61 \
+ } \
+ }
+#endif
+EFI_GUID gPowerMgmtInitDoneProtocolGuid = EFI_POWER_MGMT_INIT_DONE_PROTOCOL_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+
+#define DXE_PLATFORM_ME_POLICY_GUID \
+ { 0x69bf9e8a, 0x4ad6, 0x9a28, 0x87, 0xf3, 0x09, 0xa0, 0x71, 0x29, 0x2a, 0x00}
+EFI_GUID gDxePlatformMePolicyGuid = DXE_PLATFORM_ME_POLICY_GUID;
+
+#define ME_INFO_SETUP_GUID \
+ { 0x78259433, 0x7B6D, 0x4DB3, 0x9A, 0xE8, 0x36, 0xC4, 0xC2, 0xC3, 0xA1, 0x7D}
+EFI_GUID gMeSetupInfoGuid = ME_INFO_SETUP_GUID;
+
+#define AMI_CPU_INTERNAL_ME_FW_VERSION_GUID \
+ { 0x9b875aac, 0x36ec, 0x4550, 0xa4, 0xae, 0x86, 0xc8, 0x4e, 0x96, 0x76, 0x7e}
+EFI_GUID gAmiCpuMEFwVerGuid = AMI_CPU_INTERNAL_ME_FW_VERSION_GUID;
+typedef struct{
+ UINT8 MeFirmwareInfo;
+ UINT32 MeMajor;
+ UINT32 MeMinor;
+ UINT32 MeHotFix;
+ UINT32 MeBuildNo;
+} ME_INFO_SETUP_DATA;
+
+BIOS_SETTING_DATA *gBiosSettingData;
+#endif
+
+#ifndef FVID_MAX_STATES
+#define FVID_MAX_STATES 16
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NumberOfPStatesSupport
+//
+// Description: Provide variable data which constains number of P states support
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID NumberOfPStatesSupport(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID gSetupGuid = SETUP_GUID;
+#if PERF_TUNE_SUPPORT == 1
+ UINTN SetupDataSize = sizeof(OC_SETUP_DATA);
+ OC_SETUP_DATA SetupData;
+#else
+ UINTN SetupDataSize = sizeof(SETUP_DATA);
+ SETUP_DATA SetupData;
+#endif
+ P_STATES_DATA PStatesData;
+ UINT16 mMaxBusRatio;
+ UINT16 mMinBusRatio;
+ UINT16 BusRatioRange;
+ UINT64 MsrPlatformInfo;
+
+#if PERF_TUNE_SUPPORT == 1
+ Status = pRS->GetVariable(L"OcSetupData",&gSetupGuid, NULL, &SetupDataSize, &SetupData);
+#else
+ Status = pRS->GetVariable(L"Setup",&gSetupGuid, NULL, &SetupDataSize, &SetupData);
+#endif
+ if(EFI_ERROR(Status)) {
+ TRACE((-1,"Get Setup variable fail!!\n"));
+ return;
+ }
+
+ if (!EFI_ERROR(Status)) {
+ if (!SetupData.EIST) {
+ PStatesData.NumberOfPStates = 0;
+ }
+ else {
+ MsrPlatformInfo = ReadMsr(0xce);
+ mMaxBusRatio = (UINT16)(Shr64(MsrPlatformInfo, 8) & 0xff);
+ mMinBusRatio = (UINT16)(Shr64(MsrPlatformInfo, 40) & 0xff);
+ BusRatioRange = mMaxBusRatio - mMinBusRatio;
+
+ PStatesData.NumberOfPStates = ((BusRatioRange + 1) < FVID_MAX_STATES ? (BusRatioRange + 1) : FVID_MAX_STATES);
+
+ if (SetupData.TurboMode & isTurboModeSupported()) {
+ if (PStatesData.NumberOfPStates == FVID_MAX_STATES)
+ PStatesData.NumberOfPStates--;
+ }
+ }
+
+ Status = pRS->SetVariable(
+ L"NumOfPState",
+ &gSetupGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(P_STATES_DATA),
+ &PStatesData
+ );
+ if(EFI_ERROR(Status)) {
+ TRACE((-1,"Set number of P states variable fail!!\n"));
+ }
+ }
+}
+
+#if PERF_TUNE_SUPPORT == 1
+
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FillXtuGaciData
+//
+// Description: Fill CPU information for xtu 3.0 specification
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FillXtuGaciData(
+ IN PERF_TUNE_ASL_PROTOCOL *PerfTuneAslProtocol
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINT8 *Buffer = NULL;
+ UINT8 *ptr = NULL;
+ UINTN Len = 0;
+ UINT64 PlatformInfo = ReadMsr(MSR_PLATFORM_INFO);
+ UINT16 Bins = Shr64(ReadMsr(MSR_FLEX_RATIO),17) & 0x7; //overclocking bins supported
+ UINT16 MNTR = gBiosSettingData->ProcessorMul;
+
+ //----------------------------CPU Ratio GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CpuMulGaciData = {BIOS_PROC_MULT_IMPLEMENTATION, 0x0, 0, 0, 0, 0, 0, 0, 0};
+
+ //----------------------------CPU TDC GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CpuTdcGaciData = {BIOS_TDC_VALUE_IMPLEMENTATION, 4096, 3, 0, 0, 0, 4095, 0, 511875};
+
+ //----------------------------CPU TDP GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CpuTdpGaciData = {BIOS_TDP_VALUE_IMPLEMENTATION, 4096, 3, 0, 0, 0, 4095, 0, 511875};
+
+ //-------------------TOTAL DESIGN POWER LOCK SWITCH DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ExtTDPSwGaciData= {BIOS_EXTENDED_TDP_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 0, 0, 1, 0, 1};
+
+ //----------------------------CPU Core Ratio Limit GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu1CoreRatioLimGaci = {BIOS_1_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu2CoreRatioLimGaci = {BIOS_2_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu3CoreRatioLimGaci = {BIOS_3_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu4CoreRatioLimGaci = {BIOS_4_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu5CoreRatioLimGaci = {BIOS_5_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA Cpu6CoreRatioLimGaci = {BIOS_6_CORE_RATIO_IMPLEMENTATION, 0x1, 0, 0, 0, 0, 0, 0, 0};
+
+ //----------------------------CPU Turbo Mode GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA TurboModeGaciData = {BIOS_TURBO_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ //----------------------------CPU Max Turbo Mode Cpu Voltage GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA TMCpuVoltGaci = {BIOS_MAX_TURBO_MODE_CPU_VOLTAGE_IMPLEMENTATION, 256, 5, 0, 0, 0, 255, 0, 99609375};
+
+ //----------------------------CPU EIST GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA EistGaciData = {BIOS_EIST_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ //----------------------------CPU TDP Related GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ShortTDPSwGaciData= {BIOS_SHORT_TDP_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ShortTdpGaci = {BIOS_SHORT_TDP_IMPLEMENTATION, 513, 0, 0, 0, 0, 512, 0, 512};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ //static GACI_DATA ExtTdpGaci = {BIOS_EXTENDED_TDP_IMPLEMENTATION, 4096, 3, 0, 0, 0, 4095, 0, 511875};
+ static GACI_DATA ExtTdpGaci = {BIOS_EXTENDED_TDP_IMPLEMENTATION, 513, 0, 0, 0, 0, 512, 0, 512};
+
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA ExtTdpTimeGaci = {BIOS_EXTENDED_TIME_WINDOW_IMPLEMENTATION, 0xFFFF, 0, 0, 1, 0, 0, 0, 0};
+
+ //----------------------------IA CORE CURRENT MAX--------------------------
+ // GACI_DATA DevNameGaciData { ControlID, NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA IACoreAmpGaci = {BIOS_PACKAGE_CURRENT_LIMIT_IMPLEMENTATION, 8192, 3, 0, 0, 0, 8191, 0, 1023875};
+
+ //----------------------------IGFX CORE CURRENT MAX--------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ //static GACI_DATA iGFXCoreAmpGaci = {BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION, 8192, 3, 0, 0, 0, 8191, 0, 1023875};
+
+
+ //----------------------------INTERNAL PLL Overvoltage Enable--------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA iPLLOvGaci = {BIOS_CPU_PLL_VOLTAGE_UNLOCK_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 0, 0, 1, 0, 1};
+
+ //----------------------------Overclocking Lock GACI DATA----------------------------
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA OverclockingGaciData = {BIOS_OVERCLOCKING_ENABLE_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+ //----------------------------Overclocking Related GACI DATA----------------------------
+ //IA core
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CPUVoltOverrideGaci = {BIOS_CPU_VOLTAGE_IMPLEMENTATION, 2001, 3, 0, 0, 0, 2000, 0, 2000};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CPUVoltModeGaci = {BIOS_IA_CORE_VOLTAGE_MODE_IMPLEMENTATION, 2, 0, 0, 0, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA CPUVoltOffsetGaci = {BIOS_CPU_VOLTAGE_OFFSET_IMPLEMENTATION, 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+ //RING
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGRatioGaci = { BIOS_RING_RATIO_IMPLEMENTATION, 1, 0, 0, 0, 0, 0, 0, 0};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGVoltOverrideGaci = {BIOS_RING_VOLTAGE_OVERRIDE_IMPLEMENTATION, 2001, 3, 0, 0, 0, 2000, 0, 2000};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGVoltModeGaci = {BIOS_RING_VOLTAGE_MODE_IMPLEMENTATION, 2, 0, 0, 0, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA RINGVoltOffsetGaci = {BIOS_RING_VOLTAGE_OFFSET_IMPLEMENTATION, 2001, 0, 0, 1000, 0, 2000, 0xFFFFFc18, 1000};
+
+ //SVID and FIVR
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA SVIDControlGaci = {BIOS_DYNAMIC_SVID_CONTROL_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA SVIDVoltOverrideGaci = {BIOS_SVID_VOLTAGE_OVERRIDE_IMPLEMENTATION, 2501, 3, 0, 0, 0, 2500, 0, 2500};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA FivrFaultsGaciData = {BIOS_FIVR_FAULTS_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+ // GACI_DATA DevNameGaciData { ControlID,NumberOfValues,Precision,Flags,DefaultDataValue,MinDataValue,MaxDataValue,MinDisplayValue,MaxDisplayValue}
+ static GACI_DATA FivrEfficiencyGaciData = {BIOS_FIVR_EFFICIENCY_MANAGEMENT_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+ //Filter PLL Frequency
+ static GACI_DATA FilterPLLGaciData = {BIOS_FILTER_PLL_FREQUENCY_IMPLEMENTATION, 0x2, 0, 0, 1, 0, 1, 0, 1};
+#endif
+
+ TRACE((-1, "XTU Fill XTU Cpu Gaci data\n"));
+
+ //--1. CPU ratio GACI DATA--------------------------------------------
+ //CpuMulGaciData.MinDataValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ //CpuMulGaciData.MaxDataValue = (UINT16)(Shr64(PlatformInfo, 8) & 0xFF);
+
+ //CpuMulGaciData.MinDisplayValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ //CpuMulGaciData.MaxDisplayValue = (UINT16)(Shr64(PlatformInfo, 8) & 0xFF);
+
+ //CpuMulGaciData.NumberOfValues = CpuMulGaciData.MaxDataValue - CpuMulGaciData.MinDataValue + 1;
+ //CpuMulGaciData.DefaultDataValue = (UINT16)(Shr64(PlatformInfo, 8) & 0xFF);
+
+ //Len = sizeof(GACI_DATA);
+ //Buffer = MallocZ(Len);
+ //if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ //MemCpy(Buffer, &CpuMulGaciData, sizeof(CpuMulGaciData));
+ //Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ //pBS->FreePool(Buffer);
+ CpuMulGaciData.MinDataValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ CpuMulGaciData.MaxDataValue = (UINT16)gCpuRatioLimitData->MaxNonTurboRatio;
+ CpuMulGaciData.MinDisplayValue = (UINT16)(Shr64(PlatformInfo, 40) & 0xFF);
+ CpuMulGaciData.MaxDisplayValue = (UINT16)gCpuRatioLimitData->MaxNonTurboRatio;
+ CpuMulGaciData.NumberOfValues = CpuMulGaciData.MaxDataValue - CpuMulGaciData.MinDataValue + 1;
+ CpuMulGaciData.DefaultDataValue = (UINT16)gCpuRatioLimitData->MaxNonTurboRatio;
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CpuMulGaciData, sizeof(CpuMulGaciData));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+
+ //--2. CPU TDC GACI DATA--------------------------------------------
+ CpuTdcGaciData.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdc);
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &CpuTdcGaciData, Len);
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+
+ //--3. CPU TDP GACI DATA--------------------------------------------
+ CpuTdpGaciData.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdp);
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &CpuTdpGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--4. TOTAL DESIGN POWER LOCK SWITCH DATA----------------------------
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &ExtTDPSwGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--5. CPU Cores ratio limit GACI DATA--------------------------------------------
+ Cpu1CoreRatioLimGaci.MinDataValue = MNTR;
+ Cpu1CoreRatioLimGaci.MinDisplayValue = MNTR;
+
+ MemCpy(&(Cpu2CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu3CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu4CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu5CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+ MemCpy(&(Cpu6CoreRatioLimGaci.NumberOfValues), &(Cpu1CoreRatioLimGaci.NumberOfValues), sizeof(GACI_DATA) - sizeof(UINT32));
+
+ Cpu1CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->OneCoreRatioLimit + (UINT16)Bins;
+ Cpu1CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->OneCoreRatioLimit + (UINT16)Bins;
+ Cpu1CoreRatioLimGaci.NumberOfValues = Cpu1CoreRatioLimGaci.MaxDataValue - Cpu1CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu2CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->TwoCoreRatioLimit + (UINT16)Bins;
+ Cpu2CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->TwoCoreRatioLimit + (UINT16)Bins;
+ Cpu2CoreRatioLimGaci.NumberOfValues = Cpu2CoreRatioLimGaci.MaxDataValue - Cpu2CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu3CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->ThreeCoreRatioLimit + (UINT16)Bins;
+ Cpu3CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->ThreeCoreRatioLimit + (UINT16)Bins;
+ Cpu3CoreRatioLimGaci.NumberOfValues = Cpu3CoreRatioLimGaci.MaxDataValue - Cpu3CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu4CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FourCoreRatioLimit + (UINT16)Bins;
+ Cpu4CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FourCoreRatioLimit + (UINT16)Bins;
+ Cpu4CoreRatioLimGaci.NumberOfValues = Cpu4CoreRatioLimGaci.MaxDataValue - Cpu4CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu5CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FiveCoreRatioLimit + (UINT16)Bins;
+ Cpu5CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->FiveCoreRatioLimit + (UINT16)Bins;
+ Cpu5CoreRatioLimGaci.NumberOfValues = Cpu5CoreRatioLimGaci.MaxDataValue - Cpu5CoreRatioLimGaci.MinDataValue + 1;
+
+ Cpu6CoreRatioLimGaci.MaxDataValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->SixCoreRatioLimit + (UINT16)Bins;
+ Cpu6CoreRatioLimGaci.MaxDisplayValue = (Bins == 0x7)? 80 : (UINT16)gTdcTdpHob->SixCoreRatioLimit + (UINT16)Bins;
+ Cpu6CoreRatioLimGaci.NumberOfValues = Cpu6CoreRatioLimGaci.MaxDataValue - Cpu6CoreRatioLimGaci.MinDataValue + 1;
+
+ gTdcTdpHob->OneCoreRatioMax = Cpu1CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->TwoCoreRatioMax = Cpu2CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->ThreeCoreRatioMax = Cpu3CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->FourCoreRatioMax = Cpu4CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->FiveCoreRatioMax = Cpu5CoreRatioLimGaci.MaxDataValue;
+ gTdcTdpHob->SixCoreRatioMax = Cpu6CoreRatioLimGaci.MaxDataValue;
+
+
+ Cpu1CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->OneCoreRatioLimit);
+ Cpu2CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->TwoCoreRatioLimit);
+ Cpu3CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->ThreeCoreRatioLimit);
+ Cpu4CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->FourCoreRatioLimit);
+ Cpu5CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->FiveCoreRatioLimit);
+ Cpu6CoreRatioLimGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->SixCoreRatioLimit);
+
+ Len = sizeof(GACI_DATA);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &Cpu1CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit1)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu2CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit2)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu3CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit3)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu4CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit4)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu5CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit5)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ MemCpy(Buffer, &Cpu6CoreRatioLimGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if (MNTR > gBiosSettingData->CoreRatioLimit6)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, MNTR);
+
+ pBS->FreePool(Buffer);
+ pBS->FreePool(gBiosSettingData);
+
+ //--6. Turbo Mode GACI DATA--------------------------------------------
+ Len = sizeof(TurboModeGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &TurboModeGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--7. Max Turbo Mode CPU Voltage-------------------------------------
+ Len = sizeof(TMCpuVoltGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &TMCpuVoltGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--8. CPU EIST GACI DATA-------------------------------------
+ Len = sizeof(EistGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &EistGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--9. ShortTdpGaci------------------------------------------
+ //ShortTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdc);
+ ShortTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdc / 8 );
+ Len = sizeof(ShortTdpGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ShortTdpGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //-- ShortTDPSwGaci------------------------------------------
+ Len = sizeof(ShortTDPSwGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ShortTDPSwGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--10.ExtTdpGaci------------------------------------------
+ //ExtTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdp);
+ ExtTdpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->Tdp / 8 );
+ Len = sizeof(ExtTdpGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ExtTdpGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //-- ExtTdpTimeGaci------------------------------------------
+ ExtTdpTimeGaci.DefaultDataValue = 8; // For desktop, default is 8.
+ Len = sizeof(ExtTdpTimeGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &ExtTdpTimeGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+
+ //11.IA CORE CRUUENT MAX----------------------------------------------------
+ IACoreAmpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->IaCoreCurrentMax);
+ Len = sizeof(IACoreAmpGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &IACoreAmpGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //12.iGFX CORE CURRENT MAX--------------------------------------------------
+ //iGFXCoreAmpGaci.DefaultDataValue = (UINT16)(gTdcTdpHob->IGfxCoreCurrentMax);
+ //Len = sizeof(iGFXCoreAmpGaci);
+ //Buffer = MallocZ(Len);
+ //if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ //MemCpy(Buffer, &iGFXCoreAmpGaci, sizeof(GACI_DATA));
+ //Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ //pBS->FreePool(Buffer);
+
+
+ //13.INTERNAL PLL OVERVOLTAGE ENABLE---------------------------
+ Len = sizeof(iPLLOvGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &iPLLOvGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //--14. Overclocking Enable GACI DATA-------------------------------------
+ Len = sizeof(OverclockingGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Buffer, &OverclockingGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+ //--15. Overclocking Feature GACI DATA-------------------------------------
+//IA core
+ //CPU voltage override
+ Len = sizeof(CPUVoltOverrideGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CPUVoltOverrideGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //IA core voltage mode
+ Len = sizeof(CPUVoltModeGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CPUVoltModeGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Dynamic CPU Voltage Offset
+ Len = sizeof(CPUVoltOffsetGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &CPUVoltOffsetGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//CLR/RING
+ //Ring Ratio
+ RINGRatioGaci.MaxDataValue = (UINT16)gOcConfigData->OCCap[RING].MaxOcRatioLimit;
+ RINGRatioGaci.MaxDisplayValue = (UINT16)gOcConfigData->OCCap[RING].MaxOcRatioLimit;
+ RINGRatioGaci.NumberOfValues = RINGRatioGaci.MaxDataValue - RINGRatioGaci.MinDataValue + 1;
+ RINGRatioGaci.DefaultDataValue = (UINT16)gTdcTdpHob->OneCoreRatioLimit;
+ Len = sizeof(RINGRatioGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGRatioGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Ring Voltage Override
+ Len = sizeof(RINGVoltOverrideGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGVoltOverrideGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Ring Voltage Mode
+ Len = sizeof(RINGVoltModeGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGVoltModeGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //Ring Voltage Offset
+ Len = sizeof(RINGVoltOffsetGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &RINGVoltOffsetGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+//SVID and FIVR
+ //SVID Voltage Override
+ Len = sizeof(SVIDVoltOverrideGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &SVIDVoltOverrideGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ //SVID Control Enable/Disable
+ Len = sizeof(SVIDControlGaci);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &SVIDControlGaci, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if(gOcConfigData->IsPowerCycle)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)1); // Re-Enable SVID Control if cold boot
+ pBS->FreePool(Buffer);
+
+ //FIVR FAULTS DISABLE
+ Len = sizeof(FivrFaultsGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &FivrFaultsGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ if(gOcConfigData->IsPowerCycle)
+ Status = PerfTuneAslProtocol->SyncHwValue(Buffer, (UINT16)1); // Re-Enable FIVR FAULTS if cold boot
+ pBS->FreePool(Buffer);
+
+ //FIVR EFFICIENCY DISABLE
+ Len = sizeof(FivrEfficiencyGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &FivrEfficiencyGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+
+ pBS->FreePool(gCpuRatioLimitData);
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+ //Filter PLL
+ Len = sizeof(FilterPLLGaciData);
+ Buffer = MallocZ(Len);
+ if(!Buffer) return EFI_OUT_OF_RESOURCES;
+ MemCpy(Buffer, &FilterPLLGaciData, sizeof(GACI_DATA));
+ Status = PerfTuneAslProtocol->SetGaciData(Buffer, Len);
+ pBS->FreePool(Buffer);
+#endif
+
+ return EFI_SUCCESS;
+
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IntelXtuFillCpuDataCallBack
+//
+// Description: Callback function for Intel XTU data init
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IntelXtuFillCpuDataCallBack(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ EFI_GUID PerfTuneAslProtocolGuid = PERF_TUNE_ASL_PROTOCOL_GUID;
+ PERF_TUNE_ASL_PROTOCOL *PerfTuneAslProtocol = NULL;
+
+ TRACE((-1, "XTU Fill Cpu Data Callback\n"));
+
+ Status = pBS->LocateProtocol(&PerfTuneAslProtocolGuid, NULL, &PerfTuneAslProtocol);
+ if(!EFI_ERROR(Status))
+ FillXtuGaciData(PerfTuneAslProtocol);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CpuPllOverVoltageProgress
+//
+// Description: CPU pll over voltage initialize code in DXE phase
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPllOverVoltageProgress(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_GUID AmiPllOvFlagHobGuid = AMI_PLL_OVER_VOTAGE_FLAG_HOB_GUID;
+ EFI_GUID AmiPllOvFlagDataGuid = AmiPllOvFlagHobGuid;
+ EFI_GUID gHobListGuid = HOB_LIST_GUID;
+ PLL_OV_FLAG_DATA_HOB *PllOvFlagDataHob;
+ UINT64 CoreRatioLimits = ReadMsr(0x1ad);
+ EFI_STATUS Status = EFI_NOT_STARTED;
+ VOID *FirstHob;
+ PERF_TUNE_WDT_PROTOCOL *InternalWdtProtocol;
+
+ TRACE((-1,"CpuPllOverVoltageProgress Start\n"));
+
+ // Get Hob List
+ FirstHob = GetEfiConfigurationTable(pST, &gHobListGuid);
+ if (!FirstHob) return EFI_NOT_READY;
+
+ PllOvFlagDataHob = (PLL_OV_FLAG_DATA_HOB*)FirstHob;
+
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION,&PllOvFlagDataHob))) {
+ if (guidcmp(&PllOvFlagDataHob->EfiHobGuidType.Name,&AmiPllOvFlagHobGuid) == 0) break;
+ }
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ Status = EFI_ALREADY_STARTED;
+
+ if((PllOvFlagDataHob->PllOvData.PLLOvFlag == 0x1) && (CoreRatioLimits = 0x060606))
+ {
+ //Delay for 1.5 ms
+ pBS->Stall(150);
+
+ PllOvFlagDataHob->PllOvData.PLLOvFlag = 0x2;
+
+ //write back original Core Ratio Limits.
+ WriteMsr(0x1ad, PllOvFlagDataHob->PllOvData.OriTurboRatio);
+
+ Status = pRS->SetVariable(
+ L"PLLOvFlag",
+ &AmiPllOvFlagDataGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(PLL_OV_FLAG_DATA),
+ &PllOvFlagDataHob->PllOvData
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&InternalWdtGuid, NULL, &InternalWdtProtocol);
+ if(!EFI_ERROR(Status))
+ {
+ TRACE((-1,"Internal PLL Over Voltage Reset Requirement.\n"));
+ //reset
+ InternalWdtProtocol->AllowKnownReset();
+ IoWrite8 (0xCF9,0x02);
+ IoWrite8 (0xCF9,0x06);
+ EFI_DEADLOOP();
+ }
+ }else if(PllOvFlagDataHob->PllOvData.PLLOvFlag== 0x2) {
+ //Clear Flag to Zero
+ PllOvFlagDataHob->PllOvData.PLLOvFlag = 0x0;
+ Status = pRS->SetVariable(
+ L"PLLOvFlag",
+ &AmiPllOvFlagDataGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(PLL_OV_FLAG_DATA),
+ &PllOvFlagDataHob->PllOvData
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((-1,"Clear Pll Overvoltage Flag %r.\n",Status));
+ }
+
+ TRACE((-1,"CpuPllOverVoltageProgress End\n"));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveMEFWVersion
+//
+// Description: CPU pll over voltage initialize code in DXE phase
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveMEFWVersion(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ ME_INFO_SETUP_DATA MeInfoSetupData;
+ UINTN DataSize = sizeof(ME_INFO_SETUP_DATA);
+
+ TRACE((-1,"SaveMEFWVersion start!!\n"));
+
+ pBS->CloseEvent( Event);
+ Status = pRS->GetVariable(
+ L"MeInfoSetup",
+ &gMeSetupInfoGuid,
+ NULL,
+ &DataSize,
+ &MeInfoSetupData
+ );
+ if(EFI_ERROR(Status)){
+ TRACE((-1,"Get ME firmware version fail!!\n"));
+ return Status;
+ }
+
+ Status = pRS->SetVariable(
+ L"MEFWVersion",
+ &gAmiCpuMEFwVerGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(ME_INFO_SETUP_DATA),
+ &MeInfoSetupData
+ );
+ if(EFI_ERROR(Status)){
+ TRACE((-1,"Set ME firmware version fail!!\n"));
+ return Status;
+ }
+
+ TRACE((-1,"SaveMEFWVersion end!!\n"));
+
+ return Status;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuDxeMiscFuncs
+//
+// Description:
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CpuDxeMiscFuncs(VOID)
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+#if PERF_TUNE_SUPPORT == 1
+ {
+
+ EFI_GUID PerfTuneAslProtocolGuid = PERF_TUNE_ASL_PROTOCOL_GUID;
+ EFI_EVENT IntelXtuCpuCallbackEvt;
+ VOID *IntelXtuCpuCallbackReg;
+ VOID *FirstHob;
+ EFI_EVENT PllOvCallbackEvt;
+ VOID *PllOvCallbackReg;
+ EFI_EVENT MEFWCallbackEvt;
+ VOID *MEFWCallbackReg;
+ EFI_GUID gAmiPerfTuneDataHobGuid = AMI_PERF_TUNE_DATA_HOB_GUID;
+ EFI_GUID gAmiOcConfigHobGuid = AMI_OVERCLOCK_CONFIG_HOB_GUID;
+ UINTN DataSize;
+ OVERCLOCKING_CONFIG_HOB *OcConfigHob = NULL;
+ CPU_RATIO_LIMIT_HOB *CpuRatioLimitHob = NULL;
+ UINT32 Attributes = 0;
+
+ FirstHob = GetEfiConfigurationTable(pST, &gHobListGuid);
+
+ //If First boot or CPU change is detected, record new MaxNonTurboRatio.
+ CpuRatioLimitHob = (CPU_RATIO_LIMIT_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &CpuRatioLimitHob))) {
+ if (guidcmp(&CpuRatioLimitHob->EfiHobGuidType.Name, &gAmiCpuRatioLimitHobGuid) == 0){
+ if(CpuRatioLimitHob->IsChangeCpu){
+ Status = pRS->SetVariable(
+ L"CpuRatioLimit",
+ &gAmiCpuRatioLimitHobGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE),
+ sizeof(CPU_RATIO_LIMIT_DATA),
+ &CpuRatioLimitHob->CpuRatioLimitData );
+ ASSERT_EFI_ERROR(Status);
+ }
+ break;
+ }
+ }
+
+ // get TdcTdpHob.
+ gTdcTdpHob = (AMI_INTERNAL_FACTORY_TDC_TDP_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &gTdcTdpHob))) {
+ if (guidcmp(&gTdcTdpHob->EfiHobGuidType.Name, &gAmiInternalFactoryTdcTdpHobGuid) == 0){
+
+ Status = RegisterProtocolCallback(
+ &PerfTuneAslProtocolGuid,
+ IntelXtuFillCpuDataCallBack,
+ NULL,
+ &IntelXtuCpuCallbackEvt,
+ &IntelXtuCpuCallbackReg
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ break;
+ }
+ }
+ if(!EFI_ERROR(Status)){
+ // get overclocking config HOB
+ OcConfigHob = (OVERCLOCKING_CONFIG_HOB*)FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OcConfigHob))) {
+ if (guidcmp(&OcConfigHob->EfiHobGuidType.Name, &gAmiOcConfigHobGuid) == 0){
+ break;
+ }
+ }
+ gOcConfigData = NULL;
+ if(!EFI_ERROR(Status))
+ gOcConfigData = &OcConfigHob->OverclockData;
+ else
+ ASSERT_EFI_ERROR(Status);
+
+ // get Cpu ratio limit default value.
+ DataSize = sizeof(CPU_RATIO_LIMIT_DATA);
+ Status = pBS->AllocatePool(EfiBootServicesData, DataSize, &gCpuRatioLimitData);
+ Status = pRS->GetVariable(
+ L"CpuRatioLimit",
+ &gAmiCpuRatioLimitHobGuid,
+ NULL,
+ &DataSize,
+ gCpuRatioLimitData );
+ ASSERT_EFI_ERROR(Status);
+
+ // Restores default value when Cpu change or watch dog timeout.
+ if( gOcConfigData->IsCpuRunDefault ){
+ SETUP_DATA *SetupData;
+ DataSize = sizeof(SETUP_DATA);
+ Status = pBS->AllocatePool(EfiBootServicesData, DataSize, &SetupData);
+ Status = pRS->GetVariable(
+ L"Setup",
+ &gSetupGuid,
+ &Attributes,
+ &DataSize,
+ SetupData
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ SetupData->LcSbSelect = 0;
+ SetupData->PackageCurrentLock = 0;
+
+ Status = pRS->SetVariable(
+ L"Setup",
+ &gSetupGuid,
+ Attributes,
+ sizeof(SETUP_DATA),
+ SetupData
+ );
+ ASSERT_EFI_ERROR(Status);
+ pBS->FreePool(SetupData);
+ }
+
+ // get current setting data of XTU
+ DataSize = sizeof(BIOS_SETTING_DATA);
+ Status = pBS->AllocatePool(EfiBootServicesData, DataSize, &gBiosSettingData);
+ Status = pRS->GetVariable(
+ L"OcCurrent",
+ &gSetupGuid,
+ NULL,
+ &DataSize,
+ gBiosSettingData);
+ }
+
+ Status = RegisterProtocolCallback(
+ &InternalWdtGuid,
+ CpuPllOverVoltageProgress,
+ NULL,
+ &PllOvCallbackEvt,
+ &PllOvCallbackReg );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = RegisterProtocolCallback(
+ &gDxePlatformMePolicyGuid,
+ SaveMEFWVersion,
+ NULL,
+ &MEFWCallbackEvt,
+ &MEFWCallbackReg);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ NumberOfPStatesSupport();
+
+ return;
+}
diff --git a/Core/CPU/CpuPei.c b/Core/CPU/CpuPei.c
new file mode 100644
index 0000000..901171b
--- /dev/null
+++ b/Core/CPU/CpuPei.c
@@ -0,0 +1,936 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.c 9 8/05/14 2:21a Crystallee $
+//
+// $Revision: 9 $
+//
+// $Date: 8/05/14 2:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.c $
+//
+// 9 8/05/14 2:21a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] For backward compatible, add old MTRR setting method
+// back. Change new MTRR setting method to Policy2.
+//
+// 8 7/16/14 4:12a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add WbMemMap and UcMemMap vectors size to prevent
+// accessing out of bound.
+//
+// 7 7/08/14 3:35a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add all the possible methods to describing memory in
+// MTRRS.
+// [Files] CpuPei.c, CpuPei.h, CpuPeiFuncs.c
+//
+// 6 6/25/14 2:15a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Add APIC version information in CpuInfoHob
+//
+// 5 6/13/14 2:22a Davidhsieh
+// [TAG] EIP173454
+// [Category] Improvement
+// [Description] Add TSEG address and size in CpuInfoHob
+//
+// 4 9/05/12 1:40a Davidhsieh
+// Rename PEI_IFFS_TRANSITION_START_PPI_GUID to
+// PEI_RAPID_START_TRANSITION_START_PPI_GUID
+//
+// 3 3/16/12 3:11a Davidhsieh
+// Setup items create for CPU RC policy
+//
+// 2 3/09/12 2:13a Davidhsieh
+// Create BIST data
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuPei.c
+//
+// Description:
+// This file is the main CPU PEI component file. This component utilizes
+// CPU I/O & PCI CFG PPI to publish early CPU Init PPI which can be used
+// by NB PEI to load itself. Also this file contains a CPU init routine
+// to be executed in permanent memory present environment. This is handled
+// by issuing a notifyPPI on permanent memory PPI.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "cpu.h"
+#include "AmiCspLibInc.h"
+#include <AmiPeiLib.h>
+#include <core\PeiHob.h>
+#include <token.h>
+#include <Ppi\ReadOnlyVariable.h>
+#include "CpuPei.h"
+
+#define EFI_HT_BIST_HOB_GUID \
+ { \
+ 0xbe644001, 0xe7d4, 0x48b1, 0xb0, 0x96, 0x8b, 0xa0, 0x47, 0xbc, 0x7a, 0xe7 \
+ }
+
+typedef struct _CPU_BIST_HOB {
+ EFI_HOB_GENERIC_HEADER Header;
+ EFI_GUID Name;
+ UINT32 ApicId;
+ UINT32 BIST;
+} CPU_BIST_HOB;
+
+// Setup GUID variables for installing, locating and notifying PPIs
+EFI_GUID gPeiCachePpiGuid = PEI_CACHE_PPI_GUID;
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+EFI_GUID gAmiCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID;
+EFI_GUID gEfiPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+EFI_GUID gAmiInternaluCodeHobGuid = AMI_INTERNAL_UCODE_HOB_GUID;
+EFI_GUID gSmmHobGuid = SMM_HOB_GUID;
+EFI_GUID gPeiRapidStartTransitionStartPpiGuid = PEI_RAPID_START_TRANSITION_START_PPI_GUID;
+//EFI_GUID gCacheInstallGuid = EFI_CACHE_INSTALL_PPI_GUID;
+EFI_GUID gAmiStatusCodeCpuBistDataGuid = AMI_STATUS_CODE_CPU_BIST_DATA_GUID;
+EFI_GUID gEfiHtBistHobGuid = EFI_HT_BIST_HOB_GUID;
+
+EFI_STATUS NotifyAtPeiEnd (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+);
+
+EFI_PEI_NOTIFY_DESCRIPTOR CpuNotifyDescs = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ NotifyAtPeiEnd
+};
+
+/*EFI_PEI_PPI_DESCRIPTOR CacheInstallPpi[] = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gCacheInstallGuid,
+ NULL
+};*/
+
+EFI_PEI_PPI_DESCRIPTOR IffsTransitionStartPpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), \
+ &gPeiRapidStartTransitionStartPpiGuid,
+ NULL
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReportBistStatusCodes
+//
+// Description: Report the BIST Status Code.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ReportBistStatusCodes(IN EFI_PEI_SERVICES **PeiServices, IN CPUINFO_HOB *CpuInfoHob, IN UINT32 NumCpus)
+{
+ UINT32 i;
+ AMI_STATUS_CODE_CPU_BIST_DATA BistData;
+
+ BistData.DataHeader.HeaderSize = sizeof(EFI_STATUS_CODE_DATA);
+ BistData.DataHeader.Size = sizeof(UINT32);
+ MemCpy(&BistData.DataHeader.Type, &gAmiStatusCodeCpuBistDataGuid, sizeof(EFI_GUID));
+
+ for (i = 0; i < NumCpus; ++i) {
+ if (CpuInfoHob->Cpuinfo[i].BIST != 0) {
+ PEI_TRACE((-1, PeiServices, "CpuInfo[%x].BIST = %x \n", i, CpuInfoHob->Cpuinfo[i].BIST));
+ BistData.Bist = CpuInfoHob->Cpuinfo[i].BIST;
+
+ (*PeiServices)->ReportStatusCode(
+ PeiServices,
+ EFI_ERROR_CODE| EFI_ERROR_MAJOR,
+ PEI_CPU_SELF_TEST_FAILED,
+ CpuInfoHob->Cpuinfo[i].ApicId,
+ NULL,
+ (EFI_STATUS_CODE_DATA*)&BistData
+ );
+ }
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateCpuHobWithDefaults
+//
+// Description: Create CPU Hob and fill in default data.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN UINT8 NumCpus
+//
+// Output:
+// CPUINFO_HOB *
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CPUINFO_HOB * CreateCpuHobWithDefaults(EFI_PEI_SERVICES **PeiServices, UINT8 NumCpus)
+{
+ CPUINFO_HOB *CpuinfoHob;
+ EFI_STATUS Status;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ UINT8 i;
+ VOID *FirstHob;
+ CPU_BIST_HOB *SecBistHob;
+
+ //Create hob for storing Cpu Data
+ Status = (**PeiServices).CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ //NOTE: sizeof(CPUINFO_HOB) already includes size of one CPUINFO structure
+ sizeof(CPUINFO_HOB) + (NumCpus - 1) * sizeof(CPUINFO),
+ &CpuinfoHob
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ CpuinfoHob->EfiHobGuidType.Name = gAmiCpuinfoHobGuid;
+ CpuinfoHob->CpuCount = NumCpus;
+ CpuinfoHob->NodeCount = NUMBER_CPU_SOCKETS;
+ CpuinfoHob->CacheLineSize = 64;
+
+ CpuinfoHob->TsegAddress = NBGetTsegBase();
+ CpuinfoHob->TsegSize = TSEG_SIZE;
+
+
+ for(i = 0; i < NumCpus; ++i) {
+ CpuinfoHob->Cpuinfo[i].Valid = FALSE;
+ CpuinfoHob->Cpuinfo[i].Disabled = FALSE;
+ CpuinfoHob->Cpuinfo[i].BIST = 0;
+ CpuinfoHob->Cpuinfo[i].ApicVer = (UINT8)MemRead32((UINT32*)(UINTN)(LOCAL_APIC_BASE + APIC_VERSION_REGISTER));
+ }
+//Save BSP features to CpuinfoHob
+ CPULib_CpuID(0x01, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ CpuinfoHob->CpuFeatures.FeatureEcx = RegEcx;
+ CpuinfoHob->CpuFeatures.FeatureEdx = RegEdx;
+
+ CPULib_CpuID(0x80000001, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ CpuinfoHob->CpuFeatures.ExtFeatureEax = RegEax;
+ CpuinfoHob->CpuFeatures.ExtFeatureEbx = RegEbx;
+ CpuinfoHob->CpuFeatures.ExtFeatureEcx = RegEcx;
+ CpuinfoHob->CpuFeatures.ExtFeatureEdx = RegEdx;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ (VOID*)SecBistHob = FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &SecBistHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)SecBistHob)->Name, &gEfiHtBistHobGuid) == 0) {
+ break;
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ CpuinfoHob->Cpuinfo[SecBistHob->ApicId].BIST = SecBistHob->BIST;
+ }
+
+ return CpuinfoHob;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: UpdateOrCreateCpuHob
+//
+// Description: Finds or Create Cpu Hob and initialize it.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UpdateOrCreateCpuHob(EFI_PEI_SERVICES **PeiServices)
+{
+ VOID *FirstHob;
+ EFI_HOB_CPU *CpuHob;
+ UINT32 RegEax;
+ UINT32 RegEbx;
+ UINT32 RegEcx;
+ UINT32 RegEdx;
+ EFI_STATUS Status;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ CpuHob = (EFI_HOB_CPU*) FirstHob;
+ Status = FindNextHobByType(EFI_HOB_TYPE_CPU, &CpuHob);
+ if (EFI_ERROR(Status)) {
+ Status = (**PeiServices).CreateHob(PeiServices,
+ EFI_HOB_TYPE_CPU,
+ sizeof(CpuHob),
+ &CpuHob
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ CpuHob->SizeOfMemorySpace = 0xff;
+ MemSet(CpuHob->Reserved, 6, 0);
+ }
+
+ CPULib_CpuID(0x80000008, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ RegEax &= 0xff;
+ if (RegEax < CpuHob->SizeOfMemorySpace) CpuHob->SizeOfMemorySpace = RegEax;
+ CpuHob->SizeOfIoSpace = 16;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: NotifyAtPeiEnd
+//
+// Description: According to resource descriptor HOBs to config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor
+// IN VOID *Ppi
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotifyAtPeiEnd (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+)
+{
+ EFI_STATUS Status;
+ PEI_CACHE_PPI *CachePpi;
+ UINT64 MaxMemoryLength;
+ EFI_BOOT_MODE BootMode;
+
+#if MTRR_POLICY == 1
+ EFI_PEI_HOB_POINTERS Hob;
+ UINT64 Above4GMemoryLength = 0;
+ MEMORY_MAP WbMemMap[12]; //Memory map of wb regions.
+ MEMORY_MAP UcMemMap[12]; //Memory map of uc regions.
+ UINTN i;
+#endif
+ //
+ //Get bootmode
+ //
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ PEI_TRACE((-1, PeiServices, "CPUPEI Get boot mode in end of PEI\n"));
+
+ if (BootMode == BOOT_ON_S3_RESUME){
+ PEI_TRACE((-1, PeiServices, "CPUPEI boot mode is S3 in end of PEI\n"));
+ //Trigger SWSMI to save CPU fixed & varible MTRRs
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_RESTORE_MSR);
+ IoWrite8(SW_SMI_IO_ADDRESS, SW_SMI_S3_RESTORE_MSR_FROM_SDL);
+ }else{
+ //
+ // Load Cache PPI
+ //
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiCachePpiGuid,
+ 0,
+ NULL,
+ &CachePpi
+ ) ;
+ ASSERT_PEI_ERROR (PeiServices, Status);
+#if MTRR_POLICY == 1
+ //if MTRR_POLICY = 1, init MTRR above4G here
+ Above4GMemoryLength = 0;
+ (*PeiServices)->GetHobList(PeiServices, &Hob.Raw);
+ //Get above 4G memory length
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+ ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
+ ) {
+ if (Hob.ResourceDescriptor->PhysicalStart >= SIZE_4G
+ && Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ Above4GMemoryLength += (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ //
+ // Program the MTRR for above 4G memory range if it exist
+ // or just disable cache flash range
+ //
+ if (Above4GMemoryLength > 0) {
+ Status = InitMtrrPolicy1(PeiServices, WbMemMap, UcMemMap, Above4GMemoryLength);
+ if(EFI_ERROR(Status))
+ Status = InitMtrrPolicy2(PeiServices, WbMemMap, UcMemMap, Above4GMemoryLength);
+
+ //If cache map init successful, start program MTRR
+ if(!EFI_ERROR(Status)){
+ CachePpi->ResetCache(
+ PeiServices,
+ CachePpi);
+ //WB region start first
+ for(i = 0; i < 10 ;i++){
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ WbMemMap[i].Base,
+ WbMemMap[i].Len,
+ EfiCacheTypeWriteBack);
+ if(WbMemMap[i + 1].Len == 0) break;
+ }
+ //UC region start
+ if(UcMemMap[0].Len != 0){
+ for(i = 0; i < 10 ;i++){
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ UcMemMap[i].Base,
+ UcMemMap[i].Len,
+ EfiCacheTypeUncacheable);
+ if(UcMemMap[i + 1].Len == 0) break;
+ }
+ }
+ //
+ // Programm fix MTRRs WB from 0 to A0000
+ //
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ 0,
+ 640*1024,
+ EfiCacheTypeWriteBack );
+ } else{ //Get MTRR setting fail, still need disable cache flash range
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeUncacheable
+ );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Disabling Flash Area Cache Error!!\n"));
+ }
+ } else{ // if (Above4GMemoryLength > 0)
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeUncacheable
+ );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Disabling Flash Area Cache Error!!\n"));
+ }
+ //
+ //Disable NEM, Update MTRR setting from MTRR buffer
+ //
+ CachePpi->ActivateCache (PeiServices, CachePpi);
+#else
+ //
+ // MTRR for above 4G memory range is already done at this point,
+ // only disable cache flash range is required
+ //
+
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeUncacheable );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Disabling Flash Area Cache Error!!\n"));
+
+ //
+ //Disable NEM, Update MTRR setting from MTRR buffer
+ //
+ CachePpi->ActivateCache (PeiServices, CachePpi);
+#endif
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: SetupCache
+//
+// Description: According to resource descriptor HOBs to config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_BOOT_MODE BootMode
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetupCache ( IN EFI_PEI_SERVICES **PeiServices, IN EFI_BOOT_MODE BootMode)
+{
+ EFI_STATUS Status;
+ PEI_CACHE_PPI *CachePpi;
+ UINT64 MemoryLength;
+ UINT64 MemoryLengthUc;
+ UINT64 MaxMemoryLength;
+ UINT64 CurrentBaseAddress;
+ UINT64 Above4GMemoryLength;
+ UINT64 PowerTwo;
+ UINT64 PowerTwoEnd;
+ UINT8 MtrrCount = 0;
+#if MTRR_POLICY == 0
+ EFI_PEI_HOB_POINTERS Hob;
+#endif
+ //
+ // Load Cache PPI
+ //
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiCachePpiGuid,
+ 0,
+ NULL,
+ &CachePpi
+ ) ;
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //
+ // Clear the CAR Settings
+ //
+ CachePpi->ResetCache(
+ PeiServices,
+ CachePpi
+ );
+
+
+ //
+ // Parse the HOB list and determine the amount of memory installed
+ // The first 1MB will be set until overridden by the CSM.
+ // The above 4G memory length will be calculated separately.
+ //
+
+ MemoryLength = SIZE_1M;
+ Above4GMemoryLength = 0;
+
+ MemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ PEI_TRACE((-1, PeiServices, "Memory Length below 4G= %lx.\n", MemoryLength));
+
+ //
+ // Record the current address
+ //
+ CurrentBaseAddress = 0;
+ //
+ // Set WB loop first
+ //
+
+ for (PowerTwo = SIZE_2G, PowerTwoEnd = SIZE_64M; PowerTwo >= PowerTwoEnd; PowerTwo = Shr64 (PowerTwo, 1)) {
+ if (MemoryLength >= PowerTwo && MtrrCount < 8) {
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", PowerTwo, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, PowerTwo, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ CurrentBaseAddress += PowerTwo;
+ MemoryLength -= PowerTwo;
+ }
+ }
+ //
+ // Get Max Address for WB/UC
+ //
+ if (MemoryLength == GetPowerOfTwo64 (MemoryLength)) {
+ MaxMemoryLength = MemoryLength;
+ } else {
+ MaxMemoryLength = GetPowerOfTwo64 (Shl64 (MemoryLength, 1));
+ }
+ //
+ // Set the MAX memory range as WB
+ //
+ if (MaxMemoryLength != 0 && MtrrCount < 8) {
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", MaxMemoryLength, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, MaxMemoryLength, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ }
+ //
+ // Start Setting UC here
+ //
+ while (MaxMemoryLength != MemoryLength) {
+ if (MtrrCount == 8) break;
+ MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - MemoryLength);
+ PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx.\n", MemoryLengthUc, CurrentBaseAddress + MaxMemoryLength - MemoryLengthUc));
+ CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ CurrentBaseAddress + MaxMemoryLength - MemoryLengthUc,
+ MemoryLengthUc,
+ EfiCacheTypeUncacheable
+ );
+ MtrrCount++;
+ MaxMemoryLength -= MemoryLengthUc;
+ }
+
+#if MTRR_POLICY == 0
+ //
+ // Program the MTRR for above 4G memory range
+ // if MTRR_POLICY = 1, program the MTRR for above 4G memory range at end of PEI
+ //
+ if (BootMode != BOOT_ON_S3_RESUME){
+ (*PeiServices)->GetHobList(PeiServices, &Hob.Raw);
+ while (!END_OF_HOB_LIST (Hob)) {
+ if (Hob.Header->HobType == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
+ if ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) ||
+ ((Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_MEMORY_RESERVED))
+ ) {
+ //
+ // Calculate the memory above 4G
+ //
+ if (Hob.ResourceDescriptor->PhysicalStart >= SIZE_4G
+ && Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {
+ Above4GMemoryLength += (Hob.ResourceDescriptor->ResourceLength);
+ }
+ }
+ }
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ }
+ }
+ PEI_TRACE((-1, PeiServices, "Memory Length Above 4G= %lx.\n", Above4GMemoryLength));
+ if (Above4GMemoryLength > 0) {
+ CurrentBaseAddress = SIZE_4G;
+ while (Above4GMemoryLength >= SIZE_4G) {
+ if (MtrrCount == 10) break;
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", SIZE_4G, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, SIZE_4G, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ Above4GMemoryLength -= SIZE_4G;
+ CurrentBaseAddress += SIZE_4G;
+ }
+ //
+ // Set WB loop first
+ //
+ for (PowerTwo = SIZE_2G, PowerTwoEnd = SIZE_256M; PowerTwo >= PowerTwoEnd; PowerTwo = Shr64 (PowerTwo, 1)) {
+ if (MtrrCount == 10) break;
+ if (Above4GMemoryLength >= PowerTwo) {
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", PowerTwo, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, PowerTwo, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ CurrentBaseAddress += PowerTwo;
+ Above4GMemoryLength -= PowerTwo;
+ }
+ }
+ //
+ // Get Max Address for WB/UC
+ //
+ if (Above4GMemoryLength == GetPowerOfTwo64 (Above4GMemoryLength)) {
+ MaxMemoryLength = Above4GMemoryLength;
+ } else {
+ MaxMemoryLength = GetPowerOfTwo64 (Shl64(Above4GMemoryLength, 1));
+ }
+ //
+ // Set the MAX memory range as WB
+ //
+ if (MaxMemoryLength != 0 && MtrrCount < 10) {
+ //PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx.\n", MaxMemoryLength, CurrentBaseAddress));
+ CachePpi->SetCache (PeiServices, CachePpi, CurrentBaseAddress, MaxMemoryLength, EfiCacheTypeWriteBack);
+ MtrrCount++;
+ }
+ //
+ // Start Setting UC here
+ //
+ while (MaxMemoryLength != Above4GMemoryLength) {
+ if (MtrrCount == 10) break;
+ MemoryLengthUc = GetPowerOfTwo64 (MaxMemoryLength - Above4GMemoryLength);
+ if (MtrrCount == 9 && (MaxMemoryLength - Above4GMemoryLength) != MemoryLengthUc) {
+ MemoryLengthUc = Shl64 (MemoryLengthUc, 1);
+ }
+ PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx.\n", MemoryLengthUc, CurrentBaseAddress + MaxMemoryLength - MemoryLengthUc));
+ CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (CurrentBaseAddress+ MaxMemoryLength - MemoryLengthUc),
+ MemoryLengthUc,
+ EfiCacheTypeUncacheable
+ );
+ MtrrCount++;
+ MaxMemoryLength -= MemoryLengthUc;
+ }
+ }
+#endif
+ //
+ // Programm fix MTRRs WB from 0 to A0000
+ //
+ PEI_TRACE((-1, PeiServices, "WB Memory Length = %08x at %09x.\n", 640*1024, 0));
+ CachePpi->SetCache(
+ PeiServices,
+ CachePpi,
+ 0,
+ 640*1024,
+ EfiCacheTypeWriteBack
+ );
+
+#if PEI_CACHE_FLASH_ENABLED
+ //
+ // Cache Flash Area
+ //
+ MaxMemoryLength = GetPowerOfTwo64 (FLASH_SIZE);
+ if (MaxMemoryLength < FLASH_SIZE) {
+ MaxMemoryLength = Shl64 (MaxMemoryLength, 1);
+ }
+
+ PEI_TRACE((-1, PeiServices, "WP Memory Length = %08lx at %09lx.\n", MaxMemoryLength, (SIZE_4G - MaxMemoryLength)));
+ Status = CachePpi->SetCache (
+ PeiServices,
+ CachePpi,
+ (SIZE_4G - MaxMemoryLength),
+ MaxMemoryLength,
+ EfiCacheTypeWriteProtected
+ );
+
+ if (Status) PEI_TRACE((-1, PeiServices, "Flash Area Caching Error!!\n"));
+#endif
+ //
+ //Disable NEM, Update MTRR setting from MTRR buffer
+ //
+ CachePpi->ActivateCache (PeiServices, CachePpi);
+
+ //Call back to disable caching flash at end of PEI.
+ (*PeiServices)->NotifyPpi(
+ PeiServices,
+ &CpuNotifyDescs
+ );
+ //
+ // Install EFI_CACHE_INSTALL_PPI_GUID to indicate memory and CPU cache are initialzed.
+ //
+ /*Status = (*PeiServices)->InstallPpi (
+ PeiServices,
+ CacheInstallPpi);
+ ASSERT_PEI_ERROR(PeiServices, Status);*/
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CpuPeiEntry
+//
+// Description: AMI CPU PEI driver entry
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable;
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+ CPUINFO_HOB *CpuinfoHob;
+ UINT32 NumCpus;
+ BOOLEAN X2ApicEnabled = FALSE;
+ BOOLEAN Serialize = FALSE;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ VOID *MicrocodeAddr = NULL;
+ UINT32 MicrocodeSize = 0;
+ EFI_PHYSICAL_ADDRESS MicrocodeBuffer;
+ AMI_INTERNAL_UCODE_HOB *uCodeHob;
+ UINT32 Tseg = (UINT32)NBGetTsegBase();
+ SMM_HOB *SmmHob;
+ UINT32 SmmBspBase;
+ UINT32 SmmCpuBase;
+ UINT32 SmmBase;
+ UINT32 LargestSmmBase;
+ UINT32 MaxCpusBeforeOverlap;
+ UINT32 BeforeOverlapCount;
+ UINT32 NextUnoverlapSmmBase;
+ UINT32 i;
+
+ PEI_PROGRESS_CODE(PeiServices, PEI_CPU_INIT);
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices, &gEfiPeiReadOnlyVariablePpiGuid, 0, NULL, &ReadOnlyVariable
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ SetupCache(PeiServices, BootMode);
+ UpdateOrCreateCpuHob(PeiServices);
+
+ Status = (*PeiServices)->InstallPpi( PeiServices, \
+ &IffsTransitionStartPpiDescriptor);
+
+ //After initialized, APs are in holding loop until halted.
+ NumCpus = (UINT32)((UINT8)ReadMsr(MSR_CORE_THREAD_COUNT));
+
+ PEI_TRACE((-1, PeiServices, "Cpu Pei - number of Cpus %x\n",NumCpus ));
+ CpuinfoHob = CreateCpuHobWithDefaults(PeiServices, NumCpus);
+
+ CpuinfoHob->BspNo = 0;
+
+ ReportBistStatusCodes(PeiServices, CpuinfoHob, NumCpus);
+ //Create Smm Hob
+ Status = (*PeiServices)->CreateHob(
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(SMM_HOB)+ (NumCpus - 1) * sizeof(VOID*),
+ &SmmHob
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ MemCpy(&SmmHob->EfiHobGuidType.Name, &gSmmHobGuid, sizeof(EFI_GUID));
+
+ SmmHob->Tseg = Tseg;
+ SmmHob->TsegLength = TSEG_SIZE;
+ PEI_ASSERT(PeiServices, (SmmHob->Tseg & 0x7fffff)==0); //Must be 8MB boundary.
+ PEI_ASSERT(PeiServices, TSEG_SIZE >= 0x800000); //Must be >= 8MB.
+
+ SmmHob->IedStart = Tseg + TSEG_SIZE - IED_SIZE;
+ SmmHob->IedSize = IED_SIZE;
+
+ SmmHob->NumCpus = NumCpus;
+ SmmHob->Bsp = 0;
+
+ SmmBspBase = (UINTN)Tseg - 0x8000; //Get bottom of TSEG - 0x8000
+ SmmBase = SmmBspBase + MAX_SMM_SAVE_STATE_SIZE;
+
+ MaxCpusBeforeOverlap = 0x8000 / MAX_SMM_SAVE_STATE_SIZE - 1;
+ BeforeOverlapCount = 0;
+ NextUnoverlapSmmBase = (UINTN)Tseg - 0x8000 + 0x10000 - 2 * MAX_SMM_SAVE_STATE_SIZE;
+ LargestSmmBase = 0;
+
+ for (i = 0; i < NumCpus; ++i)
+ {
+ if (i == SmmHob->Bsp)
+ {
+ SmmCpuBase = SmmBspBase;
+ if (SmmCpuBase >= ((UINTN)Tseg - 0x8000)) ++BeforeOverlapCount; //Only increment count if BSP in TSEG.
+ }
+ else
+ {
+ SmmCpuBase = SmmBase;
+ ++BeforeOverlapCount;
+ if (BeforeOverlapCount < MaxCpusBeforeOverlap)
+ {
+ SmmBase += MAX_SMM_SAVE_STATE_SIZE;
+ }
+ else
+ {
+ SmmBase = NextUnoverlapSmmBase;
+ NextUnoverlapSmmBase += 0x10000 - 2 * MAX_SMM_SAVE_STATE_SIZE;
+ BeforeOverlapCount = 0;
+ }
+ }
+
+ SmmHob->SmmBase[i] = SmmCpuBase;
+
+ if (SmmCpuBase > LargestSmmBase) LargestSmmBase = SmmCpuBase;
+ }
+
+ if (LargestSmmBase < 0xC0000)
+ SmmHob->ManagedMemStart = Tseg;
+ else
+ SmmHob->ManagedMemStart = LargestSmmBase + 0x10000; //+ 0x10000 = end of save state.
+
+ SmmHob->ManagedMemSize = Tseg + TSEG_SIZE - SmmHob->ManagedMemStart;
+ SmmHob->ManagedMemSize -= SmmHob->IedSize;
+
+ PEI_TRACE((-1, PeiServices, "TSEG Base %x\n", SmmHob->Tseg));
+ PEI_TRACE((-1, PeiServices, "TSEG Size %x\n", SmmHob->TsegLength));
+ PEI_TRACE((-1, PeiServices, "ManagedMemStart %x\n", SmmHob->ManagedMemStart));
+
+ if (BootMode != BOOT_ON_S3_RESUME){
+ //Copy CPU microcode from ROM to RAM, when flash ragne is still cached
+ //and create hob to record the microcode address
+ //Create CPU microcode HOB
+ MicrocodeAddr = CPULib_FindMicrocode();
+
+ if(MicrocodeAddr != NULL){
+ PEI_TRACE((-1, PeiServices, "Cpu uCode ID - %x\n",((MICROCODE_HEADER*)MicrocodeAddr)->CpuSignature ));
+ MicrocodeSize = ((MICROCODE_HEADER*)MicrocodeAddr)->TotalSize;
+
+ Status = (*PeiServices)->AllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES (MicrocodeSize),
+ &MicrocodeBuffer );
+ if(!EFI_ERROR(Status)){
+ // Copy Microcode from ROM to RAM
+ (*PeiServices)->CopyMem (
+ (VOID*)MicrocodeBuffer,
+ (VOID*)MicrocodeAddr,
+ (UINTN)MicrocodeSize );
+
+ Status = (*PeiServices)->CreateHob(
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(AMI_INTERNAL_UCODE_HOB),
+ &uCodeHob );
+ if (!EFI_ERROR(Status)){
+ MemCpy(&uCodeHob->EfiHobGuidType.Name, &gAmiInternaluCodeHobGuid, sizeof(EFI_GUID));
+ uCodeHob->uCodeAddr = (UINT32)MicrocodeBuffer;
+ }
+ }
+ }
+ }
+
+ CpuPeiMiscFuncs(PeiServices, ReadOnlyVariable, BootMode);
+
+ return EFI_SUCCESS;
+
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuPei.dxs b/Core/CPU/CpuPei.dxs
new file mode 100644
index 0000000..ba054a4
--- /dev/null
+++ b/Core/CPU/CpuPei.dxs
@@ -0,0 +1,65 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.dxs 1 2/07/12 3:58a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:58a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.dxs $
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CPUPEI.dxs
+//
+// Description: Dependency expression for CPU PEI component.
+// Currently it is dependent on the CPU IO & PCI CFG PPI.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <pei.h>
+#include <ppi\CpuIo.h>
+#include <ppi\PciCfg.h>
+#include <Ppi\ReadOnlyVariable.h>
+
+DEPENDENCY_START
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI AND
+ EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI AND
+ EFI_PEI_CPU_IO_PPI_INSTALLED_GUID AND
+ EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID AND
+ EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuPei.h b/Core/CPU/CpuPei.h
new file mode 100644
index 0000000..b004293
--- /dev/null
+++ b/Core/CPU/CpuPei.h
@@ -0,0 +1,206 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.h 4 8/05/14 2:21a Crystallee $
+//
+// $Revision: 4 $
+//
+// $Date: 8/05/14 2:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPei.h $
+//
+// 4 8/05/14 2:21a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] For backward compatible, add old MTRR setting method
+// back. Change new MTRR setting method to Policy2.
+//
+// 3 7/08/14 3:35a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add all the possible methods to describing memory in
+// MTRRS.
+// [Files] CpuPei.c, CpuPei.h, CpuPeiFuncs.c
+//
+// 2 9/05/12 1:40a Davidhsieh
+// Rename PEI_IFFS_TRANSITION_START_PPI_GUID to
+// PEI_RAPID_START_TRANSITION_START_PPI_GUID
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuPei.h
+//
+// Description: Cpu PEI header file.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CPU_PEI_H__
+#define __CPU_PEI_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define IED_SIZE 0x400000
+#define VariableMtrrCount 10
+
+#define SIZE_1M 0x100000
+#define SIZE_64M 0x4000000
+#define SIZE_128M 0x8000000
+#define SIZE_256M 0x10000000
+#define SIZE_512M 0x20000000
+#define SIZE_1G 0x40000000
+#define SIZE_2G 0x80000000
+#define SIZE_4G 0x100000000
+#define SIZE_8G 0x200000000
+#define SIZE_16G 0x400000000
+
+//Chagned in IvyBridge RC 0.8
+//#define PEI_CACHE_PPI_GUID \
+// {0xc153205a, 0xe898, 0x4c24, 0x86, 0x89, 0xa4, 0xb4, 0xbc, 0xc5, 0xc8, 0xa2}
+#define PEI_CACHE_PPI_GUID \
+ {0x9be4bc2, 0x790e, 0x4dea, 0x8b, 0xdc, 0x38, 0x5, 0x16, 0x98, 0x39, 0x44}
+
+#define AMI_INTERNAL_UCODE_HOB_GUID \
+ {0x94567c6f, 0xf7a9, 0x4229, 0x13, 0x30, 0xfe, 0x11, 0xcc, 0xab, 0x3a, 0x11}
+
+#define PEI_RAPID_START_TRANSITION_START_PPI_GUID \
+ { \
+ 0xde8f2878, 0x36d5, 0x498e, 0xba, 0x59, 0x16, 0x8c, 0x26, 0x47, 0xb3, 0x35 \
+ }
+
+typedef struct {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ UINT32 uCodeAddr;
+} AMI_INTERNAL_UCODE_HOB;
+
+typedef enum _EFI_MEMORY_CACHE_TYPE
+{
+ EfiCacheTypeUncacheable = 0,
+ EfiCacheTypeWriteCombining= 1,
+ EfiCacheTypeReserved2 = 2,
+ EfiCacheTypeReserved3 = 3,
+ EfiCacheTypeWriteThrough = 4,
+ EfiCacheTypeWriteProtected= 5,
+ EfiCacheTypeWriteBack = 6,
+ EfiCacheTypeMaximumType = 7
+} EFI_MEMORY_CACHE_TYPE;
+
+
+typedef struct _PEI_CACHE_PPI PEI_CACHE_PPI;
+
+//
+// *******************************************************
+// PEI_SET_CACHE_PPI
+// *******************************************************
+//
+typedef
+EFI_STATUS
+(EFIAPI *PEI_SET_CACHE_PPI) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CACHE_PPI * This,
+ IN EFI_PHYSICAL_ADDRESS MemoryAddress,
+ IN UINT64 MemoryLength,
+ IN EFI_MEMORY_CACHE_TYPE MemoryCacheType
+ );
+
+//
+// *******************************************************
+// PEI_RESET_CACHE_PPI
+// *******************************************************
+//
+typedef
+EFI_STATUS
+(EFIAPI *PEI_RESET_CACHE_PPI) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CACHE_PPI * This
+ );
+
+//
+// *******************************************************
+// PEI_ACTIVATE_CACHE_PPI
+// *******************************************************
+//
+typedef
+EFI_STATUS
+(EFIAPI *PEI_ACTIVATE_CACHE_PPI) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_CACHE_PPI * This
+ );
+
+//
+// *******************************************************
+// PEI_CACHE_PPI
+// *******************************************************
+//
+typedef struct _PEI_CACHE_PPI {
+ PEI_SET_CACHE_PPI SetCache;
+ PEI_RESET_CACHE_PPI ResetCache;
+ PEI_ACTIVATE_CACHE_PPI ActivateCache;
+} PEI_CACHE_PPI;
+
+typedef struct {
+ UINT64 Base;
+ UINT64 Len;
+} MEMORY_MAP;
+
+EFI_STATUS InitMtrrPolicy1 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+);
+
+EFI_STATUS InitMtrrPolicy2 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+);
+
+VOID CpuPeiMiscFuncs (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi,
+ IN EFI_BOOT_MODE BootMode
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuPeiBeforeMem.c b/Core/CPU/CpuPeiBeforeMem.c
new file mode 100644
index 0000000..9647874
--- /dev/null
+++ b/Core/CPU/CpuPeiBeforeMem.c
@@ -0,0 +1,1268 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiBeforeMem.c 8 10/16/13 4:03a Crystallee $
+//
+// $Revision: 8 $
+//
+// $Date: 10/16/13 4:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiBeforeMem.c $
+//
+// 8 10/16/13 4:03a Crystallee
+// [TAG] EIP138897
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Locate BIST ppi will fail after disable CAR.
+// [RootCause] All SEC PPIs must be reinstalled outside of SEC,
+// otherwise they will be lost when CAR is no longer used.
+// [Solution] Reinstall BIST PPI outside of SEC.
+//
+// 7 6/03/13 12:04a Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description]
+// 1. Fix PLL setting is invalid once PEG/DMI ratio is 1:1.
+// 2. Modify IA core ratio minimun value. Use "max non turbo ratio(MSR
+// CEh)" instead of "power on turbo default value".
+//
+// 6 4/08/13 12:04a Hsingyingchung
+// [TAG] None
+// [Category] Improvement
+// [Description] Limit CPU boot performance at Non-Turbo speed when add
+// XTU.
+//
+// 5 2/07/13 4:13a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description] Add:
+// 1. Support IA core and Ring voltage offset negative in OC mailbox.
+// 2. Add Filter PLL function, please change
+// "HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT" token if need to use this
+// function.
+//
+// Fixed:
+// 1. TDP Time Window is now programmed to 8 seconds by default.
+// 2. When cold reset, re-enabling FIVR faults and SVID control.
+// 3. Initialize OC mailbox for each boot.
+//
+// 4 12/20/12 10:15a Hsingyingchung
+// [TAG] EIP108128
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] "Max non-turbo ratio" can't show in BIOS setup when first
+// boot after flashing BIOS
+// [RootCause] Doesn't initialize max non-turbo ratio value when first
+// boot after flashing BIOS.
+// [Solution] Add initialize code for max non-turbo ratio.
+//
+// 3 12/20/12 9:58a Hsingyingchung
+// [TAG] EIP107712
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Change core ratio limit is not effective for oc cpu.
+// [RootCause] The IA core max ratio in mailbox is not same as active
+// one core ratio limit in MSR 0x1AD
+// [Solution] Update the IA core max ratio in mailbox according to
+// active one core ratio limit in XTU setting data
+//
+// 2 11/23/12 2:09a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuPeiBeforeMem.c
+//
+// Description: This file is the main contains Cpu code that must execute
+// before memory.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Pei.h>
+#include <AmiPeiLib.h>
+#include "CPU.h"
+#include "AmiCspLibInc.h"
+#include "token.h"
+#include <Ppi\AmiEarlyBistPpi.h>
+
+#if PERF_TUNE_SUPPORT == 1
+ #include <Ppi\PerfTunePpi.h>
+ #include <PerfTune.h>
+ #include "Ppi\CpuPlatformPolicy\CpuPlatformPolicy.h"
+ #include <Setup.h>
+ #include <PPI\Stall.h>
+ #include "Board\EM\PerfTune\PerfTuneCpuSetup.h"
+ typedef struct{
+ UINT8 MeFirmwareInfo;
+ UINT32 MeMajor;
+ UINT32 MeMinor;
+ UINT32 MeHotFix;
+ UINT32 MeBuildNo;
+ } ME_INFO_SETUP_DATA;
+#define AMI_CPU_INTERNAL_ME_FW_VERSION_GUID \
+ {0x9b875aac, 0x36ec, 0x4550, 0xa4, 0xae, 0x86, 0xc8, 0x4e, 0x96, 0x76, 0x7e}
+EFI_GUID gAmiCpuMEFwVerGuid = AMI_CPU_INTERNAL_ME_FW_VERSION_GUID;
+#endif
+
+
+#if PERF_TUNE_SUPPORT == 1
+
+static EFI_GUID gPeiCpuPlatformPolicyGuid = PEI_CPU_PLATFORM_POLICY_PPI_GUID;
+static EFI_GUID gPerfTunePpiGuid = PERF_TUNE_PPI_GUID;
+static EFI_GUID gWdtPpiGuid = PERF_TUNE_WDT_PPI_GUID;
+static EFI_GUID gAmiOcConfigHobGuid = AMI_OVERCLOCK_CONFIG_HOB_GUID;
+static EFI_GUID gAmiCpuRatioLimitHobGuid = AMI_INTERNAL_CPU_RATIO_LIMIT;
+
+EFI_STATUS CpuPeiPolicyNotify(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+);
+
+// PPI that are notified
+static EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiCpuPlatformPolicyGuid,
+ CpuPeiPolicyNotify
+ }
+};
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PLLFilterFunction
+//
+// Description: Filter PLL setting High(3.2GHz) or lower(1.6GHz)
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// BIOS_SETTING_DATA *SettingData
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PLLFilterFunction (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN BIOS_SETTING_DATA *SettingData
+)
+{
+ UINT8 GpioSel;
+ UINT8 GpRstSel;
+ UINT32 RcbaAddress;
+ UINT8 PmCFG2;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+
+ //
+ // Set GPIO_USE_SEL[8] to `0'
+ //
+ GpioSel = READ_IO8(GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL); // 0x00
+ GpioSel = GpioSel & 0x7F;
+ WriteIo8 ((GPIO_BASE_ADDRESS + GP_IOREG_USE_SEL), GpioSel);
+
+ //
+ // Set GP_RST_SEL[8] is `1'
+ //
+ GpRstSel = READ_IO8 (GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1); // 0x60
+ GpRstSel |= BIT8;
+ WriteIo8 ((GPIO_BASE_ADDRESS + GP_IOREG_GP_RST_SEL1), GpRstSel);
+
+ //
+ //
+ // Set PCH_RCRB_PM_CFG 0x3318 bit 5
+ RcbaAddress = (READ_PCI32 (00, 0x1F, 0x0, 0xF0)) & 0xFFFFF000;
+ PmCFG2 = READ_MEM8 (RcbaAddress + 0x3318);
+ if (SettingData->FilterPLLFrequency){
+ PmCFG2 |= BIT5; //Bit5 set 1
+ }else{
+ PmCFG2 &= 0xDF; //Bit5 set 0
+ }
+ WRITE_MEM8 (RcbaAddress + 0x3318, PmCFG2);
+
+
+ //
+ // Issue a CF9h with a power cycle
+ //
+ //Let WDT know this is a normal reset.
+ (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ WdtPpi->AllowKnowReset(PeiServices);
+ IoWrite8 (0xCF9,0x0e);
+ EFI_DEADLOOP();
+
+ return EFI_SUCCESS;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OverrideNonTurboRatio
+//
+// Description: Override CPU NonTurbo Ratio Maximum value
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// UINT8 ProcessorMul
+// CPU_CONFIG_PPI *CpuConfig
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OverrideNonTurboRatio(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 ProcessorMul,
+ IN CPU_CONFIG_PPI *CpuConfig
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID PeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID gAmiCpuRatioLimitHobGuid = AMI_INTERNAL_CPU_RATIO_LIMIT;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ CPU_RATIO_LIMIT_DATA CpuRatioLimitData;
+ UINTN VarSize = sizeof(CPU_RATIO_LIMIT_DATA);
+
+ PEI_TRACE((-1, PeiServices, "OverrideNonTurboRatio start!!\n"));
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status))return Status;
+
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"CpuRatioLimit",
+ &gAmiCpuRatioLimitHobGuid,
+ NULL,
+ &VarSize,
+ &CpuRatioLimitData
+ );
+ if(EFI_ERROR(Status))return Status;
+
+ //check if cpuratio in PurfTuneCPUSetup is not default Max Non Turbo Ratio.
+ if((UINT8)(ProcessorMul & 0xFF) != ((CpuRatioLimitData.MaxNonTurboRatio) & 0xFF)){
+ CpuConfig->CpuRatioOverride = CPU_FEATURE_ENABLE;
+ CpuConfig->CpuRatio = (UINT8)(ProcessorMul & 0xFF);
+ }
+
+ PEI_TRACE((-1, PeiServices, "OverrideNonTurboRatio end!!\n"));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PEGDMIRatio
+//
+// Description: Modify PEG/DMI Ratio for CPU
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// BIOS_SETTING_DATA *SettingData
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PEGDMIRatio(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN BIOS_SETTING_DATA *SettingData
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 PciAddress, PciRegData;
+ UINT64 PCIEPLLRatio, MsrData;
+ EFI_BOOT_MODE BootMode = (EFI_BOOT_MODE)-1;
+ UINT8 Ratio = 0xFF;
+ EFI_GUID PeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ UINTN VarSize = sizeof(SETUP_DATA);
+ SETUP_DATA SetupData;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+ ME_INFO_SETUP_DATA mMeInfoSetupData;
+ UINTN MeVarSize = sizeof(ME_INFO_SETUP_DATA);
+
+ PEI_TRACE((-1, PeiServices, "Change PEGDMIRatio start!!\n"));
+
+ //is SBPLL desired
+ //MSR 0x61E , bit2: SBPLL(1) or LCPLL(0).
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status))return Status;
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"Setup",
+ &SetupGuid,
+ NULL,
+ &VarSize,
+ &SetupData
+ );
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, " Get SetupData fail!!\n"));
+ return Status;
+ }
+ MsrData = ReadMsr(0x61E);
+ PEI_TRACE((-1, PeiServices, "SetupData.LcSbSelect: %x !!\n",SetupData.LcSbSelect));
+ MsrData = (SetupData.LcSbSelect)? MsrData | BIT2 : (MsrData & ~(BIT2));
+ WriteMsr(0x61E,MsrData);
+
+ //read ICC PEG/DMI ratio setting
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x16) << 11) | ((0x0) << 8) | 0x60;
+ IoWrite32(0x0cf8,PciAddress);
+ PciRegData = IoRead32(0x0cfc);
+
+ //B0:D22:F0, FWstatus3[2:0]
+ //000b = 5/5, 1 - Used when BCLK at 100MHz
+ //001b = 5/4, 1.25 - Used when BCLK around 125MHz
+ //010b = 5/3, 1.66 - Used when BCLK around 166MHz
+ //011b = 5/2, 2.5 - Used when BCLK around 250MHz
+ //100b~111b = Reserved
+ switch(SettingData->PEGDMIRatio){
+ case 100: Ratio = 0x0; break;
+ case 125: Ratio = 0x1; break;
+ case 167: Ratio = 0x2; break;
+ case 250: Ratio = 0x3; break;
+ }
+ if((PciRegData & 0x3) == (ReadMsr(0x61E)& 0x3) || (PciRegData & 0x3) != Ratio){
+ PEI_TRACE((-1, PeiServices, "Change PEGDMIRatio suspend!!\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ //read CMOS and check if need to set bootmode = BOOT_ON_S3_RESUME
+ IoWrite8(0x70,0x50);
+ PEI_TRACE((-1, PeiServices, "S3 resume request: %x\n",IoRead8(0x71)));
+ if(IoRead8(0x71) == 0xA5){
+ (*PeiServices)->SetBootMode(PeiServices, BOOT_ON_S3_RESUME); //restore BootMode after set BCLK over ratio and generate warm reset.
+ IoWrite8(0x71,0x5A); //clear scratch
+ }
+
+ PCIEPLLRatio = ReadMsr(0x61E) & ~(BIT0 | BIT1 | BIT3); //clear PCIE_Ratio & Long_Reset bit
+
+ //PCIE_Ratio bit
+ MsrData = 0;
+ switch(Ratio){
+ case 0x0: MsrData = 0; break;
+ case 0x1: MsrData = 0 | BIT0; break;
+ case 0x2: MsrData = 0 | BIT1; break;
+ case 0x3: MsrData = 0 | BIT0 | BIT1; break;
+ }
+ //long reset bit
+ MsrData |= BIT3;
+
+ PCIEPLLRatio |= MsrData;
+ WriteMsr(0x61E,PCIEPLLRatio);
+
+ //Record current BootMode for restore after warm reset
+ (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ if (BootMode == BOOT_ON_S3_RESUME)
+ IoWrite8(0x71,0xA5);
+ PEI_TRACE((-1, PeiServices, "S3scratchpad value: %x\n",IoRead8(0x71)));
+
+ //Is Memory in Self refresh?(B0:D31:F0, REG:0xa2)
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x1f) << 11) | ((0x0) << 8) | 0xa0;
+ IoWrite32(0x0cf8,PciAddress);
+ PciRegData = IoRead32(0x0cfc);
+ PEI_TRACE((-1, PeiServices, "Read GEN_PMCON2 value: %x\n",PciRegData));
+ if(!((PciRegData >> 16) & BIT5)){ //is memory in self-refresh
+ //clear GEN_PMCON2 bit7(DRAM Initialization Bit)
+ IoWrite32(0x0cfc,PciRegData & ~(BIT7 << 16));
+ }
+
+ //Need to send ICC message to enable Ramp when ME Firmware build no. is above 1221.
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"MEFWVersion",
+ &gAmiCpuMEFwVerGuid,
+ NULL,
+ &MeVarSize,
+ &mMeInfoSetupData
+ );
+ if(!EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "ME FW Build No %d\n",mMeInfoSetupData.MeBuildNo));
+ if(mMeInfoSetupData.MeBuildNo >= 1221){
+ //Write a value of 0x60000001 to PCI 0:22:0 offset 0x4C.
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x16) << 11) | ((0x0) << 8) | 0x4c;
+ IoWrite32(0x0cf8,PciAddress);
+ //Bits 31:28 - Message Type:
+ // 0x06 - ICC BIOS Message
+ //Bit 0 - BCLK Ramp Enable
+ // 0x01 - BCLK Ramp Enable
+ IoWrite32(0x0cfc,0x60000001);
+
+ //Wait for FW ACK by reading FWStatus PCI 0:22:0 offset 0x40 for ICC FW ACK
+ //type and success status.
+ PciAddress = (0x1) << 31 | ((0x0) << 16) | ((0x16) << 11) | ((0x0) << 8) | 0x40;
+ IoWrite32(0x0cf8,PciAddress);
+ //Bits 31:28 - Message Type:
+ // 0x06 - ICC BIOS Message
+ //Bits 27:25 - ICC BIOS Ack Data
+ // 0 - ICC Success
+ // 1 - ICC BIOS Request Failed
+ while((Shr64(IoRead32(0x0cfc),25) & 0x7) != 0){} //wait for BCLK Ramp Enable success
+ }
+ }
+ else
+ PEI_TRACE((-1, PeiServices, "Get Me Fw Version fail!!\n"));
+
+ //warm reset
+ PEI_TRACE((-1, PeiServices, "Warmreset!!\n"));
+ //Let WDT know this is a normal reset.
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ WdtPpi->AllowKnowReset(PeiServices);
+ IoWrite8 (0xCF9,0x06);
+ EFI_DEADLOOP();
+
+ PEI_TRACE((-1, PeiServices, "Change PEGDMIRatio end!!\n"));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnablePLLOverVoltage
+//
+// Description: Enable PLL over voltage for CPU
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// UINT8 NumOfCpuCore
+// UINT16 *pCoreRatioData
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnablePLLOverVoltage(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 NumOfCpuCore,
+ IN UINT16 *pCoreRatioData
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID gAmiPllOvFlagHobGuid = AMI_PLL_OVER_VOTAGE_FLAG_HOB_GUID;
+ EFI_GUID gPeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID gAmiPllOvFlagDataGuid = gAmiPllOvFlagHobGuid;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ UINTN VarSize = sizeof(PLL_OV_FLAG_DATA);
+ PLL_OV_FLAG_DATA_HOB *PllOvFlagHob;
+ UINT16 i;
+ UINT8 *OriRatioLimit;
+
+ PEI_TRACE((-1, PeiServices, "EnablePLLOverVoltage Start\n"));
+ Status = (*PeiServices)->CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(PLL_OV_FLAG_DATA_HOB),
+ &PllOvFlagHob);
+ if (EFI_ERROR(Status))return Status;
+
+ PllOvFlagHob->EfiHobGuidType.Name = gAmiPllOvFlagHobGuid;
+ OriRatioLimit = (UINT8*)&PllOvFlagHob->PllOvData.OriTurboRatio;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status))return Status;
+
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"PLLOvFlag",
+ &gAmiPllOvFlagDataGuid,
+ NULL,
+ &VarSize,
+ &PllOvFlagHob->PllOvData
+ );
+
+ if(!(EFI_ERROR(Status)) && (PllOvFlagHob->PllOvData.PLLOvFlag== 0x2)) return EFI_ALREADY_STARTED;
+
+ for(i = 0; i < sizeof(UINT64); i++){
+ if( i < NumOfCpuCore)
+ OriRatioLimit[i] = (UINT8)pCoreRatioData[i];
+ else
+ OriRatioLimit[i] = 0x00;
+
+ if( i < 3)
+ pCoreRatioData[i] = 0x06;
+ else
+ pCoreRatioData[i] = 0x00;
+ }
+
+ PllOvFlagHob->PllOvData.PLLOvFlag = 0x1;
+ WriteMsr(MSR_TURBO_RATIO_LIMIT,0x60606);
+
+ PEI_TRACE((-1, PeiServices, "EnablePLLOverVoltage End\n"));
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectOcConfig
+//
+// Description: Collect Overclocking Config data from MSR 0x150.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// OVERCLOCKING_CONFIG_HOB *OverclockConfig
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CollectOcConfig(
+ EFI_PEI_SERVICES **PeiServices,
+ OVERCLOCKING_CONFIG_DATA *OverclockConfig
+){
+ EFI_STATUS Status;
+ UINT64 MsrData;
+ UINT8 i;
+ PERF_TUNE_PPI *PerfTunePpi;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+
+ PEI_TRACE((-1, PeiServices, "Collect Overclocking config data(MSR 0x150) Start\n"));
+
+ OverclockConfig->OcSupport = 0;
+ OverclockConfig->IsPowerCycle = IsPowerCycle();
+ OverclockConfig->IsCpuRunDefault = TRUE;
+
+ //collect CPU overclocking config data
+ for(i=0;i<DOMAIN_MAX_NUM;++i){
+ //1. Overclocking Capability
+ MsrData = 0;
+ Status = GetOcCapability(i, &MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->OCCap[i].MaxOcRatioLimit = (UINT8)MsrData;
+ OverclockConfig->OCCap[i].RatioOcSupported = (MsrData & BIT8)?1:0;
+ OverclockConfig->OCCap[i].VoltageOverridesSupported = (MsrData & BIT9)?1:0;
+ OverclockConfig->OCCap[i].VoltageOffsetSupported = (MsrData & BIT10)?1:0;
+ if (!OverclockConfig->OcSupport)
+ OverclockConfig->OcSupport = OverclockConfig->OCCap[i].RatioOcSupported ||
+ OverclockConfig->OCCap[i].VoltageOverridesSupported||
+ OverclockConfig->OCCap[i].VoltageOffsetSupported ;
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "Domain %x GetOcCapability fail [0x%x]\n",i,Shr64(MsrData,32) & 0xFF));
+ }
+
+ //2. Overclocking Voltage/Frequency
+ MsrData = 0;
+ Status = GetVoltFreq(i, &MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->VFDef[i].MaxOcRatio = (UINT8)MsrData;
+ OverclockConfig->VFDef[i].VoltageTargetMode = (UINT8)(Shr64(MsrData,20) & 0x1);
+ OverclockConfig->VFDef[i].VoltageTarget = (UINT16)(Shr64(MsrData,8) & 0xFFF);
+ OverclockConfig->VFDef[i].VoltageOffset = (INT16)(Shr64(MsrData,21) & 0x7FF);
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "Domain %x GetVoltFreq fail [0x%x]\n",i,Shr64(MsrData,32) & 0xFF));
+ }
+ }
+ //3. SVID Config
+ MsrData = 0;
+ Status = GetSVIDConfig(&MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->SvidDisable = (MsrData & BIT31)?1:0;
+ OverclockConfig->SvidVoltageOverride = (UINT16)(MsrData & 0xFFF);
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "GetSVIDConfig fail [0x%x]\n",Shr64(MsrData,32) & 0xFF));
+ }
+
+ //4. Misc Global Config
+ MsrData = 0;
+ Status = GetFIVRConfig(&MsrData);
+ if(!EFI_ERROR(Status)){
+ OverclockConfig->FivrFaultsDisable = (MsrData & BIT0)?1:0;
+ OverclockConfig->FivrEfficiencyDisable = (MsrData & BIT1)?1:0;
+ }
+ else{
+ PEI_TRACE((-1, PeiServices, "GetMiscConfig fail [0x%x]\n",Shr64(MsrData,32) & 0xFF));
+ }
+
+ PEI_TRACE((-1, PeiServices, "Collect Overclocking config data(MSR 0x150) end\n"));
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPerfTunePpiGuid,
+ 0,
+ NULL,
+ &PerfTunePpi
+ );
+ if(EFI_ERROR(Status)) return;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ if(EFI_ERROR(Status)) return;
+
+ if ( !(PerfTunePpi->IsChangeCpu(PeiServices) && PerfTunePpi->IsRunDefault(PeiServices)) && !(WdtPpi->QueryTimeOut(PeiServices))){
+ OverclockConfig->IsCpuRunDefault = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitOcMailbox
+//
+// Description: Initialize Overclocking Config data.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitOcMailbox(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *FirstHob;
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+
+ PEI_TRACE((-1, PeiServices, "InitOcMailbox start!!\n"));
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ OverclockConfigHob = (OVERCLOCKING_CONFIG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OverclockConfigHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)OverclockConfigHob)->Name, &gAmiOcConfigHobGuid) == 0) {
+ break;
+ }
+ }
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Get OC config HOB fail!!\n"));
+ return Status;
+ }
+ OverclockData = &OverclockConfigHob->OverclockData;
+
+ //
+ // Initialize Overclocking Data
+ //
+ if(OverclockData->OCCap[IA].RatioOcSupported){
+ OverclockingConfig->CoreMaxOcTurboRatio = ReadMsr(0x1AD) & 0xFF;
+ }
+
+ if(OverclockData->OCCap[RING].RatioOcSupported){
+ OverclockingConfig->ClrMaxOcTurboRatio = ReadMsr(0x1AD) & 0xFF; // read core one max ratio limit
+ }
+
+ OverclockingConfig->SvidEnable = 1; // 1: Enable
+ OverclockingConfig->FivrFaultsEnable = 1; // 1: Enable
+ OverclockingConfig->FivrEfficiencyEnable = 1; // 1: Enable
+
+ OverclockingConfig->OcSupport = 1; // 0: Disable, 1: Enable
+
+ PEI_TRACE((-1, PeiServices, "InitOcMailbox End!!\n"));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OverlockingConfigUpdate
+//
+// Description: Update Overclocking Config data.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// BIOS_SETTING_DATA *SettingData
+// OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OverlockingConfigUpdate(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN BIOS_SETTING_DATA *SettingData,
+ IN OVERCLOCKING_CONFIG_PPI *OverclockingConfig
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *FirstHob;
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+
+ PEI_TRACE((-1, PeiServices, "OverlockingConfigUpdate start!!\n"));
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ OverclockConfigHob = (OVERCLOCKING_CONFIG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OverclockConfigHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)OverclockConfigHob)->Name, &gAmiOcConfigHobGuid) == 0) {
+ break;
+ }
+ }
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Get OC config HOB fail!!\n"));
+ return Status;
+ }
+ OverclockData = &OverclockConfigHob->OverclockData;
+
+
+ //Overwrite OverclockingConfig data in Intel reference code
+ if(OverclockData->OcSupport){
+ //IA core
+ // Core Max overclocking turbo ratio
+ if(OverclockData->OCCap[IA].RatioOcSupported){
+ OverclockingConfig->CoreMaxOcTurboRatio = (SettingData->CoreRatioLimit1)?SettingData->CoreRatioLimit1:ReadMsr(0x1AD) & 0xFF;
+ if (SettingData->CoreRatioLimit1 < SettingData->ProcessorMul )
+ OverclockingConfig->CoreMaxOcTurboRatio = SettingData->ProcessorMul;
+ }
+
+ if(OverclockData->OCCap[IA].VoltageOverridesSupported){
+ // Voltage Mode, 0: Adaptive, 1: Override(Static)
+ OverclockingConfig->CoreVoltageMode = (UINT8)SettingData->IACoreVoltageMode;
+
+ if(SettingData->IACoreVoltageMode == 0x1){
+ // Override(Static) mode
+ OverclockingConfig->CoreVoltageOverride = SettingData->CPUVoltage;
+ if(SettingData->CPUVoltage == 0xFFFF)
+ OverclockingConfig->CoreVoltageOverride = 0;
+ OverclockingConfig->CoreExtraTurboVoltage = 0;
+ }
+ else{
+ // Adaptive mode
+ OverclockingConfig->CoreExtraTurboVoltage = SettingData->CPUVoltage;
+ if(SettingData->CPUVoltage == 0xFFFF)
+ OverclockingConfig->CoreExtraTurboVoltage = 0;
+ OverclockingConfig->CoreVoltageOverride = 0;
+ }
+ }
+
+ if(OverclockData->OCCap[IA].VoltageOffsetSupported){
+ if (SettingData->DynamicCPUVoltage >=0 && \
+ SettingData->DynamicCPUVoltage <= 999){
+ OverclockingConfig->CoreVoltageOffset = ~(1000 - SettingData->DynamicCPUVoltage) + 1;
+ }else if (SettingData->DynamicCPUVoltage >=1000 && \
+ SettingData->DynamicCPUVoltage <= 1998){
+ OverclockingConfig->CoreVoltageOffset = SettingData->DynamicCPUVoltage - 1000;
+ }
+
+ }
+
+ //RING
+ // Ring Max overclocking turbo ratio
+ if(OverclockData->OCCap[RING].RatioOcSupported){
+ if(SettingData->RingRatio){
+ OverclockingConfig->ClrMaxOcTurboRatio = SettingData->RingRatio;
+ }
+ else{
+ // first boot
+ OverclockingConfig->ClrMaxOcTurboRatio = ReadMsr(0x1AD) & 0xFF; // read core one max ratio limit
+ }
+ }
+
+ if(OverclockData->OCCap[RING].VoltageOverridesSupported){
+ // Voltage Mode, 0: Adaptive, 1: Override(Static)
+ OverclockingConfig->ClrVoltageMode = (UINT8)SettingData->RingVoltageMode;
+
+ if(SettingData->RingVoltageMode == 0x1){
+ // Override(Static) mode
+ OverclockingConfig->ClrVoltageOverride = SettingData->RingVoltageOverride;
+ if(SettingData->RingVoltageOverride == 0xFFFF)
+ OverclockingConfig->ClrVoltageOverride = 0;
+ OverclockingConfig->ClrExtraTurboVoltage = 0;
+ }
+ else{
+ // Adaptive mode
+ OverclockingConfig->ClrExtraTurboVoltage = SettingData->RingVoltageOverride;
+ if(SettingData->RingVoltageOverride == 0xFFFF)
+ OverclockingConfig->ClrExtraTurboVoltage = 0;
+ OverclockingConfig->ClrVoltageOverride = 0;
+ }
+ }
+
+ if(OverclockData->OCCap[RING].VoltageOffsetSupported){
+ if (SettingData->RingVoltageOffset >=0 && \
+ SettingData->RingVoltageOffset <= 999){
+ OverclockingConfig->ClrVoltageOffset = ~(1000 - SettingData->RingVoltageOffset) + 1;
+ }else if (SettingData->RingVoltageOffset >=1000 && \
+ SettingData->RingVoltageOffset <= 1998){
+ OverclockingConfig->ClrVoltageOffset = SettingData->RingVoltageOffset - 1000;
+ }
+ }
+
+ //SVID and FIVR
+ if(SettingData->DynamicSVIDControl != 0xFFFF)
+ OverclockingConfig->SvidEnable = (UINT8)(SettingData->DynamicSVIDControl); // 0: Disable, 1: Enable
+ if(OverclockData->IsPowerCycle)
+ OverclockingConfig->SvidEnable = 1; // When cold boot, reset to the default value '1'.
+ if(SettingData->DynamicSVIDControl != 0xFFFF && SettingData->SVIDVoltageOverride != 0xFFFF)
+ OverclockingConfig->SvidVoltageOverride = (SettingData->DynamicSVIDControl)? SettingData->SVIDVoltageOverride : 0; // External VR voltage override
+
+ if(SettingData->FIVRFaults != 0xFFFF)
+ OverclockingConfig->FivrFaultsEnable = (UINT8)(SettingData->FIVRFaults); // 0: Disable, 1: Enable
+ if(OverclockData->IsPowerCycle)
+ OverclockingConfig->FivrFaultsEnable = 1; // When cold boot, reset to the default value '1'.
+ if(SettingData->FIVREfficiencyManagenment != 0xFFFF)
+ OverclockingConfig->FivrEfficiencyEnable = (UINT8)(SettingData->FIVREfficiencyManagenment); // 0: Disable, 1: Enable
+
+ //Enable orDisable Reference code execute Cpu Overclocking Initialize(CpuOcInit).
+ OverclockingConfig->OcSupport = 1; // 0: Disable, 1: Enable
+ OverclockingConfig->BitReserved = 0;
+ }
+ PEI_TRACE((-1, PeiServices, "OverlockingConfigUpdate end!!\n"));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiPolicyOverWrite
+//
+// Description: This function over writes the CPU PEI RC policy
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CpuPeiPolicyOverWrite (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+
+ //UINT8 MaxNonTurboRatio;
+ //UINT8 NumBinsSupport;
+ UINT8 CpuCores = NumCpuCores();
+ UINT16 i;
+ UINT16 Xtu_CoreRatioArray[6];
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ //UINT64 MsrData;
+
+ EFI_STATUS Status;
+ PEI_CPU_PLATFORM_POLICY_PPI *PeiCpuPolicyPpi;
+ //PPI_CPU_POWER_FEATURE_CONFIG *PeiCpuPowerFeatureConfig;
+ POWER_MGMT_CONFIG_PPI *PeiCpuPowerFeatureConfig;
+ PERF_TUNE_PPI *PerfTunePpi;
+ //PERF_TUNE_WDT_PPI *WdtPpi;
+ BIOS_SETTING_DATA SettingData;
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+ CPU_RATIO_LIMIT_HOB *CpuRatioLimitHob;
+ CPU_RATIO_LIMIT_DATA *CpuRatioLimitData;
+ EFI_GUID PeiReadOnlyVariable2PpiGuid = EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable2;
+ SETUP_DATA SetupData;
+ UINTN VarSize = sizeof(SETUP_DATA);
+
+ PEI_TRACE((-1, PeiServices, "Start CPU PEI RC policy overwrite\n"));
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable2
+ );
+ if(EFI_ERROR(Status)) return;
+ Status = ReadOnlyVariable2->GetVariable(
+ ReadOnlyVariable2,
+ L"Setup",
+ &SetupGuid,
+ NULL,
+ &VarSize,
+ &SetupData
+ );
+ if(EFI_ERROR(Status)) return;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiCpuPlatformPolicyGuid,
+ 0,
+ NULL,
+ &PeiCpuPolicyPpi
+ );
+ if(EFI_ERROR(Status)) return;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPerfTunePpiGuid,
+ 0,
+ NULL,
+ &PerfTunePpi
+ );
+ if(EFI_ERROR(Status)) return;
+ PEI_TRACE((-1, PeiServices, "Perfmorance tunning PPI located\n"));
+
+ // collect OcMailbox data
+ Status = (*PeiServices)->CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(OVERCLOCKING_CONFIG_HOB),
+ &OverclockConfigHob);
+ if (EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Create OverclockConfigHob fail\n"));
+ return;
+ }
+ OverclockConfigHob->EfiHobGuidType.Name = gAmiOcConfigHobGuid;
+ OverclockData = &OverclockConfigHob->OverclockData;
+ CollectOcConfig(PeiServices,OverclockData);
+ InitOcMailbox(PeiServices,PeiCpuPolicyPpi->OverclockingConfig);
+
+ if(PerfTunePpi->IsChangeCpu(PeiServices)){
+ Status = (*PeiServices)->CreateHob(PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(CPU_RATIO_LIMIT_HOB),
+ &CpuRatioLimitHob);
+ if (EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Create NonTurboRatioMax HOB fail\n"));
+ return;
+ }
+ CpuRatioLimitHob->EfiHobGuidType.Name = gAmiCpuRatioLimitHobGuid;
+ CpuRatioLimitData = &CpuRatioLimitHob->CpuRatioLimitData;
+ CpuRatioLimitData->MaxNonTurboRatio = (UINT8)(Shr64(ReadMsr(0x0ce), 8) & 0xFF);
+ CpuRatioLimitHob->IsChangeCpu = PerfTunePpi->IsChangeCpu(PeiServices);
+ }
+ /*
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gWdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ if(EFI_ERROR(Status)) return;
+ PEI_TRACE((-1, PeiServices, "watch dogger timer PPI located\n"));
+ */
+ Status = PerfTunePpi->GetSettingData(
+ PeiServices,
+ &SettingData
+ );
+
+ if(EFI_ERROR(Status)) return;
+ PEI_TRACE((-1, PeiServices, "Got Perfmorance tunning setting data\n"));
+
+ if(!((PerfTunePpi->IsChangeCpu(PeiServices) && PerfTunePpi->IsRunDefault(PeiServices)))){
+ //if(!(WdtPpi->QueryTimeOut(PeiServices))){
+
+ PEI_TRACE((-1, PeiServices, "ReConfig XE policy from XTU\n"));
+ //PeiCpuPowerFeatureConfig = PeiCpuPolicyPpi->PpiCpuPowerFeatureConfig;
+ PeiCpuPowerFeatureConfig = PeiCpuPolicyPpi->PowerMgmtConfig;
+ //PeiCpuPowerFeatureConfig->PrimaryPlaneCurrentLimit = (SettingData.IACoreCurrentMax & 0x1fff);
+ PeiCpuPowerFeatureConfig->VrCurrentLimit = (SettingData.PackageCurrentLimit & 0x1fff);
+ //PeiCpuPowerFeatureConfig->SecondaryPlaneCurrentLimit = (SettingData.IGFXCoreCurrentMax & 0x1fff);
+ PeiCpuPowerFeatureConfig->VrCurrentLimitLock = (!OverclockData->IsCpuRunDefault)? SetupData.PackageCurrentLock : CPU_FEATURE_DISABLE ;
+ // CPU boot with Maximum Non-Turbo speed.
+ PeiCpuPowerFeatureConfig->BootInLfm = CPU_FEATURE_DISABLE;
+
+ if (isXECoreRatioLimitSupported())
+ {
+ PEI_TRACE((-1, PeiServices, "XE part CPU found\n"));
+
+ PeiCpuPowerFeatureConfig->Xe = CPU_FEATURE_ENABLE;
+ Xtu_CoreRatioArray[0] = SettingData.CoreRatioLimit1;
+ Xtu_CoreRatioArray[1] = SettingData.CoreRatioLimit2;
+ Xtu_CoreRatioArray[2] = SettingData.CoreRatioLimit3;
+ Xtu_CoreRatioArray[3] = SettingData.CoreRatioLimit4;
+ Xtu_CoreRatioArray[4] = SettingData.CoreRatioLimit5;
+ Xtu_CoreRatioArray[5] = SettingData.CoreRatioLimit6;
+
+ for(i = 0; i < CpuCores; ++i)
+ if(SettingData.ProcessorMul > Xtu_CoreRatioArray[i])
+ Xtu_CoreRatioArray[i] = SettingData.ProcessorMul;
+
+ /*Force Runtime Turbo not suuport now
+ if (CpuSigNoVer == SANDY_BRIDGE && SettingData.RuntimeTurboEanble)
+ {
+ PEI_TRACE((-1, PeiServices, "SnadyBridge Runtime Turbo ratio change\n"));
+ MsrData = ReadMsr(MSR_FLEX_RATIO);
+ NumBinsSupport = (UINT8)((UINT32)MsrData >> 17) & 0x7;
+
+ //Read Max_Non turbo ratio.
+ MsrData = ReadMsr(MSR_PLATFORM_INFO);
+ MaxNonTurboRatio = ((UINT32) MsrData >> MAX_NON_TURBO_RATIO_OFFSET) & MAX_NON_TURBO_RATIO_MASK;
+
+ MsrData = ReadMsr(MSR_TURBO_RATIO_LIMIT);
+ for(i = 0; i < CpuCores; i++)
+ {
+ if((NumBinsSupport > 0)&&(NumBinsSupport < 7))
+ {
+ PeiCpuPowerFeatureConfig->RatioLimit[i] = MsrData & 0xff + NumBinsSupport;
+ } else {
+ PeiCpuPowerFeatureConfig->RatioLimit[i] = 0x39;
+ }
+ MsrData = Shr64(MsrData, 8);
+ }
+
+ } else {*/
+ PEI_TRACE((-1, PeiServices, "CPU core ratio limit change\n"));
+ for(i = 0; i < CpuCores; i++){
+ PeiCpuPowerFeatureConfig->RatioLimit[i] = (UINT8)(Xtu_CoreRatioArray[i]);
+ PEI_TRACE((-1, PeiServices, "XTU for %x core ratio limit = %x \n", (i + 1, Xtu_CoreRatioArray[i])));
+ }
+ //}
+
+ //PeiCpuPowerFeatureConfig->OverClockExtraVoltage = SettingData.MaxTurboModeCPUVoltage;
+
+ // Change Cpu Max Non-Tubro Ratio
+ if(SettingData.ProcessorMul != 0xFFFF){
+ Status = OverrideNonTurboRatio(PeiServices,SettingData.ProcessorMul,PeiCpuPolicyPpi->CpuConfig);
+ }
+ }
+
+#if HASWELL_PERFTUNE_CPU_FILTER_PLL_SUPPORT == 1
+ if(SettingData.FilterPLLFrequency != 0xFFFF){
+ UINT32 RcbaAdd;
+ UINT8 PmCFG;
+
+ RcbaAdd = (READ_PCI32 (00, 0x1F, 0x0, 0xF0)) & 0xFFFFF000;
+ PmCFG = READ_MEM8 (RcbaAdd + 0x3318);
+ if ( SettingData.FilterPLLFrequency != ( (PmCFG & BIT5) >> 5)){
+ PLLFilterFunction(PeiServices,&SettingData);
+ }
+ }
+#endif
+
+ // Change PEG/DMI Ratio
+ if(SettingData.PEGDMIRatio != 0xFFFF){
+ if(isBCLKRatioSuuported()){
+ PEGDMIRatio(PeiServices,&SettingData);
+ }
+ }
+ // Enable PLL Over Voltage feature
+ if(SettingData.CpuPllVoltageUnlockEnable == 0x1){
+ Status = EnablePLLOverVoltage(PeiServices,CpuCores,(UINT16*)Xtu_CoreRatioArray);
+ }
+
+ // Updata OC config data in CpuOcInit.c
+ Status = OverlockingConfigUpdate(PeiServices,&SettingData,PeiCpuPolicyPpi->OverclockingConfig);
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiPolicyNotify
+//
+// Description: CPU PEI pollicy PPI notify function
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor
+// VOID *NullPpi
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiPolicyNotify(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+)
+{
+ CpuPeiPolicyOverWrite(PeiServices);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiXtuInitBeforeMem
+//
+// Description: CPU XTU init code in PEI phase
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiXtuInitBeforeMem(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+
+ EFI_STATUS Status;
+ PEI_CPU_PLATFORM_POLICY_PPI *PeiCpuPolicyPpi;
+
+ Status = (*PeiServices)->LocatePpi (PeiServices, &gPeiCpuPlatformPolicyGuid, 0, NULL, &PeiCpuPolicyPpi);
+ if (Status == EFI_SUCCESS) {
+ CpuPeiPolicyOverWrite(PeiServices);
+ } else {
+ Status = (*PeiServices)->NotifyPpi(PeiServices, mNotifyList);
+ }
+
+ return Status;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReinstallSecPpis
+//
+// Description:
+// Reinstall PPIs from stack because stack will be lost when cache-as-ram is turned off.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//Sec Core Descriptors on stack will be lost when cache-as-ram is turned off.
+VOID ReinstallSecPpis(IN EFI_PEI_SERVICES **PeiServices)
+{
+ EFI_STATUS Status;
+ EFI_GUID gAmiEarlyBistGuid = AMI_EARLY_BIST_PPI_GUID;
+
+ AMI_EARLY_BIST_PPI *OldAmiBistPpi;
+ AMI_EARLY_BIST_PPI *NewAmiBistPpi;
+
+ EFI_PEI_PPI_DESCRIPTOR *OldPpiDesc;
+ EFI_PEI_PPI_DESCRIPTOR *NewPpiDesc;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gAmiEarlyBistGuid,
+ 0,&OldPpiDesc,
+ &OldAmiBistPpi
+ );
+ if (!EFI_ERROR(Status)) {
+
+ //Create new PPI in allocated memory because the location in stack from Sec Core
+ //will not be available after memory.
+ Status = (*PeiServices)->AllocatePool(PeiServices,
+ sizeof(AMI_EARLY_BIST_PPI) + (OldAmiBistPpi->NumBists - 1) * sizeof(CPU_BIST),
+ &NewAmiBistPpi
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ MemCpy(
+ NewAmiBistPpi,
+ OldAmiBistPpi,
+ sizeof(AMI_EARLY_BIST_PPI) + (OldAmiBistPpi->NumBists - 1) * sizeof(CPU_BIST)
+ );
+
+ //Create new Descriptor
+ Status = (*PeiServices)->AllocatePool(PeiServices,
+ sizeof(EFI_PEI_PPI_DESCRIPTOR),
+ &NewPpiDesc
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+ MemCpy(NewPpiDesc, OldPpiDesc, sizeof(EFI_PEI_PPI_DESCRIPTOR));
+ NewPpiDesc->Ppi = NewAmiBistPpi;
+
+ (*PeiServices)->ReInstallPpi(
+ PeiServices,
+ (EFI_PEI_PPI_DESCRIPTOR*)OldPpiDesc,
+ (EFI_PEI_PPI_DESCRIPTOR*)NewPpiDesc
+ );
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuPeiBeforeMemEntry
+//
+// Description: CPU PEI functions before memory ready
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuPeiBeforeMemEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+#if PERF_TUNE_SUPPORT == 1
+ EFI_STATUS Status;
+ Status = CpuPeiXtuInitBeforeMem(PeiServices);
+#endif
+
+ ReinstallSecPpis(PeiServices);
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuPeiFuncs.c b/Core/CPU/CpuPeiFuncs.c
new file mode 100644
index 0000000..c5bb238
--- /dev/null
+++ b/Core/CPU/CpuPeiFuncs.c
@@ -0,0 +1,1378 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiFuncs.c 10 8/06/14 11:57p Crystallee $
+//
+// $Revision: 10 $
+//
+// $Date: 8/06/14 11:57p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuPeiFuncs.c $
+//
+// 10 8/06/14 11:57p Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add special case for saving MTRRs.
+//
+// 9 8/05/14 2:21a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] For backward compatible, add old MTRR setting method
+// back. Change new MTRR setting method to Policy2.
+//
+// 8 7/08/14 3:35a Crystallee
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add all the possible methods to describing memory in
+// MTRRS.
+// [Files] CpuPei.c, CpuPei.h, CpuPeiFuncs.c
+//
+// 7 6/03/13 2:37a Hsingyingchung
+// [TAG] EIP123835
+// [Category] Spec Update
+// [Severity] Important
+// [Description] SBY Performance Tuning Guid rev. 1.1 update.
+//
+// 6 2/07/13 3:59a Hsingyingchung
+// [TAG] EIP112631
+// [Category] Improvement
+// [Description] add PEI/DMI ratio control item.
+//
+// 5 12/20/12 10:09a Hsingyingchung
+// [TAG] EIP
+// [Category] Improvement
+// [Description] Remove mailbox item limit. Because mailbox item is not
+// be effected by turbo mode support or not.
+//
+// 4 11/23/12 2:10a Hsingyingchung
+// [TAG] EIP99095
+// [Category] Improvement
+// [Description] Update by XTU 4.X
+//
+// 3 10/25/12 4:01a Davidhsieh
+// Add ReadOnlyVariable.h file include
+//
+// 2 3/09/12 2:14a Davidhsieh
+// Use all variable MTRRs
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: CpuPeiFuncs.c
+//
+// Description:
+// This file is the main CPU PEI component file. This file provides
+// misc functions for CPU PEI drvier usage.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "cpu.h"
+#include "AmiCspLibInc.h"
+#include <AmiPeiLib.h>
+#include <core\PeiHob.h>
+#include <token.h>
+#include <Ppi\ReadOnlyVariable.h>
+#include "CpuPei.h"
+#include "Setup.h"
+
+#if PERF_TUNE_SUPPORT == 1
+ #include <Ppi\PerfTunePpi.h>
+ #include <PerfTune.h>
+
+ //TODO: Update library and remove private structure.
+ typedef struct {
+ SETUP_DATA *SetupData;
+ } PRIVATE_CPU_SETUP_LIB;
+
+ EFI_GUID gAmiDddtPreFlagHobGuid = AMI_DDDT_PRESENT_FLAG_HOB_GUID;
+ EFI_GUID gAmiOcConfigHobGuid = AMI_OVERCLOCK_CONFIG_HOB_GUID;
+#endif
+
+#if MTRR_POLICY == 1
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitMtrrPolicy1
+//
+// Description: Config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN PEI_CACHE_PPI *CachePpi
+// IN UINT64 Above4GMemoryLength
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitMtrrPolicy1 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+)
+{
+
+ UINT64 TotalAbove4GMemoryLength = Above4GMemoryLength + SIZE_4G;
+ UINT64 RemainMemoryLength = TotalAbove4GMemoryLength - GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ UINT64 Below4GMemoryLength;
+ UINT64 MemoryLengthUc;
+ UINT64 CurrentBaseAddress;
+ UINT64 PowerTwo;
+ UINTN i, WbCount = 0, UcCount = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 NumOfOne = 0;
+
+ CurrentBaseAddress = 0;
+
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ WbCount++;
+ MtrrCount++;
+
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ //
+ // UC memory length below 4GB = 4GB - total memory length below 4GB
+ //
+ MemoryLengthUc = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (MemoryLengthUc);
+
+ for (PowerTwo = GetPowerOfTwo64 (MemoryLengthUc);
+ CurrentBaseAddress >= Below4GMemoryLength; PowerTwo = GetPowerOfTwo64 (MemoryLengthUc)) {
+
+ //PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %08lx.\n", PowerTwo, CurrentBaseAddress));
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = PowerTwo;
+ MemoryLengthUc -= PowerTwo;
+ CurrentBaseAddress -= GetPowerOfTwo64 (MemoryLengthUc);
+ UcCount++;
+ MtrrCount++;
+ if (MtrrCount > VariableMtrrCount) return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Calculate how many MTRRs needs if only use WB type
+ //
+ for (i = 0; i < 32; i++) {
+ if (Shr64(RemainMemoryLength, i) & 0x1 )
+ NumOfOne++;
+ }
+
+ //PEI_TRACE((-1, PeiServices, "Remain above 4G Memory Length = %08lx number of one = %x.\n", RemainMemoryLength, NumOfOne));
+
+ if (NumOfOne + MtrrCount < VariableMtrrCount){ //Use WB range is enough
+
+ CurrentBaseAddress = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ while(RemainMemoryLength)
+ {
+ PowerTwo = GetPowerOfTwo64 (RemainMemoryLength);
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = PowerTwo;
+ WbCount++;
+ CurrentBaseAddress += (UINT64)PowerTwo;
+ RemainMemoryLength -= (UINT64)PowerTwo;
+ MtrrCount++;
+ if (MtrrCount > VariableMtrrCount) return EFI_OUT_OF_RESOURCES;
+ }
+ } else{
+ //
+ // Use UC to overwrite WB memory
+ //
+ if ((RemainMemoryLength - GetPowerOfTwo64(RemainMemoryLength)) < SIZE_2G)
+ {
+ WbMap[WbCount].Base = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ WbMap[WbCount].Len = GetPowerOfTwo64(RemainMemoryLength);
+ RemainMemoryLength -= WbMap[WbCount].Len;
+ WbCount++;
+ MtrrCount++;
+ WbMap[WbCount].Base = WbMap[WbCount - 1].Base + WbMap[WbCount - 1].Len;
+ WbMap[WbCount].Len = GetPowerOfTwo64(Shl64(RemainMemoryLength,1));
+
+ MemoryLengthUc = WbMap[WbCount].Len - RemainMemoryLength;
+ CurrentBaseAddress = (WbMap[WbCount].Base + WbMap[WbCount].Len) - GetPowerOfTwo64(MemoryLengthUc);
+ if ((WbMap[WbCount].Len + WbMap[WbCount - 1].Len) == GetPowerOfTwo64(WbMap[WbCount].Len + WbMap[WbCount - 1].Len))
+ {
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+ } else {
+ WbCount++;
+ MtrrCount++;
+ }
+
+ } else{
+ WbMap[WbCount].Base = GetPowerOfTwo64(TotalAbove4GMemoryLength);
+ WbMap[WbCount].Len = GetPowerOfTwo64(Shl64(RemainMemoryLength,1));
+ if (WbMap[WbCount - 1].Len == WbMap[WbCount].Base){
+ // special case to save mtrr
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+ WbCount--;
+ MtrrCount--;
+ }
+
+ MemoryLengthUc = (WbMap[WbCount].Base + WbMap[WbCount].Len) - TotalAbove4GMemoryLength;
+ CurrentBaseAddress = (WbMap[WbCount].Base + WbMap[WbCount].Len) - GetPowerOfTwo64(MemoryLengthUc);
+ WbCount++;
+ MtrrCount++;
+ }
+ //PEI_TRACE((-1, PeiServices, "Above 4G UC Memory Length = %08lx base start at %08lx.\n", MemoryLengthUc, CurrentBaseAddress));
+ for (PowerTwo = GetPowerOfTwo64 (MemoryLengthUc);
+ CurrentBaseAddress >= TotalAbove4GMemoryLength; PowerTwo = GetPowerOfTwo64 (MemoryLengthUc)) {
+
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = PowerTwo;
+ MemoryLengthUc -= PowerTwo;
+ CurrentBaseAddress -= GetPowerOfTwo64 (MemoryLengthUc);
+ UcCount++;
+ MtrrCount++;
+ if (MtrrCount > VariableMtrrCount) return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy1 success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: NumOfOne
+//
+// Description: Count how many of ones in the binary value.
+//
+// Input:
+// IN UINT64 InputValue - Needed count value.
+//
+// Output:
+// UINT8 - Number of one.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 NumOfOne(
+ IN UINT64 InputValue)
+{
+ UINT8 i, j;
+
+ for (i = 0, j = 0; i < 40; i++) {
+ if (Shr64(InputValue, i) & 0x1 )
+ j++;
+ if (Shr64(InputValue, i) == 0)
+ break;
+ }
+ return j;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitMtrrPolicy2
+//
+// Description: Config system cache.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN PEI_CACHE_PPI *CachePpi
+// IN UINT64 Above4GMemoryLength
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitMtrrPolicy2 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN MEMORY_MAP *WbMap,
+ IN MEMORY_MAP *UcMap,
+ IN UINT64 Above4GMemoryLength
+)
+{
+ UINT64 TotalMemoryLength = Above4GMemoryLength + SIZE_4G;
+ UINT64 RemainMemoryLength;
+ UINT64 Below4GMemoryLength;
+ UINTN i;
+ UINT8 WbMtrrCountBelow4G1 = 0;
+ UINT8 WbMtrrCountBelow4G2 = 0;
+ UINT8 UcMtrrCountBelow4G1 = 0;
+ UINT8 UcMtrrCountBelow4G2 = 0;
+ UINT8 WbMtrrCountAbove4G1 = 0;
+ UINT8 WbMtrrCountAbove4G2 = 0;
+ UINT8 UcMtrrCountAbove4G1 = 0;
+ UINT8 UcMtrrCountAbove4G2 = 0;
+ UINT8 UcMtrrCountAbove4G3 = 0;
+ UINT8 UcMtrrCountAbove4G4 = 0;
+ UINT8 MtrrCountRemainMemory1 = 0;
+ UINT8 MtrrCountRemainMemory2 = 0;
+ UINT8 MtrrCountRemainMemory3 = 0;
+ UINT64 MemoryLength;
+ UINT8 PolicyOneMtrrCount = 0;
+ UINT8 PolicyTwoMtrrCount = 0;
+ UINT8 PolicyThreeMtrrCount = 0;
+ UINT8 PolicyFourMtrrCount = 0;
+ UINT8 PolicyFiveMtrrCount = 0;
+ UINT8 PolicySixMtrrCount = 0;
+ BOOLEAN WbSpecialCase1 = 0;
+ BOOLEAN WbSpecialCase2 = 0;
+
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+
+ //First, we calculate how many MTRR we need in different situation.
+ //1. Calculating MTRR when only use wb type in below 4G memory
+ //There are two size of Below4GMemoryLength. One is NBGetTsegBase() + TSEG_SIZE, the other is NBGetTsegBase().
+ //Therefore we have two calculating method to calculate wb MTRR below 4G memory.
+ //A.When Below4GMemoryLength is NBGetTsegBase()
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ WbMtrrCountBelow4G1 = NumOfOne(Below4GMemoryLength);
+
+ //B.When Below4GMemoryLength is NBGetTsegBase() + TSEG_SIZE
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ WbMtrrCountBelow4G2 = NumOfOne(Below4GMemoryLength);
+
+ //2. Calculating MTRR when use wb type from 0 to 4G, then use uc type to overwrite 4G to Below4GMemoryLength.
+ //There are two size of Below4GMemoryLength. One is NBGetTsegBase() + TSEG_SIZE, the other is NBGetTsegBase().
+ //Therefore we have two calculating method to calculate uc MTRR below 4G memory.
+ //A.When Below4GMemoryLength is NBGetTsegBase()
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ UcMtrrCountBelow4G1 = NumOfOne(((UINT64)SIZE_4G - Below4GMemoryLength));
+
+ //B.When Below4GMemoryLength is NBGetTsegBase() + TSEG_SIZE
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ UcMtrrCountBelow4G2 = NumOfOne(((UINT64)SIZE_4G - Below4GMemoryLength));
+
+ //3. Calculating MTRR when Memory above 4G is larger then 4G.
+ //A.If it's larger then 4G, memory above 4G should minus SIZE_4G and MTRR count should add 1.
+ //Next, if remain memory above 4G still larger than SIZE_8G, remain memory minus SIZE_8G and MTRR count should add 1.
+ //Next, if remain memory above 4G still larger than SIZE_16G, remain memory minus SIZE_16G and MTRR count should add 1. And so on.
+ RemainMemoryLength = Above4GMemoryLength;
+ MemoryLength = SIZE_4G;
+ for (MtrrCountRemainMemory1 = 0; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+ MtrrCountRemainMemory1++;
+ RemainMemoryLength -= MemoryLength;
+ }
+
+ //B.Calculating MTRR when use wb type till remain memory is smaller then 2G
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ for (MtrrCountRemainMemory2 = 0; RemainMemoryLength >= SIZE_2G;) {
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ MtrrCountRemainMemory2++;
+ RemainMemoryLength -= MemoryLength;
+ }
+
+ //C.Calculating MTRR when only use wb type in remain memory
+ WbMtrrCountAbove4G1 = NumOfOne(RemainMemoryLength) + MtrrCountRemainMemory2;
+
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting. This case only occur in Policy two.
+ if ((MtrrCountRemainMemory2 != 0) && (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1) == MemoryLength))
+ WbSpecialCase1 = 0;
+ else
+ WbSpecialCase1 = 1;
+
+ //D.Calculating MTRR when use uc type to overwrite wb type.
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1)) - RemainMemoryLength;
+ UcMtrrCountAbove4G2 = NumOfOne(RemainMemoryLength);
+
+ //4. Calculating MTRR when use uc type to overwrite wb type above 4G memory, there are two calculating methods.
+ //A.Set wb type from 4G to shl(PowerOfTwo64(TotalMemoryLength),1),
+ //then use uc to overwrite overflow wb memory.
+ RemainMemoryLength = TotalMemoryLength - Shl64(SIZE_4G , MtrrCountRemainMemory1);
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1)) - RemainMemoryLength;
+ UcMtrrCountAbove4G1 = NumOfOne(RemainMemoryLength);
+
+ //B.Set wb type from 0 to shl(PowerOfTwo64(TotalMemoryLength), 1),
+ //then use uc to overwrite overflow wb memory.
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (TotalMemoryLength), 1)) - TotalMemoryLength;
+ UcMtrrCountAbove4G3 = NumOfOne(RemainMemoryLength);
+
+ //5. Calculating MTRR when (TotalMemoryLength) minus PowerOfTwo64(TotalMemoryLength) is larger then 2G.
+ //A. Calculating MTRR when use wb type till remain memory is smaller then 2G
+ RemainMemoryLength = TotalMemoryLength - GetPowerOfTwo64(TotalMemoryLength);
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ for (MtrrCountRemainMemory3 = 0; RemainMemoryLength >= SIZE_2G;) {
+ MemoryLength = GetPowerOfTwo64(RemainMemoryLength);
+ MtrrCountRemainMemory3++;
+ RemainMemoryLength -= MemoryLength;
+ }
+ //B.Calculating MTRR when use wb type in Remain memory
+ WbMtrrCountAbove4G2 = NumOfOne(RemainMemoryLength) + MtrrCountRemainMemory3;
+
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting. This case only occur in Policy five.
+ if ((MtrrCountRemainMemory3 != 0) && (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1) == MemoryLength))
+ WbSpecialCase2 = 0;
+ else
+ WbSpecialCase2 = 1;
+
+ //C.Calculating MTRR when use uc type to overwrite wb type.
+ RemainMemoryLength = (Shl64(GetPowerOfTwo64 (RemainMemoryLength), 1)) - RemainMemoryLength;
+ UcMtrrCountAbove4G4 = NumOfOne(RemainMemoryLength);
+
+ //Second, Calculating MTRR for each setting MTRR policy.
+ //Policy 1:Only use wb type from 0 to Below4GMemoryLength, and 4G to TotalMemoryLength.
+ //
+ // _______ TotalMemoryLength
+ // |Wb Set |
+ // |-------| 4G
+ // |Uc Ori |
+ // |-------| Below4GMemoryLength
+ // |Wb Set |
+ // |_______| 0
+ //Chose which Below4GMemoryLength((NBGetTsegBase() + TSEG_SIZE) or NBGetTsegBase()) is better for below 4G memory MTRR setting.
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ PolicyOneMtrrCount = WbMtrrCountBelow4G1 + WbMtrrCountAbove4G1 + MtrrCountRemainMemory1;
+ else
+ PolicyOneMtrrCount = WbMtrrCountBelow4G2 + WbMtrrCountAbove4G1 + MtrrCountRemainMemory1;
+
+ //Policy 2:First, Use wb type from 0 to Below4GMemoryLength. Use wb type from 4G to 8G, 8G to 16G, and so on.
+ // Second, if remain memory larger then 2G , use wb type till remain memory samller then 2G. last, set wb type to shl(RemainMemory, 1).
+ // Third, use uc type from shl(RemainMemory, 1) to TotalMemoryLength.
+ // first Second third
+ // |-------| |-------| shl(RemainMemory, 1)
+ // | | |Uc Set |
+ // |Wb Set | |_______| TotalMemoryLength
+ // |-------| 4G |-------| 4G
+ // |Uc Ori | |Same |
+ // |-------| Below4GMemoryLength |as |
+ // |Wb Set | |first |
+ // |_______| 0 |_______| 0
+ //Chose which Below4GMemoryLength((NBGetTsegBase() + TSEG_SIZE) or NBGetTsegBase()) is better for below 4G memory MTRR setting.
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ PolicyTwoMtrrCount = WbMtrrCountBelow4G1 + MtrrCountRemainMemory1 + MtrrCountRemainMemory2 + WbSpecialCase1 + UcMtrrCountAbove4G2;
+ else
+ PolicyTwoMtrrCount = WbMtrrCountBelow4G2 + MtrrCountRemainMemory1 + MtrrCountRemainMemory2 + WbSpecialCase1 + UcMtrrCountAbove4G2;
+
+ //Policy 3: First, Use wb type from 0 to Below4GMemoryLength. Use wb type from 4G to 8G, 8G to 16G, and so on.
+ // Second, set wb type to shl(RemainMemory, 1).
+ // Third, use uc type form shl(RemainMemory, 1) to TotalMemoryLength;
+ // first Second third
+ // |-------| shl(PowerOfTwo64(TotalMemoryLength), 1) |-------| shl(PowerOfTwo64(TotalMemoryLength), 1)
+ // | | |Uc Set |
+ // |Wb Set | |_______| TotalMemoryLength
+ // |-------| 4G |-------| 4G
+ // |Uc Ori | |Same |
+ // |-------| Below4GMemoryLength |as |
+ // |Wb Set | |first |
+ // |_______| 0 |_______| 0
+ //Chose which Below4GMemoryLength((NBGetTsegBase() + TSEG_SIZE) or NBGetTsegBase()) is better for below 4G memory MTRR setting.
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ PolicyThreeMtrrCount = WbMtrrCountBelow4G1 + MtrrCountRemainMemory1 + 1 + UcMtrrCountAbove4G1;
+ else
+ PolicyThreeMtrrCount = WbMtrrCountBelow4G2 + MtrrCountRemainMemory1 + 1 + UcMtrrCountAbove4G1;
+
+ //Policy 4: First, use wb type from 0 to PowerOfTwo64(TotalMemoryLength).
+ // Second, use uc type from 4G to Below4GMemoryLength.
+ // Third, use wb type from PowerOfTwo64(TotalMemoryLength) to TotalMemoryLength.
+ // first second and third
+ // |--------| PowerOfTwo64(TotalMemoryLength) _______ TotalMemoryLength
+ // | | |Wb Set |
+ // |Wb Set | |-------| PowerOfTwo64(TotalMemoryLength)
+ // |ALL | | |
+ // | | |-------| 4G
+ // | | |Uc Set |
+ // | | |-------| Below4GMemoryLength
+ // |________| 0 |_______| 0
+ //Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ PolicyFourMtrrCount = 1 + UcMtrrCountBelow4G1 + WbMtrrCountAbove4G2;
+ else
+ PolicyFourMtrrCount = 1 + UcMtrrCountBelow4G2 + WbMtrrCountAbove4G2;
+
+ //Policy 5: First, use wb type from 0 to PowerOfTwo64(TotalMemoryLength).
+ // Second, use uc type from 4G to Below4GMemoryLength.
+ // Third, remain memory will be (TotalMemoryLength - PowerOfTwo64(TotalMemoryLength)) use wb type\
+ // from PowerOfTwo64(TotalMemoryLength) to shl(RemainMemory, 1).
+ // Four, use uc type from shl(RemainMemory, 1) to TotalMemoryLength.
+ // first second and third Four
+ // |--------| PowerOfTwo64(TotalMemoryLength) ------- shl(RemainMemory, 1) ------- shl(RemainMemory, 1)
+ // | | |_______| TotalMemoryLength |Uc Set |
+ // |Wb Set | |Wb Set | |_______| TotalMemoryLength
+ // |ALL | |-------| PowerOfTwo64(TotalMemoryLength) | |
+ // | | |-------| 4G |Same |
+ // | | |Uc Set | |as |
+ // | | |-------| Below4GMemoryLength |before |
+ // |________| 0 |_______| 0 |_______| 0
+ //Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ PolicyFiveMtrrCount = 1 + UcMtrrCountBelow4G1 + MtrrCountRemainMemory3 + WbSpecialCase2 + UcMtrrCountAbove4G4;
+ else
+ PolicyFiveMtrrCount = 1 + UcMtrrCountBelow4G2 + MtrrCountRemainMemory3 + WbSpecialCase2 + UcMtrrCountAbove4G4;
+
+ //Policy 6:First, use wb type to shl(PowerOfTwo64(TotalMemoryLength), 1).
+ // Second, use uc type from 4G to Below4GMemoryLength and
+ // Uc type from shl(PowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength.
+ // first second
+ // |--------| shl(PowerOfTwo64(TotalMemoryLength), 1) |-------| shl(PowerOfTwo64(TotalMemoryLength), 1)
+ // | | |Uc Set |
+ // |Wb Set | |_______| TotalMemoryLength
+ // |ALL | | |
+ // | | |-------| 4G
+ // | | |Uc Set |
+ // | | |-------| Below4GMemoryLength
+ // |________| 0 |_______| 0
+ //Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ PolicySixMtrrCount = 1 + UcMtrrCountBelow4G1 + UcMtrrCountAbove4G3;
+ else
+ PolicySixMtrrCount = 1 + UcMtrrCountBelow4G2 + UcMtrrCountAbove4G3;
+
+// PEI_TRACE((-1, PeiServices, "WbMtrrCountBelow4G1 = %d, WbMtrrCountBelow4G2 = %d.\n", WbMtrrCountBelow4G1, WbMtrrCountBelow4G2));
+// PEI_TRACE((-1, PeiServices, "UcMtrrCountBelow4G1 = %d, UcMtrrCountBelow4G2 = %d.\n", UcMtrrCountBelow4G1, UcMtrrCountBelow4G2));
+// PEI_TRACE((-1, PeiServices, "WbMtrrCountAbove4G1 = %d, WbMtrrCountAbove4G2= %d, UcMtrrCountAbove4G1 = %d.\n", WbMtrrCountAbove4G1, WbMtrrCountAbove4G2, UcMtrrCountAbove4G1));
+// PEI_TRACE((-1, PeiServices, "UcMtrrCountAbove4G2 = %d, UcMtrrCountAbove4G3 = %d, UcMtrrCountAbove4G4= %d.\n", UcMtrrCountAbove4G2, UcMtrrCountAbove4G3, UcMtrrCountAbove4G4));
+// PEI_TRACE((-1, PeiServices, "WbSpecialCase1 = %d, WbSpecialCase2 = %d.\n", WbSpecialCase1, WbSpecialCase2));
+// PEI_TRACE((-1, PeiServices, "MtrrCountRemainMemory1 = %d, MtrrCountRemainMemory2 = %d, MtrrCountRemainMemory3 = %d.\n", MtrrCountRemainMemory1, MtrrCountRemainMemory2, MtrrCountRemainMemory3));
+// PEI_TRACE((-1, PeiServices, "PolicyOneMtrrCount = %d, PolicyTwoMtrrCount = %d, PolicyThreeMtrrCount = %d.\n", PolicyOneMtrrCount, PolicyTwoMtrrCount, PolicyThreeMtrrCount));
+// PEI_TRACE((-1, PeiServices, "PolicyFourMtrrCount = %d, PolicyFiveMtrrCount = %d, PolicySixMtrrCount = %d.\n", PolicyFourMtrrCount, PolicyFiveMtrrCount, PolicySixMtrrCount));
+// PEI_TRACE((-1, PeiServices, "TsegBase = 0x%8lX, Above4GMemoryLength = 0x%8lX.\n", (UINT64)NBGetTsegBase(), Above4GMemoryLength));
+
+ //Policy one
+ if (PolicyOneMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ //2.Use wb type from 0 to Below4GMemoryLength
+ RemainMemoryLength = Below4GMemoryLength;
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //3.When memory above 4G is larger then 4G, set a wb type MTRR from 4G to 8G.
+ //Next, if remain memory above 4G still larger than 8G, set a wb type MTRR from 8G to 16G. And so on.
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = Above4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G;
+ for (MemoryLength = SIZE_4G; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //4.Next, set RemainMemoryLength to wb type.
+ if (Status == EFI_SUCCESS) {
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy one success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Two
+ if (PolicyTwoMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ //2.Use wb type from 0 to Below4GMemoryLength
+ RemainMemoryLength = Below4GMemoryLength;
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //3.When memory above 4G is larger then 4G, set a wb type MTRR from 4G to 8G.
+ //Next, if remain memory above 4G still larger than 8G, set a wb type MTRR from 8G to 16G. And so on.
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = Above4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G;
+ for (MemoryLength = SIZE_4G; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //4.Next, if remain memory larger than 2G, set wb type till remain memory smaller than 2G.
+ if (Status == EFI_SUCCESS) {
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength >= SIZE_2G; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+ }
+
+ //5. Set a wb type from CurrentBaseAddress to shl(PowerOfTwo64(RemainMemoryLength), 1)
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting.
+ if (((WbMap[WbCount - 1].Base + WbMap[WbCount - 1].Len) == WbMap[WbCount].Base) &&
+ (GetPowerOfTwo64(WbMap[WbCount - 1].Base) > WbMap[WbCount - 1].Len) &&
+ (WbMap[WbCount - 1].Len == WbMap[WbCount].Len)) {
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount - 1].Len, WbMap[WbCount - 1].Base, MtrrCount - 1));
+ }
+ else {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount].Len, CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ }
+
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+
+ //6.Next, set uc type from Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength, overwrite wb type.
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) - RemainMemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64(RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy two success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Three
+ if (PolicyThreeMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (WbMtrrCountBelow4G1 < WbMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+ //2.Use wb type from 0 to Below4GMemoryLength
+ RemainMemoryLength = Below4GMemoryLength;
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //3.When memory above 4G is larger then 4G, set a wb type MTRR from 4G to 8G.
+ //Next, if remain memory above 4G still larger than 8G, set a wb type MTRR from 8G to 16G.
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = Above4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G;
+ for (MemoryLength = SIZE_4G; RemainMemoryLength >= MemoryLength; MemoryLength = Shl64(MemoryLength, 1)) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += MemoryLength;
+ RemainMemoryLength -= MemoryLength;
+ }
+ }
+
+ //4.Next, set wb type from 4G to Shl64(GetPowerOfTwo64(RemainMemoryLength), 1).
+ RemainMemoryLength = TotalMemoryLength - CurrentBaseAddress;
+ if (Status == EFI_SUCCESS) {
+ if (RemainMemoryLength > 0) {
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", Shl64(GetPowerOfTwo64(RemainMemoryLength), 1), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) - RemainMemoryLength;
+ }
+ }
+
+ //5.Next, set uc type from Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) to RemainMemoryLength
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy three success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Four
+ if (PolicyFourMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ RemainMemoryLength = TotalMemoryLength;
+
+ //2.Set GetPowerOfTwo64(RemainMemoryLength) to wb type.
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = GetPowerOfTwo64(RemainMemoryLength);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", GetPowerOfTwo64(RemainMemoryLength), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += GetPowerOfTwo64(RemainMemoryLength);
+ RemainMemoryLength -= GetPowerOfTwo64(RemainMemoryLength);
+
+ //3.Next, use wb type from CurrentBaseAddress to TotalMemoryLength.
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress += MemoryLength;
+ }
+ }
+
+ //4.Next, use uc type from Below4GMemoryLength to 4G
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy four success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Five
+ if (PolicyFiveMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ RemainMemoryLength = TotalMemoryLength;
+
+ //2.Set GetPowerOfTwo64(RemainMemoryLength) to wb type.
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = GetPowerOfTwo64(RemainMemoryLength);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", GetPowerOfTwo64(RemainMemoryLength), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += GetPowerOfTwo64(RemainMemoryLength);
+ RemainMemoryLength -= GetPowerOfTwo64(RemainMemoryLength);
+
+ //3.Next, use wb type from CurrentBaseAddress till remain memory is smaller 2G.
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength >= SIZE_2G; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = MemoryLength;
+ MtrrCount++;
+ WbCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress += MemoryLength;
+ }
+ }
+
+ //4. Set a wb type from CurrentBaseAddress to shl(PowerOfTwo64(RemainMemoryLength), 1)
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+ //Special case for saving MTRR. If wb setting can combine with previous wb setting.
+ if (((WbMap[WbCount - 1].Base + WbMap[WbCount - 1].Len) == WbMap[WbCount].Base) &&
+ (GetPowerOfTwo64(WbMap[WbCount - 1].Base) > WbMap[WbCount - 1].Len) &&
+ (WbMap[WbCount - 1].Len == WbMap[WbCount].Len)) {
+ WbMap[WbCount - 1].Len += WbMap[WbCount].Len;
+ WbMap[WbCount].Base = 0;
+ WbMap[WbCount].Len = 0;
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount - 1].Len, WbMap[WbCount - 1].Base, MtrrCount - 1));
+ }
+ else {
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", WbMap[WbCount].Len, CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ }
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(RemainMemoryLength), 1);
+
+ //5.Next, set uc type from Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength, overwrite wb type.
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(RemainMemoryLength), 1) - RemainMemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64(RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ //6.Next, use uc type from Below4GMemoryLength to 4G
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy five success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+
+ //Initialize, just in case
+ if ((WbMap[0].Len != 0) || (UcMap[0].Len != 0)) {
+ for(i = 0; i < 10; i++){
+ WbMap[i].Len = 0;
+ UcMap[i].Len = 0;
+ }
+ }
+
+ //Policy Six
+ if (PolicySixMtrrCount <= VariableMtrrCount) {
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 CurrentBaseAddress = 0;
+ UINT8 MtrrCount = 0;
+ UINT8 WbCount = 0;
+ UINT8 UcCount = 0;
+
+ //1.Chose which Below4GMemoryLength is better for below 4G memory MTRR setting.
+ if (UcMtrrCountBelow4G1 < UcMtrrCountBelow4G2)
+ Below4GMemoryLength = (UINT64)NBGetTsegBase();
+ else
+ Below4GMemoryLength = (UINT64)NBGetTsegBase() + TSEG_SIZE;
+
+ //2.Set wb type from 0 to Shl64(GetPowerOfTwo64(TotalMemoryLength), 1).
+ WbMap[WbCount].Base = CurrentBaseAddress;
+ WbMap[WbCount].Len = Shl64(GetPowerOfTwo64(TotalMemoryLength), 1);
+// PEI_TRACE((-1, PeiServices, "WB Memory Length = %08lx at %09lx. MtrrCount = %x\n", Shl64(GetPowerOfTwo64(TotalMemoryLength), 1), CurrentBaseAddress, MtrrCount));
+ MtrrCount++;
+ WbCount++;
+ CurrentBaseAddress += Shl64(GetPowerOfTwo64(TotalMemoryLength), 1);
+
+ //3.Next, set uc type from Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) to TotalMemoryLength.
+ RemainMemoryLength = Shl64(GetPowerOfTwo64(TotalMemoryLength), 1) - TotalMemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64(RemainMemoryLength);
+ for (MemoryLength = GetPowerOfTwo64(RemainMemoryLength); RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+
+ //4.Next, use uc type from Below4GMemoryLength to 4G
+ if (Status == EFI_SUCCESS) {
+ RemainMemoryLength = SIZE_4G - Below4GMemoryLength;
+ CurrentBaseAddress = SIZE_4G - GetPowerOfTwo64 (RemainMemoryLength);
+ for (MemoryLength = SIZE_2G; RemainMemoryLength > 0; MemoryLength = GetPowerOfTwo64(RemainMemoryLength)) {
+ if (RemainMemoryLength >= MemoryLength) {
+// PEI_TRACE((-1, PeiServices, "UC Memory Length = %08lx at %09lx. MtrrCount = %x\n", MemoryLength, CurrentBaseAddress, MtrrCount));
+ if (MtrrCount >= VariableMtrrCount) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ UcMap[UcCount].Base = CurrentBaseAddress;
+ UcMap[UcCount].Len = MemoryLength;
+ MtrrCount++;
+ UcCount++;
+ RemainMemoryLength -= MemoryLength;
+ CurrentBaseAddress -= GetPowerOfTwo64 (RemainMemoryLength);
+ }
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ PEI_TRACE((-1, PeiServices, "Set MTRR policy six success. MtrrCount = %d\n", MtrrCount));
+ return EFI_SUCCESS;
+ }
+ }
+ PEI_TRACE((-1, PeiServices, "Set MTRR status = EFI_OUT_OF_RESOURCES\n"));
+ return EFI_OUT_OF_RESOURCES;
+}
+#endif
+
+#if PERF_TUNE_SUPPORT == 1
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CpuPeiIntelXtuDataInit
+//
+// Description:
+// Interl XTU utility data initialize in PEI phase
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi
+// IN EFI_BOOT_MODE BootMode
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuPeiIntelXtuDataInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+ EFI_STATUS Status;
+ BIOS_SETTING_DATA SettingData;
+ EFI_GUID PerfTunePpiGuid = PERF_TUNE_PPI_GUID;
+ EFI_GUID WdtPpiGuid = PERF_TUNE_WDT_PPI_GUID;
+ PERF_TUNE_PPI *PerfTunePpi;
+ PERF_TUNE_WDT_PPI *WdtPpi;
+ DDDT_PRESENT_FLAG_HOB *DddtPreFlagHob;
+ VOID *FirstHob;
+ UINT32 CpuSignature = GetCpuSignature();
+ UINT32 CpuSigNoVer = CpuSignature & 0xfffffff0;
+ UINT8 i;
+ UINT8 CpuCores = NumCpuCores();
+ UINT8 NumOcBins = 0;
+ UINT8 CpuImptype[] = {BIOS_1_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_2_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_3_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_4_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_5_CORE_RATIO_IMPLEMENTATION,\
+ BIOS_6_CORE_RATIO_IMPLEMENTATION };
+
+ OVERCLOCKING_CONFIG_HOB *OverclockConfigHob;
+ OVERCLOCKING_CONFIG_DATA *OverclockData;
+
+ if (CpuSigNoVer != IVY_BRIDGE)
+ NumOcBins = (UINT8)((UINT32)(ReadMsr(MSR_FLEX_RATIO)) >> 17) & 0x7;
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ DddtPreFlagHob = (DDDT_PRESENT_FLAG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &DddtPreFlagHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)DddtPreFlagHob)->Name, &gAmiDddtPreFlagHobGuid) == 0) {
+ break;
+ }
+ }
+
+ if(!EFI_ERROR(Status)){
+ //iGfx Core Current Max Dddt Flag set to 1 or 0
+ //if((DddtPreFlagHob->PresentFlag[BIOS_GRAPHICS_TURBO_RATIO_LIMIT_IMPLEMENTATION] == 0)||\
+ // (DddtPreFlagHob->PresentFlag[BIOS_GRAPHICS_CORE_VOLTAGE_IMPLEMENTATION] == 0))
+ // DddtPreFlagHob->PresentFlag[BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION] = 0;
+ //else
+ // DddtPreFlagHob->PresentFlag[BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION] = 1;
+ DddtPreFlagHob->PresentFlag[BIOS_IGFX_CORE_CURRENT_MAX_IMPLEMENTATION] = 0; //disable IGFX current MAX
+
+ //if Cpu is partial unlock or full unlock then turbo Core ratio dddt should not build.
+ PEI_TRACE((-1, PeiServices, "CPU PEI XTU data init CpuCores = %x\n", CpuCores));
+ for (i = 0; i < sizeof(CpuImptype); i++){
+ if(CpuCores < (i + 1)){
+ DddtPreFlagHob->PresentFlag[CpuImptype[i]] = 0;
+ }
+ }
+
+ //Force Runtime Turbo disable
+ if (NumOcBins)
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_ENABLE_IMPLEMENTATION] = 1;
+ else
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_ENABLE_IMPLEMENTATION] = 0;
+
+ //Overclocking Core Ratio Limit disable
+ if (!isXECoreRatioLimitSupported()){
+ DddtPreFlagHob->PresentFlag[BIOS_1_CORE_RATIO_IMPLEMENTATION] = 0;//One-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_2_CORE_RATIO_IMPLEMENTATION] = 0;//Two-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_3_CORE_RATIO_IMPLEMENTATION] = 0;//Three-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_4_CORE_RATIO_IMPLEMENTATION] = 0;//Four-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_5_CORE_RATIO_IMPLEMENTATION] = 0;//Five-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_6_CORE_RATIO_IMPLEMENTATION] = 0;//Six-core Flag
+ }
+
+ //Package Power Limit disable
+ // Skus that support Config TDP are not able to change power limit(MSR 0x610) in real time.
+ if (!isXETdcTdpLimitSupported() || (Shr64(ReadMsr(MSR_PLATFORM_INFO), 32) & (BIT1 | BIT2)) ){
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_IMPLEMENTATION] = 0; //Short TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_IMPLEMENTATION] = 0; //Extended TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_ENABLE_IMPLEMENTATION] = 0; //Short TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_ENABLE_IMPLEMENTATION] = 0; //Package TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TIME_WINDOW_IMPLEMENTATION] = 0; //Package TDP Time Window Flag
+ }
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 0;
+ DddtPreFlagHob->PresentFlag[BIOS_MAX_TURBO_MODE_CPU_VOLTAGE_IMPLEMENTATION] = 0;
+
+ //if cpu not support turbo mode, disable TDP, TDC, extend tdp, short tdp and all core ratio DDD table creation.
+ if(!isTurboModeSupported()){
+ DddtPreFlagHob->PresentFlag[BIOS_TURBO_ENABLE_IMPLEMENTATION] = 0; //Turbo Eanble Flag
+ DddtPreFlagHob->PresentFlag[BIOS_TDC_VALUE_IMPLEMENTATION] = 0; //TDC Flag
+ DddtPreFlagHob->PresentFlag[BIOS_TDP_VALUE_IMPLEMENTATION] = 0; //TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_1_CORE_RATIO_IMPLEMENTATION] = 0; //One-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_2_CORE_RATIO_IMPLEMENTATION] = 0; //Two-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_3_CORE_RATIO_IMPLEMENTATION] = 0; //Three-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_4_CORE_RATIO_IMPLEMENTATION] = 0; //Four-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_5_CORE_RATIO_IMPLEMENTATION] = 0; //Five-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_6_CORE_RATIO_IMPLEMENTATION] = 0; //Six-core Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_IMPLEMENTATION] = 0; //Short TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_IMPLEMENTATION] = 0; //Extended TDP Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SHORT_TDP_ENABLE_IMPLEMENTATION] = 0; //Short TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 0; //Runtime Turbo Overwride Flag
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_PLL_VOLTAGE_UNLOCK_ENABLE_IMPLEMENTATION] = 0; //Internal PLL overvoltage Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TDP_ENABLE_IMPLEMENTATION] = 0; //Package TDP Enable Flag
+ DddtPreFlagHob->PresentFlag[BIOS_EXTENDED_TIME_WINDOW_IMPLEMENTATION] = 0; //Package TDP Time Window Flag
+ /*
+ DddtPreFlagHob->PresentFlag[BIOS_OVERCLOCKING_ENABLE_IMPLEMENTATION] = 0; //Overclocking Lock Flag
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_IMPLEMENTATION] = 0; //Malibox: CPU Voltage Target Flag
+ DddtPreFlagHob->PresentFlag[BIOS_IA_CORE_VOLTAGE_MODE_IMPLEMENTATION] = 0; //Malibox: CPU Voltage Mode Flag
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_OFFSET_IMPLEMENTATION] = 0; //Malibox: CPU Voltage Offset Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_RATIO_IMPLEMENTATION] = 0; //Malibox: RING Ratio Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OVERRIDE_IMPLEMENTATION] = 0; //Malibox: RING Voltage Target Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_MODE_IMPLEMENTATION] = 0; //Malibox: RING Voltage Mode Flag
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OFFSET_IMPLEMENTATION] = 0; //Malibox: RING Voltage Offset Flag
+ DddtPreFlagHob->PresentFlag[BIOS_DYNAMIC_SVID_CONTROL_IMPLEMENTATION] = 0; //Malibox: SVID Control Flag
+ DddtPreFlagHob->PresentFlag[BIOS_SVID_VOLTAGE_OVERRIDE_IMPLEMENTATION] = 0; //Malibox: SVID Voltage Target Flag
+ DddtPreFlagHob->PresentFlag[BIOS_FIVR_FAULTS_IMPLEMENTATION] = 0; //Malibox: FIVR Faults Flag
+ DddtPreFlagHob->PresentFlag[BIOS_FIVR_EFFICIENCY_MANAGEMENT_IMPLEMENTATION] = 0; //Malibox: FIVR Efficiency Management Flag
+ */
+ }
+
+ if(!(isFullUnlockCpuSuuported())){
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_PLL_VOLTAGE_UNLOCK_ENABLE_IMPLEMENTATION] = 0; //Internal PLL overvoltage Enable Flag
+ }
+
+ if(!(isBCLKRatioSuuported())){
+ DddtPreFlagHob->PresentFlag[BIOS_PEG_DMI_RATIO_IMPLEMENTATION] = 0; // PEG/DMI ratio Enable Flag
+ }
+
+ DddtPreFlagHob->PresentFlag[BIOS_TDC_VALUE_IMPLEMENTATION] = 0; //TDC Flag
+ DddtPreFlagHob->PresentFlag[BIOS_TDP_VALUE_IMPLEMENTATION] = 0; //TDP Flag
+
+ OverclockConfigHob = (OVERCLOCKING_CONFIG_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &OverclockConfigHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)OverclockConfigHob)->Name, &gAmiOcConfigHobGuid) == 0) {
+ break;
+ }
+ }
+ if(!EFI_ERROR(Status)){
+ OverclockData = &OverclockConfigHob->OverclockData;
+ //Mailbox item
+ //IA core
+ if(!OverclockData->OCCap[IA].VoltageOverridesSupported){
+ DddtPreFlagHob->PresentFlag[BIOS_IA_CORE_VOLTAGE_MODE_IMPLEMENTATION] = 0;
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_IMPLEMENTATION] = 0;
+ }
+ if(!OverclockData->OCCap[IA].VoltageOffsetSupported)
+ DddtPreFlagHob->PresentFlag[BIOS_CPU_VOLTAGE_OFFSET_IMPLEMENTATION] = 0;
+ //RING
+ if(!OverclockData->OCCap[RING].RatioOcSupported)
+ DddtPreFlagHob->PresentFlag[BIOS_RING_RATIO_IMPLEMENTATION] = 0;
+ if(!OverclockData->OCCap[RING].VoltageOverridesSupported){
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_MODE_IMPLEMENTATION] = 0;
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OVERRIDE_IMPLEMENTATION] = 0;
+ }
+ if(!OverclockData->OCCap[RING].VoltageOffsetSupported)
+ DddtPreFlagHob->PresentFlag[BIOS_RING_VOLTAGE_OFFSET_IMPLEMENTATION] = 0;
+ }
+ }
+
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &PerfTunePpiGuid,
+ 0,
+ NULL,
+ &PerfTunePpi
+ );
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &WdtPpiGuid,
+ 0,
+ NULL,
+ &WdtPpi
+ );
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = PerfTunePpi->GetSettingData(PeiServices, &SettingData);
+ if(EFI_ERROR(Status)) return Status;
+
+ if(SettingData.RuntimeTurboEanble == 1 && NumOcBins != 0)
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 1;
+ else
+ DddtPreFlagHob->PresentFlag[BIOS_RUNTIME_TURBO_OVERRIDE_IMPLEMENTATION] = 0;
+
+ return Status;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CpuPeiMiscFuncs
+//
+// Description:
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi
+// IN EFI_BOOT_MODE BootMode
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuPeiMiscFuncs (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariablePpi,
+ IN EFI_BOOT_MODE BootMode
+)
+{
+
+#if PERF_TUNE_SUPPORT == 1
+ EFI_STATUS Status;
+
+ Status = CpuPeiIntelXtuDataInit(PeiServices, ReadOnlyVariablePpi, BootMode);
+#endif
+
+ return;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/CPU/CpuSmbios.c b/Core/CPU/CpuSmbios.c
new file mode 100644
index 0000000..aa0c42a
--- /dev/null
+++ b/Core/CPU/CpuSmbios.c
@@ -0,0 +1,734 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuSmbios.c 6 6/16/14 4:52a Davidhsieh $
+//
+// $Revision: 6 $
+//
+// $Date: 6/16/14 4:52a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/CpuSmbios.c $
+//
+// 6 6/16/14 4:52a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Support the cache size which bigger than 0x8000MB
+// [Files] AmiCpuInfo.h, CpuSmbios.c
+//
+// 5 8/14/13 4:53a Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Smbios CpuMaxSpeed value is from Cpu when token
+// SMBIOS_TYPE_4_MAX_SPEED is zero
+//
+// 4 2/27/13 5:00a Crystallee
+// [TAG] EIP115822
+// [Category] Improvement
+// [Description] Add SMBIOS type7 information for L4 cache if CPU
+// supported
+// And create a token to control this.
+//
+// 3 3/21/12 4:33a Davidhsieh
+//
+// 2 3/20/12 3:23a Davidhsieh
+// Create SMBIOS type4 and type7 in AMI CPU module part
+//
+// 1 2/07/12 3:58a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuSmbios.c
+//
+// Description:
+// Installs TYPE 4 and TYPE 7 SMBIOS tables.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include <Efi.h>
+#include <AmiLib.h>
+#include <Protocol\SmBios.h>
+#include <Protocol\AmiCpuInfo.h>
+#include <Protocol\AmiCpuInfo2.h>
+#include <AmiCspLibInc.h>
+#include <Token.h>
+#include "Cpu.h"
+#include "CpuDxe.h"
+
+extern AMI_CPU_INFO_PROTOCOL gAmiCpuInfoProtocol;
+extern PRIVATE_AMI_CPU_INFO_2_PROTOCOL *gPrivateAmiCpuInfo2;
+AMI_CPU_INFO *gGetCpuInfo = NULL;
+EFI_SMBIOS_PROTOCOL *gSmbiosProtocol;
+
+UINT32 GetCpuNumByPkgCoreThrd(
+ IN UINT32 Package,
+ IN UINT32 Core,
+ IN UINT32 Thread
+);
+
+UINT32 gType4Instance = 1;
+UINT32 gType7Instance = 1;
+
+EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
+
+EFI_EVENT gSmbiosEvent;
+VOID *gSmbiosRegistration = 0;
+
+UINT32 GetBoardSocketNumber(IN UINT32 ApicId);
+UINT8 GetCacheSharedThreads(IN UINT8 Level);
+
+CACHE_DESCRIPTOR_INFO *gCacheDescInfo;
+UINT8 gCacheTypeTable[] = {4, 3, 0, 5};
+UINT8 gAssociativityTable[] = {2, 6 ,4 ,1 ,5 ,1 ,1 ,1 ,7 ,1 ,1 ,1 ,9 ,1 ,1, 1, 8, 1, 1, 1, 0xe,
+ 1, 1, 1, 0xa, 1, 1, 1, 1, 1, 1, 1, 0xb
+};
+
+typedef struct {
+ UINT32 Size;
+ UINT8 Type;
+ UINT8 Assoc;
+} CACHE_INFO;
+
+#if !CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+CACHE_INFO gCacheInfo[3]; //[0] = L1, [1] = L2, [2] = L3
+#else
+CACHE_INFO gCacheInfo[4]; //[0] = L1, [1] = L2, [2] = L3, [3] = L4
+#endif
+
+#define SMBIOS_CACHE_ECC_PARITY 4
+#define SMBIOS_CACHE_ECC_SINGLE_BIT 5
+
+#define SMBIOS_MAX_NUM_SOCKETS 8
+
+CHAR8 *gSocketDesgination[8] = {
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_0),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_1),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_2),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_3),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_4),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_5),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_6),
+ CONVERT_TO_STRING(SMBIOS_TYPE_4_SOCKET_DESIGINTATION_SOCKET_7)
+};
+
+
+typedef struct {
+ //Private Data
+ UINT8 *StrBuf;
+ INT32 StrBufSize;
+ INT32 StrBufAvail;
+ UINT8 Tok;
+} SMBIOS_TABLE_STR_BUFFER;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EstablishStringBuffer
+//
+// Description: Initialize string buffer variables
+//
+// Input:
+// IN VOID *Buffer - Buffer address
+// IN UINT32 Size - Buffer Size
+// OUT SMBIOS_TABLE_STR_BUFFER **StrBuffer - String Buffer structure
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EstablishStringBuffer(
+ IN VOID *Buffer,
+ IN UINT32 Size,
+ OUT SMBIOS_TABLE_STR_BUFFER **StrBuffer
+)
+{
+ EFI_STATUS Status;
+ SMBIOS_TABLE_STR_BUFFER *Buf;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SMBIOS_TABLE_STR_BUFFER), &Buf);
+ ASSERT_EFI_ERROR(Status);
+
+ Buf->StrBuf = Buffer;
+ Buf->StrBufSize = Size;
+ Buf->StrBufAvail = Size;
+ Buf->Tok = 0;
+
+ *StrBuffer = Buf;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AddStrGetTok
+//
+// Description: Add string to buffer and return token value.
+//
+// Input:
+// IN SMBIOS_TABLE_STR_BUFFER *StrBuffer - String Buffer structure
+// IN UINT8 *Str - Pointer to string.
+//
+// Output: UINT8 - token of string
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 AddStrGetTok(
+ IN SMBIOS_TABLE_STR_BUFFER *StrBuffer,
+ IN UINT8 *Str
+)
+{
+ INT32 Len = (INT32)Strlen(Str);
+
+ if (Len == 0) return 0; //No string
+
+ //For string buffer, 2 bytes at end reserved for double 0, so that is why
+ //gStrBufAvail - 2
+ if (Len > (StrBuffer->StrBufAvail - 2)) return 0; //Not enough space left.
+
+ Strcpy(StrBuffer->StrBuf, Str);
+ StrBuffer->StrBuf += Len + 1;
+ StrBuffer->StrBufAvail -= Len + 1;
+ ++StrBuffer->Tok;
+ return StrBuffer->Tok;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetBufferSizeUsed
+//
+// Description: Get amount storage space used by strings.
+//
+// Input:
+// IN SMBIOS_TABLE_STR_BUFFER *StrBuffer - String Buffer structure
+//
+// Output: UINT32 - Size needed for strings.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetBufferSizeUsed(IN SMBIOS_TABLE_STR_BUFFER *StrBuffer)
+{
+ return StrBuffer->StrBufSize - StrBuffer->StrBufAvail;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RemoveStringBuffer
+//
+// Description: Remove String Buffer structure.
+//
+// Input:
+// IN SMBIOS_TABLE_STR_BUFFER *StrBuffer - String Buffer structure
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID RemoveStringBuffer(IN SMBIOS_TABLE_STR_BUFFER *StrBuffer)
+{
+ pBS->FreePool(StrBuffer);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetMaxSpeedFromBrandString
+//
+// Description: Get the max speed from the brand string.
+//
+// Input:
+// IN CHAR8 *CpuBrandString - Pointer to CPU brand string.
+//
+// Output: UINT32 - frequency found in MHz.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetMaxSpeedFromBrandString(IN CHAR8 *CpuBrandString)
+{
+ UINT32 i;
+ UINT8 CharCount;
+ BOOLEAN TransToMHz = FALSE;
+ BOOLEAN FreqStringFound = FALSE;
+ CHAR8 FrequencyString[] = "0000";
+
+ while (*CpuBrandString != 0) {
+ if (*CpuBrandString == 'G' && *(CpuBrandString + 1) == 'H' && *(CpuBrandString + 2) == 'z') {
+ FreqStringFound = TRUE;
+ TransToMHz = TRUE;
+ break;
+ } else if (*CpuBrandString == 'M' && *(CpuBrandString+1) == 'H' && *(CpuBrandString + 2) == 'z') {
+ FreqStringFound = TRUE;
+ break;
+ } else ++CpuBrandString;
+ }
+
+ --CpuBrandString; //first numeric char
+
+ //search numeric char
+ CharCount = 0;
+ for(i = 0 ; i < 4; ++i) {
+ if (*CpuBrandString >= '0' && *CpuBrandString <= '9') {
+ --CpuBrandString;
+ ++CharCount;
+ } else if (*CpuBrandString == '.') {
+ --CpuBrandString;
+ ++CharCount;
+ } else break;
+ }
+
+ ++CpuBrandString; //first numeric char
+
+ if (FreqStringFound && CharCount > 0) {
+ for(i = 0; i < CharCount; ++i) {
+ if (TransToMHz && *CpuBrandString == '.') CpuBrandString++;
+
+ FrequencyString[i] = *CpuBrandString;
+ ++CpuBrandString;
+ }
+ if (TransToMHz) FrequencyString[3] = '0';
+ } else FreqStringFound = FALSE;
+
+ return FreqStringFound ? Atoi(FrequencyString) : 0;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CollectCacheInfo
+//
+// Description: Store cache information in variables.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CollectCacheInfo()
+{
+ INT32 i;
+ UINT8 Type;
+ UINT8 Assoc;
+ UINT32 NumCores = NumSupportedCpuCores();
+
+ MemSet(gCacheInfo, sizeof(gCacheInfo), 0);
+
+ gCacheDescInfo = gGetCpuInfo->CacheInfo;
+ for(i = 0; gCacheDescInfo[i].Desc; ++i) { // End of descriptors, Desc = 0.
+ UINT8 Level = gGetCpuInfo->CacheInfo[i].Level;
+ switch(Level) {
+#if !CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ case 1: case 2: case 3:
+#else
+ case 1: case 2: case 3: case 4:
+#endif
+ Type = gCacheTypeTable[gCacheDescInfo[i].Type];
+
+ if (gCacheDescInfo[i].Associativity < sizeof(gAssociativityTable)/sizeof(UINT8))
+ Assoc = gAssociativityTable[gCacheDescInfo[i].Associativity];
+ else Assoc = 1;
+
+ //If multiple caches of same level, add sizes.
+ gCacheInfo[Level - 1].Size += gCacheDescInfo[i].Size;
+
+ //If multiple caches of same level have different types report as other.
+ if (gCacheInfo[Level - 1].Type == 0) gCacheInfo[Level - 1].Type = Type;
+ else if (gCacheInfo[Level - 1].Type != Type) gCacheInfo[Level - 1].Type = 1;
+
+ if (gCacheInfo[Level - 1].Assoc == 0) gCacheInfo[Level - 1].Assoc = Assoc;
+ else if (gCacheInfo[Level - 1].Assoc != Assoc) gCacheInfo[Level - 1].Assoc = 1;
+ }
+ }
+
+ if (GetCacheSharedThreads(1) <= 2) gCacheInfo[0].Size *= NumCores;
+ if (GetCacheSharedThreads(2) <= 2) gCacheInfo[1].Size *= NumCores;
+ if (GetCacheSharedThreads(3) <= 2) gCacheInfo[2].Size *= NumCores;
+#if CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ if (GetCacheSharedThreads(4) <= 2) gCacheInfo[3].Size *= NumCores;
+#endif
+}
+
+#define TYPE7_STRING_BUFFER_SIZE 100
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateSmbiosTable7
+//
+// Description: Create SMBIOS Table 7
+//
+// Input: IN UINT8 CacheLevel (L1, L2, L3)
+//
+// Output: UINT16 - Handle for table.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 CreateSmbiosTable7(IN UINT8 CacheLevel)
+{
+ SMBIOS_CACHE_INFO *CacheInfo;
+ UINT16 Handle;
+ EFI_STATUS Status;
+ UINT32 Type7ActStrBufSize;
+ SMBIOS_TABLE_STR_BUFFER *StrBuffer;
+
+ if (gCacheInfo[CacheLevel-1].Size == 0) return 0xffff;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(SMBIOS_CACHE_INFO) + TYPE7_STRING_BUFFER_SIZE, &CacheInfo);
+ ASSERT_EFI_ERROR(Status);
+
+ EstablishStringBuffer((UINT8*)CacheInfo + sizeof(SMBIOS_CACHE_INFO), TYPE7_STRING_BUFFER_SIZE, &StrBuffer);
+
+ Handle = gSmbiosProtocol->SmbiosGetFreeHandle();
+
+ CacheInfo->StructureType.Type = 7;
+ CacheInfo->StructureType.Length = 0x13;
+ CacheInfo->StructureType.Handle = Handle;
+ CacheInfo->SocketDesignation = 0;
+
+ if(gCacheInfo[CacheLevel-1].Size > 0x07FFF){
+ CacheInfo->MaxCacheSize = 0x8000 | (gCacheInfo[CacheLevel-1].Size / 64);
+ CacheInfo->InstalledSize = 0x8000 | (gCacheInfo[CacheLevel-1].Size / 64);
+ } else {
+ CacheInfo->MaxCacheSize = gCacheInfo[CacheLevel-1].Size;
+ CacheInfo->InstalledSize = gCacheInfo[CacheLevel-1].Size;
+ }
+
+ CacheInfo->SystemCacheType = gCacheInfo[CacheLevel-1].Type;
+ CacheInfo->Associativity = gCacheInfo[CacheLevel-1].Assoc;
+
+ switch (CacheLevel) {
+ case 1:
+ CacheInfo->CacheConfig = 0x180;
+#ifdef SMBIOS_TYPE_7_L1_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L1_SOCKET_DESIGNATION));
+#endif
+ break;
+ case 2:
+ CacheInfo->CacheConfig = 0x181;
+#ifdef SMBIOS_TYPE_7_L2_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L2_SOCKET_DESIGNATION));
+#endif
+ break;
+ case 3:
+ CacheInfo->CacheConfig = 0x182;
+#ifdef SMBIOS_TYPE_7_L3_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L3_SOCKET_DESIGNATION));
+#endif
+ break;
+#if CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ case 4:
+ CacheInfo->CacheConfig = 0x183;
+#ifdef SMBIOS_TYPE_7_L4_SOCKET_DESIGNATION
+ CacheInfo->SocketDesignation = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_7_L4_SOCKET_DESIGNATION));
+#endif
+ break;
+#endif
+ }
+
+ CacheInfo->SupportSRAM = 2;
+ CacheInfo->CurrentSRAM = 2;
+ CacheInfo->CacheSpeed = 0;
+ CacheInfo->ErrorCorrectionType = 0x05; //ECC
+ Type7ActStrBufSize = GetBufferSizeUsed(StrBuffer);
+
+ if (Type7ActStrBufSize == 0) {
+ *(UINT16*)(CacheInfo + 1) = 0; //Double NULL.
+ } else {
+ *((UINT8*)(CacheInfo + 1) + Type7ActStrBufSize) = 0; //End structure of NULL.
+ }
+
+ Status = gSmbiosProtocol->SmbiosAddStrucByHandle(
+ Handle,
+ (VOID*)CacheInfo,
+ (UINT16)(sizeof(SMBIOS_CACHE_INFO) + (Type7ActStrBufSize == 0 ? 2 : Type7ActStrBufSize + 1))
+ );
+
+ pBS->FreePool(CacheInfo);
+ RemoveStringBuffer(StrBuffer);
+
+ return !EFI_ERROR(Status) ? Handle : 0xffff;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AutodetectFamily
+//
+// Description: Return family type from Brand String.
+//
+// Input: IN CHAR8 *BrandString
+//
+// Output: UINT8 - Family
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 AutodetectFamily(IN CHAR8 *BrandString)
+{
+ CHAR8 *p = BrandString;
+
+ while(*p) {
+ if (MemCmp(p, "Xeon", 4) == 0) return 0xb3;
+ if (MemCmp(p, "i7", 2) == 0) return 0xc6;
+ if (MemCmp(p, "i5", 2) == 0) return 0xcd;
+ if (MemCmp(p, "i3", 2) == 0) return 0xce;
+ if (MemCmp(p, "Pentiu", 6) == 0) return 0x0b;
+ if (MemCmp(p, "Celero", 6) == 0) return 0x0f;
+ ++p;
+ }
+
+ return 0xcd; //default as i5 family
+}
+
+#define TYPE4_STRING_BUFFER_SIZE 200
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateSmbiosTable4
+//
+// Description: Create SMBIOS Table 4
+//
+// Input: IN UINT32 PhysSocket
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateSmbiosTable4(IN UINT32 PhysSocket)
+{
+ SMBIOS_PROCESSOR_INFO * ProcInfo;
+ EFI_STATUS Status;
+ UINT32 ActStrBufSize;
+ UINT32 MaxFreqBrandStr;
+ SMBIOS_TABLE_STR_BUFFER *StrBuffer;
+ SMBIOS_STRUCTURE_HEADER *Hdr;
+ UINT16 Size;
+ BOOLEAN HandleExists = FALSE;
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData, sizeof(SMBIOS_PROCESSOR_INFO) + TYPE4_STRING_BUFFER_SIZE, &ProcInfo
+ );
+
+ EstablishStringBuffer((UINT8*)ProcInfo + sizeof(SMBIOS_PROCESSOR_INFO), TYPE4_STRING_BUFFER_SIZE, &StrBuffer);
+
+ ProcInfo->StructureType.Type = 4;
+ ProcInfo->StructureType.Length = 0x2a;
+ ProcInfo->StructureType.Handle = 0xffff; //To be updated by SMBIOS driver.
+
+ if (PhysSocket >= SMBIOS_MAX_NUM_SOCKETS) ProcInfo->SocketDesignation = 0;
+ else ProcInfo->SocketDesignation = AddStrGetTok(StrBuffer, gSocketDesgination[PhysSocket]);
+
+ ProcInfo->ProcessotType = 3; //Central processor
+
+ if (SMBIOS_TYPE_4_PROC_FAMILY != 0) ProcInfo->Family = SMBIOS_TYPE_4_PROC_FAMILY;
+ else ProcInfo->Family = AutodetectFamily(gGetCpuInfo->BrandString);
+
+ ProcInfo->ProcessorManufacturer = AddStrGetTok(StrBuffer, "Intel");
+
+ ProcInfo->ProcessorID_1 = (UINT32)(gGetCpuInfo->Version);
+ ProcInfo->ProcessorID_2 = (UINT32)(gGetCpuInfo->Features);
+ ProcInfo->ProcessorVersion = AddStrGetTok(StrBuffer, gGetCpuInfo->BrandString);
+ ProcInfo->Voltage = (UINT8)(12) + BIT7; // 1.2 volts
+ //ProcInfo->Voltage = BIT7; // 1.2 volts
+ ProcInfo->MaxSpeed = SMBIOS_TYPE_4_MAX_SPEED;
+
+ MaxFreqBrandStr = GetMaxSpeedFromBrandString(gGetCpuInfo->BrandString);
+ if (MaxFreqBrandStr) ProcInfo->CurrentSpeed = MaxFreqBrandStr;
+ else ProcInfo->CurrentSpeed = gGetCpuInfo->IntendedFreq;
+
+#if !SMBIOS_TYPE_4_MAX_SPEED
+ ProcInfo->MaxSpeed = ProcInfo->CurrentSpeed;
+#endif
+ ProcInfo->ExtClockFreq = (UINT16)(gGetCpuInfo->FSBFreq);
+ ProcInfo->Status = 0x41; //Populated and enabled.
+ ProcInfo->Upgrade = SMBIOS_TYPE_4_PROC_UPGRADE;
+ ProcInfo->SerialNumber = 0;
+
+#ifdef SMBIOS_TYPE_4_ASSET_TAG
+ ProcInfo->AssetTag = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_4_ASSET_TAG));
+#else
+ ProcInfo->AssetTag = 0;
+#endif
+#ifdef SMBIOS_TYPE_4_PART_NUMBER
+ ProcInfo->PartNumber = AddStrGetTok(StrBuffer, CONVERT_TO_STRING(SMBIOS_TYPE_4_PART_NUMBER));
+#else
+ ProcInfo->PartNumber = 0;
+#endif
+ ProcInfo->CoreCount = NumSupportedCpuCores(); //This must be the same across sockets.
+ ProcInfo->CoreEnabled = gGetCpuInfo->NumCores;
+ ProcInfo->ThreadCount = NumSupportedCpuCores() * NumSupportedThreadsPerCore(); //This must be the same across sockets.
+ ProcInfo->ProcessorChar = 4; //X64 Support
+ ProcInfo->Family2 = ProcInfo->Family;
+
+ ActStrBufSize = GetBufferSizeUsed(StrBuffer);
+ if (ActStrBufSize == 0) {
+ *(UINT16*)(ProcInfo + 1) = 0; //Double NULL.
+ } else {
+ *((UINT8*)(ProcInfo + 1) + ActStrBufSize) = 0; //End structure of NULL.
+ }
+
+ Status = gSmbiosProtocol->SmbiosAddStructure(
+ (VOID*)ProcInfo,
+ (UINT16)(sizeof(SMBIOS_PROCESSOR_INFO) + (ActStrBufSize == 0 ? 2 : ActStrBufSize + 1))
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gSmbiosProtocol->SmbiosReadStrucByType(4, 1, (UINT8**)&Hdr, &Size);
+ ProcInfo->StructureType.Handle = Hdr->Handle;
+ ProcInfo->L1CacheHandle = CreateSmbiosTable7(1);
+ ProcInfo->L2CacheHandle = CreateSmbiosTable7(2);
+ ProcInfo->L3CacheHandle = CreateSmbiosTable7(3);
+#if CPU_CACHE_L4_DISPLAY_IN_SMBIOS
+ CreateSmbiosTable7(4);
+#endif
+ Status = gSmbiosProtocol->SmbiosWriteStructure(
+ ProcInfo->StructureType.Handle,
+ (VOID*)ProcInfo,
+ (UINT16)(sizeof(SMBIOS_PROCESSOR_INFO) + (ActStrBufSize == 0 ? 2 : ActStrBufSize + 1))
+ );
+
+ pBS->FreePool(ProcInfo);
+ RemoveStringBuffer(StrBuffer);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateCpuSmbiosTables
+//
+// Description: Create CPU SMBIOS Tables 4 and 7.
+//
+// Input:
+// IN EFI_EVENT Event - Not used
+// IN VOID *Context - Note Used
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateCpuSmbiosTables(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT32 NumSocketsPop = NumberOfCpuSocketsPopulated();
+ UINT32 SocketPopBitmap = 0;
+ SMBIOS_STRUCTURE_HEADER *Hdr;
+ UINT16 Size;
+ UINT32 Cpu;
+
+ ASSERT(NUMBER_CPU_SOCKETS <= SMBIOS_MAX_NUM_SOCKETS);
+
+ Status = pBS->LocateProtocol(&gEfiSmbiosProtocolGuid, NULL, &gSmbiosProtocol);
+ if (EFI_ERROR(Status)) return; //First call, error, because protocol not installed yet.
+
+//Delete existing CPU SBIOS structures type 4 and type 7.
+ while (!EFI_ERROR(gSmbiosProtocol->SmbiosReadStrucByType(4, 1, (UINT8**)&Hdr, &Size))) {
+ gSmbiosProtocol->SmbiosDeleteStructure(Hdr->Handle);
+ pBS->FreePool(Hdr);
+ }
+
+ while (!EFI_ERROR(gSmbiosProtocol->SmbiosReadStrucByType(7, 1, (UINT8**)&Hdr, &Size))) {
+ gSmbiosProtocol->SmbiosDeleteStructure(Hdr->Handle);
+ pBS->FreePool(Hdr);
+ }
+
+//Add CPU SMBIOS structures for populated sockets.
+ Cpu = 0;
+ for (i = 0; i < NumSocketsPop; ++i) {
+ UINT32 ApicId;
+ UINT32 PhysSocket;
+
+ Status = gAmiCpuInfoProtocol.GetCpuInfo(&gAmiCpuInfoProtocol, Cpu, &gGetCpuInfo);
+ ASSERT_EFI_ERROR(Status);
+
+ CollectCacheInfo(); //For one thread.
+
+ Status = ((AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2)->GetApicInfo(
+ (AMI_CPU_INFO_2_PROTOCOL*)gPrivateAmiCpuInfo2, i, 0, 0, &ApicId, NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) ApicId = 0;
+ PhysSocket = GetBoardSocketNumber(ApicId);
+
+ CreateSmbiosTable4(PhysSocket);
+ if (PhysSocket < SMBIOS_MAX_NUM_SOCKETS) SocketPopBitmap |= 1 << PhysSocket;
+
+ //Update Cpu from gGetCpuInfo
+ Cpu += gGetCpuInfo->NumCores * (gGetCpuInfo->NumHts == 0 ? 1 : 2);
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CpuSmbios
+//
+// Description: Create CPU SMBIOS Tables. Installs notification on SMBIOS handlers.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CpuSmbios()
+{
+ EFI_STATUS Status;
+
+ Status = RegisterProtocolCallback(
+ &gEfiSmbiosProtocolGuid,
+ CreateCpuSmbiosTables,
+ NULL,
+ &gSmbiosEvent,
+ &gSmbiosRegistration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ CreateCpuSmbiosTables(gSmbiosEvent, NULL);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/CpuSpSmi.DXS b/Core/CPU/CpuSpSmi.DXS
new file mode 100644
index 0000000..9362072
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.DXS
@@ -0,0 +1,59 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.DXS 1 2/07/12 4:00a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 4:00a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.DXS $
+//
+// 1 2/07/12 4:00a Davidhsieh
+//
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuSpSmi.DXS
+//
+// Description: Dependency file for the CpuSp SMI
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CpuSpSmi.h"
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CPU/CpuSpSmi.c b/Core/CPU/CpuSpSmi.c
new file mode 100644
index 0000000..bd4469d
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.c
@@ -0,0 +1,568 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.c 8 5/24/15 11:37p Davidhsieh $
+//
+// $Revision: 8 $
+//
+// $Date: 5/24/15 11:37p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.c $
+//
+// 8 5/24/15 11:37p Davidhsieh
+// [TAG] EIP215675
+// [Category] New Feature
+// [Description] Smm Access Check feautre support
+// [Files] Cpu.sdl, CpuDxe.c, CpuSpSmi.sdl, CpuSpsmi.c
+//
+// 7 10/08/13 3:10a Crystallee
+// [TAG] EIP137873
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CPU Security Configuration(MSR 4E0[0]) will be changed
+// after S3 resume
+// [RootCause] Didn't restore the Cpu MSR 4e0 while S3 resume.
+// [Solution] Restore the Cpu MSR 0x4E0 while S3 resume.
+//
+// 6 1/24/13 10:45p Davidhsieh
+// [TAG] EIP112381
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TBoot S3 resume fail
+// [RootCause] MSR 0x2e7 is not restored
+// [Solution] Save and restore MSR 0x2e7 for S3
+//
+// 5 12/18/12 9:23p Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Check CPU before lock SMM_FEATURE_CONTROL MSR
+//
+// 4 12/09/12 10:35p Davidhsieh
+// [TAG] None
+// [Category] Improvement
+// [Description] Lock SMM_FEATURE_CONTROL MSR
+//
+// 3 10/04/12 9:20a Davidhsieh
+// Change the procedure of configuring MTRR
+//
+// 2 7/10/12 2:51a Davidhsieh
+// [TAG] EIP93180
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The "Event Kernel-Power 137" error event log shows while
+// resumed from S3
+// [RootCause] The fixed and variable Mtrrs of BSP are not restored
+// [Solution] Restore BPS's mtrss
+//
+// 1 2/07/12 4:00a Davidhsieh
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuSpSmi.C
+//
+// Description: Provide functions to CPU specific SMI
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CpuSpSmi.h"
+
+UINT64 ReadMsr (UINT32 Msr);
+VOID WriteMsr(UINT32 Msr, UINT64 Value);
+
+UINTN MpMtrrSynchUpEntry (VOID);
+VOID MpMtrrSynchUpExit (UINTN Cr4);
+
+EFI_GUID SwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+
+EFI_SMM_SYSTEM_TABLE *mSmst;
+EFI_SMM_BASE_PROTOCOL *pSmmBase;
+EFI_SMM_SW_DISPATCH_PROTOCOL *gSwDispatch;
+
+//
+// MSR table for S3 resume
+//
+EFI_MSR_VALUES mFixedMtrrValues[] = {
+ { MTRR_FIX_64K_00000, 0 },
+ { MTRR_FIX_16K_80000, 0 },
+ { MTRR_FIX_16K_A0000, 0 },
+ { MTRR_FIX_4K_C0000, 0 },
+ { MTRR_FIX_4K_C8000, 0 },
+ { MTRR_FIX_4K_D0000, 0 },
+ { MTRR_FIX_4K_D8000, 0 },
+ { MTRR_FIX_4K_E0000, 0 },
+ { MTRR_FIX_4K_E8000, 0 },
+ { MTRR_FIX_4K_F0000, 0 },
+ { MTRR_FIX_4K_F8000, 0 },
+ { 0, 0 }
+};
+
+EFI_MSR_VALUES mVariableMtrrValues[] = {
+ { MTRR_PHYS_BASE_0, 0 },
+ { MTRR_PHYS_MASK_0, 0 },
+ { MTRR_PHYS_BASE_1, 0 },
+ { MTRR_PHYS_MASK_1, 0 },
+ { MTRR_PHYS_BASE_2, 0 },
+ { MTRR_PHYS_MASK_2, 0 },
+ { MTRR_PHYS_BASE_3, 0 },
+ { MTRR_PHYS_MASK_3, 0 },
+ { MTRR_PHYS_BASE_4, 0 },
+ { MTRR_PHYS_MASK_4, 0 },
+ { MTRR_PHYS_BASE_5, 0 },
+ { MTRR_PHYS_MASK_5, 0 },
+ { MTRR_PHYS_BASE_6, 0 },
+ { MTRR_PHYS_MASK_6, 0 },
+ { MTRR_PHYS_BASE_7, 0 },
+ { MTRR_PHYS_MASK_7, 0 },
+ { MTRR_PHYS_BASE_8, 0 },
+ { MTRR_PHYS_MASK_8, 0 },
+ { MTRR_PHYS_BASE_9, 0 },
+ { MTRR_PHYS_MASK_9, 0 }
+};
+
+#define MiscMsrCount 1
+
+EFI_MSR_VALUES mMiscMsrValues[] = {
+ { 0x2e7, 0 }
+};
+
+EFI_MSR_VALUES mSmmFeatureCtrl = { 0x4e0, 0};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveCpuMsr
+//
+// Description: This function saves the CPU MSRs for S3 resume usage.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SaveCpuMsr(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UINT32 i;
+
+ if (Shr64(ReadMsr(0x17d),57) & 0x03){
+ if (!(ReadMsr(mSmmFeatureCtrl.Index) && 0x01))
+ WriteMsr(mSmmFeatureCtrl.Index, ReadMsr(mSmmFeatureCtrl.Index) | 0x01);
+ mSmmFeatureCtrl.Value = ReadMsr(mSmmFeatureCtrl.Index);
+ }
+
+ //Save Fixed MTRR
+ for(i=0; i < NUM_OF_FIXED_MTRRS; i++)
+ {
+ mFixedMtrrValues[i].Value = ReadMsr(mFixedMtrrValues[i].Index);
+ }
+
+ //Save variable MTRR
+ for (i = 0; i < ((UINT8)(ReadMsr(MSR_IA32_MTRR_CAP) & VCNT_MASK)); i++)
+ {
+ mVariableMtrrValues[i * 2].Value = ReadMsr(mVariableMtrrValues[i * 2].Index);
+ mVariableMtrrValues[i * 2 + 1].Value = ReadMsr(mVariableMtrrValues[i * 2 + 1].Index);
+ }
+
+ mMiscMsrValues[0].Value = ReadMsr(mMiscMsrValues[0].Index);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreMsrOnCpu
+//
+// Description: This function restores the CPU MSRs during S3 resume.
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RestoreMsrOnCpu(IN VOID *data)
+{
+ UINT32 i;
+ UINTN Cr4;
+
+ Cr4 = MpMtrrSynchUpEntry();
+
+ //Restore Fixed MTRR
+ for(i=0; i < NUM_OF_FIXED_MTRRS; i++)
+ {
+ WriteMsr(mFixedMtrrValues[i].Index, mFixedMtrrValues[i].Value );
+ }
+
+ //Restore variable MTRR
+ for (i = 0; i < ((UINT8)(ReadMsr(MSR_IA32_MTRR_CAP) & VCNT_MASK)); i++)
+ {
+ WriteMsr(mVariableMtrrValues[i * 2].Index, mVariableMtrrValues[i * 2].Value );
+ WriteMsr(mVariableMtrrValues[i * 2 + 1].Index, mVariableMtrrValues[i * 2 + 1].Value );
+ }
+
+ MpMtrrSynchUpExit (Cr4);
+
+ WriteMsr(mMiscMsrValues[0].Index, mMiscMsrValues[0].Value);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreCpuMsr
+//
+// Description: This function restores the CPU MSRs during S3 resume.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RestoreCpuMsr(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UINT32 i;
+ UINTN Cr4;
+
+ if (Shr64(ReadMsr(0x17d),57) & 0x03){
+ if (!(ReadMsr(mSmmFeatureCtrl.Index) && 0x01)){
+ WriteMsr(mSmmFeatureCtrl.Index, (mSmmFeatureCtrl.Value & ~0x01));
+ WriteMsr(mSmmFeatureCtrl.Index, ReadMsr(mSmmFeatureCtrl.Index) | 0x01);
+ }
+ }
+
+ for (i = 0; i < pSmst->NumberOfCpus; ++i) {
+ pSmst->SmmStartupThisAp(RestoreMsrOnCpu, i, NULL);
+ }
+
+ Cr4 = MpMtrrSynchUpEntry();
+ RestoreMsrOnCpu(NULL);
+ MpMtrrSynchUpExit (Cr4);
+}
+
+#define SMRAM_CPU_DATA_VARIABLE_GUID \
+ { \
+ 0x429501d9, 0xe447, 0x40f4, 0x86, 0x7b, 0x75, 0xc9, 0x3a, 0x1d, 0xb5, 0x4e \
+ }
+
+#define SMRAM_CPU_DATA_VARIABLE L"SmramCpuDataVar"
+
+#define SMM_FROM_CPU_DRIVER_SAVE_INFO 0x81
+
+EFI_GUID mSmramCpuDataVariableGuid = SMRAM_CPU_DATA_VARIABLE_GUID;
+BOOLEAN mLocked = FALSE;
+
+/**
+ Dispatch function for a Software SMI handler.
+
+ @param DispatchHandle The handle of this dispatch function.
+ @param DispatchContext The pointer to the dispatch function's context.
+ The SwSmiInputValue field is filled in
+ by the software dispatch driver prior to
+ invoking this dispatch function.
+ The dispatch function will only be called
+ for input values for which it is registered.
+
+ @return None
+
+**/
+VOID
+EFIAPI
+SmramSaveInfoHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+/**
+
+@brief
+
+ Dispatch function for a Software SMI handler
+
+ @param[in] DispatchHandle - The handle of this dispatch function.
+ @param[in] DispatchContext - The pointer to the dispatch function's context.
+
+
+**/
+{
+ EFI_STATUS Status;
+ UINT64 VarData[3];
+ UINTN VarSize;
+
+ if (!mLocked && IoRead8 (SW_SMI_IO_ADDRESS+1) == SMM_FROM_CPU_DRIVER_SAVE_INFO) {
+ VarSize = sizeof (VarData);
+ Status = pRS->GetVariable (
+ SMRAM_CPU_DATA_VARIABLE,
+ &mSmramCpuDataVariableGuid,
+ NULL,
+ &VarSize,
+ VarData
+ );
+ if (!EFI_ERROR (Status) && VarSize == sizeof (VarData)) {
+ MemCpy (
+ (VOID *) (UINTN) (VarData[0]),
+ (VOID *) (UINTN) (VarData[1]),
+ (UINTN) (VarData[2])
+ );
+ }
+
+ mLocked = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuSmmFeatureEn
+//
+// Description:
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CpuSmmFeatureEn(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+
+ UINT64 MsrData;
+
+ if (Shr64(ReadMsr(0x17d),58) & 0x01){
+ if (!(ReadMsr(0x4e0) && 0x01)){
+ MsrData = ReadMsr(0x4e0);
+ MsrData |= 0x4;
+ WriteMsr(0x4e0, MsrData);
+ }
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: Called from InstallSmiHandler
+//
+// Input:
+//
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ EFI_SMM_SW_DISPATCH_CONTEXT Save_CPU_MSR = {SW_SMI_SAVE_MSR};
+ EFI_SMM_SW_DISPATCH_CONTEXT Restore_CPU_MSR = {SW_SMI_RESTORE_MSR};
+ EFI_SMM_SW_DISPATCH_CONTEXT CpuDriverSaveInfo = { SMM_FROM_SMBASE_DRIVER };
+ EFI_SMM_SW_DISPATCH_CONTEXT CpuSmmFeatureEnable = {SW_SMI_ENABLE_SMM_FEATURE};
+
+ Status = pBS->LocateProtocol(&SwDispatchProtocolGuid,NULL,&gSwDispatch);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ SaveCpuMsr,
+ &Save_CPU_MSR,
+ &Handle
+ );
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ RestoreCpuMsr,
+ &Restore_CPU_MSR,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ SmramSaveInfoHandler,
+ &CpuDriverSaveInfo,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSwDispatch->Register(
+ gSwDispatch,
+ CpuSmmFeatureEn,
+ &CpuSmmFeatureEnable,
+ &Handle
+ );
+
+ Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ /*Status = pBS->LocateProtocol (&gEfiSmmThunkProtocolGuid, NULL, &mSmmThunk);
+ if (EFI_ERROR(Status)) {
+ TRACE_IDESMM(((UINTN)TRACE_ALWAYS, "SMM Thunk Protocol not located.\n"));
+ } else {
+ TRACE_IDESMM(((UINTN)TRACE_ALWAYS, "SMM Thunk Protocol located.\n"));
+ }*/
+
+ pSmmBase->GetSmstLocation (pSmmBase, &mSmst);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NotInSmmFunction
+//
+// Description: If Not In Smm Function
+//
+// Input:
+//
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotInSmmFunction(
+ )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuSpSmiInit
+//
+// Description: Initializes CPU specific SMM Drivers.
+//
+// Input:
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Here is the control flow of this function:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CpuSpSmiInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ //EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //Status = pBS->LocateProtocol(&SwDispatchProtocolGuid,NULL,&gSwDispatch);
+ //if (EFI_ERROR(Status)) return Status;
+//InitSmmHandler
+
+ // return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NonSmmElinkFunctions);
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/CPU/CpuSpSmi.cif b/Core/CPU/CpuSpSmi.cif
new file mode 100644
index 0000000..9f0e181
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "CpuSp SMI"
+ category = ModulePart
+ LocalRoot = "Core\CPU
+ RefName = "CpuSpSMI"
+[files]
+"CpuSpSmi.sdl"
+"CpuSpSmi.mak"
+"CpuSpSmi.h"
+"CpuSpSmi.c"
+"CpuSpSmi.DXS"
+<endComponent>
diff --git a/Core/CPU/CpuSpSmi.h b/Core/CPU/CpuSpSmi.h
new file mode 100644
index 0000000..bb05202
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.h
@@ -0,0 +1,118 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.h 1 2/07/12 4:00a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 4:00a $
+//
+//*********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.h $
+//
+// 1 2/07/12 4:00a Davidhsieh
+//
+//*********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: <CpuSpSmi.h>
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the CpuSpSMI Component
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _CPUSPSMI_H_
+#define _CPUSPSMI_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <AmiDxeLib.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include <Token.h>
+
+#define NUM_OF_FIXED_MTRRS 11
+
+#define MSR_IA32_MTRR_CAP 0xFE
+ #define VCNT_MASK 0xFF
+
+#define MTRR_PHYS_BASE_0 0x200
+#define MTRR_PHYS_MASK_0 0x201
+#define MTRR_PHYS_BASE_1 0x202
+#define MTRR_PHYS_MASK_1 0x203
+#define MTRR_PHYS_BASE_2 0x204
+#define MTRR_PHYS_MASK_2 0x205
+#define MTRR_PHYS_BASE_3 0x206
+#define MTRR_PHYS_MASK_3 0x207
+#define MTRR_PHYS_BASE_4 0x208
+#define MTRR_PHYS_MASK_4 0x209
+#define MTRR_PHYS_BASE_5 0x20a
+#define MTRR_PHYS_MASK_5 0x20b
+#define MTRR_PHYS_BASE_6 0x20c
+#define MTRR_PHYS_MASK_6 0x20d
+#define MTRR_PHYS_BASE_7 0x20e
+#define MTRR_PHYS_MASK_7 0x20f
+#define MTRR_PHYS_BASE_8 0x210
+#define MTRR_PHYS_MASK_8 0x211
+#define MTRR_PHYS_BASE_9 0x212
+#define MTRR_PHYS_MASK_9 0x213
+#define MTRR_FIX_64K_00000 0x250
+#define MTRR_FIX_16K_80000 0x258
+#define MTRR_FIX_16K_A0000 0x259
+#define MTRR_FIX_4K_C0000 0x268
+#define MTRR_FIX_4K_C8000 0x269
+#define MTRR_FIX_4K_D0000 0x26a
+#define MTRR_FIX_4K_D8000 0x26b
+#define MTRR_FIX_4K_E0000 0x26c
+#define MTRR_FIX_4K_E8000 0x26d
+#define MTRR_FIX_4K_F0000 0x26e
+#define MTRR_FIX_4K_F8000 0x26f
+
+typedef struct _EFI_MSR_VALUES {
+ UINT16 Index;
+ UINT64 Value;
+} EFI_MSR_VALUES;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _IDESMM_H_
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/CPU/CpuSpSmi.mak b/Core/CPU/CpuSpSmi.mak
new file mode 100644
index 0000000..e25e332
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.mak
@@ -0,0 +1,65 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.mak 1 2/07/12 4:00a Davidhsieh $
+#
+# $Revision: 1 $
+#
+# $Date: 2/07/12 4:00a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CpuSp SMI/CpuSpSmi.mak $
+#
+# 1 2/07/12 4:00a Davidhsieh
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CpuSpSmi.mak
+#
+# Description: Make file for the CpuSpSMI component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CPUSPSMI
+
+CPUSPSMI : $(BUILD_DIR)\CpuSpSmi.mak CpuSpSmiBin
+
+$(BUILD_DIR)\CpuSpSmi.mak : $(CPUSPSMI_DIR)\$(@B).cif $(CPUSPSMI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CPUSPSMI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CpuSpSmiBin : $(AMIDXELIB)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CpuSpSmi.mak all\
+ GUID=116e1acf-2533-4cc2-820a-bbc10a2aB07c\
+ ENTRY_POINT=CpuSpSmiInit\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/CpuSpSmi.sdl b/Core/CPU/CpuSpSmi.sdl
new file mode 100644
index 0000000..be2e366
--- /dev/null
+++ b/Core/CPU/CpuSpSmi.sdl
@@ -0,0 +1,56 @@
+TOKEN
+ Name = "CPUSPSMI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IDESMM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_SAVE_MSR"
+ Value = "0x56"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_RESTORE_MSR"
+ Value = "0x57"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_ENABLE_SMM_FEATURE"
+ Value = "0x58"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_S3_RESTORE_MSR_FROM_SDL"
+ Value = "0x59"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "CPUSPSMI_DIR"
+End
+
+MODULE
+ Help = "Includes CpuSpSmi.mak to Project"
+ File = "CpuSpSmi.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CpuSpSmi.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/CPU/CpuTools.cif b/Core/CPU/CpuTools.cif
new file mode 100644
index 0000000..1cafb1b
--- /dev/null
+++ b/Core/CPU/CpuTools.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "CpuTools"
+ category = ModulePart
+ LocalRoot = "Core\Cpu"
+ RefName = "CpuTools"
+[files]
+"CpuTools.sdl"
+"SecFixup.exe"
+"CreateSecFfs.exe"
+<endComponent>
diff --git a/Core/CPU/CpuTools.sdl b/Core/CPU/CpuTools.sdl
new file mode 100644
index 0000000..b259ecf
--- /dev/null
+++ b/Core/CPU/CpuTools.sdl
@@ -0,0 +1,13 @@
+TOKEN
+ Name = CpuTools_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable CpuTools support in Project"
+End
+
+PATH
+ Name = "CPU_TOOLS_DIR"
+End
diff --git a/Core/CPU/CreateSecFfs.exe b/Core/CPU/CreateSecFfs.exe
new file mode 100644
index 0000000..345c2e5
--- /dev/null
+++ b/Core/CPU/CreateSecFfs.exe
Binary files differ
diff --git a/Core/CPU/IA32/AmiIa32Lib.cif b/Core/CPU/IA32/AmiIa32Lib.cif
new file mode 100644
index 0000000..e86bed7
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "AmiIa32Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "AmiIa32Lib"
+[files]
+"AmiIa32Lib.sdl"
+"AmiIa32Lib.mak"
+"IA32CLib.c"
+"IA32AsmLib\EnableLongMode.asm"
+"IA32AsmLib\EnableMachineCheck.asm"
+<endComponent>
diff --git a/Core/CPU/IA32/AmiIa32Lib.mak b/Core/CPU/IA32/AmiIa32Lib.mak
new file mode 100644
index 0000000..304209c
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.mak
@@ -0,0 +1,67 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/IA32Core/AmiIa32Lib.mak 1 10/13/06 8:36p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 10/13/06 8:36p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/IA32Core/AmiIa32Lib.mak $
+#
+# 1 10/13/06 8:36p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiIa32Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+AmiIa32Lib : $(BUILD_DIR)\AmiIa32Lib.mak AmiIa32LibBin
+
+$(BUILD_DIR)\AmiIa32Lib.mak : $(AmiIa32Lib_DIR)\$(@B).cif $(AmiIa32Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AmiIa32Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+AmiDxeLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+AmiPeiLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+$(BUILD_DIR)\AmiIa32Lib.lib : AmiIa32Lib
+!ELSEIF "$(PROCESSOR)"=="x64"
+AmiPeiLibBin : $(BUILD_DIR)\AmiIa32Lib.lib
+$(BUILD_DIR)\AmiIa32Lib.lib : AmiIa32Lib
+!ENDIF
+
+AmiIa32LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiIa32Lib.mak all\
+ TYPE=PEI_LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/AmiIa32Lib.sdl b/Core/CPU/IA32/AmiIa32Lib.sdl
new file mode 100644
index 0000000..8581f00
--- /dev/null
+++ b/Core/CPU/IA32/AmiIa32Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "AmiIa32Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AmiIa32Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AmiIa32Lib_DIR"
+End
+
+MODULE
+ Help = "Includes AmiIa32Lib.mak to Project"
+ File = "AmiIa32Lib.mak"
+End
+
diff --git a/Core/CPU/IA32/FoundationIa32.cif b/Core/CPU/IA32/FoundationIa32.cif
new file mode 100644
index 0000000..8f9a179
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "FoundationIa32"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "FoundationIa32"
+[files]
+"FoundationIa32.sdl"
+"FoundationIa32.mak"
+"efijump.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"Processor.c"
+"ProcessorAsms.Asm"
+"SwitchCoreStacks.asm"
+"Processor.h"
+<endComponent>
diff --git a/Core/CPU/IA32/FoundationIa32.mak b/Core/CPU/IA32/FoundationIa32.mak
new file mode 100644
index 0000000..93f45d4
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.mak
@@ -0,0 +1,69 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/IA32/FoundationIa32.mak 1 8/24/06 12:35p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:35p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/IA32/FoundationIa32.mak $
+#
+# 1 8/24/06 12:35p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FoundationIa32.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+FoundationIa32 : $(BUILD_DIR)\FoundationIa32.mak FoundationIa32Bin
+
+$(BUILD_DIR)\FoundationIa32.mak : $(FoundationIa32_DIR)\$(@B).cif $(FoundationIa32_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FoundationIa32_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+FoundationBin : $(BUILD_DIR)\FoundationIa32.lib
+FoundationPeiBin : $(BUILD_DIR)\FoundationIa32.lib
+$(BUILD_DIR)\FoundationIa32.lib : FoundationIa32
+!ELSEIF "$(PROCESSOR)"=="x64"
+FoundationPeiBin : $(BUILD_DIR)\FoundationIa32.lib
+$(BUILD_DIR)\FoundationIa32.lib : FoundationIa32
+!ENDIF
+
+
+FoundationIa32Bin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FoundationIa32.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=PEI_LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/FoundationIa32.sdl b/Core/CPU/IA32/FoundationIa32.sdl
new file mode 100644
index 0000000..67f7c70
--- /dev/null
+++ b/Core/CPU/IA32/FoundationIa32.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "FoundationIa32_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FoundationIa32 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FoundationIa32_DIR"
+End
+
+MODULE
+ Help = "Includes FoundationIa32.mak to Project"
+ File = "FoundationIa32.mak"
+End
+
diff --git a/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm b/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm
new file mode 100644
index 0000000..14af3dd
--- /dev/null
+++ b/Core/CPU/IA32/IA32AsmLib/EnableLongMode.asm
@@ -0,0 +1,143 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32AsmLib/EnableLongMode.asm 2 8/06/12 2:43p Markw $
+;
+; $Revision: 2 $
+;
+; $Date: 8/06/12 2:43p $Log:$
+;
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.686p
+.xmm
+.model flat
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableLongMode
+;
+; Description:
+; VOID EnableLongMode(IN VOID *PageTable, IN VOID *Function,
+; IN VOID *Parameter1, IN VOID *Parameter2) enables long mode then calls the
+; provided function with the provided parameters.
+;
+; Input:
+; IN VOID *PageTable
+; Pointer to level 4 page map.
+;
+; IN VOID *Function
+; Pointer to function to call.
+;
+; IN VOID *Parameter1
+; Parameter 1 for above function call.
+;
+; IN VOID *Parameter2
+; Parameter 2 for above function call.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableLongMode proc C public PageTable:DWORD, Function:DWORD, Parameter1:DWORD, Parameter2:DWORD
+ mov eax, PageTable
+ mov cr3, eax ;Set CR3 to first page directory pointer table
+
+ mov eax, cr4
+ or ax, 620h ;Enable PAE and XMM in case it was turned off.
+ mov cr4, eax
+
+ ;Enable long mode in msr register. Doesn't actually enter long mode yet.
+ mov ecx, 0c0000080h
+ rdmsr
+ bts eax, 8
+ wrmsr
+
+ ;Enable paging
+ mov eax, cr0
+ bts eax, 31
+ mov cr0, eax ;Now in long mode compatiblity.
+ jmp @f
+@@:
+
+ ;jmp far segment:offset
+ db 67h, 0eah
+ dd offset long_mode_64
+ dw 38h ;SYS_CODE64_SEL
+long_mode_64:
+ ;in 64-bit long mode
+
+ db 48h
+ xor eax, eax ;xor rax, rax
+ db 48h
+ xor ebx, ebx ;xor rbx, rbx
+ db 48h
+ xor ecx, ecx ;xor rcx, rcx
+ db 48h
+ xor edx, edx ;xor rdx, rdx
+
+ mov ecx, Parameter1
+ mov edx, Parameter2
+ mov ebx, Function
+
+ mov ax, 30h ;SYS_DATA64_SEL
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+
+ push 37fh
+ fldcw word ptr [esp] ;Uses rsp. Set FP control word according UEFI
+ db 48h
+ add esp, 8 ;add rsp, 8
+
+
+ mov eax, 0fffffff0h
+ db 48h
+ and esp, eax ;rsp must be on a 16 byte boundary. C compiler expects that.
+ call ebx ;call rbx
+ ret
+EnableLongMode endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm b/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm
new file mode 100644
index 0000000..8b3cd2a
--- /dev/null
+++ b/Core/CPU/IA32/IA32AsmLib/EnableMachineCheck.asm
@@ -0,0 +1,78 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32AsmLib/EnableMachineCheck.asm 1 10/01/10 4:56p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 4:56p $Log:$
+;
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.686p
+.xmm
+.model flat
+.code
+
+;*************************************************************************
+;
+; Name: EnableMachineCheck
+;
+; Description:
+; VOID EnableMachineCheck(VOID) sets the Machine Check Exception bit in CR4,
+; which enables machine check interrupts to occur.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;*************************************************************************
+_EnableMachineCheck proc
+ mov eax, cr4
+ or eax, 1 SHL 6
+ mov cr4, eax
+ ret
+_EnableMachineCheck endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/IA32/IA32CLib.c b/Core/CPU/IA32/IA32CLib.c
new file mode 100644
index 0000000..4cf579c
--- /dev/null
+++ b/Core/CPU/IA32/IA32CLib.c
@@ -0,0 +1,1959 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IA32Core/IA32CLib.c 14 11/11/11 3:39p Artems $
+//
+// $Revision: 14 $
+//
+// $Date: 11/11/11 3:39p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IA32Core/IA32CLib.c $
+//
+// 14 11/11/11 3:39p Artems
+// Bug fix: Verify pointer is not NULL when return value
+//
+// 13 10/18/11 11:47a Yakovlevs
+// [TAG] EIP71694
+// [Category] Bug Fix
+// [Symptom] Option ROM is corrupted when copied from device on Rosecity
+// Core 4.6.5.1.
+// [RootCause] MemCpy was updated to use 8 bytes at a time.
+// PCI ROM BAR was not able to handle this type of request.
+// [Solution] Introducesd MemCpy32 functiom.
+// [Files] AmiLib.h; AmiX64Lib.cif; IA32CLib.c
+// MemCpy32.asm - added
+//
+// 12 10/01/10 4:57p Felixp
+// Most of the functions from IA32AsmLib.asm moved here
+//
+// 11 11/25/09 1:55p Felixp
+//
+// 10 11/24/09 5:24p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support. InitLongMode function modified.
+//
+// 9 11/05/09 5:03p Oleksiyy
+// EIP 27821 Support for 64 bit operations in IoRead and IoWrite added.
+//
+// 8 7/10/09 9:26a Felixp
+// Function headers are added
+//
+// 7 4/17/08 2:30p Markw
+// Update InitLongMode to create pages above 32-bits.
+//
+// 6 3/24/08 2:18p Markw
+// Added support for pages tables above 4GB. Currently, disabled.
+//
+// 5 3/18/08 2:41p Markw
+// Update page table for first 2MB to have 4k pages. This is so cache
+// attributes will not be different in a page.
+//
+// 4 4/25/07 5:36p Felixp
+// InitLongMode and EnableLongMode routines extended so support calling of
+// the x64 routine with 2 parameters
+//
+// 3 12/28/06 6:21p Felixp
+// VC8 32-bit compiler support added
+//
+// 2 10/09/06 10:09a Felixp
+// Clean up
+//
+// 1 8/24/06 12:54p Felixp
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: IA32CLib.c
+//
+// Description:
+// Generic CPU library functions for the IA32 architecture. See function
+// definitions in the x64 library; most IA32 functions have been removed
+// from help builder output to fix a name collision issue.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <PEI.h>
+#include <AmiLib.h>
+#include <Hob.h>
+
+//*************************************************************************
+// Math
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: Shr64
+//
+// Description:
+// UINT64 Shr64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// right the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted.
+//
+// IN UINT8 Shift
+// The number of bits to shift right.
+//
+// Output:
+// UINT64 Value shifted right Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Shr64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ _asm {
+ mov edx, dword ptr Value[4]
+ mov eax, dword ptr Value
+ mov cl, Shift
+
+ cmp cl, 64
+ jb less_64
+ xor eax, eax
+ xor edx, edx
+ jmp exit
+less_64:
+ cmp cl, 32 //Shift is 32 modulo
+ jb less_32
+
+ mov eax, edx
+ xor edx, edx
+less_32:
+ shrd eax, edx, cl
+ shr edx, cl
+exit:
+ }
+}
+
+//*************************************************************************
+//
+// Name: Shl64
+//
+// Description:
+// UINT64 Shl64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// left the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted left.
+//
+// IN UINT8 Shift
+// The number of bits to shift.
+//
+// Output:
+// UINT64 Value shifted left Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Shl64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ _asm {
+ mov edx, dword ptr Value[4]
+ mov eax, dword ptr Value
+ mov cl, Shift
+
+ cmp cl, 64
+ jb less_64
+ xor eax, eax
+ xor edx, edx
+ jmp exit
+less_64:
+ cmp cl, 32 //Shift is 32 modulo
+ jb less_32
+
+ mov edx, eax
+ xor eax, eax
+less_32:
+ shld edx, eax, cl
+ shl eax, cl
+exit:
+ }
+}
+
+//*************************************************************************
+//
+// Name: Div64
+//
+// Description:
+// UINT64 Div64(IN UINT64 Dividend, IN UINTN Divisor,
+// OUT UINTN *Remainder OPTIONAL) divides a 64-bit number, Dividend, by the
+// Divisor, which can be up to 31-bits.
+//
+// Input:
+// IN UINT64 Dividend
+// The 64-bit number to be divided.
+//
+// IN UINT Divisor
+// The number to divide Dividend by; may not exceed 31-bits in size.
+//
+// OUT UINTN *Remainder OPTIONAL
+// The remainder of the division. Provide NULL if undesired; otherwise user
+// is responsible for handling the necessary memory resources.
+//
+// Output:
+// UINT64 result of dividing Dividend by Divisor.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Div64 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result;
+ UINT32 Rem;
+ _asm
+ {
+ mov eax, dword ptr Dividend[0]
+ mov edx, dword ptr Dividend[4]
+ mov esi, Divisor
+ xor edi, edi ; Remainder
+ mov ecx, 64 ; 64 bits
+Div64_loop:
+ shl eax, 1 ;Shift dividend left. This clears bit 0.
+ rcl edx, 1
+ rcl edi, 1 ;Shift remainder left. Bit 0 = previous dividend bit 63.
+
+ cmp edi, esi ; If Rem >= Divisor, don't adjust
+ cmc ; else adjust dividend and subtract divisor.
+ sbb ebx, ebx ; if Rem >= Divisor, ebx = 0, else ebx = -1.
+ sub eax, ebx ; if adjust, bit 0 of dividend = 1
+ and ebx, esi ; if adjust, ebx = Divisor, else ebx = 0.
+ sub edi, ebx ; if adjust, subtract divisor from remainder.
+ loop Div64_loop
+
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov Rem, edi
+ }
+
+ if (Remainder) *Remainder = Rem;
+
+ return Result;
+}
+//*************************************************************************
+//
+// Name: Mul64
+//
+// Description:
+// UINT64 Mul64(IN UINT64 Value64, IN UINTN Value32) multiplies a 64-bit
+// number by a 32-bit number and returns the 64-bit result.
+//
+// Input:
+// IN UINTN64 Value64
+// The 64-bit number to multiply by.
+//
+// IN UINTN Value32
+// The 32-bit number to multiply by.
+//
+// Output:
+// UINT64 result of multiplying Value64 by Value32.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 Mul64(
+ IN UINT64 Value64,
+ IN UINTN Value32
+ )
+{
+ UINT64 Result;
+
+ _asm {
+ mov eax, dword ptr Value64[0]
+ mul Value32
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov eax, dword ptr Value64[4]
+ mul Value32
+ add dword ptr Result[4], eax
+ }
+
+ return Result;
+}
+
+//*************************************************************************
+// Memory Operations
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: MemCpy
+//
+// Description:
+// VOID MemCpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+// copies Count bytes of memory from Source to Destination.
+//
+// Input:
+// OUT VOID *pDestination
+// Memory address where data shall be copied. User is responsible for
+// allocating the necessary memory resources.
+//
+// IN VOID *pSource
+// Memory address from where data shall be copied.
+//
+// IN UINTN Count
+// Number of bytes to copy from pSource.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// This function checks for overlapping of source and destination and
+// selects copy direction that prevents memory corruption.
+//
+//*************************************************************************
+VOID MemCpy(VOID* pDestination, VOID* pSource, UINTN Count)
+{
+ _asm{
+// esi, edi, ebx are saved/restores in compiler prolog/epilog code
+ pushf
+ mov esi, pSource
+ mov edi, pDestination
+ mov ecx, Count
+ mov dl, 0
+ mov eax, esi
+ sub eax, edi
+ jnb CopyForward
+ lea ebx, [esi+ecx]
+ neg eax
+ cmp ebx, edi
+ jb CopyForward
+ mov esi, ebx
+ lea edi, [edi+ecx]
+ mov dl, 1
+ std
+CopyForward:
+ cmp ecx, 4
+ jb m8
+ cmp eax, 4
+ jb m8
+ mov eax, esi
+ mov ebx, edi
+ and eax, 3
+ and ebx, 3
+ test dl, dl
+ jz skip1
+ dec esi
+ dec edi
+skip1:
+ cmp eax, ebx
+ jne m32
+ test eax, eax
+ jz m32
+ test dl, dl
+ jnz skip_nz1
+ neg eax
+ add eax, 4
+skip_nz1:
+ xchg eax, ecx
+ sub eax, ecx
+ rep movsb
+ mov ecx, eax
+m32:
+ test dl, dl
+ jz skip2
+ sub esi, 3
+ sub edi, 3
+skip2:
+ mov eax, ecx
+ shr ecx, 2
+ rep movsd
+ and eax, 3
+ jz end
+ test dl, dl
+ jz skip3
+ add esi, 4
+ add edi, 4
+skip3:
+ mov ecx, eax
+m8:
+ test dl, dl
+ jz skip4
+ dec esi
+ dec edi
+skip4:
+ rep movsb
+end:
+ popf
+// esi, edi, ebx are saved/restores in compiler prolog/epilog code
+ }
+}
+
+VOID MemCpy32(VOID* pDestination, VOID* pSource, UINTN Count){
+ MemCpy(pDestination, pSource, Count);
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: memcpy
+//
+// Description:
+// VOID memcpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count) is
+// a wrapper for MemCpy, which copies Count bytes of memory from Source to
+// Destination.
+//
+// Input:
+// OUT VOID *pDestination
+// Memory address where data shall be copied. User is responsible for
+// allocating the necessary memory resources.
+//
+// IN VOID *pSource
+// Memory address from where data shall be copied.
+//
+// IN UINTN Count
+// Number of bytes to copy from pSource.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// MemCpy
+//
+// Notes:
+// MemCpy checks for overlapping of source and destination and selects copy
+// direction that prevents memory corruption.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID memcpy(VOID* pDestination, VOID* pSource, UINTN Count)
+{
+ MemCpy(pDestination,pSource,Count);
+}
+
+//*************************************************************************
+//
+// Name: MemSet
+//
+// Description:
+// VOID MemSet(IN VOID *pBuffer, IN UINTN Count, IN UINT8 Value) fills Count
+// bytes of memory in pBuffer with Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID MemSet(VOID* pBuffer, UINTN Count, UINT8 Value)
+{
+ _asm{
+// edi, ebx are saved/restores in compiler prolog/epilog code
+ // fill EAX with the Value so that we can perform DWORD operatins
+ mov al,Value
+ mov ah, al
+ mov bx,ax
+ shl eax,16
+ mov ax,bx
+ mov edi, pBuffer
+ // if Counter is less then 4, jump to byte copy
+ mov ecx, Count
+ cmp ecx, 4
+ jb CopyByte
+ // check if the Buffer is 4-bytes aligned
+ mov edx,edi
+ and edx, 3
+ // if the Buffer is 4-bytes aligned, jump to DWORD copy
+ jz CopyDword
+ // Buffer is not 4-bytes aligned
+ // Calculate 4-(Buffer%4), which is a number of bytes we have to copy before
+ // Buffer will reach 4-bytes boundary, and perform byte copy
+ neg edx
+ add edx, 4
+ xchg ecx, edx
+ sub edx, ecx
+ rep stosb
+ mov ecx, edx
+CopyDword:
+ // perform DWORD copy
+ mov edx, ecx
+ shr ecx, 2
+ rep stosd
+ // copy the remainder
+ and edx,3
+ mov ecx, edx
+CopyByte:
+ rep stosb
+ ///
+// edi, ebx are saved/restores in compiler prolog/epilog code
+ }
+}
+
+//*************************************************************************
+//
+// Name: memset
+//
+// Description:
+// VOID memset(IN VOID *pBuffer, IN UINT8 Value, IN UINTN Count) is a
+// wrapper for MemSet which fills Count bytes of memory in pBuffer with
+// Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID memset(VOID* pBuffer, UINTN Value, UINTN Count)
+{
+ MemSet(pBuffer,Count,(UINT8)Value);
+}
+//*************************************************************************
+// Debug routines
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: checkpoint
+//
+// Description:
+// VOID checkpoint(IN UINT8 c) writes the value c to port 0x80.
+//
+// Input:
+// IN UINT8 c
+// The value/checkpoint to write to 0x80.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// This routine should only be used if the PROGRESS_CODE or
+// PEI_PROGRESS_CODE macros are unavailable.
+//
+//*************************************************************************
+VOID checkpoint(UINT8 c){
+ _asm{
+ mov al, c
+ out 0x80,al
+ }
+}
+
+//*************************************************************************
+//
+// Name: GetCpuTimer
+//
+// Description:
+// UINT64 GetCpuTimer() returns the value of the CPU timer.
+//
+// Input:
+// None.
+//
+// Output:
+// UINT64 value of the CPU timer.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 GetCpuTimer(){_asm rdtsc}
+
+//*************************************************************************
+// I/O Operations
+//*************************************************************************
+
+//*************************************************************************
+//
+// Name: IoRead8
+//
+// Description:
+// UINT8 IoRead8(IN UINT16 Port) reads the 8-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 8-bits from.
+//
+// Output:
+// UINT8 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT8 IoRead8(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in al, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite8
+//
+// Description:
+// VOID IoWrite8(IN UINT16 Port, IN UINT8 Value) writes the 8-bit Value to
+// the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 8-bits to.
+//
+// IN UINT8 Value
+// 8-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite8(UINT16 Port,UINT8 Value)
+{
+ _asm {
+ mov dx, Port
+ mov al, Value
+ out dx, al
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead16
+//
+// Description:
+// UINT16 IoRead16(IN UINT16 Port) reads the 16-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 16-bits from.
+//
+// Output:
+// UINT16 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT16 IoRead16(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in ax, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite16
+//
+// Description:
+// VOID IoWrite16(IN UINT16 Port, IN UINT16 Value) writes the 16-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 16-bits to.
+//
+// IN UINT16 Value
+// 16-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite16(UINT16 Port,UINT16 Value)
+{
+ _asm {
+ mov dx, Port
+ mov ax, Value
+ out dx, ax
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead32
+//
+// Description:
+// UINT32 IoRead32(IN UINT16 Port) reads the 32-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 32-bits from.
+//
+// Output:
+// UINT32 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT32 IoRead32(UINT16 Port)
+{
+ _asm {
+ mov dx, Port
+ in eax, dx
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoWrite32
+//
+// Description:
+// VOID IoWrite32(IN UINT16 Port, IN UINT32 Value) writes the 32-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 32-bits to.
+//
+// IN UINT32 Value
+// 32-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite32(UINT16 Port,UINT32 Value)
+{
+ _asm {
+ mov dx, Port
+ mov eax, Value
+ out dx, eax
+ }
+}
+
+//*************************************************************************
+//
+// Name: IoRead64
+//
+// Description:
+// UINT32 IoRead64(IN UINT16 Port) reads the 64-bit value stored at the I/O
+// port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to read 64-bits from.
+//
+// Output:
+// UINT64 value stored at I/O Port.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 IoRead64(UINT16 Port)
+{
+
+ UINT64 Result;
+ UINT64 *Buffer = &Result;
+
+ _asm {
+ xor edx, edx
+ mov dx, Port
+ mov esi, Buffer
+ in eax, dx
+ mov dword ptr[esi],eax
+ add esi, 4
+ add dx, 4
+ in eax, dx
+ mov dword ptr[esi],eax
+ }
+ return Result;
+}
+
+//*************************************************************************
+//
+// Name: IoWrite64
+//
+// Description:
+// VOID IoWrite64(IN UINT16 Port, IN UINT64 Value) writes the 64-bit Value
+// to the I/O port defined by Port.
+//
+// Input:
+// IN UINT16 Port
+// I/O port to write 64-bits to.
+//
+// IN UINT64 Value
+// 64-bits to write to the I/O Port.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+void IoWrite64(UINT16 Port, UINT64 Value)
+{
+// UINT32 Lo=(UINT32)Value, Hi=(UINT32)Shr64(Value,32);
+
+ VOID* Buffer=&Value;
+
+
+ _asm {
+ xor edx, edx
+ mov dx, Port
+ mov esi, Buffer
+ mov eax, dword ptr[esi]
+ out dx, eax
+ add esi, 4
+ add dx, 4
+ mov eax, dword ptr[esi]
+ out dx, eax
+ }
+
+
+
+}
+
+VOID EnableLongMode(VOID *PageTable, VOID *Function, VOID *Parameter1, VOID *Parameter2);
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: InitLongModeExt
+//
+// Description:
+// VOID InitLongMode(IN EFI_PEI_SERVICES **PeiServices, IN VOID *Function,
+// IN VOID *Parameter1, IN VOID *Parameter2) initializes memory page mapping,
+// enables long mode and jumps to a provided function.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// Double pointer to the PEI Services table.
+//
+// IN VOID *Function
+// Pointer to a function for EnableLongMode to call.
+//
+// IN VOID *Parameter1
+// First parameter to provide the Function to be called.
+//
+// IN VOID *Parameter2
+// Second parameter to provide the Function to be called.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// FindNextHobByType
+// EFI_ERROR
+// GetPageTableNumPages
+// FillPageTable
+// EnableLongMode
+//
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID InitLongModeExt(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2,
+ IN UINT8 NumMemBits
+)
+{
+ EFI_PHYSICAL_ADDRESS PageTable;
+ UINT32 NumPages;
+ EFI_STATUS Status;
+//TODO: In AllocatePages below, change EfiACPIMemoryNVS to EfiBootServicesData.
+//TODO: It is left as EfiACPIMemoryNVS until future projects can be updated to
+//TODO: a later CPU module. Future CPU modules will allocate EfiACPIMemoryNVS
+//TODO: for only 32-bits.
+
+ NumPages = GetPageTableNumPages(NumMemBits);
+
+ Status = (*PeiServices)->AllocatePages(
+ PeiServices,
+ EfiACPIMemoryNVS,
+ NumPages,
+ &PageTable
+ );
+ //ASSERT_PEI_ERROR(PeiServices,Status);
+
+ FillPageTable(NumMemBits, (VOID*)PageTable);
+
+ EnableLongMode((VOID*)PageTable, Function, Parameter1, Parameter2);
+}
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: InitLongMode
+//
+// Description:
+// VOID InitLongMode(IN EFI_PEI_SERVICES **PeiServices, IN VOID *Function,
+// IN VOID *Parameter1, IN VOID *Parameter2) initializes memory page mapping,
+// enables long mode and jumps to a provided function.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// Double pointer to the PEI Services table.
+//
+// IN VOID *Function
+// Pointer to a function for EnableLongMode to call.
+//
+// IN VOID *Parameter1
+// First parameter to provide the Function to be called.
+//
+// IN VOID *Parameter2
+// Second parameter to provide the Function to be called.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// FindNextHobByType
+// EFI_ERROR
+// GetPageTableNumPages
+// FillPageTable
+// EnableLongMode
+//
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID InitLongMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2
+)
+{
+
+
+ UINT8 NumMemBits = 32;
+ EFI_HOB_CPU *CpuHob;
+ VOID *FirstHob;
+ EFI_STATUS Status;
+
+ (*PeiServices)->GetHobList(PeiServices, &FirstHob);
+ //if (!FirstHob) ASSERT_PEI_ERROR(PeiServices, EFI_NOT_FOUND);
+
+ CpuHob = (EFI_HOB_CPU*) FirstHob;
+ Status = FindNextHobByType(EFI_HOB_TYPE_CPU, &CpuHob);
+
+ //If error during release mode, The memory cache size will be 32-bits.
+ //During debug mode, an assert will happen to alert that the CPU HOB is
+ //not produced, so that all memory will not be paged.
+ //ASSERT_PEI_ERROR(PeiServices, Status);
+
+ //Find APIC ID Hob.
+ if (!EFI_ERROR(Status)) {
+ NumMemBits = CpuHob->SizeOfMemorySpace;
+ }
+
+ InitLongModeExt (PeiServices, Function, Parameter1, Parameter2, NumMemBits);
+}
+
+//*************************************************************************
+//
+// Name: GetPowerOfTwo64
+//
+// Description:
+// UINT64 GetPowerOfTwo64(IN UINT64 Input) returns the highest bit set in
+// the provided UINT64 Input. Equivalent to 1 << log2(x).
+//
+// Input:
+// IN UINT64 Input
+// The 64-bit value to check for its highest bit.
+//
+// Output:
+// UINT64 value of the highest bit; if Input is 0, returns 0.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 GetPowerOfTwo64(
+ IN UINT64 Input
+)
+{
+ UINT64 Result = 0;
+
+ if (Input > 0xffffffff) {
+ _asm {
+ bsr eax, dword ptr Input[4]
+ bts dword ptr Result[4], eax
+ }
+ } else {
+ _asm {
+ bsr eax, dword ptr Input[0]
+ bts dword ptr Result[0], eax
+ }
+ }
+ return Result;
+}
+
+//*************************************************************************
+//
+// Name: ReadMsr
+//
+// Description:
+// UINT64 ReadMsr(IN UINT32 Msr) reads the CPU MSR index defined by Msr and
+// returns the value.
+//
+// Input:
+// IN UINT32 Msr
+// 32-bit MSR index to be read.
+//
+// Output:
+// UINT64 MSR value at MSR index, Msr.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 ReadMsr(IN UINT32 Msr){
+ _asm{
+ mov ecx, Msr ;MSR register
+ rdmsr
+ }
+}
+
+//*************************************************************************
+//
+// Name: WriteMsr
+//
+// Description:
+// VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value) writes the Value to the
+// supplied MSR index, Msr.
+//
+// Input:
+// IN UINT32 Msr
+// 32-bit MSR index to be written to.
+//
+// IN UINT64 Value
+// Value to be written to MSR index.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value){
+ _asm{
+ mov ecx, Msr ;MSR register
+ mov edx, dword ptr Value[4] ;Upper 32 bit MSR Value
+ mov eax, dword ptr Value[0] ;Lower 32 bit MSR Value
+ wrmsr
+ }
+}
+//*************************************************************************
+//
+// Name: CPULib_CpuID
+//
+// Description:
+// VOID CPULib_CpuID(IN UINT32 CpuIDIndex, IN OUT UINT32 *pRegEAX,
+// IN OUT UINT32 *pRegEBX, IN OUT UINT32 *pRegECX, IN OUT UINT32 *pRegEDX)
+// issues the CPUID instruction with the index provided and returns the
+// register values.
+//
+// Input:
+// IN UINT32 CpuIDIndex
+// 32-bit CPUID index.
+//
+// IN OUT UINT32 *pRegEAX
+// Pointer to UINT32 for EAX return value.
+//
+// IN OUT UINT32 *pRegEBX
+// Pointer to UINT32 for EBX return value.
+//
+// IN OUT UINT32 *pRegECX
+// Pointer to UINT32 for ECX return value.
+//
+// IN OUT UINT32 *pRegEDX
+// Pointer to UINT32 for EDX return value.
+//
+// Output:
+// IN OUT UINT32 *pRegEAX
+// Value of EAX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegEBX
+// Value of EBX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegECX
+// Value of ECX after CPUID instruction.
+//
+// IN OUT UINT32 *pRegEDX
+// Value of EDX after CPUID instruction.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_CpuID(
+ IN UINT32 CpuIDIndex,
+ IN OUT UINT32 *pRegEAX,
+ IN OUT UINT32 *pRegEBX,
+ IN OUT UINT32 *pRegECX,
+ IN OUT UINT32 *pRegEDX)
+{
+ _asm{
+ push ebx
+ push ecx
+ push edx
+ push esi
+ mov esi, pRegECX
+ mov ecx, [esi]
+ mov eax, CpuIDIndex
+ cpuid
+ mov esi, pRegEAX
+ or esi, esi
+ jz skip1
+ mov [esi], eax
+skip1:
+ mov esi, pRegEBX
+ or esi, esi
+ jz skip2
+ mov [esi], ebx
+skip2:
+ mov esi, pRegECX
+ or esi, esi
+ jz skip3
+ mov [esi], ecx
+skip3:
+ mov esi, pRegEDX
+ or esi, esi
+ jz skip4
+ mov [esi], edx
+skip4:
+ pop esi
+ pop edx
+ pop ecx
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: DisableCacheInCR0
+//
+// Description:
+// VOID DisableCacheInCR0(VOID) disables the CPU cache using the CR0 register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID DisableCacheInCR0(VOID){
+ _asm{
+ wbinvd
+ mov eax, cr0
+ or eax, 060000000h ;SET CD, NW
+ mov cr0, eax
+ wbinvd ;Invalidate cache
+ }
+}
+
+//*************************************************************************
+//
+// Name: EnableCacheInCR0
+//
+// Description:
+// VOID EnableCacheInCR0(VOID) enables the CPU cache using the CR0 register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID EnableCacheInCR0(VOID){
+ _asm{
+ // Enable cache
+ mov eax, cr0
+ and eax, 09fffffffh ;SET CD, NW
+ mov cr0, eax
+ wbinvd
+ }
+}
+//*************************************************************************
+//
+// Name: ReadCr3
+//
+// Description:
+// UINTN ReadCr3(VOID) reads the register CR3 and returns its value.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINTN value stored in the CR3 register.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINTN ReadCr3(VOID){
+ _asm{
+ mov eax, cr3
+ }
+}
+//*************************************************************************
+//
+// Name: WriteCr3
+//
+// Description:
+// VOID WriteCr3(IN UINTN CR3) writes the provided value to the CR3 register.
+//
+// Input:
+// IN UINTN CR3
+// Value to be written to the CR3 register.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WriteCr3(IN UINTN CR3){
+ _asm{
+ mov eax, CR3
+ mov cr3, eax
+ }
+}
+//*************************************************************************
+//
+// Name: CPULib_EnableInterrupt
+//
+// Description:
+// VOID CPULib_EnableInterrupt(VOID) enables interrupts on the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_EnableInterrupt(VOID){
+ _asm{
+ // Enable Interrupt
+ sti
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_DisableInterrupt
+//
+// Description:
+// VOID CPULib_DisableInterrupt() disables interrupts on the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_DisableInterrupt(){
+ _asm{
+ // Disable Interrupt
+ cli
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_GetInterruptState
+//
+// Description:
+// BOOLEAN CPULib_GetInterruptState(VOID)returns the current CPU interrupt
+// state.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns FALSE if interrupts are disabled; otherwise TRUE.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+BOOLEAN CPULib_GetInterruptState(VOID){
+ _asm{
+ xor bl, bl
+ pushfd ; push flags onto stack.
+ pop eax ; eax = flags.
+ bt eax,9 ; IF (bit 9) if set, set carry flag.
+ ; Interrupts are allowed if IF is set.
+ adc bl, 0 ; BL = IF = CF.
+
+ mov al, bl ; Return value
+ }
+}
+
+//*************************************************************************
+//
+// Name: GetCsSegment
+//
+// Description:
+// UINT16 GetCsSegment(VOID) retreives the value of the CS register.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINT16 value of CS.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT16 GetCsSegment(VOID){
+ _asm{
+ mov ax, cs
+ }
+}
+
+//*************************************************************************
+//
+// Name: ReadRtdsc
+//
+// Description:
+// UINT64 ReadRtdsc(VOID) retrieves the time stamp counter.
+//
+// Input:
+// VOID.
+//
+// Output:
+// Returns UINT64 value of the time stamp counter.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT64 ReadRtdsc(VOID){
+ _asm{
+ rdtsc
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitForever
+//
+// Description:
+// VOID WaitForever(VOID) performs an infinite loop which does nothing.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitForever(VOID){
+ _asm{
+ bbb:
+ jmp bbb
+ }
+}
+
+//*************************************************************************
+//
+// Name: HltCpu
+//
+// Description:
+// VOID HltCpu(VOID) halts the CPU.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID HltCpu(VOID){
+ _asm{
+ bbb:
+ cli
+ hlt
+ jmp bbb
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_Pause
+//
+// Description:
+// VOID CPULib_Pause(VOID) performs the pause assembly instruction.
+//
+// Input:
+// VOID.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_Pause(VOID){
+ _asm{
+ pause
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitForSemaphore
+//
+// Description:
+// VOID WaitForSemaphore(IN volatile UINT8 *Semaphore) waits for the
+// semaphore to become available; once available, it claims the semaphore and
+// returns.
+//
+// Input:
+// IN volatile UINT8 *Semaphore
+// Pointer to the desired semaphore.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitForSemaphore(IN volatile UINT8 *Semaphore){
+ _asm{
+ push ebx
+ mov al, 1
+ mov ebx, Semaphore
+ bbb:
+ xchg al, [ebx]
+ or al, al
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitUntilZero8
+//
+// Description:
+// VOID WaitUntilZero8(IN volatile UINT8 *Value) waits until the byte stored
+// at Value becomes 0, then continues.
+//
+// Input:
+// IN volatile UINT8 *Value
+// Address of the byte value to be monitored.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitUntilZero8(IN volatile UINT8 *Value){
+ _asm{
+ push ebx
+ mov ebx, Value
+ bbb:
+ mov al, [ebx]
+ or al, al
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: WaitUntilZero32
+//
+// Description:
+// VOID WaitUntilZero32(IN volatile UINT32 *Value) waits until the UINT32
+// value stored at the Value address becomes 0, then continues.
+//
+// Input:
+// IN volatile UINT32 *Value
+// Address of the UINT32 value to be monitored.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID WaitUntilZero32(IN volatile UINT32 *Value) {
+ _asm{
+ push ebx
+ mov ebx, Value
+ bbb:
+ mov eax, [ebx]
+ or eax, eax
+ pause
+ jnz bbb
+ pop ebx
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LockByteInc
+//
+// Description:
+// VOID CPULib_LockByteInc(IN UINT8 *ptr) locks the next byte after the
+// address pointed to by ptr.
+//
+// Input:
+// IN UINT8 *ptr// Address to the byte which preceeds the desired byte to be locked.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LockByteInc(IN UINT8 *xptr){
+ _asm{
+ mov eax, xptr
+ lock inc byte ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LockByteDec
+//
+// Description:
+// VOID CPULib_LockByteDec(IN UINT8 *ptr) locks the preceeding byte before
+// the address pointed to by ptr.
+//
+// Input:
+// IN UINT8 *ptr
+// Address to the byte which follows the desired byte to be locked.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LockByteDec(IN UINT8 *xptr) {
+ _asm{
+ mov eax, xptr
+ lock dec byte ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LoadGdt
+//
+// Description:
+// VOID CPULib_LoadGdt(IN VOID *ptr) loads the GDT at the location pointed to
+// by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address of the GDT to be loaded.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LoadGdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ lgdt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_SaveGdt
+//
+// Description:
+// VOID CPULib_SaveGdt(IN VOID *ptr) stores the loaded GDT at the location
+// provided by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address to save the GDT. User is responsible for allocating the necessary
+// memory resources.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_SaveGdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ sgdt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_LoadIdt
+//
+// Description:
+// VOID CPULib_LoadIdt(IN VOID *ptr) loads the IDT at the location provided
+// by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address of the IDT to be loaded.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_LoadIdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ lidt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: CPULib_SaveIdt
+//
+// Description:
+// VOID CPULib_SaveIdt(IN VOID *ptr) stores the loaded IDT at the location
+// provided by ptr.
+//
+// Input:
+// IN VOID *ptr
+// Address to save the IDT. User is responsible for allocating the necessary
+// memory resources.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID CPULib_SaveIdt(IN VOID *xptr) {
+ _asm{
+ mov eax, xptr
+ sidt fword ptr [eax]
+ }
+}
+
+//*************************************************************************
+//
+// Name: MemRead32
+//
+// Description:
+// UINT32 MemRead32(IN UINT32 *Address) reads and returns the 32-bit value
+// stored at the user provided address.
+//
+// Input:
+// IN UINT32 *Address
+// Address to read 32-bits from.
+//
+// Output:
+// UINT32 value stored at Address.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+UINT32 MemRead32(IN UINT32 *Address) {
+ _asm{
+ push esi
+ mov esi, Address ;esi = address
+ mov eax, [esi]
+ pop esi
+ }
+}
+
+//*************************************************************************
+//
+// Name: MemReadWrite32
+//
+// Description:
+// VOID MemReadWrite32(IN UINT32 *Address, IN UINT32 Value, IN UINT32 Mask)
+// reads the 32-bit value stored at Address, ANDs it with Mask, ORs the result
+// with Value, then writes the result back to Address.
+//
+// Input:
+// IN UINT32 *Address
+// Address which shall be read from and subsequently written to.
+//
+// IN UINT32 Value
+// Value to be ORed with the value stored at Address after it has been ANDed
+// with the provided Mask.
+//
+// IN UINT32 Mask
+// Mask to be ANDed with the original value stored at Address.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//*************************************************************************
+VOID MemReadWrite32(
+ IN UINT32 *Address,
+ IN UINT32 Value,
+ IN UINT32 Mask)
+{
+ _asm{
+ push esi
+ mov esi, Address ;esi = address
+ mov eax, [esi]
+ and eax, Mask ;Mask
+ or eax, Value ;Value
+ mov [esi], eax
+ pop esi
+ }
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/IA32/IA32Core.cif b/Core/CPU/IA32/IA32Core.cif
new file mode 100644
index 0000000..352c150
--- /dev/null
+++ b/Core/CPU/IA32/IA32Core.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "IA32 Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IA32\"
+ RefName = "IA32Core"
+[files]
+"IA32Core.sdl"
+"IA32rules.mak"
+<endComponent>
diff --git a/Core/CPU/IA32/IA32Core.sdl b/Core/CPU/IA32/IA32Core.sdl
new file mode 100644
index 0000000..98f179a
--- /dev/null
+++ b/Core/CPU/IA32/IA32Core.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "IA32Core_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IA32 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "AFLAGSIA32"
+ Value = "/coff"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "IA32Core_DIR"
+End
+
+ELINK
+ Name = "IA32"
+ Parent = "PROCESSOR"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IA32Core_DIR)\IA32rules.mak"
+ Parent = "PROCESSOR_RULES"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CPU/IA32/IA32rules.mak b/Core/CPU/IA32/IA32rules.mak
new file mode 100644
index 0000000..8f58110
--- /dev/null
+++ b/Core/CPU/IA32/IA32rules.mak
@@ -0,0 +1,62 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/IA32Core/IA32rules.mak 2 12/28/06 6:22p Felixp $
+#
+# $Revision: 2 $
+#
+# $Date: 12/28/06 6:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/IA32Core/IA32rules.mak $
+#
+# 2 12/28/06 6:22p Felixp
+# VC8 32-bit compiler support added
+#
+# 1 10/13/06 8:30p Felixp
+#
+# 1 8/24/06 12:54p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IA32rules.mak
+#
+# Description: Defines IA32-specific build rules.
+# This file is included into the template makefile rules.mak
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF "$(TOOLS)"=="vc8"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /GS-
+!ENDIF
+
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) $(CFLAGSIA32)
+EXTRA_LFLAGS=$(EXTRA_LFLAGS) $(LFLAGSIA32)
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) $(AFLAGSIA32)
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IA32/PeCoffLoaderEx.c b/Core/CPU/IA32/PeCoffLoaderEx.c
new file mode 100644
index 0000000..3e08c1c
--- /dev/null
+++ b/Core/CPU/IA32/PeCoffLoaderEx.c
@@ -0,0 +1,93 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ IA-32 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImage.h"
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) ||
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
diff --git a/Core/CPU/IA32/PeCoffLoaderEx.h b/Core/CPU/IA32/PeCoffLoaderEx.h
new file mode 100644
index 0000000..a83282d
--- /dev/null
+++ b/Core/CPU/IA32/PeCoffLoaderEx.h
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ IA-32 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an IA-32 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IA32/Processor.c b/Core/CPU/IA32/Processor.c
new file mode 100644
index 0000000..fcdd4bf
--- /dev/null
+++ b/Core/CPU/IA32/Processor.c
@@ -0,0 +1,140 @@
+/*++
+
+Copyright (c) 2004 - 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+TransferControlSetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+TransferControlLongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+//
+// Table declarations
+//
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ TransferControlSetJump,
+ TransferControlLongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ FlushInstructionCacheFlush
+};
+
+
+EFI_STATUS
+InstallEfiPeiTransferControl (
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+ In the case of IA32, this flushing is not necessary and is thus not implemented.
+
+Arguments:
+
+ This - Pointer to CPU Architectural Protocol interface
+ Start - Start adddress in memory to flush
+ Length - Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+}
diff --git a/Core/CPU/IA32/Processor.h b/Core/CPU/IA32/Processor.h
new file mode 100644
index 0000000..0084d4a
--- /dev/null
+++ b/Core/CPU/IA32/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Processor.h
+
+Abstract:
+ This file contains the IA-32 processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE)
+
+#endif \ No newline at end of file
diff --git a/Core/CPU/IA32/ProcessorAsms.Asm b/Core/CPU/IA32/ProcessorAsms.Asm
new file mode 100644
index 0000000..86f4606
--- /dev/null
+++ b/Core/CPU/IA32/ProcessorAsms.Asm
@@ -0,0 +1,223 @@
+;
+; Copyright (c) 2004, Intel Corporation
+; All rights reserved. This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+;
+; ProcessorAsms.Asm
+;
+; Abstract:
+; This is separated from processor.c to allow this functions to be built with /O1
+;
+; Notes:
+; - Masm uses "This", "ebx", etc as a directive.
+; - H2INC is still not embedded in our build process so I translated the struc manually.
+; - Unreferenced variables/arguments (This, NewBsp, NewStack) were causing compile errors and
+; did not know of "pragma" mechanism in MASM and I did not want to reduce the warning level.
+; Instead, I did a dummy referenced.
+;
+
+ .686P
+ .MMX
+ .MODEL SMALL
+ .CODE
+
+EFI_SUCCESS equ 0
+EFI_WARN_RETURN_FROM_LONG_JUMP equ 5
+
+;
+; Generated by h2inc run manually
+;
+_EFI_JUMP_BUFFER STRUCT 2t
+_ebx DWORD ?
+_esi DWORD ?
+_edi DWORD ?
+_ebp DWORD ?
+_esp DWORD ?
+_eip DWORD ?
+_EFI_JUMP_BUFFER ENDS
+
+EFI_JUMP_BUFFER TYPEDEF _EFI_JUMP_BUFFER
+
+TransferControlSetJump PROTO C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+TransferControlLongJump PROTO C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+SwitchStacks PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+SwitchIplStacks PROTO C \
+ EntryPoint:PTR DWORD, \
+ Parameter1:DWORD, \
+ Parameter2:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+;
+;Routine Description:
+;
+; This routine implements the IA32 variant of the SetJump call. Its
+; responsibility is to store system state information for a possible
+; subsequent LongJump.
+;
+;Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+;Returns:
+;
+; EFI_SUCCESS
+;
+TransferControlSetJump PROC C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+ mov eax, _This
+ mov ecx, Jump
+ mov (EFI_JUMP_BUFFER PTR [ecx])._ebx, ebx
+ mov (EFI_JUMP_BUFFER PTR [ecx])._esi, esi
+ mov (EFI_JUMP_BUFFER PTR [ecx])._edi, edi
+ mov eax, [ebp]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._ebp, eax
+ lea eax, [ebp+4]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._esp, eax
+ mov eax, [ebp+4]
+ mov (EFI_JUMP_BUFFER PTR [ecx])._eip, eax
+ mov eax, EFI_SUCCESS
+
+ ret
+
+TransferControlSetJump ENDP
+
+;
+; Routine Description:
+;
+; This routine implements the IA32 variant of the LongJump call. Its
+; responsibility is restore the system state to the Context Buffer and
+; pass control back.
+;
+; Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+; Returns:
+;
+; EFI_WARN_RETURN_FROM_LONG_JUMP
+;
+
+TransferControlLongJump PROC C \
+ _This:PTR EFI_PEI_TRANSFER_CONTROL_PROTOCOL, \
+ Jump:PTR EFI_JUMP_BUFFER
+
+ push ebx
+ push esi
+ push edi
+
+ mov eax, _This
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov eax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov ecx, Jump
+ mov ebx, (EFI_JUMP_BUFFER PTR [ecx])._ebx
+ mov esi, (EFI_JUMP_BUFFER PTR [ecx])._esi
+ mov edi, (EFI_JUMP_BUFFER PTR [ecx])._edi
+ mov ebp, (EFI_JUMP_BUFFER PTR [ecx])._ebp
+ mov esp, (EFI_JUMP_BUFFER PTR [ecx])._esp
+ add esp, 4 ;pop the eip
+ jmp DWORD PTR (EFI_JUMP_BUFFER PTR [ecx])._eip
+ mov eax, EFI_WARN_RETURN_FROM_LONG_JUMP
+
+ pop edi
+ pop esi
+ pop ebx
+ ret
+
+TransferControlLongJump ENDP
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter - Parameter to pass in
+; NewStack - New Location of the stack
+; NewBsp - New BSP
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchStacks PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+ push ebx
+ mov eax, NewBsp
+ mov ebx, Parameter
+ mov ecx, EntryPoint
+ mov eax, NewStack
+ mov esp, eax
+ push ebx
+ push 0
+ jmp ecx
+
+ pop ebx
+ ret
+
+SwitchStacks ENDP
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter
+; Parameter1/Parameter2 - Parameter to pass in
+; NewStack - New Location of the stack
+; NewBsp - New BSP
+;
+; Returns:
+;
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchIplStacks PROC C \
+ EntryPoint:PTR DWORD, \
+ Parameter1:DWORD, \
+ Parameter2:DWORD, \
+ NewStack:PTR DWORD, \
+ NewBsp:PTR DWORD
+
+ push ebx
+ mov eax, NewBsp
+ mov ebx, Parameter1
+ mov edx, Parameter2
+ mov ecx, EntryPoint
+ mov eax, NewStack
+ mov esp, eax
+
+ push edx
+ push ebx
+ call ecx
+
+ pop ebx
+ ret
+
+SwitchIplStacks ENDP
+
+ END
+
diff --git a/Core/CPU/IA32/SwitchCoreStacks.asm b/Core/CPU/IA32/SwitchCoreStacks.asm
new file mode 100644
index 0000000..dbb664d
--- /dev/null
+++ b/Core/CPU/IA32/SwitchCoreStacks.asm
@@ -0,0 +1,104 @@
+ TITLE SwitchCoreStacks.asm: Core stack switching routine
+
+;------------------------------------------------------------------------------
+;Copyright (c) 2004, Intel Corporation
+;All rights reserved. This program and the accompanying materials
+;are licensed and made available under the terms and conditions of the BSD License
+;which accompanies this distribution. The full text of the license may be found at
+;http://opensource.org/licenses/bsd-license.php
+;
+;THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+;Module Name:
+;
+; SwitchCoreStacks.asm
+;
+;Abstract:
+;
+; Core stack switching routine, invoked when real system memory is
+; discovered and installed.
+;
+;------------------------------------------------------------------------------
+
+ .686P
+ .XMM
+ .MODEL SMALL
+ .CODE
+
+
+include token.equ
+
+AsmWriteMm7 PROTO C
+
+AsmWriteMm7 PROC C
+;------------------------------------------------------------------------------
+; VOID
+; EFIAPI
+; AsmWriteMm7 (
+; IN UINT64 Value
+; );
+;------------------------------------------------------------------------------
+ movq mm7, [esp + 4]
+ ret
+AsmWriteMm7 ENDP
+
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+SwitchCoreStacks PROTO C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, Parameter3: DWORD, NewStack: DWORD
+
+SwitchCoreStacks PROC C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, Parameter3: DWORD, NewStack: DWORD
+ELSE
+SwitchCoreStacks PROTO C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, NewStack: DWORD
+
+SwitchCoreStacks PROC C EntryPoint: DWORD, Parameter1: DWORD, Parameter2: DWORD, NewStack: DWORD
+ENDIF
+
+;------------------------------------------------------------------------------
+; VOID
+; SwitchCoreStacks (
+; IN VOID *EntryPoint,
+; IN UINTN Parameter1,
+; IN UINTN Parameter2,
+; IN UINTN Parameter3,
+; IN VOID *NewStack
+; )
+;
+; Routine Description:
+;
+; Routine for PEI switching stacks.
+;
+; Arguments:
+;
+; EntryPoint - Entry point with new stack.
+; Parameter1 - First parameter for entry point.
+; Parameter2 - Second parameter for entry point.
+; Parameter3 - Third parameter for entry point.
+; NewStack - Pointer to new stack.
+;
+; Returns:
+;
+; None
+;
+;----------------------------------------------------
+
+ mov ebx, Parameter1
+ mov edx, Parameter2
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ mov eax, Parameter3
+ENDIF
+ mov ecx, EntryPoint
+ mov esp, NewStack
+
+ ; First push Parameter3, and then Parameter2 ,at last Parameter1.
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ push eax
+ENDIF
+ push edx
+ push ebx
+ call ecx
+
+ ret
+
+SwitchCoreStacks ENDP
+
+END
diff --git a/Core/CPU/IA32/efijump.h b/Core/CPU/IA32/efijump.h
new file mode 100644
index 0000000..d676f88
--- /dev/null
+++ b/Core/CPU/IA32/efijump.h
@@ -0,0 +1,34 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an IA32 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+typedef struct {
+ UINT32 ebx;
+ UINT32 esi;
+ UINT32 edi;
+ UINT32 ebp;
+ UINT32 esp;
+ UINT32 eip;
+} EFI_JUMP_BUFFER;
+
+#endif
diff --git a/Core/CPU/IPF/FoundationIPF.cif b/Core/CPU/IPF/FoundationIPF.cif
new file mode 100644
index 0000000..c6f8c63
--- /dev/null
+++ b/Core/CPU/IPF/FoundationIPF.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "FoundationIPF"
+ category = ModulePart
+ LocalRoot = "Core\CPU\IPF\"
+ RefName = "FoundationIPF"
+[files]
+"FoundationIPF.sdl"
+"FoundationIPF.mak"
+"SwitchStack.s"
+"asm.h"
+"efijump.h"
+"ia_64gen.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"PerformancePrimitives.s"
+"pioflush.s"
+"processor.c"
+"setjmp.s"
+"Processor.h"
+"SwitchToCacheMode.c"
+"IpfCpuCore.s"
+"IpfCpuCore.i"
+
+<endComponent>
diff --git a/Core/CPU/IPF/FoundationIPF.mak b/Core/CPU/IPF/FoundationIPF.mak
new file mode 100644
index 0000000..ad13ce2
--- /dev/null
+++ b/Core/CPU/IPF/FoundationIPF.mak
@@ -0,0 +1,66 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/IPF/FoundationIPF.mak 1 8/24/06 12:37p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:37p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/IPF/FoundationIPF.mak $
+#
+# 1 8/24/06 12:37p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FoundationIPF.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+FoundationIPF : $(BUILD_DIR)\FoundationIPF.mak FoundationIPFBin
+
+$(BUILD_DIR)\FoundationIPF.mak : $(FoundationIPF_DIR)\$(@B).cif $(FoundationIPF_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FoundationIPF_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="IPF"
+FoundationBin : $(BUILD_DIR)\FoundationIPF.lib
+FoundationPeiBin : $(BUILD_DIR)\FoundationIPF.lib
+$(BUILD_DIR)\FoundationIPF.lib : FoundationIPF
+!ENDIF
+
+
+FoundationIPFBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FoundationIPF.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/IPF/FoundationIPF.sdl b/Core/CPU/IPF/FoundationIPF.sdl
new file mode 100644
index 0000000..32db6cc
--- /dev/null
+++ b/Core/CPU/IPF/FoundationIPF.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "FoundationIPF_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FoundationIPF support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FoundationIPF_DIR"
+End
+
+MODULE
+ Help = "Includes FoundationIPF.mak to Project"
+ File = "FoundationIPF.mak"
+End
+
diff --git a/Core/CPU/IPF/IpfCpuCore.i b/Core/CPU/IPF/IpfCpuCore.i
new file mode 100644
index 0000000..d0c6fa2
--- /dev/null
+++ b/Core/CPU/IPF/IpfCpuCore.i
@@ -0,0 +1,93 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// IpfCpuCore.i
+//
+// Abstract:
+// IPF CPU definitions
+//
+//--
+
+#ifndef _IPF_CPU_CORE_
+#define _IPF_CPU_CORE_
+
+#define PEI_BSP_STORE_SIZE 0x4000
+#define ResetFn 0x00
+#define MachineCheckFn 0x01
+#define InitFn 0x02
+#define RecoveryFn 0x03
+#define GuardBand 0x10
+
+//
+// Define hardware RSE Configuration Register
+//
+
+//
+// RS Configuration (RSC) bit field positions
+//
+#define RSC_MODE 0
+#define RSC_PL 2
+#define RSC_BE 4
+//
+// RSC bits 5-15 reserved
+//
+#define RSC_MBZ0 5
+#define RSC_MBZ0_V 0x3ff
+#define RSC_LOADRS 16
+#define RSC_LOADRS_LEN 14
+//
+// RSC bits 30-63 reserved
+//
+#define RSC_MBZ1 30
+#define RSC_MBZ1_V 0x3ffffffffULL
+
+//
+// RSC modes
+//
+
+//
+// Lazy
+//
+#define RSC_MODE_LY (0x0)
+//
+// Store intensive
+//
+#define RSC_MODE_SI (0x1)
+//
+// Load intensive
+//
+#define RSC_MODE_LI (0x2)
+//
+// Eager
+//
+#define RSC_MODE_EA (0x3)
+
+//
+// RSC Endian bit values
+//
+#define RSC_BE_LITTLE 0
+#define RSC_BE_BIG 1
+
+//
+// RSC while in kernel: enabled, little endian, pl = 0, eager mode
+//
+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+//
+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode
+//
+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+//
+// RSE disabled: disabled, pl = 0, little endian, eager mode
+//
+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+
+#endif
diff --git a/Core/CPU/IPF/IpfCpuCore.s b/Core/CPU/IPF/IpfCpuCore.s
new file mode 100644
index 0000000..d3b7c62
--- /dev/null
+++ b/Core/CPU/IPF/IpfCpuCore.s
@@ -0,0 +1,196 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// IpfCpuCore.s
+//
+// Abstract:
+// IPF Specific assembly routines
+//
+//--
+
+.file "IpfCpuCore.s"
+
+#include "IpfMacro.i"
+#include "IpfCpuCore.i"
+
+//----------------------------------------------------------------------------------
+// This module supports terminating CAR (Cache As RAM) stage. It copies all the
+// CAR data into real RAM and then makes a stack switch.
+
+// EFI_STATUS
+// SwitchCoreStacks (
+// IN VOID *EntryPoint,
+// IN UINTN CopySize,
+// IN VOID *OldBase,
+// IN VOID *NewBase
+// IN UINTN NewSP, OPTIONAL
+// IN UINTN NewBSP OPTIONAL
+// )
+// EFI_STATUS
+// SwitchCoreStacks (
+// IN VOID *EntryPointForContinuationFunction,
+// IN UINTN StartupDescriptor,
+// IN VOID PEICorePointer,
+// IN UINTN NewSP
+// )
+//----------------------------------------------------------------------------------
+PROCEDURE_ENTRY (SwitchCoreStacks)
+
+ NESTED_SETUP (4,2,0,0)
+
+ // first save all stack registers in GPRs.
+ mov r13 = in0;; // this is a pointer to the PLABEL of the continuation function.
+ ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL
+ ld8 gp = [r13];; // gp = gp of continuation function from the PLABEL
+ mov b1 = r16;;
+
+ // save the parameters in r5, r6. these 2 seemed to be preserved across PAL calls
+ mov r5 = in1;; // this is the parameter1 to pass to the continuation function
+ mov r6 = in2;; // this is the parameter2 to pass to the continuation function
+ dep r6=0,r6,63,1;; // zero the bit 63.
+
+ mov r8 = in3;; // new stack pointer.
+
+ // r8 has the sp, this is 128K stack size, from this we will reserve 16K for the bspstore
+ movl r15 = PEI_BSP_STORE_SIZE;;
+ sub r8 = r8, r15;;
+ add r15 = (GuardBand),r8;; // some little buffer, now r15 will be our bspstore
+
+ // save the bspstore value to r4, save sp value to r7
+ mov r4 = r15
+ mov r7 = r8
+ mov r16 = r8;; // will be the new sp in uncache mode
+
+
+ alloc r11=0,0,0,0;; // Set 0-size frame
+ flushrs;;
+
+ mov r21 = RSC_KERNEL_DISABLED;; // for rse disable
+ mov ar.rsc = r21;; // turn off RSE
+
+ add sp = r0, r16 // transfer to the EFI stack
+ mov ar.bspstore = r15 // switch to EFI BSP
+ invala // change of ar.bspstore needs invala.
+
+ mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode
+ mov ar.rsc = r19;; // turn rse on, in kernel mode
+
+//-----------------------------------------------------------------------------------
+// Save here the meaningful stuff for next few lines and then make the PAL call.
+// Make PAL call to terminate the CAR status.
+ // AVL: do this only for recovery check call...
+
+ mov r28=ar.k3;;
+ dep r2 = r28,r0,0,8;; // Extract Function bits from GR20.
+ cmp.eq p6,p7 = RecoveryFn,r2;; // Is it Recovery check
+ (p7) br.sptk.few DoneCARTermination; // if not, don't terminate car..
+
+TerminateCAR::
+
+ mov r28 = ip;;
+ add r28 = (DoneCARTerminationPALCall - TerminateCAR),r28;;
+ mov b0 = r28
+
+ mov r8 = ar.k5;;
+ mov b6 = r8
+ mov r28 = 0x208
+
+ mov r29 = r0
+ mov r30 = r0
+ mov r31 = r0
+ mov r8 = r0;;
+ br.sptk.few b6;; // Call PAL-A call.
+
+DoneCARTerminationPALCall::
+
+// don't check error in soft sdv, it is always returning -1 for this call for some reason
+#if SOFT_SDV
+#else
+ReturnToPEIMain::
+ cmp.eq p6,p7 = r8,r0;;
+ //
+ // dead loop if the PAL call failed, we have the CAR on but the stack is now pointing to memory
+ //
+ (p7) br.sptk.few ReturnToPEIMain;;
+ //
+ // PAL call successed,now the stack are in memory so come into cache mode
+ // instead of uncache mode
+ //
+
+ alloc r11=0,0,0,0;; // Set 0-size frame
+ flushrs;;
+
+ mov r21 = RSC_KERNEL_DISABLED;; // for rse disable
+ mov ar.rsc = r21;; // turn off RSE
+
+ dep r6 = 0,r6,63,1 // zero the bit 63
+ dep r7 = 0,r7,63,1 // zero the bit 63
+ dep r4 = 0,r4,63,1;; // zero the bit 63
+ add sp = r0, r7 // transfer to the EFI stack in cache mode
+ mov ar.bspstore = r4 // switch to EFI BSP
+ invala // change of ar.bspstore needs invala.
+
+ mov r19 = RSC_KERNEL_LAZ;; // RSC enabled, Lazy mode
+ mov ar.rsc = r19;; // turn rse on, in kernel mode
+
+#endif
+
+DoneCARTermination::
+
+ // allocate a stack frame:
+ alloc r11=0,2,2,0 ;; // alloc outs going to ensuing DXE IPL service
+ // on the new stack
+ mov out0 = r5;;
+ mov out1 = r6;;
+
+ mov r16 = b1;;
+ mov b6 = r16;;
+ br.call.sptk.few b0=b6;; // Call the continuation function
+
+ NESTED_RETURN
+
+PROCEDURE_EXIT(SwitchCoreStacks)
+//-----------------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------------
+//++
+// GetHandOffStatus
+//
+// This routine is called by all processors simultaneously, to get some hand-off
+// status that has been captured by IPF dispatcher and recorded in kernel registers.
+//
+// Arguments :
+//
+// On Entry : None.
+//
+// Return Value: Lid, R20Status.
+//
+//--
+//----------------------------------------------------------------------------------
+PROCEDURE_ENTRY (GetHandOffStatus)
+
+ NESTED_SETUP (0,2+0,0,0)
+
+ mov r8 = ar.k6 // Health Status (Self test params)
+ mov r9 = ar.k4 // LID bits
+ mov r10 = ar.k3;; // SAL_E entry state
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ mov r11 = ar.k7 // Return address to PAL
+ #else
+ mov r11 = ar.k1 // Return address to PAL
+ #endif
+
+ NESTED_RETURN
+PROCEDURE_EXIT (GetHandOffStatus)
+//----------------------------------------------------------------------------------
+
+
diff --git a/Core/CPU/IPF/PeCoffLoaderEx.c b/Core/CPU/IPF/PeCoffLoaderEx.c
new file mode 100644
index 0000000..60018ed
--- /dev/null
+++ b/Core/CPU/IPF/PeCoffLoaderEx.c
@@ -0,0 +1,268 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ Fixes Intel Itanium(TM) specific relocation types
+
+
+Revision History
+
+--*/
+
+#include "TianoCommon.h"
+#include "EfiImage.h"
+
+#define EXT_IMM64(Value, Address, Size, InstPos, ValPos) \
+ Value |= (((UINT64)((*(Address) >> InstPos) & (((UINT64)1 << Size) - 1))) << ValPos)
+
+#define INS_IMM64(Value, Address, Size, InstPos, ValPos) \
+ *(UINT32*)Address = (*(UINT32*)Address & ~(((1 << Size) - 1) << InstPos)) | \
+ ((UINT32)((((UINT64)Value >> ValPos) & (((UINT64)1 << Size) - 1))) << InstPos)
+
+#define IMM64_IMM7B_INST_WORD_X 3
+#define IMM64_IMM7B_SIZE_X 7
+#define IMM64_IMM7B_INST_WORD_POS_X 4
+#define IMM64_IMM7B_VAL_POS_X 0
+
+#define IMM64_IMM9D_INST_WORD_X 3
+#define IMM64_IMM9D_SIZE_X 9
+#define IMM64_IMM9D_INST_WORD_POS_X 18
+#define IMM64_IMM9D_VAL_POS_X 7
+
+#define IMM64_IMM5C_INST_WORD_X 3
+#define IMM64_IMM5C_SIZE_X 5
+#define IMM64_IMM5C_INST_WORD_POS_X 13
+#define IMM64_IMM5C_VAL_POS_X 16
+
+#define IMM64_IC_INST_WORD_X 3
+#define IMM64_IC_SIZE_X 1
+#define IMM64_IC_INST_WORD_POS_X 12
+#define IMM64_IC_VAL_POS_X 21
+
+#define IMM64_IMM41a_INST_WORD_X 1
+#define IMM64_IMM41a_SIZE_X 10
+#define IMM64_IMM41a_INST_WORD_POS_X 14
+#define IMM64_IMM41a_VAL_POS_X 22
+
+#define IMM64_IMM41b_INST_WORD_X 1
+#define IMM64_IMM41b_SIZE_X 8
+#define IMM64_IMM41b_INST_WORD_POS_X 24
+#define IMM64_IMM41b_VAL_POS_X 32
+
+#define IMM64_IMM41c_INST_WORD_X 2
+#define IMM64_IMM41c_SIZE_X 23
+#define IMM64_IMM41c_INST_WORD_POS_X 0
+#define IMM64_IMM41c_VAL_POS_X 40
+
+#define IMM64_SIGN_INST_WORD_X 3
+#define IMM64_SIGN_SIZE_X 1
+#define IMM64_SIGN_INST_WORD_POS_X 27
+#define IMM64_SIGN_VAL_POS_X 63
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an Itanium-based specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ Status code
+
+--*/
+{
+ UINT64 *F64;
+ UINT64 FixupVal;
+
+ switch ((*Reloc) >> 12) {
+
+ case EFI_IMAGE_REL_BASED_IA64_IMM64:
+
+ //
+ // Align it to bundle address before fixing up the
+ // 64-bit immediate value of the movl instruction.
+ //
+
+ Fixup = (CHAR8 *)((UINTN) Fixup & (UINTN) ~(15));
+ FixupVal = (UINT64)0;
+
+ //
+ // Extract the lower 32 bits of IMM64 from bundle
+ //
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X,
+ IMM64_IMM7B_SIZE_X,
+ IMM64_IMM7B_INST_WORD_POS_X,
+ IMM64_IMM7B_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X,
+ IMM64_IMM9D_SIZE_X,
+ IMM64_IMM9D_INST_WORD_POS_X,
+ IMM64_IMM9D_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X,
+ IMM64_IMM5C_SIZE_X,
+ IMM64_IMM5C_INST_WORD_POS_X,
+ IMM64_IMM5C_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IC_INST_WORD_X,
+ IMM64_IC_SIZE_X,
+ IMM64_IC_INST_WORD_POS_X,
+ IMM64_IC_VAL_POS_X
+ );
+
+ EXT_IMM64(FixupVal,
+ (UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X,
+ IMM64_IMM41a_SIZE_X,
+ IMM64_IMM41a_INST_WORD_POS_X,
+ IMM64_IMM41a_VAL_POS_X
+ );
+
+ //
+ // Update 64-bit address
+ //
+ FixupVal += Adjust;
+
+ //
+ // Insert IMM64 into bundle
+ //
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM7B_INST_WORD_X),
+ IMM64_IMM7B_SIZE_X,
+ IMM64_IMM7B_INST_WORD_POS_X,
+ IMM64_IMM7B_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM9D_INST_WORD_X),
+ IMM64_IMM9D_SIZE_X,
+ IMM64_IMM9D_INST_WORD_POS_X,
+ IMM64_IMM9D_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM5C_INST_WORD_X),
+ IMM64_IMM5C_SIZE_X,
+ IMM64_IMM5C_INST_WORD_POS_X,
+ IMM64_IMM5C_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IC_INST_WORD_X),
+ IMM64_IC_SIZE_X,
+ IMM64_IC_INST_WORD_POS_X,
+ IMM64_IC_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM41a_INST_WORD_X),
+ IMM64_IMM41a_SIZE_X,
+ IMM64_IMM41a_INST_WORD_POS_X,
+ IMM64_IMM41a_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM41b_INST_WORD_X),
+ IMM64_IMM41b_SIZE_X,
+ IMM64_IMM41b_INST_WORD_POS_X,
+ IMM64_IMM41b_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_IMM41c_INST_WORD_X),
+ IMM64_IMM41c_SIZE_X,
+ IMM64_IMM41c_INST_WORD_POS_X,
+ IMM64_IMM41c_VAL_POS_X
+ );
+
+ INS_IMM64(FixupVal,
+ ((UINT32 *)Fixup + IMM64_SIGN_INST_WORD_X),
+ IMM64_SIGN_SIZE_X,
+ IMM64_SIGN_INST_WORD_POS_X,
+ IMM64_SIGN_VAL_POS_X
+ );
+
+ F64 = (UINT64 *) Fixup;
+ if (*FixupData != NULL) {
+ *FixupData = ALIGN_POINTER(*FixupData, sizeof(UINT64));
+ *(UINT64 *)(*FixupData) = *F64;
+ *FixupData = *FixupData + sizeof(UINT64);
+ }
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IPF, EBC,
+ images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA64) || (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/Core/CPU/IPF/PeCoffLoaderEx.h b/Core/CPU/IPF/PeCoffLoaderEx.h
new file mode 100644
index 0000000..fc14551
--- /dev/null
+++ b/Core/CPU/IPF/PeCoffLoaderEx.h
@@ -0,0 +1,87 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ Fixes Intel Itanium(TM) specific relocation types
+
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an Itanium-based specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IPF, EBC,
+ images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IPF/PerformancePrimitives.s b/Core/CPU/IPF/PerformancePrimitives.s
new file mode 100644
index 0000000..5aeb886
--- /dev/null
+++ b/Core/CPU/IPF/PerformancePrimitives.s
@@ -0,0 +1,61 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// PerformancePrimitives.s
+//
+// Abstract:
+//
+//
+// Revision History:
+//
+//--
+
+.file "PerformancePrimitives.s"
+
+#include "IpfMacro.i"
+
+//-----------------------------------------------------------------------------
+//++
+// GetTimerValue
+//
+// Implementation of CPU-based time service
+//
+// On Entry :
+// EFI_STATUS
+// GetTimerValue (
+// OUT UINT64 *TimerValue
+// )
+//
+// Return Value:
+// r8 = Status
+// r9 = 0
+// r10 = 0
+// r11 = 0
+//
+// As per static calling conventions.
+//
+//--
+//---------------------------------------------------------------------------
+PROCEDURE_ENTRY (GetTimerValue)
+
+ NESTED_SETUP (1,8,0,0)
+ mov r8 = ar.itc;;
+ st8 [r32]= r8
+ mov r8 = r0
+ mov r9 = r0
+ mov r10 = r0
+ mov r11 = r0
+ NESTED_RETURN
+
+PROCEDURE_EXIT (GetTimerValue)
+//---------------------------------------------------------------------------
+
diff --git a/Core/CPU/IPF/Processor.h b/Core/CPU/IPF/Processor.h
new file mode 100644
index 0000000..8e49d37
--- /dev/null
+++ b/Core/CPU/IPF/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Processor.h
+
+Abstract:
+ This file contains the Ipf processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE * 2)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE * 2)
+
+#endif \ No newline at end of file
diff --git a/Core/CPU/IPF/SwitchStack.s b/Core/CPU/IPF/SwitchStack.s
new file mode 100644
index 0000000..5de7e18
--- /dev/null
+++ b/Core/CPU/IPF/SwitchStack.s
@@ -0,0 +1,122 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// SwitchStack.s
+//
+// Abstract:
+//
+// Contains an implementation of a stack switch for the Itanium-based architecture.
+//
+//
+//
+// Revision History:
+//
+//--
+
+ .file "SwitchStack.s"
+
+#include <asm.h>
+#include <ia_64gen.h>
+
+// Define hardware RSE Configuration Register
+//
+// RS Configuration (RSC) bit field positions
+
+#define RSC_MODE 0
+#define RSC_PL 2
+#define RSC_BE 4
+// RSC bits 5-15 reserved
+#define RSC_MBZ0 5
+#define RSC_MBZ0_V 0x3ff
+#define RSC_LOADRS 16
+#define RSC_LOADRS_LEN 14
+// RSC bits 30-63 reserved
+#define RSC_MBZ1 30
+#define RSC_MBZ1_V 0x3ffffffffULL
+
+// RSC modes
+// Lazy
+#define RSC_MODE_LY (0x0)
+// Store intensive
+#define RSC_MODE_SI (0x1)
+// Load intensive
+#define RSC_MODE_LI (0x2)
+// Eager
+#define RSC_MODE_EA (0x3)
+
+// RSC Endian bit values
+#define RSC_BE_LITTLE 0
+#define RSC_BE_BIG 1
+
+// RSC while in kernel: enabled, little endian, pl = 0, eager mode
+#define RSC_KERNEL ((RSC_MODE_EA<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+// Lazy RSC in kernel: enabled, little endian, pl = 0, lazy mode
+#define RSC_KERNEL_LAZ ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+// RSE disabled: disabled, pl = 0, little endian, eager mode
+#define RSC_KERNEL_DISABLED ((RSC_MODE_LY<<RSC_MODE) | (RSC_BE_LITTLE<<RSC_BE))
+
+
+//VOID
+//SwitchStacks (
+// VOID *ContinuationFunction,
+// UINTN Parameter,
+// UINTN NewTopOfStack,
+// UINTN NewBSPStore OPTIONAL
+//)
+///*++
+//
+//Input Arguments
+//
+// ContinuationFunction - This is a pointer to the PLABEL of the function that should be called once the
+// new stack has been created.
+// Parameter - The parameter to pass to the continuation function
+// NewTopOfStack - This is the new top of the memory stack for ensuing code. This is mandatory and
+// should be non-zero
+// NewBSPStore - This is the new BSP store for the ensuing code. It is optional on IA-32 and mandatory on Itanium-based platform.
+//
+//--*/
+
+PROCEDURE_ENTRY(SwitchStacks)
+
+ mov r16 = -0x10;;
+ and r16 = r34, r16;; // get new stack value in R16, 0 the last nibble.
+ mov r15 = r35;; // Get new BspStore into R15
+ mov r13 = r32;; // this is a pointer to the PLABEL of the continuation function.
+ mov r17 = r33;; // this is the parameter to pass to the continuation function
+
+ alloc r11=0,0,0,0 // Set 0-size frame
+ ;;
+ flushrs;;
+
+ mov r21 = RSC_KERNEL_DISABLED // for rse disable
+ ;;
+ mov ar.rsc = r21 // turn off RSE
+
+ add sp = r0, r16;; // transfer to the EFI stack
+ mov ar.bspstore = r15 // switch to EFI BSP
+ invala // change of ar.bspstore needs invala.
+
+ mov r18 = RSC_KERNEL_LAZ // RSC enabled, Lazy mode
+ ;;
+ mov ar.rsc = r18 // turn rse on, in kernel mode
+ ;;
+ alloc r11=0,0,1,0;; // alloc 0 outs going to ensuing DXE IPL service
+ mov out0 = r17
+ ld8 r16 = [r13],8;; // r16 = address of continuation function from the PLABEL
+ ld8 gp = [r13] // gp = gp of continuation function from the PLABEL
+ mov b6 = r16
+ ;;
+ br.call.sptk.few b0=b6;; // Call the continuation function
+ ;;
+PROCEDURE_EXIT(SwitchStacks)
+
+
diff --git a/Core/CPU/IPF/SwitchToCacheMode.c b/Core/CPU/IPF/SwitchToCacheMode.c
new file mode 100644
index 0000000..9f938d4
--- /dev/null
+++ b/Core/CPU/IPF/SwitchToCacheMode.c
@@ -0,0 +1,77 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ SwitchToCacheMode.c
+
+Abstract:
+
+ Ipf CAR specific function used to switch to cache mode for the later memory access
+
+Revision History
+
+--*/
+#include "Tiano.h"
+#include "PeiCore.h"
+#include "IpfCpuCore.i"
+
+extern
+SAL_RETURN_REGS
+GetHandOffStatus (
+ VOID
+ );
+
+VOID
+SwitchToCacheMode (
+ IN PEI_CORE_INSTANCE *CoreData
+ )
+/*++
+
+Routine Description:
+
+ Switch the PHIT pointers to cache mode after InstallPeiMemory in CAR.
+
+Arguments:
+
+ CoreData - The PEI core Private Data
+
+Returns:
+
+--*/
+{
+ EFI_HOB_HANDOFF_INFO_TABLE *Phit;
+
+ if (CoreData == NULL) {
+ //
+ // the first call with CoreData as NULL.
+ //
+ return;
+ }
+
+ if ((GetHandOffStatus().r10 & 0xFF) == RecoveryFn) {
+ CoreData->StackBase = CoreData->StackBase & CACHE_MODE_ADDRESS_MASK;
+ CoreData->HobList.Raw = (UINT8 *)((UINTN)CoreData->HobList.Raw & CACHE_MODE_ADDRESS_MASK);
+
+ //
+ // Change the PHIT pointer value to cache mode
+ //
+ Phit = CoreData->HobList.HandoffInformationTable;
+
+ Phit->EfiMemoryTop = Phit->EfiMemoryTop & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiFreeMemoryTop = Phit->EfiFreeMemoryTop & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiMemoryBottom = Phit->EfiMemoryBottom & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiFreeMemoryBottom = Phit->EfiFreeMemoryBottom & CACHE_MODE_ADDRESS_MASK;
+ Phit->EfiEndOfHobList = Phit->EfiEndOfHobList & CACHE_MODE_ADDRESS_MASK;
+ }
+
+ return;
+} \ No newline at end of file
diff --git a/Core/CPU/IPF/asm.h b/Core/CPU/IPF/asm.h
new file mode 100644
index 0000000..2db93d6
--- /dev/null
+++ b/Core/CPU/IPF/asm.h
@@ -0,0 +1,35 @@
+//
+//
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// asm.h
+//
+// Abstract:
+//
+// This module contains generic macros for an assembly writer.
+//
+//
+// Revision History
+//
+#ifndef _ASM_H
+#define _ASM_H
+
+#define TRUE 1
+#define FALSE 0
+#define PROCEDURE_ENTRY(name) .##text; \
+ .##type name, @function; \
+ .##proc name; \
+ name::
+
+#define PROCEDURE_EXIT(name) .##endp name
+
+#endif // _ASM_H
diff --git a/Core/CPU/IPF/efijump.h b/Core/CPU/IPF/efijump.h
new file mode 100644
index 0000000..4a078ce
--- /dev/null
+++ b/Core/CPU/IPF/efijump.h
@@ -0,0 +1,112 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an IA32 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// NOTE:Set/LongJump needs to have this buffer start
+// at 16 byte boundary. Either fix the structure
+// which call this buffer or fix inside SetJump/LongJump
+// Choosing 1K buffer storage for now
+//
+typedef struct {
+ CHAR8 Buffer[1024];
+} EFI_JUMP_BUFFER;
+
+EFI_STATUS
+SetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ )
+/*++
+
+Routine Description:
+
+ SetJump stores the current register set in the area pointed to
+by "save". It returns zero. Subsequent calls to "LongJump" will
+restore the registers and return non-zero to the same location.
+ On entry, r32 contains the pointer to the jmp_buffer
+
+Arguments:
+
+ This - Calling context
+ Jump - Jump buffer
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+LongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ )
+/*++
+
+Routine Description:
+
+ LongJump initializes the register set to the values saved by a
+previous 'SetJump' and jumps to the return location saved by that
+'SetJump'. This has the effect of unwinding the stack and returning
+for a second time to the 'SetJump'.
+
+Arguments:
+
+ This - Calling context
+ Jump - Jump buffer
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+VOID
+RtPioICacheFlush (
+ IN VOID *StartAddress,
+ IN UINTN SizeInBytes
+ )
+/*++
+
+Routine Description:
+
+ Flushing the CPU instruction cache.
+
+Arguments:
+
+ StartAddress - Start address to flush
+ SizeInBytes - Length in bytes to flush
+
+Returns:
+
+ None
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/IPF/ia_64gen.h b/Core/CPU/IPF/ia_64gen.h
new file mode 100644
index 0000000..8e8d1a5
--- /dev/null
+++ b/Core/CPU/IPF/ia_64gen.h
@@ -0,0 +1,214 @@
+//
+//
+//
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+//Module Name: ia_64gen.h
+//
+//
+//Abstract:
+//
+//
+//
+//
+//Revision History
+//
+//
+#ifndef _IA64GEN_H
+#define _IA64GEN_H
+
+#define TT_UNAT 0
+#define C_PSR 0
+#define J_UNAT 0
+#define T_TYPE 0
+#define T_IPSR 0x8
+#define T_ISR 0x10
+#define T_IIP 0x18
+#define T_IFA 0x20
+#define T_IIPA 0x28
+#define T_IFS 0x30
+#define T_IIM 0x38
+#define T_RSC 0x40
+#define T_BSP 0x48
+#define T_BSPSTORE 0x50
+#define T_RNAT 0x58
+#define T_PFS 0x60
+#define T_KBSPSTORE 0x68
+#define T_UNAT 0x70
+#define T_CCV 0x78
+#define T_DCR 0x80
+#define T_PREDS 0x88
+#define T_NATS 0x90
+#define T_R1 0x98
+#define T_GP 0x98
+#define T_R2 0xa0
+#define T_R3 0xa8
+#define T_R4 0xb0
+#define T_R5 0xb8
+#define T_R6 0xc0
+#define T_R7 0xc8
+#define T_R8 0xd0
+#define T_R9 0xd8
+#define T_R10 0xe0
+#define T_R11 0xe8
+#define T_R12 0xf0
+#define T_SP 0xf0
+#define T_R13 0xf8
+#define T_R14 0x100
+#define T_R15 0x108
+#define T_R16 0x110
+#define T_R17 0x118
+#define T_R18 0x120
+#define T_R19 0x128
+#define T_R20 0x130
+#define T_R21 0x138
+#define T_R22 0x140
+#define T_R23 0x148
+#define T_R24 0x150
+#define T_R25 0x158
+#define T_R26 0x160
+#define T_R27 0x168
+#define T_R28 0x170
+#define T_R29 0x178
+#define T_R30 0x180
+#define T_R31 0x188
+#define T_F2 0x1f0
+#define T_F3 0x200
+#define T_F4 0x210
+#define T_F5 0x220
+#define T_F6 0x230
+#define T_F7 0x240
+#define T_F8 0x250
+#define T_F9 0x260
+#define T_F10 0x270
+#define T_F11 0x280
+#define T_F12 0x290
+#define T_F13 0x2a0
+#define T_F14 0x2b0
+#define T_F15 0x2c0
+#define T_F16 0x2d0
+#define T_F17 0x2e0
+#define T_F18 0x2f0
+#define T_F19 0x300
+#define T_F20 0x310
+#define T_F21 0x320
+#define T_F22 0x330
+#define T_F23 0x340
+#define T_F24 0x350
+#define T_F25 0x360
+#define T_F26 0x370
+#define T_F27 0x380
+#define T_F28 0x390
+#define T_F29 0x3a0
+#define T_F30 0x3b0
+#define T_F31 0x3c0
+#define T_FPSR 0x1e0
+#define T_B0 0x190
+#define T_B1 0x198
+#define T_B2 0x1a0
+#define T_B3 0x1a8
+#define T_B4 0x1b0
+#define T_B5 0x1b8
+#define T_B6 0x1c0
+#define T_B7 0x1c8
+#define T_EC 0x1d0
+#define T_LC 0x1d8
+#define J_NATS 0x8
+#define J_PFS 0x10
+#define J_BSP 0x18
+#define J_RNAT 0x20
+#define J_PREDS 0x28
+#define J_LC 0x30
+#define J_R4 0x38
+#define J_R5 0x40
+#define J_R6 0x48
+#define J_R7 0x50
+#define J_SP 0x58
+#define J_F2 0x60
+#define J_F3 0x70
+#define J_F4 0x80
+#define J_F5 0x90
+#define J_F16 0xa0
+#define J_F17 0xb0
+#define J_F18 0xc0
+#define J_F19 0xd0
+#define J_F20 0xe0
+#define J_F21 0xf0
+#define J_F22 0x100
+#define J_F23 0x110
+#define J_F24 0x120
+#define J_F25 0x130
+#define J_F26 0x140
+#define J_F27 0x150
+#define J_F28 0x160
+#define J_F29 0x170
+#define J_F30 0x180
+#define J_F31 0x190
+#define J_FPSR 0x1a0
+#define J_B0 0x1a8
+#define J_B1 0x1b0
+#define J_B2 0x1b8
+#define J_B3 0x1c0
+#define J_B4 0x1c8
+#define J_B5 0x1d0
+#define TRAP_FRAME_LENGTH 0x3d0
+#define C_UNAT 0x28
+#define C_NATS 0x30
+#define C_PFS 0x8
+#define C_BSPSTORE 0x10
+#define C_RNAT 0x18
+#define C_RSC 0x20
+#define C_PREDS 0x38
+#define C_LC 0x40
+#define C_DCR 0x48
+#define C_R1 0x50
+#define C_GP 0x50
+#define C_R4 0x58
+#define C_R5 0x60
+#define C_R6 0x68
+#define C_R7 0x70
+#define C_SP 0x78
+#define C_R13 0x80
+#define C_F2 0x90
+#define C_F3 0xa0
+#define C_F4 0xb0
+#define C_F5 0xc0
+#define C_F16 0xd0
+#define C_F17 0xe0
+#define C_F18 0xf0
+#define C_F19 0x100
+#define C_F20 0x110
+#define C_F21 0x120
+#define C_F22 0x130
+#define C_F23 0x140
+#define C_F24 0x150
+#define C_F25 0x160
+#define C_F26 0x170
+#define C_F27 0x180
+#define C_F28 0x190
+#define C_F29 0x1a0
+#define C_F30 0x1b0
+#define C_F31 0x1c0
+#define C_FPSR 0x1d0
+#define C_B0 0x1d8
+#define C_B1 0x1e0
+#define C_B2 0x1e8
+#define C_B3 0x1f0
+#define C_B4 0x1f8
+#define C_B5 0x200
+#define TT_R2 0x8
+#define TT_R3 0x10
+#define TT_R8 0x18
+#define TT_R9 0x20
+#define TT_R10 0x28
+#define TT_R11 0x30
+#define TT_R14 0x38
+
+#endif _IA64GEN_H
diff --git a/Core/CPU/IPF/pioflush.s b/Core/CPU/IPF/pioflush.s
new file mode 100644
index 0000000..0f0d760
--- /dev/null
+++ b/Core/CPU/IPF/pioflush.s
@@ -0,0 +1,106 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// pioflush.s
+//
+// Abstract:
+//
+//
+// Revision History:
+//
+//--
+
+ .file "pioflush.c"
+ .radix D
+ .section .text, "ax", "progbits"
+ .align 32
+ .section .pdata, "a", "progbits"
+ .align 4
+ .section .xdata, "a", "progbits"
+ .align 8
+ .section .data, "wa", "progbits"
+ .align 16
+ .section .rdata, "a", "progbits"
+ .align 16
+ .section .bss, "wa", "nobits"
+ .align 16
+ .section .tls$, "was", "progbits"
+ .align 16
+ .section .sdata, "was", "progbits"
+ .align 16
+ .section .sbss, "was", "nobits"
+ .align 16
+ .section .srdata, "as", "progbits"
+ .align 16
+ .section .rdata, "a", "progbits"
+ .align 16
+ .section .rtcode, "ax", "progbits"
+ .align 32
+ .type RtPioICacheFlush# ,@function
+ .global RtPioICacheFlush#
+// Function compile flags: /Ogsy
+ .section .rtcode
+
+// Begin code for function: RtPioICacheFlush:
+ .proc RtPioICacheFlush#
+ .align 32
+RtPioICacheFlush:
+// File e:\tmp\pioflush.c
+ { .mii //R-Addr: 0X00
+ alloc r3=2, 0, 0, 0 //11, 00000002H
+ cmp4.leu p0,p6=32, r33;; //15, 00000020H
+ (p6) mov r33=32;; //16, 00000020H
+ }
+ { .mii //R-Addr: 0X010
+ nop.m 0
+ zxt4 r29=r33;; //21
+ dep.z r30=r29, 0, 5;; //21, 00000005H
+ }
+ { .mii //R-Addr: 0X020
+ cmp4.eq p0,p7=r0, r30 //21
+ shr.u r28=r29, 5;; //19, 00000005H
+ (p7) adds r28=1, r28;; //22, 00000001H
+ }
+ { .mii //R-Addr: 0X030
+ nop.m 0
+ shl r27=r28, 5;; //25, 00000005H
+ zxt4 r26=r27;; //25
+ }
+ { .mfb //R-Addr: 0X040
+ add r31=r26, r32 //25
+ nop.f 0
+ nop.b 0
+ }
+$L143:
+ { .mii //R-Addr: 0X050
+ fc r32 //27
+ adds r32=32, r32;; //28, 00000020H
+ cmp.ltu p14,p15=r32, r31 //29
+ }
+ { .mfb //R-Addr: 0X060
+ nop.m 0
+ nop.f 0
+ (p14) br.cond.dptk.few $L143#;; //29, 880000/120000
+ }
+ { .mmi
+ sync.i;;
+ srlz.i
+ nop.i 0;;
+ }
+ { .mfb //R-Addr: 0X070
+ nop.m 0
+ nop.f 0
+ br.ret.sptk.few b0;; //31
+ }
+// End code for function:
+ .endp RtPioICacheFlush#
+// END
diff --git a/Core/CPU/IPF/processor.c b/Core/CPU/IPF/processor.c
new file mode 100644
index 0000000..9740948
--- /dev/null
+++ b/Core/CPU/IPF/processor.c
@@ -0,0 +1,118 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include "PeiHob.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+EFI_STATUS
+WinNtFlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ SetJump,
+ LongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ WinNtFlushInstructionCacheFlush
+};
+
+EFI_STATUS
+InstallEfiPeiTransferControl (
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ EFI_SUCCESS - Successfully installed
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+WinNtFlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+
+Arguments:
+
+ This - Pointer to CPU Architectural Protocol interface
+ Start - Start adddress in memory to flush
+ Length - Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ RtPioICacheFlush ((UINT8 *) Start, (UINTN) Length);
+ return EFI_SUCCESS;
+}
diff --git a/Core/CPU/IPF/setjmp.s b/Core/CPU/IPF/setjmp.s
new file mode 100644
index 0000000..ee27ca7
--- /dev/null
+++ b/Core/CPU/IPF/setjmp.s
@@ -0,0 +1,325 @@
+//++
+// Copyright (c) 2004, Intel Corporation
+// All rights reserved. This program and the accompanying materials
+// are licensed and made available under the terms and conditions of the BSD License
+// which accompanies this distribution. The full text of the license may be found at
+// http://opensource.org/licenses/bsd-license.php
+//
+// THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+// WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+//
+// Module Name:
+//
+// setjmp.s
+//
+// Abstract:
+//
+// Contains an implementation of setjmp and longjmp for the
+// Itanium-based architecture.
+//
+//
+//
+// Revision History:
+//
+//--
+
+ .file "setjmp.s"
+
+#include <asm.h>
+#include <ia_64gen.h>
+
+// int SetJump(struct jmp_buffer save)
+//
+// Setup a non-local goto.
+//
+// Description:
+//
+// SetJump stores the current register set in the area pointed to
+// by "save". It returns zero. Subsequent calls to "LongJump" will
+// restore the registers and return non-zero to the same location.
+//
+// On entry, r32 contains the pointer to the jmp_buffer
+//
+
+PROCEDURE_ENTRY(SetJump)
+ //
+ // Make sure buffer is aligned at 16byte boundary
+ //
+ mov r32 = r33
+
+ add r10 = -0x10,r0 ;; // mask the lower 4 bits
+ and r32 = r32, r10;;
+ add r32 = 0x10, r32;; // move to next 16 byte boundary
+
+ add r10 = J_PREDS, r32 // skip Unats & pfs save area
+ add r11 = J_BSP, r32
+ //
+ // save immediate context
+ //
+ mov r2 = ar.bsp // save backing store pointer
+ mov r3 = pr // save predicates
+ ;;
+ //
+ // save user Unat register
+ //
+ mov r16 = ar.lc // save loop count register
+ mov r14 = ar.unat // save user Unat register
+
+ st8 [r10] = r3, J_LC-J_PREDS
+ st8 [r11] = r2, J_R4-J_BSP
+ ;;
+ st8 [r10] = r16, J_R5-J_LC
+ st8 [r32] = r14, J_NATS // Note: Unat at the
+ // beginning of the save area
+ mov r15 = ar.pfs
+ ;;
+ //
+ // save preserved general registers & NaT's
+ //
+ st8.spill [r11] = r4, J_R6-J_R4
+ ;;
+ st8.spill [r10] = r5, J_R7-J_R5
+ ;;
+ st8.spill [r11] = r6, J_SP-J_R6
+ ;;
+ st8.spill [r10] = r7, J_F3-J_R7
+ ;;
+ st8.spill [r11] = sp, J_F2-J_SP
+ ;;
+ //
+ // save spilled Unat and pfs registers
+ //
+ mov r2 = ar.unat // save Unat register after spill
+ ;;
+ st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs
+ ;;
+ st8 [r32] = r15 // save pfs
+ //
+ // save floating registers
+ //
+ stf.spill [r11] = f2, J_F4-J_F2
+ stf.spill [r10] = f3, J_F5-J_F3
+ ;;
+ stf.spill [r11] = f4, J_F16-J_F4
+ stf.spill [r10] = f5, J_F17-J_F5
+ ;;
+ stf.spill [r11] = f16, J_F18-J_F16
+ stf.spill [r10] = f17, J_F19-J_F17
+ ;;
+ stf.spill [r11] = f18, J_F20-J_F18
+ stf.spill [r10] = f19, J_F21-J_F19
+ ;;
+ stf.spill [r11] = f20, J_F22-J_F20
+ stf.spill [r10] = f21, J_F23-J_F21
+ ;;
+ stf.spill [r11] = f22, J_F24-J_F22
+ stf.spill [r10] = f23, J_F25-J_F23
+ ;;
+ stf.spill [r11] = f24, J_F26-J_F24
+ stf.spill [r10] = f25, J_F27-J_F25
+ ;;
+ stf.spill [r11] = f26, J_F28-J_F26
+ stf.spill [r10] = f27, J_F29-J_F27
+ ;;
+ stf.spill [r11] = f28, J_F30-J_F28
+ stf.spill [r10] = f29, J_F31-J_F29
+ ;;
+ stf.spill [r11] = f30, J_FPSR-J_F30
+ stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr
+ //
+ // save FPSR register & branch registers
+ //
+ mov r2 = ar.fpsr // save fpsr register
+ mov r3 = b0
+ ;;
+ st8 [r11] = r2, J_B1-J_FPSR
+ st8 [r10] = r3, J_B2-J_B0
+ mov r2 = b1
+ mov r3 = b2
+ ;;
+ st8 [r11] = r2, J_B3-J_B1
+ st8 [r10] = r3, J_B4-J_B2
+ mov r2 = b3
+ mov r3 = b4
+ ;;
+ st8 [r11] = r2, J_B5-J_B3
+ st8 [r10] = r3
+ mov r2 = b5
+ ;;
+ st8 [r11] = r2
+ ;;
+ //
+ // return
+ //
+ mov r8 = r0 // return 0 from setjmp
+ mov ar.unat = r14 // restore unat
+ br.ret.sptk b0
+
+PROCEDURE_EXIT(SetJump)
+
+
+//
+// void LongJump(struct jmp_buffer *)
+//
+// Perform a non-local goto.
+//
+// Description:
+//
+// LongJump initializes the register set to the values saved by a
+// previous 'SetJump' and jumps to the return location saved by that
+// 'SetJump'. This has the effect of unwinding the stack and returning
+// for a second time to the 'SetJump'.
+//
+
+PROCEDURE_ENTRY(LongJump)
+ //
+ // Make sure buffer is aligned at 16byte boundary
+ //
+ mov r32 = r33
+
+ add r10 = -0x10,r0 ;; // mask the lower 4 bits
+ and r32 = r32, r10;;
+ add r32 = 0x10, r32;; // move to next 16 byte boundary
+
+ //
+ // caching the return value as we do invala in the end
+ //
+/// mov r8 = r33 // return value
+ mov r8 = 1 // For now return hard coded 1
+
+ //
+ // get immediate context
+ //
+ mov r14 = ar.rsc // get user RSC conf
+ add r10 = J_PFS, r32 // get address of pfs
+ add r11 = J_NATS, r32
+ ;;
+ ld8 r15 = [r10], J_BSP-J_PFS // get pfs
+ ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs
+ ;;
+ mov ar.unat = r2
+ ;;
+ ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer
+ mov ar.rsc = r0 // put RSE in enforced lazy
+ mov ar.pfs = r15
+ ;;
+
+ //
+ // while returning from longjmp the BSPSTORE and BSP needs to be
+ // same and discard all the registers allocated after we did
+ // setjmp. Also, we need to generate the RNAT register since we
+ // did not flushed the RSE on setjmp.
+ //
+ mov r17 = ar.bspstore // get current BSPSTORE
+ ;;
+ cmp.ltu p6,p7 = r17, r16 // is it less than BSP of
+(p6) br.spnt.few .flush_rse
+ mov r19 = ar.rnat // get current RNAT
+ ;;
+ loadrs // invalidate dirty regs
+ br.sptk.many .restore_rnat // restore RNAT
+
+.flush_rse:
+ flushrs
+ ;;
+ mov r19 = ar.rnat // get current RNAT
+ mov r17 = r16 // current BSPSTORE
+ ;;
+.restore_rnat:
+ //
+ // check if RNAT is saved between saved BSP and curr BSPSTORE
+ //
+ dep r18 = 1,r16,3,6 // get RNAT address
+ ;;
+ cmp.ltu p8,p9 = r18, r17 // RNAT saved on RSE
+ ;;
+(p8) ld8 r19 = [r18] // get RNAT from RSE
+ ;;
+ mov ar.bspstore = r16 // set new BSPSTORE
+ ;;
+ mov ar.rnat = r19 // restore RNAT
+ mov ar.rsc = r14 // restore RSC conf
+
+
+ ld8 r3 = [r11], J_R4-J_LC // get lc register
+ ld8 r2 = [r10], J_R5-J_PREDS // get predicates
+ ;;
+ mov pr = r2, -1
+ mov ar.lc = r3
+ //
+ // restore preserved general registers & NaT's
+ //
+ ld8.fill r4 = [r11], J_R6-J_R4
+ ;;
+ ld8.fill r5 = [r10], J_R7-J_R5
+ ld8.fill r6 = [r11], J_SP-J_R6
+ ;;
+ ld8.fill r7 = [r10], J_F2-J_R7
+ ld8.fill sp = [r11], J_F3-J_SP
+ ;;
+ //
+ // restore floating registers
+ //
+ ldf.fill f2 = [r10], J_F4-J_F2
+ ldf.fill f3 = [r11], J_F5-J_F3
+ ;;
+ ldf.fill f4 = [r10], J_F16-J_F4
+ ldf.fill f5 = [r11], J_F17-J_F5
+ ;;
+ ldf.fill f16 = [r10], J_F18-J_F16
+ ldf.fill f17 = [r11], J_F19-J_F17
+ ;;
+ ldf.fill f18 = [r10], J_F20-J_F18
+ ldf.fill f19 = [r11], J_F21-J_F19
+ ;;
+ ldf.fill f20 = [r10], J_F22-J_F20
+ ldf.fill f21 = [r11], J_F23-J_F21
+ ;;
+ ldf.fill f22 = [r10], J_F24-J_F22
+ ldf.fill f23 = [r11], J_F25-J_F23
+ ;;
+ ldf.fill f24 = [r10], J_F26-J_F24
+ ldf.fill f25 = [r11], J_F27-J_F25
+ ;;
+ ldf.fill f26 = [r10], J_F28-J_F26
+ ldf.fill f27 = [r11], J_F29-J_F27
+ ;;
+ ldf.fill f28 = [r10], J_F30-J_F28
+ ldf.fill f29 = [r11], J_F31-J_F29
+ ;;
+ ldf.fill f30 = [r10], J_FPSR-J_F30
+ ldf.fill f31 = [r11], J_B0-J_F31 ;;
+
+ //
+ // restore branch registers and fpsr
+ //
+ ld8 r16 = [r10], J_B1-J_FPSR // get fpsr
+ ld8 r17 = [r11], J_B2-J_B0 // get return pointer
+ ;;
+ mov ar.fpsr = r16
+ mov b0 = r17
+ ld8 r2 = [r10], J_B3-J_B1
+ ld8 r3 = [r11], J_B4-J_B2
+ ;;
+ mov b1 = r2
+ mov b2 = r3
+ ld8 r2 = [r10], J_B5-J_B3
+ ld8 r3 = [r11]
+ ;;
+ mov b3 = r2
+ mov b4 = r3
+ ld8 r2 = [r10]
+ ld8 r21 = [r32] // get user unat
+ ;;
+ mov b5 = r2
+ mov ar.unat = r21
+
+ //
+ // invalidate ALAT
+ //
+ invala ;;
+
+ br.ret.sptk b0
+PROCEDURE_EXIT(LongJump)
+
+
diff --git a/Core/CPU/MBIOSMAC.MAC b/Core/CPU/MBIOSMAC.MAC
new file mode 100644
index 0000000..5fe3105
--- /dev/null
+++ b/Core/CPU/MBIOSMAC.MAC
@@ -0,0 +1,512 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*****************************************************************;
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MBIOSMAC.MAC 1 2/07/12 3:58a Davidhsieh $
+;
+; $Revision: 1 $
+;
+; $Date: 2/07/12 3:58a $
+;*****************************************************************;
+;*****************************************************************;
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MBIOSMAC.MAC $
+;
+; 1 2/07/12 3:58a Davidhsieh
+;
+;
+;*****************************************************************;
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: MBIOSMAC.MAC
+;
+; Description: Assembly Macros
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+
+ifndef _mbiosmac_mac_
+_mbiosmac_mac_ equ 1
+.xlist
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEXTERN_NEAR
+;
+; Description: External Near macro
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEXTERN_NEAR MACRO LabelName
+
+ EXTERN LabelName:NEAR ; Define the label as a NEAR EXTERN.
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEXTERN_NEAR32
+;
+; Description: External Near 32 Macro
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEXTERN_NEAR32 MACRO LabelName
+
+ EXTERN LabelName:NEAR32 ; Define the label as a NEAR EXTERN.
+
+ENDM
+
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEXTERN_FAR
+;
+; Description: External Far macro
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEXTERN_FAR MACRO LabelName
+
+ EXTERN LabelName:FAR ; Define the label as a FAR EXTERN.
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_PROC_NEAR
+;
+; Description: Start Near procedure macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_PROC_NEAR MACRO LabelName
+
+LabelName PROC NEAR PUBLIC
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_PROC_NEAR32
+;
+; Description: Start Near 32-bit procedure macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_PROC_NEAR32 MACRO LabelName
+
+LabelName PROC NEAR32 PUBLIC
+
+ENDM
+
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_CALL_PROC_NEAR
+;
+; Description: Call near macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_CALL_PROC_NEAR MACRO LabelID, LabelName
+
+ call LabelName
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_JMP_PROC_NEAR
+;
+; Description: Jump Near Macro. Provide a return label to jump to.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_JMP_PROC_NEAR MACRO LabelID, LabelName
+
+ jmp LabelName
+ PUBLIC LabelName&End
+LabelName&End::
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_JMP_PROC_NEAR32
+;
+; Description: Jump near 32-bit macro. Provide a return label to jump to.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_JMP_PROC_NEAR32 MACRO LabelID, LabelName
+
+ jmp LabelName
+ PUBLIC LabelName&End
+LabelName&End::
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_NEAR
+;
+; Description: End near procedure macro. Last in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_NEAR MACRO LabelName
+
+ ret
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_WITH_JMP_NEAR
+;
+; Description: End of procedure and jump near macro. Last procedure in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_WITH_JMP_NEAR MACRO LabelName
+
+ EXTERN LabelName&End:NEAR
+ jmp LabelName&End
+LabelName ENDP
+
+ENDM
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_WITH_JMP_NEAR32
+;
+; Description: Jump Near 32-bit macro. Last macro in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_WITH_JMP_NEAR32 MACRO LabelName
+
+ EXTERN LabelName&End:NEAR32
+ jmp LabelName&End
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_PROC_FAR
+;
+; Description: Far procedure macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_PROC_FAR MACRO LabelName
+
+LabelName PROC FAR PUBLIC
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_CALL_PROC_FAR
+;
+; Description: Call far macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_CALL_PROC_FAR MACRO LabelID, LabelName
+
+ call LabelName
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_JMP_PROC_FAR
+;
+; Description: jmp far macro with return label to jump back to.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_JMP_PROC_FAR MACRO LabelID, LabelName
+
+ jmp LabelName
+ PUBLIC LabelName&End
+LabelName&End::
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_FAR
+;
+; Description: Ret procedure macro. Last in a group.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_FAR MACRO LabelName
+
+ ret
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_PROC_WITH_JMP_FAR
+;
+; Description: End procedure macro. Last in agroup.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_PROC_WITH_JMP_FAR MACRO LabelName
+
+ EXTERN LabelName&End:FAR
+ jmp LabelName&End
+LabelName ENDP
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mSTART_TBL
+;
+; Description: Start table macro.
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mSTART_TBL MACRO LabelName
+
+ PUBLIC LabelName
+LabelName LABEL BYTE
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_TBL_ENTRY_NEAR
+;
+; Description: Start table enty macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_TBL_ENTRY_NEAR MACRO LabelID, LabelName
+
+ stTblEntryNEAR <LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_ID_AND_TBL_ENTRY_NEAR
+;
+; Description: Start ID Table Entry macro.
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_ID_AND_TBL_ENTRY_NEAR MACRO LabelID, LabelName
+
+ stIDAndTblEntryNEAR <LabelID, LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_TBL_ENTRY_FAR
+;
+; Description:
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_TBL_ENTRY_FAR MACRO LabelID, LabelName
+
+ stTblEntryFAR <LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mBODY_ID_AND_TBL_ENTRY_FAR
+;
+; Description:
+;
+; Input:
+; LabelID
+; LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mBODY_ID_AND_TBL_ENTRY_FAR MACRO LabelID, LabelName
+
+ stIDAndTblEntryFAR <LabelID, LabelName>
+
+ENDM
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: mEND_TBL
+;
+; Description:
+;
+; Input: LabelName
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+mEND_TBL MACRO LabelName
+
+ PUBLIC LabelName&End
+LabelName&End LABEL BYTE
+
+ENDM
+
+.list
+
+endif ;_mbiosmac_mac_
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/FwhFvb.c b/Core/CPU/MicrocodeUpdate/FwhFvb.c
new file mode 100644
index 0000000..9450272
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/FwhFvb.c
@@ -0,0 +1,140 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/FwhFvb.c 1 2/07/12 3:59a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:59a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/FwhFvb.c $
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FwhFvb.c
+//
+// Description:
+// This file contains code for flash update used by the MicrocodeUpdate module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#include "Flash.h"
+#include "Token.h"
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FwhFvbErase
+//
+// Description: This function erases a block of NVRAM.
+//
+// Input: Address - Address of the block to erase
+//
+// Output: Return Status based on errors that occurred while erasing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FwhErase(
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+)
+{
+ UINTN FlashBlockStart = BLOCK(Address);
+ UINTN FlashBlockEnd = BLOCK(Address + NumberOfBytes - 1);
+ UINTN FlashBlock;
+ BOOLEAN bStatus;
+
+ FlashDeviceWriteEnable();
+
+ for (FlashBlock = FlashBlockStart; FlashBlock <= FlashBlockEnd; FlashBlock += FLASH_BLOCK_SIZE) {
+ FlashBlockWriteEnable((UINT8*)FlashBlock);
+ bStatus = FlashEraseBlock((UINT8*)FlashBlock);
+ FlashBlockWriteDisable((UINT8*)FlashBlock);
+ if (!bStatus) break;
+ }
+
+ FlashDeviceWriteDisable();
+
+ return bStatus ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FwhWrite
+//
+// Description: This function writes a block of NVRAM.
+//
+// Input: Address - Address of the block to write.
+// Buffer - Pointer to a buffer containing data to write.
+// NumberOfBytes - The number of bytes to write
+//
+// Output: Return Status based on errors that occurred while writing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FwhWrite(
+ IN UINT8 *Buffer,
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+)
+{
+ BOOLEAN bStatus;
+ UINTN FlashBlockStart = BLOCK(Address);
+ UINTN FlashBlockEnd = BLOCK(Address + NumberOfBytes - 1);
+ UINTN FlashBlock;
+
+ FlashDeviceWriteEnable();
+
+ for (FlashBlock = FlashBlockStart; FlashBlock <= FlashBlockEnd; FlashBlock += FLASH_BLOCK_SIZE) {
+ FlashBlockWriteEnable((UINT8*)FlashBlock);
+ }
+
+
+ bStatus = FlashProgram((UINT8*)Address, Buffer, (UINT32)NumberOfBytes);
+
+
+ for (FlashBlock = FlashBlockStart; FlashBlock <= FlashBlockEnd; FlashBlock += FLASH_BLOCK_SIZE) {
+ FlashBlockWriteDisable((UINT8*)FlashBlock);
+ }
+
+ FlashDeviceWriteDisable();
+
+ return bStatus ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c
new file mode 100644
index 0000000..bc3b696
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.c
@@ -0,0 +1,1164 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.c 4 4/14/15 2:48a Crystallee $
+//
+// $Revision: 4 $
+//
+// $Date: 4/14/15 2:48a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.c $
+//
+// 4 4/14/15 2:48a Crystallee
+//
+// 3 5/15/14 2:32a Crystallee
+// [TAG] EIP169079
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in Microcode update
+// SWSMI.
+//
+// 2 10/28/12 11:23p Davidhsieh
+// [TAG] EIP104874
+// [Category] Improvement
+// [Description] Add signature check before search microcode ffs
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MicrocodeUpdate.c
+//
+// Description: Microcode Update SMI handler.
+// This file contains code for processing Interrupt 15 function
+// D042h, and for registering the callback that does the processing.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <token.h>
+#include <AmiDxeLib.h>
+#include <Ffs.h>
+#include <AmiCspLibInc.h>
+#include "MicrocodeUpdate.h"
+#include <AmiSmm.h>
+#include <AmiHobs.h>
+
+#ifndef INT15_D042_SWSMI
+#define INT15_D042_SWSMI 0x44
+#endif
+
+#pragma optimize("", off)
+
+EFI_GUID gMcodeFfsguid =
+ {0x17088572, 0x377F, 0x44ef, 0x8F,0x4E,0xB0,0x9F,0xFF,0x46,0xA0,0x70};
+
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+
+#if MICROCODE_SPLIT_BB_UPDATE
+UINT8 *gMcodeFlashStartFixed = 0;
+UINT32 gMcodeFlashSizeFixed = 0;
+#endif
+
+UINT8 *gMcodeFlashStartUpdate = 0;
+UINT32 gMcodeFlashSizeUpdate = 0;
+
+typedef enum {
+ MCODE_BLK_EMPTY = 0,
+ MCODE_BLK_START,
+ MCODE_BLK_CONT
+} MCODE_BLK_TYPE;
+
+typedef struct {
+ UINT8 *Addr;
+ UINT32 Size; //0 if less than 64k
+ MCODE_BLK_TYPE Type;
+} MCODE_BLK_MAP;
+
+UINT16 gNumMcodeBlks = 0;
+UINT16 gFirstEmptyBlk = 0xffff;
+MCODE_BLK_MAP *gMcodeBlkMap = NULL;
+
+UINT32 gCpuSignature;
+UINT8 gCpuFlag;
+UINT32 gUcRevision;
+
+SMM_HOB gSmmHob;
+
+#define MAX_MICROCODE_UPDATE_FUNCTIONS 4
+VOID(*MicrocodeUpdate[4])(SMI_UC_DWORD_REGS *) = {
+ PresenceTest, WriteUpdateData, UpdateControl, ReadUpdateData
+};
+
+#define MICROCODE_SIZE(Hdr) \
+ (((MICROCODE_HEADER*)(Hdr))->TotalSize ? ((MICROCODE_HEADER*)Hdr)->TotalSize : 2048)
+
+#if PACK_MICROCODE
+#define MICROCODE_ALIGN_SIZE(Hdr) \
+ ((MICROCODE_SIZE(Hdr) + 16 - 1) & ~(16 - 1))
+#else
+#define MICROCODE_ALIGN_SIZE(Hdr) \
+ ((MICROCODE_SIZE(Hdr) + MICROCODE_BLOCK_SIZE - 1) & ~(MICROCODE_BLOCK_SIZE - 1))
+#endif
+
+#if PACK_MICROCODE
+#define MICROCODE_BLOCKS(Hdr) \
+ ((((MICROCODE_SIZE(Hdr) + MICROCODE_BLOCK_SIZE - 1) & ~(MICROCODE_BLOCK_SIZE - 1)))/MICROCODE_BLOCK_SIZE)
+#else
+ #define MICROCODE_BLOCKS(Hdr) (MICROCODE_ALIGN_SIZE(Hdr)/MICROCODE_BLOCK_SIZE)
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckAddressRange
+//
+// Description: Check address range to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Range - length of the area
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// EFI_ACCESS_DENIED - Access denied!
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CheckAddressRange( IN UINT8 *Address, IN UINTN Range )
+{
+ // Check the size and range
+ if ( ((EFI_PHYSICAL_ADDRESS)Address >= gSmmHob.Tseg) &&
+ ((EFI_PHYSICAL_ADDRESS)Address <= (gSmmHob.Tseg + gSmmHob.TsegLength)) )
+ return EFI_ACCESS_DENIED;
+
+ if ( (((EFI_PHYSICAL_ADDRESS)Address + Range) >= gSmmHob.Tseg) &&
+ (((EFI_PHYSICAL_ADDRESS)Address + Range) <= (gSmmHob.Tseg + gSmmHob.TsegLength)) )
+ return EFI_ACCESS_DENIED;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsValidHeader
+//
+// Description: Check if the header is valid.
+//
+// Input: MICROCODE_HEADER *uHeader -- Address of Microcode Header.
+//
+// Output: BOOLEAN -- TRUE if microcode header is valid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsValidHeader(MICROCODE_HEADER *uHeader)
+{
+ if (uHeader->HeaderVersion != UC_HEADER_VERSION) return FALSE;
+ if (uHeader->LoaderRevison != UC_LOADER_REVISION) return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsValidChecksum
+//
+// Description: Validate the checksum.
+//
+// Input:
+// VOID *Microcode - Address of Microcode Header.
+// UINT32 Size - Microcode Size.
+//
+// Output: BOOLEAN -- TRUE if checksum is valid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsValidChecksum(VOID *Mcode, UINT32 Size)
+{
+ UINT32 NumDwords = Size >> 2;
+ UINT32 *p32 = (UINT32*)Mcode;
+ UINT32 Checksum = 0;
+ UINT32 i;
+
+ for(i = 0; i < NumDwords; ++i) Checksum += p32[i]; //Checksum is the summation dwords.
+
+ return Checksum == 0 ? TRUE : FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInstalledMicrocodeRevision
+//
+// Description: Get the installed microcode revision on the cpu.
+//
+// Input: VOID
+//
+// Output: UINT32 - Revision of microcode currently installed on CPU.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 GetInstalledMicrocodeRevision()
+{
+ UINT32 RegEax, RegEbx, RegEcx, RegEdx;
+
+ //Clear IA32_BIOS_SIGN_ID of microcode loaded.
+ WriteMsr(0x8b, 0); //IA32_BIOS_SIGN_ID
+
+ //Reading CPU ID 1, updates the MSR to the microcode revision.
+ CPULib_CpuID(1, &RegEax, &RegEbx, &RegEcx, &RegEdx);
+ return (UINT32) Shr64(ReadMsr(0x8b), 32);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CountBlks
+//
+// Description: Count blocks taken by microcode in FFS.
+//
+// Input:
+// IN UINT8 *McodeStart - Start of microcode in FFS.
+// IN UINT32 McodeSize - Size of microcode and empty space in FFS.
+// IN BOOLEAN CountEmpty - TRUE if calculate blocks for empty space.
+//
+// Output: UINT16 - Number of blocks needed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 CountBlks(IN UINT8 *McodeStart, IN UINT32 McodeSize, IN BOOLEAN CountEmpty)
+{
+ UINT8 *p = McodeStart;
+ UINT8 *EndOfMcode = p + McodeSize;
+ UINT16 TotBlks = 0;
+
+ while(p < EndOfMcode) {
+ if (*(UINT32*)p != 0xffffffff && *(UINT32*)p != 0) {
+ TotBlks += MICROCODE_BLOCKS(p);
+ p += MICROCODE_ALIGN_SIZE(p);
+ } else if (CountEmpty) {
+ TotBlks += (UINT16)((EndOfMcode - p) / MICROCODE_BLOCK_SIZE);
+ break;
+ }
+ else break;
+ }
+
+ return TotBlks;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillMicrocodeBlkMap
+//
+// Description: Update gMcodeBlkMap with data for microcode.
+//
+// Input:
+// IN OUT *BlkStart - On Input: Start update with this block. Output: Next call use this value.
+// IN UINT8 *McodeStart - Start of microcode in FFS.
+// IN UINT32 McodeSize - Size of microcode and empty space in FFS.
+// IN BOOLEAN CountEmpty - TRUE if update blocks for empty space.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillMicrocodeBlkMap(IN OUT UINT16 *BlkStart, IN UINT8 *McodeStart, IN UINT32 McodeSize, IN BOOLEAN CountEmpty)
+{
+ UINT8 *p = McodeStart;
+ UINT8 *EndOfMcode = p + McodeSize;
+ UINT16 BlkIndex = *BlkStart;
+
+ while(p < EndOfMcode) {
+ if (*(UINT32*)p != 0xffffffff && *(UINT32*)p != 0) {
+ UINT16 NumBlks = MICROCODE_BLOCKS(p);
+ UINT32 McodeSize = MICROCODE_SIZE(p);
+#if PACK_MICROCODE == 0
+ UINT32 PackDiff = MICROCODE_ALIGN_SIZE(p) - McodeSize;
+#endif
+
+ gMcodeBlkMap[BlkIndex].Addr = p;
+ gMcodeBlkMap[BlkIndex].Size = MICROCODE_BLOCK_SIZE;
+ gMcodeBlkMap[BlkIndex].Type = MCODE_BLK_START;
+ if (NumBlks <= 1 && McodeSize < MICROCODE_BLOCK_SIZE) {
+ gMcodeBlkMap[BlkIndex].Size = McodeSize;
+ }
+ p += gMcodeBlkMap[BlkIndex].Size;
+ McodeSize -= gMcodeBlkMap[BlkIndex].Size;
+ ++BlkIndex;
+ while(--NumBlks) {
+ gMcodeBlkMap[BlkIndex].Addr = p;
+ gMcodeBlkMap[BlkIndex].Size = MICROCODE_BLOCK_SIZE;
+ gMcodeBlkMap[BlkIndex].Type = MCODE_BLK_CONT;
+ if (NumBlks == 1 && McodeSize < MICROCODE_BLOCK_SIZE) {
+ gMcodeBlkMap[BlkIndex].Size = McodeSize;
+ }
+ p += gMcodeBlkMap[BlkIndex].Size;
+ McodeSize -= gMcodeBlkMap[BlkIndex].Size;
+ ++BlkIndex;
+ }
+#if PACK_MICROCODE == 0
+ p += PackDiff;
+#endif
+ } else if (CountEmpty) {
+ gFirstEmptyBlk = BlkIndex;
+ while (BlkIndex < gNumMcodeBlks) {
+ gMcodeBlkMap[BlkIndex].Addr = p;
+ gMcodeBlkMap[BlkIndex].Size = MICROCODE_BLOCK_SIZE;
+ gMcodeBlkMap[BlkIndex].Type = MCODE_BLK_EMPTY;
+ BlkIndex++;
+ }
+ break;
+ } else break;
+ }
+ *BlkStart = BlkIndex;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitMcodeBlkMap
+//
+// Description: Initialize gMcodeBlkMap and related globals for all microcode FFS.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitMcodeBlkMap()
+{
+ UINT16 BlkStart = 0;
+
+ if (gMcodeBlkMap != NULL) pSmst->SmmFreePool(gMcodeBlkMap);
+ gNumMcodeBlks = 0;
+#if MICROCODE_SPLIT_BB_UPDATE
+ gNumMcodeBlks += CountBlks(gMcodeFlashStartFixed, gMcodeFlashSizeFixed, FALSE);
+#endif
+ gNumMcodeBlks += CountBlks(gMcodeFlashStartUpdate, gMcodeFlashSizeUpdate, TRUE);
+
+ pSmst->SmmAllocatePool(0, gNumMcodeBlks * sizeof(MCODE_BLK_MAP), &gMcodeBlkMap);
+
+ gFirstEmptyBlk = 0xffff;
+#if MICROCODE_SPLIT_BB_UPDATE
+ FillMicrocodeBlkMap(&BlkStart, gMcodeFlashStartFixed, gMcodeFlashSizeFixed, FALSE);
+#endif
+ FillMicrocodeBlkMap(&BlkStart, gMcodeFlashStartUpdate, gMcodeFlashSizeUpdate, TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindMicrocodeFfs
+//
+// Description: Find Micorode FFS in FV.
+//
+// Input: IN EFI_FIRMWARE_VOLUME_HEADER *FvHdr - Firmware volume to search
+//
+// Output: UINT8 * - Return FFS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 *FindMicrocodeFfs(IN EFI_FIRMWARE_VOLUME_HEADER *FvHdr)
+{
+ UINT8 *FvPtr = (UINT8*)FvHdr + FvHdr->HeaderLength;
+ UINT8 *EndOfFv = (UINT8*)FvHdr + FvHdr->FvLength;
+
+ //Check for corrupt firmware volume.
+ if (FvHdr->Signature != 'HVF_') return NULL;
+ //Search the FV_MAIN firmware volume for the microcode file.
+ while (FvPtr < EndOfFv && *FvPtr != -1) {
+ if (guidcmp(&gMcodeFfsguid, &((EFI_FFS_FILE_HEADER*)FvPtr)->Name)==0)
+ return FvPtr;
+
+ FvPtr += *(UINT32*)&((EFI_FFS_FILE_HEADER*)FvPtr)->Size & 0xffffff;
+ FvPtr = (UINT8*)(((UINTN)FvPtr + 7) & ~7); //8 byte alignment
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitMicrocodeVariables
+//
+// Description: Initialize global variables used by the driver.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN InitMicrocodeVariables()
+{
+ UINT8 *FfsPtr;
+ UINT32 McodeFfsSize;
+ UINT64 MsrValue;
+ UINT32 RegEbx, RegEcx, RegEdx;
+#if MICROCODE_SPLIT_BB_UPDATE
+ UINT16 MPDTLengthFixed;
+#endif
+ UINT16 MPDTLengthUpdate;
+
+#if MICROCODE_SPLIT_BB_UPDATE
+ FfsPtr = FindMicrocodeFfs((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FV_MICROCODE_BASE);
+ if (FfsPtr == NULL) return FALSE;
+
+ gMcodeFlashStartFixed = FfsPtr + sizeof(EFI_FFS_FILE_HEADER);
+ McodeFfsSize = ((*(UINT32*)((EFI_FFS_FILE_HEADER*)FfsPtr)->Size) & 0xffffff);
+#if MPDTable_CREATED
+ MPDTLengthFixed = *(UINT16*)(FfsPtr + McodeFfsSize - 2); //Last 2 bytes is table size.
+#else
+ MPDTLengthFixed = 0;
+#endif
+ gMcodeFlashSizeFixed = McodeFfsSize - sizeof(EFI_FFS_FILE_HEADER) - MPDTLengthFixed;
+#endif
+
+#if MICROCODE_SPLIT_BB_UPDATE
+ FfsPtr = FindMicrocodeFfs((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FV_MICROCODE_UPDATE_BASE);
+#else
+ FfsPtr = FindMicrocodeFfs((EFI_FIRMWARE_VOLUME_HEADER*)(UINTN)FV_MICROCODE_BASE);
+#endif
+ if (FfsPtr == NULL) return FALSE;
+
+ gMcodeFlashStartUpdate = FfsPtr + sizeof(EFI_FFS_FILE_HEADER);
+ McodeFfsSize = ((*(UINT32*)((EFI_FFS_FILE_HEADER*)FfsPtr)->Size) & 0xffffff);
+#if MPDTable_CREATED
+ MPDTLengthUpdate = *(UINT16*)(FfsPtr + McodeFfsSize - 2); //Last 2 bytes is table size.
+#else
+ MPDTLengthUpdate = 0;
+#endif
+ gMcodeFlashSizeUpdate = McodeFfsSize - sizeof(EFI_FFS_FILE_HEADER) - MPDTLengthUpdate;
+
+ InitMcodeBlkMap();
+
+ //Clear revision value. CPUID of 1 will update this revision value.
+ WriteMsr(0x8b, 0); //IA32_BIOS_SIGN_ID
+
+ CPULib_CpuID(1, &gCpuSignature, &RegEbx, &RegEcx, &RegEdx);
+ gCpuSignature &= 0x00ffffff;
+ MsrValue = ReadMsr(0x17);
+ gCpuFlag = (UINT8)(Shr64(MsrValue, 50) & 7); //Get the CPU flags.
+ gUcRevision = (UINT32) Shr64(ReadMsr(0x8b), 32); //Get the current microcode revision loaded.
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindMicrocodeOfStepping
+//
+// Description: Search the microcode in the firmware for the cpu signature
+// or earlier steping.
+//
+// Input:
+// UINT8 *Mcode - Address of Mcode Header.
+// UINT8 *End - Mcode End.
+// UINT32 CpuSignature - Signature of CPU to find.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *FindMicrocodeOfStepping(UINT8 *Mcode, UINT8 *End, UINT32 CpuSignature)
+{
+ UINT8 *ptr;
+ for(ptr = Mcode; ptr < End; ptr += MICROCODE_ALIGN_SIZE(ptr)) {
+ MICROCODE_HEADER* uC = (MICROCODE_HEADER*)ptr;
+
+ if (*(UINT32*)ptr == 0xffffffff || *(UINT32*)ptr == 0) return 0;
+ if (uC->CpuSignature == CpuSignature) return ptr;
+
+ if (uC->TotalSize > (uC->DataSize + 48)) { //Extended signature count.
+ MICROCODE_EXT_PROC_SIG_TABLE *SigTable = (MICROCODE_EXT_PROC_SIG_TABLE*)(ptr + uC->DataSize + 48);
+ UINT32 ExtSigCount = SigTable->Count;
+ UINT8 i;
+
+ for (i = 0; i < ExtSigCount; ++i) {
+ if (SigTable->ProcSig[i].CpuSignature == CpuSignature) return ptr;
+ }
+ }
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadMicrocode
+//
+// Description: Load the microcode onto the CPU.
+//
+// Input:
+// VOID *Mcode - Address of Microcode Header.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LoadMicrocode(IN VOID *Mcode)
+{
+ WriteMsr(0x79, (UINT64)(UINTN)Mcode + 48); //IA32_BIOS_UPDT_TRIG
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadMicrocodeEachCpu
+//
+// Description: Load the microcode on each CPU.
+//
+// Input: EFI_SMI_CPU_SAVE_STATE *CpuSaveState
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LoadMicrocodeEachCpu(IN VOID *Mcode)
+{
+ UINT8 i;
+ //In for loop, BSP CPU will return error and continue for all APs.
+ for (i = 0; i < pSmst->NumberOfCpus; ++i) {
+ pSmst->SmmStartupThisAp(LoadMicrocode, i, Mcode);
+ }
+ LoadMicrocode(Mcode);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PresenceTest
+//
+// Description: Execute the presence test function for int 15h.
+//
+// Input: SMI_UC_DWORD_REGS *Regs
+//
+// Output: VOID
+//
+// Notes:
+//
+// Input:
+// AX - D042h
+// BL - 00h i.e., PRESCENCE_TEST
+//
+// Output:
+// CF NC - All return values are valid
+// CY - Failure, AH contains status.
+//
+// AH Return code
+// AL Additional OEM information
+// EBX Part one of the signature 'INTE'.
+// ECX Part two of the signature 'LPEP'.
+// EDX Version number of the BIOS update loader
+// SI Number of update blocks system can record in NVRAM (1 based).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PresenceTest(SMI_UC_DWORD_REGS *Regs)
+{
+ Regs->EBX = 'INTE'; //Part 1 of the Signature
+ Regs->ECX = 'LPEP'; //Part 2 of the Signature.
+ Regs->EDX = UC_LOADER_VERSION;
+
+ *(UINT16*)&Regs->ESI = gNumMcodeBlks; //Number of blocks.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateControl
+//
+// Description: Execute the update control for int 15h.
+//
+// Input: SMI_UC_DWORD_REGS *Regs
+//
+// Output: VOID
+//
+// Notes:
+// Input:
+// AX - D042h
+// BL - 02h i.e., UPDATE_CONTROL
+// BH - Task
+// 1 - Enable the update loading at initialization time.
+// 2 - Determine the current state of the update control without changing its status.
+//
+// Output:
+// AH Return code
+// AL Additional OEM information
+// BL Update status Disable or Enable.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UpdateControl(SMI_UC_DWORD_REGS *Regs)
+{
+
+ //This is checking for a task of 0 or > 2. This is not in the specification, but in Intel code.
+ if ((Regs->EBX & 0xff00) == 0 || (Regs->EBX & 0x0ff00) > 0x200) { //Check BH
+ // Indicate we cannot determinate the Enable/Disable status via CMOS
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_READ_FAILURE;
+ }
+
+ Regs->EBX = (Regs->EBX & 0xffffff00) | UC_INT15_ENABLE; // Always enabled.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadUpdateData
+//
+// Description: Read microcode using int15h.
+//
+// Input: SMI_UC_DWORD_REGS *Regs
+//
+// Output: VOID
+//
+// Notes:
+//
+// Input:
+// AX - D042h
+// BL - 03h i.e., READ_UPDATE_DATA
+// ES:DI - Real Mode Pointer to the Intel Update structure.
+// SS:SP - Stack pointer (32K minimum)
+// SI - Update number, the index number of the update block to be read.
+// This number is zero based and must be less than the update
+// count returned from the prescence test function.
+//
+// Output:
+// AH Return code
+// AL Additional OEM information
+// BL Update status Disable or Enable.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ReadUpdateData(SMI_UC_DWORD_REGS *Regs)
+{
+ EFI_STATUS Status;
+ UINT16 Index = (UINT16)Regs->ESI;
+ UINT8 *UpdateBuffer;
+ MICROCODE_HEADER *Header;
+
+ if (Index >= gNumMcodeBlks) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_UPDATE_NUM_INVALID;
+ return;
+ }
+
+ if (gMcodeBlkMap[Index].Type == MCODE_BLK_CONT) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_NOT_EMPTY;
+ return;
+ }
+
+ UpdateBuffer = (UINT8*)(UINTN)(((UINT16)Regs->ES << 4) + (UINT16)Regs->EDI);
+
+ Status = CheckAddressRange (UpdateBuffer, MICROCODE_BLOCK_SIZE);
+ if(EFI_ERROR(Status)) return;
+
+ if (gMcodeBlkMap[Index].Type == MCODE_BLK_EMPTY) {
+ MemSet(UpdateBuffer, MICROCODE_BLOCK_SIZE, 0xff);
+ return;
+ }
+
+ Header = (MICROCODE_HEADER *)gMcodeBlkMap[Index].Addr;
+
+ MemCpy(UpdateBuffer, Header, MICROCODE_SIZE(Header));
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////
+
+static UINT8 *gFlashBlk; //Pointer to current flash block to write.
+static UINT8 *gFlashBuffer; //Pointer to beginning of buffer.
+static UINT8 *gFlashBufferPos; //Pointer to current posisiton.
+static UINT32 gFlashBufferUsed; //Number of bytes used in the buffer.
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlushBufferToFlash
+//
+// Description: Helper function to write the buffer to the flash and reset the buffer.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FlushBufferToFlash()
+{
+ FwhErase((UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ FwhWrite(gFlashBuffer, (UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ gFlashBlk += FLASH_BLOCK_SIZE;
+ gFlashBufferPos = gFlashBuffer;
+ gFlashBufferUsed = 0;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeFlashBuffer
+//
+// Description: Initialize the flash buffer before using.
+//
+// Input:
+// IN UINT8* FirstFlashBlk - Address of first block to flash.
+// IN UINT8* FlashBuffer - Flash Buffer.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitializeFlashBuffer(IN UINT8* FirstFlashBlk, IN UINT8 *FlashBuffer)
+{
+ gFlashBlk = FirstFlashBlk;
+ gFlashBuffer = FlashBuffer;
+ gFlashBufferPos = gFlashBuffer;
+ gFlashBufferUsed = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyToFlashBuffer
+//
+// Description: Copy data to the buffer. When the buffer is full, write to the flash,
+// and continues to copy data.
+//
+// Input:
+// IN UINT8 Data - Start of data to write.
+// IN UINT32 Size - Amount to Write.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CopyToFlashBuffer(IN UINT8 *Data, IN UINT32 Size)
+{
+ while (Size) {
+ if (gFlashBufferUsed + Size <= FLASH_BLOCK_SIZE) {
+ MemCpy(gFlashBufferPos, Data, Size);
+
+ gFlashBufferPos += Size;
+ gFlashBufferUsed += Size;
+
+ if (gFlashBufferUsed == FLASH_BLOCK_SIZE) FlushBufferToFlash();
+ return;
+ }
+
+ MemCpy(gFlashBufferPos, Data, FLASH_BLOCK_SIZE - gFlashBufferUsed);
+ Data += FLASH_BLOCK_SIZE - gFlashBufferUsed;
+ Size -= FLASH_BLOCK_SIZE - gFlashBufferUsed;
+ FlushBufferToFlash();
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteValueToFlashBuffer
+//
+// Description: Fill part of the buffer with a value. When the buffer is full, write to the flash,
+// and continue to update the beginning of the buffer with a value.
+//
+// Input:
+// IN UINT8 Value - Value to write.
+// IN UINT32 Size - Amount to Write.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteValueToFlashBuffer(IN UINT8 Value, IN UINT32 Size)
+{
+
+ while (Size) {
+ if (gFlashBufferUsed + Size <= FLASH_BLOCK_SIZE) {
+ MemSet(gFlashBufferPos, Size, Value);
+
+ gFlashBufferPos += Size;
+ gFlashBufferUsed += Size;
+
+ if (gFlashBufferUsed == FLASH_BLOCK_SIZE) FlushBufferToFlash();
+ return;
+ }
+
+ MemSet(gFlashBufferPos, FLASH_BLOCK_SIZE - gFlashBufferUsed, Value);
+ Size -= FLASH_BLOCK_SIZE - gFlashBufferUsed;
+ FlushBufferToFlash();
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillBufferAndFlush
+//
+// Description: Fill the rest of the buffer of a size of the flash block, then update the flash.
+//
+// Input: IN UINT8 *Data - Pointer to starting of data to write to the flash.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FillFlashBufferAndFlush(IN UINT8 *Data)
+{
+ if (gFlashBufferUsed != 0) {
+ MemCpy(gFlashBufferPos, Data, FLASH_BLOCK_SIZE - gFlashBufferUsed);
+ FwhErase((UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ FwhWrite(gFlashBuffer, (UINTN)gFlashBlk, FLASH_BLOCK_SIZE);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMI_UC_DWORD_REGS
+//
+// Description: Write microcode to flash and load microcode into each CPU.
+//
+// Input: EFI_SMI_CPU_SAVE_STATE *Regs
+//
+// Output: VOID
+//
+// Input:
+// AX - D042h
+// BL - 01h i.e., WRITE_UPDATE_DATA
+// ES:DI - Real Mode Pointer to the Intel Update structure.
+// CX - Scratch Pad1 (Real Mode Scratch segment 64K in length)
+// DX - Scratch Pad2 (Real Mode Scratch segment 64K in length)
+// SI - Scratch Pad3 (Real Mode Scratch segment 64K in length)
+// SS:SP - Stack pointer (32K minimum)
+//
+// Output:
+// CF NC - All return values are valid
+// CY - Failure, AH contains status.
+//
+// AH Return code
+// AL Additional OEM information
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteUpdateData(SMI_UC_DWORD_REGS *Regs)
+{
+ EFI_STATUS Status;
+ UINT8 *NewMcode = (UINT8*)(UINTN)((Regs->ES << 4) + (Regs->EDI & 0xFFFF));
+ MICROCODE_HEADER *Header = (MICROCODE_HEADER*)NewMcode;
+ INT32 NewMcodeAlignSize = MICROCODE_ALIGN_SIZE(NewMcode);
+ INT32 NewMcodeSize = MICROCODE_SIZE(NewMcode);
+ BOOLEAN Compact = FALSE;
+
+ UINT8 *OldMcode;
+ INT32 OldMcodeAlignSize;
+ UINT8 *BlkStart;
+ UINT8 *McodeUpdateStart;
+ UINT8 *Buffer;
+
+ Status = CheckAddressRange(NewMcode, NewMcodeAlignSize);
+ if(EFI_ERROR(Status)) return;
+
+ if (!IsValidHeader(Header)) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_INVALID_HEADER;
+ return;
+ }
+
+ if (!IsValidChecksum(NewMcode, NewMcodeSize)) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_INVALID_HEADER_CS;
+ return;
+ }
+
+ //Only update if microcode is for the installed CPU.
+ if (Header->CpuSignature != gCpuSignature || !(Header->Flags & (1<<gCpuFlag))) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_CPU_NOT_PRESENT;
+ return;
+ }
+
+ //Only update a different revision.
+ if (Header->UpdateRevision == gUcRevision) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_INVALID_REVISION;
+ return;
+ }
+
+ //If no microcode installed, then the revision is 0.
+ if (gUcRevision != 0) { //Quick check.
+ if(FindMicrocodeOfStepping(gMcodeFlashStartUpdate,
+ gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate,
+ gCpuSignature
+ ) != NULL) {
+ Compact = TRUE; //Remove old version.
+ }
+ }
+ if (gFirstEmptyBlk == 0xffff || NewMcodeAlignSize >
+ (gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate - gMcodeBlkMap[gFirstEmptyBlk].Addr)
+ ) Compact = TRUE; //Volume is full.
+
+ if (!Compact) {
+ //Append blocks.
+ UINT8 *pEmptyBlk = gMcodeBlkMap[gFirstEmptyBlk].Addr;
+ LoadMicrocodeEachCpu(NewMcode); //Install new microcode.
+
+ //Check to see if new microcode is installed.
+ if (Header->UpdateRevision != GetInstalledMicrocodeRevision()) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_SECURITY_FAILURE;
+ return;
+ }
+
+ FwhWrite(NewMcode, (UINTN)pEmptyBlk, NewMcodeSize); //Currently ignoring status
+
+ InitMcodeBlkMap();
+ return;
+ }
+
+ //***Compact Flash Part***
+
+ //Currently restrict FLASH_BLOCK_SIZE to 64k or smaller
+ if (FLASH_BLOCK_SIZE > 64 * 1024) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_NOT_IMPLEMENTED;
+ }
+
+ //Set up Buffer.
+ Buffer = (UINT8*)(UINTN)((UINT16)Regs->ECX << 4);
+
+ Status = CheckAddressRange(Buffer, FLASH_BLOCK_SIZE);
+ if(EFI_ERROR(Status)) return;
+
+ //Find existing microcode of same revision.
+ McodeUpdateStart = gFirstEmptyBlk == 0xffff ?
+ gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate : gMcodeBlkMap[gFirstEmptyBlk].Addr;
+
+ OldMcode = FindMicrocodeOfStepping(
+ gMcodeFlashStartUpdate,
+ McodeUpdateStart,
+ gCpuSignature
+ );
+
+ //Old Microcode not available to remove?
+ if (!OldMcode) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_STORAGE_FULL;
+ return;
+ }
+ OldMcodeAlignSize = MICROCODE_ALIGN_SIZE(OldMcode);;
+
+ //Check to see if space big enough for new microcode.
+ if ((gMcodeFlashStartUpdate + gMcodeFlashSizeUpdate - McodeUpdateStart + OldMcodeAlignSize) < NewMcodeAlignSize) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_STORAGE_FULL;
+ return;
+ }
+
+ //Load new microcode, if can't load exit.
+ LoadMicrocodeEachCpu(NewMcode); //Install new microcode.
+ if (Header->UpdateRevision != GetInstalledMicrocodeRevision()) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_SECURITY_FAILURE;
+ return;
+ }
+
+ //Start compacting at block with Old Microcode to remove.
+ BlkStart = (UINT8*)((UINTN)OldMcode & ~(FLASH_BLOCK_SIZE - 1)); //Must start at block boundary.
+
+ //Note: When Buffer is full, it will flush to flash.
+ InitializeFlashBuffer(BlkStart, Buffer);
+ CopyToFlashBuffer(BlkStart, (UINT32)(OldMcode - BlkStart)); //Copy before old microcode.
+
+ CopyToFlashBuffer(OldMcode + OldMcodeAlignSize, (UINT32)(McodeUpdateStart - (OldMcode + OldMcodeAlignSize))); //Copy after old microcode.
+
+ CopyToFlashBuffer(NewMcode, NewMcodeSize); //Copy new microcode.
+
+ WriteValueToFlashBuffer(0xff, NewMcodeAlignSize - NewMcodeSize); //Fill block space after microcode.
+
+ if (NewMcodeAlignSize < OldMcodeAlignSize) {
+ WriteValueToFlashBuffer(0xff, OldMcodeAlignSize - NewMcodeAlignSize); //Write 0xff over reclaimed space. Polarity?
+ } else {
+ McodeUpdateStart += NewMcodeAlignSize - OldMcodeAlignSize;
+ }
+ FillFlashBufferAndFlush(McodeUpdateStart);
+
+ InitMcodeBlkMap();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MicrocodeUpdateCallback
+//
+// Description: This notification function is called when an SMM Mode
+// is invoked through SMI. This may happen during RT,
+// so it must be RT safe.
+// Interrupt 15h, function D042h is processed here.
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+//
+// Output: Status code returned to function D042h caller.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID MicrocodeUpdateCallback (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ EFI_STATUS Status;
+ SMI_UC_DWORD_REGS *Regs;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1;
+ UINT8 Function;
+ UINTN i;
+
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+ Regs = (SMI_UC_DWORD_REGS*)(UINTN)(pSmst->CpuSaveState[Cpu].Ia32SaveState.ESI);
+
+ Status = CheckAddressRange((UINT8*)Regs, sizeof(SMI_UC_DWORD_REGS));
+ if(EFI_ERROR(Status)) return;
+
+ if ((UINT16)Regs->EAX != 0xD042) return;
+
+ Function = (UINT8)Regs->EBX; //BL
+
+ //Initialize return as successful.
+ Regs->EFLAGS &= ~CARRY_FLAG;
+ Regs->EAX &= 0xffff0000;
+
+ if (Function >= MAX_MICROCODE_UPDATE_FUNCTIONS) {
+ Regs->EFLAGS |= CARRY_FLAG;
+ *(UINT16*)&Regs->EAX = UC_NOT_IMPLEMENTED;
+ return;
+ }
+
+ MicrocodeUpdate[Function](Regs);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: This function is called from the InitSmmHandler if driver is in SMM.
+//
+// Input: ImageHandle - Pointer to the loaded image protocol for this driver
+// SystemTable - Pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ SMM_HOB *SmmHob;
+ EFI_GUID SmmHobGuid = SMM_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ BOOLEAN IsInit = InitMicrocodeVariables();
+ if (!IsInit) return EFI_UNSUPPORTED;
+
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+ ASSERT_EFI_ERROR(Status);
+
+ SmmHob = (SMM_HOB*)GetEfiConfigurationTable(pST, &HobListGuid);
+ if (SmmHob == NULL) return EFI_NOT_FOUND;
+
+ Status = FindNextHobByGuid(&SmmHobGuid,(VOID**)&SmmHob);
+ if (EFI_ERROR(Status)) return Status;
+
+ gSmmHob = *SmmHob;
+
+ SwContext.SwSmiInputValue = INT15_D042_SWSMI;
+
+ Status = pSwDispatch->Register(pSwDispatch, MicrocodeUpdateCallback, &SwContext, &Handle);
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeMicrocodeSmm
+//
+// Description: This function registers the INT15 D042 SW SMI handler
+// This is the driver entry pOoint.
+//
+// Input: ImageHandle - Pointer to the loaded image protocol for this driver
+// SystemTable - Pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitializeMicrocodeSmm(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif
new file mode 100644
index 0000000..8a965ea
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "MicrocodeUpdate"
+ category = ModulePart
+ LocalRoot = "Core\CPU\MicrocodeUpdate\"
+ RefName = "MicrocodeUpdate"
+[files]
+"MicrocodeUpdate.sdl"
+"MicrocodeUpdate.mak"
+"MicrocodeUpdate.c"
+"MicrocodeUpdate.h"
+"MicrocodeUpdate.dxs"
+"FwhFvb.c"
+<endComponent>
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs
new file mode 100644
index 0000000..f6a5ffa
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.dxs
@@ -0,0 +1,48 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.dxs 1 2/07/12 3:59a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:59a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.dxs $
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//**********************************************************************
+
+#include <Protocol\SmmSwDispatch.h>
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h
new file mode 100644
index 0000000..73b5dea
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.h
@@ -0,0 +1,133 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.h 1 2/07/12 3:59a Davidhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/12 3:59a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.h $
+//
+// 1 2/07/12 3:59a Davidhsieh
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MicrocodeUpdate.h
+//
+// Description: Header file for Microcode Update SMI handler.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _MICROCODE_UPDATE_H_
+#define _MICROCODE_UPDATE_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//#define SIG_PART_ONE 0x0494e5445 // 'INTE'
+//#define SIG_PART_TWO 0x04c504550 // 'LPEP'
+
+
+#define CARRY_FLAG 1
+
+#define UC_LOADER_VERSION 1
+
+#define UC_HEADER_VERSION 1
+#define UC_LOADER_REVISION 1
+
+#define UC_INT15_ENABLE 0x01
+
+#define UC_PRESCENCE_TEST 0
+#define UC_WRITE_UPDATE_DATA 1
+#define UC_UPDATE_CONTROL 2
+#define UC_READ_UPDATE_DATA 3
+
+#define UC_SUCCESS 0x0000
+#define UC_NOT_IMPLEMENTED 0x8600
+#define UC_ERASE_FAILURE 0x9000
+#define UC_WRITE_FAILURE 0x9100
+#define UC_READ_FAILURE 0x9200
+#define UC_STORAGE_FULL 0x9300
+#define UC_CPU_NOT_PRESENT 0x9400
+#define UC_INVALID_HEADER 0x9500
+#define UC_INVALID_HEADER_CS 0x9600
+#define UC_SECURITY_FAILURE 0x9700
+#define UC_INVALID_REVISION 0x9800
+#define UC_UPDATE_NUM_INVALID 0x9900
+#define UC_NOT_EMPTY 0x9a00
+
+typedef struct {
+ UINT32 EAX;
+ UINT32 EBX;
+ UINT32 ECX;
+ UINT32 EDX;
+ UINT32 ESI;
+ UINT32 EDI;
+ UINT32 EFLAGS;
+ UINT16 ES;
+ UINT16 CS;
+ UINT16 SS;
+ UINT16 DS;
+ UINT16 FS;
+ UINT16 GS;
+ UINT32 EBP;
+} SMI_UC_DWORD_REGS;
+
+VOID PresenceTest(SMI_UC_DWORD_REGS *Regs);
+VOID WriteUpdateData(SMI_UC_DWORD_REGS *Regs);
+VOID UpdateControl(SMI_UC_DWORD_REGS *Regs);
+VOID ReadUpdateData(SMI_UC_DWORD_REGS *Regs);
+
+EFI_STATUS FwhErase(
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+);
+
+EFI_STATUS FwhWrite(
+ IN UINT8 *Buffer,
+ IN UINTN Address,
+ IN UINTN NumberOfBytes
+);
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1987-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak
new file mode 100644
index 0000000..160baf9
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.mak
@@ -0,0 +1,58 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.mak 1 2/07/12 3:59a Davidhsieh $
+#
+# $Revision: 1 $
+#
+# $Date: 2/07/12 3:59a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MicrocodeUpdate/MicrocodeUpdate.mak $
+#
+# 1 2/07/12 3:59a Davidhsieh
+#
+#************************************************************************//
+
+all : MicrocodeUpdate
+
+MicrocodeUpdate: $(BUILD_DIR)\MicrocodeUpdate.mak MicrocodeUpdateBin
+
+$(BUILD_DIR)\MicrocodeUpdate.mak : $(MICROCODEUPDATE_PATH)\MicrocodeUpdate.cif $(MICROCODEUPDATE_PATH)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(MICROCODEUPDATE_PATH)\MicrocodeUpdate.cif $(CIF2MAK_DEFAULTS)
+
+MicrocodeUpdateBin : $(AMIDXELIB) $(FLASHLIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\MicrocodeUpdate.mak all\
+ GUID=F3331DE6-4A55-44e4-B767-7453F7A1A021\
+ ENTRY_POINT=InitializeMicrocodeSmm\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1987-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl
new file mode 100644
index 0000000..2acaf0d
--- /dev/null
+++ b/Core/CPU/MicrocodeUpdate/MicrocodeUpdate.sdl
@@ -0,0 +1,32 @@
+TOKEN
+ Name = "MicrocodeUpdate_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Microcode Update support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+ Token = "Microcode_SUPPORT" "=" "1"
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "MICROCODEUPDATE_PATH"
+End
+
+MODULE
+ Help = "Includes MicorcodeUpdate.mak to Project"
+ File = "MicrocodeUpdate.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MicrocodeUpdate.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = " "
+ Parent = "$(BUILD_DIR)\MicrocodeUpdate.ffs"
+ Token = "AMI_DEBUGGER_SUPPORT" "=" "1"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/CPU/ResetVector.asm b/Core/CPU/ResetVector.asm
new file mode 100644
index 0000000..dd134ad
--- /dev/null
+++ b/Core/CPU/ResetVector.asm
@@ -0,0 +1,99 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/ResetVector.asm 3 6/15/12 3:27a Davidhsieh $
+;
+; $Revision: 3 $
+;
+; $Date: 6/15/12 3:27a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/ResetVector.asm $
+;
+; 3 6/15/12 3:27a Davidhsieh
+; [TAG] None
+; [Category] New Feature
+; [Description] For FIT module support
+;
+; 2 3/16/12 3:11a Davidhsieh
+; Setup items create for CPU RC policy
+;
+; 1 2/07/12 3:58a Davidhsieh
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: ResetVector.asm
+;
+; Description:
+; Reset Vector. Fixup will update code to jump to EntryPoint of Startup32.asm.
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+.586P
+.XMM
+.model tiny
+
+include token.equ
+
+RESET_SEG SEGMENT PARA PUBLIC 'CODE' USE16
+ org 0 ;offset 0xFFFFFFC0h
+ifndef MKF_INTEL_FIT_TABLE_ADDRESS
+ dd 0EEEEEEEEh
+ dd 0EEEEEEEEh
+else
+ dd MKF_INTEL_FIT_TABLE_ADDRESS ;Reserve
+ dd 0h
+endif
+ org 10h ;offset 0xFFFFFFD0h
+ mov di, "AP" ;Actual AP startup (SIPI) is hardcoded to jump here.
+ jmp ApStartup
+
+ org 20h ;offset 0xFFFFFFE0
+ dd 87654321h ;Fixed up by tool to point to PEI CORE Entry.
+
+ org 30h ;offset 0xFFFFFFF0
+ nop ;Place holder to maintain byte sequence for build tool fix-ups.
+ nop ;Place holder to maintain byte sequence for build tool fix-ups.
+ApStartup:
+ ; Use machine code directly in case of the assembler optimization
+ ; SEC entry point relatvie address will be fixed up by some build tool.
+ ;
+ db 0e9h ;jmp Rel16
+ dw -3 ;SecFixup utility changes to point to flat32.asm Entry Point.
+
+ org 3ch ;offset 0xFFFFFFFC
+ dd 012345678h ;Fixed up by GenFvImage to Boot Firmware Volume Base.
+RESET_SEG ENDS
+END
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
diff --git a/Core/CPU/SecFixup.exe b/Core/CPU/SecFixup.exe
new file mode 100644
index 0000000..950343c
--- /dev/null
+++ b/Core/CPU/SecFixup.exe
Binary files differ
diff --git a/Core/CPU/Startup32.asm b/Core/CPU/Startup32.asm
new file mode 100644
index 0000000..9728a39
--- /dev/null
+++ b/Core/CPU/Startup32.asm
@@ -0,0 +1,618 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/Startup32.asm 3 11/28/12 1:11a Davidhsieh $
+;
+; $Revision: 3 $
+;
+; $Date: 11/28/12 1:11a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/Startup32.asm $
+;
+; 3 11/28/12 1:11a Davidhsieh
+; [TAG] EIP107763
+; [Category] Bug Fix
+; [Severity] Important
+; [Symptom] UEFI SCT 2.3.1 Floating Point ABI Test fail
+; [RootCause] According to UEFI 2.3.1 errata C, Floating-point control
+; word must be initialized to 0x037F
+; [Solution] Use 0x37f for Floating-point control word
+;
+; 2 3/09/12 2:13a Davidhsieh
+; Create BIST data
+;
+; 1 2/07/12 3:58a Davidhsieh
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: StartUp32.asm
+;
+; Description: Switch CPU to protected mode, INIT CAR and setup stack.
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+.586P
+.XMM
+.model small
+
+include token.equ
+include cpu.equ
+
+ifndef MKF_PI_SPECIFICATION_VERSION
+MKF_PI_SPECIFICATION_VERSION EQU 0
+endif
+
+ifndef MKF_CSM_SUPPORT
+MKF_CSM_SUPPORT EQU 0
+endif
+
+ifndef MKF_MPDTable_CREATED
+MKF_MPDTable_CREATED EQU 0
+endif
+
+ifndef MKF_PACK_MICROCODE
+MKF_PACK_MICROCODE EQU 0
+endif
+
+ifndef MKF_MICROCODE_SPLIT_BB_UPDATE
+MKF_MICROCODE_SPLIT_BB_UPDATE EQU 0
+endif
+
+PhysMask equ (NOT (MKF_CAR_TOTAL_SIZE - 1)) ;8k stack
+
+WriteBack equ 6
+ValidMask equ 1 SHL 11
+
+IA32_MISC_ENABLE EQU 1A0h
+FAST_STRING_ENABLE_BIT EQU 01h
+
+MTRR_PHYS_BASE_0 EQU 0200h
+MTRR_PHYS_MASK_0 EQU 0201h
+MTRR_PHYS_BASE_1 EQU 0202h
+MTRR_PHYS_MASK_1 EQU 0203h
+MTRR_PHYS_BASE_2 EQU 0204h
+MTRR_PHYS_MASK_2 EQU 0205h
+MTRR_PHYS_BASE_3 EQU 0206h
+MTRR_PHYS_MASK_3 EQU 0207h
+MTRR_PHYS_BASE_4 EQU 0208h
+MTRR_PHYS_MASK_4 EQU 0209h
+MTRR_PHYS_BASE_5 EQU 020Ah
+MTRR_PHYS_MASK_5 EQU 020Bh
+MTRR_PHYS_BASE_6 EQU 020Ch
+MTRR_PHYS_MASK_6 EQU 020Dh
+MTRR_PHYS_BASE_7 EQU 020Eh
+MTRR_PHYS_MASK_7 EQU 020Fh
+MTRR_FIX_64K_00000 EQU 0250h
+MTRR_FIX_16K_80000 EQU 0258h
+MTRR_FIX_16K_A0000 EQU 0259h
+MTRR_FIX_4K_C0000 EQU 0268h
+MTRR_FIX_4K_C8000 EQU 0269h
+MTRR_FIX_4K_D0000 EQU 026Ah
+MTRR_FIX_4K_D8000 EQU 026Bh
+MTRR_FIX_4K_E0000 EQU 026Ch
+MTRR_FIX_4K_E8000 EQU 026Dh
+MTRR_FIX_4K_F0000 EQU 026Eh
+MTRR_FIX_4K_F8000 EQU 026Fh
+MTRR_DEF_TYPE EQU 02FFh
+
+EFI_PEI_PPI_DESCRIPTOR_PPI EQU 00000010h
+EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST EQU 80000000h
+
+FV_LENGTH EQU (16 + 16)
+FV_SIGNATURE EQU (FV_LENGTH + 8)
+FV_HDR_LENGTH EQU (FV_SIGNATURE + 4 + 4)
+
+FFS_LENGTH EQU (16 + 2 + 1 + 1)
+FFS_HDR_LENGTH EQU (FFS_LENGTH + 3 + 1)
+
+uCODE_CPU_SIGNATURE EQU 12
+uCODE_CPU_FLAGS EQU 24
+uCODE_DATA_SIZE EQU 28
+uCODE_TOTAL_SIZE EQU 32
+
+; Externs
+EXTERN SECCoreAtPowerOn:NEAR32
+PUBLIC SECCoreAtPowerOnEnd
+
+;STARTUP_SEG SEGMENT USE32
+;----------------------------------------------------------------------------
+; STARTUP_SEG S E G M E N T STARTS
+;----------------------------------------------------------------------------
+STARTUP_SEG SEGMENT PARA PUBLIC 'CODE' USE32
+
+MICOCODE_FFS_GUID label dword
+ dd 17088572h
+ dw 377Fh
+ dw 44efh
+ db 8Fh,4Eh,0B0h,9Fh,0FFh,46h,0A0h,70h
+
+AMI_BIST_GUID label dword
+ dd 0A7E2CE72h
+ dw 0DC32h
+ dw 04BC0h
+ db 9Eh, 35h, 0FEh, 0B3h, 0Ah, 0E5h, 0CCh, 47h
+
+SEC_CORE_PPI_DESC STRUCT
+ BIST_FLAGS dd ?
+ BIST_GUID dd ?
+ BIST_PPI dd ?
+SEC_CORE_PPI_DESC ends
+
+
+SecCorePpiDesc SEC_CORE_PPI_DESC < \
+ EFI_PEI_PPI_DESCRIPTOR_PPI + EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \
+ offset AMI_BIST_GUID, \
+ 0 \
+>
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+; Procedure: FindMicrocode
+;
+; Description: This routine searches the file volume for a microcode update
+; and returns the address if found.
+;
+; Input: None
+;
+; Output: eax = Pointer to microcode. 0 if not found.
+;
+; Notes:
+; This routine can not use stack. It can be called from rom or ram.
+; If called from rom, a hard coded stack must be exist in rom.
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+IF MKF_Microcode_SUPPORT
+public FindMicrocode
+extern FindMicrocodeEnd:NEAR32
+FindMicrocode proc
+IF MKF_MICROCODE_SPLIT_BB_UPDATE
+ mov ebx, MKF_FV_MICROCODE_UPDATE_BASE
+FindMicrocodeFv:
+ELSE
+ mov ebx, MKF_FV_MICROCODE_BASE
+ENDIF
+ cmp dword ptr [ebx + FV_SIGNATURE], 'HVF_'
+ jne Microcode_Not_Found ;Corrupt FV?
+
+ mov edx, ebx
+ mov eax, [ebx + FV_HDR_LENGTH]
+ and eax, 0ffffh ;Get 16 bit FV header length
+ add ebx, eax ;ebx = start of FFS
+ jc Microcode_Not_Found ;Corrupt FV?
+ add edx, [edx + FV_LENGTH]
+ jz @f ;zf if Boot Block
+ jc Microcode_Not_Found ;Corrupt FV?
+@@:
+ dec edx ;edx = End of FFS
+;---Find File ---
+;ebx = Start of FFS
+;edx = End of FFS
+Get_Next_File:
+ cmp dword ptr [ebx], -1 ;Is in end of files, but not firmware volume.
+ je File_not_found
+ mov ecx, 4
+ mov esi, ebx
+ mov edi, offset MICOCODE_FFS_GUID
+ ;compare file guid
+ repe cmpsd
+ je Found_File
+;---get next file--
+ ;get file length and add to ebx
+ mov eax, [ebx + FFS_LENGTH]
+ and eax, 0ffffffh ;eax = File length (24 bits)
+ add ebx, eax ;next file
+ ;align file
+ add ebx, 7
+ jc Microcode_Not_Found ;Check for wrap-around if bad data.
+ and ebx, not 7
+
+ cmp ebx, edx ;Is end of firmware volume?
+ jb Get_Next_file
+File_not_found:
+ jmp Microcode_Not_Found
+;---Found File---
+Found_File:
+;ebx = Start of Microcode FFS
+;edx = End of FFS + 1
+
+;---Search micocode for match.---
+ mov edi, ebx
+
+ mov eax, [ebx + FFS_LENGTH]
+ and eax, 0ffffffh ;eax = File length (24 bits)
+ add edi, eax ;edi = end of file
+ jc Microcode_Not_Found ;Check for wrap-around if bad data.
+
+IF MKF_MPDTable_CREATED
+ movzx eax, word ptr [edi-2] ;eax = MPDT length
+ sub edi, eax ;edi = end of microcodes.
+ENDIF
+
+ add ebx, FFS_HDR_LENGTH
+ jc Microcode_Not_Found ;Check for wrap-around if bad data.
+
+ mov esi, ebx
+
+ mov eax, 1
+ cpuid
+ mov ebx, eax ;ebx = CPU signature
+
+ mov ecx, 17h
+ rdmsr ;read CPUS flags
+
+ shr edx, 18
+ and dl, 7 ;dl = CPU FLAG
+ mov cl, dl
+ mov dl, 1
+ shl dl, cl ;dl = bit set for CPU flag
+
+ xchg ebx, esi ;ebx = ptr, esi = signature
+Next_Microcode:
+ cmp ebx, edi ;Check to see if microcode at end of FFS File.
+ jae Microcode_Not_Found
+
+ cmp dword ptr [ebx], 1 ;Check if correct header revision
+ jne Microcode_Not_Found
+
+ mov ecx, 2048 ;total size if data size in field = 0.
+ cmp dword ptr [ebx + uCODE_DATA_SIZE], 0
+ jz @f
+ mov ecx, [ebx + uCODE_TOTAL_SIZE] ;Get total size.
+@@:
+
+ cmp esi, [ebx + uCODE_CPU_SIGNATURE]
+ jne Check_Ext_Sig
+
+ mov eax, ebx ;Store uC addr in eax, so if jnz succeeds.
+ test dl, [ebx + uCODE_CPU_FLAGS] ;uC flags match?
+ jnz Exit_Find_Microcode
+
+Check_Ext_Sig:
+ mov ebp, [ebx + uCODE_TOTAL_SIZE] ;Get total size.
+ mov eax, [ebx + uCODE_DATA_SIZE] ;Get Data Size
+ add eax, 48
+ cmp ebp, eax
+ jbe Find_Next_Microcode ;No extended signature.
+
+ mov ecx, [ebx + eax] ;Get extended signature.
+ cmp ecx, 20
+ jae Microcode_Not_Found ;Corrupt?
+ lea ebp, [ebx + eax + 20] ;First Proc Signature.
+
+@@:
+ cmp [ebp], esi ;Check Signature
+ jne Next_Ext_Sig
+
+ mov eax, ebx
+ test dl, [ebp + 4] ;Check processor flags
+ jnz Exit_Find_Microcode
+Next_Ext_Sig:
+ add ebp, 12
+ loop @b
+ mov ecx, [ebx + uCODE_TOTAL_SIZE] ;Get total size.
+Find_Next_Microcode:
+ ;align to next block size
+IF MKF_PACK_MICROCODE
+ add ecx, 15
+ and ecx, 0fffffff0h
+ELSE
+ add ecx, MKF_MICROCODE_BLOCK_SIZE - 1
+ and ecx, NOT (MKF_MICROCODE_BLOCK_SIZE - 1)
+ENDIF
+ add ebx, ecx
+ jc Microcode_Not_Found ;Overflow - bad data.
+ jmp Next_Microcode
+
+Microcode_Not_Found:
+IF MKF_MICROCODE_SPLIT_BB_UPDATE
+ cmp ebx, MKF_FV_MICROCODE_BASE
+ jae @f
+ mov ebx, MKF_FV_MICROCODE_BASE
+ jmp FindMicrocodeFv
+@@:
+ENDIF
+ xor eax, eax
+Exit_Find_Microcode:
+ jmp FindMicrocodeEnd
+FindMicrocode endp
+
+ENDIF ;MKF_Microcode_SUPPORT
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: CPU_START
+;
+; Description: Switch CPU to protected mode, INIT CAR and setup stack.
+;
+; Input: None
+;
+; Output: None
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+public _CPU_START
+_CPU_START:
+ ;---16 bit in 32 bit assembler--
+ ;---Some 16-bit and 32-bit assmebly is the same, others are not.---
+ ;---Need to use some machine code.---
+
+ fninit ;Clear any pending Floating point exceptions
+ movd mm0, eax ;Save BIST state in MM0
+
+ cli
+
+if MKF_CSM_SUPPORT EQ -1
+ db 0B8h, 00h, 0F0h ;mov ax, 0F000h
+ db 8Eh, 0D8h ;mov ds, ax
+ db 0BEh, 0F0h, 0FFh ;mov si, 0FFF0h
+ db 80h, 3Ch, 0EAh ;cmp BYTE PTR [si], 0EAh ; Is it warm reset ?
+ jne NotWarmReset ; If not.
+
+ db 0EAh ;DB 0EAh ; Far jump to F000:E05B (legacy BIOS warm reset entry)
+ dw 0E05Bh ;DW 0E05Bh
+ dw 0F000h ;DW 0F000h
+NotWarmReset:
+endif
+
+ ;Switch to protected mode
+ ;lgdt fword ptr cs:[GdtDescriptor] ;Relative to 4G.
+; db 66h,2eh,0fh,1,16h
+; dw offset GdtDescriptor ;<-------Problem------<
+
+ db 66h
+ mov ebx, offset GdtDescriptor
+ ;lgdt fword ptr cs:[bx]
+ db 66h, 2eh,0fh,1,17h
+
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+ ;In 16 bit protected mode
+
+ cld
+ db 0b8h ;mov ax, DATA_SEL
+ dw DATA_SEL
+ db 8eh, 0d8h ;mov ds, ax
+ db 8eh, 0c0h ;mov es, ax
+ db 8eh, 0d0h ;mov ss, ax
+ db 8eh, 0e0h ;mov fs, ax
+ db 8eh, 0e8h ;mov gs, ax
+
+ ;set cs segment
+ ;jmp 10:CHANGE_CS
+ db 66h, 0eah
+ dd CHANGE_CS ;Relative to 4G.
+ dw CODE_SEL
+CHANGE_CS:
+ ;---If Limit CPU ID enabled because of soft reset, disable.
+ mov ecx, 01a0h
+ rdmsr
+ btr eax, 22 ;Reset bit
+ jnc @f ;If already reset, don't write to 1a0.
+ wrmsr
+@@:
+ ;---Change APIC Address---
+ mov ecx, MSR_XAPIC_BASE ; Enable local APIC
+ rdmsr
+ and edx, NOT 0fh ;Mask local APIC address
+ and eax, NOT 0fffff000h ;Mask local APIC address
+ or eax, MKF_LOCAL_APIC_BASE
+ wrmsr
+
+;--------------------------------------------------------------------
+
+ ;In CR4, set OSFXSR bit 9 and OSXMMEXCPT bit 10
+ mov eax, cr4
+ or ax, 1 SHL 9 + 1 SHL 10
+ mov cr4, eax
+
+;---------------------------------------------
+;---------------------------------------------
+;---------------------------------------------
+
+; Invoke the SECCore Init hook for other components to hook functions
+; This also executes referece code.
+ jmp SECCoreAtPowerOn
+SECCoreAtPowerOnEnd::
+
+ ; This stores the BIST for SBSP.
+ ; The PBSPs BIST is stored in MM0. The value will preserved across INIT-SIPI and captured
+ ; in CPU PEI.
+ movd eax, mm0
+ pushd eax ;Bist0
+
+ ;Get Apic ID
+ mov eax, MKF_LOCAL_APIC_BASE + 20h
+ mov ebx, [eax]
+ shr ebx, 24
+ pushd ebx ;ApicId0
+ pushd 1 ;Num BISTS
+
+ mov ebx, esp ;points to AMI_BIST_PPI_STRUCT
+
+ sub esp, size SEC_CORE_PPI_DESC
+ mov esi, offset SecCorePpiDesc
+ mov edi, esp
+ mov ecx, size SEC_CORE_PPI_DESC / 4
+ rep movsd
+
+ mov (SEC_CORE_PPI_DESC PTR [esp]).BIST_PPI, ebx
+ mov ebx, esp
+
+IFDEF EFIx64
+ pushd 37fh
+ELSE
+ pushd 27fh
+ENDIF
+ fldcw word ptr [esp] ;Set FP control word according UEFI
+ add esp, 4
+
+ ; Pass NEM address into the PEI Core
+ push MKF_CAR_BASE_ADDRESS
+
+ ; Dispatch table
+ push ebx
+
+IF MKF_PI_SPECIFICATION_VERSION GE 00010000h
+ ; Initialize EFI_SEC_PEI_HAND_OFF data structure in CAR
+ mov ebx, MKF_CAR_BASE_ADDRESS
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).DataSize, sizeof EFI_SEC_PEI_HAND_OFF
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).Reserved1, 0
+
+ ; Report the Boot Firmware Volume that PEI should search for PEIMS (FV_BB)
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).BootFirmwareVolumeBase, MKF_FV_BB_BASE
+
+ ; Report the Size of the Boot Firmware Volume, in Bytes
+ mov eax, MKF_FV_BB_BASE + 32
+ mov eax, [eax]
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).BootFirmwareVolumeSize, eax
+
+ ; Report the start the CAR Base address and size (based on SDL tokens)
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).TemporaryRamBase, MKF_CAR_BASE_ADDRESS
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).TemporaryRamSize, MKF_CAR_TOTAL_SIZE
+
+ ; Report the starting address of the CAR that PEI Core can use
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).PeiTemporaryRamBase, MKF_CAR_BASE_ADDRESS + sizeof EFI_SEC_PEI_HAND_OFF + EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).PeiTemporaryRamSize, MKF_CAR_TOTAL_SIZE - sizeof EFI_SEC_PEI_HAND_OFF - EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+
+ ; Report the start of the stack and its size (should point into top of CAR region)
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).StackBase, MKF_CAR_BASE_ADDRESS + MKF_CAR_TOTAL_SIZE
+ mov (EFI_SEC_PEI_HAND_OFF ptr [ebx]).StackSize, MKF_CAR_TOTAL_SIZE
+
+ ; In CAR, reserve 8 bytes space before IDT Base Address for a pointer to a pointer
+ ; of the PEI Services Table (EFI_PEI_SERVICES**) which will be initialized in PEI
+
+ ; IDT Base Address = MKF_CAR_BASE_ADDRESS + sizeof EFI_SEC_PEI_HAND_OFF + EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+ ; IDT Size is 0 because it will be initalized in PEI. Here, it is only
+ ; used to reserved 8 bytes space for (EFI_PEI_SERVICES**)
+ sub esp, sizeof IDTR32
+ mov (IDTR32 ptr [esp]).BaseAddress, MKF_CAR_BASE_ADDRESS + sizeof EFI_SEC_PEI_HAND_OFF + EFI_PEI_SERVICES_DOUBLE_POINTER_SIZE
+ mov (IDTR32 ptr [esp]).Limit, 0
+ lidt FWORD PTR [esp]
+ add esp, sizeof IDTR32
+
+ ; Push a pointer to the the EFI_PEI_PPI_DESCRIPTOR AMI_PI_TODO:
+ ;push 0
+
+ ; Push a pointer to the EFI_SEC_PEI_HAND_OFF data structure onto the stack
+ push MKF_CAR_BASE_ADDRESS
+
+ELSE
+ ; Pass stack size into the PEI Core
+ push MKF_CAR_TOTAL_SIZE
+
+ ; Pass BFV into the PEI Core
+ push DWORD PTR ds:[0FFFFFFFCh]
+ENDIF
+
+ ;mov edi, 0FFFFFFE0h
+ call DWORD PTR ds:[0FFFFFFE0h]
+;---Does not return---
+
+align 16
+MTRR_TABLE label byte
+ dw MTRR_DEF_TYPE
+ dw MTRR_PHYS_BASE_0, MTRR_PHYS_MASK_0
+ dw MTRR_PHYS_BASE_1, MTRR_PHYS_MASK_1
+ dw MTRR_PHYS_BASE_2, MTRR_PHYS_MASK_2
+ dw MTRR_PHYS_BASE_3, MTRR_PHYS_MASK_3
+ dw MTRR_PHYS_BASE_4, MTRR_PHYS_MASK_4
+ dw MTRR_PHYS_BASE_5, MTRR_PHYS_MASK_5
+ dw MTRR_PHYS_BASE_6, MTRR_PHYS_MASK_6
+ dw MTRR_PHYS_BASE_7, MTRR_PHYS_MASK_7
+ dw MTRR_FIX_64K_00000
+ dw MTRR_FIX_16K_80000
+ dw MTRR_FIX_16K_A0000
+ dw MTRR_FIX_4K_C0000, MTRR_FIX_4K_C8000
+ dw MTRR_FIX_4K_D0000, MTRR_FIX_4K_D8000
+ dw MTRR_FIX_4K_E0000, MTRR_FIX_4K_E8000
+ dw MTRR_FIX_4K_F0000, MTRR_FIX_4K_F8000
+MTRR_TABLE_END label byte
+
+;----------------------------------------------
+align 16
+GDT_BASE:
+NULL_SEL equ $-GDT_BASE ;NULL Selector 0
+ dd 0, 0
+
+DATA_SEL equ $-GDT_BASE ; Selector 8, Data 0-ffffffff 32 bit
+ dd 0000ffffh
+ dd 00cf9300h
+
+CODE_SEL equ $-GDT_BASE ; Selector 10h, CODE 0-ffffffff 32 bit
+ dd 0000ffffh
+ dd 00cf9b00h
+
+; We only need this because Intel DebugSupport driver
+; (RegisterPeriodicCallback function) assumes that selector 0x20 is valid
+; The funciton sets 0x20 as a code selector in IDT
+;
+; To switch to 16 bit, Selectors SYS16_CODE_SEL and SYS16_DATA_SEL are used.
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x18]
+ dd 0000FFFFh ;0 - f_ffff
+ dd 00cf9300h ;data, expand-up, notwritable, 32-bit
+
+; System code segment descriptor
+SYS_CODE_SEL equ $ - GDT_BASE ; Selector [0x20]
+ dd 0000FFFFh ;0 - f_ffff
+ dd 00cf9b00h ;data, expand-up, writable, 32-bit
+SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]
+ dd 0, 0
+SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]
+ dd 0000FFFFh
+ dd 00cf9300h
+SYS_CODE64_SEL equ $-GDT_BASE ; Selector [0x38]
+ dd 0000FFFFh
+ dd 00af9b00h
+SPARE4_SEL equ $-GDT_BASE ; Selector [0x40]
+ dd 0, 0
+GDT_SIZE equ $-GDT_BASE ;Size of Descriptor Table
+
+GdtDescriptor:
+ dw GDT_SIZE - 1 ; GDT limit
+ dd offset GDT_BASE ; GDT base Relative to 4G.
+
+STARTUP_SEG ENDS
+
+end
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1987-2013, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/CPU/x64/AmiX64Lib.cif b/Core/CPU/x64/AmiX64Lib.cif
new file mode 100644
index 0000000..5070b67
--- /dev/null
+++ b/Core/CPU/x64/AmiX64Lib.cif
@@ -0,0 +1,52 @@
+<component>
+ name = "AmiX64Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\"
+ RefName = "AmiX64Lib"
+[files]
+"AmiX64Lib.sdl"
+"AmiX64Lib.mak"
+"x64CLib.c"
+"x64AsmLib\checkpoint.asm"
+"x64AsmLib\CPULib_CpuID.asm"
+"x64AsmLib\CPULib_DisableInterrupt.asm"
+"x64AsmLib\CPULib_EnableInterrupt.asm"
+"x64AsmLib\CPULib_GetInterruptState.asm"
+"x64AsmLib\CPULIB_GetPageTable.asm"
+"x64AsmLib\CPULib_LoadGdt.asm"
+"x64AsmLib\CPULib_LoadIdt.asm"
+"x64AsmLib\CPULib_LockByteDec.asm"
+"x64AsmLib\CPULib_LockByteInc.asm"
+"x64AsmLib\CPULib_Pause.asm"
+"x64AsmLib\CPULib_SaveGdt.asm"
+"x64AsmLib\CPULib_SaveIdt.asm"
+"x64AsmLib\DisableCacheInCR0.asm"
+"x64AsmLib\EnableCacheInCR0.asm"
+"x64AsmLib\EnableMachineCheck.asm"
+"x64AsmLib\GetCpuTimer.asm"
+"x64AsmLib\GetCsSegment.asm"
+"x64AsmLib\GetPowerOfTwo64.asm"
+"x64AsmLib\HltCpu.asm"
+"x64AsmLib\IoRead16.asm"
+"x64AsmLib\IoRead32.asm"
+"x64AsmLib\IoRead64.asm"
+"x64AsmLib\IoRead8.asm"
+"x64AsmLib\IoWrite16.asm"
+"x64AsmLib\IoWrite32.asm"
+"x64AsmLib\IoWrite64.asm"
+"x64AsmLib\IoWrite8.asm"
+"x64AsmLib\MemCpy.asm"
+"x64AsmLib\MemRead32.asm"
+"x64AsmLib\MemReadWrite32.asm"
+"x64AsmLib\MemSet.asm"
+"x64AsmLib\ReadCr3.asm"
+"x64AsmLib\ReadMsr.asm"
+"x64AsmLib\ReadRtdsc.asm"
+"x64AsmLib\WaitForever.asm"
+"x64AsmLib\WaitForSemaphore.asm"
+"x64AsmLib\WaitUntilZero32.asm"
+"x64AsmLib\WaitUntilZero8.asm"
+"x64AsmLib\WriteCr3.asm"
+"x64AsmLib\WriteMsr.asm"
+"x64AsmLib\MemCpy32.asm"
+<endComponent>
diff --git a/Core/CPU/x64/AmiX64Lib.mak b/Core/CPU/x64/AmiX64Lib.mak
new file mode 100644
index 0000000..e2cd482
--- /dev/null
+++ b/Core/CPU/x64/AmiX64Lib.mak
@@ -0,0 +1,63 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/x64Core/AmiX64Lib.mak 1 10/13/06 8:37p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 10/13/06 8:37p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/x64Core/AmiX64Lib.mak $
+#
+# 1 10/13/06 8:37p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiX64Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+AmiX64Lib : $(BUILD_DIR)\AmiX64Lib.mak AmiX64LibBin
+
+$(BUILD_DIR)\AmiX64Lib.mak : $(AmiX64Lib_DIR)\$(@B).cif $(AmiX64Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AmiX64Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="x64"
+AmiDxeLibBin : $(BUILD_DIR)\AmiX64Lib.lib
+$(BUILD_DIR)\AmiX64Lib.lib : AmiX64Lib
+!ENDIF
+
+AmiX64LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiX64Lib.mak all\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/AmiX64Lib.sdl b/Core/CPU/x64/AmiX64Lib.sdl
new file mode 100644
index 0000000..79b7e36
--- /dev/null
+++ b/Core/CPU/x64/AmiX64Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "AmiX64Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AmiX64Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AmiX64Lib_DIR"
+End
+
+MODULE
+ Help = "Includes AmiX64Lib.mak to Project"
+ File = "AmiX64Lib.mak"
+End
+
diff --git a/Core/CPU/x64/EfiJump.h b/Core/CPU/x64/EfiJump.h
new file mode 100644
index 0000000..61f371f
--- /dev/null
+++ b/Core/CPU/x64/EfiJump.h
@@ -0,0 +1,42 @@
+/*++
+
+Copyright (c) 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiJump.h
+
+Abstract:
+
+ This is the Setjump/Longjump pair for an x64 processor.
+
+--*/
+
+#ifndef _EFI_JUMP_H_
+#define _EFI_JUMP_H_
+
+typedef struct {
+ UINT64 Rbx;
+ UINT64 Rsp;
+ UINT64 Rbp;
+ UINT64 Rdi;
+ UINT64 Rsi;
+ UINT64 R10;
+ UINT64 R11;
+ UINT64 R12;
+ UINT64 R13;
+ UINT64 R14;
+ UINT64 R15;
+ UINT64 Rip;
+ UINT32 MxCsr;
+ UINT8 XmmBuffer[160]; // XMM6-XMM15
+} EFI_JUMP_BUFFER;
+
+#endif
diff --git a/Core/CPU/x64/Foundationx64.cif b/Core/CPU/x64/Foundationx64.cif
new file mode 100644
index 0000000..cb10e7a
--- /dev/null
+++ b/Core/CPU/x64/Foundationx64.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Foundationx64"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\"
+ RefName = "Foundationx64"
+[files]
+"Foundationx64.sdl"
+"Foundationx64.mak"
+"ProcessorAsms.Asm"
+"EfiJump.h"
+"PeCoffLoaderEx.c"
+"PeCoffLoaderEx.h"
+"Processor.c"
+"Processor.h"
+<endComponent>
diff --git a/Core/CPU/x64/Foundationx64.mak b/Core/CPU/x64/Foundationx64.mak
new file mode 100644
index 0000000..488e672
--- /dev/null
+++ b/Core/CPU/x64/Foundationx64.mak
@@ -0,0 +1,65 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/x64/Foundationx64.mak 1 8/24/06 12:36p Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 8/24/06 12:36p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/x64/Foundationx64.mak $
+#
+# 1 8/24/06 12:36p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Foundationx64.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+Foundationx64 : $(BUILD_DIR)\Foundationx64.mak Foundationx64Bin
+
+$(BUILD_DIR)\Foundationx64.mak : $(Foundationx64_DIR)\$(@B).cif $(Foundationx64_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(Foundationx64_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="x64"
+FoundationBin : $(BUILD_DIR)\Foundationx64.lib
+$(BUILD_DIR)\Foundationx64.lib : Foundationx64
+!ENDIF
+
+
+Foundationx64Bin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Foundationx64.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR)"\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/Foundationx64.sdl b/Core/CPU/x64/Foundationx64.sdl
new file mode 100644
index 0000000..bb61c1a
--- /dev/null
+++ b/Core/CPU/x64/Foundationx64.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "Foundationx64_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Foundationx64 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Foundationx64_DIR"
+End
+
+MODULE
+ Help = "Includes Foundationx64.mak to Project"
+ File = "Foundationx64.mak"
+End
+
diff --git a/Core/CPU/x64/MiscLib/Misc.asm b/Core/CPU/x64/MiscLib/Misc.asm
new file mode 100644
index 0000000..facdd89
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/Misc.asm
@@ -0,0 +1,124 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/Misc.asm 2 10/04/12 9:17a Davidhsieh $
+;
+; $Revision: 2 $
+;
+; $Date: 10/04/12 9:17a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/Misc.asm $
+;
+; 2 10/04/12 9:17a Davidhsieh
+; Add MpMtrrSynchUpEntry and MpMtrrSynchUpExit procedures
+;
+; 1 5/15/12 5:41a Davidhsieh
+;
+; 1 5/08/12 6:02a Dukeyeh
+; [TAG] EIP89382
+; [Category] Improvement
+; [Description] clear direction flag inside Timer callback function.
+; [Files] MiscX64Lib.cif
+; Misc.asm
+; MiscX64Lib.sdl
+; MiscX64Lib.mak
+;
+; 6 1/13/10 2:13p Felixp
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: Misc
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+.code
+
+ClearDirectionFlag Proc
+ cld
+ ret
+ClearDirectionFlag endp
+
+MpMtrrSynchUpEntry PROC PUBLIC
+ ;
+ ; Enter no fill cache mode, CD=1(Bit30), NW=0 (Bit29)
+ ;
+ mov rax, cr0
+ and rax, 0DFFFFFFFh
+ or rax, 040000000h
+ mov cr0, rax
+ ;
+ ; Flush cache
+ ;
+ wbinvd
+ ;
+ ; Clear PGE flag Bit 7
+ ;
+ mov rax, cr4
+ mov rdx, rax
+ and rax, 0FFFFFF7Fh
+ mov cr4, rax
+ ;
+ ; Flush all TLBs
+ ;
+ mov rax, cr3
+ mov cr3, rax
+
+ mov rax, rdx
+
+ ret
+
+MpMtrrSynchUpEntry ENDP
+
+MpMtrrSynchUpExit PROC PUBLIC
+ ;
+ ; Flush all TLBs the second time
+ ;
+ mov rax, cr3
+ mov cr3, rax
+ ;
+ ; Enable Normal Mode caching CD=NW=0, CD(Bit30), NW(Bit29)
+ ;
+ mov rax, cr0
+ and rax, 09FFFFFFFh
+ mov cr0, rax
+ ;
+ ; Set PGE Flag in CR4 if set
+ ;
+ mov cr4, rcx
+ ret
+
+MpMtrrSynchUpExit ENDP
+
+END
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/MiscLib/MiscX64Lib.cif b/Core/CPU/x64/MiscLib/MiscX64Lib.cif
new file mode 100644
index 0000000..c05edf2
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/MiscX64Lib.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "MiscX64Lib"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\MiscLib"
+ RefName = "MiscX64Lib"
+[files]
+"Misc.asm"
+"MiscX64Lib.sdl"
+"MiscX64Lib.mak"
+<endComponent>
diff --git a/Core/CPU/x64/MiscLib/MiscX64Lib.mak b/Core/CPU/x64/MiscLib/MiscX64Lib.mak
new file mode 100644
index 0000000..61e7446
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/MiscX64Lib.mak
@@ -0,0 +1,74 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/MiscX64Lib.mak 1 5/15/12 5:41a Davidhsieh $
+#
+# $Revision: 1 $
+#
+# $Date: 5/15/12 5:41a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SharkBayRefCodes/Haswell/AMI Cpu PKG/CPU Core/MiscX64Lib/MiscX64Lib.mak $
+#
+# 1 5/15/12 5:41a Davidhsieh
+#
+# 1 5/08/12 6:02a Dukeyeh
+# [TAG] EIP89382
+# [Category] Improvement
+# [Description] clear direction flag inside Timer callback function.
+# [Files] MiscX64Lib.cif
+# Misc.asm
+# MiscX64Lib.sdl
+# MiscX64Lib.mak
+#
+# 1 10/13/06 8:37p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: MiscX64Lib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+MiscX64Lib : $(BUILD_DIR)\MiscX64Lib.mak MiscX64LibBin
+
+$(BUILD_DIR)\MiscX64Lib.mak : $(MiscX64Lib_DIR)\$(@B).cif $(MiscX64Lib_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(MiscX64Lib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(PROCESSOR)"=="x64"
+AmiDxeLibBin : $(BUILD_DIR)\MiscX64Lib.lib
+$(BUILD_DIR)\MiscX64Lib.lib : MiscX64Lib
+!ENDIF
+
+MiscX64LibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\MiscX64Lib.mak all\
+ TYPE=LIBRARY
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CPU/x64/MiscLib/MiscX64Lib.sdl b/Core/CPU/x64/MiscLib/MiscX64Lib.sdl
new file mode 100644
index 0000000..a9c676e
--- /dev/null
+++ b/Core/CPU/x64/MiscLib/MiscX64Lib.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "MiscX64Lib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable MiscX64Lib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "MiscX64Lib_DIR"
+End
+
+MODULE
+ Help = "Includes MiscX64Lib.mak to Project"
+ File = "MiscX64Lib.mak"
+End
+
diff --git a/Core/CPU/x64/PeCoffLoaderEx.c b/Core/CPU/x64/PeCoffLoaderEx.c
new file mode 100644
index 0000000..ff216a7
--- /dev/null
+++ b/Core/CPU/x64/PeCoffLoaderEx.c
@@ -0,0 +1,87 @@
+/*++
+
+Copyright (c) 2005 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name:
+
+ PeCoffLoaderEx.c
+
+Abstract:
+
+ x64 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "EfiImage.h"
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+ Performs an x64 specific relocation fixup
+
+Arguments:
+ Reloc - Pointer to the relocation record
+ Fixup - Pointer to the address to fix up
+ FixupData - Pointer to a buffer to log the fixups
+ Adjust - The offset to adjust the fixup
+
+Returns:
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+{
+ if ((Machine == EFI_IMAGE_MACHINE_IA32) || (Machine == EFI_IMAGE_MACHINE_X64) ||
+ (Machine == EFI_IMAGE_MACHINE_EBC)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/Core/CPU/x64/PeCoffLoaderEx.h b/Core/CPU/x64/PeCoffLoaderEx.h
new file mode 100644
index 0000000..a3f78e0
--- /dev/null
+++ b/Core/CPU/x64/PeCoffLoaderEx.h
@@ -0,0 +1,85 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoaderEx.h
+
+Abstract:
+
+ x64 Specific relocation fixups
+
+Revision History
+
+--*/
+
+#ifndef _PE_COFF_LOADER_EX_H_
+#define _PE_COFF_LOADER_EX_H_
+
+EFI_STATUS
+PeCoffLoaderRelocateImageEx (
+ IN UINT16 *Reloc,
+ IN OUT CHAR8 *Fixup,
+ IN OUT CHAR8 **FixupData,
+ IN UINT64 Adjust
+ )
+/*++
+
+Routine Description:
+
+ Performs an x64 specific relocation fixup
+
+Arguments:
+
+ Reloc - Pointer to the relocation record
+
+ Fixup - Pointer to the address to fix up
+
+ FixupData - Pointer to a buffer to log the fixups
+
+ Adjust - The offset to adjust the fixup
+
+Returns:
+
+ EFI_UNSUPPORTED - relocate unsupported
+
+--*/
+;
+
+BOOLEAN
+PeCoffLoaderImageFormatSupported (
+ IN UINT16 Machine
+ )
+/*++
+Routine Description:
+
+ Returns TRUE if the machine type of PE/COFF image is supported. Supported
+ does not mean the image can be executed it means the PE/COFF loader supports
+ loading and relocating of the image type. It's up to the caller to support
+ the entry point.
+
+ This function implies the basic PE/COFF loader/relocator supports IA32, EBC,
+ & X64 images. Calling the entry point in a correct mannor is up to the
+ consumer of this library.
+
+Arguments:
+
+ Machine - Machine type from the PE Header.
+
+Returns:
+
+ TRUE - if this PE/COFF loader can load the image
+ FALSE - if this PE/COFF loader cannot load the image
+
+--*/
+;
+
+#endif
diff --git a/Core/CPU/x64/Processor.c b/Core/CPU/x64/Processor.c
new file mode 100644
index 0000000..21a1649
--- /dev/null
+++ b/Core/CPU/x64/Processor.c
@@ -0,0 +1,146 @@
+/*++
+
+Copyright 2005 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+Module Name:
+
+ Processor.c
+
+Abstract:
+
+--*/
+
+#include "Tiano.h"
+#include "EfiJump.h"
+#include EFI_GUID_DEFINITION (PeiFlushInstructionCache)
+#include EFI_GUID_DEFINITION (PeiTransferControl)
+
+//
+// Prototypes
+//
+EFI_STATUS
+EFIAPI
+TransferControlSetJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+TransferControlLongJump (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN EFI_JUMP_BUFFER *Jump
+ );
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+//
+// Table declarations
+//
+EFI_PEI_TRANSFER_CONTROL_PROTOCOL mTransferControl = {
+ TransferControlSetJump,
+ TransferControlLongJump,
+ sizeof (EFI_JUMP_BUFFER)
+};
+
+EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL mFlushInstructionCache = {
+ FlushInstructionCacheFlush
+};
+
+
+EFI_STATUS
+EFIAPI
+InstallEfiPeiTransferControl(
+ IN OUT EFI_PEI_TRANSFER_CONTROL_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the transfer control mechanism
+
+Arguments:
+
+ This - Pointer to transfer control mechanism.
+
+Returns:
+
+ This - Pointer to transfer control mechanism.
+
+--*/
+{
+ *This = &mTransferControl;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+InstallEfiPeiFlushInstructionCache (
+ IN OUT EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Installs the pointer to the flush instruction cache mechanism
+
+Arguments:
+
+ This - Pointer to flush instruction cache mechanism.
+
+Returns:
+
+ This - Pointer to flush instruction cache mechanism.
+
+--*/
+{
+ *This = &mFlushInstructionCache;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+FlushInstructionCacheFlush (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ This routine would provide support for flushing the CPU instruction cache.
+ In the case of IA32, this flushing is not necessary and is thus not implemented.
+
+Arguments:
+
+ Pointer to CPU Architectural Protocol interface
+ Start adddress in memory to flush
+ Length of memory to flush
+
+Returns:
+
+ Status
+ EFI_SUCCESS
+
+--*/
+{
+ return EFI_SUCCESS;
+}
+
diff --git a/Core/CPU/x64/Processor.h b/Core/CPU/x64/Processor.h
new file mode 100644
index 0000000..cdf2992
--- /dev/null
+++ b/Core/CPU/x64/Processor.h
@@ -0,0 +1,27 @@
+/*++
+
+Copyright (c) 2005, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+ Processor.h
+
+Abstract:
+ This file contains the x64 processor specific definitions
+
+--*/
+
+#ifndef _PROCESSOR_H_
+#define _PROCESSOR_H_
+
+#define EFI_ACPI_RUNTIME_PAGE_ALLOCATION_ALIGNMENT (EFI_PAGE_SIZE)
+
+#define DEFAULT_PAGE_ALLOCATION (EFI_PAGE_SIZE)
+
+#endif
diff --git a/Core/CPU/x64/ProcessorAsms.Asm b/Core/CPU/x64/ProcessorAsms.Asm
new file mode 100644
index 0000000..ebd8b03
--- /dev/null
+++ b/Core/CPU/x64/ProcessorAsms.Asm
@@ -0,0 +1,186 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2005 - 2007, Intel Corporation
+; All rights reserved. This program and the accompanying materials
+; are licensed and made available under the terms and conditions of the BSD License
+; which accompanies this distribution. The full text of the license may be found at
+; http://opensource.org/licenses/bsd-license.php
+;
+; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;
+; Module Name:
+; ProcessorAsms.Asm
+;
+; Abstract:
+; This is separated from processor.c to allow this functions to be built with /O1
+;
+;
+;------------------------------------------------------------------------------
+
+text SEGMENT
+
+
+;
+; Routine Description:
+; This allows the caller to switch the stack and goes to the new entry point
+;
+; Arguments:
+; EntryPoint - Pointer to the location to enter // rcx
+; Parameter - Parameter to pass in // rdx
+; NewStack - New Location of the stack // r8
+; NewBsp - New BSP // r9 - not used
+;
+; Returns:
+; Nothing. Goes to the Entry Point passing in the new parameters
+;
+SwitchStacks PROC PUBLIC
+
+ ; Adjust stack for
+ ; 1) leave 4 registers space
+ ; 2) let it 16 bytes aligned after call
+ sub r8, 20h
+ and r8w, 0fff0h ; do not assume 16 bytes aligned
+
+ mov rsp, r8 ; rsp = NewStack
+ mov r10, rcx ; save EntryPoint
+ mov rcx, rdx ; Arg1 = Parameter
+ call r10 ; r10 = copy of EntryPoint
+ ;
+ ; no ret as we have a new stack and we jumped to the new location
+ ;
+ ret
+
+SwitchStacks ENDP
+
+
+EFI_SUCCESS equ 0
+EFI_WARN_RETURN_FROM_LONG_JUMP equ 5
+
+;
+; Generated by h2inc run manually
+;
+_EFI_JUMP_BUFFER STRUCT 2t
+_rbx QWORD ?
+_rsp QWORD ?
+_rbp QWORD ?
+_rdi QWORD ?
+_rsi QWORD ?
+_r10 QWORD ?
+_r11 QWORD ?
+_r12 QWORD ?
+_r13 QWORD ?
+_r14 QWORD ?
+_r15 QWORD ?
+_rip QWORD ?
+_MxCsr DWORD ?
+_XmmBuffer DB 160 DUP (?)
+_EFI_JUMP_BUFFER ENDS
+
+EFI_JUMP_BUFFER TYPEDEF _EFI_JUMP_BUFFER
+
+
+;
+;Routine Description:
+;
+; This routine implements the x64 variant of the SetJump call. Its
+; responsibility is to store system state information for a possible
+; subsequent LongJump.
+;
+;Arguments:
+;
+; Pointer to CPU context save buffer.
+;
+;Returns:
+;
+; EFI_SUCCESS
+;
+; EFI_STATUS
+; EFIAPI
+; TransferControlLongJump (
+; IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+; IN EFI_JUMP_BUFFER *Jump
+; );
+;
+; rcx - *This
+; rdx - JumpBuffer
+;
+PUBLIC TransferControlSetJump
+TransferControlSetJump PROC
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rbx, rbx
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rsp, rsp
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rbp, rbp
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rdi, rdi
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rsi, rsi
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r10, r10
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r11, r11
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r12, r12
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r13, r13
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r14, r14
+ mov (EFI_JUMP_BUFFER PTR [rdx])._r15, r15
+ ; save non-volatile fp registers
+ stmxcsr (EFI_JUMP_BUFFER PTR [rdx])._MxCsr
+ lea rax, (EFI_JUMP_BUFFER PTR [rdx])._XmmBuffer
+ movdqu [rax], xmm6
+ movdqu [rax + 10h], xmm7
+ movdqu [rax + 20h], xmm8
+ movdqu [rax + 30h], xmm9
+ movdqu [rax + 40h], xmm10
+ movdqu [rax + 50h], xmm11
+ movdqu [rax + 60h], xmm12
+ movdqu [rax + 70h], xmm13
+ movdqu [rax + 80h], xmm14
+ movdqu [rax + 90h], xmm15
+ mov rax, QWORD PTR [rsp+0]
+ mov (EFI_JUMP_BUFFER PTR [rdx])._rip, rax
+ mov rax, EFI_SUCCESS
+ ret
+
+TransferControlSetJump ENDP
+
+;
+; EFI_STATUS
+; EFIAPI
+; TransferControlLongJump (
+; IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This, // rcx
+; IN EFI_JUMP_BUFFER *Jump // rdx
+; );
+;
+;
+PUBLIC TransferControlLongJump
+TransferControlLongJump PROC
+ ; load non-volatile fp registers
+ ldmxcsr (EFI_JUMP_BUFFER PTR [rdx])._MxCsr
+ lea rax, (EFI_JUMP_BUFFER PTR [rdx])._XmmBuffer
+ movdqu xmm6, [rax]
+ movdqu xmm7, [rax + 10h]
+ movdqu xmm8, [rax + 20h]
+ movdqu xmm9, [rax + 30h]
+ movdqu xmm10, [rax + 40h]
+ movdqu xmm11, [rax + 50h]
+ movdqu xmm12, [rax + 60h]
+ movdqu xmm13, [rax + 70h]
+ movdqu xmm14, [rax + 80h]
+ movdqu xmm15, [rax + 90h]
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov rax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov rbx, (EFI_JUMP_BUFFER PTR [rdx])._rbx
+ mov rsp, (EFI_JUMP_BUFFER PTR [rdx])._rsp
+ mov rbp, (EFI_JUMP_BUFFER PTR [rdx])._rbp
+ mov rdi, (EFI_JUMP_BUFFER PTR [rdx])._rdi
+ mov rsi, (EFI_JUMP_BUFFER PTR [rdx])._rsi
+ mov r10, (EFI_JUMP_BUFFER PTR [rdx])._r10
+ mov r11, (EFI_JUMP_BUFFER PTR [rdx])._r11
+ mov r12, (EFI_JUMP_BUFFER PTR [rdx])._r12
+ mov r13, (EFI_JUMP_BUFFER PTR [rdx])._r13
+ mov r14, (EFI_JUMP_BUFFER PTR [rdx])._r14
+ mov r15, (EFI_JUMP_BUFFER PTR [rdx])._r15
+ add rsp, 8 ;pop the eip
+ jmp QWORD PTR (EFI_JUMP_BUFFER PTR [rdx])._rip
+ ; set return from SetJump to EFI_WARN_RETURN_FROM_LONG_JUMP
+ mov rax, EFI_WARN_RETURN_FROM_LONG_JUMP
+ ret
+TransferControlLongJump ENDP
+
+text ENDS
+END
diff --git a/Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm b/Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm
new file mode 100644
index 0000000..973357f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULIB_GetPageTable.asm
@@ -0,0 +1,80 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULIB_GetPageTable.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULIB_GetPageTable.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULIB_GetPageTable
+;
+; Description:
+; VOID* CPULIB_GetPageTable() retrieves the address of the page table.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID* address of the page table.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULIB_GetPageTable proc
+ mov rax, cr3
+ ret
+CPULIB_GetPageTable endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm b/Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm
new file mode 100644
index 0000000..53719f2
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_CpuID.asm
@@ -0,0 +1,130 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_CpuID.asm 2 11/11/11 3:40p Artems $
+;
+; $Revision: 2 $
+;
+; $Date: 11/11/11 3:40p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_CpuID.asm $
+;
+; 2 11/11/11 3:40p Artems
+; Bug fix: Verify pointer is not NULL, when return value
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_CpuID
+;
+; Description:
+; VOID CPULib_CpuID(IN UINT32 CpuIDIndex, IN UINT32 *pRegEAX,
+; IN UINT32 *pRegEBX, IN UINT32 *pRegECX, IN UINT32 *pRegEDX) issues the
+; CPUID instruction with the index provided and returns the register values.
+;
+; Input:
+; IN UINT32 CpuIDIndex
+; 32-bit CPUID index.
+;
+; IN UINT32 *pRegEAX
+; Value of EAX after CPUID instruction.
+;
+; IN UINT32 *pRegEBX
+; Value of EBX after CPUID instruction.
+;
+; IN UINT32 *pRegECX
+; Value of ECX after CPUID instruction.
+;
+; IN UINT32 *pRegEDX
+; Value of EDX after CPUID instruction.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_CpuID proc
+;rcx = CpuIDIndex
+;rdx = pRegEax
+;r8 = pRegEBX
+;r9 = pRegECX
+;[rsp + 8] = pRegEDX:DWORD
+
+ push rbx
+ mov r11, [rsp + 30h] ;pRegEDX
+ mov r10, r9 ;pRegECX
+ mov r9, r8 ;pRegEBX
+ mov r8, rdx ;pRegEAX
+
+ mov eax, ecx
+ mov ecx, [r10]
+ cpuid
+
+ or r8, r8
+ jz skip1
+ mov [r8], eax
+skip1:
+ or r9, r9
+ jz skip2
+ mov [r9], ebx
+skip2:
+ or r10, r10
+ jz skip3
+ mov [r10], ecx
+skip3:
+ or r11, r11
+ jz skip4
+ mov [r11], edx
+skip4:
+ pop rbx
+ ret
+CPULib_CpuID endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm b/Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm
new file mode 100644
index 0000000..6c63f8a
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_DisableInterrupt.asm
@@ -0,0 +1,81 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_DisableInterrupt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_DisableInterrupt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_DisableInterrupt
+;
+; Description:
+; VOID CPULib_DisableInterrupt() disables interrupts on the CPU.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_DisableInterrupt PROC PUBLIC
+; Disable Interrupt
+ cli
+ ret
+CPULib_DisableInterrupt ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm b/Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm
new file mode 100644
index 0000000..bc43c62
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_EnableInterrupt.asm
@@ -0,0 +1,81 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_EnableInterrupt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_EnableInterrupt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_EnableInterrupt
+;
+; Description:
+; VOID CPULib_EnableInterrupt() enables interrupts on the CPU.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_EnableInterrupt PROC PUBLIC
+; Enable Interrupt
+ sti
+ ret
+CPULib_EnableInterrupt ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm b/Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm
new file mode 100644
index 0000000..436cba7
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_GetInterruptState.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_GetInterruptState.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_GetInterruptState.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_GetInterruptState
+;
+; Description:
+; BOOLEAN CPULib_GetInterruptState()returns the current CPU interrupt state.
+;
+; Input:
+; VOID.
+;
+; Output:
+; FALSE if interrupts are disabled; otherwise TRUE.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_GetInterruptState PROC PUBLIC
+ xor cl, cl
+ pushf ; push flags onto stack.
+ pop ax ; eax = flags.
+ bt ax, 9 ; IF (bit 9) if set, set carry flag.
+ ; Interrupts are allowed if IF is set.
+ adc cl, 0 ; CL = IF = CF.
+
+ mov al, cl ; Return value
+ ret
+CPULib_GetInterruptState ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm
new file mode 100644
index 0000000..1fc3c23
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LoadGdt.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadGdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadGdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LoadGdt
+;
+; Description:
+; VOID CPULib_LoadGdt(IN VOID *ptr) loads the GDT at the location pointed to
+; by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address of the GDT to be loaded.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LoadGdt proc
+ lgdt fword ptr [rcx]
+ ret
+CPULib_LoadGdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm
new file mode 100644
index 0000000..3c4afc8
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LoadIdt.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadIdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LoadIdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LoadIdt
+;
+; Description:
+; VOID CPULib_LoadIdt(IN VOID *ptr) loads the IDT at the location provided
+; by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address of the IDT to be loaded.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LoadIdt proc
+ lidt fword ptr [rcx]
+ ret
+CPULib_LoadIdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm b/Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm
new file mode 100644
index 0000000..433bd1b
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LockByteDec.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteDec.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteDec.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LockByteDec
+;
+; Description:
+; VOID CPULib_LockByteDec(IN UINT8 *ptr) locks the preceeding byte before
+; the address pointed to by ptr.
+;
+; Input:
+; IN UINT8 *ptr
+; Address to the byte which follows the desired byte to be locked.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LockByteDec proc
+ lock dec byte ptr [rcx]
+ ret
+CPULib_LockByteDec endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm b/Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm
new file mode 100644
index 0000000..83addc8
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_LockByteInc.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteInc.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_LockByteInc.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_LockByteInc
+;
+; Description:
+; VOID CPULib_LockByteInc(IN UINT8 *ptr) locks the next byte after the
+; address pointed to by ptr.
+;
+; Input:
+; IN UINT8 *ptr
+; Address to the byte which preceeds the desired byte to be locked.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_LockByteInc proc
+ lock inc byte ptr [rcx]
+ ret
+CPULib_LockByteInc endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_Pause.asm b/Core/CPU/x64/x64AsmLib/CPULib_Pause.asm
new file mode 100644
index 0000000..c7d2574
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_Pause.asm
@@ -0,0 +1,80 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_Pause.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_Pause.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_Pause
+;
+; Description:
+; VOID CPULib_Pause() performs the pause assembly instruction.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_Pause Proc
+ pause
+ ret
+CPULib_Pause endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm
new file mode 100644
index 0000000..28258cf
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_SaveGdt.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveGdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveGdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_SaveGdt
+;
+; Description:
+; VOID CPULib_SaveGdt(IN VOID *ptr) stores the loaded GDT at the location
+; provided by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address to save the GDT. User is responsible for allocating the necessary
+; memory resources.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_SaveGdt proc
+ sgdt fword ptr [rcx]
+ ret
+CPULib_SaveGdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm b/Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm
new file mode 100644
index 0000000..046b7f6
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/CPULib_SaveIdt.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveIdt.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/CPULib_SaveIdt.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: CPULib_SaveIdt
+;
+; Description:
+; VOID CPULib_SaveIdt(IN VOID *ptr) stores the loaded IDT at the location
+; provided by ptr.
+;
+; Input:
+; IN VOID *ptr
+; Address to save the IDT. User is responsible for allocating the necessary
+; memory resources.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+CPULib_SaveIdt proc
+ sidt fword ptr [rcx]
+ ret
+CPULib_SaveIdt endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm b/Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm
new file mode 100644
index 0000000..c03cd1f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/DisableCacheInCR0.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/DisableCacheInCR0.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/DisableCacheInCR0.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: DisableCacheInCR0
+;
+; Description:
+; VOID DisableCacheInCR0() disables the CPU cache using the CR0 register.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+DisableCacheInCR0 PROC PUBLIC
+ wbinvd
+ mov rax, cr0
+ or eax, 060000000h ;SET CD, NW
+ mov cr0, rax
+ wbinvd ;Invalidate cache
+ ret
+DisableCacheInCR0 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm b/Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm
new file mode 100644
index 0000000..7633a1f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/EnableCacheInCR0.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableCacheInCR0.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableCacheInCR0.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableCacheInCR0
+;
+; Description:
+; VOID EnableCacheInCR0() enables the CPU cache using the CR0 register.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableCacheInCR0 PROC PUBLIC
+; Enable cache
+ mov rax, cr0
+ and eax, 09fffffffh ;SET CD, NW
+ mov cr0, rax
+ wbinvd
+ ret
+EnableCacheInCR0 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm b/Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm
new file mode 100644
index 0000000..b220afd
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/EnableMachineCheck.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableMachineCheck.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/EnableMachineCheck.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: EnableMachineCheck
+;
+; Description:
+; VOID EnableMachineCheck() sets the Machine Check Exception bit in CR4,
+; which enables machine check interrupts to occur.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+EnableMachineCheck proc
+ mov rax, cr4
+ or eax, 1 SHL 6
+ mov cr4, rax
+ ret
+EnableMachineCheck endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/GetCpuTimer.asm b/Core/CPU/x64/x64AsmLib/GetCpuTimer.asm
new file mode 100644
index 0000000..f606744
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/GetCpuTimer.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCpuTimer.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCpuTimer.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: GetCpuTimer
+;
+; Description:
+; UINT64 GetCpuTimer() returns the value of the CPU timer.
+;
+; Input:
+; None.
+;
+; Output:
+; UINT64 value of the CPU timer.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+GetCpuTimer proc
+ rdtsc
+ shl rdx,32
+ or rax, rdx
+ ret
+GetCpuTimer endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/GetCsSegment.asm b/Core/CPU/x64/x64AsmLib/GetCsSegment.asm
new file mode 100644
index 0000000..02138c3
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/GetCsSegment.asm
@@ -0,0 +1,79 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCsSegment.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetCsSegment.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: GetCsSegment
+;
+; Description:
+; UINT16 GetCsSegment() retreives the value of the CS register.
+;
+; Input:
+; VOID.
+;
+; Output:
+; UINT16 value of CS.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+GetCsSegment proc
+ mov ax, cs
+ ret
+GetCsSegment endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm b/Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm
new file mode 100644
index 0000000..9cebe72
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/GetPowerOfTwo64.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetPowerOfTwo64.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/GetPowerOfTwo64.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: GetPowerOfTwo64
+;
+; Description:
+; UINT64 GetPowerOfTwo64(IN UINT64 Input) returns the highest bit set in
+; the provided UINT64 Input. Equivalent to 1 << log2(x).
+;
+; Input:
+; IN UINT64 Input
+; The 64-bit value to check for its highest bit.
+;
+; Output:
+; UINT64 value of the highest bit; if Input is 0, returns 0.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+GetPowerOfTwo64 proc
+ bsr rdx, rcx
+ xor rax, rax
+ bts rax, rdx
+ ret
+GetPowerOfTwo64 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/HltCpu.asm b/Core/CPU/x64/x64AsmLib/HltCpu.asm
new file mode 100644
index 0000000..a8c8a6e
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/HltCpu.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/HltCpu.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/HltCpu.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: HltCpu
+;
+; Description:
+; VOID HltCpu() halts the CPU.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+HltCpu Proc
+@@:
+ cli
+ hlt
+ jmp @b
+ ret
+HltCpu endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead16.asm b/Core/CPU/x64/x64AsmLib/IoRead16.asm
new file mode 100644
index 0000000..3403a34
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead16.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead16.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead16.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead16
+;
+; Description:
+; UINT16 IoRead16(IN UINT16 Port) reads the 16-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 16-bits from.
+;
+; Output:
+; UINT16 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead16 proc
+ mov dx, cx
+ in ax, dx
+ ret
+IoRead16 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead32.asm b/Core/CPU/x64/x64AsmLib/IoRead32.asm
new file mode 100644
index 0000000..510a01f
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead32.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead32
+;
+; Description:
+; UINT32 IoRead32(IN UINT16 Port) reads the 32-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 32-bits from.
+;
+; Output:
+; UINT32 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead32 proc
+ mov dx, cx
+ in eax, dx
+ ret
+IoRead32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead64.asm b/Core/CPU/x64/x64AsmLib/IoRead64.asm
new file mode 100644
index 0000000..ff1da50
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead64.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead64.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead64.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead64
+;
+; Description:
+; UINT32 IoRead64(IN UINT16 Port) reads the 64-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 64-bits from.
+;
+; Output:
+; UINT64 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead64 proc
+ mov dx, cx
+ in rax, dx
+ ret
+IoRead64 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoRead8.asm b/Core/CPU/x64/x64AsmLib/IoRead8.asm
new file mode 100644
index 0000000..3dfd1fd
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoRead8.asm
@@ -0,0 +1,83 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead8.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoRead8.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoRead8
+;
+; Description:
+; UINT8 IoRead8(IN UINT16 Port) reads the 8-bit value stored at the I/O
+; port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to read 8-bits from.
+;
+; Output:
+; UINT8 value stored at I/O Port.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoRead8 proc
+ mov dx, cx
+ in al, dx
+ ret
+IoRead8 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite16.asm b/Core/CPU/x64/x64AsmLib/IoWrite16.asm
new file mode 100644
index 0000000..2616d1a
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite16.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite16.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite16.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite16
+;
+; Description:
+; VOID IoWrite16(IN UINT16 Port, IN UINT16 Value) writes the 16-bit Value
+; to the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 16-bits to.
+;
+; IN UINT16 Value
+; 16-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite16 proc
+ mov ax, dx
+ mov dx, cx
+ out dx, ax
+ ret
+IoWrite16 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite32.asm b/Core/CPU/x64/x64AsmLib/IoWrite32.asm
new file mode 100644
index 0000000..98096d7
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite32.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite32
+;
+; Description:
+; VOID IoWrite32(IN UINT16 Port, IN UINT32 Value) writes the 32-bit Value
+; to the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 32-bits to.
+;
+; IN UINT32 Value
+; 32-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite32 proc
+ mov eax, edx
+ mov dx, cx
+ out dx, eax
+ ret
+IoWrite32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite64.asm b/Core/CPU/x64/x64AsmLib/IoWrite64.asm
new file mode 100644
index 0000000..c38c832
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite64.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite64.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite64.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite64
+;
+; Description:
+; VOID IoWrite64(IN UINT16 Port, IN UINT64 Value) writes the 64-bit Value
+; to the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 64-bits to.
+;
+; IN UINT64 Value
+; 64-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite64 proc
+ mov rax, rdx
+ mov dx, cx
+ out dx, rax
+ ret
+IoWrite64 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/IoWrite8.asm b/Core/CPU/x64/x64AsmLib/IoWrite8.asm
new file mode 100644
index 0000000..4bd5119
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/IoWrite8.asm
@@ -0,0 +1,87 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite8.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/IoWrite8.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: IoWrite8
+;
+; Description:
+; VOID IoWrite8(IN UINT16 Port, IN UINT8 Value) writes the 8-bit Value to
+; the I/O port defined by Port.
+;
+; Input:
+; IN UINT16 Port
+; I/O port to write 8-bits to.
+;
+; IN UINT8 Value
+; 8-bits to write to the I/O Port.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+IoWrite8 proc
+ mov al, dl
+ mov dx, cx
+ out dx, al
+ ret
+IoWrite8 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemCpy.asm b/Core/CPU/x64/x64AsmLib/MemCpy.asm
new file mode 100644
index 0000000..a671ec8
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemCpy.asm
@@ -0,0 +1,178 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy.asm 2 3/09/11 1:58p Felixp $
+;
+; $Revision: 2 $
+;
+; $Date: 3/09/11 1:58p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy.asm $
+;
+; 2 3/09/11 1:58p Felixp
+; MemCpy is updated to copy 8 bytes at a time (used to be 4)
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemCpy
+;
+; Description:
+; VOID MemCpy(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+; copies Count bytes of memory from Source to Destination.
+;
+; Input:
+; OUT VOID *pDestination
+; Memory address where data shall be copied. User is responsible for
+; allocating the necessary memory resources.
+;
+; IN VOID *pSource
+; Memory address from where data shall be copied.
+;
+; IN UINTN Count
+; Number of bytes to copy from pSource.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+; This function checks for overlapping of source and destination and
+; selects copy direction that prevents memory corruption.
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+public memcpy
+memcpy:
+MemCpy proc
+ push rdi
+ push rsi
+ push rbx
+ pushf
+ mov rsi, rdx ; pSource
+ mov rdi, rcx ; pDestination
+ mov rcx, r8 ; Count
+ mov dl, 0
+ ; if pSource > pDestination CopyForward
+ mov rax, rsi
+ sub rax, rdi ; rax = pSource-pDestination
+ jnb CopyForward; if pSource-pDestination > 0 CopyForward
+ ; if pSource+Count < pDestination then CopyForward
+ lea rbx, [rsi+rcx] ; rbx = pSource + Count
+ neg rax ; rax = pDestination - pSource
+ cmp rbx, rdi
+ jb CopyForward ; if (pSource + Count < pDestination ) CopyForward
+ ; Copy Backward
+ mov rsi, rbx; rsi = pSource + Count
+ lea rdi, [rdi+rcx]; rdi = pDestination + Count
+ mov dl, 1; Flag to indicate that we are copying backward
+ std; set direction flag to copy backward
+CopyForward:
+ cmp rcx, 8 ; if (Counter<8) copy byte by byte
+ jb m8
+ cmp rax, 8 ; if (pDestination - pSource < 8) copy byte by byte
+ jb m8
+ ; if pSource and pDestination are not 8 byte aligned
+ ; Calculate 8-(Buffer%8), which is a number of bytes we have to copy to align the buffer
+ ; if this number if the same for source and destinations
+ ; copy several bytes to align them
+ ; otherwise proceed to QWORD copy
+ mov rax, rsi
+ mov rbx, rdi
+ and rax, 7
+ and rbx, 7
+ test dl, dl
+ jz skip1
+ dec rsi
+ dec rdi
+skip1:
+ cmp rax, rbx
+ jne m64
+ test rax, rax
+ jz m64
+ test dl, dl
+ jnz skip_nz1
+ neg rax
+ add rax, 8
+skip_nz1:
+ xchg rax, rcx
+ sub rax, rcx
+ rep movsb
+ mov rcx, rax
+m64:
+ test dl, dl
+ jz skip2
+ sub rsi, 7
+ sub rdi, 7
+skip2:
+ mov rax, rcx
+ shr rcx, 3
+ rep movsq
+ and rax, 7
+ jz MemCpuEnd
+ test dl, dl
+ jz skip3
+ add rsi, 8
+ add rdi, 8
+skip3:
+ mov rcx, rax
+m8:
+ test dl, dl
+ jz skip4
+ dec rsi
+ dec rdi
+skip4:
+ rep movsb
+MemCpuEnd:
+ popf
+ pop rbx
+ pop rsi
+ pop rdi
+ ret
+MemCpy endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemCpy32.asm b/Core/CPU/x64/x64AsmLib/MemCpy32.asm
new file mode 100644
index 0000000..a5886b3
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemCpy32.asm
@@ -0,0 +1,178 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy32.asm 1 10/17/11 1:03p Yakovlevs $
+;
+; $Revision: 1 $
+;
+; $Date: 10/17/11 1:03p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemCpy32.asm $
+;
+; 1 10/17/11 1:03p Yakovlevs
+; [TAG] EIP71694
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemCpy32
+;
+; Description:
+; VOID MemCpy32(OUT VOID *pDestination, IN VOID *pSource, IN UINTN Count)
+; copies Count bytes of memory from Source to Destination.
+;
+; Input:
+; OUT VOID *pDestination
+; Memory address where data shall be copied. User is responsible for
+; allocating the necessary memory resources.
+;
+; IN VOID *pSource
+; Memory address from where data shall be copied.
+;
+; IN UINTN Count
+; Number of bytes to copy from pSource.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+; This function checks for overlapping of source and destination and
+; selects copy direction that prevents memory corruption.
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+public memcpy32
+memcpy32:
+MemCpy32 proc
+ push rdi
+ push rsi
+ push rbx
+ pushf
+ mov rsi, rdx ; pSource
+ mov rdi, rcx ; pDestination
+ mov rcx, r8 ; Count
+ mov dl, 0
+ ; if pSource > pDestination CopyForward
+ mov rax, rsi
+ sub rax, rdi ; rax = pSource-pDestination
+ jnb CopyForward; if pSource-pDestination > 0 CopyForward
+ ; if pSource+Count < pDestination then CopyForward
+ lea rbx, [rsi+rcx] ; rbx = pSource + Count
+ neg rax ; rax = pDestination - pSource
+ cmp rbx, rdi
+ jb CopyForward ; if (pSource + Count < pDestination ) CopyForward
+ ; Copy Backward
+ mov rsi, rbx; rsi = pSource + Count
+ lea rdi, [rdi+rcx]; rdi = pDestination + Count
+ mov dl, 1; Flag to indicate that we are copying backward
+ std; set direction flag to copy backward
+CopyForward:
+ cmp rcx, 4 ; if (Counter<4) copy byte by byte
+ jb m8
+ cmp rax, 4 ; if (pDestination - pSource < 4) copy byte by byte
+ jb m8
+ ; if pSource and pDestination are not 4 byte aligned
+ ; Calculate 4-(Buffer%4), which is a number of bytes we have to copy to align the buffer
+ ; if this number if the same for source and destinations
+ ; copy several bytes to align them
+ ; otherwise proceed to DWORD copy
+ mov rax, rsi
+ mov rbx, rdi
+ and rax, 3
+ and rbx, 3
+ test dl, dl
+ jz skip1
+ dec rsi
+ dec rdi
+skip1:
+ cmp rax, rbx
+ jne m32
+ test rax, rax
+ jz m32
+ test dl, dl
+ jnz skip_nz1
+ neg rax
+ add rax, 4
+skip_nz1:
+ xchg rax, rcx
+ sub rax, rcx
+ rep movsb
+ mov rcx, rax
+m32:
+ test dl, dl
+ jz skip2
+ sub rsi, 3
+ sub rdi, 3
+skip2:
+ mov rax, rcx
+ shr rcx, 2
+ rep movsd
+ and rax, 3
+ jz MemCpuEnd
+ test dl, dl
+ jz skip3
+ add rsi, 4
+ add rdi, 4
+skip3:
+ mov rcx, rax
+m8:
+ test dl, dl
+ jz skip4
+ dec rsi
+ dec rdi
+skip4:
+ rep movsb
+MemCpuEnd:
+ popf
+ pop rbx
+ pop rsi
+ pop rdi
+ ret
+MemCpy32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemRead32.asm b/Core/CPU/x64/x64AsmLib/MemRead32.asm
new file mode 100644
index 0000000..3f79a06
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemRead32.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemRead32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemRead32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemRead32
+;
+; Description:
+; UINT32 MemRead32(IN UINT32 *Address) reads and returns the 32-bit value
+; stored at the user provided address.
+;
+; Input:
+; IN UINT32 *Address
+; Address to read 32-bits from.
+;
+; Output:
+; UINT32 value stored at Address.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+MemRead32 proc
+ mov eax, [rcx]
+ ret
+MemRead32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemReadWrite32.asm b/Core/CPU/x64/x64AsmLib/MemReadWrite32.asm
new file mode 100644
index 0000000..a9ab5ba
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemReadWrite32.asm
@@ -0,0 +1,93 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemReadWrite32.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemReadWrite32.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemReadWrite32
+;
+; Description:
+; VOID MemReadWrite32(IN UINT32 *Address, IN UINT32 Value, IN UINT32 Mask)
+; reads the 32-bit value stored at Address, ANDs it with Mask, ORs the result
+; with Value, then writes the result back to Address.
+;
+; Input:
+; IN UINT32 *Address
+; Address which shall be read from and subsequently written to.
+;
+; IN UINT32 Value
+; Value to be ORed with the value stored at Address after it has been ANDed
+; with the provided Mask.
+;
+; IN UINT32 Mask
+; Mask to be ANDed with the original value stored at Address.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+MemReadWrite32 proc
+ mov eax, [rcx]
+ and eax, r8D ;Mask
+ or eax, edx ;Value
+ mov [rcx], eax
+ ret
+MemReadWrite32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/MemSet.asm b/Core/CPU/x64/x64AsmLib/MemSet.asm
new file mode 100644
index 0000000..246b985
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/MemSet.asm
@@ -0,0 +1,127 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemSet.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/MemSet.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: MemSet
+;
+; Description:
+; VOID MemSet(IN VOID *pBuffer, IN UINTN Count, IN UINT8 Value) fills Count
+; bytes of memory in pBuffer with Value.
+;
+; Input:
+; IN VOID *pBuffer
+; The starting location in memory where to begin filling.
+;
+; IN UINTN Count
+; The number of bytes to fill with Value.
+;
+; IN UINT8 Value
+; The value to fill memory with starting at pBuffer.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+MemSet proc
+ push rdi
+ push rbx
+ mov rdi, rcx ; rdi = pBuffer
+ mov rcx, rdx ; rcx = Count
+ mov rax, r8 ; al = Value
+ ; fill EAX with the Value so that we can perform DWORD operatins
+ mov ah, al
+ mov bx,ax
+ shl rax,16
+ mov ax,bx
+ ; if Counter is less then 4, jump to byte copy
+ cmp rcx, 4
+ jb CopyByte
+ ; check if the Buffer is 4-bytes aligned
+ mov rdx,rdi
+ and rdx, 3
+ ; if the Buffer is 4-bytes aligned, jump to DWORD copy
+ jz CopyDword
+ ; Buffer is not 4-bytes aligned
+ ; Calculate 4-(Buffer%4), which is a number of bytes we have to copy before
+ ; Buffer will reach 4-bytes boundary, and perform byte copy
+ neg rdx
+ add rdx, 4
+ xchg rcx, rdx
+ sub rdx, rcx
+ rep stosb
+ mov rcx, rdx
+CopyDword:
+ ; perform DWORD copy
+ mov rdx, rcx
+ shr rcx, 2
+ rep stosd
+ ; copy the remainder
+ and rdx,3
+ mov rcx, rdx
+CopyByte:
+ rep stosb
+ ;;;
+ pop rbx
+ pop rdi
+ ret
+MemSet endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/ReadCr3.asm b/Core/CPU/x64/x64AsmLib/ReadCr3.asm
new file mode 100644
index 0000000..ad90c20
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/ReadCr3.asm
@@ -0,0 +1,79 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadCr3.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadCr3.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: ReadCr3
+;
+; Description:
+; UINTN ReadCr3() reads the register CR3 and returns its value.
+;
+; Input:
+;
+; Output:
+; UINTN value stored in the CR3 register.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+ReadCr3 PROC PUBLIC
+ mov rax, cr3
+ ret
+ReadCr3 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/ReadMsr.asm b/Core/CPU/x64/x64AsmLib/ReadMsr.asm
new file mode 100644
index 0000000..3fbeff6
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/ReadMsr.asm
@@ -0,0 +1,85 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadMsr.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadMsr.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: ReadMsr
+;
+; Description:
+; UINT64 ReadMsr(UINT32 Msr) reads the CPU MSR index defined by Msr and
+; returns the value.
+;
+; Input:
+; IN UINT32 Msr
+; 32-bit MSR index to be read.
+;
+; Output:
+; UINT64 MSR value at MSR index, Msr.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+ReadMsr Proc ;(UINT32 Msr)
+ rdmsr ;rcx = MSR
+ and rax, 0ffffffffh
+ shl rdx, 32
+ or rax, rdx ;rax = (rdx << 32) | eax
+ ret
+ReadMsr endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/ReadRtdsc.asm b/Core/CPU/x64/x64AsmLib/ReadRtdsc.asm
new file mode 100644
index 0000000..078964c
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/ReadRtdsc.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadRtdsc.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/ReadRtdsc.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: ReadRtdsc
+;
+; Description:
+; UINT64 ReadRtdsc() retrieves the time stamp counter.
+;
+; Input:
+; VOID.
+;
+; Output:
+; UINT64 value of the time stamp counter.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+ReadRtdsc Proc
+ rdtsc
+ shl rdx,32
+ or rax, rdx
+ ret
+ReadRtdsc endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm b/Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm
new file mode 100644
index 0000000..a5efa82
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitForSemaphore.asm
@@ -0,0 +1,88 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForSemaphore.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForSemaphore.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitForSemaphore
+;
+; Description:
+; VOID WaitForSemaphore(IN volatile UINT8 *Semaphore) waits for the
+; semaphore to become available; once available, it claims the semaphore and
+; returns.
+;
+; Input:
+; IN volatile UINT8 *Semaphore
+; Pointer to the desired semaphore.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitForSemaphore Proc
+ mov al, 1
+@@:
+ xchg al, [rcx]
+ or al, al
+ pause
+ jnz @b
+ ret
+WaitForSemaphore endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitForever.asm b/Core/CPU/x64/x64AsmLib/WaitForever.asm
new file mode 100644
index 0000000..c010643
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitForever.asm
@@ -0,0 +1,82 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForever.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitForever.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitForever
+;
+; Description:
+; VOID WaitForever() performs an infinite loop which does nothing.
+;
+; Input:
+; VOID.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitForever Proc
+@@:
+ Pause
+ jmp @b
+ ret
+WaitForever endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm b/Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm
new file mode 100644
index 0000000..cdda323
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitUntilZero32.asm
@@ -0,0 +1,86 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero32.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero32.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitUntilZero32
+;
+; Description:
+; VOID WaitUntilZero32(IN volatile UINT32 *Value) waits until the UINT32
+; value stored at the Value address becomes 0, then continues.
+;
+; Input:
+; IN volatile UINT32 *Value
+; Address of the UINT32 value to be monitored.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitUntilZero32 Proc
+@@:
+ mov eax, [rcx]
+ or eax, eax
+ pause
+ jnz @b
+ ret
+WaitUntilZero32 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm b/Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm
new file mode 100644
index 0000000..b2c5f4d
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WaitUntilZero8.asm
@@ -0,0 +1,86 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero8.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WaitUntilZero8.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WaitUntilZero8
+;
+; Description:
+; VOID WaitUntilZero8(IN volatile UINT8 *Value) waits until the byte stored
+; at Value becomes 0, then continues.
+;
+; Input:
+; IN volatile UINT8 *Value
+; Address of the byte value to be monitored.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WaitUntilZero8 Proc
+@@:
+ mov al, [rcx]
+ or al, al
+ pause
+ jnz @b
+ ret
+WaitUntilZero8 endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WriteCr3.asm b/Core/CPU/x64/x64AsmLib/WriteCr3.asm
new file mode 100644
index 0000000..d028b07
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WriteCr3.asm
@@ -0,0 +1,81 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteCr3.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteCr3.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WriteCr3
+;
+; Description:
+; VOID WriteCr3(IN UINTN CR3) writes the provided value to the CR3 register.
+;
+; Input:
+; IN UINTN CR3
+; Value to be written to the CR3 register.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WriteCr3 PROC PUBLIC
+ mov cr3, rcx
+ ret
+WriteCr3 ENDP
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/WriteMsr.asm b/Core/CPU/x64/x64AsmLib/WriteMsr.asm
new file mode 100644
index 0000000..b181a5b
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/WriteMsr.asm
@@ -0,0 +1,89 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteMsr.asm 1 10/01/10 5:08p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:08p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/WriteMsr.asm $
+;
+; 1 10/01/10 5:08p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: WriteMsr
+;
+; Description:
+; VOID WriteMsr(IN UINT32 Msr, IN UINT64 Value) writes the Value to the
+; supplied MSR index, Msr.
+;
+; Input:
+; IN UINT32 Msr
+; 32-bit MSR index to be written to.
+;
+; IN UINT64 Value
+; Value to be written to MSR index.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+WriteMsr proc
+ ;rcx = MSR
+ mov rax, rdx ;rax = rdx = Value
+ and rax, 0ffffffffh ;Lower 32 bit MSR Value
+ shr rdx, 32 ;Upper 32 bit MSR Value
+ wrmsr
+ ret
+WriteMsr endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64AsmLib/checkpoint.asm b/Core/CPU/x64/x64AsmLib/checkpoint.asm
new file mode 100644
index 0000000..38edb52
--- /dev/null
+++ b/Core/CPU/x64/x64AsmLib/checkpoint.asm
@@ -0,0 +1,84 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/checkpoint.asm 1 10/01/10 5:07p Felixp $
+;
+; $Revision: 1 $
+;
+; $Date: 10/01/10 5:07p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64AsmLib/checkpoint.asm $
+;
+; 1 10/01/10 5:07p Felixp
+;
+; 1 8/24/06 12:57p Felixp
+;
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name:
+;
+; Description:
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+.code
+
+;*************************************************************************
+;<AMI_PHDR_START>
+;
+; Name: checkpoint
+;
+; Description:
+; VOID checkpoint(IN UINT8 c) writes the value c to port 0x80.
+;
+; Input:
+; IN UINT8 c
+; The value/checkpoint to write to 0x80.
+;
+; Output:
+; VOID.
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+; This routine should only be used if the PROGRESS_CODE or
+; PEI_PROGRESS_CODE macros are unavailable.
+;
+;<AMI_PHDR_END>
+;*************************************************************************
+checkpoint proc
+ mov al, cl
+ out 80h,al
+ ret
+checkpoint endp
+
+END
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
diff --git a/Core/CPU/x64/x64CLib.c b/Core/CPU/x64/x64CLib.c
new file mode 100644
index 0000000..ad96411
--- /dev/null
+++ b/Core/CPU/x64/x64CLib.c
@@ -0,0 +1,328 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/x64Core/x64CLib.c 4 7/10/09 9:30a Felixp $
+//
+// $Revision: 4 $
+//
+// $Date: 7/10/09 9:30a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/x64Core/x64CLib.c $
+//
+// 4 7/10/09 9:30a Felixp
+// Function headers are added.
+//
+// 3 10/09/06 10:11a Felixp
+// MemCpy/MemSet replaced with assembler routines
+//
+// 2 8/25/06 10:52a Felixp
+// memcpy, memset functions updated with the volotile qualifier to
+// restrain compiler optimization.
+//
+// 1 8/24/06 12:57p Felixp
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: x64CLib.c
+//
+// Description:
+// Generic CPU library functions for the x64 architecture.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <efi.h>
+
+//*************************************************************************
+// Math
+//*************************************************************************
+
+//*************************************************************************
+//<AMI_GHDR_START>
+//
+// Name: Math_64_Bit_Functions
+//
+// Description:
+// Math functions involving 64-bit input parameters designed to be usable on
+// both 32-bit and 64-bit platforms.
+//
+// Fields: Header Function Description
+// ------------------------------------------------------------------
+// AmiLib Shr64 Shift 64-bit value right.
+// AmiLib Shl64 Shift 64-bit value left.
+// AmiLib Div64 Divide 64-bit value by a 31-bit value.
+// AmiLib Mul64 Multiply 64-bit value by a 32-bit value.
+// AmiLib GetPowerOfTwo64 Determine the highest set bit in a 64-bit value.
+//
+// Notes:
+// Header details which header file contains the function prototype for
+// the above functions. Append .h to the given name.
+//
+//<AMI_GHDR_END>
+//*************************************************************************
+
+//*************************************************************************
+//<AMI_GHDR_START>
+//
+// Name: CPU_Functions
+//
+// Description:
+// CPU related functions defined in the AMI library.
+//
+// Fields: Header Function Description
+// ------------------------------------------------------------------
+// None CPULib_CpuID Perform the cpuid assembly instruction.
+// None CPULib_DisableInterrupt Disable interrupts.
+// None CPULib_EnableInterrupt Enable interrupts.
+// None CPULib_GetInterruptState Get current interrupt state (enabled or disabled).
+// None CPULIB_GetPageTable Retrieve address of the page table.
+// None CPULib_LoadGdt Load GDT.
+// None CPULib_LoadIdt Load IDT.
+// None CPULib_LockByteDec Lock preceeding byte.
+// None CPULib_LockByteInc Lock following byte.
+// None CPULib_Pause Pause CPU.
+// None CPULib_SaveGdt Save GDT at provided location.
+// None CPULib_SaveIdt Save IDT at provided location.
+// None DisableCacheInCR0 Disable CPU cache using CR0.
+// None EnableCacheInCR0 Enable CPU cache using CR0.
+// None EnableMachineCheck Enable machine check exception bit in CR4.
+// AmiLib GetCpuTimer Retrieve the CPU timer's value.
+// None GetCsSegment Retrieve the code segment.
+// None HltCpu Halt the CPU.
+// None WaitForever Perform infinite loop.
+// None WaitForSemaphore Wait for semaphore to become available. then take control.
+// None WaitUntilZero32 Wait until a 32-bit memory region becomes zero.
+// None WaitUntilZero8 Wait until an 8-bit meomry region becomes zero.
+// None WriteMsr Write a value to a MSR.
+// None ReadMsr Read value from a MSR.
+// AmiLib WriteCr3 Write a value to CR3.
+// AmiLib ReadCr3 Read value from CR3.
+// None ReadRtdsc Retrieve the time stamp counter.
+//
+// Notes:
+// Header details which header file contains the function prototype for
+// the above functions. Append .h to the given name.
+//
+//<AMI_GHDR_END>
+//*************************************************************************
+
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Shr64
+//
+// Description:
+// UINT64 Shr64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// right the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted.
+//
+// IN UINT8 Shift
+// The number of bits to shift right.
+//
+// Output:
+// UINT64 Value shifted right Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Shr64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ return Value>>Shift;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Shl64
+//
+// Description:
+// UINT64 Shl64(IN UINT64 Value, IN UINT8 Shift) shifts the 64-bit Value
+// left the provided number of bits, Shift.
+//
+// Input:
+// IN UINT64 Value
+// The value to be shifted left.
+//
+// IN UINT8 Shift
+// The number of bits to shift.
+//
+// Output:
+// UINT64 Value shifted left Shift number of bits.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Shl64(
+ IN UINT64 Value,
+ IN UINT8 Shift
+ )
+{
+ return Value<<Shift;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Div64
+//
+// Description:
+// UINT64 Div64(IN UINT64 Dividend, IN UINTN Divisor,
+// OUT UINTN *Remainder OPTIONAL) divides a 64-bit number, Dividend, by the
+// Divisor, which can be up to 31-bits.
+//
+// Input:
+// IN UINT64 Dividend
+// The 64-bit number to be divided.
+//
+// IN UINT Divisor
+// The number to divide Dividend by; may not exceed 31-bits in size.
+//
+// OUT UINTN *Remainder OPTIONAL
+// The remainder of the division. Provide NULL if undesired; otherwise user
+// is responsible for handling the necessary memory resources.
+//
+// Output:
+// UINT64 result of dividing Dividend by Divisor.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Div64 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result = Dividend/Divisor;
+ if (Remainder) *Remainder=Dividend%Divisor;
+ return Result;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: Mul64
+//
+// Description:
+// UINT64 Mul64(IN UINT64 Value64, IN UINTN Value32) multiplies a 64-bit
+// number by a 32-bit number and returns the 64-bit result.
+//
+// Input:
+// IN UINTN64 Value64
+// The 64-bit number to multiply by.
+//
+// IN UINTN Value32
+// The 32-bit number to multiply by.
+//
+// Output:
+// UINT64 result of multiplying Value64 by Value32.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT64 Mul64(
+ IN UINT64 Value64,
+ IN UINTN Value32
+ )
+{
+ return Value64*Value32;
+}
+
+//*************************************************************************
+// Memory Operations
+//*************************************************************************
+
+VOID MemSet(VOID* pBuffer, UINTN Count, UINT8 Value);
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: memset
+//
+// Description:
+// VOID memset(IN VOID *pBuffer, IN UINT8 Value, IN UINTN Count) is a
+// wrapper for MemSet which fills Count bytes of memory in pBuffer with
+// Value.
+//
+// Input:
+// IN VOID *pBuffer
+// The starting location in memory where to begin filling.
+//
+// IN UINT8 Value
+// The value to fill memory with starting at pBuffer.
+//
+// IN UINTN Count
+// The number of bytes to fill with Value.
+//
+// Output:
+// VOID.
+//
+// Modified:
+//
+// Referrals:
+// MemSet
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID memset(VOID* pBuffer, UINTN Value, UINTN Count)
+{
+ MemSet(pBuffer,Count,(UINT8)Value);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CPU/x64/x64Core.cif b/Core/CPU/x64/x64Core.cif
new file mode 100644
index 0000000..0d92f09
--- /dev/null
+++ b/Core/CPU/x64/x64Core.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "x64 Core"
+ category = ModulePart
+ LocalRoot = "Core\CPU\x64\"
+ RefName = "x64Core"
+[files]
+"x64Core.sdl"
+"x64rules.mak"
+<endComponent>
diff --git a/Core/CPU/x64/x64Core.sdl b/Core/CPU/x64/x64Core.sdl
new file mode 100644
index 0000000..389aa0f
--- /dev/null
+++ b/Core/CPU/x64/x64Core.sdl
@@ -0,0 +1,112 @@
+TOKEN
+ Name = "x64_BUILD"
+ Value = "0"
+ Help = "Main switch to enable x64 support in Project\DO REBUILD ALL AFTER CHANGING THIS SWITCH!!!"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "GLOBAL_DEFINES_x64"
+ Value = "/DEFIx64 /DEFIX64"
+ Help = "Global x64-specific macro definitions. Added to CFLAGSx64 and AFLAGSx64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CC"
+ Value = "$(SILENT)$(CCX64DIR)\CL"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LINK"
+ Value = "$(SILENT)$(CCX64DIR)\LINK"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LIBEXE"
+ Value = "$(SILENT)$(CCX64DIR)\LINK /LIB"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CCPEI"
+ Value = "$(SILENT)$(CCX86DIR)\CL"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LINKPEI"
+ Value = "$(SILENT)$(CCX86DIR)\LINK"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LIBEXEPEI"
+ Value = "$(SILENT)$(CCX86DIR)\LINK /LIB"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CFLAGSx64"
+ Value = "/GS- $(GLOBAL_DEFINES_x64)"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ASMx64"
+ Value = "$(SILENT)$(CCX64DIR)\ML64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "AFLAGSx64"
+ Value = "$(GLOBAL_DEFINES_x64) /Cp"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LFLAGSx64"
+ Value = "/MACHINE:AMD64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CP"
+ Value = "$(SILENT)$(CCX64DIR)\CL /nologo /EP"
+ Help = "C preprocessor"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "x64Core_DIR"
+End
+
+ELINK
+ Name = "x64"
+ Parent = "IA32"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(x64Core_DIR)\x64rules.mak"
+ Parent = "$(IA32Core_DIR)\IA32rules.mak"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/CPU/x64/x64rules.mak b/Core/CPU/x64/x64rules.mak
new file mode 100644
index 0000000..ed1ab3c
--- /dev/null
+++ b/Core/CPU/x64/x64rules.mak
@@ -0,0 +1,86 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/x64Core/x64rules.mak 3 8/02/07 1:33a Felixp $
+#
+# $Revision: 3 $
+#
+# $Date: 8/02/07 1:33a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/x64Core/x64rules.mak $
+#
+# 3 8/02/07 1:33a Felixp
+# minor modification to use newly defined COMPONENT_BUILD_RULES macro
+# defined in rules.mak
+#
+# 2 3/13/07 11:53a Felixp
+# Global and CPU architecture specific macros are now passed
+# to C preprocessor (used during DepEx and VFR compilation)
+#
+# 1 10/13/06 8:31p Felixp
+#
+# 3 9/05/06 6:03p Felixp
+# define PROCESSOR is IA32 when building PEI components in x64 build.
+#
+# 2 8/25/06 11:12a Felixp
+#
+# 1 8/24/06 12:57p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: x64rules.mak
+#
+# Description: Defines x64-specific build rules.
+# This file is included into the template makefile rules.mak
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF "$(COMPONENT_BUILD_RULES)"=="PEI"
+# IA32 Build
+CC = $(CCPEI)
+LINK = $(LINKPEI)
+LIBEXE=$(LIBEXEPEI)
+
+LIB_BUILD_DIR=$(BUILD_ROOT)\IA32
+!UNDEF PROCESSOR
+PROCESSOR=IA32
+!INCLUDE $(IA32Core_DIR)\IA32rules.mak
+
+!ELSE
+# x64 Build
+ASM=$(ASMx64)
+
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) $(CFLAGSx64)
+EXTRA_LFLAGS=$(EXTRA_LFLAGS) $(LFLAGSx64)
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) $(AFLAGSx64)
+EXTRA_AFLAGS16=$(EXTRA_AFLAGS16) $(GLOBAL_DEFINES_x64)
+CPFLAGS=$(CPFLAGS) $(GLOBAL_DEFINES_x64)
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CSPLib/CSP Library.chm b/Core/CSPLib/CSP Library.chm
new file mode 100644
index 0000000..9aca1b6
--- /dev/null
+++ b/Core/CSPLib/CSP Library.chm
Binary files differ
diff --git a/Core/CSPLib/CspLib.CIF b/Core/CSPLib/CspLib.CIF
new file mode 100644
index 0000000..c53fab8
--- /dev/null
+++ b/Core/CSPLib/CspLib.CIF
@@ -0,0 +1,20 @@
+<component>
+ name = "CSP Library"
+ category = eBoard
+ LocalRoot = "Core\CSPLib\"
+ RefName = "CSP Library"
+[files]
+"CspLib.sdl"
+"CspLib.mak"
+"CspLibPei.C"
+"CspLibDxe.C"
+"CspLibDxe.Dxs"
+"CspLibGeneric.C"
+"CspLibGeneric.h"
+"CSP Library.chm"
+"FID.c"
+[parts]
+"CSP Library Include"
+"CSP Library Protocols"
+"CSP Library PPIs"
+<endComponent>
diff --git a/Core/CSPLib/CspLib.mak b/Core/CSPLib/CspLib.mak
new file mode 100644
index 0000000..990087e
--- /dev/null
+++ b/Core/CSPLib/CspLib.mak
@@ -0,0 +1,251 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLib.mak 25 3/15/11 5:24p Felixp $
+#
+# $Revision: 25 $
+#
+# $Date: 3/15/11 5:24p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLib.mak $
+#
+# 25 3/15/11 5:24p Felixp
+# Include $(CSP_LIB_DIR)\CspLibGeneric.h at the beginning of
+# AMICSPLIBINc.h
+#
+# 24 2/22/11 3:48p Artems
+# EIP 51548 - replaced TABs with spaces
+#
+# 23 2/22/11 12:38p Artems
+# Updated file header. Removed dependency of Fid.c from Fid.ffs (EIP
+# 52936)
+#
+# 20 5/25/10 6:06p Artems
+# Fixed bug, use CORE_COMBINED_VERSION instead of CORE_REVISION
+#
+# 19 5/21/10 4:38p Artems
+# Changed backward compatibility token from CORE_REVISION to
+# CORE_COMBINED_VERSION
+#
+# 18 5/07/10 3:57p Artems
+# Build CSP library separately for PEI and DXE phase
+#
+# 17 5/06/10 12:22p Artems
+# EIP 38241 - $FID signature is absent
+#
+# 16 4/05/10 5:50p Artems
+# Added Core 4.6.3 backward compatibility fix
+#
+# 15 3/25/10 3:07p Artems
+# EIP 33953: Added eLink infrastructure to support runtime shadow ram
+# writing
+#
+# 14 12/02/09 4:52p Robert
+# Added changes for support for Revision 2 of the Firmware Version
+# Structure
+#
+# 13 8/26/09 10:59a Robert
+# Adding back the changes from checkin #11. This was accidentally
+# overwritten in checkin #12
+#
+# 12 8/14/09 10:47a Robert
+# Added FID.asm to the component for compliance with AMI Utility
+# specification
+#
+# 11 8/11/09 12:34p Felixp
+# Improvement (EIP 24965). New method of contributing files to CspLib
+# library. Modules that contribute files to CspLib should now use new
+# notation.
+# 1. AMI_CSP_LIB_INCLUDE_FILES is replaced with dependency from
+# $(BUILD_DIR)\AMICSPLIBInc.H (no plus needed between files)
+# 2. AMI_CSP_LIB_OBJS is replaced with dependency from AMICSPLibBin
+# 3. AMI_CSP_LIB_LIBRARY_PATH should not be used
+# Items #1 & #2 are improvements. Old macros based approach only worked
+# for modules that are above than CspLib in the project tree.
+# Item #3 is a cleanup.
+#
+# 10 6/11/09 5:43p Robert
+# Comment updates for CHM and coding standard
+#
+# 9 10/13/07 11:41p Michaela
+# Added CspLibGeneric.c to CSP library
+#
+# 8 8/25/06 11:02a Felixp
+#
+# 7 8/24/06 3:40p Felixp
+# Preliminary x64 support (work in progress)
+#
+# 6 12/08/05 11:19a Felixp
+#
+# 5 11/21/05 6:51p Felixp
+# dependency for $(BUILD_DIR)\AMICSPLIBInc.H added
+#
+# 4 10/12/05 8:38p Felixp
+# CspLibPei is no longer a separate FFS file. It is now linked with PEI
+# Core
+# CspLib.mak,CspLib.lib, and CspLib.cif modified.
+# CspLibPei.dxe removed
+#
+# 3 4/19/05 2:52p Sivagarn
+# Changed the dependency order
+#
+# 2 3/25/05 11:44a Sivagarn
+# Fixed a build issue related to wrong dependency
+#
+# 1 1/21/05 12:46p Sivagarn
+# Initial Checkin - Version 0.05
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#---------------------------------------------------------------------------
+# Name: CspLib.mak
+#
+# Description:
+# Make file for the CSP Library. CSP library contains all library
+# functions related to chipset and CPU. The main idea for this library is
+# to consolidate porting hooks related to various components
+# (like CSM, SMM etc) in respective chipset files say NB, SB, CPU etc.
+# This library can be built us a LIB file or as various FFS files.
+# The MACROS and library init functions mask the actual implementation
+# which is controlled by the SDL token
+#
+#---------------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+all : AMICSPLib $(BUILD_DIR)\AMICSPLIBInc.H
+
+!IF "$(CORE_COMBINED_VERSION)"==""
+CORE_COMBINED_VERSION=0x40280
+!ENDIF
+
+!IF $(CORE_COMBINED_VERSION) >= 0x40280
+$(AMICSPLib) : $(BUILD_DIR)\AMICSPLIBInc.H AMICSPLib $(BUILD_DIR)\Fid.ffs AMICspLibPei AMICspLibDxe
+!ELSE
+$(AMICSPLib) : $(BUILD_DIR)\AMICSPLIBInc.H AMICSPLib AMICspLibPei AMICspLibDxe
+!ENDIF
+
+CSP_LIB_DIR = Core\CspLib
+
+AMICSPLib : $(BUILD_DIR)\AMICSPLib.mak AMICSPLibBin
+
+$(BUILD_DIR)\AMICspLib.mak : $(CSP_LIB_DIR)\CSPLib.cif $(CSP_LIB_CIF_FILES) $(CSP_LIB_DIR)\CspLib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(CSP_LIB_DIR)\CSPLib.cif $(CIF2MAK_DEFAULTS) $(CSP_LIB_CIF_FILES)
+
+#---------------------------------------------------------------------------
+# Add Generic Functions to CSP Library
+#---------------------------------------------------------------------------
+
+AMICSPLibBin : $(BUILD_DIR)\CspLibGeneric.obj
+
+{$(CSP_LIB_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /D\"RUNTIME_SHADOW_RAM_WRITE_LIST=$(RuntimeShadowRamWrite)\" /I $(CSP_LIB_DIR) /Fo$(BUILD_DIR)\ $<
+
+$(BUILD_DIR)\CspLibGeneric.obj : $(CSP_LIB_DIR)\CspLibGeneric.c
+
+#---------------------------------------------------------------------------
+# Generate CSP Library
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\AMICSPLIBInc.H : $(AMI_CSP_LIB_INCLUDE_FILES:+= )
+ $(ECHO) #include"$(BUILD_DIR)\token.h" > $@
+ $(ECHO) #include"$(CSP_LIB_DIR)\CspLibGeneric.h" >> $@
+ $(SILENT) for %%f in ($(**:"=)) do $(ECHO) #include"%%f" >> $@
+
+AMICSPLibBin : $(AMI_CSP_LIB_OBJS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMICSPLib.mak all\
+ NAME=AMICSPLib\
+ OBJECTS=\
+ TYPE=LIBRARY
+ $(MAKE) /$(MAKEFLAGS) BUILD_ROOT=$(BUILD_DIR) "EXT_OBJS=$(**:Build\=Build\IA32\)" PROJECT_DIR=$(PROJECT_DIR)\
+ /f $(BUILD_DIR)\AMICSPLib.mak all\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ NAME=AMICSPLib\
+ OBJECTS=\
+ TYPE=PEI_LIBRARY
+
+#---------------------------------------------------------------------------
+# Generate CSP Library PEI
+#---------------------------------------------------------------------------
+CORE_PEIBin : $(BUILD_DIR)\CspLibPei.lib
+
+$(BUILD_DIR)\CspLibPei.lib : $(BUILD_DIR)\AMICSPLib.mak AMICspLibPei
+
+CSP_LIB_PEI_OBJECTS =\
+$$(BUILD_DIR)\$(CSP_LIB_DIR)\CspLibPei.obj
+
+!IF $(CORE_COMBINED_VERSION) >= 0x40280
+
+$(BUILD_DIR)\Fid.ffs : $(BUILD_DIR)\AMICspLib.mak
+ $(MAKE) /$(MAKEFLAGS) EXT_OBJS= $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMICspLib.mak bin\
+ NAME=Fid OBJECTS=$(BUILD_DIR)\$(CSP_LIB_DIR)\Fid.obj\
+ MAKEFILE=$(BUILD_DIR)\AMICspLib.mak \
+ TYPE=BINARY
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=3FD1D3A2-99F7-420b-BC69-8BB1D492A332 \
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ FFSFILE=$@ COMPRESS=0 NAME=$(@B)\
+ RESOURCE=$(BUILD_DIR)\Fid.bin \
+ SECTION_GUID=2EBE0275-6458-4AF9-91ED-D3F4EDB100AA \
+
+!ELSE
+
+CSP_LIB_PEI_OBJECTS =\
+$(CSP_LIB_PEI_OBJECTS)\
+$$(BUILD_DIR)\$(CSP_LIB_DIR)\Fid.obj
+
+!ENDIF
+
+AMICspLibPei : $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMICspLib.mak all\
+ NAME=CspLibPei\
+ MAKEFILE=$(BUILD_DIR)\AMICspLib.mak \
+ OBJECTS="$(CSP_LIB_PEI_OBJECTS)" \
+ TYPE=PEI_LIBRARY
+
+
+#---------------------------------------------------------------------------
+# Generate CSP Library DXE
+#---------------------------------------------------------------------------
+AMICspLibDxe :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMICspLib.mak all\
+ NAME=CspLibDxe\
+ MAKEFILE=$(BUILD_DIR)\AMICspLib.mak \
+ GUID=CD84562C-6864-40a3-A081-C8D35E82B920 \
+ OBJECTS=$(BUILD_DIR)\$(CSP_LIB_DIR)\CspLibDxe.obj \
+ DEPEX1=$(CSP_LIB_DIR)\CspLibDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ ENTRY_POINT=CspLibDxe_Init \
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/CSPLib/CspLib.sdl b/Core/CSPLib/CspLib.sdl
new file mode 100644
index 0000000..cb5e5d4
--- /dev/null
+++ b/Core/CSPLib/CspLib.sdl
@@ -0,0 +1,107 @@
+TOKEN
+ Name = "CSPLIB_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CSP Library support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CSP_LIBRARY"
+ Value = "1"
+ Help = "Build as library"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMICSPLib"
+ Value = "$$(LIB_BUILD_DIR)\AmiCSPLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CSP_LIB_MAJOR_VER"
+ Value = "00"
+ Help = "CSP Library Major Version Number.\ DO NOT CHANGE THIS VALUE"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "CSP_LIB_MINOR_VER"
+ Value = "17"
+ Help = "CSP Library Minor Version Number.\ DO NOT CHANGE THIS VALUE"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "BIOS_TAG"
+ Value = "$(PROJECT_TAG)$(PROJECT_MAJOR_VERSION)$(PROJECT_MINOR_VERSION)"
+ Help = "BIOS Tag inserted into Firmware ID structure.\9 characters. \5 characters of project tag followed by 3 characters of project version and terminating zero"
+ TokenType = Expression
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FW_VERSION_GUID"
+ Value = "{0xb5c59087, 0xfeac, 0x4b41, {0x9d, 0x80, 0x79, 0xb, 0xa5, 0xaa, 0x7, 0xf}}"
+ Help = "FW Version GUID inserted into Firmware ID structure.\FW version has to be overridden for every project."
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+End
+
+MODULE
+ Help = "Includes CSPLib.mak to Project"
+ File = "CspLib.mak"
+End
+
+ELINK
+ Name = "CSP_LIB_CIF_FILES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CspLibDxe.ffs"
+ Parent = "FV_MAIN"
+ Help = "CSP Library DXE Component"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/I $(BUILD_DIR) "
+ Parent = "CFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CspLibPei_Init,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RuntimeShadowRamWrite"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\fid.ffs"
+ Parent = "FV_BB"
+ Token = "CORE_COMBINED_VERSION" ">=" "0x40280"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/CSPLib/CspLibDxe.C b/Core/CSPLib/CspLibDxe.C
new file mode 100644
index 0000000..499cf55
--- /dev/null
+++ b/Core/CSPLib/CspLibDxe.C
@@ -0,0 +1,104 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//
+// $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibDxe.C 3 2/22/11 3:36p Artems $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/11 3:36p $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibDxe.C $
+//
+// 3 2/22/11 3:36p Artems
+// EIP 51548 - Added AMI copyright headers, replaced TABs with spaces
+//
+// 2 6/11/09 5:43p Robert
+// Comment updates for CHM and coding standard
+//
+// 1 1/21/05 12:46p Sivagarn
+// Initial Checkin - Version 0.05
+//
+//
+//*****************************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CspLibDxe.C
+//
+// Description: This file contains code for Generic Csp protocols such as
+// PCI table init etc
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+// Module specific Includes
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+
+#include "protocol\CspLibProtocols.h"
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CspLibDxe_Init
+//
+// Description:
+// This function is the entry point for this DXE. This function installs
+// necessary Csp protocols
+//
+// Input:
+// EFI_HANDLE ImageHandle - Image handle
+// EFI_SYSTEM_TABLE SystemTable - Pointer to the system table
+//
+// Output:
+// Return Status currently always EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CspLibDxe_Init (
+IN EFI_HANDLE ImageHandle,
+IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+
+ return Status;
+
+}
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CSPLib/CspLibDxe.Dxs b/Core/CSPLib/CspLibDxe.Dxs
new file mode 100644
index 0000000..0c58b73
--- /dev/null
+++ b/Core/CSPLib/CspLibDxe.Dxs
@@ -0,0 +1,67 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//
+// $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibDxe.Dxs 3 2/22/11 3:35p Artems $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/11 3:35p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibDxe.Dxs $
+//
+// 3 2/22/11 3:35p Artems
+// EIP 51548 - Added AMI copyright headers, replaced TABs with spaces
+//
+// 2 6/11/09 5:43p Robert
+// Comment updates for CHM and coding standard
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CspLibDxe.DXS
+//
+// Description: This file is the dependency file for the CspLib DXE
+// driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Protocol\Cpu.h>
+
+DEPENDENCY_START
+ EFI_CPU_ARCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/CSPLib/CspLibGeneric.C b/Core/CSPLib/CspLibGeneric.C
new file mode 100644
index 0000000..6b96877
--- /dev/null
+++ b/Core/CSPLib/CspLibGeneric.C
@@ -0,0 +1,399 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//
+// $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibGeneric.C 7 11/12/11 6:39p Artems $
+//
+// $Revision: 7 $
+//
+// $Date: 11/12/11 6:39p $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibGeneric.C $
+//
+// 7 11/12/11 6:39p Artems
+// Added functions for TopSwap functionality
+//
+// 6 2/22/11 3:33p Artems
+// EIP 51548 - Added AMI copyright headers, replaced TABs with spaces
+//
+// 5 3/31/10 11:31a Artems
+// Updated function help header
+//
+// 4 3/29/10 3:58p Artems
+// Fixed OemRuntimeShadowRamWrite function help header
+//
+// 3 3/25/10 3:07p Artems
+// EIP 33953: Added eLink infrastructure to support runtime shadow ram
+// writing
+//
+// 2 6/11/09 5:43p Robert
+// Comment updates for CHM and coding standard
+//
+// 1 10/13/07 11:27p Michaela
+// Initial Checkin
+//
+// 1 10/05/07 7:02a Michaela
+// Initial checkin.
+//
+//*****************************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CspLibGeneric.c
+//
+// Description: This file contains generic code to add functionality that can
+// be used by any module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Token.h>
+#include "CspLibGeneric.h"
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateMultiplePpi
+//
+// Description:
+// This function wraps the initialization and error checking of LocatePpi()
+// in a table, in order to reduce code size in functions that use several PPI.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices - Instance of a pointer to the PeiServices pointer
+// UINT32 PpiTableSize - Size of argument table
+// PPI_LOCATE_STRUCT *Ppi - Table of arguments for LocatePpi()
+//
+// Output:
+// Pointers in PPI_LOCATE_STRUCT are updated
+// Status is returned with values defined by the LocatePpi function
+//
+// Note:
+// This function will use a Guid pointer or a Guid value defined locally
+// in the PPI_LOCATE_STRUCT of the caller.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LocateMultiplePpi (
+ EFI_PEI_SERVICES **PeiServices,
+ UINT32 PpiTableSize,
+ PPI_LOCATE_STRUCT *Ppi
+)
+{
+ EFI_STATUS Status;
+ UINT32 i;
+ EFI_PEI_LOCATE_PPI Locate = (*PeiServices)->LocatePpi;
+
+ for (i = 0; i < PpiTableSize; i++) {
+ //-------------------------------------------
+ // locate the PPI (or) break on error
+ Status = Locate( PeiServices,
+ (Ppi[i].Guid.Data1 == 0)
+ ? Ppi[i].GuidPtr : &Ppi[i].Guid,
+ Ppi[i].Instance,
+ Ppi[i].Descriptor,
+ Ppi[i].Ptr );
+ if (EFI_ERROR(Status)){
+ break;
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateMultipleProtocol
+//
+// Description:
+// This function wraps the initialization and error checking of
+// LocateProtocol() in a table, in order to reduce code size in functions
+// that use several Protocol.
+//
+// Input:
+// EFI_BOOT_SERVICES *pBS - Instance of a pointer to the Boot Services Table
+// UINT32 ProtocolTableSize - Number of Protocols in the table
+// PROTOCOL_LOCATE_STRUCT *Protocol - Table of Parameters for LocateProtocol
+//
+// Output:
+// Pointers in PROTOCOL_LOCATE_STRUCT are updated
+// Status is returned with values defined by the LocateProtocol function
+//
+// Note:
+// This function will use a Guid pointer or a Guid value defined locally in
+// the PROTOCOL_LOCATE_STRUCT of the caller.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LocateMultipleProtocol (
+ EFI_BOOT_SERVICES *pBS,
+ UINT32 ProtocolTableSize,
+ PROTOCOL_LOCATE_STRUCT *Protocol
+)
+{
+ EFI_STATUS Status;
+ UINT32 i;
+ EFI_LOCATE_PROTOCOL Locate = pBS->LocateProtocol;
+
+ for (i = 0; i < ProtocolTableSize; i++) {
+ //-------------------------------------------
+ // locate the PPI (or) break on error
+ Status = Locate((Protocol[i].Guid.Data1 == 0)
+ ? Protocol[i].GuidPtr
+ : &Protocol[i].Guid,
+ Protocol[i].Registration,
+ Protocol[i].Interface );
+ if (EFI_ERROR(Status)){
+ break;
+ }
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiWritePci
+//
+// Description:
+// This function writes a value to a PCI register using a PCI_CONTROL
+// structure to simplify the call.
+//
+// Input:
+// PEI_PCI_ARGS *Pci - control structure
+//
+// Output:
+// Status is returned with values defined in the PCI PPI Write function
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiWritePci (
+ PEI_PCI_ARGS *Pci
+)
+{
+ EFI_STATUS Status;
+ Status = Pci->Cfg->Write( Pci->PeiServices,
+ Pci->Cfg,
+ Pci->Width,
+ Pci->Address,
+ Pci->Value );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiReadPci
+//
+// Description:
+// This function reads the value in a PCI Register using a PCI_CONTROL
+// structure to simplify the call.
+//
+// Input:
+// PEI_PCI_ARGS *Pci - control structure
+//
+// Output:
+// Pci->Value is updated with the value read from the PCI device
+// Status is returned with values defined in the PCI PPI Read function
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiReadPci (
+ PEI_PCI_ARGS *Pci
+)
+{
+ EFI_STATUS Status;
+ Status = Pci->Cfg->Read( Pci->PeiServices,
+ Pci->Cfg,
+ Pci->Width,
+ Pci->Address,
+ Pci->Value );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RbReadPci
+//
+// Description:
+// This function reads the value(s) in a PCI Register using a RTBRG_PCI_ARGS
+// structure to simplify the call.
+//
+// Input:
+// RTBRG_PCI_ARGS *Arg - pointer to an instance of RTBRG_PCI_ARGS that contains parameters to the RootBrg PCI Read Function
+//
+// Output:
+// Arg->Buffer is filled with the data read from the PCI device
+// Return the status returned by the PCI Read funcntion of the Root Bridge protocol
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS RbReadPci (
+ RTBRG_PCI_ARGS *Arg
+)
+{
+ EFI_STATUS Status =
+ Arg->RtBrdg->Pci.Read( Arg->RtBrdg,
+ Arg->Width,
+ Arg->Address,
+ Arg->Count,
+ Arg->Buffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RbWritePci
+//
+// Description:
+// This function writes the value(s) in a PCI Register using a RTBRG_PCI_ARGS
+// structure to simplify the call.
+//
+// Input:
+// RTBRG_PCI_ARGS *Arg - pointer to an instance of RTBRG_PCI_ARGS that contains parameters to the RootBrg PCI Read Function
+//
+// Output:
+// Return the status
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS RbWritePci (
+ RTBRG_PCI_ARGS *Arg
+)
+{
+ EFI_STATUS Status =
+ Arg->RtBrdg->Pci.Write( Arg->RtBrdg,
+ Arg->Width,
+ Arg->Address,
+ Arg->Count,
+ Arg->Buffer);
+ return Status;
+}
+
+//************** Runtime Shadow Ram access support ****************************
+typedef VOID (RUNTIME_SHADOW_RAM_WRITE)(
+ IN BOOLEAN Enable
+);
+
+extern RUNTIME_SHADOW_RAM_WRITE RUNTIME_SHADOW_RAM_WRITE_LIST EndOfList;
+RUNTIME_SHADOW_RAM_WRITE* RuntimeShadowRamWriteList[] = {RUNTIME_SHADOW_RAM_WRITE_LIST NULL};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemRuntimeShadowRamWrite
+//
+// Description: This function enables or disables runtime writing to shadow RAM
+// (E000-F000 segment)
+//
+//
+// Input:
+// IN BOOLEAN Enable - if TRUE - enable writing to shadow region
+// if FALSE - disable writing to shadow region
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemRuntimeShadowRamWrite(
+ IN BOOLEAN Enable
+)
+{
+ UINTN i;
+
+ for (i = 0; RuntimeShadowRamWriteList[i]; i++)
+ RuntimeShadowRamWriteList[i](Enable);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsTopSwapOn
+//
+// Description: This function checks if TopSwap (A16 address line inversion)
+// is on
+//
+//
+// Input:
+// None
+//
+// Output:
+// TRUE - TopSwap is ON
+// FALSE - TopSwap is OFF
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsTopSwapOn(
+ VOID
+)
+{
+ volatile UINT8* Address8;
+
+ Address8 = (UINT8 *)(SB_RCBA + SB_BACKED_UP_CONTROL_REGISTER);
+
+ return ((*Address8) & 1) ? TRUE : FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetTopSwap
+//
+// Description: This function sets TopSwap (A16 address line inversion) ON or OFF
+//
+// Input:
+// BOOLEAN On - if TRUE, set TopSwap to ON, if FALSE - set to OFF
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetTopSwap(
+ IN BOOLEAN On
+)
+{
+ volatile UINT8* Address8;
+
+ Address8 = (UINT8 *)(SB_RCBA + SB_BACKED_UP_CONTROL_REGISTER);
+
+ if (On) {
+ *Address8 |= 1;
+ } else {
+ *Address8 &= 0xFE;
+ }
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/CSPLib/CspLibGeneric.h b/Core/CSPLib/CspLibGeneric.h
new file mode 100644
index 0000000..0c24d1f
--- /dev/null
+++ b/Core/CSPLib/CspLibGeneric.h
@@ -0,0 +1,444 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//
+// $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibGeneric.h 6 11/12/11 6:39p Artems $
+//
+// $Revision: 6 $
+//
+// $Date: 11/12/11 6:39p $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibGeneric.h $
+//
+// 6 11/12/11 6:39p Artems
+// Added functions for TopSwap functionality
+//
+// 5 7/14/11 3:19p Artems
+// EIP 64106: Updated source to be UEFI 2.3.1 and PI 1.2 compliant
+//
+// 4 2/22/11 3:31p Artems
+// EIP 51548 - Added AMI copyright headers, replaced TABs with spaces
+//
+// 3 3/25/10 3:08p Artems
+// EIP 33953: Added eLink infrastructure to support runtime shadow ram
+// writing
+//
+// 2 6/11/09 5:43p Robert
+// Comment updates for CHM and coding standard
+//
+// 1 10/13/07 11:29p Michaela
+// Initial Checkin
+//
+//
+//*****************************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CspLibGeneric.h
+//
+// Description: This file contains generic code to add functionality that can
+// be used by any module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __CSP_LIB_GENERIC__H__
+#define __CSP_LIB_GENERIC__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <efi.h>
+#include <pei.h>
+#include <Protocol\PciRootBridgeIo.h>
+
+#ifndef GUID_ZERO
+#define GUID_ZERO \
+{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
+GUID_VARIABLE_DECLARATION(GuidZero, GUID_ZERO);
+#endif
+
+
+//<AMI_MHDR_START>
+//----------------------------------------------------------------------------
+// Name: AMI_TRACE
+//
+// Description:
+// This general-purpose, phase-independent macro allows debugging
+// messages in code that is shared between PEI and DXE phases.
+//
+// Input:
+// Identical to TRACE (Type must be AMI_TRACE_ALWAYS)
+//
+// Notes:
+// For PEI phase, this macro assumes the identifier PeiServices is
+// defined.
+//
+// The usage of this macro is identical to TRACE with the exception that
+// the type must always be AMI_TRACE_ALWAYS:
+//
+// AMI_TRACE((AMI_TRACE_ALWAYS, "Hello World\n"));
+//
+//----------------------------------------------------------------------------
+//<AMI_MHDR_END>
+
+#if ( defined(TRACE) )
+ #define AMI_TRACE(args) TRACE(args)
+ #define AMI_TRACE_ALWAYS TRACE_ALWAYS
+#elif ( defined(PEI_TRACE) )
+ //------------------------------------------------------------------------
+ // Generate a compiler message to help identify the build error if
+ // PeiServices is not defined in the calling function.
+ //------------------------------------------------------------------------
+ #pragma message("AMI_TRACE requires identifier definition: EFI_PEI_SERVICES **PeiServices")
+ #define AMI_TRACE(args) PEI_TRACE(args)
+ #define AMI_TRACE_ALWAYS TRACE_ALWAYS,PeiServices
+#else
+ #define AMI_TRACE(args)
+ #define AMI_TRACE_ALWAYS
+#endif
+
+
+//<AMI_MHDR_START>
+//----------------------------------------------------------------------------
+// Name: ABORT_ERROR
+//
+// Description:
+// This phase-independent macro can be used to force premature
+// return from a function on error, displaying a message if possible and
+// returning the EFI_STATUS value of the error. (For compatibility,
+// ABORT_CALL is also defined as a synonym for this macro.)
+//
+// Input:
+// arg - type must be EFI_STATUS
+//
+// Notes:
+// Use the macro with a function call to save screen/source file
+// real estate:
+//
+// ABORT_ERROR(FunctionCall(...));
+//
+// The macro is replaced with the following:
+//
+// {
+// EFI_STATUS Status = FunctionCall(...);
+// if (EFI_ERROR(Status)){
+// ...message with file name, line number and function name...
+// return Status;
+// }
+// }
+//
+//----------------------------------------------------------------------------
+//<AMI_MHDR_END>
+
+#define ABORT_ERROR(arg) { \
+ EFI_STATUS Status = arg; \
+ if ( EFI_ERROR( Status ) ) \
+ { \
+ AMI_TRACE((AMI_TRACE_ALWAYS, \
+ "\n\nABORT Error in %s \nLine %i: %s\n\n\n",__FILE__, __LINE__, #arg)); \
+ return Status; \
+ } }
+#ifndef ABORT_CALL
+#define ABORT_CALL(arg) ABORT_ERROR(arg)
+#endif
+
+
+//<AMI_MHDR_START>
+//----------------------------------------------------------------------------
+// Name: ABORT_ERROR_STATUS
+//
+// Description:
+// This phase-independent macro can be used to force premature
+// return from a function on error, displaying a message if possible and
+// returning the caller-specified value in the event of an error.
+// (For compatibility, ABORT_CALL_STATUS is also defined as a
+// synonym for this macro.)
+//
+// Input:
+// status - value to return (no type constraint)
+// arg - type must be EFI_STATUS
+//
+// Notes:
+// Use the macro with a function call to save screen/source file
+// real estate (note: the return value is discarded):
+//
+// ABORT_ERROR_STATUS(MyErrorValue, FunctionCall(...));
+//
+// The macro is replaced with the following:
+//
+// {
+// if (EFI_ERROR( FunctionCall(...) ) ){
+// ...message with file name, line number and function name...
+// return MyErrorValue;
+// }
+// }
+//
+//----------------------------------------------------------------------------
+//<AMI_MHDR_END>
+
+#define ABORT_ERROR_STATUS(retval, arg) { \
+ if ( EFI_ERROR(arg) ) \
+ { \
+ AMI_TRACE((AMI_TRACE_ALWAYS, \
+ "\n\nABORT Error in %s \nLine %i: %s\n\n\n",__FILE__, __LINE__, #arg)); \
+ return (retval); \
+ } }
+#ifndef ABORT_CALL_STATUS
+#define ABORT_CALL_STATUS(retval, arg) ABORT_ERROR_STATUS(retval, arg)
+#endif
+
+
+//<AMI_MHDR_START>
+//----------------------------------------------------------------------------
+// Name: STOP_ERROR
+//
+// Description:
+// This phase-independent macro can be used to force an infinite loop
+// on error, ensuring execution does not continue past the error and
+// easing the burden of locating the source of the error. A message is
+// displayed if possible. (For compatibility, ASSERT_CALL is
+// also defined as a synonym for this macro.)
+//
+// Input:
+// arg - type must be EFI_STATUS
+//
+// Notes:
+// Use the macro with a function call to save screen/source file
+// real estate (note: the return value is discarded):
+//
+// STOP_ERROR(FunctionCall(...));
+//
+// The macro is replaced with the following:
+//
+// {
+// if (EFI_ERROR(FunctionCall(...))){
+// ...message with file name, line number and function name...
+// EFI_DEADLOOP();
+// }
+// }
+//
+//----------------------------------------------------------------------------
+//<AMI_MHDR_END>
+
+#define STOP_ERROR(arg) { \
+ if ( EFI_ERROR( arg ) ) { \
+ AMI_TRACE((AMI_TRACE_ALWAYS, \
+ "\n\nSTOP Error in %s \nLine %i: %s\n",__FILE__, __LINE__,#arg)); \
+ EFI_DEADLOOP(); \
+ } }
+#ifndef ASSERT_CALL
+#define ASSERT_CALL(arg) STOP_ERROR(arg)
+#endif
+
+
+//----------------------------------------------------------------------------
+// LocateMultiplePpi types/declarations
+
+//<AMI_THDR_START>
+//------------------------------------------------------------------
+//
+// Name: PPI_LOCATE_STRUCT
+//
+// Fields: Type ParameterName Description
+//------------------------------------------------------------------
+// EFI_GUID Guid - GUID_ZERO or value of Guid
+// EFI_GUID *GuidPtr - NULL or pointer to Guid
+// UINTN Instance - Instance Number to discover
+// EFI_PEI_PPI_DESCRIPTOR **Descriptor - Pointer to a Pointer to reference the found descriptor. If not NULL, returns a pointer to the descriptor (includes flags, etc)
+// VOID **Ptr - Pointer to be updated with an instance of a pointer to a pointer of the PPI being located
+//
+// Description:
+// This data structure contains the information that is used to
+// make a call to LocatePpi and return the needed pointers
+//
+// Notes:
+//
+//------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ EFI_GUID Guid; // GUID_ZERO or value of Guid
+ EFI_GUID *GuidPtr; // NULL or pointer to Guid
+ UINTN Instance;
+ EFI_PEI_PPI_DESCRIPTOR **Descriptor;
+ VOID **Ptr;
+} PPI_LOCATE_STRUCT;
+
+EFI_STATUS LocateMultiplePpi (
+ EFI_PEI_SERVICES **PeiServices,
+ UINT32 PpiTableSize,
+ PPI_LOCATE_STRUCT *Ppi
+);
+
+
+//----------------------------------------------------------------------------
+// LocateMultipleProtocol types/declarations
+
+//<AMI_THDR_START>
+//------------------------------------------------------------------
+//
+// Name: PROTOCOL_LOCATE_STRUCT
+//
+// Fields: Type ParameterName Description
+//------------------------------------------------------------------
+// EFI_GUID Guid - GUID_ZERO or value of Guid
+// EFI_GUID *GuidPtr - NULL or pointer to Guid
+// VOID *Registration - Optional Registration Key returned from RegisterProtocolNotify()
+// VOID **Interface - Pointer to be updated with an instance of a pointer to a pointer of the Protocol being located
+//
+// Description:
+// This data structure contains the information that is used to
+// make a call to LocateProtocol and return the needed pointers
+//
+// Notes:
+//
+//------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ EFI_GUID Guid; // GUID_ZERO or value of Guid
+ EFI_GUID *GuidPtr; // NULL or pointer to Guid
+ VOID *Registration;
+ VOID **Interface;
+} PROTOCOL_LOCATE_STRUCT;
+
+EFI_STATUS LocateMultipleProtocol (
+ EFI_BOOT_SERVICES *pBS,
+ UINT32 ProtocolTableSize,
+ PROTOCOL_LOCATE_STRUCT *Protocol
+);
+
+
+//----------------------------------------------------------------------------
+// PEI PCI Access related types/declarations
+
+//<AMI_THDR_START>
+//------------------------------------------------------------------
+//
+// Name: PEI_PCI_ARGS
+//
+// Fields: Type ParameterName Description
+//------------------------------------------------------------------
+// EFI_PEI_SERVICES **PeiServices - instance of the PEI Services Table
+// EFI_PEI_PCI_CFG_PPI *Cfg - OPTIONAL Pointer to an Instance of the PciCfg PPI
+// EFI_PEI_PCI_CFG_PPI_WIDTH Width - Width of the data to be accessed in the PCI space
+// UINT32 Address - (B/D/F/R) PCI address of the device to read from
+// VOID *Value - Buffer to store Data to Write or Data that is read
+//
+// Description:
+// This data structure contains the information that is used to
+// read or write to PCI Devices using the PEI PciCfg PPI
+//
+// Notes:
+//
+//------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ EFI_PEI_SERVICES **PeiServices;
+ EFI_PEI_PCI_CFG2_PPI *Cfg;
+ EFI_PEI_PCI_CFG_PPI_WIDTH Width;
+ UINT32 Address; // PEI phase uses 32-bit addresses
+ VOID *Value;
+} PEI_PCI_ARGS;
+
+EFI_STATUS
+PeiWritePci (
+ PEI_PCI_ARGS *Pci
+);
+
+EFI_STATUS
+PeiReadPci(
+ PEI_PCI_ARGS *Pci
+);
+
+
+//----------------------------------------------------------------------------
+// DXE PCI Access related related types/declarations
+
+//<AMI_THDR_START>
+//------------------------------------------------------------------
+//
+// Name: RTBRG_PCI_ARGS
+//
+// Fields: Type ParameterName Description
+//------------------------------------------------------------------
+// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RtBrdg - Pointer to an instance of the DXE PCI Root Bridge Protocol
+// EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width - Width of the data to read from or write to the PCI Device
+// UINT64 Address - PCI Address of the Device to read from or write to
+// UINTN Count - Number of times to repeat the Read or write command
+// VOID *Buffer - Buffer to store Data to Write or Data that is read
+//
+// Description:
+// This data structure contains the information that is used to
+// read or write to PCI Devices using the DXE PCI Root Bridge Protocol
+//
+// Notes:
+//
+//------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RtBrdg;
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width;
+ IN UINT64 Address;
+ IN UINTN Count;
+ IN OUT VOID *Buffer;
+} RTBRG_PCI_ARGS;
+
+EFI_STATUS RbReadPci (
+ RTBRG_PCI_ARGS *Arg
+);
+
+EFI_STATUS RbWritePci (
+ RTBRG_PCI_ARGS *Arg
+);
+
+VOID OemRuntimeShadowRamWrite(
+ IN BOOLEAN Enable
+);
+
+
+#define SB_BACKED_UP_CONTROL_REGISTER 0x3414
+
+BOOLEAN IsTopSwapOn(
+ VOID
+);
+
+VOID SetTopSwap(
+ IN BOOLEAN On
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/CSPLib/CspLibPei.C b/Core/CSPLib/CspLibPei.C
new file mode 100644
index 0000000..50a83a1
--- /dev/null
+++ b/Core/CSPLib/CspLibPei.C
@@ -0,0 +1,329 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//
+// $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibPei.C 17 7/14/11 2:44p Artems $
+//
+// $Revision: 17 $
+//
+// $Date: 7/14/11 2:44p $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/CspLibPei.C $
+//
+// 17 7/14/11 2:44p Artems
+// EIP 64106: Updated source to be UEFI 2.3.1 and PI 1.2 compliant
+//
+// 16 3/23/11 1:02p Artems
+// Bug fix - added backward compatibility with Core 4.6.4.1
+//
+// 15 2/22/11 3:48p Artems
+// EIP 51548 - Added AMI copyright headers, replaced TABs with spaces
+//
+// 1 2/02/11 5:17p Artems
+//
+// 14 5/07/10 10:09a Artems
+// Fixed bug that causes build error when use Core 4.6.4.0
+//
+// 13 5/06/10 12:22p Artems
+// EIP 38241 - $FID signature is absent
+//
+// 12 8/14/09 10:47a Robert
+// Added FID.asm to the component for compliance with AMI Utility
+// specification
+//
+// 11 6/11/09 5:43p Robert
+// Comment updates for CHM and coding standard
+//
+// 10 10/13/07 11:49p Michaela
+// added PciTableInit2 with a PCI access width parameter to support
+// PCI initialization tables for various access widths
+//
+// 9 2/16/07 6:13p Felixp
+// Better handling of Firmware ID structure:
+// 1. FW_VERSION_GUID and BIOS Tag come from SDL tokens.
+// 2. Core/Project versions properly reported
+// 3. CSM version removed
+//
+// 5 6/06/05 3:20p Felixp
+// updated to match PEI CIS 0.91 (CpuIo and PciCfg usage model changed)
+//
+// 4 4/08/05 11:39a Sivagarn
+// Included FID table
+//
+// 3 2/15/05 12:29p Sivagarn
+// Optimized the register programming call
+//
+// 1 1/21/05 12:46p Sivagarn
+// Initial Checkin - Version 0.05
+//
+//*****************************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CspLibPei.C
+//
+// Description:
+// This file contains code for Generic CSP Library PEI functions. The
+// functions include PCI table update etc.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//============================================================================
+// Module specific Includes
+#include <token.h>
+#include <Efi.h>
+#include <Pei.h>
+#include <StatusCodes.h>
+#include <AmiLib.h>
+#include <AmiPeiLib.h>
+#include <PPI\CspLibPpi.h>
+#include <PPI\PCICfg.h>
+
+
+
+//============================================================================
+// GUID Definitions
+EFI_GUID gPeiPCITableInitPCIGUID = AMI_PEI_PCI_TABLE_INIT_PPI_GUID;
+
+//============================================================================
+
+
+#if CORE_REVISION <= 3
+#include "ppi\FwVersion.h"
+extern FW_VERSION FwVersionData;
+FW_VERSION *Version = &FwVersionData;
+#endif //#if CORE_REVISION <= 3
+
+#ifndef PI_SPECIFICATION_VERSION //old Core
+
+EFI_STATUS PciCfgModify(
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN SetBits,
+ IN UINTN ClearBits)
+{
+ if((*PeiServices)->PciCfg==NULL)
+ return EFI_NOT_AVAILABLE_YET;
+
+ return (*PeiServices)->PciCfg->Modify(
+ (EFI_PEI_SERVICES**)PeiServices,
+ (*PeiServices)->PciCfg,
+ Width, Address,
+ SetBits, ClearBits);
+}
+#endif
+
+
+EFI_STATUS PciTableInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN AMI_PEI_PCI_TABLE_INIT_PPI *This,
+ IN EFI_PEI_PCI_CFG2_PPI *PciCfg,
+ IN UINT64 Address,
+ IN AMI_PEI_PCI_INIT_TABLE_STRUCT *PCIInitTable,
+ IN UINT16 wSize
+);
+
+EFI_STATUS PciTableInit2 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN AMI_PEI_PCI_TABLE_INIT_PPI *This,
+ IN EFI_PEI_PCI_CFG2_PPI *PciCfg, // OPTIONAL
+ IN UINT64 CfgAddress,
+ IN AMI_PEI_PCI_INIT_TABLE_STRUCT2 *PciInitTable,
+ IN UINT16 TableEntries,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH AccessWidth
+);
+
+
+// PPI interface definition
+AMI_PEI_PCI_TABLE_INIT_PPI mPciTableInitPpi =
+{
+ PciTableInit,
+ PciTableInit2,
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiPCITableInitPCIGUID,
+ &mPciTableInitPpi};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciTableInit
+//
+// Description:
+// This function programs the PCI device with the values provided
+// in the init table provided
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices - Pointer to the PEI Core data Structure
+// AMI_PEI_PCI_TABLE_INIT_PPI *This - Pointer to an instance of the AMI PEI PCI TABLE INIT PPI
+// EFI_PEI_PCI_CFG_PPI *PciCfg - Optional pointer to an instance of the PciCfg PPI
+// UINT64 Address - PCI address of the register to write to (Bus/Dev/Func/Reg)
+// AMI_PEI_PCI_INIT_TABLE_STRUCT *PCIInitTable - Table with register number, set and clear bits
+// UINT16 wSize - Table length (multiples of structure)
+//
+// Output:
+// Always returns EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PciTableInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN AMI_PEI_PCI_TABLE_INIT_PPI *This,
+ IN EFI_PEI_PCI_CFG2_PPI *PciCfg,
+ IN UINT64 Address,
+ IN AMI_PEI_PCI_INIT_TABLE_STRUCT *PCIInitTable,
+ IN UINT16 wSize)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN Index;
+ UINT64 LocalAddr;
+
+
+ if ((! wSize) || (!PCIInitTable))
+ return Status;
+
+ // Take data defined in the PCIInitTable and program the PCI devices
+ // as ported
+ for (Index = 0; Index < wSize; Index ++) {
+ LocalAddr = Address + PCIInitTable[Index].bRegIndex;
+
+ PciCfgModify( PeiServices,
+ EfiPeiPciCfgWidthUint8,
+ LocalAddr,
+ PCIInitTable[Index].bORMask,
+ ~PCIInitTable[Index].bANDMask );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciTableInit2
+//
+// Description:
+// This function is identical to PciTableInit with the addition of an extra
+// parameter to specify PCI access width.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices - Pointer to the PEI Core data Structure
+// AMI_PEI_PCI_TABLE_INIT_PPI *This - Pointer to an instance of the AMI PEI PCI TABLE INIT PPI
+// EFI_PEI_PCI_CFG_PPI *PciCfg - Optional pointer to an instance of the PciCfg PPI
+// UINT64 CfgAddress - PCI address of the register to write to (Bus/Dev/Func/Reg)
+// AMI_PEI_PCI_INIT_TABLE_STRUCT2 *PCIInitTable - Table with register number, set and clear bits
+// UINT16 TableEntries - Table length (multiples of structure)
+// EFI_PEI_PCI_CFG_PPI_WIDTH AccessWidth - Register-level access width
+//
+// Output:
+// Always returns EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PciTableInit2 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN AMI_PEI_PCI_TABLE_INIT_PPI *This,
+ IN EFI_PEI_PCI_CFG2_PPI *PciCfg, // OPTIONAL
+ IN UINT64 CfgAddress,
+ IN AMI_PEI_PCI_INIT_TABLE_STRUCT2 *PciInitTable,
+ IN UINT16 TableEntries,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH AccessWidth)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN Index;
+ UINT64 LocalAddr;
+
+
+ if ((! TableEntries) || (!PciInitTable))
+ return Status;
+
+ // Take data defined in the PCIInitTable and program the PCI devices
+ // as ported
+ for (Index = 0;
+ Index < TableEntries && !EFI_ERROR(Status);
+ Index ++)
+ {
+ LocalAddr = CfgAddress + PciInitTable[Index].bRegIndex;
+
+ Status = PciCfgModify( PeiServices,
+ AccessWidth,
+ LocalAddr,
+ PciInitTable[Index].bORMask,
+ PciInitTable[Index].bANDMask );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CspLibPei_Init
+//
+// Description:
+// This function is the entry point for this PEI. This function initializes
+// installs the CSP PPI
+//
+// Input:
+// FfsHeader Pointer to the FFS file header
+// PeiServices Pointer to the PEI services table
+//
+// Output:
+// Return Status based on errors that are returned by the InstallPpi function
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CspLibPei_Init (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices)
+{
+ EFI_STATUS Status;
+
+ // Install the NB Init Policy PPI
+ Status = (*PeiServices)->InstallPpi(PeiServices, &mPpiList[0]);
+#ifdef EFI_DEBUG
+ if (Status) {
+ PEI_TRACE((TRACE_PEI_CHIPSET, PeiServices, "CspLibPei_Init Return Code : %r\n", Status));
+ }
+#endif
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+
diff --git a/Core/CSPLib/FID.c b/Core/CSPLib/FID.c
new file mode 100644
index 0000000..8b33f92
--- /dev/null
+++ b/Core/CSPLib/FID.c
@@ -0,0 +1,108 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//
+// $Header: /Alaska/BIN/Chipset/Template/CSPLibrary/FID.c 6 2/22/11 3:28p Artems $
+//
+// $Revision: 6 $
+//
+// $Date: 2/22/11 3:28p $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Chipset/Template/CSPLibrary/FID.c $
+//
+// 6 2/22/11 3:28p Artems
+// EIP 51548 - Added AMI copyright headers, replaced TABs with spaces
+//
+// 5 12/17/10 4:42p Artems
+// Added OEM activation key support
+//
+// 4 5/21/10 4:29p Artems
+// Changed to version 3 as per Utility specification
+//
+// 3 4/05/10 6:15p Artems
+// Added Core 4.6.3 backward compatibility fix
+//
+// 2 12/03/09 12:09p Robert
+// updated comments and file header information
+//
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FID.C
+//
+// Description:
+// This file the Firmware Version Data Structure definition
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+// Module specific Includes
+#include "Pei.h"
+#include "token.h"
+#include <timestamp.h>
+#include <AmiLib.h>
+#include <Ppi\FwVersion.h>
+
+#define THREE_CHAR_ARRAY(x) {(x)/10+'0',(x)%10+'0',0}
+
+FW_VERSION FwVersionData = {
+ "$FID", //$FID signature of the FW VERSION STRUCTURE
+ 0x04, //Version 4
+ sizeof(FW_VERSION), //Size of this structure
+ CONVERT_TO_STRING(BIOS_TAG), //8 character BIOS Tag, Plus NULL Cahracter at the end
+ FW_VERSION_GUID, //FW Version GUID
+ THREE_CHAR_ARRAY(CORE_MAJOR_VERSION), //Core Major Version from BIOS Parameters
+ THREE_CHAR_ARRAY(CORE_MINOR_VERSION), //Core Minor Version from BIOS Parameters
+ THREE_CHAR_ARRAY(PROJECT_MAJOR_VERSION), //Project Major Version from BIOS Parameters
+ THREE_CHAR_ARRAY(PROJECT_MINOR_VERSION), //Project Minor Version from BIOS Parameters
+ FOUR_DIGIT_YEAR_INT,
+ TWO_DIGIT_MONTH_INT,
+ TWO_DIGIT_DAY_INT,
+ TWO_DIGIT_HOUR_INT,
+ TWO_DIGIT_MINUTE_INT,
+ TWO_DIGIT_SECOND_INT,
+ 0xffff,
+ CONVERT_TO_STRING(T_ACPI_OEM_ID),
+ CONVERT_TO_STRING(T_ACPI_OEM_TBL_ID),
+ 49,
+ {
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
+ 0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
+ }
+};
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/Core.chm b/Core/Core.chm
new file mode 100644
index 0000000..f729513
--- /dev/null
+++ b/Core/Core.chm
Binary files differ
diff --git a/Core/Core.cif b/Core/Core.cif
new file mode 100644
index 0000000..979ba56
--- /dev/null
+++ b/Core/Core.cif
@@ -0,0 +1,33 @@
+<component>
+ name = "Core"
+ category = eCore
+ LocalRoot = "Core\"
+ RefName = "Core"
+[files]
+"Core.sdl"
+"Core.mak"
+"FV.mak"
+"FFS.mak"
+"Rules.mak"
+"InitList.c"
+"FloppyCtrl.ffs"
+"FileSystem.ffs"
+"FileSystemx64.ffs"
+"Core.chm"
+"Languages.mak"
+[parts]
+"Build"
+"Include"
+"Library"
+"CORE_PEI"
+"CORE_DXE"
+"Runtime"
+"IdeBus"
+"Recovery"
+"IA32Core"
+"x64Core"
+"PciBus"
+"AmiBoardInfo"
+"PlatformToDriver"
+"EBC"
+<endComponent>
diff --git a/Core/Core.mak b/Core/Core.mak
new file mode 100644
index 0000000..dc58d98
--- /dev/null
+++ b/Core/Core.mak
@@ -0,0 +1,859 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Core.mak 78 9/10/12 4:52p Artems $
+#
+# $Revision: 78 $
+#
+# $Date: 9/10/12 4:52p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Core.mak $
+#
+# 78 9/10/12 4:52p Artems
+# [TAG] EIP88859
+# [Description] Build error in GenRomLayout.bat when too many FFS files
+# or file name is too long.
+# [Files] Core.mak Fv.mak
+#
+# 77 8/02/12 11:51a Artems
+# [TAG] EIP N/A
+# [Category] Improvement
+# [Description] Removed FV_SIGNED attribute from NVRAM firmware volume
+# [Files] Core.mak
+#
+# 76 12/20/11 4:07p Artems
+# Added token for extended rom layout filename to support new FWbuild
+# feature
+#
+# 75 11/16/11 9:46a Felixp
+# [TAG] EIP75724
+# [Category] Improvement
+# [Description] Disable delayed environment variable expansion in the
+# selectdbg.bat.
+#
+# 74 10/28/11 4:14p Felixp
+# [TAG] EIP70518
+# [Category] Improvement
+# [Description] New FV_BB_DESCRIPTOR attribute is added.
+# ROM_AREA_VITAL attribute is added to mark that the area is required for
+# the firmware recovery to work.
+#
+# 73 6/29/11 2:43p Artems
+# Removed support for UEFI 2.0
+#
+# 72 6/28/11 3:06p Felixp
+#
+# 71 6/14/11 5:24p Artems
+# EIP 61949: Fixed bug in apriori list generation
+#
+# 70 6/13/11 11:56a Artems
+# Added NVRAM to list of signed volumes
+#
+# 69 5/13/11 4:22p Artems
+# Added secure flash update. Added new Error message about incompatible
+# token combinations
+# Changed Error message format
+#
+# 68 3/25/11 9:55a Felixp
+# Enhancement: HpkTool command line in the Defaults target is updated
+# to use new TSE SDL token INI_FILE_PATH.
+#
+# 67 3/16/11 10:58p Felixp
+# CIF2MAK_DEFAULTS SDL token is added(used to be a macro in Core.mak).
+#
+# 66 3/15/11 5:20p Felixp
+# BUILD_RULES SDL token is created (used to be a macro in Core.mak).
+#
+# 65 3/09/11 10:03a Artems
+# Fixed bug - handle situation when nested FV is empty
+#
+# 64 2/05/11 1:40p Artems
+# Added PI 1.0-1.1 support
+# Added Nested FV support
+# Changed ROM layout structure (field "OFFSET" added)
+#
+# 63 11/08/10 5:12p Felixp
+# $(BUILD_DIR)\Tokens.c.h target is updated to make sure the file is
+# re-built when Token.h changes
+#
+# 62 11/05/10 2:24p Felixp
+# EDK_INCLUDES macro override is removed
+#
+# 61 11/05/10 1:44p Felixp
+# Improvement(EIP 46043):
+# The build script that generates firmware volume description files
+# (Build\FV_xxx.inf) is updated
+# to support longer file lists.
+#
+# 60 10/01/10 10:56a Felixp
+# Error message is printed when Setup Data Layout Override is used in
+# UEFI 2.0 mode.
+#
+# 59 10/01/10 7:56a Felixp
+# Minor improvement of RomLayout.c: comments with area name are added
+#
+# 58 6/20/10 11:49p Felixp
+# CIF2MAK_DEFAULTS macro is updated.
+# /lproject.lfo switch is added.
+#
+# 57 6/09/10 10:38p Felixp
+# Setup Customization Framework Support.
+#
+# 56 4/26/10 2:56p Felixp
+#
+# 55 4/23/10 5:26p Felixp
+# Support for setup defaults in FV_MAIN is added.
+#
+# 54 3/05/10 5:30p Felixp
+# Enhancement:
+# Targets of types GUID_LIBRARY and PEI_GUID_LIBRARY are updated to
+# reduce length of the command line.
+#
+# 53 2/24/10 2:48p Felixp
+#
+# 52 2/04/10 5:12p Felixp
+# Auto-generated file Build\AutoId.h is included in Setup.h
+#
+# 51 1/26/10 5:03p Felixp
+# Support for generation of the DXE apriori file is added.
+# The list of FFS files that should be added to the DXE a priori list is
+# specified
+# as a part of FV descriptor using DXE_APRIORI_FILE_LIST parameter.
+#
+# 50 1/21/10 3:54p Felixp
+# Font file target $(BUILD_DIR)\Font.ffs is replaced with pseudo-target
+# FontFfs to always recreate the file.
+# The /F 2.1 switch is added for UEFI 2.1 builds to create UEFI 2.1 font
+# pack.
+#
+# 49 12/17/09 2:29p Felixp
+# Minor updates:
+# 1. Target name and UEFI version are printed at the end of the build
+# process
+# 2. Print standard message about successful build completion for a
+# single component build(EIP 32658).
+#
+# 48 11/24/09 11:33a Felixp
+# AmiProtocolLib build command is updated to pass value of the
+# DEFAULT_LANGUAGE.
+#
+# 47 10/09/09 5:11p Felixp
+# UEFI 2.1-related changes.
+#
+# 46 8/27/09 11:47a Felixp
+# Generate PeiSym.lst only if PEI Debugger is enabled
+#
+# 42 7/01/09 1:29p Felixp
+# Tokens.c target: add dependency from Token.h
+# ROM Layout generation: do not describe ROM Holes in FwBuild script
+# (this is not supported by some versions of FwBuild).
+#
+# 40 5/22/09 6:16p Felixp
+# FWBUILD flags updated to generate AMI Debugger listing file
+#
+# 38 5/08/09 6:05p Felixp
+# - support for ROM holes (FFS files with fixed addresses)
+# - ROM_AREA_FV_BOOT attributes is removed
+# - NVRAM back up area is defined using eLink
+# (hard coded entry in the ROM script is removed)
+#
+# 37 5/08/09 12:15a Felixp
+# Ifrastructure to simplify ROM layout customization(EIP 18426).
+# Build process and source code that deals with ROM layout
+# is updated in order to simplify ROM layout customization.
+#
+# 36 5/04/09 2:00p Felixp
+# Support for alternative font data packaging(EIP 18489) is added.
+# Description: Build process is updated to provide framework that can be
+# used to
+# overwrite default packaging of the font data.
+# Two new SDL tokens are created:
+# "LANGUAGE_FONT_LIST" - Space separated list of language identifiers.
+# The fonts for these languages will be included into the ROM image.
+# "STRING_PACK_POST_PROCESS_COMMAND" - The token defines command
+# used in rules.mak to perform additional processing of
+# module's HII string pack ($(BUILD_DIR)$(NAME)Str.hpk)
+# after standard processing (performed by StrGather utility) is
+# completed.
+#
+# 35 3/05/09 9:46a Felixp
+# Bug fix: Problem with target specific builds (build.bat target=X).
+# Description: The target specific build didn't work for modules that
+# use Setup.h without prior full build.
+# Symptoms: Build fails with "SetupDefinitions.h not found" error.
+# Details: Core make files are updated to add target that
+# generates SetupDefinitions.h into the list of dependents of the top
+# level target being built (original code only did it for target
+# "all").
+#
+# 34 11/03/08 10:31a Felixp
+# Current debug mode is printed at the end of the build process.
+#
+# 32 10/22/08 3:56p Felixp
+# Some of the build process warnings are eliminated
+#
+# 30 10/10/08 9:43a Felixp
+# Dependency list for $(BUILD_DIR)\SetupDefinitions.h target is created
+# (the file used to be built during every build).
+#
+# 29 10/10/08 9:36a Felixp
+# - AFTER_ROM target was not in the list of dependents of the target all
+# - Delete ROM image at the beginning of the build process
+#
+# 28 10/09/08 11:54a Felixp
+# Fault tolerant NVRAM update support
+#
+# 27 9/05/07 1:42a Felixp
+# 1. Debugging-related tokens updated to use boolean tokens instead of
+# enumeration
+# 2. Support for ROM_IMAGE_SIZE is added.
+#
+# 26 9/04/07 11:38a Felixp
+# Two pseudo-targets AFTER_FV and AFTER_ROM are added.
+# These targets can be used to add custom build steps towards the end of
+# the build process.
+# AFTER_FV - Use this target to execute your custom build steps after the
+# firmware volumes are built and before the final ROM image is created.
+# AFTER_ROM - Use this target to execute your custom build steps after
+# the final ROM image is created.
+# For example, to hook up custom target X to be executed at the end of
+# the build process add
+# AFTER_ROM : X or AFTER_FV : X
+# into a make file, which defines target X.
+#
+# 25 8/31/07 9:33a Felixp
+# The way FV_NVRAM created is changed:
+# 1. FV_NVRAM is now a standard (FFS-based) FV.
+# 2. NVRAM image is encapsulated into FFS file (NVRAM.ffs)
+# 3. NVRAM image (NVRAM.bin) is no longer blank. It is expected that it
+# will be generated by one of the modules (currently AMITSE).
+#
+# 22 3/18/07 12:45p Felixp
+# FWBUILD is used to dump ROM content at the end of the build process
+#
+# 21 12/28/06 6:37p Felixp
+# Added message at the end of the build process to display ROM file name
+# and build mode.
+#
+# 20 12/27/06 7:32a Felixp
+# Updated to support new version of debugger that can keep PEI binaries
+# in FV_MAIN
+#
+# 19 12/07/06 10:23a Pavell
+# Moved ITK processing to ITK.mak
+#
+# 15 9/26/06 9:01a Felixp
+# Multilanguage support added. New FontTool is required.
+#
+# 13 8/24/06 9:06a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 11 6/21/06 5:44p Felixp
+# ProtocolLib renamed to AmiProtocolLib
+# PpiLib renamed to AmiPpiLib
+#
+# 8 1/17/06 11:27a Felixp
+# Final ROM image generation altered: exact addresses for FV_MAIN, FV_BB
+# and NVRAM used.
+#
+# 7 8/22/05 7:03p Felixp
+# AMI Debugger support
+#
+# 6 7/22/05 2:20a Felixp
+# NVRAM enclosed into Firmware volume
+#
+# 5 6/17/05 3:24p Felixp
+# Setup support: Setup Map generation commands added
+#
+# 4 6/16/05 10:42a Felixp
+# 1. Tokens.c added. It has variables representing SDL tokens.
+# 2. InitList.c extended to support 2 init lists
+#
+# 3 2/11/05 5:33p Felixp
+# CORE_BIN_DIR definition removed
+#
+# 2 2/04/05 9:19a Felixp
+# $(AMI_ROM) value is saved to file $(BUILD_DIR)\amiromname.txt
+# The file is used by the Build.mak to implement Clean command
+#
+# 3 1/25/05 12:53p Felixp
+# Check for validity of DEBUG_MODE added
+#
+# 2 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 9 12/03/04 7:26p Felixp
+# CIF2MAK version 2.0
+#
+# 7 11/18/04 6:25p Felixp
+# support for 2 FVs added
+#
+# 6 7/26/04 4:41p Yakovlevs
+#
+# 4 1/13/04 12:18p Felixp
+# merge64 command line switch /s added to launch the utility in silent
+# mode
+#
+# 3 1/08/04 4:46p Felixp
+# comments improved
+#
+# 2 12/09/03 11:50a Felixp
+# Comments changed for the better HelpBuiler compatibility.
+#
+# 1 12/05/03 4:15p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Core.mak
+#
+# Description: Makefile that builds the BIOS.
+# Prerequisites(set up by the Build.mak):
+# - BUILD_DIR macros is set
+# - $(BUILD_DIR) directory exists
+# - $(BUILD_DIR)\token.mak file generated by AMISDL exists
+#
+# Core.mak includes make files for all other modules in the project
+# Makefiles of individual modules has to add their targets
+# to the dependents list of the target ALL.
+# Core.mak also defines how to create a final rom image (AMI_ROM).
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!INCLUDE $(BUILD_DIR)\token.mak
+!INCLUDE Core\Languages.mak
+
+!IF $(EFI_SPECIFICATION_VERSION) <= 0x20000
+ERROR_MESSAGE=UEFI 2.0 mode is not supported.^
+To resolve the problem, increase the value of EFI_SPECIFICATION_VERSION
+!ERROR $(ERROR_MESSAGE)
+!ENDIF
+
+!IF "$(CoreSrc_SUPPORT)"!="1"
+ERROR_MESSAGE=Core Sources are required for build the project
+!ERROR $(ERROR_MESSAGE)
+!ENDIF
+
+BUILD_DEFAULTS = \
+ "EXT_OBJS=$**" BUILD_ROOT=$(BUILD_DIR) PROJECT_DIR=$(PROJECT_DIR)
+NO_EXT_OBJS_BUILD_DEFAULTS = \
+ BUILD_ROOT=$(BUILD_DIR) PROJECT_DIR=$(PROJECT_DIR)
+
+!IF "$(TARGET)"!="PREPARE"
+$(TARGET) : PREPARE
+!ENDIF
+
+$(BUILD_DIR)\Core.mak : $(CORE_DIR)\$(@B).cif $(CORE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CORE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\Tokens.c.h : $(LIBRARY_DIR)\Tokens.c $(BUILD_DIR)\Core.mak $(BUILD_DIR)\token.h
+ $(SILENT)copy << $(BUILD_DIR)\Tokens.c.h > NUL
+#include <$(LIBRARY_DIR)\Tokens.c>
+<<KEEP
+
+$(BUILD_DIR)\AmiProtocolLib.lib : Include\Protocol\*.h $(BUILD_DIR)\Tokens.c.h
+ $(MAKE) /$(MAKEFLAGS) $(NO_EXT_OBJS_BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Core.mak all\
+ TYPE=GUID_LIBRARY NAME=$(@B)\
+ "HEADERS=Include\Protocol\^*.h $(BUILD_DIR)\Tokens.c.h"\
+ "MY_DEFINES=/D_PIDEController_ /DDEFAULT_LANGUAGE_CODE=$(DEFAULT_LANGUAGE)"
+
+$(BUILD_DIR)\AmiPpiLib.lib : Include\Ppi\*.h $(BUILD_DIR)\Tokens.c.h
+ $(MAKE) /$(MAKEFLAGS) $(NO_EXT_OBJS_BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Core.mak all\
+ TYPE=PEI_GUID_LIBRARY NAME=$(@B)\
+ "HEADERS=Include\Ppi\^*.h $(BUILD_DIR)\Tokens.c.h"
+
+PREPARE :
+ $(ECHO) $(AMI_ROM) > $(BUILD_DIR)\amiromname.txt
+ -@if exist $(BUILD_DIR)\targets.mak $(DEL) $(BUILD_DIR)\targets.mak
+ -@if exist $(AMI_ROM) $(DEL) $(AMI_ROM)
+ $(FONT_TOOL) /S /T $(BUILD_DIR)\font.tmp
+#create list of debuggable modules
+!IF "$(SELECTIVE_DEBUGGING_SUPPORT)"=="1" && "$(SELECTIVE_DEBUGGING)"!=""
+#The first IF clause is needed to be able to use
+#ELSEIF in the for loop below
+ $(SILENT)type << >$(BUILD_DIR)\selectdbg.bat
+@echo off
+setlocal disabledelayedexpansion
+echo !IF 0 > $(BUILD_DIR)\selectivedebugmodules.mak
+for %%i in ($(SELECTIVE_DEBUGGING)) do (
+echo !ELSEIF "$$(NAME)"=="%%i" >> $(BUILD_DIR)\selectivedebugmodules.mak
+echo SELECTIVE_DEBUG_ENABLE=1 >> $(BUILD_DIR)\selectivedebugmodules.mak
+)
+echo !ELSE >> $(BUILD_DIR)\selectivedebugmodules.mak
+echo SELECTIVE_DEBUG_ENABLE=0 >> $(BUILD_DIR)\selectivedebugmodules.mak
+echo !ENDIF >> $(BUILD_DIR)\selectivedebugmodules.mak
+<<
+ $(SILENT)$(BUILD_DIR)\selectdbg.bat
+!ENDIF
+
+PREPARE : $(BUILD_DIR)\SetupDefinitions.h
+!IF "$(Setup_SUPPORT)"=="1"
+# $(BUILD_DIR)\AUTOID.h target is defined in Setup.mak
+PREPARE : $(BUILD_DIR)\AUTOID.h
+!ENDIF
+PREPARE : $(BUILD_DIR)\RomLayout.ini
+
+$(BUILD_DIR)\SetupDefinitions.h : $(SETUP_DEFINITIONS) $(BUILD_DIR)\token.mak Core\Core.mak
+ type << >$(BUILD_DIR)\SetupDefinitions.h
+!IF "$(SETUP_DEFINITIONS)"!=""
+#include<$(SETUP_DEFINITIONS: =>^
+#include<)>
+!ENDIF
+<<
+ type << >$(BUILD_DIR)\ControlDefinitions.h
+!IF "$(SETUP_DEFINITIONS)"!=""
+#define CONTROL_DEFINITION
+#include<SetupDefinitions.h>
+#undef CONTROL_DEFINITION
+#define CONTROLS_ARE_DEFINED
+!ENDIF
+<<
+ type << >$(BUILD_DIR)\GenericSetupDataDefinition.h
+#pragma pack(1)
+typedef struct{
+ UINT8 Numlock;
+ #define SETUP_DATA_DEFINITION
+ #include <SetupDefinitions.h>
+ #undef SETUP_DATA_DEFINITION
+} SETUP_DATA;
+#pragma pack()
+<<
+ type << >$(BUILD_DIR)\SetupDataDefinition.h
+!IF "$(SETUP_DATA_LAYOUT_OVERRIDE_HEADER)"==""
+#include<GenericSetupDataDefinition.h>
+!ELSE
+!IF $(EFI_SPECIFICATION_VERSION) < 0x2000A
+!MESSAGE Setup Data Layout Override is not supported in UEFI 2.0 mode.
+!MESSAGE To disable Setup Data Layout Override, set SETUP_DATA_LAYOUT_OVERRIDE_SUPPORT SDL token to "Off".
+!MESSAGE To switch to UEFI 2.1 mode, set EFI_SPECIFICATION_VERSION SDL token to 0x2000A.
+!ERROR Unsupported configuration.
+!ENDIF
+!IF !EXIST($(SETUP_DATA_LAYOUT_OVERRIDE_HEADER))
+!ERROR Setup Data Layout Override header file "$(SETUP_DATA_LAYOUT_OVERRIDE_HEADER)" defined by the SETUP_DATA_LAYOUT_OVERRIDE_HEADER SDL token is not found.
+!ENDIF
+#ifndef VFRCOMPILE
+#include<$(SETUP_DATA_LAYOUT_OVERRIDE_HEADER)>
+#else
+#include<GenericSetupDataDefinition.h>
+#endif
+!ENDIF
+!IF "$(PROJECT_SETUP_HEADER)"!=""
+!IF !EXIST($(PROJECT_SETUP_HEADER))
+!ERROR Project specific setup header file "$(PROJECT_SETUP_HEADER)" defined by the PROJECT_SETUP_HEADER SDL token is not found.
+!ENDIF
+#include<$(PROJECT_SETUP_HEADER)>
+!ENDIF
+<<
+
+
+CC_TARGET=$(SILENT)maketarget $(BUILD_DIR)\targets.mak $(BUILD_DIR) $$(CC) $$(EXTRA_CFLAGS)
+ASM_TARGET=$(SILENT)maketarget $(BUILD_DIR)\targets.mak $(BUILD_DIR) $$(ASM) $$(EXTRA_AFLAGS)
+CC=$(CC_TARGET)
+
+!INCLUDE $(BUILD_DIR)\module.mak
+
+#NOTE: starting from Core 4.6.3.6
+# generation of the Firmware Volumes (FV) is no longer a separate build step.
+# All FV and the final ROM image are created by the single ROM target command.
+# COMPATIBILITY IMPLICATION: *.fv files are no longer available during execution
+# of the AFTER_FV target commands.
+# Targets BEFORE_FV, FV, and AFTER_FV are now equivalent.
+# All three of them are preserved for backward compatibility
+# (otherwise just one would be enough).
+all : BEFORE_FV FV AFTER_FV ROM AFTER_ROM
+
+BEFORE_FV : FontFfs $(BUILD_DIR)\NVRAM.ffs
+
+FontFfs :
+ $(FONT_TOOL) /IL $(LANGUAGE_FONT_LIST) /T $(BUILD_DIR)\font.tmp
+ $(FONT_TOOL)\
+!IF $(EFI_SPECIFICATION_VERSION) >= 0x2000A
+ /F 2.1\
+!ENDIF
+ /O $(BUILD_DIR)\font.out /T $(BUILD_DIR)\font.tmp
+ $(AMIRC) /s /o$(BUILD_DIR)\font.sec $(BUILD_DIR)\font.out
+ $(MAKE) /$(MAKEFLAGS) /f Core\FFS.mak \
+ NAME=$(@B) \
+ BUILD_DIR=$(BUILD_DIR) \
+#Do not change this GUID. HIIDB uses this GUID to locate font file
+ GUID=DAC2B117-B5FB-4964-A312-0DCC77061B9B \
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ FFSFILE=$(BUILD_DIR)\Font.ffs COMPRESS=1 \
+ SECTION=font.sec \
+
+# create NVRAM.FFS
+$(BUILD_DIR)\NVRAM.FFS : $(BUILD_DIR)\NVRAM.bin
+ $(MAKE) /f Core\FFS.mak BUILD_DIR=$(BUILD_DIR) \
+ GUID=CEF5B9A3-476D-497f-9FDC-E98143E0422C \
+ TYPE=EFI_FV_FILETYPE_RAW FFS_CHECKSUM=0\
+ RAWFILE=$(BUILD_DIR)\NVRAM.bin \
+ FFSFILE=$(BUILD_DIR)\NVRAM.FFS COMPRESS=0 NAME=NVRAM
+
+# Don't change this GUID; NVRAM driver expects it
+# // {9221315B-30BB-46b5-813E-1B1BF4712BD3}
+#define SETUP_DEFAULTS_FFS_GUID { 0x9221315b, 0x30bb, 0x46b5, { 0x81, 0x3e, 0x1b, 0x1b, 0xf4, 0x71, 0x2b, 0xd3 } }
+SETUP_DEFAULTS_FFS_GUID=9221315B-30BB-46b5-813E-1B1BF4712BD3
+
+!IF "$(SETUP_DEFAULTS_IN_FV_MAIN)"=="1"
+BEFORE_FV : Defaults
+
+Defaults:
+ $(HPKTOOL) -i$(IFR_DIR_LIST: = -i)\
+!IF "$(INI_FILE_PATH)"!=""
+ -f$(INI_FILE_PATH)\
+!ELSEIF $(EFI_SPECIFICATION_VERSION) > 0x20000
+ -f$(TSEBIN_DIR)\uefisetup.ini\
+!ELSE
+ -f$(TSEBIN_DIR)\setup.ini\
+!ENDIF
+ -o$(BUILD_DIR)\tmp.asm -do$(BUILD_DIR)\Defaults.bin\
+!IF "$(MANUFACTURING_MODE_SUPPORT)"=="1"
+ -dm\
+!ENDIF
+ -r -de$(FLASH_ERASE_POLARITY) -dl$(DEFAULT_LANGUAGE)\
+ -dg4599D26F-1A11-49b8-B91F-858745CFF824\
+ -h$(AMITSE_HPK_FILE_ORDER)
+ -$(DEL) pkgtmp*.tmp
+ $(MAKE) /f Core\FFS.mak BUILD_DIR=$(BUILD_DIR)\
+ GUID=$(SETUP_DEFAULTS_FFS_GUID)\
+ TYPE=EFI_FV_FILETYPE_FREEFORM\
+ BINFILE=$(BUILD_DIR)\Defaults.bin \
+ FFSFILE=$(BUILD_DIR)\Defaults.FFS COMPRESS=1 NAME=Defaults
+!ENDIF
+
+#**********************************************************************
+#<AMI_GHDR_START>
+# Name: AMI_ROM
+#
+# Description:
+# BIOS ROM image (AMI_ROM) includes FV_MAIN firmware volume
+# and blank NVRAM area.
+# FV.MAK is used to create FV_MAIN
+# Prerequisites:
+# - Core.mak Prerequisites
+# The following macros must be defined:
+# - FV_MAIN - List of Base Names (file name w/o extension)
+# for the FFS files to be included in the Firmware Volume
+# This macros is getting generated by
+# the AMISDL from the corresponding eLink defined in Core.sdl
+# To add module to FV_MAIN, module's SDL file has to define eLink
+# with the name set to base name of the module's FFS binary
+# and the parent set to FV_MAIN.
+# The following macros are expected to be defined by the SDL file
+# of the Flash Module:
+# -FLASH_SIZE - Size of the Flash Device in bytes
+# -FLASH_BLOCK_SIZE - Size of the Flash Device Block
+# -FLASH_ERASE_POLARITY - Flash Device Erase Polarity
+# -FV_MAIN_BASE - Base Address of the FV_MAIN
+# -FV_MAIN_BLOCKS - Number of Blocks occupied by the FV_MAIN
+# -NVRAM_SIZE - Size of NVRAM area
+#
+#<AMI_GHDR_END>
+#**********************************************************************
+#Nothing to do here.
+# The FV are created by the ROM target command
+#This target is here for backward compatibility.
+# See also comment above the all target description
+FV :
+
+#Nothing to do here.
+#This target that can be used by OEM modules for any custom
+#build steps that need to be performed after FV generation and prior to ROM generation.
+
+#-----Long e-Link handling example--------------
+#uncomment the following code to solve the problem from EIP 88859
+#$(BUILD_DIR)\FvMainFfsList.mak : $(BUILD_DIR)\token.mak
+# @copy << $(BUILD_DIR)\FvMainFfsList.mak
+#FILE_LIST=$(FV_MAIN)
+#<<KEEP
+#-----Long e-Link handling example end----------
+
+AFTER_FV:
+
+FV_NVRAM_DESCRIPTOR=FV(\
+name=FV_NVRAM, address=$(NVRAM_ADDRESS),\
+offset=$(NVRAM_ADDRESS)-$(FLASH_BASE),\
+size=$(NVRAM_SIZE), file_list=$(BUILD_DIR)\NVRAM.FFS\
+)
+FV_MAIN_DESCRIPTOR=FV(\
+name=FV_MAIN, address=$(FV_MAIN_BASE),\
+offset=$(FV_MAIN_BASE)-$(FLASH_BASE),\
+size=$(FV_MAIN_BLOCKS)*$(FLASH_BLOCK_SIZE),\
+!IF "$(FV_MAIN_NESTED)"!=""
+file_list=$(BUILD_DIR)\FV_MAIN_NESTED.ffs $(FV_MAIN),\
+attr=ROM_AREA_FV_PEI+ROM_AREA_FV_DXE+ROM_AREA_FV_NFV_PRESENT+ROM_AREA_FV_SIGNED\
+!ELSE
+file_list=$(FV_MAIN),\
+#-----Long e-Link handling example--------------
+#uncomment the following string below to solve the problem from EIP 88859
+#file_list_file=$(BUILD_DIR)\FvMainFfsList.mak,\
+#-----Long e-Link handling example end----------
+attr=ROM_AREA_FV_PEI+ROM_AREA_FV_DXE+ROM_AREA_FV_SIGNED\
+!ENDIF
+)
+
+!IF "$(FV_MAIN_NESTED)"!=""
+FV_MAIN_NESTED_DESCRIPTOR=FV(\
+name=FV_MAIN_NESTED, nested=1,\
+file_list=$(FV_MAIN_NESTED)\
+)
+ROM_IMAGE=$(ROM_IMAGE) $(FV_MAIN_NESTED_DESCRIPTOR)
+!ENDIF
+
+FV_BB_DESCRIPTOR=FV(\
+name=FV_BB, address=$(FV_BB_BASE),\
+offset=$(FV_BB_BASE)-$(FLASH_BASE),\
+size=$(FV_BB_BLOCKS)*$(FLASH_BLOCK_SIZE),\
+file_list=$(FV_BB), attr=ROM_AREA_FV_PEI+ROM_AREA_FV_DXE+ROM_AREA_FV_SIGNED+ROM_AREA_VITAL\
+)
+NVRAM_BACKUP_DESCRIPTOR=HOLE(\
+name=NVRAM_BACKUP, address=$(NVRAM_BACKUP_ADDRESS),\
+offset=$(NVRAM_BACKUP_ADDRESS)-$(FLASH_BASE),\
+size=$(NVRAM_SIZE)\
+)
+
+#-----Long e-Link handling example--------------
+#uncomment the following string below and use it instead of generic one to solve the problem from EIP 88859
+#$(BUILD_DIR)\RomLayout.ini : $(BUILD_DIR)\token.mak Core\Core.mak Core\Fv.mak $(BUILD_DIR)\FvMainFfsList.mak
+#-----Long e-Link handling example end----------
+$(BUILD_DIR)\RomLayout.ini : $(BUILD_DIR)\token.mak Core\Core.mak Core\Fv.mak
+ @echo all : > $(BUILD_DIR)\beforefv.mak
+ $(SILENT)copy << $(BUILD_DIR)\RomLayout.ini > NUL
+output
+ BIOS($(AMI_ROM))
+end
+group BIOS
+!IF "$(ROM_IMAGE_SIZE)"!=""
+ size=$(ROM_IMAGE_SIZE)
+!ELSE
+ size=$(FLASH_SIZE)
+!ENDIF
+ upper=0xFFFFFFFF
+ components
+<<KEEP
+ $(SILENT)copy << $(BUILD_DIR)\RomLayout.c > NUL
+#include <RomLayout.h>
+#pragma pack(1)
+ROM_AREA RomLayout[] = {
+<<KEEP
+ $(SILENT)copy << $(BUILD_DIR)\GenRomLayout.bat > NUL
+@echo off
+set BUILD_DIR=$(BUILD_DIR)
+set ERASE_POLARITY=$(FLASH_ERASE_POLARITY)
+set BLOCK_SIZE=$(FLASH_BLOCK_SIZE)
+set ECHO=$(ECHO)
+set MAKE=$(MAKE)
+set chunks=0
+for /f "tokens=1 delims=( " %%a in (%1) do @(
+ set /A chunks+=1
+)
+set rchunks=0
+for /f "tokens=1* delims=( " %%a in (%1) do @(
+ set /A rchunks+=1
+ for /f "tokens=1* delims=)" %%c in ("%%b") do @(
+ call $(BUILD_DIR)\GenFvDesc.bat "type=%%a,%%c"
+ if not exist $(BUILD_DIR)\RomLayout.ini goto :eof
+ )
+)
+if not %chunks%==%rchunks% (
+ echo ERROR: file list too long
+ goto error
+)
+goto :eof
+:error
+del $(BUILD_DIR)\RomLayout.ini
+<<KEEP
+ $(SILENT)copy << $(BUILD_DIR)\GenFvDesc.bat > NUL
+@echo off
+setlocal
+for /f "tokens=1-10 delims=," %%a in (%*) do (
+ if NOT "%%a"=="" set %%a
+ if NOT "%%b"=="" set %%b
+ if NOT "%%c"=="" set %%c
+ if NOT "%%d"=="" set %%d
+ if NOT "%%e"=="" set %%e
+ if NOT "%%f"=="" set %%f
+ if NOT "%%g"=="" set %%g
+ if NOT "%%h"=="" set %%h
+ if NOT "%%i"=="" set %%i
+ if NOT "%%j"=="" set %%j
+)
+if /I "%attr%"=="" set attr=0
+if not "%NAME%"=="" echo // %NAME% >> $(BUILD_DIR)\RomLayout.c
+if /I %type%==FV (
+!IF !$(BRIEF)
+ echo FV: NAME="%NAME%" ADDRESS="%ADDRESS%" SIZE="%SIZE%"
+!ENDIF
+ if /I "%nested%"=="1" (
+ if "%ADDRESS%"=="" set ADDRESS=0
+ set GLOBAL_COMPRESSION=0
+ )
+ if "%SIZE%"=="" (
+ set BLOCKS=AUTO
+ ) else (
+ set /A BLOCKS=%size%/%BLOCK_SIZE%
+ )
+
+ $(MAKE) -f Core\fv.mak PI_SPECIFICATION_VERSION=$(PI_SPECIFICATION_VERSION)
+ if not exist $(BUILD_DIR)\%NAME%.inf goto error
+ if /I not "%nested%"=="1" (
+ echo file %NAME% FvDesc=$(BUILD_DIR)\%NAME%.inf lower=%ADDRESS% end >> $(BUILD_DIR)\RomLayout.ini
+ echo {%ADDRESS%, %OFFSET%, %SIZE%, RomAreaTypeFv, %attr%}, >> $(BUILD_DIR)\RomLayout.c
+ ) else (
+ $(MAKE) -f Core\ffs.mak TYPE=EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE FV_DESC=$(BUILD_DIR)\%NAME%.inf BUILD_DIR=$(BUILD_DIR) GUID=AE717C2F-1A42-4f2b-8861-78B79CA07E07 FFSFILE=$(BUILD_DIR)\%NAME%.ffs NAME=%NAME% COMPRESS=1
+ )
+)else if /I %type%==file (
+!IF !$(BRIEF)
+ echo File: NAME="%NAME%" ADDRESS="%ADDRESS%" FILE="%FILE%"
+!ENDIF
+ echo file %NAME% binfile=%FILE% lower=%ADDRESS% end >> $(BUILD_DIR)\RomLayout.ini
+ echo {%ADDRESS%, %OFFSET%, %SIZE%, RomAreaTypeRaw, %attr%}, >> $(BUILD_DIR)\RomLayout.c
+)else if /I %type%==hole (
+!IF !$(BRIEF)
+ echo Hole: NAME="%NAME%" ADDRESS="%ADDRESS%" SIZE="%SIZE%"
+!ENDIF
+ echo {%ADDRESS%, %OFFSET%, %SIZE%, RomAreaTypeRaw, %attr%}, >> $(BUILD_DIR)\RomLayout.c
+)else (
+ echo ERROR: Invalid ROM_IMAGE element "%type%".
+ goto error
+)
+if "%ADDRESS%"=="" (
+ echo ERROR: Invalid ROM_IMAGE element. Address is not defined for element "%type%(%NAME% %FILE%)".
+ goto error
+)
+endlocal
+goto :eof
+:error
+del $(BUILD_DIR)\RomLayout.ini
+<<KEEP
+ $(SILENT)copy << $(BUILD_DIR)\GenFvList.bat > NUL
+@echo off
+echo %3 >> %2
+for /f %%f in (%1) do @(
+ for /f "tokens=1,2 delims=:" %%i in ("%%f") do @(
+ if /I %%i==TYPE (
+ echo %%i = %%j >> %2
+ ) else if /I %%i==LOCATION (
+ echo %%i = %%j >> %2
+ ) else if /I %%i==SIZE (
+ echo %%i = %%j >> %2
+ ) else (
+ for /F "delims=\" %%y in ("%%i") do (
+ if 1==0 (
+ echo EFI_FILE_NAME = %%i >> %2
+ ) else if /I %%y==$(BUILD_DIR) (
+ if not exist %%~dpni__.pkg (
+ echo EFI_FILE_NAME = %%i >> %2
+ ) else (
+ echo EFI_FILE_NAME = %%~dpni__.pkg >> %2
+ )
+ ) else (
+ echo EFI_FILE_NAME = %%i >> %2
+ )
+ )
+ )
+ )
+)
+<<KEEP
+ $(SILENT)Build\GenRomLayout.bat <<$(BUILD_DIR)\RomLayout.txt
+$(ROM_IMAGE:)=^)^
+)
+<<KEEP
+ @if not exist $(BUILD_DIR)\RomLayout.ini @copy file_that_does_not_exist x > NUL
+ $(ECHO) end >> $(BUILD_DIR)\RomLayout.ini
+ $(ECHO) end >> $(BUILD_DIR)\RomLayout.ini
+ $(ECHO) {0, 0, 0, 0} >> $(BUILD_DIR)\RomLayout.c
+ $(ECHO) }; >> $(BUILD_DIR)\RomLayout.c
+
+!IF $(PI_SPECIFICATION_VERSION)>=0x00010000
+FWBUILD_FLAGS = $(FWBUILD_FLAGS) /p 1.0
+!ENDIF
+FWBUILD_FLAGS = $(FWBUILD_FLAGS) /d /c $(BUILD_DIR)\RomLayout.ini /m $(ROM_LAYOUT_EX)
+!IF "$(AMI_DEBUGGER_SUPPORT)"=="1" && "$(PeiDebugger_SUPPORT)"=="1"
+FWBUILD_FLAGS = $(FWBUILD_FLAGS) /b $(BUILD_DIR)\peisym.lst
+!ENDIF
+
+# create a final ROM image
+ROM:
+ $(MAKE) /$(MAKEFLAGS) /f $(BUILD_DIR)\beforefv.mak all
+ @echo all : > $(BUILD_DIR)\beforefv.mak
+ $(FWBUILD) $(AMI_ROM) $(FWBUILD_FLAGS)
+
+!IF "$(DEBUG_MODE)"=="1"
+DEBUG_MODE_STRING=on
+!ELSE
+DEBUG_MODE_STRING=off
+!ENDIF
+
+!IF $(EFI_SPECIFICATION_VERSION)==0x1000A
+EFI_VERSION_STRING=1.10
+!ELSEIF $(EFI_SPECIFICATION_VERSION)==0x20000
+EFI_VERSION_STRING=2.0
+!ELSEIF $(EFI_SPECIFICATION_VERSION)==0x2000A
+EFI_VERSION_STRING=2.1
+!ELSEIF $(EFI_SPECIFICATION_VERSION)==0x20014
+EFI_VERSION_STRING=2.2
+!ELSEIF $(EFI_SPECIFICATION_VERSION)==0x2001E
+EFI_VERSION_STRING=2.3
+!ELSEIF $(EFI_SPECIFICATION_VERSION)==0x2001F
+EFI_VERSION_STRING=2.3.1
+!ENDIF
+!IF $(PI_SPECIFICATION_VERSION) < 0x00010000
+PI_VERSION_STRING=0.91
+!ELSEIF $(PI_SPECIFICATION_VERSION) == 0x00010000
+PI_VERSION_STRING=1.0
+!ELSEIF $(PI_SPECIFICATION_VERSION) == 0x0001000A
+PI_VERSION_STRING=1.1
+!ELSEIF $(PI_SPECIFICATION_VERSION) == 0x00010014
+PI_VERSION_STRING=1.2
+!ENDIF
+
+#This is target that can be used by OEM modules for any custom
+#build steps that need to be performed after ROM generation.
+AFTER_ROM:
+!IF $(BRIEF)
+#in brief mode ROM info is printed during ROM file generation
+# $(FWBUILD) $(AMI_ROM) /s
+!ELSE
+ $(FWBUILD) $(AMI_ROM) /v
+!ENDIF
+
+!IF "$(TARGET)"!="END"
+$(TARGET) : END
+!ENDIF
+#IMPORTANT: This has to be the last step of the build process.
+#Any build process customizations must happen prior to this point
+#Use AFTER_ROM or AFTER_FV targets for any custom build steps.
+END:
+ @echo TARGET: $(TARGET). UEFI Version: $(EFI_VERSION_STRING). PI Version: $(PI_VERSION_STRING)
+ @echo ROM IMAGE: $(AMI_ROM). ROM TYPE: $(PROCESSOR). DEBUG MODE: $(DEBUG_MODE_STRING)
+ @echo All output modules were successfully built.
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/Core.sdl b/Core/Core.sdl
new file mode 100644
index 0000000..7cc1a4a
--- /dev/null
+++ b/Core/Core.sdl
@@ -0,0 +1,991 @@
+TOKEN
+ Name = "CORE_MAJOR_VERSION"
+ Value = "4"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CORE_MINOR_VERSION"
+ Value = "6"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CORE_REVISION"
+ Value = "5"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CORE_BUILD_NUMBER"
+ Value = "4"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CORE_COMBINED_VERSION"
+ Value = "$(CORE_MAJOR_VERSION)*65536+$(CORE_MINOR_VERSION)*100+$(CORE_REVISION)*10+$(CORE_BUILD_NUMBER)"
+ Help = "The token value is an aggregation of all core version tokens into a single integer."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "CORE_VENDOR"
+ Value = "American Megatrends"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEBUG_MODE"
+ Value = "0"
+ Help = "Main switch to control debugging features.\If this switch is set to off, all debugging capabilities are disabled.\If this switch is set to on, the following SDL tokens can be used to fine-tune debugging capabilities:\OPTIMIZATION, DEBUG_CODE, DEBUG_INFO."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Range = "0 - 1"
+End
+
+TOKEN
+ Name = "OPTIMIZATION"
+ Value = "0"
+ Help = "Once DEBUG_MODE is on, this swtich is used to control compiler and linker optimization.\If DEBUG_MODE is set to off, this switch is ignored and optimization is enabled."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "DEBUG_INFO"
+ Value = "1"
+ Help = "Once DEBUG_MODE is on, this swtich is used to control generation of the debugging information.\Debug information is used by Debuggers to provide source level debugging capability. \If DEBUG_MODE is set to off, this switch is ignored and generation of the debugging information is disabled."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "DEBUG_CODE"
+ Value = "1"
+ Help = "Once DEBUG_MODE is on, this swtich is used to enable or disable debugging code\such as debugging messages, assert statements, and any code enclosed into #ifdef EFI_DEBUG ... #endif.\If DEBUG_MODE is set to off, this switch is ignored and debugging code is disabled."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "INDEPENDENT_PEI_DEBUG_SETTINGS"
+ Value = "0"
+ Help = "If DEBUG_MODE is set to off, this switch is ignored and all debugging capabilities are disabled.\If this switch is set to on, an independent set of debug settings can be defined for PEI modules.\If this switch is set to on, the following SDL tokens can be used to fine-tune PEI debugging capabilities:\PEI_OPTIMIZATION, PEI_DEBUG_CODE, PEI_DEBUG_INFO.\"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Range = "0-1"
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "PEI_OPTIMIZATION"
+ Value = "0"
+ Help = "Applies to PEI modules only.\Once INDEPENDENT_PEI_DEBUG_SETTINGS is on, this swtich is used to control compiler and linker optimization for PEI modules\If INDEPENDENT_PEI_DEBUG_SETTINGS is set to off, this switch is ignored and OPTIMIZATION switch is used instead."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "INDEPENDENT_PEI_DEBUG_SETTINGS" "=" "1"
+End
+
+TOKEN
+ Name = "PEI_DEBUG_INFO"
+ Value = "1"
+ Help = "Applies to PEI modules only.\Once INDEPENDENT_PEI_DEBUG_SETTINGS is on, this swtich is used to control generation of the debugging information for PEI modules.\Debug information is used by Debuggers to provide source level debugging capability. \If INDEPENDENT_PEI_DEBUG_SETTINGS is set to off, this switch is ignored and DEBUG_INFO switch is used instead."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "INDEPENDENT_PEI_DEBUG_SETTINGS" "=" "1"
+End
+
+TOKEN
+ Name = "PEI_DEBUG_CODE"
+ Value = "1"
+ Help = "Applies to PEI modules only.\Once INDEPENDENT_PEI_DEBUG_SETTINGS is on, this swtich is used to enable or disable debugging code\such as debugging messages, assert statements, and any code enclosed into #ifdef EFI_DEBUG ... #endif.\If INDEPENDENT_PEI_DEBUG_SETTINGS is set to off, this switch is ignored and DEBUG_CODE switch is used instead."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "INDEPENDENT_PEI_DEBUG_SETTINGS" "=" "1"
+End
+
+TOKEN
+ Name = "SELECTIVE_DEBUGGING_SUPPORT"
+ Value = "0"
+ Help = "If DEBUG_MODE is set to off, this switch is ignored and all debugging capabilities are disabled.\Enables/disables selective debugging support.\Selective debugging provides a capability to specify independent set of debug settings for a group of modules defined by SELECTIVE_DEBUGGING eLink.\SELECTIVE_DEBUGGING eLink defines list of module RefNames.\If this switch is set to on, the following SDL tokens can be used to fine-tune selective debugging capabilities:\SELECTIVE_OPTIMIZATION, SELECTIVE_DEBUG_CODE, SELECTIVE_DEBUG_INFO\"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Range = "0-1"
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "SELECTIVE_OPTIMIZATION"
+ Value = "0"
+ Help = "Once SELECTIVE_DEBUGGING_SUPPORT is on, this swtich is used to control compiler and linker optimization \for modules from the SELECTIVE_DEBUGGING list.\"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "SELECTIVE_DEBUGGING_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SELECTIVE_DEBUG_INFO"
+ Value = "1"
+ Help = "Once SELECTIVE_DEBUGGING_SUPPORT is on, this swtich is used to control generation of the debugging information\for modules from the SELECTIVE_DEBUGGING list.\Debug information is used by Debuggers to provide source level debugging capability. "
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "SELECTIVE_DEBUGGING_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SELECTIVE_DEBUG_CODE"
+ Value = "1"
+ Help = "Once SELECTIVE_DEBUGGING_SUPPORT is on, this swtich is used to enable or disable debugging code\such as debugging messages, assert statements, and any code enclosed into #ifdef EFI_DEBUG ... #endif\for modules from the SELECTIVE_DEBUGGING list."
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "SELECTIVE_DEBUGGING_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "BRIEF"
+ Value = "1"
+ Help = "Brief build mode."
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "EMBEDDED_RESOURCES"
+ Value = "0"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CREATE_UI_SECTION"
+ Value = "1"
+ Help = "Setting of this switch to on enables generation of UI section for every FFS file. \The UI section has a Unicode representation of the FFS file name."
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "EFI_SPECIFICATION_VERSION"
+ Value = "0x2000A"
+ Help = "version of the supported EFI/UEFI specification:\0x2000A - UEFI 2.1\0x20014 - UEFI 2.2\0x2001E - UEFI 2.3\0x2001F - UEFI 2.3.1"
+ TokenType = Integer
+ TargetMAK = Yes
+ Range = "0x2000A, 0x20014, 0x2001E, 0x2001F"
+End
+
+TOKEN
+ Name = "PI_SPECIFICATION_VERSION"
+ Value = "0x0005B"
+ Help = "version of the PI specification supported:\0x0005B - PI 0.91\0x10000 - PI 1.0\0x1000A - PI 1.1\0x10014 - PI 1.2"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Range = "0x0005B, 0x10000, 0x1000A, 0x10014"
+End
+
+TOKEN
+ Name = "CJK_CHARACTERS_SUPPORT"
+ Value = "0"
+ Help = "Enables/Disables build process support for the Chinese/Japanese/Korean characters.\Since these languages are not alphabet-based, it is impossible to include glyphs for all the language characters. Only characters used in the project are included for these languages. \Extra build steps required to detect, which characters are used.\This token is created to remove build time overhead, when this is not needed.\"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LANGUAGE_FONT_LIST"
+ Value = "drawing $(SUPPORTED_LANGUAGES)"
+ Help = "Space separated list of language identifiers. \The fonts for these languages will be included into the ROM image."
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "FONT_TOOL_HII_FORMAT_SWITCH"
+ Value = "/F 2.1"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+End
+
+TOKEN
+ Name = "STRING_PACK_POST_PROCESS_COMMAND"
+ Value = "$(FONT_TOOL) $(FONT_TOOL_HII_FORMAT_SWITCH) /P $(BUILD_DIR)\$(NAME)Str.hpk /T $(BUILD_DIR)\font.tmp"
+ Help = "The token defines command used in rules.mak to perform additional processing \of module's HII string pack ($(BUILD_DIR)$(NAME)Str.hpk) \after standard processing (performed by StrGather utility) is completed."
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "CJK_CHARACTERS_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "ISA_IRQ_MASK"
+ Value = "0xE305"
+ Help = "This is an IRQ mask which may be used by ISA devices\ If BIT == 0 IRQ Available BIT == 1 IRQ Used.\DEFAULT VALUE == 0xE305."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0...0FFFFh"
+End
+
+TOKEN
+ Name = "ISA_DMA_MASK"
+ Value = "0x10"
+ Help = "This is DEFAULT mask of ISA DMA channels which may be used by ISA devices.\Set BIT=1 means Channel CAN NOT be used, Reset BIT=0 means Channel is AVAILABLE.\Channel 4 of ISA DMA controller is tacken for CASCADE DMA channel. \All the rest are available."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0...0EFh"
+End
+
+TOKEN
+ Name = "KBC_SUPPORT"
+ Value = "1"
+ Help = "Enable/Disable KBC support"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "SIO_SUPPORT" "=" "1"
+ Token = "ACPI_IA_BOOT_ARCH" "&" "2"
+End
+
+TOKEN
+ Name = "FLOPPY_CTRL_SUPPORT"
+ Value = "1"
+ Help = "Switch to enable ISA Floppy Controller support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Token = "SIO_SUPPORT" "=" "1"
+ Token = "ACPI_IA_BOOT_ARCH" "&" "1"
+End
+
+TOKEN
+ Name = "TOOL_DIR"
+ Value = "tools"
+ Help = "Tools directory"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "FWIMAGE"
+ Value = "$(SILENT)FwImage"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ASL"
+ Value = "$(SILENT)asl"
+ Help = "ASL compiler"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "GENDEPEX"
+ Value = "$(SILENT)GENDEPEX"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "GENFFSFILE"
+ Value = "$(SILENT)GENFFSFILE"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "GENFVIMAGE"
+ Value = "GENFVIMAGE"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "GENSECTION"
+ Value = "$(SILENT)GENSECTION /nologo"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "GENTEIMAGE"
+ Value = "$(SILENT)GENTEIMAGE"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "PEIREBASE"
+ Value = "$(SILENT)PEIREBASE"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "STRGATHER"
+ Value = "STRGATHER"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" "<=" "0x20000"
+End
+
+TOKEN
+ Name = "VFRCOMPILE"
+ Value = "$(SILENT)VFRCOMPILE"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" "<=" "0x20000"
+End
+
+TOKEN
+ Name = "STRGATHER"
+ Value = "UEFISTRGATHER"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+End
+
+TOKEN
+ Name = "VFRCOMPILE"
+ Value = "$(SILENT)UEFIVFRCOMPILE"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+End
+
+TOKEN
+ Name = "CIF2MAK"
+ Value = "$(SILENT)CIF2MAK /nologo"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "PACKOPROM"
+ Value = "$(SILENT)PackOpRom /nologo"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "AMIRC"
+ Value = "$(SILENT)AmiRc /nologo"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "VFRID"
+ Value = "$(SILENT)VfrId /nologo"
+ TokenType = Integer
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "MAKE"
+ Value = "$(SILENT)NMAKE -NOLOGO -R"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CC"
+ Value = "$(SILENT)CL"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CP"
+ Value = "$(SILENT)CL /nologo /EP"
+ Help = "C preprocessor"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LINK"
+ Value = "$(SILENT)LINK"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ASM"
+ Value = "$(SILENT)ML"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ASM16"
+ Value = "$(SILENT)ML"
+ TokenType = Integer
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "LIBEXE"
+ Value = "$(SILENT)LINK /LIB"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ASMLINK"
+ Value = "$(SILENT)LINK16"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "PEIDEBUGFIXUP"
+ Value = "$(SILENT)PEIDEBUGFIXUP"
+ Help = "This is the tool responsible for patching the FV_BB \by replacing the address of PEI core entry point with \the address of PEI Debugger entry point, so that the \control can be given to PEI debugger"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "EFI_APRIORI_GUID"
+ Value = "FC510EE7-FFDC-11D4-BD41-0080C73C8881"
+ Help = "GUID used to identify 'a priori' file within the Firmware Volume"
+ TokenType = Expression
+ TargetMAK = Yes
+ Range = "GUID"
+End
+
+TOKEN
+ Name = "MERGE"
+ Value = "MERGE64"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "FWBUILD"
+ Value = "$(SILENT)FWBUILD"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ECHO"
+ Value = "$(SILENT)echo"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "DEL"
+ Value = "$(SILENT)del"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SILENT"
+ Value = "@"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "BRIEF" "=" "1"
+End
+
+TOKEN
+ Name = "SILENT_OUT"
+ Value = "> NUL"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "BRIEF" "=" "1"
+End
+
+TOKEN
+ Name = "DBG"
+ Value = "Dbg"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "DEBUG_MODE" "!=" "0"
+End
+
+TOKEN
+ Name = "ARCH"
+ Value = "x64"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+TOKEN
+ Name = "FONT_TOOL"
+ Value = "$(SILENT)FontTool"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "NV_SIMULATION"
+ Value = "0"
+ Help = "Debug Switch. When the switch is on, NVRAM\variables are not stored in NVRAM"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NVRAM_HEADER_SIZE"
+ Value = "96"
+ Help = "Size of NVRAM header, which is number of bytes from\the NVRAM_ADDRESS to the first variable record.\Currently defined as:\72(FV Header Size) + 24 (FFS File Header Size)"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+ Range = "0-NVRAM_SIZE-1"
+End
+
+TOKEN
+ Name = "MANUFACTURING_MODE_SUPPORT"
+ Value = "0"
+ Help = "When enabled adds support for manufactoring mode.\NVRAM image generated during build process will contain manufactoring defaults for variables used in Setup."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FAULT_TOLERANT_NVRAM_UPDATE"
+ Value = "0"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BEEP_ENABLE"
+ Value = "1"
+ Help = "This flag enables/disables all firmware beeps"
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "USE_CC_RESPONSE_FILE"
+ Value = "0"
+ Help = "When this option is enabled, all C-compiler(CC) options are passed via the response file.\Enable when the length of the CC command line exceeds maximum supported limit.\"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "USE_CP_RESPONSE_FILE"
+ Value = "0"
+ Help = "When this option is enabled, all C-preprocessor(CP) options are passed via the response file.\Enable when the length of the CP command line exceeds maximum supported limit.\"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "USE_LINKER_RESPONSE_FILE"
+ Value = "0"
+ Help = "When this option is enabled, all linker options are passed via the response file.\Enable when the length of the linker command line exceeds maximum supported limit.\"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "GENERATE_CC_LISTING_FILE"
+ Value = "0"
+ Help = "Enables/disables generation of the assembly listing file."
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "TRACE_LEVEL_MASK"
+ Value = "TRACE_ALWAYS"
+ Help = "Defines enabled trace message levels.\The value is a bitwise OR of trace levels defined in AmiLib.h.\TRACE_ALWAYS enables all trace messages.\TRACE_NEVER disables all trace messages.\Has no effect if trace messages are disabled."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_DEFAULTS_IN_FV_MAIN"
+ Value = "1"
+ Help = "When this token is enabled, a copy of setup defaults \will be included into FV_MAIN as an FFS file $(BUILD_DIR)\Defaults.ffs"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Token = "AMITSE_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "UART_INPUT_CLOCK"
+ Value = "1843200"
+ Help = "This is an UART input clock. The default value is (24000000/13) = 1843200 MHz"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_DATA_LAYOUT_OVERRIDE_SUPPORT"
+ Value = "0"
+ Help = "This switch enables/disables support of the setup data (SETUP_DATA) structure override.\When this token is disabled (default), the SETUP_DATA definition is generated by the build process based on the content of the project .sd files.\When this token is enabled, the SETUP_DATA definition is provided by the external header defined by the SETUP_DATA_LAYOUT_OVERRIDE_HEADER SDL token\"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_DATA_LAYOUT_OVERRIDE_HEADER"
+ Help = "Name of the project specific header file containing definition of the setup data structure.\The project specific definition replaces generic once when SETUP_DATA_LAYOUT_OVERRIDE_HEADER\token is enabled."
+ TokenType = Integer
+ TargetMAK = Yes
+ Token = "SETUP_DATA_LAYOUT_OVERRIDE_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "LZMA_SUPPORT"
+ Value = "0"
+ Help = "Enables/Disables LZMA compression support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BUILD_RULES"
+ Value = "$(CORE_DIR)\Rules.mak"
+ Help = "Name of the template file processed by CIF2MAK to generate the make file."
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CIF2MAK_DEFAULTS"
+ Value = "/r$(BUILD_RULES) /d$(PROJECT_DIR) /o$@ /vPROJECT_DIR /lproject.lfo"
+ Help = "Command line of the CIF2MAK utility."
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "BACKWARD_COMPATIBLE_MODE"
+ Value = "1"
+ Help = "Enables/Disabled backward compatibility definitions in Core header files."
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "NO_PI_MP_SERVICES_SUPPORT"
+ Value = "1"
+ Help = "Temporarily added to avoid collision with CPU module"
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "ROM_LAYOUT_EX"
+ Value = "$(BUILD_DIR)\RomLayoutEx.bin"
+ Help = "Name of the file used by secure flash module to sign ROM image"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "USE_RECOVERY_IMAGE_ON_FLASH_UPDATE"
+ Value = "1"
+ Help = "If set to 1 system will boot using image provided in recovery capsule"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "CORE_DIR"
+End
+
+ELINK
+ Name = "FV_MAIN"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FV_MAIN_NESTED"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CFLAGS"
+ Help = "command line options of the C compiler"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/nologo /c /Gy"
+ Parent = "CFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/W3 /WX"
+ Parent = "CFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LFLAGS"
+ Help = "command line options for 32-bit linker"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/NOLOGO"
+ Parent = "LFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/OPT:REF"
+ Parent = "LFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AFLAGS"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/nologo /c /Cx"
+ Parent = "AFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/W3 /WX"
+ Parent = "AFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AFLAGS16"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/nologo /c /omf /Cx"
+ Parent = "AFLAGS16"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/OUT:$@"
+ Parent = "LFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "FV_BB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(CORE_DIR)\FloppyCtrl.ffs"
+ Parent = "FV_BB"
+ Token = "FLOPPY_CTRL_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(CORE_DIR)\FileSystem$(ARCH).ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AmiProtocolLib.lib"
+ Parent = "AMIDXELIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AmiPpiLib.lib"
+ Parent = "AMIPEILIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PROCESSOR"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PROCESSOR_RULES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Font.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(GLOBAL_DEFINES)"
+ Parent = "CFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(GLOBAL_DEFINES)"
+ Parent = "AFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(GLOBAL_DEFINES)"
+ Parent = "AFLAGS16"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SELECTIVE_DEBUGGING"
+ Token = "SELECTIVE_DEBUGGING_SUPPORT" "=" "1"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "/D EFI_SPECIFICATION_VERSION=$(EFI_SPECIFICATION_VERSION)"
+ Parent = "GLOBAL_DEFINES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D PI_SPECIFICATION_VERSION=$(PI_SPECIFICATION_VERSION)"
+ Parent = "GLOBAL_DEFINES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "GLOBAL_DEFINES"
+ Help = "Global macro definitions. Added to CFLAGS and AFLAGS"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ROM_IMAGE"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(FV_BB_DESCRIPTOR)"
+ Parent = "ROM_IMAGE"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(FV_MAIN_DESCRIPTOR)"
+ Parent = "ROM_IMAGE"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(NVRAM_BACKUP_DESCRIPTOR)"
+ Parent = "ROM_IMAGE"
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(FV_NVRAM_DESCRIPTOR)"
+ Parent = "ROM_IMAGE"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/NODEFAULTLIB /DLL /ALIGN:32 /IGNORE:4108"
+ Parent = "LFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/SUBSYSTEM:NATIVE"
+ Parent = "LFLAGS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Defaults.ffs"
+ Parent = "FV_MAIN"
+ Token = "SETUP_DEFAULTS_IN_FV_MAIN" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D BACKWARD_COMPATIBLE_MODE=1"
+ Parent = "GLOBAL_DEFINES"
+ Token = "BACKWARD_COMPATIBLE_MODE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D NO_PI_MP_SERVICES_SUPPORT=1"
+ Parent = "GLOBAL_DEFINES"
+ Token = "NO_PI_MP_SERVICES_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+OUTPUTREGISTER
+ Name = "TOKEN_EQU"
+ Path = "Build"
+ File = "token.equ"
+End
+
+OUTPUTREGISTER
+ Name = "TOKEN_H"
+ Path = "Build"
+ File = "token.h"
+End
+
+OUTPUTREGISTER
+ Name = "TOKEN_MAK"
+ Path = "Build"
+ File = "token.mak"
+End
+
+OUTPUTREGISTER
+ Name = "MODULE_MAK"
+ Help = "list of make files for enabled components"
+ Path = "Build"
+ File = "module.mak"
+End
+
+OUTPUTREGISTER
+ Name = "BUSNUM_XLAT"
+ Path = "Build"
+ File = "BusNumXlat.INC"
+End
+
+OUTPUTREGISTER
+ Name = "IRQ_ASM"
+ Path = "Build"
+ File = "oempir.inc"
+End
+
diff --git a/Core/CoreSrc.cif b/Core/CoreSrc.cif
new file mode 100644
index 0000000..e5946b3
--- /dev/null
+++ b/Core/CoreSrc.cif
@@ -0,0 +1,20 @@
+<component>
+ name = "Core Sources"
+ category = eCore
+ LocalRoot = "Core\"
+ RefName = "CoreSrc"
+[files]
+"CoreSrc.sdl"
+[parts]
+"LibSrc"
+"RuntimeSrc"
+"IdeBusSrc"
+"FloppyCtrl"
+"FileSystem"
+"RecoverySrc"
+"FoundationEdk"
+"NVRAM"
+"PciBusSrc"
+"EdkIILib"
+"Capsule2_0"
+<endComponent>
diff --git a/Core/CoreSrc.sdl b/Core/CoreSrc.sdl
new file mode 100644
index 0000000..5bb2984
--- /dev/null
+++ b/Core/CoreSrc.sdl
@@ -0,0 +1,50 @@
+TOKEN
+ Name = "CoreSrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Core Sources support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "PEI_PERFORMANCE"
+ Value = "0"
+ Help = "Enables/Disables PEI performance measurement API"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "DXE_PERFORMANCE"
+ Value = "0"
+ Help = "Enables/Disables PEI performance measurement API"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "USE_DXE_STATUS_CODE_INSTANCE_IN_SMM"
+ Value = "0"
+ Help = "To use DXE status code instance from SMM set this token to On.\If this token is Off, SMM instance is used.\Setting this token to On is not safe (calls outside of SMM) and should only be done for debug purposes. "
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "DEBUG_CODE" "=" "1"
+End
+
+ELINK
+ Name = "/D EFI_DXE_PERFORMANCE"
+ Parent = "GLOBAL_DEFINES"
+ Token = "DXE_PERFORMANCE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D EFI_PEI_PERFORMANCE"
+ Parent = "GLOBAL_DEFINES"
+ Token = "PEI_PERFORMANCE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/ACPI/ACPICORE.CIF b/Core/EM/ACPI/ACPICORE.CIF
new file mode 100644
index 0000000..7278965
--- /dev/null
+++ b/Core/EM/ACPI/ACPICORE.CIF
@@ -0,0 +1,23 @@
+<component>
+ name = "ACPI - Core"
+ category = ModulePart
+ LocalRoot = "Core\EM\ACPI\"
+ RefName = "ACPI_CORE"
+[files]
+"AcpiCore.c"
+"AcpiCore.h"
+"mptable.c"
+"mptable.h"
+"MpPciIrq.asm"
+"AcpiS3.h"
+"Aml.c"
+"AmlChild.c"
+"AmlNamespace.c"
+"AmlOption.c"
+"AmlString.c"
+"AcpiSdt.c"
+"AcpiSdtPrivate.h"
+[parts]
+"ASL_CORE"
+"AtadSmi"
+<endComponent>
diff --git a/Core/EM/ACPI/AMLUPD.asl b/Core/EM/ACPI/AMLUPD.asl
new file mode 100644
index 0000000..112797c
--- /dev/null
+++ b/Core/EM/ACPI/AMLUPD.asl
@@ -0,0 +1,163 @@
+// OEM ASL file. Defines ASL Name fields to be linked to AML Exchange bufer location
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AMLUPD.asl 10 10/14/10 4:59p Oleksiyy $
+//
+// $Revision: 10 $
+//
+// $Date: 10/14/10 4:59p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AMLUPD.asl $
+//
+// 10 10/14/10 4:59p Oleksiyy
+// [TAG] EIP46166
+// [Category] Improvement
+// [Description] Fix to made Primary VGA selection on different Root
+// Bridges backward compatible with Core 4.6.4.0.
+// [Files] AMLUPD.asl, RbRes.asl
+//
+// 9 9/28/09 6:35p Yakovlevs
+// Changes to support Multy Root resource reporting features.
+// All PCI ROOT resource reporting features moved to RbRes.asl
+//
+// 8 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 7 6/28/05 5:22p Yakovlevs
+//
+// 6 6/03/05 2:42p Yakovlevs
+//
+// 5 5/31/05 12:09p Yakovlevs
+//
+// 4 5/27/05 5:57p Yakovlevs
+//
+// 3 5/18/05 11:49a Yakovlevs
+//
+// 2 5/05/05 7:11p Yakovlevs
+//
+// 3 5/05/05 5:39p Yakovlevs
+//
+// 2 4/28/05 2:51p Yakovlevs
+//
+// 1 4/25/05 10:56a Markw
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 8 7/17/02 12:13p Alexp
+// Add example of code to report memory above 4GB. Code is commented out.
+//
+// 7 6/10/02 11:53a Alexp
+// Delete IO APIC related ranges from AMLdata buffer. Use ACPI SDL
+// parameters to provide same ranges.
+//
+// 6 5/17/02 11:01a Alexp
+// Removed several names (SPIO, PMBS,..) as they were defined as static
+// equates and can be passed to ASL from SDL outut directly, not using
+// Aml_exchange buffer
+//
+// 5 3/20/02 11:54a Alexp
+//
+// 4 2/26/02 12:16p Alexp
+// Update headers to generate proper .chm help
+//
+// 3 11/05/01 1:23p Alexp
+// Remove Thermal variables from Template AML_Exchange buffer
+//
+// 2 11/01/01 9:50a Alexp
+//
+//----------------------------------------------------------------------
+
+
+//;<AMI_THDR_START>
+//;------------------------------------------------------------------------/
+//;
+//; Name: BIOS
+//;
+//; Type: OperationRegion
+//;
+//; Description: Set of name objects used as an exchange buffer for BIOS to
+//; pass the System information to AML code
+//; List of mandatory Name Objects to be defined:
+//; SS1 - SS4 - BIOS setup enabled sleep states.
+//; MG1B, MG1L - Non-shadowed memory range below 1Mb. Available for PCI0 bus.
+//; MG2B, MG2L - Memory range above available System memory. Available for PCI0 bus.
+//;
+//; Notes: Memory location and all Name values are updated in BIOS POST
+//; Referrals: AMLDATA
+//;-------------------------------------------------------------------------
+//;<AMI_THDR_END>
+
+///////////////////////////////////////////////////////////////////////////////////
+//Values are set like this to have ASL compiler reserve enough space for objects
+///////////////////////////////////////////////////////////////////////////////////
+// Available Sleep states
+Name(SS1,1) // is S1 enabled in setup?
+Name(SS2,0)
+Name(SS3,1)
+Name(SS4,1)
+///////////////////////////////////////////////////////////////////////////////////
+// Bit mask of statuses of IO peripheral devices, enabled in Setup
+// 0x0 - Serial A (Modem)
+// 1 - Serial B (IR)
+// 2 - LPT
+// 3 - FDD
+//----------------------------
+// 4 - SB16 Audio
+// 5 - Midi
+// 6 - Mss Audio
+// 7 - Adlib sound (FM synth)
+//----------------------------
+// 8 - Game 1 port
+// 9 - Game 2 port
+// a - KBC 60 & 64
+// b - EC 62 & 66
+//----------------------------
+// c - reserved
+// d - reserved
+// e - PS2Mouse
+// f - reserved
+///////////////////////////////////////////////////////////////////////////////////
+Name(IOST,0xFFFF) // Bit mask of statuses of IO peripheral devices,
+ // enabled in Setup
+///////////////////////////////////////////////////////////////////////////////////
+Name(TOPM,0xFFFFF) // System memory top address below 4GB, bytes
+
+///////////////////////////////////////////////////////////////////////////////////
+Name(ROMS,0xffe00000) // Boot strap BIOS image address at top 4Gbyte
+
+///////////////////////////////////////////////////////////////////////////////////
+Name(VGAF, 0x1) //Flag to indicate Legacy VGA Resources were clamed already
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/ASLCORE.CIF b/Core/EM/ACPI/ASLCORE.CIF
new file mode 100644
index 0000000..7a3fe18
--- /dev/null
+++ b/Core/EM/ACPI/ASLCORE.CIF
@@ -0,0 +1,37 @@
+<component>
+ name = "ASL - CORE"
+ category = ModulePart
+ LocalRoot = "CORE\EM\ACPI\"
+ RefName = "ASL_CORE"
+[files]
+"\Uart4ir.asl"
+"\Uart4.asl"
+"\Uart3ir.asl"
+"\Uart3.asl"
+"\Uart2ir.asl"
+"\Uart2.asl"
+"\Uart1ir.asl"
+"\Uart1.asl"
+"\SMB_EC.ASL"
+"\PS2ms.asl"
+"\PS2kb.asl"
+"\midi.asl"
+"\MAX1617R.ASL"
+"\MAX1617L.ASL"
+"\Mathco.asl"
+"\Lpte.asl"
+"\LM75.ASL"
+"\irda.asl"
+"\GameMpu.asl"
+"\game.asl"
+"\Fdc.asl"
+"\CIR.ASL"
+"\rmisc.asl"
+"\AMLUPD.asl"
+"\asllib.asl"
+"\OSCM.asl"
+"\PCIEACCESS.ASL"
+"\PCIEHP.ASL"
+"\RbRes.asl"
+"\TimeAndAlarm.asl"
+<endComponent>
diff --git a/Core/EM/ACPI/AcpiCore.c b/Core/EM/ACPI/AcpiCore.c
new file mode 100644
index 0000000..7cb3366
--- /dev/null
+++ b/Core/EM/ACPI/AcpiCore.c
@@ -0,0 +1,4475 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/ACPI/AcpiCore.c 9 4/16/14 6:17a Chaseliu $
+//
+// $Revision: 9 $
+//
+// $Date: 4/16/14 6:17a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/ACPI/AcpiCore.c $
+//
+// 9 4/16/14 6:17a Chaseliu
+// sync to ACPI module 48
+//
+// 8 9/18/13 4:06a Thomaschen
+// Update for ACPI module labeled 47.
+//
+// 108 3/14/14 10:42a Oleksiyy
+// [TAG] EIP121819
+// [Category] Improvement
+// [Description] Add FID acpi table. filling of Tbl_IDs up to date.
+// [Files] AcpiCore.c.
+//
+// 107 3/03/14 5:02p Oleksiyy
+// [TAG] EIP154308
+// [Category] Improvement
+// [Description] Aptio 4: Intel Doc #542550 4h) FirmwarePerformance EFI
+// variable contains address of FPDT ACPI table.
+// [Files] AcpiCore.c and S3Resume.c
+//
+// 106 1/23/14 5:38p Oleksiyy
+// [TAG] EIP113941
+// [Category] New Feature
+// [Description] Time and Alarm ACPI device implemented.
+// [Files] AcpiCore.c
+// ACPICORE.CIF
+//
+// 105 10/28/13 12:05p Oleksiyy
+// [TAG] EIP121819
+// [Category] Improvement
+// [Description] Add FID acpi table.
+// [Files] AcpiCore.c, AcpiCore.h
+//
+// 104 10/04/13 11:55a Oleksiyy
+// [TAG] EIP138574
+// [Category] Improvement
+// [Description] Assert in LockLegacyRes removed.
+// [Files] AcpiCore.c
+//
+// 103 8/12/13 4:07p Oleksiyy
+// [TAG] EIP132574
+// [Category] Improvement
+// [Description] When checking address range && replaced with & to save
+// memory.
+// [Files] AcpiCore.c
+//
+// 102 8/01/13 6:00p Oleksiyy
+// [TAG] EIP130457
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang up 78h and BSOD issue after enter OS when
+// enable X64 support
+// [RootCause] hen only RSDT is validayted by OS and DSDT was located
+// above 4Gig and then typecasted to UINT32 addres info was lost.
+// [Solution] Allocate memory for DSDT always under 4 Gig.
+// [Files] AcpiCore.c
+//
+// 101 6/03/13 5:05p Oleksiyy
+// [TAG] EIP125666
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Wrong typecasting in Registernotify function.
+// [RootCause] Wrong typecasting in Registernotify function.
+// [Solution] Typecastnig removed.
+// [Files] AcpiCore.c
+//
+// 100 12/13/12 11:59a Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 99 11/19/12 6:01p Oleksiyy
+// [TAG] EIP101547
+// [Category] New Feature
+// [Description] Support Uninstalling MADT with ACPI Table Protocol
+// [Files] AcpiCore.c
+//
+// 98 6/12/12 3:17p Oleksiyy
+// TAG] EIP90322
+// [Category] Improvement
+// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to
+// AmiLib.h.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 97 6/12/12 11:16a Oleksiyy
+// [TAG] EIP88889
+// [Category] Improvement
+// [Description] FACP ver 5.0 structure added, FPDT mesurment accuracy
+// improved.
+// [Files] ACPI50.h, ACPI.sdl, AcpiCore.c, S3Resume.c, Image.c,
+// EfiLib.c
+//
+// 96 5/22/12 4:33p Oleksiyy
+// [TAG] EIP90322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail, improper variable FPDT_Variable in
+// ACPI module
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 95 5/04/12 10:48a Oleksiyy
+// [TAG] EIP88478
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ACPI error when booting to Windows with 4G+ memory
+// [RootCause] "x64_BUILD_SUPPORT" not defined
+// [Solution] Change to EFIx64 identifier.
+// [Files] AcpiCore.c
+//
+// 94 4/12/12 11:53a Oleksiyy
+// [TAG] EIP86325
+// [Category] Improvement
+// [Description] Disabling PciExpNative in BIOS setup doesn't cause bit
+// 4 in IAPC_BOOT_ARCH to be set.
+// Bit preservation is added.
+// [Files] AcpiCore.c
+//
+// 93 12/05/11 4:24p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Increasing of whole table length after adding FPDT was
+// skiped by mistake. Fixed
+// [Files] AcpiCore.c.
+//
+// 92 11/28/11 5:34p Oleksiyy
+// [TAG] EIP76419
+// [Category] Improvement
+// [Description] TPL level chang to TPL_APPLICATION removed in ACPI
+// Table Protocol functions
+// [Files] AcpiCore.c
+//
+// 90 11/11/11 5:10p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added. FirmPerfDataTab.h renamed to ACPI50.h
+// [Files] AcpiCore.c, EfiLib.c, S3Resume.c and ACPI50.h added.
+//
+// 89 11/08/11 4:52p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added.
+// [Files] AcpiCore.c, AmiDxeLib.h, CSM.c, DxeMain.c, EfiLib.c,
+// Image.c, S3Resume.c and FirmPerfDataTab.h
+//
+// 88 10/25/11 5:54p Oleksiyy
+// [TAG] EIP71540
+// [Category] Improvement
+// [Description] Fix of "any amount of spaces in table IDs replaced with
+// only one".
+// [Files] ACPI.mak and AcpiCore.c
+//
+// 87 9/30/11 4:23p Oleksiyy
+// [TAG] EIP71374
+// [Category] Improvement
+// [Description] ACPI sleep state setup option update.
+// [Files] ACPI.sd, ACPI.uni and AcpiCore.c
+//
+// 86 8/30/11 4:04p Oleksiyy
+// [TAG] EIP67951
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BGRT Table does not exist in XSDT
+// [RootCause] Due to bug in OEM Activation routine last table in XSDT
+// was deleted.
+// [Solution] Wrong else statment fixed.
+// [Files] AcpiCore.c
+//
+// 85 7/19/11 11:31a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 84 6/10/11 5:10p Oleksiyy
+// [TAG] EIP60372
+// [Category] Improvement
+// [Description] Conformance fix in Uninstall Table function.
+// [Files] AcpiCore.c
+//
+// 83 5/27/11 5:32p Felixp
+// Enhancement: AcpiInstallAcpiTable/ AcpiUninstallAcpiTable are updated.
+// CONST qualifier is added to the parameters to match the specification.
+//
+// 82 5/20/11 2:39p Oleksiyy
+// [TAG] EIP60633
+// [Category] New Feature
+// [Description] Acpi part of Microsoft OEM Activation 3.0
+// [Files] AcpiCore.c
+//
+// 81 5/18/11 5:15p Oleksiyy
+// [TAG] EIP60634
+// [Category] Improvement
+// [Description] Small fix in Install table functionality
+// [Files] AcpiCore.c
+//
+// 80 5/14/11 2:47p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+// 79 4/06/11 6:01p Markw
+// [TAG] EIP53334
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] CPU module provide NMI information if protocol
+// available. This is to properly support x2APIC NMI structures.
+// [Files] AcpiCore.c
+//
+// 78 3/16/11 12:07p Oleksiyy
+// [TAG] EIP56178
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Assert on Legacy free systems
+// [RootCause] The function LockLegacyRes() will assert if it cannot
+// find any handles that have the gEfiAmiSioProtocolGuid installed on
+// them.
+// [Solution] Assert removed from LockLegacyRes function.
+// [Files] AcpiCore.c
+//
+// 77 3/03/11 6:09p Oleksiyy
+// [TAG] EIP55071
+// [Category] New Feature
+// [Description] APIC/SAPIC Differentiation Algorithm Not Working for
+// AMD I/O APIC
+// Sdl tokens are added to set set IOAPIC/IOSAPIC and LAPIC/LSAPIC
+// revision BOUNDARY.
+// [Files] ACPI.sdl and AcpiCore.c
+//
+// 76 1/03/11 10:46a Oleksiyy
+// [TAG] EIP49202
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang at CKP 0x9A
+// [RootCause] System hang at CKP 0x9A if memory is up to 4GB or above
+// and token "x64_BUILD" = 0, "DEBUG_MODE" = 1.
+// [Solution] gRsdtPtrStr typecasted to UINTN before typecasting to
+// EFI_PHYSICAL_ADDRESS.
+// [Files] AcpiCore.c
+//
+// 75 12/23/10 12:02p Oleksiyy
+// [TAG] EIP50019
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Add support for all fields of ACPI_IA_BOOT_ARCH flag in
+// FACP
+// [RootCause] All values of ACPI_IA_BOOT_ARCH flag, added in ACPI 4
+// spec, is cleared during updating of LEGACY_DEVICES and 8042 fields in
+// CollectAmlUpdInfo routine.
+// [Solution] AcpiCore.c file modified to preserve values of
+// ACPI_IA_BOOT_ARCH flag set in sdl file.
+// [Files] AcpiCore.c and ACPI.sdl
+//
+// 74 12/17/10 5:14p Oleksiyy
+// [TAG] EIP50325
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Incorrect order of MADT entries for Agesa projects
+// [RootCause] Dummy entries placed before active cores in MADT table
+// [Solution] Token SKIP_DUMMY_LAPICS should be added to any .sdl file
+// to force AcpiCore not to create dummy lapics entires for processors
+// that are absent, but could be hot plugged.
+// Also, BuildLapic function changed and now dummy lapics will have higher
+// Id.
+// [Files] AcpiCore.c
+//
+// 73 10/11/10 5:52p Oleksiyy
+// Healp builder error - Function Header Fixed.
+//
+// 72 10/01/10 11:55a Oleksiyy
+// Issue Number: 45160
+//
+// Category: Improvement
+//
+// Description: AcpiSupportSetAcpiTable function was modified to checksum
+// table, after it was changed by OemAcpiSetPlatformId hook, if Checksum
+// parameter of SetAcpiTable function is FALSE, but table was correctly
+// checksumed before call to OemAcpiSetPlatformId hook.
+//
+// Files: AcpiCore.c
+//
+// 71 9/27/10 11:56a Oleksiyy
+// Issue Number: 44740
+//
+// Category: Improvement
+//
+// Description: Functionality to Publish all tables, added on ReadyToBoot
+// through EFI_ACPI_SUPPORT_PROTOCOL, automatically
+// is added.
+//
+// Files: AcpiCore.c
+//
+// 70 5/25/10 11:07a Oleksiyy
+// Assert in publish tables fixed
+//
+// 69 4/28/10 2:46p Oleksiyy
+// EIP 35563 "Force to ACPI ver. 1.1" ACPI setup menu (default is OFF)
+// added. If Enabled - only Tables for ver. 1.1 will be builded (FACP,
+// FACS,
+// RSDT (no XSDT), and MADT) al other tables added by means of
+// ACPI protocols not modified.
+// EIP 37874 - ACPI_APIC_TBL token added if OFF - MADT will not
+// created (PIC mode).
+//
+// 68 4/05/10 4:46p Oleksiyy
+// EIP 37055 - TPL check added. + Some spelling issues fixed.
+//
+// 67 2/19/10 12:24p Oleksiyy
+// EIP 35099: Functionality to lock legacy resources from OS added,
+// based on setup question. Default value controlled by
+// DEFAULT_ACPI_LOCK_LEGACY_DEV SDL token and "OFF".
+//
+// 66 2/02/10 2:45p Oleksiyy
+// EIP 32520 Update AML part function is changed to perform update
+// before publishing table. Freepool assert when trying to delete old
+// DSDT fixed.
+//
+// 65 12/08/09 11:41a Oleksiyy
+// Minor bug fix in typecasting
+//
+// 64 11/24/09 5:20p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support.
+//
+// 63 9/28/09 6:32p Yakovlevs
+// Changes to support Multy Root resource reporting features.
+// All PCI ROOT resource reporting features moved to PciHootBridge.c.
+//
+// 62 9/25/09 11:24a Oleksiyy
+// EIP 26777: RSDP Revision fixed
+//
+// 61 8/20/09 3:02p Oleksiyy
+// EIP 25407: 32 bit mode bug fix
+//
+// 60 8/11/09 3:39p Markw
+// EIP #24914 - Add local x2APIC support.
+//
+// 59 5/27/09 5:39p Yakovlevs
+// Fixed inconsistancy in SetAcpiTable Routine.
+//
+// 58 5/26/09 1:44p Yakovlevs
+// Fixed Issues in Pointers handling in SetAcpiTable fubction
+//
+// 57 5/18/09 10:09a Yakovlevs
+// Fixed issue in sorting IOAPICs entries.
+//
+// 56 5/15/09 12:49p Yakovlevs
+// Fixed logic in IOAPIC discovery ordering.
+//
+// 55 5/14/09 5:36p Yakovlevs
+// Minor bug fixes and Improvements see release notes for Label 31
+//
+// 54 5/08/09 1:15p Yakovlevs
+// Made ACPI Driver use AMI Board Info Protocol if available without
+// breaking compatibility.
+//
+// 53 5/07/09 5:46p Markw
+// Use #ifdef ACPI_INFO2_PROTOCOL_PUBLISHED to exclude code that uses ACPI
+// INFO 2 for CPUs that provide the header files.
+//
+// 52 5/04/09 5:48p Markw
+// EIP #17903 Use AmiCpuInfo2 Protocol if available. Small bug fixes from
+// last update.
+//
+// 51 4/30/09 5:51p Markw
+// EIP #17903 Use AmiCpuInfo2 Protocol if available. This provides correct
+// ordering for Nehalem in APIC table.
+//
+// 50 4/27/09 5:39p Oleksiyy
+// EIP 21205 - Win XP (SP2) instalation problem fix. Added compatibility
+// fields in FACP Ver 1.
+//
+// 49 4/14/09 11:13a Oleksiyy
+// Removed one ASSERT.
+//
+// 48 3/27/09 4:09p Oleksiyy
+// Code clean-up.
+//
+// 47 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 2/18/09 3:51p Oleksiyy
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <AcpiCore.c>
+//
+// Description: Main ACPI Driver File. It has ACPI Driver entry point,
+// ACPISupport Protocol and ACPITable Protocol.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#if PI_SPECIFICATION_VERSION >= 0x10014
+#include <Protocol\SuperIo.h>
+#else
+#include <Protocol\AmiSio.h>
+#endif
+#include <Protocol\DevicePath.h>
+#include <AMIHobs.h>
+#include <token.h>
+#include <Dxe.h>
+#include <AcpiRes.h>
+#include "AcpiCore.h"
+#include <Setup.h>
+#include "AcpiOemElinks.h"
+#include "ACPI50.h"
+#include <Ppi\FwVersion.h>
+#if ATAD_SUPPORT == 1
+#include "AtadSmi.h"
+#endif
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+#include <Protocol\AmiCpuInfo2.h>
+#endif
+
+
+#include <Protocol\AmiBoardInfo.h>
+#include <Protocol/Cpu.h>
+ // [EIP106575], [EIP106731]>
+#include <Protocol/MpService.h>
+ // <[EIP106575], [EIP106731]
+EFI_GUID gAmiBoardInfoGuid = AMI_BOARD_INFO_PROTOCOL_GUID;
+AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfoProtocol=NULL;
+
+//--------------------------------------
+//Some Global vars
+EFI_GUID gDsdt11Guid = EFI_ACPI_DSDT_V_1_1_GUID;
+EFI_GUID gDsdt20Guid = EFI_ACPI_DSDT_V_2_0_GUID;
+//EFI_GUID gDPProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+//EFI_GUID gSioProtocolGuid = EFI_AMI_SIO_PROTOCOL_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+AMI_CPU_INFO_2_PROTOCOL* gAmiCpu2Info;
+EFI_GUID gAmiCpuInfo2ProtocolGuid = AMI_CPU_INFO_2_PROTOCOL_GUID;
+#endif
+
+ACPI_DB gAcpiData = {0, 0, NULL, 0};
+FACS_20 *gFacs, *gxFacs;
+RSDT_PTR_20 *gRsdtPtrStr = NULL;
+UINTN gAcpiTblPages = 0;
+ACPI_AML_UPD_INFO *gAuiGlob = NULL;
+UINT16 gAcpiIaBootArch=0xFFFF;
+EFI_EVENT gEvtReadyToBoot;
+EFI_GUID gAcpi11TAbleGuid = EFI_ACPI_11_TABLE_GUID;
+EFI_GUID gAcpi20TAbleGuid = EFI_ACPI_20_TABLE_GUID;
+BOOLEAN gX2Apic = FALSE;
+UINT8 gForceAcpi1 = 0, gPublishedOnReadyToBoot = 0, gMaxLapic = 0;
+
+//Here goes Interrupt Source Override MADT entry parameter table
+//Generated From Information on IRQ_XX_OVERRIDE_ENABLE SDL tokens
+ISO_PARAMETER_TABLE IsoTbl[]=
+{
+//UINT8 PicIrq; UINT8 Flags; UINT16 ApicInt
+#if IRQ_00_OVERRIDE_ENABLE == 1
+ { 0x00, (IRQ_00_TRIGGER_MODE<<2)|IRQ_00_POLARITY, IRQ_00_APIC_INT },
+#else
+ { 0xFF, 0, 0 },
+#endif
+#if IRQ_01_OVERRIDE_ENABLE == 1
+ { 0x01, (IRQ_01_TRIGGER_MODE<<2)|IRQ_01_POLARITY, IRQ_01_APIC_INT },
+#else
+ { 0xFF, 0, 1 },
+#endif
+//just dummy entry instead of IRQ2 to keep array consistent
+ { 0xFF, 0, 2 },
+#if IRQ_03_OVERRIDE_ENABLE == 1
+ { 0x03, (IRQ_03_TRIGGER_MODE<<2)|IRQ_03_POLARITY, IRQ_03_APIC_INT },
+#else
+ { 0xFF, 0, 3 },
+#endif
+#if IRQ_04_OVERRIDE_ENABLE == 1
+ { 0x04, (IRQ_04_TRIGGER_MODE<<2)|IRQ_04_POLARITY, IRQ_04_APIC_INT },
+#else
+ { 0xFF, 0, 4 },
+#endif
+#if IRQ_05_OVERRIDE_ENABLE == 1
+ { 0x05, (IRQ_05_TRIGGER_MODE<<2)|IRQ_05_POLARITY, IRQ_05_APIC_INT },
+#else
+ { 0xFF, 0, 5 },
+#endif
+#if IRQ_06_OVERRIDE_ENABLE == 1
+ { 0x06, (IRQ_06_TRIGGER_MODE<<2)|IRQ_06_POLARITY, IRQ_06_APIC_INT },
+#else
+ { 0xFF, 0, 6 },
+#endif
+#if IRQ_07_OVERRIDE_ENABLE == 1
+ { 0x07, (IRQ_07_TRIGGER_MODE<<2)|IRQ_07_POLARITY, IRQ_07_APIC_INT },
+#else
+ { 0xFF, 0, 7 },
+#endif
+
+#if IRQ_08_OVERRIDE_ENABLE == 1
+ { 0x08, (IRQ_08_TRIGGER_MODE<<2)|IRQ_08_POLARITY, IRQ_08_APIC_INT },
+#else
+ { 0xFF, 0, 8 },
+#endif
+#if IRQ_09_OVERRIDE_ENABLE == 1
+ { 0x09, (IRQ_09_TRIGGER_MODE<<2)|IRQ_09_POLARITY, IRQ_09_APIC_INT },
+#else
+ { 0xFF, 0, 9 },
+#endif
+#if IRQ_10_OVERRIDE_ENABLE == 1
+ { 0x0A, (IRQ_10_TRIGGER_MODE<<2)|IRQ_10_POLARITY, IRQ_10_APIC_INT },
+#else
+ { 0xFF, 0, 10 },
+#endif
+#if IRQ_11_OVERRIDE_ENABLE == 1
+ { 0x0B, (IRQ_11_TRIGGER_MODE<<2)|IRQ_11_POLARITY, IRQ_11_APIC_INT },
+#else
+ { 0xFF, 0, 11 },
+#endif
+#if IRQ_12_OVERRIDE_ENABLE == 1
+ { 0x0C, (IRQ_12_TRIGGER_MODE<<2)|IRQ_12_POLARITY, IRQ_12_APIC_INT },
+#else
+ { 0xFF, 0, 12 },
+#endif
+#if IRQ_13_OVERRIDE_ENABLE == 1
+ { 0x0D, (IRQ_13_TRIGGER_MODE<<2)|IRQ_13_POLARITY, IRQ_13_APIC_INT },
+#else
+ { 0xFF, 0, 13 },
+#endif
+#if IRQ_14_OVERRIDE_ENABLE == 1
+ { 0x0E, (IRQ_14_TRIGGER_MODE<<2)|IRQ_14_POLARITY, IRQ_14_APIC_INT },
+#else
+ { 0xFF, 0, 14 },
+#endif
+#if IRQ_15_OVERRIDE_ENABLE == 1
+ { 0x0F, (IRQ_15_TRIGGER_MODE<<2)|IRQ_15_POLARITY, IRQ_15_APIC_INT },
+#else
+ { 0xFF, 0, 15 },
+#endif
+};
+
+static UINTN IsoCnt=sizeof(IsoTbl)/sizeof(ISO_PARAMETER_TABLE);
+
+EFI_STATUS MpsTableBuilderInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+MADT_ENTRY_HEADER * BuildLocalApicNmi(
+ IN BOOLEAN X2Apic,
+ IN UINT32 ProcessorId,
+ IN UINT8 LapicInitIn,
+ IN UINT16 Flags
+ );
+
+UINT8 ACPI_OEM_ID[6] = ACPI_OEM_ID_MAK; //"A M I"; //add 0 at the end.OemId 6 bytes
+UINT8 ACPI_OEM_TBL_ID[8] = ACPI_OEM_TBL_ID_MAK; //"ALASKA"; //add 0 at the end.OemTableId 8 bytes
+
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+#define EFI_OA3_MSDM_VARIABLE L"OA3MSDMvariable"
+
+typedef struct _EFI_OA3_MSDM_STRUCTURE {
+ EFI_PHYSICAL_ADDRESS XsdtAddress;
+ EFI_PHYSICAL_ADDRESS MsdmAddress;
+ EFI_PHYSICAL_ADDRESS ProductKeyAddress;
+} EFI_OA3_MSDM_STRUCTURE;
+
+BOOLEAN gOA3Variable = FALSE;
+EFI_OA3_MSDM_STRUCTURE gMsdmVariable;
+#endif
+
+#if ATAD_SUPPORT == 1
+ VOID *AtadBuffPtr = NULL;
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemCopy
+//
+// Description: This routine copies data from source to destination.
+//
+// Input:
+// fpSrc - Pointer to the source.
+// fpDest - Pointer to the destination.
+// wSize - Number of bytes to copy.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+MemCopy (
+ UINT8* fpSrc,
+ UINT8* fpDest,
+ UINT32 dSize)
+{
+ UINT32 dCount;
+
+ //
+ // Check for pointer validity
+ //
+ if ((fpSrc) && (fpDest))
+ {
+ for (dCount = 0; dCount < dSize; dCount++)
+ {
+ fpDest[dCount] = fpSrc[dCount];
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrepareHdr20
+//
+// Description:
+// This function creates ACPI table v 2.0+ header with specified signature
+//
+// Input:
+// IN UINT32 TblSig - ACPI table signature
+// IN OUT ACPI_HDR* HdrPtr - Pointer to memory, where the header should be placed
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void PrepareHdr20(UINT32 TblSig, ACPI_HDR *HeaderPtr, UINTN Vers)
+{
+ UINTN i;
+ EFI_STATUS Status;
+
+ if (HeaderPtr==NULL) return;
+
+ HeaderPtr->Signature=TblSig;
+
+ //Check what Revision# header needs depends on TABLE we're building
+ switch (TblSig)
+ {
+ case RSDT_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+1;
+ break;
+
+ case XSDT_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+2;
+ break;
+
+ case FACP_SIG:
+ HeaderPtr->Revision=ACPI_REV3;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+3;
+
+ if (Vers > 2)
+ {
+
+ HeaderPtr->Revision=ACPI_REV4;
+ HeaderPtr->CreatorRev++;
+ }
+
+ break;
+ case APIC_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ HeaderPtr->CreatorRev=CREATOR_REV_MS+4;
+
+ if (Vers > 2)
+ {
+
+ HeaderPtr->Revision=ACPI_REV2;
+ HeaderPtr->CreatorRev++;
+ }
+
+ if (Vers > 3)HeaderPtr->Revision=ACPI_REV3;
+
+ break;
+ case SBST_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ break;
+ case SPCR_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ break;
+ case ECDT_SIG:
+ HeaderPtr->Revision=ACPI_REV1;
+ break;
+ //case DSDT_SIG:
+ //HeaderPtr->CreatorRev=CREATOR_REV_MS+5;
+ //HeaderPtr->Revision=ACPI_REV2;
+ break;
+ }
+
+ //instead of puting fixed revision number
+ //HeaderPtr->Revision=ACPI_REV2;
+
+ //Dont' touch Creator ID and Creator Revision;
+ if (TblSig != DSDT_SIG)
+ {
+ if (TblSig == RSDT_SIG)
+ HeaderPtr->CreatorId = CREATOR_ID_MS;
+ else
+ HeaderPtr->CreatorId = CREATOR_ID_AMI;
+
+ HeaderPtr->CreatorRev = CREATOR_REV_MS;
+ HeaderPtr->OemRev = ACPI_OEM_REV;
+ }
+
+ //Get the platform specific OEM_IDs
+ Status=OemAcpiSetPlatformId(HeaderPtr);
+
+ //if platform does not support OEM_ID overwrite
+ if (EFI_ERROR(Status))
+ {
+ for (i=0; i<6; i++) HeaderPtr->OemId[i]=ACPI_OEM_ID[i];
+
+ for (i=0; i<8; i++) HeaderPtr->OemTblId[i]=ACPI_OEM_TBL_ID[i];
+ }
+
+} //PrepareHdr20
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrepareHdr1
+//
+// Description:
+// This function creates ACPI V1 table header with specified signature
+//
+// Input:
+// IN UINT32 TblSig - ACPI table signature
+// IN OUT ACPI_HDR* HdrPtr - Pointer to memory, where the header should be placed
+//
+// Output:
+// VOID
+//
+// Notes:
+// Depends on type of memory provided, ACPI table header can be in 32 or 64 bit
+// format
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void PrepareHdr1(UINT32 TblSig, ACPI_HDR* HdrPtr)
+{
+ UINTN i;
+ EFI_STATUS Status;
+
+ if (HdrPtr==NULL) return;
+
+ HdrPtr->Signature = TblSig;
+ HdrPtr->Revision = ACPI_REV1;
+
+ //Dont' touch Creator ID and Creator Revision;
+ if (TblSig != DSDT_SIG)
+ {
+ if (TblSig == RSDT_SIG)
+ HdrPtr->CreatorId = CREATOR_ID_MS;
+ else
+ HdrPtr->CreatorId = CREATOR_ID_AMI;
+
+ HdrPtr->CreatorRev = CREATOR_REV_MS;
+ HdrPtr->OemRev = ACPI_OEM_REV;
+ }
+
+ //Get the platform specific OEM_IDs
+ Status=OemAcpiSetPlatformId(HdrPtr);
+
+ //if platform does not support OEM_ID overwrite
+ if (EFI_ERROR(Status))
+ {
+ for (i=0; i<6; i++) HdrPtr->OemId[i]=ACPI_OEM_ID[i];
+
+ for (i=0; i<8; i++) HdrPtr->OemTblId[i]=ACPI_OEM_TBL_ID[i];
+ }
+
+}//PrepareHdr1
+
+
+
+ // [EIP106575], [EIP106731]>
+EFI_STATUS
+GetNanoFreqCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN VarSize = sizeof (UINT32);
+ EFI_FPDT_STRUCTURE *FpdtVar;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+
+ pBS->CloseEvent(Event);
+
+ Status = pRS->GetVariable(
+ EFI_FPDT_VARIABLE, \
+ &gAmiGlobalVariableGuid,
+ NULL, \
+ &VarSize, \
+ &FpdtVar );
+ if (EFI_ERROR (Status)) {
+ TRACE((-1,"Acpi BuildFPDT: No Cpu Protocol was found.\n"));
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (
+ &gEfiCpuArchProtocolGuid,
+ NULL,
+ &Cpu
+ );
+ if (!EFI_ERROR (Status)) {
+
+ UINT64 CurrentTicker, TimerPeriod;
+
+ Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod);
+
+ if (!EFI_ERROR (Status))
+ FpdtVar->NanoFreq = TimerPeriod;
+
+ if (FpdtVar->NanoFreq == 0) {
+ IoWrite8(0x80, 0xEE);
+ while(1);
+ }
+
+ } else {
+
+ TRACE((-1,"Acpi BuildFPDT: No Cpu Protocol was found.\n"));
+ return Status;
+
+ }
+
+ Status = pRS->SetVariable(
+ L"FPDT_Variable", \
+ &gAmiGlobalVariableGuid, \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+ EFI_VARIABLE_RUNTIME_ACCESS, \
+ sizeof(UINT32), \
+ &FpdtVar );
+
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+ // <[EIP106575], [EIP106731]
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFPDT
+//
+// Description: This function allocates memory for and fills FPDT struscure. It also
+// creates Variable with the addres od S3 and Normal Boot performance srtuctures
+// to be filled later.
+// Input:
+// IN UINTN TablVer - Version of FACP table
+// IN OUT **ACPI_HDR TablPtr - Pointer to memory, where the FACP table will resides.
+// Filled by this procedure
+// Output:
+// EFI_STATUS:
+// EFI_OUT_OF_RESOURCES - Memory for the table could not be allocated
+// EFI_SUCCESS - Table was successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildFPDT (IN UINTN TablVer, OUT ACPI_HDR **TablPtr)
+
+{
+ UINT8 *TempPtr;
+ PERF_TAB_HEADER *S3PerfRecHdr, *BasBootPerfRecHdr;
+ BASIC_S3_RESUME_PERF_REC *S3PerfRec;
+ BASIC_BOOT_PERF_REC *BasBootPerfRec;
+ UINTN RecordsSize;
+ FPDT_50 *FPDT;
+ EFI_STATUS Status;
+ EFI_FPDT_STRUCTURE *FpdtVar, *OldFpdtVarAddress;
+ EFI_CPU_ARCH_PROTOCOL *Cpu;
+ UINTN VarSize = sizeof (UINT32);
+ // [EIP106575], [EIP106731]>
+ VOID *Registration;
+ EFI_EVENT Event;
+ // <[EIP106575], [EIP106731]
+
+//-----------------------------
+
+ if (TablVer<1 || TablVer>4) return EFI_INVALID_PARAMETER;
+ RecordsSize = (sizeof(EFI_FPDT_STRUCTURE) + sizeof(PERF_TAB_HEADER)*2 +
+ sizeof(BASIC_S3_RESUME_PERF_REC)+
+ sizeof(BASIC_BOOT_PERF_REC));
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, RecordsSize, &TempPtr);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+#ifdef EFIx64
+ if (((UINT64)TempPtr) & 0xffffffff00000000)
+ {
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+ Status = pBS->FreePool(TempPtr);
+ ASSERT_EFI_ERROR(Status);
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiRuntimeServicesData, 1, &Memory);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ TempPtr = (UINT8*)Memory;
+ }
+#endif
+ pBS->SetMem(TempPtr, RecordsSize, 0);
+
+ *TablPtr = MallocZ (sizeof(FPDT_50));
+
+ if ((*TablPtr)==NULL)
+ {
+ ASSERT(*TablPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FpdtVar = (EFI_FPDT_STRUCTURE*) TempPtr;
+ TempPtr += sizeof(EFI_FPDT_STRUCTURE);
+ S3PerfRecHdr = (PERF_TAB_HEADER*) TempPtr;
+ TempPtr += sizeof(PERF_TAB_HEADER);
+ S3PerfRec = (BASIC_S3_RESUME_PERF_REC*)TempPtr;
+ TempPtr += sizeof(BASIC_S3_RESUME_PERF_REC);
+ BasBootPerfRecHdr = (PERF_TAB_HEADER*) TempPtr;
+ TempPtr += sizeof(PERF_TAB_HEADER);
+ BasBootPerfRec = (BASIC_BOOT_PERF_REC*)TempPtr;
+
+ S3PerfRecHdr->Signature = 0x54503353;// `S3PT'
+ S3PerfRecHdr->Length = sizeof(PERF_TAB_HEADER) + sizeof(BASIC_S3_RESUME_PERF_REC);
+
+ S3PerfRec->Header.PerfRecType = 0;
+ S3PerfRec->Header.RecLength = sizeof(BASIC_S3_RESUME_PERF_REC);
+ S3PerfRec->Header.Revision = 1;
+
+ BasBootPerfRecHdr->Signature = 0x54504246;// `FBPT'
+ BasBootPerfRecHdr->Length = sizeof(PERF_TAB_HEADER) + sizeof(BASIC_BOOT_PERF_REC);
+
+ BasBootPerfRec->Header.PerfRecType = 2;
+ BasBootPerfRec->Header.RecLength = sizeof(BASIC_BOOT_PERF_REC);
+ BasBootPerfRec->Header.Revision = 2;
+
+ FPDT = (FPDT_50*)*TablPtr;
+ PrepareHdr20(FPDT_SIG, (ACPI_HDR*)FPDT, TablVer);
+ FPDT->Header.Length = sizeof(FPDT_50);
+ FPDT->Header.Revision = 1;
+ FPDT->BasS3Rec.PerfRecType = 1;
+ FPDT->BasS3Rec.Length = sizeof(FPDT_PERF_RECORD);
+ FPDT->BasS3Rec.Revision = 1;
+ FPDT->BasS3Rec.Pointer = (EFI_PHYSICAL_ADDRESS)((UINTN)S3PerfRecHdr);
+
+ FPDT->BasBootRec.PerfRecType = 0;
+ FPDT->BasBootRec.Length = sizeof(FPDT_PERF_RECORD);
+ FPDT->BasBootRec.Revision = 1;
+ FPDT->BasBootRec.Pointer = (EFI_PHYSICAL_ADDRESS)((UINTN)BasBootPerfRecHdr);
+
+ FPDT->Header.Checksum = ChsumTbl((UINT8*)FPDT, FPDT->Header.Length);
+
+ Status = pBS->LocateProtocol (
+ &gEfiCpuArchProtocolGuid,
+ NULL,
+ &Cpu
+ );
+ if (!EFI_ERROR (Status))
+ {
+ UINT64 CurrentTicker, TimerPeriod;
+ Status = Cpu->GetTimerValue (Cpu, 0, &CurrentTicker, &TimerPeriod);
+ if (!EFI_ERROR (Status))
+ FpdtVar->NanoFreq = TimerPeriod;
+
+ } else {
+ Status = pBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ GetNanoFreqCallback,
+ NULL,
+ &Event
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = pBS->RegisterProtocolNotify (
+ &gEfiMpServiceProtocolGuid,
+ Event,
+ &Registration
+ );
+ }
+ }
+ // <[EIP106575], [EIP106731]
+
+ // Get Cpu Frequency
+
+ FpdtVar->S3Pointer = FPDT->BasS3Rec.Pointer;
+ FpdtVar->BasBootPointer = FPDT->BasBootRec.Pointer;
+ Status = pRS->SetVariable(
+ EFI_FPDT_VARIABLE,
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(UINT32),
+ &FpdtVar
+ );
+ Status = pRS->GetVariable(
+ L"FPDT_Variable_NV", &gAmiGlobalVariableGuid,
+ NULL, &VarSize, &OldFpdtVarAddress
+ );
+ if (EFI_ERROR(Status) || (FpdtVar != OldFpdtVarAddress))
+ {
+ Status = pRS->SetVariable(
+ L"FPDT_Variable_NV",
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32),
+ &FpdtVar
+ );
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFIDT
+//
+// Description: This function allocates memory for and fills FIDT struscure.
+//
+// Input:
+// IN OUT **ACPI_HDR TablPtr - Pointer to memory, where the FACP table will resides.
+// Filled by this procedure
+// Output:
+// EFI_STATUS:
+// EFI_OUT_OF_RESOURCES - Memory for the table could not be allocated
+// EFI_SUCCESS - Table was successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildFIDT (IN OUT ACPI_HDR **TablPtr)
+
+{
+
+ FW_VERSION *FidPtr = NULL;
+ UINTN FidLen = 0;
+ ACPI_HDR *FidTblHdr;
+ EFI_GUID FwGuid = FW_VERSION_GUID;
+ UINT8 i;
+ CHAR8 CoreMajVer [3] = THREE_CHAR_ARRAY(CORE_MAJOR_VERSION);
+ CHAR8 CoreMinVer [3] = THREE_CHAR_ARRAY(CORE_MINOR_VERSION);
+ CHAR8 ProjMajVer [3] = THREE_CHAR_ARRAY(PROJECT_MAJOR_VERSION);
+ CHAR8 ProjMinVer [3] = THREE_CHAR_ARRAY(PROJECT_MINOR_VERSION);
+
+ FidLen = sizeof(ACPI_HDR) + sizeof(FW_VERSION);
+ *TablPtr = MallocZ (FidLen);
+ if ((*TablPtr)==NULL)
+ {
+ ASSERT(*TablPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ FidTblHdr = (ACPI_HDR*)*TablPtr;
+ PrepareHdr20(FIDT_SIG, FidTblHdr, 4);
+ FidTblHdr->Length = (UINT32)FidLen;
+ FidTblHdr->Revision = 1;
+
+ FidPtr = (FW_VERSION*) ((UINT8*)FidTblHdr + sizeof(ACPI_HDR));
+
+ Strcpy (FidPtr->FirmwareID, CONVERT_TO_STRING($FID));
+ FidPtr->StructVersion = 4;
+ FidPtr->Size = sizeof(FW_VERSION);
+ Strcpy (FidPtr->BiosTag, CONVERT_TO_STRING(BIOS_TAG));
+ FidPtr->FirmwareGuid = FwGuid;
+ MemCpy(FidPtr->CoreMajorVersion, CoreMajVer, 3);
+ MemCpy(FidPtr->CoreMinorVersion, CoreMinVer, 3);
+ MemCpy(FidPtr->ProjectMajorVersion, ProjMajVer, 3);
+ MemCpy(FidPtr->ProjectMinorVersion, ProjMinVer, 3);
+
+ FidPtr->SignOnStringId = 0xffff;
+
+ for (i=0; i<6; i++) FidPtr->OemId[i]=ACPI_OEM_ID[i];
+
+ for (i=0; i<8; i++) FidPtr->OemTableId[i]=ACPI_OEM_TBL_ID[i];
+
+ FidTblHdr->Checksum = ChsumTbl((UINT8*)FidTblHdr, FidTblHdr->Length);
+
+
+
+ //TRACE((TRACE_ALWAYS, "FIDT Created.\n"));
+
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFacpiAll (NUINT TablVer, VOID *TablPtr)
+//
+// Description: This function allocates memory for and fills FACP table v 1.1+ with
+// predefined values from SDL tokens
+// Input:
+// IN UINTN TablVer - Version of FACP table
+// IN OUT **ACPI_HDR TablPtr - Pointer to memory, where the FACP table will resides.
+// Filled by this procedure
+// Output:
+// EFI_STATUS:
+// EFI_OUT_OF_RESOURCES - Memory for the table could not be allocated
+// EFI_SUCCESS - Table was successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS BuildFacpiAll (IN UINTN TablVer, OUT ACPI_HDR **TablPtr)
+
+{
+ FACP_50 *facp;
+ ACPI_HDR *FACP_Hdr;
+ UINT32 SizeOfFacp = sizeof(FACP_20);
+//-----------------------------
+
+ if (TablVer<1 || TablVer>4) return EFI_INVALID_PARAMETER;
+
+ if (TablVer == 1) SizeOfFacp = 0x84;// size of compatability 1.1 structure
+ if (ACPI_BUILD_TABLES_5_0 == 1) SizeOfFacp = sizeof(FACP_50);
+ *TablPtr = MallocZ (SizeOfFacp);
+ if ((*TablPtr)==NULL)
+ {
+ ASSERT(*TablPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ FACP_Hdr = *TablPtr;
+
+ if (TablVer == 1)
+ {
+ PrepareHdr20(FACP_SIG, FACP_Hdr, 2);
+ FACP_Hdr->Revision = ACPI_REV2;// compatability 1.1 structure
+ }
+
+ else
+ PrepareHdr20(FACP_SIG, FACP_Hdr, TablVer);
+
+ facp = (PFACP_50) *TablPtr;
+
+ facp->Reserved1 = ACPI_INT_MODEL;
+
+ facp->PM_PPROF = ACPI_PM_PROFILE;
+ facp->SCI_INT = ACPI_SCI_INT;
+ facp->SMI_CMD = SW_SMI_IO_ADDRESS;
+ facp->ACPI_ENABLE_CMD = SW_SMI_ACPI_ENABLE;
+ facp->ACPI_DISABLE_CMD = SW_SMI_ACPI_DISABLE;
+ facp->S4BIOS_REQ = SW_SMI_S4BIOS;
+
+ facp->PSTATE_CNT = SW_SMI_PSTATE_CNT;
+
+ if (PM1A_EVT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1a_EVT_BLK = 0;
+ else
+ facp->PM1a_EVT_BLK = PM1A_EVT_BLK_ADDRESS;
+
+ if (PM1B_EVT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1b_EVT_BLK = 0;
+ else
+ facp->PM1b_EVT_BLK = PM1B_EVT_BLK_ADDRESS;
+
+ if (PM1A_CNT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1a_CNT_BLK = 0;
+ else
+ facp->PM1a_CNT_BLK = PM1A_CNT_BLK_ADDRESS;
+
+ if (PM1B_CNT_BLK_ADDRESS > 0xffffffff)
+ facp->PM1b_CNT_BLK = 0;
+ else
+ facp->PM1b_CNT_BLK = PM1B_CNT_BLK_ADDRESS;
+
+ if (PM2_CNT_BLK_ADDRESS > 0xffffffff)
+ facp->PM2_CNT_BLK = 0;
+ else
+ facp->PM2_CNT_BLK = PM2_CNT_BLK_ADDRESS;
+
+ if (PM_TMR_BLK_ADDRESS > 0xffffffff)
+ facp->PM_TMR_BLK = 0;
+ else
+ facp->PM_TMR_BLK = PM_TMR_BLK_ADDRESS;
+
+ if (GPE0_BLK_ADDRESS > 0xffffffff)
+ facp->GPE0_BLK = 0;
+ else
+ facp->GPE0_BLK = GPE0_BLK_ADDRESS;
+
+ if (GPE1_BLK_ADDRESS > 0xffffffff)
+ facp->GPE1_BLK = 0;
+ else
+ facp->GPE1_BLK = GPE1_BLK_ADDRESS;
+
+ facp->GPE0_BLK_LEN = GPE0_BLK_LENGTH;
+ facp->GPE1_BLK_LEN = GPE1_BLK_LENGTH;
+ facp->GPE1_BASE = GPE1_BASE_OFFSET;
+ facp->PM1_EVT_LEN = PM1_EVT_LENGTH;
+ facp->PM1_CNT_LEN = PM1_CNT_LENGTH;
+ facp->PM2_CNT_LEN = PM2_CNT_LENGTH;
+ facp->PM_TM_LEN = PM_TMR_LENGTH;
+
+ facp->CST_CNT = SW_SMI_CST_CNT;
+ facp->P_LVL2_LAT = P_LVL2_LAT_VAL;
+ facp->P_LVL3_LAT = P_LVL3_LAT_VAL;
+ facp->FLUSH_SIZE = FLUSH_SIZE_VAL;
+ facp->FLUSH_STRIDE = FLUSH_STRIDE_VAL;
+ facp->DUTY_OFFSET = DUTY_OFFSET_VAL;
+ facp->DUTY_WIDTH = DUTY_WIDTH_VAL;
+ facp->DAY_ALRM = ACPI_ALARM_DAY_CMOS;
+ facp->MON_ALRM = ACPI_ALARM_MONTH_CMOS;
+ facp->CENTURY = ACPI_CENTURY_CMOS;
+ facp->IAPC_BOOT_ARCH = ACPI_IA_BOOT_ARCH;
+
+ //--------Filling Flags for V.1----------------------
+
+ facp->FLAGS = 0;
+
+ if (FACP_FLAG_WBINVD) facp->FLAGS = 1;
+
+ if (FACP_FLAG_WBINVD_FLUSH) facp->FLAGS |= 1<<1;
+
+ if (FACP_FLAG_PROC_C1) facp->FLAGS |= 1<<2;
+
+ if (FACP_FLAG_P_LVL2_UP) facp->FLAGS |= 1<<3;
+
+ if (FACP_FLAG_PWR_BUTTON) facp->FLAGS |= 1<<4;
+
+ if (FACP_FLAG_SLP_BUTTON) facp->FLAGS |= 1<<5;
+
+ if (FACP_FLAG_FIX_RTC) facp->FLAGS |= 1<<6;
+
+ if (FACP_FLAG_RTC_S4) facp->FLAGS |= 1<<7;
+
+ if (FACP_FLAG_TMR_VAL_EXT) facp->FLAGS |= 1<<8;
+
+ if (FACP_FLAG_DCK_CAP) facp->FLAGS |= 1<<9;
+
+
+ //--------Filling Flags for V.2 and GAS compat structure for v.1----------------------
+
+ if (FACP_FLAG_RESET_REG_SUP) facp->FLAGS |= 1<<10;
+
+ if (FACP_FLAG_SEALED_CASE) facp->FLAGS |= 1<<11;
+
+ if (FACP_FLAG_HEADLESS) facp->FLAGS |= 1<<12;
+
+ if (FACP_FLAG_CPU_SW_SLP) facp->FLAGS |= 1<<13;
+
+#if ACPI_BUILD_TABLES_3_0
+
+ if (FACP_FLAG_USE_PLATFORM_CLOCK) facp->FLAGS |= 1<<15;
+
+ if (FACP_FLAG_S4_RTC_STS_VALID) facp->FLAGS |= 1<<16;
+
+ if (FACP_FLAG_REMOTE_POWER_ON_CAPABLE) facp->FLAGS |= 1<<17;
+
+ if (TablVer > 2)
+ {
+ if (FACP_FLAG_FORCE_APIC_CLUSTER_MODEL) facp->FLAGS |= 1<<18;
+
+ if (FACP_FLAG_FORCE_APIC_PHYSICAL_DESTINATION_MODE) facp->FLAGS |= 1<<19;
+
+ if (FACP_FLAG_PCI_EXP_WAK) facp->FLAGS |= 1<<14;
+ }
+
+#endif
+
+ // RESET_REG GAS_20 structure and value
+ facp->RESET_REG.AddrSpcID = ACPI_RESET_REG_TYPE;
+ facp->RESET_REG.RegBitWidth = ACPI_RESET_REG_BITWIDTH;
+ facp->RESET_REG.RegBitOffs = ACPI_RESET_REG_BITOFFSET;
+ facp->RESET_REG.Address = ACPI_RESET_REG_ADDRESS;
+ facp->RESET_VAL = ACPI_RESET_REG_VALUE;
+
+ if (ACPI_RESET_REG_ADDRESS)
+ {
+ // Set FACP flag
+ facp->FLAGS |= 1<<10;
+ }
+
+ if (TablVer == 1)
+ {
+ facp->Header.Length = 0x84;
+ facp->Header.Checksum = 0;
+ facp->Header.Checksum = ChsumTbl((UINT8*)facp, facp->Header.Length);
+ return EFI_SUCCESS;
+ }
+
+ //--------This is all for V.1-----------------------
+
+ // PM1a_EVT_BLK GAS_20 structure
+ facp->X_PM1a_EVT_BLK.AddrSpcID = PM1A_EVT_BLK_TYPE;
+ facp->X_PM1a_EVT_BLK.RegBitWidth= PM1A_EVT_BLK_BITWIDTH;
+ facp->X_PM1a_EVT_BLK.RegBitOffs = PM1A_EVT_BLK_BITOFFSET;
+ facp->X_PM1a_EVT_BLK.AccessSize = 2;
+ facp->X_PM1a_EVT_BLK.Address = PM1A_EVT_BLK_ADDRESS;
+
+ // PM1a_CNT_BLK GAS_20 structure
+ facp->X_PM1a_CNT_BLK.AddrSpcID = PM1A_CNT_BLK_TYPE;
+ facp->X_PM1a_CNT_BLK.RegBitWidth= PM1A_CNT_BLK_BITWIDTH;
+ facp->X_PM1a_CNT_BLK.RegBitOffs = PM1A_CNT_BLK_BITOFFSET;
+ facp->X_PM1a_CNT_BLK.AccessSize = 2;
+ facp->X_PM1a_CNT_BLK.Address = PM1A_CNT_BLK_ADDRESS;
+
+ // PM1b_EVT_BLK GAS_20 structure
+ facp->X_PM1b_EVT_BLK.AddrSpcID = PM1B_EVT_BLK_TYPE;
+ facp->X_PM1b_EVT_BLK.RegBitWidth= PM1B_EVT_BLK_BITWIDTH;
+ facp->X_PM1b_EVT_BLK.RegBitOffs = PM1B_EVT_BLK_BITOFFSET;
+ facp->X_PM1b_EVT_BLK.AccessSize = 2;
+ facp->X_PM1b_EVT_BLK.Address = PM1B_EVT_BLK_ADDRESS;
+
+ // PM1b_CNT_BLK GAS_20 structure
+ facp->X_PM1b_CNT_BLK.AddrSpcID = PM1B_CNT_BLK_TYPE;
+ facp->X_PM1b_CNT_BLK.RegBitWidth= PM1B_CNT_BLK_BITWIDTH;
+ facp->X_PM1b_CNT_BLK.RegBitOffs = PM1B_CNT_BLK_BITOFFSET;
+ facp->X_PM1b_CNT_BLK.AccessSize = 2;
+ facp->X_PM1b_CNT_BLK.Address = PM1B_CNT_BLK_ADDRESS;
+
+ // PM1b_CNT_BLK GAS_20 structure
+ facp->X_PM2_CNT_BLK.AddrSpcID = PM2_CNT_BLK_TYPE;
+ facp->X_PM2_CNT_BLK.RegBitWidth = PM2_CNT_BLK_BITWIDTH;
+ facp->X_PM2_CNT_BLK.RegBitOffs = PM2_CNT_BLK_BITOFFSET;
+ facp->X_PM2_CNT_BLK.AccessSize = 1;
+ facp->X_PM2_CNT_BLK.Address = PM2_CNT_BLK_ADDRESS;
+
+ facp->X_PM_TMR_BLK.AddrSpcID = PM_TMR_BLK_TYPE;
+ facp->X_PM_TMR_BLK.RegBitWidth = PM_TMR_BLK_BITWIDTH;
+ facp->X_PM_TMR_BLK.RegBitOffs = PM_TMR_BLK_BITOFFSET;
+ facp->X_PM_TMR_BLK.AccessSize = 3;
+ facp->X_PM_TMR_BLK.Address = PM_TMR_BLK_ADDRESS;
+
+ facp->X_GPE0_BLK.AddrSpcID = GPE0_BLK_TYPE;
+ facp->X_GPE0_BLK.RegBitWidth = GPE0_BLK_BITWIDTH;
+ facp->X_GPE0_BLK.RegBitOffs = GPE0_BLK_BITOFFSET;
+ facp->X_GPE0_BLK.AccessSize = 1;
+ facp->X_GPE0_BLK.Address = GPE0_BLK_ADDRESS;
+
+ facp->X_GPE1_BLK.AddrSpcID = GPE1_BLK_TYPE;
+ facp->X_GPE1_BLK.RegBitWidth = GPE1_BLK_BITWIDTH;
+ facp->X_GPE1_BLK.RegBitOffs = GPE1_BLK_BITOFFSET;
+ facp->X_GPE1_BLK.AccessSize = 1;
+ facp->X_GPE1_BLK.Address = GPE1_BLK_ADDRESS;
+
+ if (ACPI_BUILD_TABLES_5_0 == 1)
+ {
+#if HW_REDUCED_ACPI
+
+ facp->FLAGS |= 1<<20;
+
+ facp->SLEEP_CONTROL_REG.AddrSpcID = SLEEP_CONTROL_REG_TYPE;
+ facp->SLEEP_CONTROL_REG.RegBitWidth = SLEEP_CONTROL_REG_BITWIDTH;
+ facp->SLEEP_CONTROL_REG.RegBitOffs = SLEEP_CONTROL_REG_BITOFFSET;
+ facp->SLEEP_CONTROL_REG.AccessSize = SLEEP_CONTROL_REG_ACCESS_SIZE;
+ facp->SLEEP_CONTROL_REG.Address = SLEEP_CONTROL_REG_ADDRESS;
+
+ facp->SLEEP_STATUS_REG.AddrSpcID = SLEEP_STATUS_REG_TYPE;
+ facp->SLEEP_STATUS_REG.RegBitWidth = SLEEP_STATUS_REG_BITWIDTH;
+ facp->SLEEP_STATUS_REG.RegBitOffs = SLEEP_STATUS_REG_BITOFFSET;
+ facp->SLEEP_STATUS_REG.AccessSize = SLEEP_STATUS_REG_ACCESS_SIZE;
+ facp->SLEEP_STATUS_REG.Address = SLEEP_STATUS_REG_ADDRESS;
+#endif
+
+ if (LOW_POWER_S0_IDLE_CAPABLE) facp->FLAGS |= 1<<21;
+ facp->Header.Revision = 5; // ACPI 5.0 revision
+ }
+ facp->Header.Length = SizeOfFacp;
+ facp->Header.Checksum = 0;
+ facp->Header.Checksum = ChsumTbl((UINT8*)facp, facp->Header.Length);
+
+ return EFI_SUCCESS;
+
+}// end of BuildFacpiAll
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapic
+//
+// Description: Allocates memory for and builds LAPIC entry for MADT table
+//
+// Input: IN CPUINFO *CpuInfo - Pointer to a block of information about cpu
+// passed through cpu info HOB, if NULL - it is a
+// dummy entry.
+// IN UINTN CpuCount - Number of the cpu
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+MADT_ENTRY_HEADER *BuildLapic(IN CPUINFO *CpuInfo, IN UINT32 CpuId)
+{
+ LAPIC_H32 *LapicPtr;
+ LapicPtr = MallocZ(sizeof(LAPIC_H32));
+ ASSERT (LapicPtr);
+
+ if (!LapicPtr) return NULL;
+
+ LapicPtr->Header.Type = (UINT8) AT_LAPIC; //Type 0 - indicating LAPIC Entry
+ LapicPtr->Header.Length = (UINT8) sizeof(LAPIC_H32);
+ LapicPtr->CpuId = CpuId;
+
+ if (CpuInfo != NULL) // This is not a dummy entry
+ {
+ LapicPtr->LapicId = (UINT8) CpuInfo->ApicId;
+ if (gMaxLapic < LapicPtr->LapicId) gMaxLapic = LapicPtr->LapicId;
+ LapicPtr->Flags = (CpuInfo->Valid) ? FL_ENABLE : 0;
+ }
+
+ else // Tis is a dummy entry for not installed processor
+ {
+ LapicPtr->LapicId = ++gMaxLapic;
+ LapicPtr->Flags = 0;
+ }
+
+ return (MADT_ENTRY_HEADER*) LapicPtr;
+
+}// end of BuildLapic
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLx2Apic
+//
+// Description: Allocates memory for and builds Local x2APIC entry for MADT table
+//
+// Input:
+// IN UINT32 ApicId - Apic Id of processor.
+// IN UINT32 Uid - UID of processor.
+// IN UINT32 Flags - Flags of entry.
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LX2APIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+MADT_ENTRY_HEADER *BuildLx2Apic(IN UINT32 ApicId, IN UINT32 Uid, IN UINT32 Flags)
+{
+ LX2APIC *Lx2ApicPtr;
+ Lx2ApicPtr = MallocZ(sizeof(LX2APIC));
+ ASSERT (Lx2ApicPtr);
+
+ if (!Lx2ApicPtr) return NULL;
+
+ Lx2ApicPtr->Header.Type = (UINT8) AT_LX2APIC; //Type A - indicating LX2APIC Entry
+ Lx2ApicPtr->Header.Length = (UINT8) sizeof(LX2APIC);
+ Lx2ApicPtr->ApicId = ApicId;
+ Lx2ApicPtr->Flags = Flags;
+ Lx2ApicPtr->Uid = Uid;
+ return (MADT_ENTRY_HEADER*) Lx2ApicPtr;
+}// end of BuildLx2Apic
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLsapic
+//
+// Description: Allocates memory for and builds LSAPIC entry for MADT table
+//
+//
+// Input: IN CPUINFO *CpuInfo - Pointer to a block of information about cpu
+// passed through cpu info HOB
+// IN UINT32 CpuCount - Number of the cpu
+// IN UINTN Ver - Version of MADT table
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+MADT_ENTRY_HEADER *BuildLsapic(IN CPUINFO *CpuInfo, IN UINT32 CpuId, IN UINTN Ver)
+{
+ LSAPIC_H20 *LsapicPtr;
+
+ if (Ver < 3)
+ LsapicPtr = MallocZ(sizeof(LSAPIC_H20));
+ else
+ LsapicPtr = MallocZ(sizeof(LSAPIC_H30));
+
+ ASSERT (LsapicPtr);
+
+ if (!LsapicPtr) return NULL;
+
+ LsapicPtr->Header.Type = (UINT8) AT_LSAPIC; //Type 7 - indicating LSAPIC Entry
+
+ if (Ver < 3)
+ LsapicPtr->Header.Length = (UINT8) sizeof(LSAPIC_H20);
+ else
+ LsapicPtr->Header.Length = (UINT8) sizeof(LSAPIC_H30);
+
+ LsapicPtr->CpuId = CpuId;
+ LsapicPtr->LsapicId = (UINT8) CpuInfo->ApicId;
+ LsapicPtr->LsapicEid = (UINT8) CpuInfo->ApicEId;
+ LsapicPtr->Flags = (CpuInfo->Valid) ? FL_ENABLE : 0;
+ return (MADT_ENTRY_HEADER*) LsapicPtr;
+
+}// end of BuildLsapic LapicPtr
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildIoapicIosapic
+//
+// Description:
+// This function will probe IndReg and DataReg of discovered IOxAPIC base address
+// and allocate memory for and builds Ioapic/Iosapic entry for MADT table
+//
+// Input:
+// IN UINT64 BaseAddr - Base Addrerss where IOxApic presence detected
+// IN OUT UINT64 *VecBase - pointer to the System Vector Base variable that
+// needs to be updated with IOAPIC.MAXREDIR# by this function
+//
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the Ioapic/Iosapi entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#pragma optimize( "", off )
+MADT_ENTRY_HEADER *BuildIoapicIosapic(IN UINT32 BaseAddr, OUT UINT32 *VecBase)
+{
+ UINT32 Tmp;
+ UINT32 volatile *DatPtr;
+ UINT8 volatile *IdxPtr;
+ UINT32 IoapicId;
+ UINT32 IoapicVer;
+ IOAPIC_H20 *IoapicPtr;
+ IOSAPIC_H20 *IosapicPtr;
+
+//==============================
+ //Read IOAPIC.ID reg and figure out
+ //1.How many INTINs it has
+ //2.What ID did BIOS gave to it
+ IdxPtr=(UINT8*)(BaseAddr + IOA_IND_REG_OFFS);
+ DatPtr=(UINT32*)(BaseAddr + IOA_DAT_REG_OFFS);
+
+ *IdxPtr = IOA_ID_IND; // bits 27..24=IOAPIC_ID
+
+ Tmp = *DatPtr;
+
+ IoapicId = ((Tmp&0x0f000000)>>24);
+
+ *IdxPtr = IOA_VER_IND; // IOAPIC_VER register
+
+ Tmp=*DatPtr;
+
+ IoapicVer=(Tmp&0xff);
+
+ if (IoapicVer < IO_APIC_VERSION_PARAMETER) // This is Ioapic
+ {
+ IoapicPtr = MallocZ(sizeof(IOAPIC_H20));
+ ASSERT (IoapicPtr);
+
+ if (!IoapicPtr) return NULL;
+
+ IoapicPtr->Header.Type = (UINT8) AT_IOAPIC; // 1 - For IOAPIC Structure
+ IoapicPtr->Header.Length = (UINT8) sizeof (IOAPIC_H20);
+ IoapicPtr->IoapicAddress = (UINT32) BaseAddr;
+ IoapicPtr->IoapicId = (UINT8) IoapicId;
+ IoapicPtr->SysVectBase = (UINT32) *VecBase;
+ //Adjust VecBase with current Max Redirection value
+ (*VecBase)+=((UINT32)((Tmp&0x00ff0000)>>16))+1;
+ return (MADT_ENTRY_HEADER*) IoapicPtr;
+ }
+
+ else // This is Iosapic
+ {
+ IosapicPtr = MallocZ(sizeof(IOSAPIC_H20));
+ ASSERT (IosapicPtr);
+
+ if (!IosapicPtr) return NULL;
+
+ IosapicPtr->Header.Type = (UINT8) AT_IOSAPIC; // 6 - For IOSAPIC Structure
+ IosapicPtr->Header.Length = (UINT8) sizeof (IOSAPIC_H20);
+ IosapicPtr->IosapicAddress = (UINT64) BaseAddr;
+ IosapicPtr->IoapicId = (UINT8) IoapicId;
+ IosapicPtr->SysVectBase = (UINT32) *VecBase;
+ //Adjust VecBase with current Max Redirection value
+ (*VecBase)+=((UINT32)((Tmp&0x00ff0000)>>16))+1;
+ return (MADT_ENTRY_HEADER*) IosapicPtr;
+ }
+
+}// End of BuildIoapicIosapic
+#pragma optimize( "", on )
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildIoapicManualy
+//
+// Description: Allocates memory for and builds LAPIC entry for MADT table filled with
+// Dummy information
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MADT_ENTRY_HEADER *BuildIoapicManualy()
+{
+ IOAPIC_H20 *IoapicPtr;
+
+ IoapicPtr = MallocZ(sizeof(IOAPIC_H20));
+ ASSERT (IoapicPtr);
+
+ if (!IoapicPtr) return NULL;
+
+ IoapicPtr->Header.Type = (UINT8) AT_IOAPIC; // 1 - For IOAPIC Structure
+ IoapicPtr->Header.Length = (UINT8) sizeof (IOAPIC_H20);
+ IoapicPtr->IoapicAddress = (UINT32) APCB;
+ IoapicPtr->IoapicId = (UINT8) 0;
+ IoapicPtr->SysVectBase = (UINT32) 0;
+ return (MADT_ENTRY_HEADER*) IoapicPtr;
+
+
+}// end of BuildIoapicManualy
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddIsoFromTbl
+//
+// Description: Allocates memory for and builds ISO entry for MADT table, based
+// on INTERRUPT SOURCE OVERRIDE info from predifined table
+//
+// Input: UINTN IsoTblNumb - Number of entry in ISO table for which an entry should
+// be build.
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the ISO entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MADT_ENTRY_HEADER *BuildIsoFromTbl (UINTN IsoTblNumb)
+{
+ ISO_H20 *IsoPtr;
+
+ IsoPtr = MallocZ(sizeof(ISO_H20));
+ ASSERT (IsoPtr);
+
+ if (!IsoPtr) return NULL;
+
+ IsoPtr->Header.Type = AT_ISO; // 2 - For ISO structure
+ IsoPtr->Header.Length = sizeof(ISO_H20);
+ IsoPtr->Bus = 0;
+ IsoPtr->Source = (UINT8) IsoTbl[IsoTblNumb].PicIrq;
+ IsoPtr->GlobalSysVect = (UINT32) IsoTbl[IsoTblNumb].ApicInt;
+ IsoPtr->Flags = (UINT16) IsoTbl[IsoTblNumb].Flags;
+ return (MADT_ENTRY_HEADER*) IsoPtr;
+}//end of BuildIsoFromTbl
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapicsFromHob
+//
+// Description:
+// Build Local Apic Entries from HOB.
+//
+// Input:
+// IN UINTN TableVer - ACPI Spec. Version
+// IN OUT MADT_ENTRIES *MadtTblEntries - MADT Table Entry list.
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_UNSUPPORTED - CPU info hob not found
+// EFI_INVALID_PARAMETER - invalid ACPI version
+// EFI_SUCCESS - MADT table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildLapicsFromHob(
+ IN UINTN TablVer,
+ IN OUT MADT_ENTRIES *MadtTblEntries
+)
+{
+ UINT32 NumbOfCPUs, DummyCPUs = 0, i;
+ static EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ UINT32 CpuCount, LastItem = 1;
+ CPUINFO_HOB *CpuInfoHob;
+ CPUINFO *CpuInfo = NULL;
+ MADT_ENTRY_HEADER *HdrPtr;
+ EFI_STATUS Status;
+
+ CpuInfoHob = (CPUINFO_HOB*)GetEfiConfigurationTable(pST,&HobListGuid);
+
+ if (CpuInfoHob == NULL) Status = EFI_UNSUPPORTED;
+ else Status = FindNextHobByGuid(&CpuInfoHobGuid,(VOID**)&CpuInfoHob);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ NumbOfCPUs = CpuInfoHob->CpuCount;
+
+#if defined SKIP_DUMMY_LAPICS && SKIP_DUMMY_LAPICS==1
+// If SKIP_DUMMY_LAPICS defined and 1 - somebody want to skip creation of dummy lapics
+// So do nothing there
+#else
+#if NCPU != 0
+DummyCPUs = NCPU; // NCPU - maximum poccesoros supported by platform - so we need to create dummy entries for
+#endif // all processors that are not present, but could be hotpluged.
+#endif
+
+//---Creating LAPIC or/and LSAPIC Entries----------------
+ if (DummyCPUs <= NumbOfCPUs) DummyCPUs = NumbOfCPUs;
+
+ for (CpuCount=0; CpuCount < DummyCPUs; CpuCount++)
+ {
+ if (CpuCount < NumbOfCPUs)
+ {
+ CpuInfo = &(CpuInfoHob->Cpuinfo[CpuCount]);
+
+ if (CpuInfo->ApicVer < LOCAL_APIC_VERSION_PARAMETER)
+ HdrPtr = BuildLapic(CpuInfo, CpuCount + 1); //Id must match processor object, so add 1 to Cpu Count.
+ else
+ HdrPtr = BuildLsapic(CpuInfo, CpuCount + 1, TablVer); //Id must match processor object, so add 1 to Cpu Count.
+ }
+
+ else HdrPtr = BuildLapic(NULL, CpuCount + 1); // Just add dummy entry
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries->MadtEntCount == 0) // Adding entries in groving LapicId/LsapicId value order
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);// First entry
+ else
+ {
+ for (i = (LastItem - 1); i < MadtTblEntries->MadtEntCount; i++) // No need to handle LSAPIC entry in different way
+ {
+ if (((LAPIC_H32*)HdrPtr)->LapicId < ((LAPIC_H32*)MadtTblEntries->MadtEntries[i])->LapicId) break; // LapicId and LsapicId filds are on the same place in bouth structures
+ } // found entry with bigger LapicId/LsapicId
+
+ if (i == MadtTblEntries->MadtEntCount)
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);
+ else
+ Status = InsertItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr, i);
+ }
+
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapicsFromProtocol
+//
+// Description:
+// Build Local Apic Entries from Protocol.
+//
+// Input:
+// IN UINTN TableVer - ACPI Spec. Version
+// IN OUT MADT_ENTRIES *MadtTblEntries - MADT Table Entry list.
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_UNSUPPORTED - CPU info hob not found
+// EFI_INVALID_PARAMETER - invalid ACPI version
+// EFI_SUCCESS - MADT table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+
+EFI_STATUS BuildLapicsFromProtocol(
+ IN UINTN TablVer,
+ IN OUT MADT_ENTRIES *MadtTblEntries
+)
+{
+ EFI_STATUS Status;
+ MADT_ENTRY_HEADER *HdrPtr;
+ ACPI_PROCESSOR_INFO *AcpiProcInfo;
+ UINT32 NumEntries;
+ UINT32 Index;
+ CPUINFO CpuInfo;
+
+ if (gAmiCpu2Info->ProtocolVer < 1) return EFI_UNSUPPORTED;
+
+ Status = gAmiCpu2Info->GetAcpiInfo(
+ gAmiCpu2Info, (VOID**) &AcpiProcInfo, &NumEntries
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ for (Index = 0; Index < NumEntries; ++Index)
+ {
+ //Note: Only some ACPI_PROCESSOR_INFO fields may only valid for some minimum ACPI_PROCESSOR_INFO.Length.
+ //The ACPI_PROCESSOR_INFO may have additional fields added in later version. Please see comments in
+ //AmiCpuInfo2.h file.
+ if (AcpiProcInfo->Type == ACPI_PROCESSOR_INFO_TYPE)
+ {
+ if (AcpiProcInfo->Length >= 60 && AcpiProcInfo->LocalApicType == ACPI_PROC_INFO_x2APIC)
+ {
+ HdrPtr = BuildLx2Apic(AcpiProcInfo->ApicId, AcpiProcInfo->ProcId, 1);
+ gX2Apic = TRUE;
+ }
+
+ else
+ {
+ //This current implementation only supports 8 bit APIC Id and 8-bit extended Id.
+ CpuInfo.Valid = (BOOLEAN)AcpiProcInfo->Enable;
+ CpuInfo.ApicId = (UINT8)AcpiProcInfo->ApicId;
+ CpuInfo.ApicEId = (UINT8)(AcpiProcInfo->ApicId >> 8);
+ CpuInfo.ApicVer = (UINT8)AcpiProcInfo->ApicVer;
+
+ //Produce entry.
+ if (AcpiProcInfo->ApicVer < LOCAL_APIC_VERSION_PARAMETER)
+ HdrPtr = BuildLapic(&CpuInfo, AcpiProcInfo->ProcId);
+ else
+ HdrPtr = BuildLsapic(&CpuInfo, AcpiProcInfo->ProcId, TablVer);
+ }
+
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ }
+
+ //An earlier version ACPI_PROCESSOR_INFO with a smaller structure may be have been published,
+ //so use length field.
+ AcpiProcInfo = (ACPI_PROCESSOR_INFO*)((UINT8*)AcpiProcInfo + AcpiProcInfo->Length);
+ }
+
+ return EFI_SUCCESS;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLapicNmiFromProtocol
+//
+// Description:
+// Build Local Apic NMI Entries from Protocol.
+//
+// Input:
+// IN OUT MADT_ENTRIES *MadtTblEntries - MADT Table Entry list.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if AMI_CPU_INFO_2_PROTOCOL_VERSION >= 3
+EFI_STATUS BuildLapicNmiFromProtocol(
+ IN OUT MADT_ENTRIES *MadtTblEntries
+)
+{
+ EFI_STATUS Status;
+ MADT_ENTRY_HEADER *HdrPtr;
+ ACPI_PROCESSOR_INFO *AcpiProcInfo;
+ UINT32 NumEntries;
+ UINT32 Index;
+
+ if (gAmiCpu2Info->ProtocolVer < 1) return EFI_UNSUPPORTED;
+
+ Status = gAmiCpu2Info->GetAcpiInfo(
+ gAmiCpu2Info, (VOID**) &AcpiProcInfo, &NumEntries
+ );
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = EFI_NOT_FOUND;
+
+ for (Index = 0; Index < NumEntries; ++Index)
+ {
+ //Note: Only some ACPI_PROCESSOR_INFO fields may only valid for some minimum ACPI_PROCESSOR_INFO.Length.
+ //The ACPI_PROCESSOR_INFO may have additional fields added in later version. Please see comments in
+ //AmiCpuInfo2.h file.
+ if (AcpiProcInfo->Type == ACPI_PROCESSOR_INFO_TYPE)
+ {
+ if (AcpiProcInfo->Length >= 72 && AcpiProcInfo->ProduceNmi == TRUE)
+ {
+ HdrPtr = BuildLocalApicNmi(
+ AcpiProcInfo->LocalApicType == ACPI_PROC_INFO_x2APIC,
+ AcpiProcInfo->ProcId,
+ AcpiProcInfo->LintnPin,
+ AcpiProcInfo->NmiFlags
+ );
+
+ Status = AppendItemLst ((T_ITEM_LIST*)MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+ //An earlier version ACPI_PROCESSOR_INFO with a smaller structure may be have been published,
+ //so use length field.
+ AcpiProcInfo = (ACPI_PROCESSOR_INFO*)((UINT8*)AcpiProcInfo + AcpiProcInfo->Length);
+ }
+ return Status;
+}
+
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildLocalApicNmi
+//
+// Description: Allocates memory for and builds local APIC or local x2APIC NMI entry
+//
+// Input:
+// IN UINT32 ProcessorId - MADT NMI entry processor id or UID
+// IN UINT8 LapicInitIn - MADT Local (x2)apic NMI Pin
+// IN UINT16 Flags - MADT Local (x2) apic flags
+//
+// Output:
+// MADT_ENTRY_HEADER * - pointer to the LAPIC NMI entry header for the MADT table
+// if NULL - not enough memory
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MADT_ENTRY_HEADER * BuildLocalApicNmi(IN BOOLEAN X2Apic, IN UINT32 ProcessorId, IN UINT8 LapicInitIn, IN UINT16 Flags)
+{
+ MADT_ENTRY_HEADER *HdrPtr;
+
+ if (X2Apic)
+ {
+ HdrPtr = MallocZ(sizeof(LX2APIC_NMI));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return NULL;
+
+ ((LX2APIC_NMI*) HdrPtr)->Header.Type = AT_LX2APIC_NMI; //Type 10 - indicating Local x2APIC NMI Entry.
+ ((LX2APIC_NMI*) HdrPtr)->Header.Length = sizeof(LX2APIC_NMI);
+ ((LX2APIC_NMI*) HdrPtr)->Flags = Flags;
+ ((LX2APIC_NMI*) HdrPtr)->Uid = ProcessorId;
+ ((LX2APIC_NMI*) HdrPtr)->LapicIntin = LapicInitIn;
+ }
+ else
+ {
+ HdrPtr = MallocZ(sizeof(LNMI_H20));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return NULL;
+
+ ((LNMI_H20*) HdrPtr)->Header.Type = AT_LAPIC_NMI; //Type 4 - indicating LAPIC NMIs Entry
+ ((LNMI_H20*) HdrPtr)->Header.Length = sizeof(LNMI_H20);
+ ((LNMI_H20*) HdrPtr)->Flags = Flags;
+ ((LNMI_H20*) HdrPtr)->CPU_ID = (UINT8)ProcessorId;
+ ((LNMI_H20*) HdrPtr)->LapicIntin = LapicInitIn;
+ }
+
+ return HdrPtr;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildMadtAll
+//
+// Description: Creates MADT entries, stores them as T_ITEM_LIST, calculates
+// space needed, allocates memory and builds MADT table from entries
+//
+// Input:
+// IN UINTN TablVer - ACPI Spec. Version
+// OUT ACPI_HDR **TablPtr - Pointer, to the MADT table, filled by this function
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_UNSUPPORTED - CPU info hob not found
+// EFI_INVALID_PARAMETER - invalid ACPI version
+// EFI_SUCCESS - MADT table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildMadtAll(IN UINTN TablVer, OUT ACPI_HDR **TablPtr)
+{
+ UINTN LastItem;
+ EFI_STATUS Status;
+ MADT_ENTRIES MadtTblEntries = {0, 0, NULL};
+ MADT_ENTRY_HEADER *HdrPtr;
+ UINT32 IoapicVbase = 0, AllStrLength = 0, IoapicAddr = 0;
+ UINT8 *DestinPtr;
+ UINTN i, j;
+ UINTN IoApicCnt=0;
+
+//--------------------------------
+ if (TablVer<1 || TablVer>4) return EFI_INVALID_PARAMETER;
+
+//-------Build LAPIC or/and LSAPIC Entries.
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ // Update for Haswell CPU Refcode. >>>
+ Status = pBS->LocateProtocol(&gAmiCpuInfo2ProtocolGuid, NULL, &gAmiCpu2Info);
+ // <<< Update for Haswell CPU Refcode.
+ Status = EFI_UNSUPPORTED;
+
+ //First try to build Local APIC information from the protocol.
+ if (gAmiCpu2Info != NULL)
+ {
+ Status = BuildLapicsFromProtocol(TablVer, &MadtTblEntries);
+ }
+
+ //If protocol fails, try CPU INFO HOB.
+ if (EFI_ERROR(Status))
+ {
+
+#endif
+ Status = BuildLapicsFromHob(TablVer, &MadtTblEntries);
+ ASSERT_EFI_ERROR(Status);
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ }
+
+#endif
+ //Set Marker at last item before IOAPIC/IOsAPIC entries
+ LastItem = MadtTblEntries.MadtEntCount;
+
+//The folloving code may enable IOAPIC Devices found on PCI BUS
+//This IOAPICs might use their ABARs to clame MMIO in FEC0_0000 space.
+//So we need to run this code prior if we don't want to miss any IOAPICs.
+//--------------------------------------------------------------------
+#if PCI_BUS_APIC_AUTODETECT == 1
+ {
+ EFI_HANDLE *pHandleBuffer;
+ UINTN NumberOfHandles;
+ UINT8 PciData[4];
+ EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+ EFI_PCI_IO_PROTOCOL *pPciIoProtocol;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &PciIoProtocolGuid,
+ NULL, &NumberOfHandles, &pHandleBuffer);
+
+ //The protocol might not be available when function runs first time.
+ //we will rerun it on READY_TO_BOOT event again.
+ if (!EFI_ERROR(Status))
+ {
+
+ for (i = 0; i < NumberOfHandles; i++)
+ {
+ Status = pBS->HandleProtocol(pHandleBuffer[i], &PciIoProtocolGuid,
+ (VOID**)&pPciIoProtocol);
+
+ if (EFI_ERROR(Status))
+ continue;
+
+ //read class code information at 0x8 offset in PCI header
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x8, 1, &PciData[0]);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) //problem
+ continue;
+
+ //if IO APIC device
+ if ((PciData[3] == 0x8) && (PciData[2] == 0) && (PciData[1] >= 0x10))
+ {
+ UINT64 Attr=0, OldAttr=0;
+ //----------------------
+ //1. make sure it is Enabled and Decoding it's resources
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationGet, Attr, &OldAttr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSupported, 0, &Attr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSet, Attr&(EFI_PCI_DEVICE_ENABLE), NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+
+ //2. collect info
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x10, 1, (VOID*)&IoapicAddr);
+ //problem or mapped to default address range
+ ASSERT_EFI_ERROR(Status);
+
+ if ( ! (EFI_ERROR(Status) || (IoapicAddr == 0)) )
+ {
+ HdrPtr = BuildIoapicIosapic(IoapicAddr, &IoapicVbase);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries.MadtEntCount == LastItem) // Adding entries in groving IOapicId/IOsapicId value order
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);// First entry
+ }
+
+ else
+ {
+ for (j = (LastItem); j < MadtTblEntries.MadtEntCount; j++) // No need to handle LSAPIC entry in different way
+ {
+ // IOapicId and IOsapicId filds are on the same place in bouth structures
+ if (((IOAPIC_H32*)HdrPtr)->IoapicId < ((IOAPIC_H32*)MadtTblEntries.MadtEntries[j])->IoapicId) break;
+ } // found entry with bigger IOapicId/IOsapicId
+
+ if (j == MadtTblEntries.MadtEntCount)
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ }
+
+ else
+ {
+ Status = InsertItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr, j);
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ IoApicCnt++;
+ }
+ }//if( ! (EFI_ERROR(Status) || (IoapicAddr == 0)) )
+
+#if PCI_BUS_APIC_LEAVE_ENABLE != 0
+ //Restore attributes of the device
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSet, OldAttr, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) continue;
+
+#endif
+ }//if((PciData[3] == 0x8) && (PciData[2] == 0) && (PciData[1] >= 0x10))
+ }//for(i = 0; i < NumberOfHandles; i++)
+
+ pBS->FreePool(pHandleBuffer);
+ }//if(!EFI_ERROR(Status))
+ }
+#endif //PCI_BUS_APIC_AUTODETECT == 1
+
+//--------------------------------------------------------------------
+//---Creating IOAPIC or/and IOSAPIC Entries
+#if (APCB != 0)
+ IoapicAddr = APCB;
+#else
+ IoapicAddr = IOA_BASE_BOT;
+#endif
+
+#if FEC00000_APIC_AUTODETECT == 1
+
+ //trying to check if something alive present at 0xFEC00000..0xFED00000
+ for ( ; IoapicAddr < IOA_BASE_TOP; IoapicAddr += 0x1000)
+ { //If so read IOAPIC.ID reg and figure out
+ //1.How many INTINs it has
+ //2.What ID BIOS give to it
+ if (*((UINT8 *)(IoapicAddr + IOA_IND_REG_OFFS)) != 0xFF)
+ {
+ HdrPtr = BuildIoapicIosapic(IoapicAddr, &IoapicVbase);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries.MadtEntCount == LastItem) // Adding entries in groving IOapicId/IOsapicId value order
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);// First entry
+ else
+ {
+ for (j = (LastItem); j < MadtTblEntries.MadtEntCount; j++)
+ { // No need to handle LSAPIC entry in different way
+ if (((IOAPIC_H32*)HdrPtr)->IoapicId < ((IOAPIC_H32*)MadtTblEntries.MadtEntries[j])->IoapicId) break; // IOapicId and IOsapicId filds are on the same place in bouth structures
+ } // found entry with bigger IOapicId/IOsapicId
+
+ if (j == MadtTblEntries.MadtEntCount)
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ }
+
+ else
+ {
+ Status = InsertItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr, j);
+ }
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ IoApicCnt++;
+ }
+ }
+
+#endif //FEC00000_APIC_AUTODETECT == 1
+
+//---------------------------------------------------------------------
+
+#if USE_BOARD_INFO_APIC_DATA == 1
+ {
+ AMI_APIC_INFO *BrdApicInfo;
+ BOOLEAN Present;
+
+ //-----------------
+ for (i=0; i<(gAmiBoardInfoProtocol->ApicInfoLength/sizeof(AMI_APIC_INFO)); i++)
+ {
+
+ BrdApicInfo=&gAmiBoardInfoProtocol->ApicInfoTable[i];
+
+ //This is a special case it could be a duplicate entries in MadtTblEntries[]
+ //if other options of IOAPIC/IOsAPIC detection was on.
+ //So check if IOAPIC/IOsAPIC entries with the same properties already present in DB.
+ for (j=(LastItem),Present=FALSE; j < MadtTblEntries.MadtEntCount; j++)
+ {
+ HdrPtr=MadtTblEntries.MadtEntries[j];
+
+ if (HdrPtr->Type==AT_IOAPIC)
+ {
+ IOAPIC_H20 *apic=(IOAPIC_H20*)HdrPtr;
+
+ //----------------------
+ if (BrdApicInfo->ApicAddress.ADDRESS == apic->IoapicAddress)
+ {
+ Present = TRUE;
+ break;
+ }
+ }
+
+ else //Nothing else should not be here except IOAPIC or IOSAPIC entries
+ {
+ IOSAPIC_H20 *sapic=(IOSAPIC_H20*)HdrPtr;
+
+ //----------------------
+ if ((UINT64)BrdApicInfo->ApicAddress.ADDRESS == sapic->IosapicAddress)
+ {
+ Present = TRUE;
+ break;
+ }
+ }
+ }
+
+ //Entry with this address already present in MadtTblEntries array
+ if (Present) continue;
+
+ //Looks like it is a new IOAPIC/IOSAPIC entry!
+ //Check if something alive at this address
+ if (*((UINT8 *)BrdApicInfo->ApicAddress.ADDRESS) != 0xFF)
+ {
+ IoapicAddr=BrdApicInfo->ApicAddress.ADDRESS;
+ HdrPtr = BuildIoapicIosapic(IoapicAddr, &IoapicVbase);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ if (MadtTblEntries.MadtEntCount == LastItem) // Adding entries in groving IOapicId/IOsapicId value order
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);// First entry
+ else
+ {
+ for (j = (LastItem); j < MadtTblEntries.MadtEntCount; j++)
+ { // No need to handle LSAPIC entry in different way
+ if (((IOAPIC_H32*)HdrPtr)->IoapicId < ((IOAPIC_H32*)MadtTblEntries.MadtEntries[j])->IoapicId) break; // IOapicId and IOsapicId filds are on the same place in bouth structures
+ } // found entry with bigger IOapicId/IOsapicId
+
+ if (j == MadtTblEntries.MadtEntCount)
+ {
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ }
+
+ else
+ {
+ Status = InsertItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr, j);
+ }
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ IoApicCnt++;
+ }
+ } // if(...i<(gAmiBoardInfoProtocol->ApicInfoLength/sizeof(AMI_APIC_INFO))
+ }
+#endif //USE_BOARD_INFO_APIC_DATA ==1
+
+//-------------------------------------------------------------------------------------------
+ if (!IoApicCnt)
+ {
+ HdrPtr = BuildIoapicManualy();
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ IoapicVbase = (UINT32) 1;
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ }
+
+
+//-------Build ISO Structure----------------------------
+ for (i=0; i<IsoCnt; i++)
+ {
+ if (IsoTbl[i].PicIrq == 0xFF) continue; //no override for this entry
+
+ HdrPtr = BuildIsoFromTbl(i);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+//-------Build NMIs Structure---------------------------
+ Status = EFI_UNSUPPORTED;
+#if AMI_CPU_INFO_2_PROTOCOL_VERSION >= 3
+ //First try to build Local APIC information from the protocol.
+ if (gAmiCpu2Info != NULL)
+ {
+ Status = BuildLapicNmiFromProtocol(&MadtTblEntries);
+ }
+#endif
+
+ if (EFI_ERROR(Status))
+ {
+#if (NMIs_QUANTITY > 0)
+
+ HdrPtr = MallocZ(sizeof(NMI_H20));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ ((NMI_H20*) HdrPtr)->Header.Type = (UINT8) AT_NMI; //Type 3 - indicating NMIs Entry
+ ((NMI_H20*) HdrPtr)->Header.Length = (UINT8) sizeof(NMI_H20);
+ ((NMI_H20*) HdrPtr)->Flags = (UINT16)((NMI_0_TRIGGER_MODE<<2) | NMI_0_POLARITY);
+ ((NMI_H20*) HdrPtr)->GlobalSysVect = (UINT32) NMI_GLOBAL_SYS_INT_0;
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+#if (NMIs_QUANTITY > 1)
+ HdrPtr = MallocZ(sizeof(NMIH_20));
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ ((NMI_H20*) HdrPtr)->Header.Type = (UINT8) AT_NMI; //Type 3 - indicating NMIs Entry
+ ((NMI_H20*) HdrPtr)->Header.Length = (UINT8) sizeof(NMI_H20);
+ ((NMI_H20*) HdrPtr)->Flags = (UINT16)((NMI_1_TRIGGER_MODE<<2) | NMI_1_POLARITY);
+ ((NMI_H20*) HdrPtr)->GlobalSysVect = (UINT32) NMI_GLOBAL_SYS_INT_1;
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+#endif
+
+//---Porting Hook 1 ------ If NMIs_QUANTITY > 2 - Add more structures
+#endif
+//--------Build LAPIC NMI-------------------------
+
+#if (LAPIC_QUANTITY > 0)
+
+ if (LAPIC_0_INT_TYPE == 1) // This is NMI - so build a table for it
+ {
+ HdrPtr = BuildLocalApicNmi(gX2Apic ? TRUE : FALSE, 0xffffffff, LAPIC_0_DEST_LINTIN, (LAPIC_0_TRIGGER_MODE<<2) | LAPIC_0_POLARITY);
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+#if (LAPIC_QUANTITY > 1)
+
+ if (LAPIC_1_INT_TYPE == 1) // This is NMI - so build a table for it
+ {
+ HdrPtr = BuildLocalApicNmi(gX2Apic ? TRUE : FALSE, 0xffffffff, LAPIC_1_DEST_LINTIN, (LAPIC_1_TRIGGER_MODE<<2) | LAPIC_1_POLARITY);
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+#endif
+#if (LAPIC_QUANTITY > 2)
+
+ if (LAPIC_2_INT_TYPE == 1) // This is NMI - so build a table for it
+ {
+ HdrPtr = BuildLocalApicNmi(gX2Apic ? TRUE : FALSE, 0xffffffff, LAPIC_2_DEST_LINTIN, (LAPIC_2_TRIGGER_MODE<<2) | LAPIC_2_POLARITY);
+ ASSERT (HdrPtr);
+
+ if (!HdrPtr) return EFI_OUT_OF_RESOURCES;
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&MadtTblEntries, (VOID*) HdrPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+#endif
+//------Porting Hook 2----If LAPIC_QUANTITY > 3 - Add more structures
+#endif
+ }
+
+//---Tis ia all for Ver 1 - building a table----------------------
+//----Here starts entries for V 2 and 3 which are empty for now----------------------------------
+//
+// Here entries for LAPIC Address overrride structure and Platforme interrupt source structure
+//
+
+ for (i = 0; i < MadtTblEntries.MadtEntCount; i++)
+ {
+
+ AllStrLength += MadtTblEntries.MadtEntries[i]->Length;
+ }
+
+ *TablPtr = MallocZ(sizeof(APIC_20H) + (UINTN) AllStrLength);
+ ASSERT (*TablPtr);
+
+ if (!(*TablPtr)) return EFI_OUT_OF_RESOURCES;
+
+ if (TablVer == 1) PrepareHdr1 (APIC_SIG, (PACPI_HDR) *TablPtr);
+ else PrepareHdr20 (APIC_SIG, (PACPI_HDR) *TablPtr, TablVer);
+
+ (*TablPtr)->Length = (sizeof(APIC_20H) + AllStrLength);
+ ((APIC_20H*)*TablPtr)->LAPIC_Address = LOCAL_APIC_BASE;
+ ((APIC_20H*)*TablPtr)->Flags = ACPI_APIC_FLAGS;
+ DestinPtr = ((UINT8*) *TablPtr + sizeof(APIC_20H));
+
+ for (i = 0; i < MadtTblEntries.MadtEntCount; i++)
+ {
+
+ MemCopy ((UINT8*)MadtTblEntries.MadtEntries[i], DestinPtr, (UINT32) MadtTblEntries.MadtEntries[i]->Length);
+ DestinPtr += MadtTblEntries.MadtEntries[i]->Length;
+ pBS->FreePool((VOID*)MadtTblEntries.MadtEntries[i]);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ (*TablPtr)->Checksum = 0;
+ (*TablPtr)->Checksum = ChsumTbl((UINT8*)*TablPtr, (*TablPtr)->Length);
+
+ return EFI_SUCCESS;
+}// end of BuildMadtAll-----------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildFacs
+//
+// Description: Allocates ACPI NVS memory and builds FACS table from values,
+// defined by SDL tokens
+//
+// Input: none
+//
+//
+// Output: EFI_STATUS
+// EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_SUCCESS - FACS table were successfully build
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BuildFacs ()
+{
+ EFI_STATUS Status;
+ UINTN Size;
+
+
+ if (gForceAcpi1) Size = sizeof(FACS_20);
+ else Size = sizeof(FACS_20)*2;
+ Status = pBS->AllocatePool(EfiACPIMemoryNVS, Size+64, &gFacs);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+#ifdef EFIx64
+
+ if (((UINT64)gFacs) & 0xffffffff00000000)
+ {
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+ Status = pBS->FreePool(gFacs);
+ ASSERT_EFI_ERROR(Status);
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, 1, &Memory);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ (UINTN) gFacs = Memory;
+ }
+
+#endif
+ (UINTN) gFacs += 64;
+ (UINTN) gFacs &= (~0x3F);
+ pBS->SetMem(gFacs, Size, 0);
+ gFacs->Signature=(UINT32)FACS_SIG;
+ gFacs->Length=sizeof(FACS_20);
+ gFacs->Flags=FACS_FLAG_S4BIOS;
+
+ if (gForceAcpi1) return EFI_SUCCESS;
+
+ (UINTN) gxFacs = (UINTN) gFacs + sizeof(FACS_20);
+ gxFacs->Signature=(UINT32)FACS_SIG;
+ gxFacs->Length=sizeof(FACS_20);
+
+ if (ACPI_BUILD_TABLES_4_0 != 1)
+ {
+ gxFacs->Flags=FACS_FLAG_S4BIOS;
+ gxFacs->Version=ACPI_REV1;
+ }
+
+ else
+ {
+ gxFacs->Flags = FACS_FLAG_S4BIOS | (FACS_FLAG_64BIT_WAKE_SUPPORTED << 1);
+ gxFacs->Version=ACPI_REV2;
+ }
+
+
+
+
+ return EFI_SUCCESS;
+}// end of BuildFacs ---------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDsdtFv
+//
+// Description:
+// This function finds DSDT table in firmvare volume
+//
+// Input:
+// OUT ACPI_HDR **Dsdt1 - pointer to memory where DSDT v1.1 table will be stored
+// OUT ACPI_HDR **Dsdt2 - pointer to memory where DSDT v2.0+ table will be stored
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ABORTED - ACPI storage file not found
+// EFI_NOT_FOUND - DSDT table not found in firmware volume
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetDsdtFv(OUT ACPI_HDR **Dsdt1, OUT ACPI_HDR **Dsdt2)
+{
+
+ //In current AmiBoardInfo implementation separate instance of
+ //DSDT for ACPI version 1.1b DOES OT SUPPORTED!
+ *Dsdt1=NULL;
+ *Dsdt2 = Malloc(((ACPI_HDR*)gAmiBoardInfoProtocol->BoardAcpiInfo)->Length);
+ ASSERT(*Dsdt2);
+ if (((UINT64)*Dsdt2) & 0xffffffff00000000)
+ {
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+
+ Status = pBS->FreePool(*Dsdt2);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(((ACPI_HDR*)gAmiBoardInfoProtocol->BoardAcpiInfo)->Length),
+ &Memory);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ *Dsdt2 = (ACPI_HDR *)((UINTN)Memory);
+ }
+
+ if (*Dsdt2==NULL) return EFI_OUT_OF_RESOURCES;
+
+ pBS->CopyMem(*Dsdt2, gAmiBoardInfoProtocol->BoardAcpiInfo,
+ ((ACPI_HDR*)gAmiBoardInfoProtocol->BoardAcpiInfo)->Length);
+
+
+ if ((*Dsdt1 == NULL) && (*Dsdt2 == NULL))
+ {
+ TRACE((-1,"Acpi: No DSDT was FOUND: Status=EFI_NOT_FOUND\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //PrepareHdr1(DSDT_SIG, (ACPI_HDR*)(*Dsdt1));
+ PrepareHdr20(DSDT_SIG, (ACPI_HDR*)(*Dsdt2),2);
+
+ return EFI_SUCCESS;
+
+}// end of GetDsdtFv -----------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateFacp
+//
+// Description: This function Updates FACP with the new values for DSDT and Facs
+// pointers
+//
+// Input: FACS_20* gFacs1 - Pointer to gFacs Table for V 1
+// FACS_20* gFacs2 - Pointer to gFacs Table for V 2 or 3
+//
+// Output: EFI_SUCCESS - Function executed successfully
+// EFI_ABORTED - Error
+//
+//
+// Modifies gAcpiData
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateFacp () //(FACS_20 *gFacs1, FACS_20 *gFacs2)
+{
+ ACPI_HDR *Facp1 = NULL, *Facp2 = NULL, *Dsdt1 = NULL, *Dsdt2 = NULL;
+ UINTN i;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Facp1 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 1.1
+ else
+ Facp2 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 2+
+ }
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Dsdt1 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 1.1
+ else
+ Dsdt2 = gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 2+
+ }
+ }
+
+ if (Dsdt1 == NULL) Dsdt1 = Dsdt2; // The same DSDT for V1.1
+
+ if (Dsdt2 == NULL) Dsdt2 = Dsdt1; // The same DSDT for V2
+
+ if ((Facp1 == NULL) || (Dsdt1 == NULL)) Status = EFI_ABORTED;
+ if ((Facp2 == NULL) && (!gForceAcpi1)) Status = EFI_ABORTED;
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return Status;
+
+//--- Updating FACP for V1.1 and 2+---------------------------
+ ((FACP32*) Facp1)->FIRMWARE_CTRL = (UINT32) gFacs;
+ ((FACP32*) Facp1)->DSDT = (UINT32) Dsdt1;
+
+
+ Facp1->Checksum = 0;
+ Facp1->Checksum = ChsumTbl((UINT8*)Facp1, Facp1->Length);
+ if (gForceAcpi1) return Status;
+ if (ACPI_BUILD_TABLES_4_0 == 1) ((FACP_20*) Facp2)->FIRMWARE_CTRL = (UINT32) gxFacs;
+ else ((FACP_20*) Facp2)->FIRMWARE_CTRL = (UINT32) gFacs;
+
+ ((FACP_20*) Facp2)->DSDT = (UINT32) Dsdt1;
+
+ if (ACPI_BUILD_TABLES_4_0 != 1)((FACP_20*) Facp2)->X_FIRMWARE_CTRL = (UINT64) ((UINTN) gxFacs);
+
+ ((FACP_20*) Facp2)->X_DSDT = (UINT64) ((UINTN)Dsdt2);
+ Facp2->Checksum = 0;
+ Facp2->Checksum = ChsumTbl((UINT8*)Facp2, Facp2->Length);
+ return Status;
+}// end of UpdateFacp
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindAcpiTblByHandle
+//
+// Description: Finds ACPI table by Handle and returns its entry number in
+// gAcpiData structure
+//
+// Input: UINTN *Handle - Handle (pointer to ACPI table header)
+//
+//
+// Output: UINTN - Entry number in gAcpiData structure
+// ACPI_TABLE_NOT_FOUND if not found
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN FindAcpiTblByHandle (UINTN *Handle)
+{
+ UINTN i;
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if (*Handle == (UINTN)gAcpiData.AcpiEntries[i]->BtHeaderPtr) // Handle is the address of ACPI table
+ {
+ return i;
+ }
+ }
+
+ return ACPI_TABLE_NOT_FOUND;
+}// end of FindAcpiTblByHandle
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBtTable
+//
+// Description: Founds ACPI Table with defined Signature (Sig) and Version in gAcpiData structure.
+//
+//
+// Input: OUT ACPI_TBL_ITEM **TblPtr - pointer to the ACPI entrie in gAcpiData,
+// modifided by this function
+// IN UINT32 Sig - Signature of a table to search for
+// IN EFI_ACPI_TABLE_VERSION - Version of a table to be found
+//
+// Output: EFI_SUCCESS - table with corresponding signature was found
+// EFI_NOT_FOUND - otherwise
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetBtTable (OUT ACPI_TBL_ITEM **TblPtr, IN UINT32 Sig, IN EFI_ACPI_TABLE_VERSION Versiov)
+{
+ UINTN i;
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if ((gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == Sig)
+ && (gAcpiData.AcpiEntries[i]->AcpiTblVer & Versiov))
+ {
+ *TblPtr = gAcpiData.AcpiEntries[i];
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}// end of GetBtTable
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DispatchSdtNotify
+//
+// Description: Checks if Notify function(s) present dispatches it.
+//
+//
+// Input: EFI_ACPI_SDT_HEADER *TableHeaderPtr - pointer to the ACPI Table header,
+// modifided by this function
+// Output: EFI_STATAUS - From the function dispatched.
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DispatchSdtNotify(ACPI_TBL_ITEM* TableItemPtr){
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN i;
+//--------
+ for(i=0;i<gAcpiData.NotifyFnCount; i++){
+ Status=gAcpiData.AcpiNotifyFn[i]((EFI_ACPI_SDT_HEADER*)TableItemPtr->BtHeaderPtr,TableItemPtr->AcpiTblVer,(UINTN)TableItemPtr);
+
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FillAcpiStr
+//
+// Description: Copys table from position pointed by FromPtr to a position pointed
+// by ToPtr (which is in EfiACPIReclaimMemory) and fills RSDT and XSDT
+// pointers with ToPtr value
+//
+//
+// Input: RSDT32 *RsdtPtr - pionter to RSDT
+// XSDT_20 *XsdtPtr - pionter to XSDT
+// VOID *FromPtr - pointer to a table which should be copyed
+// VOID *ToPtr - pointer to EfiACPIReclaimMemory where table should be placed
+//
+// Output: UINT8* - Pointer to the next avaiable space in allocated EfiACPIReclaimMemory
+// right after copyed table (alligned already)
+// If NUUL - Invalid parameters.
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 *FillAcpiStr (RSDT32 *RsdtPtr, XSDT_20 *XsdtPtr, VOID *FromPtr, VOID *ToPtr)
+{
+ UINT8 *NextPtr;
+ UINTN i;
+
+
+ if ((RsdtPtr == NULL) && (XsdtPtr == NULL)) return NULL;
+
+ if ((FromPtr == NULL) || (ToPtr == NULL)) ASSERT(0);
+
+ pBS->CopyMem(ToPtr, FromPtr, ((ACPI_HDR*)FromPtr)->Length);
+
+ if (RsdtPtr != NULL)
+ {
+ for (i = 0; RsdtPtr->Ptrs[i] != 0; i++); // Find first unfilled (last) entry in RSDT
+
+ RsdtPtr->Ptrs[i] = (UINT32) ToPtr;
+ }
+
+ if (XsdtPtr != NULL)
+ {
+ for (i = 0; XsdtPtr->Ptrs[i] != 0; i++); // Find first unfilled (last) entry in XSDT
+
+ XsdtPtr->Ptrs[i] = (UINT64) ((UINTN)ToPtr);
+ }
+
+ NextPtr = (UINT8*) ((UINT8*)ToPtr+((ACPI_HDR*)ToPtr)->Length + 7);
+ (UINTN) NextPtr &= (~0x7);
+
+ return NextPtr;
+
+}//end of FillAcpiStr
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PublishTbl
+//
+// Description: Creates or rewrites RSDT_PTR structure and copys tables, stored
+// in gAcpiData structure in allocated EfiACPIReclaimMemory.
+//
+//
+// Input: IN UINTN RsdtBuild - if 1 - Build RSDT and copy tables of Ver 1.1
+// IN UINTN XsdtBuild - if 1 - Build XSDT and copy tables of Ver 2+
+//
+// Output: EFI_OUT_OF_RESOURCES - not enough memory
+// EFI_ABORTED - invalid parameters
+// EFI_SUCCESS - RSDT_PTR structure was successfully build
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PublishTbl (IN UINTN RsdtBuild, IN UINTN XsdtBuild)
+{
+ ACPI_HDR *Facp = NULL, *FacpX = NULL, *Dsdt = NULL, *DsdtX = NULL;
+ RSDT32 *Rsdt = NULL;
+ XSDT_20 *Xsdt = NULL;
+ UINTN i, j, RsdtCnt = 0, XsdtCnt = 0, SpaceNeeded = 0, RsdtSize = 0, XsdtSize = 0, Skip;
+ EFI_STATUS Status;
+ UINT8 *Ptr = NULL, *Dummy = NULL, OneDsdt = 0;
+ EFI_PHYSICAL_ADDRESS Memory = 0x00000000ffffffff;
+
+ if (((RsdtBuild == 0) && (XsdtBuild == 0)) || (RsdtBuild > 1 ) || (XsdtBuild > 1)) return EFI_ABORTED;
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if (!gOA3Variable)
+ {
+ UINTN SizeOfMsdm = sizeof(EFI_OA3_MSDM_STRUCTURE);
+ //Looking for Var which signals that MSDM table may be updated on runtime
+ Status = pRS->GetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &gAmiGlobalVariableGuid,
+ NULL,
+ &SizeOfMsdm,
+ &gMsdmVariable
+ );
+ if (Status == EFI_SUCCESS)
+ {
+ gOA3Variable = TRUE;
+ XsdtCnt++; // Reserving Entry for MSDM (OEM Activation)
+ }
+ }
+ else XsdtCnt++;
+#endif
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer < EFI_ACPI_TABLE_VERSION_1_0B) continue;
+
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ RsdtCnt ++;
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ Facp = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ Dsdt = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ }
+
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer > EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ XsdtCnt ++;
+ RsdtCnt ++;
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ {
+ FacpX = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ //if (Facp != NULL) RsdtCnt --;
+ //continue;
+ }
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ {
+ DsdtX = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ }
+
+ for (j = 0; j < gAcpiData.AcpiEntCount; j++)
+ {
+ if (j == i) continue;
+
+ if ((gAcpiData.AcpiEntries[j]->BtHeaderPtr->Signature == gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature)
+ && (gAcpiData.AcpiEntries[j]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)) RsdtCnt --;
+ }
+ }
+ }
+
+ if ((Dsdt == NULL) || (DsdtX == NULL)) OneDsdt = 1;
+
+ if (Dsdt == NULL) Dsdt = DsdtX;
+
+ if (DsdtX == NULL) DsdtX = Dsdt;
+
+ RsdtSize = RsdtBuild * (sizeof(ACPI_HDR) + (RsdtCnt-1) * sizeof(UINT32) + 7); //DSDT does not goes in RSDT (RsdtCnt-1)
+
+ XsdtSize = XsdtBuild * (sizeof(ACPI_HDR) + (XsdtCnt-1) * sizeof(UINT64) + 7); //DSDT does not goes in XSDT (XsdtCnt-1)
+ SpaceNeeded = sizeof(RSDT_PTR_20) + RsdtSize + XsdtSize + gAcpiData.AcpiLength + (gAcpiData.AcpiEntCount + 1) * 8;
+
+ if (gRsdtPtrStr != NULL)
+ {
+ Status = pBS->FreePages((EFI_PHYSICAL_ADDRESS)(UINTN) gRsdtPtrStr, gAcpiTblPages);
+ ASSERT_EFI_ERROR(Status);
+ }
+ /*
+ Status = pBS->AllocatePool(EfiACPIReclaimMemory, SpaceNeeded, (VOID**)&gRsdtPtrStr);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ */
+ gAcpiTblPages = EFI_SIZE_TO_PAGES(SpaceNeeded);
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if (gOA3Variable)
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiACPIMemoryNVS, gAcpiTblPages , &Memory);
+ else
+#endif
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiACPIReclaimMemory, gAcpiTblPages , &Memory);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gRsdtPtrStr = (RSDT_PTR_20*)Memory;
+
+ pBS->SetMem(gRsdtPtrStr, SpaceNeeded, 0);
+
+ if (RsdtBuild)
+ {
+ Dummy = (UINT8*) ((UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + 7);
+ (UINTN) Dummy &= (~0x7);
+ Rsdt = (RSDT32*) Dummy;
+ Ptr = (UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + RsdtSize + XsdtSize + 7;
+ (UINTN) Ptr &= (~0x7);
+ Dummy = FillAcpiStr (Rsdt, NULL, (VOID*) Facp, (VOID*) Ptr);// The first table in RSDT must be Facp
+ Facp = (ACPI_HDR*) Ptr;
+ Ptr = Dummy;
+ pBS->CopyMem((VOID*)Ptr, (VOID*)Dsdt, Dsdt->Length);
+
+ if (Dsdt == DsdtX) Dsdt = DsdtX = (ACPI_HDR*) Ptr;
+ else Dsdt = (ACPI_HDR*) Ptr;
+
+ Ptr += (Dsdt->Length + 7);
+ (UINTN) Ptr &= (~0x7);
+ ((FACP32*)Facp)->FIRMWARE_CTRL = (UINT32) gFacs;
+ ((FACP32*)Facp)->DSDT = (UINT32) Dsdt;
+ Facp->Checksum = 0;
+ Facp->Checksum = ChsumTbl((UINT8*)Facp, Facp->Length);
+ }
+
+ if ((XsdtBuild) && (!gForceAcpi1))
+ {
+ Dummy = (UINT8*) ((UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + RsdtSize + 7);
+ (UINTN) Dummy &= (~0x7);
+ Xsdt = (XSDT_20*) Dummy;
+
+ if (Ptr == NULL)
+ {
+ Ptr = (UINT8*) ((UINT8*)gRsdtPtrStr + sizeof(RSDT_PTR_20) + RsdtSize + XsdtSize + 7);
+ //else Ptr += (((ACPI_HDR*)Ptr)->Length + 7);
+ (UINTN) Ptr &= (~0x7);
+ }
+
+ Dummy = FillAcpiStr (NULL, Xsdt, (VOID*) FacpX,( VOID*) Ptr);
+ FacpX = (ACPI_HDR*) Ptr;
+ Ptr = Dummy;
+
+ if ((!OneDsdt) || (!RsdtBuild))
+ {
+ pBS->CopyMem((VOID*)Ptr, (VOID*)DsdtX, DsdtX->Length);
+ DsdtX = (ACPI_HDR*) Ptr;
+ Ptr += (DsdtX->Length + 7);
+ (UINTN) Ptr &= (~0x7);
+ }
+
+ if (ACPI_BUILD_TABLES_4_0 == 1) ((FACP_20*)FacpX)->FIRMWARE_CTRL = (UINT32) gxFacs;
+ else ((FACP_20*)FacpX)->FIRMWARE_CTRL = (UINT32) gFacs;
+
+ ((FACP_20*)FacpX)->DSDT = (UINT32) Dsdt;
+
+ if (ACPI_BUILD_TABLES_4_0 != 1)((FACP_20*)FacpX)->X_FIRMWARE_CTRL = (UINT64) ((UINTN)gxFacs);
+
+ ((FACP_20*)FacpX)->X_DSDT = (UINT64) ((UINTN)DsdtX);
+ FacpX->Checksum = 0;
+ FacpX->Checksum = ChsumTbl((UINT8*)FacpX, FacpX->Length);
+ }
+
+ for (i = 0; i < gAcpiData.AcpiEntCount; i++)
+ {
+ if ((gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG) ||
+ (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG) ||
+ (gAcpiData.AcpiEntries[i]->AcpiTblVer < EFI_ACPI_TABLE_VERSION_1_0B)) continue;
+
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ Dummy = FillAcpiStr (Rsdt, NULL, (VOID*) gAcpiData.AcpiEntries[i]->BtHeaderPtr,( VOID*) Ptr);
+
+ if (Dummy != NULL) Ptr = Dummy;
+ }
+
+ else
+ {
+ Skip = 0;
+
+ for (j = 0; j < gAcpiData.AcpiEntCount; j++)
+ {
+ if (j == i) continue;
+
+ if ((gAcpiData.AcpiEntries[j]->BtHeaderPtr->Signature == gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature)
+ && (gAcpiData.AcpiEntries[j]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)) Skip = 1;
+ }
+
+ if (Skip) Dummy = FillAcpiStr (NULL, Xsdt, (VOID*) gAcpiData.AcpiEntries[i]->BtHeaderPtr,( VOID*) Ptr);
+ else Dummy = FillAcpiStr (Rsdt, Xsdt, (VOID*) gAcpiData.AcpiEntries[i]->BtHeaderPtr,( VOID*) Ptr);
+
+ if (Dummy != NULL) Ptr = Dummy;
+ }
+ }
+
+ if (Ptr > ((UINT8*)gRsdtPtrStr + SpaceNeeded)) Status = EFI_OUT_OF_RESOURCES;
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ gRsdtPtrStr->Signature = RSDP_SIG;
+
+ if ((!XsdtBuild) || (gForceAcpi1)) gRsdtPtrStr->Revision = 0; //Reserved in ver 1
+ else gRsdtPtrStr->Revision = ACPI_REV2; // 2 for ver 2 and 3
+
+ gRsdtPtrStr->Length = sizeof(RSDT_PTR_20);//this is the length of entire structure
+
+ for (i=0; i<6; i++) gRsdtPtrStr->OEMID[i]=ACPI_OEM_ID[i];
+
+ gRsdtPtrStr->RsdtAddr = (UINT32) Rsdt;
+ gRsdtPtrStr->XsdtAddr = (UINT64) ((UINTN)Xsdt);
+ gRsdtPtrStr->Checksum = ChsumTbl((UINT8*)gRsdtPtrStr, 20);
+ gRsdtPtrStr->XtdChecksum = ChsumTbl((UINT8*)gRsdtPtrStr, sizeof (RSDT_PTR_20));
+
+ if (RsdtBuild)
+ {
+ PrepareHdr1 (RSDT_SIG, (ACPI_HDR*) Rsdt);
+ Rsdt->Header.Length = (UINT32) (RsdtSize - 7);
+ Rsdt->Header.Checksum = 0;
+ Rsdt->Header.Checksum = ChsumTbl((UINT8*)Rsdt, Rsdt->Header.Length);
+ Status = pBS->InstallConfigurationTable(&gAcpi11TAbleGuid, (VOID*) gRsdtPtrStr);
+ TRACE((-1,"Installing ACPI 1.1: %r, %X\n",Status,gRsdtPtrStr));////-----------------------------------------
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ if (XsdtBuild)
+ {
+ if (ACPI_BUILD_TABLES_3_0 == 1) PrepareHdr20 (XSDT_SIG, (ACPI_HDR*) Xsdt, 3);
+ else PrepareHdr20 (XSDT_SIG, (ACPI_HDR*) Xsdt, 2);
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if (gOA3Variable)
+ Xsdt->Header.Length = (UINT32) (XsdtSize - sizeof(UINT64) - 7);//one reserved position for MSDM
+ else
+#endif
+ Xsdt->Header.Length = (UINT32) (XsdtSize - 7);
+ Xsdt->Header.Checksum = 0;
+ Xsdt->Header.Checksum = ChsumTbl((UINT8*)Xsdt, Xsdt->Header.Length);
+// if (RsdtBuild) Status = pBS->InstallConfigurationTable(&gAcpi11TAbleGuid, NULL); // Delete V1.1 entry - Only one
+ Status = pBS->InstallConfigurationTable(&gAcpi20TAbleGuid, (VOID*) gRsdtPtrStr);
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+#if defined(OemActivation_SUPPORT) && (OemActivation_SUPPORT == 1)
+ if ((Xsdt != NULL) && gOA3Variable)
+ {
+ gMsdmVariable.XsdtAddress = (EFI_PHYSICAL_ADDRESS) Xsdt;
+ Status = pRS->SetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(EFI_OA3_MSDM_STRUCTURE),
+ &gMsdmVariable
+ );
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+ return EFI_SUCCESS;
+
+}// end of PublishTbl
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateAml
+//
+// Description:
+// This function updates AML objects with values provided in ACPI_AML_UPD_INFO
+// structure
+//
+// Input:
+// IN ACPI_AML_UPD_INFO *AmlUpdInfo - pointer to ACPI_AML_UPD_INFO structure
+//
+// Output:
+// EFI_SUCCESS - AML objects updated successfully
+// EFI_ERROR - some error occured during update process
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateAml(ACPI_AML_UPD_INFO *AmlUpdInfo)
+{
+ UINTN i;
+ ACPI_HDR *Dsdt;
+ EFI_STATUS Status = 0;
+
+//-------------------------
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i) Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt1Addr;
+ else Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt2Addr;
+
+ if (Dsdt)
+ {
+ //Update TOPM Object
+ Status = UpdateAslNameObject(Dsdt, "TOPM", AmlUpdInfo->TopOfMemory);
+ ASSERT_EFI_ERROR (Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ //Update ROMS Object
+ //Status = UpdateNameObject(Dsdt, AML_NAME_ROMS, AmlUpdInfo->RomStart);
+ //ASSERT_EFI_ERROR(Status)
+ //if(EFI_ERROR(Status)) return Status;
+//TODO: IOST and SSx Objects update
+ //Update IOST Object
+ Status = UpdateAslNameObject(Dsdt, "IOST", (UINT64)AmlUpdInfo->SioDevStatusVar.DEV_STATUS);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = UpdateAslNameObject(Dsdt, "SS4", (UINT64)AmlUpdInfo->SS4);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+#if ATAD_SUPPORT == 1
+ if (AtadBuffPtr)
+ {
+ TRACE((-1, "AtadBuffPtr=0x%lX ", (UINT64)AtadBuffPtr));
+ Status = UpdateAslNameObject(Dsdt, "ATBF", (UINT64)AtadBuffPtr);
+ ASSERT_EFI_ERROR (Status);
+ if (!EFI_ERROR(Status))
+ Status = UpdateAslNameObject(Dsdt, "BUFU", 1);
+ ASSERT_EFI_ERROR (Status);
+ }
+#endif
+
+ Status = UpdateAslNameObject(Dsdt, "SS3", (UINT64)AmlUpdInfo->SS3);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = UpdateAslNameObject(Dsdt, "SS2", (UINT64)AmlUpdInfo->SS2);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = UpdateAslNameObject(Dsdt, "SS1", (UINT64)AmlUpdInfo->SS1);
+ ASSERT_EFI_ERROR(Status)
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Dsdt->Checksum = 0;
+ Dsdt->Checksum = ChsumTbl((UINT8*)Dsdt, Dsdt->Length);
+ }
+ }
+
+ return Status;
+
+
+}//end of UpdateAml
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LockLegacyRes
+//
+// Description:
+// This function Hides Legacy Resources from OS by destroing _PRS method
+// in each Legacy Device ASL Object in DSDT
+//
+// Input:
+// IN ACPI_AML_UPD_INFO *AmlUpdInfo - pointer to ACPI_AML_UPD_INFO structure
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LockLegacyRes (ACPI_AML_UPD_INFO *AmlUpdInfo)
+
+{
+
+ UINTN HandleCnt, j, i;
+ EFI_HANDLE *HandleBuffer = NULL;
+ SPIO_DEV *SpIoDev;
+ ASL_OBJ_INFO AslObj={0};
+ ACPI_HDR *Dsdt;
+ EFI_STATUS Status = 0;
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ EFI_SIO_DATA *EfiSioData;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiSioProtocolGuid, NULL, &HandleCnt, &HandleBuffer);
+#else
+ AMI_SIO_PROTOCOL *AmiSio;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiAmiSioProtocolGuid, NULL, &HandleCnt, &HandleBuffer);
+#endif
+ //Locate all handles for SIO
+
+ if ((EFI_ERROR(Status)) || (HandleBuffer == NULL)) return;
+
+ for (j = 0; j < HandleCnt; j++)
+ {
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ Status = pBS->HandleProtocol(HandleBuffer[j], &gEfiSioProtocolGuid, &EfiSioData);
+#else
+ Status = pBS->HandleProtocol(HandleBuffer[j], &gEfiAmiSioProtocolGuid, &AmiSio);
+#endif
+ if (EFI_ERROR(Status)) continue;
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ SpIoDev = EfiSioData->Owner;
+#else
+ SpIoDev = (SPIO_DEV*)(UINTN)AmiSio;
+#endif
+ if (SpIoDev->DeviceInfo->AslName[0])
+// TRACE ((-1,"Found SIO Protocol. Name: %s\n",(UINT32)SpIoDev->DeviceInfo->AslName));
+ // If this device has ASL Name and is present in DSDT
+ {
+ for (i = 0; i < 2; i++)
+ {
+ if (i) Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt1Addr;
+ else Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt2Addr;
+
+ if (Dsdt)
+ {
+// TRACE ((-1,"Looking DSDT for Name: %s\n", SpIoDev->DeviceInfo->AslName));
+ Status = GetAslObj((UINT8*)Dsdt+sizeof(ACPI_HDR),
+ Dsdt->Length-sizeof(ACPI_HDR)-1, &SpIoDev->DeviceInfo->AslName[0],
+ otDevice, &AslObj);
+ // Get Asl object associated with this Legacy device
+ ASSERT_EFI_ERROR(Status);
+
+// TRACE ((-1,"Going to hide object Data statr= %x, Length= %x\n",AslObj.DataStart, AslObj.Length));
+ if (!EFI_ERROR(Status)) HideAslMethodFromOs (&AslObj, "_PRS");
+
+ // Lock this Device by destroing _PRS method of this object
+ }
+ }
+ }
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ if (i) Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt1Addr;
+ else Dsdt = (ACPI_HDR*)AmlUpdInfo->Dsdt2Addr;
+
+ if (Dsdt)
+ {
+ Dsdt->Checksum = 0;
+ Dsdt->Checksum = ChsumTbl((UINT8*)Dsdt, Dsdt->Length);
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectAmlUpdInfo
+//
+// Description:
+// This function will be called when ReadyToBoot event will be signaled and
+// will update IO devices status and then update AML binary. It allso publish all
+// ACPI tables.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CollectAmlUpdInfo(EFI_EVENT Event, VOID *Context)
+{
+ ACPI_AML_UPD_INFO *Aui=Context;
+ FACP_20 *xFacp = NULL;
+// ACPI_HDR *Dsdt1 = NULL, *Dsdt2 = NULL;
+// FACP32 *Facp = NULL;
+ FACP_20 *Facp = NULL;
+ UINTN i;
+ EFI_STATUS Status;
+ SETUP_DATA *SetupData=NULL;
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+//-------------------------------------------
+ //Init Setup Sleep States with Default Values;
+ TRACE((-1,"IN Collect AML Info: %x\n",0));
+
+ //we need to recreate MADT table instances on READY_TO_BOOT event.
+ for (i=0; i<gAcpiData.AcpiEntCount; i++)
+ {
+ ACPI_TBL_ITEM *AcpiTable = gAcpiData.AcpiEntries[i];
+ UINTN AcpiVer;
+ //-------------------------------------------
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == FACP_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Facp = (FACP_20*) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 1.1
+ else
+ xFacp = (FACP_20*) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find FACP for V 2+
+ }
+
+ if (gAcpiData.AcpiEntries[i]->BtHeaderPtr->Signature == DSDT_SIG)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer == EFI_ACPI_TABLE_VERSION_1_0B)
+ Aui->Dsdt1Addr = (UINT64) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 1.1
+ else
+ Aui->Dsdt2Addr = (UINT64) gAcpiData.AcpiEntries[i]->BtHeaderPtr; // Find DSDT for V 2+
+ }
+
+ if (AcpiTable->BtHeaderPtr->Signature == APIC_SIG )
+ {
+
+ switch (AcpiTable->AcpiTblVer)
+ {
+ case EFI_ACPI_TABLE_VERSION_1_0B: AcpiVer=1; break;
+ case EFI_ACPI_TABLE_VERSION_2_0: AcpiVer=2; break;
+ case EFI_ACPI_TABLE_VERSION_3_0: AcpiVer=3; break;
+ case EFI_ACPI_TABLE_VERSION_4_0: AcpiVer=4; break;
+ default: AcpiVer=0;
+ }
+
+ gAcpiData.AcpiLength -= AcpiTable->BtHeaderPtr->Length;
+
+ pBS->FreePool(AcpiTable->BtHeaderPtr);
+ AcpiTable->BtHeaderPtr=NULL;
+
+
+ Status = BuildMadtAll (AcpiVer, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return;
+
+ gAcpiData.AcpiLength += AcpiTable->BtHeaderPtr->Length;
+ }
+ }
+
+
+ ASSERT_EFI_ERROR(Status);
+ TRACE((-1,"IN Collect AML Info after PT: %x\n",Status));
+
+ Aui->SS1=DEFAULT_SS1;
+ Aui->SS2=DEFAULT_SS2;
+ Aui->SS3=DEFAULT_SS3;
+ Aui->SS4=DEFAULT_SS4;
+
+ Status = GetEfiVariable(L"Setup",&gSetupGuid,NULL,&i,&SetupData);
+
+ if (!EFI_ERROR(Status))
+ {
+ //Such Variable exists so use customer choices
+ if (!SetupData->AcpiAuto)
+ {
+ Aui->SS4=SetupData->AcpiHibernate;
+
+ switch (SetupData->AcpiSleepState)
+ {
+ case 0:
+ Aui->SS3=0;
+ Aui->SS1=0;
+ break;
+ case 1:
+ Aui->SS1=1;
+ Aui->SS3=0;
+ break;
+ case 2:
+ Aui->SS3=1;
+ Aui->SS1=0;
+ break;
+ case 3:
+ Aui->SS3=1;
+ Aui->SS1=1;
+ break;
+ }
+ }
+ }
+
+//TODO//TODO//TODO//TODO//TODO
+// Check Setup options (if any) to enable/disable some onboard devices
+//TODO//TODO//TODO//TODO//TODO
+
+ Status = pRS->GetVariable(SIO_DEV_STATUS_VAR_NAME, &SioDevStatusVarGuid, NULL,
+ &SioDevStatusVarSize, &Aui->SioDevStatusVar.DEV_STATUS);
+
+ if (EFI_ERROR(Status)) Aui->SioDevStatusVar.DEV_STATUS = 0;
+ gAcpiIaBootArch &= (~((UINT16)(IA_LEGACY | IA_8042)));// clear first 2 bits of gAcpiIaBootArch,
+ // while preserving others. This 2 bits will be updated later.
+
+ //Dynamically update IA_PC_BOOT_ARCHITECTURE flag based on SIO_DEV_STATUS_VAR
+ if (
+ (Aui->SioDevStatusVar.SerialA == 1 ) ||
+ (Aui->SioDevStatusVar.SerialB == 1 ) ||
+ (Aui->SioDevStatusVar.Lpt == 1 ) ||
+ (Aui->SioDevStatusVar.Fdd == 1 ) ||
+ (Aui->SioDevStatusVar.Game1 == 1 ) ||
+ (Aui->SioDevStatusVar.Game2 == 1 )
+ )
+ gAcpiIaBootArch |= IA_LEGACY;
+
+ if (
+ (Aui->SioDevStatusVar.Key60_64 == 1) ||
+ (Aui->SioDevStatusVar.Ps2Mouse == 1) ||
+ (Aui->SioDevStatusVar.Ec62_66 == 1)
+ )
+ gAcpiIaBootArch |= IA_8042;
+
+
+ if ( xFacp != NULL)
+ {
+ xFacp->IAPC_BOOT_ARCH &= gAcpiIaBootArch;
+ xFacp->Header.Checksum = 0;
+ xFacp->Header.Checksum = ChsumTbl((UINT8*)&xFacp->Header, xFacp->Header.Length);
+ }
+
+ if ((UINT8*) xFacp != (UINT8*) Facp)
+ {
+ //ACPI v1.0b don't have IAPC_BOOT_ARCH flag field!
+ //Legacy free extension has but.. 1.1b Legacy free extension has. REV==2 and higher
+ if (Facp->Header.Revision > ACPI_REV1)
+ {
+ Facp->IAPC_BOOT_ARCH &= gAcpiIaBootArch;
+ Facp->Header.Checksum = 0;
+ Facp->Header.Checksum = ChsumTbl((UINT8*)&Facp->Header, Facp->Header.Length);
+ }
+ }
+
+ Status=UpdateAml(Aui);
+ ASSERT_EFI_ERROR(Status);
+
+ if (SetupData->AcpiLockLegacyRes) LockLegacyRes (Aui); // LockLegacyDev
+
+ if (!gForceAcpi1) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (1, 0);
+ ASSERT_EFI_ERROR(Status);
+ gPublishedOnReadyToBoot = 1;
+// pBS->CloseEvent()
+// pBS->FreePool(Aui);
+}// end of CollectAmlUpdInfo
+
+
+//#pragma warning ( pop )
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// ACPI SUPPORT PPROTOCOL function Implementation
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiSupportGetAcpiTable
+//
+// Description:
+// This function returns ACPI table
+//
+// Input:
+// IN EFI_ACPI_SUPPORT_PROTOCOL *This - pointer to EFI_ACPI_SUPPORT_PROTOCOL instance
+// IN INTN Index - Index of ACPI table to return
+// OUT VOID **Table - Pointer where to place found table
+// OUT EFI_ACPI_TABLE_VERSION Version - requested ACPI table version
+// OUT UINTN *Handle - requested ACPI table handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to allocate table
+// EFI_INVALID_PARAMETER - invalid EFI_ACPI_SUPPORT_PROTOCOL pointer
+// EFI_NOT_FOUND - requested ACPI table not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiSupportGetAcpiTable (
+ IN EFI_ACPI_SUPPORT_PROTOCOL *This,
+ IN INTN Index,
+ OUT VOID **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *Handle )
+{
+ ACPI_HDR *HdrPtr;
+ VOID *Ptr;
+ UINTN i;
+
+//----------------------
+
+ if (This!=&gAcpiData.AcpiSupportProtocol) return EFI_INVALID_PARAMETER;
+
+ if (Index > ((INTN)gAcpiData.AcpiEntCount - 1)) return EFI_NOT_FOUND;
+
+ for (i = Index; i < (UINTN) gAcpiData.AcpiEntCount; i++)
+ {
+ if (gAcpiData.AcpiEntries[i]->AcpiTblVer < ACPI_TABLE_NOT_REMOVABLE)
+ {
+ // means this table was added by EFI_ACPI_TABLE_PROTOCOL.InstallAcpiTable
+ // So it is illegal for EFI_ACPI_SUPPORT_PROTOCOL to receive a Handle for it
+ HdrPtr = gAcpiData.AcpiEntries[i]->BtHeaderPtr;
+ Ptr = Malloc(HdrPtr->Length);
+ ASSERT(Ptr);
+
+ if (!Ptr) return EFI_OUT_OF_RESOURCES;
+
+ *Version = gAcpiData.AcpiEntries[i]->AcpiTblVer;
+ *Handle = (UINTN) HdrPtr;
+ pBS->CopyMem(Ptr, HdrPtr, HdrPtr->Length);
+ *Table = Ptr;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}//end of AcpiSupportGetAcpiTable
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiSupportSetAcpiTable
+//
+// Description:
+// This function allows to add, remove of modify ACPI table
+//
+// Input:
+// IN EFI_ACPI_SUPPORT_PROTOCOL *This - pointer to EFI_ACPI_SUPPORT_PROTOCOL instance
+// IN OPTIONAL VOID *Table - Pointer to update data. If NULL, corresponded table
+// should be removed
+// IN BOOLEAN Checksum - if TRUE, function will recalculate checksum before adding table
+// IN EFI_ACPI_TABLE_VERSION Version - requested ACPI table version
+// IN OUT UINTN *Handle - requested ACPI table handle
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+// EFI_INVALID_PARAMETER - invalid EFI_ACPI_SUPPORT_PROTOCOL pointer or ACPI table
+// content
+// EFI_ABORTED - provided ACPI table already present
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiSupportSetAcpiTable(
+ IN EFI_ACPI_SUPPORT_PROTOCOL *This,
+ IN VOID *Table OPTIONAL,
+ IN BOOLEAN Checksum,
+ IN EFI_ACPI_TABLE_VERSION Version,
+ IN OUT UINTN *Handle )
+{
+ ACPI_TBL_ITEM *AcpiTableAdded = NULL, *TblDummy = NULL;
+ ACPI_HDR *Hdr1 = NULL, *Hdr2 = NULL, *Dsdt = NULL, *XtDsdt = NULL;
+ VOID *Ptr = NULL;
+ EFI_ACPI_TABLE_VERSION XtDsdtVer = 0, DsdtVer = 0, MultyVer = 0;
+ EFI_STATUS Status = 0;
+ UINTN TblNum = ACPI_TABLE_NOT_FOUND;
+ BOOLEAN CorrectFacp = FALSE, WasChecksummed = FALSE;
+
+
+ //Handle == NULL Table != NULL add the table
+ //Handle != NULL Table != NULL replace the table
+ //Handle != NULL Table == NULL remove the table
+//-----------------------------------------------------------------------------------
+ if ((This != &gAcpiData.AcpiSupportProtocol) || (Handle==NULL) || (*Handle == 0 && Table == NULL )) //---------------------------------------------------------------
+ {
+ Status = EFI_INVALID_PARAMETER;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ TRACE((-1, "ACPI: SetAcpiTable() Table=0x%X; Handle=0x%X; *Handle=0x%X\n", Table, Handle, *Handle));
+ if (Table != NULL)
+ {
+ Hdr1 = (ACPI_HDR*) Table;
+
+ //Check is we are getting a "special" table that needs a specific care
+ if (Hdr1->Signature == FACS_SIG)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Hdr1->Signature == FACP_SIG)
+ {
+ if (*Handle == 0) // --- Do not delete or add FACP - only replace it
+ {
+ Status = GetBtTable(&TblDummy, FACP_SIG, ( EFI_ACPI_TABLE_VERSION_X ));
+ ASSERT_EFI_ERROR(Status); // --- Or if new version > 2 and old version of FACP = 2
+ // --- And action = add table - replace old one with the new one
+ if (EFI_ERROR (Status))
+ {
+ return EFI_ABORTED;
+ }
+
+ if (TblDummy->AcpiTblVer >= Version)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ else
+ {
+ *Handle = (UINTN)TblDummy->BtHeaderPtr;
+ CorrectFacp = TRUE;
+ }
+ }
+ }
+
+ if (Hdr1->Signature == DSDT_SIG)
+ {
+
+ //Just in case reset
+ TblDummy=NULL;
+
+ if (*Handle == 0) // --- Do not delete or add DSDT - only replace it
+ {
+ Status = GetBtTable(&TblDummy, DSDT_SIG, (EFI_ACPI_TABLE_VERSION_X));
+
+ // --- Or if new version > 2 and old version of FACP = 2
+ if (!EFI_ERROR (Status)) // --- And action = add table - replace old one with the new one
+ {
+ XtDsdt = TblDummy->BtHeaderPtr;
+ XtDsdtVer = TblDummy->AcpiTblVer;
+ }
+
+ Status = GetBtTable(&TblDummy, DSDT_SIG, EFI_ACPI_TABLE_VERSION_1_0B);
+
+ if (!EFI_ERROR (Status))
+ {
+ Dsdt = TblDummy->BtHeaderPtr;
+ DsdtVer = TblDummy->AcpiTblVer;
+ }
+
+ if ((Version == EFI_ACPI_TABLE_VERSION_1_0B) && DsdtVer)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ else
+ {
+ if ((Version > DsdtVer) && (Version > XtDsdtVer))
+ {
+ if (XtDsdtVer)
+ *Handle = (UINTN) XtDsdt;
+ }
+
+ else
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ }
+
+ CorrectFacp = TRUE;
+ }
+
+ if (Version == EFI_ACPI_TABLE_VERSION_NONE)
+ Status = pBS->AllocatePool(EfiACPIMemoryNVS, Hdr1->Length, &Ptr);
+ else
+ Ptr = Malloc(Hdr1->Length);
+
+ ASSERT(Ptr);
+
+ if (Ptr==NULL)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ pBS->CopyMem(Ptr, Hdr1, Hdr1->Length);
+ AcpiTableAdded = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTableAdded);
+
+ if (!AcpiTableAdded)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AcpiTableAdded->AcpiTblVer = Version;
+ AcpiTableAdded->BtHeaderPtr = (ACPI_HDR*) Ptr;
+ if (!Checksum)
+ if (!ChsumTbl((UINT8*)Ptr, ((ACPI_HDR*) Ptr)->Length))
+ WasChecksummed = TRUE;
+ //If table was checksumed and Checksum parameter of SetTable function was not set
+ //to TRUE in next string OemAcpiSetPlatformId may modify the table - let's
+ //remember was it checksumed or not
+
+ if (EFI_ERROR(OemAcpiSetPlatformId ((ACPI_HDR*) Ptr))) WasChecksummed = FALSE;
+ //If OemAcpiSetPlatformId did not modifies table - reset WasChecksummed to FALSE
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ Status = DispatchSdtNotify(AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status))
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+
+ if (Version != EFI_ACPI_TABLE_VERSION_NONE)
+ gAcpiData.AcpiLength += ((ACPI_HDR*) Ptr)->Length;
+
+ if (Checksum || WasChecksummed)
+ {
+ ((ACPI_HDR*) Ptr)->Checksum = 0;
+ ((ACPI_HDR*) Ptr)->Checksum = ChsumTbl((UINT8*)Ptr, ((ACPI_HDR*) Ptr)->Length);
+ }
+ }
+
+ if (*Handle)
+ {
+ Status=EFI_SUCCESS;
+
+ TRACE((-1, "ACPI: SetAcpiTable() Hnd!=0, Removing Tbl. Ver=0x%X, ",Version));
+
+ Hdr2 = (ACPI_HDR*)(*Handle);
+
+ //Check is we are getting a "special" table that needs a specific care
+ if (Hdr2->Signature == FACS_SIG)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Hdr2->Signature == FACP_SIG) && (!Table))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((Hdr2->Signature == DSDT_SIG) && (!Table))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ TblNum = FindAcpiTblByHandle (Handle);
+ TRACE((-1, "TblNum=0x%X ", TblNum));
+
+ if (TblNum == ACPI_TABLE_NOT_FOUND) Status=EFI_INVALID_PARAMETER;
+
+ TRACE((-1,"Status = %r\n", Status));
+
+ // Table with this Handle does not exist
+ if (EFI_ERROR(Status))
+ {
+ return Status;
+ }
+
+ //if sombody is trying to replace or delete table with version
+ //which is a combination of bits (for example V1 and 2 or V2 and 3, etc)
+ if ((Version != gAcpiData.AcpiEntries[TblNum]->AcpiTblVer) && (Version != ACPI_TABLE_NOT_REMOVABLE))
+ {
+ MultyVer = gAcpiData.AcpiEntries[TblNum]->AcpiTblVer;
+
+ if ((MultyVer == EFI_ACPI_TABLE_VERSION_1_0B) ||
+ (MultyVer == EFI_ACPI_TABLE_VERSION_2_0) ||
+ (MultyVer == EFI_ACPI_TABLE_VERSION_3_0) || (MultyVer == EFI_ACPI_TABLE_VERSION_4_0))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ else MultyVer ^= Version;
+ }
+
+ if (Version != EFI_ACPI_TABLE_VERSION_NONE)
+ gAcpiData.AcpiLength -= gAcpiData.AcpiEntries[TblNum]->BtHeaderPtr->Length;
+
+ Status = DeleteItemLst((T_ITEM_LIST*) &gAcpiData, TblNum, TRUE);
+ TRACE((-1,"ACPI: Deleting Table From Storage: Status = %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status))
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (MultyVer)
+ {
+ AcpiTableAdded = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTableAdded);
+
+ if (!AcpiTableAdded)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ AcpiTableAdded->AcpiTblVer = MultyVer;
+
+ AcpiTableAdded->BtHeaderPtr = Hdr2;
+ OemAcpiSetPlatformId(Hdr2);
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ Status = DispatchSdtNotify(AcpiTableAdded);
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ if (EFI_ERROR(Status))
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[TblNum]->BtHeaderPtr->Length;
+ }
+
+ else pBS->FreePool(Hdr2);
+ }
+
+ //Update Handle with New Table Instance.
+ *Handle=(UINTN)Ptr;
+
+ if (CorrectFacp)
+ {
+ Status = UpdateFacp ();
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status))
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ TRACE((-1,"ACPI: SetAcpiTable() Exiting... Status = %r\n", Status));
+
+ if (gPublishedOnReadyToBoot)
+ {
+ if (!gForceAcpi1) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (1, 0);
+ }
+ TRACE((-1,"ACPI: PublishTables in SetAcpiTable() Status = %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+//--- !!!!!!!!!!!!!!!!!!!!!!!!!! Version none Done ???? !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+}// end of AcpiSupportSetAcpiTable
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiSupportPublishTables
+//
+// Description: Causes one or more versions of the ACPI tables to be published in
+// the EFI system configuration tables.
+//
+// Input:
+// IN EFI_ACPI_SUPPORT_PROTOCOL *This - pointer to EFI_ACPI_SUPPORT_PROTOCOL instance
+// IN EFI_ACPI_TABLE_VERSION Version - ACPI table version
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ABORTED - invalid EFI_ACPI_SUPPORT_PROTOCOL pointer or
+// an error occurred and the function could not complete successfully.
+// EFI_UNSUPPORTED - passed ACPI table version invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiSupportPublishTables(
+ IN EFI_ACPI_SUPPORT_PROTOCOL *This,
+ IN EFI_ACPI_TABLE_VERSION Version )
+{
+ EFI_STATUS Status;
+
+ if ((Version < EFI_ACPI_TABLE_VERSION_1_0B) || (Version > EFI_ACPI_TABLE_VERSION_ALL) || (This!=&gAcpiData.AcpiSupportProtocol))
+ return EFI_UNSUPPORTED;
+ if (Version == EFI_ACPI_TABLE_VERSION_1_0B)
+ {
+ if ((gRsdtPtrStr != NULL) && (gRsdtPtrStr->XsdtAddr != 0)) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (1, 0);
+ }
+
+ if ((Version > EFI_ACPI_TABLE_VERSION_1_0B) && (!gForceAcpi1))
+ {
+ if ((gRsdtPtrStr != NULL) && (gRsdtPtrStr->RsdtAddr != 0)) Status = PublishTbl (1, 1);
+ else Status = PublishTbl (0, 1);
+ }
+ ASSERT_EFI_ERROR (Status);
+
+ if (EFI_ERROR (Status)) return EFI_ABORTED;
+ else return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiInstallAcpiTable
+//
+// Description: Installs an ACPI table into the RSDT/XSDT.
+//
+// Input:
+// IN EFI_ACPI_TABLE_PROTOCOL *This - A pointer to a EFI_ACPI_TABLE_PROTOCOL.
+// IN VOID *AcpiTableBuffer - A pointer to a buffer containing the ACPI table to be installed.
+// IN UINTN AcpiTableBufferSize - Specifies the size, in bytes, of the AcpiTableBuffer buffer.
+// OUT UINTN *TableKey - Returns a key to refer to the ACPI table.
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_INVALID_PARAMETER - Either AcpiTableBuffer is NULL, TableKey is NULL, or
+// AcpiTableBufferSize and the size field embedded in the ACPI
+// table pointed to by AcpiTableBuffer are not in sync
+// EFI_OUT_OF_RESOURCES - Insufficient resources exist to complete the request.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AcpiInstallAcpiTable(
+ IN CONST EFI_ACPI_TABLE_PROTOCOL *This,
+ IN CONST VOID *AcpiTableBuffer,
+ IN UINTN AcpiTableBufferSize,
+ OUT UINTN *TableKey)
+{
+ EFI_STATUS Status;
+ UINTN IntTableKey = 0;
+ // Update for LPT PCH Refcode. >>>
+ EFI_ACPI_TABLE_VERSION AcpiVersion = ACPI_TABLE_NOT_REMOVABLE;
+ UINTN TblNum = ACPI_TABLE_NOT_FOUND;
+ // <<< Update for LPT PCH Refcode.
+
+
+ if ((AcpiTableBuffer == NULL) || (AcpiTableBufferSize != (UINTN)((ACPI_HDR*)AcpiTableBuffer)->Length)
+ || (TableKey == NULL)) return EFI_INVALID_PARAMETER;
+ // Update for LPT PCH Refcode. >>>
+ if (*TableKey != 0)
+ {
+ TblNum = FindAcpiTblByHandle(TableKey);
+ if (TblNum != ACPI_TABLE_NOT_FOUND)
+ {
+ AcpiVersion = gAcpiData.AcpiEntries[TblNum]->AcpiTblVer;
+ IntTableKey = *TableKey;
+ }
+ }
+
+ Status = AcpiSupportSetAcpiTable(&gAcpiData.AcpiSupportProtocol,
+ (VOID*)AcpiTableBuffer,
+ TRUE,
+ // This is the mark, that means, that this table was added by the new protocol
+ AcpiVersion,
+ &IntTableKey);
+ ASSERT_EFI_ERROR(Status);
+ // <<< Update for LPT PCH Refcode.
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ *TableKey = IntTableKey;
+
+ if (!gForceAcpi1) Status = PublishTbl (1, 1);
+ else PublishTbl (1, 0);
+ return Status;
+}// end of AcpiInstallAcpiTable
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiUninstallAcpiTable
+//
+// Description: Function allows a caller to remove an ACPI table.
+//
+// Input:
+// IN EFI_ACPI_TABLE_PROTOCOL *This - A pointer to a EFI_ACPI_TABLE_PROTOCOL.
+// IN UINTN *TableKey - Specifies the table to uninstall. The key was returned from
+// InstallAcpiTable().
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_NOT_FOUND - TableKey does not refer to a valid key for a table entry.
+// EFI_OUT_OF_RESOURCES - Insufficient resources exist to complete the request.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiUninstallAcpiTable(
+ IN CONST EFI_ACPI_TABLE_PROTOCOL *This,
+ IN UINTN TableKey)
+{
+ EFI_STATUS Status;
+
+ Status = AcpiSupportSetAcpiTable(&gAcpiData.AcpiSupportProtocol,
+ NULL,
+ FALSE,
+ // This is the mark, that means, that this table was added by the new protocol
+ ACPI_TABLE_NOT_REMOVABLE,
+ &TableKey);
+ if (EFI_ERROR(Status))
+ return (EFI_NOT_FOUND);
+ else
+ return Status;
+}//end of AcpiUninstallAcpiTable
+
+
+//
+// ACPI SDT Protocol functions implementation.
+//
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAcpiTable2
+//
+// Description:
+// Returns a requested ACPI table.
+// The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
+// with the Index that was input. The following structures are not considered elements in the list of
+// ACPI tables:
+// - Root System Description Pointer (RSD_PTR)
+// - Root System Description Table (RSDT)
+// - Extended System Description Table (XSDT)
+// Version is updated with a bit map containing all the versions of ACPI of which the table is a
+// member.
+//
+// Input:
+// Index The zero-based index of the table to retrieve.
+// Table Pointer for returning the table buffer.
+// Version On return, updated with the ACPI versions to which this table belongs. Type
+// EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
+// EFI_ACPI_SDT_PROTOCOL.
+// TableKey On return, points to the table key for the specified ACPI system definition table. This
+// is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
+// Output:
+// EFI_SUCCESS The function completed successfully.
+// EFI_NOT_FOUND The requested index is too large and a table was not found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetAcpiTable2 (
+ IN UINTN Index,
+ OUT EFI_ACPI_SDT_HEADER **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *TableKey)
+{
+
+ return AcpiSupportGetAcpiTable (&gAcpiData.AcpiSupportProtocol, Index,
+ Table, Version,TableKey);
+
+}
+
+EFI_STATUS RegisterNotify(
+ IN BOOLEAN Register,
+ IN EFI_ACPI_NOTIFICATION_FN Notification)
+{
+ if(Notification == NULL) return EFI_INVALID_PARAMETER;
+
+ if(Register){
+ return AppendItemLst((T_ITEM_LIST*)&gAcpiData.NotifyInitCount, Notification);
+ } else {
+ UINTN i;
+ //-----------------
+ for(i=0; i<gAcpiData.NotifyFnCount; i++){
+ if(gAcpiData.AcpiNotifyFn[i]==Notification){
+ return DeleteItemLst((T_ITEM_LIST*)&gAcpiData.NotifyInitCount,i,FALSE);
+ }
+ }
+ //can't found matching notify function.
+ return EFI_INVALID_PARAMETER;
+ }
+}
+#endif
+
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// Driver entry point
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiNewCoreEntry
+//
+// Description:
+// This function is ACPI driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, ACPI_SUPPORT_PROTOCOL installed
+// EFI_ABORTED - Dsdt table not found or table publishing failed
+// EFI_ALREADY_STARTED - driver already started
+// EFI_OUT_OF_RESOURCES - not enough memory to perform operation
+//
+// Notes:
+// This function also creates ReadyToBoot event to update AML objects before booting
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiNewCoreEntry (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ ACPI_HDR *Dsdt1Ptr = NULL, *Dsdt2Ptr = NULL;
+ VOID *DummyPtr;
+ static EFI_GUID Acpisupguid = EFI_ACPI_SUPPORT_GUID;
+ static EFI_GUID AcpiTableProtocolGuid = EFI_ACPI_TABLE_PROTOCOL_GUID;
+ UINTN AcpiVer;
+ EFI_ACPI_TABLE_VERSION EfiAcpiVer;
+ ACPI_TBL_ITEM *AcpiTable = NULL;
+#if FORCE_TO_ACPI1_SETUP_ENABLE
+ SETUP_DATA *SetupData = NULL;
+ UINTN SetupSize = 0;
+#endif
+//------------------------
+ InitAmiLib(ImageHandle,SystemTable);
+ PROGRESS_CODE(DXE_ACPI_INIT);
+ TRACE((-1,"IN ACPI Start: %x\n", Status));
+ //it must be ony one instance of this protocol
+ Status = pBS->LocateProtocol(&Acpisupguid,NULL,&DummyPtr);
+
+ if (!EFI_ERROR(Status)) return EFI_ALREADY_STARTED;
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ //Use AMI_CPU_INFO_2_PROTOCOL if published.
+ Status = pBS->LocateProtocol(&gAmiCpuInfo2ProtocolGuid, NULL, &gAmiCpu2Info);
+
+ if (EFI_ERROR(Status)) gAmiCpu2Info = NULL;
+
+#endif
+
+
+ Status = pBS->LocateProtocol(&gAmiBoardInfoGuid, NULL,(VOID**)&gAmiBoardInfoProtocol);
+
+ if (EFI_ERROR(Status))
+ {
+ gAmiBoardInfoProtocol = NULL;
+ TRACE((-1, "ACPI: Can't find AMI Board Info Protocol %r EXITING!",Status));
+ return Status;
+ }
+
+
+
+ AcpiVer = 2;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_2_0;
+
+ if (ACPI_BUILD_TABLES_3_0 == 1)
+ {
+ AcpiVer = 3;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_3_0;
+ }
+
+ if (ACPI_BUILD_TABLES_4_0 == 1)
+ {
+ AcpiVer = 4;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_4_0;
+ }
+#if ATAD_SUPPORT == 1
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, 4, &AtadBuffPtr);
+ if (!EFI_ERROR(Status) && AtadBuffPtr)
+ {
+ EFI_GUID AtadSmiGuid = ATAD_SMI_GUID;
+ UINTN AtadVarSize = sizeof(AtadBuffPtr);
+ Status = pRS->SetVariable ( L"AtadSmiBuffer",
+ &AtadSmiGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ AtadVarSize,
+ &AtadBuffPtr );
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#endif
+
+#if FORCE_TO_ACPI1_SETUP_ENABLE
+ Status = GetEfiVariable(L"Setup",&gSetupGuid,NULL,&SetupSize,&SetupData);
+ ASSERT_EFI_ERROR(Status);
+ if (!EFI_ERROR (Status))
+ if (SetupData->ForceToAcpi1 ==1)
+ {
+ AcpiVer = gForceAcpi1 = 1;
+ EfiAcpiVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ }
+#endif
+ Status = BuildFacs ();
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ Status = BuildFacpiAll (1, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ if (!gForceAcpi1)
+ {
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ Status = BuildFacpiAll (AcpiVer, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR (Status)) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+ TRACE((-1,"IN ACPI 1: %x\n", Status));
+
+ Status = GetDsdtFv(&Dsdt1Ptr, &Dsdt2Ptr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_ABORTED;
+
+ if ((Dsdt2Ptr != NULL) && (Dsdt1Ptr != NULL))
+ {
+ TRACE((-1,"DSDT1 addres 0x%X; -> %r \n", Dsdt1Ptr, Status));
+ TRACE((-1,"DSDT2 addres 0x%X; -> %r \n", Dsdt2Ptr, Status));
+
+ Dsdt1Ptr->Checksum = 0;
+ Dsdt2Ptr->Checksum = 0;
+ Dsdt1Ptr->Checksum = ChsumTbl((UINT8*)Dsdt1Ptr, Dsdt1Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt1Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+
+ Dsdt2Ptr->Checksum = ChsumTbl((UINT8*)Dsdt2Ptr, Dsdt2Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt2Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_2_0;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+
+ if (Dsdt1Ptr == NULL)
+ {
+ TRACE((-1,"DSDT21 addres 0x%lX; -> %r \n", Dsdt2Ptr, Status));
+ Dsdt2Ptr->Checksum = 0;
+ Dsdt2Ptr->Checksum = ChsumTbl((UINT8*)Dsdt2Ptr, Dsdt2Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt2Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_2_0;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+
+ if (Dsdt2Ptr == NULL)
+ {
+ TRACE((-1,"DSDT11 addres 0x%lX; -> %r \n", Dsdt1Ptr, Status));
+ Dsdt1Ptr->Checksum = 0;
+ Dsdt1Ptr->Checksum = ChsumTbl((UINT8*)Dsdt1Ptr, Dsdt1Ptr->Length);
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ AcpiTable->BtHeaderPtr = Dsdt1Ptr;
+ AcpiTable->AcpiTblVer = EFI_ACPI_TABLE_VERSION_1_0B;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+
+ Status = UpdateFacp ();
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_ABORTED;
+
+#if ACPI_APIC_TBL == 1
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (!AcpiTable) return EFI_OUT_OF_RESOURCES;
+
+ Status = BuildMadtAll (AcpiVer, &AcpiTable->BtHeaderPtr);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_ABORTED;
+
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+#endif
+
+#if MPS_TABLE_SUPPORT == 1
+ Status = MpsTableBuilderInit(ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR(Status);
+#endif
+//------ Performance Measurment ------------------------------------
+
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (AcpiTable)
+ {
+ Status = BuildFPDT (AcpiVer, &AcpiTable->BtHeaderPtr);
+
+ if (!EFI_ERROR(Status))
+ {
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+ }
+//------ Performance Measurment End --------------------------------
+
+//------ FID Table Start -------------------------------------------
+ AcpiTable = MallocZ (sizeof (ACPI_TBL_ITEM));
+ ASSERT(AcpiTable);
+
+ if (AcpiTable)
+ {
+ Status = BuildFIDT (&AcpiTable->BtHeaderPtr);
+
+ if (!EFI_ERROR(Status))
+ {
+ AcpiTable->AcpiTblVer = EfiAcpiVer;
+ Status = AppendItemLst ((T_ITEM_LIST*)&gAcpiData, (VOID*) AcpiTable);
+ ASSERT_EFI_ERROR(Status);
+ gAcpiData.AcpiLength += gAcpiData.AcpiEntries[gAcpiData.AcpiEntCount-1]->BtHeaderPtr->Length;
+ }
+ }
+
+//------ FID Table End --------------------------------------------
+
+ gAuiGlob = MallocZ(sizeof(ACPI_AML_UPD_INFO));
+ ASSERT(gAuiGlob);
+
+
+
+ //free temporary space used during this routine execution ??????
+
+ // ???? Publish all tbls 1,1 ??????
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK, CollectAmlUpdInfo, gAuiGlob, &gEvtReadyToBoot
+ );
+ ASSERT_EFI_ERROR(Status);
+
+
+
+ if (EFI_ERROR(Status))return EFI_ABORTED;
+
+
+ gAcpiData.AcpiSupportProtocol.GetAcpiTable = AcpiSupportGetAcpiTable;
+ gAcpiData.AcpiSupportProtocol.SetAcpiTable = AcpiSupportSetAcpiTable;
+ gAcpiData.AcpiSupportProtocol.PublishTables = AcpiSupportPublishTables;
+
+ gAcpiData.AcpiTableProtocol.InstallAcpiTable = AcpiInstallAcpiTable;
+ gAcpiData.AcpiTableProtocol.UninstallAcpiTable = AcpiUninstallAcpiTable;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ gAcpiData.AcpiSdtProtocol.GetAcpiTable=GetAcpiTable2;
+ gAcpiData.AcpiSdtProtocol.RegisterNotify=RegisterNotify;
+ gAcpiData.AcpiSdtProtocol.Open=Open;
+ gAcpiData.AcpiSdtProtocol.OpenSdt=OpenSdt;
+ gAcpiData.AcpiSdtProtocol.Close=Close;
+ gAcpiData.AcpiSdtProtocol.GetChild=GetChild;
+ gAcpiData.AcpiSdtProtocol.GetOption=GetOption;
+ gAcpiData.AcpiSdtProtocol.SetOption=SetOption;
+ gAcpiData.AcpiSdtProtocol.FindPath=FindPath;
+ gAcpiData.AcpiSdtProtocol.AcpiVersion=EFI_ACPI_TABLE_VERSION_ALL;
+#endif
+
+ gAcpiData.AcpiSupportHandle = NULL;
+ //Instasll ProtocolInterface;
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &gAcpiData.AcpiSupportHandle,
+ &Acpisupguid,
+ &gAcpiData.AcpiSupportProtocol,
+ &AcpiTableProtocolGuid,
+ &gAcpiData.AcpiTableProtocol,
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ &gEfiAcpiSdtProtocolGuid,
+ &gAcpiData.AcpiSdtProtocol,
+#endif
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ //TRACE((-1,"Before PublishTbl: %x\n", Status));
+ //Status = PublishTbl (1, 1);
+ //TRACE((-1,"After PublishTbl: %x\n", Status));
+ return Status;
+
+//return EFI_SUCCESS;
+}
+
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AcpiCore.h b/Core/EM/ACPI/AcpiCore.h
new file mode 100644
index 0000000..598b8bf
--- /dev/null
+++ b/Core/EM/ACPI/AcpiCore.h
@@ -0,0 +1,573 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/ACPICORE.H 25 10/28/13 12:06p Oleksiyy $
+//
+// $Revision: 25 $
+//
+// $Date: 10/28/13 12:06p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/ACPICORE.H $
+//
+// 25 10/28/13 12:06p Oleksiyy
+// [TAG] EIP121819
+// [Category] Improvement
+// [Description] Add $FID ACPI table.
+// [Files] AcpiCore.c, AcpiCore.h
+//
+// 24 12/03/12 11:50a Oleksiyy
+// [TAG] EIP107890
+// [Category] Improvement
+// [Description] Create a token that it define the Bot and Top of Io
+// APIC address.
+// [Files] AcpiCore.h and mptable.h
+//
+// 23 5/27/11 5:34p Felixp
+// AcpiSdt.h is renamed to AcpiSystemDescriptionTable.h.
+//
+// 22 5/14/11 2:48p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+// 21 8/11/09 12:46p Markw
+// EIP# 24914 -- Add Local x2APIC support.
+//
+// 20 5/26/09 1:43p Yakovlevs
+//
+// 19 5/14/09 5:38p Yakovlevs
+// Commented out Duplicated EFI_ACPI_TABLE_VERSION definition
+//
+// 18 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 2/18/09 3:51p Oleksiyy
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiCore.h
+//
+// Description: ACPI Core Header File. Main ACPI Driver Specific Definitions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __AcpiCore__H__
+#define __AcpiCore__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Protocol\FirmwareVolume.h >
+#include <Protocol\AmiSio.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\AcpiSupport.h>
+#include <AmiDxeLib.h>
+#include <AMIHobs.h>
+#include <token.h>
+#include <Dxe.h>
+#include <AcpiRes.h>
+#include "OEM_ACPI.h"
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+#include <Protocol\AcpiSystemDescriptionTable.h>
+#include "AcpiSdtPrivate.h"
+#endif
+#include <Setup.h>
+#include <acpi11.h>
+#include <acpi20.h>
+#include <Efi.h>
+#include <Acpi.h>
+#include <GenericSio.h>
+#pragma pack(push, 1)
+
+//**********************************************************************
+// Protocol Data Definitions
+//**********************************************************************
+// ACPI Version bitmap definition:
+//
+// EFI_ACPI_TABLE_VERSION_1_0B - ACPI Version 1.0b (not supported curently)
+// EFI_ACPI_TABLE_VERSION_2_0 - ACPI Version 2.0
+// EFI_ACPI_TABLE_VERSION_NONE - No ACPI Versions. This might be used
+// to create memory-based operation regions or other information
+// that is not part of the ACPI "tree" but must still be found
+// in ACPI memory space and/or managed by the core ACPI driver.
+//
+//**********************************************************************
+/*
+#define EFI_ACPI_TABLE_VERSION UINT32
+
+#define EFI_ACPI_TABLE_VERSION_NONE 0x00000001
+#define EFI_ACPI_TABLE_VERSION_1_0B 0x00000002
+#define EFI_ACPI_TABLE_VERSION_2_0 0x00000004
+#define EFI_ACPI_TABLE_VERSION_3_0 0x00000008
+#define EFI_ACPI_TABLE_VERSION_X (EFI_ACPI_TABLE_VERSION_2_0 | EFI_ACPI_TABLE_VERSION_3_0)
+#define EFI_ACPI_TABLE_VERSION_ALL (EFI_ACPI_TABLE_VERSION_1_0B|EFI_ACPI_TABLE_VERSION_X)
+*/
+//==================================================================//
+//GUID for DSDT storage type FFS_FILEGUID = 11D8AC35-FB8A-44d1-8D09-0B5606D321B9
+#define EFI_ACPI_DSDT_V_1_1_GUID {0x9410046e,0x1d26,0x45bc,0xb6,0x58,0xde,0xca,0xb1,0x4d,0x75,0x65}
+
+#define EFI_ACPI_DSDT_V_2_0_GUID {0x11D8AC35,0xFB8A,0x44d1,0x8D,0x09,0x0B,0x56,0x06,0xD3,0x21,0xB9}
+//ACPI tables GUIDs must be published in System Configuration table
+#define EFI_ACPI_11_TABLE_GUID {0xeb9d2d30,0x2d88,0x11d3,0x9a,0x16,0x00,0x90,0x27,0x3f,0xc1,0x4d}
+#define EFI_ACPI_20_TABLE_GUID {0x8868e871,0xe4f1,0x11d3,0xbc,0x22,0x00,0x80,0xc7,0x3c,0x88,0x81}
+
+#define ACPI_REV1 0x01
+#define ACPI_REV2 0x02
+#define ACPI_REV3 0x03
+#define ACPI_REV4 0x04
+
+#define ACPI_TABLE_NOT_FOUND (~0)
+#define ACPI_TABLE_NOT_REMOVABLE (~1)
+//======================================================
+// Here Follows Definitions that are not Chipset specific
+//======================================================
+
+#define CREATOR_ID_MS 0x5446534D //"TFSM""MSFT"(Microsoft)
+
+#define CREATOR_REV_MS 0x00010013
+
+#define CREATOR_ID_AMI 0x20494D41 //" IMA""AMI "(AMI)
+
+#define CREATOR_REV 0x00000000
+
+
+#define APIC_SIG 0x43495041 //"APIC"Multiple APIC Description Table
+
+#define SPIC_SIG 0x43495053 //"SPIC"Multiple SAPIC Description Table
+
+#define BOOT_SIG 0x544F4F42 //"BOOT"MS Simple Boot Spec
+
+#define DBGP_SIG 0x50474244 //"DBGP" MS Bebug Port Spec
+
+#define DSDT_SIG 0x54445344 //"DSDT" Differentiated System Description Table
+
+#define ECDT_SIG 0x54444345 //"ECDT" Embedded Controller Boot Resources Table
+
+#define ETDT_SIG 0x54445445 //"ETDT" Event Timer Description Table
+
+#define FACP_SIG 0x50434146 //"FACP" Fixed ACPI Description Table (FADT)
+
+#define FACS_SIG 0x53434146 //"FACS" //Firmware ACPI Control Structure
+
+#define PSDT_SIG 0x54445350 //"PSDT"Persistent System Description Table
+
+#define RSDT_SIG 0x54445352 //"RSDT"Root System Description Table
+
+#define SBST_SIG 0x54534253 //"SBST"Smart Battery Specification Table
+
+#define SLIT_SIG 0x54494C53 //"SLIT"System Locality Information Table
+
+#define SPCR_SIG 0x52435053 //"SPCR"Serial Port Concole Redirection Table
+
+#define SRAT_SIG 0x54415253 //"SBST"Static Resource Affinity Table
+
+#define SSDT_SIG 0x54445353 //"SSDT"Secondary System Description Table
+
+#define SPMI_SIG 0x494D5053 //"SPMI"Server Platform Management Interface Table
+
+#define XSDT_SIG 0x54445358 //"XSDT" eXtended System Description Table
+
+#define RSDP_SIG 0x2052545020445352 //"RSD PTR "
+
+//======================================================
+// ACPI Description Headers Signatures
+//======================================================
+#define MCFG_SIG 0x4746434D //PCI Express Congiguration Table
+
+#define HPET_SIG 0x54455048
+
+//for testing purposes only
+#define IPPT_SIG 0x54505049 // "IPPT" -- IA64 Platform Properties Table
+
+#define FIDT_SIG 0x54444946 //"FIDT" $FID Table
+
+#define THREE_CHAR_ARRAY(x) {(x)/10+'0',(x)%10+'0',0}
+
+//======================================================
+// Bits Description in APICXX.Type field. ACPI 2.0
+//======================================================
+#ifndef AT_LAPIC_H
+#define AT_LAPIC_H 0
+#endif
+
+#ifndef AT_IOAPIC
+#define AT_IOAPIC 1
+#endif
+
+#ifndef AT_ISO
+#define AT_ISO 2
+#endif
+
+#ifndef AT_NMI
+#define AT_NMI 3
+#endif
+
+#ifndef AT_LAPIC_H_NMI
+#define AT_LAPIC_H_NMI 4
+#endif
+
+#ifndef AT_LAPIC_H_ADR
+#define AT_LAPIC_H_ADR 5
+#endif
+
+#ifndef AT_IOSAPIC
+#define AT_IOSAPIC 6
+#endif
+//Updated according ACPI Spec 2.0 errata 1.3
+#ifndef AT_LSAPIC
+#define AT_LSAPIC 7
+#endif
+
+#ifndef AT_PIS
+#define AT_PIS 8
+#endif
+
+#ifndef AT_LX2APIC
+#define AT_LX2APIC 9
+#endif
+
+#ifndef AT_LX2APIC_NMI
+#define AT_LX2APIC_NMI 0xa
+#endif
+
+#define IOA_BASE_BOT APCB
+
+#if defined(IO_APIC_BASE_TOP_ADDRESS)
+#define IOA_BASE_TOP IO_APIC_BASE_TOP_ADDRESS
+#else
+#define IOA_BASE_TOP 0xFED00000
+#endif
+
+#define IOA_IND_REG_OFFS 0x00
+#define IOA_DAT_REG_OFFS 0x10
+#define IOA_ID_IND 0x00
+#define IOA_VER_IND 0x01
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_AML_RES
+//
+// Description: Structure to store System resource Information
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Base UINT64
+// Length UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _ACPI_AML_RES {
+ UINT64 Base;
+ UINT64 Length;
+} ACPI_AML_RES;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_AML_UPD_INFO
+//
+// Description: Structure to store Aml update information
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Dsdt1Addr UINT64
+// Dsdt2Addr UINT64
+// PciGap ACPI_AML_RES[3]
+// SS1 BOOLEAN
+// SS2 BOOLEAN
+// SS3 BOOLEAN
+// SS4 BOOLEAN
+// RomStart UINT32
+// TopOfMemory UINT32
+// SioDevStatusVar SIO_DEV_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct _ACPI_AML_UPD_INFO {
+ UINT64 Dsdt1Addr;
+ UINT64 Dsdt2Addr;
+ ACPI_AML_RES PciGap[3];
+ BOOLEAN SS1;
+ BOOLEAN SS2;
+ BOOLEAN SS3;
+ BOOLEAN SS4;
+ UINT32 RomStart;
+ UINT32 TopOfMemory;
+ SIO_DEV_STATUS SioDevStatusVar;
+} ACPI_AML_UPD_INFO;
+
+EFI_STATUS LocateACPITableProtocol (IN EFI_GUID *Protocol, OUT VOID **Instance, IN UINT8 Version);
+
+typedef enum {
+ pgBelow1M,
+ pgBelow4G,
+ pgAbove4G,
+ pgMaxResType,
+} AML_RES_TYPE;
+
+//======================================================
+// Bits Description in LAPIC_XX.Flags field. ACPI 2.0
+//======================================================
+#define FL_ENABLE 0x0001
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MADT_ENTRY_HEADER
+//
+// Description: Header of the entrie for MADT table.
+//
+//
+// Fields: Type Name Description
+//----------------------------------------------------------------------------
+// UINT8 Type
+// UINT8 Length
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct _MADT_ENTRY_HEADER{
+ UINT8 Type;
+ UINT8 Length;
+}MADT_ENTRY_HEADER;
+
+//======================================================
+// LAPIC Structure per each CPU IA32
+//======================================================
+typedef struct _LAPIC_H32 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 CpuId;
+ UINT8 LapicId;
+ UINT32 Flags;
+} LAPIC_H32,*PLAPIC_H32, LAPIC_H_20,*PLAPIC_H_20;
+
+//======================================================
+// LX2APIC Structure per each CPU IA32
+//======================================================
+typedef struct _LX2APIC {
+ MADT_ENTRY_HEADER Header;
+ UINT16 Reserved;
+ UINT32 ApicId;
+ UINT32 Flags;
+ UINT32 Uid;
+} LX2APIC,*PLX2APIC;
+
+//======================================================
+// IOAPIC Structure per each CPU IA32
+//======================================================
+typedef struct _IOAPIC_H32 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 IoapicId; //2
+ UINT8 Reserved; //3
+ UINT32 IoapicAddress; //4
+ UINT32 SysVectBase; //8
+} IOAPIC_H32,*PIOAPIC_H32, IOAPIC_H20,*PIOAPIC_H20;
+
+//======================================================
+// ISO Interrupt Source Override Structure IA32
+//======================================================
+// Should be present per each ISA Interrupt which
+// is not identity-mapped into SAPIC Interrupt space
+//======================================================
+typedef struct _ISO_H32 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 Bus; //2
+ UINT8 Source; //3
+ UINT32 GlobalSysVect; //4
+ UINT16 Flags; //8
+
+} ISO_H20,*PISO_H20;
+
+typedef struct _LSAPIC_H20 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 CpuId; //2
+ UINT8 LsapicId; //3
+ UINT8 LsapicEid; //4
+ UINT8 Reserved1; //5
+ UINT8 Reserved2; //6
+ UINT8 Reserved3; //7
+ UINT32 Flags; //8 Same as MPS 1.4
+} LSAPIC_H20,*PLSAPIC_H20;
+
+typedef struct _LSAPIC_H30 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 CpuId; //2
+ UINT8 LsapicId; //3
+ UINT8 LsapicEid; //4
+ UINT8 Reserved1; //5
+ UINT8 Reserved2; //6
+ UINT8 Reserved3; //7
+ UINT32 Flags; //8 Same as MPS 1.4
+ UINT32 AcpiProcUidVal; //12
+ UINT8 AcpiProcUidString; //16 This value could be bigger than 1 byte
+ //------ To Do - Deal with variable length of AcpiProcUidString
+} LSAPIC_H30,*PLSAPIC_H30;
+
+typedef struct _IOSAPIC_H20 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 IoapicId; //2
+ UINT8 Reserved; //3
+ UINT32 SysVectBase; //8
+ UINT64 IosapicAddress; //4
+} IOSAPIC_H20,*PIOSAPIC_H20;
+
+typedef struct _ISO_PARAMETER_TABLE{
+ UINT8 PicIrq;
+ UINT8 Flags;
+ UINT16 ApicInt;
+}ISO_PARAMETER_TABLE;
+
+
+typedef struct _NMI_H20 {
+ MADT_ENTRY_HEADER Header;
+ UINT16 Flags; //2 same as MPS INTI flags 1.4
+ UINT32 GlobalSysVect; //4
+} NMI_H20,*PNMI_H20;
+
+typedef struct _LNMI_H20 {
+ MADT_ENTRY_HEADER Header;
+ UINT8 CPU_ID; //2
+ UINT16 Flags; //3 same as MPS INTI flags 1.4
+ UINT8 LapicIntin; //5
+} LNMI_H20,*PLNMI_H20;
+
+typedef struct _LX2APIC_NMI {
+ MADT_ENTRY_HEADER Header;
+ UINT16 Flags; //same as MPS INTI flags 1.4
+ UINT32 Uid;
+ UINT8 LapicIntin;
+ UINT8 Reserved[3];
+} LX2APIC_NMI,*PLX2APIC_NMI;
+
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MADT_ENTRIES
+//
+// Description: Structure for storing collected entries for MADT table before
+// actualy building it. It is in the form of T_ITEM_LIST.
+//
+// Fields: Type Name Description
+//----------------------------------------------------------------------------
+// UINTN MadtEntInitCount
+// UINTN MadtEntCount
+// MADT_ENTRY_HEADER **MadtEntries
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct _MADT_ENTRIES {
+ UINTN MadtEntInitCount;
+ UINTN MadtEntCount;
+ MADT_ENTRY_HEADER **MadtEntries;
+
+} MADT_ENTRIES;
+
+//======================================================
+// Bits Description in FACS.GlobalLock field. ACPI 2.0
+//======================================================
+#define GL_PENDING 0x01
+#define GL_OWNED 0x20
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_TBL_ITEM
+//
+// Description: Structure for storing pointers for ACPI tables and it's Version
+// Member of ACPI_DB
+//
+// Fields: Type Name Description
+//----------------------------------------------------------------------------
+// ACPI_HDR *BtHeaderPtr
+// EFI_ACPI_TABLE_VERSION AcpiTblVer
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct _ACPI_TBL_ITEM {
+ ACPI_HDR *BtHeaderPtr;
+ EFI_ACPI_TABLE_VERSION AcpiTblVer;
+
+} ACPI_TBL_ITEM;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_DB
+//
+// Description: Structure for storing ACPI tables and protocols during Boottime.
+// ACPI tables are stored in the form of T_ITEM_LIST.
+//
+// Fields: Type Name Description
+//----------------------------------------------------------------------------
+// UINTN AcpiInitCount
+// UINTN AcpiEntCount
+// ACPI_TBL_ITEM **AcpiEntries
+// UINT32 AcpiLength
+// EFI_ACPI_TABLE_PROTOCOL AcpiTableProtocol
+// EFI_ACPI_SUPPORT_PROTOCOL AcpiSupportProtocol
+// EFI_HANDLE AcpiSupportHandle
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct _ACPI_DB {
+ UINTN AcpiInitCount;
+ UINTN AcpiEntCount;
+ ACPI_TBL_ITEM **AcpiEntries;
+ UINT32 AcpiLength;
+ EFI_ACPI_TABLE_PROTOCOL AcpiTableProtocol;
+ EFI_ACPI_SUPPORT_PROTOCOL AcpiSupportProtocol;
+ EFI_HANDLE AcpiSupportHandle;
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ EFI_ACPI_SDT_PROTOCOL AcpiSdtProtocol;
+ UINTN NotifyInitCount;
+ UINTN NotifyFnCount;
+ EFI_ACPI_NOTIFICATION_FN *AcpiNotifyFn;
+
+// UINTN SdtHndInitCount;
+// UINTN SdtHandleCount;
+// EFI_ACPI_NOTIFICATION_FN *AcpiNotifyFn;
+ EFI_AML_NODE_LIST *AmlRootNode;
+#endif
+} ACPI_DB;
+
+//Function Prototypes
+UINTN FindAcpiTblByHandle (UINTN *Handle);
+
+
+
+#pragma pack(pop)
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AcpiS3.h b/Core/EM/ACPI/AcpiS3.h
new file mode 100644
index 0000000..8fcbe7c
--- /dev/null
+++ b/Core/EM/ACPI/AcpiS3.h
@@ -0,0 +1,170 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AcpiS3.h 6 3/26/09 4:51p Oleksiyy $
+//
+// $Revision: 6 $
+//
+// $Date: 3/26/09 4:51p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AcpiS3.h $
+//
+// 6 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 5 4/15/08 9:15p Yakovlevs
+// Functions Headers added
+//
+// 4 4/09/08 5:14p Yakovlevs
+// Make S3 Save code remember all possible locations of FACS.
+//
+// 3 11/20/06 4:14a Yakovlevs
+// updated structure of ACPI_CPU_DATA to match with declared in MRC code
+//
+// 2 9/22/06 6:10p Markw
+// 64-bit fix.
+//
+// 1 5/04/05 12:24p Markw
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AcpiS3.h
+//
+// Description: ACPI S3 data structures definitions
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __ACPI_S3_H__
+#define __ACPI_S3_H__
+
+#include <Efi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define ACPI_GLOBAL_VARIABLE L"AcpiGlobalVariable"
+#define EFI_ACPI_VARIABLE_GUID \
+ {0xaf9ffd67,0xec10,0x488a,0x9d,0xfc,0x6c,0xbf,0x5e,0xe2,0x2c,0x2e}
+
+#pragma pack (1)
+typedef struct {
+ UINT16 Limit;
+ UINT32 Base;
+} PSEUDO_DESCRIPTOR;
+#pragma pack()
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_CPU_DATA
+//
+// Description: ACPI Cpu related data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// APState BOOLEAN
+// S3BootPath BOOLEAN
+// WakeUpBuffer EFI_PHYSICAL_ADDRESS
+// GdtrProfile EFI_PHYSICAL_ADDRESS
+// IdtrProfile EFI_PHYSICAL_ADDRESS
+// CpuPrivateData EFI_PHYSICAL_ADDRESS
+// StackAddress EFI_PHYSICAL_ADDRESS
+// MicrocodePointerBuffer EFI_PHYSICAL_ADDRESS
+// SmramBase EFI_PHYSICAL_ADDRESS
+// SmmStartImageBase EFI_PHYSICAL_ADDRESS
+// SmmStartImageSize UINT32
+// NumberOfCpus UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct ACPI_CPU_DATA {
+ BOOLEAN APState;
+ BOOLEAN S3BootPath;
+ EFI_PHYSICAL_ADDRESS WakeUpBuffer;
+ EFI_PHYSICAL_ADDRESS GdtrProfile;
+ EFI_PHYSICAL_ADDRESS IdtrProfile;
+ EFI_PHYSICAL_ADDRESS CpuPrivateData;
+ EFI_PHYSICAL_ADDRESS StackAddress;
+ EFI_PHYSICAL_ADDRESS MicrocodePointerBuffer;
+ EFI_PHYSICAL_ADDRESS SmramBase;
+ EFI_PHYSICAL_ADDRESS SmmStartImageBase;
+ UINT32 SmmStartImageSize;
+ UINT32 NumberOfCpus;
+} ACPI_CPU_DATA;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_VARIABLE_SET
+//
+// Description: The structure combine all ACPI related variables into one
+// in order to boost performance
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// AcpiReservedMemoryBase EFI_PHYSICAL_ADDRESS
+// AcpiReservedMemorySize UINT32
+// S3ReservedLowMemoryBase EFI_PHYSICAL_ADDRESS
+// AcpiBootScriptTable EFI_PHYSICAL_ADDRESS
+// RuntimeScriptTableBase EFI_PHYSICAL_ADDRESS
+// AcpiFacsTable[3] EFI_PHYSICAL_ADDRESS
+// SystemMemoryLength UINT64
+// AcpiCpuData ACPI_CPU_DATA
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _ACPI_VARIABLE_SET {
+ //
+ // Acpi Related variables
+ //
+ EFI_PHYSICAL_ADDRESS AcpiReservedMemoryBase;
+ UINT32 AcpiReservedMemorySize;
+ EFI_PHYSICAL_ADDRESS S3ReservedLowMemoryBase;
+ EFI_PHYSICAL_ADDRESS AcpiBootScriptTable;
+ EFI_PHYSICAL_ADDRESS RuntimeScriptTableBase;
+ EFI_PHYSICAL_ADDRESS AcpiFacsTable[3];
+ UINT64 SystemMemoryLength;
+ ACPI_CPU_DATA AcpiCpuData;
+} ACPI_VARIABLE_SET;
+
+
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AcpiSdt.c b/Core/EM/ACPI/AcpiSdt.c
new file mode 100644
index 0000000..5e5c8bb
--- /dev/null
+++ b/Core/EM/ACPI/AcpiSdt.c
@@ -0,0 +1,821 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AcpiSdt.c 3 12/04/12 2:29p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 12/04/12 2:29p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AcpiSdt.c $
+//
+// 3 12/04/12 2:29p Oleksiyy
+// [TAG] EIP108375
+// [Category] Bug Fix
+// [Severity:] Normal
+// [Symptom:] SdtOpenSdtTable function in AcpiSdt.c returns
+// EFI_OUT_OF_RESOURCES.
+// [Root Cause] Error in "if"condition after locating memory.
+// [Solution] Condition is fixed from "!=" to "=="
+// [Files] AcpiSdt.c
+//
+// 2 5/14/11 2:14p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiSdt.c
+//
+// Description:
+// ACPI SDT protocol Implementation.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//
+// Includes
+//
+#include "AcpiCore.h"
+
+extern ACPI_DB gAcpiData;
+
+
+/**
+ This function finds the table specified by the buffer.
+
+ @param[in] Buffer Table buffer to find.
+
+ @return ACPI table list.
+**/
+/*
+EFI_ACPI_TABLE_LIST *
+FindTableByBuffer (
+ IN VOID *Buffer
+ )
+{
+ EFI_ACPI_TABLE_INSTANCE *AcpiTableInstance;
+ LIST_ENTRY *CurrentLink;
+ EFI_ACPI_TABLE_LIST *CurrentTableList;
+ LIST_ENTRY *StartLink;
+
+ //
+ // Get the instance of the ACPI Table
+ //
+ AcpiTableInstance = SdtGetAcpiTableInstance ();
+
+ //
+ // Find the notify
+ //
+ StartLink = &AcpiTableInstance->TableList;
+ CurrentLink = StartLink->ForwardLink;
+
+ while (CurrentLink != StartLink) {
+ CurrentTableList = EFI_ACPI_TABLE_LIST_FROM_LINK (CurrentLink);
+ if (((UINTN)CurrentTableList->PageAddress <= (UINTN)Buffer) &&
+ ((UINTN)CurrentTableList->PageAddress + EFI_PAGES_TO_SIZE(CurrentTableList->NumberOfPages) > (UINTN)Buffer)) {
+ //
+ // Good! Found Table.
+ //
+ return CurrentTableList;
+ }
+
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return NULL;
+}
+*/
+
+/**
+ This function updates AML table checksum.
+ It will search the ACPI table installed by ACPI_TABLE protocol.
+
+ @param[in] Buffer A piece of AML code buffer pointer.
+
+ @retval EFI_SUCCESS The table holds the AML buffer is found, and checksum is updated.
+ @retval EFI_NOT_FOUND The table holds the AML buffer is not found.
+**/
+/*
+EFI_STATUS
+SdtUpdateAmlChecksum (
+ IN VOID *Buffer
+ )
+{
+ EFI_ACPI_TABLE_LIST *CurrentTableList;
+
+ CurrentTableList = FindTableByBuffer (Buffer);
+ if (CurrentTableList == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ AcpiPlatformChecksum (
+ (VOID *)CurrentTableList->Table,
+ CurrentTableList->Table->Length,
+ OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum)
+ );
+ return EFI_SUCCESS;
+}
+*/
+
+/**
+ This function finds MAX AML buffer size.
+ It will search the ACPI table installed by ACPI_TABLE protocol.
+
+ @param[in] Buffer A piece of AML code buffer pointer.
+ @param[out] MaxSize On return it holds the MAX size of buffer.
+
+ @retval EFI_SUCCESS The table holds the AML buffer is found, and MAX size if returned.
+ @retval EFI_NOT_FOUND The table holds the AML buffer is not found.
+**/
+/*
+EFI_STATUS
+SdtGetMaxAmlBufferSize (
+ IN VOID *Buffer,
+ OUT UINTN *MaxSize
+ )
+{
+ EFI_ACPI_TABLE_LIST *CurrentTableList;
+
+ CurrentTableList = FindTableByBuffer (Buffer);
+ if (CurrentTableList == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ *MaxSize = (UINTN)CurrentTableList->Table + CurrentTableList->Table->Length - (UINTN)Buffer;
+ return EFI_SUCCESS;
+}
+*/
+
+
+/**
+ Create a handle for the first ACPI opcode in an ACPI system description table.
+
+ @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
+ @param[out] Handle On return, points to the newly created ACPI handle.
+
+ @retval EFI_SUCCESS Handle created successfully.
+ @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
+**/
+EFI_STATUS
+SdtOpenSdtTable (IN UINTN TableKey, OUT EFI_ACPI_HANDLE *Handle)
+{
+ ACPI_TBL_ITEM *TableItem;
+ EFI_ACPI_SDT_HEADER *Table;
+ EFI_AML_HANDLE *AmlHandle;
+ UINTN i;
+//-----------------------
+
+ // Get the instance of the ACPI Table
+ i=FindAcpiTblByHandle(&TableKey);
+
+ // Find the table
+ if(i==ACPI_TABLE_NOT_FOUND) return EFI_INVALID_PARAMETER;
+
+ TableItem=gAcpiData.AcpiEntries[i];
+ Table=(EFI_ACPI_SDT_HEADER*)TableItem->BtHeaderPtr;
+
+ if(Table->Signature!=DSDT_SIG || Table->Signature!=SSDT_SIG)
+
+
+ AmlHandle = MallocZ(sizeof(*AmlHandle));
+ ASSERT (AmlHandle != NULL);
+ if(AmlHandle == NULL) return EFI_OUT_OF_RESOURCES;
+
+
+ AmlHandle->Signature = EFI_AML_ROOT_HANDLE_SIGNATURE;
+ AmlHandle->Buffer = (VOID *)((UINTN)Table + sizeof(EFI_ACPI_SDT_HEADER));
+ AmlHandle->Size = Table->Length - sizeof(EFI_ACPI_SDT_HEADER);
+// AmlHandle->AmlByteEncoding = NULL;
+// AmlHandle->Modified = FALSE;
+ AmlHandle->Table = Table;
+
+
+ //
+ // return the ACPI handle
+ //
+ *Handle = (EFI_ACPI_HANDLE)AmlHandle;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create a handle for the first ACPI opcode in an ACPI system description table.
+
+ @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
+ @param[out] Handle On return, points to the newly created ACPI handle.
+
+ @retval EFI_SUCCESS Handle created successfully.
+ @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
+**/
+EFI_STATUS
+EFIAPI
+OpenSdt (
+ IN UINTN TableKey,
+ OUT EFI_ACPI_HANDLE *Handle
+ )
+{
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SdtOpenSdtTable (TableKey, Handle);
+}
+
+/*
+/**
+ Create a handle from an ACPI opcode
+
+ @param[in] Buffer Points to the ACPI opcode.
+ @param[in] BufferSize Max buffer size.
+ @param[out] Handle Upon return, holds the handle.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
+ invalid opcode.
+
+**/
+EFI_STATUS
+SdtOpenEx (
+ IN VOID *Buffer,
+ IN UINTN BufferSize,
+ OUT EFI_ACPI_HANDLE *Handle
+ )
+{
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ EFI_AML_HANDLE *AmlHandle;
+
+ AmlByteEncoding = AmlSearchByOpByte (Buffer);
+ if (AmlByteEncoding == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Do not open NameString as handle
+ //
+ if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Good, find it
+ //
+ AmlHandle = Malloc (sizeof(*AmlHandle));
+ ASSERT (AmlHandle != NULL);
+
+ AmlHandle->Signature = EFI_AML_HANDLE_SIGNATURE;
+ AmlHandle->Buffer = Buffer;
+ AmlHandle->AmlByteEncoding = AmlByteEncoding;
+ AmlHandle->Modified = FALSE;
+
+ AmlHandle->Size = AmlGetObjectSize (AmlByteEncoding, Buffer, BufferSize);
+ if (AmlHandle->Size == 0) {
+ pBS->FreePool (AmlHandle);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *Handle = (EFI_ACPI_HANDLE)AmlHandle;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create a handle from an ACPI opcode
+
+ @param[in] Buffer Points to the ACPI opcode.
+ @param[out] Handle Upon return, holds the handle.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
+ invalid opcode.
+
+**/
+EFI_STATUS
+EFIAPI
+Open (
+ IN VOID *Buffer,
+ OUT EFI_ACPI_HANDLE *Handle
+ )
+{
+/*
+ EFI_STATUS Status;
+ UINTN MaxSize;
+
+ MaxSize = 0;
+
+ //
+ // Check for invalid input parameters
+ //
+ if (Buffer == NULL || Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = SdtGetMaxAmlBufferSize (Buffer, &MaxSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return SdtOpenEx (Buffer, MaxSize, Handle);
+*/
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Close an ACPI handle.
+
+ @param[in] Handle Returns the handle.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+ IN EFI_ACPI_HANDLE Handle
+ )
+{
+ EFI_AML_HANDLE *AmlHandle;
+
+ //
+ // Check for invalid input parameters
+ //
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlHandle = (EFI_AML_HANDLE *)Handle;
+ if ((AmlHandle->Signature != EFI_AML_ROOT_HANDLE_SIGNATURE) &&
+ (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Update Checksum only if modified
+ //
+ if (AmlHandle->Modified) {
+ AmlHandle->Table->Checksum=0;
+ AmlHandle->Table->Checksum=ChsumTbl((UINT8*)&AmlHandle->Table->Signature, AmlHandle->Table->Length);
+ }
+
+ pBS->FreePool(AmlHandle);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve information about an ACPI object.
+
+ @param[in] Handle ACPI object handle.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
+ for the specified index.
+ @param[out] Data Upon return, points to the pointer to the data.
+ @param[out] DataSize Upon return, points to the size of Data.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+EFIAPI
+GetOption (
+ IN EFI_ACPI_HANDLE Handle,
+ IN UINTN Index,
+ OUT EFI_ACPI_DATA_TYPE *DataType,
+ OUT CONST VOID **Data,
+ OUT UINTN *DataSize
+ )
+{
+ EFI_AML_HANDLE *AmlHandle;
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ EFI_STATUS Status;
+
+ ASSERT (DataType != NULL);
+ ASSERT (Data != NULL);
+ ASSERT (DataSize != NULL);
+
+ //
+ // Check for invalid input parameters
+ //
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlHandle = (EFI_AML_HANDLE *)Handle;
+ //
+ // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle
+ //
+ if (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlByteEncoding = AmlHandle->AmlByteEncoding;
+ if (Index > AmlByteEncoding->MaxIndex) {
+ *DataType = EFI_ACPI_DATA_TYPE_NONE;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Parse option
+ //
+ Status = AmlParseOptionHandleCommon (AmlHandle, (AML_OP_PARSE_INDEX)Index, DataType, (VOID **)Data, DataSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Change information about an ACPI object.
+
+ @param[in] Handle ACPI object handle.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[in] Data Points to the data.
+ @param[in] DataSize The size of the Data.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
+ @retval EFI_BAD_BUFFER_SIZE Data cannot be accommodated in the space occupied by
+ the option.
+
+**/
+EFI_STATUS
+EFIAPI
+SetOption (
+ IN EFI_ACPI_HANDLE Handle,
+ IN UINTN Index,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ )
+{
+ EFI_AML_HANDLE *AmlHandle;
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ EFI_STATUS Status;
+ EFI_ACPI_DATA_TYPE DataType;
+ VOID *OrgData;
+ UINTN OrgDataSize;
+
+ ASSERT (Data != NULL);
+
+ //
+ // Check for invalid input parameters
+ //
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlHandle = (EFI_AML_HANDLE *)Handle;
+ //
+ // Do not check EFI_AML_ROOT_HANDLE_SIGNATURE because there is no option for Root handle
+ //
+ if (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ AmlByteEncoding = AmlHandle->AmlByteEncoding;
+
+ if (Index > AmlByteEncoding->MaxIndex) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Parse option
+ //
+ Status = AmlParseOptionHandleCommon (AmlHandle, (AML_OP_PARSE_INDEX)Index, &DataType, &OrgData, &OrgDataSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (DataType == EFI_ACPI_DATA_TYPE_NONE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DataSize > OrgDataSize) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
+ // Update
+ //
+
+ pBS->CopyMem(OrgData, (VOID*)Data, DataSize);
+ AmlHandle->Modified = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return the child ACPI objects.
+
+ @param[in] ParentHandle Parent handle.
+ @param[in, out] Handle On entry, points to the previously returned handle or NULL to start with the first
+ handle. On return, points to the next returned ACPI handle or NULL if there are no
+ child objects.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
+**/
+
+EFI_STATUS
+EFIAPI
+GetChild (
+ IN EFI_ACPI_HANDLE ParentHandle,
+ IN OUT EFI_ACPI_HANDLE *Handle
+ )
+{
+ EFI_AML_HANDLE *AmlParentHandle;
+ EFI_AML_HANDLE *AmlHandle;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ ASSERT (Handle != NULL);
+
+ //
+ // Check for invalid input parameters
+ //
+ if (ParentHandle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlHandle = *Handle;
+ if ((AmlHandle != NULL) && (AmlHandle->Signature != EFI_AML_HANDLE_SIGNATURE)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlParentHandle = (EFI_AML_HANDLE *)ParentHandle;
+ if (AmlParentHandle->Signature == EFI_AML_ROOT_HANDLE_SIGNATURE) {
+ //
+ // Root handle
+ //
+ Status = AmlGetChildFromRoot (AmlParentHandle, AmlHandle, &Buffer);
+ } else if (AmlParentHandle->Signature == EFI_AML_HANDLE_SIGNATURE) {
+ //
+ // Non-root handle
+ //
+ Status = AmlGetChildFromNonRoot (AmlParentHandle, AmlHandle, &Buffer);
+ } else {
+ //
+ // Invalid
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Buffer == NULL) {
+ *Handle = NULL;
+ return EFI_SUCCESS;
+ }
+ return SdtOpenEx (Buffer, (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size - (UINTN)Buffer, Handle);
+}
+
+
+/**
+ Returns the handle of the ACPI object representing the specified ACPI path
+
+ @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
+ @param[in] AmlPath Points to the AML path.
+ @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
+ HandleIn.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
+**/
+
+EFI_STATUS
+SdtFindPathFromNonRoot (
+ IN EFI_ACPI_HANDLE HandleIn,
+ IN UINT8 *AmlPath,
+ OUT EFI_ACPI_HANDLE *HandleOut
+ )
+{
+ EFI_AML_HANDLE *AmlHandle;
+ VOID *Buffer;
+ EFI_STATUS Status;
+
+ AmlHandle = (EFI_AML_HANDLE *)HandleIn;
+
+ //
+ // For non-root handle, we need search from THIS node instead of ROOT.
+ //
+ Status = AmlFindPath (AmlHandle, AmlPath, &Buffer, FALSE);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Buffer == NULL) {
+ *HandleOut = NULL;
+ return EFI_SUCCESS;
+ }
+ return SdtOpenEx (Buffer, (UINTN)AmlHandle->Buffer + AmlHandle->Size - (UINTN)Buffer, HandleOut);
+}
+
+
+/**
+ Duplicate AML handle.
+
+ @param[in] AmlHandle Handle to be duplicated.
+
+ @return Duplicated AML handle.
+**/
+
+EFI_AML_HANDLE *
+SdtDuplicateHandle (
+ IN EFI_AML_HANDLE *AmlHandle
+ )
+{
+ EFI_AML_HANDLE *DstAmlHandle;
+
+ DstAmlHandle = Malloc(sizeof(*DstAmlHandle));
+ ASSERT (DstAmlHandle != NULL);
+ pBS->CopyMem(DstAmlHandle, (VOID *)AmlHandle, sizeof(*DstAmlHandle));
+
+ return DstAmlHandle;
+}
+
+/**
+ Returns the handle of the ACPI object representing the specified ACPI path
+
+ @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
+ @param[in] AmlPath Points to the AML path.
+ @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
+ HandleIn.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
+**/
+
+EFI_STATUS
+SdtFindPathFromRoot (
+ IN EFI_ACPI_HANDLE HandleIn,
+ IN UINT8 *AmlPath,
+ OUT EFI_ACPI_HANDLE *HandleOut
+ )
+{
+ EFI_ACPI_HANDLE ChildHandle;
+ EFI_AML_HANDLE *AmlHandle;
+ EFI_STATUS Status;
+ VOID *Buffer;
+
+ AmlHandle = (EFI_AML_HANDLE *)HandleIn;
+
+ //
+ // Handle case that AcpiPath is Root
+ //
+ if (AmlIsRootPath (AmlPath)) {
+ //
+ // Duplicate RootHandle
+ //
+ *HandleOut = (EFI_ACPI_HANDLE)SdtDuplicateHandle (AmlHandle);
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Let children find it.
+ //
+ ChildHandle = NULL;
+ while (TRUE) {
+ Status = GetChild (HandleIn, &ChildHandle);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ChildHandle == NULL) {
+ //
+ // Not found
+ //
+ *HandleOut = NULL;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // More child
+ //
+ AmlHandle = (EFI_AML_HANDLE *)ChildHandle;
+ Status = AmlFindPath (AmlHandle, AmlPath, &Buffer, TRUE);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Buffer != NULL) {
+ //
+ // Great! Find it, open
+ //
+ Status = SdtOpenEx (Buffer, (UINTN)AmlHandle->Buffer + AmlHandle->Size - (UINTN)Buffer, HandleOut);
+ if (!EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+ //
+ // Not success, try next one
+ //
+ }
+ }
+
+ //
+ // Should not run here
+ //
+}
+
+
+/**
+ Returns the handle of the ACPI object representing the specified ACPI path
+
+ @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
+ @param[in] AcpiPath Points to the ACPI path, which conforms to the ACPI encoded path format.
+ @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
+ HandleIn.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
+**/
+
+EFI_STATUS
+EFIAPI
+FindPath (
+ IN EFI_ACPI_HANDLE HandleIn,
+ IN VOID *AcpiPath,
+ OUT EFI_ACPI_HANDLE *HandleOut
+ )
+{
+ EFI_AML_HANDLE *AmlHandle;
+ EFI_STATUS Status;
+ UINT8 *AmlPath;
+
+ //
+ // Check for invalid input parameters
+ //
+ if (HandleIn == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ AmlHandle = (EFI_AML_HANDLE *)HandleIn;
+
+ //
+ // Convert ASL path to AML path
+ //
+ AmlPath = AmlNameFromAslName (AcpiPath);
+ if (AmlPath == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+// DEBUG_CODE_BEGIN ();
+// DEBUG ((EFI_D_ERROR, "AcpiSdt: FindPath - "));
+// AmlPrintNameString (AmlPath);
+// DEBUG ((EFI_D_ERROR, "\n"));
+// DEBUG_CODE_END ();
+
+ if (AmlHandle->Signature == EFI_AML_ROOT_HANDLE_SIGNATURE) {
+ //
+ // Root Handle
+ //
+ Status = SdtFindPathFromRoot (HandleIn, AmlPath, HandleOut);
+ } else if (AmlHandle->Signature == EFI_AML_HANDLE_SIGNATURE) {
+ //
+ // Non-Root handle
+ //
+ Status = SdtFindPathFromNonRoot (HandleIn, AmlPath, HandleOut);
+ } else {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ pBS->FreePool (AmlPath);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AcpiSdtPrivate.h b/Core/EM/ACPI/AcpiSdtPrivate.h
new file mode 100644
index 0000000..17ea790
--- /dev/null
+++ b/Core/EM/ACPI/AcpiSdtPrivate.h
@@ -0,0 +1,798 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AcpiSdtPrivate.h 2 5/14/11 2:15p Yakovlevs $
+//
+// $Revision: 2 $
+//
+// $Date: 5/14/11 2:15p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AcpiSdtPrivate.h $
+//
+// 2 5/14/11 2:15p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiSdtPrivate.h
+//
+// Description:
+// ACPI SDT protocol Private data Definitions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _ACPI_SDT_H_
+#define _ACPI_SDT_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "AcpiCore.h"
+//
+// ACPI AML definition
+//
+
+//
+// Primary OpCode
+//
+#define AML_ZERO_OP 0x00
+#define AML_ONE_OP 0x01
+#define AML_ALIAS_OP 0x06
+#define AML_NAME_OP 0x08
+#define AML_BYTE_PREFIX 0x0a
+#define AML_WORD_PREFIX 0x0b
+#define AML_DWORD_PREFIX 0x0c
+#define AML_STRING_PREFIX 0x0d
+#define AML_QWORD_PREFIX 0x0e
+#define AML_SCOPE_OP 0x10
+#define AML_BUFFER_OP 0x11
+#define AML_PACKAGE_OP 0x12
+#define AML_VAR_PACKAGE_OP 0x13
+#define AML_METHOD_OP 0x14
+#define AML_DUAL_NAME_PREFIX 0x2e
+#define AML_MULTI_NAME_PREFIX 0x2f
+#define AML_NAME_CHAR_A 0x41
+#define AML_NAME_CHAR_B 0x42
+#define AML_NAME_CHAR_C 0x43
+#define AML_NAME_CHAR_D 0x44
+#define AML_NAME_CHAR_E 0x45
+#define AML_NAME_CHAR_F 0x46
+#define AML_NAME_CHAR_G 0x47
+#define AML_NAME_CHAR_H 0x48
+#define AML_NAME_CHAR_I 0x49
+#define AML_NAME_CHAR_J 0x4a
+#define AML_NAME_CHAR_K 0x4b
+#define AML_NAME_CHAR_L 0x4c
+#define AML_NAME_CHAR_M 0x4d
+#define AML_NAME_CHAR_N 0x4e
+#define AML_NAME_CHAR_O 0x4f
+#define AML_NAME_CHAR_P 0x50
+#define AML_NAME_CHAR_Q 0x51
+#define AML_NAME_CHAR_R 0x52
+#define AML_NAME_CHAR_S 0x53
+#define AML_NAME_CHAR_T 0x54
+#define AML_NAME_CHAR_U 0x55
+#define AML_NAME_CHAR_V 0x56
+#define AML_NAME_CHAR_W 0x57
+#define AML_NAME_CHAR_X 0x58
+#define AML_NAME_CHAR_Y 0x59
+#define AML_NAME_CHAR_Z 0x5a
+#define AML_ROOT_CHAR 0x5c
+#define AML_PARENT_PREFIX_CHAR 0x5e
+#define AML_NAME_CHAR__ 0x5f
+#define AML_LOCAL0 0x60
+#define AML_LOCAL1 0x61
+#define AML_LOCAL2 0x62
+#define AML_LOCAL3 0x63
+#define AML_LOCAL4 0x64
+#define AML_LOCAL5 0x65
+#define AML_LOCAL6 0x66
+#define AML_LOCAL7 0x67
+#define AML_ARG0 0x68
+#define AML_ARG1 0x69
+#define AML_ARG2 0x6a
+#define AML_ARG3 0x6b
+#define AML_ARG4 0x6c
+#define AML_ARG5 0x6d
+#define AML_ARG6 0x6e
+#define AML_STORE_OP 0x70
+#define AML_REF_OF_OP 0x71
+#define AML_ADD_OP 0x72
+#define AML_CONCAT_OP 0x73
+#define AML_SUBTRACT_OP 0x74
+#define AML_INCREMENT_OP 0x75
+#define AML_DECREMENT_OP 0x76
+#define AML_MULTIPLY_OP 0x77
+#define AML_DIVIDE_OP 0x78
+#define AML_SHIFT_LEFT_OP 0x79
+#define AML_SHIFT_RIGHT_OP 0x7a
+#define AML_AND_OP 0x7b
+#define AML_NAND_OP 0x7c
+#define AML_OR_OP 0x7d
+#define AML_NOR_OP 0x7e
+#define AML_XOR_OP 0x7f
+#define AML_NOT_OP 0x80
+#define AML_FIND_SET_LEFT_BIT_OP 0x81
+#define AML_FIND_SET_RIGHT_BIT_OP 0x82
+#define AML_DEREF_OF_OP 0x83
+#define AML_CONCAT_RES_OP 0x84
+#define AML_MOD_OP 0x85
+#define AML_NOTIFY_OP 0x86
+#define AML_SIZE_OF_OP 0x87
+#define AML_INDEX_OP 0x88
+#define AML_MATCH_OP 0x89
+#define AML_CREATE_DWORD_FIELD_OP 0x8a
+#define AML_CREATE_WORD_FIELD_OP 0x8b
+#define AML_CREATE_BYTE_FIELD_OP 0x8c
+#define AML_CREATE_BIT_FIELD_OP 0x8d
+#define AML_OBJECT_TYPE_OP 0x8e
+#define AML_CREATE_QWORD_FIELD_OP 0x8f
+#define AML_LAND_OP 0x90
+#define AML_LOR_OP 0x91
+#define AML_LNOT_OP 0x92
+#define AML_LEQUAL_OP 0x93
+#define AML_LGREATER_OP 0x94
+#define AML_LLESS_OP 0x95
+#define AML_TO_BUFFER_OP 0x96
+#define AML_TO_DEC_STRING_OP 0x97
+#define AML_TO_HEX_STRING_OP 0x98
+#define AML_TO_INTEGER_OP 0x99
+#define AML_TO_STRING_OP 0x9c
+#define AML_COPY_OBJECT_OP 0x9d
+#define AML_MID_OP 0x9e
+#define AML_CONTINUE_OP 0x9f
+#define AML_IF_OP 0xa0
+#define AML_ELSE_OP 0xa1
+#define AML_WHILE_OP 0xa2
+#define AML_NOOP_OP 0xa3
+#define AML_RETURN_OP 0xa4
+#define AML_BREAK_OP 0xa5
+#define AML_BREAK_POINT_OP 0xcc
+#define AML_ONES_OP 0xff
+
+//
+// Extended OpCode
+//
+#define AML_EXT_OP 0x5b
+
+#define AML_EXT_MUTEX_OP 0x01
+#define AML_EXT_EVENT_OP 0x02
+#define AML_EXT_COND_REF_OF_OP 0x12
+#define AML_EXT_CREATE_FIELD_OP 0x13
+#define AML_EXT_LOAD_TABLE_OP 0x1f
+#define AML_EXT_LOAD_OP 0x20
+#define AML_EXT_STALL_OP 0x21
+#define AML_EXT_SLEEP_OP 0x22
+#define AML_EXT_ACQUIRE_OP 0x23
+#define AML_EXT_SIGNAL_OP 0x24
+#define AML_EXT_WAIT_OP 0x25
+#define AML_EXT_RESET_OP 0x26
+#define AML_EXT_RELEASE_OP 0x27
+#define AML_EXT_FROM_BCD_OP 0x28
+#define AML_EXT_TO_BCD_OP 0x29
+#define AML_EXT_UNLOAD_OP 0x2a
+#define AML_EXT_REVISION_OP 0x30
+#define AML_EXT_DEBUG_OP 0x31
+#define AML_EXT_FATAL_OP 0x32
+#define AML_EXT_TIMER_OP 0x33
+#define AML_EXT_REGION_OP 0x80
+#define AML_EXT_FIELD_OP 0x81
+#define AML_EXT_DEVICE_OP 0x82
+#define AML_EXT_PROCESSOR_OP 0x83
+#define AML_EXT_POWER_RES_OP 0x84
+#define AML_EXT_THERMAL_ZONE_OP 0x85
+#define AML_EXT_INDEX_FIELD_OP 0x86
+#define AML_EXT_BANK_FIELD_OP 0x87
+#define AML_EXT_DATA_REGION_OP 0x88
+
+//
+// Privacy data structure
+//
+#define LIST_ENTRY EFI_LIST_ENTRY
+
+typedef struct _AML_BYTE_ENCODING AML_BYTE_ENCODING;
+typedef struct _EFI_AML_NODE_LIST EFI_AML_NODE_LIST;
+
+//
+// AML Node Linked List Signature.
+//
+#define EFI_AML_NODE_LIST_SIGNATURE SIGNATURE_32 ('E', 'A', 'M', 'L')
+
+//
+// AML Node Linked List Entry definition.
+//
+// Signature must be set to EFI_AML_NODE_LIST_SIGNATURE
+// Link is the linked list data.
+// Name is the ACPI node name.
+// This is listed for PATH finding.
+// Buffer is the ACPI node buffer pointer, the first/second bytes are opcode.
+// This buffer should not be freed.
+// Size is the total size of this ACPI node buffer.
+// Children is the children linked list of this node.
+//
+#define AML_NAME_SEG_SIZE 4
+
+struct _EFI_AML_NODE_LIST {
+ UINT32 Signature;
+ UINT8 Name[AML_NAME_SEG_SIZE];
+ UINT8 *Buffer;
+ UINTN Size;
+ LIST_ENTRY Link;
+ LIST_ENTRY Children;
+ EFI_AML_NODE_LIST *Parent;
+ AML_BYTE_ENCODING *AmlByteEncoding;
+};
+
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#ifndef _CR
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+#endif
+
+#ifndef CR
+#define CR(record, TYPE, field, signature) _CR(record, TYPE, field)
+#endif
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
+#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+
+
+//
+// Containment record for AML Node linked list.
+//
+#define EFI_AML_NODE_LIST_FROM_LINK(_link) CR (_link, EFI_AML_NODE_LIST, Link, EFI_AML_NODE_LIST_SIGNATURE)
+
+//
+// AML Handle Signature.
+//
+#define EFI_AML_HANDLE_SIGNATURE SIGNATURE_32 ('E', 'A', 'H', 'S')
+#define EFI_AML_ROOT_HANDLE_SIGNATURE SIGNATURE_32 ('E', 'A', 'R', 'H')
+
+//
+// AML Handle Entry definition.
+//
+// Signature must be set to EFI_AML_HANDLE_SIGNATURE or EFI_AML_ROOT_HANDLE_SIGNATURE
+// Buffer is the ACPI node buffer pointer, the first/second bytes are opcode.
+// This buffer should not be freed.
+// Size is the total size of this ACPI node buffer.
+//
+typedef struct {
+ UINT32 Signature;
+ UINT8 *Buffer;
+ UINTN Size;
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ EFI_ACPI_SDT_HEADER *Table;
+ BOOLEAN Modified;
+ BOOLEAN OnBuffer;
+} EFI_AML_HANDLE;
+
+typedef UINT32 AML_OP_PARSE_INDEX;
+
+#define AML_OP_PARSE_INDEX_GET_OPCODE 0
+#define AML_OP_PARSE_INDEX_GET_TERM1 1
+#define AML_OP_PARSE_INDEX_GET_TERM2 2
+#define AML_OP_PARSE_INDEX_GET_TERM3 3
+#define AML_OP_PARSE_INDEX_GET_TERM4 4
+#define AML_OP_PARSE_INDEX_GET_TERM5 5
+#define AML_OP_PARSE_INDEX_GET_TERM6 6
+#define AML_OP_PARSE_INDEX_GET_SIZE (AML_OP_PARSE_INDEX)-1
+
+typedef UINT32 AML_OP_PARSE_FORMAT;
+#define AML_NONE 0
+#define AML_OPCODE 1
+#define AML_UINT8 2
+#define AML_UINT16 3
+#define AML_UINT32 4
+#define AML_UINT64 5
+#define AML_NAME 6
+#define AML_STRING 7
+#define AML_OBJECT 8
+
+typedef UINT32 AML_OP_ATTRIBUTE;
+#define AML_HAS_PKG_LENGTH 0x1 // It is ACPI attribute - if OpCode has PkgLength
+#define AML_IS_NAME_CHAR 0x2 // It is ACPI attribute - if this is NameChar
+#define AML_HAS_CHILD_OBJ 0x4 // it is ACPI attribute - if OpCode has Child Object.
+#define AML_IN_NAMESPACE 0x10000 // It is UEFI SDT attribute - if OpCode will be in NameSpace
+ // NOTE; Not all OBJECT will be in NameSpace
+ // For example, BankField | CreateBitField | CreateByteField | CreateDWordField |
+ // CreateField | CreateQWordField | CreateWordField | Field | IndexField.
+
+struct _AML_BYTE_ENCODING {
+ UINT8 OpCode;
+ UINT8 SubOpCode;
+ AML_OP_PARSE_INDEX MaxIndex;
+ AML_OP_PARSE_FORMAT Format[6];
+ AML_OP_ATTRIBUTE Attribute;
+};
+
+//
+// AcpiSdt protocol declaration
+//
+
+/**
+ Returns a requested ACPI table.
+
+ The GetAcpiTable() function returns a pointer to a buffer containing the ACPI table associated
+ with the Index that was input. The following structures are not considered elements in the list of
+ ACPI tables:
+ - Root System Description Pointer (RSD_PTR)
+ - Root System Description Table (RSDT)
+ - Extended System Description Table (XSDT)
+ Version is updated with a bit map containing all the versions of ACPI of which the table is a
+ member.
+
+ @param[in] Index The zero-based index of the table to retrieve.
+ @param[out] Table Pointer for returning the table buffer.
+ @param[out] Version On return, updated with the ACPI versions to which this table belongs. Type
+ EFI_ACPI_TABLE_VERSION is defined in "Related Definitions" in the
+ EFI_ACPI_SDT_PROTOCOL.
+ @param[out] TableKey On return, points to the table key for the specified ACPI system definition table. This
+ is identical to the table key used in the EFI_ACPI_TABLE_PROTOCOL.
+
+ @retval EFI_SUCCESS The function completed successfully.
+ @retval EFI_NOT_FOUND The requested index is too large and a table was not found.
+**/
+EFI_STATUS
+EFIAPI
+GetAcpiTable2 (
+ IN UINTN Index,
+ OUT EFI_ACPI_SDT_HEADER **Table,
+ OUT EFI_ACPI_TABLE_VERSION *Version,
+ OUT UINTN *TableKey
+ );
+
+/**
+ Register or unregister a callback when an ACPI table is installed.
+
+ This function registers or unregisters a function which will be called whenever a new ACPI table is
+ installed.
+
+ @param[in] Register If TRUE, then the specified function will be registered. If FALSE, then the specified
+ function will be unregistered.
+ @param[in] Notification Points to the callback function to be registered or unregistered.
+
+ @retval EFI_SUCCESS Callback successfully registered or unregistered.
+ @retval EFI_INVALID_PARAMETER Notification is NULL
+ @retval EFI_INVALID_PARAMETER Register is FALSE and Notification does not match a known registration function.
+**/
+EFI_STATUS
+EFIAPI
+RegisterNotify (
+ IN BOOLEAN Register,
+ IN EFI_ACPI_NOTIFICATION_FN Notification
+ );
+
+/**
+ Create a handle for the first ACPI opcode in an ACPI system description table.
+
+ @param[in] TableKey The table key for the ACPI table, as returned by GetTable().
+ @param[out] Handle On return, points to the newly created ACPI handle.
+
+ @retval EFI_SUCCESS Handle created successfully.
+ @retval EFI_NOT_FOUND TableKey does not refer to a valid ACPI table.
+**/
+EFI_STATUS
+EFIAPI
+OpenSdt (
+ IN UINTN TableKey,
+ OUT EFI_ACPI_HANDLE *Handle
+ );
+
+/**
+ Create a handle from an ACPI opcode
+
+ @param[in] Buffer Points to the ACPI opcode.
+ @param[out] Handle Upon return, holds the handle.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
+ invalid opcode.
+
+**/
+EFI_STATUS
+EFIAPI
+Open (
+ IN VOID *Buffer,
+ OUT EFI_ACPI_HANDLE *Handle
+ );
+
+/**
+ Close an ACPI handle.
+
+ @param[in] Handle Returns the handle.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+EFIAPI
+Close (
+ IN EFI_ACPI_HANDLE Handle
+ );
+
+/**
+ Retrieve information about an ACPI object.
+
+ @param[in] Handle ACPI object handle.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
+ for the specified index.
+ @param[out] Data Upon return, points to the pointer to the data.
+ @param[out] DataSize Upon return, points to the size of Data.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+EFIAPI
+GetOption (
+ IN EFI_ACPI_HANDLE Handle,
+ IN UINTN Index,
+ OUT EFI_ACPI_DATA_TYPE *DataType,
+ OUT CONST VOID **Data,
+ OUT UINTN *DataSize
+ );
+
+/**
+ Change information about an ACPI object.
+
+ @param[in] Handle ACPI object handle.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[in] Data Points to the data.
+ @param[in] DataSize The size of the Data.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Handle is NULL or does not refer to a valid ACPI object.
+ @retval EFI_BAD_BUFFER_SIZE Data cannot be accommodated in the space occupied by
+ the option.
+
+**/
+EFI_STATUS
+EFIAPI
+SetOption (
+ IN EFI_ACPI_HANDLE Handle,
+ IN UINTN Index,
+ IN CONST VOID *Data,
+ IN UINTN DataSize
+ );
+
+/**
+ Return the child ACPI objects.
+
+ @param[in] ParentHandle Parent handle.
+ @param[in, out] Handle On entry, points to the previously returned handle or NULL to start with the first
+ handle. On return, points to the next returned ACPI handle or NULL if there are no
+ child objects.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+EFIAPI
+GetChild (
+ IN EFI_ACPI_HANDLE ParentHandle,
+ IN OUT EFI_ACPI_HANDLE *Handle
+ );
+
+/**
+ Returns the handle of the ACPI object representing the specified ACPI path
+
+ @param[in] HandleIn Points to the handle of the object representing the starting point for the path search.
+ @param[in] AcpiPath Points to the ACPI path, which conforms to the ACPI encoded path format.
+ @param[out] HandleOut On return, points to the ACPI object which represents AcpiPath, relative to
+ HandleIn.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER HandleIn is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+EFIAPI
+FindPath (
+ IN EFI_ACPI_HANDLE HandleIn,
+ IN VOID *AcpiPath,
+ OUT EFI_ACPI_HANDLE *HandleOut
+ );
+
+//
+// ACPI SDT function
+//
+
+/**
+ Create a handle from an ACPI opcode
+
+ @param[in] Buffer Points to the ACPI opcode.
+ @param[in] BufferSize Max buffer size.
+ @param[out] Handle Upon return, holds the handle.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER Buffer is NULL or Handle is NULL or Buffer points to an
+ invalid opcode.
+
+**/
+EFI_STATUS
+SdtOpenEx (
+ IN VOID *Buffer,
+ IN UINTN BufferSize,
+ OUT EFI_ACPI_HANDLE *Handle
+ );
+
+//
+// AML support function
+//
+
+/**
+ Get AML NameString size.
+
+ @param[in] Buffer AML NameString.
+ @param[out] BufferSize AML NameString size
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid AML NameString.
+**/
+EFI_STATUS
+AmlGetNameStringSize (
+ IN UINT8 *Buffer,
+ OUT UINTN *BufferSize
+ );
+
+/**
+ This function retuns package length from the buffer.
+
+ @param[in] Buffer AML buffer
+ @param[out] PkgLength The total length of package.
+
+ @return The byte data count to present the package length.
+**/
+UINTN
+AmlGetPkgLength (
+ IN UINT8 *Buffer,
+ OUT UINTN *PkgLength
+ );
+
+/**
+ This function returns AcpiDataType according to AmlType.
+
+ @param[in] AmlType AML Type.
+
+ @return AcpiDataType
+**/
+EFI_ACPI_DATA_TYPE
+AmlTypeToAcpiType (
+ IN AML_OP_PARSE_FORMAT AmlType
+ );
+
+/**
+ This function returns AmlByteEncoding according to OpCode Byte.
+
+ @param[in] OpByteBuffer OpCode byte buffer.
+
+ @return AmlByteEncoding
+**/
+AML_BYTE_ENCODING *
+AmlSearchByOpByte (
+ IN UINT8 *OpByteBuffer
+ );
+
+/**
+ Return object size.
+
+ @param[in] AmlByteEncoding AML Byte Encoding.
+ @param[in] Buffer AML object buffer.
+ @param[in] MaxBufferSize AML object buffer MAX size. The parser can not parse any data exceed this region.
+
+ @return Size of the object.
+**/
+UINTN
+AmlGetObjectSize (
+ IN AML_BYTE_ENCODING *AmlByteEncoding,
+ IN UINT8 *Buffer,
+ IN UINTN MaxBufferSize
+ );
+
+/**
+ Return object name.
+
+ @param[in] AmlHandle AML handle.
+
+ @return Name of the object.
+**/
+CHAR8 *
+AmlGetObjectName (
+ IN EFI_AML_HANDLE *AmlHandle
+ );
+
+/**
+ Retrieve information according to AmlHandle
+
+ @param[in] AmlHandle AML handle.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
+ for the specified index.
+ @param[out] Data Upon return, points to the pointer to the data.
+ @param[out] DataSize Upon return, points to the size of Data.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlParseOptionHandleCommon (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN AML_OP_PARSE_INDEX Index,
+ OUT EFI_ACPI_DATA_TYPE *DataType,
+ OUT VOID **Data,
+ OUT UINTN *DataSize
+ );
+
+/**
+ Return offset of last option.
+
+ @param[in] AmlHandle AML Handle.
+ @param[out] Buffer Upon return, points to the offset after last option.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetOffsetAfterLastOption (
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT UINT8 **Buffer
+ );
+
+/**
+ Return the child ACPI objects from Root Handle.
+
+ @param[in] AmlParentHandle Parent handle. It is Root Handle.
+ @param[in] AmlHandle The previously returned handle or NULL to start with the first handle.
+ @param[out] Buffer On return, points to the next returned ACPI handle or NULL if there are no
+ child objects.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromRoot (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT VOID **Buffer
+ );
+
+/**
+ Return the child ACPI objects from Non-Root Handle.
+
+ @param[in] AmlParentHandle Parent handle. It is Non-Root Handle.
+ @param[in] AmlHandle The previously returned handle or NULL to start with the first handle.
+ @param[out] Buffer On return, points to the next returned ACPI handle or NULL if there are no
+ child objects.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromNonRoot (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT VOID **Buffer
+ );
+
+/**
+ Return AML name according to ASL name.
+ The caller need free the AmlName returned.
+
+ @param[in] AslPath ASL name.
+
+ @return AmlName
+**/
+UINT8 *
+AmlNameFromAslName (
+ IN UINT8 *AslPath
+ );
+
+/**
+ Returns the handle of the ACPI object representing the specified ACPI AML path
+
+ @param[in] AmlHandle Points to the handle of the object representing the starting point for the path search.
+ @param[in] AmlPath Points to the ACPI AML path.
+ @param[out] Buffer On return, points to the ACPI object which represents AcpiPath, relative to
+ HandleIn.
+ @param[in] FromRoot TRUE means to find AML path from \ (Root) Node.
+ FALSE means to find AML path from this Node (The HandleIn).
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER HandleIn does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlFindPath (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN UINT8 *AmlPath,
+ OUT VOID **Buffer,
+ IN BOOLEAN FromRoot
+ );
+
+/**
+ Print AML NameString.
+
+ @param[in] Buffer AML NameString.
+**/
+VOID
+AmlPrintNameString (
+ IN UINT8 *Buffer
+ );
+
+/**
+ Print AML NameSeg.
+
+ @param[in] Buffer AML NameSeg.
+**/
+VOID
+AmlPrintNameSeg (
+ IN UINT8 *Buffer
+ );
+
+/**
+ Check if it is AML Root name
+
+ @param[in] Buffer AML path.
+
+ @retval TRUE AML path is root.
+ @retval FALSE AML path is not root.
+**/
+BOOLEAN
+AmlIsRootPath (
+ IN UINT8 *Buffer
+ );
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/Aml.c b/Core/EM/ACPI/Aml.c
new file mode 100644
index 0000000..a5510cb
--- /dev/null
+++ b/Core/EM/ACPI/Aml.c
@@ -0,0 +1,350 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Aml.c 2 5/14/11 2:08p Yakovlevs $
+//
+// $Revision: 2 $
+//
+// $Date: 5/14/11 2:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Aml.c $
+//
+// 2 5/14/11 2:08p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Aml.c
+//
+// Description:
+// Generic AML Parsing functions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+#include "AcpiCore.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+AML_BYTE_ENCODING mAmlByteEncoding[] = {
+ // OpCode SubOpCode Num 1 2 3 4 5 6 Attribute
+/* ZeroOp - 0x00 */ {AML_ZERO_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* OneOp - 0x01 */ {AML_ONE_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* AliasOp - 0x06 */ {AML_ALIAS_OP, 0, 2, AML_NAME, AML_NAME, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IN_NAMESPACE},
+/* NameOp - 0x08 */ {AML_NAME_OP, 0, 2, AML_NAME, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IN_NAMESPACE},
+/* BytePrefix - 0x0A */ {AML_BYTE_PREFIX, 0, 1, AML_UINT8, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* WordPrefix - 0x0B */ {AML_WORD_PREFIX, 0, 1, AML_UINT16, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* DWordPrefix - 0x0C */ {AML_DWORD_PREFIX, 0, 1, AML_UINT32, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* StringPrefix - 0x0D */ {AML_STRING_PREFIX, 0, 1, AML_STRING, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* QWordPrefix - 0x0E */ {AML_QWORD_PREFIX, 0, 1, AML_UINT64, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ScopeOp - 0x10 */ {AML_SCOPE_OP, 0, 1, AML_NAME, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ | AML_IN_NAMESPACE},
+/* BufferOp - 0x11 */ {AML_BUFFER_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH},
+/* PackageOp - 0x12 */ {AML_PACKAGE_OP, 0, 1, AML_UINT8, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ},
+/* VarPackageOp - 0x13 */ {AML_VAR_PACKAGE_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ},
+/* MethodOp - 0x14 */ {AML_METHOD_OP, 0, 2, AML_NAME, AML_UINT8, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ | AML_IN_NAMESPACE},
+/* DualNamePrefix - 0x2F */ {AML_DUAL_NAME_PREFIX, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* MultiNamePrefix - 0x2F */ {AML_MULTI_NAME_PREFIX, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x41 */ {'A', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x42 */ {'B', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x43 */ {'C', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x44 */ {'D', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x45 */ {'E', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x46 */ {'F', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x47 */ {'G', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x48 */ {'H', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x49 */ {'I', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x4A */ {'J', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x4B */ {'K', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x4C */ {'L', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x4D */ {'M', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x4E */ {'N', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x4F */ {'O', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x50 */ {'P', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x51 */ {'Q', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x52 */ {'R', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x53 */ {'S', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x54 */ {'T', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x55 */ {'U', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x56 */ {'V', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x57 */ {'W', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x58 */ {'X', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x59 */ {'Y', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x5A */ {'Z', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* MutexOp - 0x5B 0x01 */ {AML_EXT_OP, AML_EXT_MUTEX_OP, 2, AML_NAME, AML_UINT8, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IN_NAMESPACE},
+/* EventOp - 0x5B 0x02 */ {AML_EXT_OP, AML_EXT_EVENT_OP, 1, AML_NAME, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IN_NAMESPACE},
+/* CondRefOfOp - 0x5B 0x12 */ {AML_EXT_OP, AML_EXT_COND_REF_OF_OP, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* CreateFieldOp - 0x5B 0x13 */ {AML_EXT_OP, AML_EXT_CREATE_FIELD_OP,4, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NAME, AML_NONE, AML_NONE, 0},
+/* LoadTableOp - 0x5B 0x1F */ {AML_EXT_OP, AML_EXT_LOAD_TABLE_OP, 6, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_OBJECT, 0},
+/* LoadOp - 0x5B 0x20 */ {AML_EXT_OP, AML_EXT_LOAD_OP, 2, AML_NAME, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* StallOp - 0x5B 0x21 */ {AML_EXT_OP, AML_EXT_STALL_OP, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* SleepOp - 0x5B 0x22 */ {AML_EXT_OP, AML_EXT_SLEEP_OP, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* AcquireOp - 0x5B 0x23 */ {AML_EXT_OP, AML_EXT_ACQUIRE_OP, 2, AML_OBJECT, AML_UINT16, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* SignalOp - 0x5B 0x24 */ {AML_EXT_OP, AML_EXT_SIGNAL_OP, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* WaitOp - 0x5B 0x25 */ {AML_EXT_OP, AML_EXT_WAIT_OP, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ResetOp - 0x5B 0x26 */ {AML_EXT_OP, AML_EXT_RESET_OP, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ReleaseOp - 0x5B 0x27 */ {AML_EXT_OP, AML_EXT_RELEASE_OP, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* FromBCDOp - 0x5B 0x28 */ {AML_EXT_OP, AML_EXT_FROM_BCD_OP, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ToBCDOp - 0x5B 0x29 */ {AML_EXT_OP, AML_EXT_TO_BCD_OP, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* UnloadOp - 0x5B 0x2A */ {AML_EXT_OP, AML_EXT_UNLOAD_OP, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* RevisionOp - 0x5B 0x30 */ {AML_EXT_OP, AML_EXT_REVISION_OP, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* DebugOp - 0x5B 0x31 */ {AML_EXT_OP, AML_EXT_DEBUG_OP, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* FatalOp - 0x5B 0x32 */ {AML_EXT_OP, AML_EXT_FATAL_OP, 3, AML_UINT8, AML_UINT32, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* TimerOp - 0x5B 0x33 */ {AML_EXT_OP, AML_EXT_TIMER_OP, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* OpRegionOp - 0x5B 0x80 */ {AML_EXT_OP, AML_EXT_REGION_OP, 4, AML_NAME, AML_UINT8, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_IN_NAMESPACE},
+/* FieldOp - 0x5B 0x81 */ {AML_EXT_OP, AML_EXT_FIELD_OP, 2, AML_NAME, AML_UINT8, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH},
+/* DeviceOp - 0x5B 0x82 */ {AML_EXT_OP, AML_EXT_DEVICE_OP, 1, AML_NAME, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ | AML_IN_NAMESPACE},
+/* ProcessorOp - 0x5B 0x83 */ {AML_EXT_OP, AML_EXT_PROCESSOR_OP, 4, AML_NAME, AML_UINT8, AML_UINT32, AML_UINT8, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ | AML_IN_NAMESPACE},
+/* PowerResOp - 0x5B 0x84 */ {AML_EXT_OP, AML_EXT_POWER_RES_OP, 3, AML_NAME, AML_UINT8, AML_UINT16, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ | AML_IN_NAMESPACE},
+/* ThermalZoneOp - 0x5B 0x85 */ {AML_EXT_OP, AML_EXT_THERMAL_ZONE_OP,1, AML_NAME, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ | AML_IN_NAMESPACE},
+/* IndexFieldOp - 0x5B 0x86 */ {AML_EXT_OP, AML_EXT_INDEX_FIELD_OP, 3, AML_NAME, AML_NAME, AML_UINT8, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH},
+/* BankFieldOp - 0x5B 0x87 */ {AML_EXT_OP, AML_EXT_BANK_FIELD_OP, 4, AML_NAME, AML_NAME, AML_OBJECT, AML_UINT8, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH},
+/* DataRegionOp - 0x5B 0x88 */ {AML_EXT_OP, AML_EXT_DATA_REGION_OP, 4, AML_NAME, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_IN_NAMESPACE},
+/* RootChar - 0x5C */ {AML_ROOT_CHAR, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* ParentPrefixChar - 0x5E */ {AML_PARENT_PREFIX_CHAR, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* NameChar - 0x5F */ {'_', 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_IS_NAME_CHAR},
+/* Local0Op - 0x60 */ {AML_LOCAL0, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local1Op - 0x61 */ {AML_LOCAL1, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local2Op - 0x62 */ {AML_LOCAL2, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local3Op - 0x63 */ {AML_LOCAL3, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local4Op - 0x64 */ {AML_LOCAL4, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local5Op - 0x65 */ {AML_LOCAL5, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local6Op - 0x66 */ {AML_LOCAL6, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Local7Op - 0x67 */ {AML_LOCAL7, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg0Op - 0x68 */ {AML_ARG0, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg1Op - 0x69 */ {AML_ARG1, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg2Op - 0x6A */ {AML_ARG2, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg3Op - 0x6B */ {AML_ARG3, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg4Op - 0x6C */ {AML_ARG4, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg5Op - 0x6D */ {AML_ARG5, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* Arg6Op - 0x6E */ {AML_ARG6, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* StoreOp - 0x70 */ {AML_STORE_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* RefOfOp - 0x71 */ {AML_REF_OF_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* AddOp - 0x72 */ {AML_ADD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ConcatOp - 0x73 */ {AML_CONCAT_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* SubtractOp - 0x74 */ {AML_SUBTRACT_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* IncrementOp - 0x75 */ {AML_INCREMENT_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* DecrementOp - 0x76 */ {AML_DECREMENT_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* MultiplyOp - 0x77 */ {AML_MULTIPLY_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* DivideOp - 0x78 */ {AML_DIVIDE_OP, 0, 4, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, 0},
+/* ShiftLeftOp - 0x79 */ {AML_SHIFT_LEFT_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ShiftRightOp - 0x7A */ {AML_SHIFT_RIGHT_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* AndOp - 0x7B */ {AML_AND_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* NAndOp - 0x7C */ {AML_NAND_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* OrOp - 0x7D */ {AML_OR_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* NorOp - 0x7E */ {AML_NOR_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* XOrOp - 0x7F */ {AML_XOR_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* NotOp - 0x80 */ {AML_NOT_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* FindSetLeftBitOp - 0x81 */ {AML_FIND_SET_LEFT_BIT_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* FindSetRightBitOp - 0x82 */ {AML_FIND_SET_RIGHT_BIT_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* DerefOfOp - 0x83 */ {AML_DEREF_OF_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ConcatResOp - 0x84 */ {AML_CONCAT_RES_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ModOp - 0x85 */ {AML_MOD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* NotifyOp - 0x86 */ {AML_NOTIFY_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* SizeOfOp - 0x87 */ {AML_SIZE_OF_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* IndexOp - 0x88 */ {AML_INDEX_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* MatchOp - 0x89 */ {AML_MATCH_OP, 0, 6, AML_OBJECT, AML_UINT8, AML_OBJECT, AML_UINT8, AML_OBJECT, AML_OBJECT, 0},
+/* CreateDWordFieldOp - 0x8A */ {AML_CREATE_DWORD_FIELD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_NAME, AML_NONE, AML_NONE, AML_NONE, 0},
+/* CreateWordFieldOp - 0x8B */ {AML_CREATE_WORD_FIELD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_NAME, AML_NONE, AML_NONE, AML_NONE, 0},
+/* CreateByteFieldOp - 0x8C */ {AML_CREATE_BYTE_FIELD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_NAME, AML_NONE, AML_NONE, AML_NONE, 0},
+/* CreateBitFieldOp - 0x8D */ {AML_CREATE_BIT_FIELD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_NAME, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ObjectTypeOp - 0x8E */ {AML_OBJECT_TYPE_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* CreateQWordFieldOp - 0x8F */ {AML_CREATE_QWORD_FIELD_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_NAME, AML_NONE, AML_NONE, AML_NONE, 0},
+/* LAndOp - 0x90 */ {AML_LAND_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* LOrOp - 0x91 */ {AML_LOR_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* LNotOp - 0x92 */ {AML_LNOT_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* LEqualOp - 0x93 */ {AML_LEQUAL_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* LGreaterOp - 0x94 */ {AML_LGREATER_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* LLessOp - 0x95 */ {AML_LLESS_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ToBufferOp - 0x96 */ {AML_TO_BUFFER_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ToDecimalStringOp - 0x97 */ {AML_TO_DEC_STRING_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ToHexStringOp - 0x98 */ {AML_TO_HEX_STRING_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ToIntegerOp - 0x99 */ {AML_TO_INTEGER_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ToStringOp - 0x9C */ {AML_TO_STRING_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* CopyObjectOp - 0x9D */ {AML_COPY_OBJECT_OP, 0, 2, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* MidOp - 0x9E */ {AML_MID_OP, 0, 3, AML_OBJECT, AML_OBJECT, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ContinueOp - 0x9F */ {AML_CONTINUE_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* IfOp - 0xA0 */ {AML_IF_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ},
+/* ElseOp - 0xA1 */ {AML_ELSE_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ},
+/* WhileOp - 0xA2 */ {AML_WHILE_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_HAS_PKG_LENGTH | AML_HAS_CHILD_OBJ},
+/* NoopOp - 0xA3 */ {AML_NOOP_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* ReturnOp - 0xA4 */ {AML_RETURN_OP, 0, 1, AML_OBJECT, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* BreakOp - 0xA5 */ {AML_BREAK_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* BreakPointOp - 0xCC */ {AML_BREAK_POINT_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+/* OnesOp - 0xFF */ {AML_ONES_OP, 0, 0, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, AML_NONE, 0},
+};
+
+GLOBAL_REMOVE_IF_UNREFERENCED
+EFI_ACPI_DATA_TYPE mAmlTypeToAcpiType[] = {
+ EFI_ACPI_DATA_TYPE_NONE, // AML_NONE
+ EFI_ACPI_DATA_TYPE_OPCODE, // AML_OPCODE
+ EFI_ACPI_DATA_TYPE_UINT, // AML_UINT8
+ EFI_ACPI_DATA_TYPE_UINT, // AML_UINT16
+ EFI_ACPI_DATA_TYPE_UINT, // AML_UINT32
+ EFI_ACPI_DATA_TYPE_UINT, // AML_UINT64
+ EFI_ACPI_DATA_TYPE_NAME_STRING, // AML_NAME
+ EFI_ACPI_DATA_TYPE_STRING, // AML_STRING
+ EFI_ACPI_DATA_TYPE_CHILD // AML_OBJECT
+};
+
+/**
+ This function returns AmlByteEncoding according to OpCode Byte.
+
+ @param[in] OpByteBuffer OpCode byte buffer.
+
+ @return AmlByteEncoding
+**/
+AML_BYTE_ENCODING *
+AmlSearchByOpByte (
+ IN UINT8 *OpByteBuffer
+ )
+{
+ UINT8 OpCode;
+ UINT8 SubOpCode;
+ UINTN Index;
+
+ //
+ // Get OpCode and SubOpCode
+ //
+ OpCode = OpByteBuffer[0];
+ if (OpCode == AML_EXT_OP) {
+ SubOpCode = OpByteBuffer[1];
+ } else {
+ SubOpCode = 0;
+ }
+
+ //
+ // Search the table
+ //
+ for (Index = 0; Index < sizeof(mAmlByteEncoding)/sizeof(mAmlByteEncoding[0]); Index++) {
+ if ((mAmlByteEncoding[Index].OpCode == OpCode) && (mAmlByteEncoding[Index].SubOpCode == SubOpCode)) {
+ return &mAmlByteEncoding[Index];
+ }
+ }
+
+ return NULL;
+}
+
+/**
+ This function returns AcpiDataType according to AmlType.
+
+ @param[in] AmlType AML Type.
+
+ @return AcpiDataType
+**/
+EFI_ACPI_DATA_TYPE
+AmlTypeToAcpiType (
+ IN AML_OP_PARSE_FORMAT AmlType
+ )
+{
+ if (AmlType >= sizeof(mAmlTypeToAcpiType)/sizeof(mAmlTypeToAcpiType[0])) {
+ ASSERT(FALSE);
+ return EFI_ACPI_DATA_TYPE_NONE;
+ }
+ return mAmlTypeToAcpiType [AmlType];
+}
+
+/**
+ This function retuns package length from the buffer.
+
+ @param[in] Buffer AML buffer
+ @param[out] PkgLength The total length of package.
+
+ @return The byte data count to present the package length.
+**/
+UINTN
+AmlGetPkgLength (
+ IN UINT8 *Buffer,
+ OUT UINTN *PkgLength
+ )
+{
+ UINT8 LeadByte;
+ UINT8 ByteCount;
+ UINTN RealLength;
+ UINTN Offset;
+
+ //
+ // <bit 7-6: ByteData count that follows (0-3)>
+ // <bit 5-4: Only used if PkgLength < 63>
+ // <bit 3-0: Least significant package length nybble>
+ //
+ // Note: The high 2 bits of the first byte reveal how many follow bytes are in the
+ // If the PkgLength has only one byte, bit 0 through 5 are used to encode the
+ // package length (in other words, values 0-63). If the package length value is more than
+ // 63, more than one byte must be used for the encoding in which case bit 4 and 5 of the
+ // PkgLeadByte are reserved and must be zero. If the multiple bytes encoding is used,
+ // bits 0-3 of the PkgLeadByte become the least significant 4 bits of the resulting
+ // package length value. The next ByteData will become the next least significant 8 bits
+ // of the resulting value and so on, up to 3 ByteData bytes. Thus, the maximum package
+ // length is 2**28.
+ //
+
+ LeadByte = *Buffer;
+ ByteCount = (UINT8)((LeadByte >> 6) & 0x03);
+ Offset = ByteCount + 1;
+ RealLength = 0;
+
+ switch (ByteCount) {
+ case 0:
+ RealLength = (UINT32)LeadByte;
+ break;
+ case 1:
+ RealLength = *(Buffer + 1);
+ RealLength = (RealLength << 4) | (LeadByte & 0xF);
+ break;
+ case 2:
+ RealLength = *(Buffer + 1);
+ RealLength |= (*(Buffer + 2)) << 8;
+ RealLength = (RealLength << 4) | (LeadByte & 0xF);
+ break;
+ case 3:
+ RealLength = *(Buffer + 1);
+ RealLength |= (*(Buffer + 2)) << 8;
+ RealLength |= (*(Buffer + 3)) << 16;
+ RealLength = (RealLength << 4) | (LeadByte & 0xF);
+ break;
+ default:
+ ASSERT (0);
+ break;
+ }
+
+ *PkgLength = RealLength;
+ return Offset;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AmlChild.c b/Core/EM/ACPI/AmlChild.c
new file mode 100644
index 0000000..1c6ecc2
--- /dev/null
+++ b/Core/EM/ACPI/AmlChild.c
@@ -0,0 +1,326 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AmlChild.c 2 5/14/11 2:10p Yakovlevs $
+//
+// $Revision: 2 $
+//
+// $Date: 5/14/11 2:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AmlChild.c $
+//
+// 2 5/14/11 2:10p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmlChild.c
+//
+// Description:
+// ACPI AML Name space parsing/manipulation functions for ACPI SDT.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "AcpiCore.h"
+
+/**
+ Return the child objects buffer from AML Handle's buffer.
+
+ @param[in] AmlParentHandle Parent handle.
+ @param[in] CurrentBuffer The current child buffer.
+ @param[out] Buffer On return, points to the next returned child buffer or NULL if there are no
+ child buffer.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER AmlParentHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromObjectBuffer (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN UINT8 *CurrentBuffer,
+ OUT VOID **Buffer
+ )
+{
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ UINTN DataSize;
+
+ //
+ // Root is considered as SCOPE, which has TermList.
+ // We need return only Object in TermList.
+ //
+ while ((UINTN)CurrentBuffer < (UINTN)(AmlParentHandle->Buffer + AmlParentHandle->Size)) {
+ AmlByteEncoding = AmlSearchByOpByte (CurrentBuffer);
+ if (AmlByteEncoding == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // NOTE: We need return everything, because user might need parse the returned object.
+ //
+ if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) == 0) {
+ *Buffer = CurrentBuffer;
+ return EFI_SUCCESS;
+ }
+
+ DataSize = AmlGetObjectSize (
+ AmlByteEncoding,
+ CurrentBuffer,
+ (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size - (UINTN)CurrentBuffer
+ );
+ if (DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ CurrentBuffer += DataSize;
+ }
+
+ //
+ // No more
+ //
+ *Buffer = NULL;
+ return EFI_SUCCESS;
+}
+
+/**
+ Return the child ACPI objects from Root Handle.
+
+ @param[in] AmlParentHandle Parent handle. It is Root Handle.
+ @param[in] AmlHandle The previously returned handle or NULL to start with the first handle.
+ @param[out] Buffer On return, points to the next returned ACPI handle or NULL if there are no
+ child objects.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromRoot (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT VOID **Buffer
+ )
+{
+ UINT8 *CurrentBuffer;
+
+ if (AmlHandle == NULL) {
+ //
+ // First One
+ //
+ CurrentBuffer = (VOID *)AmlParentHandle->Buffer;
+ } else {
+ CurrentBuffer = (VOID *)(AmlHandle->Buffer + AmlHandle->Size);
+ }
+
+ return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
+}
+
+/**
+ Return the child objects buffer from AML Handle's option list.
+
+ @param[in] AmlParentHandle Parent handle.
+ @param[in] AmlHandle The current child handle.
+ @param[out] Buffer On return, points to the next returned child buffer or NULL if there are no
+ child buffer.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER AmlParentHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromOptionList (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT VOID **Buffer
+ )
+{
+ EFI_ACPI_DATA_TYPE DataType;
+ VOID *Data;
+ UINTN DataSize;
+ AML_OP_PARSE_INDEX Index;
+ EFI_STATUS Status;
+ AML_OP_PARSE_INDEX MaxTerm;
+
+ Index = AML_OP_PARSE_INDEX_GET_TERM1;
+ MaxTerm = AmlParentHandle->AmlByteEncoding->MaxIndex;
+ while (Index <= MaxTerm) {
+ Status = AmlParseOptionHandleCommon (
+ AmlParentHandle,
+ (AML_OP_PARSE_INDEX)Index,
+ &DataType,
+ (VOID **)&Data,
+ &DataSize
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (DataType == EFI_ACPI_DATA_TYPE_NONE) {
+ //
+ // Not found
+ //
+ break;
+ }
+
+ //
+ // Find it, and Check Data
+ //
+ if ((DataType == EFI_ACPI_DATA_TYPE_CHILD) &&
+ ((UINTN)AmlHandle->Buffer < (UINTN)Data)) {
+ //
+ // Buffer < Data means current node is next one
+ //
+ *Buffer = Data;
+ return EFI_SUCCESS;
+ }
+ //
+ // Not Child
+ //
+ Index ++;
+ }
+
+ *Buffer = NULL;
+ return EFI_SUCCESS;
+}
+
+/**
+ Return the child objects buffer from AML Handle's object child list.
+
+ @param[in] AmlParentHandle Parent handle.
+ @param[in] AmlHandle The current child handle.
+ @param[out] Buffer On return, points to the next returned child buffer or NULL if there are no
+ child buffer.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER AmlParentHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromObjectChildList (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT VOID **Buffer
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *CurrentBuffer;
+
+ if ((AmlParentHandle->AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
+ //
+ // No ObjectList
+ //
+ *Buffer = NULL;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Do we need add node within METHOD?
+ // Yes, just add Object is OK. But we need filter NameString for METHOD invoke.
+ //
+
+ //
+ // Now, we get the last node.
+ //
+ Status = AmlGetOffsetAfterLastOption (AmlParentHandle, &CurrentBuffer);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Go through all the reset buffer.
+ //
+ if ((UINTN)AmlHandle->Buffer < (UINTN)CurrentBuffer) {
+ //
+ // Buffer < Data means next node is first object
+ //
+ } else if ((UINTN)AmlHandle->Buffer + AmlHandle->Size < (UINTN)AmlParentHandle->Buffer + AmlParentHandle->Size) {
+ //
+ // There is still more node
+ //
+ CurrentBuffer = AmlHandle->Buffer + AmlHandle->Size;
+ } else {
+ //
+ // No more data
+ //
+ *Buffer = NULL;
+ return EFI_SUCCESS;
+ }
+
+ return AmlGetChildFromObjectBuffer (AmlParentHandle, CurrentBuffer, Buffer);
+}
+
+/**
+ Return the child ACPI objects from Non-Root Handle.
+
+ @param[in] AmlParentHandle Parent handle. It is Non-Root Handle.
+ @param[in] AmlHandle The previously returned handle or NULL to start with the first handle.
+ @param[out] Buffer On return, points to the next returned ACPI handle or NULL if there are no
+ child objects.
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER ParentHandle is NULL or does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetChildFromNonRoot (
+ IN EFI_AML_HANDLE *AmlParentHandle,
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT VOID **Buffer
+ )
+{
+ EFI_STATUS Status;
+
+ if (AmlHandle == NULL) {
+ //
+ // NULL means first one
+ //
+ AmlHandle = AmlParentHandle;
+ }
+
+ //
+ // 1. Get Option
+ //
+ Status = AmlGetChildFromOptionList (AmlParentHandle, AmlHandle, Buffer);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (*Buffer != NULL) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // 2. search ObjectList
+ //
+ return AmlGetChildFromObjectChildList (AmlParentHandle, AmlHandle, Buffer);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AmlNamespace.c b/Core/EM/ACPI/AmlNamespace.c
new file mode 100644
index 0000000..2c72400
--- /dev/null
+++ b/Core/EM/ACPI/AmlNamespace.c
@@ -0,0 +1,659 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AmlNamespace.c 2 5/14/11 2:11p Yakovlevs $
+//
+// $Revision: 2 $
+//
+// $Date: 5/14/11 2:11p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AmlNamespace.c $
+//
+// 2 5/14/11 2:11p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmlNamespace.c
+//
+// Description:
+// ACPI AML Name space parsing/manipulation functions for ACPI SDT.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "AcpiCore.h"
+
+/**
+ Construct node list according to the AML handle.
+
+ @param[in] AmlHandle AML handle.
+ @param[in] AmlRootNodeList AML root node list.
+ @param[in] AmlParentNodeList AML parent node list.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlConstructNodeList (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN EFI_AML_NODE_LIST *AmlRootNodeList,
+ IN EFI_AML_NODE_LIST *AmlParentNodeList
+ );
+
+/**
+ Create AML Node.
+
+ @param[in] NameSeg AML NameSeg.
+ @param[in] Parent AML parent node list.
+ @param[in] AmlByteEncoding AML Byte Encoding.
+
+ @return AML Node.
+**/
+EFI_AML_NODE_LIST *
+AmlCreateNode (
+ IN UINT8 *NameSeg,
+ IN EFI_AML_NODE_LIST *Parent,
+ IN AML_BYTE_ENCODING *AmlByteEncoding
+ )
+{
+ EFI_AML_NODE_LIST *AmlNodeList;
+
+ AmlNodeList = Malloc(sizeof(*AmlNodeList));
+ ASSERT (AmlNodeList != NULL);
+
+ AmlNodeList->Signature = EFI_AML_NODE_LIST_SIGNATURE;
+ pBS->CopyMem (AmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE);
+ AmlNodeList->Buffer = NULL;
+ AmlNodeList->Size = 0;
+ InitializeListHead (&AmlNodeList->Link);
+ InitializeListHead (&AmlNodeList->Children);
+ AmlNodeList->Parent = Parent;
+ AmlNodeList->AmlByteEncoding = AmlByteEncoding;
+
+ return AmlNodeList;
+}
+
+/**
+ Find the AML NameSeg in the children of AmlParentNodeList.
+
+ @param[in] NameSeg AML NameSeg.
+ @param[in] AmlParentNodeList AML parent node list.
+ @param[in] Create TRUE means to create node if not found.
+
+ @return AmlChildNode whoes name is same as NameSeg.
+**/
+EFI_AML_NODE_LIST *
+AmlFindNodeInThis (
+ IN UINT8 *NameSeg,
+ IN EFI_AML_NODE_LIST *AmlParentNodeList,
+ IN BOOLEAN Create
+ )
+{
+ EFI_AML_NODE_LIST *CurrentAmlNodeList;
+ LIST_ENTRY *CurrentLink;
+ LIST_ENTRY *StartLink;
+ EFI_AML_NODE_LIST *AmlNodeList;
+
+ StartLink = &AmlParentNodeList->Children;
+ CurrentLink = StartLink->ForwardLink;
+
+ while (CurrentLink != StartLink) {
+ CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
+ //
+ // AML name is same as the one stored
+ //
+ if (MemCmp (CurrentAmlNodeList->Name, NameSeg, AML_NAME_SEG_SIZE) == 0) {
+ //
+ // Good! Found it
+ //
+ return CurrentAmlNodeList;
+ }
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ //
+ // Not found
+ //
+ if (!Create) {
+ return NULL;
+ }
+
+ //
+ // Create new node with NULL buffer - it means namespace not be returned.
+ //
+ AmlNodeList = AmlCreateNode (NameSeg, AmlParentNodeList, NULL);
+ InsertTailList (&AmlParentNodeList->Children, &AmlNodeList->Link);
+
+ return AmlNodeList;
+}
+
+/**
+ Find the AML NameString in the children of AmlParentNodeList or AmlRootNodeList.
+
+ @param[in] NameString AML NameString.
+ @param[in] AmlRootNodeList AML root node list.
+ @param[in] AmlParentNodeList AML parent node list.
+ @param[in] Create TRUE means to create node if not found.
+
+ @return AmlChildNode whoes name is same as NameSeg.
+**/
+EFI_AML_NODE_LIST *
+AmlFindNodeInTheTree (
+ IN UINT8 *NameString,
+ IN EFI_AML_NODE_LIST *AmlRootNodeList,
+ IN EFI_AML_NODE_LIST *AmlParentNodeList,
+ IN BOOLEAN Create
+ )
+{
+ UINT8 *Buffer;
+ EFI_AML_NODE_LIST *AmlNodeList;
+ EFI_AML_NODE_LIST *AmlCurrentNodeList;
+ UINT8 Index;
+ UINT8 SegCount;
+
+ Buffer = NameString;
+
+ //
+ // Handle root or parent prefix
+ //
+ if (*Buffer == AML_ROOT_CHAR) {
+ AmlCurrentNodeList = AmlRootNodeList;
+ Buffer += 1;
+ } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
+ AmlCurrentNodeList = AmlParentNodeList;
+ do {
+ if (AmlCurrentNodeList->Parent != NULL) {
+ AmlCurrentNodeList = AmlCurrentNodeList->Parent;
+ } else {
+ //
+ // Only root has no parent
+ //
+ ASSERT (AmlCurrentNodeList == AmlRootNodeList);
+ }
+ Buffer += 1;
+ } while (*Buffer == AML_PARENT_PREFIX_CHAR);
+ } else {
+ AmlCurrentNodeList = AmlParentNodeList;
+ }
+
+ //
+ // Handle name segment
+ //
+ if (*Buffer == AML_DUAL_NAME_PREFIX) {
+ Buffer += 1;
+ SegCount = 2;
+ } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
+ Buffer += 1;
+ SegCount = *Buffer;
+ Buffer += 1;
+ } else if (*Buffer == 0) {
+ //
+ // NULL name, only for Root
+ //
+ ASSERT (AmlCurrentNodeList == AmlRootNodeList);
+ return AmlCurrentNodeList;
+ } else {
+ SegCount = 1;
+ }
+
+ //
+ // Handle NamePath
+ //
+ Index = 0;
+ do {
+ AmlNodeList = AmlFindNodeInThis (Buffer, AmlCurrentNodeList, Create);
+ if (AmlNodeList == NULL) {
+ return NULL;
+ }
+ AmlCurrentNodeList = AmlNodeList;
+ Buffer += AML_NAME_SEG_SIZE;
+ Index ++;
+ } while (Index < SegCount);
+
+ return AmlNodeList;
+}
+
+/**
+ Insert the NameString to the AmlNodeList.
+
+ @param[in] NameString AML NameString.
+ @param[in] Buffer Buffer for the Node.
+ @param[in] Size Size for the Node.
+ @param[in] AmlRootNodeList AML root node list.
+ @param[in] AmlParentNodeList AML parent node list.
+
+ @return AmlChildNode whoes name is NameString.
+**/
+EFI_AML_NODE_LIST *
+AmlInsertNodeToTree (
+ IN UINT8 *NameString,
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN EFI_AML_NODE_LIST *AmlRootNodeList,
+ IN EFI_AML_NODE_LIST *AmlParentNodeList
+ )
+{
+ EFI_AML_NODE_LIST *AmlNodeList;
+
+ AmlNodeList = AmlFindNodeInTheTree (
+ NameString,
+ AmlRootNodeList,
+ AmlParentNodeList,
+ TRUE // Find and Create
+ );
+ ASSERT (AmlNodeList != NULL);
+ if (AmlNodeList == NULL) {
+ return NULL;
+ }
+
+ //
+ // Check buffer
+ //
+ if (AmlNodeList->Buffer == NULL) {
+ //
+ // NULL means new added one or SCOPE_OP
+ //
+ if (*(UINT8 *)Buffer != AML_SCOPE_OP) {
+ //
+ // We need check if new one is SCOPE_OP, because SCOPE_OP just means namespace, not a real device.
+ // We should not return SCOPE_OP.
+ //
+ AmlNodeList->Buffer = Buffer;
+ AmlNodeList->Size = Size;
+ AmlNodeList->AmlByteEncoding = AmlSearchByOpByte (Buffer);
+ }
+ return AmlNodeList;
+ }
+
+ //
+ // Already added
+ //
+ if (*(UINT8 *)Buffer == AML_SCOPE_OP) {
+ //
+ // The new one is SCOPE_OP, OK just return;
+ //
+ return AmlNodeList;
+ }
+
+ //
+ // Oops!!!, There must be something wrong.
+ //
+ TRACE ((-1, "AML: Override Happen - %a!\n", NameString));
+ TRACE ((-1, "AML: Existing Node - %x\n", AmlNodeList->Buffer));
+ TRACE ((-1, "AML: New Buffer - %x\n", Buffer));
+
+ return NULL;
+}
+
+/**
+ Construct child node list according to the AML handle.
+
+ @param[in] AmlHandle AML handle.
+ @param[in] AmlRootNodeList AML root node list.
+ @param[in] AmlParentNodeList AML parent node list.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlConstructNodeListForChild (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN EFI_AML_NODE_LIST *AmlRootNodeList,
+ IN EFI_AML_NODE_LIST *AmlParentNodeList
+ )
+{
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ UINT8 *CurrentBuffer;
+ EFI_AML_HANDLE *AmlChildHandle;
+ EFI_STATUS Status;
+
+ AmlByteEncoding = AmlHandle->AmlByteEncoding;
+ Buffer = AmlHandle->Buffer;
+ BufferSize = AmlHandle->Size;
+
+ //
+ // Check if we need recursively add node
+ //
+ if ((AmlByteEncoding->Attribute & AML_HAS_CHILD_OBJ) == 0) {
+ //
+ // No more node need to be added
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Do we need add node within METHOD?
+ // Yes, just add Object is OK. But we need filter NameString for METHOD invoke.
+ //
+
+ //
+ // Now, we get the last node.
+ //
+ Status = AmlGetOffsetAfterLastOption (AmlHandle, &CurrentBuffer);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Go through all the reset buffer.
+ //
+ while ((UINTN)CurrentBuffer < (UINTN)Buffer + BufferSize) {
+ //
+ // Find the child node.
+ //
+ Status = SdtOpenEx (CurrentBuffer, (UINTN)Buffer + BufferSize - (UINTN)CurrentBuffer, (EFI_ACPI_HANDLE *)&AmlChildHandle);
+ if (EFI_ERROR (Status)) {
+ //
+ // No child found, break now.
+ //
+ break;
+ }
+
+ //
+ // Good, find the child. Construct node recursively
+ //
+ Status = AmlConstructNodeList (
+ AmlChildHandle,
+ AmlRootNodeList,
+ AmlParentNodeList
+ );
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // Parse next one
+ //
+ CurrentBuffer += AmlChildHandle->Size;
+
+ Close ((EFI_ACPI_HANDLE)AmlChildHandle);
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Construct node list according to the AML handle.
+
+ @param[in] AmlHandle AML handle.
+ @param[in] AmlRootNodeList AML root node list.
+ @param[in] AmlParentNodeList AML parent node list.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AML handle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlConstructNodeList (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN EFI_AML_NODE_LIST *AmlRootNodeList,
+ IN EFI_AML_NODE_LIST *AmlParentNodeList
+ )
+{
+ VOID *NameString;
+ EFI_AML_NODE_LIST *AmlNodeList;
+
+ //
+ // 1. Check if there is need to construct node for this OpCode.
+ //
+ if ((AmlHandle->AmlByteEncoding->Attribute & AML_IN_NAMESPACE) == 0) {
+ //
+ // No need to construct node, so we just skip this OpCode.
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // 2. Now, we need construct node for this OpCode.
+ //
+ NameString = AmlGetObjectName (AmlHandle);
+ if (NameString == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Now, we need to insert node to the node list.
+ // NOTE: The name here could be AML NameString. So the callee need parse it.
+ //
+ AmlNodeList = AmlInsertNodeToTree (NameString, AmlHandle->Buffer, AmlHandle->Size, AmlRootNodeList, AmlParentNodeList);
+ ASSERT (AmlNodeList != NULL);
+
+ //
+ // 3. Ok, we need to parse the object list to see if there are more node to be added.
+ //
+ return AmlConstructNodeListForChild (AmlHandle, AmlRootNodeList, AmlNodeList);
+}
+
+/**
+ Destruct node list
+
+ @param[in] AmlParentNodeList AML parent node list.
+**/
+VOID
+AmlDestructNodeList (
+ IN EFI_AML_NODE_LIST *AmlParentNodeList
+ )
+{
+ EFI_AML_NODE_LIST *CurrentAmlNodeList;
+ LIST_ENTRY *CurrentLink;
+ LIST_ENTRY *StartLink;
+
+ //
+ // Get the children link
+ //
+ StartLink = &AmlParentNodeList->Children;
+ CurrentLink = StartLink->ForwardLink;
+
+ //
+ // Go through all the children
+ //
+ while (CurrentLink != StartLink) {
+ //
+ // Destruct the child's list recursively
+ //
+ CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
+ CurrentLink = CurrentLink->ForwardLink;
+
+ //
+ // Remove this child from list and free the node
+ //
+ RemoveEntryList (&(CurrentAmlNodeList->Link));
+
+ AmlDestructNodeList (CurrentAmlNodeList);
+ }
+
+ //
+ // Done.
+ //
+ pBS->FreePool (AmlParentNodeList);
+ return ;
+}
+
+/**
+ Dump node list
+
+ @param[in] AmlParentNodeList AML parent node list.
+ @param[in] Level Output debug level.
+**/
+VOID
+AmlDumpNodeInfo (
+ IN EFI_AML_NODE_LIST *AmlParentNodeList,
+ IN UINTN Level
+ )
+{
+ EFI_AML_NODE_LIST *CurrentAmlNodeList;
+ volatile LIST_ENTRY *CurrentLink;
+ UINTN Index;
+
+ CurrentLink = AmlParentNodeList->Children.ForwardLink;
+
+ if (Level == 0) {
+ TRACE ((-1, "\\"));
+ } else {
+ for (Index = 0; Index < Level; Index++) {
+ TRACE ((-1, " "));
+ }
+ AmlPrintNameSeg (AmlParentNodeList->Name);
+ }
+ TRACE ((-1, "\n"));
+
+ while (CurrentLink != &AmlParentNodeList->Children) {
+ CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
+ AmlDumpNodeInfo (CurrentAmlNodeList, Level + 1);
+ CurrentLink = CurrentLink->ForwardLink;
+ }
+
+ return ;
+}
+
+/**
+ Returns the handle of the ACPI object representing the specified ACPI AML path
+
+ @param[in] AmlHandle Points to the handle of the object representing the starting point for the path search.
+ @param[in] AmlPath Points to the ACPI AML path.
+ @param[out] Buffer On return, points to the ACPI object which represents AcpiPath, relative to
+ HandleIn.
+ @param[in] FromRoot TRUE means to find AML path from \ (Root) Node.
+ FALSE means to find AML path from this Node (The HandleIn).
+
+ @retval EFI_SUCCESS Success
+ @retval EFI_INVALID_PARAMETER HandleIn does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlFindPath (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN UINT8 *AmlPath,
+ OUT VOID **Buffer,
+ IN BOOLEAN FromRoot
+ )
+{
+ EFI_AML_NODE_LIST *AmlRootNodeList;
+ EFI_STATUS Status;
+ EFI_AML_NODE_LIST *AmlNodeList;
+ UINT8 RootNameSeg[AML_NAME_SEG_SIZE];
+ EFI_AML_NODE_LIST *CurrentAmlNodeList;
+ LIST_ENTRY *CurrentLink;
+
+ //
+ // 1. create tree
+ //
+
+ //
+ // Create root handle
+ //
+ RootNameSeg[0] = AML_ROOT_CHAR;
+ RootNameSeg[1] = 0;
+ AmlRootNodeList = AmlCreateNode (RootNameSeg, NULL, AmlHandle->AmlByteEncoding);
+
+ Status = AmlConstructNodeList (
+ AmlHandle,
+ AmlRootNodeList, // Root
+ AmlRootNodeList // Parent
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if EFI_DEBUG
+ TRACE ((-1, "AcpiSdt: NameSpace:\n"));
+ AmlDumpNodeInfo (AmlRootNodeList, 0);
+#endif
+ //
+ // 2. Search the node in the tree
+ //
+ if (FromRoot) {
+ //
+ // Search from Root
+ //
+ CurrentAmlNodeList = AmlRootNodeList;
+ } else {
+ //
+ // Search from this node, NOT ROOT.
+ // Since we insert node to ROOT one by one, we just get the first node and search from it.
+ //
+ CurrentLink = AmlRootNodeList->Children.ForwardLink;
+ if (CurrentLink != &AmlRootNodeList->Children) {
+ //
+ // First node
+ //
+ CurrentAmlNodeList = EFI_AML_NODE_LIST_FROM_LINK (CurrentLink);
+ } else {
+ //
+ // No child
+ //
+ CurrentAmlNodeList = NULL;
+ }
+ }
+
+ //
+ // Search
+ //
+ if (CurrentAmlNodeList != NULL) {
+#if EFI_DEBUG
+ TRACE ((-1, "AcpiSdt: Search from: \\"));
+ AmlPrintNameSeg (CurrentAmlNodeList->Name);
+ TRACE ((-1, "\n"));
+#endif
+ AmlNodeList = AmlFindNodeInTheTree (
+ AmlPath,
+ AmlRootNodeList, // Root
+ CurrentAmlNodeList, // Parent
+ FALSE
+ );
+ } else {
+ AmlNodeList = NULL;
+ }
+
+ *Buffer = NULL;
+ Status = EFI_SUCCESS;
+ if (AmlNodeList != NULL && AmlNodeList->Buffer != NULL) {
+ *Buffer = AmlNodeList->Buffer;
+ }
+
+ //
+ // 3. free the tree
+ //
+ AmlDestructNodeList (AmlRootNodeList);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AmlOption.c b/Core/EM/ACPI/AmlOption.c
new file mode 100644
index 0000000..55ef7f7
--- /dev/null
+++ b/Core/EM/ACPI/AmlOption.c
@@ -0,0 +1,500 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AmlOption.c 2 5/14/11 2:12p Yakovlevs $
+//
+// $Revision: 2 $
+//
+// $Date: 5/14/11 2:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AmlOption.c $
+//
+// 2 5/14/11 2:12p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmlOption.c
+//
+// Description:
+// ACPI AML Name space parsing/manipulation functions for ACPI SDT.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "AcpiCore.h"
+
+/**
+ Retrieve option term according to AmlByteEncoding and Buffer.
+
+ @param[in] AmlByteEncoding AML Byte Encoding.
+ @param[in] Buffer AML buffer.
+ @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region.
+ @param[in] TermIndex Index of the data to retrieve from the object.
+ @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
+ for the specified index.
+ @param[out] Data Upon return, points to the pointer to the data.
+ @param[out] DataSize Upon return, points to the size of Data.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlParseOptionTerm (
+ IN AML_BYTE_ENCODING *AmlByteEncoding,
+ IN UINT8 *Buffer,
+ IN UINTN MaxBufferSize,
+ IN AML_OP_PARSE_INDEX TermIndex,
+ OUT EFI_ACPI_DATA_TYPE *DataType,
+ OUT VOID **Data,
+ OUT UINTN *DataSize
+ )
+{
+ AML_BYTE_ENCODING *ChildAmlByteEncoding;
+ EFI_STATUS Status;
+
+ if (DataType != NULL) {
+ *DataType = AmlTypeToAcpiType (AmlByteEncoding->Format[TermIndex - 1]);
+ }
+ if (Data != NULL) {
+ *Data = Buffer;
+ }
+ //
+ // Parse term according to AML type
+ //
+ switch (AmlByteEncoding->Format[TermIndex - 1]) {
+ case AML_UINT8:
+ *DataSize = sizeof(UINT8);
+ break;
+ case AML_UINT16:
+ *DataSize = sizeof(UINT16);
+ break;
+ case AML_UINT32:
+ *DataSize = sizeof(UINT32);
+ break;
+ case AML_UINT64:
+ *DataSize = sizeof(UINT64);
+ break;
+ case AML_STRING:
+ *DataSize = (Strlen((CHAR8 *)Buffer)+1);
+ break;
+ case AML_NAME:
+ Status = AmlGetNameStringSize (Buffer, DataSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ case AML_OBJECT:
+ ChildAmlByteEncoding = AmlSearchByOpByte (Buffer);
+ if (ChildAmlByteEncoding == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // NOTE: We need override DataType here, if there is a case the AML_OBJECT is AML_NAME.
+ // We need convert type from EFI_ACPI_DATA_TYPE_CHILD to EFI_ACPI_DATA_TYPE_NAME_STRING.
+ // We should not return CHILD because there is NO OpCode for NameString.
+ //
+ if ((ChildAmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) {
+ if (DataType != NULL) {
+ *DataType = AmlTypeToAcpiType (AML_NAME);
+ }
+ Status = AmlGetNameStringSize (Buffer, DataSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ }
+
+ //
+ // It is real AML_OBJECT
+ //
+ *DataSize = AmlGetObjectSize (
+ ChildAmlByteEncoding,
+ Buffer,
+ MaxBufferSize
+ );
+ if (*DataSize == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ break;
+ case AML_NONE:
+ //
+ // No term
+ //
+ case AML_OPCODE:
+ default:
+ ASSERT (FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+ if (*DataSize > MaxBufferSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve information according to AmlByteEncoding and Buffer.
+
+ @param[in] AmlByteEncoding AML Byte Encoding.
+ @param[in] Buffer AML buffer.
+ @param[in] MaxBufferSize AML buffer MAX size. The parser can not parse any data exceed this region.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
+ for the specified index.
+ @param[out] Data Upon return, points to the pointer to the data.
+ @param[out] DataSize Upon return, points to the size of Data.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlParseOptionCommon (
+ IN AML_BYTE_ENCODING *AmlByteEncoding,
+ IN UINT8 *Buffer,
+ IN UINTN MaxBufferSize,
+ IN AML_OP_PARSE_INDEX Index,
+ OUT EFI_ACPI_DATA_TYPE *DataType,
+ OUT VOID **Data,
+ OUT UINTN *DataSize
+ )
+{
+ UINT8 *CurrentBuffer;
+ UINTN PkgLength;
+ UINTN OpLength;
+ UINTN PkgOffset;
+ AML_OP_PARSE_INDEX TermIndex;
+ EFI_STATUS Status;
+
+ ASSERT ((Index <= AmlByteEncoding->MaxIndex) || (Index == AML_OP_PARSE_INDEX_GET_SIZE));
+
+ //
+ // 0. Check if this is NAME string.
+ //
+ if ((AmlByteEncoding->Attribute & AML_IS_NAME_CHAR) != 0) {
+ //
+ // Only allow GET_SIZE
+ //
+ if (Index != AML_OP_PARSE_INDEX_GET_SIZE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // return NameString size
+ //
+ Status = AmlGetNameStringSize (Buffer, DataSize);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (*DataSize > MaxBufferSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Not NAME string, start parsing
+ //
+ CurrentBuffer = Buffer;
+
+ //
+ // 1. Get OpCode
+ //
+ if (Index != AML_OP_PARSE_INDEX_GET_SIZE) {
+ *DataType = EFI_ACPI_DATA_TYPE_OPCODE;
+ *Data = (VOID *)CurrentBuffer;
+ }
+ if (*CurrentBuffer == AML_EXT_OP) {
+ OpLength = 2;
+ } else {
+ OpLength = 1;
+ }
+ *DataSize = OpLength;
+ if (Index == AML_OP_PARSE_INDEX_GET_OPCODE) {
+ return EFI_SUCCESS;
+ }
+ if (OpLength > MaxBufferSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+ CurrentBuffer += OpLength;
+
+ //
+ // 2. Skip PkgLength field, if have
+ //
+ if ((AmlByteEncoding->Attribute & AML_HAS_PKG_LENGTH) != 0) {
+ PkgOffset = AmlGetPkgLength(CurrentBuffer, &PkgLength);
+ //
+ // Override MaxBufferSize if it is valid PkgLength
+ //
+ if (OpLength + PkgLength > MaxBufferSize) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ MaxBufferSize = OpLength + PkgLength;
+ }
+ } else {
+ PkgOffset = 0;
+ PkgLength = 0;
+ }
+ CurrentBuffer += PkgOffset;
+
+ //
+ // 3. Get Term one by one.
+ //
+ TermIndex = AML_OP_PARSE_INDEX_GET_TERM1;
+ while ((Index >= TermIndex) && (TermIndex <= AmlByteEncoding->MaxIndex) && ((UINTN)CurrentBuffer < (UINTN)Buffer + MaxBufferSize)) {
+ Status = AmlParseOptionTerm (
+ AmlByteEncoding,
+ CurrentBuffer,
+ (UINTN)Buffer + MaxBufferSize - (UINTN)CurrentBuffer,
+ TermIndex,
+ DataType,
+ Data,
+ DataSize
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Index == TermIndex) {
+ //
+ // Done
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Parse next one
+ //
+ CurrentBuffer += *DataSize;
+ TermIndex ++;
+ }
+
+ //
+ // Finish all options, but no option found.
+ //
+ if ((UINTN)CurrentBuffer > (UINTN)Buffer + MaxBufferSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if ((UINTN)CurrentBuffer == (UINTN)Buffer + MaxBufferSize) {
+ if (Index != AML_OP_PARSE_INDEX_GET_SIZE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // 4. Finish parsing all node, return size
+ //
+ ASSERT (Index == AML_OP_PARSE_INDEX_GET_SIZE);
+ if ((AmlByteEncoding->Attribute & AML_HAS_PKG_LENGTH) != 0) {
+ *DataSize = OpLength + PkgLength;
+ } else {
+ *DataSize = (UINTN)CurrentBuffer - (UINTN)Buffer;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Return object size.
+
+ @param[in] AmlByteEncoding AML Byte Encoding.
+ @param[in] Buffer AML object buffer.
+ @param[in] MaxBufferSize AML object buffer MAX size. The parser can not parse any data exceed this region.
+
+ @return Size of the object.
+**/
+UINTN
+AmlGetObjectSize (
+ IN AML_BYTE_ENCODING *AmlByteEncoding,
+ IN UINT8 *Buffer,
+ IN UINTN MaxBufferSize
+ )
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+
+ Status = AmlParseOptionCommon (
+ AmlByteEncoding,
+ Buffer,
+ MaxBufferSize,
+ AML_OP_PARSE_INDEX_GET_SIZE,
+ NULL,
+ NULL,
+ &DataSize
+ );
+ if (EFI_ERROR (Status)) {
+ return 0;
+ } else {
+ return DataSize;
+ }
+}
+
+/**
+ Return object name.
+
+ @param[in] AmlHandle AML handle.
+
+ @return Name of the object.
+**/
+CHAR8 *
+AmlGetObjectName (
+ IN EFI_AML_HANDLE *AmlHandle
+ )
+{
+ AML_BYTE_ENCODING *AmlByteEncoding;
+ VOID *NameString;
+ UINTN NameSize;
+ AML_OP_PARSE_INDEX TermIndex;
+ EFI_STATUS Status;
+ EFI_ACPI_DATA_TYPE DataType;
+
+ AmlByteEncoding = AmlHandle->AmlByteEncoding;
+
+ ASSERT ((AmlByteEncoding->Attribute & AML_IN_NAMESPACE) != 0);
+
+ //
+ // Find out Last Name index, accroding to OpCode table.
+ // The last name will be the node name by design.
+ //
+ TermIndex = AmlByteEncoding->MaxIndex;
+ for (TermIndex = AmlByteEncoding->MaxIndex; TermIndex > 0; TermIndex--) {
+ if (AmlByteEncoding->Format[TermIndex - 1] == AML_NAME) {
+ break;
+ }
+ }
+ ASSERT (TermIndex != 0);
+
+ //
+ // Get Name for this node.
+ //
+ Status = AmlParseOptionHandleCommon (
+ AmlHandle,
+ TermIndex,
+ &DataType,
+ &NameString,
+ &NameSize
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ ASSERT (DataType == EFI_ACPI_DATA_TYPE_NAME_STRING);
+
+ return NameString;
+}
+
+/**
+ Return offset of last option.
+
+ @param[in] AmlHandle AML Handle.
+ @param[out] Buffer Upon return, points to the offset after last option.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlGetOffsetAfterLastOption (
+ IN EFI_AML_HANDLE *AmlHandle,
+ OUT UINT8 **Buffer
+ )
+{
+ EFI_ACPI_DATA_TYPE DataType;
+ VOID *Data;
+ UINTN DataSize;
+ EFI_STATUS Status;
+
+ Status = AmlParseOptionHandleCommon (
+ AmlHandle,
+ AmlHandle->AmlByteEncoding->MaxIndex,
+ &DataType,
+ &Data,
+ &DataSize
+ );
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // We need to parse the rest buffer after last node.
+ //
+ *Buffer = (UINT8 *)((UINTN)Data + DataSize);
+
+ //
+ // We need skip PkgLength if no Option
+ //
+ if (DataType == EFI_ACPI_DATA_TYPE_OPCODE) {
+ *Buffer += AmlGetPkgLength (*Buffer, &DataSize);
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Retrieve information according to AmlHandle
+
+ @param[in] AmlHandle AML handle.
+ @param[in] Index Index of the data to retrieve from the object. In general, indexes read from left-to-right
+ in the ACPI encoding, with index 0 always being the ACPI opcode.
+ @param[out] DataType Points to the returned data type or EFI_ACPI_DATA_TYPE_NONE if no data exists
+ for the specified index.
+ @param[out] Data Upon return, points to the pointer to the data.
+ @param[out] DataSize Upon return, points to the size of Data.
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER AmlHandle does not refer to a valid ACPI object.
+**/
+EFI_STATUS
+AmlParseOptionHandleCommon (
+ IN EFI_AML_HANDLE *AmlHandle,
+ IN AML_OP_PARSE_INDEX Index,
+ OUT EFI_ACPI_DATA_TYPE *DataType,
+ OUT VOID **Data,
+ OUT UINTN *DataSize
+ )
+{
+ return AmlParseOptionCommon (
+ AmlHandle->AmlByteEncoding,
+ AmlHandle->Buffer,
+ AmlHandle->Size,
+ Index,
+ DataType,
+ Data,
+ DataSize
+ );
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AmlString.c b/Core/EM/ACPI/AmlString.c
new file mode 100644
index 0000000..b3640f3
--- /dev/null
+++ b/Core/EM/ACPI/AmlString.c
@@ -0,0 +1,600 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AmlString.c 3 12/13/12 12:00p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 12/13/12 12:00p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AmlString.c $
+//
+// 3 12/13/12 12:00p Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 2 5/14/11 2:13p Yakovlevs
+// [TAG] EIP 56526
+// [Category] New Feature
+// [Description] ACPI Manipulation Protocol. PI 1.2 Spec Vol 5 Section
+// 9. Initial checkin.
+// [Files] AcpiCore.c; AcpiCore.h; AcpiSdtPrivate.h; Aml.c; AmlChild.c;
+// AmlNamespace.c; AmlOption.c; AmlString.c AcpiSdt.c;
+// Protocol\AcpiSdt.h.
+//
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmlString.c
+//
+// Description:
+// ACPI AML Name space parsing/manipulation functions for ACPI SDT.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "AcpiCore.h"
+
+/**
+ Check if it is AML Root name
+
+ @param[in] Buffer AML path.
+
+ @retval TRUE AML path is root.
+ @retval FALSE AML path is not root.
+**/
+BOOLEAN
+AmlIsRootPath (
+ IN UINT8 *Buffer
+ )
+{
+ if ((Buffer[0] == AML_ROOT_CHAR) && (Buffer[1] == 0)) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Check if it is AML LeadName.
+
+ @param[in] Ch Char.
+
+ @retval TRUE Char is AML LeadName.
+ @retval FALSE Char is not AML LeadName.
+**/
+BOOLEAN
+AmlIsLeadName (
+ IN CHAR8 Ch
+ )
+{
+ if ((Ch == '_') || (Ch >= 'A' && Ch <= 'Z')) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Check if it is AML Name.
+
+ @param[in] Ch Char.
+
+ @retval TRUE Char is AML Name.
+ @retval FALSE Char is not AML Name.
+**/
+BOOLEAN
+AmlIsName (
+ IN CHAR8 Ch
+ )
+{
+ if (AmlIsLeadName (Ch) || (Ch >= '0' && Ch <= '9')) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Return is buffer is AML NameSeg.
+
+ @param[in] Buffer AML NameSement.
+
+ @retval TRUE It is AML NameSegment.
+ @retval FALSE It is not AML NameSegment.
+**/
+BOOLEAN
+AmlIsNameSeg (
+ IN UINT8 *Buffer
+ )
+{
+ UINTN Index;
+ if (!AmlIsLeadName (Buffer[0])) {
+ return FALSE;
+ }
+ for (Index = 1; Index < AML_NAME_SEG_SIZE; Index++) {
+ if (!AmlIsName (Buffer[Index])) {
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/**
+ Get AML NameString size.
+
+ @param[in] Buffer AML NameString.
+ @param[out] BufferSize AML NameString size
+
+ @retval EFI_SUCCESS Success.
+ @retval EFI_INVALID_PARAMETER Buffer does not refer to a valid AML NameString.
+**/
+EFI_STATUS
+AmlGetNameStringSize (
+ IN UINT8 *Buffer,
+ OUT UINTN *BufferSize
+ )
+{
+ UINTN SegCount;
+ UINTN Length;
+ UINTN Index;
+
+ Length = 0;
+
+ //
+ // Parse root or parent prefix
+ //
+ if (*Buffer == AML_ROOT_CHAR) {
+ Buffer ++;
+ Length ++;
+ } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
+ do {
+ Buffer ++;
+ Length ++;
+ } while (*Buffer == AML_PARENT_PREFIX_CHAR);
+ }
+
+ //
+ // Parse name segment
+ //
+ if (*Buffer == AML_DUAL_NAME_PREFIX) {
+ Buffer ++;
+ Length ++;
+ SegCount = 2;
+ } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
+ Buffer ++;
+ Length ++;
+ SegCount = *Buffer;
+ Buffer ++;
+ Length ++;
+ } else if (*Buffer == 0) {
+ //
+ // NULL Name, only for Root
+ //
+ SegCount = 0;
+ Buffer --;
+ if ((Length == 1) && (*Buffer == AML_ROOT_CHAR)) {
+ *BufferSize = 2;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ //
+ // NameSeg
+ //
+ SegCount = 1;
+ }
+
+ Index = 0;
+ do {
+ if (!AmlIsNameSeg (Buffer)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Buffer += AML_NAME_SEG_SIZE;
+ Length += AML_NAME_SEG_SIZE;
+ Index ++;
+ } while (Index < SegCount);
+
+ *BufferSize = Length;
+ return EFI_SUCCESS;
+}
+
+/**
+ Check if it is ASL LeadName.
+
+ @param[in] Ch Char.
+
+ @retval TRUE Char is ASL LeadName.
+ @retval FALSE Char is not ASL LeadName.
+**/
+BOOLEAN
+AmlIsAslLeadName (
+ IN CHAR8 Ch
+ )
+{
+ if (AmlIsLeadName (Ch) || (Ch >= 'a' && Ch <= 'z')) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Check if it is ASL Name.
+
+ @param[in] Ch Char.
+
+ @retval TRUE Char is ASL Name.
+ @retval FALSE Char is not ASL Name.
+**/
+BOOLEAN
+AmlIsAslName (
+ IN CHAR8 Ch
+ )
+{
+ if (AmlIsAslLeadName (Ch) || (Ch >= '0' && Ch <= '9')) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+/**
+ Get ASL NameString size.
+
+ @param[in] Buffer ASL NameString.
+
+ @return ASL NameString size.
+**/
+UINTN
+AmlGetAslNameSegLength (
+ IN UINT8 *Buffer
+ )
+{
+ UINTN Length;
+ UINTN Index;
+
+ if (*Buffer == 0) {
+ return 0;
+ }
+
+ Length = 0;
+ //
+ // 1st
+ //
+ if (AmlIsAslLeadName (*Buffer)) {
+ Length ++;
+ Buffer ++;
+ }
+ if ((*Buffer == 0) || (*Buffer == '.')) {
+ return Length;
+ }
+ //
+ // 2, 3, 4 name char
+ //
+ for (Index = 0; Index < 3; Index++) {
+ if (AmlIsAslName (*Buffer)) {
+ Length ++;
+ Buffer ++;
+ }
+ if ((*Buffer == 0) || (*Buffer == '.')) {
+ return Length;
+ }
+ }
+
+ //
+ // Invalid ASL name
+ //
+ return 0;
+}
+
+/**
+ Get ASL NameString size.
+
+ @param[in] Buffer ASL NameString.
+ @param[out] Root On return, points to Root char number.
+ @param[out] Parent On return, points to Parent char number.
+ @param[out] SegCount On return, points to Segment count.
+
+ @return ASL NameString size.
+**/
+UINTN
+AmlGetAslNameStringSize (
+ IN UINT8 *Buffer,
+ OUT UINTN *Root,
+ OUT UINTN *Parent,
+ OUT UINTN *SegCount
+ )
+{
+ UINTN NameLength;
+ UINTN TotalLength;
+
+ *Root = 0;
+ *Parent = 0;
+ *SegCount = 0;
+ TotalLength = 0;
+ NameLength = 0;
+ if (*Buffer == AML_ROOT_CHAR) {
+ *Root = 1;
+ Buffer ++;
+ } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
+ do {
+ Buffer ++;
+ (*Parent) ++;
+ } while (*Buffer == AML_PARENT_PREFIX_CHAR);
+ }
+
+ //
+ // Now parse name
+ //
+ while (*Buffer != 0) {
+ NameLength = AmlGetAslNameSegLength (Buffer);
+ if ((NameLength == 0) || (NameLength > AML_NAME_SEG_SIZE)) {
+ return 0;
+ }
+ (*SegCount) ++;
+ Buffer += NameLength;
+ if (*Buffer == 0) {
+ break;
+ }
+ Buffer ++;
+ }
+
+ //
+ // Check SegCoount
+ //
+ if (*SegCount > 0xFF) {
+ return 0;
+ }
+
+ //
+ // Calculate total length
+ //
+ TotalLength = *Root + *Parent + (*SegCount) * AML_NAME_SEG_SIZE;
+ if (*SegCount > 2) {
+ TotalLength += 2;
+ } else if (*SegCount == 2) {
+ TotalLength += 1;
+ }
+
+ //
+ // Add NULL char
+ //
+ TotalLength ++;
+
+ return TotalLength;
+}
+
+/**
+ Copy mem, and cast all the char in dest to be upper case.
+
+ @param[in] DstBuffer Destination buffer.
+ @param[in] SrcBuffer Source buffer.
+ @param[in] Length Buffer length.
+**/
+VOID
+AmlUpperCaseCopyMem (
+ IN UINT8 *DstBuffer,
+ IN UINT8 *SrcBuffer,
+ IN UINTN Length
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < Length; Index++) {
+ if (SrcBuffer[Index] >= 'a' && SrcBuffer[Index] <= 'z') {
+ DstBuffer[Index] = (UINT8)(SrcBuffer[Index] - 'a' + 'A');
+ } else {
+ DstBuffer[Index] = SrcBuffer[Index];
+ }
+ }
+}
+
+/**
+ Return AML name according to ASL name.
+ The caller need free the AmlName returned.
+
+ @param[in] AslPath ASL name.
+
+ @return AmlName
+**/
+UINT8 *
+AmlNameFromAslName (
+ IN UINT8 *AslPath
+ )
+{
+ UINTN Root;
+ UINTN Parent;
+ UINTN SegCount;
+ UINTN TotalLength;
+ UINTN NameLength;
+ UINT8 *Buffer;
+ UINT8 *AmlPath;
+ UINT8 *AmlBuffer;
+
+ TotalLength = AmlGetAslNameStringSize (AslPath, &Root, &Parent, &SegCount);
+ if (TotalLength == 0) {
+ return NULL;
+ }
+
+ AmlPath = Malloc (TotalLength);
+ ASSERT (AmlPath != NULL);
+
+ AmlBuffer = AmlPath;
+ Buffer = AslPath;
+
+ //
+ // Handle Root and Parent
+ //
+ if (Root == 1) {
+ *AmlBuffer = AML_ROOT_CHAR;
+ AmlBuffer ++;
+ Buffer ++;
+ } else if (Parent > 0) {
+ MemSet (AmlBuffer, Parent, AML_PARENT_PREFIX_CHAR);
+ AmlBuffer += Parent;
+ Buffer += Parent;
+ }
+
+ //
+ // Handle SegCount
+ //
+ if (SegCount > 2) {
+ *AmlBuffer = AML_MULTI_NAME_PREFIX;
+ AmlBuffer ++;
+ *AmlBuffer = (UINT8)SegCount;
+ AmlBuffer ++;
+ } else if (SegCount == 2) {
+ *AmlBuffer = AML_DUAL_NAME_PREFIX;
+ AmlBuffer ++;
+ }
+
+ //
+ // Now to name
+ //
+ while (*Buffer != 0) {
+ NameLength = AmlGetAslNameSegLength (Buffer);
+ ASSERT ((NameLength != 0) && (NameLength <= AML_NAME_SEG_SIZE));
+ AmlUpperCaseCopyMem (AmlBuffer, Buffer, NameLength);
+ MemSet (AmlBuffer + NameLength, AML_NAME_SEG_SIZE - NameLength, AML_NAME_CHAR__);
+ Buffer += NameLength;
+ AmlBuffer += AML_NAME_SEG_SIZE;
+ if (*Buffer == 0) {
+ break;
+ }
+ Buffer ++;
+ }
+
+ //
+ // Add NULL
+ //
+ AmlPath[TotalLength - 1] = 0;
+
+ return AmlPath;
+}
+
+/**
+ Print AML NameSeg.
+
+ @param[in] Buffer AML NameSeg.
+**/
+VOID
+AmlPrintNameSeg (
+ IN UINT8 *Buffer
+ )
+{
+ TRACE ((-1, "%c", Buffer[0]));
+ if ((Buffer[1] == '_') && (Buffer[2] == '_') && (Buffer[3] == '_')) {
+ return ;
+ }
+ TRACE ((-1, "%c", Buffer[1]));
+ if ((Buffer[2] == '_') && (Buffer[3] == '_')) {
+ return ;
+ }
+ TRACE ((-1, "%c", Buffer[2]));
+ if (Buffer[3] == '_') {
+ return ;
+ }
+ TRACE ((-1, "%c", Buffer[3]));
+ return ;
+}
+
+/**
+ Print AML NameString.
+
+ @param[in] Buffer AML NameString.
+**/
+VOID
+AmlPrintNameString (
+ IN UINT8 *Buffer
+ )
+{
+ UINT8 SegCount;
+ UINT8 Index;
+
+ if (*Buffer == AML_ROOT_CHAR) {
+ //
+ // RootChar
+ //
+ Buffer ++;
+ TRACE ((-1, "\\"));
+ } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
+ //
+ // ParentPrefixChar
+ //
+ do {
+ Buffer ++;
+ TRACE ((-1, "^"));
+ } while (*Buffer == AML_PARENT_PREFIX_CHAR);
+ }
+
+ if (*Buffer == AML_DUAL_NAME_PREFIX) {
+ //
+ // DualName
+ //
+ Buffer ++;
+ SegCount = 2;
+ } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
+ //
+ // MultiName
+ //
+ Buffer ++;
+ SegCount = *Buffer;
+ Buffer ++;
+ } else if (*Buffer == 0) {
+ //
+ // NULL Name
+ //
+ return ;
+ } else {
+ //
+ // NameSeg
+ //
+ SegCount = 1;
+ }
+
+ AmlPrintNameSeg (Buffer);
+ Buffer += AML_NAME_SEG_SIZE;
+ for (Index = 0; Index < SegCount - 1; Index++) {
+ TRACE ((-1, "."));
+ AmlPrintNameSeg (Buffer);
+ Buffer += AML_NAME_SEG_SIZE;
+ }
+
+ return ;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/AtadSmi.c b/Core/EM/ACPI/AtadSmi.c
new file mode 100644
index 0000000..31d57a5
--- /dev/null
+++ b/Core/EM/ACPI/AtadSmi.c
@@ -0,0 +1,254 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.c 1 1/23/14 5:47p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 1/23/14 5:47p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.c $
+//
+// 1 1/23/14 5:47p Oleksiyy
+// [TAG] EIP113941
+// [Category] New Feature
+// [Description] Time and Alarm ACPI device implemented.
+// [Files] AtadSmi.cif
+// AtadSmi.sdl
+// AtadSmi.mak
+// AtadSmi.dxs
+// AtadSmi.h
+// AtadSmi.c
+//
+// 6 1/13/10 2:13p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <AtadSmi.c>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <AmiSmm.h>
+#include "AtadSmi.h"
+#include <token.h>
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+ #include <Protocol/SmmSwDispatch.h>
+ #include <Protocol/SmmControl.h>
+#else
+ #include <Protocol/SmmSwDispatch2.h>
+ #include <Protocol/SmmControl2.h>
+ #include <Protocol/SmmCpu.h>
+#endif
+
+
+
+EFI_HANDLE VarSmiHandle = NULL;
+
+VOID *gAtadBuffer = NULL;
+EFI_EVENT EvtAtadSmi;
+VOID *RegAtadSmi;
+UINT32 i=0;
+UINT32 j=0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtadSmiHandler
+//
+// Description: The SMI handler for Nvram services.
+//
+// Input: NONE
+//
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtadSmiHandler ()
+{
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ ATAD_VARIABLE *SmmVarBuffer;
+ EFI_GUID gEfiTimeVariableGuid = EFI_TIME_VARIABLE_GUID;
+ TIME_VARIABLE TimeVar;
+ UINTN TimeVarSize = sizeof(TIME_VARIABLE);
+ UINT32 TimeVarFlags = EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS;
+ //TRACE((-1,"AtadSmiHandler . 1.\n"));
+ //checkpoint(0x24);
+ if (gAtadBuffer == NULL) return EFI_SUCCESS;
+
+ SmmVarBuffer = (ATAD_VARIABLE*)gAtadBuffer;
+
+
+
+
+ //checkpoint(0x25);
+ switch (SmmVarBuffer->Signature){
+
+ case ATAD_SW_SMI_UPDATE:
+ //TRACE((-1,"AtadSmiHandler . ATAD_SW_SMI_UPDATE.\n"));
+ TimeVar.TimeZone = SmmVarBuffer->TimeZone;
+ TimeVar.Daylight = SmmVarBuffer->DayLight;
+ Status = pRS->SetVariable( L"EfiTime",
+ &gEfiTimeVariableGuid,
+ TimeVarFlags,
+ TimeVarSize,
+ &TimeVar );
+
+ if (!EFI_ERROR(Status)) SmmVarBuffer->Signature = ATAD_SW_SMI_OK;
+ else SmmVarBuffer->Signature = ATAD_SW_SMI_NOT_GOOD;
+ //checkpoint(0x30+i++);
+ break;
+
+ case ATAD_SW_SMI_GET:
+ //TRACE((-1,"AtadSmiHandler . ATAD_SW_SMI_GET.\n"));
+ Status = pRS->GetVariable( L"EfiTime",
+ &gEfiTimeVariableGuid,
+ &TimeVarFlags,
+ &TimeVarSize,
+ &TimeVar );
+ if (!EFI_ERROR(Status))
+ {
+ SmmVarBuffer->TimeZone = TimeVar.TimeZone;
+ SmmVarBuffer->DayLight = TimeVar.Daylight;
+ SmmVarBuffer->Signature = ATAD_SW_SMI_OK;
+ }
+ else SmmVarBuffer->Signature = ATAD_SW_SMI_NOT_GOOD;
+ //checkpoint(0x40+j++);
+ break;
+
+ default:
+ SmmVarBuffer->Signature = ATAD_SW_SMI_NOT_GOOD;
+ }
+ //checkpoint(0x26);
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS AtadSmiHandler2 (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+
+{
+
+ CONST EFI_SMM_SW_REGISTER_CONTEXT *DispatchContext = Context;
+ //checkpoint(0x22);
+ //TRACE((-1,"AtadSmiHandler2\n"));
+ if ((gAtadBuffer == NULL) || ((UINT8)DispatchContext->SwSmiInputValue != ACPI_TIME_AND_ALARM_SW_SMI))
+ return EFI_DEVICE_ERROR;
+ //TRACE((-1,"AtadSmiHandler22\n"));
+ //checkpoint(0x23);
+ return AtadSmiHandler();
+
+}
+
+EFI_STATUS AtadInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = 0;
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+ EFI_GUID EfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch = NULL;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ Status = pBS->LocateProtocol(
+#else
+ EFI_GUID EfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch = NULL;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+ Status = pSmst->SmmLocateProtocol(
+#endif
+ &EfiSmmSwDispatchProtocolGuid,
+ NULL,
+ &SwDispatch
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ SwContext.SwSmiInputValue = ACPI_TIME_AND_ALARM_SW_SMI;
+ Status = SwDispatch->Register ( SwDispatch,
+ AtadSmiHandler2,
+ &SwContext,
+ &Handle );
+ ASSERT_EFI_ERROR(Status);
+ TRACE((TRACE_ALWAYS,"AtadInitSmmHandler pSwDispatch->Register Status=%r\n",Status));
+ return Status;
+}
+
+
+EFI_STATUS
+AtadSmiEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+
+
+ EFI_STATUS Status;
+ EFI_GUID AtadSmiGuid = ATAD_SMI_GUID;
+ UINTN VariableSize = sizeof(gAtadBuffer);
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ TRACE((TRACE_ALWAYS,"AtadSmiEntry\n"));
+
+ Status = pRS->GetVariable ( L"AtadSmiBuffer",
+ &AtadSmiGuid,
+ NULL,
+ &VariableSize,
+ &gAtadBuffer );
+ if ((EFI_ERROR(Status)) || (gAtadBuffer == NULL)) return EFI_NOT_FOUND;
+ //TRACE((-1, "AtadSmiEntry2 \n"));
+ Status = InitSmmHandler(
+ ImageHandle,
+ SystemTable,
+ AtadInSmmFunction,
+ NULL
+ );
+ TRACE((TRACE_ALWAYS,"AtadInitSmmHandler Status=%r\n",Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/AtadSmi.cif b/Core/EM/ACPI/AtadSmi.cif
new file mode 100644
index 0000000..7708ac1
--- /dev/null
+++ b/Core/EM/ACPI/AtadSmi.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "AtadSmi"
+ category = ModulePart
+ LocalRoot = "Core\EM\ACPI\"
+ RefName = "AtadSmi"
+[files]
+"AtadSmi.sdl"
+"AtadSmi.mak"
+"AtadSmi.dxs"
+"AtadSmi.h"
+"AtadSmi.c"
+<endComponent>
diff --git a/Core/EM/ACPI/AtadSmi.dxs b/Core/EM/ACPI/AtadSmi.dxs
new file mode 100644
index 0000000..a8e9ba3
--- /dev/null
+++ b/Core/EM/ACPI/AtadSmi.dxs
@@ -0,0 +1,98 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.dxs 1 1/23/14 5:47p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 1/23/14 5:47p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.dxs $
+//
+// 1 1/23/14 5:47p Oleksiyy
+// [TAG] EIP113941
+// [Category] New Feature
+// [Description] Time and Alarm ACPI device implemented.
+// [Files] AtadSmi.cif
+// AtadSmi.sdl
+// AtadSmi.mak
+// AtadSmi.dxs
+// AtadSmi.h
+// AtadSmi.c
+//
+// 3 1/12/12 9:35a Vyacheslava
+//
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SmmOemActivation.dxs
+//
+// Description: This file is the dependency file for OemActivation module.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+//---------------------------------------------------------------------------
+// Header files for GUID definitions
+//---------------------------------------------------------------------------
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+//---------------------------------------------------------------------------
+
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/AcpiTable.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+ EFI_ACPI_TABLE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//---------------------------------------------------------------------------
+#else
+//---------------------------------------------------------------------------
+
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/AcpiTable.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID AND
+ EFI_ACPI_TABLE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//---------------------------------------------------------------------------
+#endif
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/ACPI/AtadSmi.h b/Core/EM/ACPI/AtadSmi.h
new file mode 100644
index 0000000..546399a
--- /dev/null
+++ b/Core/EM/ACPI/AtadSmi.h
@@ -0,0 +1,91 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.h 1 1/23/14 5:47p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 1/23/14 5:47p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.h $
+//
+// 1 1/23/14 5:47p Oleksiyy
+// [TAG] EIP113941
+// [Category] New Feature
+// [Description] Time and Alarm ACPI device implemented.
+// [Files] AtadSmi.cif
+// AtadSmi.sdl
+// AtadSmi.mak
+// AtadSmi.dxs
+// AtadSmi.h
+// AtadSmi.c
+//
+// 6 1/13/10 2:13p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <Atad.h>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//---------------------------------------------------------------------------
+
+#define ATAD_SW_SMI_UPDATE 2
+#define ATAD_SW_SMI_GET 1
+#define ATAD_SW_SMI_OK 3
+#define ATAD_SW_SMI_NOT_GOOD 0xA5
+
+
+#define ATAD_SMI_GUID \
+{0x6F431B9F, 0x57E2, 0x1049, 0x5A, 0x3B, 0x69, 0x50, 0x4A, 0xED, 0x4F, 0x57}
+#define EFI_TIME_VARIABLE_GUID \
+{0x9d0da369, 0x540b, 0x46f8, 0x85, 0xa0, 0x2b, 0x5f, 0x2c, 0x30, 0x1e, 0x15}
+
+#pragma pack(push, 1)
+typedef struct {
+ INT16 TimeZone;
+ UINT8 Daylight;
+ } TIME_VARIABLE;
+
+
+typedef struct
+{
+ UINT8 Signature;
+ UINT8 DayLight;
+ UINT16 TimeZone;
+
+} ATAD_VARIABLE;
+
+#pragma pack(pop)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/AtadSmi.mak b/Core/EM/ACPI/AtadSmi.mak
new file mode 100644
index 0000000..0117e76
--- /dev/null
+++ b/Core/EM/ACPI/AtadSmi.mak
@@ -0,0 +1,82 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.mak 1 1/23/14 5:47p Oleksiyy $
+#
+# $Revision: 1 $
+#
+# $Date: 1/23/14 5:47p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/ACPI/Template/Core/AtadSmi.mak $
+#
+# 1 1/23/14 5:47p Oleksiyy
+# [TAG] EIP113941
+# [Category] New Feature
+# [Description] Time and Alarm ACPI device implemented.
+# [Files] AtadSmi.cif
+# AtadSmi.sdl
+# AtadSmi.mak
+# AtadSmi.dxs
+# AtadSmi.h
+# AtadSmi.c
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <ComponentName>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all: AtadSmi
+
+AtadSmi: $(BUILD_DIR)\AtadSmi.mak AtadSmiBin
+
+$(BUILD_DIR)\AtadSmi.mak : $(AtadSmi_DIR)\$(@B).cif $(AtadSmi_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AtadSmi_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+AtadSmiBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AtadSmi.mak all\
+ GUID=88F34ACA-3A7B-FF3C-D401-16A3B6834F2A\
+ ENTRY_POINT=AtadSmiEntry\
+!IF $(PI_SPECIFICATION_VERSION)<0x00001000A
+ TYPE=BS_DRIVER\
+!ELSE
+ TYPE=SMM_DRIVER\
+!ENDIF
+ DEPEX1=$(AtadSmi_DIR)\AtadSmi.dxs\
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.h"\
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/AtadSmi.sdl b/Core/EM/ACPI/AtadSmi.sdl
new file mode 100644
index 0000000..0c7c2f4
--- /dev/null
+++ b/Core/EM/ACPI/AtadSmi.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = AtadSmi_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable AtadSmi support in Project"
+ Token = "ATAD_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "AtadSmi_DIR"
+End
+
+MODULE
+ Help = "Includes AtadSmi.mak to Project"
+ File = "AtadSmi.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AtadSmi.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/ACPI/CIR.ASL b/Core/EM/ACPI/CIR.ASL
new file mode 100644
index 0000000..6b83461
--- /dev/null
+++ b/Core/EM/ACPI/CIR.ASL
@@ -0,0 +1,168 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/CIR.ASL 4 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 4 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/CIR.ASL $
+//
+// 4 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 3 4/19/06 1:37p Stacyh
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 1 03/04/07 5:48p Chung
+// Add ASL core for new all I/O beta version
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// Standalone InfraRed device //
+//**********************************************************************;
+// Category # :0x10 (Generic IO range 1)
+Device(CIR){
+ Name(_HID, EISAID("PNP0510")) //PnP Device ID IrDA
+ Method(_STA, 0) {Return(IRST(0x10))} //Get status
+ Method(_DIS, 0) {DCNT(0x10, 0)} //Disable
+ Method(_CRS, 0) {Return(IRCR(0x10))} //Get CIR current resources
+ Method(_SRS, 1) {IRSR(Arg0, 0x10)} //Set CIR recources
+// Method(_PRS, 0) {Return(IRPR)} //Return possible resources
+
+//-----------------------------------------------------------------------
+// IRST - GET SIO DEVICE STATUS according to ACTR/IOAH/IOAL
+//
+// Input - Arg0 : Device's category #
+// Return- Device Status Byte
+//-----------------------------------------------------------------------
+ Method(IRST, 1){
+ ENFG(CGLD(Arg0)) //Enter Config Mode, Select LDN
+ If(ACTR)
+ {Store(0x0F, Local0)} //Present & Active
+ Else{
+ If(IOAH)
+ {Store(0x0D, Local0)} //Then present & not active
+ Else
+ {Store(0, Local0)} //Not present
+ }
+ EXFG() //Exit Config Mode
+ Return(Local0) //Return device status
+ } // End Of IRST
+
+//-----------------------------------------------------------------------
+// IrDa Possible Resources
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate(){
+ StartDependentFn(0, 0){
+ IO(Decode16, 0x3E0, 0x3E0, 8, 8)
+ IRQNoFlags() {10}
+ }
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x3E0, 0x3E0, 8, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ }
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x2E0, 0x2E0, 8, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ }
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x298, 0x298, 8, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ }
+ EndDependentFn()
+ })
+
+//-----------------------------------------------------------------------
+// IRCR - Returns Byte stream of Current resources. May contain Resources such:
+//
+// Input - Arg0 : Device's category #
+// Return- Buffer
+//-----------------------------------------------------------------------
+ Name(PBUF, ResourceTemplate() {
+ IO(Decode16, 0, 0, 1, 8, PBP1)
+ IRQNoFlags(PBI1) {0}
+ })
+
+ Method(IRCR, 1){
+ // Arg0 - LDN
+ CreateByteField(PBUF, 0x02, IOLO) //Range Min Base LSB
+ CreateByteField(PBUF, 0x03, IOHI) //Range Min Base MSB
+ CreateWordField(PBUF, 0x02, IOHL) //Range Min Base Word
+ CreateWordField(PBUF, 0x04, IORL) //Range Max Base Word
+ CreateByteField(PBUF, 0x06, ALMN) //Alignment
+ CreateByteField(PBUF, 0x07, LENG) //Number of IO ports
+ CreateWordField(PBUF, 0x09, IRQL) //IRQ Mask
+
+ ENFG(CGLD(Arg0)) //Enter Config Mode, Select LDN
+
+ // Write Current Settings into Buffer for IO Descriptor
+ Store(IOAH, IOHI) //Get IO Base MSB
+ Store(IOAL, IOLO) //Get IO Base LSB
+ Store(IOHL, IORL) //Set MaxBase = MinBase
+ Store(0x01, ALMN) //Set alignment
+ Store(0x08, LENG) //Set IO length
+
+ // Write Current Settings into IRQ descriptor
+ Store(One, Local0)
+ ShiftLeft(Local0, INTR, IRQL)
+
+ EXFG() //Exit Config Mode
+ Return(PBUF) //Return Byte Stream
+ }
+
+//-----------------------------------------------------------------------
+// IRSR - Configures new Resources to be decoded by a Device
+//
+// Input - Arg0 : PnP Resource String to set
+// Arg1 : Device's category #
+// Return- nothing
+//-----------------------------------------------------------------------
+ Method(IRSR, 2){
+ CreateByteField (Arg0, 0x02, POLB) //Range Min Base LSB
+ CreateByteField (Arg0, 0x03, POHB) //Range Min Base MSB
+ CreateWordField (Arg0, 0x09, PIRQ) //IRQ number
+
+ ENFG(CGLD(Arg1)) //Enter Config Mode, Select LDN
+
+ // Set Base IO Address
+ Store(POLB, IOAL) //Set IO Base LSB
+ Store(POHB, IOAH) //Set IO Base MSB
+
+ // Set IRQ
+ FindSetRightBit(PIRQ, Local0)
+ Subtract(Local0, 1, INTR)
+
+ Store(One, ACTR) //Activate
+ EXFG() //Exit Config Mode
+ }
+
+} // End Of IRDA //
diff --git a/Core/EM/ACPI/Fdc.asl b/Core/EM/ACPI/Fdc.asl
new file mode 100644
index 0000000..e53e9e4
--- /dev/null
+++ b/Core/EM/ACPI/Fdc.asl
@@ -0,0 +1,150 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Fdc.asl 4 6/12/12 12:13p Oleksiyy $
+//
+// $Revision: 4 $
+//
+// $Date: 6/12/12 12:13p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Fdc.asl $
+//
+// 4 6/12/12 12:13p Oleksiyy
+// [TAG] EIP89379
+// [Category] Improvement
+// [Description] Added token for support to changing iasl compiler.
+// [Files] ACPI.sdl, Fdc.asl and AmiBoardinfo.mak
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 9 03/04/07 5:39p Chung
+// Modify all I/O beta version
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+// Floppy Disk Controller - FDC //
+//**********************************************************************;
+// Category # :0x03
+Device(FDC) {
+ Name(_HID, EISAID("PNP0700")) //PnP Device ID
+// _FDE : 5 Dword Package (1-4 are for each FDD present, #5 is for optional tape drive)
+// 0 - Device is not present
+// 1 - Device is Present
+// 2 - Device is never Present
+// >2- Reserved
+// Tape drive is never present
+ Name(_FDE, BUFFER(){1,0,2,2,2}) //_FDE - Floppy Disk Enumerate
+
+ Method(_STA, 0) {Return(^^SIO1.DSTA(3))} //Get status
+
+ Method(_DIS, 0) {^^SIO1.DCNT(3, 0)} //Disable FDC
+
+ Method(_CRS, 0) { //Return FDC Current Resources
+ ^^SIO1.DCRS(3, 1) //Fill in Return buffer with DMA, Irq and 1st IO
+ //Move resources from CRS1 ro CRS2 buffer
+ Store(^^SIO1.IRQM, ^^SIO1.IRQE) //IRQ mask 0x1
+ Store(^^SIO1.DMAM, ^^SIO1.DMAE) //DMA 0x04
+ Store(^^SIO1.IO11, ^^SIO1.IO21) //1st IO Range Min Base Word 0x8
+ Store(^^SIO1.IO12, ^^SIO1.IO22) // Max Base Word 0xa
+ Store(6, ^^SIO1.LEN2)
+
+ Add(^^SIO1.IO21, 0x07, ^^SIO1.IO31) //2nd IO range
+ Store(^^SIO1.IO31, ^^SIO1.IO32)
+ Store(1, ^^SIO1.LEN3)
+ Return(^^SIO1.CRS2)
+ }
+
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate() { //FDC Possible Resources
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x3F0, 0x3F0, 1, 6)
+ IO(Decode16, 0x3F7, 0x3F7, 1, 1)//0x3F6 port reserved for Legacy IDE
+ IRQNoFlags() {6}
+ DMA(Compatibility, NotBusMaster, Transfer8) {2}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F0, 0x3F0, 1, 6)
+ IO(Decode16, 0x3F7, 0x3F7, 1, 1)//0x3F6 port reserved for Legacy IDE
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x370, 0x370, 1, 6)
+ IO(Decode16, 0x377, 0x377, 1, 1)//0x376 port reserved for Legacy IDE
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {2,3}
+ }
+ EndDependentFn()
+ })
+
+ Method(_SRS, 1) { //Set resources/Enable FDC
+ ^^SIO1.DSRS(Arg0, 3)
+
+ CreateWordField(Arg0, ^^SIO1.IRQ2._INT, IRQE) //IRQ mask 0x1
+ CreateByteField(Arg0, ^^SIO1.DMA2._DMA, DMAE) //DMA 0x4
+
+ ^^SIO1.ENFG(^^SIO1.CGLD(3)) //Enter Config Mode, Select LDN
+// Set IRQ
+ If(IRQE){
+ FindSetRightBit(IRQE, Local0)
+ Subtract(Local0, 1, ^^SIO1.INTR)
+ }Else{
+ Store(0, ^^SIO1.INTR) // No IRQ used
+ }
+// Set DMA
+ If(DMAE){
+ FindSetRightBit(DMAE, Local0)
+ Subtract(Local0, 1, ^^SIO1.DMCH)
+ }Else{
+ Store(4, ^^SIO1.DMCH)// No DMA
+ }
+ ^^SIO1.EXFG() //Exit Config Mode
+ }
+
+
+//---------Power Resources for FDD -------------------------
+/*
+ PowerResource(FDDP, 0, 0) { // SystemLevel Parameter=0,
+ Method(_STA, 0) {
+ Return(FDCP) // Get Power Status
+ } // end of _STA
+ Method(_ON) {
+ Store(1, FDCP) // Power on
+ } // end of _ON
+ Method(_OFF){
+ Store(0, FDCP) // Power off
+ } // end of _OFF
+ }
+ Name(_PR0, Package(){FDDP}) // Reference to PowerResources
+*/
+} // End Of FDC0 ////////////////////////////////////////////////////////
diff --git a/Core/EM/ACPI/GameMpu.asl b/Core/EM/ACPI/GameMpu.asl
new file mode 100644
index 0000000..7364e8c
--- /dev/null
+++ b/Core/EM/ACPI/GameMpu.asl
@@ -0,0 +1,185 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/GameMpu.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/GameMpu.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 4 03/04/07 5:40p Chung
+// Modify all I/O beta version
+//
+// 3 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+// Combined Game & Midi Logical Device
+//**********************************************************************;
+// Generic Game Port
+//-----------------------------------------------------------------------
+// Category # :0x08
+Device(GAME){
+ Name(_HID, EISAID("PNPB02F")) //PnP ID for GamePort
+ Method(_STA, 0) {Return(DSTA(8))} //Get status
+// Method(_DIS, 0) {DCNT(8,0)} //Disable
+//-----------------------------------------------------------------------
+// GamePort Current Resource template (to be returned by _CRS)
+//-----------------------------------------------------------------------
+ Name(GMCR, ResourceTemplate(){
+ IO(Decode16, 0x201, 0x201, 1, 8, GMIO)
+ })
+
+ Method(_CRS, 0){
+ CreateByteField(GMCR, 0x02, IOLO) //Range Min Base LSB
+ CreateByteField(GMCR, 0x03, IOHI) //Range Min Base MSB
+ CreateWordField(GMCR, 0x02, IOHL) //Range Min Base Word
+ CreateWordField(GMCR, 0x04, IORL) //Range Max Base Word
+
+ ENFG(CGLD(8)) //Enter Config Mode, Select LDN
+
+// Write Current Settings into Buffer for IO Descriptor
+ Store(IOAH, IOHI) //Get IO Base MSB
+ Store(IOAL, IOLO) //Get IO Base LSB
+ Store(IOHL, IORL) //Set MaxBase = MinBase
+
+ EXFG() //Exit Config Mode
+ Return(GMCR) //Return Byte Stream
+ }
+
+ Method(_SRS, 1){
+ CreateByteField (Arg0, 0x02, POLB) // Range Min Base LSB
+ CreateByteField (Arg0, 0x03, POHB) // Range Min Base MSB
+
+ ENFG(CGLD(8)) // Enter Config Mode, Select LDN
+
+// Set Base IO Address
+ Store(POLB, IOAL) // Set IO Base LSB
+ Store(POHB, IOAH) // Set IO Base MSB
+// Enable ACTR
+ DCNT(8, 1) // Enable Device (Routing)
+ EXFG() // Exit Config Mode
+ }
+//-----------------------------------------------------------------------
+// GamePort Possible Resources (returned by _PRS)
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate(){
+ StartDependentFn(0,0) {
+ IO(Decode16, 0x201, 0x201, 1, 8)
+ }
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x209, 0x209, 1, 8)
+ }
+ EndDependentFn()
+ })
+}
+// End Of GamePort //////////////////////////////////////////////////////
+// Win627 specific Combined Game & Midi Logical Device
+// IO ports are defined at offset 0x62, 0x63 of LDN configuratsion space
+//**********************************************************************;
+// Generic MPU 401 Device
+//**********************************************************************;
+// Category # :0x05
+Device(MIDI){
+ Name(_HID, EISAID("PNPB006")) //PnP ID for GamePort
+ Method(_STA, 0) {Return(DSTA(5))} //Get status
+// Method(_DIS, 0) {DCNT(5,0)} //Disable
+//-----------------------------------------------------------------------
+// MIDIPort Current Resources template (returned by _CRS)
+//-----------------------------------------------------------------------
+ Name(MDCR, ResourceTemplate(){
+ IO(Decode16, 0x300, 0x300, 1, 2, MDIO)
+ IRQNoFlags(MBI1) {5}
+ })
+
+ Method(_CRS, 0){
+ CreateByteField(MDCR, 0x02, IOLO) //Range Min Base LSB
+ CreateByteField(MDCR, 0x03, IOHI) //Range Min Base MSB
+ CreateWordField(MDCR, 0x02, IOHL) //Range Min Base Word
+ CreateWordField(MDCR, 0x04, IORL) //Range Max Base Word
+ CreateWordField(MDCR, 0x09, MIRQ) //IRQ Mask (word)
+
+ ENFG(CGLD(5)) //Enter Config Mode, Select LDN
+
+// Write Current Settings into Buffer for IO Descriptor
+ Store(IOH2, IOHI) //Get IO Base MSB
+ Store(IOL2, IOLO) //Get IO Base LSB
+ Store(IOHL, IORL) //Set MaxBase = MinBase
+// Write Current Settings into IRQ descriptor
+ ShiftLeft(1, INTR, MIRQ)
+
+ EXFG() //Exit Config Mode
+ Return(MDCR) //Return Byte Stream
+ }
+
+ Method(_SRS, 1){
+// Arg0 - PnP Resource String to set
+ CreateByteField (Arg0, 0x02, POLB) //Range Min Base LSB
+ CreateByteField (Arg0, 0x03, POHB) //Range Min Base MSB
+ CreateWordField (Arg0, 0x09, MIRQ) //IRQ mask (word)
+
+ ENFG(CGLD(5)) //Enter Config Mode, Select LDN
+
+// Set Base IO Address
+ Store(POLB, IOL2) //Set IO Base LSB
+ Store(POHB, IOH2) //Set IO Base MSB
+
+// Set IRQ
+ FindSetRightBit(MIRQ, Local0)
+ Subtract(Local0, 1, INTR)
+
+ DCNT(5, 1) //Enable Device (Routing)
+ EXFG() //Exit Config Mode
+ }
+
+//-----------------------------------------------------------------------
+// MIDIPort Possible Resources (returned by _PRS)
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate(){
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x300, 0x300, 1, 2)
+ IRQNoFlags() {5,7,9,10,11}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x330, 0x330, 1, 2)
+ IRQNoFlags() {5,7,9,10,11}
+ }
+ EndDependentFn()
+ })
+}
+// End Of Midi //////////////////////////////////////////////////////////
diff --git a/Core/EM/ACPI/LM75.ASL b/Core/EM/ACPI/LM75.ASL
new file mode 100644
index 0000000..afffa64
--- /dev/null
+++ b/Core/EM/ACPI/LM75.ASL
@@ -0,0 +1,179 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/LM75.ASL 2 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/LM75.ASL $
+//
+// 2 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 2 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//;**********************************************************************;
+//**********************************************************************;
+// ASL interface to LM75 thermal sensor over SMBus
+//**********************************************************************;
+
+// change LM75 trip points
+ Method(TCHG, 0) {
+
+ Store(RBYT(TSAD, 0x00), Local0) // Read Current temp
+/*
+If(LGreaterEqual(Local0,TMAX)) {
+ Store(TCRT, Local1) // Tcrt
+ }
+ Else {
+ If(LGreaterEqual(Local0,TMIN)) {
+ Store(TMAX, Local1) // Thigh
+ }
+ Else {
+ Store(TMIN, Local1) // TLow
+ }
+ }
+ STOS(0,Local1) // Set Thigh
+
+ STHY(0, Add(Local0, 2)) // Set TLow T + 2.0C to arm the Thermal int
+
+// Subtract(TMIN, 5, Local2) // Set Thyst as TMIN-5.0
+
+// Add(Local0, 0x5, Local1) // Set Thigh T + 5.0 C
+ Subtract(Local0, 0x1, Local2) // Set Tlow T - 1.0 C
+ Subtract(TMIN, 0x5, Local3) // Set Tlow TMIN - 5.0 C
+// If(LGreater(Local2,Local3))
+// {
+// Store(Local3, Local2)
+// }
+
+ STHY(0,Local2) // Set TLow
+*/
+ STOS(TCRT) // Set Thigh TCRT
+ STHY(Subtract(Local0, 5)) // Set TLow TMIN-5.0C
+
+ Notify(\_TZ.THRM, 0x81) // Notify of trip point change
+ }
+
+// Set configuration register
+Method(SCFG, 1) {
+ // Arg0 = configuration byte
+
+ WBYT(TSAD, 0x01, Arg0)
+ }
+
+// Set Tos register
+
+Method(STOS, 1) {
+ // Arg0 = temperature word data
+
+ // Set pointer register (occupy the command byte) to 0x03
+ // Somehow LM75 wants to send out the MSB byte first !
+
+ WWRD(TSAD, 0x03, Arg0)
+ }
+
+// Set Thyst register
+
+Method(STHY, 1) {
+ // Arg0 = temperature word data
+
+ // Set pointer register (occupy the command byte) to 0x02
+ // Somehow LM75 wants to send out the MSB byte first !
+
+ WWRD(TSAD, 0x02, Arg0)
+ }
+
+// Read temperature register
+
+Method(RTMP, 0) {
+ // Set pointer register (occupy the command byte) to 0x00
+
+ Store(RWRD(TSAD, 0x00), Local0)
+
+Store(Local0, DBG8)
+
+ // Somehow LM75 returns right byte first!
+
+ If(Not(Local0)) // Read command completed
+ {
+ Return( Local0 )
+ }
+ Else // Read command failed
+ {
+ Store("_TMP Read ERROR", Debug)
+ Return(Add(TMIN, 2)) // MIN trip point + 2.0 C
+ }
+
+ } // Method(RTMP)
+
+// LM75 Thermal interrupt handler
+Method(THDL,0) {
+//**********************************************************************;
+// Trip point handler
+// TPOL status bit applys for PIIX4 based design only
+// PMBS is an ACPI I/O Base address
+// PM controller IO space
+ OperationRegion(PMRG, SystemIO, PMBS, 0x40)
+ Field(PMRG,ByteAcc,NoLock,Preserve)
+ {
+ Offset(0x28),
+ ,2,
+ TPOL,1, // 28.2h Thermal Polarity bit
+ }
+
+ If(TPOL)
+// Temp goes up, Tos threshold being crossed
+ {
+ \GFAN._ON() // Turn FAN On
+ }
+ Else
+// Temp goes down, Thyst threshold being crossed
+ {
+ \GFAN._OFF() // Turn FAN Off
+ }
+
+ TCHG() // Reevaluate Thigh/TLow for LM75
+ Not(TPOL,TPOL) // Toggle the Polarity pin
+}
+//**********************************************************************;
+// *****************************************************************;
+// *****************************************************************;
+// ** **;
+// ** (C)Copyright 1985-1996, American Megatrends, Inc. **;
+// ** **;
+// ** All Rights Reserved. **;
+// ** **;
+// ** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
+// ** **;
+// ** Phone (770)-246-8600 **;
+// ** **;
+// *****************************************************************;
+// *****************************************************************;
+//**********************************************************************;
+// DON'T CHANGE ANY CODE UNLESS REQUIRED !!!
+//**********************************************************************;
diff --git a/Core/EM/ACPI/Lpte.asl b/Core/EM/ACPI/Lpte.asl
new file mode 100644
index 0000000..164c9a1
--- /dev/null
+++ b/Core/EM/ACPI/Lpte.asl
@@ -0,0 +1,199 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Lpte.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Lpte.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 7 03/04/07 5:41p Chung
+// Modify all I/O beta version
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// Parallel port - LPT or ECP(Extended mode)/////////////////////////////
+//**********************************************************************;
+// Category # :0x02
+Device(LPTE) {
+ Method(_HID, 0){ //PnP Device ID
+ If(^^SIO1.LPTM(2)) //Get LPT mode : 0-plain LPT, non Zero-ECP mode
+ {Return(EISAID("PNP0401"))} //PnP ID for ECP Port
+ Else
+ {Return(EISAID("PNP0400"))} //PnP ID for LPT Port
+ }
+
+ Method(_STA, 0) {Return(^^SIO1.DSTA(2))} //Get Device status
+
+ Method(_DIS, 0) {^^SIO1.DCNT(2,0)} //Disable LPT, arg0 - LDN, arg1 - 1(disable)
+
+ Method(_CRS, 0) { //Get LPT current resources
+ ^^SIO1.DCRS(2, 1) //Fill in Return buffer with DMA, Irq and 1st IO
+ If(^^SIO1.LPTM(2)){ //Extended LPT mode ?
+ //Move resources from CRS1 ro CRS2 buffer
+ Store(^^SIO1.IRQM, ^^SIO1.IRQE) //IRQ mask 0x1
+ Store(^^SIO1.DMAM, ^^SIO1.DMAE) //DMA 0x04
+
+ Store(^^SIO1.IO11, ^^SIO1.IO21) //1st IO Range Min Base Word 0x8
+ Store(^^SIO1.IO12, ^^SIO1.IO22) // Max Base Word 0xa
+ Store(^^SIO1.LEN1, ^^SIO1.LEN2)
+
+ Add(^^SIO1.IO21, 0x400, ^^SIO1.IO31) //2nd IO range
+ Store(^^SIO1.IO31, ^^SIO1.IO32)
+ Store(^^SIO1.LEN2, ^^SIO1.LEN3)
+ Return(^^SIO1.CRS2)
+ }else{
+ Return(^^SIO1.CRS1)
+ }
+ }
+
+ Method(_SRS, 1) { //Set LPT resources
+ ^^SIO1.DSRS(Arg0, 2)
+ }
+
+ Method(_PRS, 0) { //Return Possible resources
+ If(^^SIO1.LPTM(2)) //Get LPT mode : 0-plain LPT, non Zero-ECP mode
+ {Return(EPPR)} //ECP mode resources
+ Else
+ {Return(LPPR)} //LPT mode resources
+ }
+
+
+//-----------------------------------------------------------------------
+// LPT Possible Resources
+//-----------------------------------------------------------------------
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(LPPR, ResourceTemplate(){
+// IRQ
+ StartDependentFn(0,0) {
+ IO(Decode16, 0x378, 0x378, 1, 8)
+ IRQNoFlags() {5}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x378, 0x378, 1, 8)
+ IRQNoFlags() {5,6,7,10,11,12}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x278, 0x278, 1, 8)
+ IRQNoFlags() {5,6,7,10,11,12}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3BC, 0x3BC, 1, 4)
+ IRQNoFlags() {5,6,7,10,11,12}
+ }
+// No IRQ
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x378, 0x378, 1, 8)
+ IRQNoFlags() {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x278, 0x278, 1, 8)
+ IRQNoFlags() {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3BC, 0x3BC, 1, 4)
+ IRQNoFlags() {}
+ }
+ EndDependentFn()
+ })
+
+//-----------------------------------------------------------------------
+// ECP Possible Resources
+//-----------------------------------------------------------------------
+ Name(EPPR, ResourceTemplate() {
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x378, 0x378, 1, 8)
+ IO(Decode16, 0x778, 0x778, 1, 8)
+ IRQNoFlags() {5}
+ DMA(Compatibility, NotBusMaster, Transfer8) {3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x378, 0x378, 1, 8)
+ IO(Decode16, 0x778, 0x778, 1, 8)
+ IRQNoFlags() {5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x278, 0x278, 1, 8)
+ IO(Decode16, 0x678, 0x678, 1, 8)
+ IRQNoFlags() {5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3BC, 0x3BC, 1, 4)
+ IO(Decode16, 0x7BC, 0x7BC, 1, 4)
+ IRQNoFlags() {5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,3}
+ }
+// No IRQ
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x378, 0x378, 1, 8)
+ IO(Decode16, 0x778, 0x778, 1, 8)
+ IRQNoFlags() {}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x278, 0x278, 1, 8)
+ IO(Decode16, 0x678, 0x678, 1, 8)
+ IRQNoFlags() {}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3BC, 0x3BC, 1, 4)
+ IO(Decode16, 0x7BC, 0x7BC, 1, 4)
+ IRQNoFlags() {}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,3}
+ }
+ EndDependentFn()
+ })
+
+/*
+//---------Power Resources for LPT -------------------------
+ PowerResource(LPTP, 0, 0) { // SystemLevel Parameter=0,
+ Method(_STA, 0) {
+ Return(LPTP) // Get Power Status
+ } // end of _STA
+ Method(_ON) {
+ Store(1,LPTP)
+ } // end of _ON
+ Method(_OFF){
+ Store(0,LPTP)
+ } // end of _OFF
+ }
+ Name(_PR0, Package(){LPTP}) // Reference to PowerResources
+*/
+//**********************************************************************;
+} // End Of LPTE ////////////////////////////////////////////////////////
diff --git a/Core/EM/ACPI/MAX1617L.ASL b/Core/EM/ACPI/MAX1617L.ASL
new file mode 100644
index 0000000..193e19c
--- /dev/null
+++ b/Core/EM/ACPI/MAX1617L.ASL
@@ -0,0 +1,219 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/MAX1617L.ASL 2 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/MAX1617L.ASL $
+//
+// 2 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 2 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//;**********************************************************************;
+//**********************************************************************;
+// ASL interface to MAX1617 thermal sensor over SMBus
+// Local sensor
+//**********************************************************************;
+// change max1617 trip point
+ Method(TCHG, 0) {
+
+ Store(RBYT(TSAD, 0x00), Local0) // Read local Current temp
+
+ Add(Local0, 0x1, Local1) // Set Thigh T + 1.0 C
+ Subtract(Local0, 0x1, Local2) // Set Tlow T - 1.0 C
+
+ STOS(Local1) // Set Thigh
+ STHY(Local2) // Set Tlow
+// STOS(0x7f) // Set Thigh
+// STHY(0xbf) // Set Tlow
+ RBYT(TSAD, 0x02) // Read status byte after limit changes
+ // Clears ALARM bit
+/*
+ Store(RBYT(TSAD, 0x07), Local0) // remote high limit
+ Store(RBYT(TSAD, 0x08), Local1) // remote low limit
+ Store(RBYT(TSAD, 0x01), Local2) // remote current temp
+ RBYT(TSAD, 0x02) // Read status byte
+ if( LGreaterEqual(Local2,Local0) ) {
+ // High limit alert
+ if( LEqual(Local0, TMIN) ) {
+ // Set TMAX to high limit & TMIN-2 to low limit
+ STOS(TMAX) // Set Thigh to TMAX
+ Subtract(TMIN, 2, Local3)
+ STHY(Local3) // Set Tlow to TMIN-2
+ }
+ else {
+ if( LEqual(Local0, TMAX) ) {
+ // Set TCRT to high limit & TMAX-2 to low limit
+ STOS(TCRT) // Set Thigh to TCRT
+ Subtract(TMAX, 2, Local3)
+ STHY(Local3) // Set Tlow to TMAX-2
+ }
+ else {
+ if( LEqual(Local0, TCRT) ) {
+ // Notify OS to shutdown
+ // Set Extreeme high to high limit & TCRT-2 to low limit
+ STOS(0x7f) // Set Thigh to extreeme high (127C)
+ Subtract(TCRT, 2, Local3)
+ STHY(Local3) // Set Tlow to TCRT-2
+ }
+// else {
+// // This from init. set TMIN to high & Extreeme to low limit
+// STOS(TMIN) // Set Thigh to TMIN
+// STHY(0xc9) // Set Tlow to extreeme low (-55C)
+// }
+ }
+ }
+ }
+ else {
+ if( LLessEqual(Local2, Local1) ) {
+ // Low limit alert
+ if( LLess(Local1, TMIN) ) {
+ // Set TMIN to high limit & Extreeme to low limit
+ STOS(TMIN) // Set Thigh to TMIN
+ STHY(0xc9) // Set Tlow to extreeme low (-55C)
+ }
+ else {
+ if( LLess(Local1, TMAX) ) {
+ // Set TMAX to high limit & TMIN-2 to low limit
+ STOS(TMAX) // Set Thigh to TMAX
+ Subtract(TMIN, 2, Local3)
+ STHY(Local3) // Set Tlow to TMIN-2
+ }
+ else {
+ if( LLess(Local1, TCRT) ) {
+ // Set TCRT to high limit & TMAX-2 to low limit
+ STOS(TCRT) // Set Thigh to TCRT
+ Subtract(TMAX, 2, Local3)
+ STHY(Local3) // Set Tlow to TMAX-2
+ }
+// else {
+// // This from init. set TMIN to high & Extreeme to low
+// STOS(TMIN) // Set Thigh to TMIN
+// STHY(0xc9) // Set Tlow to extreeme low (-55C)
+// }
+ }
+ }
+ }
+ }
+
+
+ RBYT(TSAD, 0x02) // Read status byte after limit changes
+ RSBT(0x19, 0) // Receive Byte, Addr 0x18
+*/
+ Notify(\_TZ.THRM, 0x81) // Notify of trip point change
+ }
+
+// Set configuration register #0x9
+Method(SCFG, 1) {
+ // Arg0 = configuration byte
+
+ WBYT(TSAD, 0x09, Arg0)
+ }
+
+// Read Status Byte
+Method(RSTS, 0) {
+ // Arg0 = configuration byte
+
+ Return(RBYT(TSAD, 0x02))
+ }
+
+// Set Tos register #0xb
+Method(STOS, 1) {
+ // Arg0 = temperature low byte
+
+ // Set pointer register (occupy the command byte) to 0x0B
+
+ WBYT(TSAD, 0x0B, Arg0)
+ }
+
+// Set Thyst register #0xC
+Method(STHY, 1) {
+ // Arg0 = temperature low byte
+
+ // Set pointer register (occupy the command byte) to 0x0C
+ WBYT(TSAD, 0x0C, Arg0)
+ }
+// Get Tos register #0x5
+Method(GTOS, 0) {
+
+ Store(RBYT(TSAD, 0x05), Debug)
+ }
+
+// Set Thyst register #0x6
+Method(GTHY, 0) {
+
+ Store(RBYT(TSAD, 0x06), Debug)
+ }
+
+// Read local temperature register
+
+Method(RTMP, 0) {
+ // Set pointer register (occupy the command byte) to 0x00
+
+ Store(RBYT(TSAD, 0x00), Local0)
+
+Store(Local0, DBG8)
+
+ If(Not(Local0)) // Read command completed
+ {
+ Return( Local0 )
+ }
+ Else // Read command failed
+ {
+ Store("_TMP Read ERROR", Debug)
+ Return(Add(TMIN, 2)) // MIN trip point + 2.0 C
+ }
+} // Method(RTMP)
+
+// MAX1617 Thermal interrupt handler
+Method(THDL,0) {
+//**********************************************************************;
+ TCHG() // change Trip points
+ // Clear ALARM bit
+ RSBT(0x19, 0) // Receive Byte, Addr 0x18
+//**********************************************************************;
+}
+//**********************************************************************;
+// *****************************************************************;
+// *****************************************************************;
+// ** **;
+// ** (C)Copyright 1985-1996, American Megatrends, Inc. **;
+// ** **;
+// ** All Rights Reserved. **;
+// ** **;
+// ** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
+// ** **;
+// ** Phone (770)-246-8600 **;
+// ** **;
+// *****************************************************************;
+// *****************************************************************;
+//**********************************************************************;
+// DON'T CHANGE ANY CODE UNLESS REQUIRED !!!
+//**********************************************************************;
diff --git a/Core/EM/ACPI/MAX1617R.ASL b/Core/EM/ACPI/MAX1617R.ASL
new file mode 100644
index 0000000..aa60f73
--- /dev/null
+++ b/Core/EM/ACPI/MAX1617R.ASL
@@ -0,0 +1,222 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/MAX1617R.ASL 2 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/MAX1617R.ASL $
+//
+// 2 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 2 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//;**********************************************************************;
+//**********************************************************************;
+// ASL interface to MAX1617 thermal sensor over SMBus
+// Remote sensor
+//**********************************************************************;
+
+// change max1617 trip point
+/*
+// Original TCHG method
+ Method(TCHG, 0) {
+
+ Store(RBYT(TSAD, 0x01), Local0) // Read remote Current temp
+
+ Add(Local0, 0x5, Local1) // Set Thigh T + 5.0 C
+
+ Subtract(Local0, 0x5, Local2) // Set Tlow T - 5.0 C
+// Subtract(Local0, 0x2, Local2) // Set Tlow T - 2.0 C
+
+ Subtract(TMIN, 0x5, Local3) // Set Tlow TMIN - 5.0 C
+// If(LGreater(Local2,Local3))
+// {Store(Local3,Local2)}
+
+ STOS(Local1) // Set Thigh
+ STHY(Local2) // Set Tlow
+ // Clear ALARM bit
+ Notify(\_TZ.THRM, 0x81) // Notify of trip point change
+ }
+*/
+// Customized Method
+ Method(TCHG, 0) {
+
+ Store(RBYT(TSAD, 0x07), Local0) // remote high limit
+ Store(RBYT(TSAD, 0x08), Local1) // remote low limit
+ Store(RBYT(TSAD, 0x01), Local2) // remote current temp
+ RBYT(TSAD, 0x02) // Read status byte
+ if( LGreaterEqual(Local2,Local0) ) {
+ // High limit alert
+ if( LEqual(Local0, TMIN) ) {
+ // Set TMAX to high limit & TMIN-2 to low limit
+ STOS(TMAX) // Set Thigh to TMAX
+ Subtract(TMIN, 2, Local3)
+ STHY(Local3) // Set Tlow to TMIN-2
+ }
+ else {
+ if( LEqual(Local0, TMAX) ) {
+ // Set TCRT to high limit & TMAX-2 to low limit
+ STOS(TCRT) // Set Thigh to TCRT
+ Subtract(TMAX, 2, Local3)
+ STHY(Local3) // Set Tlow to TMAX-2
+ }
+ else {
+ if( LEqual(Local0, TCRT) ) {
+ // Notify OS to shutdown
+ // Set Extreeme high to high limit & TCRT-2 to low limit
+ STOS(0x7f) // Set Thigh to extreeme high (127C)
+ Subtract(TCRT, 2, Local3)
+ STHY(Local3) // Set Tlow to TCRT-2
+ }
+// else {
+// // This from init. set TMIN to high & Extreeme to low limit
+// STOS(TMIN) // Set Thigh to TMIN
+// STHY(0xc9) // Set Tlow to extreeme low (-55C)
+// }
+ }
+ }
+ }
+ else {
+ if( LLessEqual(Local2, Local1) ) {
+ // Low limit alert
+ if( LLess(Local1, TMIN) ) {
+ // Set TMIN to high limit & Extreeme to low limit
+ STOS(TMIN) // Set Thigh to TMIN
+ STHY(0xc9) // Set Tlow to extreeme low (-55C)
+ }
+ else {
+ if( LLess(Local1, TMAX) ) {
+ // Set TMAX to high limit & TMIN-2 to low limit
+ STOS(TMAX) // Set Thigh to TMAX
+ Subtract(TMIN, 2, Local3)
+ STHY(Local3) // Set Tlow to TMIN-2
+ }
+ else {
+ if( LLess(Local1, TCRT) ) {
+ // Set TCRT to high limit & TMAX-2 to low limit
+ STOS(TCRT) // Set Thigh to TCRT
+ Subtract(TMAX, 2, Local3)
+ STHY(Local3) // Set Tlow to TMAX-2
+ }
+// else {
+// // This from init. set TMIN to high & Extreeme to low
+// STOS(TMIN) // Set Thigh to TMIN
+// STHY(0xc9) // Set Tlow to extreeme low (-55C)
+// }
+ }
+ }
+ }
+ }
+
+
+ RBYT(TSAD, 0x02) // Read status byte after limit changes
+ RSBT(0x19, 0) // Receive Byte, Addr 0x18
+ Notify(\_TZ.THRM, 0x81) // Notify of trip point change
+ }
+
+// Set configuration register #0x9
+Method(SCFG, 1) {
+ // Arg0 = configuration byte
+
+ WBYT(TSAD, 0x09, Arg0)
+ }
+
+// Read Status Byte
+Method(RSTS, 0) {
+ // Arg0 = configuration byte
+
+ Return(RBYT(TSAD, 0x02))
+ }
+
+// Set remote Thigh register #0x0d
+Method(STOS, 1) {
+ // Arg0 = temperature low byte
+
+ // Set pointer register (occupy the command byte) to 0x0d
+ // Somehow max1617 wants to send out the MSB byte first !
+
+ WBYT(TSAD, 0x0d, Arg0)
+ }
+
+// Set remote Tlow register #0x0e
+Method(STHY, 1) {
+ // Arg0 = temperature low byte
+
+ // Set pointer register (occupy the command byte) to 0x0C
+ // Somehow max1617 wants to send out the MSB byte first !
+
+ WBYT(TSAD, 0x0e, Arg0)
+ }
+
+// Read remote temperature register
+Method(RTMP, 0) {
+ // Set pointer register (occupy the command byte) to 0x00
+ // DATW, DB00 and DB01 are defined as global buffer fields
+
+ Store(RBYT(TSAD, 0x01), Local0)
+
+Store(Local0, DBG8)
+
+ If(Not(Local0)) // Read command completed
+ {
+ Return( Local0 )
+ }
+ Else // Read command failed
+ {
+ Store("_TMP Read ERROR", Debug)
+ Return(Add(TMIN, 2)) // MIN trip point + 2.0 C
+ }
+
+} // Method(RTMP)
+
+// MAX1617 Thermal interrupt handler
+Method(THDL,0) {
+//**********************************************************************;
+ // Clear ALARM bit
+ RSBT(0x19, 0) // Receive Byte, Addr 0x18
+ TCHG() // change Trip points
+//**********************************************************************;
+}
+//**********************************************************************;
+// *****************************************************************;
+// *****************************************************************;
+// ** **;
+// ** (C)Copyright 1985-1996, American Megatrends, Inc. **;
+// ** **;
+// ** All Rights Reserved. **;
+// ** **;
+// ** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
+// ** **;
+// ** Phone (770)-246-8600 **;
+// ** **;
+// *****************************************************************;
+// *****************************************************************;
+//**********************************************************************;
+// DON'T CHANGE ANY CODE UNLESS REQUIRED !!!
+//**********************************************************************;
diff --git a/Core/EM/ACPI/Mathco.asl b/Core/EM/ACPI/Mathco.asl
new file mode 100644
index 0000000..3885d93
--- /dev/null
+++ b/Core/EM/ACPI/Mathco.asl
@@ -0,0 +1,50 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Mathco.asl 2 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Mathco.asl $
+//
+// 2 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//;**********************************************************************;
+//-------------------------
+// Math Coprocessor Device
+//-------------------------
+Device(COPR) {
+ Name(_HID,EISAID("PNP0C04"))
+ Name(_CRS, ResourceTemplate()
+ {
+ IO(Decode16, 0xf0, 0xf0, 0, 0x10)
+ IRQNoFlags(){13}
+ })
+} // End of Math Coprocessor
diff --git a/Core/EM/ACPI/MpPciIrq.asm b/Core/EM/ACPI/MpPciIrq.asm
new file mode 100644
index 0000000..e0f5d94
--- /dev/null
+++ b/Core/EM/ACPI/MpPciIrq.asm
@@ -0,0 +1,99 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/BIN/Modules/ACPI/Template/Core/MpPciIrq.asm 3 3/26/09 4:51p Oleksiyy $
+;
+; $Revision: 3 $
+;
+; $Date: 3/26/09 4:51p $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/BIN/Modules/ACPI/Template/Core/MpPciIrq.asm $
+;
+; 3 3/26/09 4:51p Oleksiyy
+; New ACPI Core implementation - improves logic, execution time and
+; memory usage of ACPI module.
+;
+; 2 2/08/07 12:47p Artems
+;
+; 1 2/06/07 4:54p Artems
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: MpPciIrq.asm
+;
+; Description: This file includes MPS related tables, generated by AMISDL
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+IFNDEF EFIx64
+.586P
+option language:c
+ENDIF
+
+; MPS PCI IRQ - APIC description table
+;------------------------------------------------------------------------------
+MP_IRI STRUC
+ PciBusNumber db ?
+ DeviceNumber db ?
+ IntA_ApicItin db ?
+ IntA_ApicId db ?
+ IntB_ApicItin db ?
+ IntB_ApicId db ?
+ IntC_ApicItin db ?
+ IntC_ApicId db ?
+ IntD_ApicItin db ?
+ IntD_ApicId db ?
+ Reserved db ?
+MP_IRI ENDS
+
+MP_IAI STRUC
+ ApicAddress dd ?
+ ApicId db ?
+ Reserved db ?
+MP_IAI ENDS
+
+;IFDEF MpsTable_SUPPORT
+
+IFNDEF EFIx64
+MPSDATA_SEG SEGMENT USE32 'DATA'
+ELSE
+MPSDATA_SEG SEGMENT 'DATA'
+ENDIF
+ include mppciirq.inc
+MPSDATA_SEG ENDS
+
+;ENDIF
+
+end
+
+
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/OSCM.asl b/Core/EM/ACPI/OSCM.asl
new file mode 100644
index 0000000..9a3e76f
--- /dev/null
+++ b/Core/EM/ACPI/OSCM.asl
@@ -0,0 +1,124 @@
+// The ASL file for _OSC Method Implementation
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//-----------------------------------------------------------------------
+
+//;<AMI_PHDR_START>
+//;------------------------------------------------------------------------
+//;
+//; Procedure: _OSC
+//; Description: METHOD CALLED ON SYSTEM STARTUP TO NEGOTIATE OS/BIOS
+//; SUPPORTED FEATURES
+//; Input: Arg0 (Buffer): UUID
+//; Arg1 (Integer): Revision ID
+//; Arg2 (Integer): Count
+//; Arg3 (Buffer): Capabilities Buffer,
+//;
+//; Output: Returns modified Arg3.
+//;
+//;-------------------------------------------------------------------------
+//;<AMI_PHDR_END>
+
+ Method(_OSC,4)
+ {
+ Name(SUPP,0) // PCI _OSC Support Field value
+ Name(CTRL,0) // PCI _OSC Control Field value
+ // Create DWord-adressable fields from the Capabilities Buffer
+ CreateDWordField(Arg3,0,CDW1)
+ CreateDWordField(Arg3,4,CDW2)
+ CreateDWordField(Arg3,8,CDW3)
+ // Check for proper UUID
+ If(LEqual(Arg0,ToUUID("33DB4D5B-1FF7-401C-9657-7441C03DD766")))
+ {
+ // Save Capabilities DWord2 & 3
+ Store(CDW2,SUPP)
+ Store(CDW3,CTRL)
+ //Support Bits:
+ //0 - extended pci config operation region
+ //1 - ASPM supported
+ //2 - Clock Power Management Capability supported
+ //3 - Pci Segment Groups supported
+ //4 - MSI supported
+
+ //Control Bits:
+ //0 - Pci Express Native Hot Plug control
+ //1 - SHPC Native Hot Plug control
+ //2 - Pci Express Native Power Management Events control
+ //3 - Pci Express Advanced Error Reporting control
+ //4 - Pci Express Capability Structure control
+
+ // Only allow native hot plug control if OS supports:
+ // * ASPM
+ // * Clock PM
+ // * MSI/MSI-X
+
+ If(LNotEqual(And(SUPP, 0x16), 0x16))
+ {
+ And(CTRL,0x1E, CTRL) // Mask bit 0 (and undefined bits)
+ }
+ //Tokens ACPI.sdl
+ if (LNot(PEHP))//BIOS Supports PCI Express HP?
+ {
+ And(CTRL,0x1E,CTRL)
+ }
+ if (LNot(SHPC)) //BIOS Supports SHPC Hot Plug ?
+ {
+ And(CTRL,0x1D,CTRL)
+ }
+ if (LNot(PEPM)) //BIOS Supports PCI Express ASPM?
+ {
+ And(CTRL,0x1B,CTRL)
+ }
+ if (LNot(PEER)) //BIOS Supports PCI Express Adv Error Reporting?
+ {
+ And(CTRL,0x15,CTRL)
+ }
+ if (LNot(PECS)) //BIOS Provides PCI Express MCFG Table?
+ {
+ And(CTRL,0xF,CTRL)
+ }
+
+ If(LNotEqual(Arg1,One))
+ { // Unknown revision
+ Or(CDW1,0x08,CDW1)
+ }
+ If(LNotEqual(CDW3,CTRL))
+ { // Certain Capabilities bits were masked
+ Or(CDW1,0x10,CDW1)
+ }
+
+ // Update DWORD3 in the buffer
+ Store(CTRL,CDW3)
+
+ Return(Arg3)
+ } Else {
+ Or(CDW1,4,CDW1) // Unrecognized UUID
+ Return(Arg3)
+ }
+ } // End _OSC
+
+//-----------------------------------------------------------------------
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/PCIEACCESS.ASL b/Core/EM/ACPI/PCIEACCESS.ASL
new file mode 100644
index 0000000..65ac844
--- /dev/null
+++ b/Core/EM/ACPI/PCIEACCESS.ASL
@@ -0,0 +1,170 @@
+//**********************************************************************;
+// *****************************************************************;
+// ** **;
+// ** (C)Copyright 1985-2003, American Megatrends, Inc. **;
+// ** **;
+// ** All Rights Reserved. **;
+// ** **;
+// ** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
+// ** **;
+// ** Phone (770)-246-8600 **;
+// ** **;
+// *****************************************************************;
+//-----------------------------------------------------------------------
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/PCIEACCESS.ASL 1 5/07/09 2:44p Yakovlevs $
+//
+// $Revision: 1 $
+//
+// $Date: 5/07/09 2:44p $
+//****************************************************************;
+//*****************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/PCIEACCESS.ASL $
+//
+// 1 5/07/09 2:44p Yakovlevs
+//
+// 1 12/10/03 2:40p Srinin
+// PCIe access routines added.
+//
+// 1 12/10/03 12:21p Srinin
+// PCIe access routines added.
+//
+//
+//
+//-----------------------------------------------------------------------
+
+Scope (\_SB) {
+
+//PCIe Capability Structure pointer
+
+Name (XCPD, 0x0) // PCIe Cap ID
+Name (XNPT, 0x1) // Next Pointer Cap Pointer
+Name (XCAP, 0x2) // PCIe Capability pointer
+Name (XDCP, 0x4) // Device Capability
+Name (XDCT, 0x8) // Device Control
+Name (XDST, 0xa) // Device Status
+Name (XLCP, 0xc) // Link Capability
+Name (XLCT, 0x10) // Link Control
+Name (XLST, 0x12) // Link Status
+Name (XSCP, 0x14) // Slot Capability
+Name (XSCT, 0x18) // Slot Control
+Name (XSST, 0x1A) // Slot Status
+Name (XRCT, 0x1C) // Root Control
+Mutex(MUTe, 0) //Mutex object to syncronize Memory mapped access
+
+
+
+// Read PCIe Byte Arg0 : Offset (Zero based)
+
+ Method (RbPe, 1) {
+ Acquire(MUTe, 1000)
+ Add (Arg0, \PEBS, Local0) // PEBS : PCIe MM base address
+ OperationRegion (PCFG, SystemMemory, Local0, 0x1)
+
+ Field (PCFG, ByteAcc, Nolock, Preserve){
+ XCFG, 8 ,
+ }
+ Release (MUTe)
+ Return (XCFG)
+ } // End of \SB.RbPe
+
+// Read PCIe Word Arg0 : Offset (Zero based)
+ Method (RwPe, 1) {
+ Acquire(MUTe, 1000)
+ And (Arg0, 0xFFFFFFFE, Arg0)
+ Add (Arg0, \PEBS, Local0) // PEBS : PCIe MM base address
+ OperationRegion (PCFG, SystemMemory, Local0, 0x2)
+
+ Field (PCFG, WordAcc, Nolock, Preserve){
+ XCFG, 16 ,
+ }
+ Release (MUTe)
+ Return (XCFG)
+ } // End of \SB.RwPe
+
+// Read PCIe Dword Arg0 : Offset (Zero based)
+ Method (RdPe, 1) {
+ Acquire(MUTe, 1000)
+ And (Arg0, 0xFFFFFFFC, Arg0)
+ Add (Arg0, \PEBS, Local0) // PEBS : PCIe MM base address
+ OperationRegion (PCFG, SystemMemory, Local0, 0x4)
+
+ Field (PCFG, DwordAcc, Nolock, Preserve){
+ XCFG, 32 ,
+ }
+ Release (MUTe)
+ Return (XCFG)
+ } // End of \SB.RdPe
+
+// Write PCIe byte Arg0 : Offset (Zero based), Arg1 : Value (Byte)
+ Method (WbPe, 2) {
+ Acquire(MUTe, 0xfff)
+ Add (Arg0, \PEBS, Local0)
+ OperationRegion (PCFG, SystemMemory, Local0, 0x1)
+ Field (PCFG, ByteAcc, Nolock, Preserve){
+ XCFG, 8 ,
+ }
+ Store (Arg1,XCFG)
+ Release (MUTe)
+ } // End of \SB.WbPe
+
+// Write PCIe word Arg0 : Offset (Zero based), Arg1 : Value (word)
+ Method (WwPe, 2) {
+ Acquire(MUTe, 1000)
+ And (Arg0, 0xFFFFFFFE, Arg0)
+ Add (Arg0, \PEBS, Local0)
+ OperationRegion (PCFG, SystemMemory, Local0, 0x2)
+ Field (PCFG, WordAcc, Nolock, Preserve){
+ XCFG, 16 ,
+ }
+ Store (Arg1,XCFG)
+ Release (MUTe)
+ } // End of \SB.WwPe
+
+// Write PCIe Dword Arg0 : Offset (Zero based), Arg1 : Value (Dword)
+ Method (WdPe, 2) {
+ Acquire(MUTe, 1000)
+ And (Arg0, 0xFFFFFFFC, Arg0)
+ Add (Arg0, \PEBS, Local0)
+ OperationRegion (PCFG, SystemMemory, Local0, 0x4)
+
+ Field (PCFG, DwordAcc, Nolock, Preserve){
+ XCFG, 32 ,
+ }
+ Store (Arg1,XCFG)
+ Release (MUTe)
+ } // End of \SB.WdPe
+
+
+// RW PCIe Dword Arg0 : Offset (Zero based), Arg1 : Value (Dword), Arg2 : Mask (Dword)
+ Method (RWdP, 3) {
+ Acquire(MUTe, 1000)
+ And (Arg0, 0xFFFFFFFC, Arg0)
+ Add (Arg0, \PEBS, Local0)
+ OperationRegion (PCFG, SystemMemory, Local0, 0x4)
+
+ Field (PCFG, DwordAcc, Nolock, Preserve){
+ XCFG, 32 ,
+ }
+ And (XCFG, Arg2, Local1)
+ Or (Local1, Arg1, XCFG)
+ Release (MUTe)
+ } // End of \_SB.RWdP
+
+// Checks for PME status in Root port status register
+ Method (RPME, 1) { // Arg0 Enhanced config. memory address map
+ add (Arg0, 0x84, Local0)
+ Store (\_SB.RdPe(Local0), Local1)
+ if (LEQUAL(Local1, 0xffffffff)) {
+ Return (0) // PME not asserted
+ }
+ else {
+ if (Land(Local1, 0x10000)) {
+ \_SB.WdPe(Local0, And(Local1, 0x10000))
+ Return (1) // PME asserted
+ }
+ Return (0) // PME not asserted
+ }
+ } // End of RPME
+} // End of \_SB
diff --git a/Core/EM/ACPI/PCIEHP.ASL b/Core/EM/ACPI/PCIEHP.ASL
new file mode 100644
index 0000000..c5b69ee
--- /dev/null
+++ b/Core/EM/ACPI/PCIEHP.ASL
@@ -0,0 +1,346 @@
+//**********************************************************************;
+// *****************************************************************;
+// ** **;
+// ** (C)Copyright 1985-2004, American Megatrends, Inc. **;
+// ** **;
+// ** All Rights Reserved. **;
+// ** **;
+// ** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
+// ** **;
+// ** Phone (770)-246-8600 **;
+// ** **;
+// *****************************************************************;
+//-----------------------------------------------------------------------
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/PCIEHP.ASL 1 5/07/09 2:44p Yakovlevs $
+//
+// $Revision: 1 $
+//
+// $Date: 5/07/09 2:44p $
+//****************************************************************;
+//*****************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/PCIEHP.ASL $
+//
+// 1 5/07/09 2:44p Yakovlevs
+//
+// 1 1/15/09 2:11p Vasudevans
+// Initial check-in for Tylersburg PCIe Hotplug support.
+//
+// 1 12/10/03 2:40p Srinin
+// PCIe HP support added.
+//
+// 1 12/10/03 12:21p Srinin
+// PCIe Hot plug support added.
+//
+//
+//
+//-----------------------------------------------------------------------
+//Constants
+
+Name (SLHC, 0x040) // Slot Hot plug capable
+
+Name (SPDS, 0x040) // Slot Presence Detect state
+Name (MRLS, 0x020) // MRL open
+Name (CCOM, 0x010) // Command complete
+Name (SPDC, 0x08) // Slot Presence Detect Changes
+Name (MRLC, 0x04) // Slot MRL changed
+Name (SPFD, 0x02) // Slot power fault Detected
+Name (SABP, 0x01) // Slot attention button pressed
+
+Name (SPOF, 0x400) // Slot Power off
+Name (SPON, 0x3FF) // Slot Power on Mask
+
+
+Name (ALMK, 0xFF3F) // Slot atten. LED Mask
+Name (ALON, 0x0040) // Slot atten. LED on
+Name (ALBL, 0x0080) // Slot atten. LED Blink
+Name (ALOF, 0x00C0) // Slot atten. LED off
+
+Name (PLMK, 0xFCFF) // Slot Pwr. LED Mask
+Name (PLON, 0x100) // Slot Pwr. LED on
+Name (PLBL, 0x200) // Slot Pwr. LED Blink
+Name (PLOF, 0x300) // Slot Pwr. LED off
+
+Name (HPEV, 0x0F) // Possible interrupt events (all)
+
+
+Scope (\_SB.PCI0) {
+
+ Mutex (MUTH, 0)
+
+//---------------------------------------
+// Hot plug controller command
+//---------------------------------------
+ Method (HPCC, 2) {
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+// ARG1 : Slot Control Register value
+ Acquire(MUTH, 0xFFF)
+ Store (Rwpe(Add(Arg0, XSCT)), Local0)
+ Store (Arg1, Local1)
+ And (Local0, 0x7C0, Local0)
+ And (Local1, 0x7C0, Local1)
+// If (LNotEqual(Local1, Local0)) {
+ Wbpe(Add(Arg0,XSST), CCOM) // Clear the command complete status
+ Wwpe(Add(Arg0, XSCT), Arg1)
+ Store (0, Local0)
+ Sleep (2) // Give time to complete the command
+ While (LLess(Local0, 100)){ // Command completed ?
+ Sleep (10)
+ Add (Local0, 10, Local0)
+ if(LEqual(And(Rwpe(Add(Arg0, XSST)), CCOM), CCOM)){ // Command completed ?
+ If (LGreaterEqual(Local0, 100)) {
+ Break // May not work in all OSes
+ }
+ Store (100, Local0)
+ }
+ }
+ Wbpe(Add(Arg0,XSST), CCOM) // Clear the command complete status
+// }
+// else { // Don't wait for command status to update
+// Wwpe(Add(Arg0, XSCT), Arg1)
+// }
+ Release(MUTH)
+ } // end of HPCC
+
+//---------------------------------------
+// Attention button Indicator
+//---------------------------------------
+ Method (ATCM, 2) {
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+// Arg1 : Attention Indicator Value
+// Check if Attention Indicator is present
+ Store (Rwpe(Add(Arg0, XSCP)), Local0) // Read Slot Capability Register
+ if (And(Local0, 0x08)) { // Attention indicator present
+ Store (Rwpe(Add(Arg0, XSCT)), Local0)// Read Slot Control Register
+ And (Local0, ALMK, Local0) // Clear Attention indicator control
+ If (LEqual(Arg1, 0x01)) { // Attention indicator "ON"?
+ Or (Local0, ALON, Local0)
+ }
+ If (LEqual(Arg1, 0x02)) { // Attention indicator "BLINK"?
+ Or (Local0, ALBL, Local0)
+ }
+ If (LEqual(Arg1, 0x03)) { // Attention indicator "OFF"?
+ Or (Local0, ALOF, Local0)
+ }
+ HPCC (Arg0, local0)
+ }
+ } // End of ATCM
+
+//---------------------------------------
+// Power Indicator
+//---------------------------------------
+ Method (PWCM, 2) {
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+// Arg1 : Power Indicator Value
+// Check if Power Indicator is present
+ Store (Rwpe(Add(Arg0, XSCP)), Local0) // Read Slot Capability Register
+ if (And(Local0, 0x10)) { // Power indicator present
+ Store (Rwpe(Add(Arg0, XSCT)), Local0)
+ And (Local0, PLMK, Local0)
+ If (LEqual(Arg1, 0x01)) { // Power indicator "ON"?
+ Or (Local0, PLON, Local0)
+ }
+ If (LEqual(Arg1, 0x02)) { // Power indicator "BLINK"?
+ Or (Local0, PLBL, Local0)
+ }
+ If (LEqual(Arg1, 0x03)) { // Power indicator "OFF"?
+ Or (Local0, PLOF, Local0)
+ }
+ HPCC (Arg0, local0)
+ }
+ } // End of PWCM
+
+//---------------------------------------
+// Slot Power Control
+//---------------------------------------
+ Method (PWSL, 2) {
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+// Arg1 : Power Controller on/off
+// Check if Power controller is present?
+ Store (Rwpe(Add(Arg0, XSCP)), Local0) // Read Slot Capability Register
+ if (And(Local0, 0x2)) { // Power controller present
+ Store (Rwpe(Add(Arg0, XSCT)), Local0)
+ If (LEqual(Arg1, 0x0)) { // Power slot "OFF"?
+ Or (Local0, SPOF, Local0)
+ }
+ If (LEqual(Arg1, 0x01)) { // Power Slot "ON"?
+ And (Local0, SPON, Local0)
+ }
+ HPCC (Arg0, local0)
+ }
+ } // End of PWSL
+
+//---------------------------------------
+// Attention button Interupt Enable/Disable
+//---------------------------------------
+ Method (ABIE, 2) {
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+// Arg1 : Attention button Interrupt Enable/Disable
+// Check if Attention Button present
+ Store (Rwpe(Add(Arg0, XSCP)), Local0) // Read Slot Capability Register
+ if (And(Local0, SABP)) { // Attention button present
+ Store (Rwpe(Add(Arg0, XSCT)), Local0)
+ If (LEqual(Arg1, 0x0)) { // Disable Attention button interrupt
+ And (Local0, 0xFFFE, Local0)
+ }
+ If (LEqual(Arg1, 0x01)) { // Enable Attention button interrupt
+ Or (Local0, SABP, Local0)
+ }
+ HPCC (Arg0, local0)
+ }
+ } // End of ABIE
+
+
+//---------------------------------------
+// EJection Main Handler
+//---------------------------------------
+ Method (EJMH, 1) {
+ Store(0x62, DBG8) // DBG8 name translates to IO port 80h
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+ Store (Rwpe(Add(Arg0, XSCT)), Local0)
+ Or (Local0, SPOF, Local0) // Power COntroller to Power OFF
+ Or (Local0, PLOF, Local0) // Power Indicator to OFF
+ Or (Local0, ALOF, Local0) // Attention "OFF"
+ HPCC (Arg0, Local0)
+ } // End of EJMH
+
+//---------------------------------------
+// Hnadler of Hot Plug Event
+//---------------------------------------
+ Method (HHPE, 1){
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure
+ Store (RdPe(Arg0), Local0)
+ If (Lequal(Local0, 0xFFFFFFFF)) {Return (0xFF)}
+ Store (RbPe(Add(Arg0,XSST)), Local0)
+ If (And(HPEV, Local0)) { // Check for Slot status
+ Store (PP4H(Arg0), Local0) // Hot plug interrupt Handler
+ Return (Local0) // Return PP4H information
+ }
+ Else {
+ Return (0xFF) // This controller didn't interrupt
+ }
+ }
+
+ Method (PP4H, 1) {
+// Arg0 : Memory mapped Address to PCIe Feature capability Structure 1
+ Store (RbPe(Add(Arg0,XSST)), Local0)
+ If (And(Local0, SABP)) { // Attention button pressed? 2
+ Wbpe(Add(Arg0,XSST),SABP) // Clear interrupt status
+ If (LEqual(And(Local0, SPDS), 0x00)) { // Slot empty? 3
+ PWSL (Arg0, 0x0) // Power off
+ PWCM (Arg0, 0x3) // Power indicator off
+ ATCM (Arg0, 0x3) // Attention indicator off
+ Return (0x03) // Eject Request
+ } // 3
+// Card is present and slot is already powered. User presses attention button to eject the card
+ Store (RwPe(Add(Arg0,XSCT)), Local0)
+ If (LEqual(And(Local0,SPOF), 0x00)) { // Slot already powered 4
+ ABIE (Arg0, 0x0) // Disable Attention button interrupt
+ PWCM (Arg0, 0x02) // Set power Indicator to blink
+ Store (0x0, Local0) // 5sec counter
+ While (LNotEqual(And(Rwpe(Add(Arg0, XSST)), SABP), SABP)){ //Check for Attention button again 5
+ Sleep (200) // Wiat 200msec
+ Add (Local0, 200, Local0)
+ If (Lequal (5000, Local0)){ // 6
+ ABIE (Arg0, 0x1) // Enable Attention button interrupt
+ Return (0x03) // Continue with Eject Request
+ } // 6
+ } // 5
+// User presses attention button again to abort eject request
+ PWCM (Arg0, 0x01) // Set power indicator off
+ Wbpe (Add(Arg0, XSST), SABP) // Clear attention status
+ ABIE (Arg0, 1) // Enable Attention button interrupt
+ Return (0xff) // Do nothing and abort
+ } // 4
+// Card is present and slot is not powered
+// User presses attention button to indicate card is inserted
+ Else { // Slot power is "OFF". So power up the slot 7
+ ABIE (Arg0, 0) // Disable Attention button interrupt
+ PWCM(Arg0, 0x2) // Set power indicator to blink
+// Check if user presses attention button again to cancel the insertion
+ Store (0x0, Local0) // Set 5 sec accumulator to 0
+ While (LNotEqual(And(Rwpe(Add(Arg0, XSST)), SABP), SABP)){ //Check for Attention button again 8
+ Sleep(200)
+ Add(Local0, 200, Local0)
+ if (LEqual(5000, Local0)){ // 9
+ ABIE (Arg0, 1) // Enable Attention button interrupt
+ ATCM (Arg0, 0x3) // Set attention indicator off
+ PWSL (Arg0, 0x1) // Power the slot
+ Sleep (500) // Wait for .5sec for the power to stabilize
+// Check for Power fault Detection
+ If (LNotEqual(And(Rwpe(Add(Arg0, XSST)), SPFD), SPFD)) { // No power fault
+ PWCM (Arg0, 0x1) // Set power indicator to "ON"
+ Return (0x0) // Insertion request
+ }
+ Else { // Power Fault present 10
+ PWCM (Arg0, 0x3) // Set power indicator to OFF
+ PWSL (Arg0, 0x0) // Set power off
+ ATCM (Arg0, 0x2) // Set attention indicator to Blink
+ Return (0x3) // Eject Request
+ } // 10
+ } // 9
+ } // 8
+// User presses attention button again, Leave slot unpowered
+ Wbpe (Add(Arg0, XSST), SABP) // Clear attention status
+ ABIE (Arg0, 1) // Enable Attention button interrupt
+ PWCM (Arg0, 0x3) // Set Power indicator back to "OFF"
+ Return (0xff) //
+ } // End if Slot power if "OFF" 7
+ } // End for Attention button Hot plug interrupt 2
+
+ If (And(Rwpe(Add(Arg0, XSST)), SPFD)) { // Check if power fault detected
+ Wbpe (Add(Arg0, XSST), SPFD) // Clear the power fault Status
+ PWCM (Arg0, 0x3) // Set power indicator to "OFF"
+ PWSL (Arg0, 0x0) // Set power off
+ ATCM (Arg0, 0x2) // Set attention indicator "Blink"
+ Return (0x3) // Eject request
+ } // End for Power Fault Interrupt
+
+
+ If (And(Rwpe(Add(Arg0, XSST)), MRLC)) { // Check if interrupt caused by the MRL sensor
+ Wbpe (Add(Arg0, XSST), MRLC) // Clear the MRL status
+ Return (0x3) // Eject request
+ }
+
+ If (And(Rwpe(Add(Arg0, XSST)), SPDC)) { // Check if Presence Detect changed status 11
+ Wbpe (Add(Arg0, XSST), SPDC) // Clear Presence Detect Changed status
+ If (LEqual(And(Rwpe(Add(Arg0, XSST)), SPDS), 0x00)) { // Check if Slot empty
+ PWSL (Arg0, 0x0) // Set power slot "OFF"
+ PWCM (Arg0, 0x3) // Set power indicator to "OFF"
+ Return (0x3) // Eject Request
+ }
+ Else { // Card is present 12
+ ABIE (Arg0, 0) // Attention button Interrupt disable
+ PWCM (Arg0, 0x2) // Set power indicator to blink
+ Store (0x0, Local0) // set 5 sec accumulator to 0
+ While (LEqual(And(Rwpe(Add(Arg0, XSST)), SABP), 0x00)){ //Check for Attention button again 13
+ Sleep (200) // wait 200ms
+ Add (Local0, 200, Local0)
+ If (LEqual(5000, Local0)){ // 14
+ ABIE (Arg0, 1) // Enable Attention button interrupt
+ ATCM (Arg0, 0x3) // Set attention indicator "OFF"
+ PWSL (Arg0, 0x1) // Power the slot
+ Sleep (500) // wair for 0.5 sec for power to stabilize
+ If (LEqual(And(Rwpe(Add(Arg0, XSST)), SPFD), 0x00)) { // No power fault 16
+ PWCM (Arg0, 0x1) // Set power indicator to "ON"
+ Return (0x0) // Notify OS to load the driver
+ } // 16
+ Else { // Power Fault detected // 15
+ PWCM (Arg0, 0x3) // Set power indicator to "OFF"
+ PWSL (Arg0, 0x0) // Set power "OFF"
+ ATCM (Arg0, 0x2) // Set attention indicator to "Blink"
+ Return (0x3) // Eject request
+ } // End of Power Fault 15
+ } // 14
+ } // 13
+// Attention button pressed to abort the process
+ ABIE (Arg0, 1) // Enable Attention button interrupt
+ PWCM (Arg0, 0x3) // Set power indicator back to "OFF"
+ Return (0xff) //
+ } // End of Slot power on/off 12
+ } // End of Presence Detect changed Hot plug interrupt 11
+ Return (0xff) // Control should not come here
+ } // End of PP4H 1
+} // End of \_SB.PCI0
+
diff --git a/Core/EM/ACPI/PS2kb.asl b/Core/EM/ACPI/PS2kb.asl
new file mode 100644
index 0000000..55cc136
--- /dev/null
+++ b/Core/EM/ACPI/PS2kb.asl
@@ -0,0 +1,121 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/PS2kb.asl 10 5/07/12 10:49a Oleksiyy $
+//
+// $Revision: 10 $
+//
+// $Date: 5/07/12 10:49a $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/PS2kb.asl $
+//
+// 10 5/07/12 10:49a Oleksiyy
+// [TAG] EIP88686
+// [Category] Improvement
+// [Description] Add tokens for _CID and _HID to pass the WHCK
+// [Files] ACPI.sdl, PS2kb.asl and PS2ms.asl
+//
+// 9 2/09/12 2:08p Oleksiyy
+// [TAG] EIP82016
+// [Category] Improvement
+// [Description] Change ASL macro FixedIO to IO
+// [Files] PS2kb.asl and GenericSio.c
+//
+// 8 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 7 4/16/08 12:09p Yakovlevs
+// Changed 0x60 0x64 resources to clame 16 bit IO.
+//
+// 6 4/15/08 9:25p Yakovlevs
+// Moved from OEMDSDT device specific 2nd Level wake up control method and
+// wake flag
+//
+// 5 4/09/08 6:05p Yakovlevs
+//
+// 4 4/09/08 5:10p Yakovlevs
+//
+// 3 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 2 7/12/05 10:57a Girim
+// Updated and Cleaned up the code.
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+// PS2 Keyboard Device, IO category # - 10
+//---------------------------------------------------------------------
+
+
+Device(PS2K) {
+ //Name(_HID,EISAID("PNP0303")) // Standard Keyboard 101/102
+ Method(_HID,0){
+ Return (\HIDK)
+ }
+
+ //Name(_CID,EISAID("PNP030b")) // Compatible ID, PC/AT Enhanced Keyboard 101/102
+ Method(_CID,0){
+ Return (\CIDK)
+ }
+
+ Method(_STA,0) {
+ If(And(\IOST, 0x0400)){
+ Return (0x0F)
+ } else {
+ Return (0x00)
+ }
+ }
+
+ Name(_CRS,ResourceTemplate()
+ {
+ IO(Decode16, 0x60, 0x60, 0, 0x1) //PS2 resource
+ IO(Decode16, 0x64, 0x64, 0, 0x1)
+ IRQNoFlags(){1}
+ })
+
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate(){
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x60, 0x60, 0, 0x1)
+ IO(Decode16, 0x64, 0x64, 0, 0x1)
+ IRQNoFlags(){1}
+ }
+ EndDependentFn()
+ })
+
+ // Keyboard 2nd Level wake up control method
+ Method(_PSW, 1){
+ Store(Arg0, \KBFG)
+ }
+
+}// End of PS2K
+
+Scope(\){
+ Name(\KBFG, 0x01) //Keyboard wake-up flag default enable
+}
diff --git a/Core/EM/ACPI/PS2ms.asl b/Core/EM/ACPI/PS2ms.asl
new file mode 100644
index 0000000..41bf925
--- /dev/null
+++ b/Core/EM/ACPI/PS2ms.asl
@@ -0,0 +1,128 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/PS2ms.asl 8 5/07/12 10:50a Oleksiyy $
+//
+// $Revision: 8 $
+//
+// $Date: 5/07/12 10:50a $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/PS2ms.asl $
+//
+// 8 5/07/12 10:50a Oleksiyy
+// [TAG] EIP88686
+// [Category] Improvement
+// [Description] Add tokens for _CID and _HID to pass the WHCK
+// [Files] ACPI.sdl, PS2kb.asl and PS2ms.asl
+//
+// 7 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 6 4/16/08 12:08p Yakovlevs
+// Added 60, 64 resources when KB is not present.
+//
+// 5 4/15/08 9:22p Yakovlevs
+// Moved from OEMDSDT device specific 2nd Level wake up control method and
+// wake flag
+//
+// 4 4/09/08 6:04p Yakovlevs
+//
+// 3 4/09/08 5:09p Yakovlevs
+// Made _STA return bit set value from \IOST object
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 2 9/17/04 12:10p Yakovlevs
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 6 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+// PS2 Mouse Device, IO category # - 12
+//---------------------------------------------------------------------
+Device(PS2M) {
+
+// Name(_HID, EISAID("PNP0F03")) // Hardware Device ID - Microsoft mouse
+ // check if MSFT Mouse driver supports D3 properly on all MSFT OSes.
+ // It may prevent OS to go to S3 sleep state
+ // Use Logitech _HID instead if OS rejecting to go to S3.
+ Method(_HID,0){
+ Return (\HIDM)
+ }
+// Name(_HID, EISAID("PNP0F12")) // Logitech PS2 Mouse ID
+// Name(_CID, EISAID("PNP0F13")) // Compatible ID
+ Method(_CID,0){
+ Return (\CIDM)
+ }
+
+ Method(_STA, 0) {
+ // Check if PS2Mouse detected in BIOS Post
+ // IOST - bit mask of enabled devices, 0x4000 - PS2M mask
+ If(And(\IOST, 0x4000)){ // Check if PS2MS detected in BIOS Post
+ Return(0x0f)
+ } else {
+ Return(0x00)// device's not present
+ }
+ }
+ Name(CRS1, ResourceTemplate()
+ {
+ IRQNoFlags(){12}
+ })
+ Name(CRS2, ResourceTemplate()
+ {
+ IO(Decode16, 0x60, 0x60, 0, 0x1)
+ IO(Decode16, 0x64, 0x64, 0, 0x1)
+ IRQNoFlags(){12}
+ })
+ Method(_CRS,0)
+ {
+ If(And(\IOST, 0x0400)){ // PS2K is present, I/O resources 0x60 & 0x64 are reserved there
+ Return(CRS1)
+ } else { // single PS/2 mouse(no PS/2 kbd), need to supply I/O resources 0x60 & 0x64 for PS/2 Controller.
+ Return(CRS2)
+ }
+ }
+
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate(){
+ StartDependentFn(0, 0) {
+ IRQNoFlags(){12}
+ }
+ EndDependentFn()
+ })
+
+ // Mouse 2nd Level wake up control method
+ Method(_PSW, 1){
+ Store(Arg0, \MSFG)
+ }
+
+}// End of PS2M
+
+Scope(\){
+ Name(\MSFG, 0x01) //Mouse wake-up flag default enable
+}
diff --git a/Core/EM/ACPI/RbRes.asl b/Core/EM/ACPI/RbRes.asl
new file mode 100644
index 0000000..b2b8d6a
--- /dev/null
+++ b/Core/EM/ACPI/RbRes.asl
@@ -0,0 +1,501 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: NBRes.ASL
+//
+// Description: PCI Root Bridge resources buffer and CRS Method
+// MUST be included from NB.ASL directly using "include" ASL term
+// Suppose to be already in ROOT BRIDGE Device ASL Scope.
+//
+// NOTE: NO Porting needed
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//Defining some place holders, we need to updte at runtime.
+ Name(CPRB, 0x0) //BOOLEAN Compatible Root Bridge if !=0
+ Name(LVGA, 0x55) //BOOLEAN Legacy Video Present if !=0
+ Name(STAV,0x0F)
+//Information Provided in RootBridgeIo->Configuration() function.
+ Name(BRB, 0x0100) //Bus Range Base
+ Name(BRL, 0x0100) //Bus Range Length
+
+ Name(IOB, 0x0100) //IO Range BASE (16bit resource)
+ Name(IOL, 0x0100) //IO Range LENGTH
+
+ Name(MBB, 0x10000) //Memory Range Below 4G BASE (32bit resource)
+ Name(MBL, 0x10000) //Memory Range Below 4G LENGTH (32bit resource)
+
+ Name(MABL, 0x10000) //Memory Range Above 4G BASE LSDW (32bit resource)
+ Name(MABH, 0x10000) //Memory Range Above 4G BASE MSDW (32bit resource)
+
+ Name(MALL, 0x10000) //Memory Range Above 4G LENGTH LSDW (32bit resource)
+ Name(MALH, 0x10000) //Memory Range Above 4G LENGTH LSDW (32bit resource)
+
+ Name(MAML, 0x10000) //Memory Range Above 4G LENGTH LSDW (32bit resource)
+ Name(MAMH, 0x10000) //Memory Range Above 4G LENGTH LSDW (32bit resource)
+
+//---------------------------------------------------------------------------
+ //Resource buffer to be used for COMPATIBILITY ROOT BRIDGE (one that decodes ISA resources)
+ Name(CRS1, ResourceTemplate() {
+ WORDBusNumber( //Bus number resource (0); the bridge produces bus numbers for its subsequent buses
+ ResourceProducer, // bit 0 of general flags is 1
+ MinFixed, // Range is not fixed
+ MaxFixed, // Range is not fixed
+ PosDecode, // PosDecode
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x007f, // Max; half of the available bus numbers are reserved for this root bus
+ 0x0000, // Translation
+ 0x0080, // Range Length
+ ,,
+ BUS1
+ )
+
+ // CF8 - CFC
+ IO( //Consumed resource for 1st root bus(CF8-CFF)
+ Decode16,
+ 0x0cf8,
+ 0xcf8,
+ 1,
+ 8
+ )
+
+ // All IO below 3B0
+ WORDIO( //Consumed-and-produced resource (all I/O below 3B0 is assigned to this root bus)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x03af, // Max
+ 0x0000, // Translation
+ 0x03b0 // Range Length
+ )
+
+ // 3E0 - CF7
+ WORDIO( //Consumed-and-produced resource (all I/O between 3E0 and CF8 is assigned to this root bus)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x03e0, // Min
+ 0x0cf7, // Max
+ 0x0000, // Translation
+ 0x0918 // Range Length
+ )
+
+ // For Legacy Video IO (3B0 - 3DF)
+ WORDIO( //Consumed-and-produced resource (Used for legacy video)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x0000, // Max
+ 0x0000, // Translation
+ 0x0000, // Range Length
+ ,,
+ VIO1
+ )
+
+ // Other IO used by this root bridge
+ WORDIO( //Consumed-and-produced resource
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0d00, // Min
+ 0x0fff, // Max
+ 0x0000, // Translation
+ 0x0300, // Range Length
+ ,,
+ IOW2
+ )
+
+ // For Legacy Video Memory (A000 - BFFF)
+ DWORDMEMORY( // descriptor for video RAM behind ISA bus
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x00000000, // Min
+ 0x00000000, // Max
+ 0x00000000, // Translation
+ 0x00000000, // Range Length
+ ,,
+ VGA1
+ )
+
+ // ISA Option ROMs
+ DWORDMEMORY( // for device ROMs for ISA plugins devices
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ NonCacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x000c0000, // Min
+ 0x000dffff, // Max
+ 0x00000000, // Translation
+ 0x00020000 // Range Length
+ )
+
+ // Memory < 4GB
+ DWORDMEMORY( // Consumed-and-produced resource(all of memory space)
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode, // positive Decode
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x02000000, // Min (calculated dynamically)
+ 0xffdfffff, // Max = 4GB - 2MB
+ 0x00000000, // Translation
+ 0xfdfc0000, // Range Length (calculated dynamically)
+ , // Optional field left blank
+ , // Optional field left blank
+ MEM3 // Name declaration for this descriptor
+ )
+
+ // Memory > 4GB
+ QWORDMEMORY( // descriptor for MMIO ABOVE 4G
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x00000000, // Min
+ 0x00000000, // Max
+ 0x00000000, // Translation
+ 0x00000000, // Range Length
+ ,,
+ MEM8
+ )
+
+ })//End resource template Name CRS1
+
+
+ //Resource buffer to be used for NONE COMPATIBILITY ROOT BRIDGE
+ Name(CRS2, ResourceTemplate() {
+ WORDBusNumber( //Bus number resource (0); the bridge produces bus numbers for its subsequent buses
+ ResourceProducer, // bit 0 of general flags is 1
+ MinFixed, // Range is not fixed
+ MaxFixed, // Range is not fixed
+ PosDecode, // PosDecode
+ 0x0000, // Granularity
+ 0x0080, // Min
+ 0x00ff, // Max; half of the available bus numbers are reserved for this root bus
+ 0x0000, // Translation
+ 0x0080, // Range Length
+ ,,
+ BUS2
+ )
+
+ // For Legacy Video IO (3B0 - 3DF)
+ WORDIO( //Consumed-and-produced resource (Used for legacy video)
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x0000, // Max
+ 0x0000, // Translation
+ 0x0000, // Range Length
+ ,,
+ VIO2
+ )
+
+ // Other IO used by this root bridge
+ WORDIO( //Consumed-and-produced resource
+ ResourceProducer, // bit 0 of general flags is 0
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is fixed
+ PosDecode,
+ EntireRange,
+ 0x0000, // Granularity
+ 0x0000, // Min
+ 0x0000, // Max
+ 0x0000, // Translation
+ 0x0000, // Range Length
+ ,,
+ IOW3
+ )
+
+ // For Legacy Video Memory (A000 - BFFF)
+ DWORDMEMORY( // descriptor for video RAM behind ISA bus
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x00000000, // Min
+ 0x00000000, // Max
+ 0x00000000, // Translation
+ 0x00000000, // Range Length
+ ,,
+ VGA2
+ )
+
+ // Memory < 4GB
+ DWORDMEMORY( // descriptor for video RAM behind ISA bus
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x80000000, // Min
+ 0xffffffff, // Max
+ 0x00000000, // Translation
+ 0x80000000, // Range Length
+ ,,
+ MEM1
+ )
+
+ // Memory > 4GB
+ QWORDMEMORY( // descriptor for MMIO ABOVE 4G
+ ResourceProducer, // bit 0 of general flags is 0
+ PosDecode,
+ MinFixed, // Range is fixed
+ MaxFixed, // Range is Fixed
+ Cacheable,
+ ReadWrite,
+ 0x00000000, // Granularity
+ 0x00000000, // Min
+ 0x00000000, // Max
+ 0x00000000, // Translation
+ 0x00000000, // Range Length
+ ,,
+ MEM9
+ )
+ } ) //End resource template Name CRS2
+
+ Method(_STA, 0){
+ Return(STAV)
+ }
+
+ Method(_CRS, 0) {
+
+ //breakpoint
+
+
+ //This is for compatibility bridges
+ If(CPRB){
+
+ //Bus Range
+ CreateWordField(CRS1, ^BUS1._MIN, MIN0) // Min
+ CreateWordField(CRS1, ^BUS1._MAX, MAX0) // Max
+ CreateWordField(CRS1, ^BUS1._LEN, LEN0) // Length
+
+ Store(BRB, MIN0)
+ Store(BRL, LEN0)
+ Store(LEN0,Local0)
+ Add(MIN0, Decrement(Local0), MAX0)
+
+ //Update Upper IO from 0x0D00 up to IOB+IOL
+ CreateWordField(CRS1, ^IOW2._MIN, MIN1) // Min
+ CreateWordField(CRS1, ^IOW2._MAX, MAX1) // Max
+ CreateWordField(CRS1, ^IOW2._LEN, LEN1) // Length
+
+
+ If(LEqual(IOB, 0x1000)){
+ Store(IOL, Local0)
+ Add(IOB, Decrement(Local0), MAX1)
+ Subtract(MAX1,MIN1,Local0)
+ Add(Local0,1,LEN1)
+ } else {
+ Store(IOB, MIN1)
+ Store(IOL, LEN1)
+ Store(LEN1,Local0)
+ Add(MIN1, Decrement(Local0), MAX1)
+ }
+
+ If(LOr(LEqual(LVGA,1),LEqual(LVGA,0x55))){
+ if(VGAF){//will update this only once.
+ CreateWordField(CRS1, ^VIO1._MIN, IMN1) // Min
+ CreateWordField(CRS1, ^VIO1._MAX, IMX1) // Max
+ CreateWordField(CRS1, ^VIO1._LEN, ILN1) // Length
+
+ Store(0x03b0, IMN1)
+ Store(0x03df, IMX1)
+ Store(0x0030, ILN1)
+
+ CreateDWordField(CRS1, ^VGA1._MIN, VMN1) // Min
+ CreateDWordField(CRS1, ^VGA1._MAX, VMX1) // Max
+ CreateDWordField(CRS1, ^VGA1._LEN, VLN1) // Length
+
+ Store(0x000a0000, VMN1)
+ Store(0x000bffff, VMX1)
+ Store(0x00020000, VLN1)
+ Store(0, VGAF)
+ }
+ }
+
+ //Update MMIO Below 4G
+ CreateDWordField(CRS1, ^MEM3._MIN, MIN3) // Min
+ CreateDWordField(CRS1, ^MEM3._MAX, MAX3) // Max
+ CreateDWordField(CRS1, ^MEM3._LEN, LEN3) // Length
+
+ Store(MBB, MIN3)
+ Store(MBL, LEN3)
+ Store(LEN3,Local0)
+ Add(MIN3, Decrement(Local0), MAX3)
+
+ If(LOr(MALH,MALL)){
+ CreateDWordField(CRS1, ^MEM8._MIN, MN8L) // Min_LO
+ Add(^MEM8._MIN,4,Local0)
+ CreateDWordField(CRS1, Local0, MN8H) // Min_HI
+ Store(MABL, MN8L)
+ Store(MABH, MN8H)
+
+ CreateDwordField(CRS1, ^MEM8._MAX, MX8L) // Max_LO
+ Add(^MEM8._MAX,4,Local1)
+ CreateDWordField(CRS1, Local1, MX8H) // Max_HI
+
+ CreateDwordField(CRS1, ^MEM8._LEN, LN8L) // Len_LO
+ Add(^MEM8._LEN,4,Local2)
+ CreateDWordField(CRS1, Local2, LN8H) // Len_HI
+
+ //Update fields.
+ //1. _MIN 64bits...
+ Store(MABL, MN8L)
+ Store(MABH, MN8H)
+ //2. _LEN 64Bits
+ Store(MALL, LN8L)
+ Store(MALH, LN8H)
+ //2. _MAX 64Bits
+ Store(MAML, MX8L)
+ Store(MAMH, MX8H)
+ }
+
+ Return(CRS1)
+ } else {
+ //Bus Range
+ CreateWordField(CRS2, ^BUS2._MIN, MIN2) // Min
+ CreateWordField(CRS2, ^BUS2._MAX, MAX2) // Max
+ CreateWordField(CRS2, ^BUS2._LEN, LEN2) // Length
+
+ Store(BRB, MIN2)
+ Store(BRL, LEN2)
+ Store(LEN2,Local1)
+ Add(MIN2, Decrement(Local1), MAX2)
+
+ //Update Upper IO from IOB up to IOB+IOL
+ CreateWordField(CRS2, ^IOW3._MIN, MIN4) // Min
+ CreateWordField(CRS2, ^IOW3._MAX, MAX4) // Max
+ CreateWordField(CRS2, ^IOW3._LEN, LEN4) // Length
+
+ Store(IOB, MIN4)
+ Store(IOL, LEN4)
+ Store(LEN4,Local1)
+ Add(MIN4, Decrement(Local1), MAX4)
+
+ If(LVGA){
+ CreateWordField(CRS2, ^VIO2._MIN, IMN2) // Min
+ CreateWordField(CRS2, ^VIO2._MAX, IMX2) // Max
+ CreateWordField(CRS2, ^VIO2._LEN, ILN2) // Length
+
+ Store(0x03b0, IMN2)
+ Store(0x03df, IMX2)
+ Store(0x0030, ILN2)
+
+ CreateDWordField(CRS2, ^VGA2._MIN, VMN2) // Min
+ CreateDWordField(CRS2, ^VGA2._MAX, VMX2) // Max
+ CreateDWordField(CRS2, ^VGA2._LEN, VLN2) // Length
+
+ Store(0x000a0000, VMN2)
+ Store(0x000bffff, VMX2)
+ Store(0x00020000, VLN2)
+ }
+
+ //Update MMIO Below 4G
+ CreateDWordField(CRS2, ^MEM1._MIN, MIN5) // Min
+ CreateDWordField(CRS2, ^MEM1._MAX, MAX5) // Max
+ CreateDWordField(CRS2, ^MEM1._LEN, LEN5) // Length
+
+ Store(MBB, MIN5)
+ Store(MBL, LEN5)
+ Store(LEN5,Local1)
+ Add(MIN5, Decrement(Local1), MAX5)
+
+ //Update Above 4G memory space if any
+ If(LOr(MALH, MALL)){
+ CreateDWordField(CRS2, ^MEM9._MIN, MN9L) // Min_LO
+ Add(^MEM9._MIN,4,Local0)
+ CreateDWordField(CRS2, Local0, MN9H) // Min_HI
+
+ CreateDwordField(CRS2, ^MEM9._MAX, MX9L) // Max_LO
+ Add(^MEM9._MAX,4,Local1)
+ CreateDWordField(CRS2, Local1, MX9H) // Max_HI
+
+ CreateDwordField(CRS2, ^MEM9._LEN, LN9L) // Len_LO
+ Add(^MEM9._LEN,4,Local2)
+ CreateDWordField(CRS2, Local2, LN9H) // Len_HI
+
+ //Update fields.
+ //1. _MIN 64bits...
+ Store(MABL, MN9L)
+ Store(MABH, MN9H)
+ //2. _LEN 64Bits
+ Store(MALL, LN9L)
+ Store(MALH, LN9H)
+ //2. _MAX 64Bits
+ Store(MAML, MX9L)
+ Store(MAMH, MX9H)
+ }
+
+ Return(CRS2)
+ }
+
+ } // end ROOT BRIDGE PCIx._CRS Method
+//----------------------------------------------------------------------------
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/ACPI/SMB_EC.ASL b/Core/EM/ACPI/SMB_EC.ASL
new file mode 100644
index 0000000..b82bdfb
--- /dev/null
+++ b/Core/EM/ACPI/SMB_EC.ASL
@@ -0,0 +1,91 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/SMB_EC.ASL 2 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/SMB_EC.ASL $
+//
+// 2 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 2 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+//**********************************************************************;
+// DON'T CHANGE ANY NAMES UNLESS REQUIRED !!!
+//**********************************************************************;
+// ACPI Embedded controller SMBus interface methods
+//**********************************************************************;
+
+// SMBR - SMBus read method
+//
+// Arg0 - Device address
+// Arg1 - Command Code
+// Arg2 - Data to write
+// Arg3 - Protocol (basically RDWD, WRWD or RDBL)
+
+ Method(SMBR,4) {
+ If (LEqual(Arg3,RDBL)) {Store(0,DATB)}
+ Store(5, Local0)
+ While(Local0) {
+ Store(Arg0, ADDR) // Set the device address
+ Store(Arg1, SCMD) // Read Power unit value 0x3 offset
+ If (LEqual(Arg3, WRWD)) {Store(Arg2, DAT0)}
+ Store(Arg3, PRTC) // Set protocol - start SMBus transaction
+ Wait(SMBF, 0xFFF) // Wait till SMBus transaction completed
+
+ Reset(SMBF)
+
+// One of known problems - ReadBlock of GLW SmartBattery may return BCNT=3
+// and data as FF FF FF with no any SMBus errors. To avoid this:
+// If(Or(SSTS,And(LEqual(Arg2,RDBL),And(LEqual(BCNT,3),LEqual(DAT0,0xFFFF)))))
+ If(SSTS)
+ {Decrement(Local0)} // If any SMBus error
+
+ Else {
+ Return(Ones) // exit on OK
+ }
+ }
+ Return(Zero) // exit on failure
+ }
+
+//**********************************************************************;
+// *****************************************************************;
+// *****************************************************************;
+// ** **;
+// ** (C)Copyright 1985-1996, American Megatrends, Inc. **;
+// ** **;
+// ** All Rights Reserved. **;
+// ** **;
+// ** 6145-F Northbelt Pkwy, Norcross, GA 30071 **;
+// ** **;
+// ** Phone (770)-246-8600 **;
+// ** **;
+// *****************************************************************;
+// *****************************************************************;
diff --git a/Core/EM/ACPI/TimeAndAlarm.asl b/Core/EM/ACPI/TimeAndAlarm.asl
new file mode 100644
index 0000000..31ecd78
--- /dev/null
+++ b/Core/EM/ACPI/TimeAndAlarm.asl
@@ -0,0 +1,523 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/TimeAndAlarm.asl 1 1/23/14 5:25p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 1/23/14 5:25p $
+
+
+
+ // !!! IMPORTANT !!! !!! IMPORTANT !!! !!! IMPORTANT !!! !!! IMPORTANT !!!
+ // This is an example of ACPI Time and Alarm Device implementation, proven to be working on Sharkbay platform.
+ // On different platforms this code may not work "as is" and may require light or heavy modification
+
+
+ // ACPI RTC device
+ //
+ // Note: we assume 24-hr mode and date/time in BCD.
+
+ Device(TAAD)
+ {
+ Name (_HID, "ACPI000E")
+ Name (_CID, "ACPI000E")
+ Name (_UID, 1)
+
+ Name(PRWP, Package(){Zero, 4})
+ Method(_PRW, 0) { Return(PRWP) } // can wakeup from S4 state
+
+ Name (TMZN, 2047) // Timezone - set to 2047 to indicate value not specified. Will be used if no buffer for SMI was found
+ Name (DAYL, 0) // daylight - bit field to indicate daylight adjustment requirement. Will be used if no buffer for SMI was found
+ Name (ALWS, 0xF) // Init Alarm wake status - Stores alarm wake status; 0xF to indicate contents are invalid
+
+ Name (ATBF, 0x100000000) //Adress of communication buffer
+ Name (BUFU, 0x0) //Indicator that buffer was allocated and usable.
+
+ //Mutex used to synchronize between methods accessing RTC
+ Mutex(RTCL, 0)
+
+ // Region for SW SMI port
+ OperationRegion (CSMI, SystemIO, SMIP , 0x1)
+ Field (CSMI, ByteAcc, NoLock, Preserve)
+ {
+ INQ,8
+ }
+
+ OperationRegion (ADPS, SystemIO, PMBS, 4)
+ Field (ADPS, ByteAcc,NoLock,Preserve)
+ {
+ PMS, 16,
+ PMEN, 16
+ }
+
+ // Regions for SW SMI data buffer. Need two, one for byte access, one for nibble access.
+ OperationRegion (DSMI, SystemMemory, ATBF, 0x4)
+ Field (DSMI, AnyAcc, NoLock, Preserve)
+ {
+ BSTA, 8,
+ BDLY, 8,
+ BTZN, 16
+ }
+
+
+ OperationRegion(VRTC, SystemCMOS, 0, 0x10)
+ Field(VRTC, ByteAcc, Lock, Preserve)
+ {
+
+ SEC, 8,
+ SECA, 8,
+
+ MIN, 8,
+ MINA, 8,
+
+ HOR, 8,
+ HORA, 8,
+
+ DAYW, 8,
+ DAY, 8,
+
+ MON, 8,
+ YEAR, 8,
+
+ STAA, 8,
+ STAB, 8,
+ STAC, 8,
+ STAD, 8
+ }
+
+ Method(_S1W, 0) {
+ return (0)
+ }
+ Method(_S2W, 0) {
+ return (0)
+ }
+ Method(_S3W, 0) {
+ return (3)
+ }
+ Method(_S4W, 0) {
+ return (3)
+ }
+
+ Method(_DSW, 3) {
+
+ // Disable the device's wake capabilities
+ if( LEqual(Arg0, 0) ) {
+ And(PMEN, 0x0400, PMEN)
+ }
+ if( LEqual(Arg0, 1) ) {
+ if( LLessEqual(Arg1, 4) ){
+ Or(PMEN, 0x400, PMEN)
+ }
+ }
+ return
+ }
+
+ // RTC Allow Update
+ Method (ALLW, 0x0, Serialized) {
+ Acquire(RTCL, 2000)
+
+ And(STAB, 0x7F, STAB)
+
+ Release(RTCL)
+ Return (One)
+ }
+
+ // RTC Inhibit Update
+ Method (INHB, 0x00, Serialized) {
+ Acquire(RTCL, 2000)
+ Or(STAB, 0x80, STAB)
+ Release(RTCL)
+ Return (One)
+ }
+
+ Method (RTWT, 0x00) {
+ Acquire(RTCL, 2000)
+
+ // Loop until an update completes (the Update-Ended Flag (UF) is set)
+ While( LNotEqual(And(STAC, 0x10), 0x10 )){
+ NoOp
+ }
+
+ Release(RTCL)
+ return (One)
+ }
+
+ // Get Capability
+ // This object is required and provides the OSPM with a bit mask of the device capabilities. The device
+ // can implement the time function inaddition to the wake function. The capabilities bitmask will
+ // indicate to the OSPM what support is implemented. If the platform implements both AC and DC
+ // timers then it is capable of waking up based on the power source
+
+ // Only AC timer here, so it will be the wake source regardless of the power source
+ Method (_GCP, 0x0, NotSerialized)
+ {
+ //Store(0x11, DBG8)
+ Return (0x5) //Get/Set real time features implemented, real time accuracy in seconds and AC timer only;
+ }
+
+
+ // Get Real time Method
+ // This object is required ifthe capabilities bit 2 is set to 1. The OSPM can use this object to get time.
+ // The return value is a buffer containing the time information
+ Method (_GRT, 0x0, Serialized)
+ {
+ Name(RBUF, Buffer(16) {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}) //Buffer of 16 bytes - return value
+
+ // Create fields to address different offsets in the buffer
+ CreateWordField(RBUF, 0x0, TYAR)
+ CreateByteField(RBUF, 0x2, TMON)
+ CreateByteField(RBUF, 0x3, TDAY)
+ CreateByteField(RBUF, 0x4, THOR)
+ CreateByteField(RBUF, 0x5, TMIN)
+ CreateByteField(RBUF, 0x6, TSEC)
+ CreateByteField(RBUF, 0x7, TVAL) // Time Valid if 1, not valid if 0
+ CreateWordField(RBUF, 0xA, TZN) // Timezone not supported through rRTC - return value stored in ASL
+ CreateByteField(RBUF, 0xC, DYL) // Daylight not supported through rRTC - emulate in ASL
+
+ if (BUFU)
+ {
+ // Read value from NVRAM
+ Store (0x01, BSTA)
+ Store (ATAA, INQ)
+ Sleep (100)
+
+ if( LEqual(BSTA, 0x03 ) ) {
+ Store (BDLY, DAYL)
+ Store (BTZN, TMZN)
+ } else {
+ Store(2047, TMZN)
+ Store (0, DAYL)
+ }
+ }
+
+ RTWT()
+
+ FromBCD(YEAR, TYAR) // Get Year
+ FromBCD (MON, TMON) // Get Month
+ FromBCD (DAY, TDAY) // Get Day
+ FromBCD (HOR, THOR)
+ FromBCD (MIN, TMIN)
+ FromBCD (SEC, TSEC)
+
+ Store (TMZN, TZN)
+ Store (DAYL, DYL)
+
+ // we don't have centry byte
+ ADD(TYAR, 2000, TYAR)
+
+ Store (0x1, TVAL) // Data valid
+ return (RBUF)
+ }
+
+ // Set Real Time
+ // This object is required if the capabilities bit 2 is set to 1. The OSPM can use this object to set the
+ // time. The argument is a buffer containingthe time information
+
+ Method (_SRT, 0x1, Serialized)
+ {
+ CreateWordField(Arg0, 0x0, TYAR)
+ CreateByteField(Arg0, 0x2, TMON)
+ CreateByteField(Arg0, 0x3, TDAY)
+ CreateByteField(Arg0, 0x4, THOR)
+ CreateByteField(Arg0, 0x5, TMIN)
+ CreateByteField(Arg0, 0x6, TSEC)
+ CreateWordField(Arg0, 0xA, TZN) // Timezone not supported through rRTC - return value stored in ASL
+ CreateByteField(Arg0, 0xC, DYL) // Daylight not supported through rRTC
+
+ // TODO: Adjust the timezone, daylight, date and time based on the daylight bitmask
+
+ if (BUFU)
+ {
+ // Send Daylight to NVRAM
+ Store (0x2, BSTA)
+ Store (DYL, BDLY)
+ Store (TZN, BTZN)
+
+ Store (ATAA, INQ)
+ }
+
+ RTWT()
+
+ ToBCD(Subtract(TYAR, 2000), YEAR)
+ ToBCD (TMON, MON) // Set month
+ ToBCD (TDAY, DAY) // Set day
+ ToBCD (THOR, HOR) // Set hour
+ ToBCD (TMIN, MIN) // Set minute
+ ToBCD (TSEC, SEC) // Set second
+
+ Store (TZN, TMZN)
+ Store (DYL, DAYL)
+
+ If(LEqual(BSTA, 0x3)) // SMI handler set status to OK
+ {
+ return (0x0) // return success
+ }
+
+ return (0xFFFFFFFF) // return error
+ }
+
+ // Get wake Status
+ //This object is required and enables the OSPM to read the status ofwake alarms. Expired wake timers
+ //will wake the platform even if the transition to a sleep state was completed after the wake timer has
+ //expired. This method enables the OSPM to retrieve the status of wake timers and clear any of them if
+ //needed.
+
+ Method (_GWS, 0x1, Serialized)
+ {
+ // From the ACPI specification
+ // "Writes to the DC timer when AC only wake is supported will be ignored"
+ if (LEqual(0x1, Arg0)) {
+ return (0x0)
+ }
+
+ // read alarm status from Register C and remember if it was set
+ // if it wasn't set, keep alarm wake status field invalid
+ // if it was set, indicate to the OS that the alarm expired and that it woke the system.
+ // TODO: Find out if the alarm woke the system, for now assume it did (this will need usage of SMI
+ // handlers.)
+
+ if (LEqual(0xF, ALWS)) {
+ if (LAnd (STAC, 0x20)) {
+ Store (0x3, ALWS)
+ return (ALWS)
+ }
+ }
+
+ return (0x0)
+ }
+
+ // Clear Wake alarm status.
+ //This object is required and enables the OSPM to clear the status of wake alarms. Expired wake
+ //timers will wake the platform even if the transition to a sleep state was completed after the wake
+ //timer has expired. This method enables the OSPMto clear the status of expired wake timers.
+ Method (_CWS, 0x1, Serialized)
+ {
+ // From the ACPI specification
+ // "Writes to the DC timer when AC only wake is supported will be ignored"
+ if (LEqual(1, Arg0)) {
+ return (0)
+ }
+
+ RTWT()
+
+ INHB()
+ // Clear the alarm seconds, alarm minutes and alarm hours
+ Store (0x00, SECA)
+ Store (0x00, MINA)
+ Store (0x00, HORA)
+ ALLW()
+
+ // Clear the "Date Alarm" in RTC_REGD (bits 5:0)
+ And (STAD, 0x80, STAD)
+
+ // Reading Register C should clear the "Alarm Flag (AF)" (Bit5)
+ if (LEqual(0xF, ALWS)) {
+ Store (STAC, Local0)
+ }
+
+ // Disable the "Alarm Interrupt Enable" (AIE) bit in RTC_REGB
+ And(STAB, 0xDF, STAB)
+
+ // Mark ALWS invalid
+ Store (0xF, ALWS)
+
+ return (0x0)
+ }
+
+ // Sets the timer wake policy.
+
+ //This object is required and sets the expired timer wake policy.The policy is applied when a
+ //corresponding timer expired but the wake signal was not asserted as a result of the power source.
+ //The platform accumulates elapsed time on the power source and asserts the wake signal when the
+ //elapsed timer on the power source exceeds the expired timer wake policy value. Power source
+ //transitions do not reset the expired timer wake policy values. When the Wake Alarm device asserts
+ //the wake, the expired timer wake policy values ofboth the AC timer and DC timer are reset to
+ //0xFFFFFFFF automatically by hardware.
+
+ Method (_STP, 0x2, Serialized)
+ {
+ // From the ACPI specification
+ // "Writes to the DC timer when AC only wake is supported will be ignored"
+ if (LEqual(0x1, Arg0)) {
+ return (0)
+ }
+
+ //
+ if (LGreater(Arg1, 0x01)) {
+ return (0x1)
+ }
+
+ return (0x0)
+ }
+
+ // Set the value in specified timer
+
+ //This object is required and setsthe timer to the specified value. As defined in _TIV, the value
+ //indicates the number of seconds between the time when the timer is programmed and the time when
+ //it expires. When the Wake Alarm device asserts the wake signal, the timer value is automatically
+ //reset to 0xFFFFFFFF (disabled).
+ Method (_STV, 0x2, Serialized)
+ {
+ Name(THOR, 0)
+ Name(TMIN, 0)
+ Name(TSEC, 0)
+
+ // From the ACPI specification
+ // "Writes to the DC timer when AC only wake is supported will be ignored"
+ if (LEqual(0x01, Arg0)) {
+ return (0x0)
+ }
+
+
+ // RTC hours/minutes/seconds cannot be set for more than 23 hours, 59 minutes
+ // and 59 seconds in the future, otherwise we would be setting the current time
+ // and the alarm would tigger immediatly
+ if (LGreater(Arg1, 86399)) {
+ return (0x1)
+ }
+
+ // Divide the time (which is passed in seconds) into hours, minutes and seconds
+ Divide(Arg1, 60, TSEC, TMIN)
+ Divide(TMIN, 60, TMIN, THOR)
+
+ RTWT()
+ // Add the current seconds to the number of seconds in the future to set the alarm
+ // and check if its greater than 59
+ if( LGreater(Add(FromBCD(SEC), TSEC, TSEC), 59) ){
+ // It is greater than 59, so get the mod 60 and convert to BCD and store into the
+ // the seconds alarm. Increment the TMIN too
+ ToBCD(Mod(TSEC, 60), Local1)
+ INCREMENT(TMIN)
+ } else {
+ // Its less than 60, just conver to BCD and store it
+ ToBCD(TSEC, Local1)
+ }
+ Store(Local1, TSEC)
+
+ // Add the current minutes to the number of minutes in the future
+ // and check if its greater than 59
+ if( LGreater(Add(FromBCD(MIN), TMIN, TMIN), 59) ){
+ // It is greater than 59, so get the mod 60 and store it into
+ // the minutes alarm and increment the THORs
+ ToBCD(Mod(TMIN, 60), Local1)
+ INCREMENT(THOR)
+ } else {
+ // Its less than 60, just conver to BCD and store it
+ ToBCD(TMIN, Local1)
+ }
+ Store(Local1, TMIN)
+
+ // Add the current hours to the number of hours in the future
+ // and check if its greater than 24
+ if( LGreater(Add(FromBCD(HOR), THOR, THOR), 23) ){
+ // It is greater than 63, so get the mod 24 and store it into
+ // the hours alarm
+ ToBCD(Mod(THOR, 60), Local1)
+ } else {
+ ToBCD(THOR, Local1)
+ }
+ Store(Local1, THOR)
+
+ // Inhibit updating and then program the Alarm
+ INHB()
+ Store(THOR, HORA)
+ Store(TMIN, MINA)
+ Store(TSEC, SECA)
+
+ // Clear the Date Alarm in RTC_REGD (bits 5:0) to ensure they do not
+ // interfere the RTC alarm
+ And (STAD, 0x80, STAD)
+
+ // Write the Alarm Interrupt Enable (AIE) bit in RTC_REGB
+ OR(STAB, 0x20, STAB)
+ ALLW()
+
+ Or(PMEN, 0x0400, PMEN)
+ Or(PMS, 0x0400, PMS)
+
+ return (0x0)
+ }
+
+ // Get the timer wake policy of the specified timer
+ //This object returns the current expired timer wake policy setting ofthe specified timer.
+
+ // Ret Value is an Integer (DWORD) containing current expired timer wake policy:
+ //0x00000000 - The timer will wake up the system instantly after the power source changes
+ //0x00000001 - 0xFFFFFFFE: Time between the power source changes and the timer wakes up the
+ //system ( in units of seconds)
+ //0xFFFFFFFF - The timer will never wake up the system after the power source changes
+
+ Method (_TIP, 0x1, Serialized) {
+
+ if( LEqual(Arg0, 1)) {
+ return (0xFFFFFFFF)
+ }
+
+ return (0x0)
+ }
+
+
+ // Get the remaining timer value
+ Method (_TIV, 0x1, Serialized)
+ {
+ Name(TTIM, 0x00000000)
+
+ // If queried about the DC timer, return
+ if (LEqual(0x01, Arg0)) {
+ return (0xFFFFFFFF)
+ }
+
+ RTWT()
+
+ if( LGreaterEqual(HORA, HOR) ) {
+ FromBCD(Subtract(HORA, HOR), Local0)
+ } else {
+ Subtract(24, FromBCD(HOR), Local0)
+ Add(FromBCD(HORA), Local0, Local0)
+ }
+ Add(Multiply(Local0, 3600), TTIM, TTIM)
+
+ if( LGreaterEqual(MINA, MIN) ) {
+ FromBCD(Subtract(MINA, MIN), Local0)
+ } else {
+ Subtract(60, FromBCD(MIN), Local0)
+ Add(FromBCD(MINA), Local0, Local0)
+ }
+ Add(Multiply(Local0, 60), TTIM, TTIM)
+
+ if( LGreaterEqual(SECA, SEC) ) {
+ FromBCD(Subtract(SECA, SEC), Local0)
+ } else {
+ Subtract(60, FromBCD(SEC), Local0)
+ Add(FromBCD(SECA), Local0, Local0)
+ }
+ Add(Local0, TTIM, TTIM)
+
+ return (TTIM)
+ }
+ }
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/Uart1.asl b/Core/EM/ACPI/Uart1.asl
new file mode 100644
index 0000000..61344f7
--- /dev/null
+++ b/Core/EM/ACPI/Uart1.asl
@@ -0,0 +1,159 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart1.asl 7 10/01/10 3:43p Oleksiyy $
+//
+// $Revision: 7 $
+//
+// $Date: 10/01/10 3:43p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart1.asl $
+//
+// 7 10/01/10 3:43p Oleksiyy
+// Issue Number: 39752
+//
+// Category: Improvement
+//
+// Description: File modified to support Status Code in Runtime by hiding
+// COM0 from OS.
+//
+// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c,
+// CsmLib.c, AmiDxeLib.h and StatusCode eModule.
+//
+// 6 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 5 8/03/06 12:45p Stacyh
+// Updated to allow the use of SI1P for systems with 2 SIOs. Now contains
+// generic methods assuming SI1P to be 0 as well as methods which check
+// SI1P (these are commented out).
+//
+// 4 4/21/06 12:38p Felixp
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 7 03/04/07 5:41p Chung
+// Modify all I/O beta version
+//
+// 5 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// UART1 //
+// Category # :0x00
+Device(UAR1) {
+ Name(_UID, 1) //Generic ID for COMA
+
+// Use the following if not using SI1P or only have 1 SIO
+ Method(_HID, 0) {Return(^^SIO1.UHID(0))} //PnP Device ID
+ Method(_STA,0,Serialized)
+ {
+ If(And(\IOST,0x01)){
+ Return (0x0F) // UART1 device Present
+ } else {
+ Return(0x00) // Device not present
+ }
+ }
+
+ Method(_DIS, 0) {^^SIO1.DCNT(0, 0)} //Disable UART
+ Method(_CRS, 0) {Return(^^SIO1.DCRS(0, 0))} //Get UART current resources
+ Method(_SRS, 1) {^^SIO1.DSRS(Arg0, 0)} //Set UART recources
+
+// Use the following if using SI1P
+// Method(_HID, 0) { //PnP Device ID
+// if(SI1P){Return(^^SIO1.UHID(0))}
+// else{Return(^^SIO2.UHID(0))}
+// }
+// Method(_STA, 0) { //Get UART status
+// if(SI1P){Return(^^SIO1.DSTA(0))}
+// else{Return(^^SIO2.DSTA(0))}
+// }
+// Method(_DIS, 0) { //Disable UART
+// if(SI1P){^^SIO1.DCNT(0, 0)}
+// else{^^SIO2.DCNT(0, 0)}
+// }
+// Method(_CRS, 0) { //Get UART current resources
+// if(SI1P){Return(^^SIO1.DCRS(0, 0))}
+// else{Return(^^SIO2.DCRS(0, 0))}
+// }
+// Method(_SRS, 1) { //Set UART resources
+// if(SI1P){^^SIO1.DSRS(Arg0, 0)}
+// else{^^SIO2.DSRS(Arg0, 0)}
+// }
+
+//-----------------------------------------------------------------------
+// UART1 Possible Resources
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate() {
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IRQNoFlags() {4}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0x2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0x2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ EndDependentFn()
+ })
+
+
+/*
+//---------Power Resources for UART1 -------------------------
+ PowerResource(URP1, 0, 0) { //SystemLevel Parameter=0,
+ //which means UART can be turned off
+ //in any sleep state
+ Method(_STA, 0) {
+ Return(URAP) //Get Power Status
+ } //end of _STA
+ Method(_ON) {
+ Store(1, URAP) //Power on
+ } //end of _ON
+ Method(_OFF){
+ Store(0, URAP) //Power off
+ } //end of _OFF
+ }
+ Name(_PR0, Package(){URP1}) //Reference to PowerResources
+*/
+} // End Of UAR1
+//-----------------------------------------------------------------------
diff --git a/Core/EM/ACPI/Uart1ir.asl b/Core/EM/ACPI/Uart1ir.asl
new file mode 100644
index 0000000..de5e165
--- /dev/null
+++ b/Core/EM/ACPI/Uart1ir.asl
@@ -0,0 +1,143 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart1ir.asl 4 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 4 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart1ir.asl $
+//
+// 4 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 3 8/03/06 12:45p Stacyh
+// Updated to allow the use of SI1P for systems with 2 SIOs. Now contains
+// generic methods assuming SI1P to be 0 as well as methods which check
+// SI1P (these are commented out).
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 7 03/04/07 5:42p Chung
+// Modify all I/O beta version
+//
+// 6 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// UART + IrDa = COMA //
+// Category # :0x00
+// Cannot be included along with UART1.ASL. Only one UART1 can be present in ASL.
+Device(UAR1) {
+ Name(_UID, 1) //Generic ID for COMA
+
+// Use the following if not using SI1P or only have 1 SIO
+ Method(_HID, 0) {Return(^^SIO1.UHID(0))} //PnP Device ID
+ Method(_STA, 0) {Return(^^SIO1.DSTA(0))} //Get UART status
+ Method(_DIS, 0) {^^SIO1.DCNT(0, 0)} //Disable UART
+ Method(_CRS, 0) {Return(^^SIO1.DCRS(0, 1))} //Get UART current resources
+ Method(_SRS, 1) {^^SIO1.DSRS(Arg0, 0)} //Set UART resources
+
+// Use the following if using SI1P
+// Method(_HID, 0) { //PnP Device ID
+// if(SI1P){Return(^^SIO1.UHID(0))}
+// else{Return(^^SIO2.UHID(0))}
+// }
+// Method(_STA, 0) { //Get UART status
+// if(SI1P){Return(^^SIO1.DSTA(0))}
+// else{Return(^^SIO2.DSTA(0))}
+// }
+// Method(_DIS, 0) { //Disable UART
+// if(SI1P){^^SIO1.DCNT(0, 0)}
+// else{^^SIO2.DCNT(0, 0)}
+// }
+// Method(_CRS, 0) { //Get UART current resources
+// if(SI1P){Return(^^SIO1.DCRS(0, 1))}
+// else{Return(^^SIO2.DCRS(0, 1))}
+// }
+// Method(_SRS, 1) { //Set UART resources
+// if(SI1P){^^SIO1.DSRS(Arg0, 0)}
+// else{^^SIO2.DSRS(Arg0, 0)}
+// }
+
+//------------------------------------------------------------------------
+// UART1/2 , IrDa Possible Resources
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+// IRQ, No DMA
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {4}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0X3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+// DMA,IRQ
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ EndDependentFn()
+ })
+} // End Of UAR1
+//------------------------------------------------------------------------
diff --git a/Core/EM/ACPI/Uart2.asl b/Core/EM/ACPI/Uart2.asl
new file mode 100644
index 0000000..eda0bb6
--- /dev/null
+++ b/Core/EM/ACPI/Uart2.asl
@@ -0,0 +1,137 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart2.asl 4 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 4 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart2.asl $
+//
+// 4 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 3 8/03/06 12:45p Stacyh
+// Updated to allow the use of SI1P for systems with 2 SIOs. Now contains
+// generic methods assuming SI1P to be 0 as well as methods which check
+// SI1P (these are commented out).
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 7 03/04/07 5:42p Chung
+// Modify all I/O beta version
+//
+// 5 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// UART2 - COMB or Infrared //
+// Requires Uart1(ir).asl component present as well
+// Category # :0x01
+Device(UAR2) {
+ Name(_UID, 2) //Generic ID for COMB
+
+// Use the following if not using SI1P or only have 1 SIO
+ Method(_HID, 0) {Return(^^SIO1.UHID(1))} //PnP Device ID
+ Method(_STA, 0) {Return(^^SIO1.DSTA(1))} //Get UART status
+ Method(_DIS, 0) {^^SIO1.DCNT(1, 0)} //Disable UART
+ Method(_CRS, 0) {Return(^^SIO1.DCRS(1, 0))} //Get UART current resources
+ Method(_SRS, 1) {^^SIO1.DSRS(Arg0, 1)} //Set UART resources
+
+// Use the following if using SI1P
+// Method(_HID, 0) { //PnP Device ID
+// if(SI1P){Return(^^SIO1.UHID(1))}
+// else{Return(^^SIO2.UHID(1))}
+// }
+// Method(_STA, 0) { //Get UART status
+// if(SI1P){Return(^^SIO1.DSTA(1))}
+// else{Return(^^SIO2.DSTA(1))}
+// }
+// Method(_DIS, 0) { //Disable UART
+// if(SI1P){^^SIO1.DCNT(1, 0)}
+// else{^^SIO2.DCNT(1, 0)}
+// }
+// Method(_CRS, 0) { //Get UART current resources
+// if(SI1P){Return(^^SIO1.DCRS(1, 0))}
+// else{Return(^^SIO2.DCRS(1, 0))}
+// }
+// Method(_SRS, 1) { //Set UART resources
+// if(SI1P){^^SIO1.DSRS(Arg0, 1)}
+// else{^^SIO2.DSRS(Arg0, 1)}
+// }
+
+//------------------------------------------------------------------------
+// UART2 Possible Resources
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x2F8, 0x2F8, 1, 8)
+ IRQNoFlags() {3}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0x2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0x2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ EndDependentFn()
+ })
+
+
+/*
+//---------Power Resources for UART2 -------------------------
+ PowerResource(URP2, 0, 0) { //SystemLevel Parameter=0,
+ Method(_STA, 0) {
+ Return(URBP) //Get Power Status
+ } //end of _STA
+ Method(_ON) {
+ Store(1, URBP) //Power on
+ } //end of _ON
+ Method(_OFF){
+ Store(0, URBP) //Power off
+ } //end of _OFF
+ }
+ Name(_PR0, Package(){URP2}) //Reference to PowerResources
+*/
+} // End Of UAR2
diff --git a/Core/EM/ACPI/Uart2ir.asl b/Core/EM/ACPI/Uart2ir.asl
new file mode 100644
index 0000000..5aa5b86
--- /dev/null
+++ b/Core/EM/ACPI/Uart2ir.asl
@@ -0,0 +1,467 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart2ir.asl 7 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 7 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart2ir.asl $
+//
+// 7 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 6 4/09/08 5:05p Yakovlevs
+//
+// 5 9/18/07 10:13a Pats
+// Removed unnecessary decode range code.
+//
+// 4 3/30/07 12:00p Pats
+// Modified to support Fast IR.
+//
+// 3 8/03/06 12:45p Stacyh
+// Updated to allow the use of SI1P for systems with 2 SIOs. Now contains
+// generic methods assuming SI1P to be 0 as well as methods which check
+// SI1P (these are commented out).
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 6 03/04/07 5:42p Chung
+// Modify all I/O beta version
+//
+// 5 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// UART2 - COMB or Infrared //
+// Requires Uart1(ir).asl component present as well
+// Cannot be included along with UART2.ASL. Only one UART2 Device can be present in ASL.
+// Category # :0x01
+Device(UAR2) // SMSC N207 UART 2.
+{
+
+OperationRegion(IOID, // Name of Operation Region for SuperIO device
+ SystemIO, // Type of address space
+ SP1O, // Offset to start of region
+ 2) // Size of region in bytes
+ // End of Operation Region
+Field(IOID, ByteAcc, NoLock,Preserve){
+ INDX, 8, // Field named INDX is 8 bit wide
+ DATA, 8 // Field DATA is 8 bit wide
+}
+
+
+//----------------------------------------------------------------------
+// Set of Field names to be used to access SIO configuration space.
+//----------------------------------------------------------------------
+IndexField(INDX, DATA, ByteAcc, NoLock, Preserve){
+ Offset(0x02),
+ CR02, 8, // UART Power Management
+ Offset(0x0C),
+ CR0C, 8, // UARTMODE
+ Offset(0x24),
+ CR24, 8, // UART 1 Base Address
+ CR25, 8, // UART 2 Base Address
+ Offset(0x28),
+ CR28, 8, // UART IRQ Select
+ Offset(0x2B),
+ CR2B, 8, // FIR Base address
+ CR2C, 8, // FIR DMA
+ Offset(0x3A),
+ CR3A, 8, // LPC Docking Activate
+ CR3B, 8, // LPC Docking Base (High)
+ CR3C, 8, // LPC Docking Base (Low)
+// Offset(0x55),
+// CR55, 8, // Configuration Enable Key
+// Offset(0xAA),
+// CRAA, 8 // Configuration Disable Key
+} //End of indexed field
+
+
+//------------------------------------------------------------------------
+// Entry Config Mode
+//------------------------------------------------------------------------
+Method(ENFG) {
+ Store(0x55, INDX)
+}
+
+
+//------------------------------------------------------------------------
+// Exit Config Mode
+//------------------------------------------------------------------------
+Method(EXFG, 0) {
+ Store(0xAA, INDX)
+}
+
+ // Identify UART 2 as an IR Device.
+ Name(_UID, 2) //Generic ID for COMA
+// Name(_HID, EISAID("PNP0510"))
+
+ Method(_HID, 0){
+ ENFG()
+ And(CR0C, 0x18, Local0)
+ Store(CR2B, Local1)
+ EXFG()
+ If(Local0){
+ If(Local1)
+ {Return(EISAID("SMCF010"))} //PnP Device ID FIR Type
+ Else
+ {Return(EISAID("PNP0510"))} //PnP Device ID InfraRed Type
+ }Else
+ {Return(EISAID("PNP0501"))} //PnP Device ID 16550 Type
+ }
+
+
+ // Status Method for UART 2.
+ Method(_STA,0,Serialized)
+ {
+ //
+ //Check SIR Base Address, If ADR9 and ADR8 are 0, SIR disabled.
+ //
+
+ If(And(\IOST,0x02)){
+ Return (0x0F) // UART2 device Present
+ } else {
+ Return(0x00) // Device not present
+ }
+
+ }
+
+ // Disable Method for UART 2.
+ Method(_DIS,0,Serialized)
+ {
+ ENFG()
+ Store(And(CR02,0x0F),CR02)
+ EXFG()
+ }
+
+
+ //
+ // Current Resource Setting Method for UART 2.
+ //
+ Method(_CRS,0,Serialized)
+ {
+
+ ENFG()
+ Store(CR2B, Local0)
+ EXFG()
+ If(Local0)
+ {
+ // Create the FIR Buffer that stores the Resources to
+ // be returned.
+ Name(BUF0,ResourceTemplate()
+ {
+ IO(Decode16, 0x0000, 0x0000, 0x01, 0x08)
+ IO(Decode16, 0x0000, 0x0000, 0x01, 0x08)
+ IRQNoFlags() {7}
+ DMA(Compatibility, NotBusMaster, Transfer8, ) {2}
+ })
+
+ // Create pointers to the specific byte.
+ //
+ CreateByteField(BUF0,0x02,IO10)
+ CreateByteField(BUF0,0x03,IO11)
+ CreateByteField(BUF0,0x04,IO12)
+ CreateByteField(BUF0,0x05,IO13)
+ CreateByteField(BUF0,0x0a,IO20)
+ CreateByteField(BUF0,0x0b,IO21)
+ CreateByteField(BUF0,0x0c,IO22)
+ CreateByteField(BUF0,0x0d,IO23)
+ CreateWordField(BUF0,0x11,IRQW)
+ CreateByteField(BUF0,0x14,DMA0)
+
+ ENFG()
+
+ //
+ // Write the Base Address into the Buffer.
+ //
+ ShiftLeft(CR25,2,IO10) // Low Byte.
+ ShiftRight(And(CR25,0xC0), 6, IO11)
+ Store(IO10, IO12)
+ Store(IO11, IO13)
+
+ ShiftLeft(CR2B,3,IO20) // Low Byte.
+ ShiftRight(And(CR2B,0xE0), 5, IO21)
+ Store(IO20, IO22)
+ Store(IO21, IO23)
+
+ //
+ // Write the IRQ value into the Buffer.
+ //
+ Store(0x0,Local1)
+ And(CR28,0x0F,Local1)
+ ShiftLeft(1, Local1, IRQW)
+
+ // Write DMA value into buffer
+ Store(0x0,Local1)
+ And(CR2C,0x0F,Local1)
+ If(LEqual(Local1, 0x0F)){
+ Store(0, DMA0) //No DMA
+ }Else{
+ ShiftLeft(1, Local1, DMA0)
+ }
+
+ EXFG()
+
+ Return(BUF0)
+ }
+ Else
+ {
+ // Create the SIR Buffer that stores the Resources to
+ // be returned.
+ Name(BUF1,ResourceTemplate()
+ {
+ IO(Decode16,0x0000, 0x0000, 0x01, 0x08)
+ IRQNoFlags(){7}
+ })
+
+ // Create pointers to the specific byte.
+ //
+ CreateByteField(BUF1,0x02,IOL0)
+ CreateByteField(BUF1,0x03,IOL1)
+ CreateByteField(BUF1,0x04,IOL2)
+ CreateByteField(BUF1,0x05,IOL3)
+ CreateWordField(BUF1,0x09,IRQR)
+
+ ENFG()
+
+ //
+ // Write the Base Address into the Buffer.
+ //
+ ShiftLeft(CR25,2,IOL0) // Low Byte.
+ ShiftRight(And(CR25,0xC0), 6, IOL1)
+ Store(IOL0, IOL2)
+ Store(IOL0, IOL3)
+
+ //
+ // Write the IRQ value into the Buffer.
+ //
+ Store(0x0,Local1)
+ And(CR28,0x0F,Local1)
+ ShiftLeft(One,Local1,IRQR)
+
+ EXFG()
+
+ Return(BUF1)
+ }
+ }
+
+ //
+ // Possible Resource Setting Method for UART 2.
+ //
+ Name(_PRS, ResourceTemplate() {
+// IRQ, No DMA
+ StartDependentFn(0, 0)
+ {
+ IO(Decode16,0x3E8,0x3E8,0x01,0x08)
+ IRQNoFlags(){7}
+ }
+
+ StartDependentFnNoPri()
+ {
+ IO(Decode16,0x2F8,0x2F8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ }
+
+ StartDependentFnNoPri()
+ {
+ IO(Decode16,0x3F8,0x3F8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ }
+
+ StartDependentFnNoPri()
+ {
+ IO(Decode16,0x2E8,0x2E8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ }
+
+//IRA and DMA
+ StartDependentFn(0, 0) {
+ IO(Decode16,0x3E8,0x3E8,0x01,0x08)
+ IO(Decode16,0x7E8,0x7E8,0x01,0x08)
+ IRQNoFlags(){7}
+ DMA(Compatibility, NotBusMaster, Transfer8) {3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IO(Decode16,0x7E8,0x7E8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0x3F8, 1, 8)
+ IO(Decode16,0x7E8,0x7E8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IO(Decode16,0x7E8,0x7E8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0x3E8, 1, 8)
+ IO(Decode16,0x7E8,0x7E8,0x01,0x08)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {1,2,3}
+ }
+ EndDependentFn()
+ })
+
+
+ // Set Resource Setting Method for UART 2.
+ Method(_SRS,1,Serialized)
+ {
+ ENFG()
+ Store(CR2B, Local0)
+ EXFG()
+ If(Local0)
+ {
+ // Point to the specific information in the passed
+ // in Buffer.
+ CreateByteField(Arg0,0x02,IO10)
+ CreateByteField(Arg0,0x03,IO11)
+ CreateByteField(Arg0,0x0a,IO20)
+ CreateByteField(Arg0,0x0b,IO21)
+ CreateWordField(Arg0,0x11,IRQW)
+ CreateByteField(Arg0,0x14,DMA0)
+
+ ENFG()
+
+ //
+ // Disable the device.
+ //
+ And(CR02,0x0F,CR02)
+
+ //
+ // Set UART2 mode
+ //
+// Store(0x0B, CR0C)
+// Store(0x40, CR0A)
+// Store(0x0C, CR0C)
+
+ //
+ // Set the Base IO Address.
+ //
+ Store(ShiftRight(IO10,2),CR25)
+ Or(CR25,ShiftLeft(IO11,6),CR25)
+ If(IO20){
+ Store(ShiftRight(IO20,3),CR2B)
+ Or(CR2B,ShiftLeft(IO21,5),CR2B)
+ }
+
+
+ //
+ // Set the IRQ.
+ //
+ And(CR28,0xF0,CR28)
+ Or(CR28,Subtract(FindSetRightBit(IRQW),1),CR28)
+
+ // Set DMA
+ And(CR2C,0xF0,CR2C)
+ If(DMA0)
+ {
+ Or(CR2C,Subtract(FindSetRightBit(DMA0),1),CR2C)
+ }
+ Else
+ {
+ Or(CR2C,0x0F,CR2C) // No DMA
+ }
+
+ //
+ // Enable the device.
+ //
+ Or(CR02,0x80,CR02)
+
+ EXFG()
+
+ }
+ Else
+ {
+ // Point to the specific information in the passed
+ // in Buffer.
+ CreateByteField(Arg0,0x02,IOLO)
+ CreateByteField(Arg0,0x03,IOHI)
+ CreateWordField(Arg0,0x09,IRQR)
+
+ ENFG()
+
+ //
+ // Disable the device.
+ //
+ And(CR02,0x0F,CR02)
+
+ //
+ // Set UART2 mode
+ //
+// Store(0x0B, CR0C)
+// Store(0x40, CR0A)
+// Store(0x0C, CR0C)
+
+ //
+ // Set the Base IO Address.
+ //
+ Store(ShiftRight(IOLO,2),CR25)
+ Or(CR25,ShiftLeft(IOHI,6),CR25)
+
+ //
+ // Set the IRQ.
+ //
+ And(CR28,0xF0,CR28)
+ Or(CR28,Subtract(FindSetRightBit(IRQR),1),CR28)
+
+ //
+ // Enable the device.
+ //
+ Or(CR02,0x80,CR02)
+
+ EXFG()
+ }
+ }
+
+ //
+ // D0 Method for UART 2.
+ //
+ Method(_PS0,0,Serialized)
+ {
+ ENFG()
+ Store(Or(CR02,0x80),CR02)
+ EXFG()
+ }
+
+
+
+ //
+ // D3 Method for UART 2.
+ //
+ Method(_PS3,0,Serialized)
+ {
+ ENFG()
+ Store(And(CR02,0x0F),CR02)
+ EXFG()
+ }
+
+} \ No newline at end of file
diff --git a/Core/EM/ACPI/Uart3.asl b/Core/EM/ACPI/Uart3.asl
new file mode 100644
index 0000000..4163521
--- /dev/null
+++ b/Core/EM/ACPI/Uart3.asl
@@ -0,0 +1,103 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart3.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart3.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:41p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 1 03/04/07 5:54p Chung
+// Add ASL core for new all I/O beta version
+//
+//**********************************************************************;
+// UART3 //
+// Category # :0x00
+Device(UAR3) {
+ Name(_UID, 3) //Generic ID for COMC
+ Method(_HID, 0) { //PnP Device ID
+ if(SI1P){Return(^^SIO2.UHID(0))}
+ else{Return(^^SIO1.UHID(0))}
+ }
+ Method(_STA, 0) { //Get UART status
+ if(SI1P){Return(^^SIO2.DSTA(0))}
+ else{Return(^^SIO1.DSTA(0))}
+ }
+ Method(_DIS, 0) { //Disable UART
+ if(SI1P){^^SIO2.DCNT(0, 0)}
+ else{^^SIO1.DCNT(0, 0)}
+ }
+ Method(_CRS, 0) { //Get UART current resources
+ if(SI1P){Return(^^SIO2.DCRS(0, 0))}
+ else{Return(^^SIO1.DCRS(0, 0))}
+ }
+ Method(_SRS, 1) { //Set UART resources
+ if(SI1P){^^SIO2.DSRS(Arg0, 0)}
+ else{^^SIO1.DSRS(Arg0, 0)}
+ }
+
+
+//-----------------------------------------------------------------------
+// UART3 Possible Resources
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IRQNoFlags() {7}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0x2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0x2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ EndDependentFn()
+ })
+} // End Of UAR3 //------------------------------------------------------
diff --git a/Core/EM/ACPI/Uart3ir.asl b/Core/EM/ACPI/Uart3ir.asl
new file mode 100644
index 0000000..11f2c4e
--- /dev/null
+++ b/Core/EM/ACPI/Uart3ir.asl
@@ -0,0 +1,127 @@
+//**********************************************************************;
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************;
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart3ir.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart3ir.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:41p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 1 03/04/07 5:55p Chung
+// Add ASL core for new all I/O beta version
+//
+//**********************************************************************;
+// UART3 //
+// Category # :0x00
+Device(UAR3) {
+ Name(_UID, 3) //Generic ID for COMC
+ Method(_HID, 0) { //PnP Device ID
+ if(SI1P){Return(^^SIO2.UHID(0))}
+ else{Return(^^SIO1.UHID(0))}
+ }
+ Method(_STA, 0) { //Get UART status
+ if(SI1P){Return(^^SIO2.DSTA(0))}
+ else{Return(^^SIO1.DSTA(0))}
+ }
+ Method(_DIS, 0) { //Disable UART
+ if(SI1P){^^SIO2.DCNT(0, 0)}
+ else{^^SIO1.DCNT(0, 0)}
+ }
+ Method(_CRS, 0) { //Get UART current resources
+ if(SI1P){Return(^^SIO2.DCRS(0, 1))}
+ else{Return(^^SIO1.DCRS(0, 1))}
+ }
+ Method(_SRS, 1) { //Set UART resources
+ if(SI1P){^^SIO2.DSRS(Arg0, 0)}
+ else{^^SIO1.DSRS(Arg0, 0)}
+ }
+
+
+//-----------------------------------------------------------------------
+// UART3 IrDa Possible Resources
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+// IRQ, No DMA
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {11}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+// IRQ, DMA
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ EndDependentFn()
+ })
+} // End Of UAR3 //------------------------------------------------------
diff --git a/Core/EM/ACPI/Uart4.asl b/Core/EM/ACPI/Uart4.asl
new file mode 100644
index 0000000..ee2ce3a
--- /dev/null
+++ b/Core/EM/ACPI/Uart4.asl
@@ -0,0 +1,109 @@
+//**********************************************************************;
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************;
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart4.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart4.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:41p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 1 03/04/07 5:56p Chung
+// Add ASL core for new all I/O beta version
+//
+// 5 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+// UART4 - COMD or Infrared //
+// Requires Uart4(ir).asl component present as well
+// Category # :0x01
+Device(UAR4) {
+ Name(_UID, 4) //Generic ID for COMD
+ Method(_HID, 0) { //PnP Device ID
+ if(SI1P){Return(^^SIO2.UHID(1))}
+ else{Return(^^SIO1.UHID(1))}
+ }
+ Method(_STA, 0) { //Get UART status
+ if(SI1P){Return(^^SIO2.DSTA(1))}
+ else{Return(^^SIO1.DSTA(1))}
+ }
+ Method(_DIS, 0) { //Disable UART
+ if(SI1P){^^SIO2.DCNT(1, 0)}
+ else{^^SIO1.DCNT(1, 0)}
+ }
+ Method(_CRS, 0) { //Get UART current resources
+ if(SI1P){Return(^^SIO2.DCRS(1, 0))}
+ else{Return(^^SIO1.DCRS(1, 0))}
+ }
+ Method(_SRS, 1) { //Set UART resources
+ if(SI1P){^^SIO2.DSRS(Arg0, 1)}
+ else{^^SIO1.DSRS(Arg0, 1)}
+ }
+
+//------------------------------------------------------------------------
+// UART4 Possible Resources
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+// IRQ, No DMA
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {10}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ EndDependentFn()
+ })
+} // End Of UAR4
diff --git a/Core/EM/ACPI/Uart4ir.asl b/Core/EM/ACPI/Uart4ir.asl
new file mode 100644
index 0000000..eba59b0
--- /dev/null
+++ b/Core/EM/ACPI/Uart4ir.asl
@@ -0,0 +1,128 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************;
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/Uart4ir.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/Uart4ir.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:41p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 1 03/04/07 5:57p Chung
+// Add ASL core for new all I/O beta version
+//
+//**********************************************************************;
+// UART4 - COMD or Infrared //
+// Requires Uart4(ir).asl component present as well
+// Cannot be included along with UART4IR.ASL. Only one UART4 Device can be present in ASL.
+// Category # :0x01
+Device(UAR4) {
+ Name(_UID, 4) //Generic ID for COMD
+ Method(_HID, 0) { //PnP Device ID
+ if(SI1P){Return(^^SIO2.UHID(1))}
+ else{Return(^^SIO1.UHID(1))}
+ }
+ Method(_STA, 0) { //Get UART status
+ if(SI1P){Return(^^SIO2.DSTA(1))}
+ else{Return(^^SIO1.DSTA(1))}
+ }
+ Method(_DIS, 0) { //Disable UART
+ if(SI1P){^^SIO2.DCNT(1, 0)}
+ else{^^SIO1.DCNT(1, 0)}
+ }
+ Method(_CRS, 0) { //Get UART current resources
+ if(SI1P){Return(^^SIO2.DCRS(1, 1))}
+ else{Return(^^SIO1.DCRS(1, 1))}
+ }
+ Method(_SRS, 1) { //Set UART resources
+ if(SI1P){^^SIO2.DSRS(Arg0, 1)}
+ else{^^SIO1.DSRS(Arg0, 1)}
+ }
+
+
+//-----------------------------------------------------------------------
+// UART4 IrDa Possible Resources
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+// IRQ, No DMA
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x2E8, 0x2E8, 1, 8)
+ IRQNoFlags() {10}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0x2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0x2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+// IRQ, DMA
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0x3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0x2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0x3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0x2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,9,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ EndDependentFn()
+ })
+} // End Of UAR4 //------------------------------------------------------
diff --git a/Core/EM/ACPI/asllib.asl b/Core/EM/ACPI/asllib.asl
new file mode 100644
index 0000000..a90c541
--- /dev/null
+++ b/Core/EM/ACPI/asllib.asl
@@ -0,0 +1,325 @@
+// ASL generic library objects
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/asllib.asl 10 6/04/13 4:39p Oleksiyy $
+//
+// $Revision: 10 $
+//
+// $Date: 6/04/13 4:39p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/asllib.asl $
+//
+// 10 6/04/13 4:39p Oleksiyy
+// [TAG] EIP125640
+// [Category] Improvement
+// [Description] Adding Win 8.1 to the OS list in OSFL method.
+// [Files] asllib.asl
+//
+// 9 7/20/12 5:00p Oleksiyy
+// [TAG] EIP92404
+// [Category] Improvement
+// [Description] ACPI method _OSI("Linux") should no longer be used
+// [Files] asllib.asl
+//
+// 8 4/10/12 6:23p Oleksiyy
+// [TAG] EIP87370
+// [Category] Improvement
+// [Description] Operation System Vendor String for Win8
+// [Files] asllib.asl
+//
+// 7 9/29/09 5:06p Oleksiyy
+// EIP 20586: RRIO and rDMA methods removed. They are implemented in
+// SB.asl file.
+//
+// 6 9/08/09 11:16a Yakovlevs
+// Fixed issue in OSVR detection. Because of "ElseIf" statement it use to
+// return wrong (Lovest) value.
+//
+// 4 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 3 5/24/06 3:50p Ambikas
+//
+// 2 5/05/05 7:10p Yakovlevs
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 18 1/22/03 3:38p Alexp
+// Modify GPRW() method
+//
+// 17 1/15/03 6:09p Alexp
+// GPRW-> modify code to make use of Sleep State Bit mask field inside
+// BIOS OpRegion.
+//
+// 16 10/08/02 10:44a Mirk
+// missing bracket in OSFL method
+//
+// 15 10/08/02 10:38a Mirk
+// Display proper cp ACPI in PIC mode : AC and for APIC mode : AA
+//
+// 14 9/20/02 10:04a Alexp
+// Uncomment code to store detected WinME to OSFL OS flag.
+//
+// 13 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//;**********************************************************************;
+// File to be included to root ASL scope of DSDT.ASL
+//**********************************************************************;
+// 1. RRIO(4) & rDMA(3) Dummy control methods. Required when I/O Positive decoding's disabled
+// 2. Name PICM - Global Name returns current Interrupt controller mode; updated from _PIC control method
+// 3. Method _PIC(1) - Updates PICM with current Interrupt controller mode
+// 4. Method MCTH(Str1, Str2) - Compare Str1 and Str2.
+// 5. Method GPRW(Package(x,y)) Generic Wake up Control Method to detect the Max Sleep State available in ASL Name scope
+// and Return the Package compatible with _PRW format
+// 6. Method WAKP(Package) - Return package for _WAK method
+// 7. Debug OperationRegions used to display ASL checkpoints int LED CheckPoint Card
+//----------------------------------------------------------------------
+
+/*
+;<AMI_PHDR_START>
+;------------------------------------------------------------------------
+;
+; Procedure: _PIC
+;
+; Description: Interrupt mode Control method, returns current Interrupt controller mode; updated from _PIC control method
+; OS invokes _PIC to notify ASL of current Interrupt controller mode
+; _PIC Input arguments : 0-PIC mode (Default), 1-APIC mode
+; Input: Arg0 - Interrupt mode
+; Output: Nothing
+;
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+ Name(PICM, 0) // Global Name, returns current Interrupt controller mode; updated from _PIC control method
+// OS invokes _PIC to notify ASL of current Interrupt controller mode
+// _PIC Input arguments : 0-PIC mode (Default), 1-APIC mode
+ Method(_PIC, 1) {
+ if(Arg0) {
+ Store(0xAA, DBG8) // APIC
+ } else {
+ Store(0xAC, DBG8) // PIC
+ }
+ Store(Arg0, PICM)
+ }
+
+/*
+;<AMI_PHDR_START>
+;------------------------------------------------------------------------
+;
+; Procedure: OSFL
+;
+; Description: OSFL object is used to detect the currently running OS
+; Input: Nothing
+; Output: OS type
+; running under 0 - Win 2000
+; 1 - Win 98/Se
+; 2 - Win Me
+; 3 - Linux
+; 4 - WinXP
+; 5 - Windows Server 2003
+; 6 - FreeBSD
+; 7 - HP-UX
+; 8 - OpenVMS
+;-------------------New Values Added -----------------------------
+; 9 - WinXP SP1
+; 10 - WinXP SP2
+; 11 - WinXP SP3
+; 12 - Vista
+; 13 - Vista SP1
+; 14 - Win7
+; 15 - Win8
+; 16 - Win8.1
+; 17..n - reserved
+;
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+ Name(OSVR, Ones) // Global Name, returns current OS version ID
+ Method(OSFL, 0){
+ if(LNotEqual(OSVR, Ones)) {Return(OSVR)} // OS version was already detected
+ if(LEqual(PICM,0)) {Store(0xAC, DBG8)} // to indicate OS is running in ACPI PIC mode
+ Store(3, OSVR) // default - Linux
+//// Detect currently running OS
+ if(CondRefOf(\_OSI,Local0))
+ {
+ //If(\_OSI("Linux")){Store(3, OSVR)} // Tested on the Redhat Linux
+ If(\_OSI("Windows 2001")){Store(4, OSVR)}
+ If(\_OSI("Windows 2001.1")){Store(5, OSVR)}
+ If(\_OSI("FreeBSD")){Store(6, OSVR)}
+ If(\_OSI("HP-UX")){Store(7, OSVR)}
+ If(\_OSI("OpenVMS")){Store(8, OSVR)}
+ If(\_OSI("Windows 2001 SP1")){Store(9,OSVR)}
+ If(\_OSI("Windows 2001 SP2")){Store(10,OSVR)}
+ If(\_OSI("Windows 2001 SP3")){Store(11,OSVR)}
+ If(\_OSI("Windows 2006")){Store(12,OSVR)}
+ If(\_OSI("Windows 2006 SP1")){Store(13,OSVR)}
+ If(\_OSI("Windows 2009")){Store(14,OSVR)}
+ If(\_OSI("Windows 2012")){Store(15,OSVR)}
+ If(\_OSI("Windows 2013")){Store(16,OSVR)}
+ } else {
+ If(MCTH(\_OS,"Microsoft Windows NT")){Store(0, OSVR)}
+ If(MCTH(\_OS,"Microsoft Windows")){Store(1, OSVR)}
+ If(MCTH(\_OS,"Microsoft WindowsME: Millennium Edition")){Store(2, OSVR)}
+ If(MCTH(\_OS,"Linux")){Store(3, OSVR)} // Tested on the Redhat Linux
+ If(MCTH(\_OS,"FreeBSD")){Store(6, OSVR)}
+ If(MCTH(\_OS,"HP-UX")){Store(7, OSVR)}
+ If(MCTH(\_OS,"OpenVMS")){Store(8, OSVR)}
+ }
+ Return(OSVR)
+ }
+
+/*
+;<AMI_PHDR_START>
+;-------------------------------------------------------------------------
+;
+; Procedure: MCTH
+;
+; Description: Generic control Method. Used to compare two strings and return TRUE/FALSE result
+; MCTH(Str1, Str2) - Compare Str1 and Str2.
+; Input: Arg0 - str1, Arg1 - str2
+; Output: string comparison result
+; One if Str1 == Str2
+; Zero if Str1 != Str2
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+ Method(MCTH, 2) {
+//1. If Length str1 < Str2 - Return (Zero)
+ If(LLess(Sizeof(Arg0), Sizeof(Arg1)))
+ {
+ Return(Zero)
+ }
+//2. Convert str1 & str2 into buffer with length of str2
+ Add(Sizeof(Arg0), 1, Local0)
+// Local0 contains length of string + NULL character.
+ Name(BUF0, Buffer(Local0) {})
+ Name(BUF1, Buffer(Local0) {})
+ Store(Arg0, BUF0)
+ Store(Arg1, BUF1)
+ While(Local0)
+ {
+ Decrement(Local0)
+ If(LNotEqual(Derefof(Index(BUF0, Local0)), Derefof(Index(BUF1, Local0))))
+ { Return(Zero) }
+ }
+ Return(One) // Str1 & Str2 are match
+ }
+
+/*
+;<AMI_PHDR_START>
+;------------------------------------------------------------------------
+;
+; Procedure: GPRW
+;
+; Description: Generic Wake up Control Method ("Big brother") to detect the Max Sleep State available in ASL Name scope
+; and Return the Package compatible with _PRW format.
+; Input: Arg0 = bit offset within GPE register space device event will be triggered to
+; Arg1 = Max Sleep state, device can resume the System from
+; If Arg1 = 0 , Update Arg1 with Max _Sx state enabled in the System
+; Output: _PRW package
+;
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+ Name(PRWP, Package(){Zero, Zero}) // _PRW Package
+ Method(GPRW, 2)
+ {
+ Store(Arg0, Index(PRWP, 0)) // copy GPE#
+// SS1-SS4 - enabled in BIOS Setup Sleep states
+ Store(ShiftLeft(SS1,1),Local0) // S1 ?
+ Or(Local0,ShiftLeft(SS2,2),Local0) // S2 ?
+ Or(Local0,ShiftLeft(SS3,3),Local0) // S3 ?
+ Or(Local0,ShiftLeft(SS4,4),Local0) // S4 ?
+// Local0 has a bit mask of enabled Sx(1 based)
+ // bit mask of enabled in BIOS Setup Sleep states(1 based)
+ If(And(ShiftLeft(1, Arg1), Local0)){ // Requested wake up value (Arg1) is present in Sx list of available Sleep states
+ Store(Arg1, Index(PRWP, 1)) // copy Sx#
+ } Else { // Not available -> match Wake up value to the higher Sx state
+ ShiftRight(Local0, 1, Local0)
+ If(LOr(LEqual(OSFL, 1), LEqual(OSFL, 2))) { // ??? Win9x
+ FindSetLeftBit(Local0, Index(PRWP,1)) // Arg1 == Max Sx
+ } Else { // ??? Win2k / XP
+ FindSetRightBit(Local0, Index(PRWP,1)) // Arg1 == Min Sx
+ }
+ }
+ Return(PRWP)
+ }
+
+/*
+;<AMI_PHDR_START>
+;------------------------------------------------------------------------
+;
+; Procedure: WAKP
+;
+; Description: Return package for _WAK method. Contains 2 DWORDS
+; 0 - Status
+; 0x00000001 - wake was signaled but failed due to lack of power
+; 0x00000002 - wake was signaled but failed due to thermal condition
+; other bits are reserved
+; 1 - PSS if non-zero, the effective S-state the Power Supply realy entered
+; Output: _WAK return package
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+// Return package for _WAK method 2 DWORDS
+ Name(WAKP, Package(){Zero, Zero})
+
+//--------------------------//
+// Debug output registers //
+//--------------------------//
+
+/*
+;<AMI_PHDR_START>
+;------------------------------------------------------------------------
+; Procedure: DBG8
+; Procedure: DBG9
+; Description: Logical names for Debug ports 0x80 (byte) and 0x90(word).
+; If such debug ports exist in the System, the value, stored into the Port will be displayed to LED
+; Input: Nothing
+; Output: Nothing
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+
+ OperationRegion (DEB0, SystemIO, 0x80, 1)
+ Field (DEB0, ByteAcc,NoLock,Preserve)
+ { DBG8,8,}
+
+ OperationRegion (DEB1, SystemIO, 0x90, 2)
+ Field (DEB1, WordAcc,NoLock,Preserve)
+ { DBG9,16,}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/ACPI/game.asl b/Core/EM/ACPI/game.asl
new file mode 100644
index 0000000..3e7a2e2
--- /dev/null
+++ b/Core/EM/ACPI/game.asl
@@ -0,0 +1,101 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/game.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/game.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 5 03/04/07 5:39p Chung
+// Modify all I/O beta version
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+//**********************************************************************;
+// Generic Game Port
+//------------------------------------------------------------------------
+// Category # :0x08
+Device(GAME) {
+ Name(_HID, EISAID("PNPB02F")) // PnP ID for GamePort
+ Method(_STA, 0) { Return(DSTA(8))} // Get status
+ Method(_DIS, 0) { DCNT(8,0) } // Disable
+// GamePort Current Resource template (to be returned by _CRS)
+ Name(GMCR, ResourceTemplate() {
+ IO(Decode16, 0, 0, 8, 8, GIO1)
+ })
+
+ Method(_CRS, 0) {
+ CreateWordField(GMCR, ^GIO1._MIN, IOGL) // Min Base Word
+ CreateWordField(GMCR, ^GIO1._MAX, IOGH) // Max Base Word
+
+ ENFG(CGLD(8)) // Enter Config Mode, Select LDN
+
+// Write Current Settings into Buffer for IO Descriptor
+// IO ports for Game
+ ShiftLeft(IOAH, 8, IOGL) // Get IO Base MSB
+ Or(IOAL, IOGL, IOGL) // Get IO Base LSB
+ Store(IOGL, IOGH) // Set Max Base Word
+
+ EXFG() // Exit Config Mode
+ Return(GMCR) // Return Byte Stream
+ }
+
+ Method(_SRS, 1) {
+ CreateWordField(Arg0, ^GIO1._MIN, IO11) // Range 1 Min Base Word
+ ENFG(CGLD(8)) // Enter Config Mode, Select LDN
+// Set Game Base IO Address
+ And(IO11, 0xff, IOAL) // Set IO Base LSB
+ ShiftRight(IO11, 0x8, IOAH) // Set IO Base MSB
+ DCNT(8, 1) // Enable Device (Routing)
+ EXFG() // Exit Config Mode
+ }
+//------------------------------------------------------------------------
+// GamePort Possible Resources
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+
+ Name(_PRS, ResourceTemplate() {
+ StartDependentFn(0,0) {
+ IO(Decode16, 0x201, 0x201, 1, 8)
+ }
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x209, 0x209, 1, 8)
+ }
+ EndDependentFn()
+ })
+
+} // End Of GamePort ////////////////////////////////////////////////////
diff --git a/Core/EM/ACPI/irda.asl b/Core/EM/ACPI/irda.asl
new file mode 100644
index 0000000..ba91163
--- /dev/null
+++ b/Core/EM/ACPI/irda.asl
@@ -0,0 +1,115 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/irda.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/irda.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 5 03/04/07 5:40p Chung
+// Modify all I/O beta version
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//
+//**********************************************************************;
+// Standalone InfraRed device //
+//**********************************************************************;
+// Category # :0x10 (Generic IO range 1)
+Device(IRDA) {
+ Name(_HID, EISAID("PNP0510")) //PnP Device ID IrDa
+ Name(_UID, 3) //Unique ID for IrDa 3
+ Method(_STA, 0) {Return(DSTA(0x10))} //Get status
+ Method(_DIS, 0) {DCNT(0x10, 0)} //Disable
+ Method(_CRS, 0) {Return(DCRS(0x10, 0))} //Get current resources
+ Method(_SRS, 1) {DSRS(Arg0, 0x10) } //Set recources
+// Method(_PRS, 0) {Return(CMPR)} //Return possible resources
+
+
+//------------------------------------------------------------------------
+// UART1/2 , IrDa Possible Resources
+//------------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate() {
+// IRQ, No DMA
+ StartDependentFn(0, 0) {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {4}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {}
+ }
+// DMA, IRQ
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3F8, 0X3F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2F8, 0X2F8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x3E8, 0X3E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ StartDependentFnNoPri() {
+ IO(Decode16, 0x2E8, 0X2E8, 1, 8)
+ IRQNoFlags() {3,4,5,6,7,10,11,12}
+ DMA(Compatibility, NotBusMaster, Transfer8) {0,1,2,3}
+ }
+ EndDependentFn()
+})
+} // End Of IRDA //
diff --git a/Core/EM/ACPI/midi.asl b/Core/EM/ACPI/midi.asl
new file mode 100644
index 0000000..12473e2
--- /dev/null
+++ b/Core/EM/ACPI/midi.asl
@@ -0,0 +1,124 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/midi.asl 3 3/26/09 4:53p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 3/26/09 4:53p $
+//**********************************************************************;
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/midi.asl $
+//
+// 3 3/26/09 4:53p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/03/06 4:05p Felixp
+// New Super I/O infrastructure Support
+//
+// 1 3/24/05 5:01p Sivagarn
+//
+// 1 2/03/05 6:42p Sivagarn
+// 0ABHI001 Check in
+//
+// 1 7/27/04 2:48p Yakovlevs
+//
+// 5 03/04/07 5:41p Chung
+// Modify all I/O beta version
+//
+// 4 9/06/02 10:53a Alexp
+// Add SourceSafe headers to all core asl files
+//
+//**********************************************************************;
+//**********************************************************************;
+// Generic MPU 401 Device
+//**********************************************************************;
+// Category # :0x05
+Device(MIDI){
+ Name(_HID, EISAID("PNPB006")) //PnP ID for GamePort
+ Method(_STA, 0) {Return(DSTA(5))} //Get status
+ Method(_DIS, 0) {DCNT(5,0)} //Disable
+
+//-----------------------------------------------------------------------
+// MIDIPort Current Resources template (returned by _CRS)
+//-----------------------------------------------------------------------
+ Name(MDCR, ResourceTemplate(){
+// IO(Decode16, 0, 0, 0x30, 2, GIO1)
+// IRQNoFlags(GIRQ) {10}
+ IO(Decode16, 0, 0, 1, 2, GIO1)
+ IRQNoFlags(GIRQ) {5}
+ })
+
+ Method(_CRS, 0){
+ CreateWordField(MDCR, ^GIO1._MIN, IOML) //Range 2 Min Base Word
+ CreateWordField(MDCR, ^GIO1._MAX, IOMH) //Range 2 Max Base Word
+ CreateWordField(MDCR, ^GIRQ._INT, IRQM) //IRQ mask 0x1
+
+ ENFG(CGLD(5)) //Enter Config Mode, Select LDN
+
+// Write Current Settings into Buffer for IO Descriptor
+// IO ports for MPU 401
+ ShiftLeft(IOAH, 8, IOML) //Get IO Base MSB
+ Or(IOAL, IOML, IOML) //Get IO Base LSB
+ Store(IOML, IOMH) //Set Max Base Word
+// Write Current Settings into IRQ descriptor
+ If(INTR)
+ {ShiftLeft(1, INTR, IRQM)}
+ Else
+ {Store(0, IRQM)} //No IRQ used
+ EXFG() //Exit Config Mode
+ Return(MDCR) //Return Byte Stream
+ }
+
+ Method(_SRS, 1){
+// Arg0 - PnP Resource String to set
+ CreateWordField(Arg0, ^GIO1._MIN, IO11) //Range 1 Min Base Word
+ CreateWordField(Arg0, ^GIRQ._INT, IRQM) //IRQ mask 0x1
+
+ ENFG(CGLD(5)) //Enter Config Mode, Select LDN
+
+ // Set Midi Base IO Address
+ And(IO11, 0xFF, IOAL) //Set IO Base LSB
+ ShiftRight(IO11, 0x08, IOAH) //Set IO Base MSB
+ // Set IRQ
+ If(IRQM){
+ FindSetRightBit(IRQM, Local0)
+ Subtract(Local0, 1, INTR)
+ }
+ Else
+ {Store(0, INTR)} //No IRQ used
+ DCNT(5, 1) //Enable Device (Routing)
+ EXFG() //Exit Config Mode
+ }
+
+//-----------------------------------------------------------------------
+// MIDIPort Possible Resources
+//-----------------------------------------------------------------------
+//-----------------------------------------------------------------------
+//NOTE: _PRS MUST be the NAME not a METHOD object
+//to have GENERICSIO.C working right!
+//-----------------------------------------------------------------------
+ Name(_PRS, ResourceTemplate(){
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x300, 0x300, 1, 2)
+ IRQNoFlags() {5,7,9,10,11}
+ }
+ StartDependentFnNoPri(){
+ IO(Decode16, 0x330, 0x330, 1, 2)
+ IRQNoFlags() {5,7,9,10,11}
+ }
+ EndDependentFn()
+ })
+} // End Of Midi ////////////////////////////////////////////////////////
diff --git a/Core/EM/ACPI/mptable.c b/Core/EM/ACPI/mptable.c
new file mode 100644
index 0000000..66fe0d4
--- /dev/null
+++ b/Core/EM/ACPI/mptable.c
@@ -0,0 +1,1553 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/mptable.c 31 12/13/12 12:01p Oleksiyy $
+//
+// $Revision: 31 $
+//
+// $Date: 12/13/12 12:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/mptable.c $
+//
+// 31 12/13/12 12:01p Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 30 1/12/12 4:51p Oleksiyy
+// [TAG] EIP80870
+// [Category] Improvement
+// [Description] MP table entry has a zero sized Address Length.
+// [Files] mptable.c
+//
+// 29 1/12/12 4:15p Oleksiyy
+// [TAG] EIP79240
+// [Category] Improvement
+// [Description] Added Variable to handle the situation when MP table
+// created multiple times.
+// [Files] mptable.c
+//
+// 28 11/29/11 12:20p Oleksiyy
+// [TAG] EIP76814
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MP_TABLE_LEGACY_REGION_LOCATION = 0 causes build error
+// [RootCause] Unreferenced variable: LegacyBiosProtocol
+// [Solution] Variable declared only if MP_TABLE_LEGACY_REGION_LOCATION
+// != 0
+// [Files] mptable.c
+//
+// 27 7/19/11 11:31a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 26 5/25/10 5:07p Yakovlevs
+// Fixed Issue when with Multiple IO APICs, upper IOAPIC's INT_IN 0 was
+// excluded from the table.
+//
+// 25 9/28/09 3:59p Yakovlevs
+//
+// 24 5/27/09 5:41p Yakovlevs
+// CSM Protocol definition moved in #if scope
+//
+// 23 5/18/09 10:11a Yakovlevs
+// Added support of IOAPIC discovery tokens. Some project don't want
+// certain algorithms to be used.
+//
+// 22 5/15/09 12:49p Yakovlevs
+// Fixed logic in IOAPIC discovery ordering.
+//
+// 21 5/14/09 5:39p Yakovlevs
+// Added code to use "USE_BOARD_INFO_APIC_DATA" token
+//
+// 20 5/08/09 1:16p Yakovlevs
+// Made ACPI Driver use AMI Board Info Protocol if available without
+// breaking compatibility.
+//
+// 19 5/07/09 5:46p Markw
+// Use #ifdef ACPI_INFO2_PROTOCOL_PUBLISHED to exclude code that uses ACPI
+// INFO 2 for CPUs that provide the header files.
+//
+// 18 5/04/09 5:49p Markw
+// EIP #17903 If AmiCpuInfo2 Protocol available, MP tables will use this
+// instead of hobs.
+//
+// 17 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 16 2/06/09 4:52p Yakovlevs
+// Added Creating EFI Config Table Entry for MPS 14.
+//
+// 15 10/06/08 3:07p Yakovlevs
+// Restored accidentally removed fixes.
+//
+// 14 9/25/08 4:14p Artems
+// Solve problem with non-consecutive IO APIC IDs
+//
+// 13 7/14/08 3:26p Markw
+// In for loop count total number of local apics (hyper-threading) not
+// just number of cores. Code already correctly skips hyper-treading in
+// for loop.
+//
+// 12 7/07/08 5:06p Artems
+// Fixed bug in PCI IOAPIC detection
+//
+// 11 6/11/08 5:58p Markw
+// Update MpsTableAddCpuEntry function to multiple cores and threads to
+// get total CPUs instead just cores.
+//
+// 10 4/15/08 9:16p Yakovlevs
+// Functions Headers added
+//
+// 9 4/11/07 5:44p Artems
+// Multi processor detection added
+//
+// 8 3/28/07 10:42a Artems
+// Fixed bug - added System memory map entry for legacy video
+//
+// 7 3/19/07 12:19p Felixp
+// Clean up
+//
+// 6 3/13/07 6:40p Yakovlevs
+//
+// 5 3/13/07 5:41p Artems
+// MPS 1.4 TABLE SUPPORT added
+//
+// 3 2/06/07 5:38p Artems
+//
+// 2 2/06/07 5:25p Artems
+//
+// 1 2/06/07 4:54p Artems
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: mptable.c
+//
+// Description: MPS table builder functions implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Token.h>
+
+//------------------------ Include files ------------------------------
+
+#include <AmiDxeLib.h>
+#include <AmiHobs.h>
+
+#include <Protocol/LegacyBios.h>
+#include <Protocol/AmiCpuInfo.h>
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+#include <Protocol\AmiCpuInfo2.h>
+#endif
+
+
+#include "acpicore.h"
+#include "mptable.h"
+
+
+#include <Protocol\AmiBoardInfo.h>
+extern AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfoProtocol;
+
+//------------------------ Global variables ---------------------------
+
+static EFI_GUID gMpsTableGuid = MPS_TABLE_GUID;
+static EFI_GUID EfiLegacyBiosProtocolGuid = EFI_LEGACY_BIOS_PROTOCOL_GUID;
+AMI_CPU_INFO_PROTOCOL *AmiCpuInfoProtocol = NULL;
+static EFI_GUID AmiCpuInfoProtocolGuid = AMI_CPU_INFO_PROTOCOL_GUID;
+static EFI_EVENT MpsTableReadyToBootEvent = 0;
+static MP_FLOATING_POINTER MpsTableFloatingPointer;
+static VOID *MpsTablePointer = NULL;
+static VOID *MpsTableCurrentPointer = NULL;
+static VOID *MpsExTablePointer = NULL;
+static VOID *MpsExTableCurrentPointer = NULL;
+static UINT16 BaseTableLength = 0;
+static UINT16 BaseTableEntryCount = 0;
+static UINT16 ExtendedTableLength = 0;
+static UINT8 OemId[8] = CONVERT_TO_STRING(T_ACPI_OEM_TBL_ID); //{ 0,1,2,3,4,5,6,7 };
+static UINT8 ProductId[12] = CONVERT_TO_STRING(T_ACPI_OEM_ID); //{ 0,1,2,3,4,5,6,7,8,9,0xA, 0xB };
+
+static BUS_INFO BusEntry[MP_TABLE_MAX_BUS_ENTRIES];
+static UINT8 MaxBusId = 0;
+static UINT8 CurrentBusEntry = 0;
+static UINT8 IsaBusId = 0;
+static UINT8 *BusTypeString[] = {"CBUS ", "CBUSII", "EISA ", "FUTURE", "INTERN", "ISA ",
+ "MBI ", "MBII ", "MCA ", "MPI ", "MPSA ", "NUBUS ",
+ "PCI ", "PCMCIA", "TC ", "VL ", "VME ", "XPRESS" };
+static UINT8 BridgeBusTypes[] = { 12, 5, 2, 8, 12, 13, 11 }; //each number represents corresponding
+ //number in BusTypeString array, i.e.
+ //bridge subclass 0 - PCI host has number
+ //12 in array, subclass 1 - ISA bridge -
+ //number 5 etc.
+static IO_APIC_INFO IoApicEntry[MP_TABLE_MAX_IO_APIC_ENTRIES];
+static UINT8 CurrentIoApicEntry = 0;
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+extern AMI_CPU_INFO_2_PROTOCOL* gAmiCpu2Info;
+#endif
+
+
+extern ISO_PARAMETER_TABLE IsoTbl[];
+EFI_STATUS MpsTableCreateStatus = EFI_NO_RESPONSE;
+EFI_STATUS MpsTableFloatPointerModifyStatus = EFI_NO_RESPONSE;
+BOOLEAN MpsTableWasCreated = FALSE;
+//------------------------ Functions ----------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableBuilderInit
+//
+// Description: MPS table builder entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - MPS table builder image handle
+// IN EFI_SYSTEM_TABLE *SystemTaple - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Initialization completed successfully
+// EFI_ERROR - Initialization failed
+//
+// Modified: MpsTableReadyToBootEvent
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS MpsTableBuilderInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK,
+ MpsTableReadyToBootNotify,
+ NULL,
+ &MpsTableReadyToBootEvent);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableReadyToBootNotify
+//
+// Description: MPS table builder ReadyToBoot notification function
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to calling context
+//
+// Output:
+// VOID
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID MpsTableReadyToBootNotify(
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ EFI_STATUS Status;
+
+ if(EFI_ERROR(MpsTableCreateStatus))
+ {
+ MpsTableCreateStatus = MpsTableCreate();
+ if(EFI_ERROR(MpsTableCreateStatus))
+ return;
+ }
+ if(EFI_ERROR(MpsTableFloatPointerModifyStatus))
+ MpsTableFloatPointerModifyStatus = MpsTableFloatPointerModify();
+
+ //Install a Configuration table Entry
+ Status=pBS->InstallConfigurationTable(&gMpsTableGuid,MpsTablePointer);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return;
+ //After we did everything needed
+ pBS->CloseEvent(Event);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableFloatPointerModify
+//
+// Description: Fills MP_FLOATING_POINTER structure with actual data
+// and places it into F000 segment
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_SUCCESS - Pointer created and placed successfully
+// EFI_ERROR - Some error occurs
+//
+// Modified: MpsTableFloatingPointer
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS MpsTableFloatPointerModify(VOID)
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBiosProtocol;
+ VOID *LegacyRegionAddress;
+
+ MpsTableFloatingPointer.Signature = MP_FLOATING_POINTER_SIGNATURE;
+
+//at this point we have address of MPS table
+ MpsTableFloatingPointer.PhysicalAddresPointer = (UINT32) MpsTablePointer;
+
+//length in 16-byte paragraphs
+ MpsTableFloatingPointer.Length = sizeof(MP_FLOATING_POINTER)/16;
+
+//here must be token
+ MpsTableFloatingPointer.VersionNumber = MP_TABLE_VERSION_1_4;
+
+//force checksum to zero before calculate actual checksum
+ MpsTableFloatingPointer.CheckSum = 0;
+
+//here must be token
+ MpsTableFloatingPointer.DefaultConfiguration = 0;
+
+//here must be token
+ MpsTableFloatingPointer.IMCRflag = 0;
+
+ MpsTableFloatingPointer.Reserved[0] = 0;
+ MpsTableFloatingPointer.Reserved[1] = 0;
+ MpsTableFloatingPointer.Reserved[2] = 0;
+
+//now we are ready to calculate checksum
+ MpsTableFloatingPointer.CheckSum = ChsumTbl((UINT8 *)&MpsTableFloatingPointer,
+ sizeof(MP_FLOATING_POINTER));
+
+ Status = pBS->LocateProtocol(&EfiLegacyBiosProtocolGuid,
+ NULL,
+ &LegacyBiosProtocol);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = LegacyBiosProtocol->GetLegacyRegion(LegacyBiosProtocol,
+ (UINTN)sizeof(MP_FLOATING_POINTER),
+ F0000_BIT,
+ 0x10,
+ &LegacyRegionAddress);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = LegacyBiosProtocol->CopyLegacyRegion(LegacyBiosProtocol,
+ (UINTN) sizeof(MP_FLOATING_POINTER),
+ LegacyRegionAddress,
+ (VOID *) &MpsTableFloatingPointer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableCreate
+//
+// Description: Allocates space and creates MPS table
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_SUCCESS - function executed successfully
+// EFI_ERROR - some error occured
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MpsTableCreate(VOID)
+{
+ EFI_STATUS Status;
+ UINT16 EntryCount;
+
+ if (MpsTableWasCreated)
+ return MpsTableAddHeader();
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ MP_TBL_TMP_BUFFER_SIZE,
+ &MpsTablePointer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ MpsTableCurrentPointer = MpsTablePointer;
+
+//split buffer onto two parts for base and extended tables
+ MpsExTablePointer = MpsTablePointer;
+ (UINT8 *)MpsExTablePointer += ((MP_TBL_TMP_BUFFER_SIZE)/2);
+ MpsExTableCurrentPointer = MpsExTablePointer;
+
+//Leave placeholder for header
+ (UINT8 *)MpsTableCurrentPointer += sizeof(MP_CONFIGURATION_TABLE_HEADER);
+ BaseTableLength += sizeof(MP_CONFIGURATION_TABLE_HEADER);
+
+//add CPU Entry
+ EntryCount = MpsTableAddCpuEntry();
+ (UINT8 *)MpsTableCurrentPointer += sizeof(MP_TABLE_CPU_ENTRY) * EntryCount;
+ BaseTableLength += sizeof(MP_TABLE_CPU_ENTRY) * EntryCount;
+ BaseTableEntryCount += EntryCount;
+
+//add Bus Entry
+ EntryCount = MpsTableAddBusEntry();
+ (UINT8 *)MpsTableCurrentPointer += sizeof(MP_TABLE_BUS_ENTRY) * EntryCount;
+ BaseTableLength += sizeof(MP_TABLE_BUS_ENTRY) * EntryCount;
+ BaseTableEntryCount += EntryCount;
+
+//add IO Apic Entry
+ EntryCount = MpsTableAddIoApicEntry();
+ (UINT8 *)MpsTableCurrentPointer += sizeof(MP_TABLE_IO_APIC_ENTRY) * EntryCount;
+ BaseTableLength += sizeof(MP_TABLE_IO_APIC_ENTRY) * EntryCount;
+ BaseTableEntryCount += EntryCount;
+
+//add Interrupt assignment Entry
+ EntryCount = MpsTableAddIntAssignEntry();
+ (UINT8 *)MpsTableCurrentPointer += sizeof(MP_TABLE_INT_ASSIGN_ENTRY) * EntryCount;
+ BaseTableLength += sizeof(MP_TABLE_INT_ASSIGN_ENTRY) * EntryCount;
+ BaseTableEntryCount += EntryCount;
+
+//add Local interrupt assignment Entry
+ EntryCount = MpsTableAddLocalIntAssignEntry();
+ (UINT8 *)MpsTableCurrentPointer += sizeof(MP_TABLE_LOCAL_INT_ASSIGN_ENTRY) * EntryCount;
+ BaseTableLength += sizeof(MP_TABLE_LOCAL_INT_ASSIGN_ENTRY) * EntryCount;
+ BaseTableEntryCount += EntryCount;
+
+ MpsTableAddExtendedTable();
+
+ MpsTableWasCreated = TRUE;
+
+ return MpsTableAddHeader();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddHeader
+//
+// Description: Creates MPS table header, allocates space and copies entire
+// table into RuntimeServicesData memory
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_SUCCESS - function executed successfully
+//
+// Modified: MpsTablePointer
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MpsTableAddHeader(VOID)
+{
+ EFI_STATUS Status;
+ MP_CONFIGURATION_TABLE_HEADER *HeaderPointer;
+ VOID *AllocationPointer;
+#if MP_TABLE_LEGACY_REGION_LOCATION != 0
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBiosProtocol;
+#endif
+ HeaderPointer = (MP_CONFIGURATION_TABLE_HEADER *) MpsTablePointer;
+
+ HeaderPointer->Signature = MP_CONFIGURATION_TABLE_SIGNATURE;
+ HeaderPointer->BaseTableLength = BaseTableLength;
+ HeaderPointer->VersionNumber = MP_TABLE_VERSION_1_4;
+ HeaderPointer->CheckSum = 0; //force checksum to zero before calculating
+
+ MemCpy((VOID *)HeaderPointer->OemId, (VOID *)OemId, 8);
+ MemCpy((VOID *)HeaderPointer->ProductId, (VOID *)ProductId, 12);
+
+ HeaderPointer->OemTablePointer = 0;
+ HeaderPointer->OemTableSize = 0;
+ HeaderPointer->BaseTableEntryCount = BaseTableEntryCount;
+ HeaderPointer->LocalApicAddress = LOCAL_APIC_BASE; //sdl token
+ HeaderPointer->ExtendedTableLength = ExtendedTableLength;
+ HeaderPointer->ExtendedCheckSum = 0;
+ HeaderPointer->Reserved = 0;
+
+ HeaderPointer->ExtendedCheckSum = ChsumTbl(MpsExTablePointer, ExtendedTableLength);
+ HeaderPointer->CheckSum = ChsumTbl(MpsTablePointer, BaseTableLength);
+
+#if MP_TABLE_LEGACY_REGION_LOCATION == 0
+
+//publish table in high memory
+ Status = pBS->AllocatePool(EfiRuntimeServicesData,
+ BaseTableLength + ExtendedTableLength,
+ &AllocationPointer);
+
+ if(EFI_ERROR(Status))
+ return Status;
+ MemCpy(AllocationPointer, //memory allocated - copy MPS table to new location
+ MpsTablePointer,
+ (UINTN) (BaseTableLength + ExtendedTableLength));
+
+#else
+
+//publish table in F0000 segment
+ Status = pBS->LocateProtocol(&EfiLegacyBiosProtocolGuid,
+ NULL,
+ &LegacyBiosProtocol);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = LegacyBiosProtocol->GetLegacyRegion(LegacyBiosProtocol,
+ (UINTN)(BaseTableLength + ExtendedTableLength),
+ F0000_BIT,
+ 0x10,
+ &AllocationPointer);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = LegacyBiosProtocol->CopyLegacyRegion(LegacyBiosProtocol,
+ (UINTN) (BaseTableLength + ExtendedTableLength),
+ AllocationPointer,
+ MpsTablePointer);
+#endif
+
+ pBS->FreePool(MpsTablePointer);
+ MpsTablePointer = AllocationPointer;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddCpuEntryByHob
+//
+// Description: Adds CPU entries to MPS table from HOB.
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 MpsTableAddCpuEntryByHob(VOID)
+{
+ MP_TABLE_CPU_ENTRY *EntryPointer;
+ UINT16 EntryCount = 0;
+ static EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ CPUINFO_HOB *pCpuInfoHob;
+ CPUINFO CpuInfo;
+ VOID *pHobList;
+ EFI_STATUS Status;
+ INTN i;
+ UINTN CpuIndex = 0;
+ UINT8 NumberOfCores;
+ UINT8 NumberOfThreads;
+
+
+ EntryPointer = (MP_TABLE_CPU_ENTRY *)MpsTableCurrentPointer;
+
+ pHobList = GetEfiConfigurationTable(pST, &HobListGuid);
+ if(pHobList == NULL)
+ Status = EFI_NOT_FOUND;
+ else
+ Status = FindNextHobByGuid(&CpuInfoHobGuid, &pHobList);
+
+ //If no CPU info available, we've got a UniProccessor System
+ if (EFI_ERROR(Status))
+ {
+ EntryPointer->EntryType = MP_TABLE_CPU_ENTRY_TYPE;
+ EntryPointer->LocalApicId = 0;
+ EntryPointer->LocalApicVersion = 0;
+ EntryPointer->CpuFlags.CpuEnable = 1;
+ EntryPointer->CpuFlags.CpuBootStrap = 1;
+ EntryPointer->CpuFlags.Reserved = 0;
+ EntryPointer->CpuSignature = 0;
+ EntryPointer->FeatureFlags = 0;
+ EntryPointer->Reserved[0] = 0;
+ EntryPointer->Reserved[1] = 0;
+
+ return 1; //just one CPU entry
+ }
+
+ pCpuInfoHob = (CPUINFO_HOB *)pHobList;
+
+ while(!EFI_ERROR(GetCpuInfo(CpuIndex, &NumberOfCores, &NumberOfThreads)))
+ {
+ for(i = 0; i < NumberOfCores * NumberOfThreads; i += NumberOfThreads)
+ {
+ CpuInfo = pCpuInfoHob->Cpuinfo[i + CpuIndex];
+
+ EntryPointer->EntryType = MP_TABLE_CPU_ENTRY_TYPE;
+ EntryPointer->LocalApicId = CpuInfo.ApicId;
+ EntryPointer->LocalApicVersion = CpuInfo.ApicVer;
+ EntryPointer->CpuFlags.CpuEnable = (CpuInfo.Disabled) ? 0 : 1;
+ EntryPointer->CpuFlags.CpuBootStrap = ((i + CpuIndex) == pCpuInfoHob->BspNo) ? 1 : 0;
+ EntryPointer->CpuFlags.Reserved = 0;
+ EntryPointer->CpuSignature = CpuInfo.CpuSignature;
+ EntryPointer->FeatureFlags = (UINT32) CpuInfo.CpuFeatureInfo;
+ EntryPointer->Reserved[0] = 0;
+ EntryPointer->Reserved[1] = 0;
+
+ EntryPointer++;
+ EntryCount++;
+ }
+ CpuIndex += NumberOfCores * NumberOfThreads;
+ }
+ return EntryCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddCpuEntryByProtocol.
+//
+// Description: Adds CPU entries to MPS table from protocol.
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+UINT16 MpsTableAddCpuEntryByProtocol(VOID)
+{
+ MP_TABLE_CPU_ENTRY *EntryPointer;
+ EFI_STATUS Status;
+ ACPI_PROCESSOR_INFO *AcpiProcInfo;
+ UINT32 NumEntries;
+ UINT32 EntryCount = 0;
+ UINT32 Index;
+
+ if (gAmiCpu2Info->ProtocolVer < 1) return 0;
+
+ Status = gAmiCpu2Info->GetAcpiInfo(
+ gAmiCpu2Info, (VOID**) &AcpiProcInfo, &NumEntries
+ );
+ if (EFI_ERROR(Status)) return 0;
+
+ EntryPointer = (MP_TABLE_CPU_ENTRY *)MpsTableCurrentPointer;
+
+ for (Index = 0; Index < NumEntries; ++Index) {
+ //Note: Only some ACPI_PROCESSOR_INFO fields may only valid for some minimum ACPI_PROCESSOR_INFO.Length.
+ //The ACPI_PROCESSOR_INFO may have additional fields added in later version. Please see comments in
+ //AmiCpuInfo2.h file.
+ if (AcpiProcInfo->Type == ACPI_PROCESSOR_INFO_TYPE
+ && AcpiProcInfo->Thread == 0
+ ) {
+ EntryPointer->EntryType = MP_TABLE_CPU_ENTRY_TYPE;
+ EntryPointer->LocalApicId = AcpiProcInfo->ApicId;
+ EntryPointer->LocalApicVersion = AcpiProcInfo->ApicVer;
+ EntryPointer->CpuFlags.CpuEnable = AcpiProcInfo->Enable;
+ EntryPointer->CpuFlags.CpuBootStrap = AcpiProcInfo->Bsp;
+ EntryPointer->CpuFlags.Reserved = 0;
+ EntryPointer->CpuSignature = AcpiProcInfo->CpuSignature;
+ EntryPointer->FeatureFlags = AcpiProcInfo->FeatureFlags;
+ EntryPointer->Reserved[0] = 0;
+ EntryPointer->Reserved[1] = 0;
+ EntryPointer++;
+ EntryCount++;
+ }
+
+ AcpiProcInfo = (ACPI_PROCESSOR_INFO*)((UINT8*)AcpiProcInfo + AcpiProcInfo->Length);
+ }
+
+ return (UINT16)EntryCount;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddCpuEntry.
+//
+// Description: Adds CPU entries to MPS table.
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 MpsTableAddCpuEntry(VOID)
+{
+ UINT16 EntryCount = 0;
+ //First try to build Local APIC information from the protocol.
+#ifdef ACPI_INFO2_PROTOCOL_PUBLISHED
+ if (gAmiCpu2Info != NULL) EntryCount = MpsTableAddCpuEntryByProtocol();
+ //If protocol fails, try CPU INFO HOB.
+#endif
+ if (!EntryCount) EntryCount = MpsTableAddCpuEntryByHob();
+ return EntryCount;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddBusEntry
+//
+// Description: Adds Bus entries to MPS table
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 MpsTableAddBusEntry(VOID)
+{
+ MP_TABLE_BUS_ENTRY *EntryPointer;
+ UINT16 EntryCount = 0;
+ UINT16 i;
+
+ EntryPointer = (MP_TABLE_BUS_ENTRY *)MpsTableCurrentPointer;
+
+ QueryBusInfo();
+
+ for(i = 0; i < CurrentBusEntry; i++)
+ {
+ EntryPointer->EntryType = MP_TABLE_BUS_ENTRY_TYPE;
+ EntryPointer->BusId = BusEntry[i].BusId;
+
+ MemCpy((VOID *)EntryPointer->BusTypeString, (VOID *)BusTypeString[(BusEntry[i].BusType)], 6);
+
+ EntryPointer++;
+ EntryCount++;
+ }
+ return EntryCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddIoApicEntry
+//
+// Description: Adds IO Apic entries to MPS table
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 MpsTableAddIoApicEntry(VOID)
+{
+ MP_TABLE_IO_APIC_ENTRY *EntryPointer;
+ UINT16 EntryCount = 0;
+ UINT8 i=0;
+#if FEC00000_APIC_AUTODETECT == 1
+ UINT64 SearchAddress=0;
+#endif
+ EntryPointer = (MP_TABLE_IO_APIC_ENTRY *)MpsTableCurrentPointer;
+
+#if FEC00000_APIC_AUTODETECT == 1
+//first we detect IO APICS mapped into default address range
+ for(SearchAddress = IO_APIC_BASE_ADDRESS_BOTTOM;
+ SearchAddress < IO_APIC_BASE_ADDRESS_TOP;
+ SearchAddress += IO_APIC_SEARCH_STEP)
+
+ if(*((UINT8 *)SearchAddress) != 0xFF) //we have something
+ CollectIoApicInfo(NULL, (UINT32)SearchAddress);
+
+//second we arrange IO APIC in their ID ascending order (if there more than one)
+#endif
+
+
+//Check also SDL ceated Structures they might address very none standard IOAPICS.
+//-------------------------------------------------------------------------------------------
+
+#if USE_BOARD_INFO_APIC_DATA == 1
+{
+ AMI_APIC_INFO *BrdApicInfo;
+ BOOLEAN Present;
+ UINTN j;
+ //-----------------
+ for(i=0; i<(gAmiBoardInfoProtocol->ApicInfoLength/sizeof(AMI_APIC_INFO)); i++){
+ BrdApicInfo=&gAmiBoardInfoProtocol->ApicInfoTable[i];
+ //This is a special case it could be a duplicate entries in MadtTblEntries[]
+ //if other options of IOAPIC/IOsAPIC detection was on.
+ //So check if IOAPIC/IOsAPIC entries with the same properties already present in DB.
+ for(j=0,Present=FALSE; j < CurrentIoApicEntry; j++){
+ if(BrdApicInfo->ApicAddress.ADDRESS == IoApicEntry[j].IoApicAddress){
+ Present = TRUE;
+ break;
+ }
+ }
+ //Entry with this address already present in IoApicEntry[] array
+ if(Present) continue;
+
+ //Looks like it is a new IOAPIC/IOSAPIC entry!
+ //Check if something alive at this address
+ CollectIoApicInfo(NULL, BrdApicInfo->ApicAddress.ADDRESS);
+ } // for(...i<(gAmiBoardInfoProtocol->ApicInfoLength/sizeof(AMI_APIC_INFO))
+}
+#endif //USE_BOARD_INFO_APIC_DATA ==1
+
+//-------------------------------------------------------------------------------------------
+
+ if(CurrentIoApicEntry > 1)
+ ArrangeIoApicEntries();
+
+
+//now we are ready to create MPS table IO APIC entries
+ for(i = 0; i < CurrentIoApicEntry; i++)
+ {
+ EntryPointer->EntryType = MP_TABLE_IO_APIC_ENTRY_TYPE;
+ EntryPointer->IoApicId = IoApicEntry[i].IoApicId;
+ EntryPointer->IoApicVersion = IoApicEntry[i].IoApicVersion;
+ EntryPointer->Flags = IoApicEntry[i].IoApicFlags;
+ EntryPointer->IoApicAddress = IoApicEntry[i].IoApicAddress;
+
+ EntryPointer++;
+ EntryCount++;
+ }
+ return EntryCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddIntAssignEntry
+//
+// Description: Adds Interrupt assignment entries to MPS table
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 MpsTableAddIntAssignEntry(VOID)
+{
+
+ MP_TABLE_INT_ASSIGN_ENTRY *EntryPointer;
+ UINT16 EntryCount = 0;
+ UINT16 Dummy;
+ PCI_IRQ_APIC_ROUTE *RouteTable;
+ UINT8 i, j;
+
+ EntryPointer = (MP_TABLE_INT_ASSIGN_ENTRY *)MpsTableCurrentPointer;
+
+//First assign ISA IRQ interrupts
+ AmiIsaIrqMask(&Dummy, TRUE);
+
+ for(i = 0; i < 16; i++)
+ {
+ if((Dummy & 1) && (i != 2)) //create entry only if IRQ is used
+ { //and it isn't IRQ2
+ EntryPointer->EntryType = MP_TABLE_INT_ASSIGN_ENTRY_TYPE;
+ EntryPointer->InterruptType = INT_TYPE_INT;
+ EntryPointer->Flags = (UINT16)IsoTbl[i].Flags;
+ EntryPointer->SourceBusId = IsaBusId;
+ EntryPointer->SourceBusIrq.IsaBusIrq = i;
+//define Apic ID and Itin depends of GLobal sys vector
+ GetIoApicId(IsoTbl[i].ApicInt,
+ &EntryPointer->DestIoApicId,
+ &EntryPointer->DestIoApicItin);
+
+ EntryPointer++;
+ EntryCount++;
+ }
+ Dummy >>= 1;
+ }
+
+//Second assign PCI IRQ Entries
+
+ Dummy = (UINT16)gAmiBoardInfoProtocol->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE);
+ RouteTable = gAmiBoardInfoProtocol->ApicRoutTable;
+
+ for(i = 0; i < Dummy; i++)
+ {
+//define runtime bus number from build bus number
+
+ for(j = 0; j < 4; j++)
+ {
+ if((RouteTable[i].Intn[j].IoApicItin != 0) || (RouteTable[i].Intn[j].IoApicId != 0))
+ {
+ EntryPointer->EntryType = MP_TABLE_INT_ASSIGN_ENTRY_TYPE;
+ EntryPointer->InterruptType = INT_TYPE_INT;
+ EntryPointer->Flags = 0; //always conforms PCI bus specs
+ EntryPointer->SourceBusId = RouteTable[i].PciBusNumber;
+ EntryPointer->SourceBusIrq.PciBusIrq.PciIntSignal = j;
+ EntryPointer->SourceBusIrq.PciBusIrq.PciDeviceNumber = RouteTable[i].DeviceNumber;
+ EntryPointer->SourceBusIrq.PciBusIrq.Reserved = 0;
+ EntryPointer->DestIoApicId = RouteTable[i].Intn[j].IoApicId;
+ EntryPointer->DestIoApicItin = RouteTable[i].Intn[j].IoApicItin;
+
+ EntryPointer++;
+ EntryCount++;
+ }
+ }
+ }
+
+ return EntryCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddLocalIntAssignEntry
+//
+// Description: Adds Local interrupt assignment entries to MPS table
+//
+// Input:
+// VOID
+//
+// Output:
+// UINT16 - Number of entries added
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 MpsTableAddLocalIntAssignEntry(VOID)
+{
+ MP_TABLE_LOCAL_INT_ASSIGN_ENTRY *EntryPointer;
+ UINT16 EntryCount = 0;
+
+ EntryPointer = (MP_TABLE_LOCAL_INT_ASSIGN_ENTRY *)MpsTableCurrentPointer;
+
+ EntryPointer->EntryType = MP_TABLE_LOCAL_INT_ASSIGN_ENTRY_TYPE;
+ EntryPointer->InterruptType = INT_TYPE_EXT_INT;
+ EntryPointer->InterruptSignal.Polarity = POLARITY_CONFORM_SPEC;
+ EntryPointer->InterruptSignal.TriggerMode = TRIGGER_MODE_CONFORM_SPEC;
+ EntryPointer->InterruptSignal.Reserved = 0;
+ EntryPointer->SourceBusId = 0;
+ EntryPointer->SourceBusIrq = 0;
+ EntryPointer->DestLocalApicId = 0xFF;
+ EntryPointer->DestLocalApicItin = 0;
+
+ EntryPointer++;
+ EntryCount++;
+
+ EntryPointer->EntryType = MP_TABLE_LOCAL_INT_ASSIGN_ENTRY_TYPE;
+ EntryPointer->InterruptType = INT_TYPE_NMI;
+ EntryPointer->InterruptSignal.Polarity = POLARITY_CONFORM_SPEC;
+ EntryPointer->InterruptSignal.TriggerMode = TRIGGER_MODE_CONFORM_SPEC;
+ EntryPointer->InterruptSignal.Reserved = 0;
+ EntryPointer->SourceBusId = 0;
+ EntryPointer->SourceBusIrq = 0;
+ EntryPointer->DestLocalApicId = 0xFF;
+ EntryPointer->DestLocalApicItin = 1;
+
+ EntryPointer++;
+ EntryCount++;
+
+ return EntryCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsTableAddExtendedTable
+//
+// Description: Adds Extended table entries to base table
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MpsTableAddExtendedTable(VOID)
+{
+ MemCpy(MpsTableCurrentPointer, MpsExTablePointer, ExtendedTableLength);
+ MpsExTablePointer = MpsTableCurrentPointer;
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsExTableAddSysAddressMapEntry
+//
+// Description: Creates Extended MPS table system address space map entryies
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *pPciRootBridgeIoProtocol
+// IN UINT8 BusId - PCI bus number
+// IN UINT8 BusAttributes - PCI bus attributes
+//
+// Output:
+// VOID
+//
+// Modified: MpsExTableCurrentPointer
+// ExtendedTableLength
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MpsExTableAddSysAddressMapEntry(
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *pPciRootBridgeIoProtocol,
+ IN UINT8 BusId,
+ IN UINT8 BusAttributes)
+{
+ MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY *EntryPointer;
+ ACPI_ADDRESS_SPACE_DESC *Resources;
+ BOOLEAN VgaMemoryAdded = FALSE;
+
+ EntryPointer = (MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY *)MpsExTableCurrentPointer;
+
+ pPciRootBridgeIoProtocol->Configuration(pPciRootBridgeIoProtocol, &Resources);
+
+//add entries to ISA decode
+ if(BusAttributes & 0x3) //support ISA I/O space
+ {
+ EntryPointer->EntryType = MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY_TYPE;
+ EntryPointer->EntryLength = sizeof(MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY);
+ EntryPointer->BusId = BusId;
+ EntryPointer->AddressType = 0; //IO descriptor
+ EntryPointer->AddressBase = 0;
+ EntryPointer->AddressLength = 0x1000;
+ EntryPointer++;
+ ExtendedTableLength += sizeof(MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY);
+ }
+
+ while(Resources->Signature == 0x8A)
+ {
+ if(Resources->ResourceType != 2 && Resources->AddressLength)
+ {
+ if(Resources->ResourceType == 1) //IO descriptor
+ EntryPointer->AddressType = 0;
+ else if(Resources->TypeSpecificFlags & 6) //bits 1 and 2 set
+ EntryPointer->AddressType = 2; //memory prefetch address
+ else
+ EntryPointer->AddressType = 1; //memory descriptor
+
+// VGA region should be at the beginning of Memory range
+ if ((EntryPointer->AddressType == 1) && (BusAttributes & 0x1C) && (!(VgaMemoryAdded))) {
+ EntryPointer->EntryType = MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY_TYPE;
+ EntryPointer->EntryLength = sizeof(MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY);
+ EntryPointer->BusId = BusId;
+ EntryPointer->AddressType = 1; //memory descriptor
+ EntryPointer->AddressBase = 0xA0000;
+ EntryPointer->AddressLength = 0x20000;
+ EntryPointer++;
+ ExtendedTableLength += sizeof(MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY);
+ VgaMemoryAdded = TRUE;
+ EntryPointer->AddressType = 1; //memory descriptor
+ }
+
+ EntryPointer->EntryType = MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY_TYPE;
+ EntryPointer->EntryLength = sizeof(MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY);
+ EntryPointer->BusId = BusId;
+ EntryPointer->AddressBase = Resources->AddressRangeMin;
+ EntryPointer->AddressLength = Resources->AddressLength;
+
+ EntryPointer++;
+ ExtendedTableLength += sizeof(MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY);
+ }
+ Resources++;
+ }
+
+ MpsExTableCurrentPointer = (VOID *)EntryPointer;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsExTableAddBusHierarchyEntry
+//
+// Description: Creates Extended MPS table bus hierarchy entryies
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified: MpsExTableCurrentPointer
+// ExtendedTableLength
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MpsExTableAddBusHierarchyEntry(VOID)
+{
+ MP_EX_TABLE_BUS_HIERARCHY_ENTRY *EntryPointer;
+ UINT8 i;
+
+ EntryPointer = (MP_EX_TABLE_BUS_HIERARCHY_ENTRY *)MpsExTableCurrentPointer;
+
+ for(i = 0; i < CurrentBusEntry; i++)
+ {
+ if(BusEntry[i].ParentBusId != 0xFF && BusEntry[i].BusType != 12) //skip root bridge and P2P bridge
+ {
+ EntryPointer->EntryType = MP_EX_TABLE_BUS_HIERARCHY_ENTRY_TYPE;
+ EntryPointer->EntryLength = sizeof(MP_EX_TABLE_BUS_HIERARCHY_ENTRY);
+ EntryPointer->BusId = BusEntry[i].BusId;
+ EntryPointer->BusInfo = BusEntry[i].Flags;
+ EntryPointer->ParentBusId = BusEntry[i].ParentBusId;
+ EntryPointer->Reserved[0] = 0;
+ EntryPointer->Reserved[1] = 0;
+ EntryPointer->Reserved[2] = 0;
+
+ EntryPointer++;
+ ExtendedTableLength += sizeof(MP_EX_TABLE_BUS_HIERARCHY_ENTRY);
+ }
+ }
+ MpsExTableCurrentPointer = (VOID *)EntryPointer;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MpsExTableAddCompatBusAddressModifierEntry
+//
+// Description: Creates Extended MPS table compatibility bus address space
+// modifier entryies
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified: MpsExTableCurrentPointer
+// ExtendedTableLength
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MpsExTableAddCompatBusAddressModifierEntry(VOID)
+{
+ MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY *EntryPointer;
+ UINT8 i;
+
+ EntryPointer = (MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY *)MpsExTableCurrentPointer;
+
+ for(i = 0; i < CurrentBusEntry; i++)
+ {
+ if(BusEntry[i].ParentBusId == 0xFF)
+ {
+ //add/subtract ISA predefined range
+ EntryPointer->EntryType = MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY_TYPE;
+ EntryPointer->EntryLength = sizeof(MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY);
+ EntryPointer->BusId = BusEntry[i].BusId;
+ EntryPointer->RangeList = 0; //isa range list
+ EntryPointer->AddressModifier = (BusEntry[i].Flags & 0x3) ? 0 : 1;
+
+ EntryPointer++;
+ ExtendedTableLength += sizeof(MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY);
+
+ //add/subtract VGA predefined range
+ EntryPointer->EntryType = MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY_TYPE;
+ EntryPointer->EntryLength = sizeof(MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY);
+ EntryPointer->BusId = BusEntry[i].BusId;
+ EntryPointer->RangeList = 1; //vga range list
+ EntryPointer->AddressModifier = (BusEntry[i].Flags & 0x1C) ? 0 : 1;
+
+ EntryPointer++;
+ ExtendedTableLength += sizeof(MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY);
+ }
+ }
+ MpsExTableCurrentPointer = (VOID *)EntryPointer;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: QueryBusInfo
+//
+// Description: Retreive system info about buses and bus ierarchy and fills
+// BUS_INFO structure. Also creates MPS table extended entries
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified: BusEntry
+// MaxBusId
+// CurrentBusEntry
+// IsaBusId
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID QueryBusInfo(VOID)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *pHandleBuffer;
+ UINTN NumberOfHandles;
+ UINTN i;
+
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *pPciRootBridgeIoProtocol;
+ static EFI_GUID PciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+ ACPI_ADDRESS_SPACE_DESC *pAddressDescriptor;
+
+ EFI_PCI_IO_PROTOCOL *pPciIoProtocol;
+ static EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+ UINT8 PciData[4];
+ UINTN BusNumber;
+ UINTN dummy[3];
+ UINT64 SupportedAttributes;
+
+//First detect and retreive bus Id for PCI host (root) buses
+ Status = pBS->LocateHandleBuffer(ByProtocol, &PciRootBridgeIoProtocolGuid,
+ NULL, &NumberOfHandles, &pHandleBuffer);
+ if(EFI_ERROR(Status))
+ return;
+
+ for(i = 0; i < NumberOfHandles; i++)
+ {
+ Status = pBS->HandleProtocol(pHandleBuffer[i], &PciRootBridgeIoProtocolGuid,
+ (VOID**)&pPciRootBridgeIoProtocol);
+ ASSERT_EFI_ERROR(Status);
+ Status = pPciRootBridgeIoProtocol->Configuration(pPciRootBridgeIoProtocol,
+ &pAddressDescriptor);
+ ASSERT_EFI_ERROR(Status);
+ Status = pPciRootBridgeIoProtocol->GetAttributes(pPciRootBridgeIoProtocol,
+ &SupportedAttributes,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+//find bus range decoding - the min will be host PCI bus Id
+ while((pAddressDescriptor->Signature == 0x8A) && \
+ (pAddressDescriptor->ResourceType != 2))
+ pAddressDescriptor++;
+
+ BusEntry[CurrentBusEntry].BusId = (UINT8)pAddressDescriptor->AddressRangeMin;
+ BusEntry[CurrentBusEntry].ParentBusId = 0xFF; //host bus has no parent
+ BusEntry[CurrentBusEntry].BusType = BridgeBusTypes[0];
+ BusEntry[CurrentBusEntry].Flags = (UINT8)SupportedAttributes; //for host we save ISA/VGA support values
+
+ MaxBusId = (MaxBusId > BusEntry[CurrentBusEntry].BusId) ? \
+ MaxBusId : BusEntry[CurrentBusEntry].BusId;
+
+ MpsExTableAddSysAddressMapEntry(pPciRootBridgeIoProtocol,
+ BusEntry[CurrentBusEntry].BusId,
+ BusEntry[CurrentBusEntry].Flags);
+ CurrentBusEntry++;
+ }
+ pBS->FreePool(pHandleBuffer);
+
+//Second detect all other buses via PCI bridges
+ Status = pBS->LocateHandleBuffer(ByProtocol, &PciIoProtocolGuid,
+ NULL, &NumberOfHandles, &pHandleBuffer);
+ if(EFI_ERROR(Status))
+ return;
+
+ for(i = 0; i < NumberOfHandles; i++)
+ {
+ Status = pBS->HandleProtocol(pHandleBuffer[i], &PciIoProtocolGuid,
+ (VOID**)&pPciIoProtocol);
+ if(EFI_ERROR(Status))
+ continue;
+
+ //read class code information at 0x8 offset in PCI header
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x8, 1, (VOID*)PciData);
+ if(EFI_ERROR(Status)) //problem
+ continue;
+#if PCI_BUS_APIC_AUTODETECT == 1
+//if IO APIC device collect info, we will need it later
+ if((PciData[3] == 0x8) && (PciData[2] == 0) && (PciData[1] >= 0x10))
+ {
+ UINT64 Attr=0, OldAttr=0;
+ //----------------------
+ //1. make sure it is Enabled and Decoding it's resources
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationGet, Attr, &OldAttr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) continue;
+
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSupported, 0, &Attr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) continue;
+
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSet, Attr&(EFI_PCI_DEVICE_ENABLE), NULL);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) continue;
+
+ CollectIoApicInfo(pPciIoProtocol, NULL);
+
+#if PCI_BUS_APIC_LEAVE_ENABLE != 0
+ //Restore attributes of the device
+ Status=pPciIoProtocol->Attributes(pPciIoProtocol,EfiPciIoAttributeOperationSet, OldAttr, NULL);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) continue;
+#endif//PCI_BUS_APIC_LEAVE_ENABLE
+
+ continue;
+ }
+#endif//PCI_BUS_APIC_AUTODETECT
+
+ if(PciData[3] != 0x6) //not bridge device
+ continue;
+
+ if((PciData[2] == 0) || (PciData[2] > 6)) //PCI host bridge we already know, so skip it
+ continue; //or unknown bridge - skip it also
+
+ BusEntry[CurrentBusEntry].BusType = BridgeBusTypes[(PciData[2])];
+
+ if(PciData[2] == 4) // PCI to PCI bridge
+ {
+ BusEntry[CurrentBusEntry].Flags = PciData[1];
+ //read primary and secondary bus numbers
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x18, 1, (VOID*)PciData);
+
+ BusEntry[CurrentBusEntry].BusId = PciData[1]; //bus Id prodused by this bridge
+ BusEntry[CurrentBusEntry].ParentBusId = PciData[0];
+ MaxBusId = (MaxBusId > BusEntry[CurrentBusEntry].BusId) ? \
+ MaxBusId : BusEntry[CurrentBusEntry].BusId;
+ }
+ else //any other bridge
+ {
+ BusEntry[CurrentBusEntry].Flags = 1; //all other buses has this feature
+ BusEntry[CurrentBusEntry].BusId = 0xFF; //we will assign Id after enumerating PCI buses
+ //get bridge location to determine parent bus Id
+ Status = pPciIoProtocol->GetLocation(pPciIoProtocol, &dummy[0], &BusNumber,
+ &dummy[1], &dummy[2]);
+
+ BusEntry[CurrentBusEntry].ParentBusId = (UINT8)BusNumber;
+ }
+ CurrentBusEntry++;
+ }
+ pBS->FreePool(pHandleBuffer);
+
+// Third enumerate all other buses
+ for(i = 0; i < CurrentBusEntry; i++)
+ {
+ if(BusEntry[i].BusId == 0xFF)
+ {
+ BusEntry[i].BusId = MaxBusId + 1;
+ MaxBusId++;
+ if(BusEntry[i].BusType == BUS_TYPE_ISA) //save ISA bus Id for interrupt assign procedure
+ IsaBusId = MaxBusId;
+ }
+ }
+ MpsExTableAddBusHierarchyEntry();
+ MpsExTableAddCompatBusAddressModifierEntry();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CollectIoApicInfo
+//
+// Description: Retreive system info about IO APIC
+//
+// Input:
+// IN OPTIONAL EFI_PCI_IO_PROTOCOL *pPciIoProtocol
+// IN OPTIONAL UINT32 BaseAddress - base address of IO APIC
+//
+// Output:
+// VOID
+//
+// Modified: IoApicEntry
+// CurrentIoApicEntry
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CollectIoApicInfo(
+ IN EFI_PCI_IO_PROTOCOL *pPciIoProtocol OPTIONAL,
+ IN UINT32 BaseAddress OPTIONAL)
+{
+ UINT32 IoApicAddress;
+ EFI_STATUS Status;
+ UINT32 volatile *IoApicMemory32;
+ UINT8 volatile *IoApicMemory8;
+ UINT32 data;
+
+ if(BaseAddress == NULL) //IO APIC visible as PCI device
+ {
+ Status = pPciIoProtocol->Pci.Read(pPciIoProtocol, EfiPciIoWidthUint32,
+ 0x10, 1, (VOID*)&IoApicAddress);
+ if(EFI_ERROR(Status) || (IoApicAddress == 0)) //problem or mapped to default address range
+ return;
+ }
+ else // IO APIC mapped to default range
+ IoApicAddress = BaseAddress;
+
+ IoApicMemory32 = (UINT32 *)IoApicAddress;
+ IoApicMemory8 = (UINT8 *)IoApicAddress;
+
+ IoApicMemory8[IO_APIC_INDEX_REG] = IO_APIC_MAP_ID_REG;
+ data = IoApicMemory32[IO_APIC_DATA_REG];
+
+ IoApicEntry[CurrentIoApicEntry].IoApicId = (UINT8)((data & 0x0F000000) >> 24);
+
+ IoApicMemory8[IO_APIC_INDEX_REG] = IO_APIC_MAP_VERSION_REG;
+ data = IoApicMemory32[IO_APIC_DATA_REG];
+
+ IoApicEntry[CurrentIoApicEntry].IoApicVersion = (UINT8)(data & 0xFF);
+ IoApicEntry[CurrentIoApicEntry].MaxRedirectionEntries = (UINT8)((data & 0x00FF0000) >> 16);
+ IoApicEntry[CurrentIoApicEntry].IoApicFlags = 1;
+ IoApicEntry[CurrentIoApicEntry].IoApicAddress = IoApicAddress;
+
+ CurrentIoApicEntry++;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ArrangeIoApicEntries
+//
+// Description: Arranges IO APIC Entries in their ID ascending order
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified: IoApicEntry
+// CurrentIoApicEntry
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ArrangeIoApicEntries(VOID)
+{
+ UINT8 i;
+ BOOLEAN Swap = TRUE;
+ IO_APIC_INFO Temp;
+
+ while(Swap)
+ {
+ Swap = FALSE;
+ for(i = 0; i < CurrentIoApicEntry - 1; i++)
+ {
+ if(IoApicEntry[i].IoApicId > IoApicEntry[i+1].IoApicId)
+ {
+ Swap = TRUE;
+ MemCpy(&Temp, &IoApicEntry[i], sizeof(IO_APIC_INFO));
+ MemCpy(&IoApicEntry[i], &IoApicEntry[i+1], sizeof(IO_APIC_INFO));
+ MemCpy(&IoApicEntry[i+1], &Temp, sizeof(IO_APIC_INFO));
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetIoApicId
+//
+// Description: Returns IO APIC ID and Pin number assosiated with given SysVectorNumber
+//
+// Input:
+// IN UINT16 SysVectorNumber - system interrupt vector number
+// OUT UINT8 *IoApicId - Id of IO APIC which handles that vector
+// OUT UINT8 *IoApicItin - IO APIC Pin number associated with given vector number
+//
+// Output:
+// VOID
+//
+// Modified: IoApicEntry
+// CurrentIoApicEntry
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetIoApicId(
+ IN UINT16 SysVectorNumber,
+ OUT UINT8 *IoApicId,
+ OUT UINT8 *IoApicItin)
+{
+ UINT8 i;
+
+ for(i = 0; i < CurrentIoApicEntry; i++)
+ {
+ if(SysVectorNumber < IoApicEntry[i].MaxRedirectionEntries) //this is Apic we need
+ {
+ *IoApicId = IoApicEntry[i].IoApicId;
+ *IoApicItin = (UINT8)SysVectorNumber;
+ return;
+ }
+ SysVectorNumber -= IoApicEntry[i].MaxRedirectionEntries;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetCpuInfo
+//
+// Description: Returns number of cores and threads of given CPU
+//
+// Input:
+// IN UINTN Cpu - Cpu number
+// OUT UINT8 *Cores - number of cores in given Cpu
+// OUT UINT8 *Threads - number of threads in given Cpu
+//
+// Output:
+// EFI_SUCCESS - function executed successfully
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetCpuInfo(
+ IN UINTN Cpu,
+ OUT UINT8 *Cores,
+ OUT UINT8 *Threads)
+{
+ EFI_STATUS Status;
+ AMI_CPU_INFO *Info;
+
+//find AMICpuInfo protocol
+ if(AmiCpuInfoProtocol == NULL)
+ {
+ Status = pBS->LocateProtocol(&AmiCpuInfoProtocolGuid,
+ NULL,
+ &AmiCpuInfoProtocol);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ Status = AmiCpuInfoProtocol->GetCpuInfo(AmiCpuInfoProtocol, Cpu, &Info);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ *Cores = Info->NumCores;
+ *Threads = (Info->NumHts == 0) ? 1 : Info->NumHts;
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/mptable.h b/Core/EM/ACPI/mptable.h
new file mode 100644
index 0000000..6389c50
--- /dev/null
+++ b/Core/EM/ACPI/mptable.h
@@ -0,0 +1,593 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/mptable.h 8 12/03/12 11:47a Oleksiyy $
+//
+// $Revision: 8 $
+//
+// $Date: 12/03/12 11:47a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/Core/mptable.h $
+//
+// 8 12/03/12 11:47a Oleksiyy
+// [TAG] EIP107890
+// [Category] Improvement
+// [Description] Create a token that it define the Bot and Top of Io
+// APIC address.
+// [Files] AcpiCore.h and mptable.h
+//
+// 7 5/08/09 1:16p Yakovlevs
+// Made ACPI Driver use AMI Board Info Protocol if available without
+// breaking compatibility.
+//
+// 6 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 5 4/15/08 9:16p Yakovlevs
+//
+// 4 4/11/07 5:45p Artems
+// Multiprocessor detection added
+//
+// 3 3/28/07 10:43a Artems
+// Fixed bug - added System memory entry for legacy video
+//
+// 2 2/06/07 5:41p Artems
+//
+// 1 2/06/07 4:54p Artems
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Mptable.h
+//
+// Description: Header file for MP table builder
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __MPTABLE__H__
+#define __MPTABLE__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//------------------------ Include files ------------------------------
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciIo.h>
+#include <token.h>
+
+//------------------------ Type declarations --------------------------
+#define MP_TABLE_MAX_BUS_ENTRIES 0xFF //from 0 to 0xFE, FF reserved means no parent bus
+#define MP_TABLE_MAX_IO_APIC_ENTRIES 0x10
+
+#define MP_FLOATING_POINTER_SIGNATURE 0x5F504D5F // _MP_
+#define MP_CONFIGURATION_TABLE_SIGNATURE 0x504D4350 // PCMP
+
+#define MP_TABLE_VERSION_1_1 0x1
+#define MP_TABLE_VERSION_1_4 0x4
+
+#define MP_TABLE_CPU_ENTRY_TYPE 0
+#define MP_TABLE_BUS_ENTRY_TYPE 1
+#define MP_TABLE_IO_APIC_ENTRY_TYPE 2
+#define MP_TABLE_INT_ASSIGN_ENTRY_TYPE 3
+#define MP_TABLE_LOCAL_INT_ASSIGN_ENTRY_TYPE 4
+
+#define MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY_TYPE 128
+#define MP_EX_TABLE_BUS_HIERARCHY_ENTRY_TYPE 129
+#define MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY_TYPE 130
+
+#define IO_APIC_BASE_ADDRESS_BOTTOM APCB //defined earlier
+
+#if defined(IO_APIC_BASE_TOP_ADDRESS)
+#define IO_APIC_BASE_ADDRESS_TOP IO_APIC_BASE_TOP_ADDRESS //must be redefined
+#else //
+#define IO_APIC_BASE_ADDRESS_TOP 0xFED00000 //if different from default
+#endif
+
+#define IO_APIC_SEARCH_STEP 0x1000
+
+#define IO_APIC_INDEX_REG 0x0
+#define IO_APIC_DATA_REG 0x4 //(0x10 in bytes = 0x4 in dwords
+
+#define IO_APIC_MAP_ID_REG 0x0
+#define IO_APIC_MAP_VERSION_REG 0x1
+
+#define INT_TYPE_INT 0
+#define INT_TYPE_NMI 1
+#define INT_TYPE_SMI 2
+#define INT_TYPE_EXT_INT 3
+
+#define POLARITY_CONFORM_SPEC 0
+#define POLARITY_ACTIVE_HIGH 1
+#define POLARITY_ACTIVE_LOW 3
+
+#define TRIGGER_MODE_CONFORM_SPEC 0
+#define TRIGGER_MODE_EDGE_TRIGGERED 1
+#define TRIGGER_MODE_LEVEL_TRIGGERED 3
+
+#define BUS_TYPE_ISA 5
+
+#pragma pack(1)
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_FLOATING_POINTER
+//
+// Description: This structure represents MP table floating pointer format
+// as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_FOATING_POINTER
+{
+ UINT32 Signature;
+ UINT32 PhysicalAddresPointer;
+ UINT8 Length;
+ UINT8 VersionNumber;
+ UINT8 CheckSum;
+ UINT8 DefaultConfiguration;
+ UINT8 IMCRflag;
+ UINT8 Reserved[3];
+} MP_FLOATING_POINTER;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_CONFIGURATION_TABLE_HEADER
+//
+// Description: This structure represents MP configuration table header format
+// as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_CONFIGURATION_TABLE_HEADER
+{
+ UINT32 Signature;
+ UINT16 BaseTableLength;
+ UINT8 VersionNumber;
+ UINT8 CheckSum;
+ UINT8 OemId[8];
+ UINT8 ProductId[12];
+ UINT32 OemTablePointer;
+ UINT16 OemTableSize;
+ UINT16 BaseTableEntryCount;
+ UINT32 LocalApicAddress;
+ UINT16 ExtendedTableLength;
+ UINT8 ExtendedCheckSum;
+ UINT8 Reserved;
+} MP_CONFIGURATION_TABLE_HEADER;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_TABLE_CPU_ENTRY
+//
+// Description: This structure represents MP configuration table CPU entry format
+// as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_TABLE_CPU_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 LocalApicId;
+ UINT8 LocalApicVersion;
+ struct
+ {
+ UINT8 CpuEnable : 1;
+ UINT8 CpuBootStrap : 1;
+ UINT8 Reserved : 6;
+ } CpuFlags;
+ UINT32 CpuSignature;
+ UINT32 FeatureFlags;
+ UINT32 Reserved[2];
+} MP_TABLE_CPU_ENTRY;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_TABLE_BUS_ENTRY
+//
+// Description: This structure represents MP configuration table bus entry format
+// as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_TABLE_BUS_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 BusId;
+ UINT8 BusTypeString[6];
+} MP_TABLE_BUS_ENTRY;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_TABLE_IO_APIC_ENTRY
+//
+// Description: This structure represents MP configuration table IO APIC entry format
+// as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_TABLE_IO_APIC_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 IoApicId;
+ UINT8 IoApicVersion;
+ UINT8 Flags;
+
+ UINT32 IoApicAddress;
+} MP_TABLE_IO_APIC_ENTRY;
+
+typedef union
+{
+ UINT8 IsaBusIrq;
+ struct
+ {
+ UINT8 PciIntSignal : 2;
+ UINT8 PciDeviceNumber : 5;
+ UINT8 Reserved : 1;
+ } PciBusIrq;
+} SOURCE_IRQ;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_TABLE_INT_ASSIGN_ENTRY
+//
+// Description: This structure represents MP configuration table interrupt assingment
+// entry format as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_TABLE_INT_ASSIGN_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 InterruptType;
+ UINT16 Flags;
+ UINT8 SourceBusId;
+ SOURCE_IRQ SourceBusIrq;
+ UINT8 DestIoApicId;
+ UINT8 DestIoApicItin;
+} MP_TABLE_INT_ASSIGN_ENTRY;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_TABLE_LOCAL_INT_ASSIGN_ENTRY
+//
+// Description: This structure represents MP table local interrupt assingment
+// entry format as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_TABLE_LOCAL_INT_ASSIGN_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 InterruptType;
+ struct
+ {
+ UINT16 Polarity : 2;
+ UINT16 TriggerMode : 2;
+ UINT16 Reserved : 12;
+ } InterruptSignal;
+ UINT8 SourceBusId;
+ UINT8 SourceBusIrq;
+ UINT8 DestLocalApicId;
+ UINT8 DestLocalApicItin;
+} MP_TABLE_LOCAL_INT_ASSIGN_ENTRY;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY
+//
+// Description: This structure represents MP table system address map extended
+// entry format as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 EntryLength;
+ UINT8 BusId;
+ UINT8 AddressType;
+ UINT64 AddressBase;
+ UINT64 AddressLength;
+} MP_EX_TABLE_SYS_ADDRESS_MAP_ENTRY;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_EX_TABLE_BUS_HIERARCHY_ENTRY
+//
+// Description: This structure represents MP table bus hierarchy extended
+// entry format as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_EX_TABLE_BUS_HIERARCHY_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 EntryLength;
+ UINT8 BusId;
+ UINT8 BusInfo;
+ UINT8 ParentBusId;
+ UINT8 Reserved[3];
+} MP_EX_TABLE_BUS_HIERARCHY_ENTRY;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY
+//
+// Description: This structure represents MP table compatibility bus address modifier
+// extended entry format as defined in MPS specification v1.4
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY
+{
+ UINT8 EntryType;
+ UINT8 EntryLength;
+ UINT8 BusId;
+ UINT8 AddressModifier;
+ UINT32 RangeList;
+} MP_EX_TABLE_COMPAT_BUS_ADDRESS_MODIFIER_ENTRY;
+
+//----------------------- Additional structures -----------------------
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BUS_INFO
+//
+// Description: PCI bus description data structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// BusId UINT8 Bus Id number
+// ParentBusId UINT8 Parent bus Id number
+// BusType UINT8 Bus type number
+// Flags UINT8 Bus flags
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _BUS_INFO
+{
+ UINT8 BusId;
+ UINT8 ParentBusId;
+ UINT8 BusType;
+ UINT8 Flags;
+} BUS_INFO;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: ACPI_ADDRESS_SPACE_DESC
+//
+// Description: This structure represents ACPI address space descriptor
+// format as defined in ACPI specification v3.0
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _ACPI_ADDRESS_SPACE_DESC
+{
+ UINT8 Signature;
+ UINT16 DescLength;
+ UINT8 ResourceType;
+ UINT8 GeneralFlags;
+ UINT8 TypeSpecificFlags;
+ UINT64 AddressSpaceGranularity;
+ UINT64 AddressRangeMin;
+ UINT64 AddressRangeMax;
+ UINT64 AddressTranslationOffset;
+ UINT64 AddressLength;
+} ACPI_ADDRESS_SPACE_DESC;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: IO_APIC_DEST
+//
+// Description: Device interrupt destination description data structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// IoApicItin UINT8 IO APIC pin number
+// IoApicId UINT8 IO APIC Id
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _IO_APIC_DEST
+{
+ UINT8 IoApicItin;
+ UINT8 IoApicId;
+} IO_APIC_DEST;
+
+#if AmiBoardInfo_SUPPORT == 0
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: PCI_IRQ_APIC_ROUTE
+//
+// Description: PCI interrupt routing description data structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// PciBusNumber UINT8 PCI bus number
+// DeviceNumber UINT8 PCI device number
+// Intn IO_APIC_DEST Interrupt destination
+// Reserved UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _PCI_IRQ_APIC_ROUTE
+{
+ UINT8 PciBusNumber;
+ UINT8 DeviceNumber;
+ IO_APIC_DEST Intn[4];
+ UINT8 Reserved;
+} PCI_IRQ_APIC_ROUTE;
+#endif
+
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: IO_APIC_INFO
+//
+// Description: IO APIC description data structure
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// IoApicId UINT8 IO APIC Id
+// IoApicVersion UINT8 IO APIC version
+// IoApicFlags UINT8 IO APIC flags
+// MaxRedirectionEntries UINT8 Max number of redirection entries supported by IO APIC
+// IoApicAddress UINT32 IO APIC address in memory
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct _IO_APIC_INFO
+{
+ UINT8 IoApicId;
+ UINT8 IoApicVersion;
+ UINT8 IoApicFlags;
+ UINT8 MaxRedirectionEntries;
+ UINT32 IoApicAddress;
+} IO_APIC_INFO;
+
+#pragma pack()
+
+//------------------------ Global variables ---------------------------
+
+
+//------------------------ Functions prototypes -----------------------
+
+EFI_STATUS MpsTableBuilderInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS MpsTableFloatPointerModify(
+ VOID
+ );
+
+EFI_STATUS MpsTableCreate(
+ VOID
+ );
+
+VOID MpsTableReadyToBootNotify(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS MpsTableAddHeader(
+ VOID
+ );
+
+UINT16 MpsTableAddCpuEntry(
+ VOID
+ );
+
+UINT16 MpsTableAddBusEntry(
+ VOID
+ );
+
+UINT16 MpsTableAddIoApicEntry(
+ VOID
+ );
+
+UINT16 MpsTableAddIntAssignEntry(
+ VOID
+ );
+
+UINT16 MpsTableAddLocalIntAssignEntry(
+ VOID
+ );
+
+VOID MpsTableAddExtendedTable(
+ VOID
+ );
+
+VOID MpsExTableAddSysAddressMapEntry(
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *pPciRootBridgeIoProtocol,
+ IN UINT8 BusId,
+ IN UINT8 BusAttributes
+ );
+
+VOID MpsExTableAddBusHierarchyEntry(
+ VOID
+ );
+
+VOID MpsExTableAddCompatBusAddressModifierEntry(
+ VOID
+ );
+
+
+//----------------------- Additional functions -------------------------
+
+VOID QueryBusInfo(
+ VOID
+ );
+
+VOID CollectIoApicInfo(
+ IN EFI_PCI_IO_PROTOCOL *pPciIoProtocol OPTIONAL,
+ IN UINT32 BaseAddress OPTIONAL
+ );
+
+VOID ArrangeIoApicEntries(
+ VOID
+ );
+
+VOID GetIoApicId(
+ IN UINT16 SysVectorNumber,
+ OUT UINT8 *IoApicId,
+ OUT UINT8 *IoApicItin
+ );
+
+EFI_STATUS GetCpuInfo(
+ IN UINTN Cpu,
+ OUT UINT8 *Cores,
+ OUT UINT8 *Threads
+ );
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/ACPI/rmisc.asl b/Core/EM/ACPI/rmisc.asl
new file mode 100644
index 0000000..07b541c
--- /dev/null
+++ b/Core/EM/ACPI/rmisc.asl
@@ -0,0 +1,120 @@
+// Miscellaneous I/O and memory resources
+// System board extension Device node for ACPI BIOS
+// THIS FILE IS INCLUDED to LPC/ISA PCI bridge scope
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//-----------------------------------------------------------------------
+// $Header: /Alaska/BIN/Modules/ACPI/Template/Core/rmisc.asl 5 7/12/10 11:26a Oleksiyy $Revision:
+//
+// $Date: 7/12/10 11:26a $Log:
+//**********************************************************************;
+/*
+;<AMI_PHDR_START>
+;------------------------------------------------------------------------
+;
+; Procedure: RMSC
+;
+; Description: Chipset Miscellaneous I/O and memory resources
+; This table should contain any I/O port that is not used by a specific
+; device but does not return FFh when read. Some examples of I/O ports
+; that should be reserved here are:
+; Any I/O port in the range 00 - FF that is not used by any other dev node
+; The IRQ edge/level control ports (4D0/4D1)
+;
+; Input: Nothing
+;
+; Output: _CRS buffer
+;
+;-------------------------------------------------------------------------
+;<AMI_PHDR_END>
+*/
+ Device(RMSC) {
+
+ Name(_HID, EISAID("PNP0C02")) // System board resources device node ID
+ Name(_UID, 0x10) // Unique ID. Used first I/O range address from _CRS buffer.
+
+ Name(CRS1, ResourceTemplate()
+ {
+ IO(Decode16,0x10, 0x10, 0,0x10)
+ IO(Decode16,0x22, 0x22, 0,0x1e)
+ IO(Decode16,0x44, 0x44, 0,0x1c)
+ IO(Decode16,0x62, 0x62, 0,0x02)
+ IO(Decode16,0x65, 0x65, 0,0x0b)
+ IO(Decode16,0x72, 0x72, 0,0x0e)
+ IO(Decode16,0x80, 0x80, 0,0x01)
+ IO(Decode16,0x84, 0x84, 0,0x03)
+ IO(Decode16,0x88, 0x88, 0,0x01)
+ IO(Decode16,0x8c, 0x8c, 0,0x03)
+ IO(Decode16,0x90, 0x90, 0,0x10)
+ IO(Decode16,0xa2, 0xa2, 0,0x1e)
+ IO(Decode16,0xe0, 0xe0, 0,0x10)
+// Decoded but not used by FDC. Reserved in FDC device node resources
+// IO(Decode16, 0x3f3, 0x3f3, 0, 0x1)
+// Reserve 4D0 and 4D1 for IRQ edge/level control port
+ IO(Decode16, 0x4d0, 0x4d0, 0, 0x2)
+//S.Y Not existing resource
+// SB NVRAM 1 I/O space
+// IO(Decode16, 0xDE00, 0xDE00, 0, 0x80)
+// SB NVRAM 2 I/O space
+// IO(Decode16, 0xDE80, 0xDE80, 0, 0x80)
+
+ } // End of ResourceTemplate
+ ) // end of CRS1
+ Name(CRS2, ResourceTemplate()
+ {
+ IO(Decode16,0x10, 0x10, 0,0x10)
+ IO(Decode16,0x22, 0x22, 0,0x1e)
+ IO(Decode16,0x44, 0x44, 0,0x1c)
+ IO(Decode16,0x72, 0x72, 0,0x0e)
+ IO(Decode16,0x80, 0x80, 0,0x01)
+ IO(Decode16,0x84, 0x84, 0,0x03)
+ IO(Decode16,0x88, 0x88, 0,0x01)
+ IO(Decode16,0x8c, 0x8c, 0,0x03)
+ IO(Decode16,0x90, 0x90, 0,0x10)
+ IO(Decode16,0xa2, 0xa2, 0,0x1e)
+ IO(Decode16,0xe0, 0xe0, 0,0x10)
+// Decoded but not used by FDC. Reserved in FDC device node resources
+// IO(Decode16, 0x3f3, 0x3f3, 0, 0x1)
+// Reserve 4D0 and 4D1 for IRQ edge/level control port
+ IO(Decode16, 0x4d0, 0x4d0, 0, 0x2)
+//S.Y Not existing resource
+// SB NVRAM 1 I/O space
+// IO(Decode16, 0xDE00, 0xDE00, 0, 0x80)
+// SB NVRAM 2 I/O space
+// IO(Decode16, 0xDE80, 0xDE80, 0, 0x80)
+
+ } // End of ResourceTemplate
+ ) // end of CRS2
+ Method (_CRS, 0)
+ {
+ If(And(\MBEC, 0xFFFF)){//Check if there is an EC in system
+ Return(CRS1)
+ }else{
+ Return(CRS2)
+ }
+ }
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMIDebugRx/AMIDebugRx.chm b/Core/EM/AMIDebugRx/AMIDebugRx.chm
new file mode 100644
index 0000000..257131c
--- /dev/null
+++ b/Core/EM/AMIDebugRx/AMIDebugRx.chm
Binary files differ
diff --git a/Core/EM/AMIDebugRx/AMIDebugRx.cif b/Core/EM/AMIDebugRx/AMIDebugRx.cif
new file mode 100644
index 0000000..9dc6679
--- /dev/null
+++ b/Core/EM/AMIDebugRx/AMIDebugRx.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "AMI Debug Rx"
+ category = eModule
+ Rank = 46
+ LocalRoot = "Core\em\AMIDebugRx\"
+ RefName = "AMIDebugRx"
+[files]
+"AMIDebugRx.sdl"
+[parts]
+"DebugRx"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/AMIDebugRx.mak b/Core/EM/AMIDebugRx/AMIDebugRx.mak
new file mode 100644
index 0000000..93f67fe
--- /dev/null
+++ b/Core/EM/AMIDebugRx/AMIDebugRx.mak
@@ -0,0 +1,88 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/AMIDebugRx.mak 3 8/28/12 8:59a Sudhirv $Revision: 1 $
+#
+# $Date: 8/28/12 8:59a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/AMIDebugRx.mak $(BUILD_DIR)\AMIDebugRx.mak
+#
+# 3 8/28/12 8:59a Sudhirv
+# Updated for AMI Debug for UEFI 2.04.0073 Label
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 2 7/13/09 2:41p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:45p Sudhirv
+# Restructure Binaries Created
+#
+# 2 4/29/09 8:05a Sudhirv
+# Updated
+#
+# 1 4/29/09 7:51a Sudhirv
+# AMI Debug Rx module created
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AMIDebugRx_mak
+#
+# Description: Make file for the USB Redirection component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF "$(AMI_DEBUGGER_SUPPORT)"!="1" && "$(USB_REDIRECTION_SUPPORT)"!="1" && "$(AMIDEBUG_RX_SUPPORT)"=="1" && "$(PeiDebugger_SUPPORT)"=="0"
+!ERROR AMIDEBUG_RX_SUPPORT requires the PeiDebugger_SUPPORT SDL token to be 1.\
+ AMIDebugRx requires the PeiDebugger_SUPPORT SDL token to be enabled.
+!ENDIF
+
+!IF "$(AMI_DEBUGGER_SUPPORT)"!="1" && "$(USB_REDIRECTION_SUPPORT)"!="1" && "$(AMIDEBUG_RX_SUPPORT)"=="1" && "$(USB_DEBUG_TRANSPORT)"=="0"
+!ERROR AMIDEBUG_RX_SUPPORT requires the USB_DEBUG_TRANSPORT SDL token to be 1.\
+ AMIDebugRx requires the USB_DEBUG_TRANSPORT SDL token to be enabled.
+!ENDIF
+
+all : AMIDebugRx
+
+AMIDebugRx : $(BUILD_DIR)\AMIDebugRx.mak
+
+$(BUILD_DIR)\AMIDebugRx.mak : $(AMI_DebugRx_DIR)\$(@B).cif $(AMI_DebugRx_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AMI_DebugRx_DIR)\DebugRx.cif $(CIF2MAK_DEFAULTS)
+
+SetupSdbs : AMIDebugRxSDB
+
+AMIDebugRxSDB : $(BUILD_DIR)\AMIDebugRx.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMIDebugRx.mak all\
+ TYPE=SDB NAME=AMIDebugRx STRING_CONSUMERS=$(AMI_DebugRx_DIR)\AMIDebugRx.sd
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/AMIDebugRx.sd b/Core/EM/AMIDebugRx/AMIDebugRx.sd
new file mode 100644
index 0000000..75ff84a
--- /dev/null
+++ b/Core/EM/AMIDebugRx/AMIDebugRx.sd
@@ -0,0 +1,66 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/AMIDebugRx.sd 4 7/17/09 7:19p Madhans $
+//
+// $Revision: 4 $
+//
+// $Date: 7/17/09 7:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/AMIDebugRx.sd $
+//
+// 4 7/17/09 7:19p Madhans
+// Fix the Header
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: USBRedirection.sd
+//
+// Description: This is the setup page which displays the message if AMI
+// Debug Rx is Enabled or not.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef ADVANCED_FORM_SET
+
+ #ifdef FORM_SET_ITEM
+
+ SUBTITLE(STRING_TOKEN(STR_AMI_DEBUG_RX_PRESENT))
+
+ SEPARATOR
+
+ #endif //ifdef FORM_SET_FORM
+
+#endif //ifdef ADVANCED_FORM_SET
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/AMIDebugRx.sdl b/Core/EM/AMIDebugRx/AMIDebugRx.sdl
new file mode 100644
index 0000000..c3ad8bb
--- /dev/null
+++ b/Core/EM/AMIDebugRx/AMIDebugRx.sdl
@@ -0,0 +1,34 @@
+TOKEN
+ Name = "AMIDEBUG_RX_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Ami Debug Rx Module."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "DEBUGGER_MAJOR_VERSION"
+ Value = "2"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEBUGGER_MINOR_VERSION"
+ Value = "04"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEBUGGER_BUILD"
+ Value = "0074"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
diff --git a/Core/EM/AMIDebugRx/AMIDebugRx.uni b/Core/EM/AMIDebugRx/AMIDebugRx.uni
new file mode 100644
index 0000000..6d10b49
--- /dev/null
+++ b/Core/EM/AMIDebugRx/AMIDebugRx.uni
Binary files differ
diff --git a/Core/EM/AMIDebugRx/DebugRx.cif b/Core/EM/AMIDebugRx/DebugRx.cif
new file mode 100644
index 0000000..b5e7279
--- /dev/null
+++ b/Core/EM/AMIDebugRx/DebugRx.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "DebugRx"
+ category = ModulePart
+ LocalRoot = "Core\EM\AMIDebugRx\"
+ RefName = "DebugRx"
+[files]
+"AMIDebugRx.chm"
+"AMIDebugRx.mak"
+"AMIDebugRx.sd"
+"AMIDebugRx.uni"
+"DebugRx.sdl"
+[parts]
+"PeiAMIDebugRx"
+"PeiDbgStatusCodeLibBin"
+"DbgrUsbCableSelectLib"
+"DbgrX64Lib"
+"DebuggerLib"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/DebugRx.sdl b/Core/EM/AMIDebugRx/DebugRx.sdl
new file mode 100644
index 0000000..7c96ea5
--- /dev/null
+++ b/Core/EM/AMIDebugRx/DebugRx.sdl
@@ -0,0 +1,121 @@
+TOKEN
+ Name = "SEND_CHECKPOINT_SUPPORT"
+ Value = "1"
+ Help = "Token to enable/disable Checkpoint sending support."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SEND_DEBUG_MESSAGE_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable/disable Debug messages redirection"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REDIRECTION_ONLY_MODE"
+ Value = "1"
+ Help = "Internal Switch to control the Redirection only support withing the modules. Please don't change it."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PeiDebugger_SUPPORT"
+ Value = "1"
+ Help = "Can be changed only if debugger/USBRedirction module is present. Main switch to enable Pei Debugger support in Project."
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "USB_DEBUG_TRANSPORT"
+ Value = "1"
+ Help = "Can be changed only if debugger/USBRedirction module is present. Main token switch to enable the USB Debug Port interface\installation into the project.\Disable this switch if Serial or Generic USB Cable interface is desired."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMI_DEBUG_RX_IN_S3_SUPPORT"
+ Value = "0"
+ Help = "SDL token to have AMI Debug RX support in S3 Resume. "
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT"
+ Value = "0"
+ Help = "SDL token to have Debugger related ffs in FV_MAIN or FV_BB. "
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "S3_BASE_MEMORY_SIZE"
+ Value = "0x100000"
+ Help = "Number of bytes for S3 resume base memory."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0x40000 = 256K, increase/decrease it in units of 0x1000 = 4K"
+ Token = "AMI_DEBUG_RX_IN_S3_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "DBG_WRITE_IO_SUPPORT"
+ Value = "1"
+ Help = "Main token switch to enable Write IO support from Debugger User."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "REDIRECTION_ONLY_MODE" "!=" "1"
+End
+
+TOKEN
+ Name = "DBG_WRITE_IO_80_SUPPORT"
+ Value = "1"
+ Help = "Token switch to 1:Enable\0:Disable the port 80 checkpoints from AMIDebugRx\Debugger modules."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "AMI_DebugRx_DIR"
+End
+
+MODULE
+ Help = "Includes AMIDebugRx.mak to Project"
+ File = "AMIDebugRx.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AMIDebugRx.sdb"
+ Parent = "SETUP_SDBS"
+ Priority = 50
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(AMI_DebugRx_DIR)\AMIDebugRx.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 50
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D AMI_DEBUGRx_SUPPORT"
+ Parent = "CFLAGS"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.cif b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.cif
new file mode 100644
index 0000000..c9471bc
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "DbgrUsbCableSelectLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\AMIDebugRx\binaries\LIBS\"
+ RefName = "DbgrUsbCableSelectLib"
+[files]
+"\DbgrUsbCableSelectLib.mak"
+"\UsbCableSelect.c"
+"\DbgrUsbCableSelectLib.sdl"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.mak b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.mak
new file mode 100644
index 0000000..4b0c304
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.mak
@@ -0,0 +1,150 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.mak 2 7/17/09 7:15p Madhans $
+#
+# $Revision: 2 $
+#
+# $Date: 7/17/09 7:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.mak $
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 2 7/13/09 2:43p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 2 5/01/09 7:44p Madhans
+#
+# 1 4/29/09 7:51a Sudhirv
+# AMI Debug Rx module created
+#
+# 9 12/12/08 5:13p Madhans
+# USB Redirecion Module.
+#
+# 7 9/07/07 12:07a Madhans
+# 1.07.0008 Eng Release
+#
+# 6 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 5 3/12/07 6:19p Madhans
+# !!!coding standards!!!!
+#
+# 4 1/22/07 4:14p Madhans
+# 1.04.0002 Binary Version.
+#
+# 3 12/26/06 7:07p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+# 2 9/22/06 11:33a Ashrafj
+# Removed the previous specific changes made to support the new USB
+# cable, by means of SDL token.
+# New changes made to support the new USB cables by means of providing
+# the USB Standard Device Requests command functions in USB Transport
+# modules, so that the porting engineer can use those in
+# DbgrUsbCableSelectLib library sources.
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: DbgrUsbCableSelectLib.mak
+#
+# Description: Makefile of Debugger Usb Cable select lib
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+AMITransportBin : $(AMIDXELIB) $(BUILD_DIR)\DbgrUsbCableSelectLib.lib
+
+!IF "$(PeiDebugger_SUPPORT)"=="1"
+!IF "$(x64_BUILD)"!="1"
+PeiDbgXportBin : $(BUILD_DIR)\DbgrUsbCableSelectLib.lib
+!ELSE
+PeiDbgXportBin : $(BUILD_DIR)\PeiDbgrUsbCableSelectLib.lib
+PeiDbgXportx64Bin : $(BUILD_DIR)\DbgrUsbCableSelectLib.lib
+!ENDIF
+!ENDIF
+
+!ENDIF
+
+$(BUILD_DIR)\DbgrUsbCableSelectLib.lib : DbgrUsbCableSelectLib
+
+DbgrUsbCableSelectLib : $(BUILD_DIR)\DbgrUsbCableSelectLib.mak DbgrUsbCableSelectLibBin
+
+$(BUILD_DIR)\DbgrUsbCableSelectLib.mak : $(DbgrUsbCableSelectLib_DIR)\$(@B).cif $(DbgrUsbCableSelectLib_DIR)\DbgrUsbCableSelectLib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(DbgrUsbCableSelectLib_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(x64_BUILD)"!="1"
+
+DbgrUsbCableSelectLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\DbgrUsbCableSelectLib.mak all\
+ TYPE=LIBRARY \
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT"
+!ELSE
+
+$(BUILD_DIR)\PeiDbgrUsbCableSelectLib.lib : DbgrUsbCableSelectLib
+
+DbgrUsbCableSelectLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\DbgrUsbCableSelectLib.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\DbgrUsbCableSelectLib.lib\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT"
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\DbgrUsbCableSelectLib.mak all\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(BUILD_DIR)\PeiDbgrUsbCableSelectLib.lib\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT"
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.sdl b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.sdl
new file mode 100644
index 0000000..394be27
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrUsbCableSelectLib.sdl
@@ -0,0 +1,9 @@
+PATH
+ Name = "DbgrUsbCableSelectLib_DIR"
+End
+
+MODULE
+ Help = "Includes DbgrUsbCableSelect.mak to Project"
+ File = "DbgrUsbCableSelectLib.mak"
+End
+
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/AsmDbgrx64Libs.h b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/AsmDbgrx64Libs.h
new file mode 100644
index 0000000..ade7358
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/AsmDbgrx64Libs.h
@@ -0,0 +1,202 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DbgrX64Lib/AsmDbgrx64Libs.h 4 3/13/12 10:52a Sudhirv $
+//
+// $Revision: 4 $
+//
+// $Date: 3/13/12 10:52a $
+//*****************************************************************
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DbgrX64Lib/AsmDbgrx64Libs.h $
+//
+// 4 3/13/12 10:52a Sudhirv
+// [TAG] EIP60224
+// [Category] Improvement
+// [Description] Function implement When broken in SMM, show the register
+// context for 'outside' SMM.
+//
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// [TAG] EIP81423
+// [Category] Improvement
+// [Description] VeB Debugger - Improve the EFI tab's Handle Display
+// feature
+//
+// [TAG] EIP84201
+// [Category] Improvement
+// [Description] AMIDebugRx\Debugger Target modules usage of the Port 80
+// must be controlable
+//
+// 3 9/22/10 7:09p Sudhirv
+// 4.6.2_AMIDebugRx_2.01.0026_Beta Release
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 3 7/16/09 3:07p Madhans
+// To fix the Serial Debugger issuel and To do cleanup.
+//
+// 2 7/13/09 2:44p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:51a Sudhirv
+// AMI Debug Rx module created
+//
+// 3 9/07/07 12:07a Madhans
+// 1.07.0008 Eng Release
+//
+// 7 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 6 2/23/07 5:34p Madhans
+// EnableMasterPICIRQ function added
+//
+// 5 1/22/07 11:36a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//**********************************************************************
+//*****************************************************************
+//*****************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AsmDbgrx64Libs.h
+//
+// Description: File containing the Prototypes for the library functions
+//
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "Efi.h"
+
+UINT8
+DbgrIoRead8 (
+ IN UINT64 Address
+ )
+/*++
+
+Routine Description:
+ Do a one byte IO read
+
+Arguments:
+ Address - IO address to read
+
+Returns:
+ Data read
+
+--*/
+;
+VOID
+DbgrIoWrite8 (
+ IN UINT64 Address,
+ IN UINT8 Data
+ )
+/*++
+
+Routine Description:
+ Do a one byte IO write
+
+Arguments:
+ Address - IO address to write
+ Data - Data to write to Address
+
+Returns:
+ NONE
+
+--*/
+;
+void DbgrDisableInterrupt();
+void DbgrRestoreInterrupt();
+
+void DebugWriteChkPort(UINT8 DbgChkPoint);
+
+UINT32 ReadPCIConfigSpace(IN UINT32 PCIAddr);
+VOID WritePCIConfigSpace(UINT32 PCIAddr,UINT32 Data);
+
+void DisableMasterPICIRQ(UINT8 IrqBit);
+void EnableMasterPICIRQ(UINT8 IrqBit);
+
+#define DISABLE_INTx64 DbgrDisableInterrupt()
+#define RESTORE_INTx64 DbgrRestoreInterrupt()
+
+void DisableDebugFeature(UINTN *pStoreDr7);
+void EnableDebugFeature(UINTN *pLoadDr7);
+
+VOID SetHWBreakpointX64_DR2(UINTN Address);
+VOID DisableIF(VOID);
+VOID EnableIF(VOID);
+void EnableBreakpointOnIO();
+void DisableBreakpointOnIO();
+VOID GetIdtr(VOID *addr);
+
+UINT8 IoReadByte(UINT16 Port);
+VOID IoWriteByte(UINT16 Port, UINT8 Value);
+UINT32 GetCPUInfo0(VOID);
+UINT32 GetCPUInfo4(VOID);
+UINT32 GetCPUInfo8(VOID);
+UINT32 GetVersion(VOID);
+UINT32 GetFeature(VOID);
+UINT8 ReadIoAsm8(UINT16 Port);
+VOID WriteIoAsm8 (UINT16 Port,UINT8 Val);
+UINT16 IoReadWord(UINT16 Port);
+VOID IoWriteWord(UINT16 Port, UINT16 Value);
+UINT32 IoReadDword(UINT16 Port);
+VOID IoWriteDword(UINT16 Port, UINT32 Value);
+VOID SET_SOFTWAREBREAKPOINT();
+
+// For IndirectIO Support
+UINT8 IIoReadByte(UINT16 DataPort, UINT16 IndexPort, UINT16 Port);
+VOID IIoWriteByte(UINT16 DataPort, UINT16 IndexPort, UINT16 Port, UINT8 Value);
+UINT16 IIoReadWord(UINT16 DataPort, UINT16 IndexPort, UINT16 Port);
+VOID IIoWriteWord(UINT16 DataPort, UINT16 IndexPort, UINT16 Port, UINT16 Value);
+UINT32 IIoReadDword(UINT16 DataPort, UINT16 IndexPort, UINT16 Port);
+VOID IIoWriteDword(UINT16 DataPort, UINT16 IndexPort, UINT16 Port, UINT32 Value);
+UINT64 GetCpuTmr();
+
+//EIP 80406 - Debugger support for Dynamic pci express base token
+UINT32 IoRead32(UINT16);
+VOID IoWrite32(UINT16 Port, UINT32 Value);
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.cif b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.cif
new file mode 100644
index 0000000..329b6ca
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "DbgrX64Lib"
+ category = ModulePart
+ LocalRoot = "Core\EM\AMIDebugRx\binaries\LIBS\DbgrX64Lib\"
+ RefName = "DbgrX64Lib"
+[files]
+"DbgrX64Lib.sdl"
+"DbgrX64Lib.mak"
+"DbgrX64Lib.lib"
+"AsmDbgrx64Libs.h"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.lib b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.lib
new file mode 100644
index 0000000..aa1607c
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.lib
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.mak b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.mak
new file mode 100644
index 0000000..80f213a
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.mak
@@ -0,0 +1,110 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.mak 3 4/20/11 8:59a Sudhirv $
+#
+# $Revision: 3 $
+#
+# $Date: 4/20/11 8:59a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.mak $
+#
+# 3 4/20/11 8:59a Sudhirv
+# [TAG] EIP58619
+# [Category] Defect
+# [Severity] Major
+# [Symptom] Statuscode 16 and 17 have build errors with USBRedirection
+# [RootCause] StatuscodeRuntimeBin added after Statuscode_15 was having
+# build errors in accessing Dbgrx64 lib functions.
+# [Solution] StatusCodeRuntimeBin build support with DbgrX64Lib.lib
+# [Files] DbgrX64Lib.mak
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 2 7/13/09 2:44p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 1 4/29/09 7:51a Sudhirv
+# AMI Debug Rx module created
+#
+# 2 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 1 1/22/07 4:14p Madhans
+# 1.04.0002 Binary Version.
+#
+# 2 1/05/07 1:05p Ashrafj
+# Latest version 1.04.0001 Beta
+# Known issues from previous 1.04.000 Beta release has been fixed.
+#
+# 1 12/26/06 7:09p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: DbgrX64Lib.mak
+#
+# Description: Common library to support the porting of Debugger to
+# support EFIx64
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+!IF "$(PROCESSOR)"=="x64"
+PeiDbgDbgrx64Bin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+PeiDbgXportx64Bin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+PeiDbgDxeCpuLibBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+#AMIDebuggerBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+IsaSerialDbgBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+PeiDbgStatusCodeLibBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+AMITransportBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+CORE_DXEBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+#EIP 58619 - Building issue between UsbRedirection and StatusCode modules (16-17) on HuronRiver project
+StatusCodeRuntimeBin : $(DbgrX64_DIR)\DbgrX64Lib.lib
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.sdl b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.sdl
new file mode 100644
index 0000000..99c5060
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DbgrX64Lib/DbgrX64Lib.sdl
@@ -0,0 +1,16 @@
+PATH
+ Name = "DbgrX64_DIR"
+End
+
+MODULE
+ Help = "Includes DbgrX64Lib.mak to Project"
+ File = "DbgrX64Lib.mak"
+End
+
+ELINK
+ Name = "Init_AMI_USBDebugPort_HOB,"
+ Parent = "DxeCoreInitialize"
+ Token = "x64_BUILD" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.cif b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.cif
new file mode 100644
index 0000000..3c3f435
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "DebuggerLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\AMIDebugRx\binaries\LIBS\DebuggerLib\"
+ RefName = "DebuggerLib"
+[files]
+"DebuggerLib.sdl"
+"DebuggerLib.mak"
+"DebuggerLib.lib"
+"DebuggerLibX64.lib"
+"DebuggerLib_PI_1_1.lib"
+"DebuggerLibX64_PI_1_1.lib"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.lib b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.lib
new file mode 100644
index 0000000..998b4ee
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.lib
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.mak b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.mak
new file mode 100644
index 0000000..ac53106
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.mak
@@ -0,0 +1,133 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.mak 4 3/16/11 4:42p Sudhirv $
+#
+# $Revision: 4 $
+#
+# $Date: 3/16/11 4:42p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.mak $
+#
+# 4 3/16/11 4:42p Sudhirv
+# Changes to Support Older Core before 4.6.5.0
+#
+# 3 3/09/11 8:16a Sudhirv
+# EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 2 7/13/09 2:45p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 1 4/29/09 7:51a Sudhirv
+# AMI Debug Rx module created
+#
+# 4 12/12/08 5:14p Madhans
+# USB Redirecion Module.
+#
+# 3 9/07/07 11:14a Madhans
+# 1.07.0008 Eng Release
+#
+# 2 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 1 3/10/07 2:37p Madhans
+# For 1.05.binary Release.
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: DebuggerLib.mak
+#
+# Description: Library to send Ld image notifications to PEI debugger
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+!IFDEF PI_SPECIFICATION_VERSION
+!IF $(PI_SPECIFICATION_VERSION)>=0x00010000
+
+CORE_PEIBin : $(DebuggerLib_DIR)\DebuggerLib_PI_1_1.lib
+
+PeiDebugSupportBin : $(DebuggerLib_DIR)\DebuggerLib_PI_1_1.lib
+
+!IF "$(x64_BUILD)"!="1"
+CORE_DXEBin : $(DebuggerLib_DIR)\DebuggerLib_PI_1_1.lib
+
+!ELSE
+CORE_DXEBin : $(DebuggerLib_DIR)\DebuggerLibX64_PI_1_1.lib
+
+
+!ENDIF
+
+!ELSE
+CORE_PEIBin : $(DebuggerLib_DIR)\DebuggerLib.lib
+
+#!IF "$(DbgPortStatusRedirectionOnly_SUPPORT)" != "1"
+PeiDebugSupportBin : $(DebuggerLib_DIR)\DebuggerLib.lib
+
+!IF "$(x64_BUILD)"!="1"
+CORE_DXEBin : $(DebuggerLib_DIR)\DebuggerLib.lib
+
+!ELSE
+CORE_DXEBin : $(DebuggerLib_DIR)\DebuggerLibX64.lib
+
+
+!ENDIF
+!ENDIF
+!ELSE
+
+CORE_PEIBin : $(DebuggerLib_DIR)\DebuggerLib.lib
+
+#!IF "$(DbgPortStatusRedirectionOnly_SUPPORT)" != "1"
+PeiDebugSupportBin : $(DebuggerLib_DIR)\DebuggerLib.lib
+
+!IF "$(x64_BUILD)"!="1"
+CORE_DXEBin : $(DebuggerLib_DIR)\DebuggerLib.lib
+
+!ELSE
+CORE_DXEBin : $(DebuggerLib_DIR)\DebuggerLibX64.lib
+
+
+!ENDIF
+#!ENDIF
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.sdl b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.sdl
new file mode 100644
index 0000000..042f87d
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib.sdl
@@ -0,0 +1,29 @@
+PATH
+ Name = "DebuggerLib_DIR"
+End
+
+MODULE
+ Help = "Includes DebuggerLib.mak to Project"
+ File = "DebuggerLib.mak"
+End
+
+ELINK
+ Name = "InitDbgLdImageNotify,"
+ Parent = "DxeCoreInitialize"
+ Token = "REDIRECTION_ONLY_MODE" "!=" "1"
+ Token = "PeiDebugger_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiDbgSptLdr,"
+ Parent = "PeiCoreInitialize"
+ Token = "PeiDebugger_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ReadyToBootFunc,"
+ Parent = "DxeCoreInitialize"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64.lib b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64.lib
new file mode 100644
index 0000000..9bfdc32
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64.lib
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64_PI_1_1.lib b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64_PI_1_1.lib
new file mode 100644
index 0000000..e45046a
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLibX64_PI_1_1.lib
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib_PI_1_1.lib b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib_PI_1_1.lib
new file mode 100644
index 0000000..e0b06b4
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/DebuggerLib/DebuggerLib_PI_1_1.lib
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.mak b/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.mak
new file mode 100644
index 0000000..dedc6d7
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.mak
@@ -0,0 +1,287 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.mak 5 3/14/11 9:15p Madhans $
+#
+# $Revision: 5 $
+#
+# $Date: 3/14/11 9:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.mak $
+#
+# 5 3/14/11 9:15p Madhans
+# To contribute to CSPLib a function to know if DebugRx is connected or
+# Not connected.
+#
+# 4 9/30/09 8:00p Madhans
+# Updated for 1.31. Refer release notes.
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 6 7/16/09 6:35p Sudhirv
+# Updated the Path to avoid build errors with GENERIC_CABLE_SUPPORT
+#
+# 5 7/16/09 5:20p Madhans
+# Fix for Build error in Peidebugger Off
+#
+# 4 7/16/09 3:07p Madhans
+# To fix the Serial Debugger issuel and To do cleanup.
+#
+# 3 7/15/09 5:56p Madhans
+# X64 Support and clean up.
+#
+# 2 7/13/09 2:43p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 3 5/01/09 7:44p Madhans
+#
+# 2 4/30/09 8:52a Sudhirv
+# Added DummySerialIo for AMI Debug Rx
+#
+# 1 4/29/09 7:51a Sudhirv
+# AMI Debug Rx module created
+#
+# 15 12/12/08 5:13p Madhans
+# USB Redirecion Module.
+#
+# 13 5/21/08 12:26p Madhans
+# To Support New Status Code Lib changes.
+#
+# 12 10/26/07 5:03p Madhans
+# For 1.20.0011 Release
+#
+# 10 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 9 4/05/07 6:36p Madhans
+# Debugger 1.05.0005
+#
+# 8 3/12/07 6:19p Madhans
+# !!!coding standards!!!!
+#
+# 7 3/10/07 2:36p Madhans
+# For 1.05.binary Release.
+#
+# 6 2/28/07 7:57p Madhans
+# Dbgrhelp.obj kept as source.
+#
+# 5 1/25/07 10:33a Madhans
+# PLATFORM_DIR symbol name canged to _DBG_PLATFORM_DIR as it confilicts
+# with SantaROSA.
+#
+# 4 1/22/07 4:46p Madhans
+# Fixed the build issue.
+#
+# 3 1/22/07 4:14p Madhans
+# 1.04.0002 Binary Version.
+#
+# 7 1/05/07 1:05p Ashrafj
+# Latest version 1.04.0001 Beta
+# Known issues from previous 1.04.000 Beta release has been fixed.
+#
+# 6 12/26/06 7:07p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+# 5 6/30/06 12:12p Ashrafj
+# Modified to support the redirection of StatusCode debug messages
+# through DXE debugger, which was previously possible only if PEI Debug
+# support is enabled.
+# The PeiDbgStatusCodeLib component's ELINK is now enabled for DXE
+# debugger, without PEI Debug support. This means that StatusCode
+# messages will not cross over the wire until DXE debugger gets control
+# of the target.
+#
+# 4 6/14/06 7:33p Ashrafj
+# Minor build error fix - added dependency of AMIDXELIB
+#
+# 3 3/15/06 7:41p Ashrafj
+# Modfication done to provide the Binary integration for Aptio 4
+# projects.
+#
+# 2 10/20/05 10:07a Felixp
+# missing dependencies added
+#
+# 1 10/19/05 10:54a Felixp
+#
+# 1 10/19/05 10:44a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgStatusCodeLib.mak
+#
+# Description: Makefile of pei debugger status code lib
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+STSCODELIB_CFLAGS = /DALASKA_SUPPORT /I $(AMI_DebugRx_DIR)\binaries\PeiAMIDebugRx\INC
+
+BUILD_DBGSTATUSCODE_DIR=$(BUILD_DIR)\$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib
+
+!IF "$(x64_BUILD)"=="1"
+_DBG_PLATFORM_DIR=x64
+!ELSE
+_DBG_PLATFORM_DIR=ia32
+!ENDIF
+
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+!IF "$(PeiDebugger_SUPPORT)"=="1"
+DBGSTATUSCODE_OBJS= \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\PeiDbgStatusCode.obj \
+$(BUILD_DBGSTATUSCODE_DIR)\DbgrHelp.obj \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\GetDbgInterfaceDxe.obj \
+!IF "$(CONSOLE_REDIRECTION_SUPPORT)" != "1" || "$(REDIRECTION_ONLY_MODE)" != "1"
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\DummyAmiSerialIO.obj
+!ENDIF
+
+IA32_DBGSTATUSCODE_OBJS= \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\IA32\PeiDbgStatusCode.obj \
+$(BUILD_DIR)\IA32\$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\DbgrHelp.obj \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\IA32\GetDbgInterfacePei.obj
+
+!ELSE
+DBGSTATUSCODE_OBJS= \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\AMIDbgPortStatusCodeDxe.obj\
+!IF "$(CONSOLE_REDIRECTION_SUPPORT)" != "1" || "$(REDIRECTION_ONLY_MODE)" != "1"
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\DummyAmiSerialIO.obj
+!ENDIF
+
+IA32_DBGSTATUSCODE_OBJS= \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\IA32\AMIDbgPortStatusCodePei.obj \
+!ENDIF
+
+!ELSE
+DBGSTATUSCODE_OBJS= \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\PeiDbgStatusCode.obj \
+$(BUILD_DBGSTATUSCODE_DIR)\DbgrHelp.obj \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\GetDbgInterfaceDxe.obj \
+!IF "$(CONSOLE_REDIRECTION_SUPPORT)" != "1" || "$(REDIRECTION_ONLY_MODE)" != "1"
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\$(_DBG_PLATFORM_DIR)\DummyAmiSerialIO.obj
+!ENDIF
+
+IA32_DBGSTATUSCODE_OBJS= \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\IA32\PeiDbgStatusCode.obj \
+$(BUILD_DIR)\IA32\$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\DbgrHelp.obj \
+$(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\IA32\GetDbgInterfacePei.obj
+!ENDIF
+
+PeiDbgStatusCodeLib : $(BUILD_DIR)\PeiDbgStatusCodeLibBin.mak PeiDbgStatusCodeLibBin DxeDbgStatusCodeLibBin
+
+$(BUILD_DIR)\PeiDbgStatusCodeLibBin.mak : $(PeiDbgStatusCodeLib_DIR)\PeiDbgStatusCodeLibBin.cif $(PeiDbgStatusCodeLib_DIR)\PeiDbgStatusCodeLib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDbgStatusCodeLib_DIR)\PeiDbgStatusCodeLibBin.cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(x64_BUILD)"!="1"
+
+PEIDBGSTATUSCODELIB = $(BUILD_DIR)\PeiDbgStatusCodeLib.lib
+
+PEIDBGSTATUSCODEPEILIB = $(BUILD_DIR)\PeiDbgStatusCodePeiLib.lib
+
+StatusCodeBin : $(PEIDBGSTATUSCODELIB) $(AMIDXELIB)
+StatusCodePeiBin: $(PEIDBGSTATUSCODEPEILIB)
+StatusCodeDxeBin: $(PEIDBGSTATUSCODELIB)
+
+CORE_DXEBin: $(PEIDBGSTATUSCODELIB) $(AMIDXELIB)
+
+$(PEIDBGSTATUSCODELIB) $(PEIDBGSTATUSCODEPEILIB) : PeiDbgStatusCodeLib
+
+PeiDbgStatusCodeLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgStatusCodeLibBin.mak all\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(PEIDBGSTATUSCODEPEILIB)\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "OBJECTS=$(IA32_DBGSTATUSCODE_OBJS)"\
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT /DPEIDBG_BUILD_ONLY $(STSCODELIB_CFLAGS)"
+
+DxeDbgStatusCodeLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgStatusCodeLibBin.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(PEIDBGSTATUSCODELIB)\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "OBJECTS=$(DBGSTATUSCODE_OBJS)"\
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT $(STSCODELIB_CFLAGS)"
+
+
+!ELSE
+
+PEIDBGSTATUSCODELIB = $(BUILD_DIR)\PeiDbgStatusCodeLib.lib
+PEIDBGSTATUSCODELIBX64 = $(BUILD_DIR)\PeiDbgStatusCodeLibX64.lib
+
+StatusCodeBin : $(PEIDBGSTATUSCODELIB)
+StatusCodeBin : $(PEIDBGSTATUSCODELIBX64)
+StatusCodePeiBin : $(PEIDBGSTATUSCODELIB)
+StatusCodeDxeBin: $(PEIDBGSTATUSCODELIBX64)
+
+$(PEIDBGSTATUSCODELIB) $(PEIDBGSTATUSCODELIBX64) : PeiDbgStatusCodeLib
+
+PeiDbgStatusCodeLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgStatusCodeLibBin.mak all\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(PEIDBGSTATUSCODELIB)\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "OBJECTS=$(IA32_DBGSTATUSCODE_OBJS)"\
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT /DPEIDBG_BUILD_ONLY $(STSCODELIB_CFLAGS)"
+
+DxeDbgStatusCodeLibBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgStatusCodeLibBin.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(PEIDBGSTATUSCODELIBX64)\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "OBJECTS=$(DBGSTATUSCODE_OBJS)"\
+ "CFLAGS = $(CFLAGS) /DALASKA_SUPPORT $(STSCODELIB_CFLAGS)"
+
+!ENDIF
+
+AMICSPLibBin : $(BUILD_DIR)\HostConStatus.obj
+$(BUILD_DIR)\HostConStatus.obj : $(BUILD_DIR)\Token.mak $(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\HostConStatus.c
+ $(CC) $(C_FLAGS) $(STSCODELIB_CFLAGS) /DALASKA_SUPPORT /c $(PeiDbgStatusCodeLib_DIR)\StatusCodeLib\HostConStatus.c /Fo$@ /FR$(@R).SBR
+
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.sdl b/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.sdl
new file mode 100644
index 0000000..c4dafba
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLib.sdl
@@ -0,0 +1,49 @@
+PATH
+ Name = "PeiDbgStatusCodeLib_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgStatusCodeLib.mak to Project"
+ File = "PeiDbgStatusCodeLib.mak"
+End
+
+# (EIP 54793)>
+ELINK
+ Name = "PeiDbgrSendDebugText,"
+ Parent = "ReportStringStatus"
+ InvokeOrder = AfterParent
+ Token = "SEND_DEBUG_MESSAGE_SUPPORT" "=" "1"
+End
+# (EIP 54793)>
+
+ELINK
+ Name = "PeiDbgrSendCheckPoint,"
+ Parent = "ReportSimpleStatus"
+ InvokeOrder = AfterParent
+ Token = "SEND_CHECKPOINT_SUPPORT" "=" "1"
+End
+
+
+ELINK
+ Name = "PeiDbgrSendProgressCode,"
+ Parent = "ReportCheckpoint"
+ InvokeOrder = AfterParent
+ Token = "SEND_CHECKPOINT_SUPPORT" "=" "1"
+ Token = "STATUS_CODE_VERSION" ">=" "15"
+End
+
+
+ELINK
+ Name = " "
+ Parent = "PeiDbgrSendCheckPoint,"
+ InvokeOrder = ReplaceParent
+ Token = "STATUS_CODE_VERSION" ">=" "15"
+ Token = "SEND_CHECKPOINT_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "PeiDbgStatusToDBGMsg,"
+ Parent = "ReportSimpleStatus"
+ InvokeOrder = AfterParent
+ Token = "SEND_DEBUG_MESSAGE_SUPPORT" "=" "1"
+End
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLibBin.cif b/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLibBin.cif
new file mode 100644
index 0000000..493510f
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/PeiDbgStatusCodeLibBin.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PeiDbgStatusCodeLibBin"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\LIBS\"
+ RefName = "PeiDbgStatusCodeLibBin"
+[files]
+"PeiDbgStatusCodeLib.sdl"
+"PeiDbgStatusCodeLib.mak"
+"StatusCodeLib\DbgrHelp.c"
+"StatusCodeLib\HostConStatus.c"
+[parts]
+"StsCodeObjsIa32Rx"
+"StsCodeObjsx64Rx"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/DbgrHelp.c b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/DbgrHelp.c
new file mode 100644
index 0000000..7d75b33
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/DbgrHelp.c
@@ -0,0 +1,260 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/StatusCodeLib/DbgrHelp.c 5 3/17/11 7:54a Sudhirv $
+//
+// $Revision: 5 $
+//
+// $Date: 3/17/11 7:54a $
+//*****************************************************************
+//*****************************************************************
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/StatusCodeLib/DbgrHelp.c $
+//
+// 5 3/17/11 7:54a Sudhirv
+// Support to Boot with S3 Resume in Core_4.6.5.0
+//
+// 4 3/11/11 8:41a Sudhirv
+// Added support to return Database Address correctly with Cores older
+// than 4.6.4x
+//
+// 3 3/09/11 8:18a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 4 7/16/09 3:07p Madhans
+// To fix the Serial Debugger issuel and To do cleanup.
+//
+// 3 7/15/09 5:56p Madhans
+// Release mode binaries. With S3 resume Off.
+//
+// 2 7/13/09 2:46p Sudhirv
+// Update with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:51a Sudhirv
+// AMI Debug Rx module created
+//
+// 13 12/12/08 5:14p Madhans
+// USB Redirecion Module.
+//
+// 11 6/26/08 3:09p Sudhirv
+// Uploaded after checking coding standards
+//
+// 10 8/29/07 3:49p Madhans
+// To resolve AMD Platfrom issues.
+//
+// 9 8/29/07 12:44p Madhans
+// Common code for 4.x and 3.x
+//
+// 8 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 7 3/12/07 6:19p Madhans
+// !!!coding standards!!!!
+//
+// 6 3/10/07 2:22p Madhans
+// For non PEI debuggers it should return 0.
+//
+// 5 3/01/07 10:44a Madhans
+// token.h included
+//
+// 4 1/22/07 11:36a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 3 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//*****************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DbgrHelp.c
+//
+// Description: File containing the globals for CAR base address & size.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <EFI.h>
+#include <AmiPeiLib.h>
+
+#include "misc.h"
+#include "AMIPeiDebug.h"
+#ifdef ALASKA_SUPPORT
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+
+//**********************************************************************
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = 0;
+UINTN AMI_PEIDEBUGGER_DS_SIZE = 0x2048;
+#else
+const UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = PEI_DEBUG_DATASECTION_BASEADDRESS;
+const UINTN AMI_PEIDEBUGGER_DS_SIZE = PEI_DEBUG_DATASECTION_SIZE;
+#endif
+volatile UINT16 gS3ResumeSupport = AMI_DEBUG_RX_IN_S3_SUPPORT;
+
+VOID CPULib_SaveIdt(DESCRIPTOR_TABLE);
+
+UINTN GetCARBaseAddress()
+{
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+ EFI_PEI_SERVICES **PeiServices;
+ VOID *PeiDbgData;
+ EFI_GUID mPeiDbgBasePpiGuid = EFI_PEI_DBG_BASEADDRESS_PPI_GUID;
+ EFI_STATUS Status;
+ IDTBASE Idtr;
+
+#ifndef EFIx64
+ _asm{
+ sidt fword ptr Idtr
+ }
+#else
+ CPULib_SaveIdt(&Idtr);
+#endif
+ PeiServices = (EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.IDTBaseAddr - sizeof (UINTN)));
+
+ if (PeiServices == NULL)
+ return (Idtr.IDTBaseAddr); //Point to the area after PEI Services
+ else
+ {
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &mPeiDbgBasePpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiDbgData // PPI
+ );
+ if (!EFI_ERROR(Status))
+ return *((UINTN*)PeiDbgData);
+ else
+ return (Idtr.IDTBaseAddr);
+ }
+#else
+ return AMI_PEIDEBUGGER_DS_BASEADDRESS;
+#endif
+
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsAmiDbgrBaseValid
+//
+// Description: It is a function that helps to behave the status
+// code redirection through debugger differently
+// based in SDL tokens in different cases.
+//
+// Input: void
+//
+// Output: UINT8
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 IsAmiDbgrBaseValid(void)
+{
+
+#if REDIRECTION_ONLY_MODE
+ return 1;
+#else
+#ifndef AMI_PEI_DEBUG_SUPPORT
+ return 0;
+#else
+// if PEI Debugger is enabled
+#ifdef EFIx64
+ return 0;
+#else
+ IDTBASE Idtr;
+ _asm{
+ sidt fword ptr Idtr
+ }
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+ // Doubtful code recheck again
+ if(Idtr.IDTBaseAddr != NULL)
+#else
+ if(Idtr.IDTBaseAddr == AMI_PEIDEBUGGER_DS_BASEADDRESS)
+#endif
+ return 1;
+ else
+ return 0;
+#endif
+#endif
+#endif
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsBsp()
+//
+// Description:
+//
+// Input: void
+//
+// Output: UINT8
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 IsBsp(void)
+{
+#ifdef EFIx64
+ return 1;
+#else
+ UINT8 IsBsp = 1;
+#define MSR_XAPIC_BASE 0x1B
+#define XAPIC_BASE_BSP_BIT 8
+#define XAPIC_BASE_BSP_BIT_MASK (1 << XAPIC_BASE_BSP_BIT)
+ _asm
+ {
+ mov ecx,MSR_XAPIC_BASE
+ rdmsr
+ and eax,0x100
+ cmp eax,0x100
+ je BSP
+ mov IsBsp,0
+BSP:
+ }
+ return IsBsp;
+#endif
+}
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/HostConStatus.c b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/HostConStatus.c
new file mode 100644
index 0000000..d782224
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/HostConStatus.c
@@ -0,0 +1,213 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/StatusCodeLib/HostConStatus.c 2 4/15/11 7:09p Madhans $
+//
+// $Revision: 2 $
+//
+// $Date: 4/15/11 7:09p $
+//
+//*********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/StatusCodeLib/HostConStatus.c $
+//
+// 2 4/15/11 7:09p Madhans
+// [TAG] EIP58122
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] IsAMIDebugRxConnected() CSPLIB function used in PEI gives
+// build issues.
+// [RootCause] IsAMIDebugRxConnected in PEI case code is incomplete.
+// [Solution] IsAMIDebugRxConnected fixed.
+// [Files] HostConStatus.c
+//
+// 1 3/14/11 9:13p Madhans
+// To contribute CSPLib tO check if DebugRx is connected or Not.
+//
+//*********************************************************************
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HostConStatus.C
+//
+// Description: Checks whether the target is connected with host or not.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "efi.h"
+#include "pei.h"
+#include "amidxelib.h"
+#include "Hob.h"
+#ifndef EFIx64
+#include "AMIPeiDebug.h"
+#else
+#include "AMIPeiDebugX64.h"
+#endif
+
+
+BOOLEAN CheckForHostConnectedinPEI (EFI_PEI_SERVICES **PeiServices);
+#define PEI_DBGSUPPORT_DATA_GUID \
+ {0x41cac730, 0xe64e, 0x463b, 0x89, 0x72, 0x25, 0x5e, 0xec, 0x55, 0x55, 0xc2}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetEfiConfigurationTableLocal
+//
+// Description: Gets the efi configuration table
+//
+// Input: EFI_SYSTEM_TABLE *, EFI_GUID *
+//
+// Output: void *
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * GetEfiConfigurationTableLocal(
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_GUID *Guid
+ )
+{
+ EFI_CONFIGURATION_TABLE *Table = SystemTable->ConfigurationTable;
+ UINTN i = SystemTable->NumberOfTableEntries;
+
+ for (;i;--i,++Table)
+ {
+ if (guidcmp(&Table->VendorGuid,Guid)==0) return Table->VendorTable;
+ }
+ return 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsAMIDebugRxConnected
+//
+// Description: checks whether the target is connected with host or not.
+//
+// Input: EFI_PEI_SERVICES **, EFI_SYSTEM_TABLE *
+//
+// Output: BOOLEAN
+// TRUE: If host is connected
+// FALSE : If host is not connected
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsAMIDebugRxConnected (EFI_PEI_SERVICES **PeiServices, EFI_SYSTEM_TABLE *ST)
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ BOOLEAN RetStatus = FALSE;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID mPeiDebugDataGuid = PEI_DBGSUPPORT_DATA_GUID;
+ EFI_HOB_MEMORY_ALLOCATION *MemoryHob = NULL;
+ PEIDebugData_T *pPeiDbgDataSection;
+ EFI_PHYSICAL_ADDRESS DSMemoryBaseAddress = 0;
+ SerXPortGblData_T *pSerXPortGblData_T = NULL;
+
+ if (PeiServices == NULL) //For DXE check
+ {
+ MemoryHob = (EFI_HOB_MEMORY_ALLOCATION*)GetEfiConfigurationTableLocal (ST,&HobListGuid);
+ if (MemoryHob)
+ {
+ //Status = FindNextHobByGuid(&mPeiDebugDataGuid,(VOID**)&MemoryHob);
+ for(;;){
+ Status = FindNextHobByType (EFI_HOB_TYPE_MEMORY_ALLOCATION,&MemoryHob);
+ if (EFI_ERROR(Status)) break;
+ if (!guidcmp(&MemoryHob->AllocDescriptor.Name,&mPeiDebugDataGuid)) {
+ DSMemoryBaseAddress = MemoryHob->AllocDescriptor.MemoryBaseAddress;
+ pPeiDbgDataSection = (PEIDebugData_T*) DSMemoryBaseAddress;
+ pSerXPortGblData_T = (SerXPortGblData_T *)pPeiDbgDataSection->XportLocalVar;
+ if (pSerXPortGblData_T->m_IsHostConnected)
+ {
+ RetStatus = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+ else //For PEI Check
+ {
+ RetStatus = CheckForHostConnectedinPEI (PeiServices);
+ }
+ return RetStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForHostConnectedinPEI
+//
+// Description: checks whether the target is connected with host in PEI
+//
+// Input: void
+//
+// Output: BOOLEAN
+// TRUE: If host is connected
+// FALSE : If host is not connected
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CheckForHostConnectedinPEI (EFI_PEI_SERVICES **PeiServices)
+{
+ PEIDebugData_T *pData;
+ SerXPortGblData_T *SerData;
+ VOID *FirstHob = NULL;
+ EFI_HOB_MEMORY_ALLOCATION *Hob = NULL;
+ EFI_GUID mPeiDebugDataGuid = PEI_DBGSUPPORT_DATA_GUID;
+
+ //Find PEI Debugger Data section by HOB
+ for((*PeiServices)->GetHobList(PeiServices,&FirstHob);
+ !EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_MEMORY_ALLOCATION,&FirstHob));
+ )
+ {
+ Hob = (EFI_HOB_MEMORY_ALLOCATION *) FirstHob;
+
+ if (guidcmp (&mPeiDebugDataGuid, &Hob->AllocDescriptor.Name) == 0) {
+ pData = (PEIDebugData_T *)Hob->AllocDescriptor.MemoryBaseAddress;
+ break;
+ }
+ }
+ if(pData == NULL)
+ return FALSE;
+
+ SerData = (SerXPortGblData_T *)(pData->XportLocalVar);
+
+ if(SerData->m_IsHostConnected)
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************// \ No newline at end of file
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodeDxe.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodeDxe.obj
new file mode 100644
index 0000000..97f4622
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodeDxe.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodePei.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodePei.obj
new file mode 100644
index 0000000..4f01b7d
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/AMIDbgPortStatusCodePei.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/DummyAmiSerialIO.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/DummyAmiSerialIO.obj
new file mode 100644
index 0000000..e89056e
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/DummyAmiSerialIO.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfaceDxe.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfaceDxe.obj
new file mode 100644
index 0000000..f6e3ddc
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfaceDxe.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfacePei.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfacePei.obj
new file mode 100644
index 0000000..9cf6a2f
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/GetDbgInterfacePei.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/PeiDbgStatusCode.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/PeiDbgStatusCode.obj
new file mode 100644
index 0000000..fae0606
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/PeiDbgStatusCode.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/StsCodeObjsIA32Rx.cif b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/StsCodeObjsIA32Rx.cif
new file mode 100644
index 0000000..0bdcb20
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/ia32/StsCodeObjsIA32Rx.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "StsCodeObjsIa32Rx"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\LIBS\StatusCodeLib\ia32"
+ RefName = "StsCodeObjsIa32Rx"
+[files]
+"PeiDbgStatusCode.obj"
+"GetDbgInterfaceDxe.obj"
+"GetDbgInterfacePei.obj"
+"DummyAmiSerialIO.obj"
+"AMIDbgPortStatusCodePei.obj"
+"AMIDbgPortStatusCodeDxe.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodeDxe.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodeDxe.obj
new file mode 100644
index 0000000..960321c
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodeDxe.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodePei.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodePei.obj
new file mode 100644
index 0000000..e1d01bf
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/AMIDbgPortStatusCodePei.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/DummyAmiSerialIO.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/DummyAmiSerialIO.obj
new file mode 100644
index 0000000..02fac5f
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/DummyAmiSerialIO.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/GetDbgInterfaceDxe.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/GetDbgInterfaceDxe.obj
new file mode 100644
index 0000000..015cc2f
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/GetDbgInterfaceDxe.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/PeiDbgStatusCode.obj b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/PeiDbgStatusCode.obj
new file mode 100644
index 0000000..01a5ccc
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/PeiDbgStatusCode.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/StsCodeObjsx64Rx.cif b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/StsCodeObjsx64Rx.cif
new file mode 100644
index 0000000..e10ed22
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/StatusCodeLib/x64/StsCodeObjsx64Rx.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "StsCodeObjsx64Rx"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\LIBS\StatusCodeLib\x64"
+ RefName = "StsCodeObjsx64Rx"
+[files]
+"PeiDbgStatusCode.obj"
+"GetDbgInterfaceDxe.obj"
+"DummyAmiSerialIO.obj"
+"AMIDbgPortStatusCodePei.obj"
+"AMIDbgPortStatusCodeDxe.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/LIBS/UsbCableSelect.c b/Core/EM/AMIDebugRx/binaries/LIBS/UsbCableSelect.c
new file mode 100644
index 0000000..d67bec5
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/LIBS/UsbCableSelect.c
@@ -0,0 +1,180 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/UsbCableSelect.c 3 9/29/11 3:21p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 9/29/11 3:21p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/LIBS/UsbCableSelect.c $
+//
+// 3 9/29/11 3:21p Madhans
+// File revision # 2 Comments corrected.
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:43p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:51a Sudhirv
+// AMI Debug Rx module created
+//
+// 8 3/27/09 8:24a Sudhirv
+// Updated Coding Standards.
+//
+// 7 8/29/07 12:45p Madhans
+// Common code for 4.x and 3.x
+//
+// 6 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 5 1/22/07 11:36a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 3 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+// 2 9/21/06 6:40p Ashrafj
+// Remove the specific changes made previously to support for the USB File transfer
+// Cable, which was provided by means of SDL token support
+// and instead provided the USB Device Request command interface to the
+// DbgrUsbCableSelectLib, so any new cables support can be added through
+// this library.
+//
+// 1 9/13/06 6:54p Ashrafj
+// New Usb Cable support (Multi-LinQ Usb 2.0 cable) added. The usage of
+// this cable is based on new SDL token named USE_ALI_5632_CTRL_USB2_CABLE is
+// added, along with new library named DbgrUsbCableSelectLib. This library
+// is common for both PEI and DXE Transport modules to select between 2
+// USB cables.
+//
+//*****************************************************************
+
+//<AMI_FHDR_START>
+//--------------------------------------------------------------------
+//
+// Name: UsbCableSelect.c
+//
+// Description: DbgrUsbCableSelectLib library source file.
+//
+//--------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//--------------------------------------------------------------------
+#include <Efi.h>
+#ifdef ALASKA_SUPPORT
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+//--------------------------------------------------------------------
+//
+// The following functions are from the USB Transport module, to INIT USB
+// Cable Device.
+//
+EFI_STATUS InitUsb2DebugCableDevice();
+EFI_STATUS SetFeature(UINT16 FeatureSelector);
+EFI_STATUS SetAddress(UINT8 Addr);
+EFI_STATUS SetConfiguration(UINT16 ConfigValue);
+void UpdateBulkTransferEndpoints(UINT8 InEndpoint, UINT8 OutEndpoint);
+//--------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: Init_ALi5632Ctrl_Usb2Cable
+//
+// Description: Sets ALi 5632 Controller USB Cable device address
+// and issues configuration commands.
+// This is left as an example for porting engineer.
+//
+// Input: UINT8 Addr
+//
+// Output: EFI_STATUS
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if USE_ALI_5632_CTRL_USB2_CABLE
+
+EFI_STATUS Init_ALi5632Ctrl_Usb2Cable(UINT8 Addr)
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ Status = SetAddress(Addr);
+ if(Status == EFI_SUCCESS){
+
+ Status = SetConfiguration(1);
+
+ //update the globals for bulk transfer endpoints
+ UpdateBulkTransferEndpoints(1,2);
+ }
+
+ return Status;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: InitUsbCableDevice()
+//
+// Description: To select between Usb 2.0 Debug Cable device or any
+// other OEM specific USB 2.0 USB cable like ALi 5632 Usb2.0 Cable.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitUsbCableDevice()
+{
+#if USE_ALI_5632_CTRL_USB2_CABLE
+ //
+ //This is just left as an example to porting Engineer
+ //
+ return Init_ALi5632Ctrl_Usb2Cable(MULTI_LINQ_USB2_DEVICE_ADDRESS);
+#else
+ return InitUsb2DebugCableDevice();
+#endif
+}
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/DbgrHdr.c b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/DbgrHdr.c
new file mode 100644
index 0000000..d0b4a2e
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/DbgrHdr.c
@@ -0,0 +1,357 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/DbgrHdr.c 11 4/04/12 4:56p Sudhirv $
+//
+// $Revision: 11 $
+//
+// $Date: 4/04/12 4:56p $
+//*****************************************************************
+//*****************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/DbgrHdr.c $
+//
+// 11 4/04/12 4:56p Sudhirv
+// To Avoid Build errors in special cases.
+//
+// 10 4/03/12 4:43p Sudhirv
+// To avoid Build errors for redirection modes.
+//
+// 9 3/27/12 12:02p Sudhirv
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// 8 3/13/12 10:47a Sudhirv
+// [TAG] EIP60224
+// [Category] Improvement
+// [Description] Function implement When broken in SMM, show the register
+// context for 'outside' SMM.
+//
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// [TAG] EIP81423
+// [Category] Improvement
+// [Description] VeB Debugger - Improve the EFI tab's Handle Display
+// feature
+//
+// [TAG] EIP84201
+// [Category] Improvement
+// [Description] AMIDebugRx\Debugger Target modules usage of the Port 80
+// must be controlable
+//
+// 7 8/19/11 8:28p Sudhirv
+// Fix To get PCIExBaseaddress correctly for ReadPCI.
+//
+// 6 7/22/11 12:19p Sudhirv
+// [TAG] Compilation Error
+// [Description] To avoid Compilation errors in some Projects.
+// [Files] DbgrHdr.c
+//
+// 5 7/12/11 5:23p Sudhirv
+// [TAG] SMM Info
+// [Category] New Feature
+// [Description] To support send SMM Info to host
+//
+// 4 3/17/11 7:57a Sudhirv
+// Support to Boot with S3 Resume in Core_4.6.5.0
+//
+// 3 3/09/11 8:21a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:49p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 8 3/27/09 8:38a Sudhirv
+// Updated Coding Standards.
+//
+// 7 8/29/07 12:47p Madhans
+// Common code for 4.x and 3.x
+//
+// 6 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 5 2/27/07 5:01p Madhans
+//
+//*****************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DbgrHdr.c
+//
+// Description: File containing the globals for CAR base address & size.
+// Also the code which make use of this so that it can be
+// integrated as it is Debugger eModule of binary.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "pei.h"
+#include "misc.h"
+#include "AMIPeiDebug.h"
+//**********************************************************************
+#ifdef ALASKA_SUPPORT
+#define CAR_Start_Addr PEI_DEBUG_DATASECTION_BASEADDRESS // CAR Size = 8k
+#define CAR_End_Addr PEI_DEBUG_DATASECTION_BASEADDRESS + PEI_DEBUG_DATASECTION_SIZE
+#define Code_Start_Addr 0xffffffff - FLASH_SIZE
+#define Code_End_Addr 0xffffffff
+#else
+#define CAR_Start_Addr DATA_STACK_BASEADDRESS // CAR Size = 64k
+#define CAR_End_Addr (DATA_STACK_BASEADDRESS | 0x10000)
+#define Code_Start_Addr 0xffdfffff // Max BootBlock Size = 4Gig - 2MB
+#define Code_End_Addr 0xffffffff
+#endif
+
+#ifndef SW_SMI_IO_ADDRESS
+#define SW_SMI_IO_ADDRESS 0
+#endif
+#ifndef SMM_BASE_SAVE_STATE_OFFSET
+#define SMM_BASE_SAVE_STATE_OFFSET 0
+#endif
+#ifndef MAX_SMM_SAVE_STATE_SIZE
+#define MAX_SMM_SAVE_STATE_SIZE 0
+#endif
+#ifndef SMM_BSP_BASE
+#define SMM_BSP_BASE 0
+#endif
+#ifndef TSEG_SIZE
+#define TSEG_SIZE 0
+#endif
+#ifndef PCIEX_BASE_ADDRESS
+#define PCIEX_BASE_ADDRESS 0
+#endif
+#ifndef DYNAMIC_PCIEXBASE_SUPPORT
+#define DYNAMIC_PCIEXBASE_SUPPORT 0
+#endif
+#ifndef DBG_WRITE_IO_SUPPORT
+#define DBG_WRITE_IO_SUPPORT 0
+#endif
+#ifndef DBG_WRITE_IO_80_SUPPORT
+#define DBG_WRITE_IO_80_SUPPORT 0
+#endif
+
+//To support send SMM Info to host
+volatile UINT16 gSMIIOAddress = SW_SMI_IO_ADDRESS;
+volatile UINTN gSMMBaseSaveState = SMM_BASE_SAVE_STATE_OFFSET;
+volatile UINTN gSMMSaveStateSize = MAX_SMM_SAVE_STATE_SIZE;
+volatile UINTN gSMMBspBase = SMM_BSP_BASE;
+volatile UINTN gTsegSize = TSEG_SIZE;
+//**********************************************************************
+
+volatile UINTN gPCIEXBaseAddress = PCIEX_BASE_ADDRESS;
+
+//EIP 80406 - Debugger support for Dynamic pci express base token
+#ifdef DYNAMIC_PCIEXBASE_SUPPORT
+volatile UINTN gDynamicPCIExBase = DYNAMIC_PCIEXBASE_SUPPORT;
+#else
+volatile UINTN gDynamicPCIExBase = 0;
+#endif
+
+volatile UINTN gDbgWriteIOSupport = DBG_WRITE_IO_SUPPORT;
+volatile UINTN gDbgWriteIO80Support = DBG_WRITE_IO_80_SUPPORT;
+
+//**********************************************************************
+//<AMI_SHDR_START>
+//
+// Name: PeiDbgDataSection of type PEI_DBG_DATA_SECTION
+//
+// Description: The following global data structure is for relocation purpose
+// in order to support debugging after the debugger data section
+// is relocated. This second parameter of the data structure has
+// to be updated by the debugger service PEIM to point to relocated
+// data section into memory.The code section has this module
+// has to relocated before the update of second parameter.
+//
+//<AMI_SHDR_END>
+//**********************************************************************
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+PEI_DBG_DATA_SECTION PeiDbgDataSection = {
+ "DBGR",
+ 0 //This will be updated by debugger service PEIM
+}; //after the DBgr data section is relocated to memory from CAR
+#else
+PEI_DBG_DATA_SECTION PeiDbgDataSection = {
+ "DBGR",
+ PEI_DEBUG_DATASECTION_BASEADDRESS //This will be updated by debugger service PEIM
+}; //after the DBgr data section is relocated to memory from CAR
+
+#endif
+
+UINTN GetCARBaseAddress()
+{
+ EFI_PEI_SERVICES **PeiServices;
+ VOID *PeiDbgData;
+ EFI_GUID mPeiDbgBasePpiGuid = EFI_PEI_DBG_BASEADDRESS_PPI_GUID;
+ EFI_STATUS Status;
+
+ if((PeiDbgDataSection.DATABASEADDRESS)==NULL)
+ {
+ IDTBASE Idtr;
+ _asm{
+ sidt fword ptr Idtr
+ }
+ PeiServices = (EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.IDTBaseAddr - sizeof (UINTN)));
+
+ if (PeiServices == NULL)
+ return (Idtr.IDTBaseAddr); //Point to the area after PEI Services
+ else
+ {
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &mPeiDbgBasePpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiDbgData // PPI
+ );
+ if (!EFI_ERROR(Status))
+ return *((UINTN*)PeiDbgData);
+ else
+ return (Idtr.IDTBaseAddr);
+ }
+ }
+ else {
+ return((UINTN)PeiDbgDataSection.DATABASEADDRESS);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsDbgrInCAR
+//
+// Description: Internal Helper function.
+//
+// Input: none
+//
+// Output: 1 - yes or 0 - no (UINT32)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 IsDbgrInCAR()
+{
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+ if((PeiDbgDataSection.DATABASEADDRESS)==NULL)
+#else
+ if(PEI_DEBUG_DATA_BASEADDRESS == PEI_DEBUG_DATASECTION_BASEADDRESS)
+#endif
+ return 1; //yes
+ else
+ return 0; //no
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsAddrValidInCAR
+//
+// Description: Internal Helper function.
+//
+// Input: UINT64 Addr
+//
+// Output: 1 - TRUE OR 0 - FALSE (INTN)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN IsAddrValidInCAR (UINT64 Addr) {
+
+ if (Addr >= CAR_Start_Addr && Addr <= CAR_End_Addr)
+ return(1);
+ else
+ return(0);
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsAddrValidInCode
+//
+// Description: Internal Helper function.
+//
+// Input: UINT64 Addr
+//
+// Output: 1 OR 0 (INTN)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN IsAddrValidInCode (UINT64 Addr) {
+
+ if (Addr >= Code_Start_Addr && Addr <= Code_End_Addr)
+ return(1);
+ else
+ return(0);
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: Get_CAR_EndAddr
+//
+// Description: Internal Helper function.
+//
+// Input: none
+//
+// Output: CAR_End_Addr (UINTN)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN Get_CAR_EndAddr()
+{
+ return (CAR_End_Addr);
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: Get_Code_EndAddr
+//
+// Description: Internal Helper function.
+//
+// Input: none
+//
+// Output: Code_End_Addr (UINTN)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN Get_Code_EndAddr()
+{
+ return (Code_End_Addr);
+}
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/mindbgr.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/mindbgr.obj
new file mode 100644
index 0000000..6385bb0
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/DBGR/mindbgr.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/IDT/emptyidt.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/IDT/emptyidt.obj
new file mode 100644
index 0000000..f86c054
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/IDT/emptyidt.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebug.h b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebug.h
new file mode 100644
index 0000000..6bdb229
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebug.h
@@ -0,0 +1,469 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebug.h 6 3/16/11 4:43p Sudhirv $
+//
+// $Revision: 6 $
+//
+// $Date: 3/16/11 4:43p $
+//*****************************************************************
+//*****************************************************************
+//
+// peidebug.h
+//
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebug.h $
+//
+// 6 3/16/11 4:43p Sudhirv
+// Changes to Support Older Cores before 4.6.5.0
+//
+// 5 3/09/11 8:22a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 4 9/22/10 7:09p Sudhirv
+// 4.6.2_AMIDebugRx_2.01.0026_Beta Release
+//
+// 3 9/30/09 8:00p Madhans
+// Updated for 1.31. Refer release notes.
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:49p Sudhirv
+// Update with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 25 3/19/09 3:41p Sudhirv
+// Added After changes for Target Sending Exception Packets
+//
+// 23 1/30/09 12:32p Sudhirv
+// Added after Console Redirection Support
+//
+// 22 9/25/08 4:29p Sudhirv
+// Updated SMM Debugging and Read/Write Mem
+//
+// 21 7/29/08 1:09p Sudhirv
+// Changes made to support SMM debugging in savemem and loadmem
+// extension commands
+//
+// 20 6/26/08 3:30p Sudhirv
+// Uploaded after checking coding standards
+//
+// 19 6/11/08 2:24p Sudhirv
+// After Addibg GP Handling in MSR
+//
+// 18 6/11/08 5:46a Sudhirv
+// Uploaded for Release with Read/WriteMSR restriction, Readio/Writeio
+// restriction, Read/Write IndirectIO, ListModules and PciList
+//
+// 17 12/05/07 8:23a Sudhirv
+// Added to support and Restrict ReadMSR/WriteMSR commands
+//
+// 16 10/24/07 10:31a Madhans
+// Hatdriver Support.
+//
+// 15 8/29/07 3:49p Madhans
+// To resolve AMD Platfrom issues.
+//
+// 14 8/29/07 12:49p Madhans
+// Common code for 4.x and 3.x
+//
+// 13 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 12 6/13/07 2:37p Madhans
+// To improve the performance in Load FV though Serial.
+//
+// 11 6/05/07 7:10p Natalyak
+// Load FV support
+//
+// 10 4/05/07 6:33p Madhans
+// CAR_BASE_ADJUST_OFFSET removed.
+//
+// 9 3/10/07 1:24p Madhans
+// CAR_BASE_ADJUST_OFFSET allows to have PEI_SERVICES address above IDT
+//
+// 8 2/23/07 5:36p Madhans
+// PeiDbgr_SendPeiLoadImage function added.
+//
+// 7 1/22/07 11:41a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 11 1/05/07 6:15p Madhan
+//
+// 10 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+// 9 12/26/06 7:07p Ashrafj
+// Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+// Host.zip).
+// PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+// Support added for StatusCode redirection without Debug feature enabled
+// (not working if DXE only and x64 is enabled).
+// Plus, some new SDL tokens defined to support the Aptio 4.5 build
+// process in Debug or non-debug mode.
+// All the components of Debugger eModule in source form.
+//
+// 7 6/27/06 11:44a Ashrafj
+// New feature added:
+// To enable the PEI Debug support after system memory is installed, based
+// on build option provided through a new SDL token named
+// "PEI_DEBUG_SUPPORT_AFTER_MEMORY".
+//
+// 6 3/15/06 7:45p Ashrafj
+// Modfication done to provide the Binary integration for Aptio 4
+// projects.
+//
+// 5 12/22/05 12:42p Ashrafj
+// Changes done to support the complete Chipset template porting.
+//
+// To use this changes, make sure to have the latest Board components of
+// CPU, SB and SIO, which have the following ELINKS ported:
+// - SBPEIDBG_Initialize,
+// - CPUPEIDBG_Initialize,
+// - SIOPEIDBG_Initialize,
+// - SBPEIDBG_InitUsbEhci.
+//
+// 4 12/05/05 7:29p Ashrafj
+// Serial Port Debug Support added for PEI - DXE Debugger.
+//
+// Change in Serial Port Communication: Now the data transmission through
+// Serial Port is supported with the hardware Flow control feature of the
+// Serial Port controller.
+//
+// 3 11/29/05 6:07p Markw
+// Change USB interface function parameters.
+//
+// 2 10/25/05 11:38a Ashrafj
+// Minor fix - packed structure alignment and width size of global
+// variable.
+//
+// 1 10/19/05 10:54a Felixp
+//
+// 1 10/19/05 10:44a Felixp
+//
+//
+//
+//*****************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AMIPeiDebug.h
+//
+// Description: Contains 32 bit Pei Debugger prototypes
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _AMI_PEIDEBUG_H_
+#define _AMI_PEIDEBUG_H_
+
+#ifdef USB_DEBUGGER
+#include "EHCI.h"
+#endif
+
+#ifdef ALASKA_SUPPORT
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+
+#define EFI_PEI_DBG_BASEADDRESS_PPI_GUID \
+ { 0x9bf4e141, 0xa4ec, 0x4d72, {0xbc, 0xc4, 0x94, 0x2, 0x1d, 0x2b, 0x80, 0xbd }}
+
+#if defined (PI_SPECIFICATION_VERSION)
+#if PI_SPECIFICATION_VERSION>=0x00010000
+UINTN GetCARBaseAddress();
+#define PEI_DEBUG_DATASECTION_BASEADDRESS GetCARBaseAddress() //Starting address of PEI debugger data section
+#define PEI_DEBUG_DATASECTION_SIZE 0x2048
+
+#else //if PI_SPECIFICATION_VERSION >= 0x00010000
+#ifdef ALASKA_SUPPORT
+#define PEI_DEBUG_DATASECTION_BASEADDRESS CAR_BASE_ADDRESS //Starting address of PEI debugger data section
+#define PEI_DEBUG_DATASECTION_SIZE CAR_TOTAL_SIZE
+#else //ifdef ALASKA_SUPPORT
+#define PM_BASE_ADDRESS APLIB_PM_BASE_ADDRESS
+#define DATA_STACK_BASEADDRESS APLIB_CAR_BASEADDRESS
+#define PEI_DEBUG_DATASECTION_BASEADDRESS DATA_STACK_BASEADDRESS //Starting address of PEI debugger data section
+#define PEI_DEBUG_DATASECTION_SIZE 0x400
+#endif //ifdef ALASKA_SUPPORT
+
+#endif //if PI_SPECIFICATION_VERSION >= 0x00010000
+
+#else //if not defined (PI_SPECIFICATION_VERSION)
+#ifdef ALASKA_SUPPORT
+#define PEI_DEBUG_DATASECTION_BASEADDRESS CAR_BASE_ADDRESS //Starting address of PEI debugger data section
+#define PEI_DEBUG_DATASECTION_SIZE CAR_TOTAL_SIZE
+#else //ifdef ALASKA_SUPPORT
+#define PM_BASE_ADDRESS APLIB_PM_BASE_ADDRESS
+#define DATA_STACK_BASEADDRESS APLIB_CAR_BASEADDRESS
+#define PEI_DEBUG_DATASECTION_BASEADDRESS DATA_STACK_BASEADDRESS //Starting address of PEI debugger data section
+#define PEI_DEBUG_DATASECTION_SIZE 0x400
+#endif //ifdef ALASKA_SUPPORT
+
+#endif //if defined (PI_SPECIFICATION_VERSION)
+
+#define IRQ_VECTOR_BASE 0x8
+
+typedef struct {
+ UINT8 Signature[4];
+ UINT32 DATABASEADDRESS;
+}PEI_DBG_DATA_SECTION;
+
+#ifdef RELOCATE
+
+#if defined PI_SPECIFICATION_VERSION
+#if (PI_SPECIFICATION_VERSION >= 0x00010000)
+#define PEI_DEBUG_DATA_BASEADDRESS GetCARBaseAddress() //(PeiDbgDataSection.DATABASEADDRESS)
+#else
+extern PEI_DBG_DATA_SECTION PeiDbgDataSection;
+#define PEI_DEBUG_DATA_BASEADDRESS (PeiDbgDataSection.DATABASEADDRESS)
+#endif
+#else
+extern PEI_DBG_DATA_SECTION PeiDbgDataSection;
+#define PEI_DEBUG_DATA_BASEADDRESS (PeiDbgDataSection.DATABASEADDRESS)
+#endif
+
+#else
+#define PEI_DEBUG_DATA_BASEADDRESS PEI_DEBUG_DATASECTION_BASEADDRESS // Fixed Base Address
+#endif
+
+#define IDT_ENTRIES 0x14 // Number of Entries in IDT
+#define IDT_SIZE 0xa0 // Total Size = 160 Bytes
+#define CONTEXT_SIZE 0x74 // Total Size = 116 Bytes
+
+#define XPORTLOCALVAR_SIZE 0x48 // Total Size = 72 Bytes
+
+#define XPORTGLOBALVAR_SIZE 0x18 // Total Size = 24 Bytes
+//#define DBGRLOCALVAR_SIZE 0x2c // Total Size = 44 Bytes
+#define DBGRLOCALVAR_SIZE 0x36 // Total Size = 56 Bytes
+#define XPORTEXPTNBUF_SIZE 0x20 // Total Size = 32 Bytes
+
+//#define GLOBALBUF_SIZE 0x235 // Total Size = 565 Bytes
+#define GLOBALBUF_SIZE 0x210 // Total Size = 528 Bytes
+
+#define ACKBUF_SIZE 0x0a // Total Size = 10 Bytes
+
+
+
+#define PEI_DEBUG_IDTBASEADDR PEI_DEBUG_DATA_BASEADDRESS
+#define PEI_DEBUG_CONTEXTADDR PEI_DEBUG_DATA_BASEADDRESS + IDT_SIZE
+#define PEI_DEBUG_XPORTLOCALVARADDR PEI_DEBUG_CONTEXTADDR + CONTEXT_SIZE
+#define PEI_DEBUG_XPORTGLOBALVARADDR PEI_DEBUG_XPORTLOCALVARADDR + XPORTLOCALVAR_SIZE
+#define PEI_DEBUG_DBGRLOCALVARADDR PEI_DEBUG_XPORTGLOBALVARADDR + XPORTGLOBALVAR_SIZE
+#define PEI_DEBUG_XPORTEXPTNADDR PEI_DEBUG_DBGRLOCALVARADDR + DBGRLOCALVAR_SIZE
+#define PEI_DEBUG_BUFADDR PEI_DEBUG_XPORTEXPTNADDR + XPORTEXPTNBUF_SIZE
+#define PEI_DEBUG_ACKADDR PEI_DEBUG_BUFADDR + GLOBALBUF_SIZE
+
+#define IN_PEI_BEFORE_MEMORY 0
+#define IN_PEI_AFTER_MEMORY 01
+#define IN_DXE_WITH_PEI_DBGR 02
+#define IN_DXE_WITH_DXE_DBGR 03
+
+#pragma pack (push, pei_struct_data_pack, 1)
+
+typedef struct {
+ unsigned char IDTSet[IDT_SIZE];
+ unsigned char ContextReg[CONTEXT_SIZE];
+ unsigned char XportLocalVar[XPORTLOCALVAR_SIZE];
+ unsigned char XportGlobalVar[XPORTGLOBALVAR_SIZE];
+ unsigned char DbgrLocalVar[DBGRLOCALVAR_SIZE];
+ unsigned char XportExptn[XPORTEXPTNBUF_SIZE];
+ unsigned char GlobalBuf[GLOBALBUF_SIZE];
+ unsigned char AckBuf[ACKBUF_SIZE];
+} PEIDebugData_T;
+
+
+#pragma pack (pop, pei_struct_data_pack)
+
+
+typedef struct _AMI_PEI_TRANSPORT_PROTOCOL {
+ UINT8 Signature[4];
+ UINT16 (*Initialize)();
+ UINT16 (*Restore)();
+ UINT16 (*Send)();
+ UINT16 (*Receive)();
+ UINT16 (*SyncPacketNumber)();
+ UINT16 (*RegisterHandler)();
+ VOID (*Callback)();
+ UINT16 (*SendNoAck)();
+ EFI_STATUS (*ConsoleIn)();
+ VOID (*SendExptn)();
+} AMI_PEI_TRANSPORT_PROTOCOL;
+
+typedef struct{
+ UINT8 Signature[4];
+ VOID (*ExceptionCallback)();
+ VOID (*SendMessage)();
+ UINTN (*PeiDbgr_EnableDebugSupport)(UINTN BrkPtAddr);
+ UINTN (*PeiDbgr_SendPeiLoadImage)(UINTN FileHandle,UINTN ImageAddr,UINTN ImageSize,void * PDBFileName);
+ VOID (*DoSpecialBreakPoint)(UINT32 EaxValue,UINT32 EdxValue);
+}AMI_DEBUGGER_INTERFACE;
+
+#pragma pack(1)
+typedef struct {
+ UINT32 m_EIP;
+ UINT16 m_SendPktSize;
+ UINT8 m_CurSendPktNum;
+ UINT16 m_CurIxInRcvPkt;
+ UINT8 m_CurRcvPktNum;
+ UINT32 m_ExptnHndlr;
+ UINT8 m_IsSending;
+ UINT16 m_ExptnType;
+ UINT8 m_PrevByteEsc;
+ UINT8 m_RcvingPkt;
+ UINT8 m_RcvPktReady;
+ UINT16 m_RcvPktSize;
+ UINT8 m_IsPortInListenMode;
+ UINT8 m_IsHostConnected;
+ UINT8 m_IsPeiDbgIsS3;
+#ifndef USB_DEBUGGER
+ UINT16 m_BaseAddr;
+// UINT8 m_IsCOMPortInListenMode;
+// UINT32 m_ReadAttempts; //only for debugging purpose -remove later
+// UINT8 m_CacheRecvFIFO[24];
+// UINT8 m_CacheSize;
+// UINT8 m_CacheIndex;
+
+ //To obtain info from Porting template support, and use it to publish HOB
+ UINT8 m_SIO_LDN_UART; //Logical Device Number for COM port
+#else
+ UINT32 USBBASE;
+ UINT32 USB2_DEBUG_PORT_REGISTER_INTERFACE;
+ UINT8 gDebugUSBAddress;
+ UINT8 gDebugInEndpoint;
+ UINT8 gDebugOutEndpoint;
+ GET_DESCRIPTOR_DEBUG_PORT Descriptor;
+ UINT8 gUSBBulkTransferSetAddr;
+
+ UINT8 gIN_DATAPID;
+ UINT8 gOUT_DATAPID;
+
+ UINT8 gIN_DATABUFFER[8];
+ UINT8 gOUT_DATABUFFER[8];
+
+ UINT8 gCurrentINDataBufferLength;
+ UINT8 gCurrentINDataBufferIndex;
+ UINT8 gCurrentOUTDataBufferIndex;
+
+ UINT8 lastdata;
+
+ UINT8 gIsUsbDebugPortInUse;
+// UINT8 gIsUsbDebugPortInListenMode;
+
+ //To obtain info from Porting template support, and use it to publish HOB
+ UINT16 m_EHCI_MEMORY_SIZE;
+ UINT8 m_PCI_EHCI_BUS_NUMBER;
+ UINT8 m_PCI_EHCI_DEVICE_NUMBER;
+ UINT8 m_PCI_EHCI_FUNCTION_NUMBER;
+ UINT8 m_PCI_EHCI_BAR_OFFSET;
+#endif
+ UINT64 m_PeiDbgRxInitTimerVal;
+}SerXPortGblData_T;
+
+typedef struct {
+ AMI_PEI_TRANSPORT_PROTOCOL *gTransportProtocol;
+ UINT16 (*Handler)();
+
+ //Additional parameters added in order to support DXE phase callback of
+ //IRQ register handlers
+ UINTN InterruptType;
+ UINTN ContextData;
+ VOID (*IRQRegisterHandler)(UINTN,UINTN);
+
+#ifdef USB_DEBUGGER
+ //Additional interface for PeiDbgSIO module to reinit EHCI memory base
+// void (*PeiDbgSIO_Init_USB_EHCI)(UINTN PeiDbgData_BaseAddr,UINTN MMIO_BaseAddr);
+// void (*PeiDbgSIO_Init_USB_EHCI)(UINTN UsbBaseAddress, UINTN *Usb2DebugPortReg);
+ void (*PeiDbgSIO_Init_USB_EHCI)(VOID *);
+#endif
+}SerXPortGblVar_T;
+
+typedef struct {
+ UINT8 m_BrkPtType;
+ UINT16 m_CS;
+ UINT32 m_EIP;
+ UINT16 m_SS;
+ UINT32 m_ESP;
+ UINT32 m_DR2;
+ UINT32 m_DR7;
+ UINT8 m_TargetRunning;
+ UINT8 m_DbgrBusy;
+ UINT8 m_DR2Valid;
+
+ UINT8 m_GPOccrd;
+ UINT8 m_MSRState;
+
+ UINT8 m_NotifyAndBreak;
+
+ UINT16 m_DbgSendBufSize;
+ UINT16 m_DbgRcvBufSize;
+ VOID (*PeiDbgrReportStatusCode)();
+ UINT8 m_FlagToDebugAfterMemory;
+ UINTN (*PeiDbgr_EnableDebugSupport)(UINTN BrkPtAddr);
+ AMI_DEBUGGER_INTERFACE *pPeiDbgDbgrIfc;
+ UINT8 m_TargetState;
+ VOID* m_ppPeiSVC;
+ EFI_STATUS (*UpdateFVHob)();
+}DbgGblData_T;
+
+#pragma pack()
+
+#pragma pack(1)
+typedef struct {
+ UINT16 m_OffLow;
+ UINT16 m_SegSel;
+ UINT16 m_Reserved;
+ UINT16 m_OffHigh;
+}IDTEntry_T;
+
+typedef struct {
+ UINT16 IDTLength;
+ UINTN IDTBaseAddr; //should work for both 32 and 64 mode
+}IDTBASE;
+
+typedef UINT8 (DBG_IS_S3)(void);
+#pragma pack()
+
+void DriverSpecialBreakPoint(UINT32 EaxVal, UINT32 EdxVal);
+
+#endif
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebugX64.h b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebugX64.h
new file mode 100644
index 0000000..d3bc15f
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebugX64.h
@@ -0,0 +1,509 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebugX64.h 5 3/09/11 8:22a Sudhirv $
+//
+// $Revision: 5 $
+//
+// $Date: 3/09/11 8:22a $
+//*****************************************************************
+//*****************************************************************
+//
+// peidebug.h
+//
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/AMIpeidebugX64.h $
+//
+// 5 3/09/11 8:22a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 4 9/22/10 7:09p Sudhirv
+// 4.6.2_AMIDebugRx_2.01.0026_Beta Release
+//
+// 3 9/30/09 8:00p Madhans
+// Updated for 1.31. Refer release notes.
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:49p Sudhirv
+// Update with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 19 3/19/09 3:41p Sudhirv
+// Added After changes for Target Sending Exception Packets
+//
+// 17 1/30/09 12:32p Sudhirv
+// Added after Console Redirection Support
+//
+// 16 6/26/08 3:30p Sudhirv
+// Uploaded after checking coding standards
+//
+// 15 6/11/08 2:24p Sudhirv
+// After Addibg GP Handling in MSR
+//
+// 14 6/11/08 5:46a Sudhirv
+// Uploaded for Release with Read/WriteMSR restriction, Readio/Writeio
+// restriction, Read/Write IndirectIO, ListModules and PciList
+//
+// 13 12/05/07 8:23a Sudhirv
+// Added to support and Restrict ReadMSR/WriteMSR commands
+//
+// 12 10/24/07 10:31a Madhans
+// Hatdriver Support.
+//
+// 11 8/29/07 3:49p Madhans
+// To resolve AMD Platfrom issues.
+//
+// 10 8/29/07 12:49p Madhans
+// Common code for 4.x and 3.x
+//
+// 9 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 8 6/05/07 7:11p Natalyak
+// Load FV support
+//
+// 7 4/05/07 6:33p Madhans
+// CAR_BASE_ADJUST_OFFSET removed.
+//
+// 6 3/10/07 1:24p Madhans
+// CAR_BASE_ADJUST_OFFSET allows to have PEI_SERVICES address above IDT
+//
+// 5 2/23/07 5:37p Madhans
+// Changes made for LoadImag PPI/Protocol Notifications.
+//
+// 4 1/22/07 11:41a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+// 1 12/26/06 7:09p Ashrafj
+// Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+// Host.zip).
+// PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+// Support added for StatusCode redirection without Debug feature enabled
+// (not working if DXE only and x64 is enabled).
+// Plus, some new SDL tokens defined to support the Aptio 4.5 build
+// process in Debug or non-debug mode.
+// All the components of Debugger eModule in source form.
+//
+// 7 6/27/06 11:44a Ashrafj
+// New feature added:
+// To enable the PEI Debug support after system memory is installed, based
+// on build option provided through a new SDL token named
+// "PEI_DEBUG_SUPPORT_AFTER_MEMORY".
+//
+// 6 3/15/06 7:45p Ashrafj
+// Modfication done to provide the Binary integration for Aptio 4
+// projects.
+//
+// 5 12/22/05 12:42p Ashrafj
+// Changes done to support the complete Chipset template porting.
+//
+// To use this changes, make sure to have the latest Board components of
+// CPU, SB and SIO, which have the following ELINKS ported:
+// - SBPEIDBG_Initialize,
+// - CPUPEIDBG_Initialize,
+// - SIOPEIDBG_Initialize,
+// - SBPEIDBG_InitUsbEhci.
+//
+// 4 12/05/05 7:29p Ashrafj
+// Serial Port Debug Support added for PEI - DXE Debugger.
+//
+// Change in Serial Port Communication: Now the data transmission through
+// Serial Port is supported with the hardware Flow control feature of the
+// Serial Port controller.
+//
+// 3 11/29/05 6:07p Markw
+// Change USB interface function parameters.
+//
+// 2 10/25/05 11:38a Ashrafj
+// Minor fix - packed structure alignment and width size of global
+// variable.
+//
+// 1 10/19/05 10:54a Felixp
+//
+// 1 10/19/05 10:44a Felixp
+//
+//
+//
+//*****************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AmiPeiDebugx64.C
+//
+// Description: Contains X64 Pei Debugger prototypes
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _AMI_PEIDEBUGx64_H_
+#define _AMI_PEIDEBUGx64_H_
+
+#ifdef USB_DEBUGGER
+#include "EHCI.h"
+#endif
+
+#ifdef ALASKA_SUPPORT
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+
+#ifdef ALASKA_SUPPORT
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+//#define PEI_DEBUG_DATASECTION_BASEADDRESS CAR_BASE_ADDRESS //Starting address of PEI debugger data section
+#else
+#define PEI_DEBUG_DATASECTION_BASEADDRESS CAR_BASE_ADDRESS //Starting address of PEI debugger data section
+#endif
+#else
+
+#define PM_BASE_ADDRESS APLIB_PM_BASE_ADDRESS
+#define DATA_STACK_BASEADDRESS APLIB_CAR_BASEADDRESS
+
+#define PEI_DEBUG_DATASECTION_BASEADDRESS DATA_STACK_BASEADDRESS //Starting address of PEI debugger data section
+#endif
+
+
+#define PEI_DEBUG_DATASECTION_SIZEx64 \
+ (IDT_SIZEx64 + CONTEXT_SIZEx64 + XPORTLOCALVAR_SIZEx64 + XPORTGLOBALVAR_SIZEx64\
+ + DBGRLOCALVAR_SIZEx64 + XPORTEXPTNBUF_SIZEx64 + GLOBALBUF_SIZEx64 + ACKBUF_SIZEx64)
+
+#define IRQ_VECTOR_BASE 0x8
+
+typedef struct {
+ UINT8 Signature[4];
+ UINT32 DATABASEADDRESS;
+}PEI_DBG_DATA_SECTIONx64;
+
+#ifdef RELOCATE
+extern PEI_DBG_DATA_SECTIONx64 PeiDbgDataSection;
+#define PEI_DEBUG_DATA_BASEADDRESS (PeiDbgDataSection.DATABASEADDRESS)
+#else
+#define PEI_DEBUG_DATA_BASEADDRESS PEI_DEBUG_DATASECTION_BASEADDRESS // Fixed Base Address
+#endif
+
+#define IDT_ENTRIES 0x14 // Number of Entries in IDT
+#define IDT_SIZEx64 0x160 // Total Size = 352 Bytes
+#define CONTEXT_SIZEx64 0x140 // Total Size = 320 Bytes
+
+#define XPORTLOCALVAR_SIZEx64 0x50 // Total Size = 80 Bytes
+
+#define XPORTGLOBALVAR_SIZEx64 0x30 // Total Size = 48 Bytes
+//#define DBGRLOCALVAR_SIZEx64 0x50 // Total Size = 80 Bytes
+#define DBGRLOCALVAR_SIZEx64 0x62 // Total Size = 98 Bytes
+#define XPORTEXPTNBUF_SIZEx64 0x20 // Total Size = 32 Bytes
+
+#define GLOBALBUF_SIZEx64 0x235 // Total Size = 565 Bytes
+
+#define ACKBUF_SIZEx64 0x0a // Total Size = 10 Bytes
+
+
+
+#define PEI_DEBUG_IDTBASEADDRx64 PEI_DEBUG_DATA_BASEADDRESS
+#define PEI_DEBUG_CONTEXTADDRx64 PEI_DEBUG_DATA_BASEADDRESS + IDT_SIZEx64
+#define PEI_DEBUG_XPORTLOCALVARADDRx64 PEI_DEBUG_CONTEXTADDRx64 + CONTEXT_SIZEx64
+#define PEI_DEBUG_XPORTGLOBALVARADDRx64 PEI_DEBUG_XPORTLOCALVARADDRx64 + XPORTLOCALVAR_SIZEx64
+#define PEI_DEBUG_DBGRLOCALVARADDRx64 PEI_DEBUG_XPORTGLOBALVARADDRx64 + XPORTGLOBALVAR_SIZEx64
+#define PEI_DEBUG_XPORTEXPTNADDRx64 PEI_DEBUG_DBGRLOCALVARADDRx64 + DBGRLOCALVAR_SIZEx64
+#define PEI_DEBUG_BUFADDRx64 PEI_DEBUG_XPORTEXPTNADDRx64 + XPORTEXPTNBUF_SIZEx64
+#define PEI_DEBUG_ACKADDRx64 PEI_DEBUG_BUFADDRx64 + GLOBALBUF_SIZEx64
+
+
+#pragma pack (push, pei_struct_data_pack, 1)
+
+typedef struct {
+ unsigned char IDTSet[IDT_SIZEx64];
+ unsigned char ContextReg[CONTEXT_SIZEx64];
+ unsigned char XportLocalVar[XPORTLOCALVAR_SIZEx64];
+ unsigned char XportGlobalVar[XPORTGLOBALVAR_SIZEx64];
+ unsigned char DbgrLocalVar[DBGRLOCALVAR_SIZEx64];
+ unsigned char XportExptn[XPORTEXPTNBUF_SIZEx64];
+ unsigned char GlobalBuf[GLOBALBUF_SIZEx64];
+ unsigned char AckBuf[ACKBUF_SIZEx64];
+}PEIDebugData_Tx64;
+
+
+#pragma pack (pop, pei_struct_data_pack)
+
+
+#pragma pack(1)
+typedef struct {
+ UINT8 Signature[4];
+ UINT16 (*Initialize)();
+ UINT16 (*Restore)();
+ UINT16 (*Send)();
+ UINT16 (*Receive)();
+ UINT16 (*SyncPacketNumber)();
+ UINT16 (*RegisterHandler)();
+ VOID (*Callback)();
+ UINT16 (*SendNoAck)();
+ EFI_STATUS (*ConsoleIn)();
+ VOID (*SendExptn)();
+ VOID (*IrqHandler)(); //Not to be use as API by any other drivers
+} AMI_PEI_TRANSPORT_PROTOCOLx64;
+
+//typedef UINT32 GET_DESCRIPTOR_DEBUG_PORT;
+
+//#pragma pack(1)
+typedef struct {
+ UINT64 m_EIP;
+ UINT16 m_SendPktSize;
+ UINT8 m_CurSendPktNum;
+ UINT16 m_CurIxInRcvPkt;
+ UINT8 m_CurRcvPktNum;
+ UINT32 m_ExptnHndlr;
+ UINT8 m_IsSending;
+ UINT16 m_ExptnType;
+ UINT8 m_PrevByteEsc;
+ UINT8 m_RcvingPkt;
+ UINT8 m_RcvPktReady;
+ UINT16 m_RcvPktSize;
+ UINT8 m_IsPortInListenMode;
+ UINT8 m_IsHostConnected;
+ UINT8 m_IsPeiDbgIsS3;
+#ifndef USB_DEBUGGER
+ UINT16 m_BaseAddr;
+// UINT8 m_IsCOMPortInListenMode;
+// UINT32 m_ReadAttempts; //only for debugging purpose -remove later
+// UINT8 m_CacheRecvFIFO[24];
+// UINT8 m_CacheSize;
+// UINT8 m_CacheIndex;
+ //To obtain info from Porting template support, and use it to publish HOB
+ UINT8 m_SIO_LDN_UART; //Logical Device Number for COM port
+#else
+ UINT32 USBBASE;
+ UINT32 USB2_DEBUG_PORT_REGISTER_INTERFACE;
+ UINT8 gDebugUSBAddress;
+ UINT8 gDebugInEndpoint;
+ UINT8 gDebugOutEndpoint;
+ GET_DESCRIPTOR_DEBUG_PORT Descriptor;
+ UINT8 gUSBBulkTransferSetAddr;
+
+ UINT8 gIN_DATAPID;
+ UINT8 gOUT_DATAPID;
+
+ UINT8 gIN_DATABUFFER[8];
+ UINT8 gOUT_DATABUFFER[8];
+
+ UINT8 gCurrentINDataBufferLength;
+ UINT8 gCurrentINDataBufferIndex;
+ UINT8 gCurrentOUTDataBufferIndex;
+
+ UINT8 lastdata;
+
+ UINT8 gIsUsbDebugPortInUse;
+// UINT8 gIsUsbDebugPortInListenMode;
+
+ //To obtain info from Porting template support, and use it to publish HOB
+ UINT16 m_EHCI_MEMORY_SIZE;
+ UINT8 m_PCI_EHCI_BUS_NUMBER;
+ UINT8 m_PCI_EHCI_DEVICE_NUMBER;
+ UINT8 m_PCI_EHCI_FUNCTION_NUMBER;
+ UINT8 m_PCI_EHCI_BAR_OFFSET;
+#endif
+ UINT64 m_PeiDbgRxInitTimerVal;
+}SerXPortGblData_Tx64;
+
+typedef struct {
+ AMI_PEI_TRANSPORT_PROTOCOLx64 *gTransportProtocol;
+ UINT16 (*Handler)();
+
+ //Additional parameters added in order to support DXE phase callback of
+ //IRQ register handlers
+ UINTN InterruptType;
+ UINTN ContextData;
+ VOID (*IRQRegisterHandler)(UINTN,UINTN);
+
+#ifdef USB_DEBUGGER
+ //Additional interface for PeiDbgSIO module to reinit EHCI memory base
+// void (*PeiDbgSIO_Init_USB_EHCI)(UINTN PeiDbgData_BaseAddr,UINTN MMIO_BaseAddr);
+// void (*PeiDbgSIO_Init_USB_EHCI)(UINTN UsbBaseAddress, UINTN *Usb2DebugPortReg);
+ void (*PeiDbgSIO_Init_USB_EHCI)(VOID *);
+#endif
+}SerXPortGblVar_Tx64;
+
+typedef struct{
+ UINT8 Signature[4];
+ VOID (*ExceptionCallback)();
+ VOID (*SendMessage)();
+ UINTN (*PeiDbgr_EnableDebugSupport)(UINTN BrkPtAddr);
+ VOID (*INT1ExceptionHandler)(); //not to be use as API
+ VOID (*INT3ExceptionHandler)(); //not to be use as API
+ VOID (*INTnExceptionHandler)(); //not to be use as API
+ UINTN (*PeiDbgr_SendPeiLoadImage)(UINTN FileHandle,UINTN ImageAddr,UINTN ImageSize,void * PDBFileName);
+ VOID (*INTFExceptionHandler)(); //not to be use as API
+}AMI_DEBUGGER_INTERFACEx64;
+
+typedef struct {
+ UINT8 m_BrkPtType;
+ UINT16 m_CS;
+ UINT64 m_EIP;
+ UINT16 m_SS;
+ UINT64 m_ESP;
+ UINT64 m_DR2;
+ UINT64 m_DR7;
+ UINT8 m_TargetRunning;
+
+ UINT8 m_MSRState;
+ UINT8 m_GPOccrd;
+
+ UINT8 m_NotifyAndBreak;
+
+ UINT8 m_DbgrBusy;
+ UINT8 m_DR2Valid;
+ UINT16 m_DbgSendBufSize;
+ UINT16 m_DbgRcvBufSize;
+ UINT64 m_BackupDR7;
+ UINT8 m_PICMask;
+ union{
+ VOID (*PeiDbgrReportStatusCode)();
+ UINT64 res1;
+ };
+ UINT8 m_FlagToDebugAfterMemory;
+ union{
+ UINTN (*PeiDbgr_EnableDebugSupport)(UINTN BrkPtAddr);
+ UINT64 res2;
+ };
+ union{
+ AMI_DEBUGGER_INTERFACEx64 *pPeiDbgDbgrIfc;
+ UINT64 res3;
+ };
+ UINT8 m_TargetState;
+ VOID* m_ppPeiSVC;
+// VOID* m_pFVHob;
+ EFI_STATUS (*UpdateFVHob)();
+}DbgGblData_Tx64;
+//#pragma pack()
+
+//#pragma pack(1)
+typedef struct {
+ UINT16 m_OffLow;
+ UINT16 m_SegSel;
+ UINT16 m_Reserved;
+ UINT16 m_OffHigh;
+ UINT32 m_OffHighExt;
+ UINT32 m_Reserved2;
+}IDTEntry_Tx64;
+
+typedef struct {
+ UINT16 IDTLength;
+ UINT64 IDTBaseAddr; //should work for both 32 and 64 mode
+}IDTBASEx64;
+#pragma pack()
+
+//=========================================================================
+// Prototypes of structure definitions to be used handoff of 32 to 64 PEI
+// Debugger
+//=========================================================================
+#pragma pack(1)
+typedef struct {
+ UINT64 gTransportProtocol; //AMI_PEI_TRANSPORT_PROTOCOL *gTransportProtocol;
+ UINT64 Handler; //UINT16 (*Handler)();
+
+ //Additional parameters added in order to support DXE phase callback of
+ //IRQ register handlers
+ UINTN InterruptType;
+ UINTN ContextData;
+ UINT64 IRQRegisterHandler; //VOID (*IRQRegisterHandler)(UINTN,UINTN);
+
+#ifdef USB_DEBUGGER
+ UINT64 PeiDbgSIO_Init_USB_EHCI; //void (*PeiDbgSIO_Init_USB_EHCI)(VOID *);
+#endif
+}SerXPortGblVar_Tx64_Proto;
+
+typedef struct{
+ UINT8 Signature[4];
+ UINT64 pExceptionCallback; //VOID (*ExceptionCallback)();
+ UINT64 pSendMessage; //VOID (*SendMessage)();
+ UINT64 pPeiDbgr_EnableDebugSupport; //UINTN (*PeiDbgr_EnableDebugSupport)(UINTN BrkPtAddr);
+ UINT64 pINT1ExceptionHandler; //VOID (*INT1ExceptionHandler)();
+ UINT64 pINT3ExceptionHandler; //VOID (*INT3ExceptionHandler)();
+ UINT64 pINTnExceptionHandler; //VOID (*INTnExceptionHandler)();
+ UINT64 pPeiDbgr_SendPeiLoadImage; //UINTN (*PeiDbgr_SendPeiLoadImage)(UINTN FileHandle,UINTN ImageAddr,UINTN ImageSize,void * PDBFileName);
+ UINT64 pINTFExceptionHandler; //VOID (*INTFExceptionHandler)();
+}AMI_DEBUGGER_INTERFACEx64_Proto;
+
+typedef struct {
+ UINT8 Signature[4];
+ UINT64 pInitialize; //UINT16 (*Initialize)();
+ UINT64 pRestore; //UINT16 (*Restore)();
+ UINT64 pSend; //UINT16 (*Send)();
+ UINT64 pReceive; //UINT16 (*Receive)();
+ UINT64 pSyncPacketNumber; //UINT16 (*SyncPacketNumber)();
+ UINT64 pRegisterHandler; //UINT16 (*RegisterHandler)();
+ UINT64 pCallback; //VOID (*Callback)();
+ UINT64 pSendNoAck; //UINT16 (*SendNoAck)();
+ UINT64 pConsoleIn; // EFI_STATUS (*ConsoleIn)();
+ UINT64 pSendExptn; // VOID (*SendExptn)();
+ UINT64 pIrqHandler; //VOID (*IrqHandler)();
+} AMI_PEI_TRANSPORT_PROTOCOLx64__Proto;
+#pragma pack()
+
+#ifdef EFIx64
+typedef PEI_DBG_DATA_SECTIONx64 PEI_DBG_DATA_SECTION;
+typedef DbgGblData_Tx64 DbgGblData_T;
+typedef SerXPortGblData_Tx64 SerXPortGblData_T;
+typedef PEIDebugData_Tx64 PEIDebugData_T;
+typedef AMI_PEI_TRANSPORT_PROTOCOLx64 AMI_PEI_TRANSPORT_PROTOCOL;
+typedef SerXPortGblVar_Tx64 SerXPortGblVar_T;
+typedef AMI_DEBUGGER_INTERFACEx64 AMI_DEBUGGER_INTERFACE;
+typedef IDTEntry_Tx64 IDTEntry_T;
+typedef IDTBASEx64 IDTBASE;
+
+#define PEI_DEBUG_IDTBASEADDR PEI_DEBUG_IDTBASEADDRx64
+#define PEI_DEBUG_CONTEXTADDR PEI_DEBUG_CONTEXTADDRx64
+#define PEI_DEBUG_XPORTLOCALVARADDR PEI_DEBUG_XPORTLOCALVARADDRx64
+#define PEI_DEBUG_XPORTGLOBALVARADDR PEI_DEBUG_XPORTGLOBALVARADDRx64
+#define PEI_DEBUG_DBGRLOCALVARADDR PEI_DEBUG_DBGRLOCALVARADDRx64
+#define PEI_DEBUG_XPORTEXPTNADDR PEI_DEBUG_XPORTEXPTNADDRx64
+#define PEI_DEBUG_BUFADDR PEI_DEBUG_BUFADDRx64
+#define PEI_DEBUG_ACKADDR PEI_DEBUG_ACKADDRx64
+#endif
+
+//=========================================================================
+//#define SET_SWBRKPT _SetBrkPt:0xcc;
+#endif
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/EHCI.h b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/EHCI.h
new file mode 100644
index 0000000..65659fb
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/EHCI.h
@@ -0,0 +1,244 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/EHCI.h 2 7/17/09 7:15p Madhans $
+//
+// $Revision: 2 $
+//
+// $Date: 7/17/09 7:15p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/EHCI.h $
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:49p Sudhirv
+// Update with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 5 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 4 3/13/07 4:08p Ashrafj
+// !!!Coding standard!!!
+//
+// 3 1/22/07 11:41a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ehci.h
+//
+// Description: EHCI controller related declarations and #defines.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+/*
+ USB Debug port resides in EHCI
+ Following is specific to chipset (ICH4,ICH5)
+*/
+#ifndef __EHCI_H__
+#define __EHCI_H__
+
+#define EHCI_BUS_NUMBER 0
+#define EHCI_DEVICE_NUMBER 29
+#define EHCI_FUNCTION_NUMBER 7
+
+#define EHCI_CAPABILITY_REG 0x34
+
+#define EHCI_POWERMGMT_CAP_REG 0x50 //ICH4 & ICH5(i875 MB)
+#define EHCI_DEBUGPORT_CAP_REG 0x58 //ICH4 & ICH5(i875 MB)
+
+#define ICH5_EHCI_BASE_ADDRESS_REGISTER 0x10
+
+#define MEMORYMAP_BASE_ADDR 0xEFFFFFFF //4GB - 256MB
+#define MEMORYMAP_WINDOW_SIZE 0x3FF //1 KB relocateble mem space (ICH4/5)
+
+//
+// Turn off the PWE assertion and put the device into D0 State
+//
+#define ICH5_PMCSR 0x8000
+////////////////////////////////////////////////
+
+#define ICH5_PCI_CAPABILITY_ID_PMI 0x01
+#define ICH5_EHCI_COMMAND_REGISTER 0x04
+
+#define DEBUG_PORT 0x0A
+#define PORTSC_CURRENT_CONNECT_STATUS 1
+#define PORTSC_CONNECT_STATUS_CHANGE 2
+#define PORTSC_PORT_ENABLE 4
+#define PORTSC_PORT_DISABLE 0xFFFFFFFB
+#define PORTSC_PORT_RESET 0x100
+#define PORTSC_PORT_NOT_RESET 0xFFFFFEFF
+
+#define IN_PID 0x69
+#define OUT_PID 0xE1
+#define SETUP_PID 0x2D
+#define DATA0 0xC3
+#define DATA1 0x4B
+
+#define ACK 0xD2
+#define NAK 0x5A
+#define STALL 0x1E
+#define NYET 0x96
+
+#define DEBUG_PORT_DESCRIPTOR_TYPE 0x0A
+
+#define MAX_USBDEBUGPORT_DATASIZE 8
+
+#pragma pack(1)
+typedef struct _CAP_REG_LIST{
+ UINT8 CapID;
+ UINT8 Nxt_Ptr;
+ UINT16 Offset :13;
+ UINT16 BAR :3;
+}CAP_REG_LIST;
+
+typedef struct _DEBUG_PORT_CONTROL_REGISTER{
+ UINT32 DataLength : 4;
+ UINT32 WriteRead : 1;
+ UINT32 Go : 1;
+ UINT32 ErrorGood : 1;
+ UINT32 Exception : 3;
+ UINT32 InUse : 1;
+ UINT32 Reserved1 : 5;
+ UINT32 Done : 1;
+ UINT32 Reserved2 : 11;
+ UINT32 Enabled : 1;
+ UINT32 Reserved3 : 1;
+ UINT32 Owner : 1;
+ UINT32 Reserved4 : 1;
+}DEBUG_PORT_CONTROL_REGISTER;
+
+typedef struct _USB_PID{
+ UINT32 TokenPID : 8;
+ UINT32 SendPID : 8;
+ UINT32 RecievedPID : 8;
+ UINT32 Reserved : 8;
+}USB_PID;
+
+typedef struct _DATA_BUFFER{
+ UINT32 LowDword;
+ UINT32 HighDword;
+}DATA_BUFFER;
+
+typedef struct _DEVICE_ADDR_REGISTER{
+ UINT32 USBEndPoint : 4;
+ UINT32 Reserved1 : 4;
+ UINT32 USBAddress : 7;
+ UINT32 Reserved2 : 17;
+}DEVICE_ADDR_REGISTER;
+
+typedef struct _HCSPARAMS{
+ UINT32 N_PORTS : 4;
+ UINT32 PPC : 1;
+ UINT32 Resrvd : 2;
+ UINT32 PRR : 1;
+ UINT32 N_PCC : 4;
+ UINT32 N_CC : 4;
+ UINT32 P_INDICATOR : 1;
+ UINT32 Resrvd2 : 3;
+ UINT32 DebugPortNum : 4;
+ UINT32 Resrvd3 : 8;
+}HCSPARAMS;
+
+typedef struct _GET_DESCRIPTOR_DEBUG_PORT{
+ UINT8 bLength;
+ UINT8 bDescriptorType;
+ UINT8 bDebugInEndpoint;
+ UINT8 bDebugOutEndpoint;
+}GET_DESCRIPTOR_DEBUG_PORT;
+
+
+typedef struct _USB_CMD{
+ UINT32 RunStop : 1;
+ UINT32 HCRESET : 1;
+ UINT32 FLS : 2;
+ UINT32 PSE : 1;
+ UINT32 ASE : 1;
+ UINT32 IAAD : 1;
+ UINT32 LHCR : 1;
+ UINT32 ASPMC : 3;
+ UINT32 ASPME : 1;
+ UINT32 Resvd1 : 4;
+ UINT32 ITC : 8;
+ UINT32 Resvd2 : 8;
+}USBCMD;
+
+typedef struct _USB_STS{
+ UINT32 USBINTR : 1;
+ UINT32 USBERRINT : 1;
+ UINT32 PCD : 1;
+ UINT32 FLR : 1;
+ UINT32 HSE : 1;
+ UINT32 INTASYNC : 1;
+ UINT32 Resvd1 : 6;
+ UINT32 HCHalted : 1;
+ UINT32 Reclamation : 1;
+ UINT32 PSS : 1;
+ UINT32 ASS : 1;
+ UINT32 Resvd2 : 16;
+}USBSTS;
+
+typedef struct _CONFIG_FLAG{
+ UINT32 CF : 1;
+ UINT32 Reserved : 31;
+}CONFIGFLAG, *PCONFIGFLAG;
+
+typedef struct _OPERATIONAL_REGISTER{
+ USBCMD USBCommandReg;
+ USBSTS USBStatusReg;
+}OPERATIONAL_REGISTER, *POPERATIONAL_REGISTER;
+
+#pragma pack()
+
+#endif // __EHCI_H__
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/INC.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/INC.cif
new file mode 100644
index 0000000..520a96b
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/INC.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "INC"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\INC\"
+ RefName = "INC"
+[files]
+"AMIpeidebug.h"
+"EHCI.h"
+"misc.h"
+"AMIpeidebugX64.h"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/misc.h b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/misc.h
new file mode 100644
index 0000000..b486fd9
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/INC/misc.h
@@ -0,0 +1,178 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/misc.h 2 7/17/09 7:15p Madhans $
+//
+// $Revision: 2 $
+//
+// $Date: 7/17/09 7:15p $
+//*****************************************************************
+//*****************************************************************
+//
+// misc.h
+//
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/INC/misc.h $
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:49p Sudhirv
+// Update with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 6 8/29/07 12:49p Madhans
+// Common code for 4.x and 3.x
+//
+// 5 6/13/07 3:17p Madhans
+// Copyright Year updated.
+//
+// 4 3/13/07 4:08p Ashrafj
+// !!!Coding standard!!!
+//
+// 3 1/22/07 11:41a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 5 1/05/07 6:15p Madhan
+//
+// 4 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+// 3 12/05/05 7:29p Ashrafj
+// Serial Port Debug Support added for PEI - DXE Debugger.
+//
+// Change in Serial Port Communication: Now the data transmission through
+// Serial Port is supported with the hardware Flow control feature of the
+// Serial Port controller.
+//
+// 2 11/29/05 6:08p Markw
+// For Alaska, include efi.h instead of defining new typecasts.
+//
+// 1 10/19/05 10:54a Felixp
+//
+// 1 10/19/05 10:44a Felixp
+//
+//
+//
+//*****************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: misc.h
+//
+// Description: Generic Misc header file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef ALASKA_SUPPORT
+
+#include <efi.h>
+
+#else /* Support for APTIO projects */
+
+#define UINT64 unsigned __int64
+#define UINT32 unsigned long
+#define UINT16 unsigned short
+#define UINT8 unsigned char
+
+#define INT32 signed long
+#define INT8 signed char
+#define INT16 signed short
+
+#define CHAR8 char
+#define CHAR16 unsigned short
+#define BOOLEAN unsigned char
+
+#define UINTN UINT32
+#define INTN INT32
+
+#define VOID void
+
+#ifndef _EFI_TYPES_H_
+
+#define TRUE 1
+
+#define FALSE 0
+
+#define NULL 0
+
+#define IN
+#define OUT
+
+//EFI error types
+
+//typedef UINTN EFI_STATUS;
+#define EFI_STATUS UINTN
+
+#define EFI_ERROR(a) (((INTN) a) < 0)
+
+#define EFIERR(a) (0x80000000 | a)
+
+#define EFI_SUCCESS 0
+#define EFI_LOAD_ERROR EFIERR(1)
+#define EFI_INVALID_PARAMETER EFIERR(2)
+#define EFI_UNSUPPORTED EFIERR(3)
+#define EFI_BAD_BUFFER_SIZE EFIERR(4)
+#define EFI_BUFFER_TOO_SMALL EFIERR(5)
+#define EFI_NOT_READY EFIERR(6)
+#define EFI_DEVICE_ERROR EFIERR(7)
+#define EFI_WRITE_PROTECTED EFIERR(8)
+#define EFI_OUT_OF_RESOURCES EFIERR(9)
+#define EFI_VOLUME_CORRUPTED EFIERR(10)
+#define EFI_VOLUME_FULL EFIERR(11)
+#define EFI_NO_MEDIA EFIERR(12)
+#define EFI_MEDIA_CHANGED EFIERR(13)
+#define EFI_NOT_FOUND EFIERR(14)
+#define EFI_ACCESS_DENIED EFIERR(15)
+#define EFI_NO_RESPONSE EFIERR(16)
+#define EFI_NO_MAPPING EFIERR(17)
+#define EFI_TIMEOUT EFIERR(18)
+#define EFI_NOT_STARTED EFIERR(19)
+#define EFI_ALREADY_STARTED EFIERR(20)
+#define EFI_ABORTED EFIERR(21)
+#define EFI_ICMP_ERROR EFIERR(22)
+#define EFI_TFTP_ERROR EFIERR(23)
+#define EFI_PROTOCOL_ERROR EFIERR(24)
+
+#endif
+
+#endif
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain.ffs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain.ffs
new file mode 100644
index 0000000..b5a9058
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain.ffs
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain_PI_1_1.ffs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain_PI_1_1.ffs
new file mode 100644
index 0000000..772afb1
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/MAIN/PeiDbgMain_PI_1_1.ffs
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.cif
new file mode 100644
index 0000000..80875d3
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "Pei AMI Debug Rx"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\"
+ RefName = "PeiAMIDebugRx"
+[files]
+"PeiAMIDebugRx.sdl"
+[parts]
+"PeiDbgMain"
+"PeiDbgIDT"
+"PeiDbgPort"
+"PeiDbgDbgr"
+"PeiDbgXport"
+"PeiDebugSupport"
+"INC"
+"PeiDbgDbgrx64"
+"PeiDbgXportx64"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.sdl
new file mode 100644
index 0000000..a9cf21b
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiAMIDebugRx.sdl
@@ -0,0 +1,44 @@
+TOKEN
+ Name = "PeiDebugModule_SUPPORT"
+ Value = "1"
+ Help = "Master SDL token of the Module depends on PeiDebugger_SUPPORT SDL token"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+ Lock = Yes
+ Token = "PeiDebugger_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "DBG_PI_INT_SUPPORT"
+ Value = "0"
+ TokenType = Integer
+End
+
+TOKEN
+ Name = "DBG_PI_INT_SUPPORT"
+ Value = "1"
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x5B"
+ TokenType = Integer
+End
+
+TOKEN
+ Name = "PEI_DBG_CFLAGS"
+ Value = "/nologo /c /O1 /W3 /WX /DALASKA_SUPPORT"
+ Token = "DBG_PI_INT_SUPPORT" "=" "0"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "PEI_DBG_CFLAGS"
+ Value = "/nologo /c /O1 /W3 /WX /DALASKA_SUPPORT /D EFI_SPECIFICATION_VERSION=$(EFI_SPECIFICATION_VERSION) /D PI_SPECIFICATION_VERSION=$(PI_SPECIFICATION_VERSION)"
+ Token = "DBG_PI_INT_SUPPORT" "=" "1"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "PeiAMIDebugRx_DIR"
+End
+
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.cif
new file mode 100644
index 0000000..75c0d11
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PeiDbgDbgr"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\"
+ RefName = "PeiDbgDbgr"
+[files]
+"PeiDbgDbgr.sdl"
+"PeiDbgDbgr.mak"
+"PeiDbgDbgr.dxs"
+"DBGR\mindbgr.obj"
+"DBGR\DbgrHdr.c"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.dxs
new file mode 100644
index 0000000..d537ae1
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.dxs
@@ -0,0 +1,57 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.dxs 3 2/22/10 4:17p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:17p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.dxs $
+//
+// 3 2/22/10 4:17p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.mak
new file mode 100644
index 0000000..1440d92
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.mak
@@ -0,0 +1,136 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.mak 2 7/17/09 7:15p Madhans $
+#
+# $Revision: 2 $
+#
+# $Date: 7/17/09 7:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.mak $
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 4 7/15/09 5:56p Madhans
+# X64 Support and clean up.
+#
+# 3 7/13/09 2:48p Sudhirv
+# Updated with Coding Standards
+#
+# 2 7/08/09 9:34a Sudhirv
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 6 12/12/08 5:42p Madhans
+# USB Redirection Module
+#
+# 4 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 3 6/06/07 12:30p Madhans
+# Debugger 1.06
+#
+# 2 3/12/07 6:19p Madhans
+# !!!coding standards!!!!
+#
+# 1 1/22/07 4:12p Madhans
+# 1.04.0002 Binary Version.
+#
+# 2 10/20/05 10:06a Felixp
+# missing dependencies added
+#
+# 1 10/19/05 10:54a Felixp
+#
+# 1 10/19/05 10:44a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgDbgr.mak
+#
+# Description: Make file pei debugger
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PeiDbgDbgr
+
+PEIDBGDBGR_BUILD_DIR=$(PeiDbgDbgr_DIR)\DBGR
+
+PEIDBGDBGR_OBJECTS = \
+$(BUILD_DIR)\$(PeiDbgDbgr_DIR)\DBGR\dbgrhdr.obj
+
+PEIDBGMIN_OBJECTS = \
+$(PEIDBGDBGR_BUILD_DIR)\mindbgr.obj
+
+PEIDBGDBGRLIB = $(BUILD_DIR)\PeiDbgDbgr.lib
+
+PeiDbgDbgr : $(BUILD_DIR)\PeiDbgDbgr.mak $(PEIDBGDBGRLIB) PeiDbgDbgrBin
+
+$(BUILD_DIR)\PeiDbgDbgr.mak : $(PeiDbgDbgr_DIR)\$(@B).cif $(PeiDbgDbgr_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDbgDbgr_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+$(PEIDBGDBGRLIB) :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgDbgr.mak all\
+ TYPE=PEI_LIBRARY\
+ LIBRARY_NAME=$(PEIDBGDBGRLIB)\
+ "CFLAGS=$(PEI_DBG_CFLAGS) /DRELOCATE /I$(PeiAMIDebugRx_DIR)\INC /I$(Foundation_DIR)"\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak"
+
+PeiDbgDbgrBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgDbgr.mak all\
+ GUID=4AAAAE15-5AEB-4c11-B91D-A3966AC04847\
+ ENTRY_POINT=InitDbgLayer\
+ TYPE=PEIM \
+ PE_IMAGE_FORMAT=1\
+ COMPRESS=0\
+ "OBJECTS="\
+ PRECOMPILED_OBJS=\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "CFLAGS=$(PEI_DBG_CFLAGS) /DRELOCATE /I$(PeiDbgDbgr_DIR)\INC"
+
+PeiDbgDbgrBin : $(PEIDBGDBGR_OBJECTS)
+
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+PeiDbgDbgrBin : $(PEIDBGMIN_OBJECTS)
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.sdl
new file mode 100644
index 0000000..3870fd2
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgDbgr.sdl
@@ -0,0 +1,22 @@
+PATH
+ Name = "PeiDbgDbgr_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgDbgr.mak to Project"
+ File = "PeiDbgDbgr.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgDbgr.ffs"
+ Parent = "FV_MAIN"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgDbgr.ffs"
+ Parent = "FV_BB"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.cif
new file mode 100644
index 0000000..29573db
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PeiDbgIDT"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\"
+ RefName = "PeiDbgIDT"
+[files]
+"PeiDbgIDT.sdl"
+"PeiDbgIDT.mak"
+"PeiDbgIDT.dxs"
+"IDT\emptyidt.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.dxs
new file mode 100644
index 0000000..6f2decf
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.dxs
@@ -0,0 +1,59 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.dxs 3 2/22/10 4:17p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:17p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.dxs $
+//
+// 3 2/22/10 4:17p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.mak
new file mode 100644
index 0000000..a4158d7
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.mak
@@ -0,0 +1,112 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.mak 2 7/17/09 7:15p Madhans $
+#
+# $Revision: 2 $
+#
+# $Date: 7/17/09 7:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.mak $
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 2 7/13/09 2:48p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 5 12/12/08 5:42p Madhans
+# USB Redirection Module
+#
+# 3 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 2 3/12/07 6:19p Madhans
+# !!!coding standards!!!!
+#
+# 1 1/22/07 4:12p Madhans
+# 1.04.0002 Binary Version.
+#
+# 2 10/20/05 10:05a Felixp
+# missing dependencies added
+#
+# 1 10/19/05 10:54a Felixp
+#
+# 1 10/19/05 10:44a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgIDT.mak
+#
+# Description: Makefile of pei idt module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PeiDbgIDT
+
+PEI_DBGIDT_BUILD_DIR=$(PeiDbgIDT_DIR)\IDT
+
+PEIDBGIDT_OBJECTS = \
+$(PeiDbgIDT_DIR)\IDT\emptyidt.obj
+
+PeiDbgIDT : $(BUILD_DIR)\PeiDbgIDT.mak PeiDbgIDTBin
+
+$(BUILD_DIR)\PeiDbgIDT.mak : $(PeiDbgIDT_DIR)\$(@B).cif $(PeiDbgIDT_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDbgIDT_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PeiDbgIDTBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgIDT.mak all\
+ GUID=811B4F4D-FB0B-4008-A42B-E551FD4A0F28\
+ ENTRY_POINT=SetUpIDT\
+ TYPE=PEIM \
+ COMPRESS=0\
+ "OBJECTS="\
+ PRECOMPILED_OBJS=\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "CFLAGS=$(PEI_DBG_CFLAGS) /I$(PeiAMIDebugRx_DIR)\INC"
+
+
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+PeiDbgIDTBin : $(PEIDBGIDT_OBJECTS)
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.sdl
new file mode 100644
index 0000000..610d3e9
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgIDT.sdl
@@ -0,0 +1,22 @@
+PATH
+ Name = "PeiDbgIDT_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgIDT.mak to Project"
+ File = "PeiDbgIDT.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgIDT.ffs"
+ Parent = "FV_MAIN"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgIDT.ffs"
+ Parent = "FV_BB"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.cif
new file mode 100644
index 0000000..1b548e5
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "PeiDbgMain"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\"
+ RefName = "PeiDbgMain"
+[files]
+"\PeiDbgMain.sdl"
+"\MAIN\PeiDbgMain.ffs"
+"\MAIN\PeiDbgMain_PI_1_1.ffs"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.sdl
new file mode 100644
index 0000000..88d4276
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgMain.sdl
@@ -0,0 +1,55 @@
+PATH
+ Name = "PeiDbgMain_DIR"
+End
+
+ELINK
+ Name = "$(PeiDbgMain_DIR)\MAIN\PeiDbgMain.ffs"
+ Parent = "FV_MAIN"
+ Token = "DBG_PI_INT_SUPPORT" "=" "1"
+ Token = "PI_SPECIFICATION_VERSION" "<" "0x10000"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PeiDbgMain_DIR)\MAIN\PeiDbgMain.ffs"
+ Parent = "FV_BB"
+ Token = "DBG_PI_INT_SUPPORT" "=" "1"
+ Token = "PI_SPECIFICATION_VERSION" "<" "0x10000"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PeiDbgMain_DIR)\MAIN\PeiDbgMain_PI_1_1.ffs"
+ Parent = "FV_MAIN"
+ Token = "DBG_PI_INT_SUPPORT" "=" "1"
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x10000"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PeiDbgMain_DIR)\MAIN\PeiDbgMain_PI_1_1.ffs"
+ Parent = "FV_BB"
+ Token = "DBG_PI_INT_SUPPORT" "=" "1"
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x10000"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PeiDbgMain_DIR)\MAIN\PeiDbgMain.ffs"
+ Parent = "FV_BB"
+ Token = "DBG_PI_INT_SUPPORT" "=" "0"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PeiDbgMain_DIR)\MAIN\PeiDbgMain.ffs"
+ Parent = "FV_MAIN"
+ Token = "DBG_PI_INT_SUPPORT" "=" "0"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.c b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.c
new file mode 100644
index 0000000..b816222
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.c
@@ -0,0 +1,390 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.c 10 4/04/12 4:55p Sudhirv $
+//
+// $Revision: 10 $
+//
+// $Date: 4/04/12 4:55p $
+//*****************************************************************
+//*****************************************************************
+//
+// PeiSer.c
+//
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.c $
+//
+// 10 4/04/12 4:55p Sudhirv
+// To Avoid Build errors in special cases.
+//
+// 9 3/13/12 10:47a Sudhirv
+// [TAG] EIP60224
+// [Category] Improvement
+// [Description] Function implement When broken in SMM, show the register
+// context for 'outside' SMM.
+//
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// [TAG] EIP81423
+// [Category] Improvement
+// [Description] VeB Debugger - Improve the EFI tab's Handle Display
+// feature
+//
+// [TAG] EIP84201
+// [Category] Improvement
+// [Description] AMIDebugRx\Debugger Target modules usage of the Port 80
+// must be controlable
+//
+// 8 4/01/11 2:46p Sudhirv
+// [TAG] EIP56888
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] DEBURX S3 resume hang 0x05 problem on Sabine platform
+// [Solution] Fixed the Initialization of the Debug Port to not differ
+// with Normal boot or S3 Resume.
+// [Files] PeiDbgPort.c
+//
+// 7 3/16/11 4:43p Sudhirv
+// Changes to Support Older Core before 4.6.5.0
+//
+// 6 3/09/11 8:20a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 5 9/22/10 7:09p Sudhirv
+// 4.6.2_AMIDebugRx_2.01.0026_Beta Release
+//
+// 4 2/22/10 4:17p Madhans
+// 1.32
+//
+// 4 10/19/09 7:25a Sudhirv
+// Updated to Reduce S3 Resume wake time and fix SIO Issue
+//
+// 3 9/30/09 3:05p Sudhirv
+// For Debugger 1.31.0023_PreAlpha
+//
+// 2 7/13/09 2:48p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 11 3/27/09 8:45a Sudhirv
+// Updated Coding Standards.
+//
+// 10 8/29/07 1:00p Madhans
+// Common code for 4.x and 3.x
+//
+// 9 6/13/07 3:16p Madhans
+// Copyright Year updated.
+//
+// 8 3/13/07 4:00p Ashrafj
+// Update for Coding standard
+//
+// 7 3/06/07 7:51p Ashrafj
+// Checkpoint error code added for improper chipset init porting support
+// form the Aptio Core.
+//
+// 6 1/22/07 11:41a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 10 1/05/07 6:15p Madhan
+//
+// 9 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+// 8 12/26/06 7:07p Ashrafj
+// Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+// Host.zip).
+// PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+// Support added for StatusCode redirection without Debug feature enabled
+// (not working if DXE only and x64 is enabled).
+// Plus, some new SDL tokens defined to support the Aptio 4.5 build
+// process in Debug or non-debug mode.
+// All the components of Debugger eModule in source form.
+//
+// 7 12/15/06 4:51p Ashrafj
+// Updated the Debugger eModule sources to support the CAR base address
+// define in the APtio 4.5 project SDL token itself.
+// Move the PEI Debugger modules (except PeiDebugSupport) from FV_BB to
+// FV_MAIN to avoid insufficient space problem in PEI. Note that for this
+// changes the Aptio 4.5 project should have the new version 0.4
+// PEIDEBUGFIXUP utility build tool with CORE.MAK modified (Refer Santa
+// Rosa project).
+//
+// 6 6/27/06 11:44a Ashrafj
+// New feature added:
+// To enable the PEI Debug support after system memory is installed, based
+// on build option provided through a new SDL token named
+// "PEI_DEBUG_SUPPORT_AFTER_MEMORY".
+//
+// 5 4/21/06 12:38p Ashrafj
+// Code cleanup.
+//
+// 4 3/15/06 7:41p Ashrafj
+// Modfication done to provide the Binary integration for Aptio 4
+// projects.
+//
+// 3 12/22/05 12:42p Ashrafj
+// Changes done to support the complete Chipset template porting.
+//
+// To use this changes, make sure to have the latest Board components of
+// CPU, SB and SIO, which have the following ELINKS ported:
+// - SBPEIDBG_Initialize,
+// - CPUPEIDBG_Initialize,
+// - SIOPEIDBG_Initialize,
+// - SBPEIDBG_InitUsbEhci.
+//
+// 2 12/15/05 12:13p Ashrafj
+// Minor reorganisation of Chipset porting method.
+//
+// 1 11/29/05 6:04p Markw
+//
+// 1 10/19/05 10:54a Felixp
+//
+//
+//*****************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: peidbgport.c
+//
+// Description: Calls the chipset elink and calls the initializartion
+// routines of debug port.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef ALASKA_SUPPORT
+#include "Efi.h"
+#include "SimpleCpuIoLib.h"
+#else
+#include <Efi.h>
+#endif
+#include "AmiDebugPort.h"
+#include "AMIPeiDebug.h"
+
+/////////////////////////////Porting definitions////////////////
+#ifdef ALASKA_SUPPORT
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+
+#ifdef ALASKA_SUPPORT
+#ifdef PEI_DBG_INIT_LIST
+extern PEI_INIT_FUNCTION PEI_DBG_INIT_LIST EndOfInitList;
+PEI_INIT_FUNCTION* PeiDebuggerInitList [] = {PEI_DBG_INIT_LIST NULL};
+#endif
+#endif
+
+#ifdef ALASKA_SUPPORT
+#ifdef PEI_DBG_S3_INIT_LIST
+extern PEI_INIT_FUNCTION PEI_DBG_S3_INIT_LIST EndOfInitS3List;
+PEI_INIT_FUNCTION* PeiDebuggerS3InitList [] = {PEI_DBG_S3_INIT_LIST NULL};
+#endif
+#endif
+
+#ifdef ALASKA_SUPPORT
+#ifdef IS_S3
+extern DBG_IS_S3 IS_S3 EndOfS3InitList;
+DBG_IS_S3 * IsDbgInS3[] = {IS_S3 NULL};
+#endif
+#endif
+
+#if defined PI_SPECIFICATION_VERSION
+#if PI_SPECIFICATION_VERSION >= 0x00010000
+const UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = 0;
+#else
+const UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = PEI_DEBUG_DATASECTION_BASEADDRESS;
+#endif
+#else
+const UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = PEI_DEBUG_DATASECTION_BASEADDRESS;
+#endif
+
+#ifndef ALASKA_SUPPORT
+extern EFI_STATUS SBPEIDBG_Initialize(PEI_DBG_PORT_INFO *DebugPort);
+extern EFI_STATUS CPUPEIDBG_Initialize(PEI_DBG_PORT_INFO *DebugPort);
+extern EFI_STATUS SIOPEIDBG_Initialize(PEI_DBG_PORT_INFO *DebugPort);
+#ifdef USB_DEBUGGER
+extern EFI_STATUS SBPEIDBG_InitUsbEhci(PEI_DBG_PORT_INFO *DebugPort);
+#endif
+#endif;
+
+#ifndef DBG_WRITE_IO_80_SUPPORT
+DBG_WRITE_IO_80_SUPPORT 0
+#endif
+//---->EIP 38453
+volatile UINT16 gS3ResumeSupport = AMI_DEBUG_RX_IN_S3_SUPPORT;
+volatile UINTN gDbgWriteIO80Support = DBG_WRITE_IO_80_SUPPORT;
+
+//---->EIP 38453
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: ExecutePeiDebuggerInitList()
+//
+// Description: Internal Helper function to invoke ELINKS.
+//
+// Input: PEI_DBG_PORT_INFO *DebugPort
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ExecutePeiDebuggerInitList(
+ IN OUT PEI_DBG_PORT_INFO *DebugPort
+)
+{
+#ifdef ALASKA_SUPPORT
+ UINTN i;
+
+ if(!PeiDebuggerInitList){
+ if(gDbgWriteIO80Support)
+ IoWrite8(0x80,0xD0); //err code for No elinks found
+ while(1);
+ }
+ for(i=0; PeiDebuggerInitList[i]; i++) PeiDebuggerInitList[i](DebugPort);
+#else
+ SBPEIDBG_Initialize(DebugPort);
+ CPUPEIDBG_Initialize(DebugPort);
+ SIOPEIDBG_Initialize(DebugPort);
+#ifdef USB_DEBUGGER
+ SBPEIDBG_InitUsbEhci(DebugPort);
+#endif
+#endif
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: ExecutePeiDebuggerS3InitList()
+//
+// Description: Internal Helper function to invoke ELINKS.
+//
+// Input: PEI_DBG_PORT_INFO *DebugPort
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ExecutePeiDebuggerS3InitList(
+ IN OUT PEI_DBG_PORT_INFO *DebugPort
+)
+{
+#ifdef ALASKA_SUPPORT
+ UINTN i;
+ for(i=0; PeiDebuggerS3InitList[i]; i++) PeiDebuggerS3InitList[i](DebugPort);
+#else
+ SIOPEIDBG_Initialize(DebugPort);
+#endif
+}
+////////////Routine part of Chipset Porting template/////////////////////
+
+void Initialise(PEI_DBG_PORT_INFO *DebugPort);
+void InitPeiDebugPortInterface(PEI_DBG_PORT_INFO *DebugPort, UINTN SetupFlag, UINTN IDTBaseAddress);
+/////////////////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: InitMain
+//
+// Description: entrypoint for the PeiDbgPort, the module init the specific
+// chipset.
+//
+// Input: void
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitMain(UINTN IDTBASEADDR)
+{
+ PEI_DBG_PORT_INFO DebugPort;
+ UINTN PeiDbgSetupFlag;
+ UINT8 Val;
+
+ PEIDebugData_T *pData = (PEIDebugData_T *)IDTBASEADDR;
+ SerXPortGblData_T *SerData = (SerXPortGblData_T *)pData->XportLocalVar;
+
+#if PEI_DEBUG_SUPPORT_AFTER_MEMORY
+ PeiDbgSetupFlag = 1;
+#else
+ PeiDbgSetupFlag = 0;
+#endif
+ SerData->m_IsHostConnected = 0;
+
+//---->EIP 38453
+ // If AMI_DEBUG_RX_IN_S3_SUPPORT is ON AmidebugRx should initialize for both S3 and normal boot
+ if(gS3ResumeSupport)
+ {
+ // EIP 56888 - DEBURX S3 resume hang 0x05 problem on Sabine platform
+ // If SDL Token is ON then there must be no difference for normal boot or S3 Resume
+ SerData->m_IsPeiDbgIsS3 = 1;
+ Initialise(&DebugPort);
+
+ ExecutePeiDebuggerInitList(&DebugPort);
+
+ InitPeiDebugPortInterface(&DebugPort,PeiDbgSetupFlag,IDTBASEADDR);
+ }
+ else // else SDL token is OFF AMIDebugRx should be init only if normal boot.
+ {
+ //To find if PeiDbgPort is happening for normal boot or for S3 while resume
+ Val = IsDbgInS3[0](); //Hook will return 1 if SBPeiDbg_Initialize is there else 0
+ if(!Val)
+ { // 0 returned - Normal Boot
+ SerData->m_IsPeiDbgIsS3 = 1;
+ Initialise(&DebugPort);
+
+ ExecutePeiDebuggerInitList(&DebugPort);
+
+ InitPeiDebugPortInterface(&DebugPort,PeiDbgSetupFlag,IDTBASEADDR);
+ }
+ else
+ { //1 returned - Returning from S3
+ ExecutePeiDebuggerS3InitList(&DebugPort);
+ SerData->m_IsPeiDbgIsS3 = 0;
+ }
+//---->EIP 38453
+ }
+}
+
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.cif
new file mode 100644
index 0000000..1b8c397
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PeiDbgPort"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\"
+ RefName = "PeiDbgPort"
+[files]
+"PeiDbgPort.sdl"
+"PeiDbgPort.mak"
+"PeiDbgPort.dxs"
+"PeiDbgPortUSB.obj"
+"PeiDbgPort.c"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.dxs
new file mode 100644
index 0000000..80fdc9c
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.dxs
@@ -0,0 +1,60 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.dxs 3 2/22/10 4:17p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:17p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.dxs $
+//
+// 3 2/22/10 4:17p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.mak
new file mode 100644
index 0000000..448998c
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.mak
@@ -0,0 +1,176 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.mak 6 6/28/11 7:53a Sudhirv $
+#
+# $Revision: 6 $
+#
+# $Date: 6/28/11 7:53a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.mak $
+#
+# 6 6/28/11 7:53a Sudhirv
+# [TAG] EIP63446
+# [Category] Defect.
+# [Description] To avoid build errors with Core 4.6.5.1_2 and
+# AMIDebugRx Bin
+# [Files] PEIDbgPort.mak
+#
+# 5 3/24/11 7:00p Madhans
+# To remove /Fc from the CFLAGS
+#
+# 4 2/22/10 4:17p Madhans
+# 1.32
+#
+# 5 2/20/10 11:44a Madhans
+# if PeiDebuggerS3Initialize is found then use that in S3 case.
+# If not found try to use defaultSioinit function(SIOPEIDBG_Initialize)
+# if it found in PeiDebuggerInitialize
+#
+# 4 10/19/09 7:25a Sudhirv
+# Updated to Reduce S3 Resume wake time and fix SIO Issue
+#
+# 3 9/30/09 3:05p Sudhirv
+# For Debugger 1.31.0023_PreAlpha
+#
+# 2 7/13/09 2:48p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 2 5/01/09 7:45p Madhans
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 5 12/12/08 5:42p Madhans
+# USB Redirection Module
+#
+# 3 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 2 3/12/07 6:19p Madhans
+# !!!coding standards!!!!
+#
+# 1 1/22/07 4:12p Madhans
+# 1.04.0002 Binary Version.
+#
+# 5 12/26/06 7:07p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+# 4 4/21/06 12:38p Ashrafj
+# Code cleanup.
+#
+# 3 3/15/06 7:41p Ashrafj
+# Modfication done to provide the Binary integration for Aptio 4
+# projects.
+#
+# 2 12/22/05 12:42p Ashrafj
+# Changes done to support the complete Chipset template porting.
+#
+# To use this changes, make sure to have the latest Board components of
+# CPU, SB and SIO, which have the following ELINKS ported:
+# - SBPEIDBG_Initialize,
+# - CPUPEIDBG_Initialize,
+# - SIOPEIDBG_Initialize,
+# - SBPEIDBG_InitUsbEhci.
+#
+# 1 11/29/05 6:04p Markw
+#
+# 2 10/20/05 10:05a Felixp
+# missing dependencies added
+#
+# 1 10/19/05 10:54a Felixp
+#
+# 1 10/19/05 10:44a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgPort.mak
+#
+# Description: Makefile of Pei debugPort module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PeiDbgPort
+
+PEIDBGPORT_OBJECTS = \
+$(BUILD_DIR)\$(PEI_DBG_PORT_DIR)\PeiDbgPort.obj \
+
+PEIDBGPORTUSB_OBJECTS = \
+$(PEI_DBG_PORT_DIR)\PeiDbgPortUSB.obj
+
+#if PeiDebuggerS3Initialize is found then use that in S3 case.
+#If not found try to use defaultSioinit function(SIOPEIDBG_Initialize) if it found in PeiDebuggerInitialize
+!IF "$(PeiDebuggerS3Initialize)" == ""
+!IF "$(PeiDebuggerInitialize:SIOPEIDBG_Initialize,=)" != "$(PeiDebuggerInitialize)"
+DbgRxSioS3Initialize = SIOPEIDBG_Initialize,
+!ENDIF
+!ELSE
+DbgRxSioS3Initialize = $(PeiDebuggerS3Initialize)
+!ENDIF
+
+PeiDbgPort : $(BUILD_DIR)\PeiDbgPort.mak PeiDbgPortBin
+
+$(BUILD_DIR)\PeiDbgPort.mak : $(PEI_DBG_PORT_DIR)\$(@B).cif $(PEI_DBG_PORT_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PEI_DBG_PORT_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PeiDbgPortBin : $(AMICSPLib) $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgPort.mak all\
+ GUID=EB7D9740-DB60-45c2-A7A0-C2714EF4EB56\
+ ENTRY_POINT=InitMain\
+ TYPE=PEIM \
+ COMPRESS=0\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ EXT_HEADERS=$(BUILD_DIR)\token.h\
+ "OBJECTS=$(PEIDBGPORT_OBJECTS)"\
+ "INIT_LIST=$(IsDbgS3)"\
+ PRECOMPILED_OBJS=\
+ "CFLAGS= $(GLOBAL_DEFINES) $(PEI_DBG_CFLAGS) /I$(PEI_DBG_PORT_DIR)\INC /D\"PEI_DBG_INIT_LIST=$(PeiDebuggerInitialize)\" /D\"PEI_DBG_S3_INIT_LIST=$(DbgRxSioS3Initialize)\" /DUSB_DEBUGGER /D\"IS_S3=$(IsDbgS3)\" "
+
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+PeiDbgPortBin : $(PEIDBGPORTUSB_OBJECTS)
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.sdl
new file mode 100644
index 0000000..b0b1f55
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPort.sdl
@@ -0,0 +1,51 @@
+PATH
+ Name = "PEI_DBG_PORT_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgPort.mak to Project"
+ File = "PeiDbgPort.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgPort.ffs"
+ Parent = "FV_MAIN"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgPort.ffs"
+ Parent = "FV_BB"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiDebuggerInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = " "
+ Parent = "PeiSioInit,"
+ Token = "PeiDebugger_SUPPORT" "=" "1"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "IsDbgS3"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiDbgIsS3Hook,"
+ Parent = "IsDbgS3"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiDebuggerS3Initialize"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPortUSB.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPortUSB.obj
new file mode 100644
index 0000000..a374375
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgPortUSB.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.cif
new file mode 100644
index 0000000..f648655
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PeiDbgXport"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\"
+ RefName = "PeiDbgXport"
+[files]
+"PeiDbgXport.sdl"
+"PeiDbgXport.mak"
+"PeiDbgXport.dxs"
+"XPORT\XportHdr.c"
+[parts]
+"PeiXportDbgr"
+"PeiXportRedir"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.dxs
new file mode 100644
index 0000000..18deabe
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.dxs
@@ -0,0 +1,59 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.dxs 3 2/22/10 4:17p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:17p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.dxs $
+//
+// 3 2/22/10 4:17p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.mak
new file mode 100644
index 0000000..e6af02d
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.mak
@@ -0,0 +1,160 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.mak 3 7/17/09 7:15p Madhans $
+#
+# $Revision: 3 $
+#
+# $Date: 7/17/09 7:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.mak $
+#
+# 3 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 3 7/13/09 2:48p Sudhirv
+# Updated with Coding Standards
+#
+# 2 7/10/09 11:44a Sudhirv
+# Updated
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 2 5/05/09 8:05p Madhans
+# Use the timestamp.h instead of timstamp.mak to avoid the octal issues.
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 2 5/01/09 7:45p Madhans
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 7 12/12/08 5:42p Madhans
+# USB Redirection Module
+#
+# 5 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 4 6/06/07 12:30p Madhans
+# Debugger 1.06
+#
+# 3 3/12/07 6:19p Madhans
+# !!!coding standards!!!!
+#
+# 2 1/25/07 3:07p Madhans
+# xporthdr.c added as source
+#
+# 1 1/22/07 4:12p Madhans
+# 1.04.0002 Binary Version.
+#
+# 6 12/15/06 4:51p Ashrafj
+# Updated the Debugger eModule sources to support the CAR base address
+# define in the APtio 4.5 project SDL token itself.
+# Move the PEI Debugger modules (except PeiDebugSupport) from FV_BB to
+# FV_MAIN to avoid insufficient space problem in PEI. Note that for this
+# changes the Aptio 4.5 project should have the new version 0.4
+# PEIDEBUGFIXUP utility build tool with CORE.MAK modified (Refer Santa
+# Rosa project).
+#
+# 5 3/15/06 7:43p Ashrafj
+# Modfication done to provide the Binary integration for Aptio 4
+# projects.
+#
+# 4 12/12/05 3:22p Ashrafj
+# Compiler optimization disable for Serial Port PEI Debug Transport.
+#
+# 3 10/20/05 10:51a Ashrafj
+# Compiler flags reset to original.
+#
+# 2 10/20/05 10:06a Felixp
+# missing dependencies added
+#
+# 1 10/19/05 10:54a Felixp
+#
+# 1 10/19/05 10:44a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgXport.mak
+#
+# Description: Makefile of Pei debugger Xport module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PeiDbgXport
+
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+PEIDBGXPORT_BUILD_DIR=$(PeiDbgXport_DIR)\XPORT\REDIR\
+!ELSE
+PEIDBGXPORT_BUILD_DIR=$(PeiDbgXport_DIR)\XPORT\DBGR\
+!ENDIF
+
+PEIDBGXPORT_OBJECTS = \
+$(BUILD_DIR)\$(PeiDbgXport_DIR)\XPORT\XportHdr.obj\
+$(PEIDBGXPORT_BUILD_DIR)\xp_layer.obj\
+$(PEIDBGXPORT_BUILD_DIR)\transport.obj\
+
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+PEIDBGXPORT_USB_OBJECTS = \
+$(PEIDBGXPORT_BUILD_DIR)\UsbDebugPort.obj\
+$(PEIDBGXPORT_BUILD_DIR)\usb_acc.obj\
+$(PEIDBGXPORT_BUILD_DIR)\usb_xp.obj
+!ENDIF
+
+PeiDbgXport : $(BUILD_DIR)\PeiDbgXport.mak PeiDbgXportBin
+
+$(BUILD_DIR)\PeiDbgXport.mak : $(PeiDbgXport_DIR)\$(@B).cif $(PeiDbgXport_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDbgXport_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PeiDbgXportBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgXport.mak all\
+ GUID=C7E8BB67-1C3F-41ba-820F-3D0E9C365042\
+ ENTRY_POINT=InitXLayer\
+ TYPE=PEIM \
+ PE_IMAGE_FORMAT=1\
+ COMPRESS=0\
+ "EXT_HEADERS=$(PeiDbgXport_DIR)\PeiDbgXport.mak $(BUILD_DIR)\Token.mak" \
+ "OBJECTS=$(PEIDBGXPORT_OBJECTS)"\
+ PRECOMPILED_OBJS=\
+ "CFLAGS=$(PEI_DBG_CFLAGS) /DRELOCATE /I$(PeiAMIDebugRx_DIR)\INC"
+
+
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+PeiDbgXportBin : $(PEIDBGXPORT_USB_OBJECTS)
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.sdl
new file mode 100644
index 0000000..42a90ba
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDbgXport.sdl
@@ -0,0 +1,32 @@
+PATH
+ Name = "PeiDbgXport_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgXport.mak to Project"
+ File = "PeiDbgXport.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgXport.ffs"
+ Parent = "FV_MAIN"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgXport.ffs"
+ Parent = "FV_BB"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "TARGET_PROJECT_TAG"
+ Value = "$(PROJECT_TAG)$(PROJECT_MAJOR_VERSION)$(PROJECT_MINOR_VERSION).rom"
+ Help = "File name of the BIOS rom image"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "valid file name"
+End
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/AmiDebugPort.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/AmiDebugPort.obj
new file mode 100644
index 0000000..7d83a0b
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/AmiDebugPort.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/CopyDbgXPortUsb.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/CopyDbgXPortUsb.obj
new file mode 100644
index 0000000..4caa1bd
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/CopyDbgXPortUsb.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DbgrHelp.c b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DbgrHelp.c
new file mode 100644
index 0000000..fda0704
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DbgrHelp.c
@@ -0,0 +1,168 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DbgrHelp.c 6 4/04/12 4:57p Sudhirv $
+//
+// $Revision: 6 $
+//
+// $Date: 4/04/12 4:57p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DbgrHelp.c $
+//
+// 6 4/04/12 4:57p Sudhirv
+// To Avoid Build errors in special cases.
+//
+// 5 3/13/12 10:47a Sudhirv
+// [TAG] EIP60224
+// [Category] Improvement
+// [Description] Function implement When broken in SMM, show the register
+// context for 'outside' SMM.
+//
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// [TAG] EIP81423
+// [Category] Improvement
+// [Description] VeB Debugger - Improve the EFI tab's Handle Display
+// feature
+//
+// [TAG] EIP84201
+// [Category] Improvement
+// [Description] AMIDebugRx\Debugger Target modules usage of the Port 80
+// must be controlable
+//
+// 4 5/13/11 4:13p Madhans
+// [TAG] EIP60365
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] LoadFV not working for PI 1.1 BIOS
+// [RootCause] The SDK Token values need to come from the building
+// project. But it was included with Binary so change SDL value cause the
+// feature to break
+// [Solution] SDL token values are will used be source.
+// [Files] relocdbg.obj
+// relocdbg_PI_1_1.obj
+// dbghelp.c
+//
+// 3 3/09/11 8:23a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 2 7/17/09 7:15p Madhans
+// DebugRx 1.30.0022
+//
+// 2 7/13/09 2:50p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:46p Sudhirv
+// Restructure Binaries Created
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 6 3/27/09 8:41a Sudhirv
+// Updated Coding Standards.
+//
+// 5 6/13/07 3:17p Madhans
+// Copyright Year updated.
+//
+// 4 1/22/07 11:42a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 4 1/05/07 6:15p Madhan
+//
+// 3 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+
+//*****************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DbgHelp.c
+//
+// Description: File containing the globals for CAR base address & size.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "misc.h"
+#include "AMIPeiDebug.h"
+
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+const UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = 0;
+const UINTN AMI_PEIDEBUGGER_DS_SIZE = 0x2048;
+#else
+const UINTN AMI_PEIDEBUGGER_DS_BASEADDRESS = PEI_DEBUG_DATASECTION_BASEADDRESS;
+const UINTN AMI_PEIDEBUGGER_DS_SIZE = PEI_DEBUG_DATASECTION_SIZE;
+#endif
+
+#ifndef ALASKA_SUPPORT
+
+#define FV_MAIN_BLOCKS FLASH_REGION_FVMAIN_SIZE_IN_BLOCKS
+#define FV_BB_BLOCKS FLASH_REGION_FV_RECOVERY_SIZE_IN_BLOCKS
+#define FV_MAIN_BASE FLASH_REGION_FVMAIN_BASE
+
+#endif
+
+#ifndef FV_MAIN_BASE
+#define FV_MAIN_BASE 0
+#endif
+#ifndef FV_MAIN_BLOCKS
+#define FV_MAIN_BLOCKS 0
+#endif
+#ifndef FV_BB_BLOCKS
+#define FV_BB_BLOCKS 0
+#endif
+#ifndef FLASH_BLOCK_SIZE
+#define FLASH_BLOCK_SIZE 0
+#endif
+#ifndef DBG_WRITE_IO_80_SUPPORT
+#define DBG_WRITE_IO_80_SUPPORT 0
+#endif
+
+UINTN gFvMainBase = FV_MAIN_BASE;
+UINTN gFvMainBlocks = FV_MAIN_BLOCKS;
+UINTN gFvBBBlocks = FV_BB_BLOCKS;
+UINTN gBlockSize = FLASH_BLOCK_SIZE;
+
+volatile UINTN gDbgWriteIO80Support = DBG_WRITE_IO_80_SUPPORT;
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DebugPortUsb.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DebugPortUsb.obj
new file mode 100644
index 0000000..1f99233
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/DebugPortUsb.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/EmptyNotify.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/EmptyNotify.obj
new file mode 100644
index 0000000..c195566
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/EmptyNotify.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/Emptyrelocdbgidt.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/Emptyrelocdbgidt.obj
new file mode 100644
index 0000000..cdea427
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/Emptyrelocdbgidt.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64.obj
new file mode 100644
index 0000000..4434d4a
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64_PI_1_1.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64_PI_1_1.obj
new file mode 100644
index 0000000..fc4e630
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDbgSupportX64_PI_1_1.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.cif
new file mode 100644
index 0000000..4fffdab
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.cif
@@ -0,0 +1,23 @@
+<component>
+ name = "PeiDebugSupport"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\PeiDebugSupport\"
+ RefName = "PeiDebugSupport"
+[files]
+"PeiDebugSupport.sdl"
+"PeiDebugSupport.mak"
+"PeiDebugSupport.dxs"
+"PeiDebugSupport.obj"
+"PeiDebugSupport_PI_1_1.obj"
+"relocdbg.obj"
+"relocdbg_PI_1_1.obj"
+"Emptyrelocdbgidt.obj"
+"AmiDebugPort.obj"
+"DebugPortUsb.obj"
+"CopyDbgXPortUsb.obj"
+"EmptyNotify.obj"
+"PeiDbgSupportX64.obj"
+"PeiDbgSupportX64_PI_1_1.obj"
+"emptyX64idt.obj"
+"DbgrHelp.c"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.dxs
new file mode 100644
index 0000000..8d1f5bc
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.dxs
@@ -0,0 +1,54 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.dxs 3 2/22/10 4:18p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:18p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.dxs $
+//
+// 3 2/22/10 4:18p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+//
+//
+//*****************************************************************
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.mak
new file mode 100644
index 0000000..216ca79
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.mak
@@ -0,0 +1,191 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.mak 4 3/16/11 4:44p Sudhirv $
+#
+# $Revision: 4 $
+#
+# $Date: 3/16/11 4:44p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.mak $
+#
+# 4 3/16/11 4:44p Sudhirv
+# Changes to Support Older Cores before 4.6.5.0
+#
+# 3 3/09/11 8:23a Sudhirv
+# EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 2 7/13/09 2:50p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 2 5/01/09 7:47p Madhans
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 7 12/12/08 5:42p Madhans
+# USB Redirection Module
+#
+# 5 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 4 6/06/07 6:13p Madhans
+# Leave the Peidbgsupport in PE format
+#
+# 3 3/12/07 6:20p Madhans
+# !!!coding standards!!!!
+#
+# 2 3/10/07 2:40p Madhans
+# For 1.05.binary Release.
+#
+# 1 1/22/07 4:12p Madhans
+# 1.04.0002 Binary Version.
+#
+# 6 12/26/06 7:07p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+# 5 12/15/06 4:51p Ashrafj
+# Updated the Debugger eModule sources to support the CAR base address
+# define in the APtio 4.5 project SDL token itself.
+# Move the PEI Debugger modules (except PeiDebugSupport) from FV_BB to
+# FV_MAIN to avoid insufficient space problem in PEI. Note that for this
+# changes the Aptio 4.5 project should have the new version 0.4
+# PEIDEBUGFIXUP utility build tool with CORE.MAK modified (Refer Santa
+# Rosa project).
+#
+# 4 7/05/06 1:39p Ashrafj
+# Include path updated
+#
+# 3 3/15/06 7:48p Ashrafj
+# Modfication done to provide the Binary integration for Aptio 4
+# projects.
+#
+# 2 10/20/05 10:06a Felixp
+# missing dependencies added
+#
+# 1 10/19/05 10:54a Felixp
+#
+# 1 10/19/05 10:44a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDebugSupport.mak
+#
+# Description: Makefile of Pei DebugSupport PEI Module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+PEI_DBGSUPPORT_CFLAGS = $(PEI_DBG_CFLAGS) /I$(PeiAMIDebugRx_DIR)\INC
+
+PEI_DBGSUPPORT_BUILD_DIR=$(PeiDebugSupport_DIR)
+
+PEI_DBGSUPPORT_OBJECTS =\
+!IFDEF PI_SPECIFICATION_VERSION
+!IF $(PI_SPECIFICATION_VERSION)>=0x00010000
+$(PEI_DBGSUPPORT_BUILD_DIR)\peidebugsupport_PI_1_1.obj \
+$(PEI_DBGSUPPORT_BUILD_DIR)\relocdbg_PI_1_1.obj \
+!ELSE
+$(PEI_DBGSUPPORT_BUILD_DIR)\peidebugsupport.obj \
+$(PEI_DBGSUPPORT_BUILD_DIR)\relocdbg.obj \
+!ENDIF
+!ELSE
+$(PEI_DBGSUPPORT_BUILD_DIR)\peidebugsupport.obj \
+$(PEI_DBGSUPPORT_BUILD_DIR)\relocdbg.obj \
+!ENDIF
+$(PEI_DBGSUPPORT_BUILD_DIR)\AmiDebugPort.obj \
+$(BUILD_DIR)\$(PeiDebugSupport_DIR)\DbgrHelp.obj \
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+$(PEI_DBGSUPPORT_BUILD_DIR)\DebugPortUsb.obj \
+!ENDIF
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+$(PEI_DBGSUPPORT_BUILD_DIR)\Emptyrelocdbgidt.obj \
+!ENDIF
+!IF "$(x64_BUILD)"=="1"
+!IFDEF PI_SPECIFICATION_VERSION
+!IF $(PI_SPECIFICATION_VERSION)>=0x00010000
+$(PEI_DBGSUPPORT_BUILD_DIR)\PeiDbgSupportX64_PI_1_1.obj \
+!ELSE
+$(PEI_DBGSUPPORT_BUILD_DIR)\PeiDbgSupportX64.obj \
+!ENDIF
+!ELSE
+$(PEI_DBGSUPPORT_BUILD_DIR)\PeiDbgSupportX64.obj \
+!ENDIF
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+$(PEI_DBGSUPPORT_BUILD_DIR)\CopyDbgXPortUsb.obj \
+!ENDIF
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+$(PEI_DBGSUPPORT_BUILD_DIR)\emptyX64idt.obj \
+!ENDIF
+!ELSE
+$(PEI_DBGSUPPORT_BUILD_DIR)\EmptyNotify.obj \
+!ENDIF
+
+
+all : PeiDebugSupport
+
+PeiDebugSupport : $(BUILD_DIR)\PeiDebugSupport.mak PeiDebugSupportBin
+
+$(BUILD_DIR)\PeiDebugSupport.mak : $(PeiDebugSupport_DIR)\$(@B).cif $(PeiDebugSupport_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDebugSupport_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PeiDebugSupportBin : $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDebugSupport.mak all\
+ GUID=A47438D5-94E9-49b3-BC31-7E6BC9363814\
+ ENTRY_POINT=PeiDebugSupportEntry \
+ TYPE=PEIM \
+ PE_IMAGE_FORMAT=1\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.mak" \
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ COMPRESS=0\
+ PRECOMPILED_OBJS=\
+ "OBJECTS=$(PEI_DBGSUPPORT_OBJECTS)"\
+ "CFLAGS = $(PEI_DBGSUPPORT_CFLAGS)"
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.obj
new file mode 100644
index 0000000..ab08637
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.sdl
new file mode 100644
index 0000000..b6ad7a5
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport.sdl
@@ -0,0 +1,24 @@
+PATH
+ Name = "PeiDebugSupport_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDebugSupport.mak to Project"
+ File = "PeiDebugSupport.mak"
+End
+
+
+# To move PeiDebugSupport.ffs to FV_MAIN refer the Release notes
+#ELINK
+# Name = "$(BUILD_DIR)\PeiDebugSupport.ffs"
+# Parent = "FV_MAIN"
+# Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+# InvokeOrder = AfterParent
+#End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDebugSupport.ffs"
+ Parent = "FV_BB"
+# Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "!=" "1"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport_PI_1_1.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport_PI_1_1.obj
new file mode 100644
index 0000000..c57e301
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/PeiDebugSupport_PI_1_1.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/emptyX64idt.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/emptyX64idt.obj
new file mode 100644
index 0000000..48e0fa3
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/emptyX64idt.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg.obj
new file mode 100644
index 0000000..2883933
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg_PI_1_1.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg_PI_1_1.obj
new file mode 100644
index 0000000..df1707d
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/PeiDebugSupport/relocdbg_PI_1_1.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/UsbDebugPort.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/UsbDebugPort.obj
new file mode 100644
index 0000000..291e959
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/UsbDebugPort.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/transport.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/transport.obj
new file mode 100644
index 0000000..966529a
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/transport.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_acc.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_acc.obj
new file mode 100644
index 0000000..2be39d9
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_acc.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_xp.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_xp.obj
new file mode 100644
index 0000000..6f39d73
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/usb_xp.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/xp_layer.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/xp_layer.obj
new file mode 100644
index 0000000..2a532d9
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/DBGR/xp_layer.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportDbgr.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportDbgr.cif
new file mode 100644
index 0000000..1ec1cf0
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportDbgr.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PeiXportDbgr"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\XPORT"
+ RefName = "PeiXportDbgr"
+[files]
+"DBGR\xp_layer.obj"
+"DBGR\transport.obj"
+"DBGR\usb_acc.obj"
+"DBGR\usb_xp.obj"
+"DBGR\UsbDebugPort.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportRedir.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportRedir.cif
new file mode 100644
index 0000000..0d80331
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/PeiXportRedir.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PeiXportRedir"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\XPORT"
+ RefName = "PeiXportRedir"
+[files]
+"REDIR\xp_layer.obj"
+"REDIR\transport.obj"
+"REDIR\usb_acc.obj"
+"REDIR\usb_xp.obj"
+"REDIR\UsbDebugPort.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/UsbDebugPort.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/UsbDebugPort.obj
new file mode 100644
index 0000000..6600831
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/UsbDebugPort.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/transport.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/transport.obj
new file mode 100644
index 0000000..95a8db8
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/transport.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_acc.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_acc.obj
new file mode 100644
index 0000000..989438e
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_acc.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_xp.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_xp.obj
new file mode 100644
index 0000000..bfb1726
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/usb_xp.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/xp_layer.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/xp_layer.obj
new file mode 100644
index 0000000..2552aed
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/REDIR/xp_layer.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/XportHdr.c b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/XportHdr.c
new file mode 100644
index 0000000..56c2ad7
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/XportHdr.c
@@ -0,0 +1,454 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/XportHdr.c 9 4/04/12 4:57p Sudhirv $
+//
+// $Revision: 9 $
+//
+// $Date: 4/04/12 4:57p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/XPORT/XportHdr.c $
+//
+// 9 4/04/12 4:57p Sudhirv
+// To Avoid Build errors in special cases.
+//
+// 8 3/13/12 10:47a Sudhirv
+// [TAG] EIP60224
+// [Category] Improvement
+// [Description] Function implement When broken in SMM, show the register
+// context for 'outside' SMM.
+//
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// [TAG] EIP81423
+// [Category] Improvement
+// [Description] VeB Debugger - Improve the EFI tab's Handle Display
+// feature
+//
+// [TAG] EIP84201
+// [Category] Improvement
+// [Description] AMIDebugRx\Debugger Target modules usage of the Port 80
+// must be controlable
+//
+// 7 7/12/11 5:27p Sudhirv
+// [TAG] EIP62342
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Target Crashes when Debugger enabled and AMIDebugRx is in
+// Checkpoint mode
+// [RootCause] Debugger is Enabled and AMIDebugRx device is connected in
+// checkpoint mode. Target MAchine is unaware of the type of host
+// connected in DXE phase.
+// [Solution] Support to not crash when Debugger enabled and Rx switch
+// in Checkpoint Mode.
+//
+// 6 3/17/11 8:09a Sudhirv
+// Support to Boot with S3 Resume in Core_4.6.5.0
+//
+// 5 3/09/11 8:27a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 4 2/15/10 8:05a Mallikarjunanv
+// Updated after fix for EIP 35101 - Binary Debug Rx module doesn't report
+// BIOS TAG correctly.
+//
+// 3 9/30/09 3:03p Sudhirv
+// For Debugger 1.31.0023_PreAlpha
+//
+// 2 7/13/09 2:53p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:47p Sudhirv
+// Restructure Binaries Created
+//
+// 2 5/05/09 8:05p Madhans
+// Use the timestamp.h instead of timstamp.mak to avoid the octal issues.
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 8 3/27/09 8:43a Sudhirv
+// Updated Coding Standards.
+//
+// 7 8/29/07 12:59p Madhans
+// Common code for 4.x and 3.x
+//
+// 6 6/13/07 3:17p Madhans
+// Copyright Year updated.
+//
+// 5 3/12/07 6:19p Madhans
+// !!!coding standards!!!!
+//
+// 4 1/22/07 11:43a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 4 1/05/07 6:15p Madhan
+//
+// 3 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+//*****************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: XportHdr.c
+//
+// Description: File containing the globals for CAR base address & size.
+// Also the code which make use of this so that it can be
+// integrated as it is Debugger eModule of binary.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "efi.h"
+#include "Pei.h"
+
+#include "misc.h"
+#ifndef EFIx64
+#include "AMIPeiDebug.h"
+#else
+#include "AMIPeiDebugX64.h"
+#include "AsmDbgrx64Libs.h"
+#endif
+#include "timestamp.h"
+
+#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+#ifndef DBG_WRITE_IO_80_SUPPORT
+#define DBG_WRITE_IO_80_SUPPORT 0
+#endif
+
+const char *sTargetProjectTag= STR(TARGET_PROJECT_TAG);
+
+//EIP 62342 - Support to not crash when Debugger enabled and Rx switch in Checkpoint Mode.
+UINTN gAMIDebuggerEnabled = REDIRECTION_ONLY_MODE;
+
+volatile UINTN gDbgWriteIO80Support = DBG_WRITE_IO_80_SUPPORT;
+
+typedef struct {
+ UINT16 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+} DateTime_T;
+
+VOID AddExtDelay();
+
+//**********************************************************************
+//<AMI_SHDR_START>
+//
+// Name: PeiDbgDataSection of type PEI_DBG_DATA_SECTION
+//
+// Description: The following global data structure is for relocation purpose
+// in order to support debugging after the debugger data section
+// is relocated. This second parameter of the data structure has
+// to be updated by the debugger service PEIM to point to relocated
+// data section into memory.The code section has this module
+// has to relocated before the update of second parameter.
+//
+//<AMI_SHDR_END>
+//**********************************************************************
+
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+PEI_DBG_DATA_SECTION PeiDbgDataSection = {
+ "XPRT",
+ NULL
+};
+#else
+PEI_DBG_DATA_SECTION PeiDbgDataSection = {
+ "XPRT",
+ PEI_DEBUG_DATASECTION_BASEADDRESS
+};
+
+#endif
+
+UINTN GetCARBaseAddress()
+{
+ EFI_PEI_SERVICES **PeiServices;
+ VOID *PeiDbgData;
+ EFI_GUID mPeiDbgBasePpiGuid = EFI_PEI_DBG_BASEADDRESS_PPI_GUID;
+ EFI_STATUS Status;
+
+ if((PeiDbgDataSection.DATABASEADDRESS)==NULL)
+ {
+ IDTBASE Idtr;
+#ifndef EFIx64
+ _asm{
+ sidt fword ptr Idtr
+ }
+#else
+ GetIdtr(&Idtr);
+#endif
+ PeiServices = (EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.IDTBaseAddr - sizeof (UINTN)));
+
+ if (PeiServices == NULL)
+ return (Idtr.IDTBaseAddr); //Point to the area after PEI Services
+ else
+ {
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &mPeiDbgBasePpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiDbgData // PPI
+ );
+ if (!EFI_ERROR(Status))
+ return *((UINTN*)PeiDbgData);
+ else
+ return (Idtr.IDTBaseAddr);
+ }
+ }
+ else {
+ return((UINTN)PeiDbgDataSection.DATABASEADDRESS);
+ }
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsDbgrInCAR
+//
+// Description: Internal Helper function.
+//
+// Input: none
+//
+// Output: 1 for yes & 0 for no (UINT32)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 IsDbgrInCAR()
+{
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+ if((PeiDbgDataSection.DATABASEADDRESS)==NULL)
+#else
+ if(PEI_DEBUG_DATA_BASEADDRESS == PEI_DEBUG_DATASECTION_BASEADDRESS)
+#endif
+ return 1; //yes
+ else
+ return 0; //no
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IoRead32
+//
+// Description: Internal Helper function. Reads 32-bit value from IO port
+//
+// Input: UINT16 Port
+//
+// Output: UINT32 - port data
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 IoRead32(UINT16 Port)
+{
+#ifdef EFIx64
+ return IoReadDword(Port);
+#else
+ _asm {
+ mov dx, Port
+ in eax, dx
+ }
+#endif
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: Stall
+//
+// Description: Internal Helper function.
+//
+// Input: UINTN Usec (microseconds)
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Stall (UINTN Usec)
+{
+ UINTN Counter = (Usec * 7)/2; // 3.58 count per microsec
+ UINTN i;
+ UINT32 Data32;
+ UINT32 PrevData;
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData=Data32; // FIX need to find out the real diff betweek different count.
+ }
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddDelay
+//
+// Description: Internal Helper function.
+//
+// Input: is currently designed to provide either software delay
+// or through ACPI timer who has fixed frequency.
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddDelay()
+{
+ Stall(10*1000); //for 10 milliseconds
+ return;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddUsbDelay
+//
+// Description: Internal Helper function.
+//
+// Input: is currently designed to provide either software delay
+// or through ACPI timer who has fixed frequency.
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddUsbDelay()
+{
+ Stall(2*1000); //for 2 milliseconds
+ return;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddSpecialDelay()
+//
+// Description: Internal Helper function.
+//
+// Input: void
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddSpecialDelay()
+{
+#if !PEI_CACHE_ENABLED
+ if(IsDbgrInCAR())
+ AddExtDelay();
+ else{
+ UINTN CriticalDelay = 60;
+ while(CriticalDelay--)
+ AddExtDelay();
+ }
+#else
+ UINTN CriticalDelay = 60;
+
+CriticalDelay = 1; // TESTING...
+ while(CriticalDelay--)
+ AddExtDelay();
+#endif
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddExtDelay()
+//
+// Description: Internal Helper function.
+//
+// Input: void
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddExtDelay()
+{
+// UINT8 i = 35; //providing 250 ms delay
+ UINT8 i = 25;
+ i =1; // TESTING...
+ while(i--)
+ AddDelay();
+ return;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: GetBuildTime()
+//
+// Description: Sends the Build Time Details
+//
+// Input: void*
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#define Str2No(A) (A - '0')
+
+#define TwoDigitStr2BCD(String) (Str2No(String[0])*0x10+Str2No(String[1]))
+
+VOID GetBuildTime(void *Buffer)
+{
+ UINT8 *strYear = FOUR_DIGIT_YEAR;
+ UINT8 *strMonth = TWO_DIGIT_MONTH;
+ UINT8 *strDay = TWO_DIGIT_DAY;
+ UINT8 *strHour = TWO_DIGIT_HOUR;
+ UINT8 *strMin = TWO_DIGIT_MINUTE;
+ UINT8 *strSec = TWO_DIGIT_SECOND;
+
+
+ ((DateTime_T*)Buffer)->Year=(Str2No(strYear[0])*0x1000+Str2No(strYear[1])*0x100+Str2No(strYear[2])*0x10+Str2No(strYear[3]));
+ ((DateTime_T*)Buffer)->Month=TwoDigitStr2BCD(strMonth);
+ ((DateTime_T*)Buffer)->Day=TwoDigitStr2BCD(strDay);
+ ((DateTime_T*)Buffer)->Hour=TwoDigitStr2BCD(strHour);
+ ((DateTime_T*)Buffer)->Minute=TwoDigitStr2BCD(strMin);
+ ((DateTime_T*)Buffer)->Second=TwoDigitStr2BCD(strSec);
+ return;
+}
+
+
+//#endif
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.cif
new file mode 100644
index 0000000..8b8b525
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "PeiDbgDbgrx64"
+ category = ModulePart
+ LocalRoot = "Core\EM\AMIDebugRx\binaries\PeiAMIDebugRx\x64\DBGR\"
+ RefName = "PeiDbgDbgrx64"
+[files]
+"PeiDbgDbgrx64.sdl"
+"PeiDbgDbgrx64.mak"
+"mindbgr.obj"
+"PeiDbgDbgrx64.dxs"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.dxs
new file mode 100644
index 0000000..178dd50
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.dxs
@@ -0,0 +1,60 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.dxs 3 2/22/10 4:18p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:18p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.dxs $
+//
+// 3 2/22/10 4:18p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.mak
new file mode 100644
index 0000000..98670fe
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.mak
@@ -0,0 +1,125 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.mak 2 7/17/09 7:15p Madhans $
+#
+# $Revision: 2 $
+#
+# $Date: 7/17/09 7:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.mak $
+#
+# 2 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 3 7/15/09 5:56p Madhans
+# X64 Support and clean up.
+#
+# 2 7/13/09 2:51p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:46p Sudhirv
+# Restructure Binaries Created
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 5 12/12/08 5:42p Madhans
+# USB Redirection Module
+#
+# 3 6/13/07 3:38p Madhans
+# Copyright Year updated.
+#
+# 2 3/12/07 6:20p Madhans
+# !!!coding standards!!!!
+#
+# 1 1/22/07 4:12p Madhans
+# 1.04.0002 Binary Version.
+#
+# 1 12/26/06 7:17p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+# 1 12/26/06 7:10p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgDbgrx64.mak
+#
+# Description: Makefile of Debugger x64 Module that is loaded by Peidebugsupport
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PeiDbgDbgrx64
+
+PeiDbgDbgrx64 : $(BUILD_DIR)\PeiDbgDbgrx64.mak PeiDbgDbgrx64Bin
+
+$(BUILD_DIR)\PeiDbgDbgrx64.mak : $(PeiDbgDbgrx64_DIR)\$(@B).cif $(PeiDbgDbgrx64_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDbgDbgrx64_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PEIDBGDBGR_OBJS = \
+$(PeiDbgDbgrx64_DIR)\mindbgr.obj
+
+
+PeiDbgDbgrx64Bin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgDbgrx64.mak all\
+ GUID=C253ED0A-C48B-4ee3-A65E-75F61F3AD251\
+ ENTRY_POINT=InitDbgLayer\
+ TYPE=BS_DRIVER \
+ PRECOMPILED_OBJS=\
+ COMPRESS=1\
+ "OBJECTS="\
+
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+PeiDbgDbgrx64Bin : $(PEIDBGDBGR_OBJS)
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.sdl
new file mode 100644
index 0000000..f466826
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/PeiDbgDbgrx64.sdl
@@ -0,0 +1,35 @@
+TOKEN
+ Name = "PeiDbgDbgrx64_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PeiDbgDbgrx64 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Lock = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+PATH
+ Name = "PeiDbgDbgrx64_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgDbgrx64.mak to Project"
+ File = "PeiDbgDbgrx64.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgDbgrx64.ffs"
+ Parent = "FV_MAIN"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgDbgrx64.ffs"
+ Parent = "FV_BB"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/mindbgr.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/mindbgr.obj
new file mode 100644
index 0000000..8092523
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/DBGR/mindbgr.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/UsbDebugPort.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/UsbDebugPort.obj
new file mode 100644
index 0000000..6ad950d
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/UsbDebugPort.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/transport.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/transport.obj
new file mode 100644
index 0000000..d30f432
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/transport.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_acc.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_acc.obj
new file mode 100644
index 0000000..a041426
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_acc.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_xp.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_xp.obj
new file mode 100644
index 0000000..9b2b225
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/usb_xp.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/xp_layer.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/xp_layer.obj
new file mode 100644
index 0000000..bb7e135
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/DBGR/xp_layer.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.cif
new file mode 100644
index 0000000..ba1e486
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "PeiDbgXportx64"
+ category = ModulePart
+ LocalRoot = "Core\EM\AMIDebugRx\binaries\PeiAMIDebugRx\x64\XPORT\"
+ RefName = "PeiDbgXportx64"
+[files]
+"PeiDbgXportx64.sdl"
+"PeiDbgXportx64.mak"
+"PeiDbgXportx64.dxs"
+"XportHdr.c"
+[parts]
+"PeiXportx64Redir"
+"PeiXportx64Dbgr"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.dxs b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.dxs
new file mode 100644
index 0000000..5c9dcc4
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.dxs
@@ -0,0 +1,59 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.dxs 3 2/22/10 4:18p Madhans $
+//
+// $Revision: 3 $
+//
+// $Date: 2/22/10 4:18p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.dxs $
+//
+// 3 2/22/10 4:18p Madhans
+// 1.32
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 3 1/05/07 6:15p Madhan
+//
+// 2 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.mak b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.mak
new file mode 100644
index 0000000..6955680
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.mak
@@ -0,0 +1,139 @@
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+# $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.mak 3 7/17/09 7:15p Madhans $
+#
+# $Revision: 3 $
+#
+# $Date: 7/17/09 7:15p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.mak $
+#
+# 3 7/17/09 7:15p Madhans
+# DebugRx 1.30.0022
+#
+# 3 7/15/09 5:56p Madhans
+# X64 Support and clean up.
+#
+# 2 7/13/09 2:52p Sudhirv
+# Updated with Coding Standards
+#
+# 1 7/07/09 4:47p Sudhirv
+# Restructure Binaries Created
+#
+# 2 5/04/09 11:35a Madhans
+#
+# 1 5/01/09 7:48p Madhans
+# AMIDebug Rx Module. Intial Checkin.
+#
+# 2 5/01/09 7:47p Madhans
+#
+# 1 4/29/09 7:52a Sudhirv
+# AMI Debug Rx module created
+#
+# 4 6/13/07 3:17p Madhans
+# Copyright Year updated.
+#
+# 3 1/22/07 11:43a Madhans
+# Modification made for Binary Release 1.04.0003.
+#
+# 1 12/26/06 7:17p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+# 1 12/26/06 7:10p Ashrafj
+# Support added to support the Aptio 4.5 x64 EFI BIOS (use latest
+# Host.zip).
+# PEI Debugger in FV_MAIN (use new PEIDEBUGFIXUP).
+# Support added for StatusCode redirection without Debug feature enabled
+# (not working if DXE only and x64 is enabled).
+# Plus, some new SDL tokens defined to support the Aptio 4.5 build
+# process in Debug or non-debug mode.
+# All the components of Debugger eModule in source form.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiDbgXportx64.mak
+#
+# Description: Makefile of Xport64 module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+
+!IF "$(REDIRECTION_ONLY_MODE)" == "1"
+PEIDBGXPORTx64_BUILD_DIR=$(PeiDbgXportx64_DIR)\REDIR
+!ELSE
+PEIDBGXPORTx64_BUILD_DIR=$(PeiDbgXportx64_DIR)\DBGR
+!ENDIF
+
+PEIDBGXPORTX64_OBJS=\
+$(PEIDBGXPORTx64_BUILD_DIR)\transport.obj\
+$(PEIDBGXPORTx64_BUILD_DIR)\xp_layer.obj\
+$(BUILD_DIR)\$(PeiDbgXportx64_DIR)\XportHdr.obj\
+
+PEIDBGXPORTx64_USB_OBJECTS =\
+$(PEIDBGXPORTx64_BUILD_DIR)\usb_acc.obj\
+$(PEIDBGXPORTx64_BUILD_DIR)\usb_xp.obj\
+$(PEIDBGXPORTx64_BUILD_DIR)\UsbDebugPort.obj
+
+!INCLUDE $(BUILD_DIR)\TimeStamp.mak
+
+all : PeiDbgXportx64
+
+PeiDbgXportx64 : $(BUILD_DIR)\PeiDbgXportx64.mak PeiDbgXportx64Bin
+
+$(BUILD_DIR)\PeiDbgXportx64.mak : $(PeiDbgXportx64_DIR)\$(@B).cif $(PeiDbgXportx64_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiDbgXportx64_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PeiDbgXportx64Bin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiDbgXportx64.mak all\
+ GUID=511D0266-F2E0-4df8-AE3A-FDB98523BFB9\
+ ENTRY_POINT=InitXLayer\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+ "OBJECTS=$(PEIDBGXPORTX64_OBJS)"\
+ "CFLAGS=$(PEI_DBG_CFLAGS) /DRELOCATE /I$(PeiDbgDbgr_DIR)\INC /I$(DbgrX64_DIR) "
+
+!IF "$(USB_DEBUG_TRANSPORT)" == "1"
+PeiDbgXportx64Bin : $(PEIDBGXPORTx64_USB_OBJECTS)
+!ENDIF
+
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
+#//** **//
+#//** (C)Copyright 2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+#//** **//
+#//** Phone (770)-246-8600 **//
+#//** **//
+#//*****************************************************************//
+#//*****************************************************************//
+#//*****************************************************************//
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.sdl b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.sdl
new file mode 100644
index 0000000..380f960
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiDbgXportx64.sdl
@@ -0,0 +1,34 @@
+TOKEN
+ Name = "PeiDbgXportx64_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PeiDbgXportx64 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Lock = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+PATH
+ Name = "PeiDbgXportx64_DIR"
+End
+
+MODULE
+ Help = "Includes PeiDbgXportx64.mak to Project"
+ File = "PeiDbgXportx64.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgXportx64.ffs"
+ Parent = "FV_MAIN"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiDbgXportx64.ffs"
+ Parent = "FV_BB"
+ Token = "DEBUG_RX_FFS_IN_FVMAIN_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportDbgrx64.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportDbgrx64.cif
new file mode 100644
index 0000000..5bbd63f
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportDbgrx64.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PeiXportx64Dbgr"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\x64\XPORT"
+ RefName = "PeiXportx64Dbgr"
+[files]
+"DBGR\xp_layer.obj"
+"DBGR\transport.obj"
+"DBGR\usb_acc.obj"
+"DBGR\usb_xp.obj"
+"DBGR\UsbDebugPort.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportx64Redir.cif b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportx64Redir.cif
new file mode 100644
index 0000000..806c72b
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/PeiXportx64Redir.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "PeiXportx64Redir"
+ category = ModulePart
+ LocalRoot = "Core\em\AMIDebugRx\binaries\PeiAMIDebugRx\x64\XPORT"
+ RefName = "PeiXportx64Redir"
+[files]
+"REDIR\xp_layer.obj"
+"REDIR\transport.obj"
+"REDIR\usb_acc.obj"
+"REDIR\usb_xp.obj"
+"REDIR\UsbDebugPort.obj"
+<endComponent>
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/UsbDebugPort.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/UsbDebugPort.obj
new file mode 100644
index 0000000..df06970
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/UsbDebugPort.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/transport.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/transport.obj
new file mode 100644
index 0000000..0890fb7
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/transport.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_acc.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_acc.obj
new file mode 100644
index 0000000..2057d96
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_acc.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_xp.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_xp.obj
new file mode 100644
index 0000000..a749ebf
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/usb_xp.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/xp_layer.obj b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/xp_layer.obj
new file mode 100644
index 0000000..833dab5
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/REDIR/xp_layer.obj
Binary files differ
diff --git a/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/XportHdr.c b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/XportHdr.c
new file mode 100644
index 0000000..3cc95b8
--- /dev/null
+++ b/Core/EM/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/XportHdr.c
@@ -0,0 +1,445 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Header: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/XportHdr.c 9 4/04/12 4:58p Sudhirv $
+//
+// $Revision: 9 $
+//
+// $Date: 4/04/12 4:58p $
+//*****************************************************************
+//*****************************************************************
+//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMIDebugRx/binaries/PeiAMIDebugRx/x64/XPORT/XportHdr.c $
+//
+// 9 4/04/12 4:58p Sudhirv
+// To Avoid Build errors in special cases.
+//
+// 8 3/13/12 10:47a Sudhirv
+// [TAG] EIP60224
+// [Category] Improvement
+// [Description] Function implement When broken in SMM, show the register
+// context for 'outside' SMM.
+//
+// [TAG] EIP80406
+// [Category] Improvement
+// [Description] Debugger support for Dynamic pci express base token
+//
+// [TAG] EIP81423
+// [Category] Improvement
+// [Description] VeB Debugger - Improve the EFI tab's Handle Display
+// feature
+//
+// [TAG] EIP84201
+// [Category] Improvement
+// [Description] AMIDebugRx\Debugger Target modules usage of the Port 80
+// must be controlable
+//
+// 7 7/12/11 5:54p Sudhirv
+// [TAG] EIP62342
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Target Crashes when Debugger enabled and AMIDebugRx is in
+// Checkpoint mode
+// [RootCause] Debugger is Enabled and AMIDebugRx device is connected in
+// checkpoint mode. Target MAchine is unaware of the type of host
+// connected in DXE phase.
+// [Solution] Support to not crash when Debugger enabled and Rx switch
+// in Checkpoint Mode.
+//
+// 6 3/09/11 8:25a Sudhirv
+// EIP 53658 - AMIDebugRx\Debugger support for PI 1.1
+//
+// 5 2/15/10 8:05a Mallikarjunanv
+// Updated after fix for EIP 35101 - Binary Debug Rx module doesn't report
+// BIOS TAG correctly.
+//
+// 3 9/30/09 3:03p Sudhirv
+// For Debugger 1.31.0023_PreAlpha
+//
+// 2 7/13/09 2:52p Sudhirv
+// Updated with Coding Standards
+//
+// 1 7/07/09 4:47p Sudhirv
+// Restructure Binaries Created
+//
+// 2 5/04/09 11:35a Madhans
+//
+// 1 5/01/09 7:48p Madhans
+// AMIDebug Rx Module. Intial Checkin.
+//
+// 1 4/29/09 7:52a Sudhirv
+// AMI Debug Rx module created
+//
+// 8 3/27/09 8:43a Sudhirv
+// Updated Coding Standards.
+//
+// 7 8/29/07 12:59p Madhans
+// Common code for 4.x and 3.x
+//
+// 6 6/13/07 3:17p Madhans
+// Copyright Year updated.
+//
+// 5 3/12/07 6:19p Madhans
+// !!!coding standards!!!!
+//
+// 4 1/22/07 11:43a Madhans
+// Modification made for Binary Release 1.04.0003.
+//
+// 4 1/05/07 6:15p Madhan
+//
+// 3 1/05/07 1:05p Ashrafj
+// Latest version 1.04.0001 Beta
+// Known issues from previous 1.04.000 Beta release has been fixed.
+//
+//
+//*****************************************************************
+//*****************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: XportHdr.c
+//
+// Description: File containing the globals for CAR base address & size.
+// Also the code which make use of this so that it can be
+// integrated as it is Debugger eModule of binary.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "efi.h"
+#include "Pei.h"
+
+#include "misc.h"
+#ifndef EFIx64
+#include "AMIPeiDebug.h"
+#else
+#include "AMIPeiDebugX64.h"
+#include "AsmDbgrx64Libs.h"
+#endif
+#include "timestamp.h"
+
+#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+#ifndef DBG_WRITE_IO_80_SUPPORT
+#define DBG_WRITE_IO_80_SUPPORT 0
+#endif
+const char *sTargetProjectTag= STR(TARGET_PROJECT_TAG);
+
+//EIP 62342 - Support to not crash when Debugger enabled and Rx switch in Checkpoint Mode.
+UINTN gAMIDebuggerEnabled = REDIRECTION_ONLY_MODE;
+
+volatile UINTN gDbgWriteIO80Support = DBG_WRITE_IO_80_SUPPORT;
+
+typedef struct {
+ UINT16 Year;
+ UINT8 Month;
+ UINT8 Day;
+ UINT8 Hour;
+ UINT8 Minute;
+ UINT8 Second;
+} DateTime_T;
+
+VOID AddExtDelay();
+
+//**********************************************************************
+//<AMI_SHDR_START>
+//
+// Name: PeiDbgDataSection of type PEI_DBG_DATA_SECTION
+//
+// Description: The following global data structure is for relocation purpose
+// in order to support debugging after the debugger data section
+// is relocated. This second parameter of the data structure has
+// to be updated by the debugger service PEIM to point to relocated
+// data section into memory.The code section has this module
+// has to relocated before the update of second parameter.
+//
+//<AMI_SHDR_END>
+//**********************************************************************
+
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+PEI_DBG_DATA_SECTION PeiDbgDataSection = {
+ "XPRT",
+ NULL
+};
+#else
+PEI_DBG_DATA_SECTION PeiDbgDataSection = {
+ "XPRT",
+ PEI_DEBUG_DATASECTION_BASEADDRESS
+};
+
+#endif
+
+#ifndef EFIx64
+UINTN GetCARBaseAddress()
+{
+ EFI_PEI_SERVICES **PeiServices;
+ VOID *PeiDbgData;
+ EFI_GUID mPeiDbgBasePpiGuid = EFI_PEI_DBG_BASEADDRESS_PPI_GUID;
+ EFI_STATUS Status;
+
+ if((PeiDbgDataSection.DATABASEADDRESS)==NULL)
+ {
+ IDTBASE Idtr;
+ _asm{
+ sidt fword ptr Idtr
+ }
+ PeiServices = (EFI_PEI_SERVICES **) (*(UINTN*)(Idtr.IDTBaseAddr - sizeof (UINTN)));
+
+ if (PeiServices == NULL)
+ return (Idtr.IDTBaseAddr); //Point to the area after PEI Services
+ else
+ {
+ Status = (**PeiServices).LocatePpi(
+ PeiServices,
+ &mPeiDbgBasePpiGuid, // GUID
+ 0, // INSTANCE
+ NULL, // EFI_PEI_PPI_DESCRIPTOR
+ &PeiDbgData // PPI
+ );
+ if (!EFI_ERROR(Status))
+ return (UINTN)PeiDbgData;
+ else
+ return (Idtr.IDTBaseAddr);
+ }
+ }
+ else {
+ return((UINTN)PeiDbgDataSection.DATABASEADDRESS);
+ }
+}
+#endif
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IsDbgrInCAR
+//
+// Description: Internal Helper function.
+//
+// Input: none
+//
+// Output: 1 for yes & 0 for no (UINT32)
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 IsDbgrInCAR()
+{
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+ if((PeiDbgDataSection.DATABASEADDRESS)==NULL)
+#else
+ if(PEI_DEBUG_DATA_BASEADDRESS == PEI_DEBUG_DATASECTION_BASEADDRESS)
+#endif
+ return 1; //yes
+ else
+ return 0; //no
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: IoRead32
+//
+// Description: Internal Helper function. Reads 32-bit value from IO port
+//
+// Input: UINT16 Port
+//
+// Output: UINT32 - port data
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 IoRead32(UINT16 Port)
+{
+#ifdef EFIx64
+ return IoReadDword(Port);
+#else
+ _asm {
+ mov dx, Port
+ in eax, dx
+ }
+#endif
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: Stall
+//
+// Description: Internal Helper function.
+//
+// Input: UINTN Usec (microseconds)
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Stall (UINTN Usec)
+{
+ UINTN Counter = (Usec * 7)/2; // 3.58 count per microsec
+ UINTN i;
+ UINT32 Data32;
+ UINT32 PrevData;
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData=Data32; // FIX need to find out the real diff betweek different count.
+ }
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddDelay
+//
+// Description: Internal Helper function.
+//
+// Input: is currently designed to provide either software delay
+// or through ACPI timer who has fixed frequency.
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddDelay()
+{
+ Stall(10*1000); //for 10 milliseconds
+ return;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddUsbDelay
+//
+// Description: Internal Helper function.
+//
+// Input: is currently designed to provide either software delay
+// or through ACPI timer who has fixed frequency.
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddUsbDelay()
+{
+ Stall(2*1000); //for 2 milliseconds
+ return;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddSpecialDelay()
+//
+// Description: Internal Helper function.
+//
+// Input: void
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddSpecialDelay()
+{
+#if !PEI_CACHE_ENABLED
+ if(IsDbgrInCAR())
+ AddExtDelay();
+ else{
+ UINTN CriticalDelay = 60;
+ while(CriticalDelay--)
+ AddExtDelay();
+ }
+#else
+ UINTN CriticalDelay = 60;
+
+CriticalDelay = 1; // TESTING...
+ while(CriticalDelay--)
+ AddExtDelay();
+#endif
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: AddExtDelay()
+//
+// Description: Internal Helper function.
+//
+// Input: void
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+void AddExtDelay()
+{
+// UINT8 i = 35; //providing 250 ms delay
+ UINT8 i = 25;
+ i =1; // TESTING...
+ while(i--)
+ AddDelay();
+ return;
+}
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------
+// Procedure: GetBuildTime()
+//
+// Description: Sends the Build Time Details
+//
+// Input: void*
+//
+// Output: void
+//
+//--------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#define Str2No(A) (A - '0')
+
+#define TwoDigitStr2BCD(String) (Str2No(String[0])*0x10+Str2No(String[1]))
+
+VOID GetBuildTime(void *Buffer)
+{
+ UINT8 *strYear = FOUR_DIGIT_YEAR;
+ UINT8 *strMonth = TWO_DIGIT_MONTH;
+ UINT8 *strDay = TWO_DIGIT_DAY;
+ UINT8 *strHour = TWO_DIGIT_HOUR;
+ UINT8 *strMin = TWO_DIGIT_MINUTE;
+ UINT8 *strSec = TWO_DIGIT_SECOND;
+
+
+ ((DateTime_T*)Buffer)->Year=(Str2No(strYear[0])*0x1000+Str2No(strYear[1])*0x100+Str2No(strYear[2])*0x10+Str2No(strYear[3]));
+ ((DateTime_T*)Buffer)->Month=TwoDigitStr2BCD(strMonth);
+ ((DateTime_T*)Buffer)->Day=TwoDigitStr2BCD(strDay);
+ ((DateTime_T*)Buffer)->Hour=TwoDigitStr2BCD(strHour);
+ ((DateTime_T*)Buffer)->Minute=TwoDigitStr2BCD(strMin);
+ ((DateTime_T*)Buffer)->Second=TwoDigitStr2BCD(strSec);
+ return;
+}
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMITSE/AMITSE.chm b/Core/EM/AMITSE/AMITSE.chm
new file mode 100644
index 0000000..727ade4
--- /dev/null
+++ b/Core/EM/AMITSE/AMITSE.chm
Binary files differ
diff --git a/Core/EM/AMITSE/AMITSE.cif b/Core/EM/AMITSE/AMITSE.cif
new file mode 100644
index 0000000..d2c0206
--- /dev/null
+++ b/Core/EM/AMITSE/AMITSE.cif
@@ -0,0 +1,52 @@
+<component>
+ name = "TSE Binary"
+ category = eModule
+ LocalRoot = "Core\em\AMITSE\"
+ RefName = "AMITSE"
+[files]
+"AMITSE.sdl"
+"AMITSE.mak"
+"AMITSE.chm"
+"bootflow.c"
+"bootflow.h"
+"commonoem.c"
+"commonoem.h"
+"FakeTokens.c"
+"SmLogo.bmp"
+"setup.ini"
+"HpkTool.exe"
+"AmiTSEStr.uni"
+"Inc\boot.h"
+"Inc\HiiLib.h"
+"Inc\LogoLib.h"
+"Inc\mem.h"
+"Inc\PwdLib.h"
+"Inc\variable.h"
+"Inc\HookAnchor.h"
+"HookList.c"
+"CommonHelper.c"
+"Keymon.c"
+"Keymon.h"
+"Inc\TseElinks.h"
+"Inc\TseCommon.h"
+"Inc\setupdata.h"
+"Uefisetup.ini"
+"UefiHpkTool.exe"
+"changelog.log"
+"TseDrvHealth.h"
+"setupdbg.h"
+"OEMLogo.bmp"
+[parts]
+"TSEIncludes"
+"AMITSEBoard"
+"TseAdvancedBin"
+"MinisetupBin"
+"TseLiteBin"
+"Uefi20Bin"
+"TseOEM"
+"Uefi21Bin"
+"EzportBin"
+"LegacyBin"
+"EzportPlusBin"
+"PasswordEncodeBin"
+<endComponent>
diff --git a/Core/EM/AMITSE/AMITSE.mak b/Core/EM/AMITSE/AMITSE.mak
new file mode 100644
index 0000000..843907c
--- /dev/null
+++ b/Core/EM/AMITSE/AMITSE.mak
@@ -0,0 +1,614 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/AMITSE.mak 43 5/02/14 9:37a Premkumara $
+#
+# $Revision: 43 $
+#
+# $Date: 5/02/14 9:37a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/AMITSE.mak $
+#
+# 43 5/02/14 9:37a Premkumara
+# [TAG] EIP162662
+# [Category] Improvement
+# [Description] Configuring adding RT access to variable in HPKTool
+# using SDL token
+# [Files] AMITSE.sdl, AMITSE.mak
+#
+# 42 5/02/14 5:40a Arunsb
+# [TAG] EIP156258
+# [Category] Improvement
+# [Description] Providing ELINK option to suppress the handle
+# comparison on dynamic parsing
+# [Files] AMITSE.mak, AMITSE.sdl, commonoem.c, commonoem.h and Parse.c
+#
+# 41 5/02/14 4:39a Premkumara
+# [TAG] EIP95647
+# [Category] Improvement
+# [Description] Dynamic Forms need to hide.
+# [Files] AMITSE.mak, AMITSE.sdl, CommonOem.c, Parse.c
+#
+# 40 5/02/14 3:43a Premkumara
+# [TAG] EIP151966
+# [Category] Improvement
+# [Description] Added the implementation for getting the BIOS build
+# year dynamically
+# from TimeStamp.h file and updated the Build year in copyright message
+# in both Setup and POST.
+# [Files] style.c,style.c,style.c,notify.c,minisetupext.c,CommonHelper
+# .c,
+# AmiTSEStr.uni,AMITSE.mak
+#
+# 39 4/16/14 2:54p Arunsb
+# [TAG] EIP154326
+# [Category] Bug Fix
+# [Severity] Normal
+# [Symptom] Build error if we have more TSE ELinks
+# [RootCause] Make file echo throwing build error if we have too many
+# ELinks
+# [Solution] echo removed and used redirections
+# [Files] amitse.mak
+#
+# 38 2/11/14 7:37p Arunsb
+# Copyright version modified
+#
+# 37 12/04/13 3:00a Premkumara
+# [TAG] EIP139099
+# [Category] New Feature
+# [Description] Supress formset other than
+# EFI_HII_PLATFORM_SETUP_FORMSET_GUID and
+# EFI_HII_DRIVER_HEALTH_FORMSET_GUID through elink based on token
+# [Files] AMITSE.sdl, AMITSE.mak, CommonOem.c, Hii.c, Parse.c,
+# TseUefiHii.h
+#
+# 36 4/18/13 9:56a Arunsb
+# Copyright year changed to 2013
+#
+# 35 4/17/13 1:50a Arunsb
+# [TAG] EIP100539
+# [Category] Improvement
+# [Description] HpkTool should generate proper header for StdDefaults
+# [Files] amitse.mak and uefihpktool.exe
+#
+# 34 3/29/13 8:39a Arunsb
+# [TAG] EIP111061
+# [Category] Improvement
+# [Description] Provide support for efivarstore opcode
+# [Files] Parse.c, amitse.mak and tseuefihii.h
+#
+# 33 3/25/13 8:51a Premkumara
+# [TAG] EIP116315
+# [Category] Improvement
+# [Description] Display control prompt string for password control.
+# (for String on CHAP secret popup)
+# [Files] - AMITSE.sdl
+# - CommonHelper.c
+# - FakeToken.c
+# - AmiTSEStr.uni
+# - TseLite\PopupPassword.c
+# - uefi2.1\UefiWapper21.c
+# - uefi2.0\UefiWapper20.c
+# - uefi2.0\HiiCallback.c
+# - uefi2.0\hii.h
+# - uefi2.0\hii.c
+#
+# 32 2/13/13 2:15a Arunsb
+# [TAG] EIP111742
+# [Category] Improvement
+# [Description] ChangeLogo romhole PI compatibility.
+# Support for romhole with changelogo in PI 0.9 also.
+# [Files] amitse.mak
+#
+# 31 10/18/12 5:30a Arunsb
+# Updated for 2.16.1235 QA submission
+##
+## 21 10/10/12 12:21p Arunsb
+## Synched the source for v2.16.1232 backup with Aptio
+#
+# 29 9/25/12 9:27a Rajashakerg
+# [TAG] EIP92053
+# [Category] Improvement
+# [Description] Need support define Root page order using elinks
+# [Files] AMITSE.sdl, Menu.c, AMIVfr.h, AMITSE.mak, commonoem.c
+#
+# 28 9/25/12 7:47a Rajashakerg
+# [TAG] EIP94424
+# [Category] Improvement
+# [Description] Some form can't normal display when add Hii item will
+# in runtime during
+# [Files] AMITSE.sdl, AMITSE.mak
+#
+# 27 5/29/12 3:01a Arunsb
+# [TAG] EIP91109
+# [Category] Improvement
+# [Description] Sync the Aptio IV source for AptioV
+#
+# 26 4/27/12 9:23a Arunsb
+# [TAG] EIP88895
+# [Category] Improvement
+# [Description] Changing GetUefiSpecVersion as board module hook and
+# also controlling callback spec version from TSE
+# [Files] Amitse.sdl, amitse.mak and commonhelper.c
+#
+# 25 2/03/12 5:43a Premkumara
+# Updated Copyright year to 2012
+#
+# 24 2/02/12 1:08a Premkumara
+# Updated ROMHOLE_GUID with TSE_ROMHOLE_MAKFILE_GUID for ROMHOLE
+#
+# 23 2/02/12 12:41a Premkumara
+# [TAG] EIP75136
+# [Category] New Feature
+# [Description] Generic support for logos in RomHoles
+# [Files] CommomHelper.c, AMITSE.sdl, AMITSE.mak, LogoLib.h
+#
+# 22 1/31/12 1:15p Premkumara
+# [TAG] EIP75136
+# [Category] New Feature
+# [Description] Generic support for logos in RomHoles
+# [Files] CommomHelper.c, AMITSE.sdl, AMITSE.mak, LogoLib.h,
+# Postmgmt.c, AMILogo.h
+#
+# 21 12/21/11 5:09a Arunsb
+# [TAG] EIP70892
+# [Category] Improvement
+# [Description] Provisioning to set manufacturing default language too
+# [Files] amitse.mak and uefihpktoo.exe
+#
+# 20 7/21/11 2:14a Arunsb
+# Copyright version updated to 2011
+#
+# 19 7/01/11 5:20p Madhans
+# [TAG] EIP60910
+# [Category] New Feature
+# [Description] PNG image support in TSE.
+# [Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c,
+# png.h, pnguncmp.c, TseAdvanced.cif
+#
+# 18 6/19/11 4:07p Arunsb
+# [TAG] EIP58712
+# [Category] New Feature
+# [Description] To disable the BIOS Signon Message and TSE copyright
+# version in post screen.
+# [Files] amitse.sdl, amitse.mak, commonhelper.c and notify.c
+#
+# 17 4/29/11 4:26p Arunsb
+# For 2.13 public patch release signon message hiding feature is omitted
+#
+# 15 1/12/11 12:13p Madhans
+# To Update the CopyRight Year in SignOn message.
+#
+# 14 12/28/10 1:48p Mallikarjunanv
+# [TAG] EIP 51007
+# [Category] Improvement
+# [Description] Provided the sdl Token to customize the path of Setup
+# ini
+# [Files] AMITSE.sdl
+# AMITSE.mak
+#
+# 13 12/23/10 6:13p Madhans
+# [TAG] - EIP 50400
+# [Category]- Enhancment
+# [Severity]- Mordarate
+# [Symptom]- Neede Information on the ROM about Logo Type and Size
+# support.
+# [RootCause] - ChangeLogo need to validate of the Logo file is support
+# in the ROM image or not.
+# [Solution]- TSE creates $LGO$ section. Uses SETUP_BMP_LOGO_SUPPORT,
+# SETUP_JPEG_LOGO_SUPPORT, SETUP_GIF_LOGO_SUPPORT SETUP_PCX_LOGO_SUPPORT
+# for Image type support. And Uses MAX_POST_GC_MODE SDL (Assign one of
+# Max GC_MODEx SDL token) token for Size.
+# Clone MAX_POST_GC_MODE SDL token and Update the right Max Mode
+# supported in the project.
+# [Files] - amitse.sdl and amitse.mak
+#
+# 12 9/21/10 6:09p Madhans
+# [TAG] -
+# [Category] BUILD ISSUE FIX
+# [Symptom] Build issues when Build called with Today and Now parameters
+# [RootCause] Dater.mak is not created if today and Now parameters are
+# passed
+# [Solution] use timestamp.mak indtead of dater.mak
+# [Files] amitse.mak
+#
+# 11 9/16/10 8:39p Madhans
+# Updated for TSE 2.10. Refer changelog.log for more deatils.
+#
+## 16 8/27/10 4:54a Mallikarjunanv
+## EIP-39334: support to build TSE without the CSM module support
+##
+## 15 7/28/10 4:47a Mallikarjunanv
+## EIP-29951: TSE Device Path Name support updated
+##
+## 14 7/12/10 4:48p Madhans
+## EIP 39113: Sign ON Message Support.
+##
+## 13 4/21/10 12:13p Madhans
+##
+## 12 4/13/10 5:12p Madhans
+## EIP: 37439 To support extended OEM Key support.
+##
+## 11 4/05/10 10:36a Madhans
+## EIP 37036 : To make TSE 2.01 Binary module to work with older Cores
+##
+## 10 4/02/10 5:02p Madhans
+## EIP 36875. Support to add OEM multiple header files to TSE 2.x.
+##
+## 9 2/26/10 1:28p Madhans
+## Bootonly source module need AMITSEStrTokens.h
+##
+## 8 2/19/10 2:30p Madhans
+##
+## 5 10/28/09 5:34p Madhans
+## 1. Support to Add the String from other modules to TSE.
+## 2. Clean of GIF and Image code Control them with minimal code from TSE
+## binary.
+##
+##
+## 4 9/15/09 9:05a Sudhirv
+## added support for default langue handling
+##
+## 3 7/30/09 7:50a Mallikarjunanv
+## updated the code to move the exit page option elinks to Tse Binary
+##
+## 2 7/14/09 6:32p Blaines
+## For GTSE first Release.,
+##
+## 1 6/04/09 7:49p Madhans
+## AMI TSE Advanced.
+#
+# 2 5/07/09 10:31a Madhans
+# Changes After Bin module.
+##
+## 3 5/06/09 12:28p Mallikarjunanv
+## updated with tse bin support
+##
+## 2 5/05/09 3:26p Madhans
+## include the external UNI in the end to not to affect the index
+##
+## 1 4/28/09 10:24p Madhans
+## Tse 2.0 Code complete Checkin.
+##
+## 2 1/30/09 6:06p Madhans
+## Function headers added.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AMITSE.mak
+#
+# Description: AMI TSE BIN module makefile for Aptio.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+TSE_BINARY_INCLUDES = \
+ -I $(TSEBIN_DIR)\Inc \
+ -I $(TSE_BOARD_DIR) \
+ -I $(PROJECT_DIR)\Include\Protocol
+
+!INCLUDE Build\TimeStamp.mak
+
+!IF "$(TSE_SDBS)"!=""
+TSE_SDBS = -db $(TSE_SDBS: = -db )
+!ENDIF
+
+!IF "$(AMITSE_VERSION)"!=""
+#Dummy variable to append space
+SPACE_APPEND=
+AMITSE_VERSION=$(AMITSE_VERSION) $(SPACE_APPEND)
+!ENDIF
+
+all : AMITSE
+
+!IF "$(TSE_ROMHOLE_SUPPORT)" == "1"
+AMITSE : SetupData SignONPack $(BUILD_DIR)\AMITSE.mak AMITSESDB AMITSEHpk AMITSEBin $(BUILD_DIR)\SmLogo.FFS $(BUILD_DIR)\OEMLogo.FFS ROMHOLESupport $(BUILD_DIR)\ROMHOLE.ffs
+!ELSE
+AMITSE : SetupData SignONPack $(BUILD_DIR)\AMITSE.mak AMITSESDB AMITSEHpk AMITSEBin $(BUILD_DIR)\SmLogo.FFS $(BUILD_DIR)\OEMLogo.FFS
+!ENDIF
+
+$(BUILD_DIR)\AMITSE.mak : $(TSEBIN_DIR)\$(@B).cif $(TSEBIN_DIR)\$(@B).mak $(BUILD_RULES) ELinkList OemHeaderList
+ $(CIF2MAK) $(TSEBIN_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+ElinkList :
+ @copy << $(BUILD_DIR)\AMITSEElinks.h
+
+#define HOOK_LIST_FROM_ELINKS $(AMITSE_Hooks)
+#define CONTROL_KEY_MAP_LIST $(CONTROL_KEY_MAP_LIST)
+#define EXIT_PAGE_OPTIONS_LIST $(EXIT_PAGE_OPTIONS_LIST)
+#define OEM_KEY_CALLBACK_FN $(OEM_KEY_CALLBACK_LIST)
+#define AMITSE_HIDDEN_PAGE_LIST $(AMITSE_HIDDEN_PAGE_LIST)
+#define AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST $(AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST)
+#define AMITSE_ROOT_PAGE_ORDER $(AMITSE_ROOT_PAGE_ORDER)
+#define PASSWORD_ENOCDE_LIST $(PASSWORD_ENOCDE_LIST)
+#define AMITSE_FILTER_CLASSGUID_FORMSETS $(AMITSE_FILTER_CLASSGUID_FORMSETS)
+#define AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST $(AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST)
+#define AMITSE_DYNAMICPARSING_HANDLE_SUPPRESS_LIST $(AMITSE_DYNAMICPARSING_HANDLE_SUPPRESS_LIST)
+
+<<
+
+OemHeaderList:$(AMITSE_OEM_HEADER_LIST) $(BUILD_DIR)\token.mak
+ type << >$(BUILD_DIR)\AMITSEOem.h
+!IF "$(AMITSE_OEM_HEADER_LIST)"!=""
+#include<$(AMITSE_OEM_HEADER_LIST: =>^
+#include<)>
+!ENDIF
+<<
+
+!if "$(UEFI_2_1_SUPPORT)" == "1"
+IFRSUPPORTLIB = $(UEFIEFIIFRSUPPORTLIB)
+!else
+IFRSUPPORTLIB = $(EFIIFRSUPPORTLIB)
+!endif
+
+AMITSE_Objects = $(AMITSE_Objects) \
+ $(BUILD_DIR)\$(TSEBIN_DIR)\bootflow.obj \
+ $(BUILD_DIR)\$(TSEBIN_DIR)\commonoem.obj \
+ $(BUILD_DIR)\$(TSEBIN_DIR)\HookList.obj \
+ $(BUILD_DIR)\$(TSEBIN_DIR)\CommonHelper.obj \
+ $(BUILD_DIR)\$(TSEBIN_DIR)\KeyMon.obj \
+
+
+!if "$(TSE_USE_EDK_LIBRARY)" == "1"
+EDK : AMITSEHpk
+AMITSEBin : $(MINISETUPLIB) $(EFIDRIVERLIB) $(IFRSUPPORTLIB) $(EDKFRAMEWORKGUIDLIB) $(EFIDRIVERLIB)
+!else
+AMITSEBin : $(MINISETUPLIB) $(AMIDXELIB)
+!endif
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMITSE.mak all\
+ "MY_INCLUDES=$(TSE_BINARY_INCLUDES)"\
+ GUID=B1DA0ADF-4F77-4070-A88E-BFFE1C60529A\
+ ENTRY_POINT=MiniSetupApplication\
+ TYPE=BS_DRIVER HAS_RESOURCES=1 LIBRARIES= \
+ RESOURCE=$(BUILD_DIR)\setupdat.bin\
+ SECTION_GUID=FE612B72-203C-47B1-8560-A66D946EB371\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ COMPRESS=1\
+ SDB_FILES=\
+ "VFR_PACKS=$(BUILD_DIR)\AMITSEStr.hpk $(VFR_PACKS)"\
+ "OBJECTS=$(AMITSE_Objects)"\
+ "CFLAGS=$(CFLAGS) /DTSE_FOR_APTIO_4_50 /DTSE_CALLBACK_SPEC_VERSION=$(TSE_CALLBACK_SPEC_VERSION)"
+
+# "STRING_CONSUMERS=$(TSE_STRING_CONSUMERS_LIST)"\
+# "UNI_INCLUDE_PATH=$(TSEBIN_DIR) $(TSE_UNI_INCLUDE_PATH)"\
+
+SetupData :
+#The actual NVRAM size is $(NVRAM_SIZE) - $(NVRAM_HEADER_SIZE)
+ $(ECHO) SET /A NVRAM_SIZE=$(NVRAM_SIZE)-$(NVRAM_HEADER_SIZE) > $(BUILD_DIR)\HPKTOOL.bat
+## EIP-51007: changed the ini file path as sdl Token
+ $(ECHO) $(HPKTOOL) -i$(IFR_DIR_LIST: = -i) -f$(INI_FILE_PATH)\
+ -o$(BUILD_DIR)\setupdata_asm.asm -do$(BUILD_DIR)\NVRAM.bin\
+!IF "$(MANUFACTURING_MODE_SUPPORT)"=="1"
+ -dm -ml$(DEFAULT_LANGUAGE)\
+!ENDIF
+############################################################################
+## Adding RT attribute to DEFAULT_VAR_ATTRIBUTE in command-line
+## based on token RT_ACCESS_SUPPORT_IN_HPKTOOL
+## when token is enabled RT will add to DEFAULT_VAR_ATTRIBUTE to form 0x07
+#############################################################################
+!IF "$(RT_ACCESS_SUPPORT_IN_HPKTOOL)"=="1"
+ -RT\
+!ENDIF
+#############################################################################
+ -dl$(DEFAULT_LANGUAGE)\
+ -ds%%NVRAM_SIZE%% -dp$(SETUP_ORPHAN_PAGES_AS_ROOT_PAGE) -dn$(NVRAM_RECORD_CHECKSUM_SUPPORT) -de$(FLASH_ERASE_POLARITY) -vs$(EFI_SPECIFICATION_VERSION) -h$(AMITSE_HPK_FILE_ORDER) >> $(BUILD_DIR)\HPKTOOL.bat
+ $(BUILD_DIR)\HPKTOOL.bat
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\ $(BUILD_DIR)\setupdata_asm.asm
+ $(ASMLINK) $(BUILD_DIR)\setupdata_asm.obj, $(BUILD_DIR)\setupdat.exe, $(BUILD_DIR)\setupdata_asm.map,,,
+ exe2bin $(BUILD_DIR)\setupdat.exe $(BUILD_DIR)\setupdat.bin
+ -$(DEL) pkgtmp*.tmp
+
+$(BUILD_DIR)\SmLogo.ffs : $(TSEBIN_DIR)\SmLogo.bmp
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=63819805-67BB-46ef-AA8D-1524A19A01E4 \
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ BINFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+
+$(BUILD_DIR)\OEMLogo.ffs : $(OEMLogo_FILE_PATH)
+!IF "$(TSE_OEM_POSTLOGO_SUPPORT)" == "1"
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+# Don't change the GUID. ChangeLogo expects this GUID.
+ GUID=294B1CEF-9BEB-42D5-9971-0C8963CDAF02 \
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ BINFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+!ENDIF
+
+$(BUILD_DIR)\AMITSEStrTokens.h : AMITSEHpk
+
+AMITSEHpk : $(BUILD_DIR)\AMITSE.mak AMITSESDB
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AMITSE.mak all\
+ "UNI_INCLUDE_PATH=$(TSEBIN_DIR) $(TSE_UNI_INCLUDE_PATH)"\
+ STRING_CONSUMERS=$(TSEBIN_DIR)\FakeTokens.c\
+ TYPE=SDB NAME=AMITSE
+
+ $(MAKE) /$(MAKEFLAGS) /a $(BUILD_DEFAULTS) TYPE=SDB\
+ "UNI_INCLUDE_PATH=$(TSEBIN_DIR) $(TSE_UNI_INCLUDE_PATH)"\
+ "STRING_CONSUMERS=$(TSE_STRING_CONSUMERS_LIST)"\
+ "STRGATHER_FLAGS=-db $(BUILD_DIR)\AMITSE.sdb $(TSE_SDBS)"\
+ /f $(BUILD_DIR)\AMITSE.mak $(BUILD_DIR)\AMITSEStrTokens.h
+# EIP-75136 ROMHOLE Support start
+##################################################################################################
+# ROMHOLE generation ##
+# Generating FV_HOLE_VOL.inf file for ROMHole ##
+##################################################################################################
+
+!IF "$(TSE_ROMHOLE_SUPPORT)" == "1"
+
+!IF EXIST ($(BUILD_DIR)\FV_HOLE_VOL.inf )
+ del $(BUILD_DIR)\FV_HOLE_VOL.inf
+!ENDIF
+ echo [options] >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+# This is a dummy base address to store logos in ROMHOLE.This address has no effect in ROMHOLE.
+ echo EFI_BASE_ADDRESS = 0xFFFE0000 >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_FILE_NAME = $(BUILD_DIR)\FV_HOLE_VOL.FV >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_NUM_BLOCKS = $(ROMHOLE_NUMBER_OF_BLOCK) >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_BLOCK_SIZE = $(ROMHOLE_BLOCK_SIZE) >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo IGNORE_COMPRESSION = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo [attributes] >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_READ_DISABLED_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_READ_ENABLED_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_READ_STATUS = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_WRITE_DISABLED_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_WRITE_ENABLED_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_WRITE_STATUS = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_LOCK_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_LOCK_STATUS = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_STICKY_WRITE = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_MEMORY_MAPPED = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ERASE_POLARITY = 1 >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_2 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_4 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_8 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_16 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_32 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_64 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_128 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_256 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_512 = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_1K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_2K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_4K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_8K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_16K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_32K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_ALIGNMENT_64K = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_READ_LOCK_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_READ_LOCK_STATUS = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_WRITE_LOCK_CAP = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_WRITE_LOCK_STATUS = TRUE >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo EFI_FVB2_ALIGNMENT = 8 >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+ echo [files] >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+!IF "$(TSE_OEM_POSTLOGO_SUPPORT)" == "1"
+ echo EFI_FILE_NAME = $(BUILD_DIR)\OEMLogo__.pkg >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+!ENDIF
+ echo EFI_FILE_NAME = $(BUILD_DIR)\Logo__.pkg >> $(BUILD_DIR)\FV_HOLE_VOL.inf
+!ENDIF
+
+ROMHOLESupport:
+!IF $(PI_SPECIFICATION_VERSION) >= 0x00010000
+ $(FWBUILD) Build\ROMHOLE.fv /f $(BUILD_DIR)\FV_HOLE_VOL.inf /p 1.0
+!ELSE
+ $(FWBUILD) Build\ROMHOLE.fv /f $(BUILD_DIR)\FV_HOLE_VOL.inf
+!ENDIF
+
+$(BUILD_DIR)\ROMHOLE.ffs: Build\ROMHOLE.fv
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=$(TSE_ROMHOLE_MAKFILE_GUID)\
+ TYPE=EFI_FV_FILETYPE_RAW\
+ FFS_ALIGNMENT=1 FFS_CHECKSUM=0\
+ RAWFILE=$** FFSFILE=$@ COMPRESS=0 NAME=$(**B)
+
+#####################################################################################################################################
+# EIP-75136 ROMHOLE Support End
+# Signon Pack
+SignONPack :
+ copy << $(BUILD_DIR)\logomode.c
+ #include "token.h"
+ MAX_POST_GC_MODE
+<<
+ copy << $(BUILD_DIR)\logomode.bat
+ $(CP) /EP $(BUILD_DIR)\logomode.c > $(BUILD_DIR)\mode.txt
+ @for /F "tokens=4,5 delims=,}" %%B in ($(BUILD_DIR)\mode.txt) do @(
+ set MAX_X=%%B
+ set MAX_Y=%%C )
+ @echo LOGO_X EQU %MAX_X% > $(BUILD_DIR)\LogoRes.inc
+ @echo LOGO_Y EQU %MAX_Y% >> $(BUILD_DIR)\LogoRes.inc
+<<
+ $(BUILD_DIR)\logomode.bat
+ $(SILENT)copy << $(BUILD_DIR)\sgn.asm > NUL
+.586p
+.model flat,C
+.data
+
+include $(BUILD_DIR)\LogoRes.inc
+!IF "$(SETUP_BMP_LOGO_SUPPORT)" == "1"
+BMP_SUPPORT EQU 01h
+!ELSE
+BMP_SUPPORT EQU 00h
+!endif
+
+!IF "$(SETUP_JPEG_LOGO_SUPPORT)" == "1"
+JPEG_SUPPORT EQU 02h
+!ELSE
+JPEG_SUPPORT EQU 00h
+!endif
+
+!IF "$(SETUP_GIF_LOGO_SUPPORT)" == "1"
+GIF_SUPPORT EQU 04h
+!ELSE
+GIF_SUPPORT EQU 00h
+!endif
+
+!IF "$(SETUP_PCX_LOGO_SUPPORT)" == "1"
+PCX_SUPPORT EQU 08h
+!ELSE
+PCX_SUPPORT EQU 00h
+!endif
+
+!IF "$(SETUP_PNG_LOGO_SUPPORT)" == "1"
+PNG_SUPPORT EQU 10h
+!ELSE
+PNG_SUPPORT EQU 00h
+!endif
+
+
+public _SgnOn
+
+_SgnOn label byte
+
+ db 24h, 'S', 'G', 'N', 24h
+ db 2h
+ dw 0 ;Reserved
+ db '$(AMITSE_VERSION)Copyright (C) %04x American Megatrends, Inc.',0h
+ db '$(BIOS_SIGNON_MESSAGE2)',0h
+ db 24h,'L','G','O',24h
+ db 1h
+ dd BMP_SUPPORT+JPEG_SUPPORT+GIF_SUPPORT+PCX_SUPPORT+PNG_SUPPORT
+ dw LOGO_Y
+ dw LOGO_X
+end
+<<KEEP
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\ $(BUILD_DIR)\sgn.asm
+ $(ASMLINK) $(BUILD_DIR)\sgn.obj, $(BUILD_DIR)\sgn.exe, $(BUILD_DIR)\sgn.map,,,
+ exe2bin $(BUILD_DIR)\sgn.exe $(BUILD_DIR)\sgn.bin
+ $(MAKE) /f Core\FFS.mak BUILD_DIR=$(BUILD_DIR) \
+ GUID=A59A0056-3341-44b5-9C9C-6D76F7673817 \
+ HAS_RESOURCES=1 \
+ RESOURCE=$(BUILD_DIR)\sgn.bin\
+ SECTION_GUID=2EBE0275-6458-4af9-91ED-D3F4EDB100AA\
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ FFSFILE=$(BUILD_DIR)\SignON.FFS COMPRESS=0 NAME=SignON
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, Georgia 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/AMITSE/AMITSE.sdl b/Core/EM/AMITSE/AMITSE.sdl
new file mode 100644
index 0000000..80e26af
--- /dev/null
+++ b/Core/EM/AMITSE/AMITSE.sdl
@@ -0,0 +1,3655 @@
+TOKEN
+ Name = "AMITSE_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AMITSE support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "TSE_MAJOR"
+ Value = "0x02"
+ Help = "TSE Major Version number"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_MINOR"
+ Value = "0x17"
+ Help = "TSE Minor Version number"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_BUILD"
+ Value = "0x1247"
+ Help = "TSE Build number"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_BMP_LOGO_SUPPORT"
+ Value = "1"
+ Help = "BMP Logo support in Setup"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_GIF_LOGO_SUPPORT"
+ Value = "0"
+ Help = "GIF Logo support in Setup"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_JPEG_LOGO_SUPPORT"
+ Value = "0"
+ Help = "JPEG Logo support in Setup."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_PCX_LOGO_SUPPORT"
+ Value = "0"
+ Help = "PCX Logo support in Setup"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_PNG_LOGO_SUPPORT"
+ Value = "0"
+ Help = "PNG Logo support in Setup"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_OEM_FORMAT_LOGO_SUPPORT"
+ Value = "0"
+ Help = "GIF Logo support in Setup"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_GRAYOUT_READONLY_CONTROL"
+ Value = "0"
+ Help = "Diaplay readonly controls as grayout"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_SETUP_GRAYOUT_SELECTABLE"
+ Value = "0"
+ Help = "0 is DEFAULT. set 1=> to allow grayed-out options set focus and to be selectable by the user. Set 0=> to make grayed-out options not to focus and editable"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_POST_GC_MODE"
+ Value = "$(GC_MODE0)"
+ Help = "Port this SDL to select the Maximum Support Graphical module. Should be one of (GC_MODEx SDL tokens). Based on this token logo capability table created."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DEBUG_MESSAGES"
+ Value = "0x0"
+ Help = "A switch to enable TSE Debug messages: Bit0: Uefi functions, Bit1: HiiCallbacks, Bit2: HiiNotifications, Bit3: HiiParsing"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SUPPRESS_PRINT"
+ Value = "1"
+ Help = "A switch to supress TSE Debug messages."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SERIAL_DEBUG"
+ Value = "1"
+ Help = "A switch to print TSE Debug messages over Serial Port."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HPKTOOL"
+ Value = "$(SILENT)$(TSEBIN_DIR)\HPKTOOL"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" "<=" "0x20000"
+End
+
+TOKEN
+ Name = "HPKTOOL"
+ Value = "$(SILENT)$(TSEBIN_DIR)\UefiHPKTOOL"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+End
+
+TOKEN
+ Name = "SETUP_PRINT_ENTER_SETUP_MSG"
+ Value = "1"
+ Help = "Set to 1 to print the Setup Enter messages in POST"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_PRINT_ENTER_BBSPOPUP_MSG"
+ Value = "1"
+ Help = "Set to 1 to print the Setup BBS Popup Menu messages in POST"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ENTRY_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'. Remember to check STR_DEL_ENTER_SETUP string in MiniSetupStr.uni."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ENTRY_SCAN"
+ Value = "EFI_SCAN_DEL"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol. Remember to check STR_DEL_ENTER_SETUP string in MiniSetupStr.uni."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ENTRY_SHIFT_STATE"
+ Value = "0"
+ Help = "Set to one of the defined constants from AMI_KEY_CODE_PROTOCOL."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ALT_ENTRY_ENABLE"
+ Value = "1"
+ Help = "Enable or disable the SETUP_ALT_ENTRY"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ALT_ENTRY_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'. Remember to check STR_DEL_ENTER_SETUP string in MiniSetupStr.uni."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_ALT_ENTRY_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_ALT_ENTRY_SCAN"
+ Value = "EFI_SCAN_ESC"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol. Remember to check STR_DEL_ENTER_SETUP string in MiniSetupStr.uni."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_ALT_ENTRY_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_ALT_ENTRY_SHIFT_STATE"
+ Value = "0"
+ Help = "Set to one of the defined constants from AMI_KEY_CODE_PROTOCOL."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_ALT_ENTRY_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "TSE_ANSI_ESC_CODE_SUPPORT"
+ Value = "0"
+ Help = "Tse advanced Esc colour support"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_TOGGLE_KEY_UNICODE"
+ Value = "L'\t'"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_TOGGLE_KEY_SCANCODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_BBS_POPUP_ENABLE"
+ Value = "0"
+ Help = "Enable or disable the SETUP_BBS_POPUP_ENABLE. CAUTION This works only if complete TSE sources are present."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "POPUP_MENU_ENTRY_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_BBS_POPUP_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "POPUP_MENU_ENTRY_SCAN"
+ Value = "EFI_SCAN_F7"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_BBS_POPUP_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "POPUP_MENU_ENTRY_SHIFT_STATE"
+ Value = "0"
+ Help = "Set to one of the defined constants from AMI_KEY_CODE_PROTOCOL."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_BBS_POPUP_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_ENABLE"
+ Value = "0"
+ Help = "Enable or disable the SETUP_OEM_KEY1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY1_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_SCAN"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY1_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_ENABLE"
+ Value = "0"
+ Help = "Enable or disable the SETUP_OEM_KEY2"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY2_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_SCAN"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY2_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_ENABLE"
+ Value = "0"
+ Help = "Enable or disable the SETUP_OEM_KEY3"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY3_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_SCAN"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY3_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_ENABLE"
+ Value = "0"
+ Help = "Enable or disable the SETUP_OEM_KEY4"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_UNICODE"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol or a character value like L'a'"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY4_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_SCAN"
+ Value = "0x0000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY4_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "TSE_BOOT_ONLY_SPLASH_LOGO_SUPPORT"
+ Value = "1"
+ Help = "Turn on the TSE to make boot only driver without UI"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_RUNTIME_IFR_PROCESSING"
+ Value = "1"
+ Help = "Processes IFR data that are added to hii at runtime. This will cause an increased FW footprint and remove AMIBCP compatibility for those new pages."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_HOOKBASE_VALUE"
+ Value = "0xFFFF0000"
+ Help = "Base value for the HOOK defines that Allows to manage TSE HOOKs.Format 0xXXXX0000,Makeure it is not conflicts physical memory Address"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_PASSWORD_LENGTH"
+ Value = "20"
+ Help = "Default maximum password length. TSE Source needed to change the length"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_MSGBOX_WIDTH"
+ Value = "45"
+ Help = "Set the value to change the message box dispaly width."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_PASSWORD_NON_CASE_SENSITIVE"
+ Value = "1"
+ Help = "Allow to use of case sensitive password. Note:This token should be OFF with SETUP_STORE_KEYCODE_PASSWORD value 1 or 2."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "WIDE_GLYPH_SUPPORT"
+ Value = "1"
+ Help = "Far east language support"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_DEFAULT_TIMEOUT"
+ Value = "10"
+ Help = "Default timeout value before system boots"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_TIMEOUT_IN_TENTHOFSEC"
+ Value = "0"
+ Help = "Maks the Setup Timout value as 1/10 Sec to support fast boot. Makesure to change the Vfr and Strings if this is ON."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_FOR_64BIT"
+ Value = "1"
+ Help = "Enable build support for 64 bit(x64/IA64) TSE"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_CSM_SUPPORT"
+ Value = "1"
+ Help = "Include CSM Support in TSE"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PROGRESSBAR_BACKGROUNDCOLOR"
+ Value = "{0,0,0,0}"
+ Help = "Set the value of progressbar bgcolor in EFI_UGA_PIXEL format"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PROGRESSBAR_BORDERCOLOR"
+ Value = "{0xc0,0xc0,0xc0,0}"
+ Help = "Set the value of progressbar border color in EFI_UGA_PIXEL format"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PROGRESSBAR_FILLCOLOR"
+ Value = "{0xc0,0xc0,0xc0,0}"
+ Help = "Set the value of progressbar fill color in EFI_UGA_PIXEL format"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "POPUP_MENU_SHOW_ALL_BBS_DEVICES"
+ Value = "0"
+ Help = "1 => Shows all BBS devices in BBS POPup menu. 0 => Shows only the first device of a BBS type in BBS POPUP menu."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_SHOW_ALL_BBS_DEVICES"
+ Value = "0"
+ Help = "1 => Shows all BBS devices in boot override menu. 0 => Shows only the first device of a BBS type in override menu."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DEVICE_PATH_NAME"
+ Value = "0"
+ Help = "Turn on to be able to configure name for legacy devices."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DEVICE_PATH_UEFI_NAME"
+ Value = "1"
+ Help = "Turn on to be able to configure name for UEFI devices using Device path."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "TSE_DEVICE_PATH_NAME" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_BOOT_NOW_IN_BOOT_ORDER"
+ Value = "0"
+ Help = "Turn on to see boot override/BBS Popup menu with in the devices listed in boot order."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_CLEAR_USERPW_WITH_ADMINPW"
+ Value = "0"
+ Help = "Support to clear the User password if Admin password is empty"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_USE_AMI_DEFAULTS"
+ Value = "1"
+ Help = "Use AMIBCP compatible defaults instead of HII defaults"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_LOAD_PASSWORD_ON_DEFAULTS"
+ Value = "0"
+ Help = "Loads the User/Admin password from Defaults.If Off, Passwords are unaffected while loading defaults"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MINISETUP_MOUSE_SUPPORT"
+ Value = "0"
+ Help = "Mouse suport."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OLD_MOUSE_DRIVER_SUPPORT"
+ Value = "0"
+ Help = "Old Mouse Driver Mouse suport."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "MINISETUP_MOUSE_SUPPORT" "!=" "0"
+End
+
+TOKEN
+ Name = "SINGLE_CLICK_ACTIVATION"
+ Value = "0"
+ Help = "On- Single click will be used to enter the subMenu and Select the option. OFF- Double Click will be used."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL"
+ Value = "1"
+ Help = "AMIKeyCode Protocol support. TSE Sources need to be present to disable this token"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_STORE_KEYCODE_PASSWORD"
+ Value = "0"
+ Help = "For Extened Password support, the Value can be 1 or 2. Set Value as 1 to support Efi Key as password. Set Value as 2 to support Scan Code in password. Need AMIKeyCode Protocol & TSE sources support, Set Value as 0 to support Unicode in password, which is the default"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_PRINT_EVAL_MSG"
+ Value = "0"
+ Help = "Enable/Disable Evaluation message in Post screen"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_PRN_SCRN_EVENT_SUPPORT"
+ Value = "0"
+ Help = "Turn on to generate Print screen event if TSE_PRN_SCRN_KEY_SCAN key pressed."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "STYLE_DATE_FORMAT"
+ Value = "0"
+ Help = "Controls the Date Format. (Default 0 => mm/dd/yyyy) (1 => yyyy/dd/mm)"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-3"
+End
+
+TOKEN
+ Name = "STYLE_SHOW_DAY"
+ Value = "1"
+ Help = "Controls the display of Day in Date Format."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_USER_PASSWORD_POLICY"
+ Value = "1"
+ Help = "Allow to use system with Admin password set and User password NOT set (Boot Password policy)"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_SUPPORT_PLATFORM_LANG_VAR"
+ Value = "0"
+ Help = "Set to enable PlatformLang and PlatformLangCode Vars."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_SUPPORT_ADD_BOOT_OPTION"
+ Value = "0"
+ Help = "Set to enable Add/Delete boot option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_SUPPORT_ADD_DRIVER_OPTION"
+ Value = "0"
+ Help = "Set to enable Add/Delete Driver option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_SUPPORT_RES_ADD_DEL_BOOT_OPTION_NAME"
+ Value = "0"
+ Help = "Not to allow Reserved Names (RESERVED_ADD_DEL_BOOT_OPTION_NAME) for new Boot Options. Reserved names defined in RESERVED_ADD_DEL_BOOT_OPTION_NAME SDL token"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "SETUP_SUPPORT_ADD_BOOT_OPTION" "=" "1"
+End
+
+TOKEN
+ Name = "RESERVED_ADD_DEL_BOOT_OPTION_NAME"
+ Value = "UEFI:"
+ Help = "Reserved names that are not allowed to use for add or delete boot options"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_SUPPORT_RES_ADD_DEL_BOOT_OPTION_NAME" "=" "1"
+End
+
+TOKEN
+ Name = "SETUP_ENTRY_LEGACY_CODE"
+ Value = "0x53"
+ Help = "Set legacy scan code for entry key."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ALT_ENTRY_LEGACY_CODE"
+ Value = "0x3c"
+ Help = "Set legacy code for Alternate entry key"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_ALT_ENTRY_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "POPUP_MENU_ENTRY_LEGACY_CODE"
+ Value = "0x41"
+ Help = "Set legacy scan code for popup menu entry"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_BBS_POPUP_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_LEGACY_CODE"
+ Value = "0x0"
+ Help = "Set legacy code for OEM key 1"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY1_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_EFIKEY"
+ Value = "0x5F"
+ Help = "Set to one of the defined EFI_KEY enumeration"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY1_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_SHIFT"
+ Value = "0x00000000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY1_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY1_TOGGLE"
+ Value = "0x00"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY1_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_LEGACY_CODE"
+ Value = "0x0"
+ Help = "Set legacy code for OEM key 2"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY2_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_EFIKEY"
+ Value = "0x00"
+ Help = "Set to one of the defined EFI_KEY enumeration"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY2_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_SHIFT"
+ Value = "0x00000000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY2_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY2_TOGGLE"
+ Value = "0x00"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY2_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_LEGACY_CODE"
+ Value = "0x0"
+ Help = "Set legacy code for OEM key 3"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY3_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_EFIKEY"
+ Value = "0x00"
+ Help = "Set to one of the defined EFI_KEY enumeration"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY3_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_SHIFT"
+ Value = "0x00000000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY3_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY3_TOGGLE"
+ Value = "0x00"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY3_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_LEGACY_CODE"
+ Value = "0x0"
+ Help = "Set legacy code for OEM key 4"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY4_ENABLE" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_EFIKEY"
+ Value = "0x00"
+ Help = "Set to one of the defined EFI_KEY enumeration"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY4_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_SHIFT"
+ Value = "0x00000000"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY4_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_OEM_KEY4_TOGGLE"
+ Value = "0x00"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT_EX protocol"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_OEM_KEY4_ENABLE" "!=" "0"
+ Token = "TSE_USE_AMI_EFI_KEYCODE_PROTOCOL" "!=" "0"
+End
+
+TOKEN
+ Name = "SETUP_SUPPORT_KEY_MONITORING"
+ Value = "0"
+ Help = "Enable or Disable monitoring keys during Legacy mode"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_STORE_EFI_KEY_PASSWORD"
+ Value = "0"
+ Help = "This Token becomes Obsolete after adding the Token SETUP_STORE_KEYCODE_PASSWORD. / Enables support to store EFI_KEYs as password. TSE Sources should be required to present to Enable this token."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_CAPITAL_BOOT_OPTION"
+ Value = "0"
+ Help = "This Token Stores/Creates the Boot Option numbers to Capital Hex Numbers"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "CORE_COMBINED_VERSION" "<" "0x40281"
+End
+
+TOKEN
+ Name = "TSE_CAPITAL_BOOT_OPTION"
+ Value = "1"
+ Help = "This Token Stores/Creates the Boot Option numbers to Capital Hex Numbers"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "CORE_COMBINED_VERSION" ">=" "0x40281"
+End
+
+TOKEN
+ Name = "SETUP_IDE_SECURITY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "SECURITY_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PASSWORD_WITH_SPECIAL_CHAR_SUPPORT"
+ Value = "1"
+ Help = "0 => Only alphanumeric characters are support in the Password 1 => Also supports printable special characters."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_LINK_HISTORY_SUPPORT"
+ Value = "1"
+ Help = "Preserves navigation history of Ref linked pages. Pressing the <ESC> returns control to the previous page if the current page was linked from a REF control."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_DISPLAY_SUBMENU_PAGETITLE"
+ Value = "0"
+ Help = "Displays page title of submenu pages in the menu tab."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_GROUP_DYNAMIC_PAGES"
+ Value = "1"
+ Help = "Allows Dynamic IFR Pages to be relocated under subpages. Make sure to have the VFR changes to show the dynamic pages"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ORPHAN_PAGES_AS_ROOT_PAGE"
+ Value = "0"
+ Help = "Allows Orphan IFR Pages to be relocated to root pages."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ITK_COMPATIBILITY"
+ Value = "0"
+ Help = "Enables and disables ITK compatibility. Need customization in Board module to support ITK projects."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NO_VARSTORE_SUPPORT"
+ Value = "0"
+ Help = "Enables and disables no var store support. This needs modification of VFRs. Need customization of board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_CONTINUE_BOOT_NOW_ON_FAIL"
+ Value = "1"
+ Help = "Turn on to continue boot to other device when selected one fails."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_UPDATE_BOOT_ORDER_CURSOR"
+ Value = "0"
+ Help = "When the boot order is changed, the cursor moves with the selection. Else, the cursor remains in the same location as the current question."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_PRESERVE_DISABLED_BBS_DEVICE_ORDER"
+ Value = "0"
+ Help = "Prevents TSE from repositioning disabled BBS boot in the boot order."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_BOOT_TIME_OUT_AS_ZERO"
+ Value = "0"
+ Help = "1=>Provides Boot time out value as zero 0=> Reads from the NVRAM, defaultly it is disabled."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_SAVE_DISABLED_BBS_DEVICEPATH"
+ Value = "1"
+ Help = "1 => Saves the DevicePaths of Disabled BBS devices to NVRAM Variable. \Depends on that varaible to keep device disbaled in next boot. \0 => Doesn't save the Disabled BBS devicepath."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_POSTSCREEN_SCROLL_AREA"
+ Value = "{0,0,24,80}"
+ Help = "Format:{TopRow, TopCol, BottomRow, BottomCol}. Used to Configure the TSE PostScreen Scroll Area. Note Post message are still printed in whole Screen."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DRIVER_HEALTH_SUPPORT"
+ Value = "1"
+ Help = "1 = Enabling Driver health support in TSE and 0 = Disabling Driver health support in TSE."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">=" "0x20014"
+End
+
+TOKEN
+ Name = "HONOR_DRVHLTH_CONFIGREQD_ON_BOOTFAIL"
+ Value = "0"
+ Help = "1 => If driver need to be configured during the device boot then this token should be enabled to display the form produced from dirver health protocol & 0 => Disables the form produced by the driver health protocol."
+ TokenType = Integer
+ TargetH = Yes
+ Token = "DRIVER_HEALTH_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "EDK_1_05_RETRIEVE_DATA"
+ Value = "1"
+ Help = "1=>If UEFI>=2.1 and Core>=4.6.5.1.Modified code to return BrowserCallback String according to either EDK browser or spec.Please be careful when to change this to 0, May cause Addon Card to not to work."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">=" "0x2000A"
+ Token = "CORE_COMBINED_VERSION" ">=" "0x4028B"
+End
+
+
+TOKEN
+ Name = "EDK_1_05_RETRIEVE_DATA"
+ Value = "0"
+ Help = "0=>If UEFI>=2.1 and Core<4.6.5.1.Modified code to return BrowserCallback String according to either EDK browser or spec.Please be careful when to change this to 0, May cause Addon Card to not to work."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">=" "0x2000A"
+ Token = "CORE_COMBINED_VERSION" "<" "0x4028B"
+End
+
+TOKEN
+ Name = "TSE_USE_OEM_ACTION_READ_KEY"
+ Value = "0"
+ Help = "If user likes to read the key in their own way then enable this token and define _OemActionReadKey function."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SECONDARY_BOOT_FROM_ENABLED_DEVICES"
+ Value = "0"
+ Help = "0-> Loads \EFI\BOOT\BOOT{machine type short-name}.EFI from any of the devices & 1-> Loads the default image only from enabled devices"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST_SUPPORT"
+ Value = "0"
+ Help = "1 -> Shows subpages as root page & 0 -> Shows subpages as is"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMITSE_HIDE_ROOT_PAGE"
+ Value = "0"
+ Help = "1 -> Hides the root page & 0 -> The support is disabled"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_CheckIsAllowedPasswordChar"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the CheckIsAllowedPasswordChar function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPasswordFormCallback"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PopupPasswordFormCallback function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPwdHandleActionOverRide"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PopupPwdHandleActionOverRide function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PasswordCheckInstalled"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PasswordCheckInstalled function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PasswordAuthenticate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PasswordAuthenticate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PasswordUpdate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PasswordUpdate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PasswordCommitChanges"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PasswordCommitChanges function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPasswordCheckInstalled"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PopupPasswordCheckInstalled function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPasswordAuthenticate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PopupPasswordAuthenticate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_NoVarStoreSupport"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the NoVarStoreSupport function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_NoVarStoreUpdateSystemAccess"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the NoVarStoreUpdateSystemAccess function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_ItkSupport"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the ItkSupport function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_BbsItkBoot"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the BbsItkBoot function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_GetAMITSEVariable"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the GetAMITSEVariable function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_GetBootTimeOut"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the GetBootTimeOut function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_VarBuildItkDefaults"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the VarBuildItkDefaults function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_SetSystemAccessValueItk"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the SetSystemAccessValueItk function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_FindVarFromITKQuestionId"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the FindVarFromITKQuestionId function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_IsOEMLogoType"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the IsOEMLogoType function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_ConvertOEMFormatToUgaBlt"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the ConvertOEMFormatToUgaBlt function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_CleanUpOEMLogo"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the CleanUpOEMLogo function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_DoOEMLogoAnimate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the DoOEMLogoAnimate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_BBSBuildName"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the BBSBuildName function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_BBSGetNonStandardGroupType"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the BBSGetNonStandardGroupType function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_FramePwdCallbackIdePasswordUpdate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the FramePwdCallbackIdePasswordUpdate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPwdAuthenticateIDEPwd"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PopupPwdAuthenticateIDEPwd function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPwdUpdateIDEPwd"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the PopupPwdUpdateIDEPwd function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordGetName"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordGetName function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordAuthenticate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordAuthenticate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordUpdate"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordUpdate function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordGetDataPtr"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordGetDataPtr function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordGetLocked"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordGetLocked function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordCheck"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordCheck function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEPasswordFreezeDevices"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEPasswordFreezeDevices function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEUnlockHDD"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEUnlockHDD function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSESetHDDPassword"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSESetHDDPassword function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIDEUpdateConfig"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEIDEUpdateConfig function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OEMSpecialGetControlCount"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the OEMSpecialGetControlCount function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OEMSpecialOneOfFixup"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the OEMSpecialOneOfFixup function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OEMSpecialUpdateOneOf"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the OEMSpecialUpdateOneOf function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OEMSpecialGotoFixup"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the OEMSpecialGotoFixup function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OEMSpecialGotoSelect"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the OEMSpecialGotoSelect function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseInitHook"
+ Value = "0"
+ Help = "set to 1 if oem/Modules wants to override the TSEMouseInitHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseStopHook"
+ Value = "0"
+ Help = "set to 1 if oem/Modules wants to override the TSEMouseStopHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseDestoryHook"
+ Value = "0"
+ Help = "set to 1 if oem/Modules wants to override the TSEMouseDestoryHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseRefreshHook"
+ Value = "0"
+ Help = "set to 1 if oem/Modules wants to override the TSEMouseRefreshHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseStartHook"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEMouseStartHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseIgnoreMouseActionHook"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEMouseIgnoreMouseActionHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEStringReadLoopEntryHook"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEStringReadLoopEntryHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEStringReadLoopExitHook"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the TSEStringReadLoopExitHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_GetMessageboxColorHook"
+ Value = "0"
+ Help = "Set to 1 if oem wants to override the GetMessageboxColorHook function from Board module"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_GOPSetScreenResolutionHook"
+ Value = "0"
+ Help = "Set to 1 if oem wants to override the GOPSetScreenResolutionHook function from Board module"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_LaunchHotKeyBootOption"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the LaunchHotKeyBootOption function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_DriverHealthSystemReset"
+ Value = "0"
+ Help = "set to 1 if oem wants to override the DriverHealthSystemReset function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_UefiBootFailHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the OVERRIDE_UefiBootFailHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_LegacyBootFailHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the OVERRIDE_LegacyBootFailHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_UpdateNumericDisplayString"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the UpdateNumericDisplayString function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_MainSetupLoopHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the MainSetupLoopHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_MainSetupLoopInitHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the MainSetupLoopInitHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_ProcessBrowserActionRequestHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the ProcessBrowserActionRequestHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OEMCheckControlCondition"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the OemCheckControlCondition function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_GetUefiSpecVersion"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the GetUefiSpecVersion function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseInit"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseInit function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseStop"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseStop function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEIsMouseClickedonSoftkbd"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEIsMouseClickedonSoftkbd function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseRefresh"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseRefresh function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseStart"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseStart function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseFreeze"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseFreeze function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEGetCoordinates"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEGetCoordinates function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseReadInfo"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseReadInfo function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEMouseDestroy"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEMouseDestroy function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSEGetactualScreentop"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSEGetactualScreentop function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSENumericSoftKbdInit"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSENumericSoftKbdInit function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TSENumericSoftKbdExit"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TSENumericSoftKbdExit function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_LaunchSecondaryBootPath"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the LaunchSecondaryBootPath function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_OsUpdateCapsuleWrap"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the OsUpdateCapsuleWrap function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_UIUpdateCallbackHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the UIUpdateCallback function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_FixMergePagesExtraHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the FixMergePagesExtraHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PageRemoveHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the PageRemoveHook function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_ProcessPackNotificationHook"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the ProcessPackNotification function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_CsmBBSBootOptionName"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the CsmBBSBootOptionName function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MSGBOX_PROGRESS_BAR_SEGMENT_COUNT"
+ Value = "20"
+ Help = "Mod of 100 with this number should be 0, for example (100 % 20 = 0)."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CONTRIB_BGRT_TABLE_TO_ACPI"
+ Value = "1"
+ Help = "Set to Contribute the BGRT table to ACPI."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BIOS_SIGNON_MESSAGE2"
+ Value = "BIOS Date: $(TODAY) $(NOW) Ver: $(PROJECT_TAG)$(PROJECT_MAJOR_VERSION)$(PROJECT_MINOR_VERSION)"
+ Help = "BIOS Sign On Message"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_APTIO_5_SUPPORT"
+ Value = "0"
+ Help = "Turn on to to build under Aptio 5"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_USE_GETGYLPH_PRINTLENGH"
+ Value = "0"
+ Help = "Turn on to to build under Aptio 5"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INI_FILE_PATH"
+ Value = "$(TSEBIN_DIR)\setup.ini"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" "<=" "0x20000"
+End
+
+TOKEN
+ Name = "INI_FILE_PATH"
+ Value = "$(TSEBIN_DIR)\uefisetup.ini"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+End
+
+TOKEN
+ Name = "SETUP_HIDE_DISABLE_BOOT_OPTIONS"
+ Value = "0"
+ Help = "1 => Hide the disabled boot options in boot override menu. 0 => Shows all boot options boot override menu."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "POPUP_MENU_HIDE_DISABLE_BOOT_OPTIONS"
+ Value = "0"
+ Help = "1 => Hide the disabled boot options in BBS POPup menu. 0 => Shows all boot options in BBS POPup menu."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_LOAD_OPTION_HIDDEN"
+ Value = "1"
+ Help = "1 => Hide LOAD_OPTION_HIDDEN Boot option. 0 => Shows all boot options."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">" "0x20000"
+End
+
+TOKEN
+ Name = "SETUP_HIDE_BIOS_SIGNON_MESSAGE2"
+ Value = "0"
+ Help = "1 => Hides the BIOS signon message. 0 => Shows the BIOS sign on message."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMITSE_VERSION"
+ Value = "Version %x.%02x.%04x."
+ Help = "TSE Version for displaying in the init screen. If no need of version to display then use empty string, if changing the format specifiers then care should be taken in source."
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_FLOW_NORMAL_LAUNCH_DEFAULT_BOOTIMAGE"
+ Value = "1"
+ Help = "Support for UEFI specification v 2.3.1 section 3.4.1.1 and 3.4.1.2 to load the default boot image (efi\boot\boot####.efi) from any of the available file system if no boot option found. 1 = Enabling default image boot and 0 = Disabling default image boot."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_FLOW_NORMAL_INFINITE_LOOP"
+ Value = "0"
+ Help = "1 = TSE tries to loads all the boot options and all fails checks for SETUP_ENTRY keys if found then enters the setup else TSE tries to load all the boot options once again and continues the mentioned procedure infinitely and 0 = Neglects the SETUP_ENTRY key check, always tries to load all the boot options infinitely."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "STYLE_HELP_AREA_SCROLLBAR"
+ Value = "0"
+ Help = "Support Scrollable Help Text"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_MULTILINE_CONTROLS"
+ Value = "0"
+ Help = "Turns on multi line controls. Currently subtitle and static text controls are supported. Default is DISABLE"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_ROMHOLE_SUPPORT"
+ Value = "0"
+ Help = "Enable to support ROMHOLE generation."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_ROMHOLE_SUPPORT"
+ Value = "1"
+ Help = "Enable to support ROMHOLE generation. Default enable with secure boot module support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "SecureMod_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_OEM_POSTLOGO_SUPPORT"
+ Value = "0"
+ Help = "Enable to support OEMLogo image in postscreen."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OEMLogo_FILE_PATH"
+ Value = "$(TSEBIN_DIR)\OEMLogo.bmp"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "TSE_OEM_POSTLOGO_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_ROMHOLE_MAKFILE_GUID"
+ Value = "05ca020b-0fc1-11dc-9011-00173153eba8"
+ Help = "One among 16-GUID used to identify ROMHOLE by AMI utilities such as AFU, BCP, and MMTool. If TSE_ROMHOLE_MAKFILE_GUID token value is changed then TSE_ROMHOLE_HEADER_GUID token value should update "
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_ROMHOLE_HEADER_GUID"
+ Value = "{0x05ca020b, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8}"
+ Help = "One among 16-GUID used to identify ROMHOLE by AMI utilities such as AFU, BCP, and MMTool. This value should sync with TSE_ROMHOLE_MAKFILE_GUID token value"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ROMHOLE_BLOCK_SIZE"
+ Value = "0x10000"
+ Help = "Size of Block used for ROMHOLE"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ROMHOLE_NUMBER_OF_BLOCK"
+ Value = "2"
+ Help = "Number of Block used for ROMHOLE"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_CALLBACK_SPEC_VERSION"
+ Value = "EFI_SPECIFICATION_VERSION"
+ Help = "Version to change the callback functionality"
+ TokenType = Integer
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "OSIndication_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Help = "Main token to disable or enable the OSIndication Support. If disable then OSIndication module can be used"
+End
+
+TOKEN
+ Name = "SETUP_DELAY_LOGO_TILL_INPUT"
+ Value = "0"
+ Help = "DISABLE is default. 1 => delays logo display untill SIMPLE TEXT IN protocol is available.0 => logo is displayed as soon as UGA DRAW, CONSOLE SPLITTER & SIMPLE TEXT OUT IS AVAILABLE (Will increase code size)."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_DELAY_POST_TILL_GOP"
+ Value = "1"
+ Help = "ENABLE is default.Wait for GOP"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DRAW_POST_LOGO_AT_0POS"
+ Value = "0"
+ Help = "Displays the post logo at top(0,0) graphics position. Disable by default make it 1 to avail this feature"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_IGNORE_KEY_FOR_FASTBOOT"
+ Value = "0"
+ Help = "DISABLE is default. 1=> To ignore check for key when FastBoot is enabled. 0=> Allow check for key when FastBoot is enabled"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_CURSOR_SUPPORT"
+ Value = "1"
+ Help = "Token to display cursor for string, password type controls.ENABLE is default.1=>To display cursor in TSE.0=>Not to display cursor in TSE"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SUPPORT_ESRT"
+ Value = "1"
+ Help = "Enable to support ESRT"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "CORE_COMBINED_VERSION" ">=" "0x4028e"
+End
+
+TOKEN
+ Name = "TSE_SUPPORT_NATIVE_RESOLUTION"
+ Value = "1"
+ Help = "Sets the graphics mode for quiet boot from EDID. 1 - Defaultly enable make 0 to disable the feature"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_OVERRIDE_BOOTNEXT_VARIABLE_FEATURE"
+ Value = "0"
+ Help = "DISABLE is default.1=> To show menu for BootOverride options to modifiy BootNext variable when BootNext variable is supported by project. 0=> Not to show menu for BootOverride options"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_SUPPRESS_MULTILINE_FOR_ONEOFLABEL"
+ Value = "0"
+ Help = "1=> is to suppress multiline support for one of option . 0=> is to support multiline for one of option which is defalut behaviour"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "TSE_MULTILINE_CONTROLS" "=" "1"
+End
+
+TOKEN
+ Name = "SETUP_SAVE_PSWD_TO_NVRAM"
+ Value = "0"
+ Help = "1 => Save password to Nvram. 0 => Save password to cache."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DONOT_LOAD_PASSWORD_ON_DEFAULTS"
+ Value = "0"
+ Help = "1 => Will not load defaults for password when we press F3. 0 => Load default passowrd."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SHELL_TEXT_MODE"
+ Value = "0xFF"
+ Help = "Assign the GC_MODE while boot to SHELL.\0xFF = ignored, 0/1/2/.. = GC_MODE0/GC_MODE1/GC_MODE2/.."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FLUSH_KEYS_AFTER_READ"
+ Value = "1"
+ Help = "Disable to flush the key buffer."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_LOAD_DEFAULTS_FROM_DEFAULTS_BUFFER"
+ Value = "1"
+ Help = "0 => Will not load defaults from Default buffer(NVRAM.bin) on pressing F3. 1 => Will Load default from the default buffer."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMITSE_ROOT_PAGE_ORDER_SUPPORT"
+ Value = "0"
+ Help = "1 => Enable the Root Page Order support for TSE. 0 => Disable the Root Page Order support for TSE."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_ROOT_PAGE_ORDER_GUID"
+ Value = " { 0x9204ecbe, 0xa665, 0x49d3, 0x86, 0xde, 0x8, 0x12, 0x99, 0xe2, 0x23, 0xef }"
+ Help = "Setup root Page Order Guid"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY"
+ Value = "0"
+ Help = "DISABLE is default.Set to ENABLE to goto Exit page on pressing ESC key. If Enabled, on Pressing ESC key, by default it will go to Exit page.If user needs to change the page then user has provide proper FormID in the dependency tokens"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EXIT_PAGE_GUID"
+ Value = "{0xa43b03dc, 0xc18a, 0x41b1, 0x91, 0xc8, 0x3f, 0xf9, 0xaa, 0xa2, 0x57, 0x13}"
+ Help = "GUID used to identify exit page"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY" "!=" "0"
+ Token = "EFI_SPECIFICATION_VERSION" ">=" "0x2000A"
+End
+
+TOKEN
+ Name = "EXIT_PAGE_GUID"
+ Value = "{0xEC87D643, 0xEBA4, 0x4BB5, 0xA1, 0xE5, 0x3F, 0x3E, 0x36, 0xB2, 0x0D, 0xA9}"
+ Help = "GUID used to identify exit page"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY" "!=" "0"
+ Token = "EFI_SPECIFICATION_VERSION" "<" "0x2000A"
+End
+
+TOKEN
+ Name = "EXIT_PAGE_CLASS"
+ Value = "0x20"
+ Help = "Exit Page Formset class"
+ TokenType = Integer
+ TargetH = Yes
+ Token = "SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY" "!=" "0"
+End
+
+TOKEN
+ Name = "EXIT_PAGE_SUB_CLASS"
+ Value = "0"
+ Help = "Exit Page Formset Subclass"
+ TokenType = Integer
+ TargetH = Yes
+ Token = "SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY" "!=" "0"
+End
+
+TOKEN
+ Name = "EXIT_PAGE_FORM_ID"
+ Value = "EXIT_MAIN"
+ Help = "Exit Page ID"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY" "!=" "0"
+End
+
+TOKEN
+ Name = "TSE_SHOW_PROMPT_STRING_AS_TITLE"
+ Value = "0"
+ Help = "0 is DEFAULT.1 => To use password control's prompt's string for Password Title. 0 => To use standard TSE string for Password Title."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DONOT_LOAD_SYSTEM_ACCESS_FOR_USER_DEFAULT"
+ Value = "0"
+ Help = "0 is DEFAULT.1 => To enable to not to load SystemAccess variable on pressing Restore User Default. 0=> To load SystemAccess variable on pressing Restore User Default"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SHOW_FORMSETS_WITH_CLASSGUID"
+ Value = "1"
+ Help = "0 is DEFAULT.1 => To display formset based on formset ClassGUID in elink AMITSE_FILTER_CLASSGUID_FORMSETS(By default this elink will have EFI_HII_PLATFORM_SETUP_FORMSET_GUID and EFI_HII_DRIVER_HEALTH_FORMSET_GUID). 0 => To display all formset and no filter in formsets."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DBG_DISABLE_APPDESTRUCTOR"
+ Value = "0"
+ Help = "0 => Free the TSE used memory. 1 => Won't free the TSE used memory, may be used only for debugging purposes. CAUTION: If making the token to 1 then TSE won't free the memory it used. We recommend not to make it enable."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_HASH_PASSWORD"
+ Value = "0"
+ Help = "0 is Default. 1 => To encode the entered password using hash algorithm. 0 => Encode entered password using TSE logic."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "CryptLib_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "AMITSE_SUPPRESS_DYNAMIC_FORMSET"
+ Value = "0"
+ Help = "0 is Default. 1 -> To suppress dynamic formset mentioned in elink AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST and do not show in setup. 0 -> Display dynamic page and not to suppress dynamic page"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SUPPRESS_HANDLE_FOR_VAR_CREATION"
+ Value = "0"
+ Help = "0 is DEFAULT.0 => Includes handle comparison to create new variable cache in TSE. 1 => Won't compare handle to create new variable. The variable detail should present in AMITSE_DYNAMICPARSING_HANDLE_SUPPRESS_LIST to not compare handle"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_GetGraphicsBitMapFromFV"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the GetGraphicsBitMapFromFV function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_CheckAdvShiftState"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the CheckAdvShiftState function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_LaunchSecBootPathFromEnabledDevs"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the LaunchSecBootPathFromEnabledDevs function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_FramePasswordAdvancedCallback"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the FramePasswordAdvancedCallback function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TseLaunchFileSystem"
+ Value = "0"
+ Help = "set to 1 if OEM wants to override the TseLaunchFileSystem function from Board module."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_DEFAULT_SETUP_PASSWORD_SUPPORT"
+ Value = "0"
+ Help = "0 is default.set 1=> to Enable default setup password"
+ TokenType = Expression
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SETUP_PWD_AT_FIRSTBOOT_ONLY"
+ Value = "1"
+ Help = "1 is default. 1 => Sets the TSE_ADMIN_PASSWORD and TSE_USER_PASSWORD at first boot only. 0 => Sets TSE_ADMIN_PASSWORD and TSE_USER_PASSWORD in TSE defaults, on load defaults these data will be loaded"
+ TokenType = Expression
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "TSE_DEFAULT_SETUP_PASSWORD_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_ADMIN_PASSWORD"
+ Value = "EMPTY_DATA"
+ Help = "Defaultly no password is given. Need TSE source to change this. Provide data to set as default admin password. Maximum string can be provide is based on SETUP_PASSWORD_LENGTH token. String should be atleat minimum length mentioned in vfr. If no password is given it will not set any default password. Note: specify EMPTY_DATA in value if default admin password is not required"
+ TokenType = Expression
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "TSE_DEFAULT_SETUP_PASSWORD_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "TSE_USER_PASSWORD"
+ Value = "EMPTY_DATA"
+ Help = "Defaultly no password is given. Need TSE source to change this. Provide data to set as default user password. Maximum string can be provide is based on SETUP_PASSWORD_LENGTH token. String should be minimum length mentioned in vfr. If no password is given it will not set any default password. Note: specify EMPTY_DATA in value if default user password is not required"
+ TokenType = Expression
+ TargetH = Yes
+ TargetMAK = Yes
+ Token = "TSE_DEFAULT_SETUP_PASSWORD_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "RT_ACCESS_SUPPORT_IN_HPKTOOL"
+ Value = "0"
+ Help = "0 is default no RT flag for variables. 1=> enable to add RT attribute for variables, uefisetup.ini attributes persists"
+ TokenType = Expression
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "DISABLE_ESC_IN_BBS"
+ Value = "0"
+ Help = "0 is DEFAULT.1 => To disable ESC behaviour in BBS menu and retain in BBS menu. 0 => To enable ESC behaviour in BBS menu."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_SUPPORT_DEFAULT_FOR_STRING_CONTROL"
+ Value = "0"
+ Help = "0 is DEFAULT. 1 => To construct optimal and failsafe defaults for STRING type controls based on CONTROLPtr from controlInfo.0 => Not to construct and load optimal and failsafe defaults for STRING type controls."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TSE_BEST_TEXT_GOP_MODE"
+ Value = "0"
+ Help = "0 is DEFAULT.1 => To save and restore text(100*31) and GOP(800*600) mode before using any TSE Interfaces in post/after TSE. 0 => Not to handle text and GOP mode before using any TSE interfaces in post/after TSE and use post mode without any change."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "TSEBIN_DIR"
+End
+
+MODULE
+ Help = "Includes AMITSE.mak to Project"
+ File = "AMITSE.mak"
+End
+
+ELINK
+ Name = "DrawQuietBootLogoHook,"
+ Parent = "HOOK1,"
+ Priority = 1
+ Help = "Anchor for hook #1 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK1,"
+ Parent = "AMITSE_Hooks"
+ Priority = 1
+ Help = "Anchor for hook #1 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK2,"
+ Parent = "AMITSE_Hooks"
+ Priority = 2
+ Help = "Anchor for hook #2 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessConInAvailabilityHook,"
+ Parent = "HOOK2,"
+ Priority = 2
+ Help = "Anchor for hook #2 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessEnterSetupHook,"
+ Parent = "HOOK3,"
+ Priority = 3
+ Help = "Anchor for hook #3 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK3,"
+ Parent = "AMITSE_Hooks"
+ Priority = 3
+ Help = "Anchor for hook #3 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessProceedToBootHook,"
+ Parent = "HOOK4,"
+ Priority = 4
+ Help = "Anchor for hook #4 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK4,"
+ Parent = "AMITSE_Hooks"
+ Priority = 4
+ Help = "Anchor for hook #4 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MinisetupDriverEntryHookHook,"
+ Parent = "HOOK5,"
+ Priority = 5
+ Help = "Anchor for hook #5 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK5,"
+ Parent = "AMITSE_Hooks"
+ Priority = 5
+ Help = "Anchor for hook #5 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PostManagerHandShakeHookHook,"
+ Parent = "HOOK6,"
+ Priority = 6
+ Help = "Anchor for hook #6 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK6,"
+ Parent = "AMITSE_Hooks"
+ Priority = 6
+ Help = "Anchor for hook #6 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MapControlKeysHook,"
+ Parent = "HOOK7,"
+ Priority = 7
+ Help = "Anchor for hook #7 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK7,"
+ Parent = "AMITSE_Hooks"
+ Priority = 7
+ Help = "Anchor for hook #7 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CheckForKeyHook,"
+ Parent = "HOOK8,"
+ Priority = 8
+ Help = "Anchor for hook #8 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK8,"
+ Parent = "AMITSE_Hooks"
+ Priority = 8
+ Help = "Anchor for hook #8 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BeforeLegacyBootLaunchHook,"
+ Parent = "HOOK9,"
+ Priority = 9
+ Help = "Anchor for hook #9 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK9,"
+ Parent = "AMITSE_Hooks"
+ Priority = 9
+ Help = "Anchor for hook #9 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AfterLegacyBootLaunchHook,"
+ Parent = "HOOK10,"
+ Priority = 10
+ Help = "Anchor for hook #10 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK10,"
+ Parent = "AMITSE_Hooks"
+ Priority = 10
+ Help = "Anchor for hook #10 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BeforeEfiBootLaunchHook,"
+ Parent = "HOOK11,"
+ Priority = 11
+ Help = "Anchor for hook #11 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK11,"
+ Parent = "AMITSE_Hooks"
+ Priority = 11
+ Help = "Anchor for hook #11 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AfterEfiBootLaunchHook,"
+ Parent = "HOOK12,"
+ Priority = 12
+ Help = "Anchor for hook #12 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK12,"
+ Parent = "AMITSE_Hooks"
+ Priority = 12
+ Help = "Anchor for hook #12 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SavedConfigChangesHook,"
+ Parent = "HOOK13,"
+ Priority = 13
+ Help = "Anchor for hook #13 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK13,"
+ Parent = "AMITSE_Hooks"
+ Priority = 13
+ Help = "Anchor for hook #13 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedConfigDefaultsHook,"
+ Parent = "HOOK14,"
+ Priority = 14
+ Help = "Anchor for hook #14 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK14,"
+ Parent = "AMITSE_Hooks"
+ Priority = 14
+ Help = "Anchor for hook #15 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TimeOutLoopHookHook,"
+ Parent = "HOOK15,"
+ Priority = 15
+ Help = "Anchor for hook #15 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK15,"
+ Parent = "AMITSE_Hooks"
+ Priority = 15
+ Help = "Anchor for hook #15 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey1HookHook,"
+ Parent = "HOOK16,"
+ Priority = 16
+ Help = "Anchor for hook #16 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK16,"
+ Parent = "AMITSE_Hooks"
+ Priority = 16
+ Help = "Anchor for hook #16 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey2HookHook,"
+ Parent = "HOOK17,"
+ Priority = 17
+ Help = "Anchor for hook #17 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK17,"
+ Parent = "AMITSE_Hooks"
+ Priority = 17
+ Help = "Anchor for hook #17 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey3HookHook,"
+ Parent = "HOOK18,"
+ Priority = 18
+ Help = "Anchor for hook #18 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK18,"
+ Parent = "AMITSE_Hooks"
+ Priority = 18
+ Help = "Anchor for hook #18 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey4HookHook,"
+ Parent = "HOOK19,"
+ Priority = 19
+ Help = "Anchor for hook #19 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK19,"
+ Parent = "AMITSE_Hooks"
+ Priority = 19
+ Help = "Anchor for hook #19 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PasswordEncodeHook,"
+ Parent = "HOOK20,"
+ Priority = 20
+ Help = "Anchor for hook #20 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK20,"
+ Parent = "AMITSE_Hooks"
+ Priority = 20
+ Help = "Anchor for hook #20 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SetControlColorsHook,"
+ Parent = "HOOK21,"
+ Priority = 21
+ Help = "Anchor for hook #21 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK21,"
+ Parent = "AMITSE_Hooks"
+ Priority = 21
+ Help = "Anchor for hook #21 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InvalidActionHook,"
+ Parent = "InvalidActionHookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InvalidActionHookHook,"
+ Parent = "HOOK22,"
+ Priority = 22
+ Help = "Anchor for hook #22 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK22,"
+ Parent = "AMITSE_Hooks"
+ Priority = 22
+ Help = "Anchor for hook #22 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedUserDefaults,"
+ Parent = "LoadedUserDefaultsHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedUserDefaultsHook,"
+ Parent = "HOOK23,"
+ Priority = 23
+ Help = "Anchor for hook #23 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK23,"
+ Parent = "AMITSE_Hooks"
+ Priority = 23
+ Help = "Anchor for hook #23 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedBuildDefaults,"
+ Parent = "LoadedBuildDefaultsHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedBuildDefaultsHook,"
+ Parent = "HOOK24,"
+ Priority = 24
+ Help = "Anchor for hook #24 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK24,"
+ Parent = "AMITSE_Hooks"
+ Priority = 24
+ Help = "Anchor for hook #24 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+
+ELINK
+ Name = "LoadedPreviousValues,"
+ Parent = "LoadedPreviousValuesHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedPreviousValuesHook,"
+ Parent = "HOOK25,"
+ Priority = 25
+ Help = "Anchor for hook #25 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK25,"
+ Parent = "AMITSE_Hooks"
+ Priority = 25
+ Help = "Anchor for hook #25 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+
+ELINK
+ Name = "SetupConfigModified,"
+ Parent = "SetupConfigModifiedHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SetupConfigModifiedHook,"
+ Parent = "HOOK26,"
+ Priority = 26
+ Help = "Anchor for hook #26 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK26,"
+ Parent = "AMITSE_Hooks"
+ Priority = 26
+ Help = "Anchor for hook #26 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DrawBbsPopupMenu,"
+ Parent = "DrawBootOnlyBbsPopupMenu,"
+ InvokeOrder = ReplaceParent
+ Token = "SETUP_BBS_POPUP_ENABLE" "=" "1"
+End
+
+ELINK
+ Name = "DrawBootOnlyBbsPopupMenu,"
+ Parent = "DrawPopupMenuHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK27,"
+ Parent = "AMITSE_Hooks"
+ Priority = 27
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DrawPopupMenuHook,"
+ Parent = "HOOK27,"
+ Priority = 27
+ Help = "Anchor for hook #27 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+
+ELINK
+ Name = "BbsBoot,"
+ Parent = "BbsBootHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK28,"
+ Parent = "AMITSE_Hooks"
+ Priority = 28
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BbsBootHook,"
+ Parent = "HOOK28,"
+ Priority = 28
+ Help = "Anchor for hook #28 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK29,"
+ Parent = "AMITSE_Hooks"
+ Priority = 29
+ Help = "Anchor for hook #29 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadSetupDefaultsHook,"
+ Parent = "HOOK29,"
+ Priority = 29
+ Help = "Anchor for hook #29 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadSetupDefaults,"
+ Parent = "LoadSetupDefaultsHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK30,"
+ Parent = "AMITSE_Hooks"
+ Priority = 30
+ Help = "Anchor for hook #30 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreSystemResetHookHook,"
+ Parent = "HOOK30,"
+ Priority = 30
+ Help = "Anchor for hook #30 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreSystemResetHook,"
+ Parent = "PreSystemResetHookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK31,"
+ Parent = "AMITSE_Hooks"
+ Priority = 31
+ Help = "Anchor for hook #31 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MapControlMouseActionHook,"
+ Parent = "HOOK31,"
+ Priority = 31
+ Help = "Anchor for hook #31 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MapControlMouseAction,"
+ Parent = "MapControlMouseActionHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessProceedToBootNowHook,"
+ Parent = "HOOK32,"
+ Priority = 32
+ Help = "Anchor for hook #32 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK32,"
+ Parent = "AMITSE_Hooks"
+ Priority = 32
+ Help = "Anchor for hook #32 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessProceedToBootNow,"
+ Parent = "ProcessProceedToBootNowHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessConOutAvailableHook,"
+ Parent = "HOOK33,"
+ Priority = 33
+ Help = "Anchor for hook #32 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK33,"
+ Parent = "AMITSE_Hooks"
+ Priority = 33
+ Help = "Anchor for hook #33 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessConOutAvailable,"
+ Parent = "ProcessConOutAvailableHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessUIInitHookHook,"
+ Parent = "HOOK34,"
+ Priority = 34
+ Help = "Anchor for hook #34 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK34,"
+ Parent = "AMITSE_Hooks"
+ Priority = 34
+ Help = "Anchor for hook #34 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AfterInitPostScreenHook,"
+ Parent = "HOOK35,"
+ Priority = 35
+ Help = "Anchor for hook #35 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AfterInitPostScreen,"
+ Parent = "AfterInitPostScreenHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK35,"
+ Parent = "AMITSE_Hooks"
+ Priority = 35
+ Help = "Anchor for hook #35 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CheckForClickHook,"
+ Parent = "HOOK36,"
+ Priority = 36
+ Help = "Anchor for hook #36 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK36,"
+ Parent = "AMITSE_Hooks"
+ Priority = 36
+ Help = "Anchor for hook #36 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SwitchToPostScreenHook,"
+ Parent = "HOOK37,"
+ Priority = 37
+ Help = "Anchor for hook #37 - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SwitchToPostScreen,"
+ Parent = "SwitchToPostScreenHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK37,"
+ Parent = "AMITSE_Hooks"
+ Priority = 37
+ Help = "Anchor for hook #37 - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+
+ELINK
+ Name = "ProcessUIInitHook,"
+ Parent = "ProcessUIInitHookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AMITSE.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SignON.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmLogo.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMLogo.ffs"
+ Parent = "FV_MAIN"
+ Token = "TSE_OEM_POSTLOGO_SUPPORT" "=" "1"
+ Token = "TSE_ROMHOLE_SUPPORT" "!=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = " "
+ Parent = "$(BUILD_DIR)\Logo.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "TSE_ROMHOLE_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\ROMHOLE.ffs"
+ Parent = "FV_MAIN"
+ Token = "TSE_ROMHOLE_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IFR_DIR_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "MINISETUPLIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "TSELITELIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_Objects"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_Hooks"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "DrawQuietBootLogo,"
+ Parent = "DrawQuietBootLogoHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessEnterSetup,"
+ Parent = "ProcessEnterSetupHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessProceedToBoot,"
+ Parent = "ProcessProceedToBootHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MinisetupDriverEntryHook,"
+ Parent = "MinisetupDriverEntryHookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PostManagerHandShakeHook,"
+ Parent = "PostManagerHandShakeHookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MapControlKeys,"
+ Parent = "MapControlKeysHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CheckForKey,"
+ Parent = "CheckForKeyHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CheckForClick,"
+ Parent = "CheckForClickHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BeforeLegacyBootLaunch,"
+ Parent = "BeforeLegacyBootLaunchHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AfterLegacyBootLaunch,"
+ Parent = "AfterLegacyBootLaunchHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BeforeEfiBootLaunch,"
+ Parent = "BeforeEfiBootLaunchHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AfterEfiBootLaunch,"
+ Parent = "AfterEfiBootLaunchHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SavedConfigChanges,"
+ Parent = "SavedConfigChangesHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LoadedConfigDefaults,"
+ Parent = "LoadedConfigDefaultsHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TimeOutLoopHook,"
+ Parent = "TimeOutLoopHookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessConInAvailability,"
+ Parent = "ProcessConInAvailabilityHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey1Hook,"
+ Parent = "OemKey1HookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey2Hook,"
+ Parent = "OemKey2HookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey3Hook,"
+ Parent = "OemKey3HookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemKey4Hook,"
+ Parent = "OemKey4HookHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PasswordEncode,"
+ Parent = "PasswordEncodeHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SetControlColors,"
+ Parent = "SetControlColorsHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LastTSEHook"
+ Parent = "HOOK0,"
+ Help = "Anchor for last hook - DO NOT MODIFY"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "HOOK0,"
+ Parent = "AMITSE_Hooks"
+ Help = "Anchor for last hook - DO NOT MODIFY."
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(TSEBIN_DIR)\setupdbg.h"
+ Parent = "AMITSE_OEM_HEADER_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{{SCAN_F11, 0},0, SetupShowDebugScreen, 0 },"
+ Parent = "HOTKEY_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{{TSE_PRN_SCRN_KEY_SCAN,0},0, PrntScrnKeyNotification, 0 },"
+ Parent = "HOTKEY_LIST"
+ InvokeOrder = AfterParent
+ Token = "TSE_PRN_SCRN_EVENT_SUPPORT" "=" "1"
+End
+
+
+ELINK
+ Name = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{ControlActionSelect, CHAR_CARRIAGE_RETURN, SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionNextSelection, CHAR_TAB, SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionPrevSelection, CHAR_TAB, SCAN_NULL, 0x80000003},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionBackSpace, CHAR_BACKSPACE, SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionDecreament, L'-', SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionIncreament, L' ', SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionIncreament, L'+', SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionNextLeft, CHAR_NULL, SCAN_LEFT, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionNextRight, CHAR_NULL, SCAN_RIGHT, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionNextUp, CHAR_NULL, SCAN_UP, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionNextDown, CHAR_NULL, SCAN_DOWN, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionAbort, CHAR_NULL, SCAN_ESC, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionPageUp, CHAR_NULL, SCAN_PAGE_UP, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionPageDown, CHAR_NULL, SCAN_PAGE_DOWN, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionHelpPageUp, L'k', SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionHelpPageDown, L'm', SCAN_NULL, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionHome, CHAR_NULL, SCAN_HOME, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ControlActionEnd, CHAR_NULL, SCAN_END, 0},"
+ Parent = "CONTROL_KEY_MAP_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{ {SAVE_AND_EXIT_VALUE}, HandleSaveAndExit },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {DISCARD_AND_EXIT_VALUE}, HandleExitApplication },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {SAVE_AND_RESET_VALUE}, HandleSaveAndReset },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {DISCARD_AND_RESET_VALUE}, HandleResetSys },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {SAVE_VALUE}, HandleSaveWithoutExit },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {DISCARD_VALUE}, HandleLoadPreviousValues },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {RESTORE_DEFAULTS_VALUE}, HandleLoadOptimalDefaults },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {SAVE_USER_DEFAULTS_VALUE}, HandleSaveUserDefaults },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {RESTORE_USER_DEFAULTS_VALUE}, HandleRestoreUserDefaults },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {SAVE_BOOT_OPTION}, HandleBootAddBootOption },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ Token = "SETUP_SUPPORT_ADD_BOOT_OPTION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {LAUNCH_FILE_PATH}, HandleLaunchFileSystem },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ Token = "SETUP_SUPPORT_ADD_BOOT_OPTION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {SAVE_DRIVER_OPTION}, HandleDriverAddDriverOption },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ Token = "SETUP_SUPPORT_ADD_DRIVER_OPTION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {LAUNCH_FILE_PATH_DRIVER}, HandleLaunchFileSystemDriver },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ Token = "SETUP_SUPPORT_ADD_DRIVER_OPTION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{ {END_OF_EXIT_PAGE_OPTION_LIST}, NULL },"
+ Parent = "EXIT_PAGE_OPTIONS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TSE_STRING_CONSUMERS_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(TSEBIN_DIR)\FakeTokens.c"
+ Parent = "TSE_STRING_CONSUMERS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TSE_UNI_INCLUDE_PATH"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_HPK_FILE_ORDER"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "TSE_SDBS"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "TSE_LIB_INCLUDES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "-I $(TSEBIN_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-I $(TSEBIN_DIR)\Inc"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-I $(TSESRC_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "MiniSetup_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(TSESRC_DIR)\AMILOGO"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "MiniSetup_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(UEFISRC_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "UEFI_SOURCES_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(TSE_STYLE_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "TSE_STYLE_EZPORT_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(TSELITESRC_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "TseLite_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(TSE_ADVANCED_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "TSE_ADVANCED_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(TSE_BOARD_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+ Token = "TSE_BOARD_SOURCE_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-I $(PROJECT_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-I $(PROJECT_DIR)\Include"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-I $(PROJECT_DIR)\Include\Protocol"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-I $(PROJECT_DIR)\Core"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-I $(BUILD_DIR)"
+ Parent = "TSE_LIB_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AMITSE_OEM_HEADER_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_KEY_CALLBACK_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_HIDDEN_PAGE_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_ROOT_PAGE_ORDER"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PASSWORD_ENOCDE_LIST"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_FILTER_CLASSGUID_FORMSETS"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{ 0x93039971, 0x8545, 0x4b04, 0xb4, 0x5e, 0x32, 0xeb, 0x83, 0x26, 0x4, 0xe },{ 0xf22fc20c, 0x8cf4, 0x45eb, 0x8e, 0x6, 0xad, 0x4e, 0x50, 0xb9, 0x5d, 0xd3 }"
+ Parent = "AMITSE_FILTER_CLASSGUID_FORMSETS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST"
+ Help = "Provide GUIDs of dynmaic formset to suppress. Terminate entry with comma"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AMITSE_DYNAMICPARSING_HANDLE_SUPPRESS_LIST"
+ Help = "Provide Guid followed by variable name with single quotes. Terminate entry with comma"
+ InvokeOrder = ReplaceParent
+End
+
+#ELINK
+# Name = "{{ 0xE770BB69, 0xBCB4, 0x4D04, 0x9E, 0x97, 0x23, 0xFF, 0x94, 0x56, 0xFE, 0xAC }, {'S','y','s','t','e','m','A','c','c','e','s','s'}},"
+# Parent = "AMITSE_DYNAMICPARSING_HANDLE_SUPPRESS_LIST"
+# Help = "Provide GUIDs of variable and Variable name as above format to suppress handle while parsing variable if it is present already in other formset."
+# InvokeOrder = AfterParent
+#End
+
diff --git a/Core/EM/AMITSE/AmiTSEStr.uni b/Core/EM/AMITSE/AmiTSEStr.uni
new file mode 100644
index 0000000..43301e1
--- /dev/null
+++ b/Core/EM/AMITSE/AmiTSEStr.uni
Binary files differ
diff --git a/Core/EM/AMITSE/CommonHelper.c b/Core/EM/AMITSE/CommonHelper.c
new file mode 100644
index 0000000..786f0c2
--- /dev/null
+++ b/Core/EM/AMITSE/CommonHelper.c
@@ -0,0 +1,6230 @@
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy , Norcross, GA 30071 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/CommonHelper.c $
+//
+// $Author: Premkumara $
+//
+// $Revision: 158 $
+//
+// $Date: 9/05/14 2:28p $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/CommonHelper.c $
+//
+// 158 9/05/14 2:28p Premkumara
+// Moved below functions from HiiString21.c to CommonHelper.c
+// - IsSupportDefaultForStringControl()
+// - IsTseBestTextGOPModeSupported()
+//
+// 157 9/05/14 6:29a Premkumara
+// [TAG] EIP141986
+// [Category] Improvement
+// [Description] Make grayedout control focusable and this feature is
+// handled by token TSE_SETUP_GRAYOUT_SELECTABLE
+// [Files] AMITSE.sdl, CommonHelper.c, Frame.c, Label.c, Minisetupext.c,
+// Numeric.c, PopupPassword.c, PopupSel.c, PopupString. SubMenu.c
+//
+// 156 8/28/14 10:08a Premkumara
+// [TAG] EIP174031
+// [Category] Improvement
+// [Description] Removed TODO comments and added proper comments in those
+// places
+// [Files] commonoem.c, commonhelper.c, special.c, submenu.c,
+// minisetupext.c, uefi21wapper.c and legacy.c
+//
+// 155 8/28/14 7:27a Premkumara
+// [TAG] EIP107833, 125388
+// [Category] Improvement
+// [Symptom:] Setting best text and GOP mode while using TSEPostinterfaces
+// before TSE or after TSE.
+// [Files] Protocol.c, AMITSE.sdl, CommonHelper.c, MiniSetup.sdl,
+// PostMgmtc, PostmgmtExt.c, MessagBox.c
+//
+// 154 8/28/14 4:28a Premkumara
+// EIP-135253 Updating file name proper in #include
+//
+// 153 7/12/14 5:44p Arunsb
+//
+// 152 5/08/14 9:09p Arunsb
+// [TAG] EIP162981
+// [Category] Improvement
+// [Description] Configuring default Password through SDL token.
+// Based on RT_ACCESS_SUPPORT_IN_HPKTOOL, attribute is set for amitsesetup
+// variable
+//
+// 151 5/08/14 4:26p Arunsb
+// [TAG] EIP162197
+// [Category] Improvement
+// [Description] Password encode feature modify to encode using Hashing
+// based on token.
+// IsPasswordSupportNonCaseSensitive moved to PasswordEncode module
+//
+// 150 5/02/14 9:22p Arunsb
+// EIP141986 changes reverted.
+//
+// 149 5/02/14 2:43p Premkumara
+// Resolve build error for undeclared fn CheckandDeactivateSoftkbd()
+//
+// 148 5/02/14 2:09p Premkumara
+// [TAG] EIP140123
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] While showing secureboot error msg mouse is not move and
+// get hang. Softkbd is displaying
+// [RootCause] MouseClickEvent is not stopped while boot to any option.
+// So clicking outside msg box causes displaying
+// softkbd and mouse is not init at this phase.
+// [Solution] Initialized mouse and deactivating any softkbd activated
+// before showing secureboot error msg box.
+// [Files] CommonHelper.c, CommonOem.c, MessageBox.c
+//
+// 147 5/02/14 1:09p Premkumara
+// [TAG] EIP128526
+// [Category] Improvement
+// [Description] Disable ESC action in BBS popup menu
+// [Files] AMITSE.sdl, CommonHelper.c, TseLite/MinisetupExt.c
+//
+// 146 5/02/14 11:08a Premkumara
+// [TAG] EIP141986
+// [Category] New Feature
+// [Description] Made Grayed controls to focus-able when token
+// TSE_SETUP_GRAYOUT_SELECTABLE
+// is enabled and can't edit the values
+// [Files] AMITSE.sdl,CommonHelper.c,frame.c,Label.c,minisetupext.h,
+// numeric.c,PopupPassword.c,PopupSel.c,PopupString.c,SubMenu.c
+//
+// 145 5/02/14 8:37a Premkumara
+// [TAG] EIP162981
+// [Category] Improvement
+// [Description] Configuring default Password through SDL token
+// [Files] AMITSE.sdl, CommonHelper.c, Minisetup.c, TseAdvanced.c
+//
+// 144 5/02/14 6:47a Premkumara
+// [TAG] EIP164232
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] When password keyboard is launched and mouse pointer is
+// placed on softkbd mouse will flickers continously.
+// [RootCause] MouseRefresh and MouseStop is calling contiously in loop
+// so mouse pointer get flickers
+// [Solution] When mouse pointer is on softkbd and is static then stop
+// calling MouseRefresh and MouseFreeze
+// [Files] PopupPassword.c, CommonHelper.c, Mouse.c
+//
+// 143 5/02/14 6:08a Premkumara
+// [TAG] EIP123431
+// [Category] Improvement
+// [Description] Need create one override token to TSE.
+// [Files] CommonHelper.c, AMITSE.sdl
+//
+// 142 5/02/14 3:53a Premkumara
+// [TAG] EIP151966
+// [Category] Improvement
+// [Description] Added the implementation for getting the BIOS build
+// year dynamically
+// from TimeStamp.h file and updated the Build year in copyright message
+// in both Setup and POST.
+// [Files] style.c,style.c,style.c,notify.c,minisetupext.c,CommonHelper
+// .c,
+// AmiTSEStr.uni,AMITSE.mak
+//
+// 141 5/02/14 3:00a Arunsb
+// IsHashingSupported function removed since TSE_HASH_PASSWORD can he
+// handled directly. Since implementation is there in binary only.
+//
+// 140 5/02/14 2:30a Arunsb
+// Reverted 137341 change
+//
+// 137 5/02/14 2:13a Arunsb
+// [TAG] EIP142690
+// [Category] Improvement
+// [Description] Create token OVERRIDE_CsmBBSBootOptionName for function
+// CsmBBSBootOptionName
+// [Files] Amitse.sdl and commonhelper.c
+//
+// 135 5/02/14 1:19a Arunsb
+// [TAG] EIP137341
+// [Category] Bug Fix
+// [Symptom:] The use of T_ACPI_OEM_ID and T_ACPI_OEM_TBL_ID when
+// generating the BGRT does not display blank characters.
+// [Root Cause] The macro CONVERT_TO_STRING() will consume the blank char,
+// so there's nothing different between the use of " AMI" and "AMI" when
+// showing in the ACPI table.
+// [Solution] The functions GetACPIOEMID and GetACPIOEMTableID should no
+// longer use T_ACPI_OEM_ID and T_ACPI_OEM_TBL_ID in token.h
+// But should use the tokens ACPI_OEM_ID_MAK and ACPI_OEM_TBL_ID_MAK from
+// AcpiOemElinks.h
+// [Files] CommonHelper.c
+//
+// 134 2/11/14 7:03p Arunsb
+// Updated in synch with Aptio5.
+// For EIPs 129750, 130997, 131969, 131739, 130529, 126746 and 148693
+//
+// 133 12/05/13 1:00a Premkumara
+// [TAG] EIP140123
+// [Category] Bug Fix
+// [Symptom:] Not able to close SecureError Msgbox using touch/mouse and
+// softkeyboard is displaying while displaying secureerror msgbox
+// [Root Cause] Mouse is not not initilalized when showing msg box during
+// ProceedToBoot and sofkbd is not cleared in this case also.
+// [Solution] CommonHelper.c
+// [Files] CommonHelper.c
+//
+// 132 12/04/13 3:40p Premkumara
+// [TAG] EIP136946
+// [Category] Improvement
+// [Description] Made gBootFileName shell boot compatable with x32, x64
+// and ARM for aptio4&5
+// [Files] CommonHelper.c
+//
+// 131 12/03/13 1:26p Premkumara
+// [TAG] EIP128526
+// [Category] Improvement
+// [Description] Disable ESC action in BBS popup menu
+// [Files] AMITSE.sdl, CommonHelper.c, TseLite/MinisetupExt.c
+//
+// 130 12/03/13 12:52p Premkumara
+// [TAG] EIP141986
+// [Category] Improvement
+// [Description] Make grayedout control focusable and this feature is
+// handled by token TSE_SETUP_GRAYOUT_SELECTABLE
+// [Files] AMITSE.sdl, CommonHelper.c, Frame.c, Label.c, Minisetupext.c,
+// Numeric.c, PopupPassword.c, PopupSel.c, PopupString. SubMenu.c
+//
+// 129 11/26/13 10:24a Premkumara
+// [TAG] EIP123431
+// [Category] Improvement
+// [Description] Need create one override token to TSE.
+// [Files] CommonHelper.c, AMITSE.sdl
+//
+// 128 11/26/13 1:30a Premkumara
+// [TAG] EIP118342
+// [Category] Improvement
+// [Description] Show meaningful error message when HDD is locked after
+// reached maximum unlocking attempt.
+// [Files] TseAdvanced.c, CommonHelper.c
+//
+// 127 8/06/13 3:58a Premkumara
+// [TAG] EIP130529
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] When entered into setup with User mode and On pressing
+// "Restore User Defaults" SystemAccess variable is loading and the user
+// mode is changes to Admin mode so the controls are editable
+// [RootCause] LoadUserDefaultsSilently() function is loading defaults
+// for all types of variable
+// [Solution] Skipping loading SystemAccess variable while loading
+// defaults for user default variable.
+// [Files] TseAdvanced.c, AMITSE.sdl, CommonHelper.c
+//
+// 126 4/18/13 9:49a Arunsb
+// Wrapper function introduced to avoid build error in 2.0 build
+//
+// 125 3/29/13 12:15p Premkumara
+// [TAG] EIP97611
+// [Category] New Feature
+// [Description] PrintScreen Support in TSE
+// [Files] AMITSE.sdl, CommonHelper.c, HotKeyBin.h, AddBootOption.c,
+// Page.c, TseUefiHii.h, Uefi21Wapper.c
+//
+// 124 3/25/13 8:46a Premkumara
+// [TAG] EIP116315
+// [Category] Improvement
+// [Description] Display control prompt string for password control.
+// (for String on CHAP secret popup)
+// [Files] - AMITSE.sdl
+// - CommonHelper.c
+// - FakeToken.c
+// - AmiTSEStr.uni
+// - TseLite\PopupPassword.c
+// - uefi2.1\UefiWapper21.c
+// - uefi2.0\UefiWapper20.c
+// - uefi2.0\HiiCallback.c
+// - uefi2.0\hii.h
+// - uefi2.0\hii.c
+//
+// 123 3/16/13 3:58a Rajashakerg
+// [TAG] EIP107221
+// [Category] Improvement
+// [Description] Logo disappear after HDD password verified
+// [Files] CommonHelper.c, notify.c, minisetupext.c
+//
+// 122 3/12/13 6:56a Rajashakerg
+// [TAG] EIP105167
+// [Category] Improvement
+// [Description] Making the specify setup items departing from F2/F3
+// effect.
+// [Files] AMITSE.sdl, CommonHelper.c, callback.c, minisetupext.h,
+// PopupPassword.c, SubMenu.c, HiiCallback.c
+//
+// 121 2/20/13 11:42p Rajashakerg
+// [TAG] EIP104521
+// [Category] Improvement
+// [Description] Customer needs AMITSE modification to popup boxes so
+// highlighted choices can be seen via VT100 console redirection
+// [Files] AMITSE.sdl, CommonHelper.c, Ezport\stylecommon.c,
+// EzportPlus\stylecommon.c, Legacy\stylecommon.c
+//
+// 120 2/19/13 4:15a Premkumara
+// [TAG] EIP103540
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Currently _BootBuildFVDevicePath function using FV
+// protocol alone not FV2 protocol. So applications loading from ffs are
+// not loading properly.
+// [RootCause] _BootBuildFVDevicePath() function used
+// gEfiFirmwareVolumeProtocolGuid only not gEfiFirmwareVolume2ProtocolGuid
+// [Solution] Used gEfiFirmwareVolume2ProtocolGuid based on
+// PISpecVersion
+// [Files] CommonHelper.c, Boot.c
+//
+// 119 2/11/13 6:10a Premkumara
+// [TAG] EIP112628
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] (JP000E)SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY does not work on
+// 4.6.2_TSE_2_15_1234
+// [RootCause] The Exit FormID value will change if any form is
+// generated before Exit page
+// [Solution] Handled Exit FormID from Binary and handling Exit FormID
+// from binary
+// [Files] Ezport.c, Ezport.sdl, Legacy.c, Legacy.sdl, EzportPlus.c,
+// EzportPlus.sdl
+//
+// 118 2/10/13 11:51p Rajashakerg
+// [TAG] EIP104521
+// [Category] Improvement
+// [Description] Customer needs AMITSE modification to popup boxes so
+// highlighted choices can be seen via VT100 console redirection
+// [Files] AMITSE.sdl, CommonHelper.c, Ezport\stylecommon.c,
+// EzportPlus\stylecommon.c, Legacy\stylecommon.c
+//
+// 117 2/06/13 9:07a Arunsb
+// Checking in properly. Instead check in Alaska previously made in PBA.
+//
+// 117 1/31/13 12:49p Arunsb
+// [TAG] EIP109382
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Boot Device name incorrect when load default
+// [RootCause] Legacy offset in gbootdata corrupted so names displayed
+// improperly.
+// [Solution] Legacy offsets re-calculated properly
+// [Files] CommonHelper.c, BootOnly\bbs.c and callback.c
+//
+// 116 12/05/12 5:29a Rajashakerg
+// [TAG] EIP103381
+// [Category] Improvement
+// [Description] adopting SDL to control timeout spec
+// [Files] AMITSE.sdl, CommonHelper.c, protocol.c
+//
+// 115 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 43 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 113 9/21/12 12:30p Premkumara
+// [TAG] EIP99022
+// [Category] Improvement
+// [Description] Tokenize the feature of flushing keyboard after every
+// key read
+// [Files] AMITSE.sdl, CommonHelper.c, TseAdvanced.c, Action.c
+//
+// 112 9/17/12 5:59a Rajashakerg
+// Updated EIP changes for 2.16 release.
+//
+// 110 9/12/12 5:21a Rajashakerg
+// [TAG] EIP94205
+// [Category] Improvement
+// [Description] OEM needs Token to assign the display mode of SHELL
+// [Files] AMITSE.sdl, boot.c, CommonHelper.c
+//
+// 109 9/10/12 5:03a Rajashakerg
+// [TAG] EIP93881 and 93873
+// [Category] Improvement
+// [Description] need keep system password after Load default and
+// Password saved into NVRAM immediately(not buffer) while it is installed
+// in TSE
+// [Files] frame.c, callback.c, AMITSE.sdl, CommonHelper.c
+//
+// 108 9/08/12 1:22p Arunsb
+// [TAG] EIP100558
+// [Category] New Feature
+// [Description] Provide solution to display the small logo in (0,0)
+// graphics position
+// [Files] AMITSE.sdl, commonhelper.c, postmgmt.c and boot.c
+//
+// 107 9/08/12 11:44a Arunsb
+// [TAG] EIP99059
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] _ReInitializeSetupdataPointers function crashes in Hii.C
+// when DyanmicPage processed with PageIdListSize =0
+// [RootCause] Hii pack notification installed for
+// SETUP_RUNTIME_IFR_PROCESSING is disabled also
+// [Solution] Hii pack notification installed only if
+// SETUP_RUNTIME_IFR_PROCESSING is enabled
+// [Files] commonhelper.c and Hii.c
+//
+// 106 9/06/12 1:06a Rajashakerg
+// [TAG] EIP91410
+// [Category] Improvement
+// [Description] TSE_MULTILINE_CONTROLS=1 makes one of option with max
+// string looks not good.
+// [Files] PopupSel.c, COmmonHelper.c, AMITSE.sdl
+//
+// 105 9/03/12 3:07a Premkumara
+// [TAG] EIP 96246
+// [Category] Improvement
+// [Description] Improvement of a boots override when firmware has a
+// BootNext variable
+// [Files] AMITSE.sdl, CommonHelper.c, FakeToken.c, AmiTSEStr.uni,
+// TseAdvanced.c
+//
+// 104 8/29/12 4:09p Arunsb
+// [TAG] EIP94702
+// [Description] Support for Native Resolution in POST/BOOT
+// [Files] amitse.sdl, commonhelper.c, commonoem.c, boot.c, logo.c,
+// notify.c, postmgmt.c, ezport/stylecommon.c,
+// ezportplus/stylecommon.c,legacy/stylecommon.c
+// tselite\minisetupext.c
+//
+// 103 8/29/12 12:35p Arunsb
+// [TAG] EIP93521
+// [Category] New Feature
+// [Description] Support of ESRT
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonhelper.c and
+// dobmpmgr.c
+//
+// 102 8/29/12 8:33a Premkumara
+// [TAG] EIP 91364
+// [Category] Improvement
+// [Description] Token to disable the Cursor of TSE Password Dialog
+// [Files] AMITSE.sdl, CommonHelper.c, Postmgmtext.c, PopupPassword.c,
+// PopupString.c
+//
+// 101 8/27/12 6:18a Premkumara
+// [TAG] EIP 94616
+// [Category] Improvement
+// [Description] TSE should not wait for key if fast boot is in progress
+// [Files] AMITSE.sdl, CommonHelper.c, Notify.c, Protocol.c
+//
+// 100 8/23/12 6:31p Arunsb
+//
+// 99 8/21/12 7:55p Arunsb
+// [TAG] EIP93521
+// [Category] New Feature
+// [Description] Support of ESRT
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonhelper.c and
+// dobmpmgr.c
+//
+// 98 6/28/12 8:19p Arunsb
+// [TAG] EIP93524
+// [Category] Improvement
+// [Description] Invalidate the BGRT table when boot device launched
+// from BBS popup or from shell or launched as second boot device
+// [Files] commonhelper.c, boot.c and minisetup.c
+//
+// 97 5/29/12 3:15a Arunsb
+// [TAG] EIP91109
+// [Category] Improvement
+// [Description] Sync the Aptio IV source for AptioV
+//
+// 96 5/28/12 12:30p Premkumara
+// [TAG] EIP67049 & 90224
+// [Category] New Feature
+// [Description] Support mouse drag operation in frame and list box
+// [Files] CommonHelper.c, Frame.c, ListBox.c, Minisetupext.h
+//
+// 95 5/28/12 12:00p Premkumara
+// [TAG] EIP89272
+// [Category] Improvement
+// [Description] Change softkbd layout for numeric control
+// [Files] CommonHelper.c, Mouse.c, Minisetup.h, C, Numeric.c
+//
+// 94 5/28/12 11:24a Premkumara
+// [TAG] EIP88912
+// [Category] Improvement
+// [Description] On password window display the softkbd with only with
+// valid key's
+// [Files] CommonHelper.c, Postmgmtext.c, Mouse.c, PopupPassword.c
+//
+// 93 5/28/12 6:08a Rajashakerg
+// [TAG] EIP89377
+// [Category] Improvement
+// [Description] Support to LegacyBootFailHook() in TSE.
+// [Files] AMITSE.sdl, CommonHelper.c, boot.c
+//
+// 92 5/28/12 5:35a Premkumara
+// [TAG] EIP75236
+// [Category] Improvement
+// [Description] Add the support to control the GOP dependency in TSE
+// notification.
+// [Files] AMITSE.sdl, CommonHelper.c, Notify.c, Minisetup.h,
+// Minisetup.sdl, protocol.c, FormBrowser.c, FormBrowser2.c
+//
+// 91 5/28/12 2:49a Arunsb
+// [TAG] EIP88447
+// [Category] New Feature
+// [Description] Disable UEFI boot option in BIOS setup should not load
+// the default image \EFI\BOOT\BOOT{machine type short-name}.EFI
+// [Files] Amitse.sdl, commonhelper.c and bootflow.c
+//
+// 90 5/09/12 6:31p Premkumara
+// EIP-83703 Updated CleareNumericShiftstate function
+//
+// 89 5/09/12 5:09p Premkumara
+// Removed #pragma optimize( "", off ) line
+//
+// 88 5/09/12 5:06p Premkumara
+// [TAG] EIP83703
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TSE hangs while clicking on the "link training time out"
+// value [this is happening while trying the specified steps immediate
+// after bios flash
+// [RootCause] When invalid range input is provided for numeric control
+// ESC sequence is not provided if it is handled by the mouse.
+// [Solution] Provided the proper ESC sequence to the control such that
+// it close the Invalid Range Fail MsgBox when handled with the mouse and
+// key.
+// [Files] Numeric.c, CommonHelper.c
+//
+// 87 4/27/12 9:23a Arunsb
+// [TAG] EIP88895
+// [Category] Improvement
+// [Description] Changing GetUefiSpecVersion as board module hook and
+// also controlling callback spec version from TSE
+// [Files] Amitse.sdl, amitse.mak and commonhelper.c
+//
+// 86 4/27/12 1:40a Premkumara
+// [TAG] EIP88527
+// [Category] Improvement
+// [Description] Implement BGRT logo calculation based on Windows-8
+// [Files] CommonHelper.c, Logo.c
+//
+// 85 4/05/12 7:09a Rajashakerg
+// [TAG] EIP87122,85508,86449
+// [Category] Improvement
+// [Description] Numeric in old style, softkbd issues
+// [Files] CommonHelper.c, Mouse.c, Date.c, edit.c, frame.c,
+// minisetupext.h, numeric.c, numeric.h, PopupEdit.c, PopupEdit.h, time.c
+//
+// 84 4/04/12 12:24a Rajashakerg
+// [TAG] EIP86253
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse and SoftKbd does not work after displaying "No option
+// to boot to" in POST
+// [RootCause] Mouse timer cleared once after displaying the "No option
+// to boot to" in POST
+// [Solution] Mouse timer cleared only when its going to boot.
+// [Files] CommonHelper.c, commonoem.c, minisetupext.c, protocol.c
+//
+// 83 2/04/12 9:08a Premkumara
+// Moved DrawOEMImage with some modification from binary to source
+//
+// 82 2/02/12 12:39a Premkumara
+// [TAG] EIP75136
+// [Category] New Feature
+// [Description] Generic support for logos in RomHoles
+// [Files] CommomHelper.c, AMITSE.sdl, AMITSE.mak, LogoLib.h,
+//
+// 81 2/01/12 4:55a Rajashakerg
+// [TAG] EIP77256
+// [Category] Improvement
+// [Description] Provide the Support to override the control Condition
+// checking() generically. And provide customization to supress the
+// controls with Security GUIDed opcode.
+// [Files] AMITSE.sdl, CommonHelper.c, CtrlCond.c and CtrlCond.h
+//
+// 80 1/31/12 1:17p Premkumara
+// [TAG] EIP75136
+// [Category] New Feature
+// [Description] Generic support for logos in RomHoles
+// [Files] CommomHelper.c, AMITSE.sdl, AMITSE.mak, LogoLib.h,
+// Postmgmt.c, AMILogo.h
+//
+// 79 1/31/12 6:08a Arunsb
+// [TAG] EIP81830
+// [Category] Improvement
+// [Description] Support to uninstall the BGRT on legacy boot.
+// [Files] Commonhelper.c, postmgmt.c and boot.c
+//
+// 78 1/27/12 12:03a Rajashakerg
+// [TAG] EIP81623
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] IDE security login dialog was not displayed properly and
+// observed password dialog label name displayed in text field
+// [RootCause] IDE security module uses _ReportInBox() to draw the
+// password text label which draws the text background.
+// [Solution] Provided the Gtse background color to the text label
+// field.
+// [Files] CommonHelper.c
+//
+// 77 1/25/12 7:59a Rajashakerg
+// [TAG] EIP81617
+// [Category] Improvement
+// [Description] Avoiding memory leaks in TSE
+// [Files] hiistring21.c, CommonHelper.c, notify.c
+//
+// 76 1/18/12 7:20a Premkumara
+// [TAG] EIP79959
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Scree is not cleared properly while showing ""Secure boot
+// violation"" warning message
+// [RootCause] When any boot option fails then screen is not cleared
+// properly before display Violatioin MessageBox in UefiBootFailHook()
+// [Solution] When any boot option fails then clear screen before
+// display Violatioin MessageBox to avoid screen corruption in
+// UefiBootFailHook()
+// [Files] CommonHelper.c
+//
+// 75 1/18/12 4:54a Rajashakerg
+// [TAG] EIP79962
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse pointer corruption in GTSE
+// [RootCause] For GTSE, the cordanites comparison logic went wrong for
+// stopping the mouse pointer when it is present while
+// updating the screen buffer.
+// [Solution] Corrected the logic to stop the mouse when mouse pointer
+// is present on screen we are updating.
+// [Files] buffer.c, CommonHelper.c, Mouse.c
+//
+// 74 12/28/11 4:12a Arunsb
+// [TAG] EIP75021
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] [TSE] In Date and Time item Press Shift+Tab key can't move
+// previous field.
+// [RootCause] Shift states not checked properly
+// [Solution] Shift state bits are cleared for every combinations and
+// compared at last
+// [Files] commonoem.c and commonhelper.c
+//
+// 73 12/08/11 9:03p Arunsb
+// Wrapper function added for GetFormSetTitleAndHelpWrapper fnc to resolve
+// the build error in 2.0
+//
+// 72 12/08/11 12:29p Rajashakerg
+// Updated the file to overcome build errors when build for x32 mode.
+//
+// 71 12/08/11 9:34a Rajashakerg
+// [TAG] EIP77108
+// [Category] Improvement
+// [Description] Updated the file to aviod build errors when build for
+// UEFI 20
+//
+// 70 12/08/11 12:04a Arunsb
+// [TAG] EIP75021
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] In Date and Time item Press Shift+Tab key can't move
+// previous field
+// [RootCause] Combination of keys not handled properly
+// [Solution] Combination of keys handled properly
+// [Files] commonhelper.c
+//
+// 69 12/07/11 9:29a Rajashakerg
+// [TAG] EIP77108
+// [Category] Improvement
+// [Description] Make ProcessBrowserActionRequest as board module hook
+// [Files] AMITSE.sdl, CommonHelper.c, HiiCallback.c
+//
+// 68 12/01/11 5:34a Rajashakerg
+// [TAG] EIP74963
+// [Category] Improvement
+// [Description] MAX_MSGBOX_WIDTH cannot be overridden
+// [Files] AMITSE.sdl, CommonHelper.c, minisetup.h, legacy.c,
+// MessageBox.c, MessageBox.h, FormBrowser.c
+//
+// 67 11/22/11 1:09a Premkumara
+// Updated GetPasswordReportInboxcolor() with missing #endif
+//
+// 66 11/22/11 12:08a Premkumara
+// [TAG] EIP70175
+// [Category] Improvement
+// [Description] Color of Password Validation for TSE and GTSE
+// [Files] CommonHelper.c, postmgmtext.c
+//
+// 65 11/21/11 10:31a Premkumara
+// [TAG] EIP72610
+// [Category] Improvement
+// [Description] Moving TSE_MULTILINE_CONTROLS to Binary
+// [Files] AMITSE-CommonHelper.c, AMITSE.sdl,
+// TSELITE-UefiAction.c, TseLite.sdl, Time.h, Text.c,
+// SubMenu.c, ResetButton.c, PopupString.c, PopupSel.h, PopupSel.c,
+// PopupPassword.c, OrderListBox.c, Numeric.c, Label.c, Frame.c, Edit.c,
+// Date.h, Date.c,
+// LEGACY-Legacy.c,
+// BOOTONLY- Minisetup.h
+//
+// 64 11/21/11 9:42a Rajashakerg
+// [TAG] EIP62763
+// [Description] For avoiding build errors when softkbd present and
+// MINISETUP_MOUSE_SUPPORT is disabled.
+//
+// 63 11/21/11 5:44a Rajashakerg
+// [TAG] EIP74591
+// [Category] Improvement
+// [Description] Make MainSetupLoop as board module hook
+// [Files] AMITSE.sdl, CommonHelper.c, protocol.c, minisetup.h,
+// FormBrowser.c, FormBrowser2.
+//
+// 62 11/20/11 8:09a Premkumara
+// [TAG] EIP70175
+// [Category] Improvement
+// [Description] Color of PopupPassword Window to validate password in
+// GTSE style
+// [Files] CommonHelper.c, postmgmtext.c, minisetup.h
+//
+// 61 11/20/11 6:48a Rajashakerg
+// [TAG] EIP62763
+// [Category] Improvement
+// [Description] Utilize the Improvements done from mouse driver in
+// AMITSE
+// [Files] HookAnchor.h, TseCommon.h, AMITSE.sdl, CommonHelper.c,
+// commonoem.c, commonoem.h, buffer.c, globals.c, HookAnchor.c,
+// minisetup.h, notify.c, postmgmt.c, protocol.c, ezport.c, stylecommon.c,
+// Mouse.c, Action.c, Date.c, frame.c, MessageBox.c, minisetupext.c,
+// minisetupext.h, numeric.c, numeric.h, page.c, PopupEdit.c, PopupEdit.h,
+// PopupPassword.c, postmgmtext.c, time.c.
+//
+// 60 11/19/11 9:22a Premkumara
+// [TAG] EIP70175
+// [Category] Improvement
+// [Description] Color of PopupPassword Window to validate password in
+// GTSE style
+// [Files] CommonHelper.c, postmgmtext.c, minisetup.h
+//
+// 59 11/14/11 6:52p Blaines
+// [TAG] - EIP 75486
+// [Category]- Function Request
+// [Synopsis]- Support grayout condition for readonly controls.
+// [Description] - Display readonly controls as grayout, non-selectable.
+// [Files]
+// AMITSE.sdl, CommonHelper.c, Minisetupext.h, stylecommon.c, Legacy.c,
+// date.c, edit.c, label.c, memo.c, menu.c,, numeric.c, ordlistbox.c,
+// PopupPassword.c,
+// PopupSel.c, PopupString.c, ResetButton.c, SubMenu.c, Text.c, Time.c,
+// UefiAction.c, ctrlcond.c,
+//
+// 58 11/13/11 12:17p Arunsb
+// [TAG] EIP70421
+// [Category] New Feature
+// [Description] Support for driver order in TSE
+// [Files] AMITSE.SDL, CommonHelper.c, setup.ini, uefisetup.ini,
+// boot.c,
+// minisetup.h, bbs.c, special.c, special.h, tseadvanced.c,
+// addbootoption.c,
+// callback.c, minisetupext.c, minisetupext.h, popupsel.c, popupsel.h,
+// TseLitehelper.c, variable.c, Uefi21Wapper.c, AMIVfr.h, boot.h,
+// TseElink.h, variable.h,
+// setup.h, Boot.vfr and Setup.uni
+//
+// 57 11/09/11 9:57a Premkumara
+// [TAG] EIP74375
+// [Category] Improvement
+// [Description] Control STYLE_HELP_AREA_SCROLLBAR from binary
+// [Files] CommonHelper.c, AMITSE.sdl, StyleHook.h,
+// Legacy\StyleCommon.c, Legacy.sdl,
+// EzportPlus\StyleCommon.c, EzportPlus.sdl, Ezport\StyleCommon.c,
+// Ezport.sdl
+//
+// 56 11/01/11 4:19a Arunsb
+// [Category] Improvement
+// [Description] To change the single click behaviour as like double
+// click
+// [Files] amitse.sdl, commonhelper.c, commonoem.c and listbox.c
+//
+// 55 10/20/11 12:23p Blaines
+// Correct the comments.
+//
+// 54 10/20/11 11:44a Blaines
+// [TAG] EIP 72333
+// [Category] Sighting
+// [Symptom] Some SAS controller card HII Screen Titles are displaying
+// the wrong information
+// [RootCause] Menu tab always displays the root page title when
+// navigating submenu pages. TSE did not support the display of Formset
+// Help.
+//
+// [Solution] Display Formset Help for Dynamic page, Display page title of
+// submenu pages in the menu tab.
+//
+// [Files Changed]
+// - AMITSE.sdl, CommonHelper.c, special.c, Menu.c, minisetupext.h,
+// TseUefiHii.h, Uefi21Wapper.c
+//
+// 53 10/10/11 1:43a Arunsb
+// [TAG] EIP66976
+// [Category] Improvement
+// [Description] Provision to change the Numeric string format
+// [Files] Amitse.sdl, commonhelper.c and numeric.c
+//
+// 52 9/04/11 3:57a Arunsb
+// [TAG] EIP65320
+// [Category] Improvement
+// [Description] Board module hook for LoadImage failure.
+// Review comment addressed.
+// [Files] Commonhelper.c, amitsestr.uni, boot.c and faketokens.c
+//
+// 51 7/20/11 3:23p Rajashakerg
+// Removed the unwanted function for mouse hot click operation
+//
+// 48 7/01/11 4:23a Rajashakerg
+// Updated to avoid Build errors when build with binaries alone
+//
+// 47 6/30/11 11:52a Arunsb
+// EDKVersion_1_05_RetrieveData wrapper function added to return the
+// EDK_1_05_RETRIEVE_DATA token value.
+//
+// 46 6/30/11 4:00a Arunsb
+// [TAG] EIP57661
+// [Category] New Feature
+// [Description] Boot manager algorithm for interaction with Driver
+// Health protocol.
+// Wrapper functions added.
+// Added board module hook to perform rebooting the
+// system.
+// [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+// commonhelper.c, uefisetup.ini, tsedrvhealth.h,
+// amivfr.h, minisetupbin.mak,
+// hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+// special.h, boot.h, minisetup.h,
+// uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+// uefi21wapper.c.
+//
+// 45 6/29/11 4:35p Rajashakerg
+// Updated for Help frame scroll changes
+//
+// 44 6/29/11 2:01p Arunsb
+// gHotKeyBootOption declaration added and the same is removed in
+// commonoem.c file.
+//
+// 43 6/29/11 1:32p Rajashakerg
+// [TAG] EIP47086
+// [Category] New Feature
+// [Description] Right clicking from the Main page is not exiting from
+// BIOS setup.
+//
+// [Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+// Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif,
+// EzportPlus\style.h, EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak,
+// EzportPlus\EzportPlusBin.cif, EzportPlus\ezportplus.c, Legacy\style.h,
+// Legacy\EzportPlusBin.sdl, Legacy\LegacyBin.mak, Legacy\LegacyBin.cif,
+// Legacy\legacy.c, TseLiteBin.sdl, TseLite.cif, Memo.c, frame.c,
+// application.h, application.c, commonoem.h, CommonHelper.c
+//
+// 42 6/29/11 5:50a Arunsb
+// [TAG] EIP 62631
+// [Category] New Feature
+// [Description] Hot key boot option support in TSE as per UEFI spec.
+// section 3.1.6.
+// CheckAdvShiftState function moved from commonoem.c to
+// here.
+// LaunchHotKeyBootOption function added to launch hot key
+// boot device.
+// [Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c,
+// commonoem.c, commonoem.h, boot.c,
+// hiistring20.c, hiistring21.c and notify.c.
+//
+// 41 6/23/11 3:39p Rajashakerg
+// [TAG] EIP55762, 58925, 59971
+// [Category] New Feature
+// [Description] Support REF2,REF3 and REF4 in AMITSE
+// Support direct form navigation path
+// Improper layout of controls in the root page when Dynamic pages are
+// added using the Legacy Setup Style
+// [Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c,
+// Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c,
+// minisetupext.h, numeric.c, page.c Popupstring.c, Hii.c,
+// Uefi21Wrapper.c, Parse.c Hii.c
+//
+// 40 6/23/11 5:30a Rajashakerg
+// [TAG] EIP63073
+// [Category] New Feature
+// [Description] Source modules in TSE should get the version details
+// from binary in run time not at build time
+// [Files] CommonHelper.c, minisetupext.c, notify.c, Ezport\style.c,
+// EzportPlus\style.c, Legacy\style.c
+//
+// 37 6/20/11 11:41a Rajashakerg
+// [TAG] EIP59417
+// [Category] New Feature
+// [Description] Spport LOAD_OPTION_HIDDEN option in TSE
+// [Files] boot.h, AMITSE.sdl, CommonHelper.c, bbs.c, boot.c,
+// minisetup.h, special.c, callback.c
+//
+// 36 6/19/11 4:13p Arunsb
+// [TAG] EIP58712
+// [Category] New Feature
+// [Description] To disable the BIOS Signon Message and TSE copyright
+// version in post screen.
+// [Files] amitse.sdl, amitse.mak, commonhelper.c and notify.c
+//
+// 35 6/13/11 12:37p Rajashakerg
+// [TAG] EIP60910
+// [Category] New Feature
+// [Description] PNG image support in TSE.
+// [Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c,
+// png.h, pnguncmp.c, TseAdvanced.cif
+//
+// 34 6/04/11 1:54p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Wrapper function added for InvalidateStatusInBgrt
+// function.
+// [Files] Postmgmt.c, boot.c, logo.c commonoem.c and
+// commonhelper.c
+//
+// 33 5/29/11 12:02p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Quiet boot logo's only added for BGRT. BGRT status
+// field cleared if any changes happened in screen other than displaying
+// the image.
+// [Files] Postmgmt.c, boot.c, logo.c commonoem.c and
+// commonhelper.c
+//
+// 32 5/13/11 12:42p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Contributing BGRT table to ACPI table. Image blt formed
+// with the coordinates drawn onto the screen.
+// [Files] Postmgmt.c, commonoem.c,logo.c and commonhelper.c
+//
+// 31 5/04/11 5:03p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Contributing BGRT table to ACPI table.
+// CONTRIB_BGRT_TABLE_TO_ACPI token added. Wrapper function
+// ContribBGRTTableToAcpi added.
+// [Files] Postmgmt.c, commonoem.c,logo.c and commonhelper.c
+//
+// 30 4/29/11 5:03p Arunsb
+// For 2.13 public patch release signon message hiding feature is omitted
+//
+// 29 4/29/11 4:49p Madhans
+// [TAG] EIP59177
+// [Category] Improvement
+// [Description] Support for JPEG with RSI markers. Fix to support logo
+// size that bigger then Screen resolution.
+// [Files] Logo.c
+// Jpeg6.c
+// commonHelper.c
+//
+// 28 4/23/11 4:56p Arunsb
+// [TAG] EIP58712
+// [Category] New Feature
+// [Description] To disable the BIOS Signon Message and TSE copyright
+// version in post screen.
+// [Files] amitse.sdl, amitse.mak, commonhelper.c and notify.c
+//
+// 27 4/23/11 3:13p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Contributing BGRT table to ACPI table.
+// CONTRIB_BGRT_TABLE_TO_ACPI token added.
+// [Files] Postmgmt.c, commonoem.c and commonhelper.c
+//
+// 26 4/22/11 5:34p Arunsb
+// [TAG] EIP58009
+// [Category] Bug Fix
+// [RootCause] Certain controls not compatible with UEFI 2.3 version.
+// [Solution] The UEFI 2.3 features will be added only if core supports
+// it.
+// [Files] Hiicallback.c and commonhelper.c
+//
+// 25 4/04/11 10:40a Arunsb
+// Small logo cleared properly when it is placed at the top most
+//
+// 24 4/04/11 10:31a Arunsb
+// Added GetGraphicsBitMapFromFV function.
+//
+// 23 3/28/11 11:39p Madhans
+// [TAG] EIP50878
+// [Category] Improvement
+// [Description] Support to move the Control With Boot Order Change.
+// [Files] AMITSE.sdl
+// commonoem.c
+// minisetup.h
+// popupsel.c
+//
+// 22 3/28/11 9:06p Madhans
+// [TAG] EIP41744
+// [Category] Improvement
+// [Description] SoftKeyBoard Support in TSE. and Support to Work with
+// new mouse driver(Label 07).
+// [Files] HookAnchor.h
+// AMITSE.sdl
+// CommonHelper.c
+// commonoem.c
+// commonoem.h
+// HookList.c
+// HookAnchor.c
+// Mouse.c
+// minisetupext.c
+// postmgmtext.c
+// minisetupext.h
+// PopupPassword.c
+// PopupString.c
+// TseLiteCommon.c
+//
+// 21 3/23/11 8:37p Blaines
+// [TAG] - EIP 23601
+// [Category]- Enhancement
+// [Symptom]- Add support for OEM special controls.
+// [Files] - AmiTse.sdl, CommonHelper.c, Setup.ini, UefiSetup.ini,
+// AmiVfr.h, minisetup.h, minisetup.sdl, variable.c, special.c
+//
+// 20 3/15/11 5:12a Rajashakerg
+// [TAG] EIP51671
+// [Category] New Feature
+// [Description] Boot overide menu devices are not disable
+// [Files] boot.c, minisetup.h, special.c, minisetupext.c, AMITSE.sdl,
+// boot.h, CommonHelper.c
+//
+// 19 3/07/11 4:54p Arunsb
+// [TAG] EIP53106
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Invalid string appears in the boot order for Network
+// related devices.
+// [RootCause] Handle not obtained for network related devices.
+// [Solution] Disabled option is checked only if
+// GROUP_BOOT_OPTIONS_BY_TAG token is enabled.
+// [Files] bbs.c and commonhelper.c
+//
+// 18 2/10/11 12:31p Blaines
+// [TAG] - EIP 53146
+// [Category]- New Feature
+// [Description] -Add the support to Move the Dynamic IFR Pages under
+// subpages. It should be customizable to move around.
+//
+// 17 12/28/10 6:01p Mallikarjunanv
+// [TAG] EIP41615
+// [Category] New Feature
+// [Description] Added the file browser support for the Add boot option
+// reated controls
+// [Files] AmiVfr.h, AmiTse.sdl, AmiTseStr.uni, CommonHelper.c,
+// Faketokens.c, TseElinks.h, EdkHelper.h, minisetup.h, TseAdvanced.c,
+// AddBootOption.c
+//
+// 16 10/06/10 5:58p Madhans
+// [TAG] - EIP 45620
+// [Category]- Enhancment
+// [Severity]- Mordarate
+// [Symptom]- TSE with TSE_CONTINUE_BOOT_NOW_ON_FAIL ON Not allows to boot
+// to USB group of devices with customized BDS.
+// [RootCause] - BBSTable does not contain the DeviceType called USB. Only
+// in EFI Logical group is created in EFI variables.
+// TSE was checking the DeviceType to set the priorities.
+// [Solution]- TSE is changed to not check for DeviceType in BBSTable. But
+// set the priorities based on LegacyDevOrder.
+// [Files] - bbs.c commonhelper.c minisetup.h
+//
+// 15 10/05/10 5:37p Madhans
+// [TAG] - EIP 45299
+// [Category]- Enhancment
+// [Severity]- Minor
+// [Symptom]- TSE by default saves the Disbaled BBS devices device path in
+// NVRAM Varaiable "DisabledDevs" Variable. In Next boots it depend on
+// this variable to consider the device as disabled inaddtion to
+// LegacyDevOrder.
+// Some BDS customized projects don't want this.
+// [Solution]- TSE_SAVE_DISABLED_BBS_DEVICEPATH SDL token created to
+// control this option. Bydefault It is Enabled.
+// [Files] - callback.c bbs.c commonhelper.c minisetup.h AMITSE.sdl
+//
+// 14 9/20/10 6:46p Madhans
+// [TAG] EIP44542
+// [Category] BUILD ISSUE FIX
+// [Symptom] Build issues with TSE label (INT)4.6.2_TSE_2_10_1207_TEST
+// when IdeSecurity and FastBoot modules added to the project
+// [RootCause] -
+// [Solution] Build issues resolved
+// [Files] CommonHelper.c, Tsecommon.h, Hiilib.h, Boot.h, minisetup.h,
+// bbs.c, special.c, Bds.c TseLitehelp
+//
+// 13 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 35 9/08/10 6:57a Mallikarjunanv
+// EIP-42080: TSE updates with respect to Fast Boot Support
+//
+// 34 8/27/10 4:54a Mallikarjunanv
+// EIP-39334: support to build TSE without the CSM module support
+//
+// 33 8/27/10 4:43a Mallikarjunanv
+// EIP-39764: Setup password non-case sensitive support and password
+// encode support updated
+//
+// 32 8/19/10 12:50p Mallikarjunanv
+// EIP-42520: Updated to get the BBS group type from the Board module in
+// case of a non standard type.
+//
+// 31 8/13/10 11:03a Mallikarjunanv
+// EIP-39670: handled the function CheckIsAllowedPasswordChar() with
+// override token
+//
+// 30 7/28/10 4:47a Mallikarjunanv
+// EIP-29951: TSE Device Path Name support updated
+//
+// 29 6/08/10 4:59p Blaines
+// Add SDL tokens to overrie the following functions:
+//
+// TseFramePwdCallbackIdePasswordUpdate
+// TsePopupPwdAuthenticateIDEPwd
+// TsePopupPwdUpdateIDEPwd
+// IDEPasswordGetName
+// IDEPasswordAuthenticate
+// IDEPasswordUpdate
+// IDEPasswordGetDataPtr
+// IDEPasswordGetLocked
+// IDEPasswordCheck
+// IDEPasswordFreezeDevices
+// UnlockHDD
+// SetHDDPassword
+// IDEUpdateConfig
+//
+// 28 4/07/10 6:23p Madhans
+// Post Screen Scroll Area Support.TSE_POSTSCREEN_SCROLL_AREA Sdl token
+// Controls it.
+//
+// 27 4/02/10 4:46p Madhans
+// To getride of OEM header files from TSE sources..
+//
+// 26 3/26/10 6:08p Madhans
+// Eip 35562 To create Boot Option variables
+//
+// 25 3/23/10 5:03p Blaines
+// Preseve the order of disabled BBS boot devices.
+//
+// 24 3/19/10 2:39p Madhans
+// Support to Load Defaults from NVRAM Defaults.
+//
+// 23 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 22 2/15/10 10:01p Madhans
+// Wide Glyph support for uefi 2.1
+//
+// 21 2/04/10 11:07p Madhans
+// Mouse Support Code optimized
+//
+// 20 1/29/10 5:15p Madhans
+// To avoid build error of CSM support is off
+//
+// 19 1/25/10 1:35a Mallikarjunanv
+// eip-24791: changed the function BBSBuildName as a board module hook
+//
+// 18 1/09/10 2:32a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 17 1/04/10 9:49a Mallikarjunanv
+// Added support for reserved boot option names and added condition not to
+// accept empty boot option names
+//
+// 16 12/18/09 2:23p Madhans
+// To avoid compiler issues.
+//
+// 15 10/28/09 5:34p Madhans
+// 1. Support to Add the String from other modules to TSE.
+// 2. Clean of GIF and Image code Control them with minimal code from TSE
+// binary.
+//
+//
+// 14 9/24/09 9:42a Sudhirv
+// EIP-24971: moved the dependency for TSE_CONTINUE_BOOT_NOW_ON_FAIL to
+// Tse Binary
+//
+// 13 9/17/09 9:03a Sudhirv
+// Remove Load Driver Option from TSE 2.x as it will be handled from Core
+//
+// 12 9/16/09 6:14p Madhans
+// EIP 25416 : Support have 1/10 sec Timeout
+//
+// 11 9/15/09 9:14a Sudhirv
+// updated ADD DEL boot opions handling and added empty functions to
+// support SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+//
+// 10 8/20/09 6:41p Madhans
+// Fix for the Mouse Click crash issue.
+//
+// 9 8/17/09 9:00a Mallikarjunanv
+// Updated with the board module logo and keyhook fucntions to keep the
+// empty board module as empty
+//
+// 8 8/13/09 12:09p Blaines
+// Move Image support to binary module
+//
+// 7 8/13/09 7:31a Mallikarjunanv
+// eips: 25075, 24971 and hii functions miving from binary to uefi module
+//
+// 6 8/03/09 7:54a Mallikarjunanv
+// Moved the IDE Security related hook functions from Tse Binary to Tse
+// Board Module
+//
+// 5 7/20/09 1:05p Mallikarjunanv
+// updated the code for PASSWORD_WITH_SPECIAL_CHAR_SUPPORT token
+//
+// 4 7/14/09 6:32p Blaines
+// For GTSE first Release.,
+//
+// 3 6/24/09 6:33p Madhans
+// Coding Standards
+//
+// 2 6/08/09 5:33p Madhans
+// Funtionality to get the Lang/PlatformLang variable name based on SDL
+// setting.
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 3 5/07/09 10:31a Madhans
+// Changes After Bin module.
+//
+// 2 4/29/09 9:01p Madhans
+// Bug Fixes after unit Testing..
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 2 1/30/09 6:06p Madhans
+// Function headers added.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: commonhelper.c
+//
+// Description: This file is Helper file for Boot only TSE module
+// This functions may be overridden by Other Advanced TSE module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#pragma warning( disable : 4028 )
+
+#include "TimeStamp.h"
+#ifdef TSE_FOR_APTIO_4_50
+
+#include "Token.h"
+#include <Efi.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/EfiOemBadging.h>
+#include <Protocol/AMIPostMgr.h>
+#include "AMITSEStrTokens.h"
+#include <Protocol/FirmwareVolume.h>
+#include "AmiLib.h" //Added for using CONVERT_TO_STRING macro
+#include "AmiDxeLib.h"
+#include "AMITSEElinks.h"
+#include "AutoId.h" //EIP-112628
+#include "TseElinks.h" //EIP106950
+
+VOID *
+EfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ );
+
+#else //#ifdef TSE_FOR_APTIO_4_50
+
+#include "minisetup.h"
+
+#endif //#ifdef TSE_FOR_APTIO_4_50
+
+#include "commonoem.h"
+#include "LogoLib.h"
+#include "Mem.h"
+#include "HiiLib.h"
+#include "PwdLib.h"
+#include "boot.h"
+#include "bootflow.h"
+#include "variable.h"
+#include "TseCommon.h"
+// Build time file generated from AMITSE_OEM_HEADER_LIST elink.
+#include "AmiTseOem.h"
+#include "SetupData.h"
+#if SUPPORT_ESRT
+#include "amireflashprotocol.h"
+#endif
+
+
+
+
+/////////////OEM_SPECIAL_CONTROL////////////////
+#if SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+//#include "SetupData.h"
+
+VOID *VarGetVariable( UINT32 variable, UINTN *size );
+#define VARIABLE_ID_OEM_TSE_VAR 17
+
+#endif //SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+
+#if SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+UINT16 OEMSpecialGetControlCount(CONTROL_INFO *controlInfo);
+VOID OEMSpecialOneOfFixup( CONTROL_INFO *control , UINT16 value );
+VOID OEMSpecialGotoFixup(CONTROL_INFO *control, UINT16 value );
+#endif //#if SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+
+//#include EFI_PROTOCOL_DEFINITION(LegacyBios)
+
+//EIP:39334 - START
+//#if !TSE_APTIO_5_SUPPORT
+#if !TSE_CSM_SUPPORT
+EFI_GUID gEfiLegacyBiosProtocolGuid = EFI_LEGACY_BIOS_PROTOCOL_GUID;
+#endif
+//#endif
+//EIP:39334 - END
+
+#define VARIABLE_NAME_LENGTH 40
+#define _CharIsUpper(c) ((c >= L'A') && (c <= L'Z'))
+#define _CharIsLower(c) ((c >= L'a') && (c <= L'z'))
+#define _CharIsAlpha(c) (_CharIsUpper(c) || _CharIsLower(c))
+#define _CharIsNumeric(c) ((c >= L'0') && (c <= L'9'))
+#define _CharIsAlphaNumeric(c) (_CharIsAlpha(c) || _CharIsNumeric(c))
+#define _CharIsAlphaNumericSpecial(c) ((c >= (CHAR16)0x20) && (c <= (CHAR16)0x7E))
+#define Str2No(A) (A - '0')
+#define TSE_STRUCT_OFFSET(type, field) (UINTN)&(((type *)0)->field)
+
+//EIP-75236 Starts
+#define NOTIFY_MASK_UGA (0x00000001)
+#define NOTIFY_MASK_CONSOLE_CONTROL (0x00000002)
+#define NOTIFY_MASK_CONSOLE_IN (0x00000004)
+#define NOTIFY_MASK_CONSOLE_OUT (0x00000008)
+#define NOTIFY_MASK_MOUSE_DRIVER (0x00000010)
+
+#if SETUP_DELAY_POST_TILL_GOP
+ #if SETUP_DELAY_LOGO_TILL_INPUT
+ #define SOMETHING (NOTIFY_MASK_UGA | NOTIFY_MASK_CONSOLE_CONTROL | NOTIFY_MASK_CONSOLE_IN | NOTIFY_MASK_CONSOLE_OUT /*| NOTIFY_MASK_MOUSE_DRIVER*/)
+ //EIP160126 no need of mouse dependency lets have only if pwd set
+ #else
+ #define SOMETHING (NOTIFY_MASK_UGA | NOTIFY_MASK_CONSOLE_CONTROL | NOTIFY_MASK_CONSOLE_OUT /*| NOTIFY_MASK_MOUSE_DRIVER*/)
+ #endif
+#else
+ #if SETUP_DELAY_LOGO_TILL_INPUT
+ #define SOMETHING ( NOTIFY_MASK_CONSOLE_CONTROL | NOTIFY_MASK_CONSOLE_IN | NOTIFY_MASK_CONSOLE_OUT /*| NOTIFY_MASK_MOUSE_DRIVER*/)
+ #else
+ #define SOMETHING ( NOTIFY_MASK_CONSOLE_CONTROL | NOTIFY_MASK_CONSOLE_OUT /*| NOTIFY_MASK_MOUSE_DRIVER*/)
+ #endif
+#endif
+//EIP-75236 Ends
+
+#ifndef SCAN_F12
+#define SCAN_F12 EFI_SCAN_F12
+#endif
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_RUNTIME_SERVICES *gRT;
+extern BOOLEAN gQuietBoot;
+VOID *VarGetNvramName( CHAR16 *name, EFI_GUID *guid, UINT32 *attributes, UINTN *size );
+VOID GetTseBuildVersion(UINTN *TseMajor, UINTN *TseMinor, UINTN *TseBuild);//EIP 63073 : Source modules in TSE should get the version details from binary in run time not at build time
+
+#if TSE_FOR_64BIT
+CHAR16 gBootFileName[]=L"\\EFI\\BOOT\\BOOTX64.EFI";
+#else
+CHAR16 gBootFileName[]=L"\\EFI\\BOOT\\BOOTIA32.EFI";
+#endif //TSE_FOR_64BIT
+
+#if TSE_CAPITAL_BOOT_OPTION
+CHAR16 gBootFormarSpecifier[]=L"Boot%04X";
+CHAR16 gDriverFormarSpecifier[]=L"Driver%04X";
+#else
+CHAR16 gBootFormarSpecifier[]=L"Boot%04x";
+CHAR16 gDriverFormarSpecifier[]=L"Driver%04x";
+#endif
+
+BOOLEAN gPopupMenuShowAllBbsDev = POPUP_MENU_SHOW_ALL_BBS_DEVICES;
+BOOLEAN gShowAllBbsDev = SETUP_SHOW_ALL_BBS_DEVICES;
+BOOLEAN gIsSaveDisabledBBSDevicePath = TSE_SAVE_DISABLED_BBS_DEVICEPATH;
+BOOLEAN gSetupHideDisableBootOptions = SETUP_HIDE_DISABLE_BOOT_OPTIONS;//EIP:51671 Global declerations to access the tokens from Binary
+BOOLEAN gPopupMenuHideDisableBootOptions = POPUP_MENU_HIDE_DISABLE_BOOT_OPTIONS;
+#ifdef TSE_LOAD_OPTION_HIDDEN
+BOOLEAN gLoadOptionHidden = TSE_LOAD_OPTION_HIDDEN;//EIP:59417 -Global declerations to access the tokens from Binary
+#else
+BOOLEAN gLoadOptionHidden = 0;
+#endif
+
+const UINTN TsePasswordLength = SETUP_PASSWORD_LENGTH;
+
+
+
+
+EFI_STATUS GetGifNextFrame( IN OUT VOID **UgaBlt, OUT UINTN *GifDelay );
+extern VOID DrawBltBuffer( EFI_UGA_PIXEL *UgaBlt, CO_ORD_ATTRIBUTE Attribute, UINTN Width, UINTN Height,
+ INTN DestX, INTN DestY, UINTN BufferWidth);
+
+
+extern EFI_STATUS ConvertBmpToUgaBlt (IN VOID *BmpImage, IN UINTN BmpImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINTN *UgaBltSize, OUT UINTN *PixelHeight, OUT UINTN *PixelWidth );
+
+extern EFI_STATUS ConvertGifToUgaBlt ( IN VOID *GifImage, IN UINTN GifImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINTN *UgaBltSize, OUT UINTN *PixelHeight, OUT UINTN *PixelWidth, OUT UINTN *GifDelay );
+
+extern EFI_STATUS ConvertJPEGToUgaBlt ( IN VOID *JPEGImage, IN UINT32 JPEGImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize, OUT UINT32 *PixelHeight, OUT UINT32 *PixelWidth, OUT UINT32 *punBufferWidth);
+
+extern EFI_STATUS ConvertPCXToUgaBlt ( IN VOID *PCXImage, IN UINT32 PCXImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize, OUT UINT32 *PixelHeight, OUT UINT32 *PixelWidth);
+
+extern EFI_STATUS ConvertPNGToUgaBlt ( IN VOID *PCXImage, IN UINT32 PCXImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize, OUT UINT32 *PixelHeight, OUT UINT32 *PixelWidth);
+//Functions
+VOID DoAddBootOptionFixup (VOID *ControlInfo);
+VOID SpecialFixupDelBootOption( VOID *ControlInfo);
+VOID BootAddBootOption();
+BOOLEAN DoBootDelBootOption(VOID *popupSel);
+void TseUpdateAddDeleteBootVar (void);
+VOID DiscardAddDelBootOptions(VOID);
+VOID SaveAddDelBootOptions();
+UINT16 * TseBootNowinBootOrderInit(VOID);
+EFI_STATUS TseVarBuildAMIDefaults(VOID);
+VOID TSEMouseInit(VOID);
+VOID TSEMouseStop(VOID);
+EFI_STATUS TSEGetCoordinates(INT32 *x, INT32 *y, INT32 *z);
+BOOLEAN TSEIsMouseClickedonSoftkbd(VOID);
+VOID TSEMouseRefresh(VOID);
+VOID TSEMouseFreeze(VOID);
+VOID TSEMouseStart(VOID);
+VOID TSEMouseDestroy(VOID);
+INT32 TSEGetactualScreentop(VOID);
+VOID TSENumericSoftKbdExit(VOID);
+VOID TSENumericSoftKbdInit(VOID);
+VOID TSESetPwdKeyboardLayout(VOID);//EIP-88912
+VOID TSEResetPwdKeyboardLayout(VOID);//EIP-88912
+VOID TSEPrintableKeysSoftKbdInit(VOID);//EIP-89272
+VOID TSEPrintableKeysSoftKbdExit(VOID);//EIP-89272
+EFI_STATUS TSEMouseReadInfo(VOID *MouseInfo);
+EFI_STATUS TSEMouseScrollBarMove(VOID *frame, BOOLEAN bScrollUp, UINT32 Size); //EIP-67049
+EFI_STATUS TSEMouseListBoxScrollBarMove(VOID *listbox, BOOLEAN bScrollUp, UINT32 Size); //EIP-67049
+EFI_STATUS TSEMouseFrameHandleAction( VOID *frame, VOID *action,VOID *control );
+EFI_STATUS TSEMouseSubMenuHandleAction( VOID *submenu, VOID *Data);
+EFI_STATUS TSEMouseMsgBoxHandleAction( VOID *msgbox, VOID *Data,BOOLEAN * pRedraw);
+EFI_STATUS TSEMousePopupSelHandleAction( VOID *popupSel, VOID *Data);
+EFI_STATUS TSEMousePopupEditHandleAction( VOID *PopupEdit, VOID *Data, BOOLEAN * pRedraw );
+EFI_STATUS TSEMouseMenuHandleAction( VOID *menu, VOID *Data );
+EFI_STATUS TSEMouseListBoxHandleAction( VOID *listbox, VOID *Data);
+VOID ClearUserPasswordPolicy(VOID *callbackData,VOID *saveData);
+EFI_STATUS TseFramePwdCallbackIdePasswordUpdate ( VOID *control,VOID *saveData);
+EFI_STATUS TsePopupPwdAuthenticateIDEPwd(VOID *popuppassword, BOOLEAN *AbortUpdate,VOID *data);
+VOID TsePopupPwdUpdateIDEPwd (VOID);
+VOID RTIfrProcessExit(VOID);
+VOID RTIfrProcessAddVarListAndPageIDList(VOID);
+BOOLEAN RTIfrProcessFormIfUpdated(UINT16 link);
+VOID RTIfrProcessRunTimeForms(VOID*ref);
+LOGO_TYPE GetBmpLogoType(UINT8 *ImageData);
+LOGO_TYPE GetGifLogoType(UINT8 *ImageData);
+LOGO_TYPE GetJPEGLogoType(UINT8 *ImageData);
+LOGO_TYPE GetPCXLogoType(UINT8 *ImageData);
+LOGO_TYPE GetOEMLogoType(UINT8 *ImageData);
+VOID CleanUpGif(VOID);
+VOID DoGifAnimate(CO_ORD_ATTRIBUTE Attribute,INTN CoordinateX,INTN CoordinateY);
+UINTN HiiTestPrintLength ( IN CHAR16 *String );
+UINTN UefiHiiTestPrintLength ( IN CHAR16 *String );
+UINTN EfiTestPrintLength ( IN CHAR16 *String );
+VOID BBSSetBootPriorities( BOOT_DATA *pBootData, UINT16 *pOrder, UINTN u16OrderCount);
+BOOLEAN IsBBSDevicePath( EFI_DEVICE_PATH_PROTOCOL *DevicePath );
+CHAR16 * GetBBSBootOptionName( BOOT_DATA *bootData);
+EFI_STATUS BBSSetBootNowPriority( BOOT_DATA *BootData,UINTN uiPrefferedDevice,BOOLEAN ShowAllBbsDev);
+VOID BBSGetDeviceList( VOID );
+VOID BBSBuildDefaultName( CHAR16 *String, VOID *info, UINTN index, VOID *HDDInfo );
+VOID BBSBuildDevicePathName( CHAR16 *String, VOID *info, UINTN index, VOID *HDDInfo );
+VOID SaveBBSOrder(VOID*);
+VOID BBSSetDisabled(UINT16 Index, VOID **DisDPs, UINTN *DPSize);
+VOID RearrangeBBSOrderVariable(VOID *popupSel, UINT8 bIncrease,UINT16 *newOption);
+VOID LoadDefaultLegDevOrder(VOID);
+VOID BBSUpdateOrder(UINT16 *newOption,UINT32 *offset,UINTN *size, VOID **buffer);
+VOID BBSSetBootPriorities_BootOrder(UINT16);
+UINTN GetANSIEscapeCode(CHAR16 *String,UINT8 *Bold,UINT8 *Foreground, UINT8 *Background);
+CHAR16 *StrDup(CHAR16 *String);
+CHAR16 *SkipEscCode(CHAR16 *String);
+BOOLEAN CheckShiftState(UINT32 ActionKey, UINT32 HotkeyState);
+BOOLEAN SupportPrintScreenEvent();
+VOID SupportPrintScreen();
+VOID GetBootLanguages( VOID );
+VOID GetPlatformBootLanguages( VOID );
+VOID RTIfrUpdateVariableInfo( UINT32 ControlVariable, EFI_HANDLE Handle );
+void ClearGrphxScreen (void);
+VOID ConvertBmpandAddBGRT (
+ BOOLEAN GifImagePresence
+ );
+VOID InvalidateStatusInBgrt (VOID);
+UINT32 GetMsgboxWidth(VOID);//EIP74963 : MAX_MSGBOX_WIDTH macro changed as token and handled from binary
+INTN gHotKeyBootOption = -1;
+extern UINT32 gBootFlow;
+VOID InvalidateStatusInBgrtWrapper (VOID);
+
+//EIP70421 & 70422 Support for driver order starts
+VOID SpecialFixupDelDriverOption (VOID *);
+BOOLEAN DoDriverDelDriverOption (VOID *);
+void TseUpdateAddDeleteDriverVar (VOID );
+VOID DiscardAddDelDriverOptions (VOID);
+VOID SaveAddDelDriverOptions ();
+//EIP70421 & 70422 Support for driver order Ends
+VOID UninstallBGRT (VOID); //EIP81830 Support to uninstall the BGRT on legacy boot
+//EIP-75136 ROMHole Support
+LOGO_TYPE GetExtendedLogoType(UINT8 *ImageData);
+//EIP-75136 End
+
+VOID *SavePostScreen( UINTN *SizeOfX, UINTN *SizeOfY );
+VOID RestorePostScreen( VOID *UgaBlt, UINTN SizeOfX, UINTN SizeOfY );
+
+extern BOOT_DATA *gBootData; //EIP 88447
+extern UINTN gBootOptionCount;
+extern EFI_GUID _gBootFlowGuid;
+
+VOID SetupDebugPrint(IN CONST CHAR8 *Format, ...) ;
+#if SUPPRESS_PRINT
+ #define SETUP_DEBUG_TSE(format,...)
+#else //Else of SUPPRESS_PRINT
+ #define SETUP_DEBUG_TSE(format,...) SetupDebugPrint(format, __VA_ARGS__)
+#endif
+
+//EIP106950 : Starts
+//Controlling from binary
+PASSWORD_ENOCDE_LIST_TEMPLATE gPasswordEncodeList [] = {PASSWORD_ENOCDE_LIST {{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, 0}}; //Last structure for avoiding build error.
+UINT32 gEncodeListCount = sizeof (gPasswordEncodeList)/ sizeof (PASSWORD_ENOCDE_LIST_TEMPLATE);
+//EIP106950 : Ends
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------------
+// Procedure: CheckForAddDelBootOption
+//
+// Description: Function to return the SETUP_SUPPORT_ADD_BOOT_OPTION token value
+//
+// Input: None
+//
+// Output: BOOLEAN
+//
+//--------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckForAddDelBootOption ()
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ return 1;
+#else
+ return 0;
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------------
+// Procedure: CheckForAddDelDriverOption
+//
+// Description: Function to return the SETUP_SUPPORT_ADD_DRIVER_OPTION token value
+//
+// Input: None
+//
+// Output: BOOLEAN
+//
+//--------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckForAddDelDriverOption (VOID)
+{
+#ifdef SETUP_SUPPORT_ADD_DRIVER_OPTION
+ return SETUP_SUPPORT_ADD_DRIVER_OPTION; //Since there is no token dependency for this, returning as such
+#else
+ return 0;
+#endif
+}
+
+VOID TseDoAddBootOptionFixup(VOID *ControlInfo )
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ DoAddBootOptionFixup(ControlInfo);
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+
+VOID TSESpecialFixupDelBootOption(VOID *ControlInfo)
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ SpecialFixupDelBootOption(ControlInfo);
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+VOID TSESpecialFixupDelDriverOption (VOID *ControlInfo)
+{
+#if SETUP_SUPPORT_ADD_DRIVER_OPTION
+ SpecialFixupDelDriverOption (ControlInfo);
+#endif
+}
+
+VOID TseBootAddBootOption()
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ BootAddBootOption();
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+VOID TseDriverAddDriverOption ()
+{
+#if SETUP_SUPPORT_ADD_DRIVER_OPTION
+ DriverAddDriverOption ();
+#endif
+}
+
+// EIP-41615: Start.
+EFI_STATUS FileBrowserLaunchFileSystem (UINT32 Variable);
+EFI_STATUS FileBrowserLaunchFilePath (UINT32 Variable);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TseLaunchFileSystem
+//
+// Description: This function to handle launching file system
+//
+// Input: UINT32
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TseLaunchFileSystem
+EFI_STATUS TseLaunchFileSystem (UINT32 Variable)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+#if SETUP_SUPPORT_ADD_BOOT_OPTION || SETUP_SUPPORT_ADD_DRIVER_OPTION //EIP70421 & 70422 Support for driver order
+ Status = FileBrowserLaunchFileSystem (Variable);
+ if(!EFI_ERROR(Status))
+ Status = FileBrowserLaunchFilePath (Variable);
+#endif
+ return Status;
+}
+#endif
+// EIP-41615: End
+
+BOOLEAN TseDoBootDelBootOption(VOID *popupSel)
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ return DoBootDelBootOption(popupSel);
+#else
+ return 0;
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+BOOLEAN TseDoDriverDelDriverOption (VOID *popupSel)
+{
+#if SETUP_SUPPORT_ADD_DRIVER_OPTION
+ return DoDriverDelDriverOption (popupSel);
+#else
+ return 0;
+#endif
+}
+
+void UpdateAddDeleteBootVar(void)
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ TseUpdateAddDeleteBootVar();
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+void UpdateAddDeleteDriverVar (void)
+{
+#if SETUP_SUPPORT_ADD_DRIVER_OPTION
+ TseUpdateAddDeleteDriverVar ();
+#endif
+}
+
+VOID TseDiscardAddDelBootOptions()
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ DiscardAddDelBootOptions();
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+VOID TseDiscardAddDelDriverOptions ()
+{
+#if SETUP_SUPPORT_ADD_DRIVER_OPTION
+ DiscardAddDelDriverOptions ();
+#endif
+}
+
+VOID TseSaveAddDelBootOptions()
+{
+#if SETUP_SUPPORT_ADD_BOOT_OPTION
+ SaveAddDelBootOptions();
+#endif //#if SETUP_SUPPORT_ADD_BOOT_OPTION
+}
+
+//EIP70421 & 70422 Support for driver order
+VOID TseSaveAddDelDriverOptions ()
+{
+#if SETUP_SUPPORT_ADD_DRIVER_OPTION
+ SaveAddDelDriverOptions ();
+#endif
+}
+
+//EIP# 58925 start
+BOOLEAN IsLinkHistorySupport()
+{
+#if SETUP_LINK_HISTORY_SUPPORT
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//EIP# 58925 End
+
+
+//EIP# 72333
+BOOLEAN IsSubMenuDisplayTitle()
+{
+#if SETUP_DISPLAY_SUBMENU_PAGETITLE
+ return 1;
+#else
+ return 0;
+#endif
+}//EIP# 72333
+
+//EIP 75486
+BOOLEAN IsReadOnlyGrayout()
+{
+#if SETUP_GRAYOUT_READONLY_CONTROL
+ return 1;
+#else
+ return 0;
+#endif
+}//EIP# 75486
+
+BOOLEAN IsGroupDynamicPages()
+{
+#if SETUP_GROUP_DYNAMIC_PAGES
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN IsOrphanPagesAsRootPage()
+{
+#if SETUP_ORPHAN_PAGES_AS_ROOT_PAGE
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN IsUpdateBootOrderCursor()
+{
+#if SETUP_UPDATE_BOOT_ORDER_CURSOR
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN IsPreservedDisabledBootOptionOrder()
+{
+#if TSE_PRESERVE_DISABLED_BBS_DEVICE_ORDER
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN IsReservedBootOptionNamesEnable()
+{
+#if SETUP_SUPPORT_RES_ADD_DEL_BOOT_OPTION_NAME
+ return 1;
+#else
+ return 0;
+#endif //#if SETUP_SUPPORT_RES_ADD_DEL_BOOT_OPTION_NAME
+}
+
+//EIP 103381 - START
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsBootTimeOutValueZero
+//
+// Description: function to return TSE_BOOT_TIME_OUT_AS_ZERO value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsBootTimeOutValueZero()
+{
+#ifdef TSE_BOOT_TIME_OUT_AS_ZERO
+ return TSE_BOOT_TIME_OUT_AS_ZERO;
+#else
+ return 0;
+#endif //#if TSE_BOOT_TIME_OUT_AS_ZERO
+}
+//EIP 103381 - END
+
+BOOT_DATA * BootGetBootNowBootData(BOOT_DATA *bootData, UINT16 *BootOrder, UINTN i )
+{
+#if TSE_BOOT_NOW_IN_BOOT_ORDER
+ return BootGetBootData(BootOrder[i]);
+#else
+ return (bootData + i);
+#endif
+}
+
+
+UINT16 * BootNowinBootOrderInit(VOID)
+{
+#if TSE_BOOT_NOW_IN_BOOT_ORDER
+ return TseBootNowinBootOrderInit();
+#else
+ return NULL;
+#endif
+}
+
+
+EFI_STATUS VarBuildAMIDefaults(VOID)
+{
+#if SETUP_USE_AMI_DEFAULTS
+ return TseVarBuildAMIDefaults();
+#else
+ return EFI_UNSUPPORTED;
+#endif // SETUP_USE_AMI_DEFAULTS
+}
+
+///
+/// Mouse Functions
+///
+
+VOID MouseInit(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEMouseInit();
+#endif
+}
+
+BOOLEAN IsMouseSupported(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+BOOLEAN IsSoftKbdSupported(VOID)
+{
+#if AMITSE_SOFTKBD_SUPPORT
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+
+
+VOID MouseStop(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEMouseStop();
+#endif
+}
+
+VOID GetCoordinates(INT32 *x, INT32 *y, INT32 *z)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEGetCoordinates(x,y,z);
+#endif
+}
+
+VOID MouseRefresh(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEMouseRefresh();
+#endif
+}
+BOOLEAN IsMouseClickedonSoftkbd(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEIsMouseClickedonSoftkbd();
+#endif
+return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMouseOnSoftkbd
+//
+// Description: Function to return whether MousePointer is on softkbd or not
+//
+// Input: None
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+TSEIsMouseOnSoftkbd(VOID);
+BOOLEAN IsMouseOnSoftkbd(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ return TSEIsMouseOnSoftkbd();
+#endif
+ return FALSE;
+}
+
+VOID MouseFreeze(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEMouseFreeze();
+#endif
+}
+
+VOID MouseStart(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEMouseStart();
+#endif
+}
+
+VOID NumericSoftKbdInit(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ TSENumericSoftKbdInit();
+#endif
+
+}
+
+VOID NumericSoftKbdExit(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ TSENumericSoftKbdExit();
+#endif
+
+}
+//EIP-88912 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetPwdKeyboardLayout
+//
+// Description: function to initialize SetKeyboardLayout
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetPwdKeyboardLayout(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ TSESetPwdKeyboardLayout();
+#endif
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetPwdKeyboardLayout
+//
+// Description: function to exit ResetKeyboardLayout and reset with default keyboard layout
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ResetPwdKeyboardLayout(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ TSEResetPwdKeyboardLayout();
+#endif
+
+}
+//EIP-88912 Ends
+
+//EIP-89272 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintableKeysSoftKbdInit
+//
+// Description: function to launch PrintableKeysSoftKbd layout
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PrintableKeysSoftKbdInit(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ TSEPrintableKeysSoftKbdInit();
+#endif
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintableKeysSoftKbdExit
+//
+// Description: function to exit PrintableKeysSoftKbd and reset with default keyboard layout
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PrintableKeysSoftKbdExit(VOID)
+{
+#if (MINISETUP_MOUSE_SUPPORT && AMITSE_SOFTKBD_SUPPORT)
+ TSEPrintableKeysSoftKbdExit();
+#endif
+
+}
+//EIP-89272 Ends
+
+EFI_STATUS MouseReadInfo(VOID *MouseInfo)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseReadInfo(MouseInfo);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+VOID MouseDestroy(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ TSEMouseDestroy();
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetactualScreentop
+//
+// Description: function to get the actual screen top value for mouse
+//
+// Input: None
+//
+// Output: INT32
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INT32 GetactualScreentop(VOID)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEGetactualScreentop();//EIP79962 function to return the actual screen top of the setup
+#endif
+
+return 0;
+}
+EFI_STATUS MouseFrameHandleAction( VOID *frame, VOID *action,VOID *control )
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseFrameHandleAction(frame, action, control);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+EFI_STATUS MouseMsgBoxHandleAction( VOID *msgbox, VOID *Data,BOOLEAN * pRedraw)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseMsgBoxHandleAction(msgbox, Data, pRedraw);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+EFI_STATUS MouseMenuHandleAction( VOID *menu, VOID *Data )
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseMenuHandleAction(menu, Data);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+
+EFI_STATUS MouseListBoxHandleAction( VOID *listbox, VOID *Data)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseListBoxHandleAction(listbox, Data);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FramePasswordAdvancedCallback
+//
+// Description: This function to handle password callback inside setup
+//
+// Input: VOID*, VOID*
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_FramePasswordAdvancedCallback
+VOID FramePasswordAdvancedCallback(VOID *callbackData,VOID *saveData)
+{
+#if TSE_CLEAR_USERPW_WITH_ADMINPW
+ ClearUserPasswordPolicy(callbackData,saveData);
+#endif //#if TSE_CLEAR_USERPW_WITH_ADMINPW
+}
+#endif
+
+
+#if !OVERRIDE_FramePwdCallbackIdePasswordUpdate
+EFI_STATUS FramePwdCallbackIdePasswordUpdate ( VOID *control,VOID *saveData)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return TseFramePwdCallbackIdePasswordUpdate ( control,saveData);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+#endif
+
+#if !OVERRIDE_PopupPwdAuthenticateIDEPwd
+EFI_STATUS PopupPwdAuthenticateIDEPwd(VOID *popuppassword, BOOLEAN *AbortUpdate,VOID *data)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return TsePopupPwdAuthenticateIDEPwd(popuppassword, AbortUpdate,data);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+#endif
+
+#if !OVERRIDE_PopupPwdUpdateIDEPwd
+VOID PopupPwdUpdateIDEPwd (VOID)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ TsePopupPwdUpdateIDEPwd ();
+#endif
+}
+#endif
+
+LOGO_TYPE GetBmpLogoType(UINT8 *ImageData)
+{
+#if SETUP_BMP_LOGO_SUPPORT
+// if ( ((BMP_IMAGE_HEADER *)ImageData)->CharB == 'B' && ((BMP_IMAGE_HEADER *)ImageData)->CharM == 'M' )
+ if ( ImageData[0] == 'B' && ImageData[1] == 'M' )
+ return BMP_Logo;
+#endif
+ return Unsupported_Logo;
+}
+
+
+LOGO_TYPE GetGifLogoType(UINT8 *ImageData)
+{
+#if SETUP_GIF_LOGO_SUPPORT
+ if ( 0 == EfiCompareMem(ImageData, "GIF87a", 6) || 0 == EfiCompareMem(ImageData, "GIF89a", 6) )
+ return GIF_Logo;
+#endif
+
+ return Unsupported_Logo;
+}
+
+
+
+LOGO_TYPE GetJPEGLogoType(UINT8 *ImageData)
+{
+
+#if SETUP_JPEG_LOGO_SUPPORT
+ // Start of Image
+ if(0x0D8FF == *((UINT16*)ImageData))
+ return JPEG_Logo;
+#endif
+
+ return Unsupported_Logo;
+}
+
+LOGO_TYPE GetPCXLogoType(UINT8 *ImageData)
+{
+
+#if SETUP_PCX_LOGO_SUPPORT
+ if (((*ImageData) == 0x0A) && (*(ImageData+2) == 0x01))
+ return PCX_Logo;
+#endif
+
+ return Unsupported_Logo;
+}
+
+LOGO_TYPE GetPNGLogoType(UINT8 *ImageData)
+{
+
+#if SETUP_PNG_LOGO_SUPPORT
+ if ((ImageData[0] == 0x89) && (ImageData[1] == 0x50) && (ImageData[2] == 0x4E ) && (ImageData[3] == 0x47 ) && (ImageData[4] == 0x0D ) && (ImageData[5] == 0x0A ) && (ImageData[6] == 0x1A ) && (ImageData[7] == 0x0A ))
+ return PNG_Logo;
+#endif
+
+ return Unsupported_Logo;
+}
+
+LOGO_TYPE GetOEMLogoType(UINT8 *ImageData)
+{
+
+#if SETUP_OEM_FORMAT_LOGO_SUPPORT
+ if(IsOEMLogoType(ImageData))
+ return OEM_Format_LOGO;
+#endif
+
+ return Unsupported_Logo;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertOEMFormatToUgaBltWrapper
+//
+// Description: Wrapper function to process ConvertOEMFormatToUgaBlt
+// functionallity based on SDL token.
+//
+//
+// Input: OEMImage - Pointer to GIF file
+// OEMImageSize - Number of bytes in BmpImage
+// UgaBlt - Buffer containing UGA version of GifImage.
+// UgaBltSize - Size of UgaBlt in bytes.
+// Height - Height of UgaBlt/BmpImage in pixels
+// Width - Width of UgaBlt/BmpImage in pixels
+// Animate -
+//
+// Output: EFI_SUCCESS - UgaBlt and UgaBltSize are returned.
+// EFI_UNSUPPORTED - GifImage is not a valid *.GIF image
+// EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.
+// UgaBltSize will contain the required size.
+// EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertOEMFormatToUgaBltWrapper ( IN VOID *OEMImage, IN UINT32 OEMImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize, OUT UINT32 *Height, OUT UINT32 *Width, BOOLEAN * Animate)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+#if SETUP_OEM_FORMAT_LOGO_SUPPORT
+ Status = ConvertOEMFormatToUgaBlt(
+ ImageData,
+ (UINT32)ImageSize,
+ UgaBlt,
+ (UINT32*)UgaBltSize,
+ (UINT32*)Height,
+ (UINT32*)Width,
+ Animate
+ );
+#endif
+ return Status ;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertBmpToUgaBltWrapper
+//
+// Description: Wrapper function to process ConvertBmpToUgaBlt
+// functionallity based on SDL token.
+//
+// Input: BmpImage - Pointer to BMP file
+// BmpImageSize - Number of bytes in BmpImage
+// UgaBlt - Buffer containing UGA version of BmpImage.
+// UgaBltSize - Size of UgaBlt in bytes.
+// PixelHeight - Height of UgaBlt/BmpImage in pixels
+// PixelWidth - Width of UgaBlt/BmpImage in pixels
+//
+// Output: EFI_SUCCESS - UgaBlt and UgaBltSize are returned.
+// EFI_UNSUPPORTED - BmpImage is not a valid *.BMP image
+// EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.
+// UgaBltSize will contain the required size.
+// EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertBmpToUgaBltWrapper(
+ IN VOID *BmpImage,
+ IN UINTN BmpImageSize,
+ IN OUT VOID **UgaBlt,
+ IN OUT UINTN *UgaBltSize,
+ OUT UINTN *PixelHeight,
+ OUT UINTN *PixelWidth)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+#if SETUP_BMP_LOGO_SUPPORT
+ Status = ConvertBmpToUgaBlt(
+ BmpImage,
+ BmpImageSize,
+ UgaBlt,
+ UgaBltSize,
+ PixelHeight,
+ PixelWidth
+ );
+#endif
+ return Status ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CleanUpExtendedLogoWrapper
+//
+// Description: function to clear the logo
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CleanUpExtendedLogoWrapper()
+{
+#if SETUP_GIF_LOGO_SUPPORT
+ CleanUpGif();
+#endif
+#if SETUP_OEM_FORMAT_LOGO_SUPPORT
+ CleanUpOEMLogo();
+#endif
+ ClearGrphxScreen ();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DoLogoAnimateWrapper
+//
+// Description: function to Handle logo animation
+//
+// Input: CO_ORD_ATTRIBUTE Attribute,
+// INTN CoordinateX,INTN CoordinateY
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DoLogoAnimateWrapper(CO_ORD_ATTRIBUTE Attribute,INTN CoordinateX,INTN CoordinateY)
+{
+
+#if SETUP_GIF_LOGO_SUPPORT
+ DoGifAnimate(Attribute,CoordinateX,CoordinateY);
+#endif
+
+#if SETUP_OEM_FORMAT_LOGO_SUPPORT
+ DoOEMLogoAnimate(Attribute,CoordinateX,CoordinateY);
+#endif
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertGifToUgaBltWrapper
+//
+// Description: Wrapper function to process ConvertGifToUgaBlt
+// functionallity based on SDL token.
+//
+//
+// Input: GifImage - Pointer to GIF file
+// GifImageSize - Number of bytes in BmpImage
+// UgaBlt - Buffer containing UGA version of GifImage.
+// UgaBltSize - Size of UgaBlt in bytes.
+// PixelHeight - Height of UgaBlt/BmpImage in pixels
+// PixelWidth - Width of UgaBlt/BmpImage in pixels
+// GifDelay -
+//
+// Output: EFI_SUCCESS - UgaBlt and UgaBltSize are returned.
+// EFI_UNSUPPORTED - GifImage is not a valid *.GIF image
+// EFI_BUFFER_TOO_SMALL - The passed in UgaBlt buffer is not big enough.
+// UgaBltSize will contain the required size.
+// EFI_OUT_OF_RESOURCES - No enough buffer to allocate
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConvertGifToUgaBltWrapper (
+ IN VOID *GifImage,
+ IN UINTN GifImageSize,
+ IN OUT VOID **UgaBlt,
+ IN OUT UINTN *UgaBltSize,
+ OUT UINTN *PixelHeight,
+ OUT UINTN *PixelWidth,
+ OUT BOOLEAN *Animate
+ )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+#if SETUP_GIF_LOGO_SUPPORT
+ UINTN GifDelay;
+
+ GifDelay = 0;
+
+ Status = ConvertGifToUgaBlt(
+ GifImage,
+ GifImageSize,
+ UgaBlt,
+ UgaBltSize,
+ PixelHeight,
+ PixelWidth,
+ &GifDelay
+ );
+ //the first frame usually doesn't have valid data so we get the
+ //second one and set the timer
+ if(!EFI_ERROR(Status) )
+ {
+ if(GifDelay)
+ {
+ *Animate = TRUE;
+ }
+ }
+
+#endif
+ return Status ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertJPEGToUgaBltWrapper
+//
+// Description: Wrapper function to process ConvertJPEGToUgaBlt
+// functionallity based on SDL token.
+//
+// Input: IN VOID *JPEGImage - Pointer to the memory that has the
+// JPEG Image that need to be decoded.
+// IN UINT32 JPEGImageSize - Size of the JPEG Image
+// IN OUT VOID **UgaBlt - Two cases
+// Case 1: Memory is expected to be allocated by the callee.
+// Address provided as input should be NULL.
+// pointer that will recieve the address of the UGA buffer.
+// The buffer is allocated by callee.
+// This buffer need to be freed by the caller.
+// Case 2: Memory is allocated by the caller
+// IN OUT UINT32 *UgaBltSize - Pointer that stores Size of UgaBlt
+// in bytes. This will be treated as an input. This should have
+// value ZERO for Case 2 above.
+// OUT UINT32 *PixelHeight - Height of UgaBlt/JPEG Image in pixels
+// OUT UINT32 *PixelWidth - Width of UgaBlt/JPEG Image in pixels
+// OUT UINT32 *pun32BufferWidth - Width of UgaBlt/JPEG Buffer
+//
+// Output: EFI_SUCCESS - The image was successfully decoded and placed in the buffer
+// EFI_UNSUPPORTED
+// EFI_BUFFER_TOO_SMALL
+// EFI_OUT_OF_RESOURCES
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertJPEGToUgaBltWrapper (
+ IN VOID *JPEGImage,
+ IN UINT32 JPEGImageSize,
+ IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize,
+ OUT UINT32 *PixelHeight,
+ OUT UINT32 *PixelWidth,
+ OUT UINT32 *pun32BufferWidth)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+#if SETUP_JPEG_LOGO_SUPPORT
+ Status = ConvertJPEGToUgaBlt(
+ JPEGImage,
+ (UINT32)JPEGImageSize,
+ UgaBlt,
+ (UINT32*)UgaBltSize,
+ (UINT32*)PixelHeight,
+ (UINT32*)PixelWidth,
+ (UINT32*)pun32BufferWidth
+ );
+#endif
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertPCXToUgaBltWrapper
+//
+// Description: Wrapper function to process ConvertPCXToUgaBlt
+// functionallity based on SDL token.
+//
+// Input: VOID *PCXImage - Pointer to the memory that has the PCX
+// Image that need to be decoded.
+// UINT32 PCXImageSize - Size of the PCX Image
+// OUT VOID **UgaBlt - Two cases
+// Case 1: Memory is expected to be allocated by the callee.
+// Address provided as input should be NULL.
+// pointer that will receive the address of the UGA buffer.
+// The buffer is allocated by callee.
+// This buffer need to be freed by the caller.
+// Case 2: Memory is allocated by the caller
+// OUT UINT32 *UgaBltSize - Pointer that stores Size of UgaBlt in bytes.
+// This will be treated as an input. This should have value ZERO for Case 2 above.
+// UINT32 *PixelHeight - Height of UgaBlt/PCX Image in pixels
+// UINT32 *PixelWidth - Width of UgaBlt/PCX Image in pixels
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertPCXToUgaBltWrapper (
+ IN VOID *PCXImage,
+ IN UINT32 PCXImageSize,
+ IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize,
+ OUT UINT32 *PixelHeight,
+ OUT UINT32 *PixelWidth)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+#if SETUP_PCX_LOGO_SUPPORT
+ Status = ConvertPCXToUgaBlt (
+ PCXImage,
+ PCXImageSize,
+ UgaBlt,
+ UgaBltSize,
+ PixelHeight,
+ PixelWidth);
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertPNGToUgaBltWrapper
+//
+// Description: Wrapper function to process ConvertPNGToUgaBlt
+// functionallity based on SDL token.
+//
+// Input: VOID *PNGImage - Pointer to the memory that has the PNG
+// Image that need to be decoded.
+// UINT32 PNGImageSize - Size of the PNG Image
+// OUT VOID **UgaBlt - Two cases
+// Case 1: Memory is expected to be allocated by the callee.
+// Address provided as input should be NULL.
+// pointer that will receive the address of the UGA buffer.
+// The buffer is allocated by callee.
+// This buffer need to be freed by the caller.
+// Case 2: Memory is allocated by the caller
+// OUT UINT32 *UgaBltSize - Pointer that stores Size of UgaBlt in bytes.
+// This will be treated as an input. This should have value ZERO for Case 2 above.
+// UINT32 *PixelHeight - Height of UgaBlt/PNG Image in pixels
+// UINT32 *PixelWidth - Width of UgaBlt/PNG Image in pixels
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertPNGToUgaBltWrapper (
+ IN VOID *PNGImage,
+ IN UINT32 PNGImageSize,
+ IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize,
+ OUT UINT32 *PixelHeight,
+ OUT UINT32 *PixelWidth)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+#if SETUP_PNG_LOGO_SUPPORT
+ Status = ConvertPNGToUgaBlt (
+ PNGImage,
+ PNGImageSize,
+ UgaBlt,
+ UgaBltSize,
+ PixelHeight,
+ PixelWidth);
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrProcessExitWrapper
+//
+// Description: Wrapper function to process the RuntimeParsing Exit
+// functionallity based on SDL token.
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RTIfrProcessExitWrapper(VOID)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ RTIfrProcessExit();
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrProcessAddVarListAndPageIDListWrapper
+//
+// Description: Wrapper function to add runtime variable and Pages
+// based on SDL token.
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RTIfrProcessAddVarListAndPageIDListWrapper(VOID)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ RTIfrProcessAddVarListAndPageIDList();
+#endif
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrProcessFormIfUpdatedWrapper
+//
+// Description: Wrapper function to include RTIfrProcessFormIfUpdated
+// based on SDL token.
+//
+// Input: Link
+//
+// Output: Bool
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN RTIfrProcessFormIfUpdatedWrapper(UINT16 link)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ return RTIfrProcessFormIfUpdated(link);
+#else
+ return FALSE;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrUpdateVariableInfoWrapper
+//
+// Description: Wrapper function to include RTIfrUpdateVariableInfo
+// based on SDL token.
+//
+// Input: ControlVariable, Handle
+//
+// Output: Bool
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if UEFI_2_1_SUPPORT
+BOOLEAN RTIfrUpdateVariableInfoWrapper(UINT32 ControlVariable, EFI_HANDLE Handle)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ RTIfrUpdateVariableInfo(ControlVariable, Handle);
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrProcessRunTimeFormsWrapper
+//
+// Description: Wrapper function to process runtime Ifrs
+// based on SDL token.
+//
+// Input: Link
+//
+// Output: Bool
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RTIfrProcessRunTimeFormsWrapper(VOID*ref)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ RTIfrProcessRunTimeForms(ref);
+#endif
+}
+
+EFI_STATUS Uefi20HiiInitializeProtocol( VOID );
+EFI_STATUS Uefi21HiiInitializeProtocol(VOID);
+EFI_STATUS HiiInitializeProtocol( VOID )
+{
+#if UEFI_2_1_SUPPORT
+ return Uefi21HiiInitializeProtocol();
+#else
+ return Uefi20HiiInitializeProtocol();
+#endif
+}
+
+CHAR16 *Uefi20HiiGetStringLanguage( VOID* handle, UINT16 token, CHAR16 *lang );
+CHAR16 *Uefi21HiiGetStringLanguage(VOID * handle, UINT16 token, CHAR16 *lang);
+CHAR16 *HiiGetStringLanguage( VOID* handle, UINT16 token, CHAR16 *lang )
+{
+#if UEFI_2_1_SUPPORT
+ return Uefi21HiiGetStringLanguage(handle,token,lang);
+#else
+ return Uefi20HiiGetStringLanguage(handle,token,lang);
+#endif
+}
+
+UINT16 Uefi20HiiChangeStringLanguage( VOID* handle, UINT16 token, CHAR16 *lang, CHAR16 *string );
+UINT16 Uefi21HiiChangeStringLanguage(VOID* handle, UINT16 token, CHAR16 *lang, CHAR16 *string);
+UINT16 HiiChangeStringLanguage( VOID* handle, UINT16 token, CHAR16 *lang, CHAR16 *string )
+{
+#if UEFI_2_1_SUPPORT
+ return Uefi21HiiChangeStringLanguage( handle, token, lang, string );
+#else
+ return Uefi20HiiChangeStringLanguage( handle, token, lang, string);
+#endif
+}
+
+UINTN Uefi20HiiGetGlyphWidth(VOID);
+UINTN Uefi20HiiGetGlyphHeight(VOID);
+UINTN Uefi21HiiGetGlyphWidth(VOID);
+UINTN Uefi21HiiGetGlyphHeight(VOID);
+UINTN HiiGetGlyphWidth(VOID)
+{
+#if UEFI_2_1_SUPPORT
+ return Uefi21HiiGetGlyphWidth();
+#else
+ return Uefi20HiiGetGlyphWidth();
+#endif
+}
+
+UINTN HiiGetGlyphHeight(VOID)
+{
+#if UEFI_2_1_SUPPORT
+ return Uefi21HiiGetGlyphHeight();
+#else
+ return Uefi20HiiGetGlyphHeight();
+#endif
+}
+
+
+EFI_STATUS GetUnicodeCollection2Protocol(VOID **Protocol);
+EFI_STATUS GetUnicodeCollectionProtocol(VOID **Protocol);
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure : InitUnicodeCollectionProtocol
+//
+// Description : function to add a string
+//
+// Input : .
+//
+// Output : status and VOID** UnicodeCollectionProtocol
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitUnicodeCollectionProtocol(VOID **Protocol)
+{
+#if UEFI_2_1_SUPPORT
+ return GetUnicodeCollection2Protocol(Protocol);
+#else
+ return GetUnicodeCollectionProtocol(Protocol);
+#endif
+}
+
+//----------------------------------------------------------------------------
+// In Aptio UnicodeCollation2 protocol is supported in the same file as
+// UnicodeCollation Protocol depending on EFI_SPECIFICATION_VERSION
+//----------------------------------------------------------------------------
+#include EFI_PROTOCOL_DEFINITION(UnicodeCollation)
+#if UEFI_2_1_SUPPORT
+#ifndef TSE_FOR_APTIO_4_50
+#include EFI_PROTOCOL_DEFINITION(UnicodeCollation2)
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure : MetaiMatch
+//
+// Description : Calles MetaiMatch of EFI_UNICODE_COLLATION2_PROTOCOL or EFI_UNICODE_COLLATION_PROTOCOL
+//
+// Input :
+//
+// Output : Boolean
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MetaiMatch(VOID *Protocol,IN CHAR16 *String,IN CHAR16 *Pattern)
+{
+#if UEFI_2_1_SUPPORT
+ return ((EFI_UNICODE_COLLATION2_PROTOCOL*)Protocol)->MetaiMatch((EFI_UNICODE_COLLATION2_PROTOCOL*)Protocol,String,Pattern);
+#else
+ return ((EFI_UNICODE_COLLATION_PROTOCOL*)Protocol)->MetaiMatch((EFI_UNICODE_COLLATION_PROTOCOL*)Protocol,String,Pattern);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure : StringColl
+//
+// Description : Calles StriColl of EFI_UNICODE_COLLATION2_PROTOCOL or EFI_UNICODE_COLLATION_PROTOCOL
+//
+// Input : VOID *Protocol,IN CHAR16 *String1,IN CHAR16 *String2
+//
+// Output : INTN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN StringColl(VOID *Protocol,IN CHAR16 *String1,IN CHAR16 *String2)
+{
+#if UEFI_2_1_SUPPORT
+ return ((EFI_UNICODE_COLLATION2_PROTOCOL*)Protocol)->StriColl((EFI_UNICODE_COLLATION2_PROTOCOL*)Protocol, String1, String2 );
+#else
+ return ((EFI_UNICODE_COLLATION_PROTOCOL*)Protocol)->StriColl((EFI_UNICODE_COLLATION_PROTOCOL*)Protocol, String1, String2 );
+#endif
+}
+
+UINTN TestPrintLength ( IN CHAR16 *String )
+{
+#if WIDE_GLYPH_SUPPORT
+#if !UEFI_2_1_SUPPORT
+ return HiiTestPrintLength ( String );
+#else
+ return UefiHiiTestPrintLength ( String );
+#endif /* #if !UEFI_2_1_SUPPORT */
+#else
+ return EfiTestPrintLength ( String );
+#endif //WIDE_GLYPH_SUPPORT
+}
+
+//#undef TSE_CSM_SUPPORT
+//#define TSE_CSM_SUPPORT 0
+
+
+VOID CsmBBSSetBootPriorities( BOOT_DATA *pBootData, UINT16 *pOrder, UINTN u16OrderCount)
+{
+#if TSE_CSM_SUPPORT
+ BBSSetBootPriorities( pBootData, pOrder, u16OrderCount);
+#endif
+}
+
+BOOLEAN BBSValidDevicePath( EFI_DEVICE_PATH_PROTOCOL *DevicePath )
+{
+#if TSE_CSM_SUPPORT
+ return IsBBSDevicePath(DevicePath);
+#else
+ return FALSE;
+#endif
+}
+
+//----------------------------------------------------------------------------
+// Procedure: CsmBBSBootOptionName
+//
+// Description: Override function. OEM can override this function to change the
+// default behaviour of function
+//----------------------------------------------------------------------------
+#if !OVERRIDE_CsmBBSBootOptionName
+CHAR16 * CsmBBSBootOptionName( BOOT_DATA *bootData)
+{
+#if TSE_CSM_SUPPORT
+ return GetBBSBootOptionName( bootData);
+#else
+ return NULL;
+#endif
+}
+#endif
+
+EFI_STATUS CsmBBSSetBootNowPriority( BOOT_DATA *BootData,UINTN uiPrefferedDevice,BOOLEAN ShowAllBbsDev)
+{
+#if TSE_CSM_SUPPORT
+ return BBSSetBootNowPriority( BootData, uiPrefferedDevice, ShowAllBbsDev);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+
+VOID CsmBBSGetDeviceList( VOID )
+{
+#if TSE_CSM_SUPPORT
+ BBSGetDeviceList();
+#endif
+}
+EFI_STATUS BBSLaunchDevicePath( EFI_DEVICE_PATH_PROTOCOL *DevicePath );
+EFI_STATUS CsmBBSLaunchDevicePath( EFI_DEVICE_PATH_PROTOCOL *DevicePath )
+{
+#if TSE_CSM_SUPPORT
+ return BBSLaunchDevicePath( DevicePath);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+
+VOID CsmSaveBBSOrder( VOID *nvPtr )
+{
+#if TSE_CSM_SUPPORT
+ SaveBBSOrder(nvPtr);
+#endif
+}
+
+//EIP109382 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure : CsmRearrangeBBSOrder
+//
+// Description : Calls RearrangeBBSOrder function
+//
+// Input : VOID * -> Cache buffer, VOID * -> Default buffer
+//
+// Output : VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RearrangeBBSOrder (NVRAM_VARIABLE *nvPtr, NVRAM_VARIABLE *DefaultBuffer);
+VOID CsmRearrangeBBSOrder (VOID *nvPtr, VOID *DefaultBuffer)
+{
+#if TSE_CSM_SUPPORT
+ RearrangeBBSOrder (nvPtr, DefaultBuffer);
+#endif
+}
+//EIP109382 Ends
+
+VOID CsmBBSSetDisabled(UINT16 Index, VOID **DisDPs, UINTN *DPSize)
+{
+#if TSE_CSM_SUPPORT
+ BBSSetDisabled(Index, DisDPs, DPSize);
+#endif
+}
+
+
+VOID CsmRearrangeBBSOrderVariable(VOID *popupSel, UINT8 bIncrease,UINT16 *newOption)
+{
+#if TSE_CSM_SUPPORT
+ RearrangeBBSOrderVariable(popupSel, bIncrease,newOption);
+#endif
+}
+
+VOID CsmLoadDefaultLegDevOrder(VOID)
+{
+#if TSE_CSM_SUPPORT
+ LoadDefaultLegDevOrder();
+#endif
+}
+
+EFI_STATUS CsmBBSUpdateOrder(UINT16 *newOption,UINT32 *offset,UINTN *size, VOID **buffer)
+{
+#if TSE_CSM_SUPPORT
+ BBSUpdateOrder(newOption,offset,size, buffer);
+ return EFI_SUCCESS;
+#else
+ return EFI_INVALID_PARAMETER;
+#endif
+}
+
+// EIP-24971: Start , moving dependency to board module...
+VOID TseBBSSetBootPriorities_BootOrder(UINT16 Priority)
+{
+#if TSE_CONTINUE_BOOT_NOW_ON_FAIL
+ BBSSetBootPriorities_BootOrder(Priority);
+#endif
+}
+//EIP-24971: End
+
+VOID GetProgressColor(EFI_UGA_PIXEL * BGColor, EFI_UGA_PIXEL * BDRColor, EFI_UGA_PIXEL * FillColor)
+{
+ EFI_UGA_PIXEL backgroundColor = PROGRESSBAR_BACKGROUNDCOLOR;
+ EFI_UGA_PIXEL borderColor = PROGRESSBAR_BORDERCOLOR;
+ EFI_UGA_PIXEL fillColor = PROGRESSBAR_FILLCOLOR;
+
+ MemCopy( BGColor, &backgroundColor, sizeof(EFI_UGA_PIXEL) );
+ MemCopy( BDRColor, &borderColor, sizeof(EFI_UGA_PIXEL) );
+ MemCopy( FillColor, &fillColor, sizeof(EFI_UGA_PIXEL) );
+}
+
+///IDE Password Hooks...
+UINTN gCurrIDESecPage;
+
+#if !OVERRIDE_TSEIDEPasswordGetName
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordGetName
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: UINT16 Index
+//
+// Output: UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 TSEIDEPasswordGetName(UINT16 Index)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return IDEPasswordGetName(Index);
+#else
+ return 0;
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEPasswordAuthenticate
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordAuthenticate
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: CHAR16 *Password, VOID* DataPtr, BOOLEAN bCheckUser
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TSEIDEPasswordAuthenticate(CHAR16 *Password, VOID* DataPtr, BOOLEAN bCheckUser)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return IDEPasswordAuthenticate(Password, DataPtr, bCheckUser);
+#else
+ return FALSE;
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEPasswordUpdate
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordUpdate
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: UINT32 DeviceIndex, CHAR16 *Password, BOOLEAN bCheckUser
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TSEIDEPasswordUpdate( UINT32 DeviceIndex, CHAR16 *Password, BOOLEAN bCheckUser)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return IDEPasswordUpdate(DeviceIndex, Password, bCheckUser);
+#else
+ return FALSE;
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEPasswordGetDataPtr
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordGetDataPtr
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: UINTN Index
+//
+// Output: VOID*
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* TSEIDEPasswordGetDataPtr(UINTN Index)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return IDEPasswordGetDataPtr(Index);
+#else
+ return NULL;
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEPasswordGetLocked
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordGetLocked
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: UINTN Index
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TSEIDEPasswordGetLocked(UINTN Index)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ return IDEPasswordGetLocked(Index);
+#else
+ return FALSE;
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEPasswordCheck
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordCheck
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TSEIDEPasswordCheck()
+{
+ VOID *UgaBlt = NULL;
+ UINTN SizeOfX=0, SizeOfY=0;
+
+#if SETUP_IDE_SECURITY_SUPPORT
+ UgaBlt = SavePostScreen(&SizeOfX, &SizeOfY);
+ IDEPasswordCheck();
+ RestorePostScreen( UgaBlt, SizeOfX, SizeOfY);
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEPasswordFreezeDevices
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEPasswordFreezeDevices
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TSEIDEPasswordFreezeDevices()
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ IDEPasswordFreezeDevices();
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEUnlockHDD
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEUnlockHDD
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TSEUnlockHDD()
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ UnlockHDD();
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSESetHDDPassword
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSESetHDDPassword
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TSESetHDDPassword()
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ SetHDDPassword();
+#endif
+}
+#endif
+
+#if !OVERRIDE_TSEIDEUpdateConfig
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEIDEUpdateConfig
+//
+// Description: Hook function for the IDE Password fuctionality based on
+// the security token SETUP_IDE_SECURITY_SUPPORT
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TSEIDEUpdateConfig(VOID *ideSecConfig, UINTN value)
+{
+#if SETUP_IDE_SECURITY_SUPPORT
+ IDEUpdateConfig(ideSecConfig, value);
+#endif
+}
+#endif
+
+UINTN TseGetANSIEscapeCode(CHAR16 *String,UINT8 *Bold,UINT8 *Foreground, UINT8 *Background)
+{
+#if TSE_ANSI_ESC_CODE_SUPPORT
+ return GetANSIEscapeCode(String, Bold, Foreground, Background);
+#else
+ return 0;
+#endif
+}
+
+CHAR16 *TseSkipEscCode(CHAR16 *String)
+{
+#if TSE_ANSI_ESC_CODE_SUPPORT
+ return (CHAR16 *)SkipEscCode(String);
+#else
+ return StrDup(String);
+#endif
+}
+
+BOOLEAN TseCheckShiftState(AMI_EFI_KEY_DATA ActionKey, UINT32 HotkeyState)
+{
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ return (TSE_CHECK_SHIFTSTATE(ActionKey.KeyState.KeyShiftState, HotkeyState));
+#else
+ return 1;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TsePrintScreenSupport
+//
+// Description: Function to return print screen support feature
+//
+// Input: UINT16 ScanCode
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TsePrintScreenEventSupport(UINT16 ScanCode)
+{
+#if TSE_PRN_SCRN_EVENT_SUPPORT
+ if( ScanCode == TSE_PRN_SCRN_KEY_SCAN )
+ return 1;
+ else
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+
+VOID TseHotkeyPrintScreenSupport()
+{
+#if TSE_PRN_SCRN_EVENT_SUPPORT
+ SupportPrintScreen();
+#endif
+}
+
+BOOLEAN CheckSystemPasswordPolicy(UINT32 PasswordInstalled)
+{
+#if SETUP_USER_PASSWORD_POLICY
+ return (PasswordInstalled & AMI_PASSWORD_USER)?TRUE:FALSE;
+#else
+ return (PasswordInstalled & AMI_PASSWORD_ANY)?TRUE:FALSE;
+#endif
+}
+
+
+
+extern VOID EfiStrCpy(IN CHAR16 *Destination, IN CHAR16 *Source);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure : GetVariableNameByID
+//
+// Description : function to get Variable Name based on ID
+//
+// Input : UINT32 VariableID
+//
+// Output : CHAR16 *
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR16 *GetVariableNameByID( UINT32 VariableID )
+{
+ CHAR16 *varName = (CHAR16 *)EfiLibAllocateZeroPool(VARIABLE_NAME_LENGTH);
+ if(varName != NULL)
+ {
+ switch(VariableID)
+ {
+ case VARIABLE_ID_LANGUAGE:
+#if SETUP_SUPPORT_PLATFORM_LANG_VAR
+ EfiStrCpy(varName, L"PlatformLang");
+#else
+ EfiStrCpy(varName, L"Lang");
+#endif
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ return varName;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure : GetGUIDNameByID
+//
+// Description : function to get GUID Name based on Variable ID
+//
+// Input : UINT32 VariableID
+//
+// Output : CHAR16 *
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR16 *GetGUIDNameByID( UINT32 VariableID )
+{
+ CHAR16 *guidName = (CHAR16 *)EfiLibAllocateZeroPool(VARIABLE_NAME_LENGTH);
+ if(guidName != NULL)
+ {
+ switch(VariableID)
+ {
+ case VARIABLE_ID_LANGUAGE:
+#if SETUP_SUPPORT_PLATFORM_LANG_VAR
+ EfiStrCpy(guidName, L"PlatformLangCodes");
+#else
+ EfiStrCpy(guidName, L"LangCodes");
+#endif
+ break;
+ default:
+ break;
+ }
+ }
+ return guidName;
+}
+
+VOID BootGetLanguages()
+{
+#if SETUP_SUPPORT_PLATFORM_LANG_VAR
+ GetPlatformBootLanguages();
+#else
+ GetBootLanguages();
+#endif
+}
+
+
+///EIP - 24971
+BOOLEAN PlatformLangVerSupport()
+{
+#if SETUP_SUPPORT_PLATFORM_LANG_VAR
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN BootNowInBootOrderSupport()
+{
+#if TSE_BOOT_NOW_IN_BOOT_ORDER
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+BOOLEAN IsTseLoadPasswordOnDefaults()
+{
+ return TSE_LOAD_PASSWORD_ON_DEFAULTS;
+}
+
+UINT16 GetNoVarStoreBootCountOffset()
+{
+#if NO_VARSTORE_SUPPORT
+ return (UINT16)(TSE_STRUCT_OFFSET(TSE_SETUP_DATA, BootCount));
+#else
+ return 0;
+#endif
+}
+
+
+VOID SetPostScreenScrollArea(UINTN TopRow, UINTN TopCol, UINTN BottomRow, UINTN BottomCol);
+VOID ConfigPostScrollArea(VOID)
+{
+ UINTN X[]= TSE_POSTSCREEN_SCROLL_AREA;
+ SetPostScreenScrollArea(X[0],X[1],X[2],X[3]);
+}
+
+///EIP - 24971
+
+////////// BOARD MODULE FUNCTIONS /////////////
+
+#if !OVERRIDE_CheckIsAllowedPasswordChar
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckIsAllowedPasswordChar
+//
+// Description: Check is the char allowed for password control
+// based on SDL token.
+//
+// Input: Input character
+//
+// Output: Bool
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckIsAllowedPasswordChar(CHAR16 Char)
+{
+#if PASSWORD_WITH_SPECIAL_CHAR_SUPPORT
+ return (BOOLEAN)_CharIsAlphaNumericSpecial(Char);
+#else
+ return (BOOLEAN)_CharIsAlphaNumeric(Char);
+#endif
+}
+#endif
+
+#if !OVERRIDE_PopupPasswordFormCallback
+EFI_STATUS PopupPasswordFormCallback(/*CONTROL_INFO*/VOID * pControlData,UINT16 Key,UINT8 Flags)
+{
+ return EFI_UNSUPPORTED;
+}
+#endif
+
+#if !OVERRIDE_PopupPwdHandleActionOverRide
+EFI_STATUS _PopupPasswordHandleAction( VOID *popuppassword, VOID *Data);
+EFI_STATUS PopupPwdHandleActionOverRide(VOID *popuppassword, VOID *Data)
+{
+ return _PopupPasswordHandleAction(popuppassword, Data);
+}
+#endif
+
+#if !OVERRIDE_PasswordCheckInstalled
+UINT32 PasswordCheckInstalledLocal(VOID);
+UINT32 PasswordCheckInstalled( VOID )
+{
+ UINT32 Installed = AMI_PASSWORD_NONE;
+
+ Installed = PasswordCheckInstalledLocal();
+
+ return Installed;
+}
+#endif
+
+#if !OVERRIDE_PasswordAuthenticate
+UINT32 PasswordAuthenticateLocal( CHAR16 *Password );
+UINT32 PasswordAuthenticate( CHAR16 *Password )
+{
+ UINT32 PasswordType = AMI_PASSWORD_NONE;
+
+ PasswordType = PasswordAuthenticateLocal(Password);
+
+ return PasswordType;
+}
+#endif
+
+#if !OVERRIDE_PasswordUpdate
+CHAR16 *PasswordUpdateLocal( CHAR16 *Password, UINTN Size );
+CHAR16 *PasswordUpdate( CHAR16 *Password, UINTN Size )
+{
+ CHAR16 *Buffer = NULL;
+
+ Buffer = PasswordUpdateLocal(Password, Size);
+
+ return Buffer;
+}
+#endif
+
+#if !OVERRIDE_PasswordCommitChanges
+VOID PasswordCommitChanges( BOOLEAN SaveChanges )
+{
+}
+#endif
+
+#if !OVERRIDE_PopupPasswordCheckInstalled
+UINT32 PopupPasswordCheckInstalledLocal(VOID *popuppassword);
+UINT32 PopupPasswordCheckInstalled(VOID *popuppassword)
+{
+ return PopupPasswordCheckInstalledLocal(popuppassword);
+}
+#endif
+
+#if !OVERRIDE_PopupPasswordAuthenticate
+BOOLEAN PopupPasswordAuthenticateLocal( VOID *popuppassword, CHAR16 *Password );
+BOOLEAN PopupPasswordAuthenticate( VOID *popuppassword, CHAR16 *Password )
+{
+ return PopupPasswordAuthenticateLocal( popuppassword, Password );
+}
+#endif
+
+/*
+BOOLEAN IsPasswordSupportNonCaseSensitive()
+{
+#if SETUP_PASSWORD_NON_CASE_SENSITIVE
+ return TRUE;
+#endif
+ return FALSE;
+}
+*/
+
+#if !OVERRIDE_NoVarStoreSupport
+BOOLEAN NoVarStoreSupport(VOID)
+{
+ return NO_VARSTORE_SUPPORT;
+}
+#endif
+
+#if !OVERRIDE_NoVarStoreUpdateSystemAccess
+VOID NoVarStoreUpdateSystemAccess(UINT8 sysAccessValue)
+{
+}
+#endif
+
+#if !OVERRIDE_ItkSupport
+BOOLEAN ItkSupport(VOID)
+{
+ return SETUP_ITK_COMPATIBILITY;
+}
+#endif
+
+
+#if !OVERRIDE_BbsItkBoot
+EFI_STATUS BbsItkBoot()
+{
+ return EFI_UNSUPPORTED;
+}
+#endif
+
+#if !OVERRIDE_GetAMITSEVariable
+VOID GetAMITSEVariableLocal(VOID **mSysConf, UINT8 **setup, UINTN *VarSize);
+VOID GetAMITSEVariable(VOID **mSysConf, UINT8 **setup, UINTN *VarSize)
+{
+ GetAMITSEVariableLocal(mSysConf, setup, VarSize);
+}
+#endif
+
+#if !OVERRIDE_GetBootTimeOut
+UINT16 GetBootTimeOutLocal(UINT16 DefaultValue);
+UINT16 GetBootTimeOut(UINT16 DefaultValue)
+{
+ UINT16 Val;
+
+ Val = GetBootTimeOutLocal(SETUP_DEFAULT_TIMEOUT);
+
+ if(Val == 0xFFFF)
+ return Val;
+ if(SETUP_TIMEOUT_IN_TENTHOFSEC)
+ return Val; //timeout Value Calcualted in 1/0 Sec. Value is already in 1/10 Sec.
+ else
+ {
+ //timeout Value Calcualted in 1/0 Sec. Value is in Sec and Multiply by 10 to make 1/10.
+ if((65530/10) > Val) // To avoid overflow
+ return Val*10;
+ else
+ return 0xFFFE; // return Max timeout possible.
+ }
+
+}
+#endif
+
+#if !OVERRIDE_VarBuildItkDefaults
+VOID VarBuildItkDefaults(VOID)
+{
+}
+#endif
+
+#if !OVERRIDE_SetSystemAccessValueItk
+VOID SetSystemAccessValueItk(UINT8 sysAccessValue)
+{
+}
+#endif
+
+#if !OVERRIDE_FindVarFromITKQuestionId
+UINT32 FindVarFromITKQuestionId(UINT16 QuestionId)
+{
+ return 0;
+}
+#endif
+
+#if !OVERRIDE_IsOEMLogoType
+BOOLEAN IsOEMLogoType(UINT8 *ImageData)
+{
+ // Return TRUE if OEM format.
+ return FALSE;
+}
+#endif
+
+#if !OVERRIDE_ConvertOEMFormatToUgaBlt
+EFI_STATUS ConvertOEMFormatToUgaBlt ( IN VOID *OEMImage, IN UINT32 OEMImageSize, IN OUT VOID **UgaBlt,
+ IN OUT UINT32 *UgaBltSize, OUT UINT32 *Height, OUT UINT32 *Width, BOOLEAN * Animate)
+{
+ // Use this override function to convert the oem image to UGABlt.
+ return EFI_UNSUPPORTED;
+}
+#endif
+
+#if !OVERRIDE_CleanUpOEMLogo
+VOID CleanUpOEMLogo(VOID)
+{
+ //Use this override function to free up memory If needed
+}
+#endif
+
+#if !OVERRIDE_DoOEMLogoAnimate
+VOID DoOEMLogoAnimate(CO_ORD_ATTRIBUTE Attribute,INTN CoordinateX,INTN CoordinateY)
+{
+ //Takecare to init the timer to animate.
+}
+#endif
+
+#if !OVERRIDE_BBSBuildName
+VOID BBSBuildName( CHAR16 *String, VOID *info, UINTN index, VOID *HDDInfo )
+{
+#if TSE_CSM_SUPPORT
+#if TSE_DEVICE_PATH_NAME
+ BBSBuildDevicePathName(String, info, index, HDDInfo);
+#else
+ BBSBuildDefaultName(String, info, index, HDDInfo );
+#endif
+#endif
+}
+#endif
+
+VOID StopClickEvent(VOID);
+/// EIP74591: START
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MainSetupLoopHook
+//
+// Description: Set OVERRIDE_MainSetupLoopHook to 1, if OEM wants to override the MainSetupLoopHook function from Board module.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_MainSetupLoopHook
+EFI_STATUS MainSetupLoop( VOID );
+EFI_STATUS MainSetupLoopHook( VOID )
+{//EIP74591 : Modified MainSetupLoop as board module hook
+ StopClickEvent();//EIP 86253 : Mouse and SoftKbd does not work after displaying "No option to boot to" in POST
+ return MainSetupLoop();
+}
+#endif
+#if EFI_SPECIFICATION_VERSION>=0x2000A
+//EIP77108 : START
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessBrowserActionRequestHook
+//
+// Description: Set OVERRIDE_ProcessBrowserActionRequestHook to 1, if OEM wants to override the ProcessBrowserActionRequestHook function from Board module.
+//
+// Input: EFI_BROWSER_ACTION_REQUEST ActionReq
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_ProcessBrowserActionRequestHook
+EFI_STATUS ProcessBrowserActionRequest(EFI_BROWSER_ACTION_REQUEST ActionReq);
+EFI_STATUS ProcessBrowserActionRequestHook(EFI_BROWSER_ACTION_REQUEST ActionReq)
+{//EIP77108 : Modified ProcessBrowserActionRequest as board module hook
+ return ProcessBrowserActionRequest(ActionReq);
+}
+#endif
+#endif
+//EIP77108 : END
+/// EIP74591: END
+/// EIP-42520: START
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BBSGetNonStandardGroupType
+//
+// Description: Set OVERRIDE_BBSGetNonStandardGroupType to 1, then add the OEM
+// specific function to override this function to provide a non standard
+// group type for the given Device Type.
+//
+// Input: BBS Device Type
+//
+// Output: String Token
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_BBSGetNonStandardGroupType
+UINT16 BBSGetNonStandardGroupType(UINT16 DeviceType)
+{
+ // By default return the Unknown order
+ return STRING_TOKEN(STR_UNKNOWN_ORDER);
+}
+#endif
+/// EIP-42520: END
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEMouseInitHook
+//
+// Description: Hook function which is called when Mouse init is done.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEMouseInitHook
+VOID TSEMouseInitHook(VOID)
+{
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEMouseStopHook
+//
+// Description: Hook function which is called when Mouse Stop is done.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEMouseStopHook
+VOID TSEMouseStopHook(VOID)
+{
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEMouseRefreshHook
+//
+// Description: Hook function which is called when Mouse Refresh action is done.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEMouseRefreshHook
+VOID TSEMouseRefreshHook(VOID)
+{
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEMouseStartHook
+//
+// Description: Hook function which is called when Mouse start action is done.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEMouseStartHook
+VOID TSEMouseStartHook(VOID)
+{
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEMouseDestroyHook
+//
+// Description: Hook function which is called when Mouse Destory is done.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEMouseDestoryHook
+VOID TSEMouseDestroyHook(VOID)
+{
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEMouseIgnoreMouseActionHook
+//
+// Description: Hook function which can make TSE to Ignore the mouse action.
+// This function is called whenever TSE read the mouse action
+// This hook need to be used carefully. It can used in the cases when Mouse
+// actions consumes by modules like Softkeyboard and not to be used by TSE
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+// TRUE - Mouse actions will be ignored by TSE
+// FALSE - Mouse action
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEMouseIgnoreMouseActionHook
+BOOLEAN TSEMouseIgnoreMouseActionHook(VOID)
+{
+ return FALSE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEStringReadLoopEntryHook
+//
+// Description: Hook function which is called when Strings/Password is going to be read.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEStringReadLoopEntryHook
+VOID TSEStringReadLoopEntryHook(VOID)
+{
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TSEStringReadLoopExitHook
+//
+// Description: Hook function which is called after Strings/Password read.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_TSEStringReadLoopExitHook
+VOID TSEStringReadLoopExitHook(VOID)
+{
+}
+#endif
+
+EFI_STATUS GetAdvanceDeviceName( CHAR16 *String, VOID *info, UINTN index, VOID *HDDInfo )
+{
+#if TSE_ADVANCED_BIN_SUPPORT
+ BBSBuildDevicePathName(String, info, index, HDDInfo);
+ return EFI_SUCCESS;
+#endif
+ return EFI_UNSUPPORTED;
+}
+
+CHAR16 *GetUefiDevPathString(EFI_DEVICE_PATH_PROTOCOL *DevPath);
+CHAR16 *TseGetUefiDevPathString(EFI_DEVICE_PATH_PROTOCOL *DevPath)
+{
+#if TSE_DEVICE_PATH_UEFI_NAME
+ return GetUefiDevPathString(DevPath);
+#endif
+ return NULL;
+}
+
+/////////////OEM_SPECIAL_CONTROL////////////////
+#if SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMSpecialGetControlCount
+//
+// Description: OEM Hook Function can allows exploding into multiple controls.
+// Based on the OEM policies it returns number controls need to exploded.
+//
+//
+// Input: CONTROL_INFO *controlInfo
+//
+// Output: UINT16 Control Count.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OEMSpecialGetControlCount
+UINT16 OEMSpecialGetControlCount(CONTROL_INFO *controlInfo)
+{
+// SAMPLE CODE: START
+
+// SAMPLE Code : for One of Special control returns 1 and for Other(Submenu) it returns the OemTseVar
+/*
+ if(controlInfo->ControlType == CONTROL_TYPE_POPUPSEL)
+ return 1;
+ else
+ {
+ UINT16 * pValue=NULL,Val;
+ UINTN size;
+
+ pValue = VarGetVariable( VARIABLE_ID_OEM_TSE_VAR, &size );
+ if(pValue)
+ {
+ Val = *pValue;
+ MemFreePointer((VOID **) &pValue);
+ return Val;
+ }
+ else
+ return 1;
+ }
+*/
+// SAMPLE CODE: END
+
+ //Add the OEM code like above for customization
+
+ return 1;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMSpecialOneOfFixup
+//
+// Description: If the OEM Special control is One of Control the members of the one of control
+// Can be fixed up in this function. If OEM needs multiple control,
+// for each one of it will be called.
+// This function has to create dynamic IFR Oneof Options
+//
+// Input: CONTROL_INFO *control - ControlInfo that need to be patched.
+// UINT16 value - Index of the control that need to be pathched.
+//
+// Output: NONE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OEMSpecialOneOfFixup
+VOID OEMSpecialOneOfFixup( CONTROL_INFO *control , UINT16 value )
+{
+// SAMPLE CODE: START
+
+// Sample Code: To create the One of options based in the OemTSEVar count.
+/*
+ EFI_IFR_ONE_OF *ifrPtr;
+ EFI_IFR_ONE_OF_OPTION *templatePtr, *oneOf;
+
+ VOID *tempPtr;
+ UINTN i, size;
+ CHAR16 Number[]=L"0";
+ UINT16 * pValue=NULL,Val=0;
+
+ pValue = VarGetVariable( VARIABLE_ID_OEM_TSE_VAR, &size );
+ if(pValue)
+ {
+ Val = *pValue;
+ MemFreePointer((VOID **) &pValue);
+ }
+
+ //Create one one_of_option for each OEM option
+ size = sizeof(EFI_IFR_ONE_OF) + sizeof(EFI_IFR_END_ONE_OF) + (Val) * sizeof(EFI_IFR_ONE_OF_OPTION);
+ tempPtr = EfiLibAllocateZeroPool( size );
+ if ( tempPtr == NULL )
+ return;
+
+ ifrPtr = (VOID *)control->ControlPtr;
+ MemCopy( tempPtr, ifrPtr, ifrPtr->Header.Length );
+ control->ControlPtr = (UINTN)tempPtr;
+
+ templatePtr = (EFI_IFR_ONE_OF_OPTION *)((UINTN)ifrPtr + ifrPtr->Header.Length);
+ oneOf = (EFI_IFR_ONE_OF_OPTION *)((UINTN)tempPtr + ifrPtr->Header.Length);
+ for ( i = 0; i < Val; i++, oneOf++ )
+ {
+ MemCopy( oneOf, templatePtr, sizeof(EFI_IFR_ONE_OF_OPTION) );
+ oneOf->Value = (UINT16)i+1;
+ Number[0]=L'0'+(UINT16)i+1;
+ oneOf->Option = HiiAddString( control->ControlHandle, Number );
+ }
+
+ oneOf->Header.OpCode = EFI_IFR_END_ONE_OF_OP;
+ oneOf->Header.Length = sizeof(EFI_IFR_END_ONE_OF);
+
+ ifrPtr = (EFI_IFR_ONE_OF *)control->ControlPtr;
+ control->ControlHelp = ifrPtr->Help;
+*/
+// SAMPLE CODE: END
+
+ //Add the OEM code like above for customization
+
+ return;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMSpecialUpdateOneOf
+//
+// Description: Hook to update the OEM Variable based on Selection.
+// TSE updates the varible buffer in the normal way (updates with option value selected)
+// If any OEM Special updatation required OEM may use this function and return EFI_SUCCESS.
+//
+//
+// Input: newOption - Option value selected.
+// offset - Variable offset
+// Size - size of the variable
+// buffer - OutBuffer Allocate and fill this if OEM Updated the buffer. (Return Success)
+//
+// Output: EFI_SUCCESS - If OEM Updates the Buffer with OEM policy
+// EFI_ERROR (EFI_INVALID_PARAMETER) - Standard TSE Update is enough. No Updates done for OEM
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OEMSpecialUpdateOneOf
+EFI_STATUS OEMSpecialUpdateOneOf(UINT16 newOption,UINT32 *offset,UINTN *size, VOID OUT **buffer)
+{
+
+ return EFI_INVALID_PARAMETER;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMSpecialGotoFixup
+//
+// Description: If the OEM Special control is Submenu Control. Based on the OEMSpecialGetControlCount
+// The submenus are added with same promt/help. If OEM want to Fix the prompt and help fields
+// of the submenu control. It can be done here.
+// For each submenu of that OEM special control it is called.
+//
+// Input: CONTROL_DATA *ctrlData - Control data.
+// UINT16 value - Index of the control that need to be pathched.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OEMSpecialGotoFixup
+VOID OEMSpecialGotoFixup(CONTROL_INFO *control, UINT16 value )
+{
+// SAMPLE CODE: START
+ // Sample Code: To Fix the OEM One of controls prompt based on Value.
+/*
+UINTN
+SPrint (
+ OUT CHAR16 *Buffer,
+ IN UINTN BufferSize,
+ IN CONST CHAR16 *Format,
+ ...
+ );
+
+ CHAR16 str[100];
+ SPrint(str,200,L"OEM Goto Control %d",value);
+ ((EFI_IFR_REF *)control->ControlPtr)->Prompt = HiiAddString( control->ControlHandle,str);
+*/
+// SAMPLE CODE: END
+
+ //Add the OEM code like above for customization
+
+ return;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMSpecialGotoSelect
+//
+// Description: Hook for OEM Goto control Action Handler.
+// On Selection of the OEM Goto control it is called.
+//
+// Input: UINT16 value - Index of the control that is selected
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OEMSpecialGotoSelect
+VOID OEMSpecialGotoSelect(UINT16 value)
+{
+// SAMPLE CODE: START
+/*
+ // Sample Code: To display the message box on what is selected.
+
+ CHAR16 str[100];
+ UINT8 ShowPostMsgBox(IN CHAR16 *MsgBoxTitle,IN CHAR16 *Message,IN UINT8 MsgBoxType);
+
+ SPrint(str,200,L"OEM Goto Control %d Selected",value);
+ ShowPostMsgBox(L"OEM Goto Select",str,MSGBOX_TYPE_OK);
+*/
+// SAMPLE CODE: END
+
+ //Add the OEM code like above for customization
+
+ return;
+}
+#endif
+
+#endif // SETUP_OEM_SPECIAL_CONTROL_SUPPORT
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemCheckControlCondition
+//
+// Description: Set OVERRIDE_OemCheckControlCondition to 1, if OEM wants to override the OemCheckControlCondition function from Board module.
+//
+// Input: UINT8 FinalCond, CONTROL_INFO *controlInfo
+//
+// Output: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OEMCheckControlCondition
+UINT8 OEMCheckControlCondition(UINT8 FinalCond, CONTROL_INFO *controlInfo)
+{
+ return FinalCond;
+}
+#endif
+
+#if !OVERRIDE_FastBootLaunch
+EFI_STATUS FastBootLaunch()
+{
+ return EFI_UNSUPPORTED;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StyleGetMessageboxColorHook
+//
+// Description: Hook function to set Messagebox Color.
+//
+// Input: UINT8 **Color
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_GetMessageboxColorHook
+VOID GetMessageboxColorHook(UINT8 **Color)
+{
+// **Color = EFI_BACKGROUND_LIGHTGRAY | EFI_BLUE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GOPScreenResolution
+//
+// Description: Hook function to set GOPScreen Resolution.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_GOPSetScreenResolutionHook
+EFI_STATUS GOPSetScreenResolutionHook(UINTN *Width, UINTN *Height, UINT32 Index)
+{
+ return EFI_SUCCESS;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LaunchHotKeyBootOption
+//
+// Description: Board module hook for LaunchHotKeyBootOption function
+//
+// Input: BOOT_FLOW *
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_LaunchHotKeyBootOption
+EFI_STATUS LaunchHotKeyBootOption (BOOT_FLOW *Bflow)
+{
+ if (-1 != gHotKeyBootOption)
+ {
+ return (BootLaunchBootOption ((UINT16)gHotKeyBootOption, NULL, 0) );
+ }
+ return EFI_NOT_FOUND;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DriverHealthSystemReset
+//
+// Description: Board module hook for DriverHealthSystemReset function
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_DriverHealthSystemReset
+VOID DriverHealthSystemReset (VOID)
+{
+ CHAR16 *Text = NULL;
+ Text = HiiGetString (gHiiHandle, STRING_TOKEN (STR_DRV_HLTH_REBOOT_POST));
+ PostManagerDisplayPostMessage (Text);
+ gBS->Stall (2000000);
+ gRT->ResetSystem (EfiResetWarm, EFI_SUCCESS, 0, NULL);
+}
+#endif
+
+void SetDesiredTextMode();
+//EIP 89377 : START
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyBootFailHook
+//
+// Description: Board module hook for LegacyBootFailHook function
+// This function invoked when LoadImage fails
+//
+// Input: EFI_STATUS => Status returned from CsmBBSLaunchDevicePath
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void CheckandDeactivateSoftkbd();
+#if !OVERRIDE_LegacyBootFailHook
+VOID LegacyBootFailHook (EFI_STATUS Status)
+{
+ UINT8 Sel;
+ UINT16 OptionToken = STR_CTRL_OK;
+ CHAR16 *Title = NULL;
+ CHAR16 *Message = NULL;
+ AMI_POST_MGR_KEY Key;
+
+ if(EFI_SECURITY_VIOLATION == Status)
+ {
+ MouseInit();
+ CheckandDeactivateSoftkbd (); //EIP-140123 disabling any softkbd activated while showing msgbox
+
+ SetDesiredTextMode(); //EIP94702
+ Title = HiiGetString (gHiiHandle, STRING_TOKEN (STR_SECBOOT_VIOLATION));
+ Message = HiiGetString (gHiiHandle, STRING_TOKEN (STR_SECBOOT_INV_SIGN));
+ ClearScreen( EFI_BACKGROUND_BLACK | EFI_LIGHTGRAY );
+ PostManagerDisplayMsgBoxEx (
+ Title,
+ Message,
+ NULL,
+ MSGBOX_EX_CATAGORY_ERROR,
+ MSGBOX_TYPE_CUSTOM,
+ &OptionToken,
+ 1,
+ NULL,
+ 0,
+ &Sel,
+ &Key
+ );
+ MouseDestroy(); //EIP-140123
+ }
+}
+#endif
+////EIP 89377 : END
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UefiBootFailHook
+//
+// Description: Board module hook for UefiBootFailHook function
+// This function invoked when LoadImage fails
+//
+// Input: EFI_STATUS => Status returned from LoadImage
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_UefiBootFailHook
+VOID UefiBootFailHook (EFI_STATUS Status)
+{
+ UINT8 Sel;
+ UINT16 OptionToken = STR_CTRL_OK;
+ CHAR16 *Title = NULL;
+ CHAR16 *Message = NULL;
+ AMI_POST_MGR_KEY Key;
+
+ if ((EFI_SECURITY_VIOLATION == Status) || (EFI_ACCESS_DENIED == Status))
+ {
+ MouseInit();
+ CheckandDeactivateSoftkbd (); //EIP-140123 disabling any softkbd activated while showing msgbox
+
+ SetDesiredTextMode(); //EIP94702
+ Title = HiiGetString (gHiiHandle, STRING_TOKEN (STR_SECBOOT_VIOLATION));
+ Message = HiiGetString (gHiiHandle, STRING_TOKEN (STR_SECBOOT_INV_SIGN));
+ ClearScreen( EFI_BACKGROUND_BLACK | EFI_LIGHTGRAY );//EIP-79959 Clear screen before display Violatioin MessageBox to avoid screen corruption
+ PostManagerDisplayMsgBoxEx (
+ Title,
+ Message,
+ NULL,
+ MSGBOX_EX_CATAGORY_ERROR,
+ MSGBOX_TYPE_CUSTOM,
+ &OptionToken,
+ 1,
+ NULL,
+ 0,
+ &Sel,
+ &Key
+ );
+ InvalidateStatusInBgrtWrapper (); //Since mode changed invalidating status field in BGRT table. EIP93524
+ MouseDestroy(); //EIP-140123
+ }
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------------------
+// Procedure: UpdateNumericDisplayString
+//
+// Description: Board module hook for UpdateNumericDisplayString function
+// This function invoked before displaying the numeric control
+// Can use this function to change the display style of numeric control
+//
+// Input: CHAR16 ** => Numeric string to be formatted
+// INT64 => Numeric data to be formatted
+// UINT8 => Base of the numeric control, might be AMI_BASE_HEX, AMI_BASE_INT_DEC, AMI_BASE_DEC
+// UINT16 => Width of the numeric control
+// UINT16 => Size of the CHAR16 **Text
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_UpdateNumericDisplayString
+VOID UpdateNumericDisplayString (CHAR16 **Text, INT64 Num, UINT8 Base, UINT16 ControlDataWidth, UINT16 SizeofText)
+{
+#if 0 //Replace 0 with 1
+ #define AMI_BASE_HEX 16
+//Example for showing the numeric hex variables in uppercase and with leading zeroes
+ if (AMI_BASE_HEX == Base)
+ {
+ SPrint (*Text, SizeofText, L"%0*X", (ControlDataWidth * 2), Num);
+ }
+#endif
+}
+#endif
+
+//EIP 88895 Starts
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetUEFISpecVersion
+//
+// Description: Returns the Specification version assigned to TSE_CALLBACK_SPEC_VERSION
+//
+// Input: VOID
+//
+// Output: UINT32 => Callback Version
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_GetUefiSpecVersion
+UINT32 GetUefiSpecVersion (VOID)
+{
+ return TSE_CALLBACK_SPEC_VERSION;
+}
+#endif
+//EIP 88895 Ends
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FBBootFlow
+//
+// Description:
+//
+// Input: BOOT_FLOW *
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FBBootFlow ( BOOT_FLOW * Bflow)
+{
+ gBootFlow = BOOT_FLOW_CONDITION_FAST_BOOT;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsBootOptionsGroupingEnabled
+//
+// Description: Returns the value for grouping the boot options
+//
+// Input: void
+//
+// Output: UINT8 - Value for grouping boot options
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 IsBootOptionsGroupingEnabled (void)
+{
+#ifdef GROUP_BOOT_OPTIONS_BY_TAG
+ return ((UINT8)GROUP_BOOT_OPTIONS_BY_TAG);
+#else
+ return 1; //In older version grouping is defaultly enabled
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSetupHideBiosSignOnMsg
+//
+// Description: Returns the value for hiding the bios signon msg
+//
+// Input: void
+//
+// Output: UINT8 - Value for hiding bios signon msg
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 IsSetupHideBiosSignOnMsg (void)
+{
+#ifdef SETUP_HIDE_BIOS_SIGNON_MESSAGE2
+ return ((UINT8)SETUP_HIDE_BIOS_SIGNON_MESSAGE2);
+#else
+ return 0; //In older version no chance for hiding sign on msg
+#endif
+}
+//EIP-75136 ROMHole support Start
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsOEMPOSTLogoSupport
+//
+// Description: To Return OEMLogo Draw Support token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsOEMPOSTLogoSupport()
+{
+#ifdef TSE_OEM_POSTLOGO_SUPPORT
+ return TSE_OEM_POSTLOGO_SUPPORT;
+#else
+ return 0;
+#endif
+}
+//EIP-75136 ROMHole support End
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetGraphicsBitMapFromFV.
+// This is Override function. OEM can override the default behaviour
+//
+// Description: Return the graphics image file named FileNameGuid into Image
+// and return it's size in ImageSize. All Firmware Volumes (FV)
+// in the system are searched for the file name.
+//
+// Input: FileNameGuid - File Name of graphics file in the FV(s).
+// Image - Pointer to pointer to return graphics image.
+// If NULL, a buffer will be allocated.
+// ImageSize - Size of the graphics Image in bytes. Zero if no image found.
+//
+// Output: EFI_SUCCESS - Image and ImageSize are valid.
+// EFI_BUFFER_TOO_SMALL - Image not big enough. ImageSize has required size
+// EFI_NOT_FOUND - FileNameGuid not found
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_GetGraphicsBitMapFromFV
+EFI_STATUS
+GetGraphicsBitMapFromFV ( IN EFI_GUID *FileNameGuid, OUT VOID **Image, OUT UINTN *ImageSize )
+{
+ EFI_STATUS Status;
+ UINTN FvProtocolCount;
+ EFI_HANDLE *FvHandles;
+ UINTN Index;
+ UINT32 AuthenticationStatus;
+
+#if (TSE_ROMHOLE_SUPPORT) //EIP-75136 Start
+ EFI_FV_FILE_ATTRIBUTES Attrib = (EFI_FV_FILE_ATTRIBUTES)NULL;
+ EFI_FIRMWARE_VOLUME_HEADER *FvVolume = (EFI_FIRMWARE_VOLUME_HEADER *)NULL;
+ EFI_HANDLE processFvHandle = NULL;
+ DXE_SERVICES *DXE_Service = NULL;
+ EFI_TPL CurrentTpl = 0;
+ EFI_GUID DxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;
+ EFI_GUID AMIROMHOLEGuid = TSE_ROMHOLE_HEADER_GUID;
+#endif //EIP-75136 End
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ NULL,
+ &FvProtocolCount,
+ &FvHandles
+ );
+ if (EFI_ERROR (Status))
+ return EFI_NOT_FOUND;
+
+ for (Index = 0; Index < FvProtocolCount; Index++)
+ {
+ Status = gBS->HandleProtocol (
+ FvHandles[Index],
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ (VOID **) &Fv
+ );
+
+ // Assuming Image and ImageSize are correct on input.
+ Status = Fv->ReadSection (
+ Fv,
+ FileNameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ Image,
+ ImageSize,
+ &AuthenticationStatus
+ );
+
+ if (!EFI_ERROR (Status))
+ {
+ //81617 : Avoiding memory leaks in TSE
+ gBS->FreePool(FvHandles);
+ return EFI_SUCCESS;
+ }
+ else if (Status == EFI_BUFFER_TOO_SMALL) // ImageSize updated to needed size so return
+ {
+ //81617 : Avoiding memory leaks in TSE
+ gBS->FreePool(FvHandles);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ }
+//EIP-75136 Start
+#if (TSE_ROMHOLE_SUPPORT)
+
+ for (Index = 0; Index < FvProtocolCount; Index++)
+ {
+ Status = gBS->HandleProtocol (
+ FvHandles[Index],
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ (VOID **) &Fv
+ );
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ // Get FV buffer and FV_ImageSize from RomHole FV
+ Status = Fv->ReadFile (
+ Fv,
+ &AMIROMHOLEGuid,
+ Image,
+ ImageSize,
+ (VOID *)EFI_SECTION_RAW,
+ &Attrib,
+ &AuthenticationStatus
+ );
+
+ if (!EFI_ERROR (Status))//If it found before end of iteration then break the loop
+ {
+ if (*ImageSize)
+ *ImageSize = 0;
+ break;
+ }
+
+ }
+
+ MemFreePointer ((VOID **)&FvHandles);
+ if (EFI_ERROR (Status)){
+ return EFI_NOT_FOUND;
+ }
+
+ DXE_Service = (DXE_SERVICES *)GetEfiConfigurationTable(gST,&DxeServicesTableGuid);
+ FvVolume = (EFI_FIRMWARE_VOLUME_HEADER *)*Image;
+
+ //Raise TPL level to Install FV protocol for ROMHole
+ CurrentTpl = gBS->RaiseTPL( TPL_HIGH_LEVEL );
+ gBS->RestoreTPL( TPL_APPLICATION);
+
+ //Install new FV protocol for ROMHole
+ Status = DXE_Service->ProcessFirmwareVolume (FvVolume, FvVolume->HeaderLength, &processFvHandle);
+
+ //Free Image data after ProcessFirmwareVolume
+ MemFreePointer((VOID **)Image);
+
+ if (EFI_ERROR(Status)){
+ return Status;
+ }
+
+ gBS->RaiseTPL( TPL_HIGH_LEVEL );
+ gBS->RestoreTPL( CurrentTpl );
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ NULL,
+ &FvProtocolCount,
+ &FvHandles
+ );
+
+ if (EFI_ERROR (Status)){
+ return EFI_NOT_FOUND;
+ }
+
+ for (Index = 0; Index < FvProtocolCount; Index++)
+ {
+ Status = gBS->HandleProtocol (
+ FvHandles[Index],
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ (VOID **) &Fv
+ );
+
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ // Assuming Image and ImageSize are correct on input.
+ Status = Fv->ReadSection (
+ Fv,
+ FileNameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ Image,
+ ImageSize,
+ &AuthenticationStatus
+ );
+
+ if (!EFI_ERROR (Status))
+ {
+ MemFreePointer ((VOID **)&FvHandles);
+ return EFI_SUCCESS;
+ }
+ else if (EFI_BUFFER_TOO_SMALL == Status) // ImageSize updated to needed size so return
+ {
+ MemFreePointer ((VOID **)&FvHandles);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ }
+#endif
+//EIP-75136 End
+
+ //81617 : Avoiding memory leaks in TSE
+ gBS->FreePool(FvHandles);
+ return EFI_NOT_FOUND;
+}
+#endif
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetACPIOEMID
+//
+// Description: Returns the ACPI OEM ID
+//
+// Input: VOID
+//
+// Output: UINT8 * => OEM ID String
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 *GetACPIOEMID (VOID)
+{
+#ifdef T_ACPI_OEM_ID
+ return CONVERT_TO_STRING (T_ACPI_OEM_ID);
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetACPIOEMTableID
+//
+// Description: Returns the ACPI OEM Table ID
+//
+// Input: VOID
+//
+// Output: UINT8 * => OEM Table ID String
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 *GetACPIOEMTableID (VOID)
+{
+#ifdef T_ACPI_OEM_TBL_ID
+ return CONVERT_TO_STRING (T_ACPI_OEM_TBL_ID);
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetACPIOEMRevision
+//
+// Description: Returns the ACPI OEM Revision
+//
+// Input: VOID
+//
+// Output: UINT32 => ACPI OEM Revision
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetACPIOEMRevision (VOID)
+{
+#ifdef ACPI_OEM_REV
+ return ACPI_OEM_REV;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: ContribBGRTTableToAcpi
+//
+// Description: Wrapper function to call ConvertBmpandAddBGRT
+//
+// Input: BOOLEAN
+//
+// Output: VOID
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ContribBGRTTableToAcpi (
+ BOOLEAN GifImagePresence
+ )
+{
+#if CONTRIB_BGRT_TABLE_TO_ACPI
+ ConvertBmpandAddBGRT (GifImagePresence);
+#endif
+}
+
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: InvalidateStatusInBgrtWrapper
+//
+// Description: Wrapper function to call InvalidateStatusInBgrt
+//
+// Input: BOOLEAN
+//
+// Output: VOID
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InvalidateStatusInBgrtWrapper (
+ )
+{
+#if CONTRIB_BGRT_TABLE_TO_ACPI
+ InvalidateStatusInBgrt ();
+#endif
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: LoadDefaultsFromDefaultBuffer
+//
+// Description: Wrapper function to provide TSE_LOAD_DEFAULTS_FROM_DEFAULTS_BUFFER
+//
+// Input: BOOLEAN
+//
+// Output: VOID
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+//EIP 105167 : START
+BOOLEAN LoadDefaultsFromDefaultBuffer( VOID )
+{
+
+#ifdef TSE_LOAD_DEFAULTS_FROM_DEFAULTS_BUFFER
+ return TSE_LOAD_DEFAULTS_FROM_DEFAULTS_BUFFER;
+#else
+ return FALSE;
+#endif
+
+}
+//EIP 105167 : END
+
+//EIP81830 starts - Support to uninstall the BGRT on legacy boot starts
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: UninstallBgrtWrapper
+//
+// Description: Wrapper function to call UninstallBgrtWrapper
+//
+// Input: BOOLEAN
+//
+// Output: VOID
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UninstallBgrtWrapper (
+ )
+{
+#if CONTRIB_BGRT_TABLE_TO_ACPI
+ UninstallBGRT ();
+#endif
+}
+//EIP81830 ends
+
+//EIP 63073 START
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetTseBuildVersion
+//
+// Description: Function to fill the TSE build information
+//
+// Input: UINTN *TseMajor, UINTN *TseMinor, UINTN *TseBuild
+//
+// Output: VOID
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetTseBuildVersion(UINTN *TseMajor, UINTN *TseMinor, UINTN *TseBuild)
+{
+ *TseMajor = TSE_MAJOR;
+ *TseMinor = TSE_MINOR;
+ *TseBuild = TSE_BUILD;
+}
+//EIP 63073 END
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetTseBuildYear
+//
+// Description: Function to fill the TSE build Year
+//
+// Input: UINT16 *TseBuildYear
+//
+//
+// Output: VOID
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetTseBuildYear(UINT16 *TseBuildYear)
+{
+ CHAR8 BuildYear[5]=FOUR_DIGIT_YEAR;
+ *TseBuildYear=(Str2No(BuildYear[0])*0x1000+Str2No(BuildYear[1])*0x100+Str2No(BuildYear[2])*0x10+Str2No(BuildYear[3]));
+}
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------------------
+// Procedure: CheckAdvShiftState
+// This is override function. OEM can override default behaviour of this function
+//
+// Description: Checks the input shift state with the condition shift state
+//
+// Input: UINT32 = Key shift state obtained from console input devices
+// UINT32 = Shift state condition to match with input key shift state
+//
+// Output: BOOLEAN = TRUE => When input and condition shift states matches
+// FALSE => When input and condition shift states not matches
+//
+//-----------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_CheckAdvShiftState
+BOOLEAN CheckAdvShiftState (UINT32 AmiKeyShiftState, UINT32 CondShiftState)
+{
+ BOOLEAN Result = TRUE;
+
+ AmiKeyShiftState = AmiKeyShiftState & (~SHIFT_STATE_VALID);
+ CondShiftState = CondShiftState & (~SHIFT_STATE_VALID);
+
+ if (AmiKeyShiftState == CondShiftState)
+ {
+ goto DONE;
+ }
+ else
+ {
+ Result = FALSE;
+ //If condition shift state has both the shift key set then checking for any one pressed
+ if ((CondShiftState & RIGHT_LEFT_SHIFT_PRESSED) == RIGHT_LEFT_SHIFT_PRESSED)
+ {
+ if (!(AmiKeyShiftState & RIGHT_LEFT_SHIFT_PRESSED))
+ {
+ goto DONE;
+ }
+ AmiKeyShiftState &= ~RIGHT_LEFT_SHIFT_PRESSED; //Clearing the left right bits
+ CondShiftState &= ~RIGHT_LEFT_SHIFT_PRESSED;
+ }
+ //If condition shift state has both the Ctrl key set then checking for any one pressed
+ if ((CondShiftState & RIGHT_LEFT_CONTROL_PRESSED) == RIGHT_LEFT_CONTROL_PRESSED)
+ {
+ if (!(AmiKeyShiftState & RIGHT_LEFT_CONTROL_PRESSED))
+ {
+ goto DONE;
+ }
+ AmiKeyShiftState &= ~RIGHT_LEFT_CONTROL_PRESSED;
+ CondShiftState &= ~RIGHT_LEFT_CONTROL_PRESSED;
+ }
+ //If condition shift state has both the Alt key set then checking for any one pressed
+ if ((CondShiftState & RIGHT_LEFT_ALT_PRESSED) == RIGHT_LEFT_ALT_PRESSED)
+ {
+ if (!(AmiKeyShiftState & RIGHT_LEFT_ALT_PRESSED))
+ {
+ goto DONE;
+ }
+ AmiKeyShiftState &= ~RIGHT_LEFT_ALT_PRESSED;
+ CondShiftState &= ~RIGHT_LEFT_ALT_PRESSED;
+ }
+ //If condition shift state has both the logo key set then checking for any one pressed
+ if ((CondShiftState & RIGHT_LEFT_LOGO_PRESSED) == RIGHT_LEFT_LOGO_PRESSED)
+ {
+ if (!(AmiKeyShiftState & RIGHT_LEFT_LOGO_PRESSED))
+ {
+ goto DONE;
+ }
+ AmiKeyShiftState &= ~RIGHT_LEFT_LOGO_PRESSED;
+ CondShiftState &= ~RIGHT_LEFT_LOGO_PRESSED;
+ }
+ if (CondShiftState == AmiKeyShiftState)
+ {
+ Result = TRUE;
+ }
+ }
+DONE:
+ return Result;
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: IsDriverHealthSupported
+//
+// Description: Retrurns DRIVER_HEALTH_SUPPORT token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsDriverHealthSupported (VOID)
+{
+#ifdef DRIVER_HEALTH_SUPPORT
+ return DRIVER_HEALTH_SUPPORT;
+#else
+ return 0; //Defaultly disabled.
+#endif
+}
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: AdvancedRepairSupported
+//
+// Description: Returns the SHOW_DRV_HEALTH_BOOT_TIME_SENDFORM token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN AdvancedRepairSupported (VOID)
+{
+#ifdef HONOR_DRVHLTH_CONFIGREQD_ON_BOOTFAIL
+ return HONOR_DRVHLTH_CONFIGREQD_ON_BOOTFAIL;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: EDKVersion_1_05_RetrieveData
+//
+// Description: Returns the EDK_1_05_RETRIEVE_DATA token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN EDKVersion_1_05_RetrieveData (VOID)
+{
+#ifdef EDK_1_05_RETRIEVE_DATA
+ return EDK_1_05_RETRIEVE_DATA;
+#else
+ return 1;
+#endif
+}
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: SingleClickActivation
+//
+// Description: Returns the SINGLE_CLICK_ACTIVATION token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SingleClickActivation (VOID)
+{
+ return SINGLE_CLICK_ACTIVATION;
+}
+//EIP-74375
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsHelpAreaScrollBarSupport
+//
+// Description: Returns value as enable or disable STYLE_HELP_AREA_SCROLLBAR support
+//
+// Input: void
+//
+// Output: UINT8 - Value for grouping boot options
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsHelpAreaScrollBarSupport (void)
+{
+#if STYLE_HELP_AREA_SCROLLBAR
+ return STYLE_HELP_AREA_SCROLLBAR;
+#else
+ return 0;
+#endif
+}
+//<--End EIP-74375 Control STYLE_HELP_AREA_SCROLLBAR from binary
+
+//Start_EIP-70175 Set Password Popup Window and PopupTextBox color
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPasswordPopupTextBoxColor
+//
+// Description: Function to Get PasswordPopupTextBox Color
+//
+// Input: VOID
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetPasswordPopupTextBoxColor(VOID)
+{
+#if TSE_STYLE_GTSE_BIN_SUPPORT
+ return (EFI_BACKGROUND_BLACK | EFI_WHITE);//For GTSE
+#else
+ return (EFI_BACKGROUND_LIGHTGRAY | EFI_BLUE);//For TSE
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPasswordPopupWindowColor
+//
+// Description: Function to Get PasswordPopupWindow Color
+//
+// Input: VOID
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetPasswordPopupWindowColor(VOID)
+{
+#if TSE_STYLE_GTSE_BIN_SUPPORT
+ return (EFI_BACKGROUND_LIGHTGRAY | EFI_WHITE);//For GTSE
+#else
+ return (EFI_BACKGROUND_BLUE | EFI_WHITE);//For TSE
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPasswordReportInboxcolor
+//
+// Description: Function to Get PasswordReportInBox Color
+//
+// Input: VOID
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetPasswordReportInboxcolor(VOID)
+{
+#if TSE_STYLE_GTSE_BIN_SUPPORT
+ return (EFI_BACKGROUND_LIGHTGRAY | EFI_WHITE);//EIP 81623 : For GTSE IDE security password dialog label name displayed in text field
+#else
+ return (EFI_BACKGROUND_BLUE | EFI_WHITE);//For TSE
+#endif
+}
+//End_EIP-70175
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: IsTSEMultilineControlSupported
+//
+// Description: Retrurns TSE_MULTILINE_CONTROLS token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsTSEMultilineControlSupported (VOID)
+{
+#ifdef TSE_MULTILINE_CONTROLS
+ return TSE_MULTILINE_CONTROLS;
+#endif
+ return FALSE; //Defaultly disabled.
+}
+//EIP74963 : MAX_MSGBOX_WIDTH macro changed as token and handled from binary
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: GetMsgboxWidth
+//
+// Description: Returns the message box width
+//
+// Input: VOID
+//
+// Output: UINT32
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetMsgboxWidth(VOID)
+{
+ return MAX_MSGBOX_WIDTH;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetFormSetTitleAndHelp
+//
+// Description: GetFormSetTitleAndHelp
+//
+// Parameter: EFI_HII_HANDLE Handle, EFI_STRING_ID *Title, EFI_STRING_ID *Help
+//
+// Return value: status
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFormSetTitleAndHelp (EFI_HII_HANDLE Handle, UINT16 *Title, UINT16 *Help);
+EFI_STATUS GetFormSetTitleAndHelpWrapper (VOID *Handle, UINT16 *Title, UINT16 *Help)
+{
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ return GetFormSetTitleAndHelp (Handle, Title, Help);
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+//EIP-88527 Starts
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: IsBGRTSupported
+//
+// Description: Retrurns CONTRIB_BGRT_TABLE_TO_ACPI token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsBGRTSupported (VOID)
+{
+#ifdef CONTRIB_BGRT_TABLE_TO_ACPI
+ return CONTRIB_BGRT_TABLE_TO_ACPI; //Default is ENABLE
+#endif
+ return FALSE;
+}
+//EIP-88527 Ends
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: ClearNumericShiftState
+//
+// Description:
+//
+// Input: VOID*
+//
+// Output:
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ClearNumericShiftState (AMI_EFI_KEY_DATA *Data)
+{
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ Data->KeyState.KeyShiftState = 0;
+#endif
+}
+
+//EIP 88447 Starts
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: FindDevPathTotLength
+//
+// Description: Find the length of the complete device path
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *
+//
+// Output: UINTN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN FindDevPathTotLength (EFI_DEVICE_PATH_PROTOCOL *DevPath)
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDevPath = DevPath;
+ UINTN TotalLength = sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ while (!isEndNode (TempDevPath))
+ {
+ TotalLength += NODE_LENGTH (TempDevPath);
+ TempDevPath = NEXT_NODE (TempDevPath);
+ }
+ return TotalLength;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------
+// Procedure: BootDevPathMatchEnabled
+//
+// Description: Checks whether the input device path matches exactly with any of the boot options
+// device path. This will be useful for USB, Floppy....
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *
+//
+// Output: BOOLEAN - TRUE - Device path matched and the corresponding boot option is enabled
+// FALSE - Device path matched and the corresponding boot option is disbled
+//
+//------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BootDevPathMatchEnabled (EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ UINTN iIndex = 0;
+// UINTN CmpLength = 0; Not used
+ EFI_DEVICE_PATH_PROTOCOL *TempDevPath = DevicePath;
+
+ while (!isEndNode (TempDevPath))
+ {
+ if ((MEDIA_DEVICE_PATH == TempDevPath->Type) && (MEDIA_FILEPATH_DP == TempDevPath->SubType))
+ {
+ for (iIndex = 0; iIndex < gBootOptionCount; iIndex ++)
+ {
+ if (((UINTN)TempDevPath - (UINTN)DevicePath) <= FindDevPathTotLength (gBootData [iIndex].DevicePath))
+ {
+ if (!MemCmp (DevicePath, gBootData [iIndex].DevicePath, (UINTN)TempDevPath - (UINTN)DevicePath))
+ {
+ if (!gBootData [iIndex].Active)
+ {
+ return FALSE;
+ }
+ }
+ }
+ }
+ break;
+ }
+ TempDevPath = NEXT_NODE (TempDevPath);
+ }
+ return TRUE; //If nothing matched then boot from that device path
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------
+// Procedure: MediaDevPathMatchEnabled
+//
+// Description: Checks whether the input device path matches with any of the boot options
+// media device path. This will be useful for drives with partition.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *
+//
+// Output: BOOLEAN - TRUE - Device path matched and the corresponding boot option is enabled
+// FALSE - Device path matched and the corresponding boot option is disbled
+//
+//------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MediaDevPathMatchEnabled (EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ UINTN iIndex = 0;
+ UINTN CmpLength = 0;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevPath = DevicePath;
+
+ while (!isEndNode (TempDevPath))
+ {
+ if ((MEDIA_DEVICE_PATH == TempDevPath->Type) && (MEDIA_HARDDRIVE_DP == TempDevPath->SubType))
+ {
+ CmpLength = NODE_LENGTH (TempDevPath);
+ break;
+ }
+ TempDevPath = NEXT_NODE (TempDevPath);
+ }
+ if (CmpLength)
+ {
+ for (iIndex = 0; iIndex < gBootOptionCount; iIndex ++)
+ {
+ if (CmpLength <= FindDevPathTotLength (gBootData [iIndex].DevicePath))
+ {
+ if (!MemCmp (TempDevPath, gBootData [iIndex].DevicePath, CmpLength))
+ {
+ if (!gBootData [iIndex].Active)
+ {
+ return FALSE;
+ }
+ }
+ }
+ }
+ }
+ return TRUE; //If nothing matched then boot from that device path
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------
+// Procedure: LaunchSecBootPathFromEnabledDevs
+// This is override function. OEM can override default behaviour of this function
+//
+// Description: Launches default image from the path \EFI\BOOT\BOOT{machine type short-name}.EFI
+// from the enabled devices in setup.
+//
+// Input: CHAR16 *
+//
+// Output: EFI_STATUS - EFI_SUCCESS -> If default image loaded successfully
+// !EFI_SUCCESS -> If default image not loaded successfully
+//
+//------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_DEVICE_PATH_PROTOCOL *_BootBuildFileDevicePath( UINT32 *, CHAR16 *);
+EFI_STATUS _BootLaunchDevicePath( EFI_DEVICE_PATH_PROTOCOL *, VOID *, UINTN, BOOLEAN);
+#if !OVERRIDE_LaunchSecBootPathFromEnabledDevs
+EFI_STATUS LaunchSecBootPathFromEnabledDevs (CHAR16 *FileName)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINT32 index = 0;
+
+ EFI_DEVICE_PATH_PROTOCOL *devicePath;
+ do
+ {
+ devicePath = _BootBuildFileDevicePath (&index, FileName);
+ if (index != (UINT32)-1)
+ {
+ if ((BootDevPathMatchEnabled (devicePath)) && (MediaDevPathMatchEnabled (devicePath)))
+ {
+ Status = _BootLaunchDevicePath (devicePath, NULL, 0,FALSE);
+ }
+ }
+ MemFreePointer ((VOID **)&devicePath);
+ } while ((EFI_ERROR (Status)) && (index != (UINT32)-1));
+ return Status;
+}
+#endif
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------
+// Procedure: LaunchSecondaryPath
+//
+// Description: Launches default image from the path \EFI\BOOT\BOOT{machine type short-name}.EFI
+//
+// Input: CHAR16 *
+//
+// Output: EFI_STATUS - EFI_SUCCESS -> If default image loaded successfully
+// !EFI_SUCCESS -> If default image not loaded successfully
+//
+//------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_LaunchSecondaryBootPath
+EFI_STATUS LaunchSecondaryBootPath (CHAR16 *FileName)
+{
+#if SECONDARY_BOOT_FROM_ENABLED_DEVICES
+ return LaunchSecBootPathFromEnabledDevs (FileName); //If user need to boot the default image from only enabled devices
+#else //Default case
+ return BootLaunchFilename (FileName); //EIP 57660 loads the default image from any of the file system
+#endif
+}
+#endif
+//EIP 88447 Ends
+
+//EIP-75236 Starts
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: IsDelayLogoTillInputSupported
+//
+// Description: Retrurns SETUP_DELAY_LOGO_TILL_INPUT token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsDelayLogoTillInputSupported (VOID)
+{
+#ifdef SETUP_DELAY_LOGO_TILL_INPUT
+ return SETUP_DELAY_LOGO_TILL_INPUT;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: GetNotifyMaskValue
+//
+// Description: Retrurns notify mask vaule
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetNotifyMaskValue (VOID)
+{
+//#if AMITSE_SOFTKBD_SUPPORT
+ return SOMETHING;
+/*#else
+ return (SOMETHING & (~NOTIFY_MASK_MOUSE_DRIVER));
+#endif*/
+}
+//EIP-75236 Ends
+
+//EIP-67049 Start
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MouseScrollBarMove
+//
+// Description: Function to move scrollbar in Frame using mouse
+//
+// Parameter: VOID *, BOOLEAN, UINT32
+//
+// Return value: status
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MouseScrollBarMove(VOID *frame, BOOLEAN bScrollUp, UINT32 Size)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseScrollBarMove( frame, bScrollUp, Size );
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MouseListBoxScrollBarMove
+//
+// Description: Function to move scrollbar in ListBox using mouse
+//
+// Parameter: VOID *, BOOLEAN, UINT32
+//
+// Return value: status
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MouseListBoxScrollBarMove(VOID *listbox, BOOLEAN bScrollUp, UINT32 Size)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ return TSEMouseListBoxScrollBarMove( listbox, bScrollUp, Size );
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+//EIP-67049 End
+
+//EIP-94616 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: TseIgnoreKeyForFastBoot
+//
+// Description: Function to return FastBoot is ENABLED or DISABLED
+//
+// Parameter: VOID
+//
+// Return value: BOOLEAN
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN TseIgnoreKeyForFastBoot()
+{
+#if TSE_IGNORE_KEY_FOR_FASTBOOT
+ UINT32 *currentBootFlow;
+ UINTN size = 0;
+
+ currentBootFlow = VarGetNvramName( L"BootFlow", &_gBootFlowGuid, NULL, &size );
+ if (currentBootFlow != NULL && *currentBootFlow == BOOT_FLOW_CONDITION_FAST_BOOT)
+ {
+ MemFreePointer( (VOID **)&currentBootFlow );
+ return TRUE;
+ }
+ else
+ {
+ if (currentBootFlow)
+ {
+ MemFreePointer ((VOID **)&currentBootFlow );
+ }
+ return FALSE;
+ }
+#else
+ return FALSE;
+#endif
+}
+//EIP-94616 Ends
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: IsTSECursorSupport
+//
+// Description: Function to return TSE_CURSOR_SUPPORT token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsTSECursorSupport (VOID)
+{
+#ifdef TSE_CURSOR_SUPPORT
+ return TSE_CURSOR_SUPPORT;
+#else
+ return 0;
+#endif
+}
+
+
+//EIP93521 Starts
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------
+// Procedure: OsUpdateCapsuleWrap
+//
+// Description: Dispalys the image obtained form OS Update and calls the capsule to update
+//
+// Input: BOOT_FLOW *
+//
+// Output: EFI_STATUS - EFI_SUCCESS -> Capsule update is success
+// !EFI_SUCCESS -> Fault happenend in capsule update
+//
+//------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_OsUpdateCapsuleWrap
+TSE_POST_STATUS PostManagerGetPostStatus(VOID);
+LOGO_TYPE GetLogoType(UINT8 *ImageData);
+EFI_STATUS OsUpdateCapsuleWrap (BOOT_FLOW *bootFlowPtr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+#if SUPPORT_ESRT
+ EFI_GUID ReflashGuid = EFI_REFLASH_PROTOCOL_GUID;
+ UINT8 *ImageData = NULL;
+ UINTN ImageSize = 0;
+ UINTN CoordinateX = 0;
+ UINTN CoordinateY = 0;
+ UINTN Width = 0;
+ UINTN Height = 0;
+ UINTN LogoType = 0;
+ UINTN UgaBltSize = 0;
+ UINTN unBufferWidth = 0;
+ EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+ EFI_UGA_PIXEL *UgaBlt = NULL;
+ EFI_REFLASH_PROTOCOL *ReFlash = NULL;
+
+ SETUP_DEBUG_TSE ("\nEntering OsUpdateCapsuleWrap");
+ Status = gBS->LocateProtocol (&ReflashGuid, NULL, &ReFlash);
+ if (!EFI_ERROR (Status))
+ {
+ Status = ReFlash->GetDisplayImage (ReFlash, &CoordinateX, &CoordinateY, &ImageData); //Recovery module have to allocate and send the image data
+ SETUP_DEBUG_TSE ("\nGetDisplayImage status is %x", Status);
+ if (!EFI_ERROR (Status)) //TSE wont free the ImageData
+ { //Recovery module have to provide the X,Y coordinates too
+ Attribute = EfiBadgingDisplayAttributeCustomized; //and wont free the memory
+ Height = 0;
+ Width = 0;
+ LogoType = GetLogoType (ImageData);
+
+ if (BMP_Logo == LogoType) //Draw only for BMP image
+ {
+ Status = ConvertBmpToUgaBltWrapper(
+ ImageData,
+ ImageSize,
+ &UgaBlt,
+ &UgaBltSize,
+ &Height,
+ &Width );
+ SETUP_DEBUG_TSE ("\nStatus for blt wrap is %x", Status);
+ unBufferWidth = Width;
+ SETUP_DEBUG_TSE ("\nCoordinateX is %x CoordinateY is %x", CoordinateX, CoordinateY);
+ SETUP_DEBUG_TSE ("\nDrawing the string");
+ DrawBltBuffer (UgaBlt, Attribute, Width, Height, CoordinateX, CoordinateY, unBufferWidth);
+ }
+ SETUP_DEBUG_TSE ("\nCalling CapUpdProgress");
+ Status = ReFlash->CapUpdProgress (ReFlash);
+ }
+ }
+#endif
+ SETUP_DEBUG_TSE ("\nExiting OsUpdateCapsuleWrap");
+ return Status;
+}
+#endif
+//EIP93521 Ends
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsBootOverrideBootNextSupport
+//
+// Description: Function to return BOOT_OVERRIDE_BOOTNEXT_VARIABLE_FEATURE value
+//
+// Parameter: VOID
+//
+// Return value: BOOLEAN
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsBootOverrideBootNextSupport (VOID)
+{
+#if BOOT_OVERRIDE_BOOTNEXT_VARIABLE_FEATURE
+ return BOOT_OVERRIDE_BOOTNEXT_VARIABLE_FEATURE;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: TseSuppressOneofMultilineSupport
+//
+// Description: Function to return TSE_SUPPRESS_MULTILINE_FOR_ONEOFLABEL value
+//
+// Parameter: VOID
+//
+// Return value: BOOLEAN
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TseSuppressOneofMultilineSupport(VOID)
+{
+
+#ifdef TSE_SUPPRESS_MULTILINE_FOR_ONEOFLABEL
+ return TSE_SUPPRESS_MULTILINE_FOR_ONEOFLABEL;
+#else
+ return FALSE;
+#endif
+
+}
+
+//EIP99059 starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrRegFormNotificationWrapper
+//
+// Description: Wrapper function for RegFormNotification
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RegFormNotification (VOID);
+EFI_STATUS RTIfrRegFormNotificationWrapper (VOID)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ return RegFormNotification ();
+#else
+ return EFI_SUCCESS;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RTIfrUnRegFormNotificationWrapper
+//
+// Description: Wrapper function for UnRegFormNotification
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UnRegFormNotification (VOID);
+VOID RTIfrUnRegFormNotificationWrapper (VOID)
+{
+#if SETUP_RUNTIME_IFR_PROCESSING
+ UnRegFormNotification ();
+#endif
+}
+//EIP99059 ends
+
+//EIP94234 starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: DrawPostLogoAt0Pos
+//
+// Description: Retrurns DRAW_POST_LOGO_AT_0POS token value
+//
+// Parameter: VOID
+//
+// Return value: BOOLEAN
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN DrawPostLogoAt0Pos (VOID)
+{
+#ifdef DRAW_POST_LOGO_AT_0POS
+ return DRAW_POST_LOGO_AT_0POS;
+#else
+ return FALSE;
+#endif
+}
+//EIP94234 ends
+//EIP 93881 & 93873 : START
+//Save pwd to nvram and not loading empty pwd on loading defaults.
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: TSEPwdSavetoNvram
+//
+// Description: Returns the token value for SETUP_SAVE_PSWD_TO_NVRAM
+//
+// Input: VOID
+//
+// Output: UINT32
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TSEPwdSavetoNvram(VOID)
+{
+
+#ifdef SETUP_SAVE_PSWD_TO_NVRAM
+ return SETUP_SAVE_PSWD_TO_NVRAM;
+#endif
+ return FALSE; //Defaultly disabled.
+
+}
+
+//<AMI_PHDR_START>
+//-------------------------------------------------------------------------------------------------------------
+// Procedure: TSEDonotLoadPasswordOnDefaults
+//
+// Description: Returns the token value for TSE_DONOT_LOAD_PASSWORD_ON_DEFAULTS
+//
+// Input: VOID
+//
+// Output: UINT32
+//
+//-------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TSEDonotLoadPasswordOnDefaults(VOID)
+{
+
+#ifdef TSE_DONOT_LOAD_PASSWORD_ON_DEFAULTS
+ return TSE_DONOT_LOAD_PASSWORD_ON_DEFAULTS;
+#endif
+ return FALSE; //Defaultly disabled.
+
+}
+//EIP 93881 & 93873 : END
+//EIP 94205 START
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------
+// Procedure: ShellTextMode
+//
+// Description: Returns type of shell text mode
+//
+// Input: VOID
+//
+// Output: UINT32
+//
+//-----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 ShellTextMode (VOID)
+{//EIP 94205 : OEM needs Token to assign the display mode of SHELL.
+#ifdef SHELL_TEXT_MODE
+ return SHELL_TEXT_MODE;
+#else
+ return 0xFF;
+#endif
+}
+//EIP 94205 END
+
+//EIP-99022 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlushKeysAfterRead
+//
+// Description: Returns value of disable FLUSH_KEYS_AFTER_READ
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FlushKeysAfterRead(VOID)
+{
+#ifdef FLUSH_KEYS_AFTER_READ
+ return FLUSH_KEYS_AFTER_READ;
+#else
+ return 0;
+#endif
+}
+//EIP-99022 Ends
+
+//EIP-112628 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: gotoExitOnEscKey
+//
+// Description: Returns value of disable SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN gotoExitOnEscKey(EFI_GUID *exitPageGuid, UINT16 *pageClass, UINT16 *pageSubclass, UINT16 *pageFormID)
+{
+#if SETUP_GO_TO_EXIT_PAGE_ON_EXIT_KEY
+
+ EFI_GUID ExitPageGuid = EXIT_PAGE_GUID;
+ MemCopy(exitPageGuid, &ExitPageGuid, sizeof(EFI_GUID));
+ *pageClass = (UINT16)EXIT_PAGE_CLASS;
+ *pageSubclass = (UINT16)EXIT_PAGE_SUB_CLASS;
+ *pageFormID = (UINT16)EXIT_PAGE_FORM_ID;
+
+ return TRUE;
+#else
+ return FALSE;
+#endif
+}
+//EIP-112628 ENDS
+
+//EIP-103540 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PISpecVersion
+//
+// Description: Returns PI_SPECIFICATION_VERSION value
+//
+// Input: VOID
+//
+// Output: UINTN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN PISpecVersion(VOID)
+{
+#ifdef PI_SPECIFICATION_VERSION
+ return PI_SPECIFICATION_VERSION;
+#else
+ return 0;
+#endif
+}
+//EIP-103540 Ends
+
+//EIP-116315 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsShowPromptStringAsTitle
+//
+// Description: Returns token value TSE_SHOW_PROMPT_STRING_AS_TITLE
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsShowPromptStringAsTitle(VOID)
+{
+#if TSE_SHOW_PROMPT_STRING_AS_TITLE
+ return TSE_SHOW_PROMPT_STRING_AS_TITLE;
+#else
+ return 0;
+#endif
+}
+//EIP-116315 Ends
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrntScrnKeyHandleactionWrapper
+//
+// Description: Wrapper function to call PrntScrnKeyHandleaction
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteDataToFile(CHAR16 *filename, VOID *Data, UINTN length, UINT32 index);
+EFI_STATUS WriteDataToFileWrapper (CHAR16 *filename, VOID *Data, UINTN length, UINT32 index)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+#if EFI_SPECIFICATION_VERSION>=0x2000A
+ Status = WriteDataToFile (filename, Data, length, index);
+#endif
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UIUpdateCallbackHook
+//
+// Description: Set OVERRIDE_UIUpdateCallbackHook to 1, if OEM wants to override the UIUpdateCallbackHook function from Board module.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_UIUpdateCallbackHook
+VOID UIUpdateCallback( VOID * Handle, UINT32 OldVariableCount );
+VOID UIUpdateCallbackHook( VOID * Handle, UINT32 OldVariableCount )
+{ //EIP 129750 : Modified UIUpdateCallback as module hook
+ UIUpdateCallback((VOID*)Handle, OldVariableCount);
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Procedure: FixMergePagesExtraHook
+//
+// Description: Set OVERRIDE_FixMergePagesExtraHook to 1, if OEM wants to override the UIUpdateCallbackHook function from Board module.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_FixMergePagesExtraHook
+VOID FixMergePagesExtraHook (VOID *gPages, VOID *tempPages)
+{
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Procedure: PageRemoveHook
+//
+// Description: Set OVERRIDE_PageRemoveHook to 1, if OEM wants to override the PageRemoveHook function from Board module.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_PageRemoveHook
+void PageRemoveHook (UINTN PageIndex, void *pageInfo, void *PageHandle, UINT16 PageFormID)
+{
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Procedure: ProcessPackNotificationHook
+//
+// Description: Set OVERRIDE_ProcessPackNotificationHook to 1, if OEM wants to override the ProcessPackNotificationHook function from Board module.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_ProcessPackNotificationHook
+EFI_STATUS ProcessPackNotification (void);
+EFI_STATUS ProcessPackNotificationHook (void)
+{
+ return ProcessPackNotification ();
+}
+#endif
+
+//EIP131739 Starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MainSetupLoopInitHook
+//
+// Description: Set OVERRIDE_MainSetupLoopInitHook to 1, if OEM wants to override the MainSetupLoopInitHook function from Board module.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if !OVERRIDE_MainSetupLoopInitHook
+VOID MainSetupLoopInit(VOID);
+VOID MainSetupLoopInitHook ( VOID )
+{ //EIP131739 : Modified MainSetupLoopInit as module hook for TSE
+ MainSetupLoopInit();
+}
+#endif
+//EIP131739 Ends
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsLoadSysteAccessOnUserDefault
+//
+// Description: Returns token value TSE_DONOT_LOAD_SYSTEM_ACCESS_FOR_USER_DEFAULT
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLoadSysteAccessOnUserDefault(VOID)
+{
+#if TSE_DONOT_LOAD_SYSTEM_ACCESS_FOR_USER_DEFAULT
+ return TSE_DONOT_LOAD_SYSTEM_ACCESS_FOR_USER_DEFAULT;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsANSIEscapeCodeSupported
+//
+// Description: Returns token value TSE_ANSI_ESC_CODE_SUPPORT
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsANSIEscapeCodeSupported(VOID)
+{
+#if TSE_ANSI_ESC_CODE_SUPPORT
+ return TSE_ANSI_ESC_CODE_SUPPORT;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TseDebugDisableApplicationDestructor
+//
+// Description: Returns token value TSE_DBG_DISABLE_APPDESTRUCTOR
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TseDebugDisableApplicationDestructor (VOID)
+{
+#ifdef TSE_DBG_DISABLE_APPDESTRUCTOR
+ return TSE_DBG_DISABLE_APPDESTRUCTOR;
+#else
+ return FALSE;
+#endif
+}
+
+//EIP 162981 Providing defaults through sdl tokens starts
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TseDefaultSetupPasswordSupported
+//
+// Description: Returns token value TSE_DEFAULT_SETUP_PASSWORD_SUPPORT
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TseDefaultSetupPasswordSupported (void)
+{
+#ifdef TSE_DEFAULT_SETUP_PASSWORD_SUPPORT
+ return TSE_DEFAULT_SETUP_PASSWORD_SUPPORT;
+#else
+ return FALSE;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DefaultSetupPwdAtFirstBootOnly
+//
+// Description: Returns token value DEFAULT_SETUP_PWD_AT_FIRSTBOOT_ONLY
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN DefaultSetupPwdAtFirstBootOnly (void)
+{
+#ifdef DEFAULT_SETUP_PWD_AT_FIRSTBOOT_ONLY
+ return DEFAULT_SETUP_PWD_AT_FIRSTBOOT_ONLY;
+#else
+ return FALSE;
+#endif
+}
+//EIP 162981 Providing defaults through sdl tokens ends
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsDisableESCinBBSMenu
+//
+// Description: Returns token DISABLE_ESC_IN_BBS value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsDisableESCinBBSMenu (VOID)
+{
+#ifdef DISABLE_ESC_IN_BBS
+ return DISABLE_ESC_IN_BBS;
+#else
+ return 0;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TseRtAccessSupport
+//
+// Description: Returns token RT_ACCESS_SUPPORT_IN_HPKTOOL value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TseRtAccessSupport (VOID)
+{
+#ifdef RT_ACCESS_SUPPORT_IN_HPKTOOL
+ return RT_ACCESS_SUPPORT_IN_HPKTOOL;
+#else
+ return 0;
+#endif
+}
+
+
+//<AMI_PHDR_START>
+// Procedure: IsGrayoutSelectable
+//
+// Description: Returns token value TSE_SETUP_GRAYOUT_SELECTABLE
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsGrayoutSelectable()
+{
+#if TSE_SETUP_GRAYOUT_SELECTABLE
+ return 1;
+#else
+ return 0;
+#endif
+}
+
+//EIP-93340 Start
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSupportDefaultForStringControl
+//
+// Description: Returns TSE_SUPPORT_DEFAULT_FOR_STRING_CONTROL token value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSupportDefaultForStringControl (VOID)
+{
+#if TSE_SUPPORT_DEFAULT_FOR_STRING_CONTROL
+ return TSE_SUPPORT_DEFAULT_FOR_STRING_CONTROL;
+#else
+ return FALSE;
+#endif
+}
+//EIP-93340 End
+
+//EIP-107833 Start
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsTseBestTextGOPModeSupported
+//
+// Description: Returns token TSE_BEST_TEXT_GOP_MODE value
+//
+// Input: VOID
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsTseBestTextGOPModeSupported (VOID)
+{
+#ifdef TSE_BEST_TEXT_GOP_MODE
+ return TSE_BEST_TEXT_GOP_MODE;
+#else
+ return FALSE;
+#endif
+}
+//EIP-197833 End
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/FakeTokens.c b/Core/EM/AMITSE/FakeTokens.c
new file mode 100644
index 0000000..80289b3
--- /dev/null
+++ b/Core/EM/AMITSE/FakeTokens.c
@@ -0,0 +1,391 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/FakeTokens.c $
+//
+// $Author: Arunsb $
+//
+// $Revision: 25 $
+//
+// $Date: 2/11/14 7:35p $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/FakeTokens.c $
+//
+// 25 2/11/14 7:35p Arunsb
+// Changes reverted for 2.16.1243 label
+//
+// 24 11/26/13 9:49a Premkumara
+// [TAG] EIP118342
+// [Category] Improvement
+// [Description] Show meaningful error message when HDD is locked after
+// reached maximum unlocking attempt.
+// [Files] TseAdvanced.c, CommonHelper.c, FakeToken.c, AmiTseStr.uni
+//
+// 23 5/22/13 11:18p Premkumara
+// [TAG] EIP123432
+// [Category] Bug Fix
+// [Issue Faced] Take print screen for save & Exit msg box. OK
+// of msg box is consumed by Save & Exit msg box.
+// - Cursor is missing after taking print screen of popupedit box in
+// string control
+// - Printscreen support is not given for Filebrowser feature
+// [RootCause] - When msg box for Save&Exit is popped and printscreen
+// event is called and displaying msg box over Save&Exit. Then msgbox
+// handleaction for printscreen event will change the result value in
+// _CallbackMsgbox() function so it will break the while loop in
+// _CallbackGetValue() function so destroy the next msg box in
+// CallbackShowMessageBox() function.
+// - DrawCursor variable is not set to TRUE after printscreen event
+// [Solution] - Returning EFI_UNSUPPORTED for printscreen event handling
+// function for messgebox and change the result value to 0xff
+// - Support given for file browser feature
+// [Files] Callback.c, MessageBox.c, Minisetupext.c, PopupString.c,
+// AddBootOption.c
+// AmiTSEStr.uni, FakeToken.c
+//
+// 22 4/18/13 1:48a Arunsb
+// [TAG] EIP81490
+// [Category] New Feature
+// [Description] Post message support for BBS popup menu
+// [Files] AMITSE.sdl, AmiTSEStr.uni, commonoem.c, FakeTokens.c and
+// globals.c
+//
+// 21 3/25/13 8:42a Premkumara
+// [TAG] EIP116315
+// [Category] Improvement
+// [Description] Display control prompt string for password control.
+// (for String on CHAP secret popup)
+// [Files] - AMITSE.sdl
+// - CommonHelper.c
+// - FakeToken.c
+// - AmiTSEStr.uni
+// - TseLite\PopupPassword.c
+// - uefi2.1\UefiWapper21.c
+// - uefi2.0\UefiWapper20.c
+// - uefi2.0\HiiCallback.c
+// - uefi2.0\hii.h
+// - uefi2.0\hii.c
+//
+// 20 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 11 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 18 9/17/12 5:59a Rajashakerg
+// Updated EIP changes for 2.16 release.
+//
+// 16 9/03/12 3:08a Premkumara
+// [TAG] EIP 96246
+// [Category] Improvement
+// [Description] Improvement of a boots override when firmware has a
+// BootNext variable
+// [Files] AMITSE.sdl, CommonHelper.c, FakeToken.c, AmiTSEStr.uni,
+// TseAdvanced.c
+//
+// 15 1/09/12 1:38a Arunsb
+// [TAG] EIP79952
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Add driver option displays select boot option as title
+// [RootCause] Title problem
+// [Solution] Title changes
+// [Files] Faketokens.c, amitsestr.uni, addbootoption.c,
+// uefi2.0\hiicallback.c and uefi21wapper.c
+//
+// 14 12/16/11 7:16a Arunsb
+// Ordered the strings as Bootonly strings then normal strings
+//
+// 13 12/16/11 6:05a Premkumara
+// [TAG] EIP63190
+// [Category] Improvement
+// [Description] Changed Order of Strings based on TSE flavors.
+// [Files] AmiTSEStr.uni, FakeTokens.c
+//
+// 12 11/20/11 7:38a Premkumara
+// [TAG] EIP73226
+// [Category] New Feature
+// [Description] Extended support for password prompt
+// [Files] FakeToken.c, Uefi21Wapper.c, AmiTSEStr.uni, PopupPassword.c,
+//
+// 11 11/14/11 2:40p Blaines
+// [TAG] - EIP 75481
+// [Category]- Function Request
+// [Synopsis]- TSE debug print infrastructure.
+// [Description]- Add TSE debug print info for basic functions such as
+// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms
+// data.
+// [Files]
+// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c
+// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c,
+// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h,
+// Uefi21Wrapper.c, setupdbg.h
+//
+// 10 9/04/11 3:59a Arunsb
+// [TAG] EIP65320
+// [Category] Improvement
+// [Description] Board module hook for LoadImage failure.
+// Review comment addressed.
+// [Files] Commonhelper.c, amitsestr.uni, boot.c and faketokens.c
+//
+// 9 6/30/11 3:57a Arunsb
+// [TAG] EIP57661
+// [Category] New Feature
+// [Description] Boot manager algorithm for interaction with Driver
+// Health protocol.
+// Driver health related string tokens added.
+// [Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+// commonhelper.c, uefisetup.ini, tsedrvhealth.h,
+// amivfr.h, minisetupbin.mak,
+// hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+// special.h, boot.h, minisetup.h,
+// uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+// uefi21wapper.c.
+//
+// 8 3/28/11 11:00p Madhans
+// [TAG] EIP56414
+// [Category] Improvement
+// [Description] TSE: Support for EFI_IFR_NO_SUBMIT_IF opcode
+// [Files] Callback.c, FakeToken.c, AMITSEstr.uni, Parse.c, CtrlCond.c,
+// CtrlCond.h, ctrlcond.h, ctrlcond.c
+//
+// 7 12/28/10 5:59p Mallikarjunanv
+// [TAG] EIP41615
+// [Category] New Feature
+// [Description] Added the file browser support for the Add boot option
+// reated controls
+// [Files] AmiVfr.h, AmiTse.sdl, AmiTseStr.uni, CommonHelper.c,
+// Faketokens.c, TseElinks.h, EdkHelper.h, minisetup.h, TseAdvanced.c,
+// AddBootOption.c
+//
+// 6 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 5 8/04/10 12:12a Mallikarjunanv
+// EIP-29951 : Device Path Name support updates
+//
+// 4 4/16/10 5:10p Madhans
+// Changes for Tse 2.02. Please see Changelog.log for more details.
+//
+// 3 2/19/10 12:58p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 4 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 3 1/04/10 9:49a Mallikarjunanv
+// Added support for reserved boot option names and added condition not to
+// accept empty boot option names
+//
+// 2 10/28/09 5:34p Madhans
+// 1. Support to Add the String from other modules to TSE.
+// 2. Clean of GIF and Image code Control them with minimal code from TSE
+// binary.
+//
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: faketokens.c
+//
+// Description:
+// This file does not add any code. It has, all the string tokens that
+// are used by Minisetup, to fake the usage to strgather.exe. Add to
+// this list, the new string tokens that are defined in
+// AmiTSEStrstr.uni and to be used by Minisetup
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+//Following code is to force strgatherer to include these strings
+#if 0
+STRING_TOKEN(STR_MAIN_TITLE)
+STRING_TOKEN(STR_MAIN_COPYRIGHT)
+STRING_TOKEN(STR_CTRL_CHKBOX_ENABLE)
+STRING_TOKEN(STR_CTRL_CHKBOX_DISABLE)
+STRING_TOKEN(STR_HELP_TITLE)
+
+STRING_TOKEN(STR_FDD)
+STRING_TOKEN(STR_HDD)
+STRING_TOKEN(STR_CDROM)
+STRING_TOKEN(STR_NETWORK)
+STRING_TOKEN(STR_BEV)
+STRING_TOKEN(STR_PRI_MAS)
+STRING_TOKEN(STR_PRI_SLA)
+STRING_TOKEN(STR_SEC_MAS)
+STRING_TOKEN(STR_SEC_SLA)
+STRING_TOKEN(STR_SATA_X)
+STRING_TOKEN(STR_NO_BOOT_OPTIONS)
+STRING_TOKEN(STR_PASSWORD_PROMPT)
+STRING_TOKEN(STR_ERROR_PSWD)
+STRING_TOKEN(STR_DRV_HLTH_REBOOT_POST)
+STRING_TOKEN(STR_EVAL_MSG)
+STRING_TOKEN(STR_ACK_BBS_POPUP)
+STRING_TOKEN(STR_DEL_ENTER_SETUP)
+STRING_TOKEN(STR_ACK_ENTER_SETUP)
+STRING_TOKEN(STR_GENERAL_HELP)
+STRING_TOKEN(STR_GENERAL_HELP_MSG)
+STRING_TOKEN(STR_BOOT_MANAGER)
+STRING_TOKEN(STR_BOOT_MANAGER_HELP)
+STRING_TOKEN(STR_LANGUAGE)
+STRING_TOKEN(STR_LANGUAGE_HELP)
+STRING_TOKEN(STR_LOAD_PREVIOUS)
+STRING_TOKEN(STR_LOAD_PREVIOUS_MSG)
+STRING_TOKEN(STR_LOAD_FAILSAFE)
+STRING_TOKEN(STR_LOAD_FAILSAFE_HELP)
+STRING_TOKEN(STR_LOAD_FAILSAFE_MSG)
+STRING_TOKEN(STR_LOAD_OPTIMAL)
+STRING_TOKEN(STR_LOAD_OPTIMAL_HELP)
+STRING_TOKEN(STR_LOAD_OPTIMAL_MSG)
+STRING_TOKEN(STR_SAVE_EXIT)
+STRING_TOKEN(STR_SAVE_EXIT_HELP)
+STRING_TOKEN(STR_SAVE_EXIT_MSG)
+STRING_TOKEN(STR_SAVE_RESET)
+STRING_TOKEN(STR_SAVE_RESET_HELP)
+STRING_TOKEN(STR_SAVE_RESET_MSG)
+STRING_TOKEN(STR_SAVE_VALUES)
+STRING_TOKEN(STR_SAVE_VALUES_MSG)
+STRING_TOKEN(STR_EXIT)
+STRING_TOKEN(STR_EXIT_MSG)
+STRING_TOKEN(STR_RESET)
+STRING_TOKEN(STR_RESET_MSG)
+STRING_TOKEN(STR_SAVE_USER_DEFAULTS)
+STRING_TOKEN(STR_LOAD_USER_DEFAULTS)
+STRING_TOKEN(STR_LOAD_USER_MSG)
+STRING_TOKEN(STR_SUBMENU_OPTION)
+STRING_TOKEN(STR_CTRL_OK)
+STRING_TOKEN(STR_CTRL_CANCEL)
+STRING_TOKEN(STR_CTRL_YES)
+STRING_TOKEN(STR_CTRL_NO)
+STRING_TOKEN(STR_DAY_SUNDAY)
+STRING_TOKEN(STR_DAY_MONDAY)
+STRING_TOKEN(STR_DAY_TUESDAY)
+STRING_TOKEN(STR_DAY_WEDNESDAY)
+STRING_TOKEN(STR_DAY_THURSDAY)
+STRING_TOKEN(STR_DAY_FRIDAY)
+STRING_TOKEN(STR_DAY_SATURDAY)
+STRING_TOKEN(STR_OLD_PSWD)
+STRING_TOKEN(STR_NEW_PSWD)
+STRING_TOKEN(STR_CONFIRM_NEW_PSWD)
+STRING_TOKEN(STR_PSWD_CLR)
+STRING_TOKEN(STR_ERROR)
+STRING_TOKEN(STR_WARNING)
+STRING_TOKEN(STR_WARNING_NOT_FOUND)
+STRING_TOKEN(STR_ERROR_INPUT)
+STRING_TOKEN(STR_EMPTY_STRING)
+STRING_TOKEN(STR_INCONSISTENT_MSG_TITLE)
+STRING_TOKEN(STR_NOSUBMITIF_MSG_TITLE)
+STRING_TOKEN(STR_BBS_POPUP_TITLE_STRING)
+STRING_TOKEN(STR_BBS_POPUP_HELP1_STRING)
+STRING_TOKEN(STR_BBS_POPUP_HELP2_STRING)
+STRING_TOKEN(STR_BBS_POPUP_HELP3_STRING)
+STRING_TOKEN(STR_BBS_POPUP_HELP_STRING)
+STRING_TOKEN(STR_POPUPMENU_ENTER_SETUP)
+STRING_TOKEN(STR_USB)
+STRING_TOKEN(STR_VENDOR)
+STRING_TOKEN(STR_FILEPATH)
+STRING_TOKEN(STR_PROTOCOL)
+STRING_TOKEN(STR_FV_FILEPATH)
+STRING_TOKEN(STR_USB_DP)
+STRING_TOKEN(STR_SCSI_DP)
+STRING_TOKEN(STR_FIBRE_CHANNEL_DP)
+STRING_TOKEN(STR_1394_DP)
+STRING_TOKEN(STR_I20_DP)
+STRING_TOKEN(STR_INFINIBAND_DP)
+STRING_TOKEN(STR_VENDOR_DP)
+STRING_TOKEN(STR_MAC_DP)
+STRING_TOKEN(STR_NETWORK_IPV4_DP)
+STRING_TOKEN(STR_NETWORK_IPV6_DP)
+STRING_TOKEN(STR_UART_DP)
+STRING_TOKEN(STR_USB_CLASS_DP)
+STRING_TOKEN(STR_USB_CLASS_PHY_DP)
+STRING_TOKEN(STR_USB_CLASS_MASS_DP)
+STRING_TOKEN(STR_USB_LOGICAL_DP)
+STRING_TOKEN(STR_USB_SATA_DP)
+STRING_TOKEN(STR_USB_ISCSI_DP)
+STRING_TOKEN(STR_HARD_DISK_ORDER)
+STRING_TOKEN(STR_CDROM_ORDER)
+STRING_TOKEN(STR_FLOPPY_DISK_ORDER)
+STRING_TOKEN(STR_NETWORK_ORDER)
+STRING_TOKEN(STR_BEV_ORDER)
+STRING_TOKEN(STR_USB_ORDER)
+STRING_TOKEN(STR_PCMCIA_ORDER)
+STRING_TOKEN(STR_UNKNOWN_ORDER)
+STRING_TOKEN(STR_ADD_BOOT_OPTION_RESERVED)
+STRING_TOKEN(STR_ADD_BOOT_OPTION_EMPTY)
+STRING_TOKEN(STR_ADD_DRIVER_OPTION_EMPTY)
+STRING_TOKEN(STR_DEL_BOOT_OPTION_RESERVED)
+STRING_TOKEN(STR_MSGBOX_PROGRESS_TITLE)
+STRING_TOKEN(STR_MSGBOX_PROGRESS_TEXT)
+STRING_TOKEN(STR_FILE_SYSTEM)
+STRING_TOKEN(STR_FILE_PATH)
+STRING_TOKEN(STR_DRIVER_PATH)
+STRING_TOKEN(STR_DRV_HLTH_TITLE)
+STRING_TOKEN(STR_DRV_HLTH_RECON)
+STRING_TOKEN(STR_DRV_HLTH_REBOOT)
+STRING_TOKEN(STR_SECBOOT_VIOLATION)
+STRING_TOKEN(STR_SECBOOT_INV_SIGN)
+STRING_TOKEN(STR_DBG_PRINT_CHECKED)
+STRING_TOKEN(STR_DBG_PRINT_HIIPARSING)
+STRING_TOKEN(STR_DBG_PRINT_HIIFUNCTION)
+STRING_TOKEN(STR_DBG_PRINT_HIICALLBACK)
+STRING_TOKEN(STR_DBG_PRINT_HIINOTIFICATION)
+STRING_TOKEN(STR_DBG_PRINT_IFRFORM)
+STRING_TOKEN(STR_DBG_PRINT_VARIABLE_CACHE)
+STRING_TOKEN(STR_OVERRIDE_BOOTNEXT_OPTION_1)
+STRING_TOKEN(STR_OVERRIDE_BOOTNEXT_OPTION_2)
+STRING_TOKEN(STR_OVERRIDE_BOOTNEXT_OPTION_3)
+STRING_TOKEN(STR_OVERRIDE_OPTION_MENU_TITLE)
+STRING_TOKEN(STR_OVERRIDE_OPTION_MENU_LEGEND)
+STRING_TOKEN(STR_OLD_PSWD_LABEL)
+STRING_TOKEN(STR_NEW_PSWD_LABEL)
+STRING_TOKEN(STR_CONFIRM_NEW_PSWD_LABEL)
+STRING_TOKEN(STR_PSWD_CLR_LABEL)
+STRING_TOKEN(STR_FILE_SYSTEM_TO_SAVE_IMG)
+#endif
+
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMITSE/HookList.c b/Core/EM/AMITSE/HookList.c
new file mode 100644
index 0000000..ffb4bca
--- /dev/null
+++ b/Core/EM/AMITSE/HookList.c
@@ -0,0 +1,187 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/HookList.c $
+//
+// $Author: Premkumara $
+//
+// $Revision: 11 $
+//
+// $Date: 8/28/14 4:28a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/HookList.c $
+//
+// 11 8/28/14 4:28a Premkumara
+// EIP-135253 Updating file name proper in #include
+//
+// 10 3/06/13 12:24a Premkumara
+// [TAG] EIP111415
+// [Category] Improvement
+// [Description] Elink function for SETUP_TOGGLE_KEY_UNICODE function
+// [Files] HookAnchor.h, AMITSE.sdl, commonoem.c, Commonoem.h,
+// HookList.c, HookAnchor.c
+//
+// 9 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 10 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 8 3/28/11 9:06p Madhans
+// [TAG] EIP41744
+// [Category] Improvement
+// [Description] SoftKeyBoard Support in TSE. and Support to Work with
+// new mouse driver(Label 07).
+// [Files] HookAnchor.h
+// AMITSE.sdl
+// CommonHelper.c
+// commonoem.c
+// commonoem.h
+// HookList.c
+// HookAnchor.c
+// Mouse.c
+// minisetupext.c
+// postmgmtext.c
+// minisetupext.h
+// PopupPassword.c
+// PopupString.c
+// TseLiteCommon.c
+//
+// 7 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 6 6/04/10 12:12p Blaines
+// Created new AMITSE hook, hook33
+//
+// 5 4/16/10 5:10p Madhans
+// Changes for Tse 2.02. Please see Changelog.log for more details.
+//
+// 4 2/19/10 12:58p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 5 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 4 1/09/10 2:32a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 3 9/15/09 9:20a Sudhirv
+// added entry number 31
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards
+//
+// 2 6/24/09 11:52a Blaines
+// Coding standard update
+//
+// 1 6/09/09 9:52a Madhans
+// TSE 2.00.1201
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: hooklist.c
+//
+// Description: AMITSE Hook definitions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifdef TSE_FOR_APTIO_4_50
+#include <Efi.h>
+#include "Token.h"
+#else
+#include "Tiano.h"
+#include "tokens.h"
+#endif
+
+#include "AMITSEElinks.h"
+
+UINTN gHookBase = TSE_HOOKBASE_VALUE;
+
+typedef VOID TSE_HOOK (VOID);
+
+extern TSE_HOOK HOOK_LIST_FROM_ELINKS;
+
+#define HOOK0 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE)
+#define HOOK1 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+1)
+#define HOOK2 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+2)
+#define HOOK3 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+3)
+#define HOOK4 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+4)
+#define HOOK5 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+5)
+#define HOOK6 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+6)
+#define HOOK7 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+7)
+#define HOOK8 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+8)
+#define HOOK9 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+9)
+#define HOOK10 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+10)
+#define HOOK11 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+11)
+#define HOOK12 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+12)
+#define HOOK13 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+13)
+#define HOOK14 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+14)
+#define HOOK15 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+15)
+#define HOOK16 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+16)
+#define HOOK17 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+17)
+#define HOOK18 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+18)
+#define HOOK19 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+19)
+#define HOOK20 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+20)
+#define HOOK21 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+21)
+#define HOOK22 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+22)
+#define HOOK23 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+23)
+#define HOOK24 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+24)
+#define HOOK25 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+25)
+#define HOOK26 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+26)
+#define HOOK27 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+27)
+#define HOOK28 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+28)
+#define HOOK29 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+29)
+#define HOOK30 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+30)
+#define HOOK31 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+31)
+#define HOOK32 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+32)
+#define HOOK33 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+33)
+#define HOOK34 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+34)
+#define HOOK35 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+35)
+#define HOOK36 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+36)
+#define HOOK37 (TSE_HOOK *)((UINTN)TSE_HOOKBASE_VALUE+37)//EIP-111415 SwitchToPostScreenHook
+
+TSE_HOOK * AMITSE_HookList [] = {HOOK_LIST_FROM_ELINKS, NULL};
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/HpkTool.exe b/Core/EM/AMITSE/HpkTool.exe
new file mode 100644
index 0000000..bfc0c3c
--- /dev/null
+++ b/Core/EM/AMITSE/HpkTool.exe
Binary files differ
diff --git a/Core/EM/AMITSE/Inc/HiiLib.h b/Core/EM/AMITSE/Inc/HiiLib.h
new file mode 100644
index 0000000..a0bc7ba
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/HiiLib.h
@@ -0,0 +1,127 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/HiiLib.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 6 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/HiiLib.h $
+//
+// 6 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 11 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 5 9/20/10 6:46p Madhans
+// [TAG] EIP44542
+// [Category] BUILD ISSUE FIX
+// [Symptom] Build issues with TSE label (INT)4.6.2_TSE_2_10_1207_TEST
+// when IdeSecurity and FastBoot modules added to the project
+// [RootCause] -
+// [Solution] Build issues resolved
+// [Files] CommonHelper.c, Tsecommon.h, Hiilib.h, Boot.h, minisetup.h,
+// bbs.c, special.c, Bds.c TseLitehelp
+//
+// 4 6/17/10 2:17p Madhans
+// Refer Changelog.log.
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 7 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 6 1/09/10 2:29a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 5 10/28/09 5:34p Madhans
+//
+// 4 8/13/09 7:33a Mallikarjunanv
+// changed after moving the hii ralated function to uefi module from
+// binary module
+//
+// 3 7/20/09 11:54a Mallikarjunanv
+// added external variable gHiiProtocol to use in tse binary
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards.
+//
+// 1 6/09/09 9:53a Madhans
+// TSE 2.00.1201
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: hiilib.h
+//
+// Description: Hii related functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _HIILIB_H_
+#define _HIILIB_H_
+
+EFI_STATUS HiiInitializeProtocol( VOID );
+CHAR16 *HiiGetString( VOID* handle, UINT16 token );
+UINT16 HiiAddString( VOID* handle, CHAR16 *string );
+UINTN TestPrintLength ( IN CHAR16 *String );
+
+extern VOID * gHiiHandle;
+
+#ifndef INVALID_HANDLE
+#define INVALID_HANDLE ((VOID*)(UINTN)-1)
+#endif
+
+#ifndef INVALID_TOKEN
+#define INVALID_TOKEN ((UINT16)-1)
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/HookAnchor.h b/Core/EM/AMITSE/Inc/HookAnchor.h
new file mode 100644
index 0000000..106d722
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/HookAnchor.h
@@ -0,0 +1,252 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/HookAnchor.h $
+//
+// $Author: Premkumara $
+//
+// $Revision: 10 $
+//
+// $Date: 3/06/13 12:20a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/HookAnchor.h $
+//
+// 10 3/06/13 12:20a Premkumara
+// [TAG] EIP111415
+// [Category] Improvement
+// [Description] Elink function for SETUP_TOGGLE_KEY_UNICODE function
+// [Files] HookAnchor.h, AMITSE.sdl, commonoem.c, Commonoem.h,
+// HookList.c, HookAnchor.c
+//
+// 9 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 11 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 8 11/20/11 6:33a Rajashakerg
+// [TAG] EIP62763
+// [Category] Improvement
+// [Description] Utilize the Improvements done from mouse driver in
+// AMITSE
+// [Files] HookAnchor.h, TseCommon.h, AMITSE.sdl, CommonHelper.c,
+// commonoem.c, commonoem.h, buffer.c, globals.c, HookAnchor.c,
+// minisetup.h, notify.c, postmgmt.c, protocol.c, ezport.c, stylecommon.c,
+// Mouse.c, Action.c, Date.c, frame.c, MessageBox.c, minisetupext.c,
+// minisetupext.h, numeric.c, numeric.h, page.c, PopupEdit.c, PopupEdit.h,
+// PopupPassword.c, postmgmtext.c, time.c.
+//
+// 7 3/28/11 9:06p Madhans
+// [TAG] EIP41744
+// [Category] Improvement
+// [Description] SoftKeyBoard Support in TSE. and Support to Work with
+// new mouse driver(Label 07).
+// [Files] HookAnchor.h
+// AMITSE.sdl
+// CommonHelper.c
+// commonoem.c
+// commonoem.h
+// HookList.c
+// HookAnchor.c
+// Mouse.c
+// minisetupext.c
+// postmgmtext.c
+// minisetupext.h
+// PopupPassword.c
+// PopupString.c
+// TseLiteCommon.c
+//
+// 6 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 5 6/04/10 12:12p Blaines
+// Created new AMITSE hook, hook33
+//
+// 4 4/16/10 5:11p Madhans
+// Changes for Tse 2.02. Please see Changelog.log for more details.
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 5 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 4 2/04/10 11:08p Madhans
+// MapControlMouseAction hook added
+//
+// 3 9/15/09 9:03a Sudhirv
+// added two hooks one for LoadSetupDefaults and the other for
+// PreSystemReset
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards.
+//
+// 1 6/09/09 9:53a Madhans
+// TSE 2.00.1201
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: hookanchor.h
+//
+// Description: TSE hook functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _HOOKANCHOR_H_
+#define _HOOKANCHOR_H_
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+#include <Protocol/AmiKeyCode.h>
+#else
+#ifndef _AMI_EFI_KEY_DATA_
+#define _AMI_EFI_KEY_DATA_
+typedef struct {
+ EFI_INPUT_KEY Key;
+} AMI_EFI_KEY_DATA;
+#endif
+#endif
+
+VOID DrawQuietBootLogoHook(VOID);
+BOOLEAN ProcessConInAvailabilityHook(VOID);
+VOID ProcessEnterSetupHook(VOID);
+VOID ProcessProceedToBootHook(VOID);
+VOID MinisetupDriverEntryHookHook(VOID);
+VOID PostManagerHandShakeHookHook(VOID);
+CONTROL_ACTION MapControlKeysHook(AMI_EFI_KEY_DATA key);
+VOID CheckForKeyHook( EFI_EVENT Event, VOID *Context );
+VOID CheckForClickHook( EFI_EVENT Event, VOID *Context );//EIP 62763 : Utilize the Improvements done from mouse driver in AMITSE
+VOID BeforeLegacyBootLaunchHook(VOID);
+VOID AfterLegacyBootLaunchHook(VOID);
+VOID BeforeEfiBootLaunchHook(VOID);
+VOID AfterEfiBootLaunchHook(VOID);
+VOID SavedConfigChangesHook(VOID);
+VOID LoadedConfigDefaultsHook(VOID);
+VOID TimeOutLoopHookHook(VOID);
+EFI_STATUS OemKey1HookHook ( BOOT_FLOW *bootFlowPtr );
+EFI_STATUS OemKey2HookHook ( BOOT_FLOW *bootFlowPtr );
+EFI_STATUS OemKey3HookHook ( BOOT_FLOW *bootFlowPtr );
+EFI_STATUS OemKey4HookHook ( BOOT_FLOW *bootFlowPtr );
+VOID PasswordEncodeHook( CHAR16 *Password, UINTN MaxSize);
+EFI_STATUS SetControlColorsHook(UINT8 *BGColor, UINT8 *FGColor, UINT8 *SecBGColor, UINT8 *SecFGColor,
+ UINT8 *SelBGColor, UINT8 *SelFGColor, UINT8 *NSelBGColor, UINT8 *NSelFGColor,
+ UINT8 *LabelBGColor, UINT8 *LabelFGColor,UINT8 *NSelLabelFGColor, UINT8 *EditBGColor, UINT8 *EditFGColor,
+ UINT8 *PopupFGColor, UINT8 *PopupBGColor);
+VOID InvalidActionHookHook(VOID);
+VOID LoadedUserDefaultsHook(VOID);
+VOID LoadedBuildDefaultsHook(VOID);
+VOID LoadedPreviousValuesHook(VOID);
+VOID SetupConfigModifiedHook(VOID);
+VOID DrawPopupMenuHook();
+VOID BbsBootHook();
+VOID LoadSetupDefaultsHook( NVRAM_VARIABLE *defaults, UINTN data );
+VOID PreSystemResetHookHook(VOID);
+CONTROL_ACTION MapControlMouseActionHook(VOID *pMouseInfo);
+VOID ProcessProceedToBootNowHook(VOID);
+VOID ProcessConOutAvailableHook(VOID);
+VOID ProcessUIInitHookHook(VOID);
+VOID AfterInitPostScreenHook(VOID);
+VOID SwitchToPostScreenHook(VOID);//EIP-111415 SwitchToPostScreenHook
+
+VOID LastTSEHook(VOID);
+
+typedef VOID (TSE_HOOK) (VOID);
+typedef BOOLEAN (TSE_HOOK_T1) ();
+typedef CONTROL_ACTION (TSE_HOOK_T2) (AMI_EFI_KEY_DATA key);
+typedef VOID (TSE_HOOK_T3) (EFI_EVENT Event, VOID *Context);
+typedef EFI_STATUS (TSE_HOOK_T4) (BOOT_FLOW *bootFlowPtr);
+typedef VOID (TSE_HOOK_T5) (CHAR16 *Password, UINTN MaxSize);
+typedef EFI_STATUS (TSE_HOOK_T6) (UINT8 *BGColor, UINT8 *FGColor, UINT8 *SecBGColor, UINT8 *SecFGColor,
+ UINT8 *SelBGColor, UINT8 *SelFGColor, UINT8 *NSelBGColor, UINT8 *NSelFGColor,
+ UINT8 *LabelBGColor, UINT8 *LabelFGColor,UINT8 *NSelLabelFGColor, UINT8 *EditBGColor, UINT8 *EditFGColor,
+ UINT8 *PopupFGColor, UINT8 *PopupBGColor);
+typedef CONTROL_ACTION (TSE_HOOK_T7) (VOID *MouseInfo);
+
+extern TSE_HOOK * AMITSE_HookList [];
+
+extern UINTN gHookBase;
+
+#define HOOKID0 (gHookBase)
+#define HOOKID1 (gHookBase+1)
+#define HOOKID2 (gHookBase+2)
+#define HOOKID3 (gHookBase+3)
+#define HOOKID4 (gHookBase+4)
+#define HOOKID5 (gHookBase+5)
+#define HOOKID6 (gHookBase+6)
+#define HOOKID7 (gHookBase+7)
+#define HOOKID8 (gHookBase+8)
+#define HOOKID9 (gHookBase+9)
+#define HOOKID10 (gHookBase+10)
+#define HOOKID11 (gHookBase+11)
+#define HOOKID12 (gHookBase+12)
+#define HOOKID13 (gHookBase+13)
+#define HOOKID14 (gHookBase+14)
+#define HOOKID15 (gHookBase+15)
+#define HOOKID16 (gHookBase+16)
+#define HOOKID17 (gHookBase+17)
+#define HOOKID18 (gHookBase+18)
+#define HOOKID19 (gHookBase+19)
+#define HOOKID20 (gHookBase+20)
+#define HOOKID21 (gHookBase+21)
+#define HOOKID22 (gHookBase+22)
+#define HOOKID23 (gHookBase+23)
+#define HOOKID24 (gHookBase+24)
+#define HOOKID25 (gHookBase+25)
+#define HOOKID26 (gHookBase+26)
+#define HOOKID27 (gHookBase+27)
+#define HOOKID28 (gHookBase+28)
+#define HOOKID29 (gHookBase+29)
+#define HOOKID30 (gHookBase+30)
+#define HOOKID31 (gHookBase+31)
+#define HOOKID32 (gHookBase+32)
+#define HOOKID33 (gHookBase+33)
+#define HOOKID34 (gHookBase+34)
+#define HOOKID35 (gHookBase+35)
+#define HOOKID36 (gHookBase+36)
+#define HOOKID37 (gHookBase+37)//EIP-SwitchToPostScreenHook
+
+
+#endif /* _HOOKANCHOR_H_ */
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/LogoLib.h b/Core/EM/AMITSE/Inc/LogoLib.h
new file mode 100644
index 0000000..7707268
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/LogoLib.h
@@ -0,0 +1,241 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/LogoLib.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 10 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/LogoLib.h $
+//
+// 10 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 8 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 9 2/02/12 12:40a Premkumara
+// [TAG] EIP75136
+// [Category] New Feature
+// [Description] Generic support for logos in RomHoles
+// [Files] CommomHelper.c, AMITSE.sdl, AMITSE.mak, LogoLib.h
+//
+// 8 1/31/12 1:18p Premkumara
+// [TAG] EIP75136
+// [Category] New Feature
+// [Description] Generic support for logos in RomHoles
+// [Files] CommomHelper.c, AMITSE.sdl, AMITSE.mak, LogoLib.h,
+// Postmgmt.c, AMILogo.h
+//
+// 7 9/29/11 7:00p Blaines
+// [TAG] - EIP 66860
+// [Category]- Function Request
+// [Synopsis]- AmiPostManager interface for text entry.
+// [Files] - LogoLib.h, AMIPostMgr.h, protocol.c, protocol.h,
+// TseAdvanced.c, TseLitehelper.c, TseUefiHii.h, Uefi21Wapper.c
+//
+// 6 6/22/11 9:17a Premkumara
+// [TAG] EIP60048
+// [Category] Improvement
+// [Description] TSE should Change the System Resolution according to
+// the Quite Logo Size
+// [Files] CommonHelper.c, AMITSE.sdl, Logo.c, LogoLib.h
+//
+// 5 6/13/11 12:29p Rajashakerg
+// [TAG] EIP60910
+// [Category] New Feature
+// [Description] PNG image support in TSE.
+// [Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c, png.h,
+// pnguncmp.c, TseAdvanced.cif
+//
+// 4 4/16/10 5:11p Madhans
+// Changes for Tse 2.02. Please see Changelog.log for more details.
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 5 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 4 2/04/10 12:01p Blaines
+// EIP-28005
+//
+// Added PostManagerSetAttribute to support display of text in color.
+// Added support for handling string characters --- \n, \r.
+//
+// 3 8/13/09 12:09p Blaines
+// Move Image support to binary module
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards.
+//
+// 1 6/09/09 9:53a Madhans
+// TSE 2.00.1201
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: logolib.h
+//
+// Description: logo related header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _LOGOLIB_H_
+#define _LOGOLIB_H_
+
+//OEM_POST Logo GUID. Don't change the GUID. ChangeLogo expects this GUID.
+#define AMI_OEM_LOGO_GUID \
+ { 0x294b1cef, 0x9beb, 0x42d5, 0x99, 0x71, 0x0c, 0x89, 0x63, 0xcd, 0xaf, 0x02}
+
+typedef enum {
+ BMP_Logo,
+ GIF_Logo,
+ JPEG_Logo,
+ PCX_Logo,
+ PNG_Logo,
+ OEM_Format_LOGO,
+ Unsupported_Logo
+} LOGO_TYPE;
+
+EFI_STATUS SetScreenResolution(UINTN ResX, UINTN ResY);
+EFI_STATUS GetScreenResolution(UINTN *ResX, UINTN *ResY);
+EFI_STATUS GOPSetScreenResolution(UINTN *Width, UINTN *Height);
+EFI_STATUS GOPSetScreenResolutionHook(UINTN *Width, UINTN *Height, UINT32 Index);
+
+EFI_STATUS
+GetGraphicsBitMapFromFV (
+IN EFI_GUID *FileNameGuid,
+IN OUT VOID **Image,
+IN OUT UINTN *ImageSize
+);
+
+EFI_STATUS
+DrawImage(
+IN UINT8 *ImageData,
+IN UINTN ImageSize,
+IN CO_ORD_ATTRIBUTE Attribute,
+IN INTN CoOrdX,
+IN INTN CoOrdY,
+IN BOOLEAN AdjustScreenResolution,
+OUT UINTN *Width,
+OUT UINTN *Height
+);
+
+EFI_STATUS PostManagerDisplayPostMessage( CHAR16 *message );
+EFI_STATUS PostManagerDisplayPostMessageEx( CHAR16 *message, UINTN Attribute );
+EFI_STATUS PostManagerSwitchToPostScreen( VOID );
+
+EFI_STATUS
+PostManagerDisplayMsgBox(
+ IN CHAR16 *MsgBoxTitle,
+ IN CHAR16 *Message,
+ IN UINT8 MsgBoxType,
+ OUT UINT8 *MsgBoxSel
+);
+
+EFI_STATUS
+PostManagerDisplayTextBox(
+ IN VOID *HiiHandle,
+ IN UINT16 TitleToken,
+ IN TEXT_INPUT_TEMPLATE *InputData,
+ IN UINT16 ItemCount,
+ IN DISPLAY_TEXT_KEY_VALIDATE DisplayTextKeyValidate
+);
+
+EFI_STATUS
+PostManagerDisplayProgress(
+IN UINT8 ProgressBoxState,
+IN CHAR16 *Title,
+IN CHAR16 *Message,
+IN CHAR16 *Legend,
+IN UINTN Percent, // 0 - 100
+IN OUT VOID **Handle, //Out HANDLE. Valid Handle for update and close
+OUT AMI_POST_MGR_KEY *OutKey //Out Key
+);
+
+EFI_STATUS
+PostManagerDisplayMsgBoxEx(
+ IN CHAR16 *Title,
+ IN CHAR16 *Message,
+ IN CHAR16 *Legend,
+ IN MSGBOX_EX_CATAGORY MsgBoxExCatagory,
+ IN UINT8 MsgBoxType,
+ IN UINT16 *OptionPtrTokens, // Valid only with MSGBOX_TYPE_CUSTOM
+ IN UINT16 OptionCount, // Valid only with MSGBOX_TYPE_CUSTOM
+ IN AMI_POST_MGR_KEY *HotKeyList, // NULL - AnyKeyPress closes
+ IN UINT16 HotKeyListCount,
+ OUT UINT8 *MsgBoxSel,
+ OUT AMI_POST_MGR_KEY *OutKey
+);
+
+EFI_STATUS
+PostManagerDisplayQuietBootMessage(
+ CHAR16 *Message,
+ INTN CoOrdX,
+ INTN CoOrdY,
+ CO_ORD_ATTRIBUTE Attribute,
+ EFI_UGA_PIXEL Foreground,
+ EFI_UGA_PIXEL Background
+);
+
+EFI_STATUS PostManagerDisplayInfoBox( CHAR16 *InfoBoxTitle,
+ CHAR16 *InfoString,
+ UINTN Timeout,
+ EFI_EVENT *Event
+ );
+
+EFI_STATUS PostManagerSetCursorPosition(UINTN X, UINTN Y);
+EFI_STATUS PostManagerGetCursorPosition(UINTN *pX, UINTN *pY);
+EFI_STATUS PostManagerSetAttribute(UINT8 ATTRIB);
+VOID CleanUpLogo( VOID );
+
+VOID InitPostScreen( VOID );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/PwdLib.h b/Core/EM/AMITSE/Inc/PwdLib.h
new file mode 100644
index 0000000..a229378
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/PwdLib.h
@@ -0,0 +1,148 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/PwdLib.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 4 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/PwdLib.h $
+//
+// 4 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 5 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 3 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 2 10/28/09 5:34p Madhans
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: pwdlib.h
+//
+// Description: password handling realted header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _PWDLIB_H_
+#define _PWDLIB_H_
+
+#define AMI_PASSWORD_NONE 0
+#define AMI_PASSWORD_USER 1
+#define AMI_PASSWORD_ADMIN 2
+#define AMI_PASSWORD_ANY 3
+
+UINT32
+CheckSystemPassword(
+IN OUT UINT32 EmptyPasswordType,
+IN UINTN *NoOfRetries,
+IN OUT UINTN *TimeOut
+);
+
+BOOLEAN CheckSystemPasswordPolicy(UINT32 PasswordInstalled);
+
+UINT32 PasswordCheckInstalled( VOID );
+VOID SetPasswordType( UINT32 PasswordType );
+
+extern UINT32 gPasswordType; //Provides what is the current access level
+
+// Internal Helper functions
+// Used for HDD Security module.
+VOID _DrawPasswordWindow(UINT16 PromptToken, UINTN PasswordLength, UINTN *CurrXPos, UINTN *CurrYPos);
+
+VOID _ReportInBox(
+ UINTN PasswordLength,
+ UINT16 BoxToken,
+ UINTN CurrXPos,
+ UINTN CurrYPos,
+ BOOLEAN bWaitForReturn
+ );
+EFI_STATUS _GetPassword(
+ CHAR16 *PasswordEntered,
+ UINTN PasswordLength,
+ UINTN CurrXPos,
+ UINTN CurrYPos,
+ UINTN *TimeOut
+ );
+
+// Expected from IDE sec module.
+extern UINT16 IDEPasswordGetName(UINT16 Index);
+extern EFI_STATUS IDEPasswordAuthenticate(
+ CHAR16 *Password,
+ VOID* Ptr,
+ BOOLEAN bCheckUser
+);
+extern BOOLEAN IDEPasswordUpdate(
+ UINT32 Index,
+ CHAR16 *Password,
+ BOOLEAN bCheckUser
+);
+extern VOID* IDEPasswordGetDataPtr( UINTN Index);
+extern BOOLEAN IDEPasswordGetLocked(
+ UINTN Index
+);
+extern VOID IDEPasswordCheck();
+extern VOID IDEPasswordFreezeDevices();
+extern VOID UnlockHDD(VOID);
+extern VOID SetHDDPassword(VOID);
+extern VOID IDEUpdateConfig(
+ VOID *TempideSecConfig,
+ UINTN value
+);
+
+
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/TseCommon.h b/Core/EM/AMITSE/Inc/TseCommon.h
new file mode 100644
index 0000000..62e6030
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/TseCommon.h
@@ -0,0 +1,147 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/TseCommon.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 6 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/TseCommon.h $
+//
+// 6 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 7 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 5 11/20/11 6:38a Rajashakerg
+// [TAG] EIP62763
+// [Category] Improvement
+// [Description] Utilize the Improvements done from mouse driver in
+// AMITSE
+// [Files] HookAnchor.h, TseCommon.h, AMITSE.sdl, CommonHelper.c,
+// commonoem.c, commonoem.h, buffer.c, globals.c, HookAnchor.c,
+// minisetup.h, notify.c, postmgmt.c, protocol.c, ezport.c, stylecommon.c,
+// Mouse.c, Action.c, Date.c, frame.c, MessageBox.c, minisetupext.c,
+// minisetupext.h, numeric.c, numeric.h, page.c, PopupEdit.c, PopupEdit.h,
+// PopupPassword.c, postmgmtext.c, time.c.
+//
+// 4 9/20/10 6:46p Madhans
+// [TAG] EIP44542
+// [Category] BUILD ISSUE FIX
+// [Symptom] Build issues with TSE label (INT)4.6.2_TSE_2_10_1207_TEST
+// when IdeSecurity and FastBoot modules added to the project
+// [RootCause] -
+// [Solution] Build issues resolved
+// [Files] CommonHelper.c, Tsecommon.h, Hiilib.h, Boot.h, minisetup.h,
+// bbs.c, special.c, Bds.c TseLitehelp
+//
+// 3 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 2 8/04/10 12:11a Mallikarjunanv
+// EIP-29951 : Device Path Name support updates
+//
+// 1 2/19/10 12:58p Madhans
+// Uploaded for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 2 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 1 10/28/09 5:32p Madhans
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: TseCommon.h
+//
+// Description: Tse Common Helper header file
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _TSECOMMON_H_
+#define _TSECOMMON_H_
+
+#include "HiiLib.h"
+#include "Mem.h"
+#include "Variable.h"
+#include "PwdLib.h"
+
+EFI_STATUS
+EfiLibReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ );
+
+VOID *
+EfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ );
+
+extern INTN
+EfiCompareMem (
+ IN VOID *MemOne,
+ IN VOID *MemTwo,
+ IN UINTN Len
+ );
+
+UINTN
+SPrint (
+ OUT CHAR16 *Buffer,
+ IN UINTN BufferSize,
+ IN CONST CHAR16 *Format,
+ ...
+ );
+
+EFI_STATUS ShowPostMsgBox(IN CHAR16 *MsgBoxTitle,IN CHAR16 *Message,IN UINT8 MsgBoxType, UINT8 *pSelection);
+
+VOID CheckForKeyHook( EFI_EVENT Event, VOID *Context );
+VOID CheckForClickHook( EFI_EVENT Event, VOID *Context );
+VOID ClearScreen( UINT8 Attrib );
+VOID *SaveScreen( VOID );
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_GUID gEfiDevicePathProtocolGuid;
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/TseElinks.h b/Core/EM/AMITSE/Inc/TseElinks.h
new file mode 100644
index 0000000..f64cbcd
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/TseElinks.h
@@ -0,0 +1,159 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/TseElinks.h $
+//
+// $Author: Premkumara $
+//
+// $Revision: 6 $
+//
+// $Date: 3/25/13 8:41a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/TseElinks.h $
+//
+// 6 3/25/13 8:41a Premkumara
+// [TAG] EIP116315
+// [Category] Improvement
+// [Description] Display control prompt string for password control.
+// (for String on CHAP secret popup)
+// [Files] - AMITSE.sdl
+// - CommonHelper.c
+// - FakeToken.c
+// - AmiTSEStr.uni
+// - TseLite\PopupPassword.c
+// - uefi2.1\UefiWapper21.c
+// - uefi2.0\UefiWapper20.c
+// - uefi2.0\HiiCallback.c
+// - uefi2.0\hii.h
+// - uefi2.0\hii.c
+//
+// 5 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 5 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 4 5/28/12 6:21a Rajashakerg
+// [TAG] EIP80873
+// [Category] Improvement
+// [Description] TSE Load/Save defaults without Messaaagebox.
+// [Files] TseElinks.h, Tseadvanced.c
+//
+// 3 11/13/11 12:22p Arunsb
+// [TAG] EIP70421
+// [Category] New Feature
+// [Description] Support for driver order in TSE
+// [Files] AMITSE.SDL, CommonHelper.c, setup.ini, uefisetup.ini,
+// boot.c,
+// minisetup.h, bbs.c, special.c, special.h, tseadvanced.c,
+// addbootoption.c,
+// callback.c, minisetupext.c, minisetupext.h, popupsel.c, popupsel.h,
+// TseLitehelper.c, variable.c, Uefi21Wapper.c, AMIVfr.h, boot.h,
+// TseElink.h, variable.h,
+// setup.h, Boot.vfr and Setup.uni
+//
+// 2 12/29/10 5:11a Mallikarjunanv
+// [TAG] EIP41615
+// [Category] New Feature
+// [Description] Added the file browser support for the Add boot option
+// reated controls
+//
+// [Files] AmiVfr.h, AmiTse.sdl, AmiTseStr.uni, CommonHelper.c,
+// Faketokens.c, TseElinks.h, EdkHelper.h, minisetup.h, TseAdvanced.c,
+// AddBootOption.c
+//
+// 1 2/19/10 12:58p Madhans
+// Uploaded for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 2 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 1 7/30/09 7:32a Mallikarjunanv
+// New header file to handle the Elinks related inforamtion
+//
+// 1 7/30/09 7:27a Mallikarjunanv
+// New file to handle Elink related definitions
+//
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: TseElinks.h
+//
+// Description: Header file for Elink related customizations
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _TSEELINKS_H_
+#define _TSEELINKS_H_
+
+#define END_OF_EXIT_PAGE_OPTION_LIST 0xFF
+
+///Default fucntions to handle Exit page options...
+VOID HandleSaveAndExit(VOID);
+VOID HandleExitApplication(VOID);
+VOID HandleSaveAndReset(VOID);
+VOID HandleResetSys(VOID);
+VOID HandleSaveWithoutExit(VOID);
+VOID HandleLoadPreviousValues(VOID);
+VOID HandleLoadOptimalDefaults(VOID);
+VOID HandleSaveUserDefaults(VOID);
+VOID HandleRestoreUserDefaults(VOID);
+VOID HandleBootAddBootOption(VOID);
+VOID HandleLaunchFileSystem(VOID); //EIP_41615 related to file browser support in AddBootOption
+VOID HandleLaunchFileSystemDriver (VOID);
+VOID HandleDriverAddDriverOption (VOID);
+VOID SaveUserDefaultsSilently(VOID);
+VOID LoadUserDefaultsSilently(VOID);
+
+typedef VOID (*OPTION_CALLBACK)(VOID);
+
+typedef struct _EXIT_PAGE_OPTIONS
+{
+ UINT8 OptIdx;
+ OPTION_CALLBACK ExitPageCallBack;
+}
+EXIT_PAGE_OPTIONS;
+
+typedef struct
+{
+ EFI_GUID FormsetGuid;
+ UINT32 QuestionID;
+ BOOLEAN EncodingFlag;
+}PASSWORD_ENOCDE_LIST_TEMPLATE;
+
+#endif /* _TSEELINKS_H_ */
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/boot.h b/Core/EM/AMITSE/Inc/boot.h
new file mode 100644
index 0000000..3172a07
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/boot.h
@@ -0,0 +1,537 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/boot.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 12 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/boot.h $
+//
+// 12 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 8 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 10 9/21/12 9:41a Premkumara
+// [TAG] EIP 97704
+// [Category] Improvement
+// [Description] Support BootFFFF variable
+// [Files] Boot.h, Boot.c, Special.c
+//
+// 9 5/29/12 2:55a Arunsb
+// [TAG] EIP91109
+// [Category] Improvement
+// [Description] Sync the Aptio IV source for AptioV
+// [Files] boot.h
+//
+// 8 11/13/11 12:21p Arunsb
+// [TAG] EIP70421
+// [Category] New Feature
+// [Description] Support for driver order in TSE
+// [Files] AMITSE.SDL, CommonHelper.c, setup.ini, uefisetup.ini,
+// boot.c,
+// minisetup.h, bbs.c, special.c, special.h, tseadvanced.c,
+// addbootoption.c,
+// callback.c, minisetupext.c, minisetupext.h, popupsel.c, popupsel.h,
+// TseLitehelper.c, variable.c, Uefi21Wapper.c, AMIVfr.h, boot.h,
+// TseElink.h, variable.h,
+// setup.h, Boot.vfr and Setup.uni
+//
+// 7 6/20/11 11:38a Rajashakerg
+// [TAG] EIP59417
+// [Category] New Feature
+// [Description] Spport LOAD_OPTION_HIDDEN option in TSE
+// [Files] boot.h, AMITSE.sdl, CommonHelper.c, bbs.c, boot.c,
+// minisetup.h, special.c, callback.c
+//
+// 6 3/15/11 5:11a Rajashakerg
+// [TAG] EIP51671
+// [Category] New Feature
+// [Description] Boot overide menu devices are not disable
+// [Files] boot.c, minisetup.h, special.c, minisetupext.c, AMITSE.sdl,
+// boot.h, CommonHelper.c
+//
+// 5 9/20/10 6:46p Madhans
+// [TAG] EIP44542
+// [Category] BUILD ISSUE FIX
+// [Symptom] Build issues with TSE label (INT)4.6.2_TSE_2_10_1207_TEST
+// when IdeSecurity and FastBoot modules added to the project
+// [RootCause] -
+// [Solution] Build issues resolved
+// [Files] CommonHelper.c, Tsecommon.h, Hiilib.h, Boot.h, minisetup.h,
+// bbs.c, special.c, Bds.c TseLitehelp
+//
+// 4 3/26/10 5:26p Madhans
+// EIP 35562: Support To create Boot option in Capital letters.
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 4 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 3 1/09/10 2:29a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards.
+//
+// 1 6/09/09 9:53a Madhans
+// TSE 2.00.1201
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: boot.h
+//
+// Description: UEFI Boot related header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _BOOT_H_
+#define _BOOT_H_
+
+#if !TSE_USE_EDK_LIBRARY
+//EIP:39334 - START
+#if TSE_CSM_SUPPORT
+#include <Protocol/LegacyBios.h>
+#else //If CSM support is not available, then TSE need the following info to build.
+
+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \
+ { 0xdb9a1e3d, 0x45cb, 0x4abb, 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d}
+
+GUID_VARIABLE_DECLARATION(gEfiLegacyBiosProtocolGuid,EFI_LEGACY_BIOS_PROTOCOL_GUID);
+
+#ifndef GUID_VARIABLE_DEFINITION
+#include <Protocol/DevicePath.h>
+
+typedef struct _EFI_LEGACY_BIOS_PROTOCOL EFI_LEGACY_BIOS_PROTOCOL;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: HDD_INFO
+//
+// Fields:
+// Status UINT16 Status of IDE device. See Notes for details.
+// Bus UINT32 PCI bus of IDE controller.
+// Device UINT32 PCI device of IDE controller.
+// Function UINT32 PCI function of IDE controller.
+// CommandBaseAddress UINT16 Command ports base address.
+// ControlBaseAddress UINT16 Control ports base address.
+// BusMasterAddress UINT16 Bus master address.
+// IdentifyDrive ATAPI_IDENTIFY Data that identifies the drive data.
+//
+// Notes:
+// The values for the Status field are the following:
+// HDD_PRIMARY 0x01
+// HDD_SECONDARY 0x02
+// HDD_MASTER_ATAPI 0x04
+// HDD_SLAVE_ATAPI 0x08
+// HDD_MASTER_IDE 0x20
+// HDD_SLAVE_IDE 0x40
+// HDD_SATA_PATA 0x80
+// There is one HDD_INFO structure per IDE controller. The IdentifyDrive is
+// one per drive. Index 0 is master and index 1 is slave.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _ATAPI_IDENTIFY {
+ UINT16 Raw[256];
+} ATAPI_IDENTIFY;
+
+//*************************************************
+// IDE device status values
+//*************************************************
+
+#define HDD_PRIMARY 0x01
+#define HDD_SECONDARY 0x02
+#define HDD_MASTER_ATAPI 0x04
+#define HDD_SLAVE_ATAPI 0x08
+#define HDD_MASTER_IDE 0x20
+#define HDD_SLAVE_IDE 0x40
+#define HDD_SATA_PATA 0x80
+
+typedef struct _HDD_INFO {
+ UINT16 Status;
+ UINT32 Bus;
+ UINT32 Device;
+ UINT32 Function;
+ UINT16 CommandBaseAddress;
+ UINT16 ControlBaseAddress;
+ UINT16 BusMasterAddress;
+ UINT8 HddIrq;
+ ATAPI_IDENTIFY IdentifyDrive[2];
+} HDD_INFO;
+
+
+//****************************************************
+// BBS related definitions
+//****************************************************
+
+//
+// BootPriority values
+//
+#define BBS_DO_NOT_BOOT_FROM 0xFFFC
+#define BBS_LOWEST_PRIORITY 0xFFFD
+#define BBS_UNPRIORITIZED_ENTRY 0xFFFE
+#define BBS_IGNORE_ENTRY 0xFFFF
+//
+// Following is a description of the above fields.
+//
+// BBS_DO_NOT_BOOT_FROM - Removes a device from the boot list but still
+// allows it to be enumerated as a valid device
+// under MS-DOS*.
+// BBS_LOWEST_PRIORITY - Forces the device to be the last boot device.
+// BBS_UNPRIORITIZED_ENTRY - Value that is placed in the BBS_TABLE.BootPriority
+// field before priority has been assigned but that
+// indicates it is valid entry. Other values indicate
+// the priority, with 0x0000 being the highest priority.
+// BBS_IGNORE_ENTRY - When placed in the BBS_TABLE.BootPriority field,
+// indicates that the entry is to be skipped.
+//
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BBS_STATUS_FLAGS
+//
+// Fields:
+// OldPosition UINT16:4 Prior priority.
+// Reserved1 UINT16:4 Reserved for future use.
+// Enabled UINT16:1 If 0, ignore this entry.
+// Failed UINT16:1 0-Not known if boot failure occurred; 1-Boot attempt failed.
+// MediaPresent UINT16:2 State of media present, see notes.
+// Reserved2 UINT16:4 Reserved for future use.
+//
+// Notes:
+// MediaPresent field details:
+// 00 = No bootable media is present in the device.
+// 01 = Unknown if a bootable media present.
+// 10 = Media is present and appears bootable.
+// 11 = Reserved.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT16 OldPosition : 4;
+ UINT16 Reserved1 : 4;
+ UINT16 Enabled : 1;
+ UINT16 Failed : 1;
+ UINT16 MediaPresent: 2;
+ UINT16 Reserved2 : 4;
+} BBS_STATUS_FLAGS;
+
+
+
+//****************************************************
+// DeviceType values
+//****************************************************
+#define BBS_FLOPPY 0x01
+#define BBS_HARDDISK 0x02
+#define BBS_CDROM 0x03
+#define BBS_PCMCIA 0x04
+#define BBS_USB 0x05
+#define BBS_EMBED_NETWORK 0x06
+#define BBS_BEV_DEVICE 0x80
+#define BBS_UNKNOWN 0xff
+
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BBS_TABLE
+//
+// Fields:
+// BootPriority UINT16 The boot priority for this boot device.
+// Bus UINT32 The PCI bus for this boot device.
+// Device UINT32 The PCI device for this boot device.
+// Function UINT32 The PCI function for the boot device.
+// Class UINT8 The PCI class for this boot device..
+// SubClass UINT8 The PCI Subclass for this boot device.
+// MfgString UINT32 Segment:offset address of an ASCIIZ description.
+// DeviceType UINT16 BBS device type.
+// StatusFlags BBS_STATUS_FLAGS Status of this boot device.
+// BootHandler UINT32 Segment:Offset address of boot loader for IPL devices.
+// DescString UINT32 Segment:offset address of an ASCIIZ description string.
+// InitPerReserved UINT32 Reserved.
+// AdditionalIrq??Handler UINT32 See notes for details.
+// AssignedDriveNumber UINT8 The drive number(0x80 -0x8?) assigned by the 16-bit code.
+// IBV1 UINT32 IBV specific field.
+// IBV2 UINT32 IBV specific field.
+//
+// Notes:
+// The use of AdditionalIrq??Handler fields is IBV dependent. They can be
+// used to flag that an OpROM has hooked the specified IRQ. The OpROM
+// may be BBS compliant as some SCSI BBS-compliant OpROMs also hook IRQ
+// vectors in order to run their BIOS Setup.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _BBS_TABLE {
+ UINT16 BootPriority;
+ UINT32 Bus;
+ UINT32 Device;
+ UINT32 Function;
+ UINT8 Class;
+ UINT8 SubClass;
+ UINT16 MfgStringOffset;
+ UINT16 MfgStringSegment;
+ UINT16 DeviceType;
+ BBS_STATUS_FLAGS StatusFlags;
+ UINT16 BootHandlerOffset;
+ UINT16 BootHandlerSegment;
+ UINT16 DescStringOffset;
+ UINT16 DescStringSegment;
+ UINT32 InitPerReserved;
+ UINT32 AdditionalIrq13Handler;
+ UINT32 AdditionalIrq18Handler;
+ UINT32 AdditionalIrq19Handler;
+ UINT32 AdditionalIrq40Handler;
+ UINT8 AssignedDriveNumber;
+ UINT32 AdditionalIrq41Handler;
+ UINT32 AdditionalIrq46Handler;
+ UINT32 IBV1;
+ UINT32 IBV2;
+} BBS_TABLE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_LEGACY_BIOS_BOOT
+//
+// Description: Boots a traditional OS
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// BootOption The EFI device path from BootXXXX variable.
+// LoadOptionSize Size of LoadOption.
+// LoadOption The load option from BootXXXX variable.
+//
+// Output:
+// EFI_DEVICE_ERROR Failed to boot from any boot device and
+// memory is uncorrupted.
+//
+// Notes: This function normally never returns. It will either boot the OS
+// or reset the system if memory has been "corrupted" by loading a
+// boot sector and passing control to it.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_BOOT) (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN BBS_BBS_DEVICE_PATH *BootOption,
+ IN UINT32 LoadOptionsSize,
+ IN VOID *LoadOptions
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_LEGACY_BIOS_GET_BBS_INFO
+//
+// Description: Presents BBS information to external agents.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// HddCount Number of HDD_INFO structures.
+// HddInfo Onboard IDE controller information.
+// BbsCount Number of BBS_TABLE structures.
+// BbsTable BBS entry.
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_LEGACY_BIOS_GET_BBS_INFO) (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ OUT UINT16 *HddCount,
+ OUT struct _HDD_INFO **HddInfo,
+ OUT UINT16 *BbsCount,
+ IN OUT struct _BBS_TABLE **BbsTable
+ );
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_LEGACY_BIOS_PROTOCOL
+//
+// Description: Abstracts the traditional BIOS from the rest of EFI. The
+// LegacyBoot() member function allows the BDS to support booting
+// a traditional OS. EFI thunks drivers that make EFI bindings for
+// BIOS INT services use all the other member functions.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _EFI_LEGACY_BIOS_PROTOCOL {
+ EFI_LEGACY_BIOS_BOOT LegacyBoot;
+ EFI_LEGACY_BIOS_GET_BBS_INFO GetBbsInfo;
+} EFI_LEGACY_BIOS_PROTOCOL;
+
+#endif //#ifndef GUID_VARIABLE_DEFINITION
+#endif //#if !TSE_CSM_SUPPORT
+#endif
+//EIP:39334 - END
+
+
+#define MAX_BOOT_OPTIONS 0xFFFF
+
+#ifndef LOAD_OPTION_ACTIVE
+#define LOAD_OPTION_ACTIVE 0x00000001
+#endif
+//EIP:59417 - Checking for LOAD_OPTION_HIDDEN attribute declearaton
+#define LOAD_OPTION_HIDDEN 0x00000008
+
+#ifndef LOAD_OPTION_FORCE_RECONNECT
+#define LOAD_OPTION_FORCE_RECONNECT 0x00000002
+#endif
+//EIP-97704 changed macro to global variable
+//#define DISABLED_BOOT_OPTION 0xFFFF
+//#define DISABLED_DRIVER_OPTION 0xFFFF
+extern UINT16 DISABLED_BOOT_OPTION;
+extern UINT16 DISABLED_DRIVER_OPTION;
+
+#define BOOT_ORDER_OPTION 0
+#define DRIVER_ORDER_OPTION 1
+
+typedef struct _BOOT_OPTION
+{
+ UINT32 Active;
+ UINT16 PathLength;
+ CHAR16 Name[1];
+}
+BOOT_OPTION;
+
+typedef struct _BBS_ORDER_LIST BBS_ORDER_LIST;
+
+typedef struct _BOOT_DATA
+{
+ UINT16 Option;
+ UINT32 Active;
+ CHAR16 *Name;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ VOID *LoadOptions;
+ UINTN LoadOptionSize;
+ BOOLEAN bNewOption;
+ UINTN LegacyEntryOffset;
+ UINT16 LegacyDevCount;
+ BBS_ORDER_LIST *OrderList;
+}
+BOOT_DATA;
+
+typedef struct _LANGUAGE_DATA
+{
+//#if SETUP_SUPPORT_PLATFORM_LANG_VAR
+ CHAR8 *LangCode;
+ CHAR16 *Unicode;
+//#else
+// CHAR8 LangCode[4];
+// CHAR16 Unicode[4];
+//#endif
+ CHAR16 *LangString;
+ UINT16 Token;
+}
+LANGUAGE_DATA;
+
+//#if SETUP_SUPPORT_ADD_BOOT_OPTION
+typedef struct _FS_DATA
+{
+ CHAR16 *FsId;
+ EFI_DEVICE_PATH_PROTOCOL *FsPath;
+}
+FS_DATA;
+//#endif
+
+//exported variables
+extern UINTN gBootOptionCount;
+extern CHAR16 gBootFileName[];
+extern BOOLEAN gShowAllBbsDev,gPopupMenuShowAllBbsDev;
+extern BOOLEAN gSetupHideDisableBootOptions,gPopupMenuHideDisableBootOptions;// EIP:51671 extern decleration of the global varibales to use in soruces.
+extern BOOLEAN gLoadOptionHidden; //EIP:59417 - extern decleration of the global varibales to use in soruces.
+extern CHAR16 gBootFormarSpecifier[];
+
+extern UINT16 *gBBSDisabled;
+//#if SETUP_SUPPORT_ADD_BOOT_OPTION
+extern UINTN gFsCount;
+extern FS_DATA *gFsList;
+//#endif
+
+//exported functions
+EFI_STATUS BootGetBootOptions( VOID );
+EFI_STATUS BootLaunchBootOption(UINT16 u16Option, UINT16 *pOrder, UINTN u16OrderCount);
+BOOT_DATA *BootGetBootData( UINT16 Option );
+CHAR16 *BootGetOptionName( BOOT_DATA *bootData);
+
+CHAR16 *BootGetBootNowName( UINT16 value, BOOLEAN ShowAllBBSDev, BOOLEAN TseBootNowInBootOrde);
+
+VOID BootGetLanguages( VOID );
+//EFI_STATUS BootLaunchBootNow( UINT16 Index );
+EFI_STATUS BootLaunchBootNow( UINT16 index, BOOLEAN ShowAllBbsDev );
+EFI_STATUS BootLaunchGuid( EFI_GUID *guid );
+EFI_STATUS BootLaunchFilename( CHAR16 *fileName );
+//#if SETUP_SUPPORT_ADD_BOOT_OPTION
+VOID BootAddBootOption( VOID );
+VOID BootDelBootOption( UINT16 index );
+VOID DiscardAddDelBootOptions(VOID);
+VOID SaveAddDelBootOptions(VOID);
+
+//EIP70421 & 70422 Support for driver order starts
+extern UINTN gDriverOptionCount;
+extern CHAR16 gDriverFormarSpecifier [];
+BOOT_DATA *DriverGetDriverData (UINT16);
+CHAR16 *DriverGetOptionName (BOOT_DATA *);
+VOID DriverDelDriverOption (UINT16);
+VOID DriverAddDriverOption ();
+VOID DiscardAddDelDriverOptions (VOID);
+VOID SaveAddDelDriverOptions (VOID);
+//EIP70421 & 70422 Support for driver order ends
+//#endif
+
+#endif /* _BOOT_H_ */
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/mem.h b/Core/EM/AMITSE/Inc/mem.h
new file mode 100644
index 0000000..f4b93d9
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/mem.h
@@ -0,0 +1,100 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/mem.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 5 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/mem.h $
+//
+// 5 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 5 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 4 11/10/11 12:46a Arunsb
+// [TAG] EIP67735
+// [Category] Improvement
+// [Description] Zeroing password buffers before freeing
+// [Files] mem.c, mem.h, popupedit.c, popuppassword.c and tseadvanced.c
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 3 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 2 6/24/09 6:12p Madhans
+// Made TSE_USE_EDK_LIBRARY=OFF to not to refer EDK module.
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: mem.h
+//
+// Description: memory utility functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _MEM_H_
+#define _MEM_H_
+
+VOID MemFreePointer (VOID **ptr);
+VOID StringZeroFreeMemory (VOID **ptr);
+VOID MemCopy( VOID *dest, VOID *src, UINTN size );
+VOID MemSet( VOID *buffer, UINTN size, UINT8 value );
+#if !TSE_USE_EDK_LIBRARY
+INTN MemCmp( VOID *dest, VOID *src, UINTN size );
+#endif
+VOID *MemReallocateZeroPool( VOID *oldBuffer, UINTN oldSize, UINTN newSize );
+VOID MemFillUINT16Buffer( VOID *buffer, UINTN bufferSize, UINT16 value );
+
+#endif /* _MEM_H_ */
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/setupdata.h b/Core/EM/AMITSE/Inc/setupdata.h
new file mode 100644
index 0000000..b92052f
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/setupdata.h
@@ -0,0 +1,421 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/setupdata.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 10 $
+//
+// $Date: 4/02/13 8:01a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/setupdata.h $
+//
+// 10 4/02/13 8:01a Arunsb
+// [TAG] EIP113919
+// [Category] Improvement
+// [Description] Provide support for EFI_IFR_WRITE, EFI_IFR_READ,
+// EFI_IFR_GET, EFI_IFR_SET and EFI_IFR_MAP_OP.
+// [Files] Setupdata.h, ctrlcond.c, expression.c, hii.c and parse.c
+//
+// 9 3/25/13 8:08a Premkumara
+// [TAG] EIP105468
+// [Category] New Feature
+// [Description] Support for EFI_IFR_REFRESH_ID opcode for Offline
+// Parsing
+// [Files] Parse.c, Hii.c, Setupdata.h
+//
+// 8 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 9 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 7 1/20/12 12:46a Rajashakerg
+// [TAG] EIP80426
+// [Category] Improvement
+// [Description] When restoring settings, avoid accessing the varstore
+// for text controls
+// [Files] uefi21wapper.c, Setupdata.h.
+//
+// 6 6/23/11 3:38p Rajashakerg
+// [TAG] EIP55762, 58925, 59971
+// [Category] New Feature
+// [Description] Support REF2,REF3 and REF4 in AMITSE
+// Support direct form navigation path
+// Improper layout of controls in the root page when Dynamic pages are
+// added using the Legacy Setup Style
+// [Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c,
+// Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c,
+// minisetupext.h, numeric.c, page.c Popupstring.c, Hii.c,
+// Uefi21Wrapper.c, Parse.c Hii.c
+//
+// 5 4/29/11 4:28p Arunsb
+// For 2.13 public patch release IFR RefX feature is omitted
+//
+// 3 2/10/11 12:31p Blaines
+// [TAG] - EIP 53146
+// [Category]- New Feature
+// [Description] -Add the support to Move the Dynamic IFR Pages under
+// subpages. It should be customizable to move around.
+//
+// 2 6/17/10 2:17p Madhans
+// Refer Changelog.log.
+//
+// 1 2/19/10 12:58p Madhans
+// Uploaded for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 4 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 3 2/18/10 7:56p Madhans
+// AMI Special Var Attribute
+//
+// 2 1/09/10 2:34a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 1 10/28/09 5:32p Madhans
+//
+// 3 6/16/09 2:16p Presannar
+// Added File Headers for Header Files
+//
+// 2 6/12/09 7:44p Presannar
+// Initial implementation of coding standards for AMITSE2.0
+//
+// 1 6/04/09 8:05p Madhans
+//
+// 1 4/28/09 11:06p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 4 4/28/09 9:40p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 3 3/31/09 4:12p Madhans
+//
+// 2 1/30/09 6:06p Madhans
+// Function headers added.
+//
+// 1 12/18/08 7:59p Madhans
+// Intial version of TSE Lite sources
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: setupdata.h
+//
+// Description: Header file for setup data
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _SETUPDATA_H_
+#define _SETUPDATA_H_
+
+
+
+// forward declarations
+typedef struct _SETUP_PKG SETUP_PKG;
+typedef struct _SCREEN_INFO SCREEN_INFO;
+typedef struct _PAGE_LIST PAGE_LIST;
+typedef struct _PAGE_INFO PAGE_INFO;
+typedef struct _PAGE_FLAGS PAGE_FLAGS;
+typedef struct _CONTROL_LIST CONTROL_LIST;
+typedef struct _CONTROL_INFO CONTROL_INFO;
+typedef struct _CONTROL_FLAGS CONTROL_FLAGS;
+typedef struct _VARIABLE_LIST VARIABLE_LIST;
+typedef struct _VARIABLE_INFO VARIABLE_INFO;
+typedef struct _HPK_INFO HPK_INFO;
+typedef struct _GUID_LIST GUID_LIST;
+typedef struct _GUID_FLAGS GUID_FLAGS;
+typedef struct _GUID_INFO GUID_INFO;
+typedef struct _PAGE_ID_LIST PAGE_ID_LIST;
+typedef struct _PAGE_ID_INFO PAGE_ID_INFO;
+
+#define VARIABLE_NAME_LENGTH 40
+// Control types
+#define CONTROL_TYPE_NULL 0x0000
+#define CONTROL_TYPE_SUBMENU 0x0001
+#define CONTROL_TYPE_LABEL 0x0002
+#define CONTROL_TYPE_TEXT 0x0003
+#define CONTROL_TYPE_DATE 0x0004
+#define CONTROL_TYPE_TIME 0x0005
+#define CONTROL_TYPE_POPUPSEL 0x0006
+#define CONTROL_TYPE_MEMO 0x0008
+#define CONTROL_TYPE_MSGBOX 0x0009
+#define CONTROL_TYPE_CHECKBOX 0x000A
+#define CONTROL_TYPE_NUMERIC 0x000B
+#define CONTROL_TYPE_EDIT 0x000C
+#define CONTROL_TYPE_PASSWORD 0x000D
+#define CONTROL_TYPE_MENU 0x000E
+#define CONTROL_TYPE_ORDERED_LIST 0x000F
+#define CONTROL_TYPE_POPUPEDIT 0x0010
+#define CONTROL_TYPE_VARSTORE_SELECT 0x0011
+#define CONTROL_TYPE_VARSTORE_SELECT_PAIR 0x0012
+#define CONTROL_TYPE_POPUP_STRING 0x0013
+#define CONTROL_TYPE_VARSTORE 0x0014
+#define INCONSISTENT_IF 0x0015
+
+// UEFI 2.1 Defines
+#define NO_SUBMIT_IF 0x0016
+#define DISABLE_IF 0x0017
+#define CONTROL_TYPE_VARSTORE_NAME_VALUE 0x0018
+#define CONTROL_TYPE_VARSTORE_EFI 0x0019
+#define CONTROL_TYPE_VARSTORE_DEVICE 0x001A
+#define CONTROL_TYPE_ACTION 0x001B
+#define CONTROL_TYPE_RESET 0x001C
+#define CONTROL_TYPE_RULE 0x001D
+#define CONTROL_TYPE_REF2 0x001E // EIP 80426:When restoring settings, avoid accessing the varstore for text controls
+
+// Used in Edit.c
+#ifndef IFR_PASSWORD_OP
+#define IFR_PASSWORD_OP 0x08
+#endif
+
+#pragma warning( disable : 4201 )
+
+#pragma pack(8)
+struct _SETUP_PKG
+{
+ CHAR8 PackageSignature[4]; //'$SPF' Signature to identify the package file
+ UINT16 StructureRevision; //0x0100 Revision of this structure
+ UINT32 PackageVersion; //0x00000100 Version number of the structure data
+ UINT8 Reserved[6]; //0 Reserved for future expansion
+ EFI_GUID PackageGuid; //Varies EFI_GUID for the entire setup package
+ UINT32 PackageVariable; //0x00000001 ID of the default GUID-Name variable store for this package
+ UINT32 PackageScreen; //Varies Offset to start of SCREEN_INFO structure
+ UINT32 PackagePageList; //Varies Offset to start of PAGE_LIST structure
+ UINT32 PackageControlOffset; //Varies Offset to start of controls
+ UINT32 PackageVariableList; //Varies Offset to start of VARIABLE_LIST structure
+ UINT32 PackageHpkData; //Varies Offset to source HPK info that we need
+ UINT32 PackageGuidList; //Varies List of OEM GUIDs requiring application launch
+ UINT32 PackagePageIdList; //Varies Offset to list of Page ID triplets guid class subclass
+ UINT32 PackageIfrData; //Varies IFR data that is used to build our 'static' pages
+};
+
+struct _SCREEN_INFO //Structure containing global information used by all pages
+{
+ union {
+ /*EFI_HII_HANDLE*/VOID * MainHandle; //Varies HII Handle to the formset that contains the global screen info
+ UINT8 res[8];
+ };
+ UINT16 MainTitle; //Varies Token for title string
+ UINT16 MainCopyright; //Varies Token for copyright string
+ UINT16 MainHelpTitle; //Varies Token for help 'window' title
+ UINT16 MainMenuCount; //Varies Number of entries in main menu (0 = no main menu)
+ UINT16 MainNavCount; //Varies Number of nav help strings on the page
+ //UINT16 MenuEntries[]; //Varies Tokens for menu strings
+ //UINT16 MainNavToken[]; //Varies Tokens for all navigational help strings
+};
+
+struct _PAGE_LIST //This is the listing of all the pages in setup
+{
+ UINT32 PageCount; //Varies Number of pages in Setup
+ UINT32 PageList[1]; //Varies Offsets to each of the page structures
+};
+
+struct _PAGE_FLAGS //Structure containing the attributes global to a page
+{
+ UINT32 PageVisible : 1; //TRUE Controls whether or not this page is visible
+ UINT32 PageHelpVisible : 1; //TRUE Controls whether or not help is visible on this page
+ UINT32 PageDisableHotKeys : 1; //FALSE Controls whether globals hot keys are enabled for this page
+ UINT32 PageRefresh : 1; //TRUE Controls whether the page is refreshable
+ UINT32 PageModal : 1; //TRUE Controls whether the page is Modal
+ UINT32 PageDynamic : 1; //TRUE Controls whether the page is Dynamic
+ UINT32 PageStdMap : 1; // set 0 if Form map is not found otherwise set 1
+ UINT32 Reserved : 25; //0 Reserved for future use
+};
+
+struct _CONTROL_LIST //Structure containing the offsets of all the control data
+{
+ UINT32 ControlCount; //Varies Number of controls in this list
+ UINT32 ControlList[1]; //Varies Offsets to each of the control structures
+};
+
+struct _PAGE_INFO //Structure containing the layout of the page
+{
+ union {
+ /*EFI_HII_HANDLE*/VOID * PageHandle; //Varies HII Handle to the formset that contains this control
+ UINT8 res[8];
+ };
+ UINT16 PageIdIndex; //varies Index in to PageIdList triplets
+ UINT16 PageFormID; //Varies Form ID within the formset for this page
+ UINT16 PageTitle; //Varies Allows a page to override the main title bar
+ UINT16 PageSubTitle; //Varies Token for the subtitle string for this page
+ UINT16 PageID; //Varies unique ID for this page
+ UINT16 PageParentID; //Varies Identify this page's parent page
+ PAGE_FLAGS PageFlags; //3 Various attributes for a specific page
+ UINT32 PageVariable; //Varies Overrides the variable ID for this page (0 = use default)
+ CONTROL_LIST PageControls; //Varies Listing of controls for this page
+};
+
+
+struct _CONTROL_FLAGS //Structure containing the attributes for a specific control
+{
+ UINT32 ControlVisible : 1; //TRUE Whether or not a control is shown to the user
+#define CONTROL_ACCESS_DEFAULT 0 //Do not override VFR
+#define CONTROL_ACCESS_EXT_USER 1 //Admin - Editable; User - Editable;
+#define CONTROL_ACCESS_USER 2 //Admin - Editable; User - Visible but not editable;
+#define CONTROL_ACCESS_ADMIN 3 //Admin - Editable; User - Invisible;
+ UINT32 ControlAccess : 2; //0 User access to control
+ UINT32 ControlReset : 1; //FALSE Whether or not changing a value requires a system reset
+ UINT32 ControlReadOnly : 1; //FALSE Weather or not the control is read only.
+ UINT32 ControlInteractive : 1; //FALSE Weather the Control is interactive or not
+ UINT32 ControlEvaluateDefault : 1; // FALSE If set Default is obtained by expression evaluation
+ UINT32 Reserved1 : 1; //0 Reserved for future use
+ UINT32 ControlRefresh : 8; //0 Refresh timer (in 0.1s intervals) (0 = refresh disabled)
+ UINT32 RefreshID : 1; //TRUE or FALSE to denote RefreshID status
+ UINT32 ControlRWEvaluate : 1; // set 0 if read/write expression is not found otherwise set 1
+ UINT32 Reserved2 : 14; //0 Reserved for future use
+};
+
+struct _CONTROL_INFO //Structure containing control data
+{
+ union {
+ /*EFI_HII_HANDLE*/VOID * ControlHandle; //Varies HII Handle to the formset that contains this control
+ UINT8 res[8];
+ };
+ UINT32 ControlVariable; //Varies Overrides the variable ID for this control (0 = use default)
+ union
+ {
+ UINT32 ControlConditionalVariable[2]; //Varies Overrides the condition variable ID for this control (0 = use default)
+ struct
+ {
+ UINT16 ControlKey; // Varies Variable unique identifier same as QuestionID in UEFI2.1
+ UINT16 DevicePathId; // Device Path as specified by VarStoreDevicePath nested within the scope of this question.
+ UINT8 DefaultStoreCount; // Constant No of Defaults (n) values other than Optimal and Failsafe for that control.
+//EIP# 55762
+ UINT8 Reserved[1]; // Reserved space for use in future.
+ UINT16 DestQuestionID; // This is for EFI_IFR_REFX support
+//EIP# 55762
+ };
+ };
+ UINT16 ControlType; //Varies Type of the control on the page
+ UINT16 ControlPageID; //Varies Page ID that contains this control
+ UINT16 ControlDestPageID; //FFFFh Only needed for controls of type CONTROL_TYPE_SUBMENU
+ CONTROL_FLAGS ControlFlags; //1 Various attributes for a specific control
+ UINT16 ControlHelp; //Varies Token for help string for this control
+ UINT16 ControlLabel; //Varies One-based label number that this control is 'linked to'
+ UINT16 ControlIndex; //Varies Zero-based control number from the label, not formset
+ UINT16 ControlLabelCount; //Varies number of opcodes associated with this control's label
+ union {
+ VOID * ControlPtr; //Varies Pointer to control data in HII
+ UINT64 res1;
+ };
+ union {
+ VOID * ControlConditionalPtr; //Varies Pointer to control condition data in HII
+ UINT64 res2;
+ };
+ UINT16 ControlDataLength; //Varies Length of HII data for control
+ UINT16 ControlDataWidth; //Varies Width of data (in bytes) for this control
+ UINT16 QuestionId; //Varies Offset for data of this control in the Variable
+ //UINT8 ControlFailsafeValue; //Varies Used when user selects load failsafe value
+ //UINT8 ControlOptimalValue; //Varies Used when user selects load optimal value
+};
+
+struct _VARIABLE_LIST
+{
+ UINT32 VariableCount; //Varies Number of GUID-Name pairs in this list
+ UINT32 VariableList[1]; //Varies Offsets to each of the variable structures
+};
+
+struct _VARIABLE_INFO //Structure containing GUID-Name pairs for variable access
+{
+ EFI_GUID VariableGuid; //Varies EFI_GUID for the NVRAM variable store for this data
+ CHAR16 VariableName[VARIABLE_NAME_LENGTH]; //Varies Variable store name
+ UINT32 VariableAttributes; //Varies Attributes of the variable
+ UINT32 VariableID; //Varies unique variable number, 0x0FFFF for our own variables.
+#define VARIABLE_ATTRIBUTE_VARSTORE 0x0000 // Buffer varstore accessed via Config. Access protocol exposed by the driver.
+#define VARIABLE_ATTRIBUTE_EFI_VARSTORE 0x1000 // EFI Variable, GetVeriable and SetVariable Can be used.
+#define VARIABLE_ATTRIBUTE_NAMEVALUE 0x2000 // Namevalue varstore accessed via Config. Access protocol exposed by the driver.
+#define AMI_SPECIAL_NO_DEFAULTS 0x00000001
+#define AMI_SPECIAL_VARIABLE_NO_SET 0x00000002
+#define AMI_SPECIAL_VARIABLE_NO_GET 0x00000004
+ UINT32 ExtendedAttibutes; //Varies Extended Attributes to identify type of Variable.
+ UINT16 VariableNameId; //Varies Id for the Variable Name
+ UINT8 Reserved[2]; // Reserved space for use in future.
+ union
+ {
+ /*EFI_HII_HANDLE*/VOID* VariableHandle; //Varies HII Handle to the formset that contains this VarStore
+ UINT64 res;
+ };
+ UINT16 VariableSize; //Varies The size of Buffer Varstore
+};
+
+struct _HPK_INFO
+{
+ UINT32 Length;
+ UINT16 Class;
+ UINT16 SubClass;
+};
+
+struct _GUID_LIST
+{
+ UINT32 GuidCount; //Varies Number of GUID-Name pairs in this list
+ UINT32 GuidList[1]; //Varies Offsets to each of the variable structures
+};
+
+struct _GUID_FLAGS
+{
+ UINT32 GuidLaunchCallback : 1;
+ UINT32 GuidLaunchGuid : 1;
+ UINT32 GuidLaunchFilename : 1;
+ UINT32 GuidLaunchCallbackUpdateTemplate : 1;
+ UINT32 Reserved : 28;
+};
+
+struct _GUID_INFO
+{
+ EFI_GUID GuidValue;
+ CHAR16 GuidName[VARIABLE_NAME_LENGTH];
+ GUID_FLAGS GuidFlags;
+ UINT32 GuidKey;
+};
+
+struct _PAGE_ID_LIST
+{
+ UINT32 PageIdCount; //Varies Number of guid class subclass triplets
+ UINT32 PageIdList[1]; //Varies Offsets to each of the PageId structures
+};
+
+struct _PAGE_ID_INFO //Structure containing page id triplets guid class and subclass
+{
+ EFI_GUID PageGuid; //Varies EFI_GUID for the pages
+ UINT16 PageClass; //Varies Class for the pages
+ UINT16 PageSubClass; //Varies SubClass for the pages
+};
+
+#pragma pack()
+
+#endif /* _SETUPDATA_H_ */
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Inc/variable.h b/Core/EM/AMITSE/Inc/variable.h
new file mode 100644
index 0000000..18a8a08
--- /dev/null
+++ b/Core/EM/AMITSE/Inc/variable.h
@@ -0,0 +1,251 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/variable.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 13 $
+//
+// $Date: 5/03/14 6:37p $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc/variable.h $
+//
+// 13 5/03/14 6:37p Arunsb
+// [TAG] EIP130198
+// [Category] Improvement
+// [Description] Increase the variable ID range from 25 to 54
+// [Files] Variable.h, Setup.ini, UefiSetup.ini
+//
+// 12 2/11/14 7:37p Arunsb
+// Changes reverted for 2.16.1243 label
+//
+// 11 8/19/13 2:49a Premkumara
+// [TAG] EIP130198
+// [Category] Improvement
+// [Description] Increase the variable ID range from 25 to 54
+// [Files] Variable.h, Setup.ini, UefiSetup.ini
+//
+// 10 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 6 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 9 1/30/12 1:33a Arunsb
+// [TAG] EIP74676
+// [Category] Improvement
+// [Description] Setup.ini and Upfisetup.ini to reserve 3~5 variable and
+// GUID for porting purpose
+// [Files] Amivfr.h, special.h, variable.h, Uefisetup.ini and setup.ini
+//
+// 8 12/05/11 5:46a Rajashakerg
+// [TAG] EIP76381
+// [Category] Improvement
+// [Description] Performance: Improving variable data load and usage
+// [Files] callback.c, minisetupext.c, variable.c, variable.h,
+// minisetup.h, Hii.c, FormBrowser2.c
+//
+// 7 11/23/11 5:08a Rajashakerg
+// [TAG] EIP75473
+// [Category] Improvement
+// [Description] System Time is not updated every second
+// [Files] variable.h, variable.c, FormBrowser2.c, TseUefiHii.h,
+// Uefi21Wapper.c, hii.h, uefi20Wapper.c
+//
+// 6 11/13/11 12:23p Arunsb
+// [TAG] EIP70421
+// [Category] New Feature
+// [Description] Support for driver order in TSE
+// [Files] AMITSE.SDL, CommonHelper.c, setup.ini, uefisetup.ini,
+// boot.c,
+// minisetup.h, bbs.c, special.c, special.h, tseadvanced.c,
+// addbootoption.c,
+// callback.c, minisetupext.c, minisetupext.h, popupsel.c, popupsel.h,
+// TseLitehelper.c, variable.c, Uefi21Wapper.c, AMIVfr.h, boot.h,
+// TseElink.h, variable.h,
+// setup.h, Boot.vfr and Setup.uni
+//
+// 5 7/19/11 3:06p Arunsb
+// [TAG] EIP57661
+// [Category] New Feature
+// [Description] Drv health related variable declarations added to
+// update the cache.
+// [Files] notify.c, Uefi21Wapper.c and variable.h
+//
+// 4 7/19/11 10:47a Blaines
+// [TAG] - EIP 63262
+// [Category]- Defect
+// [Symptom]- Setup page display problem on rose city.
+// When SETUP_GROUP_DYNAMIC_PAGES is enabled and Network Stack is enabled,
+// the "iSCSI" menu is listed as a dynamic page in advanced menu but only
+// 3 of 4 "Port Configuration" pages shows up. The TSE dynamic page count
+// is incorrect.
+//
+// [Solution]- In the functions (RTIfrProcessRunTimeForms,
+// HandleNewIFRPack, HandleRemoveIFRPack, HandleAddIFRPack), make sure the
+// nvram cache is updated by calling
+// VarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT) when updating
+// "DynamicPageCount" variable name.
+// .
+// [Files] - Hii.c, Minisetup.h, Variable.h
+//
+// 3 2/19/10 12:59p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 4 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 3 1/09/10 2:31a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 2 10/28/09 5:34p Madhans
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:50p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: variable.h
+//
+// Description: Variable handling header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _VARIABLE_H_
+#define _VARIABLE_H_
+
+typedef struct _NVRAM_VARIABLE
+{
+ UINT8 *Buffer;
+ UINTN Size;
+}
+NVRAM_VARIABLE;
+
+#define VAR_ZERO_OFFSET 0
+
+#define VAR_COMMAND_GET_VALUE 0
+#define VAR_COMMAND_SET_VALUE 1
+
+#define VAR_COMMAND_GET_NVRAM 0
+#define VAR_COMMAND_SET_NVRAM 1
+
+// Variable IDs
+#define VARIABLE_ID_SETUP 0
+#define VARIABLE_ID_LANGUAGE 1
+#define VARIABLE_ID_BOOT_TIMEOUT 2
+#define VARIABLE_ID_USER_DEFAULTS 3
+#define VARIABLE_ID_ERROR_MANAGER 4
+#define VARIABLE_ID_AMITSESETUP 5
+#define VARIABLE_ID_IDE_SECURITY 6
+#define VARIABLE_ID_BOOT_ORDER 7
+#define VARIABLE_ID_BBS_ORDER 8
+#define VARIABLE_ID_DEL_BOOT_OPTION 9
+#define VARIABLE_ID_ADD_BOOT_OPTION 10
+#define VARIABLE_ID_BOOT_MANAGER 11
+#define VARIABLE_ID_BOOT_NOW 12
+#define VARIABLE_ID_LEGACY_DEV_INFO 13
+#define VARIABLE_ID_AMI_CALLBACK 14
+#define VARIABLE_ID_LEGACY_GROUP_INFO 15
+#define VARIABLE_ID_OEM_TSE_VAR 17
+#define VARIABLE_ID_DYNAMIC_PAGE_COUNT 18
+#define VARIABLE_ID_DRV_HLTH_ENB 19
+#define VARIABLE_ID_DRV_HLTH_COUNT 20
+#define VARIABLE_ID_DRIVER_MANAGER 22 //EIP70421 & 70422 Support for driver order
+#define VARIABLE_ID_DRIVER_ORDER 23
+#define VARIABLE_ID_ADD_DRIVER_OPTION 24
+#define VARIABLE_ID_DEL_DRIVER_OPTION 25
+#define VARIABLE_ID_PORT_OEM1 26 //EIP74676 variables for porting purpose
+#define VARIABLE_ID_PORT_OEM2 27
+#define VARIABLE_ID_PORT_OEM3 28
+#define VARIABLE_ID_PORT_OEM4 29
+#define VARIABLE_ID_PORT_OEM5 30
+#define VARIABLE_ID_PORT_OEM6 31
+#define VARIABLE_ID_PORT_OEM7 32
+#define VARIABLE_ID_PORT_OEM8 33
+#define VARIABLE_ID_PORT_OEM9 34
+#define VARIABLE_ID_PORT_OEM10 35
+#define VARIABLE_ID_PORT_OEM11 36
+#define VARIABLE_ID_PORT_OEM12 37
+#define VARIABLE_ID_PORT_OEM13 38
+#define VARIABLE_ID_PORT_OEM14 39
+#define VARIABLE_ID_PORT_OEM15 40
+#define VARIABLE_ID_PORT_OEM16 41
+#define VARIABLE_ID_PORT_OEM17 42
+#define VARIABLE_ID_PORT_OEM18 43
+#define VARIABLE_ID_PORT_OEM19 44
+#define VARIABLE_ID_PORT_OEM20 45
+#define VARIABLE_ID_PORT_OEM21 46
+#define VARIABLE_ID_PORT_OEM22 47
+#define VARIABLE_ID_PORT_OEM23 48
+#define VARIABLE_ID_PORT_OEM24 49
+#define VARIABLE_ID_PORT_OEM25 50
+#define VARIABLE_ID_PORT_OEM26 51
+#define VARIABLE_ID_PORT_OEM27 52
+#define VARIABLE_ID_PORT_OEM28 53
+#define VARIABLE_ID_PORT_OEM29 54
+
+//EIP 76381 : Performance Improving of variable data load and usage
+EFI_STATUS GetNvramVariableList(NVRAM_VARIABLE **RetNvramVarList);
+VOID CleanTempNvramVariableList();
+EFI_STATUS CopyNvramVariableList(NVRAM_VARIABLE *SrcVarList, NVRAM_VARIABLE **DestVarList);
+
+EFI_STATUS VarLoadVariables( VOID **list, NVRAM_VARIABLE *defaultList );
+EFI_STATUS VarBuildDefaults( VOID );
+VOID *VarGetNvramName( CHAR16 *name, EFI_GUID *guid, UINT32 *attributes, UINTN *size );
+EFI_STATUS VarSetNvramName( CHAR16 *name, EFI_GUID *guid, UINT32 attributes, VOID *buffer, UINTN size );
+VOID *VarGetNvram( UINT32 variable, UINTN *size );
+VOID *VarGetNvramQuestionValue(UINT32 variable, UINTN Offset, UINTN Size);
+EFI_STATUS VarSetNvram( UINT32 variable, VOID *buffer, UINTN size );
+EFI_STATUS VarGetDefaults( UINT32 variable, UINT32 offset, UINTN size, VOID *buffer );
+EFI_STATUS VarGetValue( UINT32 variable, UINT32 offset, UINTN size, VOID *buffer );
+EFI_STATUS VarSetValue( UINT32 variable, UINT32 offset, UINTN size, VOID *buffer );
+VOID VarUpdateVariable(UINT32 variable);
+VOID VarUpdateDefaults(UINT32 variable);
+VOID *VarGetVariable( UINT32 variable, UINTN *size );
+
+EFI_STATUS _VarGetData( UINT32 variable, UINT32 offset, UINTN size, VOID *buffer, BOOLEAN useDefaults );
+EFI_STATUS _VarGetSetValue( UINTN command, NVRAM_VARIABLE *list, UINT32 variable, UINT32 offset, UINTN size, VOID *buffer );
+
+#endif /* _VARIABLE_H_ */
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Keymon.c b/Core/EM/AMITSE/Keymon.c
new file mode 100644
index 0000000..94904a0
--- /dev/null
+++ b/Core/EM/AMITSE/Keymon.c
@@ -0,0 +1,302 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Keymon.c $
+//
+// $Author: Premkumara $
+//
+// $Revision: 7 $
+//
+// $Date: 8/28/14 4:29a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Keymon.c $
+//
+// 7 8/28/14 4:29a Premkumara
+// EIP-135253 Updating file name proper in #include
+//
+// 6 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 6 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 5 11/04/11 4:37a Arunsb
+// [TAG] EIP67615
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Keyattribute support doesn't work in AMITSE Keymon support
+// [RootCause] {SETUP_ENTRY_LEGACY_CODE,0} - This initilization code
+// initilize only ScanCode and ShiftKey.
+// It doesn't initilize the AltKey, CtrlKey etc ( Other fields in the
+// KEY_ATTRIBUTE structure).
+// [Solution] Modified the initilization like
+// {SETUP_ENTRY_LEGACY_CODE,{0,0,0,0}}
+// [Files] keymon.c
+//
+// 4 2/19/10 12:58p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 4 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 3 7/14/09 6:32p Blaines
+// For GTSE first Release.,
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 3 10/03/08 12:40p Madhans
+// Update the changes provided by the core team
+//
+// 2 7/18/07 7:58a Arunkumars
+// clean up
+//
+// 1 7/09/07 1:18p Arunkumars
+// - Added elink hooks for Logo, Password management and Control Keys
+// customizations
+//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//
+// Name: Keymon.c
+//
+// Description: Contains key monitoring functions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef TSE_FOR_APTIO_4_50
+
+#include "Token.h"
+#include <Efi.h>
+
+#else //#ifdef TSE_FOR_APTIO_4_50
+
+#include "minisetup.h"
+
+#endif //#ifdef TSE_FOR_APTIO_4_50
+
+#if SETUP_SUPPORT_KEY_MONITORING
+
+#include <Protocol\KeyMonPlatform.h>
+#include <Protocol\MonitorKeyFilter.h>
+
+#include "KeyMon.h"
+
+
+EFI_STATUS
+GetPlatformMonitorKeyOptions(
+ IN EFI_KEYMON_PLATFORM_PROTOCOL *This,
+ OUT KEY_ELEMENT **KeyList,
+ OUT UINTN *KeyListSize
+ );
+
+static EFI_GUID EfiKeyMonPlatformProtocolGuid = EFI_KEYMON_PLATFORM_PROTOCOL_GUID;
+
+static EFI_KEYMON_PLATFORM_PROTOCOL gKeyMonPlatformProtocol =
+{
+ GetPlatformMonitorKeyOptions
+};
+
+enum SETUP_KEYS
+{
+ SK_EntryKey
+#if SETUP_ALT_ENTRY_ENABLE
+ ,SK_AltEntryKey
+#endif
+#if SETUP_BBS_POPUP_ENABLE
+ ,SK_PopupBootEntryKey
+#endif
+#if SETUP_OEM_KEY1_ENABLE
+ ,SK_OemKey1
+#endif
+#if SETUP_OEM_KEY2_ENABLE
+ ,SK_OemKey2
+#endif
+#if SETUP_OEM_KEY3_ENABLE
+ ,SK_OemKey3
+#endif
+#if SETUP_OEM_KEY4_ENABLE
+ ,SK_OemKey4
+#endif
+};
+
+KEY_ELEMENT gLegacyKeyTable[]=
+{
+ {SETUP_ENTRY_LEGACY_CODE,{0,0,0,0}}
+#if SETUP_ALT_ENTRY_ENABLE
+ ,{SETUP_ALT_ENTRY_LEGACY_CODE,{0,0,0,0}}
+#endif
+#if SETUP_BBS_POPUP_ENABLE
+ ,{POPUP_MENU_ENTRY_LEGACY_CODE,{0,0,0,0}}
+#endif
+#if SETUP_OEM_KEY1_ENABLE
+ ,{SETUP_OEM_KEY1_LEGACY_CODE,{0,0,0,0}}
+#endif
+#if SETUP_OEM_KEY2_ENABLE
+ ,{SETUP_OEM_KEY2_LEGACY_CODE,{0,0,0,0}}
+#endif
+#if SETUP_OEM_KEY3_ENABLE
+ ,{SETUP_OEM_KEY3_LEGACY_CODE,{0,0,0,0}}
+#endif
+#if SETUP_OEM_KEY4_ENABLE
+ ,{SETUP_OEM_KEY4_LEGACY_CODE,{0,0,0,0}}
+#endif
+};
+
+UINT32 gLegacyKeys;
+EFI_HANDLE KeyMonProtocolHandle;
+
+extern EFI_BOOT_SERVICES *gBS;
+
+VOID InstallKeyMonProtocol(VOID)
+{
+ gBS->InstallProtocolInterface(
+ &KeyMonProtocolHandle,
+ &EfiKeyMonPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gKeyMonPlatformProtocol
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPlatformMonitorKeyOptions
+//
+// Description: This function registers keys with key monitor driver
+// for monitoring in the legacy mode.
+//
+// Input: EFI_USB_LEGACY_PLATFORM_PROTOCOL *This
+// KEY_ELEMENT **KeyList: List of keys to be monitored.
+// UINTN *KeyListSize: Size of data returned in KeyList.
+//
+// Output: Return Status based on errors that occurred in library
+// functions.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetPlatformMonitorKeyOptions(
+ IN EFI_KEYMON_PLATFORM_PROTOCOL *This,
+ OUT KEY_ELEMENT **KeyList,
+ OUT UINTN *KeyListSize
+ )
+{
+ *KeyList = gLegacyKeyTable;
+ *KeyListSize = sizeof(gLegacyKeyTable);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetKeysFromKeyMonFilter
+//
+// Description: This function receives keys from key monitor filter
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetKeysFromKeyMonFilter(VOID)
+{
+ UINT32 KeyDetected;
+ EFI_MONITOR_KEY_FILTER_PROTOCOL *MonKey;
+ EFI_STATUS Status;
+ EFI_GUID EfiMonitorKeyFilterProtocolGuid = EFI_MONITOR_KEY_FILTER_PROTOCOL_GUID;
+
+ // Locate protocols
+ Status = gBS->LocateProtocol (
+ &EfiMonitorKeyFilterProtocolGuid,
+ NULL, &MonKey);
+ if ( !(EFI_ERROR(Status)) )
+ {
+ MonKey->GetMonitoredKeys(MonKey, &KeyDetected);
+
+ if(KeyDetected & (1 << SK_EntryKey))
+ {
+ gLegacyKeys|=SETUP_ENTRY_KEY_BIT;
+ }
+#if SETUP_ALT_ENTRY_ENABLE
+ if(KeyDetected & (1 << SK_AltEntryKey))
+ {
+ gLegacyKeys|=SETUP_ENTRY_KEY_BIT;
+ }
+#endif
+#if SETUP_BBS_POPUP_ENABLE
+ if(KeyDetected & (1 << SK_PopupBootEntryKey))
+ {
+ gLegacyKeys|=POPUP_ENTRY_KEY_BIT;
+ }
+#endif
+#if SETUP_OEM_KEY1_ENABLE
+ if(KeyDetected & (1 << SK_OemKey1))
+ {
+ gLegacyKeys|=OEM_KEY1_BIT;
+ }
+#endif
+#if SETUP_OEM_KEY2_ENABLE
+ if(KeyDetected & (1 << SK_OemKey2))
+ {
+ gLegacyKeys|=OEM_KEY2_BIT;
+ }
+#endif
+#if SETUP_OEM_KEY3_ENABLE
+ if(KeyDetected & (1 << SK_OemKey3))
+ {
+ gLegacyKeys|=OEM_KEY3_BIT;
+ }
+#endif
+#if SETUP_OEM_KEY4_ENABLE
+ if(KeyDetected & (1 << SK_OemKey4))
+ {
+ gLegacyKeys|=OEM_KEY4_BIT;
+ }
+#endif
+
+ }
+}
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/Keymon.h b/Core/EM/AMITSE/Keymon.h
new file mode 100644
index 0000000..ac8ecf5
--- /dev/null
+++ b/Core/EM/AMITSE/Keymon.h
@@ -0,0 +1,106 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Keymon.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 4 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/Keymon.h $
+//
+// 4 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 5 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 3 2/19/10 12:58p Madhans
+// Updated for TSE 2.01. Refer Changelog.log for File change history.
+//
+// 3 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 2 6/24/09 6:33p Madhans
+// Coding Standards
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 7/09/07 1:18p Arunkumars
+// - Added elink hooks for Logo, Password management and Control Keys
+// customizations
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: keymon.h
+//
+// Description: header of keymon.c
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#if SETUP_SUPPORT_KEY_MONITORING
+
+#define SETUP_ENTRY_KEY_BIT 0x00000001
+#if SETUP_BBS_POPUP_ENABLE
+#define POPUP_ENTRY_KEY_BIT 0x00000002
+#endif
+#if SETUP_OEM_KEY1_ENABLE
+#define OEM_KEY1_BIT 0x00000004
+#endif
+#if SETUP_OEM_KEY2_ENABLE
+#define OEM_KEY2_BIT 0x00000008
+#endif
+#if SETUP_OEM_KEY3_ENABLE
+#define OEM_KEY3_BIT 0x00000100
+#endif
+#if SETUP_OEM_KEY4_ENABLE
+#define OEM_KEY4_BIT 0x00000200
+#endif
+
+VOID InstallKeyMonProtocol(VOID);
+VOID GetKeysFromKeyMonFilter(VOID);
+
+extern UINT32 gLegacyKeys;
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/AMITSE/OEMLogo.bmp b/Core/EM/AMITSE/OEMLogo.bmp
new file mode 100644
index 0000000..8015098
--- /dev/null
+++ b/Core/EM/AMITSE/OEMLogo.bmp
Binary files differ
diff --git a/Core/EM/AMITSE/SmLogo.bmp b/Core/EM/AMITSE/SmLogo.bmp
new file mode 100644
index 0000000..cad458e
--- /dev/null
+++ b/Core/EM/AMITSE/SmLogo.bmp
Binary files differ
diff --git a/Core/EM/AMITSE/TseDrvHealth.h b/Core/EM/AMITSE/TseDrvHealth.h
new file mode 100644
index 0000000..804285f
--- /dev/null
+++ b/Core/EM/AMITSE/TseDrvHealth.h
@@ -0,0 +1,188 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2012, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseDrvHealth.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 5 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseDrvHealth.h $
+//
+// 5 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 2 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 4 5/29/12 3:19a Arunsb
+// [TAG] EIP91109
+// [Category] Improvement
+// [Description] Sync the Aptio IV source for AptioV
+//
+// 3 5/28/12 11:09a Premkumara
+// [TAG] EIP83080
+// [Category] Improvement
+// [Description] Support REF4 type control.
+// [Files] TseDrvHealth.h, Hii.c
+//
+// 2 7/01/11 5:13a Arunsb
+// Build error suppressed when building with binaries alone.
+//
+// 1 6/30/11 4:04a Arunsb
+// Contains TSE specific driver health declarations.
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: TseDrvHealth.h
+//
+// Description: Header file for driver health only contains TSE specific.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#if EFI_SPECIFICATION_VERSION>=0x20014
+#include "Protocol/DriverHealth.h"
+#include "Protocol/DevicePathToText.h"
+#else
+
+#ifndef __DRIVER_HEALTH_PROTOCOL__H__
+#define __DRIVER_HEALTH_PROTOCOL__H__
+
+#define EFI_DRIVER_HEALTH_PROTOCOL_GUID \
+ { 0x2a534210, 0x9280, 0x41d8, 0xae, 0x79, 0xca, 0xda, 0x1, 0xa2, 0xb1, 0x27 }
+typedef struct _EFI_DRIVER_HEALTH_PROTOCOL EFI_DRIVER_HEALTH_PROTOCOL;
+
+typedef enum {
+ EfiDriverHealthStatusHealthy,
+ EfiDriverHealthStatusRepairRequired,
+ EfiDriverHealthStatusConfigurationRequired,
+ EfiDriverHealthStatusFailed,
+ EfiDriverHealthStatusReconnectRequired,
+ EfiDriverHealthStatusRebootRequired
+} EFI_DRIVER_HEALTH_STATUS;
+
+typedef UINT16 EFI_STRING_ID;
+typedef struct {
+ EFI_HII_HANDLE HiiHandle;
+ EFI_STRING_ID StringId;
+ UINT64 Reserved;
+} EFI_DRIVER_HEALTH_HII_MESSAGE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DRIVER_HEALTH_REPAIR_NOTIFY) (
+ IN UINTN Value,
+ IN UINTN Limit
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DRIVER_HEALTH_GET_HEALTH_STATUS) (
+ IN EFI_DRIVER_HEALTH_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle, OPTIONAL
+ IN EFI_HANDLE ChildHandle, OPTIONAL
+ OUT EFI_DRIVER_HEALTH_STATUS *HealthStatus,
+ OUT EFI_DRIVER_HEALTH_HII_MESSAGE **MessageList, OPTIONAL
+ OUT EFI_HII_HANDLE *FormHiiHandle OPTIONAL
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DRIVER_HEALTH_REPAIR) (
+ IN EFI_DRIVER_HEALTH_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle, OPTIONAL
+ IN EFI_DRIVER_HEALTH_REPAIR_NOTIFY RepairNotify OPTIONAL
+);
+
+struct _EFI_DRIVER_HEALTH_PROTOCOL {
+ EFI_DRIVER_HEALTH_GET_HEALTH_STATUS GetHealthStatus;
+ EFI_DRIVER_HEALTH_REPAIR Repair;
+};
+
+#endif /* __DRIVER_HEALTH_PROTOCOL__H__ */
+
+#ifndef __DEVICE_PATH_TO_TEXT_PROTOCOL__H__
+#define __DEVICE_PATH_TO_TEXT_PROTOCOL__H__
+
+
+#define EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID \
+ { 0x8b843e20, 0x8132, 0x4852, 0x90, 0xcc, 0x55, 0x1a, 0x4e, 0x4a, 0x7f, 0x1c }
+
+GUID_VARIABLE_DECLARATION(gEfiDevicePathToTextProtocolGuid, EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID);
+
+
+typedef struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL EFI_DEVICE_PATH_TO_TEXT_PROTOCOL;
+
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_NODE) (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+);
+
+typedef
+CHAR16*
+(EFIAPI *EFI_DEVICE_PATH_TO_TEXT_PATH) (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+);
+
+struct _EFI_DEVICE_PATH_TO_TEXT_PROTOCOL {
+ EFI_DEVICE_PATH_TO_TEXT_NODE ConvertDeviceNodeToText;
+ EFI_DEVICE_PATH_TO_TEXT_PATH ConvertDevicePathToText;
+};
+
+#endif /* __DEVICE_PATH_TO_TEXT_PROTOCOL__H__ */
+#endif /* EFI_SPECIFICATION_VERSION */
+
+typedef struct DRV_HEALTH_HNDLS{
+ EFI_HANDLE ControllerHandle;
+ EFI_HANDLE ChildHandle;
+ EFI_DRIVER_HEALTH_STATUS HealthStatus;
+ struct DRV_HEALTH_HNDLS *Next;
+}DRV_HEALTH_HNDLS;
+
+CHAR16 *GetDrvHlthCtrlName (DRV_HEALTH_HNDLS *);
+VOID AddHandleIntoList (EFI_HANDLE, EFI_HANDLE, EFI_DRIVER_HEALTH_STATUS);
+VOID DisplayMsgListMessageBox (EFI_DRIVER_HEALTH_HII_MESSAGE *MessageList);
+BOOLEAN AdvancedRepairSupported (VOID);
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2012, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************// \ No newline at end of file
diff --git a/Core/EM/AMITSE/UefiHpkTool.exe b/Core/EM/AMITSE/UefiHpkTool.exe
new file mode 100644
index 0000000..eb880b7
--- /dev/null
+++ b/Core/EM/AMITSE/UefiHpkTool.exe
Binary files differ
diff --git a/Core/EM/AMITSE/Uefisetup.ini b/Core/EM/AMITSE/Uefisetup.ini
new file mode 100644
index 0000000..1ab7b37
--- /dev/null
+++ b/Core/EM/AMITSE/Uefisetup.ini
@@ -0,0 +1,533 @@
+[section]
+variablecount = 55 ; number of variables to parse
+guidCount = 19 ; this is the number of GUID's to parse
+refreshrate = 2 ; rate of refresh in 0.1 second intervals
+fakeVarKey = 64254 ; 0xfafe is the key for fake var
+;VariableAttrib = 7 ; default attribute for variables found in VFR's
+;DefultsCount = 1 ; default data that to set from this ini file.
+guid = EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9
+scrtoken1 = 0
+scrtoken2 = 2
+scrtoken3 = 3
+scrtoken4 = 4
+scrtoken5 = 0
+scrtoken6 = 0
+scrtoken7 = 0
+
+[files]
+filecount = 6
+file1 = Main.hpk
+file2 = Advanced.hpk
+file3 = Chipset.hpk
+file4 = Boot.hpk
+file5 = Security.hpk
+file6 = Exit.hpk
+
+[variable0]
+guid = EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9
+name = Setup
+flags = 7
+extFlags = 0
+key = 0 ; 0x0 id is for setup variable
+
+[variable1]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = PlatformLang
+flags = 7
+extFlags = 1 ; no defaults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable2]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = Timeout
+flags = 7
+extFlags = 0
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable3]
+guid = C4CC0DE8-0687-4422-99C1-65351A5D5F95
+name = UserDefaults
+flags = 7
+extFlags = 0
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[Variable4]
+guid = ADDEBF82-A560-46B9-A280-78C6AB61AEDA
+name = ErrorManager
+flags = 0
+extFlags = 0
+key = 65535
+
+[Variable5]
+guid = c811fa38-42c8-4579-a9bb-60e94eddfb34
+name = AMITSESetup
+flags = 7
+extFlags = 0
+key = 65535
+
+[Variable6]
+guid = 3DD0DE67-02D7-4129-914A-9F377CC34B0D
+name = IDESecDev
+flags = 7
+extFlags = 0
+key = 65535
+
+[variable7]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = BootOrder
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable8]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652
+name = LegacyDevOrder
+flags = 3
+extFlags = 1 ; no defults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[Variable9]
+guid = F6C73719-F34C-479C-B32F-277FCBBCFE4F
+name = DelBootOption
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable10]
+guid = 19d96d3f-6a6a-47d2-b195-7b2432da3be2
+name = AddBootOption
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable11]
+guid = B4909CF3-7B93-4751-9BD8-5BA8220B9BB2
+name = BootManager
+flags = 7
+extFlags = 0
+key = 65535
+
+[Variable12]
+guid = 052E6EB0-F240-42C5-8309-45874545C6B4
+name = BootNowCount
+flags = 7
+extFlags = 0
+key = 65535
+
+[Variable13]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652
+name = LegacyDev
+flags = 1
+extFlags = 0
+key = 65535
+
+[Variable14]
+guid = 9CF0F18E-7C7D-49DE-B5AA-BBBAD6B21007
+name = AMICallback
+flags = 1
+extFlags = 0
+key = 65535
+
+[Variable15]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652
+name = LegacyGroup
+flags = 1
+extFlags = 0
+key = 65535
+
+[Variable16]
+guid = 052E6EB0-F240-42C5-8309-45874545C6B4
+name = SetupSaveState
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable17]
+guid = F4B2C007-94A1-4cd5-A710-F4141FCEBCA0
+name = OemTSEVar
+flags = 7
+key = 65535
+
+[Variable18]
+guid = B63BF800-F267-4f55-9217-E97FB3B69846
+name = DynamicPageCount
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable19]
+guid = 0885F288-418C-4be1-A6AF-8BAD61DA08FE
+name = DriverHlthEnable
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable20]
+guid = 7459A7D4-6533-4480-BBA7-79E25A4443C9
+name = DriverHealthCount
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable21]
+guid = 58279C2D-FB19-466e-B42E-CD437016DC25
+name = DrvHealthCtrlCnt
+flags = 2
+extFlags = 0
+key = 65535
+
+[variable22]
+guid = C0B4FB05-15E5-4588-9FE9-B3D39C067715
+name = DriverManager
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable23]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = DriverOrder
+flags = 3 ;variable attributes
+extFlags = 1 ; no defaults ;Extended attributes
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable24]
+guid = 7DF66C0F-D40A-4748-AC5A-6C0BEA786A1A
+name = AddDriverOption
+flags = 3 ;variable attributes
+extFlags = 1 ; no defaults ;Extended attributes
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[Variable25]
+guid = 17A3C5DA-F51F-437c-91B6-002B6F262593
+name = DelDriverOption
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable26]
+guid = EDA2B104-7A10-4519-B0A1-EBA5C52ACFCE
+name = OemPortVar1
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable27]
+guid = EF402953-B819-4cc2-A44C-4C9B4CFBC889
+name = OemPortVar2
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable28]
+guid = 1D6F853E-0006-40d8-9B4B-79618A5733B0
+name = OemPortVar3
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable29]
+guid = 47E87E67-FBC0-4c01-9002-4A0A6ECB92FF
+name = OemPortVar4
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable30]
+guid = 2799A453-FC10-4334-9E66-D3D6EF09D0EE
+name = OemPortVar5
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable31]
+guid = D77A3FE1-51FE-4613-A81D-82AE24464CFD
+name = OemPortVar6
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable32]
+guid = B5CEC017-74CB-4e10-BAC3-924A4CC629C8
+name = OemPortVar7
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable33]
+guid = 78A6FB37-8F27-40a4-9C4E-9FC9E438D5E2
+name = OemPortVar8
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable34]
+guid = 8DAC5195-3FD5-4e32-9C2A-1A65BD699932
+name = OemPortVar9
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable35]
+guid = A6DB3378-CFD7-4bfd-A1C4-2709FEC52F8B
+name = OemPortVar10
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable36]
+guid = EA629472-D7C6-4c0e-8820-2B811C7EE3AF
+name = OemPortVar11
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable37]
+guid = 4CD97B67-12BB-4fc5-8B2A-580ADB6A6368
+name = OemPortVar12
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable38]
+guid = C03DDD47-DC0A-4319-9FEC-44B078C242E6
+name = OemPortVar13
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable39]
+guid = 2AAEC318-E84B-4e0b-BF41-AC65F17E9E2F
+name = OemPortVar14
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable40]
+guid = 1967167B-A13D-4e45-801B-A605D11946D5
+name = OemPortVar15
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable41]
+guid = 466A7291-50DF-4b40-A2EB-CEE67D5428C9
+name = OemPortVar16
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable42]
+guid = 4639A701-74F9-4635-B126-9FF048D6B0D0
+name = OemPortVar17
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable43]
+guid = EF02529C-A283-48cd-8D08-6A1E9C3C03D3
+name = OemPortVar18
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable44]
+guid = 4CD28F5E-4BBB-4602-ACB8-741BAA7EB313
+name = OemPortVar19
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable45]
+guid = 83C233EB-D01A-45d8-9FA1-AF40206FCC9B
+name = OemPortVar20
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable46]
+guid = 6169D4F6-0659-4fb5-B03C-3645D8C80DC8
+name = OemPortVar21
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable47]
+guid = 1C1EAB81-9229-42ac-B940-757C498A09ED
+name = OemPortVar22
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable48]
+guid = 0ECEDD30-67EC-4570-9EFB-308DE53EE93D
+name = OemPortVar23
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable49]
+guid = 913FA238-7B16-4b72-A5F0-815E7D2C8C1F
+name = OemPortVar24
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable50]
+guid = FE075D44-D9F1-4da1-AE6A-8250553CDE66
+name = OemPortVar25
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable51]
+guid = 471F5144-6037-4952-8B01-CFF586FDE6B3
+name = OemPortVar26
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable52]
+guid = 1318FED0-2765-42b5-803E-3215A3C093C5
+name = OemPortVar27
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable53]
+guid = FF5A0DC3-DFAC-434a-B3DF-FFD4C1EA7E41
+name = OemPortVar28
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable54]
+guid = 3F8DC333-CCD5-4e58-B8CF-7B9A8F31EA96
+name = OemPortVar29
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+;
+;These are samples of how to add GUID information into this file
+;
+[GUID0]
+guid = B4909CF3-7B93-4751-9BD8-5BA8220B9BB2
+name = BootManager
+flags = 1
+key = 1
+
+[GUID1]
+guid = 052E6EB0-F240-42C5-8309-45874545C6B4
+name = BootNowCount
+flags = 1
+key = 1
+
+[GUID2]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652 ;GUID for LegacyDevOrder & LegacyDev are same
+name = LegacyDevOrder
+flags = 1
+key = 7
+
+[GUID3]
+guid = 9CF0F18E-7C7D-49DE-B5AA-BBBAD6B21007
+name = AMICallback
+flags = 1
+key = 2
+
+[GUID4]
+guid = ADDEBF82-A560-46B9-A280-78C6AB61AEDA
+name = ErrorManager
+flags = 9
+key = 3
+
+[GUID5]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = PlatformLangCodes
+flags = 7
+key = 5
+
+[GUID6]
+guid = c57ad6b7-0515-40a8-9d21-551652854e37
+name = shell.efi|shellx64.efi|shellia64.efi
+flags = 6
+key = 0
+
+[GUID7]
+guid = 50064C83-F3D9-4270-B97B-BAC47B61E8DB
+name = shellpbm.efi
+flags = 6
+key = 0
+
+[GUID8]
+guid = 3DD0DE67-02D7-4129-914A-9F377CC34B0D
+name = IDESecDev
+flags = 1
+key = 8
+
+[GUID9]
+guid = 19d96d3f-6a6a-47d2-b195-7b2432da3be2
+name = AddBootOption
+flags = 0
+key = 9
+
+[GUID10]
+guid = F4B2C007-94A1-4cd5-A710-F4141FCEBCA0
+name = OemTSEVar
+flags = 1
+key = 10
+
+[GUID11]
+guid = B63BF800-F267-4f55-9217-E97FB3B69846
+name = DynamicPageCount
+flags = 0
+key = 14
+
+[GUID12]
+guid = 0885F288-418C-4be1-A6AF-8BAD61DA08FE
+name = DriverHlthEnable
+flags = 1
+key = 15
+
+[GUID13]
+guid = 7459A7D4-6533-4480-BBA7-79E25A4443C9
+name = DriverHealthCount
+flags = 1
+key = 16
+
+[GUID14]
+guid = 58279C2D-FB19-466e-B42E-CD437016DC25
+name = DrvHealthCtrlCnt
+flags = 1
+key = 17
+
+[GUID15]
+guid = C0B4FB05-15E5-4588-9FE9-B3D39C067715
+name = DriverManager
+flags = 0
+key = 18
+
+[GUID16]
+guid = ECFD4BCE-4279-40f8-BAF2-DCB79638D41E
+name = OemPortGuid1
+flags = 0
+key = 19
+
+[GUID17]
+guid = 23F69CD0-FF46-4db6-B982-63EDF1A901FF
+name = OemPortGuid2
+flags = 0
+key = 20
+
+[GUID18]
+guid = 8BDDF24B-2C8A-4360-A3BB-AEF094983BEA
+name = AMIDiag
+flags = 2
+key = 21
+
+;;syntax to set a default variable initial value from this ini file
+;[defaults0]
+;variable = 5 ;; variable number
+;mode = 0 ;; Standard (0) or Manufacturer (1)
+;offset = 80 ;; offset of the variable data
+;size = 1 ;; size of data to replace
+;data = 1 ;; Data to replace Format (Hex Bytes delimted by space)
diff --git a/Core/EM/AMITSE/bootflow.c b/Core/EM/AMITSE/bootflow.c
new file mode 100644
index 0000000..6d1b548
--- /dev/null
+++ b/Core/EM/AMITSE/bootflow.c
@@ -0,0 +1,445 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/bootflow.c $
+//
+// $Author: Premkumara $
+//
+// $Revision: 21 $
+//
+// $Date: 8/28/14 4:27a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/bootflow.c $
+//
+// 21 8/28/14 4:27a Premkumara
+// EIP-135253 Updating file name proper in #include section
+//
+// 20 12/04/13 2:43p Arunsb
+// [TAG] EIP125219
+// [Category] Improvement
+// [Description] Add event at end of BootFlowManageExit() after second
+// boot path
+// [Files] bootflow.c, AMIVfr.h
+//
+// 19 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 10 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 17 9/17/12 5:59a Rajashakerg
+// Updated EIP changes for 2.16 release.
+//
+// 15 8/29/12 12:31p Arunsb
+// [TAG] EIP93521
+// [Category] New Feature
+// [Description] Support of ESRT
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonhelper.c and
+// dobmpmgr.c
+//
+// 14 8/23/12 6:25p Arunsb
+//
+// 13 8/21/12 7:53p Arunsb
+// [TAG] EIP93521
+// [Category] New Feature
+// [Description] Support of ESRT
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonhelper.c and
+// dobmpmgr.c
+//
+// 12 5/28/12 2:50a Arunsb
+// [TAG] EIP88447
+// [Category] New Feature
+// [Description] Disable UEFI boot option in BIOS setup should not load
+// the default image \EFI\BOOT\BOOT{machine type short-name}.EFI
+// [Files] Amitse.sdl, commonhelper.c and bootflow.c
+//
+// 11 6/29/11 5:37a Arunsb
+// [TAG] EIP 62631
+// [Category] New Feature
+// [Description] Hot key boot option support in TSE as per UEFI spec.
+// section 3.1.6.
+// Added BOOT_FLOW_HOTKEY_BOOT bootflow option in
+// BOOT_FLOW.
+// [Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c,
+// commonoem.c, commonoem.h, boot.c,
+// hiistring20.c, hiistring21.c and notify.c.
+//
+// 10 6/23/11 7:41p Arunsb
+// [TAG] EIP57660
+// [Category] New Feature
+// [Description] Non-removable media boot behavior as described in UEFI
+// specification v 2.3.1, p. 3.4.1.
+// Checks for the setup key if no boot options avail
+// or not succedded to boot. If setup key pressed launches
+// the setup.
+// If no boot option avail then inserting thumb drive with
+// image efi\boot\bootxxxx.efi TSE will launch that image.
+// [Files] amitse.sdl, bootflow.c and protocol.c
+//
+// 9 6/20/11 3:43p Arunsb
+// [TAG] EIP57660
+// [Category] New Feature
+// [Description] Non-removable media boot behavior as described in UEFI
+// specification v 2.3.1, p. 3.4.1.
+// If BOOT_FLOW's LaunchShell param sets to
+// BOOTFLOW_EXIT_LAUNCH_DEFAULT_BOOTIMAGE then TSE tries to load the
+// efi/boot/bootxxxx.efi from any of the file system.
+// If BOOT_FLOW's InfiniteLoop param sets to
+// BOOTFLOW_EXIT_INFINITE_LOOP_LAUNCH_SETUP then TSE tried to enter the
+// setup
+// if no boot option present or succeeded to boot. Enters
+// to setup only when setup key detected after boot options failure
+// occurs.
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c, boot.c
+// and protocol.c
+//
+// 8 6/10/11 2:38p Arunsb
+// [TAG] EIP57660
+// [Category] New Feature
+// [Description] Non-removable media boot behavior as described in UEFI
+// specification v 2.3.1, p. 3.4.1.2
+// [Files] boot.c, bootflow.c and bootflow.h
+//
+// 7 6/08/11 11:38p Arunsb
+// [TAG] EIP57650
+// [Category] New Feature
+// [Description] Support in TSE Out of resources boot flow option.
+// [Files] bootflow.c and bootflow.h
+//
+// 6 3/15/11 2:39a Pugazhendhip
+// [TAG] EIP54858
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When developing projects with a custom Bootflow and custom
+// Setup, this PageFormID may not exist and will therefore cause a build
+// error
+// [RootCause] The MAIN_MAIN and MAIN_FORM_SET_CLASS are defined inside
+// the ifdef condition. Hence, when the condition macro is defined in the
+// project, the MAIN_MAIN and MAIN_FORM_SET_CLASS macros are not
+// available which causes the build error in the _gBootFlowTable array
+// declaration.
+// [Solution] Moved the following code fragment outside of else
+// condition compiler case (TSE_FOR_APTIO_4_50)
+//
+// #ifndef MAIN_FORM_SET_CLASS
+// #define MAIN_FORM_SET_CLASS 1
+// #endif
+//
+// #ifndef MAIN_MAIN
+// #define MAIN_MAIN 1
+// #endif
+//
+// [Files] bootflow.c
+//
+// 5 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 6 9/08/10 6:57a Mallikarjunanv
+// EIP-42080: TSE updates with respect to Fast Boot Support
+//
+// 5 4/13/10 5:12p Madhans
+// EIP: 37439 To support extended OEM Key support.
+//
+// 4 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 3 1/29/10 5:17p Madhans
+// changes to support UEFI 2.1 build also.
+//
+// 2 1/09/10 2:24a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 2 5/07/09 10:31a Madhans
+// Changes After Bin module.
+//
+// 3 5/05/09 3:10p Madhans
+// gBootFlowTable points to the Bootflow. OEM may update this Pointer with
+// OEM bootflow table.
+//
+// 2 5/01/09 8:25p Mallikarjunanv
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 2 1/30/09 6:06p Madhans
+// Function headers added.
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: bootflow.c
+//
+// Description: This file bootflow related functions and tables
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifdef TSE_FOR_APTIO_4_50
+
+#include "Token.h"
+#include <Efi.h>
+#include <Protocol/SimpleTextIn.h>
+
+#include "setup.h" // for MAIN_FORM_SET_CLASS
+#include "AutoId.h" // for MAIN_MAIN
+
+#else //#ifdef TSE_FOR_APTIO_4_50
+
+#include "minisetup.h"
+
+#endif //#ifdef TSE_FOR_APTIO_4_50
+
+#include "AmiVfr.h"
+#include "Variable.h"
+#include "boot.h"
+#include "bootflow.h"
+#include "mem.h"
+#include "commonoem.h"
+#include "HookAnchor.h"
+
+#ifndef MAIN_FORM_SET_CLASS
+#define MAIN_FORM_SET_CLASS 1
+#endif
+
+#ifndef MAIN_MAIN
+#define MAIN_MAIN 1
+#endif
+
+extern BOOLEAN gEnterSetup;
+extern EFI_GUID gEfiShellFileGuid;
+
+EFI_GUID _gBootFlowGuid = BOOT_FLOW_VARIABLE_GUID;
+static EFI_GUID _gTPMBootFlowGuid = TPM_BOOT_FLOW_VARIABLE_GUID;
+
+VOID SetupDebugPrint(IN CONST CHAR8 *Format, ...) ;
+#if SUPPRESS_PRINT
+ #define SETUP_DEBUG_TSE(format,...)
+#else //Else of SUPPRESS_PRINT
+ #define SETUP_DEBUG_TSE(format,...) SetupDebugPrint(format, __VA_ARGS__)
+#endif
+
+static BOOT_FLOW _gBootFlowTable[] =
+{
+// { Condition, PageClass, PageSubClass, PageFormID, ControlNumber, MessageBoxToken, MessageBoxTimeout, GotoPageOnEntry, ProceedBooting, InfiniteLoop, LaunchShell, DoNotEnterSetup, CallbackFunction },
+ { BOOT_FLOW_CONDITION_NORMAL, 0, 0, 0, 0, 0, 0, FALSE, TRUE, BOOT_FLOW_NORMAL_INFINITE_LOOP, BOOT_FLOW_NORMAL_LAUNCH_DEFAULT_BOOTIMAGE, FALSE, NULL },
+ { BOOT_FLOW_CONDITION_ERROR, ERROR_MANAGER_KEY_ID, 0, 1, 0, 0, 0, TRUE, FALSE, FALSE, TRUE, FALSE, NULL },
+ { BOOT_FLOW_CONDITION_RECOVERY, 0x40, 0, 1, 0, 0, 0, TRUE, TRUE, FALSE, TRUE, FALSE, NULL },
+ { BOOT_FLOW_CONDITION_PCI_OUT_OF_RESOURCE, 0x79, 0, 1, 0, 0, 0, TRUE, TRUE, FALSE, TRUE, FALSE, NULL },
+ { BOOT_FLOW_CONDITION_FIRST_BOOT, MAIN_FORM_SET_CLASS, 0, MAIN_MAIN, 0, 0, 0, TRUE, TRUE, FALSE, TRUE, FALSE, NULL },
+ { BOOT_FLOW_CONDITION_OS_UPD_CAP, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &OsUpdateCapsuleWrap }, //EIP93521
+ { BOOT_FLOW_HOTKEY_BOOT, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &LaunchHotKeyBootOption },
+#if SETUP_OEM_KEY1_ENABLE
+ { BOOT_FLOW_CONDITION_OEM_KEY1, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &OemKey1HookHook },
+#endif
+#if SETUP_OEM_KEY2_ENABLE
+ { BOOT_FLOW_CONDITION_OEM_KEY2, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &OemKey2HookHook },
+#endif
+#if SETUP_OEM_KEY3_ENABLE
+ { BOOT_FLOW_CONDITION_OEM_KEY3, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &OemKey3HookHook },
+#endif
+#if SETUP_OEM_KEY4_ENABLE
+ { BOOT_FLOW_CONDITION_OEM_KEY4, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &OemKey4HookHook },
+#endif
+#if SETUP_BBS_POPUP_ENABLE
+ { BOOT_FLOW_CONDITION_BBS_POPUP, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, &DoPopup },
+#endif
+ { BOOT_FLOW_CONDITION_OEM_KEY_CALLBACK, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, FALSE, FALSE, NULL }, // Callback is null and on OEMkey press it will updated.
+ { BOOT_FLOW_CONDITION_NO_SETUP, 0, 0, 0, 0, 0, 0, FALSE, TRUE, TRUE, FALSE, TRUE, NULL },
+#if FAST_BOOT_SUPPORT
+ { BOOT_FLOW_CONDITION_FAST_BOOT, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, TRUE, TRUE, &FBBootFlow },
+#endif
+ // this MUST be the last entry in the boot flow table
+ { BOOT_FLOW_CONDITION_NULL, 0, 0, 0, 0, 0, 0, FALSE, TRUE, FALSE, TRUE, FALSE, NULL }
+};
+
+// Set the initial Bootflow table.
+// OEM may have thier own Bottflow table and update the gBootFlowTable with that in the Entry hooks.
+BOOT_FLOW *gBootFlowTable = _gBootFlowTable;
+EFI_STATUS LaunchSecondaryBootPath (CHAR16 *); //EIP 88447
+EFI_STATUS EfiLibNamedEventSignal (IN EFI_GUID *Name ); //EIP125219
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BootFlowManageEntry
+//
+// Description: Determines boot flow entry path based on the boot
+// flow variable.
+//
+// Input: VOID
+//
+// Output: EFI_SUCCESS: Normal boot
+// EFI_UNSUPPORTED: do not proceed to boot
+// EFI_NOT_STARTED: Do not enter setup
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootFlowManageEntry( VOID )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 condition = BOOT_FLOW_CONDITION_NORMAL;
+ UINT32 *conditionPtr;
+ UINTN size = 0;
+
+ BOOT_FLOW *bootFlowPtr;
+
+ SETUP_DEBUG_TSE ("\n[TSE] Entering BootFlowManageEntry");
+ conditionPtr = VarGetNvramName( L"BootFlow", &_gBootFlowGuid, NULL, &size );
+ if ( conditionPtr != NULL )
+ condition = *conditionPtr;
+
+ MemFreePointer( (VOID **)&conditionPtr );
+
+ size = 0;
+ conditionPtr = VarGetNvramName( L"TPMBootFlow", &_gTPMBootFlowGuid, NULL, &size );
+
+ if ( conditionPtr != NULL )
+ {
+ if(*conditionPtr != BOOT_FLOW_CONDITION_NORMAL)
+ condition = *conditionPtr;
+ }
+
+ MemFreePointer( (VOID **)&conditionPtr );
+ bootFlowPtr = gBootFlowTable;
+ for ( bootFlowPtr = gBootFlowTable;
+ bootFlowPtr->Condition != BOOT_FLOW_CONDITION_NULL; bootFlowPtr++ )
+ {
+ if ( condition != bootFlowPtr->Condition )
+ continue;
+ SETUP_DEBUG_TSE ("\n[TSE] BootFlow condition is %d", condition);
+ if ( bootFlowPtr->CallbackFunction != NULL )
+ Status = bootFlowPtr->CallbackFunction( bootFlowPtr );
+ if ( ! bootFlowPtr->ProceedBooting )
+ Status = EFI_UNSUPPORTED;
+
+ if ( bootFlowPtr->MessageBoxToken != 0 )
+ _BootFlowShowMessageBox( bootFlowPtr );
+ if ( ( bootFlowPtr->GotoPageOnEntry ) && ( bootFlowPtr->PageClass != 0 ) )
+ {
+ _BootFlowSetActivePage( bootFlowPtr );
+ _BootFlowSetActiveControl( bootFlowPtr );
+ }
+
+ if(bootFlowPtr->DoNotEnterSetup)
+ {
+ gEnterSetup = FALSE;
+ Status = EFI_NOT_STARTED;
+ }
+
+ break;
+ }
+ SETUP_DEBUG_TSE ("\n[TSE] Exiting BootFlowManageEntry");
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BootFlowManageExit
+//
+// Description: Determines boot flow exit path based on the boot
+// flow variable.
+//
+// Input: VOID
+//
+// Output: EFI_UNSUPPORTED: enter setup if all the boot options
+// fail
+// EFI_NOT_STARTED: try again and again if all boot
+// options fail
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootFlowManageExit (VOID)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 condition = BOOT_FLOW_CONDITION_NORMAL;
+ UINT32 *conditionPtr;
+ UINTN size = 0;
+ BOOT_FLOW *bootFlowPtr;
+ EFI_GUID AfterLastBootGuid = AMITSE_AFTER_LAST_BOOT_OPTION_GUID;
+
+ SETUP_DEBUG_TSE ("\n[TSE] Entering BootFlowManageExit");
+ conditionPtr = VarGetNvramName( L"BootFlow", &_gBootFlowGuid, NULL, &size );
+ if ( conditionPtr != NULL )
+ condition = *conditionPtr;
+
+ MemFreePointer( (VOID **)&conditionPtr );
+
+ size =0;
+ conditionPtr = VarGetNvramName( L"TPMBootFlow", &_gTPMBootFlowGuid, NULL, &size );
+
+ if ( conditionPtr != NULL )
+ {
+ if(*conditionPtr != BOOT_FLOW_CONDITION_NORMAL)
+ condition = *conditionPtr;
+ }
+
+ MemFreePointer( (VOID **)&conditionPtr );
+
+ bootFlowPtr = gBootFlowTable;
+ for ( bootFlowPtr = gBootFlowTable;
+ bootFlowPtr->Condition != BOOT_FLOW_CONDITION_NULL; bootFlowPtr++ )
+ {
+ if ( condition != bootFlowPtr->Condition )
+ continue;
+ SETUP_DEBUG_TSE ("\n[TSE] BootFlow condition is %d", condition);
+
+ if ( bootFlowPtr->PageClass != 0 )
+ {
+ _BootFlowSetActivePage( bootFlowPtr );
+ _BootFlowSetActiveControl( bootFlowPtr );
+ Status = EFI_NOT_STARTED;
+ break;
+ }
+
+ if ( ! bootFlowPtr->InfiniteLoop )
+ Status = EFI_UNSUPPORTED;
+ else
+ Status = EFI_NOT_STARTED;
+
+ if (bootFlowPtr->LaunchShell)
+ {
+ LaunchSecondaryBootPath (gBootFileName); //EIP 88447
+ EfiLibNamedEventSignal (&AfterLastBootGuid); //EIP125219 notifying last boot
+ BootLaunchGuid (&gEfiShellFileGuid);
+ }
+ break;
+ }
+ SETUP_DEBUG_TSE ("\n[TSE] Exiting BootFlowManageExit");
+ return Status;
+}
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMITSE/bootflow.h b/Core/EM/AMITSE/bootflow.h
new file mode 100644
index 0000000..9a91189
--- /dev/null
+++ b/Core/EM/AMITSE/bootflow.h
@@ -0,0 +1,207 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/bootflow.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 15 $
+//
+// $Date: 10/18/12 5:31a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/bootflow.h $
+//
+// 15 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 6 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 13 9/17/12 5:59a Rajashakerg
+// Updated EIP changes for 2.16 release.
+//
+// 11 8/29/12 12:32p Arunsb
+// [TAG] EIP93521
+// [Category] New Feature
+// [Description] Support of ESRT
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonhelper.c and
+// dobmpmgr.c
+//
+// 10 8/23/12 6:26p Arunsb
+// Reverted back 2.15.1229 for making GTSE, TSELite and BootOnly labels
+//
+// 9 8/21/12 7:54p Arunsb
+// [TAG] EIP93521
+// [Category] New Feature
+// [Description] Support of ESRT
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonhelper.c and
+// dobmpmgr.c
+//
+// 8 6/29/11 5:25a Arunsb
+// [TAG] EIP 62631
+// [Category] New Feature
+// [Description] Hot key boot option support in TSE as per UEFI spec.
+// section 3.1.6.
+// Added BOOT_FLOW_HOTKEY_BOOT bootflow option for
+// honoring the hot key boot.
+// [Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c,
+// commonoem.c, commonoem.h, boot.c,
+// hiistring20.c, hiistring21.c and notify.c.
+//
+// 7 6/20/11 3:45p Arunsb
+// [TAG] EIP57660
+// [Category] New Feature
+// [Description] Non-removable media boot behavior as described in UEFI
+// specification v 2.3.1, p. 3.4.1.
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c, boot.c
+// and protocol.c
+//
+// 6 6/10/11 2:39p Arunsb
+// [TAG] EIP57660
+// [Category] New Feature
+// [Description] Non-removable media boot behavior as described in UEFI
+// specification v 2.3.1, p. 3.4.1.2
+// [Files] boot.c, bootflow.c and bootflow.h
+//
+// 5 6/08/11 11:38p Arunsb
+// [TAG] EIP57650
+// [Category] New Feature
+// [Description] Support in TSE Out of resources boot flow option.
+// [Files] bootflow.c and bootflow.h
+//
+// 4 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 4 9/08/10 6:57a Mallikarjunanv
+// EIP-42080: TSE updates with respect to Fast Boot Support
+//
+// 3 4/13/10 5:12p Madhans
+// EIP: 37439 To support extended OEM Key support.
+//
+// 2 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 2 1/30/09 6:06p Madhans
+// Function headers added.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: bootflow.h
+//
+// Description: bootflow header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _BOOTFLOW_H_
+#define _BOOTFLOW_H_
+
+/* EF152FB4-7B2F-427D-BDB4-7E0A05826E64 */
+#define BOOT_FLOW_VARIABLE_GUID \
+ { 0xEF152FB4, 0x7B2F, 0x427D, 0xBD, 0xB4, 0x7E, 0x0A, 0x05, 0x82, 0x6E, 0x64 }
+
+#define TPM_BOOT_FLOW_VARIABLE_GUID \
+ { 0xb6460a49, 0x0ac1, 0x484f, 0xae, 0x58, 0xf1, 0x6e, 0xb2, 0x39, 0xdb, 0x3d }
+
+#define BOOT_FLOW_CONDITION_NORMAL 0
+#define BOOT_FLOW_CONDITION_ERROR 1
+#define BOOT_FLOW_CONDITION_RECOVERY 2
+#define BOOT_FLOW_CONDITION_FIRST_BOOT 4
+
+#define BOOT_FLOW_CONDITION_OEM_KEY1 0x00001001
+#define BOOT_FLOW_CONDITION_OEM_KEY2 0x00001002
+#define BOOT_FLOW_CONDITION_OEM_KEY3 0x00001003
+#define BOOT_FLOW_CONDITION_OEM_KEY4 0x00001004
+#define BOOT_FLOW_CONDITION_OEM_KEY_CALLBACK 0x00001005
+#define BOOT_FLOW_CONDITION_NO_SETUP 5
+#define BOOT_FLOW_CONDITION_BBS_POPUP 6
+#define BOOT_FLOW_CONDITION_FAST_BOOT 7
+#define BOOT_FLOW_CONDITION_PCI_OUT_OF_RESOURCE 9
+#define BOOT_FLOW_HOTKEY_BOOT 0xA
+#define BOOT_FLOW_CONDITION_OS_UPD_CAP 0xB //EIP93521
+#define BOOT_FLOW_CONDITION_NULL 0xFFFFFFFF
+
+typedef struct _BOOT_FLOW BOOT_FLOW;
+
+typedef EFI_STATUS (*BOOT_FLOW_CALLBACK)( BOOT_FLOW * );
+
+struct _BOOT_FLOW
+{
+ UINT32 Condition;
+ UINT16 PageClass;
+ UINT16 PageSubClass;
+ UINT16 PageFormID;
+ UINT32 ControlNumber;
+ UINT16 MessageBoxToken;
+ UINT16 MessageBoxTimeout;
+ BOOLEAN GotoPageOnEntry;
+ BOOLEAN ProceedBooting;
+ BOOLEAN InfiniteLoop;
+ BOOLEAN LaunchShell;
+ BOOLEAN DoNotEnterSetup;
+ BOOT_FLOW_CALLBACK CallbackFunction;
+};
+
+EFI_STATUS BootFlowManageEntry( VOID );
+EFI_STATUS BootFlowManageExit( VOID );
+VOID _BootFlowShowMessageBox( BOOT_FLOW *bootFlowPtr );
+VOID _BootFlowSetActivePage( BOOT_FLOW *bootFlowPtr );
+VOID _BootFlowSetActiveControl( BOOT_FLOW *bootFlowPtr );
+
+EFI_STATUS OemKey1Hook ( BOOT_FLOW * );
+EFI_STATUS OemKey2Hook ( BOOT_FLOW * );
+EFI_STATUS OemKey3Hook ( BOOT_FLOW * );
+EFI_STATUS OemKey4Hook ( BOOT_FLOW * );
+EFI_STATUS DoPopup( BOOT_FLOW * );
+//EFI_STATUS DoPopupMenu( BOOT_FLOW * );
+//EFI_STATUS DoBootOnlyPopupMenu( BOOT_FLOW * );
+EFI_STATUS FBBootFlow (BOOT_FLOW *);
+EFI_STATUS LaunchHotKeyBootOption (BOOT_FLOW *);
+EFI_STATUS OsUpdateCapsuleWrap (BOOT_FLOW *BootFlow);
+
+#endif /* _BOOTFLOW_H_ */
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMITSE/changelog.log b/Core/EM/AMITSE/changelog.log
new file mode 100644
index 0000000..b4ce53f
--- /dev/null
+++ b/Core/EM/AMITSE/changelog.log
@@ -0,0 +1,1269 @@
+$/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+
+[TAG] EIP65320
+[Category] Improvement
+[Description] Board module hook for LoadImage failure.
+ OVERRIDE_UefiBootFailHook token added.
+[Files] amitse.sdl, commonhelper.c and boot.c
+
+[Files] AMITSE.sdl
+Minor version incremented for 2.14.1219 QA build
+
+[Files] AMITSE.sdl
+[TAG] EIP60910
+[Category] New Feature
+[Description] PNG image support in TSE.
+[Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c, png.h, pnguncmp.c, TseAdvanced.cif
+
+[Files] AMITSE.mak
+Copyright version updated to 2011
+
+[Files] AMITSE.mak
+Updated for 2.14.1219 internal release.
+
+[Files] AMITSE.chm
+[TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS setup.
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl, Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h, EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif, EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl, Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl, TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h, CommonHelper.c
+
+[Files] commonoem.h
+Removed the unwanted code for mouse hot click operation
+
+[TAG] EIP 63262
+[Category] Defect
+[Symptom] Setup page display problem on rose city.When SETUP_GROUP_DYNAMIC_PAGES is enabled and Network Stack is enabled, the "iSCSI" menu is listed as a dynamic page in advanced menu but only 3 of 4 "Port Configuration" pages shows up. The TSE dynamic page count is incorrect.
+[Solution] In the functions (RTIfrProcessRunTimeForms, HandleNewIFRPack, HandleRemoveIFRPack, HandleAddIFRPack), make sure the nvram cache is updated by callingVarUpdateVariable(VARIABLE_ID_DYNAMIC_PAGE_COUNT) when updating "DynamicPageCount" variable name. .
+[Files] Hii.c, Minisetup.h, Variable.h
+
+[TAG] EIP57661
+[Category] New Feature
+[Description] Drv health related variable declarations added to update the cache.
+[Files] notify.c, Uefi21Wapper.c and variable.h
+
+[TAG] EIP65320
+[Category] Improvement
+[Description] Board module hook for LoadImage failure
+[Files] amitse.sdl, commonhelper.c and boot.c
+
+[Files] CommonHelper.c
+Removed the unwanted function for mouse hot click operation
+
+[TAG] EIP62098
+[Description] HOTCLICK_FULLSCREEN_SUPPORT token added to disable the mouse hot click operations.
+[Files] Ezport\EzportBin.sdl
+
+[TAG] EIP62098
+[Description] NULL entry added in gHotClickInfo array in hotclickbin.c file so removed the NULL entry here.
+[Files] Ezport\EzportBin.sdl
+
+[Files] Ezport\EzportBin.sdl
+Updated with correct co-ordinates for helpframe hotclick with mouse
+
+[TAG] EIP62098
+[Description] NULL entry added in gHotClickInfo array for handling HOTCLICK_FULLSCREEN_SUPPORT=0.
+[Files] Ezport\HotclickBin.c and Legacy\HotclickBin.c
+
+[TAG] EIP62098
+[Description] HOTCLICK_FULLSCREEN_SUPPORT token added to disable the mouse hot click operations.
+[Files] Legacy\LegacyBin.sdl
+
+[TAG] EIP62098
+[Description] HOTCLICK_FULLSCREEN_SUPPORT token added for disabling mouse hot click operations.
+[Files] EzportPlus\EzportPlusBin.sdl
+
+[TAG] EIP62098
+[Description] NULL entry added in gHotClickInfo array for handling HOTCLICK_FULLSCREEN_SUPPORT=0
+[Files] EzportPlus\HotclickBin.c
+
+
+***************** TSEStyleLegacyx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 7:48p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TSEStyleLegacy.lib *****************
+User: Arunsb Date: 6/30/11 Time: 7:47p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** Uefi20Localx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 7:47p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/uefi2.0
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** Uefi20Local.lib *****************
+User: Arunsb Date: 6/30/11 Time: 7:47p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/uefi2.0
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseStyleEzportPlusx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:59p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseStyleEzportPlus.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:58p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseStylex64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:58p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseStyle.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:57p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** Uefi21Localx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:57p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Uefi2.1
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** Uefi21Local.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:56p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Uefi2.1
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseLiteLocalx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:56p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseLite
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseLiteLocal.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:55p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseLite
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** MiniSetupLocalx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:54p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** MiniSetupLocal.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:54p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseAdvancedx64.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:53p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseAdvanced
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** TseAdvanced.lib *****************
+User: Arunsb Date: 6/30/11 Time: 6:53p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseAdvanced
+Comment:
+ Updated for 2.14.1218 internal release.
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/30/11 Time: 1:01p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ HONOR_DRVHLTH_CONFIGREQD_ON_BOOTFAIL token defaultly disabled.
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/30/11 Time: 11:52a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ EDKVersion_1_05_RetrieveData wrapper function added to return the
+EDK_1_05_RETRIEVE_DATA token value.
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/30/11 Time: 11:51a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ EDK_1_05_RETRIEVE_DATA token added and it is removed from
+uefi21.sdl.
+Minor version and build version incremented for 2.14.1218 release
+
+***************** EzportPlusBin.sdl *****************
+User: Rajashakerg Date: 6/30/11 Time: 5:09a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ Removed extra TABs
+
+***************** AMITSE.cif *****************
+User: Arunsb Date: 6/30/11 Time: 4:10a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ TseDrvHealth.h file added.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** hiistring20.c *****************
+User: Arunsb Date: 6/30/11 Time: 4:09a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+
+
+***************** hiistring21.c *****************
+User: Arunsb Date: 6/30/11 Time: 4:08a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Boot device repair operation related functions added.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** MiniSetupBin.mak *****************
+User: Arunsb Date: 6/30/11 Time: 4:07a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Include directories added.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** AMIVfr.h *****************
+User: Arunsb Date: 6/30/11 Time: 4:06a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Include
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Added driver health structures for vfr.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** Version 64 *****************
+User: Arunsb Date: 6/30/11 Time: 4:04a
+Added TseDrvHealth.h
+
+***************** Uefisetup.ini *****************
+User: Arunsb Date: 6/30/11 Time: 4:01a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Driver health related variables and guids added.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/30/11 Time: 4:00a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Wrapper functions added.
+ Added board module hook to perform rebooting the system.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** AmiTSEStr.uni *****************
+User: Arunsb Date: 6/30/11 Time: 3:58a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Driver health related strings added.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** FakeTokens.c *****************
+User: Arunsb Date: 6/30/11 Time: 3:57a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+ Driver health related string tokens added.
+[Files] amitse.cif, amitse.sdl, faketokens.c, amitsestr.uni,
+ commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h,
+minisetupbin.mak,
+ hiistring21.c, hiistring20.c, tseadvanced.c, special.c,
+special.h, boot.h, minisetup.h,
+ uefi20wapper.c, formbrowser2.c, hii.c, parse.c and
+uefi21wapper.c.
+
+***************** commonoem.c *****************
+User: Arunsb Date: 6/30/11 Time: 3:55a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ Unused BootOption variable removed.
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/30/11 Time: 3:54a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57661
+[Category] New Feature
+[Description] Boot manager algorithm for interaction with Driver Health
+protocol.
+The following tokens added
+DRIVER_HEALTH_SUPPORT
+HONOR_DRVHLTH_CONFIGREQD_ON_BOOTFAIL
+OVERRIDE_DriverHealthSystemReset
+[Files] amitse.cif, amitse.sdl, commonoem.c, faketokens.c, amitsestr.uni,
+commonhelper.c, uefisetup.ini, tsedrvhealth.h, amivfr.h, minisetupbin.mak,
+hiistring21.c, hiistring20.c, tseadvanced.c, special.c, special.h, boot.h,
+minisetup.h, uefi20wapper.c, formbrowser2.c,
+hii.c, parse.c and uefi21wapper.c.
+
+***************** CommonHelper.c *****************
+User: Rajashakerg Date: 6/29/11 Time: 4:35p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ Updated for Help frame scroll changes
+
+***************** commonoem.c *****************
+User: Arunsb Date: 6/29/11 Time: 2:06p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ EIP 62631 gHotKeyBootOption declaration moved to commonhelper.c
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/29/11 Time: 2:01p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ gHotKeyBootOption declaration added and the same is removed in
+commonoem.c file.
+
+***************** CommonHelper.c *****************
+User: Rajashakerg Date: 6/29/11 Time: 1:32p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** commonoem.h *****************
+User: Rajashakerg Date: 6/29/11 Time: 1:03p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** TseLiteBin.sdl *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:59p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseLite
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** LegacyBin.mak *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:46p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** LegacyBin.sdl *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** EzportPlusBin.mak *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:39p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** EzportPlusBin.sdl *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:38p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** EzportBin.mak *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:30p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** EzportBin.sdl *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:29p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+ [TAG] EIP47086
+[Category] New Feature
+[Description] Right clicking from the Main page is not exiting from BIOS
+setup.
+
+[Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif, EzportPlus\style.h,
+EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak, EzportPlus\EzportPlusBin.cif,
+EzportPlus\ezportplus.c, Legacy\style.h, Legacy\EzportPlusBin.sdl,
+Legacy\LegacyBin.mak, Legacy\LegacyBin.cif, Legacy\legacy.c, TseLiteBin.sdl,
+TseLite.cif, Memo.c, frame.c, application.h, application.c, commonoem.h,
+CommonHelper.c
+
+***************** LegacyBin.cif *****************
+User: Rajashakerg Date: 6/29/11 Time: 12:00p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+
+
+***************** Legacy *****************
+User: Rajashakerg Date: 6/29/11 Time: 11:58a
+Added HotclickBin.c
+
+***************** Legacy *****************
+User: Rajashakerg Date: 6/29/11 Time: 11:58a
+Added HotclickBin.h
+
+***************** EzportPlusBin.cif *****************
+User: Rajashakerg Date: 6/29/11 Time: 11:54a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+
+
+***************** EzportPlus *****************
+User: Rajashakerg Date: 6/29/11 Time: 11:52a
+Added HotclickBin.c
+
+***************** EzportPlus *****************
+User: Rajashakerg Date: 6/29/11 Time: 11:52a
+Added HotclickBin.h
+
+***************** EzportBin.cif *****************
+User: Rajashakerg Date: 6/29/11 Time: 11:47a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+
+
+***************** hiistring21.c *****************
+User: Arunsb Date: 6/29/11 Time: 6:24a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option support in TSE as per UEFI spec. section
+3.1.6.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c.
+
+***************** hiistring20.c *****************
+User: Arunsb Date: 6/29/11 Time: 6:17a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option support in TSE as per UEFI spec. section
+3.1.6.
+ Dummy functions added.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c.
+
+***************** commonoem.c *****************
+User: Arunsb Date: 6/29/11 Time: 6:03a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option support in TSE as per UEFI spec. section
+3.1.6.
+ CheckAdvShiftState function moved from commonoem.c to here.
+ BootLaunchBootOption removed in checkforkey function to avoid
+TPL problem.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c.
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/29/11 Time: 5:50a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option support in TSE as per UEFI spec. section
+3.1.6.
+ CheckAdvShiftState function moved from commonoem.c to here.
+ LaunchHotKeyBootOption function added to launch hot key boot
+device.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c.
+
+***************** bootflow.c *****************
+User: Arunsb Date: 6/29/11 Time: 5:37a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option support in TSE as per UEFI spec. section
+3.1.6.
+ Added BOOT_FLOW_HOTKEY_BOOT bootflow option in BOOT_FLOW.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c.
+
+***************** bootflow.h *****************
+User: Arunsb Date: 6/29/11 Time: 5:25a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option support in TSE as per UEFI spec. section
+3.1.6.
+ Added BOOT_FLOW_HOTKEY_BOOT bootflow option for honoring the hot
+key boot.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c.
+
+***************** Ezport *****************
+User: Rajashakerg Date: 6/29/11 Time: 5:18a
+Added HotclickBin.c
+
+***************** Ezport *****************
+User: Rajashakerg Date: 6/29/11 Time: 5:18a
+Added HotclickBin.h
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/28/11 Time: 8:19p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option in TSE as per UEFI spec. section 3.1.6.
+ OVERRIDE_LaunchHotKeyBootOption function added for hot key boot
+option.
+[Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c, commonoem.c,
+commonoem.h, boot.c,
+ hiistring20.c, hiistring21.c and notify.c
+
+***************** commonoem.c *****************
+User: Arunsb Date: 6/23/11 Time: 8:29p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP62466
+[Category] Improvement
+[Description] Trace message support in commonoem.c.
+Included amidxelib.h file.
+[Files] commonoem.c
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/23/11 Time: 8:02p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ Removed the unwanted tokens
+
+***************** bootflow.c *****************
+User: Arunsb Date: 6/23/11 Time: 7:41p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+ specification v 2.3.1, p. 3.4.1.
+ Checks for the setup key if no boot options avail
+ or not succedded to boot. If setup key pressed launches the
+setup.
+ If no boot option avail then inserting thumb drive with image
+efi\boot\bootxxxx.efi TSE will launch that image.
+[Files] amitse.sdl, bootflow.c and protocol.c
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/23/11 Time: 7:40p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+
+
+***************** AMITSE.sdl *****************
+User: Rajashakerg Date: 6/23/11 Time: 3:40p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP55762, 58925, 59971
+[Category] New Feature
+[Description] Support REF2,REF3 and REF4 in AMITSE
+Support direct form navigation path
+Improper layout of controls in the root page when Dynamic pages are added using
+the Legacy Setup Style
+
+[Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c,
+Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, minisetupext.h,
+numeric.c, page.c Popupstring.c, Hii.c, Uefi21Wrapper.c, Parse.c Hii.c
+
+***************** CommonHelper.c *****************
+User: Rajashakerg Date: 6/23/11 Time: 3:39p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP55762, 58925, 59971
+[Category] New Feature
+[Description] Support REF2,REF3 and REF4 in AMITSE
+Support direct form navigation path
+Improper layout of controls in the root page when Dynamic pages are added using
+the Legacy Setup Style
+[Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c,
+Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, minisetupext.h,
+numeric.c, page.c Popupstring.c, Hii.c, Uefi21Wrapper.c, Parse.c Hii.c
+
+***************** setupdata.h *****************
+User: Rajashakerg Date: 6/23/11 Time: 3:38p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc
+Comment:
+ [TAG] EIP55762, 58925, 59971
+[Category] New Feature
+[Description] Support REF2,REF3 and REF4 in AMITSE
+Support direct form navigation path
+Improper layout of controls in the root page when Dynamic pages are added using
+the Legacy Setup Style
+[Files] setupdata.h, CommonHelper.c, AMITSE.sdl, Legacy\Legacy.c,
+Legacy\style.h, Legacy\style.h, frame.c, minisetupext.c, minisetupext.h,
+numeric.c, page.c Popupstring.c, Hii.c, Uefi21Wrapper.c, Parse.c Hii.c
+
+***************** CommonHelper.c *****************
+User: Rajashakerg Date: 6/23/11 Time: 5:30a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP63073
+[Category] New Feature
+[Description] Source modules in TSE should get the version details from binary
+in run time not at build time
+[Files] CommonHelper.c, minisetupext.c, notify.c, Ezport\style.c,
+EzportPlus\style.c, Legacy\style.c
+
+***************** hiistring21.c *****************
+User: Arunsb Date: 6/22/11 Time: 2:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Support for Hot key boot option in TSE as per UEFI spec. section
+3.1.6.
+[Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h, boot.c,
+hiistring20.c and hiistring21.c.
+
+***************** hiistring20.c *****************
+User: Arunsb Date: 6/22/11 Time: 2:21p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ [TAG] EIP 62631
+[Category] New Feature
+[Description] Hot key boot option in TSE as per UEFI spec. section 3.1.6.
+ Dummy FormHotBootKeys function added
+[Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h, boot.c,
+hiistring20.c and hiistring21.c.
+
+***************** LogoLib.h *****************
+User: Premkumara Date: 6/22/11 Time: 9:17a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc
+Comment:
+ [TAG] EIP60048
+[Category] Improvement
+[Description] TSE should Change the System Resolution according to the Quite
+Logo Size
+[Files] CommonHelper.c, AMITSE.sdl, Logo.c, LogoLib.h
+
+***************** AMITSE.sdl *****************
+User: Premkumara Date: 6/22/11 Time: 9:13a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP60048
+[Category] Improvement
+[Description] TSE should Change the System Resolution according to the Quite
+Logo Size
+[Files] CommonHelper.c, AMITSE.sdl, Logo.c, LogoLib.h
+
+***************** CommonHelper.c *****************
+User: Premkumara Date: 6/22/11 Time: 9:08a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP60048
+[Category] Improvement
+[Description] TSE should Change the System Resolution according to the Quite
+Logo Size
+[Files] CommonHelper.c, AMITSE.sdl, Logo.c, LogoLib.h
+
+***************** commonoem.h *****************
+User: Arunsb Date: 6/22/11 Time: 7:18a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631, 60128
+[Category] New Feature
+[Description] Hot key boot option in TSE as per UEFI spec. section 3.1.6.
+ TSE_CHECK_SHIFTSTATE macro redefined to CheckAdvShiftState
+[Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h, boot.c,
+hiistring20.c and hiistring21.c.
+
+***************** commonoem.c *****************
+User: Arunsb Date: 6/22/11 Time: 7:10a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP 62631, 60128
+[Category] New Feature
+[Description] Hot key boot option in TSE as per UEFI spec. section 3.1.6.
+ Hot key checked.
+ CheckAdvShiftState function added to handle special case like
+Ctrl+Alt+F6.
+ TSE_CHECK_SHIFTSTATE added for checking special key to launch
+setup.
+[Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h, boot.c,
+hiistring20.c and hiistring21.c.
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/22/11 Time: 6:54a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP62631
+[Category] New Feature
+[Description] Hot key boot option in TSE as per UEFI spec. section 3.1.6
+[Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h,
+boot.c, hiistring20.c and hiistring21.c.
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/22/11 Time: 6:49a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP62631
+[Category] New Feature
+[Description] Hot key boot option in TSE as per UEFI spec. section 3.1.6
+[Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h, boot.c,
+hiistring20.c and hiistring21.c.
+
+***************** commonoem.c *****************
+User: Arunsb Date: 6/20/11 Time: 3:50p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1.
+ Added CheckForSetupKey function to check setup key
+pressed.
+[Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c, boot.c and
+protocol.c
+
+***************** bootflow.h *****************
+User: Arunsb Date: 6/20/11 Time: 3:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1.
+[Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c, boot.c and
+protocol.c
+
+***************** bootflow.c *****************
+User: Arunsb Date: 6/20/11 Time: 3:43p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1.
+ If BOOT_FLOW's LaunchShell param sets to
+BOOTFLOW_EXIT_LAUNCH_DEFAULT_BOOTIMAGE then TSE tries to load the
+ efi/boot/bootxxxx.efi from any of the file system.
+ If BOOT_FLOW's InfiniteLoop param sets to
+BOOTFLOW_EXIT_INFINITE_LOOP_LAUNCH_SETUP then TSE tried to enter the setup
+ if no boot option present or succeeded to boot. Enters to setup
+only when setup key detected after boot options failure occurs.
+[Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c, boot.c and
+protocol.c
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/20/11 Time: 3:37p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1
+[Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c, boot.c and
+protocol.c
+
+***************** CommonHelper.c *****************
+User: Rajashakerg Date: 6/20/11 Time: 11:41a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP59417
+[Category] New Feature
+[Description] Spport LOAD_OPTION_HIDDEN option in TSE
+[Files] boot.h, AMITSE.sdl, CommonHelper.c, bbs.c, boot.c, minisetup.h,
+special.c, callback.c
+
+***************** AMITSE.sdl *****************
+User: Rajashakerg Date: 6/20/11 Time: 11:39a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP59417
+[Category] New Feature
+[Description] Spport LOAD_OPTION_HIDDEN option in TSE
+[Files] boot.h, AMITSE.sdl, CommonHelper.c, bbs.c, boot.c, minisetup.h,
+special.c, callback.c
+
+***************** boot.h *****************
+User: Rajashakerg Date: 6/20/11 Time: 11:38a
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc
+Comment:
+ [TAG] EIP59417
+[Category] New Feature
+[Description] Spport LOAD_OPTION_HIDDEN option in TSE
+[Files] boot.h, AMITSE.sdl, CommonHelper.c, bbs.c, boot.c, minisetup.h,
+special.c, callback.c
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/19/11 Time: 4:13p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP58712
+[Category] New Feature
+[Description] To disable the BIOS Signon Message and TSE copyright version in
+post screen.
+[Files] amitse.sdl, amitse.mak, commonhelper.c and notify.c
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/19/11 Time: 4:10p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP58712
+[Category] New Feature
+[Description] To disable the BIOS Signon Message and TSE copyright version in
+post screen.
+[Files] amitse.sdl, amitse.mak, commonhelper.c and notify.c
+
+***************** AMITSE.mak *****************
+User: Arunsb Date: 6/19/11 Time: 4:07p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP58712
+[Category] New Feature
+[Description] To disable the BIOS Signon Message and TSE copyright version in
+post screen.
+[Files] amitse.sdl, amitse.mak, commonhelper.c and notify.c
+
+***************** UefiHpkTool.exe *****************
+User: Arunsb Date: 6/15/11 Time: 4:49p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP61650
+[Category] Bug Fix
+[Severity] Minor
+[Symptom] Cannot edit time field when using new "time" format
+[RootCause] Default refresh interval set to all the time variables
+[Solution] Default refresh interval provided only for RTC time variable
+[Files] time.c, date.c, parse.c and uefihpktool.exe
+
+***************** CommonHelper.c *****************
+User: Rajashakerg Date: 6/13/11 Time: 12:37p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP60910
+[Category] New Feature
+[Description] PNG image support in TSE.
+[Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c, png.h,
+pnguncmp.c, TseAdvanced.cif
+
+***************** AMITSE.sdl *****************
+User: Rajashakerg Date: 6/13/11 Time: 12:36p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP60910
+[Category] New Feature
+[Description] PNG image support in TSE.
+[Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c, png.h,
+pnguncmp.c, TseAdvanced.cif
+
+***************** LogoLib.h *****************
+User: Rajashakerg Date: 6/13/11 Time: 12:29p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Inc
+Comment:
+ [TAG] EIP60910
+[Category] New Feature
+[Description] PNG image support in TSE.
+[Files] LogoLib.h, AMITSE.sdl, CommonHelper.c, logo.c, png.c, png.h,
+pnguncmp.c, TseAdvanced.cif
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/10/11 Time: 2:40p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1.2
+[Files] boot.c, bootflow.c and bootflow.h
+
+***************** bootflow.h *****************
+User: Arunsb Date: 6/10/11 Time: 2:39p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1.2
+[Files] boot.c, bootflow.c and bootflow.h
+
+***************** bootflow.c *****************
+User: Arunsb Date: 6/10/11 Time: 2:38p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57660
+[Category] New Feature
+[Description] Non-removable media boot behavior as described in UEFI
+specification v 2.3.1, p. 3.4.1.2
+[Files] boot.c, bootflow.c and bootflow.h
+
+***************** bootflow.h *****************
+User: Arunsb Date: 6/08/11 Time: 11:38p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57650
+[Category] New Feature
+[Description] Support in TSE Out of resources boot flow option.
+[Files] bootflow.c and bootflow.h
+
+***************** bootflow.c *****************
+User: Arunsb Date: 6/08/11 Time: 11:38p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP57650
+[Category] New Feature
+[Description] Support in TSE Out of resources boot flow option.
+[Files] bootflow.c and bootflow.h
+
+***************** Version 63 *****************
+Label: (INT)4.6.2_TSE_2_13_1217
+User: Arunsb Date: 6/04/11 Time: 6:00p
+Labeled '(INT)4.6.2_TSE_2_13_1217'
+Label comment:
+ [SS Server] alaska
+[SS Path] $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+[Label] (INT)4.6.2_TSE_2_13_1217
+[Module Name] TSE Binary
+[Description]
+Release to QA cycle 2.
+*) Fix for dynamic update for the goto control to same target page.
+*) Fix for boot override hangs with exception 0x0d.
+*) BGRT table will be formed only for quiet boot logos. BGRT status field will
+be cleared when some changes happened in screen other than displaying the image.
+
+[Entries]
+New Features:
+=============
+
+[TAG] EIP58954
+[Category] New Feature
+[Description] Quiet boot logos only added for BGRT. BGRT status field cleared
+if any changes happened in screen other than displaying the images. BltBuffer
+freed in ConvertBlt2Bmp function.
+[Files] Postmgmt.c, boot.c, logo.c commonoem.c and commonhelper.c
+
+
+General Bug Fixes:
+===================
+
+[TAG] EIP61588
+[Category] Bug Fix
+[Severity] Important
+[Symptom] Advanced -> ISCSI -> Add an attempt-> Mac Address -> Save
+changes causes the system to hang.
+[RootCause] Dynamic update for the goto control to same target page was not
+updated correctly.
+[Solution] Fixed to update the control destination page correctly.
+[Files] parse.c and special.c
+
+[TAG] EIP48930
+[Description] Boot override hangs with exception 0x0d
+[Files] Parse.c and hii.c
+
+***************** TseStyleEzportPlusx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:46p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseStyleEzportPlus.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:46p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/EzportPlus
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TSEStyleLegacyx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TSEStyleLegacy.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Legacy
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseStylex64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseStyle.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:45p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Ezport
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** Uefi21Localx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:44p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Uefi2.1
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** Uefi21Local.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:44p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/Uefi2.1
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** Uefi20Localx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:44p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/uefi2.0
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** Uefi20Local.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:43p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/uefi2.0
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseLiteLocalx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:42p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseLite
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseLiteLocal.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:42p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseLite
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** MiniSetupLocalx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:42p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** MiniSetupLocal.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:41p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/BootOnly
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseAdvancedx64.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:41p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseAdvanced
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** TseAdvanced.lib *****************
+User: Arunsb Date: 6/04/11 Time: 4:40p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE/TseAdvanced
+Comment:
+ Updated for 2.13.1217 internal release
+
+***************** AMITSE.chm *****************
+User: Arunsb Date: 6/04/11 Time: 4:06p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ 2.13.1217 release notes updated
+
+***************** AMITSE.sdl *****************
+User: Arunsb Date: 6/04/11 Time: 1:55p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ Build version incremented for 2.13.1217 internal release
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 6/04/11 Time: 1:54p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP58954
+[Category] New Feature
+[Description] Wrapper function added for InvalidateStatusInBgrt function.
+[Files] Postmgmt.c, boot.c, logo.c commonoem.c and
+ commonhelper.c
+
+***************** CommonHelper.c *****************
+User: Arunsb Date: 5/29/11 Time: 12:02p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP58954
+[Category] New Feature
+[Description] Quiet boot logo's only added for BGRT. BGRT status field cleared
+if any changes happened in screen other than displaying the image.
+[Files] Postmgmt.c, boot.c, logo.c commonoem.c and commonhelper.c
+
+***************** commonoem.c *****************
+User: Arunsb Date: 5/29/11 Time: 12:01p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMITSE
+Comment:
+ [TAG] EIP58954
+[Category] New Feature
+[Description] Quiet boot logo's only added for BGRT. BGRT status field cleared
+if any changes happened in screen other than displaying the image.
+[Files] Postmgmt.c, boot.c, logo.c commonoem.c and commonhelper.c
+
+***************** TseLiteLocalx64.lib *****************
+User: Arunsb Date: 5/17/11 Time: 7:18p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMIGTSE/TseLite
+Comment:
+ Updated for GTSE 2.13.1216 release.
+
+***************** TseLiteLocal.lib *****************
+User: Arunsb Date: 5/17/11 Time: 7:16p
+Checked in $/Alaska/BIN/Modules/AMITSE2_0/AMIGTSE/TseLite
+Comment:
+ Updated for GTSE 2.13.1216 release.
+
diff --git a/Core/EM/AMITSE/commonoem.c b/Core/EM/AMITSE/commonoem.c
new file mode 100644
index 0000000..cdc4d35
--- /dev/null
+++ b/Core/EM/AMITSE/commonoem.c
@@ -0,0 +1,2654 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/em/AMITSE/commonoem.c $
+//
+// $Author: Chienhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 7/08/15 4:29a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/em/AMITSE/commonoem.c $
+//
+// 1 7/08/15 4:29a Chienhsieh
+// Update rev66
+//
+// 66 4/22/15 8:22a Omkark
+// [TAG] EIP201836
+// [Category] Bug Fix
+// [Severity:] Normal
+// [Symptom:] ARM systems generate exception after 3 invalid password
+// tries in the POST
+// [Root Cause] Parameters are not used properly for WaitForEvent function
+// during POST password.
+// [Solution] Handled parameters for WaitForEvent() function.
+// [Files] commonoem.c
+//
+// 62 8/28/14 12:02p Premkumara
+// [TAG] EIP174154
+// [Category] Bug Fix
+// [Severity:] Normal
+// [Symptom:] TMM Settings page is moved to wrong position
+// [Solution] If root page ordering is not present for some of the boot
+// flows then menu ordering will not present.
+// So for the boot flows which doesn't has ordering now
+// BOOT_FLOW_CONDITION_NORMAL ordering will be applied.
+// [Files] commonoem.c
+//
+// 61 8/28/14 10:09a Premkumara
+// [TAG] EIP174031
+// [Category] Improvement
+// [Description] Removed TODO comments and added proper comments in those
+// places
+// [Files] commonoem.c, commonhelper.c, special.c, submenu.c,
+// minisetupext.c, uefi21wapper.c and legacy.c
+//
+// 60 5/21/14 6:23p Arunsb
+// [TAG] EIPEIP169096,168632
+// [Description] Changed global variable guid usage for tse debug messages
+// [Files] commonoem.c, setupdbg.h and print.c
+//
+// 59 5/08/14 4:25p Arunsb
+// [TAG] EIP162197
+// [Category] Improvement
+// [Description] Password encode feature modify to encode using Hashing
+// based on token.
+// PasswordEncode function moved to PasswordEncode module.
+//
+// 58 5/02/14 2:10p Premkumara
+// [TAG] EIP140123
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] While showing secureboot error msg mouse is not move and
+// get hang. Softkbd is displaying
+// [RootCause] MouseClickEvent is not stopped while boot to any option.
+// So clicking outside msg box causes displaying
+// softkbd and mouse is not init at this phase.
+// [Solution] Initialized mouse and deactivating any softkbd activated
+// before showing secureboot error msg box.
+// [Files] CommonHelper.c, CommonOem.c, MessageBox.c
+//
+// 57 5/02/14 5:44a Arunsb
+// [TAG] EIP156258
+// [Category] Improvement
+// [Description] Providing ELINK option to suppress the handle
+// comparison on dynamic parsing
+// [Files] AMITSE.mak, AMITSE.sdl, commonoem.c, commonoem.h and Parse.c
+//
+// 56 5/02/14 4:41a Premkumara
+// [TAG] EIP95647
+// [Category] Improvement
+// [Description] Dynamic Forms need to hide.
+// [Files] AMITSE.mak, AMITSE.sdl, CommonOem.c, Parse.c
+//
+// 55 2/11/14 10:52p Arunsb
+// Build error rectified for EFI_STRING_ID
+//
+// 54 12/04/13 5:17a Premkumara
+// [TAG] EIP123535
+// [Category] Improvement
+// [Description] Moved saving quietboot resolution to DrawQuietBootLogo()
+// to avoid setting resolution of initPostScreenthis while booting.
+// [Files] commonoem.c, Boot.c, Logo.c, MinisetupExt.c
+//
+// 53 12/04/13 2:58a Premkumara
+// [TAG] EIP139099
+// [Category] New Feature
+// [Description] Supress formset other than
+// EFI_HII_PLATFORM_SETUP_FORMSET_GUID and
+// EFI_HII_DRIVER_HEALTH_FORMSET_GUID through elink based on token
+// [Files] AMITSE.sdl, AMITSE.mak, CommonOem.c, Hii.c, Parse.c,
+// TseUefiHii.h
+//
+// 52 5/22/13 10:13a Arunsb
+// Moving password encoding to source
+//
+// 51 4/18/13 1:47a Arunsb
+// [TAG] EIP81490
+// [Category] New Feature
+// [Description] Post message support for BBS popup menu
+// [Files] AMITSE.sdl, AmiTSEStr.uni, commonoem.c, FakeTokens.c and
+// globals.c
+//
+// 50 3/18/13 2:04p Blaines
+// [TAG] - EIP 118410
+// [Category] - Defect
+// [Symptom] - Hidden tabs when dynamic pages are present in setup.
+// [Description] - Setup is missing tabs (i.e. Security, Boot, Exit), when
+// pages are dynamically added to Advanced menu.
+// This has been seen with both SAS and Network UEFI drivers that
+// dynamically publish setup pages.
+//
+// [Root cause]
+// The functions FixSubPageAsRootPageList and FixHiddenPageList will
+// typecast gPages->PageCount to UINT8 in the for-loop to search the page
+// data.
+// The masking of this count value will affect the parsing of
+// AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST, and AMITSE_ROOT_PAGE_ORDER.
+//
+// [Solution]- Use UINTN to typecast gPages->PageCount in the for-loop
+// used to search the page data.
+//
+// [Files]
+// - commonoem.c
+//
+// [Functions]
+// - FixSubPageAsRootPageList
+// - FixHiddenPageList
+//
+// 49 3/06/13 12:23a Premkumara
+// [TAG] EIP111415
+// [Category] Improvement
+// [Description] Elink function for SETUP_TOGGLE_KEY_UNICODE function
+// [Files] HookAnchor.h, AMITSE.sdl, commonoem.c, Commonoem.h,
+// HookList.c, HookAnchor.c
+//
+// 48 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 30 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 46 9/25/12 12:26p Rajashakerg
+// [TAG] EIP92053
+// [Category] Improvement
+// [Description] Need support define Root page order using elinks
+// [Files] AMITSE.sdl, Menu.c, AMIVfr.h, AMITSE.mak, commonoem.c
+//
+// 45 9/25/12 9:27a Rajashakerg
+// [TAG] EIP92053
+// [Category] Improvement
+// [Description] Need support define Root page order using elinks
+// [Files] AMITSE.sdl, Menu.c, AMIVfr.h, AMITSE.mak, commonoem.c
+//
+// 44 9/21/12 7:27a Premkumara
+// [TAG] EIP 90647
+// [Category] Improvement
+// [Description] Implement new token to launch Boot Menu using shift
+// state key such as CTRL+F7
+// [Files] AMITSE.sdl, Commonoem.c
+//
+// 43 9/17/12 5:59a Rajashakerg
+// Updated EIP changes for 2.16 release.
+//
+// 41 8/29/12 4:11p Arunsb
+// [TAG] EIP94702
+// [Description] Support for Native Resolution in POST/BOOT
+// [Files] amitse.sdl, commonhelper.c, commonoem.c, boot.c, logo.c,
+// notify.c, postmgmt.c, tselite\minisetupext.c, ezport/stylecommon.c,
+// ezportplus/stylecommon.c andlegacy/stylecommon.c
+//
+// 40 5/29/12 3:18a Arunsb
+// [TAG] EIP91109
+// [Category] Improvement
+// [Description] Sync the Aptio IV source for AptioV
+//
+// 39 5/09/12 5:25p Arunsb
+// [TAG] EIP85768
+// [Category] Improvement
+// [Description] Combination key does not work properly for checkoemkey
+// functionality
+// [Files] commonoem.c
+//
+// 38 4/27/12 2:05p Arunsb
+// Build error rectified
+//
+// 37 4/27/12 11:18a Arunsb
+// [TAG] EIP85904
+// [Category] New Feature
+// [Description] OS indication support
+// [Files] Amitse.sdl and commonoem.c
+//
+// 36 4/27/12 9:44a Arunsb
+// [TAG] EIP84199
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ProcessConInAvailability displays "Press <F2> or <DEL> to
+// enter Setup." message on the POST screen as many times as it is hooked.
+// [RootCause] ProcessConInAvailability called twice
+// [Solution] Messages displayed only once regardless of number of times
+// ProcessConInAvailability hook get called
+// [Files] commonoem.c
+//
+// 35 4/04/12 12:24a Rajashakerg
+// [TAG] EIP86253
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse and SoftKbd does not work after displaying "No option
+// to boot to" in POST
+// [RootCause] Mouse timer cleared once after displaying the "No option
+// to boot to" in POST
+// [Solution] Mouse timer cleared only when its going to boot.
+// [Files] CommonHelper.c, commonoem.c, minisetupext.c, protocol.c
+//
+// 34 2/03/12 9:29p Madhans
+// [TAG] EIP82552
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Soft Keyboard is On after booted to BIOS setup from POST
+// [RootCause] Soft Keyboard is not deactivated for time out in post
+// [Solution] Soft keyboard deactivated for time out too
+// [Files] commonoem.c
+//
+// 33 2/02/12 1:21a Arunsb
+// [TAG] EIP81959
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Stop at LOGO if continue to press one of Shift / Alt / Ctrl
+// keys
+// [RootCause] Partial keys not handled
+// [Solution] Partial keys handled properly
+// [Files] commonoem.c
+//
+// 32 2/01/12 1:55a Arunsb
+// [TAG] EIP74968
+// [Category] Improvement
+// [Description] Support for mouse drag and drop to rearrange the items
+// in the Orderlist.
+// [Files] Ordlistbox.c, commonoem.c and commonoem.h
+//
+// 31 1/25/12 8:31a Rajashakerg
+// [TAG] EIP62763
+// [Category] Improvement
+// [Description] Utilize the Improvements done from mouse driver in
+// AMITSE
+// [Files] commonoem.c
+//
+// 30 12/28/11 4:10a Arunsb
+// [TAG] EIP75021
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] [TSE] In Date and Time item Press Shift+Tab key can't move
+// previous field.
+// [RootCause] Shift states not checked properly
+// [Solution] Shift state bits are cleared for every combinations and
+// compared at last
+// [Files] commonoem.c and commonhelper.c
+//
+// 29 11/20/11 6:54a Rajashakerg
+// [TAG] EIP62763
+// [Category] Improvement
+// [Description] Utilize the Improvements done from mouse driver in
+// AMITSE
+// [Files] HookAnchor.h, TseCommon.h, AMITSE.sdl, CommonHelper.c,
+// commonoem.c, commonoem.h, buffer.c, globals.c, HookAnchor.c,
+// minisetup.h, notify.c, postmgmt.c, protocol.c, ezport.c, stylecommon.c,
+// Mouse.c, Action.c, Date.c, frame.c, MessageBox.c, minisetupext.c,
+// minisetupext.h, numeric.c, numeric.h, page.c, PopupEdit.c, PopupEdit.h,
+// PopupPassword.c, postmgmtext.c, time.c.
+//
+// 28 11/14/11 2:40p Blaines
+// [TAG] - EIP 75481
+// [Category]- Function Request
+// [Synopsis]- TSE debug print infrastructure.
+// [Description]- Add TSE debug print info for basic functions such as
+// Hiiparsing, HiiNotifications, HiiCallbacks. Variables, and Ifrforms
+// data.
+// [Files]
+// AMITSE.sdl, AmiTSEStr.uni, CommonHelper.c, commonoem.c, FakeTokens.c
+// Globals.c, Minisetup.cif, Minisetup.h, print.c, FormBrowser2.c, Hii.c,
+// HiiCallback.c, HiiNotificationHandler.c, Parse.c, TseUefiHii.h,
+// Uefi21Wrapper.c, setupdbg.h
+//
+// 27 11/01/11 4:21a Arunsb
+// [Category] Improvement
+// [Description] To change the single click behaviour as like double
+// click
+// [Files] amitse.sdl, commonhelper.c, commonoem.c and listbox.c
+//
+// 26 9/22/11 2:45a Arunsb
+// [TAG] EIP64402
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] If logo.ffs not present in TSE then BGRT table not
+// formed for badging images.
+// This one is fixed.
+// [Files] commonoem.c
+//
+// 25 9/21/11 1:56p Arunsb
+// [TAG] EIP66443
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Build fails when SETUP_BBS_POPUP_ENABLE is enabled and
+// SETUP_ALT_ENTRY_ENABLE is disabled.
+// [RootCause] By default, SETUP_BBS_POPUP_ENABLE is set to disabled and
+// SETUP_ALT_ENTRY_ENABLE is enabled.
+// If the customer sets SETUP_BBS_POPUP_ENABLE to enabled, and
+// SETUP_ALT_ENTRY_ENABLE to disabled, then the
+// SETUP_ALT_ENTRY_SHIFT_STATE SDL token is not defined and thus the build
+// error arose.
+// [Solution] SETUP_ALT_ENTRY_SHIFT_STATE SDL token is validated before
+// its usage.
+// [Files] commonoem.c
+//
+// 24 6/30/11 3:55a Arunsb
+// Unused BootOption variable removed.
+//
+// 23 6/29/11 2:06p Arunsb
+// EIP 62631 gHotKeyBootOption declaration moved to commonhelper.c
+//
+// 22 6/29/11 6:03a Arunsb
+// [TAG] EIP 62631
+// [Category] New Feature
+// [Description] Hot key boot option support in TSE as per UEFI spec.
+// section 3.1.6.
+// CheckAdvShiftState function moved from commonoem.c to
+// here.
+// BootLaunchBootOption removed in checkforkey function to
+// avoid TPL problem.
+// [Files] AMITSE.sdl, bootflow.c, bootflow.h, CommonHelper.c,
+// commonoem.c, commonoem.h, boot.c,
+// hiistring20.c, hiistring21.c and notify.c.
+//
+// 21 6/23/11 8:29p Arunsb
+// [TAG] EIP62466
+// [Category] Improvement
+// [Description] Trace message support in commonoem.c.
+// Included amidxelib.h file.
+// [Files] commonoem.c
+//
+// 20 6/22/11 7:10a Arunsb
+// [TAG] EIP 62631, 60128
+// [Category] New Feature
+// [Description] Hot key boot option in TSE as per UEFI spec. section
+// 3.1.6.
+// Hot key checked.
+// CheckAdvShiftState function added to handle special
+// case like Ctrl+Alt+F6.
+// TSE_CHECK_SHIFTSTATE added for checking special key to
+// launch setup.
+// [Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h,
+// boot.c, hiistring20.c and hiistring21.c.
+//
+// 19 6/20/11 3:50p Arunsb
+// [TAG] EIP57660
+// [Category] New Feature
+// [Description] Non-removable media boot behavior as described in UEFI
+// specification v 2.3.1, p. 3.4.1.
+// Added CheckForSetupKey function to check setup
+// key pressed.
+// [Files] amitse.sdl, bootflow.c, bootflow.h, commonoem.c,
+// boot.c and protocol.c
+//
+// 18 5/29/11 12:01p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Quiet boot logo's only added for BGRT. BGRT status
+// field cleared if any changes happened in screen other than displaying
+// the image.
+// [Files] Postmgmt.c, boot.c, logo.c commonoem.c and
+// commonhelper.c
+//
+// 17 5/03/11 9:55p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Contributing BGRT table to ACPI table.
+// CONTRIB_BGRT_TABLE_TO_ACPI token added. EDK Build support added. Code
+// moved to drawimage function.
+// [Files] Postmgmt.c, commonoem.c and commonhelper.c
+//
+// 16 4/23/11 3:10p Arunsb
+// [TAG] EIP58954
+// [Category] New Feature
+// [Description] Contributing BGRT table to ACPI table.
+// CONTRIB_BGRT_TABLE_TO_ACPI token added.
+// [Files] Postmgmt.c and commonoem.c
+//
+// 15 3/28/11 9:06p Madhans
+// [TAG] EIP41744
+// [Category] Improvement
+// [Description] SoftKeyBoard Support in TSE. and Support to Work with
+// new mouse driver(Label 07).
+// [Files] HookAnchor.h
+// AMITSE.sdl
+// CommonHelper.c
+// commonoem.c
+// commonoem.h
+// HookList.c
+// HookAnchor.c
+// Mouse.c
+// minisetupext.c
+// postmgmtext.c
+// minisetupext.h
+// PopupPassword.c
+// PopupString.c
+// TseLiteCommon.c
+//
+// 14 12/28/10 4:15p Mallikarjunanv
+// [TAG] EIP 47837
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Shift key combinations are not working properly.
+// [RootCause] Issues with handling shiftstate in case of AMI Keycode
+// protocol
+// [Solution] udpated the sources to verify the key with and without
+// shiftstate value in case of TSE_USE_AMI_KEYCODE_PROTOCOL enabled.
+//
+// [Files] Commonoem.c
+//
+// 13 12/27/10 3:07a Mallikarjunanv
+//
+// 12 12/26/10 5:15p Mallikarjunanv
+// [TAG] EIP47387
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Shift key combinations are not working properly.
+// [RootCause] Issues with handling shiftstate in case of AMI Keycode
+// protocol
+// [Solution] udpated the sources to verify the key with and without
+// shiftstate value in case of TSE_USE_AMI_KEYCODE_PROTOCOL enabled.
+// [Files] commonoem.c
+//
+// 11 12/02/10 2:31p Madhans
+// [TAG] - EIP 48169
+// [Category]- Enhancement
+// [Severity]- Mordarate
+// [Symptom]- Code Cleanup and Compiler Warning need to resolved.
+// [Rootcause] Warnings reported when we build AMI higher Warning level.
+// [Solution]- 1. Fix the warnings and do the code cleanup.
+// 2. Introduce proper checks.
+// 3. change the popupSel.c to not change the Option/variable
+// cache to default or first option
+// when the variable cache is not matching with any of
+// option.
+// [Files] - commonoem.c bbs.c boot.c hiistring.c resource.c
+// popuppassword.c popupsel.c
+// expression.c hii.c parse.c
+//
+// 10 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 25 8/18/10 6:15p Mallikarjunanv
+// EIP-38089: Hook after pressing F2 key and before showing setup menu.
+//
+// 24 8/13/10 10:21a Mallikarjunanv
+// EIP-40772: Created a token to control enter setup string in POST during
+//
+// 23 7/07/10 7:36p Madhans
+// To fix the issue of Not booting from BBS if SetupEntry and BBS Keys
+// pressed togather multiple time.
+//
+// 22 6/14/10 7:03p Madhans
+// To avoid warning
+//
+// 21 6/08/10 5:06p Blaines
+// Created new AMITSE hook (hook33), called when TSE determines that
+// console out is available.
+//
+// 20 5/14/10 4:08p Madhans
+// EIp 38626 : to include the OEM header files in commonoem.h
+//
+// 19 4/21/10 11:09a Mallikarjunanv
+// EIP-36596: Logo ImageData buffer freeing issue fixed
+//
+// 18 4/13/10 6:01p Madhans
+// Eip: 33100 To create new hook for BootNowLaunching. (From bbsPopoup and
+// Boot override menu).
+//
+// 17 4/13/10 5:12p Madhans
+// EIP: 37439 To support extended OEM Key support.
+//
+// 16 4/07/10 6:23p Madhans
+// Post Screen Scroll Area Support.TSE_POSTSCREEN_SCROLL_AREA Sdl token
+// Controls it.
+//
+// 15 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 14 2/15/10 10:02p Madhans
+//
+// 13 2/04/10 11:06p Madhans
+// MapControlActionMouse hook added.
+//
+// 12 1/18/10 2:05a Mallikarjunanv
+// EIP-28501: Updated for Keyboard scancode as password. Added a new Token
+// SETUP_STORE_KEYCODE_PASSWORD to support the EFI key or Scan code as
+// password
+//
+// 11 1/09/10 2:26a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 10 12/04/09 7:13a Mallikarjunanv
+// Fix for EIP:30263 - Gif Logo Issue
+//
+// 9 11/05/09 12:38p Mallikarjunanv
+// deleted the function HiiGetEfiKey, which is moved to uefi module
+//
+// 8 10/30/09 9:46a Mallikarjunanv
+// EIP-28551 : Fixed TSE 2.0 Build error releated to
+// SETUP_STORE_EFI_KEY_PASSWORD and TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+//
+// 7 10/28/09 5:34p Madhans
+// 1. Support to Add the String from other modules to TSE.
+// 2. Clean of GIF and Image code Control them with minimal code from TSE
+// binary.
+//
+//
+// 6 9/15/09 9:16a Sudhirv
+// added new hooks for LoadSetupDefaults and PreSystemReset
+//
+// 5 8/13/09 7:31a Mallikarjunanv
+// eips: 25075, 24971 and hii functions miving from binary to uefi module
+//
+// 4 7/31/09 11:45a Blaines
+// Add support for non-case sensitive password.
+//
+// 3 7/30/09 7:51a Mallikarjunanv
+// updated the code to move the exit page option elinks to Tse Binary
+//
+// 2 7/20/09 1:07p Mallikarjunanv
+// fixed syntax errors
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 2 4/29/09 9:01p Madhans
+// Bug Fixes after unit Testing..
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 2 1/30/09 6:06p Madhans
+// Function headers added.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Commonoem.c
+//
+// Description: contains default implementation of TSE hooks
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifdef TSE_FOR_APTIO_4_50
+
+#include "Token.h"
+#include <Efi.h>
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/EfiOemBadging.h>
+#include <Protocol/AMIPostMgr.h>
+#include "AMITSEStrTokens.h"
+#include "AMITSEElinks.h"
+#include <AmiDxeLib.h>
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+#include "Protocol/AmiKeyCode.h"
+#else
+#ifndef _AMI_EFI_KEY_DATA_
+#define _AMI_EFI_KEY_DATA_
+typedef struct {
+ EFI_INPUT_KEY Key;
+} AMI_EFI_KEY_DATA;
+#endif
+#endif
+
+#pragma pack (1)
+#ifndef _TSE_EFI_IFR_FORM_SET
+#define _TSE_EFI_IFR_FORM_SET
+typedef UINT16 EFI_STRING_ID; //For avoiding build error in EFI 2.0
+typedef struct _TSE_EFI_IFR_FORM_SET {
+ EFI_IFR_OP_HEADER Header;
+ EFI_GUID Guid;
+ EFI_STRING_ID FormSetTitle;
+ EFI_STRING_ID Help;
+ UINT8 Flags;
+ EFI_GUID ClassGuid[1];
+} TSE_EFI_IFR_FORM_SET;
+#endif
+#pragma pack ()
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+EFI_GUID gAmiEfiKeycodeProtocolGuid = AMI_EFIKEYCODE_PROTOCOL_GUID;
+#endif
+
+VOID *
+EfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ );
+
+#else //#ifdef TSE_FOR_APTIO_4_50
+
+#include "minisetup.h"
+#include "AMITSEElinks.h"
+#endif //#ifdef TSE_FOR_APTIO_4_50
+
+#ifdef TSE_FOR_APTIO_4_50
+// Definitions of keys are different in Alaska and Tiano. So for
+// Alaska define Tiano key definitions.
+
+#define CharIsUpper(c) ((c >= L'A') && (c <= L'Z'))
+#define CharIsLower(c) ((c >= L'a') && (c <= L'z'))
+#define CharIsAlpha(c) (CharIsUpper(c) || CharIsLower(c))
+#define CharIsNumeric(c) ((c >= L'0') && (c <= L'9'))
+
+#define CHAR_NULL 0x0000
+#define CHAR_BACKSPACE 0x0008
+#define CHAR_TAB 0x0009
+#define CHAR_LINEFEED 0x000A
+#define CHAR_CARRIAGE_RETURN 0x000D
+
+#ifndef SCAN_NULL
+#define SCAN_NULL EFI_SCAN_NULL
+#endif
+
+#ifndef SCAN_UP
+#define SCAN_UP EFI_SCAN_UP
+#endif
+
+#ifndef SCAN_DOWN
+#define SCAN_DOWN EFI_SCAN_DN
+#endif
+
+#ifndef SCAN_RIGHT
+#define SCAN_RIGHT EFI_SCAN_RIGHT
+#endif
+
+#ifndef SCAN_LEFT
+#define SCAN_LEFT EFI_SCAN_LEFT
+#endif
+
+#ifndef SCAN_HOME
+#define SCAN_HOME EFI_SCAN_HOME
+#endif
+
+#ifndef SCAN_END
+#define SCAN_END EFI_SCAN_END
+#endif
+
+#ifndef SCAN_INSERT
+#define SCAN_INSERT EFI_SCAN_INS
+#endif
+
+#ifndef SCAN_DELETE
+#define SCAN_DELETE EFI_SCAN_DEL
+#endif
+
+#ifndef SCAN_PAGE_UP
+#define SCAN_PAGE_UP EFI_SCAN_PGUP
+#endif
+
+#ifndef SCAN_PAGE_DOWN
+#define SCAN_PAGE_DOWN EFI_SCAN_PGDN
+#endif
+
+#ifndef SCAN_F1
+#define SCAN_F1 EFI_SCAN_F1
+#endif
+
+#ifndef SCAN_F2
+#define SCAN_F2 EFI_SCAN_F2
+#endif
+
+#ifndef SCAN_F3
+#define SCAN_F3 EFI_SCAN_F3
+#endif
+
+#ifndef SCAN_F4
+#define SCAN_F4 EFI_SCAN_F4
+#endif
+
+#ifndef SCAN_F5
+#define SCAN_F5 EFI_SCAN_F5
+#endif
+
+#ifndef SCAN_F6
+#define SCAN_F6 EFI_SCAN_F6
+#endif
+
+#ifndef SCAN_F7
+#define SCAN_F7 EFI_SCAN_F7
+#endif
+
+#ifndef SCAN_F8
+#define SCAN_F8 EFI_SCAN_F8
+#endif
+
+#ifndef SCAN_F9
+#define SCAN_F9 EFI_SCAN_F9
+#endif
+
+#ifndef SCAN_F10
+#define SCAN_F10 EFI_SCAN_F10
+#endif
+
+#ifndef SCAN_F11
+#define SCAN_F11 EFI_SCAN_F11
+#endif
+
+#ifndef SCAN_F12
+#define SCAN_F12 EFI_SCAN_F12
+#endif
+
+#ifndef SCAN_ESC
+#define SCAN_ESC EFI_SCAN_ESC
+#endif
+
+
+#endif //#ifdef TSE_FOR_APTIO_4_50
+#include "commonoem.h"
+#include "LogoLib.h"
+#include "Mem.h"
+#include "HiiLib.h"
+#include "PwdLib.h"
+#include "KeyMon.h"
+#include "bootflow.h"
+#include "variable.h"
+#include "TseElinks.h"
+#include "AmiVfr.h"
+#if MINISETUP_MOUSE_SUPPORT
+#include "Include\Protocol\MouseProtocol.h"
+extern DXE_MOUSE_PROTOCOL *TSEMouse;
+#endif
+#include <setupdata.h>
+#include <AutoId.h> // for MAIN_MAIN
+
+// Build time file generated from AMITSE_OEM_HEADER_LIST elink.
+#include "AmiTseOem.h"
+
+#ifndef EFI_DEFAULT_BMP_LOGO_GUID
+#define EFI_DEFAULT_BMP_LOGO_GUID \
+ {0x7BB28B99,0x61BB,0x11d5,0x9A,0x5D,0x00,0x90,0x27,0x3F,0xC1,0x4D}
+#endif
+
+typedef struct {
+ UINT8 CtrlAction;
+ CHAR16 UnicodeChar;
+ UINT16 ScanCode;
+ UINT32 KeyShiftState;
+} USER_CONTROL_KEY_DATA;
+
+extern PAGE_LIST *gPages;
+extern UINT8 *gApplicationData;
+extern PAGE_ID_LIST *gPageIdList;
+
+typedef struct _HII_FORM_ADDRESS
+{
+ EFI_GUID formsetGuid; // Required
+ UINT16 formId; // Required
+ VOID * Handle; // Optional
+}HII_FORM_ADDRESS;
+#define NULL_GUID \
+ { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }
+HII_FORM_ADDRESS RootPageList[] = { AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, NULL}, };
+HII_FORM_ADDRESS HiddenPageList[] = { AMITSE_HIDDEN_PAGE_LIST { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, NULL}, };
+HII_FORM_ADDRESS RootPageOrder[] = { AMITSE_ROOT_PAGE_ORDER { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, 0, NULL}, };
+
+EFI_GUID gFormSetClassGuidList[] = {AMITSE_FILTER_CLASSGUID_FORMSETS, NULL_GUID};
+EFI_GUID gSuppressDynamicFormsetList[] = { AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST NULL_GUID };
+VAR_DYNAMICPARSING_HANDLESUPPRESS gHandleSuppressVarList [] = {AMITSE_DYNAMICPARSING_HANDLE_SUPPRESS_LIST {NULL_GUID, ""}};
+
+extern BOOLEAN
+EfiCompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ );
+
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_RUNTIME_SERVICES *gRT;
+extern BOOLEAN gEnterSetup;
+extern BOOLEAN gEnterBoot;
+extern BOOLEAN gQuietBoot;
+extern STYLECOLORS Colors;
+extern VOID StyleOverRideComponent(VOID);
+VOID ConfigPostScrollArea(VOID);
+extern UINT32 gBootFlow;
+extern EFI_GUID _gBootFlowGuid;
+extern UINT16 gDbgPrint ;
+///Assign the Exit Page options info. from Elink...
+EXIT_PAGE_OPTIONS gExitPageOptions[] = {
+ EXIT_PAGE_OPTIONS_LIST
+};
+extern BOOLEAN GifImageFlag; //flag to denote the gif animation
+VOID ContribBGRTTableToAcpi (BOOLEAN);
+extern UINT8 gAddBgrtResolutions;
+BOOLEAN CheckforHotKey (AMI_EFI_KEY_DATA);
+VOID TSEStringReadLoopEntryHook(VOID);
+BOOLEAN TSEMouseIgnoreMouseActionHook(VOID);
+VOID StopClickEvent(VOID);
+VOID TSEStringReadLoopExitHook(VOID);
+VOID MouseStop(VOID);
+VOID MouseRefresh(VOID);
+VOID SwitchToPostScreenHook(VOID);//EIP-111415 SwitchToPostScreenHook
+
+//EIP81959
+#ifndef KEY_STATE_EXPOSED
+#define KEY_STATE_EXPOSED 0x40
+#endif
+static BOOLEAN gPostScreenMsg = FALSE; //EIP 84199 ProcessConInAvailability needs protection against getting called twice
+
+BOOLEAN gIsRootPageOrderPresent = FALSE;
+//UINT16 *gRootPageOrder;
+HII_FORM_ADDRESS *gRootPageOrder;
+UINT16 gRootPageOrderIndex = 0;
+UINTN CurrentScreenresolutionX, CurrentScreenresolutionY;
+extern UINTN gPostStatus; //EIP-140123
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DrawQuietBootLogo
+//
+// Description: This function is the generic implementation of
+// drawing quiet boot logo. This function is available
+// as an ELINK.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetNativeResFromEdid (VOID);
+VOID DrawQuietBootLogo(VOID)
+{
+ EFI_STATUS Status;
+ BOOLEAN LogoToDo = TRUE;
+ EFI_OEM_BADGING_PROTOCOL *Badging = NULL;
+ UINT32 Instance = 0;
+ EFI_BADGING_FORMAT Format;
+ UINT8 *ImageData = NULL;
+ UINTN ImageSize = 0;
+ EFI_BADGING_DISPLAY_ATTRIBUTE Attribute;
+ INTN CoordinateX = 0;
+ INTN CoordinateY = 0;
+ EFI_GUID LogoFile = EFI_DEFAULT_BMP_LOGO_GUID;
+ UINTN Width, Height;
+ BOOLEAN AdjustSize = TRUE;
+ UINTN NoOfHandles = 0;
+ EFI_HANDLE *Handles;
+ UINTN HandleIndex = 0;
+ BOOLEAN AddBgrtToAcpi = TRUE;
+
+ // Draw the Logo
+#if TSE_SUPPORT_NATIVE_RESOLUTION
+ SetNativeResFromEdid (); //EIP94702
+#endif
+ Status = GetGraphicsBitMapFromFV( &LogoFile, &ImageData, &ImageSize );
+ MouseStop ();//EIP 62763 : Stopping the mouse before drawing the Quiet boot logo.
+ if (!EFI_ERROR (Status))
+ {
+ //No need for initializing CoordinateX and CoordinateY
+ //because image will be cenetered and they will be ignored
+ //anyways
+ Attribute = EfiBadgingDisplayAttributeCenter;
+ gAddBgrtResolutions = 1;
+ Status = DrawImage(
+ ImageData,
+ ImageSize,
+ (CO_ORD_ATTRIBUTE)Attribute,
+ CoordinateX,
+ CoordinateY,
+ AdjustSize,
+ &Width,
+ &Height
+ );
+ AdjustSize = FALSE;
+ if (EFI_SUCCESS != Status)
+ {
+ AddBgrtToAcpi = FALSE; //EIP 58954 Not Adding BGRT table to ACPI
+ }
+ //In case of gif animation not to clear the image data
+ if (!GifImageFlag)
+ MemFreePointer((VOID **)&ImageData);
+ }
+
+ //Locate Badging protocol Handles
+ Status = gBS->LocateHandleBuffer(ByProtocol,&gEfiOEMBadgingProtocolGuid,NULL,&NoOfHandles,&Handles);
+
+ if (!EFI_ERROR (Status))
+ {
+ if (!gAddBgrtResolutions) //EIP64402 to support oem logo module. If logo.ffs not present from TSE then this wiil set the gAddBgrtResolutions.
+ {
+ gAddBgrtResolutions = 1;
+ }
+
+ // for each badging protocol
+ for(HandleIndex=0; HandleIndex<NoOfHandles;HandleIndex++)
+ {
+ Badging = NULL;
+ Instance = 0;
+ gBS->HandleProtocol(Handles[HandleIndex],&gEfiOEMBadgingProtocolGuid,&Badging);
+ if(Badging != NULL)
+ LogoToDo = TRUE;
+
+ //Draw all Logo obtained from Badging protocol or FV
+ while ( LogoToDo )
+ {
+ Status = Badging->GetImage (
+ Badging,
+ &Instance,
+ &Format,
+ &ImageData,
+ &ImageSize,
+ &Attribute,
+ &CoordinateX,
+ &CoordinateY
+ );
+ if(EFI_ERROR (Status))
+ {
+ LogoToDo = FALSE;
+ break;
+ }
+ Status = DrawImage(
+ ImageData,
+ ImageSize,
+ (CO_ORD_ATTRIBUTE)Attribute,
+ CoordinateX,
+ CoordinateY,
+ AdjustSize,
+ &Width,
+ &Height
+ );
+ if (EFI_SUCCESS != Status) //EIP 58954 Not Adding BGRT table to ACPI
+ {
+ AddBgrtToAcpi = FALSE;
+ }
+ AdjustSize = FALSE;
+
+ //In case of gif animation not to clear the image data
+ if(!GifImageFlag)
+ MemFreePointer((VOID **)&ImageData);
+ }
+ }
+ if(NoOfHandles)
+ gBS->FreePool(Handles);
+ }
+ gAddBgrtResolutions = 0;
+ if (TRUE == AddBgrtToAcpi)
+ {
+ ContribBGRTTableToAcpi (GifImageFlag);
+ }
+ MouseRefresh();//EIP 62763 : Refreshing the mouse after drawing the Quiet boot logo.
+ GetScreenResolution(&CurrentScreenresolutionX, &CurrentScreenresolutionY); //EIP-123535 Getting QuietBoot resolution
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessConInAvailability
+//
+// Description: This function is a hook called when TSE determines
+// that console is available. This function is available
+// as ELINK. In the generic implementation boot password
+// is prompted in this function.
+//
+// Input: VOID
+//
+// Output: BOOLEAN. Should return TRUE if the screen was used to
+// ask password; FALSE if the screen was not used to ask
+// password.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ProcessConInAvailability(VOID)
+{
+ UINTN NoOfRetries;
+ UINT32 PasswordInstalled = AMI_PASSWORD_NONE;
+ UINTN Index;
+ EFI_INPUT_KEY Key;
+ BOOLEAN bScreenUsed = FALSE;
+#if SETUP_PRINT_EVAL_MSG || SETUP_PRINT_ENTER_SETUP_MSG
+ CHAR16 *text = NULL;
+#endif
+ if (!gPostScreenMsg) //EIP 84199 ProcessConInAvailability needs protection against getting called twice
+ {
+#if SETUP_PRINT_EVAL_MSG
+ //Print evaluation message here
+ text = HiiGetString( gHiiHandle, STRING_TOKEN(STR_EVAL_MSG));
+ if ( text != NULL )
+ PostManagerDisplayPostMessage(text);
+ MemFreePointer( (VOID **)&text );
+#endif
+#if SETUP_PRINT_ENTER_SETUP_MSG //EIP:40772 - new token to control Setup enter message display
+ text = HiiGetString( gHiiHandle, STRING_TOKEN(STR_DEL_ENTER_SETUP) );
+ if ( text != NULL )
+ PostManagerDisplayPostMessage(text);
+ MemFreePointer( (VOID **)&text );
+#endif
+ gPostScreenMsg = TRUE;
+ }
+ // if gPasswordType is not AMI_PASSWORD_NONE, Already got the Password.
+ // Don't Ask for Password if it is already entered.
+ if ( gPasswordType == AMI_PASSWORD_NONE )
+ {
+ PasswordInstalled = PasswordCheckInstalled();
+ NoOfRetries = 3;
+
+ if(CheckSystemPasswordPolicy(PasswordInstalled))
+ {
+ bScreenUsed = TRUE;
+ if(AMI_PASSWORD_NONE == CheckSystemPassword( AMI_PASSWORD_NONE, &NoOfRetries, NULL))
+ {
+ while(1)
+ {
+ //Patch
+ //Ctl-Alt-Del is not recognized by core unless a
+ //ReadKeyStroke is issued
+ gBS->WaitForEvent( 1, &(gST->ConIn->WaitForKey), &Index );
+ gST->ConIn->ReadKeyStroke( gST->ConIn, &Key );
+ }
+ }
+ }
+ }
+ return bScreenUsed;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessEnterSetup
+//
+// Description: This function is a hook called when TSE determines
+// that SETUP utility has to be displayed. This function
+// is available as ELINK. In the generic implementation
+// setup password is prompted in this function.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessEnterSetup(VOID)
+{
+ UINTN NoOfRetries;
+ UINT32 PasswordInstalled = AMI_PASSWORD_NONE;
+ UINTN Index;
+ EFI_INPUT_KEY Key;
+
+ if ( gPasswordType == AMI_PASSWORD_NONE )
+ {
+
+ PasswordInstalled = PasswordCheckInstalled();
+
+ if ( !( PasswordInstalled & AMI_PASSWORD_ADMIN ) )
+ {
+ SetPasswordType( AMI_PASSWORD_ADMIN );
+ }
+ else
+ {
+ NoOfRetries = 3;
+
+ if(AMI_PASSWORD_NONE == CheckSystemPassword( AMI_PASSWORD_USER, &NoOfRetries, NULL))
+ {
+ while(1)
+ {
+ //Patch
+ //Ctl-Alt-Del is not recognized by core unless a
+ //ReadKeyStroke is issued
+ gBS->WaitForEvent( 1, &(gST->ConIn->WaitForKey), &Index );
+ gST->ConIn->ReadKeyStroke( gST->ConIn, &Key );
+ }
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessEnterSetup
+//
+// Description: This function is a hook called when TSE determines
+// that it has to load the boot options in the boot
+// order. This function is available as ELINK. In the
+// generic implementation this function is empty. OEM
+// may decide to prompt for boot password in this
+// function.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessProceedToBoot(VOID)
+{
+}
+
+///Control key handling using Elinks...
+
+USER_CONTROL_KEY_DATA gUserCtrlKeyData[]= { CONTROL_KEY_MAP_LIST };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetKeySelection
+//
+// Description: Function to validate the selected key based the key data.
+//
+// Input: UserCtrlKeyData: User initialized data for the key
+// Key: Key provided by SimpleTextIn protocol
+// KeyCodeProtocolSupport: flag to verify KeyShiftState.
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GetKeySelection(USER_CONTROL_KEY_DATA UserCtrlKeyData, AMI_EFI_KEY_DATA AmiKey, BOOLEAN KeyCodeProtocolSupport)
+{
+ ///EIP-47387: Start
+ if (KeyCodeProtocolSupport)
+ {
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ /// validate the key including KeyShiftState.
+ if ((TSE_CHECK_SHIFTSTATE(AmiKey.KeyState.KeyShiftState, UserCtrlKeyData.KeyShiftState) )&&
+ (AmiKey.Key.UnicodeChar == UserCtrlKeyData.UnicodeChar ) &&
+ (AmiKey.Key.ScanCode == UserCtrlKeyData.ScanCode ) )
+ {
+ return 1;
+ }
+#endif
+ }
+ /// validate the key without KeyShiftState
+ else if( (AmiKey.Key.UnicodeChar == UserCtrlKeyData.UnicodeChar ) &&
+ (AmiKey.Key.ScanCode == UserCtrlKeyData.ScanCode ) )
+ {
+ return 1;
+ }
+ return 0;
+ ///EIP-47387: End
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MapControlKeys
+//
+// Description: This function is a hook called inside setup utility
+// to determine the action to be taken for a particular
+// key press. This function is available as ELINK. OEMs
+// may choose to have a different action or a different
+// key. With this function OEMs can change key mappings
+// for the controls in the setup utility. Post hot keys
+// and Setup utility hot keys are out of this functions
+// scope.
+//
+// Input: Key: Key provided by SimpleTextIn protocol
+//
+// Output: CONTROL_ACTION: enumeration defined in commonoem.h.
+// Input EFI_INPUT_KEY has to mapped to one of the
+// enumerations in CONTROL_ACTION.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CONTROL_ACTION MapControlKeys(AMI_EFI_KEY_DATA key)
+{
+ UINT8 CtrlCnt=0;
+ UINT32 UserCtrlKeyCount=0;
+ UserCtrlKeyCount = ( sizeof(gUserCtrlKeyData) / sizeof(USER_CONTROL_KEY_DATA));
+
+///EIP-47387: Start
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ ///To get the selected key data with shiftstate using Keycode protocol.
+ for( CtrlCnt=0; CtrlCnt<UserCtrlKeyCount; CtrlCnt++ )
+ {
+ if( GetKeySelection (gUserCtrlKeyData[CtrlCnt], key, 1) )
+ {
+ return gUserCtrlKeyData[CtrlCnt].CtrlAction;
+ }
+ }
+#else
+ ///To get the selected key data without shiftstate
+ for( CtrlCnt=0; CtrlCnt<UserCtrlKeyCount; CtrlCnt++ )
+ {
+ if( GetKeySelection (gUserCtrlKeyData[CtrlCnt], key, 0) )
+ {
+ return gUserCtrlKeyData[CtrlCnt].CtrlAction;
+ }
+ }
+#endif
+///EIP-47387: End
+
+ if( CharIsAlpha(key.Key.UnicodeChar) )
+ return ControlActionAlpha;
+ if( CharIsNumeric(key.Key.UnicodeChar) )
+ return ControlActionNumeric;
+
+ return ControlActionUnknown;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SupportOSIndication
+//
+// Description: Adds OSIndication support
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#define EFI_OS_INDICATIONS_BOOT_TO_FW_UI 0x0000000000000001
+VOID SupportOSIndication (VOID)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID EfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+ UINT64 OsIndicationsSupported = EFI_OS_INDICATIONS_BOOT_TO_FW_UI;
+ UINT64 OsIndications = 0;
+ UINTN DataSize = sizeof (UINT64);
+ UINT32 Attributes = 0;
+ UINT32 BootFlow = BOOT_FLOW_CONDITION_FIRST_BOOT;
+ EFI_GUID BootFlowGuid = BOOT_FLOW_VARIABLE_GUID;
+
+ Status = pRS->SetVariable (L"OsIndicationsSupported", &EfiGlobalVariableGuid, (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS), DataSize, (VOID *)&OsIndicationsSupported);
+ if (!EFI_ERROR (Status))
+ {
+ DataSize = sizeof (UINT64);
+ Status = pRS->GetVariable (L"OsIndications", &EfiGlobalVariableGuid, &Attributes, &DataSize, (VOID *)&OsIndications);
+ if (!EFI_ERROR (Status))
+ {
+ if (OsIndications & EFI_OS_INDICATIONS_BOOT_TO_FW_UI)
+ {
+ Status = pRS->SetVariable (L"BootFlow",
+ &BootFlowGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (BootFlow),
+ &BootFlow);
+ OsIndications = OsIndications & (~EFI_OS_INDICATIONS_BOOT_TO_FW_UI);
+ Status = pRS->SetVariable (L"OsIndications", &EfiGlobalVariableGuid, Attributes, DataSize, (VOID *)&OsIndications);
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MinisetupDriverEntryHook
+//
+// Description: This function is a hook called at the end of TSE
+// driver entry. This function is available as ELINK.
+// In the generic implementation TSE installs Key
+// monitoring protocol. OEMs may choose to do additional
+// logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MinisetupDriverEntryHook(VOID)
+{
+#if TSE_DEBUG_MESSAGES
+ EFI_STATUS Status;
+ EFI_GUID guidDbgPrint = TSE_DEBUG_MESSAGES_GUID;
+ UINTN dbgVarSize = sizeof(gDbgPrint);
+ UINT16 FeatureBit ;
+
+#endif
+
+#if SETUP_SUPPORT_KEY_MONITORING
+ InstallKeyMonProtocol();
+#endif
+ StyleOverRideComponent();
+ ConfigPostScrollArea();
+
+#if TSE_DEBUG_MESSAGES
+
+ Status = pRS->GetVariable(
+ L"TseDebugPrint",
+ &guidDbgPrint,
+ NULL,
+ &dbgVarSize,
+ &FeatureBit) ;
+
+ if(!EFI_ERROR( Status ) )
+ gDbgPrint = FeatureBit ;
+#endif
+#if OSIndication_SUPPORT
+ SupportOSIndication ();
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PostManagerHandShakeHook
+//
+// Description: This function is a hook called at the begining of the
+// PostManagerHandShake protocol function. This function
+// is available as ELINK. In the generic implementation
+// TSE gets keys from key monitor filter. OEMs may choose
+// to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PostManagerHandShakeHook(VOID)
+{
+#if SETUP_SUPPORT_KEY_MONITORING
+ GetKeysFromKeyMonFilter();
+#endif
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintEnterBBSPopupMessage
+//
+// Description: Displays STR_ACK_BBS_POPUP message in screen
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PrintEnterBBSPopupMessage ()
+{
+ if(gEnterBoot != TRUE) // Print the "Entering Boot" message only once
+ {
+#if SETUP_PRINT_ENTER_BBSPOPUP_MSG
+ CHAR16 *text = NULL;
+
+ //Print Entering Boot Menu here
+ text = HiiGetString( gHiiHandle, STRING_TOKEN(STR_ACK_BBS_POPUP) );
+ if ( text != NULL )
+ PostManagerDisplayPostMessage(text);
+ MemFreePointer( (VOID **)&text );
+#endif
+ gEnterBoot = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintEnterSetupMessage
+//
+// Description: Displays STR_ACK_ENTER_SETUP message in screen
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void PrintEnterSetupMessage()
+{
+ if(gEnterSetup != TRUE) // To print the "Entering setup" message only once
+ {
+#if SETUP_PRINT_ENTER_SETUP_MSG //EIP:40772 - new token to control Setup enter message display
+ CHAR16 *text = NULL;
+
+ //Print Entering setup here
+ text = HiiGetString( gHiiHandle, STRING_TOKEN(STR_ACK_ENTER_SETUP) );
+ if ( text != NULL )
+ PostManagerDisplayPostMessage(text);
+ MemFreePointer( (VOID **)&text );
+#endif
+ gEnterSetup = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckandDeactivateSoftkbd
+//
+// Description: This function is called to check and Deactivate the Softkbd
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void CheckandDeactivateSoftkbd()
+{
+ if(TSEMouseIgnoreMouseActionHook() == TRUE)
+ TSEStringReadLoopExitHook();
+}
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+BOOLEAN CheckOEMKey(AMI_EFI_KEY_DATA* AmiKey, UINT16 UnicodeCharSDL, UINT16 ScanCodeSDL,
+ EFI_KEY EfiKeySDL, UINT32 ShiftStateSDL, EFI_KEY_TOGGLE_STATE ToggleStateSDL)
+{
+ BOOLEAN bRet = FALSE;
+ BOOLEAN bKeyMatch = FALSE;
+ BOOLEAN bShiftStateMatch = FALSE;
+ BOOLEAN bToggleStateMatch = FALSE;
+
+ if ( ( ((AmiKey->Key.UnicodeChar == UnicodeCharSDL)&&(UnicodeCharSDL != 0))
+ || ((AmiKey->Key.ScanCode == ScanCodeSDL)&&(ScanCodeSDL!=0)) )
+ ^((AmiKey->EfiKey == EfiKeySDL)&&(EfiKeySDL != 0)) )
+ bKeyMatch = TRUE;
+
+ //find if the shift key is valid and matching
+ /*if (!(ShiftStateSDL & SHIFT_STATE_VALID))//we don't have to check
+ bShiftStateMatch = TRUE;*/
+ if (AmiKey->KeyState.KeyShiftState & SHIFT_STATE_VALID)
+ {
+ bShiftStateMatch = CheckAdvShiftState(AmiKey->KeyState.KeyShiftState, ShiftStateSDL); // EIP85768
+ /* if( ((AmiKey->KeyState.KeyShiftState &(~SHIFT_STATE_VALID)) & ShiftStateSDL)
+ || ((AmiKey->KeyState.KeyShiftState == SHIFT_STATE_VALID)
+ && (ShiftStateSDL == SHIFT_STATE_VALID)) )
+ bShiftStateMatch = TRUE;*/
+ }
+ //find if the toggle key is valid and matching
+ if (!(ToggleStateSDL & TOGGLE_STATE_VALID))//we don't have to check
+ bToggleStateMatch = TRUE;
+ else if (AmiKey->KeyState.KeyToggleState & TOGGLE_STATE_VALID)
+ {
+ if( ((AmiKey->KeyState.KeyToggleState &(~TOGGLE_STATE_VALID)) & ToggleStateSDL)
+ || ((AmiKey->KeyState.KeyToggleState == TOGGLE_STATE_VALID)
+ && (ToggleStateSDL == TOGGLE_STATE_VALID)) )
+ bToggleStateMatch = TRUE;
+ }
+
+ bRet = (bKeyMatch && bShiftStateMatch && bToggleStateMatch) ? TRUE : FALSE;
+
+ return bRet;
+}
+#else
+BOOLEAN CheckOEMKey(AMI_EFI_KEY_DATA* AmiKey, UINT16 UnicodeCharSDL, UINT16 ScanCodeSDL)
+{
+ if ( ( AmiKey->Key.UnicodeChar == UnicodeCharSDL )
+ && ( AmiKey->Key.ScanCode == ScanCodeSDL ) )
+ return TRUE;
+ else
+ return FALSE;
+}
+#endif
+typedef BOOLEAN (OEM_KEY_CALLBACK_CHECK_FN) ( CHAR16 UnicodeChar, UINT16 ScanCode, UINT32 ShiftState, OUT VOID **OemKeyCallbackFn );
+
+extern OEM_KEY_CALLBACK_CHECK_FN OEM_KEY_CALLBACK_FN EndOfOemCallbackList;
+OEM_KEY_CALLBACK_CHECK_FN * OemKeyCheckFnList[] = { OEM_KEY_CALLBACK_FN NULL };
+extern BOOT_FLOW *gBootFlowTable;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckOEMKeyCallback
+//
+// Description: This function to check OEMKey is consumed by any of the modules that
+// has child elink to OEM_KEY_CALLBACK_LIST. If it wants to handle the key
+// It can return success and callback funciton. The callback function will be
+// called in Bootflowentry.
+//
+// Input: AMI_EFI_KEY_DATA
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckOEMKeyCallback(AMI_EFI_KEY_DATA* AmiKey)
+{
+ UINT32 ShiftState = 0;
+ VOID *CallbackFunction=NULL;
+ UINTN i;
+ BOOT_FLOW *bootFlowPtr;
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ ShiftState = AmiKey->KeyState.KeyShiftState;
+#endif
+ for( i=0;OemKeyCheckFnList[i];i++)
+ {
+ if(OemKeyCheckFnList[i](AmiKey->Key.UnicodeChar, AmiKey->Key.ScanCode, ShiftState, &CallbackFunction))
+ {
+ // OEMKey Claimed
+ if(CallbackFunction != NULL)
+ {
+ bootFlowPtr = gBootFlowTable;
+ for ( bootFlowPtr = gBootFlowTable;
+ bootFlowPtr->Condition != BOOT_FLOW_CONDITION_NULL; bootFlowPtr++ )
+ {
+ if(bootFlowPtr->Condition == BOOT_FLOW_CONDITION_OEM_KEY_CALLBACK)
+ {
+ // Update the OEM Key Callback function.
+ bootFlowPtr->CallbackFunction = (BOOT_FLOW_CALLBACK)(UINTN)CallbackFunction;
+ return TRUE;
+ }
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForKey
+//
+// Description: This function is a hook called to perform specific
+// action for a POST hot key. This function is called
+// periodically. This function is available as ELINK.
+//
+// Input: Event: Timer event.
+// Context: Event context; always NULL
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CheckForKey (EFI_EVENT Event, VOID *Context)
+{
+ EFI_STATUS Status;
+ AMI_EFI_KEY_DATA AmiKey;
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ AMI_EFI_KEY_DATA KeyFlush;
+ EFI_STATUS StatusFlush;
+ AMI_EFIKEYCODE_PROTOCOL *pKeyCodeProtocol;
+
+ Status = gBS->HandleProtocol(gST->ConsoleInHandle, &gAmiEfiKeycodeProtocolGuid, (void*)&pKeyCodeProtocol);
+ if (EFI_ERROR(Status)) return;
+#endif
+
+ if ( gST->ConIn == NULL )
+ return;
+
+ if ( gEnterSetup || gBootFlow )
+ return;
+ do
+ {
+#if SETUP_SUPPORT_KEY_MONITORING
+ if(gLegacyKeys)
+ {
+ if(gLegacyKeys & SETUP_ENTRY_KEY_BIT)
+ PrintEnterSetupMessage();
+#if SETUP_BBS_POPUP_ENABLE
+ else if (gLegacyKeys & POPUP_ENTRY_KEY_BIT) {
+ PrintEnterBBSPopupMessage ();
+ gBootFlow = BOOT_FLOW_CONDITION_BBS_POPUP;
+ }
+#endif
+#if SETUP_OEM_KEY1_ENABLE
+ else if (gLegacyKeys & OEM_KEY1_BIT)
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY1;
+#endif
+#if SETUP_OEM_KEY2_ENABLE
+ else if (gLegacyKeys & OEM_KEY2_BIT)
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY2;
+#endif
+#if SETUP_OEM_KEY3_ENABLE
+ else if (gLegacyKeys & OEM_KEY3_BIT)
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY3;
+#endif
+#if SETUP_OEM_KEY4_ENABLE
+ else if (gLegacyKeys & OEM_KEY4_BIT)
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY4;
+#endif
+ }
+#endif
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ Status = pKeyCodeProtocol->ReadEfikey( pKeyCodeProtocol, &AmiKey );
+
+ // If it Partial Key make the Status as Error to ignore
+ // the Partial Key.
+ if((AmiKey.KeyState.KeyToggleState & KEY_STATE_EXPOSED) == KEY_STATE_EXPOSED) //EIP81959 - Ignoring Partial keys
+ if( (!EFI_ERROR( Status )) && (AmiKey.Key.ScanCode==0) && (AmiKey.Key.UnicodeChar==0))
+ Status = EFI_NOT_READY;
+
+ if ( ! EFI_ERROR( Status ) )
+ {
+ do
+ {
+ StatusFlush = pKeyCodeProtocol->ReadEfikey( pKeyCodeProtocol, &KeyFlush );
+ // If it Partial Key make the Status as Error to ignore
+ // the Partial Key.
+ if((KeyFlush.KeyState.KeyToggleState & KEY_STATE_EXPOSED) == KEY_STATE_EXPOSED) //EIP81959 - Ignoring Partial keys
+ if( (!EFI_ERROR( Status )) && (KeyFlush.Key.ScanCode==0) && (KeyFlush.Key.UnicodeChar==0))
+ break;
+ } while ( ! EFI_ERROR( StatusFlush ) );
+ }
+
+#else
+ Status = gST->ConIn->ReadKeyStroke( gST->ConIn, &AmiKey.Key );
+#endif
+
+ if ( ! EFI_ERROR( Status ))
+ {
+ if(
+ ( (SETUP_ENTRY_UNICODE == AmiKey.Key.UnicodeChar)
+ &&(SETUP_ENTRY_SCAN == AmiKey.Key.ScanCode)
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ && (TSE_CHECK_SHIFTSTATE(AmiKey.KeyState.KeyShiftState, SETUP_ENTRY_SHIFT_STATE))
+#endif
+ )
+#if SETUP_ALT_ENTRY_ENABLE
+ || ( (SETUP_ALT_ENTRY_UNICODE == AmiKey.Key.UnicodeChar)
+ && (SETUP_ALT_ENTRY_SCAN == AmiKey.Key.ScanCode)
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+ && (TSE_CHECK_SHIFTSTATE(AmiKey.KeyState.KeyShiftState, SETUP_ALT_ENTRY_SHIFT_STATE))
+#endif
+ )
+#endif
+ )
+
+ {
+ CheckandDeactivateSoftkbd();// EIP62763 : Check and Deactivate if softkbd present
+ PrintEnterSetupMessage();
+ }
+#if SETUP_BBS_POPUP_ENABLE
+ else if ( (AmiKey.Key.UnicodeChar == POPUP_MENU_ENTRY_UNICODE)
+ && (AmiKey.Key.ScanCode == POPUP_MENU_ENTRY_SCAN)
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+#ifdef POPUP_MENU_ENTRY_SHIFT_STATE
+ && (TSE_CHECK_SHIFTSTATE (AmiKey.KeyState.KeyShiftState, POPUP_MENU_ENTRY_SHIFT_STATE))
+#endif
+#endif
+ )
+ {
+ CheckandDeactivateSoftkbd();// EIP62763 : Check and Deactivate if softkbd present
+ PrintEnterBBSPopupMessage ();
+ gBootFlow = BOOT_FLOW_CONDITION_BBS_POPUP;
+ }
+#endif
+#if EFI_SPECIFICATION_VERSION>0x20000
+ else if (CheckforHotKey (AmiKey)) //EIP: 62631 checking for hot boot keys
+ {
+ gBootFlow = BOOT_FLOW_HOTKEY_BOOT;
+ }
+#endif
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+#if SETUP_OEM_KEY1_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY1_UNICODE, SETUP_OEM_KEY1_SCAN,
+ SETUP_OEM_KEY1_EFIKEY, SETUP_OEM_KEY1_SHIFT, SETUP_OEM_KEY1_TOGGLE))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY1;
+#endif
+
+#if SETUP_OEM_KEY2_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY2_UNICODE, SETUP_OEM_KEY2_SCAN,
+ SETUP_OEM_KEY2_EFIKEY, SETUP_OEM_KEY2_SHIFT, SETUP_OEM_KEY2_TOGGLE))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY2;
+#endif
+
+#if SETUP_OEM_KEY3_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY3_UNICODE, SETUP_OEM_KEY3_SCAN,
+ SETUP_OEM_KEY3_EFIKEY, SETUP_OEM_KEY3_SHIFT, SETUP_OEM_KEY3_TOGGLE))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY3;
+#endif
+
+#if SETUP_OEM_KEY4_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY4_UNICODE, SETUP_OEM_KEY4_SCAN,
+ SETUP_OEM_KEY4_EFIKEY, SETUP_OEM_KEY4_SHIFT, SETUP_OEM_KEY4_TOGGLE))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY4;
+#endif
+
+#else // if no TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+#if SETUP_OEM_KEY1_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY1_UNICODE, SETUP_OEM_KEY1_SCAN))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY1;
+#endif
+
+#if SETUP_OEM_KEY2_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY2_UNICODE, SETUP_OEM_KEY2_SCAN))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY2;
+#endif
+
+#if SETUP_OEM_KEY3_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY3_UNICODE, SETUP_OEM_KEY3_SCAN))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY3;
+#endif
+
+#if SETUP_OEM_KEY4_ENABLE
+ else if (CheckOEMKey(&AmiKey, SETUP_OEM_KEY4_UNICODE, SETUP_OEM_KEY4_SCAN))
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY4;
+#endif
+#endif
+ else if (CheckOEMKeyCallback(&AmiKey) )
+ gBootFlow = BOOT_FLOW_CONDITION_OEM_KEY_CALLBACK;
+#ifndef STANDALONE_APPLICATION
+ else if ( ( AmiKey.Key.UnicodeChar == SETUP_TOGGLE_KEY_UNICODE )
+ && ( AmiKey.Key.ScanCode == SETUP_TOGGLE_KEY_SCANCODE) )
+ {
+ if ( gQuietBoot )
+ {
+ gQuietBoot = FALSE;
+ MouseStop();//EIP 62763 : Stopping the mouse before cleanuplogo when TAB key pressed
+ CleanUpLogo();
+ SwitchToPostScreenHook();//EIP-111415 SwitchToPostScreenHook
+ InitPostScreen();
+ }
+ }
+#endif
+ }
+ } while ( ! EFI_ERROR( Status ) );
+
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForClick
+//
+// Description: This function is a hook called to perform specific
+// action for a POST hot key. This function is called
+// periodically. This function is available as ELINK.
+//
+// Input: Event: Timer event.
+// Context: Event context; always NULL
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CheckForClick (EFI_EVENT Event, VOID *Context)
+{
+#if MINISETUP_MOUSE_SUPPORT
+ INT32 Button_Status=0;
+
+ if(TSEMouseIgnoreMouseActionHook())
+ {
+ return;// EIP62763 : Check for softkbd, if present return
+ }
+ if(TSEMouse!=NULL)
+ {
+ TSEMouse->MousePoll(TSEMouse);
+ TSEMouse->GetButtonStatus(TSEMouse,&Button_Status);
+
+ if (TSE_POST_STATUS_PROCEED_TO_BOOT == gPostStatus) ////EIP-140123 To StopclickEvent andd avoid displaying softkbd when Proceed_To_Boot
+ StopClickEvent();
+
+ if(((Button_Status == TSEMOUSE_RIGHT_CLICK)||(Button_Status == TSEMOUSE_LEFT_DCLICK)||(Button_Status == TSEMOUSE_LEFT_CLICK))&&(!TSEMouseIgnoreMouseActionHook()))
+ {
+ TSEStringReadLoopEntryHook();
+ StopClickEvent();
+ }
+
+ }
+#endif
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeforeLegacyBootLaunch
+//
+// Description: This function is a hook called before launching
+// legacy boot option. This function is available as
+// ELINK. In the generic implementation this function is
+// empty. OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BeforeLegacyBootLaunch(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AfterLegacyBootLaunch
+//
+// Description: This function is a hook called after launching
+// legacy boot option. This function is available as
+// ELINK. In the generic implementation this function is
+// empty. OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AfterLegacyBootLaunch(VOID)
+{
+}
+VOID MouseDestroy(VOID);
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeforeEfiBootLaunch
+//
+// Description: This function is a hook called before launching EFI
+// boot option. This function is available as ELINK. In
+// the generic implementation this function is empty.
+// OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BeforeEfiBootLaunch(VOID)
+{
+ StopClickEvent();//EIP 86253 : Mouse and SoftKbd does not work after displaying "No option to boot to" in POST
+ MouseDestroy();
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AfterEfiBootLaunch
+//
+// Description: This function is a hook called after launching EFI
+// boot option. This function is available as ELINK. In
+// the generic implementation this function is empty.
+// OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AfterEfiBootLaunch(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SavedConfigChanges
+//
+// Description: This function is a hook called after setup utility
+// saves changes based on user input. This function is
+// available as ELINK. In the generic implementation
+// this function is empty. OEMs may choose to do
+// additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SavedConfigChanges(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadedConfigDefaults
+//
+// Description: This function is a hook called after setup utility
+// loaded config defaults based on user input. This
+// function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LoadedConfigDefaults(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TimeOutLoopHook
+//
+// Description: This function is a hook called in every iteration
+// (not every second) while TSE is waiting for POST time
+// out. This function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TimeOutLoopHook(VOID)
+{
+}
+
+VOID HiiGetEfiKey(CHAR16 *PwKey);
+///////////////////////////////////////////////////////////////////
+////////PasswordEncode moved to PasswordEncode module//////////////
+///////////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetControlColors
+//
+// Description: This function is a hook called when colour of a
+// control has to be decided. This function is available
+// as ELINK. OEMs may choose to use different colour
+// combination.
+//
+// Input: BGColor: Back ground colour
+// FGColor: Fore ground colour
+// SecBGColor: Secondary back ground colour used for
+// time, date and menu
+// SecFGColor: Secondary fore ground colour used for
+// time, date and menu
+// SelBGColor: Selected back ground colour
+// SelFGColor: Selected fore ground colour
+// NSelBGColor: Not selected back ground colour
+// NSelFGColor: Not selected fore ground colour
+// LabelBGColor: Label back ground colour
+// LabelFGColor: Label fore ground colour
+// NSelLabelFGColor: Not selected label fore ground
+// EditBGColor: Edit box back ground
+// EditFGColor: Edit box fore ground
+// PopupFGColor: Popup fore ground
+// PopupBGColor: Popup back ground
+//
+// Output: EFI_STATUS: always EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetControlColors(UINT8 *BGColor, UINT8 *FGColor, UINT8 *SecBGColor, UINT8 *SecFGColor,
+ UINT8 *SelBGColor, UINT8 *SelFGColor, UINT8 *NSelBGColor, UINT8 *NSelFGColor,
+ UINT8 *LabelBGColor, UINT8 *LabelFGColor,UINT8 *NSelLabelFGColor, UINT8 *EditBGColor, UINT8 *EditFGColor,
+ UINT8 *PopupFGColor, UINT8 *PopupBGColor)
+{
+ if(FGColor !=NULL) *FGColor = Colors.FGColor ;
+ if(BGColor !=NULL) *BGColor = Colors.BGColor ;
+
+ if(SecFGColor !=NULL) *SecFGColor = Colors.SecFGColor ;
+ if(SecBGColor !=NULL) *SecBGColor = Colors.SecBGColor ;
+
+ if(SelFGColor !=NULL) *SelFGColor = Colors.SelFGColor ;
+ if(SelBGColor !=NULL) *SelBGColor = Colors.SelBGColor ;
+
+ if(NSelFGColor !=NULL) *NSelFGColor = Colors.NSelFGColor ;
+ if(NSelBGColor !=NULL) *NSelBGColor = Colors.NSelBGColor ;
+
+ if(LabelFGColor !=NULL) *LabelFGColor = Colors.LabelFGColor ;
+ if(LabelBGColor !=NULL) *LabelBGColor = Colors.LabelBGColor ;
+
+ if(NSelLabelFGColor !=NULL) *NSelLabelFGColor = Colors.NSelLabelFGColor ;
+
+ if(EditFGColor !=NULL) *EditFGColor = Colors.EditFGColor ;
+ if(EditBGColor !=NULL) *EditBGColor = Colors.EditBGColor ;
+
+ if(PopupFGColor !=NULL) *PopupFGColor = Colors.PopupFGColor ;
+ if(PopupBGColor !=NULL) *PopupBGColor = Colors.PopupBGColor ;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InvalidActionHook
+//
+// Description: This function is the hook call the appropriate InvalidActions function.
+// OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InvalidActionHook(VOID)
+{
+ /// Call the Invalid action function (Ex: Beep )
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadedUserDefaults
+//
+// Description: This function is a hook called after setup utility
+// loaded user defaults based on user input. This
+// function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LoadedUserDefaults(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadedBuildDefaults
+//
+// Description: This function is a hook called after setup utility
+// loaded Oem defaults based on user input. This
+// function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LoadedBuildDefaults(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadedPreviousValues
+//
+// Description: This function is a hook called after setup utility
+// loaded previously saved values based on user input. This
+// function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LoadedPreviousValues(VOID)
+{
+ //UpdateControlStatus(TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetupConfigModified
+//
+// Description: This function is a hook called after some control
+// modified in the setup utility by user. This
+// function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetupConfigModified(VOID)
+{
+ //UpdateControlStatus(TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadSetupDefaults
+//
+// Description: This function is a hook called when user loads the manufacturing
+// or optimal defaults. This function is
+// available as ELINK. OEMs may override the function and
+// decide the policy.
+//
+// Input: defaults : (NVRAM_VARIABLE *)optimal or manufacturing
+// data : Messagebox
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID _LoadDefaults( NVRAM_VARIABLE *defaults, UINTN data );
+VOID LoadSetupDefaults (VOID *defaults, UINTN data )
+{
+
+ _LoadDefaults((NVRAM_VARIABLE *)defaults, data );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetupConfigModified
+//
+// Description: This function is a hook called after some control
+// modified in the setup utility by user. This
+// function is available as ELINK. In the generic
+// implementation this function is empty. OEMs may
+// choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PreSystemResetHook(VOID)
+{
+ ///to have the oem customizations just before resetting
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemKey1Hook
+//
+// Description: This function is a hook called when user activates
+// configurable post hot key 1. This function is
+// available as ELINK. Generic implementation is empty.
+// OEMs may choose to use different logic here.
+//
+// Input: bootFlowPtr: Boot flow entry that triggered this call
+//
+// Output: always EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OemKey1Hook ( BOOT_FLOW *bootFlowPtr )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ //
+ // Add code here on enabling SETUP_OEM_KEY1_ENABLE for callback
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemKey2Hook
+//
+// Description: This function is a hook called when user activates
+// configurable post hot key 2. This function is
+// available as ELINK. Generic implementation is empty.
+// OEMs may choose to use different logic here.
+//
+// Input: bootFlowPtr: Boot flow entry that triggered this call
+//
+// Output: always EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OemKey2Hook ( BOOT_FLOW *bootFlowPtr )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ //
+ // Add code here on enabling SETUP_OEM_KEY2_ENABLE for callback
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemKey3Hook
+//
+// Description: This function is a hook called when user activates
+// configurable post hot key 3. This function is
+// available as ELINK. Generic implementation is empty.
+// OEMs may choose to use different logic here.
+//
+// Input: bootFlowPtr: Boot flow entry that triggered this call
+//
+// Output: always EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OemKey3Hook ( BOOT_FLOW *bootFlowPtr )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ //
+ // Add code here on enabling SETUP_OEM_KEY3_ENABLE for callback
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemKey4Hook
+//
+// Description: This function is a hook called when user activates
+// configurable post hot key 4. This function is
+// available as ELINK. Generic implementation is empty.
+// OEMs may choose to use different logic here.
+//
+// Input: bootFlowPtr: Boot flow entry that triggered this call
+//
+// Output: always EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OemKey4Hook ( BOOT_FLOW *bootFlowPtr )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ //
+ // Add code here on enabling SETUP_OEM_KEY4_ENABLE for callback
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MapControlMouseAction
+//
+// Description: This function is a hook called inside setup utility
+// to determine the action to be taken for a particular
+// Mouse Click. This function is available as ELINK. OEMs
+// may choose to have a different action or a different
+// mouse click.
+//
+// Input: MOUSE_INFO *pMouseInfo
+//
+// Output: CONTROL_ACTION: enumeration defined in commonoem.h.
+// Input EFI_INPUT_KEY has to mapped to one of the
+// enumerations in CONTROL_ACTION.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CONTROL_ACTION MapControlMouseAction(MOUSE_INFO *pMouseInfo)
+{
+ if(pMouseInfo!=NULL)
+ {
+ if(TSEMOUSE_RIGHT_CLICK == pMouseInfo->ButtonStatus)
+ return ControlActionAbort;
+#if SINGLE_CLICK_ACTIVATION //EIP74141 providing select option for single click too
+ if(TSEMOUSE_LEFT_DCLICK == pMouseInfo->ButtonStatus || TSEMOUSE_LEFT_CLICK == pMouseInfo->ButtonStatus)
+ return ControlActionSelect;
+#else
+ if(TSEMOUSE_LEFT_CLICK == pMouseInfo->ButtonStatus)
+ return ControlActionChoose;
+
+ if(TSEMOUSE_LEFT_DCLICK == pMouseInfo->ButtonStatus)
+ return ControlActionSelect;
+#endif
+ if(TSEMOUSE_LEFT_DOWN == pMouseInfo->ButtonStatus) //EIP74968
+ return ControlMouseActionLeftDown;
+
+ if(TSEMOUSE_LEFT_UP == pMouseInfo->ButtonStatus) //EIP74968
+ return ControlMouseActionLeftUp;
+
+ }
+ return ControlActionUnknown;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessProceedToBootNow
+//
+// Description: This function is a hook called when Boots from
+// BBS popup or Bootoverride page.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessProceedToBootNow(VOID)
+{
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessConOutAvailable
+//
+// Description: This function is a hook called when TSE determines
+// that console out is available. This function is available
+// as ELINK.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessConOutAvailable(VOID)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FixSubPageAsRootPageList
+//
+// Description: This function Fixes the SubPage as root pages from
+// AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FixSubPageAsRootPageList()
+{
+ UINTN RootPageListCount = sizeof(RootPageList) / sizeof (HII_FORM_ADDRESS);
+ UINTN i,j;
+ PAGE_INFO *info;
+ PAGE_ID_INFO *pageIdInfo;
+ // Support to Handle some child pages as root pages.
+ for(j=0; j<RootPageListCount;j++)
+ {
+ for ( i = 0; i < (UINTN)gPages->PageCount; i++ ) // EIP118410
+ {
+ info = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[i]);
+
+ // To Make Page as root
+ if( info->PageFormID == RootPageList[j].formId)
+ {
+ // If Handle is not null compare. If it null Ignore
+ if(RootPageList[j].Handle != NULL)
+ {
+ if(info->PageHandle != RootPageList[j].Handle)
+ continue;
+ }
+ pageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[info->PageIdIndex]);
+
+ if( EfiCompareGuid(&pageIdInfo->PageGuid,&RootPageList[j].formsetGuid) )//Compare Guid
+ info->PageParentID =0;
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FixSubPageAsRootPageList
+//
+// Description: This function Fixes the Hides pages from
+// AMITSE_HIDDEN_PAGE_LIST
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FixHiddenPageList(VOID)
+{
+ UINTN HiddenPageListCount = sizeof(HiddenPageList) / sizeof (HII_FORM_ADDRESS);
+ UINTN i,j;
+ PAGE_INFO *info;
+ PAGE_ID_INFO *pageIdInfo;
+ // To Hide Pages
+ for(j=0; j<HiddenPageListCount;j++)
+ {
+ for ( i = 0; i < (UINTN)gPages->PageCount; i++ ) // EIP118410
+ {
+ info = (PAGE_INFO*)((UINTN)gApplicationData + gPages->PageList[i]);
+
+ if( info->PageFormID == HiddenPageList[j].formId)
+ {
+ // If Handle is not null compare. If it null Ignore
+ if(RootPageList[j].Handle != NULL)
+ {
+ if(info->PageHandle != HiddenPageList[j].Handle)
+ continue;
+ }
+ pageIdInfo = (PAGE_ID_INFO *)(((UINT8 *) gPageIdList) + gPageIdList->PageIdList[info->PageIdIndex]);
+
+ if( EfiCompareGuid(&pageIdInfo->PageGuid,&HiddenPageList[j].formsetGuid) )//Compare Guid
+ {
+ info->PageFlags.PageVisible = TRUE;
+ /* This is needed as the PageDynamic is true if the IFR page is added dynamically. Then it will be shown under Dynamic pages. By making PageDynamic as FALSE we can make sure it is not shown anywere. */
+ info->PageFlags.PageDynamic = FALSE;
+ }
+ }
+ }
+ }
+}
+
+VOID TseUpdateRootPageOrder(VOID);
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessUIInitHook
+//
+// Description: This function is a hook called just before creating
+// the setup application for oem customizations. This function is
+// available as ELINK. OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessUIInitHook(VOID)
+{
+ CheckandDeactivateSoftkbd (); //EIP82552 Deactivating softkbd when time out occurs in post and enters into setup
+#if AMITSE_SUBPAGE_AS_ROOT_PAGE_LIST_SUPPORT
+ FixSubPageAsRootPageList ();
+#endif
+#if AMITSE_HIDE_ROOT_PAGE
+ FixHiddenPageList ();
+#endif
+ TseUpdateRootPageOrder();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AfterInitPostScreen
+//
+// Description: This function is a hook called After post screen is initilzed.
+// This function is available as ELINK. In the generic implementation this function
+// is empty. OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AfterInitPostScreen(VOID)
+{
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TseUpdateRootPageOrder
+//
+// Description: This function is to update the Root page order from the specified elink.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID TseUpdateRootPageOrder(VOID)
+{
+
+#if AMITSE_ROOT_PAGE_ORDER_SUPPORT
+
+ UINTN RootPageOrderCount = sizeof(RootPageOrder) / sizeof (HII_FORM_ADDRESS);
+ UINTN j,k;
+ EFI_GUID gSetupPageOrderGuid = SETUP_ROOT_PAGE_ORDER_GUID, NullGuid = NULL_GUID;
+ UINT32 *currentBootFlow;
+ UINTN size = 0;
+ UINT32 BootFlow = BOOT_FLOW_CONDITION_NORMAL;
+
+ //EIP166682 gBootFlow is changing constantly so better get it from NVRAM and proceed
+ currentBootFlow = VarGetNvramName( L"BootFlow", &_gBootFlowGuid, NULL, &size );
+ if (NULL != currentBootFlow)
+ {
+ BootFlow = *currentBootFlow;
+ MemFreePointer ((VOID **)&currentBootFlow);
+ }
+
+ if((1 == RootPageOrderCount)&&(EfiCompareGuid(&NullGuid,&RootPageOrder[0].formsetGuid)))
+ return;
+
+ if(gRootPageOrder!=NULL)
+ return;
+
+ gRootPageOrder = EfiLibAllocateZeroPool (RootPageOrderCount * sizeof (HII_FORM_ADDRESS));
+ if (NULL == gRootPageOrder)
+ return;
+ // To Hide Pages
+ for(j=0; j<RootPageOrderCount;j++)
+ {
+ if((EfiCompareGuid(&gSetupPageOrderGuid,&RootPageOrder[j].formsetGuid))&&(RootPageOrder[j].formId == BootFlow))
+ {
+ k = j + 1;
+ while(!((EfiCompareGuid(&gSetupPageOrderGuid,&RootPageOrder[k].formsetGuid)) || (EfiCompareGuid(&NullGuid,&RootPageOrder[k].formsetGuid))))
+ {
+ gBS->CopyMem (&gRootPageOrder[gRootPageOrderIndex], &RootPageOrder[k], sizeof (HII_FORM_ADDRESS));
+ gRootPageOrderIndex ++;
+ gIsRootPageOrderPresent = TRUE;
+ k ++;
+ }
+ break;
+ }
+ }
+
+ //EIP166682 If root page ordering is not found for any bootflow then trying for BOOT_FLOW_CONDITION_NORMAL bootflow. Helpful for BOOT_FLOW_CONDITION_OEM_KEY1 etc.,,
+ if ( (FALSE == gIsRootPageOrderPresent) && (BOOT_FLOW_CONDITION_NORMAL != BootFlow) )
+ {
+ for(j=0; j<RootPageOrderCount;j++)
+ {
+ if ( (EfiCompareGuid (&gSetupPageOrderGuid,&RootPageOrder[j].formsetGuid)) && (RootPageOrder[j].formId == BOOT_FLOW_CONDITION_NORMAL) )
+ {
+ k=++j;
+ while (!( (EfiCompareGuid (&gSetupPageOrderGuid,&RootPageOrder[k].formsetGuid)) || (EfiCompareGuid(&NullGuid,&RootPageOrder[k].formsetGuid)) ) )
+ {
+ gBS->CopyMem (&gRootPageOrder[gRootPageOrderIndex], &RootPageOrder[k], sizeof (HII_FORM_ADDRESS));
+ gRootPageOrderIndex ++;
+ gIsRootPageOrderPresent = TRUE;
+ k ++;
+ }
+ break;
+ }
+ }
+ }
+#endif
+}
+//EIP-111415 SwitchToPostScreenHook Start
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SwitchToPostScreen
+//
+// Description: This function is a hook called during SwitchToPostScreen post.
+// This function is available as ELINK. In the generic implementation this function
+// is empty. OEMs may choose to do additional logic here.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SwitchToPostScreen(VOID)
+{
+
+}
+//EIP-111415 SwitchToPostScreenHook Ends
+
+//EIP-139099 Start
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------------------------
+// Procedure: IsHideFormsetsWithClassGuid
+//
+// Description: This function filter formset and display formset based on ClassGUID mentioned in elink AMITSE_FILTER_CLASSGUID_FORMSETS
+//
+// Input: EFI_IFR_FORMSET. Formset to compare with elink classGuid.
+//
+// Output: BOOLEAN. Return TRUE formset matches with elink ClassGuid else FALSE
+//
+//---------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ShowClassGuidFormsets (TSE_EFI_IFR_FORM_SET *FormSet )
+{
+#if SHOW_FORMSETS_WITH_CLASSGUID
+ UINT16 FilterListcount = sizeof(gFormSetClassGuidList) / sizeof (EFI_GUID);
+ UINT16 index = 0;
+
+ if (FormSet->ClassGuid)
+ {
+ for (index = 0; index < (FilterListcount-1); index++)//(FilterListcount-1) To avoid check with NULL guid
+ {
+ if ( EfiCompareGuid ( FormSet->ClassGuid, &gFormSetClassGuidList[index]) )
+ return TRUE;
+ }
+ return FALSE;
+ }
+#endif
+ return TRUE;//if token is disable
+}
+//EIP-139099 End
+
+//EIP-95647 Start
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------------------------
+// Procedure: HideDynamicFormsets
+//
+// Description: This function suppress dynamic formset mentioned in the elink AMITSE_SUPPRESS_DYNAMIC_FORMSET_LIST
+//
+// Input: GUID. Formset guid to compare with gSuppressDynamicFormsetList elink guids.
+//
+// Output: BOOLEAN. Return TRUE if any guid matches with gSuppressDynamicFormsetList elink else FALSE
+//
+//---------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN HideDynamicFormsets (EFI_GUID *FormSetGuid )
+{
+#if AMITSE_SUPPRESS_DYNAMIC_FORMSET
+ UINTN suppressDynamicFormsetListCount = sizeof(gSuppressDynamicFormsetList) / sizeof (EFI_GUID);
+ UINT16 index = 0;
+
+ if (FormSetGuid)
+ {
+ for (index = 0; index < (suppressDynamicFormsetListCount-1); index++)
+ {
+ if ( EfiCompareGuid ( FormSetGuid, &gSuppressDynamicFormsetList[index]) )
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+//EIP-95647 End
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+// Procedure: VariableHandleSuppressed
+//
+// Description: This function informs to match the handle or not for creating new variable using VAR_DYNAMICPARSING_HANDLESUPPRESS_LIST ELink
+//
+// Input: EFI_GUID *, CHAR16 *
+//
+// Output: BOOLEAN. Return TRUE handle matches with elink else FALSE
+//
+//-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR8* StrDup16to8(CHAR16 *String);
+INTN EfiStrCmp (IN CHAR16 *String, IN CHAR16 *String2);
+BOOLEAN VariableHandleSuppressed (EFI_GUID *VariableGuid, CHAR16 *VariableName)
+{
+#if SUPPRESS_HANDLE_FOR_VAR_CREATION
+ UINTN HandleSuppressListCount = sizeof (gHandleSuppressVarList)/sizeof (VAR_DYNAMICPARSING_HANDLESUPPRESS);
+ UINTN i = 0;
+ CHAR8 *VariableNameStr8 = (CHAR8 *)NULL;
+
+ VariableNameStr8 = StrDup16to8 (VariableName);
+ if (NULL == VariableNameStr8)
+ {
+ return FALSE;
+ }
+ for(i=0; i < HandleSuppressListCount; i++)
+ {
+ if ( (EfiCompareGuid(VariableGuid, &(gHandleSuppressVarList [i].VariableGuid))) && (Strcmp (VariableNameStr8, gHandleSuppressVarList [i].VariableName) ==0) )
+ {
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/AMITSE/commonoem.h b/Core/EM/AMITSE/commonoem.h
new file mode 100644
index 0000000..ec1cd37
--- /dev/null
+++ b/Core/EM/AMITSE/commonoem.h
@@ -0,0 +1,354 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+// $Archive: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/commonoem.h $
+//
+// $Author: Arunsb $
+//
+// $Revision: 18 $
+//
+// $Date: 5/02/14 5:45a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/AMITSE2_0/AMITSE/commonoem.h $
+//
+// 18 5/02/14 5:45a Arunsb
+// [TAG] EIP156258
+// [Category] Improvement
+// [Description] Providing ELINK option to suppress the handle
+// comparison on dynamic parsing
+// [Files] AMITSE.mak, AMITSE.sdl, commonoem.c, commonoem.h and Parse.c
+//
+// 17 3/06/13 12:24a Premkumara
+// [TAG] EIP111415
+// [Category] Improvement
+// [Description] Elink function for SETUP_TOGGLE_KEY_UNICODE function
+// [Files] HookAnchor.h, AMITSE.sdl, commonoem.c, Commonoem.h,
+// HookList.c, HookAnchor.c
+//
+// 16 10/18/12 5:31a Arunsb
+// Updated for 2.16.1235 QA submission
+//
+// 13 10/10/12 12:23p Arunsb
+// Synched the source for v2.16.1232 backup with Aptio
+//
+// 15 2/01/12 1:53a Arunsb
+// [TAG] EIP74968
+// [Category] Improvement
+// [Description] Support for mouse drag and drop to rearrange the items
+// in the Orderlist.
+// [Files] Ordlistbox.c, commonoem.c and commonoem.h
+//
+// 14 11/20/11 6:56a Rajashakerg
+// [TAG] EIP62763
+// [Category] Improvement
+// [Description] Utilize the Improvements done from mouse driver in
+// AMITSE
+// [Files] HookAnchor.h, TseCommon.h, AMITSE.sdl, CommonHelper.c,
+// commonoem.c, commonoem.h, buffer.c, globals.c, HookAnchor.c,
+// minisetup.h, notify.c, postmgmt.c, protocol.c, ezport.c, stylecommon.c,
+// Mouse.c, Action.c, Date.c, frame.c, MessageBox.c, minisetupext.c,
+// minisetupext.h, numeric.c, numeric.h, page.c, PopupEdit.c, PopupEdit.h,
+// PopupPassword.c, postmgmtext.c, time.c.
+//
+// 13 7/20/11 3:25p Rajashakerg
+// Removed the unwanted code for mouse hot click operation
+//
+// 11 6/29/11 1:03p Rajashakerg
+// [TAG] EIP47086
+// [Category] New Feature
+// [Description] Right clicking from the Main page is not exiting from
+// BIOS setup.
+//
+// [Files] minisetup.h, Ezport\style.h,Ezport\EzportBin.sdl,
+// Ezport\EzportBin.mak, Ezport\ezport.c, Ezport\EzportBin.cif,
+// EzportPlus\style.h, EzportPlus\EzportPlusBin.sdl, EzportPlusBin.mak,
+// EzportPlus\EzportPlusBin.cif, EzportPlus\ezportplus.c, Legacy\style.h,
+// Legacy\EzportPlusBin.sdl, Legacy\LegacyBin.mak, Legacy\LegacyBin.cif,
+// Legacy\legacy.c, TseLiteBin.sdl, TseLite.cif, Memo.c, frame.c,
+// application.h, application.c, commonoem.h, CommonHelper.c
+//
+// 10 6/22/11 7:18a Arunsb
+// [TAG] EIP 62631, 60128
+// [Category] New Feature
+// [Description] Hot key boot option in TSE as per UEFI spec. section
+// 3.1.6.
+// TSE_CHECK_SHIFTSTATE macro redefined to
+// CheckAdvShiftState
+// [Files] AMITSE.sdl, CommonHelper.c, commonoem.c, commonoem.h,
+// boot.c, hiistring20.c and hiistring21.c.
+//
+// 9 3/28/11 9:06p Madhans
+// [TAG] EIP41744
+// [Category] Improvement
+// [Description] SoftKeyBoard Support in TSE. and Support to Work with
+// new mouse driver(Label 07).
+// [Files] HookAnchor.h
+// AMITSE.sdl
+// CommonHelper.c
+// commonoem.c
+// commonoem.h
+// HookList.c
+// HookAnchor.c
+// Mouse.c
+// minisetupext.c
+// postmgmtext.c
+// minisetupext.h
+// PopupPassword.c
+// PopupString.c
+// TseLiteCommon.c
+//
+// 8 9/16/10 8:39p Madhans
+// Updated for TSE 2.10. Refer changelog.log for more deatils.
+//
+// 11 8/18/10 6:15p Mallikarjunanv
+// EIP-38089: Hook after pressing F2 key and before showing setup menu.
+//
+// 10 6/08/10 5:06p Blaines
+// Created new AMITSE hook (hook33), called when TSE determines that
+// console out is available.
+//
+// 9 4/13/10 6:01p Madhans
+// Eip: 33100 To create new hook for BootNowLaunching. (From bbsPopoup and
+// Boot override menu).
+//
+// 8 2/19/10 7:59a Mallikarjunanv
+// updated the year in copyright message
+//
+// 7 2/04/10 11:06p Madhans
+// Map Control Mouse Action Hook Added.
+//
+// 6 1/09/10 2:26a Mallikarjunanv
+// Updated TSE2.01 Release sources with coding standards
+//
+// 5 9/15/09 9:19a Sudhirv
+// added new hook entries for LoadSetupDefaults and PreResetSystem
+//
+// 4 7/30/09 4:16p Blaines
+// Fix for EIP #23127
+//
+// Item #8 : Shift + Tab handling.
+//
+// MapControlKeys() does not handle correctly because of
+// TSE_CHECK_SHIFTSTATE macro has problem.
+// ControlActionNextSelection is always became true so never checks
+// ControlActionPrevSelection.
+//
+// 3 6/24/09 6:33p Madhans
+// Coding Standards
+//
+// 2 6/24/09 11:52a Blaines
+// Coding standard update
+//
+// 1 6/09/09 9:52a Madhans
+// TSE 2.00.1201
+//
+// 1 6/04/09 7:49p Madhans
+// AMI TSE Advanced.
+//
+// 2 4/29/09 9:01p Madhans
+// Bug Fixes after unit Testing..
+//
+// 1 4/28/09 10:49p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 1 4/28/09 10:24p Madhans
+// Tse 2.0 Code complete Checkin.
+//
+// 2 1/30/09 6:06p Madhans
+// Function headers added.
+//
+//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: commonoem.h
+//
+// Description: header of commonoem.h
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _COMMONOEM_H_
+#define _COMMONOEM_H_
+
+typedef enum
+{
+ ControlActionUnknown,
+ ControlActionNextLeft,
+ ControlActionNextRight,
+ ControlActionNextUp,
+ ControlActionNextDown,
+ ControlActionPageUp,
+ ControlActionPageDown,
+ ControlActionNextSelection,
+ ControlActionPrevSelection,
+ ControlActionSelect,
+ ControlActionIncreament,
+ ControlActionDecreament,
+ ControlActionBackSpace,
+ ControlActionAbort,
+ ControlActionAlpha,
+ ControlActionNumeric,
+ ControlActionHelpPageUp,
+ ControlActionHelpPageDown,
+
+ ControlActionHome,
+ ControlActionEnd,
+ ControlActionChoose,
+ ControlMouseActionLeftDown,
+ ControlMouseActionLeftUp
+}CONTROL_ACTION;
+
+typedef struct _STYLECOLORS
+{
+ UINT8 FGColor;
+ UINT8 BGColor;
+ UINT8 SecFGColor;
+ UINT8 SecBGColor;
+ UINT8 SelFGColor;
+ UINT8 SelBGColor;
+ UINT8 NSelFGColor;
+ UINT8 NSelBGColor;
+ UINT8 LabelBGColor;
+ UINT8 LabelFGColor;
+ UINT8 NSelLabelFGColor;
+ UINT8 EditBGColor;
+ UINT8 EditFGColor;
+ UINT8 PopupFGColor;
+ UINT8 PopupBGColor;
+}STYLECOLORS;
+
+
+//For CLICK Event
+#define TSEMOUSE_NULL_CLICK 0
+#define TSEMOUSE_RIGHT_CLICK 1
+#define TSEMOUSE_LEFT_CLICK 2
+//#define TSEMOUSE_MIDDLE_CLICK 3
+#define TSEMOUSE_LEFT_DCLICK 4
+#define TSEMOUSE_RIGHT_DOWN 5
+#define TSEMOUSE_LEFT_DOWN 6
+//#define TSEMOUSE_MIDDLE_DOWN 7
+#define TSEMOUSE_RIGHT_UP 8
+#define TSEMOUSE_LEFT_UP 9
+//#define TSEMOUSE_MIDDLE_UP 10
+
+//Data Structure for Storing Mouse action
+typedef struct _MOUSE_INFO
+{
+ UINT32 Top;
+ UINT32 Left;
+ UINT32 ButtonStatus;
+}MOUSE_INFO;
+
+#if TSE_USE_AMI_EFI_KEYCODE_PROTOCOL
+#include <Protocol/AmiKeyCode.h>
+
+
+//Start EIP #23127 Item #8
+//EIP 60128 Ctrl+Alt+F6 also working as Ctrl+F6 or Alt+F6
+BOOLEAN CheckAdvShiftState (UINT32 AmiKeyShiftState, UINT32 CondShiftState);
+#define TSE_CHECK_SHIFTSTATE CheckAdvShiftState
+
+/*( (!(AmiKeyShiftSate &(~SHIFT_STATE_VALID)) && (!CondShiftState)) || \
+(((AmiKeyShiftSate &(~SHIFT_STATE_VALID)) & CondShiftState) == (CondShiftState & (~SHIFT_STATE_VALID))) || \
+((AmiKeyShiftSate == SHIFT_STATE_VALID) && (CondShiftState == SHIFT_STATE_VALID)) )*/
+//End EIP #23127 Item #8
+
+#else
+#ifndef _AMI_EFI_KEY_DATA_
+#define _AMI_EFI_KEY_DATA_
+typedef struct {
+ EFI_INPUT_KEY Key;
+} AMI_EFI_KEY_DATA;
+#endif
+#endif
+
+VOID DrawQuietBootLogo(VOID);
+BOOLEAN ProcessConInAvailability(VOID);
+VOID ProcessEnterSetup(VOID);
+VOID ProcessProceedToBoot(VOID);
+VOID MinisetupDriverEntryHook(VOID);
+VOID PostManagerHandShakeHook(VOID);
+CONTROL_ACTION MapControlKeys(AMI_EFI_KEY_DATA key);
+VOID CheckForKey( EFI_EVENT Event, VOID *Context );
+VOID CheckForClick( EFI_EVENT Event, VOID *Context );
+VOID BeforeLegacyBootLaunch(VOID);
+VOID AfterLegacyBootLaunch(VOID);
+VOID BeforeEfiBootLaunch(VOID);
+VOID AfterEfiBootLaunch(VOID);
+VOID SavedConfigChanges(VOID);
+VOID LoadedConfigDefaults(VOID);
+VOID TimeOutLoopHook(VOID);
+VOID PasswordEncode( CHAR16 *Password, UINTN MaxSize);
+EFI_STATUS SetControlColors(UINT8 *BGColor, UINT8 *FGColor, UINT8 *SecBGColor, UINT8 *SecFGColor,
+ UINT8 *SelBGColor, UINT8 *SelFGColor, UINT8 *NSelBGColor, UINT8 *NSelFGColor,
+ UINT8 *LabelBGColor, UINT8 *LabelFGColor,UINT8 *NSelLabelFGColor, UINT8 *EditBGColor, UINT8 *EditFGColor,
+ UINT8 *PopupFGColor, UINT8 *PopupBGColor);
+
+VOID InvalidActionHook(VOID);
+VOID LoadedUserDefaults(VOID);
+VOID LoadedBuildDefaults(VOID);
+VOID LoadedPreviousValues(VOID);
+VOID SetupConfigModified(VOID);
+VOID LoadSetupDefaults (VOID *defaults, UINTN data );
+VOID PreSystemResetHook(VOID);
+CONTROL_ACTION MapControlMouseAction(VOID *pMouseInfo);
+VOID ProcessProceedToBootNow(VOID);
+VOID ProcessConOutAvailable(VOID);
+VOID ProcessUIInitHook(VOID);
+VOID AfterInitPostScreen(VOID);
+VOID SwitchToPostScreen(VOID);//EIP-111415 SwitchToPostScreenHook
+
+
+
+#define MODIFIER_DUAL_KEYS 0x000000FF //For handling any oTf the two dual(ctrl, alt, shift and logo) keys pressed
+#define RIGHT_LEFT_SHIFT_PRESSED 0x00000003
+#define RIGHT_LEFT_CONTROL_PRESSED 0x0000000C
+#define RIGHT_LEFT_ALT_PRESSED 0x00000030
+#define RIGHT_LEFT_LOGO_PRESSED 0x000000C0
+
+
+#define EFI_MOUSE_DRIVER_PROTOCOL_GUID \
+{0xc7a7030c, 0xc3d8, 0x45ee, 0xbe, 0xd9, 0x5d, 0x9e, 0x76, 0x76, 0x29, 0x53}
+
+typedef struct
+{
+ EFI_GUID VariableGuid;
+ CHAR8 VariableName [50];
+}VAR_DYNAMICPARSING_HANDLESUPPRESS;
+
+#endif
+
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************// \ No newline at end of file
diff --git a/Core/EM/AMITSE/setup.ini b/Core/EM/AMITSE/setup.ini
new file mode 100644
index 0000000..e903f1c
--- /dev/null
+++ b/Core/EM/AMITSE/setup.ini
@@ -0,0 +1,533 @@
+[section]
+variablecount = 55 ; number of variables to parse
+guidCount = 19 ; this is the number of GUID's to parse
+refreshrate = 2 ; rate of refresh in 0.1 second intervals
+fakeVarKey = 64254 ; 0xfafe is the key for fake var
+;VariableAttrib = 7 ; default attribute for variables found in VFR's
+;DefultsCount = 1 ; default data that to set from this ini file.
+guid = EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9
+scrtoken1 = 0
+scrtoken2 = 2
+scrtoken3 = 3
+scrtoken4 = 4
+scrtoken5 = 0
+scrtoken6 = 0
+scrtoken7 = 0
+
+[files]
+filecount = 6
+file1 = Main.hpk
+file2 = Advanced.hpk
+file3 = Chipset.hpk
+file4 = Boot.hpk
+file5 = Security.hpk
+file6 = Exit.hpk
+
+[variable0]
+guid = EC87D643-EBA4-4BB5-A1E5-3F3E36B20DA9
+name = Setup
+flags = 7
+extFlags = 0
+key = 0 ; 0x0 id is for setup variable
+
+[variable1]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = Lang
+flags = 7
+extFlags = 1 ; no defaults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable2]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = Timeout
+flags = 7
+extFlags = 0
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable3]
+guid = C4CC0DE8-0687-4422-99C1-65351A5D5F95
+name = UserDefaults
+flags = 7
+extFlags = 0
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[Variable4]
+guid = ADDEBF82-A560-46B9-A280-78C6AB61AEDA
+name = ErrorManager
+flags = 0
+extFlags = 0
+key = 65535
+
+[Variable5]
+guid = c811fa38-42c8-4579-a9bb-60e94eddfb34
+name = AMITSESetup
+flags = 7
+extFlags = 0
+key = 65535
+
+[Variable6]
+guid = 3DD0DE67-02D7-4129-914A-9F377CC34B0D
+name = IDESecDev
+flags = 7
+extFlags = 0
+key = 65535
+
+[variable7]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = BootOrder
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable8]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652
+name = LegacyDevOrder
+flags = 3
+extFlags = 1 ; no defults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[Variable9]
+guid = F6C73719-F34C-479C-B32F-277FCBBCFE4F
+name = DelBootOption
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable10]
+guid = 19d96d3f-6a6a-47d2-b195-7b2432da3be2
+name = AddBootOption
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable11]
+guid = B4909CF3-7B93-4751-9BD8-5BA8220B9BB2
+name = BootManager
+flags = 7
+extFlags = 0
+key = 65535
+
+[Variable12]
+guid = 052E6EB0-F240-42C5-8309-45874545C6B4
+name = BootNowCount
+flags = 7
+extFlags = 0
+key = 65535
+
+[Variable13]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652
+name = LegacyDev
+flags = 1
+extFlags = 0
+key = 65535
+
+[Variable14]
+guid = 9CF0F18E-7C7D-49DE-B5AA-BBBAD6B21007
+name = AMICallback
+flags = 1
+extFlags = 0
+key = 65535
+
+[Variable15]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652
+name = LegacyGroup
+flags = 1
+extFlags = 0
+key = 65535
+
+[Variable16]
+guid = 052E6EB0-F240-42C5-8309-45874545C6B4
+name = SetupSaveState
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable17]
+guid = F4B2C007-94A1-4cd5-A710-F4141FCEBCA0
+name = OemTSEVar
+flags = 7
+key = 65535
+
+[Variable18]
+guid = B63BF800-F267-4f55-9217-E97FB3B69846
+name = DynamicPageCount
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable19]
+guid = 0885F288-418C-4be1-A6AF-8BAD61DA08FE
+name = DriverHlthEnable
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable20]
+guid = 7459A7D4-6533-4480-BBA7-79E25A4443C9
+name = DriverHealthCount
+flags = 2
+extFlags = 0
+key = 65535
+
+[Variable21]
+guid = 58279C2D-FB19-466e-B42E-CD437016DC25
+name = DrvHealthCtrlCnt
+flags = 2
+extFlags = 0
+key = 65535
+
+[variable22]
+guid = C0B4FB05-15E5-4588-9FE9-B3D39C067715
+name = DriverManager
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable23]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = DriverOrder
+flags = 3 ;variable attributes
+extFlags = 1 ; no defaults ;Extended attributes
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[variable24]
+guid = 7DF66C0F-D40A-4748-AC5A-6C0BEA786A1A
+name = AddDriverOption
+flags = 3 ;variable attributes
+extFlags = 1 ; no defaults ;Extended attributes
+key = 65535 ; 0xffff id is for minisetup variables use
+
+[Variable25]
+guid = 17A3C5DA-F51F-437c-91B6-002B6F262593
+name = DelDriverOption
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable26]
+guid = EDA2B104-7A10-4519-B0A1-EBA5C52ACFCE
+name = OemPortVar1
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable27]
+guid = EF402953-B819-4cc2-A44C-4C9B4CFBC889
+name = OemPortVar2
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable28]
+guid = 1D6F853E-0006-40d8-9B4B-79618A5733B0
+name = OemPortVar3
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable29]
+guid = 47E87E67-FBC0-4c01-9002-4A0A6ECB92FF
+name = OemPortVar4
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable30]
+guid = 2799A453-FC10-4334-9E66-D3D6EF09D0EE
+name = OemPortVar5
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable31]
+guid = D77A3FE1-51FE-4613-A81D-82AE24464CFD
+name = OemPortVar6
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable32]
+guid = B5CEC017-74CB-4e10-BAC3-924A4CC629C8
+name = OemPortVar7
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable33]
+guid = 78A6FB37-8F27-40a4-9C4E-9FC9E438D5E2
+name = OemPortVar8
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable34]
+guid = 8DAC5195-3FD5-4e32-9C2A-1A65BD699932
+name = OemPortVar9
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable35]
+guid = A6DB3378-CFD7-4bfd-A1C4-2709FEC52F8B
+name = OemPortVar10
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable36]
+guid = EA629472-D7C6-4c0e-8820-2B811C7EE3AF
+name = OemPortVar11
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable37]
+guid = 4CD97B67-12BB-4fc5-8B2A-580ADB6A6368
+name = OemPortVar12
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable38]
+guid = C03DDD47-DC0A-4319-9FEC-44B078C242E6
+name = OemPortVar13
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable39]
+guid = 2AAEC318-E84B-4e0b-BF41-AC65F17E9E2F
+name = OemPortVar14
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable40]
+guid = 1967167B-A13D-4e45-801B-A605D11946D5
+name = OemPortVar15
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable41]
+guid = 466A7291-50DF-4b40-A2EB-CEE67D5428C9
+name = OemPortVar16
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable42]
+guid = 4639A701-74F9-4635-B126-9FF048D6B0D0
+name = OemPortVar17
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable43]
+guid = EF02529C-A283-48cd-8D08-6A1E9C3C03D3
+name = OemPortVar18
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable44]
+guid = 4CD28F5E-4BBB-4602-ACB8-741BAA7EB313
+name = OemPortVar19
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable45]
+guid = 83C233EB-D01A-45d8-9FA1-AF40206FCC9B
+name = OemPortVar20
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable46]
+guid = 6169D4F6-0659-4fb5-B03C-3645D8C80DC8
+name = OemPortVar21
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable47]
+guid = 1C1EAB81-9229-42ac-B940-757C498A09ED
+name = OemPortVar22
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable48]
+guid = 0ECEDD30-67EC-4570-9EFB-308DE53EE93D
+name = OemPortVar23
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable49]
+guid = 913FA238-7B16-4b72-A5F0-815E7D2C8C1F
+name = OemPortVar24
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable50]
+guid = FE075D44-D9F1-4da1-AE6A-8250553CDE66
+name = OemPortVar25
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable51]
+guid = 471F5144-6037-4952-8B01-CFF586FDE6B3
+name = OemPortVar26
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable52]
+guid = 1318FED0-2765-42b5-803E-3215A3C093C5
+name = OemPortVar27
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable53]
+guid = FF5A0DC3-DFAC-434a-B3DF-FFD4C1EA7E41
+name = OemPortVar28
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+[Variable54]
+guid = 3F8DC333-CCD5-4e58-B8CF-7B9A8F31EA96
+name = OemPortVar29
+flags = 3
+extFlags = 1 ; no defaults
+key = 65535
+
+;
+;These are samples of how to add GUID information into this file
+;
+[GUID0]
+guid = B4909CF3-7B93-4751-9BD8-5BA8220B9BB2
+name = BootManager
+flags = 1
+key = 1
+
+[GUID1]
+guid = 052E6EB0-F240-42C5-8309-45874545C6B4
+name = BootNowCount
+flags = 1
+key = 1
+
+[GUID2]
+guid = A56074DB-65FE-45F7-BD21-2D2BDD8E9652 ;GUID for LegacyDevOrder & LegacyDev are same
+name = LegacyDevOrder
+flags = 1
+key = 7
+
+[GUID3]
+guid = 9CF0F18E-7C7D-49DE-B5AA-BBBAD6B21007
+name = AMICallback
+flags = 1
+key = 2
+
+[GUID4]
+guid = ADDEBF82-A560-46B9-A280-78C6AB61AEDA
+name = ErrorManager
+flags = 9
+key = 3
+
+[GUID5]
+guid = 8BE4DF61-93CA-11D2-AA0D-00E098032B8C
+name = LangCodes
+flags = 7
+key = 5
+
+[GUID6]
+guid = c57ad6b7-0515-40a8-9d21-551652854e37
+name = shell.efi|shellx64.efi|shellia64.efi
+flags = 6
+key = 0
+
+[GUID7]
+guid = 50064C83-F3D9-4270-B97B-BAC47B61E8DB
+name = shellpbm.efi
+flags = 6
+key = 0
+
+[GUID8]
+guid = 3DD0DE67-02D7-4129-914A-9F377CC34B0D
+name = IDESecDev
+flags = 1
+key = 8
+
+[GUID9]
+guid = 19d96d3f-6a6a-47d2-b195-7b2432da3be2
+name = AddBootOption
+flags = 0
+key = 9
+
+[GUID10]
+guid = F4B2C007-94A1-4cd5-A710-F4141FCEBCA0
+name = OemTSEVar
+flags = 1
+key = 10
+
+[GUID11]
+guid = B63BF800-F267-4f55-9217-E97FB3B69846
+name = DynamicPageCount
+flags = 0
+key = 14
+
+[GUID12]
+guid = 0885F288-418C-4be1-A6AF-8BAD61DA08FE
+name = DriverHlthEnable
+flags = 1
+key = 15
+
+[GUID13]
+guid = 7459A7D4-6533-4480-BBA7-79E25A4443C9
+name = DriverHealthCount
+flags = 1
+key = 16
+
+[GUID14]
+guid = 58279C2D-FB19-466e-B42E-CD437016DC25
+name = DrvHealthCtrlCnt
+flags = 1
+key = 17
+
+[GUID15]
+guid = C0B4FB05-15E5-4588-9FE9-B3D39C067715
+name = DriverManager
+flags = 0
+key = 18
+
+[GUID16]
+guid = ECFD4BCE-4279-40f8-BAF2-DCB79638D41E
+name = OemPortGuid1
+flags = 0
+key = 19
+
+[GUID17]
+guid = 23F69CD0-FF46-4db6-B982-63EDF1A901FF
+name = OemPortGuid2
+flags = 0
+key = 20
+
+[GUID18]
+guid = 8BDDF24B-2C8A-4360-A3BB-AEF094983BEA
+name = AMIDiag
+flags = 2
+key = 21
+
+;;syntax to set a default variable initial value from this ini file
+;[defaults0]
+;variable = 5 ;; variable number
+;mode = 0 ;; Standard (0) or Manufacturer (1)
+;offset = 80 ;; offset of the variable data
+;size = 1 ;; size of data to replace
+;data = 1 ;; Data to replace Format (Hex Bytes delimted by space)
diff --git a/Core/EM/AMITSE/setupdbg.h b/Core/EM/AMITSE/setupdbg.h
new file mode 100644
index 0000000..2927593
--- /dev/null
+++ b/Core/EM/AMITSE/setupdbg.h
@@ -0,0 +1,51 @@
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//*****************************************************************//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: setupdbg.h
+//
+// Description: Header file for string functionalities.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _SETUPDBG_H_
+#define _SETUPDBG_H_
+
+VOID SetupShowDebugScreen(VOID *app, VOID *hotkey, VOID *cookie );
+
+#define TSE_DEBUG_MESSAGES_GUID \
+ {0x408acdd4, 0xe088, 0x4bac, 0xa2, 0x53, 0x6c, 0x27, 0xcf, 0xd3, 0xd6, 0x1f }
+
+#endif /* _SETUPDBG_H_ */
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Building 200,Norcross, Georgia 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AInt13.c b/Core/EM/Ahci/AInt13.c
new file mode 100644
index 0000000..1df91f1
--- /dev/null
+++ b/Core/EM/Ahci/AInt13.c
@@ -0,0 +1,1366 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AInt13.c 25 11/24/14 11:59p Kapilporwal $
+//
+// $Revision: 25 $
+//
+// $Date: 11/24/14 11:59p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AInt13.c $
+//
+// 25 11/24/14 11:59p Kapilporwal
+// [TAG] EIP191939
+// [Category] Improvement
+// [Description] Issue about BIG_REAL_MODE_MMIO_ACCESS of AHCI module
+// [Files] AI13.bin
+// AHCIACC.ASM
+// AhciInt13Dxe.c
+// AhciInt13Dxe.dxs
+// AhciInt13Smm.c
+// AhciInt13Smm.cif
+// AhciInt13Smm.dxs
+// AhciInt13Smm.h
+// AhciInt13Smm.mak
+// AhciInt13Smm.sdl
+// AInt13.c
+// Aint13.cif
+// AInt13.h
+// AhciSmm.c
+// AhciSmm.h
+// AhciSmmProtocol.h
+//
+// 24 9/10/12 2:50a Rameshr
+// [TAG] EIP95440
+// [Category] Improvement
+// [Description] Add HddSecurity and HddSmart feature under UEFI Raid
+// driver mode
+// [Files] Ahcibus.c, Pahcibus.h, Aint13.c
+//
+// 23 8/02/12 8:11a Deepthins
+// [TAG] EIP93480
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AHCI legacy support module is corrupting the memory.
+// [RootCause] AHCI legacy support module is corrupting the memory as it
+// was using wrong offset for storing the base address.
+// [Solution] Properly calculating offset for storing the base address.
+// [Files] AINT13.EQU, AInt13.c, AInt13.h and AHCIACC.ASM
+//
+// 22 6/02/12 2:53a Anandakrishnanl
+// [TAG] EIP91233
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] pBS->CloseEvent(Event) has to be added in function of
+// SetEbdaAddressForPort() asit cabn handle the multiple legacy boot
+// events.
+// [RootCause] CloseEvent not handled properly as SetEbdaAddressForPort
+// will be re executed
+// [Solution] Event should be closed in SetEbdaAddressForPort when the
+// event callback happens
+// [Files] AInt13.c
+//
+// 21 4/24/12 12:53a Deepthins
+// [TAG] EIP86336
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Can't boot from AHCI if SATA_PORT_COUNT=12
+// [RootCause] The controller number was not updated in DEV_INFO_STRUC
+// for all the Hard Disk
+// [Solution] Updated the controller number in the DEV_INFO_STRUC for
+// all the AHCI devices.
+// [Files] AInt13.c, AInt13.h
+//
+// 20 1/13/12 12:15a Deepthins
+// [TAG] EIP78099
+// [Category] Improvement
+// [Description] Handle multiple AHCI controller in legacy.
+// [Files] Aint13.sdl , AInt13.c , AInt13.h , AHCIACC.ASM , AHCI.EQU ,
+// AINT13.bin (AHCIACC.ASM , AINT13.EQU)
+//
+// 19 11/29/11 4:23a Rameshr
+// [TAG] EIP76393
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Any time AHCI is starting when EBDA size is more than 64K,
+// the problem will show as memory corruption.
+// [RootCause] AHCI INT13 code does not use EBDA properly when at the
+// time of EBDA allocation current size of EBDA exceeds 64K
+// [Solution] Modified code to extend the width of EbdaStart offset from
+// 16-bit to 32-bit.
+// [Files] Aint13.asm, Ahcibsp.asm, Aint13.c, Aint13.h, Aint13.bin
+//
+// 18 6/06/11 2:04a Rameshr
+// [TAG]- EIP 57762
+// [Category]-IMPROVEMENT
+// [Description]- Please help to put SATA ODD PxCLB and PxCLBU to E820 and
+// below 1M.
+// [Files]- Aint13.c
+//
+// 17 2/10/11 10:49a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] Aint13.mak
+// AInt13.h
+// AInt13.c
+//
+// 16 6/21/10 5:31a Rameshr
+// AHCI Legacy booting through MMIO reg.
+// EIP 38444
+//
+// 15 4/16/10 4:18p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 14 7/08/09 5:28p Rameshr
+// Bugfix in ConfigureHddParameter function. EIP#23599
+//
+// 13 7/02/09 10:26a Olegi
+// Bugfix in ConfigureHddParameter function. EIP#23599
+//
+// 12 4/28/09 5:33p Rameshr
+//
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 11 11/26/08 12:24p Olegi
+// Added device handle into BBS table.
+//
+// 10 9/09/08 3:20p Michaela
+// Added AHCI_CD_CSM_ID_OFFSET for assigning
+// device numbers for CDs/DVDs in order to
+// avoid a CSM16 conflict with PATA CD devices, which
+// may be present on some systems
+//
+// 9 6/04/08 11:10a Olegi
+// Use externally defined GUIDs instead of redefining them.
+//
+// 8 5/28/08 9:42a Rameshraju
+// Updated the AMI Address.
+//
+// 7 5/13/08 4:31p Olegi
+// Changes related to the latest release of AI13.BIN
+//
+// 6 5/01/08 1:40p Olegi
+// Increase EBDA size by 1KB to be used in runtime for stack.
+//
+// 5 3/28/08 12:16p Michaela
+// updated copyright
+//
+// 4 28/02/08 6:12p Anandakrishnanl
+// Updated for device detection in AHCI mode.
+//
+// 3 2/09/08 4:41p Olegi
+// Modifications related to the changed AllocateEbda interface.
+//
+// 2 19/12/07 4:32p Anandakrishnanl
+// Transition from EDK AHCI driver to AMI AHCI driver.
+//
+// 1 12/07/07 11:17a Olegi
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+//
+// Name: AInt13.c
+// Description: AHCI Int13 structures initialization routines
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "Aint13.h"
+#include "AmiDxeLib.h"
+
+#include "Protocol\LegacyBiosExt.h"
+#include "Protocol\LegacyAhci.h"
+#include "Protocol\BlockIo.h"
+#include "Protocol\DevicePath.h"
+#include "AhciBus.h"
+
+EFI_STATUS InitDrivesInformation (VOID*, UINT16);
+
+EFI_AHCI_INT13_INIT_PROTOCOL gAint13;
+UINT32 EbdaStartOffset;
+
+VOID *gLegacyMemoryAddress;
+VOID *gImage;
+LEGACY16_TO_EFI_DATA_TABLE_STRUC *gLegacy16Data = 0;
+EFI_PCI_IO_PROTOCOL *gPciIo = NULL;
+UINT8 *gHddReadData;
+BOOLEAN gAint13InstallationExecuted = FALSE;
+
+EFI_STATUS InitAhciInt13Support();
+UINT8 gController=0;
+CONTROLLER_INFO_STRUC ControllerInfo[AHCI_CONTROLLER_COUNT];
+EFI_LEGACY_BIOS_EXT_PROTOCOL *gBiosExtensions = NULL;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: Ai13EntryPoint
+//
+// Description: Installs gAhciInt13Init protocol
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS Ai13EntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ gAint13.InitAhciInt13Support = InitAhciInt13Support;
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &gAint13ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gAint13
+ );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CountDrives
+//
+// Description: This routine returns the number of connected AHCI drives as well
+// as it fills the optional SATA_DEVICE_INTERFACE* buffer with the
+// device information.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+CountDrives(
+ IN EFI_HANDLE *HandleBuffer,
+ IN UINTN HandleCount,
+ IN VOID *Devices
+)
+{
+ EFI_STATUS Status;
+ DLINK *dlink;
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+ UINT16 Drives = 0;
+ UINTN n;
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+
+ //
+ // Go through all controllers, count the number of valid connected drives
+ //
+ for (n = 0; n < HandleCount; n++) {
+ Status = pBS->HandleProtocol(HandleBuffer[n], &gAciBusInitProtocolGuid, &AhciBusInterface);
+ if (EFI_ERROR(Status)) return Drives;
+
+ for (dlink = AhciBusInterface->SataDeviceList.pHead; dlink; dlink = dlink->pNext) {
+ SataDevInterface = OUTTER(dlink, SataDeviceLink, SATA_DEVICE_INTERFACE);
+ if (SataDevInterface->DeviceState == DEVICE_CONFIGURED_SUCCESSFULLY &&
+ (SataDevInterface->DeviceType == ATA || SataDevInterface->DeviceType == ATAPI)) {
+ if (Devices != NULL) {
+ *((UINTN*)Devices)++ = (UINTN)SataDevInterface;
+ }
+ Drives++;
+ }
+ }
+ }
+
+ return Drives;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetEbdaAddressForPort
+//
+// Description: This function will be called when Legacy boot Event Signled
+// This function will set the EBDA address for PxCLB and PxFB
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetEbdaAddressForPort (IN EFI_EVENT Event, IN VOID *Context)
+{
+ AHCI_BUS_PROTOCOL *AhciBusInterface=(AHCI_BUS_PROTOCOL*)Context;
+ UINT32 PortsImplemented;
+ UINT8 i, PortNumber;
+ UINT32 CurrentEbda;
+ UINT32 PortCommandListBaseAddr=0;
+ UINT32 PortFISBaseAddr=0;
+
+ PortsImplemented = AhciBusInterface->HBAPortImplemented;
+ PortNumber = 0;
+
+ //
+ // Find the EBDA Address from the EbdaStartOffset
+ //
+ if (EbdaStartOffset) {
+ CurrentEbda = (UINT32)(UINTN)(*(UINT16*)0x40e << 4);
+ EbdaStartOffset += CurrentEbda;
+ EbdaStartOffset += (1024-1);
+ PortCommandListBaseAddr = EbdaStartOffset & (~(1024-1));
+ PortFISBaseAddr=PortCommandListBaseAddr + 1024;
+ }
+
+ for (i=0; PortsImplemented; PortsImplemented>>=1, PortNumber++){
+ if (PortsImplemented & 1) {
+
+ //
+ // Clear Start
+ //
+ HBA_PORT_REG32_AND (AhciBusInterface->AhciBaseAddress, PortNumber, HBA_PORTS_CMD, ~(HBA_PORTS_CMD_ST));
+
+ //
+ // Program PxCLB and PxFB
+ //
+ HBA_PORT_WRITE_REG32 (AhciBusInterface->AhciBaseAddress,
+ PortNumber,
+ HBA_PORTS_CLB,
+ PortCommandListBaseAddr);
+
+ HBA_PORT_WRITE_REG32 (AhciBusInterface->AhciBaseAddress,
+ PortNumber, 0x0008,
+ PortFISBaseAddr);
+
+ i++;
+ }
+ }
+
+ pBS->CloseEvent(Event);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitAhciInt13Support
+//
+// Description: LegacyAhci driver API function. It initializes drive infomation
+// and places it in BBS table as well as in AHCI INT13 runtime area.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitAhciInt13Support()
+{
+ EFI_HANDLE *HandleBuffer = 0;
+ UINTN HandleCount = 0;
+ UINT16 DevCount = 0;
+ VOID *Devices;
+ EFI_STATUS Status;
+ EFI_EVENT LegacyEvent;
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+ SATA_DEVICE_INTERFACE *Device;
+
+
+ //
+ // First, find out if we have been called already. If yes - do not do anything
+ // since INT13 installation is not intended to be called multiple times.
+ //
+ if (gAint13InstallationExecuted) return EFI_SUCCESS;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gAciBusInitProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer);
+
+// ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) {
+ return EFI_SUCCESS;
+ }
+
+ DevCount = CountDrives(HandleBuffer, HandleCount, NULL);
+ //
+ // For the 1st time CountDrives was called to get the number of connected
+ // drives; for the 2nd time it will actually return the device information
+ //
+ if (DevCount == 0) return EFI_SUCCESS;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(VOID*)*DevCount, &Devices);
+ ASSERT_EFI_ERROR(Status);
+
+ CountDrives(HandleBuffer, HandleCount, Devices);
+
+ Status = InitDrivesInformation(Devices, DevCount);
+
+ //
+ // Program the EBDA Address on Legacy boot Event.
+ //
+ Device = *((SATA_DEVICE_INTERFACE**)Devices);
+ AhciBusInterface=Device->AhciBusInterface;
+ CreateLegacyBootEvent(TPL_CALLBACK, &SetEbdaAddressForPort, (VOID*)AhciBusInterface, &LegacyEvent);
+
+ pBS->FreePool(Devices);
+
+ gAint13InstallationExecuted = TRUE;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: GetNumberOfSectors
+//
+// Description: Returns the total number of sectors from IDENTIFY_DATA
+//
+// Input: IdendifyData - ptr to the IDENTIFY_DATA array
+//
+// Output: Total0 - lower DWORD of the total number of blocks
+// Total1 - higher WORD of the total number of blocks
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+GetNumberOfSectors(
+ IN UINT16 *IdentifyData,
+ OUT UINT32 *Total0,
+ OUT UINT16 *Total1
+)
+{
+ UINT32 d0 = 0;
+ UINT16 d1 = 0;
+
+ //
+ // Get total #of sectors
+ // Word-61, Word-60 = Total #of user addressable sectors
+ // Word-103, Word-102, Word-101, Word-100 = Max user LBA for 48bit LBA
+ //
+ d0 = *(UINT32*)((UINTN)IdentifyData+60*2); // get Words 60-61
+
+ //
+ // If 48-bit LBA enabled then get total number of sectors
+ // from words 100..102
+ //
+ if (IdentifyData[86] & 0x400) {
+ d0 = *(UINT32*)((UINTN)IdentifyData+100*2); // get Words 100-101
+ d1 = *(UINT16*)((UINTN)IdentifyData+102*2); // get Word 102
+ }
+
+ *Total0 = d0;
+ *Total1 = d1;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CalcTranslatedCyl
+//
+// Description: Returns the CHS-translated number of cylinders
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+CalcTranslatedCyl(
+ IN OUT UINT16 *Cyl,
+ IN OUT UINT8 *Heads,
+ IN OUT UINT8 *Sectors,
+ IN UINT32 TotalBlocks
+)
+{
+ UINT8 heads = *Heads;
+ UINT8 sec = *Sectors;
+ UINT16 cyl;
+
+ for (cyl=TotalBlocks/(UINT16)heads*(UINT16)sec; cyl>1024;) {
+ //
+ // Current xlat scheme does not make #of cylinders <= 1024, try next scheme
+ //
+ cyl = 1024;
+ if (heads == 0xFF) {
+ break; // Head limit reached
+ }
+ heads <<= 1; // Double the heads
+ if (heads == 0) heads = 0xFF;
+ }
+ *Heads = heads;
+ *Sectors = sec;
+ *Cyl = cyl;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: TranslateHdSec
+//
+// Description: This function returns the translated max #of heads (1-based),
+// number of cylinders and sectors/track.
+//
+// Input: Heads - Maximum head number (1-based)
+// Sectors - Sectors/track
+// Cyl - Number of cylinders
+// TotalBlocks - Total number of sectors
+//
+// Output: Cyl - Translated number of cylinders
+// Heads - Translated max head number (1-based)
+// Sectors - Translated number of sectors/track
+//
+// Notes: - If total #of sectors < 1032192 (i.e. FC000 hex),
+// translation is not needed.
+// - If total #of sectors <= 2064384 (i.e. 1F8000 hex),
+// use 63 SPT and 32 HD for translation.
+// - If total #of sectors <= 4128768 (i.e. 3F0000 hex),
+// use 63 SPT and 64 HD for translation.
+// - If total #of sectors <= 8257536 (i.e. 7E0000 hex),
+// use 63 SPT and 128 HD for translation, else
+// use 63 SPT and 255 HD for translation.
+// - In any case, check the parameters for maximum values allowed
+// by BIOS and ATA specs (i.e. 1024 cyl, 16 heads, 63 sec/track)
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+TranslateHdSec(
+ IN OUT UINT16 *Cyl,
+ IN OUT UINT8 *Heads,
+ IN OUT UINT8 *Sectors,
+ IN UINT32 TotalBlocks
+)
+{
+ UINT8 heads = *Heads;
+ UINT8 sec = *Sectors;
+ UINT16 cyl = *Cyl;
+
+ if (TotalBlocks >= 0xFC000) {
+ heads = 32; sec = 63;
+ if (TotalBlocks >= 0x1F8000) {
+ heads = 64; sec = 63;
+ if (TotalBlocks >= 0x3F0000) {
+ heads = 128; sec = 63;
+ if (TotalBlocks >= 0x7E0000) {
+ heads = 255; sec = 63;
+ }
+ }
+ }
+ CalcTranslatedCyl(&cyl, &heads, &sec, TotalBlocks);
+ }
+ else {
+ // hd <= 528MB, no translation is needed normally
+ // check maxm value of the parameters
+ if (cyl>1024 || heads>16 || sec>63) {
+ heads = 32; sec = 63;
+ CalcTranslatedCyl(&cyl, &heads, &sec, TotalBlocks);
+ }
+ }
+ *Heads = heads;
+ *Sectors = sec;
+ *Cyl = cyl;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: ConfigureHddParameter
+//
+// Description: This function fills the DEV_PARAM information for the drive.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ConfigureHddParameter(
+ IN EFI_BLOCK_IO_PROTOCOL *BlkIo,
+ IN UINT16 *IdentifyData,
+ IN OUT DEV_PARAM_STRUC *DevParam,
+ IN DEV_INFO_STRUC *DevInfo,
+ IN DEV_PTR_STRUC *DevPtr
+)
+{
+ EFI_STATUS Status;
+ UINT8 PartNo;
+ UINT8 *PartPtr;
+ UINT8 *NonActivePartPtr = NULL;
+ UINT32 OemName;
+ BOOLEAN ValidTable = FALSE;
+ BOOLEAN ValidMBR=FALSE;
+ UINT8 heads, sec;
+ UINT16 cyl;
+ UINT16 SecTimesHeads;
+ UINT32 TotalBlocks;
+
+ //
+ // Check whether the hard disk is already formatted. If already formatted,
+ // find out what mode it was formatted with.
+ //
+ if(BlkIo == NULL ) {
+ return;
+ }
+ Status = BlkIo->ReadBlocks(BlkIo, BlkIo->Media->MediaId, 0, 0x200, gHddReadData);
+ if (!EFI_ERROR(Status) && (*(UINT16*)(gHddReadData+0x1FE) == 0xAA55)) {
+ //
+ // Drive has a partition table, take parameter from 1st bootable partition
+ //
+ PartPtr = gHddReadData+0x1BE;
+
+ for (PartNo=0; PartNo<4; PartNo++, PartPtr+=0x10) {
+ if ((*PartPtr) == 0x80) {
+ ValidTable = TRUE;
+ break;
+ }
+ if (((*(UINT16*)(PartPtr+5)) & 0x3F00) == 0) {
+ // not well formed paritioned table, end sector# = 0
+ continue;
+ }
+ if (NonActivePartPtr == NULL) {
+ NonActivePartPtr = PartPtr;
+ }
+ }
+
+ if (!ValidTable && (NonActivePartPtr != NULL)) {
+ //
+ // No active partition found, use 1st non-active valid partition
+ //
+ PartPtr = NonActivePartPtr;
+ ValidTable = TRUE;
+ }
+
+ if (ValidTable) {
+ //
+ // Either active or first non-active entry found at PartPtr
+ // Read it at gHddReadData + 0xE00
+ //
+ Status = BlkIo->ReadBlocks(BlkIo, BlkIo->Media->MediaId,
+ *(UINT32*)(PartPtr+8), 0x200, gHddReadData+0x800);
+ if (!EFI_ERROR(Status) && (*(UINT16*)(gHddReadData+0x800+0x1FE) == 0xAA55)) {
+ //
+ // Read succeeded so the drive is formatted; check for
+ // valid MSDOS/MSWIN/NTFS boot record
+ //
+ OemName = *(UINT32*)(gHddReadData+0x800+3);
+
+ // 'ODSM' for MSDO
+ // 'IWSM' for MSWI
+ // 'SFTN' for NTFS
+ if((OemName == 0x4F44534D) || (OemName == 0x4957534D) || (OemName == 0x5346544E)) {
+ ValidMBR=TRUE;
+ } else {
+ // Check for valid FAT,FAT16,FAT32 boot records
+ *(gHddReadData+0x800+0x36+3) = 0x20; // Ignore the 4th byte and fill it with space
+ if ((*(UINT32*)(gHddReadData+0x800+0x36) == 0x20544146) // " TAF" for FATx
+ || (*(UINT32*)(gHddReadData+0x800+0x52) == 0x33544146)) // "3TAF" for FAT3
+ {
+ ValidMBR = TRUE;
+ }
+ }
+ }
+ if (ValidMBR) {
+ heads = *(gHddReadData+0x800+0x1A); // number of heads
+ sec = *(gHddReadData+0x800+0x18); // Sectors/track
+ SecTimesHeads = heads * sec;
+ if (SecTimesHeads == 0) {
+ ValidMBR = FALSE;
+ } else {
+ //
+ // Here we have heads/sectors info from partition boot record of known OSes.
+ // NOTE: sectors/track and #of heads is the information with which
+ // the concerned partition was created. This information must be used to
+ // calculate #of cylinders to maintain the current translation scheme.
+ //
+
+ // Find the total #of sectors in the hard disk C * H * S
+ TotalBlocks = DevParam->bMAXHN * DevParam->bMAXSN * DevParam->wMAXCYL;
+ // Calculate #of cylinders using the same translation scheme
+ cyl = TotalBlocks / SecTimesHeads;
+ if (cyl>1024) cyl = 1024;
+ }
+ }
+ }
+ }
+
+ if (!ValidMBR) {
+ //
+ // Hard disk was not formatted OR no valid partition table entry was found;
+ // find the translation scheme which will be used for the hard disk.
+ //
+ cyl = DevParam->wMAXCYL;
+ heads = DevParam->bMAXHN;
+ sec = DevParam->bMAXSN;
+ TotalBlocks = cyl * sec * heads;
+
+ TranslateHdSec(&cyl, &heads, &sec, TotalBlocks);
+ }
+
+
+ DevParam->wLBACYL = DevParam->wMAXCYL;
+ DevParam->bLBAHD = DevParam->bMAXHN;
+ DevParam->bLBASPT = DevParam->bMAXSN;
+
+ DevParam->wMAXCYL = cyl;
+ DevParam->bMAXHN = heads;
+ DevParam->bMAXSN = sec;
+
+ if (heads > 8) {
+ DevParam->bCBYTE = 8; // More than 8 heads indication
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitAhciHddDev
+//
+// Description: This function initializes the AHCI HD drive specific information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitAhciHddDev (
+ IN SATA_DEVICE_INTERFACE *Dev,
+ IN DEV_PARAM_STRUC *DevParam,
+ IN DEV_INFO_STRUC *DevInfo,
+ IN DEV_PTR_STRUC *DevPtr,
+ AHCI_RT_MISC_DATA *AhciRtMiscData
+)
+{
+ UINT16 *IdentifyData;
+ UINT32 d0;
+ UINT16 d1;
+ UINT8 DevNo;
+ UINT32 SegOfs;
+ UINT16 heads, spt, cyl;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ UINT32 Temp;
+ UINT8 Temp2 = 0;
+
+ IdentifyData = (UINT16*)&Dev->IdentifyData;
+
+ heads = IdentifyData[3];
+ spt = IdentifyData[6];
+ ASSERT((heads<255) && (spt<255)); // Both heads & sectors/track must be 8-bit
+
+ //
+ // Save AHCI HD Mode Information
+ //
+ DevInfo->bPIOInfo = (UINT8)IdentifyData[64];
+ DevInfo->bUDMAInfo = (UINT8)IdentifyData[88];
+
+ cyl = IdentifyData[1];
+
+ DevParam->wMAXCYL = cyl;
+ DevParam->bMAXHN = (UINT8)heads;
+ DevParam->bMAXSN = (UINT8)spt;
+
+ GetNumberOfSectors(IdentifyData, &d0, &d1);
+ DevInfo->dTotalSectorsLo = d0;
+ DevInfo->dTotalSectorsHi = (UINT32)d1;
+
+ DevNo = AhciRtMiscData->NumAhciDevice++;
+ DevInfo->bInt13Num = DevNo | 0x80;
+ DevPtr->bInt13Num = DevNo | 0x80;
+ DevPtr->bPMnum = Dev->PortNumber;
+ DevPtr->bPortNum = Dev->PMPortNumber;
+ //
+ // Update SEG:OFS address for current DevParam and DevInfo
+ //
+ SegOfs = ((UINT32)gLegacyMemoryAddress<<12)+(UINT32)((UINTN)DevParam-(UINTN)gImage);
+ DevPtr->dParamTablePtr = SegOfs;
+
+ SegOfs = ((UINT32)gLegacyMemoryAddress<<12)+(UINT32)((UINTN)DevInfo-(UINTN)gImage);
+ DevPtr->dInfoTablePtr = SegOfs;
+
+ //
+ // Indicate device is LBA capable
+ // Note: Non-LBA device are not supported in this release
+ //
+ DevInfo->bSelector |= SELECTOR_LBA;
+
+ //
+ // Check whether device is 48-bit LBA capable
+ //
+ if (IdentifyData[86] & 0x400) {
+ DevInfo->bInfoFlag |= INFO_LBA_48;
+ }
+ //
+ // Update sector size if necessary
+ //
+ if ( (IdentifyData[106] & 0x4000) && (!(IdentifyData[106] & 0x8000)) && (IdentifyData[106] & 0x1000) ) {
+ Temp = (UINT32)(IdentifyData[117] + (IdentifyData[118] << 16)) * 2;
+ while (Temp > 1) {
+ Temp = Temp >> 1;
+ Temp2++;
+ }
+ DevInfo->bSectorSizeN = Temp2;
+ }
+ //
+ // Note: Interrupt driven mechanism is not supported
+ //
+ DevInfo->bInfoFlag &= ~(INFO_IRQ);
+
+ //
+ // Do the LBA to CHS translation; use BlkIo to read partition/boot record
+ //
+ BlkIo = &Dev->SataBlkIo->BlkIo;
+ ConfigureHddParameter(BlkIo, IdentifyData, DevParam, DevInfo, DevPtr);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitAhciCd
+//
+// Description: This function initializes AHCI CD/DVDROM device information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitAhciCd(
+ IN SATA_DEVICE_INTERFACE *Dev,
+ IN DEV_PARAM_STRUC *DevParam,
+ IN DEV_INFO_STRUC *DevInfo,
+ IN DEV_PTR_STRUC *DevPtr,
+ AHCI_RT_MISC_DATA *AhciRtMiscData
+)
+{
+ UINT8 DevNo;
+ UINT32 SegOfs;
+
+ DevNo = AhciRtMiscData->NumAhciDevice++;
+ DevInfo->bInt13Num = (DevNo + AHCI_CD_CSM_ID_OFFSET) | BIT7 ;
+ DevPtr->bInt13Num = (DevNo + AHCI_CD_CSM_ID_OFFSET) | BIT7;
+ DevPtr->bPMnum = Dev->PortNumber;
+ DevPtr->bPortNum = Dev->PMPortNumber;
+ //
+ // Update SEG:OFS address for current DevParam and DevInfo
+ //
+ SegOfs = ((UINT32)gLegacyMemoryAddress<<12)+(UINT32)((UINTN)DevParam-(UINTN)gImage);
+ DevPtr->dParamTablePtr = SegOfs;
+
+ SegOfs = ((UINT32)gLegacyMemoryAddress<<12)+(UINT32)((UINTN)DevInfo-(UINTN)gImage);
+ DevPtr->dInfoTablePtr = SegOfs;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: UpdateControllerInfoToLegacy
+//
+// Description: This function will check if the BusDevFunc is existing in
+// the array, if it exist then it returns EFI_SUCCESS and if not then
+// it will add BusDevFunc into the array and returns EFI_NOT_FOUND.
+//
+// Input: Dev - Structure pointing to SATA_DEVICE_INTERFACE
+// DevInfo - Stucture that maintatin device information
+// wBusDevFunc - It contatin the BusDevFunc number for a device
+//
+// Output: EFI_NOT_FOUND - If wBusDevFunc is not present in the array.
+// i.e a new controller is found
+// EFI_SUCCESS - If wBusDevFunc is present in the array
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateControllerInfoToLegacy(
+ IN SATA_DEVICE_INTERFACE *Dev,
+ IN DEV_INFO_STRUC *DevInfo,
+ IN UINT16 wBusDevFunc
+ )
+{
+ UINT8 i;
+ EFI_STATUS Status;
+ UINT32 Addr16=0;
+ UINT16 *TempAddress;
+
+ for(i=0;i<gController;i++) {
+ if(ControllerInfo[i].BusDevFun == wBusDevFunc) {
+ //
+ // Updatng the respective controller number.
+ //
+ DevInfo->bControllerNo=ControllerInfo[i].ControllerNo;
+ return;
+ }
+ }
+
+ //
+ // A new controller is found so BusDevFunc and ControllerNo is added
+ // into the array of structure.
+ //
+ ControllerInfo[gController].BusDevFun = wBusDevFunc;
+ ControllerInfo[gController].ControllerNo = gController;
+ DevInfo->bControllerNo= gController++;
+
+ //
+ // Store the current controller's PciIO in global variable
+ //
+ gPciIo = Dev->AhciBusInterface->PciIO;
+ Status = gBiosExtensions->Get16BitFuncAddress(
+ CSM16_CSP_AHCI_ACCESSHBA,
+ &Addr16
+ );
+
+ //
+ //At 'Addr16+2' there is a pointer that point to the structure
+ //that maintains index, data and base address for a controller
+ //
+ TempAddress=(UINT16*)(Addr16+2);
+ Addr16=Addr16 + (*TempAddress);
+
+ //
+ // No Addr16 points to ReadWriteRegisterDword routine implemented in
+ // AHCIACC.ASM in CSP module part
+ //
+ if (!EFI_ERROR(Status)) {
+ Status = InitCspData((UINT16)((Addr16>>4) & 0xF000), (UINT16)Addr16, (UINT32)(Dev->AhciBusInterface->AhciBaseAddress),DevInfo->bControllerNo);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitAhciDev
+//
+// Description: This function initializes AHCI device specific information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitAhciDev(
+ IN SATA_DEVICE_INTERFACE *Dev,
+ IN DEV_PARAM_STRUC *DevParam,
+ IN DEV_INFO_STRUC *DevInfo,
+ IN DEV_PTR_STRUC *DevPtr,
+ AHCI_RT_MISC_DATA *AhciRtMiscData
+)
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN seg, bus, dev, func;
+ UINT8 bIrq;
+ UINT32 dHbaBase;
+ UINT8 bPort;
+ EFI_STATUS Status;
+
+ PciIo = Dev->AhciBusInterface->PciIO;
+
+ bPort = Dev->PortNumber;
+ DevInfo->bPortNum = bPort;
+ DevInfo->bPMNum = Dev->PMPortNumber;
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0x3C, 1, &bIrq);
+ ASSERT_EFI_ERROR(Status);
+ DevInfo->bIrq = bIrq;
+
+ Status = PciIo->GetLocation(PciIo, &seg, &bus, &dev, &func);
+ ASSERT_EFI_ERROR(Status);
+ DevInfo->wBusDevFunc = ((UINT16)bus<<8) + ((UINT16)dev<<3) + (UINT16)func;
+
+ //
+ // Pass the Controller Information to Legacy.
+ //
+ UpdateControllerInfoToLegacy(Dev,DevInfo,DevInfo->wBusDevFunc);
+
+ DevInfo->dHbaCap = Dev->AhciBusInterface->HBACapability;
+ DevInfo->bSelector = SELECTOR_NON_LBA;
+ DevInfo->bSectorSizeN = SECTOR_LENGTH_N; // N value of default sector size 2^N;
+ dHbaBase = (UINT32)Dev->AhciBusInterface->AhciBaseAddress;
+ DevInfo->dHbaBase = dHbaBase;
+ DevInfo->dPortBase = dHbaBase + PORT_REGISTER_START + ((UINT32)bPort<<PORT_REGISTER_SET_SIZE_N);
+
+ if (Dev->DeviceType == ATAPI) {
+ DevInfo->bInfoFlag |= INFO_ATAPI;
+ InitAhciCd(Dev, DevParam, DevInfo, DevPtr, AhciRtMiscData);
+ } else {
+ InitAhciHddDev(Dev, DevParam, DevInfo, DevPtr, AhciRtMiscData);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CreateAhciDriveString
+//
+// Description: This function generates the readable string with the name of
+// device and the SATA port number this device is connected to.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+CreateAhciDriveString(
+ IN OUT UINT8 *DescString,
+ IN UINT16 *IdentifyData,
+ IN UINT8 DevicePortNum,
+ IN UINT8 DevicePortMulNum
+)
+{
+ UINT8 s[MAX_DESCRIPTION_STRLEN] = "xP :";
+ UINT8 i, data8;
+
+ s[0] = DevicePortNum+0x30;
+
+ // Get the drive name out of IdentifyDrive data word 27..46 (upto 40 chars)
+ pBS->CopyMem(&s[4], IdentifyData+27, MAX_DESCRIPTION_STRLEN-5);
+ // Swap the bytes
+ for (i=0; i<MAX_DESCRIPTION_STRLEN; i+=2) {
+ data8=s[i];
+ s[i]=s[i+1];
+ s[i+1]=data8;
+ }
+
+ s[MAX_DESCRIPTION_STRLEN-1] = 0; // terminate with zero
+
+ pBS->CopyMem(DescString, s, MAX_DESCRIPTION_STRLEN);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: CreateBbsEntry
+//
+// Description: This function creates BBS entry with the device data filled
+// according to the actual device information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateBbsEntry(
+ IN SATA_DEVICE_INTERFACE *Dev,
+ IN OUT DEV_BBS_OUTFIT *DevOutfit,
+ IN OUT BBS_TABLE *BbsEntry,
+ IN UINT8 Int13Handle,
+ IN UINT16 BcvOffset
+)
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN seg, bus, dev, func;
+ EFI_STATUS Status;
+ UINT8 dData[4];
+ UINT8 bDevAndSysType;
+ UINT8 bHandle;
+ UINT8 bMasterSlave = 0;
+ UINT8 bBaidDeviceType;
+
+ pBS->SetMem(BbsEntry, sizeof(BBS_TABLE), 0);
+
+ //
+ // Get PCI location
+ //
+ PciIo = Dev->AhciBusInterface->PciIO;
+ Status = PciIo->GetLocation(PciIo, &seg, &bus, &dev, &func);
+ BbsEntry->Bus = (UINT32)bus;
+ BbsEntry->Device = (UINT32)dev;
+ BbsEntry->Function = (UINT32)func;
+
+ //
+ // Get class/subclass information
+ //
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint32,
+ 8, // offset
+ 1, // width
+ &dData);
+ ASSERT_EFI_ERROR(Status);
+
+ BbsEntry->Class = dData[3];
+ BbsEntry->SubClass = dData[2];
+
+ CreateAhciDriveString(
+ DevOutfit->DescString,
+ (UINT16*)&Dev->IdentifyData,
+ Dev->PortNumber,
+ Dev->PMPortNumber
+ );
+
+ BbsEntry->DescStringSegment = (UINT16)((UINTN)gLegacyMemoryAddress >> 4);
+ BbsEntry->DescStringOffset = (UINT16)((UINTN)DevOutfit->DescString-(UINTN)gImage);
+
+ bDevAndSysType = (SYSTYPE_ATA << 4)+DEVTYPE_SYS;
+ bHandle = Int13Handle;
+
+ if (Dev->DeviceType == ATAPI) {
+ bBaidDeviceType = BAID_TYPE_CDROM;
+ BbsEntry->DeviceType = BBS_CDROM;
+ BbsEntry->BootHandlerSegment = 0xF000;
+ BbsEntry->BootHandlerOffset = gLegacy16Data->CdrBevOffset;
+
+ } else {
+ BbsEntry->DeviceType = BBS_HARDDISK;
+ bBaidDeviceType = BAID_TYPE_HDD;
+ BbsEntry->BootHandlerSegment = (UINT16)((UINTN)gLegacyMemoryAddress >> 4);
+ BbsEntry->BootHandlerOffset = BcvOffset + (Int13Handle & 0x7F)*4;
+ }
+
+ BbsEntry->InitPerReserved = ((UINT32)bBaidDeviceType<<24)
+ +((UINT32)bMasterSlave<<16)
+ +((UINT32)bHandle<<8)
+ +(UINT32)bDevAndSysType;
+
+ *(UINTN*)(&BbsEntry->IBV1) = (UINTN)Dev->IdeDeviceHandle;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitDrivesInformation
+//
+// Description: Initialization of data structures and placement of runtime
+// code of AHCI INT13
+//
+// Input: Devices - pointer to the beginning of the instances of
+// SATA_DEVICE_INTERFACE*
+// DeviceCount - number of valid AHCI devices pointed by
+// Devices parameter
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitDrivesInformation(
+ IN VOID *Devices,
+ IN UINT16 DeviceCount
+)
+{
+ EFI_LEGACY_BIOS_PROTOCOL *Bios = NULL;
+ UINTN ImageSize;
+ EFI_STATUS Status;
+ AHCI_I13_RTDATA *Ai13Data;
+ UINTN Count, i;
+ UINT32 EbdaAddress;
+ BBS_TABLE BbsEntry;
+ UINT32 LockUnlockAddr, LockUnlockSize;
+ UINT16 CheckForAhciCdromOffset;
+ UINT32 CheckForAhciCdromAddress;
+ UINT8 *addr;
+ SATA_DEVICE_INTERFACE *Device;
+ UINT8 PciConfig[16];
+
+
+ if (DeviceCount == 0) return EFI_SUCCESS; // No devices connected
+
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosProtocolGuid, NULL, &Bios);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Get the AHCI INT13 runtime image
+ //
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosExtProtocolGuid, NULL, &gBiosExtensions);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = gBiosExtensions->GetEmbeddedRom(
+ CSM16_MODULEID, CSM16_VENDORID, CSM16_AHCI_RT_DID, &gImage, &ImageSize);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Instantiate data area
+ //
+ Ai13Data = (AHCI_I13_RTDATA*)gImage;
+
+ //
+ // Fill the data area with the init values
+ //
+ pBS->SetMem(Ai13Data, sizeof (AHCI_I13_RTDATA), 0);
+ pBS->SetMem(Ai13Data->DevPtr, sizeof(DEV_PTR_STRUC)*SATA_PORT_COUNT, 0xFF);
+
+ //
+ // Allocate legacy region in E000 segment; store SEG:OFS of the allocated
+ // memory in global variables
+ //
+ Status = Bios->GetLegacyRegion(Bios, ImageSize, 2, 0x10, &gLegacyMemoryAddress);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Allocate EBDA area for Command List/Command Table/FIS
+ //
+ Status = gBiosExtensions->AllocateEbda(
+ gBiosExtensions,
+ SIZE_CLCTFIS_AREA_K+1, // 1K extra for stack
+ &EbdaAddress,
+ &EbdaStartOffset );
+ ASSERT_EFI_ERROR(Status);
+
+#if AINT13_AVOID_MULTIPLE_SMI
+ Ai13Data->AhciRtMiscData.RunAttribute |= A_INT13_SWSMI_USED;
+ Ai13Data->AhciRtMiscData.AhciSmmRt.MiscInfo = 1;
+ Ai13Data->AhciRtMiscData.AhciSmmRt.SmmAttr = 0;
+ Ai13Data->AhciRtMiscData.AhciSmmRt.SmmPort = SW_SMI_IO_ADDRESS;
+ Ai13Data->AhciRtMiscData.AhciSmmRt.SmmData = AHCI_INT13_SMM_SWSMI_VALUE;
+#endif
+
+ Ai13Data->AhciRtMiscData.AhciEbdaStart = EbdaStartOffset;
+ Ai13Data->AhciRtMiscData.RunAttribute |= A_EBDA_USED;
+
+ gBiosExtensions->UnlockShadow(
+ (UINT8*)gLegacyMemoryAddress, ImageSize,
+ &LockUnlockAddr, &LockUnlockSize);
+
+ gLegacy16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xF0000 + *(UINT16*)0xFFF4C);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, 0x1000, &gHddReadData);
+ ASSERT_EFI_ERROR(Status)
+
+ //
+ // Here is a tricky part: we will have to convert the data passed by Ahci Bus
+ // driver to the data used by INT13
+ //
+ for (Count=0, i=0; i<DeviceCount; i++, ((UINTN*)Devices)++) {
+ Device = *((SATA_DEVICE_INTERFACE**)Devices);
+ InitAhciDev(Device,
+ &Ai13Data->DevParam[Count],
+ &Ai13Data->DevInfo[Count],
+ &Ai13Data->DevPtr[Count],
+ &Ai13Data->AhciRtMiscData
+ );
+
+ Status = gPciIo->Pci.Read ( gPciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig
+ );
+
+ //
+ //Under Raid mode ATA devices are not added into BBS table.
+ //
+ if((PciConfig [IDE_SUB_CLASS_CODE]!= SCC_RAID_CONTROLLER) || (Device->DeviceType != ATA)) {
+ Status = CreateBbsEntry(Device,
+ &Ai13Data->DevOutfit[Count],
+ &BbsEntry,
+ Ai13Data->DevPtr[Count].bInt13Num,
+ ((AHCI_I13_DATA*)Ai13Data)->AhciBcvOffset
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBiosExtensions->AddBbsEntry(&BbsEntry);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ Count++;
+ if (Count==SATA_PORT_COUNT) break;
+ }
+
+ //
+ // Patch farReturnCDROMSupportAPIPointer routine with "call farCheckForAHCICdrom"
+ //
+ CheckForAhciCdromOffset = ((AHCI_I13_DATA*)Ai13Data)->CheckForAhciCdromOffset;
+ CheckForAhciCdromAddress =
+ (UINT32)((UINTN)gLegacyMemoryAddress<<12) + (UINT32)CheckForAhciCdromOffset;
+
+ addr = (UINT8*)(UINTN)(0xF0000+gLegacy16Data->CDROMSupportAPIOfs+10);
+ *addr++ = 0x9A; // far call opcode
+ *(UINT32*)addr = CheckForAhciCdromAddress;
+
+ //
+ // Copy the image into the shadow
+ //
+ pBS->CopyMem(gLegacyMemoryAddress, gImage, ImageSize);
+
+ gBiosExtensions->LockShadow(LockUnlockAddr, LockUnlockSize);
+
+ pBS->FreePool(gHddReadData);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitCspData
+//
+// Description: Initialization of chipset specific fields of AHCI runtime
+// (INT 13) code.
+//
+// Input: Seg16, Ofs16 - 16-bit address of chipset specific 16-bit code/data.
+//
+// Output: Status of operation
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitCspData(
+ IN UINT16 Seg16,
+ IN UINT16 Ofs16,
+ IN UINT32 BaseAddress,
+ IN UINT8 ControllerNumber
+
+)
+{
+ UINT16 indx, data;
+ UINT16 *addr;
+ EFI_STATUS Status;
+
+ ASSERT(gPciIo);
+
+ //
+ // Calculate the address according to the segment ,offset and controller
+ // number.
+ addr = (UINT16*)(UINTN)(((UINTN)Seg16<<4)+(UINTN)Ofs16)+ 4*(ControllerNumber);
+
+ //
+ // Update the Ahci Base Address
+ //
+ *(UINT32*)(addr+2)=BaseAddress;
+
+ Status = GetAccessInfo (gPciIo, &indx, &data);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Update the Index and Data Port
+ //
+ *addr++ = indx;
+ *addr = data;
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AInt13.dxs b/Core/EM/Ahci/AInt13.dxs
new file mode 100644
index 0000000..877fea3
--- /dev/null
+++ b/Core/EM/Ahci/AInt13.dxs
@@ -0,0 +1,37 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+#include "token.h"
+#ifdef CSM_SUPPORT
+#include <Protocol/LegacyBios.h>
+#endif
+
+DEPENDENCY_START
+#if CSM_SUPPORT
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/Ahci/AInt13.h b/Core/EM/Ahci/AInt13.h
new file mode 100644
index 0000000..a55d3d0
--- /dev/null
+++ b/Core/EM/Ahci/AInt13.h
@@ -0,0 +1,395 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AInt13.h 17 11/25/14 12:00a Kapilporwal $
+//
+// $Revision: 17 $
+//
+// $Date: 11/25/14 12:00a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AInt13.h $
+//
+// 17 11/25/14 12:00a Kapilporwal
+// [TAG] EIP191939
+// [Category] Improvement
+// [Description] Issue about BIG_REAL_MODE_MMIO_ACCESS of AHCI module
+// [Files] AI13.bin
+// AHCIACC.ASM
+// AhciInt13Dxe.c
+// AhciInt13Dxe.dxs
+// AhciInt13Smm.c
+// AhciInt13Smm.cif
+// AhciInt13Smm.dxs
+// AhciInt13Smm.h
+// AhciInt13Smm.mak
+// AhciInt13Smm.sdl
+// AInt13.c
+// Aint13.cif
+// AInt13.h
+// AhciSmm.c
+// AhciSmm.h
+// AhciSmmProtocol.h
+//
+// 16 11/29/12 12:58a Rameshr
+// [TAG] EIP107365
+// [Category] Improvement
+// [Description] Increase the SATA_PORT_COUNT to 32 to support 32 SATA
+// devices on Legacyboot
+// [Files] Aint13.h, Ahci.sdl ( Ain13.bin)
+//
+// 15 8/02/12 8:12a Deepthins
+// [TAG] EIP93480
+// [Category] Bug Fix
+// [Symptom] AHCI legacy support module is corrupting the memory.
+// [RootCause] AHCI legacy support module is corrupting the memory as it
+// was using wrong offset for storing the base address.
+// [Solution] Properly calculating offset for storing the base address.
+// [Files] AINT13.EQU, AInt13.c, AInt13.h and AHCIACC.ASM
+//
+// 14 7/20/12 6:12a Anandakrishnanl
+// [TAG] EIP88683
+// [Category] New Feature
+// [Description] EFI_ATA_PASS_THRU_PROTOCOL Support for Aptio IDE
+// [Files] AhciBus.c
+// AhciBus.h
+// AInt13.h
+// IdeBus.c
+// IdeBus.h
+// PIDEBus.h
+// PAhciBus.h
+// AtaPassThru.sdl
+// AtaPassThru.mak
+// AtaPassThru.c
+// AtaPassThruSupport.h
+// AtaPassThru.chm
+//
+// 13 4/24/12 12:54a Deepthins
+// [TAG] EIP86336
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Can't boot from AHCI if SATA_PORT_COUNT=12
+// [RootCause] The controller number was not updated in DEV_INFO_STRUC
+// for all the Hard Disk
+// [Solution] Updated the controller number in the DEV_INFO_STRUC for
+// all the AHCI devices.
+// [Files] AInt13.c, AInt13.h
+//
+// 12 1/13/12 12:18a Deepthins
+// [TAG] EIP78099
+// [Category] Improvement
+// [Description] Handle multiple AHCI controller in legacy.
+// [Files] Aint13.sdl , AInt13.c , AInt13.h , AHCIACC.ASM , AHCI.EQU ,
+// AINT13.bin (AHCIACC.ASM , AINT13.EQU)
+//
+// 11 11/29/11 4:27a Rameshr
+// [TAG] EIP76393
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Any time AHCI is starting when EBDA size is more than 64K,
+// the problem will show as memory corruption.
+// [RootCause] AHCI INT13 code does not use EBDA properly when at the
+// time of EBDA allocation current size of EBDA exceeds 64K
+// [Solution] Modified code to extend the width of EbdaStart offset from
+// 16-bit to 32-bit.
+// [Files] Aint13.asm, Ahcibsp.asm, Aint13.c, Aint13.h, Aint13.bin
+//
+// 10 2/10/11 10:49a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] Aint13.mak
+// AInt13.h
+// AInt13.c
+//
+// 9 6/21/10 5:32a Rameshr
+// AHCI Legacy booting through MMIO reg.
+// EIP 38444
+//
+// 8 9/09/08 3:19p Michaela
+// Added AHCI_CD_CSM_ID_OFFSET for assigning
+// device numbers for CDs/DVDs in order to
+// avoid a CSM16 conflict with PATA devices, which
+// may be present on some systems
+//
+// 7 5/28/08 9:41a Rameshraju
+// Updated the AMI Address.
+//
+// 6 5/13/08 4:31p Olegi
+// Modifications in DEV_PARAM_STRUC and DEV_PTR_STRUC to accomodate the
+// new AI13.BIN that is based on the latest AHCI Core8 src.
+//
+// 3 3/28/08 12:16p Michaela
+// updated copyright
+//
+// 2 19/12/07 4:29p Anandakrishnanl
+//
+// 1 12/07/07 11:17a Olegi
+//
+//****************************************************************************
+
+#ifndef __AI13_HEADER__
+#define __AI13_HEADER__
+
+#include "efi.h"
+#include "Protocol\PciIo.h"
+
+#pragma pack(1)
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AINT13.H
+// Description: Definitions and structures for AHCI INT13
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+typedef struct _DEV_INFO_STRUC {
+ UINT8 bDetectType; // Detected Device Type (Details Below)
+ UINT8 bInstalledType; // Device Installed Type (See Below)
+ UINT16 wStatus; // Bit-mapped device Init Status (Details Below)
+ UINT8 bInt13Num; // Device# for INT13 (8xh)
+ UINT8 bPMNum; // Port Multipier Port #
+ UINT8 bPortNum; // SATA Port# (0-Based) where device is present
+ UINT16 wBusDevFunc; // Bus#, Dev#, Func# of Controller
+ UINT8 bControllerNo; // Ahci Controller number
+ UINT32 dHbaBase; // HBA Base Address of Generic Host Control Registers
+ UINT32 dHbaCap; // HBA Capabilities
+ UINT32 dPortBase; // Base Address of SATA port where device is present
+ UINT8 bSelector; // Device selector value
+ UINT8 bIrq; // IRQ used by this device
+ UINT8 bInfoFlag; // Information Flag (details below)
+ UINT8 bSectorSizeN; // N value of Sector size 2^N ;For 512bytes sector, N = 9
+ UINT16 wSmartInfo; // SMART info (details below)
+ UINT32 dTotalSectorsLo;// Total #of sectors in device (1-based)
+ UINT32 dTotalSectorsHi;
+ UINT16 wXferCount; // Device transfer count. Used for ATAPI packer size
+ UINT8 bBlockInfo;
+ UINT8 b32BitInfo;
+ UINT8 bUDMAInfo;
+ UINT8 bPIOInfo;
+} DEV_INFO_STRUC;
+
+typedef struct _CONTROLLER_INFO_STRUC
+{
+ UINT16 BusDevFun; // Bus, Device and Function number for a controller
+ UINT8 ControllerNo; // Controler number for a controller
+}CONTROLLER_INFO_STRUC;
+
+// Details of bDetectType
+
+#define DETECT_NO 0
+#define DETECT_ATA 1
+#define DETECT_ATAPI_CD 2
+#define DETECT_ATAPI_ARMD 3
+
+// Details of bInstalledType
+
+#define INSTALLED_NO 0
+#define INSTALLED_HDD 1
+#define INSTALLED_CDROM 2
+#define INSTALLED_ARMD_FDD 3
+#define INSTALLED_ARMD_HDD 4
+
+// Details of wStatus
+
+// Bit 0 = 1, successful (device is installed in this case)
+// Bit 1 = 1, Identify Device Failed
+// Bit 2 = 1, Invalid Device Geometry
+// Bit 3 = 1, Init device parameter failed
+// Bit 4 = 1, Recalibrate failed
+// Bit 5 = 1, SMART failed
+// Bit 6 = 1, Verify failed
+// Bit 7 = 1, Security Freeze Lock failed
+// Bit 8 = 1, Port Reset failed
+// Bit 9 = 1, SMART Event was found
+// Bit 10 = 1, Device will be supported by RIAD OROM, not AHCI OROM (ex. HDD)
+// Bit 14-11, Reserved for future use
+// Bit 15 = 1, Device not supported
+
+#define ST_SUCCESS 0x0001
+#define ST_ID_DEV_ERR 0x0002
+#define ST_DEV_GEOMETRY_ERR 0x0004
+#define ST_INIT_DEV_PARAM_ERR 0x0008
+#define ST_RECALI_ERR 0x0010
+#define ST_SMART_ERR 0x0020
+#define ST_VERIFY_ERR 0x0040
+#define ST_FREEZE_LOCK_ERR 0x0080
+#define ST_PORT_RESET_ERR 0x0100
+#define ST_SMART_EVENT 0x0200
+#define ST_RAID_SUPPORT_ERR 0x0400
+#define ST_NOT_SUPPORT_ERR 0x8000
+
+
+// Details of bInt13Num
+
+// Bit 7 = 1, this bit must be set for CDs/HDDs
+// AHCI_CD_CSM_ID_OFFSET, PATA CDs/DVDs use the device handle range 0x80-0x8F
+// so this value will be added to ensure AHCI CDs/DVDs
+// are above that range
+
+#define AHCI_CD_CSM_ID_OFFSET 0x10
+
+
+// Details of bInfoFlag, a bit-mapped field
+
+// Bit 0 = 1, Device supports removable media
+// Bit 1 = 1, 48bit LBA enabled
+// Bit 2 = 1, Device uses IRQ; 0, Device uses DRQ
+// Bit 6-2, Reserved
+// Bit 7 = 1, ATAPI Device; 0, ATA Device
+
+#define INFO_REMOVABLE 0x01
+#define INFO_LBA_48 0x02
+#define INFO_IRQ 0x04
+#define INFO_ATAPI 0x80
+
+// Details wSmartInfo
+
+// Bit 0 = 0/1, SMART (Not Supported/Supported)
+// Bit 1 = 0/1, SMART (Disabled/Enabled)
+// Bit 2 = 0/1, Device Status Good/Bad
+// Bit 7 = 0/1, SMART Execution Successful/Error
+// Bit 15-8, Reserved
+
+#define AHCI_SMART_SUPPORT 0x01
+#define AHCI_SMART_ENABLE 0x02
+#define AHCI_SMART_EN 0x02
+#define AHCI_SMART_STATUS 0x04
+#define AHCI_SMART_COMMAND_STATUS 0x80
+
+#define SECTOR_LENGTH_N 9
+#define SELECTOR_NON_LBA 0xA0
+#define SELECTOR_LBA 0xE0
+#define MAX_STND_XFER_SECTOR 0x80
+#define MAX_EXTD_XFER_SECTOR 0x7F
+#define BLOCK_SIZE 0x80
+#define BLOCK_SIZE_N 0xB
+
+typedef struct _DEV_PTR_STRUC {
+ UINT8 bInt13Num; // INT13 Drive# for this Port
+ UINT8 bDetectType; // Detected Device Type
+ UINT8 bPMnum; // Port Multipier port #
+ UINT8 bPortNum; // Port# (0-based) on Controller
+ UINT32 dParamTablePtr; // Ptr to device parameter table
+ UINT32 dInfoTablePtr; // Ptr to device info table
+} DEV_PTR_STRUC;
+
+typedef struct _DEV_PARAM_STRUC {
+ UINT16 wMAXCYL; // maximum no. of cylinders..INT13 interface. (logical)
+ UINT8 bMAXHN; // maximum no. of heads..INT13 interface. (logical)
+ UINT8 bLBASIG; // LBA signature
+ UINT8 bLBASPT; // #of sectors per track drive is configured for. (physical)
+ UINT16 wWPCYL; // start write precomp cyl no.
+ UINT8 bReserved; // reserved
+ UINT8 bCBYTE; // bit 3 for more than 8 heads
+ UINT16 wLBACYL; // #of cylinders drive is configured for. (physical)
+ UINT8 bLBAHD; // #of heads drive is configured for. (physical)
+ UINT16 wLANDZ; // Landing zone
+ UINT8 bMAXSN; // no. of sectors per track..INT13 interface. (logical)
+ UINT8 bLBACHK; // checksum..LBA
+} DEV_PARAM_STRUC;
+
+//
+// The following definitions should be in sync with 16-bit definition
+//
+#define SATA_PORT_COUNT 32
+#define MAX_DESCRIPTION_STRLEN 32
+
+typedef struct _AHCI_SMM_RTS {
+ UINT8 MiscInfo;
+ UINT16 SmmAttr;
+ UINT32 SmmPort;
+ UINT32 SmmData;
+} AHCI_SMM_RTS;
+
+typedef struct _AHCI_RT_MISC_DATA {
+ UINT8 NumAhciDevice; // #of AHCI device installed by BIOS
+ UINT8 RunAttribute; // Bit-mapped information about runtime environment
+ UINT8 AhciEbdaSizeK; // Size of EBDA in unit of 1k that is created by AHCI init
+ UINT32 AhciEbdaStart; // Start offset of AHCI communication area in EBDA
+ AHCI_SMM_RTS AhciSmmRt; // Port and Data information to generate software SMI
+} AHCI_RT_MISC_DATA;
+
+typedef struct _DEV_BBS_OUTFIT {
+ UINT8 DescString[MAX_DESCRIPTION_STRLEN];
+} DEV_BBS_OUTFIT;
+
+typedef struct _AHCI_I13_RTDATA {
+ DEV_PARAM_STRUC DevParam[SATA_PORT_COUNT];
+ DEV_INFO_STRUC DevInfo[SATA_PORT_COUNT+1];
+ DEV_PTR_STRUC DevPtr[SATA_PORT_COUNT];
+ AHCI_RT_MISC_DATA AhciRtMiscData;
+ DEV_BBS_OUTFIT DevOutfit[SATA_PORT_COUNT];
+} AHCI_I13_RTDATA;
+
+typedef struct _AHCI_I13_DATA {
+ AHCI_I13_RTDATA rtdata;
+ UINT16 CheckForAhciCdromOffset;
+ UINT16 AhciBcvOffset;
+} AHCI_I13_DATA;
+
+// Details of bSignature field: A signature Axh indicates that the table is translated.
+#define DPTBL_SIG_MASK 0x0F0
+// A0h signature indicating LBA translation
+#define LBA_SIGNATURE 0x0A0
+
+//-------------------------------------------------------------------------
+// Port registers
+//
+#define PORT_REGISTER_START 0x100
+#define PORT_REGISTER_SET_SIZE 0x80
+#define PORT_REGISTER_SET_SIZE_N 7
+
+#define SIZE_CLCTFIS_AREA_K 4
+#define A_EBDA_USED 1
+#define A_INT13_SWSMI_USED BIT2
+
+#define BAID_TYPE_HDD 1
+#define BAID_TYPE_RMD_HDD 2
+#define BAID_TYPE_CDROM 3
+#define BAID_TYPE_RMD_FDD 4
+#define BAID_TYPE_FDD 5
+
+#define DEFAULT_DEVICE_STATUS 0x50
+#define SYSTYPE_ATA 0
+#define DEVTYPE_SYS 1
+
+EFI_STATUS GetAccessInfo (EFI_PCI_IO_PROTOCOL*, UINT16*, UINT16*);
+EFI_STATUS InitCspData (UINT16, UINT16,UINT32,UINT8);
+UINT16 CountDrives(IN EFI_HANDLE *HandleBuffer,
+ IN UINTN HandleCount,
+ IN VOID *Devices
+ );
+#pragma pack()
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciBus.c b/Core/EM/Ahci/AhciBus.c
new file mode 100644
index 0000000..ae1fd38
--- /dev/null
+++ b/Core/EM/Ahci/AhciBus.c
@@ -0,0 +1,4477 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciBus.c 74 6/25/14 10:01a Anandakrishnanl $
+//
+// $Revision: 74 $
+//
+// $Date: 6/25/14 10:01a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciBus.c $
+//
+// 74 6/25/14 10:01a Anandakrishnanl
+// [TAG] EIP170118
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MDAT can't program correctly in AHCI module
+// [RootCause] Identify Data Word 76_79 Offset for DiPM Support/Enabled
+// is incorrect for validation
+// [Solution] Changed separating DiPM and Device Sleep into two routines
+// and also modified the tokens to disable both support by default .
+// Corrected Identify data validations.
+// [Files] AhciBus.c
+// AhciBus.h
+// AhciSrc.sdl
+// PAhciBus.h
+// PIDEBus.h
+//
+// 73 6/09/14 9:56a Anbuprakashp
+// [TAG] EIP172443
+// [Category] Improvement
+// [Description] "RaidDriverBlockingStatus" is using
+// gEfiGlobalVariableGuid that violates UEFI 2.4 spec in
+// IdeSecurityBdsCall.c and Runtime attribute set of this variable need to
+// be removed
+// [Files] IdeSecurityBdsCall.c, AhciBus.c
+//
+// 72 1/27/14 4:55a Rameshr
+// [TAG] EIP148180
+// [Category] Improvement
+// [Description] change from EFI_MBR_WRITE_PROTECTION_PROTOCOL to
+// AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL
+// [Files] Ahcibus.c, Ahcibus.h, AhciComponentName.c, AhciController.c
+//
+// 71 1/13/14 4:26a Rameshr
+// [TAG] EIP147909
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Boot devices can not find after resume from s4
+// [RootCause] HddPassword Verification failed because of
+// gHddSecurityEndProtocolGuid is uninstalled on the controller handle
+// [Solution] If the gHddSecurityEndProtocolGuid protocol is already
+// installed , to signel the event Reinstall Protocol interface is done
+// instead of uninstalling the protocol interface.
+// [Files] Ahcibus.c
+//
+// 70 12/20/13 4:06a Rameshr
+// [TAG] EIP126640
+// [Category] Improvement
+// [Description] AHCIBUS driver need to preserve the port settings in
+// GeneratePortReset
+// [Files] Ahcibus.c, AhciController.c
+//
+// 69 12/18/13 3:17a Srikantakumarp
+// [TAG] EIP127356
+// [Category] Improvement
+// [Description] Flash NVRAM seems to cause HDD can't be unlocked when
+// S3 resume.
+// [Files] IdeSecurity.c, IDESMM.c, HddPassword.c, AhciBus.c, AhciBus.h
+//
+// 68 12/02/13 5:46a Anbuprakashp
+// [TAG] EIP138377
+// [Category] Improvement
+// [Description] "CR has Bad Signature" error on AHCI eModule when
+// "disconnect -r" from shell
+// [Files] AhciBus.c
+//
+// 67 9/26/13 2:22a Rameshr
+// [TAG] EIP128963
+// [Category] Improvement
+// [Description] Uninitilized variable cleaned up in AhciBus Stop
+// function.
+// [Files] Ahcibus.c
+//
+// 66 9/26/13 2:10a Rameshr
+// [TAG] EIP125006
+// [Category] Improvement
+// [Description] Dummy Protocol installed for the protocol event
+// signaling is uninstalled. So that Ahcibus driver can signal the event
+// again if the bus driver gets starts again.
+// [Files] Ahcibus.c
+//
+// 65 8/27/13 4:19a Rameshr
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] MbrWriteProtectionProtocol file name changesd to
+// AmiMbrWriteProtectionProtocol.h
+// [Files] AhciController.c, AhciBus.h, Ahcibus.c
+//
+// 64 8/22/13 2:52a Srikantakumarp
+// [TAG] EIP106423
+// [Category] Improvement
+// [Description] Correcting the previous changes.
+// [Files] AhciBus.c
+//
+// 63 7/23/13 11:52p Srikantakumarp
+// [TAG] EIP129989
+// [Category] Improvement
+// [Description] Added DIPM support in Aptio 4.x AHCIBUS driver.
+// [Files] AhciBus.c, AhciBus.h, AhciController.h, AhciSrc.sdl,
+// PAhciBus.h
+//
+// 62 7/22/13 2:05a Rameshr
+// [TAG] EIP129028
+// [Category] Improvement
+// [Description] Implement the POWERUP_IN_STANDBY_MODE support in
+// AHCIBUS driver
+// [Files] Ahcibus.c, Ahcibus.h, Pahcibus.h
+//
+// 61 7/18/13 4:21a Rameshr
+// [TAG] EIP127919
+// [Category] Improvement
+// [Description] "Device is Atapi" bit of PxCMD will be set if the ATAPI
+// device connected on the Port and "Drive LED on ATAPI" Enabled by AHCI
+// platform policy
+// [Files] Pahcibus.h, Ahcibus.c, Ahcibus.h
+//
+// 60 7/01/13 4:31a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 59 6/06/13 4:22a Rameshr
+// [TAG] EIP106423
+// [Category] Improvement
+// [Description] HddPassword Support in UEFI Raid and Legacy Raid. And
+// also taken care where there is no Conin Device avilable in the post
+// [Files] IdeSecurity.cif,IdeSecurity.sdl,IdeSecurity.mak,IdeSecurityB
+// dsCall.c,HddPassword.c, Ahcibus.c, Pidebus.h
+//
+// 58 6/06/13 2:30a Rameshr
+// [TAG] EIP119759
+// [Category] Improvement
+// [Description] Ahcibus driver should not be stated when the Idebus
+// driver is active on the SATA Controller
+// [Files] Ahcibus.c
+//
+// 57 3/25/13 4:55a Rameshr
+// [TAG] EIP118033
+// [Category] Improvement
+// [Description] If the device is not yet detected in the remaining
+// device path port, proceed for the device detection and configuration.
+//
+// [Files] Ahcibus.c
+//
+// 56 2/11/13 12:35a Rameshr
+// [TAG] EIP114276
+// [Category] Improvement
+// [Description] Error in AHCIBus Driver when Power management and HPA
+// support is turned on. Removed the unused Power mangement and HPA code
+// from Ahcibus driver
+// [Files] Ahcibus.c
+//
+// 55 10/18/12 5:36a Srilathasc
+// [TAG] EIP95446
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Diskinfo Identify function returns the invalid Identify
+// data after post
+// [RootCause] DiskInfoIdentify function copies the identify data from
+// buffer.
+//
+// [Solution] DiskInfoIdentify function should send command and get
+// identify data.
+// [Files] IdeBus.c, AhciBus.c
+//
+// 54 9/17/12 1:49a Anandakrishnanl
+// [TAG] EIP100891
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] PortFISBaseAddr and PortCommandListBaseAddr allocation to
+// support memory allocation above 4gb
+// [RootCause] System hangs in Ahci Mode > 4Gb memory allocation, With
+// Filesystem and UEFI Boot Failing
+// [Solution] Fixed by handling FIS and Command List base Address
+// allocation >4gb allocation
+// [Files] AhciBus.c
+//
+// 53 9/17/12 12:48a Rameshr
+// [TAG] EIP100335
+// [Category] Improvement
+// [Description] Port Multiplier spend long time to connect device.
+// [Files] Ahcibus.c, AhciController.c
+//
+// 52 9/10/12 2:48a Rameshr
+// [TAG] EIP95440
+// [Category] Improvement
+// [Description] Add HddSecurity and HddSmart feature under UEFI Raid
+// driver mode
+// [Files] Ahcibus.c, Pahcibus.h, Aint13.c
+//
+// 51 9/03/12 6:07a Rameshr
+// [TAG] EIP94991
+// [Category] Improvement
+// [Description] If the link is already established before setting up
+// the allowed port speed, current interface speed has not been set based
+// on the port speed allowed. ComReset has been issued to setup the
+// current interface speed according to the port speed allowed.
+// [Files] Ahcibus.c
+//
+// 50 8/21/12 2:13a Rameshr
+// [TAG] EIP98436
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] FISAddress is being set incorrrectly.
+// [RootCause] Before setting the FIS Address, it has been used in
+// GeneratePortReset function.
+// [Solution] Moveed the FIS base address and command list base address
+// programming before GeneratePortReset
+// [Files] Ahcibus.c
+//
+// 49 8/16/12 3:05a Rajeshms
+// [TAG] EIP97048
+// [Category] New Feature
+// [Description] ATAPI PassThru Support using
+// EFI_EXT_SCSI_PASS_THRU_PROTOCOL.
+// [Files] AhciBus.c, AhciController.c, IdeBus.c, Atapi.c, PIDEBus.h,
+// PAhciBus.h, ScsiPassThruAtapi.sdl, ScsiPassThruAtapi.mak,
+// ScsiPassThruAtapi.c, ScsiPassThruAtapiSupport.h, ScsiPassThruAtapi.chm,
+// ScsiPassThruExt.h
+//
+// 48 8/16/12 2:27a Anandakrishnanl
+// [TAG] EIP97113
+// [Category] Improvement
+// [Description] AtaPassThru - Module Enhancement
+// [Files] AtaPassThru.c,
+// AtaPassThruSupport.h,AtaPassThru.mak,IdeBus.c,AhciBus.c
+//
+// 47 7/20/12 6:09a Anandakrishnanl
+// [TAG] EIP88683
+// [Category] New Feature
+// [Description] EFI_ATA_PASS_THRU_PROTOCOL Support for Aptio IDE
+// [Files] AhciBus.c
+// AhciBus.h
+// AInt13.h
+// IdeBus.c
+// IdeBus.h
+// PIDEBus.h
+// PAhciBus.h
+// AtaPassThru.sdl
+// AtaPassThru.mak
+// AtaPassThru.c
+// AtaPassThruSupport.h
+// AtaPassThru.chm
+//
+// 46 11/03/11 5:44a Rajeshms
+// [TAG] EIP73249
+// [Category] Improvement
+// [Description] AHCI Driver Follow the UEFI Driver Model as per the
+// UEFI Spec. and STOP function was Verified.
+// [Files] AhciBus.c
+//
+// 45 10/11/11 2:21a Rameshr
+// [TAG] EIP71410
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] 10 seconds Delay in post if ODD with CD/DVD
+// [RootCause] ATA Specific commands are executed for ATAPI devices
+// also.
+// [Solution] ATA device check added before sending the command.
+// [Files] Ahcibus.c
+//
+// 44 9/19/11 3:03a Lavanyap
+// [TAG] EIP69398
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Function ConfigureController() has a runtime error (NULL
+// pointer dereference)
+// [RootCause] variable SupportedModes has been initialized again in
+// ConfigureController().
+// [Solution] variable SupportedModes is passed as an input parameter
+// for ConfigureController() and ConfigureDevice().
+// [Files] AhciBus.c, AhciBus.h
+//
+// 43 8/02/11 4:34a Rameshr
+// [TAG] - EIP 61076
+// [Category]- IMPROVEMENT
+// [Description]- Setting the Interface Speed Support in CAP.ISS. so that
+// it's get programmed in PxSCT[7:4]. For this programming the link
+// communication should not be established. If it's already established we
+// should use GeneratePortReset function to set the speed
+// [Files] - AhciBus.c
+//
+// 42 7/05/11 2:50a Anandakrishnanl
+// [TAG] EIP56530
+// [Category] Improvement
+// [Description] EFI_IDE_CONTROLLER_INIT_PROTOCOL and
+// EFI_DISK_INFO_PROTOCOL are used accordingly to the PI 1.2 spec
+// [Files] AhciBus.c, IdeControllerInit.h, PDiskInfo.h
+//
+// 41 6/14/11 5:48a Rameshr
+// [TAG]- EIP 59495
+// [Category]-IMPROVEMENT
+// [Description]- Update implementation of EFI_BLOCK_IO_PROTOCOL as
+// described in UEFI specification v 2.3.1, page 12.8
+// [Files]- AhciBus.c
+//
+// 40 5/19/11 3:12a Anandakrishnanl
+// [TAG] EIP53565
+// [Category] New Feature
+// [Description] UEFI2.3+ Specifications defines Storage Security
+// protocol which needs to be implemented.
+// [Files] AhciBus.c,IdeBus.c,AHCIOpalSec.c,IDEOpalSec.c,OpalSecurity.c
+// ,OpalSecurity.chm,OpalSecurity.cif,OpalSecurity.h,OpalSecurity.mak,Opal
+// Security.sdl,PIDEBus.h,StorageSecurityProtocol.CIF,StorageSecurityProto
+// col.h
+//
+// 39 2/18/11 5:04a Rameshr
+// [TAG]- EIP 37975
+// [Category]-IMPROVEMENT
+// [Description]- Klocwork Issues II - IDE/Ahci module
+// [Files]- AhciBus.c, AhciController.c
+//
+// 38 2/11/11 4:22a Rameshr
+// [TAG] EIP53730
+// [Category] Improvement
+// [Description] Add Odd Loading type information into ATAPI_DEVICE
+// structure in AHCI mode
+// [Files] AhciBus.c
+// AhciController.c
+// AhciBus.h
+//
+// 37 2/10/11 10:35a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSrc.mak
+// AhciBus.c
+// AhciController.c
+// AhciComponentName.c
+// AhciBus.h
+// AhciController.h
+//
+// 36 12/30/10 3:48a Rameshr
+// [TAG] - EIP 49229
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - SATA interface setting (SATA speed)
+// [RootCause]- Read the SATA device speed from the Capabilities Register
+// and set it to Port Control speed Register
+// [Solution] - Read the SATA device speed from the Capabilities Register
+// and set it to Port Control speed Register.
+// [Files] - AhciBus.c
+//
+// 35 12/23/10 3:58a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 34 11/25/10 7:09a Rameshr
+//
+// [TAG] - EIP 48045
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DISABLE_SOFT_SET_PREV sdl token set 1 , throws build error
+// in AHCI driver.
+// [RootCause]- Status Variable not declared
+// [Solution] - Declared the Status variable.
+// [Files] - Ahcibus.c
+//
+// 33 11/02/10 12:03a Rameshr
+// [TAG] - EIP 45266
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - E-SATA card will hang up on post and debug card show "AE
+// [RootCause]- Device doesn't support any of the UDMA mode and function
+// ReturnMsbbit returns incorrect values
+// [Solution] - If any of the bit is not set in Input value, ReturnMsbbit
+// returns 0xFF.
+// [Files] - Ata.c, AhciBus.c
+//
+// 32 10/11/10 6:28p Krishnakumarg
+// [TAG] - EIP 44800
+// [Category] - Defect
+// [Severity] - Major
+// [Symptom] - Side Effect of EIP 40528. HDD security setup option
+// disappear on warn boot in AHCI mode.
+// [RootCause]- When FORCE_HDD_PASSWORD_PROMPT token enabled,Software
+// preservation is disabled only when password is enabled.
+// [Solution] - Software preservation is disabled when HDD can support
+// software preservation.
+// [Files] - AhciBus.c
+//
+// 31 9/24/10 2:40a Rameshr
+// [TAG]- EIP 42817
+// [Category]-IMPROVEMENT
+// [Description]- Ide Smart checks HDDs for errors moved after Idebus
+// Device path has been installed.
+// [Files]- AhciBus.c, IdeBus.c
+//
+// 30 5/26/10 6:21a Rameshr
+// Checked the Device Configuration Overlay feature set supported status
+// before sending the DEV_CONFIG_FREEZE_LOCK
+// EIP 38384
+//
+// 29 5/07/10 11:44a Krishnakumarg
+// Coding standard update
+//
+// 28 4/16/10 4:15p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 27 3/26/10 5:35p Krishnakumarg
+// UEFI2.1 compliance change EIP#34744.
+//
+// 26 2/15/10 5:51p Srinin
+// KlockWork flags "'SupportedModes' is explicitly dereferenced.". Fix
+// added.
+//
+// 25 2/11/10 4:00a Rameshr
+// Atapi devices are handled by AhciBus driver based on
+// SUPPORT_ATAPI_IN_RAID_MODE SDL token.
+// EIP 34583
+//
+// 24 1/11/10 12:12p Krishnakumarg
+// Update for Eip 11835 - To implement Acoustic Management function
+// EIP 30041 - Aptio 4 Device Initiated Power Management (DipM) support
+// for SATA devices
+//
+// 23 10/15/09 11:46p Fasihm
+// EIP#28961: Corrected the Disk Info Protocol installation information,
+// and corrected it from EFI_BLOCK_IO_PROTOCOL to EFI_DISK_INFO_PROTOCOL.
+//
+// 22 9/22/09 10:57a Krishnakumarg
+// Code modified to update SataDevInterface->identifydata in
+// GetIdentifyData function instead of returning in global variable -
+// EIP26411
+//
+// 21 9/04/09 3:32p Krishnakumarg
+// Coding Standard and unwanted code removal in InitAcousticSupport
+// function
+//
+// 20 9/04/09 3:16p Krishnakumarg
+// Acoustic Management function updated to set acoustic level according to
+// setup option EIP:11835
+//
+// 19 8/18/09 2:04p Rameshr
+// AhciBus driver doesn't work for Multi Entry.
+// Ahci Int13 initilization code moved from AhciBus to CsmHwinfo.c
+// EIP: 25369
+//
+// 18 8/17/09 2:55p Rameshr
+// AHCI bus driver doesn't detect the devices other than port 0 when the
+// remaining device path is not null
+// EIP:25368
+//
+// 17 7/13/09 3:37p Rameshr
+// Symptom: After installing the UEFI windows 7 and reboot, system hangs
+// on post.
+// Rootcause: Devicepath created with NULL when the Remainingdevicepath
+// has valid value.
+// Solution: Created the Devicepath even if the RemainingDevicePath has
+// the valid value.
+//
+// 16 6/22/09 11:33a Rameshr
+// Odd Type information Saved in Atapi Device Structure.
+// EIP:21548
+//
+// 15 4/28/09 3:47p Rameshr
+//
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 14 12/31/08 3:05p Rameshraju
+// BugFix- Validate the PIO mode before programming the PIO mode into the
+// device EIP:17885
+//
+// 13 14/08/08 10:47a Anandakrishnanl
+// Compatible Mode AHCI Support Added and Sdl Token Added in IdeBusSrc.sdl
+//
+// 12 5/28/08 9:38a Rameshraju
+// Based on the SDL token index/data or MMIO method used to access the
+// AHCI configuration space.
+//
+// 11 5/14/08 4:42p Rameshraju
+// Error code added if error happens while configuring device or
+// controller.
+//
+// 10 5/09/08 9:59a Rameshraju
+// Cdrom block size initilized.
+//
+// 9 5/02/08 3:41p Rameshraju
+// Insteed of OR, Write the FIS base address.
+//
+// 8 4/23/08 12:30p Srinin
+// Bug fix in CheckDevicePresence()
+//
+// 7 4/18/08 2:58p Srinin
+// If Device SPINUP is enabled, check is added to see whether
+// COMRESET is expected or not.
+//
+// 6 4/14/08 4:58p Rameshraju
+// Security feature stopped when the AHCI bus driver is stopped.
+//
+// 5 3/27/08 11:23a Srinin
+// CreateSataDevicePath() modified to create a devicepath
+// even if Remaining devicepath is not NULL.
+//
+// 4 3/24/08 6:17p Fasihm
+// Fixed the issue that HDD Password prompt is not displayed in POST in
+// AHCI mode when DISABLE_SOFT_SET_PREV is enabled.
+//
+// 3 7/03/08 5:31p Anandakrishnanl
+// Added Smart Support as a seperate Driver and Corresponding changes to
+// invoke Smart Protocols and removed SDL-Token
+//
+// 2 28/02/08 6:21p Anandakrishnanl
+// Cleaned up Code and re Checked - in
+//
+// 1 28/02/08 6:03p Anandakrishnanl
+// AHCI Bus Driver initial check-in.
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AhciBus.c
+//
+// Description: Provides AHCI Block IO protocol
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "AhciBus.h"
+#include "protocol\legacyahci.h"
+#if SBIDE_SUPPORT
+#include "SBIDE.h"
+#endif
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *AmiBlkWriteProtection = NULL;
+#endif
+
+EFI_GUID gEfiAhciBusProtocolGuid = AHCI_BUS_INIT_PROTOCOL_GUID;
+EFI_GUID gAhciBusDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+EFI_GUID gEfiIdeControllerProtocolGuid = IDE_CONTROLLER_PROTOCOL_GUID;
+static EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#else
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+#endif
+
+static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+EFI_GUID gEfiAhciDiskInfoProtocolGuid = EFI_DISK_INFO_AHCI_INTERFACE_GUID;
+EFI_GUID gSecurityModeProtocolGuid = IDE_SECURITY_INTERFACE_GUID;
+EFI_GUID gSMARTProtocolGuid = IDE_SMART_INTERFACE_GUID;
+EFI_GUID gPowerMgmtProtocolGuid = IDE_POWER_MGMT_INTERFACE_GUID;
+EFI_GUID gHPAProtocolGuid = IDE_HPA_INTERFACE_GUID;
+EFI_GUID gStorageSecurityProtocolGuid = EFI_STORAGE_SECURITY_COMMAND_PROTOCOL_GUID;
+EFI_EVENT gIDEBusEvtBootScript = NULL;
+static EFI_GUID gHddSecurityInitProtocolGuid= HDD_SECURITY_INIT_PROTOCOL_GUID;
+static EFI_GUID gHddSmartInitProtocolGuid = HDD_SMART_INIT_PROTOCOL_GUID;
+static EFI_GUID gHddSecurityEndProtocolGuid = HDD_SECURITY_END_PROTOCOL_GUID;
+static EFI_GUID gOpalSecInitProtocolGuid = OPAL_SEC_INIT_PROTOCOL_GUID;
+static EFI_GUID gAtaPassThruInitProtocolGuid= ATA_PASS_THRU_INIT_PROTOCOL_GUID;
+static EFI_GUID gScsiPassThruAtapiInitProtocolGuid = SCSI_PASS_THRU_ATAPI_INIT_PROTOCOL_GUID;
+static EFI_GUID gEfiIdeBusInitProtocolGuid = IDE_BUS_INIT_PROTOCOL_GUID;
+static EFI_GUID gOnboardRaidControllerGuid = ONBOARD_RAID_CONTROLLER_GUID;
+static EFI_GUID gHddPasswordVerifiedGuid = HDD_PASSWORD_VERIFIED_GUID;
+static EFI_GUID gAmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+
+
+#if SBIDE_SUPPORT
+EFI_GUID gIdeSetupProtocolguid = IDE_SETUP_PROTOCOL_GUID;
+VOID InitMiscConfig(IN SATA_DEVICE_INTERFACE *SataDevInterface);
+#endif
+
+
+#if INDEX_DATA_PORT_ACCESS
+extern InitilizeIndexDataPortAddress();
+#endif
+
+extern
+EFI_STATUS
+ExecutePacketCommand (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE *CommandStructure,
+ IN BOOLEAN READWRITE
+);
+
+#if (EFI_SPECIFICATION_VERSION > 0x00020000)
+extern EFI_COMPONENT_NAME2_PROTOCOL gAhciBusControllerDriverName;
+#else
+extern EFI_COMPONENT_NAME_PROTOCOL gAhciBusControllerDriverName;
+#endif
+
+
+AHCI_CONTOLLER_LINKED_LIST AhciControllerLinkedList;
+
+EFI_DRIVER_BINDING_PROTOCOL gAhciBusDriverBinding = {
+ AhciBusSupported,
+ AhciBusStart,
+ AhciBusStop,
+ AHCI_BUS_DRIVER_VERSION, // version
+ NULL, // ImageHandle
+ NULL // DriverBindingHandle
+};
+
+HDD_SECURITY_INIT_PROTOCOL *HddSecurityInitProtocol;
+HDD_SMART_INIT_PROTOCOL *HddSmartInitProtocol;
+OPAL_SECURITY_INIT_PROTOCOL *OpalSecInitProtocol;
+ATA_PASS_THRU_INIT_PROTOCOL *AtaPassThruInitProtocol;
+SCSI_PASS_THRU_ATAPI_INIT_PROTOCOL *gScsiPassThruAtapiInitProtocol;
+AHCI_PLATFORM_POLICY_PROTOCOL *AhciPlatformPolicy = NULL;
+
+//
+// Instantiate AHCI_PLATFORM_POLICY_PROTOCOL with default values
+//
+AHCI_PLATFORM_POLICY_PROTOCOL gDefaultAhciPlatformPolicy = {
+ FALSE, // Legacy Raid option selected
+ TRUE, // Ahcibus driver handles the ATAPI devices
+ FALSE, // Drive LED on ATAPI Enable (DLAE)
+#ifdef POWERUP_IN_STANDBY_SUPPORT
+ POWERUP_IN_STANDBY_SUPPORT, // PowerUpInStandby feature is supported or not
+#else
+ FALSE,
+#endif
+#ifdef POWERUP_IN_STANDBY_MODE
+ POWERUP_IN_STANDBY_MODE, // PowerUpInStandby mode
+#else
+ FALSE,
+#endif
+#ifdef DiPM_SUPPORT
+ DiPM_SUPPORT, // Device Initiated power management
+#else
+ FALSE,
+#endif
+#ifdef ENABLE_DIPM
+ ENABLE_DIPM,
+#else
+ FALSE,
+#endif
+#ifdef DEVICE_SLEEP_SUPPORT
+ DEVICE_SLEEP_SUPPORT,
+#else
+ FALSE,
+#endif
+#ifdef ENABLE_DEVICE_SLEEP
+ ENABLE_DEVICE_SLEEP
+#else
+ FALSE
+#endif
+
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AhciBusEntryPoint
+//
+// Description: Installs gAhciBusDriverBinding protocol
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces DListInit
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS AhciBusEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+
+ gAhciBusDriverBinding.DriverBindingHandle=NULL;
+ gAhciBusDriverBinding.ImageHandle=ImageHandle;
+
+ InitAmiLib(ImageHandle, SystemTable);
+ DListInit(&(AhciControllerLinkedList.AhciControllerList));
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gAhciBusDriverBinding.DriverBindingHandle,
+ &gAhciBusDriverBindingProtocolGuid,&gAhciBusDriverBinding,
+ &gComponentNameProtocolGuid, &gAhciBusControllerDriverName,
+ NULL
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AhciBusSupported
+//
+// Description: Checks whether EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID
+// is installed on the controller. If 'yes', return SUCCESS else ERROR
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If Devicepath is NULL, check "gEfiIdeControllerInitProtocolGuid"
+// is installed by IdeController device driver,if yes, it is the
+// IDE controller that this Bus will manage. Then return Success.
+// 2. If Devicepath is valid, check if it is a SATA device Path. See
+// if gEfiAhciBusProtocolGuid is installed on the device.
+// 3. make sure the the Controller class code is AHCI
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AhciBusSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+
+ EFI_STATUS Status;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL IdeControllerInterface;
+ SATA_DEVICE_PATH *SataRemainingDevicePath = (SATA_DEVICE_PATH *) RemainingDevicePath;
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ UINT8 PciConfig[256];
+
+ //
+ // Check for Valid SATA Device Path. If no return UNSUPPORTED
+ //
+ if (!(SataRemainingDevicePath == NULL)) {
+ //
+ // Check if the SataRemainingDevicePath is valid 8.3.4.1
+ //
+ if (SataRemainingDevicePath->Header.Type != MESSAGING_DEVICE_PATH ||
+ SataRemainingDevicePath->Header.SubType != MSG_USB_SATA_DP &&
+ NODE_LENGTH(&SataRemainingDevicePath->Header) != SATA_DEVICE_PATH_LENGTH) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Now check whether it is OK to enumerate the specified device.
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiAhciBusProtocolGuid,
+ (VOID **)&AhciBusInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED) {
+ pBS->CloseProtocol (
+ Controller,
+ &gEfiAhciBusProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ SataDevInterface = GetSataDevInterface(
+ AhciBusInterface,
+ (UINT8)SataRemainingDevicePath->PortNumber,
+ (UINT8)SataRemainingDevicePath->MultiplierPortNumber
+ );
+
+ // If the device in the remaining device path Port already detected and configued
+ // return as EFI_ALREADY_STARTED. If the device is not yet detected in the
+ // remaining device path port, proceed for the device detection and configuration
+
+ if (SataDevInterface && (SataDevInterface->DeviceState >= DEVICE_DETECTION_FAILED)) {
+ return EFI_ALREADY_STARTED;
+ }
+ else {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ // Check if the IDEBUS installed on the controller. If it is installed
+ // Idebus driver already handling the Controller. So AHCIBUS driver should not handle
+ // the controller
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (Status == EFI_SUCCESS) {
+
+ // Idebus handling the controller. Return with Error.
+ return EFI_UNSUPPORTED;
+ }
+
+
+ // Check whether IDE_CONTROLLER_PROTOCOL has been installed on
+ // this controller
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ (VOID **)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ //
+ // IDE_CONTROLLER_PROTOCOL will be opened by each device. So
+ // EFI_ALREADY_STARTED is not an error.
+ //
+ if ( !(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Close IDE_CONTROLLER_PROTOCOL
+ //
+ pBS->CloseProtocol (
+ Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Check if Controller is in AHCI mode or not?
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIO,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if (EFI_ERROR(Status)) {return EFI_UNSUPPORTED;}
+
+ Status = PciIO->Pci.Read ( PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig
+ );
+
+ if (PciConfig [IDE_SUB_CLASS_CODE] == SCC_AHCI_CONTROLLER) {
+#ifdef AHCI_COMPATIBLE_MODE
+ #if !(AHCI_COMPATIBLE_MODE)
+ return EFI_SUCCESS;
+ #endif
+#endif
+ }
+
+#ifdef SUPPORT_ATAPI_IN_RAID_MODE
+#ifdef HDD_PASSWORD_SUPPORT_UNDER_RAIDMODE
+ #if SUPPORT_ATAPI_IN_RAID_MODE || HDD_PASSWORD_SUPPORT_UNDER_RAIDMODE
+ if (PciConfig [IDE_SUB_CLASS_CODE] == SCC_RAID_CONTROLLER) {
+
+ //
+ // Under Raid mode, don't detect the devices again
+ // Check if AHCI_BUS_PROTOCOL installed status. If already installed
+ // Ahcibus started already and device detection done
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiAhciBusProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+
+ if ( EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ #endif
+#endif
+#endif
+
+ return EFI_UNSUPPORTED;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AhciBusStart
+//
+// Description: Installs AHCI Block IO Protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol InstallProtocolInterface
+// AllocatePool InstallAhciBusProtocol CheckPortImplemented
+// DetectAndConfigureDevice.
+//
+// Notes:
+// 1. Collect the info about the number of devices to detect and configure.
+// 2. Configure the AHCI controller if it is not done yet.
+// 3. Detect the device connected to the port
+// 4. If the device is a Port Multiplier, detect & configure all the
+// devices behind it, else configure the device directly connected
+// to the port.
+// 5. Continue step 3 and 4 for all the ports on the controller.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AhciBusStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+ UINT8 Enumeration_Process = ENUMERATE_ALL;
+ SATA_DEVICE_PATH *SataRemainingDevicePath = (SATA_DEVICE_PATH *)RemainingDevicePath;
+ UINT8 PortEnumeration = 0xFF, PMPortEnumeration = 0xFF; // Bit Map
+ UINT8 CurrentPort = 0, CurrentPMPort = 0xFF;
+ BOOLEAN Enabled = TRUE;
+ UINT8 MaxDevices = 0;
+ UINT8 Data8;
+ EFI_HANDLE SecHandle=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ VOID *TempProtocolPtr;
+ EFI_STATUS SecurityStatus=EFI_NOT_FOUND;
+ BOOLEAN RaidDriverBlocked=FALSE;
+
+ PROGRESS_CODE(DXE_IDE_BEGIN);
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ if(AmiBlkWriteProtection == NULL) {
+ Status = pBS->LocateProtocol(&gAmiBlockIoWriteProtectionProtocolGuid, NULL, &AmiBlkWriteProtection);
+ if(EFI_ERROR(Status)) {
+ AmiBlkWriteProtection = NULL;
+ }
+ }
+#endif
+
+ // Open IDE_CONTROLLER_PROTOCOL. If success or Already opened, It is OK to proceed.
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ (VOID **)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if ( !(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED)) return EFI_DEVICE_ERROR;
+
+ // Get the PciIO interface
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIO,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ // Check if AHCI_BUS_PROTOCOL installed.
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiAhciBusProtocolGuid,
+ (VOID **)&AhciBusInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+
+ if ( !(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED)) {
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof(AHCI_BUS_PROTOCOL),
+ (VOID**)&AhciBusInterface
+ );
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES; //No need to close IDE_CONTROLLER_PROTOCOL
+
+ Status = InstallAhciBusProtocol (Controller, AhciBusInterface, IdeControllerInterface, PciIO);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR; //No need to close the protocol. Will be handled in STOP
+ }
+
+ if (!IdeControllerInterface->EnumAll) {
+ // Check if sataRemainingDevicePath is valid or not
+ if (!(SataRemainingDevicePath == NULL)) {
+ // Check if the SataRemainingDevicePath is valid 8.3.4.1
+ if (SataRemainingDevicePath->Header.Type != MESSAGING_DEVICE_PATH ||
+ SataRemainingDevicePath->Header.SubType != MSG_USB_SATA_DP &&
+ NODE_LENGTH(&SataRemainingDevicePath->Header) != SATA_DEVICE_PATH_LENGTH) {
+ return EFI_DEVICE_ERROR;
+ }
+ // Get the Port# that needs to be processed.
+ PortEnumeration = 1 << SataRemainingDevicePath->PortNumber; //Bit Map
+ PMPortEnumeration = 1 << SataRemainingDevicePath->MultiplierPortNumber; // Bit Map
+ CurrentPMPort = (UINT8) SataRemainingDevicePath->MultiplierPortNumber;
+ }
+ }
+ else {
+ PortEnumeration = AhciBusInterface->HBAPortImplemented;
+ }
+
+ //
+ // Get the Ahci Platform Policy Protocol
+ //
+ Status=pBS->LocateProtocol(&gAciPlatformPolicyProtocolGuid, NULL, &AhciPlatformPolicy);
+ if(EFI_ERROR(Status)) {
+ //
+ // If the Ahci Platform policy protocol not found, initilize with default value
+ //
+ AhciPlatformPolicy=(AHCI_PLATFORM_POLICY_PROTOCOL *)&gDefaultAhciPlatformPolicy;
+ }
+
+
+ TRACE_AHCI((-1,"\nAHCI Driver Detection and Configuratiion starts\n"));
+
+
+ //--------------------------------------------------------------------------
+ // Detection and Configuration starts
+ //--------------------------------------------------------------------------
+ for ( ; PortEnumeration != 0 ; PortEnumeration >>= 1, CurrentPort++, CurrentPMPort = 0xFF) {
+
+ if(!(PortEnumeration & 1)) {
+ continue;
+ }
+
+ // Check if the current port is implemented or not?
+ Status = CheckPortImplemented(AhciBusInterface, CurrentPort);
+ if (EFI_ERROR(Status)) { continue;}
+
+ Status = IdeControllerInterface->NotifyPhase (IdeControllerInterface, EfiIdeBeforeChannelEnumeration, CurrentPort);
+ if (EFI_ERROR(Status)) { continue;}
+
+ Status = IdeControllerInterface->GetChannelInfo(IdeControllerInterface, CurrentPort, &Enabled, &MaxDevices);
+ if (EFI_ERROR(Status) || !Enabled) { goto NextDevice; }
+
+ Status = DetectAndConfigureDevice(This, Controller, RemainingDevicePath, AhciBusInterface, IdeControllerInterface, CurrentPort, CurrentPMPort);
+ SataDevInterface = GetSataDevInterface(AhciBusInterface, CurrentPort, CurrentPMPort);
+
+ if(SataDevInterface != NULL && EFI_ERROR(SecurityStatus)) {
+ // Verify that Security interface has been installed
+ // on atleast one device
+ SecurityStatus = pBS->HandleProtocol(SataDevInterface->IdeDeviceHandle,
+ &gSecurityModeProtocolGuid,
+ &TempProtocolPtr
+ );
+ }
+
+ // Check whether the device detected is PM. Also check whether PM is supported by the Controller
+ // and also MaxDevices should be more than 1 if PM is Supported.
+ if (!EFI_ERROR(Status) && SataDevInterface && SataDevInterface->NumPMPorts &&
+ (SataDevInterface->DeviceType == PMPORT) && MaxDevices > 1){
+
+ Data8 = SataDevInterface->NumPMPorts > MaxDevices ? MaxDevices : SataDevInterface->NumPMPorts;
+ PMPortEnumeration = 1;
+ for (Data8-- ;Data8; Data8-- ){
+ PMPortEnumeration = (PMPortEnumeration << 1) | 1;
+ }
+
+ // Port Multiplier loop
+ for (CurrentPMPort = 0; PMPortEnumeration & 1 ; PMPortEnumeration >>= 1, CurrentPMPort++ ){
+ DetectAndConfigureDevice(This, Controller, RemainingDevicePath, AhciBusInterface, IdeControllerInterface, CurrentPort, CurrentPMPort);
+ }
+
+ }
+
+NextDevice:
+ IdeControllerInterface->NotifyPhase(IdeControllerInterface, EfiIdeAfterChannelEnumeration, CurrentPort);
+
+ }
+
+
+ TRACE_AHCI((-1," AHCI Driver Detection and Configuratiion Ends\n"));
+
+ Status = pBS->LocateProtocol (
+ &gAtaPassThruInitProtocolGuid,
+ NULL,
+ &AtaPassThruInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(AtaPassThruInitProtocol != NULL) {
+ AtaPassThruInitProtocol->InstallAtaPassThru(Controller, TRUE);
+ }
+ }
+
+ // SCSIPassThruAtapi install
+ Status = pBS->LocateProtocol (
+ &gScsiPassThruAtapiInitProtocolGuid,
+ NULL,
+ &gScsiPassThruAtapiInitProtocol
+ );
+
+
+ if(!EFI_ERROR(Status)) {
+ if(gScsiPassThruAtapiInitProtocol != NULL) {
+ gScsiPassThruAtapiInitProtocol->InstallScsiPassThruAtapi(Controller, TRUE);
+ }
+ }
+
+ // Handle the Onboard Raid controller Password Verification
+
+ Status = pBS->HandleProtocol(Controller,
+ &gHddSecurityEndProtocolGuid,
+ & TempProtocolPtr
+ );
+
+ if(Status == EFI_SUCCESS) {
+ //
+ // Protocol already installed on the Controller handle.
+ // Re-Install the protocol interface to Notify the Password verification
+ //
+ Status = pBS->ReinstallProtocolInterface(
+ &Controller,
+ &gHddSecurityEndProtocolGuid, NULL,NULL
+ );
+ } else {
+ //
+ // This will notify AMITSE to invoke the HDD password Screen
+ //
+ Status = pBS->InstallProtocolInterface(
+ &Controller,
+ &gHddSecurityEndProtocolGuid, EFI_NATIVE_INTERFACE,NULL
+ );
+ }
+
+ if(!EFI_ERROR(Status) && !EFI_ERROR(SecurityStatus)) {
+
+ // Handle the Onboard Raid controller Password Verification
+
+ Status = pBS->HandleProtocol(Controller,
+ &gOnboardRaidControllerGuid,
+ &TempProtocolPtr
+ );
+ if(!EFI_ERROR(Status)) {
+
+
+ // Check the Hdd Password verification done. If the password
+ // Verification done, proceed for RAID driver launch. Otherwise
+ // Hold the Raid driver until Password verification finished.
+
+ Status = pBS->HandleProtocol(Controller,
+ &gHddPasswordVerifiedGuid,
+ &TempProtocolPtr
+ );
+
+ if(EFI_ERROR(Status)) {
+
+ // Don't launch the Raid Option rom until password verified
+
+ Status = pBS->OpenProtocol (
+ Controller,
+ &gDevicePathProtocolGuid,
+ (VOID *) &DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if(Status == EFI_SUCCESS) {
+ RaidDriverBlocked=TRUE;
+ Status = pRS->SetVariable(L"RaidDriverBlockingStatus",
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(RaidDriverBlocked),
+ &RaidDriverBlocked );
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DetectAndConfigureDevice
+//
+// Description: Detects and Configures Sata Device
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+// AHCI_BUS_PROTOCOL *AhciBusInterface,
+// EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+// UINT8 Port,
+// UINT8 PMPort
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AhciDetectDevice ConfigureDevice InitSataBlockIO InitSataDiskInfo
+//
+// Notes:
+// 1. Detect whether device is connected to the port. If no device exit.
+// 2. Install SataDevInterface. If PMPort, Configure PMPort and Exit.
+// 3. Configure the SATA device and the controller.
+// 4. Install DevicePath, BlockIO and DiskInfo protocol.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+DetectAndConfigureDevice (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ UINT8 Port,
+ UINT8 PMPort
+)
+{
+
+ EFI_STATUS Status;
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+ EFI_ATA_COLLECTIVE_MODE *SupportedModes = NULL;
+ UINT16 SecurityStatus = 0;
+
+ SataDevInterface = GetSataDevInterface(AhciBusInterface, Port, PMPort);
+
+ if (SataDevInterface && ((SataDevInterface->DeviceState == DEVICE_DETECTION_FAILED)||
+ (SataDevInterface->DeviceState == DEVICE_CONFIGURED_SUCCESSFULLY))){
+ return EFI_SUCCESS;
+ }
+
+ Status = AhciDetectDevice(AhciBusInterface, IdeControllerInterface, Port, PMPort);
+ SataDevInterface = GetSataDevInterface(AhciBusInterface, Port, PMPort);
+ if (EFI_ERROR(Status)) {
+ if (SataDevInterface) SataDevInterface->DeviceState = DEVICE_DETECTION_FAILED;
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (!SataDevInterface) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ SataDevInterface->DeviceState = DEVICE_DETECTED_SUCCESSFULLY;
+
+ //
+ // if this is a Port Multiplier skip the rest
+ //
+ if (SataDevInterface->DeviceType == PMPORT) {
+ SataDevInterface->DeviceState = DEVICE_CONFIGURED_SUCCESSFULLY;
+
+ //
+ //Update Port Multiplier Data
+ //
+ Status = ConfigurePMPort(SataDevInterface);
+ if (!EFI_ERROR(Status)) {
+ TRACE_AHCI((-1,"AHCI: SATA Device type %x detected at Port Number : %x, PM Port Number : %x\n",
+ SataDevInterface->DeviceType, SataDevInterface->PortNumber, SataDevInterface->PMPortNumber));
+ }
+ return Status;
+ }
+
+ Status = ConfigureDevice(SataDevInterface, &SupportedModes);
+ if (EFI_ERROR(Status)) {
+ ERROR_CODE(DXE_IDE_DEVICE_FAILURE, EFI_ERROR_MAJOR);
+ SataDevInterface->DeviceState = DEVICE_DETECTION_FAILED;
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = ConfigureController(SataDevInterface, SupportedModes);
+ if (EFI_ERROR(Status)) {
+ ERROR_CODE(DXE_IDE_DEVICE_FAILURE, EFI_ERROR_MAJOR);
+ SataDevInterface->DeviceState = DEVICE_DETECTION_FAILED;
+ return EFI_DEVICE_ERROR;
+ }
+
+ SataDevInterface->DeviceState = DEVICE_CONFIGURED_SUCCESSFULLY;
+
+ Status = ConfigureSataPort(SataDevInterface);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Create the Devicepath
+ //
+ Status = CreateSataDevicePath (This, Controller, SataDevInterface, RemainingDevicePath);
+ if (EFI_ERROR(Status)) { return EFI_DEVICE_ERROR; }
+
+ //
+ // Initialize Block_IO Protocol
+ //
+ Status = InitSataBlockIO (SataDevInterface);
+ if (EFI_ERROR(Status)){
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Initialize IDE EFI_DISK_INFO_PROTOCOL
+ //
+ Status = InitSataDiskInfo (SataDevInterface);
+ if (EFI_ERROR(Status)){
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Install Devicepath
+ //
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &(SataDevInterface->IdeDeviceHandle),
+ &gDevicePathProtocolGuid, SataDevInterface->DevicePathProtocol,
+ NULL);
+
+ if(EFI_ERROR(Status)) {
+ SataDevInterface->DeviceState = DEVICE_DETECTION_FAILED;
+ if (EFI_ERROR(Status)){
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ //
+ // Open IdeControllerProtocol
+ //
+ Status = pBS->OpenProtocol(Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ (VOID **)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ SataDevInterface->IdeDeviceHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+
+ Status = pBS->LocateProtocol (
+ &gHddSecurityInitProtocolGuid,
+ NULL,
+ &HddSecurityInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(HddSecurityInitProtocol != NULL) {
+ HddSecurityInitProtocol->InstallSecurityInterface(SataDevInterface, TRUE);
+ }
+ } else {
+
+ //
+ // If Security Feature support is not enabled, always freeze
+ // lock the security feature
+ //
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_82 & 0x2) {
+ COMMAND_STRUCTURE CommandStructure;
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SECURITY_FREEZE_LOCK;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ //
+ // if Device Configuration Overlay feature set supported then issue the
+ // Dev config Free lock command.
+ //
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x800) {
+ CommandStructure.Command = DEV_CONFIG_FREEZE_LOCK;
+ CommandStructure.Features = DEV_CONFIG_FREEZE_LOCK_FEATURES;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ //
+ // Update the Identify device buffer
+ //
+ Status = GetIdentifyData(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ }
+
+ Status = pBS->LocateProtocol (
+ &gOpalSecInitProtocolGuid,
+ NULL,
+ &OpalSecInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(OpalSecInitProtocol != NULL) {
+ OpalSecInitProtocol->InstallOpalSecurityInterface(SataDevInterface, TRUE);
+ }
+ }
+
+ Status = pBS->LocateProtocol (
+ &gHddSmartInitProtocolGuid,
+ NULL,
+ &HddSmartInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(HddSmartInitProtocol != NULL) {
+ HddSmartInitProtocol->InitSMARTSupport(SataDevInterface, TRUE);
+ //
+ // Update the Idendify Data.
+ //
+ Status = GetIdentifyData(SataDevInterface);
+ if(HddSmartInitProtocol->SmartDiagonasticFlag) {
+ HddSmartInitProtocol->InstallSMARTInterface(SataDevInterface, TRUE);
+ }
+ }
+ }
+
+ //
+ // Check BlockIO has been installed or not.
+ //
+ Status = pBS->OpenProtocol( SataDevInterface->IdeDeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ SataDevInterface->IdeDeviceHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ //
+ // BLOCKIO not installed and device has been configured successfully
+ //
+ Status = EFI_UNSUPPORTED;
+ SecurityStatus = 0;
+ }
+
+ if ((Status == EFI_UNSUPPORTED) || (!(SecurityStatus & 4))){
+ //
+ // Either the device doesn't support Security Mode OR Device is not locked
+ //
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &(SataDevInterface->IdeDeviceHandle),
+ &gEfiDiskInfoProtocolGuid,
+ (EFI_DISK_INFO_PROTOCOL *)(SataDevInterface->SataDiskInfo),
+ NULL);
+
+#if HDD_PASSWORD_SUPPORT_UNDER_RAIDMODE
+ if (!(!(AhciBusInterface->AHCIRAIDMODE) && (SataDevInterface->DeviceType == ATA))) {
+#endif
+
+ //
+ // If it's Raid mode and AHCIBUS handles the ATAPI devices, install the BlockIo
+ // for the ATAPI devices. BlockIo Will be installed for all the ATA and ATAPI device under AHCI mode
+ //
+ if (!(!(AhciBusInterface->AHCIRAIDMODE) && (AhciPlatformPolicy->AhciBusAtapiSupport == FALSE ))) {
+
+ //
+ // Either the device doesn't support Security Mode OR Device is not locked
+ //
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &(SataDevInterface->IdeDeviceHandle),
+ &gEfiBlockIoProtocolGuid,
+ (EFI_BLOCK_IO_PROTOCOL *)(SataDevInterface->SataBlkIo),
+ NULL);
+ }
+
+#if HDD_PASSWORD_SUPPORT_UNDER_RAIDMODE
+ }
+#endif
+
+ } // Install BLOCKIO
+
+ TRACE_AHCI((-1,"AHCI: SATA Device type %x detected at Port Number : %x, PM Port Number : %x\n",
+ SataDevInterface->DeviceType, SataDevInterface->PortNumber, SataDevInterface->PMPortNumber));
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AhciBusStop
+//
+// Description: Uninstall all devices installed in start procedure.
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN UINTN NumberOfChildren,
+// IN EFI_HANDLE *ChildHandleBuffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+// 1. Check whether "gEfiAhciBusProtocolGuid" is installed on this
+// controller. If not exit with error.
+// 2. If "NumberOfChildren" is zero, check wether all child devices
+// have been stopped. If not exit with error.If all child devices
+// have been stopped, then close "gEfiAhciBusProtocolGuid" and
+// "gEfiIdeControllerInitProtocolGuid",uninstall
+// "gEfiIdeControllerInitProtocolGuid" and then exit with success.
+// 3. If "NumberOfChildren" is non-zero, close
+// "gEfiIdeControllerInitProtocolGuid" opened by the child device
+// in start function.Uninstall all protocols installed on this
+// child device in start function,free up all resources allocated
+// in start function. Repeat step 3 for all child devices and
+// return success at the end.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AhciBusStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+ SATA_DEVICE_INTERFACE *SataDeviceInterface;
+ EFI_STATUS Status;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface;
+ UINT16 Index = 0;
+ UINT16 Port=0;
+ UINT16 PMPort=0;
+ BOOLEAN Flag = TRUE;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ DLINK *dlink;
+
+ //
+ // Check if AHCI_BUS_PROTOCOL is installed on the Controller.
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiAhciBusProtocolGuid,
+ (VOID **)&AhciBusInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check if ChildHandleBuffer is valid
+ //
+ if (NumberOfChildren) {
+ while (NumberOfChildren) {
+
+
+ Status = pBS->CloseProtocol ( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]);
+
+ Status = pBS->OpenProtocol(
+ ChildHandleBuffer[Index],
+ &gDevicePathProtocolGuid,
+ (VOID **)&DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ //
+ // Lookout for SATA device path ACPI_DEVICE path, PCI
+ // Device path and then ATAPI device path will be the sequence
+ //
+ do {
+ if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_USB_SATA_DP)) {
+ Port = ((SATA_DEVICE_PATH *)DevicePath)->PortNumber;
+ PMPort = ((SATA_DEVICE_PATH *)DevicePath)->MultiplierPortNumber;
+ break;
+ }
+ else {
+ DevicePath = NEXT_NODE(DevicePath);
+ }
+ } while (DevicePath->Type != END_DEVICE_PATH);
+
+ if(DevicePath->Type == END_DEVICE_PATH) {
+ //Unable to find the Messaging device path node.
+ ASSERT(FALSE);
+ return EFI_DEVICE_ERROR;
+ }
+
+ SataDeviceInterface = GetSataDevInterface(AhciBusInterface, (UINT8)Port, (UINT8)PMPort);
+ if (!SataDeviceInterface) return EFI_DEVICE_ERROR;
+
+ //
+ // Before uninstalling DiskInfo check whether it is installed or not
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gEfiDiskInfoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status == EFI_SUCCESS) {
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDiskInfoProtocolGuid,
+ (EFI_DISK_INFO_PROTOCOL *)(SataDeviceInterface->SataDiskInfo),
+ NULL);
+ }
+
+ //
+ // Before uninstalling BLOCKIO check whether it is installed or not
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status == EFI_SUCCESS) {
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid,
+ (EFI_BLOCK_IO_PROTOCOL *)(SataDeviceInterface->SataBlkIo),
+ NULL);
+ }
+
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gDevicePathProtocolGuid,
+ SataDeviceInterface->DevicePathProtocol,
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ } else {
+
+ //
+ // Now free up all resources allocated.
+ //
+ if (SataDeviceInterface->AtapiDevice != NULL){
+ pBS->FreePool(SataDeviceInterface->AtapiDevice->PacketBuffer);
+ pBS->FreePool(SataDeviceInterface->AtapiDevice->InquiryData);
+ pBS->FreePool(SataDeviceInterface->AtapiDevice);
+ }
+
+ //
+ // Freeup resources allocated for component names
+ //
+ if (SataDeviceInterface->UDeviceName != NULL) {
+ pBS->FreePool(SataDeviceInterface->UDeviceName->Language);
+ pBS->FreePool(SataDeviceInterface->UDeviceName->UnicodeString);
+ pBS->FreePool(SataDeviceInterface->UDeviceName);
+ }
+
+ //
+ // Before uninstalling HDD security check whether it is installed or not
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gSecurityModeProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status == EFI_SUCCESS) {
+ if(HddSecurityInitProtocol != NULL) {
+ HddSecurityInitProtocol->StopSecurityModeSupport(SataDeviceInterface, TRUE);
+ }
+ }
+
+ //
+ // Before uninstalling Hdd Smart check whether it is installed or not
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gSMARTProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status == EFI_SUCCESS) {
+ if(HddSmartInitProtocol != NULL) {
+ if(HddSmartInitProtocol->SmartDiagonasticFlag) {
+ HddSmartInitProtocol->UnInstallSMARTInterface(SataDeviceInterface, TRUE);
+ }
+ }
+ }
+
+ //
+ // Before uninstalling OPAL security interface check whether it is installed or not.
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gStorageSecurityProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status == EFI_SUCCESS) {
+ if(OpalSecInitProtocol != NULL) {
+ OpalSecInitProtocol->UnInstallOpalSecurityInterface(SataDeviceInterface, TRUE);
+ }
+ }
+
+ pBS->FreePool(SataDeviceInterface->SataBlkIo->BlkIo.Media);
+ pBS->FreePool(SataDeviceInterface->SataBlkIo);
+ pBS->FreePool(SataDeviceInterface->SataDiskInfo);
+ pBS->FreePool (SataDeviceInterface->DevicePathProtocol);
+ DListDelete(&(AhciBusInterface->SataDeviceList), &(SataDeviceInterface->SataDeviceLink));
+ pBS->FreePool (SataDeviceInterface);
+ }
+ NumberOfChildren--;
+ Index++;
+ }
+ } else {
+
+ //
+ // Check if AHCI_BUS_PROTOCOL can be removed. No device other
+ // than Port Multiplier can be present.
+ //
+ dlink = AhciBusInterface->SataDeviceList.pHead;
+ Status = EFI_SUCCESS;
+ if (dlink){
+ do {
+ SataDeviceInterface = OUTTER(dlink, SataDeviceLink, SATA_DEVICE_INTERFACE);
+ if (SataDeviceInterface->DeviceType != PMPORT ||
+ SataDeviceInterface->DeviceState == DEVICE_CONFIGURED_SUCCESSFULLY) {
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ dlink = dlink-> pNext;
+ }while (dlink);
+ }
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Free PM resources
+ //
+ dlink = AhciBusInterface->SataDeviceList.pHead;
+ Status = EFI_SUCCESS;
+ if (dlink){
+ do {
+ SataDeviceInterface = OUTTER(dlink, SataDeviceLink, SATA_DEVICE_INTERFACE);
+ //
+ // Now free up all resources allocated.
+ //
+ if (SataDeviceInterface->AtapiDevice != NULL){
+ pBS->FreePool(SataDeviceInterface->AtapiDevice->PacketBuffer);
+ pBS->FreePool(SataDeviceInterface->AtapiDevice->InquiryData);
+ pBS->FreePool(SataDeviceInterface->AtapiDevice);
+ }
+
+ //
+ // Freeup resources allocated for component names
+ //
+ if (SataDeviceInterface->UDeviceName != NULL) {
+ pBS->FreePool(SataDeviceInterface->UDeviceName->Language);
+ pBS->FreePool(SataDeviceInterface->UDeviceName->UnicodeString);
+ pBS->FreePool(SataDeviceInterface->UDeviceName);
+ }
+ DListDelete(&(AhciBusInterface->SataDeviceList), &(SataDeviceInterface->SataDeviceLink));
+ dlink = dlink-> pNext;
+ pBS->FreePool (SataDeviceInterface);
+ }while (dlink);
+ }
+
+ //
+ // Close all the protocols opened in Start Function
+ //
+ Status = pBS->CloseProtocol ( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ //
+ // AtaPass Thru uninstall
+ //
+ Status = pBS->LocateProtocol (
+ &gAtaPassThruInitProtocolGuid,
+ NULL,
+ &AtaPassThruInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(AtaPassThruInitProtocol != NULL) {
+ AtaPassThruInitProtocol->StopAtaPassThruSupport(Controller, TRUE);
+ }
+ }
+
+ //
+ // SCSIPassThruAtapi uninstall
+ //
+ Status = pBS->LocateProtocol (
+ &gScsiPassThruAtapiInitProtocolGuid,
+ NULL,
+ &gScsiPassThruAtapiInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(gScsiPassThruAtapiInitProtocol != NULL) {
+ gScsiPassThruAtapiInitProtocol->StopScsiPassThruAtapiSupport(Controller, TRUE);
+ }
+ }
+
+ Status = pBS->CloseProtocol( Controller,
+ &gEfiAhciBusProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ Status = pBS->UninstallProtocolInterface ( Controller,
+ &gEfiAhciBusProtocolGuid,
+ AhciBusInterface);
+
+ if (EFI_ERROR(Status)) {
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiAhciBusProtocolGuid,
+ (VOID **)&AhciBusInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ (VOID **)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Free the Pages allocated for the FIS and Command List
+ if (AhciBusInterface->Address1) {
+ pBS->FreePages(AhciBusInterface->Address1,
+ EFI_SIZE_TO_PAGES(AhciBusInterface->NumberofPortsImplemented * RECEIVED_FIS_SIZE + 0x100 ));
+ }
+
+ if (AhciBusInterface->Address2) {
+ pBS->FreePages((AhciBusInterface->Address2),EFI_SIZE_TO_PAGES(COMMAND_LIST_SIZE_PORT * 2));
+ }
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InstallAhciBusProtocol
+//
+// Description: Installs BUS Init Protocol on the IDE controller Handle
+//
+// Input:
+// IN EFI_HANDLE Controller,
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface,
+// IDE_CONTROLLER_PROTOCOL *IdeControllerInterface,
+// EFI_PCI_IO_PROTOCOL *PciIO
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool, InstallProtocolInterface, AhciInitController
+//
+// Notes:
+// 1. Call AhciInitController
+// 2. Install gEfiAhciBusProtocolGuid protocol
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InstallAhciBusProtocol (
+ IN EFI_HANDLE Controller,
+ IN OUT AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ IN EFI_PCI_IO_PROTOCOL *PciIO
+ )
+{
+
+ EFI_STATUS Status;
+ UINT8 PciConfig[16];
+#if SBIDE_SUPPORT
+ IDE_SETUP_PROTOCOL *gIdeSetupProtocol;
+#endif
+
+ //
+ // Initialize the default Values
+ //
+ ZeroMemory (AhciBusInterface, sizeof(AHCI_BUS_PROTOCOL));
+
+ AhciBusInterface->ControllerHandle = Controller;
+ AhciBusInterface->IdeControllerInterface = IdeControllerInterface;
+ AhciBusInterface->PciIO = PciIO;
+ DListInit(&(AhciBusInterface->SataDeviceList));
+
+ AhciBusInterface->SataReadWritePio = SataReadWritePio;
+ AhciBusInterface->SataPioDataOut = SataPioDataOut;
+ AhciBusInterface->ExecutePioDataCommand = ExecutePioDataCommand;
+ AhciBusInterface->ExecuteNonDataCommand = ExecuteNonDataCommand;
+ AhciBusInterface->WaitforCommandComplete = WaitforCommandComplete;
+ AhciBusInterface->GeneratePortReset = GeneratePortReset;
+ AhciBusInterface->ExecutePacketCommand = ExecutePacketCommand;
+ AhciBusInterface->AHCIRAIDMODE = TRUE; // Set TRUE when in AHCI mode
+
+ Status = PciIO->Pci.Read ( PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig
+ );
+
+ if (PciConfig [IDE_SUB_CLASS_CODE]== SCC_RAID_CONTROLLER ){
+ AhciBusInterface->AHCIRAIDMODE = FALSE;
+ }
+
+ //
+ // Using setup question if needed, set Bit 0 to enable/Disable
+ // Acoustic Power Management.
+ // Set bit1 only if HDD Losses power in S3 state. HDD freeze lock
+ // command will be issued during S3 resume when this bit is set
+ // and also if Password is enabled for HDD, it will be unlocked
+ // during S3 resume.
+ //
+
+ AhciBusInterface->Acoustic_Enable = 0; // ACOUSTIC_SUPPORT_DISABLE
+
+#if SBIDE_SUPPORT
+ Status = pBS->LocateProtocol(&gIdeSetupProtocolguid, NULL, &gIdeSetupProtocol);
+
+ #if ACOUSTIC_MANAGEMENT_SUPPORT
+ if (!EFI_ERROR(Status)) {
+ AhciBusInterface->Acoustic_Enable = gIdeSetupProtocol->AcousticPwrMgmt;
+ AhciBusInterface->Acoustic_Management_Level = gIdeSetupProtocol->AcousticLevel;
+ } else {
+ AhciBusInterface->Acoustic_Enable = ACOUSTIC_SUPPORT_DISABLE;
+ AhciBusInterface->Acoustic_Management_Level = ACOUSTIC_LEVEL_BYPASS;
+ }
+ #endif //End of ACOUSTIC_MANAGEMENT_SUPPORT
+#endif // end of if SBIDE_SUPPORT
+
+
+ // Initialize PrevPortNum and PrevPortMultiplierPortNum for AtaPassThru to 0xFFFF
+
+ AhciBusInterface->PrevPortNum = 0xffff;
+ AhciBusInterface->PrevPortMultiplierPortNum = 0xffff;
+
+ //
+ // Init AHCI Controller
+ //
+ Status = AhciInitController(AhciBusInterface);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->InstallProtocolInterface(
+ &Controller,
+ &gEfiAhciBusProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ AhciBusInterface);
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AhciInitController
+//
+// Description: Initializes AHCI Controller
+//
+// Input:
+// IN OUT AHCI_BUS_PROTOCOL *AhciBusInterface
+//
+// Output:
+// EFI_STATUS
+//
+//
+// Notes:
+// 1. Update internal Data area about the AHCI controller Capabilities.
+// 2. Allocate memory for FIS and CommandList
+// 3. Enable AHCI mode
+// 3. Disable all the ports
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AhciInitController (
+ IN OUT AHCI_BUS_PROTOCOL *AhciBusInterface
+)
+{
+ EFI_STATUS Status;
+ UINT8 PciConfig[40];
+ UINT32 PortsImplemented;
+ UINT8 i, PortNumber;
+ UINT32 AhciBaseAddr;
+ UINTN AllocatePageSize = 0;
+ UINT32 Data32;
+
+
+ //
+ // Make sure AHCI Base address is programmed Properly
+ //
+ Status = AhciBusInterface->PciIO->Pci.Read (
+ AhciBusInterface->PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig
+ );
+
+ if (EFI_ERROR(Status)) { return Status;}
+
+ AhciBusInterface->AhciBaseAddress = *(UINT32 *)(PciConfig + PCI_ABAR);
+ if (!AhciBusInterface->AhciBaseAddress) return EFI_DEVICE_ERROR;
+
+ AhciBaseAddr = (UINT32) (AhciBusInterface->AhciBaseAddress);
+
+#if INDEX_DATA_PORT_ACCESS
+ Status = InitilizeIndexDataPortAddress (AhciBusInterface->PciIO);
+#endif
+
+ //
+ // Get AHCI Capability
+ //
+ AhciBusInterface->HBACapability = HBA_REG32(AhciBaseAddr, HBA_CAP);
+ if (AhciBusInterface->HBACapability == 0xFFFFFFFF) return EFI_DEVICE_ERROR; // Not decoded properly
+
+ //
+ // Get # of Ports Implemented (bit map)
+ //
+ AhciBusInterface->HBAPortImplemented = HBA_REG32(AhciBaseAddr, HBA_PI);
+ if (!AhciBusInterface->HBAPortImplemented) return EFI_DEVICE_ERROR;
+
+ //
+ // Cross check whether # of Ports implemented is less or equal to
+ // Max. # of ports supported by the silicon
+ //
+ PortsImplemented = AhciBusInterface->HBAPortImplemented;
+ AhciBusInterface->NumberofPortsImplemented = 0;
+ for ( ;PortsImplemented; PortsImplemented >>= 1){
+ if (PortsImplemented & 1) AhciBusInterface->NumberofPortsImplemented++;
+ }
+ if (((AhciBusInterface->HBACapability & HBA_CAP_NP_MASK) + 1) < AhciBusInterface->NumberofPortsImplemented)
+ { return EFI_DEVICE_ERROR; }
+
+ //
+ // Get the HBA version #
+ //
+ AhciBusInterface->AhciVersion = HBA_REG32(AhciBaseAddr, HBA_VS);
+
+ //
+ // Set AE bit
+ //
+ HBA_REG32_OR(AhciBaseAddr, HBA_GHC, HBA_GHC_AE);
+
+ //
+ // Allocate memory for FIS. Should be aligned on 256 Bytes. Each
+ // Port will have it own FIS data area.
+ //
+
+ AhciBusInterface->PortFISBaseAddr=0xFFFFFFFF;
+ AllocatePageSize = AhciBusInterface->NumberofPortsImplemented * RECEIVED_FIS_SIZE + 0x100;
+
+ Status = pBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize), // Bytes->4KiloBytes conversion
+ (EFI_PHYSICAL_ADDRESS*)&(AhciBusInterface->PortFISBaseAddr));
+
+ ZeroMemory ((VOID *) AhciBusInterface->PortFISBaseAddr,
+ AhciBusInterface->NumberofPortsImplemented * RECEIVED_FIS_SIZE + 0x100);
+ AhciBusInterface->PortFISBaseAddrEnd = AhciBusInterface->PortFISBaseAddr +
+ AhciBusInterface->NumberofPortsImplemented * RECEIVED_FIS_SIZE;
+ AhciBusInterface->Address1 = AhciBusInterface->PortFISBaseAddr; // Will be used to free the memory later
+ AhciBusInterface->PortFISBaseAddr = (AhciBusInterface->PortFISBaseAddr & (~0xFF))+ 0x100;
+
+ //
+ // Allocate memory for Command List (1KB aligned) and Command Table (128KB aligned).
+ // All the ports in the controller will share Command List and Command table data Area.
+ //
+
+ AhciBusInterface->PortCommandListBaseAddr=0xFFFFFFFF;
+ AllocatePageSize = COMMAND_LIST_SIZE_PORT * 2;
+
+ Status = pBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize), // Bytes->4KiloBytes conversion
+ (EFI_PHYSICAL_ADDRESS*)&(AhciBusInterface->PortCommandListBaseAddr));
+
+ ZeroMemory ((VOID *)AhciBusInterface->PortCommandListBaseAddr, COMMAND_LIST_SIZE_PORT * 2);
+ AhciBusInterface->Address2 = AhciBusInterface->PortCommandListBaseAddr;
+
+ AhciBusInterface->PortCommandListBaseAddr = (AhciBusInterface->PortCommandListBaseAddr & (~0x3FF)) + 0x400;
+ AhciBusInterface->PortCommandListLength = 0x20;
+ AhciBusInterface->PortCommandTableBaseAddr = AhciBusInterface->PortCommandListBaseAddr + 0x80;
+ AhciBusInterface->PortCommandTableLength = COMMAND_LIST_SIZE_PORT - 0x80;
+
+ //
+ // Make sure controller is not running
+ //
+ PortsImplemented = AhciBusInterface->HBAPortImplemented;
+ PortNumber = 0;
+ for (i=0; PortsImplemented; PortsImplemented>>=1, PortNumber++){
+ if (PortsImplemented & 1) {
+
+ //
+ // Program PxCLB and PxFB
+ //
+ HBA_PORT_WRITE_REG32 (AhciBaseAddr, PortNumber, HBA_PORTS_CLB,AhciBusInterface->PortCommandListBaseAddr);
+
+ HBA_PORT_WRITE_REG32 (AhciBaseAddr, PortNumber, 0x0008, AhciBusInterface->PortFISBaseAddr +(i * RECEIVED_FIS_SIZE));
+
+ //
+ // Clear Start
+ //
+ HBA_PORT_REG32_AND(AhciBaseAddr, PortNumber, HBA_PORTS_CMD, ~(HBA_PORTS_CMD_ST));
+
+ //
+ // Make sure CR is 0 with in 500msec
+ //
+ Status = WaitForMemClear(AhciBaseAddr, PortNumber, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_CR_CLEAR_TIMEOUT
+ );
+
+ if (EFI_ERROR(Status)) {
+ // Get the Port Speed allowed and Interface Power Management Transitions Allowed
+ // Pass the values for PortReset.
+ Data32 = HBA_PORT_REG32 ((UINT32)(AhciBusInterface->AhciBaseAddress), PortNumber, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+
+ Status = GeneratePortReset(AhciBusInterface, NULL, PortNumber, 0xFF,
+ (UINT8)((Data32 & 0xF0) >> 4), (UINT8)(Data32 >> 8));
+ }
+
+ if (EFI_ERROR(Status)) {
+ HostReset(AhciBusInterface);
+ }
+
+ //
+ // Clear FIS receive enable.
+ //
+ HBA_PORT_REG32_AND (AhciBaseAddr, PortNumber,
+ HBA_PORTS_CMD, ~(HBA_PORTS_CMD_FRE));
+ //
+ // Make sure FR is 0 with in 500msec
+ //
+ Status = WaitForMemClear(AhciBaseAddr, PortNumber, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ HBA_PORT_REG32_OR (AhciBaseAddr, PortNumber,
+ HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR); // Clear Status register
+
+ i++;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPortImplemented
+//
+// Description: Check if the port is implemented in the AHCI Controller
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN UINT8 Port
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// 1. Check Port Implemented register whether the PORT is
+// implemented in the Controller or not.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckPortImplemented (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN UINT8 Port
+)
+{
+
+ if (AhciBusInterface->HBAPortImplemented & (1<< Port)) return EFI_SUCCESS;
+
+ return EFI_NOT_FOUND;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciDetectDevice
+//
+// Description: Detects a SATA device connected to given Port and PMPort
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: CheckDevicePresence CheckPMDevicePresence GenerateSoftReset
+//
+// Notes:
+// 1. if CheckDevicePresence fails exit.
+// 2. If Controller supports PM, issue Softreset
+// 3. Check the Device Signature.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AhciDetectDevice (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+
+ PROGRESS_CODE(DXE_IDE_DETECT);
+
+ IdeControllerInterface->NotifyPhase (IdeControllerInterface, EfiIdeBusBeforeDevicePresenceDetection, Port);
+
+ SataDevInterface = GetSataDevInterface(AhciBusInterface, Port, PMPort);
+
+ if (!SataDevInterface){
+
+ //
+ // A device is present.
+ //
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof(SATA_DEVICE_INTERFACE),
+ (VOID**)&SataDevInterface);
+ if (EFI_ERROR(Status)) return Status;
+
+ ZeroMemory (SataDevInterface, sizeof(SATA_DEVICE_INTERFACE));
+
+ SataDevInterface->PortNumber = Port;
+ SataDevInterface->PMPortNumber = PMPort;
+ SataDevInterface->AhciBusInterface = AhciBusInterface;
+ SataDevInterface->DeviceState = DEVICE_IN_RESET_STATE;
+
+ //
+ // Update Base addresses
+ //
+ SataDevInterface->PortCommandListBaseAddr = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_CLB);
+ SataDevInterface->PortFISBaseAddr = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_FB);
+
+ //
+ // Add to the AhciBusInterface
+ //
+ DListAdd(&(AhciBusInterface->SataDeviceList), &(SataDevInterface->SataDeviceLink));
+
+
+ }
+
+ if (PMPort == 0xFF) {
+ Status = CheckDevicePresence (SataDevInterface, IdeControllerInterface, Port, PMPort);
+ }
+ else {
+ Status = CheckPMDevicePresence (SataDevInterface, IdeControllerInterface, Port, PMPort);
+ }
+
+ if (EFI_ERROR(Status)) {
+ IdeControllerInterface->NotifyPhase (IdeControllerInterface, EfiIdeBusAfterDevicePresenceDetection, Port);
+ if (SataDevInterface->DeviceState == DEVICE_IN_RESET_STATE) {
+ DListDelete(&(AhciBusInterface->SataDeviceList), &(SataDevInterface->SataDeviceLink));
+ pBS->FreePool(SataDevInterface);
+ }
+ return EFI_DEVICE_ERROR;
+ }
+
+ #if PORT_MULTIPLIER_SUPPORT
+ //
+ // Check if PM support is present
+ //
+ if (AhciBusInterface->HBACapability & HBA_CAP_SPM) {
+ Status = GenerateSoftReset(SataDevInterface, PMPort == 0xFF ? CONTROL_PORT : PMPort);
+ if (EFI_ERROR(Status)) {
+
+ //
+ // We know link has been established, meaning device is
+ // present. Maybe we need delay before giving a Soft reset.
+ //
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (!EFI_ERROR(Status)){
+ pBS->Stall(3000000); // 3sec delay
+ Status = GenerateSoftReset(SataDevInterface, PMPort == 0xFF ? CONTROL_PORT : PMPort);
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ IdeControllerInterface->NotifyPhase (IdeControllerInterface, EfiIdeBusAfterDevicePresenceDetection, Port);
+ if (SataDevInterface->DeviceState == DEVICE_IN_RESET_STATE) {
+ DListDelete(&(AhciBusInterface->SataDeviceList), &(SataDevInterface->SataDeviceLink));
+ pBS->FreePool(SataDevInterface);
+ }
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ #endif
+
+ if (!(SataDevInterface->PortCommandListBaseAddr) || !(SataDevInterface->PortFISBaseAddr)) {
+ ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
+ }
+
+ //
+ // Save the Signature
+ //
+ SataDevInterface->Signature = HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_SIG);
+ switch (SataDevInterface->Signature) {
+ case ATA_SIGNATURE_32:
+ SataDevInterface->DeviceType = ATA;
+ break;
+ case ATAPI_SIGNATURE_32:
+ SataDevInterface->DeviceType = ATAPI;
+ break;
+ case PMPORT_SIGNATURE:
+ SataDevInterface->DeviceType = PMPORT;
+ // 1 sec Delay needed for the next device to be discovered from PM.
+ pBS->Stall(1000000);
+ break;
+ default:
+ Status = EFI_DEVICE_ERROR;
+ }
+
+#if !HDD_PASSWORD_SUPPORT_UNDER_RAIDMODE
+ if ((!AhciBusInterface->AHCIRAIDMODE) && (SataDevInterface->DeviceType == ATA)) {
+ DListDelete(&(AhciBusInterface->SataDeviceList), &(SataDevInterface->SataDeviceLink));
+ pBS->FreePool(SataDevInterface);
+ Status = EFI_DEVICE_ERROR;
+ }
+#endif
+
+#if !SUPPORT_ATAPI_IN_RAID_MODE
+
+ //
+ // If the Atapi devices are handled by Raid option rom, then
+ // don't configure the Atapi devices.
+ //
+ if ((!AhciBusInterface->AHCIRAIDMODE) && (SataDevInterface->DeviceType == ATAPI)) {
+ DListDelete(&(AhciBusInterface->SataDeviceList), &(SataDevInterface->SataDeviceLink));
+ pBS->FreePool(SataDevInterface);
+ Status = EFI_DEVICE_ERROR;
+ }
+#endif
+ IdeControllerInterface->NotifyPhase (IdeControllerInterface, EfiIdeBusAfterDevicePresenceDetection, Port);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckDevicePresence
+//
+// Description: Check if any device is connected to the port
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: HandlePortComReset CheckValidDevice GeneratePortReset
+//
+// Notes:
+// 1. If Staggered spin-up is supported, power-up the device.
+// 2. Call CheckValidDevice if success exit. Else generate Softreset.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckDevicePresence (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ UINT8 CapIss;
+ UINT8 PortSpeed=0;
+ UINT8 CurrentPortSpeed=0;
+ UINT32 Data32;
+
+ //
+ // PM disabled
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SCTL, HBA_PORTS_SCTL_IPM_PSD_SSD);
+
+ //
+ // Clear Status register
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ //
+ // Get the Interface Speed Support( Maximum Speed supported)
+ //
+ CapIss = (UINT8)((HBA_REG32(AhciBaseAddr, HBA_CAP) & HBA_CAP_ISS_MASK)>>20);
+
+ //
+ // Get the Speed Allowed (SPD) for the Port. Maximum speed allowed for the Port
+ //
+ PortSpeed = (UINT8)((HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_SCTL)
+ & HBA_PORTS_SCTL_SPD_MASK)>>4);
+
+ //
+ // If the Maximum speed allowed is programmed for the port, use the Port Speed allowed value
+ //
+ if(PortSpeed != 0 ) {
+ if(PortSpeed > CapIss) {
+ //
+ // Port Speed allowed can't be more than Interface Speed. So limit Port speed to Interface Speed
+ //
+ PortSpeed = CapIss;
+ }
+ } else {
+ //
+ // If there is no Maximum speed allowed for the port, use the Interface Speed
+ //
+ PortSpeed = CapIss;
+ }
+
+ //
+ // Check if Link is already established
+ //
+ if ((HBA_PORT_REG32 (AhciBusInterface->AhciBaseAddress, Port, HBA_PORTS_SSTS)
+ & HBA_PORTS_SSTS_DET_MASK) == HBA_PORTS_SSTS_DET_PCE) {
+
+ //
+ // As the Link is already established, get the negotiated interface
+ // communication speed
+ //
+ CurrentPortSpeed = (UINT8)((HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_SSTS)
+ & HBA_PORTS_SSTS_SPD_MASK)>>4);
+
+ //
+ // Check the Current Interface Speed with Speed Allowed. If current inerface speed is more than
+ // Speed allowed set, then set the port speed according to the speed allowed
+ //
+ if( CurrentPortSpeed > PortSpeed) {
+
+ Status = GeneratePortReset(AhciBusInterface, SataDevInterface, Port, PMPort,
+ PortSpeed, HBA_PORTS_SCTL_IPM_PSSD);
+ }
+ } else {
+ //
+ // Link Not Established. Set SPD by PortSpeed
+ //
+ CapIss = (UINT8)((HBA_REG32(AhciBaseAddr, HBA_CAP) & HBA_CAP_ISS_MASK)>>20);
+ HBA_PORT_REG32_AND_OR (AhciBaseAddr, Port, HBA_PORTS_SCTL, ~HBA_PORTS_SCTL_SPD_MASK,PortSpeed<<4 );
+ }
+
+ //
+ // Check if Staggered Spinup is supported
+ //
+ if (HBA_REG32 (AhciBaseAddr, HBA_CAP) & HBA_CAP_SSS) {
+
+ //
+ // Check if Link is already established, if yes dodn't expect a COMRESET
+ //
+ if ((HBA_PORT_REG32 (AhciBusInterface->AhciBaseAddress, Port, HBA_PORTS_SSTS)
+ & HBA_PORTS_SSTS_DET_MASK) != HBA_PORTS_SSTS_DET_PCE) {
+ //
+ // Enable FIS Receive Enable
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE);
+
+ //
+ // Wait till FIS is running
+ //
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_SUD); // Spin up the device
+
+ //
+ // Todo Todo delay necessary here after power up?
+ //
+ Status = HandlePortComReset(AhciBusInterface, NULL, Port, 0xFF);
+
+ //
+ // Disable FIS Receive Enable
+ //
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~HBA_PORTS_CMD_FRE);
+
+ IdeControllerInterface->NotifyPhase (IdeControllerInterface, EfiIdeBusAfterDevicePresenceDetection, Port);
+ }
+ else {
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_SUD); // Spin up the device
+ }
+ }
+
+ //
+ // Check if Device detected. And check if Cold Presence logic
+ // is enabled. If yes enable POD
+ //
+ if (((HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SSTS) & HBA_PORTS_SSTS_DET_MASK) == HBA_PORTS_SSTS_DET_PCE) &&
+ (HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_CMD) & HBA_PORTS_CMD_CPD)) {
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_POD);
+ }
+
+ Status = CheckValidDevice(AhciBusInterface, Port, PMPort);
+
+#if PORT_MULTIPLIER_SUPPORT
+ // If PORT Multiplier support is enabled, SoftReset generated later will get the signature.
+ // No need for this additional Port Reset here
+ if ((HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SSTS) & HBA_PORTS_SSTS_DET_MASK) == HBA_PORTS_SSTS_DET_PCE) {
+ return EFI_SUCCESS;
+ }
+#else
+ if (EFI_ERROR(Status)) {
+ IdeControllerInterface->NotifyPhase (
+ IdeControllerInterface,
+ EfiIdeBeforeChannelReset,
+ (UINT8)Port
+ );
+
+ // Get the Port Speed allowed and Interface Power Management Transitions Allowed
+ // Pass the values for PortReset.
+ Data32 = HBA_PORT_REG32 ((UINT32)(AhciBusInterface->AhciBaseAddress), Port, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+
+ Status = GeneratePortReset(
+ AhciBusInterface,
+ SataDevInterface,
+ Port,
+ PMPort,
+ (UINT8)((Data32 & 0xF0) >> 4),
+ (UINT8)(Data32 >> 8)
+ );
+
+ IdeControllerInterface->NotifyPhase (
+ IdeControllerInterface,
+ EfiIdeAfterChannelReset,
+ (UINT8)Port
+ );
+ }
+#endif
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPMDevicePresence
+//
+// Description: Checks for the presence device behind a Port Multiplier.
+//
+// Input:
+// SATA_DEVICE_INTERFACE *SataDevInterface,
+// EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+// UINT8 Port,
+// UINT8 PMPort
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadWritePMPort GeneratePortReset
+//
+// Notes:
+// 1. Check whether communication is established?
+// 2. If yes exit else issues Port Reset
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckPMDevicePresence (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ UINT32 Data32 = 0, Init_SStatus = 0;
+
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_0_SSTATUS, &Init_SStatus, FALSE);
+
+ SataDevInterface->SControl = HBA_PORTS_SCTL_IPM_PSD_SSD;
+ if ((Init_SStatus & HBA_PORTS_SSTS_DET_MASK) == HBA_PORTS_SSTS_DET_PCE) {
+ Data32 = HBA_PORTS_SCTL_IPM_PSD_SSD;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_2_SCONTROL, &Data32, TRUE);
+ } else {
+
+ //
+ // Perform Port Reset to bring the communication back
+ //
+ IdeControllerInterface->NotifyPhase (
+ IdeControllerInterface,
+ EfiIdeBeforeChannelReset,
+ (UINT8)Port
+ );
+
+ // Get the Port Speed allowed and Interface Power Management Transitions Allowed
+ // Pass the values for PortReset.
+ Data32 = HBA_PORT_REG32 ((UINT32)(AhciBusInterface->AhciBaseAddress), Port, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+
+ Status = GeneratePortReset(
+ AhciBusInterface,
+ SataDevInterface,
+ Port,
+ PMPort,
+ (UINT8)((Data32 & 0xF0) >> 4),
+ (UINT8)(Data32 >> 8)
+ );
+
+ IdeControllerInterface->NotifyPhase (
+ IdeControllerInterface,
+ EfiIdeAfterChannelReset,
+ (UINT8)Port
+ );
+
+ // Giving a Softreset immediatly after Port Reset doesn't help to detect the
+ // devices behind PM quickly. Add a delay here before Softreset is generated.
+ // Add 1Sec delay
+ pBS->Stall(1000000);
+ }
+
+ //
+ // Clear Status register
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ Data32 = HBA_PORTS_ERR_CLEAR;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_1_SERROR, &Data32, TRUE);
+
+ Data32 = 0;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_0_SSTATUS, &Data32, FALSE);
+
+ if ((Data32 & HBA_PORTS_SSTS_DET_MASK) == HBA_PORTS_SSTS_DET_PCE) Status = EFI_SUCCESS;
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConfigureSataPort
+//
+// Description: Configure Sata Port settings
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConfigureSataPort (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+
+ // Check for the ATAPI device
+ if (SataDevInterface->DeviceType == ATAPI) {
+ //
+ // Set Device is ATAPI Bit in CMD register
+ //
+ HBA_PORT_REG32_OR (
+ SataDevInterface->AhciBusInterface->AhciBaseAddress,
+ SataDevInterface->PortNumber,
+ HBA_PORTS_CMD,
+ HBA_PORTS_CMD_ATAPI
+ );
+ }
+
+ // Check the AHCI platform policy protocol to set the
+ // Drive LED on ATAPI Enable (DLAE) bit
+
+ if(AhciPlatformPolicy->DriverLedOnAtapiEnable) {
+ //
+ // Set Drive LED on ATAPI Enable (DLAE) Bit in CMD register
+ //
+ HBA_PORT_REG32_OR (
+ SataDevInterface->AhciBusInterface->AhciBaseAddress,
+ SataDevInterface->PortNumber,
+ HBA_PORTS_CMD,
+ HBA_PORTS_CMD_DLAE
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConfigurePMPort
+//
+// Description: Configure Port Multiplier
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+//
+// Modified:
+//
+// Referrals: ReadWritePMPort
+//
+// Notes:
+// 1. Read the number of Ports implemented in the Port Multiplier
+// 2. Update PM attached bit in the AHCI controller.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConfigurePMPort (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+ EFI_STATUS Status;
+ UINT32 Data;
+
+ //
+ // Read the number of Ports preset in PM
+ //
+ Status = ReadWritePMPort (SataDevInterface, CONTROL_PORT, GSCR_2, &Data, FALSE);
+ SataDevInterface->NumPMPorts = ((UINT8)Data) - 1;
+
+ //
+ // Set PM Attched bit in CMD register
+ //
+ HBA_PORT_REG32_OR (
+ SataDevInterface->AhciBusInterface->AhciBaseAddress,
+ SataDevInterface->PortNumber,
+ HBA_PORTS_CMD,
+ HBA_PORTS_CMD_PMA
+ );
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConfigureDevice
+//
+// Description: Configure the SATA device
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+// IN OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes -
+// Modes collection supported by the device
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: GetIdentifyData, GeneratePortReset, ExecuteNonDataCommand, InitAcousticSupport
+//
+// Notes:
+// 1. Get the Identify data command.
+// 2. From the IdeControllerInit protocol, get the DMA & PIO supported
+// 3. Issue Set feature command to set PIO, DMA and multiple mode
+// 4. Initialize Acoustic, SMART, Power Management features.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConfigureDevice (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT EFI_ATA_COLLECTIVE_MODE **SupportedModes
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface = AhciBusInterface->IdeControllerInterface;
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT8 Data8;
+ UINT32 Data32;
+ UINT8 Index;
+ UINT16 DeviceName[41];
+ CHAR8 Language[] = "Eng";
+ EFI_UNICODE_STRING_TABLE *tempUnicodeTable;
+
+
+ if (SataDevInterface->DeviceType == PMPORT) return EFI_SUCCESS; // This is a Port Multiplier
+
+ Status = GetIdentifyData(SataDevInterface);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+#if !DISABLE_SOFT_SET_PREV
+#if FORCE_HDD_PASSWORD_PROMPT
+ if ((SataDevInterface->DeviceType == ATA) &&
+ (SataDevInterface->IdentifyData.Reserved_76_79[0] != 0xFFFF )&&
+ (SataDevInterface->IdentifyData.Reserved_76_79[2] & 0x0040)&& // Software Preservation support
+ (SataDevInterface->IdentifyData.Reserved_76_79[3] & 0x0040)){ // Software Preservation Enabled
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.Features = DISABLE_SATA2_SOFTPREV; // Disable Software Preservation
+ CommandStructure.SectorCount = 6;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+
+ // Get the Port Speed allowed and Interface Power Management Transitions Allowed
+ // Pass the values for PortReset.
+ Data32 = HBA_PORT_REG32 ((UINT32)(AhciBusInterface->AhciBaseAddress), Port, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+
+ GeneratePortReset(AhciBusInterface,
+ SataDevInterface,
+ Port,
+ PMPort,
+ (UINT8)((Data32 & 0xF0) >> 4),
+ (UINT8)(Data32 >> 8)
+ );
+
+ CommandStructure.Features = 0x10; // Enable Software Preservation
+ CommandStructure.SectorCount = 6;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+#endif
+#endif
+
+ //
+ // Check if Device need spin-up
+ //
+ if ((SataDevInterface->IdentifyData.General_Config_0 & 4) &&
+ (SataDevInterface->IdentifyData.Special_Config_2 == SPIN_UP_REQUIRED1 ||
+ SataDevInterface->IdentifyData.Special_Config_2 == SPIN_UP_REQUIRED2 )){
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SET_DEVICE_SPINUP;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+
+ //
+ // Get the Identify Command once more
+ //
+ Status = GetIdentifyData(SataDevInterface);
+ if (EFI_ERROR(Status)){
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ Status = IdeControllerInterface->SubmitData(IdeControllerInterface,
+ Port,
+ PMPort == 0xFF ? 0 : PMPort,
+ (EFI_IDENTIFY_DATA *) &(SataDevInterface->IdentifyData));
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = IdeControllerInterface->CalculateMode(IdeControllerInterface,
+ Port,
+ PMPort == 0xFF ? 0 : PMPort,
+ SupportedModes);
+
+ if (EFI_ERROR(Status) || (*SupportedModes == NULL) )
+ return EFI_INVALID_PARAMETER;
+
+ //
+ // Check ExtMode
+ //
+ if ((*SupportedModes)->ExtMode[0].TransferProtocol) { // Not Auto speed
+ Status = GeneratePortReset(AhciBusInterface, SataDevInterface, Port, PMPort,
+ (*SupportedModes)->ExtMode[0].TransferProtocol, HBA_PORTS_SCTL_IPM_PSSD);
+ if (PMPort != 0xFF) {
+ Data32 = HBA_PORTS_ERR_CLEAR;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_1_SERROR, &Data32, TRUE);
+ }
+ }
+
+ Status = IdeControllerInterface->SetTiming(IdeControllerInterface,
+ Port,
+ PMPort == 0xFF ? 0 : PMPort,
+ (*SupportedModes));
+ if (EFI_ERROR(Status)) return Status;
+
+ SataDevInterface->PIOMode = 0xff;
+ SataDevInterface->SWDma = 0xff;
+ SataDevInterface->MWDma = 0xff;
+ SataDevInterface->UDma = 0xff;
+
+ if ((*SupportedModes)->PioMode.Valid)
+ SataDevInterface->PIOMode = (*SupportedModes)->PioMode.Mode;
+
+ if ((*SupportedModes)->SingleWordDmaMode.Valid)
+ SataDevInterface->SWDma = (*SupportedModes)->SingleWordDmaMode.Mode;
+
+ if ((*SupportedModes)->MultiWordDmaMode.Valid)
+ SataDevInterface->MWDma = (*SupportedModes)->MultiWordDmaMode.Mode;
+
+ if ((*SupportedModes)->UdmaMode.Valid)
+ SataDevInterface->UDma = (*SupportedModes)->UdmaMode.Mode;
+
+ SataDevInterface->IORdy = ((EFI_IDENTIFY_DATA *)&(SataDevInterface->IdentifyData))->AtaData.capabilities & 0x800;
+
+ if ((SataDevInterface->IdentifyData.Valid_Bits_53 & 0x2) && ((*SupportedModes)->PioMode.Valid)){
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SET_TRANSFER_MODE;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.SectorCount = PIO_FLOW_CONTROL | SataDevInterface->PIOMode;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+
+ if (EFI_ERROR(Status))
+ return EFI_DEVICE_ERROR;
+
+ //
+ // Issue Set Multiple Mode Command only for ATA device
+ //
+ if (SataDevInterface->DeviceType == ATA){
+ Data8 = SataDevInterface->IdentifyData.Maximum_Sector_Multiple_Command_47 & 0xff;
+ if (Data8 & 0x2) Data8 = 2;
+ if (Data8 & 0x4) Data8 = 0x4;
+ if (Data8 & 0x8) Data8 = 0x8;
+ if (Data8 & 0x10) Data8 = 0x10;
+ if (Data8 & 0x20) Data8 = 0x20;
+ if (Data8 & 0x40) Data8 = 0x40;
+ if (Data8 & 0x80) Data8 = 0x80;
+
+ if (Data8 > 1) {
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_MULTIPLE_MODE;
+ CommandStructure.SectorCount = Data8;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ }
+
+ //
+ // Check if UDMA is supported
+ //
+ if (SataDevInterface->UDma != 0xff){
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SET_TRANSFER_MODE;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.SectorCount = UDMA_MODE | SataDevInterface->UDma;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ else {
+ if (SataDevInterface->MWDma != 0xff){
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SET_TRANSFER_MODE;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.SectorCount = MWDMA_MODE | SataDevInterface->MWDma;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ }
+
+ //
+ // Convert the Device string from Engligh to Unicode
+ //
+ SataDevInterface->UDeviceName = NULL;
+ for (Index = 0; Index < 40; Index += 2) {
+ DeviceName[Index] = ((UINT8 *)SataDevInterface->IdentifyData.Model_Number_27)[Index + 1];
+ DeviceName[Index + 1] = ((UINT8 *)SataDevInterface->IdentifyData.Model_Number_27)[Index];
+ }
+ DeviceName[40] = 0; // Word
+
+ tempUnicodeTable = MallocZ(sizeof (EFI_UNICODE_STRING_TABLE) * 2);
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (Language),
+ (VOID**)&tempUnicodeTable[0].Language
+ );
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (DeviceName),
+ (VOID**)&tempUnicodeTable[0].UnicodeString
+ );
+
+ pBS->CopyMem(tempUnicodeTable[0].Language, &Language, sizeof(Language));
+ pBS->CopyMem(tempUnicodeTable[0].UnicodeString, DeviceName, sizeof (DeviceName));
+ tempUnicodeTable[1].Language = NULL;
+ tempUnicodeTable[1].UnicodeString = NULL;
+ SataDevInterface->UDeviceName = tempUnicodeTable;
+
+ #if SBIDE_SUPPORT
+ InitMiscConfig(SataDevInterface);
+ #endif
+
+
+ if( AhciPlatformPolicy->DipmSupport) {
+ // Initialize and Enable Device initiated Power management
+ InitializeDipm(SataDevInterface);
+ }
+
+ if( AhciPlatformPolicy->DeviceSleepSupport) {
+ // Initialize and Enable Device Sleep Support
+ InitializeDeviceSleep(SataDevInterface);
+ }
+
+
+ ConfigurePowerUpInStandby(SataDevInterface);
+
+ Status = GetIdentifyData(SataDevInterface);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConfigureController
+//
+// Description: Configure the AHCI Controller
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+// IN EFI_ATA_COLLECTIVE_MODE *SupportedModes -
+// Modes collection supported by the device
+//
+// Output:
+// EFI_STATUS
+//
+//
+// Notes:
+// 1. Issue IdeControllerInterface->SetTiming for setting uDMA
+// and PIO mode timings in the controller.
+// 2. Update the Read/Write command for the device
+// 3. Update the Device name used in Component Name protocol
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConfigureController (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN EFI_ATA_COLLECTIVE_MODE *SupportedModes
+)
+{
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface = AhciBusInterface->IdeControllerInterface;
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+
+ //
+ // Check if UDMA and MWDMA are programmed successfully
+ //
+ if (SataDevInterface->UDma != 0xff) {
+ if (!(ReturnMSBset((SataDevInterface->IdentifyData.UDMA_Mode_88 >> 8)) == SataDevInterface->UDma)) {
+ SataDevInterface->UDma = ReturnMSBset((SataDevInterface->IdentifyData.UDMA_Mode_88 >> 8));
+ SupportedModes->UdmaMode.Mode = SataDevInterface->UDma;
+ IdeControllerInterface->SetTiming (IdeControllerInterface, Port,
+ PMPort == 0xFF ? 0 : PMPort, SupportedModes);
+ }
+ }
+ else {
+ if (SataDevInterface->MWDma != 0xff) {
+ if (!(ReturnMSBset(SataDevInterface->IdentifyData.MultiWord_DMA_63 >> 8) == SataDevInterface->MWDma)) {
+ SataDevInterface->MWDma = ReturnMSBset((SataDevInterface->IdentifyData.MultiWord_DMA_63 >> 8));
+ SupportedModes->MultiWordDmaMode.Mode = SataDevInterface->MWDma;
+ IdeControllerInterface->SetTiming (IdeControllerInterface, Port,
+ PMPort == 0xFF ? 0 : PMPort, SupportedModes);
+ }
+ }
+ }
+
+ //
+ // Check for ATA
+ //
+ if (SataDevInterface->DeviceType == ATA) {
+
+ //
+ // Update IDE Read/Write Command
+ //
+ if ((SataDevInterface->IdentifyData.Valid_Bits_59 & 0x100) &&
+ (SataDevInterface->IdentifyData.Valid_Bits_59 & 0xff)) { // Check if Multiple Read/Write
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x400) {
+
+ //
+ // 48Bit LBA supported
+ //
+ SataDevInterface->ReadCommand = READ_MULTIPLE_EXT;
+ SataDevInterface->WriteCommand = WRITE_MULTIPLE_EXT;
+ }
+ else {
+ SataDevInterface->ReadCommand = READ_MULTIPLE;
+ SataDevInterface->WriteCommand = WRITE_MULTIPLE;
+ }
+ } // End of Multiple
+ else { // 1 Block = 1 Sector
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x400) {
+
+ //
+ // 48Bit LBA supported
+ //
+ SataDevInterface->ReadCommand = READ_SECTORS_EXT;
+ SataDevInterface->WriteCommand = WRITE_SECTORS_EXT;
+ }
+ else {
+ SataDevInterface->ReadCommand = READ_SECTORS;
+ SataDevInterface->WriteCommand = WRITE_SECTORS;
+ }
+ }
+ if (DMACapable(SataDevInterface)) {
+ #if IDEBUSMASTER_SUPPORT
+ SataDevInterface->ReadCommand = READ_DMA;
+ SataDevInterface->WriteCommand = WRITE_DMA;
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x400) {
+
+ //
+ // 48Bit LBA supported
+ //
+ SataDevInterface->ReadCommand = READ_DMA_EXT;
+ SataDevInterface->WriteCommand = WRITE_DMA_EXT;
+ }
+ #endif
+ }
+ } // end of ATA
+
+#if DISABLE_SOFT_SET_PREV
+
+ //
+ // Software settings preserved
+ //
+ if ((SataDevInterface->DeviceType == ATA) &&
+ (SataDevInterface->IdentifyData.Reserved_76_79[0] != 0xFFFF )&&
+ (SataDevInterface->IdentifyData.Reserved_76_79[2] & 0x0040)) {
+
+ COMMAND_STRUCTURE CommandStructure;
+ EFI_STATUS Status;
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.Features = DISABLE_SATA2_SOFTPREV;
+ CommandStructure.SectorCount = 6;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+
+ //
+ // Update the Identify device buffer
+ //
+ Status = GetIdentifyData(SataDevInterface);
+ if (EFI_ERROR(Status)){
+ return EFI_DEVICE_ERROR;
+ }
+ }
+#endif
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeDipm
+//
+// Description: Initialize Dipm in the device and controller
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// VOID
+//
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+InitializeDipm (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ COMMAND_STRUCTURE CommandStructure;
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.SectorCount = DiPM_SUB_COMMAND; // 0x03 : DiPM
+
+ // Check Host Supports Aggressive Link Power Management
+ // and Check DiPM supported by device
+
+ if((SataDevInterface->AhciBusInterface->HBACapability & HBA_CAP_SALP) &&
+ (SataDevInterface->IdentifyData.Reserved_76_79[0] & IDENTIFY_DiPM_HIIPM_REQUESTS_CAPABLE) &&
+ (SataDevInterface->IdentifyData.Reserved_76_79[2] & IDENTIFY_DiPM__SUPPORT)){
+
+ // Check DiPM needs to be enabled from Platform Policy
+ if(AhciPlatformPolicy->DipmEnable) {
+ // Check DiPM is already enabled via Identify Data Word.
+ if (!(SataDevInterface->IdentifyData.Reserved_76_79[3] & IDENTIFY_DiPM_ENABLED)) {
+ // Enable DiPM and Issue Set Feature command.
+ CommandStructure.Features = DiPM_ENABLE;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ } else {
+ if (SataDevInterface->IdentifyData.Reserved_76_79[3] & IDENTIFY_DiPM_ENABLED) {
+
+ // Disable DiPM and Issue Set Feature command only if it is enabled already.
+ CommandStructure.Features = DiPM_DISABLE;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ }
+ }
+ return;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeDeviceSleep
+//
+// Description: Initialize Device Sleep in the device and controller
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// VOID
+//
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitializeDeviceSleep (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ UINT8 PortNumber = SataDevInterface->PortNumber;
+ COMMAND_STRUCTURE CommandStructure;
+ EFI_STATUS Status;
+ UINT8 DevSleep_Exit_TimeOut = DEVSLEEP_EXIT_TIMEOUT;
+ UINT8 Minimum_DevSleep_Assertion_Time = MINIMUM_DEVSLP_ASSERTION_TIME;
+ UINT8 DITO_Multiplier = 0xF;
+ UINT8 *Buffer = NULL;
+ UINT32 PxDevSlp;
+ UINT8 SectorCount = 1;
+
+ // If Aggressive DelSlp is supported then DevSlp also supported. Also check if the port supports DevSlp or not
+ if ((HBA_REG32(AhciBaseAddr, HBA_CAP2) & HBA_CAP2_SADM) &&
+ (HBA_PORT_REG32(AhciBaseAddr, PortNumber, HBA_PORTS_PxDEVSLP) & HBA_PORTS_PxDEVSLP_DSP)) {
+
+ //Clear ADSE
+ HBA_PORT_REG32_AND (AhciBaseAddr, PortNumber, HBA_PORTS_PxDEVSLP, ~(HBA_PORTS_PxDEVSLP_ADSE));
+
+ // Check Word 78 Bit8 and Word 77 Bit7 of Identify Data.
+ if ((SataDevInterface->IdentifyData.Reserved_76_79[2] & IDENTIFY_DEVSLEEP_SUPPORT) &&
+ (SataDevInterface->IdentifyData.Reserved_76_79[1] & IDENTIFY_DEVSLP_TO_REDUCED_PWRSTATE_CAPABLE)) {
+
+ if(AhciPlatformPolicy->DeviceSleepEnable) {
+
+ // DevSlp not enabled in device. Issue Set Feature command.
+ if (!(SataDevInterface->IdentifyData.Reserved_76_79[3] & IDENTIFY_DEVSLEEP_ENABLED)) {
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.SectorCount = DEVSLEEP_SUB_COMMAND;
+ CommandStructure.Features = DEVSLEEP_ENABLE;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+
+ // Allocate Memory for Identify Device Data
+ pBS->AllocatePool(EfiBootServicesData, ATA_SECTOR_BYTES, (VOID**)&Buffer);
+ ZeroMemory(Buffer, ATA_SECTOR_BYTES);
+
+ // Get Identify Device Data Log (log 30h Page 8)
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = READ_LOG_EXT;
+ CommandStructure.SectorCount = SectorCount;
+ CommandStructure.LBAMid = SERIAL_ATA_SETTINGS_PAGE;
+ CommandStructure.LBALow = IDENTIFY_DEVICE_DATA_LOG;
+ CommandStructure.ByteCount = SectorCount * ATA_SECTOR_BYTES;;
+ CommandStructure.Buffer = Buffer;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, FALSE);
+ if (!EFI_ERROR(Status)){
+
+ // Update the Time out values
+ ///BYTE 30h..37h DEVSLP Timing Variables (Qword) of Identify Device Data log (log 30h page 08h)
+ ///63 Valid
+ ///62:16 Reserved
+ ///15:8 DevSleep Exit Timeout, in ms (DETO)
+ ///5:7 Reserved
+ ///4:0 Minimum DEVSLP Assertion Time, in ms (MDAT)
+
+ DevSleep_Exit_TimeOut = Buffer[DEVSLP_TIMING_VARIABLES_OFFSET + 1] ? Buffer[DEVSLP_TIMING_VARIABLES_OFFSET + 1] : DEVSLEEP_EXIT_TIMEOUT;
+ Minimum_DevSleep_Assertion_Time = (Buffer[DEVSLP_TIMING_VARIABLES_OFFSET] & 0x1F) ? (Buffer[DEVSLP_TIMING_VARIABLES_OFFSET] & 0x1F) : MINIMUM_DEVSLP_ASSERTION_TIME;
+ }
+
+ // Program the Timeouts and Multiplier value in PxDEVSLP Registers
+ PxDevSlp = HBA_PORT_REG32 (AhciBaseAddr, PortNumber, HBA_PORTS_PxDEVSLP);
+ PxDevSlp &= ~(HBA_PORTS_PxDEVSLP_DETO_MASK | HBA_PORTS_PxDEVSLP_DMDAT_MASK | HBA_PORTS_PxDEVSLP_DM_MASK);
+ PxDevSlp |= ((DevSleep_Exit_TimeOut << 2) + (Minimum_DevSleep_Assertion_Time << 10) + (DITO_Multiplier << 25));
+ HBA_PORT_REG32_OR (AhciBaseAddr, PortNumber, HBA_PORTS_PxDEVSLP, PxDevSlp);
+
+ // Enable PxDEVSLP.ADSE
+ HBA_PORT_REG32_OR (AhciBaseAddr, PortNumber, HBA_PORTS_PxDEVSLP, HBA_PORTS_PxDEVSLP_ADSE);
+ pBS->FreePool(Buffer);
+ } else {
+ if (SataDevInterface->IdentifyData.Reserved_76_79[3] & IDENTIFY_DEVSLEEP_ENABLED) {
+
+ // Disable Device Sleep and Issue Set Feature command only if it is enabled already.
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.SectorCount = DEVSLEEP_SUB_COMMAND;
+ CommandStructure.Features = DEVSLEEP_DISABLE;
+ ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ }
+ }
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSataDevInterface
+//
+// Description:
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+//
+// Output:
+// SATA_DEVICE_INTERFACE*
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Return the Pointer to the SATA_DEVICE_INTERFACE for the given
+// Port and PM Port
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+SATA_DEVICE_INTERFACE *
+GetSataDevInterface(
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ DLINK *dlink = AhciBusInterface->SataDeviceList.pHead;
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+
+ if (!dlink) return NULL;
+ do {
+ SataDevInterface = OUTTER(dlink, SataDeviceLink, SATA_DEVICE_INTERFACE);
+ if (SataDevInterface->PortNumber == Port &&
+ SataDevInterface->PMPortNumber == PMPort ) break;
+ dlink = dlink-> pNext;
+ SataDevInterface = NULL;
+ }while (dlink);
+
+ return SataDevInterface;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitForMemSet
+//
+// Description: Wait for memory to be set to the test value.
+//
+// Input: MemTestAddr - The memory address to test
+// MaskValue - The mask value of memory
+// TestValue - The test value of memory
+// WaitTimeInMs - The time out value for wait memory set
+//
+// Output: EFI_SUCCESS - HBA reset successfully.
+// EFI_DEVICE_ERROR - HBA failed to complete hardware reset.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitForMemSet (
+ IN UINT32 BaseAddr,
+ IN UINT8 Port,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 TestValue,
+ IN UINT32 WaitTimeInMs
+)
+{
+ UINT8 Delay;
+ while(WaitTimeInMs!=0){
+ for ( Delay = 10; Delay > 0; Delay--) {
+
+ if(((HBA_PORT_REG32(BaseAddr, Port, Register)) & AndMask) == TestValue){
+ return EFI_SUCCESS;
+ }
+
+ pBS->Stall (100); // 100 usec * 10 = 1Msec
+ }
+ WaitTimeInMs--;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitForMemClear
+//
+// Description: Wait for memory to be set to the test value.
+//
+// Input: MemTestAddr - The memory address to test
+// MaskValue - The mask value of memory
+// WaitTimeInMs - The time out value for wait memory set
+//
+// Output: EFI_SUCCESS - HBA reset successfully.
+// EFI_DEVICE_ERROR - HBA failed to complete hardware reset.
+//
+// Modified:
+//
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitForMemClear (
+ IN UINT32 BaseAddr,
+ IN UINT8 Port,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 WaitTimeInMs
+)
+{
+ UINT8 Delay;
+ while(WaitTimeInMs!=0){
+ for ( Delay = 10; Delay > 0; Delay--) {
+
+ if(!((HBA_PORT_REG32(BaseAddr, Port, Register)) & AndMask)){
+ return EFI_SUCCESS;
+ }
+
+ pBS->Stall (100); // 100 usec * 10 = 1Msec
+ }
+ WaitTimeInMs--;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ReturnMSBset
+//
+// Description: Returns the MOST significant Bit set.
+//
+// Input:
+// IN UINT32 Data
+//
+// Output:
+// UINT8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+UINT8
+ReturnMSBset(
+ IN UINT32 Data
+ )
+{
+ UINT8 Index;
+ UINT8 Value = 0xFF;
+
+ for (Index = 0; Index < 32; Index++) {
+ if ( Data & 1) {
+ Value = Index;
+ }
+ Data >>= 1;
+ }
+
+ return Value;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitSataBlockIO
+//
+// Description: Initializes SATA Block IO interface
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool, OpenProtocol, DetectAtapiMedia, AtapiInquiryData
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize EFI_BLOCK_IO_PROTOCOL Protocol.
+// 2. In case of Removable devices, detect Media presence.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InitSataBlockIO (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ SATA_BLOCK_IO *SataBlkIo;
+ EFI_BLOCK_IO_MEDIA *BlkMedia;
+ ATAPI_DEVICE *AtapiDevice;
+ UINT8 *Data, *InquiryData;
+ UINT16 InquiryDataSize;
+ UINT16 OddType=0;
+ UINT8 OddLoadingType=0xFF;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof(SATA_BLOCK_IO),
+ (VOID**)&SataBlkIo);
+ if (EFI_ERROR(Status)) return Status;
+
+ BlkMedia = MallocZ(sizeof(EFI_BLOCK_IO_MEDIA));
+ if (!BlkMedia) {
+ pBS->FreePool (SataBlkIo);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the IdeBlkIo pointer in IDE_BUS_PROTOCOL (IdeBusInterface)
+ //
+ SataDevInterface->SataBlkIo = SataBlkIo;
+
+ //
+ // Initialize the fields in IdeBlkIo (SATA_BLOCK_IO)
+ //
+ SataBlkIo->SataDevInterface = SataDevInterface;
+
+ if (SataDevInterface->DeviceType == ATA){
+ // ATA
+ BlkIo = &(SataBlkIo->BlkIo);
+
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ BlkIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ } else {
+ BlkIo->Revision = BLKIO_REVISION;
+ }
+#else
+ BlkIo->Revision = BLKIO_REVISION;
+#endif
+ BlkIo->Media = BlkMedia;
+ BlkIo->Reset = SataReset;
+ BlkIo->ReadBlocks = SataBlkRead;
+ BlkIo->WriteBlocks = SataBlkWrite;
+ BlkIo->FlushBlocks = SataBlkFlush;
+
+ BlkMedia->MediaId = 0;
+ BlkMedia->RemovableMedia = (SataDevInterface->IdentifyData.General_Config_0 & 0x80) == 0x80 ? TRUE : FALSE;
+
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->LogicalPartition = FALSE;
+ BlkMedia->ReadOnly = FALSE;
+ BlkMedia->WriteCaching = FALSE;
+
+ if((SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(SataDevInterface->IdentifyData.Reserved_104_126[13] + \
+ (SataDevInterface->IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+
+ BlkMedia->BlockSize = SectorSize;
+ BlkMedia->IoAlign = 4;
+
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x400) {
+ BlkMedia->LastBlock = SataDevInterface->IdentifyData.LBA_48 - 1;
+ }
+ else {
+ BlkMedia->LastBlock = SataDevInterface->IdentifyData.Addressable_Sector_60 - 1;
+ }
+
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+
+ BlkMedia->OptimalTransferLengthGranularity=BlkMedia->BlockSize;
+ //
+ // bit 14 of word 106 is set to one and bit 15 of word 106 is cleared to zero,
+ // then the contents of word 106 contain valid information .
+ // Otherwise, information is not valid in this word.
+ //
+ if ( (SataDevInterface->IdentifyData.Reserved_104_126[2] & 0xC000) == 0x4000 ) {
+ //
+ // If bit 13 of word 106 is set to one, then the device has more than one
+ // logical sector per physical sector and bits (3:0) of word 106 are valid
+ //
+ if ( SataDevInterface->IdentifyData.Reserved_104_126[2] & 0x2000 ) {
+
+ BlkMedia->LogicalBlocksPerPhysicalBlock = 1 <<
+ (SataDevInterface->IdentifyData.Reserved_104_126[2] & 0xF);
+
+ //
+ // Bits 13:0 of word 209 indicate the Logical sector offset within the first physical
+ // sector where the first logical sector is placed
+ //
+ BlkMedia->LowestAlignedLba =SataDevInterface->IdentifyData.Reserved_206_254[3] & 0x3FFF;
+
+ } else {
+ //
+ // Default set the 1 logical blocks per PhysicalBlock
+ //
+ BlkMedia->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ BlkMedia->LowestAlignedLba=0;
+ }
+ } else {
+ //
+ // Default set the 1 logical blocks per PhysicalBlock
+ //
+ BlkMedia->LogicalBlocksPerPhysicalBlock=1;
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ BlkMedia->LowestAlignedLba=0;
+ }
+ }
+#endif
+
+ } else {
+
+ //
+ // If it is an ATAPI device, check whether it is a CDROM or not.
+ // Currently only CDROM/Direct access Devices are supported.
+ //
+ if ((SataDevInterface->IdentifyData.General_Config_0 & 0x1f00) == (CDROM_DEVICE << 8) ||
+ (SataDevInterface->IdentifyData.General_Config_0 & 0x1f00) == (DIRECT_ACCESS_DEVICE << 8) ||
+ (SataDevInterface->IdentifyData.General_Config_0 & 0x1f00) == (OPTICAL_MEMORY_DEVICE << 8)){
+
+ AtapiDevice = MallocZ(sizeof (ATAPI_DEVICE));
+
+ if (!AtapiDevice) return EFI_OUT_OF_RESOURCES;
+
+ SataDevInterface->AtapiDevice = AtapiDevice;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ 16,
+ (VOID**)&Data
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ AtapiDevice->PacketBuffer = Data;
+ AtapiDevice->DeviceType = (SataDevInterface->IdentifyData.General_Config_0 & 0x1f00) >> 8;
+ AtapiDevice->PacketSize = (SataDevInterface->IdentifyData.General_Config_0 & 3) == 1 ? 16 : 12;
+
+ BlkIo = &(SataBlkIo->BlkIo);
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ BlkIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ } else {
+ BlkIo->Revision = BLKIO_REVISION;
+ }
+#else
+ BlkIo->Revision = BLKIO_REVISION;
+#endif
+ BlkIo->Media = BlkMedia;
+ BlkIo->Reset = SataReset;
+ BlkIo->ReadBlocks = SataAtapiBlkRead;
+ BlkIo->WriteBlocks = SataAtapiBlkWrite;
+ BlkIo->FlushBlocks = SataBlkFlush;
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE;
+
+ //
+ // Update Inquiry Data
+ //
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ INQUIRY_DATA_LENGTH,
+ (VOID**)&InquiryData);
+ if (EFI_ERROR(Status)) return Status;
+ InquiryDataSize = INQUIRY_DATA_LENGTH;
+ SataAtapiInquiryData(SataDevInterface, InquiryData, &InquiryDataSize);
+ AtapiDevice->InquiryData = InquiryData;
+ AtapiDevice->InquiryDataSize = InquiryDataSize;
+
+ //
+ // Get the ATAPI drive type information and save it ATAPI_DEVICE
+ //
+ Status=SataGetOddType(SataDevInterface, &OddType);
+ if(!EFI_ERROR(Status)) {
+ AtapiDevice->OddType=GetEnumOddType(OddType);
+ }
+
+ //
+ // Get the ATAPI drive Loading information and save it ATAPI_DEVICE
+ //
+ Status=SataGetOddLoadingType(SataDevInterface, &OddLoadingType);
+
+ if ( !EFI_ERROR( Status )) {
+ AtapiDevice->OddLoadingType = (ODD_LOADING_TYPE)OddLoadingType;
+ } else {
+ AtapiDevice->OddLoadingType = (ODD_LOADING_TYPE)0xFF;
+ }
+
+ BlkMedia->RemovableMedia = (SataDevInterface->IdentifyData.General_Config_0 & 0x80) == 0x80 ? TRUE : FALSE;
+ BlkMedia->LogicalPartition = FALSE;
+ BlkMedia->WriteCaching = FALSE;
+ BlkMedia->IoAlign = 4;
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ //
+ // For Atapi Devices, Default set the 1 for logical blocks per PhysicalBlock
+ //
+ BlkMedia->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // For Atapi Devices, Default value set to 0 for Lowest Aligned LBA
+ //
+ BlkMedia->LowestAlignedLba=0;
+
+ BlkMedia->OptimalTransferLengthGranularity=BlkMedia->BlockSize;
+ }
+#endif
+ }
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetEnumOddType
+//
+// Description: Get the Enum value for ODD type found on profile
+//
+// Input:
+//
+// UINT16 Oddtype
+// Output:
+// ODD_TYPE EnumValue
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ODD_TYPE GetEnumOddType(
+ UINT16 OddType
+)
+{
+
+ switch(OddType) {
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ return Obsolete;
+
+ case 2:
+ return Removabledisk;
+
+ case 8:
+ return CDROM;
+
+ case 9:
+ return CDR;
+
+ case 0xa:
+ return CDRW;
+
+ case 0x10:
+ return DVDROM;
+
+ case 0x11:
+ return DVDRSequentialrecording;
+
+ case 0x12:
+ return DVDRAM;
+
+ case 0x13:
+ return DVDRWRestrictedOverwrite;
+
+ case 0x15:
+ return DVDRWSequentialrecording;
+
+ case 0x16:
+ return DVDRDualLayerJumprecording;
+
+ case 0x17:
+ return DVDRWDualLayer;
+
+ case 0x18:
+ return DVDDownloaddiscrecording;
+
+ case 0x1a:
+ return DVDRW;
+
+ case 0x1b:
+ return DVDR;
+
+ case 0x40:
+ return BDROM;
+
+ case 0x41:
+ return BDRSequentialRecording;
+
+ case 0x42:
+ return BDRRandomRecordingMode;
+
+ case 0x43:
+ return BDRE;
+
+ case 0x50:
+ return HDDVDROM;
+
+ case 0x51:
+ return HDDVDR;
+
+ case 0x52:
+ return HDDVDRAM;
+
+ case 0x53:
+ return HDDVDRW;
+
+ case 0x58:
+ return HDDVDRDualLayer;
+
+ case 0x5a:
+ return HDDVDRWDualLayer;
+
+ default:
+ return UnknownType;
+ }
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitSataDiskInfo
+//
+// Description: Initializes SATA DiskInfo Interface
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InitSataDiskInfo (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+ EFI_STATUS Status;
+ SATA_DISK_INFO *SataDiskInfo;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof(SATA_DISK_INFO),
+ (VOID**)&SataDiskInfo);
+ if (EFI_ERROR(Status)){
+ return Status;
+ }
+
+ //
+ // Initialize the SataBlkIo pointer in SATA_DEVICE_INTERFACE
+ //
+ SataDevInterface->SataDiskInfo = SataDiskInfo;
+
+ // Initialize the fields in SataDiskInfo (SATA_DISK_INFO)
+ SataDiskInfo->SataDevInterface = SataDevInterface;
+
+ pBS->CopyMem (&(SataDiskInfo->DiskInfo.Interface), &gEfiAhciDiskInfoProtocolGuid, sizeof (EFI_GUID));
+ SataDiskInfo->DiskInfo.Inquiry = DiskInfoInquiry;
+ SataDiskInfo->DiskInfo.Identify = DiskInfoIdentify;
+ SataDiskInfo->DiskInfo.SenseData = DiskInfoSenseData;
+ SataDiskInfo->DiskInfo.WhichIde = DiskInfoWhichIDE;
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CreateSataDevicePath
+//
+// Description: Creates a SATA device devicepath and adds it to SataDevInterface
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+// IN OUT EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool, OpenProtocol, IdeBusStart
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If Remaining Devicepath is not NULL, we have already verified that it is a
+// valid Atapi device path in IdeBusStart. So nothing to do. Just exit.
+// 2. Build a Atapi devicepath and a End devce path.
+// 3. Get the Devicepath for the IDE controller.
+// 4. Append Atapi devicepath to IDE controller devicepath.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CreateSataDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ SATA_DEVICE_PATH NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+
+ NewDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+ NewDevicePath.Header.SubType = MSG_USB_SATA_DP;
+ SET_NODE_LENGTH(&NewDevicePath.Header,SATA_DEVICE_PATH_LENGTH);
+ NewDevicePath.PortNumber = SataDevInterface->PortNumber;
+ NewDevicePath.MultiplierPortNumber = SataDevInterface->PMPortNumber == 0xFF ? 0xFFFF : SataDevInterface->PMPortNumber;
+ NewDevicePath.LogicalUnitNumber = 0;
+
+ //
+ // Append the Device Path
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gDevicePathProtocolGuid,
+ (VOID **)&TempDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ SataDevInterface->DevicePathProtocol = DPAddNode(TempDevicePath, &NewDevicePath.Header);
+ return Status;
+
+}
+
+#if SBIDE_SUPPORT
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitMiscConfig
+//
+// Description: Initialize misc IDE configurations.
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// None
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID InitMiscConfig (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+ IDE_SETUP_PROTOCOL *gIdeSetupProtocol;
+ COMMAND_STRUCTURE CommandStructure;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = pBS->LocateProtocol(&gIdeSetupProtocolguid, NULL, &gIdeSetupProtocol);
+ if(EFI_ERROR(Status)){
+ return;
+ }
+
+ #if ACOUSTIC_MANAGEMENT_SUPPORT
+ InitAcousticSupport (SataDevInterface);
+ #endif
+
+}
+#endif
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ConfigurePowerUpInStandby
+//
+// Description: Configure PowerUpInStandby
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecuteNonDataCommand
+//
+// Notes:
+// 1. Check if the device support PowerUp In Standby.
+// 2. Check the desired state Vs the current state.
+// 3. If both are equal nothing to do, exit else program the desired level
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ConfigurePowerUpInStandby (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+ COMMAND_STRUCTURE CommandStructure;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(AhciPlatformPolicy->PowerUpInStandbySupport) {
+ //
+ // Check if the device supports PowerUpInStandby feature
+ //
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x20){
+ //
+ //Check if the desired state is already present or not
+ //
+ if (!((SataDevInterface->IdentifyData.Command_Set_Enabled_86 & 0x20) ==
+ (AhciPlatformPolicy->PowerUpInStandbyMode))){
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ CommandStructure.Features = (AhciPlatformPolicy->PowerUpInStandbyMode) == 0 ? DISABLE_POWERUP_IN_STANDBY : ENABLE_POWERUP_IN_STANDBY;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+
+ }
+ }
+ }
+
+ return Status;
+}
+
+#if ACOUSTIC_MANAGEMENT_SUPPORT
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitAcousticSupport
+//
+// Description: Initialize Acoustic functionality
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecuteNonDataCommand
+//
+// Notes:
+// 1. Check if the device support Acoustic management.
+// 2. Check the desired state Vs the current state.
+// 3. If both are equal nothing to do, exit else program the desired level
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InitAcousticSupport (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+
+ UINT8 Data8;
+ COMMAND_STRUCTURE CommandStructure;
+ EFI_STATUS Status;
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+
+ //
+ // Check if the device supports Acoustic Management
+ //
+ if (SataDevInterface->IdentifyData.Command_Set_Supported_83 & 0x200){
+
+ //
+ // Check if Acoustic Level need to be enabled or Disabled
+ //
+ if (SataDevInterface->AhciBusInterface->Acoustic_Enable & ACOUSTIC_SUPPORT_ENABLE) {
+ Data8 = SataDevInterface->AhciBusInterface->Acoustic_Management_Level;
+
+ //
+ // Do we need to program the recommended value
+ //
+ if (Data8 == ACOUSTIC_LEVEL_BYPASS) {
+
+ //
+ // Get the rcommended value
+ //
+ Data8 = (UINT8)(SataDevInterface->IdentifyData.Acoustic_Level_94 >> 8);
+ }
+
+ CommandStructure.Features = ACOUSTIC_MANAGEMENT_ENABLE;
+ CommandStructure.SectorCount = Data8;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+
+ } else {
+
+ //
+ // If already disabled, nothing to do
+ //
+ if (SataDevInterface->IdentifyData.Command_Set_Enabled_86 & 0x200) {
+ CommandStructure.Features = ACOUSTIC_MANAGEMENT_DISABLE;
+ CommandStructure.SectorCount = 0;
+ Status = ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+#endif // ACOUSTIC_MANAGEMENT_SUPPORT ends
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DMACapable
+//
+// Description: Check if DMA is supported
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// TRUE : DMA Capable
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check the Identify Data to check if device supports DMA
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN
+DMACapable(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+
+ if (SataDevInterface->DeviceType == ATAPI){
+ //For Atapi Devices check Bit 8 in Word 49 = DMA Supported or not
+ if((SataDevInterface->IdentifyData.Capabilities_49 & 0x100) == 0) return FALSE;
+ }
+
+ if ( (SataDevInterface->UDma != 0xff) ||
+ (SataDevInterface->MWDma != 0xff))
+ return TRUE;
+ else
+ return FALSE;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DiskInfoInquiry
+//
+// Description: Return ATAPI Inquiry data
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This,
+// IN OUT VOID *InquiryData,
+// IN OUT UINT32 *InquiryDataSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitSataDiskInfo
+//
+// Notes:
+// 1. Check for Atapi Device. If not exit
+// 2. COpy the Inquiry Data from AtapiDevice->InquiryData to the input pointer.
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+DiskInfoInquiry (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *InquiryData,
+ IN OUT UINT32 *InquiryDataSize
+)
+{
+
+ SATA_DEVICE_INTERFACE *SataDevInterface = ((SATA_BLOCK_IO *)This)->SataDevInterface;
+ ATAPI_DEVICE *AtapiDevice = SataDevInterface->AtapiDevice;
+
+ //
+ // Check for ATAPI device. If not return EFI_NOT_FOUND
+ //
+ if (SataDevInterface->DeviceType == ATA){
+ return EFI_NOT_FOUND; // ATA device
+ }
+ else {
+ if (*InquiryDataSize < AtapiDevice->InquiryDataSize) {
+ *InquiryDataSize = AtapiDevice->InquiryDataSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ if (AtapiDevice->InquiryData != NULL) {
+ pBS->CopyMem (InquiryData, AtapiDevice->InquiryData, AtapiDevice->InquiryDataSize);
+ *InquiryDataSize = AtapiDevice->InquiryDataSize;
+ return EFI_SUCCESS;
+ }
+ else return EFI_NOT_FOUND;
+ }
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DiskInfoIdentify
+//
+// Description: Return Identify Data
+//
+// Input:
+// EFI_DISK_INFO_PROTOCOL *This,
+// IN OUT VOID *IdentifyData,
+// IN OUT UINT32 *IdentifyDataSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitSataDiskInfo
+//
+// Notes:
+// 1. Return the Identify command data.
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+DiskInfoIdentify (
+ EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *IdentifyData,
+ IN OUT UINT32 *IdentifyDataSize
+ )
+{
+
+ SATA_DEVICE_INTERFACE *SataDevInterface = ((SATA_BLOCK_IO *)This)->SataDevInterface;
+
+ if (*IdentifyDataSize < sizeof (IDENTIFY_DATA)) {
+ *IdentifyDataSize = sizeof (IDENTIFY_DATA);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // ATA devices identify data might be changed because of the SetFeature command,
+ // So read the data from the device again by sending identify command.
+ //
+ if(SataDevInterface->DeviceType == ATA){
+ GetIdentifyData(SataDevInterface);
+ }
+
+ pBS->CopyMem (IdentifyData, &(SataDevInterface->IdentifyData), sizeof (IDENTIFY_DATA));
+ *IdentifyDataSize = sizeof (IDENTIFY_DATA);
+ return EFI_SUCCESS;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DiskInfoSenseData
+//
+// Description: Return InfoSenseData.
+//
+// Input:
+// EFI_DISK_INFO_PROTOCOL *This,
+// VOID *SenseData,
+// UINT32 *SenseDataSize,
+// UINT8 *SenseDataNumber
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitSataDiskInfo
+//
+// Notes:
+// 1. Return the Sense data for the Atapi device.
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+DiskInfoSenseData(
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT VOID *SenseData,
+ OUT UINT32 *SenseDataSize,
+ OUT UINT8 *SenseDataNumber
+ )
+
+{
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DiskInfoWhichIDE
+//
+// Description: Returns info about where the device is connected.
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This,
+// OUT UINT32 *IdeChannel,
+// OUT UINT32 *IdeDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitSataDiskInfo
+//
+// Notes:
+// 1. Return Port and PMPort
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+DiskInfoWhichIDE
+(
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT UINT32 *IdeChannel,
+ OUT UINT32 *IdeDevice
+ )
+{
+
+ SATA_DEVICE_INTERFACE *SataDevInterface = ((SATA_BLOCK_IO *)This)->SataDevInterface;
+
+ *IdeChannel = SataDevInterface->PortNumber;
+ *IdeDevice = SataDevInterface->PMPortNumber == 0xFF ? 0 : SataDevInterface->PMPortNumber;
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciBus.h b/Core/EM/Ahci/AhciBus.h
new file mode 100644
index 0000000..c557262
--- /dev/null
+++ b/Core/EM/Ahci/AhciBus.h
@@ -0,0 +1,919 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciBus.h 18 6/25/14 10:04a Anandakrishnanl $
+//
+// $Revision: 18 $
+//
+// $Date: 6/25/14 10:04a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciBus.h $
+//
+// 18 6/25/14 10:04a Anandakrishnanl
+// [TAG] EIP170118
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MDAT can't program correctly in AHCI module
+// [RootCause] Identify Data Word 76_79 Offset for DiPM Support/Enabled
+// is incorrect for validation
+// [Solution] Changed separating DiPM and Device Sleep into two routines
+// and also modified the tokens to disable both support by default .
+// Corrected Identify data validations.
+// [Files] AhciBus.c
+// AhciBus.h
+// AhciSrc.sdl
+// PAhciBus.h
+// PIDEBus.h
+//
+// 17 1/27/14 4:56a Rameshr
+// [TAG] EIP148180
+// [Category] Improvement
+// [Description] change from EFI_MBR_WRITE_PROTECTION_PROTOCOL to
+// AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL
+// [Files] Ahcibus.c, Ahcibus.h, AhciComponentName.c, AhciController.c
+//
+// 16 12/18/13 3:21a Srikantakumarp
+// [TAG] EIP127356
+// [Category] Improvement
+// [Description] Flash NVRAM seems to cause HDD can't be unlocked when
+// S3 resume.
+// [Files] IdeSecurity.c, IDESMM.c, HddPassword.c, AhciBus.c, AhciBus.h
+//
+// 15 8/27/13 4:18a Rameshr
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] MbrWriteProtectionProtocol file name changesd to
+// AmiMbrWriteProtectionProtocol.h
+// [Files] AhciController.c, AhciBus.h, Ahcibus.c
+//
+// 14 7/23/13 11:54p Srikantakumarp
+// [TAG] EIP129989
+// [Category] Improvement
+// [Description] Added DIPM support in Aptio 4.x AHCIBUS driver.
+// [Files] AhciBus.c, AhciBus.h, AhciController.h, AhciSrc.sdl,
+// PAhciBus.h
+//
+// 13 7/22/13 2:07a Rameshr
+// [TAG] EIP129028
+// [Category] Improvement
+// [Description] Implement the POWERUP_IN_STANDBY_MODE support in
+// AHCIBUS driver
+// [Files] Ahcibus.c, Ahcibus.h, Pahcibus.h
+//
+// 12 7/18/13 4:22a Rameshr
+// [TAG] EIP127919
+// [Category] Improvement
+// [Description] "Device is Atapi" bit of PxCMD will be set if the ATAPI
+// device connected on the Port and "Drive LED on ATAPI" Enabled by AHCI
+// platform policy
+// [Files] Pahcibus.h, Ahcibus.c, Ahcibus.h
+//
+// 11 7/20/12 6:10a Anandakrishnanl
+// [TAG] EIP88683
+// [Category] New Feature
+// [Description] EFI_ATA_PASS_THRU_PROTOCOL Support for Aptio IDE
+// [Files] AhciBus.c
+// AhciBus.h
+// AInt13.h
+// IdeBus.c
+// IdeBus.h
+// PIDEBus.h
+// PAhciBus.h
+// AtaPassThru.sdl
+// AtaPassThru.mak
+// AtaPassThru.c
+// AtaPassThruSupport.h
+// AtaPassThru.chm
+//
+// 10 9/27/11 3:02a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 9 9/19/11 3:05a Lavanyap
+// [TAG] EIP69398
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Function ConfigureController() has a runtime error (NULL
+// pointer dereference)
+// [RootCause] variable SupportedModes has been initialized again in
+// ConfigureController().
+// [Solution] variable SupportedModes is passed as an input parameter
+// for ConfigureController() and ConfigureDevice().
+// [Files] AhciBus.c, AhciBus.h
+//
+// 8 2/11/11 4:23a Rameshr
+// [TAG] EIP53730
+// [Category] Improvement
+// [Description] Add Odd Loading type information into ATAPI_DEVICE
+// structure in AHCI mode
+// [Files] AhciBus.c
+// AhciController.c
+// AhciBus.h
+//
+// 7 2/10/11 10:35a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSrc.mak
+// AhciBus.c
+// AhciController.c
+// AhciComponentName.c
+// AhciBus.h
+// AhciController.h
+//
+// 6 12/23/10 3:59a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 5 5/07/10 11:45a Krishnakumarg
+// Coding standard update
+//
+// 4 6/22/09 11:34a Rameshr
+// Odd Type information Saved in Atapi Device Structure.
+// EIP:21548
+//
+// 3 4/28/09 3:58p Rameshr
+//
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 2 5/28/08 9:39a Rameshraju
+// Based on the SDL token index/data or MMIO method used to access the
+// AHCI configuration space.
+//
+// 1 28/02/08 6:03p Anandakrishnanl
+// AHCI Bus Driver initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AhciBus.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _AhciBus_
+#define _AhciBus_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include <Protocol\ComponentName.h>
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\PAhciBus.h>
+#include <protocol\AtaPassThru.h>
+#include <protocol\StorageSecurityCommand.h>
+#include "AhciController.h"
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+#include <Protocol\AmiBlockIoWriteProtection.h>
+#endif
+
+#define TRACE_AHCI_LEVEL2
+#define TRACE_AHCI TRACE
+
+#ifdef Debug_Level_1
+VOID EfiDebugPrint (IN UINTN ErrorLevel,IN CHAR8 *Format,...);
+#endif
+
+#define AHCI_BUS_DRIVER_VERSION 0x01
+#define ONE_MILLISECOND 1000
+
+#define COMMAND_LIST_SIZE_PORT 0x800
+
+#ifndef ATAPI_BUSY_CLEAR_TIMEOUT
+#define ATAPI_BUSY_CLEAR_TIMEOUT 16000 // 16sec
+#endif
+
+#ifndef S3_BUSY_CLEAR_TIMEOUT
+#define S3_BUSY_CLEAR_TIMEOUT 10000 // 10Sec
+#endif
+
+#define BUSY_CLEAR_TIMEOUT 1000 // 1Sec
+#define DRDY_TIMEOUT 1000 // 1Sec
+#define DRQ_TIMEOUT 10 // 10msec
+#define DRQ_CLEAR_TIMEOUT 1000 // 1sec
+#define DRQ_SET_TIMEOUT 10 // 10msec
+#define HP_COMMAND_COMPLETE_TIMEOUT 2000 // 2Sec
+#define COMMAND_COMPLETE_TIMEOUT 5000 // 5Sec
+
+#ifndef DMA_ATA_COMMAND_COMPLETE_TIMEOUT
+#define DMA_ATA_COMMAND_COMPLETE_TIMEOUT 5000 // 5Sec
+#endif
+
+#ifndef DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT
+#define DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT 16000 // 16Sec
+#endif
+
+#ifndef ATAPI_RESET_COMMAND_TIMEOUT
+#define ATAPI_RESET_COMMAND_TIMEOUT 5000
+#endif
+
+#ifndef POWERON_BUSY_CLEAR_TIMEOUT
+#define POWERON_BUSY_CLEAR_TIMEOUT 10000 // 10 Sec
+#endif
+
+#define TIMEOUT_1SEC 1000 // 1sec Serial ATA 1.0 Sec 5.2
+
+
+
+#define BLKIO_REVISION 1
+
+#define DEVICE_DISABLED 0
+#define DEVICE_IN_RESET_STATE 1
+#define DEVICE_DETECTION_FAILED 2
+#define DEVICE_DETECTED_SUCCESSFULLY 3
+#define DEVICE_CONFIGURED_SUCCESSFULLY 4
+#define DEVICE_REMOVED 5
+#define CONTROLLER_NOT_PRESENT 0xff
+
+#define ENUMERATE_ALL 0xff
+#define ENUMERATE_PRIMARY_MASTER 0x0
+#define ENUMERATE_PRIMARY_SLAVE 0x1
+#define ENUMERATE_SECONDARY_MASTER 0x2
+#define ENUMERATE_SECONDARY_SLAVE 0x3
+#define INQUIRY_DATA_LENGTH 0x96
+#define READ_CAPACITY_DATA_LENGTH 0x08
+
+// PCI Config Space equates
+#define PROGRAMMING_INTERFACE_OFFSET 0x09
+#define IDE_SUB_CLASS_CODE 0x0A
+ #define SCC_IDE_CONTROLLER 0x01
+ #define SCC_AHCI_CONTROLLER 0x06
+ #define SCC_RAID_CONTROLLER 0x04
+#define IDE_BASE_CLASS_CODE 0x0B
+ #define BASE_CODE_IDE_CONTROLLER 0x01
+#define PRIMARY_COMMAND_BLOCK_OFFSET 0x10
+#define PRIMARY_CONTROL_BLOCK_OFFSET 0x14
+#define SECONDARY_COMMAND_BLOCK_OFFSET 0x18
+#define SECONDARY_CONTROL_BLOCK_OFFSET 0x1C
+#define LEGACY_BUS_MASTER_OFFSET 0x20
+
+#define EFI_SUCCESS_ACTIVE_SET 0x80000000
+
+
+EFI_STATUS
+CreateIdeDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface,
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ UINT8 Current_Channel,
+ UINT8 Current_Device
+);
+
+EFI_STATUS
+InitIdeBlockIO (
+ IDE_BUS_PROTOCOL *IdeBusInterface
+);
+
+EFI_STATUS
+InitIdeDiskInfo (
+ IDE_BUS_PROTOCOL *IdeBusInterface
+);
+
+EFI_STATUS
+InstallAhciBusProtocol (
+ IN EFI_HANDLE Controller,
+ AHCI_BUS_PROTOCOL *IdeBusInitInterface,
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ EFI_PCI_IO_PROTOCOL *PciIO
+);
+
+EFI_STATUS
+AhciInitController (
+ AHCI_BUS_PROTOCOL *AhciBusInterface
+);
+
+EFI_STATUS
+CheckPortImplemented (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ UINT8 Port
+);
+
+EFI_STATUS
+AhciDetectDevice (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ UINT8 Port,
+ UINT8 PMPortNumber
+);
+
+EFI_STATUS
+CheckDevicePresence (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ UINT8 Port,
+ UINT8 PMPort
+);
+
+EFI_STATUS
+CheckPMDevicePresence (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ UINT8 Port,
+ UINT8 PMPort
+);
+
+EFI_STATUS
+ConfigureDevice (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ EFI_ATA_COLLECTIVE_MODE **SupportedModes
+);
+
+EFI_STATUS
+ConfigureController (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ EFI_ATA_COLLECTIVE_MODE *SupportedModes
+);
+
+VOID
+InitializeDipm(
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+VOID
+InitializeDeviceSleep (
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+HostReset (
+ AHCI_BUS_PROTOCOL *AhciBusInterface
+);
+
+
+EFI_STATUS
+GeneratePortReset (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 PMPort,
+ UINT8 Speed,
+ UINT8 PowerManagement
+);
+
+EFI_STATUS
+GenerateSoftReset (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 PMPort
+);
+
+EFI_STATUS
+GetIdentifyData (
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+HandlePortComReset(
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 PMPort
+);
+
+EFI_STATUS
+CheckValidDevice (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ UINT8 Port,
+ UINT8 PMPort
+);
+
+SATA_DEVICE_INTERFACE*
+GetSataDevInterface(
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ UINT8 Port,
+ UINT8 PMPort
+);
+
+EFI_STATUS
+ExecuteNonDataCommand (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE CommandStructure
+);
+
+EFI_STATUS
+ExecutePioDataCommand (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ BOOLEAN READWRITE
+);
+
+EFI_STATUS
+ExecuteDmaDataCommand (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ BOOLEAN READWRITE
+);
+
+EFI_STATUS
+SataReadWritePio(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE
+) ;
+
+EFI_STATUS
+SataPioDataOut (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT8 Features,
+ IN UINT8 LBALow,
+ IN UINT8 LBALowExp,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAMidExp,
+ IN UINT8 LBAHigh,
+ IN UINT8 LBAHighExp,
+ IN UINT8 Command,
+ IN BOOLEAN READWRITE
+) ;
+
+EFI_STATUS
+WaitforCommandComplete (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_TYPE CommandType,
+ UINTN TimeOut
+);
+
+UINT8
+ReturnMSBset(
+ UINT32 Data
+);
+
+EFI_STATUS
+StartController (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT32 CIBitMask
+);
+
+EFI_STATUS
+ReadytoAcceptCmd (
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+StopController(
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ BOOLEAN StartOrStop
+) ;
+
+EFI_STATUS
+DetectAndConfigureDevice (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *IdeControllerInterface,
+ UINT8 Port,
+ UINT8 PMPort
+);
+
+EFI_STATUS
+ConfigurePMPort (
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+ReadWritePMPort (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 RegNum,
+ UINT32 *Data,
+ BOOLEAN READWRITE
+);
+
+UINT32
+ReadSCRRegister (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 PMPort,
+ UINT8 Register
+);
+
+EFI_STATUS
+WriteSCRRegister (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 PMPort,
+ UINT8 Register,
+ UINT32 Data32
+);
+
+EFI_STATUS
+WritePMPort (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 RegNum,
+ UINT32 Data
+);
+
+EFI_STATUS
+BuildCommandList (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ AHCI_COMMAND_LIST *CommandList,
+ UINT32 CommandTableBaseAddr
+);
+
+EFI_STATUS
+BuildCommandFIS (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE CommandStructure,
+ AHCI_COMMAND_LIST *CommandList,
+ AHCI_COMMAND_TABLE *Commandtable
+);
+
+EFI_STATUS
+BuildAtapiCMD(
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE CommandStructure,
+ AHCI_COMMAND_LIST *CommandList,
+ AHCI_COMMAND_TABLE *Commandtable
+);
+
+EFI_STATUS
+BuildPRDT
+(
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE CommandStructure,
+ AHCI_COMMAND_LIST *CommandList,
+ AHCI_COMMAND_TABLE *Commandtable
+);
+
+EFI_STATUS
+WaitForMemSet (
+ IN UINT32 BaseAddr,
+ IN UINT8 Port,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 TestValue,
+ IN UINT32 WaitTimeInMs
+);
+
+EFI_STATUS
+WaitforPMMemSet (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 PMPort,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 TestValue,
+ IN UINT32 WaitTimeInMs
+);
+
+EFI_STATUS
+WaitForMemClear (
+ IN UINT32 BaseAddr,
+ IN UINT8 Port,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 WaitTimeInMs
+);
+
+EFI_STATUS
+CreateSataDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS
+InitSataBlockIO (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+InitSataDiskInfo (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+InitAcousticSupport (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+InitSMARTSupport (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+SMARTReturnStatusWrapper(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+ConfigurePowerUpInStandby (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+AhciBusSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS
+AhciBusStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS
+AhciBusStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+);
+
+
+EFI_STATUS
+DiskInfoInquiry (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *InquiryData,
+ IN OUT UINT32 *InquiryDataSize
+);
+
+EFI_STATUS
+DiskInfoIdentify (
+ EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *IdentifyData,
+ IN OUT UINT32 *IdentifyDataSize
+);
+
+EFI_STATUS
+DiskInfoSenseData(
+ EFI_DISK_INFO_PROTOCOL *This,
+ VOID *SenseData,
+ UINT32 *SenseDataSize,
+ UINT8 *SenseDataNumber
+);
+
+EFI_STATUS
+DiskInfoWhichIDE
+(
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT UINT32 *IdeChannel,
+ OUT UINT32 *IdeDevice
+);
+
+#define ZeroMemory(Buffer,Size) pBS->SetMem(Buffer,Size,0)
+
+
+BOOLEAN
+DMACapable(
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+SataBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+SataBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+SataAtaBlkReadWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer,
+ BOOLEAN READWRITE
+);
+
+EFI_STATUS
+SataAtapiBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+SataAtapiBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+SataReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS
+SataBlkFlush(
+ IN EFI_BLOCK_IO_PROTOCOL *This
+);
+
+EFI_STATUS
+SataReadWriteBusMaster(
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE
+);
+
+EFI_STATUS
+SataAtapiInquiryData (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 *InquiryData,
+ UINT16 *InquiryDataSize
+);
+
+EFI_STATUS
+DetectAtapiMedia(
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+TestUnitReady(
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+ExecutePacketCommand (
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ BOOLEAN READWRITE
+);
+
+EFI_STATUS
+SataAtapiBlkReadWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer,
+ BOOLEAN READWRITE
+);
+
+EFI_STATUS
+HandleAtapiError (
+ SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+BOOLEAN
+Check48BitCommand (
+ IN UINT8 Command
+);
+
+EFI_STATUS
+InitSMARTSupport (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+SMARTReturnStatusWrapper(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+EFI_STATUS
+SataGetOddType (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT UINT16 *OddType
+);
+
+EFI_STATUS
+SataGetOddLoadingType (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT UINT8 *OddLoadingType
+);
+
+ODD_TYPE
+GetEnumOddType(
+ IN UINT16 OddType
+);
+
+EFI_STATUS
+ConfigureSataPort (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+);
+
+
+#if INDEX_DATA_PORT_ACCESS
+UINT32
+ReadDataDword(
+ IN UINTN BaseAddr,
+ IN UINTN Index
+);
+
+UINT16
+ReadDataWord(
+ IN UINTN BaseAddr,
+ IN UINTN Index
+);
+
+UINT8
+ReadDataByte(
+ IN UINTN BaseAddr,
+ IN UINTN Index
+);
+
+VOID
+WriteDataDword(
+ IN UINTN BaseAddr,
+ IN UINTN Index,
+ IN UINTN Data
+);
+
+VOID
+WriteDataWord(
+ IN UINTN BaseAddr,
+ IN UINTN Index,
+ IN UINTN Data
+);
+
+VOID
+WriteDataByte(
+ IN UINTN BaseAddr,
+ IN UINTN Index,
+ IN UINTN Data
+);
+#endif
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciComponentName.c b/Core/EM/Ahci/AhciComponentName.c
new file mode 100644
index 0000000..1d68ea5
--- /dev/null
+++ b/Core/EM/Ahci/AhciComponentName.c
@@ -0,0 +1,314 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciComponentName.c 7 1/27/14 4:57a Rameshr $
+//
+// $Revision: 7 $
+//
+// $Date: 1/27/14 4:57a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciComponentName.c $
+//
+// 7 1/27/14 4:57a Rameshr
+// [TAG] EIP148180
+// [Category] Improvement
+// [Description] Change from EFI_MBR_WRITE_PROTECTION_PROTOCOL to
+// AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL
+// [Files] Ahcibus.c, Ahcibus.h, AhciComponentName.c, AhciController.c
+//
+// 6 2/10/11 10:35a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSrc.mak
+// AhciBus.c
+// AhciController.c
+// AhciComponentName.c
+// AhciBus.h
+// AhciController.h
+//
+// 5 5/07/10 11:45a Krishnakumarg
+// Coding standard update
+//
+// 4 3/26/10 5:37p Krishnakumarg
+// UEFI2.1 compliance change EIP#34744.
+//
+// 3 4/28/09 3:57p Rameshr
+//
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 2 5/28/08 9:39a Rameshraju
+//
+// 1 28/02/08 6:03p Anandakrishnanl
+// AHCI Bus Driver initial check-in.
+//
+//
+//
+//**********************************************************************
+
+#include "AhciBus.h"
+
+extern EFI_GUID gSecurityModeProtocolGuid;
+static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+extern EFI_DRIVER_BINDING_PROTOCOL gAhciBusDriverBinding;
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#define LANGUAGE_CODE_ENGLISH "eng"
+#define EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL
+#endif
+
+EFI_STATUS AhciBusCtlDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+);
+
+EFI_STATUS
+AhciBusCtlGetControllerName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+);
+
+
+CHAR16 *gAhciBusDriverName = L"AMI AHCI BUS Driver";
+CHAR16 *gAhciBusControllerName = L"AHCI Mass Storage Controller";
+
+//==================================================================================
+EFI_COMPONENT_NAME2_PROTOCOL gAhciBusControllerDriverName = {
+ AhciBusCtlDriverName,
+ AhciBusCtlGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: AhciBusCtlDriverName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// RETURN:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciBusCtlDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ //
+ //Supports only English
+ //
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+ *DriverName = gAhciBusDriverName;
+ return EFI_SUCCESS;
+}
+
+
+
+//---------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// FUNCTION: AhciBusCtlGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// RETURNS:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//---------------------------------------------------------------------------
+
+
+EFI_STATUS
+AhciBusCtlGetControllerName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+
+ EFI_STATUS Status;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ SECURITY_PROTOCOL *AhciSecurityInterface;
+ UINTN j, InfoCount;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *pInfo;
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ NULL,
+ gAhciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Supports only "eng"
+ //
+ if(!Language || !ControllerName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+
+ if (ChildHandle == NULL) {
+ *ControllerName = gAhciBusControllerName;
+ return EFI_SUCCESS;
+ }
+ else {
+ Status = pBS->OpenProtocolInformation(
+ Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ &pInfo,&InfoCount
+ );
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ for(j=0; j<InfoCount; j++) {
+ if (pInfo[j].Attributes!=EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) continue;
+ if (pInfo[j].ControllerHandle==ChildHandle) break;
+ }
+ if (InfoCount) pBS->FreePool(pInfo);
+ if (j >= InfoCount) return EFI_UNSUPPORTED;
+
+ //
+ // Open the BLOCK_IO protocol installed on the child device.
+ //
+ Status = pBS->OpenProtocol ( ChildHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **)&BlkIo,
+ gAhciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+
+ if (EFI_ERROR(Status)) {
+ //
+ // If BLKIO protocol is not installed, maybe Securitymode
+ // protocol is installed.
+ //
+ Status = pBS->OpenProtocol ( ChildHandle,
+ &gSecurityModeProtocolGuid,
+ (VOID **)&AhciSecurityInterface,
+ gAhciBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ //
+ // Return Error.
+ //
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+ SataDevInterface = AhciSecurityInterface->BusInterface;
+ }else {
+ SataDevInterface = ((SATA_BLOCK_IO *)BlkIo)->SataDevInterface;
+ }
+ if (SataDevInterface->IdeDeviceHandle != ChildHandle) return EFI_UNSUPPORTED;
+
+ *ControllerName = SataDevInterface->UDeviceName->UnicodeString;
+ return EFI_SUCCESS;
+ }
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciController.c b/Core/EM/Ahci/AhciController.c
new file mode 100644
index 0000000..73d6c31
--- /dev/null
+++ b/Core/EM/Ahci/AhciController.c
@@ -0,0 +1,3403 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciController.c 41 1/27/14 4:57a Rameshr $
+//
+// $Revision: 41 $
+//
+// $Date: 1/27/14 4:57a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciController.c $
+//
+// 41 1/27/14 4:57a Rameshr
+// [TAG] EIP148180
+// [Category] Improvement
+// [Description] Change from EFI_MBR_WRITE_PROTECTION_PROTOCOL to
+// AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL
+// [Files] Ahcibus.c, Ahcibus.h, AhciComponentName.c, AhciController.c
+//
+// 40 12/20/13 4:06a Rameshr
+// [TAG] EIP126640
+// [Category] Improvement
+// [Description] AHCIBUS driver need to preserve the port settings in
+// GeneratePortReset
+// [Files] Ahcibus.c, AhciController.c
+//
+// 39 8/27/13 4:16a Rameshr
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] MbrWriteProtectionProtocol file name changesd to
+// AmiMbrWriteProtectionProtocol.h
+// [Files] AhciController.c, AhciBus.h, Ahcibus.c
+//
+// 38 7/01/13 5:32a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 37 11/18/12 11:45p Rameshr
+// [TAG] EIP102518
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SCT failure for ATAPI BlockIO
+// [RootCause] BufferSize and IOAllign checking not added for Atapi
+// BlockIO protocol functions
+// [Solution] Added BufferSize and IOAllign checking for Atapi BlockIO
+// protocol functions
+// [Files] AhciController.c
+//
+// 36 9/17/12 12:52a Rameshr
+// [TAG] EIP100335
+// [Category] Improvement
+// [Description] Port Multiplier spend long time to connect device.
+// [Files] Ahcibus.c , AhciController.c
+//
+// 35 9/17/12 12:43a Anandakrishnanl
+// [TAG] EIP100847
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hangs when Memory allocation >4Gb in AHCI Mode
+// [RootCause] DBAU not programmed for AhciController
+// [Solution] Fixed by Programming DBAU in PRDT Table
+// [Files] AhciController.c
+//
+// 34 8/21/12 2:28a Rameshr
+// [TAG] EIP98526
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] FIS and CommandList Base address store and restore wont
+// work incase of recursive call
+// [RootCause] FIS and CommandList Base address store and restore wont
+// work incase of recursive call
+// [Solution] FIS and Command List base Address save and restore done
+// properly when the function called recursively.
+// [Files] Ahcicontroller.c
+//
+// 33 8/17/12 3:10a Srikantakumarp
+// [TAG] EIP95863
+// [Category] Bug Fix
+// [Symptom] AhciSmm doesnt save and restore the upper 32bits of FBU and
+// CLBU
+// [RootCause] As Windows uses the 64bit address for FIS Base Address
+// and Command List Base Address, and AHCISMM driver doesn't take care of
+// the upper 32bit value of those which cause the failure in AhciSMM
+// driver.
+// [Solution] Save and Restore the upper 32bits of FBU and CLBU in
+// AhciSmm Driver.
+// [Files] AhciController.c, AhciSmm.c
+//
+// 32 8/16/12 3:06a Rajeshms
+// [TAG] EIP97048
+// [Category] New Feature
+// [Description] ATAPI PassThru Support using
+// EFI_EXT_SCSI_PASS_THRU_PROTOCOL.
+// [Files] AhciBus.c, AhciController.c, IdeBus.c, Atapi.c, PIDEBus.h,
+// PAhciBus.h, ScsiPassThruAtapi.sdl, ScsiPassThruAtapi.mak,
+// ScsiPassThruAtapi.c, ScsiPassThruAtapiSupport.h, ScsiPassThruAtapi.chm,
+// ScsiPassThruExt.h
+//
+// 31 2/03/12 3:23a Rameshr
+// [TAG] EIP82275
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SataReadWritePio doesn't work if the ReadSector count is
+// more than 256 sectors
+// [RootCause] Buffer Address not incremented for the next Read
+// [Solution] Handled the buffer address properly for the next Pio Read
+// [Files] AhciController.c
+//
+// 30 11/08/11 5:19a Deepthins
+// [TAG] EIP74607
+// [Category] Improvement
+// [Description] Block IO Read/Write function, the alignment should be
+// proper. IoAlign value is 0 or 1 means that the buffer can be placed
+// anywhere in memory. Otherwise, IoAlign must be a power of 2, and the
+// requirement is that the start address of a buffer must be evenly
+// divisible by IoAlign with no remainder.
+// [Files] Ata.c, Atapi.c and AhciController.c
+//
+// 29 11/07/11 4:31a Deepthins
+// [TAG] EIP74607
+// [Category] Improvement
+// [Description] IoAlign value is 0 or 1 means that the buffer can be
+// placed anywhere in memory. Otherwise, IoAlign must be a power of 2, and
+// the requirement is that the start address of a buffer must be
+// evenlydivisible by 2 to the power of IoAlign with no remainder.
+// [Files] AhciController.c
+//
+// 28 11/07/11 2:30a Deepthins
+// [TAG] EIP73941
+// [Category] Improvement
+// [Description] BufferSize is 0, ReadBlock function should return
+// EFI_SUCCESS without actual reading.
+// [Files] AhciController.c
+//
+// 27 5/09/11 6:29a Anandv
+// [TAG] - EIP59552
+// [Category] - BUG FIX
+// [Severity] - Normal
+// [Symptom] -AhciController.c file in Ahci driver needs modification to
+// Support Index/Data Port access method for getting the FIS Address.
+// [RootCause] - FISAddress was Obtained using MMIO method irrespective of
+// "INDEX_DATA_PORT_ACCESS" SDL token.
+// [Solution] - FISAddress is now obtained using Port I/O or MMIO method
+// depending on
+// "INDEX_DATA_PORT_ACCESS" SDL token.
+// [Files] - AhciController.c
+//
+// 26 3/29/11 1:03a Lavanyap
+// [TAG] - EIP53849
+// [Category] - BUG FIX
+// [Severity] - Normal
+// [Symptom] - Ide Bus Sources cannot build in IA32 DEBUG mode.
+// [RootCause] - It happened because of usage of << and * with UINT64
+// values in AtaPioDataOut() and SataPioDataOut().
+// [Solution] - Shl64 and Mul64 functions have been implemented to operate
+// UINT64 values.
+// [Files] - Ata.c, AhciController.c
+//
+// 25 2/21/11 3:38a Rameshr
+// Helpbuilder Issue Resolved
+//
+// 24 2/18/11 5:06a Rameshr
+// [TAG]- EIP 37975
+// [Category]-IMPROVEMENT
+// [Description]- Klocwork Issues II - IDE/Ahci module
+// [Files]- AhciBus.c, AhciController.c
+//
+// 23 2/11/11 4:22a Rameshr
+// [TAG] EIP53730
+// [Category] Improvement
+// [Description] Add Odd Loading type information into ATAPI_DEVICE
+// structure in AHCI mode
+// [Files] AhciBus.c
+// AhciController.c
+// AhciBus.h
+//
+// 22 2/10/11 10:35a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSrc.mak
+// AhciBus.c
+// AhciController.c
+// AhciComponentName.c
+// AhciBus.h
+// AhciController.h
+//
+// 21 12/23/10 3:59a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 20 4/16/10 4:15p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 19 9/22/09 10:53a Krishnakumarg
+// Code modified to update SataDevInterface->identifydata in
+// GetIdentifyData function instead of returning in global variable -
+// EIP26411
+//
+// 18 9/21/09 12:34p Krishnakumarg
+// It takes a long time to detect large size HDD(eg. 500GB, 1TB size)
+// under AHCI mode-EIP26499.
+// Replaced TAB with spaces for AMI code standard
+//
+// 17 8/12/09 5:07p Davidd
+// Corrected command parameter error in all PACKET_COMMAND - EIP 24817
+//
+// 16 6/22/09 11:35a Rameshr
+// Odd Type information Saved in Atapi Device Structure.
+// EIP:21548
+//
+// 15 6/18/09 4:27p Rameshr
+// if the Erase command timeout value is 0 or 255, wait for the Erase
+// command completion without timeout value
+// EIP:20630
+//
+// 14 4/29/09 10:54a Rameshr
+//
+// 13 4/28/09 3:51p Rameshr
+//
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 12 3/29/09 11:08a Rameshr
+// Security Erase command timeout value should be from the Identify packet
+// command word 89
+// EIP 20630
+//
+// 11 12/11/08 1:55p Srinin
+// After COMRESET, wait for shadow status register to get synced up with
+// D2H FIS
+//
+// 10 26/09/08 12:32p Anandakrishnanl
+// Fixed Ahci Block Write Issue Which Exceeds 4MB. Added the Proper Offset
+// of Descriptor and Fixed Valid PRDT_I Bit.
+//
+// 9 13/08/08 2:24p Anandakrishnanl
+// Fixed the Minor error that occured in Previous Checkin for EfiDiag NO
+// Media Issue
+//
+// 8 12/08/08 11:26a Anandakrishnanl
+// Fixed the error reported by EFI Diag r(CD/DVD test) to return
+// EFI_NO_MEDIA.
+//
+// 7 5/28/08 9:38a Rameshraju
+// Based on the SDL token index/data or MMIO method used to access the
+// AHCI configuration space.
+//
+// 6 5/09/08 10:05a Rameshraju
+// Default status initilized.
+//
+// 5 4/10/08 12:52p Srinin
+// PMPort field in Command header and in FIS is set to zero instead of 0xF
+// when PORT 0 is accessed.
+//
+// 4 4/03/08 4:40p Srinin
+// In ReadytoAcceptCmd Status was not initialized. Fixed it.
+//
+// 3 3/24/08 6:19p Fasihm
+// Fixed issue that few HDDs not detected because of PhyRdy Change bit.
+//
+// 2 7/03/08 5:31p Anandakrishnanl
+// Added Smart Support as a seperate Driver and Corresponding changes to
+// invoke Smart Protocols and removed SDL-Token
+//
+// 1 28/02/08 6:03p Anandakrishnanl
+// AHCI Bus Driver initial check-in.
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AhciController.c
+//
+// Description: Provides Access to AHCI Controller
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "AhciBus.h"
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+extern AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *AmiBlkWriteProtection;
+#endif
+
+BOOLEAN gPortReset = FALSE; // Avoid Re-entry
+BOOLEAN gSoftReset = FALSE; // Avoid Re-entry
+UINT32 gCommandListBaseAddress = 0;
+UINT32 gFisBaseAddress;
+UINT32 gCommandListBaseAddress2;
+UINT32 gFisBaseAddress2;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SataBlkRead
+//
+// Description: Read from the Sata ATA Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: SataAtaBlkReadWrite
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+
+ EFI_STATUS Status;
+
+ Status = SataAtaBlkReadWrite(This, MediaId, LBA, BufferSize, Buffer, 0);
+
+ TRACE((TRACE_ALWAYS,"AHCI Read: LBA : %lx ByteCount : %lx\n", LBA, BufferSize));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SataBlkWrite
+//
+// Description: Write to Sata ATA Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: SataAtaBlkReadWrite
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+
+ EFI_STATUS Status;
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ if(AmiBlkWriteProtection != NULL) {
+ // Get user input
+ Status = AmiBlkWriteProtection->BlockIoWriteProtectionCheck(
+ AmiBlkWriteProtection,
+ This,
+ LBA,
+ BufferSize
+ );
+ // Abort operation if denied
+ if(Status == EFI_ACCESS_DENIED) {
+ return Status;
+ }
+ }
+#endif
+
+ Status = SataAtaBlkReadWrite(This, MediaId, LBA, BufferSize, Buffer, 1);
+
+ TRACE((TRACE_ALWAYS,"AHCI Write: LBA : %lx ByteCount : %lx\n", LBA, BufferSize));
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SataAtaBlkReadWrite
+//
+// Description: Read/Write to/from Sata ATA Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer,
+// BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: SataReadWriteBusMaster, SataReadWritePio
+//
+// Notes:
+// 1. Check for validity of the input
+// 2. Issue DMA or PIO Read/Write call.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataAtaBlkReadWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer,
+ BOOLEAN READWRITE
+)
+{
+
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ SATA_DEVICE_INTERFACE *SataDevInterface = ((SATA_BLOCK_IO *)This)->SataDevInterface;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ UINTN DataN;
+ UINTN BufferAddress;
+
+ // Check if Media ID matches
+ if (BlkMedia->MediaId != MediaId) return EFI_MEDIA_CHANGED;
+
+ if (BufferSize == 0) return EFI_SUCCESS;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((BlkMedia->IoAlign > 1 ) && (BufferAddress % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check whether the block size is multiple of BlkMedia->BlockSize
+ DataN = BufferSize % BlkMedia->BlockSize;
+ if (DataN) return EFI_BAD_BUFFER_SIZE;
+
+ // Check for Valid start LBA #
+ if (LBA > BlkMedia->LastBlock) return EFI_INVALID_PARAMETER;
+
+ // Check for Valid End LBA #
+ DataN = BufferSize / BlkMedia->BlockSize;
+ if (LBA + DataN > BlkMedia->LastBlock + 1) return EFI_INVALID_PARAMETER;
+
+ #if IDEBUSMASTER_SUPPORT
+ if (DMACapable(SataDevInterface)) {
+ Status = SataReadWriteBusMaster (SataDevInterface, Buffer, BufferSize, LBA,
+ READWRITE ? SataDevInterface->WriteCommand : SataDevInterface->ReadCommand,
+ READWRITE);
+ return Status;
+ }
+ #endif
+
+ Status = SataReadWritePio (SataDevInterface, Buffer, BufferSize, LBA,
+ READWRITE ? SataDevInterface->WriteCommand : SataDevInterface->ReadCommand,
+ READWRITE);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SataAtapiBlkRead
+//
+// Description: Read from the Sata ATAPI Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: SataAtapiBlkReadWrite
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SataAtapiBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+
+ EFI_STATUS Status;
+
+ Status = SataAtapiBlkReadWrite(This, MediaId, LBA, BufferSize, Buffer, 0);
+
+ TRACE((TRACE_ALWAYS,"AHCI ATAPI Read: LBA : %lx ByteCount : %lx\n", LBA, BufferSize));
+
+ return Status;
+
+
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SataAtapiBlkWrite
+//
+// Description: Write to Sata ATAPI Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: SataAtapiBlkReadWrite
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataAtapiBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+
+ EFI_STATUS Status;
+
+ Status = SataAtapiBlkReadWrite(This, MediaId, LBA, BufferSize, Buffer, 1);
+
+ TRACE((TRACE_ALWAYS,"AHCI ATAPI Read: LBA : %lx ByteCount : %lx\n", LBA, BufferSize));
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SataAtapiBlkReadWrite
+//
+// Description: Read/Write to/from Sata ATAPI Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check for validity of Inputs
+// 2. Check whether Media is present or not
+// 3. Issue ATAPi Packet command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataAtapiBlkReadWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer,
+ BOOLEAN READWRITE
+ )
+{
+
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ SATA_DEVICE_INTERFACE *SataDevInterface = ((SATA_BLOCK_IO *)This)->SataDevInterface;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ UINTN DataN;
+ ATAPI_DEVICE *AtapiDevice = SataDevInterface->AtapiDevice;
+ COMMAND_STRUCTURE CommandStructure;
+ INTN TotalNumberofBlocks;
+ INTN TransferLength;
+ UINTN BytesRemainingTobeRead;
+ VOID *TempBuffer = Buffer;
+ UINTN BufferAddress;
+
+
+ // Check if Media Present
+
+ if (BlkMedia->MediaPresent == FALSE) {
+ Status = DetectAtapiMedia(SataDevInterface);
+ if (Status == EFI_SUCCESS) return EFI_MEDIA_CHANGED;
+ if (Status == EFI_NO_MEDIA) return Status;
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Check if Media ID matches
+
+ if (BlkMedia->MediaId != MediaId) return EFI_MEDIA_CHANGED;
+
+ if (BufferSize == 0) return EFI_SUCCESS;
+
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+
+ (VOID *)BufferAddress = Buffer;
+ if((BlkMedia->IoAlign > 1 ) && (BufferAddress % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check whether the block size is multiple of BlkMedia->BlockSize
+
+ DataN = BufferSize % BlkMedia->BlockSize;
+ if (DataN) return EFI_BAD_BUFFER_SIZE;
+
+ // Check for Valid start LBA #
+
+ if (LBA > BlkMedia->LastBlock) return EFI_INVALID_PARAMETER;
+
+ // Check for Valid End LBA #8
+
+ DataN = BufferSize / BlkMedia->BlockSize;
+ if (LBA + DataN > BlkMedia->LastBlock + 1) return EFI_INVALID_PARAMETER;
+
+
+ TotalNumberofBlocks = BufferSize / AtapiDevice->BlockSize;
+
+ for (; TotalNumberofBlocks > 0; TotalNumberofBlocks -= TransferLength) {
+
+ ZeroMemory (&CommandStructure, sizeof(CommandStructure));
+
+ // Calculate # of blocks to be transferred
+
+ if (TotalNumberofBlocks > 0xffff)
+ TransferLength = 0xffff;
+ else
+ TransferLength = TotalNumberofBlocks;
+
+ BytesRemainingTobeRead = TransferLength * AtapiDevice->BlockSize;
+
+ if (READWRITE) CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = SataDevInterface->WriteCommand;
+ else CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = SataDevInterface->ReadCommand;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = AtapiDevice->Lun << 5;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[2] = (UINT8)(((UINT32) LBA) >> 24);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[3] = (UINT8)(((UINT32) LBA) >> 16);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[4] = (UINT8)(((UINT16) LBA) >> 8);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[5] = (UINT8)(((UINT8) LBA) & 0xff);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[7] = (UINT8) (TransferLength >> 8); // MSB
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[8] = (UINT8) (TransferLength & 0xff); // LSB
+ CommandStructure.Buffer = TempBuffer;
+ CommandStructure.ByteCount = (UINT32)BytesRemainingTobeRead;
+
+ Status = ExecutePacketCommand(SataDevInterface, &CommandStructure, READWRITE);
+
+ if (Status != EFI_SUCCESS) {
+
+ // Some error has occured
+ // Check if Device is getting ready. If yes, wait till it gets ready
+
+ if (AtapiDevice->Atapi_Status == BECOMING_READY) {
+ Status = TestUnitReady(SataDevInterface);
+ }
+
+ if (Status == EFI_MEDIA_CHANGED ) {
+ Status = DetectAtapiMedia(SataDevInterface);
+ if (Status == EFI_SUCCESS) return EFI_MEDIA_CHANGED; // Return Media Change
+ if (Status == EFI_NO_MEDIA) {
+ SataDevInterface->SataBlkIo->BlkIo.Media->MediaPresent = FALSE;
+ return Status;
+ }
+ }
+ return Status;
+ }
+
+ if (CommandStructure.ByteCount != BytesRemainingTobeRead) return EFI_DEVICE_ERROR;
+
+ // Update pointer
+
+ (UINT8 *) TempBuffer += BytesRemainingTobeRead;
+ LBA += TransferLength;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataReset
+//
+// Description: Reset ATA device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN BOOLEAN ExtendedVerification
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataBlkFlush
+//
+// Description: Flush the cache
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataBlkFlush(
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataReadWritePio
+//
+// Description: Issues Read/Write Command and Read/Write the data from/to the ATA device
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN OUT VOID *Buffer,
+// UINTN ByteCount,
+// UINT64 LBA
+// IN UINT8 ReadWriteCommand,
+// IN BOOLEAN ReadWrite Read/Write = 0/1
+//
+// Output:
+// *Buffer, EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePioDataCommand
+//
+// Notes:
+// 1. Get the Max. number of sectors that can be Read/written in one Read/Write PIO command
+// 2. Update the Command Structure
+// 3. Issue ExecutePioDataCommand.
+// 4. If all the bytes are read exit else goto step 2
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataReadWritePio(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE
+ )
+{
+ EFI_STATUS Status;
+ UINT32 SectorCount;
+ INT64 MaxSectorCount;
+ INT64 Total_Number_Of_Sectors;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+ UINT8 *TempBuffer = Buffer;
+ if (Check48BitCommand(ReadWriteCommand))
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO_48BIT;
+ else
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO;
+
+ //
+ // Calculate Sector Size
+ //
+ if((SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(SataDevInterface->IdentifyData.Reserved_104_126[13] + \
+ (SataDevInterface->IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+
+ if (SectorSize > ByteCount) SectorSize = (UINT32)ByteCount;
+
+ // Calculate the total number of Sectors to be transferred
+ Total_Number_Of_Sectors = ByteCount / SectorSize ;
+
+ for ( ;Total_Number_Of_Sectors > 0; Total_Number_Of_Sectors -= MaxSectorCount) {
+
+ if (Total_Number_Of_Sectors > MaxSectorCount) SectorCount = 0;
+ else SectorCount = (UINT32) Total_Number_Of_Sectors;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ if (Check48BitCommand (ReadWriteCommand)) {
+ CommandStructure.LBALowExp = (UINT8)Shr64(LBA,24);
+ CommandStructure.LBAMidExp = (UINT8)Shr64(LBA,32);
+ CommandStructure.LBAHighExp = (UINT8)Shr64(LBA,40);
+ CommandStructure.Device = 0x40; // 48Bit LBA
+ }
+ else { // 28 Bit LBA
+ CommandStructure.Device = ((UINT8) ((UINT32) LBA >> 24) & 0x0f) | 0x40;
+ }
+
+ CommandStructure.SectorCount = (UINT16) SectorCount;
+ CommandStructure.LBALow = (UINT8)LBA;
+ CommandStructure.LBAMid = (UINT8)(((UINT32)LBA >>8) & 0xff);
+ CommandStructure.LBAHigh = (UINT8)(((UINT32)LBA >>16) & 0xff);
+ CommandStructure.Command = ReadWriteCommand;
+
+ CommandStructure.Buffer = TempBuffer;
+ CommandStructure.ByteCount = (UINT32)(SectorCount == 0 ? MaxSectorCount : Total_Number_Of_Sectors) * SectorSize ;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, READWRITE); // Returns # of bytes read
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TempBuffer += CommandStructure.ByteCount;
+ SectorCount = CommandStructure.ByteCount / SectorSize ;
+ LBA += SectorCount;
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataPioDataOut
+//
+// Description: Issues Read/Write Command with SubCommand feature
+// and Reads/Writes data to the ATA device.
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN OUT VOID *Buffer,
+// IN UINTN ByteCount,
+// IN UINT8 Features,
+// IN UINT16 LBALow,
+// IN UINT8 LBALowExp,
+// IN UINT8 LBAMid,
+// IN UINT8 LBAMidExp,
+// IN UINT8 LBAHigh,
+// IN UINT8 LBAHighExp,
+// IN UINT8 ReadWriteCommand
+// IN BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePioDataCommand
+//
+// Notes:
+// 1. Get the Max. number of sectors that can be transferred in one Read/Write PIO command
+// 2. Update the Command Structure
+// 3. Issue ExecutePioDataCommand.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SataPioDataOut (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT8 Features,
+ IN UINT8 LBALow,
+ IN UINT8 LBALowExp,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAMidExp,
+ IN UINT8 LBAHigh,
+ IN UINT8 LBAHighExp,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE
+ )
+{
+ EFI_STATUS Status;
+ UINT32 SectorCount;
+ INT64 MaxSectorCount;
+ INT64 Total_Number_Of_Sectors;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+ UINT64 LBA = 0;
+ UINT64 LBAHighDword = 0;
+
+ if (Check48BitCommand(ReadWriteCommand)) {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO_48BIT;
+ //
+ // if 48 Bit LBA form Upper Dword
+ //
+ LBAHighDword |= LBAHighExp;
+ LBAHighDword = ( Shl64(( Shl64( LBAHighDword, 8)| LBAMidExp), 8)| LBALowExp);
+ } else {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO;
+ }
+ //
+ // Complete LBA
+ //
+ LBA |= LBAHigh;
+ LBA = (( Shl64(( Shl64( LBA, 8) | LBAMid ), 8)| LBALow)| Shl64( LBAHighDword, 24 ));
+
+ //
+ // Calculate Sector Size
+ //
+ if((SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(SataDevInterface->IdentifyData.Reserved_104_126[13] + \
+ (SataDevInterface->IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+
+ if (SectorSize > ByteCount) SectorSize = (UINT32)ByteCount;
+
+ // Calculate the total number of Sectors to be transferred
+ Total_Number_Of_Sectors = ByteCount / SectorSize ;
+
+ for ( ;Total_Number_Of_Sectors > 0; Total_Number_Of_Sectors -= MaxSectorCount) {
+
+ if ( Total_Number_Of_Sectors > MaxSectorCount ) SectorCount = 0;
+ else SectorCount = (UINT32) Total_Number_Of_Sectors;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ if (Check48BitCommand (ReadWriteCommand)) {
+ //
+ // If 48Bit LBA then form Upper DWord
+ //
+ CommandStructure.LBALowExp = LBALowExp;
+ CommandStructure.LBAMidExp = LBAMidExp;
+ CommandStructure.LBAHighExp = LBAHighExp;
+ CommandStructure.Device = 0x40;
+ }
+ else { // 28 Bit LBA
+ CommandStructure.Device = ((UINT8) LBAHigh & 0x0f) | 0x40;
+ }
+
+ CommandStructure.Features = Features; // SubCommand
+ CommandStructure.SectorCount = (UINT16) SectorCount;
+ CommandStructure.LBALow = LBALow;
+ CommandStructure.LBAMid = LBAMid;
+ CommandStructure.LBAHigh = LBAHigh;
+ CommandStructure.Command = ReadWriteCommand;
+
+ CommandStructure.Buffer = Buffer;
+ CommandStructure.ByteCount = (UINT32)(SectorCount == 0 ? MaxSectorCount : Total_Number_Of_Sectors) * SectorSize ;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, READWRITE); // Returns # of bytes read
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ SectorCount = CommandStructure.ByteCount / SectorSize ;
+ LBA += SectorCount;
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SataReadWriteBusMaster
+//
+// Description: Issues Read/Write Command and Read/Write the data from/to the ATA device
+// using BusMaster
+//
+// Input:
+// SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN OUT VOID *Buffer,
+// IN UINTN ByteCount,
+// IN UINT64 LBA,
+// IN UINT8 ReadWriteCommand,
+// IN BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecuteDmaDataCommand
+//
+// Notes:
+// 1. Get the Max. number of sectors that can be Read/written in one Read/Write Bus master command
+// 2. Update the Command Structure
+// 3. Issue ExecutePioDataCommand.
+// 4. If all the bytes are read exit else goto step 2
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+SataReadWriteBusMaster(
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE
+ )
+{
+
+ EFI_STATUS Status;
+ UINTN Total_Number_Of_Sectors,MaxSectorCount;
+ UINTN CurrentSectorCount,CurrentByteCount;
+ UINT8 *TempBuffer = Buffer;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+
+ if (Check48BitCommand(ReadWriteCommand))
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO_48BIT;
+ else
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO;
+
+ //
+ // Calculate Sector Size
+ //
+ if((SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (SataDevInterface->IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(SataDevInterface->IdentifyData.Reserved_104_126[13] + \
+ (SataDevInterface->IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+ if (SectorSize > ByteCount) SectorSize = (UINT32)ByteCount;
+
+ Total_Number_Of_Sectors = ByteCount / SectorSize ;
+
+ do {
+ if (Total_Number_Of_Sectors > MaxSectorCount) CurrentSectorCount = 0;
+ else CurrentSectorCount = Total_Number_Of_Sectors;
+ CurrentByteCount = (CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount) * SectorSize ;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.Buffer = TempBuffer;
+ CommandStructure.ByteCount = (UINT32)CurrentByteCount;
+ CommandStructure.Command = ReadWriteCommand;
+
+ if (Check48BitCommand (ReadWriteCommand)) {
+ // 48 Bit LBA
+ // Write the Upper LBA DWORD and Upper byte of Sector Count
+ CommandStructure.LBALowExp = (UINT8)Shr64(LBA,24);
+ CommandStructure.LBAMidExp = (UINT8) Shr64(LBA,32);
+ CommandStructure.LBAHighExp = (UINT8) Shr64(LBA,40);
+ CommandStructure.Device = 0x40; // 48Bit LBA
+ }
+ else { // 28 Bit LBA
+ CommandStructure.Device = ((UINT8) ((UINT32) LBA >> 24) & 0x0f) | 0x40;
+ }
+
+ CommandStructure.SectorCount = (UINT16) CurrentSectorCount;
+ CommandStructure.LBALow = (UINT8)LBA;
+ CommandStructure.LBAMid = (UINT8) (((UINT32)LBA >>8) & 0xff);
+ CommandStructure.LBAHigh = (UINT8) (((UINT32)LBA >>16) & 0xff);
+
+ Status = ExecuteDmaDataCommand (SataDevInterface, &CommandStructure, READWRITE); // Returns # of bytes read
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ CurrentByteCount = CommandStructure.ByteCount;
+ CurrentSectorCount = CurrentByteCount / SectorSize;
+
+ TempBuffer += CurrentByteCount;
+ Total_Number_Of_Sectors -= (CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount);
+ LBA += (CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount);
+
+ } while (Total_Number_Of_Sectors);
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Check48BitCommand
+//
+// Description: Checks if the command is for 48-bit LBA
+//
+// Input:
+// IN UINT8 Command
+//
+// Output:
+// TRUE/FLASE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+Check48BitCommand (
+ IN UINT8 Command
+ )
+{
+ if ( Command == READ_SECTORS_EXT ||
+ Command == READ_MULTIPLE_EXT ||
+ Command == WRITE_SECTORS_EXT ||
+ Command == WRITE_MULTIPLE_EXT ||
+ Command == READ_DMA_EXT ||
+ Command == WRITE_DMA_EXT )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExecuteNonDataCommand
+//
+// Description: Issue a Non-Data command to the SATA Device
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Stop the Controller
+// 2. Check if the device is ready to accept a Command.
+// 3. Build Command list
+// 4. Start the Controller.
+// 5. Wait till command completes. Check for errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ExecuteNonDataCommand (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure
+)
+{
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *)(UINTN) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)(UINTN)AhciBusInterface->PortCommandTableBaseAddr;
+
+ Status = StopController(AhciBusInterface, SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+ return Status;
+ }
+
+ BuildCommandList(SataDevInterface, CommandList, AhciBusInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, CommandStructure, CommandList, Commandtable);
+
+ // Data-in
+ CommandList->Ahci_Cmd_W = 0;
+
+ // Update of Command Register
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, NON_DATA_CMD, ATAPI_BUSY_CLEAR_TIMEOUT );
+
+ // Stop Controller
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExecutePioDataCommand
+//
+// Description: Ececute PIO Data In/Out command
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN OUT COMMAND_STRUCTURE *CommandStructure
+// IN BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS, CommandStructure->ByteCount
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, BuildAtapiCMD
+// BuildPRDT, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Stop the Controller
+// 2. Check if the device is ready to accept a Command.
+// 3. Build Command list
+// 4. Start the Controller.
+// 5. Wait till command completes. Check for errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ExecutePioDataCommand (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT COMMAND_STRUCTURE *CommandStructure,
+ IN BOOLEAN READWRITE
+)
+{
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *)(UINTN) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)(UINTN)AhciBusInterface->PortCommandTableBaseAddr;
+
+
+ Status = StopController(AhciBusInterface, SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+ return Status;
+ }
+ BuildCommandList(SataDevInterface, CommandList, AhciBusInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildAtapiCMD(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildPRDT(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+
+ if (READWRITE) {
+ CommandList->Ahci_Cmd_W = 1;
+ }
+ else {
+ CommandList->Ahci_Cmd_W = 0;
+ }
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+
+ // For Security Erase command the time out value comes from Identify Data.
+ if(CommandStructure->Command == SECURITY_ERASE_UNIT ) {
+ UINT32 EraseCommandTimeout;
+ EraseCommandTimeout= (UINT32)(SataDevInterface->IdentifyData.Time_security_Earse_89);
+ if(EraseCommandTimeout <= 254) {
+ EraseCommandTimeout=EraseCommandTimeout * 2 * 1000 * 60; //Value * 2Minitues
+ } else {
+ EraseCommandTimeout= 0; // No timeout
+ }
+ Status = WaitforCommandComplete(SataDevInterface, PIO_DATA_IN_CMD, EraseCommandTimeout);
+ } else {
+ Status = WaitforCommandComplete(SataDevInterface, PIO_DATA_IN_CMD,
+ SataDevInterface->DeviceType == ATA? DMA_ATA_COMMAND_COMPLETE_TIMEOUT \
+ : DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT );
+ }
+
+ CommandStructure->ByteCount = CommandList->Ahci_Cmd_PRDBC;
+
+ // Stop Controller
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExecuteDmaDataCommand
+//
+// Description:
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE *CommandStructure
+// IN BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, BuildAtapiCMD
+// BuildPRDT, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Stop the Controller
+// 2. Check if the device is ready to accept a Command.
+// 3. Build Command list
+// 4. Start the Controller.
+// 5. Wait till command completes. Check for errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ExecuteDmaDataCommand (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE *CommandStructure,
+ IN BOOLEAN READWRITE
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *)(UINTN) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)(UINTN)AhciBusInterface->PortCommandTableBaseAddr;
+
+
+ Status = StopController(AhciBusInterface, SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+ return Status;
+ }
+ BuildCommandList(SataDevInterface, CommandList, AhciBusInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildAtapiCMD(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildPRDT(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+
+ // Data-in
+ if (READWRITE) {
+ CommandList->Ahci_Cmd_W = 1;
+ }
+ else {
+ CommandList->Ahci_Cmd_W = 0 ;
+ }
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, DMA_DATA_IN_CMD,
+ SataDevInterface->DeviceType == ATA? DMA_ATA_COMMAND_COMPLETE_TIMEOUT \
+ : DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT );
+
+ if (!EFI_ERROR(Status)){
+ //Check if the required BYTES have been received
+ if (CommandList->Ahci_Cmd_PRDBC != CommandStructure->ByteCount){
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+ // Stop Controller
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+
+ CommandStructure->ByteCount = CommandList->Ahci_Cmd_PRDBC;
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExecutePacketCommand
+//
+// Description: Execute a Atapi Packet command
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE *CommandStructure
+// IN BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, BuildAtapiCMD
+// BuildPRDT, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Stop the Controller
+// 2. Check if the device is ready to accept a Command.
+// 3. Build Command list
+// 4. Start the Controller.
+// 5. Wait till command completes. Check for errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ExecutePacketCommand (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE *CommandStructure,
+ IN BOOLEAN READWRITE
+ )
+{
+
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *)(UINTN) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)(UINTN)AhciBusInterface->PortCommandTableBaseAddr;
+ UINT32 AhciBaseAddr = (UINT32)AhciBusInterface->AhciBaseAddress;
+ ATAPI_DEVICE *AtapiDevice = SataDevInterface->AtapiDevice;
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 Data8;
+
+ CommandStructure->LBAMid = (UINT8)(CommandStructure->ByteCount);
+ CommandStructure->LBAHigh = (UINT8)(CommandStructure->ByteCount >> 8);
+ CommandStructure->Command = PACKET_COMMAND;
+
+ Status = StopController(AhciBusInterface, SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+ return Status;
+ }
+ BuildCommandList(SataDevInterface, CommandList, AhciBusInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildAtapiCMD(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildPRDT(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+
+ if (READWRITE) {
+ CommandList->Ahci_Cmd_W = 1;
+ }
+ else {
+ CommandList->Ahci_Cmd_W = 0;
+ }
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, PIO_DATA_IN_CMD,
+ SataDevInterface->DeviceType == ATA? DMA_ATA_COMMAND_COMPLETE_TIMEOUT \
+ : DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT );
+
+
+ // Handle ATAPI device error
+ if (EFI_ERROR(Status) && SataDevInterface->DeviceType == ATAPI) {
+ Data8 = HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD);
+ if (Data8 & CHK ){
+ return HandleAtapiError(SataDevInterface);
+
+ }
+ }
+ AtapiDevice->Atapi_Status = EFI_SUCCESS;
+
+ CommandStructure->ByteCount = CommandList->Ahci_Cmd_PRDBC;
+
+ // Stop Controller
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HandleAtapiError
+//
+// Description: Check for ATAPI Errors
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePacketCommand
+//
+// Notes:
+// 1. Execute ATAPI Request Sense command.
+// 2. Check for Device getting ready, Media Change, No Media and other errors. Update AtapiDevice->Atapi_Status
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+HandleAtapiError (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+
+ EFI_STATUS Status;
+ UINT8 Data8 = 0;
+ UINT8 SenseData[256];
+ COMMAND_STRUCTURE CommandStructure;
+ ATAPI_DEVICE *AtapiDevice = SataDevInterface->AtapiDevice;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)AhciBusInterface->AhciBaseAddress;
+ UINT8 Port = SataDevInterface->PortNumber;
+
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+
+ ZeroMemory (SenseData, 256);
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_REQUEST_SENSE;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[4] = 0xff;
+
+ CommandStructure.ByteCount = 256;
+ CommandStructure.Buffer = SenseData;
+
+ Status = ExecutePacketCommand(SataDevInterface, &CommandStructure, 0);
+
+ if (EFI_ERROR(Status)) {
+ Data8 = HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD);
+ }
+
+ SataDevInterface->AtapiSenseDataLength = 0;
+
+ // Check for DF and CHK
+ if (Data8 & (DF | CHK)) {
+ goto exit_HandleAtapiError_with_Reset;
+ }
+
+ if (!EFI_ERROR(Status)){
+ //
+ // Store the SenseData whcih would be used by ScsiPassThruAtapi PassThru Interface.
+ //
+ pBS->CopyMem( SataDevInterface->AtapiSenseData, SenseData, 256);
+ SataDevInterface->AtapiSenseDataLength = CommandStructure.ByteCount;
+
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR; // Default Value
+
+ if (((SenseData[2] & 0xf) == 2) && (SenseData[12] == 0x3a)) {
+ Status = EFI_NO_MEDIA;
+ AtapiDevice->Atapi_Status = MEDIUM_NOT_PRESENT;
+ }
+ if (((SenseData[2] & 0xf) == 2) && (SenseData[12] == 0x04) && (SenseData[13] == 0x01)) {
+ Status = EFI_MEDIA_CHANGED;
+ AtapiDevice->Atapi_Status = BECOMING_READY;
+ }
+
+ if (((SenseData[2] & 0xf) == 6) && (SenseData[12] == 0x28)){
+ Status = EFI_MEDIA_CHANGED;
+ AtapiDevice->Atapi_Status = MEDIA_CHANGED;
+ }
+
+ if (((SenseData[2] & 0xf) == 7) && (SenseData[12] == 0x27)){
+ Status = EFI_WRITE_PROTECTED;
+ AtapiDevice->Atapi_Status = WRITE_PROTECTED_MEDIA;
+ }
+
+ if (((SenseData[2] & 0xf) == 6) && (SenseData[12] == 0x29)){
+ AtapiDevice->Atapi_Status = POWER_ON_OR_DEVICE_RESET;
+ }
+
+ if (((SenseData[2] & 0xf) == 5) && (SenseData[0] == 0x70)){
+ AtapiDevice->Atapi_Status = ILLEGAL_REQUEST;
+ }
+ }
+
+exit_HandleAtapiError_with_Reset:
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadWritePMPort
+//
+// Description: Read/Write routine to PM ports
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 RegNum,
+// IN OUT UINT32 *Data
+// IN BOOLEAN READWRITE // TRUE for Write
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, BuildAtapiCMD
+// BuildPRDT, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Update Command Structure for READ/Write Port Multiplier command
+// 2. Issue command
+// 3. Check for errors.
+// 4. Read the out data in case of READ.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadWritePMPort (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 RegNum,
+ IN OUT UINT32 *Data,
+ IN BOOLEAN READWRITE
+)
+{
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+ AHCI_RECEIVED_FIS *PortFISBaseAddr = (AHCI_RECEIVED_FIS *)(UINTN)(SataDevInterface->PortFISBaseAddr);
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *)(UINTN) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)(UINTN)AhciBusInterface->PortCommandTableBaseAddr;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.Command = READ_PORT_MULTIPLIER;
+
+ if (READWRITE) {
+ CommandStructure.SectorCount = (UINT16) (*Data & 0xFF);
+ CommandStructure.LBALow = (UINT8) (*Data >> 8);
+ CommandStructure.LBAMid = (UINT8)(*Data >> 16);
+ CommandStructure.LBAHigh = (UINT8)(*Data >> 24);
+ CommandStructure.Command = WRITE_PORT_MULTIPLIER;
+ }
+
+ CommandStructure.Device = Port;
+ CommandStructure.Features = RegNum;
+
+ Status = StopController(AhciBusInterface, SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+ return Status;
+ }
+
+ BuildCommandList(SataDevInterface, CommandList, AhciBusInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, CommandStructure, CommandList, Commandtable);
+
+ // Data-in
+ CommandList->Ahci_Cmd_W = 0;
+
+ // Update of Command Register
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ // Update the Port Address
+ CommandList->Ahci_Cmd_PMP = CONTROL_PORT;
+ Commandtable->CFis.AHci_CFis_PmPort = CONTROL_PORT;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, NON_DATA_CMD, TIMEOUT_1SEC);
+
+ // Stop Controller
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+
+ if (!READWRITE) {
+ *Data = 0;
+ if (!EFI_ERROR(Status)) {
+ *Data = PortFISBaseAddr->Ahci_Rfis[12] |
+ (PortFISBaseAddr->Ahci_Rfis[4] << 8) |
+ (PortFISBaseAddr->Ahci_Rfis[5] << 16) |
+ (PortFISBaseAddr->Ahci_Rfis[6] << 24);
+ }
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetIdentifyData
+//
+// Description: Reaturn Identify data from SATA device
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// gIdentifyDataBuffer
+// EFI_STATUS
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Build CommandStructure.
+// 2. Issue ExecutePioDataCommand
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetIdentifyData (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+ IDENTIFY_DATA tIdentifyData;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ // Read Identifydata
+ CommandStructure.Buffer = &tIdentifyData;
+ CommandStructure.ByteCount = sizeof(IDENTIFY_DATA);
+ CommandStructure.Device = 0;
+ CommandStructure.Command = SataDevInterface->DeviceType == ATA ? IDENTIFY_COMMAND : IDENTIFY_PACKET_COMMAND;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, FALSE);
+
+ if (CommandStructure.ByteCount != sizeof(IDENTIFY_DATA)) { Status = EFI_DEVICE_ERROR; }
+
+ if(!EFI_ERROR(Status))
+ pBS->CopyMem(&(SataDevInterface->IdentifyData), &tIdentifyData, sizeof(IDENTIFY_DATA));
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataAtapiInquiryData
+//
+// Description: Return ATAPI Inquiry data
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// OUT UINT8 *InquiryData,
+// IN OUT UINT16 *InquiryDataSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePioDataCommand
+//
+// Notes:
+// 1. Update CommandStructure
+// 2. Issue ExecutePioDataCommand
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataAtapiInquiryData (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ OUT UINT8 *InquiryData,
+ IN OUT UINT16 *InquiryDataSize
+)
+{
+
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = InquiryData;
+ CommandStructure.ByteCount = *InquiryDataSize;
+ CommandStructure.Command = PACKET_COMMAND;
+ CommandStructure.LBAMid = (UINT8)*InquiryDataSize;
+ CommandStructure.LBAHigh = (UINT8)(*InquiryDataSize >> 8);
+
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0]=ATAPI_INQUIRY;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[4]=(UINT8)*InquiryDataSize;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, 0);
+
+ if (!EFI_ERROR(Status)) {
+ *InquiryDataSize = (UINT16)CommandStructure.ByteCount;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DetectAtapiMedia
+//
+// Description: Detects whether a Media is present in the ATAPI Removable device or not.
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: TestUnitReady, ExecutePacketCommand
+//
+// Notes:
+// 1. Issue Read Capacity command for CDROM or Read Format command for other ATAPI devices.
+// 2. If step 1 is successfull, update last LBA, Block Size, Read/Write capable, Media ID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DetectAtapiMedia(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+ UINT8 *InputData, LoopCount;
+ ATAPI_DEVICE *AtapiDevice = SataDevInterface->AtapiDevice;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = SataDevInterface->SataBlkIo->BlkIo.Media;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT16 ByteCount = 256, Data16;
+ COMMAND_STRUCTURE CommandStructure;
+ BOOLEAN ReadCapacity=FALSE;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+// Default Values
+ BlkMedia->MediaPresent = FALSE;
+ BlkMedia->LastBlock = 0x100; // Dummy value
+ SataDevInterface->ReadCommand = ATAPI_READ_10;
+ SataDevInterface->WriteCommand = ATAPI_WRITE_10;
+
+ Status = TestUnitReady(SataDevInterface);
+ if ((Status != EFI_MEDIA_CHANGED) && (Status != EFI_SUCCESS)) {
+ return Status;
+ }
+
+// Issue Read Capacity command
+ Status = pBS->AllocatePool (EfiBootServicesData, ByteCount, (VOID**)&InputData);
+ if (EFI_ERROR(Status)) return Status;
+
+// For CDROM use Read Capacity command else use Read Format Command
+ if (AtapiDevice->DeviceType == CDROM_DEVICE){
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE; // Default size
+ AtapiDevice->BlockSize = (UINT16)(BlkMedia->BlockSize);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_READ_CAPACITY;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = AtapiDevice->Lun << 5;
+ Data16 = 8;
+ }
+ else {
+ BlkMedia->BlockSize = LS120_BLOCK_SIZE; // Default Size
+ AtapiDevice->BlockSize = (UINT16)(BlkMedia->BlockSize);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_READ_FORMAT_CAPACITIES;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = AtapiDevice->Lun << 5;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[7] = (UINT8)(ByteCount >> 8);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[8] = (UINT8)(ByteCount & 0xff);
+ Data16 = ByteCount;
+ }
+
+ for (LoopCount = 0; LoopCount < 5; LoopCount++) { // 5sec loop
+ ByteCount = Data16;
+ ZeroMemory (InputData, ByteCount);
+ CommandStructure.Buffer = InputData;
+ CommandStructure.ByteCount = ByteCount;
+ Status = ExecutePacketCommand(SataDevInterface, &CommandStructure, 0);
+ if(CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] == ATAPI_READ_FORMAT_CAPACITIES &&
+ AtapiDevice->Atapi_Status == ILLEGAL_REQUEST) {
+ //
+ //If the Read Format Capacities not supported by device, try
+ //ReadCapacity command
+ //
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE; // Default size
+ AtapiDevice->BlockSize = (UINT16)(BlkMedia->BlockSize);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_READ_CAPACITY;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = AtapiDevice->Lun << 5;
+ Data16 = 8;
+ ReadCapacity=TRUE;
+ }
+ if (AtapiDevice->Atapi_Status == EFI_SUCCESS) break;
+ if (AtapiDevice->Atapi_Status == MEDIUM_NOT_PRESENT) break;
+ }
+
+ if (Status == EFI_SUCCESS) {
+ if(ReadCapacity == TRUE) {
+ BlkMedia->LastBlock = InputData[0] << 24 | InputData[1] << 16 | InputData[2] << 8 | InputData[3];
+ BlkMedia->LastBlock--;
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->MediaId ++;
+ BlkMedia->BlockSize = InputData[4] << 24 | InputData[5] << 16 | InputData[6] << 8 | InputData[7];
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ BlkMedia->ReadOnly = FALSE;
+ } else if (AtapiDevice->DeviceType == CDROM_DEVICE) {
+ BlkMedia->LastBlock = InputData[0] << 24 | InputData[1] << 16 | InputData[2] << 8 | InputData[3];
+ BlkMedia->LastBlock--;
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE;
+ AtapiDevice->BlockSize = (UINT16)(BlkMedia->BlockSize);
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->MediaId ++;
+ BlkMedia->ReadOnly = TRUE;
+ } else if (InputData[8] != 3) { // No media present
+ BlkMedia->LastBlock = InputData[4] << 24 | InputData[5] << 16 | InputData[6] << 8 | InputData[7];
+ BlkMedia->LastBlock--;
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->MediaId ++;
+ BlkMedia->BlockSize = InputData[9] << 16 | InputData[10] << 8 | InputData[11];
+ BlkMedia->ReadOnly = FALSE;
+ AtapiDevice->BlockSize = (UINT16)(BlkMedia->BlockSize);
+ }
+
+// Update ReadOnly Status
+ if (AtapiDevice->DeviceType != CDROM_DEVICE) {
+ ByteCount = 256;
+ ZeroMemory (InputData, ByteCount);
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_MODE_SENSE;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[2] = RETURN_ALL_PAGES;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[7] = (UINT8)(ByteCount >> 8);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[8] = (UINT8)(ByteCount & 0xff);
+ CommandStructure.Buffer = InputData;
+ CommandStructure.ByteCount= ByteCount;
+ Status = ExecutePacketCommand(SataDevInterface, &CommandStructure, 0);
+ if ((Status == EFI_SUCCESS) && (ByteCount > 8)) {
+ BlkMedia->ReadOnly = (InputData[3] & 0x80) != 0 ? TRUE : FALSE;
+ }
+ }
+ }
+
+ pBS->FreePool(InputData);
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataCheckOddType
+//
+// Description: Return ODD type
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePioDataCommand
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataGetOddType (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT UINT16 *OddType
+)
+
+{
+
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT8 *ProfileData;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,16,(VOID**)&ProfileData);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = ProfileData;
+ CommandStructure.ByteCount = 16;
+ CommandStructure.Command = PACKET_COMMAND;
+ CommandStructure.LBAMid = 16;
+ CommandStructure.LBAHigh = 0;
+
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0]= ATAPI_GET_CONFIGURATION;
+ //
+ // Get the Feature Discriptor.
+ //
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = FEATURE_DISCRIPTOR;
+ //
+ // Get the Profile list
+ //
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[3] = GET_PROFILE_LIST;
+ //
+ // Responce Data Size
+ //
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[8] = 0x10;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, 0);
+
+ if (!EFI_ERROR(Status)) {
+ //
+ // Get the Profile Number
+ //
+ *OddType=(UINT16 )(((ProfileData[sizeof(GET_CONFIGURATION_HEADER)+4]) << 8) + ProfileData[sizeof(GET_CONFIGURATION_HEADER)+5]);
+ }
+
+ pBS->FreePool(ProfileData);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SataGetOddLoadingType
+//
+// Description: Return ODD Loading type information
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePioDataCommand
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SataGetOddLoadingType (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN OUT UINT8 *OddLoadingType
+)
+
+{
+
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT8 *ProfileData;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,16,(VOID**)&ProfileData);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = ProfileData;
+ CommandStructure.ByteCount = 16;
+ CommandStructure.Command = PACKET_COMMAND;
+ CommandStructure.LBAMid = 16;
+ CommandStructure.LBAHigh = 0;
+
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0]= ATAPI_GET_CONFIGURATION;
+ //
+ // Get the Feature Discriptor.
+ //
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = FEATURE_DISCRIPTOR;
+ //
+ // Get the Removable Medium feature
+ //
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[3] = GET_REMOVEABLE_MEDIUM_FEATURE;
+ //
+ // Responce Data Size
+ //
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[8] = 0x10;
+
+ Status = ExecutePioDataCommand (SataDevInterface, &CommandStructure, 0);
+
+ if (!EFI_ERROR(Status)) {
+ //
+ // Get the ODD Loading Type
+ //
+ *OddLoadingType=(UINT8 )(((ProfileData[sizeof(GET_CONFIGURATION_HEADER)+4]) & 0xE0) >> 5);
+ }
+
+ pBS->FreePool(ProfileData);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: TestUnitReady
+//
+// Description: Issues Start/Stop unit Command
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS EFI_SUCCESS : If Media is accessible
+// EFI_NO_MEDIA
+// EFI_MEDIA_CHANGED
+// EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals: ExecutePacketCommand
+//
+// Notes:
+// 1. Update CommandStructure for ATAPI_TEST_UNIT_READY command
+// 2. Issue ExecutePacketCommand
+// 3. Check if the device is ready to accept command, whether Media is present or not.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+TestUnitReady(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+ )
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ ATAPI_DEVICE *AtapiDevice = SataDevInterface->AtapiDevice;
+ UINT16 LoopCount;
+ COMMAND_STRUCTURE CommandStructure;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_TEST_UNIT_READY;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = AtapiDevice->Lun << 5;
+ CommandStructure.Buffer = NULL;
+ CommandStructure.ByteCount = 0x100;
+
+ for (LoopCount = 0; LoopCount < 1000; LoopCount++) { // 10sec loop ( 1000 * 10 msec = 10Sec)
+ Status = ExecutePacketCommand(SataDevInterface, &CommandStructure, 0);
+ if (Status == EFI_SUCCESS) break;
+ if (AtapiDevice->Atapi_Status == MEDIUM_NOT_PRESENT) break;
+ if (AtapiDevice->Atapi_Status == MEDIA_CHANGED) break;
+ pBS->Stall(10000); // 10msec
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildCommandList
+//
+// Description: Builds command list
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN UINT32 CommandTableBaseAddr
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Update CommandList bits
+// 2. Not all fields like Ahci_Cmd_A are updated.
+// 3. Port number is set to 0xF (Control port) if PM Port number is 0xFF.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildCommandList (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN UINT32 CommandTableBaseAddr
+)
+{
+
+
+ ZeroMemory (CommandList, sizeof(AHCI_COMMAND_LIST));
+ // CommandList->Ahci_Cmd_A = SataDevInterface->DeviceType == ATAPI ? 1 : 0; // set elsewhere
+ CommandList->Ahci_Cmd_P = 0;
+ CommandList->Ahci_Cmd_R = 0;
+ CommandList->Ahci_Cmd_B = 0;
+ CommandList->Ahci_Cmd_Rsvd1 = 0;
+ CommandList->Ahci_Cmd_PMP = SataDevInterface->PMPortNumber == 0xFF ? 0x0 : SataDevInterface->PMPortNumber;
+ CommandList->Ahci_Cmd_PRDTL = 0;
+ CommandList->Ahci_Cmd_PRDBC = 0;
+ CommandList->Ahci_Cmd_CTBA = CommandTableBaseAddr;
+ CommandList->Ahci_Cmd_CTBAU = 0;
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildCommandFIS
+//
+// Description: Build Command FIS
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN AHCI_COMMAND_TABLE *Commandtable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Update Command FIS data area.
+// 2. Update the Command FIS lenght in Command List table
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildCommandFIS (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN AHCI_COMMAND_TABLE *Commandtable
+)
+{
+
+
+ ZeroMemory (Commandtable, sizeof(AHCI_COMMAND_TABLE));
+
+ Commandtable->CFis.Ahci_CFis_Type = FIS_REGISTER_H2D;
+ Commandtable->CFis.AHci_CFis_PmPort = SataDevInterface->PMPortNumber == 0xFF ? 0x0 : SataDevInterface->PMPortNumber;
+// Commandtable->CFis.Ahci_CFis_C = 1; // Set elsewhere
+ Commandtable->CFis.Ahci_CFis_Cmd = CommandStructure.Command;
+
+ Commandtable->CFis.Ahci_CFis_Features = CommandStructure.Features;
+ Commandtable->CFis.Ahci_CFis_FeaturesExp = CommandStructure.FeaturesExp;
+
+ Commandtable->CFis.Ahci_CFis_SecNum = CommandStructure.LBALow;
+ Commandtable->CFis.Ahci_CFis_SecNumExp = CommandStructure.LBALowExp;
+
+ Commandtable->CFis.Ahci_CFis_ClyLow = CommandStructure.LBAMid;
+ Commandtable->CFis.Ahci_CFis_ClyLowExp = CommandStructure.LBAMidExp;
+
+ Commandtable->CFis.Ahci_CFis_ClyHigh = CommandStructure.LBAHigh;
+ Commandtable->CFis.Ahci_CFis_ClyHighExp = CommandStructure.LBAHighExp;
+
+ Commandtable->CFis.Ahci_CFis_SecCount = (UINT8)(CommandStructure.SectorCount);
+ Commandtable->CFis.Ahci_CFis_SecCountExp = (UINT8)(CommandStructure.SectorCount >> 8);
+
+ Commandtable->CFis.Ahci_CFis_DevHead = CommandStructure.Device;
+ Commandtable->CFis.Ahci_CFis_Control = CommandStructure.Control;
+
+ CommandList->Ahci_Cmd_CFL = FIS_REGISTER_H2D_LENGTH / 4;
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildAtapiCMD
+//
+// Description:
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN AHCI_COMMAND_TABLE *Commandtable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Copy Packet data to command table
+// 2. Set Atapi bit in Command List
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildAtapiCMD(
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN AHCI_COMMAND_TABLE *Commandtable
+)
+{
+
+
+ pBS->CopyMem(&(Commandtable->AtapiCmd),&(CommandStructure.AtapiCmd),sizeof(AHCI_ATAPI_COMMAND));
+
+ if (Commandtable->CFis.Ahci_CFis_Cmd == PACKET_COMMAND){ // Is it a packet command?
+ CommandList->Ahci_Cmd_A = 1;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildPRDT
+//
+// Description: Build PRDT table
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN AHCI_COMMAND_TABLE *Commandtable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Build as many PRDT table entries based on ByteCount.
+// 2. Set the I flag for the lasr PRDT table.
+// 3. Update PRDT table lenght in CommandList
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildPRDT (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN AHCI_COMMAND_TABLE *Commandtable
+)
+{
+
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 ByteCount = CommandStructure.ByteCount;
+ UINT16 Prdtlength = 0;
+ AHCI_COMMAND_PRDT *PrdtTable = &(Commandtable->PrdtTable);
+
+ for (;ByteCount; (UINT8 *)PrdtTable += sizeof(AHCI_COMMAND_PRDT)){
+ PrdtTable->Ahci_Prdt_DBA = (UINT32)(UINTN)CommandStructure.Buffer;
+ PrdtTable->Ahci_Prdt_DBAU = (UINT32)Shr64((UINTN)CommandStructure.Buffer, 32);
+ PrdtTable->Ahci_Prdt_DBC = ByteCount >= PRD_MAX_DATA_COUNT ? (PRD_MAX_DATA_COUNT - 1) : (ByteCount - 1);
+ ByteCount -= (PrdtTable->Ahci_Prdt_DBC + 1);
+ PrdtTable->Ahci_Prdt_I = 0;
+ Prdtlength+= sizeof(AHCI_COMMAND_PRDT);
+ if ((UINT32)(Prdtlength + 0x80) >= AhciBusInterface->PortCommandTableLength) {
+ //ASSERT_EFI_ERROR(EFI_OUT_OF_RESOURCES);
+ break;
+ }
+ (UINT8 *)CommandStructure.Buffer += PrdtTable->Ahci_Prdt_DBC + 1;
+ }
+ // Set I flag only for the last entry.
+ (UINT8 *)PrdtTable -= sizeof(AHCI_COMMAND_PRDT);
+ PrdtTable->Ahci_Prdt_I = 1;
+ CommandList->Ahci_Cmd_PRDTL = Prdtlength / sizeof(AHCI_COMMAND_PRDT);
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StartController
+//
+// Description:
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT32 CIBitMask
+//
+// Output:
+// EFI_STATUS
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Clear Status register
+// 2. Enable FIS and CR running bit
+// 3. Enable Start bit
+// 4. Update CI bit mask
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+StartController (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT32 CIBitMask
+)
+{
+
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ UINT8 Port = SataDevInterface->PortNumber;
+
+ // Clear Status
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ // Enable FIS Receive
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE);
+
+ // Wait till FIS is running
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ // Clear FIS Receive area
+ ZeroMemory ((VOID *)(UINTN)SataDevInterface->PortFISBaseAddr, RECEIVED_FIS_SIZE);
+
+ // Enable ST
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_ST);
+
+ // Enable Command Issued
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CI, CIBitMask);
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitforCommandComplete
+//
+// Description: Wait till cmd completes
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_TYPE CommandType,
+// IN UINTN TimeOut
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check for SError bits. If set return error.
+// 2. For PIO IN/Out and Packet IN/OUT command wait till PIO Setup FIS is received
+// 3. If D2H register FIS is received, exit the loop.
+// 4. Check for SError and TFD bits.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitforCommandComplete (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN COMMAND_TYPE CommandType,
+ IN UINTN TimeOut
+)
+{
+
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)AhciBusInterface->AhciBaseAddress;
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT32 Data32_SERR, Data32_IS, i;
+ BOOLEAN PxSERR_ERROR = FALSE, PIO_SETUP_FIS = FALSE;
+ volatile AHCI_RECEIVED_FIS *FISReceiveAddress = (AHCI_RECEIVED_FIS *)(UINTN)SataDevInterface->PortFISBaseAddr;
+ UINTN TimeOutCount = TimeOut;
+
+ i=0;
+ do {
+ pBS->Stall(500);
+
+ // Check for Error bits
+ Data32_SERR = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SERR);
+ if (Data32_SERR & HBA_PORTS_ERR_CHK) {
+ PxSERR_ERROR = TRUE;
+ break;
+ }
+
+ // Check for Error bits
+ Data32_IS = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_IS);
+ if (Data32_IS & HBA_PORTS_IS_ERR_CHK) {
+ PxSERR_ERROR = TRUE;
+ break;
+ }
+
+ switch (CommandType) {
+
+ case PIO_DATA_IN_CMD:
+ case PIO_DATA_OUT_CMD:
+ case PACKET_PIO_DATA_IN_CMD:
+ case PACKET_PIO_DATA_OUT_CMD:
+ // check if PIO setup received
+ if(FISReceiveAddress->Ahci_Psfis[0] == FIS_PIO_SETUP) {
+ FISReceiveAddress->Ahci_Psfis[0] = 0;
+ TimeOutCount = TimeOut;
+ PIO_SETUP_FIS = TRUE;
+ }
+ break;
+ default:
+ break;
+
+ }
+
+ // check if D2H register FIS is received
+ if(FISReceiveAddress->Ahci_Rfis[0] == FIS_REGISTER_D2H) break;
+
+ // For PIO Data in D2H register FIS is not received. So rely on BSY bit
+ if ((CommandType == PIO_DATA_IN_CMD) && PIO_SETUP_FIS &&
+ !((HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD) &
+ (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_DRQ)))){
+ break;
+ }
+ //If the Timeout is 0, Then there is no timeout for command processing
+ if(TimeOut==0) {
+ continue;
+ }
+ i++;
+ } while(i < TimeOutCount * 2);
+
+ if (PxSERR_ERROR) {
+ // clear the status and return error
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+ return EFI_DEVICE_ERROR;
+ }
+
+ // check if CI register is zero
+ if (HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_CI)){
+ return EFI_DEVICE_ERROR;
+ }
+
+ // check for status bits
+ if (HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD) & (HBA_PORTS_TFD_ERR | HBA_PORTS_TFD_DRQ)){
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StopController
+//
+// Description: Stop FIS and CR
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: GeneratePortReset
+//
+// Notes:
+// 1. clear ST bit and wait till CR bits gets reset
+// 2. if not generate Port reset
+// 3. Clear FIS running bit.
+// 4. Clear status register
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+StopController(
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN BOOLEAN StartOrStop
+)
+{
+
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ EFI_STATUS Status;
+ UINT32 PortFISBaseAddr = SataDevInterface->PortFISBaseAddr;
+ UINT32 CommandListBaseAddress = SataDevInterface->PortCommandListBaseAddr;
+ UINT32 Data32;
+
+ if(StartOrStop && (HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB) != CommandListBaseAddress)) {
+ gCommandListBaseAddress=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB);
+ gFisBaseAddress=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_FB);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB,CommandListBaseAddress);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,PortFISBaseAddr);
+
+ //
+ // Saving the Upper 32 bits of FIS and Command List Registers
+ //
+ gCommandListBaseAddress2=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU);
+ gFisBaseAddress2=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU,0);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU,0);
+ }
+
+ // Clear Start
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~(HBA_PORTS_CMD_ST));
+ // Make sure CR is 0 with in 500msec
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_CR_CLEAR_TIMEOUT);
+
+ if (EFI_ERROR(Status)) {
+
+ // Get the Port Speed allowed and Interface Power Management Transitions Allowed
+ // Pass the values for PortReset.
+ Data32 = HBA_PORT_REG32 ((UINT32)(AhciBusInterface->AhciBaseAddress), Port, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+
+ Status = GeneratePortReset(AhciBusInterface, SataDevInterface, Port, PMPort,
+ (UINT8)((Data32 & 0xF0) >> 4), (UINT8)(Data32 >> 8));
+ };
+
+ if (EFI_ERROR(Status)) {
+ goto StopController_ErrorExit;
+ }
+
+ // Clear FIS receive enable.
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port,
+ HBA_PORTS_CMD, ~(HBA_PORTS_CMD_FRE));
+ // Make sure FR is 0 with in 500msec
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+
+StopController_ErrorExit:
+
+ // Clear Status register
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ if(!StartOrStop && gCommandListBaseAddress) {
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB,gCommandListBaseAddress);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,gFisBaseAddress);
+ //
+ // Restoring the Upper 32 bits of FIS and Command List Registers
+ //
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU,gCommandListBaseAddress2);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU,gFisBaseAddress2);
+
+ gCommandListBaseAddress = 0;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadytoAcceptCmd
+//
+// Description: Check if the device is ready to accept cmd.
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: GeneratePortReset, ReadWritePMPort
+//
+// Notes:
+// 1. Check the device is ready to accept the command. BSY and DRQ should be de-asserted.
+// 2. If set, generate Port reset
+// 3. In case Port Multiplier is connected to the port, enable all the ports of the Port Multiplier.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadytoAcceptCmd (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+ SATA_DEVICE_INTERFACE *SataPMDevInterface, *SataPMPortDevInterface;
+ UINT32 Data32 = 0, Init_SStatus = 0;
+ UINT8 PowerManagement, Speed;
+
+ // Is the Device ready to accept the command
+ if (HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD) & (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_DRQ)){
+ Data32 = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+ // make sure the status we read is for the right port
+ Status = GeneratePortReset(AhciBusInterface, SataDevInterface, Port, 0xFF,
+ (UINT8)((Data32 & 0xF0) >> 4), (UINT8)(Data32 >> 8));
+ if (EFI_ERROR(Status)) return Status;
+
+ // If it is a PMPort, Make sure all the Ports are in enabled state.
+ SataPMDevInterface = GetSataDevInterface(AhciBusInterface, Port, 0xFF);
+ if (!SataPMDevInterface) {
+ return EFI_DEVICE_ERROR;
+ }
+ if (SataPMDevInterface->DeviceType == PMPORT) {
+ for (PMPort = 0; PMPort < SataPMDevInterface->NumPMPorts; PMPort++){
+ SataPMPortDevInterface = GetSataDevInterface(AhciBusInterface, Port, PMPort);
+ if (!SataPMPortDevInterface) continue;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_0_SSTATUS, &Init_SStatus, FALSE);
+ if ((Init_SStatus & HBA_PORTS_SSTS_DET_MASK) == HBA_PORTS_SSTS_DET_PCE) {
+ Data32 = SataPMPortDevInterface->SControl;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_2_SCONTROL, &Data32, TRUE);
+ }
+ else {
+ Speed = (UINT8)((SataDevInterface->SControl >> 4) & 0xF);
+ PowerManagement = (UINT8)((SataDevInterface->SControl >> 8) & 0xF);
+ GeneratePortReset(AhciBusInterface, SataDevInterface, Port, PMPort,
+ Speed, PowerManagement);
+ }
+ Data32 = HBA_PORTS_ERR_CLEAR;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_1_SERROR, &Data32, TRUE);
+ }
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HostReset
+//
+// Description:
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+//
+// Output:
+//
+// Modified:
+//
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+HostReset (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface
+)
+{
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GeneratePortReset
+//
+// Description: Issue a Port Reset
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 CurrentPort,
+// IN UINT8 Speed,
+// IN UINT8 PowerManagement
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadWritePMPort, HandlePortComReset
+//
+// Notes:
+// 1. Issue port reset by setting DET bit in SControl register
+// 2. Call HandlePortComReset to check the status of the reset.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GeneratePortReset (
+ AHCI_BUS_PROTOCOL *AhciBusInterface,
+ SATA_DEVICE_INTERFACE *SataDevInterface,
+ UINT8 Port,
+ UINT8 PMPort,
+ UINT8 Speed,
+ UINT8 PowerManagement
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 AhciBaseAddr = (UINT32) AhciBusInterface->AhciBaseAddress;
+ volatile AHCI_RECEIVED_FIS *FISAddress = (AHCI_RECEIVED_FIS *)HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_FB);
+ UINT32 Data32;
+
+ TRACE_AHCI_LEVEL2((-1,"AHCI: PortReset on Port : %x PMPort : %x", Port, PMPort));
+
+ if (!FISAddress) return EFI_DEVICE_ERROR; // FIS receive address is not programmed.
+
+ if (gPortReset) return EFI_SUCCESS;
+ gPortReset = TRUE;
+
+ // Disable Start bit
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~HBA_PORTS_CMD_ST);
+
+ // Wait till CR is cleared
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_CR_CLEAR_TIMEOUT);
+
+ // Clear Status register
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ if (PMPort != 0xFF) {
+ Data32 = HBA_PORTS_ERR_CLEAR;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_1_SERROR, &Data32, TRUE);
+ }
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ // Enable FIS Receive Enable
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE);
+
+ // Wait till FIS is running and then clear the data area
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+
+ FISAddress->Ahci_Rfis[0] = 0;
+
+ if (PMPort == 0xFF) {
+ // Issue Port COMRESET
+ HBA_PORT_REG32_AND_OR (AhciBaseAddr, Port, HBA_PORTS_SCTL, 0xFFFFF000,
+ HBA_PORTS_SCTL_DET_INIT + (Speed << 4) + (PowerManagement << 8));
+ pBS->Stall (1000); // 1msec
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_SCTL, ~HBA_PORTS_SCTL_DET_MASK);
+ }
+ else {
+ Data32 = HBA_PORTS_SCTL_DET_INIT + (Speed << 4) + (PowerManagement << 8);
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_2_SCONTROL, &Data32, TRUE);
+ pBS->Stall (1000); // 1msec
+ Data32 = (Speed << 4) + (PowerManagement << 8);
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_2_SCONTROL, &Data32, TRUE);
+ }
+
+ Status = HandlePortComReset(AhciBusInterface, SataDevInterface, Port, PMPort);
+
+ // Disable FIS Receive Enable
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~HBA_PORTS_CMD_FRE);
+
+ SataDevInterface->SControl = (Speed << 4) + (PowerManagement << 8);
+
+ gPortReset = FALSE;
+
+ if (EFI_ERROR(Status)) {
+ TRACE_AHCI_LEVEL2((-1," Status : %r\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+
+ TRACE_AHCI_LEVEL2((-1," Status : %r\n", Status));
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GenerateSoftReset
+//
+// Description: Generate Soft Reset
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// In UINT8 PMPort
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, StartController
+//
+// Notes:
+// 1. Issue a Control register update, H2D register FIS with reset bit set.
+// 2. Wait for 100usec
+// 3. Issue a Control register update, H2D register FIS with reset bit reset.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GenerateSoftReset (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 PMPort
+
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface = SataDevInterface->AhciBusInterface;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *)(UINTN) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)(UINTN)AhciBusInterface->PortCommandTableBaseAddr;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT32 Data32;
+ UINT8 Port = SataDevInterface->PortNumber;
+
+ TRACE_AHCI_LEVEL2((-1,"AHCI: SoftReset on Port : %x PMPort : %x", Port, PMPort));
+
+ PROGRESS_CODE(DXE_IDE_RESET);
+
+ if (gSoftReset) return EFI_SUCCESS;
+
+ gSoftReset = TRUE;
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ Status = StopController(AhciBusInterface, SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) {
+ goto GenerateSoftReset_Exit;
+ }
+
+
+ // if Command list Override is supported, set CLO bit
+ Data32 = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD) & (HBA_PORTS_TFD_DRQ | HBA_PORTS_TFD_BSY);
+ if ((AhciBusInterface->HBACapability & HBA_CAP_SCLO) && Data32){
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_CLO);
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CLO,
+ BUSY_CLEAR_TIMEOUT);
+ }
+
+ CommandStructure.Control = 4;
+ BuildCommandList(SataDevInterface, CommandList, (UINT32)(UINTN)Commandtable);
+ BuildCommandFIS(SataDevInterface, CommandStructure, CommandList, Commandtable);
+
+ CommandList->Ahci_Cmd_W = 0;
+ // Update of Control Register
+ Commandtable->CFis.Ahci_CFis_C = 0;
+ CommandList->Ahci_Cmd_R = 1;
+ CommandList->Ahci_Cmd_C= 1;
+
+ if (PMPort != 0xFF) Commandtable->CFis.AHci_CFis_PmPort = PMPort;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+ // Wait till command is processed
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CI,
+ BIT00,
+ ONE_MILLISECOND * 5);
+
+ // Is the command complete?
+ if (EFI_ERROR(Status)){
+ goto GenerateSoftReset_Exit;
+ }
+ pBS->Stall (100); // 100 usec
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ BuildCommandList(SataDevInterface, CommandList, (UINT32)(UINTN)Commandtable);
+ BuildCommandFIS(SataDevInterface, CommandStructure, CommandList, Commandtable);
+
+ CommandList->Ahci_Cmd_W = 0;
+ // Update of Control Register
+ Commandtable->CFis.Ahci_CFis_C = 0;
+ if (PMPort != 0xFF) Commandtable->CFis.AHci_CFis_PmPort = PMPort;
+
+ StartController(AhciBusInterface, SataDevInterface, BIT00);
+ Status = WaitforCommandComplete(SataDevInterface, NON_DATA_CMD, ATAPI_BUSY_CLEAR_TIMEOUT);
+
+ // Stop Controller
+ StopController(AhciBusInterface, SataDevInterface,FALSE);
+
+GenerateSoftReset_Exit:
+
+ gSoftReset = FALSE;
+ TRACE_AHCI_LEVEL2((-1," Status : %r\n", Status));
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HandlePortComReset
+//
+// Description: Check if COM Reset is successful or not
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadSCRRegister, WriteSCRRegister
+//
+// Notes:
+// 1. Check if Link is active. If not return error.
+// 2. If Link is present, wait for PhyRdy Change bit to be set.
+// 3. Clear SError register
+// 4. Wait for D2H register FIS
+// 5. Check the Status register for errors.
+// 6. If COMRESET is success wait for sometime if the device is ATAPI or GEN1
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+HandlePortComReset(
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ BOOLEAN DeviceDetected = FALSE;
+ UINT32 Data32, i, SStatusData;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+ volatile AHCI_RECEIVED_FIS *FISAddress;
+ UINT32 SError = 0;
+ // Check if detection is complete
+ for (i = 0; i < HBA_PRESENCE_DETECT_TIMEOUT; i++){ // Total delay 10msec
+ SStatusData = ReadSCRRegister (AhciBusInterface, SataDevInterface, Port, PMPort, 0); // SStatus
+ SStatusData &= HBA_PORTS_SSTS_DET_MASK;
+ if ((SStatusData == HBA_PORTS_SSTS_DET_PCE) || (SStatusData == HBA_PORTS_SSTS_DET)) {
+ DeviceDetected = TRUE;
+ break;
+ }
+ pBS->Stall (1000); // 1msec
+ }
+
+ if (DeviceDetected) {
+ // Wait till PhyRdy Change bit is set
+ if (PMPort == 0xFF) {
+ Status = WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_SERR,
+ HBA_PORTS_SERR_EX,
+ HBA_PORTS_SERR_EX,
+ ATAPI_BUSY_CLEAR_TIMEOUT);
+ }
+ else {
+ Status = WaitforPMMemSet (SataDevInterface, PMPort, PSCR_1_SERROR,
+ HBA_PORTS_SERR_EX, HBA_PORTS_SERR_EX, ATAPI_BUSY_CLEAR_TIMEOUT);
+ }
+
+ FISAddress = (AHCI_RECEIVED_FIS *)HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_FB);
+
+ for (i = 0; i < ATAPI_BUSY_CLEAR_TIMEOUT; ) {
+ SError = ReadSCRRegister (AhciBusInterface, SataDevInterface, Port, PMPort, 2); // SError
+ if (SError & HBA_PORTS_ERR_CHK) {
+ WriteSCRRegister (AhciBusInterface, SataDevInterface, Port, PMPort, 1, HBA_PORTS_ERR_CLEAR ); //SError
+ }
+ if(FISAddress->Ahci_Rfis[0] == FIS_REGISTER_D2H) {break;}
+ pBS->Stall (1000); // 1msec Strange. Delay is needed for read to succeed.
+ if (PMPort != 0xFF) {i+= 100;} // For device behind PM Port, there is a delay in writing to the register. So count can be decreased.
+ else { i++; }
+ }
+
+ // Wait till PxTFD gets updated from D2H FIS
+ for (i = 0; i < 100; i++){ // Total delay 10msec
+ WriteSCRRegister (AhciBusInterface, SataDevInterface, Port, PMPort, 1, HBA_PORTS_ERR_CLEAR); //SError
+ if((FISAddress->Ahci_Rfis[2] & HBA_PORTS_TFD_MASK) == (HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD) & HBA_PORTS_TFD_MASK)) break;
+ pBS->Stall (100); // 100usec
+ }
+
+ // check for errors
+ if (FISAddress->Ahci_Rfis[2] & (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_ERR)) Status = EFI_DEVICE_ERROR;
+
+ Data32 = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_IS);
+ if (Data32 & (BIT30 + BIT29 + BIT28 + BIT27 + BIT26)) Status = EFI_DEVICE_ERROR;
+
+ // Clear the status
+ WriteSCRRegister (AhciBusInterface, SataDevInterface, Port, PMPort, 1, HBA_PORTS_ERR_CLEAR); //SError
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ }
+ else {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadSCRRegister
+//
+// Description:
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+// IN UINT8 Register (0 : SStatus 1: SError 2: SControl)
+//
+// Output:
+// UINT32
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check if the device is connected directly to the port
+// 2. if yes, read to the AHCI Controller else write to the Port Multiplier register.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+ReadSCRRegister (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort,
+ IN UINT8 Register
+)
+{
+
+ UINT32 Data32 = 0;
+ UINT32 Reg = HBA_PORTS_SSTS;
+
+ if (PMPort != 0xFF) {
+ ReadWritePMPort (SataDevInterface, PMPort, Register, &Data32, FALSE);
+ }
+ else {
+ if (Register == 1) Reg = HBA_PORTS_SCTL;
+ if (Register == 2) Reg = HBA_PORTS_SERR;
+ Data32 = HBA_PORT_REG32 (AhciBusInterface->AhciBaseAddress, Port, Reg);
+ }
+
+ return Data32;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteSCRRegister
+//
+// Description: Write to SCONTROL/Serror/SStatus register
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+// IN UINT8 Register, (0 : SStatus 1: SError 2: SControl)
+// IN UINT32 Data32
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check if the device is connected directly to the port
+// 2. if yes, write to the AHCI Controller else write to the Port Multiplier register
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WriteSCRRegister (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort,
+ IN UINT8 Register,
+ IN UINT32 Data32
+)
+{
+
+ UINT32 Reg = HBA_PORTS_SSTS;
+
+ if (PMPort != 0xFF) {
+ ReadWritePMPort (SataDevInterface, PMPort, Register, &Data32, TRUE);
+ }
+ else {
+ if (Register == 2) Reg = HBA_PORTS_SCTL;
+ if (Register == 1) Reg = HBA_PORTS_SERR;
+ HBA_PORT_REG32_OR (AhciBusInterface->AhciBaseAddress, Port, Reg, Data32);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitforPMMemSet
+//
+// Description: Wait for memory to be set to the test value.
+//
+// Input:
+// SATA_DEVICE_INTERFACE *SataDevInterface,
+// PMPort
+// Register
+// MaskValue - The mask value of memory
+// TestValue - The test value of memory
+// WaitTimeInMs - The time out value for wait memory set
+//
+// Output: EFI_SUCCESS - HBA reset successfully.
+// EFI_DEVICE_ERROR - HBA failed to complete hardware reset.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitforPMMemSet (
+ IN SATA_DEVICE_INTERFACE *SataDevInterface,
+ IN UINT8 PMPort,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 TestValue,
+ IN UINT32 WaitTimeInMs
+)
+{
+ UINT32 Data32;
+
+ while(WaitTimeInMs!=0){
+ ReadWritePMPort (SataDevInterface, PMPort, Register, &Data32, FALSE);
+ if((Data32 & AndMask) == TestValue) {return EFI_SUCCESS;}
+ pBS->Stall (1000); // 1Msec
+ WaitTimeInMs--;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckValidDevice
+//
+// Description: Check for valid ATA/ATAPI/PMPORT signature
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check if Link is active
+// 2. Enable FIS and Command list run bits
+// 3. Check for valid signature
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckValidDevice (
+ IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ UINT8 Data8;
+ UINT32 Data32;
+ UINT32 AhciBaseAddr = (UINT32)(AhciBusInterface->AhciBaseAddress);
+
+ // Check if Link is active
+ Data8 = (UINT8)(HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SSTS) & HBA_PORTS_SSTS_DET_MASK);
+ if (Data8 != HBA_PORTS_SSTS_DET_PCE) return EFI_DEVICE_ERROR;
+
+ // Enable FIS receive and CI so that TFD gets updated properly
+ // Clear out the command slot
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CI, 0);
+
+ // Enable FIS Receive
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE | HBA_PORTS_CMD_ST);
+
+ // Wait till FIS is running
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ // Wait till CR list is running
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_PORTS_CMD_CR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ // Clear Start Bit
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~(HBA_PORTS_CMD_ST));
+ WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_CR_CLEAR_TIMEOUT);
+
+ //Clear FIS Receive enable bit
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~(HBA_PORTS_CMD_FRE));
+ WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+
+ // Check if valid signature is present
+ Data32 = HBA_PORT_REG32(AhciBaseAddr, Port, HBA_PORTS_SIG);
+ if (Data32 != ATA_SIGNATURE_32 && Data32 != ATAPI_SIGNATURE_32 && Data32 != PMPORT_SIGNATURE)
+ return EFI_DEVICE_ERROR;
+
+ Data8 = HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD);
+ if (Data8 & (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_DRQ)) return EFI_DEVICE_ERROR;
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Ahci/AhciController.h b/Core/EM/Ahci/AhciController.h
new file mode 100644
index 0000000..9ec5e75
--- /dev/null
+++ b/Core/EM/Ahci/AhciController.h
@@ -0,0 +1,633 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciController.h 9 11/13/13 1:52a Divyac $
+//
+// $Revision: 9 $
+//
+// $Date: 11/13/13 1:52a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciController.h $
+//
+// 9 11/13/13 1:52a Divyac
+// [TAG] EIP143018
+// [Category] Improvement
+// [Description] Removed the EIP 128912 changes and checked-in again.
+// EIP 128912 changes creates lot more side effect, so we planed to remove
+// the changes.
+// [Files] AhciController.h
+//
+// 8 7/23/13 11:56p Srikantakumarp
+// [TAG] EIP129989
+// [Category] Improvement
+// [Description] Added DIPM support in Aptio 4.x AHCIBUS driver.
+// [Files] AhciBus.c, AhciBus.h, AhciController.h, AhciSrc.sdl,
+// PAhciBus.h
+//
+// 7 7/18/13 7:35a Rameshr
+// [TAG] EIP128912
+// [Category] Improvement
+// [Description] 10b to 8b decode error is mentioned as Diagnostic error
+// for use by Diagnostic software, So removed this error status checking
+// [Files] AhciController.h
+//
+// 6 7/17/13 10:40a Rameshr
+// [TAG] EIP128912
+// [Category] Improvement
+// [Description] 10b to 8b decode error is mentioned as Diagnostic error
+// for use by Diagnostic software, So removed this error status checking.
+// [Files] AhciController.h
+//
+// 5 2/10/11 10:35a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSrc.mak
+// AhciBus.c
+// AhciController.c
+// AhciComponentName.c
+// AhciBus.h
+// AhciController.h
+//
+// 4 5/07/10 11:45a Krishnakumarg
+// Coding standard update
+//
+// 3 7/09/09 4:50p Fasihm
+// Fixed the Read/Write failure when ALPE is Enabled.
+//
+// 2 5/28/08 9:39a Rameshraju
+// Based on the SDL token index/data or MMIO method used to access the
+// AHCI configuration space.
+//
+// 1 28/02/08 6:03p Anandakrishnanl
+// AHCI Bus Driver initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AhciController.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+// Forward reference for pure ANSI compatability
+typedef struct _AHCI_COMMAND_FIS AHCI_COMMAND_FIS;
+typedef struct _AHCI_ATAPI_COMMAND AHCI_ATAPI_COMMAND;
+typedef struct _AHCI_COMMAND_PRDT AHCI_COMMAND_PRDT;
+
+#pragma pack(1)
+
+// Command List Structure
+typedef struct {
+ UINT32 Ahci_Cmd_CFL:5;
+ UINT32 Ahci_Cmd_A:1;
+ UINT32 Ahci_Cmd_W:1;
+ UINT32 Ahci_Cmd_P:1;
+ UINT32 Ahci_Cmd_R:1;
+ UINT32 Ahci_Cmd_B:1;
+ UINT32 Ahci_Cmd_C:1;
+ UINT32 Ahci_Cmd_Rsvd1:1;
+ UINT32 Ahci_Cmd_PMP:4;
+ UINT32 Ahci_Cmd_PRDTL:16;
+ UINT32 Ahci_Cmd_PRDBC;
+ UINT32 Ahci_Cmd_CTBA;
+ UINT32 Ahci_Cmd_CTBAU;
+ UINT32 Ahci_Cmd_Rsvd2[4];
+} AHCI_COMMAND_LIST;
+
+typedef struct {
+ UINT8 Ahci_Dsfis[0x1C]; // DMA Setup Fis
+ UINT8 Ahci_Dsfis_Rsvd[0x04];
+ UINT8 Ahci_Psfis[0x14]; // PIO Setip Fis
+ UINT8 Ahci_Psfis_Rsvd[0x0C];
+ UINT8 Ahci_Rfis[0x14]; // D2H Register Fis
+ UINT8 Ahci_Rfis_Rsvd[0x04];
+ UINT64 Ahci_Sdbfis; // Set Device Bits Fis
+ UINT8 Ahci_Ufis[0x40]; // Unkonw FIS
+ UINT8 Ahci_Ufis_Rsvd[0x60];
+} AHCI_RECEIVED_FIS;
+
+// Register - Host to Device FIS Layout
+typedef struct _AHCI_COMMAND_FIS{
+ UINT8 Ahci_CFis_Type;
+ UINT8 AHci_CFis_PmPort:4;
+ UINT8 Ahci_CFis_Rsvd1:1;
+ UINT8 Ahci_CFis_Rsvd2:1;
+ UINT8 Ahci_CFis_Rsvd3:1;
+ UINT8 Ahci_CFis_C:1;
+ UINT8 Ahci_CFis_Cmd;
+ UINT8 Ahci_CFis_Features;
+ UINT8 Ahci_CFis_SecNum;
+ UINT8 Ahci_CFis_ClyLow;
+ UINT8 Ahci_CFis_ClyHigh;
+ UINT8 Ahci_CFis_DevHead;
+ UINT8 Ahci_CFis_SecNumExp;
+ UINT8 Ahci_CFis_ClyLowExp;
+ UINT8 Ahci_CFis_ClyHighExp;
+ UINT8 Ahci_CFis_FeaturesExp;
+ UINT8 Ahci_CFis_SecCount;
+ UINT8 Ahci_CFis_SecCountExp;
+ UINT8 Ahci_CFis_Rsvd4;
+ UINT8 Ahci_CFis_Control;
+ UINT8 Ahci_CFis_Rsvd5[4];
+ UINT8 Ahci_CFis_Rsvd6[44];
+} AHCI_COMMAND_FIS;
+
+// Physical Region Descriptor Table
+typedef struct _AHCI_COMMAND_PRDT{
+ UINT32 Ahci_Prdt_DBA;
+ UINT32 Ahci_Prdt_DBAU;
+ UINT32 Ahci_Prdt_Rsvd;
+ UINT32 Ahci_Prdt_DBC:22;
+ UINT32 Ahci_Prdt_Rsvd1:9;
+ UINT32 Ahci_Prdt_I:1;
+} AHCI_COMMAND_PRDT;
+
+// Command table
+
+typedef struct _AHCI_COMMAND_TABLE{
+ AHCI_COMMAND_FIS CFis;
+ AHCI_ATAPI_COMMAND AtapiCmd;
+ UINT8 Rsvd[0x30];
+ AHCI_COMMAND_PRDT PrdtTable;
+} AHCI_COMMAND_TABLE;
+
+typedef struct _AHCI_COMMAND_TABLE_NO_PRDT{
+ AHCI_COMMAND_FIS CFis;
+ AHCI_ATAPI_COMMAND AtapiCmd;
+ UINT8 Rsvd[0x30];
+} AHCI_COMMAND_TABLE_NO_PRDT;
+
+#pragma pack()
+
+#define ATA_SIGNATURE_32 0x00000101
+#define ATAPI_SIGNATURE_32 0xEB140101
+#define PMPORT_SIGNATURE 0x96690101
+#define PRD_MAX_DATA_COUNT 0x400000
+
+
+
+#define PCI_ABAR 0x24
+#define RECEIVED_FIS_SIZE 0x100
+
+#define CONTROL_PORT 0x0F
+
+//Generic Host Control Registers
+#define HBA_CAP 0x0000
+#define HBA_CAP_NP_MASK 0x1F
+#define HBA_CAP_EMS BIT06
+#define HBA_CAP_PSC BIT13
+#define HBA_CAP_SSC BIT14
+#define HBA_CAP_PMD BIT15
+#define HBA_CAP_FBSS BIT16
+#define HBA_CAP_SPM BIT17
+#define HBA_CAP_SAM BIT18
+#define HBA_CAP_SNZO BIT19
+#define HBA_CAP_ISS_MASK (BIT20 | BIT21 | BIT22 | BIT23)
+#define HBA_CAP_SCLO BIT24
+#define HBA_CAP_SAL BIT25
+#define HBA_CAP_SALP BIT26
+#define HBA_CAP_SSS BIT27
+#define HBA_CAP_SMPS bit28
+#define HBA_CAP_SSNTF BIT29
+#define HBA_CAP_SCQA BIT30
+#define HBA_CAP_S64A BIT31
+
+#define HBA_GHC 0x0004
+#define HBA_GHC_RESET 0x0001
+#define HBA_GHC_IE 0x0002
+#define HBA_GHC_AE 0x80000000
+#define HBA_GHC_AE_RESET 0x80000001
+#define HBA_IS 0x0008
+#define HBA_PI 0x000C
+#define HBA_VS 0x0010
+#define HBA_CCC_CTL 0x0014
+#define HBA_CCC_PORTS 0x0018
+#define HBA_EM_LOC 0x001C
+#define HBA_EM_CTL 0x0020
+#define HBA_CAP2 0x0024
+#define HBA_CAP2_APST 0x0004
+#define HBA_CAP2_SDS 0x0008
+#define HBA_CAP2_SADM 0x0010
+#define HBA_CAP2_DESO 0x0020
+
+//Port Registers
+#define HBA_PORTS_START 0x0100
+#define HBA_PORTS_REG_WIDTH 0x0080
+#define HBA_PORTS_CLB 0x0000
+#define HBA_PORTS_CLBU 0x0004
+#define HBA_PORTS_FB 0x0008
+#define HBA_PORTS_FBU 0x000C
+#define HBA_PORTS_IS 0x0010
+#define HBA_PORTS_IS_DHRS BIT00
+#define HBA_PORTS_IS_PSS BIT01
+#define HBA_PORTS_IS_SSS BIT02
+#define HBA_PORTS_IS_SDBS BIT03
+#define HBA_PORTS_IS_UFS BIT04
+#define HBA_PORTS_IS_DPS BIT05
+#define HBA_PORTS_IS_PCS BIT06
+#define HBA_PORTS_IS_DIS BIT07
+#define HBA_PORTS_IS_PRCS BIT22
+#define HBA_PORTS_IS_IPMS BIT23
+#define HBA_PORTS_IS_OFS BIT24
+#define HBA_PORTS_IS_INFS BIT26
+#define HBA_PORTS_IS_IFS BIT27
+#define HBA_PORTS_IS_HBDS BIT28
+#define HBA_PORTS_IS_HBFS BIT29
+#define HBA_PORTS_IS_TFES BIT30
+#define HBA_PORTS_IS_CPDS BIT31
+#define HBA_PORTS_IS_CLEAR 0xFFC000FF
+#define HBA_PORTS_IS_FIS_CLEAR 0x0000001F
+#define HBA_PORTS_IS_ERR_CHK BIT04 + BIT06 + BIT23 + BIT24 + BIT27 + \
+ BIT28 + BIT29 + BIT30 + BIT31
+
+#define HBA_PORTS_IE 0x0014
+#define HBA_PORTS_CMD 0x0018
+#define HBA_PORTS_CMD_ST_MASK 0xFFFFFFFE
+#define HBA_PORTS_CMD_ST BIT00
+#define HBA_PORTS_CMD_SUD BIT01
+#define HBA_PORTS_CMD_POD BIT02
+#define HBA_PORTS_CMD_CLO BIT03
+#define HBA_PORTS_CMD_CR BIT15
+#define HBA_PORTS_CMD_FRE BIT04
+#define HBA_PORTS_CMD_FR BIT14
+#define HBA_PORTS_CMD_MASK ~(HBA_PORTS_CMD_ST | HBA_PORTS_CMD_FRE | HBA_PORTS_CMD_CLO)
+#define HBA_PORTS_CMD_PMA BIT17
+#define HBA_PORTS_CMD_HPCP BIT18
+#define HBA_PORTS_CMD_MPSP BIT19
+#define HBA_PORTS_CMD_CPD BIT20
+#define HBA_PORTS_CMD_ESP BIT21
+#define HBA_PORTS_CMD_ATAPI BIT24
+#define HBA_PORTS_CMD_DLAE BIT25
+#define HBA_PORTS_CMD_ALPE BIT26
+#define HBA_PORTS_CMD_ASP BIT27
+#define HBA_PORTS_CMD_ICC_MASK (BIT28 | BIT29 | BIT30 | BIT31)
+#define HBA_PORTS_CMD_ACTIVE (1 << 28 )
+#define HBA_PORTS_TFD 0x0020
+#define HBA_PORTS_TFD_MASK (BIT07 | BIT03 | BIT00)
+#define HBA_PORTS_TFD_BSY BIT07
+#define HBA_PORTS_TFD_DRQ BIT03
+#define HBA_PORTS_TFD_ERR BIT00
+#define HBA_PORTS_TFD_ERR_MASK 0x00FF00 // BIT8 - BIT15
+#define HBA_PORTS_SIG 0x0024
+#define HBA_PORTS_SSTS 0x0028
+#define HBA_PORTS_SSTS_DET_MASK 0x000F
+#define HBA_PORTS_SSTS_DET 0x0001
+#define HBA_PORTS_SSTS_DET_PCE 0x0003
+#define HBA_PORTS_SSTS_SPD_MASK 0x00F0
+#define HBA_PORTS_SCTL 0x002C
+#define HBA_PORTS_SCTL_DET_MASK 0x000F
+#define HBA_PORTS_SCTL_MASK (~HBA_PORTS_SCTL_DET_MASK)
+#define HBA_PORTS_SCTL_DET_INIT 0x0001
+#define HBA_PORTS_SCTL_DET_PHYCOMM 0x0003
+#define HBA_PORTS_SCTL_SPD_MASK 0x00F0
+#define HBA_PORTS_SCTL_SPD_NSNR 0x0
+#define HBA_PORTS_SCTL_SPD_GEN1 0x1
+#define HBA_PORTS_SCTL_SPD_GEN2 0x2
+#define HBA_PORTS_SCTL_SPD_GEN3 0x3
+#define HBA_PORTS_SCTL_IPM_MASK 0x0F00
+#define HBA_PORTS_SCTL_IPM_DIS 0x00
+#define HBA_PORTS_SCTL_IPM_PSD 0x01
+#define HBA_PORTS_SCTL_IPM_SSD 0x02
+#define HBA_PORTS_SCTL_IPM_PSSD 0x03
+#define HBA_PORTS_SCTL_IPM_PSD_SSD 0x0300
+#define HBA_PORTS_SERR 0x0030
+#define HBA_PORTS_SERR_RDIE BIT00
+#define HBA_PORTS_SERR_RCE BIT01
+#define HBA_PORTS_SERR_TDIE BIT08
+#define HBA_PORTS_SERR_PCDIE BIT09
+#define HBA_PORTS_SERR_PE BIT10
+#define HBA_PORTS_SERR_IE BIT11
+#define HBA_PORTS_SERR_PRC BIT16
+#define HBA_PORTS_SERR_PIE BIT17
+#define HBA_PORTS_SERR_CW BIT18
+#define HBA_PORTS_SERR_BDE BIT19
+#define HBA_PORTS_SERR_DE BIT20 // Not used
+#define HBA_PORTS_SERR_CRCE BIT21
+#define HBA_PORTS_SERR_HE BIT22
+#define HBA_PORTS_SERR_LSE BIT23
+#define HBA_PORTS_SERR_TSTE BIT24
+#define HBA_PORTS_SERR_UFT BIT25
+#define HBA_PORTS_SERR_EX BIT26
+#define HBA_PORTS_PxSACT 0x0034
+#define HBA_PORTS_PxCI 0x0038
+#define HBA_PORTS_PxDEVSLP 0x0044
+#define HBA_PORTS_PxDEVSLP_ADSE BIT00
+#define HBA_PORTS_PxDEVSLP_DSP BIT01
+#define HBA_PORTS_PxDEVSLP_DETO_MASK (0x000003FC)
+#define HBA_PORTS_PxDEVSLP_DMDAT_MASK (0x00007C00)
+#define HBA_PORTS_PxDEVSLP_DITO_MASK (0x01FF8000)
+#define HBA_PORTS_PxDEVSLP_DM_MASK (0x1E000000)
+
+#define HBA_PORTS_ERR_CHK (HBA_PORTS_SERR_TDIE + HBA_PORTS_SERR_PCDIE +\
+ HBA_PORTS_SERR_PE + HBA_PORTS_SERR_IE + \
+ HBA_PORTS_SERR_PIE + \
+ HBA_PORTS_SERR_BDE + \
+ HBA_PORTS_SERR_DE + HBA_PORTS_SERR_CRCE + \
+ HBA_PORTS_SERR_HE + HBA_PORTS_SERR_LSE + \
+ HBA_PORTS_SERR_TSTE + HBA_PORTS_SERR_UFT + \
+ HBA_PORTS_SERR_EX)
+
+#define HBA_PORTS_ERR_CLEAR (HBA_PORTS_SERR_RDIE + HBA_PORTS_SERR_RCE +\
+ HBA_PORTS_SERR_TDIE + HBA_PORTS_SERR_PCDIE +\
+ HBA_PORTS_SERR_PE + HBA_PORTS_SERR_IE + \
+ HBA_PORTS_SERR_PRC + HBA_PORTS_SERR_PIE + \
+ HBA_PORTS_SERR_CW + HBA_PORTS_SERR_BDE + \
+ HBA_PORTS_SERR_DE + HBA_PORTS_SERR_CRCE + \
+ HBA_PORTS_SERR_HE + HBA_PORTS_SERR_LSE + \
+ HBA_PORTS_SERR_TSTE + HBA_PORTS_SERR_UFT + \
+ HBA_PORTS_SERR_EX)
+#define HBA_PORTS_SACT 0x0034
+#define HBA_PORTS_CI 0x0038
+#define HBA_PORTS_SNTF 0x003C
+
+//FIS Types
+#define D2H_FIS_OFFSET 0x40
+#define DMA_FIS_OFFSET 0x00
+#define PIO_FIS_OFFSET 0x20
+#define SDB_FIS_OFFSET 0x58
+#define FIS_TYPE_MASK 0xFF
+#define U_FIS_OFFSET 0x60
+
+#define FIS_REGISTER_H2D 0x27 // Host To Device
+#define FIS_REGISTER_H2D_LENGTH 20
+#define FIS_REGISTER_D2H 0x34 // Device To Host
+#define FIS_REGISTER_D2H_LENGTH 20 // Device To Host
+#define FIS_DMA_ACTIVATE 0x39 // Device To Host
+#define FIS_DMA_ACTIVATE_LENGTH 4
+#define FIS_DMA_SETUP 0x41 // Bi-directional
+#define FIS_DMA_SETUP_LENGTH 28
+#define FIS_DATA 0x46 // Bi-directional
+#define FIS_BIST 0x58 // Bi-directional
+#define FIS_BIST_LENGTH 12
+#define FIS_PIO_SETUP 0x5F // Device To Host
+#define FIS_PIO_SETUP_LENGTH 20
+#define FIS_SET_DEVICE 0xA1 // Device To Host
+#define FIS_SET_DEVICE_LENGTH 8
+
+
+#define READ_PORT_MULTIPLIER 0xE4
+#define WRITE_PORT_MULTIPLIER 0xE8
+
+#define GSCR_0 0x00
+#define GSCR_1 0x01
+#define GSCR_2 0x02
+#define GSCR_32 32
+#define GSCR_64 64
+#define GSCR_96 96
+
+#define PSCR_0_SSTATUS 0x00
+#define PSCR_1_SERROR 0x01
+#define PSCR_2_SCONTROL 0x02
+
+
+#define HBA_CR_CLEAR_TIMEOUT 500 // AHCI 1.2 spec 10.1.2
+#define HBA_FR_CLEAR_TIMEOUT 500 // AHCI 1.2 spec 10.1.2
+#define HBA_PRESENCE_DETECT_TIMEOUT 10 // 10msec Serial ATA 1.0 Sec 5.2
+
+#if INDEX_DATA_PORT_ACCESS
+
+ //
+ //Index , Data port access
+ //
+
+#define HBA_PORT_REG_BASE(Port) \
+ (UINTN) (Port * HBA_PORTS_REG_WIDTH + HBA_PORTS_START)
+
+#define HBA_REG32( BaseAddr, Register ) \
+ (ReadDataDword ((BaseAddr), (Register)))
+
+#define HBA_WRITE_REG32( BaseAddr, Register, Data ) \
+ (WriteDataDword( BaseAddr, Register, Data ))
+
+#define HBA_REG16( BaseAddr, Register ) \
+ (ReadDataWord( BaseAddr, Register ))
+
+#define HBA_WRITE_REG16( BaseAddr, Register, Data ) \
+ (WriteDataWord( BaseAddr, Register, Data ))
+
+#define HBA_REG8( BaseAddr, Register ) \
+ (ReadDataByte ((BaseAddr), (Register)))
+
+#define HBA_WRITE_REG8( BaseAddr, Register, Data ) \
+ (WriteDataByte( BaseAddr, Register, Data ))
+
+#define HBA_REG8_OR( BaseAddr, Register, OrData) \
+ HBA_WRITE_REG8(BaseAddr, Register, ((HBA_REG8 ((BaseAddr), (Register))) | ((UINT8) (OrData))))
+
+#define HBA_REG16_OR( BaseAddr, Register, OrData) \
+ HBA_WRITE_REG16(BaseAddr, Register, ((HBA_REG16 ((BaseAddr), (Register))) | ((UINT16) (OrData))))
+
+#define HBA_REG32_OR( BaseAddr, Register, OrData) \
+ HBA_WRITE_REG32(BaseAddr, Register, ((HBA_REG32 ((BaseAddr), (Register))) | ((UINT32) (OrData))))
+
+#define HBA_REG8_AND( BaseAddr, Register, AndData) \
+ HBA_WRITE_REG8(BaseAddr, Register, ((HBA_REG8 ((BaseAddr), (Register))) & ((UINT8) (AndData))))
+
+#define HBA_REG16_AND( BaseAddr, Register, AndData) \
+ HBA_WRITE_REG16(BaseAddr, Register, ((HBA_REG16 ((BaseAddr), (Register))) & ((UINT16) (AndData))))
+
+#define HBA_REG32_AND( BaseAddr, Register, AndData) \
+ HBA_WRITE_REG32(BaseAddr, Register, ((HBA_REG32 ((BaseAddr), (Register))) & ((UINT32) (AndData))))
+
+#define HBA_REG8_AND_OR( BaseAddr, Register, AndData, OrData) \
+ HBA_WRITE_REG8(BaseAddr, Register, ((HBA_REG8 ((BaseAddr), (Register))) & ((UINT8) (AndData)) | ((UINT8) (OrData))))
+
+#define HBA_REG16_AND_OR( BaseAddr, Register, AndData, OrData) \
+ HBA_WRITE_REG16(BaseAddr, Register, ((HBA_REG16 ((BaseAddr), (Register))) & ((UINT16) (AndData)) | ((UINT16) (OrData))))
+
+#define HBA_REG32_AND_OR( BaseAddr, Register,AndData, OrData) \
+ HBA_WRITE_REG32(BaseAddr, Register, ((HBA_REG32 ((BaseAddr), (Register))) & ((UINT32) (AndData)) | ((UINT32) (OrData))))
+
+//Ports
+#define HBA_PORT_REG8(BaseAddr, Port, Register) \
+ (HBA_REG8 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port))))
+
+#define HBA_PORT_REG16(BaseAddr, Port, Register) \
+ (HBA_REG16 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port))))
+
+#define HBA_PORT_REG32(BaseAddr, Port, Register) \
+ (HBA_REG32 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port))))
+
+#define HBA_PORT_WRITE_REG8(BaseAddr, Port, Register, Data) \
+ (HBA_WRITE_REG8 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), Data))
+
+#define HBA_PORT_WRITE_REG16(BaseAddr, Port, Register, Data) \
+ (HBA_WRITE_REG16 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)),Data))
+
+#define HBA_PORT_WRITE_REG32(BaseAddr, Port, Register,Data) \
+ (HBA_WRITE_REG32 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)),Data))
+
+#define HBA_PORT_REG8_OR(BaseAddr, Port, Register, OrData) \
+ (HBA_REG8_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (OrData)))
+
+#define HBA_PORT_REG16_OR(BaseAddr, Port, Register, OrData) \
+ (HBA_REG16_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (OrData)))
+
+#define HBA_PORT_REG32_OR(BaseAddr, Port, Register, OrData) \
+ (HBA_REG32_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (OrData)))
+
+#define HBA_PORT_REG8_AND(BaseAddr, Port, Register, AndData) \
+ (HBA_REG8_AND ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData)))
+
+#define HBA_PORT_REG16_AND(BaseAddr, Port, Register, AndData) \
+ (HBA_REG16_AND ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData)))
+
+#define HBA_PORT_REG32_AND(BaseAddr, Port, Register, AndData) \
+ (HBA_REG32_AND ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData)))
+
+#define HBA_PORT_REG8_AND_OR(BaseAddr, Port, Register, AndData, OrData) \
+ (HBA_REG8_AND_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData), (OrData)))
+
+#define HBA_PORT_REG16_AND_OR(BaseAddr, Port, Register, AndData, OrData) \
+ (HBA_REG16_AND_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData), (OrData)))
+
+#define HBA_PORT_REG32_AND_OR(BaseAddr, Port, Register, AndData, OrData) \
+ (HBA_REG32_AND_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData), (OrData)))
+
+#else
+ //
+ //MMIO Access
+ //
+#define MmAddress( BaseAddr, Register ) \
+ ((UINTN)(BaseAddr) + \
+ (UINTN)(Register) \
+ )
+#define Mm32Ptr( BaseAddr, Register ) \
+ ((volatile UINT32 *)MmAddress (BaseAddr, Register ))
+
+#define Mm16Ptr( BaseAddr, Register ) \
+ ((volatile UINT16 *)MmAddress (BaseAddr, Register ))
+
+#define Mm8Ptr( BaseAddr, Register ) \
+ ((volatile UINT8 *)MmAddress (BaseAddr, Register ))
+
+//HBA Generic
+#define HBA_PORT_REG_BASE(Port) \
+ (UINTN) (Port * HBA_PORTS_REG_WIDTH + HBA_PORTS_START)
+
+#define HBA_REG32( BaseAddr, Register ) \
+ (*Mm32Ptr ((BaseAddr), (Register)))
+
+#define HBA_REG16( BaseAddr, Register ) \
+ (*Mm16Ptr ((BaseAddr), (Register)))
+
+#define HBA_REG8( BaseAddr, Register ) \
+ (*Mm8Ptr ((BaseAddr), (Register)))
+
+#define HBA_WRITE_REG32( BaseAddr, Register, Data ) \
+ (HBA_REG32 ((BaseAddr), (Register))) = ((UINT32) (Data))
+
+#define HBA_WRITE_REG16( BaseAddr, Register, Data ) \
+ (HBA_REG16 ((BaseAddr), (Register))) = ((UINT16) (Data))
+
+#define HBA_WRITE_REG8( BaseAddr, Register, Data ) \
+ (HBA_REG8 ((BaseAddr), (Register))) = ((UINT8) (Data))
+
+#define HBA_REG8_OR( BaseAddr, Register, OrData) \
+ (HBA_REG8 ((BaseAddr), (Register))) |= ((UINT8) (OrData))
+
+#define HBA_REG16_OR( BaseAddr, Register, OrData) \
+ (HBA_REG16 ((BaseAddr), (Register))) |= ((UINT16) (OrData))
+
+#define HBA_REG32_OR( BaseAddr, Register, OrData) \
+ (HBA_REG32 ((BaseAddr), (Register))) = (HBA_REG32 ((BaseAddr), (Register))) | ((UINT32) (OrData))
+
+#define HBA_REG8_AND( BaseAddr, Register, AndData) \
+ (HBA_REG8 ((BaseAddr), (Register))) = (HBA_REG8 ((BaseAddr), (Register))) & ((UINT8) (AndData))
+
+#define HBA_REG16_AND( BaseAddr, Register, AndData) \
+ (HBA_REG16 ((BaseAddr), (Register))) &= ((UINT16) (AndData))
+
+#define HBA_REG32_AND( BaseAddr, Register, AndData) \
+ (HBA_REG32 ((BaseAddr), (Register))) = (HBA_REG32 ((BaseAddr), (Register))) & ((UINT32) (AndData))
+
+#define HBA_REG8_AND_OR( BaseAddr, Register, AndData, OrData) \
+ (HBA_REG8 ((BaseAddr), (Register)) = \
+ (((HBA_REG8 ((BaseAddr), (Register))) & ((UINT8) (AndData))) | ((UINT8) (OrData))))
+
+#define HBA_REG16_AND_OR( BaseAddr, Register, AndData, OrData) \
+ (HBA_REG16 ((BaseAddr), (Register)) = \
+ (((HBA_REG16 ((BaseAddr), (Register))) & ((UINT16) AndData)) | ((UINT16) (OrData))))
+
+#define HBA_REG32_AND_OR( BaseAddr, Register,AndData, OrData) \
+ (HBA_REG32 ((BaseAddr), (Register)) = \
+ (((HBA_REG32 ((BaseAddr), (Register))) & ((UINT32) (AndData))) | ((UINT32) (OrData))))
+
+//Ports
+#define HBA_PORT_REG8(BaseAddr, Port, Register) \
+ (HBA_REG8 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port))))
+
+#define HBA_PORT_REG16(BaseAddr, Port, Register) \
+ (HBA_REG16 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port))))
+
+#define HBA_PORT_REG32(BaseAddr, Port, Register) \
+ (HBA_REG32 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port))))
+
+#define HBA_PORT_WRITE_REG8(BaseAddr, Port, Register, Data) \
+ (HBA_WRITE_REG8 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), Data))
+
+#define HBA_PORT_WRITE_REG16(BaseAddr, Port, Register, Data) \
+ (HBA_WRITE_REG16 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)),Data))
+
+#define HBA_PORT_WRITE_REG32(BaseAddr, Port, Register,Data) \
+ (HBA_WRITE_REG32 ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)),Data))
+
+#define HBA_PORT_REG8_OR(BaseAddr, Port, Register, OrData) \
+ (HBA_REG8_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (OrData)))
+
+#define HBA_PORT_REG16_OR(BaseAddr, Port, Register, OrData) \
+ (HBA_REG16_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (OrData)))
+
+#define HBA_PORT_REG32_OR(BaseAddr, Port, Register, OrData) \
+ (HBA_REG32_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (OrData)))
+
+#define HBA_PORT_REG8_AND(BaseAddr, Port, Register, AndData) \
+ (HBA_REG8_AND ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData)))
+
+#define HBA_PORT_REG16_AND(BaseAddr, Port, Register, AndData) \
+ (HBA_REG16_AND ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData)))
+
+#define HBA_PORT_REG32_AND(BaseAddr, Port, Register, AndData) \
+ (HBA_REG32_AND ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData)))
+
+#define HBA_PORT_REG8_AND_OR(BaseAddr, Port, Register, AndData, OrData) \
+ (HBA_REG8_AND_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData), (OrData)))
+
+#define HBA_PORT_REG16_AND_OR(BaseAddr, Port, Register, AndData, OrData) \
+ (HBA_REG16_AND_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData), (OrData)))
+
+#define HBA_PORT_REG32_AND_OR(BaseAddr, Port, Register, AndData, OrData) \
+ (HBA_REG32_AND_OR ((BaseAddr), ((Register) + HBA_PORT_REG_BASE (Port)), (AndData), (OrData)))
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Ahci/AhciInt13Dxe.c b/Core/EM/Ahci/AhciInt13Dxe.c
new file mode 100644
index 0000000..20724ad
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Dxe.c
@@ -0,0 +1,412 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Dxe.c 1 11/25/14 12:09a Kapilporwal $Revision:
+//
+// $Date: 11/25/14 12:09a $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Dxe.c $
+//
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: AhciInt13Dxe.c
+//
+// Description:
+// This file will register one CALLBACK function, AmiLegacyBootNotify(),
+// it will collect AHCI Int13 runtime data from gAhciI13Data and
+// send it to SMM for AHCI INT13 SMI handler.
+//****************************************************************************
+//<AMI_FHDR_END>
+
+//---------------------------------------------------------------------------
+#include <Token.h>
+#include <AmiDxeLib.h>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+#include <Protocol/SmmCommunication.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/LegacyBiosExt.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/PDiskInfo.h>
+#include <Protocol/PIDEController.h>
+#include <Protocol/PIDEBus.h>
+#include <Protocol/PAhciBus.h>
+#include "AInt13.h"
+#include "AhciInt13Smm.h"
+
+AHCI_I13_RTDATA *gAhciI13Data = NULL;
+extern EFI_GUID gAint13SmmDataGuid;
+EFI_GUID gEfiLegacyBiosProtocolGuid = EFI_LEGACY_BIOS_PROTOCOL_GUID;
+EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+EFI_GUID gEfiEventLegacyBootGuid = EFI_EVENT_LEGACY_BOOT_GUID;
+
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsSataDeviceInAhciMode
+//
+// Description: Check input BBS device is a SATA DEVICE in AHCI mode.
+//
+// Input: BBS_TABLE* - Pointer to an entry in BBS table
+//
+// Output: UINT8 TRUE - It is a SATA device and in AHCI mode
+// FALSE - It is not a SATA device or not in AHCI mode
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+IsSataDeviceInAhciMode (
+ IN BBS_TABLE *BbsEntry
+)
+{
+
+ if((BbsEntry->DeviceType == BBS_HARDDISK || BbsEntry->DeviceType == BBS_CDROM)) {
+ if(BbsEntry->Class == MASS_STORAGE || BbsEntry->SubClass == AHCI_CONTROLLER ){
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitializeAhciI13Data
+//
+// Description: It initializes AHCI INT13 runtime data pointer (gAhciI13Data).
+//
+// Input: BBS_TABLE* - Pointer to an entry in BBS table
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitializeAhciI13Data (
+ IN BBS_TABLE *BbsEntry
+)
+{
+ UINT16 StrSeg = 0, StrOff = 0;
+ UINT32 DevOutfitAddr = 0, DevOutfitStartAddr = 0;
+ UINT8 AInt13No = 0, DevNo = 0;
+
+ if(!gAhciI13Data) {
+ // INT13 Drive number (0x80~0x8F)
+ AInt13No = (UINT8)(BbsEntry->InitPerReserved >> 8);
+ DevNo = AInt13No & 0x7F; // Drive index
+
+ // Get address of drive description string i.e. AHCI_I13_RTDATA.DevOutfit[DevNo]
+ StrSeg = BbsEntry->DescStringSegment;
+ StrOff = BbsEntry->DescStringOffset;
+ DevOutfitAddr = (UINT32)((UINTN)StrSeg << 4) + (UINT32)StrOff;
+
+ // Now get address of description string of 1st drive i.e. AHCI_I13_RTDATA.DevOutfit[0]
+ DevOutfitStartAddr = DevOutfitAddr - (sizeof(DEV_BBS_OUTFIT)*DevNo);
+ // Now get base address of AHCI_I13_RTDATA structure
+ gAhciI13Data = (AHCI_I13_RTDATA*)(DevOutfitStartAddr - EFI_FIELD_OFFSET(AHCI_I13_RTDATA, DevOutfit));
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TransferAhciInt13SmmDataToSmm
+//
+// Description: It uses EFI_SMM_COMMUNICATION_PROTOCOL API to transfer data
+// from Non-SMM mode to SMM mode.
+//
+// Input: VOID* - Pointer to data to be transfered
+// UINTN - size of the data
+// EFI_GUID* - Pointer to GUID identifier for the data
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+TransferAhciInt13SmmDataToSmm (
+ IN VOID *pData,
+ IN UINTN DataSize,
+ IN EFI_GUID *pGuid
+)
+{
+ EFI_SMM_COMMUNICATION_PROTOCOL *gSmmCommunication = NULL;
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
+ UINT8 *CommunicateBuffer = NULL;
+ UINTN CommunicateBufferSize;
+ EFI_STATUS Status;
+
+ if ( pData == NULL || DataSize == 0 || pGuid == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Calculate Size of Communication buffer
+ CommunicateBufferSize = (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data)) + DataSize; // Header size (without data) + data size
+
+ // Allocate memory for Communication Buffer.
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ CommunicateBufferSize,
+ (VOID**)&CommunicateBuffer );
+ if ( EFI_ERROR( Status )) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Copy SMM Communicate Header Here
+ SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicateBuffer;
+
+ // Copy data GUID
+ pBS->CopyMem( &SmmCommunicateHeader->HeaderGuid, pGuid, sizeof( EFI_GUID ) );
+
+ // Updated data length
+ SmmCommunicateHeader->MessageLength = DataSize;
+
+ // Copy Data Here
+ pBS->CopyMem( &SmmCommunicateHeader->Data, pData, DataSize );
+
+ // Locate EFI_SMM_COMMUNICATION_PROTOCOL
+ Status = pBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &gSmmCommunication);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Send data to SMM using protocol API
+ Status = gSmmCommunication->Communicate (gSmmCommunication, CommunicateBuffer, &CommunicateBufferSize);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Free memory allocated for Communication Buffer.
+ Status = pBS->FreePool(CommunicateBuffer);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiLegacyBootNotify
+//
+// Description: This function will be called upon legacy boot event. It
+// collects information about all AHCI devices present in the system and
+// send it to SMM so that AHCI INT13 SMI handler can use it.
+// Operation:
+// 1. Locate EFI_LEGACY_BIOS_PROTOCOL and get All BBS entries and look
+// for entry corresponding to a drive in AHCI mode
+// 2. If a valid entry is found then it will use AHCI INT13 runtime
+// data and AHCI bus interface data to fill data required by AHCI
+// INT13 SMI handler.
+// 3. This newly created data structure will be transfered to SMM using
+// SmmCommunicationProtocol API.
+//
+// Input: EFI_EVENT - Event
+// VOID* - Pointer to Context
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+AmiLegacyBootNotify(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ UINT16 HddCount = 0;
+ HDD_INFO *HddInfo = NULL;
+ BBS_TABLE *BbsTable = NULL;
+ UINT16 BbsCount = 0;
+ UINT8 DevNo = 0;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ UINT16 i = 0;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo = NULL;
+ SATA_DEVICE_INTERFACE *SataDevInterface = NULL;
+ SMM_AINT13_DRIVE_INFO *pDriveInfo = NULL;
+ AHCI_INT13_SMM_DATA *AhciInt13SmmData = NULL;
+
+ // Run this function only once
+ pBS->CloseEvent(Event);
+
+ // Locate EFI_LEGACY_BIOS_PROTOCOL
+ Status = pBS->LocateProtocol( &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ &LegacyBios);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ // Get BBS_TABLE
+ Status = LegacyBios->GetBbsInfo( LegacyBios,
+ &HddCount,
+ &HddInfo,
+ &BbsCount,
+ &BbsTable);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ // Allocate Memory for AhciInt13SmmData buffer.
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(AHCI_INT13_SMM_DATA),
+ (VOID**)&AhciInt13SmmData );
+ if ( EFI_ERROR( Status )) {
+ ASSERT_EFI_ERROR(Status);
+ return;
+ }
+
+ // Initialize drive count to 0
+ AhciInt13SmmData->DriveCount = 0;
+
+ // Loop through all BBS entries
+ for (i = 0; i < BbsCount; i++) {
+
+ // Process if this BDS entry is corresponding to a HDD in AHCI mode
+ if (IsSataDeviceInAhciMode(&BbsTable[i])) {
+
+ // NOTE: We don't need EFI_DISK_INFO_PROTOCOL this is just to get SATA_DEVICE_INTERFACE structure.
+ Status = pBS->HandleProtocol ( (EFI_HANDLE)BbsTable[i].IBV1, &gEfiDiskInfoProtocolGuid, &DiskInfo );
+ if(EFI_ERROR(Status)) {
+ continue; // Goto next BBS entry
+ }
+ SataDevInterface = ((SATA_DISK_INFO *)DiskInfo)->SataDevInterface;
+
+ // Fill data in AhciInt13SmmData
+ pDriveInfo = &(AhciInt13SmmData->DriveInfo[AhciInt13SmmData->DriveCount]);
+ pDriveInfo->DriveNum = (UINT8)(BbsTable[i].InitPerReserved >> 8);
+ pDriveInfo->PMPortNum = SataDevInterface->PMPortNumber;
+ pDriveInfo->PortNum = SataDevInterface->PortNumber;
+ SataDevInterface->AhciBusInterface->PciIO->GetLocation(
+ SataDevInterface->AhciBusInterface->PciIO,
+ &SegNum, &BusNum, &DevNum, &FuncNum
+ );
+ pDriveInfo->BusNo = (UINT8)BusNum;
+ pDriveInfo->DevNo = (UINT8)DevNum;
+ pDriveInfo->FuncNo = (UINT8)FuncNum;
+ pDriveInfo->DeviceType = SataDevInterface->DeviceType;
+ if(pDriveInfo->DeviceType == ATAPI) {
+ pDriveInfo->Lun = SataDevInterface->AtapiDevice->Lun;
+ pDriveInfo->BlockSize = SataDevInterface->AtapiDevice->BlockSize;
+ } else {
+ // Initialize AHCI INT13 runtime data
+ if(!gAhciI13Data) {
+ InitializeAhciI13Data(&BbsTable[i]);
+ }
+ // Get drive index in device parameter array of gAhciI13Data
+ DevNo = pDriveInfo->DriveNum & 0x7F;
+
+ // Fill the information using gAhciI13Data
+ pDriveInfo->wMAXCYL = gAhciI13Data->DevParam[DevNo].wMAXCYL;
+ pDriveInfo->bMAXHN = gAhciI13Data->DevParam[DevNo].bMAXHN;
+ pDriveInfo->bMAXSN = gAhciI13Data->DevParam[DevNo].bMAXSN;
+ pDriveInfo->wLBACYL = gAhciI13Data->DevParam[DevNo].wLBACYL;
+ pDriveInfo->bLBAHD = gAhciI13Data->DevParam[DevNo].bLBAHD;
+ pDriveInfo->bLBASPT = gAhciI13Data->DevParam[DevNo].bLBASPT;
+ }
+ pDriveInfo->RCommand = SataDevInterface->ReadCommand;
+ pDriveInfo->WCommand = SataDevInterface->WriteCommand;
+
+ AhciInt13SmmData->DriveCount += 1; // Update drive count
+ }
+ }
+
+ // Save AhciInt13SmmData in SMM
+ if(AhciInt13SmmData->DriveCount != 0) {
+ Status = TransferAhciInt13SmmDataToSmm ( AhciInt13SmmData, sizeof(AHCI_INT13_SMM_DATA), &gAint13SmmDataGuid );
+ }
+
+ // Free the Memory Allocated for AhciInt13SmmData Buffer.
+ Status = pBS->FreePool(AhciInt13SmmData);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AhciInt13DxeEntry
+//
+// Description: This is entry point function. It registers a call back function
+// for Legacy boot event.
+//
+// Input: EFI_HANDLE - Standard EFI Image handle
+// EFI_SYSTEM_TABLE* - Pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciInt13DxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = pBS->CreateEventEx (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ AmiLegacyBootNotify,
+ NULL,
+ &gEfiEventLegacyBootGuid,
+ &Event
+ );
+
+ return Status;
+}
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciInt13Dxe.dxs b/Core/EM/Ahci/AhciInt13Dxe.dxs
new file mode 100644
index 0000000..8223f9b
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Dxe.dxs
@@ -0,0 +1,51 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Dxe.dxs 1 11/25/14 12:09a Kapilporwal $Revision:
+//
+// $Date: 11/25/14 12:09a $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Dxe.dxs $
+//
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: AhciInt13Dxe.dxs
+//
+// Description:
+// Dependency expression for the AhciInt13Dxe component
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include<Protocol\SmmCommunication.h>
+
+DEPENDENCY_START
+ EFI_SMM_COMMUNICATION_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Ahci/AhciInt13Smm.c b/Core/EM/Ahci/AhciInt13Smm.c
new file mode 100644
index 0000000..8715bce
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Smm.c
@@ -0,0 +1,1157 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.c 2 12/08/14 5:39a Anbuprakashp $Revision:
+//
+// $Date: 12/08/14 5:39a $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.c $
+//
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: AhciInt13Smm.C
+//
+// Description: This file contains code for SMI handler for AHCI INT13.
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <AmiBufferValidationLib.h>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmCpu.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/PDiskInfo.h>
+#include <Protocol/PIDEController.h>
+#include <Protocol/PIDEBus.h>
+#include <Protocol/AhciSmmProtocol.h>
+#include "AhciInt13Smm.h"
+
+EFI_SMM_CPU_PROTOCOL *gSmmCpuProtocol = NULL;
+AHCI_BUS_SMM_PROTOCOL *gAhciBusSmmProtocol = NULL;
+DLIST gDriveInfoList;
+EFI_GUID gAint13SmmDataGuid = AHCI_INT13_SMM_DATA_GUID;
+EFI_GUID gAhciSmmProtocolGuid = AHCI_SMM_PROTOCOL_GUID;
+EFI_GUID gEfiSmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+EFI_GUID gEfiSmmSwDispatch2ProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID;
+UINT64 PciExpressBaseAddress = 0;
+UINT8 *gBuffer = NULL;
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: AhciMmioRead
+//
+// Description: Read from AHCI MMIO address
+//
+// Input: IN UINT32 - AHCI MMIO address
+//
+// Output: OUT UINT32 - Value read from AHCI MMIO address
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciMmioRead (
+ IN UINT32 AhciMmioAddress,
+ OUT UINT32 *ReadValue
+)
+{
+ EFI_STATUS Status;
+ // Validate AhciBaseAddress is valid MMIO address and not reside in SMRAM region
+ Status = AmiValidateMmioBuffer( (VOID*)AhciMmioAddress, 4 );
+ if( EFI_ERROR(Status) ) {
+ return Status;
+ }
+
+ *ReadValue = *(UINT32*)(AhciMmioAddress);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: AhciMmioWrite
+//
+// Description: Write to the AHCI MMIO Address
+//
+// Input: IN UINT32 - AHCI MMIO address
+// IN UINT32 - Value to be written
+//
+// Output: EFI_STATUS - EFI_NOT_FOUND: Invalid address, EFI_SUCCESS: Success
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciMmioWrite (
+ IN UINT32 AhciMmioAddress,
+ IN UINT32 WriteValue
+)
+{
+ EFI_STATUS Status;
+
+ // Validate AhciBaseAddress is valid MMIO address and not reside in SMRAM region
+ Status = AmiValidateMmioBuffer( (VOID*)AhciMmioAddress, 4 );
+ if( EFI_ERROR(Status) ) {
+ return Status;
+ }
+
+ *(UINT32*)(AhciMmioAddress) = WriteValue;
+ return Status;
+}
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Is48BitCommand
+//
+// Description: Check if input command is a LBA48 command
+//
+// Input: UINT8 - Command
+//
+// Output: BOOLEAN - TRUE - LBA48 command
+// FALSE - Not a LBA48 command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+Is48BitCommand (
+ IN UINT8 Command
+ )
+{
+ if ( Command == READ_SECTORS_EXT ||
+ Command == READ_MULTIPLE_EXT ||
+ Command == WRITE_SECTORS_EXT ||
+ Command == WRITE_MULTIPLE_EXT ||
+ Command == READ_DMA_EXT ||
+ Command == WRITE_DMA_EXT )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsDmaCommand
+//
+// Description: Check if input command is a DMA command
+//
+// Input: UINT8 - Command
+//
+// Output: BOOLEAN - TRUE - DMA command
+// FALSE - Not a DMA command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsDmaCommand (
+ IN UINT8 Command
+ )
+{
+ if ( Command == READ_DMA ||
+ Command == READ_DMA_EXT ||
+ Command == WRITE_DMA ||
+ Command == WRITE_DMA_EXT )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CheckErrorCode
+//
+// Description: It maps EFI_STATUS code to corresponding INT13 error code
+//
+// Input: EFI_STATUS - Status
+//
+// Output: UINT8 - INT13 error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+CheckErrorCode (
+ IN EFI_STATUS Status
+ )
+{
+ switch(Status){
+ case EFI_SUCCESS:
+ return 0x0; // successful completion
+ break;
+ case EFI_INVALID_PARAMETER:
+ return 0x01; // invalid function in AH or invalid parameter
+ break;
+ case EFI_UNSUPPORTED:
+ return 0x01; // invalid function in AH or invalid parameter
+ break;
+ case EFI_NOT_READY:
+ return 0xAA; // drive not ready (hard disk)
+ break;
+ case EFI_DEVICE_ERROR:
+ return 0xE0; // status register error (hard disk)
+ break;
+ case EFI_WRITE_PROTECTED:
+ return 0x03; // disk write-protected
+ break;
+ case EFI_NO_MEDIA:
+ return 0x31; // no media in drive (IBM/MS INT 13 extensions)
+ break;
+ case EFI_MEDIA_CHANGED:
+ return 0x06; // disk changed
+ break;
+ case EFI_NOT_FOUND:
+ return 0x01; // invalid function in AH or invalid parameter
+ break;
+ case EFI_ACCESS_DENIED:
+ return 0xB6; // volume present but read protected (INT 13 extensions)
+ break;
+ case EFI_TIMEOUT:
+ return 0x80; // timeout (not ready)
+ break;
+ case EFI_ABORTED:
+ return 0xBB; // undefined error (hard disk)
+ break;
+ default:
+ break;
+ }
+ return 0xBB;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetDriveInfoByDriveNum
+//
+// Description: It returns the drive information corresponding to input drive
+// number, if found.
+//
+// Input: IN UINT8 - INT13 drive number
+// IN OUT VOID** - Pointer to SMM_AINT13_DRIVE_INFO variable
+// It will be filled with corresponding drive
+// information
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - DriveInfo is valid
+// EFI_UNSUPPORTED - Can't find the corresponding data.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetDriveInfoByDriveNum(
+ IN UINT8 DriveNum,
+ IN OUT VOID **DriveInfo
+)
+{
+ DLINK *DriveInfoLink = NULL;
+ SMM_AINT13_DRIVE_INFO *pDriveInfo = NULL;
+
+ // Look for drive information corresponding to DriveNum in gDriveInfoList
+ DriveInfoLink = gDriveInfoList.pHead;
+ for(;DriveInfoLink;DriveInfoLink=DriveInfoLink->pNext){
+ pDriveInfo = OUTTER(DriveInfoLink, dLink, SMM_AINT13_DRIVE_INFO);
+ if(DriveNum == pDriveInfo->DriveNum) {
+ // Return the information if found, also set status as success
+ *DriveInfo = pDriveInfo;
+ return EFI_SUCCESS;
+ }
+ }
+
+ // No drive information corresponding to DriveNum in gDriveInfoList
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ProcessInt13Function
+//
+// Description: Worker function to service AHCI INT13 request. Currently it
+// supports Read/Write function only.
+// Operation:
+// 1. Parse information passed as IA registers to parameter required
+// by AMI_AHCI_BUS_SMM_PROTOCOL APIs.
+// 2. Call appropriate AMI_AHCI_BUS_SMM_PROTOCOL API.
+//
+// Input: EFI_IA32_REGISTER_SET* - Pointer of EFI_IA32_REGISTER_SET
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Int13 request complete
+// EFI_UNSUPPORTED - This Int13 request is unsupported
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ProcessInt13Function(
+ IN EFI_IA32_REGISTER_SET *ExRegs
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN IsSupported = TRUE;
+ VOID *Buffer = NULL;
+ UINT8 *BufferBackup = NULL;
+ UINT32 ByteCount = 0;
+ UINT16 SectorCount = 0;
+ UINT8 Command = 0;
+ EFI_LBA Lba = 0;
+ UINT16 SkipBytesBefore = 0, SkipBytesAfter = 0;
+ UINT16 Header = 0, Cylinder = 0, Sector = 0;
+ UINT8 ReadWrite = 0; // 0 : read, 1: write
+ UINT8 *UserBuf = NULL;
+ UINT64 bAhciBaseAddress = 0;
+ UINTN i = 0;
+ UINT16 BlksPerTransfer;
+ VOID *AhciBuffer;
+ BOOLEAN UnalignedTransfer = FALSE;
+ DISK_ADDRESS_PACKAGE *Package = NULL;
+ SMM_AINT13_DRIVE_INFO *pDriveInfo = NULL;
+ COMMAND_STRUCTURE CommandStructure;
+
+ // Get drive information based on drive number
+ Status = GetDriveInfoByDriveNum(ExRegs->H.DL,&pDriveInfo);
+
+ if(!EFI_ERROR(Status)){
+ if(pDriveInfo->DeviceType == ATA) {
+ // Calculate AHCI parameter to be filled in COMMAND_STRUCTURE based on INT13 function
+ if(ExRegs->H.AH == READ_SECTOR || ExRegs->H.AH == EXT_READ){
+ Command = pDriveInfo->RCommand;
+ ReadWrite = 0; // read
+ }else if(ExRegs->H.AH == WRITE_SECTOR || ExRegs->H.AH == EXT_WRITE){
+ Command = pDriveInfo->WCommand;
+ ReadWrite = 1; // write
+ }
+ switch(ExRegs->H.AH){
+ case READ_SECTOR:
+ case WRITE_SECTOR:
+ Cylinder = ((UINT16)(ExRegs->H.CL & 0xC0 ) << 2) +ExRegs->H.CH; // cylinder: bit 6-7(CL) + CH
+ Header = (UINT16)ExRegs->H.DH; // header : DH
+ Sector = (UINT16)(ExRegs->H.CL & 0x3F); // sector : bit 0-5(CL)
+ Lba = (Cylinder*(pDriveInfo->bMAXHN) + Header) * (pDriveInfo->bMAXSN) + Sector - 1;
+ SectorCount = ExRegs->H.AL;
+ Buffer = (VOID*)(((ExRegs->X.ES) << 4 ) + ExRegs->X.BX);
+ ByteCount = SectorCount*HDD_BLOCK_SIZE;
+ break;
+ case EXT_READ:
+ case EXT_WRITE:
+ Package = (DISK_ADDRESS_PACKAGE*)(((ExRegs->X.DS) << 4 ) + ExRegs->X.SI);
+ Lba = Package->StartLba;
+ SectorCount = Package->XferSector;
+ Buffer = (VOID*)(((Package->Buffer >> 16 & 0xFFFF) << 4) + (UINT16)Package->Buffer);
+ ByteCount = SectorCount*HDD_BLOCK_SIZE;
+ break;
+ default:
+ IsSupported = FALSE;
+ break;
+ }
+ } else if(pDriveInfo->DeviceType == ATAPI){ // Only read command support is required
+ Command = pDriveInfo->RCommand;
+ ReadWrite = 0; // read
+ Buffer = (VOID*)((((ExRegs->E.EDI) >> 16 & 0xFFFF) << 4) + (UINT16)(ExRegs->E.EDI));
+ Lba = ExRegs->E.EAX;
+ SectorCount = ExRegs->X.CX; // CX
+ SkipBytesAfter = ((ExRegs->E.ECX) >> 24) * 512; // CH+ (Higher byte of higher word of ECX)
+ SkipBytesBefore = (((ExRegs->E.ECX) >> 16) & 0xFF) * 512; // CL+ (Lower byte of higher word of ECX)
+ ByteCount = SectorCount * pDriveInfo->BlockSize; // 2048
+ if(SkipBytesBefore || SkipBytesAfter) {
+ Status = pSmst->SmmAllocatePool(EfiRuntimeServicesData, sizeof(UINT8)*(SkipBytesBefore + SkipBytesAfter), &BufferBackup);
+ if (EFI_ERROR(Status)) {
+ ASSERT(TRUE);
+ IsSupported = FALSE;
+ } else {
+ // Backup bytes to be preserved.
+ for(i = 0;i<(SkipBytesBefore + SkipBytesAfter);i++) {
+ BufferBackup[i] = *(((UINT8*)Buffer)+i + (ByteCount - SkipBytesBefore - SkipBytesAfter));
+ }
+ }
+ }
+ } else {
+ IsSupported = FALSE;
+ }
+ } // if(!EFI_ERROR(Status))
+ else {
+ IsSupported = FALSE;
+ }
+
+ if(IsSupported){
+ // Backup AHCI base address from gAhciBusSmmProtocol
+ bAhciBaseAddress = gAhciBusSmmProtocol->AhciBaseAddress;
+
+ // Save current AHCI base address from AHCI controller.
+ gAhciBusSmmProtocol->AhciBaseAddress = *(UINT32*)PCI_CFG_ADDR(pDriveInfo->BusNo, pDriveInfo->DevNo, pDriveInfo->FuncNo, PCI_ABAR);
+
+ BlksPerTransfer = SectorCount;
+ AhciBuffer = Buffer;
+
+ //If Buffer isn't aligned use internal buffer
+ if(((UINT32)Buffer) & 0x1) {
+ BlksPerTransfer = 1;
+ AhciBuffer = gBuffer;
+ UnalignedTransfer = TRUE;
+ }
+
+ if(pDriveInfo->DeviceType == ATA) {
+ ByteCount = BlksPerTransfer * HDD_BLOCK_SIZE;
+ } else if(pDriveInfo->DeviceType == ATAPI){
+ ByteCount = BlksPerTransfer * pDriveInfo->BlockSize;
+ }
+
+ UserBuf = (UINT8*)Buffer;
+
+ for ( ; SectorCount; SectorCount -= BlksPerTransfer){
+
+ if (ReadWrite == 1 && UnalignedTransfer) {
+ for(i = 0; i < ByteCount; i++) {
+ *(((UINT8*)AhciBuffer)+i) = *(((UINT8*)Buffer)+i);
+ }
+ }
+
+ // clear Command structure
+ MemSet (&CommandStructure, sizeof(COMMAND_STRUCTURE), 0);
+
+ // Fill CommandStructure buffer.
+ CommandStructure.Buffer = AhciBuffer;
+ CommandStructure.ByteCount = ByteCount;
+ if(pDriveInfo->DeviceType == ATA) { // ATA
+ CommandStructure.Features = 0;
+ CommandStructure.FeaturesExp = 0;
+ CommandStructure.SectorCount = BlksPerTransfer;
+ CommandStructure.LBALow = (UINT8)Lba;
+ CommandStructure.LBAMid = (UINT8) (((UINT32)Lba >>8) & 0xff);
+ CommandStructure.LBAHigh = (UINT8) (((UINT32)Lba >>16) & 0xff);
+ if(Is48BitCommand(Command)){ // if support LBA48 feature?
+ CommandStructure.LBALowExp = (UINT8) (UINT8)Shr64(Lba,24);
+ CommandStructure.LBAMidExp = (UINT8) (UINT8)Shr64(Lba,32);
+ CommandStructure.LBAHighExp = (UINT8) (UINT8)Shr64(Lba,40);
+ CommandStructure.Device = 0x40; // LBA48
+ }else{
+ CommandStructure.Device = ((UINT8)Shr64(Lba,24) & 0x0f) | 0x40; // LBA28
+ }
+ CommandStructure.Command = Command;
+ CommandStructure.Control = 0;
+ } else if(pDriveInfo->DeviceType == ATAPI) {
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = Command;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[1] = pDriveInfo->Lun << 5;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[2] = (UINT8)(((UINT32) Lba) >> 24);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[3] = (UINT8)(((UINT32) Lba) >> 16);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[4] = (UINT8)(((UINT16) Lba) >> 8);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[5] = (UINT8)(((UINT8) Lba) & 0xff);
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[7] = (UINT8) (BlksPerTransfer >> 8); // MSB
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[8] = (UINT8) (BlksPerTransfer & 0xff); // LSB
+ }
+
+ // Send ATA/ATAPI command in AHCI mode
+ if(pDriveInfo->DeviceType == ATA) { // ATA
+ if(IsDmaCommand(Command)) {
+ Status = gAhciBusSmmProtocol->AhciSmmExecuteDmaDataCommand( gAhciBusSmmProtocol,
+ &CommandStructure,
+ pDriveInfo->PortNum,
+ pDriveInfo->PMPortNum,
+ pDriveInfo->DeviceType,
+ ReadWrite);
+ } else {
+ Status = gAhciBusSmmProtocol->AhciSmmExecutePioDataCommand( gAhciBusSmmProtocol,
+ &CommandStructure,
+ pDriveInfo->PortNum,
+ pDriveInfo->PMPortNum,
+ pDriveInfo->DeviceType,
+ ReadWrite);
+ }
+ } else { // ATAPI
+ Status = gAhciBusSmmProtocol->AhciSmmExecutePacketCommand( gAhciBusSmmProtocol,
+ &CommandStructure,
+ ReadWrite,
+ pDriveInfo->PortNum,
+ pDriveInfo->PMPortNum,
+ pDriveInfo->DeviceType);
+ }
+
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ if (ReadWrite == 0 && UnalignedTransfer) {
+ for(i = 0; i < ByteCount; i++) {
+ *(((UINT8*)Buffer)+i) = *(((UINT8*)AhciBuffer)+i);
+ }
+ }
+
+ (UINTN)Buffer = (UINTN)Buffer + ByteCount;
+ Lba += BlksPerTransfer;
+
+ }
+
+ Buffer = UserBuf;
+
+ // Restore base address to gAhciBusSmmProtocol
+ gAhciBusSmmProtocol->AhciBaseAddress = bAhciBaseAddress;
+
+ if(pDriveInfo->DeviceType == ATAPI){
+ // fill output buffer with requested data only.
+ if(SkipBytesBefore || SkipBytesAfter) {
+ UserBuf = (UINT8*)Buffer;
+ // Move requested data at start of the buffer
+ if(SkipBytesBefore != 0)
+ for(i = 0;i<ByteCount - SkipBytesBefore - SkipBytesAfter;i++) {
+ UserBuf[i] = UserBuf[i+SkipBytesBefore];
+ }
+ // Keep rest of the buffer intact. Restore the backup.
+ for(i = 0;i<SkipBytesBefore + SkipBytesAfter;i++) {
+ UserBuf[i + (ByteCount - SkipBytesBefore - SkipBytesAfter)] = BufferBackup[i];
+ }
+ pSmst->SmmFreePool(BufferBackup);
+ }
+ }
+
+ // update return register data whatever success or error!!
+ if(!EFI_ERROR(Status)){
+ // AHCI success
+ ExRegs->X.Flags.CF = 0x0; // clear if successful
+ ExRegs->H.AH = CheckErrorCode(Status); // successful completion
+ }
+ else{
+ // AHCI error
+ ExRegs->X.Flags.CF = 0x1; // set on error
+ ExRegs->H.AH = CheckErrorCode(Status); // return error code
+ }
+ }
+
+ // return EFI_SUCCESS: Int13 request is complete.
+ // return EFI_UNSUPPORTED: This function isn't supported by this routine.
+ return (IsSupported)? EFI_SUCCESS : EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AhciInt13SmiHandler
+//
+// Description: This is the SWSMI handler to service AHCI INT13 request.
+// Operation:
+// 1. Take INT13 parameters stored on real mode stack from CPU save state.
+// 2. Call a sub-function to process INT13 request.
+// 3. Update output parameters (IA registers) on real mode stack.
+//
+// Input: UINTN - Index of CPU which triggered SW SMI
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciInt13SmiHandler (
+ IN UINTN CpuIndex
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 StackSegment = 0;
+ UINT16 StackOffset = 0;
+ EFI_IA32_REGISTER_SET ExRegs;
+ INT13_TO_SMI_EXREGS *Int13ToSmiExRegs = NULL;
+TRACE((-1, "\nKAPIL: AhciInt13SmiHandler."));
+ // Read SS/ESP from CPU save state
+ gSmmCpuProtocol->ReadSaveState ( gSmmCpuProtocol,
+ 2,
+ EFI_SMM_SAVE_STATE_REGISTER_RSP,
+ CpuIndex,
+ &StackOffset );
+
+ gSmmCpuProtocol->ReadSaveState ( gSmmCpuProtocol,
+ 2,
+ EFI_SMM_SAVE_STATE_REGISTER_SS,
+ CpuIndex,
+ &StackSegment );
+
+ // Get base address of real mode stack
+ Int13ToSmiExRegs = (INT13_TO_SMI_EXREGS*)(((StackSegment << 4) + StackOffset) + 2);
+
+ MemSet (&ExRegs, sizeof(EFI_IA32_REGISTER_SET), 0);
+
+ // Initialize the SMM THUNK registers
+ ExRegs.E.EAX = Int13ToSmiExRegs->StackEAX;
+ ExRegs.E.EBX = Int13ToSmiExRegs->StackEBX;
+ ExRegs.E.ECX = Int13ToSmiExRegs->StackECX;
+ ExRegs.E.EDX = Int13ToSmiExRegs->StackEDX;
+ ExRegs.E.EDI = Int13ToSmiExRegs->StackEDI;
+ ExRegs.E.ESI = Int13ToSmiExRegs->StackESI;
+ ExRegs.E.EBP = Int13ToSmiExRegs->StackEBP;
+ ExRegs.E.DS = Int13ToSmiExRegs->StackDS;
+ ExRegs.E.ES = Int13ToSmiExRegs->StackES;
+ ExRegs.E.FS = Int13ToSmiExRegs->StackFS;
+ ExRegs.E.GS = Int13ToSmiExRegs->StackGS;
+ ExRegs.X.Flags = Int13ToSmiExRegs->StackFlags;
+
+ if(gAhciBusSmmProtocol && gDriveInfoList.pHead){
+ // Execute Int13 function by AhciSmmProtocol and update ExRegs for return caller.
+ // Note: Function will return non-EFI_SUCCESS value if Int13 function isn't
+ // supported by ProcessInt13Function().
+ Status = ProcessInt13Function(&ExRegs);
+ }
+
+ // Update the registers before go back caller.
+ Int13ToSmiExRegs->StackEAX = ExRegs.E.EAX;
+ Int13ToSmiExRegs->StackEBX = ExRegs.E.EBX;
+ Int13ToSmiExRegs->StackECX = ExRegs.E.ECX;
+ Int13ToSmiExRegs->StackEDX = ExRegs.E.EDX;
+ Int13ToSmiExRegs->StackEDI = ExRegs.E.EDI;
+ Int13ToSmiExRegs->StackESI = ExRegs.E.ESI;
+ Int13ToSmiExRegs->StackEBP = ExRegs.E.EBP;
+ Int13ToSmiExRegs->StackDS = ExRegs.E.DS;
+ Int13ToSmiExRegs->StackES = ExRegs.E.ES;
+ Int13ToSmiExRegs->StackFS = ExRegs.E.FS;
+ Int13ToSmiExRegs->StackGS = ExRegs.E.GS;
+ Int13ToSmiExRegs->StackFlags = ExRegs.X.Flags;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: AhciMmioSmiHandler
+//
+// Description: SMI handler for the AHCI_MMIO_SWSMI SW SMI
+//
+// Input: IN UINTN - Index of CPU which triggered SW SMI
+// IN UINT32 - 1/2: Read or Write MMIO operation
+//
+// Output: EFI_STATUS - EFI_SUCCESS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciMmioSmiHandler (
+ IN UINTN CpuIndex,
+ IN UINT32 FunctionNo
+)
+{
+ EFI_STATUS Status;
+ UINT32 AhciMmioAddress;
+ UINT32 WriteValue;
+ UINT32 ReadValue;
+ UINT32 ReturnStatus = 0x0FF;
+
+ gSmmCpuProtocol->ReadSaveState (gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RSI,
+ CpuIndex,
+ &AhciMmioAddress );
+
+
+ if(FunctionNo == 1) {
+ Status=AhciMmioRead(AhciMmioAddress, &ReadValue);
+
+ if(!EFI_ERROR(Status)) {
+ gSmmCpuProtocol->WriteSaveState(gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RAX,
+ CpuIndex,
+ &ReadValue);
+ ReturnStatus = 0; // Update success
+ }
+
+ gSmmCpuProtocol->WriteSaveState(gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RCX,
+ CpuIndex,
+ &ReturnStatus);
+
+ } else if(FunctionNo == 2) {
+
+ gSmmCpuProtocol->ReadSaveState (gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RBX,
+ CpuIndex,
+ &WriteValue );
+
+ Status = AhciMmioWrite(AhciMmioAddress, WriteValue);
+
+ if(!EFI_ERROR(Status)) {
+ ReturnStatus = 0; // Update success
+ }
+
+ gSmmCpuProtocol->WriteSaveState(gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RCX,
+ CpuIndex,
+ &ReturnStatus);
+ } else {
+ // Invalid function number, return Error(i.e. ReturnStatus==0xFF)
+ gSmmCpuProtocol->WriteSaveState(gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RCX,
+ CpuIndex,
+ &FunctionNo);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: AhciCommonSmmHandler
+//
+// Description: Common SMI handler for AHCI INT13 SMIs
+//
+// Input: IN EFI_HANDLE - EFI Handle
+// IN VOID* - Pointer to the EFI_SMM_SW_REGISTER_CONTEXT
+// IN VOID* - Pointer to Communication data
+// IN UINTN* - Pointer to size of Communication data
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciCommonSmmHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN CpuIndex = (UINTN)-1;
+ UINT32 FunctionNo = 0;
+
+ // Get CPU number of CPU which generated this SWSMI
+ if (CommBuffer != NULL && CommBufferSize != NULL) {
+ CpuIndex = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->SwSmiCpuIndex;
+ }
+
+ // Return if CPU number is invalid
+ if(CpuIndex == (UINTN)-1) return Status;
+
+ // Read ECX from CPU save state
+ gSmmCpuProtocol->ReadSaveState ( gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RCX,
+ CpuIndex,
+ &FunctionNo );
+
+ switch(FunctionNo) {
+ case 0x1:
+ case 0x2:
+ Status = AhciMmioSmiHandler(CpuIndex, FunctionNo);
+ break;
+
+ case 0x3:
+ Status = AhciInt13SmiHandler(CpuIndex);
+ break;
+
+ default:
+ // Invalid Function. Return Error.
+ FunctionNo = 0xFF;
+ gSmmCpuProtocol->WriteSaveState(gSmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RCX,
+ CpuIndex,
+ &FunctionNo);
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetAhciInt13SmmData
+//
+// Description: Saves AINT13 information passed from Non-SMM mode using
+// EFI_SMM_COMMUNICATION_PROTOCOL API. This is required for below reason:
+// 1)AhciSmmProtocol use port number, but Int13 service uses drive number.
+// 2)AhciSmmProtocol use LBA addressing on HDD, but Int13 Read/Write function
+// uses Cylinder, Header and Sector addressing on HDD.
+//
+// Input: IN EFI_HANDLE - EFI Handle
+// IN VOID* - Pointer to the EFI_SMM_SW_REGISTER_CONTEXT
+// IN VOID* - Pointer to Communication data
+// IN UINTN* - Pointer to size of Communication data
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetAhciInt13SmmData (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ UINTN i = 0, j = 0;
+ AHCI_INT13_SMM_DATA *AhciInt13SmmData = NULL;
+ SMM_AINT13_DRIVE_INFO *pDriveInfo = NULL;
+ SMM_AINT13_DRIVE_INFO *pSmmDriveInfo = NULL;
+
+ // Confirm that communication buffer contains required data
+ AhciInt13SmmData = (AHCI_INT13_SMM_DATA *)CommBuffer;
+ if (!AhciInt13SmmData || AhciInt13SmmData->DriveCount == 0) {
+ return EFI_SUCCESS;
+ }
+
+ // Save all information from AhciInt13SmmData to gDriveInfoList
+ for(j=0;j<AhciInt13SmmData->DriveCount;j++){
+
+ // Allocate SMM memory
+ Status = pSmst->SmmAllocatePool(EfiRuntimeServicesData, sizeof(SMM_AINT13_DRIVE_INFO), &pSmmDriveInfo);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+ // Copy all data
+ pDriveInfo = &(AhciInt13SmmData->DriveInfo[j]);
+ for(i=0;i<sizeof(SMM_AINT13_DRIVE_INFO);++i){
+ *((UINT8*)pSmmDriveInfo + i) = *((UINT8*)pDriveInfo + i);
+ }
+
+ // Add data to list
+ DListAdd(&gDriveInfoList, &pSmmDriveInfo->dLink);
+ }
+
+ // Locate AMI_AHCI_BUS_SMM_PROTOCOL
+ if(gAhciBusSmmProtocol == NULL) {
+ gAhciBusSmmProtocol = (AHCI_BUS_SMM_PROTOCOL*) GetSmstConfigurationTablePi(&gAhciSmmProtocolGuid);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AhciInt13SmmEntry
+//
+// Description: Driver entry point function. It does following tasks:
+// 1. Initializes global variables (gDriveInfoList, PciExpressBaseAddress etc.)
+// 2. Register SMI handler to get information passed through SmmCommunicationProtocol API.
+// 3. Register SW SMI handler to process AHCI INT13 requests.
+// 4. Locate EFI_SMM_CPU_PROTOCOL for Read/Write from/to CPU save state
+//
+// Input: EFI_HANDLE - Standard EFI Image handle
+// EFI_SYSTEM_TABLE* - Pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciInt13SmmEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch2;
+ EFI_SMM_SW_REGISTER_CONTEXT AhciInt13SwSmiContext = {AHCI_INT13_SMM_SWSMI_VALUE};
+ EFI_HANDLE AhciInt13SmmHandle;
+ EFI_HANDLE AhciInt13SmmDataHandle;
+
+ InitAmiSmmLibPi(ImageHandle, SystemTable);
+
+ InitAmiBufferValidationLib( ImageHandle, SystemTable );
+
+ // Initialize global drive info list
+ DListInit(&gDriveInfoList);
+
+ // Get the PCI Express Base Address from the PCD
+ PciExpressBaseAddress = PCIEX_BASE_ADDRESS;
+
+ // Return error if PSmstPi is NULL
+ if(pSmmBasePi == NULL || pSmstPi == NULL) {
+ ASSERT(TRUE);
+ return EFI_NOT_FOUND;
+ }
+
+ // Register SMI handler to save AHCI_INT13_SMM_DATA passed from DXE through SmmCommunicationProtocol
+ Status = pSmstPi->SmiHandlerRegister(
+ (VOID *)GetAhciInt13SmmData,
+ &gAint13SmmDataGuid,
+ &AhciInt13SmmDataHandle
+ );
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Locate EFI_SMM_SW_DISPATCH2_PROTOCOL
+ Status = pSmstPi->SmmLocateProtocol(
+ &gEfiSmmSwDispatch2ProtocolGuid,
+ NULL,
+ &SwDispatch2
+ );
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Register SMI handler to handle AHCI INT13 operations
+ Status = SwDispatch2->Register(
+ SwDispatch2,
+ AhciCommonSmmHandler,
+ &AhciInt13SwSmiContext,
+ &AhciInt13SmmHandle
+ );
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Locate EFI_SMM_CPU_PROTOCOL for Read/Write from/to CPU save state
+ Status = pSmstPi->SmmLocateProtocol(
+ &gEfiSmmCpuProtocolGuid,
+ NULL,
+ &gSmmCpuProtocol
+ );
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ // Use this buffer for unaligned read or write
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(2048), // 512 for ATA and 2048 for ATAPI, so taking 2048
+ (EFI_PHYSICAL_ADDRESS*)&(gBuffer));
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AhciInt13SmmEntryPoint
+//
+// Description: Entry point function for both DXE and SMM driver.
+//
+// Input: EFI_HANDLE - Standard EFI Image handle
+// EFI_SYSTEM_TABLE* - Pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciInt13SmmEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = InitSmmHandler(ImageHandle, SystemTable, AhciInt13SmmEntry, AhciInt13DxeEntry);
+
+ return Status;
+}
+
+#else
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/LoadedImage.h>
+#include <AmiSmm.h>
+
+EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciMmioSmmSMIHandler
+//
+// Description: Smi handler for the AHCI_MMIO_SWSMI Sw Smi
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+AhciMmioSmmSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ UINTN Cpu = (UINTN)-1;
+ UINT32 FunctionNo;
+ UINT32 AhciBaseAddress;
+ UINT32 Value;
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINTN i;
+
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+ // Found Invalid CPU number, return
+ if(Cpu == (UINTN) -1) {
+ return ;
+ }
+
+ pCpuSaveState = (EFI_SMM_CPU_SAVE_STATE*)pSmst->CpuSaveState;
+
+ FunctionNo = pCpuSaveState[Cpu].Ia32SaveState.ECX;
+ AhciBaseAddress = pCpuSaveState[Cpu].Ia32SaveState.ESI;
+
+ switch(FunctionNo) {
+ case 0x1:
+ Status=AhciMmioRead(AhciBaseAddress, &Value);
+ if( EFI_ERROR(Status) ) {
+ // Return Error.
+ pCpuSaveState[Cpu].Ia32SaveState.ECX = 0xFF;
+ break;
+ }
+ pCpuSaveState[Cpu].Ia32SaveState.EAX = Value;
+ pCpuSaveState[Cpu].Ia32SaveState.ECX = 0;
+ break;
+
+ case 0x2:
+
+ Status = AhciMmioWrite ( AhciBaseAddress, pCpuSaveState[Cpu].Ia32SaveState.EBX );
+ if( EFI_ERROR(Status) ) {
+ // Return Error.
+ pCpuSaveState[Cpu].Ia32SaveState.ECX = 0xFF;
+ break;
+ }
+ pCpuSaveState[Cpu].Ia32SaveState.ECX = 0;
+ break;
+ default:
+ // Invalid Function. Return Error.
+ pCpuSaveState[Cpu].Ia32SaveState.ECX = 0xFF;
+ break;
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AhciMmioSmmInSmmFunction
+//
+// Description: Regsiter the AHCI_MMIO_SWSMI SMI
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+// EFI System Table - Pointer to System Table
+//
+// Output: EFI_STATUS OR EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciMmioSmmInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+
+ InitAmiBufferValidationLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ SwContext.SwSmiInputValue = AHCI_INT13_SMM_SWSMI_VALUE;
+ Status = pSwDispatch->Register(pSwDispatch, AhciMmioSmmSMIHandler, &SwContext, &Handle);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AhciMmioSmmEntryPoint
+//
+// Description: Ahci MMIO access module entry Point
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+// EFI System Table - Pointer to System Table
+//
+// Output: EFI_STATUS OR EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AhciInt13SmmEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, AhciMmioSmmInSmmFunction, NULL);
+
+}
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciInt13Smm.cif b/Core/EM/Ahci/AhciInt13Smm.cif
new file mode 100644
index 0000000..a06480e
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Smm.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "AhciInt13Smm"
+ category = ModulePart
+ LocalRoot = "Core\eM\Ahci"
+ RefName = "AhciInt13Smm"
+[files]
+"AhciInt13Smm.sdl"
+"AhciInt13Smm.h"
+"AhciInt13Dxe.c"
+"AhciInt13Dxe.dxs"
+"AhciInt13Smm.c"
+"AhciInt13Smm.dxs"
+"AhciInt13Smm.mak"
+<endComponent>
+
diff --git a/Core/EM/Ahci/AhciInt13Smm.dxs b/Core/EM/Ahci/AhciInt13Smm.dxs
new file mode 100644
index 0000000..cb8a532
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Smm.dxs
@@ -0,0 +1,65 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.dxs 1 11/25/14 12:09a Kapilporwal $Revision:
+//
+// $Date: 11/25/14 12:09a $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.dxs $
+//
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: AhciInt13Smm.dxs
+//
+// Description:
+// Dependency expression for the AhciInt13Smm component
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+#include<Protocol/SmmBase2.h>
+#include<Protocol/SmmSwDispatch2.h>
+#include<Protocol/SmmCpu.h>
+#else
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/SmmBase.h>
+#endif
+
+DEPENDENCY_START
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID AND
+ EFI_SMM_CPU_PROTOCOL_GUID
+#else
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Ahci/AhciInt13Smm.h b/Core/EM/Ahci/AhciInt13Smm.h
new file mode 100644
index 0000000..efe0fad
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Smm.h
@@ -0,0 +1,155 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.h 1 11/25/14 12:09a Kapilporwal $Revision:
+//
+// $Date: 11/25/14 12:09a $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.h $
+//
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: AhciInt13Smm.h
+//
+// Description:
+// This file contains the definitions of function prototype, constant and
+// data structure for AhciInt13Smm module.
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#ifndef __AINT13_SMM_HEADER__
+#define __AINT13_SMM_HEADER__
+
+#define AHCI_INT13_SMM_DATA_GUID \
+ { 0xF4F63525, 0x281E, 0x4040, 0xA3, 0x13, 0xC1, 0xD6, 0x76, 0x63, 0x84, 0xBE }
+
+// PciExpressBaseAddress uses PCIEX_BASE_ADDRESS
+#define PCI_CFG_ADDR(bus,dev,func,reg) \
+ ((VOID*)(UINTN) (PciExpressBaseAddress + ((bus) << 20) + ((dev) << 15) + ((func) << 12) + reg))
+
+#define AHCI_CONTROLLER 0x06
+#define MASS_STORAGE 0x01
+#define PCI_ABAR 0x24
+#define HDD_BLOCK_SIZE 512
+
+#define READ_SECTORS 0x20
+#define READ_SECTORS_EXT 0x24
+#define READ_MULTIPLE 0xC4
+#define READ_MULTIPLE_EXT 0x29
+#define WRITE_SECTORS 0x30
+#define WRITE_SECTORS_EXT 0x34
+#define WRITE_MULTIPLE 0xC5
+#define WRITE_MULTIPLE_EXT 0x39
+#define READ_DMA 0xC8
+#define READ_DMA_EXT 0x25
+#define WRITE_DMA 0xCA
+#define WRITE_DMA_EXT 0x35
+
+// Int13 parameter definition
+// function(AH) definition
+#define READ_SECTOR 0x02
+#define WRITE_SECTOR 0x03
+#define EXT_READ 0x42
+#define EXT_WRITE 0x43
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+EFI_STATUS AhciInt13DxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+EFI_STATUS AhciInt13SmmEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+);
+
+// Prevent compiler from padding the structures
+#pragma pack(1)
+
+typedef struct {
+ DLINK dLink;
+ UINT8 DriveNum; // Int13's Drive Number(dl)
+ UINT8 PMPortNum; // PMPort number on HBA
+ UINT8 PortNum; // Port number on HBA
+ UINT8 BusNo; // Bus# of Controller
+ UINT8 DevNo; // Device# of Controller
+ UINT8 FuncNo; // Function# of Controller
+ UINT8 DeviceType; // 0 ATA, 1 ATAPI
+ UINT8 Lun; // ATAPI LUN
+ UINT16 BlockSize; // ATAPI Block Size
+ UINT16 wMAXCYL; // maximum no. of cylinders..INT13 interface. (logical)
+ UINT8 bMAXHN; // maximum no. of heads..INT13 interface. (logical)
+ UINT8 bMAXSN; // no. of sectors per track..INT13 interface. (logical)
+ UINT16 wLBACYL; // #of cylinders drive is configured for. (physical)
+ UINT8 bLBAHD; // #of heads drive is configured for. (physical)
+ UINT8 bLBASPT; // #of sectors per track drive is configured for. (physical)
+ UINT8 WCommand; // write command
+ UINT8 RCommand; // read command
+} SMM_AINT13_DRIVE_INFO;
+
+typedef struct {
+ UINT8 DriveCount;
+ SMM_AINT13_DRIVE_INFO DriveInfo[32]; // Sync array length with SATA_PORT_COUNT of Aint13.h
+} AHCI_INT13_SMM_DATA;
+
+typedef struct {
+ UINT8 PackageSize; // size of package(10h or 18h)
+ UINT8 Reserved; // reserved
+ UINT16 XferSector; // transfer sectors
+ UINT32 Buffer; // 32 bit address transfer buffer
+ UINT64 StartLba; // Start LBA sectors;
+ UINT64 Buffer64; // 64 bit address transfer buffer(option);
+} DISK_ADDRESS_PACKAGE;
+
+// DO NOT MODIFY BELOW STRUCTURE
+// NOTE: If modified, AINT13.ASM (of AI13.bin) also needs to be modified
+typedef struct {
+ UINT32 StackEDI;
+ UINT32 StackESI;
+ UINT32 StackEBP;
+ UINT32 StackESP;
+ UINT32 StackEBX;
+ UINT32 StackEDX;
+ UINT32 StackECX;
+ UINT32 StackEAX;
+ UINT16 StackDS;
+ UINT16 StackES;
+ UINT16 StackGS;
+ UINT16 StackFS;
+ EFI_FLAGS_REG StackFlags;
+} INT13_TO_SMI_EXREGS;
+
+#pragma pack()
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciInt13Smm.mak b/Core/EM/Ahci/AhciInt13Smm.mak
new file mode 100644
index 0000000..bb6a422
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Smm.mak
@@ -0,0 +1,72 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.mak 2 12/08/14 5:39a Anbuprakashp $Revision:
+#
+# $Date: 12/08/14 5:39a $Log: /Alaska/SOURCE/Modules/AHCI/INT13/AhciInt13Smm.mak $
+#
+#
+#
+#****************************************************************************
+
+#<AMI_FHDR_START>
+#****************************************************************************
+#
+# Name: AhciInt13Smm.mak
+#
+# Description:
+# MAK file for the AhciInt13Smm component
+#****************************************************************************
+#<AMI_FHDR_END>
+
+all : AhciInt13Smm
+AhciInt13Smm : $(BUILD_DIR)\AhciInt13Smm.mak AhciInt13SmmBin
+
+$(BUILD_DIR)\AhciInt13Smm.mak : $(AHCI_INT13_SMM_DIR)\AhciInt13Smm.cif $(AHCI_INT13_SMM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AHCI_INT13_SMM_DIR)\AhciInt13Smm.cif $(CIF2MAK_DEFAULTS)
+
+AHCI_INT13_SMM_INCLUDES = $(AMIDXELIB) \
+ $(BUILD_DIR)\AmiBufferValidationLib.lib
+
+AhciInt13SmmBin : $(AHCI_INT13_SMM_INCLUDES)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AhciInt13Smm.mak all\
+ GUID=501f30e9-d14f-47da-ae60-b101e4189d07\
+ ENTRY_POINT=AhciInt13SmmEntryPoint\
+!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A && $(CORE_COMBINED_VERSION) >= 0x4028B
+ TYPE=DXESMM_DRIVER PE_TYPE=RT_DRIVER\
+ DEPEX1=$(AHCI_INT13_SMM_DIR)\AhciInt13Smm.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ DEPEX2=$(AHCI_INT13_SMM_DIR)\AhciInt13Dxe.dxs \
+ DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \
+!ELSE
+ TYPE=BS_DRIVER\
+ DEPEX1=$(AHCI_INT13_SMM_DIR)\AhciInt13Smm.dxs \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+!ENDIF
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Ahci/AhciInt13Smm.sdl b/Core/EM/Ahci/AhciInt13Smm.sdl
new file mode 100644
index 0000000..b5ad133
--- /dev/null
+++ b/Core/EM/Ahci/AhciInt13Smm.sdl
@@ -0,0 +1,58 @@
+TOKEN
+ Name = "AHCI_INT13_SMM_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable SMM support for AHCI Int13/MMIO operations in Project. Currently only INT13 Read/Write functions are supported."
+ TokenType = Boolean
+ Master = Yes
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "AHCI_INT13_SMM_DIR"
+End
+
+MODULE
+ Help = "Includes AhciInt13Smm.mak"
+ File = "AhciInt13Smm.mak"
+End
+
+TOKEN
+ Name = "AHCI_INT13_SMM_SWSMI_VALUE"
+ Value = "043h"
+ Help = "Value to write into SMI command register to generate software SMI for AHCI INT13/MMIO operations."
+ TokenType = Integer
+ TargetH = Yes
+ TargetEQU = Yes
+ Range = "0 - 0xff"
+End
+
+TOKEN
+ Name = "AINT13_AVOID_MULTIPLE_SMI"
+ Value = "0"
+ Help = "Execute INT13 Read/Write functions completely in SMM and avoid multiple SMI generation for single AHCI INT13 function/call."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x1000A"
+ Token = "CORE_COMBINED_VERSION" ">=" "0x4028B"
+ Token = "SMM_COMMUNICATE_SUPPORT" "=" "1"
+ Token = "AhciSmm_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "BIG_REAL_MODE_MMIO_ACCESS"
+ Value = "0"
+ Help = "1- Access the MMIO region by switching to big real mode, 0 - Access the MMIO using SMI handler"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AhciInt13Smm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/Ahci/AhciSmm/AhciSmm.c b/Core/EM/Ahci/AhciSmm/AhciSmm.c
new file mode 100644
index 0000000..730c1d1
--- /dev/null
+++ b/Core/EM/Ahci/AhciSmm/AhciSmm.c
@@ -0,0 +1,2217 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.c 12 11/24/14 11:56p Kapilporwal $
+//
+// $Revision: 12 $
+//
+// $Date: 11/24/14 11:56p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.c $
+//
+// 12 11/24/14 11:56p Kapilporwal
+// [TAG] EIP191939
+// [Category] Improvement
+// [Description] Issue about BIG_REAL_MODE_MMIO_ACCESS of AHCI module
+// [Files] AI13.bin
+// AHCIACC.ASM
+// AhciInt13Dxe.c
+// AhciInt13Dxe.dxs
+// AhciInt13Smm.c
+// AhciInt13Smm.cif
+// AhciInt13Smm.dxs
+// AhciInt13Smm.h
+// AhciInt13Smm.mak
+// AhciInt13Smm.sdl
+// AInt13.c
+// Aint13.cif
+// AInt13.h
+// AhciSmm.c
+// AhciSmm.h
+// AhciSmmProtocol.h
+//
+// 11 8/11/14 6:47a Anbuprakashp
+// [TAG] EIP178239
+// [Category] Improvement
+// [Description] S3 Resume fails when HDD password is set where platform
+// have more than one AHCI controller
+// [Files] AhciSmm.c,AhciSmm.sdl,IDESMM.c
+//
+// 10 8/17/12 3:14a Srikantakumarp
+// [TAG] EIP95863
+// [Category] Bug Fix
+// [Symptom] AhciSmm doesnt save and restore the upper 32bits of FBU and
+// CLBU
+// [RootCause] As Windows uses the 64bit address for FIS Base Address
+// and Command List Base Address, and AHCISMM driver doesn't take care of
+// the upper 32bit value of those which cause the failure in AhciSMM
+// driver.
+// [Solution] Save and Restore the upper 32bits of FBU and CLBU in
+// AhciSmm Driver.
+// [Files] AhciController.c, AhciSmm.c
+//
+// 9 11/14/11 3:13a Rameshr
+// [TAG] EIP73137
+// [Category] Improvement
+// [Description] Modified the code to use correct status regsiter and
+// bits to check the device status.
+// [Files] AhciSmm.c
+//
+// 8 3/15/11 4:12a Rameshr
+// [TAG]- EIP 51884
+// [Category]- New Feature
+// [Description]- Added packet command function in AhciSMM for sending
+// command in SMM handler
+// [Files]- AhciSmm.c, AhciSmm.h, AhciSmmProtocols.h
+//
+// 7 2/11/11 4:11a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSmm.mak
+// AhciSmm.dxs
+// AhciSmm.c
+// AhciSmm.h
+//
+// 6 5/07/10 2:32p Krishnakumarg
+// Updated the date in AMI header
+//
+// 5 5/07/10 12:37p Krishnakumarg
+// Update for coding standard
+//
+// 4 11/13/09 6:05a Rameshr
+// AhciBaseAddress initilization moved from entryfunction to
+// AhciSmmInitPortOnS3Resume.
+// EIP: 29827
+//
+// 3 11/02/09 6:15p Davidd
+// Correct S3 resume hanging problem in AHCI mode (EIP 29827).
+//
+// 2 6/05/09 2:45p Rameshr
+// x64 mode compilation error Resolved.
+// Eip:22710
+//
+// 1 4/28/09 6:39p Rameshr
+// Initial Check-in
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//--------------------------------------------------------------------------
+//
+// Name: AHCISmm.c
+//
+// Description: AHCISmm funtion implementation.
+//
+//--------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//---------------------------------------------------------------------------
+// Include files
+//---------------------------------------------------------------------------
+//**********************************************************************
+
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\IdeControllerInit.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PIDEBus.h"
+#include <Protocol\AhciSmmProtocol.h>
+#include <Protocol\PAhciBus.h>
+#include "AhciSmm.h"
+#include <Protocol\SmmBase.h>
+#include <AmiSmm.h>
+#include "AhciController.h"
+
+#define SCC_AHCI_CONTROLLER 0x06
+#define SCC_RAID_CONTROLLER 0x04
+#define PCI_SCC 0x000A // Sub Class Code Register
+
+
+EFI_GUID gAhciSmmProtocolGuid=AHCI_SMM_PROTOCOL_GUID;
+UINT32 gCommandListBaseAddress;
+UINT32 gFisBaseAddress;
+UINT32 gCommandListBaseAddress2;
+UINT32 gFisBaseAddress2;
+
+AHCI_BUS_SMM_PROTOCOL AhciSmm;
+BOOLEAN gPortReset = FALSE; // Avoid Re-entry
+UINT8 *SenseData=NULL;
+
+
+#if defined(EFI64) || defined(EFIx64)
+static UINT64
+DivU64x32 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor,
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result = Dividend/Divisor;
+ if (Remainder) *Remainder=Dividend%Divisor;
+ return Result;
+}
+
+#else
+static UINT64
+DivU64x32 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN *Remainder OPTIONAL
+ )
+{
+ UINT64 Result;
+ UINT32 Rem;
+ _asm
+ {
+ mov eax, dword ptr Dividend[0]
+ mov edx, dword ptr Dividend[4]
+ mov esi, Divisor
+ xor edi, edi ; Remainder
+ mov ecx, 64 ; 64 bits
+Div64_loop:
+ shl eax, 1 ;Shift dividend left. This clears bit 0.
+ rcl edx, 1
+ rcl edi, 1 ;Shift remainder left. Bit 0 = previous dividend bit 63.
+
+ cmp edi, esi ; If Rem >= Divisor, don't adjust
+ cmc ; else adjust dividend and subtract divisor.
+ sbb ebx, ebx ; if Rem >= Divisor, ebx = 0, else ebx = -1.
+ sub eax, ebx ; if adjust, bit 0 of dividend = 1
+ and ebx, esi ; if adjust, ebx = Divisor, else ebx = 0.
+ sub edi, ebx ; if adjust, subtract divisor from remainder.
+ loop Div64_loop
+
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov Rem, edi
+ }
+
+ if (Remainder) *Remainder = Rem;
+
+ return Result;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Stall
+//
+// Description: Stalls for the Required Amount of MicroSeconds
+//
+// Input:
+// UINTN Usec // Number of microseconds to delay
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SmmStall (
+ UINTN Usec
+ )
+{
+ UINTN Counter, i;
+ UINT32 Data32, PrevData;
+ UINTN Remainder;
+
+ Counter = (UINTN)DivU64x32 ((Usec * 10), 3, &Remainder);
+
+ if (Remainder != 0) {
+ Counter++;
+ }
+
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ZeromemorySmm
+//
+// Description: Clears the buffer
+//
+// Input: void *Buffer,
+// UINTN Size
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void
+ZeroMemorySmm (
+ void *Buffer,
+ UINTN Size
+ )
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitforPMMemSet
+//
+// Description: Wait for memory to be set to the test value.
+//
+// Input:
+// SATA_DEVICE_INTERFACE *SataDevInterface,
+// PMPort
+// Register
+// MaskValue - The mask value of memory
+// TestValue - The test value of memory
+// WaitTimeInMs - The time out value for wait memory set
+//
+// Output: EFI_SUCCESS - HBA reset successfully.
+// EFI_DEVICE_ERROR - HBA failed to complete hardware reset.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitforPMMemSet (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT8 PMPort,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 TestValue,
+ IN UINT32 WaitTimeInMs
+)
+{
+ UINT32 Data32;
+
+ while(WaitTimeInMs!=0){
+ ReadWritePMPort (SataDevInterface, PMPort, Register, &Data32, FALSE);
+ if((Data32 & AndMask) == TestValue) {return EFI_SUCCESS;}
+ SmmStall (1000); // 1Msec
+ WaitTimeInMs--;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitForMemSet
+//
+// Description: Wait for memory to be set to the test value.
+//
+// Input: MemTestAddr - The memory address to test
+// MaskValue - The mask value of memory
+// TestValue - The test value of memory
+// WaitTimeInMs - The time out value for wait memory set
+//
+// Output: EFI_SUCCESS - HBA reset successfully.
+// EFI_DEVICE_ERROR - HBA failed to complete hardware reset.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitForMemSet (
+ IN UINT32 BaseAddr,
+ IN UINT8 Port,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 TestValue,
+ IN UINT32 WaitTimeInMs
+)
+{
+ UINT8 Delay;
+ while(WaitTimeInMs!=0){
+ for ( Delay = 10; Delay > 0; Delay--) {
+ if(((HBA_PORT_REG32(BaseAddr, Port, Register)) & AndMask) == TestValue) {return EFI_SUCCESS;}
+ SmmStall (100); // 100 usec * 10 = 1Msec
+ }
+ WaitTimeInMs--;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitForMemClear
+//
+// Description: Wait for memory to be set to the test value.
+//
+// Input: MemTestAddr - The memory address to test
+// MaskValue - The mask value of memory
+// WaitTimeInMs - The time out value for wait memory set
+//
+// Output: EFI_SUCCESS - HBA reset successfully.
+// EFI_DEVICE_ERROR - HBA failed to complete hardware reset.
+//
+// Modified:
+//
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitForMemClear (
+ IN UINT32 BaseAddr,
+ IN UINT8 Port,
+ IN UINT8 Register,
+ IN UINT32 AndMask,
+ IN UINT32 WaitTimeInMs
+)
+{
+ UINT8 Delay;
+ while(WaitTimeInMs!=0){
+ for ( Delay = 10; Delay > 0; Delay--) {
+ if(!((HBA_PORT_REG32(BaseAddr, Port, Register)) & AndMask)) {return EFI_SUCCESS;}
+ SmmStall (100); // 100 usec * 10 = 1Msec
+ }
+ WaitTimeInMs--;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadSCRRegister
+//
+// Description:
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+// IN UINT8 Register (0 : SStatus 1: SError 2: SControl)
+//
+// Output:
+// UINT32
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check if the device is connected directly to the port
+// 2. if yes, read to the AHCI Controller else write to the Port Multiplier register.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+ReadSCRRegister (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort,
+ IN UINT8 Register
+)
+{
+
+ UINT32 Data32 = 0;
+ UINT32 Reg = HBA_PORTS_SSTS;
+
+ if (PMPort != 0xFF) {
+ ReadWritePMPort (SataDevInterface, PMPort, Register, &Data32, FALSE);
+ }
+ else {
+ if (Register == 1) Reg = HBA_PORTS_SCTL;
+ if (Register == 2) Reg = HBA_PORTS_SERR;
+ Data32 = HBA_PORT_REG32 (SataDevInterface->AhciBaseAddress, Port, Reg);
+ }
+
+ return Data32;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteSCRRegister
+//
+// Description: Write to SCONTROL/Serror/SStatus register
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+// IN UINT8 Register, (0 : SStatus 1: SError 2: SControl)
+// IN UINT32 Data32
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check if the device is connected directly to the port
+// 2. if yes, write to the AHCI Controller else write to the Port Multiplier register
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WriteSCRRegister (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort,
+ IN UINT8 Register,
+ IN UINT32 Data32
+)
+{
+
+ UINT32 Reg = HBA_PORTS_SSTS;
+
+ if (PMPort != 0xFF) {
+ ReadWritePMPort (SataDevInterface, PMPort, Register, &Data32, TRUE);
+ }
+ else {
+ if (Register == 2) Reg = HBA_PORTS_SCTL;
+ if (Register == 1) Reg = HBA_PORTS_SERR;
+ HBA_PORT_REG32_OR (SataDevInterface->AhciBaseAddress, Port, Reg, Data32);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitforCommandComplete
+//
+// Description: Wait till cmd completes
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_TYPE CommandType,
+// IN UINTN TimeOut
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check for SError bits. If set return error.
+// 2. For PIO IN/Out and Packet IN/OUT command wait till PIO Setup FIS is received
+// 3. If D2H register FIS is received, exit the loop.
+// 4. Check for SError and TFD bits.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WaitforCommandComplete (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN COMMAND_TYPE CommandType,
+ IN UINTN TimeOut
+)
+{
+
+ UINT32 AhciBaseAddr = (UINT32)SataDevInterface->AhciBaseAddress;
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT32 Data32_SERR, Data32_IS, i;
+ BOOLEAN PxSERR_ERROR = FALSE, PIO_SETUP_FIS = FALSE;
+ volatile AHCI_RECEIVED_FIS *FISReceiveAddress = (AHCI_RECEIVED_FIS *)SataDevInterface->PortFISBaseAddr;
+ UINTN TimeOutCount = TimeOut;
+
+ for(i = 0; i < TimeOutCount * 2; i++, SmmStall(500)) { // 500usec
+
+ //
+ // Check for Error bits
+ //
+ Data32_SERR = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SERR);
+ if (Data32_SERR & HBA_PORTS_ERR_CHK) {
+ PxSERR_ERROR = TRUE;
+ break;
+ }
+
+ //
+ // Check for Error bits
+ //
+ Data32_IS = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_IS);
+ if (Data32_IS & HBA_PORTS_IS_ERR_CHK) {
+ PxSERR_ERROR = TRUE;
+ break;
+ }
+
+ switch (CommandType) {
+
+ case PIO_DATA_IN_CMD:
+ case PIO_DATA_OUT_CMD:
+ case PACKET_PIO_DATA_IN_CMD:
+ case PACKET_PIO_DATA_OUT_CMD:
+
+ //
+ // check if PIO setup received
+ //
+ if(FISReceiveAddress->Ahci_Psfis[0] == FIS_PIO_SETUP) {
+ FISReceiveAddress->Ahci_Psfis[0] = 0;
+ TimeOutCount = TimeOut;
+ PIO_SETUP_FIS = TRUE;
+ }
+ break;
+ default:
+ break;
+
+ }
+
+ //
+ // check if D2H register FIS is received
+ //
+ if(FISReceiveAddress->Ahci_Rfis[0] == FIS_REGISTER_D2H) break;
+
+ //
+ // For PIO Data in D2H register FIS is not received. So rely on BSY bit
+ //
+ if ((CommandType == PIO_DATA_IN_CMD) && PIO_SETUP_FIS &&
+ !((HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD) &
+ (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_DRQ)))){
+ break;
+ }
+ }
+
+ if (PxSERR_ERROR) {
+
+ //
+ // clear the status and return error
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // check if CI register is zero
+ //
+ if (HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_CI)){
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // check for status bits
+ //
+ if (HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD) & (HBA_PORTS_TFD_ERR | HBA_PORTS_TFD_DRQ)){
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StartController
+//
+// Description:
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT32 CIBitMask
+//
+// Output:
+// EFI_STATUS
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Clear Status register
+// 2. Enable FIS and CR running bit
+// 3. Enable Start bit
+// 4. Update CI bit mask
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+StartController (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT32 CIBitMask
+)
+{
+
+ UINT32 AhciBaseAddr = (UINT32)(SataDevInterface->AhciBaseAddress);
+ UINT8 Port = SataDevInterface->PortNumber;
+
+ //
+ // Clear Status
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ //
+ // Enable FIS Receive
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE);
+
+ //
+ // Wait till FIS is running
+ //
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ //
+ // Clear FIS Receive area
+ //
+ ZeroMemorySmm ((VOID *)SataDevInterface->PortFISBaseAddr, RECEIVED_FIS_SIZE);
+
+ //
+ // Enable ST
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_ST);
+
+ //
+ // Enable Command Issued
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CI, CIBitMask);
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HandlePortComReset
+//
+// Description: Check if COM Reset is successful or not
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 PMPort,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadSCRRegister, WriteSCRRegister
+//
+// Notes:
+// 1. Check if Link is active. If not return error.
+// 2. If Link is present, wait for PhyRdy Change bit to be set.
+// 3. Clear SError register
+// 4. Wait for D2H register FIS
+// 5. Check the Status register for errors.
+// 6. If COMRESET is success wait for sometime if the device is ATAPI or GEN1
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+HandlePortComReset(
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 PMPort
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ BOOLEAN DeviceDetected = FALSE;
+ UINT32 Data32, i, Delay, SStatusData;
+ UINT32 AhciBaseAddr = (UINT32)(SataDevInterface->AhciBaseAddress);
+ volatile AHCI_RECEIVED_FIS *FISAddress;
+
+ //
+ // Check if detection is complete
+ //
+ for (i = 0; i < HBA_PRESENCE_DETECT_TIMEOUT; i++){ // Total delay 10msec
+ SStatusData = ReadSCRRegister (SataDevInterface, Port, PMPort, 0); // SStatus
+ SStatusData &= HBA_PORTS_SSTS_DET_MASK;
+ if ((SStatusData == HBA_PORTS_SSTS_DET_PCE) || (SStatusData == HBA_PORTS_SSTS_DET)) {
+ DeviceDetected = TRUE;
+ break;
+ }
+ SmmStall (1000); // 1msec
+ }
+
+ if (DeviceDetected) {
+
+ //
+ // Wait till PhyRdy Change bit is set
+ //
+ if (PMPort == 0xFF) {
+ Status = WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_SERR,
+ HBA_PORTS_SERR_EX,
+ HBA_PORTS_SERR_EX,
+ ATAPI_BUSY_CLEAR_TIMEOUT);
+ }
+ else {
+ Status = WaitforPMMemSet (SataDevInterface, PMPort, PSCR_1_SERROR,
+ HBA_PORTS_SERR_EX, HBA_PORTS_SERR_EX, ATAPI_BUSY_CLEAR_TIMEOUT);
+ }
+
+ //
+ // Clear Status register
+ //
+ FISAddress = * ((AHCI_RECEIVED_FIS **)(HBA_PORT_REG_BASE(Port) + AhciBaseAddr + HBA_PORTS_FB));
+ for (i = 0; i < ATAPI_BUSY_CLEAR_TIMEOUT; ) {
+ WriteSCRRegister (SataDevInterface, Port, PMPort, 1, HBA_PORTS_ERR_CLEAR); //SError
+
+ if(FISAddress->Ahci_Rfis[0] == FIS_REGISTER_D2H){
+ break;
+ }
+
+ //
+ // 1msec Strange. Delay is needed for read to succeed.
+ //
+ SmmStall (1000); // 1msec (1000);
+
+ //
+ // For device behind PM Port, there is a delay in
+ // writing to the register. So count can be decreased.
+ //
+ if (PMPort != 0xFF) {i+= 100;}
+ else { i++; }
+ }
+
+
+ for ( Delay = 0; Delay < (ATAPI_BUSY_CLEAR_TIMEOUT * 10); Delay++) {
+ if(!((HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD)) & HBA_PORTS_TFD_BSY)) {break;}
+ if((HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_IS)) & (BIT30 + BIT29 + BIT28 + BIT27 + BIT26)) {break;}
+ SmmStall (1000); // 1msec (100); // 100 usec * 10 = 1Msec
+ }
+
+ //
+ // check for errors
+ //
+ Data32 = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_TFD);
+ if (Data32 & (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_ERR)) Status = EFI_DEVICE_ERROR;
+
+ Data32 = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_IS);
+ if (Data32 & (BIT30 + BIT29 + BIT28 + BIT27 + BIT26)) Status = EFI_DEVICE_ERROR;
+
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GeneratePortReset
+//
+// Description: Issue a Port Reset
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 CurrentPort,
+// IN UINT8 Speed,
+// IN UINT8 PowerManagement
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadWritePMPort, HandlePortComReset
+//
+// Notes:
+// 1. Issue port reset by setting DET bit in SControl register
+// 2. Call HandlePortComReset to check the status of the reset.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GeneratePortReset (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ UINT8 Port,
+ UINT8 PMPort,
+ UINT8 Speed,
+ UINT8 PowerManagement
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 AhciBaseAddr = (UINT32) SataDevInterface->AhciBaseAddress;
+ volatile AHCI_RECEIVED_FIS *FISAddress = *((AHCI_RECEIVED_FIS **)(HBA_PORT_REG_BASE(Port) + AhciBaseAddr + HBA_PORTS_FB));
+ UINT32 Data32;
+
+ if (!FISAddress){
+ return EFI_DEVICE_ERROR; // FIS receive address is not programmed.
+ }
+
+ if (gPortReset){
+ return EFI_SUCCESS;
+ }
+
+ gPortReset = TRUE;
+
+ //
+ // Disable Start bit
+ //
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~HBA_PORTS_CMD_ST);
+
+ //
+ // Wait till CR is cleared
+ //
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_CR_CLEAR_TIMEOUT);
+
+ //
+ // Clear Status register
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ if (PMPort != 0xFF) {
+ Data32 = HBA_PORTS_ERR_CLEAR;
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_1_SERROR, &Data32, TRUE);
+ }
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ //
+ // Enable FIS Receive Enable
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE);
+
+ //
+ // Wait till FIS is running and then clear the data area
+ //
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+
+ FISAddress->Ahci_Rfis[0] = 0;
+
+ if (PMPort == 0xFF) {
+
+ //
+ // Issue Port COMRESET
+ //
+ HBA_PORT_REG32_AND_OR (AhciBaseAddr, Port, HBA_PORTS_SCTL, 0xFFFFF000,
+ HBA_PORTS_SCTL_DET_INIT + (Speed << 4) + (PowerManagement << 8));
+ SmmStall (1000); // 1msec
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_SCTL, ~HBA_PORTS_SCTL_DET_MASK);
+ }
+ else {
+ Data32 = HBA_PORTS_SCTL_DET_INIT + (Speed << 4) + (PowerManagement << 8);
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_2_SCONTROL, &Data32, TRUE);
+ SmmStall (1000); // 1msec
+ Data32 = (Speed << 4) + (PowerManagement << 8);
+ ReadWritePMPort (SataDevInterface, PMPort, PSCR_2_SCONTROL, &Data32, TRUE);
+ }
+
+ Status = HandlePortComReset(SataDevInterface, Port, PMPort);
+
+ //
+ // Disable FIS Receive Enable
+ //
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~HBA_PORTS_CMD_FRE);
+
+ gPortReset = FALSE;
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StopController
+//
+// Description: Stop FIS and CR
+//
+// Input:
+// IN AHCI_BUS_PROTOCOL *AhciBusInterface,
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: GeneratePortReset
+//
+// Notes:
+// 1. clear ST bit and wait till CR bits gets reset
+// 2. if not generate Port reset
+// 3. Clear FIS running bit.
+// 4. Clear status register
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+StopController(
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN BOOLEAN StartOrStop
+)
+{
+
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+ UINT32 AhciBaseAddr = (UINT32)(SataDevInterface->AhciBaseAddress);
+ EFI_STATUS Status;
+ UINT32 PortFISBaseAddr = SataDevInterface->PortFISBaseAddr;
+ UINT32 CommandListBaseAddress = SataDevInterface->PortCommandListBaseAddr;
+
+ if(StartOrStop) {
+ gCommandListBaseAddress=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB);
+ gFisBaseAddress=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_FB);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB,CommandListBaseAddress);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,PortFISBaseAddr);
+
+ //
+ // Saving the Upper 32 bits of FIS and Command List Registers
+ //
+ gCommandListBaseAddress2=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU);
+ gFisBaseAddress2=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU,0);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU,0);
+ }
+
+ //
+ // Clear Start
+ //
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port, HBA_PORTS_CMD, ~(HBA_PORTS_CMD_ST));
+
+ //
+ // Make sure CR is 0 with in 500msec
+ //
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_CR_CLEAR_TIMEOUT);
+
+ if (EFI_ERROR(Status)) {
+ Status = GeneratePortReset(SataDevInterface, Port, PMPort,
+ HBA_PORTS_SCTL_SPD_NSNR, HBA_PORTS_SCTL_IPM_DIS);
+ };
+
+ if (EFI_ERROR(Status)) {
+ goto StopController_ErrorExit;
+ }
+
+ if (EFI_ERROR(Status)){
+ return Status;
+ }
+
+ //
+ // Clear FIS receive enable.
+ //
+ HBA_PORT_REG32_AND (AhciBaseAddr, Port,
+ HBA_PORTS_CMD, ~(HBA_PORTS_CMD_FRE));
+ //
+ // Make sure FR is 0 with in 500msec
+ //
+ Status = WaitForMemClear(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ if (EFI_ERROR(Status)) {
+ goto StopController_ErrorExit;
+ }
+
+ //
+ // Clear Status register
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR);
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ if(!StartOrStop) {
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB,gCommandListBaseAddress);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,gFisBaseAddress);
+
+ //
+ // Restoring the Upper 32 bits of FIS and Command List Registers
+ //
+
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU,gCommandListBaseAddress2);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU,gFisBaseAddress2);
+ }
+
+ return EFI_SUCCESS;
+
+StopController_ErrorExit:
+
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLB,gCommandListBaseAddress);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,gFisBaseAddress);
+
+ //
+ // Restoring the Upper 32 bits of FIS and Command List Registers
+ //
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_CLBU,gCommandListBaseAddress2);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FBU,gFisBaseAddress2);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadytoAcceptCmd
+//
+// Description: Check if the device is ready to accept cmd.
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: GeneratePortReset, ReadWritePMPort
+//
+// Notes:
+// 1. Check the device is ready to accept the command. BSY and DRQ
+// should be de-asserted.
+// 2. If set, generate Port reset
+// 3. In case Port Multiplier is connected to the port, enable all
+// the ports of the Port Multiplier.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadytoAcceptCmd (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 AhciBaseAddr = (UINT32)(SataDevInterface->AhciBaseAddress);
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+ UINT32 Data32 = 0, Init_SStatus = 0;
+
+ //
+ // Is the Device ready to accept the command
+ //
+ if (HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD) & (HBA_PORTS_TFD_BSY | HBA_PORTS_TFD_DRQ)){
+ Data32 = HBA_PORT_REG32 (AhciBaseAddr, Port, HBA_PORTS_SCTL);
+ Data32 &= 0xFF0;
+
+ //
+ // make sure the status we read is for the right port
+ //
+ Status = GeneratePortReset(SataDevInterface, Port, 0xFF,
+ (UINT8)((Data32 & 0xF0) >> 4), (UINT8)(Data32 >> 8));
+ if (EFI_ERROR(Status)) return Status;
+
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildCommandList
+//
+// Description: Builds command list
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN UINT32 CommandTableBaseAddr
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Update CommandList bits
+// 2. Not all fields like Ahci_Cmd_A are updated.
+// 3. Port number is set to 0xF (Control port) if PM Port number is 0xFF.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildCommandList (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN UINT32 CommandTableBaseAddr
+)
+{
+ UINT8 PMPort = SataDevInterface->PMPortNumber;
+
+ ZeroMemorySmm (CommandList, sizeof(AHCI_COMMAND_LIST));
+ CommandList->Ahci_Cmd_A = SataDevInterface->DeviceType == ATAPI ? 1 : 0; // set elsewhere
+ CommandList->Ahci_Cmd_P = 0;
+ CommandList->Ahci_Cmd_R = 0;
+ CommandList->Ahci_Cmd_B = 0;
+ CommandList->Ahci_Cmd_Rsvd1 = 0;
+ CommandList->Ahci_Cmd_PMP = PMPort == 0xFF ? 0x0 : SataDevInterface->PMPortNumber;
+ CommandList->Ahci_Cmd_PRDTL = 0;
+ CommandList->Ahci_Cmd_PRDBC = 0;
+ CommandList->Ahci_Cmd_CTBA = CommandTableBaseAddr;
+ CommandList->Ahci_Cmd_CTBAU = 0;
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyMemSmm
+//
+// Description: Copy Length bytes from Source to Destination.
+//
+// Input:
+// IN VOID *Destination,
+// IN VOID *Source,
+// IN UINTN Length
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CopyMemSmm (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+
+ if (Source < Destination) {
+ Destination8 = (CHAR8 *) Destination + Length - 1;
+ Source8 = (CHAR8 *) Source + Length - 1;
+ while (Length--) {
+ *(Destination8--) = *(Source8--);
+ }
+ } else {
+ Destination8 = (CHAR8 *) Destination;
+ Source8 = (CHAR8 *) Source;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildAtapiCMD
+//
+// Description:
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN AHCI_COMMAND_TABLE *Commandtable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Copy Packet data to command table
+// 2. Set Atapi bit in Command List
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildAtapiCMD(
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN AHCI_COMMAND_TABLE *Commandtable
+)
+{
+
+ CopyMemSmm(&(Commandtable->AtapiCmd),&(CommandStructure.AtapiCmd),sizeof(AHCI_ATAPI_COMMAND));
+
+ if (Commandtable->CFis.Ahci_CFis_Cmd == PACKET_COMMAND){ // Is it a packet command?
+ CommandList->Ahci_Cmd_A = 1;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildPRDT
+//
+// Description: Build PRDT table
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN AHCI_COMMAND_TABLE *Commandtable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Build as many PRDT table entries based on ByteCount.
+// 2. Set the I flag for the lasr PRDT table.
+// 3. Update PRDT table lenght in CommandList
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildPRDT (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN AHCI_COMMAND_TABLE *Commandtable
+)
+{
+
+ UINT32 ByteCount = CommandStructure.ByteCount;
+ UINT16 Prdtlength = 0;
+ AHCI_COMMAND_PRDT *PrdtTable = &(Commandtable->PrdtTable);
+
+ for (;ByteCount; (UINT8 *)PrdtTable += sizeof(AHCI_COMMAND_PRDT)){
+ PrdtTable->Ahci_Prdt_DBA = (UINT32)CommandStructure.Buffer;
+ PrdtTable->Ahci_Prdt_DBC = ByteCount >= PRD_MAX_DATA_COUNT ? (PRD_MAX_DATA_COUNT - 1) : (ByteCount - 1);
+ ByteCount -= (PrdtTable->Ahci_Prdt_DBC + 1);
+ PrdtTable->Ahci_Prdt_I = 0;
+ Prdtlength+= sizeof(AHCI_COMMAND_PRDT);
+ (UINT8 *)CommandStructure.Buffer += PrdtTable->Ahci_Prdt_DBC + 1;
+ }
+
+ //
+ // Set I flag only for the last entry.
+ //
+ (UINT8 *)PrdtTable -= sizeof(AHCI_COMMAND_PRDT);
+ PrdtTable->Ahci_Prdt_I = 1;
+ CommandList->Ahci_Cmd_PRDTL = Prdtlength / sizeof(AHCI_COMMAND_PRDT);
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BuildCommandFIS
+//
+// Description: Build Command FIS
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// IN AHCI_COMMAND_LIST *CommandList,
+// IN AHCI_COMMAND_TABLE *Commandtable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Update Command FIS data area.
+// 2. Update the Command FIS lenght in Command List table
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+BuildCommandFIS (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN AHCI_COMMAND_LIST *CommandList,
+ IN AHCI_COMMAND_TABLE *Commandtable
+)
+{
+
+ ZeroMemorySmm (Commandtable, sizeof(AHCI_COMMAND_TABLE));
+
+ Commandtable->CFis.Ahci_CFis_Type = FIS_REGISTER_H2D;
+ Commandtable->CFis.AHci_CFis_PmPort = SataDevInterface->PMPortNumber == 0xFF ? 0x0 : SataDevInterface->PMPortNumber;
+
+ Commandtable->CFis.Ahci_CFis_Cmd = CommandStructure.Command;
+
+ Commandtable->CFis.Ahci_CFis_Features = CommandStructure.Features;
+ Commandtable->CFis.Ahci_CFis_FeaturesExp = CommandStructure.FeaturesExp;
+
+ Commandtable->CFis.Ahci_CFis_SecNum = CommandStructure.LBALow;
+ Commandtable->CFis.Ahci_CFis_SecNumExp = CommandStructure.LBALowExp;
+
+ Commandtable->CFis.Ahci_CFis_ClyLow = CommandStructure.LBAMid;
+ Commandtable->CFis.Ahci_CFis_ClyLowExp = CommandStructure.LBAMidExp;
+
+ Commandtable->CFis.Ahci_CFis_ClyHigh = CommandStructure.LBAHigh;
+ Commandtable->CFis.Ahci_CFis_ClyHighExp = CommandStructure.LBAHighExp;
+
+ Commandtable->CFis.Ahci_CFis_SecCount = (UINT8)(CommandStructure.SectorCount);
+ Commandtable->CFis.Ahci_CFis_SecCountExp = (UINT8)(CommandStructure.SectorCount >> 8);
+
+ Commandtable->CFis.Ahci_CFis_DevHead = CommandStructure.Device;
+ Commandtable->CFis.Ahci_CFis_Control = CommandStructure.Control;
+
+ CommandList->Ahci_Cmd_CFL = FIS_REGISTER_H2D_LENGTH / 4;
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadWritePMPort
+//
+// Description: Read/Write routine to PM ports
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN UINT8 Port,
+// IN UINT8 RegNum,
+// IN OUT UINT32 *Data
+// IN BOOLEAN READWRITE // TRUE for Write
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, BuildAtapiCMD
+// BuildPRDT, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Update Command Structure for READ/Write Port Multiplier command
+// 2. Issue command
+// 3. Check for errors.
+// 4. Read the out data in case of READ.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadWritePMPort (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 RegNum,
+ IN OUT UINT32 *Data,
+ IN BOOLEAN READWRITE
+)
+{
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+ AHCI_RECEIVED_FIS *PortFISBaseAddr = (AHCI_RECEIVED_FIS *)(SataDevInterface->PortFISBaseAddr);
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)SataDevInterface->PortCommandTableBaseAddr;
+
+ ZeroMemorySmm (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.Command = READ_PORT_MULTIPLIER;
+
+ if (READWRITE) {
+ CommandStructure.SectorCount = (UINT16) (*Data & 0xFF);
+ CommandStructure.LBALow = (UINT8) (*Data >> 8);
+ CommandStructure.LBAMid = (UINT8)(*Data >> 16);
+ CommandStructure.LBAHigh = (UINT8)(*Data >> 24);
+ CommandStructure.Command = WRITE_PORT_MULTIPLIER;
+ }
+
+ CommandStructure.Device = Port;
+ CommandStructure.Features = RegNum;
+
+ Status = StopController(SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(SataDevInterface,FALSE);
+ return Status;
+ }
+
+ BuildCommandList(SataDevInterface, CommandList, SataDevInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, CommandStructure, CommandList, Commandtable);
+
+ //
+ // Data-in
+ //
+ CommandList->Ahci_Cmd_W = 0;
+
+ //
+ // Update of Command Register
+ //
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ //
+ // Update the Port Address
+ //
+ CommandList->Ahci_Cmd_PMP = CONTROL_PORT;
+ Commandtable->CFis.AHci_CFis_PmPort = CONTROL_PORT;
+
+ StartController(SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, NON_DATA_CMD, TIMEOUT_1SEC);
+
+ //
+ // Stop Controller
+ //
+ StopController(SataDevInterface,FALSE);
+
+ if (!READWRITE) {
+ *Data = 0;
+ if (!EFI_ERROR(Status)) {
+ *Data = PortFISBaseAddr->Ahci_Rfis[12] |
+ (PortFISBaseAddr->Ahci_Rfis[4] << 8) |
+ (PortFISBaseAddr->Ahci_Rfis[5] << 16) |
+ (PortFISBaseAddr->Ahci_Rfis[6] << 24);
+ }
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciSmmExecuteDmaDataCommand
+//
+// Description: Exectue the DMA data command
+//
+// Input:
+// IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// UINT8 PortNumber,
+// UINT8 PMPortNumber,
+// DEVICE_TYPE DeviceType,
+// BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AhciSmmExecuteDmaDataCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType,
+ BOOLEAN READWRITE
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)SataDevInterface->PortCommandTableBaseAddr;
+
+ SataDevInterface->PortNumber=PortNumber;
+ SataDevInterface->PMPortNumber=PMPortNumber;
+ SataDevInterface->DeviceType=DeviceType;
+
+ Status = StopController(SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(SataDevInterface,FALSE);
+ return Status;
+ }
+ BuildCommandList(SataDevInterface, CommandList, SataDevInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildAtapiCMD(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildPRDT(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+
+ // Data-in
+ if (READWRITE) {
+ CommandList->Ahci_Cmd_W = 1;
+ }
+ else {
+ CommandList->Ahci_Cmd_W = 0;
+ }
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, DMA_DATA_IN_CMD,
+ SataDevInterface->DeviceType == ATA? DMA_ATA_COMMAND_COMPLETE_TIMEOUT \
+ : DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT );
+
+ if (!EFI_ERROR(Status)){
+ //Check if the required BYTES have been received
+ if (CommandList->Ahci_Cmd_PRDBC != CommandStructure->ByteCount){
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+ // Stop Controller
+ StopController(SataDevInterface,FALSE);
+
+ CommandStructure->ByteCount = CommandList->Ahci_Cmd_PRDBC;
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciSmmExecutePioDataCommand
+//
+// Description: Exectue the PIO data command
+//
+// Input:
+// IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// UINT8 PortNumber,
+// UINT8 PMPortNumber,
+// DEVICE_TYPE DeviceType,
+// BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AhciSmmExecutePioDataCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType,
+ BOOLEAN READWRITE
+ )
+{
+ EFI_STATUS Status;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)SataDevInterface->PortCommandTableBaseAddr;
+
+ SataDevInterface->PortNumber=PortNumber;
+ SataDevInterface->PMPortNumber=PMPortNumber;
+ SataDevInterface->DeviceType=DeviceType;
+
+ Status = StopController(SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(SataDevInterface,FALSE);
+ return Status;
+ }
+
+ BuildCommandList(SataDevInterface, CommandList, SataDevInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildAtapiCMD(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildPRDT(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+
+ if (READWRITE) {
+ CommandList->Ahci_Cmd_W = 1;
+ } else {
+ CommandList->Ahci_Cmd_W = 0;
+ }
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(SataDevInterface, BIT00);
+
+
+ Status = WaitforCommandComplete(SataDevInterface, PIO_DATA_IN_CMD,
+ SataDevInterface->DeviceType == ATA? DMA_ATA_COMMAND_COMPLETE_TIMEOUT \
+ : DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT );
+
+ CommandStructure->ByteCount = CommandList->Ahci_Cmd_PRDBC;
+
+ //
+ // Stop Controller
+ //
+ StopController(SataDevInterface,FALSE);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciSmmExecuteNonDataCommand
+//
+// Description: Exectue the Non Data command
+//
+// Input:
+// IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// UINT8 PortNumber,
+// UINT8 PMPortNumber,
+// DEVICE_TYPE DeviceType,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AhciSmmExecuteNonDataCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ COMMAND_STRUCTURE CommandStructure,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)SataDevInterface->PortCommandTableBaseAddr;
+
+ SataDevInterface->PortNumber=PortNumber;
+ SataDevInterface->PMPortNumber=PMPortNumber;
+ SataDevInterface->DeviceType=DeviceType;
+
+ Status = StopController(SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)){
+ return Status;
+ }
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController(SataDevInterface,FALSE);
+ return Status;
+ }
+
+ BuildCommandList(SataDevInterface, CommandList, SataDevInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, CommandStructure, CommandList, Commandtable);
+
+ //
+ // Data-in
+ //
+ CommandList->Ahci_Cmd_W = 0;
+
+ //
+ // Update of Command Register
+ //
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController(SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, NON_DATA_CMD, ATAPI_BUSY_CLEAR_TIMEOUT );
+
+ //
+ // Stop Controller
+ //
+ StopController(SataDevInterface,FALSE);
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HandleAtapiError
+//
+// Description: Check for ATAPI Errors
+//
+// Input:
+// IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ExecutePacketCommand
+//
+// Notes:
+// 1. Execute ATAPI Request Sense command.
+// 2. Check for Device getting ready, Media Change, No Media and other errors. Update AtapiDevice->Atapi_Status
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+HandleAtapiError (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface
+ )
+{
+
+ EFI_STATUS Status;
+ UINT8 Data8 = 0;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT32 AhciBaseAddr = (UINT32)(SataDevInterface->AhciBaseAddress);
+ UINT8 Port = SataDevInterface->PortNumber;
+ ATAPI_DEVICE *AtapiDevice = &SataDevInterface->AtapiDevice;
+
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+
+ ZeroMemorySmm (SenseData, 256);
+ ZeroMemorySmm (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[0] = ATAPI_REQUEST_SENSE;
+ CommandStructure.AtapiCmd.Ahci_Atapi_Command[4] = 0xff;
+
+ CommandStructure.ByteCount = 256;
+ CommandStructure.Buffer = SenseData;
+
+ Status = AhciSmmExecutePacketCommand(SataDevInterface, &CommandStructure, 0,
+ Port,SataDevInterface->PMPortNumber,ATAPI);
+
+ if (EFI_ERROR(Status)) {
+ Data8 = HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD);
+ }
+
+ // Check for DF and CHK
+ if (Data8 & (DF | CHK)) {
+ goto exit_HandleAtapiError_with_Reset;
+ }
+
+ if (!EFI_ERROR(Status)){
+
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+ Status = EFI_DEVICE_ERROR; // Default Value
+
+ if (((SenseData[2] & 0xf) == 2) && (SenseData[12] == 0x3a)) {
+ Status = EFI_NO_MEDIA;
+ AtapiDevice->Atapi_Status = MEDIUM_NOT_PRESENT;
+ }
+ if (((SenseData[2] & 0xf) == 2) && (SenseData[12] == 0x04) && (SenseData[13] == 0x01)) {
+ Status = EFI_MEDIA_CHANGED;
+ AtapiDevice->Atapi_Status = BECOMING_READY;
+ }
+
+ if (((SenseData[2] & 0xf) == 6) && (SenseData[12] == 0x28)){
+ Status = EFI_MEDIA_CHANGED;
+ AtapiDevice->Atapi_Status = MEDIA_CHANGED;
+ }
+
+ if (((SenseData[2] & 0xf) == 7) && (SenseData[12] == 0x27)){
+ Status = EFI_WRITE_PROTECTED;
+ AtapiDevice->Atapi_Status = WRITE_PROTECTED_MEDIA;
+ }
+
+ if (((SenseData[2] & 0xf) == 6) && (SenseData[12] == 0x29)){
+ AtapiDevice->Atapi_Status = POWER_ON_OR_DEVICE_RESET;
+ }
+
+ if (((SenseData[2] & 0xf) == 5) && (SenseData[0] == 0x70)){
+ AtapiDevice->Atapi_Status = ILLEGAL_REQUEST;
+ }
+ }
+
+exit_HandleAtapiError_with_Reset:
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciSmmExecutePacketCommand
+//
+// Description: Execute a Atapi Packet command
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface,
+// IN COMMAND_STRUCTURE *CommandStructure
+// IN BOOLEAN READWRITE
+// UINT8 PortNumber,
+// UINT8 PMPortNumber,
+// DEVICE_TYPE DeviceType
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: StopController, ReadytoAcceptCmd, BuildCommandList, BuildCommandFIS, BuildAtapiCMD
+// BuildPRDT, StartController, WaitforCommandComplete
+//
+// Notes:
+// 1. Stop the Controller
+// 2. Check if the device is ready to accept a Command.
+// 3. Build Command list
+// 4. Start the Controller.
+// 5. Wait till command completes. Check for errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AhciSmmExecutePacketCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN COMMAND_STRUCTURE *CommandStructure,
+ IN BOOLEAN READWRITE,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType
+ )
+{
+
+ EFI_STATUS Status;
+ AHCI_COMMAND_LIST *CommandList = (AHCI_COMMAND_LIST *) SataDevInterface->PortCommandListBaseAddr;
+ AHCI_COMMAND_TABLE *Commandtable = (AHCI_COMMAND_TABLE *)SataDevInterface->PortCommandTableBaseAddr;
+ UINT32 AhciBaseAddr = (UINT32)(SataDevInterface->AhciBaseAddress);
+ UINT8 Port = SataDevInterface->PortNumber;
+ UINT8 Data8;
+ ATAPI_DEVICE *AtapiDevice = &SataDevInterface->AtapiDevice;
+
+
+ SataDevInterface->PortNumber=PortNumber;
+ SataDevInterface->PMPortNumber=PMPortNumber;
+ SataDevInterface->DeviceType=DeviceType;
+
+ CommandStructure->LBAMid = (UINT8)(CommandStructure->ByteCount);
+ CommandStructure->LBAHigh = (UINT8)(CommandStructure->ByteCount >> 8);
+ CommandStructure->Command = PACKET_COMMAND;
+
+ Status = StopController( SataDevInterface,TRUE);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = ReadytoAcceptCmd(SataDevInterface);
+ if (EFI_ERROR(Status)) {
+ StopController( SataDevInterface,FALSE);
+ return Status;
+ }
+
+ BuildCommandList(SataDevInterface, CommandList, SataDevInterface->PortCommandTableBaseAddr);
+ BuildCommandFIS(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildAtapiCMD(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+ BuildPRDT(SataDevInterface, *CommandStructure, CommandList, Commandtable);
+
+
+ if (READWRITE) {
+ CommandList->Ahci_Cmd_W = 1;
+ }
+ else {
+ CommandList->Ahci_Cmd_W = 0;
+ }
+ Commandtable->CFis.Ahci_CFis_C = 1;
+
+ StartController( SataDevInterface, BIT00);
+
+ Status = WaitforCommandComplete(SataDevInterface, PIO_DATA_IN_CMD,
+ SataDevInterface->DeviceType == ATA? DMA_ATA_COMMAND_COMPLETE_TIMEOUT \
+ : DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT );
+
+
+ // Handle ATAPI device error
+ if (EFI_ERROR(Status) && SataDevInterface->DeviceType == ATAPI) {
+ Data8 = HBA_PORT_REG8 (AhciBaseAddr, Port, HBA_PORTS_TFD);
+ if (Data8 & CHK ){
+ return HandleAtapiError(SataDevInterface);
+ }
+ }
+
+ AtapiDevice->Atapi_Status = EFI_SUCCESS;
+
+ CommandStructure->ByteCount = CommandList->Ahci_Cmd_PRDBC;
+
+ // Stop Controller
+ StopController(SataDevInterface,FALSE);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciSmmInitPortOnS3Resume
+//
+// Description: Initilize the Sata port on S3 resume
+//
+// Input:
+// IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+// UINT8 Port,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AhciSmmInitPortOnS3Resume(
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ UINT8 Port
+ )
+{
+ UINT32 AhciBaseAddr=(UINT32)SataDevInterface->AhciBaseAddress;
+ // Return error if AhciBase Address is invalid
+ if(!AhciBaseAddr) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Set the Spin up device on the port
+ //
+
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_SUD);
+
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_SSTS ,
+ HBA_PORTS_SSTS_DET_MASK ,
+ HBA_PORTS_SSTS_DET_PCE ,
+ HBA_PRESENCE_DETECT_TIMEOUT);
+
+ //
+ //Clear Error Regsiter
+ //
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port,
+ HBA_PORTS_SERR, HBA_PORTS_ERR_CLEAR); // Clear Status register
+
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_IS, HBA_PORTS_IS_CLEAR);
+
+ //
+ //Set the FIS base address
+ //
+ gFisBaseAddress=HBA_PORT_REG32(AhciBaseAddr,Port,HBA_PORTS_FB);
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,SataDevInterface->PortFISBaseAddr);
+
+ // Enable FIS Receive Enable
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_FRE);
+
+ // Wait till FIS is running
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_FR,
+ HBA_PORTS_CMD_FR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ // Enable ST
+ HBA_PORT_REG32_OR (AhciBaseAddr, Port, HBA_PORTS_CMD, HBA_PORTS_CMD_ST);
+
+ // Wait till CR list is running
+ WaitForMemSet(AhciBaseAddr, Port, HBA_PORTS_CMD,
+ HBA_PORTS_CMD_CR,
+ HBA_PORTS_CMD_CR,
+ HBA_FR_CLEAR_TIMEOUT);
+
+ //
+ //Restore the FIS base address
+ //
+ HBA_PORT_WRITE_REG32(AhciBaseAddr,Port,HBA_PORTS_FB,gFisBaseAddress);
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InSmmFunction
+//
+// Description: This function is called from SMM during SMM registration.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ UINT32 FisBaseAddress=0;
+ UINT32 PortCommandListBaseAddr=0;
+ EFI_SMM_SYSTEM_TABLE *mSmst;
+
+ //
+ //Initilize the Ahci Base addres to 0
+ //
+ AhciSmm.AhciBaseAddress=0;
+
+ //
+ // Allocate memory for FIS. Should be aligned on 256 Bytes. Each Port will have it own FIS data area.
+ //
+ Status = pBS->AllocatePool (EfiReservedMemoryType,
+ 1 * RECEIVED_FIS_SIZE + 0x100,
+ (VOID**)&FisBaseAddress);
+
+ ZeroMemorySmm ((VOID *)FisBaseAddress,1 * RECEIVED_FIS_SIZE + 0x100);
+ AhciSmm.PortFISBaseAddr =((FisBaseAddress & (~0xFF))+ 0x100);
+
+ //
+ // Allocate memory for Command List (1KB aligned) and Command Table (128KB aligned).
+ // All the ports in the controller will share Command List and Command table data Area.
+ //
+ Status = pBS->AllocatePool (EfiReservedMemoryType,
+ COMMAND_LIST_SIZE_PORT * 2,
+ (VOID**)&PortCommandListBaseAddr);
+
+ ZeroMemorySmm ((VOID *)PortCommandListBaseAddr, COMMAND_LIST_SIZE_PORT * 2);
+
+ //
+ // Allocate memory for Sense Data
+ //
+ Status = pBS->AllocatePool (EfiReservedMemoryType,
+ 256,
+ (VOID**)&SenseData);
+
+ AhciSmm.PortCommandListBaseAddr = (PortCommandListBaseAddr & (~0x3FF)) + 0x400;
+ AhciSmm.PortCommandTableBaseAddr = AhciSmm.PortCommandListBaseAddr + 0x80;
+
+ AhciSmm.AhciSmmInitPortOnS3Resume=AhciSmmInitPortOnS3Resume;
+ AhciSmm.AhciSmmExecutePioDataCommand=AhciSmmExecutePioDataCommand;
+ AhciSmm.AhciSmmExecuteDmaDataCommand=AhciSmmExecuteDmaDataCommand;
+ AhciSmm.AhciSmmExecuteNonDataCommand=AhciSmmExecuteNonDataCommand;
+ AhciSmm.AhciSmmExecutePacketCommand=AhciSmmExecutePacketCommand;
+
+
+ Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pSmmBase->GetSmstLocation (pSmmBase, &mSmst);
+
+ Status = mSmst->SmmInstallConfigurationTable(
+ mSmst,
+ &gAhciSmmProtocolGuid,
+ &AhciSmm,
+ sizeof(AHCI_BUS_SMM_PROTOCOL)
+ );
+
+
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AhciSmmDriverEntryPoint
+//
+// Description: AHCI Smm driver Entry Point
+//
+// Input: EFI_HANDLE ImageHandle,
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AhciSmmDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciSmm/AhciSmm.cif b/Core/EM/Ahci/AhciSmm/AhciSmm.cif
new file mode 100644
index 0000000..9ff312d
--- /dev/null
+++ b/Core/EM/Ahci/AhciSmm/AhciSmm.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "AhciSmm"
+ category = ModulePart
+ LocalRoot = "CORE\EM\Ahci\AhciSmm\"
+ RefName = "AhciSmm"
+[files]
+"AhciSmm.sdl"
+"AhciSmm.mak"
+"AhciSmm.dxs"
+"AhciSmm.c"
+"AhciSmm.h"
+[parts]
+"AhciSmmProtocols"
+<endComponent>
diff --git a/Core/EM/Ahci/AhciSmm/AhciSmm.dxs b/Core/EM/Ahci/AhciSmm/AhciSmm.dxs
new file mode 100644
index 0000000..c9cad9c
--- /dev/null
+++ b/Core/EM/Ahci/AhciSmm/AhciSmm.dxs
@@ -0,0 +1,87 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.dxs 6 2/11/11 4:11a Rameshr $
+//
+// $Revision: 6 $
+//
+// $Date: 2/11/11 4:11a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.dxs $
+//
+// 6 2/11/11 4:11a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSmm.mak
+// AhciSmm.dxs
+// AhciSmm.c
+// AhciSmm.h
+//
+// 5 12/13/10 11:15a Krishnakumarg
+// [TAG] EIP48678
+// [Category] Action Item
+// [Description] AHCI module does not build without CSM
+// [Solution] Remove dependecies on CSM that are required for AHCI
+// module
+// [Files]
+// AhciSmm.c
+//
+// 4 5/07/10 12:40p Krishnakumarg
+// Updated the AMI header.
+//
+// 3 12/09/09 12:32p Fasihm
+// EIP#29827: Updated the dependency and added the LegayBoot to the
+// dependents.
+//
+// 2 11/20/09 11:18a Fasihm
+// EIP#29827:HDD Password can not be unlocked on AHCI mode when the system
+// resume from S3.
+//
+// 1 4/28/09 6:39p Rameshr
+// Initial Check-in
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AhciSmm.dxs
+//
+// Description: This file is the dependency file for the AhciSmm driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Protocol\SmmBase.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciSmm/AhciSmm.h b/Core/EM/Ahci/AhciSmm/AhciSmm.h
new file mode 100644
index 0000000..81c3d8b
--- /dev/null
+++ b/Core/EM/Ahci/AhciSmm/AhciSmm.h
@@ -0,0 +1,237 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.h 8 11/24/14 11:56p Kapilporwal $
+//
+// $Revision: 8 $
+//
+// $Date: 11/24/14 11:56p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.h $
+//
+// 8 11/24/14 11:56p Kapilporwal
+// [TAG] EIP191939
+// [Category] Improvement
+// [Description] Issue about BIG_REAL_MODE_MMIO_ACCESS of AHCI module
+// [Files] AI13.bin
+// AHCIACC.ASM
+// AhciInt13Dxe.c
+// AhciInt13Dxe.dxs
+// AhciInt13Smm.c
+// AhciInt13Smm.cif
+// AhciInt13Smm.dxs
+// AhciInt13Smm.h
+// AhciInt13Smm.mak
+// AhciInt13Smm.sdl
+// AInt13.c
+// Aint13.cif
+// AInt13.h
+// AhciSmm.c
+// AhciSmm.h
+// AhciSmmProtocol.h
+//
+// 7 9/27/11 3:00a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 6 3/15/11 4:12a Rameshr
+// [TAG]- EIP 51884
+// [Category]- New Feature
+// [Description]- Added packet command function in AhciSMM for sending
+// command in SMM handler
+// [Files]- AhciSmm.c, AhciSmm.h, AhciSmmProtocols.h
+//
+// 5 2/11/11 4:11a Rameshr
+// [TAG] EIP53704
+// [Category] Improvement
+// [Description] AMI headers update for Alaska Ahci Driver
+// [Files] AhciSmm.mak
+// AhciSmm.dxs
+// AhciSmm.c
+// AhciSmm.h
+//
+// 4 9/29/10 1:20p Mirk
+// [TAG] EIP44641
+// [Synopsis] Calpella: Build error when Token INDEX_DATA_PORT_ACCESS = 1
+// in AhciSrc.sdl
+// [Category] Defect
+// [Severity] Normal
+// [Resolution] Updated AhciSmm.h and AhciSmm.mak to resolve build errors.
+// [Files] AhciSmm.h, AhciSmm.mak
+//
+// 3 5/07/10 2:30p Krishnakumarg
+// Updated the date in AMI header
+//
+// 2 5/07/10 12:38p Krishnakumarg
+// Updated the AMI header.
+//
+// 1 4/28/09 6:39p Rameshr
+// Initial Check-in
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//--------------------------------------------------------------------------
+//
+// Name: AHCISmm.h
+//
+// Description: Smm function definition
+//
+//--------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _EFI_AHCI_SMM_H_
+#define _EFI_AHCI_SMM_H_
+
+#ifndef ATAPI_BUSY_CLEAR_TIMEOUT
+#define ATAPI_BUSY_CLEAR_TIMEOUT 16000 // 16sec
+#endif
+
+#ifndef DMA_ATA_COMMAND_COMPLETE_TIMEOUT
+#define DMA_ATA_COMMAND_COMPLETE_TIMEOUT 5000 // 5Sec
+#endif
+
+#ifndef DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT
+#define DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT 16000 // 16Sec
+#endif
+
+#define COMMAND_LIST_SIZE_PORT 0x800
+#define TIMEOUT_1SEC 1000 // 1sec Serial ATA 1.0 Sec 5.2
+
+
+#define PCI_CFG_ADDR(bus,dev,func,reg) \
+ ((VOID*)(UINTN) (PCIEX_BASE_ADDRESS + ((bus) << 20) + ((dev) << 15) + ((func) << 12) + reg))
+
+
+EFI_STATUS
+AhciSmmExecuteNonDataCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ COMMAND_STRUCTURE CommandStructure,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType
+);
+
+EFI_STATUS
+AhciSmmExecutePioDataCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType,
+ BOOLEAN READWRITE
+ );
+
+EFI_STATUS
+AhciSmmExecuteDmaDataCommand (
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ COMMAND_STRUCTURE *CommandStructure,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType,
+ BOOLEAN READWRITE
+);
+
+EFI_STATUS
+AhciSmmInitPortOnS3Resume(
+ AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ UINT8 Port
+ );
+
+EFI_STATUS
+StartController (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT32 CIBitMask
+);
+
+EFI_STATUS
+ReadWritePMPort (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN UINT8 Port,
+ IN UINT8 RegNum,
+ IN OUT UINT32 *Data,
+ IN BOOLEAN READWRITE
+);
+EFI_STATUS
+AhciSmmExecutePacketCommand (
+ IN AHCI_BUS_SMM_PROTOCOL *SataDevInterface,
+ IN COMMAND_STRUCTURE *CommandStructure,
+ IN BOOLEAN READWRITE,
+ UINT8 PortNumber,
+ UINT8 PMPortNumber,
+ DEVICE_TYPE DeviceType
+ );
+
+#endif
+
+#if INDEX_DATA_PORT_ACCESS
+UINT32
+ReadDataDword(
+ IN UINTN BaseAddr,
+ IN UINTN Index
+);
+
+UINT16
+ReadDataWord(
+ IN UINTN BaseAddr,
+ IN UINTN Index
+);
+
+UINT8
+ReadDataByte(
+ IN UINTN BaseAddr,
+ IN UINTN Index
+);
+
+VOID
+WriteDataDword(
+ IN UINTN BaseAddr,
+ IN UINTN Index,
+ IN UINTN Data
+);
+
+VOID
+WriteDataWord(
+ IN UINTN BaseAddr,
+ IN UINTN Index,
+ IN UINTN Data
+);
+
+VOID
+WriteDataByte(
+ IN UINTN BaseAddr,
+ IN UINTN Index,
+ IN UINTN Data
+);
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Ahci/AhciSmm/AhciSmm.mak b/Core/EM/Ahci/AhciSmm/AhciSmm.mak
new file mode 100644
index 0000000..80ef21a
--- /dev/null
+++ b/Core/EM/Ahci/AhciSmm/AhciSmm.mak
@@ -0,0 +1,82 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.mak 4 2/11/11 4:11a Rameshr $
+#
+# $Revision: 4 $
+#
+# $Date: 2/11/11 4:11a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/AHCI/AhciSmm/AhciSmm.mak $
+#
+# 4 2/11/11 4:11a Rameshr
+# [TAG] EIP53704
+# [Category] Improvement
+# [Description] AMI headers update for Alaska Ahci Driver
+# [Files] AhciSmm.mak
+# AhciSmm.dxs
+# AhciSmm.c
+# AhciSmm.h
+#
+# 3 9/29/10 1:20p Mirk
+# [TAG] EIP44641
+# [Synopsis] Calpella: Build error when Token INDEX_DATA_PORT_ACCESS = 1
+# in AhciSrc.sdl
+# [Category] Defect
+# [Severity] Normal
+# [Resolution] Updated AhciSmm.h and AhciSmm.mak to resolve build errors.
+# [Files] AhciSmm.h, AhciSmm.mak
+#
+# 2 5/07/10 11:59a Krishnakumarg
+# Updated the AMI header.
+#
+# 1 4/28/09 6:39p Rameshr
+# Initial Check-in
+#
+#
+#**********************************************************************
+all : AhciSmm
+
+AhciSmm : $(BUILD_DIR)\AhciSmm.mak AhciSmmBin
+
+$(BUILD_DIR)\AhciSmm.mak : $(AHCI_SMM_DIR)\AhciSmm.cif $(AHCI_SMM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AHCI_SMM_DIR)\AhciSmm.cif $(CIF2MAK_DEFAULTS) $(AHCI_CSP_DIR)\AhciAccess.cif
+
+AHCI_SMM_INCLUDES=\
+ /I$(AHCI_DIR)\
+
+AhciSmmBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AhciSmm.mak all\
+ GUID=BC3245BD-B982-4f55-9F79-056AD7E987C5\
+ ENTRY_POINT=AhciSmmDriverEntryPoint\
+ "MY_INCLUDES=$(AHCI_SMM_INCLUDES)"\
+ TYPE=BS_DRIVER\
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Ahci/AhciSmm/AhciSmm.sdl b/Core/EM/Ahci/AhciSmm/AhciSmm.sdl
new file mode 100644
index 0000000..d187ae4
--- /dev/null
+++ b/Core/EM/Ahci/AhciSmm/AhciSmm.sdl
@@ -0,0 +1,24 @@
+TOKEN
+ Name = "AhciSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AhciSmm support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AHCI_SMM_DIR"
+End
+
+MODULE
+ Help = "Includes AhciSmm.mak to Project"
+ File = "AhciSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AhciSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/Ahci/AhciSources.chm b/Core/EM/Ahci/AhciSources.chm
new file mode 100644
index 0000000..4ae32b0
--- /dev/null
+++ b/Core/EM/Ahci/AhciSources.chm
Binary files differ
diff --git a/Core/EM/Ahci/AhciSrc.cif b/Core/EM/Ahci/AhciSrc.cif
new file mode 100644
index 0000000..9c3053e
--- /dev/null
+++ b/Core/EM/Ahci/AhciSrc.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "AHCI"
+ category = eModule
+ LocalRoot = "Core\em\Ahci\"
+ RefName = "AHCI"
+[files]
+"AhciSrc.sdl"
+"AhciSrc.mak"
+"AhciBus.c"
+"AhciController.c"
+"AhciComponentName.c"
+"AhciBus.h"
+"AhciController.h"
+"AhciSources.chm"
+[parts]
+"AINT13"
+"ACSP"
+"AhciSmm"
+<endComponent>
diff --git a/Core/EM/Ahci/AhciSrc.mak b/Core/EM/Ahci/AhciSrc.mak
new file mode 100644
index 0000000..a22919f
--- /dev/null
+++ b/Core/EM/Ahci/AhciSrc.mak
@@ -0,0 +1,102 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/AHCI/AhciSrc.mak 6 2/10/11 10:35a Rameshr $
+#
+# $Revision: 6 $
+#
+# $$
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/AHCI/AhciSrc.mak $
+#
+# 6 2/10/11 10:35a Rameshr
+# [TAG] EIP53704
+# [Category] Improvement
+# [Description] AMI headers update for Alaska Ahci Driver
+# [Files] AhciSrc.mak
+# AhciBus.c
+# AhciController.c
+# AhciComponentName.c
+# AhciBus.h
+# AhciController.h
+#
+# 5 5/07/10 11:42a Krishnakumarg
+# Coding standard update
+#
+# 4 5/28/08 9:36a Rameshraju
+# Based on the SDL token index/data or MMIO method used to access the
+# AHCI configuration space.
+#
+# 3 3/28/08 12:13p Michaela
+# Fixed build issue related to component name change
+#
+# 2 3/02/08 8:16p Fasihm
+# Removed the code not to build the cod files.
+#
+# 1 28/02/08 6:03p Anandakrishnanl
+# AHCI Bus Driver initial check-in.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AhciSrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Ahci
+
+Ahci : $(BUILD_DIR)\AhciSrc.mak AhciBin
+
+!IF "$(INDEX_DATA_PORT_ACCESS)"=="1"
+$(BUILD_DIR)\AhciSrc.mak : $(AHCI_DIR)\$(@B).cif $(AHCI_DIR)\$(@B).mak $(BUILD_RULES) $(AHCI_CSP_DIR)\AhciAccess.cif
+ $(CIF2MAK) $(AHCI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) $(AHCI_CSP_DIR)\AhciAccess.cif
+!ELSE
+$(BUILD_DIR)\AhciSrc.mak : $(AHCI_DIR)\$(@B).cif $(AHCI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AHCI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+!ENDIF
+
+
+# "CFLAGS = $(CFLAGS) /FAscu /O1 /Fd$(BUILD_DIR)\ /Zi /Gm" \
+# "LFLAGS = $(LFLAGS) /MAP /DEBUG /PDB:$*.pdb" \
+# "CFLAGS = $(CFLAGS:/O1=) /FAscu /Fd$(BUILD_DIR)\ /Zi /Gm" \
+# "LFLAGS= $(LFLAGS) /MAP /DEBUG /PDB:$(BUILD_DIR)\AhciSrc.pdb "\
+
+AhciBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AhciSrc.mak all\
+ MAKEFILE=$(BUILD_DIR)\AhciSrc.mak \
+ NAME=AHCI \
+ GUID=8F5A2E02-538C-4D59-B920-C4786ACBC552\
+ ENTRY_POINT=AhciBusEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Ahci/AhciSrc.sdl b/Core/EM/Ahci/AhciSrc.sdl
new file mode 100644
index 0000000..2fa93d7
--- /dev/null
+++ b/Core/EM/Ahci/AhciSrc.sdl
@@ -0,0 +1,105 @@
+TOKEN
+ Name = "AhciSrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IdeBusSrc support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AHCI_DIR"
+ Path = "Core\Em\Ahci"
+End
+
+PATH
+ Name = "AHCI_CSP_DIR"
+ Path = "CHIPSET\EM\AHCI"
+End
+
+MODULE
+ Help = "Includes AhciSrc.mak to Project"
+ File = "AhciSrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Ahci.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "PORT_MULTIPLIER_SUPPORT"
+ Value = "0"
+ Help = "Switch to Enable/Disable PM Support"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetEQU = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "INDEX_DATA_PORT_ACCESS"
+ Value = "0"
+ Help = "0-MMIO Access , 1- Index/Port access"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetEQU = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "HDD_PASSWORD_SUPPORT_UNDER_RAIDMODE"
+ Value = "1"
+ Help = "0-HDD Password not support under Raid mode 1- Enabled"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetEQU = Yes
+End
+
+TOKEN
+ Name = "SUPPORT_ATAPI_IN_RAID_MODE"
+ Value = "1"
+ Help = "1-Under Raid mode , Atapi devices are handled by AhciBus driver. 0 - Raid option rom will handle the Atapi devices."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetEQU = Yes
+End
+
+TOKEN
+ Name = "DiPM_SUPPORT"
+ Value = "0"
+ Help = "Support Device Initiated Power Management"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ENABLE_DIPM"
+ Value = "0"
+ Help = " 0 - Disable Device Initiated Power Management Feature. 1 - Enable DipM Feature"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEVICE_SLEEP_SUPPORT"
+ Value = "0"
+ Help = "Enable/Disable Token to support Device Sleep"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ENABLE_DEVICE_SLEEP"
+ Value = "0"
+ Help = " 0 - Disable Device Sleep Feature. 1 - Enable Device Sleep Feature"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
diff --git a/Core/EM/Ahci/Aint13.cif b/Core/EM/Ahci/Aint13.cif
new file mode 100644
index 0000000..4c93b5b
--- /dev/null
+++ b/Core/EM/Ahci/Aint13.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "AHCI Int13"
+ category = ModulePart
+ LocalRoot = "Core\eM\Ahci"
+ RefName = "AINT13"
+[files]
+"Aint13.sdl"
+"Aint13.mak"
+"Aint13.inf"
+"AInt13.h"
+"AInt13.c"
+"AInt13.dxs"
+[parts]
+"AHCI_INT13INIT_PROTOCOL"
+"AHCI_BINARY"
+"AHCI_INT13_CSP"
+"AhciInt13Smm"
+<endComponent>
diff --git a/Core/EM/Ahci/Aint13.inf b/Core/EM/Ahci/Aint13.inf
new file mode 100644
index 0000000..79226bb
--- /dev/null
+++ b/Core/EM/Ahci/Aint13.inf
@@ -0,0 +1,5 @@
+[MODULE]
+ModuleID = 1
+VendorID = 0
+DeviceID = 1
+File = Addon\AI13.BIN
diff --git a/Core/EM/Ahci/Aint13.mak b/Core/EM/Ahci/Aint13.mak
new file mode 100644
index 0000000..a6988fe
--- /dev/null
+++ b/Core/EM/Ahci/Aint13.mak
@@ -0,0 +1,105 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2013, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/AHCI/INT13/Aint13.mak 7 8/28/13 12:38a Rameshr $
+#
+# $Revision: 7 $
+#
+# $Date: 8/28/13 12:38a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/AHCI/INT13/Aint13.mak $
+#
+# 7 8/28/13 12:38a Rameshr
+# [TAG] EIP134204
+# [Category] Improvement
+# [Description] Build Error resolved if token INDEX_DATA_PORT_ACCESS is
+# enabled.
+# [Files] Aint13.mak
+#
+# 6 6/07/11 12:02p Olegi
+# [TAG] EIP61801
+# [Category] Improvement
+# [Description] Added dependency on LegacyBios protocol.
+#
+# 5 2/10/11 10:49a Rameshr
+# [TAG] EIP53704
+# [Category] Improvement
+# [Description] AMI headers update for Alaska Ahci Driver
+# [Files] Aint13.mak
+# AInt13.h
+# AInt13.c
+#
+# 4 5/28/08 9:41a Rameshraju
+# Updated the AMI Address.
+#
+# 3 3/28/08 12:14p Michaela
+# updated copyright
+#
+# 2 28/02/08 6:12p Anandakrishnanl
+# Added the flags in the Build process.
+#
+# 1 12/07/07 11:17a Olegi
+#
+#************************************************************************//
+
+all: AHCIINT13 AHCIINT13CSP
+
+!IF "$(INDEX_DATA_PORT_ACCESS)"=="1"
+$(BUILD_DIR)\aint13.mak : $(AINT13_DIR)\aint13.cif $(AHCI_CSP_DIR)\ahcicsp.cif $(AHCI_CSP_DIR)\AhciAccess.cif $(AINT13_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(AINT13_DIR)\aint13.cif $(AHCI_CSP_DIR)\ahcicsp.cif $(AHCI_CSP_DIR)\AhciAccess.cif
+!ELSE
+$(BUILD_DIR)\aint13.mak: $(AINT13_DIR)\aint13.cif $(AHCI_CSP_DIR)\ahcicsp.cif $(AINT13_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(AINT13_DIR)\aint13.cif $(AHCI_CSP_DIR)\ahcicsp.cif
+!ENDIF
+
+AHCIINT13: $(BUILD_DIR)\aint13.mak AHCIINT13BIN
+
+AHCI_OBJECTS = \
+$(BUILD_DIR)\$(AINT13_DIR)\aint13.obj \
+!IF "$(INDEX_DATA_PORT_ACCESS)"=="1"
+$(BUILD_DIR)\$(AHCI_CSP_DIR)\AhciAccess.obj \
+!ENDIF
+$(BUILD_DIR)\$(AHCI_CSP_DIR)\aint13csp.obj
+
+AHCIINT13BIN: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\aint13.mak all\
+ GUID=67820532-7613-4dd3-9ED7-3D9BE3A7DA63\
+ "OBJECTS=$(AHCI_OBJECTS)"\
+ ENTRY_POINT=Ai13EntryPoint\
+ TYPE=BS_DRIVER\
+ COMPRESS=1\
+ DEPEX1=$(AINT13_DIR)\aint13.dxs \
+
+AHCIINT13CSP: $(BUILD_DIR)\ahciacc.obj
+
+$(BUILD_DIR)\ahciacc.obj: $(AHCI_CSP_DIR)\ahciacc.asm
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\ /Fl$(BUILD_DIR)\ $(AHCI_CSP_DIR)\ahciacc.asm
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2013, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/Ahci/Aint13.sdl b/Core/EM/Ahci/Aint13.sdl
new file mode 100644
index 0000000..4a51110
--- /dev/null
+++ b/Core/EM/Ahci/Aint13.sdl
@@ -0,0 +1,67 @@
+TOKEN
+ Name = "AINT13_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AHCI Int13 support in the project."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+
+TOKEN
+ Name = "AHCI_CONTROLLER_COUNT"
+ Value = "1"
+ Help = "The controller count can range from 1-6"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "1-6"
+End
+
+TOKEN
+ Name = "AI13_BINARY_VERSION"
+ Value = "5714"
+ Help = "Version of AI13.bin. Higher 2 digits represent CSM version and lower 2 digits represent AI13.bin build number"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "AINT13_DIR"
+End
+
+MODULE
+ Help = "Includes Aint13.mak"
+ File = "Aint13.mak"
+End
+
+ELINK
+ Name = "AhciApiModuleStart"
+ Parent = "CsmOem16Functions"
+ ProcID = 07h
+ SrcFile = "$(AHCI_CSP_DIR)\ahciacc.asm"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(AINT13_DIR)\aint13.inf"
+ Parent = "CSM_CUSTOM_INFS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\ahciacc.obj"
+ Parent = "CSM_OEM16_OBJS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\aint13.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/BoardInfo/AMIBoardInfo.cif b/Core/EM/BoardInfo/AMIBoardInfo.cif
new file mode 100644
index 0000000..b4d1a21
--- /dev/null
+++ b/Core/EM/BoardInfo/AMIBoardInfo.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "AmiBoardInfo"
+ category = ModulePart
+ LocalRoot = "Core\EM\BoardInfo"
+ RefName = "AmiBoardInfo"
+[files]
+"AmiBoardInfo.sdl"
+"AmiBoardInfo.mak"
+"AmiBoardInfo.c"
+"AmiBoardInfo.dxs"
+"PciBoard.c"
+"AmiBoardInfo.chm"
+[parts]
+"AmiBoardInfoIncludes"
+<endComponent>
diff --git a/Core/EM/BoardInfo/AmiBoardInfo.c b/Core/EM/BoardInfo/AmiBoardInfo.c
new file mode 100644
index 0000000..2965958
--- /dev/null
+++ b/Core/EM/BoardInfo/AmiBoardInfo.c
@@ -0,0 +1,391 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/BoardInfo/AmiBoardInfo.c 7 12/16/11 5:02p Yakovlevs $
+//
+// $Revision: 7 $
+//
+// $Date: 12/16/11 5:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/BoardInfo/AmiBoardInfo.c $
+//
+// 7 12/16/11 5:02p Yakovlevs
+// Added functions headers for CHM
+//
+// 6 9/30/11 5:40p Yakovlevs
+// [TAG] EIP66222
+// [Category] New Feature
+// [Description] Modify PCI bus driver to get board info from separate
+// FFS section
+// [Files] AmiBoaardInfo.c;
+// AmiBoaardInfo.mak;
+// AmiBoaardInfo.sdl;
+// PciBoard.c
+// AmiBoaardInfo.h
+//
+// 5 6/28/11 5:51p Yakovlevs
+// [TAG] EIP 60123
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Resource padding is not functional for PCIe hot-plug.
+// [RootCause] In HP Mode #ifndef statement was not working
+// [Solution] Cahnged to reference AMI_HOTPLUG_INIT_SUPPORT token
+// [Files] AmiBoardInfo.c PciBoard.c
+//
+// 4 3/01/10 5:06p Yakovlevs
+// New separate Label with generic Multi-Root support.
+// Uses new AMI SDL "C" sytle output for the former "ASM" style.
+//
+// 3 5/05/09 3:16p Felixp
+// Disable ACPI module dependent code if ACPI_MODULE_VER is less or equal
+// than 30
+//
+// 2 5/05/09 1:07p Felixp
+// Formatting update: File headers are updated.
+//
+// 1 4/28/09 1:20p Yakovlevs
+// Added new ModulePart - Ami Board Info.
+// This module groups together all VeB generated outpit files as well as
+// DSDT generation.
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <This File Name>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Protocol\AmiBoardInfo.h>
+
+//----------------------------------------------------------------------------
+//Global GUIDs Definitions goes here
+EFI_GUID gAmiBoardInfoGuid=AMI_BOARD_INFO_PROTOCOL_GUID;
+
+/*
+//----------------------------------------------------------------------------
+//Variable definitions goes here
+//PCI Buses Xlate Table
+extern UINTN BusNumXlatTbl;
+extern UINTN BusNumXlatTblEnd;
+//----------------------------------------------------------------------------
+//Legacy IRQ routing table delivered from oempir.inc and PCIBoard.ASM
+extern UINTN IRQ_Table;
+extern UINTN IRQ_Table_end;
+//----------------------------------------------------------------------------
+//IOAPIC IRQ routing table delivered from mppciirq.inc and PCIBoard.ASM
+#if AMI_BOARD_VER_COMBINED >= 100
+extern MP_IRI_Table;
+extern UINTN MP_IRI_Table_END;
+#else
+extern UINTN MP_IRI_Table;
+extern MP_IRI_Table_END;
+#endif
+//----------------------------------------------------------------------------
+//IO/APIC(s) Info Table
+extern UINTN MP_IAI_Table;
+extern UINTN MP_IAI_Table_END;
+//----------------------------------------------------------------------------
+//Hot pluf stuff
+//For PIC we need it it has SLOT # Info APIC does not.
+//And for verification: HP_SlotP_Count has to much HP_SlotA_Count
+extern HP_SlotP_Start;
+extern HP_SlotP_End;
+//----------------------------------------------------------------------------
+//For APIC used in MP 1.4 Tables generation
+extern HP_SlotA_Start;
+extern HP_SlotA_End;
+*/
+
+extern UINT8 AmlCode[];
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gAmiBoardProtocol
+//
+// Description: Ami Board Info Protocol Instance.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+AMI_BOARD_INFO_PROTOCOL gAmiBoardProtocol = {
+ //BOOLEAN DataValid; //Signifies if Board Specific IRQ data was updated.
+ FALSE,
+ //UINT16 BusXlatEntries;
+ 0,
+ //UINT16 SdlPciIrqMask;
+ 0,
+ //UINT8 Reserved[3];
+ {0,0,0},
+ //PCI_BUS_XLAT_HDR *BusXlatTable;
+ //UINTN BusXlatLength;
+ NULL,0,//(PCI_BUS_XLAT_HDR*)&BusNumXlatTbl, 0,
+ //PCI_IRQ_PIC_ROUTE *PicRoutTable;
+ //UINTN PicRoutLength;
+ NULL,0,//(PCI_IRQ_PIC_ROUTE*)&IRQ_Table, 0,
+ //PCI_IRQ_PIC_ROUTE *HpSltTablePic;
+ //UINTN HpSltPicLength;
+ NULL,0,//(PCI_IRQ_PIC_ROUTE*)&HP_SlotP_Start, 0,
+ //PCI_IRQ_APIC_ROUTE *ApicRoutTable;
+ //UINTN ApicRoutLength;
+ NULL,0,//(PCI_IRQ_APIC_ROUTE*)&MP_IRI_Table, 0,
+ //PCI_IRQ_APIC_ROUTE *HpSltTableApic;
+ //UINTN HpSltApicLength;
+ NULL,0,//(PCI_IRQ_APIC_ROUTE*)&HP_SlotA_Start, 0,
+ //AMI_APIC_INFO *ApicInfoTable;
+ //UINTN ApicInfoLength;
+ NULL,0,//(AMI_APIC_INFO*)&MP_IAI_Table, 0,
+ //VOID *BoardAcpiInfo;
+#if ACPI_MODULE_VER<=30
+ NULL,
+#else
+ &AmlCode,
+#endif
+ //VOID *BoardOemInfo;
+ NULL
+};
+
+UINT8 *gSdlDataStart=NULL;
+UINTN gSdlDataLen=0;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gAmiBoardProtocolHandle
+//
+// Description: Ami Board Info Protocol Handle.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+EFI_HANDLE gAmiBoardInfoHandle=NULL;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ParseAmiSdlData()
+//
+// Description: Seaarches SDL Generated Data structures for specific table
+// Signature.
+//
+// Input:
+// UINT8* IN *DataPtr Pointer To the beginning of SDL Data.
+// UINTN IN DataLen Number of bytes to parse.
+// UINT32 IN Signature Table Signature to Look for.
+// VOID** IN OUT TblPtr Double Pointer To return desired tble start address.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When there are no more handles to override.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ParseAmiSdlData(UINT8 *DataPtr, UINTN DataLen, UINT32 Signature, OUT VOID **TblPtr){
+ UINT8 *start=DataPtr;
+ UINT32 *sig;
+ UINTN i;
+//-----------------
+ if(start==NULL || TblPtr==NULL || DataLen==0 ) return EFI_INVALID_PARAMETER;
+
+ for(i=0; i<DataLen-sizeof(UINT32); i++){
+ sig=(UINT32*)(&start[i]);
+ if(*sig == Signature) {
+ *TblPtr=sig;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciBusEntryPoint()
+//
+// Description: This function is the entry point for AMI Board Info Driver.
+// There it will initialize some global data and install an instance of
+// AMI_BOARD_INFO_PROTOCOL.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When something required is not found!
+// EFI_DEVICE_ERROR When the device is not responding!
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiBoardEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ AMI_BOARD_INFO_PROTOCOL *amibrd=NULL;
+ UINT8 *sdldata=NULL;
+ UINTN sdlsize=0;
+ VOID *DataPtr;
+ UINTN DataLen;
+ UINT8 *p8;
+//VARIABLES TO VERIFY CONSISTANCY OF THE DATA STRUCTURES AND PORTING
+ UINTN psc=0; //PIC table slot count
+ UINTN asc=0; //APIC table slot count
+ UINTN hpsc=0; //PIC table slot count
+ UINTN hasc=0; //APIC table slot count
+
+//--------------------------------
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //First try to check if we are running on MultiPlatfortm Enabled BIOS
+ Status=pBS->LocateProtocol(&gAmiBoardInfoGuid, NULL, &amibrd);
+ if(!EFI_ERROR(Status)){
+ TRACE((-1,"AmiBrdInfo: Multi-Platform BrdInfo present Status=%r Exiting",Status));
+ return Status;
+ }
+
+//DEBUG
+//EFI_DEADLOOP();
+//DEBUG
+
+ amibrd=&gAmiBoardProtocol;
+
+ // Reade resource section from this driver image.
+ Status=ReadImageResource(ImageHandle, &gAmiBoardInfoSectionGuid, &gSdlDataStart, &gSdlDataLen);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Init Ami Platform Info Protocol Instance...
+
+ //1. First get Xlat Table Signature
+ Status=ParseAmiSdlData(gSdlDataStart,gSdlDataLen,AMI_XLT_SIGNATURE,&DataPtr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Here we got XLAT Pointer
+ DataLen=((AMI_SDL_INFO_HDR*)DataPtr)->Size;
+ p8=(UINT8*)DataPtr;
+ gAmiBoardProtocol.BusXlatTable=(PCI_BUS_XLAT_HDR*)(p8+sizeof(AMI_SDL_INFO_HDR));
+ gAmiBoardProtocol.BusXlatLength=DataLen-sizeof(AMI_SDL_INFO_HDR);
+
+ //2. Than get Legacy $PIR table...
+ DataPtr=NULL;
+ Status=ParseAmiSdlData(gSdlDataStart,gSdlDataLen,AMI_PIR_SIGNATURE,&DataPtr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Here we suppose to get PIC IRQ Routing Table.
+ DataLen=((AMI_SDL_IRQR_HDR*)DataPtr)->Size;
+ p8=(UINT8*)DataPtr; //p8 points on the table header.
+ //Make it point at the beginning of a data
+ p8+=sizeof(AMI_SDL_IRQR_HDR);
+ gAmiBoardProtocol.PicRoutTable=(PCI_IRQ_PIC_ROUTE*)p8;
+
+ //Save slot count data for verification later.
+ psc=((AMI_SDL_IRQR_HDR*)DataPtr)->SlotCount;
+ gAmiBoardProtocol.PicRoutLength=sizeof(PCI_IRQ_PIC_ROUTE)*psc;
+
+ //advance pointer to point on HP slots start
+ p8+=gAmiBoardProtocol.PicRoutLength;
+
+ //Save HP slot count data for verification later.
+ hpsc=((AMI_SDL_IRQR_HDR*)DataPtr)->HpSlotCount;
+
+ //Now check HP Slots if any...
+ if(hpsc) {
+ gAmiBoardProtocol.HpSltTablePic=(PCI_IRQ_PIC_ROUTE*)p8;
+ gAmiBoardProtocol.HpSltPicLength=sizeof(PCI_IRQ_PIC_ROUTE)*hpsc;
+ }
+ //Add to the totoal length of the system's slots length of the HP slots.
+ gAmiBoardProtocol.PicRoutLength+=gAmiBoardProtocol.HpSltPicLength;
+
+ //Update SdlPciIrqMask field ... it is last 2 bytes of the IRQ routing data buffer.
+ p8=(UINT8*)DataPtr+DataLen-sizeof(UINT16);
+ gAmiBoardProtocol.SdlPciIrqMask=*((UINT16*)p8);
+
+ //3. Now get APIC Routing info.
+ DataPtr=NULL;
+ Status=ParseAmiSdlData(gSdlDataStart,gSdlDataLen,AMI_AIR_SIGNATURE,&DataPtr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Here we suppose to get APIC IRQ Routing Table.
+ DataLen=((AMI_SDL_IRQR_HDR*)DataPtr)->Size;
+ p8=(UINT8*)DataPtr; //p8 points on the table header.
+ //Make it point at the beginning of a data
+ p8+=sizeof(AMI_SDL_IRQR_HDR);
+ gAmiBoardProtocol.ApicRoutTable=(PCI_IRQ_APIC_ROUTE*)p8;
+
+ //Save slot count data for verification later.
+ asc=((AMI_SDL_IRQR_HDR*)DataPtr)->SlotCount;
+ gAmiBoardProtocol.ApicRoutLength=sizeof(PCI_IRQ_APIC_ROUTE)*asc;
+
+ //advance pointer to point on HP slots start
+ p8+=gAmiBoardProtocol.ApicRoutLength;
+
+ //Save HP slot count data for verification later.
+ hasc=((AMI_SDL_IRQR_HDR*)DataPtr)->HpSlotCount;
+
+ //Now check HP Slots if any...
+ if( hasc ) {
+ gAmiBoardProtocol.HpSltTableApic=(PCI_IRQ_APIC_ROUTE*)p8;
+ gAmiBoardProtocol.HpSltApicLength=sizeof(PCI_IRQ_APIC_ROUTE)*hasc;
+ }
+ //Add to the totoal length of the system's slots length of the HP slots.
+ gAmiBoardProtocol.ApicRoutLength+=gAmiBoardProtocol.HpSltApicLength;
+
+ //4. Update IO APIC info.
+ DataPtr=NULL;
+ Status=ParseAmiSdlData(gSdlDataStart,gSdlDataLen,AMI_APD_SIGNATURE,&DataPtr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Here we suppose to get IOA APIC Informationtable.
+ DataLen=((AMI_SDL_INFO_HDR*)DataPtr)->Size;
+ p8=(UINT8*)DataPtr; //p8 points on the table header.
+ gAmiBoardProtocol.ApicInfoTable=(AMI_APIC_INFO*)(p8+sizeof(AMI_SDL_INFO_HDR));
+ gAmiBoardProtocol.ApicInfoLength=DataLen-sizeof(AMI_SDL_INFO_HDR);
+
+ //So far so good...
+ //Just Check consistancy of data collected.
+ if( psc!=asc || hpsc!=hasc) {
+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
+ }
+
+ //Now install AMI BOARD INFO Protocol...
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &gAmiBoardInfoHandle,
+ &gAmiBoardInfoGuid, &gAmiBoardProtocol, NULL
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/BoardInfo/AmiBoardInfo.chm b/Core/EM/BoardInfo/AmiBoardInfo.chm
new file mode 100644
index 0000000..9917931
--- /dev/null
+++ b/Core/EM/BoardInfo/AmiBoardInfo.chm
Binary files differ
diff --git a/Core/EM/BoardInfo/AmiBoardInfo.dxs b/Core/EM/BoardInfo/AmiBoardInfo.dxs
new file mode 100644
index 0000000..8314695
--- /dev/null
+++ b/Core/EM/BoardInfo/AmiBoardInfo.dxs
@@ -0,0 +1,55 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/BoardInfo/AmiBoardInfo.dxs 3 5/05/09 4:05p Yakovlevs $
+//
+// $Revision: 3 $
+//
+// $Date: 5/05/09 4:05p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/BoardInfo/AmiBoardInfo.dxs $
+//
+// 3 5/05/09 4:05p Yakovlevs
+//
+// 2 5/05/09 1:07p Felixp
+// Formatting update: File headers are updated.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiBoardInfo.dxs
+//
+// Description: Dependency expression for the AMI Board Info Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/BoardInfo/AmiBoardInfo.mak b/Core/EM/BoardInfo/AmiBoardInfo.mak
new file mode 100644
index 0000000..fcd96ee
--- /dev/null
+++ b/Core/EM/BoardInfo/AmiBoardInfo.mak
@@ -0,0 +1,334 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/BoardInfo/AmiBoardInfo.mak 14 9/18/13 3:54a Thomaschen $
+#
+# $Revision: 14 $
+#
+# $Date: 9/18/13 3:54a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/BoardInfo/AmiBoardInfo.mak $
+#
+# 14 9/18/13 3:54a Thomaschen
+# Improved solution of EIP107638.
+#
+# 10 6/05/13 5:00a Thomaschen
+# Updated for EIP107638.
+#
+# 9 2/12/13 11:28p Wesleychen
+# - Add eLink "SB_OSCM_ASL" support.
+# - Add eLink "ASL_PCI0_INI" for Thunderbolt support.
+#
+# 8 1/29/13 12:27a Wesleychen
+# Update Core to 4.6.5.4.
+#
+# 13 5/04/12 5:48p Oleksiyy
+# [TAG] EIP89379
+# [Category] Improvement
+# [Description] Add generic support for changing iasl compiler.
+# [Files] ACPI.sdl and AmiBoardInfo.mak
+#
+# 12 1/26/12 3:19p Oleksiyy
+# [TAG] EIP80854
+# [Category] New Feature
+# [Description] Global _OSC control method is not available to read
+# system wide capabilities in multiple ASL files.
+# [Files] ACPI.sdl and AmiBoardInfo.mak
+#
+# 11 9/30/11 5:41p Yakovlevs
+# [TAG] EIP66222
+# [Category] New Feature
+# [Description] Modify PCI bus driver to get board info from separate
+# FFS section
+# [Files] AmiBoaardInfo.mak;
+# AmiBoaardInfo.sdl;
+# PciBoard.c
+# AmiBoaardInfo.h
+#
+# 10 6/17/11 12:28p Yakovlevs
+# [TAG] EIP54238
+# [Category] Improvement
+# [Description] Add ASLPREPROCESS_FLAG for the dsdt.asl proprocessing
+# [Files] AmiBoardInfo.sdl; AmiBoardInfo.mak
+#
+# 9 3/24/11 11:40a Oleksiyy
+# [TAG] EIP56433
+# [Category] Improvement
+# [Description] Elink table of include dirs for aslexpander is added.
+# [Files] AmiBoardInfo.sdl, AmiBoardInfo.mak.
+#
+# 8 12/16/10 10:41a Oleksiyy
+# [TAG] EIP50035
+# [Category] Improvement
+# [Description] #Ifdef support in ASL code generically added.
+# [Files] ACPI.sdl and AmiBoardInfo.mak
+#
+# 7 5/07/09 6:11p Yakovlevs
+# fixed BUILD error with ACPI_MODULE_VER token
+#
+# 6 5/05/09 3:16p Felixp
+# Disable ACPI module dependent code if ACPI_MODULE_VER is less or equal
+# than 30
+#
+# 5 5/05/09 1:07p Felixp
+# Formatting update: File headers are updated.
+#
+# 4 5/05/09 12:53p Yakovlevs
+# Fixed build issue in x64 mode. Default AFLAGS used /Cp switch to
+# preserve case for PUBLIC identifiers.
+#
+# 1 4/28/09 1:20p Yakovlevs
+# Added new ModulePart - Ami Board Info.
+# This module groups together all VeB generated outpit files as well as
+# DSDT generation.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiBoardInfo.mak
+#
+# Description: Make file to create AmiBoardInfo Driver
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : AmiBoardInfo
+
+AmiBoardInfo : $(BUILD_DIR)\AmiBoardInfo.mak OemPirBin AmiBoardInfoBin
+
+$(BUILD_DIR)\AmiBoardInfo.mak : $(AmiBoardInfo_DIR)\$(@B).cif $(AmiBoardInfo_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AmiBoardInfo_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OemPirBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\AmiBoardInfo.mak bin \
+ "OBJECTS=$(BUILD_DIR)\$(AmiBoardInfo_DIR)\PciBoard.obj"\
+ "MY_DEFINES=/DPCIIRQ_REMAP"\
+ "EXT_HEADERS=$(BUILD_DIR)\oempir.h $(BUILD_DIR)\mppciirq.h $(BUILD_DIR)\BusNumXlat.h"\
+ NAME=oempirall\
+ MAKEFILE=$(BUILD_DIR)\AmiBoardInfo.mak\
+ TYPE=BINARY
+
+AmiBoardInfoBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\AmiBoardInfo.mak all \
+ GUID=9F3A0016-AE55-4288-829D-D22FD344C347 \
+ "AFLAGS=$(AFLAGS:/Cp=)"\
+ "AFLAGSx64=$(AFLAGSx64:/Cp=)"\
+ ENTRY_POINT=AmiBoardEntryPoint \
+ TYPE=BS_DRIVER \
+ EXT_HEADERS=$(BUILD_DIR)\token.h\
+ "OBJECTS=$(BUILD_DIR)\$(AmiBoardInfo_DIR)\AmiBoardInfo.obj"\
+ COMPRESS=1\
+ RESOURCE=$(BUILD_DIR)\oempirall.bin \
+ SECTION_GUID=E6F4F8F7-4992-47b2-8302-8508745E4A23
+
+
+!IF "$(ACPI_SUPPORT)"=="1" && "$(ACPI_MODULE_VER)"!=""
+!IF $(ACPI_MODULE_VER) > 30
+
+AmiBoardInfoBin : $(BUILD_DIR)\dsdt.obj
+
+#----------------------------------------------------------------------------
+# In order to build AML tables (DSDT.AML & SSDT.AML)
+# ASL compiler have to be ran with DSDT.ASL and SSDT.ASL files corespondingly.
+#-----------------------------------------------------------------------
+# GENERATE ASL -> ASM Code
+#-----------------------------------------------------------------------
+
+$(BUILD_DIR)\dsdt.obj: $(PROJECT_DIR)\DSDT.ASL $(IO_ASLS) $(PCI_ASLS) $(BUILD_DIR)\token.mak
+#dsdt.asl must be in the project directory; otherwise, will not be able to include various include files, esp. pcitree.asl
+!IF "$(IFDEF_ASL_SUPPORT)"=="1"
+ $(ASLEXPANDER) $(PROJECT_DIR)\DSDT.ASL $(PROJECT_DIR)\DSDT_Temp.ASL $(PROJECT_DIR) $(ASL_EXP_INCLUDE_PATH)
+ $(CP) /EP /C /FI$(BUILD_DIR)\tokenasl.h $(ASLPREPROCESS_FLAG) $(PROJECT_DIR)\DSDT_Temp.ASL > $(PROJECT_DIR)\DSDT.ASL
+!ENDIF
+!IFDEF ASL_FLAGS
+ $(ACPI_ASL_COMPILER) $(ASL_FLAGS) $(PROJECT_DIR)\DSDT.ASL
+!ELSE
+ $(ACPI_ASL_COMPILER) -tc -vi $(PROJECT_DIR)\DSDT.ASL
+!ENDIF
+ move $(PROJECT_DIR)\DSDT.hex $(BUILD_DIR)\DSDT.c
+ $(CC) $(CFLAGS) /Fo$@ $(BUILD_DIR)\DSDT.c
+
+#-----------------------------------------------------------------------#
+# Description of ASL files that take part in building ACPI DSDT table
+# amlUpd.asl - OperationRegion and Field names to refer to BIOS exchange memory area
+# token.asl - SDL tokens stored in ASL name format
+# aslLib.asl - standard ASL routines (GPRW - generic PRW routine. MCTH - string compare routine)
+# PCItree.asl - file is generated by AMISDL. Defines PCI Devices tree, PCI IRQ routing information
+# oemDSDT.asl - defines Root PCI bridge resources (_CRS), _PTS(prepare to sleep),_WAK(after wake up) routines
+# irqLink.asl - Irq routing devices LINKx
+# ioRoute.asl - Chipset specific routines to route/release IO/DMA resources on ISA/LPC bus. Used only if Positive decoding is selected
+# FAN.asl - OEM Fan device(s) objects
+# TZ.asl - OEM Thermal Zone(s) objects
+# SI.asl - OEM System Indication objects
+#-----------------------------------------------------------------------
+DSDT_ASLS = \
+$(BUILD_DIR)\token.asl\
+!IF "$(PlatformAcpiTables_SUPPORT)"=="0"
+Core\Em\ACPI\asllib.asl\
+!ENDIF
+Core\Em\ACPI\amlupd.asl\
+$(GENERIC_ASL_BEFORE_PCITREE)\
+$(BUILD_DIR)\PCItree.asl\
+$(GENERIC_ASL)\
+!IF "$(A_SIOW)"=="00" #IO_ASLS
+!IFDEF CRB_EC_SUPPORT
+!IF "$(CRB_EC_SUPPORT)"=="0"
+$(PROJECT_DIR)\$(AcpiAslWrap_DIR)\PlatformPS2Wake.ASL\
+!ENDIF
+!ELSE
+!IF "$(CRB_SIO_SUPPORT)"=="0"
+!IF "$(AcpiAslWrap_SUPPORT)"!="0"
+$(PROJECT_DIR)\$(AcpiAslWrap_DIR)\PlatformPS2Wake.ASL\
+!ENDIF #AcpiAslWrap_SUPPORT!=0
+!ENDIF #CRB_SIO_SUPPORT == 0
+!ENDIF #CRB_EC_SUPPORT
+!ENDIF #IO_ASLS
+!IFDEF CRB_EC_SUPPORT
+!IF "$(CRB_EC_SUPPORT)"=="0"
+$(INTEL_EC_ASL)
+!ENDIF
+!ELSE
+$(INTEL_EC_ASL)
+!ENDIF
+
+ASL_SRC = $(**:\=\\)
+
+#-----------------------------------------------------------------------#
+# DSDT.ASL GENERATOR #
+#-----------------------------------------------------------------------#
+# Include any Make flag dependent ASL code in this module,
+# otherwise use OEM ASL files within ACPI_BSP_DIR for OEM modifications
+#
+# Note. 1. Do not change an order ASL files appear in above defined DSDT_ASLS list
+# 2. Any module can include own ASL files to the target DSDT.ASL
+# by adding the files to the dependency list as follows:
+# $(PROJECT_DIR)\DSDT.ASL: $(PATH)\module.asl
+#-----------------------------------------------------------------------#
+$(PROJECT_DIR)\DSDT.ASL: $(DSDT_ASLS)
+ copy << $@
+
+//==========================================================================
+// DO NOT EDIT THIS FILE
+// This file was generated automatically using NMAKE build process(ACPI.MAK)
+// If OEM changes needed, edit ASL file(s) with extension "*.asl"
+//==========================================================================
+DefinitionBlock (
+ "ami.aml",
+ "DSDT",
+!IF "$(ACPI_BUILD_TABLES_3_0)"=="1"
+ 0x02, // DSDT revision.
+!ELSE
+ 0x01, // DSDT revision.
+!ENDIF
+ // A Revision field value greater than or equal to 2 signifies that integers
+ // declared within the Definition Block are to be evaluated as 64-bit values
+ "$(T_ACPI_OEM_ID)", // OEM ID (6 byte string)
+ "$(T_ACPI_OEM_TBL_ID)", // OEM table ID (8 byte string)
+ 0x0$(PROJECT_BUILD) // OEM version of DSDT table (4 byte Integer)
+ )
+
+// BEGIN OF ASL SCOPE
+{
+// Miscellaneous services enabled in Project
+ include ("$(ASL_SRC: ="^)
+ include (")")
+// Sleep states supported by Chipset/Board.
+//----------------------------------------------------------------------
+// SSx - BIOS setup controlled enabled _Sx Sleep state status
+// Values to be written to SLP_TYPE register are provided by SBACPI.SDL (South Bridge ACPI ModulePart)
+ Name(\_S0, Package(4){$(A_S0_PKG)}) // mandatory System state
+!if "$(A_S1)"=="1"
+ if(SS1) { Name(\_S1, Package(4){$(A_S1_PKG)})}
+!endif
+!if "$(A_S2)"=="1"
+ if(SS2) { Name(\_S2, Package(4){$(A_S2_PKG)})}
+!endif
+!if "$(A_S3)"=="1"
+ if(SS3) { Name(\_S3, Package(4){$(A_S3_PKG)})}
+!endif
+!if "$(A_S4)"=="1"
+ if(SS4) { Name(\_S4, Package(4){$(A_S4_PKG)})}
+!endif
+ Name(\_S5, Package(4){$(A_S5_PKG)}) // mandatory System state
+
+ Method(PTS, 1) { // METHOD CALLED FROM _PTS (oemDSDT.asl) PRIOR TO ENTER ANY SLEEP STATE
+ If(Arg0) // entering any sleep state
+ {
+ $(ASL_PTS)
+!if "$(A_SIOW)"=="01" #IO_ASLS
+!IF "$(SIO_SUPPORT)"=="1"
+!IF "$(PlatformAcpiTables_SUPPORT)"=="1"
+ \_SB.PCI0.LPCB.SIOS(Arg0) //- SB name for INTEL LPCB
+!ELSE
+ \_SB.PCI0.SBRG.SIOS(Arg0)
+!ENDIF #PlatformAcpiTables_SUPPORT
+!ENDIF #SIO_SUPPORT
+!endif
+ }
+ }
+ Method(WAK, 1) { // METHOD CALLED FROM _WAK (oemDSDT.asl) RIGHT AFTER WAKE UP
+ $(ASL_WAK)
+!if "$(A_SIOW)"=="01" #IO_ASLS
+!IF "$(SIO_SUPPORT)"=="1"
+!IF "$(PlatformAcpiTables_SUPPORT)"=="1"
+ \_SB.PCI0.LPCB.SIOW(Arg0) //- SB name for INTEL LPCB
+!ELSE
+ \_SB.PCI0.SBRG.SIOW(Arg0)
+!ENDIF #PlatformAcpiTables_SUPPORT
+!ENDIF #SIO_SUPPORT
+!endif
+ }
+
+!IF "$(PlatformAcpiTables_SUPPORT)"=="0"
+ Method(\_SB._OSC,4){
+ $(SB_OSCM_ASL)
+ Return(Arg3)
+ }
+!ELSE
+ Method(OSCM, 4){
+ $(SB_OSCM_ASL)
+ Return(0)
+ }
+!ENDIF #PlatformAcpiTables_SUPPORT
+
+ Method(PINI, 0) { // METHOD CALLED FROM _INI of PCI0 (oemDSDT.asl) RIGHT WHEN ENTER OS
+ $(ASL_PCI0_INI)
+ }
+
+} // End of ASL File
+
+<<
+
+#----------------------------------------------------------------------------
+!ENDIF
+!ENDIF
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/BoardInfo/AmiBoardInfo.sdl b/Core/EM/BoardInfo/AmiBoardInfo.sdl
new file mode 100644
index 0000000..d9224fb
--- /dev/null
+++ b/Core/EM/BoardInfo/AmiBoardInfo.sdl
@@ -0,0 +1,113 @@
+TOKEN
+ Name = "AmiBoardInfo_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AMI Board Info support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "AMI_BOARD_INFO_MAJOR_VERSION"
+ Value = "2"
+ Help = "AMI Board Info Driver Major Version"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "AMI_BOARD_INFO_MINOR_VERSION"
+ Value = "1"
+ Help = "AMI Board Info Driver Mainor Version"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "AMI_BOARD_VER_COMBINED"
+ Value = "$(AMI_BOARD_INFO_MAJOR_VERSION)*100+ $(AMI_BOARD_INFO_MINOR_VERSION)*10"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+PATH
+ Name = "AmiBoardInfo_DIR"
+ Help = "Path to AMI Board Info Module in Project"
+End
+
+MODULE
+ Help = "Includes AmiBoardInfo.mak to Project"
+ File = "AmiBoardInfo.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AmiBoardInfo.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ASL_EXP_INCLUDE_PATH"
+ Help = "Include passes for ASL expander"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ASLPREPROCESS_FLAG"
+ Help = "Option override for preprocessing ASL files"
+ InvokeOrder = ReplaceParent
+End
+
+OUTPUTREGISTER
+ Name = "BUSNUM_XLAT_C_v2"
+ Path = "Build"
+ File = "BusNumXlat.h"
+ Token = "AMI_BOARD_INFO_MAJOR_VERSION" ">=" "1"
+End
+
+OUTPUTREGISTER
+ Name = "IRQ_C_APIC_v2"
+ Path = "Build"
+ File = "mppciirq.h"
+ Token = "AMI_BOARD_INFO_MAJOR_VERSION" ">=" "1"
+End
+
+OUTPUTREGISTER
+ Name = "IRQ_C_v2"
+ Path = "Build"
+ File = "oempir.h"
+ Token = "AMI_BOARD_INFO_MAJOR_VERSION" ">=" "1"
+End
+
+OUTPUTREGISTER
+ Name = "BUSNUM_XLAT"
+ Path = "Build"
+ File = "BusNumXlat.INC"
+ Token = "AMI_BOARD_INFO_MAJOR_VERSION" "<" "1"
+End
+
+OUTPUTREGISTER
+ Name = "IRQ_ASM_APIC"
+ Path = "Build"
+ File = "mppciirq.inc"
+ Token = "AMI_BOARD_INFO_MAJOR_VERSION" "<" "1"
+End
+
+OUTPUTREGISTER
+ Name = "IRQ_ASM"
+ Path = "Build"
+ File = "oempir.inc"
+ Token = "AMI_BOARD_INFO_MAJOR_VERSION" "<" "1"
+End
+
diff --git a/Core/EM/BoardInfo/PciBoard.c b/Core/EM/BoardInfo/PciBoard.c
new file mode 100644
index 0000000..78867a9
--- /dev/null
+++ b/Core/EM/BoardInfo/PciBoard.c
@@ -0,0 +1,119 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/BoardInfo/PciBoard.c 4 10/03/11 4:40p Yakovlevs $
+//
+// $Revision: 4 $
+//
+// $Date: 10/03/11 4:40p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/BoardInfo/PciBoard.c $
+//
+// 4 10/03/11 4:40p Yakovlevs
+//
+// 3 9/30/11 5:42p Yakovlevs
+// [TAG] EIP66222
+// [Category] New Feature
+// [Description] Modify PCI bus driver to get board info from separate
+// FFS section
+// [Files] AmiBoaardInfo.mak;
+// AmiBoaardInfo.sdl;
+// PciBoard.c
+// AmiBoaardInfo.h
+//
+// 2 6/28/11 5:51p Yakovlevs
+// [TAG] EIP 60123
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Resource padding is not functional for PCIe hot-plug.
+// [RootCause] In HP Mode #ifndef statement was not working
+// [Solution] Cahnged to reference AMI_HOTPLUG_INIT_SUPPORT token
+// [Files] AmiBoardInfo.c PciBoard.c
+//
+// 1 3/01/10 5:04p Yakovlevs
+// "C" syle file replaces PciBoard.asm
+//
+// 3 5/05/09 3:16p Felixp
+// Disable ACPI module dependent code if ACPI_MODULE_VER is less or equal
+// than 30
+//
+// 2 5/05/09 1:07p Felixp
+// Formatting update: File headers are updated.
+//
+// 1 4/28/09 1:20p Yakovlevs
+// Added new ModulePart - Ami Board Info.
+// This module groups together all VeB generated outpit files as well as
+// DSDT generation.
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <This File Name>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//#include <Efi.h>
+#pragma pack(push, 1)
+#include "oempir.h"
+#include "BusNumXlat.h"
+#include "mppciirq.h"
+#pragma pack(pop)
+
+/*
+//APIC Hhot Plug Slots
+#if AMI_HOTPLUG_INIT_SUPPORT
+//extern UINT8* APIC_HotPlug_Slots_start;
+UINTN HP_SlotA_Start = (UINTN)&APIC_HotPlug_Slots_start;
+UINTN HP_SlotA_End = (UINTN)&APIC_HotPlug_Slots_start + sizeof(APIC_HotPlug_Slots_start);
+#else
+UINTN HP_SlotA_Start = (UINTN)&MP_IRI_Table+sizeof(MP_IRI_Table);
+UINTN HP_SlotA_End = (UINTN)&MP_IRI_Table+sizeof(MP_IRI_Table);
+#endif
+
+#include "oempir.c"
+UINTN IRQ_Table = (UINTN)arr_rth_pci_dedicated_irqs_equ;
+UINTN IRQ_Table_end=(UINTN)arr_rth_pci_dedicated_irqs_equ+sizeof(arr_rth_pci_dedicated_irqs_equ);
+
+//PIC Hhot Plug Slots
+#if AMI_HOTPLUG_INIT_SUPPORT
+//extern UINT8* HotPlugIrqRoutingStart;
+UINTN HP_SlotP_Start = (UINTN)&HotPlugIrqRoutingStart;
+UINTN HP_SlotP_End = (UINTN)&HotPlugIrqRoutingStart + sizeof(HotPlugIrqRoutingStart);
+#else
+UINTN HP_SlotP_Start = (UINTN)arr_rth_pci_dedicated_irqs_equ+sizeof(arr_rth_pci_dedicated_irqs_equ);
+UINTN HP_SlotP_End = (UINTN)arr_rth_pci_dedicated_irqs_equ+sizeof(arr_rth_pci_dedicated_irqs_equ);
+#endif
+*/
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/BootScriptHide/BootScriptHide.chm b/Core/EM/BootScriptHide/BootScriptHide.chm
new file mode 100644
index 0000000..ea8c2de
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHide.chm
Binary files differ
diff --git a/Core/EM/BootScriptHide/BootScriptHide.cif b/Core/EM/BootScriptHide/BootScriptHide.cif
new file mode 100644
index 0000000..9ee7799
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHide.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Boot Script Hide"
+ category = eModule
+ LocalRoot = "Core\EM\BootScriptHide"
+ RefName = "BootScriptHide"
+[files]
+"BootScriptHide.sdl"
+"BootScriptHide.mak"
+"BootScriptHide.chm"
+"BootScriptHideDxe.c"
+"BootScriptHideDxe.dxs"
+"BootScriptHidePei.c"
+"BootScriptHidePei.dxs"
+"BootScriptHideSmm.c"
+"BootScriptHideSmm.dxs"
+<endComponent>
diff --git a/Core/EM/BootScriptHide/BootScriptHide.mak b/Core/EM/BootScriptHide/BootScriptHide.mak
new file mode 100644
index 0000000..f303c94
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHide.mak
@@ -0,0 +1,124 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#************************************************************************
+# $Header: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHide.mak 1 9/10/14 6:31p Aaronp $
+#
+# $Date: 9/10/14 6:31p $
+#
+#************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHide.mak $
+#
+# 1 9/10/14 6:31p Aaronp
+# First addition of BootScriptHide emodule.
+#************************************************************************
+
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+# Name: BootScriptHide.mak
+#
+# Description: Make file for the Boot Script Hide emodule
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+all : BootScriptHideDxe BootScriptHidePei BootScriptHideSmm
+
+$(BUILD_DIR)\BootScriptHide.mak : $(BOOT_SCRIPT_HIDE_DIR)\BootScriptHide.cif $(BUILD_RULES)
+ $(CIF2MAK) $(BOOT_SCRIPT_HIDE_DIR)\BootScriptHide.cif $(CIF2MAK_DEFAULTS)
+
+BootScriptHideDxe : $(BUILD_DIR)\BootScriptHide.mak BootScriptHideDxeBin
+
+HIDE_BOOT_SCRIPT_DXE_OBJECTS = $(BUILD_DIR)\$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHideDxe.obj
+
+### DXE ###
+BootScriptHideDxeBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\BootScriptHide.mak all\
+ NAME=BootScriptHideDxe\
+ MAKEFILE=$(BUILD_DIR)\BootScriptHide.mak \
+ BUILD_DIR=$(BUILD_DIR)\
+ OBJECTS="$(HIDE_BOOT_SCRIPT_DXE_OBJECTS)" \
+ GUID=A570F393-B0F5-44A4-8550-61600597B409 \
+ ENTRY_POINT=BootScriptHideDxeEntryPoint \
+ TYPE=BS_DRIVER \
+ DEPEX1=$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHideDxe.DXS \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=0
+
+
+### PEI ###
+!IF "$(x64_BUILD)"=="1"
+HIDE_BOOT_SCRIPT_PEI_OBJECTS = $(BUILD_DIR)\IA32\$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHidePei.obj
+!ELSE
+HIDE_BOOT_SCRIPT_PEI_OBJECTS = $(BUILD_DIR)\$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHidePei.obj
+!ENDIF
+
+BootScriptHidePei : $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\BootScriptHide.mak all\
+ NAME=BootScriptHidePei\
+ MAKEFILE=$(BUILD_DIR)\BootScriptHide.mak \
+!IF "$(x64_BUILD)"=="1"
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+!ELSE
+ BUILD_DIR=$(BUILD_DIR)\
+!ENDIF
+ OBJECTS="$(HIDE_BOOT_SCRIPT_PEI_OBJECTS)" \
+ GUID=9B8A0C3A-5186-4B55-89F4-CAFDE613DAB1 \
+ "MY_INCLUDES=/I$(ACPI_DIR)" \
+ ENTRY_POINT=BootScriptHidePeiEntryPoint \
+ TYPE=PEIM \
+ DEPEX1=$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHidePei.DXS \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=0
+
+### SMM ###
+!IF $(PI_SPECIFICATION_VERSION) < 0x0001000A
+!ERROR BotoScriptHide requires PI 1.1 or higher
+!ENDIF
+
+BootScriptHideSmm : $(BUILD_DIR)\BootScriptHide.mak BootScriptHideSmmBin
+
+HIDE_BOOT_SCRIPT_SMM_OBJECTS = $(BUILD_DIR)\$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHideSmm.obj
+
+BootScriptHideSmmBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\BootScriptHide.mak all\
+ NAME=BootScriptHideSmm\
+ MAKEFILE=$(BUILD_DIR)\BootScriptHide.mak \
+ BUILD_DIR=$(BUILD_DIR)\
+ OBJECTS="$(HIDE_BOOT_SCRIPT_SMM_OBJECTS)" \
+ GUID=70B8BACB-0B26-4048-A6F8-03A6AF2C5029 \
+ "MY_INCLUDES=/I$(ACPI_DIR)" \
+ ENTRY_POINT=BootScriptHideSmmEntryPoint \
+ TYPE=SMM_DRIVER \
+ DEPEX1=$(BOOT_SCRIPT_HIDE_DIR)\BootScriptHideSmm.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ COMPRESS=0
+
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/BootScriptHide/BootScriptHide.sdl b/Core/EM/BootScriptHide/BootScriptHide.sdl
new file mode 100644
index 0000000..fd50191
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHide.sdl
@@ -0,0 +1,50 @@
+TOKEN
+ Name = "BootScriptHide_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable BootScriptHide support in Project"
+ TokenType = Boolean
+ Master = Yes
+End
+
+PATH
+ Name = "BOOT_SCRIPT_HIDE_DIR"
+End
+
+MODULE
+ Help = "Includes BootScriptHide.mak to Project"
+ File = "BootScriptHide.mak"
+End
+
+TOKEN
+ Name = "BOOT_SCRIPT_SAVE_SW_SMI_VALUE"
+ Value = "0xD6"
+ Help = "SW SMI value used to trigger boot script saving to SMM"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_SCRIPT_RESTORE_SW_SMI_VALUE"
+ Value = "0xD7"
+ Help = "SW SMI value used to trigger boot script restoring from SMM"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\BootScriptHidePei.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\BootScriptHideSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\BootScriptHideDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/BootScriptHide/BootScriptHideDxe.c b/Core/EM/BootScriptHide/BootScriptHideDxe.c
new file mode 100644
index 0000000..39f15ca
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHideDxe.c
@@ -0,0 +1,126 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHideDxe.c 1 9/10/14 6:31p Aaronp $
+//
+// $Revision: 1 $
+//
+// $Date: 9/10/14 6:31p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHideDxe.c $
+//
+// 1 9/10/14 6:31p Aaronp
+// First addition of BootScriptHide emodule.
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: BootScriptHideDxe.c
+//
+// Description: Source file for the DXE driver. This file contains the
+// code to trigger the SWSMI that will save the boot scripts
+// into SMM. Depending on the boot path, either a legacy
+// boot event or an Exit Boot Services notification will
+// notify the trigger function
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol/SmmControl2.h>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GenerateSaveBootScriptSwSmi
+//
+// Description: Callback function called when either Exit Boot Services is called,
+// or a legacy boot event is raised. This function will use the
+// SmmControl protocol to trigger a SWSMI.
+//
+// Input:
+// IN EFI_EVENT Event - Event that caused this function to be called
+// IN VOID *Context - Context for the event that triggered this function
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GenerateSaveBootScriptSwSmi (
+ IN EFI_EVENT Event, IN VOID *Context
+){
+ static BOOLEAN BootScriptSaved = FALSE;
+ EFI_STATUS Status;
+ EFI_SMM_CONTROL2_PROTOCOL *SmmControl;
+ UINT8 SwSmiValue = BOOT_SCRIPT_SAVE_SW_SMI_VALUE;
+
+ if (BootScriptSaved){
+ pBS->CloseEvent(Event);
+ return;
+ }
+ Status = pBS->LocateProtocol (&gEfiSmmControl2ProtocolGuid, NULL, (VOID **)&SmmControl);
+ if (EFI_ERROR(Status)) return;
+ SmmControl->Trigger (SmmControl, &SwSmiValue, NULL, FALSE, 0);
+ BootScriptSaved = TRUE;
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BootScriptHideDxeEntryPoint
+//
+// Description: Entry point for the DXE driver. Entry point will register a
+// legacy boot event notification function, and a Exit Boot Services
+// event handler. The same function is called for the legacy boot
+// event and the exit boot services notification function.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - The handle that corresponds this this loaded DXE driver
+// IN EFI_SYSTEM_TABLE *SystemTable - Pointer to the EFI System Table
+//
+// Output:
+// EFI_STATUS The return status of this function
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI BootScriptHideDxeEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable){
+ EFI_EVENT Event;
+
+ InitAmiLib(ImageHandle,SystemTable);
+ // We're using TPL_NOTIFY here (as oppose to TPL_CALLBACK) to make sure our callback is called prior to NVRAM driver callback.
+ // Otherwise we may be unable to read boot time variable in our SMI handler.
+ CreateLegacyBootEvent(TPL_NOTIFY, &GenerateSaveBootScriptSwSmi, NULL, &Event);
+ pBS->CreateEvent(
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,TPL_NOTIFY,
+ &GenerateSaveBootScriptSwSmi, NULL, &Event
+ );
+ return EFI_SUCCESS;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/BootScriptHide/BootScriptHideDxe.dxs b/Core/EM/BootScriptHide/BootScriptHideDxe.dxs
new file mode 100644
index 0000000..904733c
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHideDxe.dxs
@@ -0,0 +1,33 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+#include "token.h"
+
+
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/BootScriptHide/BootScriptHidePei.c b/Core/EM/BootScriptHide/BootScriptHidePei.c
new file mode 100644
index 0000000..9b2c820
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHidePei.c
@@ -0,0 +1,266 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHidePei.c 3 5/24/16 4:28p Robert $
+//
+// $Revision: 3 $
+//
+// $Date: 5/24/16 4:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHidePei.c $
+//
+// 3 5/24/16 4:28p Robert
+// [TAG] EIP268161
+// [Category] Improvement
+// [Description] updated copyrights
+//
+// 2 5/20/16 12:10p Robert
+// [TAG] EIP268161
+// [Category] Improvement
+// [Description] Update BootScriptHide to comply with Security
+// Vulnerability related to saving other memory regions at the same time
+// as the boot scripts
+//
+// 1 9/10/14 6:31p Aaronp
+// First addition of BootScriptHide emodule.
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: BootScriptHidePei.c
+//
+// Description: Source file for the PEI driver. This file contains the
+// code to trigger the SWSMI that will restore the boot
+// scripts into regular memory from inside of SMM.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiPeiLib.h>
+#include <Token.h>
+#include <AcpiS3.h>
+#include <Ppi/SmmControl.h>
+#include <Ppi/S3Resume2.h>
+
+typedef struct{
+ EFI_PEI_S3_RESUME2_PPI Ppi;
+ EFI_PEI_S3_RESUME2_PPI *OriginalPpi;
+} S3_RESUME2_PRIVATE;
+
+//PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR S3ResumePpiListTemplate = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiS3Resume2PpiGuid,
+ NULL
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TriggerSwSmi
+//
+// Description: Function that attempts to trigger a SWSMI to restore the boot
+// script tables from SMM memory into regular system memory. This
+// function is called only when the system is resuming from S3.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - Pointer to the PEI services table
+//
+// Output:
+// EFI_STATUS - The status of attempting to trigger a SWSMI
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TriggerSwSmi(IN EFI_PEI_SERVICES **PeiServices){
+ EFI_STATUS Status;
+ PEI_SMM_CONTROL_PPI *SmmControl;
+ INT8 SmiCommand;
+ UINTN Size;
+
+ // Trigger boot script restoring SMI
+
+ // What's the best method of SW SMI generation in PEI?
+ // We're sticking with SmmControl PPI.
+ // If it's not available in your project, replace the code below...
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices, &gPeiSmmControlPpiGuid, 0, NULL, (VOID **)&SmmControl
+ );
+ if (EFI_ERROR (Status)){
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: ERROR: SmmControl PPI not found. Can't restore the boot script.\n"));
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"If PPI is not available in the project, replace code of the TriggerSwSmi function in BootScriptHidePei.c with the chipset specific SW SMI trigerring code.\n"));
+ PEI_TRACE((TRACE_ALWAYS,PeiServices," NOTE: Simple write to 0xB2 may not work. You may have to enable SW SMI in one of the SB registers.\n"));
+ PEI_TRACE((TRACE_ALWAYS,PeiServices," If SW SMI generation succeeds, you should see \"Boot script has been restored\" debug message.\n"));
+ ASSERT_PEI_ERROR(PeiServices,EFI_ABORTED);
+ return Status;
+ }
+ SmiCommand = BOOT_SCRIPT_RESTORE_SW_SMI_VALUE;
+ Size = sizeof(SmiCommand);
+ Status = SmmControl->Trigger(PeiServices, SmmControl, &SmiCommand, &Size, FALSE, 0);
+ if (EFI_ERROR (Status)){
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: ERROR: SmmControl->Trigger failed with status %r. Can't restore the boot script.\n",Status));
+ ASSERT_PEI_ERROR(PeiServices,EFI_ABORTED);
+ return Status;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ErrorHandler
+//
+// Description: Function called when the system encounters an error while
+// trying to restore the boot scripts into regular system memory.
+// If this function is called, it is because there is an error
+// in the system, and S3 resume cannot be completed
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - Pointer to the PEI services table
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ErrorHandler(IN EFI_PEI_SERVICES **PeiServices){
+ // If something went wrong and we were unable to restore the boot script, system is vulnerable.
+ // One one to go back to safety is to issue a system reset, which will change boot path from S3 resume to a normal boot.
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Couldn't restore the boot script. Resetting...\n"));
+ (*PeiServices)->ResetSystem(PeiServices);
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Couldn't reset. Dead-looping...\n"));
+ ASSERT_PEI_ERROR(PeiServices,EFI_ABORTED);
+ EFI_DEADLOOP();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: S3RestoreConfig2
+//
+// Description: This function can be considered a hook. This function is used to replace the
+// S3Resume PPI's RestoreConfig function. The original S3Resume PPI's RestoreConfig
+// is saved, and is called at the end of this function. This function will be
+// attempt to trigger the SWSMI to restore the boot script tables into regular
+// system memory.
+//
+// Input:
+// IN EFI_PEI_S3_RESUME2_PPI *This - Pointer to the S3 resume PPI.
+//
+// Output:
+// EFI_STATUS Status - the status of attempting to restore the configuration
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI S3RestoreConfig2(IN EFI_PEI_S3_RESUME2_PPI *This){
+ const CHAR16 AcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+ const EFI_GUID EfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+ EFI_STATUS Status;
+ S3_RESUME2_PRIVATE *S3Resume2Ppi = (S3_RESUME2_PRIVATE*)This;
+ EFI_PEI_SERVICES **PeiServices = GetPeiServicesTablePointer();
+ ACPI_VARIABLE_SET *AcpiVariableSet;
+ UINTN VariableSize = sizeof(AcpiVariableSet);
+ EFI_PHYSICAL_ADDRESS AcpiReservedMemoryBase;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Successfully trapped S3RestoreConfig2 call.\n"));
+
+ Status = PeiGetVariable(PeiServices,AcpiGlobalVariable,&EfiAcpiVariableGuid,NULL,&VariableSize, &AcpiVariableSet);
+ if (EFI_ERROR (Status)){
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Can't read variable %S. Status = %r.\n", AcpiGlobalVariable, Status));
+ ErrorHandler(PeiServices);
+ }
+ // We are using AcpiReservedMemoryBase field as a communication mail box between this PEIM
+ // and boot script restoring SMI handler.
+ // We are setting the field to BOOT_SCRIPT_SAVE_SW_SMI_VALUE and SMI handler if succeeds sets it to BOOT_SCRIPT_RESTORE_SW_SMI_VALUE.
+ // Preserve original AcpiReservedMemoryBase value to restore it once we are done.
+ AcpiReservedMemoryBase = AcpiVariableSet->AcpiReservedMemoryBase;
+ AcpiVariableSet->AcpiReservedMemoryBase = ~(AcpiVariableSet->AcpiReservedMemoryBase);
+ Status = TriggerSwSmi(GetPeiServicesTablePointer());
+ if (EFI_ERROR (Status)) ErrorHandler(PeiServices);
+ if (AcpiVariableSet->AcpiReservedMemoryBase != BOOT_SCRIPT_RESTORE_SW_SMI_VALUE){
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Something went wrong. SW SMI handler failed to restore the boot script.\n"));
+ ErrorHandler(PeiServices);
+ }
+
+ // Restore original AcpiReservedMemoryBase value.
+ AcpiVariableSet->AcpiReservedMemoryBase = AcpiReservedMemoryBase;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Calling original S3RestoreConfig2\n"));
+ return S3Resume2Ppi->OriginalPpi->S3RestoreConfig2(S3Resume2Ppi->OriginalPpi);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BootScriptHidePeiEntryPoint
+//
+// Description: Module entry point for the BootScripeHidePei module. This module
+// does nothing if the system is not in the S3 resume path.
+// If the system is in the S3 resume path, then the module will use the
+// installed S3Resume PPI to populate a new copy of the S3Resume PPI that
+// will contain the S3RestoreConfig2 function instead of the original S3RestoreConfig2 function.
+//
+//
+// Input:
+// IN EFI_PEI_FILE_HANDLE FileHandle - The file handle associated with this PEIM
+// IN EFI_PEI_SERVICES **PeiServices - Pointer to the PEI Services table
+//
+// Output:
+// EFI_STATUS Status - the status of registering the callbacks and hooking the S3ResumePpi functions
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI BootScriptHidePeiEntryPoint (IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_SERVICES **PeiServices){
+
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_PEI_PPI_DESCRIPTOR *S3ResumePpiList;
+ S3_RESUME2_PRIVATE *S3Resume2Ppi;
+ EFI_PEI_S3_RESUME2_PPI *OriginalS3Resume2Ppi;
+ EFI_PEI_PPI_DESCRIPTOR *OrignalS3Resume2PpiDescriptor;
+
+ Status = (*PeiServices)->GetBootMode( PeiServices, &BootMode );
+ if ( EFI_ERROR(Status) || BootMode != BOOT_ON_S3_RESUME) return EFI_UNSUPPORTED;
+ // We can't trigger SW SMI just yet because we can't be sure that it will work.
+ // Perhaps SMM initialization is yet to be done by other PEIMs.
+ // We need to delay SW SMI generation to a latter point.
+ // One one to do it is S3Resume2 PPI hijacking.
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices, &gEfiPeiS3Resume2PpiGuid, 0, &OrignalS3Resume2PpiDescriptor, (VOID **)&OriginalS3Resume2Ppi
+ );
+ if ( EFI_ERROR(Status) ) return Status;
+
+ Status = (*PeiServices)->AllocatePool(PeiServices, sizeof(S3ResumePpiListTemplate)+sizeof(*S3Resume2Ppi), &S3ResumePpiList);
+ if (EFI_ERROR(Status)) return Status;
+ *S3ResumePpiList=S3ResumePpiListTemplate;
+ S3Resume2Ppi = (S3_RESUME2_PRIVATE*)(S3ResumePpiList+1);
+ S3Resume2Ppi->Ppi.S3RestoreConfig2 = S3RestoreConfig2;
+ S3ResumePpiList->Ppi = &S3Resume2Ppi->Ppi;
+ S3Resume2Ppi->OriginalPpi = OriginalS3Resume2Ppi;
+
+ Status = (*PeiServices)->ReInstallPpi(PeiServices,OrignalS3Resume2PpiDescriptor,S3ResumePpiList);
+ if (EFI_ERROR(Status)){
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"BootScriptHide: Can't replace S3Resume2 PPI.\n"));
+ ErrorHandler(PeiServices);
+ }
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/BootScriptHide/BootScriptHidePei.dxs b/Core/EM/BootScriptHide/BootScriptHidePei.dxs
new file mode 100644
index 0000000..419a304
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHidePei.dxs
@@ -0,0 +1,35 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+#include "token.h"
+#include <PEI.h>
+#include <Ppi\S3Resume2.h>
+DEPENDENCY_START
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI AND
+ EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI AND
+ EFI_PEI_S3_RESUME2_PPI_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/BootScriptHide/BootScriptHideSmm.c b/Core/EM/BootScriptHide/BootScriptHideSmm.c
new file mode 100644
index 0000000..71fff54
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHideSmm.c
@@ -0,0 +1,388 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHideSmm.c 4 5/24/16 4:28p Robert $
+//
+// $Revision: 4 $
+//
+// $Date: 5/24/16 4:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/BootScriptHide/BootScriptHideSmm.c $
+//
+// 4 5/24/16 4:28p Robert
+// [TAG] EIP268161
+// [Category] Improvement
+// [Description] Update copyrights
+//
+// 3 5/20/16 12:11p Robert
+// [TAG] EIP268161
+// [Category] Improvement
+// [Description] Update BootScriptHide to comply with Security
+// Vulnerability related to saving other memory regions at the same time
+// as the boot scripts
+//
+// 2 11/03/14 3:31p Aaronp
+// Improved buffer validation and error detection.
+// - IsBufferInSmram is replaced with IsBadBuffer that delas with memory
+// range
+// - BootScriptSaved flag is added to signal that saved boot script
+// buffer is valid
+//
+// 1 9/10/14 6:31p Aaronp
+// First addition of BootScriptHide emodule.
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: BootScriptHideSmm.c
+//
+// Description: Source file for the SMM driver. Contains the code that is
+// signalled when it is time to save/restore the boot script
+// tables
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <AcpiS3.h>
+#include <BootScriptCommon.h>
+#include <Protocol/SmmSwDispatch2.h>
+#include <Protocol/SmmAccess2.h>
+
+#if PI_SPECIFICATION_VERSION < 0x0001000A
+#error This module requires PI 1.1 or higher
+#endif
+
+/// Maximum size of the boot script tables
+#define MAX_BOOT_SCRIPT_TABLE_SIZE 0x100000 // 1MB
+
+// The definitions below are from BootScriptPrivate.h, but we don't want to include private ACPI headers here.
+/// Structure copied out of BootScriptPrivate.h
+typedef struct {
+ UINT32 UniqueIndex; ///< Index of this entry
+ UINT32 Length; ///< Length of this entry
+} BOOT_SCRIPT_INFO_STRUCTURE;
+
+/// Structure copied out of BootScriptPrivate.h
+typedef struct {
+ UINT16 Type; ///< Type of this boot script entry
+ EFI_PHYSICAL_ADDRESS EntryPoint; ///< Entry point of the code to be dispatched.
+} BOOT_SCRIPT_DISPATCH;
+
+/// Opcode that signals the current entry is the last entry in the boot script tables
+#define TABLE_END_OP_CODE 0xff
+// End of BootScriptPrivate.h content
+
+EFI_SMRAM_DESCRIPTOR *SmramRanges;
+UINTN SmramRangeCount;
+
+UINTN BootScriptTableSize = 0;
+VOID *SmmBootScriptBuffer = NULL;
+ACPI_VARIABLE_SET *AcpiVariableSet = NULL;
+EFI_PHYSICAL_ADDRESS SmmAcpiReserveMemoryBase;
+UINT32 SmmAcpiReserveMemorySize;
+EFI_PHYSICAL_ADDRESS SmmAcpiFacsTable[3];
+EFI_PHYSICAL_ADDRESS SmmBootScriptTable;
+BOOLEAN AcpiVariableSetValuesCorrupted;
+BOOLEAN BootScriptSaved = FALSE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsBadBuffer
+//
+// Description: Function that verifies that the passed address is not contained
+// in the region of memory occupied by the SMM code.
+//
+// Input:
+// IN VOID* Buffer - Address to check against the SMM memory region
+// IN UINTN BufferSize - Size of the buffer to check against the Smm Memory Region
+//
+// Output:
+// BOOLEAN
+// TRUE - The address is part of the SMRAM region
+// FALSE - The address is not part of the SMRAM region
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsBadBuffer (IN VOID *Buffer, IN UINTN BufferSize){
+ UINTN i;
+ UINTN BufferAddress = (UINTN)Buffer;
+
+ if (BufferAddress + BufferSize < BufferAddress) return TRUE; // overflow
+ for (i = 0; i < SmramRangeCount; i ++) {
+ if ( BufferAddress >= SmramRanges[i].CpuStart
+ && BufferAddress < SmramRanges[i].CpuStart + SmramRanges[i].PhysicalSize
+ ) return TRUE; // Buffer starts in SMRAM
+ if ( BufferAddress < SmramRanges[i].CpuStart
+ && BufferAddress+BufferSize > SmramRanges[i].CpuStart
+ ) return TRUE; // Buffer overlaps with SMRAM
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBootScriptTableLength
+//
+// Description: Using the passed BootScriptTablePointer, go through the
+// entries and determine the total size of the Boot Script
+// table.
+//
+// Input:
+// VOID *BootScriptTablePtr - Pointer to the boot script tables
+//
+// Output:
+// UINTN The total size of the boot script tables
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN GetBootScriptTableLength(VOID *BootScriptTablePtr){
+ BOOT_SCRIPT_INFO_STRUCTURE* BootScriptTable = BootScriptTablePtr;
+ UINT8 Type;
+ UINTN Size = 0;
+ do{
+ Type = *(UINT8*)(BootScriptTable + 1);
+ if (Type == TABLE_END_OP_CODE){
+ // The OpCode size comes from BootScriptTable->Length.
+ // However, info structure of the End OpCode for some reason comes with the invalid Length.
+ // That is why we have to calculate OpCode size differently.
+ Size += sizeof(BOOT_SCRIPT_INFO_STRUCTURE) + 2; // 2 is sizeof(BOOT_SCRIPT_TABLE_END);
+ break;
+ }
+ // The dispatch OpCodes are dangerous. If function being dispatching is not in ROM, it can be modified by OS agent.
+ // On one hand, we can't allow dispatching of non-ROM function.
+ // On the other hand, we can't simply skip the function because it might be doing something important.
+ // We're just giving up (not saving the script).
+ // Our companion PEIM will detect that boot script has not been saved and restored and will reset the system.
+ if (Type == EFI_BOOT_SCRIPT_DISPATCH_OPCODE || Type == EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE){
+ // The entry point is a 64-bit value, but we ignore the upper four bytes because:
+ // 1) AMI boot script implementation launches dispatch function in 32-bit mode and ignores the upper 4 bytes.
+ // 2) Due to a type casting bug in some projects, the upper 4 bytes are occasionally filled with F's.
+ UINT32 EntryPoint = (UINT32)((BOOT_SCRIPT_DISPATCH*)(BootScriptTable + 1))->EntryPoint;
+ if (EntryPoint < 0xFFFFFFFF - FLASH_SIZE +1){
+ TRACE((TRACE_ALWAYS,
+ "BootScriptHide: ERROR: Boot script dispatch opcode with the Entry Point(%lX) outside of the ROM is found.\n"
+ "It's illegal to call non-ROM functions in the boot script.\n"
+ "Fix your project by searching for %s in the code and reviewing origin of the functions being dispatched.\n",
+ EntryPoint,
+ (Type == EFI_BOOT_SCRIPT_DISPATCH_OPCODE)
+ ? "\"EFI_BOOT_SCRIPT_DISPATCH_OPCODE\" or \"BOOT_SCRIPT_DISPATCH_MACRO\""
+ : "\"EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\" or \"BOOT_SCRIPT_S3_DISPATCH_MACRO\" or \"BOOT_SCRIPT_S3_DISPATCH_2_MACRO\""
+ ));
+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
+ return 0;
+ }
+ }
+ if (BootScriptTable->Length == 0 || BootScriptTable->Length > MAX_BOOT_SCRIPT_TABLE_SIZE) return 0;
+ Size += BootScriptTable->Length;
+ if (Size > MAX_BOOT_SCRIPT_TABLE_SIZE) return 0;
+ BootScriptTable = (BOOT_SCRIPT_INFO_STRUCTURE*)((UINT8*)BootScriptTable + BootScriptTable->Length);
+ }while(TRUE);
+ return Size;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveBootScriptHandle
+//
+// Description: SMM Dispatch handler to save the Boot Scripts from regular system
+// memory into SMRAM.
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle - Dispatch handle for this handler
+// IN CONST VOID *Context OPTIONAL - Context for this dispatch
+// IN VOID *CommBuffer OPTIONAL - Pointer to the buffer containing communication data
+// IN UINTN *CommBufferSize OPTIONAL - Pointer to the size of this communication buffer
+//
+// Output:
+// EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI SaveBootScriptHandle(
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+){
+ static BOOLEAN BootScriptSaveProcessed = FALSE;
+ const CHAR16 AcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+ const EFI_GUID EfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+ EFI_STATUS Status;
+ UINTN VariableSize = sizeof(AcpiVariableSet);
+ UINT8* BootScriptTable;
+
+ if (BootScriptSaveProcessed) return EFI_SUCCESS;
+ // We are setting the flag early intentionally.
+ // We want to make sure the handle is executed once
+ // (even if failed to save the script due to errors).
+ BootScriptSaveProcessed = TRUE;
+
+ Status = pRS->GetVariable(
+ (CHAR16*)AcpiGlobalVariable, (EFI_GUID*)&EfiAcpiVariableGuid,
+ NULL,&VariableSize, &AcpiVariableSet
+ );
+ if (EFI_ERROR(Status)) return Status;
+ BootScriptTable = (UINT8*)(UINTN)AcpiVariableSet->AcpiBootScriptTable;
+ if (IsBadBuffer(BootScriptTable,0)) return EFI_NOT_FOUND;
+ BootScriptTableSize = GetBootScriptTableLength(BootScriptTable);
+ if ( BootScriptTableSize==0
+ || IsBadBuffer(BootScriptTable,BootScriptTableSize)
+ ) return EFI_NOT_FOUND;
+
+ Status = pSmst->SmmAllocatePool (EfiRuntimeServicesData, BootScriptTableSize, &SmmBootScriptBuffer);
+ if (EFI_ERROR(Status)) return Status;
+ MemCpy(SmmBootScriptBuffer, BootScriptTable, BootScriptTableSize);
+ TRACE((TRACE_ALWAYS,"BootScriptHide: Boot script has been saved. Address: %X; Size :%X\n",BootScriptTable,BootScriptTableSize));
+
+ SmmBootScriptTable = AcpiVariableSet->AcpiBootScriptTable;
+ SmmAcpiReserveMemoryBase = AcpiVariableSet->AcpiReservedMemoryBase;
+ SmmAcpiReserveMemorySize = AcpiVariableSet->AcpiReservedMemorySize;
+ MemCpy(SmmAcpiFacsTable, AcpiVariableSet->AcpiFacsTable, sizeof(EFI_PHYSICAL_ADDRESS)*3);
+
+ BootScriptSaved = TRUE;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreBootScriptHandle
+//
+// Description: SMM Dispatch handler to restore the Boot Scripts from SMRAM
+// to the regular system memory
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle - Handle of the
+// IN CONST VOID *Context OPTIONAL - Context for this dispatch
+// IN VOID *CommBuffer OPTIONAL - Pointer to the buffer containing communication data
+// IN UINTN *CommBufferSize OPTIONAL - Pointer to the size of this communication buffer
+//
+// Output:
+// EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI RestoreBootScriptHandle(
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+){
+ UINT8* BootScriptTable;
+
+ if ( !BootScriptSaved )
+ return EFI_NOT_FOUND;
+
+ // We are using AcpiReservedMemoryBase field as a communication mail box between this SMI handler
+ // and companion PEIM that triggers SW SMI on S3 resume boot path.
+ // The PEIM bitwise NOTs the value, and this handler sets it to BOOT_SCRIPT_RESTORE_SW_SMI_VALUE if boot script has been restored.
+ // The values for AcpiReservedMemorySize, BootScriptTable, and AcpiFacsTable are also verified to be the same as the previous boot.
+ if ((AcpiVariableSet->AcpiReservedMemoryBase != (~SmmAcpiReserveMemoryBase)) ||
+ (AcpiVariableSet->AcpiReservedMemorySize != SmmAcpiReserveMemorySize))
+ return EFI_NOT_FOUND;
+
+ // If FACS entries are not correct, replace the pointers with known saved values and continue
+ if (MemCmp(SmmAcpiFacsTable, AcpiVariableSet->AcpiFacsTable, sizeof(EFI_PHYSICAL_ADDRESS)*3))
+ MemCpy(AcpiVariableSet->AcpiFacsTable, SmmAcpiFacsTable, sizeof(EFI_PHYSICAL_ADDRESS)*3);
+
+ // verify that the Boot Script is correct. If not update it to the correct value
+ if (AcpiVariableSet->AcpiBootScriptTable != SmmBootScriptTable)
+ AcpiVariableSet->AcpiBootScriptTable = SmmBootScriptTable;
+
+ // Now verify the Boot Script Table
+ BootScriptTable = (UINT8*)(UINTN)AcpiVariableSet->AcpiBootScriptTable;
+ // verify that the BootScript buffer location is outside of SMM Memory
+ if ( IsBadBuffer(BootScriptTable,BootScriptTableSize) )
+ return EFI_NOT_FOUND;
+#ifdef EFI_DEBUG
+ //Let's see if boot script has actually been changed
+ if (MemCmp(BootScriptTable, SmmBootScriptBuffer, BootScriptTableSize))
+ TRACE((TRACE_ALWAYS,"BootScriptHide: The boot script has been changed.\n"));
+ else
+ TRACE((TRACE_ALWAYS,"BootScriptHide: The boot script hasn't been changed.\n"));
+#endif
+ MemCpy(BootScriptTable, SmmBootScriptBuffer, BootScriptTableSize);
+ TRACE((TRACE_ALWAYS,"BootScriptHide: Boot script has been restored. Address: %X; Size :%X\n",BootScriptTable,BootScriptTableSize));
+ AcpiVariableSet->AcpiReservedMemoryBase = BOOT_SCRIPT_RESTORE_SW_SMI_VALUE;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BootScriptHideSmmEntryPoint
+//
+// Description: SMM driver entry point. This entry point will register SWSMI dispatch
+// handlers to deal with the save and restore SWSMIs.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - The handle that corresponds this this loaded SMM driver
+// IN EFI_SYSTEM_TABLE *SystemTable - Pointer to the EFI System Table
+//
+// Output:
+// EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI BootScriptHideSmmEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable){
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch;
+ EFI_HANDLE Handle;
+ EFI_SMM_SW_REGISTER_CONTEXT Context;
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+ UINTN Size;
+
+ InitAmiSmmLibPi(ImageHandle,SystemTable);
+
+ // Get SMRAM information
+ Status = pBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
+ if (EFI_ERROR(Status)) return Status;
+
+ Size = 0;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
+ if (Status != EFI_BUFFER_TOO_SMALL) return Status;
+ Status = pSmst->SmmAllocatePool (EfiRuntimeServicesData, Size, (VOID **)&SmramRanges);
+ if (EFI_ERROR(Status)) return Status;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, SmramRanges);
+ if (EFI_ERROR(Status)) return Status;
+ SmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ // Register SW SMI handlers
+ Status = pSmst->SmmLocateProtocol(&gEfiSmmSwDispatch2ProtocolGuid, NULL, &SwDispatch);
+ if (EFI_ERROR(Status)) return Status;
+
+ // Save Boot Script
+ Context.SwSmiInputValue = BOOT_SCRIPT_SAVE_SW_SMI_VALUE;
+ Status = SwDispatch->Register(SwDispatch, SaveBootScriptHandle, &Context, &Handle);
+ if (EFI_ERROR(Status)) return Status;
+ // restore Boot Script
+ Context.SwSmiInputValue = BOOT_SCRIPT_RESTORE_SW_SMI_VALUE;
+ Status = SwDispatch->Register(SwDispatch, RestoreBootScriptHandle, &Context, &Handle);
+ if (EFI_ERROR(Status)) return Status;
+
+ return EFI_SUCCESS;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/BootScriptHide/BootScriptHideSmm.dxs b/Core/EM/BootScriptHide/BootScriptHideSmm.dxs
new file mode 100644
index 0000000..ba5953f
--- /dev/null
+++ b/Core/EM/BootScriptHide/BootScriptHideSmm.dxs
@@ -0,0 +1,35 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+#include "token.h"
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/CSM/BiosData.h b/Core/EM/CSM/BiosData.h
new file mode 100644
index 0000000..dfb8e71
--- /dev/null
+++ b/Core/EM/CSM/BiosData.h
@@ -0,0 +1,179 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/biosdata.h 7 1/12/10 11:46a Olegi $
+//
+// $Revision: 7 $
+//
+// $Date: 1/12/10 11:46a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/biosdata.h $
+//
+// 7 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 6 4/27/07 5:13p Olegi
+// CSM.CHM file preparation.
+//
+// 5 5/16/06 1:57p Olegi
+//
+// 4 8/02/05 11:27a Olegi
+//
+// 3 3/04/05 1:51p Mandal
+//
+//**********************************************************************
+//----------------------------------------------------------------------------
+// BIOSDATA.H -- BIOS Global Data Area and EBDA
+//----------------------------------------------------------------------------
+#ifndef __BIOS_DATA_AREA__
+#define __BIOS_DATA_AREA__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack (1)
+
+typedef struct _BDA_DATA {
+
+UINT16 rs_232_address[4]; // 00 - RS232 adapters addresses
+UINT16 printer_address[3]; // 08 - Printer addresses
+UINT16 ext_bios_data_seg; // 0E - Segment pointer to EBDA
+UINT16 machine_config; // 10 - Hardware Equipment Status
+UINT8 test_scratch; // 12 - Scratch byte during init
+UINT16 system_memory; // 13 - System Memory in KBytes
+UINT8 sys_info; // 15 - miscellaneous system info
+UINT8 dummy_byte_1; // 16
+UINT8 kb_stat_flag; // 17 - Keyboard Status Flag
+UINT8 kb_hold_flag; // 18 - Toggle key's hold flag
+UINT8 kb_alt_char; // 19 - Alt_character byte
+UINT16 kb_buf_head_ptr; // 1A - Keyboard buffer head pointer
+UINT16 kb_buf_tail_ptr; // 1C - Keyboard buffer tail pointer
+UINT16 kb_buffer[16]; // 1E - Keyboard buffer (15 char max)
+UINT8 recal_int_flag; // 3E - Status for recalibration
+UINT8 motor_status_flag; // 3F - Status for drive motors
+UINT8 motor_time_count; // 40 - Turn off time for motor
+UINT8 floppy_io_status; // 41 - Return code status byte
+UINT8 task_file[7]; // 42 - A.K.A. fdc_8272_status
+UINT8 mode_of_vdo; // 49 - Current Video Mode (set by user)
+UINT16 columns_of_vdo; // 4A - Number of columns per row
+UINT16 page_length; // 4C - Number of bytes per Video Page
+UINT16 page_start; // 4E - Start address of Active Video Page
+UINT16 position_of_cursor[8]; // 50 - Cursor position for each Video Page
+UINT16 mode_of_cursor; // 60 - Current cursor mode setting
+UINT8 active_page_no; // 62 - Current display page no
+UINT16 address_of_6845; // 63 - Address of 6845 index reg
+UINT8 current_mode_set; // 65 - Mode set in 6845 control port
+UINT8 current_palette; // 66 - Current palette set
+//---------------------------------------
+// POST DATA STORAGES
+//---------------------------------------
+UINT16 offset_shutdown; // 67 - Offset of shutdown routine
+UINT16 segment_shutdown; // 69 - Segment of shutdown routine
+UINT8 interrupt_flag; // 6B - Interrupt flag
+//----------------------------------------------------------------------------
+// TIMER DATA STORAGES
+//----------------------------------------------------------------------------
+//UINT16 timer_low_count; // 6C - Low Word of timer count
+//UINT16 timer_high_count; // 6E - High Word of timer count
+UINT32 timer_count; // 6C - timer count
+UINT8 timer_count_rolled; // 70 - Timer Rolled Over
+//----------------------------------------------------------------------------
+// BIOS DATA STORAGES EXTENDED
+//----------------------------------------------------------------------------
+UINT8 break_flag; // 71 - Flag for CTRL-BREAK key key
+UINT16 dummy_word; // 72 - Unused data word
+//----------------------------------------------------------------------------
+// WINCHESTER DATA STORAGES
+//----------------------------------------------------------------------------
+UINT8 winch_status; // 74 - Status of Hard Disk operation
+UINT8 winch_number; // 75 - Number of Hard Disk drives
+UINT8 winch_control_byte; // 76
+UINT8 dummy_byte_2; // 77
+//----------------------------------------------------------------------------
+// PRINTER & RS232 DATA STORAGES
+//----------------------------------------------------------------------------
+UINT8 print_time_max[4]; // 78 - Maximum time for printing
+UINT8 rs_232_time_max[4]; // 7C - Maximum transmission time for COM ports
+//----------------------------------------------------------------------------
+// KEYBOARD DATA STORAGES EXTENDED
+//----------------------------------------------------------------------------
+UINT16 kb_buff_begin; // 80 - Start address of Keyboard Buffer
+UINT16 kb_buff_end; // 82 - End address of Keyboard Buffer
+UINT8 rows_of_vdo[7]; // 84 - EGA/VGA control state
+//----------------------------------------------------------------------------
+// FLOPPY DATA STORAGES EXTENDED
+//----------------------------------------------------------------------------
+UINT8 last_xfer_rate; // 8B - Last data transfer rate (Floppy)
+//----------------------------------------------------------------------------
+// WINCHESTER DATA STORAGES EXTENDED
+//----------------------------------------------------------------------------
+UINT8 winch_stat_reg; // 8C - Hard Disk status register
+UINT8 winch_error_reg; // 8D - Hard Disk error register, a.k.a. iraid_int_flag
+UINT8 winch_int_flag; // 8E - Hard Disk interrupt status
+//----------------------------------------------------------------------------
+// FLOPPY DATA STORAGES EXTENDED
+//----------------------------------------------------------------------------
+UINT8 duel_card; // 8F - Availability of 1.2M Floppy Drive
+UINT8 current_floppy_media[2]; // 90 - Type of floppy drive/media
+UINT8 run_scratch1; // 92 - Runtime Scratch data byte 1
+UINT8 run_scratch2; // 93 - Runtime Scratch data byte 1
+UINT8 current_cylinder[2];// 94 - Cylinder position of Floppy Disk
+//----------------------------------------------------------------------------
+// KEYBOARD DATA STORAGES EXTENDED
+//----------------------------------------------------------------------------
+UINT8 dummy_byte_3; // 96 - Keyboard Type byte
+UINT8 kb_leds_flag; // 97 - Keyboard LED's status byte
+//----------------------------------------------------------------------------
+// REAL TIME CLOCK DATA STORAGES
+//----------------------------------------------------------------------------
+UINT16 user_flag_offset; // 98 - Offset of user defined flag
+UINT16 user_flag_segment; // 9A - Segment of user defined flag
+UINT16 user_wait_low; // 9C - Low WORD of user defined time
+UINT16 user_wait_high; // 9E - High WORD of user defined time
+UINT8 user_wait_flag[23]; // A0 - User defined time active flag, Video data area
+//----------------------------------------------------------------------------
+// APM HANDLING BIOS DATA AREA USED FOR GREEN PC/NOTE BOOK
+//----------------------------------------------------------------------------
+UINT8 apm_data[73]; // B7
+UINT8 prtsc_status_flag; // 100 - Print Screen status byte
+
+} BDA_DATA;
+
+#pragma pack ()
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CSM.c b/Core/EM/CSM/CSM.c
new file mode 100644
index 0000000..c3b5314
--- /dev/null
+++ b/Core/EM/CSM/CSM.c
@@ -0,0 +1,2926 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/csm.c 198 8/06/14 12:57p Fasihm $
+//
+// $Revision: 198 $
+//
+// $Date: 8/06/14 12:57p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/csm.c $
+//
+// 198 8/06/14 12:57p Fasihm
+// [TAG] EIP180667
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: CPU cache attributes need adjustment.
+// [Solution] Changed the cache attributes to WriteProtect for all 4
+// regions.
+// [Files]
+// Core/EM/CSM/CSM.c
+//
+// 197 1/10/14 12:21p Olegi
+// EIP149769: LegacyToEfi boot management
+// Changed default setting, added new token to extend the functionality
+//
+// 196 10/18/13 12:36p Olegi
+// EIP139866
+// Create interface to manage LegacyToEfi CSM feature
+//
+// 195 10/07/13 10:21a Olegi
+// [TAG] EIP138427
+// [Category] New Feature
+// [Description] Create interface to let OEM customers change CSM16
+// variables
+// [Files] csm.c, csm.h, csmlib.c, legacybiosext.h
+//
+// 194 10/07/13 8:57a Olegi
+// EIP135289
+// Legacy2Efi update
+//
+// 193 8/14/13 8:38a Olegi
+// EIP132753: Legacy2Efi module support
+//
+// 192 7/24/13 11:46a Olegi
+// [TAG] EIP121303
+// [Category] Improvement
+// [Description] UEFI Win7 hibernation wake up may fail
+// [Files] csm.c
+//
+// 191 5/03/13 2:38a Rameshr
+// [TAG] EIP117874
+// [Category] Improvement
+// [Description] Modified AllConnectedCallback function event is based
+// on TPL_NOTIFY
+// [Files] csm.c
+//
+// 190 4/29/13 12:31p Olegi
+// [TAG] EIP120105
+// [Category] Improvement
+// [Description] Incorrect 'CSM16LocationAttribute' passed to
+// CopyLegacyTable(), in CSM.c
+//
+// 189 4/09/13 9:25a Olegi
+// [TAG] EIP118727
+// [Category] New Feature
+// [Description] Onboard PCI Option ROM loading is moved outside CSM
+// [Files] CSM.mak
+// CSM.dxs
+// CSM.c
+// PciInterrupts.c
+// CsmBsp.c
+// CsmLib.c
+//
+// 188 12/24/12 12:06p Olegi
+// [TAG] EIP89376
+// [Category] Improvement
+// [Description] [CSM] Support to return EFI_SECURITY_VIOLATION from
+// EFI_Legacy_BIOS_Protocol.LegacyBoot when secure boot is on
+//
+// 187 12/18/12 1:44p Olegi
+// [TAG] EIP108682
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Invalid Error Code from CSM Functions
+// [RootCause] BIT31 is used as error indication
+// [Solution] use EFI_ERROR_BIT macro instead of BIT31
+// [Files] CSM.c
+// CsmHwInfo.c
+//
+// 186 12/14/12 3:04p Olegi
+// [TAG] EIP105734
+// [Category] Bug Fix
+// [Symptom] PCI Resource Issue with PLX Bridges
+// [RootCause] Bridge stays disabled on LegacyBoot
+// [Solution] Enable the bridges on legacy boot along with the other PCI
+// devices.
+//
+// 185 7/23/12 4:46p Olegi
+// [TAG] EIP93685
+// [Category] Improvement
+// [Description] Clear CSM used resources when it is disabled
+//
+// 184 7/23/12 12:10p Olegi
+// [TAG] EIP92416
+// [Description] Testing request for Smbios (INT)a_4.6.5.1_SMBIOS_32
+// label
+// LegacyBiosExt protocol is rearranged to match the one used by the
+// SMBIOS.
+//
+// 183 6/25/12 3:59p Olegi
+// [TAG] EIP90257
+// [Category] Improvement
+// [Description] In CSM, don't clear allocated memory below 640K - added
+// ClearFreeMemory function
+// [Files] CsmOpROM.c
+// CSM.c
+// CsmHwInfo.c
+//
+// 182 6/13/12 9:12a Olegi
+// [TAG] EIP90257
+// [Category] Improvement
+// [Description] In CSM, don't clear allocated memory below 640K.
+//
+// 181 12/23/11 3:09p Olegi
+// [TAG] EIP78921
+// [Category] Improvement
+// [Description] CsmBlockIo should create device handle in BBS table
+// [Files] CSM.h
+// CSM.c
+// CsmLib.c
+//
+// 180 12/23/11 2:47p Olegi
+// [TAG] EIP79228
+// [Category] Improvement
+// [Description] Implement CSM_INT19_TRAP_IMMEDIATE_ACTION functionality
+// [Files] CsmOpROM.c
+// CSM.c
+//
+// 179 11/14/11 11:59a Olegi
+//
+// 176 11/10/11 7:28p Olegi
+// CSM_OPTOUT_SUPPORT is replaced with CsmOptOut_SUPPORT master token.
+//
+// 175 10/31/11 11:55a Olegi
+// Installation of AMISCMStartedProtocolGuid is moved our of
+// CSM_OPTOUT_IMPLEMENTED scope.
+//
+// 174 10/12/11 10:06p Olegi
+// [TAG] EIP72331
+// [Category] Improvement
+// [Description] Added CSM_INIT_LEGACY_MEMORY_FUNCTIONS eLink for custom
+// memory initialization.
+// [Files] CSM.mak
+// CSM.c
+// CsmBsp.c
+//
+// 173 10/12/11 2:56p Olegi
+// [TAG] EIP72177
+// [Category] Improvement
+// [Description] CheckPmmTable function suppressed.
+// [Files] CsmOpROM.c
+// CSM.c
+// CsmBsp.c
+// CSM.SDL
+//
+// 172 10/03/11 5:05p Olegi
+//
+// 171 10/03/11 3:22p Olegi
+// [TAG] EIP71591
+// [Category] Improvement
+// [Description] CSM opt-out changes
+//
+// 170 10/03/11 1:44p Olegi
+// Modifications in HaltApsBeforeBoot function related to PI1.1
+//
+// 169 8/29/11 2:23p Olegi
+// [TAG] EIP56792
+// [Category] Improvement
+// [Description] Original fix for this EIP checked in earlier does not
+// work for the newer Core versions. FLEXBOOT has been depreciated for
+// newer Cores, and it must be enabled for proper operation.
+// [Files] csm.c
+//
+// 168 6/10/11 5:37p Olegi
+// [TAG] EIP59263
+// [Category] New Feature
+// [Description] High memory PMM area made dynamic.
+// [Files] CSM.h
+// CsmOpROM.c
+// CSM.c
+// CsmBsp.c
+// csm.sdl
+//
+// 167 6/10/11 5:07p Olegi
+// Undone check-ins #165 and #166 as EIP59263 is resolved differently.
+//
+// 164 3/24/11 9:39a Olegi
+// [TAG] EIP56792
+// [Category] Improvement
+// [Description] The value of FLEX_BOOT is depreciated for the newer
+// Core.
+// [Files] csm.c
+//
+// 163 3/15/11 3:50p Olegi
+// [TAG] EIP55913
+// [Category] Improvement
+// [Description] Remove LastOpromAddress from EFI_COMPATIBILITY16_TABLE
+// structure
+// [Files] Csm.c LegacyBios.h LegacyBiosExt.h
+//
+// 162 3/10/11 3:04a Rameshr
+// [TAG]- EIP 54231
+// [Category]-IMPROVEMENT
+// [Description]- Display the virus warning message when writting into MBR
+// of HDD. This support added for IDE, AHCI and USB HD devices.
+// [Files]- Csm.c, CsmOem.cif, Csm.uni, Csm.sdl, Csm.sd, Amilegacy16.bin,
+// AI13.Bin, Ui13.bin, VirusProtect module
+//
+// 161 3/08/11 12:44p Olegi
+// [TAG] EIP55496
+// [Category] Improvement
+// [Description] Added ebdaOffset field to SAVED_PCI_ROM structure to
+// ensure the correct EBDA saving/restoration.
+// [Files] CSM.h
+// CsmOpROM.c
+// CSM.c
+//
+// 160 12/13/10 5:29p Olegi
+// [TAG] EIP50206
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Calls to Get16BitFuncAddress() can hang the system when
+// CSM_OEM_SUPPORT is disabled
+// [RootCause] Disabling CSM_OEM_SUPPORT and calling
+// Get16BitFuncAddress() will hang the system because gCsm16FuncAddress is
+// NULL (uninitialized) and gCsm16FuncAddress is dereferenced.
+// [Solution] Added validation of gCsm16FuncAddress variable in
+// Get16BitFuncAddress function.
+// [Files] CSM.C
+//
+// 159 11/15/10 12:04p Olegi
+// [TAG] EIP47997
+// [Category] Improvement
+// [Description] Project tag updated in F000:F4F0
+// [Files] CSM.C
+//
+// 158 10/13/10 12:43p Olegi
+// Undoing the previous change related to InitCsmSimpleIn as it is not
+// generic change.
+//
+// 157 10/12/10 5:43p Olegi
+// Function call InitCsmSimpleIn made conditional; in the older BDS this
+// call causes problem. EIP43050
+//
+// 156 9/15/10 5:21p Olegi
+// Added reverse thunk stack allocation.
+//
+// 155 7/16/10 12:47p Olegi
+//
+// 154 7/16/10 12:31p Olegi
+// - EIP39395: Update CSM16 header checksum after LastPciBus field of it
+// has been changed.
+// - EIP39768: Modifications in the video mode switching policy
+// - Isolated all AMI CSM16 specific programming into a separate function
+// so that it can be skipped in case of non-AMI CSM16.
+//
+// 153 7/09/10 9:18a Olegi
+// Changed the sequence of HaltApsBeforeBoot and SignalAmiLegacyBootEvent
+// execution. EIP39089.
+//
+// 152 7/08/10 11:31a Olegi
+// Added SignalAmiLegacyBootEvent call. EIP39089
+//
+// 151 5/27/10 4:59p Olegi
+// Modified UpdatePciLastBus function, made it a callback notification on
+// PciIo, not on RootBridgeIo. EIP#39123.
+//
+// 150 5/14/10 4:16p Olegi
+//
+// 149 5/10/10 2:24p Olegi
+// Update BIOS date/time/rev in CSM16 area. EIP#34791
+//
+// 148 4/28/10 11:53a Olegi
+//
+// 147 3/26/10 9:36a Olegi
+// Dynamic CSM16 location calculation. EIP36484
+//
+// 146 3/02/10 5:13p Olegi
+// Making use of AmiExtPciBusProtocol when PCI Bus driver version is 240
+// or newer.
+//
+// 145 2/19/10 3:13p Olegi
+//
+// 144 2/19/10 1:24p Olegi
+// Changed the resolution of EIP34733 (>10s delay during boot). Root cause
+// of the problem is one of the LEGACY_BOOT callback notification
+// functions (BootNotify function in CpuDxe.c) is initializing IDT with
+// the "iret", at the same time interrupts kept enabled. This is not
+// suitable for the HW interrupt (IRQ1 from timer) - at least EOI must be
+// sent to PIC before executing "iret". This was causing a timeout while
+// reading the HDD in the PrepareToBoot function. The current solution is
+// to mask timer interrupt after all callback notifications are complete.
+//
+// 143 2/17/10 1:50p Olegi
+// Undo the final resolution for EIP32001: UpdatePciLastBus can not be
+// called from AllConnectedCallback as the last PCI bus # may be needed
+// earlier than that (Option ROMs). EIP35258.
+//
+// 142 2/05/10 7:14p Olegi
+//
+// 141 2/01/10 1:56p Olegi
+// EIP33173: During LegacyBoot set video mode 3 only if it is not set
+// already.
+//
+// 140 1/26/10 12:38p Olegi
+// EIP32001: functionality of UpdatePciLastBus function is moved to
+// AllConnectedCallback.
+//
+// 139 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 138 12/28/09 8:48a Olegi
+// RemoveDecodingForShadow call moved to LEGACYREGION.Lock
+//
+// 137 12/28/09 8:25a Olegi
+// WinCE loader support. EIP#30803
+//
+// 136 12/02/09 10:00a Olegi
+// EIP#23106: added NMI information related call.
+//
+// 135 12/01/09 11:40a Olegi
+// Changed the order of UpdateCmos-->EnableDisableNmi functions because
+// UpdateCmos will unconditionally enable NMIs.
+//
+// 134 11/17/09 12:06p Olegi
+// Changed the order of PrepareToBoot execution. It is moved after
+// singaling LegacyBoot event. The reason is PrepareToBoot finalizes E820
+// table and LegacyBoot event callbacks may allocate some memory that must
+// be reflected in E820 map. Example - S3 resume script memory. EIP#29087.
+//
+// 133 11/10/09 8:24a Olegi
+// Added CSM SimpleTextIn support. EIP#27843
+//
+// 132 10/27/09 8:08a Olegi
+// EIP#29883: Bugfix in InitCompatibility16 function.
+//
+// 131 6/16/09 4:11p Olegi
+// Generic modifications to update LastPciBus field in
+// EFI_COMPATIBILITY16_TABLE.
+//
+// 130 4/02/09 2:14p Olegi
+// Modification in EnablePciDevices: the counter of PCI devices was
+// declared as UINT8 - some configurations have more than 256 devices.
+// Changed to UINTN.
+//
+// 129 3/30/09 5:05p Olegi
+// Change in OEM16 routines: fixups are done so that every routine is
+// entered at a correct offset; no fixup is needed to access the local
+// variables. EIP#16383.
+//
+// 128 12/16/08 10:47a Olegi
+// Correction in the return value: 0 changed to NULL. EIP#17767
+//
+// 126 12/11/08 3:00p Olegi
+// Added shadow regions initialization. EIP#17763
+//
+// 125 12/09/08 3:31p Olegi
+// Added EfiGetPlatformGateA20Information function.
+//
+// 124 11/13/08 1:01p Olegi
+//
+// 123 11/12/08 4:59p Olegi
+// Added board specific hooks.
+//
+// 122 10/10/08 3:35p Olegi
+//
+// 121 9/23/08 2:18p Olegi
+//
+// 120 9/02/08 10:54a Olegi
+// Modification in EnablePciDevice function that will keep "unused" PCI
+// bridges disabled after legacy boot.
+//
+// 119 7/23/08 9:57a Fasihm
+// Fix EIP#: 14947: Added fix for CPU MTRR registers being inconsistent
+// between cores. Moved the RemoveDecodingForShadow call from after to
+// before the Signal_Legacy_Boot event.
+//
+// 118 6/30/08 3:50p Olegi
+//
+// 117 6/09/08 2:07p Olegi
+// Added HaltApsBeforeBoot routine that halts the APs before legacy boot.
+//
+// 116 5/19/08 12:37p Olegi
+// Removed EBDA size limitation.
+//
+// 115 4/14/08 2:45p Rameshraju
+// Removed the decoding for the remaining Shadow region
+//
+// 114 3/20/08 4:44p Olegi
+// FLEXBOOT initialization added.
+//
+// 113 3/12/08 11:59a Olegi
+// Added progress status codes.
+//
+// 112 1/31/08 11:53a Olegi
+// AllocateEbda call definition changed.
+//
+// 111 1/16/08 2:17p Olegi
+// Modified AllocateEbda function.
+//
+// 110 12/17/07 4:22p Olegi
+// KBC_SUPPORT dependency removed.
+//
+// 109 12/04/07 11:07a Olegi
+//
+// 108 10/24/07 12:27p Olegi
+// Function AllocateEbda added to LegacyBiosExt protocol.
+//
+// 107 10/17/07 3:23p Olegi
+// - modified PrepareToBoot to properly Unlock/Lock shadow regions. The
+// problem was with the ROMs that are not in the SavedRom list (service
+// ROMs or non-BBS compliant ROMs). After the final locking these ROMs
+// areas were not decoded
+// - modified GetBbsInfo to treat floppy with NO_FLOPPY_DISK and
+// FLOPPY_INSERTED the same way
+//
+// 106 8/23/07 9:14a Olegi
+// Reverted #105, it causes problems on MCP55 AMD projects. Instead,
+// UninstallMemoryManagerEF call is removed from CSM16 PrepareToBoot.
+//
+// 105 8/21/07 11:07a Olegi
+// CreateLegacyBootEvent moved before PrepareToBoot call so that legacy
+// boot event callbacks have a chance to allocate E/F memory
+//
+// 104 8/10/07 11:05a Olegi
+//
+// 103 7/23/07 12:41p Olegi
+// Change the order of PrepareToBoot and BspPrepareToBoot execution.
+//
+// 102 7/10/07 12:42p Olegi
+// Added the initialization of kbd head and tail in PrepareToBoot
+// function.
+//
+// 101 6/27/07 3:52p Olegi
+// Workaround for OpROMs that use 40:13 to allocate memory, not EBDA.
+//
+// 100 6/21/07 10:32a Olegi
+//
+// 99 6/18/07 5:46p Olegi
+// Added two new protocol functions GetEmbeddedRom and AddBbsEntry.
+//
+// 98 6/12/07 5:47p Olegi
+// Removed the loop that initializes the priorities for the existing BBS
+// devices.
+//
+// 97 6/12/07 2:59p Olegi
+//
+// 96 6/04/07 12:34p Olegi
+//
+// 95 6/04/07 10:45a Olegi
+//
+// 94 6/02/07 10:46a Olegi
+//
+// 93 6/02/07 10:25a Olegi
+// Shadow size correction.
+//
+// 92 6/01/07 12:29p Olegi
+// Fixed the return values while exiting the entry point.
+//
+// 91 5/29/07 12:21p Olegi
+// The code to disable Shadow W/R for the unused shadow regions is moved
+// to CsmOpROM.c
+//
+// 90 5/24/07 4:05p Olegi
+// Added two setup questions - NumLock state at boot and OpROM display
+// mode.
+//
+// 89 5/03/07 1:23p Olegi
+// PCIE_BASE_ADDRESS token is changed to PCIEX_BASE_ADDRESS
+//
+// 88 4/27/07 5:28p Olegi
+// PCIEX_BASE_ADDRESS is used instead of PCIE_BASE_ADDRESS. It is
+// currently defined in NB.SDL
+//
+// 87 4/27/07 5:13p Olegi
+// CSM.CHM file preparation.
+//
+// 86 4/20/07 11:31a Olegi
+// Bugfix in OEM interrupts and OEM 16-bit function initialization.
+//
+// 85 4/19/07 10:21a Olegi
+// Updated InitializeOem16 function.
+//
+// 84 4/12/07 1:28p Olegi
+//
+// 83 4/10/07 5:18p Olegi
+// LastOpromAddress is passed from CSM32 to CSM16.
+//
+// 82 3/01/07 9:12a Olegi
+//
+// 81 12/13/06 4:12p Olegi
+//
+// 80 12/12/06 5:30p Olegi
+// BBS table dump before PrepareToBoot.
+//
+// 79 10/13/06 12:30a Felixp
+// UEFI2.0 compliance: use CreateLegacyBootEvent instead of
+// CreateEvent(LEGACY_BOOT)
+//
+// 78 10/05/06 5:53p Olegi
+// Added context to EFI_EVENT_SIGNAL_LEGACY_BOOT event.
+//
+// 77 9/22/06 6:13p Olegi
+//
+// 76 9/20/06 11:35a Felixp
+// x64 warning fixed
+//
+// 75 8/24/06 6:49p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 74 8/16/06 2:38p Olegi
+// Previous typecast changes undone.
+//
+// 72 8/11/06 4:44p Olegi
+//
+// 71 7/31/06 4:05p Olegi
+//
+// 70 7/28/06 4:43p Olegi
+//
+// 68 7/07/06 8:24a Olegi
+// At entry point clear 0..640K, assuming no other driver allocated any
+// memory within this range. This assumption implies the whole
+// conventional memory directly and indirectly belongs to CSM.
+//
+// 67 7/05/06 3:42p Olegi
+// LegacyBoot used to do INT10 first, then TxtOut->ClearScreen. This
+// sequence needs to be reversed.
+//
+// 64 5/25/06 2:23p Olegi
+//
+// 63 5/16/06 1:57p Olegi
+//
+// 62 5/04/06 9:42a Olegi
+// Removed the logic that fixes the location of PATA/SATA in BBS table.
+//
+// 61 4/24/06 9:27a Olegi
+// Lock/UnLock shadow regions added before and after each CSM API call.
+//
+// 59 4/18/06 12:06p Olegi
+//
+// 58 4/18/06 10:38a Olegi
+// SHADOWREGION_GRANULARITY token has been removed; shadow regions
+// granularity is taken from Lock/Unlock routines.
+//
+// 57 4/17/06 4:27p Olegi
+//
+// 56 4/17/06 9:32a Olegi
+//
+// 55 3/31/06 4:44p Olegi
+//
+// 54 3/31/06 9:14a Olegi
+//
+// 53 3/30/06 1:20p Olegi
+//
+// 50 3/03/06 5:09p Olegi
+// EFI System Table pointer is passed to CSM16.
+//
+// 49 3/01/06 3:10p Olegi
+//
+// 47 2/23/06 7:06p Olegi
+// GetLegacyRegion and CopyLegacyRegion functions added.
+//
+// 46 12/16/05 2:59p Robert
+// Clear the screen before PrepareToBoot function: some BCVs (Netcell PCI
+// SATA RAID) attempt to output messages using INT10, this causes screen
+// corruption.
+//
+// 45 12/14/05 4:16p Olegi
+// NMI enable/disable changes.
+//
+// 44 12/12/05 12:13p Olegi
+//
+// 43 10/13/05 6:23p Olegi
+// Interrupt save/restore correction.
+//
+// 42 10/11/05 2:57p Olegi
+//
+// 41 10/11/05 11:56a Olegi
+//
+// 40 10/10/05 7:27p Olegi
+//
+// 39 9/30/05 6:27p Olegi
+// VC7.1 compatibility issues solved.
+//
+// 38 9/29/05 5:20p Olegi
+// Clear TxtOut screens before booting.
+//
+// 37 9/28/05 8:29a Olegi
+// Interrupt save/restore code is divided into SW and HW interrupts
+// restoration.
+//
+// 36 9/21/05 3:55p Olegi
+//
+// 35 9/09/05 6:04p Olegi
+//
+// 34 9/09/05 11:22a Olegi
+//
+// 33 9/06/05 10:48a Olegi
+//
+// 32 9/02/05 2:57p Olegi
+// Save/restore additional interrupts.
+//
+// 31 8/25/05 10:31a Olegi
+// Previous change undone, issue with some VGA cards that hook int 6d
+// (Matrox PCI) is solved different way: vector base for the master 8259
+// is changed from 0x68 to 0x58.
+//
+// 29 8/02/05 11:28a Olegi
+// GetBbsInfo: device priorities are initialized for all entries with
+// priority different from BBS_IGNORE.
+//
+// 28 6/22/05 8:35a Olegi
+//
+// 27 6/21/05 12:12p Olegi
+// LegacyBios and LegacyBiosPlatform are combined into one FFS.
+//
+// 26 4/29/05 8:42a Olegi
+//
+// 25 4/25/05 5:32p Olegi
+//
+// 24 4/22/05 2:11p Olegi
+//
+// 24 4/21/05 9:04a Olegi
+// - moved INT 13 vector manipulation here from BiosBlkIo
+// - added ShadowPciRoms and EnablePciDevices functions
+// - modified the sequence of signaling the boot event and locking shadow
+// in LegacyBoot function
+//
+// 23 4/19/05 11:16a Olegi
+// Signal legacy boot event code moved after the shadow memory is locked.
+//
+// 22 4/19/05 11:12a Olegi
+// ShadowAllLegacyOproms call added.
+//
+// 21 4/12/05 12:20p Olegi
+//
+// 20 3/10/05 4:45p Olegi
+// Removed ASSERT after allocation of shadow memory since it might be
+// allocated already.
+//
+// 19 3/04/05 1:53p Mandal
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CSM.C
+// Description: Compatibility Support Module entry point and interface functions.
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "token.h"
+#include "csm.h"
+#include <Protocol/cpu.h>
+#include <Protocol/PciIo.h>
+#include <AmiDxeLib.h>
+#include "biosdata.h"
+#include "pci.h"
+#include "setup.h"
+#include <Protocol/MPService.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/Timer.h>
+#include <Protocol/CsmPlatform.h>
+#include "timestamp.h"
+#include <ImageAuthentication.h>
+#include <Protocol/AmiBoardInfo.h>
+
+#include <AmiCspLib.h>
+#ifndef DEFAULT_TICK_DURATION
+#define DEFAULT_TICK_DURATION ((65535 * 838 + 50) / 100)
+#endif
+#define LTEB_GUID \
+ {0xC8BCA618, 0xBFC6, 0x46B7, 0x8D, 0x19, 0x83, 0x14, 0xE2, 0xE5, 0x6E, 0xC1}
+EFI_GUID gLTEBGuid = LTEB_GUID;
+
+#define AMI_PCI_BUS_EXT_PROTOCOL_GUID \
+{ 0xf42a009d, 0x977f, 0x4f08, 0x94, 0x40, 0xbc, 0xa5, 0xa3, 0xbe, 0xd9, 0xaf };
+
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93}
+
+#define WINCE_GUID \
+{ 0xC184562C,0x6864,0x40a3,{0xA0,0x81,0xC8,0xD3,0x5E,0x82,0xB9,0x20 }}
+
+EFI_GUID WinceGuid=WINCE_GUID;
+
+EFI_GUID gEfiMpServicesProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+EFI_GUID gBdsAllDriversConnectedProtocolGuid = BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID;
+
+BIOS_INFO *CoreBiosInfo = NULL;
+SAVED_PCI_ROM *gSavedOprom;
+BOOLEAN gServiceRomsExecuted = FALSE;
+
+UINT8 *gNextRomAddress; // PCI ROM address pointer, updated as ROMs are installed
+UINTN gMaxOpRomAddress; // Highest available address for PCI ROM
+
+EXECUTED_PCI_ROM *gExecutedRomsPci; // List of PciIo's with installed OpROMs
+VOID *mAllocatedOnceMemory = NULL;
+
+BOOLEAN gIsBootPrepared;
+BOOLEAN gIsBbsInitialized;
+BOOLEAN gIsMassStorageInstalled;
+
+UINT32 HwIrqRedirSav[8]; // hw interrupts redirected vectors - IRQ0..IRQ7
+UINT8 irq0;
+
+#define MAX_NUM_IRQS_SAVERESTORE 16
+IVT_SAVE_RESTORE gIrqSav[MAX_NUM_IRQS_SAVERESTORE];
+
+//
+// gSetTxtMode
+// 0 - switching to text mode is needed (init value)
+// 1 - switching is needed, restoration is not (set in ShadowOptionRoms)
+// 2 - neither switching nor restoration is needed
+//
+UINT8 gSetTxtMode;
+
+EFI_GUID guidSetup = SETUP_GUID;
+SETUP_DATA gSetup;
+
+OEMINT_FUNC *gCsm16IntStart = 0;
+OEM16_FUNC *gCsm16FuncAddress = 0;
+UINTN gCsm32DataAddress = 0;
+VOID *gProtocolNotifyRegistration;
+
+extern EFI_HANDLE gVgaHandle;
+
+AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfo = NULL;
+
+VOID ConnectSerialIO();
+VOID DisconnectSerialIO();
+VOID DummyFunction(EFI_EVENT Event, VOID *Context);
+EFI_TPL gOldTplValue = NULL;
+UINT16 gProtectedIrqMask = 0xffff;
+BBS_TABLE *gOriginalBbsTable = NULL;
+
+VOID DumpBbsTable(UINT32);
+#define BBS_LOWEST_ACTIVE_PRIORITY 0xfffb
+
+/*---------------------------------------------------*/
+/*--- ---*/
+/*--- AMI CSM Extensions Protocol functions ---*/
+/*--- ---*/
+/*---------------------------------------------------*/
+
+EFI_LEGACY_BIOS_EXT_PROTOCOL gAmiCsmExtensionsProtocol = {
+ GetEmbeddedRom,
+ AddBbsEntry,
+ InsertBbsEntryAt,
+ RemoveBbsEntryAt,
+ AllocateEbda,
+ UnlockShadow,
+ LockShadow,
+ Get16BitFuncAddress,
+ CopyLegacyTable,
+ InstallIsaRom,
+ GetShadowRamAddress,
+ GetBbsTable,
+ Csm16Configuration
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetEmbeddedRom
+//
+// Description:
+// This function calls FindEmbeddedRom to search for onboard Option ROM.
+//
+// Output:
+// EFI_SUCCESS or EFI_NOT_FOUND
+//
+// Referrals:
+// FindEmbeddedRom
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetEmbeddedRom (
+ IN UINT16 ModuleId,
+ IN UINT16 VendorId,
+ IN UINT16 DeviceId,
+ OUT VOID **ImageStart,
+ OUT UINTN *ImageSize
+)
+{
+ return FindEmbeddedRom(ModuleId, VendorId, DeviceId, ImageStart, ImageSize);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitializeCsm16MiscInfo
+//
+// Description:
+// This function initialize AMI specific CSM16 data: POST/RT variables in
+// CSM16 based on Setup settings, OEM porting overridesIt will be skipped
+// in case of non-AMI CSM16 binary.
+//
+//
+// Notes:
+// Shadow regions are unlocked.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitializeCsm16MiscInfo(
+ LEGACY16_TO_EFI_DATA_TABLE_STRUC *Csm16Data,
+ SETUP_DATA *Setup
+)
+{
+ UINT8 KbcSupport;
+ UINTN Data;
+ EFI_STATUS Status;
+
+ //
+ // Initialize misc_info
+ //
+ KbcSupport = IoRead8(0x64);
+ if (KbcSupport != 0xff) {
+ Csm16Configuration(Csm16FeatureReset, Csm16LegacyFree, NULL);
+ }
+ else {
+ Csm16Configuration(Csm16FeatureSet, Csm16LegacyFree, NULL);
+ }
+
+ if (Setup->ZipEmulation) {
+ Csm16Configuration(Csm16FeatureSet, Csm16ZipHddEmulation, NULL);
+ }
+
+ Csm16Configuration(Csm16FeatureSet, Csm16I19Trap, NULL);
+ Csm16Configuration(Csm16FeatureSet, Csm16Flexboot, NULL);
+
+ // Set GA20 related information in misc_info and rt_cmos_byte
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformGateA20Information,
+ NULL, NULL, NULL,
+ &Data, 0, 0);
+ if (!EFI_ERROR(Status)) {
+ if (Data & 1) {
+ Csm16Configuration(Csm16FeatureSet, Csm16GA20, NULL);
+ } else {
+ Csm16Configuration(Csm16FeatureReset, Csm16GA20, NULL);
+ }
+ if (Data & 2) {
+ Csm16Configuration(Csm16FeatureSet, Csm16SkipGA20Deactivation, NULL);
+ } else {
+ Csm16Configuration(Csm16FeatureReset, Csm16SkipGA20Deactivation, NULL);
+ }
+ }
+ // Set NMI related information in misc_info and rt_cmos_byte; if porting function is not
+ // implemented, enable NMI
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformNmiInformation,
+ NULL, NULL, NULL,
+ &Data, 0, 0);
+ if (EFI_ERROR(Status) || (Data == 1)) {
+ Csm16Configuration(Csm16FeatureSet, Csm16Nmi, NULL);
+ } else {
+ Csm16Configuration(Csm16FeatureReset, Csm16Nmi, NULL);
+ }
+
+ // Allocate stack for reverse thunk
+ {
+ EFI_PHYSICAL_ADDRESS RtStackPtr;
+ UINTN CsmRtStackPtrLocation;
+
+ Status = pBS->AllocatePages(AllocateAnyPages, EfiReservedMemoryType, 16, &RtStackPtr);
+ ASSERT_EFI_ERROR(Status);
+ pBS->SetMem( (UINT8*)(UINTN)RtStackPtr, 0x10000, 0 );
+ CsmRtStackPtrLocation = 0xf0000 + Csm16Data->ReverseThunkStackPtrOfs;
+ *(UINTN*)CsmRtStackPtrLocation = (UINTN)RtStackPtr + 0x10000;
+ }
+ {
+ // Update the E000 memory bounds
+ UINTN StartOfFreeE000Ptr = 0xf0000 + Csm16Data->StartOfFreeE000Ofs;
+ UINT16 StartOfFreeE000;
+ UINT16 SizeOfFreeE000;
+
+ ASSERT(gMaxOpRomAddress >= 0xdffff);
+ ASSERT(gMaxOpRomAddress < 0xeffff);
+
+ StartOfFreeE000 = (UINT16)((UINT32)gMaxOpRomAddress + 1); // Cut off upper word
+ SizeOfFreeE000 = ~StartOfFreeE000;
+
+ *(UINT16*)StartOfFreeE000Ptr = StartOfFreeE000;
+ *(UINT16*)(StartOfFreeE000Ptr + 2) = SizeOfFreeE000;
+ }
+ {
+ // Allocate legacy boot context save buffer and pass the pointer and the size to CSM16
+ UINTN NumberOfPages = EFI_SIZE_TO_PAGES(LEGACY_TO_EFI_BOOT_BUFFER_SIZE);
+ EFI_PHYSICAL_ADDRESS Address = 0xffffffff;
+ UINTN Csm16BufferPointer = 0xf0000 + Csm16Data->BootBufferPtrOfs;
+
+ Status = pBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ NumberOfPages,
+ &Address
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((-1, "CSM LegacyBoot context save buffer: %x, size %x; pointer is updated at %x\n",
+ Address, LEGACY_TO_EFI_BOOT_BUFFER_SIZE, Csm16BufferPointer));
+
+ *(UINT32*)Csm16BufferPointer = (UINT32)Address;
+ *(UINT32*)(Csm16BufferPointer+4) = LEGACY_TO_EFI_BOOT_BUFFER_SIZE;
+
+ Csm16Configuration(Csm16FeatureReset, Csm16LegacyToEfi, NULL);
+ Csm16Configuration(Csm16FeatureReset, Csm16LegacyToEfiPonr, NULL);
+
+#if LEGACY_TO_EFI_DEFAULT
+ Csm16Configuration(Csm16FeatureSet, Csm16LegacyToEfi, NULL);
+#if LEGACY_TO_EFI_BOOTRECORD_RETURN
+ Csm16Configuration(Csm16FeatureSet, Csm16LegacyToEfiPonr, NULL);
+#endif
+#endif
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: EnablePciDevices
+//
+// Description:
+// This function enables all PCI devices before legacy boot
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnablePciDevices(EFI_LEGACY_BIOS_PROTOCOL *Bios)
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Count;
+ EFI_HANDLE *Buffer;
+ UINTN i;
+ EFI_STATUS Status;
+ UINT8 PciCfg[4];
+ UINT64 Capabilities;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &Count,
+ &Buffer);
+ ASSERT_EFI_ERROR (Status);
+
+ for (i = 0; i < Count; i++) {
+ Status = pBS->HandleProtocol (Buffer[i], &gEfiPciIoProtocolGuid, &PciIo);
+ ASSERT_EFI_ERROR (Status);
+
+ PciIo->Pci.Read (PciIo, EfiPciIoWidthUint32, 8, 1, &PciCfg); // Reg 8,9,A,B
+
+ //
+ // Skip enabling device for:
+ // - VGA
+ // - Old VGA
+ // - IDE
+ // - LPC Bridge
+ //
+ if ((PciCfg[3]==PCI_CL_DISPLAY && PciCfg[2]==PCI_CL_DISPLAY_SCL_VGA)
+ || (PciCfg[3]==PCI_CL_OLD && PciCfg[2]==PCI_CL_OLD_SCL_VGA)
+ || (PciCfg[3]==PCI_CL_MASS_STOR && PciCfg[2]==PCI_CL_MASS_STOR_SCL_IDE)) {
+ continue;
+ }
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ pBS->FreePool(Buffer);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------------
+//
+// Name: UpdatePciLastBus
+//
+// Description:
+// In a multiple root-complex platform, the CSM16 routine "rth_pci_get_last_bus"
+// needs to return the correct bus number. For example, in a 2 IOH system, the
+// base bus #s for IOH0 can be 0 and IOH1 can be 80h. It should not be assumned
+// there is only one root-complex and return the correct bus # (max bus of first IOH),
+// for the card is plugged into the 2nd IOH.
+//
+// This function creates a callback notification event for EfiPciRootBridgeProtocol GUID
+// installation. The callback function then will process the list of root bridges and
+// will update the LastPciBus field of EFI_COMPATIBILITY16_TABLE accordingly.
+//
+//------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdatePciLastBus()
+{
+ EFI_STATUS Status;
+ EFI_EVENT UpdatePciLastBusEvent;
+ VOID *UpdatePciLastBusReg = NULL;
+ EFI_GUID AmiExtPciBusProtocolGuid = AMI_PCI_BUS_EXT_PROTOCOL_GUID;
+
+ //
+ // Create the notification and register callback function on the AmiExtPciBusProtocolGuid,
+ // callback function will update Pci Last Bus in Csm16 header.
+ //
+ Status = pBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ UpdatePciLastBusCallback,
+ NULL,
+ &UpdatePciLastBusEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->RegisterProtocolNotify (
+ &AmiExtPciBusProtocolGuid,
+ UpdatePciLastBusEvent,
+ &UpdatePciLastBusReg);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+VOID ReadyToBootNotify(EFI_EVENT Event, VOID *Context)
+{
+ EFI_TO_COMPATIBILITY16_INIT_TABLE *Csm16InitTable;
+
+ Csm16InitTable = &CoreBiosInfo->Thunk->Csm16InitTable;
+ pBS->FreePool((VOID*)(UINTN)Csm16InitTable->HiPmmMemory);
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CsmEntryPoint
+//
+// Description:
+// CSM driver entry point
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ UINT16 IrqMask, SaveIrqMask;
+ UINTN Size=sizeof(SETUP_DATA);
+ EFI_EVENT Event;
+ EFI_HANDLE Handle = NULL;
+ EFI_GUID AMICSMStartedProtocolGuid = AMI_CSM_DRIVER_STARTED_GUID;
+ EFI_GUID AMICSMLoadProtocolGuid = AMI_LOAD_CSM_GUID;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ PROGRESS_CODE(DXE_CSM_INIT);
+
+ // Indicate that CSM has been launched. This protocol can be used as dependecy for other driver instead of
+ // LegacyBIOS protocol which may or may not be installed.
+ pBS->InstallProtocolInterface (
+ &Handle, &AMICSMStartedProtocolGuid, EFI_NATIVE_INTERFACE, NULL
+ );
+
+ // Clear uninitialized memory @ 0..640K
+ Status = ClearFreeMemory(0, 0xa0000);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+#if CsmOptOut_SUPPORT
+ {
+ VOID *CsmLoad;
+
+ // Check if CSM needs to be enabled or not
+ Status = pBS->LocateProtocol (&AMICSMLoadProtocolGuid, NULL, &CsmLoad);
+ if (EFI_ERROR(Status)) {
+ // Unload the image if CSM needs to be disabled
+ return Status;
+ }
+ }
+#endif
+
+ //
+ // Initialize LegacyBiosPlatform
+ //
+ Status = InitCsmBoard (ImageHandle, SystemTable);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Initialize Csm Simple Key In
+ //
+ Status = InitCsmSimpleIn (ImageHandle, SystemTable);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Instantiate LEGACY_BIOS
+ //
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(BIOS_INFO), &CoreBiosInfo);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SetMem(CoreBiosInfo, sizeof(BIOS_INFO), 0);
+ CoreBiosInfo->hImage = ImageHandle;
+
+ Status = pBS->LocateProtocol (&gEfiLegacyRegionProtocolGuid, NULL, &CoreBiosInfo->iRegion);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->LocateProtocol (&gEfiLegacyBiosPlatformProtocolGuid, NULL, &CoreBiosInfo->iBiosPlatform);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, &CoreBiosInfo->i8259);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->LocateProtocol (&gEfiLegacyInterruptProtocolGuid, NULL, &CoreBiosInfo->iInterrupt);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->LocateProtocol(&gAmiBoardInfoProtocolGuid, NULL,(VOID**)&gAmiBoardInfo);
+ if(EFI_ERROR(Status)) return Status;
+
+ CoreBiosInfo->iBios.Int86 = Int86;
+ CoreBiosInfo->iBios.FarCall86 = FarCall86;
+ CoreBiosInfo->iBios.CheckPciRom = CheckPciRom;
+ CoreBiosInfo->iBios.InstallPciRom = InstallPciRom;
+ CoreBiosInfo->iBios.PrepareToBootEFI = PrepareToBoot;
+ CoreBiosInfo->iBios.LegacyBoot = LegacyBoot;
+ CoreBiosInfo->iBios.GetBbsInfo = GetBbsInfo;
+ CoreBiosInfo->iBios.ShadowAllLegacyOproms = ShadowAllLegacyOproms;
+ CoreBiosInfo->iBios.GetLegacyRegion = GetLegacyRegion;
+ CoreBiosInfo->iBios.CopyLegacyRegion = CopyLegacyRegion;
+ CoreBiosInfo->iBios.UpdateKeyboardLedStatus = UpdateKeyboardLedStatus;
+ //
+ // Call LegacyBiosPlatform to get the end of OpROM
+ //
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformEndRomShadowAddr,
+ NULL, NULL,
+ &gMaxOpRomAddress,
+ NULL, NULL, NULL);
+ if (EFI_ERROR(Status)) {
+ gMaxOpRomAddress = 0xDFFFF;
+ }
+
+ ASSERT(gMaxOpRomAddress > 0xC0000 && gMaxOpRomAddress < 0xF0000);
+
+ //
+ // Initialize memory
+ //
+ Status = InitializeLegacyMemory(CoreBiosInfo);
+ if (EFI_ERROR(Status)) return Status;
+
+ // Get the current IRQ mask
+ Status = CoreBiosInfo->i8259->GetMask(CoreBiosInfo->i8259, &SaveIrqMask, NULL, NULL, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ // Mask all interrupts
+ IrqMask = -1;
+ Status = CoreBiosInfo->i8259->SetMask(CoreBiosInfo->i8259, &IrqMask, NULL, NULL, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pRS->GetVariable(L"Setup",&guidSetup, NULL, &Size, &gSetup);
+ if (EFI_ERROR(Status)) {
+ pBS->SetMem(&gSetup, sizeof(SETUP_DATA), 0);
+ }
+
+ // The following code implements the video mode switching policy during
+ // Option ROMs installation. There are two ingredients in this policy
+ // implementation - one SDL token and one setup question:
+ //
+ // - SDL token CSM_DEFAULT_VMODE_SWITCHING
+ // - Setup question "Option ROM Messages" (use BIOS/keep current)
+ //
+ // Meaning of the "Option ROM Messages" setup options:
+ // - "Keep Current" installs dummy INT10, output from Option ROMs is
+ // suppressed, value of CSM_DEFAULT_VMODE_SWITCHING is ignored.
+ // - "Use BIOS" will have INT10 available for the Option ROMs to output
+ // the messages.
+ // Meaning of the CSM_DEFAULT_VMODE_SWITCHING:
+ // - 0 - switch video mode from graphics to text before executing the
+ // Option ROM, switch back to graphics afterwards
+ // - 1 - use text mode during all Option ROMs execution time, no mode
+ // switching during this time frame.
+
+ gSetTxtMode = CSM_DEFAULT_VMODE_SWITCHING;
+ if (Status == EFI_SUCCESS && gSetup.ExpansionCardText == 0) {
+ gSetTxtMode = 2;
+ }
+
+ //
+ // Copy Compatibility16 binary into shadow and
+ // call its Func0 (InitializeYourself)
+ //
+ Status = InitCompatibility16(CoreBiosInfo, SystemTable);
+ if (EFI_ERROR(Status)) return Status;
+
+ // Re-enable IRQ mask
+ Status = CoreBiosInfo->i8259->SetMask(CoreBiosInfo->i8259, &SaveIrqMask, NULL, NULL, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Create entries for legacy SW SMIs
+ //
+ Status = CoreBiosInfo->iBiosPlatform->SmmInit(
+ CoreBiosInfo->iBiosPlatform,
+ &CoreBiosInfo->Thunk->Csm16BootTable);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Make a new handle and install the protocol
+ //
+ CoreBiosInfo->hBios = NULL;
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &CoreBiosInfo->hBios,
+ &gEfiLegacyBiosProtocolGuid, &CoreBiosInfo->iBios,
+ &gEfiLegacyBiosExtProtocolGuid, &gAmiCsmExtensionsProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ CoreBiosInfo->hVga = NULL;
+
+ gNextRomAddress = (UINT8*)0xC0000; // Beginning of shadow region
+ gIsBootPrepared = FALSE;
+ gIsBbsInitialized = FALSE;
+ gIsMassStorageInstalled = FALSE;
+
+ //
+ // Allocate memory for saved OpROM structures
+ //
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ MAX_BCV_OPROMS * sizeof(SAVED_PCI_ROM),
+ &gSavedOprom);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SetMem(gSavedOprom, MAX_BCV_OPROMS * sizeof(SAVED_PCI_ROM), 0);
+ gSavedOprom++; // 1st entry is zero, this will let us find the beginning
+ // afterwards.
+ //
+ // Allocate memory for PciIo's with executed OpROMs
+ //
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ MAX_EXECUTED_OPROMS * sizeof(EXECUTED_PCI_ROM),
+ &gExecutedRomsPci);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SetMem(gExecutedRomsPci, MAX_EXECUTED_OPROMS * sizeof(EXECUTED_PCI_ROM), 0);
+ gExecutedRomsPci++; // 1st entry is zero, this will let us find the
+ // beginning afterwards.
+ //
+ // Register callback notification on AllDriverConnected.
+ // This is set to TPL_NOTIFY so that this callback gets executed first
+ // and GOP will be ready for the other callback function, who wants to
+ // display based on the AllDriverconnected event
+ //
+ Status = pBS->CreateEvent( EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ AllConnectedCallback,
+ NULL,
+ &Event );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->RegisterProtocolNotify(
+ &gBdsAllDriversConnectedProtocolGuid,
+ Event,
+ &gProtocolNotifyRegistration);
+
+
+ ASSERT_EFI_ERROR(Status);
+
+ UpdatePciLastBus(); // Update Pci Last Bus number in Csm16 Header
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK, ReadyToBootNotify, NULL, &Event);
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS; // Force success: every unsuccessful status is branched
+ // before, GetVariable status will not be successful on
+ // a "fresh" boot.
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AllConnectedCallback
+//
+// Description:
+// This function is executed after all drivers have been connected.
+//
+// Notes:
+// Specific to Core version, first time this event is signaled in 4.6.3.1.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+AllConnectedCallback (
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ if (gSetTxtMode == 1 && gVgaHandle != NULL) {
+ pBS->ConnectController(gVgaHandle, NULL, NULL, TRUE);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FindCompatibility16Table
+//
+// Description:
+// This function identifies the validity of CSM16 binary by searching "$EFI"
+// and verifying table checksum and returs the location of $EFI table
+//
+// Input:
+// RomImageStart Binary location address
+// RomImageSize Size in bytes
+//
+// Output:
+// Address of the beginning of $EFI table or NULL if this table is not found
+//
+// Notes:
+// Compatibility16 binary is linked with the current section
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_COMPATIBILITY16_TABLE*
+FindCompatibility16Table(
+ VOID *RomImageStart,
+ UINTN RomImageSize
+)
+{
+ UINT8 *ImageStart = RomImageStart;
+ UINT8 *ImageEnd = ImageStart + RomImageSize;
+
+ for (;ImageStart < ImageEnd; ImageStart +=16) {
+ if (*(UINT32*)ImageStart == '$EFI') {
+ UINT8 TableLength = ((EFI_COMPATIBILITY16_TABLE*)ImageStart)->TableLength;
+ UINT8 Checksum = 0;
+ UINT8 i;
+ for(i=0; i < TableLength; ++i) Checksum += ImageStart[i];
+ return (Checksum == 0) ? (EFI_COMPATIBILITY16_TABLE*)ImageStart : 0;
+ }
+ }
+
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ClearFreeMemory
+//
+// Description:
+// This function goes through system memory map and clears memory that is not
+// allocated within the given range.
+//
+// Input:
+// Start and End addresses
+//
+// Output:
+// EFI_STATUS the status of memory clearing operation
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ClearFreeMemory(
+ EFI_PHYSICAL_ADDRESS AddrFrom,
+ EFI_PHYSICAL_ADDRESS AddrTo
+)
+{
+ EFI_MEMORY_DESCRIPTOR *MemoryMap = NULL;
+ EFI_MEMORY_DESCRIPTOR *MemDesc = NULL;
+ UINTN DescriptorSize = 0;
+ UINTN NumberOfDescriptors = 0;
+ EFI_STATUS Status;
+ UINTN i;
+ UINTN Size;
+
+ Status = GetSystemMemoryMap(&MemoryMap, &DescriptorSize, &NumberOfDescriptors);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NumberOfDescriptors; i++)
+ {
+ MemDesc = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)MemoryMap + i * DescriptorSize);
+
+ if (MemDesc->Type == EfiConventionalMemory &&
+ MemDesc->PhysicalStart < AddrTo &&
+ MemDesc->PhysicalStart >= AddrFrom
+ )
+ {
+ Size = (UINTN)MemDesc->NumberOfPages * EFI_PAGE_SIZE;
+ if (((UINTN)MemDesc->PhysicalStart + Size) > (UINTN)AddrTo)
+ {
+ Size = (UINTN)AddrTo - (UINTN)MemDesc->PhysicalStart;
+ }
+
+ pBS->SetMem((VOID*)(UINTN)MemDesc->PhysicalStart, Size, 0);
+ }
+ }
+
+ pBS->FreePool(MemoryMap);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitializeLegacyMemory
+//
+// Description:
+// This function initializes CSM related memory regions
+//
+// Input:
+// BIOS_INFO *CoreBiosInfo
+//
+// Output:
+// EFI_STATUS Legacy memory initialization status
+//
+// Referrals:
+// BIOS_INFO
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitializeLegacyMemory(BIOS_INFO *CoreBiosInfo)
+{
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_CPU_ARCH_PROTOCOL Cpu;
+ EFI_CPU_ARCH_PROTOCOL *pCpu = &Cpu;
+ EFI_GUID gCpu = EFI_CPU_ARCH_PROTOCOL_GUID;
+ EFI_STATUS Status;
+ BDA_DATA *bda;
+ UINT8 *ebda;
+ BBS_TABLE *BbsEntry;
+ UINT16 i;
+ UINT32 TopOfBaseMemory;
+
+ //
+ // Set memory attributes for legacy regions
+ //
+ Status = pBS->LocateProtocol(&gCpu, NULL, &pCpu);
+ if (EFI_ERROR(Status)) return Status;
+ pCpu->SetMemoryAttributes(pCpu, 0xC0000, 0x40000, EFI_MEMORY_WP); // WriteProtected
+
+ //
+ // Allocate PMM and EBDA areas at the top of 640K; if some memory was already allocated,
+ // then adjust base memory information accordingly in 40:13 and EBDA
+ //
+ Address = 0xa0000;
+ Status = pBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesCode,
+ PMM_EBDA_LOMEM_SIZE >> 12, // Bytes->4KiloBytes conversion
+ &Address);
+
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ TopOfBaseMemory = (UINT32)Address+PMM_EBDA_LOMEM_SIZE;
+ ASSERT(TopOfBaseMemory>=PMM_EBDA_LOMEM_SIZE+0x8000); // PMM, EBDA, and extra 32KB must fit in
+ if (TopOfBaseMemory<(PMM_EBDA_LOMEM_SIZE+0x8000))
+ return EFI_OUT_OF_RESOURCES;
+
+ //
+ // Allocate base memory for IVT/BDA(0..2K), PMM data(2K..6K), Thunk (6K..32K),
+ // low memory PMM and EBDA (640K-PMM_EBDA_LOMEM_SIZE .. 640K).
+ //
+ Address = 0; // Allocate 0..32K
+ Status = pBS->AllocatePages (AllocateAddress,
+ EfiBootServicesCode, 8, &Address);
+ ASSERT_EFI_ERROR(Status);
+
+ CoreBiosInfo->Thunk = (THUNK_MEMORY*)0x1800; // at 6K
+
+ //
+ // Initialize BDA and EBDA
+ //
+ bda = (BDA_DATA*)((UINTN) 0x400);
+
+ bda->system_memory = (TopOfBaseMemory>>10)-1; // 1K is for BIOS EBDA
+ bda->kb_buf_head_ptr = bda->kb_buf_tail_ptr = 0x1E;
+ bda->motor_time_count = 0xFF;
+ bda->kb_buff_begin = 0x1E;
+ bda->kb_buff_end = 0x3E;
+
+ bda->current_floppy_media[0] = 7;
+ bda->winch_number = 0;
+// bda->machine_config is updated later when SIO information becomes available
+
+ bda->ext_bios_data_seg = (TopOfBaseMemory>>4)-0x40;
+
+ ebda = (UINT8*)((UINTN)(TopOfBaseMemory-0x400));
+ *ebda = 1; // 1K
+
+ //
+ // Create BBS table and initialize it with BBS_IGNORE_ENTRY values
+ //
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(BBS_TABLE)*MAX_BBS_ENTRIES_NO,
+ &CoreBiosInfo->BbsTable);
+ pBS->SetMem(CoreBiosInfo->BbsTable, sizeof(BBS_TABLE)*MAX_BBS_ENTRIES_NO, 0);
+
+ for (BbsEntry = CoreBiosInfo->BbsTable, i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+ BbsEntry->BootPriority = BBS_IGNORE_ENTRY;
+ }
+
+ CoreBiosInfo->BbsEntriesNo = MAX_IDE_CONTROLLER*2 + 1; // 1 floppy + up to MAX_IDE_CONTROLLER*2 HDD
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitCompatibility16
+//
+// Description:
+// This function reads Compatibility16 binary into the pre-defined shadow
+// memory region, executes InitializeYourself function and initializes Thunk
+// data structures.
+//
+// Input:
+// BIOS_INFO *CoreBiosInfo
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_SUCCESS = Success
+//
+// Notes:
+// InitializeLegacyMemory has to be executed prior to this function
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitCompatibility16(
+ IN BIOS_INFO *CoreBiosInfo,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ VOID *RomImageStart;
+ UINTN RomImageSize;
+ EFI_IA32_REGISTER_SET RegSet;
+ EFI_TO_COMPATIBILITY16_INIT_TABLE *Csm16InitTable;
+ UINT32 *ivt = (UINT32*)0;
+ UINT16 RedirSeg, RedirOfs;
+ UINT8 i;
+ UINTN LowPmmMemorySizeInBytes;
+ UINTN HiPmmMemorySizeInBytes;
+ VOID *HiPmmMemory;
+ UINTN PciExpressBase;
+
+ struct IRQ_REDIRECTION_CODE {
+ UINT8 intOpCode;
+ UINT8 intnumOpCode;
+ UINT8 iretOpCode;
+ } RedirTable[8] = {
+ {0xcd, 0x08, 0xcf}, // int 8, iret
+ {0xcd, 0x09, 0xcf}, // int 9, iret
+ {0xcd, 0x0a, 0xcf}, // int a, iret
+ {0xcd, 0x0b, 0xcf}, // int b, iret
+ {0xcd, 0x0c, 0xcf}, // int c, iret
+ {0xcd, 0x0d, 0xcf}, // int d, iret
+ {0xcd, 0x0e, 0xcf}, // int e, iret
+ {0xcd, 0x0f, 0xcf} // int f, iret
+ };
+
+ UINT8 *InterruptsToPreserve;
+ UINTN NumberOfInterruptsToPreserve;
+
+ //
+ // Open all shadow regions for writing and initalize them
+ //
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion,
+ 0xC0000, 0x40000, NULL);
+
+ pBS->SetMem((UINT8*)(UINTN)0xC0000, gMaxOpRomAddress-0xBFFFF, 0xFF);
+ pBS->SetMem((UINT8*)(gMaxOpRomAddress+1), 0xFFFFF-gMaxOpRomAddress, 0);
+
+ CoreBiosInfo->HddCount = 0;
+
+ //
+ // Get Eficompatibility16 binary
+ //
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformBinarySystemRom,
+ &RomImageStart, &RomImageSize,
+ NULL, NULL, NULL, NULL);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->CopyMem((VOID*)((UINTN)(0x100000-RomImageSize)), RomImageStart, RomImageSize);
+ RomImageStart = (VOID*)((UINTN)(0x100000-RomImageSize));
+
+ CoreBiosInfo->Csm16Header = FindCompatibility16Table(RomImageStart, RomImageSize);
+ if (CoreBiosInfo->Csm16Header == NULL) return EFI_NOT_FOUND;
+
+ //
+ // Save CSM16 entry point
+ //
+ CoreBiosInfo->Csm16EntrySeg = CoreBiosInfo->Csm16Header->Compatibility16CallSegment;
+ CoreBiosInfo->Csm16EntryOfs = CoreBiosInfo->Csm16Header->Compatibility16CallOffset;
+
+ //
+ // Get PCIe base address
+ //
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformPciExpressBase,
+ NULL, NULL,
+ &PciExpressBase,
+ NULL, NULL, NULL);
+
+ CoreBiosInfo->Csm16Header->PciExpressBase = (EFI_ERROR(Status))? 0 : (UINT32)PciExpressBase;
+
+//TODOx64: What is SystemTable pointer is more the 4G in 64 bit mode?
+//CSM specification 0.96 defines the pointer as UINT32
+ CoreBiosInfo->Csm16Header->EfiSystemTable = (UINT32)SystemTable;
+
+ //
+ // Initialize thunk code
+ //
+ Status = InitializeThunk(CoreBiosInfo);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Fill in EFI_TO_COMPATIBILITY16_INIT_TABLE for InitializeYourself input
+ //
+ Csm16InitTable = &CoreBiosInfo->Thunk->Csm16InitTable; // Located below 1 MB
+ Csm16InitTable->ThunkStart = (UINT32)CoreBiosInfo->Thunk;
+ Csm16InitTable->ThunkSizeInBytes = sizeof (THUNK_MEMORY);
+ Csm16InitTable->LowPmmMemory = 0xa0000-PMM_EBDA_LOMEM_SIZE;
+ Csm16InitTable->ReverseThunkCallSegment = Csm16InitTable->ThunkStart >> 4;
+ Csm16InitTable->ReverseThunkCallOffset = *(UINT16*)(UINTN)(Csm16InitTable->ThunkStart + 4);
+
+ GetExtendedMemSize(&Csm16InitTable->OsMemoryAbove1Mb);
+
+ //
+ // E820 table will be valid before PrepareToBoot
+ //
+ Csm16InitTable->NumberE820Entries = 0;
+
+ //
+ // Call LegacyBiosPlatform to get the PMM boundaries
+ //
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformPmmSize,
+ NULL,
+ &LowPmmMemorySizeInBytes,
+ NULL,
+ &HiPmmMemorySizeInBytes,
+ NULL,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ Csm16InitTable->LowPmmMemorySizeInBytes = (UINT32)LowPmmMemorySizeInBytes;
+ Csm16InitTable->HiPmmMemorySizeInBytes = (UINT32)HiPmmMemorySizeInBytes;
+
+ //
+ // Allocate Hi memory for PMM
+ //
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Csm16InitTable->HiPmmMemorySizeInBytes,
+ &HiPmmMemory);
+ ASSERT_EFI_ERROR(Status);
+ Csm16InitTable->HiPmmMemory = (UINT32)HiPmmMemory;
+
+ //
+ // Make a call to 16 bit code to initialize itself
+ //
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16InitializeYourself;
+ RegSet.X.ES = EFI_SEGMENT (Csm16InitTable);
+ RegSet.X.BX = EFI_OFFSET (Csm16InitTable);
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+ if (RegSet.X.AX) Status = (RegSet.X.AX & 0x7FFF) | EFI_ERROR_BIT;
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ // InitializeYourself (func #0) that has just executed, returns a pointer to
+ // LEGACY16_TO_EFI_DATA_TABLE_STRUC to pass the AMIBIOS specific data to CSM16
+ // This structure is AMI BIOS specific, so that the following call that updates
+ // CSM16 data structures must be avoided for non-AMI CSM16 binaries.
+
+ if (IsAMICSM16(CoreBiosInfo->Csm16Header)) {
+ // Program POST/RT variables in CSM16 based on Setup settings, OEM porting overrides
+ InitializeCsm16MiscInfo(
+ (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)Csm16InitTable->BiosLessThan1MB, &gSetup
+ );
+ }
+
+ Status = InitializePortingHooks(CoreBiosInfo);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1,"No OEM/Chipset CSM16 porting hooks found.\n"));
+ }
+
+ // Update project specific fields in CSM16 bin
+ if (IsAMICSM16(CoreBiosInfo->Csm16Header)) {
+
+ // BIOS date, time, and version information
+ UINT8 BiosDate[] = TODAY;
+ UINT8 BiosTime[] = NOW;
+ UINT8 *p = (UINT8*)0xff55b;
+
+ pBS->CopyMem(p, BiosDate, 6); // MM/DD/
+ // Place two-digit year since TODAY is in a different format
+ p[6] = BiosDate[8];
+ p[7] = BiosDate[9];
+
+ pBS->CopyMem(&p[9], BiosTime, 8); // BIOS time
+
+ Sprintf(&p[23], "%02X.%02X.%02X",
+ CORE_MAJOR_VERSION, CORE_MINOR_VERSION, CORE_REVISION);
+
+ // Update BIOS project tag
+ p = (UINT8*)0xff4f0;
+
+ // The following conversion assumes the following:
+ // 1. PROJECT_TAG to be 5 Bytes long, e.g. '0ABCD'; this assumption
+ // follows AMI project naming convention.
+ // 2. PROJECT_MAJOR_VERSION is limited to one decimal digit, i.e. in
+ // the range from 0 to 9.
+ // If it is greater than 9, then the upper digit(s) will be truncated. This is
+ // needed to keep the length of the project tag as 8.
+ Sprintf(&p[0], "%s%1d%02d",
+ CONVERT_TO_STRING(PROJECT_TAG), PROJECT_MAJOR_VERSION, PROJECT_MINOR_VERSION);
+ }
+
+ ChecksumCSM16Header(CoreBiosInfo->Csm16Header);
+
+ //
+ // Lock legacy region
+ //
+ CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ 0xC0000,
+ 0x40000,
+ NULL
+ );
+
+ //
+ // Initialize interrupt save tables with 0
+ //
+ pBS->SetMem(gIrqSav, sizeof(gIrqSav), 0);
+
+ //
+ // Prepare hardware interrupt (IRQ0...IRQF) redirection table
+ //
+ pBS->CopyMem(&CoreBiosInfo->Thunk->InterruptRedirectionCode, RedirTable, 8*3);
+ RedirSeg = EFI_SEGMENT(CoreBiosInfo->Thunk->InterruptRedirectionCode);
+ RedirOfs = EFI_OFFSET(CoreBiosInfo->Thunk->InterruptRedirectionCode);
+
+ CoreBiosInfo->i8259->GetVector(CoreBiosInfo->i8259, 0, &irq0);
+
+ for(i = 0; i < 8; i++) {
+ UINT32 vector;
+
+ HwIrqRedirSav[i] = ivt[irq0 + i];
+ vector = RedirSeg << 4 | RedirOfs;
+ ivt[irq0 + i] = vector;
+ RedirOfs += 3;
+ }
+
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformIntSaveRestoreTable,
+ &InterruptsToPreserve,
+ &NumberOfInterruptsToPreserve,
+ NULL, NULL, 0, 0);
+ if (!EFI_ERROR(Status)) {
+ if (NumberOfInterruptsToPreserve > MAX_NUM_IRQS_SAVERESTORE) {
+ NumberOfInterruptsToPreserve = MAX_NUM_IRQS_SAVERESTORE;
+ }
+ for (i = 0; i < NumberOfInterruptsToPreserve; i++) {
+ gIrqSav[i].irq_num = InterruptsToPreserve[i];
+ gIrqSav[i].irq_adr = ivt[InterruptsToPreserve[i]];
+ }
+ }
+
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetBbsInfo
+//
+// Description:
+// Presents BBS information to external agents.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// HddCount Number of HDD_INFO structures.
+// HddInfo Onboard IDE controller information.
+// BbsCount Number of BBS_TABLE structures.
+// BbsTable BBS entry.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetBbsInfo (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ OUT UINT16 *HddCount,
+ OUT struct _HDD_INFO **HddInfo,
+ OUT UINT16 *BbsCount,
+ IN OUT struct _BBS_TABLE **BbsTable
+)
+{
+ BBS_TABLE *BbsEntry;
+ UINT8 count=0;
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET RegSet;
+
+ if (!gIsBbsInitialized) {
+ //
+ // Insert floppy drive entry
+ //
+ BbsEntry = CoreBiosInfo->BbsTable;
+ BbsEntry->Bus = 0xFF;
+ BbsEntry->Device = 0xFF;
+ BbsEntry->Function = 0xFF;
+ BbsEntry->DeviceType = BBS_FLOPPY;
+ BbsEntry->Class = 1;
+ BbsEntry->SubClass = 2;
+
+ switch (GetFDDStatus()) {
+ case NO_FLOPPY_DRIVE: BbsEntry->BootPriority = BBS_IGNORE_ENTRY; break;
+ case NO_FLOPPY_DISK:
+ case FLOPPY_INSERTED: BbsEntry->BootPriority = BBS_UNPRIORITIZED_ENTRY; break;
+ }
+
+ if (!gIsMassStorageInstalled) {
+ InstallLegacyMassStorageDevices();
+ }
+ Status = UpdateCsm16Configuration(&CoreBiosInfo->Thunk->Csm16BootTable);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Make UpdateBBS call to CSM16 to adjust the table if needed.
+ //
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16UpdateBbs;
+ RegSet.X.ES = EFI_SEGMENT (&CoreBiosInfo->Thunk->Csm16BootTable);
+ RegSet.X.BX = EFI_OFFSET (&CoreBiosInfo->Thunk->Csm16BootTable);
+
+ Status = CoreBiosInfo->iRegion->UnLock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+ Status = (RegSet.X.AX)? ((RegSet.X.AX & 0x7FFF) | EFI_ERROR_BIT) : EFI_SUCCESS;
+ ASSERT_EFI_ERROR(Status);
+ CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+
+ CoreBiosInfo->BbsEntriesNo = CoreBiosInfo->Thunk->Csm16BootTable.NumberBbsEntries;
+ gIsBbsInitialized = TRUE;
+ }
+
+ *HddCount = CoreBiosInfo->HddCount;
+ *HddInfo = CoreBiosInfo->Thunk->Csm16BootTable.HddInfo;
+ *BbsCount = CoreBiosInfo->BbsEntriesNo;
+ *BbsTable = CoreBiosInfo->BbsTable;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: UpdateKeyboardLedStatus
+//
+// Description:
+// Updates the BDA to reflect status of the Scroll Lock, Num Lock, and Caps
+// Lock keys and LEDs.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// Leds Current LED status, as follows:
+// Bit 0 - Scroll Lock
+// Bit 1 - Num Lock
+// Bit 2 - Caps Lock
+// Output:
+// EFI_SUCCESS The BDA was updated successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateKeyboardLedStatus(
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINT8 Leds
+)
+{
+ *(UINT8*)0x417 &= 0x8F; // Clear BIT4, BIT5 and BIT6
+ *(UINT8*)0x417 |= (Leds << 4); // Set the state of xLock keys
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CopyLegacyTable
+//
+// Description:
+// This fuction allocates CSM16 memory within E0000..FFFFF and then copies the
+// passed data into allocated region.
+//
+// Input:
+// Data to be copied, data size and CSM16 and memory location attribute
+// (F0000_BIT or E0000_BIT or both)
+//
+// Notes:
+// CSM16 memory must be open for writing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINTN
+CopyLegacyTable(
+ VOID *Table,
+ UINT16 TableSize,
+ UINT16 Alignment,
+ UINT16 Csm16LocationAttribute)
+{
+ EFI_IA32_REGISTER_SET RegSet;
+ EFI_STATUS Status;
+ UINTN Dest = 0;
+
+ Status = CoreBiosInfo->iRegion->UnLock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16GetTableAddress;
+ RegSet.X.BX = Csm16LocationAttribute;
+ RegSet.X.CX = TableSize;
+ RegSet.X.DX = Alignment;
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ 0, 0);
+
+ Status = (RegSet.X.AX)? EFI_OUT_OF_RESOURCES : EFI_SUCCESS;
+ ASSERT_EFI_ERROR(Status);
+
+ if (!(EFI_ERROR(Status))) {
+ Dest = ((UINTN)RegSet.X.DS << 4) + RegSet.X.BX;
+ pBS->CopyMem((VOID*)Dest, Table, TableSize);
+ }
+
+ Status = CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return Dest;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetLegacyRegion
+//
+// Description:
+// This function is called when EFI needs to reserve an area in the 0xE0000
+// or 0xF0000 64 KB blocks.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// LegacyMemorySize Requested size in bytes of the region.
+// Region Requested region.
+// 00 = Either 0xE0000 or 0xF0000 blocks.
+// Bit0 = 1 Specify 0xF0000 block
+// Bit1 = 1 Specify 0xE0000 block
+// Alignment Bit-mapped value specifying the address alignment
+// of the requested region. The first nonzero value
+// from the right is alignment.
+// LegacyMemoryAddress Address assigned.
+//
+// Output:
+// EFI_SUCCESS The requested region was assigned.
+// EFI_ACCESS_DENIED The function was previously invoked.
+// Other The requested region was not assigned.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetLegacyRegion (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINTN LegacyMemorySize,
+ IN UINTN Region,
+ IN UINTN Alignment,
+ OUT VOID **LegacyMemoryAddress
+ )
+{
+ EFI_IA32_REGISTER_SET Regs;
+ EFI_STATUS Status;
+
+ CoreBiosInfo->iRegion->UnLock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+
+ pBS->SetMem(&Regs, sizeof (EFI_IA32_REGISTER_SET), 0);
+ Regs.X.AX = Compatibility16GetTableAddress;
+ Regs.X.BX = (UINT16) Region;
+ Regs.X.CX = (UINT16) LegacyMemorySize;
+ Regs.X.DX = (UINT16) Alignment;
+ FarCall86 (
+ This,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &Regs,
+ NULL,
+ 0
+ );
+
+ Status = (Regs.X.AX)? ((Regs.X.AX & 0x7FFF) | EFI_ERROR_BIT) : EFI_SUCCESS;
+
+ mAllocatedOnceMemory = (VOID *) (UINTN) ((Regs.X.DS << 4) + Regs.X.BX);
+ *LegacyMemoryAddress = mAllocatedOnceMemory;
+
+ CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CopyLegacyRegion
+//
+// Description:
+// This function is called when copying data to the region assigned by
+// EFI_LEGACY_BIOS_PROTOCOL.GetLegacyRegion().
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// LegacyMemorySize Size in bytes of the memory to copy.
+// LegacyMemoryAddress The location within the region returned by
+// EFI_LEGACY_BIOS_PROTOCOL.GetLegacyRegion().
+// LegacyMemorySourceAddress Source of the data to copy.
+//
+// Output:
+// EFI_SUCCESS The data was copied successfully.
+// EFI_ACCESS_DENIED Either the starting or ending address is out of bounds.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CopyLegacyRegion (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINTN LegacyMemorySize,
+ IN VOID *LegacyMemoryAddress,
+ IN VOID *LegacyMemorySourceAddress
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (((UINTN)LegacyMemoryAddress <= gMaxOpRomAddress) ||
+ ((UINTN) ((UINTN) (LegacyMemoryAddress) + LegacyMemorySize) > 0xFFFFF)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ Status = CoreBiosInfo->iRegion->UnLock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->CopyMem(LegacyMemoryAddress, LegacyMemorySourceAddress, LegacyMemorySize);
+
+ CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: PrepareToBoot
+//
+// Description:
+// This function is called when booting an EFI-aware OS with legacy hard disks.
+// The legacy hard disks may or may not be the boot device but will be accessed
+// by the EFI-aware OS.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// BbsCount Number of BBS_TABLE structures.
+// BbsTable BBS entry.
+//
+// Output:
+// Status of the boot preparation.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PrepareToBoot(
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ OUT UINT16 *BbsCount,
+ OUT struct _BBS_TABLE **BbsTable
+)
+{
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET RegSet;
+ UINTN E820MapAddress;
+ UINT32 *ivt = (UINT32*)0;
+ SAVED_PCI_ROM *rom;
+ UINT32 LockUnlockAddr, LockUnlockSize;
+
+ CoreBiosInfo->NumberE820Entries = UpdateE820Map(CoreBiosInfo->E820Map);
+
+ Status = UpdateCsm16Configuration(&CoreBiosInfo->Thunk->Csm16BootTable);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Copy prepared ACPI, E820 tables to F000 segment and update EFI header.
+ // Note that after executing CopyLegacyTable function E/F000 regions are read-only.
+ //
+ E820MapAddress = CopyLegacyTable(
+ CoreBiosInfo->E820Map,
+ CoreBiosInfo->NumberE820Entries * sizeof(E820_ENTRY),
+ 0, // alignment
+ 0); // either E000 or F000 segment
+ ASSERT(E820MapAddress);
+
+ //
+ // Unlock the shadow regions necessary for OpROM execution
+ //
+ Status = UnlockShadow(
+ (UINT8*)(UINTN)0xC0000,
+ (UINTN)gNextRomAddress-0xC0000,
+ &LockUnlockAddr,
+ &LockUnlockSize
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ CoreBiosInfo->Csm16Header->E820Pointer = (UINT32)E820MapAddress;
+ CoreBiosInfo->Csm16Header->E820Length = CoreBiosInfo->NumberE820Entries * sizeof(E820_ENTRY);
+
+ //
+ // Restore saved OpROMs and EBDAs associated with them
+ //
+ for (rom=gSavedOprom-1; rom->Address; rom--) {
+ pBS->CopyMem (
+ rom->Address,
+ rom->Data,
+ ((LEGACY_OPT_ROM_HEADER*)rom->Data)->Size512 * 0x200
+ );
+
+ if (rom->rtDataAddr) {
+ // Adjust rt data address according to the current EBDA location
+ if (rom->isEbda) {
+ rom->rtDataAddr = (UINT8*)(UINTN)((((UINT32)*(UINT16*)0x40e) << 4) + rom->ebdaOffset);
+ }
+
+ pBS->CopyMem (
+ rom->rtDataAddr,
+ rom->rtData,
+ rom->rtDataSize
+ );
+ }
+ }
+
+ //
+ // Reset number of ATA drives to let CSM16 PrepareToBoot function connect the drives
+ //
+ *(UINT8*)0x475 = 0;
+ //
+ // Make PrepareToBoot 16 bit call
+ //
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16PrepareToBoot;
+ RegSet.X.ES = EFI_SEGMENT (&CoreBiosInfo->Thunk->Csm16BootTable);
+ RegSet.X.BX = EFI_OFFSET (&CoreBiosInfo->Thunk->Csm16BootTable);
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+
+ Status = LockShadow(
+ LockUnlockAddr,
+ LockUnlockSize
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ if (RegSet.X.AX) Status = (RegSet.X.AX & 0x7FFF) | EFI_ERROR_BIT;
+
+ if (EFI_ERROR(Status)) return Status;
+
+ gIsBootPrepared = TRUE;
+
+ *BbsCount = CoreBiosInfo->BbsEntriesNo;
+ *BbsTable = CoreBiosInfo->BbsTable;
+
+ //
+ // Reinitialize keyboard buffer tail and head
+ //
+ *(UINT16*)0x41A = 0x1E;
+ *(UINT16*)0x41C = 0x1E;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: LegacyBoot
+//
+// Description:
+// Boots a traditional OS
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// BootOption The EFI device path from BootXXXX variable.
+// LoadOptionSize Size of LoadOption.
+// LoadOption The load option from BootXXXX variable.
+//
+// Output:
+// EFI_DEVICE_ERROR Failed to boot from any legacy boot device
+//
+// Notes:
+// This function normally never returns. It will either boot the OS or
+// reset the system if memory has been "corrupted" by loading a boot sector
+// and passing control to it.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacyBoot (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN BBS_BBS_DEVICE_PATH *BootOption,
+ IN UINT32 LoadOptionsSize,
+ IN VOID *LoadOptions
+)
+{
+ UINT16 BbsCount;
+ BBS_TABLE *BbsTable;
+ EFI_EVENT eLegacyBoot;
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET RegSet;
+ UINT32 *ivt = (UINT32*)0;
+ UINT16 i;
+ EFI_TIME boottime;
+ UINT32 localtime;
+ BDA_DATA *bda;
+ UINTN Count;
+ EFI_HANDLE *Buffer;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *TxtOut;
+ UINTN Size;
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *MediaDevicePath=(MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *)BootOption;
+ EFI_TIMER_ARCH_PROTOCOL *Timer;
+ UINT8 Data;
+ static EFI_GUID EfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_EVENT Event;
+
+ PROGRESS_CODE(DXE_LEGACY_BOOT);
+
+ //
+ // Check if Secure Boot is on; if so, return EFI_SECURITY_VIOLATION
+ //
+ Size = sizeof(UINT8);
+ Status = pRS->GetVariable(EFI_SECURE_BOOT_NAME, &EfiGlobalVariableGuid, NULL, &Size, &Data);
+ if(!EFI_ERROR(Status) && (Data != 0)) {
+ return EFI_SECURITY_VIOLATION; // no CSM in secure boot mode
+ }
+
+ //
+ // Clear all screens
+ //
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiSimpleTextOutProtocolGuid,
+ NULL,
+ &Count,
+ &Buffer);
+
+ if (!EFI_ERROR (Status)) {
+ for (i = 0; i < Count; i++) {
+ Status = pBS->HandleProtocol (Buffer[i], &gEfiSimpleTextOutProtocolGuid, &TxtOut);
+ ASSERT_EFI_ERROR (Status);
+ TxtOut->ClearScreen(TxtOut);
+ }
+ }
+
+ bda = (BDA_DATA*)((UINTN) 0x400);
+ if (bda->mode_of_vdo != 3) {
+ RegSet.X.AX = 3;
+ Status = CoreBiosInfo->iBios.Int86 (&CoreBiosInfo->iBios, 0x10, &RegSet);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //
+ // Update local time data in BDA (dword at 40:6C and byte at 40:70)
+ //
+ pRS->GetTime (&boottime, NULL);
+ localtime = (boottime.Hour * 3600 + boottime.Minute * 60 + boottime.Second) + 1;
+
+ localtime = (localtime * 182)/10; // Count number of timer ticks.
+
+ bda->timer_count = localtime;
+ bda->timer_count_rolled = 0;
+ for (i=0; i<4; i++) bda->print_time_max[i] = 0x14; // Maximum time for printing
+ for (i=0; i<4; i++) bda->rs_232_time_max[i] = 0x1; // Maximum transmission time for COM ports
+
+ UpdateCmos(); // This function unconditionally enables NMI
+ EnableDisableNmi();
+
+ //
+ // Restore saved interrupts
+ //
+ for(i = 0; gIrqSav[i].irq_adr; i++) {
+ ivt[gIrqSav[i].irq_num] = gIrqSav[i].irq_adr;
+ }
+
+ Status = ShadowAllLegacyOproms(This); // Launch remaining OpROMs
+ ASSERT_EFI_ERROR(Status);
+
+ // For the 1st boot store BBS table, else update the entries
+ if (gOriginalBbsTable == NULL){
+ Status = pBS->AllocatePool(EfiBootServicesData, (sizeof(BBS_TABLE))*CoreBiosInfo->BbsEntriesNo,
+ &gOriginalBbsTable);
+ ASSERT_EFI_ERROR(Status);
+ pBS->CopyMem(gOriginalBbsTable, CoreBiosInfo->BbsTable, (sizeof(BBS_TABLE))*CoreBiosInfo->BbsEntriesNo);
+ }
+ else
+ {
+ // find the lowest priority and update failed-to-boot entries with even lower priority values
+ UINT16 LowestPriority = 0;
+
+ for (i = 0; i < CoreBiosInfo->BbsEntriesNo; i++)
+ {
+ if (CoreBiosInfo->BbsTable[i].BootPriority > LowestPriority
+ && CoreBiosInfo->BbsTable[i].BootPriority <= BBS_LOWEST_ACTIVE_PRIORITY)
+ {
+ LowestPriority = CoreBiosInfo->BbsTable[i].BootPriority;
+ }
+ }
+ // the failed entries have the priority of BBS_UNPRIORITIZED_ENTRY (set by TSE)
+ for (i = 0; i < CoreBiosInfo->BbsEntriesNo; i++)
+ {
+ if (CoreBiosInfo->BbsTable[i].BootPriority == BBS_UNPRIORITIZED_ENTRY
+ && gOriginalBbsTable[i].BootPriority != BBS_UNPRIORITIZED_ENTRY)
+ {
+ CoreBiosInfo->BbsTable[i].BootPriority = ++LowestPriority; // bump the entry all the way back
+ ASSERT(LowestPriority < BBS_LOWEST_ACTIVE_PRIORITY);
+ }
+ }
+ }
+
+ DumpBbsTable(0);
+
+ Status = EnablePciDevices(This);
+ ASSERT_EFI_ERROR(Status);
+
+// The following call moved to LEGACYREGION.Lock, EIP29087
+// RemoveDecodingForShadow((UINT32)gNextRomAddress);
+
+ Status = pBS->LocateProtocol(&gEfiTimerArchProtocolGuid, NULL, &Timer);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Signal EFI_EVENT_SIGNAL_LEGACY_BOOT event
+ //
+ Status = CreateLegacyBootEvent (
+ TPL_CALLBACK, NULL, NULL, &eLegacyBoot
+ );
+
+ if (Status == EFI_SUCCESS) {
+ Status = pBS->SignalEvent(eLegacyBoot);
+ ASSERT_EFI_ERROR(Status);
+ pBS->CloseEvent(eLegacyBoot);
+ }
+
+ Timer->SetTimerPeriod (Timer, 0); // Kill timer, mask its interrupt
+
+ Status = CoreBiosInfo->iBiosPlatform->PrepareToBoot(
+ CoreBiosInfo->iBiosPlatform,
+ BootOption,
+ CoreBiosInfo->BbsTable,
+ LoadOptionsSize,
+ LoadOptions,
+ &CoreBiosInfo->Thunk->Csm16BootTable
+ );
+
+ Status = PrepareToBoot(This, &BbsCount, &BbsTable);
+ ASSERT_EFI_ERROR(Status);
+
+ HaltApsBeforeBoot();
+
+ SignalAmiLegacyBootEvent();
+
+ //
+ // Set NumLock state according to Setup question
+ //
+ Size = sizeof(SETUP_DATA);
+ Status = pRS->GetVariable(L"Setup",&guidSetup, NULL, &Size, &gSetup);
+ if (Status==EFI_SUCCESS) {
+ i = (gSetup.Numlock)? 2 : 0;
+ } else {
+ i = 2; // NumLock is on
+ }
+ //
+ // Note: GetVariable call could have been done once in the entry point,
+ // but in this case we will have to require reset on Setup.Numlock
+ // change.
+ //
+ UpdateKeyboardLedStatus(This, (UINT8)i);
+ //(EIP52733+)>
+ DisconnectSerialIO();
+ CoreBiosInfo->i8259->GetMask(CoreBiosInfo->i8259, NULL, NULL, &gProtectedIrqMask, NULL); // Save current Mask
+ //<(EIP52733+)
+
+ //
+ // Restore redirected HW IRQ0..7
+ //
+ //(EIP52733+)>
+ gOldTplValue = pBS->RaiseTPL(TPL_HIGH_LEVEL); // disable interrupts
+ //<(EIP52733+)
+ //
+ // Note: after this point TPL stays HIGH
+ //
+ for(i = 0; i < 8; i++) {
+ ivt[irq0 + i] = HwIrqRedirSav[i];
+ }
+
+ //
+ // Program legacy vector base in 8259
+ //
+ CoreBiosInfo->i8259->SetVectorBase (CoreBiosInfo->i8259, 8, 0x70);
+
+ if(guidcmp(&MediaDevicePath->NameGuid, &WinceGuid) == 0) {
+ return EFI_NOT_FOUND; // WinCE boot request, called from WinCE module
+ }
+ //
+ // Pass control to CSM16 to execute Int19
+ //
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16Boot;
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+ //(EIP52733+)>
+ pBS->RaiseTPL(TPL_HIGH_LEVEL); // disable interrupts
+ CoreBiosInfo->i8259->SetVectorBase(CoreBiosInfo->i8259, MASTER_INTERRUPT_BASE, SLAVE_INTERRUPT_BASE);
+ CoreBiosInfo->i8259->SetMask(CoreBiosInfo->i8259, NULL , NULL, &gProtectedIrqMask, NULL);
+
+ pBS->RestoreTPL(gOldTplValue);
+ Timer->SetTimerPeriod (Timer, DEFAULT_TICK_DURATION);
+
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ DummyFunction,
+ NULL,
+ &gLTEBGuid,
+ &Event);
+
+ pBS->SignalEvent(Event);
+ pBS->CloseEvent(Event);
+
+
+ if (gVgaHandle != NULL){
+ pBS->DisconnectController(gVgaHandle, NULL, NULL);
+ pBS->ConnectController(gVgaHandle, NULL, NULL, TRUE);
+ }
+ ConnectSerialIO();
+
+ return EFI_SUCCESS;
+
+ //<(EIP52733+)
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitializePortingHooks
+//
+// Description:
+// Initialize the data areas for Chipset/OEM 16 bit and 32 bit routines and
+// interrupt handlers.
+//
+// Input:
+// BIOS_INFO *CoreBiosInfo
+//
+// Output:
+// EFI_STATUS Success of failure of the operation.
+//
+// Notes:
+// At the point of calling CSM16 is loaded, no CSM16 function is executed.
+// E0000..FFFFF area is unlocked.
+//
+// Referrals:
+// BIOS_INFO
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitializePortingHooks (
+ BIOS_INFO *CoreBiosInfo
+)
+{
+ EFI_COMPATIBILITY16_TABLE *Csm16;
+
+ EFI_IA32_REGISTER_SET Registers;
+ EFI_STATUS Status;
+ VOID *OemData;
+ UINTN OemDataSize;
+
+ Csm16 = CoreBiosInfo->Csm16Header;
+
+ //
+ // Read OEM code/data image from the FW. The following steps are to be taken:
+ // 1) Copy it into E000/F000 area
+ // 2) Initialize the appropriate pointers in CSM16: Csm16->OemIntSegment/Offset,
+ // Csm16->Oem32Segment/Offset, Csm16->Oem16Segment/Offset.
+ //
+ Status = FindEmbeddedRom(OEM_MODULEID, CSM16_VENDORID, CSM16_DEVICEID,
+ &OemData, &OemDataSize);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SetMem(&Registers, sizeof (EFI_IA32_REGISTER_SET), 0);
+ Registers.X.AX = Compatibility16GetTableAddress;
+ Registers.X.BX = E0000_BIT; // Allocate from 0xE0000 64 KB block
+ Registers.X.CX = (UINT32)OemDataSize;
+ Registers.X.DX = 1; // Alignment
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg, CoreBiosInfo->Csm16EntryOfs,
+ &Registers, 0, 0);
+ Status = (Registers.X.AX)? ((Registers.X.AX & 0x7FFF) | EFI_ERROR_BIT) : EFI_SUCCESS;
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ gCsm16IntStart = (OEMINT_FUNC*)(UINTN)(((UINTN)Registers.X.DS << 4) + Registers.X.BX);
+
+ //
+ // Copy the data to E000/F000
+ //
+ pBS->CopyMem((VOID*)gCsm16IntStart, OemData, OemDataSize);
+
+ //
+ // Initialize OEM data and update CSM16 data pointers
+ //
+ gCsm16FuncAddress = InitializeOemInt(&Csm16->OemIntSegment);
+ gCsm32DataAddress = InitializeOem16(&Csm16->Oem16Segment);
+// InitializeOemData(&Csm16->Oem32Segment);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitializeOemInt
+//
+// Description:
+// Initialize OEM interrupts and update CSM16 OEM int pointer
+//
+// Input:
+// Csm16TableStart The address of the beginning of OEM table
+// Csm16Address The address of the beginning of OEM interrupt table handler(s)
+// Csm16InitSegPtr The address of the field with OEM interrupt pointer that is
+// passed to CSM16.
+//
+// Output:
+// Pointer to the next type of OEM code/data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+OEM16_FUNC*
+InitializeOemInt(
+ IN OUT UINT16 *Csm16InitSegPtr
+)
+{
+ OEMINT_FUNC *IntFuncTable;
+
+ UINT32 *ivt = (UINT32*)0;
+ UINT32 *IntSavAddress;
+
+ UINT16 Seg16 = (UINT16)((UINTN)gCsm16IntStart >> 4);
+
+ //
+ // Update Csm16 data pointer
+ //
+ *Csm16InitSegPtr = Seg16;
+ *(Csm16InitSegPtr+1) = 0;
+
+ //
+ // Initialize interrupt handlers with the interrupt original locations
+ //
+ for (IntFuncTable=gCsm16IntStart;IntFuncTable->interrupt!=0xFFFF;IntFuncTable++) {
+ IntSavAddress = (UINT32*)((UINTN)gCsm16IntStart+IntFuncTable->funcoffset-sizeof(UINT32));
+ // interrupt vector handshake
+ *IntSavAddress = ivt[IntFuncTable->interrupt];
+ ivt[IntFuncTable->interrupt] = ((UINT32)Seg16 << 16) + IntFuncTable->funcoffset;
+ }
+
+ //
+ // Return the pointer to the OEM16 function table that immediately follows OEMINT table
+ //
+ return (OEM16_FUNC*)(++IntFuncTable);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitializeOem16
+//
+// Description:
+// Initialize OEM interrupts and update CSM16 OEM int pointer
+//
+// Input:
+// Csm16TableStart The address of the beginning of OEM table
+// Csm16Address The address of the beginning of OEM16 data/code
+// Csm16InitSegPtr The address of the field with OEM16 pointer
+// that is passed to CSM16.
+//
+// Output:
+// Pointer to the next type of OEM code/data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINTN
+InitializeOem16(
+ IN OUT UINT16 *Csm16InitSegPtr
+)
+{
+ OEM16_FUNC *Oem16FuncTable;
+
+ UINT16 Seg16 = (UINT16)(((UINTN)gCsm16FuncAddress >> 4) & 0xf000);
+ UINT16 Ofs16 = (UINT16)((UINTN)gCsm16FuncAddress & 0xffff);
+
+ //
+ // Update Csm16 data pointer
+ //
+ *Csm16InitSegPtr = Seg16;
+ *(Csm16InitSegPtr+1) = Ofs16;
+
+ //
+ // Find the offset of the first OEM16 routine, use it to update the
+ // entry points of each CSM16 routine
+ //
+ Ofs16 = 0xffff;
+ for (Oem16FuncTable = gCsm16FuncAddress;
+ Oem16FuncTable->funcID != 0xffff; Oem16FuncTable++) {
+ if (Ofs16 > *(UINT16*)&Oem16FuncTable->funcOffset) {
+ Ofs16 = *(UINT16*)&Oem16FuncTable->funcOffset;
+ }
+ }
+
+ for (Oem16FuncTable = gCsm16FuncAddress;
+ Oem16FuncTable->funcID != 0xffff; Oem16FuncTable++) {
+ *(UINT16*)&Oem16FuncTable->funcOffset -= Ofs16;
+ }
+
+ //
+ // Update the OEM16 segment to SEG so that the 1st routine has an
+ // entry point at SEG:0. Store this SEG value at gCsm16FuncAddress-2
+ // This will make all offsets in OEM16_CSEG valid.
+ //
+ *(UINT16*)((UINTN)gCsm16FuncAddress-2) = (UINT16)(((UINTN)gCsm16IntStart + Ofs16) >> 4);
+
+ //
+ // Return the pointer to the OEM16 function table that immediately follows OEMINT table
+ //
+ return (UINTN)(++Oem16FuncTable);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Get16BitFuncAddress
+//
+// Description:
+// LegacyBiosExt API, returns the entry point of 16-bit function which was
+// added using "CsmOem16Functions" eLink
+//
+// Input:
+// id function ID
+//
+// Output:
+// EFI_SUCCESS if found, Addr is updated with 32-bit pointer to the function
+// EFI_NOT_FOUND if function with the requested ID is not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Get16BitFuncAddress (
+ IN UINT16 id,
+ OUT UINT32 *Addr
+)
+{
+ OEM16_FUNC *Oem16FuncTable;
+ UINT16 Seg16;
+
+ if (gCsm16FuncAddress == NULL) return EFI_NOT_FOUND;
+
+ Oem16FuncTable = gCsm16FuncAddress;
+ Seg16 = *(UINT16*)((UINTN)gCsm16FuncAddress-2);
+
+ for (; Oem16FuncTable->funcID != 0xffff; Oem16FuncTable++) {
+ if (Oem16FuncTable->funcID == id) {
+ *Addr = ((UINT32)Seg16<<4)+(UINT32)Oem16FuncTable->funcOffset;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: HaltApsBeforeBoot
+//
+// Description:
+// This call is halting APs before giving control to Legacy OS.
+//
+// Input:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+HaltApsBeforeBoot()
+{
+ UINTN NumberOfCPUs;
+ EFI_STATUS Status;
+ EFI_MP_SERVICES_PROTOCOL *MpServices;
+
+ // Execute on running APs
+ Status = pBS->LocateProtocol (&gEfiMpServicesProtocolGuid, NULL, &MpServices);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+// Use the #else path for the CPU modules compliant with PI1.1
+#if PI_SPECIFICATION_VERSION < 0x0001000A || BACKWARD_COMPATIBLE_MODE && defined(NO_PI_MP_SERVICES_SUPPORT)
+ MpServices->GetGeneralMPInfo(MpServices,
+ &NumberOfCPUs, NULL, NULL, NULL, NULL);
+#else
+{
+ UINTN NumberOfEnabledProcessors;
+
+ MpServices->GetNumberOfProcessors(MpServices,
+ &NumberOfCPUs, &NumberOfEnabledProcessors);
+}
+#endif
+
+ NumberOfCPUs--; //Exclude BSP
+ while(NumberOfCPUs) {
+ MpServices->EnableDisableAP(
+ MpServices,
+ NumberOfCPUs,
+ FALSE,
+ NULL);
+ NumberOfCPUs--;
+ }
+}
+
+
+VOID DumpBbsTable(UINT32 CaseNumber)
+{
+#ifdef EFI_DEBUG
+ BBS_TABLE *BbsEntry;
+ EFI_HANDLE Handle;
+ EFI_GUID DevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ EFI_DEVICE_PATH_PROTOCOL *dpp;
+ UINT32 i;
+ EFI_STATUS Status;
+
+ TRACE((-1,"_____BBS_TABLE(%x)_____\n", CaseNumber));
+ for (BbsEntry = CoreBiosInfo->BbsTable, i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+ if (BbsEntry->BootPriority == BBS_IGNORE_ENTRY) continue;
+ TRACE((-1, "#%02d: %d %02X/%02X/%02X %x %x %x %04X handle: %x %x, %s\n", i, BbsEntry->BootPriority,
+ (BbsEntry->Bus==0xffffffff)? 0xff : BbsEntry->Bus,
+ (BbsEntry->Device==0xffffffff)? 0xff : BbsEntry->Device,
+ (BbsEntry->Function==0xffffffff)? 0xff : BbsEntry->Function,
+ BbsEntry->Class, BbsEntry->SubClass,
+ BbsEntry->DeviceType, BbsEntry->StatusFlags,
+ BbsEntry->IBV1, BbsEntry->IBV2,
+ (UINTN)((UINTN)BbsEntry->DescStringSegment<<4) + BbsEntry->DescStringOffset
+ ));
+ Handle = *(VOID**)(&BbsEntry->IBV1);
+ if (Handle == 0) continue;
+ Status = pBS->HandleProtocol(Handle, &DevicePathProtocolGuid, &dpp);
+ TRACE((-1, "Handle=%x, HandleProtocol status: %r, DevicePath: %x\n", Handle, Status, dpp));
+ }
+#endif
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CSM.dxs b/Core/EM/CSM/CSM.dxs
new file mode 100644
index 0000000..55d82f2
--- /dev/null
+++ b/Core/EM/CSM/CSM.dxs
@@ -0,0 +1,62 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/csm.dxs 18 4/09/13 9:25a Olegi $
+//
+// $Revision: 18 $
+//
+// $Date: 4/09/13 9:25a $
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CSM.DXS
+//
+// Description: AMI CSM dependency file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol/LegacyRegion.h>
+#include <Protocol/LegacyInterrupt.h>
+#include <Protocol/Legacy8259.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/CsmPlatform.h>
+#include <Protocol/Variable.h>
+#include <Protocol/AmiBoardInfo.h>
+
+DEPENDENCY_START
+ EFI_LEGACY_INTERRUPT_PROTOCOL_GUID AND
+ EFI_LEGACY_REGION_PROTOCOL_GUID AND
+ EFI_LEGACY_8259_PROTOCOL_GUID AND
+ EFI_CPU_ARCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+ AMI_BOARD_INFO_PROTOCOL_GUID AND
+ EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CSM.h b/Core/EM/CSM/CSM.h
new file mode 100644
index 0000000..1016a5b
--- /dev/null
+++ b/Core/EM/CSM/CSM.h
@@ -0,0 +1,1089 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/csm.h 88 8/06/14 3:20p Fasihm $
+//
+// $Revision: 88 $
+//
+// $Date: 8/06/14 3:20p $
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CSM.H
+//
+// Description: AMI CSM header file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef __CSM_HEADER__
+#define __CSM_HEADER__
+
+#include "efi.h"
+#include <Protocol\DevicePath.h>
+#include <Protocol\LegacyBios.h>
+#include <Protocol\LegacyRegion.h>
+#include <Protocol\Legacy8259.h>
+#include <Protocol\LegacyInterrupt.h>
+#include <Protocol\LegacyBiosPlatform.h>
+#include <Protocol\SimpleTextOut.h >
+#include <GenericSio.h>
+#include <Protocol\LegacyBiosExt.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack (1)
+
+#define EFI_LEGACY_BIOS_GUID \
+ { 0x2e3044ac, 0x879f, 0x490f, 0x97, 0x60, 0xbb, 0xdf, 0xaf, 0x69, 0x5f, 0x50 }
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_TO_COMPATIBILITY16_INIT_TABLE
+//
+// Description: Data structure passed to Compatibility16InitializeYourself
+// function.
+// Fields:
+// BiosLessThan1MB UINT32 Starting address of memory under 1 MB.The ending address is assumed to be 640 KB or 0x9FFFF.
+//
+// HiPmmMemory UINT32 Starting address of the high memory block
+//
+// HiPmmMemorySizeInBytes UINT32 Length of high memory block
+//
+// ReverseThunkCallSegment UINT16 The segment of the reverse thunk call code
+//
+// ReverseThunkCallOffset UINT16 The offset of the reverse thunk call code
+//
+// Number820Entries UINT32 The number of E820 entries copied to the Compatibility16 BIOS
+//
+// OsMemoryAbove1Mb UINT32 The amount of usable memory above 1 MB, e.g., E820 type 1 memory
+//
+// ThunkStart UINT32 The start of thunk code in main memory. Memory cannot be used by BIOS or PMM.
+//
+// ThunkSizeInBytes UINT32 The size of the thunk code
+//
+// LowPmmMemory UINT32 Starting address of memory below 1MB
+//
+// LowPmmMemorySizeInBytes UINT32 Length of low Memory block
+//
+// Referrals: Compatibility16InitializeYourself
+//
+// Notes: - The address of the ReverseThunkCall code is provided in case
+// the Compatibility16 code needs to invoke a Compatibility16
+// function. It is not used to return from this function or any
+// other traditional BIOS interface function. These functions simply
+// do a far return.
+// - CSM16 must handle cases where PMM pointers are NULL. That indicates
+// that PMM is not supported for that range. If both pointers are NULL
+// then PMM is not supported. That covers cases where no add-in cards
+// are supported and/or memory given to EFI.
+// - CSM16 must initialize PMM regions to zero prior to usage by OpROMs.
+// CSM16 can not assume the CSM32 had zeroed out the regions.
+// - CSM16 must monitor for EBDA size increase after OpROM is initalized
+// and adjust PMM below 1MB, if required.
+// - BiosLessThan1MB field is maintained for compatibility with the
+// previous versions of the specification and the CSM16 should not use this
+// field. The CSM16 should use LowPmmMemory and LowPmmMemorySizeInBytes fields
+// for the low memory that can be used for PMM.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT32 BiosLessThan1MB;
+ UINT32 HiPmmMemory;
+ UINT32 HiPmmMemorySizeInBytes;
+ UINT16 ReverseThunkCallSegment;
+ UINT16 ReverseThunkCallOffset;
+ UINT32 NumberE820Entries;
+ UINT32 OsMemoryAbove1Mb;
+ UINT32 ThunkStart;
+ UINT32 ThunkSizeInBytes;
+ UINT32 LowPmmMemory;
+ UINT32 LowPmmMemorySizeInBytes;
+} EFI_TO_COMPATIBILITY16_INIT_TABLE;
+
+//****************************************************
+// CSM16 related equates
+//****************************************************
+// misc_info bits
+#define CSM16_HEADLESS_INT19_RETRY_BIT 0x80
+#define CSM16_I19_TRAP_BIT 0x40
+#define CSM16_I13_HDD_MBR_WP_BIT 0x20
+#define CSM16_NO_USB_BOOT_BIT 0x10
+#define CSM16_NO_KBC_PRESENT_BIT 0x08
+#define CSM16_ZIP_HDD_EMUL_BIT 0x04
+#define CSM16_FLEXBOOT_ENABLE_BIT 0x02
+#define CSM16_FLEXBOOT_ENABLE_SHIFT_CNT 1
+#define CSM16_FAST_GATE_A20_BIT 0x01
+
+// rt_cmos_byte bits
+#define CSM_RT_CMOS_LTE_PONR_BIT 0x02
+#define CSM_RT_CMOS_PARITY_BIT 0x08
+#define CSM_RT_CMOS_SKIP_GA20_DEACTIVATION_BIT 0x10
+#define CSM_RT_CPU_RM_ONBOOT_BIT 0x20
+#define CSM_RT_CMOS_PS2_BIT 0x40
+#define CSM_RT_CMOS_LTE_BIT 0x80
+
+//****************************************************
+// Type values
+//****************************************************
+#define STANDARD_IO 0x00
+#define STANDARD_MEMORY 0x01
+
+//****************************************************
+// PortGranularity values
+//****************************************************
+#define PORT_SIZE_8 0x00
+#define PORT_SIZE_16 0x01
+#define PORT_SIZE_32 0x02
+#define PORT_SIZE_64 0x03
+
+//****************************************************
+// DataGranularity values
+//****************************************************
+#define DATA_SIZE_8 0x00
+#define DATA_SIZE_16 0x01
+#define DATA_SIZE_32 0x02
+#define DATA_SIZE_64 0x03
+
+#define EFI_SEGMENT(_Adr) (UINT16)((UINT16) (((UINTN)(_Adr)) >> 4) & 0xf000)
+#define EFI_OFFSET(_Adr) (UINT16)(((UINT16)((UINTN)_Adr)) & 0xffff)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SMM_FUNCTION
+//
+// Fields:
+// Function UINT16 Function this Soft SMI is to initiate
+// Owner UINT16 The definer of the function
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT16 Function : 15;
+ UINT16 Owner : 1;
+} SMM_FUNCTION;
+
+
+//****************************************************************************
+// Function values
+//****************************************************************************
+#define INT15_D042 0x0000
+#define GET_USB_BOOT_INFO 0x0001
+#define DMI_PNP_50_57 0x0002
+//
+// Following is a description of the fields in the above definition.
+//
+// INT15_D042 - System Configuration Data functions accessed via INT15 AX=0xD042.
+// GET_USB_BOOT_INFO - Retrieves USB boot device information for integration with BBS.
+// DMI_PNP_50_57 - Process the DMI Plug and Play functions 0x50 through
+// 0x57 via SMM code.
+// The other values are reserved for future use.
+//
+
+//****************************************************************************
+// Owner values
+//****************************************************************************
+#define STANDARD_OWNER 0x0
+#define OEM_OWNER 0x1
+//
+// Following is a description of the fields in the above definition.
+//
+// STANDARD_OWNER - This document has defined the function.
+// OEM_OWNER - An agent, other than this document, has defined the function.
+//
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SMM_ATTRIBUTES
+//
+// Fields:
+// Type UINT16 Access mechanism used to generate the soft SMI
+// PortGranularity UINT16 Size of "port" in bits
+// DataGranularity UINT16 Size of data in bits
+// Reserved UINT16 Reserved for future use
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT16 Type : 3;
+ UINT16 PortGranularity : 3;
+ UINT16 DataGranularity : 3;
+ UINT16 Reserved : 7;
+} SMM_ATTRIBUTES;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SMM_ENTRY
+//
+// Fields:
+// SmmAttributes SMM_ATTRIBUTES Describes the access mechanism, SmmPort, and SmmData sizes
+// SmmFunction SMM_FUNCTION Function Soft SMI is to perform
+// SmmPort UINT16 SmmPort size depends upon SmmAttributes and ranges from 2 bytes to 16 bytes
+// SmmData UINT16 SmmData size depends upon SmmAttributes and ranges from 2 bytes to 16 bytes
+//
+// Referrals: SMM_ATTRIBUTES, SMM_FUNCTION
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ SMM_ATTRIBUTES SmmAttributes;
+ SMM_FUNCTION SmmFunction;
+ UINT16 SmmPort;
+ UINT16 SmmData;
+} SMM_ENTRY;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SMM_TABLE
+//
+// Description: SMM Table definitions; SMM table has a header that provides
+// the number of entries. Following the header is a variable
+// length amount of data.
+// Fields:
+// NumSmmEntries UINT16 Number of entries represented by SmmEntry
+// SmmEntry SMM_ENTRY One entry per function
+//
+// Referrals: SMM_ENTRY
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT16 NumSmmEntries;
+ SMM_ENTRY SmmEntry;
+} SMM_TABLE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: LEGACY_DEVICE_FLAGS
+//
+// Fields:
+// A20Kybd UINT32:1 A20 controller by keyboard controller.
+// A20Port92 UINT32:1 A20 controlled by port 0x92.
+// Reserved UINT32:30 Reserved for future usage.
+//
+// Notes: A20Kybd and A20Port92 are not mutually exclusive.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT32 A20Kybd:1;
+ UINT32 A20Port92:1;
+ UINT32 Reserved:30;
+} LEGACY_DEVICE_FLAGS;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DEVICE_PRODUCER_FLOPPY
+//
+// Fields:
+// Address UINT16 I/O address assigned to the floppy
+// Irq UINT8 IRQ assigned to the floppy.
+// Dma UINT8 DMA assigned to the floppy.
+// NumberOfFloppy UINT8 Number of floppies in the system.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT16 Address;
+ UINT8 Irq;
+ UINT8 Dma;
+ UINT8 NumberOfFloppy;
+} DEVICE_PRODUCER_FLOPPY;
+
+typedef enum {FLOPPY_INSERTED, NO_FLOPPY_DISK, NO_FLOPPY_DRIVE} FDD_STATUS;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DEVICE_PRODUCER_PARALLEL
+//
+// Fields:
+// Address UINT16 I/O address assigned to the parallel port
+// Irq UINT8 IRQ assigned to the parallel port.
+// Dma UINT8 DMA assigned to the parallel port.
+// Mode PARALLEL_MODE Mode of the parallel port.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+//****************************************************************************
+// Parallel Mode values
+//****************************************************************************
+#define DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY 0x00
+#define DEVICE_PARALLEL_MODE_MODE_BIDIRECTIONAL 0x01
+#define DEVICE_PARALLEL_MODE_MODE_EPP 0x02
+#define DEVICE_PARALLEL_MODE_MODE_ECP 0x03
+
+typedef UINT8 PARALLEL_MODE;
+
+typedef struct {
+ UINT16 Address;
+ UINT8 Irq;
+ UINT8 Dma;
+ PARALLEL_MODE Mode;
+} DEVICE_PRODUCER_PARALLEL;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DEVICE_PRODUCER_SERIAL
+//
+// Fields:
+// Address UINT16 I/O address assigned to the serial port
+// Irq UINT8 IRQ assigned to the serial port
+// Mode SERIAL_MODE Mode of serial port
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+//****************************************************************************
+// Serial Mode values
+//****************************************************************************
+#define DEVICE_SERIAL_MODE_NORMAL 0x00
+#define DEVICE_SERIAL_MODE_IRDA 0x01
+#define DEVICE_SERIAL_MODE_ASK_IR 0x02
+#define DEVICE_SERIAL_MODE_DUPLEX_HALF 0x00
+#define DEVICE_SERIAL_MODE_DUPLEX_FULL 0x10
+
+typedef UINT8 SERIAL_MODE;
+typedef struct {
+ UINT16 Address;
+ UINT8 Irq;
+ SERIAL_MODE Mode;
+} DEVICE_PRODUCER_SERIAL;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DEVICE_PRODUCER_DATA_HEADER
+//
+// Fields:
+// Serial DEVICE_PRODUCER_SERIAL Data for serial port x
+// Parallel DEVICE_PRODUCER_PARALLEL Data for parallel port x
+// Floppy DEVICE_PRODUCER_FLOPPY Data for floppy
+// MousePresent UINT8 Flag to indicate if mouse is present
+// Flags LEGACY_DEVICE_FLAGS Miscellaneous Boolean state information passed to CSM
+//
+// Referrals: DEVICE_PRODUCER_SERIAL, DEVICE_PRODUCER_PARALLEL,
+// DEVICE_PRODUCER_FLOPPY, LEGACY_DEVICE_FLAGS
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ DEVICE_PRODUCER_SERIAL Serial[4];
+ DEVICE_PRODUCER_PARALLEL Parallel[3];
+ DEVICE_PRODUCER_FLOPPY Floppy;
+ UINT8 MousePresent;
+ LEGACY_DEVICE_FLAGS Flags;
+} DEVICE_PRODUCER_DATA_HEADER;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_TO_COMPATIBILITY16_BOOT_TABLE
+//
+// Description: Data structure passed to Compatibility16InitializeYourself
+// function.
+// Fields:
+// MajorVersion UINT16 The EfiCompatibility major version number.
+// MinorVersion UINT16 The EfiCompatibility minor version number.
+// AcpiTable UINT32 Location of the RSDT ACPI table.
+// SmbiosTable UINT32 Location of the SMBIOS table in EFI memory.
+// SmbiosTableLength UINT32 Length of the SMBIOS table in bytes.
+// SioData DEVICE_PRODUCER_DATA_HEADER Standard traditional device information.
+// DevicePathType UINT16 The default boot type. See notes for details.
+// PciIrqMask UINT16 Mask of which IRQs have been assigned to PCI.
+// NumberE820Entries UINT32 Number of E820 entries.
+// HddInfo HDD_INFO Hard disk drive information, including raw Identify Drive data.
+// NumberBbsEntries UINT32 Number of entries in the BBS table
+// BbsTable UINT32 Pointer to the BBS table.
+// SmmTable UINT32 Pointer to the SMM table.
+// OsMemoryAbove1Mb UINT32 The amount of usable memory above 1 MB, i.e. E820 type 1 memory.
+// UnconventionalDeviceTable UINT32 Information to boot off an unconventional device like a PARTIES partition.
+//
+// Referrals: Compatibility16InitializeYourself, EFI_TO_COMPATIBILITY16_INIT_TABLE, HDD_INFO
+//
+// Notes: Following are the defined DevicePathType values:
+// FD = Floppy
+// HD = Hard Disk
+// CDROM = CD-ROM
+// PCMCIA = PCMCIA
+// USB = USB
+// NET = Networks
+// BEV = BBS BEV devices
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+//#define MAX_IDE_CONTROLLER 8
+#define MAX_IDE_CONTROLLER 12
+struct _UD_TABLE;
+
+typedef struct {
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+
+ UINT32 AcpiTable; // 4 GB range
+ UINT32 SmbiosTable; // 4 GB range
+ UINT32 SmbiosTableLength;
+ //
+ // Legacy SIO state
+ //
+ DEVICE_PRODUCER_DATA_HEADER SioData;
+ UINT16 DevicePathType;
+ UINT16 PciIrqMask;
+ UINT32 NumberE820Entries;
+ //
+ // Controller & Drive Identify[2] per controller information
+ //
+ HDD_INFO HddInfo[MAX_IDE_CONTROLLER];
+ UINT32 NumberBbsEntries;
+ UINT32 BbsTable;
+ UINT32 SmmTable;
+ UINT32 OsMemoryAbove1Mb;
+ UINT32 UnconventionalDeviceTable;
+} EFI_TO_COMPATIBILITY16_BOOT_TABLE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_LEGACY_INSTALL_PCI_HANDLER
+//
+// Fields:
+// PciBus UINT8 The PCI bus of the device.
+// PciDeviceFun UINT8 The PCI device in bits 7:3 and function in bits 2:0.
+// PciSegment UINT8 The PCI segment of the device.
+// PciClass UINT8 The PCI class code of the device.
+// PciSubclass UINT8 The PCI subclass code of the device.
+// PciInterface UINT8 The PCI interface code of the device.
+// PrimaryIrq UINT8 The primary device IRQ.
+// PrimaryReserved UINT8 Reserved.
+// PrimaryControl UINT16 The primary device control I/O base.
+// PrimaryBase UINT16 The primary device I/O base.
+// PrimaryBusMaster UINT16 The primary device bus master I/O base.
+// SecondaryIrq UINT8 The secondary device IRQ.
+// SecondaryReserved UINT8 Reserved.
+// SecondaryControl UINT16 The secondary device control I/O base.
+// SecondaryBase UINT16 The secondary device I/O base.
+// SecondaryBusMaster UINT16 The secondary device bus master I/O base.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT8 PciBus;
+ UINT8 PciDeviceFun;
+ UINT8 PciSegment;
+ UINT8 PciClass;
+ UINT8 PciSubclass;
+ UINT8 PciInterface;
+ //
+ // Primary section
+ //
+ UINT8 PrimaryIrq;
+ UINT8 PrimaryReserved;
+ UINT16 PrimaryControl;
+ UINT16 PrimaryBase;
+ UINT16 PrimaryBusMaster;
+ //
+ // Secondary section
+ //
+ UINT8 SecondaryIrq;
+ UINT8 SecondaryReserved;
+ UINT16 SecondaryControl;
+ UINT16 SecondaryBase;
+ UINT16 SecondaryBusMaster;
+} EFI_LEGACY_INSTALL_PCI_HANDLER;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_DISPATCH_OPROM_TABLE
+//
+// Fields:
+// PnpInstallationCheckSegment UINT16 Segment of the PnpInstallationCheck data structure.
+// PnpInstallationCheckOffset UINT16 Offset of the PnpInstallationCheck data structure.
+// OpromSegment UINT16 The segment where the OpROM was placed. Offset is assumed to be 3.
+// PciBus UINT8 The PCI bus.
+// PciDeviceFunction UINT8 The PCI device * 0x08 | PCI function.
+// NumberBbsEntries UINT8 The number of valid BBS table entries upon entry and exit.
+// BbsTable UINT32 Pointer to the BBS table.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+#define MAX_EXECUTED_OPROMS 32
+
+typedef struct {
+ IN UINT16 PnpInstallationCheckSegment;
+ IN UINT16 PnpInstallationCheckOffset;
+ IN UINT16 OpromSegment;
+ IN UINT8 PciBus;
+ IN UINT8 PciDeviceFunction;
+ IN OUT UINT8 NumberBbbsEntries;
+ UINT32 BbsTable;
+ IN UINT16 FinalLocationSegment;
+} EFI_DISPATCH_OPROM_TABLE;
+
+typedef struct {
+ UINTN Seg;
+ UINTN Bus;
+ UINTN Dev;
+ UINTN Fun;
+ UINTN Flags;
+ UINT8 DiskFrom;
+ UINT8 DiskTo;
+ VOID *RomAddress;
+ UINT32 RomSize;
+} EXECUTED_PCI_ROM;
+
+BOOLEAN Int86 (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINT8 BiosInt,
+ IN EFI_IA32_REGISTER_SET *Regs
+);
+
+BOOLEAN FarCall86 (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN EFI_IA32_REGISTER_SET *Regs,
+ IN VOID *Stack,
+ IN UINTN StackSize
+);
+
+EFI_STATUS CheckPciRom (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage, OPTIONAL
+ OUT UINTN *RomSize, OPTIONAL
+ OUT UINTN *Flags
+);
+
+EFI_STATUS InstallPciRom (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ IN VOID **RomImage,
+ OUT UINTN *Flags,
+ OUT UINT8 *DiskStart, OPTIONAL
+ OUT UINT8 *DiskEnd, OPTIONAL
+ OUT VOID **RomShadowAddress, OPTIONAL
+ OUT UINT32 *ShadowedRomSize OPTIONAL
+);
+
+EFI_STATUS
+ShadowAllLegacyOproms (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This
+);
+
+EFI_STATUS FindEmbeddedRom(
+ UINT16 ModuleId, UINT16 VendorId, UINT16 DeviceId,
+ VOID **ImageStart, UINTN *ImageSize
+);
+
+EFI_STATUS
+GetLegacyRegion (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINTN LegacyMemorySize,
+ IN UINTN Region,
+ IN UINTN Alignment,
+ OUT VOID **LegacyMemoryAddress
+);
+
+EFI_STATUS
+CopyLegacyRegion (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINTN LegacyMemorySize,
+ IN VOID *LegacyMemoryAddress,
+ IN VOID *LegacyMemorySourceAddress
+);
+
+EFI_STATUS
+UnlockShadow(
+ IN UINT8 *Address,
+ IN UINTN Size,
+ OUT UINT32 *LockUnlockAddr,
+ OUT UINT32 *LockUnlockSize
+);
+
+EFI_STATUS
+LockShadow(
+ IN UINT32 LockAddr,
+ IN UINT32 LockSize
+);
+
+EFI_STATUS
+RemoveDecodingForShadow(
+ IN UINT32 DecodeAddr
+);
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: AMIIRQ_HEADER
+//
+// Description: AMI IRQ Routing Table Header Structure
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT32 dSignature; // '$IRT' signature
+ UINT8 bTotalEntries; // total number of slot entries present in the table
+ UINT8 bUsedEntries; // number of used slot entries in the table
+ UINT16 wExclusiveIRQ; // bitmap of IRQs used exclusively for PCI
+ UINT32 dPtrIRQSlotStart; // pointer to start of IRQ slot entries
+} AMIIRQ_HEADER;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_ADDON_PCIBUS_TABLE
+//
+// Description: Table that holds the information about the buses generated by
+// P2P bridges that are not listed in $PIR table
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT8 Bus;
+ EFI_LEGACY_PIRQ_ENTRY PirqEntry[4];
+} EFI_ADDON_PCIBUS_TABLE;
+
+
+//**********************************************************************
+//
+// The following sections is a list of the CSM16 APIs. They do not
+// require definitions and given here for reference only. (And of course
+// these headers could be used to prepare the interactive help file.)
+//
+//**********************************************************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16InitializeYourself (Function 0)
+//
+// Description: Causes the Compatibility16 code to do any internal initialization
+// required. The EFI_TO_COMPATIBILITY16_INIT_TABLE pointer is passed
+// into this function.
+// Input:
+// AX = Compatibility16InitializeYourself
+// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_INIT_TABLE
+//
+// Output: Status Codes Returned
+//
+// Referrals: EFI_TO_COMPATIBILITY16_INIT_TABLE, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16UpdateBbs (Function 1)
+//
+// Description: Causes the Compatibility16 BIOS to perform any drive number
+// translations to match the boot sequence.
+// Input:
+// AX = Compatibility16UpdateBbs
+// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
+//
+// Output: Status Codes Returned
+// EFI_SUCCESS 0x0000
+//
+// Referrals: EFI_TO_COMPATIBILITY16_BOOT_TABLE, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16PrepareToBoot (Function 2)
+//
+// Description: Allows the Compatibility16 code to perform any final actions
+// before booting. The Compatibility16 code is read/write.
+// Input:
+// AX = Compatibility16PrepareToBoot
+// ES:BX = Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE structure
+//
+// Output: Status Codes Returned
+//
+// Referrals: EFI_TO_COMPATIBILITY16_BOOT_TABLE, DEVICE_PRODUCER_DATA_HEADER
+// HDD_INFO, BBS_TABLE, BBS_STATUS_FLAGS, SMM_TABLE, UD_TABLE,
+// UDC_ATTRIBUTES, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16Boot (Function 3)
+//
+// Description: Causes the Compatibility16 BIOS to boot. The Compatibility16
+// code is Read/Only.
+// Input: AX = Compatibility16Boot
+//
+// Output: Status Codes Returned
+//
+// Referrals: EFI_TO_COMPATIBILITY16_BOOT_TABLE, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16RetrieveLastBootDevice (Function 4)
+//
+// Description: Allows the Compatibility16 code to get the last device from
+// which a boot was attempted. This is stored in CMOS and is
+// the priority number of the last attempted boot device.
+//
+// Input: AX = Compatibility16RetrieveLastBootDevice
+//
+// Output: AX = Returned status codes:
+// EFI_SUCCESS 0x0000
+// EFI_ABORTED 0x8015
+// BX = Priority number of the boot device
+//
+// Referrals: EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16DispatchOprom (Function 5)
+//
+// Description: Allows the Compatibility16 code rehook INT13, INT18, and/or
+// INT19 after dispatching a legacy OpROM.
+// Input: AX = Compatibility16DispatchOprom
+// ES:BX = Pointer to EFI_DISPATCH_OPROM_TABLE
+//
+// Output: AX = Returned status codes
+// BX = Number of non-BBS-compliant devices found. Equals 0 if
+// BBS compliant.
+//
+// Referrals: EFI_DISPATCH_OPROM_TABLE, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16GetTableAddress (Function 6)
+//
+// Description: Finds a free area in the 0xFxxxx or 0xExxxx region of the
+// specified length and returns the address of that region.
+// Input: AX = Compatibility16GetTableAddress
+// BX = Allocation region
+// 00 = Allocate from either 0xE0000 or 0xF0000 64 KB blocks.
+// Bit 0 = 1 Allocate from 0xF0000 64 KB block
+// Bit 1 = 1 Allocate from 0xE0000 64 KB block
+// CX = Requested length in bytes.
+// DX = Required address alignment. Bit mapped. First non-zero bit
+// from the right is the alignment.
+//
+// Output: AX = Returned status codes:
+// EFI_SUCCESS 0x0000
+// EFI_OUT_OF_RESOURCES 0x8009
+// DS:BX = Address of the region
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16SetKeyboardLeds (Function 7)
+//
+// Description: Enables the EfiCompatibility module to do any nonstandard
+// processing of keyboard LEDs or state.
+// Input: AX = Compatibility16SetKeyboardLeds
+// CL = LED status:
+// Bit 0 - Scroll Lock 0 = Off
+// Bit 1 - Num Lock
+// Bit 2 - Caps Lock
+// Output: Status Codes Returned
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Compatibility16InstallPciHandler (Function 8)
+//
+// Description: Enables the EfiCompatibility module to install an interrupt
+// handler for PCI mass media devices that do not have an OpROM
+// associated with them. An example is SATA
+//
+// Input: AX = Compatibility16InstallPciHandler
+// ES:BX = Pointer to EFI_LEGACY_INSTALL_PCI_HANDLER structure
+//
+// Output: Status Codes Returned
+//
+// Referrals: EFI_LEGACY_INSTALL_PCI_HANDLER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#define MAX_DRIVE_NAME 32
+
+typedef struct _DRIVE_DISPLAY_NAME {
+ UINT8 DriveName[MAX_DRIVE_NAME];
+} DRIVE_DISPLAY_NAME;
+
+typedef struct _IDE_CONTROLLER_INFO_STRUC {
+ UINT16 BusDevFun; // Bus, Device and Function number
+ UINT8 ControllerNo; // Controller number for IDE controller
+} IDE_CONTROLLER_INFO_STRUC;
+
+typedef struct {
+ UINT8 ThunkCode[0x4000]; // 12KB = 4KB of code + 8KB of stack
+ UINT8 InterruptRedirectionCode[24]; // 3 bytes of code per interrupt
+ EFI_TO_COMPATIBILITY16_INIT_TABLE Csm16InitTable;
+ EFI_TO_COMPATIBILITY16_BOOT_TABLE Csm16BootTable;
+ EFI_LEGACY_INSTALL_PCI_HANDLER PciHandler;
+ EFI_DISPATCH_OPROM_TABLE DispatchOpromTable;
+ DRIVE_DISPLAY_NAME DriveDisplayName[2*MAX_IDE_CONTROLLER];
+} THUNK_MEMORY;
+
+#define MAX_E820_ENTRIES 256
+typedef enum {
+ MemRangeAvl = 1,
+ MemRangeRes = 2,
+ MemRangeAcpiReclaim = 3,
+ MemRangeAcpiNVS = 4
+} E820_MEMORY_TYPE;
+
+#define E820_EXTATTR_ADDRESS_RANGE_ENABLED 1
+#define E820_EXTATTR_ADDRESS_RANGE_NONVOLATILE 2
+typedef struct {
+ UINT64 Adr;
+ UINT64 Len;
+ E820_MEMORY_TYPE Type;
+ UINT32 ExtendedAttr;
+} E820_ENTRY;
+
+#define PMM_TABLE_SIZE 0x1000
+#define PMM_SYSTEM_HANDLE 0x24494D41 // Handle used by AMIBIOS 'AMI$'
+#define EFI_MEMORY_HANDLE 0x24494645 // Handle used by EFI Memory 'EFI$'
+typedef struct {
+ UINT32 StartAddress; // Start address of the memory block
+ UINT32 Size; // Size of the memory block in bytes
+ UINT32 Handle; // Associated handle
+ UINT8 Reserved[4]; // Reserved for future use
+} MEMORY_ALLOCATION_ENTRY;
+
+typedef struct {
+ UINT32 Signature;
+ UINT8 Revision;
+ UINT8 Length;
+ UINT16 NextHeaderOffset;
+ UINT8 Reserved;
+ UINT8 Checksum;
+ UINT32 DevId;
+ UINT16 MfgPtr;
+ UINT16 ProductNamePtr;
+ UINT8 Class;
+ UINT8 SubClass;
+ UINT8 Interface;
+ UINT8 DevIndicators;
+ UINT16 BCV;
+ UINT16 DisconnectVector;
+ UINT16 BEV;
+ UINT16 Reserved1;
+ UINT16 StaticResourceVector;
+} PCI_PNP_EXPANSION_HEADER;
+
+#define MAX_BCV_OPROMS 32
+typedef struct {
+ UINT8 *Address;
+ UINT8 *Data;
+ UINT8 *rtData;
+ UINT8 *rtDataAddr;
+ UINT32 rtDataSize;
+ BOOLEAN isEbda;
+ UINT32 ebdaOffset;
+} SAVED_PCI_ROM;
+
+typedef struct {
+ UINT8 irq_num;
+ UINT32 irq_adr;
+} IVT_SAVE_RESTORE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BIOS_INFO
+//
+// Description:
+// This structure is not specified in CSM specification. It defines the useful
+// fields for the global variable to be used throughout POST.
+//
+// Fields:
+// iBios EFI_LEGACY_BIOS_PROTOCOL LegacyBios instance pointer
+// iRegion EFI_LEGACY_REGION_PROTOCOL LegacyRegion instance pointer
+// iBiosPlatform EFI_LEGACY_BIOS_PLATFORM_PROTOCOL LegacyPlatform instance pointer
+// iInterrupt EFI_LEGACY_INTERRUPT_PROTOCOL LegacyInterrupt instance pointer
+// i8259 EFI_LEGACY_8259_PROTOCOL Legacy8259 instance pointer
+// hBios EFI_HANDLE
+// hImage EFI_HANDLE This driver LoadedImage handle
+// hVga EFI_HANDLE Video controller handle
+// Csm16Header EFI_COMPATIBILITY16_TABLE Pointer to CSM16 header
+// Thunk THUNK_MEMORY Pointer to thunk memory area
+// Csm16EntrySeg UINT16 CSM16 entry point segment
+// Csm16EntryOfs UINT16 CSM16 entry point offset
+// BbsTable BBS_TABLE BBS table pointer
+// BbsEntriesNo UINT8 Number of BBS entries
+// HddCount UINT8 Number of hard disks in the system
+// E820Map E820_ENTRY E820 memory map entries
+// NumberE820Entries UINT16 Number of E820 entries populated
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ EFI_LEGACY_BIOS_PROTOCOL iBios;
+ EFI_LEGACY_REGION_PROTOCOL *iRegion;
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *iBiosPlatform;
+ EFI_LEGACY_INTERRUPT_PROTOCOL *iInterrupt;
+ EFI_LEGACY_8259_PROTOCOL *i8259;
+ EFI_HANDLE hBios;
+ EFI_HANDLE hImage;
+ EFI_HANDLE hVga;
+ EFI_COMPATIBILITY16_TABLE *Csm16Header;
+ THUNK_MEMORY *Thunk;
+ UINT16 Csm16EntrySeg;
+ UINT16 Csm16EntryOfs;
+ BBS_TABLE *BbsTable;
+ UINT8 BbsEntriesNo;
+ UINT8 HddCount;
+ E820_ENTRY E820Map[MAX_E820_ENTRIES];
+ UINT16 NumberE820Entries;
+} BIOS_INFO;
+
+typedef struct {
+ EFI_HANDLE hImage;
+ EFI_HANDLE hBios;
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL iBiosPlatform;
+} PLATFORM_BIOS_INFO;
+
+EFI_STATUS BspUpdatePrt(
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN VOID *RoutingTable
+);
+
+typedef struct _OEMINT_FUNC {
+ UINT16 interrupt;
+ UINT16 funcoffset;
+} OEMINT_FUNC;
+
+typedef struct _OEM16_FUNC {
+ UINT16 funcID;
+ UINT16 funcOffset;
+} OEM16_FUNC;
+
+typedef struct _LEGACY16_TO_EFI_DATA_TABLE_EXT {
+ LEGACY16_TO_EFI_DATA_TABLE_STRUC PublicData;
+ UINT16 RbMinBusArrayOfs;
+ UINT8 RbArrayCount;
+} LEGACY16_TO_EFI_DATA_TABLE_EXT;
+
+EFI_STATUS Get16BitFuncAddress (UINT16, UINT32*);
+UINTN CopyLegacyTable(VOID*, UINT16, UINT16, UINT16);
+EFI_STATUS GetEmbeddedRom(UINT16, UINT16, UINT16, VOID**, UINTN*);
+EFI_STATUS GetBbsTable (BBS_TABLE**, UINT8*);
+EFI_STATUS AddBbsEntry(BBS_TABLE*);
+EFI_STATUS InsertBbsEntryAt(EFI_LEGACY_BIOS_EXT_PROTOCOL*, BBS_TABLE*, UINT8*);
+EFI_STATUS RemoveBbsEntryAt(EFI_LEGACY_BIOS_EXT_PROTOCOL*, UINT8);
+EFI_STATUS AllocateEbda(EFI_LEGACY_BIOS_EXT_PROTOCOL*, UINT8, UINT32*, UINT32*);
+EFI_STATUS UnlockShadow(UINT8*, UINTN, UINT32*, UINT32*);
+EFI_STATUS LockShadow(UINT32, UINT32);
+EFI_STATUS InitCompatibility16(BIOS_INFO*, EFI_SYSTEM_TABLE*);
+EFI_STATUS InitializeThunk(BIOS_INFO*);
+EFI_STATUS InitializeLegacyMemory(BIOS_INFO*);
+EFI_STATUS PrepareToBoot(EFI_LEGACY_BIOS_PROTOCOL*, UINT16*, struct _BBS_TABLE**);
+EFI_STATUS LegacyBoot(EFI_LEGACY_BIOS_PROTOCOL*, BBS_BBS_DEVICE_PATH*, UINT32, VOID*);
+EFI_STATUS GetBbsInfo(EFI_LEGACY_BIOS_PROTOCOL*, UINT16*, HDD_INFO**, UINT16*, BBS_TABLE**);
+EFI_STATUS UpdateKeyboardLedStatus(EFI_LEGACY_BIOS_PROTOCOL*, UINT8);
+EFI_STATUS EnableDisableNmi();
+//EFI_STATUS GetAtaAtapiInfo(HDD_INFO**);
+VOID HaltApsBeforeBoot();
+VOID InstallLegacyMassStorageDevices();
+VOID GetExtendedMemSize(UINT32*);
+UINT32 UpdateE820Map(E820_ENTRY *);
+EFI_STATUS UpdateCsm16Configuration(EFI_TO_COMPATIBILITY16_BOOT_TABLE*);
+EFI_STATUS InitCsmBoard(EFI_HANDLE, EFI_SYSTEM_TABLE*);
+EFI_STATUS InitCsmSimpleIn(EFI_HANDLE, EFI_SYSTEM_TABLE*);
+EFI_STATUS UpdateCmos();
+EFI_STATUS InitializePortingHooks (BIOS_INFO*);
+OEM16_FUNC* InitializeOemInt(UINT16*);
+UINTN InitializeOem16(UINT16*);
+FDD_STATUS GetFDDStatus();
+VOID AllConnectedCallback (EFI_EVENT, VOID*);
+EFI_STATUS GetPlatformEmbeddedRom(UINT16, UINT16, UINT16, VOID**, UINTN*);
+EFI_STATUS GetComPortResource(UINT8, UINT16*, UINT8*);
+EFI_STATUS GetLptResource(UINT16*, UINT8*);
+VOID UpdatePciLastBusCallback(EFI_EVENT, VOID*);
+EFI_STATUS GetPlatformPciEmbeddedRom(EFI_PCI_IO_PROTOCOL*, VOID**, UINTN*);
+EFI_STATUS CheckOemPciSiblings(EFI_PCI_IO_PROTOCOL*, EXECUTED_PCI_ROM*);
+EFI_STATUS EnableOemPciSiblings(EFI_PCI_IO_PROTOCOL*);
+EFI_STATUS InstallIsaRom(EFI_LEGACY_BIOS_EXT_PROTOCOL*, UINTN);
+EFI_STATUS GetShadowRamAddress(UINT32*, UINT32, UINT32, UINT32);
+
+// SD class/subclass defined in PCI.H in 4.6.3.7
+#ifndef PCI_CL_SYSTEM_PERIPHERALS
+#define PCI_CL_SYSTEM_PERIPHERALS 0x08
+#endif
+#ifndef PCI_CL_SYSTEM_PERIPHERALS_SCL_SD
+#define PCI_CL_SYSTEM_PERIPHERALS_SCL_SD 0x05
+#endif
+
+VOID DisconnectSerialIO();
+VOID ConnectSerialIO();
+BOOLEAN IsAMICSM16(EFI_COMPATIBILITY16_TABLE*);
+UINT8 ChecksumCSM16Header(EFI_COMPATIBILITY16_TABLE*);
+EFI_STATUS GetSystemMemoryMap(EFI_MEMORY_DESCRIPTOR**, UINTN*,UINTN*);
+EFI_STATUS ClearFreeMemory(EFI_PHYSICAL_ADDRESS,EFI_PHYSICAL_ADDRESS);
+EFI_STATUS Csm16Configuration(CSM16_CONFIGURATION_ACTION, CSM16_FEATURE, UINT32*);
+
+#pragma pack ()
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CSM.mak b/Core/EM/CSM/CSM.mak
new file mode 100644
index 0000000..9e651c2
--- /dev/null
+++ b/Core/EM/CSM/CSM.mak
@@ -0,0 +1,174 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/csm.mak 36 10/07/13 8:58a Olegi $
+#
+# $Revision: 36 $
+#
+# $Date: 10/07/13 8:58a $
+#**********************************************************************
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CSMCORE.MAK
+#
+# Description: Make file for the CSM component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : CSMCORE
+
+!IF $(CORE_COMBINED_VERSION) < 262795
+!ERROR This version of CSM is compatible with Core 4.6.5.1 or later.
+!ELSE
+CSMCORE : CSMELINKFUNCTIONS $(BUILD_DIR)\csmcore.mak LEGACY_ROM CSMCOREBin
+!ENDIF
+
+!IFDEF LEGACY_TO_EFI_BOOT_SUPPORT
+!IF $(LEGACY_TO_EFI_BOOT_SUPPORT) == 1
+!ERROR LEGACY_TO_EFI_BOOT_SUPPORT detected: disable or remove LegacyToEfiBoot module. This version of CSM implements all features of LegacyToEfiBoot.
+!ENDIF
+!ENDIF
+
+CSMELINKFUNCTIONS :
+ type << >$(BUILD_DIR)\CsmElinkFunctions.h
+#define CSM_GET_OPROM_VIDEO_SWITCHING_MODE_FUNCTIONS $(CSM_GET_OPROM_VIDEO_SWITCHING_MODE_FUNCTIONS:},=},\^
+)
+#define CSM_GET_CUSTOM_PCI_PIRQ_MASK_FUNCTIONS $(CSM_GET_CUSTOM_PCI_PIRQ_MASK_FUNCTIONS:},=},\^
+)
+#define CSM_GET_GATE_A20_INFORMATION_FUNCTIONS $(CSM_GET_GATE_A20_INFORMATION_FUNCTIONS:},=},\^
+)
+#define CSM_GET_NMI_INFORMATION_FUNCTIONS $(CSM_GET_NMI_INFORMATION_FUNCTIONS:},=},\^
+)
+#define CSM_GET_OEM_INT_DATA_FUNCTIONS $(CSM_GET_OEM_INT_DATA_FUNCTIONS:},=},\^
+)
+#define CSM_GET_PLATFORM_HANDLE_FUNCTIONS $(CSM_GET_PLATFORM_HANDLE_FUNCTIONS:},=},\^
+)
+#define CSM_GET_PLATFORM_PCI_EMBEDDED_ROM_FUNCTIONS $(CSM_GET_PLATFORM_PCI_EMBEDDED_ROM_FUNCTIONS:},=},\^
+)
+#define CSM_GET_PLATFORM_EMBEDDED_ROM_FUNCTIONS $(CSM_GET_PLATFORM_EMBEDDED_ROM_FUNCTIONS:},=},\^
+)
+#define CSM_CHECK_OEM_PCI_SIBLINGS_FUNCTIONS $(CSM_CHECK_OEM_PCI_SIBLINGS_FUNCTIONS:},=},\^
+)
+#define CSM_ENABLE_OEM_PCI_SIBLINGS_FUNCTIONS $(CSM_ENABLE_OEM_PCI_SIBLINGS_FUNCTIONS:},=},\^
+)
+#define CSM_GET_ROUTING_TABLE_FUNCTIONS $(CSM_GET_ROUTING_TABLE_FUNCTIONS:},=},\^
+)
+#define CSM_BSP_UPDATE_PRT_FUNCTIONS $(CSM_BSP_UPDATE_PRT_FUNCTIONS:},=},\^
+)
+#define CSM_BSP_PREPARE_TO_BOOT_FUNCTIONS $(CSM_BSP_PREPARE_TO_BOOT_FUNCTIONS:},=},\^
+)
+#define CSM_INIT_LEGACY_MEMORY_FUNCTIONS $(CSM_INIT_LEGACY_MEMORY_FUNCTIONS:},=},\^
+)
+<<
+
+$(BUILD_DIR)\csmcore.mak : $(CSMCORE_DIR)\csmcore.cif $(CSMCORE_DIR)\csm.mak $(BUILD_RULES)
+ $(CIF2MAK) $(CSMCORE_DIR)\csmcore.cif $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\thunk.obj: $(X86THUNK_DIR)\thunk.c $(BUILD_DIR)\token.h $(CSMCORE_DIR)\csm.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(PROJECT_DIR)\$(X86THUNK_DIR)\thunk.c /I$(CSMCORE_DIR)
+
+CSMCOREBin : $(BUILD_DIR)\thunk.obj $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\csmcore.mak all\
+ GUID=A062CF1F-8473-4aa3-8793-600BC4FFE9A8 \
+ ENTRY_POINT=CsmEntryPoint \
+ "CFLAGS=$(CFLAGS) /I$(CSMCORE_DIR)"\
+ TYPE=BS_DRIVER \
+ EXT_HEADERS=$(BUILD_DIR)\token.h\
+ BINFILE=$(BUILD_DIR)\ROMs.bin \
+ SECTION_GUID=E6F4F8F7-4992-47b2-8302-8508745E4A23 \
+ COMPRESS=1\
+
+LEGACY_ROM: $(BUILD_DIR)\ROMs.inf
+ $(PACKOPROM) /o$(BUILD_DIR)\ROMs.bin $(BUILD_DIR)\ROMs.inf
+
+$(BUILD_DIR)\ROMs.inf: $(OEM_SERVICE_ROM_LIST) $(CSM_OEM_BIN_FILE) $(CSM_CUSTOM_INFS)
+ @copy << $@
+[MODULE]
+ModuleID = 1
+VendorID = 0
+DeviceID = 0
+File = $(AMILEGACY16_BIN)
+!if "$(PCI_ROMS_OUTSIDE_CSM)"=="0"
+$(PCI_OPT_ROM_LIST)
+!endif
+!if "$(PXE_BASECODE_ROM)"=="1"
+[MODULE]
+ModuleID = 2
+VendorID = 0
+DeviceID = 0
+File = $(PXE_BASECODE_ROM_FILE)
+!endif
+
+!if "$(OEM_SERVICE_ROM_LIST)"!=""
+[MODULE]
+ModuleID = 2
+VendorID = 0
+DeviceID = 0
+File = $(OEM_SERVICE_ROM_LIST: =^
+
+[MODULE]^
+ModuleID = 2^
+VendorID = 0^
+DeviceID = 0^
+File = )
+
+!endif
+!if "$(CSM_OEM_SUPPORT)"=="1"
+[MODULE]
+ModuleID = 3
+VendorID = 0
+DeviceID = 0
+File = $(CSM_OEM_BIN_FILE)
+
+!endif
+<<
+
+!if "$(CSM_CUSTOM_INFS)"!=""
+ copy $@+$(CSM_CUSTOM_INFS: =+) $@
+!endif
+
+
+#---------------------------------------------------------------------------
+# Create CSM Setup Screens
+#---------------------------------------------------------------------------
+SetupSdbs: $(BUILD_DIR)\csm.sdb
+SetupBin: $(BUILD_DIR)\csmsetup.obj
+
+$(BUILD_DIR)\csm.sdb : $(CSM_SETUP_DIR)\csm.sd $(CSM_SETUP_DIR)\csm.uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\csm.sdb $(CSM_SETUP_DIR)\csm.uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\csm.sdb -od $(BUILD_DIR)\csm.sdb $(CSM_SETUP_DIR)\csm.sd
+
+$(BUILD_DIR)\csmsetup.obj: $(CSM_SETUP_DIR)\csmsetup.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(CSM_SETUP_DIR)\csmsetup.c
+#---------------------------------------------------------------------------
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/CSM/CsmBsp.c b/Core/EM/CSM/CsmBsp.c
new file mode 100644
index 0000000..9bc04c8
--- /dev/null
+++ b/Core/EM/CSM/CsmBsp.c
@@ -0,0 +1,1295 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmBsp.c 39 8/06/14 4:40p Fasihm $
+//
+// $Revision: 39 $
+//
+// $Date: 8/06/14 4:40p $
+//
+//****************************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBsp.c
+//
+// Description:
+// Compatibility Support Module - Board Support Package.
+// This driver implements LEGACY_BIOS_PLATFORM_PTOTOCOL interface functions.
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "Efi.h"
+#include <Protocol/DevicePath.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/LoadedImage.h>
+#include "csm.h"
+#include <AmiDxeLib.h>
+#include <Protocol/LegacyBiosPlatform.h>
+#include <Protocol/FirmwareVolumeBlock.h>
+#include "token.h"
+#include "setup.h"
+#include "CsmElinkFunctions.h"
+
+typedef EFI_STATUS (CSM_GET_OPROM_VIDEO_SWITCHING_MODE)(
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ IN UINT16 TextSwitchingMode,
+ OUT UINTN *SetTxtSwitchingMode);
+extern CSM_GET_OPROM_VIDEO_SWITCHING_MODE CSM_GET_OPROM_VIDEO_SWITCHING_MODE_FUNCTIONS EndOfGetOpRomVideoModeFunctions;
+CSM_GET_OPROM_VIDEO_SWITCHING_MODE *CsmGetOpRomVideoModeSwitchingFunctions[] = { CSM_GET_OPROM_VIDEO_SWITCHING_MODE_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_GET_CUSTOM_PCI_PIRQ_MASK)(
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT16 IrqMask,
+ OUT UINTN *ModifiedIrqMask);
+extern CSM_GET_CUSTOM_PCI_PIRQ_MASK CSM_GET_CUSTOM_PCI_PIRQ_MASK_FUNCTIONS EndOfGetCustomPciPirqMaskFunctions;
+CSM_GET_CUSTOM_PCI_PIRQ_MASK *CsmGetCustomPciPirqMaskFunctions[] = { CSM_GET_CUSTOM_PCI_PIRQ_MASK_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_GET_GATE_A20_INFORMATION)(OUT UINTN *GateA20Info);
+extern CSM_GET_GATE_A20_INFORMATION CSM_GET_GATE_A20_INFORMATION_FUNCTIONS EndOfGetGateA20InformationFunctions;
+CSM_GET_GATE_A20_INFORMATION *CsmGetGateA20InformationFunctions[] = { CSM_GET_GATE_A20_INFORMATION_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_GET_NMI_INFORMATION)(OUT UINTN *NmiInfo);
+extern CSM_GET_NMI_INFORMATION CSM_GET_NMI_INFORMATION_FUNCTIONS EndOfGetNmiInformationFunctions;
+CSM_GET_NMI_INFORMATION *CsmGetNmiInformationFunctions[] = { CSM_GET_NMI_INFORMATION_FUNCTIONS NULL };
+
+// Get Platform Handle ELINK function list
+typedef EFI_STATUS (CSM_GET_PLATFORM_HANDLE)(
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ EFI_GET_PLATFORM_HANDLE_MODE Mode,
+ UINT16 Type,
+ EFI_HANDLE **HandleBuffer,
+ UINTN *HandleCount,
+ VOID OPTIONAL **AdditionalData);
+extern CSM_GET_PLATFORM_HANDLE CSM_GET_PLATFORM_HANDLE_FUNCTIONS EndOfPlatformHandleFunctions;
+CSM_GET_PLATFORM_HANDLE *CsmGetPlatformFunctions[] = { CSM_GET_PLATFORM_HANDLE_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_GET_PLATFORM_EMBEDDED_ROM)(UINT16 ModuleId, UINT16 VendorId, UINT16 DeviceId, VOID **ImageStart, UINTN *ImageSize);
+extern CSM_GET_PLATFORM_EMBEDDED_ROM CSM_GET_PLATFORM_EMBEDDED_ROM_FUNCTIONS EndOfGetPlatformEmbeddedRomFunctions;
+CSM_GET_PLATFORM_EMBEDDED_ROM *CsmGetPlatformEmbeddedRomFunctions[] = { CSM_GET_PLATFORM_EMBEDDED_ROM_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_GET_PLATFORM_PCI_EMBEDDED_ROM)(IN EFI_PCI_IO_PROTOCOL *PciIo, OUT VOID **PciRom, OUT UINTN *PciRomSize);
+extern CSM_GET_PLATFORM_PCI_EMBEDDED_ROM CSM_GET_PLATFORM_PCI_EMBEDDED_ROM_FUNCTIONS EndOfGetPlatformPciEmbeddedRomFunctions;
+CSM_GET_PLATFORM_PCI_EMBEDDED_ROM *CsmGetPlatformPciEmbeddedRomFunctions[] = { CSM_GET_PLATFORM_PCI_EMBEDDED_ROM_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_CHECK_OEM_PCI_SIBLINGS)(EFI_PCI_IO_PROTOCOL *PciIo, EXECUTED_PCI_ROM *ExecutedRom);
+extern CSM_CHECK_OEM_PCI_SIBLINGS CSM_CHECK_OEM_PCI_SIBLINGS_FUNCTIONS EndOfCheckOemPciSiblingsFunctions;
+CSM_CHECK_OEM_PCI_SIBLINGS *CsmCheckOemPciSiblingsFunctions[] = { CSM_CHECK_OEM_PCI_SIBLINGS_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_ENABLE_OEM_PCI_SIBLINGS)(EFI_PCI_IO_PROTOCOL *PciIo);
+extern CSM_ENABLE_OEM_PCI_SIBLINGS CSM_ENABLE_OEM_PCI_SIBLINGS_FUNCTIONS EndOfEnableOemPciSiblingsFunctions;
+CSM_ENABLE_OEM_PCI_SIBLINGS *CsmEnableOemPciSiblingsFunctions[] = { CSM_ENABLE_OEM_PCI_SIBLINGS_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_GET_ROUTING_TABLE)(
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ OUT VOID **RoutingTable,
+ OUT UINTN *RoutingTableEntries,
+ OUT VOID **LocalPirqTable, OPTIONAL
+ OUT UINTN *PirqTableSize, OPTIONAL
+ OUT VOID **LocalIrqPriorityTable, OPTIONAL
+ OUT UINTN *IrqPriorityTableEntries OPTIONAL);
+extern CSM_GET_ROUTING_TABLE CSM_GET_ROUTING_TABLE_FUNCTIONS EndOfGetRoutingTableFunctions;
+CSM_GET_ROUTING_TABLE *CsmGetRoutingTableFunctions[] = { CSM_GET_ROUTING_TABLE_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_BSP_UPDATE_PRT)(IN EFI_LEGACY_BIOS_PROTOCOL *This, IN VOID *RoutingTable);
+extern CSM_BSP_UPDATE_PRT CSM_BSP_UPDATE_PRT_FUNCTIONS EndOfBspUpdatePrtFunctions;
+CSM_BSP_UPDATE_PRT *CsmBspUpdatePrtFunctions[] = { CSM_BSP_UPDATE_PRT_FUNCTIONS NULL };
+
+typedef EFI_STATUS (CSM_BSP_PREPARE_TO_BOOT)( IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN BBS_BBS_DEVICE_PATH *BbsDevicePath,
+ IN VOID *BbsTable,
+ IN UINT32 LoadOptionsSize,
+ IN VOID *LoadOptions,
+ IN VOID *EfiToLegacyBootTable);
+extern CSM_BSP_PREPARE_TO_BOOT CSM_BSP_PREPARE_TO_BOOT_FUNCTIONS EndOfBspPrepareToBootFunctions;
+CSM_BSP_PREPARE_TO_BOOT *CsmBspPrepareToBootFunctions[] = { CSM_BSP_PREPARE_TO_BOOT_FUNCTIONS NULL };
+
+// end of CSM elink functions
+
+
+PLATFORM_BIOS_INFO *BspBiosInfo;
+
+
+extern EFI_LEGACY_PIRQ_TABLE_HEADER *MsPrt;
+
+//AMIIRQ_HEADER *AmiPrt;
+extern EFI_LEGACY_IRQ_ROUTING_ENTRY *Prt;
+BOOLEAN IsValidPrt;
+
+EFI_STATUS InitPrt(EFI_LEGACY_BIOS_PLATFORM_PROTOCOL*);
+EFI_STATUS Intx2Pirq (EFI_LEGACY_BIOS_PLATFORM_PROTOCOL*,
+ UINTN, UINTN, UINTN, UINT8*, UINT8*, UINT16*);
+
+extern VOID *EmbeddedRom;
+extern UINTN EmbeddedRomSize;
+extern UINT16 CurrentIrqMask;
+extern UINTN gUsedPciEntries;
+extern SETUP_DATA gSetup;
+
+//
+// The following table has a list of interrupts to be saved after
+// CSM Init call and restored before LegacyBoot. The default list
+// is defined in CSM.SDL and contains three interrups: int13, int15,
+// and int40.
+// This list can be expanded according to the project needs. Only
+// MAX_NUM_IRQS_SAVERESTORE entries will be processed, others will
+// be ignored.
+//
+UINT8 gInterruptsToPreserve[] = INTERRUPTS_TO_PRESERVE;
+
+//
+// The following table is the list of VID/DID (combined into DWORDs)
+// that will have problems with BCV executed during early POST right
+// after Option ROM is initialized, or problems with BCV executed
+// multiple times during POST. The examples of such "problematic"
+// BCVs would be trapping BIOS interrupts that are not BCV specific,
+// allocating blocks of memory, etc.
+// Note that for these devices BCV will be executed during PrepareToBoot;
+// drivers that require BCV execution before that (CsmBlockIo) will not
+// support these devices.
+//
+UINT32 gSkipBcvDeviceList[] = SKIP_EARLY_BCV_DEVICES;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetOpromVideoSwitchingMode
+//
+// Description: This function is called from LEGACY_BIOS.InstallPciRom()
+// before and after OpROM execution. It allows OEM override the
+// default video mode switching policy during OpROM execution.
+//
+// Input:
+//
+// PciIo PciIo protocol of the device associated with the OpROM;
+// This is an optional field, if NULL then it is ignored.
+//
+// TextSwitchingMode The current text switching mode. Possible values are:
+// 0 - switching to text mode is needed;
+// 1 - switching is needed, restoration is not;
+// 2 - neither switching nor restoration is needed.
+// Output:
+//
+// SetTxtSwitchingMode The mode that will be used for this OpROM. The valid
+// values are 0, 1, and 2. The meaning is the same as
+// TextSwitchingMode (above).
+//
+// EFI_SUCCESS The value of SetTxtSwithcingMode is updated according
+// to the platform policy and will be used for video mode
+// switching for the given PciIo's Option ROM.
+//
+// EFI_UNSUPPORTED The value of SetTxtSwitchingMode is not valid.
+//
+//
+// Notes: This function can change the policy of video switching for selected
+// Option ROMs by looking up the PCI VID/DID. It also can change this
+// policy for all OpROMs.
+//
+// Use SetTxtSwitchingMode value to adjust the platform policy. For
+// example, value equal to 1 probably indicates the end of the boot
+// process, when system is already in text mode and switching back
+// is not desired. In this case platform may choose not to interfere
+// with the default policy. This can be done by either returning
+// EFI_UNSUPPORTED or returning EFI_SUCCESS with SetTxtSwitchingMode
+// equal to TextSwitchingMode.
+//
+// Returning EFI_SUCCESS must be carefully considered. If function
+// returns EFI_SUCCESS, please make sure SetTxtSwitchingMode is
+// assigned the valid values: 0, 1, 2 and 3. If the wrong value is
+// assigned, then video switching policy will fail.
+//
+// The default implementation simply returns EFI_SUCCESS with the
+// SetTxtSwitchingMode set to the value passed in TextSwitchingMode.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetOpromVideoSwitchingMode(
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ IN UINT16 TextSwitchingMode,
+ OUT UINTN *SetTxtSwitchingMode
+)
+{
+/*
+// Here is an example of the platform implementation of this function.
+ UINT32 VidDid;
+ EFI_STATUS Status;
+
+ if (TextSwitchingMode == 1) return EFI_UNSUPPORTED; // see the notes
+
+ if (PciIo == NULL) return EFI_UNSUPPORTED;
+
+ //
+ // Force mode switching for certaing PCI cards
+ //
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32,
+ 0, // offset
+ 1, // width
+ &VidDid);
+ ASSERT_EFI_ERROR(Status);
+
+ if (VidDid == 0x12345678) {
+ *SetTxtSwitchingMode = 0;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+*/
+
+ EFI_STATUS Status;
+ UINTN i = 0;
+
+ // default value
+ *SetTxtSwitchingMode = (UINTN)TextSwitchingMode;
+
+ for(i = 0; CsmGetOpRomVideoModeSwitchingFunctions[i] != NULL; i++)
+ {
+ Status = CsmGetOpRomVideoModeSwitchingFunctions[i](PciIo, TextSwitchingMode, SetTxtSwitchingMode);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetCustomPciIrqMask
+//
+// Description: This function is called from PciInterrupts.ProgramPciIrq()
+// before programming PCI register 3C. This function is given
+// the PciIo of the device and a list of possible IRQ choices
+// for this device.
+// The possible IRQs are given in a form of UINT16 IRQ mask,
+// where 1 is a masked IRQ level.
+// This function can modify this list and return EFI_SUCCESS.
+// A caller then will AND the existing mask with the one returned
+// by this function. Note that this way the existing list can
+// only be shrunk, not extended.
+//
+// Input:
+//
+// PciIo PciIo protocol of the device
+//
+// IrqMask The current bit mask of IRQ levels available for this device
+//
+// Output:
+//
+// ModifiedIrqMask The value that a caller will use to OR with the existing
+// mask.
+//
+// EFI_SUCCESS Function is returning a valid ModifiedIrqMask
+//
+// EFI_UNSUPPORTED Function is not ported for this PciIo, value returned
+// in ModifiedIrqMask will be ignored.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetCustomPciIrqMask (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINT16 IrqMask,
+ OUT UINTN *ModifiedIrqMask
+)
+{
+/* Implementation example - force IRQ11 for device 0x12345678
+
+ UINT32 VidDid;
+ EFI_STATUS Status;
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32,
+ 0, // offset
+ 1, // width
+ &VidDid);
+ ASSERT_EFI_ERROR(Status);
+
+ if (VidDid == 0x12345678) {
+ if (IrqMask & 0xF7FF) {
+ *ModifiedIrqMask = 0xF7FF; // leave only IRQ11 unmaksed
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_UNSUPPORTED;
+*/
+
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINTN i = 0;
+
+ // Set a default value
+ *ModifiedIrqMask = IrqMask;
+
+ for(i = 0; CsmGetCustomPciPirqMaskFunctions[i] != NULL; i++)
+ {
+ Status = CsmGetCustomPciPirqMaskFunctions[i](PciIo, IrqMask, ModifiedIrqMask);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetGateA20Information
+//
+// Description: This function is called from LegacyBios entry point and it
+// returns the board specific information related to the way of
+// controlling GateA20. Two different aspects of GateA20 control
+// can be returned by this function:
+// 1) Line GA20 can be activated/deactivated through KBC's GPIO
+// (command D1), or through Port92 (Bit2).
+// 2) Deactivation of GA20 is be desirable at all, any CSM16
+// function related to deactivation will be skipped.
+//
+// Input: None
+//
+// Output: GateA20Info:
+// BIT0 0 - GA20 controlled through KBC
+// 1 - GA20 controlled through Port92
+// BIT1 0 - Do not skip GA20 deactivation
+// 1 - Skip GA20 deactivation
+// EFI_SUCCESS GateA20Info has valid bits 0 and 1
+//
+// EFI_UNSUPPORTED Function is not supported, GateA20Info information
+// is invalid; CSM core will use the default GA20 policy.
+//
+// Note: Skipping GA20 deactivation is needed when APs are running above
+// 1MB; if GA20 is inactive, then any access >1MB may be invalid.
+// At the same time, keeping GA20 active all the time may fail the
+// applications that test GA20 enable/disable functionality. It may
+// also affect some applications that rely on GA20 being inactive
+// after legacy boot.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetGateA20Information(
+ OUT UINTN *GateA20Info
+)
+{
+ EFI_STATUS Status;
+ UINTN i = 0;
+
+ // Set BIT0 if using Port92, Set BIT1 to skip GA20 deactivation
+ if (gSetup.KeepGA20Active == 1) *GateA20Info = 3;
+ else *GateA20Info = 1;
+
+ for(i = 0; CsmGetGateA20InformationFunctions[i] != NULL; i++)
+ {
+ Status = CsmGetGateA20InformationFunctions[i](GateA20Info);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetNmiInformation
+//
+// Description:
+// This function is called from LegacyBios entry point and it returns the board
+// specific information related to NMI.
+//
+// Input:
+// None
+//
+// Output:
+// NMI information:
+// BIT0 0 - NMI should be kept disabled
+// 1 - enable NMI
+// EFI_SUCCESS GateA20Info has valid bits 0 and 1
+// EFI_UNSUPPORTED Function is not supported, NMI information is invalid; CSM
+// will use the default NMI policy.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetNmiInformation(
+ OUT UINTN *NmiInfo
+)
+{
+ EFI_STATUS Status;
+ UINTN i = 0;
+
+ // prime the return value to enabled
+ *NmiInfo = 1;
+
+ for(i = 0; CsmGetNmiInformationFunctions[i] != NULL; i++)
+ {
+ Status = CsmGetNmiInformationFunctions[i](NmiInfo);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetPlatformInfo
+//
+// Description: Finds the binary data or other platform information.
+// Refer to the subfunctions for additional information.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// Mode Specifies what data to return:
+// EfiGetPlatformBinaryMpTable
+// EfiGetPlatformBinaryOemIntData
+// EfiGetPlatformBinaryOem16Data
+// EfiGetPlatformBinaryOem32Data
+// EfiGetPlatformBinaryTpmBinary
+// EfiGetPlatformBinarySystemRom
+// EfiGetPlatformPciExpressBase
+// EfiGetPlatformPmmSize
+// EfiGetPlatformEndRomShadowAddr
+// EfiGetPlatformOpromVideoMode
+// EfiGetPlatformIntSaveRestoreTable
+// EfiGetPlatformPciIrqMask
+// EfiGetPlatformGateA20Information
+//
+// Table Pointer to OEM legacy 16-bit code or data.
+// TableSize Size of data.
+// Location Location to place table.
+// Bit 0 = 1 0xF0000 64 KB block.
+// Bit 1 = 1 0xE0000 64 KB block.
+// Note: Multiple bits can be set.
+// Alignment Bit-mapped address alignment granularity. The first
+// nonzero bit from the right is the address granularity.
+// LegacySegment Segment where EfiCompatibility code will place the
+// table or data.
+// LegacyOffset Offset where EfiCompatibility code will place the
+// table or data.
+//
+// Output:
+// EFI_SUCCESS The data was returned successfully.
+// EFI_UNSUPPORTED Mode is not supported on this platform.
+// EFI_NOT_FOUND Binary image not found.
+//
+// Referrals: EFI_GET_PLATFORM_INFO_MODE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetPlatformInfo (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN EFI_GET_PLATFORM_INFO_MODE Mode,
+ IN OUT VOID **Table,
+ IN OUT UINTN *TableSize,
+ IN OUT UINTN *Location,
+ OUT UINTN *Alignment,
+ IN UINT16 LegacySegment,
+ IN UINT16 LegacyOffset
+ )
+{
+ switch (Mode) {
+ case EfiGetPlatformPmmSize:
+ //
+ // Return PMM area size below 1MB to be allocated in bytes.
+ // This size should be a multiple of 32K
+ //
+ *TableSize = PMM_LOMEM_SIZE;
+ //
+ // Return PMM area size above 1MB to be allocated in bytes.
+ // This size should be a multiple of 64k.
+ // Note: This field is not bit-mapped for this function.
+ //
+ *Alignment = PMM_HIMEM_SIZE;
+ return EFI_SUCCESS;
+
+ case EfiGetPlatformEndRomShadowAddr:
+ *Location = OPROM_MAX_ADDRESS;
+ return EFI_SUCCESS;
+
+ case EfiGetPlatformBinarySystemRom:
+ return FindEmbeddedRom(CSM16_MODULEID, CSM16_VENDORID, CSM16_DEVICEID,
+ Table, TableSize);
+
+ case EfiGetPlatformPciExpressBase:
+ *(UINT64*)Location = PCIEX_BASE_ADDRESS;
+ return EFI_SUCCESS;
+
+ case EfiGetPlatformOpromVideoMode:
+ return GetOpromVideoSwitchingMode((EFI_PCI_IO_PROTOCOL*)(*Table),
+ LegacySegment, TableSize);
+
+ case EfiGetPlatformIntSaveRestoreTable:
+ *Table = gInterruptsToPreserve;
+ *TableSize = sizeof(gInterruptsToPreserve);
+ return EFI_SUCCESS;
+
+ case EfiGetPlatformPciIrqMask:
+ return GetCustomPciIrqMask((EFI_PCI_IO_PROTOCOL*)(*Table),
+ LegacySegment, Alignment);
+
+ case EfiGetPlatformGateA20Information:
+ return GetGateA20Information(Alignment);
+
+ case EfiGetPlatformNmiInformation:
+ return GetNmiInformation(Alignment);
+
+ case EfiGetBcvSkipDeviceList:
+ *Table = gSkipBcvDeviceList;
+ *TableSize = sizeof(gSkipBcvDeviceList)/4;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetPlatformHandle
+//
+// Description: Returns a buffer of handles for the requested subfunction.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// Mode Specifies what handle to return.
+// GetVgaHandle
+// GetIdeHandle
+// GetIsaBusHandle
+// GetUsbHandle
+// Type Handle Modifier - Mode specific
+// HandleBuffer Pointer to buffer containing all Handles matching the
+// specified criteria. Handles are sorted in priority order.
+// Type EFI_HANDLE is defined in InstallProtocolInterface()
+// in the EFI 1.10 Specification.
+// HandleCount Number of handles in HandleBuffer.
+// AdditionalData Pointer to additional data returned - mode specific..
+//
+// Output:
+// EFI_SUCCESS The handle is valid.
+// EFI_UNSUPPORTED Mode is not supported on this platform.
+// EFI_NOT_FOUND The handle is not known.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetPlatformHandle (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN EFI_GET_PLATFORM_HANDLE_MODE Mode,
+ IN UINT16 Type,
+ OUT EFI_HANDLE **HandleBuffer,
+ OUT UINTN *HandleCount,
+ OUT VOID OPTIONAL **AdditionalData
+ )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINT16 i = 0;
+
+ for(i = 0; CsmGetPlatformFunctions[i] != NULL; i++)
+ {
+ // Call all ELINK functions until one returns EFI_SUCCESS
+ Status = CsmGetPlatformFunctions[i](This, Mode, Type, HandleBuffer, HandleCount, AdditionalData);
+ if(!EFI_ERROR(Status)) break;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetPlatformPciEmbeddedRom
+//
+// Description: This function is called from CheckPciRom and allows OEM to
+// have a custom code that looks for a binary.
+//
+// Input: Same as in FindEmbeddedRom function.
+//
+// Output: EFI_UNSUPPORTED - Function is not implemented
+// EFI_NOT_FOUND - No ROM found
+// EFI_SUCCESS - ROM is found, output is the same as
+// in FindEmbeddedRom function.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetPlatformPciEmbeddedRom (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ OUT VOID **PciRom,
+ OUT UINTN *PciRomSize
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINTN i = 0;
+
+ for(i = 0; CsmGetPlatformPciEmbeddedRomFunctions[i] != NULL; i++)
+ {
+ Status = CsmGetPlatformPciEmbeddedRomFunctions[i](PciIo, PciRom, PciRomSize);
+ if(!EFI_ERROR(Status)) break;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetPlatformEmbeddedRom
+//
+// Description:
+// This function is called from FindEmbeddedRom and allows OEM to have a custom
+// code that looks for a binary. By default all addon ROMs are packed as BINFILE
+// section. This function may be needed if binary is packed in a way that is
+// different from default (for example it can be FFS file, etc.).
+//
+// Input:
+// Same as in FindEmbeddedRom function.
+//
+// Output:
+// EFI_NOT_FOUND No ROM found, or function is not implemented.
+// EFI_SUCCESS ROM is found, output is the same as in FindEmbeddedRom
+// function.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetPlatformEmbeddedRom(
+ UINT16 ModuleId, UINT16 VendorId, UINT16 DeviceId,
+ VOID **ImageStart, UINTN *ImageSize)
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINTN i = 0;
+
+ for(i = 0; CsmGetPlatformEmbeddedRomFunctions[i] != NULL; i++)
+ {
+ Status = CsmGetPlatformEmbeddedRomFunctions[i](ModuleId, VendorId, DeviceId, ImageStart, ImageSize);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CheckOemPciSiblings
+//
+// Description:
+// This function checks whether a given PCI device can be controlled by one of
+// the Option ROMs that have been already executed.
+//
+// Input:
+// PciIo PCI I/O protocol of the device whose Option ROM is about to
+// execute
+// ExecutedRom Pointer to the last element of EXECUTED_PCI_ROM structure
+//
+// Output:
+// EFI_UNSUPPORTED Function is not implemented, use the default
+// device match criteria
+// EFI_SUCCESS Device can be managed by one of the loaded ROMs
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckOemPciSiblings(
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ EXECUTED_PCI_ROM *ExecutedRom
+)
+{
+/* By default this function returns EFI_UNSUPPORTED to make every Option ROM execute
+ One of the possible implementation is to execute only one Option ROM for all functions
+ of the PCI device. The sample below implements this kind of policy. Uncomment if needed.
+
+ EFI_STATUS Status;
+ UINTN Seg, Bus, Dev, Func;
+ EXECUTED_PCI_ROM *er;
+
+ // Go through ExecutedRoms and search for the ROM that has been executed for
+ // similar device (PCI Bus/Dev match)
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Func);
+ ASSERT_EFI_ERROR(Status);
+
+ for (er = ExecutedRom; er->Seg | er->Bus | er->Dev | er->Fun; er--) {
+ if (er->Bus == Bus && er->Dev == Dev) {
+ TRACE((TRACE_ALWAYS, "CSM OPROM: skip OpROM execution for device B%x/d%x/F%x.\n",
+ Bus, Dev, Func));
+ return EFI_SUCCESS;
+ }
+ }
+*/
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINTN i = 0;
+
+ for(i = 0; CsmCheckOemPciSiblingsFunctions[i] != NULL; i++)
+ {
+ Status = CsmCheckOemPciSiblingsFunctions[i](PciIo, ExecutedRom);
+ if(!EFI_ERROR(Status)) break;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: EnableOemPciSiblings
+//
+// Description:
+// This function enables devices on PCI bus that can be controlled by the Option
+// ROM associated with the given PCI device.
+//
+// Input:
+// PciIo PCI I/O protocol of the device whose Option ROM is about to execute
+//
+// Output:
+// EFI_UNSUPPORTED Function is not implemented
+// EFI_SUCCESS Function has enabled all related devices
+//
+// Notes:
+// If OEM code can not decide for ALL related devices, it may enable only devices
+// it knows about, and still return EFI_UNSUPPORTED. In this case CSM Core will
+// finish the job.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EnableOemPciSiblings(
+ EFI_PCI_IO_PROTOCOL *PciIo
+)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINTN i = 0;
+
+ for(i = 0; CsmEnableOemPciSiblingsFunctions[i] != NULL; i++)
+ {
+ Status = CsmEnableOemPciSiblingsFunctions[i](PciIo);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SmmInit
+//
+// Description: Loads and registers the Compatibility16 handler with the EFI SMM code.
+// In also updates EFI_TO_COMPATIBILITY16_BOOT_TABLE.SmmTable.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// EfiToCompatibility16BootTable The boot table passed to the Compatibility16.
+//
+// Output:
+// EFI_SUCCESS The SMM code loaded.
+// EFI_DEVICE_ERROR The SMM code failed to load.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SmmInit(
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN VOID *EfiToCompatibility16BootTable
+ )
+{
+ SMM_TABLE *SmmTable;
+ SMM_ENTRY *SmmEntry;
+ EFI_STATUS Status;
+ //
+ // Currently this function is implemented for two SW SMI handlers: INT15_D042 and USB
+ // change NUMBER_OF_CSM_SUPPORTED_SW_SMIS and add the new SMM_ENTRYs if needed
+ //
+ #define NUMBER_OF_CSM_SUPPORTED_SW_SMIS 2
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof (SMM_TABLE) + NUMBER_OF_CSM_SUPPORTED_SW_SMIS * sizeof(SMM_ENTRY),
+ &SmmTable);
+ ASSERT_EFI_ERROR (Status);
+ pBS->SetMem(SmmTable,
+ sizeof(SMM_TABLE) + NUMBER_OF_CSM_SUPPORTED_SW_SMIS * sizeof(SMM_ENTRY), 0);
+
+ //
+ // Fill in two SMM entries - one for INT15 func D042, another for USB
+ //
+ SmmTable->NumSmmEntries = NUMBER_OF_CSM_SUPPORTED_SW_SMIS;
+
+ SmmEntry = &SmmTable->SmmEntry;
+
+ SmmEntry->SmmAttributes.Type = STANDARD_IO;
+ SmmEntry->SmmAttributes.PortGranularity = PORT_SIZE_16;
+ SmmEntry->SmmAttributes.DataGranularity = DATA_SIZE_8;
+ SmmEntry->SmmFunction.Function = INT15_D042;
+ SmmEntry->SmmFunction.Owner = STANDARD_OWNER;
+ SmmEntry->SmmPort = SW_SMI_IO_ADDRESS;
+ SmmEntry->SmmData = INT15_D042_SWSMI;
+ SmmEntry++;
+ //
+ // SmmPort and SmmData are UINT16 data fields, in our case SmmEntry data is UINT8.
+ // We need to adjust the pointer to the next SmmEntry accofdingly so that CSM16 will
+ // find it correctly.
+ //
+ (UINT8*)SmmEntry = (UINT8*)SmmEntry - 1;
+
+ SmmEntry->SmmAttributes.Type = STANDARD_IO;
+ SmmEntry->SmmAttributes.PortGranularity = PORT_SIZE_16;
+ SmmEntry->SmmAttributes.DataGranularity = DATA_SIZE_8;
+ SmmEntry->SmmFunction.Function = GET_USB_BOOT_INFO;
+ SmmEntry->SmmFunction.Owner = STANDARD_OWNER;
+ SmmEntry->SmmPort = SW_SMI_IO_ADDRESS;
+ SmmEntry->SmmData = USB_SWSMI;
+
+//TODOx64: What is SmmTable pointer is more the 4G in 64 bit mode?
+//CSM specification 0.96 defines the pointer as UINT32
+ ((EFI_TO_COMPATIBILITY16_BOOT_TABLE*)EfiToCompatibility16BootTable)->SmmTable = (UINT32)SmmTable;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ShadowServiceRoms
+//
+// Description: Executes Option ROMs that are not associated with PCI device,
+// e.g. PXE base code image.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ShadowServiceRoms (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This
+)
+{
+ void *RomImageStart;
+ UINTN RomImageSize;
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *iLegacyBios;
+ UINTN Flags;
+ UINTN NoHandles;
+ EFI_HANDLE *HandleBuffer;
+
+#pragma pack(push,1)
+ typedef struct{
+ UINT16 ModuleId, VendorId, DeviceId;
+ UINT32 Size;
+ } OPROM_HEADER;
+#pragma pack(pop)
+ OPROM_HEADER *Header;
+
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ &NoHandles,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->HandleProtocol(
+ HandleBuffer[0],
+ &gEfiLegacyBiosProtocolGuid,
+ &iLegacyBios
+ );
+ pBS->FreePool(HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = FindEmbeddedRom(SERVICEROM_MODULEID, 0, 0, &RomImageStart, &RomImageSize);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Execute InstallPciRom for service ROMs: the 1st service ROM is pointed by
+ // RomImageStart; install this ROM and all consequent service ROMs
+ //
+ do {
+ TRACE((-1, "CsmBsp: Installing service ROM, %x...", RomImageStart));
+ Status = iLegacyBios->InstallPciRom(
+ iLegacyBios,
+ NULL, // PciHandle;
+ &RomImageStart,
+ &Flags,
+ NULL, NULL, NULL, NULL);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ Header = (OPROM_HEADER*)RomImageStart-1;
+ TRACE((-1, "...OK, size %x\n", Header->Size));
+ Header = (OPROM_HEADER*)((UINT8*)RomImageStart+Header->Size);
+ RomImageStart = Header+1;
+ } while(Header->ModuleId == SERVICEROM_MODULEID);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: PlatformHooks
+//
+// Description: Allows platform to perform any required action after a LegacyBios
+// operation.
+// Input:
+// DeviceHandle List of PCI devices in the system. Type EFI_HANDLE is defined in
+// InstallProtocolInterface() in the EFI 1.10 Specification.
+// ShadowAddress First free OpROM area, after other OpROMs have been dispatched..
+// Compatibility16Table Pointer to the Compatibility16 Table.
+// AdditionalData Pointer to additional data returned - mode specific..
+//
+// Output:
+// EFI_SUCCESS The operation performed successfully.
+// EFI_UNSUPPORTED Mode is not supported on this platform.
+// EFI_SUCCESS Mode specific.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PlatformHooks (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN EFI_GET_PLATFORM_HOOK_MODE Mode,
+ IN UINT16 Type,
+ IN EFI_HANDLE OPTIONAL DeviceHandle,
+ IN OUT UINTN OPTIONAL *ShadowAddress,
+ IN EFI_COMPATIBILITY16_TABLE OPTIONAL *Compatibility16Table,
+ OUT VOID OPTIONAL **AdditionalData
+ )
+{
+ switch (Mode) {
+ case EfiPlatformHookPrepareToScanRom:
+ return EFI_UNSUPPORTED;
+ case EfiPlatformHookShadowServiceRoms:
+ return ShadowServiceRoms(This);
+ case EfiPlatformHookAfterRomInit:
+ return EFI_UNSUPPORTED;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetRoutingTable
+//
+// Description: Returns information associated with PCI IRQ routing.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// RoutingTable Pointer to the PCI IRQ routing table. This location is
+// the $PIR table minus the header. The contents is defined
+// by the PCI IRQ Routing Table Specification; it has the
+// number of RoutingTableEntries of EFI_LEGACY_IRQ_ROUTING_ENTRY.
+// RoutingTableEntries Number of entries in the PCI IRQ routing table.
+// LocalPirqTable $PIR table. It contains EFI_LEGACY_PIRQ_TABLE_HEADER,
+// immediately followed by RoutingTable.
+// PirqTableSize Size of $PIR table.
+// LocalIrqPriorityTable A priority table of IRQs to assign to PCI. This table
+// has IrqPriorityTableEntries entries of
+// EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY type and is used to
+// prioritize the allocation of IRQs to PCI.
+// IrqPriorityTableEntries Number of entries in the priority table.
+//
+// Output:
+// EFI_SUCCESS Data was returned successfully.
+//
+// Referrals:
+// EFI_LEGACY_BIOS_PLATFORM_PROTOCOL, EFI_LEGACY_IRQ_ROUTING_ENTRY,
+// EFI_LEGACY_PIRQ_TABLE_HEADER, EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetRoutingTable(
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ OUT VOID **RoutingTable,
+ OUT UINTN *RoutingTableEntries,
+ OUT VOID **LocalPirqTable, OPTIONAL
+ OUT UINTN *PirqTableSize, OPTIONAL
+ OUT VOID **LocalIrqPriorityTable, OPTIONAL
+ OUT UINTN *IrqPriorityTableEntries OPTIONAL
+ )
+{
+ UINTN i = 0;
+ EFI_STATUS Status = EFI_NOT_READY;
+
+ if(IsValidPrt)
+ {
+ *RoutingTable = Prt;
+ // *RoutingTableEntries = AmiPrt->bUsedEntries;
+ *RoutingTableEntries = gUsedPciEntries;
+ if (LocalPirqTable != NULL) *LocalPirqTable = MsPrt;
+ if (PirqTableSize != NULL) *PirqTableSize = MsPrt->TableSize;
+ if (LocalIrqPriorityTable != NULL || IrqPriorityTableEntries != NULL) return EFI_UNSUPPORTED;
+ Status = EFI_SUCCESS;
+
+ for(i = 0; CsmGetRoutingTableFunctions[i] != NULL; i++)
+ {
+ // Do not check the return status incase there are multiple functions that update
+ // each of the tables individually.
+ Status = CsmGetRoutingTableFunctions[i](This,
+ RoutingTable,
+ RoutingTableEntries,
+ LocalPirqTable,
+ PirqTableSize,
+ LocalIrqPriorityTable,
+ IrqPriorityTableEntries);
+ }
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: BspUpdatePrt
+//
+// Description: This function is called from PciInterrupts.c when PCI Interrupt
+// routing table is ready for copying to shadow memory. Do the final
+// updates of the routing information.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// RoutingTable Pointer to the PCI IRQ routing table. This location is
+// the $PIR table. The contents is defined by the PCI IRQ
+// Routing Table Specification; it has the number of
+// RoutingTableEntries of EFI_LEGACY_IRQ_ROUTING_ENTRY.
+//
+// Output:
+// EFI_SUCCESS Data was updated successfully.
+//
+// Notes: Checksum of the table is not required in this routine, it will
+// be done after this call is executed.
+//
+// Referrals:
+// EFI_LEGACY_BIOS_PLATFORM_PROTOCOL, EFI_LEGACY_IRQ_ROUTING_ENTRY,
+// EFI_LEGACY_PIRQ_TABLE_HEADER, EFI_LEGACY_IRQ_PRIORITY_TABLE_ENTRY
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+BspUpdatePrt(
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN VOID *RoutingTable
+)
+{
+ UINTN i = 0;
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+ for(i = 0; CsmBspUpdatePrtFunctions[i] != NULL; i++)
+ {
+ Status = CsmBspUpdatePrtFunctions[i](This, RoutingTable);
+ if(!EFI_ERROR(Status)) break;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: TranslatePirq
+//
+// Description: This function translates the given PIRQ back through all
+// buses, if required, and returns the true PIRQ and associated IRQ.
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// PciBus PCI bus number for this device.
+// PciDevice PCI device number for this device.
+// PciFunction PCI function number for this device.
+// Pirq The PIRQ. PIRQ A = 0, PIRQ B = 1, and so on.
+// PirqIrq IRQ assigned to the indicated PIRQ.
+//
+// Output:
+// EFI_SUCCESS The PIRQ was translated.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+TranslatePirq (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN UINTN PciBus,
+ IN UINTN PciDevice,
+ IN UINTN PciFunction,
+ IN OUT UINT8 *Pirq,
+ OUT UINT8 *PciIrq
+ )
+{
+ return Intx2Pirq(
+ This,
+ PciBus, PciDevice, PciFunction,
+ Pirq, PciIrq, NULL);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: BspPrepareToBoot
+//
+// Description: Prepares the attempt to boot a traditional OS.
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// BbsDevicePath EFI Device Path from BootXXXX variable. Type
+// BBS_BBS_DEVICE_PATH is defined in EFI_LEGACY_BIOS_PROTOCOL.LegacyBoot().
+// BbsTable A list of BBS entries of type BBS_TABLE. Type BBS_TABLE is
+// defined in Compatibility16PrepareToBoot().
+// LoadOptionsSize Size of LoadOption in bytes.
+// LoadOptions LoadOption from BootXXXX variable.
+// EfiToLegacyBootTable Pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE. Type
+// EFI_TO_COMPATIBILITY16_BOOT_TABLE is defined
+// in Compatibility16PrepareToBoot().
+// Output:
+// EFI_SUCCESS Ready to boot.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+BspPrepareToBoot (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN BBS_BBS_DEVICE_PATH *BbsDevicePath,
+ IN VOID *BbsTable,
+ IN UINT32 LoadOptionsSize,
+ IN VOID *LoadOptions,
+ IN VOID *EfiToLegacyBootTable
+ )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINTN i = 0;
+
+ for(i = 0; CsmBspPrepareToBootFunctions[i] != NULL; i++)
+ {
+ Status = CsmBspPrepareToBootFunctions[i](This, BbsDevicePath, BbsTable, LoadOptionsSize, LoadOptions, EfiToLegacyBootTable);
+ if(!EFI_ERROR(Status)) break;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitCsmBoard
+//
+// Description: CSM BSP driver entry point, it will instantinate
+// LEGACY_BIOS_PLATFORM_PTOTOCOL interface
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+//
+// Output: The status of CSM board initalization
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitCsmBoard (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_GUID gFile;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *pFV;
+ UINT32 Authentication;
+
+// InitAmiLib(ImageHandle, SystemTable);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(PLATFORM_BIOS_INFO),
+ &BspBiosInfo);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SetMem(BspBiosInfo, sizeof(PLATFORM_BIOS_INFO), 0);
+
+ //
+ // Get LOADED_IMAGE protocol in order to get to the file name GUID
+ //
+ Status = pBS->HandleProtocol(
+ ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Now we have EFI_DEVICE_PATH_PROTOCOL *LoadedImage->FilePath
+ //
+ gFile = ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(LoadedImage->FilePath))->NameGuid;
+
+ //
+ // Get the Firmware Volume Protocol
+ //
+ Status = pBS->HandleProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiFirmwareVolumeProtocolGuid,
+ &pFV
+ );
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Read section with Legacy ROMs
+ //
+ EmbeddedRom = NULL; // make ReadSection allocate memory
+ EmbeddedRomSize = 0;
+ Status = pFV->ReadSection (
+ pFV,
+ &gFile,
+ EFI_SECTION_RAW,
+ 0,
+ &EmbeddedRom,
+ &EmbeddedRomSize,
+ &Authentication);
+ if (EFI_ERROR(Status)) return Status;
+
+ BspBiosInfo->hImage = ImageHandle;
+ BspBiosInfo->iBiosPlatform.GetPlatformInfo = GetPlatformInfo;
+ BspBiosInfo->iBiosPlatform.GetPlatformHandle = GetPlatformHandle;
+ BspBiosInfo->iBiosPlatform.SmmInit = SmmInit;
+ BspBiosInfo->iBiosPlatform.PlatformHooks = PlatformHooks;
+ BspBiosInfo->iBiosPlatform.GetRoutingTable = GetRoutingTable;
+ BspBiosInfo->iBiosPlatform.TranslatePirq = TranslatePirq;
+ BspBiosInfo->iBiosPlatform.PrepareToBoot = BspPrepareToBoot;
+
+ InitPrt(&BspBiosInfo->iBiosPlatform);
+
+ //
+ // Make a new handle and install the protocol
+ //
+ BspBiosInfo->hBios = NULL;
+ Status = pBS->InstallProtocolInterface (
+ &BspBiosInfo->hBios,
+ &gEfiLegacyBiosPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &BspBiosInfo->iBiosPlatform
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CsmHwInfo.c b/Core/EM/CSM/CsmHwInfo.c
new file mode 100644
index 0000000..ab4bce8
--- /dev/null
+++ b/Core/EM/CSM/CsmHwInfo.c
@@ -0,0 +1,2063 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CSM/CsmHwInfo.c 1 7/31/17 4:55a Chienhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 7/31/17 4:55a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CSM/CsmHwInfo.c $
+//
+// 1 7/31/17 4:55a Chienhsieh
+// [TAG] EIP184371
+// [Description] Filter the DiskInfo protocols while creating HddInfo
+// [Files] CsmHwInfo.c
+//
+// 114 8/07/14 12:44p Fasihm
+// [TAG] EIP180683
+// [Category] Improvement
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: CSM build error when disabling
+// X64_SUPPORT.
+// [Solution] Changed file to fix the build error.
+// [Files]
+// Core\EM\CSM\CsmBsp.c
+// Core/EM/CSM/CsmHwInfo.c
+//
+// 113 8/06/14 5:21p Fasihm
+// [TAG] EIP180688
+// [Category] Improvement
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: PMM high memory life cycle.
+// [Solution] Changed file to address the PMM high memory life cycle.
+// [Files]
+// Core/EM/CSM/CsmHwInfo.c
+//
+// 112 8/06/14 3:21p Fasihm
+// [TAG] EIP180674
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: CSM16: RT PCI function find_device should
+// skip buses that do not exist.
+// [Solution] find_device function in RT-PCI.ASM has been modified to
+// look for the device on the buses that are physically present in the
+// system.
+// [Files]
+// Addon/AmiLegacy16.bin
+// Core/EM/CSM/CSM.h
+// Core/EM/CSM/CsmHwInfo.c
+//
+// 111 8/06/14 12:31p Fasihm
+// [TAG] EIP180666
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Aptio4: Sata boot options need to be distinguished when
+// there are more than one controller.
+// [Solution] While displaying Boot option in the Set up screen,
+// Proposed to display in format ( C<Controller Number> :: P<Port Number>
+// - Model Number).
+// [Files]
+// Core/EM/CSM/CSM.h
+// Core/EM/CSM/CsmHwInfo.c
+//
+// 110 12/18/12 1:44p Olegi
+// [TAG] EIP108682
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Invalid Error Code from CSM Functions
+// [RootCause] BIT31 is used as error indication
+// [Solution] use EFI_ERROR_BIT macro instead of BIT31
+// [Files] CSM.c
+// CsmHwInfo.c
+//
+// 109 12/12/12 2:54p Olegi
+// [TAG] EIP109283
+// [Category] Bug Fix
+// [Symptom] PCI RT32 last bus improperly reported
+// [RootCause] The last PCI bus is reported based on the chipset
+// specific PCI bus configuration.
+// [Solution] Update RT32 binary with the last bus obtained from PCI Bus
+// driver.
+// [Files] CsmHwInfo.c, rt32core.asm
+//
+// 108 6/25/12 3:59p Olegi
+// [TAG] EIP90257
+// [Category] Improvement
+// [Description] In CSM, don't clear allocated memory below 640K - added
+// ClearFreeMemory function
+// [Files] CsmOpROM.c
+// CSM.c
+// CsmHwInfo.c
+//
+// 107 2/09/12 10:19a Olegi
+// [TAG] EIP71972
+// Correction to the original EIP71972 resolution: Slave IDE device was
+// not getting proper drive handle.
+//
+// 106 11/04/11 12:39p Olegi
+// [TAG] EIP74722
+// [Category] Improvement
+// [Description] IDE drive information is not displayed correctly in the
+// Boot page in Setup when both Master and Slave drives are connected
+// [Files] CsmHwInfo.c
+//
+// 105 10/28/11 9:24a Olegi
+// [TAG] EIP71972
+// [Category] Improvement
+// [Description] In some cases HddInfo information is not properly used
+// to create BBS entry.
+// Cases are:
+// - slave drive appears before master in DisdInfo hanle array
+// - higher controller PCI function appears before lower function in the
+// DiskInfo list
+// [Files] csmhwinfo.c
+//
+// 104 5/04/11 2:15p Olegi
+// [TAG] EIP59632
+// [Category] Improvement
+// [Description] Removed the break from for loop in
+// UpdateCsm16Configuration; this allows to finish all COM data
+// initialization.
+// [Files] CsmHwInfo.c
+//
+// 103 4/11/11 12:56p Olegi
+// [TAG] EIP56926
+// [Category] Improvement
+// [Description] Added Primary/Secondary Master/Slave information in the
+// drive string.
+// [Files] csmhwinfo.c
+//
+// 102 2/04/11 10:19a Olegi
+// [TAG] EIP53139
+// [Category] Improvement
+// [Description] Typo corrected
+// [Files] csmhwinfo.c
+//
+// 101 12/03/10 12:43p Olegi
+// [TAG] EIP48471
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] COM Port addresses are not filled in correctly in BDA when
+// COM 0(First COM port) disabled in setup.
+// [RootCause] For the COM port resource details in BDA, we should not
+// depend on the UID of the Com port.
+// [Solution] 1) Get the 1st COM port details and fill the details in
+// CSm16bootable , BDA 40:0 and increment Serial Port count in 40:0x10.
+// 2) Get the 2nd Com port details and fill the details in CSm16bootable ,
+// BDA 40:2 and increment Serial Port count in 40:0x10..Continue this for
+// 4 com ports.
+// [Files] CsmHwInfo.c
+// CsmLib.c
+//
+// 100 11/08/10 9:06a Olegi
+// Added CloseEvent call in UpdateLastPciBus callback function.
+//
+// 99 8/17/10 3:10p Olegi
+// Fixes discovered by Klockwork II engine: EIP37977
+//
+// 98 7/16/10 12:12p Olegi
+// EIP39395: Update CSM16 header checksum after LastPciBus field of it has
+// been changed.
+//
+// 97 6/18/10 10:29a Olegi
+// EIP39149: Bugfix in UpdatePciLastBusCallback function.
+//
+// 96 5/07/10 5:04p Felixp
+// Bug fix in GetSystemMemoryMap
+//
+// 95 5/07/10 5:00p Felixp
+// Minor improvement in GetSystemMemoryMap (EIP 38327):
+// use memory map descriptor size returned by the GetMemoryMap instead of
+// hard-coded value.
+//
+// 94 4/28/10 2:51p Oleksiyy
+// EIP 35563 Fixed logic when looking for ACPI 1.1 only tables.
+//
+// 93 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 92 12/28/09 7:46a Olegi
+// Added GetLptResource function.
+//
+// 91 12/28/09 7:33a Olegi
+//
+// 90 12/08/09 9:52a Olegi
+//
+// 89 12/01/09 11:38a Olegi
+// Bugfix in EnableDisableNmi function.
+//
+// 88 8/18/09 2:02p Rameshr
+// AhciBus driver doesn't work for Multi Entry.
+// Ahci Int13 initilization code moved from AhciBus to CsmHwinfo.c
+// EIP: 25369
+//
+// 87 8/06/09 11:42a Olegi
+// MaxPciBus reporting change: do not report FF; this is XP limitation,
+// EIP#24852.
+//
+// 86 6/16/09 4:11p Olegi
+// Generic modifications to update LastPciBus field in
+// EFI_COMPATIBILITY16_TABLE.
+//
+// 85 6/16/09 10:09a Olegi
+// Resolved the incompatibility with the GenericSio.h definitions.
+//
+// 84 6/05/09 10:32a Olegi
+// EIP20813 - make IRQ7 handler execute from E000 segment, this is the
+// workaround for DOS problem, that will take over IRQ7 handler if it is
+// located in F000.
+//
+// 83 4/02/09 2:12p Olegi
+// Removed the hardcoding of COM port base address/interrupt.
+//
+// 82 3/13/09 5:23p Olegi
+// Modifications in GetAtaAtapiInfo():
+// - removed checking if ABAR (PciCfg[24h]) is 0: under the condition
+// where Subclass code is 6 this checking does not make sense
+// - added the clarification of checking for SATA device path vs. AE bit
+//
+// 81 12/02/08 10:20a Olegi
+// Changed the logic of extended memory size calculation.
+//
+// 80 10/10/08 3:36p Olegi
+//
+// 79 6/04/08 11:09a Olegi
+// Bugfix in the previous modification.
+//
+// 78 6/02/08 6:13p Olegi
+// Modified GetAtaAtapiInfo to handle non-IDE mass storage controllers.
+//
+// 77 3/28/08 3:01p Olegi
+// Bugfix in GetAtaAtapiInfo for AHCI enabled controller.
+//
+// 76 2/25/08 4:48p Olegi
+// GetAtaAtapiInfo is modified to handle the situation when SATA
+// controller is in RAID mode and RAID OpROM is not handling all connected
+// devices (CDROM).
+//
+// 75 12/10/07 1:34p Olegi
+// Bug in the previous checkin is fixed.
+//
+// 74 12/10/07 12:27p Olegi
+// Modified AHCI controller checking.
+//
+// 73 12/04/07 11:07a Olegi
+//
+// 72 11/07/07 10:44a Olegi
+// Fix in GetExtendedMemSize function: if the amount of memory is 4GB or
+// more, some memory is remapped above 4GB by the chipset. In this case
+// this function will return the amount of memory before the remapped
+// area.
+//
+// 71 10/02/07 10:34a Olegi
+// Modified GetFDDStatus() routine to properly use IsSioDevicePluggedIn().
+//
+// 2 7/17/07 6:17p Fasihm
+//
+// 69 6/26/07 9:59a Olegi
+// MMIO regions with runtime attribute set will have the corresponding
+// E820 reserved entry.
+//
+// 68 6/18/07 5:46p Olegi
+//
+// 67 6/06/07 8:16a Olegi
+// Added CSM_CREATES_ATA_ATAPI_STRINGS dependency in CreateDriveString
+// function.
+//
+// 66 6/04/07 12:34p Olegi
+//
+// 65 6/02/07 10:26a Olegi
+// Shadow size correction.
+//
+// 64 5/18/07 11:46a Olegi
+// Changed setting BIT2 in 410h (legacy mouse present bit) in
+// UpdateCsm16Configuration to avoid clearing this bit if it is already
+// set.
+//
+// 63 5/09/07 1:56p Olegi
+//
+// 62 4/27/07 5:13p Olegi
+// CSM.CHM file preparation.
+//
+// 61 4/13/07 9:40a Olegi
+//
+// 60 3/29/07 5:44p Olegi
+// Modification in UpdateE820Map function to accomodate Legacy Redirection
+// data area.
+//
+// 59 12/15/06 2:09p Olegi
+// Bugfix in DiskInfoHandles usage.
+//
+// 58 12/14/06 11:06a Olegi
+// Adding AGGRESSIVELY_JOINED_E820_ENTRIES flag.
+//
+// 57 12/12/06 5:33p Olegi
+// DiskInfo handles inserted in BBS table as IBV1/IBV2.
+//
+// 56 9/26/06 4:19p Olegi
+// GetFDDStatus is modified to make default number of FDDs 0.
+//
+// 55 9/20/06 3:11p Olegi
+//
+// 54 9/13/06 9:34a Felixp
+//
+// 53 9/13/06 9:32a Felixp
+//
+// 52 9/12/06 6:10p Markw
+// Update EFI_TO_COMPATIBILITY16_BOOT_TABLE structure to UINT32 instead of
+// pointer. This structure is used for CSM16 which expects 4 byte
+// pointers.
+//
+// 51 8/28/06 9:49a Olegi
+// Bugfix in InstallLegacyMassStorageDevices routine.
+//
+// 50 8/14/06 11:24a Olegi
+//
+// 49 8/04/06 12:05p Olegi
+// E820 table optimization added.
+//
+// 48 7/28/06 4:43p Olegi
+//
+// 47 5/16/06 1:57p Olegi
+//
+// 45 5/04/06 10:55a Robert
+//
+// 44 5/04/06 9:42a Olegi
+// Removed the logic that fixes the location of PATA/SATA in BBS table.
+//
+// 43 5/03/06 3:42p Robert
+// Added the code to sort out the DiskInfo handles so that PATA goes
+// first, SATA next.
+//
+// 40 3/31/06 2:30p Olegi
+//
+// 39 3/13/06 2:32p Felixp
+//
+// 38 12/14/05 4:16p Olegi
+// NMI enable/disable changes.
+//
+// 37 11/29/05 11:38a Olegi
+// Bugfix - not all ATAPI devices are CDROMs, as it used to be considered
+// in the GetAtaAtapi routine.
+//
+// 35 10/17/05 8:56a Olegi
+//
+// 34 10/13/05 6:25p Olegi
+//
+// 33 10/11/05 11:56a Olegi
+//
+// 32 10/10/05 7:27p Olegi
+//
+// 31 10/07/05 5:16p Olegi
+//
+// 30 10/06/05 8:11p Felixp
+//
+// 29 10/06/05 11:52a Felixp
+//
+// 28 9/30/05 6:27p Olegi
+// VC7.1 compatibility issues solved.
+//
+// 27 9/29/05 5:20p Olegi
+//
+// 26 9/28/05 8:30a Olegi
+//
+// 25 9/21/05 3:56p Olegi
+//
+// 24 9/09/05 6:04p Olegi
+//
+// 23 9/09/05 11:19a Olegi
+//
+// 22 6/30/05 7:55p Olegi
+// PS/2 mouse handling reported correctly.
+//
+// 21 6/21/05 12:12p Olegi
+// LegacyBios and LegacyBiosPlatform are combined into one FFS.
+//
+// 20 5/12/05 5:15p Yakovlevs
+//
+// 19 4/22/05 2:10p Olegi
+//
+// 19 4/21/05 9:00a Olegi
+// Modified the rule for inserting E820 entries for regions >4GB
+//
+// 18 4/19/05 11:12a Olegi
+//
+// 17 3/30/05 12:28p Olegi
+// InstallIdePciHandler - IDE control port calculation corrected.
+//
+// 16 3/04/05 1:54p Mandal
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmHwInfo.c
+// Description: Hardware Information routines
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "token.h"
+#include "csm.h"
+#include <Protocol/PciIo.h>
+#include <Protocol/PDiskInfo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PIdeController.h>
+#include <Protocol/BlockIo.h>
+#include <AmiDxeLib.h>
+#include "pci.h"
+#include "biosdata.h"
+#include <Protocol/CsmPlatform.h>
+#include <AcpiRes.h>
+#ifdef AhciSrc_SUPPORT
+#if AhciSrc_SUPPORT
+#include <Protocol/LegacyAhci.h>
+#endif
+#endif
+
+#define MASTER_DRIVE 0
+#define SLAVE_DRIVE 1
+#define PRIMARY_CHANNEL 0
+#define SECONDARY_CHANNEL 1
+#define MAX_IDE_PCI_CONTROLLER (MAX_IDE_CONTROLLER << 1)
+
+// Controller information where IDE devices are connected
+IDE_CONTROLLER_INFO_STRUC IdeControllerInfo[MAX_IDE_PCI_CONTROLLER];
+UINT8 gIdeController = 0;
+
+UINT16 aInstalledPciIrq[MAX_IDE_PCI_CONTROLLER];
+
+EFI_GUID gDiskInfoProtocol = EFI_DISK_INFO_PROTOCOL_GUID;
+EFI_GUID gSataControllerProtocol = SATA_CONTROLLER_PROTOCOL_GUID;
+EFI_GUID gAcpiRsdtPtr = ACPI_20_TABLE_GUID;
+EFI_GUID gAcpiRsdtPtr1_0 = ACPI_10_TABLE_GUID;
+EFI_GUID gSmbiosTable = SMBIOS_TABLE_GUID;
+
+typedef struct {
+ ATAPI_IDENTIFY *IdentifyPtr;
+ EFI_HANDLE DriveHandle;
+} CSM_DRIVE_HANDLE_LIST;
+
+CSM_DRIVE_HANDLE_LIST DriveHandle[MAX_IDE_CONTROLLER*2] ;
+
+EFI_STATUS UpdateCsm16Configuration(EFI_TO_COMPATIBILITY16_BOOT_TABLE*);
+VOID GetExtendedMemSize(UINT32*);
+VOID GetSioDeviceStatus(SIO_DEV_STATUS *devices);
+BOOLEAN IsSioDevicePluggedIn(SIO_DEV_STATUS *plugged_devices, EFI_HANDLE *Handle);
+
+extern BIOS_INFO *CoreBiosInfo;
+extern BOOLEAN gIsMassStorageInstalled;
+extern UINTN gMaxOpRomAddress;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: UpdateCsm16Configuration
+//
+// Description:
+// This function updates Csm16BootTable and BDA. It can be called multiple
+// times during POST as the new hardware is discovered and configured.
+//
+// Input:
+// Csm16BootTable pointer to EFI_TO_COMPATIBILITY16_BOOT_TABLE
+//
+// Output:
+// EFI_SUCCESS Table is updated successfully.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateCsm16Configuration(
+ IN OUT EFI_TO_COMPATIBILITY16_BOOT_TABLE *Csm16BootTable
+)
+{
+ SIO_DEV_STATUS sio_devices;
+ SIO_DEV_STATUS sio_devices_plugged_in;
+ BDA_DATA *bda;
+ UINT16 machineconfig = 0;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINT16 Address;
+ UINT8 Irq;
+ UINT8 ComPortIndex;
+
+ //
+ // Fill in EFI_TO_COMPATIBILITY16_BOOT_TABLE
+ // Note: CSM specification 0.96 defines the pointer as UINT32 - it is
+ // assumed BbsTable pointer is within 4GB address space.
+ Csm16BootTable->BbsTable = (UINT32)CoreBiosInfo->BbsTable;
+ Csm16BootTable->NumberBbsEntries = CoreBiosInfo->BbsEntriesNo;
+
+ //
+ // Updade SIO status in Csm16BootTable->SioData and in BDA
+ //
+ bda = (BDA_DATA*)((UINTN) 0x400);
+
+// The following definitions are from the up-to-date GenericSio.h
+// they can be used after GenericSio.h will be labeled with these changes.
+//#define SIO_DEV_COM3 0x1000
+//#define SIO_DEV_COM4 0x2000
+
+ sio_devices.DEV_STATUS = SIO_DEV_COM1 | SIO_DEV_COM2 | 0x1000 | 0x2000 |
+ SIO_DEV_LPT | SIO_DEV_FDC | SIO_DEV_PS2MS;
+ GetSioDeviceStatus(&sio_devices);
+
+ if (sio_devices.Fdd) {
+ Csm16BootTable->SioData.Floppy.NumberOfFloppy = 1;
+ machineconfig |= 1;
+ }
+
+ for(ComPortIndex = 0; ComPortIndex < 4; ComPortIndex ++){
+ Status = GetComPortResource(ComPortIndex, &Address, &Irq);
+ if (!EFI_ERROR(Status))
+ {
+ Csm16BootTable->SioData.Serial[ComPortIndex].Address = Address;
+ Csm16BootTable->SioData.Serial[ComPortIndex].Irq = Irq;
+ Csm16BootTable->SioData.Serial[ComPortIndex].Mode = DEVICE_SERIAL_MODE_NORMAL;
+ bda->rs_232_address[ComPortIndex] = Address;
+ machineconfig += 0x200;
+ }
+ }
+ // Note that SIO_DEV_STATUS limits the number of LPT to one
+ if (sio_devices.Lpt) {
+ Status = GetLptResource(&Address, &Irq);
+ if (!EFI_ERROR(Status)){
+ Csm16BootTable->SioData.Parallel[0].Address = Address;
+ Csm16BootTable->SioData.Parallel[0].Irq = Irq;
+ Csm16BootTable->SioData.Parallel[0].Mode = DEVICE_PARALLEL_MODE_MODE_OUTPUT_ONLY;
+ bda->printer_address[0] = Address;
+ machineconfig |= 0x4000;
+ }
+ }
+
+ if ((bda->machine_config & 4) || sio_devices.Ps2Mouse) {
+ machineconfig |= 0x4;
+
+ sio_devices_plugged_in.DEV_STATUS = 0;
+ sio_devices_plugged_in.Ps2Mouse = 1;
+ if (IsSioDevicePluggedIn(&sio_devices_plugged_in, &Handle)) {
+ Csm16BootTable->SioData.MousePresent = 1;
+ }
+ }
+
+ machineconfig |= 2; // coprocessor is always reported present
+
+ bda->machine_config = machineconfig;
+
+ GetExtendedMemSize(&Csm16BootTable->OsMemoryAbove1Mb);
+ Csm16BootTable->NumberE820Entries = CoreBiosInfo->NumberE820Entries;
+
+ //
+ // Get ACPI&SMBIOS pointers
+ //
+//TODOx64: What is these pointers are more the 4G in 64 bit mode?
+//CSM specification 0.96 defines the pointers as UINT32
+ Csm16BootTable->AcpiTable = (UINT32)GetEfiConfigurationTable(pST, &gAcpiRsdtPtr);
+ if (Csm16BootTable->AcpiTable == 0)
+ Csm16BootTable->AcpiTable = (UINT32)GetEfiConfigurationTable(pST, &gAcpiRsdtPtr1_0);
+
+ TRACE((-1,"CSM - GetEfiConfigurationTable: ACPI table is at %x\n", Csm16BootTable->AcpiTable));
+
+ Csm16BootTable->SmbiosTable = (UINT32)GetEfiConfigurationTable(pST, &gSmbiosTable);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: GetFDDStatus
+//
+// DESCRIPTION: This function returns the status of the floppy drive.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+FDD_STATUS GetFDDStatus()
+{
+ SIO_DEV_STATUS sio_devices;
+ EFI_STATUS Status;
+ FDD_STATUS DriveStatus = NO_FLOPPY_DRIVE;
+ EFI_HANDLE Handle;
+ EFI_BLOCK_IO_PROTOCOL *blkiop;
+
+ sio_devices.DEV_STATUS = 0;
+ sio_devices.Fdd = 1;
+
+ if (!IsSioDevicePluggedIn(&sio_devices, &Handle)) return NO_FLOPPY_DRIVE;
+
+ Status = pBS->HandleProtocol(Handle,&gEfiBlockIoProtocolGuid, &blkiop);
+ ASSERT_EFI_ERROR(Status);
+
+ if (!EFI_ERROR(Status)) {
+ DriveStatus = blkiop->Media->MediaPresent? FLOPPY_INSERTED : NO_FLOPPY_DISK;
+ }
+
+ return DriveStatus;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: InstallIdePciHandler
+//
+// DESCRIPTION: This function makes InstallPciHandler CSM16 call
+//
+// PARAMETERS: PCI IDE controller data needed for the IRQ installation
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallIdePciHandler(
+ HDD_INFO* HddInfo1,
+ HDD_INFO* HddInfo2
+)
+{
+ EFI_IA32_REGISTER_SET RegSet;
+ EFI_STATUS Status;
+ UINT8 i;
+ EFI_LEGACY_INSTALL_PCI_HANDLER *PciHandlerData = &CoreBiosInfo->Thunk->PciHandler;
+ UINT16 wPciDev = 0xFFFF;
+ BOOLEAN IsNativeMode;
+ //
+ // Check whether PCI IRQ handler for this PCI device has been installed, exit if so.
+ //
+ for (i = 0; i < MAX_IDE_PCI_CONTROLLER; i++) {
+ wPciDev = (UINT16)((HddInfo1->Bus << 8) | (HddInfo1->Device << 3) | HddInfo1->Function);
+ if (!aInstalledPciIrq[i]) break; // New entry found
+ if (wPciDev == aInstalledPciIrq[i]) return EFI_SUCCESS;
+ }
+ ASSERT(i < MAX_IDE_PCI_CONTROLLER);
+ if (i == MAX_IDE_PCI_CONTROLLER) return EFI_OUT_OF_RESOURCES; // Error - no free entries
+
+ //
+ // Prepare PCI handler data in Thunk memory
+ //
+ PciHandlerData->PciBus = (UINT8)HddInfo1->Bus;
+ PciHandlerData->PciDeviceFun = (UINT8)((HddInfo1->Device << 3) | HddInfo1->Function);
+ PciHandlerData->PciSegment = 0;
+ PciHandlerData->PciClass = PCI_CL_MASS_STOR;
+ PciHandlerData->PciSubclass = PCI_CL_MASS_STOR_SCL_IDE;
+ IsNativeMode = HddInfo1->HddIrq != 14;
+ PciHandlerData->PciInterface = (IsNativeMode)?0x8F:0x8A;
+
+ //
+ // Primary section
+ //
+ PciHandlerData->PrimaryIrq = HddInfo1->HddIrq;
+ PciHandlerData->PrimaryReserved = 0;
+ PciHandlerData->PrimaryControl = HddInfo1->ControlBaseAddress;
+ PciHandlerData->PrimaryBase = HddInfo1->CommandBaseAddress;
+ PciHandlerData->PrimaryBusMaster = HddInfo1->BusMasterAddress;
+ //
+ // Secondary section
+ //
+ PciHandlerData->SecondaryIrq = HddInfo2->HddIrq;
+ PciHandlerData->SecondaryReserved = 0;
+ PciHandlerData->SecondaryControl = HddInfo2->ControlBaseAddress;
+ PciHandlerData->SecondaryBase = HddInfo2->CommandBaseAddress;
+ PciHandlerData->SecondaryBusMaster = HddInfo2->BusMasterAddress;
+
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16InstallPciHandler;
+ RegSet.X.ES = EFI_SEGMENT (PciHandlerData);
+ RegSet.X.BX = EFI_OFFSET (PciHandlerData);
+
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+ Status = (RegSet.X.AX)? ((RegSet.X.AX & 0x7FFF) | EFI_ERROR_BIT) : EFI_SUCCESS;
+ ASSERT_EFI_ERROR(Status);
+ if (!EFI_ERROR(Status)) {
+ aInstalledPciIrq[i] = wPciDev; // Save the new PCI device entry
+ }
+
+ Status = CoreBiosInfo->iRegion->Lock (CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: UpdateIdeControllerInfo
+//
+// Description: This function will check if the BusDevFunc is existing in
+// Idecontrollerinfo structure array,if it exist then it return.
+// If it is not exist, it will add BusDevFunc into IdeControllerInfo structure.
+//
+// Input: IdeBusDevFun - It contain the BusDevFunc number for a device
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void UpdateIdeControllerInfo(UINT16 IdeBusDevFun)
+{
+ UINTN i;
+
+ for(i=0; i < gIdeController ; i++) {
+ if(IdeControllerInfo[i].BusDevFun == IdeBusDevFun) {
+ /// Controller detected
+ return;
+ }
+ }
+
+ //
+ // A new controller is found so BusDevFunc and ControllerNo is added
+ // into the array of structure.
+ //
+ IdeControllerInfo[gIdeController].BusDevFun = IdeBusDevFun;
+ IdeControllerInfo[gIdeController].ControllerNo = gIdeController++;
+
+ return;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: GetAtaAtapiInfo
+//
+// DESCRIPTION: This function collects the information about currently connected
+// ATA/ATAPI devices. It stores this information in the HDD_INFO data
+// structure and installs legacy interrupt handlers.
+//
+// PARAMETERS: DiskInfoHandles - array of handles with DiskInfo protocol
+// Info - pointer to HDD_INFO array to be updated
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetAtaAtapiInfo(
+ IN OUT EFI_HANDLE **DiskInfoHandles,
+ OUT HDD_INFO* Info
+)
+{
+ EFI_STATUS Status;
+ UINTN i, j, HandlesNo;
+ EFI_DISK_INFO_PROTOCOL *pDiskInfo;
+ EFI_DEVICE_PATH_PROTOCOL *pDevicePath;
+ EFI_PCI_IO_PROTOCOL *pPciIo;
+ EFI_HANDLE Handle;
+ UINTN Seg, Bus, Dev, Func;
+ HDD_INFO *HddInfo;
+ UINT32 PriSec, MasterSlave;
+ UINT8 pciCfg[0x40];
+ UINT16 priCmdIoAddr, secCmdIoAddr;
+ UINT16 priCtlIoAddr, secCtlIoAddr;
+ UINT16 bmIoAddr;
+ UINT8 priIrq, secIrq;
+ BOOLEAN IsNativeMode, IsAtapiDevice, IsSataDevice;
+ ATAPI_IDENTIFY *pAtapiIdentifyBuffer;
+ UINT32 DataCount = sizeof (ATAPI_IDENTIFY);
+ CSM_DRIVE_HANDLE_LIST *pDriveHandle = DriveHandle;
+
+ // Clear drive handles list
+ pBS->SetMem(pDriveHandle, sizeof(CSM_DRIVE_HANDLE_LIST)*MAX_IDE_CONTROLLER*2, 0);
+
+ //
+ // Get the list of DiskInfo handles
+ //
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gDiskInfoProtocol,
+ NULL,
+ &HandlesNo,
+ DiskInfoHandles);
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+
+ for (i = 0; i < HandlesNo; i++) {
+// [ EIP184371 ]+>
+ // Check DiskInfo.Interface field
+ static EFI_GUID DiIntrfGuid = EFI_DISK_INFO_IDE_INTERFACE_GUID;
+
+ Status = pBS->HandleProtocol (
+ (*DiskInfoHandles)[i],
+ &gDiskInfoProtocol,
+ &pDiskInfo); // Get DiskInfo protocol
+ ASSERT_EFI_ERROR (Status);
+
+
+ if (guidcmp(&pDiskInfo->Interface, &DiIntrfGuid)) continue;
+// [ EIP184371 ]+<
+
+ Status = pBS->HandleProtocol ((*DiskInfoHandles)[i],
+ &gEfiDevicePathProtocolGuid,
+ (VOID*)&pDevicePath);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Get PCI device/function info out of DiskInfo device path
+ //
+ Status = pBS->LocateDevicePath(
+ &gEfiPciIoProtocolGuid, // Search key
+ &pDevicePath, // Will be updated with PCI device path
+ &Handle); // Will be updated with PCI device handle
+ if (EFI_ERROR(Status)) continue; // PCI device path is not found
+
+ // check if SataController protocol is installed
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gSataControllerProtocol,
+ &pPciIo); //Dummy. Interface is null.
+ IsSataDevice = !(BOOLEAN)EFI_ERROR(Status);
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiPciIoProtocolGuid,
+ &pPciIo); // Get PciIo protocol
+ ASSERT_EFI_ERROR (Status);
+
+// [ EIP184371 ]+>
+// Status = pBS->HandleProtocol (
+// (*DiskInfoHandles)[i],
+// &gDiskInfoProtocol,
+// &pDiskInfo); // Get DiskInfo protocol
+// ASSERT_EFI_ERROR (Status);
+// [ EIP184371 ]+<
+
+ pDiskInfo->WhichIde(pDiskInfo, &PriSec, &MasterSlave); // Device/Channel info
+ Status = pPciIo->GetLocation(pPciIo, &Seg, &Bus, &Dev, &Func); // Location on PCI bus
+ ASSERT_EFI_ERROR(Status);
+
+ /// Update controller Number for the IDE device
+ UpdateIdeControllerInfo(((UINT16)Bus<<8) + ((UINT16)Dev<<3) + (UINT16)Func);
+
+ pPciIo->Pci.Read(
+ pPciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ 0x10,
+ &pciCfg); // Get 40h bytes of PCI device configuration registers
+
+ if (pciCfg[0xB] != PCI_CL_MASS_STOR) continue;
+
+ if (pciCfg[0xA] == PCI_CL_MASS_STOR_SCL_RAID) continue;
+
+ if (pciCfg[0xA] == 6) {
+
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ //
+ // SATA controller is in AHCI mode; we can only handle it if
+ // AE bit is not set and controller is operated using legacy ATA/ATAPI
+ // mechanisms, not AHCI descriptors. Verify this by checking if
+ // SATA device path is installed on this device.
+ //
+ // Note: previously we were checking for the status of AE in controller's
+ // MMIO (ABAR at PciCfg[0x24]+4, Bit31). It was found that for some
+ // controllers it is not safe to access MMIO directly. Example: Intel
+ // ESB2 controller loses index/data access functionality after any
+ // AHCI MMIO register is read directly.
+ //
+ DevicePath = DPGetLastNode(pDevicePath);
+ if (DevicePath->Type == MESSAGING_DEVICE_PATH &&
+ DevicePath->SubType == MSG_USB_SATA_DP) {
+ continue;
+ }
+ }
+
+ IsNativeMode = pciCfg[9] & 1;
+
+ if (IsNativeMode) { // for native mode get data from PCI config space
+ priCmdIoAddr = *(UINT16*)&pciCfg[0x10] & 0xFFFE;
+ secCmdIoAddr = *(UINT16*)&pciCfg[0x18] & 0xFFFE;
+ priCtlIoAddr = (*(UINT16*)&pciCfg[0x14] & 0xFFFE) + 2;
+ secCtlIoAddr = (*(UINT16*)&pciCfg[0x1C] & 0xFFFE) + 2;
+ priIrq = secIrq = pciCfg[0x3C];
+ }
+ else { // for legacy mode use hardcoded data
+ priCmdIoAddr = 0x1F0;
+ secCmdIoAddr = 0x170;
+ priCtlIoAddr = 0x3F6;
+ secCtlIoAddr = 0x376;
+ priIrq = 0xE;
+ secIrq = 0xF;
+ }
+ bmIoAddr = *(UINT16*)&pciCfg[0x20] & 0xFFFE;
+
+ //
+ // All necessary HW data is received; the following loop searches for the
+ // next available HddInfo, fills in HDD_INFO structure and installs legacy
+ // PCI interrupt if needed.
+ //
+ for (j = 0, HddInfo = Info; j < MAX_IDE_CONTROLLER; j++, HddInfo++) {
+ if (!HddInfo->Bus && !HddInfo->Device && !HddInfo->Function) {
+ HddInfo->Status = HDD_PRIMARY;
+ HddInfo->Bus = (UINT32)Bus;
+ HddInfo->Device = (UINT32)Dev;
+ HddInfo->Function = (UINT32)Func;
+ HddInfo->CommandBaseAddress = priCmdIoAddr;
+ HddInfo->ControlBaseAddress = priCtlIoAddr;
+ HddInfo->BusMasterAddress = bmIoAddr;
+ HddInfo->HddIrq = priIrq;
+ HddInfo++;
+ HddInfo->Status = HDD_SECONDARY;
+ HddInfo->Bus = (UINT32)Bus;
+ HddInfo->Device = (UINT32)Dev;
+ HddInfo->Function = (UINT32)Func;
+ HddInfo->CommandBaseAddress = secCmdIoAddr;
+ HddInfo->ControlBaseAddress = secCtlIoAddr;
+ HddInfo->BusMasterAddress = bmIoAddr+8;
+ HddInfo->HddIrq = secIrq;
+ if (PriSec == PRIMARY_CHANNEL) HddInfo--;
+ break;
+ }
+ if (Bus == HddInfo->Bus && Dev == HddInfo->Device && Func == HddInfo->Function) {
+ if (PriSec == SECONDARY_CHANNEL) HddInfo++;
+ break;
+ }
+ }
+
+ //
+ // Copy the IDENTIFY_DRIVE information into appropriate HDD_INFO field
+ //
+ pAtapiIdentifyBuffer = HddInfo->IdentifyDrive;
+ if (MasterSlave != MASTER_DRIVE) pAtapiIdentifyBuffer++;
+ pDiskInfo->Identify(pDiskInfo, pAtapiIdentifyBuffer, &DataCount);
+ pDriveHandle->IdentifyPtr = pAtapiIdentifyBuffer;
+ pDriveHandle->DriveHandle = (*DiskInfoHandles)[i];
+ pDriveHandle++;
+ //
+ // Check whether device is ATA or ATAPI - WORD 0 bits 14 and 15
+ //
+ IsAtapiDevice = (BOOLEAN)((*(UINT16*)pAtapiIdentifyBuffer & 0xC000) == 0x8000);
+ //
+ // Update HDD_INFO status
+ //
+ if (PriSec == PRIMARY_CHANNEL) {
+ HddInfo->Status |= HDD_PRIMARY;
+ } else {
+ HddInfo->Status |= HDD_SECONDARY;
+ }
+ if (MasterSlave == MASTER_DRIVE) {
+ if (IsAtapiDevice) {
+ HddInfo->Status |= HDD_MASTER_ATAPI;
+ } else {
+ HddInfo->Status |= HDD_MASTER_IDE;
+ }
+ } else { // SLAVE_DRIVE
+ if (IsAtapiDevice) {
+ HddInfo->Status |= HDD_SLAVE_ATAPI;
+ } else {
+ HddInfo->Status |= HDD_SLAVE_IDE;
+ }
+ }
+ if (IsSataDevice) HddInfo->Status |= HDD_SATA_PATA;
+ CoreBiosInfo->HddCount++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+ //(EIP20813+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetINT0F_E0000
+//
+// Description: Change INT0F Vector To E000 Segment
+//
+// Output: EFI_STATUS Success of failure of the operation.
+//
+// Notes: If the IRQ7 vector is in F000 segment, MS-DOS will take over
+// the IRQ7 ISR and cause HDDs not working. This routine places IRQ7
+// handler in E000 segment to avoid this problem.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#pragma pack(1)
+typedef struct
+{
+ UINT8 Far_JMP;
+ UINT32 Address;
+}E0000_Int0f;
+#pragma pack()
+
+EFI_STATUS
+SetINT0F_E0000()
+{
+ EFI_STATUS Status;
+ E0000_Int0f *P_E0000_Int0f;
+ UINT32 LockUnlockAddr, LockUnlockSize;
+ UINT32 *PInt15;
+
+ PInt15=(UINT32*)(0x0f*4);
+
+ //
+ // Allocate legacy region in E000 segment; store SEG:OFS of the allocated
+ // memory in global variables
+ //
+ Status =GetLegacyRegion(&CoreBiosInfo->iBios, sizeof(E0000_Int0f), E0000_BIT, 0x10, &P_E0000_Int0f);
+
+ if(EFI_ERROR(Status)) return Status;
+
+ UnlockShadow((UINT8*)P_E0000_Int0f, sizeof(E0000_Int0f), &LockUnlockAddr, &LockUnlockSize);
+
+ P_E0000_Int0f->Far_JMP=0xEA; //far jump
+ P_E0000_Int0f->Address=*PInt15; //save original vector
+ *PInt15= EFI_SEGMENT(P_E0000_Int0f) * 0x10000 | EFI_OFFSET (P_E0000_Int0f); //Set New INT0F Vector
+
+ LockShadow(LockUnlockAddr, LockUnlockSize);
+
+ return EFI_SUCCESS;
+}
+
+ //<(EIP20813+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: InstallIdeInterrupts
+//
+// DESCRIPTION: This function installs PCI interrupts for all PATA and SATA
+// controllers.
+//
+// PARAMETERS: HDD_INFO
+//
+// NOTES: HDD_INFO is expected to be populated before this call.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallIdeInterrupts(
+ IN HDD_INFO *HddInfo
+)
+{
+ UINT8 j;
+ UINT8 hdd_irq7_set=0;
+ HDD_INFO *HddInfo1 = HddInfo;
+ HDD_INFO *HddInfo2 = HddInfo;
+ EFI_STATUS Status;
+
+ for (j = 0; j < (MAX_IDE_CONTROLLER/2); j++) {
+ HddInfo2 = HddInfo1+1;
+ if ((HddInfo1->Status &
+ (HDD_MASTER_ATAPI | HDD_SLAVE_ATAPI |
+ HDD_MASTER_IDE | HDD_SLAVE_IDE))||
+ (HddInfo2->Status &
+ (HDD_MASTER_ATAPI | HDD_SLAVE_ATAPI |
+ HDD_MASTER_IDE | HDD_SLAVE_IDE)))
+ {
+ Status = InstallIdePciHandler(HddInfo1, HddInfo2);
+ ASSERT_EFI_ERROR(Status);
+
+ //if (EFI_ERROR(Status)) return Status; //(EIP20813-)
+
+ //(EIP20813+)>
+
+ if( HddInfo1->HddIrq==0x07 || HddInfo2->HddIrq==0x07)
+ hdd_irq7_set=1;
+
+ if (EFI_ERROR(Status)) break;
+
+ //<(EIP20813+)
+ }
+ HddInfo1+=2;
+ }
+ //(EIP20813+)>
+ if(hdd_irq7_set)
+ SetINT0F_E0000();
+
+ //<(EIP20813+)
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: CreateDriveString
+//
+// DESCRIPTION: This function prepares the description string for the ATA/ATAPI
+// drive and places its pointer in the BBS entry.
+//
+// PARAMETERS: IdentifyDriveData - IDENTIFY_DRIVE data for this device
+// DriveDisplayName - pointer to the string to be updated
+// BbsDescStringOffset - pointer to the string description offset
+// in the corresponding BBS entry
+//
+// NOTE: 1) DriveDisplayName must be located below 1MB
+// 2) BbsDescStringSegment is UINT16 followed by BbsDescStringOffset
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+CreateDriveString (
+ IN UINT16 *IdentifyDriveData,
+ IN UINT16 ChannelInfo,
+ OUT DRIVE_DISPLAY_NAME *DriveDisplayName,
+ OUT UINT16 *BbsDescStringOffset,
+ UINTN DeviceAddress
+)
+{
+#if CSM_CREATES_ATA_ATAPI_STRINGS
+ UINT8 i, data8;
+ UINT16 data16 = IdentifyDriveData[76];
+ UINT8 s[MAX_DRIVE_NAME] = {0};
+ // Temp variable introduced in order to reduce the Code length
+ UINTN Temp = 0;
+
+ if(gIdeController > 1) {
+ pBS->CopyMem(&s[0], "xC::APAT :",14); // "PATA: "
+ Temp = 4;
+
+ /// find and replace the Controller Number in String
+ for(i=0;i<gIdeController;i++) {
+ if(IdeControllerInfo[i].BusDevFun == DeviceAddress) {
+ //// Controller for the AHCI Device found
+ s[0] = IdeControllerInfo[i].ControllerNo + 0x30;
+ break;
+ }
+ }
+ }
+ else {
+ pBS->CopyMem(&s[0], "APAT :",10); // "PATA: "
+ }
+
+ // Check Word76 for BIT1 and BIT2; set for SATA drives
+ if ((data16 != 0xFFFF) && (data16 & 6)) {
+ s[1 + Temp] = 'S';
+ }
+
+ if(ChannelInfo & HDD_PRIMARY) {
+ s[7 + Temp]='P';
+ if(ChannelInfo & (HDD_MASTER_IDE | HDD_MASTER_ATAPI )) {
+ s[6 + Temp]='M';
+ } else {
+ s[6 + Temp]='S';
+ }
+ } else if(ChannelInfo & HDD_SECONDARY) {
+ s[7 + Temp]='S';
+ if(ChannelInfo & (HDD_MASTER_IDE | HDD_MASTER_ATAPI )) {
+ s[6 + Temp]='M';
+ } else {
+ s[6 + Temp]='S';
+ }
+ }
+
+ // Get the drive name out of IdentifyDrive data word 27..46 (upto 40 chars)
+ pBS->CopyMem(&s[10 + Temp], IdentifyDriveData+27, MAX_DRIVE_NAME- (11+Temp) );
+ // Swap the bytes
+ for (i=0; i<MAX_DRIVE_NAME; i+=2) {
+ data8=s[i];
+ s[i]=s[i+1];
+ s[i+1]=data8;
+ }
+
+ pBS->CopyMem(DriveDisplayName, s, MAX_DRIVE_NAME);
+ // Update string pointer in BBS after converting it to SEG:OFS format
+ *BbsDescStringOffset = (UINT16)(UINTN)DriveDisplayName;
+ *(BbsDescStringOffset+1) = (UINT16)(((UINTN)DriveDisplayName >> 4) & 0xF000);
+#endif
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: GetAtapiDeviceType
+//
+// DESCRIPTION: This function returns ATAPI device type depending on the information
+// provided by IDENDIFY_DRIVE data. It could call CSM platform functions
+// to return platform specific ATAPI device type or if the type is
+// selectable in System Setup.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+GetAtapiDeviceType(
+ IN ATAPI_IDENTIFY *IdentifyDriveData
+)
+{
+ UINT16 DevType;
+ EFI_STATUS Status;
+ CSM_PLATFORM_PROTOCOL *CsmPlatformProtocol;
+
+ pBS->LocateProtocol(&gCsmPlatformProtocolGuid, NULL, &CsmPlatformProtocol);
+ //
+ // LocateProtocol will return CsmPlatformProtocol = NULL if protocol is not found.
+ //
+ if (CsmPlatformProtocol) {
+ Status = CsmPlatformProtocol->GetAtapiDeviceType(CsmPlatformProtocol, IdentifyDriveData, &DevType);
+ if (!EFI_ERROR(Status)) return DevType; // Identified
+ }
+ //
+ // Use default, "generic" method of device identification
+ //
+ DevType = BBS_FLOPPY;
+
+ if ((IdentifyDriveData->Raw[0] & 0x1F00) == 0x500)
+ {
+ DevType = BBS_CDROM;
+ }
+ return DevType;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetDriveHandle
+//
+// Description:
+// This function searches for the IDE mass storage device handle in the list
+// of handles and returns the one that matches with the given IdentifyDrive
+// information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_HANDLE GetDriveHandle(ATAPI_IDENTIFY *IdentifyPtr)
+{
+ UINT8 i;
+ for (i=0; i<MAX_IDE_CONTROLLER*2; i++){
+ if (DriveHandle[i].IdentifyPtr == IdentifyPtr)
+ return DriveHandle[i].DriveHandle;
+ }
+
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: InstallLegacyMassStorageDevices
+//
+// DESCRIPTION: This function prepares BBS table, inserts FDD/IDE/SATA entries
+// in the table and calls CSM16->UpdateBbs function to bring up
+// non-BBS compliant entries as well.
+//
+// NOTE: This function should be executed only once, when DiskInfo handles
+// are ready.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InstallLegacyMassStorageDevices()
+{
+ HDD_INFO *AtaAtapiInfo;
+ UINT8 IdeCtl, Indx;
+ EFI_STATUS Status;
+ UINT8 count = 0;
+ EFI_HANDLE *DiskInfoHandles = 0;
+
+ BBS_TABLE *BbsEntry = CoreBiosInfo->BbsTable;
+
+ //
+ // Insert ATA/ATAPI devices into CoreBiosInfo->Thunk->Csm16BootTable.HddInfo
+ //
+ for (Indx = 0; Indx < MAX_IDE_PCI_CONTROLLER; Indx++) aInstalledPciIrq[Indx] = 0;
+ AtaAtapiInfo = CoreBiosInfo->Thunk->Csm16BootTable.HddInfo;
+
+ Status = GetAtaAtapiInfo(&DiskInfoHandles, AtaAtapiInfo);
+
+ if (!EFI_ERROR(Status)) { // some IDE device are connected
+ InstallIdeInterrupts(AtaAtapiInfo);
+ //
+ // Update BBS table with controller/device information
+ //
+ for (IdeCtl = 0; IdeCtl < MAX_IDE_CONTROLLER; IdeCtl++) {
+ if (!(AtaAtapiInfo[IdeCtl].Status &
+ ( HDD_MASTER_ATAPI | HDD_SLAVE_ATAPI | HDD_MASTER_IDE | HDD_SLAVE_IDE ))) {
+ continue;
+ }
+ Indx = IdeCtl*2 + 1; // 1st entry is taken for floppy
+
+ BbsEntry[Indx].Bus = BbsEntry[Indx+1].Bus = AtaAtapiInfo[IdeCtl].Bus;
+ BbsEntry[Indx].Device = BbsEntry[Indx+1].Device = AtaAtapiInfo[IdeCtl].Device;
+ BbsEntry[Indx].Function = BbsEntry[Indx+1].Function = AtaAtapiInfo[IdeCtl].Function;
+ BbsEntry[Indx].Class = BbsEntry[Indx+1].Class = 1;
+ BbsEntry[Indx].SubClass = BbsEntry[Indx+1].SubClass = 1;
+
+ if (AtaAtapiInfo[IdeCtl].CommandBaseAddress) { // real controller
+ //
+ // Create entry for master device connected to this controller
+ //
+ if (AtaAtapiInfo[IdeCtl].Status & (HDD_MASTER_IDE | HDD_MASTER_ATAPI)) {
+ BbsEntry[Indx].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+ if (AtaAtapiInfo[IdeCtl].Status & HDD_MASTER_ATAPI) {
+ BbsEntry[Indx].DeviceType = GetAtapiDeviceType(&AtaAtapiInfo[IdeCtl].IdentifyDrive[0]);
+ } else {
+ BbsEntry[Indx].DeviceType = BBS_HARDDISK;
+ }
+ CreateDriveString(
+ AtaAtapiInfo[IdeCtl].IdentifyDrive[0].Raw,
+ AtaAtapiInfo[IdeCtl].Status & ~(HDD_SLAVE_IDE | HDD_SLAVE_ATAPI),
+ &CoreBiosInfo->Thunk->DriveDisplayName[count++],
+ &BbsEntry[Indx].DescStringOffset,
+ ((UINT16)AtaAtapiInfo[IdeCtl].Bus << 8) +((UINT16)AtaAtapiInfo[IdeCtl].Device<<3)\
+ + ((UINT16) AtaAtapiInfo[IdeCtl].Function )
+ );
+ //TRACE((-1, "i=%d, bbsentry=%x, diskinfo=%x\n", Indx, &BbsEntry[Indx], *DiskInfoHandles));
+ *(UINTN*)(&BbsEntry[Indx].IBV1) = (UINTN)GetDriveHandle(AtaAtapiInfo[IdeCtl].IdentifyDrive);//(EIP71972)
+ }
+ //
+ // Create entry for slave device connected to this controller
+ //
+ if (AtaAtapiInfo[IdeCtl].Status & (HDD_SLAVE_IDE | HDD_SLAVE_ATAPI)) {
+ BbsEntry[Indx+1].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+ if (AtaAtapiInfo[IdeCtl].Status & HDD_SLAVE_ATAPI) {
+ BbsEntry[Indx+1].DeviceType = GetAtapiDeviceType(&AtaAtapiInfo[IdeCtl].IdentifyDrive[1]);
+ } else {
+ BbsEntry[Indx+1].DeviceType = BBS_HARDDISK;
+ }
+ CreateDriveString(
+ AtaAtapiInfo[IdeCtl].IdentifyDrive[1].Raw,
+ AtaAtapiInfo[IdeCtl].Status & ~(HDD_MASTER_IDE | HDD_MASTER_ATAPI),
+ &CoreBiosInfo->Thunk->DriveDisplayName[count++],
+ &BbsEntry[Indx+1].DescStringOffset,
+ ((UINT16)AtaAtapiInfo[IdeCtl].Bus << 8) +((UINT16)AtaAtapiInfo[IdeCtl].Device<<3)\
+ + ((UINT16) AtaAtapiInfo[IdeCtl].Function )
+ );
+ //TRACE((-1, "i=%d, bbsentry=%x, diskinfo=%x\n", Indx, &BbsEntry[Indx+1], *DiskInfoHandles));
+ *(UINTN*)(&BbsEntry[Indx+1].IBV1) = (UINTN)GetDriveHandle(&AtaAtapiInfo[IdeCtl].IdentifyDrive[1]);//(EIP71972)
+ }
+ }
+ }
+ }
+
+#ifdef AhciSrc_SUPPORT
+#if AhciSrc_SUPPORT
+{
+ EFI_AHCI_INT13_INIT_PROTOCOL *Aint13;
+
+ //
+ // Initialize legacy AHCI support
+ //
+ Status = pBS->LocateProtocol(&gAint13ProtocolGuid, NULL, &Aint13);
+ if (!EFI_ERROR(Status)) {
+ Aint13->InitAhciInt13Support();
+ }
+
+}
+#endif
+#endif
+
+ gIsMassStorageInstalled = TRUE;
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: GetSystemMemoryMap
+//
+// DESCRIPTION: This function returns system memory map and count of the memory
+// entries in the map.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetSystemMemoryMap(
+ OUT EFI_MEMORY_DESCRIPTOR **MemMap,
+ OUT UINTN *MemDescSize,
+ OUT UINTN *MemEntriesCount
+)
+{
+ EFI_STATUS Status;
+ UINTN MemMapSize, MemMapKey;
+ UINT32 MemDescVer;
+
+ if (MemMap == NULL || MemDescSize == NULL || MemEntriesCount == NULL)
+ {
+ ASSERT(FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *MemMap = NULL;
+ MemMapSize = 0; // GetMemoryMap will return the size needed for the map
+ Status = pBS->GetMemoryMap(&MemMapSize, *MemMap,
+ &MemMapKey, MemDescSize, &MemDescVer);
+
+ ASSERT(Status == EFI_BUFFER_TOO_SMALL);
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ *MemEntriesCount = 0;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // The following memory allocation may alter memory map.
+ // Let's add space for 5 more descriptors to be sure buffer is big enough
+ MemMapSize += 5 * *MemDescSize;
+ Status = pBS->AllocatePool(EfiBootServicesData, MemMapSize, MemMap);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->GetMemoryMap(&MemMapSize, *MemMap,
+ &MemMapKey, MemDescSize, &MemDescVer);
+ ASSERT_EFI_ERROR(Status);
+
+ *MemEntriesCount = (UINT16)(MemMapSize / *MemDescSize);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: GetExtendedMemSize
+//
+// DESCRIPTION: This function looks through the system memory map, finds the
+// available memory regions and returns the size in bytes of the
+// system memory above 1 MB.
+// NOTE: If there is more than 4 GB of memory installed, then function
+// will return 4GB-1MB.
+// If the amount of memory is 4GB or more, some memory is remapped
+// above 4GB by the chipset. In this case this function will return
+// the amount of memory before the remapped area.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID GetExtendedMemSize(UINT32* ExtMemSize)
+{
+ UINTN MemDescSize;
+ EFI_MEMORY_DESCRIPTOR *MemMap;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ UINTN count = 0;
+ UINTN MemEntriesCount;
+ UINT64 cs = 0x100000;
+
+ GetSystemMemoryMap(&MemMap, &MemDescSize, &MemEntriesCount);
+
+ for (mm = MemMap; count < MemEntriesCount; mm=(EFI_MEMORY_DESCRIPTOR*)((UINT8*)mm+MemDescSize), count++) {
+ if (mm->PhysicalStart < 0x100000) continue; // skip low memory entries
+
+ if (mm->Type == EfiReservedMemoryType ||
+ mm->Type == EfiMemoryMappedIO ||
+ mm->Type == EfiMemoryMappedIOPortSpace ||
+ mm->Type == EfiRuntimeServicesCode ||
+ mm->Type == EfiRuntimeServicesData ||
+ mm->Type == EfiUnusableMemory ||
+ mm->Type == EfiPalCode ||
+ mm->Type == EfiACPIReclaimMemory ||
+ mm->Type == EfiACPIMemoryNVS)
+ {
+ break;
+ }
+
+ cs = mm->PhysicalStart + Shl64(mm->NumberOfPages, EFI_PAGE_SHIFT);
+ }
+ pBS->FreePool(MemMap);
+
+ *ExtMemSize = (UINT32)cs - 0x100000;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: InsertE820Entry
+//
+// DESCRIPTION: This function fills in the E820 table entry and adjusts
+// the input entry pointer. If the new entry is the extension of
+// the previous one, then entry is "extended".
+// PARAMETERS: Pointer to E820 entry to be filled.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InsertE820Entry (
+ E820_ENTRY **Entry,
+ UINT64 Address,
+ UINT64 Size,
+ E820_MEMORY_TYPE Type,
+ UINT16 *Count)
+{
+ E820_ENTRY *E820Entry = *Entry;
+ E820_ENTRY *PrevE820Entry = E820Entry - 1;
+
+ if (((PrevE820Entry->Adr + PrevE820Entry->Len) == Address) &&
+ ((PrevE820Entry->Type == Type)
+#if AGGRESSIVELY_JOINED_E820_ENTRIES
+ || ((Type == MemRangeAvl) && (Address != 0x100000))
+#endif
+))
+ {
+ // extend the current entry without touching Adr and Type
+ E820Entry = PrevE820Entry;
+ E820Entry->Len += Size;
+ } else { // new entry
+ E820Entry->Adr = Address;
+ E820Entry->Len = Size;
+ E820Entry->Type = Type;
+ (*Count)++;
+ }
+ E820Entry->ExtendedAttr = E820_EXTATTR_ADDRESS_RANGE_ENABLED;
+ *Entry = ++E820Entry;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: UpdateE820Map
+//
+// DESCRIPTION: This function retrieves the system memory map and converts it
+// into E820 map format.
+// PARAMETERS: Pointer to the 1st E820 entry in BIOS_INFO data structure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+UpdateE820Map(E820_ENTRY *e820_entry)
+{
+ UINT16 Count = 0;
+ UINTN MemDescSize;
+ EFI_MEMORY_DESCRIPTOR *MemMap;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ UINTN MemEntriesCount;
+ UINTN i;
+ E820_ENTRY *E820Entry = e820_entry;
+ E820_MEMORY_TYPE MemType;
+ UINT32 EbdaAddress;
+ BDA_DATA *bda;
+
+ GetSystemMemoryMap(&MemMap, &MemDescSize, &MemEntriesCount);
+
+ bda = (BDA_DATA*)((UINTN) 0x400); // 40:0
+
+ EbdaAddress = (bda->ext_bios_data_seg)<<4; // 40:0e
+ //
+ // Start creating E820 table entries
+ //
+ InsertE820Entry(&E820Entry, 0, (640 - ((UINT8)((0xA0000 - EbdaAddress) >> 10)) )<< 10, MemRangeAvl, &Count);
+ InsertE820Entry(&E820Entry, (640 - ((UINT8)((0xA0000 - EbdaAddress) >> 10)) ) << 10, ((UINT8)((0xA0000 - EbdaAddress) >> 10)) << 10, MemRangeRes, &Count);
+ InsertE820Entry(&E820Entry, 0xE0000, 0x20000, MemRangeRes, &Count); // E0000..FFFFF
+ //
+ // Insert entries according to memory map; EFI memory types are mapped to ACPI address
+ // range types according to ACPI 3.0 Specification, Chapter 14.3.
+ //
+ for (mm = MemMap, i = 0; i < MemEntriesCount; i++, mm=(EFI_MEMORY_DESCRIPTOR*)((UINT8*)mm+MemDescSize)) {
+ if (mm->PhysicalStart < 0x100000) continue; // skip low memory entries
+ switch (mm->Type) {
+ case EfiMemoryMappedIO:
+ if (!(mm->Attribute & EFI_MEMORY_RUNTIME)) continue;
+ case EfiReservedMemoryType:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiUnusableMemory:
+ case EfiMemoryMappedIOPortSpace:
+ case EfiPalCode:
+ MemType = MemRangeRes;
+ break;
+ case EfiACPIReclaimMemory:
+ MemType = MemRangeAcpiReclaim;
+ break;
+ case EfiACPIMemoryNVS:
+ MemType = MemRangeAcpiNVS;
+ break;
+ default: MemType = MemRangeAvl;
+ }
+ InsertE820Entry(&E820Entry,
+ mm->PhysicalStart,
+ Shl64(mm->NumberOfPages, EFI_PAGE_SHIFT),
+ MemType,
+ &Count);
+ if (Count == MAX_E820_ENTRIES) break;
+ }
+ pBS->FreePool(MemMap);
+ return Count;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: CmosRW
+//
+// DESCRIPTION: CMOS access helper
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosRW(
+ BOOLEAN rw,
+ UINT32 reg,
+ UINT8 *data
+)
+{
+ UINT32 reg_;
+ UINT8 data_;
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRB;
+
+ Status = pBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &PciRB
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) return Status;
+
+ reg_ = reg;
+
+ PciRB->Io.Write (PciRB, EfiPciWidthUint8, 0x70, 1, &reg_); // Set index
+
+ if (rw) { // read
+ PciRB->Io.Read (PciRB, EfiPciWidthUint8, 0x71, 1, &data_);
+ *data = data_;
+ } else { // write
+ data_ = *data;
+ PciRB->Io.Write (PciRB, EfiPciWidthUint8, 0x71, 1, &data_);
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: UpdateCmos
+//
+// DESCRIPTION: This function updates CMOS before booting to Legacy OS
+//
+// NOTE: This function enables NMI
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateCmos()
+{
+// UINT8 reg;
+ UINT8 data;
+ //
+ // Clear bits 0..3 on the CMOS ofs 0xE
+ //
+ CmosRW(TRUE, 0xE, &data); // Read register E
+ data &= 0xF0;
+ CmosRW(FALSE, 0xE, &data);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: NmiToBeEnabled
+//
+// DESCRIPTION: This function returns the current selection of NMI to be
+// enabled/disabled.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN NmiToBeEnabled()
+{
+ return TRUE; // TODO::Currently hardcoded, could be setup driven
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: EnableDisableNmi
+//
+// DESCRIPTION: This function enables or disables NMI according to setup
+// question.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EnableDisableNmi()
+{
+ UINT16 data16;
+ UINT8 data8;
+ EFI_STATUS Status;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRB;
+
+ Status = pBS->LocateProtocol (&gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &PciRB
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) return Status;
+
+ //
+ // Update IO reg 61h - NMI_SC-NMI Status and Control Register
+ //
+ PciRB->Io.Read (PciRB, EfiPciWidthUint8, 0x61, 1, &data8);
+ data8 &= 0xF3;
+ data16 = NmiToBeEnabled()? 0xD : 0xC8D;
+ data8 |= (data16 >> 8);
+ PciRB->Io.Write (PciRB, EfiPciWidthUint8, 0x61, 1, &data8);
+ //
+ // Update IO reg 70h - NMI_EN-NMI Enable(and Real Time Clock Index)
+ //
+ data8 = (UINT8)data16;
+ PciRB->Io.Write (PciRB, EfiPciWidthUint8, 0x70, 1, &data8);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//------------------------------------------------------------------------------------
+//
+// Name: UpdatePciLastBusCallback
+//
+// Description: This callback function then will process the list of root bridges
+// and will update the LastPciBus field of EFI_COMPATIBILITY16_TABLE
+// accordingly.
+//
+//------------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UpdatePciLastBusCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RBProtocol;
+ ASLR_QWORD_ASD *Descriptors;
+ UINTN Count=0,i=0;
+ EFI_HANDLE *Buffer;
+ UINT8 MaxBus=0;
+ EFI_STATUS Status;
+
+ LEGACY16_TO_EFI_DATA_TABLE_EXT *Csm16Data;
+ UINT8 *NextRootBridgeBus;
+ UINT8 CsmRbCount = 0;
+ BOOLEAN Csm16Is75Plus;
+ //
+ // UnLock E000 and F000 segments
+ //
+ Status = CoreBiosInfo->iRegion->UnLock (
+ CoreBiosInfo->iRegion,
+ (UINT32)0xe0000,
+ (UINT32)0x20000,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ //Locate the RootBridge protocol
+ //
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &Count,
+ &Buffer
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ Csm16Is75Plus = *(UINT8*)0xf0019 > 0x75; // CSM version 76 or later
+
+ if (Csm16Is75Plus) {
+ Csm16Data = (LEGACY16_TO_EFI_DATA_TABLE_EXT*)(UINTN)(0xf0000 + *(UINT16*)0xfff4c);
+ NextRootBridgeBus = (UINT8*)((UINTN)Csm16Data->RbMinBusArrayOfs + 0xf0000);
+ }
+
+ for (i = 0; i < Count; i++) {
+ Status = pBS->HandleProtocol (
+ Buffer[i],
+ &gEfiPciRootBridgeIoProtocolGuid,
+ &RBProtocol
+ );
+
+ if (EFI_ERROR(Status)) continue;
+ //
+ // Get the Configuration
+ //
+ RBProtocol->Configuration(
+ RBProtocol,
+ &Descriptors
+ );
+
+ if ((Descriptors)->Hdr.HDR != ASLV_END_TAG_HDR) {
+ //
+ // go till we get the Resource type = Bus Number range
+ //
+ while (Descriptors->Hdr.HDR != ASLV_END_TAG_HDR) {
+
+ if (Descriptors->Type == ASLRV_SPC_TYPE_BUS) {
+ //
+ // We got the type;update the LastPCiBus of csm16header
+ //
+ if (Csm16Is75Plus) {
+ if (++CsmRbCount < Csm16Data->RbArrayCount) {
+ *NextRootBridgeBus++ = (UINT8)Descriptors->_MIN;
+ }
+ }
+ if((UINT8)Descriptors->_MAX > MaxBus ) {
+ MaxBus =(UINT8)Descriptors->_MAX;
+ }
+ }
+ Descriptors++;
+ }
+ }
+ }
+
+ // Update Pci Last Bus in Csm16 header
+ // Note: do not report FF; this is XP limitation, EIP#24852
+ CoreBiosInfo->Csm16Header->LastPciBus = (MaxBus == 0xff)? 0xfe : MaxBus;
+
+ // Update CSM16 header checksum as LastPciBus field of it has been changed
+ ChecksumCSM16Header(CoreBiosInfo->Csm16Header);
+
+ // Look for _32_ structure and update offset 16 (0x10) with the MaxBus
+ {
+ UINTN Adr = 0xe0000;
+
+ TRACE((-1,"CSM - Attempting to update RT32 binary with the MaxBus (0x%x)\n", MaxBus));
+
+ for (; Adr < 0x100000; Adr += 0x10) {
+ if (*(UINT32*)Adr == 0x5f32335f) {
+ // found '_32_', verify checksum
+ UINT8 i;
+ UINT8 CheckSum = 0;
+ TRACE((-1,"_32_ signature is found at %x,", Adr));
+ for (i=0; i<0x10; i++) {
+ CheckSum += *((UINT8*)Adr+i);
+ }
+ if (CheckSum == 0) {
+ TRACE((-1,"checksum is OK\n"));
+ *((UINT8*)Adr+0x10) = MaxBus;
+ }
+ else {
+ TRACE((-1,"checksum is invalid.\n"));
+ }
+ }
+ }
+ }
+
+ //
+ // Lock E000 and F000 segments
+ //
+ Status = CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ (UINT32)0xe0000,
+ (UINT32)0x20000,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ // Close event, this function is to be executed once.
+ if (Event != NULL) {
+ pBS->CloseEvent(Event);
+ }
+}
+
+/**
+ * Goes through memory map looking for the requested memory block within 1MB..2GB range
+ *
+ * @param[in] MemDesc Starting memory descriptor of the memory map
+ * @param[in] MemEntriesCount Count of the memory map entries
+ * @param[in] MemDescSize Size of the memory descriptor
+ * @param[in] DesiredBlockSize Number of pages requested to be found
+ * @param[out] MemAddress Found memory block
+ * @param[out] NumberOfPages Found memory block size
+ * @retval EFI_SUCCESS Memory block is found
+ * @retval EFI_NOT_FOUND Memory block is not found
+ */
+EFI_STATUS FindMemoryBlockForHiPmm(
+ EFI_MEMORY_DESCRIPTOR *MemMap,
+ UINTN MemEntriesCount,
+ UINTN MemDescSize,
+ UINTN DesiredBlockSize,
+ EFI_PHYSICAL_ADDRESS *MemAddress,
+ UINT64 *NumberOfPages
+)
+{
+ EFI_MEMORY_DESCRIPTOR *mm;
+ UINTN count = 0;
+
+ for (mm = MemMap; count < MemEntriesCount; mm=(EFI_MEMORY_DESCRIPTOR*)((UINT8*)mm+MemDescSize), count++) {
+ if (mm->PhysicalStart < 0x100000) continue; // skip low memory entries
+ // Skip above 2GB memory entries:
+ // CORE0292.1 - value above 2GB will be assumed a negative number in find_free_memory algorithm
+ if (mm->PhysicalStart > 0x7fffffff) continue;
+
+ if (mm->Type == EfiConventionalMemory && (mm->NumberOfPages >= DesiredBlockSize))
+ {
+ *MemAddress = mm->PhysicalStart;
+ *NumberOfPages = mm->NumberOfPages;
+ break;
+ }
+ }
+
+ return (count == MemEntriesCount)? EFI_NOT_FOUND : EFI_SUCCESS;
+}
+
+/**
+ Allocates the memory at 1MB..2GB that can be used for high memory PMM allocations.
+
+ This EfiBootServicesData memory block should be outside the "main" BS memory
+ so that it can be freed during READY_TO_BOOT. For that we go through EFI memory
+ map looking for unallocated region of a given size.
+
+ @param[in] BlockSize The number of pages to be allocated.
+ @param[out] BlockAddr The address of the allocated block.
+
+ @retval EFI_SUCCESS Memory block is allocated.
+ @retval Error Value Memory can not be allocated.
+
+*/
+EFI_STATUS AllocateHiMemPmmBlock(
+ IN UINTN BlockSize,
+ OUT UINTN *BlockAddr
+)
+{
+ UINTN MemDescSize;
+ EFI_MEMORY_DESCRIPTOR *MemMap;
+ EFI_MEMORY_DESCRIPTOR *mm;
+ UINTN count = 0;
+ UINTN MemEntriesCount;
+ EFI_PHYSICAL_ADDRESS HiPmmMemory;
+ EFI_STATUS Status;
+ UINT64 NumberOfPages;
+
+ GetSystemMemoryMap(&MemMap, &MemDescSize, &MemEntriesCount);
+
+ // print memory map
+ for (mm = MemMap; count < MemEntriesCount; mm=(EFI_MEMORY_DESCRIPTOR*)((UINT8*)mm+MemDescSize), count++) {
+ TRACE((-1, "%02d: %08x, %05x, ", count, mm->PhysicalStart, mm->NumberOfPages));
+ switch (mm->Type) {
+ case EfiReservedMemoryType: TRACE((-1, "EfiReservedMemoryType\n")); break;
+ case EfiLoaderCode: TRACE((-1, "EfiLoaderCode\n")); break;
+ case EfiLoaderData: TRACE((-1, "EfiLoaderData\n")); break;
+ case EfiBootServicesCode: TRACE((-1, "EfiBootServicesCode\n")); break;
+ case EfiBootServicesData: TRACE((-1, "EfiBootServicesData\n")); break;
+ case EfiRuntimeServicesCode: TRACE((-1, "EfiRuntimeServicesCode\n")); break;
+ case EfiRuntimeServicesData: TRACE((-1, "EfiRuntimeServicesData\n")); break;
+ case EfiConventionalMemory: TRACE((-1, "EfiConventionalMemory\n")); break;
+ case EfiUnusableMemory: TRACE((-1, "EfiUnusableMemory\n")); break;
+ case EfiACPIReclaimMemory: TRACE((-1, "EfiACPIReclaimMemory\n")); break;
+ case EfiACPIMemoryNVS: TRACE((-1, "EfiACPIMemoryNVS\n")); break;
+ case EfiMemoryMappedIO: TRACE((-1, "EfiMemoryMappedIO\n")); break;
+ case EfiMemoryMappedIOPortSpace: TRACE((-1, "EfiMemoryMappedIOPortSpace\n")); break;
+ case EfiPalCode: TRACE((-1, "EfiPalCode\n")); break;
+ default: TRACE((-1, "%x\n", mm->Type));
+ }
+ }
+
+ // Try to allocate Size*4 block and use the middle of it; if not found, then try to allocate Size*2
+ // and use the end
+ Status = FindMemoryBlockForHiPmm(MemMap, MemEntriesCount, MemDescSize, BlockSize*4, &HiPmmMemory, &NumberOfPages);
+ if (!EFI_ERROR(Status)) {
+ HiPmmMemory += Shl64(NumberOfPages, 11); // Middle of the block
+ } else {
+ Status = FindMemoryBlockForHiPmm(MemMap, MemEntriesCount, MemDescSize, BlockSize*2, &HiPmmMemory, &NumberOfPages);
+ HiPmmMemory += Shl64(NumberOfPages, 12); // End of the block
+ }
+ ASSERT_EFI_ERROR(Status);
+
+
+ pBS->FreePool(MemMap);
+
+
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData, BlockSize*2, &HiPmmMemory);
+ *BlockAddr = (UINTN)HiPmmMemory;
+
+ return Status;
+}
+
+// TODO: The following definition is from DebugLib.h; currently it can not be included
+// as it clashes with AmiDxeLib.h definitions
+#define DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED 0x08
+BOOLEAN
+ClearMemoryEnabled (
+ VOID
+ )
+{
+ // In AptioV this feature is controlled by DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED bit of PcdDebugPropertyMask
+ // In Aptio4 this is project specific. By default we will return TRUE
+ return TRUE;
+}
+
+/**
+ READY_TO_BOOT notification callback that frees high memory PMM allocations.
+
+ Hi memory PMM is a double buffer. First half is a real PMM memory, second half is
+ a backup. Before freeing make a backup copy, then free the first block, then restore
+ memory, then free the backup block. This is done to prevent clearing memory while
+ executing FreePages.
+ Note: double buffering is only needed when DEBUG_PROPERTY_CLEAR_MEMORY_ENABLED is
+ set in PcdDebugPropertyMask.
+*/
+VOID FreePmmBeforeBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ UINTN NumberOfPages = (CoreBiosInfo->Thunk->Csm16InitTable.HiPmmMemorySizeInBytes >> 12) + 1;
+ UINTN Size = NumberOfPages << 12;
+ UINTN Address = CoreBiosInfo->Thunk->Csm16InitTable.HiPmmMemory;
+
+ if (ClearMemoryEnabled ())
+ {
+ pBS->CopyMem((VOID*)(Address+Size), (VOID*)Address, Size);
+ Status = pBS->FreePages(Address, NumberOfPages);
+ ASSERT_EFI_ERROR(Status);
+ pBS->CopyMem((VOID*)Address, (VOID*)(Address+Size), Size);
+ Status = pBS->FreePages(Address+Size, NumberOfPages);
+ ASSERT_EFI_ERROR(Status);
+ }
+ else
+ {
+ Status = pBS->FreePages(Address, NumberOfPages*2);
+ ASSERT_EFI_ERROR(Status);
+ }
+ pBS->CloseEvent(Event);
+
+ TRACE((-1, "Free HI PMM memory: %r\n", Status));
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CsmLib.c b/Core/EM/CSM/CsmLib.c
new file mode 100644
index 0000000..d0605ae
--- /dev/null
+++ b/Core/EM/CSM/CsmLib.c
@@ -0,0 +1,1617 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmLib.c 69 1/10/14 12:21p Olegi $
+//
+// $Revision: 69 $
+//
+// $Date: 1/10/14 12:21p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmLib.c $
+//
+// 69 1/10/14 12:21p Olegi
+// EIP149769: LegacyToEfi boot management
+// Changed default setting, added new token to extend the functionality
+//
+// 68 10/31/13 9:45a Olegi
+// Typo in Csm16ResetFeature case.
+//
+// 67 10/18/13 12:38p Olegi
+// EIP139866
+// Create interface to manage LegacyToEfi CSM feature
+//
+// 66 10/07/13 10:21a Olegi
+// [TAG] EIP138427
+// [Category] New Feature
+// [Description] Create interface to let OEM customers change CSM16
+// variables
+// [Files] csm.c, csm.h, csmlib.c, legacybiosext.h
+//
+// 65 5/17/13 10:28a Olegi
+// [TAG] EIP123915
+// [Category] Improvement
+// [Description] BBS table update in CSM should be atomic operation
+// (extra reentrance guards added)
+//
+// 64 5/15/13 3:32p Olegi
+// [TAG] EIP123915
+// [Category] Improvement
+// [Description] BBS table update in CSM should be atomic operation
+// [Files] CsmOpROM.c
+// CsmLib.c
+//
+// 63 4/09/13 9:25a Olegi
+// [TAG] EIP118727
+// [Category] New Feature
+// [Description] Onboard PCI Option ROM loading is moved outside CSM
+// [Files] CSM.mak
+// CSM.dxs
+// CSM.c
+// PciInterrupts.c
+// CsmBsp.c
+// CsmLib.c
+//
+// 62 11/06/12 10:02a Olegi
+// [TAG] EIP105801
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] CSM: FindEmbeddedRom improperly calls Check30ROM
+// [RootCause] Check30ROM updates Size parameter with the runtime size
+// of the ROM. FindEmbeddedRom passes the Init size, so after calling
+// Check30ROM init size value is lost
+// [Solution] Use dummy size variable to pass to Check30ROM
+// [Files] CsmLib.c
+//
+// 61 12/23/11 3:09p Olegi
+// [TAG] EIP78921
+// [Category] Improvement
+// [Description] CsmBlockIo should create device handle in BBS table
+// [Files] CSM.h
+// CSM.c
+// CsmLib.c
+//
+// 60 11/11/11 1:00p Olegi
+// [TAG] EIP71556
+// [Category] Improvement
+// [Description] Support for 6 IDE Controllers
+// [Files] CSM.h
+// CsmLib.c
+//
+// 59 10/12/11 3:16p Olegi
+//
+// 58 8/10/11 4:26p Olegi
+// [TAG] EIP65882
+// [Category] Improvement
+// [Description] Added checking for OPROM_MULTIPLE_MODULEID in
+// FindEmbeddedRom, PCI3.0 Option ROM section.
+// [Files] CsmLib.c
+//
+// 57 8/03/11 4:27p Olegi
+// [TAG] EIP61035, EIP65224
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] When AMIDebugger is using COM port, system halts in
+// DisconnectSerialIO().
+// [RootCause] DisconnectSerialIO() Function present in CsmLib.c
+// disconnects all SerialIO controllers including the AMI Debugger's
+// DebugPort driver.
+// [Solution] Before disconnecting SerialIo validate the controller by
+// checking if device path protocol is installed on it.
+// [Files] csmlib.c
+//
+// 56 5/05/11 10:18a Olegi
+// [TAG] EIP59628
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] BDA is not initialized correctly, reporting the maximum of
+// 2 comports in the system with 4 comports.
+// [RootCause] aPnP table did not have entries for COM3 and COM4
+// [Solution] added COM3/COM4 entries in the aPnP table.
+// [Files] csmlib.c
+//
+// 55 1/31/11 4:31p Olegi
+// [TAG] EIP50327
+// [Category] Improvement
+//
+// 54 1/18/11 11:30a Olegi
+// [TAG] EIP52322
+// [Category] Improvement
+// [Description] Projects with two or more PCI 3.0 embedded ROMs: if
+// ROM's Device List all support one device, only one option ROM would be
+// invoked.
+// [Files] Changed the search method of FindEmbeddedRom()
+//
+// 53 12/22/10 9:07a Olegi
+// Added code to clear BBS entry before setting the BBS_IGNORE priority in
+// RemoveBbsEntryAt function.
+//
+// 52 12/03/10 12:43p Olegi
+// [TAG] EIP48471
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] COM Port addresses are not filled in correctly in BDA when
+// COM 0(First COM port) disabled in setup.
+// [RootCause] For the COM port resource details in BDA, we should not
+// depend on the UID of the Com port.
+// [Solution] 1) Get the 1st COM port details and fill the details in
+// CSm16bootable , BDA 40:0 and increment Serial Port count in 40:0x10.
+// 2) Get the 2nd Com port details and fill the details in CSm16bootable ,
+// BDA 40:2 and increment Serial Port count in 40:0x10..Continue this for
+// 4 com ports.
+// [Files] CsmHwInfo.c
+// CsmLib.c
+//
+// 51 10/07/10 9:07a Olegi
+// EIP44674: Reverted changes in GetComResource function.
+//
+// 50 10/06/10 4:42p Olegi
+// Finalized changes related to EIP35156.
+//
+// 49 10/01/10 4:43p Oleksiyy
+// Issue Number: 39752
+//
+// Category: Improvement
+//
+// Description: functuanality to hide Com1 from legacy OS if we are using
+// Trace in Runtime is added.
+//
+// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c,
+// CsmLib.c, AmiDxeLib.h and StatusCode eModule.
+//
+// 48 10/01/10 4:30p Olegi
+// A call GetPlatformEmbeddedRom is replaced with the ELINK; this serves
+// the purpose of OEM function portability. EIP35156.
+//
+// 47 9/20/10 1:04p Olegi
+// EIP42722: Corrected GetComResource function.
+//
+// 46 9/01/10 10:37a Olegi
+// EIP42523: Added VendorId checking for PCI3.0 Option ROMs.
+// Background: CSM would check Device List to find the correct ROM image
+// if option ROM is PCI 3.0. But there was a lack of VendorID checking in
+// the search rule, this may cause FindEmbeddedRom return incorrect ROM
+// image.
+//
+// 45 8/30/10 4:56p Olegi
+// Added EFI_NOT_FOUND output to RemoveBbsEntryAt function.
+//
+// 44 7/16/10 12:08p Olegi
+// ConnectSerialIO/DisconnectSerialIO functions moved here from CSM.C.
+//
+// 43 7/08/10 11:31a Olegi
+// Added SignalAmiLegacyBootEvent function. EIP39089
+//
+// 42 5/21/10 2:29p Olegi
+// Modification in GetComPortResource: removed unneeded typecasting to
+// SIO_DEV.
+//
+// 41 1/28/10 9:27a Olegi
+// Bugfix in GetComPortResource::EIP33931.
+//
+// 40 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 39 12/28/09 8:49a Olegi
+// Modification in LockShadow, remove decoding of the unused shadow area.
+// EIP#29087
+//
+// 38 12/28/09 7:46a Olegi
+// Added GetLptResource function.
+//
+// 37 8/05/09 5:56p Olegi
+// FindEmbeddedRom() is modified to implement the feature of PCI3.0 OpROM
+// that handles multiple devices. EIP#24327
+//
+// 36 4/02/09 2:12p Olegi
+// Added GetComPortResource function.
+//
+// 35 12/22/08 5:27p Olegi
+// Added GetPlatformEmbeddedRom function. This allows different packing of
+// the OpROM, can be used to pack it as FFS file.
+//
+// 34 10/22/08 6:22p Robert
+// In UnlockShadow, moved the assignment of LockUnlockAddr and
+// LockUnlockSize outside the if (size) scope to cover the case where size
+// = 0
+//
+// 33 10/10/08 11:56a Olegi
+//
+// 32 10/10/08 11:54a Olegi
+// UnlockShadow: calculation of size adjustment is changed.
+//
+// 31 9/23/08 2:18p Olegi
+//
+// 30 6/30/08 3:53p Olegi
+// Added AddBbsEntryAt and RemoveBbsEntryAt functions.
+//
+// 29 6/10/08 11:05a Olegi
+// Bugfix in RemoveDecodingForShadow, the size of the region was not
+// calculated correctly.
+//
+// 28 5/19/08 12:37p Olegi
+// Removed EBDA size limitation.
+//
+// 27 5/08/08 6:03p Olegi
+// Modified FindEmbeddedRom routine to support multiple DID for one OpROM
+// for PCI onboard devices
+//
+// 26 4/14/08 2:46p Rameshraju
+// Removed the decoding for the remaining Shadow region
+//
+// 25 1/31/08 11:53a Olegi
+// AllocateEbda definition changed.
+//
+// 24 1/16/08 2:17p Olegi
+// Modified AllocateEbda function.
+//
+// 23 12/04/07 11:07a Olegi
+//
+// 22 10/08/07 5:24p Olegi
+// Bugfix in AllocateEbda() - after allocation all EBDA pointers
+// associated with already executed OpROMs must be updated.
+//
+// 21 10/02/07 10:42a Olegi
+// Modified IsSioDevicePluggedIn() function.
+//
+// 1 7/08/07 5:19p Fasihm
+//
+// 19 4/27/07 5:13p Olegi
+// CSM.CHM file preparation.
+//
+// 18 4/20/07 4:41p Olegi
+// AllocateEbda function is modified so that it properly updates 40:13
+//
+// 17 12/13/06 11:09a Olegi
+// AllocateEbda function introduction (not tested).
+//
+// 16 8/29/06 5:48p Olegi
+//
+// 15 8/28/06 11:11a Olegi
+// IsConnected[] array data is corrected.
+//
+// 14 8/24/06 6:57p Felixp
+//
+// 13 8/24/06 6:49p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 12 8/16/06 2:38p Olegi
+// Previous typecast changes undone.
+//
+// 11 8/11/06 4:54p Olegi
+//
+// 10 5/19/06 11:22p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 9 3/13/06 2:33p Felixp
+//
+// 8 11/23/05 11:22a Felixp
+// dev_status renamed to DEV_STATUS.
+//
+// 7 11/23/05 9:40a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmLib.c
+//
+// Description: Functions and variables used in different CSM modules
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "csm.h"
+#include "AmiDxeLib.h"
+#include "AcpiRes.h"
+#include <Protocol\AmiSio.h>
+#include <Protocol\SimplePointer.h>
+#include <Protocol\BlockIo.h>
+#include "token.h"
+#include "pci.h"
+#include <Protocol/SerialIo.h>
+#include <Protocol/AmiBoardInfo.h>
+
+extern BIOS_INFO *CoreBiosInfo;
+extern UINTN gMaxOpRomAddress;
+
+VOID *EmbeddedRom;
+UINTN EmbeddedRomSize;
+
+VOID UpdateEbdaMap(UINT32);
+
+extern AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfo;
+extern BOOLEAN gBbsUpdateInProgress;
+
+BOOLEAN
+Check30ROM(
+ IN VOID *RomLocation,
+ IN OUT UINTN *Size,
+ IN EFI_HANDLE PciHandle
+);
+
+static UINT16 aPnP[16] = {
+ 0x0501, // 0 - UART1
+ 0x0501, // 1 - UART2
+ 0x0400, // 2 - LPT1
+ 0x0604, // 3 - FDC
+ 0, 0, 0, 0, 0, 0,
+ 0x0303, // A - KBC
+ 0, // B - EC
+ 0x0501, //C - UART3
+ 0x0501, // D - UART4
+ 0x0F03, // E - PS/2 Mouse
+ 0 // F - Reserved
+};
+
+typedef EFI_STATUS (*IsConnectedFunc)(EFI_HANDLE);
+
+EFI_STATUS IsConnectedDummy(EFI_HANDLE);
+EFI_STATUS IsConnectedPS2MS(EFI_HANDLE);
+EFI_STATUS IsConnectedFloppy(EFI_HANDLE);
+
+static
+IsConnectedFunc IsConnected[] = {
+ IsConnectedDummy, // 0 - UART1
+ IsConnectedDummy, // 1 - UART2
+ IsConnectedDummy, // 2 - LPT1
+ IsConnectedFloppy, // 3 - FDC
+ IsConnectedDummy, // 4 - SB16
+ IsConnectedDummy, // 5 - MIDI
+ IsConnectedDummy, // 6 - MSS AUDIO
+ IsConnectedDummy, // 7 - FM Synthesizer
+ IsConnectedDummy, // 8 - Game Port1
+ IsConnectedDummy, // 9 - Game Port2
+ IsConnectedDummy, // A - KBC
+ IsConnectedDummy, // B - EC
+ IsConnectedDummy, // C - reserved
+ IsConnectedDummy, // D - reserved
+ IsConnectedPS2MS, // E - PS/2 Mouse
+ IsConnectedDummy // F - reserved
+};
+
+typedef struct _ACPI_PNPID {
+ UINT32 Signature :16;
+ UINT32 PnpID :16;
+} ACPI_PNPID;
+
+EFI_HANDLE *gSerialIoHandleBuffer=NULL;
+UINTN gSerialIoHandleCount=0;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FindEmbeddedRom
+//
+// Description: This function searches for ROM within the data previously loaded
+// from the main FV image and returns its pointer and size.
+//
+// Output: EFI_SUCCESS or EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+typedef EFI_STATUS (*CSM_GET_EMBEDDED_PCI_ROM) (
+ UINT16 VendorId, UINT16 DeviceId, VOID **ImageStart, UINTN *ImageSize);
+
+EFI_STATUS FindEmbeddedRom(
+ UINT16 ModuleId, UINT16 VendorId, UINT16 DeviceId,
+ VOID **ImageStart, UINTN *ImageSize
+)
+{
+ OPROM_HEADER *Header;
+ EFI_STATUS Status;
+ PARTIAL_OPROM_HEADER *PartialHeader = NULL;
+ UINT8 NumAdditionalDevicesWithSameOpRom = 0;
+ UINT32 SizeOfPartialHeaders = 0;
+ UINT32 i = 0;
+ PCI_DATA_STRUCTURE *pcir;
+ UINT16 *DeviceIDList;
+ CSM_GET_EMBEDDED_PCI_ROM GetEmbeddedPciRom = (CSM_GET_EMBEDDED_PCI_ROM)gAmiBoardInfo->BoardOemInfo;
+
+ Status = GetPlatformEmbeddedRom(ModuleId, VendorId, DeviceId, ImageStart, ImageSize);
+ if (!EFI_ERROR(Status)) return Status;
+
+ if ((ModuleId == OPROM_MODULEID) && (gAmiBoardInfo->BoardOemInfo != NULL))
+ {
+ GetEmbeddedPciRom = (CSM_GET_EMBEDDED_PCI_ROM)gAmiBoardInfo->BoardOemInfo;
+ Status = GetEmbeddedPciRom(
+ VendorId, DeviceId, ImageStart, ImageSize);
+ return Status;
+ }
+
+
+ for( Header = (OPROM_HEADER*)EmbeddedRom
+ ; (UINT8*)Header<(UINT8*)EmbeddedRom+EmbeddedRomSize
+ ; Header = (OPROM_HEADER*)((UINT8*)(Header+1)+
+ SizeOfPartialHeaders+
+ Header->Size)
+ )
+ {
+ if ( Header->ModuleId==ModuleId
+ && Header->VendorId==VendorId
+ && Header->DeviceId==DeviceId
+ )
+ {
+ *ImageStart = Header+1;
+ *ImageSize=Header->Size;
+ return EFI_SUCCESS;
+ }
+ else
+ {
+ // try LinkDid/LinkVid for OpROMs
+ //If there is more than 1 device using an option rom,
+ //the header of the first device has a module id with the follow format:
+ // 0xA0XX
+ //where the least significant byte is the additional number of devices using the option ROM.
+ // e.g. If there are 2 devices using the option rom, then the header of the
+ //first device has module id 0xA001.
+ //The first device device has a complete header, and the remaining devices have partial headers.
+ //A partial header is the complete header without the 'Size' field.
+ if ((Header->ModuleId & 0xFF00) == OPROM_MULTIPLE_MODULEID)
+ {
+ NumAdditionalDevicesWithSameOpRom = (UINT8) (Header->ModuleId & 0xFF);
+ SizeOfPartialHeaders = sizeof(PARTIAL_OPROM_HEADER) *
+ NumAdditionalDevicesWithSameOpRom;
+ //check the first header
+ //we do not check the module id
+ if ((Header->VendorId == VendorId) &&
+ (Header->DeviceId==DeviceId)) {
+ *ImageStart = (UINT8 *)(Header+1)+SizeOfPartialHeaders;
+ *ImageSize=Header->Size;
+ return EFI_SUCCESS;
+ }
+ //Check the partial headers of the remaining devices using this option rom.
+ //The first partial header directly follows the regular header.
+ PartialHeader = (PARTIAL_OPROM_HEADER *)(Header+1);
+ for (i = 0; i < NumAdditionalDevicesWithSameOpRom; i++) {
+ if ((PartialHeader->ModuleId == ModuleId) &&
+ (PartialHeader->VendorId == VendorId) &&
+ (PartialHeader->DeviceId == DeviceId)) {
+ *ImageStart = (UINT8 *)(Header+1)+SizeOfPartialHeaders;
+ *ImageSize=Header->Size;
+ return EFI_SUCCESS;
+ }
+ PartialHeader++;
+ }
+ } else {
+ SizeOfPartialHeaders = 0;
+ }
+ }
+ *ImageStart = 0;
+ *ImageSize = 0;
+ }
+
+ // Linked List failed. So check if it is a PCI 3.0 Option and has a valid Device List pointer
+ for( Header = (OPROM_HEADER*)EmbeddedRom
+ ; (UINT8*)Header<(UINT8*)EmbeddedRom+EmbeddedRomSize
+ ; Header = (OPROM_HEADER*)((UINT8*)(Header+1)+
+ SizeOfPartialHeaders+
+ Header->Size)
+ )
+ {
+ UINTN DummyImageSize;
+
+ if ((Header->ModuleId & 0xFF00) == OPROM_MULTIPLE_MODULEID)
+ {
+ NumAdditionalDevicesWithSameOpRom = (UINT8) (Header->ModuleId & 0xFF);
+ SizeOfPartialHeaders = sizeof(PARTIAL_OPROM_HEADER) * NumAdditionalDevicesWithSameOpRom;
+ PartialHeader = (PARTIAL_OPROM_HEADER *)(Header+1);
+ for (i = 0; i < NumAdditionalDevicesWithSameOpRom; i++) {
+ PartialHeader++;
+ }
+ } else {
+ SizeOfPartialHeaders = 0;
+ }
+
+ *ImageStart = (UINT8 *)(Header+1)+SizeOfPartialHeaders;
+ *ImageSize = Header->Size;
+ if (Check30ROM(*ImageStart, &DummyImageSize, NULL)){
+ // Check for valid Device List Pointer
+ pcir = (PCI_DATA_STRUCTURE *)((UINT8*)*ImageStart + *(UINT16*)((UINT8*)*ImageStart + 0x18));
+ if ((pcir->VendorId == VendorId) && (pcir->Reserved0)) { //(EIP42523)
+ DeviceIDList = (UINT16 *)((UINT8 *)pcir + pcir->Reserved0);
+ for (;*DeviceIDList; DeviceIDList++ ){
+ if (*DeviceIDList == DeviceId) {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ *ImageStart = 0;
+ *ImageSize = 0;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS IsConnectedDummy(EFI_HANDLE handle)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS IsConnectedPS2MS(EFI_HANDLE handle)
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_POINTER_PROTOCOL *spp;
+ EFI_SIMPLE_POINTER_STATE state;
+
+ Status = pBS->HandleProtocol(handle,&gEfiSimplePointerProtocolGuid,&spp);
+ if (!EFI_ERROR(Status)) {
+ Status = spp->GetState(spp, &state);
+ // ask A. to fix this if - should return DEVICE_ERROR, not NO_READY
+ //if (Status != EFI_DEVICE_ERROR) {
+ if (Status != EFI_NOT_READY) {
+ Status = EFI_SUCCESS;
+ }
+ }
+ return Status;
+}
+
+
+EFI_STATUS IsConnectedFloppy(EFI_HANDLE handle)
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *blkiop;
+
+ Status = pBS->HandleProtocol(handle,&gEfiBlockIoProtocolGuid,&blkiop);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Function: IsSioDevicePluggedIn
+//
+// Description: Returns connect status of certain SIO device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsSioDevicePluggedIn(
+ IN SIO_DEV_STATUS *dev_plugged_in,
+ OUT EFI_HANDLE *hDevice
+)
+{
+ EFI_STATUS Status;
+ UINT16 dev;
+ UINTN i,j,cnt;
+ ACPI_HID_DEVICE_PATH *siodp;
+ ACPI_PNPID *pnpid;
+ EFI_HANDLE *hbuff = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ BOOLEAN bIsConnected = FALSE;
+
+ dev = dev_plugged_in->DEV_STATUS;
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiAmiSioProtocolGuid, NULL, &cnt, &hbuff);
+// ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return FALSE;
+
+ //
+ // Find the device index. Note, that this function does not support multiple devices.
+ //
+ for (j=0; j<16; j++, dev>>=1) {
+ if (dev & 1) break;
+ }
+ if (j==16) {
+ pBS->FreePool(hbuff);
+ return FALSE;
+ }
+
+ for(i=0; i<cnt; i++){
+ Status=pBS->HandleProtocol(hbuff[i],&gEfiDevicePathProtocolGuid,&dp);
+ if(EFI_ERROR(Status)) continue;
+
+ siodp=DPGetLastNode(dp);
+ if(siodp->Header.Type!=ACPI_DEVICE_PATH
+ || siodp->Header.SubType!=ACPI_DP
+ || NODE_LENGTH(&siodp->Header) != ACPI_DEVICE_PATH_LENGTH) continue;
+
+ pnpid=(ACPI_PNPID*)&siodp->HID;
+ if (pnpid->PnpID == aPnP[j]) {
+ bIsConnected = (BOOLEAN) (IsConnected[j](hbuff[i]) == EFI_SUCCESS);
+ *hDevice = hbuff[i];
+ break;
+ }
+ }
+ pBS->FreePool(hbuff);
+ return bIsConnected;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Function: GetSioDeviceStatus
+//
+// Description: Returns present/absent status of SIO device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+GetSioDeviceStatus(
+ IN OUT SIO_DEV_STATUS *devsts
+)
+{
+ static EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+ SIO_DEV_STATUS siost;
+ UINTN i, j, cnt;
+ EFI_STATUS Status;
+ ACPI_HID_DEVICE_PATH *siodp;
+ ACPI_PNPID *pnpid;
+ EFI_HANDLE *hbuff = NULL;
+ UINT16 shifty;
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+
+ siost.DEV_STATUS = 0;
+ i = sizeof(siost);
+ Status = pRS->GetVariable(
+ SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ NULL,
+ &i,
+ &siost.DEV_STATUS);
+ if (EFI_ERROR(Status)) {
+ //
+ // NVRAM variable is not found, let us try to get status directly.
+ //
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiAmiSioProtocolGuid, NULL, &cnt, &hbuff);
+// ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return;
+
+ for (shifty=1,j=0; j<16; j++, shifty<<=1) { // 16 is the number of device types
+ if (!(devsts->DEV_STATUS | shifty)) continue; // not this device
+ for(i=0; i<cnt; i++){
+ Status=pBS->HandleProtocol(hbuff[i],&gEfiDevicePathProtocolGuid,&dp);
+ if(EFI_ERROR(Status)) continue;
+
+ siodp=DPGetLastNode(dp);
+ if(siodp->Header.Type!=ACPI_DEVICE_PATH
+ || siodp->Header.SubType!=ACPI_DP
+ || NODE_LENGTH(&siodp->Header) != ACPI_DEVICE_PATH_LENGTH) continue;
+
+ pnpid=(ACPI_PNPID*)&siodp->HID;
+ if (pnpid->PnpID == aPnP[j]) {
+ siost.DEV_STATUS |= shifty;
+ break;
+ }
+ }
+ }
+ pBS->FreePool(hbuff);
+ }
+
+ *devsts = siost;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Function: GetComPortResource
+//
+// Description: Returns COM port base address and interrupt
+//
+// Input: ComNo - COM port number, 0-based.
+//
+// Output: EFI_NOT_FOUND - COM port is not found.
+// EFI_SUCCESS - COM port found, the output variables are updated:
+// Address - IO base address
+// Irq - IRQ number
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetComPortResource(
+ IN UINT8 ComNo,
+ OUT UINT16 *Address,
+ OUT UINT8 *Irq
+)
+{
+ EFI_HANDLE *Handle = NULL;
+ UINTN Count;
+ UINTN i;
+ EFI_STATUS Status;
+ UINT8 ComNumber = (UINT8)-1;
+ AMI_SIO_PROTOCOL *AmiSio;
+ SPIO_DEV *SpIoDev;
+
+ // Hide COM1 from legacy OS if we are using Trace in Runtime
+ if (ComNo == 0) {
+#if RUNTIME_TRACE_SUPPORT
+ return EFI_NOT_FOUND;
+#endif
+ }
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol, &gEfiAmiSioProtocolGuid, NULL, &Count, &Handle);
+ if(EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < Count; i++)
+ {
+ Status = pBS->HandleProtocol(Handle[i],&gEfiAmiSioProtocolGuid, &AmiSio);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = EFI_NOT_FOUND;
+
+ SpIoDev = (SPIO_DEV*)(UINTN)AmiSio;
+
+ if (SpIoDev->DeviceInfo->Type != dsUART) continue; // not COM port
+ if (SpIoDev->VlData.DevImplemented == 0)
+ {
+ continue;
+ }
+ ComNumber++;
+ //
+ // Check if we have reached "ComNo" th instance of UART devices
+ //
+ if(ComNumber!=ComNo)continue;
+
+
+ *Address = (UINT16)SpIoDev->VlData.DevBase1;
+ *Irq = (UINT8)SpIoDev->VlData.DevIrq1;
+
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ pBS->FreePool(Handle);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Function: GetLptResource
+//
+// Description: Returns LPT base address and interrupt
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetLptResource(
+ OUT UINT16 *Address,
+ OUT UINT8 *Irq
+)
+{
+ EFI_HANDLE *Handle = NULL;
+ UINTN Count;
+ UINTN i;
+ EFI_STATUS Status;
+
+ AMI_SIO_PROTOCOL *AmiSio;
+ SPIO_DEV *SpIoDev;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol, &gEfiAmiSioProtocolGuid, NULL, &Count, &Handle);
+ if(EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < Count; i++) {
+ Status = pBS->HandleProtocol(Handle[i],&gEfiAmiSioProtocolGuid, &AmiSio);
+ if (EFI_ERROR(Status)) continue;
+
+ SpIoDev = (SPIO_DEV*)(UINTN)AmiSio;
+
+ if (SpIoDev->DeviceInfo->Type != dsLPT) continue; // not LPT
+ if (SpIoDev->VlData.DevImplemented == 0) continue;
+
+ *Address = (UINT16)SpIoDev->VlData.DevBase1;
+ *Irq = (UINT8)SpIoDev->VlData.DevIrq1;
+
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ pBS->FreePool(Handle);
+
+ Status = (i == Count)? EFI_NOT_FOUND : EFI_SUCCESS;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: AllocateEbda
+//
+// DESCRIPTION: This function attempts to allocate EBDA.
+//
+// INPUT: EBDA size in kilo Bytes
+//
+// RETURN: 32-bit pointer of the allocated memory block inside EBDA
+// The allocated address offset off the beginning of EBDA
+// EFI_OUT_OF_RESOURCES if EBDA can not be allocated
+// EFI_SUCCESS if memory is successfully allocated
+//
+// NOTE: - This routine can be called multiple times and every time EBDA
+// data is copied to a different location. It is the caller
+// responsibility to obtain the current EBDA segment and its size
+// and adjust the offsets before accessing the data.
+// - NewEbdaAddress could be used immediately after allocation. If
+// the allocated block is not used immediately, - any successive
+// call moves the existing data - then the caller should use
+// EbdaStartOffset to calculate the correct address of the previously
+// allocated data.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AllocateEbda(
+ IN EFI_LEGACY_BIOS_EXT_PROTOCOL *This,
+ IN UINT8 RequestedSizeKB,
+ OUT UINT32 *NewEbdaAddress,
+ OUT UINT32 *EbdaStartOffset
+)
+{
+ UINT16 CurEbdaSeg = *(UINT16*)(UINTN)0x40E;
+ UINTN CurEbdaLocation, NewEbdaLocation;
+ UINT8 CurEbdaSizeKB;
+ UINTN CurEbdaSize, EbdaSize;
+ UINTN MinEbdaAddress = 0xA0000-PMM_EBDA_LOMEM_SIZE;
+
+ //
+ // Check the current EBDA allocation and see if there is still room in it
+ //
+ CurEbdaLocation = (UINTN)CurEbdaSeg<<4;
+ ASSERT(CurEbdaLocation > MinEbdaAddress); // either not allocated or already full
+
+ EbdaSize = (UINTN)RequestedSizeKB << 10;
+ NewEbdaLocation = CurEbdaLocation - EbdaSize;
+
+ if (NewEbdaLocation < MinEbdaAddress) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Do the allocation:
+ // - copy old EBDA
+ // - clear the allocated EBDA
+ // - update EBDA pointer and EBDA size
+ //
+ CurEbdaSizeKB = *(UINT8*)CurEbdaLocation;
+ CurEbdaSize = (UINTN)CurEbdaSizeKB<<10;
+
+ pBS->CopyMem((VOID*)NewEbdaLocation, (VOID*)CurEbdaLocation, CurEbdaSize);
+
+ pBS->SetMem((UINT8*)(NewEbdaLocation+CurEbdaSize), EbdaSize, 0);
+
+ *(UINT16*)(UINTN)0x40E = (UINT16)(NewEbdaLocation>>4);
+ *(UINT8*)NewEbdaLocation = CurEbdaSizeKB + RequestedSizeKB;
+
+ //
+ // Update 40:13 with the new size of available base memory
+ //
+ *(UINT16*)(UINTN)0x413 = (*(UINT16*)(UINTN)0x413) - RequestedSizeKB;
+
+ //
+ // Update the EBDA information for the saved OpROMs
+ //
+ UpdateEbdaMap((UINT32)EbdaSize);
+
+ *NewEbdaAddress = (UINT32)(NewEbdaLocation+CurEbdaSize);
+ *EbdaStartOffset = (UINT32)CurEbdaSizeKB << 10;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: UnlockShadow
+//
+// Description: Opens the shadow region(s) for writing.
+//
+// Input: Address - starting address
+// Size - size of the region
+//
+// Output: LockUnlockAddr - address of the first unlocked block
+// LockUnlockSize - unlocked address space
+// Function returns EFI_OUT_OF_RESOURCES if there is not enough room
+// in the shadow.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UnlockShadow(
+ IN UINT8 *Address,
+ IN UINTN Size,
+ OUT OPTIONAL UINT32 *LockUnlockAddr,
+ OUT OPTIONAL UINT32 *LockUnlockSize
+)
+{
+ UINT32 Granularity;
+ UINT32 addr, size;
+ UINT32 addr_adjustment;
+ UINT32 size_adjustment = 0;
+ EFI_STATUS Status;
+
+ addr = (UINT32)(UINTN)Address;
+ size = (UINT32)Size;
+ if (size) {
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion,
+ addr, size, &Granularity);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ addr_adjustment = addr % Granularity;
+
+ if (((addr+size) % Granularity) != 0) {
+ size_adjustment = Granularity - ((addr+size) % Granularity);
+ }
+
+ // Adjust the address to align with the granularity
+ addr -= addr_adjustment;
+ // Adjust the size to align with the granularity
+ size += addr_adjustment; // Align left
+ size += size_adjustment;
+
+ }
+
+ // moved these outside the if (size) for case when size = 0
+ if (LockUnlockAddr != NULL) *LockUnlockAddr = addr;
+ if (LockUnlockSize != NULL) *LockUnlockSize = size;
+
+ //
+ // Finally make CSM16 area writable for the cases where
+ // CSM16 area needs to be updated during DispatchOptionRom
+ // call, e.g. for non-BBS OpROMs.
+ //
+ Status = CoreBiosInfo->iRegion->UnLock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: LockShadow
+//
+// Description: Locks the shadow region(s).
+//
+// Input: LockAddr - Starting address of the area to be locked
+// LockSize - Size of the area to be locked
+//
+// Output: Status of the lock operation.
+//
+// Notes: This function will also clear the R/W attribute for the region
+// from LockAddr+LockSize to gMaxOpRomAddress; this is needed for
+// some OS drivers to be loaded properly (Win PCMCIA driver)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LockShadow(
+ IN UINT32 LockAddr,
+ IN UINT32 LockSize
+)
+{
+ UINT32 Granularity;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (LockSize && ((LockAddr+LockSize) < gMaxOpRomAddress)) {
+ Status = CoreBiosInfo->iRegion->Lock (CoreBiosInfo->iRegion, LockAddr, LockSize, &Granularity);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Disable Shadow W/R for the unused shadow regions
+ // Take care of the boundary conditions: LockAddr+LockSize is not nesessarily
+ // within Granularity boundaries. For example, if LockAddr is 0xC0000, LockSize
+ // is 0x1400 and Granularity is 0x1000, then area from 0xC0000 to 0xC2000 is
+ // locked. The next call must not use 0xC0000+LockSize, otherwise part of the
+ // OpROM becomes unreadable.
+ //
+ if (LockSize % Granularity) LockSize += Granularity;
+ LockSize = (LockSize/Granularity)*Granularity;
+ }
+
+ if( LockAddr!=0 && LockSize!=0 ) {
+ BOOLEAN On=FALSE;
+ if ((LockAddr+LockSize) < gMaxOpRomAddress) {
+ Status = CoreBiosInfo->iRegion->Decode (CoreBiosInfo->iRegion,
+ LockAddr+LockSize,
+ (UINT32)gMaxOpRomAddress-LockSize-LockAddr+1,
+ &On);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+
+ CoreBiosInfo->iRegion->Lock (
+ CoreBiosInfo->iRegion,
+ (UINT32)gMaxOpRomAddress+1,
+ 0xFFFFF-(UINT32)gMaxOpRomAddress,
+ NULL
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: RemoveDecodingForShadow
+//
+// Description: This function will clear the R/W attribute for the region
+// from DecodeAddr to gMaxOpRomAddress; this is needed for
+// some OS drivers to be loaded properly (Win PCMCIA driver).
+//
+// Input: DecodeAddr - Starting address of the area to remove the decoding
+//
+// Output: Status of the decoding operation.
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveDecodingForShadow(
+ IN UINT32 DecodeAddr
+)
+{
+ BOOLEAN On=FALSE;
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINT32 Granularity;
+ UINT32 addr, size=1;
+ UINT32 addr_adjustment, size_adjustment;
+
+ addr = DecodeAddr;
+
+ //
+ //Find the nearest starting address
+ //
+ if (size) {
+TRACE((TRACE_ALWAYS, "RemoveDecoding: addr %x\n", addr));
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion,
+ addr, size, &Granularity);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ addr_adjustment = addr % Granularity;
+ size_adjustment = Granularity - ((addr+size) % Granularity);
+ // Adjust the address to align with the granularity
+ addr -= addr_adjustment;
+ // Adjust the size to align with the granularity
+ size += addr_adjustment; // Align left
+ size += size_adjustment;
+ }
+
+ Status = CoreBiosInfo->iRegion->Lock (CoreBiosInfo->iRegion, addr, size, &Granularity);
+
+ if(addr == DecodeAddr) {
+ DecodeAddr=addr;
+ } else {
+ DecodeAddr=addr+size;
+ }
+
+ if (DecodeAddr < gMaxOpRomAddress) {
+
+ Status = CoreBiosInfo->iRegion->Decode (CoreBiosInfo->iRegion,
+ DecodeAddr,
+ (UINT32)((gMaxOpRomAddress+1)-DecodeAddr),
+ &On);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetBbsTable
+//
+// Description: This function returns a pointer to the BBS table and the
+// number of entries.
+//
+// Output: BbsTable - Pointer to BBS table.
+// BbsCount - Number of entries in table.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetBbsTable (
+ IN OUT BBS_TABLE **BbsTable,
+ IN OUT UINT8 *BbsCount
+)
+{
+ if ((BbsTable == NULL) || (BbsCount == NULL))
+ return EFI_INVALID_PARAMETER;
+
+ if (CoreBiosInfo == NULL)
+ return EFI_NOT_READY;
+
+ if (CoreBiosInfo->BbsTable == NULL)
+ return EFI_NOT_READY;
+
+ *BbsTable = CoreBiosInfo->BbsTable;
+ *BbsCount = CoreBiosInfo->BbsEntriesNo;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AddBbsEntry
+//
+// Description: This function adds given BBS entry to a BBS table.
+//
+// Input: BbsEntry - BBS table entry to be added to a table.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AddBbsEntry (
+ IN BBS_TABLE *BbsEntry
+)
+{
+ if (gBbsUpdateInProgress) return EFI_NOT_READY;
+
+ gBbsUpdateInProgress = TRUE;
+
+ CoreBiosInfo->BbsTable[CoreBiosInfo->BbsEntriesNo] = *BbsEntry;
+ CoreBiosInfo->BbsTable[CoreBiosInfo->BbsEntriesNo].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+ CoreBiosInfo->BbsEntriesNo++;
+
+ gBbsUpdateInProgress = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InsertBbsEntryAt
+//
+// Description: This function is an extension of AddBbsEntry function; it
+// allows to add a BBS_ENTRY at a particular location or add
+// a new entry and return its new location.
+//
+// Input: This - Instance of LegacyBiosExt protocol.
+// EntryNumber - Pointer to 0-based index in BBS table. The
+// value of 0xFF will generate a new entry.
+//
+// Output: EFI_INVALID_PARAMETER - EntryNumber is NULL.
+// EFI_SUCCESS - EntryNumber is updated with the index of updated
+// BBS entry.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertBbsEntryAt (
+ IN EFI_LEGACY_BIOS_EXT_PROTOCOL *This,
+ IN BBS_TABLE *BbsEntry,
+ IN OUT UINT8 *EntryNumber
+)
+{
+ UINT8 EntryNo;
+
+ if (gBbsUpdateInProgress) return EFI_NOT_READY;
+
+ if (EntryNumber == NULL) return EFI_INVALID_PARAMETER;
+
+ gBbsUpdateInProgress = TRUE;
+
+ if (*EntryNumber != 0xff) {
+ EntryNo = *EntryNumber;
+ } else {
+ //
+ // Find an empty entry within MAX_IDE_CONTROLLER*2+1..BbsEntriesNo-1
+ //
+ for (EntryNo = MAX_IDE_CONTROLLER*2+1; EntryNo < CoreBiosInfo->BbsEntriesNo; EntryNo++)
+ {
+ if (CoreBiosInfo->BbsTable[EntryNo].BootPriority == BBS_IGNORE_ENTRY)
+ {
+ break;
+ }
+ }
+ //
+ // If not found, EntryNo will be equal BbsEntriesNo
+ //
+ }
+ CoreBiosInfo->BbsTable[EntryNo] = *BbsEntry;
+ CoreBiosInfo->BbsTable[EntryNo].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+
+ //
+ // BbsEntriesNo should not be incremented for the BBS entries
+ // with indexes from 0 to CoreBiosInfo->BbsEntriesNo-1
+ //
+ if (EntryNo >= CoreBiosInfo->BbsEntriesNo) {
+ CoreBiosInfo->BbsEntriesNo++;
+ }
+ *EntryNumber = EntryNo;
+
+ gBbsUpdateInProgress = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveBbsEntryAt
+//
+// Description: This function removes BBS entry from BBS table.
+//
+// Input: This - Instance of LegacyBiosExt protocol.
+// EntryNumber - Entry index to be removed.
+//
+// Output: EFI_INVALID_PARAMETER - EntryNumber exceeds the current table.
+// EFI_NOT_FOUND - Entry does not exist.
+// EFI_SUCCESS - Entry has been successfully removed.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveBbsEntryAt (
+ IN EFI_LEGACY_BIOS_EXT_PROTOCOL *This,
+ IN UINT8 EntryNumber
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (gBbsUpdateInProgress) return EFI_NOT_READY;
+
+ gBbsUpdateInProgress = TRUE;
+
+ //
+ // Can only remove a particular entry within 0..CoreBiosInfo->BbsEntriesNo-1 range;
+ //
+ if (EntryNumber >= CoreBiosInfo->BbsEntriesNo) Status = EFI_INVALID_PARAMETER;
+
+ if (!EFI_ERROR(Status)) {
+ if (CoreBiosInfo->BbsTable[EntryNumber].BootPriority == BBS_IGNORE_ENTRY) {
+ Status = EFI_NOT_FOUND;
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ //
+ // Decrement CoreBiosInfo->BbsEntriesNo only if requested index equals
+ // CoreBiosInfo->BbsEntriesNo-1
+ //
+ if (EntryNumber == (CoreBiosInfo->BbsEntriesNo-1)) {
+ CoreBiosInfo->BbsEntriesNo--;
+ }
+
+ pBS->SetMem(&CoreBiosInfo->BbsTable[EntryNumber], sizeof(BBS_TABLE), 0);
+ CoreBiosInfo->BbsTable[EntryNumber].BootPriority = BBS_IGNORE_ENTRY;
+ }
+
+ gBbsUpdateInProgress = FALSE;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SignalProtocolEvent
+//
+// Description: Internal function that installs/uninstall protocol
+// with a specified GUID and NULL interface.
+// Such protocols can be used as event signaling mechanism.
+//
+// Input: ProtocolGuid Pointer to the protocol GUID
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SignalAmiLegacyBootEvent()
+{
+ EFI_HANDLE Handle = NULL;
+ static EFI_GUID ProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+ pBS->InstallProtocolInterface (
+ &Handle, &ProtocolGuid, EFI_NATIVE_INTERFACE, NULL
+ );
+ pBS->UninstallProtocolInterface (
+ Handle, &ProtocolGuid, NULL
+ );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ConnectSerialIO
+//
+// Description: Connect all the serial IO that was disconnected before.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ConnectSerialIO()
+{
+ UINTN n;
+
+ for (n = 0; n < gSerialIoHandleCount; n++) {
+ pBS->ConnectController(gSerialIoHandleBuffer[n],NULL,NULL,TRUE);
+ }
+
+ return;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DisconnectSerialIO
+//
+// Description: Disconnect the All the Serial io Handles
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DisconnectSerialIO()
+{
+ UINTN n;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Locate all Serial IO handles
+ //
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSerialIoProtocolGuid,
+ NULL,
+ &gSerialIoHandleCount,
+ &gSerialIoHandleBuffer);
+
+ if (EFI_ERROR (Status)) {
+ return ;
+ }
+
+ for (n = 0; n < gSerialIoHandleCount; n++) {
+ //
+ // Check if we have DevicePath Protocol installed on Controller handle.
+ // If not, do not disconnect the controller because it may not be handled
+ // by the Serial IO drvier.
+ //
+ Status = pBS->HandleProtocol (
+ gSerialIoHandleBuffer[n],
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath);
+
+ if (!EFI_ERROR (Status)) {
+ pBS->DisconnectController(gSerialIoHandleBuffer[n],NULL,NULL);
+ }
+ }
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsAMICSM16
+//
+// Description:
+// This function checks whether the CSM16 image is made by AMI.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsAMICSM16(
+ EFI_COMPATIBILITY16_TABLE* Csm16Header
+)
+{
+ // Check for "AMIBIOS(" at F000:F500
+ return (*(UINT32*)0xff500 == 0x42494d41 &&
+ *(UINT32*)0xff504 == 0x28534f49);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ChecksumCSM16Header
+//
+// Description:
+// Calculates and updates a checksum field of $EFI header.
+//
+// Input:
+// Csm16Header Pointer to the EFI_COMPATIBILITY16_TABLE structure
+//
+// Output:
+// Checksum byte
+//
+// Notes:
+// Shadow region must be open for writing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+ChecksumCSM16Header (
+ EFI_COMPATIBILITY16_TABLE *Csm16Header
+)
+{
+ UINT8 i;
+ UINT8 chksum;
+ UINT8 *p;
+
+ Csm16Header->TableChecksum = 0;
+ p = (UINT8*)CoreBiosInfo->Csm16Header;
+ for (chksum = 0, i = 0; i < Csm16Header->TableLength; i++) {
+ chksum += *p++;
+ }
+ Csm16Header->TableChecksum = ~(--chksum);
+
+ return Csm16Header->TableChecksum;
+}
+
+typedef struct {
+ CSM16_FEATURE Feature;
+ UINT8 Bit;
+ UINT8 InfoByteOfs;
+} CSM16_FEATURE_LOOKUP;
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Csm16Configuration
+//
+// Description:
+// This is LegacyBiosExt interface function that manages CSM16 configuration
+// settings.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Csm16Configuration(
+ IN CSM16_CONFIGURATION_ACTION ConfigAction,
+ IN CSM16_FEATURE Param,
+ OUT OPTIONAL UINT32 *Data
+)
+{
+ LEGACY16_TO_EFI_DATA_TABLE_STRUC *Csm16Data;
+ UINT8 MiscInfo;
+ UINT8 RtCmosByte;
+ volatile UINT8 ProbeData = *(UINT8*)0xf0000;
+ UINT32 Granularity;
+ EFI_STATUS Status;
+ BOOLEAN F000WasOpen;
+ UINT32 i;
+ UINT32 Count;
+
+ static CSM16_FEATURE_LOOKUP Csm16Feature[] = {
+ { Csm16HeadlessI19Retry, CSM16_HEADLESS_INT19_RETRY_BIT, 0 },
+ { Csm16I13MbrWriteProtect, CSM16_I13_HDD_MBR_WP_BIT, 0 },
+ { Csm16LegacyFree, CSM16_NO_KBC_PRESENT_BIT, 0 },
+ { Csm16ZipHddEmulation, CSM16_ZIP_HDD_EMUL_BIT, 0 },
+ { Csm16NoUsbBoot, CSM16_NO_USB_BOOT_BIT, 0 },
+ { Csm16I19Trap, CSM16_I19_TRAP_BIT, 0 },
+ { Csm16Flexboot, CSM16_FLEXBOOT_ENABLE_BIT, 0 },
+ { Csm16GA20, CSM16_FAST_GATE_A20_BIT, 0 },
+ { Csm16SkipGA20Deactivation, CSM_RT_CMOS_SKIP_GA20_DEACTIVATION_BIT, 1 },
+ { Csm16Nmi, CSM_RT_CMOS_PARITY_BIT, 1 },
+ { Csm16CpuRealModeOnBoot, CSM_RT_CPU_RM_ONBOOT_BIT, 1 },
+ { Csm16PS2, CSM_RT_CMOS_PS2_BIT, 1 },
+ { Csm16LegacyToEfi, CSM_RT_CMOS_LTE_BIT, 1 },
+ { Csm16LegacyToEfiPonr, CSM_RT_CMOS_LTE_PONR_BIT, 1 }
+ };
+
+ Csm16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xf0000 + *(UINT16*)0xfff4c);
+ MiscInfo = *(UINT8*)(UINTN)Csm16Data->MiscInfoAddress;
+ RtCmosByte = *(UINT8*)(UINTN)Csm16Data->RtCmosByteAddress;
+
+ // see if F000 needs to be made writable
+ *(UINT8*)0xf0000 = ProbeData + 1;
+ F000WasOpen = *(UINT8*)0xf0000 != ProbeData;
+ if (F000WasOpen) {
+ *(UINT8*)0xf0000 = ProbeData; // restore byte
+ } else {
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion, 0xf0000, 0x10000, &Granularity);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return EFI_ACCESS_DENIED;
+ }
+
+ // Find parameter in the lookup table
+ Count = sizeof(Csm16Feature)/sizeof(CSM16_FEATURE_LOOKUP);
+ for (i = 0; i < Count; i++) {
+ if (Csm16Feature[i].Feature == Param) break;
+ }
+
+ if (i == Count) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Done;
+ }
+
+ Status = EFI_SUCCESS;
+
+ switch (ConfigAction) {
+ case Csm16FeatureGet:
+ if (Data == NULL) {
+ Status = EFI_INVALID_PARAMETER; break;
+ }
+ if (Csm16Feature[i].InfoByteOfs == 0)
+ *Data = (MiscInfo & Csm16Feature[i].Bit)? 1 : 0;
+ else
+ *Data = (RtCmosByte & Csm16Feature[i].Bit)? 1 : 0;
+ break;
+
+ case Csm16FeatureSet:
+ if (Csm16Feature[i].InfoByteOfs == 0) {
+ MiscInfo |= Csm16Feature[i].Bit;
+ *(UINT8*)(UINTN)Csm16Data->MiscInfoAddress = MiscInfo;
+ } else {
+ RtCmosByte |= Csm16Feature[i].Bit;
+ *(UINT8*)(UINTN)Csm16Data->RtCmosByteAddress = RtCmosByte;
+ }
+ break;
+
+ case Csm16FeatureReset:
+ if (Csm16Feature[i].InfoByteOfs == 0) {
+ MiscInfo &= ~Csm16Feature[i].Bit;
+ *(UINT8*)(UINTN)Csm16Data->MiscInfoAddress = MiscInfo;
+ } else {
+ RtCmosByte &= ~Csm16Feature[i].Bit;
+ *(UINT8*)(UINTN)Csm16Data->RtCmosByteAddress = RtCmosByte;
+ }
+ break;
+
+ default: ASSERT(FALSE); Status = EFI_INVALID_PARAMETER;
+ }
+
+Done:
+
+ if (!F000WasOpen) {
+ CoreBiosInfo->iRegion->Lock (CoreBiosInfo->iRegion, 0xf0000, 0x10000, &Granularity);
+ }
+
+ return Status;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/CSM/CsmOpROM.c b/Core/EM/CSM/CsmOpROM.c
new file mode 100644
index 0000000..15cf5c5
--- /dev/null
+++ b/Core/EM/CSM/CsmOpROM.c
@@ -0,0 +1,2726 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmOpROM.c 171 8/06/14 4:24p Fasihm $
+//
+// $Revision: 171 $
+//
+// $Date: 8/06/14 4:24p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmOpROM.c $
+//
+// 171 8/06/14 4:24p Fasihm
+// [TAG] EIP180681
+// [Category] Improvement
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: Clean the setup settings and options.
+// [Solution] INT19 trap setup question removed, cleaned code.
+// [Files]
+// Board\EM\Csm\csm.sd
+// Board\EM\Csm\csm.uni
+// Core\EM\CSM\CsmBsp.c
+// Core\EM\CSM\CsmOpROM.c
+//
+// 170 11/20/13 6:03p Olegi
+// EIP144132: Extend the checking for VGA controller.
+//
+// 169 10/25/13 3:10p Olegi
+// [TAG] EIP141160
+// [Category] Improvement
+// [Description] InstallPciRom has the code that updates the list of
+// executed ROMs; the condition used there is not correct.
+//
+// 168 6/04/13 12:15p Olegi
+// [TAG] EIP125092
+// [Category] Improvement
+// [Description] CSM does not handle PCI ROM 2.1+3.0 combination
+//
+// 167 5/15/13 3:32p Olegi
+// [TAG] EIP123915
+// [Category] Improvement
+// [Description] BBS table update in CSM should be atomic operation
+// [Files] CsmOpROM.c
+// CsmLib.c
+//
+// 166 4/01/13 8:46a Olegi
+// [TAG] EIP111209
+// [Category] Improvement
+// [Description] ISA boot devices controlled by the Option ROM are added
+// to the boot list.
+// [Files] CsmOprom.c
+//
+// 165 12/20/12 11:02a Olegi
+//
+// 164 10/23/12 4:45p Olegi
+// EIP 104052 - Support for generic Option ROMs with PCI3.0 headers
+//
+// 163 10/22/12 10:02a Olegi
+// [TAG] EIP100790
+// [Category] Improvement
+//
+// ConnectSerialIO is moved after Video is reconnected.
+//
+// 162 7/23/12 12:05p Olegi
+// [TAG] EIP92895
+// [Category] New Feature
+// [Description] Event-based PreProcessOpRom replacement for AptioV
+//
+// 161 6/25/12 3:59p Olegi
+// [TAG] EIP90257
+// [Category] Improvement
+// [Description] In CSM, don't clear allocated memory below 640K - added
+// ClearFreeMemory function
+// [Files] CsmOpROM.c
+// CSM.c
+// CsmHwInfo.c
+//
+// 160 6/15/12 10:39a Olegi
+// [TAG] EIP83856
+// [Description] Audio device show can not start under Device Manager
+// with UEFI win7
+//
+// 159 6/15/12 10:23a Olegi
+// [TAG] EIP90155
+// [Category] Improvement
+// [Description] CSM changes to support OpRomTxt module genericly
+// [Files] CsmOpROM.c
+// CsmBsp.c
+//
+// 158 6/13/12 12:56p Olegi
+// [TAG] EIP91376
+// [Category] Improvement
+// [Description] Added the verification of gExecutedRomsPci before PCI
+// Option ROM execution.
+// Increased the number of maximum PCI Option ROMs to 32.
+// [Files] CSM.h
+// CsmOpROM.c
+//
+// 157 4/24/12 6:49p Olegi
+//
+// 156 4/24/12 6:40p Olegi
+// [TAG] EIP86770
+// [Category] Improvement
+// [Description] Added ExecuteBcv function.
+//
+// 155 2/10/12 10:09a Olegi
+// [TAG] EIP82449
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] During LegacyBoot some EBDA locations might be destroyed
+// [RootCause] The amount of EBDA allocated by the Option ROM was not
+// properly calculated in case Option ROM uses several allocation methods
+// at the same time: EBDA and 40-:13.
+// [Solution] Corrected the calculation of the size of allocated EBDA
+// [Files] CsmOpROM.c
+//
+// 154 12/23/11 2:47p Olegi
+// [TAG] EIP79228
+// [Category] Improvement
+// [Description] Implement CSM_INT19_TRAP_IMMEDIATE_ACTION functionality
+// [Files] CsmOpROM.c
+// CSM.c
+//
+// 153 12/13/11 10:58a Matthewh
+//
+// 152 12/13/11 10:53a Matthewh
+// [TAG] EIP77897
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Using More then one ISA PnP Card with an Option ROM that have
+// overlapping Memory ranges only one Option ROM will be run. Address range
+// may be skipped if the address is already aligned properly before "AND"ing
+// with the Aln variable and adding the alignment.
+// [RootCause] The global variable gNextRomAddress is not moved to the next
+// available locatation untill the InstallIsaRom function is run but by then
+// both Option Roms have already been assigned to the same address. There is
+// no check to see if the address is already aligned properly before the
+// alignment calculation is applied.
+// [Solution] Change GetShadowRamAddress function to update gNextRomAddress
+// and remove the update of gNextRomAddress from InstallIsaRom. Update
+// GetShadowRamAddress function to take into account that the address may
+// already be aligned and no need to add the alignment.
+// [Files] CsmOpROM.c
+
+//
+// 151 11/11/11 6:09p Olegi
+// [TAG] EIP74894
+// [Category] Improvement
+// [Description] In some cases OEM logo partially remains on the screen
+// during EFI shell/boot popup menu.
+// [Files] csmoprom.c
+//
+// 150 10/31/11 12:38p Olegi
+// [TAG] EIP72804
+// [Category] Improvement
+// [Description] Promise FastTrak 2650 Option ROM hangs the system.
+// [Files] CsmOprom.c
+//
+// 149 10/12/11 2:56p Olegi
+// [TAG] EIP72177
+// [Category] Improvement
+// [Description] CheckPmmTable function suppressed.
+// [Files] CsmOpROM.c
+// CSM.c
+// CsmBsp.c
+// CSM.SDL
+//
+// 148 9/30/11 12:46p Olegi
+// Undone all changes related to EIP70382 (check-in 144, 146, 147. INT19
+// trapping modifications are added to CSM16.
+//
+// 147 9/29/11 10:52a Olegi
+// Continuation of check-in #144 related to EIP70382; clearing keyboard
+// status is moved to FarCall86.
+//
+// 146 9/29/11 9:45a Olegi
+// Continuation of check-in #144 related to EIP70382; adding a check for
+// Setup.I19Trap.
+//
+// 145 9/28/11 10:45a Olegi
+// [TAG] EIP71227
+// [Category] Improvement
+// [Description] Added out-of-resource reporting during memory
+// allocation failure.
+// [Files] csmoprom.c
+//
+// 144 9/27/11 6:26p Olegi
+// [TAG] EIP70382
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Keyboard is not functional in some Option ROM setup utility
+// [RootCause] When Option ROM hot key combination has Ctrl as a part of
+// it (Ctrl-H), then the state of Ctrl key might remain in 40:17 after
+// control comes back to EFI.
+// If after this another 16-bit code is executed and requires keyboard
+// handling, having improper settings in 40:17 affect the key reporting
+// data.
+// [Solution] Make sure the booting process go through INT19, and Option
+// ROM setup is not invoked earlier during PrepareToBoot.
+// INT19 code has the initialization of 40:17 that resolves the issue.
+// [Files] CsmOpROM.c
+//
+// 143 8/25/11 10:06a Olegi
+// Change in CheckPmmTable: skip the low memory PMM entries.
+//
+// 142 8/22/11 9:59a Olegi
+// [TAG] EIP66613
+// [Category] Improvement
+// [Description] Dynamic PMM size.
+// [Files] CsmOprom.c
+//
+// 141 8/15/11 5:52p Olegi
+// Changed the type of the counter variable in CheckPmmTable function from
+// UINT8 to UINTN.
+//
+// 140 8/11/11 4:23p Olegi
+// [TAG] EIP66636
+// [Category] Improvement
+// [Description] Validation of legacy Option ROM modified: some Option
+// ROMs are not properly report last image indicator (Adaptec SCSI BIOS
+// v4.31.4 (c) 2007).
+// [Files] CsmOpROM.c
+//
+// 139 6/21/11 2:03p Olegi
+// 1. EIP62285: Immediate INT19 execution call added
+// 2. VGA enabling properly done after VGA driver is disconnected
+// 3. Multiple legacy Option ROMs handling corrected to return the 1st
+// legacy
+//
+// 138 6/15/11 10:43a Olegi
+// [TAG] EIP61986
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Post Screen corruption occurs while loading multiple Option
+// ROMS.
+// [RootCause] There are cases when video get reconnected outside CSM,
+// in between Option ROM execution. That gets VGA disconnect/connect logic
+// out of hand.
+// [Solution] Added the LegacyVgaStartCounter to keep the sync between
+// disconnect/connect video, so that setting CSM_DEFAULT_VMODE_SWITCHING
+// to 1 will work correctly.
+// [Files] CsmOpROM.c
+//
+// 137 6/10/11 5:37p Olegi
+// [TAG] EIP59263
+// [Category] New Feature
+// [Description] High memory PMM area made dynamic.
+// [Files] CSM.h
+// CsmOpROM.c
+// CSM.c
+// CsmBsp.c
+// csm.sdl
+//
+// 136 5/20/11 11:27a Olegi
+// [TAG] EIP60317
+// [Category] Improvement
+// [Description] Do not enable PCI siblings for VGA; if multiple VGA is
+// enabled at the same time, OS might have a problem.
+// [Files] CsmOprom.c
+//
+// 135 3/22/11 1:52p Olegi
+// [TAG] EIP54935
+// [Category] Improvement
+// [Description] Added checking for EBDA deallocation done by the Option
+// ROM.
+// [Files] CsmOprom.c
+//
+// 134 3/18/11 10:02a Olegi
+// [TAG] EIP56215
+// [Category] Improvement
+// [Description] Added $PnP checksum validation.
+// [Files] CsmOprom.c
+//
+// 133 3/15/11 3:54p Olegi
+// Changes from #127 are restored.
+//
+// 132 3/14/11 10:00a Olegi
+// [TAG] EIP54942
+// [Category] New Feature
+// [Description] CLP support implementation
+// [Files] CsmOprom.c LegacyBiosExt.h
+//
+// 131 3/10/11 5:38a Rajeshms
+// [TAG] - EIP 39307
+// [Category]- BUG FIX
+// [Severity]- Normal
+// [Symptom] - Enter DOS no screen when legacy serial redirection enable
+// with option rom message display option is set to " Keep current" in
+// setup.
+// [RootCause] - Actual INT 10h handler was not replaced after dispatching
+// option rom. Legacy console redirection driver INT10h was replaced
+// instead of actual handler when option rom message display option was
+// set to " Keep current".
+// [Solution] - Legacy Console redirection is disabled after its handler
+// is replaced in INT 10h place by the dummy handler so that actual INT10h
+// handler is replaced by Legacy Console redirection driver. To Support
+// redirection for ISA oprom's , enable and disable of legacy console
+// redirection has been moved to CsmOpRom.c from OemDxe.c.
+// [Files] - CsmOpRom.c, OemDxe.c
+//
+// 130 3/08/11 2:15p Olegi
+// [TAG] EIP55344
+// [Category] Improvement
+// [Description] In some cases screen mode is not properly set in
+// ConsoleControl after Option ROM execution.
+// [Files] CsmOprom.c
+//
+// 129 3/08/11 12:44p Olegi
+// [TAG] EIP55496
+// [Category] Improvement
+// [Description] Added ebdaOffset field to SAVED_PCI_ROM structure to
+// ensure the correct EBDA saving/restoration.
+// [Files] CSM.h
+// CsmOpROM.c
+// CSM.c
+//
+// 128 2/21/11 1:59p Olegi
+// [TAG] EIP54262
+// [Category] Improvement
+// [Description] Modification CheckPciRom that sometimes does not return
+// the proper PCI ROM Status.
+// [Files] CsmOprom.c
+//
+// 127 1/31/11 4:34p Olegi
+// [TAG] EIP51947
+// [Category] Improvement
+// [Description] Change the handling of Option ROMs that trap INT19.
+// [Files] CsmOpROM.C, AmiLegacy16.bin
+//
+// 126 1/19/11 10:18a Olegi
+//
+// 124 12/17/10 12:09p Olegi
+// Zero FinalLocationSegment field before executing 2.1 (or any other less
+// than 3.0) PCI Option ROM.
+//
+// 123 12/15/10 1:24p Olegi
+// [TAG] EIP47379
+// [Category] Bug Fix
+// [RootCause] For multiple images in the Option ROM, if the 1st image
+// in not IA32 type, the IA32 image will not be found.
+// [Solution] Modified IsValidLegacyPciOpROM routine, now it does not
+// break on the non-IA32 image.
+// [Files] CsmOpROM.c
+//
+// 122 12/14/10 11:44a Olegi
+// [TAG] EIP48212
+// [Category] Improvement
+// [Description] The default implementation of CheckEnablePciSiblings
+// can be improved. It could enable all PCI devices with the same VID/DID
+// because most of the Option ROMs expect that.
+// [Files] CsmOpROM.C
+//
+// 121 11/08/10 9:21a Olegi
+// Modified CsmInstallRom function to use correct PciIo.
+//
+// 120 10/29/10 11:39a Olegi
+// [TAG] EIP47186
+// [Category] Bug Fix
+// [RootCause] FindAnyVga returns EFI_SUCCESS in case of headless
+// system.
+// [Solution] Correct the logic in FindAnyVga.
+// [Files] CsmOprom.c
+//
+// 119 10/21/10 4:34p Olegi
+// [TAG] EIP46470
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] VGA enable bit is being set in the upstream PCI bridge
+// control register for a non-VGA device that uses an option ROM
+// [RootCause] ShadowAllLegacyOproms was enabling EFI_VGA_DEVICE_ENABLE
+// attribute before the Option ROM execution; that was done for all
+// devices, VGA or not.
+// [Solution] Move enabling EFI_VGA_DEVICE_ENABLE attribute inside
+// InstallPciRom, do it for VGA controllers only
+// [Files] CsmOprom.c
+//
+// 118 8/17/10 3:15p Olegi
+// Fixes discovered by Klockwork II engine: EIP37977
+//
+// 117 7/29/10 3:16p Olegi
+// EIP39768:: Added a call to ConsolControl->SetMode after switching to
+// text mode.
+//
+// 116 7/21/10 9:30a Olegi
+//
+// 115 7/20/10 8:59a Olegi
+// EIP40907: Initialize Option ROM size field to 0 before ROM execution
+//
+// 114 7/16/10 12:34p Olegi
+// - removed GetPciControllerClassCode function, replaced with inline code
+// - Connect/DisconnectSerialIO functions are moved to CSMLIB.C
+//
+// 113 6/18/10 10:35a Olegi
+// Added checking for EFI ROM in IsValidLegacyPciOpROM function.
+//
+// 112 5/17/10 4:26p Olegi
+// Modified the meaning of the 2nd parameter in GetShadowRamAddress
+// function.
+//
+// 111 5/14/10 4:13p Olegi
+//
+// 110 5/06/10 4:47p Olegi
+//
+// 109 4/28/10 11:51a Olegi
+// Added InstallIsaRom funtion.
+//
+// 108 4/27/10 12:19p Olegi
+// ERROR_CODE is changed to DEVICE_ERROR_CODE, EIP#37648
+//
+//
+// 104 3/02/10 5:11p Olegi
+// Changed the parameters for Pre/PostProcessOpROM function. EIP34085.
+//
+// 103 2/17/10 4:06p Olegi
+// Change in InstallPciRom: if during Option ROM execution there is a
+// change in the BBS table, it was not processed correctly. EIP35247.
+//
+// 102 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 101 12/28/09 8:05a Olegi
+// Changed the sequence of updating INT10 vector with the dummy and
+// calling PostprocessOpRom function. EIP#32832
+//
+// 100 12/21/09 3:03p Olegi
+//
+// 99 12/08/09 5:07p Olegi
+// EIP#15138::Implementation of CheckEnablePciSiblings
+//
+// 98 11/02/09 9:32a Olegi
+// EIP#29425 Added platform function to get the ROMs from FV, since the
+// default method do not always satisfy OEM requirements.
+//
+// 97 8/07/09 2:35p Rameshr
+// SD boot support Added.
+//
+// 96 8/05/09 5:54p Olegi
+// - Added check for runtime size being FF
+// - Added check for BCV and BEV both being 0
+// - Change related to EIP#24327
+//
+// 95 6/15/09 5:50p Olegi
+// Disconnect/Reconnect serial IO devices while executing OpROMs.
+// EIP#20254.
+//
+// 94 2/21/09 3:47p Olegi
+// FetchBbsDevices is modified to properly handle iSCSI drives. EIP#19614.
+//
+// 93 12/31/08 11:41a Olegi
+// Change in FetchBbsBootDevices: device class and subclass information is
+// taken from PCI configuration space, not from PnP header.
+//
+// 92 12/30/08 9:06a Olegi
+// Modification in CheckPciRom: added a check for a valid legacy OpROM
+// after calling FindEmbeddedRom. EIP#18520.
+//
+// 91 12/12/08 3:16p Olegi
+//
+// 90 12/09/08 4:06p Olegi
+//
+// 89 11/13/08 1:01p Olegi
+//
+// 88 11/12/08 4:58p Olegi
+// Modified InstallPciRom function that now calls LegacyBiosPlatform to
+// get the VGA switching policy override.
+//
+// 87 10/10/08 3:34p Olegi
+// Added PciRomAlreadyExecuted function.
+//
+// 86 9/23/08 2:18p Olegi
+//
+// 85 8/18/08 4:53p Olegi
+// Modified the rule that verifies the presence of KBC: port 64 is only
+// checked for 0xFF, checking for 0x00 is removed.
+//
+// 84 6/05/08 12:00p Olegi
+// - PreProcessRom execution is moved before checking for VGA OpROM is
+// installed.
+// - ShadowAllRoms function is modified to execute VGA OpROM if it was not
+// executed.
+//
+// 83 6/02/08 3:59p Olegi
+// Changes in InstallPciRom that address the memory deallocation issues.
+//
+// 82 5/21/08 5:00p Olegi
+// Bugfix in InstallPciRom: did not free up low memory for 3.0 OpROMs if
+// PreprocessOprom returned error.
+//
+// 81 5/19/08 12:37p Olegi
+// Removed EBDA size limitation.
+//
+// 80 5/09/08 3:26p Olegi
+//
+// 79 3/12/08 12:56p Olegi
+// PROGRESS_CODE((DXE_LEGACY_OPROM_NO_SPACE) is changed to
+// ERROR_CODE(DXE_LEGACY_OPROM_NO_SPACE, EFI_ERROR_MAJOR)
+//
+// 78 3/12/08 11:59a Olegi
+// Added progress status codes.
+//
+// 77 12/17/07 4:22p Olegi
+// KBC_SUPPORT dependency removed.
+//
+// 76 12/04/07 11:07a Olegi
+//
+// 75 10/17/07 3:25p Olegi
+// Replaced NextRomAddress with gNextRomAddress.
+//
+// 74 9/19/07 2:04p Olegi
+// Modified UnlockShadow to return the proper LockUnlockSize.
+//
+// 73 8/21/07 11:10a Olegi
+// Added Intel AHCI Option ROM in the list of PCI 3.0 pretenders
+//
+// 72 8/10/07 11:04a Olegi
+// VGA handling changed.
+//
+// 71 7/27/07 9:33a Olegi
+// PreprocessOpRom call is moved before the shadow memory is open.
+//
+// 70 7/12/07 5:47p Olegi
+// Save BX after dispatching Option ROM to use it later for # of non-BBS
+// compliant drives checking.
+//
+// 69 7/09/07 6:05p Olegi
+//
+// 68 7/09/07 6:04p Olegi
+// Change in FetchBbsDevices for nVIDIA MCP55 LAN device in bridge mode.
+//
+// 67 6/27/07 3:52p Olegi
+// Workaround for OpROMs that use 40:13 to allocate memory, not EBDA.
+//
+// 66 6/21/07 10:32a Olegi
+//
+// 65 6/18/07 5:45p Olegi
+// bugfix in InstallPciRom for non-BBS compliant card that traps int19
+//
+// 64 6/08/07 7:57a Olegi
+// Fix in FetchBbsBootDevices that properly creates CDROM, not HDD entry
+// for BEV mass storage devices.
+//
+// 63 6/04/07 12:34p Olegi
+//
+// 62 6/02/07 10:23a Olegi
+// Shadow size correction.
+//
+// 61 30/05/07 12:34p Anandakrishnanl
+// Updated LockShadow routine.
+//
+// 60 5/29/07 12:20p Olegi
+// Added the code to disable Shadow W/R for the unused shadow regions
+// after every OpROM execution.
+//
+// 59 4/27/07 5:13p Olegi
+// CSM.CHM file preparation.
+//
+// 58 4/12/07 1:30p Olegi
+//
+// 57 4/10/07 5:17p Olegi
+// PreprocessOptionRom call moved closer to the actual option ROM
+// execution.
+//
+// 56 3/29/07 5:38p Olegi
+// Temporarily revert the option rom code execution: from
+// DispatchOptionRom C function to CSM16 function #5.
+//
+// 55 3/01/07 9:11a Olegi
+//
+// 54 1/03/07 12:57p Felixp
+// New code introduced in label 4.5.3_CSM.6.32_41 had problems.
+// Option ROM handling reverted back to label 4.5.2_CSM.6.32_40
+//
+// 51 11/14/06 12:37p Olegi
+//
+// 50 9/22/06 6:13p Olegi
+// Introduction of DispatchOptionRom routine.
+//
+// 49 9/15/06 11:48a Markw
+// Removed warning. Added typecast.
+//
+// 48 8/24/06 6:49p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 47 8/22/06 9:08a Olegi
+// "pci30pretender" list is updated with the new Robson card VID/DID.
+//
+// 46 7/31/06 4:05p Olegi
+//
+// 45 7/28/06 4:49p Olegi
+//
+// 43 7/10/06 5:52p Ambikas
+//
+// 42 5/25/06 2:23p Olegi
+//
+// 41 5/16/06 1:57p Olegi
+//
+// 40 5/11/06 12:40p Fredericko
+// Make F000 segment writable along with OpROM shadow area for the cases
+// where F000 area needs to be updated during DispatchOptionRom call, e.g.
+// for non-BBS OpROMs.
+// TODO:: remove this call when OpROM handling is moved out of CSM16.
+//
+// 39 5/01/06 5:06p Olegi
+// Added checking for VGA class code in ShadowAllLegacyOproms: enabling
+// VGA devices is skipped.
+//
+// 38 5/01/06 3:23p Olegi
+// IsValidLegacyPciOpROM: removed checking for DID/VID as some OpROMs
+// might serve several devices.
+//
+// 37 4/24/06 8:37a Olegi
+//
+// 36 4/18/06 12:08p Olegi
+// Lock/Unlock PAM regions before and after OpROMs.
+//
+// 35 12/12/05 10:05a Felixp
+// Video driver disconnected before switching to text mode
+//
+// 34 11/29/05 4:17p Olegi
+// Get the run-time Option ROM size right after Oprom is executed; the
+// value of OpROMSeg:0002 can change later, for example after BCV
+// execution (noticed on PCI NetCell RAID SATA card).
+//
+// 33 10/13/05 6:22p Olegi
+// Added HW interrupt handling.
+//
+// 32 9/30/05 6:27p Olegi
+// VC7.1 compatibility issues solved.
+//
+// 31 9/29/05 5:19p Olegi
+// UpdateEbdaMap routine added.
+//
+// 26 8/02/05 11:26a Olegi
+// FetchBbsBootDevices returns if runtime size of OpROM equals 0.
+//
+// 23 6/22/05 8:35a Olegi
+// PCI3.0 support
+//
+// 22 6/21/05 12:12p Olegi
+// LegacyBios and LegacyBiosPlatform are combined into one FFS.
+//
+// 21 4/21/05 9:06a Olegi
+// Added the logic for switching the video mode.
+//
+// 20 4/19/05 11:12a Olegi
+// ShadowAllLegacyOproms function added.
+//
+// 16 3/04/05 1:52p Mandal
+//
+//****************************************************************************
+
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOpROM.c
+// Description: CSM PCI ROM interface routines
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "csm.h"
+#include <Protocol/PciIo.h>
+#include "token.h"
+#include <AmiDxeLib.h>
+#include "pci.h"
+#include <Protocol/PciIo.h>
+#include <Protocol/CsmPlatform.h>
+//#include <Protocol/ConsoleControl.h>
+#include "setup.h"
+
+#if LEGACYSREDIR_SUPPORT
+#include "Protocol\LegacySredir.h"
+#endif
+
+#if LEGACYSREDIR_SUPPORT
+EFI_LEGACY_SREDIR_PROTOCOL *gLegacySredir=NULL;
+#endif
+
+extern SETUP_DATA gSetup;
+
+extern UINT8 *gNextRomAddress;
+extern EXECUTED_PCI_ROM *gExecutedRomsPci;
+//extern EFI_GUID gPciIoProtocol;
+extern SAVED_PCI_ROM *gSavedOprom;
+
+EFI_HANDLE gVgaHandle = NULL;
+
+BOOLEAN gBbsUpdateInProgress = FALSE;
+
+//
+// gSetTxtMode
+// 0 - switching to text mode is needed
+// 1 - switching is needed, restoration is not
+// 2 - neither switching nor restoration is needed
+//
+extern UINT8 gSetTxtMode;
+extern BOOLEAN gServiceRomsExecuted;
+
+#pragma pack(push, 1)
+
+// EFI Load Option needed for call to LegacyBios->LegacyBoot()
+static struct {
+ EFI_LOAD_OPTION LoadOption;
+ CHAR16 Description[10];
+ BBS_BBS_DEVICE_PATH BbsDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL DevicePathEnd;
+} DummyLoadOption = {
+ { // EFI_LOAD_OPTION LoadOption
+ 0, // Attributes (UINT32)
+ sizeof (BBS_BBS_DEVICE_PATH)
+ + sizeof (EFI_DEVICE_PATH_PROTOCOL), // FilePathListLength (UINT16)
+ },
+
+ L"DummyLoad", // Description
+
+ { // BbsDevicePath
+ { // Header
+ BBS_DEVICE_PATH, // Type
+ BBS_BBS_DP, // Subtype
+ sizeof(BBS_BBS_DEVICE_PATH) // Length
+ },
+
+ BBS_HARDDISK, // DeviceType
+ 0, // StatusFlags
+ 0, // String
+ },
+
+ { // DevicePathEnd
+ END_DEVICE_PATH, // Type
+ END_ENTIRE_SUBTYPE, // SubType
+ sizeof(EFI_DEVICE_PATH_PROTOCOL) // Size
+ }
+};
+
+#pragma pack(pop)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: IsValidLegacyPciOpROM
+//
+// Description: Tests PCI ROM for Legacy PCI ROM compatibility.
+//
+// Output:
+// TRUE - Image is valid
+// FALSE - Image is not valid
+//
+// Notes:
+// From PCI Fw Specification 3.0, 5.2.1.21. Backward Compatibility of Option ROMs Page # 86.
+// It is also possible to have two separate ROM images for the same PCI device: one for PCI 2.1
+// System Firmware and one for PCI 3.0 compliance. In this case, the PCI 2.1 Option ROM image
+// must appear first in the sequence of images. PCI 3.0 System Firmware will first search for a
+// PCI 3.0 Option ROM image and only use the PCI 2.1 Option ROM image if no PCI 3.0 Option ROM
+// image is found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsValidLegacyPciOpROM (
+ IN UINT32 VidDid, // PCI vendor ID/Device ID
+ IN OUT VOID **Image, // Pointer to the beginning of PCI Option ROM
+ IN OUT UINTN *Size // Input: PciIo->RomSize, Output: OpROM size in bytes
+)
+{
+ PCI_DATA_STRUCTURE *pcir;
+ BOOLEAN IsLastImage = FALSE;
+ UINT8 *RomStart = *Image;
+ UINTN RomSize = 0;
+ BOOLEAN FoundLegacyRom = FALSE;
+ UINTN RomEnd = (UINTN)*Image + *Size;
+
+ for(; !IsLastImage, (UINTN)RomStart < RomEnd; ) {
+ //
+ // Check for 55AA in the beginning of the image
+ //
+ if (((LEGACY_OPT_ROM_HEADER*)RomStart)->Signature != 0xaa55) {
+ RomStart += 512;
+ continue;
+ }
+
+ //
+ // Validate "PCIR" data
+ //
+ pcir = (PCI_DATA_STRUCTURE *)(RomStart + *(UINT16*)(RomStart + 0x18));
+ if (pcir->Signature != 0x52494350) return FALSE; // "PCIR"
+
+ IsLastImage = pcir->Indicator & 0x80;
+
+ // Code Type Description
+ // 0x00 Intel IA-32, PC-AT compatible
+ // 0x01 Open Firmware standard for PCI
+ // 0x02 Hewlett-Packard PA RISC
+ // 0x03 EFI Image
+ // 0x04-0xFF Reserved
+ //
+ if (pcir->CodeType == 0) { // IA-32, PC-AT compatible
+
+ if (pcir->Revision != 3 && FoundLegacyRom)
+ {
+ // More than one legacy OpROM is present with revision less
+ // than 3.0; return the pointer and the size of the previous one.
+ // Image and Size are updated when FoundLegacyRom became TRUE.
+ // This implements backward compatibility mentioned in the notes
+ // above.
+ //
+ return TRUE;
+ }
+
+ RomSize = ((LEGACY_OPT_ROM_HEADER*)RomStart)->Size512 << 9;
+
+ if (RomSize == 0) return FALSE;
+
+ *Image = RomStart;
+ *Size = RomSize;
+
+ if (pcir->Revision == 3) return TRUE;
+
+ FoundLegacyRom = TRUE;
+ RomStart += RomSize;
+ continue;
+ }
+
+ // Non-legacy ROM; find the size from "PCIR" structure
+ RomSize = pcir->ImageLength << 9;
+ RomStart += RomSize;
+ }
+
+ return FoundLegacyRom;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: UpdateEbdaMap
+//
+// Description: This routine is called after every OpROM (BBS or non-BBS) is
+// executed. It updates the locations of EBDA in SAVED_PCI_ROM.ebdaAddr
+// fields after OpROM expands EBDA.
+//
+// Input: The size of EBDA created by the OpROM
+//
+// Output: None
+//
+// Notes: When this function is called SAVED_PCI_ROM structure will not have
+// the current OpROM information inserted; gSavedOprom is pointing to NULL
+// located right after the last valid entry (1st entry is also NULL).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UpdateEbdaMap(UINT32 AddrChange)
+{
+ SAVED_PCI_ROM *SavedOprom;
+
+ //
+ // for every SAVED_PCI_ROM update ebdaAddr
+ //
+ for (SavedOprom=gSavedOprom-1; SavedOprom->Address; SavedOprom--) {
+ if (SavedOprom->isEbda && SavedOprom->rtDataAddr) {
+ SavedOprom->rtDataAddr -= AddrChange;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SaveOprom
+//
+// Description: This routine saves Oprom that was just executed to the next
+// gSavedOprom data field; gSavedOprom is incremented.
+//
+// Input: Rom address
+// Address and size or runtime data taken during ROM initialization
+//
+// Notes: Saving Oprom data is only required for the option ROMs that
+// produce BCV because of early BCV execution; it should not be
+// called for non-BBS compliant OpROMs, for those OpROMs related
+// memory context will be the same til the system is booted.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SaveOprom (
+ UINT8 *Rom,
+ UINT8 *RtDataAddr,
+ UINT32 RtDataSize,
+ BOOLEAN IsEbda,
+ UINT32 EbdaOffset
+)
+{
+ UINTN RomSize = ((LEGACY_OPT_ROM_HEADER*)Rom)->Size512 << 9;
+
+ if (RomSize==0) return;
+ pBS->AllocatePool(EfiBootServicesData, RomSize, &gSavedOprom->Data);
+ pBS->CopyMem(gSavedOprom->Data, Rom, RomSize);
+ gSavedOprom->Address = Rom;
+ //
+ // Save runtime data associated with this ROM
+ //
+ if (RtDataSize) {
+ ASSERT(RtDataAddr); // if size is not zero, address must not be zero
+ gSavedOprom->rtDataAddr = RtDataAddr;
+ gSavedOprom->rtDataSize = RtDataSize;
+ gSavedOprom->isEbda = IsEbda;
+ gSavedOprom->ebdaOffset = EbdaOffset;
+ pBS->AllocatePool(EfiBootServicesData, RtDataSize, &gSavedOprom->rtData);
+ pBS->CopyMem(gSavedOprom->rtData, RtDataAddr, RtDataSize);
+ }
+ gSavedOprom++; // Points to zero address/data now.
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ExecuteBcv
+//
+// Description:
+// Checks if the platform allows BCV execution; if so, executes BCV and logs
+// the status of HW interrupt changes.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ExecuteBcv (
+ BIOS_INFO *BiosInfo,
+ UINT8 *PciCfg,
+ UINT16 BcvSeg,
+ UINT16 BcvOfs,
+ UINT8 *Disk
+)
+{
+ EFI_STATUS Status;
+ UINTN TotalDevices;
+ UINT32 *DeviceList;
+ UINTN Counter;
+ EFI_IA32_REGISTER_SET RegSet;
+ UINT8 Irq;
+ UINT32 *Ivt = (UINT32*)0;
+ UINT32 IrqHandler = 0;
+
+ Status = BiosInfo->iBiosPlatform->GetPlatformInfo(BiosInfo->iBiosPlatform,
+ EfiGetBcvSkipDeviceList,
+ &DeviceList,
+ &TotalDevices,
+ NULL, NULL, 0, 0);
+
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ if (TotalDevices > 0 && *DeviceList == 0xffffffff) return EFI_UNSUPPORTED; // Force to skip BCV execution
+
+ for (Counter = 0; Counter < TotalDevices; Counter++)
+ {
+ if (*(UINT32*)PciCfg == DeviceList[Counter]) return EFI_UNSUPPORTED;
+ }
+
+ // Get the hardware interrupt vector and its handler pointer
+ Irq = *(PciCfg+0x3C);
+ if (Irq > 0 && Irq < 0xF)
+ {
+ Status = BiosInfo->i8259->GetVector (BiosInfo->i8259, Irq, &Irq); // irq has INT number
+ ASSERT_EFI_ERROR(Status);
+ IrqHandler = Ivt[Irq];
+ }
+
+ //
+ // Execute BCV
+ //
+ pBS->SetMem (&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.ES = BiosInfo->Csm16Header->PnPInstallationCheckSegment;
+ RegSet.X.DI = BiosInfo->Csm16Header->PnPInstallationCheckOffset;
+
+ FarCall86 (&BiosInfo->iBios,
+ BcvSeg,
+ BcvOfs,
+ &RegSet,
+ NULL,
+ 0);
+ if (IrqHandler && (Ivt[Irq] != IrqHandler)) {
+ *Disk |= 0x40; // Indicate BCV has hooked HW IRQ
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: FetchBbsBootDevices
+//
+// Description: Check PCI ROM for PnP structures and inserts BCV/BEV devices
+// into BBS table.
+//
+// Input: Pointer to PCI ROM.
+//
+// Output: Number of devices installed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+FetchBbsBootDevices(
+ BIOS_INFO *BiosInfo,
+ UINT8 *Rom,
+ UINT8 *PciCfgOfs8,
+ UINTN Bus, UINTN Dev, UINTN Fun,
+ UINT8 *DiskFrom,
+ BOOLEAN NewInt18,
+ BOOLEAN NewInt19)
+{
+ UINT16 BbsDevType, bbsDevType;
+ PCI_PNP_EXPANSION_HEADER *PnpHdr;
+ UINT16 PnpSeg = (UINT16)((UINTN)Rom >> 4);
+ UINT16 PnpOfs;
+ BBS_TABLE *BbsTable = BiosInfo->BbsTable;
+ UINT8 BbsCount;
+ UINT32 *ivt = (UINT32*)0;
+ UINT8 i, Checksum;
+
+ gBbsUpdateInProgress = TRUE;
+
+ BbsCount = BiosInfo->BbsEntriesNo;
+
+ //
+ // Get BBS device type
+ //
+TRACE((-1, "FetchBbsBootDevices: B%x/D%x/F%x, ClassCode %x\n", Bus, Dev, Fun, *(PciCfgOfs8+0xB)));
+
+ if (Bus|Dev|Fun) {
+ switch (*(PciCfgOfs8+0xB)) { // class code
+ case PCI_CL_SYSTEM_PERIPHERALS:
+ if(*(PciCfgOfs8+0xA) == PCI_CL_SYSTEM_PERIPHERALS_SCL_SD) {
+ BbsDevType = BBS_HARDDISK;
+ } else {
+ BbsDevType = BBS_UNKNOWN;
+ }
+ break;
+ case PCI_CL_MASS_STOR:
+ case PCI_CL_I2O: BbsDevType = BBS_HARDDISK; break;
+ case PCI_CL_NETWORK: BbsDevType = BBS_EMBED_NETWORK; break;
+ case PCI_CL_BRIDGE: BbsDevType = BBS_EMBED_NETWORK; //for nVIDIA MCP55 LAN device is bridge mode
+ break;
+ case PCI_CL_SER_BUS: BbsDevType = BBS_BEV_DEVICE; break;
+
+ default: BbsDevType = BBS_UNKNOWN;
+ }
+ } else {
+ BbsDevType = BBS_EMBED_NETWORK; // Service ROMs
+ }
+ //
+ // Get PnP information from ROM header and fill BBS structures
+ //
+ PnpOfs = *((UINT16*)(Rom + 0x1A));// Offset of the 1st PnP header
+ for (;;PnpOfs = (UINT16)PnpHdr->NextHeaderOffset) {
+ PnpHdr = (PCI_PNP_EXPANSION_HEADER*) (Rom + PnpOfs);
+ if (*((UINT32*)PnpHdr) != 0x506E5024) break; // "$PnP"
+
+ //
+ // Calculate the CheckSum and check if table is valid
+ //
+ Checksum = 0;
+ for (i = 0; i < sizeof(PCI_PNP_EXPANSION_HEADER); i++){
+ Checksum += *(((UINT8*)PnpHdr) + i);
+ }
+ if (Checksum) continue;
+
+ if (PnpHdr->BCV == 0 && PnpHdr->BEV == 0 &&
+ !(NewInt18 || NewInt19)) continue;
+
+ //
+ // Change BbsType from BBS_HARDDISK to BBS_CDROM if BCV==0 and BEV!=0
+ //
+ bbsDevType = BbsDevType;
+ if (BbsDevType == BBS_HARDDISK && (!PnpHdr->BCV) && PnpHdr->BEV) {
+ bbsDevType = BBS_CDROM;
+ }
+ if (PnpHdr->BCV != 0) {
+ bbsDevType = BBS_HARDDISK;
+ }
+
+ BbsTable[BbsCount].DeviceType = bbsDevType;
+ BbsTable[BbsCount].Bus = (UINT32)Bus;
+ BbsTable[BbsCount].Device = (UINT32)Dev;
+ BbsTable[BbsCount].Function = (UINT32)Fun;
+ BbsTable[BbsCount].Class = *(PciCfgOfs8+0xB);
+ BbsTable[BbsCount].SubClass = *(PciCfgOfs8+0xA);
+ BbsTable[BbsCount].DescStringSegment = PnpSeg;
+ BbsTable[BbsCount].DescStringOffset = PnpHdr->ProductNamePtr;
+ BbsTable[BbsCount].MfgStringSegment = PnpSeg;
+ BbsTable[BbsCount].MfgStringOffset = PnpHdr->MfgPtr;
+ BbsTable[BbsCount].BootPriority = BBS_UNPRIORITIZED_ENTRY;
+ BbsTable[BbsCount].BootHandlerSegment = PnpSeg;
+ if (NewInt18) {
+ BbsTable[BbsCount].AdditionalIrq18Handler = ivt[0x18];
+ BbsTable[BbsCount].BootHandlerOffset = ivt[0x18];
+ }
+ if (NewInt19) {
+ BbsTable[BbsCount].AdditionalIrq19Handler = ivt[0x19];
+ BbsTable[BbsCount].BootHandlerOffset = ivt[0x19];
+ }
+
+ if (PnpHdr->BCV) {
+ BbsTable[BbsCount].BootHandlerOffset = PnpHdr->BCV;
+ ExecuteBcv(BiosInfo, PciCfgOfs8, PnpSeg, PnpHdr->BCV, DiskFrom);
+ }
+ if (PnpHdr->BEV && !(NewInt18 || NewInt19)) {
+ BbsTable[BbsCount].BootHandlerOffset = PnpHdr->BEV;
+ }
+
+ BbsCount++;
+ }
+
+ //
+ // Update number of BBS entries
+ //
+ BiosInfo->BbsEntriesNo = BbsCount;
+ gBbsUpdateInProgress = FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Check30ROM
+//
+// Description: Verifies whether the passed PCI ROM image is PCI 3.0 compatible.
+// If so, returns the projected (runtime) size of this ROM.
+//
+// Output: TRUE - image is PCI 3.0 compliant ROM, size is updated
+// FALSE - image is not PCI 3.0 compliant ROM, size remains untouched.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+Check30ROM(
+ IN VOID *RomLocation,
+ IN OUT UINTN *Size,
+ IN EFI_HANDLE PciHandle
+)
+{
+ PCI_DATA_STRUCTURE *pcir;
+ EFI_STATUS Status;
+ // TODO:: move this patchy data elswhere
+ static UINT32 pci30pretender[] = {
+ 0x00041103, // Adaptec 1200 (did 0004 vid 1103)
+ 0x444d8086, // Intel ROBSON Technology card (444D)
+ 0x444e8086, // Intel ROBSON Technology card (444E)
+ 0x26818086 // Intel AHCI Option ROM
+ };
+
+ //
+ // Check for 55AA in the beginning of the image
+ //
+ if (((LEGACY_OPT_ROM_HEADER*)RomLocation)->Signature != 0xAA55) return FALSE;
+ //
+ // Validate "PCIR" data
+ //
+ pcir = (PCI_DATA_STRUCTURE *)((UINT8*)RomLocation + *(UINT16*)((UINT8*)RomLocation + 0x18));
+ if (pcir->Signature != 0x52494350) return FALSE; // "PCIR"
+
+ if (pcir->Revision == 3) {
+ UINT8 i; // check for the OpROMs that are faking PCI3.0 compatibility
+ UINT32 VidDid;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ if (PciHandle != NULL) {
+
+ Status = pBS->HandleProtocol(PciHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ ASSERT(PciIo);
+
+ if (EFI_ERROR(Status)) return FALSE;
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32,
+ 0, // offset
+ 1, // width
+ &VidDid);
+ ASSERT_EFI_ERROR(Status);
+
+ for (i=0; i<(sizeof(pci30pretender)/sizeof(pci30pretender[0])); i++) {
+ if (pci30pretender[i] == VidDid) return FALSE;
+ }
+ }
+
+ *Size = pcir->Reserved1 << 9; // Follow PCI.H definitions
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CheckPciRom
+//
+// Description: Tests to see if a traditional PCI ROM exists for this device
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// PciHandle The handle for this device. Type EFI_HANDLE is defined in
+// InstallProtocolInterface() in the EFI 1.10 Specification.
+// RomImage Pointer to the ROM image.
+// RomSize The size of the ROM image.
+// Flags The type of ROM discovered. Multiple bits can be set, as follows:
+// 00 = No ROM
+// 01 = ROM Found
+// 02 = ROM is a valid legacy ROM
+//
+// Output: EFI_SUCCESS A traditional OpROM is available for this device.
+// EFI_UNSUPPORTED A traditional OpROM is not supported.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CheckPciRom (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ OUT VOID **RomImage, OPTIONAL
+ OUT UINTN *RomSize, OPTIONAL
+ OUT UINTN *Flags
+)
+{
+ EFI_PCI_IO_PROTOCOL *pPciIo;
+ UINT32 VidDid;
+ VOID *PciRom;
+ UINTN PciRomSize = 0;
+ EFI_STATUS Status;
+ BOOLEAN ValidRom = FALSE;
+ UINTN RomStatus = 0;
+ PCI_STD_DEVICE Pci;
+ EXECUTED_PCI_ROM *ExecutedRom = gExecutedRomsPci-1;
+ EXECUTED_PCI_ROM *er;
+ UINTN PciSegment, PciBus, PciDeviceNumber, PciFunction;
+
+ Status = pBS->HandleProtocol(PciHandle, &gEfiPciIoProtocolGuid, &pPciIo);
+ if (EFI_ERROR(Status) || (&pPciIo == NULL)) return EFI_UNSUPPORTED;
+
+ PciRom = pPciIo->RomImage;
+
+ Status = pPciIo->Pci.Read(pPciIo,
+ EfiPciIoWidthUint32,
+ 0, // offset
+ 1, // width
+ &VidDid);
+ ASSERT_EFI_ERROR(Status);
+
+ if (PciRom) {
+ PciRomSize = (UINTN)pPciIo->RomSize;
+ ValidRom = IsValidLegacyPciOpROM(VidDid, &PciRom, &PciRomSize);
+ RomStatus = ValidRom? 2 : 1;
+ }
+ if (!ValidRom) {
+ Status = GetPlatformPciEmbeddedRom(pPciIo, &PciRom, &PciRomSize);
+
+ if (EFI_ERROR(Status)) {
+ Status = FindEmbeddedRom(OPROM_MODULEID, (UINT16)VidDid,
+ *((UINT16*)&VidDid+1), &PciRom, &PciRomSize);
+ }
+
+ //
+ // Check whether the identified ROM is a legacy OptionROM,
+ // and correspondingly modify the value of "RomStatus".
+ // Note: PciRomSize is initialized here
+ if (!EFI_ERROR(Status)) {
+ ValidRom = IsValidLegacyPciOpROM(VidDid, &PciRom, &PciRomSize);
+ RomStatus = ValidRom? 2 : 1;
+ }
+ }
+
+ if(!ValidRom) {
+
+ Status = pPciIo->GetLocation(pPciIo,
+ &PciSegment, &PciBus, &PciDeviceNumber, &PciFunction);
+
+ //
+ // Sd option rom can handle all the function on one time
+ // So if any of one of the function on device already launched option
+ // no need to launch the option rom for other functions.
+ //
+ for (er = ExecutedRom; er->Seg | er->Bus | er->Dev | er->Fun; er--) {
+ if (er->Seg == PciSegment && er->Bus == PciBus &&
+ er->Dev == PciDeviceNumber) {
+ break;
+ }
+ }
+
+ //
+ //SD option can handle all the function. So don't launch option for other functions.
+ //
+ if(!(er->Seg | er->Bus | er->Dev | er->Fun)) {
+
+ Status = pPciIo->Pci.Read (pPciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci);
+ //
+ //Check For SD controller. If it's SD controller find Sd option rom and launch it.
+ //
+ if ( Pci.Header.ClassCode[1] == PCI_CL_SYSTEM_PERIPHERALS_SCL_SD && \
+ Pci.Header.ClassCode[2] == PCI_CL_SYSTEM_PERIPHERALS ) {
+ Status=FindEmbeddedRom( CSM16_MODULEID, CSM16_VENDORID, CSM16_SD_BOOT_DID, &PciRom, &PciRomSize);
+ if (!EFI_ERROR(Status)) {
+ ValidRom = IsValidLegacyPciOpROM(VidDid, &PciRom, &PciRomSize);
+ RomStatus = ValidRom? 2 : 1;
+ }
+ }
+ }
+ }
+
+ *Flags = RomStatus;
+
+ if (RomStatus == 2) {
+ if (RomImage != NULL) *RomImage = PciRom;
+ if (RomSize != NULL) *RomSize = PciRomSize;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: FindAnyVga
+//
+// Description: Returns the first VGA controller handle from PciIo device list.
+//
+// Input: None
+//
+// Output: PCI VGA controller PciIo handle
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FindAnyVga(
+ OUT EFI_HANDLE* hVga
+)
+{
+ EFI_HANDLE *HandleBuffer;
+ UINTN n, HandleCount;
+ EFI_STATUS Status;
+ UINT8 dData[4];
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS VgaStatus = EFI_NOT_FOUND;
+
+ //
+ // Locate all PciIo handles
+ //
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer);
+
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ for (n = 0 ; n < HandleCount; n++) {
+
+ Status = pBS->HandleProtocol (
+ HandleBuffer[n],
+ &gEfiPciIoProtocolGuid,
+ &PciIo); // Get PciIo protocol
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) break;
+
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint32,
+ 8, // offset
+ 1, // width
+ dData);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) break;
+
+ if (dData[3]==PCI_CL_DISPLAY) {
+ *hVga = HandleBuffer[n];
+ VgaStatus = EFI_SUCCESS;
+ break;
+ }
+ }
+ pBS->FreePool(HandleBuffer);
+ return VgaStatus;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: PciRomAlreadyExecuted
+//
+// Description: Reports whether OpROM for a given PciIo already executed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EXECUTED_PCI_ROM*
+PciRomAlreadyExecuted(
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+)
+{
+ UINTN Seg, Bus, Dev, Fun;
+ EXECUTED_PCI_ROM *ExecutedRom;
+ EFI_STATUS Status;
+
+
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Fun);
+ ASSERT_EFI_ERROR(Status);
+
+ for (ExecutedRom = gExecutedRomsPci-1;
+ ExecutedRom->Seg | ExecutedRom->Bus | ExecutedRom->Dev | ExecutedRom->Fun;
+ ExecutedRom--)
+ {
+ if (ExecutedRom->Seg == Seg && ExecutedRom->Bus == Bus &&
+ ExecutedRom->Dev == Dev && ExecutedRom->Fun == Fun) {
+ return ExecutedRom;
+ }
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CheckEnablePciSiblings
+//
+// Description:
+// This function manages the ability of the Option ROM to control several PCI
+// devices in the system.
+// For example, SCSI Option ROM designed for the multi-channel SCSI adaptor
+// usually controls all the channels even though they are different PCI
+// functions of the same device. Likewise, NIC Option ROM may be able to control
+// several NICs located on different PCI devices or even on different PCI buses.
+//
+// Input:
+// PciIo - PCI I/O protocol of the PCI device whose Option ROM is about
+// to be executed
+// PciCfgData - byte array of device's PCI configuration space (registers 0..3f)
+//
+// Output:
+// EFI_SUCCESS - Option ROM is okay execute
+// EFI_ALREADY_STARTED - Option ROM must be skipped
+//
+// Notes:
+// Function code flow:
+// 1) Execute OEM porting hook to see if OEM overrides the default device enable
+// policy. If so, return EFI_ALREADY_STARTED.
+// 2) Enable all function of the given PciIo.
+// 3) Enable all PCI devices with the same VID/DID as in given PciIo.
+// 4) Return EFI_SUCCESS indicating "greenlight" for Option ROM execution.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckEnablePciSiblings(
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 *PciCfgData
+)
+{
+ EFI_STATUS Status;
+ EXECUTED_PCI_ROM *ExecutedRom = gExecutedRomsPci-1;
+ EFI_HANDLE *HandleBuffer;
+ UINTN Count;
+ UINTN HandleCount;
+ UINTN PciSegment, PciBus, PciDeviceNumber, PciFunction;
+ UINTN Seg, Bus, Dev, Func;
+ EFI_PCI_IO_PROTOCOL *CurrentPciIo;
+ UINT64 Capabilities;
+ UINT32 VidDid;
+ UINT8 PciCfgData1[40];
+ Status = pBS->LocateHandleBuffer (ByProtocol, &gEfiPciIoProtocolGuid,
+ NULL, &HandleCount, &HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CheckOemPciSiblings(PciIo, ExecutedRom);
+ if (Status == EFI_SUCCESS) return EFI_ALREADY_STARTED;
+
+ Status = EnableOemPciSiblings(PciIo);
+ if (Status == EFI_SUCCESS) return EFI_SUCCESS;
+
+
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Func);
+ ASSERT_EFI_ERROR(Status);
+
+ for (Count = 0; Count < HandleCount; Count++) {
+ Status = pBS->HandleProtocol (HandleBuffer[Count], &gEfiPciIoProtocolGuid, &CurrentPciIo);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CurrentPciIo->GetLocation(CurrentPciIo,
+ &PciSegment, &PciBus, &PciDeviceNumber, &PciFunction);
+
+ // Check if it is the same device
+ if (PciBus == Bus && PciDeviceNumber == Dev && PciFunction == Func) continue;
+
+ Status = CurrentPciIo->Pci.Read(CurrentPciIo, EfiPciIoWidthUint32, 0, 1, &VidDid);
+ ASSERT_EFI_ERROR(Status);
+
+ // Do not do anything else for VGA; if multiple VGA is enabled at the same time,
+ // OS might have a problem. EIP60317.
+ Status = CurrentPciIo->Pci.Read(CurrentPciIo, EfiPciIoWidthUint8, 0, 40, PciCfgData1);
+ ASSERT_EFI_ERROR(Status);
+ if (PciCfgData1[0xb] == PCI_CL_DISPLAY) continue;
+
+ // Check if it is a different function of the same device or if VID/DID is the same
+ if ((PciBus == Bus && PciDeviceNumber == Dev)
+ || (*(UINT32*)PciCfgData == VidDid)) {
+
+ Status = CurrentPciIo->Attributes (CurrentPciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CurrentPciIo->Attributes (CurrentPciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+ ASSERT_EFI_ERROR(Status);
+ TRACE((TRACE_ALWAYS,
+ "CSM OPROM: device B%x/d%x/F%x was enabled for B%x/d%x/F%x OPROM execution.\n",
+ PciBus, PciDeviceNumber, PciFunction, Bus, Dev, Func));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ClpExecute
+//
+// Description:
+// This is CLP execution protocol function that is called by any driver that
+// needs to perform device configuration using Command Line Protocol.
+//
+// Input:
+// PciIo Command Line Protocol instance pointer
+// CmdInputLine Pointer to a null-terminated input string
+// CmdResponseBuffer Pointer to command output buffer
+// CmdStatus CLP command execution status
+//
+// Output:
+// EFI_SUCCESS Execution succeeded, result is in CmdStatus
+// Any other value Error status of the execution
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ClpExecute (
+ IN EFI_CLP_PROTOCOL *This,
+ IN OUT UINT8 *CmdInputLine,
+ IN OUT UINT8 *CmdResponseBuffer,
+ OUT UINT32 *CmdStatus
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN FarCallStatus;
+ EFI_IA32_REGISTER_SET RegSet;
+ static EFI_LEGACY_BIOS_PROTOCOL *LegacyBios = NULL;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Seg, Bus, Dev, Fun;
+
+ // Get LegacyBios protocol for FarCall86 execution
+ if (LegacyBios == NULL) {
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ // Get PciIo protocol for the PCI bus/dev/func information
+ Status = pBS->HandleProtocol(This->Handle, &gEfiPciIoProtocolGuid, &PciIo);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Fun);
+
+ // Prepare the registers for CLP execution
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.H.AH = (UINT8)Bus;
+ RegSet.H.AL = ((UINT8)Dev << 3) | (UINT8)Fun;
+ RegSet.E.EDI = (UINT32)(UINTN)CmdInputLine;
+ RegSet.E.ESI = (UINT32)(UINTN)CmdResponseBuffer;
+
+ // Execute CLP command
+ FarCallStatus = FarCall86 (LegacyBios,
+ This->EntrySeg,
+ This->EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+
+ if (FarCallStatus == FALSE) {
+ Status = EFI_SUCCESS;
+ *CmdStatus = RegSet.E.EAX;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitClp
+//
+// Description:
+// This function is initializing and installing the CLP protocol.
+//
+// Input:
+// Handle PCI device handle
+// Csm16DOT Option ROM related data structure
+//
+// Output:
+// EFI_SUCCESS CLP protocol successfully installed
+// EFI_UNSUPPORTED CLP protocol can not be installed on this device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitClp (
+ IN EFI_HANDLE Handle,
+ IN EFI_DISPATCH_OPROM_TABLE *Csm16DOT
+)
+{
+ UINT8 *RomLocation;
+ PCI_PCIR30_DATA_STRUCTURE *Pcir;
+ EFI_CLP_PROTOCOL *ClpProtocol;
+ EFI_STATUS Status;
+ static EFI_GUID guidClp = EFI_CLP_PROTOCOL_GUID;
+
+ RomLocation = (UINT8*)(UINTN)((UINT32)Csm16DOT->OpromSegment << 4);
+
+ Pcir = (PCI_PCIR30_DATA_STRUCTURE *)(RomLocation + *(UINT16*)(RomLocation + 0x18));
+
+ if (Pcir->Signature != 0x52494350) {
+ TRACE((-1, "Init CLP: PCIR signature is missing."));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Pcir->Revision < 3) {
+ TRACE((-1, "Init CLP: CLP support requires PCI version 3.0 or above."));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Pcir->ClpEntryPoint == 0) {
+ TRACE((-1, "Init CLP: CLP entry point is not present."));
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Handle == NULL) {
+ TRACE((-1, "Init CLP: CLP ROM must be associated with PCI device."));
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(EFI_CLP_PROTOCOL), &ClpProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ ClpProtocol->Handle = Handle;
+ ClpProtocol->EntrySeg = Csm16DOT->OpromSegment;
+ ClpProtocol->EntryOfs = Pcir->ClpEntryPoint;
+ ClpProtocol->Execute = ClpExecute;
+
+ return pBS->InstallProtocolInterface(
+ &Handle, &guidClp, EFI_NATIVE_INTERFACE, ClpProtocol);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CsmInstallRom
+//
+// Description: Executes a given ROM using parameters pre-defined as input in
+// EFI_DISPATCH_OPROM_TABLE data structure.
+//
+// Input:
+// CoreBiosInfo The pointer to the BIOS_INFO variable
+// PciIo PCI IO handle, NULL for non-PCI ROMs
+// Csm16DOT ROM execution input parameters
+// NextRomAddress The location in the shadow that will have the run-time image
+// of the ROM
+// IsVga Video ROM indicator
+//
+// Output:
+// NewRomSize Run-time size of the ROM, in Bytes
+// ProcessBootDevices Indicator of the new bootable devices found during
+// ROM execution
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmInstallRom (
+ IN BIOS_INFO *CoreBiosInfo,
+ IN EFI_HANDLE Handle,
+ IN EFI_DISPATCH_OPROM_TABLE *Csm16DOT,
+ IN UINTN NextRomAddress,
+ IN BOOLEAN IsVga,
+ OUT UINT32 *NewRomSize,
+ OUT BOOLEAN *ProcessBootDevices
+)
+{
+ UINT16 ebdaSeg1, ebdaSeg2; // ebda pointer before and after OpROM execution
+ UINT16 baseMem1, baseMem2; // 40:13 before and after OpROM execution
+ UINT32 ebdaSize1, ebdaSize2; // ebda size before and after OpROM execution
+ BOOLEAN IsEbda;
+ UINT8 ebdaSizeKB;
+ EFI_IA32_REGISTER_SET RegSet;
+ UINT16 RegBX;
+ UINT8 *RtData = NULL;
+ UINT32 RtDataSize;
+ UINT32 RtRomSize;
+ UINTN SetTxtMode;
+ EFI_STATUS Status;
+ UINT32 CurrentInt10 = 0;
+ UINT8 CurrentMode = 0;
+ BOOLEAN VgaWasConnected = FALSE;
+// static EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+ UINT32 EbdaOffset;
+ EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+ EFI_PCI_IO_PROTOCOL *VgaPciIo;
+ static UINT8 LegacyVgaStartCounter = 0;
+ UINT64 VgaCapabilities;
+
+ if (Handle != NULL) {
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiPciIoProtocolGuid,
+ &PciIo);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ // Call LegacyBiosPlatform to get the VGA switching policy override
+
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformOpromVideoMode,
+ &PciIo,
+ &SetTxtMode,
+ 0,
+ 0,
+ (UINT16)gSetTxtMode,
+ 0);
+ if (EFI_ERROR(Status)) {
+ SetTxtMode = (UINTN)gSetTxtMode;
+ }
+
+ if (IsVga) {
+ LegacyVgaStartCounter++;
+ } else {
+ // If it is not for VGA, than video mode might be forced to 3 for compatibility.
+ // Current video mode is saved before the call and restored afterwards.
+ DisconnectSerialIO();
+ if (SetTxtMode != 2 && SetTxtMode != 3) {
+ CurrentMode = *(UINT8*)(UINTN)0x449;
+ Status = pBS->DisconnectController(gVgaHandle, NULL, NULL);
+
+ // Note: later VgaWasConnected is checked only for SetTxtMode == 0
+
+ VgaWasConnected = (BOOLEAN)(Status == EFI_SUCCESS);
+
+ if (VgaWasConnected) {
+ UINT64 Capabilities;
+ //
+ // VGA was successfully disconnected. Store the current attributes (to
+ // be restored after executing OptionROM), and enable MEM/IO/VGA
+ // decoding according to the supported attributes
+ //
+ Status = pBS->HandleProtocol (
+ gVgaHandle,
+ &gEfiPciIoProtocolGuid,
+ &VgaPciIo);
+ ASSERT_EFI_ERROR(Status);
+
+ // Store the attributes set by DisconnectController
+ Status = VgaPciIo->Attributes (VgaPciIo, EfiPciIoAttributeOperationGet, 0,
+ &VgaCapabilities);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = VgaPciIo->Attributes (VgaPciIo, EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities);
+ ASSERT_EFI_ERROR(Status);
+
+ // Enable VGA legacy MEM/IO access, do not check the status
+ VgaPciIo->Attributes (VgaPciIo, EfiPciIoAttributeOperationEnable,
+ (Capabilities & EFI_PCI_DEVICE_ENABLE)
+ | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL);
+ }
+
+// if (ConsoleControl == NULL) {
+// Status = pBS->LocateProtocol(&gEfiConsoleControlProtocolGuid,NULL,&ConsoleControl);
+// if (!EFI_ERROR(Status)) {
+// Status = ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenText);
+// ASSERT_EFI_ERROR(Status);
+// }
+// }
+ }
+
+#if LEGACYSREDIR_SUPPORT
+ // Enable Legacy Serial Redirection if enabled in the project
+ pBS->LocateProtocol (
+ &gEfiLegacySredirProtocolGuid,
+ NULL,
+ &gLegacySredir
+ );
+ if(gLegacySredir != NULL) {
+ gLegacySredir->EnableLegacySredir(gLegacySredir);
+ }
+#endif
+
+ if (SetTxtMode == 2) {
+ CurrentInt10 = *(UINT32*)(UINTN)0x40;
+ *(UINT32*)(UINTN)0x40 = 0xf000f065; // legacy int10
+ }
+ }
+
+ // Initialize CLP (Command Line Protocol) support for this ROM
+ Status = InitClp(Handle, Csm16DOT);
+
+ //
+ // Save the current EBDA location to check if OpROM modifies it
+ ebdaSeg1 = *(UINT16*)(UINTN)0x40e;
+ ebdaSizeKB = *(UINT8*)((UINTN)ebdaSeg1<<4);
+ ebdaSize1 = (UINT32)ebdaSizeKB << 10;
+ ASSERT(ebdaSizeKB); // should be initialized, can not be 0
+ baseMem1 = *(UINT16*)(UINTN)0x413;
+
+ // Execute OpROM
+
+// Status = DispatchOptionRom(CoreBiosInfo, Csm16DOT);
+// ASSERT_EFI_ERROR(Status);
+
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = Compatibility16DispatchOprom;
+ RegSet.X.ES = EFI_SEGMENT (Csm16DOT);
+ RegSet.X.BX = EFI_OFFSET (Csm16DOT);
+
+ FarCall86 (&CoreBiosInfo->iBios,
+ CoreBiosInfo->Csm16EntrySeg,
+ CoreBiosInfo->Csm16EntryOfs,
+ &RegSet,
+ NULL,
+ 0);
+
+ RegBX = RegSet.X.BX;
+
+ // Get the run-time Option ROM size right away; note that the value of
+ // OpROMSeg:0002 can change later, for example after BCV execution (noticed
+ // on NetCell PCI SATA RAID card).
+ RtRomSize = ((LEGACY_OPT_ROM_HEADER*)NextRomAddress)->Size512 * 0x200;
+TRACE((-1, "InstallRom...Run-time ROM Size = %x Bytes\n", RtRomSize));
+
+ // Update EBDA map
+ ebdaSeg2 = *(UINT16*)(UINTN)0x40e;
+ ebdaSize2 = *(UINT8*)((UINTN)ebdaSeg2<<4) << 10;
+
+ RtDataSize = 0;
+ if (ebdaSeg1 > ebdaSeg2) {
+ RtDataSize = ebdaSize2 - ebdaSize1; // #of bytes taken by this OpROM
+ UpdateEbdaMap((UINT32)(ebdaSeg1 - ebdaSeg2) << 4);
+ }
+
+ // Check for a ROM size not being FF
+ if (RtRomSize == 0x1fe00) RtRomSize = 0;
+
+ // Prepare the output parameters
+ *ProcessBootDevices = (RegBX == 0 && RtRomSize != 0);
+ *NewRomSize = RtRomSize;
+
+ if (IsVga) return EFI_SUCCESS; // Done for VBIOS
+
+ // Restore video mode
+ if (SetTxtMode == 2) {
+ *(UINT32*)(UINTN)0x40 = CurrentInt10;
+ }
+
+ // Disable Legacy console redirection
+#if LEGACYSREDIR_SUPPORT
+ if(gLegacySredir == NULL) {
+ pBS->LocateProtocol (
+ &gEfiLegacySredirProtocolGuid,
+ NULL,
+ &gLegacySredir
+ );
+ }
+ if(gLegacySredir != NULL) {
+ gLegacySredir->DisableLegacySredir(gLegacySredir);
+ }
+#endif
+
+
+ // VGA needs to be reconnected in several cases:
+ // 1) SetTxtMode == 0
+ // 2) SetTxtMode == 1 and VGA was started outside CSM control; this is determined
+ // by the value of LegacyVgaStartCounter (greater than 1)
+ if (SetTxtMode == 0 || (SetTxtMode == 1 && LegacyVgaStartCounter > 1))
+ {
+ if (VgaWasConnected) {
+ // Restore VgaCapabilities on VgaPciIo
+ VgaPciIo->Attributes (VgaPciIo, EfiPciIoAttributeOperationSet, VgaCapabilities, 0);
+ } else {
+ RegSet.H.AL = CurrentMode;
+ RegSet.H.AH = 0;
+ Status = CoreBiosInfo->iBios.Int86 (&CoreBiosInfo->iBios, 0x10, &RegSet);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ pBS->ConnectController(gVgaHandle, NULL, NULL, TRUE);
+
+ // Reset counter so that following OpROMs will properly switch video when SetTxtMode is 1
+ LegacyVgaStartCounter = 1;
+
+// if (ConsoleControl != NULL) {
+// Status = ConsoleControl->SetMode(ConsoleControl, EfiConsoleControlScreenGraphics);
+// ASSERT_EFI_ERROR(Status);
+// }
+ }
+
+ ConnectSerialIO();
+
+ // Update BBS device count
+ if (CoreBiosInfo->BbsEntriesNo != Csm16DOT->NumberBbbsEntries) {
+ // CSM16 had inserted some BBS entries for non-BBS devices
+ CoreBiosInfo->BbsEntriesNo = Csm16DOT->NumberBbbsEntries;
+ }
+
+ // Process boot devices
+ if (RegBX == 0 && RtRomSize != 0) { // Either BBS OpROM or no bootable devices connected
+
+ // Save the BBS compliant OpROM memory context here. Note that saving Oprom
+ // data is only required for the option ROMs that produce BCV because of early
+ // BCV execution; it should not be called for non-BBS compliant OpROMs, for
+ // those OpROMs memory context will be the same til the system is booted.
+
+ if (RtDataSize) {
+ // EBDA was allocated, calculate the address
+ IsEbda = TRUE;
+ RtData = (UINT8*)(((UINTN)ebdaSeg2<<4) + ((UINTN)ebdaSizeKB<<10));
+ } else {
+ // EBDA was not allocated; verify data is not requested
+ // by a blind update of 40:13. This memory allocation method
+ // was observed on OpROM by Adaptec 39160, FW ver V2.55.0.
+ IsEbda = FALSE;
+ baseMem2 = *(UINT16*)(UINTN)0x413;
+ RtDataSize = (UINT32)(baseMem1-baseMem2)<<10;
+ if (RtDataSize) {
+ RtData = (UINT8*)((UINTN)baseMem2<<10);
+ }
+ }
+
+ EbdaOffset = IsEbda? (UINT32)ebdaSizeKB<<10 : 0;
+ SaveOprom ((UINT8*)NextRomAddress, RtData, RtDataSize, IsEbda, EbdaOffset);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InstallPciRom
+//
+// Description: Shadows an OpROM
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// PciHandle The PCI PC-AT* OpROM from this device's ROM BAR will be loaded
+// RomImage A PCI PC-AT ROM image. This argument is non-NULL if there is
+// no hardware associated with the ROM and thus no PciHandle;
+// otherwise it must be NULL. An example is the PXE base code.
+// Flags The type of ROM discovered. Multiple bits can be set, as follows:
+// 00 = No ROM.
+// 01 = ROM found.
+// 02 = ROM is a valid legacy ROM.
+// DiskStart Disk number of the first device hooked by the ROM. If DiskStart is
+// the same as DiskEnd, no disks were hooked.
+// DiskEnd Disk number of the last device hooked by the ROM.
+// RomShadowAddress Shadow address of PC-AT ROM.
+// ShadowedRomSize Size in bytes of RomShadowAddress.
+//
+// Output:
+// EFI_SUCCESS The OpROM was shadowed
+// EFI_UNSUPPORTED The PciHandle was not found
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallPciRom (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle,
+ IN VOID **RomImage,
+ OUT UINTN *Flags,
+ OUT UINT8 *DiskStart, OPTIONAL
+ OUT UINT8 *DiskEnd, OPTIONAL
+ OUT VOID **RomShadowAddress, OPTIONAL
+ OUT UINT32 *ShadowedRomSize OPTIONAL
+ )
+{
+ EFI_STATUS Status, Status1 = EFI_SUCCESS;
+ VOID* RomLocation;
+ EFI_PHYSICAL_ADDRESS Rom30Address = 0;
+ UINTN RomSize, Rom30Size = 0;
+ EFI_DISPATCH_OPROM_TABLE *Csm16DOT;
+ UINTN PciSegment, PciBus, PciDeviceNumber, PciFunction;
+ BIOS_INFO *CoreBiosInfo = (BIOS_INFO*)This;
+ UINT32 NewRomSize = 0;
+ BOOLEAN IsVga = FALSE;
+ UINT8 DiskFrom = 0x80;
+ UINT8 DiskTo = 0x80;
+ UINT8 PciCfgData[0x40];
+ EFI_HANDLE *VgaHandlePtr = &gVgaHandle;
+ UINTN VgaHandleCount;
+ EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+ UINT64 Capabilities;
+ BOOLEAN is30ROM = FALSE;
+ UINT32 LockUnlockAddr, LockUnlockSize;
+ CSM_PLATFORM_PROTOCOL *CsmPlatformProtocol;
+ UINTN LowMem4KPages = 0;
+ EXECUTED_PCI_ROM *ExecutedRom = NULL;
+ BOOLEAN ProcessBootDevices;
+ volatile UINT32 *ivt = (UINT32*)0;
+ UINT32 Int18;
+ UINT32 Int19;
+ BOOLEAN Int19Trapped = FALSE;
+ UINT32 NumberAlreadyExecutedPciRoms;
+
+ //
+ // Handle separately HW independent OpROMs, e.g. PXE
+ //
+ if (PciHandle == NULL) {
+ IsVga = FALSE;
+ PciSegment = 0; PciBus = 0; PciDeviceNumber = 0; PciFunction = 0;
+ }
+ else {
+ Status = pBS->HandleProtocol (
+ PciHandle,
+ &gEfiPciIoProtocolGuid,
+ &PciIo); // Get PciIo protocol
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // NOTE: The following call will check whether the LegacyOpROM
+ // has already been executed for PciIo. If so, it returns EFI_SUCCESS.
+ //
+ ExecutedRom = PciRomAlreadyExecuted(PciIo);
+ if (ExecutedRom != NULL) {
+ *Flags = ExecutedRom->Flags;
+ if (DiskStart) *DiskStart = ExecutedRom->DiskFrom;
+ if (DiskEnd) *DiskEnd = ExecutedRom->DiskTo;
+ if (RomShadowAddress) *RomShadowAddress = ExecutedRom->RomAddress;
+ if (ShadowedRomSize) *ShadowedRomSize = ExecutedRom->RomSize;
+
+ return EFI_SUCCESS;
+ }
+
+ // Verify the number of already executed PCI ROMs does not exceed MAX_EXECUTED_OPROMS
+ NumberAlreadyExecutedPciRoms = 0;
+ for (
+ ExecutedRom = gExecutedRomsPci-1;
+ ExecutedRom->Seg | ExecutedRom->Bus | ExecutedRom->Dev | ExecutedRom->Fun;
+ NumberAlreadyExecutedPciRoms++, ExecutedRom--
+ ){}
+
+ if (NumberAlreadyExecutedPciRoms >= MAX_EXECUTED_OPROMS)
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0, // offset
+ 0x40, // width
+ PciCfgData);
+ ASSERT_EFI_ERROR(Status);
+
+ if (PciCfgData[0xB]==PCI_CL_OLD && PciCfgData[0xA]==PCI_CL_OLD_SCL_VGA) {
+ IsVga = TRUE;
+ }
+ if (PciCfgData[0xB]==PCI_CL_DISPLAY && PciCfgData[0xA]==PCI_CL_DISPLAY_SCL_VGA) {
+ IsVga = TRUE;
+ }
+
+ Status = CheckEnablePciSiblings(PciIo, PciCfgData);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = PciIo->GetLocation(PciIo,
+ &PciSegment, &PciBus, &PciDeviceNumber, &PciFunction);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //
+ // Execute platform pre-OpROM function
+ //
+ pBS->LocateProtocol(&gCsmPlatformProtocolGuid, NULL, &CsmPlatformProtocol);
+
+ if (CsmPlatformProtocol) {
+ Status = CsmPlatformProtocol->PreProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ if (EFI_ERROR(Status)) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ return Status;
+ }
+ }
+
+ if (IsVga) {
+ if (CoreBiosInfo->hVga != NULL) {
+ //
+ // More than one legacy video is not supported
+ // We return EFI_SUCCESS so that Video Thunk driver start function
+ // does not fail.
+ //
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ return EFI_SUCCESS;
+ }
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformHandle(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformVgaHandle,
+ 0,
+ &VgaHandlePtr,
+ &VgaHandleCount,
+ NULL);
+ if (!EFI_ERROR(Status)) { // Platform returned VGA handle
+ if (PciHandle != *VgaHandlePtr) { // Not the one requested by platform
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+ else { // Not VGA
+ if (CoreBiosInfo->hVga == NULL) {
+ EFI_PCI_IO_PROTOCOL *VgaPciIo = NULL;
+ //
+ // The control is passed to this routine to install non-VGA OpROM and VGA BIOS is
+ // not yet installed. This could happen in the following scenarios:
+ // 1) Video is controlled by Efi native video driver
+ // 2) BDS is connecting mass storage before consoles
+ // 3) The system is headless (no video controller)
+ //
+ // We will try to find video and launch its oprom; for case #1 we will disconnect
+ // the native driver and reconnect it after OpROM is executed.
+ //
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformHandle(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformVgaHandle,
+ 0,
+ &VgaHandlePtr,
+ &VgaHandleCount,
+ NULL);
+ if (EFI_ERROR(Status)) { // Platform did not return VGA handle, try to find one
+ Status1 = FindAnyVga(VgaHandlePtr);
+ }
+ if (!EFI_ERROR(Status) || !EFI_ERROR(Status1)) { // Found VGA - enable it and launch OpROM
+ Status = pBS->HandleProtocol (
+ *VgaHandlePtr,
+ &gEfiPciIoProtocolGuid,
+ &VgaPciIo); // Get PciIo protocol
+ ASSERT_EFI_ERROR(Status);
+
+ Status = VgaPciIo->Attributes (VgaPciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+
+ Status = VgaPciIo->Attributes (VgaPciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+ ASSERT_EFI_ERROR(Status);
+
+ InstallPciRom(This, // Recursive call
+ *VgaHandlePtr, NULL, Flags,
+ NULL, NULL, NULL, NULL);
+ }
+ }
+ }
+
+ VgaHandlePtr = &gVgaHandle;
+
+ if (IsVga) {
+ ASSERT(PciIo != NULL);
+ Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationGet, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationEnable,
+ Capabilities | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL); // Enable VGA legacy MEM/IO access
+ ASSERT_EFI_ERROR(Status);
+
+ CoreBiosInfo->hVga = PciHandle;
+ *VgaHandlePtr = PciHandle;
+ }
+
+ //
+ // Get the ROM image location
+ //
+ if (PciHandle != NULL) {
+ Status = CheckPciRom (This, PciHandle, &RomLocation, &RomSize, Flags);
+ if (EFI_ERROR(Status) || (RomLocation == NULL)) {
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ return EFI_UNSUPPORTED;
+ }
+
+ is30ROM = Check30ROM(RomLocation, &Rom30Size, PciHandle);
+ }
+ else { // ROM is not associated with PCI device
+ RomLocation = *RomImage;
+ RomSize = ((LEGACY_OPT_ROM_HEADER*)RomLocation)->Size512 * 0x200;
+ if (RomSize == 0) {
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ return EFI_UNSUPPORTED;
+ }
+ is30ROM = Check30ROM(RomLocation, &Rom30Size, NULL);
+ }
+
+ //
+ // For PCI3.0 compliant ROMs reserve base memory for ROM Init code
+ //
+ if (is30ROM) {
+ Rom30Address = 0xA0000;
+ LowMem4KPages = RomSize >> 12; // Number of 4KB units
+ if (RomSize % 0x1000) {
+ LowMem4KPages++;
+ }
+ Status = pBS->AllocatePages(AllocateMaxAddress,
+ EfiBootServicesData,
+ LowMem4KPages,
+ &Rom30Address);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ DEVICE_ERROR_CODE(DXE_LEGACY_OPROM_NO_SPACE, EFI_ERROR_MAJOR, PciHandle);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (Rom30Address < 0x8000) {
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ Status = EFI_OUT_OF_RESOURCES;
+ TRACE(((UINTN)TRACE_ALWAYS,"Can not execute PCI 3.0 OPROM: out of Base Memory.\n"));
+ DEVICE_ERROR_CODE(DXE_LEGACY_OPROM_NO_SPACE, EFI_ERROR_MAJOR, PciHandle);
+ goto ReturnErrorStatus;
+ }
+ }
+
+ PROGRESS_CODE(DXE_LEGACY_OPROM_INIT);
+
+ //
+ // Check for the room in shadow for this ROM and copy it from RomLocation.
+ //
+ {
+ UINTN SizeInShadow = is30ROM? Rom30Size : RomSize;
+ UINTN CopyToAddress = is30ROM? (UINTN)Rom30Address : (UINTN)gNextRomAddress;
+
+ if(((UINTN)(gNextRomAddress) + SizeInShadow) > OPROM_MAX_ADDRESS){
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+ TRACE(((UINTN)TRACE_ALWAYS,"Can not execute PCI OPROM: out of resources. RomAddr %x RomSize %x\n", gNextRomAddress, SizeInShadow));
+ Status = EFI_OUT_OF_RESOURCES;
+ DEVICE_ERROR_CODE(DXE_LEGACY_OPROM_NO_SPACE, EFI_ERROR_MAJOR, PciHandle);
+ goto ReturnErrorStatus;
+ }
+
+ Status = UnlockShadow(gNextRomAddress, SizeInShadow, &LockUnlockAddr, &LockUnlockSize);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Initilize the size field to 0.
+ //
+ ((LEGACY_OPT_ROM_HEADER*)gNextRomAddress)->Size512=0;
+ pBS->CopyMem((VOID*)CopyToAddress, RomLocation, RomSize);
+ }
+
+ DiskFrom = *(UINT8*)(UINTN)0x475 + 0x80;
+
+ Csm16DOT = &CoreBiosInfo->Thunk->DispatchOpromTable;
+ Csm16DOT->PnpInstallationCheckSegment = CoreBiosInfo->Csm16Header->PnPInstallationCheckSegment;
+ Csm16DOT->PnpInstallationCheckOffset = CoreBiosInfo->Csm16Header->PnPInstallationCheckOffset;
+ if (is30ROM) {
+ Csm16DOT->OpromSegment = (UINT16)(Shr64(Rom30Address, 4));
+ Csm16DOT->FinalLocationSegment = (UINT16)((UINTN)gNextRomAddress >> 4);
+ }
+ else {
+ Csm16DOT->OpromSegment = (UINT16)((UINTN)gNextRomAddress >> 4);
+ Csm16DOT->FinalLocationSegment = 0;
+ }
+
+ Csm16DOT->PciBus = (UINT8)PciBus;
+ Csm16DOT->PciDeviceFunction = (UINT8)(PciDeviceNumber << 3 | PciFunction);
+ Csm16DOT->NumberBbbsEntries = CoreBiosInfo->BbsEntriesNo;
+ Csm16DOT->BbsTable = (UINT32)(UINTN)(CoreBiosInfo->BbsTable);
+
+ TRACE((TRACE_ALWAYS, "OptionROM for B%x/D%x/F%x is executed from %x:0003\n",
+ PciBus, PciDeviceNumber, PciFunction, Csm16DOT->OpromSegment));
+
+ // Save INT18 and INT19 to be able to see its trapping after ROM execution
+ Int19 = ivt[0x19];
+ Int18 = ivt[0x18];
+
+ Status = CsmInstallRom(CoreBiosInfo, PciHandle,
+ Csm16DOT, (UINTN)gNextRomAddress, IsVga, &NewRomSize, &ProcessBootDevices);
+
+ Int19Trapped = Int19 != ivt[0x19];
+
+ if (ProcessBootDevices) {
+ FetchBbsBootDevices(CoreBiosInfo,
+ gNextRomAddress,
+ PciCfgData,
+ PciBus,
+ PciDeviceNumber,
+ PciFunction,
+ &DiskFrom,
+ Int18 != ivt[0x18],
+ Int19 != ivt[0x19]);
+ }
+
+ // Restore INT18 and INT19
+ ivt[0x18] = Int18;
+ ivt[0x19] = Int19;
+
+ DiskTo = DiskFrom + *(UINT8*)(UINTN)0x475;
+
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, PciIo, RomImage);
+ }
+
+ if (is30ROM) {
+ //
+ // For PCI3.0 do necessary things with Setup Routine here, then
+ // free Rom30Address memory
+ //
+ pBS->FreePages(Rom30Address, LowMem4KPages);
+ }
+
+ if (!is30ROM) {
+ if (RomSize > NewRomSize) {
+ pBS->SetMem(gNextRomAddress+NewRomSize, RomSize-NewRomSize, 0xFF);
+ }
+ }
+ Status = LockShadow(LockUnlockAddr, LockUnlockSize);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Make the rom size 2K aligned
+ //
+ if (NewRomSize % 0x800) {
+ NewRomSize += (0x800 - (NewRomSize % 0x800));
+ }
+
+ //
+ // Return OPTIONAL parameters: updated disks, oprom address and size.
+ //
+ if (DiskStart) *DiskStart = DiskFrom;
+ if (DiskEnd) *DiskEnd = DiskTo;
+ if (RomShadowAddress) *RomShadowAddress = gNextRomAddress;
+ if (ShadowedRomSize) *ShadowedRomSize = NewRomSize;
+
+ //
+ // Update the list of Executed Roms
+ //
+ if (PciHandle) {
+ gExecutedRomsPci->Seg = PciSegment;
+ gExecutedRomsPci->Bus = PciBus;
+ gExecutedRomsPci->Dev = PciDeviceNumber;
+ gExecutedRomsPci->Fun = PciFunction;
+ gExecutedRomsPci->Flags = *Flags;
+ gExecutedRomsPci->DiskFrom = DiskFrom;
+ gExecutedRomsPci->DiskTo = DiskTo;
+ gExecutedRomsPci->RomAddress = gNextRomAddress;
+ gExecutedRomsPci->RomSize = NewRomSize;
+ gExecutedRomsPci++;
+ }
+TRACE((TRACE_ALWAYS, "PCI OPROM(handle %x, %x/%x/%x): addr %x, size %x\n",
+ PciHandle, PciBus, PciDeviceNumber, PciFunction, gNextRomAddress, NewRomSize));
+ gNextRomAddress += NewRomSize;
+
+ if (Int19Trapped && !IsVga)
+ {
+ LegacyBoot (
+ &CoreBiosInfo->iBios,
+ &(DummyLoadOption.BbsDevicePath),
+ sizeof(DummyLoadOption),
+ &DummyLoadOption
+ );
+ ASSERT(FALSE); // CONTROL MUST NOT BE GIVEN BACK HERE
+ // If by any chance we are here, we have to do the needful:
+ pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+
+ return EFI_SUCCESS;
+
+ReturnErrorStatus:
+ if (LowMem4KPages != 0) {
+ pBS->FreePages(Rom30Address, LowMem4KPages);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetShadowRamAddress
+//
+// Description:
+// Returns the available shadow RAM address out of the given range.
+//
+// Input:
+// UINT32 *AddrMin Min address
+// UINT32 AddrMax Max address
+// UINT32 Size Range size, in Bytes
+// UINT32 Alignment Range alignment
+//
+// Output:
+// EFI_SUCCESS AddrMin variable contains the available address
+// EFI_OUT_OF_RESOURCES The requested memory range is not available in
+// the shadow RAM
+// Notes:
+// This function does not reserve or allocate memory in the shadow RAM
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetShadowRamAddress(
+ IN OUT UINT32 *AddrMin,
+ IN UINT32 AddrMax,
+ IN UINT32 Size,
+ IN UINT32 Alignment
+)
+{
+ UINT32 Addr = *AddrMin;
+ UINT32 Aln;
+
+ if (Addr > AddrMax) return EFI_INVALID_PARAMETER;
+ if (Size == 0x00) return EFI_INVALID_PARAMETER;
+ if (Alignment > OPROM_MAX_ADDRESS) return EFI_INVALID_PARAMETER;
+ if (AddrMax + Size > (OPROM_MAX_ADDRESS + 1)) return EFI_OUT_OF_RESOURCES;
+ if (AddrMax < (UINT32)(UINTN)gNextRomAddress) return EFI_OUT_OF_RESOURCES;
+
+ if(Alignment != 0) Alignment--;
+ Aln = ~Alignment;
+
+ if (Addr < (UINT32)(UINTN)gNextRomAddress) {
+ Addr = (UINT32)(UINTN)gNextRomAddress;
+ }
+
+ if ((Alignment !=0) && (Addr & Aln)) {
+ if ( (Addr & Aln) != Addr){
+ Addr += (Alignment+1);
+ Addr &= Aln;
+
+ }
+ }
+ gNextRomAddress = (UINT8 *)(Addr + Size);
+ *AddrMin = Addr;
+
+return EFI_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InstallIsaRom
+//
+// Description: Executes ISA Option ROM
+//
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+// RomAddress Location of the Option ROM
+//
+// Output:
+// EFI_SUCCESS ROM was successfully executed
+// EFI_OUT_OF_RESOURCES Shadow RAM full, ROM was not executed
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallIsaRom(
+ IN EFI_LEGACY_BIOS_EXT_PROTOCOL *This,
+ IN UINTN RomAddress
+)
+{
+ UINTN RomSize;
+ BOOLEAN ProcessBootDevices;
+ EFI_STATUS Status;
+ EFI_DISPATCH_OPROM_TABLE *Csm16DOT;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ BIOS_INFO *CoreBiosInfo;
+ CSM_PLATFORM_PROTOCOL *CsmPlatformProtocol;
+ UINT8 PciCfgData[0x40] = {0};
+ UINT8 DiskFrom = 0x80;
+ volatile UINT32 *ivt = (UINT32*)0;
+ UINT32 Int18;
+ UINT32 Int19;
+
+ // Validate ISA ROM
+ if (((LEGACY_OPT_ROM_HEADER*)RomAddress)->Signature != 0xAA55) {
+ TRACE((-1, "Can not execute ISA ROM: missing 0xAA55 signature.\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ // See if ROM fits in the shadow
+ RomSize = ((LEGACY_OPT_ROM_HEADER*)RomAddress)->Size512 << 9;
+ if((RomAddress + RomSize) > OPROM_MAX_ADDRESS) {
+ TRACE((-1, "Can not execute ISA ROM: won't fit in the shadow memory.\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Get BIOS_INFO variable pointer
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ ASSERT_EFI_ERROR(Status);
+ CoreBiosInfo = (BIOS_INFO*)LegacyBios;
+
+ //
+ // Execute platform pre-OpROM function
+ //
+ pBS->LocateProtocol(&gCsmPlatformProtocolGuid, NULL, &CsmPlatformProtocol);
+
+ if (CsmPlatformProtocol) {
+ Status = CsmPlatformProtocol->PreProcessOpRom(CsmPlatformProtocol, NULL, (VOID*)&RomAddress);
+ if (EFI_ERROR(Status)) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, NULL, (VOID*)&RomAddress);
+ return Status;
+ }
+ }
+
+ DiskFrom = *(UINT8*)(UINTN)0x475 + 0x80;
+
+ Csm16DOT = &CoreBiosInfo->Thunk->DispatchOpromTable;
+ Csm16DOT->OpromSegment = (UINT16)(RomAddress >> 4);
+ Csm16DOT->NumberBbbsEntries = CoreBiosInfo->BbsEntriesNo;
+ Csm16DOT->BbsTable = (UINT32)(UINTN)(CoreBiosInfo->BbsTable);
+
+ TRACE((TRACE_ALWAYS, "OptionROM for ISA Device is executed from %x:0003\n", Csm16DOT->OpromSegment));
+
+ // Save INT18 and INT19 to be able to see its trapping after ROM execution
+ Int19 = ivt[0x19];
+ Int18 = ivt[0x18];
+
+ Status = CsmInstallRom(CoreBiosInfo, NULL,
+ Csm16DOT, RomAddress, FALSE, NULL, &ProcessBootDevices);
+
+ if (ProcessBootDevices) {
+ FetchBbsBootDevices(CoreBiosInfo,
+ (UINT8*)RomAddress,
+ PciCfgData,
+ 0,
+ 0,
+ 0,
+ &DiskFrom,
+ Int18 != ivt[0x18],
+ Int19 != ivt[0x19]);
+ }
+
+ // Restore INT18 and INT19
+ ivt[0x18] = Int18;
+ ivt[0x19] = Int19;
+
+ if (CsmPlatformProtocol) {
+ CsmPlatformProtocol->PostProcessOpRom(CsmPlatformProtocol, NULL, (VOID*)&RomAddress);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: ShadowAllLegacyOproms
+//
+// Description: Allows external agents to force loading of all legacy OpROMs.
+// This function can be invoked before GetBbsInfo() to ensure all
+// devices are counted.
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PROTOCOL instance.
+//
+// Output:
+// EFI_SUCCESS OpROMs are shadowed successfully.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ShadowAllLegacyOproms (
+ IN EFI_LEGACY_BIOS_PROTOCOL *This
+)
+{
+ EFI_HANDLE *HandleBuffer;
+ UINTN n, HandleCount;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ BIOS_INFO *CoreBiosInfo = (BIOS_INFO*)This;
+ UINT64 Capabilities;
+ UINTN Flags;
+ UINT8 dData[4];
+ UINT8 SetTxtMode = gSetTxtMode;
+
+ //
+ // Locate all PciIo handles
+ //
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer);
+
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (n = 0; n < HandleCount; n++) {
+ Status = pBS->HandleProtocol (HandleBuffer[n], &gEfiPciIoProtocolGuid, &PciIo);
+ ASSERT_EFI_ERROR(Status);
+
+ if (PciRomAlreadyExecuted(PciIo)) continue;
+
+ //
+ // Skip the VGA devices: the active VGA controller might have
+ // been already enabled, all other VGA controllers have to be disabled.
+ //
+ if (CoreBiosInfo->hVga != NULL) {
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint32,
+ 8, // offset
+ 1, // width
+ &dData);
+ ASSERT_EFI_ERROR(Status);
+ if (dData[3]==PCI_CL_DISPLAY) continue;
+ }
+
+ //
+ // See if device has OpROM, if so - enable device and istlall OpROM; assume
+ // CSM has already assinged IRQ and programmed IRQ router and register 3C
+ //
+ Status = CheckPciRom(This, HandleBuffer[n], NULL, NULL, &Flags);
+ if (EFI_ERROR(Status) || (Flags != 2)) continue; // No OpROM or OpROM is invalid
+
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+
+ if (EFI_ERROR(Status)) continue;
+
+ InstallPciRom(This,
+ HandleBuffer[n], NULL, &Flags,
+ NULL, NULL, NULL, NULL);
+ }
+ pBS->FreePool(HandleBuffer);
+
+ if (!gServiceRomsExecuted) {
+ //
+ // Launch service ROMs
+ //
+ Status = CoreBiosInfo->iBiosPlatform->PlatformHooks(
+ CoreBiosInfo->iBiosPlatform,
+ EfiPlatformHookShadowServiceRoms,
+ 0, NULL, NULL, NULL, NULL);
+ gServiceRomsExecuted = TRUE;
+ }
+
+ gSetTxtMode = SetTxtMode;
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/CsmSimpleIn.c b/Core/EM/CSM/CsmSimpleIn.c
new file mode 100644
index 0000000..67540a7
--- /dev/null
+++ b/Core/EM/CSM/CsmSimpleIn.c
@@ -0,0 +1,604 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmSimpleIn.c 9 10/18/13 10:18a Olegi $
+//
+// $Revision: 9 $
+//
+// $Date: 10/18/13 10:18a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/CsmSimpleIn.c $
+//
+// 9 10/18/13 10:18a Olegi
+// [TAG] EIP140252
+// [Category] Improvement
+// [Description] Connect CsmSimpleIn on ConInStarted installation
+//
+// 8 5/27/13 7:20a Rameshr
+// [TAG] EIP122428
+// [Category] Improvement
+// [Description] Clear the LED's status before setting it.
+// [Files] CsmSimpleIn.c
+//
+// 7 2/21/13 12:53p Olegi
+// [TAG] EIP115727
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CsmSimpleIn->RegisterKeyNotify problem
+// [RootCause] If someone uses RegisterKeyNotify() to register
+// notification more than one time, then UnRegisterKeyNotify() will free
+// wrong pointer when unregistering it.
+// [Solution] Remove global KEY_WAITING_RECORD variable, add a code to
+// manage multiple instances of KEY_WAITING_RECORD
+// [Files] CsmSimpleIn.c
+//
+// 6 9/06/12 8:15a Olegi
+//
+// 4 5/14/10 11:13a Olegi
+// Modified RegisterKeyNotify/UnregisterKeyNotify functions to pass SCT.
+//
+// 3 5/07/10 10:23a Olegi
+// Added input validation in CsmSimpleInInputReadKeyEx.
+//
+// 2 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 1 11/10/09 8:16a Olegi
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmSimpleIn.c
+//
+// Description: Implements the SimpleTextIn protocol for the Csm.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <efi.h>
+#include <AmiDxeLib.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\AmiKeycode.h>
+#include <Protocol\SimpleTextOut.h >
+#include <Protocol\ConsoleControl.h>
+
+
+typedef struct _CSMSIMPLEIN_DEV {
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleTextInput;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleTextInputEx;
+ AMI_EFIKEYCODE_PROTOCOL EfiKeycodeInput;
+} CSMSIMPLEIN_DEV;
+
+UINT8 CurrentKeyState=0;
+
+typedef struct _KEY_WAITING_RECORD{
+ DLINK Link;
+ EFI_KEY_DATA Context;
+ EFI_KEY_NOTIFY_FUNCTION Callback;
+} KEY_WAITING_RECORD;
+
+DLIST mCsmKeyboardData;
+
+//Simple Input:
+
+EFI_STATUS CsmSimpleInInputReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS CsmSimpleInInputReadKey(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+);
+
+//Simple Input Ex:
+
+EFI_STATUS CsmSimpleInInputResetEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS CsmSimpleInInputReadKeyEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS CsmSimpleInInputSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+);
+
+EFI_STATUS CsmSimpleInInputRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS CsmSimpleInInputUnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+// AMI KeyCode:
+
+EFI_STATUS
+CsmSimpleInInputReadEfiKey(
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+);
+
+VOID ConnectCsmSimpleIn(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+EFI_HANDLE gCsmSimpleInHandle=NULL;
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitCsmSimpleIn
+//
+// Description: CSM SimpleIn driver entry point,
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+//
+// Output: The status of CSM board initalization
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitCsmSimpleIn (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status;
+ CSMSIMPLEIN_DEV *CsmSimpleInDev = NULL;
+ static EFI_GUID GuidConInStarted = CONSOLE_IN_DEVICES_STARTED_PROTOCOL_GUID;
+ EFI_EVENT Event;
+ VOID *pRegistration;
+
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(CSMSIMPLEIN_DEV),
+ &CsmSimpleInDev);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->SetMem(CsmSimpleInDev, sizeof(CSMSIMPLEIN_DEV), 0);
+
+ CsmSimpleInDev->SimpleTextInput.Reset = CsmSimpleInInputReset;
+ CsmSimpleInDev->SimpleTextInput.ReadKeyStroke = CsmSimpleInInputReadKey;
+ CsmSimpleInDev->SimpleTextInput.WaitForKey = NULL;
+
+ CsmSimpleInDev->SimpleTextInputEx.Reset = CsmSimpleInInputResetEx;
+ CsmSimpleInDev->SimpleTextInputEx.ReadKeyStrokeEx = CsmSimpleInInputReadKeyEx;
+ CsmSimpleInDev->SimpleTextInputEx.SetState = CsmSimpleInInputSetState;
+ CsmSimpleInDev->SimpleTextInputEx.RegisterKeyNotify = CsmSimpleInInputRegisterKeyNotify;
+ CsmSimpleInDev->SimpleTextInputEx.UnregisterKeyNotify = CsmSimpleInInputUnRegisterKeyNotify;
+ CsmSimpleInDev->SimpleTextInputEx.WaitForKeyEx = NULL;
+
+ CsmSimpleInDev->EfiKeycodeInput.Reset = CsmSimpleInInputResetEx;
+ CsmSimpleInDev->EfiKeycodeInput.ReadEfikey = CsmSimpleInInputReadEfiKey;
+ CsmSimpleInDev->EfiKeycodeInput.SetState = CsmSimpleInInputSetState;
+ CsmSimpleInDev->EfiKeycodeInput.RegisterKeyNotify = CsmSimpleInInputRegisterKeyNotify;
+ CsmSimpleInDev->EfiKeycodeInput.UnregisterKeyNotify = CsmSimpleInInputUnRegisterKeyNotify;
+ CsmSimpleInDev->EfiKeycodeInput.WaitForKeyEx = NULL;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gCsmSimpleInHandle,
+ &gEfiSimpleTextInProtocolGuid, &CsmSimpleInDev->SimpleTextInput,
+ &gEfiSimpleTextInExProtocolGuid, &CsmSimpleInDev->SimpleTextInputEx,
+ &gAmiEfiKeycodeProtocolGuid, &CsmSimpleInDev->EfiKeycodeInput,
+ NULL
+ );
+
+ RegisterProtocolCallback(
+ &GuidConInStarted, ConnectCsmSimpleIn,
+ NULL, &Event,&pRegistration
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ConnectCsmSimpleIn
+//
+// Description:
+// This function Connect the CsmSimpleIn handle
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID ConnectCsmSimpleIn(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ // Connect the CsmSimpleIn, So that Consplitter gets notified
+ pBS->ConnectController(gCsmSimpleInHandle, NULL, NULL, TRUE);
+ // Kill the Event
+ pBS->CloseEvent(Event);
+
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CsmSimpleInInputReset
+//
+// Description: In our implementation, this function does nothing.
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
+// IN BOOLEAN ExtendedVerification
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS CsmSimpleInInputReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CsmSimpleInInputResetEx
+//
+// Description: In our implementation, this function does nothing.
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This
+// IN BOOLEAN ExtendedVerification
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS CsmSimpleInInputResetEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CsmSimpleInInputReadKey
+//
+// Description: Returns a EFI_INPUT_KEY Key if possible.
+//
+// Input:
+// IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This
+// OUT EFI_INPUT_KEY *Key
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS CsmSimpleInInputReadKey(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+)
+{
+ return EFI_NOT_READY;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CsmSimpleInToggleState
+//
+// Description: Get the Key Toggle State from the BDA
+//
+// Paremeters:
+// KeyToggleState - Pointer to the EFI_KEY_TOGGLE_STATE to
+// set the state for the input device.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmSimpleInToggleState(
+ OUT EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ UINT8 KeyState;
+
+ KeyState = *(UINT8*)(UINTN)0x417;
+ if(KeyState != CurrentKeyState) {
+ if(KeyState & 0x10) {
+ *KeyToggleState |= SCROLL_LOCK_ACTIVE;
+ }
+ if(KeyState & 0x20) {
+ *KeyToggleState |= NUM_LOCK_ACTIVE;
+ }
+ if(KeyState & 0x40) {
+ *KeyToggleState |= CAPS_LOCK_ACTIVE;
+ }
+ *KeyToggleState |= TOGGLE_STATE_VALID;
+ CurrentKeyState=*(UINT8*)(UINTN)0x417;
+ return EFI_SUCCESS;
+ }
+ return EFI_NOT_READY;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CsmSimpleInInputReadKeyEx
+//
+// Description: Reads the next keystroke from the input device and
+// returns data in the form of EFI_KEY_DATA structure.
+// This routine is a part of SimpleTextInEx protocol
+// implementation.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmSimpleInInputReadKeyEx(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+
+ if(KeyData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ pBS->SetMem (KeyData, sizeof(EFI_KEY_DATA) , 0);
+ Status=CsmSimpleInToggleState(&(KeyData->KeyState.KeyToggleState));
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CsmSimpleInInputSetState
+//
+// Description: Set certain state for the input device.
+//
+// Paremeters: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyToggleState - Pointer to the EFI_KEY_TOGGLE_STATE to
+// set the state for the input device.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmSimpleInInputSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ if(KeyToggleState == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(*KeyToggleState & TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED | SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ CurrentKeyState = *(UINT8*)(UINTN)0x417;
+
+ // Clear NumLock, CapsLock, Scroll Lock status
+ CurrentKeyState &= 0x8F;
+
+ if (*KeyToggleState & SCROLL_LOCK_ACTIVE) {
+ CurrentKeyState |= 0x10;
+ }
+
+ if (*KeyToggleState & NUM_LOCK_ACTIVE) {
+ CurrentKeyState |= 0x20;
+ }
+
+ if (*KeyToggleState & CAPS_LOCK_ACTIVE) {
+ CurrentKeyState |= 0x40;
+ }
+
+ *(UINT8*)(UINTN)0x417 = CurrentKeyState;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CsmSimpleInInputRegisterKeyNotify
+//
+// Description: Register a notification function for a particular
+// keystroke for the input device.
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyData - Key value
+// KeyNotificationFunction- Pointer to the Notification Function
+// NotificationHandle - Handle to be unregisterd
+//
+// Output None
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmSimpleInInputRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+)
+{
+
+ EFI_STATUS Status;
+ KEY_WAITING_RECORD *CsmKeyIn;
+
+ if(KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ //
+ // Create database record and add to database
+ //
+ Status = pBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (KEY_WAITING_RECORD),
+ &CsmKeyIn
+ );
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Gather information about the registration request
+ //
+
+ CsmKeyIn->Context = *KeyData;
+ CsmKeyIn->Callback = KeyNotificationFunction;
+
+ DListAdd (&mCsmKeyboardData, &(CsmKeyIn->Link));
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *NotifyHandle = (EFI_HANDLE) (&CsmKeyIn->Link);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CsmSimpleInInputUnRegisterKeyNotify
+//
+// Description: Removes the notification which was previously
+// registered by CsmSimpleInInputRegisterKeyNotify.
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// NotificationHandle - Handle to be unregisterd
+//
+// Output None
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmSimpleInInputUnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+ DLINK *ListPtr;
+ KEY_WAITING_RECORD *CsmKeyIn;
+
+ if(NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListPtr = mCsmKeyboardData.pHead;
+ while ( ListPtr != NULL)
+ {
+ CsmKeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ if ( (&CsmKeyIn->Link) == NotificationHandle)
+ {
+ DListDelete(&mCsmKeyboardData, ListPtr);
+ pBS->FreePool(CsmKeyIn);
+ return EFI_SUCCESS;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ return EFI_INVALID_PARAMETER;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CsmSimpleInInputReadEfiKey
+//
+// Description: Reads the next keystroke from the input device and
+// returns data in the form of AMI_EFI_KEY_DATA structure.
+// This routine is a part of AmiEfiKeycode protocol
+// implementation.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmSimpleInInputReadEfiKey(
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ pBS->SetMem (KeyData, sizeof(AMI_EFI_KEY_DATA) , 0);
+ Status=CsmSimpleInToggleState(&(KeyData->KeyState.KeyToggleState));
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/OemPir.dat b/Core/EM/CSM/OemPir.dat
new file mode 100644
index 0000000..26fc35e
--- /dev/null
+++ b/Core/EM/CSM/OemPir.dat
@@ -0,0 +1,227 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/OemPir.dat 4 1/12/10 11:46a Olegi $
+;
+; $Revision: 4 $
+;
+; $Date: 1/12/10 11:46a $
+;**********************************************************************
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/OemPir.dat $
+;
+; 4 1/12/10 11:46a Olegi
+; Copyright message updated.
+;
+; 3 4/27/07 5:13p Olegi
+; CSM.CHM file preparation.
+;
+; 2 5/16/06 1:57p Olegi
+;
+; 1 11/07/05 7:11p Olegi
+;
+; 2 11/07/05 4:37p Olegi
+;
+; 1 6/21/05 12:12p Olegi
+; LegacyBios and LegacyBiosPlatform are combined into one FFS.
+;
+; 3 4/04/05 5:08p Mandal
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: PciInfo.asm
+;
+; Description: This file includes the PCI related tables generated by AMISDL
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+.586P
+.model small
+option language:c
+
+; MS IRQ Routing Table Header Structure
+;------------------------------------------------------------------------------
+MSIRQ_HEADER STRUC
+ dSignature dd ? ;'$PIR' signature
+ wVersion dw ? ;version (low byte = minor, high byte = major)
+ wSize dw ? ;length of routing table including header and slots
+ bRouterBus db ? ;PCI IRQ Router bus#
+ bRouterDevFunc db ? ;PCI IRQ Router dev#(7:3), func#(2:0)
+ wExclusiveIRQ dw ? ;bitmap of IRQs used exclusively for PCI
+ dCompatibleRouter dd ? ;VendorID, DeviceID of compatible IRQ router (low word = VendorID, high word = DeviceID)
+ dMiniPortData dd ? ;MiniPort Data
+ bReserved db 11 dup(?); reserved bytes (set to 0)
+ bChecksum db ? ;checksum
+MSIRQ_HEADER ENDS
+; PCI_IRQ_ENTRY follows the MSIRQ_HEADER, one entry per slot
+
+PCI_IRQ_ENTRY STRUC
+ pirq_bus_number db ? ;PCI bus number of device
+ pirq_device_number db ? ;PCI device number of device (in upper 5 bits)
+ pirq_inta_reg db ? ;Chipset register for this dev's Int A Pin
+ pirq_inta_irqs dw ? ;Bitmap of IRQs routable to Int A Pin
+ pirq_intb_reg db ? ;Chipset register for this dev's Int B Pin
+ pirq_intb_irqs dw ? ;Bitmap of IRQs routable to Int B Pin
+ pirq_intc_reg db ? ;Chipset register for this dev's Int C Pin
+ pirq_intc_irqs dw ? ;Bitmap of IRQs routable to Int C Pin
+ pirq_intd_reg db ? ;Chipset register for this dev's Int D Pin
+ pirq_intd_irqs dw ? ;Bitmap of IRQs routable to Int D Pin
+ pirq_phys_slot db ? ;Physical slot number of device
+ pirq_reserved db ?
+PCI_IRQ_ENTRY ENDS
+
+;PCIDATA_SEG SEGMENT USE32 'DATA'
+PCIDATA_SEG SEGMENT 'DATA'
+
+;<AMI_THDR_START>
+;----------------------------------------------------------------------------
+; Name: ms_irq_routing_table
+;
+; Type: Structure Array
+;
+; Description: The information below is used for two purposes:
+; 1. PCI IRQ routing during POST
+; 2. Runtime dynamic IRQ routing (using Int 1A functions
+; B10E / B10F)
+;
+; The IRQ routing table should contain one entry for each
+; on-board PCI device or PCI slot. Chipset devices such as host
+; bridges and ISA bridges do not need an entry. A generic BIOS
+; can contain a few unused entries that BCP can use when adapting
+; a generic BIOS to a customized BIOS for a motherboard containing
+; on board devices such as PCI IDE, PCI SCSI, or PCI Network chips.
+; BCP can also use a blank entry if a motherboard OEM decides to
+; put an extra
+; PCI slot on their board.
+;
+; The rth_pci_device_limit byte should be set to the total number
+; of entries that are present including any blank entries.
+;
+; The rth_pci_device_count byte should be set to the number of
+; non-blank entries (entries that are actually used in this BIOS).
+;
+; The rth_pci_dedicated_irqs word is a bitmask of IRQs that are
+; dedicated to the PCI bus. (Bit 0 = IRQ 0, ..., Bit 15 = IRQ
+; 15) In most cases this word will be set to all 0's. This
+; word may be used in systems that implement IRQ routing with
+; jumpers.
+;
+; The fields in each table entry are discussed below:
+;
+; - PCI Bus Number: Most boards contain only a single PCI bus,
+; so this byte should usually be set to 0. If a board has
+; multiple PCI busses, then this byte should be set to indicate
+; which bus the device or slot is on.
+;
+; - Dev Num: This field should be set to a slot's or device's
+; address on the PCI bus shifted left by three bits (the device
+; number should be in bits 7:3 and bits 2:0 should be 000).
+;
+; - Int A Pin, Chipset Reg: This field should be set to the
+; chipset register number that controls this slot's (or device's)
+; Int A Pin. The value in this field is basically arbitrary,
+; the value is returned by the function rth_pci_get_irq_reg.
+; Slots and devices that share the same chipset interrupt signal
+; should have the same value for this field.
+; For example:
+; if Slot 1's Int A pin and Slot 2's Int B pin are both connected
+; to the same chipset interrupt signal, then the Chipset Reg
+; value for Slot 1 Int A should match Slot 2 Int B. The core
+; BIOS (and configuration software) need this information to
+; know how IRQs are shared between slots. If a slot or device
+; has nothing connected to its Int A pin, then this field should
+; be set to 0. If a slot or device has its Int A pin hardwired
+; directly to an IRQ, then set this field to 0Fxh (where x is
+; 0-F for IRQ 0 - IRQ 15). This is useful if a motherboard has
+; a PCI IDE chip that has its Int A pin hardwired to IRQ 14.
+;
+; - Int A Pin, Bitmap of IRQs Routeable to Pin: This field should
+; be set to indicate which IRQs the chipset is capable of routing
+; to the slot's (or device's) Int A pin. If the value for Chipset
+; Reg (see above) was set to 0, then set all bits in this field
+; to 0 also. If the value for Chipset Reg was set to 0Fxh to
+; indicate a hardwired connection to a certain IRQ, then only one
+; bit corresponding to that IRQ should be set in this field.
+;
+; - Int B,C,D Pin, Chipset Reg: These fields work exactly like
+; the Chipset Reg field for Int A Pin (see above).
+;
+; - Int B,C,D Pin, Bitmap of IRQs Routeable to Pin: These fields
+; work exactly like the corresponding field for Int A Pin (see above).
+;
+; - Physical Slot Number: This field should be set to the slot
+; number of a PCI slot as it appears to the end user. Numbers
+; like 1, 2, 3, 4 should be used. On board PCI devices such as
+; PCI IDE chips should have this field set to 0 to indicate that
+; the device is not a removable card that is plugged into a slot.
+; Configuration software can use this value to translate a PCI
+; device number (0 - 1F) to a value that is meaningful to an end
+; user.
+;
+; - Reserved Byte: Always set to 0.
+;
+; Notes:
+;
+;----------------------------------------------------------------------------
+;<AMI_THDR_END>
+
+ALIGN 16
+
+ms_irq_routing_table LABEL BYTE
+; MS IRQ routing table header. this header is followed by all PCI slot entries.
+; MSIRQ_HEADER <>
+ db '$PIR' ; signature
+ db 0, 1 ;version (low byte = minor, high byte = major)
+ dw size(MSIRQ_HEADER) + (OFFSET Irq_table_empty_entries - \
+ OFFSET rth_pci_irq_routing_table) ;length of routing table including header and slots
+ db 0 ;PCI IRQ Router bus# (to be updated during runtime)
+ db 0 ;PCI IRQ Router dev#(7:3), func#(2:0), to be updated during runtime.
+ dw 0 ;bitmap of IRQs used exclusively for PCI
+ dd 0 ;VendorID, DeviceID of compatible IRQ router (low word = VendorID, high word = DeviceID)
+ dd 0 ;MiniPort Data
+ db 11 dup(0); reserved bytes (set to 0)
+ db 0 ;checksum (to be updated during runtime)
+
+rth_pci_irq_routing_table LABEL BYTE
+ include oempir.inc
+pci_irq_entry <>
+
+Irq_table_empty_entries LABEL BYTE
+; PCI IRQ routing entries defined after this label are not included.
+
+ PUBLIC IRQ_Table_end
+IRQ_Table_end LABEL BYTE
+
+PCIDATA_SEG ENDS
+end
+
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/CSM/PciInfo.asm b/Core/EM/CSM/PciInfo.asm
new file mode 100644
index 0000000..0662e0a
--- /dev/null
+++ b/Core/EM/CSM/PciInfo.asm
@@ -0,0 +1,83 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/PciInfo.asm 6 1/12/10 11:46a Olegi $
+;
+; $Revision: 6 $
+;
+; $Date: 1/12/10 11:46a $
+;**********************************************************************
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/PciInfo.asm $
+;
+; 6 1/12/10 11:46a Olegi
+; Copyright message updated.
+;
+; 5 4/27/07 5:13p Olegi
+; CSM.CHM file preparation.
+;
+; 4 8/24/06 3:05p Felixp
+; 1. x64 support
+; 2. Unused code removed
+;
+; 3 5/16/06 1:57p Olegi
+;
+; 2 11/07/05 4:37p Olegi
+;
+; 1 6/21/05 12:12p Olegi
+; LegacyBios and LegacyBiosPlatform are combined into one FFS.
+;
+; 3 4/04/05 5:08p Mandal
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: PciInfo.asm
+;
+; Description: This file includes the PCI related tables generated by AMISDL
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+IFNDEF EFIx64
+.586P
+option language:c
+ENDIF
+
+IFNDEF EFIx64
+PCIDATA_SEG SEGMENT USE32 'DATA'
+ELSE
+PCIDATA_SEG SEGMENT 'DATA'
+ENDIF
+ include busnumxlat.inc
+PCIDATA_SEG ENDS
+end
+
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2010, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/CSM/PciInterrupts.c b/Core/EM/CSM/PciInterrupts.c
new file mode 100644
index 0000000..057315d
--- /dev/null
+++ b/Core/EM/CSM/PciInterrupts.c
@@ -0,0 +1,1136 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Core/PciInterrupts.c 55 4/09/13 9:25a Olegi $
+//
+// $Revision: 55 $
+//
+// $Date: 4/09/13 9:25a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Core/PciInterrupts.c $
+//
+// 55 4/09/13 9:25a Olegi
+// [TAG] EIP118727
+// [Category] New Feature
+// [Description] Onboard PCI Option ROM loading is moved outside CSM
+// [Files] CSM.mak
+// CSM.dxs
+// CSM.c
+// PciInterrupts.c
+// CsmBsp.c
+// CsmLib.c
+//
+// 54 11/16/12 10:15a Olegi
+// Typo in previous checkin.
+//
+// 53 11/13/12 12:15p Olegi
+// [TAG] EIP99683
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System Hang at status code AE with Optimization disabled
+// [RootCause] Intx2Pirq function (PciInterrupts.c) returns various
+// errors. However, only EFI_NOT_FOUND is taken into consideration by the
+// caller.
+// [Solution] Analyze all errors returned by Intx2Pirq function.
+// [Files] PciInterrupts.c
+//
+// 52 4/09/12 5:32p Olegi
+// [TAG] EIP86722
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Function "GetXlatPciBusNumber" does not work
+// [RootCause] C-style output does not match with the ASM style output
+// [Solution] Corrected the XLAT table parse function depending on the
+// version of PCI driver.
+// [Files] PciInterrupts.c
+//
+// 51 12/13/11 11:31a Olegi
+// [TAG] EIP77755
+// [Category] Improvement
+// [Description] Modified CreateAddonBusEntry function to return if
+// requested bus # is already present in AddonPciBusTable.
+// [Files] PciInterrupts.c
+//
+// 50 12/14/10 12:02p Olegi
+// [TAG] EIP44553
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] PCI recovery card is disabled during its Option ROM
+// execution
+// [RootCause] Some mass storage controllers are not enabled before
+// option ROM execution.
+// [Solution] Modified CsmBlkIo driver to enable device before calling
+// InstallPciRom function. Device enable code is removed from
+// PciIterrupts.c
+// [Files] PciInterrupts.c, CsmBlkIo.c
+//
+// 49 11/09/10 9:39a Olegi
+// PCI_TRACE macro replaced with TRACE.
+//
+// 48 7/08/10 11:35a Olegi
+// Modified IRQ distribution logic to achieve maximum interrupt
+// dispersion. EIP39733
+//
+// 47 6/18/10 10:30a Olegi
+// EIP39733: Change in RoutePciIrq function.
+//
+// 46 3/02/10 5:17p Olegi
+// Making use of AmiExtPciBusProtocol when PCI Bus driver version is 240
+// or newer.
+//
+// 45 1/28/10 9:07a Olegi
+// ProgramPciIrq: added code that sends a notification about PCI IRQ
+// programming.
+//
+// 44 1/12/10 11:46a Olegi
+// Copyright message updated.
+//
+// 43 12/08/09 5:06p Olegi
+//
+// 42 9/23/09 9:25a Olegi
+// GetP2PSecondaryBusNum:: Fixed the problem of reading PCI device on bus
+// 80h or more.
+//
+// 41 8/07/09 2:43p Rameshr
+// SD boot support Added.
+//
+// 40 8/05/09 5:25p Olegi
+// Variable types redefinition that fixes the 32-bit mode compilation
+// warning.
+//
+// 39 6/16/09 1:52p Olegi
+// Correction in UpdatePrt() function for multiple root bridge
+// configuration.
+//
+// 38 3/10/09 1:49p Olegi
+// Added trace message in RoutePciIrq.
+//
+// 37 3/09/09 11:47a Olegi
+// Bugfix in ProgramPciIrq OEM interrupt masking: EIP#18668
+//
+// 36 12/11/08 10:16a Olegi
+// Bugfix in ProgramPciIrq; EIP#16563
+//
+// 35 11/13/08 1:01p Olegi
+// Added GetPlatformInfo call before programming PCI IRQ.
+//
+// 34 11/03/08 2:19p Olegi
+// Bugfix in UpdatePrt(), EIP #15167
+//
+// 33 10/01/08 11:50a Olegi
+// Fix for a device behind two or more P2P bridges (EIP#16563).
+//
+// 32 8/08/08 9:26a Olegi
+// Modified UpdatePrt function, invalid entries in BusNumXlat table as
+// well as in $PIR table are suppressed.
+//
+// 31 6/20/08 10:20a Olegi
+// Fix for the PCI IRQ routing table parser when PCI bus is FF.
+//
+// 30 11/02/07 10:39a Olegi
+// Added BspUpdatePrt function.
+//
+// 29 9/19/07 10:14a Olegi
+// Bugfix in CreateAddonBusEntry.
+//
+// 28 6/18/07 5:47p Olegi
+//
+// 27 6/04/07 10:47a Olegi
+//
+// 26 4/27/07 5:47p Olegi
+//
+// 25 4/27/07 5:13p Olegi
+// CSM.CHM file preparation.
+//
+// 24 4/26/07 4:24p Olegi
+//
+// 23 4/26/07 2:44p Olegi
+// Correction in RoutePciIrq routine, that will not do the routing if the
+// given register is already programmed.
+//
+// 22 4/13/07 9:46a Olegi
+//
+//**********************************************************************
+
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciInterrupts.c
+//
+// Description: PCI Interrupt routing functions
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+
+#include <AmiDxeLib.h>
+#include <Pci.h>
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_SUB_CLASS_INTELLIGENT 0x00
+
+#include <AcpiRes.h>
+#include <Token.h>
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/LegacyBiosPlatform.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/Legacy8259.h>
+#include "csm.h"
+#include "AmiCspLib.h"
+#include <Protocol/AmiBoardInfo.h>
+
+EFI_GUID gEfiPciRootBridgeIoProtocol = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+
+VOID *gPciIoNotifyReg;
+extern EFI_BOOT_SERVICES *pBS;
+BIOS_INFO *CoreBiosInfo;
+EFI_LEGACY_PIRQ_TABLE_HEADER *MsPrt; // To be obtained after
+EFI_LEGACY_IRQ_ROUTING_ENTRY *Prt; // reading GUIDed section.
+UINTN gUsedPciEntries;
+
+
+
+extern BOOLEAN IsValidPrt;
+extern PLATFORM_BIOS_INFO *BspBiosInfo;
+
+EFI_GUID gBusNumXlatProtocol = AMICSM_PCIBUSNUM_XLAT_PROTOCOL_GUID;
+AMICSM_PCIBUSNUM_XLAT_PROTOCOL BusNumXlatProtocol;
+
+extern AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfo;
+
+UINTN CopyLegacyTable(VOID*, UINT16, UINT16, UINT16);
+
+UINT8 *BusNumXlat;
+UINT8 *BusNumXlatEnd;
+
+EFI_HANDLE gHandle = NULL;
+UINTN PciRBHandlesNo=0;
+EFI_HANDLE *PciRBHandles=NULL;
+UINT16 XlatTblEntriesRemaining=0;
+//
+// The following two external variables specifiy the PCI device/function number of the root
+// bridge(s). Number of entries in this table defined by RbCount.
+// This data is a missing link between RootBridgeIo and PciIo, which allows to update
+// BusNumXlat table with actual bus numbers.
+// Each entry in the RbMap is a pair of RootBridge UID (UINT32), provided in RootBridge
+// device path, and PCI Dev/Func number (UINT8) that can be used to access Root Bridge on
+// PCI bus.
+//
+extern ROOT_BRIDGE_MAPPING_ENTRY RbMap[];
+extern UINTN RbCount;
+
+UINT8 SBGen_GetPIRQIndex (UINT8);
+
+UINT8 irq_priority_map[] = {11, 10, 9, 15, 5, 3, 7, 4, 14};
+UINT8 irq_allocated_count[sizeof(irq_priority_map)] = {0};
+UINT16 IsaIrqMask;
+
+EFI_ADDON_PCIBUS_TABLE AddonPciBusTable[MAX_ADDITIONAL_P2P_BRIDGES];
+
+UINT8 gAddonPciBusIndx;
+
+EFI_LEGACY_8259_PROTOCOL *i8259;
+
+PROGRAMMED_PCIIRQ_CTX gIrqPgmCtx = {0};
+EFI_GUID gPciIrqProgramGuid = EFI_PCIIRQ_PGM_PROTOCOL_GUID;
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RoutePciIrq
+//
+// Description: This routine selects the IRQ from the list of allowed PCI
+// interrupts, picks the best interrupt number according to
+// interrupt priority table and programs the PCI interrupt
+// router.
+// Input:
+// Int - zero based index in the list of router registers for INTA, INTB,...
+// Irq - new interrupt number
+// IrqMask - IRQ bit mask, bits are set for the interrupts that are not allowed
+//
+// Output: EFI_SUCCESS if interrupt is routed
+// EFI_ABORTED if routing register is already programmed
+//
+// Notes: This routine can not be called externally. It is to be
+// called after TranslatePirq returns the Rirq register is
+// not programmed.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RoutePciIrq(
+ IN UINT8 Int,
+ OUT UINT8 *Irq,
+ IN UINT16 IrqMask
+)
+{
+ UINT16 Mask = ~IrqMask; // PIC-style mask (1 is for interrupts that are not allowed)
+ EFI_LEGACY_INTERRUPT_PROTOCOL *iInterrupt;
+ UINT8 NewIrq;
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT8 IrqIndex;
+ UINT8 IrqFound = FALSE;
+
+ Status = pBS->LocateProtocol (&gEfiLegacyInterruptProtocolGuid, NULL, &iInterrupt);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // See if routing register is already programmed, return EFI_ABORTED if so.
+ //
+ Status = iInterrupt->ReadPirq(iInterrupt, Int, &NewIrq);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i=0; irq_priority_map[i]; i++) {
+ if (NewIrq==irq_priority_map[i]) {
+TRACE(((UINTN)-1, "The requested PIRQ[%d] is already programmed to IRQ%x. PCI Routing ABORTED.\n", Int, NewIrq));
+ return EFI_ABORTED;
+ }
+ }
+
+TRACE(((UINTN)-1,"..........IRQ MASK %x....", Mask));
+ //
+ // Remove ISA interrupts from Mask
+ //
+ Mask |= IsaIrqMask;
+
+TRACE(((UINTN)-1,"%x....\n", Mask));
+ //
+ // Find the next available interrupt; irq_priority_map is zero-terminated array
+ // used as priority list. Lower index in irq_priority_map indicates higher priority
+ // interrupt.
+ // Initially irq_priority_index is the index of zero in irq_priority_map; it will
+ // be advanced to the beginning in the following for loop.
+ //
+ for (IrqIndex = 0; IrqIndex < sizeof(irq_priority_map); IrqIndex++) {
+TRACE(((UINTN)-1,"IrqIndex %d....Allocated %d....\n", IrqIndex, irq_allocated_count[IrqIndex]));
+ if (!((1 << irq_priority_map[IrqIndex]) & Mask)) {
+ IrqFound = TRUE; // Assume that IRQ was found
+ for (i = 0; i < sizeof(irq_allocated_count); i++) {
+ // Check if the least allocated IRQ
+ if (!((1 << irq_priority_map[i]) & Mask)) {
+ if (irq_allocated_count[IrqIndex] > irq_allocated_count[i]) {
+ IrqFound = FALSE;
+ break;
+ }
+ }
+ }
+ }
+ if (IrqFound) break;
+ }
+ if (!IrqFound) return EFI_NOT_FOUND;
+
+ irq_allocated_count[IrqIndex] += 1;
+ NewIrq = irq_priority_map[IrqIndex];
+
+ // Adjust irq_priority_index
+
+ Status = iInterrupt->WritePirq(iInterrupt, Int, NewIrq);
+ if (EFI_ERROR(Status)) return Status;
+
+ *Irq = NewIrq;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Intx2Pirq
+//
+// Description: This function is similar to TranslatePirq with the additional
+// output of IrqMask. See TranslatePirq description.
+// Input:
+// This Indicates the EFI_LEGACY_BIOS_PLATFORM_PROTOCOL instance.
+// PCI bus, device and function number for this device.
+// Pirq The PIRQ. PIRQ A = 0, PIRQ B = 1, and so on.
+// PirqIrq IRQ assigned to the indicated PIRQ.
+// IrqMask Mask of IRQs that could be assigned to this register
+//
+// Output:
+// EFI_SUCCESS The PIRQ was translated.
+// EFI_NOT_FOUND The device was not in the table.
+// EFI_NOT_READY The interrupt translation table is not ready.
+// EFI_INVALID_PARAMETER Wrong input
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Intx2Pirq (
+ IN EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *This,
+ IN UINTN PciBus,
+ IN UINTN PciDevice,
+ IN UINTN PciFunction,
+ IN OUT UINT8 *Pirq,
+ OUT UINT8 *PciIrq,
+ OUT UINT16 *IrqMask OPTIONAL
+ )
+{
+ UINT8 Irq;
+ UINT8 counter;
+ EFI_LEGACY_IRQ_ROUTING_ENTRY *p;
+ EFI_LEGACY_INTERRUPT_PROTOCOL *iInterrupt;
+ EFI_STATUS Status;
+
+ UINT8 PciDev;
+ UINT8 rr = 0; // Router register
+ UINT8 rrIndx; // Router register index
+ UINT8 pirq = *Pirq;
+ UINT8 i;
+
+ if (!IsValidPrt) return EFI_NOT_READY;
+
+ if (pirq > 3) {
+ TRACE (((UINTN)TRACE_ALWAYS, "Invalid PIRQ value (%d, %d, %d) %d\n", PciBus, PciDevice, PciFunction, pirq));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PciDev = (UINT8)(PciDevice << 3);
+
+ for (p = Prt, counter = 0; counter < gUsedPciEntries; counter++, p++) {
+ if ((PciBus == p->Bus) && (PciDev == p->Device)) {
+ rr = p->PirqEntry[pirq].Pirq;
+ if (IrqMask != NULL) *IrqMask = p->PirqEntry[pirq].IrqMask;
+ break; // rrIndx is found
+ }
+ }
+
+ if (counter == gUsedPciEntries) {
+ if (gAddonPciBusIndx == 0) return EFI_NOT_FOUND; // No additional P2P bridges
+
+ //
+ // Not found in &PIR - see if device is generated by the P2P which is not
+ // listed in BusNumXlat, e.g. it is behind P2P bridge located on off-board card.
+ //
+ for (counter = 0; counter < gAddonPciBusIndx; counter++) {
+ if (AddonPciBusTable[counter].Bus == PciBus) {
+ i = (UINT8)((PciDevice + pirq) % 4); // INTA/B/C/D for Dev0, INTB/C/D/A for dev1, etc.
+ rr = AddonPciBusTable[counter].PirqEntry[i].Pirq;
+ if (IrqMask != NULL) *IrqMask = AddonPciBusTable[counter].PirqEntry[i].IrqMask;
+ break;
+ }
+ }
+ if (counter == gAddonPciBusIndx) return EFI_NOT_FOUND; // Device not found
+ }
+
+ //
+ // Find the index of given register within RRegs
+ //
+ rrIndx = SBGen_GetPIRQIndex (rr);
+ if (rrIndx == 0xFF) return EFI_UNSUPPORTED;
+
+ //
+ // Get the programmed interrupt number off the LegacyInterrupt for rrIndx
+ //
+ Status = pBS->LocateProtocol (&gEfiLegacyInterruptProtocolGuid, NULL, &iInterrupt);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = iInterrupt->ReadPirq(iInterrupt, rrIndx, &Irq);
+ if (EFI_ERROR(Status)) return Status;
+
+ *Pirq = rrIndx;
+ *PciIrq = Irq;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CreateAddonBusEntry
+//
+// Description: This function inserts a new entry into AddonPciBusTable.
+//
+// Input:
+// Bus - new bus number
+// PirqData - pointer to the new PIRQ data array
+//
+// Output:
+// EFI_SUCCESS Entry has been created successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateAddonBusEntry(
+ UINT8 Bus,
+ VOID *PirqData
+)
+{
+ UINT8 i;
+
+ // Check if the requested entry already exists in AddonPciBusTable. This will be
+ // the case when PCI bus driver has been reconnected.
+ //
+ for (i = 0; i < gAddonPciBusIndx; i++) {
+ if (AddonPciBusTable[i].Bus == Bus) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Insert new entry into AddonPciBusTable
+ //
+ AddonPciBusTable[gAddonPciBusIndx].Bus = Bus;
+ pBS->CopyMem(
+ AddonPciBusTable[gAddonPciBusIndx].PirqEntry,
+ PirqData,
+ sizeof(EFI_LEGACY_PIRQ_ENTRY)*4
+ );
+ TRACE((-1, "AddonPciBusTable entry [%d] created: Bus %x, PIRQs: %x %x %x %x\n",
+ gAddonPciBusIndx,
+ AddonPciBusTable[gAddonPciBusIndx].Bus,
+ AddonPciBusTable[gAddonPciBusIndx].PirqEntry[0].Pirq,
+ AddonPciBusTable[gAddonPciBusIndx].PirqEntry[1].Pirq,
+ AddonPciBusTable[gAddonPciBusIndx].PirqEntry[2].Pirq,
+ AddonPciBusTable[gAddonPciBusIndx].PirqEntry[3].Pirq));
+
+ gAddonPciBusIndx++;
+ ASSERT(gAddonPciBusIndx<MAX_ADDITIONAL_P2P_BRIDGES);
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CheckP2PBridge
+//
+// Description: This function verifies whether device is P2P bridge which is
+// not listed in BusNumXlat table, e.g. bridge is on PCI Add-on card.
+// For this bridge we create a new entry in AddonPciBusTable which
+// will be used for PCI IRQ routing for the devices that are located
+// behind this bridge.
+// Input:
+// PciIo pointer to EFI_PCI_IO_PROTOCOL protocol associated with this device
+// Bus, Dev PCI bus location for this device
+//
+// Output:
+// EFI_SUCCESS Device is P2P bridge; if bus generated by this bridge is not
+// described in $PIR table, then another entry in AddonPciBusTable
+// is created.
+// EFI_NOT_FOUND Device is not P2P bridge.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckP2PBridge(
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 Bus,
+ UINT8 Dev
+)
+{
+ EFI_STATUS Status;
+ UINT16 PciClassSubclass;
+ UINT8 SecBusNum;
+ EFI_LEGACY_IRQ_ROUTING_ENTRY *re;
+ UINT8 counter;
+
+ //
+ // Check if this is a P2P bridge
+ //
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, 0xA, 1, &PciClassSubclass);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Base Class=6 Ofs B (Bridge), SubClass=4 Ofs A (P2P Bridge)
+ //
+ if (PciClassSubclass != 0x0604) return EFI_NOT_FOUND;
+ //
+ // It is P2P bridge - read its secondary bus number and try to find a match in
+ // BusNumXlat table
+ //
+ TRACE((-1,"P2P bridge.\n"));
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET,
+ 1,
+ &SecBusNum);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Locate the P2P bridge as PCI device in $PIR and get EFI_LEGACY_IRQ_ROUTING_ENTRY;
+ // if found - insert new entry into AddonPciBusTable and return EFI_SUCCESS,
+ // otherwise return EFI_NOT_FOUND.
+ //
+ for (re = Prt, counter = 0; counter < gUsedPciEntries; counter++, re++) {
+ if ((re->Bus == Bus) && (re->Device == (Dev << 3))) {
+ return CreateAddonBusEntry(SecBusNum, re->PirqEntry);
+ }
+ }
+ //
+ // Not found in $PIR table - try AddonPciBusTable
+ //
+
+ if (gAddonPciBusIndx == 0) return EFI_NOT_FOUND; // No additional P2P bridges
+
+ for (counter = 0; counter < gAddonPciBusIndx; counter++) {
+ if (AddonPciBusTable[counter].Bus == Bus) {
+ //
+ // Connected to an add-on bridge, do the INT pin swizzling
+ //
+ EFI_LEGACY_PIRQ_ENTRY PirqData[4];
+ UINT8 RoundRobinXlatTable[4][4] = {
+ 0, 1, 2, 3,
+ 1, 2, 3, 0,
+ 2, 3, 0, 1,
+ 3, 0, 1, 2
+ };
+ UINT8 i = (UINT8)(Dev % 4);
+ UINT8 counter1;
+
+ for (counter1 = 0; counter1 < 4; counter1++) {
+ pBS->CopyMem(
+ &PirqData[counter1],
+ &AddonPciBusTable[counter].PirqEntry[RoundRobinXlatTable[i][counter1]],
+ sizeof(EFI_LEGACY_PIRQ_ENTRY)
+ );
+ }
+
+ return CreateAddonBusEntry(SecBusNum, PirqData);
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetIsaIrqs
+//
+// Description: Returns the ISA interrupt mask
+//
+// Input: None
+//
+// Output: ISA interrupt mask
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetIsaIrqs(
+ OUT UINT16 *IrqMask
+)
+{
+ EFI_STATUS Status;
+
+ Status=AmiIsaIrqMask(IrqMask, TRUE);
+ if(EFI_ERROR(Status)){
+ *IrqMask = ISA_IRQ_MASK; // allow IRQ 0..8, 12..15 for ISA
+ Status=AmiIsaIrqMask(IrqMask, FALSE);
+ TRACE(((UINTN)-1, "PciInterrupts: Set ISA_IRQ_MASK, Status=%r\n", Status));
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ProgramPciIrq
+//
+// Description: This function assigns IRQ to a PCI device. It programs PCI
+// IRQ register if:
+// - device requires IRQ to be assigned (reg 3D is 1..3)
+// - PCI bus information is updated in $PIR table (step 1
+// has been completed)
+// - device is present in IRQ routing table
+// When all these conditions are met, then IRQ is assigned to this
+// device according to the PCI IRQ priorities; then IRQ is programmed
+// in PCI register 3C
+//
+// Input: PCI Bus, Device and Function number of the PCI device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ProgramPciIrq(
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ VOID *Context)
+{
+ UINT16 IrqMask;
+ UINT16 Mask, EdgeLevel;
+ UINT8 Int, Irq;
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *iBiosPlatform;
+ UINTN Seg, Bus, Dev, Func;
+ UINTN OemIrqMask;
+
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Func);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ TRACE((-1,"PCI device: %x %x %x ... ", Bus, Dev, Func));
+
+ //
+ // Find out whether device is P2P bridge that is not listed in BusXlatNum table;
+ // if found - add entry into P2P bridge table and exit. Function returns:
+ // EFI_NOT_FOUND - not P2P bridge; EFI_SUCCESS - P2P bridge found and bridge table
+ // is updated.
+ //
+ Status = CheckP2PBridge(PciIo, (UINT8)Bus, (UINT8)Dev);
+
+ //
+ // Check if device requires IRQ
+ //
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0x3D, 1, &Int);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return;
+
+ if (!Int) {
+ TRACE((-1,"does not require IRQ.\n"));
+ return; // Device does not support IRQ
+ }
+
+ Int--; // Zero based INTx
+ iBiosPlatform = (EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *)Context;
+ Status = Intx2Pirq(
+ iBiosPlatform,
+ Bus, Dev, Func,
+ &Int,
+ &Irq,
+ &IrqMask);
+
+ TRACE((-1,"Intx2Pirq returns %r\n", Status));
+
+ if (Status == EFI_NOT_FOUND) {
+ // Device is not in the table
+ TRACE((-1,"Device is not found in the PCI IRQ routing table.\n"));
+ }
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ //
+ // Intx2Pirq returns:
+ // Int - routing register index;
+ // Irq - interrupt currently programmed in that index.
+ // IrqMask - bit mask of the interrupts that can possibly be
+ // assigned to this device.
+ //
+
+ // Call OEM function that can modify the list of interrupts that can be
+ // assigned. Note that the list can only be shrunk, not extended.
+
+ Status = CoreBiosInfo->iBiosPlatform->GetPlatformInfo(
+ CoreBiosInfo->iBiosPlatform,
+ EfiGetPlatformPciIrqMask,
+ &PciIo,
+ NULL, NULL,
+ &OemIrqMask,
+ IrqMask,
+ 0);
+ if (!EFI_ERROR(Status)) {
+ IrqMask &= (UINT16)OemIrqMask;
+ }
+
+ Status = RoutePciIrq(Int, &Irq, IrqMask);
+
+ TRACE((-1,"RoutePciIrq status: %r, Intx2Pirq: Int %x IRQ %x mask %x\n", Status, Int, Irq, IrqMask));
+
+ Status = PciIo->Pci.Write(PciIo, EfiPciIoWidthUint8, 0x3C, 1, &Irq);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return;
+
+ //
+ // Set corresponding mask and edge/level mode in 8259 for real mode operation
+ //
+ i8259->GetMask(i8259, &Mask, &EdgeLevel, NULL, NULL);
+ Mask &= (UINT16)~(1 << Irq);
+ EdgeLevel |= (UINT16)(1 << Irq);
+ i8259->SetMask(i8259, &Mask, &EdgeLevel, NULL, NULL);
+
+ // Send out a word about programmed PCI interrupt
+ gIrqPgmCtx.PciIo = (VOID*)PciIo;
+ gIrqPgmCtx.Irq = Irq;
+ Status = pBS->ReinstallProtocolInterface(
+ gHandle,
+ &gPciIrqProgramGuid,
+ &gIrqPgmCtx,
+ &gIrqPgmCtx
+ );
+ ASSERT_EFI_ERROR(Status);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetXlatPciBusNumber
+//
+// Description: This function returns the PCI bus number translated according
+// to Xlat table defined in BusNumXlat.inc. This translation file
+// is generated by AMISDL using "BUSNUM_XLAT" output type.
+//
+// Input: Build time PCI bus number - 1st coulmn of the xlat table
+//
+// Output: EFI_SUCCESS, real PCI bus number - 2nd column of the xlat table
+// EFI_NOT_FOUND, the requested bus is not found in the xlat table
+// EFI_INVALID_PARAMETER, if NULL pointer is supplied on input.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetXlatPciBusNumber (
+ IN OUT UINT8 *busNumber
+)
+{
+ UINT8 *p;
+
+ if (busNumber == NULL) return EFI_UNSUPPORTED;
+
+ for(p = BusNumXlat; p < BusNumXlatEnd; p++) {
+ if (*p == *busNumber) {
+ if (*(p+1)==0xFE) return EFI_NOT_FOUND;
+ *busNumber = *(p+1);
+ return EFI_SUCCESS;
+ }
+ while (*p != 0xFF) {p++;} // p points to -1 at the end of the line
+ // C style BusXlatNum output adds five more Bytes after FF, so skip them
+ p+=5;
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UpdatePrt
+//
+// Description: This function updates $PIR table with the actual PCI bus numbers.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UpdatePrt()
+{
+ EFI_STATUS Status;
+ UINTN count1;//, count2, count3;
+ UINT8 *p;
+ UINT8 chksum = 0;
+ UINTN PrtAddress;
+//-----------------------------------------
+
+ //Check if PciBus Driver updated IRQ Routing Table yet
+ ASSERT(gAmiBoardInfo->DataValid==TRUE);
+
+ //Create an instance of IRQ ROUTING tasble with $PIR Headr
+ p=MallocZ(sizeof(EFI_LEGACY_PIRQ_TABLE_HEADER) + gAmiBoardInfo->PicRoutLength);
+ MemCpy(p,MsPrt,sizeof(EFI_LEGACY_PIRQ_TABLE_HEADER));
+
+ //Since $PRT Table header was created separately
+ //free memory used for Header instance since we have copy it already.
+ pBS->FreePool(MsPrt);
+ MsPrt=(EFI_LEGACY_PIRQ_TABLE_HEADER*)p;
+ p+=sizeof(EFI_LEGACY_PIRQ_TABLE_HEADER);
+ MemCpy(p, gAmiBoardInfo->PicRoutTable, gAmiBoardInfo->PicRoutLength);
+
+ //Update gUsedPciEntries since PciBus Driver removed unused entries from the table
+ gUsedPciEntries=gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE);
+
+ //Update Prt pointer to point at new instance of table and header together.
+ Prt=(EFI_LEGACY_IRQ_ROUTING_ENTRY*)p;
+
+ //Update table size in $PRT header
+ MsPrt->TableSize = (UINT16)(gAmiBoardInfo->PicRoutLength + sizeof(EFI_LEGACY_PIRQ_TABLE_HEADER));
+
+ // Call BSP routine to do Chipset/OEM specific modifications to PRT
+ BspUpdatePrt(&CoreBiosInfo->iBios, MsPrt);
+
+
+ // Checksum the table
+ for (count1 = 0; count1 < MsPrt->TableSize; count1++) {
+ chksum = chksum + *((UINT8*)MsPrt+count1);
+ }
+ MsPrt->Checksum = (~chksum) + 1;
+ IsValidPrt = TRUE;
+
+ // Load the PCI routing table into CSM16
+ PrtAddress = CopyLegacyTable(
+ MsPrt,
+ (UINT16)MsPrt->TableSize,
+ 1, // alignment
+ F0000_BIT);
+ ASSERT(PrtAddress);
+
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion, 0xF0000, 0x10000, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ CoreBiosInfo->Csm16Header->IrqRoutingTablePointer = (UINT32)PrtAddress;
+ CoreBiosInfo->Csm16Header->IrqRoutingTableLength = (UINT32)MsPrt->TableSize;
+
+ Status = CoreBiosInfo->iRegion->Lock (CoreBiosInfo->iRegion, 0xF0000, 0x10000, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ BusNumXlatProtocol.GetXlatPciBusNum = GetXlatPciBusNumber;
+ Status = pBS->InstallProtocolInterface(
+ &gHandle,
+ &gBusNumXlatProtocol,
+ EFI_NATIVE_INTERFACE,
+ &BusNumXlatProtocol
+ );
+ ASSERT_EFI_ERROR(Status);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PciIoNotifyCallback
+//
+// Description: PciIo notification callback. It serves two purposes:
+// 1) Updates bus numbers in BusNumXlat table and in $PIR table. For
+// this the routine uses PciIo to get PCI loaction of the handle;
+// then it will match the found dev/fun against BusNumXlat table
+// and fill global RootBridges data and update bus numbers in
+// $PIR table.
+// 2) Programs PCI IRQ register if:
+// - device requires IRQ to be assigned (reg 3D is 1..3)
+// - PCI bus information is updated in $PIR table (step 1
+// has been completed)
+// - device is present in IRQ routing table
+// When all these conditions are met, then IRQ is assigned to this
+// device according to the PCI IRQ priorities; then IRQ is programmed
+// in PCI register 3C
+//
+// Input: Event - event signaled by the DXE Core upon PciIo installation
+// Context - event context
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PciIoNotifyCallback (
+ EFI_EVENT Event,
+ VOID *Context)
+{
+// UINT16 counter;
+ UINTN BufferSize = sizeof(EFI_HANDLE);
+ EFI_HANDLE Handle;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+ BOOLEAN IsRootBridge;
+ UINT8 dData[4];
+ UINT16 IrqMask;
+
+ if (!IsValidPrt) {
+ //
+ // Set 8259 interrupt mask for 16 bit mode
+ //
+ Status = GetIsaIrqs(&IsaIrqMask); // Ones for ISA IRQs
+ // TRACE((-1, "PciInterrupts: Init PRT Get ISA_IRQ_MASK, Status=%r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ IrqMask = ~IsaIrqMask;
+
+ Status = i8259->SetMask(i8259, &IrqMask, NULL, NULL, NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ UpdatePrt(); // Update bus numbers in PRT
+ }
+
+ //gBS->LocateProtocol(&gEfiPciIoProtocol, gPciIoNotifyReg, &PciIo);
+ Status = pBS->LocateHandle(ByRegisterNotify,
+ NULL, gPciIoNotifyReg, &BufferSize, &Handle);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ //
+ // Locate PciIo protocol installed on Handle
+ //
+ Status = pBS->HandleProtocol(Handle, &gEfiPciIoProtocolGuid, &PciIo);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ //
+ // Check whether Handle is PCI Root Bridge handle.
+ //
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint32,
+ 8, // offset
+ 1, // width
+ &dData);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ IsRootBridge = (dData[1] == 0) &&
+ (dData[2] == PCI_CL_BRIDGE_SCL_HOST) &&
+ (dData[3] == PCI_CL_BRIDGE); // Host bridge
+
+ if (IsRootBridge) return; // Do not process root bridges
+
+ ProgramPciIrq(PciIo, Context);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitPrt
+//
+// Description: Initialize PCI IRQ routing table
+//
+// Input: iBiosPlatform - pointer to EFI_LEGACY_BIOS_PLATFORM_PROTOCOL
+//
+// Output: PCI IRQ routing table initialization status
+//
+// Notes: 1) BusNumXlat table is generated by AMISDL and requires the actual PCI bus
+// number fields to be updated. Actual PCI bus numbers can not be obtained at
+// this time due to the following:
+// - BusNumXlat table provides PCI dev/fun information for the PCI Host Bridge(s),
+// whereas PciRootBridgeIo does not give PCI dev/fun information; in case of
+// several PCI Root Bridges, PCI location ambiguity can not be resolved at this
+// time.
+// - PCI Dev/Fun information for PCI Host bridge(s) is not available until
+// PCI Bus driver installs PciIo on PCI Host Bridge devices' handles.
+//
+// 2) In order to match PCI Root Bridge(s) against the BusNumXlat table, we
+// will register callback notification function that will be called every
+// time PciIo protocol is installed. This would identify every PCI RootBridge's
+// PCI location(dev/fun), allow to match this PCI location against XlatBusNum table,
+// traverse through XlatBusNum table entry and update the appropriate bus number
+// fields in $PIR table.
+//
+// 3) This driver must be made dependent on PciRootBridge driver since it expects
+// the valid information about PCI root bridges.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitPrt(
+ EFI_LEGACY_BIOS_PLATFORM_PROTOCOL *iBiosPlatform
+)
+{
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ EFI_LEGACY_INTERRUPT_PROTOCOL *iInterrupt;
+ UINT8 Dev, Func;
+//------------------------------------------
+
+ Status = pBS->LocateProtocol (&gEfiLegacyInterruptProtocolGuid, NULL, &iInterrupt);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Initialize global variables
+ //
+ MsPrt = MallocZ(sizeof(EFI_LEGACY_PIRQ_TABLE_HEADER));
+ ASSERT(MsPrt!=NULL);
+
+
+ BusNumXlat = (UINT8*)gAmiBoardInfo->BusXlatTable;
+ BusNumXlatEnd = (UINT8*)((UINTN)gAmiBoardInfo->BusXlatTable+gAmiBoardInfo->BusXlatLength);
+ Prt = (EFI_LEGACY_IRQ_ROUTING_ENTRY*)gAmiBoardInfo->PicRoutTable;
+ gUsedPciEntries=gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE);
+ IsValidPrt = FALSE; // becomes TRUE after bus numbers and checksum in $PRT table is updated
+
+ pBS->SetMem(AddonPciBusTable, sizeof(EFI_ADDON_PCIBUS_TABLE)*MAX_ADDITIONAL_P2P_BRIDGES, 0);
+ gAddonPciBusIndx = 0;
+
+ //Fill MSPRT Structure Header
+ MsPrt->Signature=0x52495024; //"$PIR"
+ MsPrt->MinorVersion=0; //version (low byte = minor, high byte = major)
+ MsPrt->MajorVersion=1;
+ MsPrt->TableSize=sizeof(EFI_LEGACY_PIRQ_TABLE_HEADER); //It's only header for now we will connet header and table later
+
+ Status = iInterrupt->GetLocation(iInterrupt, &MsPrt->Bus, &Dev, &Func);
+ if (EFI_ERROR(Status)) return Status;
+
+ MsPrt->DevFun = (Dev << 3) + Func;
+ MsPrt->CompatibleVid = SB_PIRQ_ROUTER_VID;
+ MsPrt->CompatibleDid = SB_PIRQ_ROUTER_DID;
+
+ MemSet(irq_allocated_count, sizeof(irq_allocated_count), 0);
+
+ //
+ // Set 8259 interrupt mask for 16 bit mode
+ //
+ Status = pBS->LocateProtocol (&gEfiLegacy8259ProtocolGuid, NULL, &i8259);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Count number of entries in BusNumXlat table globally in XlatTblEntriesRemaining
+ //
+ XlatTblEntriesRemaining=gAmiBoardInfo->BusXlatEntries;
+ //
+ // Get the list of PCI Root Bridge handles; later on, in the notification callback function,
+ // use this list to find the corresponding bus number.
+ //
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gEfiPciRootBridgeIoProtocol,
+ NULL,
+ &PciRBHandlesNo,
+ &PciRBHandles);
+ ASSERT_EFI_ERROR(Status);
+ if EFI_ERROR(Status) return Status;
+
+ //
+ // Create the notification and register callback function on the PciIo installation,
+ // callback function will update $PIR table
+ //
+ Status = pBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ PciIoNotifyCallback,
+ iBiosPlatform,
+ &Event);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->RegisterProtocolNotify (
+ &gEfiPciIoProtocolGuid,
+ Event,
+ &gPciIoNotifyReg);
+ ASSERT_EFI_ERROR(Status);
+
+ // Install PCI IRQ programming interface
+ gIrqPgmCtx.PciIo = NULL;
+ gIrqPgmCtx.Irq = 0;
+ Status = pBS->InstallProtocolInterface(
+ &gHandle,
+ &gPciIrqProgramGuid,
+ EFI_NATIVE_INTERFACE,
+ &gIrqPgmCtx
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/csmcore.cif b/Core/EM/CSM/csmcore.cif
new file mode 100644
index 0000000..160bbf3
--- /dev/null
+++ b/Core/EM/CSM/csmcore.cif
@@ -0,0 +1,23 @@
+<component>
+ name = "CSM Core"
+ category = ModulePart
+ LocalRoot = "Core\EM\CSM"
+ RefName = "CSMCORE"
+[files]
+"CSM.mak"
+"CSM.dxs"
+"CSM.h"
+"CsmOpROM.c"
+"BiosData.h"
+"CSM.c"
+"CsmHwInfo.c"
+"PciInterrupts.c"
+"PciInfo.asm"
+"OemPir.dat"
+"CsmBsp.c"
+"CsmLib.c"
+"CsmSimpleIn.c"
+[parts]
+"THUNK"
+"CSM_OEM_HOOKS"
+<endComponent>
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c b/Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c
new file mode 100644
index 0000000..6807d3e
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlkIoComponentName.c
@@ -0,0 +1,260 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlkIoComponentName.c 6 12/23/13 3:38p Olegi $
+//
+// $Revision: 6 $
+//
+// $Date: 12/23/13 3:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlkIoComponentName.c $
+//
+// 6 12/23/13 3:38p Olegi
+// EIP128504: implement EFI_COMPONENT2_NAME_PROTOCOL for CsmBlockIo driver
+//
+// 5 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 4 10/03/07 4:41p Yakovlevs
+// Removed Component Name Protocol and its Strings in NO DEBUG mode to
+// save some space.
+//
+// 3 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 2 3/04/05 1:43p Mandal
+//
+// 1 2/15/05 10:59a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBlkIoComponentName.c
+//
+// Description: Set of functions that implement Component Name protocol
+// for the CSM BlockIO driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "CsmBlockIo.h"
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#define LANGUAGE_CODE_ENGLISH "eng"
+#define EFI_COMPONENT_NAME2_PROTOCOL EFI_COMPONENT_NAME_PROTOCOL
+#endif
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+CsmBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+CsmBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+CHAR16 *gCsmBlockIoDriverName = L"AMI CSM Block I/O Driver";
+CHAR16 gCsmBlockIoControllerName[256];
+
+EFI_COMPONENT_NAME2_PROTOCOL gCsmBlockIoComponentName = {
+ CsmBlockIoComponentNameGetDriverName,
+ CsmBlockIoComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: CsmBlockIoComponentNameGetDriverName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// RETURN:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ //
+ //Supports only English
+ //
+ if (!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+ *DriverName = gCsmBlockIoDriverName;
+ return EFI_SUCCESS;
+}
+
+//---------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// FUNCTION: CsmBlockIoComponentNameGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// RETURNS:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//---------------------------------------------------------------------------
+
+EFI_STATUS
+CsmBlockIoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *LegacyBiosExt;
+ UINT8 BbsCount;
+ BBS_TABLE *BbsEntry;
+ UINT32 i;
+ EFI_HANDLE Handle;
+ CHAR8 *Str;
+ UINT8 Index = 0;
+
+ //
+ //Supports only "eng"
+ //
+ if (!Language || !ControllerName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+ if (ChildHandle == NULL) return EFI_UNSUPPORTED;
+
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosExtProtocolGuid, NULL, (VOID**)&LegacyBiosExt);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = LegacyBiosExt->GetBbsTable(&BbsEntry, &BbsCount);
+ if (EFI_ERROR(Status)) return Status;
+
+ ZeroMemory(gCsmBlockIoControllerName, sizeof(gCsmBlockIoControllerName));
+
+ for (i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+ Handle = *(VOID**)(&BbsEntry->IBV1);
+ if (Handle == ChildHandle) {
+ Str = (CHAR8*)(UINTN)((BbsEntry->DescStringSegment<<4) + BbsEntry->DescStringOffset);
+ if (Str == NULL) return EFI_UNSUPPORTED;
+ //
+ // Transfer Ascii code to Unicode
+ //
+ while (Str[Index] != 0) {
+ gCsmBlockIoControllerName[Index] = (CHAR16)Str[Index];
+ Index++;
+ }
+
+ *ControllerName = gCsmBlockIoControllerName;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
new file mode 100644
index 0000000..14438f5
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.c
@@ -0,0 +1,1076 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c 49 8/06/14 1:20p Fasihm $
+//
+// $Revision: 49 $
+//
+// $Date: 8/06/14 1:20p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.c $
+//
+// 49 8/06/14 1:20p Fasihm
+// [TAG] EIP180668
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Aptio 4 CSM: CsmBlkIO: Start function might incorrectly
+// initialize IBV fields in BBS table.
+// [Solution] Maintain the number of newly created BBS entries;
+// initialize IBV fields only for those entries created by the Option ROM.
+// [Files]
+// Core\EM\CSM\thunk\BlockIo\CsmBlockIo.c
+//
+// 48 12/23/13 3:38p Olegi
+// EIP128504: implement EFI_COMPONENT_NAME2_PROTOCOL for CsmBlockIo driver
+//
+// 47 12/23/13 3:14p Olegi
+// EIP148138: use AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL instead of
+// EFI_MBR_WRITE_PROTECTION_PROTOCOL
+//
+// 46 12/23/13 10:22a Olegi
+// EIP148123: CSM includes file which name has been changed
+//
+// 45 12/06/13 12:07a Rameshr
+// [TAG] EIP143793
+// [Category] Improvement
+// [Description] For onboard Raid controller, consumed
+// DevicePathProtocol - By driver and as a child controller, instead of
+// the PciIo Protocol. Because PciIo protocol us already consumed by
+// SataController driver.
+// [Files] CsmBlockIo.c
+//
+// 44 7/01/13 5:56a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 43 3/07/13 10:47p Olegi
+// [TAG] EIP117323
+// [Category] New Feature
+// [Description] Fiber Channel controllers support in CsmBlockIo
+//
+// 42 12/14/12 3:29p Olegi
+//
+// 41 12/23/11 2:12p Olegi
+// [TAG] EIP78921
+// [Category] Improvement
+// [Description] CsmBlockIo should create device handle in BBS table
+// [Files] CsmBlockIo.c
+// CsmBlockIo.h
+//
+// 39 11/10/11 7:15p Olegi
+// Installed thunk driver GUID
+//
+// 38 11/04/11 12:41p Olegi
+//
+// 37 8/15/11 9:45a Olegi
+//
+// 36 8/12/11 3:05p Olegi
+// Correction to the previous check-in: in Supported function some
+// protocols can not be open BY_DRIVER for the onboard RAID. Changed the
+// OpenProtocol attributes.
+//
+// 35 8/10/11 11:48a Olegi
+// GUID and variable names are corrected; Supported function modified to
+// close PciIo protocol right after it is used. EIP49352.
+//
+// 34 7/20/11 12:21p Olegi
+// Added dependency on the HDD security SDL token.
+//
+// 33 6/27/11 4:50p Olegi
+// Cleaning the headers and the comments. Change in Supported function
+// that partially undoing EIP39017 and allows non-Intel RAID option ROMs
+// produce BlkIo.
+//
+// 32 4/27/11 6:47p Olegi
+// [TAG] EIP54911
+// [Category] Improvement
+// [Description] Start function modified to return the proper value.
+// [Files] CsmBlockIo.c
+//
+// 31 1/19/11 10:19a Olegi
+//
+// 29 12/14/10 12:08p Olegi
+// [TAG] EIP48212
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Some controllers are not enabled before executing their
+// Option ROM
+// [RootCause] There is no code that enable a device in CsmBlockIo start
+// function.
+// [Solution] Added a call that enables device to the CsmBlockIo start
+// function.
+// [Files] CsmBlockIo.c, PciInterrupts.c
+//
+// 28 7/29/10 3:20p Olegi
+// EIP39017:: Added code in Supported function to prevent BlockIo from
+// binding prematurely.
+//
+// 27 3/12/10 9:49a Olegi
+// Onboard RAID option ROM related changes. EIP34602.
+//
+// 26 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 25 8/07/09 2:46p Rameshr
+// SD boot support Added.
+//
+// 24 10/04/07 3:04p Olegi
+// Bugfix in CsmBlockIoStart for HW interrupt save/restore in case of
+// multiple drives connected.
+//
+// 23 10/03/07 4:41p Yakovlevs
+// Removed Component Name Protocol and its Strings in NO DEBUG mode to
+// save some space.
+//
+// 22 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 21 4/13/07 9:37a Olegi
+//
+// 20 3/29/07 5:51p Olegi
+//
+// 19 3/29/07 1:37p Felixp
+// Bug fix in BuildDevicePath: properly initialize device path for unknown
+// devices
+//
+// 18 12/07/06 3:13p Olegi
+// Support for embedded OpROMs added.
+//
+// 17 7/31/06 4:11p Olegi
+//
+// 16 5/19/06 11:25p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 15 5/01/06 3:57p Olegi
+// CheckPciRom will be called from LegacyBios.InstallPciRom, no need to
+// call it again.
+//
+// 14 3/13/06 4:15p Felixp
+//
+// 13 3/13/06 2:38p Felixp
+//
+// 12 10/13/05 6:21p Olegi
+// Added HW interrupt handling
+//
+// 11 8/30/05 9:06a Olegi
+// BuildDevicePath correction.
+//
+// 10 7/26/05 2:51p Olegi
+//
+// 9 6/23/05 5:26p Olegi
+//
+// 8 6/22/05 8:34a Olegi
+//
+// 7 4/20/05 4:16p Olegi
+// INT 13 vector maintenance has been moved to the main CSM module.
+//
+// 6 4/12/05 12:21p Olegi
+//
+// 5 3/16/05 11:05a Olegi
+//
+// 4 3/04/05 1:45p Mandal
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBlockIo.c
+//
+// Description: CSM Block I/O Module. Main module, containing entry,
+// supported, start, and stop functions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "CsmBlockIo.h"
+#include <Protocol\Legacy8259.h>
+#include <Protocol\IdeControllerInit.h>
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+#include <Protocol\AmiBlockIoWriteProtection.h>
+AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *gBlockIoWriteProtectionProtocol = NULL;
+#endif
+
+// EFI Driver Binding Protocol Instance
+EFI_DRIVER_BINDING_PROTOCOL gCsmBlockIoDriverBinding = {
+ CsmBlockIoSupported,
+ CsmBlockIoStart,
+ CsmBlockIoStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+extern EFI_COMPONENT_NAME_PROTOCOL gCsmBlockIoComponentName;
+#else
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+extern EFI_COMPONENT_NAME2_PROTOCOL gCsmBlockIoComponentName;
+#endif
+
+// Number of current users of this driver
+UINTN mCurrentUsers = 0;
+
+// Real mode buffer to contain the buffers below
+EFI_PHYSICAL_ADDRESS mRealModeBuffer = 0;
+
+// Packet buffer under 1 MB for all version EDD calls
+EDD_DEVICE_ADDRESS_PACKET *mEDDPacketBuffer;
+
+// EDD 1.1 transfer buffer
+VOID *mEDDTransferBuffer;
+
+// This is a buffer for INT 13h func 48 information
+CSM_LEGACY_DRIVE *mDriveParameterBuffer;
+
+// The following variables will track the onboard mass storage controller
+// in RAID mode with the Option ROM that can not handle ATAPI devices:
+//
+// - gOnboardRaidGuid is GUID installed on such controller in SBDXE
+// - gOnboardRaid is the switch indicating the requested controller
+// has gOnboardRaidGuid installed on it
+//
+#define ONBOARD_RAID_GUID \
+ { 0x5d206dd3, 0x516a, 0x47dc, 0xa1, 0xbc, 0x6d, 0xa2, 0x4, 0xaa, 0xbe, 0x8};
+EFI_GUID gOnboardRaidGuid = ONBOARD_RAID_GUID;
+
+// The following GUID is used to ensure the Start function is executed after all
+// individual drives in RAID are unlocked before RAID Option ROM is executed
+//
+#define HDD_UNLOCKED_GUID \
+ { 0x1fd29be6, 0x70d0, 0x42a4, 0xa6, 0xe7, 0xe5, 0xd1, 0xe, 0x6a, 0xc3, 0x76};
+EFI_GUID gHddUnlockedGuid = HDD_UNLOCKED_GUID;
+
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoEntryPoint
+//
+// Description:
+// This is the CsmBlockIo driver entry point. It installs
+// gCsmBlockIoDriverBinding protocol
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+
+{
+ static EFI_GUID gCsmThunkDriverGuid =
+ { 0x2362ea9c, 0x84e5, 0x4dff, 0x83, 0xbc, 0xb5, 0xac, 0xec, 0xb5, 0x7c, 0xbb };
+
+ gCsmBlockIoDriverBinding.DriverBindingHandle = ImageHandle;
+ gCsmBlockIoDriverBinding.ImageHandle = ImageHandle;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ return pBS->InstallMultipleProtocolInterfaces(
+ &gCsmBlockIoDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gCsmBlockIoDriverBinding,
+ &gComponentNameProtocolGuid, &gCsmBlockIoComponentName,
+ &gCsmThunkDriverGuid, NULL,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoSupported
+//
+// Description:
+// This is a binding protocol function. It checks whether or not this
+// driver supports the given controller
+//
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_STD_DEVICE Pci;
+ VOID *IdeControllerInterface;
+
+ // See if the Legacy BIOS Protocol is available
+ Status = pBS->LocateProtocol( &gEfiLegacyBiosProtocolGuid,
+ NULL, (VOID**)&LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Check whether DevicePath Protocol has been installed on this controller
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ pBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ // Check whether this is Onboard RAID
+ Status = pBS->OpenProtocol( Controller,
+ &gOnboardRaidGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ // Do the checkings/manipulations with the onboard RAID
+ if(!EFI_ERROR(Status))
+ {
+ // Make sure drives are unlocked
+#if defined SETUP_IDE_SECURITY_SUPPORT && SETUP_IDE_SECURITY_SUPPORT == 1
+ Status = pBS->OpenProtocol( Controller,
+ &gHddUnlockedGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+#endif
+ if(EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Make sure IDE_CONTROLLER_PROTOCOL is installed; this ensures the
+ // controller is initialized
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeControllerInitProtocolGuid,
+ (VOID **)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ // Check whether PCI Protocol has been installed on this controller
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID**)&PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ // Read PCI configuration
+ Status = PciIo->Pci.Read (PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci);
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+
+ // Status is EFI_SUCCESS here
+
+ if ( Pci.Header.ClassCode[2] != PCI_CL_MASS_STOR && \
+ (Pci.Header.ClassCode[2] != PCI_BASE_CLASS_INTELLIGENT || \
+ Pci.Header.ClassCode[1] != PCI_SUB_CLASS_INTELLIGENT) )
+ {
+ Status = EFI_UNSUPPORTED;
+ }
+ if ( Pci.Header.ClassCode[1] == PCI_CL_SYSTEM_PERIPHERALS_SCL_SD && \
+ Pci.Header.ClassCode[2] == PCI_CL_SYSTEM_PERIPHERALS )
+ {
+ Status = EFI_SUCCESS;
+ }
+ if ( Pci.Header.ClassCode[1] == PCI_CL_SER_BUS_SCL_FIBCHAN &&
+ Pci.Header.ClassCode[2] == PCI_CL_SER_BUS )
+ {
+ Status = EFI_SUCCESS;
+ }
+
+// TRACE((-1, "\nCsmBlockIo.Supported: called for VID/DID: %x %x, CL %x SCL %x; Status = %r\n",
+// Pci.Header.VendorId, Pci.Header.DeviceId, Pci.Header.ClassCode[2], Pci.Header.ClassCode[1], Status));
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoStart
+//
+// Description:
+// Installs BlockIoProtocol using INT13 services produced by Option ROM
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Open PCI and Devicepath protocol
+// 2. Enable the device
+// 3. Post the option rom
+// 4. If first time, allocate buffer for real mode thunk code
+// 5. For each disk...
+// a. Allocate and initialize a private structure
+// b. Install block I/O protocol on a new child device
+// c. Open the child device
+// 6. Increment user counter
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+ UINT8 FirstDisk;
+ UINT8 LastDisk;
+ UINT8 x = 0;
+ CSM_BLOCK_IO_DEV *PrivateBlockIoStruc = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *PciDevPath;
+ UINTN i = 0;
+ UINTN Flags;
+ UINTN TempAddress = 0;
+ UINT8 irq = 0;
+ EFI_LEGACY_8259_PROTOCOL *i8259;
+ UINT32 *ivt = (UINT32*)0;
+ UINT32 TempInt;
+ UINT32 HwInterruptHandler;
+ UINT64 Capabilities;
+ UINT8 j = 0;
+ UINT8 BbsCount;
+ BBS_TABLE* BbsEntry = NULL;
+ BBS_TABLE* BbsTable = NULL;
+ BOOLEAN BbsEntryPresent[MAX_BBS_ENTRIES_NO] = {0};
+ UINTN FirstNewBbsEntry = 0;
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *LegacyBiosExt;
+ BOOLEAN OnboardRaidController=FALSE;
+ EFI_DEVICE_PATH_PROTOCOL *ChildPciDevPath;
+ UINT8 NumberOfBbsEntriesBeforeOprom = 0;
+ UINT8 NumberOfBbsEntriesAfterOprom = 0;
+ UINT8 NewBbsEntries;
+
+ // See if the Legacy BIOS Protocol is available
+ Status = pBS->LocateProtocol( &gEfiLegacyBiosProtocolGuid,
+ NULL, (VOID **)&LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // See if the Legacy BIOS Ext Protocol is available
+ Status = pBS->LocateProtocol ( &gEfiLegacyBiosExtProtocolGuid,
+ NULL, (VOID**)&LegacyBiosExt);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ if(gBlockIoWriteProtectionProtocol == NULL)
+ pBS->LocateProtocol(&gAmiBlockIoWriteProtectionProtocolGuid, NULL, &gBlockIoWriteProtectionProtocol);
+#endif
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&PciDevPath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ // Check whether this is Onboard RAID
+ Status = pBS->OpenProtocol( Controller,
+ &gOnboardRaidGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (!EFI_ERROR (Status)) {
+ OnboardRaidController=TRUE;
+ }
+
+ // Open PCI I/O Protocol
+ if (OnboardRaidController) {
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ } else {
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ }
+
+ if ( EFI_ERROR(Status) ) {
+ return Status;
+ }
+
+ // Get the hardware interrupt vector and its handler pointer
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0x3C, 1, &irq);
+ ASSERT_EFI_ERROR(Status);
+ if (irq > 0 && irq < 0xF) {
+ Status = pBS->LocateProtocol(&gEfiLegacy8259ProtocolGuid, NULL, &i8259);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = i8259->GetVector (i8259, irq, &irq); // irq has INT number
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ // Store HW interrupt vector, to be restored for PnP ROMs
+ TempInt = ivt[irq];
+
+ // Enable the device
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+ ASSERT_EFI_ERROR(Status);
+
+ // Check to see if there is a legacy option ROM image associated with this PCI device
+ Status = LegacyBios->CheckPciRom (LegacyBios,
+ Controller,
+ NULL,
+ NULL,
+ &Flags
+ );
+
+ if ( EFI_ERROR(Status) ) {
+ Status = EFI_SUCCESS;
+ goto Done;
+ }
+
+ // Get BBS table
+ Status = LegacyBiosExt->GetBbsTable(
+ &BbsEntry,
+ &BbsCount);
+ ASSERT_EFI_ERROR(Status);
+ BbsTable = BbsEntry;
+
+ // Loop through table and note entries which are populated
+ for (i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+
+ if (BbsEntry->BootPriority == BBS_IGNORE_ENTRY)
+ continue;
+
+ BbsEntryPresent[i] = TRUE;
+ NumberOfBbsEntriesBeforeOprom++;
+ }
+
+ // Post the legacy option ROM if it is available.
+ Status = LegacyBios->InstallPciRom( LegacyBios,
+ Controller,
+ NULL,
+ &Flags,
+ &FirstDisk,
+ &LastDisk,
+ NULL,
+ NULL );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ BbsEntry = BbsTable;
+
+ // Loop through BBS table and find first new entry, added due to OpROM execution
+ for (i = 0; i < MAX_BBS_ENTRIES_NO; i++, BbsEntry++) {
+ if (BbsEntry->BootPriority == BBS_IGNORE_ENTRY)
+ continue;
+ if ((BbsEntryPresent[i] == FALSE) && (FirstNewBbsEntry == 0)) {
+ FirstNewBbsEntry = i;
+ }
+ NumberOfBbsEntriesAfterOprom++;
+ }
+
+ ASSERT(NumberOfBbsEntriesAfterOprom >= NumberOfBbsEntriesBeforeOprom);
+ NewBbsEntries = NumberOfBbsEntriesAfterOprom - NumberOfBbsEntriesBeforeOprom;
+
+ HwInterruptHandler = ivt[irq];
+
+ // All users share a buffer under 1MB to put real mode thunk code in
+ // If it has not been allocated, then we allocate it.
+ if (mRealModeBuffer == 0) {
+ // Allocate below 1MB
+ mRealModeBuffer = 0x00000000000FFFFF;
+ Status = pBS->AllocatePages( AllocateMaxAddress,
+ EfiBootServicesData,
+ BLOCK_IO_BUFFER_PAGE_SIZE,
+ &mRealModeBuffer );
+
+ // Check memory allocation success
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ mRealModeBuffer = 0;
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ // Set up real mode memory for Thunk
+ TempAddress = (UINTN)mRealModeBuffer;
+ // Setup the EDD 1.1 transfer buffer
+ TempAddress += AlignAddress(TempAddress);
+ mEDDTransferBuffer = (VOID *)(TempAddress);
+ // Setup the Legacy Drive buffer
+ TempAddress += MAX_EDD11_XFER;
+ TempAddress += AlignAddress(TempAddress);
+ mDriveParameterBuffer = (CSM_LEGACY_DRIVE *)(TempAddress);
+ // Setup the EDD Packet buffer
+ TempAddress += sizeof (CSM_LEGACY_DRIVE);
+ TempAddress += AlignAddress(TempAddress);
+ mEDDPacketBuffer = (EDD_DEVICE_ADDRESS_PACKET *)TempAddress;
+ }
+
+ // Allocate the private device structure for each disk
+ for (i = FirstDisk, j = 0; i < LastDisk; i++, j++) {
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof (CSM_BLOCK_IO_DEV),
+ &PrivateBlockIoStruc );
+
+ if (EFI_ERROR(Status)) {
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ if (mRealModeBuffer != 0 && mCurrentUsers == 0) {
+ pBS->FreePages (mRealModeBuffer, BLOCK_IO_BUFFER_PAGE_SIZE);
+ mRealModeBuffer = 0;
+ }
+
+ return Status;
+ }
+
+ // Zero the private device structure
+ ZeroMemory (PrivateBlockIoStruc, sizeof (CSM_BLOCK_IO_DEV));
+
+ // Initialize the private device structure
+ PrivateBlockIoStruc->ControllerHandle = Controller;
+ PrivateBlockIoStruc->LegacyBios = LegacyBios;
+ PrivateBlockIoStruc->PciIo = PciIo;
+
+ PrivateBlockIoStruc->Drive.Floppy = FALSE;
+ x = (i & 0x40)? 0x40 : 0;
+ if (x) {
+ PrivateBlockIoStruc->HwInt = irq;
+ PrivateBlockIoStruc->HwIntHandler = HwInterruptHandler;
+ ivt[irq] = TempInt; // Restore HW interrupt
+ }
+ PrivateBlockIoStruc->Drive.Number = (UINT8) i - x;
+ PrivateBlockIoStruc->Drive.Letter = (UINT8)(i - x - 0x80 + 'C');
+ PrivateBlockIoStruc->BlockMedia.RemovableMedia = FALSE;
+
+ if (InitBlockIo (PrivateBlockIoStruc)) {
+ BuildDevicePath( PciDevPath,
+ &PrivateBlockIoStruc->Drive,
+ &PrivateBlockIoStruc->DevicePath);
+
+ // Install the Block Io Protocol onto a new child handle
+ Status = pBS->InstallMultipleProtocolInterfaces( &PrivateBlockIoStruc->Handle,
+ &gEfiBlockIoProtocolGuid,
+ &PrivateBlockIoStruc->BlockIo,
+ &gEfiDevicePathProtocolGuid,
+ PrivateBlockIoStruc->DevicePath,
+ NULL );
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (PrivateBlockIoStruc);
+ }
+
+ // Set handle to which BlockIO has been installed
+ if (j < NewBbsEntries)
+ {
+ *(UINTN*)(&(BbsTable[FirstNewBbsEntry + j].IBV1)) = (UINTN)(PrivateBlockIoStruc->Handle);
+ }
+ if(OnboardRaidController) {
+ // Open For Child Device
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID**)&ChildPciDevPath,
+ This->DriverBindingHandle,
+ PrivateBlockIoStruc->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+ } else {
+
+ // Open For Child Device
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID**)&PrivateBlockIoStruc->PciIo,
+ This->DriverBindingHandle,
+ PrivateBlockIoStruc->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+ }
+ } else {
+ pBS->FreePool (PrivateBlockIoStruc);
+ }
+ } // end for loop
+
+ mCurrentUsers++;
+
+ return Status;
+
+Done:
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+ pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: CsmBlockIoStop
+//
+// Description: Installs IdeControllerProtocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Decrement user counter
+// 2. Free global buffer
+// 3. Release PCI I/O protocol and Block I/O protocol for each child handle.
+// 4. Shut down the hardware for each child handle.
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN AllChildrenStopped;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ CSM_BLOCK_IO_DEV *PrivateBlockIoStruc;
+ UINTN i;
+ BOOLEAN OnboardRaidController=FALSE;
+
+ // Decrement the number of current users
+ mCurrentUsers--;
+
+ if (mCurrentUsers == 0) {
+ // Free our global buffer
+ Status = pBS->FreePages (mRealModeBuffer, BLOCK_IO_BUFFER_PAGE_SIZE);
+ ASSERT_EFI_ERROR (Status);
+ mRealModeBuffer = 0;
+ }
+
+ // Check whether this is Onboard RAID
+ Status = pBS->OpenProtocol( Controller,
+ &gOnboardRaidGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (!EFI_ERROR (Status)) {
+ OnboardRaidController=TRUE;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ // Close protocols and shut down hardware for each child handle.
+ for (i = 0; i < NumberOfChildren; i++) {
+
+ Status = pBS->OpenProtocol( ChildHandleBuffer[i],
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&BlockIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ PrivateBlockIoStruc = (CSM_BLOCK_IO_DEV *) BlockIo;
+
+ if(OnboardRaidController) {
+ pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[i] );
+ }
+
+ // Release PCI I/O and Block IO Protocols on the clild handle.
+ Status = pBS->UninstallMultipleProtocolInterfaces( ChildHandleBuffer[i],
+ &gEfiBlockIoProtocolGuid,
+ &PrivateBlockIoStruc->BlockIo,
+ &gEfiDevicePathProtocolGuid,
+ PrivateBlockIoStruc->DevicePath,
+ NULL );
+
+ if (EFI_ERROR(Status)) {
+ AllChildrenStopped = FALSE;
+ }
+
+ // Shutdown the hardware
+ PrivateBlockIoStruc->PciIo->Attributes (
+ PrivateBlockIoStruc->PciIo,
+ EfiPciIoAttributeOperationDisable,
+ EFI_PCI_DEVICE_ENABLE,
+ NULL);
+
+
+ if(!OnboardRaidController) {
+ pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[i] );
+ }
+
+ pBS->FreePool (PrivateBlockIoStruc);
+ } // end for loop
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = pBS->CloseProtocol( Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ if(!OnboardRaidController) {
+ Status = pBS->CloseProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+// LOCAL FUNCTIONS
+//**********************************************************************
+
+//<AMI_PHDR_START>
+//**********************************************************************
+//
+// Procedure: BuildDevicePath
+//
+// Description: Builds device path for this device
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *BaseDevicePath,
+// IN CSM_LEGACY_DRIVE *Drive,
+// OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Decrement user counter
+// 2. Free global buffer
+// 3. Release PCI I/O protocol and Block I/O protocol for each child handle.
+// 4. Shut down the hardware for each child handle.
+//
+//**********************************************************************
+//<AMI_PHDR_END>
+
+VOID
+BuildDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *BaseDevicePath,
+ IN CSM_LEGACY_DRIVE *Drive,
+ OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+)
+{
+ EFI_GUID UnknownDevGuid = UNKNOWN_DEVICE_GUID; // ditto
+ EFI_DEV_PATH Node;
+ UINT32 Controller;
+
+ Node.DevPath.Type = 0;
+ if (Drive->EddVersion == EDD_VERSION_30 &&
+ Drive->Parameters.StructureSize > 0x1A &&
+ *(UINT32*)Drive->Parameters.InterfaceType != 0) {
+ // Build device path for EDD 3.0 device
+ Controller = (UINT32)Drive->Parameters.InterfacePath.Pci.Controller;
+ if ((MemCmp ("ATAPI", Drive->Parameters.InterfaceType, 5) == 0) ||
+ (MemCmp ("ATA", Drive->Parameters.InterfaceType, 3) == 0)) {
+ // ATA or ATAPI drive found
+ Node.Atapi.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Atapi.Header.SubType = MSG_ATAPI_DP;
+ SET_NODE_LENGTH(&Node.Atapi.Header,sizeof(ATAPI_DEVICE_PATH));
+ Node.Atapi.SlaveMaster = Drive->Parameters.DevicePath.Atapi.Master;
+ Node.Atapi.Lun = Drive->Parameters.DevicePath.Atapi.Lun;
+ Node.Atapi.PrimarySecondary = (UINT8)Controller;
+ } else {
+ // Not an ATA/ATAPI drive
+ if (Controller != 0) {
+ Node.Controller.Header.Type = HARDWARE_DEVICE_PATH;
+ Node.Controller.Header.SubType = HW_CONTROLLER_DP;
+ SET_NODE_LENGTH(&Node.Controller.Header,sizeof(CONTROLLER_DEVICE_PATH));
+ Node.Controller.Controller = Controller;
+ *DevicePath = DPAddNode (BaseDevicePath, &Node.DevPath);
+ Node.DevPath.Type = 0;
+ }
+ // Since it's not ATA/ATAPI, find out what kind it is
+ if (MemCmp("SCSI", Drive->Parameters.InterfaceType, 4) == 0 ) {
+ // SCSI drive
+ Node.Scsi.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Scsi.Header.SubType = MSG_SCSI_DP;
+ SET_NODE_LENGTH(&Node.Scsi.Header,sizeof(SCSI_DEVICE_PATH));
+ Node.Scsi.Lun = (UINT16)Drive->Parameters.DevicePath.Scsi.Lun;
+ Node.Scsi.Pun = Drive->Parameters.DevicePath.Scsi.TargetId;
+ } else if (MemCmp("USB", Drive->Parameters.InterfaceType, 3) == 0 ) {
+ // USB drive
+ Node.Usb.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.Usb.Header.SubType = MSG_USB_DP;
+ SET_NODE_LENGTH(&Node.Usb.Header,sizeof(USB_DEVICE_PATH));
+ Node.Usb.ParentPortNumber = (UINT8)Drive->Parameters.DevicePath.Usb.Reserved;
+ } else if (MemCmp("1394", Drive->Parameters.InterfaceType, 4) == 0 ) {
+ // 1394 drive
+ Node.F1394.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.F1394.Header.SubType = MSG_1394_DP;
+ SET_NODE_LENGTH(&Node.F1394.Header,sizeof(F1394_DEVICE_PATH));
+ Node.F1394.Guid = Drive->Parameters.DevicePath.FireWire.Guid;
+ } else if (MemCmp("FIBRE", Drive->Parameters.InterfaceType, 5) == 0 ) {
+ // Fibre Channel drive
+ Node.FibreChannel.Header.Type = MESSAGING_DEVICE_PATH;
+ Node.FibreChannel.Header.SubType = MSG_FIBRECHANNEL_DP;
+ SET_NODE_LENGTH(&Node.FibreChannel.Header,sizeof(FIBRECHANNEL_DEVICE_PATH));
+ Node.FibreChannel.WWN = Drive->Parameters.DevicePath.FibreChannel.Wwn;
+ Node.FibreChannel.Lun = Drive->Parameters.DevicePath.FibreChannel.Lun;
+ }
+ }
+ }
+ // If Device Path Type is still zero, it means this is either EDD 1.1 device
+ // or unreconized EDD 3.0 device. Add vendor HW device node for such devices
+ if (Node.DevPath.Type == 0) {
+ Node.UnknownVendor.DevicePath.Header.Type = HARDWARE_DEVICE_PATH;
+ Node.UnknownVendor.DevicePath.Header.SubType = HW_VENDOR_DP;
+ SET_NODE_LENGTH(&Node.UnknownVendor.DevicePath.Header,sizeof(UNKNOWN_DEVICE_VENDOR_DEVICE_PATH));
+ Node.UnknownVendor.DevicePath.Guid = UnknownDevGuid;
+ Node.UnknownVendor.LegacyDriveLetter = Drive->Number;
+ }
+ *DevicePath = DPAddNode (BaseDevicePath, &Node.DevPath);
+}
+
+// Align address on boundary of UINTN for this compiler
+UINTN AlignAddress (UINTN Address)
+{
+ if((UINTN)Address % sizeof(UINTN)) {
+ return sizeof(UINTN) - ((UINTN)Address % sizeof(UINTN));
+ } else {
+ return 0;
+ }
+}
+
+// Zero memory
+VOID ZeroMemory (
+ VOID *Buffer,
+ UINTN Size
+)
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h
new file mode 100644
index 0000000..59ce30b
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.h
@@ -0,0 +1,277 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.h 10 12/23/11 2:12p Olegi $
+//
+// $Revision: 10 $
+//
+// $Date: 12/23/11 2:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmBlockIo.h $
+//
+// 10 12/23/11 2:12p Olegi
+// [TAG] EIP78921
+// [Category] Improvement
+// [Description] CsmBlockIo should create device handle in BBS table
+// [Files] CsmBlockIo.c
+// CsmBlockIo.h
+//
+// 9 6/27/11 4:50p Olegi
+//
+// 8 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 7 9/23/09 11:18a Olegi
+//
+// 6 8/07/09 2:46p Rameshr
+// SD boot support Added.
+//
+// 5 10/03/07 4:42p Yakovlevs
+// Removed Component Name Protocol and its Strings in NO DEBUG mode to
+// save some space.
+//
+// 4 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 3 3/13/06 2:38p Felixp
+//
+// 2 3/04/05 1:45p Mandal
+//
+// 1 2/15/05 11:00a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmBlockIo.h
+//
+// Description: CSM BlockIO driver header file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _CsmBlockIo_
+#define _CsmBlockIo_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <PCI.h>
+#include <AmiDxeLib.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LegacyBios.h>
+#include <Protocol\LegacyBiosExt.h>
+#include <protocol\DriverBinding.h>
+#include <Protocol\ComponentName.h>
+#include <protocol\BlockIo.h>
+
+#include "CsmEdd.h"
+
+
+// Global Variables
+#if EFI_DEBUG
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosBlockIoComponentName;
+#endif
+
+
+// Define the I2O class code
+
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_SUB_CLASS_INTELLIGENT 0x00
+
+// SD class/subclass defined in PCI.H in 4.6.3.7
+#ifndef PCI_CL_SYSTEM_PERIPHERALS
+#define PCI_CL_SYSTEM_PERIPHERALS 0x08
+#endif
+#ifndef PCI_CL_SYSTEM_PERIPHERALS_SCL_SD
+#define PCI_CL_SYSTEM_PERIPHERALS_SCL_SD 0x05
+#endif
+
+
+// Number of pages needed for our buffer under 1MB
+
+#define BLOCK_IO_BUFFER_PAGE_SIZE (((sizeof (EDD_DEVICE_ADDRESS_PACKET) + sizeof (CSM_LEGACY_DRIVE) + MAX_EDD11_XFER) / EFI_PAGE_SIZE) + 1)
+
+
+// PROTOTYPES
+
+// Driver Binding Protocol functions
+
+EFI_STATUS
+CsmBlockIoSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+CsmBlockIoStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+EFI_STATUS
+CsmBlockIoStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+// Block I/O functions
+
+EFI_STATUS
+CsmBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ );
+
+EFI_STATUS
+CsmBlockIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+// These prototypes aren't actually used -- they are the generic for the specific
+// functions below
+EFI_STATUS
+CsmBlockIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+CsmBlockIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+// Specific read/write function prototypes
+EFI_STATUS
+Edd30CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+Edd30CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+Edd11CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+Edd11CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+LegacyCsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+EFI_STATUS
+LegacyCsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+// Local support function prototypes
+BOOLEAN
+InitBlockIo (
+ IN CSM_BLOCK_IO_DEV *Dev
+ );
+
+// Local function prototypes
+VOID
+BuildDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *BaseDevicePath,
+ IN CSM_LEGACY_DRIVE *Drive,
+ IN EFI_DEVICE_PATH_PROTOCOL **DevPath
+ );
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathNode (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevPath,
+ IN EFI_DEVICE_PATH_PROTOCOL *Node
+ );
+
+UINTN AlignAddress (
+ UINTN Address
+ );
+
+VOID ZeroMemory (
+ VOID *Buffer,
+ UINTN Size
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl
new file mode 100644
index 0000000..ac17f94
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmBlockIo.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "CsmBlockIo_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CsmBlockIo support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "CSMBLOCKIO_DIR"
+ Help = "CSM BLOCK I/O source directory"
+End
+
+MODULE
+ Help = "Includes CsmBlockIo.mak to Project"
+ File = "biosblkio.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\biosblkio.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmEdd.h b/Core/EM/CSM/thunk/BlockIo/CsmEdd.h
new file mode 100644
index 0000000..0c9ff4c
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmEdd.h
@@ -0,0 +1,407 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmEdd.h 7 1/12/10 11:50a Olegi $
+//
+// $Revision: 7 $
+//
+// $Date: 1/12/10 11:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmEdd.h $
+//
+// 7 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 6 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 5 3/13/06 2:38p Felixp
+//
+// 4 10/13/05 6:21p Olegi
+//
+// 3 4/20/05 4:54p Andriyn
+// USB_DEVICE_PATH is in core now
+//
+// 2 3/04/05 1:45p Mandal
+//
+// 1 2/15/05 11:00a Olegi
+// Initial VSS check-in.
+//
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmEdd.h
+//
+// Description: EDD support definitions file
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _CSM_EDD_H_
+#define _CSM_EDD_H_
+
+#pragma pack(1)
+
+typedef struct {
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 Controller;
+ UINT32 Reserved;
+} EDD_PCI;
+
+typedef struct {
+ UINT16 Base;
+ UINT16 Reserved;
+ UINT32 Reserved2;
+} EDD_LEGACY;
+
+typedef union {
+ EDD_PCI Pci;
+ EDD_LEGACY Legacy;
+} EDD_INTERFACE_PATH;
+
+typedef struct {
+ UINT8 Master;
+ UINT8 Reserved[15];
+} EDD_ATA;
+
+typedef struct {
+ UINT8 Master;
+ UINT8 Lun;
+ UINT8 Reserved[14];
+} EDD_ATAPI;
+
+typedef struct {
+ UINT16 TargetId;
+ UINT64 Lun;
+ UINT8 Reserved[6];
+} EDD_SCSI;
+
+typedef struct {
+ UINT64 SerialNumber;
+ UINT64 Reserved;
+} EDD_USB;
+
+typedef struct {
+ UINT64 Guid;
+ UINT64 Reserved;
+} EDD_1394;
+
+typedef struct {
+ UINT64 Wwn;
+ UINT64 Lun;
+} EDD_FIBRE;
+
+typedef union {
+ EDD_ATA Ata;
+ EDD_ATAPI Atapi;
+ EDD_SCSI Scsi;
+ EDD_USB Usb;
+ EDD_1394 FireWire;
+ EDD_FIBRE FibreChannel;
+} EDD_DEVICE_PATH;
+
+typedef struct _UNKNOWN_VENDOR_DEVICE_PATH {
+ VENDOR_DEVICE_PATH DevicePath;
+ UINT8 LegacyDriveLetter;
+} UNKNOWN_DEVICE_VENDOR_DEVICE_PATH;
+
+//typedef struct _CONTROLLER_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT32 Controller;
+//} CONTROLLER_DEVICE_PATH;
+
+//typedef struct _ATAPI_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT8 Channel;
+// UINT8 Device;
+// UINT16 Lun;
+//} ATAPI_DEVICE_PATH;
+
+//typedef struct _SCSI_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT16 TargetId;
+// UINT16 Lun;
+//} SCSI_DEVICE_PATH;
+
+//typedef struct _FIBRE_CHANNEL_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT32 Reserved;
+// UINT64 WorldWideNumber;
+// UINT64 Lun;
+//} FIBRECHANNEL_DEVICE_PATH;
+
+//typedef struct _F1394_DEVICE_PATH {
+// EFI_DEVICE_PATH_PROTOCOL Header;
+// UINT32 Reserved;
+// UINT64 _1394Guid;
+//} F1394_DEVICE_PATH;
+/* AndriyN : must belong to DevicePath.h
+typedef struct _USB_DEVICE_PATH {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT8 ParentPortNumber;
+ UINT8 InterfaceNumber;
+} USB_DEVICE_PATH;
+*/
+
+// Union of all possible device paths
+typedef union {
+ EFI_DEVICE_PATH_PROTOCOL DevPath;
+ PCI_DEVICE_PATH Pci;
+// PCCARD_DEVICE_PATH PcCard;
+// MEMMAP_DEVICE_PATH MemMap;
+ VENDOR_DEVICE_PATH Vendor;
+ UNKNOWN_DEVICE_VENDOR_DEVICE_PATH UnknownVendor;
+ CONTROLLER_DEVICE_PATH Controller;
+// ACPI_HID_DEVICE_PATH Acpi;
+ ACPI_HID_DEVICE_PATH Acpi;
+ ATAPI_DEVICE_PATH Atapi;
+ SCSI_DEVICE_PATH Scsi;
+ FIBRECHANNEL_DEVICE_PATH FibreChannel;
+ F1394_DEVICE_PATH F1394;
+ USB_DEVICE_PATH Usb;
+ USB_CLASS_DEVICE_PATH UsbClass;
+ I20_DEVICE_PATH I20;
+// MAC_ADDR_DEVICE_PATH MacAddr;
+ IPv4_DEVICE_PATH Ipv4;
+ IPv6_DEVICE_PATH Ipv6;
+ INFINIBAND_DEVICE_PATH InfiniBand;
+ UART_DEVICE_PATH Uart;
+ HARDDRIVE_DEVICE_PATH HardDrive;
+ CDROM_DEVICE_PATH CD;
+// FILEPATH_DEVICE_PATH FilePath;
+// MEDIA_PROTOCOL_DEVICE_PATH MediaProtocol;
+// BBS_BBS_DEVICE_PATH Bbs;
+} EFI_DEV_PATH;
+
+#define HARDWARE_DEVICE_PATH 0x01
+#define HW_VENDOR_DP 0x04
+#define MESSAGING_DEVICE_PATH 0x03
+#define MSG_ATAPI_DP 0x01
+#define HW_CONTROLLER_DP 0x05
+#define MSG_SCSI_DP 0x02
+#define MSG_1394_DP 0x04
+#define MSG_FIBRECHANNEL_DP 0x03
+
+typedef struct {
+ UINT16 StructureSize;
+ UINT16 Flags;
+ UINT32 MaxCylinders;
+ UINT32 MaxHeads;
+ UINT32 SectorsPerTrack;
+ UINT64 PhysicalSectors;
+ UINT16 BytesPerSector;
+ UINT32 FDPT;
+ UINT16 Key;
+ UINT8 DevicePathLength;
+ UINT8 Reserved1;
+ UINT16 Reserved2;
+ CHAR8 HostBusType[4];
+ CHAR8 InterfaceType[8];
+ EDD_INTERFACE_PATH InterfacePath;
+ EDD_DEVICE_PATH DevicePath;
+ UINT8 Reserved3;
+ UINT8 Checksum;
+} EDD_DRIVE_PARAMETERS;
+
+// Flag definitions for above
+#define EDD_GEOMETRY_VALID 0x02
+#define EDD_DEVICE_REMOVABLE 0x04
+#define EDD_WRITE_VERIFY_SUPPORTED 0x08
+#define EDD_DEVICE_CHANGE 0x10
+#define EDD_DEVICE_LOCKABLE 0x20
+
+// For WIN98 limitation
+#define EDD_DEVICE_GEOMETRY_MAX 0x40
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EDD_DEVICE_ADDRESS_PACKET
+//
+// Description: Device address packet used during EDD data transfers
+//
+// Fields:
+// PacketSizeInBytes UINT8 Packet size in bytes
+// Zero UINT8
+// NumberOfBlocks UINT8 # of blocks to transfer
+// Zero2 UINT8
+// SegOffset UINT32 Data address below 1MB
+// LBA UINT64 Device Logical Block Address
+// TransferBuffer UINT64 Transfer Buffer
+// ExtendedBlockCount UINT32 Transferred blocks counter
+// Zero3 UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT8 PacketSizeInBytes; // 0x18
+ UINT8 Zero;
+ UINT8 NumberOfBlocks; // Max 0x7f
+ UINT8 Zero2;
+ UINT32 SegOffset;
+ UINT64 LBA;
+ UINT64 TransferBuffer;
+ UINT32 ExtendedBlockCount; // Max 0xffffffff
+ UINT32 Zero3;
+} EDD_DEVICE_ADDRESS_PACKET;
+
+#define UNKNOWN_DEVICE_GUID \
+ { 0xcf31fac5, 0xc24e, 0x11d2, 0x85, 0xf3, 0x0, 0xa0, 0xc9, 0x3e, 0xc9, 0x3b }
+
+#define EDD_VERSION_30 0x30
+
+// Int 13 Error Messages
+#define ERR_PASS 0x00
+#define ERR_WRITE_PROTECTED 0x03
+#define ERR_SECTOR_NOT_FOUND 0x04
+#define ERR_RESET_FAILED 0x05
+#define ERR_DISK_CHANGED 0x06
+#define ERR_DRIVE_DOES_NOT_EXIST 0x07
+#define ERR_DMA_ERROR 0x08
+#define ERR_DATA_BOUNADRY_ERROR 0x09
+#define ERR_BAD_SECTOR 0x0a
+#define ERR_BAD_TRACK 0x0b
+#define ERR_MEDIA_TYPE_NOT_FOUND 0x0c
+#define ERR_INVALID_FORMAT 0x0d
+#define ERR_ECC_ERROR 0x10
+#define ERR_ECC_CORRECTED_ERROR 0x11
+#define ERR_HARD_DRIVE_FAILURE 0x20
+#define ERR_SEEK_FAILED 0x40
+#define ERR_DRIVE_TIMEOUT 0x80
+#define ERR_DRIVE_NOT_READY 0xaa
+#define ERR_UNDEFINED_ERROR 0xbb
+#define ERR_WRITE_FAULT 0xcc
+#define ERR_SENSE_FAILED 0xff
+
+#define MAX_EDD11_XFER 0xfe00
+
+// PCI classes not defined in PCI.h
+#define PCI_BASE_CLASS_INTELLIGENT 0x0e
+#define PCI_SUB_CLASS_INTELLIGENT 0x00
+
+#define EFI_SEGMENT(_Adr) (UINT16)((UINT16) (((UINTN)(_Adr)) >> 4) & 0xf000)
+#define EFI_OFFSET(_Adr) (UINT16)(((UINT16)((UINTN)_Adr)) & 0xffff)
+
+#pragma pack()
+
+// Local data structures
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CSM_LEGACY_DRIVE
+//
+// Description: Hard drive data structure
+//
+// Fields:
+// Letter CHAR8 Drive letter
+// Number UINT8 INT13 drive handle
+// EddVersion UINT8 EDD version supported by the drive
+// ExtendedInt13 BOOLEAN Extended INT13 support status
+// DriveLockingAndEjecting BOOLEAN Locking/Ejecting support
+// Edd BOOLEAN EDD support status
+// Extensions64Bit BOOLEAN 64 bit extension support
+// ParametersValid BOOLEAN Valid parameters (Parameters field) indicator
+// ErrorCode UINT8 Error code field
+// FdptPointer VOID* Pointer to FDPT
+// Floppy BOOLEAN Device-is-a-floppy indicator
+// AtapiFloppy BOOLEAN Device-is-an-ATAPI-floppy indicator
+// MaxHead UINT8 Number of heads
+// MaxSector UINT8 Number of sectors
+// MaxCylinder UINT16 Number of cylinders
+// Pad UINT16
+// Parameters EDD_DRIVE_PARAMETERS EDD drive parameters
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ CHAR8 Letter;
+ UINT8 Number;
+ UINT8 EddVersion;
+ BOOLEAN ExtendedInt13;
+ BOOLEAN DriveLockingAndEjecting;
+ BOOLEAN Edd;
+ BOOLEAN Extensions64Bit;
+ BOOLEAN ParametersValid;
+ UINT8 ErrorCode;
+ VOID *FdptPointer;
+ BOOLEAN Floppy;
+ BOOLEAN AtapiFloppy;
+ UINT8 MaxHead;
+ UINT8 MaxSector;
+ UINT16 MaxCylinder;
+ UINT16 Pad;
+ EDD_DRIVE_PARAMETERS Parameters;
+} CSM_LEGACY_DRIVE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CSM_BLOCK_IO_DEV
+//
+// Description: CSM BlockIo device properies
+//
+// Fields:
+// BlockIo EFI_BLOCK_IO_PROTOCOL BlockIo protocol instance
+// Handle EFI_HANDLE EFI device handle
+// ControllerHandle EFI_HANDLE EFI controller handle
+// BlockMedia EFI_BLOCK_IO_MEDIA BlockIo device media
+// DevicePath EFI_DEVICE_PATH_PROTOCOL* Device path
+// PciIo EFI_PCI_IO_PROTOCOL* Device PciIo
+// LegacyBios EFI_LEGACY_BIOS_PROTOCOL* Legacy Bios instance pointer
+// Drive CSM_LEGACY_DRIVE Drive data pointer
+// HwInt UINT8 Hardware interrupt used by this device
+// HwIntHandler UINT32 Storage for the original HW interrupt
+//
+// Referrals: CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ EFI_BLOCK_IO_PROTOCOL BlockIo;
+ EFI_HANDLE Handle;
+ EFI_HANDLE ControllerHandle;
+ EFI_BLOCK_IO_MEDIA BlockMedia;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ CSM_LEGACY_DRIVE Drive;
+ UINT8 HwInt;
+ UINT32 HwIntHandler;
+} CSM_BLOCK_IO_DEV;
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/CsmInt13.c b/Core/EM/CSM/thunk/BlockIo/CsmInt13.c
new file mode 100644
index 0000000..8e3195e
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/CsmInt13.c
@@ -0,0 +1,1525 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmInt13.c 17 12/23/13 3:14p Olegi $
+//
+// $Revision: 17 $
+//
+// $Date: 12/23/13 3:14p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/CsmInt13.c $
+//
+// 17 12/23/13 3:14p Olegi
+// EIP148138: use AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL instead of
+// EFI_MBR_WRITE_PROTECTION_PROTOCOL
+//
+// 16 12/23/13 10:22a Olegi
+// EIP148123: CSM includes file which name has been changed
+//
+// 15 7/01/13 5:56a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 14 3/09/12 3:22a Deepthins
+// [TAG] EIP73940
+// [Category] Improvement
+// [Description] CSM BlockIo functions, ReadBlock and WriteBlock should
+// return EFI_INVALID_PARAMETER if alignment is not proper.
+// [Files] CsmInt13.c
+//
+// 13 5/27/11 5:47a Rameshr
+// [TAG]- EIP 58687
+// [Category]-IMPROVEMENT
+// [Description]- Update implementation of EFI_BLOCK_IO_PROTOCOL as
+// described in UEFI specification v 2.3.1, page 12.8
+// [Files]- CsmInt13.c
+//
+// 12 1/12/10 11:50a Olegi
+// Copyright message updated.
+//
+// 11 5/09/08 10:37a Olegi
+// Low memory segment is normalized before INT13 execution.
+//
+// 10 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 9 12/07/06 4:00p Olegi
+//
+// 8 3/13/06 2:38p Felixp
+//
+// 7 10/13/05 6:20p Olegi
+// Added HW interrupt handling.
+//
+// 6 9/06/05 11:55a Olegi
+//
+// 5 6/26/05 7:19a Olegi
+// Actual drive parameters size is used while copying extended drive
+// parameters data.
+//
+// 4 3/04/05 1:43p Mandal
+//
+// 3 3/02/05 8:24a Olegi
+//
+// 2 2/21/05 9:33a Olegi
+//
+// 1 2/15/05 10:59a Olegi
+// Initial VSS check-in.
+//
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmInt13.c
+//
+// Description: CSM Block I/O module. Support module containing reset,
+// flush, read and write functions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "CsmBlockIo.h"
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+#include <Protocol\AmiBlockIoWriteProtection.h>
+extern AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *gBlockIoWriteProtectionProtocol;
+#endif
+
+//extern EFI_BOOT_SERVICES *pBS;
+extern EFI_GUID gEfiBlockIoProtocolGuid;
+
+// Global variables
+
+// Packet buffer under 1 MB for all version EDD calls
+extern EDD_DEVICE_ADDRESS_PACKET *mEDDPacketBuffer;
+
+// This is a buffer for INT 13h func 48 information
+extern CSM_LEGACY_DRIVE *mDriveParameterBuffer;
+
+// EDD 1.1 transfer buffer
+extern VOID *mEDDTransferBuffer;
+
+// Local function prototypes
+BOOLEAN
+GetInt13DeviceParameters (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+);
+
+BOOLEAN
+GetInt13Extensions (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+);
+
+BOOLEAN
+GetDriveParameters (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+);
+
+VOID
+PatchHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+);
+
+VOID
+RestoreHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+);
+
+UINT32 gTempHwIntSav;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitBlockIo
+//
+// Description: Initializes BlockIo protocol for a given device
+//
+// Input: Device to initialize
+//
+// Output: TRUE initialization succeeded, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, GetInt13DeviceParameters, GetInt13Extensions
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+InitBlockIo (
+ IN CSM_BLOCK_IO_DEV *Dev
+)
+{
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_BLOCK_IO_MEDIA *BlockMedia;
+ CSM_LEGACY_DRIVE *Drive;
+
+ BlockIo = &Dev->BlockIo;
+ BlockIo->Media = &Dev->BlockMedia;
+ BlockMedia = BlockIo->Media;
+ Drive = &Dev->Drive;
+
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ BlockIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ } else {
+ BlockIo->Revision = 1;
+ }
+#else
+ BlockIo->Revision = 1;
+#endif
+
+ if (GetInt13DeviceParameters (Dev, Drive)) {
+ if (GetInt13Extensions (Dev, Drive)) {
+ BlockMedia->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ BlockMedia->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+
+ if ((Drive->Parameters.Flags & EDD_DEVICE_REMOVABLE) == EDD_DEVICE_REMOVABLE) {
+ BlockMedia->RemovableMedia = TRUE;
+ }
+
+ } else {
+ // No extensions, use Legacy parameters.
+ BlockMedia->BlockSize = 512;
+ BlockMedia->LastBlock = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1) - 1;
+ }
+
+// TRACE((-1," BlockSize = %d LastBlock = %d\n", BlockMedia->BlockSize, BlockMedia->LastBlock));
+
+ BlockMedia->LogicalPartition = FALSE;
+ BlockMedia->WriteCaching = FALSE;
+
+ BlockMedia->ReadOnly = FALSE; // Set for removable media in case no media present
+ BlockMedia->MediaPresent = TRUE; // ditto
+
+ BlockIo->Reset = CsmBlockIoReset;
+ BlockIo->FlushBlocks = CsmBlockIoFlushBlocks;
+
+ // Need logic here to test for EDD and set read/write functions if so
+ if (!Drive->ExtendedInt13) {
+ // No Int 13 extensions, use Legacy functions
+ BlockIo->ReadBlocks = LegacyCsmReadBlocks;
+ BlockIo->WriteBlocks = LegacyCsmWriteBlocks;
+/* } else if ((Drive->EddVersion == EDD_VERSION_30) && (Drive->Extensions64Bit)) {
+ // Use EDD 3.0 functions
+ BlockIo->ReadBlocks = Edd30CsmReadBlocks;
+ BlockIo->WriteBlocks = Edd30CsmWriteBlocks;
+*/
+ } else {
+ // Assume EDD 1.1 Read and Write functions.
+ BlockIo->ReadBlocks = Edd11CsmReadBlocks;
+ BlockIo->WriteBlocks = Edd11CsmWriteBlocks;
+ }
+
+ BlockMedia->LogicalPartition = FALSE;
+ BlockMedia->WriteCaching = FALSE;
+
+ //
+ // Check for Core Version > 4.6.5.0
+ //
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ //
+ // Default value set to 1 logical blocks per PhysicalBlock
+ //
+ BlockMedia->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ BlockMedia->LowestAlignedLba=0;
+
+ BlockMedia->OptimalTransferLengthGranularity=BlockMedia->BlockSize;
+ }
+
+#endif
+
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetInt13DeviceParameters
+//
+// Description: Get hard drive parameters using INT13 function 8
+//
+// Input: BlockIo device, Drive
+//
+// Output: TRUE if operation is successful, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetInt13DeviceParameters (
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+)
+{
+ BOOLEAN CarryFlag;
+ UINT16 Cylinder;
+ EFI_IA32_REGISTER_SET Regs;
+
+ Regs.H.AH = 0x08;
+ Regs.H.DL = Drive->Number;
+ PatchHwInterrupt(CsmBlockIoDev);
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ RestoreHwInterrupt(CsmBlockIoDev);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+// TRACE((-1," GetInt13DeviceParameters: INT 13 08 DL=%02x : CF=%d AH=%02x\n", Drive->Number, CarryFlag, Regs.H.AH));
+
+ if (CarryFlag || Regs.H.AH != 0x00) {
+ Drive->ErrorCode = Regs.H.AH;
+ return FALSE;
+ }
+
+ if (Drive->Floppy) {
+ if (Regs.H.BL == 0x10) {
+ Drive->AtapiFloppy = TRUE;
+ } else {
+ Drive->MaxHead = Regs.H.DH;
+ Drive->MaxSector = Regs.H.CL;
+ Drive->MaxCylinder = Regs.H.CH;
+ if (Drive->MaxSector == 0) {
+ return FALSE;
+ }
+ }
+ } else {
+ Drive->MaxHead = (UINT8)(Regs.H.DH & 0x3f);
+ Cylinder = (UINT16)(((UINT16)Regs.H.DH & 0xc0) << 4);
+ Cylinder |= (UINT16)(((UINT16)Regs.H.CL & 0xc0) << 2);
+ Drive->MaxCylinder = (UINT16)(Cylinder + Regs.H.CH);
+ Drive->MaxSector = (UINT8)(Regs.H.CL & 0x3f);
+ }
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetInt13Extensions
+//
+// Description: Executes INT13 func 41 to check EDD extensions
+//
+// Input: BlockIo device, Drive
+//
+// Output: TRUE if operation is successful, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetInt13Extensions(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+)
+{
+ BOOLEAN CarryFlag;
+ EFI_IA32_REGISTER_SET Regs;
+
+ Regs.H.AH = 0x41;
+ Regs.X.BX = 0x55aa;
+ Regs.H.DL = Drive->Number;
+ PatchHwInterrupt(CsmBlockIoDev);
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ RestoreHwInterrupt(CsmBlockIoDev);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+// TRACE((-1, " GetInt13Extensions: INT 13 41 DL=%02x : CF=%d BX=%04x\n", Drive->Number, CarryFlag, Regs.X.BX));
+
+ if (CarryFlag || Regs.X.BX != 0xaa55) {
+ Drive->ExtendedInt13 = FALSE;
+ Drive->DriveLockingAndEjecting = FALSE;
+ Drive->Edd = FALSE;
+ return(FALSE);
+ }
+ Drive->EddVersion = Regs.H.AH;
+ Drive->ExtendedInt13 = (BOOLEAN)((Regs.X.CX & 0x01) == 0x01);
+ Drive->DriveLockingAndEjecting = (BOOLEAN)((Regs.X.CX & 0x02) == 0x02);
+ Drive->Edd = (BOOLEAN)((Regs.X.CX & 0x04) == 0x04);
+ Drive->Extensions64Bit = (BOOLEAN)(Regs.X.CX & 0x08);
+
+ Drive->ParametersValid = (UINT8)GetDriveParameters(CsmBlockIoDev, Drive);
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetDriveParameters
+//
+// Description: Executes INT13 function 48 to get hard disk parameters
+//
+// Input: BlockIo device, Drive
+//
+// Output: TRUE if operation is successful, FALSE otherwise
+//
+// Referrals: CSM_BLOCK_IO_DEV, CSM_LEGACY_DRIVE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+GetDriveParameters(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev,
+ IN CSM_LEGACY_DRIVE *Drive
+)
+{
+ BOOLEAN CarryFlag;
+ EFI_IA32_REGISTER_SET Regs;
+ UINTN PointerMath;
+ UINT8 Temp;
+ UINT8 FloppyTable [] = {
+ 1, 9, 79, // Type 3 -- 720 Kb
+ 1, 18, 79, // Type 4 -- 1.44 Mb
+ 0, 1, 0, // No type 5
+ 1, 36, 79, // Type 6 -- 2.88 Mb
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 0, 1, 0,
+ 1, 9, 39, // Type C -- 360 Kb
+ 1, 15, 79 // Type D -- 1.2 Mb
+ };
+
+ Regs.H.AH = 0x48;
+ Regs.H.DL = Drive->Number;
+
+ // Get Int13 Parameters
+ mDriveParameterBuffer->Parameters.StructureSize = sizeof(EDD_DRIVE_PARAMETERS);
+ Regs.X.DS = EFI_SEGMENT(&mDriveParameterBuffer->Parameters);
+ Regs.X.SI = EFI_OFFSET(&mDriveParameterBuffer->Parameters);
+
+ PatchHwInterrupt(CsmBlockIoDev);
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+ if (CarryFlag || Regs.H.AH != 0x00) {
+ RestoreHwInterrupt(CsmBlockIoDev);
+ Drive->ErrorCode = Regs.H.AH;
+ pBS->SetMem(&Drive->Parameters, sizeof(Drive->Parameters), 0xaf);
+ return FALSE;
+ }
+
+// Copy parameters into real mode buffer
+ pBS->SetMem (&Drive->Parameters, sizeof(Drive->Parameters), 0);
+ pBS->CopyMem (
+ &Drive->Parameters,
+ &mDriveParameterBuffer->Parameters,
+ mDriveParameterBuffer->Parameters.StructureSize // updated by int 13 call
+ );
+
+ if (Drive->AtapiFloppy) {
+
+ // Get Media type
+ Regs.H.AH = 0x20;
+ Regs.H.DL = Drive->Number;
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+ if (CarryFlag) {
+
+ // Unknown or no media present
+ if ((Drive->Parameters.Flags & EDD_GEOMETRY_VALID) == EDD_GEOMETRY_VALID) {
+ Drive->MaxHead = (UINT8)(Drive->Parameters.MaxHeads - 1);
+ Drive->MaxSector = (UINT8)Drive->Parameters.SectorsPerTrack;
+ ASSERT(Drive->MaxSector != 0);
+ Drive->MaxCylinder = (UINT16)(Drive->Parameters.MaxCylinders - 1);
+ } else {
+ Drive->MaxHead = 0;
+ Drive->MaxSector = 1;
+ Drive->MaxCylinder = 0;
+ }
+
+ } else {
+
+ // Media present -- get parameters
+ Drive->MaxHead = 0;
+ Drive->MaxSector = 1;
+ Drive->MaxCylinder = 0; // Assume unknown media
+ if(Regs.H.AL != 10) {
+ if((Regs.H.AL >= 3) && (Regs.H.AL <= 0xd)) {
+ Temp = (Regs.H.AL - 3) * 3; // First drive type is 3
+ Drive->MaxHead = FloppyTable[Temp];
+ Drive->MaxSector = FloppyTable[Temp+1];
+ Drive->MaxCylinder = FloppyTable[Temp+2];
+ }
+ } else {
+ if ((Drive->Parameters.Flags & EDD_GEOMETRY_VALID) == EDD_GEOMETRY_VALID) {
+ Drive->MaxHead = (UINT8)(Drive->Parameters.MaxHeads - 1);
+ Drive->MaxSector = (UINT8)Drive->Parameters.SectorsPerTrack;
+ ASSERT(Drive->MaxSector != 0);
+ Drive->MaxCylinder = (UINT16)(Drive->Parameters.MaxCylinders - 1);
+ } else {
+ Drive->MaxHead = 0;
+ Drive->MaxSector = 1;
+ Drive->MaxCylinder = 0;
+ }
+ }
+ }
+ Drive->Parameters.PhysicalSectors = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1);
+ Drive->Parameters.BytesPerSector = 512;
+ }
+
+ // This data comes from the BIOS so it may not allways be valid
+ // since the BIOS may reuse this buffer for future accesses
+ PointerMath = EFI_SEGMENT(Drive->Parameters.FDPT) << 4;
+ PointerMath += EFI_OFFSET(Drive->Parameters.FDPT);
+ Drive->FdptPointer = (VOID *)PointerMath;
+
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return TRUE;
+}
+
+// BLOCK I/O FUNCTIONS
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CsmBlockIoFlushBlocks
+//
+// Description: BlockIo protocol function that flushes data onto the device
+//
+// Input: Instance of the EFI_BLOCK_IO_PROTOCOL
+//
+// Output: Status of the operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CsmBlockIoFlushBlocks
+//
+// Description: BlockIo protocol function that resets the device
+//
+// Input:
+// Instance of the EFI_BLOCK_IO_PROTOCOL
+// ExtendedVerification request
+//
+// Output: Status of the operation
+//
+// Referrals: CSM_BLOCK_IO_DEV, EFI_IA32_REGISTER_SET
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CsmBlockIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EFI_IA32_REGISTER_SET Regs;
+ BOOLEAN CarryFlag;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ Regs.H.AH = 0x00;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, " CsmBlockIoReset: INT 13 00 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ if (CarryFlag) {
+ if (Regs.H.AL == ERR_RESET_FAILED) {
+ Regs.H.AH = 0x00;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "CsmBlockIoReset: INT 13 00 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ if (CarryFlag) {
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+ }
+
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd30CsmReadBlocks
+//
+// Description: Read device using EDD3.0 read function
+//
+// Input: BlockIo protocol instance, Media ID, read data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd30CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket; // I exist only for readability
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+// Check for error conditions
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+ if (BufferSize == 0) return EFI_SUCCESS;
+
+// CsmBlockIoDev = ((CSM_BLOCK_IO_DEV *) ((CHAR8 *)(This) - (CHAR8 *) &(((CSM_BLOCK_IO_DEV *) 0)->BlockIo)));
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ TransferBuffer = (UINT64)Buffer;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize/BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+ AddressPacket->SegOffset = 0xffffffff;
+ AddressPacket->LBA = (UINT64)LBA;
+ AddressPacket->TransferBuffer = TransferBuffer;
+
+ Regs.H.AH = 0x42;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, " Edd30CsmReadBlocks: INT 13 42 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ BufferSize = BufferSize - TransferByteSize;
+ TransferBuffer += TransferByteSize;
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd30CsmWriteBlocks
+//
+// Description: Write device using EDD3.0 write function
+//
+// Input: BlockIo protocol instance, Media ID, write data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd30CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+ if (BufferSize == 0) return EFI_SUCCESS;
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ TransferBuffer = (UINT64)Buffer;
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize/BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+ AddressPacket->SegOffset = 0xffffffff;
+ AddressPacket->LBA = (UINT64)LBA;
+ AddressPacket->TransferBuffer = TransferBuffer;
+
+ Regs.H.AH = 0x43;
+ Regs.H.AL = 0x00; // Write Verify Off
+ Regs.H.DL = (UINT8)(CsmBlockIoDev->Drive.Number);
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, " Edd30CsmWriteBlocks: INT 13 43 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ } else if (CsmBlockIoDev->Drive.ErrorCode == ERR_WRITE_PROTECTED) {
+ Media->ReadOnly = TRUE;
+ return EFI_WRITE_PROTECTED;
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Media->ReadOnly = FALSE;
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ BufferSize = BufferSize - TransferByteSize;
+ TransferBuffer += TransferByteSize;
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+// Older read/write methods
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd11CsmReadBlocks
+//
+// Description: Read device using EDD1.1 read function
+//
+// Input: BlockIo protocol instance, Media ID, read data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd11CsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket;
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 AlignedOffset;
+ UINT16 AlignedSegment;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ TransferBuffer = (UINT64)mEDDTransferBuffer;
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize / BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+
+ //
+ // Normalize TransferBuffer address if needed
+ //
+ AlignedOffset = EFI_OFFSET(TransferBuffer);
+ AlignedSegment = EFI_SEGMENT(TransferBuffer);
+ if(AlignedOffset != 0) {
+ AlignedSegment = AlignedSegment + (AlignedOffset >> 4);
+ AlignedOffset = 0;
+ }
+
+ AddressPacket->SegOffset = AlignedSegment << 16;
+ AddressPacket->SegOffset |= AlignedOffset;
+
+ AddressPacket->LBA = (UINT64)LBA;
+
+ Regs.H.AH = 0x42;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "Edd11CsmReadBlocks: INT 13 42 DL=%02x : CF=%d AH=%02x : LBA 0x%lx Block(s) %0d \n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH, LBA, NumberOfBlocks));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ // The media has changed.
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem (Buffer, (VOID *)(UINTN)TransferBuffer, TransferByteSize);
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Edd11CsmWriteBlocks
+//
+// Description: Write device using EDD1.1 write function
+//
+// Input: BlockIo protocol instance, Media ID, write data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Edd11CsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EDD_DEVICE_ADDRESS_PACKET *AddressPacket; // I exist only for readability
+ EFI_IA32_REGISTER_SET Regs;
+ UINT64 TransferBuffer;
+ UINTN NumberOfBlocks;
+ UINTN TransferByteSize;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN MaxTransferBlocks;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 AlignedOffset;
+ UINT16 AlignedSegment;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ AddressPacket = mEDDPacketBuffer;
+
+ MaxTransferBlocks = MAX_EDD11_XFER/BlockSize;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ TransferBuffer = (UINT64)mEDDTransferBuffer;
+ while (BufferSize) {
+ NumberOfBlocks = BufferSize/BlockSize;
+ NumberOfBlocks = NumberOfBlocks > MaxTransferBlocks ? MaxTransferBlocks : NumberOfBlocks; // Max transfer MaxTransferBlocks
+ AddressPacket->PacketSizeInBytes = sizeof(EDD_DEVICE_ADDRESS_PACKET);
+ AddressPacket->Zero = 0;
+ AddressPacket->NumberOfBlocks = (UINT8)NumberOfBlocks;
+ AddressPacket->Zero2 = 0;
+
+ //
+ // Normalize TransferBuffer address if needed
+ //
+ AlignedOffset = EFI_OFFSET(TransferBuffer);
+ AlignedSegment = EFI_SEGMENT(TransferBuffer);
+
+ if (AlignedOffset != 0) {
+ AlignedSegment = AlignedSegment + (AlignedOffset >> 4);
+ AlignedOffset = 0;
+ }
+
+ AddressPacket->SegOffset = AlignedSegment << 16;
+ AddressPacket->SegOffset |= AlignedOffset;
+
+ AddressPacket->LBA = (UINT64)LBA;
+
+ Regs.H.AH = 0x43;
+ Regs.H.AL = 0x00; // Write Verify disable
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+ Regs.X.SI = EFI_OFFSET(AddressPacket);
+ Regs.X.DS = EFI_SEGMENT(AddressPacket);
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem ((VOID *)(UINTN)TransferBuffer, Buffer, TransferByteSize);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "Edd11CsmWriteBlocks: INT 13 43 DL=%02x : CF=%d AH=%02x\n: LBA 0x%lx Block(s) %0d \n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH, LBA, NumberOfBlocks));
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ ASSERT(FALSE);
+ }
+ // The media has changed.
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ } else if (CsmBlockIoDev->Drive.ErrorCode == ERR_WRITE_PROTECTED) {
+ Media->ReadOnly = TRUE;
+ Status = EFI_WRITE_PROTECTED;
+ goto Exit;
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ Media->ReadOnly = FALSE;
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ LBA += NumberOfBlocks;
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: LegacyCsmReadBlocks
+//
+// Description: Read device using INT13 function 2
+//
+// Input: BlockIo protocol instance, Media ID, read data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacyCsmReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EFI_IA32_REGISTER_SET Regs;
+ UINTN UpperCylinder, Temp;
+ UINTN Cylinder, Head, Sector;
+ UINTN NumberOfBlocks, TransferByteSize;
+ UINTN ShortLba, CheckLba;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN Retry;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ ShortLba = (UINTN) LBA;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ while (BufferSize) {
+ // Convert LBA to CHS.
+ Sector = (ShortLba % CsmBlockIoDev->Drive.MaxSector) + 1;
+ Temp = ShortLba / CsmBlockIoDev->Drive.MaxSector;
+ Head = Temp % (CsmBlockIoDev->Drive.MaxHead + 1);
+ Cylinder = Temp / (CsmBlockIoDev->Drive.MaxHead + 1);
+ // Limit number of blocks to one head and cylindar
+ NumberOfBlocks = BufferSize/BlockSize;
+ Temp = CsmBlockIoDev->Drive.MaxSector - Sector + 1;
+ NumberOfBlocks = NumberOfBlocks > Temp ? Temp : NumberOfBlocks;
+
+ Retry = 3;
+ // Loop to perform the read
+ do {
+ Regs.H.AH = 2;
+ Regs.H.AL = (UINT8) NumberOfBlocks;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+
+ UpperCylinder = (Cylinder & 0x0f00) >> 2;
+
+ CheckLba = Cylinder*(CsmBlockIoDev->Drive.MaxHead + 1) + Head;
+ CheckLba = CheckLba*CsmBlockIoDev->Drive.MaxSector + Sector - 1;
+
+// ASSERT(CheckLba == ShortLba);
+
+ Regs.H.CL = (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff));
+ Regs.H.DH = (UINT8) (Head & 0x3f);
+ Regs.H.CH = (UINT8) (Cylinder & 0xff);
+
+ Regs.X.BX = EFI_OFFSET(mEDDTransferBuffer);
+ Regs.X.ES = EFI_SEGMENT(mEDDTransferBuffer);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "LegacyCsmReadBlocks: INT 13 02 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Retry--;
+ } while (CarryFlag && Retry !=0 && Regs.H.AH != ERR_DISK_CHANGED);
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ // The media has changed
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ Media->LastBlock = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1) - 1;
+ Media->BlockSize = 512;
+ }
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem (Buffer, mEDDTransferBuffer, TransferByteSize);
+
+ ShortLba = ShortLba + NumberOfBlocks;
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ }
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: LegacyCsmWriteBlocks
+//
+// Description: Write device using INT13 function 3
+//
+// Input: BlockIo protocol instance, Media ID, write data buffer
+//
+// Output: Status of the operation
+//
+// Referrals: EFI_LBA
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacyCsmWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ )
+{
+ EFI_BLOCK_IO_MEDIA *Media;
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev;
+ EFI_IA32_REGISTER_SET Regs;
+ UINTN UpperCylinder, Temp;
+ UINTN Cylinder, Head, Sector;
+ UINTN NumberOfBlocks, TransferByteSize;
+ UINTN ShortLba, CheckLba;
+ UINTN BlockSize;
+ CSM_LEGACY_DRIVE *Drive;
+ BOOLEAN CarryFlag;
+ UINTN Retry;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BufferAddress;
+
+ Media = This->Media;
+ BlockSize = Media->BlockSize;
+
+ if (MediaId != Media->MediaId) return EFI_MEDIA_CHANGED;
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (LBA > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if ((LBA + (BufferSize / BlockSize) - 1) > Media->LastBlock) return EFI_INVALID_PARAMETER;
+ if (BufferSize % BlockSize != 0) return EFI_BAD_BUFFER_SIZE;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((Media->IoAlign > 1 ) && (BufferAddress % Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ // Verify if write is allowed
+ if(gBlockIoWriteProtectionProtocol != NULL) {
+ Status = gBlockIoWriteProtectionProtocol->BlockIoWriteProtectionCheck(
+ gBlockIoWriteProtectionProtocol,
+ This,
+ LBA,
+ BufferSize
+ );
+
+ // Abort operation if denied
+ if(Status == EFI_ACCESS_DENIED) {
+ return Status;
+ }
+ }
+#endif
+
+ CsmBlockIoDev = (CSM_BLOCK_IO_DEV *) This;
+ ShortLba = (UINTN) LBA;
+
+ PatchHwInterrupt(CsmBlockIoDev);
+
+ while(BufferSize) {
+ // Convert LBA to CHS
+ Sector = (ShortLba % CsmBlockIoDev->Drive.MaxSector) + 1;
+ Temp = ShortLba / CsmBlockIoDev->Drive.MaxSector;
+ Head = Temp % (CsmBlockIoDev->Drive.MaxHead + 1);
+ Cylinder = Temp / (CsmBlockIoDev->Drive.MaxHead + 1);
+
+ // Limit number of blocks to one head and cylindar
+ NumberOfBlocks = BufferSize/BlockSize;
+ Temp = CsmBlockIoDev->Drive.MaxSector - Sector + 1;
+ NumberOfBlocks = NumberOfBlocks > Temp ? Temp : NumberOfBlocks;
+
+
+ Retry = 3;
+ // Loop to perform the write.
+ do {
+ Regs.H.AH = 3;
+ Regs.H.AL = (UINT8) NumberOfBlocks;
+ Regs.H.DL = CsmBlockIoDev->Drive.Number;
+
+ UpperCylinder = (Cylinder & 0x0f00) >> 2;
+
+ CheckLba = Cylinder*(CsmBlockIoDev->Drive.MaxHead + 1) + Head;
+ CheckLba = CheckLba*CsmBlockIoDev->Drive.MaxSector + Sector - 1;
+
+// ASSERT(CheckLba == ShortLba);
+
+ Regs.H.CL = (UINT8) ((Sector & 0x3f) + (UpperCylinder & 0xff));
+ Regs.H.DH = (UINT8) (Head & 0x3f);
+ Regs.H.CH = (UINT8) (Cylinder & 0xff);
+
+ Regs.X.BX = EFI_OFFSET(mEDDTransferBuffer);
+ Regs.X.ES = EFI_SEGMENT(mEDDTransferBuffer);
+
+ TransferByteSize = NumberOfBlocks * BlockSize;
+ pBS->CopyMem (mEDDTransferBuffer, Buffer, TransferByteSize);
+
+ CsmBlockIoDev->LegacyBios->Int86 (CsmBlockIoDev->LegacyBios, 0x13, &Regs);
+ CarryFlag = (BOOLEAN)Regs.X.Flags.CF;
+
+// TRACE((-1, "LegacyCsmWriteBlocks: INT 13 03 DL=%02x : CF=%d AH=%02x\n", CsmBlockIoDev->Drive.Number, CarryFlag, Regs.H.AH));
+
+ Retry--;
+ } while (CarryFlag && Retry !=0 && Regs.H.AH != ERR_DISK_CHANGED);
+
+ Media->MediaPresent = TRUE;
+ if (CarryFlag) {
+ // If we have a carry, figure out the error.
+ CsmBlockIoDev->Drive.ErrorCode = Regs.H.AH;
+ if (CsmBlockIoDev->Drive.ErrorCode == ERR_DISK_CHANGED) {
+ Media->MediaId++;
+ Drive = &CsmBlockIoDev->Drive;
+ if (GetInt13DeviceParameters(CsmBlockIoDev, Drive)) {
+ if (GetInt13Extensions (CsmBlockIoDev, Drive)) {
+ Media->LastBlock = (EFI_LBA)Drive->Parameters.PhysicalSectors - 1;
+ Media->BlockSize = (UINT32)Drive->Parameters.BytesPerSector;
+ } else {
+ Media->LastBlock = (Drive->MaxHead + 1) * Drive->MaxSector * (Drive->MaxCylinder + 1) - 1;
+ Media->BlockSize = 512;
+ }
+ // The media has changed.
+ Media->ReadOnly = FALSE;
+ pBS->HandleProtocol(CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
+ pBS->ReinstallProtocolInterface (CsmBlockIoDev->Handle, &gEfiBlockIoProtocolGuid, BlockIo, BlockIo);
+ Status = EFI_MEDIA_CHANGED;
+ goto Exit;
+ }
+ } else if (CsmBlockIoDev->Drive.ErrorCode == ERR_WRITE_PROTECTED) {
+ Media->ReadOnly = TRUE;
+ Status = EFI_WRITE_PROTECTED;
+ goto Exit;
+ }
+
+ if (Media->RemovableMedia) {
+ Media->MediaPresent = FALSE;
+ }
+
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ Media->ReadOnly = FALSE;
+ ShortLba = ShortLba + NumberOfBlocks;
+ BufferSize = BufferSize - TransferByteSize;
+ Buffer = (VOID *)((UINT8 *)Buffer + TransferByteSize);
+ }
+
+Exit:
+ RestoreHwInterrupt(CsmBlockIoDev);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: PatchHwInterrupt
+//
+// Description: Saves HW interrupt vector used by this device
+//
+// Input: BlockIo device
+//
+// Output: None
+//
+// Referrals: CSM_BLOCK_IO_DEV
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+PatchHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+)
+{
+ UINT32 *ivt = (UINT32*)0;
+ if (CsmBlockIoDev->HwInt) {
+ gTempHwIntSav = ivt[CsmBlockIoDev->HwInt];
+ ivt[CsmBlockIoDev->HwInt] = CsmBlockIoDev->HwIntHandler;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: RestoreHwInterrupt
+//
+// Description: Restores HW interrupt saved by PatchHwInterrupt
+//
+// Input: BlockIo device
+//
+// Output: None
+//
+// Referrals: CSM_BLOCK_IO_DEV, PatchHwInterrupt
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+RestoreHwInterrupt(
+ CSM_BLOCK_IO_DEV *CsmBlockIoDev
+)
+{
+ UINT32 *ivt = (UINT32*)0;
+ if (CsmBlockIoDev->HwInt) {
+ ivt[CsmBlockIoDev->HwInt] = gTempHwIntSav;
+ }
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/biosblkio.dxs b/Core/EM/CSM/thunk/BlockIo/biosblkio.dxs
new file mode 100644
index 0000000..8a863fa
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/biosblkio.dxs
@@ -0,0 +1,46 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.dxs 1 10/03/11 3:38p Olegi $
+//
+// $Revision: 1 $
+//
+// $Date: 10/03/11 3:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.dxs $
+//
+// 1 10/03/11 3:38p Olegi
+//
+//**********************************************************************
+
+#include <Protocol\LegacyBios.h>
+
+DEPENDENCY_START
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/BlockIo/biosblkio.mak b/Core/EM/CSM/thunk/BlockIo/biosblkio.mak
new file mode 100644
index 0000000..879933f
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/biosblkio.mak
@@ -0,0 +1,63 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.mak 3 1/12/10 11:50a Olegi $
+#
+# $Revision: 3 $
+#
+# $Date: 1/12/10 11:50a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/INT13/biosblkio.mak $
+#
+# 3 1/12/10 11:50a Olegi
+# Copyright message updated.
+#
+# 2 12/02/05 11:44a Felixp
+#
+# 1 2/15/05 11:00a Olegi
+# Initial VSS check-in.
+#
+#
+#************************************************************************//
+all : CsmBlockIo
+
+CsmBlockIo : $(BUILD_DIR)\biosblkio.mak CsmBlockIoBin
+
+$(BUILD_DIR)\biosblkio.mak : $(CSMBLOCKIO_DIR)\int13thunk.cif $(CSMBLOCKIO_DIR)\biosblkio.mak $(BUILD_RULES)
+ $(CIF2MAK) $(CSMBLOCKIO_DIR)\int13thunk.cif $(CIF2MAK_DEFAULTS)
+
+CsmBlockIoBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\biosblkio.mak all\
+ GUID=25ACF158-DD61-4e64-9A49-55851E9A26C7\
+ ENTRY_POINT=CsmBlockIoEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CSM/thunk/BlockIo/int13thunk.cif b/Core/EM/CSM/thunk/BlockIo/int13thunk.cif
new file mode 100644
index 0000000..24c82f3
--- /dev/null
+++ b/Core/EM/CSM/thunk/BlockIo/int13thunk.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "INT13"
+ category = ModulePart
+ LocalRoot = "core\em\csm\thunk\BlockIo"
+ RefName = "BIOSBLKIO"
+[files]
+"CsmInt13.c"
+"CsmBlkIoComponentName.c"
+"CsmBlockIo.c"
+"CsmBlockIo.h"
+"CsmBlockIo.sdl"
+"CsmEdd.h"
+"biosblkio.mak"
+"biosblkio.dxs"
+<endComponent>
diff --git a/Core/EM/CSM/thunk/CsmVideo/AmiMapping.c b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.c
new file mode 100644
index 0000000..88c165b
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.c
@@ -0,0 +1,162 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.c 2 3/04/11 2:28p Olegi $
+//
+// $Revision: 2 $
+//
+// $Date: 3/04/11 2:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.c $
+//
+// 2 3/04/11 2:28p Olegi
+// [TAG] EIP55098
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] UefiBiosVideo.h
+// UefiBiosVideo.c
+// ComponentName.c
+// AmiMapping.h
+// AmiMapping.c
+//
+// 1 12/29/06 3:33p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiMapping.c
+//
+// Description: Mapping from EDK to AMI definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "AmiMapping.h"
+#include "VgaMiniPort.h"
+
+EFI_GUID gEfiVgaMiniPortProtocolGuid = EFI_VGA_MINI_PORT_PROTOCOL_GUID;
+
+EFI_STATUS EfiLibInstallAllDriverProtocols (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE DriverBindingHandle,
+#if EFI_SPECIFICATION_VERSION <= 0x20000
+ IN EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL
+#else
+ IN EFI_COMPONENT_NAME2_PROTOCOL *ComponentName, OPTIONAL
+#endif
+ IN VOID/*EFI_DRIVER_CONFIGURATION_PROTOCOL*/ *DriverConfiguration, OPTIONAL
+ IN VOID/*EFI_DRIVER_DIAGNOSTICS_PROTOCOL*/ *DriverDiagnostics OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ InitAmiLib (ImageHandle, SystemTable);
+ DriverBinding->ImageHandle = ImageHandle;
+ DriverBinding->DriverBindingHandle = DriverBindingHandle;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverBinding->DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, DriverBinding,
+ NULL
+ );
+ if (EFI_ERROR(Status)) return Status;
+ if (ComponentName)
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverBinding->DriverBindingHandle,
+#if EFI_SPECIFICATION_VERSION <= 0x20000
+ &gEfiComponentNameProtocolGuid, ComponentName,
+#else
+ &gEfiComponentName2ProtocolGuid,ComponentName,
+#endif
+ NULL
+ );
+ return Status;
+}
+
+BOOLEAN
+EfiLibCompareLanguage (
+ CHAR8 *Language1,
+ CHAR8 *Language2
+ )
+
+{
+ return *(UINT16*)Language1==*(UINT16*)Language2
+ && Language1[2]==Language2[2];
+}
+
+EFI_STATUS EfiLibLookupUnicodeString (
+ CHAR8 *Language,
+ CHAR8 *SupportedLanguages,
+ EFI_UNICODE_STRING_TABLE *UnicodeStringTable,
+ CHAR16 **UnicodeString
+ )
+{
+ //
+ // Make sure the parameters are valid
+ //
+ if (Language == NULL || UnicodeString == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // If there are no supported languages, or the Unicode String Table is empty, then the
+ // Unicode String specified by Language is not supported by this Unicode String Table
+ //
+ if (SupportedLanguages == NULL || UnicodeStringTable == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Make sure Language is in the set of Supported Languages
+ //
+ while (*SupportedLanguages != 0) {
+ if (EfiLibCompareLanguage (Language, SupportedLanguages)) {
+
+ //
+ // Search the Unicode String Table for the matching Language specifier
+ //
+ while (UnicodeStringTable->Language != NULL) {
+ if (EfiLibCompareLanguage (Language, UnicodeStringTable->Language)) {
+
+ //
+ // A matching string was found, so return it
+ //
+ *UnicodeString = UnicodeStringTable->UnicodeString;
+ return EFI_SUCCESS;
+ }
+ UnicodeStringTable++;
+ }
+ return EFI_UNSUPPORTED;
+ }
+ SupportedLanguages += 3;
+ }
+ return EFI_UNSUPPORTED;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CSM/thunk/CsmVideo/AmiMapping.h b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.h
new file mode 100644
index 0000000..9c92d54
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/AmiMapping.h
@@ -0,0 +1,153 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.h 3 12/23/13 10:21a Olegi $
+//
+// $Revision: 3 $
+//
+// $Date: 12/23/13 10:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/AmiMapping.h $
+//
+// 3 12/23/13 10:21a Olegi
+// [TAG] EIP148123
+// [Description] CSM includes file which name has been changed
+//
+// 2 3/04/11 2:28p Olegi
+// [TAG] EIP55098
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] UefiBiosVideo.h
+// UefiBiosVideo.c
+// ComponentName.c
+// AmiMapping.h
+// AmiMapping.c
+//
+// 1 12/29/06 3:33p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiMapping.h
+//
+// Description: Mapping from EDK to AMI definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __AMI_MAPPING__H__
+#define __AMI_MAPPING__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <Protocol/DriverBinding.h>
+#include <Protocol/ComponentName.h>
+#include <AmiDxeLib.h>
+#include <Token.h>
+
+#define STATIC static
+#define EFI_GUID_DEFINITION(a)
+#define EFI_PROTOCOL_DEFINITION(a) CONVERT_TO_STRING(Protocol/a.h)
+#define EFI_DRIVER_ENTRY_POINT(a)
+#define EFI_TPL_NOTIFY TPL_NOTIFY
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+
+#define EfiZeroMem(Address, Length) gBS->SetMem ((Address), (Length), 0)
+#define gBS pBS
+#define ReportStatusCodeWithDevicePath(a,b,c,d,e)
+
+#define ACPI_ADR_DISPLAY_TYPE_VGA 1
+#define ACPI_DISPLAY_ADR(_DeviceIdScheme, _HeadId, _NonVgaOutput, _BiosCanDetect, _VendorInfo, _Type, _Port, _Index) \
+ ((UINT32) ( (((_DeviceIdScheme) & 0x1) << 31) | \
+ (((_HeadId) & 0x7) << 18) | \
+ (((_NonVgaOutput) & 0x1) << 17) | \
+ (((_BiosCanDetect) & 0x1) << 16) | \
+ (((_VendorInfo) & 0xf) << 12) | \
+ (((_Type) & 0xf) << 8) | \
+ (((_Port) & 0xf) << 4) | \
+ ((_Index) & 0xf) ))
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION < 0x4028F)
+#define SetDevicePathNodeLength SET_NODE_LENGTH
+#endif
+
+#define EfiAppendDevicePathNode DPAddNode
+#define CR(pField, OutterType, Field, Signature) OUTTER(pField, Field, OutterType)
+#define EFI_SEGMENT(_Adr) (UINT16) ((UINT16) (((UINTN) (_Adr)) >> 4) & 0xf000)
+#define EFI_OFFSET(_Adr) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)
+#define EFI_SIMPLE_TEXT_OUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+#define EFI_SIMPLE_TEXT_OUTPUT_MODE SIMPLE_TEXT_OUTPUT_MODE
+#define CHAR_NULL 0x0000
+#define CHAR_BACKSPACE 0x0008
+#define CHAR_TAB 0x0009
+#define CHAR_LINEFEED 0x000A
+#define CHAR_CARRIAGE_RETURN 0x000D
+
+typedef struct {
+ CHAR8 *Language;
+ CHAR16 *UnicodeString;
+} EFI_UNICODE_STRING_TABLE;
+
+#define INSTALL_ALL_DRIVER_PROTOCOLS EfiLibInstallAllDriverProtocols
+EFI_STATUS
+EfiLibInstallAllDriverProtocols (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding,
+ IN EFI_HANDLE DriverBindingHandle,
+#if EFI_SPECIFICATION_VERSION <= 0x20000
+ IN EFI_COMPONENT_NAME_PROTOCOL *ComponentName, OPTIONAL
+#else
+ IN EFI_COMPONENT_NAME2_PROTOCOL *ComponentName, OPTIONAL
+#endif
+ IN VOID/*EFI_DRIVER_CONFIGURATION_PROTOCOL*/ *DriverConfiguration, OPTIONAL
+ IN VOID/*EFI_DRIVER_DIAGNOSTICS_PROTOCOL*/ *DriverDiagnostics OPTIONAL
+ );
+
+EFI_STATUS
+EfiLibLookupUnicodeString (
+ CHAR8 *Language,
+ CHAR8 *SupportedLanguages,
+ EFI_UNICODE_STRING_TABLE *UnicodeStringTable,
+ CHAR16 **UnicodeString
+ );
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CSM/thunk/CsmVideo/ComponentName.c b/Core/EM/CSM/thunk/CsmVideo/ComponentName.c
new file mode 100644
index 0000000..786cec4
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/ComponentName.c
@@ -0,0 +1,324 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+--*/
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ ComponentName.c
+
+Abstract:
+
+--*/
+//*** AMI PORTING BEGIN ***//
+//This file is not part of the component.
+//#include "BiosVideo.h"
+#include "UefiBiosVideo.h"
+//*** AMI PORTING END *****//
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+EFIAPI
+BiosVideoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+EFI_STATUS
+EFIAPI
+BiosVideoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+EFI_STATUS
+
+EFIAPI
+BiosVideoComponentName2GetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+
+EFI_STATUS
+EFIAPI
+BiosVideoComponentName2GetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+
+//
+// EFI Component Name Protocol
+//
+EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2 = {
+ BiosVideoComponentName2GetDriverName,
+ BiosVideoComponentName2GetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName = {
+ BiosVideoComponentNameGetDriverName,
+ BiosVideoComponentNameGetControllerName,
+ "eng"
+};
+
+static EFI_UNICODE_STRING_TABLE mBiosVideoDriverNameTable[] = {
+ {
+ "eng",
+ L"BIOS[INT10] Video Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+static EFI_UNICODE_STRING_TABLE mBiosVideoDriverNameTable2[] = {
+ {
+ LANGUAGE_CODE_ENGLISH,
+ L"BIOS[INT10] Video Driver"
+ },
+ {
+ NULL,
+ NULL
+ }
+};
+
+EFI_STATUS
+EFIAPI
+BiosVideoComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+
+ return EfiLibLookupUnicodeString (
+ Language,
+ gBiosVideoComponentName.SupportedLanguages,
+ mBiosVideoDriverNameTable,
+ DriverName
+ );
+}
+
+EFI_STATUS
+EFIAPI
+BiosVideoComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language from the point of view of the driver specified
+ by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+BiosVideoComponentName2GetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ Language - A pointer to a three character ISO 639-2 language identifier.
+ This is the language of the driver name that that the caller
+ is requesting, and it must match one of the languages specified
+ in SupportedLanguages. The number of languages supported by a
+ driver is up to the driver writer.
+ DriverName - A pointer to the Unicode string to return. This Unicode string
+ is the name of the driver specified by This in the language
+ specified by Language.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the Driver specified by This
+ and the language specified by Language was returned
+ in DriverName.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - DriverName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+
+ return EfiLibLookupUnicodeString (
+ Language,
+ gBiosVideoComponentName2.SupportedLanguages,
+ mBiosVideoDriverNameTable2,
+ DriverName
+ );
+}
+
+
+EFI_STATUS
+EFIAPI
+BiosVideoComponentName2GetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+/*++
+
+ Routine Description:
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by an EFI Driver.
+
+ Arguments:
+ This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+ ControllerHandle - The handle of a controller that the driver specified by
+ This is managing. This handle specifies the controller
+ whose name is to be returned.
+ ChildHandle - The handle of the child controller to retrieve the name
+ of. This is an optional parameter that may be NULL. It
+ will be NULL for device drivers. It will also be NULL
+ for a bus drivers that wish to retrieve the name of the
+ bus controller. It will not be NULL for a bus driver
+ that wishes to retrieve the name of a child controller.
+ Language - A pointer to a three character ISO 639-2 language
+ identifier. This is the language of the controller name
+ that that the caller is requesting, and it must match one
+ of the languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up to the
+ driver writer.
+ ControllerName - A pointer to the Unicode string to return. This Unicode
+ string is the name of the controller specified by
+ ControllerHandle and ChildHandle in the language specified
+ by Language from the point of view of the driver specified
+ by This.
+
+ Returns:
+ EFI_SUCCESS - The Unicode string for the user readable name in the
+ language specified by Language for the driver
+ specified by This was returned in DriverName.
+ EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
+ EFI_INVALID_PARAMETER - Language is NULL.
+ EFI_INVALID_PARAMETER - ControllerName is NULL.
+ EFI_UNSUPPORTED - The driver specified by This is not currently managing
+ the controller specified by ControllerHandle and
+ ChildHandle.
+ EFI_UNSUPPORTED - The driver specified by This does not support the
+ language specified by Language.
+
+--*/
+{
+ return EFI_UNSUPPORTED;
+}
diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif
new file mode 100644
index 0000000..e357445
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.cif
@@ -0,0 +1,20 @@
+<component>
+ name = "CsmVideo"
+ category = ModulePart
+ LocalRoot = "Core\EM\CSM\Thunk\CsmVideo\"
+ RefName = "CsmVideo"
+[files]
+"CsmVideo.sdl"
+"CsmVideo.mak"
+"UefiBiosVideo.h"
+"UefiBiosVideo.c"
+"ComponentName.c"
+"VesaBiosExtensions.h"
+"pci22.h"
+"AmiMapping.h"
+"AmiMapping.c"
+"VgaMiniPort.h"
+"VgaClass.h"
+"VgaClass.c"
+"CsmVideo.dxs"
+<endComponent>
diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs
new file mode 100644
index 0000000..2f961f5
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.dxs
@@ -0,0 +1,46 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.dxs 1 11/10/11 6:34p Olegi $
+//
+// $Revision: 1 $
+//
+// $Date: 11/10/11 6:34p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.dxs $
+//
+// 1 11/10/11 6:34p Olegi
+//
+//**********************************************************************
+
+#include <Protocol\LegacyBios.h>
+
+DEPENDENCY_START
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak
new file mode 100644
index 0000000..4d59620
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.mak
@@ -0,0 +1,66 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.mak 2 4/27/07 5:18p Olegi $
+#
+# $Revision: 2 $
+#
+# $Date: 4/27/07 5:18p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/CsmVideo/CsmVideo.mak $
+#
+# 2 4/27/07 5:18p Olegi
+#
+# 1 12/29/06 3:33p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CsmVideo.mak
+#
+# Description: CSM Video make file
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : CsmVideo
+
+CsmVideo : $(BUILD_DIR)\CsmVideo.mak CsmVideoBin
+
+$(BUILD_DIR)\CsmVideo.mak : $(CsmVideo_DIR)\$(@B).cif $(CsmVideo_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CsmVideo_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CsmVideoBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CsmVideo.mak all\
+ GUID=29CF55F8-B675-4f5d-8F2F-B87A3ECFD063\
+ ENTRY_POINT=BiosVideoDriverEntryPoint\
+ EXT_HEADERS=$(BUILD_DIR)\Token.h\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl
new file mode 100644
index 0000000..19768e8
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/CsmVideo.sdl
@@ -0,0 +1,58 @@
+TOKEN
+ Name = "CsmVideo_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CsmVideo support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "INT10_VESA_GO_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables support of the Graphics Output protocol using VESA INT10 extensions"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INT10_VGA_GO_SUPPORT"
+ Value = "0"
+ Help = "Enables/Disables support of the Graphics Output protocol using standard VGA INT10 calls in 640x480 16 color mode.\If both VGA_GO_SUPPORT and VESA_GO_SUPPORT enabled, VGA calls will only be used if VESA extensions are not supported by the video card."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INT10_SIMPLE_TEXT_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables support of the Simple Text Output protocol using text mode.\If VGA_GO_SUPPORT or VESA_GO_SUPPORT or both enabled, text mode will will only be used if neither VESA nor standard VGA graphical modes are supported"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INT10_TRUST_EDID_INFORMATION"
+ Value = "1"
+ Help = "Some SSUs(Server Switch Units) return invalid EDID information, for these turn this switch off."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+
+PATH
+ Name = "CsmVideo_DIR"
+End
+
+MODULE
+ Help = "Includes CsmVideo.mak to Project"
+ File = "CsmVideo.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CsmVideo.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c
new file mode 100644
index 0000000..ddbe46c
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.c
@@ -0,0 +1,3886 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+--*/
+/*++
+
+Copyright (c) 2006 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ BiosVideo.c
+
+Abstract:
+
+ ConsoleOut Routines that speak VGA.
+
+Revision History
+
+--*/
+
+//*** AMI PORTING BEGIN ***//
+#include "AcpiRes.h"
+//*** AMI PORTING END *****//
+#include "UefiBiosVideo.h"
+
+#define TRACE_BIOS_VIDEO TRACE_ALWAYS
+//#define TRACE_BIOS_VIDEO TRACE_NEVER
+
+//
+// EFI Driver Binding Protocol Instance
+//
+EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding = {
+ BiosVideoDriverBindingSupported,
+ BiosVideoDriverBindingStart,
+ BiosVideoDriverBindingStop,
+ 0x00000024,
+ NULL,
+ NULL
+};
+
+typedef struct _TEXT_MODE {
+ INT32 ModeNum;
+ INT32 Col;
+ INT32 Row;
+ UINT32 VideoCol; // horizontal pixels
+ UINT32 VideoRow; // vertical pixels
+} TEXT_MODE;
+
+#if CORE_COMBINED_VERSION < 0x4028e
+const TEXT_MODE TextModeArray[] = {GC_MODE_LIST};
+const INT32 MaxTextMode=(sizeof(TextModeArray)/sizeof(TEXT_MODE));
+#else
+extern TEXT_MODE TextModeArray[];
+extern INT32 MaxTextMode;
+#endif
+
+// remove the following line when Protocol/EdidOverride.h becomes available
+EFI_GUID gEfiEdidOverrideProtocolGuid = EFI_EDID_OVERRIDE_PROTOCOL_GUID;
+
+//*** AMI PORTING BEGIN ***//
+#if INT10_VGA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+//
+// Global lookup tables for VGA graphics modes
+//
+UINT8 mVgaLeftMaskTable[] = { 0xff, 0x7f, 0x3f, 0x1f, 0x0f, 0x07, 0x03, 0x01 };
+
+UINT8 mVgaRightMaskTable[] = { 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff };
+
+UINT8 mVgaBitMaskTable[] = { 0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01 };
+
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL mVgaColorToGraphicsOutputColor[] = {
+ { 0x00, 0x00, 0x00, 0x00 },
+ { 0x98, 0x00, 0x00, 0x00 },
+ { 0x00, 0x98, 0x00, 0x00 },
+ { 0x98, 0x98, 0x00, 0x00 },
+ { 0x00, 0x00, 0x98, 0x00 },
+ { 0x98, 0x00, 0x98, 0x00 },
+ { 0x00, 0x98, 0x98, 0x00 },
+ { 0x98, 0x98, 0x98, 0x00 },
+ { 0x10, 0x10, 0x10, 0x00 },
+ { 0xff, 0x10, 0x10, 0x00 },
+ { 0x10, 0xff, 0x10, 0x00 },
+ { 0xff, 0xff, 0x10, 0x00 },
+ { 0x10, 0x10, 0xff, 0x00 },
+ { 0xf0, 0x10, 0xff, 0x00 },
+ { 0x10, 0xff, 0xff, 0x00 },
+ { 0xff, 0xff, 0xff, 0x00 }
+};
+
+//*** AMI PORTING BEGIN ***//
+#endif //if INT10_VGA_GO_SUPPORT==1
+#if INT10_VESA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+
+//
+// Standard timing defined by VESA EDID
+//
+VESA_BIOS_EXTENSIONS_EDID_TIMING mEstablishedEdidTiming[] = {
+ //
+ // Established Timing I
+ //
+ {800, 600, 60},
+ {800, 600, 56},
+ {640, 480, 75},
+ {640, 480, 72},
+ {640, 480, 67},
+ {640, 480, 60},
+ {720, 400, 88},
+ {720, 400, 70},
+ //
+ // Established Timing II
+ //
+ {1280, 1024, 75},
+ {1024, 768, 75},
+ {1024, 768, 70},
+ {1024, 768, 60},
+ {1024, 768, 87},
+ {832, 624, 75},
+ {800, 600, 75},
+ {800, 600, 72},
+ //
+ // Established Timing III
+ //
+ {1152, 870, 75}
+};
+//*** AMI PORTING BEGIN ***//
+#endif //if INT10_VESA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+
+UINT32 SupportedResolutions[29] = { 0 };
+
+EFI_STATUS
+BiosVideoChildHandleInstall (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ParentHandle,
+ IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
+ IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios,
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+;
+
+EFI_STATUS
+BiosVideoChildHandleUninstall (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_HANDLE Handle
+ )
+;
+
+VOID
+BiosVideoDeviceReleaseResource (
+ BIOS_VIDEO_DEV *BiosVideoPrivate
+ )
+;
+
+//*** AMI PORTING BEGIN ***//
+//CsmVideo Policy Protocol support
+//The protocol can be used to set the driver policy.
+// The two supported policies are:
+// SimpleTextOut over the text mode 3 (TextMode=TRUE)
+// GOP over graphical mode (TextMode=FALSE)
+EFI_HANDLE VgaControllerHandle = NULL;
+BOOLEAN TextModePolicy = FALSE;
+
+EFI_STATUS CsmVideoPolicySetMode(
+ IN CSM_VIDEO_POLICY_PROTOCOL *This,
+ IN BOOLEAN TextMode, IN BOOLEAN ForceModeChange
+){
+#if INT10_SIMPLE_TEXT_SUPPORT==0
+ return (TextMode) ? EFI_UNSUPPORTED : EFI_SUCCESS;
+#else
+ EFI_STATUS Status;
+ BOOLEAN OriginalPolicy=TextModePolicy;
+ EFI_HANDLE Handle;
+
+ TextModePolicy = TextMode;
+ if ( VgaControllerHandle == NULL
+ || OriginalPolicy==TextModePolicy && !ForceModeChange
+ ) return EFI_SUCCESS;
+
+ // save the VGA handle
+ // the global variable VgaControllerHandle will be nullified
+ // by the Stop function during Disconnect.
+ Handle = VgaControllerHandle;
+ Status = pBS->DisconnectController( Handle, NULL, NULL );
+ if (!EFI_ERROR(Status))
+ Status = pBS->ConnectController( Handle, NULL, NULL, TRUE );
+ else
+ TextModePolicy = OriginalPolicy;
+ if (EFI_ERROR(Status)) return Status;
+ return (TextModePolicy==TextMode) ? EFI_SUCCESS : EFI_UNSUPPORTED;
+#endif
+}
+
+EFI_STATUS CsmVideoPolicyGetMode(
+ IN CSM_VIDEO_POLICY_PROTOCOL *This,IN BOOLEAN *IsTextMode
+){
+ if (IsTextMode!=NULL) *IsTextMode = TextModePolicy;
+ return (VgaControllerHandle == NULL) ? EFI_NOT_STARTED : EFI_SUCCESS;
+}
+
+CSM_VIDEO_POLICY_PROTOCOL CsmVideoPolicyProtocol = {
+ CsmVideoPolicyGetMode, CsmVideoPolicySetMode
+};
+//*** AMI PORTING END *****//
+
+EFI_STATUS GetBadEdid (
+ IN EFI_EDID_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle,
+ OUT UINT32 *Attributes,
+ IN OUT UINTN *EdidSize,
+ IN OUT UINT8 **Edid
+ )
+{
+ static UINT8 EdidData[0x80] = {0};
+ EdidData[0x7f] = 1; // invalid checksum
+
+ *Edid = EdidData;
+ *EdidSize = 0x80;
+ *Attributes = 0;
+
+ return EFI_SUCCESS;
+}
+
+
+//
+// Driver Entry Point
+//
+EFI_DRIVER_ENTRY_POINT (BiosVideoDriverEntryPoint)
+
+EFI_STATUS
+EFIAPI
+BiosVideoDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+
+ Driver Entry Point.
+
+ Arguments:
+
+ ImageHandle - Handle of driver image.
+ SystemTable - Pointer to system table.
+
+ Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ static EFI_GUID gCsmThunkDriverGuid =
+ { 0x2362ea9c, 0x84e5, 0x4dff, 0x83, 0xbc, 0xb5, 0xac, 0xec, 0xb5, 0x7c, 0xbb };
+
+ Status = EfiLibInstallAllDriverProtocols (
+ ImageHandle,
+ SystemTable,
+ &gBiosVideoDriverBinding,
+ ImageHandle,
+#if EFI_SPECIFICATION_VERSION <= 0x20000
+ &gBiosVideoComponentName,
+#else
+ &gBiosVideoComponentName2,
+#endif
+ NULL,
+ NULL
+ );
+//*** AMI PORTING BEGIN ***//
+#if INT10_SIMPLE_TEXT_SUPPORT==1
+{
+//create new handle
+ EFI_HANDLE Handle = NULL;
+ VgaClassDriverEntryPoint(Handle,SystemTable);
+}
+#endif
+
+#if INT10_TRUST_EDID_INFORMATION == 0
+{
+ // Install EdidOverride with the dummy EDID information; this is needed to ignore
+ // bad EDID information
+ EFI_STATUS Status;
+ static EFI_EDID_OVERRIDE_PROTOCOL EdidOverride = { GetBadEdid };
+
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiEdidOverrideProtocolGuid, &EdidOverride,
+ NULL
+ );
+}
+#endif
+
+// Install CsmVideoPolicy protocol
+ gBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gCsmVideoPolicyProtocolGuid, &CsmVideoPolicyProtocol,
+ &gCsmThunkDriverGuid, NULL,
+ NULL
+ );
+
+//AMI CSM Core does not need Legacy BIOS GUID
+//Just return the status
+ return Status;
+/*
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Install Legacy BIOS GUID to mark this driver as a BIOS Thunk Driver
+ //
+ return gBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gEfiLegacyBiosGuid,
+ NULL,
+ NULL
+ );
+*/
+//*** AMI PORTING END *****//
+}
+//*** AMI PORTING BEGIN ***//
+//Exit Boot Services callback is not needed.
+/*
+VOID
+BiosVideoExitBootServices (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+*/
+/*++
+
+Routine Description:
+
+ Callback function for exit boot service event
+
+Arguments:
+
+ Event - EFI_EVENT structure
+ Context - Event context
+
+Returns:
+
+ None
+
+--*/
+/*{
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ EFI_IA32_REGISTER_SET Regs;
+
+ //
+ // Get our context
+ //
+ BiosVideoPrivate = (BIOS_VIDEO_DEV *) Context;
+
+ //
+ // Set the 80x25 Text VGA Mode
+ //
+ Regs.H.AH = 0x00;
+ Regs.H.AL = 0x83;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ Regs.H.AH = 0x11;
+ Regs.H.AL = 0x14;
+ Regs.H.BL = 0;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+}
+*/
+//*** AMI PORTING END *****//
+
+EFI_STATUS
+EFIAPI
+BiosVideoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Supported.
+
+ Arguments:
+
+ This - Pointer to driver binding protocol
+ Controller - Controller handle to connect
+ RemainingDevicePath - A pointer to the remaining portion of a device path
+
+
+ Returns:
+
+ EFI_STATUS - EFI_SUCCESS:This controller can be managed by this driver,
+ Otherwise, this controller cannot be managed by this driver
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ PCI_TYPE00 Pci;
+
+ //
+ // See if the Legacy BIOS Protocol is available
+ //
+ Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // See if this is a PCI Graphics Controller by looking at the Command register and
+ // Class Code Register
+ //
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ Status = EFI_UNSUPPORTED;
+ if (Pci.Hdr.ClassCode[2] == 0x03 || (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01)) {
+ Status = EFI_SUCCESS;
+ }
+
+Done:
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+BiosVideoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Install Graphics Output Protocol onto VGA device handles
+
+ Arguments:
+
+ This - Pointer to driver binding protocol
+ Controller - Controller handle to connect
+ RemainingDevicePath - A pointer to the remaining portion of a device path
+
+ Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINTN Flags;
+//*** AMI PORTING BEGIN ***//
+// See comments below regarding the Capabilities usage
+ UINT64 Capabilities = 0;
+//*** AMI PORTING END *****//
+
+ PciIo = NULL;
+ //
+ // Prepare for status code
+ //
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Open the IO Abstraction(s) needed
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // See if the Legacy BIOS Protocol is available
+ //
+ Status = gBS->LocateProtocol (&gEfiLegacyBiosProtocolGuid, NULL, (VOID **) &LegacyBios);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ ReportStatusCodeWithDevicePath (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_ENABLE,
+ 0,
+ &gEfiCallerIdGuid,
+ ParentDevicePath
+ );
+ //
+ // Enable the device and make sure VGA cycles are being forwarded to this VGA device
+ //
+//*** AMI PORTING BEGIN ***//
+// We need to check what is supported by the hardware before enabling attributes
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &Capabilities
+ );
+
+ if ( EFI_ERROR(Status) ) {
+ goto Done;
+ }
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL
+ );
+/*
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL
+ );
+*/
+//*** AMI PORTING END *****//
+ if (EFI_ERROR (Status)) {
+ ReportStatusCodeWithDevicePath (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_RESOURCE_CONFLICT,
+ 0,
+ &gEfiCallerIdGuid,
+ ParentDevicePath
+ );
+ goto Done;
+ }
+ //
+ // Check to see if there is a legacy option ROM image associated with this PCI device
+ //
+ Status = LegacyBios->CheckPciRom (
+ LegacyBios,
+ Controller,
+ NULL,
+ NULL,
+ &Flags
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ //
+ // Post the legacy option ROM if it is available.
+ //
+ ReportStatusCodeWithDevicePath (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_RESET,
+ 0,
+ &gEfiCallerIdGuid,
+ ParentDevicePath
+ );
+ Status = LegacyBios->InstallPciRom (
+ LegacyBios,
+ Controller,
+ NULL,
+ &Flags,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ ReportStatusCodeWithDevicePath (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
+ 0,
+ &gEfiCallerIdGuid,
+ ParentDevicePath
+ );
+ goto Done;
+ }
+
+ //
+ // Create child handle and install GraphicsOutputProtocol on it
+ //
+ Status = BiosVideoChildHandleInstall (
+ This,
+ Controller,
+ PciIo,
+ LegacyBios,
+ ParentDevicePath,
+ RemainingDevicePath
+ );
+
+Done:
+ if (EFI_ERROR (Status)) {
+ if (PciIo != NULL) {
+ ReportStatusCodeWithDevicePath (
+ EFI_PROGRESS_CODE,
+ EFI_P_PC_DISABLE,
+ 0,
+ &gEfiCallerIdGuid,
+ ParentDevicePath
+ );
+ //
+ // Turn off the PCI device and disable forwarding of VGA cycles to this device
+ //
+ if (Capabilities != 0)
+ {
+ PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationDisable,
+//*** AMI PORTING BEGIN ***//
+ Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+// EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+//*** AMI PORTING END *****//
+ NULL
+ );
+ }
+ //
+ // Release PCI I/O Protocols on the controller handle.
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+BiosVideoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+ Routine Description:
+
+ Stop.
+
+ Arguments:
+
+ This - Pointer to driver binding protocol
+ Controller - Controller handle to connect
+ NumberOfChilren - Number of children handle created by this driver
+ ChildHandleBuffer - Buffer containing child handle created
+
+ Returns:
+
+ EFI_SUCCESS - Driver disconnected successfully from controller
+ EFI_UNSUPPORTED - Cannot find BIOS_VIDEO_DEV structure
+
+--*/
+{
+ EFI_STATUS Status;
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ BOOLEAN AllChildrenStopped;
+ UINTN Index;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT64 Capabilities;
+
+ BiosVideoPrivate = NULL;
+
+ if (NumberOfChildren == 0) {
+//*** AMI PORTING BEGIN ***//
+//In text mode, the child handle is not created
+//and the mini port protocol is installed on the PciIo handle.
+//Original implementation does not stop controller in this case
+//Here is the fix:
+#if INT10_SIMPLE_TEXT_SUPPORT==1
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiVgaMiniPortProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR(Status)){
+ return BiosVideoChildHandleUninstall (This, Controller, Controller);
+ }
+#endif
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationSupported,
+ 0,
+ &Capabilities
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationDisable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+//*** AMI PORTING END *****//
+ //
+ // Close PCI I/O protocol on the controller handle
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return EFI_SUCCESS;
+ }
+
+ AllChildrenStopped = TRUE;
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+ Status = BiosVideoChildHandleUninstall (This, Controller, ChildHandleBuffer[Index]);
+
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+BiosVideoChildHandleInstall (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ParentHandle,
+ IN EFI_PCI_IO_PROTOCOL *ParentPciIo,
+ IN EFI_LEGACY_BIOS_PROTOCOL *ParentLegacyBios,
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+ Install child handles if the Handle supports MBR format.
+
+Arguments:
+ This - Calling context.
+ Handle - Parent Handle
+ PciIo - Parent PciIo interface
+ LegacyBios - Parent LegacyBios interface
+ DevicePath - Parent Device Path
+
+Returns:
+ EFI_SUCCESS - If a child handle was added
+ other - A child handle was not added
+
+--*/
+{
+ EFI_STATUS Status;
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ PCI_TYPE00 Pci;
+ ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
+
+ //
+ // Allocate the private device structure for video device
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (BIOS_VIDEO_DEV),
+ &BiosVideoPrivate
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ EfiZeroMem (BiosVideoPrivate, sizeof (BIOS_VIDEO_DEV));
+
+ //
+ // See if this is a VGA compatible controller or not
+ //
+ Status = ParentPciIo->Pci.Read (
+ ParentPciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ sizeof (Pci) / sizeof (UINT32),
+ &Pci
+ );
+ if (EFI_ERROR (Status)) {
+ ReportStatusCodeWithDevicePath (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
+ 0,
+ &gEfiCallerIdGuid,
+ ParentDevicePath
+ );
+ goto Done;
+ }
+ BiosVideoPrivate->VgaCompatible = FALSE;
+ if (Pci.Hdr.ClassCode[2] == 0x00 && Pci.Hdr.ClassCode[1] == 0x01) {
+ BiosVideoPrivate->VgaCompatible = TRUE;
+ }
+
+ if (Pci.Hdr.ClassCode[2] == 0x03 && Pci.Hdr.ClassCode[1] == 0x00 && Pci.Hdr.ClassCode[0] == 0x00) {
+ BiosVideoPrivate->VgaCompatible = TRUE;
+ }
+
+ //
+ // Initialize the child private structure
+ //
+ BiosVideoPrivate->Signature = BIOS_VIDEO_DEV_SIGNATURE;
+ BiosVideoPrivate->Handle = NULL;
+
+//*** AMI PORTING BEGIN ***//
+//Exit Boot Services callback is not needed.
+/*
+ Status = gBS->CreateEvent (
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_NOTIFY,
+ BiosVideoExitBootServices,
+ BiosVideoPrivate,
+ &BiosVideoPrivate->ExitBootServicesEvent
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+*/
+//*** AMI PORTING END *****//
+
+ //
+ // Fill in Graphics Output specific mode structures
+ //
+ BiosVideoPrivate->HardwareNeedsStarting = TRUE;
+ BiosVideoPrivate->ModeData = NULL;
+ BiosVideoPrivate->LineBuffer = NULL;
+ BiosVideoPrivate->VgaFrameBuffer = NULL;
+ BiosVideoPrivate->VbeFrameBuffer = NULL;
+
+//*** AMI PORTING BEGIN ***//
+//Let's do it only if VgaMiniPort is going to be installed
+/*
+ //
+ // Fill in the VGA Mini Port Protocol fields
+ //
+ BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode;
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000;
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4;
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5;
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR;
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
+*/
+ //
+ // Assume that Graphics Output Protocol will be produced until proven otherwise
+ //
+ BiosVideoPrivate->ProduceGraphicsOutput = TRUE;
+
+ //
+ // Set Gop Device Path, here RemainingDevicePath will not be one End of Device Path Node.
+ //
+ if ((RemainingDevicePath == NULL) || (!IsDevicePathEnd (RemainingDevicePath))) {
+ if (RemainingDevicePath == NULL) {
+ EfiZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
+ AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
+ AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
+ AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
+ SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
+
+ BiosVideoPrivate->DevicePath = EfiAppendDevicePathNode (
+ ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
+ );
+ } else {
+ BiosVideoPrivate->DevicePath = EfiAppendDevicePathNode (ParentDevicePath, RemainingDevicePath);
+ }
+
+ //
+ // Create child handle associated with device path
+ // The newely created handle can be used for calling EDID_OVERRIDE_PROTOCOL
+ //
+ BiosVideoPrivate->Handle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &BiosVideoPrivate->Handle,
+ &gEfiDevicePathProtocolGuid,
+ BiosVideoPrivate->DevicePath,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+
+ //
+ // Child handle need to consume the Legacy Bios protocol
+ //
+ BiosVideoPrivate->LegacyBios = ParentLegacyBios;
+
+ //
+ // When check for VBE, PCI I/O protocol is needed, so use parent's protocol interface temporally
+ //
+ BiosVideoPrivate->PciIo = ParentPciIo;
+
+ //
+ // Check for VESA BIOS Extensions for modes that are compatible with Graphics Output
+ //
+//*** AMI PORTING BEGIN ***//
+// Status = BiosVideoCheckForVbe (BiosVideoPrivate);
+#if INT10_VESA_GO_SUPPORT==1
+ if ( TextModePolicy )
+ Status = EFI_UNSUPPORTED;
+ else
+ Status = BiosVideoCheckForVbe (BiosVideoPrivate, &Pci);
+#else
+ Status = EFI_UNSUPPORTED;
+#endif
+//*** AMI PORTING END *****//
+ if (EFI_ERROR (Status)) {
+ //
+ // The VESA BIOS Extensions are not compatible with Graphics Output, so check for support
+ // for the standard 640x480 16 color VGA mode
+ //
+//*** AMI PORTING BEGIN ***//
+// if (BiosVideoPrivate->VgaCompatible) {
+// Status = BiosVideoCheckForVga (BiosVideoPrivate);
+// }
+#if INT10_VGA_GO_SUPPORT==1
+ if (!TextModePolicy && BiosVideoPrivate->VgaCompatible) {
+ Status = BiosVideoCheckForVga (BiosVideoPrivate);
+ }
+#endif
+//*** AMI PORTING END *****//
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Neither VBE nor the standard 640x480 16 color VGA mode are supported, so do
+ // not produce the Graphics Output protocol. Instead, produce the VGA MiniPort Protocol.
+ //
+ BiosVideoPrivate->ProduceGraphicsOutput = FALSE;
+
+ //
+ // INT services are available, so on the 80x25 and 80x50 text mode are supported
+ //
+ BiosVideoPrivate->VgaMiniPort.MaxMode = 2;
+ }
+ }
+
+ if (BiosVideoPrivate->ProduceGraphicsOutput) {
+ //
+ // Create child handle and install Graphics Output Protocol,EDID Discovered/Active Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &BiosVideoPrivate->Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ &BiosVideoPrivate->GraphicsOutput,
+ &gEfiEdidDiscoveredProtocolGuid,
+ &BiosVideoPrivate->EdidDiscovered,
+ &gEfiEdidActiveProtocolGuid,
+ &BiosVideoPrivate->EdidActive,
+ NULL
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Open the Parent Handle for the child
+ //
+ Status = gBS->OpenProtocol (
+ ParentHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &BiosVideoPrivate->PciIo,
+ This->DriverBindingHandle,
+ BiosVideoPrivate->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ }
+ } else {
+//*** AMI PORTING BEGIN ***//
+#if INT10_SIMPLE_TEXT_SUPPORT==1
+//The code if moved here from BiosVideoChildHandleInstall
+ //
+ // Fill in the VGA Mini Port Protocol fields
+ //
+ BiosVideoPrivate->VgaMiniPort.SetMode = BiosVideoVgaMiniPortSetMode;
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryOffset = 0xb8000;
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterOffset = 0x3d4;
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterOffset = 0x3d5;
+ BiosVideoPrivate->VgaMiniPort.VgaMemoryBar = EFI_PCI_IO_PASS_THROUGH_BAR;
+ BiosVideoPrivate->VgaMiniPort.CrtcAddressRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
+ BiosVideoPrivate->VgaMiniPort.CrtcDataRegisterBar = EFI_PCI_IO_PASS_THROUGH_BAR;
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+ //This is needed! Otherwise VgaClass driver rejects VgaMiniPort
+ //device due to the lack of PciIo protocol
+ BiosVideoPrivate->Handle=ParentHandle;
+//*** AMI PORTING END *****//
+ //
+ // Install VGA Mini Port Protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &BiosVideoPrivate->Handle,
+ &gEfiVgaMiniPortProtocolGuid,
+ &BiosVideoPrivate->VgaMiniPort,
+ NULL
+ );
+//*** AMI PORTING BEGIN ***//
+#else
+#endif //INT10_SIMPLE_TEXT_SUPPORT==1
+//*** AMI PORTING END *****//
+ }
+
+Done:
+ if (EFI_ERROR (Status)) {
+ //
+ // Free private data structure
+ //
+ BiosVideoDeviceReleaseResource (BiosVideoPrivate);
+ }
+//*** AMI PORTING BEGIN ***//
+// The protocols are installed.
+// Update global variables used by the CsmVideoPolicy protocol implementation.
+ TextModePolicy = !BiosVideoPrivate->ProduceGraphicsOutput;
+ VgaControllerHandle = ParentHandle;
+//*** AMI PORTING END *****//
+ return Status;
+}
+
+EFI_STATUS
+BiosVideoChildHandleUninstall (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ Deregister an video child handle and free resources
+
+Arguments:
+
+ This - Protocol instance pointer.
+ Controller - Video controller handle
+ Handle - Video child handle
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET Regs;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+
+ BiosVideoPrivate = NULL;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiGraphicsOutputProtocolGuid,
+ (VOID **) &GraphicsOutput,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
+ }
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiVgaMiniPortProtocolGuid,
+ (VOID **) &VgaMiniPort,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (VgaMiniPort);
+ }
+
+ if (BiosVideoPrivate == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Close PCI I/O protocol that opened by child handle
+ //
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ //
+ // Uninstall protocols on child handle
+ //
+ if (BiosVideoPrivate->ProduceGraphicsOutput) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ BiosVideoPrivate->Handle,
+ &gEfiDevicePathProtocolGuid,
+ BiosVideoPrivate->DevicePath,
+ &gEfiGraphicsOutputProtocolGuid,
+ &BiosVideoPrivate->GraphicsOutput,
+ &gEfiEdidDiscoveredProtocolGuid,
+ &BiosVideoPrivate->EdidDiscovered,
+ &gEfiEdidActiveProtocolGuid,
+ &BiosVideoPrivate->EdidActive,
+ NULL
+ );
+ } else {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ BiosVideoPrivate->Handle,
+ &gEfiVgaMiniPortProtocolGuid,
+ &BiosVideoPrivate->VgaMiniPort,
+ NULL
+ );
+ }
+ if (EFI_ERROR (Status)) {
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ return Status;
+ }
+
+ //
+ // Set the 80x25 Text VGA Mode
+ //
+ Regs.H.AH = 0x00;
+ Regs.H.AL = 0x03;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ Regs.H.AH = 0x11;
+ Regs.H.AL = 0x14;
+ Regs.H.BL = 0;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ //
+ // Do not disable IO/memory decode since that would prevent legacy ROM from working
+ //
+
+ //
+ // Release all allocated resources
+ //
+ BiosVideoDeviceReleaseResource (BiosVideoPrivate);
+//*** AMI PORTING BEGIN ***//
+// The protocols are uninstalled.
+// Update global variables used by the CsmVideoPolicy protocol implementation.
+ VgaControllerHandle = NULL;
+//*** AMI PORTING END *****//
+ return EFI_SUCCESS;
+}
+
+VOID
+BiosVideoDeviceReleaseResource (
+ BIOS_VIDEO_DEV *BiosVideoPrivate
+ )
+/*++
+Routing Description:
+
+ Release resources of an video child device before stopping it.
+
+Arguments:
+
+ BiosVideoPrivate - Video child device private data structure
+
+Returns:
+
+ NONE
+
+---*/
+{
+ if (BiosVideoPrivate == NULL) {
+ return ;
+ }
+
+ //
+ // Release all the resourses occupied by the BIOS_VIDEO_DEV
+ //
+
+ //
+ // Free VGA Frame Buffer
+ //
+ if (BiosVideoPrivate->VgaFrameBuffer != NULL) {
+ gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);
+ BiosVideoPrivate->VgaFrameBuffer = NULL;
+ }
+ //
+ // Free VBE Frame Buffer
+ //
+ if (BiosVideoPrivate->VbeFrameBuffer != NULL) {
+ gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);
+ BiosVideoPrivate->VbeFrameBuffer = NULL;
+ }
+ //
+ // Free line buffer
+ //
+ if (BiosVideoPrivate->LineBuffer != NULL) {
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);
+ BiosVideoPrivate->LineBuffer = NULL;
+ }
+ //
+ // Free mode data
+ //
+ if (BiosVideoPrivate->ModeData != NULL) {
+ gBS->FreePool (BiosVideoPrivate->ModeData);
+ BiosVideoPrivate->ModeData = NULL;
+ }
+ //
+ // Free memory allocated below 1MB
+ //
+ if (BiosVideoPrivate->PagesBelow1MB != 0) {
+ gBS->FreePages (BiosVideoPrivate->PagesBelow1MB, BiosVideoPrivate->NumberOfPagesBelow1MB);
+ }
+
+ if (BiosVideoPrivate->VbeSaveRestorePages != 0) {
+ gBS->FreePages (BiosVideoPrivate->VbeSaveRestoreBuffer, BiosVideoPrivate->VbeSaveRestorePages);
+ }
+ //
+ // Free graphics output protocol occupied resource
+ //
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL;
+ }
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL;
+ }
+ //
+ // Free EDID discovered protocol occupied resource
+ //
+ if (BiosVideoPrivate->EdidDiscovered.Edid != NULL) {
+ gBS->FreePool (BiosVideoPrivate->EdidDiscovered.Edid);
+ BiosVideoPrivate->EdidDiscovered.Edid = NULL;
+ }
+ //
+ // Free EDID active protocol occupied resource
+ //
+ if (BiosVideoPrivate->EdidActive.Edid != NULL) {
+ gBS->FreePool (BiosVideoPrivate->EdidActive.Edid);
+ BiosVideoPrivate->EdidActive.Edid = NULL;
+ }
+
+ if (BiosVideoPrivate->DevicePath!= NULL) {
+ gBS->FreePool (BiosVideoPrivate->DevicePath);
+ BiosVideoPrivate->DevicePath = NULL;
+ }
+
+ //
+ // Close the ExitBootServices event
+ //
+//*** AMI PORTING BEGIN ***//
+//ExitBootServicesEvent is not used
+/*
+ if (BiosVideoPrivate->ExitBootServicesEvent != NULL) {
+ gBS->CloseEvent (BiosVideoPrivate->ExitBootServicesEvent);
+ }
+*/
+//*** AMI PORTING END *****//
+
+ gBS->FreePool (BiosVideoPrivate);
+
+ return ;
+}
+
+//*** AMI PORTING BEGIN ***//
+#if INT10_VESA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+STATIC
+UINT32
+CalculateEdidKey (
+ VESA_BIOS_EXTENSIONS_EDID_TIMING *EdidTiming
+ )
+/*++
+
+ Routine Description:
+
+ Generate a search key for a specified timing data.
+
+ Arguments:
+
+ EdidTiming - Pointer to EDID timing
+
+ Returns:
+ The 32 bit unique key for search.
+
+--*/
+{
+ UINT32 Key;
+
+ //
+ // Be sure no conflicts for all standard timing defined by VESA.
+ //
+ Key = (EdidTiming->HorizontalResolution * 2) + EdidTiming->VerticalResolution + EdidTiming->RefreshRate;
+ return Key;
+}
+
+STATIC
+BOOLEAN
+ParseEdidData (
+ UINT8 *EdidBuffer
+ )
+/*++
+
+ Routine Description:
+
+ Parse the Established Timing and Standard Timing in EDID data block.
+
+ Arguments:
+
+ EdidBuffer - Pointer to EDID data block
+ ValidEdidTiming - Valid EDID timing information
+
+ Returns:
+ TRUE - The EDID data is valid.
+ FALSE - The EDID data is invalid.
+
+--*/
+{
+ UINT8 CheckSum;
+ UINT32 Index;
+ UINT32 ValidNumber;
+ UINT32 TimingBits;
+ UINT8 *BufferIndex;
+ UINT16 HorizontalResolution;
+ UINT16 VerticalResolution;
+ UINT8 AspectRatio;
+ VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *EdidDataBlock;
+
+ EdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) EdidBuffer;
+
+ //
+ // Check the checksum of EDID data
+ //
+ CheckSum = 0;
+ for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE; Index ++) {
+ CheckSum = CheckSum + EdidBuffer[Index];
+ }
+ if (CheckSum != 0) {
+ TRACE((TRACE_BIOS_VIDEO, "EDID checksum is invalid, EDID will be ignored.\n"));
+ return FALSE;
+ }
+
+ ValidNumber = 0;
+ //
+ // Established timing data
+ //
+ TimingBits = EdidDataBlock->EstablishedTimings[0] |
+ (EdidDataBlock->EstablishedTimings[1] << 8) |
+ ((EdidDataBlock->EstablishedTimings[2] & 0x80) << 9) ;
+ for (Index = 0; Index < VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER; Index ++) {
+ if (TimingBits & 0x1) {
+ SupportedResolutions[Index] = mEstablishedEdidTiming[Index].VerticalResolution |
+ (mEstablishedEdidTiming[Index].HorizontalResolution << 16);
+ ValidNumber ++;
+ }
+ TimingBits = TimingBits >> 1;
+ }
+
+ //
+ // If no Established timing data, read the standard timing data
+ //
+ BufferIndex = &EdidDataBlock->StandardTimingIdentification[0];
+ for (Index = 0; Index < 8; Index ++) {
+ if ((BufferIndex[0] != 0x1) && (BufferIndex[1] != 0x1)){
+ //
+ // A valid Standard Timing
+ //
+ HorizontalResolution = BufferIndex[0] * 8 + 248;
+ AspectRatio = BufferIndex[1] >> 6;
+ switch (AspectRatio) {
+ case 0:
+ VerticalResolution = HorizontalResolution / 16 * 10;
+ break;
+ case 1:
+ VerticalResolution = HorizontalResolution / 4 * 3;
+ break;
+ case 2:
+ VerticalResolution = HorizontalResolution / 5 * 4;
+ break;
+ case 3:
+ VerticalResolution = HorizontalResolution / 16 * 9;
+ break;
+ default:
+ VerticalResolution = HorizontalResolution / 4 * 3;
+ break;
+ }
+
+ SupportedResolutions[Index + 17] = VerticalResolution |(HorizontalResolution << 16);
+ ValidNumber ++;
+ }
+ BufferIndex += 2;
+ }
+
+ if ( (EdidDataBlock->FeatureSupport & 2) == 2) {
+ // Preferred timing mode is indicated in the first detailed timing block
+ for (Index = 0; Index < 4; Index ++) {
+ if ((EdidDataBlock->DetailedTimingDescriptions[Index*18 + 0] |
+ EdidDataBlock->DetailedTimingDescriptions[Index*18 + 1]) &&
+ (EdidDataBlock->DetailedTimingDescriptions[Index*18 + 2] |
+ (EdidDataBlock->DetailedTimingDescriptions[Index*18 + 4] & 0xf0))) {
+
+ SupportedResolutions[Index + 25] =
+ (EdidDataBlock->DetailedTimingDescriptions[Index*18 + 5] | ((UINT16)(EdidDataBlock->DetailedTimingDescriptions[Index*18 + 7] & 0xF0) << 4))
+ | ((UINT32)(EdidDataBlock->DetailedTimingDescriptions[Index*18 + 2] | ((UINT16)(EdidDataBlock->DetailedTimingDescriptions[Index*18 + 4] & 0xF0) << 4)) << 16);
+
+TRACE((TRACE_BIOS_VIDEO, "EDID Detailed timing[%d]: inserted resolution 0x%x (%dx%d)\n", Index, SupportedResolutions[Index + 25],
+ EdidDataBlock->DetailedTimingDescriptions[Index*18 + 2] | ((EdidDataBlock->DetailedTimingDescriptions[Index*18 + 4] & 0xF0) << 4),
+ EdidDataBlock->DetailedTimingDescriptions[Index*18 + 5] | ((EdidDataBlock->DetailedTimingDescriptions[Index*18 + 7] & 0xF0) << 4)
+));
+
+ ValidNumber ++;
+ }
+ }
+ }
+
+//*** AMI PORTING BEGIN ***//
+// Bug fix. The function was returning TRUE even when no valid timings found.
+// return TRUE;
+ return (ValidNumber != 0);
+//*** AMI PORTING END ***//
+}
+
+STATIC
+BOOLEAN
+SearchEdidTiming (
+ UINT32 ResolutionKey
+ )
+/*++
+
+ Routine Description:
+
+ Search a specified Timing in all the valid EDID timings.
+
+ Arguments:
+
+ ValidEdidTiming - All valid EDID timing information.
+ EdidTiming - The Timing to search for.
+
+ Returns:
+
+ TRUE - Found.
+ FALSE - Not found.
+
+--*/
+{
+ UINT32 Index;
+ for (Index = 0; Index < 29; Index ++) {
+ if (ResolutionKey == SupportedResolutions[Index]) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//*** AMI PORTING BEGIN ***//
+#if CSM_VGA_64BITBAR_WORKAROUND
+BOOLEAN CheckAbove4g(PCI_TYPE00 *PciConfSpace){
+ UINTN i;
+//---------------------
+ for(i=0; i<PCI_MAX_BAR-1;i++){
+ //check all six bars if
+ if((PciConfSpace->Device.Bar[i] & 0x04) && ( PciConfSpace->Device.Bar[i+1]!=0) ) return TRUE;
+ }
+ return FALSE;
+}
+
+
+EFI_STATUS Update64BitLinearBufferAddr(EFI_PCI_IO_PROTOCOL *PciIo, UINT64 *LowerAddrPart, PCI_TYPE00 *PciConfSpace){
+ UINTN i,j;
+ EFI_STATUS Status;
+ ASLR_QWORD_ASD *BarRes=NULL;
+ UINT64 start, end, bar, test;
+ UINT32 *pUp32;
+//-----------------------------
+
+ //pBS->SetMem(&BarRes[0], sizeof(BarRes), 0);
+ //Get PciIo Bar ACPI QW Resource Descriptor and Count...
+
+ for(i=0; i<PCI_MAX_BAR; i++){
+ //Free Memory allocated for us by PciBus Driver...
+ //if we got here by continue statement...
+ if(BarRes!=NULL){
+ pBS->FreePool(BarRes);
+ BarRes=NULL;
+ }
+
+ Status = PciIo->GetBarAttributes(PciIo,(UINT8)i, NULL, &BarRes);
+ if(EFI_ERROR(Status)) return Status;
+
+ //care only about 64 bit resources end filter out Unused BARs and NOT64bit BARs
+ if(BarRes->Hdr.Name==ASLV_SR_EndTag) continue;
+ if(BarRes->_GRA < 64) continue;
+
+ start=BarRes->_MIN;
+ end=BarRes->_MAX;
+ test=*LowerAddrPart;
+
+ //Free Memory allocated for us by PciBus Driver...
+ if(BarRes!=NULL){
+ pBS->FreePool(BarRes);
+ BarRes=NULL;
+ }
+
+ //now try to match what we read from PCI Config to Res Descriptor returned by the call to PciIo...
+ for(j=0, bar=0; j<PCI_MAX_BAR-1;j++){
+ if(PciConfSpace->Device.Bar[j] & 0x04){
+ //here we got 64 bit BAR....
+ bar=PciConfSpace->Device.Bar[j] & (~0xF); //Mask read only Bar Type bits...
+ //fill Upper Part of BAR address
+ j++;
+ pUp32=((UINT32*)&bar)+1;
+ *pUp32=PciConfSpace->Device.Bar[j];
+ pUp32=((UINT32*)&test)+1;
+ *pUp32=PciConfSpace->Device.Bar[j];
+
+ //Check if we found match?
+ if(start==bar){
+ if((start <= test) && (test < end)) {
+ *LowerAddrPart=test;
+ return EFI_SUCCESS;
+ } else break;
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+#endif
+//*** AMI PORTING END *****//
+
+EFI_STATUS CheckForDuplicateMode (BIOS_VIDEO_DEV *VideoDev, UINTN ModeNumber)
+{
+ UINT16 Xres = VideoDev->VbeModeInformationBlock->XResolution;
+ UINT16 Yres = VideoDev->VbeModeInformationBlock->YResolution;
+ UINTN i;
+ BIOS_VIDEO_MODE_DATA *ModeData = VideoDev->ModeData;
+
+ // walk through the list of published modes, see if there is a match
+ for (i = 0; i < ModeNumber; i++)
+ {
+ if (ModeData->HorizontalResolution == Xres
+ && ModeData->VerticalResolution == Yres)
+ {
+ return EFI_SUCCESS;
+ }
+ ModeData++;
+ }
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS
+EFIAPI
+BiosVideoCheckForVbe (
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate,
+//*** AMI PORTING BEGIN ***//
+ PCI_TYPE00 *PciConfSpace
+//*** AMI PORTING END *****//
+ )
+/*++
+
+ Routine Description:
+
+ Check for VBE device
+
+ Arguments:
+
+ BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure
+
+ Returns:
+
+ EFI_SUCCESS - VBE device found
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET Regs;
+ UINT16 *ModeNumberPtr;
+ BOOLEAN ModeFound;
+ BOOLEAN EdidFound;
+ BOOLEAN EdidMatch;
+ BIOS_VIDEO_MODE_DATA *ModeBuffer;
+ BIOS_VIDEO_MODE_DATA *CurrentModeData;
+ UINTN PreferMode;
+ UINTN ModeNumber;
+ UINT32 ResolutionKey;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE *GraphicsOutputMode;
+ INT32 i;
+ EFI_EDID_OVERRIDE_PROTOCOL *EdidOverride;
+ UINT32 EdidAttributes;
+ BOOLEAN EdidOverrideFound;
+ UINTN EdidOverrideDataSize;
+ UINT8 *EdidOverrideDataBlock;
+ UINTN EdidActiveDataSize;
+ UINT8 *EdidActiveDataBlock;
+//*** AMI PORTING BEGIN ***//
+#if CSM_VGA_64BITBAR_WORKAROUND
+ BOOLEAN Above4g;
+#endif
+//*** AMI PORTING END *****//
+
+ EdidOverrideFound = FALSE;
+ EdidOverrideDataBlock = NULL;
+ EdidActiveDataSize = 0;
+ EdidActiveDataBlock = NULL;
+
+//*** AMI PORTING BEGIN ***//
+#if CSM_VGA_64BITBAR_WORKAROUND
+ Above4g=CheckAbove4g(PciConfSpace);
+#endif
+//*** AMI PORTING END *****//
+
+ //
+ // Allocate buffer under 1MB for VBE data structures
+ //
+ BiosVideoPrivate->NumberOfPagesBelow1MB = EFI_SIZE_TO_PAGES (
+ sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK) +
+ sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK) +
+ sizeof (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK) +
+ sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK)
+ );
+
+ BiosVideoPrivate->PagesBelow1MB = 0x00100000 - 1;
+
+ Status = gBS->AllocatePages (
+ AllocateMaxAddress,
+ EfiBootServicesData,
+ BiosVideoPrivate->NumberOfPagesBelow1MB,
+ &BiosVideoPrivate->PagesBelow1MB
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Fill in the Graphics Output Protocol
+ //
+ BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode;
+ BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode;
+ BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVbeBlt;
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL;
+
+ //
+ // Fill in the VBE related data structures
+ //
+ BiosVideoPrivate->VbeInformationBlock = (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *) (UINTN) (BiosVideoPrivate->PagesBelow1MB);
+ BiosVideoPrivate->VbeModeInformationBlock = (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeInformationBlock + 1);
+ BiosVideoPrivate->VbeEdidDataBlock = (VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1);
+ BiosVideoPrivate->VbeCrtcInformationBlock = (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *) (BiosVideoPrivate->VbeModeInformationBlock + 1);
+ BiosVideoPrivate->VbeSaveRestorePages = 0;
+ BiosVideoPrivate->VbeSaveRestoreBuffer = 0;
+
+ //
+ // Test to see if the Video Adapter is compliant with VBE 3.0
+ //
+ gBS->SetMem (&Regs, sizeof (Regs), 0);
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION;
+ gBS->SetMem (BiosVideoPrivate->VbeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK), 0);
+ BiosVideoPrivate->VbeInformationBlock->VESASignature = VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE;
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeInformationBlock);
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeInformationBlock);
+
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ // See if the VESA call succeeded
+ //
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {
+ return Status;
+ }
+ //
+ // Check for 'VESA' signature
+ //
+ if (BiosVideoPrivate->VbeInformationBlock->VESASignature != VESA_BIOS_EXTENSIONS_VESA_SIGNATURE) {
+ return Status;
+ }
+ //
+ // Check to see if this is VBE 2.0 or higher
+ //
+ if (BiosVideoPrivate->VbeInformationBlock->VESAVersion < VESA_BIOS_EXTENSIONS_VERSION_2_0) {
+ return Status;
+ }
+
+ EdidFound = FALSE;
+ EdidAttributes = 0xff;
+ EdidOverrideDataSize = 0;
+
+ //
+ // Check if EDID Override protocol is installed by platform.
+ //
+ Status = gBS->LocateProtocol (
+ &gEfiEdidOverrideProtocolGuid,
+ NULL,
+ (VOID **) &EdidOverride
+ );
+
+ if (!EFI_ERROR (Status)) {
+ //
+ // Allocate double size of VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE to avoid overflow
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof ((VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE * 2)),
+ &EdidOverrideDataBlock
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto Done;
+ }
+
+ Status = EdidOverride->GetEdid (
+ EdidOverride,
+ BiosVideoPrivate->Handle,
+ &EdidAttributes,
+ &EdidOverrideDataSize,
+ (UINT8 **) &EdidOverrideDataBlock
+ );
+ if (!EFI_ERROR (Status) &&
+//*** AMI PORTING BEGIN ***//
+// EdidAttributes == 0 &&
+//*** AMI PORTING END ***//
+ EdidOverrideDataSize != 0) {
+ //
+ // Succeeded to get EDID Override Data
+ //
+ TRACE((TRACE_BIOS_VIDEO, "EDID override protocol found: data size %x, attribute %x\n", EdidOverrideDataSize, EdidAttributes));
+ EdidOverrideFound = TRUE;
+ }
+ }
+
+
+ // "EdidFound" is forcibly FALSE,
+ // because some SSUs(Server Switch Unit) return invalid response.
+ if (!EdidOverrideFound || EdidAttributes == EFI_EDID_OVERRIDE_DONT_OVERRIDE) {
+ //
+ // If EDID Override data doesn't exist or EFI_EDID_OVERRIDE_DONT_OVERRIDE returned,
+ // read EDID information through INT10 call and fill in EdidDiscovered structure
+ //
+ gBS->SetMem (&Regs, sizeof (Regs), 0);
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_EDID;
+ Regs.X.BX = 1;
+ Regs.X.CX = 0;
+ Regs.X.DX = 0;
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeEdidDataBlock);
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeEdidDataBlock);
+
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+ if (Regs.X.AX == VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {
+
+ BiosVideoPrivate->EdidDiscovered.SizeOfEdid = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE,
+ &BiosVideoPrivate->EdidDiscovered.Edid
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ gBS->CopyMem (
+ BiosVideoPrivate->EdidDiscovered.Edid,
+ BiosVideoPrivate->VbeEdidDataBlock,
+ VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE
+ );
+
+ EdidFound = TRUE;
+ }
+ }
+
+ //
+ // Set up ActiveEdid data pointer and size
+ //
+ if (EdidFound) {
+ EdidActiveDataSize = VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE;
+ EdidActiveDataBlock = BiosVideoPrivate->EdidDiscovered.Edid;
+ } else if (EdidOverrideFound) {
+ EdidActiveDataSize = EdidOverrideDataSize;
+ EdidActiveDataBlock = EdidOverrideDataBlock;
+ EdidFound = TRUE;
+ }
+
+ if (EdidFound) {
+ //
+ // Parse EDID data structure to retrieve modes supported by monitor
+ //
+ if (ParseEdidData ((UINT8 *) EdidActiveDataBlock) == TRUE) {
+ //
+ // Copy EDID Override Data to EDID Active Data
+ //
+ BiosVideoPrivate->EdidActive.SizeOfEdid = (UINT32)EdidActiveDataSize;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ EdidActiveDataSize,
+ &BiosVideoPrivate->EdidActive.Edid
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ gBS->CopyMem (
+ BiosVideoPrivate->EdidActive.Edid,
+ EdidActiveDataBlock,
+ EdidActiveDataSize
+ );
+ }
+ } else {
+ BiosVideoPrivate->EdidActive.SizeOfEdid = 0;
+ BiosVideoPrivate->EdidActive.Edid = NULL;
+ EdidFound = FALSE;
+ }
+
+ //
+ // Walk through the mode list to see if there is at least one mode the is compatible with the EDID mode
+ //
+ ModeNumberPtr = (UINT16 *)
+ (
+ (((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0xffff0000) >> 12) |
+ ((UINTN) BiosVideoPrivate->VbeInformationBlock->VideoModePtr & 0x0000ffff)
+ );
+
+ PreferMode = 0;
+ ModeNumber = 0;
+
+ TRACE((TRACE_BIOS_VIDEO, "VESA: fetching the list of VESA modes supported by the controller from %x\n", ModeNumberPtr));
+
+ for (; *ModeNumberPtr != VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST; ModeNumberPtr++) {
+ //
+ // Make sure this is a mode number defined by the VESA VBE specification. If it isn'tm then skip this mode number.
+ //
+ TRACE((TRACE_BIOS_VIDEO,"VESA mode %x ", *ModeNumberPtr));
+
+ if ((*ModeNumberPtr & VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA) == 0) {
+ TRACE((TRACE_BIOS_VIDEO,".. skipping as it is not a proper VESA mode number\n"));
+ continue;
+ }
+
+ //
+ // Get the information about the mode
+ //
+ gBS->SetMem (&Regs, sizeof (Regs), 0);
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION;
+ Regs.X.CX = *ModeNumberPtr;
+ gBS->SetMem (BiosVideoPrivate->VbeModeInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK), 0);
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeModeInformationBlock);
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeModeInformationBlock);
+
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ //
+ // See if the call succeeded. If it didn't, then try the next mode.
+ //
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {
+ TRACE((TRACE_BIOS_VIDEO,".. skipping as we can not retrieve mode details\n"));
+ continue;
+ }
+
+ TRACE((TRACE_BIOS_VIDEO, "(%dx%d) ", BiosVideoPrivate->VbeModeInformationBlock->XResolution, BiosVideoPrivate->VbeModeInformationBlock->YResolution));
+
+ //
+ // See if the mode supported in hardware. If it doesn't then try the next mode.
+ //
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_HARDWARE) == 0) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as the mode is not supported in hardware...\n"));
+ continue;
+ }
+
+ //
+ // See if the mode supports color. If it doesn't then try the next mode.
+ //
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR) == 0) {
+ TRACE((TRACE_BIOS_VIDEO,"is invalid, skipping...\n"));
+ continue;
+ }
+ //
+ // See if the mode supports graphics. If it doesn't then try the next mode.
+ //
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS) == 0) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as the mode is not graphical...\n"));
+ continue;
+ }
+ //
+ // See if the mode supports a linear frame buffer. If it doesn't then try the next mode.
+ //
+ if ((BiosVideoPrivate->VbeModeInformationBlock->ModeAttributes & VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER) == 0) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as the mode has not linear frame buffer...\n"));
+ continue;
+ }
+ //
+ // See if the mode supports 32 bit color. If it doesn't then try the next mode.
+ // 32 bit mode can be implemented by 24 Bits Per Pixel. Also make sure the
+ // number of bits per pixel is a multiple of 8 or more than 32 bits per pixel
+ //
+ if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel < 24) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as BPP (%d) is less than 24...\n", BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel));
+ continue;
+ }
+
+ if (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel > 32) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as BPP (%d) is more than 32...\n", BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel));
+ continue;
+ }
+
+ if ((BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel % 8) != 0) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as BPP (%d) modulo 8 is non-zero...\n", BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel));
+ continue;
+ }
+ //
+ // See if the physical base pointer for the linear mode is valid. If it isn't then try the next mode.
+ //
+ if (BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr == 0) {
+ TRACE((TRACE_BIOS_VIDEO,"skipping as PhysBasePtr is zero...\n"));
+ continue;
+ }
+ EdidMatch = FALSE;
+ if (EdidFound) {
+ //
+ // EDID exist, check whether this mode match with any mode in EDID
+ //
+ ResolutionKey = BiosVideoPrivate->VbeModeInformationBlock->YResolution |
+ (BiosVideoPrivate->VbeModeInformationBlock->XResolution << 16);
+
+ if (SearchEdidTiming (ResolutionKey) == TRUE) {
+ EdidMatch = TRUE;
+ TRACE((TRACE_BIOS_VIDEO, "EDID match found.\n"));
+ }
+ }
+
+ //
+ // Select a reasonable mode to be set for current display mode
+ //
+ ModeFound = FALSE;
+
+ for(i = 0; i < MaxTextMode; i++)
+ {
+ if(TextModeArray[i].VideoCol == BiosVideoPrivate->VbeModeInformationBlock->XResolution &&
+ TextModeArray[i].VideoRow == BiosVideoPrivate->VbeModeInformationBlock->YResolution)
+ {
+ ModeFound = TRUE;
+ TRACE((TRACE_BIOS_VIDEO, "MODE match found (%d).\n", i));
+ }
+ }
+ if ((!EdidMatch) && (!ModeFound)) {
+ //
+ // When EDID exist and if the timing matches with VESA add it.
+ // And also add three possible resolutions, i.e. 1024x768, 800x600, 640x480
+ //
+ TRACE((TRACE_BIOS_VIDEO, "neither EDID nor MODE match is found.\n", i));
+ continue;
+ }
+
+ if (CheckForDuplicateMode(BiosVideoPrivate, ModeNumber) == EFI_SUCCESS)
+ {
+ TRACE((TRACE_BIOS_VIDEO, "skipping as the same resolution (%dx%d) is already available\n",
+ BiosVideoPrivate->VbeModeInformationBlock->XResolution,
+ BiosVideoPrivate->VbeModeInformationBlock->YResolution));
+ continue;
+ }
+
+ //
+ // Add mode to the list of available modes
+ //
+ ModeNumber ++;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ ModeNumber * sizeof (BIOS_VIDEO_MODE_DATA),
+ (VOID **) &ModeBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ if (ModeNumber > 1) {
+ gBS->CopyMem (
+ ModeBuffer,
+ BiosVideoPrivate->ModeData,
+ (ModeNumber - 1) * sizeof (BIOS_VIDEO_MODE_DATA)
+ );
+ }
+
+ if (BiosVideoPrivate->ModeData != NULL) {
+ gBS->FreePool (BiosVideoPrivate->ModeData);
+ BiosVideoPrivate->ModeData = NULL;
+ }
+
+ CurrentModeData = &ModeBuffer[ModeNumber - 1];
+ CurrentModeData->VbeModeNumber = *ModeNumberPtr;
+ if (BiosVideoPrivate->VbeInformationBlock->VESAVersion >= VESA_BIOS_EXTENSIONS_VERSION_3_0) {
+ CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->LinBytesPerScanLine;
+ CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRedFieldPosition;
+ CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRedMaskSize) - 1);
+ CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->LinBlueFieldPosition;
+ CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinBlueMaskSize) - 1);
+ CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->LinGreenFieldPosition;
+ CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinGreenMaskSize) - 1);
+ CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->LinRsvdFieldPosition;
+ CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->LinRsvdMaskSize) - 1);
+ } else {
+ CurrentModeData->BytesPerScanLine = BiosVideoPrivate->VbeModeInformationBlock->BytesPerScanLine;
+ CurrentModeData->Red.Position = BiosVideoPrivate->VbeModeInformationBlock->RedFieldPosition;
+ CurrentModeData->Red.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RedMaskSize) - 1);
+ CurrentModeData->Blue.Position = BiosVideoPrivate->VbeModeInformationBlock->BlueFieldPosition;
+ CurrentModeData->Blue.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->BlueMaskSize) - 1);
+ CurrentModeData->Green.Position = BiosVideoPrivate->VbeModeInformationBlock->GreenFieldPosition;
+ CurrentModeData->Green.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->GreenMaskSize) - 1);
+ CurrentModeData->Reserved.Position = BiosVideoPrivate->VbeModeInformationBlock->RsvdFieldPosition;
+ CurrentModeData->Reserved.Mask = (UINT8) ((1 << BiosVideoPrivate->VbeModeInformationBlock->RsvdMaskSize) - 1);
+ }
+//*** AMI PORTING BEGIN ***//
+//Bug fix: The original logic did not work for a modes with 24-bit pixels.
+// For a 24-bit pixels, the PixelFormat must be set to PixelBitMask, which
+// was not happening with the original "if" statement
+// if ((CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)) {
+ if ( (BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel == 32)
+ && (CurrentModeData->Red.Mask == 0xff) && (CurrentModeData->Green.Mask == 0xff) && (CurrentModeData->Blue.Mask == 0xff)
+ ) {
+//*** AMI PORTING END *****//
+ if ((CurrentModeData->Red.Position == 0) && (CurrentModeData->Green.Position == 8)) {
+ CurrentModeData->PixelFormat = PixelRedGreenBlueReserved8BitPerColor;
+ } else if ((CurrentModeData->Blue.Position == 0) && (CurrentModeData->Green.Position == 8)) {
+ CurrentModeData->PixelFormat = PixelBlueGreenRedReserved8BitPerColor;
+ }
+ } else {
+ CurrentModeData->PixelFormat = PixelBitMask;
+ }
+ CurrentModeData->PixelBitMask.RedMask = ((UINT32) CurrentModeData->Red.Mask) << CurrentModeData->Red.Position;
+ CurrentModeData->PixelBitMask.GreenMask = ((UINT32) CurrentModeData->Green.Mask) << CurrentModeData->Green.Position;
+ CurrentModeData->PixelBitMask.BlueMask = ((UINT32) CurrentModeData->Blue.Mask) << CurrentModeData->Blue.Position;
+ CurrentModeData->PixelBitMask.ReservedMask = ((UINT32) CurrentModeData->Reserved.Mask) << CurrentModeData->Reserved.Position;
+
+//*** AMI PORTING BEGIN ***//
+#if CSM_VGA_64BITBAR_WORKAROUND
+ if(Above4g){
+ UINT64 PhysBasePtr4g=BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;
+ //------------------------------------
+ Status=Update64BitLinearBufferAddr(BiosVideoPrivate->PciIo, &PhysBasePtr4g, PciConfSpace);
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)PhysBasePtr4g;
+ }else
+#endif
+ {
+ CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;
+ }
+ //CurrentModeData->LinearFrameBuffer = (VOID *) (UINTN)BiosVideoPrivate->VbeModeInformationBlock->PhysBasePtr;
+
+//*** AMI PORTING END *****//
+ CurrentModeData->HorizontalResolution = BiosVideoPrivate->VbeModeInformationBlock->XResolution;
+ CurrentModeData->VerticalResolution = BiosVideoPrivate->VbeModeInformationBlock->YResolution;
+
+ CurrentModeData->BitsPerPixel = BiosVideoPrivate->VbeModeInformationBlock->BitsPerPixel;
+
+//*** AMI PORTING BEGIN ***//
+// UEFI SCT 2.3.1 Summer Summit version reports that framebuffersize mismatch in query mode of SCT test
+// Calculated the framebuffersize based for each mode configuration
+ if(CurrentModeData->PixelFormat == PixelRedGreenBlueReserved8BitPerColor ||
+ CurrentModeData->PixelFormat == PixelBlueGreenRedReserved8BitPerColor) {
+ CurrentModeData->FrameBufferSize=((CurrentModeData->BytesPerScanLine * 8) / CurrentModeData->BitsPerPixel) *
+ CurrentModeData->VerticalResolution *
+ sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ } else {
+ CurrentModeData->FrameBufferSize = BiosVideoPrivate->VbeInformationBlock->TotalMemory * 64 * 1024;
+ }
+//*** AMI PORTING END *****//
+
+ CurrentModeData->RefreshRate = 60;
+
+ BiosVideoPrivate->ModeData = ModeBuffer;
+ }
+ //
+ // Check to see if we found any modes that are compatible with GRAPHICS OUTPUT
+ //
+ if (ModeNumber == 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto Done;
+ }
+
+ //
+ // Allocate buffer for Graphics Output Protocol mode information
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
+ (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ GraphicsOutputMode = BiosVideoPrivate->GraphicsOutput.Mode;
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ (VOID **) &GraphicsOutputMode->Info
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ GraphicsOutputMode->MaxMode = (UINT32) ModeNumber;
+ //
+ // Current mode is still unknown, set it to an invalid mode.
+ //
+ GraphicsOutputMode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
+ TRACE((TRACE_BIOS_VIDEO, "Total number of GOP modes: %d\n", ModeNumber));
+ //
+ // Find the best mode to initialize
+ //
+ Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, (UINT32) PreferMode);
+ if (EFI_ERROR (Status)) {
+ for (PreferMode = 0; PreferMode < ModeNumber; PreferMode ++) {
+ Status = BiosVideoGraphicsOutputSetMode (
+ &BiosVideoPrivate->GraphicsOutput,
+ (UINT32) PreferMode
+ );
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ if (PreferMode == ModeNumber) {
+ //
+ // None mode is set successfully.
+ //
+ goto Done;
+ }
+ }
+
+Done:
+ //
+ // If there was an error, then free the mode structure
+ //
+ if (EFI_ERROR (Status)) {
+ if (BiosVideoPrivate->ModeData != NULL) {
+ gBS->FreePool (BiosVideoPrivate->ModeData);
+ BiosVideoPrivate->ModeData = NULL;
+ }
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL;
+ }
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL;
+ }
+ }
+
+ return Status;
+}
+
+//*** AMI PORTING BEGIN ***//
+#endif//if INT10_VESA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+#if INT10_VGA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+EFI_STATUS
+EFIAPI
+BiosVideoCheckForVga (
+ IN OUT BIOS_VIDEO_DEV *BiosVideoPrivate
+ )
+/*++
+
+ Routine Description:
+
+ Check for VGA device
+
+ Arguments:
+
+ BiosVideoPrivate - Pointer to BIOS_VIDEO_DEV structure
+
+ Returns:
+
+ EFI_SUCCESS - Standard VGA device found
+
+--*/
+{
+ EFI_STATUS Status;
+ BIOS_VIDEO_MODE_DATA *ModeBuffer;
+
+ //
+ // Fill in the Graphics Output Protocol
+ //
+ BiosVideoPrivate->GraphicsOutput.QueryMode = BiosVideoGraphicsOutputQueryMode;
+ BiosVideoPrivate->GraphicsOutput.SetMode = BiosVideoGraphicsOutputSetMode;
+ BiosVideoPrivate->GraphicsOutput.Blt = BiosVideoGraphicsOutputVgaBlt;
+
+ //
+ // Allocate buffer for Graphics Output Protocol mode information
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_PROTOCOL_MODE),
+ (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ (VOID **) &BiosVideoPrivate->GraphicsOutput.Mode->Info
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Add mode to the list of available modes
+ //
+ BiosVideoPrivate->GraphicsOutput.Mode->MaxMode = 1;
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (BIOS_VIDEO_MODE_DATA),
+ (VOID **) &ModeBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ ModeBuffer->VbeModeNumber = 0x0012;
+ ModeBuffer->BytesPerScanLine = 640;
+ ModeBuffer->LinearFrameBuffer = (VOID *) (UINTN) (0xa0000);
+ ModeBuffer->FrameBufferSize = 0;
+ ModeBuffer->HorizontalResolution = 640;
+ ModeBuffer->VerticalResolution = 480;
+ ModeBuffer->RefreshRate = 60;
+ ModeBuffer->PixelFormat = PixelBltOnly;
+//*** AMI PORTING BEGIN ***//
+//Bug fix: initialize BitsPerPixel
+ ModeBuffer->BitsPerPixel = 4;
+//*** AMI PORTING END *****//
+
+ BiosVideoPrivate->ModeData = ModeBuffer;
+
+ //
+ // Test to see if the Video Adapter support the 640x480 16 color mode
+ //
+ BiosVideoPrivate->GraphicsOutput.Mode->Mode = GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER;
+ Status = BiosVideoGraphicsOutputSetMode (&BiosVideoPrivate->GraphicsOutput, 0);
+
+Done:
+ //
+ // If there was an error, then free the mode structure
+ //
+ if (EFI_ERROR (Status)) {
+ if (BiosVideoPrivate->ModeData != NULL) {
+ gBS->FreePool (BiosVideoPrivate->ModeData);
+ BiosVideoPrivate->ModeData = NULL;
+ }
+ if (BiosVideoPrivate->GraphicsOutput.Mode != NULL) {
+ if (BiosVideoPrivate->GraphicsOutput.Mode->Info != NULL) {
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode->Info);
+ BiosVideoPrivate->GraphicsOutput.Mode->Info = NULL;
+ }
+ gBS->FreePool (BiosVideoPrivate->GraphicsOutput.Mode);
+ BiosVideoPrivate->GraphicsOutput.Mode = NULL;
+ }
+ }
+ return Status;
+}
+//*** AMI PORTING BEGIN ***//
+#endif//if INT10_VGA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+
+//
+// Graphics Output Protocol Member Functions for VESA BIOS Extensions
+//
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputQueryMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to get video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to return information on.
+ Info - Caller allocated buffer that returns information about ModeNumber.
+ SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
+ EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+{
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ EFI_STATUS Status;
+ BIOS_VIDEO_MODE_DATA *ModeData;
+
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+ if (BiosVideoPrivate->HardwareNeedsStarting) {
+ ReportStatusCodeWithDevicePath (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_OUTPUT_ERROR,
+ 0,
+ &gEfiCallerIdGuid,
+ BiosVideoPrivate->DevicePath
+ );
+ return EFI_NOT_STARTED;
+ }
+
+ if (This == NULL || Info == NULL || SizeOfInfo == NULL || ModeNumber >= This->Mode->MaxMode) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION),
+ Info
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ *SizeOfInfo = sizeof (EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ ModeData = &BiosVideoPrivate->ModeData[ModeNumber];
+ (*Info)->Version = 0;
+ (*Info)->HorizontalResolution = ModeData->HorizontalResolution;
+ (*Info)->VerticalResolution = ModeData->VerticalResolution;
+ (*Info)->PixelFormat = ModeData->PixelFormat;
+ (*Info)->PixelInformation = ModeData->PixelBitMask;
+
+ (*Info)->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;
+
+ return EFI_SUCCESS;
+}
+
+//*** AMI PORTING BEGIN ***//
+// The AllocateTheBuffers function below and certain modifications of
+// the BiosVideoGraphicsOutputVbeBlt nd BiosVideoVgaMiniPortSetMode functions
+// are made to address the issues reaised in EIP 35682.
+//
+// The BLT function (BiosVideoGraphicsOutputVbeBlt) uses several memory buffers.
+// Default implementation allocates the buffers in the SetMode(BiosVideoVgaMiniPortSetMode)
+// function. We are changing implementation to allocate the buffers right in the BLT function
+// before the first use. The code that releases the buffers is still in the SetMode function.
+//
+// This is a workaround for the "UEFI Windows 7 Startup Repair" bug.
+// When Startup Repair option is selected, it crashes with the 0xc0000225 error prior
+// to the call to ExitBootServices.
+// The problem is caused by the Windows inability to handle memory map changes.
+// The memory map changes when Windows calls Gop->SetMode and our implementation of the
+// SetMode(BiosVideoGraphicsOutputVbeBlt) allocates the buffers.
+// This workaround moves buffer allocation to the BLT function (BiosVideoGraphicsOutputVbeBlt),
+// which Windows never calls and therefore memory map never changes.
+EFI_STATUS AllocateTheBuffers(BIOS_VIDEO_DEV *BiosVideoPrivate){
+ EFI_STATUS Status;
+ BIOS_VIDEO_MODE_DATA *ModeData;
+ UINT16 MaxBytesPerScanLine = 0;
+ UINT32 MaxVerticalResolution = 0;
+ UINT32 CurrentMode = (BiosVideoPrivate->GraphicsOutput).Mode->Mode;
+ UINT32 MaxMode = (BiosVideoPrivate->GraphicsOutput).Mode->MaxMode;
+ UINT32 Index;
+
+ TRACE((TRACE_BIOS_VIDEO, "UefiBiosVideo AllocateTheBuffers()\n"));
+ for(Index = 0; Index < MaxMode; Index++) {
+ ModeData = &BiosVideoPrivate->ModeData[Index];
+
+ if (MaxBytesPerScanLine < ModeData->BytesPerScanLine) {
+ MaxBytesPerScanLine = ModeData->BytesPerScanLine;
+ }
+ if (MaxVerticalResolution < ModeData->VerticalResolution) {
+ MaxVerticalResolution = ModeData->VerticalResolution;
+ }
+
+ TRACE((TRACE_BIOS_VIDEO, "VbeModeNumber: 0x%x\n", ModeData->VbeModeNumber));
+ TRACE((TRACE_BIOS_VIDEO, "BytesPerScanLine: 0x%x\n", \
+ ModeData->BytesPerScanLine));
+ TRACE((TRACE_BIOS_VIDEO, "HorizontalResolution: 0x%x\n", \
+ ModeData->HorizontalResolution));
+ TRACE((TRACE_BIOS_VIDEO, "VerticalResolution: 0x%x\n", \
+ ModeData->VerticalResolution));
+ }
+
+ TRACE((TRACE_BIOS_VIDEO, "MaxBytesPerScanLine: 0x%x\n", MaxBytesPerScanLine));
+ TRACE((TRACE_BIOS_VIDEO, "MaxVerticalResolution: 0x%x\n", \
+ MaxVerticalResolution));
+
+ ModeData = &BiosVideoPrivate->ModeData[CurrentMode];
+
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ MaxBytesPerScanLine,
+ &BiosVideoPrivate->LineBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ BiosVideoPrivate->LineBuffer=NULL;
+ return Status;
+ }
+ MemSet(BiosVideoPrivate->LineBuffer, MaxBytesPerScanLine, 0);
+
+ //
+ // Allocate a working buffer for BLT operations to the VGA frame buffer
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ 4 * 480 * 80,
+ &BiosVideoPrivate->VgaFrameBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);
+ BiosVideoPrivate->LineBuffer=NULL;
+ return Status;
+ }
+ MemSet(BiosVideoPrivate->VgaFrameBuffer, 4 * 480 * 80, 0);
+
+ //
+ // Allocate a working buffer for BLT operations to the VBE frame buffer
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ MaxBytesPerScanLine * MaxVerticalResolution,
+ &BiosVideoPrivate->VbeFrameBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);
+ BiosVideoPrivate->LineBuffer=NULL;
+ return Status;
+ }
+ MemSet(
+ BiosVideoPrivate->VbeFrameBuffer,
+ MaxBytesPerScanLine * MaxVerticalResolution,
+ 0
+ );
+
+ //
+ // Initialize the state of the VbeFrameBuffer
+ //
+ if (ModeData->VbeModeNumber >= 0x100) {
+ gBS->CopyMem (
+ BiosVideoPrivate->VbeFrameBuffer,
+ ModeData->LinearFrameBuffer,
+ (ModeData->BytesPerScanLine * ModeData->VerticalResolution));
+
+ }
+ return Status;
+}
+
+//*** AMI PORTING END *****//
+
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputSetMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
+ IN UINT32 ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to set video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to be set.
+
+ Returns:
+ EFI_SUCCESS - Graphics mode was changed.
+ EFI_DEVICE_ERROR - The device had an error and could not complete the request.
+ EFI_UNSUPPORTED - ModeNumber is not supported by this device.
+
+--*/
+{
+//*** AMI PORTING BEGIN ***//
+//Workaround for EIP 35682. See comments above
+//AllocateTheBuffers function for additional details.
+// EFI_STATUS Status;
+//*** AMI PORTING END *****//
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ EFI_IA32_REGISTER_SET Regs;
+ BIOS_VIDEO_MODE_DATA *ModeData;
+
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (ModeNumber >= This->Mode->MaxMode) {
+ return EFI_UNSUPPORTED;
+ }
+/*
+ if (ModeNumber == This->Mode->Mode) {
+ return EFI_SUCCESS;
+ }
+*/
+ ModeData = &BiosVideoPrivate->ModeData[ModeNumber];
+
+ if (BiosVideoPrivate->LineBuffer) {
+ gBS->FreePool (BiosVideoPrivate->LineBuffer);
+ BiosVideoPrivate->LineBuffer = NULL;
+ }
+
+ if (BiosVideoPrivate->VgaFrameBuffer) {
+ gBS->FreePool (BiosVideoPrivate->VgaFrameBuffer);
+ BiosVideoPrivate->VgaFrameBuffer = NULL;
+ }
+
+ if (BiosVideoPrivate->VbeFrameBuffer) {
+ gBS->FreePool (BiosVideoPrivate->VbeFrameBuffer);
+ BiosVideoPrivate->VbeFrameBuffer = NULL;
+ }
+
+ BiosVideoPrivate->LineBuffer = NULL;
+//*** AMI PORTING BEGIN ***//
+// Workaround for EIP 35682.
+// Buffer allocation code is moved to AllocateTheBuffers function,
+// which is called from the BiosVideoGraphicsOutputVbeBlt.
+// See comments above AllocateTheBuffers function for additional details.
+/*
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ ModeData->BytesPerScanLine,
+ &BiosVideoPrivate->LineBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+*/
+//*** AMI PORTING END *****//
+ //
+ // Clear all registers
+ //
+ gBS->SetMem (&Regs, sizeof (Regs), 0);
+
+ if (ModeData->VbeModeNumber < 0x100) {
+ //
+ // Allocate a working buffer for BLT operations to the VGA frame buffer
+ //
+ BiosVideoPrivate->VgaFrameBuffer = NULL;
+//*** AMI PORTING BEGIN ***//
+//*** AMI PORTING BEGIN ***//
+// Workaround for EIP 35682.
+// Buffer allocation code is moved to AllocateTheBuffers function,
+// which is called from the BiosVideoGraphicsOutputVbeBlt.
+// See comments above AllocateTheBuffers function for additional details.
+/*
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ 4 * 480 * 80,
+ &BiosVideoPrivate->VgaFrameBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+*/
+//*** AMI PORTING END *****//
+ //
+ // Set VGA Mode
+ //
+ Regs.X.AX = ModeData->VbeModeNumber;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ } else {
+ //
+ // Allocate a working buffer for BLT operations to the VBE frame buffer
+ //
+ BiosVideoPrivate->VbeFrameBuffer = NULL;
+//*** AMI PORTING BEGIN ***//
+//*** AMI PORTING BEGIN ***//
+// Workaround for EIP 35682.
+// Buffer allocation code is moved to AllocateTheBuffers function,
+// which is called from the BiosVideoGraphicsOutputVbeBlt.
+// See comments above AllocateTheBuffers function for additional details.
+/*
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ ModeData->BytesPerScanLine * ModeData->VerticalResolution,
+ &BiosVideoPrivate->VbeFrameBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+*/
+//*** AMI PORTING END *****//
+ //
+ // Set VBE mode
+ //
+ Regs.X.AX = VESA_BIOS_EXTENSIONS_SET_MODE;
+ Regs.X.BX = (UINT16) (ModeData->VbeModeNumber | VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER);
+ gBS->SetMem (BiosVideoPrivate->VbeCrtcInformationBlock, sizeof (VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK), 0);
+ Regs.X.ES = EFI_SEGMENT ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock);
+ Regs.X.DI = EFI_OFFSET ((UINTN) BiosVideoPrivate->VbeCrtcInformationBlock);
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ //
+ // Check to see if the call succeeded
+ //
+ if (Regs.X.AX != VESA_BIOS_EXTENSIONS_STATUS_SUCCESS) {
+ ReportStatusCodeWithDevicePath (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_OUTPUT_ERROR,
+ 0,
+ &gEfiCallerIdGuid,
+ BiosVideoPrivate->DevicePath
+ );
+ return EFI_DEVICE_ERROR;
+ }
+//*** AMI PORTING BEGIN ***//
+ //
+ // Initialize the state of the VbeFrameBuffer
+ //
+
+/*
+ Status = BiosVideoPrivate->PciIo->Mem.Read (
+ BiosVideoPrivate->PciIo,
+ EfiPciIoWidthUint32,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) (UINTN) ModeData->LinearFrameBuffer,
+ (ModeData->BytesPerScanLine * ModeData->VerticalResolution) >> 2,
+ BiosVideoPrivate->VbeFrameBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+*/
+// Workaround for EIP 35682.
+// Buffer allocation and initialization code is moved to AllocateTheBuffers function,
+// which is called from the BiosVideoGraphicsOutputVbeBlt.
+// See comments above AllocateTheBuffers function for additional details.
+/*
+ gBS->CopyMem (
+ BiosVideoPrivate->VbeFrameBuffer,
+ ModeData->LinearFrameBuffer,
+ (ModeData->BytesPerScanLine * ModeData->VerticalResolution));
+*/
+ }
+//*** AMI PORTING END ***//
+
+ This->Mode->Mode = ModeNumber;
+ This->Mode->Info->Version = 0;
+ This->Mode->Info->HorizontalResolution = ModeData->HorizontalResolution;
+ This->Mode->Info->VerticalResolution = ModeData->VerticalResolution;
+ This->Mode->Info->PixelFormat = ModeData->PixelFormat;
+ This->Mode->Info->PixelInformation = ModeData->PixelBitMask;
+ This->Mode->Info->PixelsPerScanLine = (ModeData->BytesPerScanLine * 8) / ModeData->BitsPerPixel;
+ This->Mode->SizeOfInfo = sizeof(EFI_GRAPHICS_OUTPUT_MODE_INFORMATION);
+
+ //
+ // Frame BufferSize remain unchanged
+ //
+ This->Mode->FrameBufferBase = (EFI_PHYSICAL_ADDRESS) ModeData->LinearFrameBuffer;
+ This->Mode->FrameBufferSize = ModeData->FrameBufferSize;
+
+ BiosVideoPrivate->HardwareNeedsStarting = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+//*** AMI PORTING BEGIN ***//
+#if INT10_VESA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+//
+// BUGBUG : Add Blt for 16 bit color, 15 bit color, and 8 bit color modes
+//
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputVbeBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol instance to block transfer for VBE device
+
+Arguments:
+
+ This - Pointer to Graphics Output protocol instance
+ BltBuffer - The data to transfer to screen
+ BltOperation - The operation to perform
+ SourceX - The X coordinate of the source for BltOperation
+ SourceY - The Y coordinate of the source for BltOperation
+ DestinationX - The X coordinate of the destination for BltOperation
+ DestinationY - The Y coordinate of the destination for BltOperation
+ Width - The width of a rectangle in the blt rectangle in pixels
+ Height - The height of a rectangle in the blt rectangle in pixels
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
+ If a subrectangle of the BltBuffer is used, then Delta represents
+ the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter passed in
+ EFI_SUCCESS - Blt operation success
+
+--*/
+{
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ BIOS_VIDEO_MODE_DATA *Mode;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_TPL OriginalTPL;
+ UINTN DstY;
+ UINTN SrcY;
+ UINTN DstX;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *Blt;
+ VOID *MemAddress;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;
+ UINTN BytesPerScanLine;
+ UINTN Index;
+ UINT8 *VbeBuffer;
+ UINT8 *VbeBuffer1;
+ UINT8 *BltUint8;
+ UINT32 VbePixelWidth;
+ UINT32 Pixel;
+
+//*** AMI PORTING BEGIN ***//
+//Bug fix: This is accessed before it's checked on NULL
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+//*** AMI PORTING END *****//
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);
+//*** AMI PORTING BEGIN ***//
+// Workaround for EIP 35682.
+// Allocate memory buffers during the first call of the funciton.
+// See comments above AllocateTheBuffers function for additional details.
+ if (BiosVideoPrivate->LineBuffer==NULL){
+ EFI_STATUS Status = AllocateTheBuffers(BiosVideoPrivate);
+ if (EFI_ERROR(Status)) return Status;
+ }
+//*** AMI PORTING END *****//
+ Mode = &BiosVideoPrivate->ModeData[This->Mode->Mode];
+ PciIo = BiosVideoPrivate->PciIo;
+
+ VbeFrameBuffer = BiosVideoPrivate->VbeFrameBuffer;
+ MemAddress = Mode->LinearFrameBuffer;
+ BytesPerScanLine = Mode->BytesPerScanLine;
+ VbePixelWidth = Mode->BitsPerPixel / 8;
+ BltUint8 = (UINT8 *) BltBuffer;
+
+//*** AMI PORTING BEGIN ***//
+//These parameter checks are moved to the beginning of the function
+/*
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+*/
+//*** AMI PORTING END *****//
+
+ if (Width == 0 || Height == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // We need to fill the Virtual Screen buffer with the blt data.
+ // The virtual screen is upside down, as the first row is the bootom row of
+ // the image.
+ //
+ if (BltOperation == EfiBltVideoToBltBuffer) {
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ if (SourceY + Height > Mode->VerticalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (SourceX + Width > Mode->HorizontalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ //
+ // BltBuffer to Video: Source is BltBuffer, destination is Video
+ //
+ if (DestinationY + Height > Mode->VerticalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DestinationX + Width > Mode->HorizontalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+ //
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+ // We would not want a timer based event (Cursor, ...) to come in while we are
+ // doing this operation.
+ //
+ OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ switch (BltOperation) {
+ case EfiBltVideoToBltBuffer:
+ for (SrcY = SourceY, DstY = DestinationY; DstY < (Height + DestinationY); SrcY++, DstY++) {
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + DstY * Delta + DestinationX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ //
+ // Shuffle the packed bytes in the hardware buffer to match EFI_GRAPHICS_OUTPUT_BLT_PIXEL
+ //
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (SrcY * BytesPerScanLine + SourceX * VbePixelWidth));
+ for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
+ Pixel = *(UINT32 *) (VbeBuffer);
+ Blt->Red = (UINT8) ((Pixel >> Mode->Red.Position) & Mode->Red.Mask);
+ Blt->Blue = (UINT8) ((Pixel >> Mode->Blue.Position) & Mode->Blue.Mask);
+ Blt->Green = (UINT8) ((Pixel >> Mode->Green.Position) & Mode->Green.Mask);
+ Blt->Reserved = 0;
+ Blt++;
+ VbeBuffer += VbePixelWidth;
+ }
+
+ }
+ break;
+
+ case EfiBltVideoToVideo:
+ for (Index = 0; Index < Height; Index++) {
+ if (DestinationY <= SourceY) {
+ SrcY = SourceY + Index;
+ DstY = DestinationY + Index;
+ } else {
+ SrcY = SourceY + Height - Index - 1;
+ DstY = DestinationY + Height - Index - 1;
+ }
+
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + DstY * BytesPerScanLine + DestinationX * VbePixelWidth);
+ VbeBuffer1 = ((UINT8 *) VbeFrameBuffer + SrcY * BytesPerScanLine + SourceX * VbePixelWidth);
+
+ gBS->CopyMem (
+ VbeBuffer,
+ VbeBuffer1,
+ Width * VbePixelWidth
+ );
+
+ if (VbePixelWidth == 4) {
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with CopyMem to optimize performance
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),
+ Width,
+ VbeBuffer
+ );
+*/
+ gBS->CopyMem ((UINT8*)MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth,
+ (UINT8*)VbeBuffer,
+ Width * VbePixelWidth);
+//*** AMI PORTING END *****//
+ } else {
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with CopyMem to optimize performance
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),
+ Width * VbePixelWidth,
+ VbeBuffer
+ );
+*/
+ gBS->CopyMem ((UINT8*)MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth,
+ (UINT8*)VbeBuffer,
+ Width * VbePixelWidth);
+ }
+//*** AMI PORTING END *****//
+ }
+ break;
+
+ case EfiBltVideoFill:
+ VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) BltUint8;
+ //
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer
+ //
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |
+ (
+ (Blt->Green & Mode->Green.Mask) <<
+ Mode->Green.Position
+ ) |
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);
+
+ for (Index = 0; Index < Width; Index++) {
+ gBS->CopyMem (
+ VbeBuffer,
+ &Pixel,
+ VbePixelWidth
+ );
+ VbeBuffer += VbePixelWidth;
+ }
+
+ VbeBuffer = (UINT8 *) ((UINTN) VbeFrameBuffer + (DestinationY * BytesPerScanLine) + DestinationX * VbePixelWidth);
+ for (DstY = DestinationY + 1; DstY < (Height + DestinationY); DstY++) {
+ gBS->CopyMem (
+ (VOID *) ((UINTN) VbeFrameBuffer + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),
+ VbeBuffer,
+ Width * VbePixelWidth
+ );
+ }
+
+ for (DstY = DestinationY; DstY < (Height + DestinationY); DstY++) {
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with CopyMem to optimize performance
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),
+ Width * VbePixelWidth,
+ VbeBuffer
+ );
+*/
+ gBS->CopyMem ((UINT8*)MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth,
+ (UINT8*)VbeBuffer,
+ Width * VbePixelWidth);
+//*** AMI PORTING END *****//
+ }
+ break;
+
+ case EfiBltBufferToVideo:
+//*** AMI PORTING BEGIN ***//
+//The original BLT loop is replaced to optimize performance by:
+// replacing PciIo->Mem.Write with CopyMem and
+// replacing multiplication with addition
+/*
+ for (SrcY = SourceY, DstY = DestinationY; SrcY < (Height + SourceY); SrcY++, DstY++) {
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *) (BltUint8 + (SrcY * Delta) + (SourceX) * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL));
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));
+ for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
+ //
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer
+ //
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |
+ ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) |
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);
+ gBS->CopyMem (
+ VbeBuffer,
+ &Pixel,
+ VbePixelWidth
+ );
+ Blt++;
+ VbeBuffer += VbePixelWidth;
+ }
+
+ VbeBuffer = ((UINT8 *) VbeFrameBuffer + (DstY * BytesPerScanLine + DestinationX * VbePixelWidth));
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) ((UINTN) MemAddress + (DstY * BytesPerScanLine) + DestinationX * VbePixelWidth),
+ Width * VbePixelWidth,
+ VbeBuffer
+ );
+ }
+*/
+{
+ UINTN VbeBufferOffset = DestinationY * BytesPerScanLine + DestinationX * VbePixelWidth;
+ UINT8* BltBufferAddress = BltUint8 + SourceY * Delta + SourceX * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ UINTN VbeLineWidth = VbePixelWidth*Width;
+ UINTN BufferOffset = VbeBufferOffset;
+
+ for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) {
+
+ VbeBuffer = (UINT8 *) VbeFrameBuffer + BufferOffset;
+
+ if (Mode->PixelFormat != PixelBlueGreenRedReserved8BitPerColor){
+ Blt = (EFI_GRAPHICS_OUTPUT_BLT_PIXEL *)BltBufferAddress;
+ for (DstX = DestinationX; DstX < (Width + DestinationX); DstX++) {
+ //
+ // Shuffle the RGB fields in EFI_GRAPHICS_OUTPUT_BLT_PIXEL to match the hardware buffer
+ //
+ Pixel = ((Blt->Red & Mode->Red.Mask) << Mode->Red.Position) |
+ ((Blt->Green & Mode->Green.Mask) << Mode->Green.Position) |
+ ((Blt->Blue & Mode->Blue.Mask) << Mode->Blue.Position);
+ gBS->CopyMem (
+ VbeBuffer,
+ &Pixel,
+ VbePixelWidth
+ );
+ Blt++;
+ VbeBuffer += VbePixelWidth;
+ }
+ VbeBuffer = (UINT8 *) VbeFrameBuffer + BufferOffset;
+ }else{
+ gBS->CopyMem (VbeBuffer, BltBufferAddress, VbeLineWidth);
+ }
+ BufferOffset += BytesPerScanLine;
+ BltBufferAddress += Delta;
+ }
+ BufferOffset = VbeBufferOffset;
+ for (SrcY = SourceY; SrcY < (Height + SourceY); SrcY++) {
+ gBS->CopyMem ((UINT8*)MemAddress + BufferOffset,
+ (UINT8 *)VbeFrameBuffer + BufferOffset,
+ VbeLineWidth);
+ BufferOffset += BytesPerScanLine;
+ }
+}
+//*** AMI PORTING END *****//
+ break;
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ return EFI_SUCCESS;
+}
+//*** AMI PORTING BEGIN ***//
+#endif //if INT10_VESA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+#if INT10_VGA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+STATIC
+VOID
+WriteGraphicsController (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINTN Address,
+ IN UINTN Data
+ )
+/*++
+
+Routine Description:
+
+ Write graphics controller registers
+
+Arguments:
+
+ PciIo - Pointer to PciIo protocol instance of the controller
+ Address - Register address
+ Data - Data to be written to register
+
+Returns:
+
+ None
+
+--*/
+{
+ Address = Address | (Data << 8);
+ PciIo->Io.Write (
+ PciIo,
+ EfiPciIoWidthUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER,
+ 1,
+ &Address
+ );
+}
+
+VOID
+VgaReadBitPlanes (
+ EFI_PCI_IO_PROTOCOL *PciIo,
+ UINT8 *HardwareBuffer,
+ UINT8 *MemoryBuffer,
+ UINTN WidthInBytes,
+ UINTN Height
+ )
+/*++
+
+Routine Description:
+
+ Read the four bit plane of VGA frame buffer
+
+Arguments:
+
+ PciIo - Pointer to PciIo protocol instance of the controller
+ HardwareBuffer - Hardware VGA frame buffer address
+ MemoryBuffer - Memory buffer address
+ WidthInBytes - Number of bytes in a line to read
+ Height - Height of the area to read
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN BitPlane;
+ UINTN Rows;
+ UINTN FrameBufferOffset;
+ UINT8 *Source;
+ UINT8 *Destination;
+
+ //
+ // Program the Mode Register Write mode 0, Read mode 0
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0
+ );
+
+ for (BitPlane = 0, FrameBufferOffset = 0;
+ BitPlane < VGA_NUMBER_OF_BIT_PLANES;
+ BitPlane++, FrameBufferOffset += VGA_BYTES_PER_BIT_PLANE
+ ) {
+ //
+ // Program the Read Map Select Register to select the correct bit plane
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER,
+ BitPlane
+ );
+
+ Source = HardwareBuffer;
+ Destination = MemoryBuffer + FrameBufferOffset;
+
+ for (Rows = 0; Rows < Height; Rows++, Source += VGA_BYTES_PER_SCAN_LINE, Destination += VGA_BYTES_PER_SCAN_LINE) {
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with CopyMem to optimize performance
+/*
+ PciIo->Mem.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Source,
+ WidthInBytes,
+ (VOID *) Destination
+ );
+*/
+ gBS->CopyMem ((UINT8*)Source,
+ (UINT8*)Destination,
+ WidthInBytes);
+//*** AMI PORTING END *****//
+ }
+ }
+}
+
+VOID
+VgaConvertToGraphicsOutputColor (
+ UINT8 *MemoryBuffer,
+ UINTN X,
+ UINTN Y,
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
+ )
+/*++
+
+Routine Description:
+
+ Internal routine to convert VGA color to Grahpics Output color
+
+Arguments:
+
+ MemoryBuffer - Buffer containing VGA color
+ X - The X coordinate of pixel on screen
+ Y - The Y coordinate of pixel on screen
+ BltBuffer - Buffer to contain converted Grahpics Output color
+
+Returns:
+
+ None
+
+--*/
+{
+ UINTN Mask;
+ UINTN Bit;
+ UINTN Color;
+
+ MemoryBuffer += ((Y << 6) + (Y << 4) + (X >> 3));
+ Mask = mVgaBitMaskTable[X & 0x07];
+ for (Bit = 0x01, Color = 0; Bit < 0x10; Bit <<= 1, MemoryBuffer += VGA_BYTES_PER_BIT_PLANE) {
+ if (*MemoryBuffer & Mask) {
+ Color |= Bit;
+ }
+ }
+
+ *BltBuffer = mVgaColorToGraphicsOutputColor[Color];
+}
+
+UINT8
+VgaConvertColor (
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer
+ )
+/*++
+
+Routine Description:
+
+ Internal routine to convert Grahpics Output color to VGA color
+
+Arguments:
+
+ BltBuffer - buffer containing Grahpics Output color
+
+Returns:
+
+ Converted VGA color
+
+--*/
+{
+ UINT8 Color;
+
+ Color = (UINT8) ((BltBuffer->Blue >> 7) | ((BltBuffer->Green >> 6) & 0x02) | ((BltBuffer->Red >> 5) & 0x04));
+//*** AMI PORTING BEGIN ***//
+// if ((BltBuffer->Red + BltBuffer->Green + BltBuffer->Blue) > 0x180) {
+ if ((BltBuffer->Red >= 0xC0) || (BltBuffer->Blue >= 0xC0) || (BltBuffer->Green >= 0xC0)) {
+ Color |= 0x08;
+ }
+ // Prevent "washing out" of single color
+ if (((BltBuffer->Red >= 0xC0) && (BltBuffer->Blue == 0) && (BltBuffer->Green == 0)) || \
+ ((BltBuffer->Blue >= 0xC0) && (BltBuffer->Red == 0) && (BltBuffer->Green == 0)) || \
+ ((BltBuffer->Green >= 0xC0) && (BltBuffer->Blue == 0) && (BltBuffer->Red == 0))) {
+ Color &= 0x07;
+ }
+//*** AMI PORTING END ***//
+
+ return Color;
+}
+
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputVgaBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+/*++
+
+Routine Description:
+
+ Grahpics Output protocol instance to block transfer for VGA device
+
+Arguments:
+
+ This - Pointer to Grahpics Output protocol instance
+ BltBuffer - The data to transfer to screen
+ BltOperation - The operation to perform
+ SourceX - The X coordinate of the source for BltOperation
+ SourceY - The Y coordinate of the source for BltOperation
+ DestinationX - The X coordinate of the destination for BltOperation
+ DestinationY - The Y coordinate of the destination for BltOperation
+ Width - The width of a rectangle in the blt rectangle in pixels
+ Height - The height of a rectangle in the blt rectangle in pixels
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
+ If a subrectangle of the BltBuffer is used, then Delta represents
+ the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter passed in
+ EFI_SUCCESS - Blt operation success
+
+--*/
+{
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ EFI_TPL OriginalTPL;
+ UINT8 *MemAddress;
+ UINTN BytesPerScanLine;
+ UINTN BytesPerBitPlane;
+ UINTN Bit;
+ UINTN Index;
+ UINTN Index1;
+ UINTN StartAddress;
+ UINTN Bytes;
+ UINTN Offset;
+ UINT8 LeftMask;
+ UINT8 RightMask;
+ UINTN Address;
+ UINTN AddressFix;
+ UINT8 *Address1;
+ UINT8 *SourceAddress;
+ UINT8 *DestinationAddress;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 Data;
+ UINT8 PixelColor;
+ UINT8 *VgaFrameBuffer;
+ UINTN SourceOffset;
+ UINTN SourceWidth;
+ UINTN Rows;
+ UINTN Columns;
+ UINTN X;
+ UINTN Y;
+ UINTN CurrentMode;
+
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS (This);
+
+//*** AMI PORTING BEGIN ***//
+// Workaround for EIP 35682.
+// Allocate memory buffers during the first call of the funciton.
+// See comments above AllocateTheBuffers function for additional details.
+ if (BiosVideoPrivate->LineBuffer==NULL){
+ EFI_STATUS Status = AllocateTheBuffers(BiosVideoPrivate);
+ if (EFI_ERROR(Status)) return Status;
+ }
+//*** AMI PORTING END *****//
+
+ CurrentMode = This->Mode->Mode;
+ PciIo = BiosVideoPrivate->PciIo;
+ MemAddress = BiosVideoPrivate->ModeData[CurrentMode].LinearFrameBuffer;
+ BytesPerScanLine = BiosVideoPrivate->ModeData[CurrentMode].BytesPerScanLine >> 3;
+ BytesPerBitPlane = BytesPerScanLine * BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution;
+ VgaFrameBuffer = BiosVideoPrivate->VgaFrameBuffer;
+
+ if (This == NULL || ((UINTN) BltOperation) >= EfiGraphicsOutputBltOperationMax) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Width == 0 || Height == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // We need to fill the Virtual Screen buffer with the blt data.
+ // The virtual screen is upside down, as the first row is the bootom row of
+ // the image.
+ //
+ if (BltOperation == EfiBltVideoToBltBuffer) {
+ //
+ // Video to BltBuffer: Source is Video, destination is BltBuffer
+ //
+ if (SourceY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (SourceX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+ } else {
+ //
+ // BltBuffer to Video: Source is BltBuffer, destination is Video
+ //
+ if (DestinationY + Height > BiosVideoPrivate->ModeData[CurrentMode].VerticalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DestinationX + Width > BiosVideoPrivate->ModeData[CurrentMode].HorizontalResolution) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // If Delta is zero, then the entire BltBuffer is being used, so Delta
+ // is the number of bytes in each row of BltBuffer. Since BltBuffer is Width pixels size,
+ // the number of bytes in each row can be computed.
+ //
+ if (Delta == 0) {
+ Delta = Width * sizeof (EFI_GRAPHICS_OUTPUT_BLT_PIXEL);
+ }
+ //
+ // We have to raise to TPL Notify, so we make an atomic write the frame buffer.
+ // We would not want a timer based event (Cursor, ...) to come in while we are
+ // doing this operation.
+ //
+ OriginalTPL = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+
+ //
+ // Compute some values we need for VGA
+ //
+ switch (BltOperation) {
+ case EfiBltVideoToBltBuffer:
+
+ SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3);
+ SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1;
+
+ //
+ // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer
+ //
+ VgaReadBitPlanes (
+ PciIo,
+ MemAddress + SourceOffset,
+ VgaFrameBuffer + SourceOffset,
+ SourceWidth,
+ Height
+ );
+
+ //
+ // Convert VGA Bit Planes to a Graphics Output 32-bit color value
+ //
+ BltBuffer += (DestinationY * (Delta >> 2) + DestinationX);
+ for (Rows = 0, Y = SourceY; Rows < Height; Rows++, Y++, BltBuffer += (Delta >> 2)) {
+ for (Columns = 0, X = SourceX; Columns < Width; Columns++, X++, BltBuffer++) {
+ VgaConvertToGraphicsOutputColor (VgaFrameBuffer, X, Y, BltBuffer);
+ }
+
+ BltBuffer -= Width;
+ }
+
+ break;
+
+ case EfiBltVideoToVideo:
+ //
+ // Check for an aligned Video to Video operation
+ //
+ if ((SourceX & 0x07) == 0x00 && (DestinationX & 0x07) == 0x00 && (Width & 0x07) == 0x00) {
+ //
+ // Program the Mode Register Write mode 1, Read mode 0
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1
+ );
+
+ SourceAddress = (UINT8 *) (MemAddress + (SourceY << 6) + (SourceY << 4) + (SourceX >> 3));
+ DestinationAddress = (UINT8 *) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));
+ Bytes = Width >> 3;
+ for (Index = 0, Offset = 0; Index < Height; Index++, Offset += BytesPerScanLine) {
+ PciIo->CopyMem (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) (DestinationAddress + Offset),
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) (SourceAddress + Offset),
+ Bytes
+ );
+ }
+ } else {
+ SourceOffset = (SourceY << 6) + (SourceY << 4) + (SourceX >> 3);
+ SourceWidth = ((SourceX + Width - 1) >> 3) - (SourceX >> 3) + 1;
+
+ //
+ // Read all the pixels in the 4 bit planes into a memory buffer that looks like the VGA buffer
+ //
+ VgaReadBitPlanes (
+ PciIo,
+ MemAddress + SourceOffset,
+ VgaFrameBuffer + SourceOffset,
+ SourceWidth,
+ Height
+ );
+ }
+
+ break;
+
+ case EfiBltVideoFill:
+ StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));
+ Bytes = ((DestinationX + Width - 1) >> 3) - (DestinationX >> 3);
+ LeftMask = mVgaLeftMaskTable[DestinationX & 0x07];
+ RightMask = mVgaRightMaskTable[(DestinationX + Width - 1) & 0x07];
+ if (Bytes == 0) {
+ LeftMask &= RightMask;
+ RightMask = 0;
+ }
+
+ if (LeftMask == 0xff) {
+ StartAddress--;
+ Bytes++;
+ LeftMask = 0;
+ }
+
+ if (RightMask == 0xff) {
+ Bytes++;
+ RightMask = 0;
+ }
+
+ PixelColor = VgaConvertColor (BltBuffer);
+
+ //
+ // Program the Mode Register Write mode 2, Read mode 0
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2
+ );
+
+ //
+ // Program the Data Rotate/Function Select Register to replace
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,
+ VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE
+ );
+
+ if (LeftMask != 0) {
+ //
+ // Program the BitMask register with the Left column mask
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,
+ LeftMask
+ );
+
+ for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) {
+ //
+ // Read data from the bit planes into the latches
+ //
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with direct memory access to optimize performance
+/*
+ PciIo->Mem.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address,
+ 1,
+ &Data
+ );
+*/
+ Data = *(volatile UINT8*)(UINTN)Address;
+//*** AMI PORTING END *****//
+ //
+ // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask
+ //
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with direct memory access to optimize performance
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address,
+ 1,
+ &PixelColor
+ );
+*/
+ *(volatile UINT8*)(UINTN)Address = PixelColor;
+//*** AMI PORTING END *****//
+ }
+ }
+
+ if (Bytes > 1) {
+ //
+ // Program the BitMask register with the middle column mask of 0xff
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,
+ 0xff
+ );
+
+ for (Index = 0, Address = StartAddress + 1; Index < Height; Index++, Address += BytesPerScanLine) {
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with SetMem to optimize performance
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthFillUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address,
+ Bytes - 1,
+ &PixelColor
+ );
+*/
+ gBS->SetMem((VOID*)Address, Bytes - 1, PixelColor);
+//*** AMI PORTING END ***//
+ }
+ }
+
+ if (RightMask != 0) {
+ //
+ // Program the BitMask register with the Right column mask
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,
+ RightMask
+ );
+
+ for (Index = 0, Address = StartAddress + Bytes; Index < Height; Index++, Address += BytesPerScanLine) {
+ //
+ // Read data from the bit planes into the latches
+ //
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with direct memory access to optimize performance
+/*
+ PciIo->Mem.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address,
+ 1,
+ &Data
+ );
+*/
+ Data = *(volatile UINT8*)(UINTN)Address;
+//*** AMI PORTING END *****//
+ //
+ // Write the lower 4 bits of PixelColor to the bit planes in the pixels enabled by BitMask
+ //
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with direct memory access to optimize performance
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address,
+ 1,
+ &PixelColor
+ );
+*/
+ *(volatile UINT8*)(UINTN)Address = PixelColor;
+//*** AMI PORTING END *****//
+ }
+ }
+ break;
+
+ case EfiBltBufferToVideo:
+ StartAddress = (UINTN) (MemAddress + (DestinationY << 6) + (DestinationY << 4) + (DestinationX >> 3));
+ LeftMask = mVgaBitMaskTable[DestinationX & 0x07];
+
+ //
+ // Program the Mode Register Write mode 2, Read mode 0
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_MODE_REGISTER,
+ VGA_GRAPHICS_CONTROLLER_READ_MODE_0 | VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2
+ );
+
+ //
+ // Program the Data Rotate/Function Select Register to replace
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER,
+ VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE
+ );
+
+ for (Index = 0, Address = StartAddress; Index < Height; Index++, Address += BytesPerScanLine) {
+ for (Index1 = 0; Index1 < Width; Index1++) {
+ BiosVideoPrivate->LineBuffer[Index1] = VgaConvertColor (&BltBuffer[(SourceY + Index) * (Delta >> 2) + SourceX + Index1]);
+ }
+ AddressFix = Address;
+
+ for (Bit = 0; Bit < 8; Bit++) {
+ //
+ // Program the BitMask register with the Left column mask
+ //
+ WriteGraphicsController (
+ PciIo,
+ VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER,
+ LeftMask
+ );
+
+ for (Index1 = Bit, Address1 = (UINT8 *) AddressFix; Index1 < Width; Index1 += 8, Address1++) {
+ //
+ // Read data from the bit planes into the latches
+ //
+//*** AMI PORTING BEGIN ***//
+// Replace PciIo.Mem with direct memory access to optimize performance
+/*
+ PciIo->Mem.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address1,
+ 1,
+ &Data
+ );
+*/
+ Data = *(volatile UINT8*)(UINTN)Address1;
+
+/*
+ PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ (UINT64) Address1,
+ 1,
+ &BiosVideoPrivate->LineBuffer[Index1]
+ );
+*/
+ *(volatile UINT8*)(UINTN)Address1 = BiosVideoPrivate->LineBuffer[Index1];
+//*** AMI PORTING END *****//
+ }
+
+ LeftMask = (UINT8) (LeftMask >> 1);
+ if (LeftMask == 0) {
+ LeftMask = 0x80;
+ AddressFix++;
+ }
+ }
+ }
+
+ break;
+ }
+
+ gBS->RestoreTPL (OriginalTPL);
+
+ return EFI_SUCCESS;
+}
+//*** AMI PORTING BEGIN ***//
+#endif //if INT10_VGA_GO_SUPPORT==1
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+#if INT10_SIMPLE_TEXT_SUPPORT==1
+//*** AMI PORTING END *****//
+//
+// VGA Mini Port Protocol Functions
+//
+EFI_STATUS
+EFIAPI
+BiosVideoVgaMiniPortSetMode (
+ IN EFI_VGA_MINI_PORT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ VgaMiniPort protocol interface to set mode
+
+Arguments:
+
+ This - Pointer to VgaMiniPort protocol instance
+ ModeNumber - The index of the mode
+
+Returns:
+
+ EFI_UNSUPPORTED - The requested mode is not supported
+ EFI_SUCCESS - The requested mode is set successfully
+
+--*/
+{
+ BIOS_VIDEO_DEV *BiosVideoPrivate;
+ EFI_IA32_REGISTER_SET Regs;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Make sure the ModeNumber is a valid value
+ //
+ if (ModeNumber >= This->MaxMode) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Get the device structure for this device
+ //
+ BiosVideoPrivate = BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS (This);
+
+ switch (ModeNumber) {
+ case 0:
+ //
+ // Set the 80x25 Text VGA Mode
+ //
+ Regs.H.AH = 0x00;
+ Regs.H.AL = 0x83;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+
+ Regs.H.AH = 0x11;
+ Regs.H.AL = 0x14;
+ Regs.H.BL = 0;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+ break;
+
+ case 1:
+ //
+ // Set the 80x50 Text VGA Mode
+ //
+ Regs.H.AH = 0x00;
+ Regs.H.AL = 0x83;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+ Regs.H.AH = 0x11;
+ Regs.H.AL = 0x12;
+ Regs.H.BL = 0;
+ BiosVideoPrivate->LegacyBios->Int86 (BiosVideoPrivate->LegacyBios, 0x10, &Regs);
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+//*** AMI PORTING BEGIN ***//
+#endif //if INT10_SIMPLE_TEXT_SUPPORT==1
+//*** AMI PORTING END *****//
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h
new file mode 100644
index 0000000..9421b5e
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/UefiBiosVideo.h
@@ -0,0 +1,597 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//
+// This file contains a 'Sample Driver' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may be modified by the user, subject to
+// the additional terms of the license agreement
+//
+/*++
+
+Copyright (c) 2006 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ UefiBiosVideo.h
+
+Abstract:
+
+Revision History
+--*/
+
+#ifndef _BIOS_GRAPHICS_OUTPUT_H
+#define _BIOS_GRAPHICS_OUTPUT_H
+
+//*** AMI PORTING BEGIN ***//
+#include "AmiMapping.h"
+#include "EdkIICommon.h"
+//#include "Tiano.h"
+//#include "EfiDriverLib.h"
+#include <Protocol/CsmVideoPolicy.h>
+//*** AMI PORTING END *****//
+#include "VesaBiosExtensions.h"
+#include "Pci22.h"
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION (DevicePath)
+#include EFI_PROTOCOL_DEFINITION (PciIo)
+#include EFI_PROTOCOL_DEFINITION (LegacyBios)
+//*** AMI PORTING BEGIN ***//
+//AMI CSM Core does not need this GUID
+//#include EFI_GUID_DEFINITION (LegacyBios)
+//*** AMI PORTING END *****//
+//*** AMI PORTING BEGIN ***//
+//#include EFI_GUID_DEFINITION (StatusCodeCallerId)
+//#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+//*** AMI PORTING END *****//
+
+//
+// Driver Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION (DriverBinding)
+#include EFI_PROTOCOL_DEFINITION (ComponentName)
+#include EFI_PROTOCOL_DEFINITION (GraphicsOutput)
+#include EFI_PROTOCOL_DEFINITION (EdidDiscovered)
+#include EFI_PROTOCOL_DEFINITION (EdidActive)
+
+//*** AMI PORTING BEGIN ***//
+//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort)
+#include "VgaMiniPort.h"
+
+// uncomment the following lind and remove the following block when Protocol/EdidOverride.h is available
+//#include EFI_PROTOCOL_DEFINITION (EdidOverride)
+#define EFI_EDID_OVERRIDE_PROTOCOL_GUID \
+ { 0x48ecb431, 0xfb72, 0x45c0, 0xa9, 0x22, 0xf4, 0x58, 0xfe, 0x4, 0xb, 0xd5 }
+
+#define EFI_EDID_OVERRIDE_DONT_OVERRIDE 0x01
+#define EFI_EDID_OVERRIDE_ENABLE_HOT_PLUG 0x02
+
+typedef struct _EFI_EDID_OVERRIDE_PROTOCOL EFI_EDID_OVERRIDE_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID) (
+ IN EFI_EDID_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE *ChildHandle,
+ OUT UINT32 *Attributes,
+ IN OUT UINTN *EdidSize,
+ IN OUT UINT8 **Edid
+ );
+
+struct _EFI_EDID_OVERRIDE_PROTOCOL {
+ EFI_EDID_OVERRIDE_PROTOCOL_GET_EDID GetEdid;
+};
+//*** AMI PORTING END *****//
+
+//
+// Packed format support: The number of bits reserved for each of the colors and the actual
+// position of RGB in the frame buffer is specified in the VBE Mode information
+//
+typedef struct {
+ UINT8 Position; // Position of the color
+ UINT8 Mask; // The number of bits expressed as a mask
+} BIOS_VIDEO_COLOR_PLACEMENT;
+
+//
+// BIOS Graphics Output Graphical Mode Data
+//
+typedef struct {
+ UINT16 VbeModeNumber;
+ UINT16 BytesPerScanLine;
+ VOID *LinearFrameBuffer;
+ UINTN FrameBufferSize;
+ UINT32 HorizontalResolution;
+ UINT32 VerticalResolution;
+ UINT32 RefreshRate;
+ UINT32 BitsPerPixel;
+ BIOS_VIDEO_COLOR_PLACEMENT Red;
+ BIOS_VIDEO_COLOR_PLACEMENT Green;
+ BIOS_VIDEO_COLOR_PLACEMENT Blue;
+ BIOS_VIDEO_COLOR_PLACEMENT Reserved;
+ EFI_GRAPHICS_PIXEL_FORMAT PixelFormat;
+ EFI_PIXEL_BITMASK PixelBitMask;
+} BIOS_VIDEO_MODE_DATA;
+
+//
+// BIOS video child handle private data Structure
+//
+#define BIOS_VIDEO_DEV_SIGNATURE EFI_SIGNATURE_32 ('B', 'V', 'M', 'p')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+
+ //
+ // Consumed Protocols
+ //
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+
+ //
+ // Produced Protocols
+ //
+ EFI_GRAPHICS_OUTPUT_PROTOCOL GraphicsOutput;
+ EFI_EDID_DISCOVERED_PROTOCOL EdidDiscovered;
+ EFI_EDID_ACTIVE_PROTOCOL EdidActive;
+ EFI_VGA_MINI_PORT_PROTOCOL VgaMiniPort;
+
+ //
+ // General fields
+ //
+ BOOLEAN VgaCompatible;
+ BOOLEAN ProduceGraphicsOutput;
+//*** AMI PORTING BEGIN ***//
+// ExitBootServicesEvent is not used
+// EFI_EVENT ExitBootServicesEvent;
+//*** AMI PORTING END *****//
+
+ //
+ // Graphics Output Protocol related fields
+ //
+ BOOLEAN HardwareNeedsStarting;
+ BIOS_VIDEO_MODE_DATA *ModeData;
+ UINT8 *LineBuffer;
+ EFI_GRAPHICS_OUTPUT_BLT_PIXEL *VbeFrameBuffer;
+ UINT8 *VgaFrameBuffer;
+
+ //
+ // VESA Bios Extensions related fields
+ //
+ UINTN NumberOfPagesBelow1MB; // Number of 4KB pages in PagesBelow1MB
+ EFI_PHYSICAL_ADDRESS PagesBelow1MB; // Buffer for all VBE Information Blocks
+ VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK *VbeInformationBlock; // 0x200 bytes. Must be allocated below 1MB
+ VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK *VbeModeInformationBlock; // 0x100 bytes. Must be allocated below 1MB
+ VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK *VbeEdidDataBlock; // 0x80 bytes. Must be allocated below 1MB
+ VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK *VbeCrtcInformationBlock; // 59 bytes. Must be allocated below 1MB
+ UINTN VbeSaveRestorePages; // Number of 4KB pages in VbeSaveRestoreBuffer
+ EFI_PHYSICAL_ADDRESS VbeSaveRestoreBuffer; // Must be allocated below 1MB
+ //
+ // Status code
+ //
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+} BIOS_VIDEO_DEV;
+
+#define BIOS_VIDEO_DEV_FROM_PCI_IO_THIS(a) CR (a, BIOS_VIDEO_DEV, PciIo, BIOS_VIDEO_DEV_SIGNATURE)
+#define BIOS_VIDEO_DEV_FROM_GRAPHICS_OUTPUT_THIS(a) CR (a, BIOS_VIDEO_DEV, GraphicsOutput, BIOS_VIDEO_DEV_SIGNATURE)
+#define BIOS_VIDEO_DEV_FROM_VGA_MINI_PORT_THIS(a) CR (a, BIOS_VIDEO_DEV, VgaMiniPort, BIOS_VIDEO_DEV_SIGNATURE)
+
+#define GRAPHICS_OUTPUT_INVALIDE_MODE_NUMBER 0xffff
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gBiosVideoDriverBinding;
+extern EFI_COMPONENT_NAME_PROTOCOL gBiosVideoComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gBiosVideoComponentName2;
+
+//
+// Driver Binding Protocol functions
+//
+EFI_STATUS
+EFIAPI
+BiosVideoDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Controller - GC_TODO: add argument description
+ RemainingDevicePath - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+BiosVideoDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Controller - GC_TODO: add argument description
+ RemainingDevicePath - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+BiosVideoDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Controller - GC_TODO: add argument description
+ NumberOfChildren - GC_TODO: add argument description
+ ChildHandleBuffer - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+//
+// Private worker functions
+//
+EFI_STATUS
+BiosVideoCheckForVbe (
+ BIOS_VIDEO_DEV *BiosVideoPrivate,
+//*** AMI PORTING BEGIN ***//
+ PCI_TYPE00 *PciConfSpace
+//*** AMI PORTING END *****//
+)
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ BiosVideoPrivate - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+BiosVideoCheckForVga (
+ BIOS_VIDEO_DEV *BiosVideoPrivate
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ BiosVideoPrivate - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+STATIC
+EFI_STATUS
+DeRegisterVideoChildHandle (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_HANDLE Handle
+ )
+/*++
+
+Routine Description:
+
+ Deregister an video child handle and free resources
+
+Arguments:
+
+ This - Protocol instance pointer.
+ Controller - Video controller handle
+ Handle - Video child handle
+
+Returns:
+
+ EFI_STATUS
+
+--*/
+;
+
+VOID
+BiosVideoDeviceReleaseResource (
+ BIOS_VIDEO_DEV *BiosVideoChildPrivate
+ )
+/*++
+Routing Description:
+
+ Release resources of a video child device before stopping it.
+
+Arguments:
+
+ BiosVideoChildPrivate - Video child device private data structure
+
+Returns:
+
+ NONE
+
+---*/
+;
+
+//
+// BIOS Graphics Output Protocol functions
+//
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputQueryMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN UINT32 ModeNumber,
+ OUT UINTN *SizeOfInfo,
+ OUT EFI_GRAPHICS_OUTPUT_MODE_INFORMATION **Info
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to get video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to return information on.
+ Info - Caller allocated buffer that returns information about ModeNumber.
+ SizeOfInfo - A pointer to the size, in bytes, of the Info buffer.
+
+ Returns:
+ EFI_SUCCESS - Mode information returned.
+ EFI_BUFFER_TOO_SMALL - The Info buffer was too small.
+ EFI_DEVICE_ERROR - A hardware error occurred trying to retrieve the video mode.
+ EFI_NOT_STARTED - Video display is not initialized. Call SetMode ()
+ EFI_INVALID_PARAMETER - One of the input args was NULL.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputSetMode (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL * This,
+ IN UINT32 ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol interface to set video mode
+
+ Arguments:
+ This - Protocol instance pointer.
+ ModeNumber - The mode number to be set.
+
+ Returns:
+ EFI_SUCCESS - Graphics mode was changed.
+ EFI_DEVICE_ERROR - The device had an error and could not complete the request.
+ EFI_UNSUPPORTED - ModeNumber is not supported by this device.
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputVbeBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+/*++
+
+Routine Description:
+
+ Graphics Output protocol instance to block transfer for VBE device
+
+Arguments:
+
+ This - Pointer to Graphics Output protocol instance
+ BltBuffer - The data to transfer to screen
+ BltOperation - The operation to perform
+ SourceX - The X coordinate of the source for BltOperation
+ SourceY - The Y coordinate of the source for BltOperation
+ DestinationX - The X coordinate of the destination for BltOperation
+ DestinationY - The Y coordinate of the destination for BltOperation
+ Width - The width of a rectangle in the blt rectangle in pixels
+ Height - The height of a rectangle in the blt rectangle in pixels
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
+ If a subrectangle of the BltBuffer is used, then Delta represents
+ the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter passed in
+ EFI_SUCCESS - Blt operation success
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+BiosVideoGraphicsOutputVgaBlt (
+ IN EFI_GRAPHICS_OUTPUT_PROTOCOL *This,
+ IN EFI_GRAPHICS_OUTPUT_BLT_PIXEL *BltBuffer, OPTIONAL
+ IN EFI_GRAPHICS_OUTPUT_BLT_OPERATION BltOperation,
+ IN UINTN SourceX,
+ IN UINTN SourceY,
+ IN UINTN DestinationX,
+ IN UINTN DestinationY,
+ IN UINTN Width,
+ IN UINTN Height,
+ IN UINTN Delta
+ )
+/*++
+
+Routine Description:
+
+ Grahpics Output protocol instance to block transfer for VGA device
+
+Arguments:
+
+ This - Pointer to Grahpics Output protocol instance
+ BltBuffer - The data to transfer to screen
+ BltOperation - The operation to perform
+ SourceX - The X coordinate of the source for BltOperation
+ SourceY - The Y coordinate of the source for BltOperation
+ DestinationX - The X coordinate of the destination for BltOperation
+ DestinationY - The Y coordinate of the destination for BltOperation
+ Width - The width of a rectangle in the blt rectangle in pixels
+ Height - The height of a rectangle in the blt rectangle in pixels
+ Delta - Not used for EfiBltVideoFill and EfiBltVideoToVideo operation.
+ If a Delta of 0 is used, the entire BltBuffer will be operated on.
+ If a subrectangle of the BltBuffer is used, then Delta represents
+ the number of bytes in a row of the BltBuffer.
+
+Returns:
+
+ EFI_INVALID_PARAMETER - Invalid parameter passed in
+ EFI_SUCCESS - Blt operation success
+
+--*/
+;
+
+//
+// BIOS VGA Mini Port Protocol functions
+//
+EFI_STATUS
+EFIAPI
+BiosVideoVgaMiniPortSetMode (
+ IN EFI_VGA_MINI_PORT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ VgaMiniPort protocol interface to set mode
+
+Arguments:
+
+ This - Pointer to VgaMiniPort protocol instance
+ ModeNumber - The index of the mode
+
+Returns:
+
+ EFI_UNSUPPORTED - The requested mode is not supported
+ EFI_SUCCESS - The requested mode is set successfully
+
+--*/
+;
+
+//
+// Standard VGA Definitions
+//
+#define VGA_HORIZONTAL_RESOLUTION 640
+#define VGA_VERTICAL_RESOLUTION 480
+#define VGA_NUMBER_OF_BIT_PLANES 4
+#define VGA_PIXELS_PER_BYTE 8
+#define VGA_BYTES_PER_SCAN_LINE (VGA_HORIZONTAL_RESOLUTION / VGA_PIXELS_PER_BYTE)
+#define VGA_BYTES_PER_BIT_PLANE (VGA_VERTICAL_RESOLUTION * VGA_BYTES_PER_SCAN_LINE)
+
+#define VGA_GRAPHICS_CONTROLLER_ADDRESS_REGISTER 0x3ce
+#define VGA_GRAPHICS_CONTROLLER_DATA_REGISTER 0x3cf
+
+#define VGA_GRAPHICS_CONTROLLER_SET_RESET_REGISTER 0x00
+
+#define VGA_GRAPHICS_CONTROLLER_ENABLE_SET_RESET_REGISTER 0x01
+
+#define VGA_GRAPHICS_CONTROLLER_COLOR_COMPARE_REGISTER 0x02
+
+#define VGA_GRAPHICS_CONTROLLER_DATA_ROTATE_REGISTER 0x03
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_REPLACE 0x00
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_AND 0x08
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_OR 0x10
+#define VGA_GRAPHICS_CONTROLLER_FUNCTION_XOR 0x18
+
+#define VGA_GRAPHICS_CONTROLLER_READ_MAP_SELECT_REGISTER 0x04
+
+#define VGA_GRAPHICS_CONTROLLER_MODE_REGISTER 0x05
+#define VGA_GRAPHICS_CONTROLLER_READ_MODE_0 0x00
+#define VGA_GRAPHICS_CONTROLLER_READ_MODE_1 0x08
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_0 0x00
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_1 0x01
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_2 0x02
+#define VGA_GRAPHICS_CONTROLLER_WRITE_MODE_3 0x03
+
+#define VGA_GRAPHICS_CONTROLLER_MISCELLANEOUS_REGISTER 0x06
+
+#define VGA_GRAPHICS_CONTROLLER_COLOR_DONT_CARE_REGISTER 0x07
+
+#define VGA_GRAPHICS_CONTROLLER_BIT_MASK_REGISTER 0x08
+
+#endif
diff --git a/Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h b/Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h
new file mode 100644
index 0000000..5adcdfb
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/VesaBiosExtensions.h
@@ -0,0 +1,463 @@
+//
+// This file contains a 'Sample Driver' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may be modified by the user, subject to
+// the additional terms of the license agreement
+//
+/*++
+
+Copyright (c) 1999 - 2006 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+Module Name:
+
+ VesaBiosExtensions.h
+
+Abstract:
+
+Revision History
+
+--*/
+
+#ifndef _VESA_BIOS_EXTENSIONS_H
+#define _VESA_BIOS_EXTENSIONS_H
+
+//
+// Turn on byte packing of data structures
+//
+#pragma pack(1)
+//
+// VESA BIOS Extensions status codes
+//
+#define VESA_BIOS_EXTENSIONS_STATUS_SUCCESS 0x004f
+
+//
+// VESA BIOS Extensions Services
+//
+#define VESA_BIOS_EXTENSIONS_RETURN_CONTROLLER_INFORMATION 0x4f00
+
+/*++
+
+ Routine Description:
+ Function 00 : Return Controller Information
+
+ Arguments:
+ Inputs:
+ AX = 0x4f00
+ ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK structure
+ Outputs:
+ AX = Return Status
+
+--*/
+#define VESA_BIOS_EXTENSIONS_RETURN_MODE_INFORMATION 0x4f01
+
+/*++
+
+ Routine Description:
+ Function 01 : Return Mode Information
+
+ Arguments:
+ Inputs:
+ AX = 0x4f01
+ CX = Mode Number
+ ES:DI = Pointer to buffer to place VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK structure
+ Outputs:
+ AX = Return Status
+
+--*/
+#define VESA_BIOS_EXTENSIONS_SET_MODE 0x4f02
+
+/*++
+
+ Routine Description:
+ Function 02 : Set Mode
+
+ Arguments:
+ Inputs:
+ AX = 0x4f02
+ BX = Desired mode to set
+ D0-D8 = Mode Number
+ D9-D10 = Reserved (must be 0)
+ D11 = 0 - Use current default refresh rate
+ = 1 - Use user specfieid CRTC values for refresh rate
+ D12-D13 = Reserved (must be 0)
+ D14 = 0 - Use windowed frame buffer model
+ = 1 - Use linear/flat frame buffer model
+ D15 = 0 - Clear display memory
+ = 1 - Don't clear display memory
+ ES:DI = Pointer to buffer to the VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK structure
+ Outputs:
+ AX = Return Status
+
+--*/
+#define VESA_BIOS_EXTENSIONS_RETURN_CURRENT_MODE 0x4f03
+
+/*++
+
+ Routine Description:
+ Function 03 : Return Current Mode
+
+ Arguments:
+ Inputs:
+ AX = 0x4f03
+ Outputs:
+ AX = Return Status
+ BX = Current mode
+ D0-D13 = Mode Number
+ D14 = 0 - Windowed frame buffer model
+ = 1 - Linear/flat frame buffer model
+ D15 = 0 - Memory cleared at last mode set
+ = 1 - Memory not cleared at last mode set
+
+--*/
+#define VESA_BIOS_EXTENSIONS_SAVE_RESTORE_STATE 0x4f04
+
+/*++
+
+ Routine Description:
+ Function 04 : Save/Restore State
+
+ Arguments:
+ Inputs:
+ AX = 0x4f03
+ DL = 0x00 - Return Save/Restore State buffer size
+ = 0x01 - Save State
+ = 0x02 - Restore State
+ CX = Requested Status
+ D0 = Save/Restore controller hardware state
+ D1 = Save/Restore BIOS data state
+ D2 = Save/Restore DAC state
+ D3 = Save/Restore Regsiter state
+ ES:BX = Pointer to buffer if DL=1 or DL=2
+ Outputs:
+ AX = Return Status
+ BX = Number of 64 byte blocks to hold the state buffer if DL=0
+
+--*/
+#define VESA_BIOS_EXTENSIONS_EDID 0x4f15
+
+/*++
+
+ Routine Description:
+ Function 15 : implement VBE/DDC service
+
+ Arguments:
+ Inputs:
+ AX = 0x4f15
+ BL = 0x00 - Report VBE/DDC Capabilities
+ CX = 0x00 - Controller unit number (00 = primary controller)
+ ES:DI = Null pointer, must be 0:0 in version 1.0
+ Outputs:
+ AX = Return Status
+ BH = Approx. time in seconds, rounded up, to transfer one EDID block(128 bytes)
+ BL = DDC level supported
+ D0 = 0 DDC1 not supported
+ = 1 DDC1 supported
+ D1 = 0 DDC2 not supported
+ = 1 DDC2 supported
+ D2 = 0 Screen not blanked during data transfer
+ = 1 Screen blanked during data transfer
+
+ Inputs:
+ AX = 0x4f15
+ BL = 0x01 - Read EDID
+ CX = 0x00 - Controller unit number (00 = primary controller)
+ DX = 0x00 - EDID block number
+ ES:DI = Pointer to buffer in which the EDID block is returned
+ Outputs:
+ AX = Return Status
+--*/
+
+//
+// Timing data from EDID data block
+//
+#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128
+#define VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER 17
+
+typedef struct {
+ UINT16 HorizontalResolution;
+ UINT16 VerticalResolution;
+ UINT16 RefreshRate;
+} VESA_BIOS_EXTENSIONS_EDID_TIMING;
+
+typedef struct {
+ UINT32 ValidNumber;
+ UINT32 Key[VESA_BIOS_EXTENSIONS_EDID_ESTABLISHED_TIMING_MAX_NUMBER];
+} VESA_BIOS_EXTENSIONS_VALID_EDID_TIMING;
+
+typedef struct {
+ UINT8 Header[8]; //EDID header "00 FF FF FF FF FF FF 00"
+ UINT16 ManufactureName; //EISA 3-character ID
+ UINT16 ProductCode; //Vendor assigned code
+ UINT32 SerialNumber; //32-bit serial number
+ UINT8 WeekOfManufacture; //Week number
+ UINT8 YearOfManufacture; //Year
+ UINT8 EdidVersion; //EDID Structure Version
+ UINT8 EdidRevision; //EDID Structure Revision
+ UINT8 VideoInputDefinition;
+ UINT8 MaxHorizontalImageSize; //cm
+ UINT8 MaxVerticalImageSize; //cm
+ UINT8 DisplayTransferCharacteristic;
+ UINT8 FeatureSupport;
+ UINT8 RedGreenLowBits; //Rx1 Rx0 Ry1 Ry0 Gx1 Gx0 Gy1Gy0
+ UINT8 BlueWhiteLowBits; //Bx1 Bx0 By1 By0 Wx1 Wx0 Wy1 Wy0
+ UINT8 RedX; //Red-x Bits 9 - 2
+ UINT8 RedY; //Red-y Bits 9 - 2
+ UINT8 GreenX; //Green-x Bits 9 - 2
+ UINT8 GreenY; //Green-y Bits 9 - 2
+ UINT8 BlueX; //Blue-x Bits 9 - 2
+ UINT8 BlueY; //Blue-y Bits 9 - 2
+ UINT8 WhiteX; //White-x Bits 9 - 2
+ UINT8 WhiteY; //White-x Bits 9 - 2
+ UINT8 EstablishedTimings[3];
+ UINT8 StandardTimingIdentification[16];
+ UINT8 DetailedTimingDescriptions[72];
+ UINT8 ExtensionFlag; //Number of (optional) 128-byte EDID extension blocks to follow
+ UINT8 Checksum;
+} VESA_BIOS_EXTENSIONS_EDID_DATA_BLOCK;
+
+//
+// Super VGA Information Block
+//
+typedef struct {
+ UINT32 VESASignature; // 'VESA' 4 byte signature
+ UINT16 VESAVersion; // VBE version number
+ UINT32 OEMStringPtr; // Pointer to OEM string
+ UINT32 Capabilities; // Capabilities of video card
+ UINT32 VideoModePtr; // Pointer to an array of 16-bit supported modes values terminated by 0xFFFF
+ UINT16 TotalMemory; // Number of 64kb memory blocks
+ UINT16 OemSoftwareRev; // VBE implementation Software revision
+ UINT32 OemVendorNamePtr; // VbeFarPtr to Vendor Name String
+ UINT32 OemProductNamePtr; // VbeFarPtr to Product Name String
+ UINT32 OemProductRevPtr; // VbeFarPtr to Product Revision String
+ UINT8 Reserved[222]; // Reserved for VBE implementation scratch area
+ UINT8 OemData[256]; // Data area for OEM strings. Pad to 512 byte block size
+} VESA_BIOS_EXTENSIONS_INFORMATION_BLOCK;
+
+//
+// Super VGA Information Block VESASignature values
+//
+#define VESA_BIOS_EXTENSIONS_VESA_SIGNATURE EFI_SIGNATURE_32 ('V', 'E', 'S', 'A')
+#define VESA_BIOS_EXTENSIONS_VBE2_SIGNATURE EFI_SIGNATURE_32 ('V', 'B', 'E', '2')
+
+//
+// Super VGA Information Block VESAVersion values
+//
+#define VESA_BIOS_EXTENSIONS_VERSION_1_2 0x0102
+#define VESA_BIOS_EXTENSIONS_VERSION_2_0 0x0200
+#define VESA_BIOS_EXTENSIONS_VERSION_3_0 0x0300
+
+//
+// Super VGA Information Block Capabilities field bit defintions
+//
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_8_BIT_DAC 0x01 // 0: DAC width is fixed at 6 bits/color
+// 1: DAC width switchable to 8 bits/color
+//
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_VGA 0x02 // 0: Controller is VGA compatible
+// 1: Controller is not VGA compatible
+//
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_NOT_NORMAL_RAMDAC 0x04 // 0: Normal RAMDAC operation
+// 1: Use blank bit in function 9 to program RAMDAC
+//
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_STEREOSCOPIC 0x08 // 0: No hardware stereoscopic signal support
+// 1: Hardware stereoscopic signal support
+//
+#define VESA_BIOS_EXTENSIONS_CAPABILITY_VESA_EVC 0x10 // 0: Stero signaling supported via external VESA stereo connector
+// 1: Stero signaling supported via VESA EVC connector
+//
+// Super VGA mode number bite field definitions
+//
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_VESA 0x0100 // 0: Not a VESA defined VBE mode
+// 1: A VESA defined VBE mode
+//
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_REFRESH_CONTROL_USER 0x0800 // 0: Use current BIOS default referesh rate
+// 1: Use the user specified CRTC values for refresh rate
+//
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_LINEAR_FRAME_BUFFER 0x4000 // 0: Use a banked/windowed frame buffer
+// 1: Use a linear/flat frame buffer
+//
+#define VESA_BIOS_EXTENSIONS_MODE_NUMBER_PRESERVE_MEMORY 0x8000 // 0: Clear display memory
+// 1: Preseve display memory
+//
+// Super VGA Information Block mode list terminator value
+//
+#define VESA_BIOS_EXTENSIONS_END_OF_MODE_LIST 0xffff
+
+//
+// Window Function
+//
+typedef
+VOID
+(*VESA_BIOS_EXTENSIONS_WINDOW_FUNCTION) (
+ VOID
+ );
+
+//
+// Super VGA Mode Information Block
+//
+typedef struct {
+ //
+ // Manadory fields for all VESA Bios Extensions revisions
+ //
+ UINT16 ModeAttributes; // Mode attributes
+ UINT8 WinAAttributes; // Window A attributes
+ UINT8 WinBAttributes; // Window B attributes
+ UINT16 WinGranularity; // Window granularity in k
+ UINT16 WinSize; // Window size in k
+ UINT16 WinASegment; // Window A segment
+ UINT16 WinBSegment; // Window B segment
+ UINT32 WindowFunction; // Pointer to window function
+ UINT16 BytesPerScanLine; // Bytes per scanline
+ //
+ // Manadory fields for VESA Bios Extensions 1.2 and above
+ //
+ UINT16 XResolution; // Horizontal resolution
+ UINT16 YResolution; // Vertical resolution
+ UINT8 XCharSize; // Character cell width
+ UINT8 YCharSize; // Character cell height
+ UINT8 NumberOfPlanes; // Number of memory planes
+ UINT8 BitsPerPixel; // Bits per pixel
+ UINT8 NumberOfBanks; // Number of CGA style banks
+ UINT8 MemoryModel; // Memory model type
+ UINT8 BankSize; // Size of CGA style banks
+ UINT8 NumberOfImagePages; // Number of images pages
+ UINT8 Reserved1; // Reserved
+ UINT8 RedMaskSize; // Size of direct color red mask
+ UINT8 RedFieldPosition; // Bit posn of lsb of red mask
+ UINT8 GreenMaskSize; // Size of direct color green mask
+ UINT8 GreenFieldPosition; // Bit posn of lsb of green mask
+ UINT8 BlueMaskSize; // Size of direct color blue mask
+ UINT8 BlueFieldPosition; // Bit posn of lsb of blue mask
+ UINT8 RsvdMaskSize; // Size of direct color res mask
+ UINT8 RsvdFieldPosition; // Bit posn of lsb of res mask
+ UINT8 DirectColorModeInfo; // Direct color mode attributes
+ //
+ // Manadory fields for VESA Bios Extensions 2.0 and above
+ //
+ UINT32 PhysBasePtr; // Physical Address for flat memory frame buffer
+ UINT32 Reserved2; // Reserved
+ UINT16 Reserved3; // Reserved
+ //
+ // Manadory fields for VESA Bios Extensions 3.0 and above
+ //
+ UINT16 LinBytesPerScanLine; // Bytes/scan line for linear modes
+ UINT8 BnkNumberOfImagePages; // Number of images for banked modes
+ UINT8 LinNumberOfImagePages; // Number of images for linear modes
+ UINT8 LinRedMaskSize; // Size of direct color red mask (linear mode)
+ UINT8 LinRedFieldPosition; // Bit posiiton of lsb of red mask (linear modes)
+ UINT8 LinGreenMaskSize; // Size of direct color green mask (linear mode)
+ UINT8 LinGreenFieldPosition; // Bit posiiton of lsb of green mask (linear modes)
+ UINT8 LinBlueMaskSize; // Size of direct color blue mask (linear mode)
+ UINT8 LinBlueFieldPosition; // Bit posiiton of lsb of blue mask (linear modes)
+ UINT8 LinRsvdMaskSize; // Size of direct color reserved mask (linear mode)
+ UINT8 LinRsvdFieldPosition; // Bit posiiton of lsb of reserved mask (linear modes)
+ UINT32 MaxPixelClock; // Maximum pixel clock (in Hz) for graphics mode
+ UINT8 Pad[190]; // Pad to 256 byte block size
+} VESA_BIOS_EXTENSIONS_MODE_INFORMATION_BLOCK;
+
+//
+// Super VGA Mode Information Block ModeAttributes field bit defintions
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_HARDWARE 0x0001 // 0: Mode not supported in handware
+// 1: Mode supported in handware
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_TTY 0x0004 // 0: TTY Output functions not supported by BIOS
+// 1: TTY Output functions supported by BIOS
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_COLOR 0x0008 // 0: Monochrome mode
+// 1: Color mode
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_GRAPHICS 0x0010 // 0: Text mode
+// 1: Graphics mode
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_VGA 0x0020 // 0: VGA compatible mode
+// 1: Not a VGA compatible mode
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NOT_WINDOWED 0x0040 // 0: VGA compatible windowed memory mode
+// 1: Not a VGA compatible windowed memory mode
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_LINEAR_FRAME_BUFFER 0x0080 // 0: No linear fram buffer mode available
+// 1: Linear frame buffer mode available
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DOUBLE_SCAN 0x0100 // 0: No double scan mode available
+// 1: Double scan mode available
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_INTERLACED 0x0200 // 0: No interlaced mode is available
+// 1: Interlaced mode is available
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_NO_TRIPPLE_BUFFER 0x0400 // 0: No hardware triple buffer mode support available
+// 1: Hardware triple buffer mode support available
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_STEREOSCOPIC 0x0800 // 0: No hardware steroscopic display support
+// 1: Hardware steroscopic display support
+//
+#define VESA_BIOS_EXTENSIONS_MODE_ATTRIBUTE_DUAL_DISPLAY 0x1000 // 0: No dual display start address support
+// 1: Dual display start address support
+//
+// Super VGA Mode Information Block WinAAttribite/WinBAttributes field bit defintions
+//
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_RELOCATABLE 0x01 // 0: Single non-relocatable window only
+// 1: Relocatable window(s) are supported
+//
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_READABLE 0x02 // 0: Window is not readable
+// 1: Window is readable
+//
+#define VESA_BIOS_EXTENSIONS_WINX_ATTRIBUTE_WRITABLE 0x04 // 0: Window is not writable
+// 1: Window is writable
+//
+// Super VGA Mode Information Block DirectColorMode field bit defintions
+//
+#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_PROG_COLOR_RAMP 0x01 // 0: Color ram is fixed
+// 1: Color ramp is programmable
+//
+#define VESA_BIOS_EXTENSIONS_DIRECT_COLOR_MODE_RSVD_USABLE 0x02 // 0: Bits in Rsvd field are reserved
+// 1: Bits in Rsdv field are usable
+//
+// Super VGA Memory Models
+//
+typedef enum {
+ memPL = 3, // Planar memory model
+ memPK = 4, // Packed pixel memory model
+ memRGB= 6, // Direct color RGB memory model
+ memYUV= 7, // Direct color YUV memory model
+} VESA_BIOS_EXTENSIONS_MEMORY_MODELS;
+
+//
+// Super VGA CRTC Information Block
+//
+typedef struct {
+ UINT16 HorizontalTotal; // Horizontal total in pixels
+ UINT16 HorizontalSyncStart; // Horizontal sync start in pixels
+ UINT16 HorizontalSyncEnd; // Horizontal sync end in pixels
+ UINT16 VericalTotal; // Vertical total in pixels
+ UINT16 VericalSyncStart; // Vertical sync start in pixels
+ UINT16 VericalSyncEnd; // Vertical sync end in pixels
+ UINT8 Flags; // Flags (Interlaced/DoubleScan/etc).
+ UINT32 PixelClock; // Pixel clock in units of Hz
+ UINT16 RefreshRate; // Refresh rate in units of 0.01 Hz
+ UINT8 Reserved[40]; // Pad
+} VESA_BIOS_EXTENSIONS_CRTC_INFORMATION_BLOCK;
+
+#define VESA_BIOS_EXTENSIONS_CRTC_FLAGS_DOUBLE_SCAN 0x01 // 0: Graphics mode is not souble scanned
+// 1: Graphics mode is double scanned
+//
+#define VESA_BIOS_EXTENSIONS_CRTC_FLAGSINTERLACED 0x02 // 0: Graphics mode is not interlaced
+// 1: Graphics mode is interlaced
+//
+#define VESA_BIOS_EXTENSIONS_CRTC_HORIZONTAL_SYNC_NEGATIVE 0x04 // 0: Horizontal sync polarity is positive(+)
+// 0: Horizontal sync polarity is negative(-)
+//
+#define VESA_BIOS_EXTENSIONS_CRTC_VERITICAL_SYNC_NEGATIVE 0x08 // 0: Verical sync polarity is positive(+)
+// 0: Verical sync polarity is negative(-)
+//
+// Turn off byte packing of data structures
+//
+#pragma pack()
+
+#endif
diff --git a/Core/EM/CSM/thunk/CsmVideo/VgaClass.c b/Core/EM/CSM/thunk/CsmVideo/VgaClass.c
new file mode 100644
index 0000000..1315bf5
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/VgaClass.c
@@ -0,0 +1,1349 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+--*/
+/*++
+
+Copyright (c) 1999 - 2003 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ VgaClass.c
+
+Abstract:
+ This driver produces a VGA console.
+
+--*/
+#include "VgaClass.h"
+//*** AMI PORTING BEGIN ***//
+#if INT10_SIMPLE_TEXT_SUPPORT==1
+//*** AMI PORTING END *****//
+
+//
+// EFI Driver Binding Protocol for the VGA Class Driver
+//
+EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding = {
+ VgaClassDriverBindingSupported,
+ VgaClassDriverBindingStart,
+ VgaClassDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+//
+// Local variables
+//
+static CHAR16 CrLfString[3] = { CHAR_CARRIAGE_RETURN, CHAR_LINEFEED, CHAR_NULL };
+
+typedef struct {
+ CHAR16 Unicode;
+ CHAR8 PcAnsi;
+ CHAR8 Ascii;
+} UNICODE_TO_CHAR;
+
+//
+// This list is used to define the valid extend chars.
+// It also provides a mapping from Unicode to PCANSI or
+// ASCII. The ASCII mapping we just made up.
+//
+//
+STATIC UNICODE_TO_CHAR UnicodeToPcAnsiOrAscii[] = {
+ BOXDRAW_HORIZONTAL,
+ 0xc4,
+ L'-',
+ BOXDRAW_VERTICAL,
+ 0xb3,
+ L'|',
+ BOXDRAW_DOWN_RIGHT,
+ 0xda,
+ L'/',
+ BOXDRAW_DOWN_LEFT,
+ 0xbf,
+ L'\\',
+ BOXDRAW_UP_RIGHT,
+ 0xc0,
+ L'\\',
+ BOXDRAW_UP_LEFT,
+ 0xd9,
+ L'/',
+ BOXDRAW_VERTICAL_RIGHT,
+ 0xc3,
+ L'|',
+ BOXDRAW_VERTICAL_LEFT,
+ 0xb4,
+ L'|',
+ BOXDRAW_DOWN_HORIZONTAL,
+ 0xc2,
+ L'+',
+ BOXDRAW_UP_HORIZONTAL,
+ 0xc1,
+ L'+',
+ BOXDRAW_VERTICAL_HORIZONTAL,
+ 0xc5,
+ L'+',
+ BOXDRAW_DOUBLE_HORIZONTAL,
+ 0xcd,
+ L'-',
+ BOXDRAW_DOUBLE_VERTICAL,
+ 0xba,
+ L'|',
+ BOXDRAW_DOWN_RIGHT_DOUBLE,
+ 0xd5,
+ L'/',
+ BOXDRAW_DOWN_DOUBLE_RIGHT,
+ 0xd6,
+ L'/',
+ BOXDRAW_DOUBLE_DOWN_RIGHT,
+ 0xc9,
+ L'/',
+ BOXDRAW_DOWN_LEFT_DOUBLE,
+ 0xb8,
+ L'\\',
+ BOXDRAW_DOWN_DOUBLE_LEFT,
+ 0xb7,
+ L'\\',
+ BOXDRAW_DOUBLE_DOWN_LEFT,
+ 0xbb,
+ L'\\',
+ BOXDRAW_UP_RIGHT_DOUBLE,
+ 0xd4,
+ L'\\',
+ BOXDRAW_UP_DOUBLE_RIGHT,
+ 0xd3,
+ L'\\',
+ BOXDRAW_DOUBLE_UP_RIGHT,
+ 0xc8,
+ L'\\',
+ BOXDRAW_UP_LEFT_DOUBLE,
+ 0xbe,
+ L'/',
+ BOXDRAW_UP_DOUBLE_LEFT,
+ 0xbd,
+ L'/',
+ BOXDRAW_DOUBLE_UP_LEFT,
+ 0xbc,
+ L'/',
+ BOXDRAW_VERTICAL_RIGHT_DOUBLE,
+ 0xc6,
+ L'|',
+ BOXDRAW_VERTICAL_DOUBLE_RIGHT,
+ 0xc7,
+ L'|',
+ BOXDRAW_DOUBLE_VERTICAL_RIGHT,
+ 0xcc,
+ L'|',
+ BOXDRAW_VERTICAL_LEFT_DOUBLE,
+ 0xb5,
+ L'|',
+ BOXDRAW_VERTICAL_DOUBLE_LEFT,
+ 0xb6,
+ L'|',
+ BOXDRAW_DOUBLE_VERTICAL_LEFT,
+ 0xb9,
+ L'|',
+ BOXDRAW_DOWN_HORIZONTAL_DOUBLE,
+ 0xd1,
+ L'+',
+ BOXDRAW_DOWN_DOUBLE_HORIZONTAL,
+ 0xd2,
+ L'+',
+ BOXDRAW_DOUBLE_DOWN_HORIZONTAL,
+ 0xcb,
+ L'+',
+ BOXDRAW_UP_HORIZONTAL_DOUBLE,
+ 0xcf,
+ L'+',
+ BOXDRAW_UP_DOUBLE_HORIZONTAL,
+ 0xd0,
+ L'+',
+ BOXDRAW_DOUBLE_UP_HORIZONTAL,
+ 0xca,
+ L'+',
+ BOXDRAW_VERTICAL_HORIZONTAL_DOUBLE,
+ 0xd8,
+ L'+',
+ BOXDRAW_VERTICAL_DOUBLE_HORIZONTAL,
+ 0xd7,
+ L'+',
+ BOXDRAW_DOUBLE_VERTICAL_HORIZONTAL,
+ 0xce,
+ L'+',
+
+ BLOCKELEMENT_FULL_BLOCK,
+ 0xdb,
+ L'*',
+ BLOCKELEMENT_LIGHT_SHADE,
+ 0xb0,
+ L'+',
+
+ GEOMETRICSHAPE_UP_TRIANGLE,
+ 0x1e,
+ L'^',
+ GEOMETRICSHAPE_RIGHT_TRIANGLE,
+ 0x10,
+ L'>',
+ GEOMETRICSHAPE_DOWN_TRIANGLE,
+ 0x1f,
+ L'v',
+ GEOMETRICSHAPE_LEFT_TRIANGLE,
+ 0x11,
+ L'<',
+
+ ARROW_LEFT,
+ 0x3c,
+ L'<',
+
+ ARROW_UP,
+ 0x18,
+ L'^',
+
+ ARROW_RIGHT,
+ 0x3e,
+ L'>',
+
+ ARROW_DOWN,
+ 0x19,
+ L'v',
+
+ 0x0000,
+ 0x00
+};
+
+//
+// Private worker functions
+//
+STATIC
+VOID
+SetVideoCursorPosition (
+ IN VGA_CLASS_DEV *VgaClassDev,
+ IN UINTN Column,
+ IN UINTN Row,
+ IN UINTN MaxColumn
+ );
+
+STATIC
+VOID
+WriteCrtc (
+ IN VGA_CLASS_DEV *VgaClassDev,
+ IN UINT16 Address,
+ IN UINT8 Data
+ );
+
+STATIC
+BOOLEAN
+LibIsValidTextGraphics (
+ IN CHAR16 Graphic,
+ OUT CHAR8 *PcAnsi, OPTIONAL
+ OUT CHAR8 *Ascii OPTIONAL
+ );
+
+STATIC
+BOOLEAN
+IsValidAscii (
+ IN CHAR16 Ascii
+ );
+
+STATIC
+BOOLEAN
+IsValidEfiCntlChar (
+ IN CHAR16 c
+ );
+
+//
+// Driver Entry Point
+//
+EFI_DRIVER_ENTRY_POINT (VgaClassDriverEntryPoint)
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+/*++
+
+ Routine Description:
+
+ Driver Entry Point.
+
+ Arguments:
+
+ (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT)
+
+ Returns:
+ EFI_STATUS
+--*/
+// GC_TODO: ImageHandle - add argument and description to function comment
+// GC_TODO: SystemTable - add argument and description to function comment
+{
+ return INSTALL_ALL_DRIVER_PROTOCOLS (
+ ImageHandle,
+ SystemTable,
+ &gVgaClassDriverBinding,
+ ImageHandle,
+//*** AMI PORTING BEGIN ***//
+ NULL,
+// &gVgaClassComponentName,
+//*** AMI PORTING END *****//
+ NULL,
+ NULL
+ );
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Supported.
+
+ Arguments:
+
+ (Standard DriverBinding Protocol Supported() function)
+
+ Returns:
+
+ EFI_STATUS
+
+--*/
+// GC_TODO: This - add argument and description to function comment
+// GC_TODO: Controller - add argument and description to function comment
+// GC_TODO: RemainingDevicePath - add argument and description to function comment
+{
+ EFI_STATUS Status;
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
+
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiVgaMiniPortProtocolGuid,
+ (VOID **) &VgaMiniPort,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Open the IO Abstraction(s) needed to perform the supported test
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+ Routine Description:
+
+ Layers the Simple Text Output Protocol on top of the
+ VGA Mini Port Protocol
+
+ Arguments:
+
+ (Standard DriverBinding Protocol Start() function)
+
+ Returns:
+
+ EFI_STATUS
+
+--*/
+// GC_TODO: This - add argument and description to function comment
+// GC_TODO: Controller - add argument and description to function comment
+// GC_TODO: RemainingDevicePath - add argument and description to function comment
+// GC_TODO: EFI_OUT_OF_RESOURCES - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ VGA_CLASS_DEV *VgaClassPrivate;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->HandleProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Report that VGA Class driver is being enabled
+ //
+ ReportStatusCodeWithDevicePath (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_ENABLE,
+ 0,
+ &gEfiCallerIdGuid,
+ DevicePath
+ );
+
+ //
+ // Open the IO Abstraction(s) needed
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **) &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiVgaMiniPortProtocolGuid,
+ (VOID **) &VgaMiniPort,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Allocate the private device structure
+ //
+ Status = gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (VGA_CLASS_DEV),
+ &VgaClassPrivate
+ );
+ if (EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiVgaMiniPortProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EfiZeroMem (VgaClassPrivate, sizeof (VGA_CLASS_DEV));
+
+ //
+ // Initialize the private device structure
+ //
+ VgaClassPrivate->Signature = VGA_CLASS_DEV_SIGNATURE;
+ VgaClassPrivate->Handle = Controller;
+ VgaClassPrivate->VgaMiniPort = VgaMiniPort;
+ VgaClassPrivate->PciIo = PciIo;
+
+ VgaClassPrivate->SimpleTextOut.Reset = VgaClassReset;
+ VgaClassPrivate->SimpleTextOut.OutputString = VgaClassOutputString;
+ VgaClassPrivate->SimpleTextOut.TestString = VgaClassTestString;
+ VgaClassPrivate->SimpleTextOut.ClearScreen = VgaClassClearScreen;
+ VgaClassPrivate->SimpleTextOut.SetAttribute = VgaClassSetAttribute;
+ VgaClassPrivate->SimpleTextOut.SetCursorPosition = VgaClassSetCursorPosition;
+ VgaClassPrivate->SimpleTextOut.EnableCursor = VgaClassEnableCursor;
+ VgaClassPrivate->SimpleTextOut.QueryMode = VgaClassQueryMode;
+ VgaClassPrivate->SimpleTextOut.SetMode = VgaClassSetMode;
+
+ VgaClassPrivate->SimpleTextOut.Mode = &VgaClassPrivate->SimpleTextOutputMode;
+ VgaClassPrivate->SimpleTextOutputMode.MaxMode = VgaMiniPort->MaxMode;
+ VgaClassPrivate->DevicePath = DevicePath;
+
+ Status = VgaClassPrivate->SimpleTextOut.SetAttribute (
+ &VgaClassPrivate->SimpleTextOut,
+ EFI_TEXT_ATTR (EFI_WHITE,
+ EFI_BLACK)
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ Status = VgaClassPrivate->SimpleTextOut.Reset (
+ &VgaClassPrivate->SimpleTextOut,
+ FALSE
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ Status = VgaClassPrivate->SimpleTextOut.EnableCursor (
+ &VgaClassPrivate->SimpleTextOut,
+ TRUE
+ );
+ if (EFI_ERROR (Status)) {
+ goto ErrorExit;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiSimpleTextOutProtocolGuid,
+ &VgaClassPrivate->SimpleTextOut,
+ NULL
+ );
+
+ return Status;
+
+ErrorExit:
+ ReportStatusCodeWithDevicePath (
+ EFI_ERROR_CODE | EFI_ERROR_MINOR,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_EC_CONTROLLER_ERROR,
+ 0,
+ &gEfiCallerIdGuid,
+ DevicePath
+ );
+
+ return Status;
+
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+ Routine Description:
+
+ Stop.
+
+ Arguments:
+
+ (Standard DriverBinding Protocol Stop() function)
+
+ Returns:
+
+ EFI_STATUS
+
+--*/
+// GC_TODO: This - add argument and description to function comment
+// GC_TODO: Controller - add argument and description to function comment
+// GC_TODO: NumberOfChildren - add argument and description to function comment
+// GC_TODO: ChildHandleBuffer - add argument and description to function comment
+// GC_TODO: EFI_SUCCESS - add return value to function comment
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL *SimpleTextOut;
+ VGA_CLASS_DEV *VgaClassPrivate;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiSimpleTextOutProtocolGuid,
+ (VOID **) &SimpleTextOut,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (SimpleTextOut);
+
+ //
+ // Report that VGA Class driver is being disabled
+ //
+ ReportStatusCodeWithDevicePath (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_DISABLE,
+ 0,
+ &gEfiCallerIdGuid,
+ VgaClassPrivate->DevicePath
+ );
+
+ Status = gBS->UninstallProtocolInterface (
+ Controller,
+ &gEfiSimpleTextOutProtocolGuid,
+ &VgaClassPrivate->SimpleTextOut
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ //
+ // Release PCI I/O and VGA Mini Port Protocols on the controller handle.
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiVgaMiniPortProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ gBS->FreePool (VgaClassPrivate);
+
+ return EFI_SUCCESS;
+}
+//
+// Simple Text Output Protocol Functions
+//
+EFI_STATUS
+EFIAPI
+VgaClassReset (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ExtendedVerification - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ EFI_STATUS Status;
+ VGA_CLASS_DEV *VgaClassPrivate;
+
+ VgaClassPrivate = VGA_CLASS_DEV_FROM_THIS (This);
+
+ ReportStatusCodeWithDevicePath (
+ EFI_PROGRESS_CODE,
+ EFI_PERIPHERAL_LOCAL_CONSOLE | EFI_P_PC_RESET,
+ 0,
+ &gEfiCallerIdGuid,
+ VgaClassPrivate->DevicePath
+ );
+
+ This->SetAttribute (This, EFI_TEXT_ATTR (This->Mode->Attribute & 0x0F, EFI_BACKGROUND_BLACK));
+
+ Status = This->SetMode (This, 0);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return This->ClearScreen (This);
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassOutputString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *WString
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ WString - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ VGA_CLASS_DEV *VgaClassDev;
+ EFI_SIMPLE_TEXT_OUTPUT_MODE *Mode;
+ UINTN MaxColumn;
+ UINTN MaxRow;
+ CHAR16 *SavedWString;
+ UINT32 VideoChar;
+ CHAR8 GraphicChar;
+
+ VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
+
+ Mode = This->Mode;
+
+ Status = This->QueryMode (
+ This,
+ Mode->Mode,
+ &MaxColumn,
+ &MaxRow
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ SavedWString = WString;
+ for (; *WString != CHAR_NULL; WString++) {
+
+ switch (*WString) {
+ case CHAR_BACKSPACE:
+ if (Mode->CursorColumn > 0) {
+ Mode->CursorColumn--;
+ }
+ break;
+
+ case CHAR_LINEFEED:
+ if (Mode->CursorRow == (INT32) (MaxRow - 1)) {
+ //
+ // Scroll the screen by copying the contents
+ // of the VGA display up one line
+ //
+ VgaClassDev->PciIo->CopyMem (
+ VgaClassDev->PciIo,
+ EfiPciIoWidthUint32,
+ VgaClassDev->VgaMiniPort->VgaMemoryBar,
+ VgaClassDev->VgaMiniPort->VgaMemoryOffset,
+ VgaClassDev->VgaMiniPort->VgaMemoryBar,
+ VgaClassDev->VgaMiniPort->VgaMemoryOffset + MaxColumn * 2,
+ ((MaxRow - 1) * MaxColumn) >> 1
+ );
+
+ //
+ // Print Blank Line of spaces with the current color attributes
+ //
+ VideoChar = (Mode->Attribute << 8) | ' ';
+ VideoChar = (VideoChar << 16) | VideoChar;
+ VgaClassDev->PciIo->Mem.Write (
+ VgaClassDev->PciIo,
+ EfiPciIoWidthFillUint32,
+ VgaClassDev->VgaMiniPort->VgaMemoryBar,
+ VgaClassDev->VgaMiniPort->VgaMemoryOffset + (MaxRow - 1) * MaxColumn * 2,
+ MaxColumn >> 1,
+ &VideoChar
+ );
+ }
+
+ if (Mode->CursorRow < (INT32) (MaxRow - 1)) {
+ Mode->CursorRow++;
+ }
+ break;
+
+ case CHAR_CARRIAGE_RETURN:
+ Mode->CursorColumn = 0;
+ break;
+
+ default:
+ if (!LibIsValidTextGraphics (*WString, &GraphicChar, NULL)) {
+ //
+ // Just convert to ASCII
+ //
+ GraphicChar = (CHAR8) *WString;
+ if (!IsValidAscii (GraphicChar)) {
+ //
+ // Keep the API from supporting PCANSI Graphics chars
+ //
+ GraphicChar = '?';
+ }
+ }
+
+ VideoChar = (Mode->Attribute << 8) | GraphicChar;
+ VgaClassDev->PciIo->Mem.Write (
+ VgaClassDev->PciIo,
+ EfiPciIoWidthUint16,
+ VgaClassDev->VgaMiniPort->VgaMemoryBar,
+ VgaClassDev->VgaMiniPort->VgaMemoryOffset + ((Mode->CursorRow * MaxColumn + Mode->CursorColumn) * 2),
+ 1,
+ &VideoChar
+ );
+
+ if (Mode->CursorColumn >= (INT32) (MaxColumn - 1)) {
+ This->OutputString (This, CrLfString);
+ } else {
+ Mode->CursorColumn++;
+ }
+ break;
+ }
+ }
+
+ SetVideoCursorPosition (
+ VgaClassDev,
+ (UINTN) Mode->CursorColumn,
+ (UINTN) Mode->CursorRow,
+ MaxColumn
+ );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassTestString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *WString
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ WString - GC_TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - GC_TODO: Add description for return value
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ while (*WString != 0x0000) {
+ if (!(IsValidAscii (*WString) || IsValidEfiCntlChar (*WString) || LibIsValidTextGraphics (*WString, NULL, NULL))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ WString++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassClearScreen (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ VGA_CLASS_DEV *VgaClassDev;
+ UINTN MaxRow;
+ UINTN MaxColumn;
+ UINT32 VideoChar;
+
+ VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
+
+ Status = This->QueryMode (
+ This,
+ This->Mode->Mode,
+ &MaxColumn,
+ &MaxRow
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ VideoChar = (This->Mode->Attribute << 8) | ' ';
+ VideoChar = (VideoChar << 16) | VideoChar;
+ VgaClassDev->PciIo->Mem.Write (
+ VgaClassDev->PciIo,
+ EfiPciIoWidthFillUint32,
+ VgaClassDev->VgaMiniPort->VgaMemoryBar,
+ VgaClassDev->VgaMiniPort->VgaMemoryOffset,
+ (MaxRow * MaxColumn) >> 1,
+ &VideoChar
+ );
+
+ This->SetCursorPosition (This, 0, 0);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassSetAttribute (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Attribute
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Attribute - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+ EFI_UNSUPPORTED - GC_TODO: Add description for return value
+
+--*/
+{
+//*** AMI PORTING BEGIN ***//
+// Comparison of unsigned value with zero
+// if (Attribute >= 0 && Attribute <= EFI_MAX_ATTRIBUTE) {
+ if (Attribute <= EFI_MAX_ATTRIBUTE) {
+//*** AMI PORTING END *****//
+ This->Mode->Attribute = (INT32) Attribute;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassSetCursorPosition (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Column - GC_TODO: add argument description
+ Row - GC_TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - GC_TODO: Add description for return value
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ VGA_CLASS_DEV *VgaClassDev;
+ UINTN MaxColumn;
+ UINTN MaxRow;
+
+ VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
+
+ Status = This->QueryMode (
+ This,
+ This->Mode->Mode,
+ &MaxColumn,
+ &MaxRow
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ if (Column >= MaxColumn || Row >= MaxRow) {
+ return EFI_UNSUPPORTED;
+ }
+
+ SetVideoCursorPosition (VgaClassDev, Column, Row, MaxColumn);
+
+ This->Mode->CursorColumn = (INT32) Column;
+ This->Mode->CursorRow = (INT32) Row;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassEnableCursor (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN Visible
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Visible - GC_TODO: add argument description
+
+Returns:
+
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ VGA_CLASS_DEV *VgaClassDev;
+
+ VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
+ if (Visible) {
+ switch (This->Mode->Mode) {
+ case 1:
+ WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x06);
+ WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x07);
+ break;
+
+ default:
+ WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x0e);
+ WriteCrtc (VgaClassDev, CRTC_CURSOR_END, 0x0f);
+ break;
+ }
+ } else {
+ WriteCrtc (VgaClassDev, CRTC_CURSOR_START, 0x20);
+ }
+
+ This->Mode->CursorVisible = Visible;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassQueryMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ModeNumber - GC_TODO: add argument description
+ Columns - GC_TODO: add argument description
+ Rows - GC_TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - GC_TODO: Add description for return value
+ EFI_UNSUPPORTED - GC_TODO: Add description for return value
+ EFI_SUCCESS - GC_TODO: Add description for return value
+
+--*/
+{
+ VGA_CLASS_DEV *VgaClassDev;
+
+ VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
+
+ if ((INT32) ModeNumber >= This->Mode->MaxMode) {
+ *Columns = 0;
+ *Rows = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ switch (ModeNumber) {
+ case 0:
+ *Columns = 80;
+ *Rows = 25;
+ break;
+
+ case 1:
+ *Columns = 80;
+ *Rows = 50;
+ break;
+
+ default:
+ *Columns = 0;
+ *Rows = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+VgaClassSetMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ModeNumber - GC_TODO: add argument description
+
+Returns:
+
+ EFI_UNSUPPORTED - GC_TODO: Add description for return value
+
+--*/
+{
+ EFI_STATUS Status;
+ VGA_CLASS_DEV *VgaClassDev;
+
+ VgaClassDev = VGA_CLASS_DEV_FROM_THIS (This);
+
+ if ((INT32) ModeNumber >= This->Mode->MaxMode) {
+ return EFI_UNSUPPORTED;
+ }
+
+ This->ClearScreen (This);
+
+ This->Mode->Mode = (INT32) ModeNumber;
+
+ Status = VgaClassDev->VgaMiniPort->SetMode (VgaClassDev->VgaMiniPort, ModeNumber);
+
+ return Status;
+}
+//
+// Private Worker Functions
+//
+STATIC
+VOID
+SetVideoCursorPosition (
+ IN VGA_CLASS_DEV *VgaClassDev,
+ IN UINTN Column,
+ IN UINTN Row,
+ IN UINTN MaxColumn
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ VgaClassDev - GC_TODO: add argument description
+ Column - GC_TODO: add argument description
+ Row - GC_TODO: add argument description
+ MaxColumn - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ Column = Column & 0xff;
+ Row = Row & 0xff;
+ MaxColumn = MaxColumn & 0xff;
+ WriteCrtc (
+ VgaClassDev,
+ CRTC_CURSOR_LOCATION_HIGH,
+ (UINT8) ((Row * MaxColumn + Column) >> 8)
+ );
+ WriteCrtc (
+ VgaClassDev,
+ CRTC_CURSOR_LOCATION_LOW,
+ (UINT8) ((Row * MaxColumn + Column) & 0xff)
+ );
+}
+
+STATIC
+VOID
+WriteCrtc (
+ IN VGA_CLASS_DEV *VgaClassDev,
+ IN UINT16 Address,
+ IN UINT8 Data
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ VgaClassDev - GC_TODO: add argument description
+ Address - GC_TODO: add argument description
+ Data - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ VgaClassDev->PciIo->Io.Write (
+ VgaClassDev->PciIo,
+ EfiPciIoWidthUint8,
+ VgaClassDev->VgaMiniPort->CrtcAddressRegisterBar,
+ VgaClassDev->VgaMiniPort->CrtcAddressRegisterOffset,
+ 1,
+ &Address
+ );
+
+ VgaClassDev->PciIo->Io.Write (
+ VgaClassDev->PciIo,
+ EfiPciIoWidthUint8,
+ VgaClassDev->VgaMiniPort->CrtcDataRegisterBar,
+ VgaClassDev->VgaMiniPort->CrtcDataRegisterOffset,
+ 1,
+ &Data
+ );
+}
+
+STATIC
+BOOLEAN
+LibIsValidTextGraphics (
+ IN CHAR16 Graphic,
+ OUT CHAR8 *PcAnsi, OPTIONAL
+ OUT CHAR8 *Ascii OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ Detects if a Unicode char is for Box Drawing text graphics.
+
+Arguments:
+
+ Grphic - Unicode char to test.
+
+ PcAnsi - Optional pointer to return PCANSI equivalent of Graphic.
+
+ Asci - Optional pointer to return Ascii equivalent of Graphic.
+
+Returns:
+
+ TRUE if Gpaphic is a supported Unicode Box Drawing character.
+
+--*/
+// GC_TODO: Graphic - add argument and description to function comment
+{
+ UNICODE_TO_CHAR *Table;
+
+ if ((((Graphic & 0xff00) != 0x2500) && ((Graphic & 0xff00) != 0x2100))) {
+ //
+ // Unicode drawing code charts are all in the 0x25xx range,
+ // arrows are 0x21xx
+ //
+ return FALSE;
+ }
+
+ for (Table = UnicodeToPcAnsiOrAscii; Table->Unicode != 0x0000; Table++) {
+ if (Graphic == Table->Unicode) {
+ if (PcAnsi) {
+ *PcAnsi = Table->PcAnsi;
+ }
+
+ if (Ascii) {
+ *Ascii = Table->Ascii;
+ }
+
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+STATIC
+BOOLEAN
+IsValidAscii (
+ IN CHAR16 Ascii
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ Ascii - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ if ((Ascii >= 0x20) && (Ascii <= 0x7f)) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+STATIC
+BOOLEAN
+IsValidEfiCntlChar (
+ IN CHAR16 c
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ c - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+{
+ if (c == CHAR_NULL || c == CHAR_BACKSPACE || c == CHAR_LINEFEED || c == CHAR_CARRIAGE_RETURN) {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+//*** AMI PORTING BEGIN ***//
+#endif //if INT10_SIMPLE_TEXT_SUPPORT==1
+//*** AMI PORTING END *****// \ No newline at end of file
diff --git a/Core/EM/CSM/thunk/CsmVideo/VgaClass.h b/Core/EM/CSM/thunk/CsmVideo/VgaClass.h
new file mode 100644
index 0000000..fd184de
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/VgaClass.h
@@ -0,0 +1,418 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//
+// This file contains a 'Sample Driver' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may be modified by the user, subject to
+// the additional terms of the license agreement
+//
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ VgaClass.h
+
+Abstract:
+
+
+Revision History
+--*/
+
+#ifndef _VGA_CLASS_H
+#define _VGA_CLASS_H
+
+//*** AMI PORTING BEGIN ***//
+#include "AmiMapping.h"
+//#include "Tiano.h"
+//#include "EfiDriverLib.h"
+//*** AMI PORTING END *****//
+#include "Pci22.h"
+//*** AMI PORTING BEGIN ***//
+//#include "EfiStatusCode.h"
+//#include "EfiCompNameSupport.h"
+//#include "ComponentName.h"
+//*** AMI PORTING END *****//
+
+//
+// Driver Consumed Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION (DevicePath)
+#include EFI_PROTOCOL_DEFINITION (PciIo)
+//*** AMI PORTING BEGIN ***//
+//#include EFI_PROTOCOL_DEFINITION (VgaMiniPort)
+#include "VgaMiniPort.h"
+//*** AMI PORTING END *****//
+#include EFI_PROTOCOL_DEFINITION (SimpleTextIn)
+//*** AMI PORTING BEGIN ***//
+//#include EFI_GUID_DEFINITION (StatusCodeCallerId)
+//#include EFI_GUID_DEFINITION (StatusCodeDataTypeId)
+//*** AMI PORTING END *****//
+
+//
+// Driver Produced Protocol Prototypes
+//
+#include EFI_PROTOCOL_DEFINITION (DriverBinding)
+#include EFI_PROTOCOL_DEFINITION (SimpleTextOut)
+
+//
+// VGA specific registers
+//
+#define CRTC_CURSOR_START 0xA
+#define CRTC_CURSOR_END 0xB
+
+#define CRTC_CURSOR_LOCATION_HIGH 0xE
+#define CRTC_CURSOR_LOCATION_LOW 0xF
+
+#define EFI_MAX_ATTRIBUTE 0x7f
+
+//
+// VGA Class Device Structure
+//
+#define VGA_CLASS_DEV_SIGNATURE EFI_SIGNATURE_32 ('V', 'G', 'A', 'C')
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ EFI_SIMPLE_TEXT_OUT_PROTOCOL SimpleTextOut;
+ EFI_SIMPLE_TEXT_OUTPUT_MODE SimpleTextOutputMode;
+ EFI_VGA_MINI_PORT_PROTOCOL *VgaMiniPort;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+} VGA_CLASS_DEV;
+
+#define VGA_CLASS_DEV_FROM_THIS(a) CR (a, VGA_CLASS_DEV, SimpleTextOut, VGA_CLASS_DEV_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_DRIVER_BINDING_PROTOCOL gVgaClassDriverBinding;
+
+//
+// Driver Binding Protocol functions
+//
+EFI_STATUS
+EFIAPI
+VgaClassDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Controller - GC_TODO: add argument description
+ RemainingDevicePath - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Controller - GC_TODO: add argument description
+ RemainingDevicePath - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Controller - GC_TODO: add argument description
+ NumberOfChildren - GC_TODO: add argument description
+ ChildHandleBuffer - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+//
+// Simple Text Output Protocol functions
+//
+EFI_STATUS
+EFIAPI
+VgaClassReset (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ExtendedVerification - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassOutputString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *WString
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ WString - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassTestString (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN CHAR16 *WString
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ WString - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassClearScreen (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassSetAttribute (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Attribute
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Attribute - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassSetCursorPosition (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Column - GC_TODO: add argument description
+ Row - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassEnableCursor (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN BOOLEAN Visible
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ Visible - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassQueryMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber,
+ OUT UINTN *Columns,
+ OUT UINTN *Rows
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ModeNumber - GC_TODO: add argument description
+ Columns - GC_TODO: add argument description
+ Rows - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+EFI_STATUS
+EFIAPI
+VgaClassSetMode (
+ IN EFI_SIMPLE_TEXT_OUT_PROTOCOL *This,
+ IN UINTN ModeNumber
+ )
+/*++
+
+Routine Description:
+
+ GC_TODO: Add function description
+
+Arguments:
+
+ This - GC_TODO: add argument description
+ ModeNumber - GC_TODO: add argument description
+
+Returns:
+
+ GC_TODO: add return values
+
+--*/
+;
+
+#endif
diff --git a/Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h b/Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h
new file mode 100644
index 0000000..e21a894
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/VgaMiniPort.h
@@ -0,0 +1,78 @@
+//
+// This file contains 'Framework Code' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may not be modified, except as allowed by
+// additional terms of your license agreement.
+//
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ VgaMiniPort.h
+
+Abstract:
+
+ Vga Mini port binding for a VGA controller
+
+Revision History
+
+--*/
+
+#ifndef _VGA_MINI_PORT_H
+#define _VGA_MINI_PORT_H
+
+#define EFI_VGA_MINI_PORT_PROTOCOL_GUID \
+ { \
+ 0xc7735a2f, 0x88f5, 0x4882, 0xae, 0x63, 0xfa, 0xac, 0x8c, 0x8b, 0x86, 0xb3 \
+ }
+
+EFI_FORWARD_DECLARATION (EFI_VGA_MINI_PORT_PROTOCOL);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_VGA_MINI_PORT_SET_MODE) (
+ IN EFI_VGA_MINI_PORT_PROTOCOL * This,
+ IN UINTN ModeNumber
+ );
+
+/*++
+
+ Routine Description:
+ Sets the text display mode of a VGA controller
+
+ Arguments:
+ This - Protocol instance pointer.
+ Mode - Mode number. 0 - 80x25 1-80x50
+
+ Returns:
+ EFI_SUCCESS - The mode was set
+ EFI_DEVICE_ERROR - The device is not functioning properly.
+
+--*/
+typedef struct _EFI_VGA_MINI_PORT_PROTOCOL {
+ EFI_VGA_MINI_PORT_SET_MODE SetMode;
+
+ UINT64 VgaMemoryOffset;
+ UINT64 CrtcAddressRegisterOffset;
+ UINT64 CrtcDataRegisterOffset;
+
+ UINT8 VgaMemoryBar;
+ UINT8 CrtcAddressRegisterBar;
+ UINT8 CrtcDataRegisterBar;
+
+ UINT8 MaxMode;
+} EFI_VGA_MINI_PORT_PROTOCOL;
+
+extern EFI_GUID gEfiVgaMiniPortProtocolGuid;
+
+#endif
diff --git a/Core/EM/CSM/thunk/CsmVideo/pci22.h b/Core/EM/CSM/thunk/CsmVideo/pci22.h
new file mode 100644
index 0000000..1c8ccd0
--- /dev/null
+++ b/Core/EM/CSM/thunk/CsmVideo/pci22.h
@@ -0,0 +1,621 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ pci22.h
+
+Abstract:
+ Support for PCI 2.2 standard.
+
+Revision History
+
+--*/
+
+#ifndef _PCI22_H
+#define _PCI22_H
+
+#define PCI_MAX_SEGMENT 0
+
+#define PCI_MAX_BUS 255
+
+#define PCI_MAX_DEVICE 31
+#define PCI_MAX_FUNC 7
+
+//
+// Command
+//
+#define PCI_VGA_PALETTE_SNOOP_DISABLED 0x20
+
+#pragma pack(push, 1)
+typedef struct {
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 Command;
+ UINT16 Status;
+ UINT8 RevisionID;
+ UINT8 ClassCode[3];
+ UINT8 CacheLineSize;
+ UINT8 LatencyTimer;
+ UINT8 HeaderType;
+ UINT8 BIST;
+} PCI_DEVICE_INDEPENDENT_REGION;
+
+typedef struct {
+ UINT32 Bar[6];
+ UINT32 CISPtr;
+ UINT16 SubsystemVendorID;
+ UINT16 SubsystemID;
+ UINT32 ExpansionRomBar;
+ UINT8 CapabilityPtr;
+ UINT8 Reserved1[3];
+ UINT32 Reserved2;
+ UINT8 InterruptLine;
+ UINT8 InterruptPin;
+ UINT8 MinGnt;
+ UINT8 MaxLat;
+} PCI_DEVICE_HEADER_TYPE_REGION;
+
+typedef struct {
+ PCI_DEVICE_INDEPENDENT_REGION Hdr;
+ PCI_DEVICE_HEADER_TYPE_REGION Device;
+} PCI_TYPE00;
+
+typedef struct {
+ UINT32 Bar[2];
+ UINT8 PrimaryBus;
+ UINT8 SecondaryBus;
+ UINT8 SubordinateBus;
+ UINT8 SecondaryLatencyTimer;
+ UINT8 IoBase;
+ UINT8 IoLimit;
+ UINT16 SecondaryStatus;
+ UINT16 MemoryBase;
+ UINT16 MemoryLimit;
+ UINT16 PrefetchableMemoryBase;
+ UINT16 PrefetchableMemoryLimit;
+ UINT32 PrefetchableBaseUpper32;
+ UINT32 PrefetchableLimitUpper32;
+ UINT16 IoBaseUpper16;
+ UINT16 IoLimitUpper16;
+ UINT8 CapabilityPtr;
+ UINT8 Reserved[3];
+ UINT32 ExpansionRomBAR;
+ UINT8 InterruptLine;
+ UINT8 InterruptPin;
+ UINT16 BridgeControl;
+} PCI_BRIDGE_CONTROL_REGISTER;
+
+typedef struct {
+ PCI_DEVICE_INDEPENDENT_REGION Hdr;
+ PCI_BRIDGE_CONTROL_REGISTER Bridge;
+} PCI_TYPE01;
+
+typedef union {
+ PCI_TYPE00 Device;
+ PCI_TYPE01 Bridge;
+} PCI_TYPE_GENERIC;
+
+typedef struct {
+ UINT32 CardBusSocketReg; // Cardus Socket/ExCA Base
+ // Address Register
+ //
+ UINT16 Reserved;
+ UINT16 SecondaryStatus; // Secondary Status
+ UINT8 PciBusNumber; // PCI Bus Number
+ UINT8 CardBusBusNumber; // CardBus Bus Number
+ UINT8 SubordinateBusNumber; // Subordinate Bus Number
+ UINT8 CardBusLatencyTimer; // CardBus Latency Timer
+ UINT32 MemoryBase0; // Memory Base Register 0
+ UINT32 MemoryLimit0; // Memory Limit Register 0
+ UINT32 MemoryBase1;
+ UINT32 MemoryLimit1;
+ UINT32 IoBase0;
+ UINT32 IoLimit0; // I/O Base Register 0
+ UINT32 IoBase1; // I/O Limit Register 0
+ UINT32 IoLimit1;
+ UINT8 InterruptLine; // Interrupt Line
+ UINT8 InterruptPin; // Interrupt Pin
+ UINT16 BridgeControl; // Bridge Control
+} PCI_CARDBUS_CONTROL_REGISTER;
+
+//
+// Definitions of PCI class bytes and manipulation macros.
+//
+#define PCI_CLASS_OLD 0x00
+#define PCI_CLASS_OLD_OTHER 0x00
+#define PCI_CLASS_OLD_VGA 0x01
+
+#define PCI_CLASS_MASS_STORAGE 0x01
+#define PCI_CLASS_MASS_STORAGE_SCSI 0x00
+#define PCI_CLASS_MASS_STORAGE_IDE 0x01 // obsolete
+#define PCI_CLASS_IDE 0x01
+#define PCI_CLASS_MASS_STORAGE_FLOPPY 0x02
+#define PCI_CLASS_MASS_STORAGE_IPI 0x03
+#define PCI_CLASS_MASS_STORAGE_RAID 0x04
+#define PCI_CLASS_MASS_STORAGE_OTHER 0x80
+
+#define PCI_CLASS_NETWORK 0x02
+#define PCI_CLASS_NETWORK_ETHERNET 0x00
+#define PCI_CLASS_ETHERNET 0x00 // obsolete
+#define PCI_CLASS_NETWORK_TOKENRING 0x01
+#define PCI_CLASS_NETWORK_FDDI 0x02
+#define PCI_CLASS_NETWORK_ATM 0x03
+#define PCI_CLASS_NETWORK_ISDN 0x04
+#define PCI_CLASS_NETWORK_OTHER 0x80
+
+#define PCI_CLASS_DISPLAY 0x03
+#define PCI_CLASS_DISPLAY_CTRL 0x03 // obsolete
+#define PCI_CLASS_DISPLAY_VGA 0x00
+#define PCI_CLASS_VGA 0x00 // obsolete
+#define PCI_CLASS_DISPLAY_XGA 0x01
+#define PCI_CLASS_DISPLAY_3D 0x02
+#define PCI_CLASS_DISPLAY_OTHER 0x80
+#define PCI_CLASS_DISPLAY_GFX 0x80
+#define PCI_CLASS_GFX 0x80 // obsolete
+#define PCI_CLASS_BRIDGE 0x06
+#define PCI_CLASS_BRIDGE_HOST 0x00
+#define PCI_CLASS_BRIDGE_ISA 0x01
+#define PCI_CLASS_ISA 0x01 // obsolete
+#define PCI_CLASS_BRIDGE_EISA 0x02
+#define PCI_CLASS_BRIDGE_MCA 0x03
+#define PCI_CLASS_BRIDGE_P2P 0x04
+#define PCI_CLASS_BRIDGE_PCMCIA 0x05
+#define PCI_CLASS_BRIDGE_NUBUS 0x06
+#define PCI_CLASS_BRIDGE_CARDBUS 0x07
+#define PCI_CLASS_BRIDGE_RACEWAY 0x08
+#define PCI_CLASS_BRIDGE_ISA_PDECODE 0x80
+#define PCI_CLASS_ISA_POSITIVE_DECODE 0x80 // obsolete
+
+#define PCI_CLASS_SCC 0x07 // Simple communications controllers
+#define PCI_SUBCLASS_SERIAL 0x00
+#define PCI_IF_GENERIC_XT 0x00
+#define PCI_IF_16450 0x01
+#define PCI_IF_16550 0x02
+#define PCI_IF_16650 0x03
+#define PCI_IF_16750 0x04
+#define PCI_IF_16850 0x05
+#define PCI_IF_16950 0x06
+#define PCI_SUBCLASS_PARALLEL 0x01
+#define PCI_IF_PARALLEL_PORT 0x00
+#define PCI_IF_BI_DIR_PARALLEL_PORT 0x01
+#define PCI_IF_ECP_PARALLEL_PORT 0x02
+#define PCI_IF_1284_CONTROLLER 0x03
+#define PCI_IF_1284_DEVICE 0xFE
+#define PCI_SUBCLASS_MULTIPORT_SERIAL 0x02
+#define PCI_SUBCLASS_MODEM 0x03
+#define PCI_IF_GENERIC_MODEM 0x00
+#define PCI_IF_16450_MODEM 0x01
+#define PCI_IF_16550_MODEM 0x02
+#define PCI_IF_16650_MODEM 0x03
+#define PCI_IF_16750_MODEM 0x04
+#define PCI_SUBCLASS_OTHER 0x80
+
+#define PCI_CLASS_SYSTEM_PERIPHERAL 0x08
+#define PCI_SUBCLASS_PIC 0x00
+#define PCI_IF_8259_PIC 0x00
+#define PCI_IF_ISA_PIC 0x01
+#define PCI_IF_EISA_PIC 0x02
+#define PCI_IF_APIC_CONTROLLER 0x10 // I/O APIC interrupt controller , 32 bye none-prefectable memory.
+#define PCI_IF_APIC_CONTROLLER2 0x20
+#define PCI_SUBCLASS_TIMER 0x02
+#define PCI_IF_8254_TIMER 0x00
+#define PCI_IF_ISA_TIMER 0x01
+#define PCI_EISA_TIMER 0x02
+#define PCI_SUBCLASS_RTC 0x03
+#define PCI_IF_GENERIC_RTC 0x00
+#define PCI_IF_ISA_RTC 0x00
+#define PCI_SUBCLASS_PNP_CONTROLLER 0x04 // HotPlug Controller
+
+#define PCI_CLASS_INPUT_DEVICE 0x09
+#define PCI_SUBCLASS_KEYBOARD 0x00
+#define PCI_SUBCLASS_PEN 0x01
+#define PCI_SUBCLASS_MOUSE_CONTROLLER 0x02
+#define PCI_SUBCLASS_SCAN_CONTROLLER 0x03
+#define PCI_SUBCLASS_GAMEPORT 0x04
+
+#define PCI_CLASS_DOCKING_STATION 0x0A
+
+#define PCI_CLASS_PROCESSOR 0x0B
+#define PCI_SUBCLASS_PROC_386 0x00
+#define PCI_SUBCLASS_PROC_486 0x01
+#define PCI_SUBCLASS_PROC_PENTIUM 0x02
+#define PCI_SUBCLASS_PROC_ALPHA 0x10
+#define PCI_SUBCLASS_PROC_POWERPC 0x20
+#define PCI_SUBCLASS_PROC_MIPS 0x30
+#define PCI_SUBCLASS_PROC_CO_PORC 0x40 // Co-Processor
+
+#define PCI_CLASS_SERIAL 0x0C
+#define PCI_CLASS_SERIAL_FIREWIRE 0x00
+#define PCI_CLASS_SERIAL_ACCESS_BUS 0x01
+#define PCI_CLASS_SERIAL_SSA 0x02
+#define PCI_CLASS_SERIAL_USB 0x03
+#define PCI_CLASS_SERIAL_FIBRECHANNEL 0x04
+#define PCI_CLASS_SERIAL_SMB 0x05
+
+#define PCI_CLASS_WIRELESS 0x0D
+#define PCI_SUBCLASS_IRDA 0x00
+#define PCI_SUBCLASS_IR 0x01
+#define PCI_SUBCLASS_RF 0x02
+
+#define PCI_CLASS_INTELLIGENT_IO 0x0E
+
+#define PCI_CLASS_SATELLITE 0x0F
+#define PCI_SUBCLASS_TV 0x01
+#define PCI_SUBCLASS_AUDIO 0x02
+#define PCI_SUBCLASS_VOICE 0x03
+#define PCI_SUBCLASS_DATA 0x04
+
+#define PCI_SECURITY_CONTROLLER 0x10 // Encryption and decryption controller
+#define PCI_SUBCLASS_NET_COMPUT 0x00
+#define PCI_SUBCLASS_ENTERTAINMENT 0x10
+
+#define PCI_CLASS_DPIO 0x11
+
+#define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c))
+#define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s)))
+#define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p)))
+
+#define IS_PCI_DISPLAY(_p) IS_CLASS1 (_p, PCI_CLASS_DISPLAY)
+#define IS_PCI_VGA(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 0)
+#define IS_PCI_8514(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_VGA, 1)
+#define IS_PCI_GFX(_p) IS_CLASS3 (_p, PCI_CLASS_DISPLAY, PCI_CLASS_DISPLAY_GFX, 0)
+#define IS_PCI_OLD(_p) IS_CLASS1 (_p, PCI_CLASS_OLD)
+#define IS_PCI_OLD_VGA(_p) IS_CLASS2 (_p, PCI_CLASS_OLD, PCI_CLASS_OLD_VGA)
+#define IS_PCI_IDE(_p) IS_CLASS2 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_IDE)
+#define IS_PCI_SCSI(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_SCSI, 0)
+#define IS_PCI_RAID(_p) IS_CLASS3 (_p, PCI_CLASS_MASS_STORAGE, PCI_CLASS_MASS_STORAGE_RAID, 0)
+#define IS_PCI_LPC(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_ISA, 0)
+#define IS_PCI_P2P(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 0)
+#define IS_PCI_P2P_SUB(_p) IS_CLASS3 (_p, PCI_CLASS_BRIDGE, PCI_CLASS_BRIDGE_P2P, 1)
+#define IS_PCI_USB(_p) IS_CLASS2 (_p, PCI_CLASS_SERIAL, PCI_CLASS_SERIAL_USB)
+
+#define HEADER_TYPE_DEVICE 0x00
+#define HEADER_TYPE_PCI_TO_PCI_BRIDGE 0x01
+#define HEADER_TYPE_CARDBUS_BRIDGE 0x02
+
+#define HEADER_TYPE_MULTI_FUNCTION 0x80
+#define HEADER_LAYOUT_CODE 0x7f
+
+#define IS_PCI_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_PCI_TO_PCI_BRIDGE))
+#define IS_CARDBUS_BRIDGE(_p) (((_p)->Hdr.HeaderType & HEADER_LAYOUT_CODE) == (HEADER_TYPE_CARDBUS_BRIDGE))
+#define IS_PCI_MULTI_FUNC(_p) ((_p)->Hdr.HeaderType & HEADER_TYPE_MULTI_FUNCTION)
+
+#define PCI_DEVICE_ROMBAR 0x30
+#define PCI_BRIDGE_ROMBAR 0x38
+
+#define PCI_MAX_BAR 0x0006
+#define PCI_MAX_CONFIG_OFFSET 0x0100
+
+#define PCI_VENDOR_ID_OFFSET 0x00
+#define PCI_DEVICE_ID_OFFSET 0x02
+#define PCI_COMMAND_OFFSET 0x04
+#define PCI_PRIMARY_STATUS_OFFSET 0x06
+#define PCI_REVISION_ID_OFFSET 0x08
+#define PCI_CLASSCODE_OFFSET 0x09
+#define PCI_CACHELINE_SIZE_OFFSET 0x0C
+#define PCI_LATENCY_TIMER_OFFSET 0x0D
+#define PCI_HEADER_TYPE_OFFSET 0x0E
+#define PCI_BIST_OFFSET 0x0F
+#define PCI_BASE_ADDRESSREG_OFFSET 0x10
+#define PCI_CARDBUS_CIS_OFFSET 0x28
+#define PCI_SVID_OFFSET 0x2C // SubSystem Vendor id
+#define PCI_SUBSYSTEM_VENDOR_ID_OFFSET 0x2C
+#define PCI_SID_OFFSET 0x2E // SubSystem ID
+#define PCI_SUBSYSTEM_ID_OFFSET 0x2E
+#define PCI_EXPANSION_ROM_BASE 0x30
+#define PCI_CAPBILITY_POINTER_OFFSET 0x34
+#define PCI_INT_LINE_OFFSET 0x3C // Interrupt Line Register
+#define PCI_INT_PIN_OFFSET 0x3D // Interrupt Pin Register
+#define PCI_MAXGNT_OFFSET 0x3E // Max Grant Register
+#define PCI_MAXLAT_OFFSET 0x3F // Max Latency Register
+
+#define PCI_BRIDGE_CONTROL_REGISTER_OFFSET 0x3E
+#define PCI_BRIDGE_STATUS_REGISTER_OFFSET 0x1E
+
+#define PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET 0x18
+#define PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET 0x19
+#define PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET 0x1a
+
+typedef struct {
+ UINT32 Reg : 8;
+ UINT32 Func : 3;
+ UINT32 Dev : 5;
+ UINT32 Bus : 8;
+ UINT32 Reserved : 7;
+ UINT32 Enable : 1;
+} PCI_CONFIG_ACCESS_CF8;
+
+#pragma pack()
+
+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55
+#define PCI_DATA_STRUCTURE_SIGNATURE EFI_SIGNATURE_32 ('P', 'C', 'I', 'R')
+#define PCI_CODE_TYPE_PCAT_IMAGE 0x00
+#define PCI_CODE_TYPE_EFI_IMAGE 0x03
+#define EFI_PCI_EXPANSION_ROM_HEADER_COMPRESSED 0x0001
+
+#define EFI_PCI_COMMAND_IO_SPACE 0x0001
+#define EFI_PCI_COMMAND_MEMORY_SPACE 0x0002
+#define EFI_PCI_COMMAND_BUS_MASTER 0x0004
+#define EFI_PCI_COMMAND_SPECIAL_CYCLE 0x0008
+#define EFI_PCI_COMMAND_MEMORY_WRITE_AND_INVALIDATE 0x0010
+#define EFI_PCI_COMMAND_VGA_PALETTE_SNOOP 0x0020
+#define EFI_PCI_COMMAND_PARITY_ERROR_RESPOND 0x0040
+#define EFI_PCI_COMMAND_STEPPING_CONTROL 0x0080
+#define EFI_PCI_COMMAND_SERR 0x0100
+#define EFI_PCI_COMMAND_FAST_BACK_TO_BACK 0x0200
+
+#define EFI_PCI_BRIDGE_CONTROL_PARITY_ERROR_RESPONSE 0x0001
+#define EFI_PCI_BRIDGE_CONTROL_SERR 0x0002
+#define EFI_PCI_BRIDGE_CONTROL_ISA 0x0004
+#define EFI_PCI_BRIDGE_CONTROL_VGA 0x0008
+#define EFI_PCI_BRIDGE_CONTROL_VGA_16 0x0010
+#define EFI_PCI_BRIDGE_CONTROL_MASTER_ABORT 0x0020
+#define EFI_PCI_BRIDGE_CONTROL_RESET_SECONDARY_BUS 0x0040
+#define EFI_PCI_BRIDGE_CONTROL_FAST_BACK_TO_BACK 0x0080
+#define EFI_PCI_BRIDGE_CONTROL_PRIMARY_DISCARD_TIMER 0x0100
+#define EFI_PCI_BRIDGE_CONTROL_SECONDARY_DISCARD_TIMER 0x0200
+#define EFI_PCI_BRIDGE_CONTROL_TIMER_STATUS 0x0400
+#define EFI_PCI_BRIDGE_CONTROL_DISCARD_TIMER_SERR 0x0800
+
+//
+// Following are the PCI-CARDBUS bridge control bit
+//
+#define EFI_PCI_BRIDGE_CONTROL_IREQINT_ENABLE 0x0080
+#define EFI_PCI_BRIDGE_CONTROL_RANGE0_MEMORY_TYPE 0x0100
+#define EFI_PCI_BRIDGE_CONTROL_RANGE1_MEMORY_TYPE 0x0200
+#define EFI_PCI_BRIDGE_CONTROL_WRITE_POSTING_ENABLE 0x0400
+
+//
+// Following are the PCI status control bit
+//
+#define EFI_PCI_STATUS_CAPABILITY 0x0010
+#define EFI_PCI_STATUS_66MZ_CAPABLE 0x0020
+#define EFI_PCI_FAST_BACK_TO_BACK_CAPABLE 0x0080
+#define EFI_PCI_MASTER_DATA_PARITY_ERROR 0x0100
+
+#define EFI_PCI_CAPABILITY_PTR 0x34
+#define EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR 0x14
+
+#pragma pack(1)
+typedef struct {
+ UINT16 Signature; // 0xaa55
+ UINT8 Reserved[0x16];
+ UINT16 PcirOffset;
+} PCI_EXPANSION_ROM_HEADER;
+
+typedef struct {
+ UINT16 Signature; // 0xaa55
+ UINT8 Size512;
+ UINT8 InitEntryPoint[3];
+ UINT8 Reserved[0x12];
+ UINT16 PcirOffset;
+} EFI_LEGACY_EXPANSION_ROM_HEADER;
+
+typedef struct {
+ UINT32 Signature; // "PCIR"
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 Reserved0;
+ UINT16 Length;
+ UINT8 Revision;
+ UINT8 ClassCode[3];
+ UINT16 ImageLength;
+ UINT16 CodeRevision;
+ UINT8 CodeType;
+ UINT8 Indicator;
+ UINT16 Reserved1;
+} PCI_DATA_STRUCTURE;
+
+//
+// PCI Capability List IDs and records
+//
+#define EFI_PCI_CAPABILITY_ID_PMI 0x01
+#define EFI_PCI_CAPABILITY_ID_AGP 0x02
+#define EFI_PCI_CAPABILITY_ID_VPD 0x03
+#define EFI_PCI_CAPABILITY_ID_SLOTID 0x04
+#define EFI_PCI_CAPABILITY_ID_MSI 0x05
+#define EFI_PCI_CAPABILITY_ID_HOTPLUG 0x06
+#define EFI_PCI_CAPABILITY_ID_PCIX 0x07
+
+typedef struct {
+ UINT8 CapabilityID;
+ UINT8 NextItemPtr;
+} EFI_PCI_CAPABILITY_HDR;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_PMI
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 PMC;
+ UINT16 PMCSR;
+ UINT8 BridgeExtention;
+ UINT8 Data;
+} EFI_PCI_CAPABILITY_PMI;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_AGP
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT8 Rev;
+ UINT8 Reserved;
+ UINT32 Status;
+ UINT32 Command;
+} EFI_PCI_CAPABILITY_AGP;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_VPD
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 AddrReg;
+ UINT32 DataReg;
+} EFI_PCI_CAPABILITY_VPD;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_SLOTID
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT8 ExpnsSlotReg;
+ UINT8 ChassisNo;
+} EFI_PCI_CAPABILITY_SLOTID;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_MSI
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 MsgCtrlReg;
+ UINT32 MsgAddrReg;
+ UINT16 MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI32;
+
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 MsgCtrlReg;
+ UINT32 MsgAddrRegLsdw;
+ UINT32 MsgAddrRegMsdw;
+ UINT16 MsgDataReg;
+} EFI_PCI_CAPABILITY_MSI64;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_HOTPLUG
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ //
+ // not finished - fields need to go here
+ //
+} EFI_PCI_CAPABILITY_HOTPLUG;
+
+//
+// Capability EFI_PCI_CAPABILITY_ID_PCIX
+//
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 CommandReg;
+ UINT32 StatusReg;
+} EFI_PCI_CAPABILITY_PCIX;
+
+typedef struct {
+ EFI_PCI_CAPABILITY_HDR Hdr;
+ UINT16 SecStatusReg;
+ UINT32 StatusReg;
+ UINT32 SplitTransCtrlRegUp;
+ UINT32 SplitTransCtrlRegDn;
+} EFI_PCI_CAPABILITY_PCIX_BRDG;
+
+#define DEVICE_ID_NOCARE 0xFFFF
+
+#define PCI_ACPI_UNUSED 0
+#define PCI_BAR_NOCHANGE 0
+#define PCI_BAR_OLD_ALIGN 0xFFFFFFFFFFFFFFFF
+#define PCI_BAR_EVEN_ALIGN 0xFFFFFFFFFFFFFFFE
+#define PCI_BAR_SQUAD_ALIGN 0xFFFFFFFFFFFFFFFD
+#define PCI_BAR_DQUAD_ALIGN 0xFFFFFFFFFFFFFFFC
+
+#define PCI_BAR_IDX0 0x00
+#define PCI_BAR_IDX1 0x01
+#define PCI_BAR_IDX2 0x02
+#define PCI_BAR_IDX3 0x03
+#define PCI_BAR_IDX4 0x04
+#define PCI_BAR_IDX5 0x05
+#define PCI_BAR_ALL 0xFF
+
+#pragma pack(pop)
+
+//
+// NOTE: The following header files are included here for
+// compatibility consideration.
+//
+//*** AMI PORTING BEGIN ***//
+//Include content
+//#include "pci23.h"
+#define PCI_EXP_MAX_CONFIG_OFFSET 0x1000
+#define EFI_PCI_CAPABILITY_ID_PCIEXP 0x10
+
+//#include "pci30.h"
+#define PCI_CLASS_MASS_STORAGE_SATADPA 0x06
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 Signature; // "PCIR"
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 DeviceListOffset;
+ UINT16 Length;
+ UINT8 Revision;
+ UINT8 ClassCode[3];
+ UINT16 ImageLength;
+ UINT16 CodeRevision;
+ UINT8 CodeType;
+ UINT8 Indicator;
+ UINT16 MaxRuntimeImageLength;
+ UINT16 ConfigUtilityCodeHeaderOffset;
+ UINT16 DMTFCLPEntryPointOffset;
+} PCI_3_0_DATA_STRUCTURE;
+
+#pragma pack(pop)
+
+//#include "EfiPci.h"
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 Register;
+ UINT8 Function;
+ UINT8 Device;
+ UINT8 Bus;
+ UINT8 Reserved[4];
+} DEFIO_PCI_ADDR;
+
+#define EFI_ROOT_BRIDGE_LIST 'eprb'
+#define EFI_PCI_EXPANSION_ROM_HEADER_EFISIGNATURE 0x0EF1
+
+typedef struct {
+ UINT16 Signature; // 0xaa55
+ UINT16 InitializationSize;
+ UINT32 EfiSignature; // 0x0EF1
+ UINT16 EfiSubsystem;
+ UINT16 EfiMachineType;
+ UINT16 CompressionType;
+ UINT8 Reserved[8];
+ UINT16 EfiImageHeaderOffset;
+ UINT16 PcirOffset;
+} EFI_PCI_EXPANSION_ROM_HEADER;
+
+typedef union {
+ UINT8 *Raw;
+ PCI_EXPANSION_ROM_HEADER *Generic;
+ EFI_PCI_EXPANSION_ROM_HEADER *Efi;
+ EFI_LEGACY_EXPANSION_ROM_HEADER *PcAt;
+} EFI_PCI_ROM_HEADER;
+
+#pragma pack(pop)
+//*** AMI PORTING END *****//
+#endif
diff --git a/Core/EM/CSM/thunk/Snp16/snp16.cif b/Core/EM/CSM/thunk/Snp16/snp16.cif
new file mode 100644
index 0000000..632b1c5
--- /dev/null
+++ b/Core/EM/CSM/thunk/Snp16/snp16.cif
@@ -0,0 +1,8 @@
+<component>
+ name = "SNP16"
+ category = ModulePart
+ LocalRoot = "core\em\csm\thunk\Snp16"
+ RefName = "BIOSSNP16"
+[files]
+[parts]
+<endComponent>
diff --git a/Core/EM/CSM/thunk/thunk.cif b/Core/EM/CSM/thunk/thunk.cif
new file mode 100644
index 0000000..4e0af2e
--- /dev/null
+++ b/Core/EM/CSM/thunk/thunk.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "CSM Thunk"
+ category = ModulePart
+ LocalRoot = "core\em\csm\thunk"
+ RefName = "THUNK"
+[parts]
+"X86THUNK"
+"BIOSBLKIO"
+"BIOSSNP16"
+"CsmVideo"
+<endComponent>
diff --git a/Core/EM/CSM/thunk/x86/thunk.c b/Core/EM/CSM/thunk/x86/thunk.c
new file mode 100644
index 0000000..57233e4
--- /dev/null
+++ b/Core/EM/CSM/thunk/x86/thunk.c
@@ -0,0 +1,793 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/x86/thunk.c 49 10/07/13 9:41a Olegi $
+//
+// $Revision: 49 $
+//
+// $Date: 10/07/13 9:41a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/x86/thunk.c $
+//
+// 49 10/07/13 9:41a Olegi
+// Undone previous checkin related to EIP125856 as it is causing assert
+// during boot.
+//
+// 48 8/30/13 4:25a Srikantakumarp
+// [TAG] EIP125856
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Assert came in SetKbcPresenceInMiscInfo() when FarCall86()
+// function is called first time in POST.
+// [RootCause] BiosLessThan1MB value is used in
+// SetKbcPresenceInMiscInfo(); and this has been initialized only after
+// the function 0 csm16 call.
+// [Solution] Returned from SetKbcPresenceInMiscInfo() if
+// BiosLessThan1MB value is not initialized.
+// [Files] thunk.c
+//
+// 47 9/12/12 1:45a Srikantakumarp
+// [TAG] EIP99561
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] KbcEmulation enabled in Int86 call but NO_KBC_PRESENT_BIT
+// bit not set properly.
+// [RootCause] Incase of INT86 , it directly calls the interrupt service
+// routine and it might be that the NO_KBC_PRESENT_BIT is not set
+// according to the KbcEmulation enabled or disabled.
+// [Solution] The NO_KBC_PRESENT_BIT is set according to the
+// KbcEmulation enabled or disabled before the call to thunk in Int86
+// function in thunk.c.
+// [Files] thunk.c
+//
+// 46 3/02/12 3:24a Rameshr
+// [TAG] EIP81041
+// [Category] Improvement
+// [Description] Re-entrance support for Farcall86 and Int86 protocol
+// function
+// [Files] thunk.c
+//
+// 45 10/19/11 3:31p Olegi
+// [TAG] EIP72642, 72645, 72810
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Adaptec x805 SAS Option ROM code hangs
+// [RootCause] Adaptec ROM has a code that directly access KBC during
+// INT handler. We did not have KBC emulation enabled for Int86 function.
+// [Solution] Added enabling KBC emulation in Int86 function.
+// [Files] thunk.c
+//
+// 44 9/29/11 11:00a Olegi
+// [TAG] EIP70382
+// [Category] Improvement
+// [Description] Clear keyboard status in BDA after FarCall86 execution.
+// [Files] thunk.c
+//
+// 43 12/14/10 4:46p Olegi
+// [TAG] EIP50111
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TPL asserts in some cases during LegacyBoot
+// [RootCause] TPL.C asserts during LocateHandleBuffer call executed
+// during LegacyBoot from FarCall86.
+// [Solution] removed a call GetPs2SimpleTextInProtocolInterface
+// execution during FarCall86. The existing handle of Ps2SimpleTextIn will
+// be used.
+// [Files] thunk.c
+//
+// 42 10/23/10 3:22p Olegi
+// Undone the changes related to moving TPL raising/lowering outside of
+// FarCall86. This made the IF to be active during thunk that caused
+// various problems.
+//
+// 41 8/17/10 2:26p Olegi
+// Reset PS/2 keyboard before legacy boot. EIP40711
+//
+// 40 7/25/10 2:43p Olegi
+// RaiseTPL/RestroreTPL are moved from FarCall86 to the ASM area.
+//
+// 39 7/19/10 4:44p Olegi
+//
+// 38 6/28/10 5:04p Olegi
+// EIP26277: Added a callback notification on
+// NonSmmEmul6064TrapProtocolGuid installation.
+//
+// 37 6/19/10 12:32p Olegi
+// Temporary undone the resolution for EIP26277 until the final resolution
+// is found. Current changes causes ASSERT due to LocateHandle is executed
+// on TPL_LEVEL_HIGH.
+//
+// 36 2/22/10 9:46a Olegi
+// Fixed the problem where some keys pressed on USB keyboard are lost
+// during the transition to OpROM. EIP26277
+//
+// 35 1/18/10 3:41a Rameshr
+// NumLock,Capslock,Scroll Lock LED's synced properly between EFI and
+// Legacy Mode.
+// EIP 27917
+//
+// 34 1/12/10 11:47a Olegi
+// Copyright message updated.
+//
+// 33 9/23/09 11:13a Olegi
+// Changed the global variable name according to the coding standard.
+//
+// 32 9/09/09 3:11p Davidd
+// Fixed hanging problem when USB is disabled by the newly added "USB
+// Support" setup question - EIP 25360
+//
+// 31 2/05/09 12:28p Olegi
+//
+// 30 2/04/09 5:30p Olegi
+// Several modifications in FarCall86:
+// - PIC SetMode is moved after raising TPL to highest level (cli)
+// - Set Pmode interrupt mask to FF before setting Rmode mask. That avoids
+// the problem where IVT is not yet set in real mode (before Func#0) and
+// some HW interrupt is pending.
+//
+// 29 11/13/08 10:00a Olegi
+// Reverse thunk implementation started.
+//
+// 28 11/07/08 4:04p Rameshraju
+// Removed unused code.
+//
+// 27 11/07/08 4:01p Rameshraju
+// BugFix- Sometime system hangs on S4 resume.
+// Fix Reason : If the Timer interrupt generates between CLI and Timer
+// Interrupt mask code, Next STI instruction try to services the Timer
+// interrupt.In this case before setting IVT system will hang
+// EIP:17401
+//
+// 26 6/12/08 8:14a Olegi
+// Modified FarCall86 to execute USB keyboard change mode code for CSM16
+// function #5 (EIP14051).
+//
+// 25 8/27/07 12:44p Olegi
+//
+// 23 6/28/07 4:14p Olegi
+//
+// 22 6/25/07 12:27p Olegi
+//
+// 21 6/18/07 5:54p Olegi
+//
+// 20 5/29/07 6:17p Olegi
+// Added UsbChangeEfiToLegacy call.
+//
+// 19 4/27/07 5:14p Olegi
+// CSM.CHM file preparation.
+//
+// 18 8/24/06 6:56p Felixp
+//
+// 17 8/24/06 6:55p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 16 8/24/06 3:11p Felixp
+// Preliminary x64 support (work in progress)
+//
+// 15 7/28/06 4:45p Olegi
+//
+// 14 5/19/06 11:22p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 13 3/13/06 2:35p Felixp
+//
+// 12 10/13/05 6:19p Olegi
+// Added condition to a previous change.
+//
+// 11 10/11/05 4:20p Srinin
+// PS2 KBD reset function is called after CM16 function 2, 3 and 5 are
+// called.
+//
+// 10 8/25/05 10:28a Olegi
+// Previous changes undone - instead the vector base for the master 8259
+// is changed from 0x68 to 0x58; with this there is no need to preserve
+// and restore IVT.
+//
+// 8 3/04/05 1:47p Mandal
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Thunk.c
+//
+// Description: 32/64 bit to 16 bit code thunk implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Protocol\DevicePath.h>
+#include <Protocol\LegacyBios.h>
+#include <Protocol\Legacy8259.h>
+#include <Protocol\SimpleTextin.h>
+#include <protocol\FirmwareVolume.h >
+#include <Ffs.h>
+#include "csm.h"
+#include <AmiDxeLib.h>
+#include "token.h"
+#if defined(AMIUSB_SUPPORT)
+#include <protocol\amiusbcontroller.h>
+#endif
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\AmiKeycode.h>
+
+
+#pragma pack(1)
+typedef struct {
+ UINT16 Offset;
+ UINT16 Segment;
+} FAR_CALL_PTR_16;
+
+typedef struct {
+ UINT32 Stack;
+ UINT32 StackSize;
+} STACK;
+
+typedef struct {
+ FAR_CALL_PTR_16 FarCall;
+ EFI_IA32_REGISTER_SET Regs;
+ STACK Stack;
+ BOOLEAN isFarCall; //if false, then INT86.
+ UINT8 BiosInt;
+} THUNK_DATA;
+
+typedef struct _ACPI_PNPID {
+ UINT32 Signature :16;
+ UINT32 PnpID :16;
+} ACPI_PNPID;
+#pragma pack()
+
+
+#if defined(AMIUSB_SUPPORT)
+EFI_USB_PROTOCOL *gUsbProtocol = NULL;
+#endif
+AMI_EFIKEYCODE_PROTOCOL *pKeyCodeProtocol=NULL;
+
+EFI_SIMPLE_TEXT_INPUT_PROTOCOL *gPS2KBDInterface = NULL;
+EFI_GUID gCsmThunkGuid = {
+ 0xA08276EC,0xA0FE,0x4e06,0x86,0x70,0x38,0x53,0x36,0xC7,0xD0,0x93
+};
+
+EFI_LEGACY_8259_PROTOCOL *gLegacy8259;
+extern BIOS_INFO *CoreBiosInfo;
+
+UINTN gThunkAsmAddr;
+extern BOOLEAN gIsBootPrepared;
+BOOLEAN gInsideThunk = FALSE;
+
+EFI_STATUS GetPs2SimpleTextInProtocolInterface(
+ BIOS_INFO *This,
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL **PS2KBDInterface
+);
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SetKbcPresenceInMiscInfo
+//
+// Description: Updates CSM16_NO_KBC_PRESENT_BIT of MiscInfoAddress accordingly
+// by checking if the KbcEmulation is Enabled or Disabled.
+//
+// Input:
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SetKbcPresenceInMiscInfo()
+{
+ EFI_TO_COMPATIBILITY16_INIT_TABLE *Csm16InitTable;
+ LEGACY16_TO_EFI_DATA_TABLE_STRUC *Csm16Data;
+ UINT8 KbcSupport,KbcCheck=0;
+ EFI_STATUS Status;
+
+ //
+ // Retrieving the Data at MiscInfoAddress
+ //
+ Csm16InitTable = &CoreBiosInfo->Thunk->Csm16InitTable;
+ Csm16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)Csm16InitTable->BiosLessThan1MB;
+
+ KbcCheck = *(UINT8*)(UINTN)Csm16Data->MiscInfoAddress;
+
+ //
+ // Setting/Resetting the CSM16_NO_KBC_PRESENT_BIT according to the KbcEmulation
+ //
+ KbcSupport = IoRead8(0x64);
+ if (KbcSupport != 0xff) {
+ KbcCheck &= ~(CSM16_NO_KBC_PRESENT_BIT);
+ }
+ else {
+ KbcCheck |= (CSM16_NO_KBC_PRESENT_BIT);
+ }
+ //
+ // Checking if the Data at MiscInfoAddress is already updated
+ //
+ if((*(UINT8*)(UINTN)Csm16Data->MiscInfoAddress) != KbcCheck){
+ //
+ // Checking if F0000 region is writable
+ //
+ *(UINT8*)(UINTN)Csm16Data->MiscInfoAddress = KbcCheck;
+
+ if((*(UINT8*)(UINTN)Csm16Data->MiscInfoAddress) == KbcCheck){
+ return;
+ }
+ else{
+ //
+ // Unlocking the region 0xE0000 - 0xFFFFF
+ //
+ Status = CoreBiosInfo->iRegion->UnLock (CoreBiosInfo->iRegion,
+ 0xE0000,
+ 0x20000,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Updating the Data at MiscInfoAddress
+ //
+ *(UINT8*)(UINTN)Csm16Data->MiscInfoAddress = KbcCheck;
+
+ //
+ // Locking the region 0xE0000 - 0xFFFFF
+ //
+ CoreBiosInfo->iRegion->Lock (CoreBiosInfo->iRegion,
+ 0xE0000,
+ 0x20000,
+ NULL);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Int86
+//
+// Description: Executes BIOS interrupt routine
+//
+// Input:
+// LegacyBios protocol instance pointer
+// BiosInt Interrupt number
+// Regs CPU register values to pass to the interrupt handler
+//
+// Output:
+// TRUE Interrupt was not executed
+// FALSE INT completed. Caller will see Regs for status
+//
+// Referrals: EFI_IA32_REGISTER_SET
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN Int86(
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINT8 BiosInt,
+ IN OUT EFI_IA32_REGISTER_SET *Regs
+)
+{
+ EFI_TPL OldTpl;
+
+ THUNK_DATA *ThunkData = (THUNK_DATA*)(gThunkAsmAddr+6);
+ //
+ // To avoid reentrance in Int86
+ //
+ if(gInsideThunk){
+ return FALSE;
+ }
+ gInsideThunk = TRUE;
+ ThunkData->isFarCall = FALSE;
+ ThunkData->BiosInt = BiosInt;
+ ThunkData->Stack.StackSize = 0; //This is required
+
+
+ //Copy thunk registers.
+ ThunkData->Regs = *Regs;
+
+#if defined(AMIUSB_SUPPORT)
+{
+ EFI_STATUS Status;
+
+ if (gUsbProtocol == NULL) {
+ Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &gUsbProtocol);
+ if (EFI_ERROR(Status)) {
+ gUsbProtocol=NULL; // To be used later, after returning from INT
+ }
+ }
+ if (gUsbProtocol != NULL) {
+ gUsbProtocol->UsbChangeEfiToLegacy(1);
+ }
+}
+#endif
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ gLegacy8259->SetMode(gLegacy8259,Efi8259LegacyMode,NULL,NULL);
+
+ SetKbcPresenceInMiscInfo();
+
+ ((void(*)(UINTN))gThunkAsmAddr)(gThunkAsmAddr);
+
+#if defined(AMIUSB_SUPPORT)
+ if (gUsbProtocol) {
+ gUsbProtocol->UsbChangeEfiToLegacy(0);
+ }
+#endif
+
+ gLegacy8259->SetMode(gLegacy8259,Efi8259ProtectedMode,NULL,NULL);
+ pBS->RestoreTPL(OldTpl);
+
+ //Restore thunk registers.
+ *Regs = ThunkData->Regs;
+ gInsideThunk = FALSE;
+
+ return FALSE; // INT completed. Caller will see Regs for status.
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FarCall86
+//
+// Description: Executes 16 bit code starting from a given address
+//
+// Input:
+// This LegacyBiosProtocol instance pointer
+// Segment, Offset Starting address of the 16 bit routine
+// Regs CPU register values to pass to the routine
+// Stack Stack pointer with the possible data to be passed to the routine
+// StackSize Size of the stack passed to the routine
+//
+// Output:
+// TRUE Call was not executed
+// FALSE Call completed. Caller will see Regs for status
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN FarCall86(
+ IN EFI_LEGACY_BIOS_PROTOCOL *This,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN EFI_IA32_REGISTER_SET *Regs,
+ IN VOID *Stack,
+ IN UINTN StackSize
+)
+{
+ EFI_TPL OldTpl;
+ UINT16 IrqMask, SaveIrqMask;
+ UINT16 ProtectedIrqMask, ProtectedSaveIrqMask;
+ THUNK_DATA *ThunkData = (THUNK_DATA*)(gThunkAsmAddr+6);
+ UINT16 FuncNumber;
+ BOOLEAN IsCsm16Call =
+ Segment == CoreBiosInfo->Csm16EntrySeg &&
+ CoreBiosInfo->Csm16EntryOfs == Offset;
+ BOOLEAN IsCsm16DispatchOpRom = IsCsm16Call &&
+ Regs->X.AX == Compatibility16DispatchOprom;
+
+ BOOLEAN IsCsm16LegacyBoot = IsCsm16Call &&
+ Regs->X.AX == Compatibility16Boot;
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_KEY_TOGGLE_STATE KeyToggleState=0;
+ //
+ // To avoid reentrance in FarCall86
+ //
+ if(gInsideThunk){
+ return FALSE;
+ }
+
+ gInsideThunk = TRUE;
+
+ //
+ // Change USB operation mode indicator from EFI to Legacy
+ //
+#if defined(AMIUSB_SUPPORT)
+ if (IsCsm16LegacyBoot == FALSE) {
+ if (gUsbProtocol == NULL) {
+ Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &gUsbProtocol);
+ if (EFI_ERROR(Status)) {
+ gUsbProtocol=NULL; // To be used later, after FarCall execution
+ }
+ }
+ }
+ if (gUsbProtocol != NULL) {
+ gUsbProtocol->UsbChangeEfiToLegacy(1);
+ }
+#endif
+
+ ThunkData->isFarCall = TRUE;
+
+ //Copy address for thunk.
+ ThunkData->FarCall.Segment = Segment;
+ ThunkData->FarCall.Offset = Offset;
+
+ //Copy address for stack
+ if (Stack)
+ {
+ ThunkData->Stack.Stack = (UINT32)Stack;
+ ThunkData->Stack.StackSize = (UINT32)StackSize;
+ } else ThunkData->Stack.StackSize = 0;
+
+ //Copy thunk registers.
+ ThunkData->Regs = *Regs;
+
+ // Reset the PS/2 keyboard before legacy boot
+ if (IsCsm16LegacyBoot == TRUE) {
+ if (gPS2KBDInterface) gPS2KBDInterface->Reset(gPS2KBDInterface, FALSE);
+ }
+
+ FuncNumber = Regs->X.AX;
+
+ if (IsCsm16Call) {
+ if (FuncNumber != 05 && FuncNumber != 02 && FuncNumber != 03) {
+ gLegacy8259->GetMask(gLegacy8259, &SaveIrqMask, NULL, NULL, NULL); // Save current Mask
+
+ IrqMask = -1;
+ gLegacy8259->SetMask(gLegacy8259, &IrqMask, NULL, NULL, NULL); // Set new Mask
+ }
+ }
+
+ //
+ // Mask all HW interrupts for real mode for CSM16 function #0 (InitializeYourself).
+ // This is needed since IVT is not installed before executing function #0.
+ //
+ // TODO: Explore the possibility of IVT installation from CSM32; in this case the
+ // code that is updating and using ProtectedIrqMask can be removed.
+ //
+ if (IsCsm16Call && FuncNumber == 00 ) {
+ gLegacy8259->GetMask(gLegacy8259, NULL, NULL, &ProtectedSaveIrqMask, NULL); // Save current Mask
+ ProtectedIrqMask = -1;
+ gLegacy8259->SetMask(gLegacy8259, NULL , NULL, &ProtectedIrqMask, NULL); // Set new Mask
+ }
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ //
+ // The following call will change the PIC settings to real mode; this includes
+ // unmasking all real mode interrupts. Note, that at this point HW interrupts
+ // must be disabled. This is done by the previous RaiseTPL call.
+ //
+ gLegacy8259->SetMode(gLegacy8259,Efi8259LegacyMode,NULL,NULL);
+
+ ((void(*)(UINTN))gThunkAsmAddr)(gThunkAsmAddr);
+
+#if defined(AMIUSB_SUPPORT)
+ if (gUsbProtocol) {
+ gUsbProtocol->UsbChangeEfiToLegacy(0);
+ }
+#endif
+
+ if (IsCsm16Call && FuncNumber == 00 ) {
+ gLegacy8259->SetMask(gLegacy8259, NULL , NULL, &ProtectedSaveIrqMask, NULL); // Set new Mask
+ }
+
+ gLegacy8259->SetMode(gLegacy8259,Efi8259ProtectedMode,NULL,NULL);
+
+ //Restore thunk registers.
+ *Regs = ThunkData->Regs;
+ pBS->RestoreTPL(OldTpl);
+
+ //
+ // Change USB operation mode indicator back to EFI
+ //
+
+ if (!IsCsm16Call ||
+ (IsCsm16Call &&
+ (FuncNumber == 05 || FuncNumber == 02 || FuncNumber == 03))) {
+// Reset PS2 Mouse
+ if (!gPS2KBDInterface) {
+ GetPs2SimpleTextInProtocolInterface((BIOS_INFO *)This, &gPS2KBDInterface);
+ }
+
+ if (gPS2KBDInterface) gPS2KBDInterface->Reset(gPS2KBDInterface, FALSE);
+
+ }
+ else gLegacy8259->SetMask(gLegacy8259, &SaveIrqMask, NULL, NULL, NULL); // Restore mask
+
+ if(IsCsm16DispatchOpRom) {
+ if((pKeyCodeProtocol == NULL && IsCsm16LegacyBoot == FALSE)) {
+ pBS->HandleProtocol(pST->ConsoleInHandle, &gAmiEfiKeycodeProtocolGuid, (void*)&pKeyCodeProtocol);
+ }
+ if(pKeyCodeProtocol != NULL) {
+ UINT8 KeyState;
+ KeyState = *(UINT8*)(UINTN)0x417;
+ if(KeyState & 0x10) {
+ KeyToggleState |= SCROLL_LOCK_ACTIVE;
+ }
+ if(KeyState & 0x20) {
+ KeyToggleState |= NUM_LOCK_ACTIVE;
+ }
+ if(KeyState & 0x40) {
+ KeyToggleState |= CAPS_LOCK_ACTIVE;
+ }
+ KeyToggleState |= TOGGLE_STATE_VALID;
+ pKeyCodeProtocol->SetState((EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL*)pKeyCodeProtocol,&KeyToggleState);
+ }
+ }
+
+ *(UINT8*)(UINTN)0x417 &= 0x70; // Clear key modifiers status in BDA
+
+ gInsideThunk = FALSE;
+
+ return FALSE; // CALL completed. Caller will see Regs for status.
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: LoadRealModeFile
+//
+// Description: Code that loads 16-bit thunk code at a particular address
+//
+// Input:
+// 16-bit binary file GUID
+// Address to load the binary to
+//
+// Output:
+// Status of the load operation
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LoadRealModeFile(EFI_GUID *Guid, VOID *Address)
+{
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ UINT32 Authentication;
+ VOID *BufferAddr=0;
+ UINTN BufferSize=0;
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN i;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiFirmwareVolumeProtocolGuid,NULL,&NumHandles,&HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i< NumHandles; ++i)
+ {
+ Status = pBS->HandleProtocol(HandleBuffer[i],&guidFV,&Fv);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = Fv->ReadSection(Fv,
+ Guid,
+ EFI_SECTION_RAW,
+ 0,
+ &BufferAddr,
+ &BufferSize,
+ &Authentication);
+
+ if (Status == EFI_SUCCESS)
+ {
+ MemCpy(
+ Address,
+ (UINT8*)BufferAddr,
+ BufferSize
+ );
+ pBS->FreePool(BufferAddr);
+ break;
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitializeThunk
+//
+// Description: 16-bit thunk initialization routine. It calls 16 bit code to
+// do the address fixups within 16-bit code.
+//
+// Input: The instance of BIOS_INFO pointer
+//
+// Output: Status of the initialization completion
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitializeThunk(
+ BIOS_INFO* CoreBiosInfo
+)
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Thunkaddr = (EFI_PHYSICAL_ADDRESS)CoreBiosInfo->Thunk;
+ UINT16 ThunkFixupsOffset;
+
+ //Locate Legacy8259 Protocol
+ gLegacy8259 = CoreBiosInfo->i8259;
+
+ //Copy ThunkAsm to memory.
+ Status = LoadRealModeFile(&gCsmThunkGuid, (VOID*)Thunkaddr);
+ if (EFI_ERROR(Status)) return Status;
+
+ gThunkAsmAddr = (UINT32)Thunkaddr;
+
+ //Call fixups
+ ThunkFixupsOffset = *(UINT16*)(gThunkAsmAddr+2);
+ ((void(*)(UINTN))(gThunkAsmAddr+ThunkFixupsOffset))(gThunkAsmAddr);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetPs2SimpleTextInProtocolInterface
+//
+// Description: This function returns the SimpleTextIn protocol interface
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetPs2SimpleTextInProtocolInterface(
+ BIOS_INFO *This,
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL **PS2KBDInterface
+)
+{
+ EFI_STATUS Status;
+ UINTN i,cnt;
+ ACPI_HID_DEVICE_PATH *siodp;
+ ACPI_PNPID *pnpid;
+ EFI_HANDLE *hbuff = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ BOOLEAN bIsConnected = FALSE;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiSimpleTextInProtocolGuid, NULL, &cnt, &hbuff);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ for(i=0; i<cnt; i++){
+ Status=pBS->HandleProtocol(hbuff[i],&gEfiDevicePathProtocolGuid,&dp);
+ if(EFI_ERROR(Status)) continue;
+
+ siodp=DPGetLastNode(dp);
+ if(siodp->Header.Type!=ACPI_DEVICE_PATH
+ || siodp->Header.SubType!=ACPI_DP
+ || NODE_LENGTH(&siodp->Header) != ACPI_DEVICE_PATH_LENGTH) continue;
+
+ pnpid=(ACPI_PNPID*)&siodp->HID;
+ if (pnpid->PnpID == 0x0303) {
+// Status = pBS->OpenProtocol (hbuff[i], &gEfiSimpleTextInProtocolGuid, &PS2KBDInterface, This->hBios, NULL, EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ Status = pBS->HandleProtocol(hbuff[i],&gEfiSimpleTextInProtocolGuid, PS2KBDInterface);
+ break;
+ }
+ Status = EFI_NOT_FOUND;
+ }
+ pBS->FreePool(hbuff);
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CSM/thunk/x86/x86thunk.asm b/Core/EM/CSM/thunk/x86/x86thunk.asm
new file mode 100644
index 0000000..9a5a781
--- /dev/null
+++ b/Core/EM/CSM/thunk/x86/x86thunk.asm
@@ -0,0 +1,828 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/x86/x86thunk.asm 37 10/07/13 9:01a Olegi $
+;
+; $Revision: 37 $
+;
+; $Date: 10/07/13 9:01a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/x86/x86thunk.asm $
+;
+; 37 10/07/13 9:01a Olegi
+; EIP135289
+; Legacy2Efi changes - CR4 save/restore
+;
+; 36 12/14/12 6:19p Olegi
+; [TAG] EIP109554
+; [Category] Improvement
+; [Description] Aptio4: Update CSM thunk to use private GDT instead of
+; GDT on entry point
+; [Files] x86thunk.asm
+;
+; 35 7/23/12 12:59p Olegi
+; [TAG] EIP95386
+; [Category] Improvement
+; [Description] CR3 register save/restore
+;
+; 34 6/13/12 12:49p Olegi
+; [TAG] EIP92524
+; [Category] Improvement
+; [Description] IDT location is limited to 4GB in CSM thunk
+;
+; 33 12/05/11 5:53p Olegi
+; [TAG] EIP77045
+; [Category] Improvement
+; [Description] Changed the values to be loaded to the segment
+; registers from static number (8) to a dynamic number that represents a
+; valid descriptor.
+; [Files] x86thunk.asm
+;
+; 32 12/01/10 9:37a Olegi
+; FarCall86 is modified to return data in stack when expected.
+;
+; 31 11/15/10 6:21p Olegi
+; [TAG] EIP48242
+; [Category] Bug Fix
+; [Severity] Critical
+; [Symptom] thunk problems for IA32 projects
+; [RootCause] wrong paths in thunk code for IA32 projects
+; [Solution] fixed the thunk code
+; [Files] x86thunk.asm
+;
+; 30 9/15/10 1:40p Olegi
+; Reverse thunk stack usage modified: stack for the PM operations will be
+; allocated externally.
+;
+; 29 9/13/10 5:26p Vyacheslava
+; Added variable PmStackPtr to use a new stack space.
+;
+; 28 9/08/10 6:16p Vyacheslava
+; Bugfix in reverse thunk: there was wrong assumption about stack
+; re-assignment. When caller (OptionROM) reassignes stack, reverse thunk
+; was failing.
+;
+; 27 7/26/10 2:23p Vyacheslava
+;
+; 26 7/25/10 2:44p Olegi
+;
+; 25 7/25/10 1:07p Olegi
+; Bugfixes in the reverse thunk implementation.
+;
+; 24 7/24/10 12:38p Olegi
+;
+; 23 7/23/10 4:09p Olegi
+; Initial reverse thunk implementation.
+;
+; 22 7/19/10 4:44p Olegi
+;
+; 21 1/12/10 11:47a Olegi
+; Copyright message updated.
+;
+; 20 11/12/08 5:02p Olegi
+;
+; 19 5/11/07 11:12a Markw
+; Save ss and set it to a flat descriptor in 64-bit mode.
+;
+; 18 4/27/07 5:14p Olegi
+; CSM.CHM file preparation.
+;
+; 17 9/15/06 12:02p Markw
+; Disable PAE when thunking because windows expects PAE in CR4 to be
+; disabled after calling INT19h to boot.
+;
+; 16 8/24/06 3:11p Felixp
+; Preliminary x64 support (work in progress)
+;
+; 15 5/25/06 2:23p Olegi
+;
+; 14 3/03/06 11:09a Markw
+; Removed some duplicate code.
+;
+; 13 10/14/05 10:16a Markw
+; Removed previous changes.
+;
+; 11 8/02/05 4:24p Markw
+; Removed some db66 from sgdt and sidt. It was instructing the CPU to do
+; a 24-bit load. However, the CPU was loading 32-bit that was needed, so
+; it worked even though the spec described the operation differently.
+;
+; 10 5/12/05 12:57p Markw
+; Fixed lidt in portected mode. It was only loading 24 of 32 bits.
+;
+; 9 4/18/05 10:54a Markw
+; Remove pushing/popping ebx (entry point).
+; make segments equal segement instead of fixup.
+;
+; 8 3/04/05 1:48p Mandal
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: x86Thunk.asm
+;
+; Description: x86 CPU thunk functions
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+.586P
+.model small
+
+;STACK_SIZE equ 8192
+STACK_TOP equ (4096 * 3)
+
+FAR_CALL_PTR_16 struct
+ ptr_offset dw ?
+ seg_offset dw ?
+FAR_CALL_PTR_16 ends
+
+REGISTERS struct
+ reg_eax dd ?
+ reg_ebx dd ?
+ reg_ecx dd ?
+ reg_edx dd ?
+ reg_esi dd ?
+ reg_edi dd ?
+ reg_eflags dd ?
+ reg_es dw ?
+ reg_cs dw ?
+ reg_ss dw ?
+ reg_ds dw ?
+ reg_fs dw ?
+ reg_gs dw ?
+ reg_ebp dd ?
+REGISTERS ends
+
+STACK_PARAM struct
+ StackPtr dd ?
+ StackSize dd ?
+STACK_PARAM ends
+
+THUNK_DATA struct
+ FarCallPtr16 FAR_CALL_PTR_16 <>
+ Regs REGISTERS <>
+ StackParm STACK_PARAM<>
+ isFarCall db 0
+ BiosInt db 0
+THUNK_DATA ends
+
+
+ASSUME ds:THUNK_SEG
+
+THUNK_SEG SEGMENT USE32 'CODE'
+
+THUNK proc
+ jmp over_data
+; The following data must be here. Don't move. These are used by the Thunk C driver.
+ dw LOWWORD offset Fixups
+ dw LOWWORD offset ReverseThunk
+ ThunkData THUNK_DATA <>
+over_data:
+ cli
+;--------------------------------------------------------------------------------
+; The following code switches from protected mode (from x64 if EFIx64 is defined,
+; otherwise from 32-bit protected mode) to 16-bit real mode.
+;--------------------------------------------------------------------------------
+; Calculate entry point and load EBX/RBX with it.
+
+ push ebx
+
+ call @f
+@@:
+ pop ebx
+ sub ebx, @b ; RBX/EBX - physical address of CSM16 entry point
+
+ mov DWORD PTR [RtReturnResult+ebx], eax
+
+ sidt fword ptr [IdtSave+ebx] ;Save IDT
+ sgdt fword ptr [GdtSave+ebx] ;Save GDT
+ lgdt fword ptr [GdtDescriptor+ebx]
+
+ mov eax, cr3 ;;Save CR3, CR4
+ mov [CR3Save+ebx], eax
+ mov eax, cr4
+ mov [CR4Save+ebx], eax
+
+ ;Save segement registers.
+ mov ax, ds
+ push eax ;64-bit doesn't support push ds, es, ss
+ mov ax, es
+ push eax
+ mov ax, ss
+ push eax
+ push fs
+ push gs
+ mov ax, cs ;This must be last for cs restore.
+ push eax
+
+ mov eax, DATA_SEL ;make sure segments are approriate for 32-bit mode.
+ mov ds, ax ; Load SS with the known descriptor value
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+
+ifdef EFIx64
+;---Jump from long mode to compatiblity mode---
+ ;jmp far ptr [ComModeAdr]
+ db 0ffh,2dh
+ dd ComModeAdr - $ - 4
+
+ComMode:
+;---Go to protected mode---
+ mov eax, cr0
+ btr eax, 31
+ mov cr0, eax ;Now in protected mode.
+ jmp $+2
+
+ mov ecx, 0c0000080h
+ rdmsr
+ btr eax, 8
+ wrmsr
+
+ mov eax, cr4
+ btr eax, 5
+ mov cr4, eax ;Turn off PAE bit. Windows expects when calling INT19h.
+endif
+
+ cmp BYTE PTR [IsReverseThunk+ebx], 1
+ je no_stack_to_copy
+
+ pushad
+ pushfd
+
+;--Save Data--
+ mov [StackSave+ebx], esp ;Save 32 bit stack address of this module.
+
+ ;---Copy Stack parameters of LegacyBiosFarCall---
+ mov ecx, [ThunkData.StackParm.StackSize+ebx]
+ or ecx, ecx
+ jz no_stack_to_copy
+
+ mov esi, [ThunkData.StackParm.StackPtr+ebx]
+ mov edi, ebx
+ add edi, STACK_TOP
+ sub edi, ecx
+ rep movsb
+no_stack_to_copy:
+;--Switch to real mode--
+ lidt fword ptr [LegacyLdtDescriptor+ebx]
+
+ mov ax, DATA_SEL_16
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ ;jmp CODE_SEL_16:next
+ db 0eah
+ dd offset next
+ dw CODE_SEL_16
+next:
+ mov eax, cr0
+ and al, 0feh
+ mov cr0, eax
+
+ ;--ITP doesn't display disassebly correctly until jump to real mode.
+
+ ;jmp CS_SEGMENT:RealModeAddr
+ db 0eah
+ dw LOWWORD offset RealMode
+RealModeFixUp:
+ dw 0
+RealMode:
+ db 8ch, 0c8h ;mov ax, cs
+ db 8eh, 0d8h ;mov ds, ax
+ db 8eh, 0c0h ;mov es, ax
+ db 8eh, 0d0h ;mov ss, ax
+ db 8eh, 0e0h ;mov fs, ax
+ db 8eh, 0e8h ;mov gs, ax
+
+; sti
+;---------------Real mode operations-----------
+ db 2eh, 80h, 3eh
+ dw LOWWORD offset IsReverseThunk
+ db 1 ;cmp cs:IsReverseThunk, 1
+
+ jnz @f
+
+ db 2eh, 0c6h, 6
+ dw LOWWORD offset IsReverseThunk
+ db 0 ;mov cs:IsReverseThunk, 0
+
+ ; Restore the registers from RtRegs
+ push cs
+ pop ss
+
+ db 0bch ; mov sp, LOWWORD OFFSET RtRegs
+ dw LOWWORD OFFSET RtRegs
+
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ db 66h, 61h ; popad
+
+ ; Restore stack pointer and its contents
+
+ db 2eh, 8eh, 16h ;mov cs:RtStackSave+4, ss
+ dw LOWWORD offset RtStackSave+4
+
+ db 66h, 2eh, 8bh, 26h ;mov sp, cs:RtStackSave
+ dw LOWWORD offset RtStackSave
+
+ ; Restore flags
+ db 66h, 2eh, 0ffh, 36h ; push DWORD PTR cs:RtSavedFlags
+ dw LOWWORD OFFSET RtSavedFlags
+ db 66h, 9dh ; popfd
+
+ db 83h, 0c4h, 4 ; add sp, 4: prepare stack for a push
+
+ db 66h, 2eh, 0ffh, 36h ; push dword ptr cs:RtRetAddressSave
+ dw LOWWORD offset RtRetAddressSave
+
+ db 66h, 2eh, 0a1h ;mov eax, RtReturnResult
+ dw LOWWORD offset RtReturnResult
+
+ db 0cbh ;retf ; reverse thunk call returns control
+
+@@:
+ db 66h
+ mov esp, STACK_TOP ;This is the top stack for real mode.
+
+ db 2bh, 26h ;sub sp, word ptr ThunkData.StackParm.StackSize
+ dw LOWWORD offset ThunkData.StackParm.StackSize
+
+ ;---copy registers for FarCall and BIOS INT---
+
+ db 66h, 8bh, 1eh ;mov ebx, ThunkData.regs.reg_ebx
+ dw LOWWORD offset ThunkData.regs.reg_ebx
+ db 66h, 8bh, 0eh ;mov ecx, ThunkData.regs.reg_ecx
+ dw LOWWORD offset ThunkData.regs.reg_ecx
+ db 66h, 8bh, 16h ;mov edx, ThunkData.regs.reg_edx
+ dw LOWWORD offset ThunkData.regs.reg_edx
+ db 66h, 8bh, 36h ;mov esi, ThunkData.regs.reg_esi
+ dw LOWWORD offset ThunkData.regs.reg_esi
+ db 66h, 8bh, 3eh ;mov edi, ThunkData.regs.reg_edi
+ dw LOWWORD offset ThunkData.regs.reg_edi
+ db 66h, 8bh, 2eh ;mov ebp, ThunkData.regs.reg_ebp
+ dw LOWWORD offset ThunkData.regs.reg_ebp
+
+ db 0a1h ;mov ax, ThunkData.regs.reg_es
+ dw LOWWORD offset ThunkData.regs.reg_es
+
+ db 08eh, 0c0h ;mov es, ax
+
+ db 66h, 0a1h ;mov eax, ThunkData.regs.reg_eax
+ dw LOWWORD offset ThunkData.regs.reg_eax
+
+ ;Change ds last, since above operations depend on ds.
+ db 0ffh, 36h ;push ThunkData.regs.reg_ds
+ dw LOWWORD offset ThunkData.regs.reg_ds
+ pop ds
+
+ ;Don't load the flags! They aren't needed, and if they aren't
+ ;initialized properly, the system hangs.
+
+ ;--Call real mode function or interrupt--
+ sti
+
+ db 2eh, 80h, 3eh ;cmp cs:ThunkData.isFarCall, 0
+ dw LOWWORD offset ThunkData.isFarCall
+ db 0
+
+ jnz FarCall
+
+ db 66h
+ pushad
+
+ db 2eh, 0a0h ;mov al, cs:ThunkData.BiosInt
+ dw LOWWORD offset ThunkData.BiosInt
+
+ db 2eh, 0a2h ;mov cs:intxx, al ;Sets the intermediate value for intxx below.
+ dw LOWWORD offset intxx
+
+ db 66h
+ mov eax, 1
+ cpuid ;serializing instruction because of runtime code modification.
+
+ db 66h
+ popad
+
+ db 0cdh ;Execute int x
+intxx label byte
+ db 0
+
+ jmp @f
+FarCall:
+ ;call dword ptr cs:[ThunkData.FarCallPtr16]
+ db 02eh, 0ffh, 1eh ;Execute far call
+ dw LOWWORD offset ThunkData.FarCallPtr16
+@@:
+
+ cli
+ ;--Copy registers back for FarCall and BIOS INT---
+
+ db 66h, 2eh, 0a3h ;mov cs:ThunkData.regs.reg_eax, eax
+ dw LOWWORD offset ThunkData.regs.reg_eax
+
+ push ds
+
+ db 2eh, 08fh, 6 ;pop cs:ThunkData.regs.reg_ds
+ dw LOWWORD offset ThunkData.regs.reg_ds
+
+ db 8ch, 0c8h ;mov ax, cs
+ db 8eh, 0d8h ;mov ds, ax
+
+ db 66h, 89h, 1eh ;mov ThunkData.regs.reg_ebx, ebx
+ dw LOWWORD offset ThunkData.regs.reg_ebx
+
+ db 66h, 89h, 0eh ;mov ThunkData.regs.reg_ecx, ecx
+ dw LOWWORD offset ThunkData.regs.reg_ecx
+
+ db 66h, 89h, 16h ;mov ThunkData.regs.reg_edx, edx
+ dw LOWWORD offset ThunkData.regs.reg_edx
+
+ db 66h, 89h, 36h ;mov ThunkData.regs.reg_esi, esi
+ dw LOWWORD offset ThunkData.regs.reg_esi
+
+ db 66h, 89h, 3eh ;mov ThunkData.regs.reg_edi, edi
+ dw LOWWORD offset ThunkData.regs.reg_edi
+
+ db 66h, 89h, 2eh ;mov ThunkData.regs.reg_ebp, ebp
+ dw LOWWORD offset ThunkData.regs.reg_ebp
+
+ db 08ch ,0c0h ;mov ax, es
+
+ db 0a3h ;mov ThunkData.regs.reg_es, ax
+ dw LOWWORD offset ThunkData.regs.reg_es
+
+ db 09ch ;pushf
+ db 08fh, 6 ;pop ThunkData.regs.reg_eflags
+ dw LOWWORD offset ThunkData.regs.reg_eflags
+
+;--------------End Real Mode operations---------
+RealToPm:
+ db 66h
+ xor ebx, ebx
+ db 8ch, 0cbh ;mov bx, cs
+ db 66h
+ shl ebx, 4 ;ebx = entry point
+
+ ;--Switch to protected mode--
+; cli
+
+ ;Reload GDT in case it was changed.
+ ;lgdt fword ptr cs:[GdtDescriptor]
+ db 66h,02eh,0fh,1,16h
+ dw LOWWORD offset GdtDescriptor
+
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+ ;jmp CODE_SEL:P32MODE
+ db 66h, 0eah
+P32ModeFixUp:
+ dd offset P32Mode
+ dw CODE_SEL
+
+P32Mode::
+ mov ax, DATA_SEL
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+ cmp BYTE PTR [IsReverseThunk + ebx], 1
+ je CreateReverseThunkESP
+ mov esp, [StackSave + ebx] ;Get original stack back.
+ ;---Copy Stack parameters of LegacyBiosFarCall---;
+ mov ecx, [ThunkData.StackParm.StackSize+ebx]
+ or ecx, ecx
+ jz @F
+ mov edi, [ThunkData.StackParm.StackPtr+ebx]
+ mov esi, ebx
+ add esi, STACK_TOP
+ sub esi, ecx
+ rep movsb
+@@:
+ popfd
+ popad
+ jmp DonePreparingESP
+
+CreateReverseThunkESP: ; EBX = ThunkStart code segment << 4
+ mov [ThunkStart + ebx], ebx
+ mov esp, [PmStackPtr + ebx]
+
+ifdef EFIx64
+ sub esp, 20h ; allocate 20h bytes in stack (x64 calling convention)
+endif
+ mov [esp], ebx
+ifdef EFIx64
+ mov DWORD PTR [esp+4], 0
+endif
+ sub esp, 4
+ mov [esp], esi ; Function pointer (DWORD)
+ifdef EFIx64
+ mov DWORD PTR [esp], 0
+ sub esp, 4
+ mov [esp], esi ; Function pointer (QWORD)
+endif
+
+DonePreparingESP:
+ xor eax, eax ; short/quick way to set EAX = 0
+ lldt ax ; (source operand == 0) => LDTR is invalid
+
+ifdef EFIx64
+ mov eax, cr4
+ bts eax, 5
+ mov cr4, eax ;Enable PAE
+
+ mov ecx, 0c0000080h
+ rdmsr
+ bts eax, 8
+ wrmsr
+
+ mov eax, cr0
+ bts eax, 31
+ mov cr0, eax ;Now in compatibility mode.
+ jmp $+2
+
+ pushd CODE_SEL_64
+ call @f ;push rip/eip
+@@:
+ add dword ptr [esp], @f - $
+ retf
+@@:
+
+ ;--In long mode.
+endif
+
+ lgdt fword ptr [GdtSave + ebx] ;Restore GDT
+ lidt fword ptr [IdtSave+ebx] ;Restore IDT
+
+ ;restore original cs
+ ;rsp/esp = cs
+ call @f ;push rip/eip
+@@:
+ add dword ptr [esp], @f - $
+ifdef EFIx64
+ db 48h
+endif
+ retf ;pop cs and eip.
+@@:
+
+ pop gs
+ pop fs
+ pop eax
+ mov ss, ax
+ pop eax
+ mov es, ax
+ pop eax
+ mov ds, ax
+
+ifdef EFIx64
+ ;TODO: Double check Reverse Thunk code.
+ cmp BYTE PTR [IsReverseThunk+ebx], 1
+ jne @f
+; Reverse thunk - copy parameters to RCX, RDX, R8, R9
+ db 48h, 8bh, 4ch, 24h, 28h ; mov rcx, [rsp + 28h]
+ db 48h, 8bh, 54h, 24h, 30h ; mov rdx, [rsp + 30h]
+ db 67h, 4ch, 8bh, 44h, 24h, 38h ; mov r8d, [rsp + 38h]
+ db 67h, 4ch, 8bh, 4ch, 24h, 40h ; mov r9d, [rsp + 40h]
+
+ jmp RealToPm_Exit
+@@:
+endif
+
+ mov eax, cs:[CR3Save + ebx]
+ mov cr3, eax
+ mov eax, cs:[CR4Save + ebx]
+ mov cr4, eax
+ pop ebx
+RealToPm_Exit:
+ ret
+
+;-----------------------------------------------------------
+ReverseThunk:
+ ; Save flags
+ db 66h, 9ch ; pushfd
+ db 66h, 2eh, 8fh, 6 ; pop DWORD PTR cs:RtSavedFlags
+ dw LOWWORD OFFSET RtSavedFlags
+
+ cli
+
+ db 66h, 2eh, 89h, 26h ;mov cs:RtStackSave, esp
+ dw LOWWORD offset RtStackSave
+
+ db 2eh, 8ch, 16h ;mov cs:RtStackSave+4, ss
+ dw LOWWORD offset RtStackSave+4
+
+ ; Get the PM stack pointer from the stack
+ db 89h, 0e5h ; mov bp, sp
+ db 66h, 8bh, 46h, 4 ; mov eax, [bp+4]
+ db 66h, 2eh, 0a3h ; mov cs:PmStackPtr, eax
+ dw LOWWORD offset PmStackPtr
+
+ ; Get return address and store it in cs:RtRetAddressSave
+ db 66h, 8bh, 46h, 0 ; mov eax, [bp+0]
+ db 66h, 2eh, 0a3h ; mov cs:RtRetAddressSave, eax
+ dw LOWWORD offset RtRetAddressSave
+
+ ; Save the registers in RtRegs
+ push cs
+ pop ss
+
+ db 0bch ; mov sp, LOWWORD OFFSET RtRegs+28h
+ dw LOWWORD OFFSET RtRegs+28h
+
+ db 66h, 60h ; pushad
+ push ds
+ push es
+ push fs
+ push gs
+
+ ; Restore SS:ESP
+ db 66h, 2eh, 8bh, 26h ;mov esp, cs:RtStackSave
+ dw LOWWORD offset RtStackSave
+
+ db 2eh, 8eh, 16h ;mov ss, cs:RtStackSave+4
+ dw LOWWORD offset RtStackSave+4
+
+ db 2eh, 0c6h, 06h ;mov cs:[IsReverseThunk], 1
+ dw LOWWORD offset IsReverseThunk
+ db 1
+
+ db 0e9h
+ dw RealToPm - ($+2) ;jmp NEAR RealToPm
+
+;-----------------------------------------------------------
+ reg_gs dw ?
+ reg_fs dw ?
+ reg_es dw ?
+ reg_ds dw ?
+ reg_eflags dd ?
+
+Fixups:
+ifdef EFIx64
+ ;In 64 bit mode, but compiled under 32-bit mode.
+ push ebx ;(push rbx) cpuid changes ebx
+ mov edx, ecx
+ shr edx, 4 ;Get segment
+
+;--Fixups---
+ ;add ComModeFixup, ecx
+ db 01, 0dh
+ dd ComModeFixup - $ - 4
+ ;add P32ModeFixUp, ecx
+ db 01, 0dh
+ dd P32ModeFixUp - $ - 4
+ ;add GdtDescriptorFixUp, ecx
+ db 01, 0dh
+ dd GdtDescriptorFixUp - $ - 4
+; add CODE_SEL_BASE_FIXUP, ecx ;must use add because upper 8 bit shouldn't change. Only 20 bit number.
+ db 01, 0dh
+ dd CODE_SEL_BASE_FIXUP - $ - 4
+; mov word ptr RealModeFixUp, dx
+ db 66h, 89h, 15h
+ dd RealModeFixUp - $ - 4
+ mov eax, 1
+ cpuid ;serialization for fixups
+ pop ebx ;pop rbx
+else
+ push ebp
+ mov ebp, esp
+
+ push ebx
+ push edx
+
+ mov ebx, [ebp+8] ;Get base address of this module
+ mov edx, ebx
+ shr edx, 4 ;Get segment
+
+;--Fixups---
+ add [P32ModeFixUp+ebx], ebx
+ add [GdtDescriptorFixUp+ebx], ebx
+ add [CODE_SEL_BASE_FIXUP+ebx], ebx ;must use add because upper 8 bit shouldn't change. Only 20 bit number.
+ mov word ptr [RealModeFixUp+ebx], dx
+
+ mov eax, 1
+ cpuid ;serialization for fixups
+ mov ebx, [ebp + 8] ;restore ebx
+
+ pop edx
+ pop ebx
+ pop ebp
+endif
+ ret
+
+align 16
+GDT_BASE:
+NULL_SEL equ $-GDT_BASE ;NULL Selector 0
+ dq 0
+DATA_SEL equ $-GDT_BASE
+ dq 00cf93000000ffffh
+CODE_SEL equ $-GDT_BASE
+ dq 00cf9b000000ffffh
+CODE_SEL_64 equ $-GDT_BASE
+ dq 00af9b000000ffffh
+DATA_SEL_16 equ $-GDT_BASE
+ dq 008f93000000ffffh
+
+CODE_SEL_16 equ $-GDT_BASE
+ dw 0ffffh
+CODE_SEL_BASE_FIXUP: ;Only 20 bits max
+ dw 0
+ db 0
+
+ db 09ah
+ db 0
+ db 0
+
+GDT_SIZE equ $-GDT_BASE ;Size of Descriptor Table
+GdtDescriptor:
+ dw GDT_SIZE - 1 ; GDT limit
+GdtDescriptorFixUp:
+ dq OFFSET GDT_BASE ; GDT base
+
+ifdef EFIx64
+align 8
+ComModeFixup equ $
+ComModeAdr equ $
+ dd offset ComMode
+ dw CODE_SEL
+endif
+
+ public StackSave
+StackSave label dword
+ dd 0
+align 8
+ public CR3Save
+CR3Save label dword
+ dq 0
+align 8
+ public CR4Save
+CR4Save label dword
+ dq 0
+align 8
+ public GdtSave
+GdtSave label fword
+ dw 0
+ dq 0
+
+align 8
+ public IdtSave
+IdtSave label fword
+ dw 0
+ dq 0
+align 8
+ public LegacyLdtDescriptor
+LegacyLdtDescriptor label fword
+ dw 3ffh
+ dq 0
+
+;------Reverse thunk data------------
+IsReverseThunk db 0
+RtReturnResult dd 0
+RtSavedFlags dd 0
+RtStackSave db 6 dup (0) ; DW for SS, DD for ESP
+PmStackPtr dd 0
+RtRetAddressSave dd 0
+ThunkStart dd 0
+RtRegs REGISTERS <>
+
+THUNK endp
+THUNK_SEG ENDS
+end
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/CSM/thunk/x86/x86thunk.cif b/Core/EM/CSM/thunk/x86/x86thunk.cif
new file mode 100644
index 0000000..61600c3
--- /dev/null
+++ b/Core/EM/CSM/thunk/x86/x86thunk.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "x86Thunk"
+ category = ModulePart
+ LocalRoot = "core\em\csm\thunk\x86"
+ RefName = "x86THUNK"
+[files]
+"\thunk.c"
+"\x86thunk.asm"
+"\x86thunk.mak"
+<endComponent>
diff --git a/Core/EM/CSM/thunk/x86/x86thunk.mak b/Core/EM/CSM/thunk/x86/x86thunk.mak
new file mode 100644
index 0000000..724023f
--- /dev/null
+++ b/Core/EM/CSM/thunk/x86/x86thunk.mak
@@ -0,0 +1,67 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CSM/Generic/Thunk/x86/x86thunk.mak 7 1/12/10 11:47a Olegi $
+#
+# $Revision: 7 $
+#
+# $Date: 1/12/10 11:47a $
+#**********************************************************************
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: x86Thunk.mak
+#
+# Description: This file has a set of rules to create a binary that will
+# be copied into lower memory that will give control to CSM16
+# code.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all: CREATE_THUNK_FFS
+
+CREATE_THUNK_FFS: $(BUILD_DIR)\x86Thunk.ffs
+
+$(BUILD_DIR)\x86Thunk.ffs : $(BUILD_DIR)\x86Thunk.bin
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) SOURCE_DIR=$(CSM_THUNKASM_DIR) \
+ GUID=A08276EC-A0FE-4e06-8670-385336C7D093 \
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ BINFILE=$** FFSFILE=$@ COMPRESS=0 NAME=$(**B)
+
+$(BUILD_DIR)\x86Thunk.bin: $(X86THUNK_DIR)\x86Thunk.asm
+!IF "$(x64_BUILD)"=="1"
+ $(ASM) /c /nologo /DEFIx64 /Fo$(BUILD_DIR)\x86thunk.obj $(X86THUNK_DIR)\x86Thunk.asm
+!ELSE
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\x86thunk.obj $(X86THUNK_DIR)\x86Thunk.asm
+!ENDIF
+ $(ASMLINK) /MAP $(BUILD_DIR)\x86thunk.obj, $(BUILD_DIR)\x86thunk.exe, $(BUILD_DIR)\x86thunk.map,,,
+ exe2bin $(BUILD_DIR)\x86thunk.exe $(BUILD_DIR)\x86Thunk.bin
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Capsule2_0/Capsule2_0.c b/Core/EM/Capsule2_0/Capsule2_0.c
new file mode 100644
index 0000000..e29e544
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0.c
@@ -0,0 +1,870 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Capsule2_0/Capsule2_0.c 3 4/16/14 3:12a Chaseliu $
+//
+// $Revision: 3 $
+//
+// $Date: 4/16/14 3:12a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Capsule2_0/Capsule2_0.c $
+//
+// 3 4/16/14 3:12a Chaseliu
+// [TAG] EIP163569
+// [Category] Improvement
+// [Description] Update for support 2014 BIOS Security Disclosures.
+// [Files]
+// Library\PeiLib.c
+// Library\EfiLib.c
+// Core\EM\NVRAM\NVRAMDXE.c
+// Core\EM\Capsule2_0\Capsule2_0.c
+// Core\CORE_DXE\FwVolBlock.c
+//
+// 2 4/16/13 5:42a Thomaschen
+// Fixed for EIP106722.
+//
+// 7 3/07/14 5:14p Artems
+// EIP 154318
+// Added fixes addressed in review comment
+//
+// 6 2/28/14 5:54p Artems
+// EIP 154318: fixed vulnerability with capsule block descriptors count
+// overflow
+//
+// 5 2/07/13 5:18p Artems
+// [TAG] EIP106722
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] Win8 firmware update doesn't work
+// [RootCause] For Win8 update capsule CapsuleRecovery device didn't
+// skip capsule header
+// [Solution] Added unique GUID to distinguish between AFU and Win8
+// capsule update
+// [Files] Capsule2_0.c CapsuleRecovery.c Capsule.h
+//
+// 4 11/30/12 6:10p Artems
+// [TAG] EIP107134
+// [Category] Improvement
+// [Description] Potential security holes in Aptio 4 Capsule eModule
+// [Files] Capsule2_0.c
+//
+// 3 7/31/12 6:18p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Added support for APTIO_FW_UPDATE capsule
+// [Files] Capsule2_0.c
+//
+// 2 7/20/12 10:44a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Capsule.c
+//
+// 1 5/24/12 4:22p Artems
+// [TAG] EIP74625
+// [Category] New Feature
+// [Description] New Capsule PPI required by latest Intel's MRC code
+// [Files] Capsule2_0.cif
+// Capsule2_0.sdl
+// Capsule2_0.mak
+// Capsule2_0.c
+// Capsule2_0.h
+// Capsule2_0Runtime.c
+// Capsule2_0Bds.c
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Capsule2_0.c
+//
+// Description: Capsule PPI implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiPeiLib.h>
+#include <AmiHobs.h>
+#include <Capsule.h>
+#include <Ppi/Capsule.h>
+#include "Capsule2_0.h"
+
+static EFI_GUID CapsuleVariableGuid = EFI_CAPSULE_AMI_GUID;
+static EFI_GUID AmiCapsuleHobGuid = AMI_CAPSULE_HOB_GUID;
+
+static PEI_CAPSULE_PPI CapsulePpi = {
+ CoreCapsuleCoalesce,
+ CoreCheckCapsuleUpdate,
+ CoreCapsuleCreateState
+};
+
+static EFI_PEI_PPI_DESCRIPTOR PpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiCapsulePpiGuid,
+ &CapsulePpi
+ }
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Capsule20PeiInit
+//
+// Description:
+// This function installs capsule PPI
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader - pointer to this file header
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI_SERVICES
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI Capsule20PeiInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ Status = CoreCheckCapsuleUpdate(PeiServices);
+ if(!EFI_ERROR(Status))
+ Status = (*PeiServices)->InstallPpi(PeiServices, PpiList);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CoreCapsuleCoalesce
+//
+// Description:
+// This function coalesces capsule data in continuous block of memory
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI_SERVICES
+// IN OUT VOID **MemoryBase - pointer to start of available memory
+// IN OUT UINTN *MemSize - pointer to available memory size
+//
+// Output:
+// EFI_SUCCESS - capsule coalesced successfully
+// EFI_ERROR - not enough memory to complete operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CoreCapsuleCoalesce (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **MemoryBase,
+ IN OUT UINTN *MemSize
+)
+{
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr;
+ UINTN Size;
+ EFI_STATUS Status;
+ VOID *Start = *MemoryBase;
+ UINTN BufferSize = *MemSize;
+ UINTN NoOfChunks;
+
+ Ptr = GetCapsuleLocation(PeiServices);
+ if(Ptr == NULL)
+ return EFI_NOT_FOUND;
+
+ Size = GetCapsuleDataSize(Ptr, &NoOfChunks);
+ if(Size == 0 || Size > MAX_CAPSULE_SIZE)
+ return EFI_NOT_FOUND;
+
+ if(Size > BufferSize)
+ return EFI_BUFFER_TOO_SMALL;
+
+/* First try to find continuous block, not overlapped with capsule data */
+ Status = FindFreeBuffer(Ptr, Size, &Start, BufferSize, TRUE);
+ if(!EFI_ERROR(Status)) {
+ CoalesceCapsule(Ptr, Start, Size);
+ *MemoryBase = Start;
+ *MemSize = Size;
+ return EFI_SUCCESS;
+ }
+
+/* Large enough buffer not found try to coalesce capsule piece by piece */
+/* Get buffer to store mailbox information */
+/* we will allocate buffer from the bottom of available memory */
+ Status = FindFreeBuffer(Ptr, sizeof(CAPSULE_BLOCK) * NoOfChunks, &Start, BufferSize, FALSE);
+ if(EFI_ERROR(Status))
+ return Status;
+/* recalculate available buffer size */
+ BufferSize = (UINTN)Start - (UINTN)(*MemoryBase);
+ if(Size > BufferSize)
+ return EFI_BUFFER_TOO_SMALL;
+
+/* store mailbox info for future use */
+ SaveCapsulePointers(Ptr, NoOfChunks, (CAPSULE_BLOCK *)Start);
+
+ Status = CoalesceCapsuleByParts((CAPSULE_BLOCK *)Start, NoOfChunks, *MemoryBase, BufferSize);
+ if(!EFI_ERROR(Status)) {
+ *MemSize = Size; //since we will coalesce from start of available memory *MemoryBase value will be valid
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CoreCheckCapsuleUpdate
+//
+// Description:
+// This function checks if capsule is present
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI_SERVICES
+//
+// Output:
+// EFI_SUCCESS - capsule present
+// EFI_NOT_FOUND - capsule not present or is beyond the 4GB boundaries
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CoreCheckCapsuleUpdate (
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr;
+
+ Ptr = GetCapsuleLocation(PeiServices);
+ return (Ptr == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CoreCapsuleCreateState
+//
+// Description:
+// This function copies coalesced capsule into reserved block of memory and creates HOB
+// with capsule parameters
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI_SERVICES
+// IN VOID *CapsuleBase - coalesced capsule start address
+// IN UINTN CapsuleSize - capsule size
+//
+// Output:
+// EFI_SUCCESS - capsule present
+// EFI_ERROR - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CoreCapsuleCreateState(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CapsuleBase,
+ IN UINTN CapsuleSize
+)
+{
+ EFI_STATUS Status;
+ UINTN TotalSize = 0;
+ EFI_CAPSULE_HEADER *Cap;
+ VOID *SaveCap;
+ AMI_CAPSULE_HOB *Hob;
+ UINTN Pages;
+ EFI_PHYSICAL_ADDRESS Save;
+ static EFI_GUID AmiFwCapsuleGuid = APTIO_FW_CAPSULE_GUID;
+ static EFI_GUID W8FwUpdateImageCapsuleGuid = W8_FW_UPDATE_IMAGE_CAPSULE_GUID;
+
+ static EFI_GUID RecoveryBootModeGuid = EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI;
+ static EFI_PEI_PPI_DESCRIPTOR RecoveryModePpi = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &RecoveryBootModeGuid, NULL
+ };
+
+ Cap = (EFI_CAPSULE_HEADER *)CapsuleBase;
+
+ while(TotalSize < CapsuleSize) {
+ Pages = EFI_SIZE_TO_PAGES(Cap->CapsuleImageSize);
+ Status = (*PeiServices)->AllocatePages(PeiServices, EfiBootServicesData, Pages, &Save);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ SaveCap = (VOID *)(UINTN)Save;
+ MemCpy(SaveCap, Cap, Cap->CapsuleImageSize);
+
+ Status = (*PeiServices)->CreateHob(PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, sizeof(AMI_CAPSULE_HOB), &Hob);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Hob->Header.Name = AmiCapsuleHobGuid;
+ Hob->CapsuleData = (EFI_PHYSICAL_ADDRESS)(UINTN)SaveCap;
+ Hob->CapsuleGuid = Cap->CapsuleGuid;
+ Hob->CapsuleLength = Cap->CapsuleImageSize;
+
+ if(!guidcmp(&(Cap->CapsuleGuid), &AmiFwCapsuleGuid) ||
+ !guidcmp(&(Cap->CapsuleGuid), &W8FwUpdateImageCapsuleGuid)) {
+ (*PeiServices)->SetBootMode(PeiServices, BOOT_ON_FLASH_UPDATE);
+ (*PeiServices)->InstallPpi(PeiServices, &RecoveryModePpi);
+ }
+
+ TotalSize += Cap->CapsuleImageSize;
+ (UINT8 *)Cap += Cap->CapsuleImageSize;
+ }
+ return EFI_SUCCESS;
+}
+
+
+/* ----------- Capsule service functions ------------ */
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCapsuleLocation
+//
+// Description:
+// This function returns pointer to capsule mailbox
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI_SERVICES
+//
+// Output:
+// EFI_CAPSULE_BLOCK_DESCRIPTOR * - pointer to mailbox, or NULL
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_CAPSULE_BLOCK_DESCRIPTOR * GetCapsuleLocation(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof (EFI_PHYSICAL_ADDRESS);
+ EFI_PHYSICAL_ADDRESS MailBox = 0;
+
+ Status = PeiGetVariable(PeiServices, CAPSULE_UPDATE_VAR, &CapsuleVariableGuid, NULL, &VarSize, &MailBox);
+ PEI_TRACE((-1, PeiServices, "Get capsule variable %r, addr %lx\n", Status, MailBox));
+ if(EFI_ERROR(Status))
+ return NULL;
+
+ if(MailBox >= MAX_CAPSULE_ADDRESS)
+ return NULL; //no support for Capsule above 4GB
+
+ return (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)MailBox;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCapsuleDataSize
+//
+// Description:
+// This function returns capsule size calculated from mailbox data
+//
+// Input:
+// IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr - pointer to capsule mailbox
+// OUT UINTN *NoOfChunks - pointer where to store quantity of capsule pieces
+//
+// Output:
+// UINTN - capsule size in bytes or 0
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN GetCapsuleDataSize(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ OUT UINTN *NoOfChunks
+)
+{
+ UINT64 Result = 0;
+ UINTN Chunks = 0;
+
+ do {
+ if(Ptr->DataBlock >= MAX_CAPSULE_ADDRESS) //pointer above 4GB
+ return 0;
+
+ if(Ptr->Length != 0) {
+ if(Ptr->Length > MAX_CAPSULE_SIZE - Result)
+ return 0;
+ Result += Ptr->Length;
+ Chunks++;
+ Ptr++;
+ } else if (Ptr->DataBlock != NULL) {
+ if(Ptr == (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer))
+ //when continuation pointer points to itself it's either error or malicious capsule, we won't process it
+ return 0;
+ Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer);
+ } else {
+ break;
+ }
+ } while(Chunks <= MAX_CAPSULE_BLOCK_DESCRIPTOR_COUNT);
+
+ if(Chunks <= MAX_CAPSULE_BLOCK_DESCRIPTOR_COUNT) {
+ *NoOfChunks = Chunks;
+ return (UINTN)Result;
+ } else
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BufferOverlap
+//
+// Description:
+// This function checks if two buffers overlap each other
+//
+// Input:
+// IN MEMORY_BLOCK *Buffer1 - buffer1 parameters
+// IN MEMORY_BLOCK *Buffer2 - buffer2 parameters
+//
+// Output:
+// TRUE - buffers overlap, FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BufferOverlap(
+ IN MEMORY_BLOCK *Buffer1,
+ IN MEMORY_BLOCK *Buffer2
+)
+{
+ return ((Buffer2->Address > (Buffer1->Address + Buffer1->Size)) ||
+ (Buffer1->Address > (Buffer2->Address + Buffer2->Size))) ? FALSE : TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustBuffer
+//
+// Description:
+// This function moves one block of memory within free range to avoid overlap
+// with another buffer
+//
+// Input:
+// IN MEMORY_BLOCK *Free - free memory range parameters
+// IN MEMORY_BLOCK *Unmovable - parameters of overlapping buffer that can't be moved
+// IN OUT MEMORY_BLOCK *Movable - parameters of overlapping buffer that can be moved
+// IN BOOLEAN FromTop - flag of moving direction in free range(TRUE - move from top, FALSE -
+// move from bottom
+//
+// Output:
+// EFI_SUCCESS - buffer moved successfully
+// EFI_BUFFER_TOO_SMALL - not enough memory to move buffer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AdjustBuffer(
+ IN MEMORY_BLOCK *Free,
+ IN MEMORY_BLOCK *Unmovable,
+ IN OUT MEMORY_BLOCK *Movable,
+ IN BOOLEAN FromTop
+)
+{
+ if(!BufferOverlap(Unmovable, Movable))
+ return EFI_SUCCESS;
+
+ if(FromTop) {
+/* Move movable block to the end of unmovalbe */
+ Movable->Address = Unmovable->Address + Unmovable->Size;
+ } else {
+/* Move movable block before unmovable */
+ Movable->Address = Unmovable->Address - Movable->Size;
+ }
+
+ return (BufferOverlap(Unmovable, Free)) ? EFI_BUFFER_TOO_SMALL : EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFreeBuffer
+//
+// Description:
+// This function searches for free continuous block of memory of required size
+//
+// Input:
+// IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr - pointer to capsule mailbox
+// IN UINTN RequiredSize - size of buffer required
+// IN OUT VOID **BaseAddress - on input pointer to start of free memory, on output
+// start of requested buffer
+// IN UINTN AvailableSize - size of free memory
+// IN BOOLEAN FromTop - flag of moving direction in free range(TRUE - move from top, FALSE -
+// move from bottom
+//
+// Output:
+// EFI_SUCCESS - buffer moved successfully
+// EFI_BUFFER_TOO_SMALL - not enough memory to move buffer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindFreeBuffer(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ IN UINTN RequiredSize,
+ IN OUT VOID **BaseAddress,
+ IN UINTN AvailableSize,
+ IN BOOLEAN FromTop
+)
+{
+ EFI_STATUS Status;
+ MEMORY_BLOCK FreeMemory;
+ MEMORY_BLOCK RequiredMemory;
+ MEMORY_BLOCK Unmovable;
+
+ FreeMemory.Address = (UINT32)(UINTN)(*BaseAddress);
+ FreeMemory.Size = AvailableSize;
+
+ RequiredMemory.Size = RequiredSize;
+
+ if(FromTop) {
+/* start looking for available space from the top of available buffer */
+ RequiredMemory.Address = FreeMemory.Address;
+ } else {
+/* start looking for available space from the bottom of available buffer */
+ RequiredMemory.Address = AvailableSize - RequiredSize;
+ }
+
+ do {
+ /* First check if we overlapped with mailbox itself */
+ Unmovable.Address = (UINT32)Ptr;
+ Unmovable.Size = sizeof(EFI_CAPSULE_BLOCK_DESCRIPTOR);
+ Status = AdjustBuffer(&FreeMemory, &Unmovable, &RequiredMemory, FromTop);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if(Ptr->Length != 0) {
+ /* Now check if we overlapped with DataBlock */
+ Unmovable.Address = (UINT32)(Ptr->DataBlock);
+ Unmovable.Size = (UINT32)(Ptr->Length);
+ Status = AdjustBuffer(&FreeMemory, &Unmovable, &RequiredMemory, FromTop);
+ Ptr++;
+ } else if (Ptr->DataBlock != NULL) {
+ Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer);
+ } else {
+ break; //we've reached end of mailbox
+ }
+ } while (!EFI_ERROR(Status));
+
+ if(!EFI_ERROR(Status)) {
+ *BaseAddress = (VOID *)(UINTN)RequiredMemory.Address;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CoalesceCapsule
+//
+// Description:
+// This function coalesces capsule from mailbox to continuous block of memory
+//
+// Input:
+// IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr - pointer to capsule mailbox
+// IN VOID *Start - pointer to start of continuous block of memory
+// IN UINTN Size - size of continuous block of memory
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CoalesceCapsule(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ IN VOID *Start,
+ IN UINTN Size
+)
+{
+ UINT8 *Walker = (UINT8 *)Start;
+ UINT64 Stop = 0;
+
+ do {
+ if(Ptr->Length != 0) {
+ MemCpy(Walker, (VOID *)(UINTN)(Ptr->DataBlock), (UINTN)Ptr->Length);
+ Walker += Ptr->Length;
+ Stop += Ptr->Length;
+ Ptr++;
+ } else if(Ptr->DataBlock != NULL) {
+ Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer);
+ } else {
+ break; //we've reached end of mailbox
+ }
+ } while (Stop <= Size);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveCapsulePointers
+//
+// Description:
+// This function relocates and reformats capsule mailbox for further processing
+//
+// Input:
+// IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr - pointer to capsule mailbox
+// IN UINTN ArraySize - size of array to store capsule mailbox pointers
+// OUT CAPSULE_BLOCK *Array - pointer where to store capsule mailbox pointers
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SaveCapsulePointers(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ IN UINTN ArraySize,
+ OUT CAPSULE_BLOCK *Array
+)
+{
+ UINTN i = 0;
+ do {
+ if(Ptr->Length != 0) {
+ Array[i].OriginalAddress = (UINT32)Ptr->DataBlock;
+ Array[i].Size = (UINT32)Ptr->Length;
+ Array[i].RelocatedAddress = 0;
+ Array[i].Attributes = 0;
+ i++;
+ Ptr++;
+ } else if(Ptr->DataBlock != NULL) {
+ Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer);
+ } else {
+ break;
+ }
+ } while(i <= ArraySize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindOverlaps
+//
+// Description:
+// This function checks if given memory block overlaps with other blocks of capsule
+//
+// Input:
+// IN CAPSULE_BLOCK *Array - pointer to capsule blocks array
+// IN UINTN ArraySize - size of array of capsule blocks
+// IN MEMORY_BLOCK *Probe - pointer to memory block to check against
+//
+// Output:
+// UINTN - number of overlaps found or 0 if there are no overlaps
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN FindOverlaps(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN MEMORY_BLOCK *Probe
+)
+{
+ UINTN i;
+ MEMORY_BLOCK Unmovable;
+ UINTN Overlap = 0;
+
+ for(i = 0; i < ArraySize; i++) {
+ if(Array[i].Attributes & CAPSULE_BLOCK_PROCESSING ||
+ Array[i].Attributes & CAPSULE_BLOCK_DONE)
+ continue;
+
+ Unmovable.Address = (Array[i].Attributes & CAPSULE_BLOCK_RELOCATED) ?
+ Array[i].RelocatedAddress : Array[i].OriginalAddress;
+ Unmovable.Size = Array[i].Size;
+ if(BufferOverlap(&Unmovable, Probe)) {
+ Overlap++;
+ Array[i].Attributes |= CAPSULE_BLOCK_OVERLAPPING;
+ }
+ }
+ return Overlap;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFreeBufferEx
+//
+// Description:
+// This function searches for continuous memory block in free range, and if not found
+// in already processed capsule blocks
+//
+// Input:
+// IN CAPSULE_BLOCK *Array - pointer to capsule blocks array
+// IN UINTN ArraySize - size of array of capsule blocks
+// IN MEMORY_BLOCK *Available - available memory block parameters
+// IN MEMORY_BLOCK *Reserved - occupied memory block parameters
+// IN OUT MEMORY_BLOCK *Free - parameters for block that requires allocation
+//
+// Output:
+// EFI_SUCCESS - block relocated successfully
+// EFI_BUFFER_TOO_SMALL - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindFreeBufferEx(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN MEMORY_BLOCK *Available,
+ IN MEMORY_BLOCK *Reserved,
+ IN OUT MEMORY_BLOCK *Free
+)
+{
+ UINTN i;
+ MEMORY_BLOCK Unmovable;
+ EFI_STATUS Status;
+
+ Free->Address = Available->Address;
+
+ for(i = 0; i < ArraySize; i++) {
+ if(Array[i].Attributes & CAPSULE_BLOCK_PROCESSING ||
+ Array[i].Attributes & CAPSULE_BLOCK_DONE)
+ continue;
+
+ Unmovable.Address = (Array[i].Attributes & CAPSULE_BLOCK_RELOCATED) ?
+ Array[i].RelocatedAddress : Array[i].OriginalAddress;
+ Unmovable.Size = Array[i].Size;
+ Status = AdjustBuffer(Available, &Unmovable, Free, TRUE);
+ if(EFI_ERROR(Status))
+ break;
+ }
+
+ if(!EFI_ERROR(Status)) {
+ return Status; //buffer found
+ }
+/* try to find free space in previously processed chunks */
+ for(i = 0; i < ArraySize; i++) {
+ if(Array[i].Attributes & CAPSULE_BLOCK_PROCESSING || Free->Size > Array[i].Size)
+ continue;
+
+ if(Array[i].Attributes & CAPSULE_BLOCK_DONE &&
+ !(Array[i].Attributes & CAPSULE_BLOCK_RELOCATED) ) {
+ /* if chunk was processed but not relocated, original address may be free */
+ Free->Address = Array[i].OriginalAddress;
+ if(!BufferOverlap(Free, Reserved)) {
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ return EFI_BUFFER_TOO_SMALL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RelocateOverlaps
+//
+// Description:
+// This function moves capsule blocks that overlap with reserved block
+//
+// Input:
+// IN CAPSULE_BLOCK *Array - pointer to capsule blocks array
+// IN UINTN ArraySize - size of array of capsule blocks
+// IN MEMORY_BLOCK *Available - available memory block parameters
+// IN MEMORY_BLOCK *Reserved - occupied memory block parameters
+//
+// Output:
+// EFI_SUCCESS - block relocated successfully
+// EFI_BUFFER_TOO_SMALL - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RelocateOverlaps(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN MEMORY_BLOCK *Available,
+ IN MEMORY_BLOCK *Reserved
+)
+{
+ UINTN i;
+ MEMORY_BLOCK Free;
+ VOID *Source;
+ EFI_STATUS Status;
+
+ for(i = 0; i < ArraySize; i++) {
+ if(!(Array[i].Attributes & CAPSULE_BLOCK_OVERLAPPING))
+ continue;
+
+ Free.Size = Array[i].Size;
+ Status = FindFreeBufferEx(Array, ArraySize, Available, Reserved, &Free);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Source = (Array[i].Attributes & CAPSULE_BLOCK_RELOCATED) ?
+ (VOID *)Array[i].RelocatedAddress : (VOID *)Array[i].OriginalAddress;
+ MemCpy((VOID *)(Free.Address), Source, Array[i].Size);
+ Array[i].Attributes |= CAPSULE_BLOCK_RELOCATED;
+ Array[i].Attributes &= ~CAPSULE_BLOCK_OVERLAPPING;
+ Array[i].RelocatedAddress = Free.Address;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CoalesceCapsuleByParts
+//
+// Description:
+// This function coalesces capsule from capsule blocks
+//
+// Input:
+// IN CAPSULE_BLOCK *Array - pointer to capsule blocks array
+// IN UINTN ArraySize - size of array of capsule blocks
+// IN VOID *Buffer - pointer to start of continuous block of memory
+// IN UINTN BufferSize - size of continuous block of memory
+//
+// Output:
+// EFI_SUCCESS - block relocated successfully
+// EFI_BUFFER_TOO_SMALL - not enough memory to perform operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CoalesceCapsuleByParts(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+)
+{
+ UINTN i;
+ UINTN Overlap;
+ VOID *Source;
+ EFI_STATUS Status;
+ MEMORY_BLOCK Available;
+ MEMORY_BLOCK Reserved;
+ MEMORY_BLOCK Current;
+
+ Current.Address = (UINT32)Buffer;
+ Reserved.Address = Current.Address;
+ Reserved.Size = 0;
+ Available.Size = BufferSize;
+
+ for(i = 0; i < ArraySize; i++) {
+ Array[i].Attributes |= CAPSULE_BLOCK_PROCESSING;
+ Current.Size = Array[i].Size;
+ Available.Address = Current.Address + Current.Size;
+ Available.Size -= Array[i].Size; //reserve space
+ Reserved.Size += Array[i].Size;
+ Overlap = FindOverlaps(Array, ArraySize, &Current);
+ if(Overlap > 0) {
+ Status = RelocateOverlaps(Array, ArraySize, &Available, &Reserved);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ Source = (Array[i].Attributes & CAPSULE_BLOCK_RELOCATED) ?
+ (VOID *)(Array[i].RelocatedAddress) : (VOID *)(Array[i].OriginalAddress);
+ MemCpy((VOID *)(Current.Address), Source, Array[i].Size);
+ Current.Address += Array[i].Size;
+ Array[i].Attributes &= ~CAPSULE_BLOCK_PROCESSING;
+ Array[i].Attributes |= CAPSULE_BLOCK_DONE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Capsule2_0/Capsule2_0.cif b/Core/EM/Capsule2_0/Capsule2_0.cif
new file mode 100644
index 0000000..b50f587
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "Capsule2_0"
+ category = ModulePart
+ LocalRoot = "Core\EM\Capsule2_0\"
+ RefName = "Capsule2_0"
+[files]
+"Capsule2_0.sdl"
+"Capsule2_0.mak"
+"Capsule2_0.c"
+"Capsule2_0.h"
+"Capsule2_0Runtime.c"
+"Capsule2_0Bds.c"
+<endComponent>
diff --git a/Core/EM/Capsule2_0/Capsule2_0.h b/Core/EM/Capsule2_0/Capsule2_0.h
new file mode 100644
index 0000000..10e804b
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0.h
@@ -0,0 +1,177 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/Capsule2_0/Capsule2_0.h 1 5/24/12 4:22p Artems $
+//
+// $Revision: 1 $
+//
+// $Date: 5/24/12 4:22p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/Capsule2_0/Capsule2_0.h $
+//
+// 1 5/24/12 4:22p Artems
+// [TAG] EIP74625
+// [Category] New Feature
+// [Description] New Capsule PPI required by latest Intel's MRC code
+// [Files] Capsule2_0.cif
+// Capsule2_0.sdl
+// Capsule2_0.mak
+// Capsule2_0.c
+// Capsule2_0.h
+// Capsule2_0Runtime.c
+// Capsule2_0Bds.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Capsule2_0.h
+//
+// Description: Capsule PPI functions definition
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __HII_PRIVATE__H__
+#define __HII_PRIVATE__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Token.h>
+#include <Efi.h>
+
+#define MAX_CAPSULE_ADDRESS 0x100000000 //4GB
+
+#define CAPSULE_BLOCK_DONE 0x0001
+#define CAPSULE_BLOCK_RELOCATED 0x0002
+#define CAPSULE_BLOCK_PROCESSING 0x0004
+#define CAPSULE_BLOCK_OVERLAPPING 0x0008
+
+typedef struct {
+ UINT32 OriginalAddress;
+ UINT32 Size;
+ UINT32 RelocatedAddress;
+ UINT32 Attributes;
+} CAPSULE_BLOCK;
+
+typedef struct {
+ UINT32 Address;
+ UINT32 Size;
+} MEMORY_BLOCK;
+
+EFI_STATUS CoreCapsuleCoalesce(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **MemoryBase,
+ IN OUT UINTN *MemSize
+);
+
+EFI_STATUS CoreCheckCapsuleUpdate(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+EFI_STATUS CoreCapsuleCreateState(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CapsuleBase,
+ IN UINTN CapsuleSize
+);
+
+EFI_CAPSULE_BLOCK_DESCRIPTOR * GetCapsuleLocation(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+UINTN GetCapsuleDataSize(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ OUT UINTN *NoOfChunks
+);
+
+BOOLEAN BufferOverlap(
+ IN MEMORY_BLOCK *Buffer1,
+ IN MEMORY_BLOCK *Buffer2
+);
+
+EFI_STATUS AdjustBuffer(
+ IN MEMORY_BLOCK *Free,
+ IN MEMORY_BLOCK *Unmovable,
+ IN OUT MEMORY_BLOCK *Movable,
+ IN BOOLEAN FromTop
+);
+
+EFI_STATUS FindFreeBuffer(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ IN UINTN RequiredSize,
+ IN OUT VOID **BaseAddress,
+ IN UINTN AvailableSize,
+ IN BOOLEAN FromTop
+);
+
+VOID CoalesceCapsule(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ IN VOID *Start,
+ IN UINTN Size
+);
+
+VOID SaveCapsulePointers(
+ IN EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr,
+ IN UINTN ArraySize,
+ OUT CAPSULE_BLOCK *Array
+);
+
+UINTN FindOverlaps(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN MEMORY_BLOCK *Probe
+);
+
+EFI_STATUS FindFreeBufferEx(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN MEMORY_BLOCK *Available,
+ IN MEMORY_BLOCK *Reserved,
+ OUT MEMORY_BLOCK *Free
+);
+
+EFI_STATUS RelocateOverlaps(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN MEMORY_BLOCK *Available,
+ IN MEMORY_BLOCK *Reserved
+);
+
+EFI_STATUS CoalesceCapsuleByParts(
+ IN CAPSULE_BLOCK *Array,
+ IN UINTN ArraySize,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/Capsule2_0/Capsule2_0.mak b/Core/EM/Capsule2_0/Capsule2_0.mak
new file mode 100644
index 0000000..791ae3a
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0.mak
@@ -0,0 +1,70 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/Capsule2_0/Capsule2_0.mak 1 5/24/12 4:22p Artems $
+#
+# $Revision: 1 $
+#
+# $Date: 5/24/12 4:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/Capsule2_0/Capsule2_0.mak $
+#
+# 1 5/24/12 4:22p Artems
+# [TAG] EIP74625
+# [Category] New Feature
+# [Description] New Capsule PPI required by latest Intel's MRC code
+# [Files] Capsule2_0.cif
+# Capsule2_0.sdl
+# Capsule2_0.mak
+# Capsule2_0.c
+# Capsule2_0.h
+# Capsule2_0Runtime.c
+# Capsule2_0Bds.c
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Capsule2_0.mak
+#
+# Description: Make file to create Capsule Driver
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_PEIBin : $(BUILD_DIR)\Capsule2_0.obj
+RUNTIMEBin : $(BUILD_DIR)\Capsule2_0Runtime.obj
+CORE_DXEBin : $(BUILD_DIR)\Capsule2_0Bds.obj
+
+CFLAGS=$(CFLAGS) /D\"OEM_PROCESS_CAPSULE_LIST=$(OemProcessCapsuleList)\"
+
+{$(Capsule2_0_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Capsule2_0/Capsule2_0.sdl b/Core/EM/Capsule2_0/Capsule2_0.sdl
new file mode 100644
index 0000000..ade3693
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0.sdl
@@ -0,0 +1,60 @@
+TOKEN
+ Name = Capsule2_0_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable Capsule2_0 support in Project"
+End
+
+PATH
+ Name = Capsule2_0_DIR
+ Help = "Path to Capsule2_0 Module in Project"
+End
+
+MODULE
+ Help = "Includes Capsule2_0.mak to Project"
+ File = "Capsule2_0.mak"
+End
+
+TOKEN
+ Name = "SUPPORT_UPDATE_CAPSULE_RESET"
+ Value = "1"
+ Help = "If ON - platform supports memory preserve across reset."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_CAPSULE_SIZE"
+ Value = "0x4000000"
+ Help = "Maximum size for capsule"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+ELINK
+ Name = "Capsule20PeiInit,"
+ Parent = "PeiInitNV,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "Capsule20RuntimeInit,"
+ Parent = "RuntimeInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ProcessCapsule,"
+ Parent = "ConnectRootBridgeHandles,"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "OemProcessCapsuleList"
+ Help = "List of callback functions to be called to process OEM capsule"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/Capsule2_0/Capsule2_0Bds.c b/Core/EM/Capsule2_0/Capsule2_0Bds.c
new file mode 100644
index 0000000..cb3b1df
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0Bds.c
@@ -0,0 +1,140 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/Capsule2_0/Capsule2_0Bds.c 2 7/31/12 6:19p Artems $
+//
+// $Revision: 2 $
+//
+// $Date: 7/31/12 6:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/Capsule2_0/Capsule2_0Bds.c $
+//
+// 2 7/31/12 6:19p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Remove Capsule mailbox from NVRAM once capsule is
+// processed
+// [Files] Capsule2_0Bds.c
+//
+// 1 5/24/12 4:22p Artems
+// [TAG] EIP74625
+// [Category] New Feature
+// [Description] New Capsule PPI required by latest Intel's MRC code
+// [Files] Capsule2_0.cif
+// Capsule2_0.sdl
+// Capsule2_0.mak
+// Capsule2_0.c
+// Capsule2_0.h
+// Capsule2_0Runtime.c
+// Capsule2_0Bds.c
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Capsule2_0Bds.c
+//
+// Description: Capsule execution implementation
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <AmiHobs.h>
+#include <Capsule.h>
+#include <Protocol/Capsule.h>
+
+
+typedef EFI_STATUS (OEM_PROCESS_CAPSULE) (EFI_CAPSULE_HEADER *Capsule);
+extern OEM_PROCESS_CAPSULE OEM_PROCESS_CAPSULE_LIST EndOfList;
+OEM_PROCESS_CAPSULE* OemProcessCapsuleList[] = { OEM_PROCESS_CAPSULE_LIST NULL };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessCapsule
+//
+// Description: Retrieve capsule and process it
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessCapsule(
+ VOID
+)
+{
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ static EFI_GUID AmiCapsuleHobGuid = AMI_CAPSULE_HOB_GUID;
+ static EFI_GUID CapsuleVendorGuid = EFI_CAPSULE_AMI_GUID;
+ EFI_STATUS Status;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHit;
+ UINTN i;
+ EFI_CAPSULE_HEADER *Capsule = NULL;
+ AMI_CAPSULE_HOB *CapsuleHob;
+ VOID *Save;
+
+
+ pHit = GetEfiConfigurationTable(pST, &HobListGuid);
+ if(EFI_ERROR(FindNextHobByGuid(&AmiCapsuleHobGuid, &pHit)))
+ return; //capsule HOB not found
+
+//capsule was found and coalesced, we have to kill mailbox
+ Status = pRS->SetVariable (
+ CAPSULE_UPDATE_VAR,
+ &CapsuleVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ 0,
+ (VOID *) Capsule);
+
+ CapsuleHob = (AMI_CAPSULE_HOB *)pHit;
+ Capsule = (EFI_CAPSULE_HEADER *)(VOID *)(UINTN)(CapsuleHob->CapsuleData);
+ for(i = 0; OemProcessCapsuleList[i] != NULL; i++) {
+ Status = OemProcessCapsuleList[i](Capsule);
+ if(!EFI_ERROR(Status))
+ return; //capsule is processed by OEM hook
+ }
+
+ if(Capsule->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) {
+ /* populate capsule via system table, move to runtime memory */
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, (UINTN)(CapsuleHob->CapsuleLength), &Save);
+ if(EFI_ERROR(Status))
+ return;
+
+ MemCpy(Save, (VOID *)(UINTN)(CapsuleHob->CapsuleData), (UINTN)(CapsuleHob->CapsuleLength));
+ Status = pBS->InstallConfigurationTable(&(CapsuleHob->CapsuleGuid), Save);
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Capsule2_0/Capsule2_0Runtime.c b/Core/EM/Capsule2_0/Capsule2_0Runtime.c
new file mode 100644
index 0000000..445fafc
--- /dev/null
+++ b/Core/EM/Capsule2_0/Capsule2_0Runtime.c
@@ -0,0 +1,457 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Capsule2_0/Capsule2_0Runtime.c 1 10/02/15 4:32a Chienhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 10/02/15 4:32a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Capsule2_0/Capsule2_0Runtime.c $
+//
+// 1 10/02/15 4:32a Chienhsieh
+// Update EIP225308
+//
+// 2 7/14/15 4:31p Artems
+// [TAG] EIP225308
+// [Category] Improvement
+// [Description] CAPSULE_UPDATE_VAR is not clear after WIN10 BSOD issue
+// capsule requriement.
+// [Files] Capsule2_0Runtime.c
+//
+// 1 5/24/12 4:22p Artems
+// [TAG] EIP74625
+// [Category] New Feature
+// [Description] New Capsule PPI required by latest Intel's MRC code
+// [Files] Capsule2_0.cif
+// Capsule2_0.sdl
+// Capsule2_0.mak
+// Capsule2_0.c
+// Capsule2_0.h
+// Capsule2_0Runtime.c
+// Capsule2_0Bds.c
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Capsule2_0Runtime.c
+//
+// Description: Capsule runtime services implementation
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include <Token.h>
+#include <Protocol/LoadedImage.h>
+#include <AmiDxeLib.h>
+#include <Capsule.h>
+#include <Protocol/Capsule.h>
+
+//----------------------------------------------------------------------
+#ifndef MAX_CAPSULE_ADDRESS
+#define MAX_CAPSULE_ADDRESS 0x100000000 //4GB
+#endif
+
+static EFI_CAPSULE_RUNTIME_DATA mCapsuleRuntimeData = { NULL, FALSE };
+
+static EFI_GUID gCapsuleVendorGuid = EFI_CAPSULE_AMI_GUID;
+static EFI_GUID gDxeServicesTableGuid = DXE_SERVICES_TABLE_GUID;
+
+EFI_STATUS UpdateCapsule(
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
+ IN UINTN CapsuleCount,
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
+);
+
+EFI_STATUS QueryCapsuleCapabilities(
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
+ IN UINTN CapsuleCount,
+ OUT UINT64 *MaximumCapsuleSize,
+ OUT EFI_RESET_TYPE *ResetType
+);
+
+BOOLEAN SupportUpdateCapsuleReset (
+ VOID
+);
+
+VOID SupportCapsuleSize (
+ IN OUT UINT32 *MaxSizePopulate,
+ IN OUT UINT32 *MaxSizeNonPopulate
+);
+
+VOID CapsuleExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+BOOLEAN ValidateSgl (
+ IN EFI_PHYSICAL_ADDRESS MailBox
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Capsule20RuntimeInit
+//
+// Description: Capsule runtime driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Capsule20RuntimeInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ pRS->UpdateCapsule = UpdateCapsule;
+ pRS->QueryCapsuleCapabilities = QueryCapsuleCapabilities;
+
+ Status = pBS->CreateEvent (
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_NOTIFY,
+ CapsuleExitBootServices,
+ &mCapsuleRuntimeData,
+ &(mCapsuleRuntimeData.CapsuleExitBootServiceEvent) );
+
+ pBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiCapsuleArchProtocolGuid,
+ NULL,
+ NULL );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateCapsule
+//
+// Description: This code finds if the capsule needs reset to update, if no, update immediately.
+//
+// Input:
+// IN EFI_CAPSULE_HEADER **CapsuleHeaderArray - array of pointers to capsule headers passed in
+// IN UINTN CapsuleCount - number of capsule
+// IN EFI_PHYSICAL_ADDRESS ScatterGatherList - physical address of datablock list points to capsule
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_INVALID_PARAMETER - CapsuleCount is less than 1,CapsuleGuid is not supported
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateCapsule (
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
+ IN UINTN CapsuleCount,
+ IN EFI_PHYSICAL_ADDRESS ScatterGatherList OPTIONAL
+)
+{
+ UINTN ArrayNumber;
+ VOID *BufferPtr;
+ EFI_STATUS Status;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+
+ if ((CapsuleCount < 1) || (CapsuleCount > MAX_SUPPORT_CAPSULE_NUM)){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BufferPtr = NULL;
+ CapsuleHeader = NULL;
+
+ //
+ //Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET
+ //and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is, the service supports.
+ //
+
+ for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
+ CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) &&
+ !(CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) &&
+ !(CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+// TODO: Add Oem porting hook to handle OEM-specific capsule
+ }
+
+ //
+ //Assume that capsules have the same flags on reseting or not.
+ //
+ CapsuleHeader = CapsuleHeaderArray[0];
+
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
+ //
+ //Check if the platform supports update capsule across a system reset
+ //
+ if (!SupportUpdateCapsuleReset()) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if (!ValidateSgl(ScatterGatherList)) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ Status = pRS->SetVariable (
+ CAPSULE_UPDATE_VAR,
+ &gCapsuleVendorGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof (EFI_PHYSICAL_ADDRESS),
+ (VOID *) &ScatterGatherList );
+ if (Status != EFI_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_INITIATE_RESET) != 0) {
+ pRS->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ EFI_DEADLOOP();
+ }
+
+ return EFI_SUCCESS;
+ }
+
+// TODO: Add Oem porting hook to handle OEM-specific capsule
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: QueryCapsuleCapabilities
+//
+// Description: This code is query about capsule capability
+//
+// Input:
+// IN EFI_CAPSULE_HEADER **CapsuleHeaderArray - array of pointers to capsule headers passed in
+// IN UINTN CapsuleCount - number of capsule
+// OUT UINT64 *MaximumCapsuleSize - pointer to store maximum supported capsule size
+// OUT EFI_RESET_TYPE *ResetType - reset type required by capsule
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_INVALID_PARAMETER - CapsuleCount is less than 1,CapsuleGuid is not supported,
+// MaximumCapsuleSize or ResetType are NULL
+// EFI_UNSUPPORTED - capsule type is not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS QueryCapsuleCapabilities(
+ IN EFI_CAPSULE_HEADER **CapsuleHeaderArray,
+ IN UINTN CapsuleCount,
+ OUT UINT64 *MaximumCapsuleSize,
+ OUT EFI_RESET_TYPE *ResetType
+)
+{
+ UINTN ArrayNumber;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ UINT32 MaxSizePopulate;
+ UINT32 MaxSizeNonPopulate;
+
+
+ if ((CapsuleCount < 1) || (CapsuleCount > MAX_SUPPORT_CAPSULE_NUM)){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((MaximumCapsuleSize == NULL) ||(ResetType == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CapsuleHeader = NULL;
+
+ //
+ //Compare GUIDs with EFI_CAPSULE_GUID, if capsule header contains CAPSULE_FLAGS_PERSIST_ACROSS_RESET
+ //and CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE flags,whatever the GUID is ,the service supports.
+ //
+ for (ArrayNumber = 0; ArrayNumber < CapsuleCount; ArrayNumber++) {
+ CapsuleHeader = CapsuleHeaderArray[ArrayNumber];
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE) &&
+ !(CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+//TODO add OEM hook to support OEM defined capsules
+ }
+
+ SupportCapsuleSize(&MaxSizePopulate,&MaxSizeNonPopulate);
+ //
+ //Assume that capsules have the same flags on reseting or not.
+ //
+ CapsuleHeader = CapsuleHeaderArray[0];
+ if ((CapsuleHeader->Flags & CAPSULE_FLAGS_PERSIST_ACROSS_RESET) != 0) {
+ //
+ //Check if the platform supports update capsule across a system reset
+ //
+ if (!SupportUpdateCapsuleReset()) {
+ return EFI_UNSUPPORTED;
+ }
+ *ResetType = EfiResetWarm;
+ *MaximumCapsuleSize = MaxSizePopulate;
+ } else {
+ *ResetType = EfiResetCold;
+ *MaximumCapsuleSize = MaxSizeNonPopulate;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SupportUpdateCapsuleReset
+//
+// Description: This function returns if the platform supports update capsule across a system reset.
+//
+// Input: None
+//
+// Output: TRUE - memory can be preserved across reset
+// FALSE - memory integrity across reset is not guaranteed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SupportUpdateCapsuleReset (
+ VOID
+)
+{
+ return SUPPORT_UPDATE_CAPSULE_RESET;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SupportCapsuleSize
+//
+// Description: This code returns the max size capsule the platform supports.
+//
+// Input:
+// IN OUT UINT32 *MaxSizePopulate - max supported capsule size, that updated across reset
+// IN OUT UINT32 *MaxSizeNonPopulate - max supported capsule size for immediate update
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SupportCapsuleSize (
+ IN OUT UINT32 *MaxSizePopulate,
+ IN OUT UINT32 *MaxSizeNonPopulate
+)
+{
+ //
+ //Here is a sample size, different platforms have different sizes.
+ //
+ *MaxSizePopulate = MAX_CAPSULE_SIZE;
+ *MaxSizeNonPopulate = MAX_CAPSULE_SIZE;
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CapsuleExitBootServices
+//
+// Description: Exit boot services event callback
+//
+// Input:
+// IN EFI_EVENT Event - Exit boot services event
+// IN VOID *Context - pointer to event context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CapsuleExitBootServices (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_CAPSULE_RUNTIME_DATA *pCapsuleRuntimeData;
+ //
+ // Get our context
+ //
+ pCapsuleRuntimeData = (EFI_CAPSULE_RUNTIME_DATA *) Context;
+ pCapsuleRuntimeData->IsRuntimeMode = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ValidateSgl
+//
+// Description:
+// This function validates ScatterGatherList
+//
+// Input:
+// IN EFI_PHYSICAL_ADDRESS MailBox - address of the capsule mailbox
+//
+// Output:
+// TRUE - ScatterGatherList is valid, FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ValidateSgl (
+ IN EFI_PHYSICAL_ADDRESS Mailbox
+)
+{
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *Ptr;
+ UINTN Chunks = 0;
+ UINT64 Result = 0;
+
+ if (Mailbox >= MAX_CAPSULE_ADDRESS || Mailbox == 0)
+ return FALSE;
+
+ Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)Mailbox;
+
+ do {
+ if(Ptr->DataBlock >= MAX_CAPSULE_ADDRESS) //pointer above 4GB
+ return FALSE;
+
+ if(Ptr->Length != 0) {
+ if(Ptr->Length > MAX_CAPSULE_SIZE - Result)
+ return FALSE;
+ Result += Ptr->Length;
+ Chunks++;
+ Ptr++;
+ } else if (Ptr->DataBlock != NULL) {
+ if(Ptr == (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer))
+ //when continuation pointer points to itself it's either error or malicious capsule, we won't process it
+ return FALSE;
+ Ptr = (EFI_CAPSULE_BLOCK_DESCRIPTOR *)(UINTN)(Ptr->ContinuationPointer);
+ } else {
+ break;
+ }
+ } while(Chunks <= MAX_CAPSULE_BLOCK_DESCRIPTOR_COUNT);
+
+ return (Chunks <= MAX_CAPSULE_BLOCK_DESCRIPTOR_COUNT) ? TRUE : FALSE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CmosManager/CmosAccess.asl b/Core/EM/CmosManager/CmosAccess.asl
new file mode 100644
index 0000000..aeff9ee
--- /dev/null
+++ b/Core/EM/CmosManager/CmosAccess.asl
@@ -0,0 +1,131 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosAccess.asl 4 1/25/12 2:36p Michaela $
+//
+// $Revision: 4 $
+//
+// $Date: 1/25/12 2:36p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosAccess.asl $
+//
+// 4 1/25/12 2:36p Michaela
+//
+// 3 12/11/11 8:52p Michaela
+//
+// 2 11/30/11 11:49p Michaela
+// [TAG] EIP56197
+// [Category] New Feature
+// [Severity] Normal
+// [Description] CMOS Manager Support in Runtime Code
+// [Files] CmosManager.sdl
+// CmosSetup.uni
+// CmosMessages.uni
+// CmosManagerSmm.cif
+// CmosAccess.h
+// CmosManagerSmm.c
+// CmosAccess.asl
+//
+// 1 3/16/11 2:44p Michaela
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CmosAccess.asl
+//
+// Description:
+// This file contains an ASL method for accessing CMOS from
+// ASL code.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+Device(CMOS)
+{
+ Name(_HID, EISAID("PNP0C02")) // System board resources
+ Name(_UID, 0x18) // Unique ID.
+
+ OperationRegion (SRB0, SystemIO, SRSI, 1)
+ Field (SRB0, ByteAcc, NoLock, Preserve)
+ {
+ SRSM, 8 // SW-SMI ctrl port
+ }
+
+ // Define a location in root scope to be updated during
+ // boot to specify the location of a communication buffer.
+ // Search CMOS_SMM_CONTEXT for data size/type info
+ // for this operation region (communication buffer).
+ // Search gAslContext for additional information regarding
+ // initialization and implemenataion details.
+
+ Name(\CCOM, 0x0123456789ABCDEF)
+
+ OperationRegion (CMOP, SystemMemory, CCOM, 40)
+ Field (CMOP, AnyAcc, NoLock, Preserve)
+ {
+ CODE, 8, // 1 byte Opcode
+ TOKN, 16, // 2 byte CMOS Token
+ BYTE, 8, // 1 byte Data value
+ STAT, 8 // 1 byte status value
+ }
+
+ //--------------------------------------------------------------------
+ // ACCE: access CMOS
+ // Arg0 - Opcode (0 = Write, 1 = Read)
+ // Arg1 - CmosToken
+ // Arg2 - CmosByte
+ //
+ // return - 0/FALSE = unsuccessful
+ // 1/TRUE = successful
+ //--------------------------------------------------------------------
+ Method(ACCE, 3, Serialized){
+
+ // if \CCOM is not updated, there was an error allocating the
+ // communication buffer.
+
+ if (LEqual(\CCOM, 0x0123456789ABCDEF)) {
+ Return(0)
+ }
+
+ // Write code & value to the communication buffer
+ Store(Arg0, CODE)
+ Store(Arg1, TOKN)
+ Store(Arg2, BYTE)
+
+ // Generate SMI type = CSMI
+ Store(CSMI, SRSM)
+ Store(BYTE, Arg2)
+
+ // Arg2 (BTYE) contains the CMOS value on read
+ // The method return value is Boolean
+ Return(STAT)
+ }
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosAccess.c b/Core/EM/CmosManager/CmosAccess.c
new file mode 100644
index 0000000..d3dea31
--- /dev/null
+++ b/Core/EM/CmosManager/CmosAccess.c
@@ -0,0 +1,2252 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosAccess.c 25 6/15/10 2:24p Michaela $
+//
+// $Revision: 25 $
+//
+// $Date: 6/15/10 2:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosAccess.c $
+//
+// 25 6/15/10 2:24p Michaela
+//
+// 24 3/10/10 4:39p Michaela
+//
+// 23 3/08/10 5:39p Michaela
+//
+// 22 3/08/10 1:31p Michaela
+//
+// 21 3/08/10 1:09p Michaela
+//
+// 20 3/05/10 4:55p Michaela
+//
+// 19 12/04/09 7:32p Michaela
+//
+// 18 12/03/09 6:42p Michaela
+// 1. Updated CmosReadWrite() to use physical access to
+// non-checksummed locations within the Managed Region
+// only if CMOS_RECOVER_ONLY_CHECKSUMMED is TRUE.
+// (controlled via CMOS_MGR_RECOVER_ONLY_CHECKUMMED
+// SDL token)
+//
+// 2. Added CanClearLegacyStatusBits() to determine
+// whether or not the legacy status bits can be
+// clear to a non-failure status.
+//
+// 3. SynchronizeLegacyStatusRegisters() is updated to
+// only clear the bad checksum failure status in
+// the legacy status registers in the DXE phase
+// or on the first boot after flashing the firmware.
+//
+// 17 11/10/09 9:14p Michaela
+//
+// 16 7/29/09 9:59a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 15 7/23/09 1:30p Michaela
+// Rename ReadRtcIndex and WriteRtcIndex
+//
+// 14 6/15/09 5:11p Michaela
+//
+// 13 6/02/09 3:27p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 12 2/23/09 6:03p Michaela
+// --code clean-up in CmosBankReadWrite()
+// --added test code to support test module it it is present
+//
+// 11 11/25/08 3:20p Michaela
+// Updates for Label 4.6.3_CMOSMGR_08
+// - Assembly macro fixes
+// - Added assembly macros
+// - Moved loading defaults into DXE phase
+// - Updated help file example
+//
+// 10 11/17/08 4:40p Michaela
+// --Removed Token Name strings in debug development code
+//
+// 9 11/17/08 3:39p Michaela
+// --Removed debug development code
+// --CMOS Buffer feature is depreciated
+// --ReadCmosStatusBytes and UpdateBatteryStatus now directly
+// calls CmosPhysicalReadWrite to avoid error when the
+// Optimal Defaults table is being used for reads & writes
+//
+// 8 11/14/08 9:12a Michaela
+// **CMOS register variables changed from UINT8 to UINT16
+// **added global CMOS_PORT_MAP array (gCmosBank) for
+// supporting board-specific access functions. The array is defined
+// using the CMOS_PORT_MAPPING Elink. The array starts at
+// index 1.
+// **Added CmosBankReadWrite() for calling the board-specific
+// access functions.
+// **Modified CmosPhysicalReadWrite() to call CmosBankReadWrite()
+// for physical CMOS access
+//
+// 7 11/07/08 5:13p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 6 3/25/08 3:04p Michaela
+// --deleted UpdateLegacyChecksumStatus
+// --Modified SynchronizeLegacyStatusRegisters to
+// update both battery and checksum status bits
+//
+// 5 3/07/08 4:07p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 4 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 3 2/26/08 12:49p Michaela
+// Added/modified Helpbuilder headers
+//
+// 2 2/22/08 3:20p Olegi
+// Renamed some of the equates to avoid the naming collisions.
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosAccess.c
+//
+// Description: Contains the routines that constitute the CMOS access
+// implementation. This file contains source code that is used
+// for both PEI and DXE phases.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#ifdef PEI_COMPILE
+ #include <Pei.h>
+ #include <AmiPeiLib.h>
+#else
+ #include <AmiDxeLib.h>
+#endif
+#include <CmosAccess.h>
+#include <SspTokens.h>
+#include "CmosManager.h"
+#include "CmosManagerHob.h"
+#include "CmosBoard.h"
+
+//---------------------------------------------------------------------------
+// CmosBank is initialized using the CMOS_PORT_MAPPING SDL Elink.
+// This array is used to determine which index/data port pair to use or
+// which board-specific access function to call for a specific CMOS register
+// address. The first element is not used and contains all zeros.
+//---------------------------------------------------------------------------
+
+CMOS_PORT_MAP gCmosBank[] = { {0,0,0,0,0}, CMOS_PORT_MAPPING };
+UINT16 gCmosBankCount = \
+ sizeof(gCmosBank) / sizeof(CMOS_PORT_MAP);
+
+EFI_CMOS_BATTERY_TEST gCmosBatteryIsGood = CMOS_BATTERY_TEST_MAPPING;
+
+//---------------------------------------------------------------------------
+// Function(s) originally defined in CmosManager.c
+//---------------------------------------------------------------------------
+extern EFI_CMOS_MANAGER_INTERFACE *GetCmosMangerInterface(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos );
+
+
+//---------------------------------------------------------------------------
+// Function(s) originally defined in CmosBuffer.c or CmosPhysical.c
+// depending on the sdl token BUFFERED_CMOS_SUPPORT
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// Function declarations for this file
+//---------------------------------------------------------------------------
+EFI_STATUS CalculateUpdatedCheckSum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN UINT16 CmosAddress,
+ IN UINT8 OldCmosValue,
+ IN UINT8 NewCmosValue,
+ OUT UINT16 *NewChecksum );
+
+EFI_STATUS CalculateChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 *ChecksumValue );
+
+EFI_STATUS WriteChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 ChecksumValue );
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EncodeParameter
+//
+// Description:
+// Value is shifted left by the bit field size specified in Token.
+//
+// Input:
+// OUT UINT8 *Value
+// -- Address of value to be encoded
+// IN CMOS_TOKEN *Token
+// -- Token describing the bit field size
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EncodeParameter(
+ OUT UINT8 *Value,
+ IN CMOS_TOKEN *Token )
+{
+ *Value <<= Token->Value.Field.BitOffset;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DecodeParameter
+//
+// Description:
+// Value is shifted right and masked by the bit field's size and offset
+// as specified in Token.
+//
+// Input:
+// OUT UINT8 *Value
+// -- Address of value to be decoded
+// IN CMOS_TOKEN *Token
+// -- Token describing the bit field's size and offset
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DecodeParameter(
+ OUT UINT8 *Value,
+ IN CMOS_TOKEN *Token )
+{
+ *Value >>= Token->Value.Field.BitOffset;
+ *Value &= (0xff >> (8 - Token->Value.Field.Size));
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BitFieldOverflow
+//
+// Description:
+// For testing whether or not a Value overflows the field size
+// as specified in Token.
+//
+// Input:
+// IN UINT8 *Value
+// -- Value to be tested
+// IN CMOS_TOKEN *Token
+// -- Token describing the bit field's size
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN BitFieldOverflow(
+ IN UINT8 *Value,
+ IN CMOS_TOKEN *Token )
+{
+ if ( *Value & ~(0xff >> (8 - Token->Value.Field.Size)) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetClobberBits
+//
+// Description:
+// Creates a mask with bits set corresponding to the size and offset
+// of the bit field as specified by Token.
+//
+// Input:
+// OUT UINT8 *Mask
+// -- Mask to be created
+// IN CMOS_TOKEN *Token
+// -- Token describing the bit field's size and offset
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SetClobberBits(
+ OUT UINT8 *Mask,
+ IN CMOS_TOKEN *Token )
+{
+ *Mask = 0xff >> (8 - Token->Value.Field.Size);
+ *Mask <<= Token->Value.Field.BitOffset;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosFindToken
+//
+// Description:
+// Returns index of CMOS token in token table or 0 if not found.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- This is the CMOS Manager interface pointer.
+// IN UINT16 CmosToken
+// -- Encoded CMOS token for which to locate an index into
+// the CMOS token table
+//
+// Output:
+// UINT16 (Return Value)
+// = Index of the CmosToken in the token table, or
+// = 0, if the CmosToken was not found
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 CmosFindToken(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN UINT16 CmosToken )
+{
+ UINT16 i = 0; // First valid token table index is 1
+
+ while (++i < Manager->TokenCount) {
+ if (Manager->TokenTable[i].Value.AllBits == CmosToken) {
+ break;
+ }
+ }
+
+ if (i < Manager->TokenCount)
+ return i;
+
+ return 0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosGetTokenFromRegister
+//
+// Description:
+// Returns encoded token for the specified register.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- This is the CMOS Manager interface pointer.
+// IN UINT8 CmosRegister
+// -- CMOS register to for which to search
+//
+// Output:
+// UINT16 (Return Value)
+// = Token found in the token table, or
+// = 0, if the Register was not found
+//
+// Notes:
+//
+// Caller must ensure the register has been reserved properly
+// in SSP.
+//
+// This should be considered a risky function call and extra care
+// should be taken to ensure the proper CmosRegister is specified.
+//
+// This function has the potential for problems, as it is possible that
+// a specified CmosRegister has not been defined in SSP and/or may
+// be used by another CmosToken.
+//
+// All verification of parameters must be done by the caller.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 CmosGetTokenFromRegister(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN UINT16 CmosRegister )
+{
+ UINT16 i = 0;
+ EFI_CMOS_MANAGER_INTERFACE *Manager = GetCmosMangerInterface(Cmos);
+
+ // Manager->TokenCount is the total number of entries in
+ // Manager->TokenTable where the first entry is zero.
+
+ while (++i < Manager->TokenCount) {
+ if (Manager->TokenTable[i].Value.Field.CmosAddress == CmosRegister){
+ break;
+ }
+ }
+
+ // Minimal error checking is to ensure it is an 8-bit CMOS Token
+ if (i < Manager->TokenCount ){
+ if (Manager->TokenTable[i].Value.Field.Size == 8)
+ return Manager->TokenTable[i].Value.AllBits;
+ }
+
+ // a valid token is greater than 0x1000
+ return 0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosBankReadWrite
+//
+// Description:
+// This function determines which structure in the global CMOS_PORT_MAP
+// array corresponds to the provided CmosAddress and either calls the
+// associated function or uses the associated IO ports to read/write the
+// CMOS register value to/from the CmosParameterValue.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the CMOS Manager internal interface
+// IN CMOS_ACCESS_TYPE AccessType
+// -- WriteType or ReadType
+// IN UINT16 CmosAddress
+// -- CMOS register to for which the access is to be made
+// IN/OUT UINT8 *CmosParameterValue
+// -- This is the value to write for write access or the
+// value that was read for read access.
+//
+//
+// Output:
+// EFI_STATUS (Return Value)
+// EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// N/A
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosBankReadWrite(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosAddress,
+ IN OUT UINT8 *CmosParameterValue )
+{
+ UINT8 i = 1;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices); // defines NULL if DXE
+
+ // scan the CMOS_PORT_MAP array to determine how to access this address
+ for (; i < gCmosBankCount; i++)
+ {
+ if ( (CmosAddress >= gCmosBank[i].Low)
+ && (CmosAddress <= gCmosBank[i].High) )
+ {
+
+ // First, attempt to call the board-specific function if available
+ if (gCmosBank[i].BoardReadWrite != NULL){
+ Status = gCmosBank[i].BoardReadWrite( PeiServices,
+ AccessType,
+ CmosAddress,
+ CmosParameterValue );
+ break;
+ }
+
+ // Otherwise, attempt to use the provided index/data ports
+ // if available (assuming 8 bit port access)
+ else if ( (gCmosBank[i].Index > 0) && (gCmosBank[i].Data > 0) ){
+ IoWrite8( gCmosBank[i].Index, (UINT8)CmosAddress );
+ if (AccessType == ReadType){
+ *CmosParameterValue = IoRead8( gCmosBank[i].Data );
+ }
+ else {
+ IoWrite8( gCmosBank[i].Data, *CmosParameterValue );
+ }
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ }
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosPhysicalReadWrite
+//
+// Description:
+// This function provides support for performing the actual
+// read or write from/to a physical CMOS location.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager interface pointer
+// IN CMOS_ACCESS_TYPE AccessType
+// -- Specifies whether to perform a read or a write
+// IN UINT8 CmosAddress
+// -- Actual CMOS address/offset
+// IN UINT8 BitsToWrite
+// -- Mask specifying the bits to be written (these
+// bits will be cleared first)
+// IN OUT UINT8 *CmosParameterValue
+// -- CMOS value to be written or, on successful exit, will
+// contain the value that was read
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosPhysicalReadWrite(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosAddress,
+ IN UINT8 BitsToWrite,
+ IN OUT UINT8 *CmosParameterValue )
+{
+ UINT8 CmosRegisterValue;
+ UINT8 NewValue;
+ UINT16 NewChecksum = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ // Always read the value
+ CmosBankReadWrite( Manager,
+ ReadType,
+ CmosAddress,
+ &CmosRegisterValue );
+
+ // If read access, simply return the unmodified data
+ if ( AccessType == ReadType ) {
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ " Physical Read: Register 0x%02X = 0x%02X\n",
+ CmosAddress, CmosRegisterValue));
+ *CmosParameterValue = CmosRegisterValue;
+ }
+
+ // If writing, then don't clobber unused bits
+ else {
+ NewValue = (CmosRegisterValue & ~BitsToWrite) | *CmosParameterValue;
+
+ // get the new checksum before writing
+ if (!Manager->CheckStatus(Manager, CMOS_FORCE_NO_CHECKSUM))
+ Status = CalculateUpdatedCheckSum( Manager, CmosAddress,
+ CmosRegisterValue, NewValue, &NewChecksum);
+
+ // write the value
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ " Physical Write: Register 0x%02X = 0x%02X\n",
+ CmosAddress, NewValue));
+ CmosBankReadWrite( Manager,
+ WriteType,
+ CmosAddress,
+ &NewValue );
+
+ // write the checksum, if necessary
+ // (this write will cause an infinite loop without a flag)
+ if (!Manager->CheckStatus(Manager, CMOS_FORCE_NO_CHECKSUM)){
+ if (Manager->CheckStatus(Manager, CMOS_ADDRESS_IS_CHECKSUMMED)){
+ Manager->SetStatus(Manager, CMOS_FORCE_NO_CHECKSUM);
+ WriteChecksum( Manager, NewChecksum );
+ Manager->ClearStatus(Manager, CMOS_FORCE_NO_CHECKSUM);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: NotChecksummed
+//
+// Description:
+// This function returns TRUE if the CmosAddress is NOT included in the
+// checksum and returns FALSE otherwise.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager interface pointer
+// IN UINT8 CmosAddress
+// -- Actual CMOS address/offset
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if CmosAddress is NOT included in the checksum
+// = FALSE if CmosAddress IS included in the checksum
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN NotChecksummed(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN UINT16 CmosAddress )
+{
+ UINT16 NoChecksumIndex = 1; // NoChecksumTable starts at 1
+
+ while ( (NoChecksumIndex < Mgr->NoChecksumCount)
+ && (CmosAddress > Mgr->NoChecksumTable[NoChecksumIndex].Index) )
+ {
+ ++NoChecksumIndex;
+ }
+
+ if ( CmosAddress == Mgr->NoChecksumTable[NoChecksumIndex].Index )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosBufferReadWrite
+//
+// Description:
+// This function provides support for performing the actual
+// read or write from/to a CMOS buffer location (using the
+// Optimal Defaults Table Buffer).
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager interface pointer
+// IN CMOS_ACCESS_TYPE AccessType
+// -- Specifies whether to perform a read or a write
+// IN UINT8 CmosAddress
+// -- Actual CMOS address/offset
+// IN UINT8 BitsToWrite
+// -- Mask specifying the bits to be written (these
+// bits will be cleared first)
+// IN OUT UINT8 *CmosParameterValue
+// -- CMOS value to be written or, on successful exit, will
+// contain the value that was read
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+//
+// Control comes here because of one of two reasons:
+//
+// 1) The checksum is bad
+//
+// All writes/read are to/from the
+// Manager->OptimalDefaultTable only for locations not found
+// in the Manager->NoChecksumTable until DXE phase.
+//
+// 2) The battery is bad
+//
+// All writes/read are to/from the
+// Manager->OptimalDefaultTable for all locations.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosBufferReadWrite(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosAddress,
+ IN UINT8 BitsToWrite,
+ IN OUT UINT8 *CmosParameterValue )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 NewValue;
+ UINT16 NewChecksum = 0;
+ UINT8 CmosRegisterValue;
+ // First CMOS register @ buffer index 1
+ UINT16 BufferIndex = CmosAddress - FIRST_CMOS_REGISTER + 1;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ if (CmosAddress < FIRST_CMOS_REGISTER || CmosAddress > LAST_CMOS_REGISTER){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ " CmosBufferReadWrite: Invalid CmosAddress (0x%X)\n",
+ CmosAddress ));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // get the default value from the table
+ CmosRegisterValue = Manager->OptimalDefaultTable[BufferIndex].Value;
+
+ // If read access, simply return the unmodified data
+ if ( AccessType == ReadType ) {
+ *CmosParameterValue = CmosRegisterValue;
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " Buffer Read: 0x%X = OptimalDefaultTable[%d].Value \n",
+ CmosRegisterValue, BufferIndex ));
+ }
+
+ // If writing, mark the location as dirty and don't clobber unused bits
+ else {
+ NewValue = (CmosRegisterValue & ~BitsToWrite) | *CmosParameterValue;
+
+ // get the new checksum before writing (this sets or clears
+ // the CMOS_ADDRESS_IS_CHECKSUMMED Manager->ManagerStatus flag)
+ if (!Manager->CheckStatus(Manager, CMOS_FORCE_NO_CHECKSUM)) {
+ Status = CalculateUpdatedCheckSum( Manager, CmosAddress,
+ CmosRegisterValue, NewValue, &NewChecksum);
+ }
+
+ // Optimal default table writes take precedence
+ Manager->OptimalDefaultTable[BufferIndex].Value = NewValue;
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " Buffer Write: OptimalDefaultTable[%d].Value = 0x%X\n",
+ BufferIndex, NewValue ));
+
+ // write the checksum, if necessary
+ // (this write will cause an infinite loop without a flag)
+ if (!Manager->CheckStatus(Manager, CMOS_FORCE_NO_CHECKSUM)){
+ if (Manager->CheckStatus(Manager, CMOS_ADDRESS_IS_CHECKSUMMED)){
+ Manager->SetStatus(Manager, CMOS_FORCE_NO_CHECKSUM);
+ WriteChecksum( Manager, NewChecksum );
+ Manager->ClearStatus(Manager, CMOS_FORCE_NO_CHECKSUM);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " NewChecksum = 0x%X\n",
+ NewChecksum ));
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosReadWrite
+//
+// Description:
+// Decides which version of xxxReadWrite to call based upon the
+// current Access Routing Logic.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager interface pointer
+// IN CMOS_ACCESS_TYPE AccessType
+// -- Specifies whether to perform a read or a write
+// IN UINT8 CmosAddress
+// -- Actual CMOS address/offset
+// IN UINT8 BitsToWrite
+// -- Mask specifying the bits to be written (these
+// bits will be cleared first)
+// IN OUT UINT8 *CmosParameter
+// -- CMOS value to be written or, on successful exit, will
+// contain the value that was read
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosReadWrite(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosAddress,
+ IN UINT8 BitsToWrite,
+ IN OUT UINT8 *CmosParameter )
+{
+ BOOLEAN UseBufferAccess = FALSE;
+
+ // If the checksum is bad or the battery is bad, accesses will be
+ // routed to the optimal default table by default.
+
+ if ( Mgr->CheckStatus( Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED )){
+ UseBufferAccess = TRUE;
+
+ // Force physical access if these conditions are applicable:
+ //
+ // 1. the CMOS is usable,
+ // 2. recovery is limited to only checksummed locations
+ // 3. the current location is not checksummed
+
+ if ( Mgr->CheckStatus( Mgr, CMOS_IS_USABLE )
+ && Mgr->CheckStatus( Mgr, CMOS_RECOVER_ONLY_CHECKSUMMED )
+ && NotChecksummed( Mgr, CmosAddress ) )
+ {
+ UseBufferAccess = FALSE;
+ }
+ }
+
+ if (UseBufferAccess)
+ return CmosBufferReadWrite( Mgr,
+ AccessType,
+ CmosAddress,
+ BitsToWrite,
+ CmosParameter);
+ else
+ return CmosPhysicalReadWrite( Mgr,
+ AccessType,
+ CmosAddress,
+ BitsToWrite,
+ CmosParameter);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosReadWriteEncodedToken
+//
+// Description:
+// This is the main worker function which verifies and either
+// reads/writes a value from/to the CMOS location as specified by the
+// encoded token.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- This is the CMOS Manager interface pointer.
+// IN CMOS_ACCESS_TYPE AccessType
+// -- Specifies whether to perform a read or a write
+// IN UINT16 TokenTableIndex
+// -- Index into the token table
+// IN OUT UINT8 *CmosParameter
+// -- CMOS value to be written or, on successful exit, will
+// contain the value that was read
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = EFI_INVALID_PARAMETER, if the CmosParameter does
+// not comply with the expected size
+// = or other valid EFI error code
+//
+// Notes:
+// 1) Gets the CMOS token from the global table
+// 2) If writing, the value is error-checked for size and
+// up-shifted to the correct bit position. Also, the
+// BitsToWrite mask is used to specify
+// which bits to clear in the destination before
+// writing.
+// 3) This token is decoded to get the CMOS index,
+// 4) The read/write is performed
+// 5) If reading, the value is down-shifted and masked to
+// return the expected value.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosReadWriteEncodedToken(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 TokenTableIndex,
+ IN OUT UINT8 *CmosParameter )
+{
+ CMOS_TOKEN *CmosToken = &Manager->TokenTable[TokenTableIndex];
+ UINT8 BitsToWrite = 0;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ // If writing, encode the CmosParameter
+
+ if (AccessType == WriteType) {
+
+ // Check to make sure the data is the correct size for the bit field
+
+ if ( BitFieldOverflow(CmosParameter, CmosToken) ){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Shift up to the correct offset within the byte
+
+ EncodeParameter(CmosParameter, CmosToken);
+
+ // Set the bits in BitsToWrite mask that are
+ // consumed by this token
+
+ SetClobberBits(&BitsToWrite, CmosToken);
+ }
+
+ // Read (or write) the CmosParameter to actual (or CMOS buffer) location
+
+ CmosReadWrite(Manager,
+ AccessType,
+ (UINT16)CmosToken->Value.Field.CmosAddress, // byte address
+ BitsToWrite,
+ CmosParameter);
+
+ // If reading, shift down to bit-position zero and mask off upper bits
+
+ if (AccessType == ReadType)
+ DecodeParameter(CmosParameter, CmosToken);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosRead
+//
+// Description:
+// Reads to CmosValue from the CMOS location specified by CmosToken.
+//
+// Input:
+// IN EFI_CMOS_ACCESS_INTERFACE *Cmos
+// -- This is the access interface pointer.
+// IN UINT16 CmosToken
+// -- This is the encoded CMOS location.
+// OUT UINT8 *CmosValue
+// -- On success, this will contain the value at
+// the specified CMOS location.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = EFI_NOT_FOUND, if the token is not in the token table
+// = or other valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosRead(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN UINT16 CmosToken,
+ OUT UINT8 *CmosValue )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT16 TokenTableIndex = 0;
+ EFI_CMOS_MANAGER_INTERFACE *Mgr = GetCmosMangerInterface(Cmos);
+ DEFINE_PEI_SERVICES(Cmos->PeiServices);
+
+ // if CmosToken <= 0xe, then always read the register. These registers
+ // will be readable regardless of the state of the battery.
+
+ if (CmosToken <= 0xe){
+ Status = CmosBankReadWrite( Mgr, ReadType, CmosToken, CmosValue );
+ }
+
+ // Otherwise, if CmosToken < MIN_TOKEN_VALUE and the battery is good,
+ // then directly read the register. (For a bad battery, return
+ // EFI_DEVICE_ERROR.)
+
+ else if (CmosToken < MIN_TOKEN_VALUE) {
+ if ( !Mgr->CheckStatus( Mgr, CMOS_IS_USABLE ) ) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ else {
+ Status = CmosBankReadWrite( Mgr, ReadType, CmosToken, CmosValue );
+ }
+ }
+
+ // Otherwise, after validating the CmosToken, decode it to read the
+ // associated register bit(s).
+
+ else {
+ TokenTableIndex = CmosFindToken(Mgr, CmosToken);
+ if (TokenTableIndex > 0) {
+ Status = CmosReadWriteEncodedToken( Mgr, ReadType,
+ TokenTableIndex, CmosValue);
+ }
+ else
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReadCmosBytes
+//
+// Description:
+// Reads Bytes from the specified CMOS register(s).
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manger interface pointer.
+// IN UINT8 Count
+// -- Count of CMOS_BYTEs to read
+// OUT CMOS_BYTE *Bytes
+// -- An array of CMOS_BYTE structures
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadCmosBytes(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN UINT16 Count,
+ OUT CMOS_BYTE *CmosBytes )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 i = 0;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+
+ for (; i < Count; i++){
+ Status = CmosReadWrite(Manager, ReadType, CmosBytes[i].Register, 0,
+ &CmosBytes[i].Value);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReadCmosStatusBytes
+//
+// Description:
+// Initializes a CMOS_STATUS_BYTES structure and reads the associated
+// CMOS registers.
+//
+// Input:
+// IN EFI_CMOS_ACCESS_INTERFACE *Cmos
+// -- Manger interface pointer.
+// OUT CMOS_STATUS_BYTES *StatusBytes
+// -- Address of a valid, uninitialized, CMOS_STATUS_BYTES
+// structure.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadCmosStatusBytes(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ OUT CMOS_STATUS_BYTES *StatusBytes )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_CMOS_MANAGER_INTERFACE *Mgr = GetCmosMangerInterface(Cmos);
+ UINT8 CmosValue;
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ if (StatusBytes == NULL)
+ return Status = EFI_INVALID_PARAMETER;
+
+ StatusBytes->DiagnosticStatusRegister = CMOS_DIAGNOSTIC_STATUS_REGISTER;
+ StatusBytes->BatteryStatusRegister = CMOS_RTC_STATUS_REGISTER;
+
+ CmosPhysicalReadWrite( Mgr,
+ ReadType,
+ StatusBytes->BatteryStatusRegister,
+ 0,
+ &StatusBytes->Battery.AllBits );
+
+ CmosPhysicalReadWrite( Mgr,
+ ReadType,
+ StatusBytes->DiagnosticStatusRegister,
+ 0,
+ &StatusBytes->Diagnostic.AllBits );
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED) )
+ StatusBytes->ConfigurationStatus.IsVirtualized = TRUE;
+ else
+ StatusBytes->ConfigurationStatus.IsVirtualized = FALSE;
+
+ // If the CMOS hardware is usable, update from cmos-based
+ // status bits, which are more reliable. Otherwise, use the
+ // the memory-based status.
+ //
+ // Note, some information could be lost on reset in DXE
+ // when using the memory-based status.
+ //
+ // Also, register 0xe is cleared in DXE, if the CMOS
+ // is usable and the checksum has been recalculated.
+
+ StatusBytes->ConfigurationStatus.BadBattery = FALSE;
+ StatusBytes->ConfigurationStatus.DefaultsLoaded = FALSE;
+ StatusBytes->ConfigurationStatus.IsFirstBoot = FALSE;
+ StatusBytes->ConfigurationStatus.BadChecksum = FALSE;
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_IS_USABLE) ) {
+ StatusBytes->ConfigurationStatus.NotUsable = FALSE;
+
+ Cmos->Read( Cmos, CMOS_MGR_BATTERY_BAD, &CmosValue );
+ StatusBytes->ConfigurationStatus.BadBattery |= CmosValue;
+
+ Cmos->Read( Cmos, CMOS_MGR_DEFAULTS_LOADED, &CmosValue );
+ StatusBytes->ConfigurationStatus.DefaultsLoaded |= CmosValue;
+
+ Cmos->Read( Cmos, CMOS_MGR_FIRST_BOOT_DETECTED, &CmosValue );
+ StatusBytes->ConfigurationStatus.IsFirstBoot |= CmosValue;
+
+ Cmos->Read( Cmos, CMOS_MGR_CHECKSUM_BAD,&CmosValue );
+ StatusBytes->ConfigurationStatus.BadChecksum |= CmosValue;
+ }
+ else {
+ StatusBytes->ConfigurationStatus.NotUsable = TRUE;
+ if ( Mgr->CheckStatus(Mgr, CMOS_BAD_BATTERY) )
+ StatusBytes->ConfigurationStatus.BadBattery = TRUE;
+ if ( Mgr->CheckStatus(Mgr, CMOS_DEFAULTS_LOADED) )
+ StatusBytes->ConfigurationStatus.DefaultsLoaded = TRUE;
+ if ( Mgr->CheckStatus(Mgr, CMOS_FIRST_BOOT_DETECTED) )
+ StatusBytes->ConfigurationStatus.IsFirstBoot = TRUE;
+ if ( Mgr->CheckStatus(Mgr, CMOS_BAD_CHECKSUM) )
+ StatusBytes->ConfigurationStatus.BadChecksum = TRUE;
+ }
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReadChecksum
+//
+// Description:
+// Reads the checksum from the CMOS register(s).
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manger interface pointer.
+// OUT UINT16 *ChecksumValue
+// -- The returned checksum value
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 *ChecksumValue )
+{
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ Manager->Access.Read( &Manager->Access, CMOS_CHECKSUM_HIGH,
+ (UINT8*)ChecksumValue );
+ *ChecksumValue <<= 8;
+ Manager->Access.Read( &Manager->Access, CMOS_CHECKSUM_LOW,
+ (UINT8*)ChecksumValue );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: WriteChecksum
+//
+// Description:
+// Write the checksum to the CMOS register(s).
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manger interface pointer.
+// IN UINT16 ChecksumValue
+// -- Value to write to the checksum location.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS WriteChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN UINT16 ChecksumValue )
+{
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ // update the HOB if available
+
+ if (Manager->ManagerHob != NULL)
+ Manager->ManagerHob->Checksum = ChecksumValue;
+
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "WriteChecksum: Value = 0x%X\n",
+ ChecksumValue ));
+
+ // update the CMOS checksum
+
+ Manager->SetStatus(Manager, CMOS_FORCE_NO_CHECKSUM);
+ Manager->Access.Write( &Manager->Access, CMOS_CHECKSUM_LOW,
+ (UINT8)ChecksumValue );
+ ChecksumValue >>= 8;
+ Manager->Access.Write( &Manager->Access, CMOS_CHECKSUM_HIGH,
+ (UINT8)ChecksumValue );
+ Manager->ClearStatus(Manager, CMOS_FORCE_NO_CHECKSUM);
+
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdateBatteryStatus
+//
+// Description:
+// This function is used to update the CMOS battery status. It is up
+// to the user of the Manager interface to determine whether or ot
+// the platform supports this feature. (If the platform does not
+// support this feature, the battery status is indeterminate.)
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS UpdateBatteryStatus (
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ BOOLEAN IsGood;
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS, "\n\nUpdateBatteryStatus Entry\n"));
+
+ // Update the battery status bit in the Manager's CMOS_MANAGER_STATUS
+ // field and update the legacy CMOS status register if legacy register
+ // updates are enabled.
+
+#ifdef PEI_COMPILE
+ IsGood = gCmosBatteryIsGood( PeiServices );
+#else
+ IsGood = gCmosBatteryIsGood( NULL );
+#endif
+
+ if ( IsGood ) {
+ Mgr->ClearStatus(Mgr, CMOS_BAD_BATTERY);
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS, " ...Battery is good.\n" ));
+ }
+ else {
+ Mgr->SetStatus(Mgr, CMOS_BAD_BATTERY);
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS, " ...Battery is BAD!!\n" ));
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CanClearLegacyStatusBits
+//
+// Description:
+// Determines whether or not the legacy status bits in
+// CMOS_DIAGNOSTIC_STATUS_REGISTER can be cleared to a non-failure
+// status.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Mgr
+// -- Manger interface pointer
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE - bits can be cleared
+// = FALSE - bits can be cleared
+//
+// Notes:
+//
+// EFI_CMOS_ACCESS_INTERFACE.PeiServices == NULL in DXE phase.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CanClearLegacyStatusBits (
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr )
+{
+ BOOLEAN IsDxePhase = (Mgr->Access.PeiServices == NULL) ? TRUE : FALSE;
+ BOOLEAN IsFirstBoot = Mgr->CheckStatus(Mgr, CMOS_FIRST_BOOT_DETECTED);
+
+ if ( IsDxePhase ){
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SynchronizeLegacyStatusRegisters
+//
+// Description:
+// Synchronizes legacy CMOS status registers with status changes.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manger interface pointer
+// IN CMOS_MANAGER_STATUS BitMap
+// -- The status bits to be modified
+// IN CMOS_BIT_ACCESS_TYPE AccessType
+// -- Specifies whether to set or clear the bits
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// The BitMap contains all the bits to be modified in the legacy
+// status registers.
+//
+// If CMOS_LEGACY_STATUS_ENABLED is off, or is being turned off, this
+// function will not modify CMOS registers.
+//
+// Failure status bits in CMOS_DIAGNOSTIC_STATUS_REGISTER can only be
+// cleared if this is the first boot or if executing in the DXE phase.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SynchronizeLegacyStatusRegisters(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN CMOS_MANAGER_STATUS BitMap,
+ IN CMOS_BIT_ACCESS_TYPE AccessType )
+{
+ DIAGNOSTIC_STATUS_BYTE StatusByte;
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "\n\nSynchronizeLegacyStatusRegisters: Entry\n" ));
+
+ // If the checksum status is being modified,
+ // then update the ChecksumIsBad bit
+
+ if ( (BitMap & CMOS_BAD_CHECKSUM) != 0 )
+ {
+ // Read the legacy diagnostic status register
+
+ CmosBankReadWrite( Mgr, ReadType, CMOS_DIAGNOSTIC_STATUS_REGISTER,
+ &StatusByte.AllBits );
+
+ if (AccessType == SetType){
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.ChecksumIsBad = 1\n" ));
+ StatusByte.Field.ChecksumIsBad = 1;
+ }
+ else if ( CanClearLegacyStatusBits(Mgr) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.ChecksumIsBad = 0\n" ));
+ StatusByte.Field.ChecksumIsBad = 0;
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.ChecksumIsBad = No Change\n" ));
+ }
+
+ // write back the changes
+
+ CmosBankReadWrite( Mgr, WriteType, CMOS_DIAGNOSTIC_STATUS_REGISTER,
+ &StatusByte.AllBits );
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.ChecksumIsBad = No Change\n" ));
+ }
+
+
+
+ // If the battery status is being modified,
+ // then update the RtcPowerIsBad bit
+
+ if ( (BitMap & CMOS_BAD_BATTERY) != 0 )
+ {
+ // Read the legacy diagnostic status register
+
+ CmosBankReadWrite( Mgr, ReadType, CMOS_DIAGNOSTIC_STATUS_REGISTER,
+ &StatusByte.AllBits );
+
+ if (AccessType == SetType){
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.RtcPowerIsBad = 1\n" ));
+ StatusByte.Field.RtcPowerIsBad = 1;
+ }
+ else if ( CanClearLegacyStatusBits(Mgr) ) {
+ StatusByte.Field.RtcPowerIsBad = 0;
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.RtcPowerIsBad = 0\n" ));
+ }
+
+ // Write the legacy diagnostic status register
+
+ CmosBankReadWrite( Mgr, WriteType, CMOS_DIAGNOSTIC_STATUS_REGISTER,
+ &StatusByte.AllBits );
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " StatusByte.Field.RtcPowerIsBad = No Change\n" ));
+ }
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "SynchronizeLegacyStatusRegisters: Exit\n\n" ));
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateUpdatedCheckSum
+//
+// Description:
+// Computes a new "updated" CMOS checksum based on the change of value
+// at a single address.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- The Manger interface pointer.
+// IN UINT16 CmosAddress
+// -- CMOS location to be changed
+// IN UINT8 OldCmosValue
+// -- Current value at the CMOS location
+// IN UINT8 NewCmosValue
+// -- New value to be written to the CMOS location
+// OUT UINT16 *NewChecksum
+// -- Updated checksum
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or a valid EFI error code
+//
+// Notes:
+// After this call, Manager->CheckStatus(Manager,
+// CMOS_ADDRESS_IS_CHECKSUMMED) returns TRUE if the address "is"
+// included in the checksum.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CalculateUpdatedCheckSum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN UINT16 CmosAddress,
+ IN UINT8 OldCmosValue,
+ IN UINT8 NewCmosValue,
+ OUT UINT16 *NewChecksum )
+{
+ UINT16 UnmanagedIndex = 1; // UnmanagedTable starts at 1
+ UINT16 NoChecksumIndex = 1; // NoChecksumTable starts at 1
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ // Check if the address is included in the NoChecksumTable
+ // or the UnmanagedTable
+
+ while ( NoChecksumIndex < Mgr->NoChecksumCount )
+ {
+ if ( CmosAddress <= Mgr->NoChecksumTable[NoChecksumIndex].Index )
+ break;
+ ++NoChecksumIndex;
+ }
+
+ while ( UnmanagedIndex < Mgr->UnmanagedTableCount )
+ {
+ if ( CmosAddress <= Mgr->UnmanagedTable[UnmanagedIndex].Index )
+ break;
+ ++UnmanagedIndex;
+ }
+
+
+ // Set ManagerStatus and compute NewChecksum if necessary
+
+ if ( CmosAddress == Mgr->NoChecksumTable[NoChecksumIndex].Index
+ || CmosAddress == Mgr->UnmanagedTable[UnmanagedIndex].Index )
+ {
+#if (FULL_CMOS_MANAGER_DEBUG)
+ if ( CmosAddress == Mgr->NoChecksumTable[NoChecksumIndex].Index ) {
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, " ->Not Checksummed (0x%X)\n", CmosAddress ));
+ }
+ else {
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, " ->Not Managed (0x%X)\n", CmosAddress ));
+ }
+#endif
+ Mgr->ClearStatus(Mgr, CMOS_ADDRESS_IS_CHECKSUMMED);
+ }
+ else {
+ ReadChecksum( Mgr, NewChecksum );
+ *NewChecksum = *NewChecksum - OldCmosValue + NewCmosValue;
+ Mgr->SetStatus(Mgr, CMOS_ADDRESS_IS_CHECKSUMMED);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateChecksum
+//
+// Description:
+// Calculate the checksum over the entire range of managed CMOS
+// (standard and/or extended CMOS).
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- The Manger interface pointer.
+// OUT UINT16 *ChecksumValue
+// -- The calculated checksum.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Modified:
+// Manager->ManagerStatus
+// CMOS_BAD_CHECKSUM - set/clear after comparing with
+// the current checksum in CMOS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CalculateChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ OUT UINT16 *ChecksumValue )
+{
+ //-----------------------------------------------------------------------
+ // Algorithm Notes:
+ //
+ // The NoChecksumTable is in numeric order and contains all CMOS
+ // registers starting at FIRST_CMOS_REGISTER and ending with
+ // LAST_CMOS_REGISTER unless the register has been explicitly specified
+ // with Checksum = YES in the NvramField declaration.
+ //
+ // ...the NoChecksumTable need traversed only once.
+ //-----------------------------------------------------------------------
+
+ UINT16 CurRegister;
+ UINT8 CurValue;
+ UINT16 UnmanagedIndex = 1; // UnmanagedTable starts at 1
+ UINT16 NoChecksumIndex = 1; // NoChecksumTable starts at 1
+ UINT16 CurrentChecksum;
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ *ChecksumValue = 0; // ...just in case
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "\n\nCalculateChecksum: Entry\n" ));
+
+ // Calculate it
+ for ( CurRegister = Mgr->FirstManagedRegister;
+ CurRegister <= Mgr->LastManagedRegister; // inclusive
+ ++CurRegister )
+ {
+ //---------------------------------------------
+ // Skip the location if the location is not managed
+ //
+ // Note: the UnmanagedTable is in numeric order,
+ // so it only needs traversed one time.
+ //---------------------------------------------
+
+ while ( (UnmanagedIndex < Mgr->UnmanagedTableCount)
+ && (CurRegister
+ > Mgr->UnmanagedTable[UnmanagedIndex].Index) )
+ {
+ ++UnmanagedIndex;
+ }
+ if ( CurRegister == Mgr->UnmanagedTable[UnmanagedIndex].Index ){
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " -->0x%X (un-managed)\n", CurRegister));
+ continue;
+ }
+
+
+ while ( (NoChecksumIndex < Mgr->NoChecksumCount)
+ && (CurRegister
+ > Mgr->NoChecksumTable[NoChecksumIndex].Index) )
+ {
+ ++NoChecksumIndex;
+ }
+
+
+ if ( (CurRegister !=
+ Mgr->NoChecksumTable[NoChecksumIndex].Index ) )
+ {
+ CmosReadWrite(Mgr, ReadType, CurRegister, 0,
+ &CurValue);
+ *ChecksumValue += CurValue; // update the output parameter
+ }
+ }
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "\n --------------------------------\n"));
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " Computed *ChecksumValue = 0x%04X\n\n",
+ *ChecksumValue ));
+
+ // Compare with physical CMOS checksum value and set/clear status bit
+
+ ReadChecksum( Mgr, &CurrentChecksum);
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "\n -----------------------\n"));
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " Saved Checksum = 0x%04X\n\n",
+ CurrentChecksum ));
+
+ if (*ChecksumValue != CurrentChecksum) {
+ Mgr->SetStatus(Mgr, CMOS_BAD_CHECKSUM);
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, " ...CMOS_BAD_CHECKSUM\n"));
+ }
+ else {
+ Mgr->ClearStatus(Mgr, CMOS_BAD_CHECKSUM);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, " ...Checksum is OK\n" ));
+ }
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CalculateChecksum: Done\n" ));
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosWrite
+//
+// Description:
+// Writes from CmosValue to CMOS location encoded into CmosToken.
+//
+// Input:
+// IN EFI_CMOS_ACCESS_INTERFACE *Cmos
+// -- This is the access interface pointer.
+// IN UINT16 CmosToken
+// -- This is the encoded CMOS location.
+// IN UINT8 CmosValue
+// -- On success, this value will be written to
+// the specified CMOS location.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = EFI_NOT_FOUND, if the token is not in the token table
+// = or other valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosWrite(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN UINT16 CmosToken,
+ IN UINT8 CmosValue )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 TokenTableIndex = 0;
+ EFI_CMOS_MANAGER_INTERFACE *Mgr = GetCmosMangerInterface(Cmos);
+ DEFINE_PEI_SERVICES(Cmos->PeiServices);
+
+
+ // if CmosToken <= 0xe, then always write the register. These registers
+ // will be writable regardless of the state of the battery.
+
+ if (CmosToken <= 0xe){
+ Status = CmosBankReadWrite( Mgr, WriteType, CmosToken, &CmosValue );
+ }
+
+ // Otherwise, if CmosToken is less than MIN_TOKEN_VALUE and the battery
+ // is good, then an additional test is made to disallow writing of actual
+ // registers if they are within the managed region. Otherwise, the
+ // actual physical register is written. (For a bad battery, return
+ // EFI_DEVICE_ERROR when trying to write the physical register.)
+
+ else if ( CmosToken < MIN_TOKEN_VALUE ){
+ if ( !Mgr->CheckStatus( Mgr, CMOS_IS_USABLE ) ) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ else if ( (CmosToken >= FIRST_MANAGED_CMOS_ADDRESS)
+ && (CmosToken < MAX_MANAGED_CMOS_ADDRESS) )
+ Status = EFI_INVALID_PARAMETER;
+ else
+ Status = CmosBankReadWrite( Mgr, WriteType,
+ CmosToken, &CmosValue );
+ }
+
+ // Otherwise, after validating the CmosToken, decode it to write the
+ // associated register bit(s).
+
+ else if ((TokenTableIndex = CmosFindToken( Mgr, CmosToken )) > 0) {
+ Status = CmosReadWriteEncodedToken( Mgr, WriteType, TokenTableIndex,
+ &CmosValue );
+ }
+ else
+ Status = EFI_INVALID_PARAMETER;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: LoadOptimalDefaults
+//
+// Description:
+// Initialize all physical CMOS registers with the default values
+// specified in NvramField's Default value.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- The Manger interface pointer.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Modified:
+// Manager->ManagerStatus bits:
+// CMOS_BAD_CHECKSUM - cleared on success
+// CMOS_ERROR_LOADING_DEFAULTS - set on error
+//
+// Notes:
+// LoadOptimalDefaults will be called for one of two reasons:
+//
+// 1) On the first boot after flashing the ROM, the default
+// values will be written to all CMOS registers, regardless
+// of whether or not they are listed in the NoChecksumTable.
+//
+// 2) If a bad checksum is reported in PEI, the
+// OptimalDefaultTable will be used as a read/write buffer
+// until DXE, where (by default) the CMOS_BAD_CHECKSUM status bit will
+// signal to write the buffer to physical CMOS.
+//
+// * The optimal defaults buffer may be modified from the original
+// version if CMOS_OPTIMAL_DEFAULTS_ENABLED status bit is set.
+//
+// * If the CMOS_BAD_CHECKSUM status is set, then only those values
+// included in the checksum are written to physical CMOS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LoadOptimalDefaults(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 CurRegister;
+ UINT8 CurValue;
+ UINT16 NewChecksum = 0;
+ UINT16 UnmanagedIndex = 1; // UnmanagedTable starts at 1
+ UINT16 DefaultIndex = 1; // OptimalDefaultTable starts at 1
+ UINT16 NoChecksumIndex = 1; // NoChecksumTable starts at 1
+ CMOS_MANAGER_STATUS SavedStatus = Mgr->ManagerStatus &
+ (CMOS_OPTIMAL_DEFAULTS_ENABLED );
+ EFI_CMOS_ACCESS_INTERFACE *Cmos = Mgr->GetAccessInterface(Mgr);
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "LoadOptimalDefaults Entry\n"));
+
+ // Calculate it
+ //-----------------------------------------------------------------------
+ // Configure to ensure reads/writes are to physical registers.
+ //-----------------------------------------------------------------------
+
+ Mgr->ClearStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED );
+
+ // temporarily disallow checksum updating
+
+ Mgr->SetStatus(Mgr, CMOS_FORCE_NO_CHECKSUM);
+
+
+ //---------------------------------------------
+ // For the first boot, ignore the bad checksum
+ // so that defaults are loaded for all
+ // registers.
+ //---------------------------------------------
+
+ if ( Mgr->CheckStatus( Mgr, CMOS_FIRST_BOOT_DETECTED ) ){
+ Mgr->ClearStatus(Mgr, CMOS_BAD_CHECKSUM);
+ }
+
+ //-----------------------------------------------------------------------
+ // Write the physical registers:
+ //
+ // There "should" be exactly one default entry for each register in the
+ // managed region. (This is not assumed to be true.)
+ //-----------------------------------------------------------------------
+
+ for ( CurRegister = Mgr->FirstManagedRegister;
+ CurRegister <= Mgr->LastManagedRegister; // inclusive
+ ++CurRegister, ++DefaultIndex )
+ {
+ if ( DefaultIndex >= Mgr->OptimalDefaultCount){ // bad news!
+ Mgr->SetStatus(Mgr, CMOS_ERROR_LOADING_DEFAULTS);
+ break;
+ }
+
+ //---------------------------------------------
+ // Skip the location if the location is not managed
+ //
+ // Note: the UnmanagedTable is in numeric order,
+ // so it only needs traversed one time.
+ //---------------------------------------------
+
+ while ( (UnmanagedIndex < Mgr->UnmanagedTableCount)
+ && (CurRegister
+ > Mgr->UnmanagedTable[UnmanagedIndex].Index) )
+ {
+ ++UnmanagedIndex;
+ }
+ if ( CurRegister == Mgr->UnmanagedTable[UnmanagedIndex].Index ){
+
+ // Ensure DefaultIndex is not incremented at the top of the
+ // loop, as un-managed locations do not have a default value.
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " -->Skip 0x%X (un-managed)\n",
+ CurRegister));
+ --DefaultIndex;
+ continue;
+ }
+
+
+ //---------------------------------------------
+ // Skip location if:
+ //
+ // 1. there is a bad checksum,
+ // 2. recovery is enabled only for checksummed locations
+ //
+ // (Note, the NoChecksumTable is in numeric order)
+ //---------------------------------------------
+
+ if ( Mgr->CheckStatus( Mgr,
+ CMOS_BAD_CHECKSUM + CMOS_RECOVER_ONLY_CHECKSUMMED ) )
+ {
+ while ( (NoChecksumIndex < Mgr->NoChecksumCount)
+ && (CurRegister
+ > Mgr->NoChecksumTable[NoChecksumIndex].Index) )
+ {
+ ++NoChecksumIndex;
+ }
+ if ( (CurRegister
+ == Mgr->NoChecksumTable[NoChecksumIndex].Index ) ){
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ " -->Skip 0x%X (not checksummed)\n",
+ CurRegister));
+ continue;
+ }
+ }
+
+ // Update the physical register
+
+ CurValue = Mgr->OptimalDefaultTable[DefaultIndex].Value;
+ Status = CmosReadWrite(Mgr, WriteType, CurRegister, ALL_BITS,
+ &CurValue);
+
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ " Unable to load default for register: 0x%X\n",
+ CurRegister ));
+ break;
+ }
+
+
+ }
+
+ // if no error, calculate checksum and reset the
+ // CMOS_BAD_CHECKSUM status bit.
+
+ if ( EFI_ERROR(Status)
+ || Mgr->CheckStatus(Mgr, CMOS_ERROR_LOADING_DEFAULTS))
+ {
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ " Error: Could not load Optimal Defaults\n"));
+ Status = EFI_UNSUPPORTED;
+ }
+ else
+ {
+ CalculateChecksum(Mgr, &NewChecksum);
+ WriteChecksum(Mgr, NewChecksum);
+ Mgr->ClearStatus(Mgr, CMOS_BAD_CHECKSUM);
+ }
+
+ //-----------------------------------------------------------------------
+ // Restore previous access routing settings.
+ //-----------------------------------------------------------------------
+
+ Mgr->ManagerStatus = Mgr->ManagerStatus | SavedStatus;
+
+ // Allow checksums to be computed now
+
+ Mgr->ClearStatus(Mgr, CMOS_FORCE_NO_CHECKSUM);
+
+ // Set status bit to indicate that defaults have been loaded
+
+ Mgr->SetStatus(Mgr, CMOS_DEFAULTS_LOADED);
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "LoadOptimalDefaults Exit\n"));
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StopTime
+//
+// Description: Stops the time on RTC clock.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Mgr
+// -- The Manger interface pointer.
+//
+// Output: None
+//
+// Notes: Here is the control flow of this function:
+// 1. Stop the time by setting bit 7 on RTC register 0xb.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID StopTime(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr )
+{
+ UINT8 Value;
+
+ CmosBankReadWrite( Mgr, ReadType, 0xb, &Value );
+ Value |= 0x80;
+ CmosBankReadWrite( Mgr, WriteType, 0xb, &Value );
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StartTime
+//
+// Description: Start the time on RTC clock. This is used when changing the
+// Date and Time
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Mgr
+// -- The Manger interface pointer.
+//
+// Output: None
+//
+// Notes: Here is the control flow of this function:
+// 1. Start the time by clearing bit 7 on RTC register 0xb.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID StartTime(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr )
+{
+ UINT8 Value;
+
+ CmosBankReadWrite( Mgr, ReadType, 0xb, &Value );
+ Value &= 0x7f;
+ CmosBankReadWrite( Mgr, WriteType, 0xb, &Value );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BCDToDec
+//
+// Description: Converts a Decimal value to a BCD value.
+//
+// Input:
+// IN UINT8 Dec - Decimal value
+//
+// Output:
+// UINT8 (return value) - BCD value
+//
+// Notes:
+// Only for 2 digit decimal.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 DecToBCD(IN UINT8 Dec)
+{
+ UINT8 FirstDigit = Dec % 10;
+ UINT8 SecondDigit = Dec / 10;
+
+ return (SecondDigit << 4) + FirstDigit;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BCDToDec
+//
+// Description: Converts a BCD value to a Decimal value.
+//
+// Input:
+// IN UINT8 BCD -- BCD value
+//
+// Output:
+// UINT8 - decimal value
+//
+// Notes:
+// Only for 2 digit BCD.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 BCDToDec(IN UINT8 BCD)
+{
+ UINT8 FirstDigit = BCD & 0xf;
+ UINT8 SecondDigit = BCD >> 4;;
+
+ return SecondDigit * 10 + FirstDigit;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CmosMgrReadRtcIndex
+//
+// Description: Read the RTC value at the given Index.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Mgr
+// -- The Manger interface pointer.
+// IN UINT8 Index
+//
+// Output:
+// UINT8 (return value) --
+// = RTC Value read from the provided Index
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read port 0x70 (RTC Index Register) to get bit 7.
+// Bit 7 is the NMI bit-it should not be changed.
+// 2. Output 0x70 with the Index and NMI bit setting.
+// 3. Read 0x71 for Data. Getting Dec when appropriate.
+// 4. Return the Data.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static UINT8 CmosMgrReadRtcIndex(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN UINT8 Index )
+{
+ UINT8 Value;
+
+ CmosBankReadWrite( Mgr, ReadType, Index, &Value );
+ Value = BCDToDec(Value);
+
+ return Value;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CmosMgrWriteRtcIndex
+//
+// Description: Write the RTC value at the given Index.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Mgr
+// -- The Manger interface pointer.
+// IN UINT8 Index
+// -- Index to write
+// IN UINT8 Value
+// -- Value to write
+//
+// Output: None
+//
+// Notes: Here is the control flow of this function:
+// 1. Read port 0x70 (RTC Index Register) to get bit 7.
+// Bit 7 is the NMI bit-it should not be changed.
+// 2. Output 0x70 with the Index. Switch to BCD when needed.
+// 3. Write the data to 0x71.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static void CmosMgrWriteRtcIndex(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN UINT8 Index,
+ IN UINT8 Value )
+{
+ Value = DecToBCD(Value);
+ CmosBankReadWrite( Mgr, WriteType, Index, &Value );
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CmosSetDateTime
+//
+// Description:
+// This routine simply writes the CMOS RTC registers from information
+// provided by the EFI_TIME structure, assuming the information is
+// correct.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- The Manger interface pointer.
+// IN EFI_TIME *Time
+// -- EFI Time structure
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Modified:
+// N/A
+//
+// Notes:
+// Data is assumed to be valid. Only a simple check for NULL pointer
+// is done.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosSetDateTime (
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN EFI_TIME *Time )
+{
+ EFI_CMOS_MANAGER_INTERFACE *Mgr = GetCmosMangerInterface(Cmos);
+ DEFINE_PEI_SERVICES(Cmos->PeiServices);
+
+ if (Time == NULL || Mgr == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ StopTime(Mgr);
+
+ CmosMgrWriteRtcIndex( Mgr, ACPI_CENTURY_CMOS, Time->Year / 100 );
+ CmosMgrWriteRtcIndex( Mgr, 9, Time->Year % 100 );
+ CmosMgrWriteRtcIndex( Mgr, 8, Time->Month );
+ CmosMgrWriteRtcIndex( Mgr, 7, Time->Day );
+ CmosMgrWriteRtcIndex( Mgr, 4, Time->Hour );
+ CmosMgrWriteRtcIndex( Mgr, 2, Time->Minute );
+ CmosMgrWriteRtcIndex( Mgr, 0, Time->Second );
+
+ StartTime(Mgr);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CmosGetDateTime
+//
+// Description: Return the current date and time
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- The Manger interface pointer.
+// OUT EFI_TIME *Time
+// -- EFI Time structure
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosGetDateTime (
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ OUT EFI_TIME *Time )
+{
+ EFI_CMOS_MANAGER_INTERFACE *Mgr = GetCmosMangerInterface(Cmos);
+ DEFINE_PEI_SERVICES(Cmos->PeiServices);
+
+ if (Time == NULL || Cmos == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ //If RTC Year only 1 digit, EFI spec says years range is 1998 - 2097
+ Time->Year = CmosMgrReadRtcIndex(Mgr, ACPI_CENTURY_CMOS) * 100
+ + CmosMgrReadRtcIndex(Mgr, 9);
+ Time->Month = CmosMgrReadRtcIndex(Mgr, 8);
+ Time->Day = CmosMgrReadRtcIndex(Mgr, 7);
+ Time->Hour = CmosMgrReadRtcIndex(Mgr, 4);
+ Time->Minute = CmosMgrReadRtcIndex(Mgr, 2);
+ Time->Second = CmosMgrReadRtcIndex(Mgr, 0);
+ Time->Nanosecond= 0;
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosBoard.c b/Core/EM/CmosManager/CmosBoard.c
new file mode 100644
index 0000000..84ad668
--- /dev/null
+++ b/Core/EM/CmosManager/CmosBoard.c
@@ -0,0 +1,517 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CmosManager/CmosBoard.c 1 10/25/12 9:02a Wesleychen $Revision: 0 $
+//
+// $Date: 10/25/12 9:02a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CmosManager/CmosBoard.c $
+//
+// 1 10/25/12 9:02a Wesleychen
+// Update it to the rev19.
+//
+// 19 6/08/12 4:48p Michaela
+// [TAG] EIP92072
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] CMOS Manager Needs Code Changes for Coding Standards
+// Compliance
+// [Files] Multiple
+//
+// 18 5/23/12 12:02p Michaela
+// [TAG] EIP90679
+// [Category] Improvement
+// [Description] MonotonicCounter variable guid changed.
+// [Files] CmosBoard.c
+//
+// 17 5/23/12 11:48a Michaela
+// [TAG] EIP90679
+// [Category] Improvement
+// [Description] MonotonicCounter variable guid changed.
+// [Files] CmosBoard.c
+//
+// 16 6/15/10 2:22p Michaela
+//
+// 15 3/08/10 1:08p Michaela
+//
+// 14 3/08/10 12:56p Michaela
+// Comment example gUnmanagedTable
+//
+// 13 3/05/10 4:53p Michaela
+//
+// 12 12/04/09 7:30p Michaela
+//
+// 11 12/03/09 6:11p Michaela
+// Added default implementation of CmosMgrIsColdBoot
+//
+// 10 7/29/09 9:54a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 9 6/15/09 5:10p Michaela
+//
+// 8 6/02/09 3:25p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 7 2/23/09 5:59p Michaela
+// --ReadWriteSecondBankTranslated() is only included as a porting
+// example, and should be added to SBGeneric.c and prototyped in
+// SBCsplib.h (See notes)
+//
+// 6 2/16/09 10:28p Michaela
+// ReadWriteStandardRange()
+// - Modified to use CMOS_BANK0_INDEX
+// and CMOS_BANK0_DATA
+// - Validation of CmosRegister parameter
+// - OR CmosRegister with CMOS_NMI_BIT_VALUE
+// to specify NMI bit.
+// ReadWriteSecondBankTranslated()
+// - Added to translate CmosRegister to
+// index port value for bank 2 access
+// - Use CMOS_BANK1_INDEX and CMOS_BANK1_DATA
+// to access bank 2
+//
+// 5 1/21/09 2:47p Michaela
+// change CMOS_CLOCK_RANGE_INDEX to CMOS_STD_INDEX
+// and CMOS_CLOCK_RANGE_DATA to CMOS_STD_DATA
+//
+// 4 1/21/09 2:38p Michaela
+// update for release 4.6.3_CMOSMGR_11:
+//
+// **Removed CMOS_CLOCK_RANGE_INDEX and
+// CMOS_CLOCK_RANGE_DATA SDL Tokens.
+// **Changed the default value of CMOS_STD_INDEX and
+// CMOS_STD_DATA to 0x70 and 0x71, respectively.
+// Updated CMOS_PORT_MAPPING elinks to use
+// ReadWriteStandardRange() for the 0x0 to 0x7f region.
+// **Added CMOS_MGR_SET_NMI_BIT to specify whether or
+// not to set the NMI bit for access to 0x0 to 0x7f
+// region.
+// **Removed ReadWriteClockRange() in CmosBoard.c
+// **Modified ReadWriteStandardRange() in CmosBoard.c
+// to access the NMI range CMOS, where the NMI bit is
+// set, as specified by the CMOS_MGR_SET_NMI_BIT
+// Boolean token.
+// Modified ReadWriteStandardRange() in CmosBoard.c to access the NMI
+// range CMOS, where the NMI bit is set, as specified by the
+// CMOS_MGR_SET_NMI_BIT Boolean token.
+//
+// 3 1/08/09 10:51a Michaela
+// >Added function headers
+// >Updated function parameter modifiers
+// >renamed and updated to CmosBoard module part
+// >Core/Board SDL Tokens and CMOS Tokens are separated
+//
+// 2 11/17/08 4:01p Michaela
+// --Added default handlers for RTC range and Standard range CMOS
+// registers
+//
+// 1 11/14/08 9:24a Michaela
+// **Add support for board-specific access functions
+//
+// 0 11/12/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosBoard.c
+//
+// Description: Contains routines that are board-specific.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CmosBoard.h"
+
+//---------------------------------------------------------------------------
+// CmosBank is initialized using the CMOS_PORT_MAPPING SDL Elink.
+// This array is used to determine which index/data port pair to use for a
+// specific CMOS register address.
+//---------------------------------------------------------------------------
+extern CMOS_PORT_MAP *gCmosBank;
+extern UINT16 gCmosBankCount;
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ReadWriteStandardRange
+//
+// Description:
+// This function is used to access addresses in the Standard CMOS
+// register range (0x0-0x7f), for PEI and DXE boot phases.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Services table pointer (NULL in DXE phase)
+// IN CMOS_ACCESS_TYPE AccessType
+// -- ReadType or WriteType to specify the type of access
+// IN UINT16 CmosRegister
+// -- The CMOS register to access
+// IN OUT UINT8 *CmosParameterValue
+// -- Pointer to the data variable to be accessed
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Modified: None
+//
+// Referrals: IoRead8, IoWrite8
+//
+// Notes: N/A
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS ReadWriteStandardRange (
+ IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosRegister,
+ IN OUT UINT8 *CmosParameterValue )
+{
+ UINT8 TempValue;
+
+ if (CmosRegister > 0x7f)
+ return EFI_INVALID_PARAMETER;
+
+ // If reading an RTC register, then check the Update in Progress bit in
+ // Status register A to ensure a read is allowed.
+ if(CmosRegister <= 9 && AccessType == ReadType) {
+ do {
+ IoWrite8(CMOS_BANK0_INDEX, 0xa | CMOS_NMI_BIT_VALUE);
+ TempValue = IoRead8(CMOS_BANK0_DATA);
+ } while (TempValue & 0x80);
+ }
+
+ IoWrite8( CMOS_BANK0_INDEX, (UINT8)CmosRegister | CMOS_NMI_BIT_VALUE );
+
+ if (AccessType == ReadType){
+ *CmosParameterValue = IoRead8( CMOS_BANK0_DATA );
+ }
+ else {
+ IoWrite8( CMOS_BANK0_DATA, *CmosParameterValue );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//----------------------------------------------------------------------------
+//
+// Name: ReadWriteBank1Translated
+//
+// Description:
+// This function is used to access addresses in the CMOS register range
+// (0x80-0xff), for PEI and DXE boot phases.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- Pointer to the PEI services table. (This pointer
+// is NULL in the DXE phase.)
+// IN CMOS_ACCESS_TYPE AccessType
+// -- ReadType or WriteType to specify the type of access
+// IN UINT16 CmosRegister
+// -- The CMOS register to access
+// IN OUT UINT8 *CmosParameterValue
+// -- Pointer to the data variable to be accessed
+//
+// Output:
+// EFI_STATUS (return value)
+// EFI_SUCCESS - the access operation was successfull.
+// Otherwise - a valid EFI error code is returned.
+//
+// Modified: None
+//
+// Referrals: IoRead8, IoWrite8
+//
+// Notes:
+// This function is used when a translation from logical
+// address to index port value is required. For example, the
+// ICH10 only allows values 0-7f for port 72/73 (upper bank)
+// access, so logical CMOS address 0x80 must be translated to
+// index port value 0, 0x81 becomes index port value 1, and
+// so on.
+//
+//--------------------------------------------------------------------------
+
+
+//============================================================================
+// Southbridge porting notes
+//============================================================================
+// The following code is an example of how to implement code that
+// translates from CMOS register number to access the physical
+// CMOS location when the register number is not identical to the
+// physical location.
+//
+// If access to the address range above 0x7f is required, and translation
+// between CMOS register number and CMOS index port value must be made,
+// then a function similar to this should be place in SBGeneric.c, SBCsplib.h,
+// and the appropriate CMOS_PORT_MAPPING eLink should also be defined.
+//============================================================================
+
+/*
+EFI_STATUS ReadWriteSecondBankTranslated (
+ IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosRegister,
+ IN OUT UINT8 *CmosParameterValue )
+{
+ if (CmosRegister < 0x80 || CmosRegister > 0xff)
+ return EFI_INVALID_PARAMETER;
+
+ IoWrite8( CMOS_BANK1_INDEX, (UINT8)(CmosRegister-0x80));
+
+ if (AccessType == ReadType){
+ *CmosParameterValue = IoRead8( CMOS_BANK1_DATA );
+ }
+ else {
+ IoWrite8( CMOS_BANK1_DATA, *CmosParameterValue );
+ }
+
+ return EFI_SUCCESS;
+}
+*/
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: CmosMgrBatteryIsGood
+//
+// Description:
+// This function is used to determing whether or not the CMOS battery is
+// good.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- Pointer to the PEI services table. (This pointer
+// is NULL in the DXE phase.)
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if the battery is good
+// = TRUE if the battery is bad
+//
+// Modified: None
+//
+// Referrals: IoRead8, IoWrite8
+//
+// Notes: Some chipsets need to check a PCI configuration space
+// register to determine the RTC power status.
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+BOOLEAN CmosMgrBatteryIsGood (
+ IN EFI_PEI_SERVICES **PeiServices /* NULL in DXE */ )
+{
+ // PORTING PORTING PORTING
+
+ IoWrite8( CMOS_BANK0_INDEX,
+ CMOS_RTC_STATUS_REGISTER + CMOS_NMI_BIT_VALUE );
+
+ return ((IoRead8( CMOS_BANK0_DATA ) & 0x80) != 0) ? TRUE : FALSE;
+
+ // PORTING PORTING PORTING
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosIsUsable
+//
+// Description:
+// This function determines whether or not the CMOS is usable. It may
+// be possible to use the CMOS even if the battery is bad.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+//
+// Output:
+// BOOLEAN (Return value)
+// = TRUE - CMOS is usable
+// = FALSE - CMOS is not usable
+//
+// Notes:
+// Typically, register 0xd can be used to determine whether or not
+// CMOS is usable. It may be possible to use the CMOS for reads/writes
+// if the battery is bad.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CmosIsUsable (
+ IN EFI_PEI_SERVICES **PeiServices /* NULL in DXE */ )
+{
+ IoWrite8( CMOS_BANK0_INDEX,
+ CMOS_RTC_STATUS_REGISTER + CMOS_NMI_BIT_VALUE );
+
+ return ((IoRead8( CMOS_BANK0_DATA ) & 0x80) != 0) ? TRUE : FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosMgrIsFirstBoot
+//
+// Description:
+// This function determines whether or not this is the first boot after
+// programming the boot device (flash part, ROM emulator, ...).
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- Pointer to the PEI services table. (This pointer
+// is NULL in the DXE phase.)
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE, if this is the first boot
+// = FALSE, otherwise
+//
+// Notes:
+// For some chipsets, there may be additional issues to consider,
+// such as warm reboot during the PEI phase, multiple processor threads
+// and so on. Therefore, this function can be implemented by an external
+// module (typically the Southbridge module).
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CmosMgrIsFirstBoot (
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#ifdef PEI_COMPILE
+ UINTN Size = sizeof(UINT32);
+#if ((CORE_COMBINED_VERSION > 262797) && defined(AMI_GLOBAL_VARIABLE_GUID))
+ EFI_GUID GlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+#else
+ EFI_GUID GlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+#endif
+ UINT32 Dummy;
+ EFI_GUID Guid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable = NULL;
+
+ // If the MonotonicCounter variable is found then return false
+ // to indicate that this is not the first boot.
+
+ Status = (*PeiServices)->LocatePpi( PeiServices, &Guid,
+ 0, NULL, &ReadOnlyVariable);
+ if (EFI_ERROR(Status))
+ return TRUE; // assume first boot if PPI not found
+
+ Status = ReadOnlyVariable->GetVariable( PeiServices,
+ L"MonotonicCounter",
+ &GlobalVariableGuid,
+ NULL,
+ &Size, &Dummy );
+#endif
+
+ // If the CmosManagerStatus variable is not found and this is not the
+ // DXE phase then this is the first boot.
+
+ if ( EFI_ERROR(Status) )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosMgrIsBsp
+//
+// Description:
+// This function returns TRUE if the currently executing CPU core
+// is the boot strap processor (BSP).
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- Pointer to the PEI services table. (This pointer
+// is NULL in the DXE phase.)
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE, the BSP is executing
+// = FALSE, otherwise
+//
+// Notes:
+// For some chipsets, this functions may need to be replaced.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CmosMgrIsBsp(
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ // if bit 8 of the APIC base register is set, then the current
+ // core is the BSP (for most chipsets)
+
+ if ( ReadMsr(MSR_XAPIC_BASE) & XAPIC_BASE_BSP_BIT_MASK )
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosMgrIsColdBoot
+//
+// Description:
+// This function returns TRUE to specify the platform is always perfoming
+// a cold boot.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- Pointer to the PEI services table. (This pointer
+// is NULL in the DXE phase.)
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE
+//
+// Notes:
+// For some chipsets, this functions may need to be replaced.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CmosMgrIsColdBoot(
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return TRUE;
+}
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosBoard.h b/Core/EM/CmosManager/CmosBoard.h
new file mode 100644
index 0000000..ad1742b
--- /dev/null
+++ b/Core/EM/CmosManager/CmosBoard.h
@@ -0,0 +1,210 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosBoard.h 12 3/05/10 4:53p Michaela $
+//
+// $Revision: 12 $
+//
+// $Date: 3/05/10 4:53p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosBoard.h $
+//
+// 12 3/05/10 4:53p Michaela
+//
+// 11 12/04/09 7:30p Michaela
+//
+// 10 12/03/09 6:12p Michaela
+// updated declarations for CmosMgrIsBsp & CmosMgrIsColdBoot
+//
+// 9 7/29/09 9:54a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 8 6/15/09 5:10p Michaela
+//
+// 7 6/02/09 3:25p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 6 2/23/09 6:00p Michaela
+// --included AmiCspLib.h for exported SB CMOS access functions
+// --ReadWriteSecondBankTranslated is commented as an example
+// declaration for SBCsplib.h
+//
+// 5 2/16/09 10:11p Michaela
+// added prototype for ReadWriteSecondBankTranslated()
+//
+// 4 1/21/09 2:38p Michaela
+// update for release 4.6.3_CMOSMGR_11:
+//
+// **Removed CMOS_CLOCK_RANGE_INDEX and
+// CMOS_CLOCK_RANGE_DATA SDL Tokens.
+// **Changed the default value of CMOS_STD_INDEX and
+// CMOS_STD_DATA to 0x70 and 0x71, respectively.
+// Updated CMOS_PORT_MAPPING elinks to use
+// ReadWriteStandardRange() for the 0x0 to 0x7f region.
+// **Added CMOS_MGR_SET_NMI_BIT to specify whether or
+// not to set the NMI bit for access to 0x0 to 0x7f
+// region.
+// **Removed ReadWriteClockRange() in CmosBoard.c
+// **Modified ReadWriteStandardRange() in CmosBoard.c
+// to access the NMI range CMOS, where the NMI bit is
+// set, as specified by the CMOS_MGR_SET_NMI_BIT
+// Boolean token.
+// Modified ReadWriteStandardRange() in CmosBoard.c to access the NMI
+// range CMOS, where the NMI bit is set, as specified by the
+// CMOS_MGR_SET_NMI_BIT Boolean token.
+//
+// 3 1/08/09 10:51a Michaela
+// >Added function headers
+// >Updated function parameter modifiers
+// >renamed and updated to CmosBoard module part
+// >Core/Board SDL Tokens and CMOS Tokens are separated
+//
+// 2 11/17/08 4:01p Michaela
+// --removed development debugging code
+//
+// 1 11/14/08 9:25a Michaela
+// **Add support for board-specific access functions
+//
+// 7 11/07/08 5:13p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 6 3/25/08 3:04p Michaela
+// --deleted UpdateLegacyChecksumStatus
+// --Modified SynchronizeLegacyStatusRegisters to
+// update both battery and checksum status bits
+//
+// 5 3/07/08 4:07p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 4 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 3 2/26/08 12:49p Michaela
+// Added/modified Helpbuilder headers
+//
+// 2 2/22/08 3:20p Olegi
+// Renamed some of the equates to avoid the naming collisions.
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosAccess.c
+//
+// Description: Contains the routines that constitute the CMOS access
+// implementation. This file contains source code that is used
+// for both PEI and DXE phases.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#ifndef _CMOS_BOARD_H
+#define _CMOS_BOARD_H
+
+#include <Efi.h>
+#ifdef PEI_COMPILE
+ #include <Pei.h>
+ #include <AmiPeiLib.h>
+ #include <Ppi\ReadOnlyVariable.h>
+#else
+ #include <AmiDxeLib.h>
+#endif
+#include <CmosAccess.h>
+#include <SspTokens.h>
+#include "AmiCspLib.h"
+#include "CmosManager.h"
+#include "CmosManagerHob.h"
+
+#ifdef MSR_XAPIC_BASE
+ #undef MSR_XAPIC_BASE
+#endif
+#ifdef XAPIC_BASE_BSP_BIT
+ #undef XAPIC_BASE_BSP_BIT
+#endif
+#ifdef XAPIC_BASE_BSP_BIT_MASK
+ #undef XAPIC_BASE_BSP_BIT_MASK
+#endif
+
+#define MSR_XAPIC_BASE 0x1b // standard APIC base MSR
+#define XAPIC_BASE_BSP_BIT 8
+#define XAPIC_BASE_BSP_BIT_MASK (1 << XAPIC_BASE_BSP_BIT)
+
+EFI_STATUS ReadWriteStandardRange (
+ IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosRegister,
+ IN OUT UINT8 *CmosParameterValue );
+
+
+
+//================================================================
+// Southbridge should implement functions to support access
+// to additional CMOS banks (add the following to SBCspLib.h)
+//================================================================
+/*
+EFI_STATUS ReadWriteSecondBankTranslated (
+ IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosRegister,
+ IN OUT UINT8 *CmosParameterValue );
+*/
+
+BOOLEAN CmosMgrBatteryIsGood (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+BOOLEAN CmosMgrIsFirstBoot (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+BOOLEAN CmosMgrIsBsp(
+ IN EFI_PEI_SERVICES **PeiServices );
+
+BOOLEAN CmosMgrIsColdBoot(
+ IN EFI_PEI_SERVICES **PeiServices );
+
+BOOLEAN CmosIsUsable(
+ IN EFI_PEI_SERVICES **PeiServices );
+
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosBoard.sdl b/Core/EM/CmosManager/CmosBoard.sdl
new file mode 100644
index 0000000..5ea4464
--- /dev/null
+++ b/Core/EM/CmosManager/CmosBoard.sdl
@@ -0,0 +1,905 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosBoard.sdl 14 6/15/10 2:22p Michaela $
+#
+# $Revision: 14 $
+#
+# $Date: 6/15/10 2:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosBoard.sdl $
+#
+# 14 6/15/10 2:22p Michaela
+#
+# 13 3/05/10 4:53p Michaela
+#
+# 12 12/04/09 7:30p Michaela
+#
+# 11 12/03/09 6:10p Michaela
+# Added additional options to control bad checksum handling
+#
+# 10 11/10/09 9:12p Michaela
+#
+# 9 7/29/09 9:54a Michaela
+# updates Aptio Enhancement EIP 22205
+# (no code changes)
+#
+# 8 6/02/09 3:25p Michaela
+# For label: 4.6.3_CMOSMGR_11
+#
+# 7 2/23/09 5:29p Michaela
+# --changed MAX_MANAGED_CMOS_ADDRESS to default of 128
+# --added CMOS_USES_STANDARD_RANGE_ACCESS to specify
+# whether or not to use CMOS Manager's access function for the
+# 0-0x7f range.
+# --Added notes on SB porting that must be done to acces CMOS
+# registers above 0x7f
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+#
+# Name: CmosBoard.sdl
+#
+# Description: This AMI SDL file defines porting constants used in
+# the CMOS Board subcomponent.
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+#
+#============================================================================
+# Southbridge porting notes
+#============================================================================
+#
+# These tokens are included as an example of tokens to add to the
+# Southbridge module for implementing access to CMOS banks above
+# 0x7f.
+#
+#TOKEN
+# Name = "CMOS_BANK1_INDEX"
+# Value = "0x72"
+# Help = "Index port to access the second CMOS bank. \(Registers in range: 0x80-0xff)"
+# TokenType = Integer
+# TargetEQU = Yes
+# TargetH = Yes
+#End
+#
+#TOKEN
+# Name = "CMOS_BANK1_DATA"
+# Value = "0x73"
+# Help = "Data port to access the second CMOS bank. \(Registers in range: 0x80-0xff)"
+# TokenType = Integer
+# TargetEQU = Yes
+# TargetH = Yes
+#End
+#
+#TOKEN
+# Name = "CMOS_BANK1_INDEX_IS_TRANSLATED"
+# Value = "1"
+# Help = "1 = Index port value requires translation from CMOS address.\0 = Index port value equals CMOS address."
+# TokenType = Boolean
+# TargetEQU = Yes
+# TargetH = Yes
+#End
+#ELINK
+# Name = "{0, 0, 0x80, 0xff, ReadWriteSecondBankTranslated},"
+# Parent = "CMOS_PORT_MAPPING"
+# Help = "Second bank CMOS access range (Registers in range: 0x80-0xff), when index port value is not identical to CMOS address"
+# InvokeOrder = AfterParent
+# Token = "CMOS_BANK1_INDEX_IS_TRANSLATED" "=" "1"
+#End
+#
+#ELINK
+# Name = "{CMOS_BANK1_INDEX, CMOS_BANK1_DATA, 0x80, 0xff, NULL},"
+# Parent = "CMOS_PORT_MAPPING"
+# Help = "Second bank CMOS access range (Registers in range: 0x80-0xff), when index port value is identical to CMOS address"
+# InvokeOrder = AfterParent
+# Token = "CMOS_BANK1_INDEX_IS_TRANSLATED" "=" "0"
+#End
+#============================================================================
+
+
+#<AMI_GHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: All_Elinks_Tokens
+#
+# Description:
+# The following files contain the SDL Tokens/Elinks
+# used in the CMOS Manager module, which may be ported.
+#
+# CmosBoard.sdl -- SDL Tokens/Elinks typically
+# used for project-specific porting
+#
+# CmosManager.sdl -- SDL Tokens/Elinks typically
+# not modified
+#
+#----------------------------------------------------------------------------
+#<AMI_GHDR_END>
+
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: FULL_CMOS_MANAGER_DEBUG
+#
+# Description:
+#
+# Default value is 0
+#
+# 1 = Turn on all available CMOS Manager debug messages,
+# resulting in larger build.
+# 0 = Only basic debugging messages are displayed,
+# dependent upon project-level debug settings.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: FIRST_MANAGED_CMOS_ADDRESS
+#
+# Description:
+#
+# Default value is 0x40
+#
+# This is the lower limit of the CMOS register range to be managed
+# by CMOS Manager
+#
+# The region starting at FIRST_MANAGED_CMOS_ADDRESS and ending at
+# MAX_MANAGED_CMOS_ADDRESS - 1 represents the managed region.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: MAX_MANAGED_CMOS_ADDRESS
+#
+# Description:
+#
+# Default value is 128 (128 bytes with max address of 127)
+#
+# This is the upper limit (last address + 1) of CMOS address locations
+# that are managed by CMOS Manager.
+#
+# (I.e., if 256 bytes of CMOS is available and is entirely managed
+# by CMOS Manager, then the value of this token would be 256.)
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_MGR_RECOVER_ONLY_CHECKUMMED
+#
+# Description:
+#
+# Default value is 0 (all Managed Region locations are recovered)
+#
+# 1 = Do not recover non-checksummed locations in the
+# Managed Region
+#
+# 0 = Recover all locations in the Managed Region
+#
+# This configures the recovery policy so that the Optimal Defaults
+# buffer is only used for checksummed locations upon bad checksum
+# detection.
+#
+# Notes:
+# 1. For the bad battery condition, the Optimal Defaults buffer
+# will always be used.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_MGR_RECOVER_IN_PEI
+#
+# Description:
+#
+# Default value is 1 (PEI recovery is enabled)
+#
+# This configures the recovery policy so that the Optimal Defaults
+# buffer is written to CMOS in the PEI phase.
+#
+# Notes:
+# 1. This setting may require replacement of the
+# default function defined in the CMOS_IS_COLD_BOOT_MAPPING
+# eLink.
+#
+# 2. The bad checksum bit in the legacy status CMOS register
+# will indicate bad checksum until the DXE phase, but
+# physical CMOS will be used in the PEI phase.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_SMM_SUPPORT
+#
+# Description:
+#
+# Default value is 1 (SMM support is enabled)
+#
+# This token specifies whether or not the CMOS Access interface is
+# available in SMM.
+#
+# 1 = Enable SMM CMOS Access
+# 0 = Disable SMM CMOS Access
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_USES_STANDARD_RANGE_ACCESS
+#
+# Description:
+#
+# Default value is 1 (default function is enabled)
+#
+# Specifies whether or not to use CMOS Manager's default access
+# function for the 0-0x7f range. If a platform provides a different
+# access function for this region this token should be FALSE.
+#
+# Notes:
+# * If this SDL Token is turned off, an alternate
+# function must be defined using the CMOS_PORT_MAPPING
+# SDL eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_BANK0_INDEX
+#
+# Description:
+#
+# Default value is 0x70
+#
+# Index I/O port to access CMOS registers in range: 0x0-0x7f.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_BANK0_DATA
+#
+# Description:
+#
+# Default value is 0x71
+#
+# Data I/O port to access CMOS registers in range: 0x0-0x7f.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_MGR_SET_NMI_BIT
+#
+# Description:
+#
+# Default value is 1 (NMI access is enabled for 0x0-0x7f)
+#
+# 1 = Set NMI bit for access to NMI region
+# 0 = Do not set NMI bit for access to NMI region
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_NMI_BIT_VALUE
+#
+# Description:
+#
+# Default value is 0x80 (CMOS_MGR_SET_NMI_BIT = TRUE by default)
+#
+# There are two possible values for this token as determined by the
+# value of CMOS_MGR_SET_NMI_BIT:
+#
+# 0x80 = if CMOS_MGR_SET_NMI_BIT == TRUE
+# 0x00 = if CMOS_MGR_SET_NMI_BIT == FALSE
+#
+# Notes:
+#
+# This value will be OR'ed with the index value for CMOS access to
+# bank 0 locations. The value will be negated and AND'ed with the
+# index to clear the NMI bit if the original index value is to be
+# restored.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_SETUP_SUPPORT
+#
+# Description:
+#
+# Default value is 0 (CMOS_SETUP_SUPPORT = FALSE by default)
+#
+# This token specifies whether or not a setup page is enabled
+# to provide CMOS Manager related information/options.
+#
+# Notes:
+#
+# This feature is only supported for TSE labels only supported for
+# TSE versions 4.6.2_TSE_2_01_1204 and later.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_MESSAGES_SUPPORT
+#
+# Description:
+#
+# Default value is 0 (CMOS_SETUP_SUPPORT = FALSE by default)
+#
+# This token specifies whether or not messages are displayed
+# to provide CMOS Manager related power-on information.
+#
+# Notes:
+#
+# This feature is only supported for TSE labels only supported for
+# TSE versions 4.6.2_TSE_2_01_1204 and later.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_USES_STANDARD_BATTERY_TEST
+#
+# Description:
+#
+# Default value is 1 (default function is used)
+#
+# This SDL Token specifies whether or not to use the default function
+# to determine whether or not the CMOS battery is good.
+#
+# Notes:
+# If this SDL Token is turned off, an alternate function must be
+# defined and linked using the CMOS_BATTERY_TEST_MAPPING SDL eLink.
+#
+# The default function eLink is CmosMgrBatteryIsGood.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_USES_STANDARD_IS_FIRST_BOOT
+#
+# Description:
+#
+# Default value is 1 (default function is used)
+#
+# This SDL Token specifies whether or not to use the default function
+# to determine whether or not the platform is executing a first boot.
+#
+# Notes:
+# If this SDL Token is turned off, an alternate function must be
+# defined using the CMOS_IS_FIRST_BOOT_MAPPING SDL eLink.
+#
+# The default function eLink is CmosMgrIsFirstBoot.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_USES_STANDARD_IS_CMOS_USABLE
+#
+# Description:
+#
+# Default value is 1 (default function is used)
+#
+# This SDL Token specifies whether or not to use the default function
+# to determine whether or not the CMOS hardware is usable.
+# If a platform provides a different function, this token should be
+# disabled.
+#
+# Notes:
+# If this SDL Token is turned off, an alternate function must be
+# defined using the CMOS_IS_USABLE_MAPPING SDL eLink.
+#
+# The default function eLink is CmosMgrIsBsp.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_USES_STANDARD_IS_BSP
+#
+# Description:
+#
+# Default value is 1 (default function is used)
+#
+# This SDL Token specifies whether or not to use the default function
+# to determine whether or not the boot strap processor is executing.
+# If a platform provides a different function for determining the BSP,
+# this token should be disabled.
+#
+# Notes:
+# If this SDL Token is turned off, an alternate function must be
+# defined using the CMOS_IS_BSP_MAPPING SDL eLink.
+#
+# The default function eLink is CmosMgrIsBsp.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_USES_STANDARD_IS_COLD_BOOT
+#
+# Description:
+#
+# Default value is 1 (default function is used)
+#
+# This SDL Token specifies whether or not to use the default function
+# to determine whether or not the platform is executing a cold boot.
+#
+# Notes:
+#
+# 1. The default function eLink is CmosMgrIsColdBoot.
+#
+# 2. In the case of a bad checksum, the Optimal Defaults buffer
+# is written to physical CMOS in the PEI phase if:
+#
+# a. CMOS_MGR_RECOVER_IN_PEI is enabled and
+# b. CmosMgrIsColdBoot returns TRUE
+#
+# 3. Some platforms may execute a warm-reset in the PEI phase,
+# with a dependency on some CMOS value, causing
+# unpredicatable results ...possibly an infinite reboot
+# sequence.
+#
+# 4. A cold boot is defined as a power-on boot, as opposed
+# to a warm boot where a reset is initiated through
+# software.
+#
+# 5. If this SDL Token is turned off, an alternate function
+# must be defined using the CMOS_IS_COLD_BOOT_MAPPING
+# SDL eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_PORT_MAPPING
+#
+# Description:
+#
+# Default value (see Notes below)
+#
+# This Elink is used to associate CMOS register address ranges with
+# an 8-bit index/data port pair or an access function.
+#
+# Additional ranges can be specified by adding additional eLinks.
+#
+# The default eLink for the 0x0-0x7f range can be replaced by first
+# disabling the CMOS_USES_STANDARD_RANGE_ACCESS SDL token and then
+# defining a new eLink.
+#
+# Notes:
+# Format:
+#
+# {IndexPort, DataPort, LowIndex, HighIndex, FunctionName},
+#
+# Default:
+#
+# ELINK
+# Name = "{0, 0, 0, 127, ReadWriteStandardRange},"
+# Parent = "CMOS_PORT_MAPPING"
+# Help = "Standard NMI-capable access range"
+# Token = "CMOS_USES_STANDARD_RANGE_ACCESS" "=" "1"
+# InvokeOrder = AfterParent
+# End
+#
+# * FunctionName takes precedence over IndexPort/DataPort, if
+# both are specified.
+#
+# * The comma is required.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_BATTERY_TEST_MAPPING
+#
+# Description:
+#
+# The default function is CmosMgrBatteryIsGood.
+#
+# This SDL eLink provides a mechanism to replace the default function
+# for determining whether or not the battery is bad.
+#
+# Notes:
+# To override the default function, set the
+# CMOS_USES_STANDARD_BATTERY_TEST SDL Token to false and define a
+# new eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_IS_USABLE_MAPPING
+#
+# Description:
+#
+# The default function is CmosIsUsable.
+#
+# This SDL eLink provides a mechanism to replace the default function
+# for determining whether or not the CMOS hardware is usable. (Note,
+# the CMOS may be usable even if the battery is bad.)
+#
+# Notes:
+# To override the default function, set the
+# CMOS_USES_STANDARD_IS_CMOS_USABLE SDL Token to FALSE (0) and define a
+# new eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_IS_FIRST_BOOT_MAPPING
+#
+# Description:
+#
+# The default function is CmosMgrIsFirstBoot.
+#
+# This SDL eLink provides a mechanism to replace the default function
+# for determining whether or not the current execution is the first
+# boot after programming the boot firmware device (flash part, ROM
+# emulator, ...).
+#
+# Notes:
+# To override the default function, set the
+# CMOS_USES_STANDARD_IS_FIRST_BOOT SDL Token to FALSE (0) and define a
+# new eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_IS_BSP_MAPPING
+#
+# Description:
+#
+# The default function is CmosMgrIsBsp.
+#
+# This SDL eLink provides a mechanism to replace the default function
+# for determining whether or not the currently executing CPU core is
+# the boot strap processor (BSP).
+#
+# Notes:
+# To override the default function, set the
+# CMOS_USES_STANDARD_IS_BSP SDL Token to FALSE (0) and define a
+# new eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_IS_COLD_BOOT_MAPPING
+#
+# Description:
+#
+# The default function is CmosMgrIsColdBoot.
+#
+# This SDL eLink provides a mechanism to replace the default function
+# for determining whether or not the platform is executing a cold
+# boot.
+#
+# Notes:
+# To override the default function, set the
+# CMOS_USES_STANDARD_IS_COLD_BOOT SDL Token to FALSE (0) and define a
+# new eLink.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+TOKEN
+ Name = "FULL_CMOS_MANAGER_DEBUG"
+ Value = "0"
+ Help = "1-Turns on all available CMOS Manager module-level debug messages, resulting in larger build\0-Only basic debugging messages are supported, dependent upon project-level debug settings."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FIRST_MANAGED_CMOS_ADDRESS"
+ Value = "0x40"
+ Help = "This is the lower limit of the CMOS register range to be managed by CMOS Manager. \\Note: the region starting at FIRST_MANAGED_CMOS_ADDRESS and ending at MAX_MANAGED_CMOS_ADDRESS - 1 represents the managed region."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_MANAGED_CMOS_ADDRESS"
+ Value = "128"
+ Help = "Last CMOS address + 1 used to specify the maximum address that is managed by CMOS Manager. \\Note: the region starting at FIRST_MANAGED_CMOS_ADDRESS and ending at MAX_MANAGED_CMOS_ADDRESS - 1 represents the managed region."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_MGR_RECOVER_ONLY_CHECKUMMED"
+ Value = "0"
+ Help = "Upon incoherency detection in the Managed Region, only use the Optimal Defaults buffer for checksummed locations."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_MGR_RECOVER_IN_PEI"
+ Value = "1"
+ Help = "Upon incoherency detection due to bad checksum in the Managed Region, invoke the recovery policy in the PEI phase."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_SMM_SUPPORT"
+ Value = "1"
+ Help = "Specifies whether or not to the CMOS Access interface is available in SMM."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CMOS_USES_STANDARD_RANGE_ACCESS"
+ Value = "1"
+ Help = "Specifies whether or not to use CMOS Manager's default access function for the 0-0x7f range. If a platform provides a different access function for this region this token should be disabled."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_BANK0_INDEX"
+ Value = "0x70"
+ Help = "Index I/O port to access CMOS registers in range: 0x0-0x7f."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_BANK0_DATA"
+ Value = "0x71"
+ Help = "Data I/O port to access CMOS registers in range: 0x0-0x7f."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_MGR_SET_NMI_BIT"
+ Value = "1"
+ Help = "1-Set NMI bit for access to NMI region\0-Do not set NMI bit for access to NMI region"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_NMI_BIT_VALUE"
+ Value = "0x80"
+ Help = "Value to be ORed with the index port value for BANK0 access, when NMI access is enabled."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+ Token = "CMOS_MGR_SET_NMI_BIT" "=" "1"
+End
+
+TOKEN
+ Name = "CMOS_NMI_BIT_VALUE"
+ Value = "0x0"
+ Help = "Value to be ORed with the index port value for BANK0 access, when NMI access is disabled."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+ Token = "CMOS_MGR_SET_NMI_BIT" "=" "0"
+End
+
+TOKEN
+ Name = "CMOS_SETUP_SUPPORT"
+ Value = "0"
+ Help = "This SDL Token specifies whether or not the CMOS module setup page is supported.\(This feature is only supported for TSE versions 4.6.2_TSE_2_01_1204 and later)"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CMOS_MESSAGES_SUPPORT"
+ Value = "0"
+ Help = "This SDL Token specifies whether or not CMOS messages are supported.\(This feature is only supported for TSE versions 4.6.2_TSE_2_01_1204 and later)"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CMOS_USES_STANDARD_BATTERY_TEST"
+ Value = "1"
+ Help = "Specifies whether or not to use CMOS Manager's default battery test function. If a platform provides a different battery test function this token should be disabled."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_USES_STANDARD_IS_FIRST_BOOT"
+ Value = "1"
+ Help = "Specifies whether or not to use CMOS Manager's default first boot test function. If a platform provides a different first boot test function this token should be disabled."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_USES_STANDARD_IS_BSP"
+ Value = "1"
+ Help = "This SDL Token specifies whether or not to use the default function to determine whether or not the boot strap processor is executing. If a platform provides a different function for determining the BSP, this token should be disabled."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_USES_STANDARD_IS_CMOS_USABLE"
+ Value = "1"
+ Help = "This SDL Token specifies whether or not to use the default function to determine whether or not the CMOS is usable. If a platform provides a different function for determining the usability of CMOS, this token should be disabled."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_USES_STANDARD_IS_COLD_BOOT"
+ Value = "1"
+ Help = "This SDL Token specifies whether or not to use the default function to determine whether or not the platform is executing a cold boot."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+ELINK
+ Name = "{0, 0, 0, 127, ReadWriteStandardRange},"
+ Parent = "CMOS_PORT_MAPPING"
+ Help = "Standard NMI-capable access range"
+ Token = "CMOS_USES_STANDARD_RANGE_ACCESS" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosMgrBatteryIsGood"
+ Parent = "CMOS_BATTERY_TEST_MAPPING"
+ Help = "Link the standard function to determine whether or not the CMOS battery is good."
+ Token = "CMOS_USES_STANDARD_BATTERY_TEST" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosMgrIsFirstBoot"
+ Parent = "CMOS_IS_FIRST_BOOT_MAPPING"
+ Help = "Link the standard function to determine whether or not the platform is executing a first boot."
+ Token = "CMOS_USES_STANDARD_IS_FIRST_BOOT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosIsUsable"
+ Parent = "CMOS_IS_USABLE_MAPPING"
+ Help = "Link the standard function to determine whether or not the is usable. (The CMOS may be usable if the battery is bad.)"
+ Token = "CMOS_USES_STANDARD_IS_CMOS_USABLE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosMgrIsBsp"
+ Parent = "CMOS_IS_BSP_MAPPING"
+ Help = "Link the standard function to determine whether or not the BSP is currently executing."
+ Token = "CMOS_USES_STANDARD_IS_BSP" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosMgrIsColdBoot"
+ Parent = "CMOS_IS_COLD_BOOT_MAPPING"
+ Help = "Link the standard function to determine whether or not the platform is executing a cold boot."
+ Token = "CMOS_USES_STANDARD_IS_COLD_BOOT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(CMOS_MANAGER_DIR)\CmosSetup.sd"
+ Parent = "SETUP_DEFINITIONS"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CmosSetup.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+End
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/CmosManager/CmosBoard.ssp b/Core/EM/CmosManager/CmosBoard.ssp
new file mode 100644
index 0000000..0c41c57
--- /dev/null
+++ b/Core/EM/CmosManager/CmosBoard.ssp
@@ -0,0 +1,171 @@
+// This AMI Setup Script Processor (SSP) file contains setup items that
+// are related to the CMOS Manager.
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosBoard.ssp 6 6/15/10 2:22p Michaela $
+//
+// $Revision: 6 $
+//
+// $Date: 6/15/10 2:22p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosBoard.ssp $
+//
+// 6 6/15/10 2:22p Michaela
+//
+// 5 7/29/09 9:54a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 4 6/15/09 5:09p Michaela
+//
+// 3 6/02/09 3:25p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 2 2/06/09 2:05p Michaela
+// MKF_DEFINE_TCG_CMOS_REGISTERS was not used for
+// conditional TPM register declarations
+//
+// 1 11/25/08 3:08p Michaela
+// Added for project specific porting
+//
+// 4 11/07/08 5:14p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 3 3/25/08 3:16p Michaela
+// Several tokens are now only conditionally predefined
+//
+// 2 2/29/08 9:34p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA $
+// Created
+//
+//***************************************************************************
+
+
+//---------------------------------------------------------------------------
+// CMOS manager starts auto-assigning at 0x40
+//
+// This is a typical CMOS usage arrangement.
+// (Note: these locations are not currently reserverd by default.)
+//---------------------------------------------------------------------------
+//
+// 0x00..0x3F Legacy CMOS area, used by CSM
+// 0x40..0x7F OEM/ODM
+// 0x80..0xBF Chipset
+// 0xC0..0xFF Core+Technologies
+//
+// This is the format of a CMOS token defintion:
+//---------------------------------------------------------------------------
+// NvramField
+// OptionBits = integer // how many bits to use
+// [Default = integer] // "optimal" value in assembler format "xxxh"
+// [CheckSum = YES | NO] // include = YES
+// [Location = cmos address, clobber mask]
+// EndNvramField
+
+
+//---------------------------------------------------------------------------
+//
+// Here we pre-define currently known, project-independent, locations.
+//
+// Note: These definitions should be updated/deleleted as modules
+// begin to integrate CMOS manager.
+//
+// *CMOS manager will not complain on duplicate names, unless there
+// is a mask or location conflict.
+//
+//---------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// CMOS Checksum Location
+//----------------------------------------------------------------------------
+// Declare the CMOS checksum location as a non-checksummed value, that spans
+// 2 bytes. The checksum will include only those CMOS addresses that have
+// been explicitly declared with Checksum = YES.
+//
+// * All non-checksummed addresses appear in the NonChecksumTable macros
+// in SspData.h)
+//
+// * The checksum will be computed/used for the entire range of managed,
+// checksummed, CMOS.
+
+NvramField (CMOS_CHECKSUM_HIGH)
+ OptionBits = 8
+ Default = 00h
+ Checksum = NO
+ Location = 040h, 0FFh
+EndNvramField
+
+NvramField (CMOS_CHECKSUM_LOW)
+ OptionBits = 8
+ Default = 00h
+ Checksum = NO
+ Location = 041h, 0FFh
+EndNvramField
+
+
+
+
+//----------------------------------------------------------------------------
+// Reserve 32-Bit CMOS API Pointer
+//----------------------------------------------------------------------------
+
+NvramField (CMOS_API_BYTE3)
+ OptionBits = 8
+ Managed = NO
+ Location = 042h, 0FFh
+EndNvramField
+
+NvramField (CMOS_API_BYTE2)
+ OptionBits = 8
+ Managed = NO
+ Location = 043h, 0FFh
+EndNvramField
+
+NvramField (CMOS_API_BYTE1)
+ OptionBits = 8
+ Managed = NO
+ Location = 044h, 0FFh
+EndNvramField
+
+NvramField (CMOS_API_BYTE0)
+ OptionBits = 8
+ Managed = NO
+ Location = 045h, 0FFh
+EndNvramField
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManager.c b/Core/EM/CmosManager/CmosManager.c
new file mode 100644
index 0000000..6513e67
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManager.c
@@ -0,0 +1,1193 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosManager.c 22 6/15/10 2:24p Michaela $
+//
+// $Revision: 22 $
+//
+// $Date: 6/15/10 2:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosManager.c $
+//
+// 22 6/15/10 2:24p Michaela
+//
+// 21 3/08/10 5:40p Michaela
+//
+// 20 3/05/10 4:55p Michaela
+//
+// 19 12/04/09 7:32p Michaela
+//
+// 18 12/03/09 6:31p Michaela
+// 1. Moved gIsBsp here and added gIsColdBoot definition
+//
+// 2. Updated CmosConfigureManager() to force calculation of
+// checksum after enabling the Optimal Defaults buffer.
+//
+// 3. Updated NewCmosManagerInterface() to update first boot,
+// BSP detected and incoherency policy settings bits prior to
+// calculating the checksum and getting the battery status.
+//
+// 17 11/10/09 9:14p Michaela
+//
+// 16 7/29/09 9:59a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 15 6/15/09 5:11p Michaela
+//
+// 14 6/02/09 3:27p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 13 3/11/09 3:38p Michaela
+//
+// 12 2/16/09 10:26p Michaela
+// Rename CmosManagerAsm to gCmosManagerAsm
+//
+// 11 2/06/09 2:02p Michaela
+// removed hard-coded FIRST_CMOS_REGISTER value
+//
+// 10 11/25/08 3:20p Michaela
+// Updates for Label 4.6.3_CMOSMGR_08
+// - Assembly macro fixes
+// - Added assembly macros
+// - Moved loading defaults into DXE phase
+// - Updated help file example
+//
+// 9 11/17/08 4:41p Michaela
+// --Removed Token Name strings in debug development code
+//
+// 8 11/17/08 3:33p Michaela
+// -added CMOS_ACCESS_TYPE typedef for client code usage
+// -CMOS Buffer feature is depreciated
+// -Removed debug code
+// -SaveApiPointerToCmos & GetApiPointerFromCmos are now
+// directly calling CmosPhysicalReadWrite to avoid error if using
+// Optimal Defaults buffer for Reads/Writes
+// -ABORT_ERROR_STATUS replaced with EFI_ERROR macro
+// usage
+//
+// 7 11/14/08 9:07a Michaela
+// CMOS register variables changed from UINT8 to UINT16
+//
+// 6 11/07/08 5:13p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 5 3/25/08 3:00p Michaela
+// Modified call to SynchronizeLegacyStatusRegisters
+//
+// 4 3/07/08 4:07p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 3 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 2 2/26/08 12:48p Michaela
+// Added/modified Helpbuilder headers
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManager.c
+//
+// Description: Contains the routines that constitute the CMOS manager
+// implementation. This files is used to create object code
+// for both PEI and DXE phases, based upon the build
+// macro PEI_COMPILE.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#ifdef PEI_COMPILE
+ #include <Pei.h>
+ #include <AmiPeiLib.h>
+#else
+ #include <AmiDxeLib.h>
+#endif
+#ifdef SMM_COMPILE
+ #include <Protocol\SmmBase.h>
+#endif
+#include <CmosAccess.h>
+#include "CmosManager.h"
+#include "CmosManagerHob.h"
+#include "SspTokens.h"
+#include "CmosBoard.h"
+
+//---------------------------------------------------------------------------
+// These functions are originally defined in CmosAccess.c
+//---------------------------------------------------------------------------
+extern EFI_STATUS CmosRead(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN UINT16 CmosToken,
+ OUT UINT8 *CmosValue );
+extern EFI_STATUS CmosWrite(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN UINT16 CmosToken,
+ IN UINT8 CmosValue );
+extern UINT16 CmosGetTokenFromRegister(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN UINT16 CmosRegister );
+extern EFI_STATUS CalculateChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 *ChecksumValue );
+extern EFI_STATUS LoadOptimalDefaults(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+extern EFI_STATUS WriteChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 ChecksumValue );
+extern EFI_STATUS ReadChecksum(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 *ChecksumValue );
+extern EFI_STATUS ReadCmosStatusBytes(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ OUT CMOS_STATUS_BYTES *StatusBytes );
+extern EFI_STATUS SynchronizeLegacyStatusRegisters(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap,
+ IN CMOS_BIT_ACCESS_TYPE AccessType );
+extern EFI_STATUS CmosPhysicalReadWrite(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosAddress,
+ IN UINT8 BitsToWrite,
+ IN OUT UINT8 *CmosParameterValue );
+
+extern EFI_STATUS CmosGetDateTime (
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ OUT EFI_TIME *Time );
+
+extern EFI_STATUS CmosSetDateTime (
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos,
+ IN EFI_TIME *Time );
+
+EFI_STATUS UpdateBatteryStatus (
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+
+// porting functions
+
+EFI_CMOS_IS_FIRST_BOOT gIsFirstBoot = CMOS_IS_FIRST_BOOT_MAPPING;
+EFI_CMOS_IS_BSP gIsBsp = CMOS_IS_BSP_MAPPING;
+EFI_CMOS_IS_COLD_BOOT gIsColdBoot = CMOS_IS_COLD_BOOT_MAPPING;
+EFI_CMOS_IS_CMOS_USABLE gCmosIsUsable = CMOS_IS_USABLE_MAPPING;
+
+
+#if defined( PEI_COMPILE ) || defined( SMM_COMPILE )
+
+ // In early PEI, these data items are accessed in ROM.
+
+ // In SMM, the gCmosOptimalDefaultTable structure is
+ // read/write.
+
+ extern CONST CMOS_TOKEN gCmosTokenTable[];
+ extern CONST UINT16 gCmosTokenTableSize;
+ extern CONST CMOS_REGISTER gCmosNoCheckSumTable[];
+ extern CONST UINT16 gCmosNoCheckSumTableSize;
+ extern CONST CMOS_REGISTER gUnmanagedTable[];
+ extern CONST UINT16 gUnmanagedTableSize;
+ extern CMOS_REGISTER gCmosOptimalDefaultTable[];
+ extern CONST UINT16 gCmosOptimalDefaultTableSize;
+ extern CONST UINT8 gFirstManagedRegister;
+ extern CONST UINT8 gLastManagedRegister;
+#endif
+
+
+#ifdef PEI_COMPILE // PEI phase-specific declarations
+ extern EFI_STATUS SaveCmosDataTablesToHob(
+ EFI_PEI_SERVICES **PeiServices,
+ EFI_CMOS_MANAGER_INTERFACE *Manager );
+ extern VOID CmosSynchronizeHobManagerStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+#endif
+
+
+// DXE phase-specific declarations
+
+#if !defined(PEI_COMPILE) && !defined(SMM_COMPILE)
+ extern EFI_STATUS InitializeCmosTablesFromHob(
+ EFI_CMOS_MANAGER_INTERFACE *Manager );
+
+#endif
+
+
+#ifdef PEI_COMPILE // PEI phase-specific globals
+ EFI_GUID gCmosAccessGuid = EFI_PEI_CMOS_ACCESS_GUID;
+ EFI_GUID gMemoryInstalledGuid =
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI;
+
+#elif defined(SMM_COMPILE) // SMM-specific globals
+ EFI_GUID gCmosAccessGuid = EFI_SMM_CMOS_ACCESS_GUID;
+
+#else // default is DXE phase-specific globals
+ EFI_GUID gCmosAccessGuid = EFI_DXE_CMOS_ACCESS_GUID;
+
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerAllocatePool
+//
+// Description:
+// This function allocates memory for all boot phases.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Services table (NULL in DXE phase)
+// IN UINTN Size
+// -- Number of bytes to allocate
+// OUT VOID **Buffer
+// -- Pointer to buffer for which memory is allocated
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosManagerAllocatePool(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN Size,
+ OUT VOID **Buffer )
+{
+#ifdef PEI_COMPILE
+ return (*PeiServices)->AllocatePool( PeiServices,
+ Size, Buffer);
+#elif defined(SMM_COMPILE)
+ return pSmst->SmmAllocatePool(0, Size, Buffer);
+#else // DXE
+ return pBS->AllocatePool( EfiBootServicesData, Size, Buffer);
+#endif
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosGetMangerInterface
+//
+// Description:
+// Gets the EFI_CMOS_MANAGER_INTERFACE for the current access
+// interface.
+//
+// Input:
+// IN EFI_CMOS_ACCESS_INTERFACE *Cmos
+// -- This is the access interface pointer.
+//
+// Output:
+// EFI_CMOS_MANAGER_INTERFACE * (Return Value)
+// -- If successful, the CMOS manager interface is returned.
+// -- Otherwise, a valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_CMOS_MANAGER_INTERFACE *GetCmosMangerInterface(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos )
+{
+ // The installed Protocol type will be EFI_CMOS_ACCESS_INTERFACE
+ // (converted as needed by the CMOS manager)
+
+ EFI_CMOS_MANAGER_INTERFACE *Interface = (EFI_CMOS_MANAGER_INTERFACE*) Cmos;
+ return Interface;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetCmosAccessInterface
+//
+// Description:
+// Gets the EFI_CMOS_ACCESS_INTERFACE for the current manager
+// interface.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- This is the manager interface pointer.
+//
+// Output:
+// EFI_CMOS_ACCESS_INTERFACE * (Return Value)
+// -- If successful, the CMOS access interface is returned.
+// -- Otherwise, NULL is returned.
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_CMOS_ACCESS_INTERFACE *GetCmosAccessInterface(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager )
+{
+ EFI_CMOS_ACCESS_INTERFACE *Interface = NULL;
+
+ // The installed Protocol type will be EFI_CMOS_ACCESS_INTERFACE
+ // (converted as needed by the CMOS manager)
+ if (Manager != NULL &&
+ Manager->CheckStatus(Manager, CMOS_VALID_INTERFACE))
+ Interface = (EFI_CMOS_ACCESS_INTERFACE*) Manager;
+
+ return Interface;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerCheckStatus
+//
+// Description:
+// This function returns true if all the status bits are set as
+// specified by the BitMap.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+// IN CMOS_MANAGER_STATUS BitMap
+// -- Bits to check
+//
+//
+// Output:
+// BOOLEAN (Return value)
+// = TRUE, if all bits in ManagerStatus specified by
+// BitMap are set.
+//
+// = FALSE, otherwise.
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CmosManagerCheckStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap )
+{
+ if ((Manager->ManagerStatus & BitMap) == BitMap)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerCheckAnyStatus
+//
+// Description:
+// This function returns true if any of the status bits are set as
+// specified by the BitMap.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+// IN CMOS_MANAGER_STATUS BitMap
+// -- Bits to check
+//
+//
+// Output:
+// BOOLEAN (Return value)
+// = TRUE, if one or more of the bits in ManagerStatus
+// specified by BitMap are set.
+//
+// = FALSE, otherwise.
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN CmosManagerCheckAnyStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap )
+{
+ if ((Manager->ManagerStatus & BitMap) != 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerSetClearStatus
+//
+// Description:
+// This function provides a single entry point into the code that
+// actually updates status values.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+// IN CMOS_MANAGER_STATUS BitMap
+// -- Bits to set or clear
+// IN CMOS_BIT_ACCESS_TYPE AccessType
+// -- SetType or ClearType depending upon whether
+// setting or clearing bits
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CmosManagerSetClearStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN CMOS_MANAGER_STATUS BitMap,
+ IN CMOS_BIT_ACCESS_TYPE AccessType )
+{
+ if (AccessType == SetType){
+ Mgr->ManagerStatus = Mgr->ManagerStatus | BitMap;
+
+ // A boot/setup event callback explicitly clears these bits each boot
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_IS_USABLE) ){
+ if ( BitMap & CMOS_BAD_BATTERY )
+ Mgr->Access.Write(&Mgr->Access, CMOS_MGR_BATTERY_BAD, 1);
+ if ( BitMap & CMOS_BAD_CHECKSUM )
+ Mgr->Access.Write(&Mgr->Access, CMOS_MGR_CHECKSUM_BAD, 1);
+ if ( BitMap & CMOS_DEFAULTS_LOADED )
+ Mgr->Access.Write(&Mgr->Access, CMOS_MGR_DEFAULTS_LOADED, 1);
+ if ( BitMap & CMOS_FIRST_BOOT_DETECTED )
+ Mgr->Access.Write(&Mgr->Access, CMOS_MGR_FIRST_BOOT_DETECTED, 1);
+ }
+
+ }
+ else
+ Mgr->ManagerStatus = Mgr->ManagerStatus & ~BitMap;
+
+#ifdef PEI_COMPILE // In PEI, update ManagerStatus for DXE
+ CmosSynchronizeHobManagerStatus(Mgr);
+#endif
+
+ // if the Checksum or Battery status is being modified, then
+ // update the legacy status registers
+ if ( (BitMap & (CMOS_BAD_CHECKSUM | CMOS_BAD_BATTERY)) != 0 ){
+ SynchronizeLegacyStatusRegisters(Mgr, BitMap, AccessType);
+ }
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerSetStatus
+//
+// Description:
+// This function sets status bits according to the specified bitmap.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+// IN CMOS_MANAGER_STATUS BitMap
+// -- Bits to set
+//
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CmosManagerSetStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap )
+{
+ CmosManagerSetClearStatus(Manager, BitMap, SetType);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerClearStatus
+//
+// Description:
+// This function clears status bits according to the specified bitmap.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+// IN CMOS_MANAGER_STATUS BitMap
+// -- Bits to clear
+//
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CmosManagerClearStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap )
+{
+ CmosManagerSetClearStatus(Manager, BitMap, ClearType);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosUpdateMemoryStatus
+//
+// Description:
+// This function is used in the PEI phase to set/clear the
+// CMOS_EXECUTING_IN_MEMORY depending on whether or not the manager
+// is executing after permanent memory has been initialized.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+//
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef PEI_COMPILE
+VOID CmosUpdateMemoryStatus (
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *InterfacePtr;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS, "CmosUpdateMemoryStatus Entry\n"));
+
+ Status = (*PeiServices)->LocatePpi( PeiServices, &gMemoryInstalledGuid,
+ 0, NULL, &InterfacePtr);
+ if ( EFI_ERROR(Status) )
+ Manager->ClearStatus(Manager, CMOS_EXECUTING_IN_MEMORY);
+ else
+ Manager->SetStatus(Manager, CMOS_EXECUTING_IN_MEMORY);
+
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosConfigureManager
+//
+// Description:
+// This function configures the CMOS Manager.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Pointer to the Manager's interface
+// IN CMOS_CONFIGURATION_SETTING Setting
+// -- Configuration setting to invoke.
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosConfigureManager(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN CMOS_CONFIGURATION_SETTING Setting )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+#define Request(x) ((Setting & (x)) != 0)
+
+ // Basic error checking
+
+ if ( Request(CMOS_OPTIMAL_DEFAULTS_ON)
+ && Request(CMOS_OPTIMAL_DEFAULTS_OFF) )
+ {
+ return Status = EFI_INVALID_PARAMETER;
+ }
+
+ //-----------------------------------------------------------------------
+ // CMOS_OPTIMAL_DEFAULTS_ON
+ //-----------------------------------------------------------------------
+ // If configuring usage of the optimal defaults buffer and it's already
+ // enabled, simply return. Otherwise...
+ //
+ // * If executing in memory, enable the optimal defaults buffer
+ // and update the checksum.
+ // * If not executing in memory, allocate the optimal defaults buffer,
+ // copy the values into it, and update the
+ // Manager->OptimalDefaultTable pointer to point to the read/write
+ // buffer.
+ // * Set the manager status bit to indicate usage of the optimal
+ // defaults buffer.
+
+ if ( Request( CMOS_OPTIMAL_DEFAULTS_ON ) )
+ {
+ if (Mgr->CheckStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED))
+ return EFI_SUCCESS; // already configured
+
+ // This will only occur in PEI phase!!
+
+ if (!Mgr->CheckStatus(Mgr, CMOS_EXECUTING_IN_MEMORY)) {
+ VOID *Temp;
+ CmosManagerAllocatePool( PeiServices,
+ Mgr->OptimalDefaultCount * sizeof(CMOS_REGISTER),
+ &Temp);
+ MemCpy( Temp , Mgr->OptimalDefaultTable,
+ Mgr->OptimalDefaultCount * sizeof(CMOS_REGISTER) );
+ Mgr->OptimalDefaultTable = Temp;
+ }
+
+ Mgr->SetStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED);
+ Mgr->CalculateChecksum(Mgr, &Mgr->Checksum);
+ Mgr->WriteChecksum(Mgr, Mgr->Checksum);
+
+ }
+
+ //-----------------------------------------------------------------------
+ // CMOS_OPTIMAL_DEFAULTS_OFF
+ //-----------------------------------------------------------------------
+ //
+ // Clear the status bit, and let the Manager interface user must decide
+ // what to do next ...call LoadOptimalDefaults, enable buffered CMOS
+ // mode, ....
+
+ if ( Request( CMOS_OPTIMAL_DEFAULTS_OFF ) ){
+ Mgr->ClearStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED);
+ }
+
+#undef Request
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveApiPointerToCmos
+//
+// Description:
+// This function saves the specified pointer to a predefined 4-byte
+// CMOS location.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *CmosManager
+// - Pointer to the manager's interface
+// IN EFI_CMOS_ACCESS_INTERFACE *ApiPointer
+// - API address
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SaveApiPointerToCmos(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ IN EFI_CMOS_ACCESS_INTERFACE *ApiPointer )
+{
+ UINT32 Offset;
+ UINT8 Byte; // Only used in PEI
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ if (ApiPointer == NULL)
+ ApiPointer = Mgr->GetAccessInterface(Mgr);
+
+ if ( !Mgr->CheckAnyStatus(Mgr, CMOS_IS_USABLE ) ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "CMOS Not Usable: Could not save API pointer.\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ for (Offset = 0; Offset < 4; Offset++){
+ Byte = (UINT8)((UINT32)ApiPointer >> (24 - (Offset * 8))) & 0xff;
+ CmosPhysicalReadWrite( Mgr,
+ WriteType,
+ CMOS_ACCESS_API_BYTE3 + Offset,
+ ALL_BITS,
+ &Byte );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetApiPointerFromCmos
+//
+// Description:
+// This function get the CMOS API pointer from a predefined 4-byte
+// CMOS location and updates the output parameter with the pointer.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *CmosManager
+// - Pointer to the manager's interface to be installed
+// OUT EFI_CMOS_ACCESS_INTERFACE **ApiPointer
+// - Address of the API pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetApiPointerFromCmos(
+ IN EFI_CMOS_MANAGER_INTERFACE *Mgr,
+ EFI_CMOS_ACCESS_INTERFACE **ApiPointer )
+{
+ UINT8 Temp;
+ UINT32 Ptr = 0;
+ UINT8 Offset;
+ DEFINE_PEI_SERVICES(Mgr->Access.PeiServices);
+
+ if ( !Mgr->CheckAnyStatus(Mgr, CMOS_IS_USABLE ) ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "CMOS Not Usable: Could not read API pointer.\n"));
+ return EFI_DEVICE_ERROR;
+ }
+
+ for (Offset = 0; Offset < 4; Offset++){
+ CmosPhysicalReadWrite( Mgr,
+ ReadType,
+ CMOS_ACCESS_API_BYTE3 + Offset,
+ 0,
+ &Temp );
+ Ptr = (Ptr << 8) | Temp;
+ }
+
+ *ApiPointer = (EFI_CMOS_ACCESS_INTERFACE*) Ptr;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallCmosAccessInterface
+//
+// Description:
+// This function installs either the PEI or DXE phase interface
+// (PPI or Protocol) for accessing CMOS.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *CmosManager
+// - Pointer to the interface to be installed
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+// CmosManager->ManagerStatus
+// = CMOS_VALID_MANAGER indicates successful
+// installation of interface.
+//
+// Notes:
+// This function is used for both PEI and DXE phase. The build
+// macro PEI_COMPILE will determine how the object code is
+// created/linked.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallCmosAccessInterface(
+ IN EFI_CMOS_MANAGER_INTERFACE *CmosManager )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_HANDLE Handle = 0;
+ DEFINE_PEI_SERVICES(CmosManager->Access.PeiServices);
+
+#ifdef PEI_COMPILE
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices, &CmosManager->Ppi[CMOS_ACCESS_PPI_TYPE]);
+#else
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle, &CmosManager->AccessGuid, CmosManager, NULL);
+#endif
+
+ if (!EFI_ERROR(Status))
+ CmosManager->SetStatus(CmosManager, CMOS_VALID_MANAGER);
+ else {
+ CmosManager->SetStatus(CmosManager, CMOS_INSTALL_FAILED);
+ CmosManager->ClearStatus(CmosManager, CMOS_VALID_MANAGER);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeCmosManagerInterface
+//
+// Description:
+// This function initializes structure data and function pointer
+// elements for a EFI_CMOS_MANAGER_INTERFACE.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// - This parameter will be NULL in the DXE phase
+// OUT EFI_CMOS_MANAGER_INTERFACE *CmosManager
+// - Pointer to the interface to be initialized
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS or valid EFI error code
+// CmosManager->ManagerStatus
+// = CMOS_VALID_INTERFACE indicates successful
+// initialization of the structure.
+//
+// Notes:
+// This function is used for both PEI and DXE phase. The build
+// macro PEI_COMPILE will determine how the object code is
+// created.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS InitializeCmosManagerInterface(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT EFI_CMOS_MANAGER_INTERFACE *CmosManager )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "InitializeCmosManagerInterface Entry\n"));
+
+ // Note: all pointers/values are already NULL/Zero
+
+ // Not using an initializer list in order to avoid problems
+ // if/when the interface declarations are modified.
+
+ //-----------------------------------------------------------------------
+ // Phase-independent initialization
+ //-----------------------------------------------------------------------
+ CmosManager->AccessGuid = gCmosAccessGuid;
+ CmosManager->Access.PeiServices = PeiServices; // ensure NULL in DXE
+ CmosManager->Access.Read = CmosRead;
+ CmosManager->Access.Write = CmosWrite;
+ CmosManager->Access.GetTokenFromRegister = CmosGetTokenFromRegister;
+ CmosManager->Access.ReadCmosStatusBytes = ReadCmosStatusBytes;
+ CmosManager->Access.GetTime = CmosGetDateTime;
+ CmosManager->Access.SetTime = CmosSetDateTime;
+ CmosManager->GetAccessInterface = GetCmosAccessInterface;
+ CmosManager->InstallAccessInterface = InstallCmosAccessInterface;
+ CmosManager->CalculateChecksum = CalculateChecksum;
+ CmosManager->ReadChecksum = ReadChecksum;
+ CmosManager->WriteChecksum = WriteChecksum;
+ CmosManager->ConfigureManager = CmosConfigureManager;
+ CmosManager->CheckStatus = CmosManagerCheckStatus;
+ CmosManager->CheckAnyStatus = CmosManagerCheckAnyStatus;
+ CmosManager->SetStatus = CmosManagerSetStatus;
+ CmosManager->ClearStatus = CmosManagerClearStatus;
+ CmosManager->LoadOptimalDefaults = LoadOptimalDefaults;
+ CmosManager->SaveApiPointerToCmos = SaveApiPointerToCmos;
+ CmosManager->GetApiPointerFromCmos = GetApiPointerFromCmos;
+
+ //-----------------------------------------------------------------------
+ // Phase-specific initialization
+ //-----------------------------------------------------------------------
+ // update the access PPI descriptor and CMOS data table pointers.
+ //
+ // Note:
+ // Before memory detection, the tables to which these pointers refer
+ // will reside in ROM. At runtime, these tables will reside in
+ // SMRAM and boot updates will be copied into them.
+ //-----------------------------------------------------------------------
+
+#if defined(PEI_COMPILE) || defined(SMM_COMPILE)
+ CmosManager->FirstManagedRegister = gFirstManagedRegister;
+ CmosManager->LastManagedRegister = gLastManagedRegister;
+ CmosManager->TokenTable = (CMOS_TOKEN*) gCmosTokenTable;
+ CmosManager->TokenCount = gCmosTokenTableSize;
+ CmosManager->NoChecksumTable = (CMOS_REGISTER*) gCmosNoCheckSumTable;
+ CmosManager->NoChecksumCount = gCmosNoCheckSumTableSize;
+ CmosManager->UnmanagedTable = (CMOS_REGISTER*) gUnmanagedTable;
+ CmosManager->UnmanagedTableCount = gUnmanagedTableSize;
+ CmosManager->OptimalDefaultTable =
+ (CMOS_REGISTER*) gCmosOptimalDefaultTable;
+ CmosManager->OptimalDefaultCount = gCmosOptimalDefaultTableSize;
+#endif
+
+#if defined(PEI_COMPILE)
+ CmosManager->Ppi[CMOS_ACCESS_PPI_TYPE].Flags =
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ CmosManager->Ppi[CMOS_ACCESS_PPI_TYPE].Guid = &gCmosAccessGuid;
+ CmosManager->Ppi[CMOS_ACCESS_PPI_TYPE].Ppi = (VOID*)CmosManager;
+#endif
+
+ CmosManager->SetStatus(CmosManager, CMOS_VALID_INTERFACE);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: NewCmosManagerInterface
+//
+// Description:
+// This function locates (or allocates memory for) the
+// EFI_CMOS_MANAGER_INTERFACE, calculates the checksum, checks the
+// battery condition and updates the Manager's status bits.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// - This parameter will be NULL in the DXE phase
+//
+// Output:
+// EFI_CMOS_MANAGER_INTERFACE* (Return Value)
+// = If successful, a pointer to the allocated/found
+// structure is returned.
+// = NULL is returned on failure to allocate
+//
+// NewManager->ManagerStatus
+// = CMOS_INTERFACE_ALREADY_INSTALLED, if the interface is
+// found prior to allocating
+// = CMOS_VALID_INTERFACE, on successful initialization
+// of the access interface.
+//
+// Notes:
+// This function is used for PEI, DXE and SMM interface initialization.
+// The build macros PEI_COMPILE and SMM_COMPILE will determine how the
+// object code is compiled.
+//
+// See CMOS_MANAGER_STATUS enum type for more information on manager
+// status bits.
+//
+// Assumptions:
+//
+// 1) This function should only be called once for each
+// entrypoint.
+//
+// 2) It is up to the user of the Manager interface to determine
+// how to use the CMOS_MANAGER_STATUS bits upon return from
+// this function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_CMOS_MANAGER_INTERFACE* NewCmosManagerInterface(
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_CMOS_MANAGER_INTERFACE *NewManager;
+ EFI_STATUS Status;
+
+ //-----------------------------------------------------------------------
+ // If the interface is found then no initialization is done.
+ //-----------------------------------------------------------------------
+
+#ifdef PEI_COMPILE
+ LOCATE_CMOS_ACCESS_PPI(Status, NewManager);
+#elif defined (SMM_COMPILE)
+ LOCATE_CMOS_ACCESS_SMM_PROTOCOL(Status, NewManager)
+#else
+ LOCATE_CMOS_ACCESS_PROTOCOL(Status, NewManager)
+#endif
+ if (Status == EFI_SUCCESS)
+ {
+ NewManager->SetStatus(NewManager, CMOS_INTERFACE_ALREADY_INSTALLED);
+ return NewManager;
+ }
+
+ //-----------------------------------------------------------------------
+ // Return NULL on allocation error.
+ //-----------------------------------------------------------------------
+
+ if (EFI_ERROR(CmosManagerAllocatePool( PeiServices,
+ sizeof(EFI_CMOS_MANAGER_INTERFACE),
+ (VOID**)&NewManager ) )){
+ return NULL;
+ }
+
+ //-----------------------------------------------------------------------
+ // Zero the interface buffer (also ensures ManagerStatus bits are clear
+ // and ensures pointers are NULL)
+ //-----------------------------------------------------------------------
+
+ MemSet( (void*)NewManager, sizeof(EFI_CMOS_MANAGER_INTERFACE), 0);
+
+ //-----------------------------------------------------------------------
+ // Initialize general structures and function pointers
+ //-----------------------------------------------------------------------
+
+ InitializeCmosManagerInterface(PeiServices, NewManager);
+
+ //-----------------------------------------------------------------------
+ // Initialize pointers to/from data structures in the HOB or DXE Buffer
+ // updates
+ //-----------------------------------------------------------------------
+ // In PEI phase:
+ // 1. Update memory status
+ //
+ // In DXE phase:
+ // 1. Get the HOB and complete the initialization of the Manager
+ // interface data structure pointers.
+ //
+ // In SMM registration:
+ // 1. Use the original optimal defaults buffer, as the DXE buffer
+ // has already by flushed to the physical registers if the battery
+ // is good. (If the battery is bad, it is unlikely CMOS is of
+ // any use in SMM.)
+
+#ifdef PEI_COMPILE
+ CmosUpdateMemoryStatus( NewManager );
+#elif !defined(SMM_COMPILE)
+ if (EFI_ERROR( InitializeCmosTablesFromHob(NewManager) ))
+ return NULL;
+#endif
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Call CmosIsUsable: " ));
+ if ( gCmosIsUsable( NewManager->Access.PeiServices ) ){
+ NewManager->SetStatus(NewManager, CMOS_IS_USABLE);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CMOS is usable\n" ));
+ }
+ else {
+ NewManager->ClearStatus(NewManager, CMOS_IS_USABLE);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CMOS is not usable\n" ));
+ }
+
+ //-----------------------------------------------------------------------
+ // Update CMOS_FIRST_BOOT_DETECTED status bit before calculating
+ // the checksum or determining the battery status.
+ //-----------------------------------------------------------------------
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Call gIsFirstBoot: " ));
+ if ( gIsFirstBoot( NewManager->Access.PeiServices ) ){
+ NewManager->SetStatus(NewManager, CMOS_FIRST_BOOT_DETECTED);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "First boot detected\n" ));
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "First boot NOT detected\n" ));
+ }
+
+ // Update CMOS_COLD_BOOT_DETECTED status bit.
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Call gIsColdBoot: " ));
+ if ( gIsColdBoot( NewManager->Access.PeiServices ) ){
+ NewManager->SetStatus(NewManager, CMOS_COLD_BOOT_DETECTED);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Cold boot detected\n" ));
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Cold boot NOT detected\n" ));
+ }
+
+ // Update CMOS_BSP_IS_EXECUTING status bit.
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Call gIsBsp: " ));
+ if ( gIsBsp( NewManager->Access.PeiServices ) ){
+ NewManager->SetStatus(NewManager, CMOS_BSP_IS_EXECUTING);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "BSP is executing\n" ));
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "BSP is NOT executing\n" ));
+ }
+
+ // Configure incoherency recovery policy
+
+#if CMOS_MGR_RECOVER_ONLY_CHECKUMMED
+ NewManager->SetStatus(NewManager, CMOS_RECOVER_ONLY_CHECKSUMMED);
+#endif
+
+#if CMOS_MGR_RECOVER_IN_PEI
+ NewManager->SetStatus(NewManager, CMOS_RECOVER_IN_PEI);
+#endif
+
+
+ //-----------------------------------------------------------------------
+ // Update the NewManager->Checksum
+ //
+ // Note: This call only calculates and updates the checksum in
+ // the manager interface structure. The CMOS_BAD_CHECKSUM bit
+ // is set in NewManager->ManagerStatus, if the calculated checksum
+ // does not match the current checksum in CMOS.
+ //
+ // The user of the Manager interface will decide how to handle
+ // a bad checksum.
+ //-----------------------------------------------------------------------
+
+ NewManager->CalculateChecksum(NewManager, &NewManager->Checksum);
+
+ UpdateBatteryStatus(NewManager);
+
+ return NewManager;
+}
+
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManager.chm b/Core/EM/CmosManager/CmosManager.chm
new file mode 100644
index 0000000..5dc1ea2
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManager.chm
Binary files differ
diff --git a/Core/EM/CmosManager/CmosManager.cif b/Core/EM/CmosManager/CmosManager.cif
new file mode 100644
index 0000000..7bedda6
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManager.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "CMOS Manager"
+ category = eModule
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosManager"
+[files]
+"CmosManager.sdl"
+"CmosManager.chm"
+[parts]
+"CmosBoard"
+"CmosSec"
+"CmosPei"
+"CmosDxe"
+"CmosSmm"
+"CmosCore"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManager.h b/Core/EM/CmosManager/CmosManager.h
new file mode 100644
index 0000000..7c039df
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManager.h
@@ -0,0 +1,260 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Includes/CmosManager.h 12 6/15/10 2:26p Michaela $
+//
+// $Revision: 12 $
+//
+// $Date: 6/15/10 2:26p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Includes/CmosManager.h $
+//
+// 12 6/15/10 2:26p Michaela
+//
+// 11 12/04/09 7:32p Michaela
+//
+// 10 7/29/09 10:00a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 9 6/15/09 5:11p Michaela
+//
+// 8 6/02/09 3:28p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 7 11/25/08 3:20p Michaela
+// Updates for Label 4.6.3_CMOSMGR_08
+// - Assembly macro fixes
+// - Added assembly macros
+// - Moved loading defaults into DXE phase
+// - Updated help file example
+//
+// 6 11/17/08 3:51p Michaela
+// --CMOS Buffer feature is depreciated
+//
+// 5 11/14/08 9:17a Michaela
+// **CMOS register variables are changed from UINT8 to UINT16
+//
+// 4 11/07/08 5:13p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 3 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 2 2/26/08 12:50p Michaela
+// Added/modified Helpbuilder headers
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManager.h
+//
+// Description: Contains the constants, data types and declarations
+// necessary to support the CMOS manager interface.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//<AMI_GHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Internal_Interfaces
+//
+// Description:
+// The page provides links to descriptions of the internal interfaces
+// used by the CMOS Manager's subsystems.
+//
+// Fields: Phase Name Description
+// ------------------------------------------------------------------
+// All EFI_CMOS_MANAGER_INTERFACE Provides general services
+//
+//----------------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+
+#ifndef _CMOS_MANAGER_H
+#define _CMOS_MANAGER_H
+
+#include <Efi.h>
+#include <CmosAccess.h>
+#include "CmosManagerHob.h"
+#include "CmosTypes.h"
+
+typedef struct _EFI_CMOS_MANAGER_INTERFACE EFI_CMOS_MANAGER_INTERFACE;
+
+typedef EFI_STATUS (*CMOS_MANAGER_DISPLAY_TOKEN_TABLE) (
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+
+typedef EFI_CMOS_ACCESS_INTERFACE * (*CMOS_MANAGER_GET_ACCESS_INTERFACE) (
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+
+typedef EFI_STATUS (*CMOS_MANAGER_INSTALL_ACCESS_INTERFACE) (
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+
+typedef EFI_STATUS (*CMOS_MANAGER_CALCULATE_CHECKSUM)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 *ChecksumValue );
+
+typedef EFI_STATUS (*CMOS_MANAGER_READ_CHECKSUM)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 *ChecksumValue );
+
+typedef EFI_STATUS (*CMOS_MANAGER_WRITE_CHECKSUM)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ OUT UINT16 ChecksumValue );
+
+typedef EFI_STATUS (*CMOS_MANAGER_CONFIGURE) (
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_CONFIGURATION_SETTING Setting );
+
+typedef VOID (*CMOS_MANAGER_SET_STATUS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap );
+
+typedef VOID (*CMOS_MANAGER_CLEAR_STATUS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap );
+
+typedef BOOLEAN (*CMOS_MANAGER_CHECK_STATUS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap );
+
+typedef BOOLEAN (*CMOS_MANAGER_CHECK_ANY_STATUS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN CMOS_MANAGER_STATUS BitMap );
+
+typedef EFI_STATUS (*CMOS_MANAGER_LOAD_OPTIMAL_DEFAULTS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager );
+
+typedef EFI_STATUS (*CMOS_MANAGER_SAVE_API_POINTER_TO_CMOS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN EFI_CMOS_ACCESS_INTERFACE *ApiPointer );
+
+typedef EFI_STATUS (*CMOS_MANAGER_GET_API_POINTER_FROM_CMOS)(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager,
+ IN EFI_CMOS_ACCESS_INTERFACE **ApiPointer );
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EFI_CMOS_MANAGER_INTERFACE
+//
+// Description:
+// This is the internal interface used by subsystems within the CMOS
+// manager module.
+//
+// Fields: Type Name Description
+// EFI_CMOS_ACCESS_INTERFACE Access The external interface
+// CMOS_MANAGER_INSTALL_ACCESS_INTERFACE InstallAccessInterface Installs the Access PPI or Protocol, depending on the phase (see InstallCmosAccessInterface)
+// CMOS_MANAGER_GET_ACCESS_INTERFACE GetAccessInterface Used internally to get a pointer to the Access interface (see GetCmosAccessInterface)
+// EFI_GUID AccessGuid The Access PPI (or Protocol) GUID
+// EFI_PEI_PPI_DESCRIPTOR Ppi[4] Descriptors for the PEIMs installed by this module
+// UINT8 FirstManagedRegister First register in the managed space
+// UINT8 LastManagedRegister Last register in the managed space
+// CMOS_TOKEN *TokenTable All defined tokens
+// UINT16 TokenCount Entry count for TokenTable (#Tokens + 1)
+// CMOS_REGISTER *OptimalDefaultTable Default values for all managed CMOS addresses
+// UINT16 OptimalDefaultCount Entry count for OptimalDefaultTable
+// CMOS_REGISTER *NoChecksumTable CMOS address of locations not included in the checksum in the managed area
+// UINT16 NoChecksumCount Entry count for NoChecksumTable
+// CMOS_MANAGER_CONFIGURE ConfigureManager Provides means for specifying configurable settings for CMOS manager during PEI/DXE initialization (see CmosConfigureManager)
+// CMOS_CHECKSUM Checksum Valid checksum after the call to NewCmosManagerInterface()
+// CMOS_MANAGER_CALCULATE_CHECKSUM CalculateChecksum Forces calculation of the checksum over the entire managed region
+// CMOS_MANAGER_READ_CHECKSUM ReadChecksum Reads checksum from the CMOS checksum location
+// CMOS_MANAGER_WRITE_CHECKSUM WriteChecksum Writes the provided checksum to the CMOS checksum location
+// CMOS_MANAGER_LOAD_OPTIMAL_DEFAULTS LoadOptimalDefaults Writes default values from the OptimalDefaultTable to all CMOS registers
+// CMOS_MANAGER_STATUS ManagerStatus Bitmap containing various Manager-related status values
+// CMOS_MANAGER_SET_STATUS SetStatus Sets bits in the ManagerStatus value (see CmosManagerSetStatus)
+// CMOS_MANAGER_CLEAR_STATUS ClearStatus Clears bits in the ManagerStatus value (see CmosManagerClearStatus)
+// CMOS_MANAGER_CHECK_STATUS CheckStatus Returns true if all of the specified bits are "set" in the ManagerStatus value (see CmosManagerCheckStatus)
+// CMOS_MANAGER_CHECK_ANY_STATUS CheckAnyStatus Returns true if any of the specified bits are "set" in the ManagerStatus value (see CmosManagerCheckAnyStatus)
+// CMOS_MANAGER_HOB *ManagerHob Pointer to the HOB defined after permanent memory detection in PEI
+// CMOS_MANAGER_SAVE_API_POINTER_TO_CMOS SaveApiPointerToCmos Pointer to the Access interface is maintained in a 4-byte CMOS location
+// CMOS_MANAGER_GET_API_POINTER_FROM_CMOS GetApiPointerFromCmos Retrieve pointer to the Access interface from 4-byte CMOS location
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+#pragma pack(push, 1) // force byte alignment
+typedef struct _EFI_CMOS_MANAGER_INTERFACE
+{
+ // Note: EFI_CMOS_ACCESS_INTERFACE must be first in this structure
+ EFI_CMOS_ACCESS_INTERFACE Access; // Access
+ CMOS_MANAGER_INSTALL_ACCESS_INTERFACE InstallAccessInterface;
+ CMOS_MANAGER_GET_ACCESS_INTERFACE GetAccessInterface;
+ EFI_GUID AccessGuid;
+ EFI_PEI_PPI_DESCRIPTOR Ppi[4];
+ UINT16 FirstManagedRegister;
+ UINT16 LastManagedRegister;
+ CMOS_TOKEN *TokenTable; // Tables
+ UINT16 TokenCount;
+ CMOS_REGISTER *OptimalDefaultTable;
+ UINT16 OptimalDefaultCount;
+ CMOS_REGISTER *NoChecksumTable;
+ UINT16 NoChecksumCount;
+ CMOS_REGISTER *UnmanagedTable;
+ UINT16 UnmanagedTableCount;
+ CMOS_MANAGER_CONFIGURE ConfigureManager; // Manager
+ CMOS_CHECKSUM Checksum;
+ CMOS_MANAGER_CALCULATE_CHECKSUM CalculateChecksum;
+ CMOS_MANAGER_READ_CHECKSUM ReadChecksum;
+ CMOS_MANAGER_WRITE_CHECKSUM WriteChecksum;
+ CMOS_MANAGER_LOAD_OPTIMAL_DEFAULTS LoadOptimalDefaults;
+ CMOS_MANAGER_STATUS ManagerStatus;
+ CMOS_MANAGER_SET_STATUS SetStatus;
+ CMOS_MANAGER_CLEAR_STATUS ClearStatus;
+ CMOS_MANAGER_CHECK_STATUS CheckStatus;
+ CMOS_MANAGER_CHECK_ANY_STATUS CheckAnyStatus;
+ CMOS_MANAGER_HOB *ManagerHob;
+ CMOS_MANAGER_SAVE_API_POINTER_TO_CMOS SaveApiPointerToCmos;
+ CMOS_MANAGER_GET_API_POINTER_FROM_CMOS GetApiPointerFromCmos;
+};
+#pragma pack(pop) // force byte alignment
+
+// This is the only exposed internal CMOS manager function
+EFI_CMOS_MANAGER_INTERFACE* NewCmosManagerInterface(
+ EFI_PEI_SERVICES **PeiServices );
+
+#endif // #ifndef _CMOS_MANAGER_H
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManager.mak b/Core/EM/CmosManager/CmosManager.mak
new file mode 100644
index 0000000..407d239
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManager.mak
@@ -0,0 +1,423 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#
+# $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Build/CmosManager.mak 23 6/15/10 2:26p Michaela $
+#
+# $Revision: 23 $
+#
+# $Date: 6/15/10 2:26p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Build/CmosManager.mak $
+#
+# 23 6/15/10 2:26p Michaela
+#
+# 22 3/05/10 4:55p Michaela
+#
+# 21 12/03/09 6:48p Michaela
+# 1. Clean-up the SEC target code
+#
+# 2. Define CMOS_IS_COLD_BOOT_MAPPING environment
+# variable passed to C-source for cold boot
+# detection function overriding
+#
+# 20 11/12/09 6:06p Michaela
+# Fixed build dependencies so that client make files can put
+# a dependency on SspTokens.h for rebuilding only if SSP files
+# change or a project rebuild is invoked.
+#
+# 19 11/10/09 9:14p Michaela
+#
+# 18 7/29/09 10:01a Michaela
+# updates Aptio Enhancement EIP 22205
+# (no code changes)
+#
+# 17 7/23/09 1:30p Michaela
+# Fix PE32 related build issue
+#
+# 16 6/15/09 5:12p Michaela
+#
+# 15 6/02/09 3:28p Michaela
+# For label: 4.6.3_CMOSMGR_11
+#
+# 14 3/11/09 3:38p Michaela
+#
+# 13 2/23/09 6:04p Michaela
+# --Added $(AMICSPLib) dependency for exported SB CMOS
+# access functions
+# --Removed Tokens.ssp
+#
+# 12 1/08/09 12:54p Michaela
+# >removed COPY_INCLUDES target because CmosAccess32.inc and
+# CmosAccessSec.inc
+# are now in the INCLUDE directory
+#
+# 11 12/15/08 12:58p Michaela
+# Removed copying of CmosAccess32.inc and CmosAccessSec.inc
+#
+# 10 11/25/08 3:20p Michaela
+# Updates for Label 4.6.3_CMOSMGR_08
+# - Assembly macro fixes
+# - Added assembly macros
+# - Moved loading defaults into DXE phase
+# - Updated help file example
+#
+# 9 11/17/08 3:57p Michaela
+# --CMOS Buffer feature is depreciated
+# --Development debugging code is removed
+# --The DXE driver is invoked through the DXE INIT_LIST
+#
+# 8 11/14/08 9:32a Michaela
+# **CMOS Manager PEI phase is now linked to CORE_PEIBin and
+# the entry point is called via PeiCoreInitialize INIT_LIST Elink
+# **CMOS_PORT_MAPPING Elink is pass to C source via
+# build environment variable.
+# **Added PeiCmosBoard.obj and CmosBoard.obj for PEI/DXE phase
+# board-specific access functions.
+# **AFTER_ROM target modified to search for
+# CMOS_MANAGER_API string in CORE_PEI FFS and update
+# the pointer in Startup.FFS
+#
+# 7 11/07/08 5:14p Michaela
+# Updated to make CMOS manager available in all phases
+# of the boot process:
+#
+# A CMOS API Pointer is maintained in CMOS and accessible
+# via provided macros in C and assembly source.
+#
+# 6 3/25/08 3:06p Michaela
+# CmosManager.ssp is now forced to be the first file in the SSP file list
+#
+# 5 2/29/08 9:35p Michaela
+# - removed redundant source file in DXE
+#
+# 4 2/27/08 11:28a Michaela
+# Modified dependencies to prevent build errors under certain conditions
+#
+# 3 2/26/08 12:51p Michaela
+# Fixed build dependency issues
+#
+# 2 2/22/08 3:21p Olegi
+# Added GENERATE_CMOS_TOKENS target.
+#
+# 1 2/22/08 2:29p Michaela
+#
+# 1 2/04/08 6:00p MichaelA $
+# Created
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+#
+# Name: CmosManager.mak
+#
+# Description:
+# This is a make file used to build the CMOS manager component
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+
+#<AMI_GHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: Entry_Functions
+#
+# Description:
+# This page provides links to descriptions of the PEI and DXE phase
+# entrypoint functions for the CMOS Manager module.
+#
+# Fields: Phase Entrypoint Description
+# ------------------------------------------------------------------
+# PEI CmosManagerPeiEntry Main PEI phase entry point
+# PEI CmosManagerAfterMemoryEntry PEI after memory detection entry point
+# DXE CmosManagerDxeEntry Main DXE phase entry point
+# DXE CmosManagerSmmEntry Entry into SMM (Runtime) CMOS access support driver
+#
+#----------------------------------------------------------------------------
+#<AMI_GHDR_END>
+
+!INCLUDE $(BUILD_DIR)\timestamp.mak
+
+PREPARE : GENERATE_CMOS_TOKENS
+
+CMOS_MANAGER_COMPONENTS=\
+ CMOS_MANAGER_PEI \
+ CMOS_MANAGER_DXE \
+!IF $(CMOS_SMM_SUPPORT)
+ CMOS_MANAGER_SMM \
+!ENDIF
+
+
+all : $(CMOS_MANAGER_COMPONENTS)
+
+
+
+#---------------------------------------------------------------------------
+# Shared module make file dependencies
+#---------------------------------------------------------------------------
+
+CMOS_MANAGER_MAK_DEPS = \
+ $(CMOS_MANAGER_DIR)\CmosManager.mak
+
+
+
+#----------------------------------------------------------------------------
+# Generate SSP output files in the build directory
+#----------------------------------------------------------------------------
+#
+# DEFAULT SETUP APPEARANCE AND ORDER
+#
+# Template.ssp (Order of the SSP files is important)
+# |
+# +--CmosBoard.ssp
+# |
+# +--ADDON_SSPs (other Modules can add SSP files here and if they
+# : define a duplicate name with the same mask the
+# : duplicate name will override the one defined in
+# CmosBoard.ssp)
+#
+#
+# AmiSsp2.exe is only executed if an SSP file is modified or if a project
+# rebuild is invoked. (Note: modifying SDL forces a project rebuild.)
+#
+# * Client modules should place a dependency on the SspTokens.h
+# output files to ensure rebuild in the case CMOS Manager is
+# rebuilt.
+#
+#----------------------------------------------------------------------------
+
+SSP_FILE_LIST = $(SSP_FILE_LIST) \
+$(CMOS_MANAGER_DIR)\Template.ssp \
+$(CMOS_MANAGER_DIR)\CmosBoard.ssp \
+$(ADDON_SSP_FILES)
+
+UPDATE_PROJECT_LOG:
+ type << >> $(BUILD_DIR)\SSP.log
+ Project build: $(TODAY) @ $(NOW)
+<<
+
+SSP_FILES = $(**:\=\\)
+$(BUILD_DIR)\SSP.log: $(SSP_FILE_LIST)
+ type << > $(BUILD_DIR)\SspFileList.txt
+include "$(SSP_FILES: ="^
+include ")"
+<<
+ @$(SSP) $(BUILD_DIR)\ -s2 -efi $(BUILD_DIR)\SspFileList.txt
+!IF EXIST($(BUILD_DIR)\$(CMOS_MANAGER_DIR))
+ -del /S /Q $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\* > NUL
+!ENDIF
+ type << >> $(BUILD_DIR)\SSP.log
+CMOS Manager build: $(TODAY) @ $(NOW)
+<<
+
+GENERATE_CMOS_TOKENS: $(BUILD_DIR)\SSP.log UPDATE_PROJECT_LOG
+
+
+#---------------------------------------------------------------------------
+# CMOS Manager SEC object component
+#---------------------------------------------------------------------------
+CMOSMGR_SEC_ASM_FLAGS = /c /nologo /Sa /I$(CMOS_MANAGER_DIR) \
+ /Fl$(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SEC\ \
+!if "$(SEC_CREATE_PE32)" == "1"
+ /coff
+!endif
+
+$(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SEC\CmosManagerSec.obj : $(CMOS_MANAGER_DIR)\CmosManagerSec.asm
+!IF !EXIST($(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SEC)
+ mkdir $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SEC
+!ENDIF
+ $(ASM) $(CMOSMGR_SEC_ASM_FLAGS) /Fo$(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SEC\ $(CMOS_MANAGER_DIR)\CmosManagerSec.asm
+
+
+
+#---------------------------------------------------------------------------
+# CMOS Manager PEI library component
+#---------------------------------------------------------------------------
+
+CMOS_MANAGER_PEI : $(BUILD_DIR)\CmosManagerPei.mak CmosManagerPeiBin
+
+CORE_PEIBin : $(BUILD_DIR)\CmosManagerPei.lib
+
+$(BUILD_DIR)\CmosManagerPei.lib : CMOS_MANAGER_PEI
+
+$(BUILD_DIR)\CmosManagerPei.mak : $(CMOS_MANAGER_MAK_DEPS) $(BUILD_RULES)
+!IF !EXIST($(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI)
+ mkdir $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI
+!ENDIF
+ $(CIF2MAK) $(CMOS_MANAGER_DIR)\CmosManager.cif $(CIF2MAK_DEFAULTS)
+
+CMOS_PEI_CFLAGS = \
+ $(CFLAGS) \
+ $(CMOS_MGR_CFLAGS) \
+ /D\"CMOS_PORT_MAPPING=$(CMOS_PORT_MAPPING)\" \
+ /D\"CMOS_IS_BSP_MAPPING=$(CMOS_IS_BSP_MAPPING)\" \
+ /D\"CMOS_IS_FIRST_BOOT_MAPPING=$(CMOS_IS_FIRST_BOOT_MAPPING)\" \
+ /D\"CMOS_BATTERY_TEST_MAPPING=$(CMOS_BATTERY_TEST_MAPPING)\" \
+ /D\"CMOS_IS_USABLE_MAPPING=$(CMOS_IS_USABLE_MAPPING)\" \
+ /D\"CMOS_IS_COLD_BOOT_MAPPING=$(CMOS_IS_COLD_BOOT_MAPPING)\" \
+ /DPEI_COMPILE
+
+
+{$(PROJECT_DIR)\Core\EM\CmosManager}.c{$(BUILD_DIR)\Core\EM\CmosManager\Pei}.obj::
+ $(CC) $(CMOS_PEI_CFLAGS) /Fo$(BUILD_DIR)\Core\EM\CmosManager\Pei\ $<
+
+CMOS_MANAGER_PEI_OBJECTS = \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI\CmosTables.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI\CmosAccess.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI\CmosBoard.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI\CmosManager.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI\CmosManagerHob.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\PEI\CmosManagerPei.obj
+
+CmosManagerPeiBin : $(AMIPEILIB) $(AMICSPLib) $(CMOS_MANAGER_PEI_OBJECTS)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\CmosManagerPei.mak all \
+ NAME=CmosManagerPei \
+ "OBJECTS=" \
+ "CFLAGS=$(CMOS_PEI_CFLAGS)" \
+ TYPE=PEI_LIBRARY \
+ LIBRARY_NAME=$(BUILD_DIR)\CmosManagerPei.lib
+
+
+
+#---------------------------------------------------------------------------
+# CMOS Manager DXE library component
+#---------------------------------------------------------------------------
+
+CMOS_MANAGER_DXE: $(BUILD_DIR)\CmosManagerDxe.mak CmosManagerDxeBin
+
+CORE_DXEBin : $(BUILD_DIR)\CmosManagerDxe.lib
+
+$(BUILD_DIR)\CmosManagerDxe.lib : CMOS_MANAGER_DXE
+
+$(BUILD_DIR)\CmosManagerDxe.mak : $(CMOS_MANAGER_MAK_DEPS) $(BUILD_RULES)
+!IF !EXIST($(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE)
+ mkdir $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE
+!ENDIF
+ $(CIF2MAK) $(CMOS_MANAGER_DIR)\CmosManager.cif $(CIF2MAK_DEFAULTS)
+
+CMOS_DXE_CFLAGS = \
+ $(CFLAGS) \
+ $(CMOS_MGR_CFLAGS) \
+ /D\"CMOS_PORT_MAPPING=$(CMOS_PORT_MAPPING)\" \
+ /D\"CMOS_IS_BSP_MAPPING=$(CMOS_IS_BSP_MAPPING)\" \
+ /D\"CMOS_IS_FIRST_BOOT_MAPPING=$(CMOS_IS_FIRST_BOOT_MAPPING)\" \
+ /D\"CMOS_BATTERY_TEST_MAPPING=$(CMOS_BATTERY_TEST_MAPPING)\" \
+ /D\"CMOS_IS_USABLE_MAPPING=$(CMOS_IS_USABLE_MAPPING)\" \
+ /D\"CMOS_IS_COLD_BOOT_MAPPING=$(CMOS_IS_COLD_BOOT_MAPPING)\"
+
+{$(PROJECT_DIR)\Core\EM\CmosManager}.c{$(BUILD_DIR)\Core\EM\CmosManager\Dxe}.obj::
+ $(CC) $(CMOS_DXE_CFLAGS) /Fo$(BUILD_DIR)\Core\EM\CmosManager\Dxe\ $<
+
+CMOS_MANAGER_DXE_OBJECTS = \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosAccess.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosBoard.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosManager.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosManagerHob.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosManagerDxe.obj
+
+CmosManagerDxeBin : $(AMICSPLib) $(AMIDXELIB) $(CMOS_MANAGER_DXE_OBJECTS)
+ @set INCLUDE=%%INCLUDE%%
+ echo $(CMOS_PORT_MAPPING)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\CmosManagerDxe.mak all \
+ NAME=CmosManagerDxe \
+ "CFLAGS=$(CMOS_DXE_CFLAGS)" \
+ "OBJECTS=" \
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(BUILD_DIR)\CmosManagerDxe.lib \
+ LIBRARIES=\
+
+
+#---------------------------------------------------------------------------
+# CMOS Manager SMM DXE driver component
+#---------------------------------------------------------------------------
+
+
+CMOS_MANAGER_SMM: $(BUILD_DIR)\CmosManagerSmm.mak CmosManagerSmmBin
+
+$(BUILD_DIR)\CmosManagerSmm.mak : $(CMOS_MANAGER_MAK_DEPS) $(BUILD_RULES)
+!IF !EXIST($(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SMM)
+ mkdir $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SMM
+!ENDIF
+ $(CIF2MAK) $(CMOS_MANAGER_DIR)\CmosManager.cif $(CIF2MAK_DEFAULTS)
+
+CMOS_SMM_CFLAGS = \
+ $(CFLAGS) \
+ $(CMOS_MGR_CFLAGS) \
+ /D\"CMOS_PORT_MAPPING=$(CMOS_PORT_MAPPING)\" \
+ /D\"CMOS_IS_BSP_MAPPING=$(CMOS_IS_BSP_MAPPING)\" \
+ /D\"CMOS_IS_FIRST_BOOT_MAPPING=$(CMOS_IS_FIRST_BOOT_MAPPING)\" \
+ /D\"CMOS_BATTERY_TEST_MAPPING=$(CMOS_BATTERY_TEST_MAPPING)\"\
+ /D\"CMOS_IS_USABLE_MAPPING=$(CMOS_IS_USABLE_MAPPING)\" \
+ /D\"CMOS_IS_COLD_BOOT_MAPPING=$(CMOS_IS_COLD_BOOT_MAPPING)\" \
+ /DSMM_COMPILE
+
+{$(PROJECT_DIR)\Core\EM\CmosManager}.c{$(BUILD_DIR)\Core\EM\CmosManager\Smm}.obj::
+ $(CC) $(CMOS_SMM_CFLAGS) /Fo$(BUILD_DIR)\Core\EM\CmosManager\Smm\ $<
+
+# CmosAccess and CmosBoard are not SMM-buid dependent
+CMOS_MANAGER_SMM_OBJECTS = \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosAccess.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\DXE\CmosBoard.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SMM\CmosTables.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SMM\CmosManager.obj \
+ $(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SMM\CmosManagerSmm.obj
+
+CmosManagerSmmBin : $(AMICSPLib) $(AMIDXELIB) $(CMOS_MANAGER_SMM_OBJECTS)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\CmosManagerSmm.mak all \
+ GUID=6869C5B3-AC8D-4973-8B37-E354DBF34ADD\
+ NAME=CmosManagerSmm \
+ ENTRY_POINT=CmosManagerSmmEntry\
+ "OBJECTS=" \
+ "CFLAGS=$(CMOS_SMM_CFLAGS)" \
+ TYPE=BS_DRIVER \
+ DEPEX1=$(CMOS_MANAGER_DIR)\CmosManagerSmm.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+
+
+#---------------------------------------------------------------------------
+# CMOS Manager setup database build script
+#---------------------------------------------------------------------------
+
+!IF "$(CMOS_SETUP_SUPPORT)" == "1"
+
+SetupSdbs : $(BUILD_DIR)\CmosSetup.sdb
+
+$(BUILD_DIR)\CmosSetup.sdb : $(CMOS_MANAGER_DIR)\$(@B).sd $(CMOS_MANAGER_DIR)\$(@B).uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\$(@B).sdb $(CMOS_MANAGER_DIR)\$(@B).uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\$(@B).sdb -od $(BUILD_DIR)\$(@B).sdb $(CMOS_MANAGER_DIR)\$(@B).sd
+
+!ENDIF
+
+#---------------------------------------------------------------------------
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManager.sdl b/Core/EM/CmosManager/CmosManager.sdl
new file mode 100644
index 0000000..e346f42
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManager.sdl
@@ -0,0 +1,409 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CMOS Manager/CmosManager.sdl 5 12/11/11 8:51p Michaela $
+#
+# $Revision: 5 $
+#
+# $Date: 12/11/11 8:51p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CMOS Manager/CmosManager.sdl $
+#
+# 5 12/11/11 8:51p Michaela
+#
+# 4 11/30/11 11:45p Michaela
+# TAG] EIP56197
+# [Category] New Feature
+# [Severity] Normal
+# [Description] CMOS Manager Support in Runtime Code
+# [Files] CmosManager.sdl
+# CmosSetup.uni
+# CmosMessages.uni
+# CmosManagerSmm.cif
+# CmosAccess.h
+# CmosManagerSmm.c
+#
+# 3 3/16/11 2:46p Michaela
+#
+# 2 6/16/10 3:25p Michaela
+#
+# 1 6/15/10 2:27p Michaela
+#
+# 15 3/05/10 4:54p Michaela
+#
+# 14 12/04/09 7:32p Michaela
+#
+# 13 12/03/09 6:26p Michaela
+# 1. CMOS_PEI_BEFORE_NVRAM_PEI token is added to control whether
+# or not CMOS PEI code executes before NVRAM PEI
+# code. (default is off)
+#
+# 2. If DEBUG_MODE is on, INIT_LIST ordering is changed
+# so that Status Codes initialization is done
+# before CMOS code.
+#
+# 3. CMOS_IS_COLD_BOOT_MAPPING eLink added to allow
+# overriding of the default cold boot detection
+# code.
+#
+# 12 11/12/09 6:04p Michaela
+# Updated destination for SEC object code
+#
+# 11 11/10/09 9:13p Michaela
+#
+# 10 7/29/09 9:57a Michaela
+# updates Aptio Enhancement EIP 22205
+# (no code changes)
+#
+# 9 6/02/09 3:27p Michaela
+# For label: 4.6.3_CMOSMGR_11
+#
+# 8 2/23/09 6:01p Michaela
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+#
+# Name: CmosManager.sdl
+#
+# Description: This AMI SDL file defines porting constants used in
+# the CMOS Manager module. Please see CmosBoard.sdl for
+# SDL Tokens/eLinks that are expected to be cloned/added
+# for project-level porting.
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_MANAGER_SUPPORT
+#
+# Description:
+# This token is the main switch to enable CMOS manager support in Project
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_RTC_STATUS_REGISTER
+#
+# Description:
+#
+# Default value is 0xd
+#
+# This is the RTC status register. Bit 7 is the battery status.
+# (Do not set the NMI bit as this is a policy to be implmeneted by
+# the ReadWrite function.)
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_DIAGNOSTIC_STATUS_REGISTER
+#
+# Description:
+#
+# Default value is 0xe
+#
+# This is the diagnostic status register. (Do not set the NMI bit as
+# this is a policy to be implmeneted by the ReadWrite function.)
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: CMOS_ACCESS_API_BYTE3
+#
+# Description:
+#
+# Default value is 0x42
+#
+# The high byte of the CMOS Access API pointer registers.
+# 1) These registers are in range: 0x10-0x7f.
+# 2) If you change this token, you must modify CmosManager.ssp.
+# 3) Do not set the NMI bit as this is a policy to be
+# implemented by the ReadWrite function.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: SSP
+#
+# Description:
+#
+# Default value is AMISSP2.exe
+#
+# Defines the location of AmiSsp2.exe, which is used to generate
+# the header files containing CMOS information.
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+#<AMI_SHDR_START>
+#----------------------------------------------------------------------------
+#
+# Name: ADDON_SSP_FILES
+#
+# Description:
+#
+# There are no default eLinks
+#
+# This eLink is used to update the list of CMOS Token definition files
+# to be processed by AmiSsp2.exe during the build process.
+#
+# For example, the following eLink will add AgesaCmosTokens.ssp to the
+# list of CMOS Token definition files:
+#
+# ELINK
+# Name = "$(AGESA_EFI_DIR)\AgesaCmosTokens.ssp"
+# Parent = "ADDON_SSP_FILES"
+# InvokeOrder = AfterParent
+# End
+#
+#----------------------------------------------------------------------------
+#<AMI_SHDR_END>
+
+TOKEN
+ Name = "CMOS_MANAGER_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CMOS manager support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CMOS_MANAGER_SOURCE_VERSION"
+ Value = "40"
+ Help = "This source version number will increase with each release of CMOS Manager."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CMOS_RTC_STATUS_REGISTER"
+ Value = "0xd"
+ Help = "This is the Battery status register. (Do not set NMI bit)."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_DIAGNOSTIC_STATUS_REGISTER"
+ Value = "0xe"
+ Help = "This is the diagnostic status register. (Do not set NMI bit)."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CMOS_ACCESS_API_BYTE3"
+ Value = "0x42"
+ Help = "The high byte of the CMOS Access API pointer registers.\1) These registers are in range: 0x10-0x7f. \2) Do not set the NMI bit.\3) If you change this token, you must modify CmosManager.ssp."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SSP"
+ Value = "AMISSP2.exe"
+ Help = "Setup Script Processor executable"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SRSI"
+ Value = "$(SW_SMI_IO_ADDRESS)"
+ TokenType = Integer
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "CSMI"
+ Value = "0x61"
+ TokenType = Integer
+ TargetH = Yes
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "CMOS_MANAGER_ASL_SUPPORT"
+ Value = "0"
+ Help = "Enable ASL support for CMOS Manager as \CMOS device"
+ TokenType = Boolean
+ TargetMak = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "CMOS_MANAGER_DIR"
+ Path = "Core\EM\CmosManager"
+End
+
+MODULE
+ Help = "Includes CmosManager.mak to Project"
+ File = "CmosManager.mak"
+End
+
+ELINK
+ Name = "$(CMOS_MANAGER_DIR)\CmosAccess.asl"
+ Parent = "GENERIC_ASL"
+ Help = "ASL code for using CMOS Manager services in ASL code"
+ InvokeOrder = AfterParent
+ Token = "CMOS_MANAGER_ASL_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\$(CMOS_MANAGER_DIR)\SEC\CmosManagerSec.OBJ"
+ Parent = "ADDON_SEC_CORE_OBJ_FILES"
+ Priority = 0
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosManagerPeiEntry,"
+ Parent = "PeiCoreInitialize"
+ Help = "This simply adds the CMOS PEI entry to the PeiCoreInitialize Init list."
+ InvokeOrder = AfterParent
+ Token = "DEBUG_MODE" "=" "0"
+End
+
+ELINK
+ Name = "CmosManagerPeiEntry,"
+ Parent = "PeiInitStatusCode,"
+ Help = "This forces CMOS PEI after status codes PEI code so that CMOS Manager console messages can be displayed."
+ InvokeOrder = AfterParent
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+ELINK
+ Name = "CmosManagerAfterMemoryEntry,"
+ Parent = "PeiCoreMemoryInstalled"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CmosManagerDxeEntry,"
+ Parent = "DxeCoreInitialize"
+ Help = "This simply adds the CMOS DXE entry point to the DxeCoreInitialize Init list."
+ InvokeOrder = AfterParent
+ Token = "DEBUG_MODE" "=" "0"
+End
+
+ELINK
+ Name = "CmosManagerDxeEntry,"
+ Parent = "DxeInitStatusCode,"
+ Help = "This forces CMOS DXE after status codes DXE code so that CMOS Manager console messages can be displayed."
+ InvokeOrder = AfterParent
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+ELINK
+ Name = "SEC_CmosManager"
+ Parent = "SECCoreAtPowerOn"
+ Help = "CMOS Early Init in SEC (before Cache as memory enabling)"
+ SrcFile = "Core\Em\CmosManager\CmosManagerSec.asm"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ADDON_SSP_FILES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CmosManagerSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SMM_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "CMOS_MGR_CFLAGS"
+ Help = "CMOS Manager command line options of the C compiler"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CMOS_PORT_MAPPING"
+ Help = "Associate a CMOS address range with an \8-bit index/data port pair or a board-specific access function:\\{Index, Data, Low, High, FunctionName},\\This function is typicall provided by the Southbridge for CMOS addresses above 0x7f."
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CMOS_BATTERY_TEST_MAPPING"
+ Help = "Returns BOOLEAN (TRUE=1, FALSE=0) value specifying whether or not the battery is good. This function is implemented by CMOS Manager but can be overriden, typically by the Southbridge."
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CMOS_IS_FIRST_BOOT_MAPPING"
+ Help = "Returns BOOLEAN (TRUE=1, FALSE=0) value specifying whether or not the this is the first boot. This function is implemented by CMOS Manager but can be overriden, typically by the Southbridge."
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CMOS_IS_BSP_MAPPING"
+ Help = "Returns BOOLEAN (TRUE=1, FALSE=0) value specifying whether or not BSP is currently executing. This function is implemented by CMOS Manager but can be overriden by another module."
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CMOS_IS_COLD_BOOT_MAPPING"
+ Help = "Returns BOOLEAN (TRUE=1, FALSE=0) value specifying whether or not the platform is currently executing a cold boot. This function is implemented by CMOS Manager but can be overriden by another module."
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CMOS_IS_USABLE_MAPPING"
+ Help = "Returns BOOLEAN (TRUE=1, FALSE=0) value specifying whether or not the CMOS hardware is usable. This function is implemented by CMOS Manager but can be overriden by another module."
+ InvokeOrder = ReplaceParent
+End
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerBoard.cif b/Core/EM/CmosManager/CmosManagerBoard.cif
new file mode 100644
index 0000000..0f22848
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerBoard.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "CMOS Board"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosBoard"
+[files]
+"CmosBoard.sdl"
+"CmosBoard.ssp"
+"CmosBoard.c"
+"CmosBoard.h"
+"CmosSetup.sd"
+"CmosSetup.uni"
+[parts]
+"CmosMessages"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerBuild.cif b/Core/EM/CmosManager/CmosManagerBuild.cif
new file mode 100644
index 0000000..957fbe1
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerBuild.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CMOS Build"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosBuild"
+[files]
+"CmosManager.mak"
+"Template.ssp"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerCore.cif b/Core/EM/CmosManager/CmosManagerCore.cif
new file mode 100644
index 0000000..85aaca5
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerCore.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "CMOS Core"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosCore"
+[files]
+[parts]
+"CmosInterfaces"
+"CmosSource"
+"CmosIncludes"
+"CmosBuild"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerDxe.c b/Core/EM/CmosManager/CmosManagerDxe.c
new file mode 100644
index 0000000..8f4c608
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerDxe.c
@@ -0,0 +1,456 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS DXE/CmosManagerDxe.c 16 6/15/10 2:24p Michaela $
+//
+// $Revision: 16 $
+//
+// $Date: 6/15/10 2:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS DXE/CmosManagerDxe.c $
+//
+// 16 6/15/10 2:24p Michaela
+//
+// 15 3/05/10 4:54p Michaela
+//
+// 14 12/04/09 7:31p Michaela
+//
+// 13 12/03/09 6:22p Michaela
+// 1. CMOS_DISCONTINUE_OPTIMAL_DEFAULTS is replace with
+// CMOS_OPTIMAL_DEFAULTS_OFF.
+//
+// 2. Loading of Optimal Defaults depends only on
+// wether or not the buffer is enabled.
+//
+// 12 11/10/09 9:13p Michaela
+//
+// 11 7/29/09 9:56a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 10 6/15/09 5:11p Michaela
+//
+// 9 6/02/09 3:26p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 8 3/11/09 3:39p Michaela
+//
+// 7 11/25/08 3:15p Michaela
+// Updates for Label 4.6.3_CMOSMGR_08
+// - Assembly macro fixes
+// - Added assembly macros
+// - Moved loading defaults into DXE phase
+// - Updated help file example
+//
+// 6 11/17/08 4:05p Michaela
+// --Removed development debugging code
+//
+// 5 11/07/08 5:15p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 4 3/07/08 4:05p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 3 2/29/08 9:33p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 2 2/26/08 12:52p Michaela
+// Added/modified Helpbuilder headers
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerDxe.c
+//
+// Description: Contains the routines that constitute the CMOS manager's
+// DXE phase entry.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CmosManagerDxe.h"
+#include <Protocol\Reset.h>
+#include <Setup.h>
+
+static EFI_EVENT gSetupEnterEvent;
+static EFI_EVENT gBootEvent;
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ClearCmosBasedStatus
+//
+// Description:
+// This function uses the CMOS Manager interface to clear the un-managed
+// private status bits upon boot or setup entry.
+//
+// Input:
+// IN EFI_EVENT Event
+// - Event handle
+// IN VOID *Context
+// - Not used
+//
+// Output:
+// None
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ClearCmosBasedStatus(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_CMOS_ACCESS_INTERFACE *Cmos;
+ EFI_STATUS Status;
+ CMOS_STATUS_BYTES CmosInfo;
+ BOOLEAN Usable;
+
+ LOCATE_CMOS_ACCESS_PROTOCOL(Status, Cmos);
+
+ if ( !EFI_ERROR(Status) ){
+
+ // get CMOS-based info
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "Clear CMOS-based status values.\n" ));
+
+ Cmos->ReadCmosStatusBytes(Cmos, &CmosInfo);
+ Usable = CmosInfo.ConfigurationStatus.NotUsable == 1 ? FALSE : TRUE;
+
+ // clear status values for next boot
+
+ if ( Usable ){
+ Cmos->Write(Cmos, CMOS_MGR_BATTERY_BAD, 0);
+ Cmos->Write(Cmos, CMOS_MGR_CHECKSUM_BAD, 0);
+ Cmos->Write(Cmos, CMOS_MGR_DEFAULTS_LOADED, 0);
+ Cmos->Write(Cmos, CMOS_MGR_FIRST_BOOT_DETECTED, 0);
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "...Done\n" ));
+ }
+
+ }
+ else
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "ClearCmosBasedStatus...Failed\n" ));
+
+
+ // This function only needs to be called one time to
+ // get proper updates in setup and to clear the CMOS values.
+
+#if CMOS_SETUP_SUPPORT
+ pBS->CloseEvent(gSetupEnterEvent);
+#endif
+ pBS->CloseEvent(gBootEvent);
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdateCmosSetupVariable
+//
+// Description:
+// This function updates the CMOS setup variable using information
+// from the CMOS-based status bits.
+//
+// Input:
+// IN EFI_EVENT Event
+// - Event handle
+// IN VOID *Context
+// - Not used
+//
+// Output:
+// None
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if CMOS_SETUP_SUPPORT
+VOID UpdateCmosSetupVariable(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_CMOS_ACCESS_INTERFACE *Cmos;
+ EFI_STATUS Status;
+ CMOS_STATUS_BYTES CmosInfo;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ UINTN VariableSize = sizeof(SETUP_DATA);
+ UINT32 Attributes;
+ SETUP_DATA Sd;
+ EFI_GUID CmosGuid = EFI_DXE_CMOS_ACCESS_GUID;
+ BOOLEAN NotUsable;
+ BOOLEAN BadBattery;
+ BOOLEAN DefaultsLoaded;
+ BOOLEAN FirstBoot;
+ BOOLEAN BadChecksum;
+
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Locate CMOS Manager interface...\n" ));
+ Status = pBS->LocateProtocol( &CmosGuid, NULL, &Cmos);
+ if (!EFI_ERROR (Status)) {
+ Status = Cmos->ReadCmosStatusBytes(Cmos, &CmosInfo);
+ if (EFI_ERROR(Status)){
+ ASSERT_EFI_ERROR(EFI_NOT_FOUND);
+ return;
+ }
+ NotUsable = (BOOLEAN)CmosInfo.ConfigurationStatus.NotUsable;
+ }
+ else {
+ ASSERT_EFI_ERROR(Status);
+ return;
+ }
+
+ // update setup data
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "Updating setup data.\n" ));
+ Status = pRS->GetVariable( L"Setup", &SetupGuid, &Attributes,
+ &VariableSize, &Sd );
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "Could not locate Setup variable.\n" ));
+ }
+ else {
+ if ( NotUsable ) {
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ " Status: Cannot use CMOS-based status\n"));
+ Sd.CmosBatteryIsBad = CmosInfo.Battery.Field.IsGood == 0 ?
+ TRUE : FALSE;
+ Sd.CmosNotUsable = TRUE;
+ }
+ else {
+ Cmos->Read(Cmos, CMOS_MGR_BATTERY_BAD, &BadBattery);
+ Cmos->Read(Cmos, CMOS_MGR_CHECKSUM_BAD, &BadChecksum);
+ Cmos->Read(Cmos, CMOS_MGR_DEFAULTS_LOADED, &DefaultsLoaded);
+ Cmos->Read(Cmos, CMOS_MGR_FIRST_BOOT_DETECTED, &FirstBoot);
+
+ Sd.CmosDefaultsLoaded = DefaultsLoaded;
+ Sd.CmosFirstBootDetected = FirstBoot;
+ Sd.CmosBatteryIsBad = BadBattery;
+ Sd.CmosCheckSumIsBad = BadChecksum;
+ Sd.CmosNotUsable = FALSE;
+ }
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ " Status: DefaultsLoaded=%X, FirstBoot=%X, BatteryBad=%X\n",
+ Sd.CmosDefaultsLoaded, Sd.CmosFirstBootDetected,
+ Sd.CmosBatteryIsBad ));
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ " BadChecksum=%X, CmosNotUsable=%X\n",
+ Sd.CmosCheckSumIsBad, Sd.CmosNotUsable ));
+ Status = pRS->SetVariable( L"Setup", &SetupGuid, Attributes,
+ VariableSize, &Sd );
+ }
+
+ // Clear the CMOS-based status bits after updating the setup variable
+
+ ClearCmosBasedStatus(Event, Context);
+
+ return;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateEventHandlers
+//
+// Description:
+// This function creates a callback on the setup entry event and boot
+// event to (respectively) update the CMOS setup variable and clear
+// the CMOS-based status bits.
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+// Notes:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CreateEventHandlers( VOID )
+{
+ EFI_STATUS Status;
+
+#if CMOS_SETUP_SUPPORT
+ EFI_GUID SetupEnterProtocolGuid = AMITSE_SETUP_ENTER_GUID;
+ VOID *Registration;
+
+ Status = RegisterProtocolCallback( &SetupEnterProtocolGuid,
+ UpdateCmosSetupVariable, NULL, &gSetupEnterEvent, &Registration );
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ Status = CreateReadyToBootEvent( TPL_CALLBACK, ClearCmosBasedStatus, NULL,
+ &gBootEvent );
+ ASSERT_EFI_ERROR(Status);
+
+
+}
+
+//---------------------------------------------------------------------------
+// DXE entry point function
+//
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerDxeEntry
+//
+// Description:
+// This function is the main DXE phase entry point for the CMOS
+// manager module.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable
+// - System table pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// * Initializes/Installs the EFI_CMOS_ACCESS_INTERFACE
+// Protocol.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosManagerDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_CMOS_MANAGER_INTERFACE *Mgr;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CmosManagerDXE Entry\n" ));
+
+ //-----------------------------------------------------------------------
+ // Initialize the manager interface and, at this point, only check for
+ // interface initialization errors.
+ //-----------------------------------------------------------------------
+
+ Mgr = NewCmosManagerInterface(NULL);
+ if ( Mgr == NULL || !Mgr->CheckStatus(Mgr, CMOS_VALID_INTERFACE) ) {
+ return Status = EFI_UNSUPPORTED;
+ }
+ if ( Mgr->CheckStatus( Mgr, CMOS_INTERFACE_ALREADY_INSTALLED) )
+ return Status = EFI_SUCCESS;
+
+
+ //-----------------------------------------------------------------------
+ // Handle specific reported errors.
+ //
+ // If there is a bad battery, continue using the Optimal Defaults Table.
+ //
+ // Otherwise, if there is a bad checksum or the Optimal Defaults table
+ // is in use from PEI, then flush the table to physical CMOS and
+ // discontinue its use.
+ //
+ // Note: the Optimal Defaults Table is enabled only in PEI
+ //-----------------------------------------------------------------------
+
+ if ( !Mgr->CheckStatus(Mgr, CMOS_IS_USABLE) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: CMOS_IS_USABLE = FALSE\n" ));
+
+ // Default handler is to continue using the Optimal Defaluts Table
+ // if the CMOS is unusable.
+ }
+ else if ( Mgr->CheckStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED) )
+ {
+#if (FULL_CMOS_MANAGER_DEBUG)
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: CMOS_OPTIMAL_DEFAULTS_ENABLED = TRUE\n" ));
+ if ( Mgr->CheckStatus(Mgr, CMOS_BAD_CHECKSUM) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: CMOS_BAD_CHECKSUM = TRUE\n" ));
+ }
+#endif
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: Calling LoadOptimalDefaults()\n" ));
+ Mgr->LoadOptimalDefaults(Mgr);
+ if ( Mgr->CheckStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: CMOS_OPTIMAL_DEFAULTS_OFF\n" ));
+ Mgr->ConfigureManager( Mgr, CMOS_OPTIMAL_DEFAULTS_OFF );
+ }
+ }
+
+
+ //-----------------------------------------------------------------------
+ // Create handlers for CMOS Manager
+ //-----------------------------------------------------------------------
+ CreateEventHandlers();
+
+ //-----------------------------------------------------------------------
+ // Install the CMOS Access interface
+ //-----------------------------------------------------------------------
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: Installing CMOS Access Protocol\n" ));
+ Mgr->InstallAccessInterface(Mgr);
+ if ( !Mgr->CheckStatus(Mgr, CMOS_VALID_MANAGER) ){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ "CmosManagerDXE: Invalid interface\n" ));
+ return Status = EFI_UNSUPPORTED;
+ }
+
+ return Status = EFI_SUCCESS;
+}
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerDxe.cif b/Core/EM/CmosManager/CmosManagerDxe.cif
new file mode 100644
index 0000000..e4d3d45
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerDxe.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CMOS DXE"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosDxe"
+[files]
+"CmosManagerDxe.c"
+"CmosManagerDxe.h"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerDxe.h b/Core/EM/CmosManager/CmosManagerDxe.h
new file mode 100644
index 0000000..aa9d03e
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerDxe.h
@@ -0,0 +1,74 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS DXE/CmosManagerDxe.h 3 7/29/09 9:56a Michaela $
+//
+// $Revision: 3 $
+//
+// $Date: 7/29/09 9:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS DXE/CmosManagerDxe.h $
+//
+// 3 7/29/09 9:56a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 2 6/15/09 5:11p Michaela
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerDxe.h
+//
+// Description: Contains declarations to support the CMOS Manager
+// in DXE phase.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _CMOS_MANAGER_DXE_H
+#define _CMOS_MANAGER_DXE_H
+
+#include <Efi.h>
+#include <AmiDxeLib.h>
+#include <SspData.h>
+#include <SspTokens.h>
+#include <CmosAccess.h>
+#include "CmosManager.h"
+
+#endif // #ifndef _CMOS_MANAGER_DXE_H
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerHob.c b/Core/EM/CmosManager/CmosManagerHob.c
new file mode 100644
index 0000000..c2d785c
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerHob.c
@@ -0,0 +1,429 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosManagerHob.c 13 6/15/10 2:24p Michaela $
+//
+// $Revision: 13 $
+//
+// $Date: 6/15/10 2:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosManagerHob.c $
+//
+// 13 6/15/10 2:24p Michaela
+//
+// 12 12/04/09 7:32p Michaela
+//
+// 11 12/03/09 6:43p Michaela
+// changed CmosManagerAfterMemoryEntry() to update
+// the PEI Services table earlier.
+//
+// 10 7/29/09 9:59a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 9 6/15/09 5:11p Michaela
+//
+// 8 6/02/09 3:27p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 7 11/17/08 3:42p Michaela
+// --Removed development debugging code
+// --ABORT_ERROR macro replaced with EFI_ERROR macro usage
+//
+// 6 11/07/08 5:13p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 5 3/07/08 4:07p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 4 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 3 2/26/08 12:49p Michaela
+// Added/modified Helpbuilder headers
+//
+// 2 2/22/08 5:08p Michaela
+// update EFI_PEI_SERVICES pointer on ppi callback
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerHob.c
+//
+// Description: Contains the routines that are used to access the
+// HOB data structure.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#ifdef PEI_COMPILE
+ #include <Pei.h>
+ #include <AmiPeiLib.h>
+#else
+ #include <AmiDxeLib.h>
+#endif
+#include "CmosManager.h"
+#include "CmosManagerHob.h"
+
+#ifdef PEI_COMPILE
+
+ //-----------------------------------------------------------------------
+ // Data originally defined in CmosTables.c
+ //-----------------------------------------------------------------------
+
+ extern CMOS_TOKEN gCmosTokenTable[];
+ extern UINT16 gCmosTokenTableSize;
+ extern CMOS_REGISTER gCmosOptimalDefaultTable[];
+ extern UINT16 gCmosOptimalDefaultTableSize;
+ extern CMOS_REGISTER gCmosNoCheckSumTable[];
+ extern UINT16 gCmosNoCheckSumTableSize;
+ extern CMOS_REGISTER gUnmanagedTable[];
+ extern UINT16 gUnmanagedTableSize;
+
+ EFI_GUID gCmosDataHobInstalledGuid =
+ EFI_CMOS_DATA_HOB_INSTALLED_GUID;
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosSynchronizeHobManagerStatus
+//
+// Description:
+// This function synchronizes the ManagerStatus information in
+// the CMOS data HOB to be passed to DXE.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager interface pointer
+//
+// Output:
+// VOID (Return value)
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef PEI_COMPILE
+VOID CmosSynchronizeHobManagerStatus(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager )
+{
+ if (Manager->ManagerHob != NULL)
+ Manager->ManagerHob->ManagerStatus = Manager->ManagerStatus;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosSynchronizeHobChecksum
+//
+// Description:
+// This function synchronizes the Checksum information in
+// the CMOS data HOB to be passed to DXE.
+//
+// Input:
+// OUT EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager->ManagerHob->CheckSum = Manager->CheckSum
+//
+// Output:
+// VOID (Return value)
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef PEI_COMPILE
+VOID CmosSynchronizeHobChecksum(
+ OUT EFI_CMOS_MANAGER_INTERFACE *Manager )
+{
+ if (Manager->ManagerHob != NULL)
+ Manager->ManagerHob->Checksum = Manager->Checksum;
+
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateCmosDataHob
+//
+// Description:
+// This function creates the CMOS data HOB, when memory is available.
+//
+// Input:
+// IN EFI_CMOS_MANAGER_INTERFACE *Manager
+// -- Manager interface pointer
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// This function is used only in PEI phase, included by the build
+// macro PEI_COMPILE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef PEI_COMPILE
+EFI_STATUS CreateCmosDataHob(
+ IN EFI_CMOS_MANAGER_INTERFACE *Manager )
+{
+ UINT16 TokenIndex = 0; // First valid token table index is 1
+ EFI_STATUS Status;
+ UINT16 HobSize = sizeof(CMOS_MANAGER_HOB);
+ EFI_GUID CmosManagerHobGuid = CMOS_MANAGER_HOB_GUID;
+ CMOS_MANAGER_HOB *CmosManagerHob;
+ DEFINE_PEI_SERVICES(Manager->Access.PeiServices);
+
+ Status = (*PeiServices)->CreateHob( PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ HobSize,
+ &CmosManagerHob);
+
+ CmosManagerHob->Header.Name = CmosManagerHobGuid;
+ CmosManagerHob->FirstManagedRegister = Manager->FirstManagedRegister;
+ CmosManagerHob->LastManagedRegister = Manager->LastManagedRegister;
+ CmosManagerHob->TokenCount = Manager->TokenCount;
+ CmosManagerHob->OptimalDefaultCount = Manager->OptimalDefaultCount;
+ CmosManagerHob->NoChecksumCount = Manager->NoChecksumCount;
+ CmosManagerHob->UnmanagedTableCount = Manager->UnmanagedTableCount;
+ CmosManagerHob->Checksum = Manager->Checksum;
+ CmosManagerHob->ManagerStatus = Manager->ManagerStatus;
+ Manager->ManagerHob = CmosManagerHob;
+
+ // Use a raw copy to initialize the tables in the HOB
+ // from global arrays
+
+ if ( EFI_ERROR(Status) )
+ return Status;
+ else {
+ MemCpy( CmosManagerHob->TokenTable,
+ Manager->TokenTable,
+ Manager->TokenCount * sizeof(CMOS_TOKEN)
+ );
+ MemCpy( CmosManagerHob->OptimalDefaultTable ,
+ Manager->OptimalDefaultTable,
+ Manager->OptimalDefaultCount * sizeof(CMOS_REGISTER)
+ );
+ MemCpy( CmosManagerHob->NoChecksumTable ,
+ Manager->NoChecksumTable,
+ Manager->NoChecksumCount * sizeof(CMOS_REGISTER)
+ );
+ MemCpy( CmosManagerHob->UnmanagedTable ,
+ Manager->UnmanagedTable,
+ Manager->UnmanagedTableCount * sizeof(CMOS_REGISTER)
+ );
+ }
+
+ //-----------------------------------------------------------------------
+ // The Manager will now use the HOB versions of the tables for
+ // faster access and to ensure proper updating of the optimal defaults
+ // buffer.
+ //-----------------------------------------------------------------------
+
+ Manager->TokenTable = CmosManagerHob->TokenTable;
+ Manager->OptimalDefaultTable = CmosManagerHob->OptimalDefaultTable;
+ Manager->NoChecksumTable = CmosManagerHob->NoChecksumTable;
+ Manager->UnmanagedTable = CmosManagerHob->UnmanagedTable;
+
+ //-----------------------------------------------------------------------
+ // Install a notification PPI to inform that the CMOS data HOB is
+ // installed.
+ //
+ // Note: The current routine is executed from within a notification,
+ // so any PPI waiting on the install notification PPI must
+ // use the EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK Flag.
+ //-----------------------------------------------------------------------
+
+ Manager->Ppi[CMOS_DATA_HOB_INSTALLED_PPI_TYPE].Flags =
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST;
+ Manager->Ppi[CMOS_DATA_HOB_INSTALLED_PPI_TYPE].Guid =
+ &gCmosDataHobInstalledGuid;
+ Manager->Ppi[CMOS_DATA_HOB_INSTALLED_PPI_TYPE].Ppi = NULL;
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices, &Manager->Ppi[CMOS_DATA_HOB_INSTALLED_PPI_TYPE]);
+
+ return Status;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerAfterMemoryEntry
+//
+// Description:
+// This function calls CreateCmosDataHob to create the DXE data HOB
+// after permanent memory has been installed, and updates the new CMOS
+// Access Interface Address, as well as the CMOS-based API pointer.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// -- EFI_FFS_FILE_HEADER pointer
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Services table pointer
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// This function is used only in PEI phase, included by the build
+// macro PEI_COMPILE.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifdef PEI_COMPILE
+EFI_STATUS CmosManagerAfterMemoryEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_CMOS_ACCESS_INTERFACE *Cmos;
+ EFI_CMOS_MANAGER_INTERFACE *Manager;
+
+ extern EFI_CMOS_MANAGER_INTERFACE *GetCmosMangerInterface(
+ IN EFI_CMOS_ACCESS_INTERFACE *Cmos );
+
+ LOCATE_CMOS_ACCESS_PPI(Status, Cmos); // get Manager's interface
+ if (EFI_ERROR(Status))
+ return Status;
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CmosManagerAfterMemoryEntry...\n" ));
+
+ Manager = GetCmosMangerInterface(Cmos);
+
+ // Update PeiServices first
+
+ Manager->Access.PeiServices = PeiServices;
+
+ // Update the API pointer in CMOS
+
+ Manager->SaveApiPointerToCmos(Manager, Cmos);
+
+ // Indicate that manager is now executing in memory
+
+ Manager->SetStatus(Manager, CMOS_EXECUTING_IN_MEMORY);
+
+ // Create the HOB
+
+ CreateCmosDataHob(Manager);
+
+ return Status;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeCmosDataTablesFromHob
+//
+// Description:
+// This function locates the HOB containing the table of CMOS tokens
+// and initializes token table information in the CMOS manager's
+// interface.
+//
+// Input:
+// OUT EFI_CMOS_MANAGER_INTERFACE *Manager
+// - The CMOS manager interface to initialize.
+//
+// Output:
+// EFI_STATUS (Return value)
+// = EFI_SUCCESS or valid EFI error code
+//
+// Notes:
+// This function is used only in DXE phase, included by the build
+// process via the absence of the macro PEI_COMPILE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#ifndef PEI_COMPILE
+EFI_STATUS InitializeCmosTablesFromHob(
+ OUT EFI_CMOS_MANAGER_INTERFACE *Manager )
+{
+ EFI_STATUS Status;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID CmosManagerHobGuid = CMOS_MANAGER_HOB_GUID;
+ CMOS_MANAGER_HOB *CmosManagerHob;
+
+ CmosManagerHob =
+ (CMOS_MANAGER_HOB*)GetEfiConfigurationTable(pST,&HobListGuid);
+ if ( CmosManagerHob == NULL )
+ return Status = EFI_UNSUPPORTED;
+
+ Status = FindNextHobByGuid( &CmosManagerHobGuid, (VOID**)&CmosManagerHob);
+ if (EFI_ERROR( Status ))
+ return Status;
+
+ Manager->ManagerHob = CmosManagerHob; // for completeness
+ Manager->FirstManagedRegister = CmosManagerHob->FirstManagedRegister;
+ Manager->LastManagedRegister = CmosManagerHob->LastManagedRegister;
+ Manager->TokenTable = CmosManagerHob->TokenTable;
+ Manager->TokenCount = CmosManagerHob->TokenCount;
+ Manager->OptimalDefaultTable = CmosManagerHob->OptimalDefaultTable;
+ Manager->OptimalDefaultCount = CmosManagerHob->OptimalDefaultCount;
+ Manager->NoChecksumTable = CmosManagerHob->NoChecksumTable;
+ Manager->NoChecksumCount = CmosManagerHob->NoChecksumCount;
+ Manager->UnmanagedTable = CmosManagerHob->UnmanagedTable;
+ Manager->UnmanagedTableCount = CmosManagerHob->UnmanagedTableCount;
+ Manager->Checksum = CmosManagerHob->Checksum;
+ Manager->ManagerStatus = CmosManagerHob->ManagerStatus;
+
+ return Status = EFI_SUCCESS;
+}
+#endif
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerHob.h b/Core/EM/CmosManager/CmosManagerHob.h
new file mode 100644
index 0000000..f460cc7
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerHob.h
@@ -0,0 +1,139 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Includes/CmosManagerHob.h 7 6/15/10 2:26p Michaela $
+//
+// $Revision: 7 $
+//
+// $Date: 6/15/10 2:26p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Includes/CmosManagerHob.h $
+//
+// 7 6/15/10 2:26p Michaela
+//
+// 6 7/29/09 10:00a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 5 6/15/09 5:11p Michaela
+//
+// 4 11/17/08 3:52p Michaela
+// --CMOS Buffer feature is depreciated
+//
+// 3 11/14/08 9:17a Michaela
+// **CMOS register variables are changed from UINT8 to UINT16
+//
+// 2 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/14/08 12:00p MichaelA
+// Created
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerHob.h
+//
+// Description: Contains declarations to support the CMOS Manager
+// CMOS_MANAGER_HOB.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _CMOS_MANAGER_HOB_H
+#define _CMOS_MANAGER_HOB_H
+
+#include <hob.h>
+#include <SspData.h>
+#include "CmosTypes.h"
+
+// Currently the manager's HOB size is calculated during the build process.
+
+// Cannot define arrays of size 0
+#if ((LAST_CMOS_REGISTER - FIRST_CMOS_REGISTER) < 1)
+ #define MANAGED_CMOS_SIZE 1
+#else
+ #define MANAGED_CMOS_SIZE LAST_CMOS_REGISTER - FIRST_CMOS_REGISTER + 2
+#endif
+
+#if (TOTAL_CMOS_TOKENS < 1)
+ #define TOKEN_COUNT 1
+#else
+ #define TOKEN_COUNT TOTAL_CMOS_TOKENS + 1
+#endif
+
+#if (TOTAL_NOT_CHECKSUMMED < 1)
+ #define NO_CHECKSUM_COUNT 1
+#else
+ #define NO_CHECKSUM_COUNT TOTAL_NOT_CHECKSUMMED + 1
+#endif
+
+
+// CMOS_MANAGER_HOB GUID
+//--------------------------------------------------------------
+// {D5367802-B873-4c0f-B544-31B7CCF5C555}
+#define CMOS_MANAGER_HOB_GUID \
+{0xd5367802, 0xb873, 0x4c0f, 0xb5, 0x44, 0x31, 0xb7, 0xcc, 0xf5, 0xc5, 0x55}
+
+
+// PPI notification that CMOS_MANAGER_HOB is installed
+//--------------------------------------------------------------
+// {5A6A93F4-2907-4a34-BD11-6CA8A0959E09}
+#define EFI_CMOS_DATA_HOB_INSTALLED_GUID \
+{ 0x5a6a93f4, 0x2907, 0x4a34, 0xbd, 0x11, 0x6c, 0xa8, 0xa0, 0x95, 0x9e, 0x9 }
+
+
+// Table indexes - For all tables, the first valid index is 1
+//
+// OptimalDefaultTable - OptimalDefaultTable[1] = FIRST_CMOS_REGISTER
+//
+typedef struct _CMOS_MANAGER_HOB {
+ EFI_HOB_GUID_TYPE Header;
+ CMOS_MANAGER_STATUS ManagerStatus;
+ CMOS_CHECKSUM Checksum;
+ UINT16 FirstManagedRegister;
+ UINT16 LastManagedRegister;
+ UINT16 TokenCount;
+ CMOS_TOKEN TokenTable[TOKEN_COUNT]; // NULL at index 0
+ UINT16 OptimalDefaultCount;
+ CMOS_REGISTER OptimalDefaultTable[MANAGED_CMOS_SIZE];
+ UINT16 NoChecksumCount;
+ CMOS_REGISTER NoChecksumTable[NO_CHECKSUM_COUNT];
+ UINT16 UnmanagedTableCount;
+ CMOS_REGISTER UnmanagedTable[TOKEN_COUNT]; // DEBUG change when AmiSsp2.exe is updated
+} CMOS_MANAGER_HOB;
+
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerIncludes.cif b/Core/EM/CmosManager/CmosManagerIncludes.cif
new file mode 100644
index 0000000..2264ff0
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerIncludes.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "CMOS Includes"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosIncludes"
+[files]
+"CmosManager.h"
+"CmosManagerHob.h"
+"CmosTypes.h"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerMessages.cif b/Core/EM/CmosManager/CmosManagerMessages.cif
new file mode 100644
index 0000000..6b119c1
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerMessages.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "CMOS Messages"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosMessages"
+[files]
+"CmosMessages.sdl"
+"CmosMessages.mak"
+"CmosMessages.c"
+"CmosMessages.uni"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerPei.c b/Core/EM/CmosManager/CmosManagerPei.c
new file mode 100644
index 0000000..3cc9458
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerPei.c
@@ -0,0 +1,264 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS PEI/CmosManagerPei.c 17 6/15/10 2:23p Michaela $
+//
+// $Revision: 17 $
+//
+// $Date: 6/15/10 2:23p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS PEI/CmosManagerPei.c $
+//
+// 17 6/15/10 2:23p Michaela
+//
+// 16 3/05/10 4:53p Michaela
+//
+// 15 12/04/09 7:30p Michaela
+//
+// 14 12/03/09 6:19p Michaela
+// 1. CMOS_BSP_IS_EXECUTING status bit
+// is used instead of gIsBsp
+//
+// 2. Loading of Optimal Defaults on bad checksum
+// is done earlier by default and is enabled/disabled
+// by CMOS_RECOVER_IN_PEI SDL token.
+//
+// Note: the bad checksum bit is not cleared until DXE.
+//
+// 3. The CMOS_USE_OPTIMAL_DEFAULTS enum is replaced with
+// CMOS_OPTIMAL_DEFAULTS_ON.
+//
+// 13 11/10/09 9:13p Michaela
+//
+// 12 7/29/09 9:56a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 11 6/15/09 5:10p Michaela
+//
+// 10 6/02/09 4:38p Michaela
+//
+// 9 6/02/09 3:26p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 8 3/11/09 3:37p Michaela
+//
+// 7 11/25/08 3:15p Michaela
+// Updates for Label 4.6.3_CMOSMGR_08
+// - Assembly macro fixes
+// - Added assembly macros
+// - Moved loading defaults into DXE phase
+// - Updated help file example
+//
+// 6 11/17/08 4:03p Michaela
+// --Removed development degugging code
+//
+// 5 11/07/08 5:14p Michaela
+// Updated to make CMOS manager available in all phases
+// of the boot process:
+//
+// A CMOS API Pointer is maintained in CMOS and accessible
+// via provided macros in C and assembly source.
+//
+// 4 3/07/08 4:06p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 3 2/29/08 9:33p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 2 2/26/08 12:52p Michaela
+// Added/modified Helpbuilder headers
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerPei.c
+//
+// Description: Contains the routines that constitute the CMOS manager's
+// PEI phase entry.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Token.h>
+#include "CmosManagerPei.h"
+
+#define LOCATE_READ_ONLY_VARIABLE_PPI(Status, InterfacePtr) { \
+ EFI_GUID Guid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID; \
+ Status = (*PeiServices)->LocatePpi( PeiServices, &Guid, \
+ 0, NULL, &InterfacePtr); }
+
+
+//---------------------------------------------------------------------------
+// PEI entry point function
+//
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerPeiEntry
+//
+// Description:
+// This function is the main PEI phase entry point for the CMOS
+// manager module.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// -- FFS file header pointer
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Services table pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// Execution Sequence:
+// 1) Initialize CMOS Manager interface
+// 2) Load default values into CMOS registers if
+// this is the first boot.
+// 3) Configure usage of the Optimal Defaults table if
+// the battery or checksum is bad.
+// 4) Update the CMOS-based API/PPI pointer.
+// 5) Install the EFI_CMOS_ACCESS_INTERFACE PPI
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosManagerPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ EFI_CMOS_MANAGER_INTERFACE *Mgr;
+ UINT8 CmosValue = 0;
+
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CmosManagerPeiEntry Entry\n" ));
+
+ //-----------------------------------------------------------------------
+ // Initialize the manager interface and, at this point, only check for
+ // interface initialization errors.
+ //-----------------------------------------------------------------------
+
+ Mgr = NewCmosManagerInterface(PeiServices);
+ if ( Mgr == NULL || !Mgr->CheckStatus(Mgr, CMOS_VALID_INTERFACE) )
+ return Status = EFI_UNSUPPORTED;
+ if ( Mgr->CheckStatus( Mgr, CMOS_INTERFACE_ALREADY_INSTALLED) )
+ return Status = EFI_SUCCESS;
+
+ //-----------------------------------------------------------------------
+ // Handle specific internally-reported conditions.
+ //-----------------------------------------------------------------------
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_IS_USABLE )
+ && Mgr->CheckStatus(Mgr, CMOS_BSP_IS_EXECUTING ) )
+ {
+ // Load optimal defaults on first boot after programming
+ // boot device.
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_FIRST_BOOT_DETECTED )
+ && Mgr->CheckStatus(Mgr, CMOS_COLD_BOOT_DETECTED ) )
+ {
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "First boot detected ...\n" ));
+ Mgr->LoadOptimalDefaults(Mgr);
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "...Defaults loaded\n" ));
+ }
+
+ // Save CMOS-based PPI pointer
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Saving PPI pointer to CMOS\n" ));
+ Mgr->SaveApiPointerToCmos(Mgr, NULL);
+ }
+ else {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Defaults were not loaded\n" ));
+ }
+
+ //-----------------------------------------------------------------------
+ // If the CMOS hardware is not usable, configure CMOS Manager to use the
+ // read/write Optimal Defaults buffer for Managed Region access.
+ //-----------------------------------------------------------------------
+
+ if ( Mgr->CheckAnyStatus( Mgr, CMOS_BAD_CHECKSUM | CMOS_BAD_BATTERY ) ){
+ if ( Mgr->CheckStatus( Mgr, CMOS_BAD_CHECKSUM) )
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "Bad Checksum:\n" ));
+
+ if ( Mgr->CheckStatus( Mgr, CMOS_BAD_BATTERY) )
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "Bad Battery:\n" ));
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_IS_USABLE )
+ && Mgr->CheckStatus(Mgr, CMOS_RECOVER_IN_PEI ) )
+ {
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, " Loading Optimal Defaults\n"));
+ Mgr->LoadOptimalDefaults( Mgr );
+ Mgr->ConfigureManager( Mgr, CMOS_OPTIMAL_DEFAULTS_OFF );
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "...Defaults loaded\n" ));
+ }
+ else {
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, " Using Optimal Defaults.\n"));
+ Mgr->ConfigureManager( Mgr, CMOS_OPTIMAL_DEFAULTS_ON );
+ }
+
+ }
+
+
+ //-----------------------------------------------------------------------
+ // Install the CMOS Access PPI
+ //-----------------------------------------------------------------------
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Installing CMOS Access PPI\n" ));
+ Mgr->InstallAccessInterface(Mgr);
+ if ( !Mgr->CheckStatus(Mgr, CMOS_VALID_MANAGER ) ){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ "Invalid interface ... Access PPI not installed\n" ));
+ return Status = EFI_UNSUPPORTED;
+ }
+
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerPeiEntry successful exit\n" ));
+
+ return Status = EFI_SUCCESS;
+}
+
+
+
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerPei.cif b/Core/EM/CmosManager/CmosManagerPei.cif
new file mode 100644
index 0000000..fb9abbb
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerPei.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CMOS PEI"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosPei"
+[files]
+"CmosManagerPei.c"
+"CmosManagerPei.h"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerPei.h b/Core/EM/CmosManager/CmosManagerPei.h
new file mode 100644
index 0000000..e216728
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerPei.h
@@ -0,0 +1,81 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS PEI/CmosManagerPei.h 5 7/29/09 9:56a Michaela $
+//
+// $Revision: 5 $
+//
+// $Date: 7/29/09 9:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS PEI/CmosManagerPei.h $
+//
+// 5 7/29/09 9:56a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 4 6/15/09 5:10p Michaela
+//
+// 3 6/02/09 3:26p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 2 3/11/09 3:37p Michaela
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerPei.h
+//
+// Description: Contains declarations to support the CMOS Manager
+// in PEI phase.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _CMOS_MANAGER_PEI_H
+#define _CMOS_MANAGER_PEI_H
+
+#include <Efi.h>
+#include <Pei.h>
+#include <AmiPeiLib.h>
+#include <AmiCspLibInc.h>
+#include <SspData.h>
+#include <SspTokens.h>
+#include <CmosAccess.h>
+#include "CmosManager.h"
+#include "CmosBoard.h"
+
+#endif // #ifndef _CMOS_MANAGER_PEI_H
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerSec.asm b/Core/EM/CmosManager/CmosManagerSec.asm
new file mode 100644
index 0000000..94ae87e
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSec.asm
@@ -0,0 +1,396 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SEC/CmosManagerSec.asm 11 12/04/09 7:30p Michaela $
+;
+; $Revision: 11 $
+;
+; $Date: 12/04/09 7:30p $
+;
+;****************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SEC/CmosManagerSec.asm $
+;
+; 11 12/04/09 7:30p Michaela
+;
+; 10 7/29/09 9:55a Michaela
+; updates Aptio Enhancement EIP 22205
+; (no code changes)
+;
+; 9 7/23/09 2:28p Michaela
+;
+; 8 7/23/09 1:35p Michaela
+; Fixed build issue related to PE32 binaries
+;
+; 7 6/02/09 3:26p Michaela
+; For label: 4.6.3_CMOSMGR_11
+;
+; 6 3/11/09 3:37p Michaela
+;
+; 5 2/23/09 6:01p Michaela
+; --Fix token name
+;
+; 4 2/16/09 10:15p Michaela
+; - Use CMOS_BANK0_INDEX/CMOS_BANK0_INDEX SDL token
+; - OR CMOS_NMI_BIT_VALUE with index port
+; values
+;
+; 3 1/21/09 3:30p Michaela
+; fixed build issue
+;
+; 2 1/21/09 2:59p Michaela
+; **Implemented check for CMOS_MGR_SET_NMI_BIT when
+; writing the address
+; **Now using CMOS_STD_INDEX and CMOS_STD_DATA
+; for all CMOS access in SEC (this restricts all SEC-phase CMOS
+; locations to below 0x80, which is not expected to be an issue)
+;
+; 1 11/25/08 3:12p Michaela
+; Organize SEC-related initialization code
+;
+; 4 11/17/08 3:44p Michaela
+; --Port and register constants are initialized using SDL tokens
+; --CMOS-based API pointer and all other SEC accesses are assumed
+; to be located in the 0xF to 0x7F standard CMOS region.
+;
+; 3 11/14/08 9:16a Michaela
+; **CmosReadWrite procedure is used for all CMOS access in the SEC
+; phase.
+; **Include CmosAccessSec.inc for the prototype, error codes
+; and jump macros
+;
+; 2 11/07/08 5:30p Michaela
+; Added SS header
+;
+
+;*************************************************************************
+;<AMI_FHDR_START>
+;
+; Name: CmosManagerSec.asm
+;
+; Description:
+; This file contains all code necessary to support CMOS Manager's SEC
+; phase initialization and external services.
+;
+;<AMI_FHDR_END>
+;*************************************************************************
+
+;----------------------------------------------------------------------------
+; Assembler build options
+;----------------------------------------------------------------------------
+
+.586P
+.XMM
+.MODEL SMALL
+
+INCLUDE TOKEN.EQU
+INCLUDE TOKENEQU.EQU
+
+CMOS_NO_EXTERNS equ 1
+INCLUDE CmosAccessSec.inc
+
+
+; Externs
+EXTERN SEC_CmosManagerEnd:NEAR32
+
+IF SEC_LAST_ADDRESS_VALID
+EXTERN LAST_ADDRESS:ABS
+ENDIF
+
+; Equates
+bcmos_addr_port equ MKF_CMOS_BANK0_INDEX
+bcmos_data_port equ MKF_CMOS_BANK0_DATA
+MKF_stnd_storage_size equ 00Fh ; size of standard
+CLOCK_STATUS_REG EQU MKF_CMOS_RTC_STATUS_REGISTER
+BATT_BIT EQU 080h ; bit 8 is battery status (set == good)
+
+MSR_XAPIC_BASE EQU 01Bh ; standard APIC base MSR
+XAPIC_BASE_BSP_BIT EQU 008h
+
+
+IO_DELAY_bb MACRO
+ jmp $+2
+ jmp $+2
+ENDM
+
+;----------------------------------------------------------------------------
+; STARTUP_SEG S E G M E N T STARTS
+;----------------------------------------------------------------------------
+STARTUP_SEG SEGMENT PARA PUBLIC 'CODE' USE32
+
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: CmosReadWrite
+;
+; Description:
+; Returns the CMOS value associated with the given CMOS token
+; from the actual CMOS storage. CMOS checksum is don't care. Upon detecting
+; an error, the carry flag is set and an error code is returned in AX.
+;
+; Input:
+; AX - CMOS Token.
+; DL - Set for write or Clear for read
+; DH - Value to write
+;
+; Output:
+; AX - CMOS value if reading
+; NC - If success
+; CY - If error & AX = Error code
+;
+; Modified:
+; AX, MM0, MM1, MM2, MM3
+; (EDX upper word and EAX upper word are unmodified)
+; All other registers are preserved
+;
+; Referrals:
+; None
+;
+; Notes:
+; An error code is returned in AX with Carry Flag set upon detected
+; error condition. The following error code constants (defined in
+; CmosAccessSec.inc) are used:
+;
+; CMOS_BATTERY_ERR
+; CMOS_BITSIZE_ERR
+; CMOS_OVERFLOW_ERR
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+CmosReadWrite PROC NEAR PUBLIC
+
+; Token[2:0] = Bit offset within a byte of item's start address in CMOS
+; Token[11:3] = Byte offset of item's start address in CMOS
+; Token[15:12] = Size of item (in units of bits)
+
+ movd mm1, ebx ; save registers
+ movd mm2, ecx
+ movd mm3, edx
+
+ mov bx, ax
+ shr bx, 12
+ cmp bx, 8 ; BX has the size in Bits
+ ja CmosReadWriteSizeError
+ cmp bx, 0
+ je CmosReadWriteSizeError
+
+ mov cx, ax
+ and cx, 07h ; CX has the bit position.
+
+
+ and ax, 0FFFh
+ shr ax, 3 ; AL has the CMOS address
+
+;-----------------------------------------------------
+; return error if battery is bad (using standard ports)
+;-----------------------------------------------------
+
+ xchg ah, al ; save address in AH
+ mov al, CLOCK_STATUS_REG
+ or al, MKF_CMOS_NMI_BIT_VALUE ; set value of NMI bit
+ out bcmos_addr_port, al
+ io_delay_bb
+ io_delay_bb
+ in al, bcmos_data_port ; AL = battery status
+ test al, BATT_BIT ; bit is set if OK
+ .if (zero?)
+ mov ax, CMOS_BATTERY_ERR ; CMOS battery is low.
+ jmp CmosReadWriteError
+ .endif
+ xchg ah, al ; restore address to AL
+
+;-----------------------------------------------------
+; Create an AND mask in CX with bits set corresponding
+; the destination bit field
+;-----------------------------------------------------
+
+ ror ecx, 16 ; ECX upper = bit position
+ xor cx, cx
+ .while (bx > 0)
+ shl cx, 1
+ or cx, 1
+ dec bx
+ .endw
+ mov bx, cx ; BX = mask
+ ror ecx, 16 ; CX = bit position
+ shl bx, cl ; BX = shifted mask
+ ror ecx, 16 ; ECX upper = bit position
+ mov cx, bx ; CX = shifted mask
+
+;-----------------------------------------------------
+; If writing, encode the value:
+;
+; 1) shift the value in DH to its position,
+; 2) complement the mask so that it can be used to clear
+; the destination bit field
+; 3) apply/test mask to DH to ensure adjacent bits are not
+; overwritten, returning an error if there is overflow
+;
+; Note: error checking here will detect an error
+; if attempted write is not within the owned
+; bits of a token.
+;-----------------------------------------------------
+
+ .if (dl == CMOS_WRITE_ACCESS)
+ ror ecx, 16 ; CX = bit position & ECX upper = mask
+ movzx bx, dh ; test upper bit overflow
+ shl bx, cl
+ or bh, bh
+ .if (!zero?) ; error if bits are shifted into BH
+ mov ax, CMOS_OVERFLOW_ERR
+ jmp CmosReadWriteError
+ .endif
+ shl dh, cl ; do the shift for real
+ ror ecx, 16 ; CX = mask & ECX upper = bit position
+ not cx ; CX = complemented mask
+ test dh, cl ; ensure no overwriting of destination
+ .if (!zero?)
+ mov ax, CMOS_OVERFLOW_ERR
+ jmp CmosReadWriteError
+ .endif
+ mov bl, dh ; BL = value to write
+ .endif
+
+;-----------------------------------------------------
+; Note: EDX will contain value/access type information
+; or data/index port information as needed.
+; MM0/MM3 are used as a swap registers for this
+; purpose.
+;-----------------------------------------------------
+
+ mov dx, bcmos_data_port
+ ror edx, 16
+ mov dx, bcmos_addr_port
+ movd mm0, edx ; save data|index in MM0
+ ; data port in EDX upper word
+ ; index port in DX
+
+;-----------------------------------------------------
+; Read/write the CMOS register
+;
+; Note: A read always occurs. If a write is requested,
+; only the bits that are owned by the token
+; are modified and written back.
+;-----------------------------------------------------
+
+ or al, MKF_CMOS_NMI_BIT_VALUE ; set value of NMI bit
+ out dx, al ; AL = address
+ io_delay_bb
+ io_delay_bb
+ xchg ah, al ; AH contains address
+ ror edx, 16 ; DX = data port
+ in al, dx ; AL = value from CMOS
+ movd edx, mm3 ; EDX = value|access type
+
+ .if (dl == CMOS_WRITE_ACCESS)
+ movd edx, mm0 ; EDX = data|index ports
+ xchg ah, al ; AL = address & AH = register value
+ out dx, al
+ io_delay_bb
+ io_delay_bb
+ xchg al, ah ; AL = register value & AH = address
+ and al, cl ; clear the destination field
+ or al, bl ; set the value in AL
+ ror edx, 16 ; DX = data port
+ out dx, al
+ clc ; clear error flag
+ jmp CmosReadWriteExit
+
+;-----------------------------------------------------
+; If reading, decode the value:
+;
+; 1) AND with mask to clear unused bits
+; 2) Shift down to zero by bit position
+;-----------------------------------------------------
+
+ .else
+ and al, cl ; CL is shifted, uncomplemented mask
+ ror ecx, 16 ; CL = bit position & ECX upper = mask
+ shr al, cl
+ movzx ax, al ; AX = value
+ clc ; clear error flag
+ jmp CmosReadWriteExit
+ .endif
+
+CmosReadWriteSizeError:
+ mov ax, CMOS_BITSIZE_ERR
+
+CmosReadWriteError:
+ stc ; set error flag
+
+CmosReadWriteExit:
+ movd ebx, mm1 ; restore registers
+ movd ecx, mm2
+ movd edx, mm3
+
+ jmp edi
+
+CmosReadWrite ENDP
+
+
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: SEC_CmosManager
+;
+; Description:
+; This is the entrypoint for CMOS Manager SEC code.
+;
+; Input:
+; None
+;
+; Output:
+; None
+;
+; Modified:
+; None
+;
+; Referrals:
+; None
+;
+; Notes:
+; Currently, there are no SEC tasks for the CMOS Manager.
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+SEC_CmosManager PROC PUBLIC
+ jmp SEC_CmosManagerEnd
+SEC_CmosManager ENDP
+
+;----------------------------------------------------------------------------
+; STARTUP_SEG S E G M E N T ENDS
+;----------------------------------------------------------------------------
+STARTUP_SEG ENDS
+
+END
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
diff --git a/Core/EM/CmosManager/CmosManagerSec.cif b/Core/EM/CmosManager/CmosManagerSec.cif
new file mode 100644
index 0000000..be948be
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSec.cif
@@ -0,0 +1,8 @@
+<component>
+ name = "CMOS SEC"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosSec"
+[files]
+"CmosManagerSec.asm"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerSmm.c b/Core/EM/CmosManager/CmosManagerSmm.c
new file mode 100644
index 0000000..e50438d
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSmm.c
@@ -0,0 +1,462 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosManagerSmm.c 8 1/25/12 2:38p Michaela $
+//
+// $Revision: 8 $
+//
+// $Date: 1/25/12 2:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosManagerSmm.c $
+//
+// 8 1/25/12 2:38p Michaela
+//
+// 7 1/25/12 2:37p Michaela
+// [TAG] EIP56197
+// [Category] New Feature
+// [Severity] Normal
+// [Description] CMOS Manager Support in Runtime Code
+// [Files] CmosManager.sdl
+// CmosSetup.uni
+// CmosMessages.uni
+// CmosManagerSmm.cif
+// CmosAccess.h
+// CmosManagerSmm.c
+// CmosAccess.asl
+//
+// 6 12/11/11 8:56p Michaela
+//
+// 4 11/30/11 11:48p Michaela
+// [TAG] EIP75889
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Support Setup Customization
+// [Files] CmosManager.sdl
+// CmosSetup.sd
+// CmosSetup.uni
+// CmosMessages.uni
+//
+// 3 3/16/11 2:45p Michaela
+//
+// 2 3/05/10 4:54p Michaela
+//
+// 1 11/10/09 8:45p Michaela
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerSmm.c
+//
+// Description: Contains the routines that initialize the CMOS manager's
+// SMM services.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "CmosManagerSmm.h"
+#include <Protocol\Reset.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\AcpiSupport.h>
+#include <Acpi.h>
+#include <AcpiRes.h>
+
+EFI_CMOS_ACCESS_INTERFACE *gCmos = NULL;
+CMOS_SMM_CONTEXT *gAslContext = NULL; // ASL communication buffer
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SmiHandler
+//
+// Description:
+// This is called from SMM or ASL code to access CMOS during
+// runtime.
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output:
+// NONE
+//
+// Modified:
+// NONE
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+VOID SmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+
+ UINT8 Function = (UINT8)DispatchContext->SwSmiInputValue;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+
+ if (Function == CSMI){
+ if (gCmos == NULL){
+ gAslContext->Status = 0; // FALSE => operation failed
+ }
+ else {
+ switch (gAslContext->Opcode) {
+ case 0: // Write from the communication buffer
+ Status = gCmos->Write(gCmos, gAslContext->CmosToken,
+ gAslContext->CmosByte);
+ break;
+ case 1: // Read into the communication buffer
+ Status = gCmos->Read(gCmos, gAslContext->CmosToken,
+ &gAslContext->CmosByte);
+ break;
+ }
+ if (EFI_ERROR(Status)){
+ gAslContext->Status = 0; // FALSE => operation failed
+ }
+ else {
+ gAslContext->Status = 1; // FALSE => operation success
+ }
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InSmmFunction
+//
+// Description:
+// This function is executed from SMM in order to install the SMRAM-based
+// CMOS Access Interface pointer.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable
+// - System table pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// * Initializes/Installs the EFI_CMOS_ACCESS_INTERFACE
+// Protocol for SMM.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InSmmFunction (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_CMOS_MANAGER_INTERFACE *Mgr;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
+ EFI_HANDLE SwHandle = NULL;
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CmosManagerSMM Entry\n" ));
+
+ //-----------------------------------------------------------------------
+ // Initialize the manager interface and, at this point, only check for
+ // interface initialization errors.
+ //-----------------------------------------------------------------------
+
+ Mgr = NewCmosManagerInterface(NULL);
+ if ( Mgr == NULL || !Mgr->CheckStatus(Mgr, CMOS_VALID_INTERFACE) ) {
+ return Status = EFI_UNSUPPORTED;
+ }
+ if ( Mgr->CheckStatus( Mgr, CMOS_INTERFACE_ALREADY_INSTALLED) )
+ return Status = EFI_SUCCESS;
+
+ //-----------------------------------------------------------------------
+ // Handle specific reported errors.
+ //
+ // Note: All boot time error conditions should have been handled
+ // before execution gets here.
+ //
+ // All that is needed is to report the status for debugging.
+ //-----------------------------------------------------------------------
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_BAD_BATTERY) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerSMM: CMOS_BAD_BATTERY = TRUE\n" ));
+
+ // Default handler is to continue from DXE phase
+ }
+ else if ( Mgr->CheckAnyStatus(Mgr, CMOS_BAD_CHECKSUM
+ | CMOS_OPTIMAL_DEFAULTS_ENABLED) )
+ {
+#if (FULL_CMOS_MANAGER_DEBUG)
+ if ( Mgr->CheckStatus(Mgr, CMOS_BAD_CHECKSUM) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerSMM: CMOS_BAD_CHECKSUM = TRUE\n" ));
+ }
+
+ if ( Mgr->CheckStatus(Mgr, CMOS_OPTIMAL_DEFAULTS_ENABLED) ) {
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerSMM: CMOS_OPTIMAL_DEFAULTS_ENABLED = TRUE\n" ));
+ }
+#endif
+ }
+
+
+ //-----------------------------------------------------------------------
+ // Install the CMOS Access interface
+ //-----------------------------------------------------------------------
+
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CmosManagerSMM: Installing CMOS Access SMM Protocol @ 0x%x\n",
+ Mgr ));
+ Mgr->InstallAccessInterface(Mgr);
+ if ( !Mgr->CheckStatus(Mgr, CMOS_VALID_MANAGER) ){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ "CmosManagerSMM: Invalid interface\n" ));
+ return Status = EFI_UNSUPPORTED;
+ }
+
+ // Update the module-scope interface pointer.
+ gCmos = (EFI_CMOS_ACCESS_INTERFACE*) &Mgr->Access;
+
+ //Register the SW SMI handler
+ Status = pBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid,
+ NULL, &SwDispatch);
+ ASSERT_EFI_ERROR(Status);
+
+ SwContext.SwSmiInputValue = CSMI;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext,
+ &SwHandle);
+
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ "InSmmFunction: could not register...\n"));
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "InSmmFunction Registered.\n"));
+
+ return Status = EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetAslNameObject
+//
+// Description:
+// This function returns the 64-bit value assigned to the ASL named
+// object.
+//
+// Input:
+// IN ACPI_HDR *PDsdt
+// - pointer to the DSDT table
+// IN UINT8 *ObjName
+// - pointer to the name string
+// OUT UINT64 *Value
+// - pointer to the value to be updated
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// N/A
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetAslNameObject(
+ IN ACPI_HDR *PDsdt,
+ IN UINT8 *ObjName,
+ OUT UINT64 *Value)
+{
+ ASL_OBJ_INFO Obj;
+ EFI_STATUS Status;
+
+ if (PDsdt->Signature != DSDT_SIG){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = GetAslObj((UINT8*)(PDsdt+1), PDsdt->Length-sizeof(ACPI_HDR)-1,
+ ObjName, otName, &Obj);
+
+ if (!EFI_ERROR(Status)){
+ *Value = *((UINT64*)((UINT8*)Obj.DataStart + 1));
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdateAslCommunicationBuffer
+//
+// Description:
+// This function is executed in non-SMM in order to allocate the
+// runtime communication buffer used by the \CMOS.ACCE asl method
+// to use CMOS Manager services at runtime.
+//
+// Input:
+// N/A
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// N/A
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateAslCommunicationBuffer ( VOID )
+{
+ EFI_PHYSICAL_ADDRESS DsdtAddress = NULL;
+ ACPI_HDR *Dsdt = NULL;
+ UINT64 CurrentValue;
+ EFI_STATUS Status;
+
+ // Get a pointer to the DSDT.
+
+ Status = LibGetDsdt(&DsdtAddress, EFI_ACPI_TABLE_VERSION_ALL);
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "CMOS Manager: failed to get DSDT\n"));
+ goto EXIT;
+ }
+ Dsdt = (ACPI_HDR*)DsdtAddress;
+
+ // Get the current value of \CCOM.
+
+ Status = GetAslNameObject(Dsdt, "CCOM", &CurrentValue);
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "Could not get \\CCOM ASL object.\n"));
+ goto EXIT;
+ }
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "CurrentValue of \\CCOM is 0x%lX\n",
+ CurrentValue));
+
+ // If \CCOM has not been updated yet, allocate the runtime communication
+ // buffer and update the ASL object. Otherwise, save the value of
+ // \CCOM to the global variable in SMRAM scope.
+
+ if (CurrentValue == 0x0123456789ABCDEF){
+ Status = pBS->AllocatePool(EfiRuntimeServicesData,
+ sizeof(CMOS_SMM_CONTEXT), &gAslContext);
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ "failed to allocate CMOS_SMM_CONTEXT\n"));
+ goto EXIT;
+ }
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS,
+ "CMOS_SMM_CONTEXT allocated to 0x%lX\n", gAslContext ));
+
+ Status = UpdateAslNameObject(Dsdt, "CCOM", (UINT64)gAslContext);
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS, "failed to update \\CCOM\n"));
+ goto EXIT;
+ }
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "Updated \\CCOM ASL object.\n"));
+ }
+ else {
+ gAslContext = (CMOS_SMM_CONTEXT*)CurrentValue;
+ CMOS_TRACE_FULL((CMOS_TRACE_ALWAYS, "gAslContext was updated\n"));
+ }
+
+EXIT:
+ return Status;
+}
+
+
+//---------------------------------------------------------------------------
+// SMM entry point function
+//
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CmosManagerSmmEntry
+//
+// Description:
+// This function is the entrypoint for installing the SMM driver for
+// CMOS Manager.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable
+// - System table pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if successful
+// = or other valid EFI error code
+//
+// Notes:
+// * Initializes/Installs the EFI_CMOS_ACCESS_INTERFACE
+// Protocol for SMM.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CmosManagerSmmEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+#if CMOS_MANAGER_ASL_SUPPORT
+ Status = UpdateAslCommunicationBuffer();
+ if (EFI_ERROR(Status)){
+ CMOS_TRACE((CMOS_TRACE_ALWAYS,
+ "CMOS Manager failed to update ASL communication buffer\n"));
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+
+}
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerSmm.cif b/Core/EM/CmosManager/CmosManagerSmm.cif
new file mode 100644
index 0000000..0ff3503
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSmm.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "CMOS SMM"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosSmm"
+[files]
+"CmosManagerSmm.c"
+"CmosManagerSmm.h"
+"CmosManagerSmm.dxs"
+"CmosAccess.asl"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosManagerSmm.dxs b/Core/EM/CmosManager/CmosManagerSmm.dxs
new file mode 100644
index 0000000..810a938
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSmm.dxs
@@ -0,0 +1,59 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosManagerSmm.dxs 1 11/10/09 8:45p Michaela $
+//
+// $Revision: 1 $
+//
+// $Date: 11/10/09 8:45p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosManagerSmm.dxs $
+//
+// 1 11/10/09 8:45p Michaela
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CmosManagerSmm.dxs
+//
+// Description: Contains the dependency expression for SMM CMOS
+// driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Protocol/SmmBase.h>
+
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerSmm.h b/Core/EM/CmosManager/CmosManagerSmm.h
new file mode 100644
index 0000000..3b65b90
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSmm.h
@@ -0,0 +1,65 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosManagerSmm.h 1 11/10/09 8:45p Michaela $
+//
+// $Revision: 1 $
+//
+// $Date: 11/10/09 8:45p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS SMM/CmosManagerSmm.h $
+//
+// 1 11/10/09 8:45p Michaela
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosManagerSmm.h
+//
+// Description: Contains declarations to support the CMOS Access interface
+// in SMM.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _CMOS_MANAGER_SMM_H
+#define _CMOS_MANAGER_SMM_H
+
+#include <Efi.h>
+#include <AmiDxeLib.h>
+#include <SspData.h>
+#include <SspTokens.h>
+#include <CmosAccess.h>
+#include "CmosManager.h"
+
+#endif // #ifndef _CMOS_MANAGER_SMM_H
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosManagerSource.cif b/Core/EM/CmosManager/CmosManagerSource.cif
new file mode 100644
index 0000000..97b7253
--- /dev/null
+++ b/Core/EM/CmosManager/CmosManagerSource.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "CMOS Source"
+ category = ModulePart
+ LocalRoot = "Core\EM\CmosManager\"
+ RefName = "CmosSource"
+[files]
+"CmosManager.c"
+"CmosAccess.c"
+"CmosTables.c"
+"CmosManagerHob.c"
+<endComponent>
diff --git a/Core/EM/CmosManager/CmosMessages.c b/Core/EM/CmosManager/CmosMessages.c
new file mode 100644
index 0000000..e262f52
--- /dev/null
+++ b/Core/EM/CmosManager/CmosMessages.c
@@ -0,0 +1,231 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CMOS Messages/CmosMessages.c 2 6/15/10 2:22p Michaela $
+//
+// $Date: 6/15/10 2:22p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CMOS Messages/CmosMessages.c $
+//
+// 2 6/15/10 2:22p Michaela
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosMessages.c
+//
+// Description: Contains code to display CMOS-related boot messages.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "Tiano.h"
+#include <Efi.h>
+#include <AmiDxeLib.h>
+#include <SspData.h>
+#include <SspTokens.h>
+#include <CmosAccess.h>
+#include "CmosManager.h"
+#include <Setup.h>
+#include <Protocol\AMIPostMgr.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextOut.h>
+#include "HiiLib.h"
+#include "Mem.h"
+#include "AMITSEStrTokens.h"
+#include "AmiVfr.h"
+
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#include "Include\UefiHii.h"
+#include "Protocol\HiiDatabase.h"
+#include "Protocol\HiiString.h"
+#else
+#include <Protocol/Hii.h>
+#endif
+
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_RUNTIME_SERVICES *gRT;
+
+// Console messages are only supported if TSE sources are included
+
+#if !TSE_SOURCES_SUPPORT
+ #ifdef CMOS_TRACE_FULL
+ #undef CMOS_TRACE_FULL
+ #endif
+ #define CMOS_TRACE_FULL
+#endif
+
+BOOLEAN CmosMgrProcessConInAvailability( VOID )
+{
+ EFI_GUID AmiPostManagerProtocolGuid
+ = AMI_POST_MANAGER_PROTOCOL_GUID;
+ AMI_POST_MANAGER_PROTOCOL *AmiPostMgr;
+ UINT8 Selection = 0;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl = 0; // zero initial value required
+ EFI_CMOS_ACCESS_INTERFACE *Cmos = NULL;
+ EFI_GUID CmosGuid = EFI_DXE_CMOS_ACCESS_GUID;
+ BOOLEAN BadBattery = FALSE;
+ BOOLEAN DefaultsLoaded = FALSE;
+ BOOLEAN NotUsable = FALSE;
+ BOOLEAN BadChecksum = FALSE;
+ BOOLEAN FirstBoot = FALSE;
+ CMOS_STATUS_BYTES CmosInfo;
+ CHAR16 *Title = NULL;
+ CHAR16 *BatteryMsg = NULL;
+ CHAR16 *ChecksumMsg = NULL;
+ CHAR16 *DefaultsMsg = NULL;
+ CHAR16 *UsableMsg = NULL;
+ CHAR16 *FirstBootMsg = NULL;
+
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Locate CMOS Manager interface...\n" ));
+ Status = gBS->LocateProtocol( &CmosGuid, NULL, &Cmos);
+ if (!EFI_ERROR (Status)) {
+ Cmos->ReadCmosStatusBytes(Cmos, &CmosInfo);
+
+ NotUsable = CmosInfo.ConfigurationStatus.NotUsable;
+ }
+ else {
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Could not locate CMOS Manager\n" ));
+ }
+
+ if ( !NotUsable ) {
+ Cmos->Read(Cmos, CMOS_MGR_CHECKSUM_BAD, &BadChecksum);
+ Cmos->Read(Cmos, CMOS_MGR_BATTERY_BAD, &BadBattery);
+ Cmos->Read(Cmos, CMOS_MGR_DEFAULTS_LOADED, &DefaultsLoaded);
+ Cmos->Read(Cmos, CMOS_MGR_FIRST_BOOT_DETECTED, &FirstBoot);
+ }
+
+ // Show messages if the battery is bad or defaults were loaded.
+
+ if ( BadChecksum || BadBattery || DefaultsLoaded
+ || NotUsable || FirstBoot )
+ {
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Locate POST Manager interface...\n" ));
+ Status = gBS->LocateProtocol( &AmiPostManagerProtocolGuid, NULL,
+ &AmiPostMgr );
+ if (EFI_ERROR (Status)) {
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Could not locate POST manager\n" ));
+ return FALSE;
+ }
+
+ // get strings
+
+ Title = HiiGetString( gHiiHandle, STRING_TOKEN(CMOS_MESSAGE_TITLE));
+ BatteryMsg = HiiGetString( gHiiHandle, STRING_TOKEN(BAD_BATTERY_MESSAGE));
+ ChecksumMsg = HiiGetString( gHiiHandle, STRING_TOKEN(BAD_CHECKSUM_MESSAGE));
+ DefaultsMsg = HiiGetString( gHiiHandle, STRING_TOKEN(DEFAULTS_LOADED_MESSAGE));
+ UsableMsg = HiiGetString( gHiiHandle, STRING_TOKEN(NOT_USABLE_MESSAGE));
+ FirstBootMsg = HiiGetString( gHiiHandle, STRING_TOKEN(FIRST_BOOT_MESSAGE));
+
+ // save current TPL and then lower TPL to EFI_TPL_APPLICATION
+
+ OldTpl = gBS->RaiseTPL( EFI_TPL_HIGH_LEVEL );
+ gBS->RestoreTPL( EFI_TPL_APPLICATION );
+
+ AmiPostMgr->SwitchToPostScreen();
+ }
+
+ if ( BadBattery ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Displaying bad battery POST message box...\n" ));
+ Status = AmiPostMgr->DisplayMsgBox( Title,
+ BatteryMsg,
+ MSGBOX_TYPE_OK,
+ &Selection);
+ }
+
+ if ( FirstBoot ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Displaying first boot POST message box...\n" ));
+ Status = AmiPostMgr->DisplayMsgBox( Title,
+ FirstBootMsg,
+ MSGBOX_TYPE_OK,
+ &Selection);
+ }
+
+ // The bad checksum message is expected on the first boot
+
+ if ( BadChecksum && !FirstBoot ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Displaying bad checksum POST message box...\n" ));
+ Status = AmiPostMgr->DisplayMsgBox( Title,
+ ChecksumMsg,
+ MSGBOX_TYPE_OK,
+ &Selection);
+ }
+
+ if ( NotUsable ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Displaying bad CMOS POST message box...\n" ));
+ Status = AmiPostMgr->DisplayMsgBox( Title,
+ UsableMsg,
+ MSGBOX_TYPE_OK,
+ &Selection);
+ }
+
+ if ( DefaultsLoaded ){
+ CMOS_TRACE_FULL(( CMOS_TRACE_ALWAYS,
+ "Displaying defaults loaded POST message box...\n" ));
+ Status = AmiPostMgr->DisplayMsgBox( Title,
+ DefaultsMsg,
+ MSGBOX_TYPE_OK,
+ &Selection);
+ }
+
+ if ( OldTpl != 0 )
+ gBS->RaiseTPL(OldTpl);
+
+ // free string memory
+
+ if ( Title != NULL )
+ MemFreePointer( (VOID **)&Title );
+ if ( BatteryMsg != NULL )
+ MemFreePointer( (VOID **)&BatteryMsg );
+ if ( ChecksumMsg != NULL )
+ MemFreePointer( (VOID **)&ChecksumMsg );
+ if ( DefaultsMsg != NULL )
+ MemFreePointer( (VOID **)&DefaultsMsg );
+ if ( UsableMsg != NULL )
+ MemFreePointer( (VOID **)&UsableMsg );
+ if ( FirstBootMsg != NULL )
+ MemFreePointer( (VOID **)&FirstBootMsg );
+
+ return FALSE; // This routine is not used for password
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosMessages.mak b/Core/EM/CmosManager/CmosMessages.mak
new file mode 100644
index 0000000..4b8fd83
--- /dev/null
+++ b/Core/EM/CmosManager/CmosMessages.mak
@@ -0,0 +1,70 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CMOS Messages/CmosMessages.mak 2 6/15/10 2:22p Michaela $
+#
+# $Revision: 2 $
+#
+# $Date: 6/15/10 2:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CMOS Messages/CmosMessages.mak $
+#
+# 2 6/15/10 2:22p Michaela
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CmosMessages.mak
+#
+# Description: Make file for the CmosMessages.obj
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+AMITSEBin : $(BUILD_DIR)\CmosMessages.obj
+
+$(BUILD_DIR)\CmosMessages.obj : $(PROJECT_DIR)\$(CMOS_MANAGER_DIR)\CmosMessages.c
+ $(CC) $(CFLAGS) -I $(TSEBIN_DIR)\Inc -I $(TSEBIN_DIR) -ICore /Fo$(BUILD_DIR)\ $(PROJECT_DIR)\$(CMOS_MANAGER_DIR)\CmosMessages.c
+
+AMITSESDB : CmosMessagesSDB
+CMOS_MANAGER_MAK_DEPS = \
+ $(CMOS_MANAGER_DIR)\CmosManagerMessages.cif \
+ $(CMOS_MANAGER_DIR)\CmosMessages.mak
+
+$(BUILD_DIR)\CmosMessages.mak : $(CMOS_MANAGER_MAK_DEPS) $(BUILD_RULES)
+ $(CIF2MAK) $(CMOS_MANAGER_DIR)\CmosManagerMessages.cif $(CIF2MAK_DEFAULTS)
+
+CmosMessagesSDB : $(BUILD_DIR)\CmosMessages.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CmosMessages.mak all\
+ "UNI_INCLUDE_PATH=$(TSEBIN_DIR) $(TSE_UNI_INCLUDE_PATH)"\
+ "STRING_CONSUMERS=$(CMOS_MANAGER_DIR)\CmosMessages.c"\
+ TYPE=SDB NAME=CmosMessages
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/CmosManager/CmosMessages.sdl b/Core/EM/CmosManager/CmosMessages.sdl
new file mode 100644
index 0000000..1c2c6d4
--- /dev/null
+++ b/Core/EM/CmosManager/CmosMessages.sdl
@@ -0,0 +1,100 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CMOS Messages/CmosMessages.sdl 2 6/15/10 2:22p Michaela $
+#
+# $Revision: 2 $
+#
+# $Date: 6/15/10 2:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CMOS Messages/CmosMessages.sdl $
+#
+# 2 6/15/10 2:22p Michaela
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+#
+# Name: CmosMessages.sdl
+#
+# Description: This AMI SDL file defines CMOS message-related information.
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+#
+
+MODULE
+ Help = "Includes CmosMessages.mak to Project"
+ File = "CmosMessages.mak"
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+ Token = "CMOS_MESSAGES_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CmosMessages.obj"
+ Parent = "AMITSE_Objects"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+ Token = "CMOS_MESSAGES_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(CMOS_MANAGER_DIR)\CmosMessages.c"
+ Parent = "TSE_STRING_CONSUMERS_LIST"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+ Token = "CMOS_MESSAGES_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "-i $(CMOS_MANAGER_DIR)"
+ Parent = "TSE_UNI_INCLUDE_PATH"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+ Token = "CMOS_MESSAGES_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CmosMessages.sdb"
+ Parent = "TSE_SDBS"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+ Token = "CMOS_MESSAGES_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "CmosMgrProcessConInAvailability,"
+ Parent = "ProcessConInAvailability,"
+ InvokeOrder = AfterParent
+ Token = "CMOS_SETUP_SUPPORT" "=" "1"
+ Token = "CMOS_MESSAGES_SUPPORT" "=" "1"
+End
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/CmosManager/CmosMessages.uni b/Core/EM/CmosManager/CmosMessages.uni
new file mode 100644
index 0000000..779b9b9
--- /dev/null
+++ b/Core/EM/CmosManager/CmosMessages.uni
Binary files differ
diff --git a/Core/EM/CmosManager/CmosSetup.sd b/Core/EM/CmosManager/CmosSetup.sd
new file mode 100644
index 0000000..1046632
--- /dev/null
+++ b/Core/EM/CmosManager/CmosSetup.sd
@@ -0,0 +1,223 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosSetup.sd 2 11/30/11 11:47p Michaela $
+//
+// $Revision: 2 $
+//
+// $Date: 11/30/11 11:47p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Board/CmosSetup.sd $
+//
+// 2 11/30/11 11:47p Michaela
+// [TAG] EIP56197
+// [Category] New Feature
+// [Severity] Normal
+// [Description] CMOS Manager Support in Runtime Code
+// [Files] CmosManager.sdl
+// CmosSetup.uni
+// CmosMessages.uni
+// CmosManagerSmm.cif
+// CmosAccess.h
+// CmosManagerSmm.c
+//
+// 1 6/15/10 2:25p Michaela
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CmosManager.sd
+//
+// Description: CMOS Form Template
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+
+/***********************************************************/
+/* Put NVRAM data definitions here.
+/* For example: UINT8 Data1;
+/* These definitions will be converted by the build process
+/* to a definitions of SETUP_DATA fields.
+/***********************************************************/
+ UINT8 CmosNotUsable; // do not remove
+ UINT8 CmosFirstBootDetected; // do not remove
+ UINT8 CmosDefaultsLoaded; // do not remove
+ UINT8 CmosBatteryIsBad; // do not remove
+ UINT8 CmosCheckSumIsBad; // do not remove
+#endif
+
+
+#ifdef FORM_SET_TYPEDEF
+ // #include
+
+ #ifndef SUPPRESS_GRAYOUT_ENDIF //old Core
+ #if EFI_SPECIFICATION_VERSION>0x20000
+ #define SUPPRESS_GRAYOUT_ENDIF endif; endif;
+ #else
+ #define SUPPRESS_GRAYOUT_ENDIF endif;
+ #endif
+ #endif
+#endif // FORM_SET_TYPEDEF
+
+//**********************************************************************
+// Compatibility Section
+//**********************************************************************
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+ #define CONTROL_DEFINITION
+#endif
+
+//**********************************************************************
+// Controls Section
+//
+// The following section contains control macros that can be overridden
+// in external files. This allows customization of control content,
+// while ensuring the control's data is available.
+//**********************************************************************
+
+#ifdef CONTROL_DEFINITION
+
+#define CMOS_MGR_NOT_USABLE \
+ oneof varid = SETUP_DATA.CmosNotUsable,\
+ prompt = STRING_TOKEN(STR_UNUSABLE_CMOS_PROMPT),\
+ help = STRING_TOKEN(STR_EMPTY),\
+ option text = STRING_TOKEN(STR_FALSE), value = 0, flags = MANUFACTURING | DEFAULT;\
+ option text = STRING_TOKEN(STR_TRUE), value = 1, flags = 0;\
+ endoneof;
+
+#define CMOS_MGR_BATTERY_IS_BAD \
+ oneof varid = SETUP_DATA.CmosBatteryIsBad,\
+ prompt = STRING_TOKEN(STR_BAD_CMOS_BATTERY_PROMPT),\
+ help = STRING_TOKEN(STR_EMPTY),\
+ option text = STRING_TOKEN(STR_FALSE), value = 0, flags = MANUFACTURING | DEFAULT;\
+ option text = STRING_TOKEN(STR_TRUE), value = 1, flags = 0;\
+ endoneof;
+
+#define CMOS_MGR_FIRST_BOOT_DETECTED \
+ oneof varid = SETUP_DATA.CmosFirstBootDetected,\
+ prompt = STRING_TOKEN(STR_FIRST_BOOT_DETECTED_PROMPT),\
+ help = STRING_TOKEN(STR_EMPTY),\
+ option text = STRING_TOKEN(STR_FALSE), value = 0, flags = MANUFACTURING | DEFAULT;\
+ option text = STRING_TOKEN(STR_TRUE), value = 1, flags = 0;\
+ endoneof;
+
+#define CMOS_MGR_DEFAULTS_LOADED \
+ oneof varid = SETUP_DATA.CmosDefaultsLoaded,\
+ prompt = STRING_TOKEN(STR_DEFAULTS_LOADED_PROMPT),\
+ help = STRING_TOKEN(STR_EMPTY),\
+ option text = STRING_TOKEN(STR_FALSE), value = 0, flags = MANUFACTURING | DEFAULT;\
+ option text = STRING_TOKEN(STR_TRUE), value = 1, flags = 0;\
+ endoneof;
+
+#define CMOS_MGR_CHECKSUM_IS_BAD \
+ oneof varid = SETUP_DATA.CmosCheckSumIsBad,\
+ prompt = STRING_TOKEN(STR_BAD_CHECKSUM_PROMPT),\
+ help = STRING_TOKEN(STR_EMPTY),\
+ option text = STRING_TOKEN(STR_FALSE), value = 0, flags = MANUFACTURING | DEFAULT;\
+ option text = STRING_TOKEN(STR_TRUE), value = 1, flags = 0;\
+ endoneof;
+
+#endif //#ifdef CONTROL_DEFINITION
+
+
+#ifdef CONTROLS_WITH_DEFAULTS
+ CMOS_MGR_NOT_USABLE
+ CMOS_MGR_BATTERY_IS_BAD
+ CMOS_MGR_FIRST_BOOT_DETECTED
+ CMOS_MGR_DEFAULTS_LOADED
+ CMOS_MGR_CHECKSUM_IS_BAD
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+
+#ifdef ADVANCED_FORM_SET
+
+ #ifdef FORM_SET_ITEM
+ // Define controls to be added to the main page of the formset
+ #endif
+
+ #ifdef FORM_SET_GOTO
+ // Define goto commands for the forms defined in this file
+ goto CMOS_FORM_ID,
+ prompt = STRING_TOKEN(STR_CMOS_FORM),
+ help = STRING_TOKEN(STR_CMOS_FORM_HELP);
+ #endif
+
+ #ifdef FORM_SET_FORM
+
+
+ #ifndef CMOS_FORM_DEF
+ #define CMOS_FORM_DEF
+ // Define forms
+ form formid = AUTO_ID(CMOS_FORM_ID),
+
+ title = STRING_TOKEN(STR_CMOS_FORM);
+ SUBTITLE(STRING_TOKEN(STR_CMOS_FORM_HELP))
+
+ SEPARATOR
+
+ // grayout (for display only)
+ suppressif ideqval SETUP_DATA.CmosNotUsable == 0;
+ grayoutif ideqval SETUP_DATA.CmosNotUsable == 1;
+ CMOS_MGR_NOT_USABLE
+ SUPPRESS_GRAYOUT_ENDIF
+
+ grayoutif ideqval SETUP_DATA.CmosBatteryIsBad == 1 OR
+ ideqval SETUP_DATA.CmosBatteryIsBad == 0;
+ CMOS_MGR_BATTERY_IS_BAD
+ endif;
+
+ grayoutif ideqval SETUP_DATA.CmosFirstBootDetected == 1 OR
+ ideqval SETUP_DATA.CmosFirstBootDetected == 0;
+ CMOS_MGR_FIRST_BOOT_DETECTED
+ endif;
+
+ suppressif ideqval SETUP_DATA.CmosNotUsable == 1;
+ grayoutif ideqval SETUP_DATA.CmosDefaultsLoaded == 1 OR
+ ideqval SETUP_DATA.CmosDefaultsLoaded == 0;
+ CMOS_MGR_DEFAULTS_LOADED
+ SUPPRESS_GRAYOUT_ENDIF
+
+ suppressif ideqval SETUP_DATA.CmosNotUsable == 1;
+ grayoutif ideqval SETUP_DATA.CmosCheckSumIsBad == 1 OR
+ ideqval SETUP_DATA.CmosCheckSumIsBad == 0;
+ CMOS_MGR_CHECKSUM_IS_BAD
+ SUPPRESS_GRAYOUT_ENDIF
+
+ endform;
+ #endif // #ifndef CMOS_FORM_DEF
+
+ #endif // FORM_SET_FORM
+
+#endif // ADVANCED_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CmosManager/CmosSetup.uni b/Core/EM/CmosManager/CmosSetup.uni
new file mode 100644
index 0000000..c6b6867
--- /dev/null
+++ b/Core/EM/CmosManager/CmosSetup.uni
Binary files differ
diff --git a/Core/EM/CmosManager/CmosTables.c b/Core/EM/CmosManager/CmosTables.c
new file mode 100644
index 0000000..fa0ef32
--- /dev/null
+++ b/Core/EM/CmosManager/CmosTables.c
@@ -0,0 +1,235 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosTables.c 12 6/15/10 2:24p Michaela $
+//
+// $Revision: 12 $
+//
+// $Date: 6/15/10 2:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Source/CmosTables.c $
+//
+// 12 6/15/10 2:24p Michaela
+//
+// 11 11/10/09 9:14p Michaela
+//
+// 10 7/29/09 9:59a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 9 6/15/09 5:11p Michaela
+//
+// 8 6/02/09 3:27p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 7 2/06/09 2:01p Michaela
+// FIRST_CMOS_REGISTER is now generated by AmiSsp2
+//
+// 6 11/17/08 4:40p Michaela
+// --Removed Token Name strings in debug development code
+//
+// 5 11/17/08 3:40p Michaela
+// --Removed development debug code
+//
+// 4 3/07/08 4:07p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 3 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 2 2/26/08 12:49p Michaela
+// Added/modified Helpbuilder headers
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosTables.c
+//
+// Description: Contains the global static data tables that are initialized
+// from AmiSsp2.exe output during the build process. These
+// tables are used in the PEI phase and passed, as needed,
+// to DXE via HOB data structure.
+//
+// This file must always be included in source form.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//<AMI_GHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Initialization_Tables
+//
+// Description:
+// This page provides links to descriptions of the major tables used in
+// initializing/supporting the CMOS Manager module.
+//
+// Fields: Phase Name Description
+// ------------------------------------------------------------------
+// ALL gCmosTokenTable all SSP defined tokens
+// ALL gCmosOptimalDefaultTable default values for all CMOS registers
+// ALL gCmosNoCheckSumTable CMOS addresses that are not checksummed
+//
+//----------------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+
+#include <Efi.h>
+#ifdef PEI_COMPILE
+ #include <Pei.h>
+ #include <AmiPeiLib.h>
+#else
+ #include <AmiDxeLib.h>
+#endif
+#include "CmosManager.h"
+#include "CmosManagerHob.h"
+#include <SspData.h>
+
+CONST UINT8 gFirstManagedRegister = FIRST_CMOS_REGISTER;
+CONST UINT8 gLastManagedRegister = LAST_CMOS_REGISTER;
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gCmosTokenTable
+//
+// Description:
+// This is a table of CMOS tokens derived from macros defined in
+// SspData.h, which is generated by AmiSsp2.exe during the build
+// process.
+//
+// Notes:
+// This is an array of type: CMOS_TOKEN
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+#define USING_SSP_MACROS
+CMOS_TOKEN gCmosTokenTable[] = { // to DXE via HOB
+ {0}, // Index starts at 1
+ #define CmosTokenTable(name,val) {val},
+#include <SspData.h>
+};
+CONST UINT16 gCmosTokenTableSize = CMOS_TOKEN_COUNT(gCmosTokenTable);
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gCmosOptimalDefaultTable
+//
+// Description:
+// This is a table of default (or optimal) CMOS register values derived
+// from macros defined in SspData.h, which is generated by AmiSsp2.exe
+// during the build process.
+//
+// Notes:
+// This is an array of type: CMOS_REGISTER
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+#define USING_SSP_MACROS
+CMOS_REGISTER gCmosOptimalDefaultTable[] = { // to DXE via HOB
+{0}, // Index starts at 1
+#define NvramOptimalDataTable(val) {val},
+#include <SspData.h>
+};
+CONST UINT16 gCmosOptimalDefaultTableSize =
+ CMOS_REGISTER_COUNT(gCmosOptimalDefaultTable);
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gCmosNoCheckSumTable
+//
+// Description:
+// This is a table of CMOS registers excluded from checksum
+// calculations. This table is derived from macros defined in
+// SspData.h, which is generated by AmiSsp2.exe during the build
+// process.
+//
+// Notes:
+// This is an array of type: CMOS_REGISTER
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+#define USING_SSP_MACROS
+CONST CMOS_REGISTER gCmosNoCheckSumTable[] = { // to DXE via HOB
+{0}, // Index starts at 1
+#define NonChecksumTable(val) {val},
+#include <SspData.h>
+};
+CONST UINT16 gCmosNoCheckSumTableSize =
+ CMOS_REGISTER_COUNT(gCmosNoCheckSumTable);
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gUnmanagedTable
+//
+// Description:
+// This is a table of CMOS registers that are allocated, but otherwise
+// unmanaged. The purpose is to provide support for locations that
+// must be written prior to CMOS Manager, and to provide alternative
+// mechanisms in situations where CMOS Manager's loading of default
+// values would cause major implementation problems.
+//
+// Notes:
+// This is an array of type: CMOS_REGISTER
+//
+// It is up to the owner of the SSP CMOS Token to determine whether
+// or not the value of an un-managed location is valid.
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+#define USING_SSP_MACROS
+CONST CMOS_REGISTER gUnmanagedTable[] = {
+{0}, // Index starts at 1
+#define UnmanagedTable(val) {val},
+#include <SspData.h>
+};
+CONST UINT16 gUnmanagedTableSize =
+ CMOS_REGISTER_COUNT(gUnmanagedTable);
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/CmosTypes.h b/Core/EM/CmosManager/CmosTypes.h
new file mode 100644
index 0000000..78ce340
--- /dev/null
+++ b/Core/EM/CmosManager/CmosTypes.h
@@ -0,0 +1,431 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Includes/CmosTypes.h 18 3/05/10 4:55p Michaela $
+//
+// $Revision: 18 $
+//
+// $Date: 3/05/10 4:55p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Includes/CmosTypes.h $
+//
+// 18 3/05/10 4:55p Michaela
+//
+// 17 12/04/09 7:32p Michaela
+//
+// 16 12/03/09 6:45p Michaela
+// 1. Added/updated typdefs for BSP test and
+// cold boot test functions.
+//
+// 2. Added additional Manager Status bits to
+// support recovery policy configuration
+// changes.
+//
+// 15 11/10/09 9:14p Michaela
+//
+// 14 7/29/09 10:00a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 13 6/15/09 5:11p Michaela
+//
+// 12 6/02/09 3:28p Michaela
+// For label: 4.6.3_CMOSMGR_11
+//
+// 11 2/06/09 2:00p Michaela
+// FIRST_CMOS_REGISTER is now generated from AmiSsp2.exe
+//
+// 10 1/08/09 12:53p Michaela
+// >force all structure declarations to be byte packed
+// as they may be used from Assembly code
+//
+// 9 11/25/08 3:20p Michaela
+// Updates for Label 4.6.3_CMOSMGR_08
+// - Assembly macro fixes
+// - Added assembly macros
+// - Moved loading defaults into DXE phase
+// - Updated help file example
+//
+// 8 11/17/08 4:39p Michaela
+// --Removed Token Name strings in debug development code
+//
+// 7 11/17/08 3:55p Michaela
+// --Port- & register-related constants are moved to SDL tokens
+// --CMOS_ACCESS_TYPE typedef is moved to CmosAccess.h for
+// client module usage
+// --Added DEFINE_PEI_SERVICES macro for declaring &
+// initializing a local PeiServices variable, as it must be NULL in
+// DXE and if the PPI is located in firmware
+//
+// 6 11/14/08 9:20a Michaela
+// **CMOS register variables are changed from UINT8 to UINT16
+// **CMOS_REGISTER typedef changed from struct to union with
+// a Value and Index member.
+// **Added typedef for EFI_CMOS_BOARD_READ_WRITE board-
+// specific CMOS access function.
+// **Added typedef for CMOS_PORT_MAP, used for invoking
+// board-specific access functions.
+//
+// 5 3/07/08 4:07p Michaela
+// Label 4.6.3_CMOSMGR_05 fixes:
+// -- write errors to Optimal Defaults buffer before memory detection
+// -- CMOS Token table corruption when name strings are disabled
+//
+// 4 2/29/08 9:35p Michaela
+// - Added recovery path policy
+// - fixed other minor bugs
+//
+// 3 2/26/08 12:50p Michaela
+// Added/modified Helpbuilder headers
+//
+// 2 2/22/08 3:20p Olegi
+// Renamed some of the equates to avoid the naming collisions.
+//
+// 1 2/04/08 6:00p MichaelA
+// Created
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CmosTypes.h
+//
+// Description: Contains the constants, data types and declarations
+// necessary to support the CMOS manager module.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _CMOS_TYPES_H
+#define _CMOS_TYPES_H
+
+#include <Efi.h>
+
+#define ALL_BITS 0xff // bits to write mask
+
+
+// For determination of boot mode
+#define MONOTONIC_VARIABLE L"MonotonicCounter"
+
+#pragma pack(push, 1) // force byte alignment on all structures
+
+typedef enum _CMOS_DEFAULTS_STATUS_TYPE {
+ UsingDefaults = 0,
+ NotUsingDefaults = 1,
+} CMOS_DEFAULTS_STATUS_TYPE;
+
+// Used in read/write functions
+
+typedef enum _CMOS_BIT_ACCESS_TYPE {
+ SetType = 1,
+ ClearType = 0,
+} CMOS_BIT_ACCESS_TYPE;
+
+typedef UINT16 CMOS_CHECKSUM;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CMOS_BYTE
+//
+// Description:
+// This structure type is used to define a generic CMOS byte that,
+// among other things, can be used to define an array of CMOS addresses
+// and values to be read or written.
+//
+// Fields: Type Name Description
+// ----------------------------------------------------------------
+// UINT16 Register CMOS register associated with this byte
+// UINT8 Value Byte value associated with the specified register
+//
+// Notes:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CMOS_BYTE
+{
+ UINT16 Register; // CMOS Register
+ UINT8 Value; // CMOS Value
+}CMOS_BYTE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CMOS_MANAGER_STATUS
+//
+// Description:
+// This enumerated type is used to define a bitmap that represents the
+// configuration status of the CMOS manager. If a bit is set then
+// the condition is TRUE. If a bit is clear then the condition it
+// represents is FALSE.
+//
+// Fields: _ Bit Condition
+// ----------------------------------------------------------------
+// _ CMOS_VALID_MANAGER The manager is initialized
+// _ CMOS_INTERFACE_ALREADY_INSTALLED The access interface has already been installed
+// _ CMOS_INSTALL_FAILED The installation of the access interface failed
+// _ CMOS_VALID_INTERFACE The access interface is valid, but not necessarily installed
+// _ CMOS_FIRST_BOOT_DETECTED Indicates first boot (after progamming the boot device) is detected
+// _ CMOS_EXECUTING_IN_MEMORY The CMOS manager is executing in permanent memory
+// _ CMOS_BAD_CHECKSUM The most recently computed checksum does not equal the saved checksum
+// _ CMOS_ADDRESS_IS_CHECKSUMMED The most recently accessed address is included in the checksum
+// _ CMOS_ERROR_LOADING_DEFAULTS CMOS could not be updated from the default optimal data table
+// _ CMOS_FORCE_NO_CHECKSUM Checksum updating is disabled
+// _ CMOS_LEGACY_STATUS_ENABLED Update legacy status registers in CMOS
+// _ CMOS_BAD_BATTERY Bad battery has been detected
+// _ CMOS_OPTIMAL_DEFAULTS_ENABLED Optimal Defaults buffer is in use
+// _ CMOS_DEFAULTS_LOADED Optimal Defaults buffer has been written to CMOS
+// _ CMOS_RECOVER_ONLY_CHECKSUMMED Use Optimal Defaults buffer only for checksummed locations upon incoherency detection
+// _ CMOS_COLD_BOOT_DETECTED Cold boot was detected
+// _ CMOS_BSP_IS_EXECUTING BSP is executing
+// _ CMOS_RECOVER_IN_PEI PEI incoherency recovery (bad checksum & good battery)
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef enum _CMOS_MANAGER_STATUS {
+ CMOS_VALID_MANAGER = BIT0, // manager is initialized
+ CMOS_INTERFACE_ALREADY_INSTALLED = BIT1, // duplicate interface found
+ CMOS_INSTALL_FAILED = BIT2, //
+ CMOS_VALID_INTERFACE = BIT3, // not necessarily installed
+ CMOS_FIRST_BOOT_DETECTED = BIT4,
+ CMOS_EXECUTING_IN_MEMORY = BIT6,
+ CMOS_BAD_CHECKSUM = BIT7,
+ CMOS_ADDRESS_IS_CHECKSUMMED = BIT8,
+ CMOS_ERROR_LOADING_DEFAULTS = BIT9,
+ CMOS_FORCE_NO_CHECKSUM = BIT10, // internal flag
+ CMOS_BAD_BATTERY = BIT12,
+ CMOS_OPTIMAL_DEFAULTS_ENABLED = BIT13, // recovery enabled
+ CMOS_DEFAULTS_LOADED = BIT14,
+ CMOS_RECOVER_ONLY_CHECKSUMMED = BIT15, // limit recovery scope
+ CMOS_COLD_BOOT_DETECTED = BIT16, // Cold boot was detected
+ CMOS_BSP_IS_EXECUTING = BIT17, // BSP is executing
+ CMOS_RECOVER_IN_PEI = BIT18, // PEI incoherency recovery
+ CMOS_IS_USABLE = BIT19, // CMOS can be used
+ // (battery may be bad)
+} CMOS_MANAGER_STATUS;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CMOS_CONFIGURATION_SETTING
+//
+// Description:
+// This enumerated type is used to define a bitmap that represents the
+// requested configuration settings for the CMOS manager. If a bit is
+// set then the associated feature or setting is requested.
+//
+// Fields: _ Bit Requests
+// ----------------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef enum _CMOS_CONFIGURATION_SETTING {
+ CMOS_OPTIMAL_DEFAULTS_ON = BIT2, // enable buffer usage
+ CMOS_OPTIMAL_DEFAULTS_OFF = BIT3, // disable buffer usage
+} CMOS_CONFIGURATION_SETTING;
+
+
+// These are the PPI that may or may not be installed, depending on
+// configuration settings
+typedef enum _CMOS_PPI_TYPE {
+ CMOS_DATA_HOB_INSTALLED_PPI_TYPE = 0, // HOB is installed
+ CMOS_ACCESS_PPI_TYPE = 1, // Access interface
+ CMOS_CREATE_HOB_NOTIFY_PPI_TYPE = 2, // In-memory callback
+} CMOS_PPI_TYPE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CMOS_TOKEN
+//
+// Description:
+// This structure type is used to define CMOS tokens, which are encoded
+// values that define the usage of bits at a particular physical CMOS
+// location.
+//
+// Fields: Type Name Description
+// ----------------------------------------------------------------
+// UINT64 Name A constant string pointer providing the name associated with the token (available only in debug mode)
+// union Value Provides access to the encoded information in the token (see Notes below)
+//
+// Notes:
+// The Value union provides access to all the bits of the token or to
+// a specific token data field:
+//
+// Value.AllBits All bits of the encoded token data
+// Value.Field Provides access to a specific token field
+// Value.Field.BitOffset Offset within the CMOS byte
+// Value.Field.CmosAddress The actual CMOS location
+// Value.Field.Size The number of bits consumed by the token
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _CMOS_TOKEN
+{
+ union _Value
+ {
+ UINT16 AllBits;
+ struct _Field {
+ UINT16 BitOffset :3; // [2:0] Bit offset (in the CMOS byte)
+ UINT16 CmosAddress :9; // [11:3] CMOS register address (0-511)
+ UINT16 Size :4; // [15:12] Size (in bits)
+ } Field;
+ } Value;
+}CMOS_TOKEN;
+
+// Gets number of elements in an array of type CMOS_TOKEN
+#define CMOS_TOKEN_COUNT(Buffer) ( sizeof(Buffer) / sizeof(CMOS_TOKEN) )
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CMOS_REGISTER
+//
+// Description:
+// This union type is used to define un-encoded register
+// values/numbers.
+//
+// Fields: Type Name Description
+// ----------------------------------------------------------------
+// UINT16 Value The un-encoded value of a register
+// UINT8 Index The un-encoded register address
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef union _CMOS_REGISTER
+{
+ UINT8 Value;
+ UINT16 Index;
+}CMOS_REGISTER;
+
+// Gets number of elements in an array of type CMOS_REGISTER
+#define CMOS_REGISTER_COUNT(Buffer) ( sizeof(Buffer) / sizeof(CMOS_REGISTER) )
+
+typedef EFI_STATUS (*EFI_CMOS_BOARD_READ_WRITE) (
+ IN EFI_PEI_SERVICES **PeiServices, // NULL in DXE phase
+ IN CMOS_ACCESS_TYPE AccessType,
+ IN UINT16 CmosRegister,
+ IN UINT8 *CmosParameterValue
+);
+
+typedef struct _CMOS_PORT_MAP
+{
+ UINT16 Index; // Index port
+ UINT16 Data; // Data Port
+ UINT16 Low; // First address in this range
+ UINT16 High; // Last address in this range
+ EFI_CMOS_BOARD_READ_WRITE BoardReadWrite;
+
+} CMOS_PORT_MAP;
+
+typedef BOOLEAN (*EFI_CMOS_BATTERY_TEST) (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+typedef BOOLEAN (*EFI_CMOS_IS_FIRST_BOOT) (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+typedef BOOLEAN (*EFI_CMOS_IS_BSP) (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+typedef BOOLEAN (*EFI_CMOS_IS_COLD_BOOT) (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+typedef BOOLEAN (*EFI_CMOS_IS_CMOS_USABLE) (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+#pragma pack(pop)
+
+//----------------------------------------------------------------------------
+// Macros
+//----------------------------------------------------------------------------
+
+// The DEFINE_PEI_SERVICES macro is used to define a local PEI_SERVICES
+// pointer used for PEI phase only. In DXE phase a NULL pointer is defined
+// to provide generic ability to call the PEI/BOOT Services wrapper functions.
+// (See CmosManagerAllocatePool() for a usage example.)
+
+#if ( defined(PEI_COMPILE))
+ #define DEFINE_PEI_SERVICES(arg) \
+ EFI_PEI_SERVICES **PeiServices = (arg);
+#else
+ #define DEFINE_PEI_SERVICES(arg) \
+ EFI_PEI_SERVICES **PeiServices = NULL;
+#endif
+
+
+// If PEI mode source
+#if ( defined(PEI_TRACE) )
+ //------------------------------------------------------------------------
+ // Generate a compiler message to help identify the build error if
+ // PeiServices is not defined in the calling function.
+ //------------------------------------------------------------------------
+ #pragma message("MESSAGE> AMI_TRACE requires identifier definition: \
+ EFI_PEI_SERVICES **PeiServices")
+ #define CMOS_TRACE(args) if (PeiServices != NULL) { PEI_TRACE(args); }
+ #define CMOS_TRACE_ALWAYS TRACE_ALWAYS,PeiServices
+
+ // CMOS manager-specific
+ #if (FULL_CMOS_MANAGER_DEBUG)
+ #define CMOS_TRACE_FULL(args) \
+ if (PeiServices != NULL) { PEI_TRACE(args); }
+ #else
+ #define CMOS_TRACE_FULL(args)
+ #endif
+
+// If DXE mode source
+#elif ( defined(TRACE) )
+
+ #define CMOS_TRACE(args) TRACE(args)
+ #define CMOS_TRACE_ALWAYS TRACE_ALWAYS
+
+ // CMOS manager-specific
+ #if (FULL_CMOS_MANAGER_DEBUG)
+ #define CMOS_TRACE_FULL(args) TRACE(args)
+ #else
+ #define CMOS_TRACE_FULL(args)
+ #endif
+
+#else
+ #define CMOS_TRACE(args)
+ #define CMOS_TRACE_ALWAYS
+ #define CMOS_TRACE_FULL(args)
+
+#endif
+
+
+#endif // #ifndef _CMOS_TYPES_H
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CmosManager/Template.ssp b/Core/EM/CmosManager/Template.ssp
new file mode 100644
index 0000000..ada4980
--- /dev/null
+++ b/Core/EM/CmosManager/Template.ssp
@@ -0,0 +1,259 @@
+//
+// TITLE TEMPLATE.SSP -- SETUP UTILITY CORE TEMPLATE
+//
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Build/Template.ssp 6 6/15/10 2:26p Michaela $
+//
+// $Revision: 6 $
+//
+// $Date: 6/15/10 2:26p $
+//***************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CMOS Manager/CMOS Core/CMOS Build/Template.ssp $
+//
+// 6 6/15/10 2:26p Michaela
+//
+// 5 9/17/09 10:04a Michaela
+// TokenInclude must be empty string for Aptio projects
+//
+// 4 7/29/09 10:01a Michaela
+// updates Aptio Enhancement EIP 22205
+// (no code changes)
+//
+// 3 6/15/09 5:12p Michaela
+//
+// 2 2/06/09 1:58p Michaela
+// updated to set first managed register location
+//
+// 1 2/22/08 2:29p Michaela
+//
+// 1 2/04/08 6:00p MichaelA $
+// Added to CmosManager Module from Core8 Implementation
+// -- Removed: Setup Engine Template Language Elements
+// -- Modified: EquInclude and TokenInclude
+//
+//
+//***************************************************************************
+// Previous History:
+//***************************************************************************
+// 1 4/23/03 2:37p Anandj
+// Moved from BSP\SETUP
+//
+// 2 10/11/01 3:59p Juand
+// Added a word to store the offset of the beginning of the file
+// SETUPDB.ASM after the $MPT signarute for AMIBCP. This word was deleted
+// accidentally.
+//
+// 7 9/05/01 2:40p Kevinm
+// Removed Q_DISPLAY_TYPE. This question is not currently supported by
+// the BIOS.
+//
+// 6 8/24/01 3:56p Kevinm
+// Removed Unattended Start functionality.
+//
+// 5 7/17/01 4:51p Kevinm
+//
+// 4 6/12/01 2:37p Chrism
+// Comment out Boot_Speed setup question. Has no purpose anymore.
+//
+// 3 6/04/01 3:17p Kevinm
+// Modified for BBS 3.1.
+//
+// 2 5/30/01 3:40p Radhikas
+//
+// 1 5/25/01 2:15p Anandj
+// First check in for CORE data base
+//
+// 5 5/16/01 10:37a Davidd
+// Roll back to previous version.
+//
+// 3 5/03/01 1:40p Juand
+// Removed EquInclude "build\\makeflag.equ". MAKEFLAG.EQU is already
+// included in CORE.SSP. This was causing the BIOS not to build in some
+// systems.
+//
+// 2 4/09/01 4:01p Juand
+// Changed to new style headers.
+// Moved CPU related setup questions to CPU.SSP
+//
+// 9 8/31/00 4:37p Olegi
+// Q_QUICK_BOOT moved out of MKF_SILENT_BOOT condition
+//
+// 8 8/31/00 11:39a Olegi
+// SIO related group is included only with LEGACY_FREE off.
+//
+// 7 8/25/00 10:26a Olegi
+// Q_EXTERNAL_CACHE has been added
+//
+// 6 8/24/00 6:58p Olegi
+// Q_INITIAL_DISPLAY made dependent on MKF_SILENT_BOOT
+//
+// 5 8/21/00 3:53p Olegi
+// equates.equ is included
+//
+// 2 6/02/00 5:34p Olegi
+// USB related questions appear only if USB_SUPPORT is on,
+// Silent Boot related questions appear only if SILENT_BOOT is on.
+//
+// 3 2/24/00 12:08p Juand
+// BBS related changes.
+//
+// 2 12/01/99 11:26a Debkumar
+// Incorporated changes for BBS (from the BBS development done for other
+// major OEMs). Files changed are CF.ASM, RM.ASM, UI.ASM, INT19.ASM,
+// GS1.ASM, HI.ASM, HD.ASM, INT13ISR.ASM, BOOTEXT.ASM, JMP.ASM, DIM.ASM,
+// BUS.ASM, DIM.DAT, DIM.EQU, BIOSDATA.DAT, CORE.SSP, CORE.ASD,
+// TEMPLATE.SSP, TEMPLATE.ASD. The new files are BBS.DAT, IPLDT.INC.
+// Known Limitations: 1) BOOTEXT.ASM should be made generic to reorganize
+// the available boot options in setup. 2) Runtime BBS functions.
+//
+//***************************************************************************
+
+EquInclude "Build\\Token.equ"
+TokenInclude ""
+
+//---------------------------------------------------------------------------
+// General Language Elements
+//---------------------------------------------------------------------------
+
+Description = "Setup Engine Template Definitions"
+LanguageVersion = 2
+
+
+// Largest supported address is 0xFF, which is 0x100 locations
+NvramSize = MKF_MAX_MANAGED_CMOS_ADDRESS
+
+// First register that CMOS Manager will manage
+// (If not specified, the FirstRegister default value is 0x10)
+FirstRegister = MKF_FIRST_MANAGED_CMOS_ADDRESS
+
+//---------------------------------------------------------------------------
+// Setup Engine Template Language Elements
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// Control Database Language Elements
+//---------------------------------------------------------------------------
+
+// FIRST LEVEL (will contain only menuitems)
+ControlGroup (G_ROOT)
+ // EMPTY (Controls Filled in by respective SSP files in fixed order)
+EndControlGroup
+
+
+//---------------------------------------------------------------------------
+// Control Database Language Elements
+//---------------------------------------------------------------------------
+
+
+
+//---------------------------------------------------------------------------
+// Other Sections
+//---------------------------------------------------------------------------
+
+StartSourceCode ("SETUPDB.ASM")
+" "
+" TITLE SETUPDB.ASM -- Setup Database"
+" "
+";----------------------------------------------------------------------------"
+"; INCLUDE FILES"
+";----------------------------------------------------------------------------"
+" "
+" INCLUDE SETUPEXT.INC"
+" INCLUDE TOKENEQU.EQU"
+" "
+";----------------------------------------------------------------------------"
+"; SETSVR_CSEG S E G M E N T STARTS"
+";----------------------------------------------------------------------------"
+"SETSVR_CSEG SEGMENT PARA PUBLIC 'CODE'"
+" ASSUME CS:SETSVR_CSEG"
+";----------------------------------------------------------------------------"
+" PUBLIC _SETUPDB_SETSVR_CSEG_STARTS"
+"_SETUPDB_SETSVR_CSEG_STARTS LABEL BYTE"
+";----------------------------------------------------------------------------"
+" "
+" BYTE '$MPT' ; Signature for the Setup Master"
+" ; Pointer Table"
+" dw offset _SETUPDB_SETSVR_CSEG_STARTS ;Refernce point."
+" "
+";----------------------------------------------------------------------------"
+" "
+EndSourceCode
+
+StartSourceCode ("TOKENEQU.ASM")
+" "
+" TITLE TOKENEQU.ASM -- NVRAM TOKEN VALUES"
+" "
+";----------------------------------------------------------------------------"
+" "
+" PUBLIC STR_RESERVED"
+"STR_RESERVED EQU 0FFFFh"
+" "
+";----------------------------------------------------------------------------"
+"; RUN_CSEG S E G M E N T STARTS"
+";----------------------------------------------------------------------------"
+"RUN_CSEG SEGMENT PARA PUBLIC 'CODE'"
+" ASSUME CS:RUN_CSEG"
+";----------------------------------------------------------------------------"
+" PUBLIC _TOKENEQU_RUN_CSEG_STARTS"
+"_TOKENEQU_RUN_CSEG_STARTS LABEL BYTE"
+";----------------------------------------------------------------------------"
+" "
+EndSourceCode
+
+
+//---------------------------------------------------------------------------
+// Internal CMOS Manager non-volatile status
+//
+//---------------------------------------------------------------------------
+
+NvramField ( CMOS_MGR_BATTERY_BAD )
+ OptionBits = 1
+ Managed = NO
+EndNvramField
+
+NvramField ( CMOS_MGR_CHECKSUM_BAD )
+ OptionBits = 1
+ Managed = NO
+EndNvramField
+
+NvramField ( CMOS_MGR_DEFAULTS_LOADED )
+ OptionBits = 1
+ Managed = NO
+EndNvramField
+
+NvramField ( CMOS_MGR_FIRST_BOOT_DETECTED )
+ OptionBits = 1
+ Managed = NO
+EndNvramField
+
+
+
+//---------------------------------------------------------------------------
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptLib/Cryptlib.cif b/Core/EM/CryptoPkg/CryptLib/Cryptlib.cif
new file mode 100644
index 0000000..d3f341b
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/Cryptlib.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Crypto LIB"
+ category = ModulePart
+ LocalRoot = "Core\EM\CryptoPkg\CryptLib\"
+ RefName = "CryptoLIB"
+[files]
+"cryptlib.chm"
+"cryptlib.sdl"
+"cryptlib.lib"
+"cryptlibX64.lib"
+"cryptlibpei.lib"
+"license.txt"
+[parts]
+"CryptoLibInc"
+<endComponent>
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlib.chm b/Core/EM/CryptoPkg/CryptLib/cryptlib.chm
new file mode 100644
index 0000000..9f80f28
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlib.chm
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlib.lib b/Core/EM/CryptoPkg/CryptLib/cryptlib.lib
new file mode 100644
index 0000000..53ce46a
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlib.lib
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlib.sdl b/Core/EM/CryptoPkg/CryptLib/cryptlib.sdl
new file mode 100644
index 0000000..8587961
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlib.sdl
@@ -0,0 +1,36 @@
+TOKEN
+ Name = "CryptLib_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CRYPTO_trace_level"
+ Value = "0"
+ Help = "0-skip debug messages, 1- short trace, 2- full trace"
+ TokenType = Integer
+ TargetH = Yes
+ TargetMAK = Yes
+ Range = "0-1-2"
+End
+
+TOKEN
+ Name = "CRYPTOLIB"
+ Value = "$(Cryptlib_DIR)\CRYPTLIB$(ARCH).lib"
+ TokenType = "Expression"
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CRYPTOLIBPEI"
+ Value = "$(Cryptlib_DIR)\CRYPTLIBPEI.lib"
+ TokenType = "Expression"
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "Cryptlib_DIR"
+End
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlibX64.lib b/Core/EM/CryptoPkg/CryptLib/cryptlibX64.lib
new file mode 100644
index 0000000..be4663b
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlibX64.lib
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/cryptlibpei.lib b/Core/EM/CryptoPkg/CryptLib/cryptlibpei.lib
new file mode 100644
index 0000000..bfad267
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/cryptlibpei.lib
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptLib/license.txt b/Core/EM/CryptoPkg/CryptLib/license.txt
new file mode 100644
index 0000000..378df36
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptLib/license.txt
@@ -0,0 +1,102 @@
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+// Name: License
+// Description: WPA Supplicant License
+======================================================================
+
+Copyright (c) 2003-2009, Jouni Malinen <j@w1.fi> and contributors
+All Rights Reserved.
+
+======================================================================
+License
+--------
+
+This software may be distributed, used, and modified
+under the terms of BSD license:
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+3. Neither the name(s) of the above-listed copyright holder(s) nor the
+ names of its contributors may be used to endorse or promote products
+ derived from this software without specific prior written permission.
+
+==============
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+======================================================================
+
+Features
+--------
+
+Internal crypto implementation (optional):
+- X.509 certificate processing in PEM and DER formats
+- PKCS #1
+- ASN.1
+- RSA
+- bignum
+- minimal size (ca. 50 kB binary, parts of which are already needed for WPA;
+ TLSv1/X.509/ASN.1/RSA/bignum parts are about 25 kB on x86)
+
+
+Requirements
+------------
+
+wpa_supplicant was designed to be portable for different drivers and
+operating systems. Hopefully, support for more wlan cards and OSes will be
+added in the future. See developer's documentation
+(http://hostap.epitest.fi/wpa_supplicant/devel/) for more information about the
+design of wpa_supplicant and porting to other drivers. One main goal
+is to add full WPA/WPA2 support to Linux wireless extensions to allow
+new drivers to be supported without having to implement new
+driver-specific interface code in wpa_supplicant.
+
+
+WPA
+---
+
+The original security mechanism of IEEE 802.11 standard was not
+designed to be strong and has proven to be insufficient for most
+networks that require some kind of security. Task group I (Security)
+of IEEE 802.11 working group (http://www.ieee802.org/11/) has worked
+to address the flaws of the base standard and has in practice
+completed its work in May 2004. The IEEE 802.11i amendment to the IEEE
+802.11 standard was approved in June 2004 and published in July 2004.
+
+Wi-Fi Alliance (http://www.wi-fi.org/) used a draft version of the
+IEEE 802.11i work (draft 3.0) to define a subset of the security
+enhancements that can be implemented with existing wlan hardware. This
+is called Wi-Fi Protected Access<TM> (WPA). This has now become a
+mandatory component of interoperability testing and certification done
+by Wi-Fi Alliance. Wi-Fi provides information about WPA at its web
+site (http://www.wi-fi.org/OpenSection/protected_access.asp).
+
+IEEE 802.11 standard defined wired equivalent privacy (WEP) algorithm
+for protecting wireless networks. WEP uses RC4 with 40-bit keys,
+24-bit initialization vector (IV), and CRC32 to protect against packet
+forgery. All these choices have proven to be insufficient: key space is
+too small against current attacks, RC4 key scheduling is insufficient
+(beginning of the pseudorandom stream should be skipped), IV space is
+too small and IV reuse makes attacks easier, there is no replay
+protection, and non-keyed authentication does not protect against bit
+flipping packet data.
+
+//<AMI_FHDR_END>
diff --git a/Core/EM/CryptoPkg/CryptoAPI.chm b/Core/EM/CryptoPkg/CryptoAPI.chm
new file mode 100644
index 0000000..7c69ddc
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.chm
Binary files differ
diff --git a/Core/EM/CryptoPkg/CryptoAPI.cif b/Core/EM/CryptoPkg/CryptoAPI.cif
new file mode 100644
index 0000000..f572730
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Crypto Protocol"
+ category = ModulePart
+ LocalRoot = "Core\EM\CryptoPkg"
+ RefName = "CryptoAPI"
+[files]
+"CryptoAPI.chm"
+"CryptoAPI.sdl"
+"CryptoAPI.mak"
+"CryptoPei.c"
+"CryptoDxe.c"
+"CryptoPei.dxs"
+"CryptoDxe.dxs"
+[parts]
+"CryptoIncludes"
+<endComponent>
diff --git a/Core/EM/CryptoPkg/CryptoAPI.mak b/Core/EM/CryptoPkg/CryptoAPI.mak
new file mode 100644
index 0000000..f83d42a
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.mak
@@ -0,0 +1,127 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoAPI.mak 1 6/13/11 5:19p Alexp $
+#
+# $Revision: 1 $
+#
+# $Date: 6/13/11 5:19p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoAPI.mak $
+#
+# 1 6/13/11 5:19p Alexp
+#
+# 2 5/11/11 12:59p Alexp
+# renamed cryptolib macro name
+#
+# 1 5/06/11 6:11p Alexp
+# initial module release
+#
+# 5 5/06/11 6:04p Alexp
+# link PEI Crypto Lib module
+#
+# 4 5/06/11 4:39p Alexp
+# add help header
+#
+# 3 4/07/11 12:22p Alexp
+#
+# 2 4/04/11 7:19p Alexp
+#
+# 1 3/10/11 4:52p Alexp
+#
+# 1 2/18/11 5:42p Alexp
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CryptoApi.mak
+#
+# Description: Build rules to build PEI, DXE and SMM Crypto drivers
+#
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : CryptoAPI
+
+BUILD_CryptoAPI_DIR = $(BUILD_DIR)\$(CryptoAPI_DIR)
+BUILD_CryptoAPIIA32_DIR = $(BUILD_DIR)\IA32\$(CryptoAPI_DIR)
+
+CryptoAPI : CryptLib $(BUILD_DIR)\CryptoAPI.mak CryptoAPIDxeBin \
+!IF "$(CryptoPPI_SUPPORT)" == "1"
+ CryptoAPIPeiBin
+!ENDIF
+
+#dummy target. Will be used to build Crypto Library if sources are present
+CryptLib:
+
+$(BUILD_DIR)\CryptoAPI.mak : $(CryptoAPI_DIR)\CryptoAPI.cif $(CryptoAPI_DIR)\CryptoAPI.mak $(BUILD_RULES)
+ $(CIF2MAK) $(CryptoAPI_DIR)\CryptoAPI.cif $(CIF2MAK_DEFAULTS)
+
+CryptoAPI_PEI_OBJECTS = \
+ $(BUILD_CryptoAPIIA32_DIR)\CryptoPei.obj
+
+CryptoAPI_DXE_OBJECTS = \
+ $(BUILD_CryptoAPI_DIR)\CryptoDxe.obj
+
+CryptoAPI_INCLUDES= \
+ /I $(CryptoAPI_DIR)\
+ /I $(Cryptlib_DIR)\
+ /I $(ReFlash_DIR)\
+ /I$(CORE_DIR)
+
+!IF "$(CryptoPPI_SUPPORT)" == "1"
+CryptoAPIPeiBin : $(AMIPEILIB) $(CRYPTOLIBPEI)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CryptoAPI.mak all\
+ NAME=CryptoPei\
+ MAKEFILE=$(BUILD_DIR)\CryptoAPI.mak \
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ GUID=D6D2FBA6-EF60-4C38-A83E-6769814D23B0 \
+ ENTRY_POINT=CryptoPei_Init \
+ "MY_INCLUDES=$(CryptoAPI_INCLUDES)"\
+ "CFLAGS=$(CFLAGS) /D PEI_BUILD" \
+ OBJECTS="$(CryptoAPI_PEI_OBJECTS)" \
+ DEPEX1=$(CryptoAPI_DIR)\CryptoPei.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM COMPRESS=1
+!ENDIF
+
+CryptoAPIDxeBin : $(AMIDXELIB) $(CRYPTOLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CryptoAPI.mak all\
+ NAME=CryptoDxe\
+ MAKEFILE=$(BUILD_DIR)\CryptoAPI.mak \
+ GUID=20D8FFFE-15C3-4ea9-9D28-CFE2745D78F3 \
+ ENTRY_POINT=CryptoDxe_Init\
+ DEPEX1=$(CryptoAPI_DIR)\CryptoDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ "MY_INCLUDES=$(CryptoAPI_INCLUDES) "\
+ OBJECTS="$(CryptoAPI_DXE_OBJECTS)" \
+ TYPE=RT_DRIVER COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoAPI.sdl b/Core/EM/CryptoPkg/CryptoAPI.sdl
new file mode 100644
index 0000000..5e6f9ee
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoAPI.sdl
@@ -0,0 +1,95 @@
+TOKEN
+ Name = "CryptoAPI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable CryptoAPI support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CryptoPPI_SUPPORT"
+ Value = "1"
+ Help = "Includes the Crypto PPI module"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CR_PEI_MAX_HEAP_SIZE"
+ Value = "48*1024"
+ Help = "Crypt Optimized Mem manager. Min 15kb in rsa decrypt in Mode2,(?? if page alligned heap)"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CR_DXE_MAX_HEAP_SIZE"
+ Value = "48*1024"
+ Help = "Crypt Optimized Mem manager. Min 48kb if process PKCS7 Certs and Rsa decrypt in Mode2,(?? if page alligned heap)"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "E_CONST"
+ Value = "0x01, 0x00, 0x01"
+ Help = "RSA2048. Predefined value of Public Exponent:E = 0x10001"
+ TokenType = Expression
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "PSS_SIG_SALTLEN"
+ Value = "8"
+ Help = "PKCS_1 PSS Signature constant. Size of the Salt (random data) field in PSS signature."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "CONFIG_PEI_PKCS7"
+ Value = "0"
+ Help = "Support x509 & Pkcs7 in PEI CryptoLib. Add ~8kb to CryptoPEI binary"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "0-1"
+End
+
+TOKEN
+ Name = "PKCS7_MUTEX_LOCK"
+ Value = "0"
+ Help = "Turn on mutex functionality for Pkcs7Verify back to back operations. Preserves internal context until mutext released/reset"
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "0-1"
+End
+
+PATH
+ Name = "CryptoAPI_DIR"
+ Help = "Path to CryptoAPI Module in Project"
+End
+
+MODULE
+ Help = "Includes CryptoAP.mak to Project"
+ File = "CryptoAPI.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CryptoPei.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+ Token = "CryptoPPI_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CryptoDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CryptoPkg/CryptoDxe.c b/Core/EM/CryptoPkg/CryptoDxe.c
new file mode 100644
index 0000000..8c40af1
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoDxe.c
@@ -0,0 +1,1108 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.c 31 8/15/13 9:43a Alexp $
+//
+// $Revision: 31 $
+//
+// $Date: 8/15/13 9:43a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.c $
+//
+// 31 8/15/13 9:43a Alexp
+// Pkcs7Verify() - add TimeStamp signature processing(UEFI ECR1009)
+// Pkcs7Verify() - enable code branch for PKCS7_MUTEX_LOCK
+//
+// 30 8/02/13 4:26p Alexp
+// Moved EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID under AmiDigSig
+// Protocol defining header file
+//
+// 29 8/02/13 4:00p Alexp
+// 1. Fix logic to get FwKey from a Hob.
+// Key is copied into pre-allocated buffer by driver entry point
+// 2. Optimized Pkcs7Verify.
+//
+// 27 6/20/13 1:55p Alexp
+// Impove FwKey handling. CryptoPEI pass FwKey location to Dxe via Hob
+// Add mor parameter checking including
+// check for FwKey location to be mapped to Flash FV_BB
+//
+// 26 1/11/13 10:07a Alexp
+// GetKey(): fix MemCpy() 2nd argument. Was not copying a key buffer.
+//
+// 25 12/28/12 2:50p Alexp
+// EIP#110823:The system cannot boot to UEFI(WIN8) OS if the Secure Flash
+// Pkg module is not supported
+// Update GetKey(); InSmmFunction() and NotInSmmFunction() routines
+// to handle cases when Fw Key FFS file not present
+//
+// 23 12/10/12 6:09p Alexp
+// Bug fix: InSmmFunction() the Key pointer gKeyBuf was to updated to Key
+// in SMM region
+//
+// 21 12/07/12 4:08p Alexp
+// disable debug crypto traces in SMM
+//
+// 20 11/29/12 3:10p Alexp
+// Pkcs7Verify()-
+// Fix error checking for input **Data parameter : Data == NULL
+//
+// 18 11/16/12 5:10p Alexp
+// EIP#105015: Add handling of x509 format for Platform FW Key in FFS
+// files
+//
+// 16 8/28/12 12:33p Alexp
+// UEFI 2.3.1. ErrataC.
+// Added support for new Hash types
+// defined by a GUID with 'NOPAD' keyword:
+// EFI_HASH_ALGORITHM_SHA1_NOPAD_GUID
+// EFI_HASH_ALGORITHM_SHA256_NOPAD_GUID
+//
+// 15 8/22/12 4:28p Alexp
+// Added support in Pkcs7Parse() for new operations:
+// Pkcs7CertValidateGetSignerKey - n-modulus of Signer key
+// Pkcs7CertGetMatchInCertChain - true if found leaf cert matching
+// to
+// trust cert
+// Pkcs7CertValidateGetCAKey, - n-modulus of CA key if detected
+// in
+// x509 chain
+// Pkcs7GetCAKey, Pkcs7GetSignerKey
+//
+// 12 7/23/12 4:12p Alexp
+// Pkcs7Verify:
+// Bug Fix. For condition:Pkcs7CertValidateGetMatchInCertChain return
+// success if leaf cert is found. Before code fell down testing
+// certificate and could return error potentially misleading Caller of this
+// function.
+//
+// 11 7/18/12 8:57p Alexp
+// Pkcs7Verify
+// fix bug - "reason" var was used uninitialized
+//
+// 10 5/04/12 9:49a Alexp
+// [TAG] EIP89280
+// [Category] Improvement
+// [Description] When secure boot enable with secure flash disable, in
+// Security page of setup menu same items will exist twice
+// Fix: Install Crypto Protocols even if Root FW Key not found (brought in
+// by Sec Flash module)
+// [Files] cryptoDxe.c
+//
+// 9 4/11/12 5:27p Alexp
+// Add new operand within Pkcs7Validate:
+// Pkcs7CertValidateGetMatchInCertChain
+//
+// 7 3/02/12 10:43a Alexp
+// Remove dependency on SDL Token FWKEY_FORMAT to determine format of PR
+// Key file
+// Try different Ffs GUIDs to select proper Key format: SHA or RSA
+//
+// 6 2/29/12 4:04p Alexp
+// 1. Add VerifyKey
+// 2. Fix GetKey (API call will be deprecated as not needed) to move PR
+// Key from file to local storage
+// 3. Use FWKEY_FORMAT to process VerifyKey according to file format. Hash
+// input RSA2048 key for comparison if PR Key stored as Hash
+//
+// 5 11/14/11 12:01p Alexp
+// InSmmFunction()->InstallMultipleProtocols() Change the HAndle argument
+// from ImageHandle to a DummyHandle=NULL
+//
+// 4 6/30/11 5:45p Alexp
+// GetRawImage: added freepool(HandleBuffer)
+//
+// 3 6/27/11 5:30p Alexp
+// removed commented out lines
+//
+// 2 6/22/11 5:46p Alexp
+// update deafult Crypto trace level
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 7 6/10/11 6:21p Alexp
+// added new Pkcs7 parse Operation: Pkcs7CertValidateGetSignerKeyHash
+//
+// 6 6/09/11 9:57a Alexp
+// always parse PKCS7 cert
+//
+// 5 5/18/11 1:18p Alexp
+// edited text in func headers
+//
+// 4 5/17/11 12:53p Alexp
+// fix WDK Level4 compiler warnings
+//
+// 3 5/11/11 7:38p Alexp
+// remove set trace level call. If needed, modify Sdl token in Crypto Src
+//
+// 2 5/10/11 6:55p Alexp
+// use external Guid variable declarations
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 10 4/22/11 4:20p Alexp
+// cleaned up CryptoGetRawImage
+//
+// 9 4/18/11 7:09p Alexp
+//
+// 8 4/11/11 12:52p Alexp
+// remove ASN1 as possible Key buf format.
+//
+// 7 4/05/11 6:31p Alexp
+// remove content from GetKey. We may add get FwSig key in later
+// revisions
+//
+// 6 3/31/11 6:14p Alexp
+// hashing of SpcIndirect data is done inside Pkcs Validate
+//
+//
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include "Setup.h"
+#include "AmiCertificate.h"
+#include <Protocol\AmiDigitalSignature.h>
+#include <Protocol\Hash.h>
+
+#include <cryptlib.h>
+
+#include <Protocol\SmmBase.h> // used for SMM Malloc
+
+//
+// Global variables
+//
+extern EFI_BOOT_SERVICES *pBS;
+extern EFI_RUNTIME_SERVICES *pRS;
+
+static EFI_GUID gPRKeyGuid = PR_KEY_GUID;
+
+// The ptr to a buffer containing the Fw Platform Key
+// Key Image is copied from .ffs to a local buffer.
+// It is a safe location in case of AmiSig running in SMM
+static CRYPT_HANDLE gKey = {{0},0,NULL};
+
+// Second part of the Public key, public exponent (e),
+// must be hardwired in the FW elsewhere(recommended value of e=65537).
+//
+// SDL Hardwired value of publicExponent--e
+const UINT8 KeyE[] = {E_CONST}; // 0x10001
+const UINT32 LenE = sizeof(KeyE);
+const INT32 saltlen = PSS_SIG_SALTLEN; // 8
+static UINT8 Rsa2048Sig[DEFAULT_RSA_SIG_LEN];
+
+// Pkcs7 Certificate private var
+//struct pkcs7_signed_data_st* PKCS7cert = NULL;
+// Mutex to control Memory reset during atomic Pkcs7 operations
+static UINT8 MutexLock = RESET;
+
+//----------------------------------------------------------------------------
+// Crypto Function prototypes
+//----------------------------------------------------------------------------
+EFI_STATUS
+Pkcs1Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CRYPT_HANDLE *PublicKey,
+ IN CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+ );
+
+EFI_STATUS
+Pkcs7Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize,
+ IN UINT8 Operation,
+ IN UINT32 Flags
+ );
+
+EFI_STATUS
+Hash(
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN Num_elem,
+ IN CONST UINT8 *Addr[],
+ IN CONST UINTN *Len,
+ OUT UINT8 *Hash
+ );
+
+EFI_STATUS
+GetKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ OUT CRYPT_HANDLE *Key,
+ IN EFI_GUID *AlgId,
+ IN UINTN KeyLen,
+ IN UINT32 Flags
+ );
+
+EFI_STATUS
+VerifyKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN EFI_GUID *AlgId,
+ IN CRYPT_HANDLE *Key
+ );
+//----------------------------------------------------------------------------
+// Crypto Protocol Identifiers
+//----------------------------------------------------------------------------
+AMI_DIGITAL_SIGNATURE_PROTOCOL mAmiSig = {
+ Pkcs1Verify,
+ Pkcs7Verify,
+ Hash,
+ GetKey,
+ VerifyKey
+};
+
+//----------------------------------------------------------------------------
+// Crypto Function Implementation
+//----------------------------------------------------------------------------
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Hash
+//
+// Description: Allows creating a hash of an arbitrary message digest using one or more hash algorithms
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+// num_elem Number of blocks to be passed via next argument:addr[]
+// addr[] Pointer to array of UINT8* addresses of data blocks to be hashed
+// len Pointer to array of integers containing length of each block listed by addr[]
+// Hash Holds the resulting hash computed from the message.
+//
+// Output:
+// EFI_SUCCESS Hash returned successfully.
+// EFI_INVALID_PARAMETER Message or Hash is NULL
+// EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
+// driver.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+Hash(
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN num_elem,
+ IN CONST UINT8 *addr[],
+ IN CONST UINTN *len,
+ OUT UINT8 *Hash
+ )
+{
+ BOOLEAN bSha1 = FALSE, bSha256 = FALSE;
+ UINT32 HashLen=SHA256_DIGEST_SIZE;
+
+// Support only SHA1 & SHA256 hashes
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1Guid) ||
+ !guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1NoPadGuid))
+ {
+ bSha1 = TRUE;
+ HashLen = SHA1_DIGEST_SIZE;
+ }
+ else
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256Guid) ||
+ !guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256NoPadGuid))
+ {
+ bSha256 = TRUE;
+ HashLen = SHA256_DIGEST_SIZE;
+ }
+ else
+ return EFI_UNSUPPORTED;
+
+ MemSet(Hash, HashLen, 0);
+ if(bSha1)
+ sha1_vector(num_elem, addr, len, Hash);
+ else
+ sha256_vector(num_elem, addr, len, Hash);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Pkcs7Verify
+//
+// Description: Verifies the validity of a PKCS#7 signed data as described in "PKCS #7: Cryptographic
+// Message Syntax Standard".
+// Function perfors several operations on input Pkcs7 certificate
+// based on the input Operation argument
+// 1. Verifies validity of the signature contained inside the Certificate
+// This function decrypts the signature with the Public key from the Signer certificate
+// and then compares the decrypted value to the input Data
+// 2. Extracts the Signer certificate in format of x509
+// 3. Extracts Root CA certificate that used to sign the Signer certificate.
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// P7Data Pointer to the PKCS#7 DER encoded message to verify.
+// P7Size Size of the PKCS#7 message in bytes.
+// TrustedCert Pointer to a trusted/root X509 certificate encoded in DER, which
+// is used for certificate chain verification.
+// CertSize Size of the trusted certificate in bytes.
+// Data Pointer to the content to be verified/returned at
+// DataSize Size of Data in bytes
+// Operation Specifies different tasks to perform:
+// 0-Function presence check. Must return EFI_SUCCESS
+// 1-Validate Certificate
+// 2-Return Signer Certificate in *Data. Performs cert chaining and time based validity tests
+// 3-Return Root CA certificate referenced by Signer. Used to compare with Trusted Cert in FW
+// 4-Validate Root Certificate
+// 5-Validate Signer Certificate Chain
+// 6-Return Signature Digest Algorithm
+// 7-Validate Certificate, return Root CA Certificate
+// 8-Validate Certificate, return Signer Certificate
+// 9-Validate Certificate, return Signer Key Hash (SHA256)
+// 10-Validate Certificate and return Success if match is found between Trust and any leaf certificates in the Signer chain
+// 11-Validate Certificate, return ptr in *Data to n-modulus of a Signer Key
+// 12-Return Success if match is found between Trust and any leaf certificates in the Signer chain
+// 13-Validate Certificate, return ptr in *Data to n-modulus of a Root CA Key
+// 14-Return ptr in *Data to n-modulus of a Root CA Key
+// 15-Return ptr in *Data to n-modulus of a Signer Key
+// 16-Validate TimeStamp certificate chain in Pkcs7 Certificate
+// 17-255 reserved values
+// Flags Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// EFI_SUCCESS The specified PKCS#7 signed data is valid
+// EFI_SECURITY_VIOLATION Invalid PKCS#7 signed data.
+// EFI_ACCESS_DENIED The Trusted certificate does not have a match in SignedData.certificate store.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+Pkcs7Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize,
+ IN UINT8 Operation,
+ IN UINT32 Flags
+ )
+{
+ EFI_STATUS Status;
+ INTN err, reason;
+ static struct pkcs7_signed_data_st* PKCS7cert;
+ struct x509_certificate *x509SignCert;
+ struct x509_certificate *x509TrustCert;
+ UINT8 *x509SignCertPtr, *x509RootCertPtr;
+ UINTN SignCert_len, CARootCert_len;
+ struct pkcs7_cert_revoke_info revokeInfo;
+ EFI_CERT_X509_SHA256 *revokeCert;
+
+// Mutex functionality:
+/*
+Structure mutex
+Mutual exclusion (mutex) semaphore locking mechanism used to serialise interthread intraprocess activities.
+*/
+#if PKCS7_MUTEX_LOCK == 1
+ switch(Flags & 0x3) {
+ case RESET:
+ ResetCRmm(); // first time needs mem clean
+ MutexLock = RESET;
+ PKCS7cert = NULL;
+ break;
+
+ case LOCK:
+ ResetCRmm(); // first time needs mem clean
+ MutexLock = LOCK;
+ PKCS7cert = NULL;
+ break;
+
+ case RELEASE: // clear memory after execute routines
+ if(MutexLock == RESET)
+ ResetCRmm();
+ MutexLock = RESET;
+ break;
+
+ case KEEP:
+ if(MutexLock == RESET)
+ ResetCRmm();
+ break;
+
+ default:
+ ResetCRmm();
+ }
+#else
+ PKCS7cert = NULL;
+ ResetCRmm();
+#endif
+/*
+ Notes of implementation:
+
+ IN order to allocate the Pool for returned Cert (Signer or CA)
+ -run getCert with Size 0 -> it will return real cert size
+ -allocate buffer of Size and re-run with new size
+ OR caller is responsible for freeng the Data buffer
+ OR caller always allocates sufficient size == Trusted Cert + 1k
+
+ GetSignerCert
+ parse Pkcs7 to *Pkcs7cert
+ get SignerName from SignerInfo.serialName
+ find x509 cert matching Signer name
+ GetCACert
+ run GetSignerCert
+ run cert chain valid for that cert
+
+ ValidateSignCert - internal Cert validation, returns Root CA Cert ptr
+ ValidateTrustCert - external Trust Cert validation, returns Sign Cert ptr
+
+*/
+ err = -1;
+ reason=0;
+
+ switch(Operation){
+ case Pkcs7Arg0:
+ Status = EFI_SUCCESS;
+ err = 0;
+ break;
+// Validate Digest and returns Root CA cert or Signer Cert
+ case Pkcs7CertGetMatchInCertChain:
+ case Pkcs7CertValidateGetMatchInCertChain: // obsolete
+ reason = -1; // non-0 reason argument forces Pkcs7_Chain_Validate to scan for matching Cert in the Chain if other checks failed
+ case Pkcs7CertValidate:
+ case Pkcs7CertValidateGetCAKey:
+ case Pkcs7CertValidateGetCACert:
+ case Pkcs7CertValidateGetSignerKey:
+ case Pkcs7CertValidateGetSignerCert:
+ case Pkcs7CertValidateGetSignerKeyHash:
+ case Pkcs7TimeStampCertValidateGet:
+ if(Data == NULL || DataSize == NULL)
+ break;
+ case Pkcs7ValidateRootCert:
+ if (!PKCS7cert) PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (!PKCS7cert)
+ break;
+ // verify Pkcs7 Signing Cert chain up to the TrustCert...if provided
+ if(TrustedCert && CertSize) {
+ x509TrustCert = x509_certificate_parse(TrustedCert, CertSize);
+ if(x509TrustCert) {
+ err = Pkcs7_x509_certificate_chain_validate_with_timestamp(PKCS7cert, (Operation == Pkcs7TimeStampCertValidateGet), x509TrustCert, NULL, (int*)&reason);
+ } else {
+ // potentially a TimeStamped revocation cert
+ revokeCert = (EFI_CERT_X509_SHA256*)TrustedCert;
+ if(CertSize == sizeof(EFI_CERT_X509_SHA256))
+ revokeInfo.ToBeSignedHashLen = 32;
+ else
+ if(CertSize == sizeof(EFI_CERT_X509_SHA384))
+ revokeInfo.ToBeSignedHashLen = 48;
+ else
+ if(CertSize == sizeof(EFI_CERT_X509_SHA512))
+ revokeInfo.ToBeSignedHashLen = 64;
+ else { // unsupported Hash struct
+ err = -1;
+ break;
+ }
+ revokeInfo.ToBeSignedHash = (UINT8*)&revokeCert->ToBeSignedHash;
+ err = Pkcs7_x509_certificate_chain_validate_with_timestamp(PKCS7cert, FALSE, NULL, &revokeInfo, (int*)DataSize);
+ }
+
+ if(err == -1 ||
+ Operation==Pkcs7CertGetMatchInCertChain ||
+ Operation == Pkcs7ValidateRootCert
+ )
+ break; // break(err=0) if leaf found to match trust cert
+ }
+ // x509SignCert== NULL -> extract SignCert from Pkcs7 crt
+ err = Pkcs7_certificate_validate_digest(PKCS7cert, NULL, (UINT8*)*Data, (UINTN)*DataSize);
+ if(!err) {
+ switch(Operation){
+ //Returns CA Root cert after successfully validating Cert chain and signature digest
+ case Pkcs7CertValidateGetCACert:
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, Data, DataSize, &x509SignCertPtr, (size_t*)&SignCert_len);
+ break;
+ //Returns Signing Key from Cert after successfully validating Cert chain and signature digest
+ case Pkcs7CertValidateGetSignerCert:
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, &x509RootCertPtr, (size_t*)&CARootCert_len, Data, DataSize);
+ break;
+ case Pkcs7CertValidateGetSignerKeyHash:
+ err = Pkcs7_x509_return_signing_Key(PKCS7cert, &x509SignCertPtr, &SignCert_len);
+ if(!err) {
+ Hash(This, &gEfiHashAlgorithmSha256Guid, 1, &x509SignCertPtr, (const UINTN*)&SignCert_len, *Data);
+ *DataSize=SHA256_DIGEST_SIZE;
+ }
+ break;
+ case Pkcs7CertValidateGetSignerKey:
+ err = Pkcs7_x509_return_signing_Key(PKCS7cert, Data, DataSize);
+ break;
+ case Pkcs7CertValidateGetCAKey:
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, Data, DataSize, &x509SignCertPtr, (size_t*)&SignCert_len);
+ if(!err)
+ err = Pkcs7_x509_return_Cert_pubKey(*Data, *DataSize, Data, DataSize);
+ break;
+ case Pkcs7TimeStampCertValidateGet:
+ err = Pkcs7_certificate_validate_timestamp_digest(PKCS7cert, (long*)DataSize);
+ break;
+ }
+ }
+ break;
+
+// returns Ptr within input P7Data DER buffer to RootCA cert or Signing Cert
+ case Pkcs7GetSignerCert:
+ case Pkcs7GetCACert:
+ case Pkcs7GetSignerKey:
+ case Pkcs7GetCAKey:
+ if(Data == NULL || DataSize == NULL) {
+ break;
+ }
+ if (!PKCS7cert) PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (PKCS7cert) {
+ err = Pkcs7_return_cerificate_ptr(PKCS7cert, &x509RootCertPtr, (size_t*)&CARootCert_len, &x509SignCertPtr, (size_t*)&SignCert_len);
+ if(!err) {
+ switch(Operation){
+ case Pkcs7GetSignerCert:
+ *DataSize = SignCert_len;
+ *Data = x509SignCertPtr;
+ break;
+ case Pkcs7GetCACert:
+ *DataSize = CARootCert_len;
+ *Data = x509RootCertPtr;
+ break;
+ case Pkcs7GetCAKey:
+ err = Pkcs7_x509_return_Cert_pubKey(x509RootCertPtr, CARootCert_len, Data, DataSize);
+ break;
+ case Pkcs7GetSignerKey:
+ err = Pkcs7_x509_return_Cert_pubKey(x509SignCertPtr, SignCert_len, Data, DataSize);
+ break;
+ }
+ }
+ }
+ break;
+
+ case x509ValidateCertChain:
+ //Validates Signer certificate's key against Trusted Cert
+ x509SignCert = x509_certificate_parse(P7Data, P7Size);
+ if(TrustedCert && CertSize)
+ x509TrustCert = x509_certificate_parse(TrustedCert, CertSize);
+ if (x509TrustCert && x509SignCert)
+ err = x509_certificate_chain_validate(x509TrustCert, x509SignCert, (int*)&reason);
+ break;
+
+ case Pkcs7GetDigestAlgorithm:
+ // validate input params.
+ if(Data == NULL || DataSize == NULL) {
+ break;
+ }
+ if (!PKCS7cert) PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (PKCS7cert) {
+ err = Pkcs7_return_digestAlgorithm(PKCS7cert, (UINT8*)*Data);
+ if(!err)
+ *DataSize = sizeof(UINT8);
+ }
+ break;
+
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ err = -1;
+ }
+
+// Security concern, memory heap is being cleared on exit
+ if(err)
+ MutexLock = RESET;
+
+#if PKCS7_MUTEX_LOCK == 1
+ if(MutexLock == RESET)
+#endif
+ {
+ ResetCRmm();
+ PKCS7cert = NULL;
+ }
+
+// failed to process
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Pkcs1Verify
+//
+// Description: Function verifies that the specified signature matches the specified hash.
+// Verifies the RSA-SSA signature with EMSA-PKCS1-v1_5 encoding scheme defined in
+// RSA PKCS#1.
+// This function decrypts the signature with the provided key and then compares
+// the decrypted value to the specified hash value
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+// Hash Handle of the hash object to verify.
+// Signature Pointer to the signature data to be verified.
+// SignatureSize The size, in bytes, of the signature data.
+// Flags Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// EFI_SUCCESS The signature is successfully verified.
+// EFI_SECURITY_VIOLATION The signature does not match the given message.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+Pkcs1Verify (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN CRYPT_HANDLE *PublicKey,
+ IN CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+ )
+{
+ EFI_STATUS Status;
+ INTN err;
+ struct crypto_rsa_key *key = NULL;
+ UINT16 Size = (UINT16)(PublicKey->BlobSize);
+ size_t *sig_len=(size_t*)&SignatureSize;
+ INT32 modulus_bitlen = DEFAULT_RSA_SIG_LEN << 3;
+ UINT32 HashLen;
+
+// Only supporting RSASSA_PKCS1V15 & PSS signature types
+ if(!((Flags & EFI_CRYPT_RSASSA_PKCS1V15) ||
+ (Flags & EFI_CRYPT_RSASSA_PSS)) )
+ return EFI_INVALID_PARAMETER;
+
+ if(!PublicKey || !Hash || !Signature)
+ return EFI_INVALID_PARAMETER;
+
+ ResetCRmm();
+ MutexLock = RESET;
+
+// For now Public Key is supported in 2 formats: RAW 256 bytes and ASN.1 Integer
+ if(!guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid))
+ key = crypto_import_rsa2048_public_key(PublicKey->Blob, Size, (UINT8*)&KeyE, LenE);
+ else
+ return EFI_INVALID_PARAMETER;
+
+// 2 hash types supporte: SHA1 & SHA256
+ if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha256Guid))
+ HashLen = SHA256_DIGEST_SIZE;
+ else if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha1Guid))
+ HashLen = SHA1_DIGEST_SIZE;
+ else
+ HashLen = SHA256_DIGEST_SIZE;
+
+ if(key == NULL )
+ err = -1;
+ else
+ err = crypto_rsa_exptmod((const UINT8*)Signature, (size_t)SignatureSize, (UINT8*)&Rsa2048Sig, sig_len, key, 0);
+
+// locate Hash inside the decrypted signature body and compare it with given Hash;
+ if(!err) {
+ if(Flags & EFI_CRYPT_RSASSA_PKCS1V15)
+ {
+ // Validate PKCS#1 Padding
+// err = pkcs_1_v1_5_decode((const UINT8 *)&Hash->Blob, HashLen, (const UINT8 *)&Rsa2048Sig, (unsigned long)*sig_len);
+ err = MemCmp((void*)(UINTN)Hash->Blob, (void*)(UINTN)((UINT32)(UINTN)Rsa2048Sig + (UINT32)(*sig_len - HashLen)), HashLen);
+ }
+ else //(Flags & EFI_CRYPT_RSASSA_PSS))
+ // Validate PKCS_1 PSS Signature: padding & hash
+ err = pkcs_1_pss_decode((UINT8*)Hash->Blob, HashLen,(const unsigned char *)&Rsa2048Sig, (unsigned long)*sig_len,
+ saltlen, modulus_bitlen);
+ }
+
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+// Security concern, memory heap is being cleared on exit
+ ResetCRmm();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CryptoGetFwKey
+//
+// Description: Passes FwKey info from a Hob to an external Key handler structure
+//
+// Input: Key - ptr to the buffer to hold the target key parameters
+//
+// Output: Status
+//
+// EFI_NOT_FOUND - Can't find the Key Hob
+// EFI_INVALID_PARAMETER - Wrong KeyID
+// EFI_LOAD_ERROR - Load fail.
+// EFI_SUCCESS - Load success.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CryptoGetFwKey (
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN CRYPT_HANDLE *Key
+)
+{
+ EFI_STATUS Status=EFI_NOT_FOUND;
+ FW_KEY_HOB *pFwKeyHob;
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ if(!Key) return EFI_INVALID_PARAMETER;
+
+ pFwKeyHob = GetEfiConfigurationTable(SystemTable, &HobListGuid);
+ if (pFwKeyHob!=NULL) {
+ Status = FindNextHobByGuid(&gPRKeyGuid, &pFwKeyHob);
+ if(!EFI_ERROR(Status)) {
+// make sure the Key buffer is mapped to FV_BB address space
+/*
+ if(!((UINT32)pFwKeyHob->KeyAddress > FV_BB_BASE &&
+ (UINT64)((UINT32)pFwKeyHob->KeyAddress+pFwKeyHob->KeySize) <
+ (UINT64)(FV_BB_BASE+(UINT64)FV_BB_BLOCKS*FLASH_BLOCK_SIZE))) {
+ return EFI_NOT_FOUND;
+*/
+ Key->Blob = (UINT8*)(UINT32)pFwKeyHob->KeyAddress;
+ Key->BlobSize = pFwKeyHob->KeySize;
+ Key->AlgGuid = pFwKeyHob->KeyGuid;
+ }
+ }
+
+ TRACE(((UINTN) -1,"Get Key File %g: %r\n(%lx, %dbytes)=%X,%X\n", Key->AlgGuid, Status, Key->Blob, Key->BlobSize, Key->Blob[0], Key->Blob[1]));
+
+ return Status;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetKey
+//
+// Description: Return Firmware Signing Key from a local storage
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE_PROTOCOL instance.
+// Key ptr to the buffer to hold the target key
+// AlgId Key GUID
+// KeyLen Length of the target Key buffer
+// Flags Specifies additional flags to further customize the GetKey behavior.
+// Output:
+// EFI_SUCCESS
+// EFI_ACCESS_DENIED The key could not be located
+// EFI_INVALID_PARAMETER Wrong KeyID
+// BUFFER_TOO_SMALL The Key->BlobSize will contain the size of the buffer to be prepared
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+GetKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ OUT CRYPT_HANDLE *Key,
+ IN EFI_GUID *AlgId,
+ IN UINTN KeyLen,
+ IN UINT32 Flags
+ )
+{
+ if(!AlgId || !Key)
+ return EFI_INVALID_PARAMETER;
+
+// Guid must match one of the valid keys we can use in Sig verification.
+ if(guidcmp(AlgId, &gPRKeyGuid))
+ return EFI_UNSUPPORTED;
+
+ if(gKey.Blob && gKey.BlobSize){
+
+// make sure the Key buffer is mapped to FV_BB address space
+/* if(!((UINT32)gKey.Blob > FV_BB_BASE &&
+ (UINT64)((UINT32)gKey.Blob+gKey.BlobSize) <
+ (UINT64)(FV_BB_BASE+(UINT64)FV_BB_BLOCKS*FLASH_BLOCK_SIZE)))
+ return EFI_NOT_FOUND;
+*/
+ Key->BlobSize = gKey.BlobSize;
+ Key->AlgGuid = gKey.AlgGuid;
+ if(Key->Blob) {
+ if(KeyLen < gKey.BlobSize)
+ return EFI_BUFFER_TOO_SMALL;
+ else
+ MemCpy(Key->Blob, gKey.Blob, gKey.BlobSize);
+ } else
+ Key->Blob = gKey.Blob;// upd address to int buffer
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: VerifyKey
+//
+// Description: Function compares the input PublicKey against
+// Platform Signing Key (PK) image in the flash.
+//
+// Input:
+// This Pointer to the AMI_DIGITAL_SIGNATURE protocol instance.
+// KeyAlgorithm Points to the EFI_GUID which identifies the PKpub algorithm to use.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+//
+// Output:
+// EFI_SUCCESS The Key is successfully verified.
+// EFI_SECURITY_VIOLATION The Key does not match current FW key.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+VerifyKey (
+ IN CONST AMI_DIGITAL_SIGNATURE_PROTOCOL *This,
+ IN EFI_GUID *AlgId,
+ IN CRYPT_HANDLE *Key
+ )
+{
+ EFI_STATUS Status;
+ CRYPT_HANDLE PubKeyHndl;
+ UINT8 Hash[SHA256_DIGEST_SIZE]={0};
+ UINT8 *KeyFfs, *KeyCmp;
+ UINTN KeyLen;
+ UINT32 Flags=0;
+ INTN err;
+
+ if(!AlgId || !Key || !Key->Blob)
+ return EFI_INVALID_PARAMETER;
+
+// Guid must match one of the valid keys we can use in Sig verification.
+ if(guidcmp(AlgId, &gPRKeyGuid))
+ return EFI_UNSUPPORTED;
+
+// Get PRKey
+ PubKeyHndl.Blob = NULL;
+ PubKeyHndl.BlobSize = 0;
+ Status = GetKey(NULL, &PubKeyHndl, AlgId, 0, Flags);
+ if(!EFI_ERROR(Status))
+ {
+ KeyFfs = PubKeyHndl.Blob;
+ KeyLen = PubKeyHndl.BlobSize;
+ KeyCmp = Key->Blob;
+
+ // If FwKey is Hash of Rsa2048 Key and Key->Algo is Rsa2048 -
+ // prepare Key for SHA256 Hash compare
+ if(!guidcmp(&Key->AlgGuid, &gEfiCertRsa2048Guid))
+ {
+ if(!guidcmp(&PubKeyHndl.AlgGuid, &gEfiCertSha256Guid))
+ {
+ KeyCmp = Hash;
+ KeyLen = SHA256_DIGEST_SIZE;
+ sha256_vector(1, (const UINT8**)&Key->Blob, (const UINTN*)&Key->BlobSize, Hash);
+ } else
+ // if FwKey is x509 and Key->Algo - gEfiCertRsa2048Guid:
+ // derive nModulus from x509 Key Cert for comparison
+ if(!guidcmp(&PubKeyHndl.AlgGuid, &gEfiCertX509Guid))
+ {
+ KeyFfs = &Rsa2048Sig[0];
+ KeyLen = DEFAULT_RSA_KEY_MODULUS_LEN;
+ ResetCRmm();
+ err = Pkcs7_x509_return_Cert_pubKey((UINT8*)PubKeyHndl.Blob, (UINTN)PubKeyHndl.BlobSize, &KeyFfs,&KeyLen);
+ ResetCRmm();
+ if(err) return EFI_SECURITY_VIOLATION;
+ }
+ }
+ err = MemCmp(KeyFfs, KeyCmp, KeyLen);
+
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+ }
+ return Status;
+}
+//----------------------------------------------------------------------------
+// END of Crypto DXE Function definitions
+//----------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DummyHandle = NULL;
+ UINT8 *pKey;
+
+ TRACE(((UINTN) -1,"Init Crypto API in SMM\n"));
+ //
+ // Init Crypto lib internal state
+ //
+ RuntimeCryptLibConstructorInSmm(ImageHandle, SystemTable);
+ //
+ // Update Crypto debug traces level
+ //
+#ifdef EFI_DEBUG
+// wpa_set_trace_level(CRYPTO_trace_level);
+#endif
+ //
+ // Get location of PRKey from .ffs
+ // ReadFfs/FindHob are preboot services whereas Key needs to be available during EFI runtime
+ //
+ gKey.Blob = NULL;
+ Status = CryptoGetFwKey(SystemTable, &gKey);
+ if(!EFI_ERROR(Status) && gKey.Blob) {
+ // re-allocate buffer in runtime mem
+ pKey = gKey.Blob; // preserve the pointer
+ Status = pSmmBase->SmmAllocatePool(pSmmBase, EfiRuntimeServicesData, gKey.BlobSize, (void**)&pKey);
+ ASSERT_EFI_ERROR (Status);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(pKey, gKey.Blob, gKey.BlobSize);
+ gKey.Blob = pKey;
+ }
+ }
+ if(EFI_ERROR(Status))
+ gKey.Blob = NULL;
+
+ TRACE((TRACE_ALWAYS,"Init: GetKey %r (addr %x(%X, %X), %d bytes)\n", Status, gKey.Blob, gKey.Blob[0], gKey.Blob[1], gKey.BlobSize));
+
+///////////////////////////////////////////////////////////////////////////////////
+// Install the SMM clone of Crypto protocols
+///////////////////////////////////////////////////////////////////////////////////
+ return pBS->InstallMultipleProtocolInterfaces (
+ &DummyHandle,
+ &gAmiSmmDigitalSignatureProtocolGuid, &mAmiSig,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NotInSmmFunction
+//
+// Description: This function is called from outside of SMM during SMM registration.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotInSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ UINT8 *pKey;
+
+ TRACE(((UINTN) -1,"Init Crypto API NOT in SMM\n"));
+ //
+ // Init Crypto lib internal state
+ //
+ RuntimeCryptLibConstructor(ImageHandle, SystemTable);
+ //
+ // Update Crypto debug traces level
+ //
+#ifdef EFI_DEBUG
+ wpa_set_trace_level(CRYPTO_trace_level);
+#else
+ wpa_set_trace_level(0);
+#endif
+ //
+ // Get location of PRKey from .ffs
+ // ReadFfs/FindHob are preboot services whereas Key needs to be available during EFI runtime
+ //
+ gKey.Blob = NULL;
+ Status = CryptoGetFwKey(SystemTable, &gKey);
+ if(!EFI_ERROR(Status) && gKey.Blob) {
+ // re-allocate buffer in runtime mem
+ pKey = gKey.Blob; // preserve the pointer
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, gKey.BlobSize, (void**)&pKey);
+ ASSERT_EFI_ERROR (Status);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(pKey, gKey.Blob, gKey.BlobSize);
+ gKey.Blob = pKey;
+ }
+ }
+ if(EFI_ERROR(Status))
+ gKey.Blob = NULL;
+
+ TRACE((TRACE_ALWAYS,"Init: GetKey %r (addr %x(%X, %X), %d bytes)\n", Status, gKey.Blob, gKey.Blob[0], gKey.Blob[1], gKey.BlobSize));
+
+
+///////////////////////////////////////////////////////////////////////////////
+//
+// Install the DXE Crypto protocols
+//
+///////////////////////////////////////////////////////////////////////////////
+ return pBS->InstallMultipleProtocolInterfaces (
+ &ImageHandle,
+ &gAmiDigitalSignatureProtocolGuid, &mAmiSig,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CryptoDxe_Init
+//
+// Description: Entry point of Crypto DXE driver
+//
+// Input: EFI_HANDLE ImageHandle,
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CryptoDxe_Init (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ //
+ // Install DXE & SMM Crypto Services
+ //
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoDxe.dxs b/Core/EM/CryptoPkg/CryptoDxe.dxs
new file mode 100644
index 0000000..ba16a62
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoDxe.dxs
@@ -0,0 +1,53 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.dxs 1 6/13/11 5:19p Alexp $
+//
+// $Revision: 1 $
+//
+// $Date: 6/13/11 5:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoDxe.dxs $
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 1 3/10/11 4:52p Alexp
+//
+// 1 2/18/11 5:42p Alexp
+//
+//**********************************************************************
+#include <Protocol/SmmBase.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoPei.c b/Core/EM/CryptoPkg/CryptoPei.c
new file mode 100644
index 0000000..1945986
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoPei.c
@@ -0,0 +1,800 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.c 15 8/01/13 6:27p Alexp $
+//
+// $Revision: 15 $
+//
+// $Date: 8/01/13 6:27p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.c $
+//
+// 15 8/01/13 6:27p Alexp
+// Comment out a check for FwKey location to be mapped to Flash FV_BB
+// In some cases FindFFS for FwKey may return a location outside of Flash
+// space.
+// Will have the logic fixed in the next label.
+//
+// 14 7/01/13 5:24p Alexp
+// CryptoPei_Init(): fix addr typecasting for pFwKeyHob->KeyAddress
+//
+// 13 6/20/13 1:55p Alexp
+// Impove FwKey handling. CryptoPEI pass FwKey location to Dxe via Hob
+// Add mor parameter checking including
+// check for FwKey location to be mapped to Flash FV_BB
+//
+// 12 5/23/13 12:04p Alexp
+// Add dependency on PKCS7_PEI_Support switch to turn off Pkcs7 support in
+// CryptoPEI. Saves ~8kb of space
+//
+// 11 12/28/12 3:05p Alexp
+// CryptoGetRawImage(): calculate raw Key size inside FwKey ffs file
+//
+// 10 12/19/12 10:31a Alexp
+// code modify to meet "cppcheck" style & performance suggestions
+//
+// 8 11/15/12 9:28a Alexp
+// update Pkcs7Verify help header
+//
+// 7 11/14/12 6:28p Alexp
+// rename ppPS to gPeiServices in order to keep backward compatibility for
+// older Secure Flash eModules
+//
+// 6 11/13/12 11:50a Alexp
+// EIP#105015: Add Pkcs#7 Cert Verification function in Crypto PPI
+// Add handling of x509 formatted FW Key in FFS files
+//
+// 5 7/25/12 10:00a Alexp
+// cleaned comments in Hash Hdr
+//
+// 4 3/12/12 4:11p Alexp
+// do not install Crypto PPI on S3 resume.
+//
+// 3 3/02/12 10:43a Alexp
+// Remove dependency on SDL Token FWKEY_FORMAT to determine format of PR
+// Key file
+// Try different Ffs GUIDs to select proper Key format: SHA or RSA
+//
+// 2 2/29/12 4:01p Alexp
+// 1. Use SDL Token FWKEY_FORMAT to define format of PR Key file: Hash or
+// RSA2048
+// 2. Modify VerifyKey to account for PR Key in SHA256 format
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 10 4/22/11 4:19p Alexp
+// fix GetRaw file
+//
+// 9 4/18/11 7:09p Alexp
+//
+// 8 4/11/11 12:53p Alexp
+// remove Verify Capsule from Crypto PPI. Function moved to SecRecovery.c
+//
+// 7 4/08/11 1:33p Alexp
+// This revision Supports single PK(FwSign) Ffs file with SigDb with
+// multiple Keys
+//
+// 6 4/05/11 6:31p Alexp
+//
+// 5 3/21/11 6:58p Alexp
+//
+// 4 3/15/11 12:48p Alexp
+//
+// 3 3/14/11 3:26p Alexp
+// add provision to handle multiple Platform Signing keys.
+// rom may containg multiple Keys as FFS files with same Guid
+//
+// 2 3/11/11 6:51p Alexp
+//
+// 1 3/10/11 4:52p Alexp
+//
+// 2 2/28/11 6:46p Alexp
+//
+// 1 2/18/11 5:42p Alexp
+//
+//**********************************************************************
+#include <Token.h>
+#include <AmiPeiLib.h>
+#include "PPI\LoadFile.h"
+#include <Protocol\Hash.h>
+#include <PPI\CryptoPPI.h>
+#include "AmiCertificate.h"
+
+#include <cryptlib.h>
+
+//
+// Global variables
+//
+
+// Although ShaXXXGuid global variables are defined in EDK's EdkProtocol Lib, but linking it adds additional 20k in debug mode.
+static EFI_GUID gEfiHashAlgorithmSha1Guid = EFI_HASH_ALGORITHM_SHA1_GUID;
+static EFI_GUID gEfiHashAlgorithmSha256Guid = EFI_HASH_ALGORITHM_SHA256_GUID;
+static EFI_GUID gPKeyGuid = PR_KEY_GUID;
+
+// Hardwired at Build time. Supported formats: RSA2048, HASH256 Key Certs
+static EFI_GUID gPKeyFileRsa2048Guid = PR_KEY_FFS_FILE_RAW_GUID;
+static EFI_GUID gPKeyFileSha256Guid = PR_KEY_FFS_FILE_SHA256_GUID;
+static EFI_GUID gPKeyFileX509Guid = PR_KEY_FFS_FILE_X509_GUID;
+
+static EFI_GUID gEfiCertSha256Guid = EFI_CERT_SHA256_GUID;
+static EFI_GUID gEfiCertRsa2048Guid = EFI_CERT_RSA2048_GUID;
+static EFI_GUID gEfiCertX509Guid = EFI_CERT_X509;
+
+static EFI_GUID *gKeyFileGuid [] = {
+ &gPKeyFileX509Guid,
+ &gPKeyFileRsa2048Guid,
+ &gPKeyFileSha256Guid,
+ NULL
+};
+static EFI_GUID *gKeyTypeGuid [] = {
+ &gEfiCertX509Guid,
+ &gEfiCertRsa2048Guid,
+ &gEfiCertSha256Guid,
+ NULL
+};
+
+EFI_PEI_SERVICES **gPeiServices;
+FW_KEY_HOB *pFwKeyHob = NULL;
+//
+// SDL defined Public Exponent E of RSA Key.
+//
+const UINT8 KeyE[] = {E_CONST}; // 0x10001
+const UINT32 LenE = sizeof(KeyE);
+// PKCS_1 PSS Signature constatnt. Size of the Salt (random data) field in PSS signature.
+const INT32 saltlen = PSS_SIG_SALTLEN; // 8
+static UINT8 DecriptedSig[DEFAULT_RSA_SIG_LEN];
+//----------------------------------------------------------------------------
+// Crypto Function prototypes
+//----------------------------------------------------------------------------
+EFI_STATUS
+PeiHash (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN num_elem,
+ IN CONST UINT8 *addr[],
+ IN CONST UINTN *len,
+ OUT UINT8 *Hash
+ );
+
+EFI_STATUS
+PeiPkcs7Verify (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize
+ );
+
+EFI_STATUS
+PeiVerifySig
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN PEI_CRYPT_HANDLE *PublicKey,
+ IN PEI_CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+);
+
+EFI_STATUS
+PeiGetKey
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ );
+
+EFI_STATUS
+PeiVerifyKey
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ );
+
+//----------------------------------------------------------------------------
+// Crypto Protocol Identifiers
+//----------------------------------------------------------------------------
+static EFI_GUID gAmiDigitalSignaturePPIGuid = AMI_DIGITAL_SIGNATURE_PPI_GUID;
+
+AMI_CRYPT_DIGITAL_SIGNATURE_PPI mSigPeiInitPpi = {
+ PeiHash,
+ PeiVerifyKey,
+ PeiVerifySig,
+ PeiGetKey,
+ PeiPkcs7Verify
+};
+
+//static
+EFI_PEI_PPI_DESCRIPTOR mPpiSigListVariable = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gAmiDigitalSignaturePPIGuid,
+ &mSigPeiInitPpi
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CryptoGetRawImage
+//
+// Description: Loads binary from RAW section of X firwmare volume
+//
+//
+// Output: Buffer - returns a pointer to allocated memory. Caller
+// must free it when done.
+// Size - returns the size of the binary loaded into the
+// buffer.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CryptoGetRawImage (IN EFI_GUID *FileGuid, IN OUT VOID **Buffer, IN OUT UINTN *Size)
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_HEADER *pFV;
+ UINTN FvNum=0;
+ EFI_FFS_FILE_HEADER *ppFile=NULL;
+
+ if (!Buffer || !Size)
+ return EFI_INVALID_PARAMETER;
+
+ Status = (*gPeiServices)->FfsFindNextVolume (gPeiServices, FvNum, &pFV);
+
+ while(TRUE)
+ {
+ Status = (*gPeiServices)->FfsFindNextFile(gPeiServices, EFI_FV_FILETYPE_ALL, pFV, &ppFile);
+ if(Status == EFI_NOT_FOUND)
+ {
+// FvNum++;
+// Status = (*gPeiServices)->FfsFindNextVolume (gPeiServices, FvNum, &pFV);
+// if(EFI_ERROR(Status)) return Status;
+// continue;
+// !!! the PK Key may only be in FV_BB volume. FvNum=0!!!!
+ return Status;
+ }
+
+ if(guidcmp(&ppFile->Name, FileGuid)==0) break;
+ }
+
+ // hopefully we found the file...now try to read raw data
+ // !!! Keys are uncompressed. There is no much reason to run compression on prime numbers anyway
+ Status = (*gPeiServices)->FfsFindSectionData(gPeiServices, EFI_SECTION_RAW, ppFile, Buffer);
+ if(!EFI_ERROR(Status)) {
+ // Size may need to subtract Section hdr size = 28 bytes sizeof(EFI_FFS_FILE_HEADER + EFI_COMMON_SECTION_HEADER)
+ *Size = FVFILE_SIZE(ppFile)-sizeof(EFI_FFS_FILE_HEADER)-sizeof(EFI_COMMON_SECTION_HEADER);
+ }
+PEI_TRACE(((UINTN)TRACE_ALWAYS, gPeiServices, "Find Key Ffs %r addr=%X (%X,%X), size=%d\n", Status, (UINT32)*Buffer, ((UINT8*)*Buffer)[0], ((UINT8*)*Buffer)[1], *Size));
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiHash
+//
+// Description: Allows creating a hash of an arbitrary message digest using one or more hash algorithms
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// HashAlgorithm Points to the EFI_GUID which identifies the algorithm to use.
+// num_elem Number of blocks to be passed via next argument:addr[]
+// addr[] Pointer to array of UINT8* addresses of data blocks to be hashed
+// len Pointer to array of integers containing length of each block listed by addr[]
+// Hash Holds the resulting hash computed from the message.
+//
+// Output:
+// EFI_SUCCESS Hash returned successfully.
+// EFI_INVALID_PARAMETER Message or Hash is NULL
+// EFI_UNSUPPORTED The algorithm specified by HashAlgorithm is not supported by this
+// driver.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiHash (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN UINTN num_elem,
+ IN CONST UINT8 *addr[],
+ IN CONST UINTN *len,
+ OUT UINT8 *Hash
+ )
+{
+ BOOLEAN bSha1 = FALSE, bSha256 = FALSE;
+ UINT32 HashLen=SHA256_DIGEST_SIZE;
+
+// Support only SHA1 & SHA256 hashes
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1Guid))
+ {
+ bSha1 = TRUE;
+ HashLen = SHA1_DIGEST_SIZE;
+ }
+ else
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256Guid))
+ {
+ bSha256 = TRUE;
+ HashLen = SHA256_DIGEST_SIZE;
+ }
+ else
+ return EFI_UNSUPPORTED;
+
+ MemSet(Hash, HashLen, 0);
+ if(bSha1)
+ sha1_vector(num_elem, addr, len, Hash);
+ else
+ sha256_vector(num_elem, addr, len, Hash);
+
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiVerifySig
+//
+// Description: Function verifies that the specified signature matches the specified hash.
+// This function decrypts the signature with the provided key and then compares
+// the decrypted value to the specified hash value
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+// Hash Handle of the hash object to verify.
+// Signature Pointer to the signature data to be verified.
+// SignatureSize The size, in bytes, of the signature data.
+// Flags Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// EFI_SUCCESS The signature is successfully verified.
+// EFI_SECURITY_VIOLATION The signature does not match the given message.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiVerifySig
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN PEI_CRYPT_HANDLE *PublicKey,
+ IN PEI_CRYPT_HANDLE *Hash,
+ IN VOID *Signature,
+ IN UINTN SignatureSize,
+ IN UINT32 Flags
+ )
+{
+ EFI_STATUS Status;
+ INTN err;
+ struct crypto_rsa_key *key = NULL;
+ UINT16 Size = (UINT16)(PublicKey->BlobSize);
+ size_t *sig_len=(size_t*)&SignatureSize;
+ INT32 modulus_bitlen = DEFAULT_RSA_SIG_LEN << 3;
+ UINT32 HashLen;
+
+// Only supporting RSASSA_PKCS1V15 signature types
+ if(!((Flags & EFI_CRYPT_RSASSA_PKCS1V15) ||
+ (Flags & EFI_CRYPT_RSASSA_PSS)) )
+ return EFI_INVALID_PARAMETER;
+
+ ResetCRmm();
+
+// check Key handle if requested PubKey is a Platform FW Key
+// In this case use the FW key from ffs image
+// validity of the Key must be verified prior to calling VerifySig
+// Guid must match one of the valid keys we can use in PEI Sig verification.
+// For now Public Key is supported in 2 formats: RAW 256 bytes and ASN.1 Integer
+// shall be extended to gPBkey_x509_Guid
+ if(!guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid))
+ key = crypto_import_rsa2048_public_key(PublicKey->Blob, Size, (UINT8*)&KeyE, LenE);
+ else
+ return EFI_INVALID_PARAMETER;
+
+ if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha256Guid))
+ HashLen = SHA256_DIGEST_SIZE;
+ else if(!guidcmp(&Hash->AlgGuid, &gEfiHashAlgorithmSha1Guid))
+ HashLen = SHA1_DIGEST_SIZE;
+ else
+ HashLen = SHA256_DIGEST_SIZE;
+
+ if(key == NULL )
+ err = -1;
+ else
+ err = crypto_rsa_exptmod((const UINT8*)Signature, (size_t)SignatureSize, (UINT8*)&DecriptedSig, sig_len, key, 0);
+// locate Hash inside the decrypted signature body and compare it with given Hash;
+// Should be extended to handle sha1, sha256 hashes. use Hash->AlgGuid to determine the Hash type
+ if(!err)
+ {
+ if(Flags & EFI_CRYPT_RSASSA_PKCS1V15)
+ {
+ // Validate PKCS#1v1.5 Padding
+// err = pkcs_1_v1_5_decode(Hash->Blob, HashLen, (const UINT8 *)&DecriptedSig, (unsigned long)*sig_len);
+// just compare the hash at the end of the sig blob
+ err = MemCmp(Hash->Blob, (void*)((UINT32)DecriptedSig + (UINT32)(*sig_len - HashLen)), HashLen);
+ } else //(Flags & EFI_CRYPT_RSASSA_PSS))
+ // Validate PKCS#1 PSS Signature: padding & hash
+ err = pkcs_1_pss_decode(
+ Hash->Blob, HashLen,
+ (const unsigned char *)&DecriptedSig, (unsigned long)*sig_len,
+ saltlen, modulus_bitlen);
+ }
+
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+// Security concern, memory heap is being cleared on exit
+ ResetCRmm();
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiPkcs7Verify
+//
+// Description: Verifies the validity of a PKCS#7 signed data as described in "PKCS #7: Cryptographic
+// Message Syntax Standard".
+// Function verifies validity of the signature contained inside the Certificate
+// This function decrypts the signature with the Public key from the Signer certificate
+// and then compares the decrypted value to the input Data
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// P7Data Pointer to the PKCS#7 DER encoded message to verify.
+// P7Size Size of the PKCS#7 message in bytes.
+// TrustedCert Pointer to a trusted/root X509 certificate encoded in DER, which
+// is used for certificate chain verification.
+// CertSize Size of the trusted certificate in bytes.
+// Data Pointer to the content to be verified/returned at
+// DataSize Size of Data in bytes
+//
+// Output:
+// EFI_SUCCESS The specified PKCS#7 signed data is valid
+// EFI_SECURITY_VIOLATION Invalid PKCS#7 signed data.
+// EFI_ACCESS_DENIED The Trusted certificate does not have a match in SignedData.certificate store.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiPkcs7Verify (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST UINT8 *P7Data,
+ IN UINTN P7Size,
+ IN CONST UINT8 *TrustedCert,
+ IN UINTN CertSize,
+ IN OUT UINT8 **Data,
+ IN OUT UINTN *DataSize
+ )
+{
+#if CONFIG_PEI_PKCS7 == 1
+
+ EFI_STATUS Status;
+ INTN err, reason;
+ struct pkcs7_signed_data_st* PKCS7cert;
+ struct x509_certificate *x509TrustCert;
+ struct x509_certificate *x509SignCert;
+
+ err = -1;
+ reason = 0;
+ x509SignCert = NULL;
+
+ if((*Data == NULL || DataSize == NULL) ||
+ (!P7Data || P7Size== 0) ||
+ (!TrustedCert || CertSize== 0)
+ )
+ return EFI_INVALID_PARAMETER;
+
+ ResetCRmm();
+
+ PKCS7cert = Pkcs7_parse_Authenticode_certificate(P7Data, P7Size);
+ if (PKCS7cert) {
+ // verify Pkcs7 Signing Cert chain up to the TrustCert...
+ x509TrustCert = x509_certificate_parse(TrustedCert, CertSize);
+ if(x509TrustCert) {
+ err = Pkcs7_x509_certificate_chain_validate(PKCS7cert, x509TrustCert, (int*)&reason);
+ if(!err)
+ err = Pkcs7_certificate_validate_digest(PKCS7cert, x509SignCert, *Data, *DataSize);
+ }
+ }
+
+ // Security concern, memory heap is being cleared on exit
+ ResetCRmm();
+
+ // failed to process
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+ return Status;
+#else
+ return EFI_UNSUPPORTED;
+#endif
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiGetKey
+//
+// Description: Function returns Ptr to a Platform Signing Key (PK) Ffs
+// inside Recovery FV (FV_BB or similar)
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// KeyAlgorithm Points to the EFI_GUID which identifies the PKpub algorithm to use.
+// PublicKey Handle to a key used to return a ptr to a Key. This handle must be identifying a public key.
+//
+// Output:
+// EFI_SUCCESS The Key is successfully returned.
+// EFI_NOT_FOUND The Key not found
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiGetKey (
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ )
+{
+ if(!PublicKey || !KeyAlgorithm)
+ return EFI_INVALID_PARAMETER;
+
+ // now only supporting PKpub key comparison
+ if(guidcmp((EFI_GUID*)KeyAlgorithm, &gPKeyGuid))
+ return EFI_INVALID_PARAMETER;
+
+ if(pFwKeyHob) {
+ PublicKey->AlgGuid = pFwKeyHob->KeyGuid;
+ PublicKey->Blob = (UINT8*)pFwKeyHob->KeyAddress;
+ PublicKey->BlobSize = pFwKeyHob->KeySize;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeiVerifyKey
+//
+// Description: Function compares the input PublicKey against
+// Platform Signing Key (PK) image in the flash.
+//
+// Input:
+// This Pointer to the AMI_CRYPT_DIGITAL_SIGNATURE_PPI instance.
+// KeyAlgorithm Points to the EFI_GUID which identifies the PKpub algorithm to use.
+// PublicKey Handle to a key used for verifying signatures. This handle must be identifying a public key.
+//
+// Output:
+// EFI_SUCCESS The Key is successfully verified.
+// EFI_SECURITY_VIOLATION The Key does not match current FW key.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+PeiVerifyKey
+(
+ IN CONST AMI_CRYPT_DIGITAL_SIGNATURE_PPI *This,
+ IN CONST EFI_GUID *KeyAlgorithm, // reserved to PKPUB_KEY_GUID
+ IN PEI_CRYPT_HANDLE *PublicKey
+ )
+{
+ EFI_STATUS Status;
+ int err;
+ PEI_CRYPT_HANDLE KeyHndl;
+ UINT8 Hash[SHA256_DIGEST_SIZE] = {0};
+ UINT8 *KeyBuf, *PKpubBuffer=NULL;
+ UINT32 KeyLen;
+
+ if(!PublicKey || !KeyAlgorithm || !PublicKey->Blob)
+ return EFI_INVALID_PARAMETER;
+// check Key handle if requested PubKey is a Platform Key PKpub.
+// In this case use PKpub key from ffs image
+ if(guidcmp((EFI_GUID*)KeyAlgorithm, &gPKeyGuid))
+ return EFI_INVALID_PARAMETER;
+
+ Status = PeiGetKey(This, KeyAlgorithm, &KeyHndl);
+ if(!EFI_ERROR(Status)) {
+// only store Sha256 or n-modulus of RSA2048. For x509 cert - compare hash of an entire cert
+// FFS - Sha256 Hash ->
+// Input =Sha258 -> cmp
+// Input =RSA2048 -> Hash n-modulus
+// Input =x509 -> Hash x509 cert
+// FFS - RSA2048 ->
+// Input =RSA2048 -> cmp
+// Input =x509 -> extract n-modulus
+// FFS - x5098 ->
+// Input =x509 -> cmp
+/*
+ PKpubBuffer = KeyHndl.Blob;
+ KeyLen = KeyHndl.BlobSize; // always 256
+ KeyBuf = PublicKey->Blob;
+
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertSha256Guid)) {
+ KeyBuf = Hash;
+ KeyLen = SHA256_DIGEST_SIZE;
+ if(!guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid) ||
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertX509Guid) ) {
+ // SHA256 Hash of RSA Key/x509 cert
+ sha256_vector(1, (const UINT8**)&PublicKey->Blob, (const UINTN*)&PublicKey->BlobSize, Hash);
+ }
+ } else
+ // if FwKey is x509 and Key->Algo - gEfiCertRsa2048Guid:
+ // derive nModulus from x509 Key Cert for comparison
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertRsa2048Guid) &&
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertX509Guid) ) {
+ PKpubBuffer = &Hash[0];
+ KeyLen = DEFAULT_RSA_KEY_MODULUS_LEN;
+ ResetCRmm();
+ err = Pkcs7_x509_return_Cert_pubKey((UINT8*)PublicKey->Blob, (UINTN)PublicKey->BlobSize, &PKpubBuffer, &KeyLen);
+ ResetCRmm();
+ if(err) return EFI_SECURITY_VIOLATION;
+ }
+*/
+ PKpubBuffer = KeyHndl.Blob;
+ KeyLen = KeyHndl.BlobSize; // always 256
+ KeyBuf = PublicKey->Blob;
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertSha256Guid) &&
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertRsa2048Guid)
+ ) {
+ // SHA256 Hash of RSA Key
+ KeyLen = SHA256_DIGEST_SIZE;
+ KeyBuf = Hash;
+ sha256_vector(1, (const UINT8**)&PublicKey->Blob, (const UINTN*)&PublicKey->BlobSize, KeyBuf);
+#if CONFIG_PEI_PKCS7 == 1
+ } else {
+ // if FwKey is x509 and Key->Algo - gEfiCertRsa2048Guid:
+ // derive nModulus from x509 Key Cert for comparison
+ if(!guidcmp(&KeyHndl.AlgGuid, &gEfiCertRsa2048Guid) &&
+ !guidcmp(&PublicKey->AlgGuid, &gEfiCertX509Guid)
+ ) {
+ PKpubBuffer = &Hash[0];
+ KeyLen = DEFAULT_RSA_KEY_MODULUS_LEN;
+ ResetCRmm();
+ err = Pkcs7_x509_return_Cert_pubKey((UINT8*)PublicKey->Blob, (UINTN)PublicKey->BlobSize, &PKpubBuffer, &KeyLen);
+ ResetCRmm();
+ if(err) return EFI_SECURITY_VIOLATION;
+ }
+#endif
+ }
+
+ err = MemCmp(PKpubBuffer, KeyBuf, KeyLen);
+ Status = !err ? EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CryptoPei_Init
+//
+// Description: This function is the entry point for this PEI.
+//
+//
+// Input: FfsHeader Pointer to the FFS file header
+// PeiServices Pointer to the PEI services table
+//
+// Output: Return Status based on errors that occurred while waiting for
+// time to expire.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CryptoPei_Init (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN Npages;
+ EFI_PHYSICAL_ADDRESS DstAddress;
+ EFI_BOOT_MODE BootMode;
+ UINT8 Index;
+ UINT8 *pBuf;
+
+ gPeiServices = PeiServices;
+
+ Status = (*gPeiServices)->GetBootMode( PeiServices, &BootMode );
+ if(EFI_ERROR(Status) || BootMode == BOOT_ON_S3_RESUME) {
+ return Status; // skip Crypto PPI install on S3 resume
+ }
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Create FwKey Hob
+//
+////////////////////////////////////////////////////////////////////////////////////
+ Index = 0;
+ while(gKeyFileGuid[Index] != NULL)
+ {
+// Available Key Cert GUIDs: RSA2048, SHA256 and x509
+ Status = CryptoGetRawImage(gKeyFileGuid[Index], (VOID**)&pBuf, (UINTN*)&Size);
+ if(!EFI_ERROR(Status)) {
+ // make sure the Key buffer is mapped to FV_BB address space
+/*
+ if(!((UINT32)pBuf > FV_BB_BASE &&
+ (UINT64)((UINT32)pBuf+Size) <
+ (UINT64)(FV_BB_BASE+(UINT64)FV_BB_BLOCKS*FLASH_BLOCK_SIZE)))
+ break;
+*/
+ Status = (*PeiServices)->CreateHob(
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(FW_KEY_HOB), &pFwKeyHob);
+ if (!EFI_ERROR(Status) && pFwKeyHob) {
+ pFwKeyHob->Header.Name = gPKeyGuid;
+ pFwKeyHob->KeyGuid = *gKeyTypeGuid[Index];
+ pFwKeyHob->KeyAddress = (EFI_PHYSICAL_ADDRESS)(UINT32)pBuf;
+ pFwKeyHob->KeySize = Size;
+ }
+ break;
+ }
+ Index++;
+ }
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Init Aux Memory Manager
+//
+////////////////////////////////////////////////////////////////////////////////////
+// convert the Heap Size in bytes to the number of pages and allocate appropriate number of pages
+
+ Size = CR_PEI_MAX_HEAP_SIZE;
+ Npages = EFI_SIZE_TO_PAGES(Size);
+ Status = (*gPeiServices)->AllocatePages(gPeiServices, EfiBootServicesData, Npages, &DstAddress);
+ PEI_TRACE(((UINTN)TRACE_ALWAYS, gPeiServices, "Heap alloc %r (addr=%X, size=%d)\n", Status, (UINT32)DstAddress, Size));
+ if(EFI_ERROR(Status))
+ {
+ return Status;
+ }
+ InitCRmm((void*)DstAddress, Size);
+ //
+ // Update Crypto debug traces level
+ //
+ wpa_set_trace_level(CRYPTO_trace_level);
+
+////////////////////////////////////////////////////////////////////////////////////
+//
+// Install VerifySig PPI
+//
+////////////////////////////////////////////////////////////////////////////////////
+ return (**gPeiServices).InstallPpi (gPeiServices, &mPpiSigListVariable);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoPei.dxs b/Core/EM/CryptoPkg/CryptoPei.dxs
new file mode 100644
index 0000000..86c2008
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoPei.dxs
@@ -0,0 +1,54 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.dxs 1 6/13/11 5:19p Alexp $
+//
+// $Revision: 1 $
+//
+// $Date: 6/13/11 5:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/CryptoPkg/CryptoPei.dxs $
+//
+// 1 6/13/11 5:19p Alexp
+//
+// 1 5/06/11 6:11p Alexp
+// initial module release
+//
+// 1 3/10/11 4:52p Alexp
+//
+// 1 2/18/11 5:42p Alexp
+//
+//**********************************************************************
+#include <pei.h>
+//#include <Ppi\ReadOnlyVariable.h>
+#include <token.h>
+
+DEPENDENCY_START
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+DEPENDENCY_END
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/CryptoPkg/CryptoPkg.cif b/Core/EM/CryptoPkg/CryptoPkg.cif
new file mode 100644
index 0000000..9a35890
--- /dev/null
+++ b/Core/EM/CryptoPkg/CryptoPkg.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "CryptoPkg"
+ category = eModule
+ LocalRoot = "Core\EM\CryptoPkg\"
+ RefName = "CryptoPkg"
+[parts]
+"CryptoAPI"
+"CryptoLIB"
+<endComponent>
diff --git a/Core/EM/CsmOptOut/CsmOptOut.c b/Core/EM/CsmOptOut/CsmOptOut.c
new file mode 100644
index 0000000..b5056cd
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.c
@@ -0,0 +1,1039 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.c 15 11/01/13 9:25p Artems $
+//
+// $Revision: 15 $
+//
+// $Date: 11/01/13 9:25p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.c $
+//
+// 15 11/01/13 9:25p Artems
+// [TAG] EIP126445
+// [Category] Improvement
+// [Description] Added UEFI Only option for OpROMS of unknown types
+// [Files] CsmOptOut.c CsmOptOut.sd CsmOptOut.sdl CsmOptOut.uni
+//
+// 14 7/30/12 10:22a Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Can't disable legacy OpROM execution
+// [RootCause] CsmOptOut didn't check if anybody already disabled OpROM
+// executio
+// [Solution] Added check of ExecuteThisOpROM flag
+// [Files] CsmOptOut.c
+//
+// 13 6/20/12 6:05p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 12 5/21/12 4:46p Artems
+// [TAG] EIP86097
+// [Category] Improvement
+// [Description] Separate control for loading UEFI Oprom Driver
+// [Files] CsmOptOut.c CsmOptOut.mak PciBus.c
+// CsmOptOut.sdl
+//
+// 11 5/10/12 5:42p Artems
+// [TAG] EIP87316
+// [Category] Improvement
+// [Description] Revert previous changes, as the improvement were made
+// in FixedBootOrder module
+// [Files] CsmOptOut.c
+//
+// 10 4/18/12 4:41p Artems
+// [TAG] EIP87316
+// [Category] Improvement
+// [Description] If legacy boot device is filtered it still appears in
+// boot order maintained by FixedBootOrder module
+// [Files] CsmOptOut.c
+//
+// 9 4/05/12 5:14p Artems
+// Removed eLinks to ConnectVga and ConnectEverything. Implemented
+// Platform specific override protocol instead to control OpROM execution
+// sequence
+//
+// 8 3/16/12 6:06p Artems
+// Fixed bug in CsmOptOutConnectEverything function - not all handles were
+// connected
+//
+// 7 3/16/12 5:15p Artems
+// EIP 82586: CSM must not be loaded if Secure Boot is enabled
+//
+// 6 1/27/12 4:34p Artems
+// Restored change killed by previous check-in
+//
+// 5 1/23/12 7:02p Artems
+// Added OpROM handling for PCI devices other than Network, Mass storage
+// or Video
+// Behavior is same as in previous Core versions
+//
+// 3 11/28/11 1:42p Artems
+// EIP 75876: Trying to use Setup variable before NVRAM driver is
+// available
+//
+// 2 11/14/11 3:37p Artems
+// Removed unnecessary Trace
+//
+// 1 11/12/11 2:57p Artems
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOut.c
+//
+// Description: This is main file of the CsmOptOut module
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+//----------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <BootOptions.h>
+#include <AmiLoadCsmPolicy.h>
+#include <Protocol\CsmPlatform.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\PlatformDriverOverride.h>
+#include <Protocol\BusSpecificDriverOverride.h>
+#include <Protocol\GraphicsOutput.h>
+
+#define DEFAULT_HANDLE_BUFFER_SIZE 0x40
+typedef struct {
+ UINTN TotalSize;
+ UINTN CurrentSize;
+ EFI_HANDLE *Array;
+} HANDLE_BUFFER;
+
+HANDLE_BUFFER ThunkHandles;
+HANDLE_BUFFER NonThunkHandles;
+static EFI_HANDLE SharedGopHandle = 0;
+static BOOLEAN UefiGopDisconnected = FALSE;
+static BOOLEAN ProceedToBoot = FALSE;
+
+
+EFI_STATUS CsmOptOutGetDriver(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+);
+
+EFI_STATUS CsmOptOutGetDriverWorker(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+);
+
+EFI_STATUS CsmOptOutGetDriverPath(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DriverImagePath
+) { return EFI_UNSUPPORTED; }
+
+EFI_STATUS CsmOptOutDriverLoaded(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *DriverImagePath,
+ IN EFI_HANDLE DriverImageHandle
+) { return EFI_UNSUPPORTED; }
+
+static EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL CsmOptOutPlatformDriverOverride = {
+ CsmOptOutGetDriver,
+ CsmOptOutGetDriverPath,
+ CsmOptOutDriverLoaded
+};
+
+
+//----------------------------------------------------------------------------
+
+static EFI_GUID SetupGuid = SETUP_GUID;
+static EFI_GUID AmiLoadCsmGuid = AMI_LOAD_CSM_GUID;
+static EFI_GUID OpRomStartEndProtocolGuid = OPROM_START_END_PROTOCOL_GUID;
+static EFI_GUID AmiCsmThunkProtocolGuid = AMI_CSM_THUNK_PROTOCOL_GUID;
+static EFI_GUID AmiOpromPolicyProtocolGuid = AMI_OPROM_POLICY_PROTOCOL_GUID;
+extern EFI_GUID BdsAllDriversConnectedProtocolGuid;
+
+UINT8 CurrentCsmState;
+VOID *ProcessOpRomRegistration;
+VOID *DriverBindingRegistration;
+static UINTN CurrentCount = 0;
+static EFI_HANDLE CurrentHandle = 0;
+static EFI_HANDLE LastReturnedImageHandle = 0;
+static BOOLEAN TransactionInProgress;
+static BOOLEAN ThunkFirst;
+
+typedef EFI_STATUS (OEM_CHECK_UEFI_OPROM_POLICY) (EFI_HANDLE PciHandle);
+extern OEM_CHECK_UEFI_OPROM_POLICY OEM_CHECK_UEFI_OPROM_POLICY_LIST EndOfList;
+OEM_CHECK_UEFI_OPROM_POLICY* OemCheckUefiOpromPolicyList[] = { OEM_CHECK_UEFI_OPROM_POLICY_LIST NULL };
+
+EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *BusSpecific = NULL;
+
+typedef struct CSM_OPTOUT_SETUP_DATA {
+ UINT8 CsmLaunchPolicy;
+ UINT8 BootOptionFilter;
+ UINT8 PxeOpRom;
+ UINT8 MassStorageOpRom;
+ UINT8 VideoOpRom;
+/*
+ We added the following field to preserve functionality existed in previous
+ PciBus versions. For PCI devices other than Network,Mass Storage or Video
+ value of following field will determine OpROM behavior as before.
+*/
+ UINT8 OldOpRom;
+} CSM_OPTOUT_SETUP_DATA;
+
+CSM_OPTOUT_SETUP_DATA CsmOptOutSetupData = {
+ DEFAULT_CSM_LAUNCH_POLICY,
+ DEFAULT_BOOT_OPTION_FILTERING_POLICY,
+ DEFAULT_PXE_OPROM_POLICY,
+ DEFAULT_MASS_STORAGE_OPROM_POLICY,
+ DEFAULT_VIDEO_OPROM_POLICY,
+ 1
+};
+
+EFI_STATUS CheckUefiOpRomPolicy(
+ IN AMI_OPROM_POLICY_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle
+);
+
+AMI_OPROM_POLICY_PROTOCOL AmiOpRomPolicyProtocol = {
+ CheckUefiOpRomPolicy
+};
+
+EFI_STATUS AddHandle(
+ IN OUT HANDLE_BUFFER *Target,
+ EFI_HANDLE Handle
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CsmOptOutFilter
+//
+// Description: This function filters available boot options based on Setup
+// control value
+//
+// Input:
+// IN BOOT_DEVICE *Device - pointer to boot device
+//
+// Output:
+// TRUE - boot option will be removed from boot list
+// FALSE - boot option won't be removed from boot list
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CsmOptOutFilter(
+ IN BOOT_DEVICE *Device
+)
+{
+ BOOLEAN Result = FALSE;
+
+ if(CurrentCsmState == 0) //CSM is disabled on current boot - no need to filter boot options
+ return Result;
+
+ switch (CsmOptOutSetupData.BootOptionFilter) {
+ case 0: // Enable all boot options
+ break;
+
+ case 1: // Disable UEFI boot options
+ Result = (Device->BbsEntry == NULL);
+ break;
+
+ case 2: // Disable Legacy boot options
+ Result = (Device->BbsEntry != NULL);
+ break;
+
+ default:
+ break;
+ }
+ return Result;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetOpRomPolicy
+//
+// Description: This function returns OpROM policy for given PCI class of the device
+//
+// Input:
+// UINT8 PciClass - class of PCI device to check
+//
+// Output:
+// UINT8 - policy (0-disable all, 1-disable Legacy, 2-disable UEFI, 3-Legacy before UEFI
+// 4-UEFI before Legacy)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetOpRomPolicy(
+ IN UINT8 PciClass
+)
+{
+ UINT8 Policy = 0xff;
+
+ switch(PciClass) {
+ case PCI_CL_NETWORK:
+ Policy = CsmOptOutSetupData.PxeOpRom;
+ break;
+
+ case PCI_CL_MASS_STOR:
+ Policy = CsmOptOutSetupData.MassStorageOpRom;
+ break;
+
+ case PCI_CL_DISPLAY:
+ Policy = CsmOptOutSetupData.VideoOpRom;
+ break;
+
+ default:
+/*
+ For PCI devices with PCI class different from Network, Mass Storage or Video
+ behavior will be as in previous versions of PciBus driver - UEFI OpROM will
+ be executed first or not executed at all
+*/
+#if OLD_OPROM_POLICY_SUPPORT
+ Policy = (CsmOptOutSetupData.OldOpRom == 1) ? 4 : 2;
+#else
+ Policy = CsmOptOutSetupData.OldOpRom;
+#endif
+ break;
+ }
+ return Policy;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckOpRomExecution
+//
+// Description: This function determines should OpROM be executed
+//
+// Input:
+// UINT8 PciClass - class of PCI device to check
+// BOOLEAN UefiOprom - TRUE if verifying UEFI OpROM, FALSE for Legacy OpROM
+//
+// Output:
+// EFI_SUCCESS - OpROM should be executed
+// EFI_UNSUPPORTED - OpROM should not be executed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckOpRomExecution(
+ IN UINT8 PciClass,
+ IN BOOLEAN UefiOprom
+)
+{
+ UINT8 Policy;
+ BOOLEAN Result = TRUE;
+
+ Policy = GetOpRomPolicy(PciClass);
+
+ switch(Policy) {
+ case 0: //all OpROMs are disabled
+ Result = FALSE;
+ break;
+
+ case 1: //only UEFI OpROMs are enabled
+ Result = (UefiOprom) ? TRUE : FALSE;
+ break;
+
+ case 2: //only Legacy OpROMs are enabled
+ Result = (UefiOprom) ? FALSE : TRUE;
+ break;
+
+ default: //all OpROMs are enabled
+ break;
+ }
+ return (Result) ? EFI_SUCCESS : EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisconnectUefiGop
+//
+// Description: This function disconnects native UEFI GOP driver before
+// executing legacy video BIOS
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIo - instance of PciIo protocol on handle,
+// that have to be disconnected
+//
+// Output:
+// EFI_SUCCESS - driver was disconnected
+// EFI_UNSUPPORTED - driver can't be disconnected
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisconnectUefiGop(
+ IN EFI_PCI_IO_PROTOCOL *PciIo
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handles;
+ EFI_HANDLE TmpHandle;
+ UINTN Count;
+ UINTN i;
+ VOID *Interface;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Entries;
+ UINT64 Capabilities;
+
+/* first find corresponding handle */
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiPciIoProtocolGuid, NULL, &Count, &Handles);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < Count; i++) {
+ Status = pBS->HandleProtocol(Handles[i], &gEfiPciIoProtocolGuid, &Interface);
+ if(EFI_ERROR(Status))
+ continue;
+
+ if((VOID *)PciIo == Interface) {
+ SharedGopHandle = Handles[i];
+ break;
+ }
+ }
+ pBS->FreePool(Handles);
+
+ if(i == Count) //no matches
+ return EFI_NOT_FOUND;
+
+/* now find child handle where Gop is installed */
+ Status = pBS->OpenProtocolInformation(SharedGopHandle, &gEfiPciIoProtocolGuid, &Entries, &Count);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < Count; i++) {
+ if(!(Entries[i].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER))
+ continue;
+
+ Status = pBS->HandleProtocol(Entries[i].ControllerHandle, &gEfiGraphicsOutputProtocolGuid, &Interface);
+ if(!EFI_ERROR(Status)) {
+ TmpHandle = Entries[i].AgentHandle;
+ break;
+ }
+ }
+ pBS->FreePool(Entries);
+
+ if(i == Count) //no matches
+ return EFI_NOT_FOUND;
+
+/* now check if AgentHandle is our CSM thunk */
+ Status = pBS->HandleProtocol(TmpHandle, &AmiCsmThunkProtocolGuid, &Interface);
+ if(!EFI_ERROR(Status))
+ return EFI_SUCCESS;
+
+ Status = pBS->DisconnectController(SharedGopHandle, NULL, NULL);
+/* we have to restore PCI attributes so video BIOS can be executed */
+ Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationSupported,
+ 0, &Capabilities);
+ Status = PciIo->Attributes (PciIo, EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE, NULL);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessOpRomCallback
+//
+// Description: This callback will be called before and after installing legacy OpROM
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProcessOpRomCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINTN Size = sizeof(EFI_HANDLE);
+ CSM_PLATFORM_POLICY_DATA *OpRomStartEndProtocol;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClassCode;
+
+ Status = pBS->LocateHandle(ByRegisterNotify, NULL, ProcessOpRomRegistration, &Size, &Handle);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return;
+
+ Status = pBS->HandleProtocol(Handle, &OpRomStartEndProtocolGuid, &OpRomStartEndProtocol);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return;
+
+ if(OpRomStartEndProtocol == NULL) { //post-process OpROM callback
+ if(UefiGopDisconnected && !ProceedToBoot)
+/* if this is last OpROM, and Gop was disconnected and we're not on legacy boot path */
+ pBS->ConnectController(SharedGopHandle, NULL, NULL, TRUE);
+ return;
+ }
+
+//check if someone already disabled execution of this OpROM
+ if(OpRomStartEndProtocol->PciIo == NULL || OpRomStartEndProtocol->ExecuteThisRom == FALSE)
+ return;
+
+ PciIo = OpRomStartEndProtocol->PciIo;
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClassCode);
+ if (EFI_ERROR(Status))
+ return;
+
+ Status = CheckOpRomExecution(PciClassCode, FALSE);
+ if(EFI_ERROR(Status)) {
+ OpRomStartEndProtocol->ExecuteThisRom = FALSE;
+ return;
+ }
+
+/* OK, we're decided to execute OpROM */
+ OpRomStartEndProtocol->ExecuteThisRom = TRUE;
+
+ if(PciClassCode == PCI_CL_DISPLAY) {
+ Status = DisconnectUefiGop(PciIo);
+ /*
+ we are executing video OpROM even if we can't disconnect
+ native UEFI driver - possible bug
+ */
+ if(!EFI_ERROR(Status))
+ UefiGopDisconnected = TRUE;
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateHandlesCallback
+//
+// Description: This callback executed every time DriverBinding is installed
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LocateHandlesCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status1;
+ UINTN Count = sizeof(EFI_HANDLE);
+ EFI_HANDLE Handle;
+ VOID *DummyInterface;
+
+ do {
+ Status = pBS->LocateHandle(ByRegisterNotify,
+ NULL,
+ DriverBindingRegistration,
+ &Count,
+ &Handle);
+ if(!EFI_ERROR(Status)) {
+ Status1 = pBS->HandleProtocol(Handle,
+ &AmiCsmThunkProtocolGuid,
+ &DummyInterface);
+ if(EFI_ERROR(Status1)) {
+ Status = AddHandle(&NonThunkHandles, Handle);
+ } else {
+ Status = AddHandle(&ThunkHandles, Handle);
+ }
+ }
+ } while (!EFI_ERROR(Status));
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitHandleBuffer
+//
+// Description: This function allocates buffer to store DriverBinding handles
+//
+// Input:
+// IN OUT HANDLE_BUFFER *Target - pointer to buffer to be initialized
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitHandleBuffer(
+ IN OUT HANDLE_BUFFER *Target
+)
+{
+ EFI_STATUS Status;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_HANDLE) * DEFAULT_HANDLE_BUFFER_SIZE,
+ (VOID **)&(Target->Array));
+ if(!EFI_ERROR(Status)) {
+ Target->TotalSize = DEFAULT_HANDLE_BUFFER_SIZE;
+ Target->CurrentSize = 0;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IncreaseHandleBuffer
+//
+// Description: This function increases and reallocates buffer to store
+// DriverBinding handles
+//
+// Input:
+// IN OUT HANDLE_BUFFER *Target - pointer to buffer to be increased
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IncreaseHandleBuffer(
+ IN OUT HANDLE_BUFFER *Target
+)
+{
+ EFI_STATUS Status;
+ VOID *NewArray;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ sizeof(EFI_HANDLE) * (Target->TotalSize + DEFAULT_HANDLE_BUFFER_SIZE),
+ &NewArray);
+ if(!EFI_ERROR(Status)) {
+ MemCpy(NewArray, Target->Array, sizeof(EFI_HANDLE) * Target->CurrentSize);
+ Target->TotalSize += DEFAULT_HANDLE_BUFFER_SIZE;
+
+ pBS->FreePool(Target->Array);
+ Target->Array = (EFI_HANDLE *)NewArray;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddHandle
+//
+// Description: This function stores handles in allocated buffer
+//
+// Input:
+// IN OUT HANDLE_BUFFER *Target - pointer to buffer to store handle in
+// EFI_HANDLE Handle - handle to be stored
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddHandle(
+ IN OUT HANDLE_BUFFER *Target,
+ EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+
+ if(Target->CurrentSize >= Target->TotalSize) {
+ Status = IncreaseHandleBuffer(Target);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ Target->Array[Target->CurrentSize] = Handle;
+ Target->CurrentSize++;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProceedToBootCallback
+//
+// Description: This callback executed when all drivers are connected and system
+// proceeds to boot
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ProceedToBootCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ ProceedToBoot = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutEntry
+//
+// Description:
+// This function is CsmOptOut driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ SETUP_DATA SetupData;
+ UINTN Size = sizeof(SETUP_DATA);
+ EFI_EVENT OptOutEvent;
+ VOID *Registration;
+
+ Status = pRS->GetVariable(L"Setup", &SetupGuid, NULL, &Size, &SetupData);
+
+ if(!EFI_ERROR(Status)) {
+ CsmOptOutSetupData.CsmLaunchPolicy = SetupData.CsmLaunchPolicy;
+ CsmOptOutSetupData.BootOptionFilter = SetupData.BootOptionFilter;
+ CsmOptOutSetupData.PxeOpRom = SetupData.PxeOpRom;
+ CsmOptOutSetupData.MassStorageOpRom = SetupData.MassStorageOpRom;
+ CsmOptOutSetupData.VideoOpRom = SetupData.VideoOpRom;
+ CsmOptOutSetupData.OldOpRom = SetupData.OldOpRom;
+ }
+
+//Determine current CSM state based on whether AmiLoadCsmGuid protocol is installed
+ Size = sizeof(EFI_HANDLE);
+ Status = pBS->LocateHandle(ByProtocol, &AmiLoadCsmGuid, NULL, &Size, &Handle);
+ CurrentCsmState = (EFI_ERROR(Status)) ? 0 : 1;
+
+ if(CurrentCsmState == 1) {
+ Status = RegisterProtocolCallback(&OpRomStartEndProtocolGuid,
+ ProcessOpRomCallback,
+ NULL,
+ &OptOutEvent,
+ &ProcessOpRomRegistration);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = RegisterProtocolCallback(&BdsAllDriversConnectedProtocolGuid,
+ ProceedToBootCallback,
+ NULL,
+ &OptOutEvent,
+ &Registration);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ /* Init platform driver override protocol */
+ Status = InitHandleBuffer(&ThunkHandles);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = InitHandleBuffer(&NonThunkHandles);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = RegisterProtocolCallback(&gEfiDriverBindingProtocolGuid,
+ LocateHandlesCallback,
+ NULL,
+ &OptOutEvent,
+ &DriverBindingRegistration);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ /*call callback manually to get already registered handles */
+ LocateHandlesCallback(OptOutEvent, NULL);
+
+ Status = pBS->InstallMultipleProtocolInterfaces(&Handle,
+ &AmiOpromPolicyProtocolGuid,
+ &AmiOpRomPolicyProtocol,
+ &gEfiPlatformDriverOverrideProtocolGuid,
+ &CsmOptOutPlatformDriverOverride,
+ NULL);
+ } else {
+//Reset Boot option filter to avoid situation, when no boot options are available
+ CsmOptOutSetupData.BootOptionFilter = 0;
+//Set video policy to UEFI only
+ CsmOptOutSetupData.VideoOpRom = 1;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetUefiOpRomPolicy
+//
+// Description:
+// This function is HII driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully, HII protocols installed
+// EFI_ERROR - Some error occured during execution
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckUefiOpRomPolicy(
+ IN AMI_OPROM_POLICY_PROTOCOL *This,
+ IN EFI_HANDLE PciHandle
+)
+{
+ UINT32 i;
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass;
+
+ for(i = 0; OemCheckUefiOpromPolicyList[i] != NULL; i++) {
+ Status = OemCheckUefiOpromPolicyList[i](PciHandle);
+ if(Status == EFI_SUCCESS || Status == EFI_UNSUPPORTED)
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(PciHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+
+ return (EFI_ERROR(Status))? Status : CheckOpRomExecution(PciClass, TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetBusSpecificHandle
+//
+// Description: This function returns bus-specific handle for given controller
+//
+// Input:
+// IN EFI_HANDLE ControllerHandle - handle of the controller
+// IN OUT EFI_HANDLE *DriverImageHandle - pointer to returned handle placeholder
+//
+// Output:
+// EFI_SUCCESS - handle returned
+// EFI_NOT_FOUND - handle not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetBusSpecificHandle(
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+)
+{
+ EFI_STATUS Status;
+
+ if(BusSpecific == NULL) {
+ Status = pBS->HandleProtocol(
+ ControllerHandle,
+ &gEfiBusSpecificDriverOverrideProtocolGuid,
+ &BusSpecific);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ return BusSpecific->GetDriver(BusSpecific, DriverImageHandle);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsManageable
+//
+// Description: This function returns if given PCI device class supports
+// controlled UEFI/Legacy OpROM execution sequence
+//
+// Input:
+// IN UINT8 PciClass - class of the device
+//
+// Output:
+// TRUE - controlled sequence supported
+// FALSE - controlled sequence not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsManageable(
+ IN UINT8 PciClass
+)
+{
+ if(PciClass == PCI_CL_DISPLAY ||
+ PciClass == PCI_CL_NETWORK ||
+ PciClass == PCI_CL_MASS_STOR)
+ return TRUE;
+
+ return FALSE;
+}
+
+VOID UpdateTransaction(
+ IN EFI_STATUS Status,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE DriverImageHandle
+)
+{
+ if(!EFI_ERROR(Status)) {
+ TransactionInProgress = TRUE;
+ CurrentHandle = ControllerHandle;
+ LastReturnedImageHandle = DriverImageHandle;
+ } else {
+ TransactionInProgress = FALSE;
+ CurrentHandle = NULL;
+ LastReturnedImageHandle = NULL;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutGetDriver
+//
+// Description: Implementation of Platform Drive Override protocol
+// GetDriver function
+//
+// Input:
+// IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This - pointer to the instance of
+// the protocol
+// IN EFI_HANDLE ControllerHandle - handle of controller for which to retrieve
+// DriverBinding handle
+// IN OUT EFI_HANDLE *DriverImageHandle - pointer to returned handle placeholder
+//
+// Output:
+// EFI_SUCCESS - handle returned
+// EFI_NOT_FOUND - handle not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutGetDriver(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+)
+{
+ EFI_STATUS Status;
+ if(TransactionInProgress) {
+ if(*DriverImageHandle != LastReturnedImageHandle ||
+ ControllerHandle != CurrentHandle) {
+ Status = EFI_INVALID_PARAMETER;
+ UpdateTransaction(Status, NULL, NULL);
+ return Status;
+ }
+ }
+
+ Status = CsmOptOutGetDriverWorker(This, ControllerHandle, DriverImageHandle);
+ UpdateTransaction(Status, ControllerHandle, *DriverImageHandle);
+ return Status;
+}
+
+EFI_STATUS CsmOptOutGetDriverWorker(
+ IN EFI_PLATFORM_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN OUT EFI_HANDLE *DriverImageHandle
+)
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass;
+ UINT8 Policy;
+
+ if(ControllerHandle == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(*DriverImageHandle == NULL) { //This is first call
+ Status = pBS->HandleProtocol(ControllerHandle, &gEfiPciIoProtocolGuid, &PciIo);
+ if(EFI_ERROR(Status))
+ return EFI_NOT_FOUND; //we don't care about non pci handles
+
+ Status = PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+ if(EFI_ERROR(Status))
+ return EFI_NOT_FOUND;
+
+ Policy = GetOpRomPolicy(PciClass);
+ if(Policy == 0) //OpROM execution is disabled
+ return EFI_NOT_FOUND;
+
+ /* check if this pci class supported for controlled OpROM
+ execution sequence
+ */
+ if(!IsManageable(PciClass))
+ return EFI_NOT_FOUND;
+
+ ThunkFirst = (Policy == 2 || Policy == 3) ? TRUE : FALSE;
+ }
+
+ if(ThunkFirst) {
+ if(CurrentCount < ThunkHandles.CurrentSize) {
+ *DriverImageHandle = ThunkHandles.Array[CurrentCount];
+ CurrentCount++;
+ return EFI_SUCCESS;
+ } else {
+ CurrentCount = 0; //reset counter
+ return EFI_NOT_FOUND;
+ }
+ } else {
+/* first get handles provided by bus specific override protocol */
+ if((UINTN)BusSpecific != 0xfffffffa) {
+ Status = GetBusSpecificHandle(ControllerHandle, DriverImageHandle);
+ if(!EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ (UINTN)BusSpecific = 0xfffffffa; //set flag we're done with bus specific override
+ }
+/* now get other Driver binding handles except those with thunk protocol */
+ if(CurrentCount < NonThunkHandles.CurrentSize) {
+ *DriverImageHandle = NonThunkHandles.Array[CurrentCount];
+ CurrentCount++;
+ return EFI_SUCCESS;
+ } else {
+ CurrentCount = 0;
+ (UINTN)BusSpecific = 0; //set flag we need to start from bus specific next time we're called
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CsmOptOut/CsmOptOut.chm b/Core/EM/CsmOptOut/CsmOptOut.chm
new file mode 100644
index 0000000..f5e23f1
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.chm
Binary files differ
diff --git a/Core/EM/CsmOptOut/CsmOptOut.cif b/Core/EM/CsmOptOut/CsmOptOut.cif
new file mode 100644
index 0000000..4147155
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "CsmOptOut"
+ category = eModule
+ LocalRoot = "Core\EM\CsmOptOut\"
+ RefName = "CsmOptOut"
+[files]
+"CsmOptOut.sdl"
+"CsmOptOut.mak"
+"CsmOptOut.c"
+"CsmOptOutRuntime.c"
+"CsmOptOutSetup.c"
+"CsmOptOut.uni"
+"CsmOptOut.sd"
+"CsmOptOut.chm"
+<endComponent>
diff --git a/Core/EM/CsmOptOut/CsmOptOut.mak b/Core/EM/CsmOptOut/CsmOptOut.mak
new file mode 100644
index 0000000..7371b03
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.mak
@@ -0,0 +1,106 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.mak 5 1/22/13 4:29p Artems $
+#
+# $Revision: 5 $
+#
+# $Date: 1/22/13 4:29p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOut.mak $
+#
+# 5 1/22/13 4:29p Artems
+# [TAG] EIP111710
+# [Category] Improvement
+# [Description] Replace MessageBox message and title with string tokens
+# to allow
+# different language usage
+# [Files] CsmOptOut.mak CsmOptOut.uni CsmOptOutSetup.c
+#
+# 4 6/20/12 6:06p Artems
+# [TAG] EIP83692
+# [Category] Improvement
+# [Description] CSM OptOut setup page grayed out if secure boot is
+# enabled
+# CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+# Removed support for Launch CSM "Auto" option
+#
+# [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+# CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+#
+# 3 5/21/12 4:43p Artems
+# [TAG] EIP86097
+# [Category] Improvement
+# [Description] Separate control for loading UEFI Oprom Driver
+# Prevent user from disable CSM in setup if active video is legacy
+# [Files] CsmOptOutSetup.c CsmOptOut.sdl CsmOptOut.mak
+# CsmOptOut.sdl
+#
+# 2 3/16/12 5:15p Artems
+# EIP 82586: CSM must not be loaded if Secure Boot is enabled
+#
+# 1 11/12/11 2:57p Artems
+# Initial check-in
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CsmOptOut.mak
+#
+# Description: Make file of the CSM OptOut module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\CsmOptOut.obj
+RUNTIMEBin : $(BUILD_DIR)\CsmOptOutRuntime.obj
+SetupBin : $(BUILD_DIR)\CsmOptOutSetup.obj
+
+CFLAGS=$(CFLAGS) /D\"OEM_CHECK_UEFI_OPROM_POLICY_LIST=$(OemCheckUefiOpromPolicyList)\"
+
+{$(CsmOptOut_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /I $(CsmOptOut_DIR) /Fo$(BUILD_DIR)\ $<
+
+$(BUILD_DIR)\CsmOptOut.obj : $(CsmOptOut_DIR)\CsmOptOut.c
+$(BUILD_DIR)\CsmOptOutRuntime.obj : $(CsmOptOut_DIR)\CsmOptOutRuntime.c
+$(BUILD_DIR)\CsmOptOutSetup.obj : $(CsmOptOut_DIR)\CsmOptOutSetup.c
+
+$(BUILD_DIR)\CsmOptOut.mak : $(CsmOptOut_DIR)\CsmOptOut.cif $(BUILD_RULES)
+ $(CIF2MAK) $(CsmOptOut_DIR)\CsmOptOut.cif $(CIF2MAK_DEFAULTS)
+
+SetupSdbs : CsmOptOutSDB
+
+CsmOptOutSDB : $(BUILD_DIR)\CsmOptOut.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CsmOptOut.mak all\
+ TYPE=SDB NAME=CsmOptOut \
+ "STRING_CONSUMERS=$(CsmOptOut_DIR)\CsmOptOut.sd $(CsmOptOut_DIR)\CsmOptOutSetup.c"
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/CsmOptOut/CsmOptOut.sd b/Core/EM/CsmOptOut/CsmOptOut.sd
new file mode 100644
index 0000000..ce0bba0
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.sd
@@ -0,0 +1,252 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CsmOptOut/CsmOptOut.sd 6 6/25/14 7:34a Chienhsieh $
+//
+// $Revision: 6 $
+//
+// $Date: 6/25/14 7:34a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/CsmOptOut/CsmOptOut.sd $
+//
+// 6 6/25/14 7:34a Chienhsieh
+// Update CsmOptOut to 4.6.5.4_Csm_OptOut_05.
+//
+// 6 11/01/13 9:27p Artems
+// [TAG] EIP126445
+// [Category] Improvement
+// [Description] Added UEFI Only option for OpROMS of unknown types
+// [Files] CsmOptOut.c CsmOptOut.sd CsmOptOut.sdl CsmOptOut.uni
+//
+// 5 10/25/12 9:12a Wesleychen
+// Update CsmOptOut to 4.6.5.4_Csm_OptOut_04.
+//
+// 4 8/15/12 7:15a Wesleychen
+// Remove some items for compatible issue.
+//
+// 5 8/29/12 2:23p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] When enable secure boot disable CSM but preserve CSM
+// optout options setting,
+// so once secure boot is disabled they can be restored
+// [Files] CsmOptOut.sd, CsmOptOut.sdl, CsmOptOutSetup.c
+// CsmOptOutRuntime.c
+//
+// 4 6/20/12 6:07p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+//
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 3 5/21/12 4:48p Artems
+// [TAG] EIP88768
+// [Category] Improvement
+// [Description] CsmOptOut Module Interactive setup callback support
+// Prevent user from disable CSM in setup if active video is legacy
+// [Files] CsmOptOutSetup.c CsmOptOut.sd CsmOptOut.mak
+// CsmOptOut.sdl
+//
+// 2 1/23/12 7:03p Artems
+// Added OpROM handling for PCI devices other than Network, Mass storage
+// or Video
+// Behavior is same as in previous Core versions
+// Added configurability for setup controls
+//
+// 1 11/12/11 2:57p Artems
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOut.sd
+//
+// Description: Definition of CsmOptOut module setup controls
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+ UINT8 CsmLaunchPolicy;
+ UINT8 BootOptionFilter;
+ UINT8 PxeOpRom;
+ UINT8 MassStorageOpRom;
+ UINT8 VideoOpRom;
+ UINT8 OldOpRom;
+#endif //SETUP_DATA_DEFINITION
+
+#ifdef FORM_SET_TYPEDEF
+typedef struct {
+ UINT8 SecureBoot;
+} SECURE_BOOT;
+#endif
+
+#ifdef CONTROL_DEFINITION
+
+#define CSM_OPT_OUT_CSM_LAUNCH_POLICY\
+ oneof varid = SETUP_DATA.CsmLaunchPolicy, questionid = AUTO_ID(CSM_OPT_OUT_LAUNCH_KEY),\
+ prompt = STRING_TOKEN(STR_CSM_LAUNCH_POLICY),\
+ help = STRING_TOKEN(STR_CSM_LAUNCH_POLICY_HELP),\
+ default = DEFAULT_CSM_LAUNCH_POLICY,\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = INTERACTIVE | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = INTERACTIVE | RESET_REQUIRED;\
+ endoneof;
+
+#define CSM_OPT_OUT_BOOT_OPTION_FILTER\
+ oneof varid = SETUP_DATA.BootOptionFilter,\
+ prompt = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY),\
+ help = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_HELP),\
+ default = DEFAULT_BOOT_OPTION_FILTERING_POLICY,\
+ option text = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_ALL), value = 0, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_LEGACY_ONLY), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_BOOT_OPTION_FILTERING_POLICY_UEFI_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define CSM_OPT_OUT_PXE_OPROM\
+ oneof varid = SETUP_DATA.PxeOpRom,\
+ prompt = STRING_TOKEN(STR_PXE_OPROM_POLICY),\
+ help = STRING_TOKEN(STR_PXE_OPROM_POLICY_HELP),\
+ default = DEFAULT_PXE_OPROM_POLICY,\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_UEFI_ONLY), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_BEFORE_UEFI), value = 3, flags = RESET_REQUIRED;\
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_AFTER_UEFI), value = 4, flags = RESET_REQUIRED;\
+//- endoneof;
+
+#define CSM_OPT_OUT_MASS_STORAGE_OPROM\
+ oneof varid = SETUP_DATA.MassStorageOpRom,\
+ prompt = STRING_TOKEN(STR_MASS_STORAGE_OPROM_POLICY),\
+ help = STRING_TOKEN(STR_MASS_STORAGE_OPROM_POLICY_HELP),\
+ default = DEFAULT_MASS_STORAGE_OPROM_POLICY,\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_UEFI_ONLY), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_BEFORE_UEFI), value = 3, flags = RESET_REQUIRED;\
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_AFTER_UEFI), value = 4, flags = RESET_REQUIRED;\
+//- endoneof;
+
+#define CSM_OPT_OUT_VIDEO_OPROM\
+ oneof varid = SETUP_DATA.VideoOpRom,\
+ prompt = STRING_TOKEN(STR_VIDEO_OPROM_POLICY),\
+ help = STRING_TOKEN(STR_VIDEO_OPROM_POLICY_HELP),\
+ default = DEFAULT_VIDEO_OPROM_POLICY,\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_UEFI_ONLY), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_BEFORE_UEFI), value = 3, flags = RESET_REQUIRED;\
+//- option text = STRING_TOKEN(STR_OPROM_POLICY_LEGACY_AFTER_UEFI), value = 4, flags = MANUFACTURING | RESET_REQUIRED;\
+//- endoneof;
+
+#if OLD_OPROM_POLICY_SUPPORT
+#define CSM_OPT_OUT_OLD_OPROM\
+ oneof varid = SETUP_DATA.OldOpRom,\
+ prompt = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY),\
+ help = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_HELP),\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_UEFI), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_LEGACY), value = 0, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define CSM_OPT_OUT_OLD_OPROM\
+ oneof varid = SETUP_DATA.OldOpRom,\
+ prompt = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY),\
+ help = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_HELP),\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_UEFI), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_LEGACY_AND_UEFI), value = 4, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_OLD_OPROM_LAUNCH_POLICY_LEGACY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#endif //#if OLD_OPROM_POLICY_SUPPORT
+
+#define CSM_OPT_OUT_FORM_GOTO\
+ suppressif ideqval SECURE_BOOT.SecureBoot == 1;\
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;\
+ goto CSM_OPTOUT_FORM_ID, \
+ prompt = STRING_TOKEN(STR_CSM_OPTOUT_FORM),\
+ help = STRING_TOKEN(STR_CSM_OPTOUT_FORM_HELP);\
+ endif;\
+ endif;
+#endif //#ifdef CONTROL_DEFINITION
+
+#ifdef CONTROLS_WITH_DEFAULTS
+
+CSM_OPT_OUT_CSM_LAUNCH_POLICY
+CSM_OPT_OUT_BOOT_OPTION_FILTER
+CSM_OPT_OUT_PXE_OPROM
+CSM_OPT_OUT_MASS_STORAGE_OPROM
+CSM_OPT_OUT_VIDEO_OPROM
+CSM_OPT_OUT_OLD_OPROM
+
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+#ifdef BOOT_FORM_SET
+ #ifdef FORM_SET_ITEM
+
+ #endif // FORM_SET_ITEM
+
+ #ifdef FORM_SET_VARSTORE
+ varstore SECURE_BOOT, name = SecureBoot, guid = EFI_GLOBAL_VARIABLE_GUID;
+ #endif // FORM_SET_VARSTORE
+
+ #ifdef FORM_SET_GOTO
+
+ CSM_OPT_OUT_FORM_GOTO
+
+ #endif // FORM_SET_GOTO
+
+ #ifdef FORM_SET_FORM
+
+ form formid = AUTO_ID(CSM_OPTOUT_FORM_ID),
+ title = STRING_TOKEN(STR_CSM_OPTOUT_FORM);
+
+ CSM_OPT_OUT_CSM_LAUNCH_POLICY
+
+ suppressif ideqval SETUP_DATA.CsmLaunchPolicy == 0;
+ CSM_OPT_OUT_BOOT_OPTION_FILTER
+ CSM_OPT_OUT_PXE_OPROM
+ CSM_OPT_OUT_MASS_STORAGE_OPROM
+ CSM_OPT_OUT_VIDEO_OPROM
+ SEPARATOR
+ CSM_OPT_OUT_OLD_OPROM
+ endif;
+
+ endform;
+
+ #endif // FORM_SET_FORM
+
+#endif // BOOT_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CsmOptOut/CsmOptOut.sdl b/Core/EM/CsmOptOut/CsmOptOut.sdl
new file mode 100644
index 0000000..11f0193
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.sdl
@@ -0,0 +1,124 @@
+TOKEN
+ Name = "CsmOptOut_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "CSM_OPTOUT_MODULE_REVISION"
+ Value = "4"
+ Help = "Version of Csm Optout module interfaces"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OLD_OPROM_POLICY_SUPPORT"
+ Value = "1"
+ Help = "If set, implement old style option ROM support for other devices where UEFI signifies both legacy and UEFI option ROMs. If disabled, provide options for UEFI only, Legacy only, or both."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_CSM_LAUNCH_POLICY"
+ Value = "1"
+ Help = "Controls default value of CSM Launch Policy setup control\1 - Launch CSM, 0 - Do not launch CSM"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_BOOT_OPTION_FILTERING_POLICY"
+ Value = "0"
+ Help = "Controls default value of Boot Option Filter setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Both UEFI and Legacy boot options enabled, 1 - Only Legacy boot options enabled , 2 - Only UEFI boot options enabled"
+End
+
+TOKEN
+ Name = "DEFAULT_PXE_OPROM_POLICY"
+ Value = "1"
+ Help = "Default value of Launch PXE OpROM policy setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Do not launch, 1 - Launch UEFI OpROM only, 2 - Launch Legacy OpROM only, 3 - Launch Legacy before UEFI, 4 - Launch Legacy after UEFI"
+End
+
+TOKEN
+ Name = "DEFAULT_MASS_STORAGE_OPROM_POLICY"
+ Value = "1"
+ Help = "Default value of Launch Storage OpROM policy setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Do not launch, 1 - Launch UEFI OpROM only, 2 - Launch Legacy OpROM only, 3 - Launch Legacy before UEFI, 4 - Launch Legacy after UEFI"
+End
+
+TOKEN
+ Name = "DEFAULT_VIDEO_OPROM_POLICY"
+ Value = "2"
+ Help = "Default value of Launch Video OpROM policy setup control"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - Do not launch, 1 - Launch UEFI OpROM only, 2 - Launch Legacy OpROM only, 3 - Launch Legacy before UEFI, 4 - Launch Legacy after UEFI"
+End
+
+PATH
+ Name = "CsmOptOut_DIR"
+End
+
+MODULE
+ Help = "Includes CsmOptOut.mak to Project"
+ File = "CsmOptOut.mak"
+End
+
+ELINK
+ Name = "$(CsmOptOut_DIR)\CsmOptOut.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 80
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CsmOptOut.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CsmOptOutFilter,"
+ Parent = "BootOptionBootDeviceFilteringFunctions"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CsmOptOutEntry,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CsmOptOutRuntimeEntry,"
+ Parent = "NvRamSmmEntry,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemCheckUefiOpromPolicyList"
+ Help = "List of callback functions to be called to determine if UEFI Oprom should be executed"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(BOOT_FORM_SET_CLASS,0,CSM_OPT_OUT_LAUNCH_KEY,CsmOptOutLaunchCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/CsmOptOut/CsmOptOut.uni b/Core/EM/CsmOptOut/CsmOptOut.uni
new file mode 100644
index 0000000..44501de
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOut.uni
Binary files differ
diff --git a/Core/EM/CsmOptOut/CsmOptOutRuntime.c b/Core/EM/CsmOptOut/CsmOptOutRuntime.c
new file mode 100644
index 0000000..389676f
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOutRuntime.c
@@ -0,0 +1,168 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutRuntime.c 4 8/29/12 2:25p Artems $
+//
+// $Revision: 4 $
+//
+// $Date: 8/29/12 2:25p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutRuntime.c $
+//
+// 4 8/29/12 2:25p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] When enable secure boot disable CSM but preserve CSM
+// optout options setting,
+// so once secure boot is disabled they can be restored
+// [Files] CsmOptOut.sd, CsmOptOut.sdl, CsmOptOutSetup.c
+// CsmOptOutRuntime.c
+//
+// 3 6/20/12 6:10p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+//
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 2 3/23/12 6:26p Artems
+// EIP 84012: Added fix to execute entrypoint only once
+//
+// 1 3/16/12 4:57p Artems
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOutRuntime.c
+//
+// Description: This is the entry point of CsmOptOut driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+//----------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <AmiLoadCsmPolicy.h>
+#include <ImageAuthentication.h>
+
+//----------------------------------------------------------------------------
+
+static EFI_GUID SetupGuid = SETUP_GUID;
+static EFI_GUID AmiLoadCsmGuid = AMI_LOAD_CSM_GUID;
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutNotInSmmEntry
+//
+// Description: CsmOptOut runtime callback for variable services
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutNotInSmmEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+ SETUP_DATA SetupData;
+ UINTN Size;
+ UINT8 CurrentCsmState;
+ UINT32 Attributes;
+ BOOLEAN SecureBoot;
+
+ Size = sizeof(UINT8);
+ Status = pRS->GetVariable(EFI_SECURE_BOOT_NAME, &gEfiGlobalVariableGuid, NULL, &Size, &CurrentCsmState);
+ SecureBoot = (!EFI_ERROR(Status) && CurrentCsmState != 0) ? TRUE : FALSE;
+
+ Size = sizeof(SETUP_DATA);
+ Status = pRS->GetVariable(L"Setup", &SetupGuid, &Attributes, &Size, &SetupData);
+
+ CurrentCsmState = (SecureBoot) ? 0 : (EFI_ERROR(Status)) ? DEFAULT_CSM_LAUNCH_POLICY : SetupData.CsmLaunchPolicy;
+ if(CurrentCsmState == 1) {
+ Status = pBS->InstallMultipleProtocolInterfaces(&Handle,
+ &AmiLoadCsmGuid, NULL,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CsmOptOutRuntimeEntry
+//
+// Description: CsmOptOut runtime callback for variable services
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutRuntimeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ UINT32 Var;
+ UINTN Size = sizeof(UINT32);
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = pRS->GetVariable(L"AmiLoadCsm", &AmiLoadCsmGuid, NULL, &Size, &Var);
+ if(!EFI_ERROR(Status))
+ return EFI_ALREADY_STARTED;
+
+ Size = sizeof(UINT32);
+ Var = 0xdeadbeef;
+ Status = pRS->SetVariable(L"AmiLoadCsm", &AmiLoadCsmGuid, EFI_VARIABLE_BOOTSERVICE_ACCESS, Size, &Var);
+ return CsmOptOutNotInSmmEntry(ImageHandle, SystemTable);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/CsmOptOut/CsmOptOutSetup.c b/Core/EM/CsmOptOut/CsmOptOutSetup.c
new file mode 100644
index 0000000..f61e77b
--- /dev/null
+++ b/Core/EM/CsmOptOut/CsmOptOutSetup.c
@@ -0,0 +1,430 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+///**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutSetup.c 10 7/08/13 4:17p Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 7/08/13 4:17p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/CsmOptOut/CsmOptOutSetup.c $
+//
+// 10 7/08/13 4:17p Artems
+// [TAG] EIP N/A
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Build error
+// [RootCause] Unreferenced local variable
+// [Solution] Removed variable
+// [Files] CsmOptOutSetup.c
+//
+// 9 7/02/13 5:06p Artems
+// [TAG] EIP125900
+// [Category] Improvement
+// [Description] Funciton IsUefiGop assumed, that GOP protocol installed
+// on the same handle
+// where PciIO is installed, which is not always the case.
+// Updated to handle different cases
+// [Files] CsmOptOutSetup.c
+//
+// 8 2/26/13 1:47p Artems
+// [TAG] EIP111710
+// [Category] Improvement
+// [Description] Added multilanguage support for error message box
+// [Files] CsmOptOutSetup.c
+//
+// 7 1/22/13 4:29p Artems
+// [TAG] EIP111710
+// [Category] Improvement
+// [Description] Replace MessageBox message and title with string tokens
+// to allow
+// different language usage
+// [Files] CsmOptOut.mak CsmOptOut.uni CsmOptOutSetup.c
+//
+// 6 9/27/12 7:14p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Secureboot enable callbacks moved to Secure Boot module
+// [Files] CsmOptOut.sdl CsmOptOutSetup.c
+//
+// 5 9/11/12 5:26p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Changed dependency on secureboot pkg module revision
+// [Files] CsmOptOutSetup.c
+//
+// 4 9/04/12 3:15p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] Use EFI_UNSUPPORTED status in Browser callback to
+// discard control value instead of FORM_DISCARD
+// [Files] CsmOptOutSetup.c
+//
+// 3 8/29/12 2:26p Artems
+// [TAG] EIP98995
+// [Category] Improvement
+// [Description] When enable secure boot disable CSM but preserve CSM
+// optout options setting,
+// so once secure boot is disabled they can be restored
+// [Files] CsmOptOut.sd, CsmOptOut.sdl, CsmOptOutSetup.c
+// CsmOptOutRuntime.c
+//
+// 2 6/20/12 6:10p Artems
+// [TAG] EIP83692
+// [Category] Improvement
+// [Description] CSM OptOut setup page grayed out if secure boot is
+// enabled
+// CSM OptOut PlatformOverride protocol modified to fix SCT bugs
+// Removed support for Launch CSM "Auto" option
+//
+// [Files] CsmOptOut.c CsmOptOut.mak CsmOptOut.sd CsmOptOut.sdl
+// CsmOptOut.uni CsmOptOutRuntime.c CsmOptOutSetup.c
+//
+// 1 5/21/12 4:34p Artems
+// [TAG] EIP N/A
+// [Category] New Feature
+// [Description] Prevent user from disable CSM in setup if active video
+// is legacy
+// [Files] CsmOptOutSetup.c CsmOptOut.sdl CsmOptOut.mak
+// CsmOptOut.sdl
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CsmOptOutSetup.c
+//
+// Description: Implementation of interactive callback to "Launch CSM" setup control
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include <AmiLoadCsmPolicy.h>
+#include <Protocol/GraphicsOutput.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/AmiPostMgr.h>
+#include <Protocol/HiiString.h>
+
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+static EFI_GUID AmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+static AMI_POST_MANAGER_PROTOCOL* AmiPostMgr = NULL;
+
+extern const char *DefaultLanguageCode;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsUefiGop
+//
+// Description: This function checks wheter passed controller is managed by UEFI GOP driver
+//
+// Input:
+// IN EFI_HANDLE pci_hnd - handle of the controller
+//
+// Output:
+// 0 - controller managed by legacy driver
+// 1 - controller managed by UEFI driver
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsUefiGop(
+ IN EFI_HANDLE pci_hnd
+)
+{
+ EFI_STATUS Status;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *ent;
+ UINTN n_ent;
+ UINTN i;
+ VOID *p;
+ static EFI_GUID AmiCsmThunkProtocolGuid = AMI_CSM_THUNK_PROTOCOL_GUID;
+ BOOLEAN Result = TRUE;
+
+ Status = pBS->OpenProtocolInformation(pci_hnd, &gEfiPciIoProtocolGuid, &ent, &n_ent);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ for(i = 0; i < n_ent; i++) {
+ if(!(ent[i].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER))
+ continue;
+
+ Status = pBS->HandleProtocol(ent[i].AgentHandle, &AmiCsmThunkProtocolGuid, &p);
+ if(!EFI_ERROR(Status)) {
+ Result = FALSE;
+ break;
+ }
+ }
+ pBS->FreePool(ent);
+
+ return Result;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsLegacyVideo
+//
+// Description: This function checks if active video is Legacy or UEFI
+//
+// Input:
+// None
+//
+// Output:
+// 0 - active video is UEFI
+// 1 - active vide is Legacy
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsLegacyVideo(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *hnd;
+ EFI_HANDLE pci_hnd;
+ UINTN n_hnd;
+ UINTN i;
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiGraphicsOutputProtocolGuid, NULL, &n_hnd, &hnd);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ for(i = 0; i < n_hnd; i++) {
+ Status = pBS->HandleProtocol(hnd[i], &gEfiDevicePathProtocolGuid, &dp);
+ if(EFI_ERROR(Status))
+ continue;
+ Status = pBS->LocateDevicePath(&gEfiPciIoProtocolGuid, &dp, &pci_hnd);
+ if(EFI_ERROR(Status))
+ continue;
+
+ if(IsUefiGop(pci_hnd))
+ return FALSE;
+ }
+ pBS->FreePool(hnd);
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetCurrentLanguage
+//
+// Description: This function retrieves current platform language and stores it in
+// passed pointer
+//
+// Input: CHAR8 ** Lang - pointer to where to store current language
+// BOOLEAN *Allocated - flag if memory was allocated for language
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetCurrentLanguage(
+ CHAR8 ** Language,
+ BOOLEAN *Allocated
+)
+{
+ EFI_STATUS Status;
+ UINTN Size = 0;
+
+ *Allocated = FALSE;
+
+ Status = pRS->GetVariable(L"PlatformLang", &EfiVariableGuid, NULL, &Size, *Language);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, Language);
+ if(!EFI_ERROR(Status)) {
+ Status = pRS->GetVariable(L"PlatformLang", &EfiVariableGuid, NULL, &Size, *Language);
+ *Allocated = TRUE;
+ }
+ }
+ if(EFI_ERROR(Status))
+ *Language = (CHAR8 *)DefaultLanguageCode;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLangString
+//
+// Description: This function reads a string from HII database with different languages
+//
+// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle
+// IN STRING_REF Token - String Token
+// IN OUT UINTN *StringSize - Length of the StringBuffer in bytes
+// OUT EFI_STRING *StringBuffer - The pointer to the buffer to receive
+// the characters in the string.
+//
+// Output: EFI_STATUS - Depending on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetLangString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID Token,
+ IN OUT UINTN *StringSize,
+ OUT EFI_STRING StringBuffer
+)
+{
+ EFI_STATUS Status;
+ EFI_HII_STRING_PROTOCOL *HiiString;
+ CHAR8 *Language;
+ BOOLEAN Allocated;
+
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, &HiiString);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ GetCurrentLanguage(&Language, &Allocated);
+
+ Status = HiiString->GetString(HiiString, Language, HiiHandle, Token, StringBuffer, StringSize, NULL);
+ if(Status == EFI_INVALID_LANGUAGE) {
+ if(Allocated)
+ Status = HiiString->GetString(HiiString, (CHAR8 *)DefaultLanguageCode, HiiHandle, Token, StringBuffer, StringSize, NULL);
+ }
+
+ if(Status == EFI_INVALID_LANGUAGE)
+ Status = HiiString->GetString(HiiString, LANGUAGE_CODE_ENGLISH, HiiHandle, Token, StringBuffer, StringSize, NULL);
+
+ if(Allocated)
+ pBS->FreePool(Language);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetUniString
+//
+// Description: This function reads a string from HII database
+//
+// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle
+// IN STRING_REF Token - String Token
+// IN OUT UINTN *StringSize - Length of the StringBuffer in bytes
+// OUT EFI_STRING *StringBuffer - The pointer to the buffer to receive
+// the characters in the string.
+//
+// Output: EFI_STATUS - Depending on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetUniString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID Token,
+ IN OUT UINTN *StringSize,
+ OUT EFI_STRING *StringBuffer
+)
+{
+ EFI_STATUS Status;
+
+ if (*StringBuffer == NULL)
+ *StringSize = 0; //reset size if buffer is NULL
+
+
+ Status = GetLangString(HiiHandle, Token, StringSize, *StringBuffer);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, *StringSize, StringBuffer);
+ if(!EFI_ERROR(Status))
+ Status = GetLangString(HiiHandle, Token, StringSize, *StringBuffer);
+ }
+
+ if(EFI_ERROR(Status))
+ *StringBuffer = NULL;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CsmOptOutLaunchCallback
+//
+// Description: This function checks if CSM can be disabled in current boot
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle - HII handle of formset
+// IN UINT16 Class - class of formset
+// IN UINT16 SubClass - subclass of formset
+// IN UINT16 Key - Id of setup control
+//
+// Output:
+// EF_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CsmOptOutLaunchCallback(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 Class,
+ IN UINT16 SubClass,
+ IN UINT16 Key
+)
+{
+ EFI_STATUS Status;
+ UINT8 MsgKey;
+ EFI_BROWSER_ACTION_REQUEST *rq;
+ EFI_STRING Title = NULL;
+ EFI_STRING Message = NULL;
+ UINTN Size;
+
+
+ CALLBACK_PARAMETERS *Callback = NULL;
+
+ Callback = GetCallbackParameters();
+ if(!Callback || Callback->Action != EFI_BROWSER_ACTION_CHANGING)
+ return EFI_UNSUPPORTED;
+
+ rq = Callback->ActionRequest;
+ *rq = EFI_BROWSER_ACTION_REQUEST_NONE;
+
+ if(Callback->Value->u8 == 0) {
+ /* trying to disable CSM */
+ if(IsLegacyVideo()) {
+ if(AmiPostMgr == NULL)
+ Status = pBS->LocateProtocol(&AmiPostManagerProtocolGuid, NULL, &AmiPostMgr);
+ if(EFI_ERROR(Status))
+ return Status;
+ GetUniString(HiiHandle, STRING_TOKEN(STR_LEGACY_VIDEO_MSGBOX_TITLE), &Size, &Title);
+ GetUniString(HiiHandle, STRING_TOKEN(STR_LEGACY_VIDEO_MSGBOX_MESSAGE), &Size, &Message);
+
+ Status = AmiPostMgr->DisplayMsgBox((Title == NULL)? L" Warning " : Title,
+ (Message == NULL)? L"Video is in Legacy mode. Select Video policy UEFI only, reboot and try again" : Message,
+ MSGBOX_TYPE_OK,
+ &MsgKey);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/EBC/EBC.cif b/Core/EM/EBC/EBC.cif
new file mode 100644
index 0000000..12fc2ee
--- /dev/null
+++ b/Core/EM/EBC/EBC.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "EBC"
+ category = ModulePart
+ LocalRoot = "Core\EM\EBC\"
+ RefName = "EBC"
+[files]
+"EBC.sdl"
+"EBC.mak"
+"EBC.dxs"
+"EBC.efi"
+"EBCx64.efi"
+<endComponent>
diff --git a/Core/EM/EBC/EBC.dxs b/Core/EM/EBC/EBC.dxs
new file mode 100644
index 0000000..1ad369a
--- /dev/null
+++ b/Core/EM/EBC/EBC.dxs
@@ -0,0 +1,54 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Ebc/EBC.dxs 1 5/13/11 5:03p Artems $
+//
+// $Revision: 1 $
+//
+// $Date: 5/13/11 5:03p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Ebc/EBC.dxs $
+//
+// 1 5/13/11 5:03p Artems
+//
+// 6 1/13/10 2:13p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EBC.dxs
+//
+// Description: Dependency expression for the component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/EBC/EBC.efi b/Core/EM/EBC/EBC.efi
new file mode 100644
index 0000000..d1d204c
--- /dev/null
+++ b/Core/EM/EBC/EBC.efi
Binary files differ
diff --git a/Core/EM/EBC/EBC.mak b/Core/EM/EBC/EBC.mak
new file mode 100644
index 0000000..a735c1c
--- /dev/null
+++ b/Core/EM/EBC/EBC.mak
@@ -0,0 +1,69 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/Ebc/EBC.mak 1 5/13/11 5:03p Artems $
+#
+# $Revision: 1 $
+#
+# $Date: 5/13/11 5:03p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/Ebc/EBC.mak $
+#
+# 1 5/13/11 5:03p Artems
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: EBC.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : EBC
+
+EBC : $(BUILD_DIR)\EBC.mak EBCBin
+
+$(BUILD_DIR)\EBC.mak : $(EBC_DIR)\$(@B).cif $(EBC_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(EBC_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+EBCBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\EBC.mak all\
+ GUID=13AC6DD0-73D0-11D4-B06B-00AA00BD6DE7\
+!IF "$(x64_BUILD)"=="1"
+ EFI_FILE=$(EBC_DIR)\EBCx64.efi\
+!ELSE
+ EFI_FILE=$(EBC_DIR)\EBC.efi\
+!ENDIF
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/EBC/EBC.sdl b/Core/EM/EBC/EBC.sdl
new file mode 100644
index 0000000..4d0bb1f
--- /dev/null
+++ b/Core/EM/EBC/EBC.sdl
@@ -0,0 +1,24 @@
+TOKEN
+ Name = "EBC_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable EBC support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "EBC_DIR"
+End
+
+MODULE
+ Help = "Includes EBC.mak to Project"
+ File = "EBC.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\EBC.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/EBC/EBCx64.efi b/Core/EM/EBC/EBCx64.efi
new file mode 100644
index 0000000..ab9f85b
--- /dev/null
+++ b/Core/EM/EBC/EBCx64.efi
Binary files differ
diff --git a/Core/EM/EdkIILib/Console.c b/Core/EM/EdkIILib/Console.c
new file mode 100644
index 0000000..dbb0745
--- /dev/null
+++ b/Core/EM/EdkIILib/Console.c
@@ -0,0 +1,200 @@
+/** @file
+ This module provide help function for displaying unicode string.
+
+ Copyright (c) 2006 - 2009, Intel Corporation<BR>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+
+
+#include <EdkIICommon.h>
+#include <AmiDxeLib.h>
+#include <Protocol/SimpleTextIn.h>
+
+
+#define EFI_SIMPLE_TEXT_OUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+#define EFI_SIMPLE_TEXT_OUTPUT_MODE SIMPLE_TEXT_OUTPUT_MODE
+
+
+
+/**
+ Draws a dialog box to the console output device specified by
+ ConOut defined in the EFI_SYSTEM_TABLE and waits for a keystroke
+ from the console input device specified by ConIn defined in the
+ EFI_SYSTEM_TABLE.
+
+ If there are no strings in the variable argument list, then ASSERT().
+ If all the strings in the variable argument list are empty, then ASSERT().
+
+ @param[in] Attribute Specifies the foreground and background color of the popup.
+ @param[out] Key A pointer to the EFI_KEY value of the key that was
+ pressed. This is an optional parameter that may be NULL.
+ If it is NULL then no wait for a keypress will be performed.
+ @param[in] ... The variable argument list that contains pointers to Null-
+ terminated Unicode strings to display in the dialog box.
+ The variable argument list is terminated by a NULL.
+
+**/
+VOID
+EFIAPI
+CreatePopUp (
+ IN UINTN Attribute,
+ OUT EFI_INPUT_KEY *Key, OPTIONAL
+ ...
+ )
+{
+ VA_LIST Args;
+ EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *ConOut;
+ EFI_SIMPLE_TEXT_OUTPUT_MODE SavedConsoleMode;
+ UINTN Columns;
+ UINTN Rows;
+ UINTN Column;
+ UINTN Row;
+ UINTN NumberOfLines;
+ UINTN MaxLength;
+ CHAR16 *String;
+ UINTN Length;
+ CHAR16 *Line;
+ UINTN EventIndex;
+
+ //
+ // Determine the length of the longest line in the popup and the the total
+ // number of lines in the popup
+ //
+ VA_START (Args, Key);
+ MaxLength = 0;
+ NumberOfLines = 0;
+ while ((String = VA_ARG (Args, CHAR16 *)) != NULL) {
+ MaxLength = MAX (MaxLength, StrLen (String));
+ NumberOfLines++;
+ }
+ VA_END (Args);
+
+ //
+ // If the total number of lines in the popup is zero, then ASSERT()
+ //
+ ASSERT (NumberOfLines != 0);
+
+ //
+ // If the maximum length of all the strings is zero, then ASSERT()
+ //
+ ASSERT (MaxLength != 0);
+
+ //
+ // Cache a pointer to the Simple Text Output Protocol in the EFI System Table
+ //
+ ConOut = gST->ConOut;
+
+ //
+ // Save the current console cursor position and attributes
+ //
+ CopyMem (&SavedConsoleMode, ConOut->Mode, sizeof (SavedConsoleMode));
+
+ //
+ // Retrieve the number of columns and rows in the current console mode
+ //
+ ConOut->QueryMode (ConOut, SavedConsoleMode.Mode, &Columns, &Rows);
+
+ //
+ // Disable cursor and set the foreground and background colors specified by Attribute
+ //
+ ConOut->EnableCursor (ConOut, FALSE);
+ ConOut->SetAttribute (ConOut, Attribute);
+
+ //
+ // Limit NumberOfLines to height of the screen minus 3 rows for the box itself
+ //
+ NumberOfLines = MIN (NumberOfLines, Rows - 3);
+
+ //
+ // Limit MaxLength to width of the screen minus 2 columns for the box itself
+ //
+ MaxLength = MIN (MaxLength, Columns - 2);
+
+ //
+ // Compute the starting row and starting column for the popup
+ //
+ Row = (Rows - (NumberOfLines + 3)) / 2;
+ Column = (Columns - (MaxLength + 2)) / 2;
+
+ //
+ // Allocate a buffer for a single line of the popup with borders and a Null-terminator
+ //
+ Line = AllocateZeroPool ((MaxLength + 3) * sizeof (CHAR16));
+ ASSERT (Line != NULL);
+
+ //
+ // Draw top of popup box
+ //
+ SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);
+ Line[0] = BOXDRAW_DOWN_RIGHT;
+ Line[MaxLength + 1] = BOXDRAW_DOWN_LEFT;
+ Line[MaxLength + 2] = L'\0';
+ ConOut->SetCursorPosition (ConOut, Column, Row++);
+ ConOut->OutputString (ConOut, Line);
+
+ //
+ // Draw middle of the popup with strings
+ //
+ VA_START (Args, Key);
+ while ((String = VA_ARG (Args, CHAR16 *)) != NULL && NumberOfLines > 0) {
+ Length = StrLen (String);
+ SetMem16 (Line, (MaxLength + 2) * 2, L' ');
+ if (Length <= MaxLength) {
+ //
+ // Length <= MaxLength
+ //
+ CopyMem (Line + 1 + (MaxLength - Length) / 2, String , Length * sizeof (CHAR16));
+ } else {
+ //
+ // Length > MaxLength
+ //
+ CopyMem (Line + 1, String + (Length - MaxLength) / 2 , MaxLength * sizeof (CHAR16));
+ }
+ Line[0] = BOXDRAW_VERTICAL;
+ Line[MaxLength + 1] = BOXDRAW_VERTICAL;
+ Line[MaxLength + 2] = L'\0';
+ ConOut->SetCursorPosition (ConOut, Column, Row++);
+ ConOut->OutputString (ConOut, Line);
+ NumberOfLines--;
+ }
+ VA_END (Args);
+
+ //
+ // Draw bottom of popup box
+ //
+ SetMem16 (Line, (MaxLength + 2) * 2, BOXDRAW_HORIZONTAL);
+ Line[0] = BOXDRAW_UP_RIGHT;
+ Line[MaxLength + 1] = BOXDRAW_UP_LEFT;
+ Line[MaxLength + 2] = L'\0';
+ ConOut->SetCursorPosition (ConOut, Column, Row++);
+ ConOut->OutputString (ConOut, Line);
+
+ //
+ // Free the allocated line buffer
+ //
+ FreePool (Line);
+
+ //
+ // Restore the cursor visibility, position, and attributes
+ //
+ ConOut->EnableCursor (ConOut, SavedConsoleMode.CursorVisible);
+ ConOut->SetCursorPosition (ConOut, SavedConsoleMode.CursorColumn, SavedConsoleMode.CursorRow);
+ ConOut->SetAttribute (ConOut, SavedConsoleMode.Attribute);
+
+ //
+ // Wait for a keystroke
+ //
+ if (Key != NULL) {
+ gBS->WaitForEvent (1, &gST->ConIn->WaitForKey, &EventIndex);
+ gST->ConIn->ReadKeyStroke (gST->ConIn, Key);
+ }
+}
diff --git a/Core/EM/EdkIILib/EdkIICommonWrap.c b/Core/EM/EdkIILib/EdkIICommonWrap.c
new file mode 100644
index 0000000..a4c967d
--- /dev/null
+++ b/Core/EM/EdkIILib/EdkIICommonWrap.c
@@ -0,0 +1,318 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/EdkIICompLib/EdkIICommonWrap.c 2 5/13/11 5:46p Artems $
+//
+// $Revision: 2 $
+//
+// $Date: 5/13/11 5:46p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EdkIICompLib/EdkIICommonWrap.c $
+//
+// 2 5/13/11 5:46p Artems
+// Added functions CopyMem and ZeroMem
+//
+// 1 5/05/11 5:06p Artems
+// EdkII compatibility library
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EdkIICommonWrap.c
+//
+// Description:
+//
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <AmiDxeLib.h>
+#include <EdkIICommon.h>
+
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+
+INTN CompareMem(
+ IN VOID *DestinationBuffer,
+ IN VOID *SourceBuffer,
+ IN UINTN Length)
+{
+ return MemCmp(DestinationBuffer, SourceBuffer, Length);
+}
+
+
+VOID* CopyMem(
+ OUT VOID *DestinationBuffer,
+ IN VOID *SourceBuffer,
+ IN UINTN Length)
+{
+ MemCpy(DestinationBuffer, SourceBuffer, Length);
+ return DestinationBuffer;
+}
+
+VOID* ZeroMem(
+ OUT VOID *Buffer,
+ IN UINTN Length)
+{
+ MemSet(Buffer, Length, 0);
+ return Buffer;
+}
+
+BOOLEAN CompareGuid(
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2)
+{
+ return (guidcmp(Guid1, Guid2)) ? FALSE : TRUE;
+}
+
+
+VOID* AllocateRuntimePool(
+ IN UINTN AllocationSize)
+{
+ VOID *p;
+ EFI_STATUS Status;
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, AllocationSize, &p);
+ return (EFI_ERROR(Status)) ? NULL : p;
+}
+
+VOID* AllocatePool(
+ IN UINTN AllocationSize)
+{
+ VOID *p;
+ EFI_STATUS Status;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, AllocationSize, &p);
+ return (EFI_ERROR(Status)) ? NULL : p;
+}
+
+VOID* AllocateZeroPool(
+ IN UINTN AllocationSize)
+{
+ VOID *p;
+
+ p = AllocatePool(AllocationSize);
+ if(p != NULL)
+ MemSet(p, AllocationSize, 0);
+
+ return p;
+}
+
+VOID* AllocateCopyPool(
+ IN UINTN AllocationSize,
+ IN VOID *Buffer)
+{
+ VOID *p;
+
+ p = AllocatePool(AllocationSize);
+ if(p != NULL)
+ MemCpy(p, Buffer, AllocationSize);
+
+ return p;
+}
+
+VOID* ReallocatePool (
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID *OldBuffer OPTIONAL)
+{
+ VOID *p;
+
+ p = AllocateZeroPool(NewSize);
+ if(p != NULL && OldBuffer != NULL) {
+ MemCpy(p, OldBuffer, MIN(OldSize, NewSize));
+ pBS->FreePool(OldBuffer);
+ }
+
+ return p;
+}
+
+VOID FreePool(
+ IN VOID *Buffer)
+{
+ pBS->FreePool(Buffer);
+}
+
+EFI_STATUS EfiGetSystemConfigurationTable(
+ IN EFI_GUID *TableGuid,
+ OUT VOID **Table)
+{
+ *Table = GetEfiConfigurationTable(pST, TableGuid);
+ return (*Table == NULL) ? EFI_NOT_FOUND : EFI_SUCCESS;
+}
+
+UINTN GetDevicePathSize(
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ return DPLength(DevicePath);
+}
+
+EFI_DEVICE_PATH_PROTOCOL* DevicePathFromHandle(
+ IN EFI_HANDLE Handle)
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_STATUS Status;
+
+ Status = pBS->HandleProtocol(
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath);
+ return (EFI_ERROR(Status)) ? NULL : DevicePath;
+}
+
+UINTN UnicodeSPrint (
+ OUT CHAR16 *StartOfBuffer,
+ IN UINTN BufferSize,
+ IN CHAR16 *FormatString,
+ ...)
+{
+ UINTN n;
+ va_list ArgList = va_start(ArgList, FormatString);
+ n = Swprintf_s_va_list(StartOfBuffer, BufferSize, FormatString, ArgList);
+ va_end(ArgList);
+ return n;
+}
+
+UINTN UnicodeVSPrint (
+ OUT CHAR16 *StartOfBuffer,
+ IN UINTN BufferSize,
+ IN CHAR16 *FormatString,
+ IN VA_LIST Marker)
+{
+ UINTN n;
+ n = Swprintf_s_va_list(StartOfBuffer, BufferSize, FormatString, Marker);
+ return n;
+}
+
+EFI_GUID* CopyGuid (
+ OUT EFI_GUID *DestinationGuid,
+ IN EFI_GUID *SourceGuid)
+{
+ *DestinationGuid = *SourceGuid;
+ return DestinationGuid;
+}
+
+VOID InitEfiPointers(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ pBS = SystemTable->BootServices;
+ pRS = SystemTable->RuntimeServices;
+ gBS = pBS;
+ gRT = pRS;
+ gST = SystemTable;
+}
+
+UINTN AsciiStrLen (
+ IN CHAR8 *String)
+{
+ UINTN Length;
+
+ for (Length = 0; *String != '\0'; String++, Length++);
+
+ return Length;
+}
+
+UINTN StrLen (
+ IN CHAR16 *String)
+{
+ UINTN Length;
+
+ for (Length = 0; *String != L'\0'; String++, Length++);
+
+ return Length;
+}
+
+UINTN StrSize (
+ IN CHAR16 *String)
+{
+ UINTN Size;
+
+ for (Size = 2; *String != L'\0'; String++, Size += 2);
+
+ return Size;
+}
+
+INTN StrCmp (
+ IN CHAR16 *FirstString,
+ IN CHAR16 *SecondString
+)
+{
+ return Wcscmp(FirstString, SecondString);
+}
+
+VOID* SetMem16 (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT16 Value)
+{
+ UINTN i;
+
+ Length /= 2; //we have input length in bytes
+
+ for(i = 0; i < Length; i++)
+ *((UINT16 *)Buffer + i) = Value;
+ return Buffer;
+}
+
+CHAR16* StrCpy (
+ OUT CHAR16 *Destination,
+ IN CHAR16 *Source)
+{
+ CHAR16 *ReturnValue;
+
+ ReturnValue = Destination;
+ while (*Source != 0) {
+ *(Destination++) = *(Source++);
+ }
+ *Destination = 0;
+ return ReturnValue;
+}
+
+CHAR16* StrCat (
+ IN OUT CHAR16 *Destination,
+ IN CHAR16 *Source)
+{
+ StrCpy (Destination + StrLen (Destination), Source);
+
+ return Destination;
+}
+
+VOID* GetEfiGlobalVariable (
+ IN CHAR16 *Name)
+{
+ EFI_STATUS Status;
+ VOID *Var = 0;
+ UINTN VarSize;
+
+ Status = GetEfiVariable(Name, &gEfiGlobalVariableGuid, NULL, &VarSize, &Var);
+ return (EFI_ERROR(Status)) ? NULL : Var;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/EdkIILib/EdkIIHiiLib.c b/Core/EM/EdkIILib/EdkIIHiiLib.c
new file mode 100644
index 0000000..521bba4
--- /dev/null
+++ b/Core/EM/EdkIILib/EdkIIHiiLib.c
@@ -0,0 +1,1328 @@
+/** @file
+ HII Library implementation that uses DXE protocols and services.
+
+ Copyright (c) 2006 - 2010, Intel Corporation<BR>
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#pragma warning (disable : 4090)
+
+#include <EdkIICommon.h>
+#include <EdkIIHii.h>
+#include <AmiDxeLib.h>
+#include <Protocol/HiiDatabase.h>
+
+/////////////////////////////////////////
+/////////////////////////////////////////
+/// IFR Functions
+/////////////////////////////////////////
+/////////////////////////////////////////
+
+#define HII_LIB_OPCODE_ALLOCATION_SIZE 0x200
+
+typedef struct {
+ UINT8 *Buffer;
+ UINTN BufferSize;
+ UINTN Position;
+} HII_LIB_OPCODE_BUFFER;
+
+///
+/// Lookup table that converts EFI_IFR_TYPE_X enum values to a width in bytes
+///
+GLOBAL_REMOVE_IF_UNREFERENCED CONST UINT8 mHiiDefaultTypeToWidth[] = {
+ 1, // EFI_IFR_TYPE_NUM_SIZE_8
+ 2, // EFI_IFR_TYPE_NUM_SIZE_16
+ 4, // EFI_IFR_TYPE_NUM_SIZE_32
+ 8, // EFI_IFR_TYPE_NUM_SIZE_64
+ 1, // EFI_IFR_TYPE_BOOLEAN
+ 3, // EFI_IFR_TYPE_TIME
+ 4, // EFI_IFR_TYPE_DATE
+ 2 // EFI_IFR_TYPE_STRING
+};
+
+static EFI_HII_DATABASE_PROTOCOL *gHiiDatabase = NULL;
+
+/**
+ Allocates and returns a new OpCode Handle. OpCode Handles must be freed with
+ HiiFreeOpCodeHandle().
+
+ @retval NULL There are not enough resources to allocate a new OpCode Handle.
+ @retval Other A new OpCode handle.
+
+**/
+VOID *
+EFIAPI
+HiiAllocateOpCodeHandle (
+ VOID
+ )
+{
+ HII_LIB_OPCODE_BUFFER *OpCodeBuffer;
+
+ OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)AllocatePool (sizeof (HII_LIB_OPCODE_BUFFER));
+ if (OpCodeBuffer == NULL) {
+ return NULL;
+ }
+ OpCodeBuffer->Buffer = (UINT8 *)AllocatePool (HII_LIB_OPCODE_ALLOCATION_SIZE);
+ if (OpCodeBuffer->Buffer == NULL) {
+ FreePool (OpCodeBuffer);
+ return NULL;
+ }
+ OpCodeBuffer->BufferSize = HII_LIB_OPCODE_ALLOCATION_SIZE;
+ OpCodeBuffer->Position = 0;
+ return (VOID *)OpCodeBuffer;
+}
+
+/**
+ Frees an OpCode Handle that was previously allocated with HiiAllocateOpCodeHandle().
+ When an OpCode Handle is freed, all of the opcodes associated with the OpCode
+ Handle are also freed.
+
+ If OpCodeHandle is NULL, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+
+**/
+VOID
+EFIAPI
+HiiFreeOpCodeHandle (
+ VOID *OpCodeHandle
+ )
+{
+ HII_LIB_OPCODE_BUFFER *OpCodeBuffer;
+
+ ASSERT (OpCodeHandle != NULL);
+
+ OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle;
+ if (OpCodeBuffer->Buffer != NULL) {
+ FreePool (OpCodeBuffer->Buffer);
+ }
+ FreePool (OpCodeBuffer);
+}
+
+/**
+ Internal function gets the current position of opcode buffer.
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+
+ @return Current position of opcode buffer.
+**/
+UINTN
+EFIAPI
+InternalHiiOpCodeHandlePosition (
+ IN VOID *OpCodeHandle
+ )
+{
+ return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Position;
+}
+
+/**
+ Internal function gets the start pointer of opcode buffer.
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+
+ @return Pointer to the opcode buffer base.
+**/
+UINT8 *
+EFIAPI
+InternalHiiOpCodeHandleBuffer (
+ IN VOID *OpCodeHandle
+ )
+{
+ return ((HII_LIB_OPCODE_BUFFER *)OpCodeHandle)->Buffer;
+}
+
+/**
+ Internal function reserves the enough buffer for current opcode.
+ When the buffer is not enough, Opcode buffer will be extended.
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] Size Size of current opcode.
+
+ @return Pointer to the current opcode.
+**/
+UINT8 *
+EFIAPI
+InternalHiiGrowOpCodeHandle (
+ IN VOID *OpCodeHandle,
+ IN UINTN Size
+ )
+{
+ HII_LIB_OPCODE_BUFFER *OpCodeBuffer;
+ UINT8 *Buffer;
+
+ ASSERT (OpCodeHandle != NULL);
+
+ OpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)OpCodeHandle;
+ if (OpCodeBuffer->Position + Size > OpCodeBuffer->BufferSize) {
+ Buffer = ReallocatePool (
+ OpCodeBuffer->BufferSize,
+ OpCodeBuffer->BufferSize + (Size + HII_LIB_OPCODE_ALLOCATION_SIZE),
+ OpCodeBuffer->Buffer
+ );
+ if (Buffer == NULL) {
+ return NULL;
+ }
+ OpCodeBuffer->Buffer = Buffer;
+ OpCodeBuffer->BufferSize += (Size + HII_LIB_OPCODE_ALLOCATION_SIZE);
+ }
+ Buffer = OpCodeBuffer->Buffer + OpCodeBuffer->Position;
+ OpCodeBuffer->Position += Size;
+ return Buffer;
+}
+
+/**
+ Internal function creates opcode based on the template opcode.
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] OpCodeTemplate Pointer to the template buffer of opcode.
+ @param[in] OpCode OpCode IFR value.
+ @param[in] OpCodeSize Size of opcode.
+ @param[in] ExtensionSize Size of extended opcode.
+ @param[in] Scope Scope bit of opcode.
+
+ @return Pointer to the current opcode with opcode data.
+**/
+UINT8 *
+EFIAPI
+InternalHiiCreateOpCodeExtended (
+ IN VOID *OpCodeHandle,
+ IN VOID *OpCodeTemplate,
+ IN UINT8 OpCode,
+ IN UINTN OpCodeSize,
+ IN UINTN ExtensionSize,
+ IN UINT8 Scope
+ )
+{
+ EFI_IFR_OP_HEADER *Header;
+ UINT8 *Buffer;
+
+ ASSERT (OpCodeTemplate != NULL);
+ ASSERT ((OpCodeSize + ExtensionSize) <= 0x7F);
+
+ Header = (EFI_IFR_OP_HEADER *)OpCodeTemplate;
+ Header->OpCode = OpCode;
+ Header->Scope = Scope;
+ Header->Length = (UINT8)(OpCodeSize + ExtensionSize);
+ Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, Header->Length);
+ return (UINT8 *)CopyMem (Buffer, Header, OpCodeSize);
+}
+
+/**
+ Internal function creates opcode based on the template opcode for the normal opcode.
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] OpCodeTemplate Pointer to the template buffer of opcode.
+ @param[in] OpCode OpCode IFR value.
+ @param[in] OpCodeSize Size of opcode.
+
+ @return Pointer to the current opcode with opcode data.
+**/
+UINT8 *
+EFIAPI
+InternalHiiCreateOpCode (
+ IN VOID *OpCodeHandle,
+ IN VOID *OpCodeTemplate,
+ IN UINT8 OpCode,
+ IN UINTN OpCodeSize
+ )
+{
+ return InternalHiiCreateOpCodeExtended (OpCodeHandle, OpCodeTemplate, OpCode, OpCodeSize, 0, 0);
+}
+
+/**
+ Append raw opcodes to an OpCodeHandle.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If RawBuffer is NULL, then ASSERT();
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] RawBuffer Buffer of opcodes to append.
+ @param[in] RawBufferSize The size, in bytes, of Buffer.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the appended opcodes.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateRawOpCodes (
+ IN VOID *OpCodeHandle,
+ IN UINT8 *RawBuffer,
+ IN UINTN RawBufferSize
+ )
+{
+ UINT8 *Buffer;
+
+ ASSERT (RawBuffer != NULL);
+
+ Buffer = InternalHiiGrowOpCodeHandle (OpCodeHandle, RawBufferSize);
+ return (UINT8 *)CopyMem (Buffer, RawBuffer, RawBufferSize);
+}
+
+/**
+ Append opcodes from one OpCode Handle to another OpCode handle.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If RawOpCodeHandle is NULL, then ASSERT();
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] RawOpCodeHandle Handle to the buffer of opcodes.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the appended opcodes.
+
+**/
+UINT8 *
+EFIAPI
+InternalHiiAppendOpCodes (
+ IN VOID *OpCodeHandle,
+ IN VOID *RawOpCodeHandle
+ )
+{
+ HII_LIB_OPCODE_BUFFER *RawOpCodeBuffer;
+
+ ASSERT (RawOpCodeHandle != NULL);
+
+ RawOpCodeBuffer = (HII_LIB_OPCODE_BUFFER *)RawOpCodeHandle;
+ return HiiCreateRawOpCodes (OpCodeHandle, RawOpCodeBuffer->Buffer, RawOpCodeBuffer->Position);
+}
+
+/**
+ Create EFI_IFR_END_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateEndOpCode (
+ IN VOID *OpCodeHandle
+ )
+{
+ EFI_IFR_END OpCode;
+
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_END_OP, sizeof (OpCode));
+}
+
+/**
+ Create EFI_IFR_ONE_OF_OPTION_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If Type is invalid, then ASSERT().
+ If Flags is invalid, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] StringId StringId for the option
+ @param[in] Flags Flags for the option
+ @param[in] Type Type for the option
+ @param[in] Value Value for the option
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateOneOfOptionOpCode (
+ IN VOID *OpCodeHandle,
+ IN UINT16 StringId,
+ IN UINT8 Flags,
+ IN UINT8 Type,
+ IN UINT64 Value
+ )
+{
+ EFI_IFR_ONE_OF_OPTION OpCode;
+
+ ASSERT (Type < EFI_IFR_TYPE_OTHER);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Option = StringId;
+ OpCode.Flags = (UINT8) (Flags & (EFI_IFR_OPTION_DEFAULT | EFI_IFR_OPTION_DEFAULT_MFG));
+ OpCode.Type = Type;
+ CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
+
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OPTION_OP, sizeof (OpCode));
+}
+
+/**
+ Create EFI_IFR_DEFAULT_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If Type is invalid, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] DefaultId DefaultId for the default
+ @param[in] Type Type for the default
+ @param[in] Value Value for the default
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateDefaultOpCode (
+ IN VOID *OpCodeHandle,
+ IN UINT16 DefaultId,
+ IN UINT8 Type,
+ IN UINT64 Value
+ )
+{
+ EFI_IFR_DEFAULT OpCode;
+
+ ASSERT (Type < EFI_IFR_TYPE_OTHER);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Type = Type;
+ OpCode.DefaultId = DefaultId;
+ CopyMem (&OpCode.Value, &Value, mHiiDefaultTypeToWidth[Type]);
+
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_DEFAULT_OP, sizeof (OpCode));
+}
+
+/**
+ Create EFI_IFR_GUID opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If Guid is NULL, then ASSERT().
+ If OpCodeSize < sizeof (EFI_IFR_GUID), then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] Guid Pointer to EFI_GUID of this guided opcode.
+ @param[in] GuidOpCode Pointer to an EFI_IFR_GUID opcode. This is an
+ optional parameter that may be NULL. If this
+ parameter is NULL, then the GUID extension
+ region of the created opcode is filled with zeros.
+ If this parameter is not NULL, then the GUID
+ extension region of GuidData will be copied to
+ the GUID extension region of the created opcode.
+ @param[in] OpCodeSize The size, in bytes, of created opcode. This value
+ must be >= sizeof(EFI_IFR_GUID).
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateGuidOpCode (
+ IN VOID *OpCodeHandle,
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *GuidOpCode, OPTIONAL
+ IN UINTN OpCodeSize
+ )
+{
+ EFI_IFR_GUID OpCode;
+ EFI_IFR_GUID *OpCodePointer;
+
+ ASSERT (Guid != NULL);
+ ASSERT (OpCodeSize >= sizeof (OpCode));
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ CopyGuid ((EFI_GUID *)(VOID *)&OpCode.Guid, Guid);
+
+ OpCodePointer = (EFI_IFR_GUID *)InternalHiiCreateOpCodeExtended (
+ OpCodeHandle,
+ &OpCode,
+ EFI_IFR_GUID_OP,
+ sizeof (OpCode),
+ OpCodeSize - sizeof (OpCode),
+ 0
+ );
+ if (OpCodePointer != NULL && GuidOpCode != NULL) {
+ CopyMem (OpCodePointer + 1, (EFI_IFR_GUID *)GuidOpCode + 1, OpCodeSize - sizeof (OpCode));
+ }
+ return (UINT8 *)OpCodePointer;
+}
+
+/**
+ Create EFI_IFR_ACTION_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] QuestionId Question ID
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] QuestionConfig String ID for configuration
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateActionOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_STRING_ID QuestionConfig
+ )
+{
+ EFI_IFR_ACTION OpCode;
+
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.QuestionConfig = QuestionConfig;
+
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_ACTION_OP, sizeof (OpCode));
+}
+
+/**
+ Create EFI_IFR_SUBTITLE_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in Flags, then ASSERT().
+ If Scope > 1, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] Flags Subtitle opcode flags
+ @param[in] Scope 1 if this opcpde is the beginning of a new scope.
+ 0 if this opcode is within the current scope.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateSubTitleOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 Flags,
+ IN UINT8 Scope
+ )
+{
+ EFI_IFR_SUBTITLE OpCode;
+
+ ASSERT (Scope <= 1);
+ ASSERT ((Flags & (~(EFI_IFR_FLAGS_HORIZONTAL))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Statement.Prompt = Prompt;
+ OpCode.Statement.Help = Help;
+ OpCode.Flags = Flags;
+
+ return InternalHiiCreateOpCodeExtended (
+ OpCodeHandle,
+ &OpCode,
+ EFI_IFR_SUBTITLE_OP,
+ sizeof (OpCode),
+ 0,
+ Scope
+ );
+}
+
+/**
+ Create EFI_IFR_REF_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] FormId Destination Form ID
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] QuestionId Question ID
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateGotoOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_FORM_ID FormId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_QUESTION_ID QuestionId
+ )
+{
+ EFI_IFR_REF OpCode;
+
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.FormId = FormId;
+
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_REF_OP, sizeof (OpCode));
+}
+
+/**
+ Create EFI_IFR_CHECKBOX_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+ If any reserved bits are set in CheckBoxFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] QuestionId Question ID
+ @param[in] VarStoreId Storage ID
+ @param[in] VarOffset Offset in Storage
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] CheckBoxFlags Flags for checkbox opcode
+ @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
+ is an optional parameter that may be NULL.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateCheckBoxOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 CheckBoxFlags,
+ IN VOID *DefaultsOpCodeHandle OPTIONAL
+ )
+{
+ EFI_IFR_CHECKBOX OpCode;
+ UINTN Position;
+
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.VarStoreId = VarStoreId;
+ OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.Flags = CheckBoxFlags;
+
+ if (DefaultsOpCodeHandle == NULL) {
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode));
+ }
+
+ Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_CHECKBOX_OP, sizeof (OpCode), 0, 1);
+ InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
+ HiiCreateEndOpCode (OpCodeHandle);
+ return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
+}
+
+/**
+ Create EFI_IFR_NUMERIC_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+ If any reserved bits are set in NumericFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] QuestionId Question ID
+ @param[in] VarStoreId Storage ID
+ @param[in] VarOffset Offset in Storage
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] NumericFlags Flags for numeric opcode
+ @param[in] Minimum Numeric minimum value
+ @param[in] Maximum Numeric maximum value
+ @param[in] Step Numeric step for edit
+ @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
+ is an optional parameter that may be NULL.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateNumericOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 NumericFlags,
+ IN UINT64 Minimum,
+ IN UINT64 Maximum,
+ IN UINT64 Step,
+ IN VOID *DefaultsOpCodeHandle OPTIONAL
+ )
+{
+ EFI_IFR_NUMERIC OpCode;
+ UINTN Position;
+
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.VarStoreId = VarStoreId;
+ OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.Flags = NumericFlags;
+
+ switch (NumericFlags & EFI_IFR_NUMERIC_SIZE) {
+ case EFI_IFR_NUMERIC_SIZE_1:
+ OpCode.data.u8.MinValue = (UINT8)Minimum;
+ OpCode.data.u8.MaxValue = (UINT8)Maximum;
+ OpCode.data.u8.Step = (UINT8)Step;
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_2:
+ OpCode.data.u16.MinValue = (UINT16)Minimum;
+ OpCode.data.u16.MaxValue = (UINT16)Maximum;
+ OpCode.data.u16.Step = (UINT16)Step;
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_4:
+ OpCode.data.u32.MinValue = (UINT32)Minimum;
+ OpCode.data.u32.MaxValue = (UINT32)Maximum;
+ OpCode.data.u32.Step = (UINT32)Step;
+ break;
+
+ case EFI_IFR_NUMERIC_SIZE_8:
+ OpCode.data.u64.MinValue = Minimum;
+ OpCode.data.u64.MaxValue = Maximum;
+ OpCode.data.u64.Step = Step;
+ break;
+ }
+
+ if (DefaultsOpCodeHandle == NULL) {
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, sizeof (OpCode));
+ }
+
+ Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_NUMERIC_OP, sizeof (OpCode), 0, 1);
+ InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
+ HiiCreateEndOpCode (OpCodeHandle);
+ return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
+}
+
+/**
+ Create EFI_IFR_STRING_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+ If any reserved bits are set in StringFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] QuestionId Question ID
+ @param[in] VarStoreId Storage ID
+ @param[in] VarOffset Offset in Storage
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] StringFlags Flags for string opcode
+ @param[in] MinSize String minimum length
+ @param[in] MaxSize String maximum length
+ @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
+ is an optional parameter that may be NULL.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateStringOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 StringFlags,
+ IN UINT8 MinSize,
+ IN UINT8 MaxSize,
+ IN VOID *DefaultsOpCodeHandle OPTIONAL
+ )
+{
+ EFI_IFR_STRING OpCode;
+ UINTN Position;
+
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.VarStoreId = VarStoreId;
+ OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.MinSize = MinSize;
+ OpCode.MaxSize = MaxSize;
+ OpCode.Flags = (UINT8) (StringFlags & EFI_IFR_STRING_MULTI_LINE);
+
+ if (DefaultsOpCodeHandle == NULL) {
+ return InternalHiiCreateOpCode (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode));
+ }
+
+ Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_STRING_OP, sizeof (OpCode), 0, 1);
+ InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
+ HiiCreateEndOpCode (OpCodeHandle);
+ return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
+}
+
+/**
+ Create EFI_IFR_ONE_OF_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+ If any reserved bits are set in OneOfFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] QuestionId Question ID
+ @param[in] VarStoreId Storage ID
+ @param[in] VarOffset Offset in Storage
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] OneOfFlags Flags for oneof opcode
+ @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
+ @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
+ is an optional parameter that may be NULL.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateOneOfOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 OneOfFlags,
+ IN VOID *OptionsOpCodeHandle,
+ IN VOID *DefaultsOpCodeHandle OPTIONAL
+ )
+{
+ EFI_IFR_ONE_OF OpCode;
+ UINTN Position;
+
+ ASSERT (OptionsOpCodeHandle != NULL);
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.VarStoreId = VarStoreId;
+ OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.Flags = OneOfFlags;
+
+ Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ONE_OF_OP, sizeof (OpCode), 0, 1);
+ InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle);
+ if (DefaultsOpCodeHandle != NULL) {
+ InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
+ }
+ HiiCreateEndOpCode (OpCodeHandle);
+ return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
+}
+
+/**
+ Create EFI_IFR_ORDERED_LIST_OP opcode.
+
+ If OpCodeHandle is NULL, then ASSERT().
+ If any reserved bits are set in QuestionFlags, then ASSERT().
+ If any reserved bits are set in OrderedListFlags, then ASSERT().
+
+ @param[in] OpCodeHandle Handle to the buffer of opcodes.
+ @param[in] QuestionId Question ID
+ @param[in] VarStoreId Storage ID
+ @param[in] VarOffset Offset in Storage
+ @param[in] Prompt String ID for Prompt
+ @param[in] Help String ID for Help
+ @param[in] QuestionFlags Flags in Question Header
+ @param[in] OrderedListFlags Flags for ordered list opcode
+ @param[in] DataType Type for option value
+ @param[in] MaxContainers Maximum count for options in this ordered list
+ @param[in] OptionsOpCodeHandle Handle for a buffer of ONE_OF_OPTION opcodes.
+ @param[in] DefaultsOpCodeHandle Handle for a buffer of DEFAULT opcodes. This
+ is an optional parameter that may be NULL.
+
+ @retval NULL There is not enough space left in Buffer to add the opcode.
+ @retval Other A pointer to the created opcode.
+
+**/
+UINT8 *
+EFIAPI
+HiiCreateOrderedListOpCode (
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_VARSTORE_ID VarStoreId,
+ IN UINT16 VarOffset,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN UINT8 OrderedListFlags,
+ IN UINT8 DataType,
+ IN UINT8 MaxContainers,
+ IN VOID *OptionsOpCodeHandle,
+ IN VOID *DefaultsOpCodeHandle OPTIONAL
+ )
+{
+ EFI_IFR_ORDERED_LIST OpCode;
+ UINTN Position;
+
+ ASSERT (OptionsOpCodeHandle != NULL);
+ ASSERT ((QuestionFlags & (~(EFI_IFR_FLAG_READ_ONLY | EFI_IFR_FLAG_CALLBACK | EFI_IFR_FLAG_RESET_REQUIRED | EFI_IFR_FLAG_OPTIONS_ONLY))) == 0);
+
+ ZeroMem (&OpCode, sizeof (OpCode));
+ OpCode.Question.Header.Prompt = Prompt;
+ OpCode.Question.Header.Help = Help;
+ OpCode.Question.QuestionId = QuestionId;
+ OpCode.Question.VarStoreId = VarStoreId;
+ OpCode.Question.VarStoreInfo.VarOffset = VarOffset;
+ OpCode.Question.Flags = QuestionFlags;
+ OpCode.MaxContainers = MaxContainers;
+ OpCode.Flags = OrderedListFlags;
+
+ Position = InternalHiiOpCodeHandlePosition (OpCodeHandle);
+ InternalHiiCreateOpCodeExtended (OpCodeHandle, &OpCode, EFI_IFR_ORDERED_LIST_OP, sizeof (OpCode), 0, 1);
+ InternalHiiAppendOpCodes (OpCodeHandle, OptionsOpCodeHandle);
+ if (DefaultsOpCodeHandle != NULL) {
+ InternalHiiAppendOpCodes (OpCodeHandle, DefaultsOpCodeHandle);
+ }
+ HiiCreateEndOpCode (OpCodeHandle);
+ return InternalHiiOpCodeHandleBuffer (OpCodeHandle) + Position;
+}
+
+/**
+ This is the internal worker function to update the data in
+ a form specified by FormSetGuid, FormId and Label.
+
+ @param[in] FormSetGuid The optional Formset GUID.
+ @param[in] FormId The Form ID.
+ @param[in] Package The package header.
+ @param[in] OpCodeBufferStart An OpCode buffer that contains the set of IFR
+ opcodes to be inserted or replaced in the form.
+ @param[in] OpCodeBufferEnd An OpCcode buffer that contains the IFR opcode
+ that marks the end of a replace operation in the form.
+ @param[out] TempPackage The resultant package.
+
+ @retval EFI_SUCCESS The function completes successfully.
+ @retval EFI_NOT_FOUND The updated opcode or endopcode is not found.
+
+**/
+EFI_STATUS
+EFIAPI
+InternalHiiUpdateFormPackageData (
+ IN EFI_GUID *FormSetGuid, OPTIONAL
+ IN EFI_FORM_ID FormId,
+ IN EFI_HII_PACKAGE_HEADER *Package,
+ IN HII_LIB_OPCODE_BUFFER *OpCodeBufferStart,
+ IN HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd, OPTIONAL
+ OUT EFI_HII_PACKAGE_HEADER *TempPackage
+ )
+{
+ UINTN AddSize;
+ UINT8 *BufferPos;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ UINTN Offset;
+ EFI_IFR_OP_HEADER *IfrOpHdr;
+ EFI_IFR_OP_HEADER *UpdateIfrOpHdr;
+ BOOLEAN GetFormSet;
+ BOOLEAN GetForm;
+ BOOLEAN Updated;
+ UINTN UpdatePackageLength;
+
+ CopyMem (TempPackage, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ UpdatePackageLength = sizeof (EFI_HII_PACKAGE_HEADER);
+ BufferPos = (UINT8 *) (TempPackage + 1);
+
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ IfrOpHdr = (EFI_IFR_OP_HEADER *)((UINT8 *) Package + sizeof (EFI_HII_PACKAGE_HEADER));
+ Offset = sizeof (EFI_HII_PACKAGE_HEADER);
+ GetFormSet = (BOOLEAN) ((FormSetGuid == NULL) ? TRUE : FALSE);
+ GetForm = FALSE;
+ Updated = FALSE;
+
+ while (Offset < PackageHeader.Length) {
+ CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
+ BufferPos += IfrOpHdr->Length;
+ UpdatePackageLength += IfrOpHdr->Length;
+
+ //
+ // Find the matched FormSet and Form
+ //
+ if ((IfrOpHdr->OpCode == EFI_IFR_FORM_SET_OP) && (FormSetGuid != NULL)) {
+ if (CompareGuid((EFI_GUID *)(VOID *)&((EFI_IFR_FORM_SET *) IfrOpHdr)->Guid, FormSetGuid)) {
+ GetFormSet = TRUE;
+ } else {
+ GetFormSet = FALSE;
+ }
+ } else if (IfrOpHdr->OpCode == EFI_IFR_FORM_OP || IfrOpHdr->OpCode == EFI_IFR_FORM_MAP_OP) {
+ if (CompareMem (&((EFI_IFR_FORM *) IfrOpHdr)->FormId, &FormId, sizeof (EFI_FORM_ID)) == 0) {
+ GetForm = TRUE;
+ } else {
+ GetForm = FALSE;
+ }
+ }
+
+ //
+ // The matched Form is found, and Update data in this form
+ //
+ if (GetFormSet && GetForm) {
+ UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *) OpCodeBufferStart->Buffer;
+ if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \
+ (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0)) {
+ //
+ // Remove the original data when End OpCode buffer exist.
+ //
+ if (OpCodeBufferEnd != NULL) {
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((UINT8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ UpdateIfrOpHdr = (EFI_IFR_OP_HEADER *) OpCodeBufferEnd->Buffer;
+ while (Offset < PackageHeader.Length) {
+ //
+ // Search the matched end opcode
+ //
+ if ((UpdateIfrOpHdr->Length == IfrOpHdr->Length) && \
+ (CompareMem (IfrOpHdr, UpdateIfrOpHdr, UpdateIfrOpHdr->Length) == 0)) {
+ break;
+ }
+ //
+ // Go to the next Op-Code
+ //
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((UINT8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ }
+
+ if (Offset >= PackageHeader.Length) {
+ //
+ // The end opcode is not found.
+ //
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ //
+ // Insert the updated data
+ //
+ AddSize = ((EFI_IFR_OP_HEADER *) OpCodeBufferStart->Buffer)->Length;
+ CopyMem (BufferPos, OpCodeBufferStart->Buffer + AddSize, OpCodeBufferStart->Position - AddSize);
+ BufferPos += OpCodeBufferStart->Position - AddSize;
+ UpdatePackageLength += OpCodeBufferStart->Position - AddSize;
+
+ if (OpCodeBufferEnd != NULL) {
+ //
+ // Add the end opcode
+ //
+ CopyMem (BufferPos, IfrOpHdr, IfrOpHdr->Length);
+ BufferPos += IfrOpHdr->Length;
+ UpdatePackageLength += IfrOpHdr->Length;
+ }
+
+ //
+ // Copy the left package data.
+ //
+ Offset += IfrOpHdr->Length;
+ CopyMem (BufferPos, (UINT8 *) Package + Offset, PackageHeader.Length - Offset);
+ UpdatePackageLength += PackageHeader.Length - Offset;
+
+ //
+ // Set update flag
+ //
+ Updated = TRUE;
+ break;
+ }
+ }
+
+ //
+ // Go to the next Op-Code
+ //
+ Offset += IfrOpHdr->Length;
+ IfrOpHdr = (EFI_IFR_OP_HEADER *) ((CHAR8 *) (IfrOpHdr) + IfrOpHdr->Length);
+ }
+
+ if (!Updated) {
+ //
+ // The updated opcode buffer is not found.
+ //
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Update the package length.
+ //
+ PackageHeader.Length = (UINT32) UpdatePackageLength;
+ CopyMem (TempPackage, &PackageHeader, sizeof (EFI_HII_PACKAGE_HEADER));
+
+ return EFI_SUCCESS;
+}
+
+/**
+ This function updates a form that has previously been registered with the HII
+ Database. This function will perform at most one update operation.
+
+ The form to update is specified by Handle, FormSetGuid, and FormId. Binary
+ comparisons of IFR opcodes are performed from the beginning of the form being
+ updated until an IFR opcode is found that exactly matches the first IFR opcode
+ specified by StartOpCodeHandle. The following rules are used to determine if
+ an insert, replace, or delete operation is performed.
+
+ 1) If no matches are found, then NULL is returned.
+ 2) If a match is found, and EndOpCodeHandle is NULL, then all of the IFR opcodes
+ from StartOpCodeHandle except the first opcode are inserted immediately after
+ the matching IFR opcode in the form to be updated.
+ 3) If a match is found, and EndOpCodeHandle is not NULL, then a search is made
+ from the matching IFR opcode until an IFR opcode exactly matches the first
+ IFR opcode specified by EndOpCodeHandle. If no match is found for the first
+ IFR opcode specified by EndOpCodeHandle, then NULL is returned. If a match
+ is found, then all of the IFR opcodes between the start match and the end
+ match are deleted from the form being updated and all of the IFR opcodes
+ from StartOpCodeHandle except the first opcode are inserted immediately after
+ the matching start IFR opcode. If StartOpCcodeHandle only contains one
+ IFR instruction, then the result of this operation will delete all of the IFR
+ opcodes between the start end matches.
+
+ If HiiHandle is NULL, then ASSERT().
+ If StartOpCodeHandle is NULL, then ASSERT().
+
+ @param[in] HiiHandle The HII Handle of the form to update.
+ @param[in] FormSetGuid The Formset GUID of the form to update. This
+ is an optional parameter that may be NULL.
+ If it is NULL, all FormSet will be updated.
+ @param[in] FormId The ID of the form to update.
+ @param[in] StartOpCodeHandle An OpCode Handle that contains the set of IFR
+ opcodes to be inserted or replaced in the form.
+ The first IFR instruction in StartOpCodeHandle
+ is used to find matching IFR opcode in the
+ form.
+ @param[in] EndOpCodeHandle An OpCcode Handle that contains the IFR opcode
+ that marks the end of a replace operation in
+ the form. This is an optional parameter that
+ may be NULL. If it is NULL, then an the IFR
+ opcodes specified by StartOpCodeHandle are
+ inserted into the form.
+
+ @retval EFI_OUT_OF_RESOURCES No enough memory resource is allocated.
+ @retval EFI_NOT_FOUND The following cases will return EFI_NOT_FOUND.
+ 1) The form specified by HiiHandle, FormSetGuid,
+ and FormId could not be found in the HII Database.
+ 2) No IFR opcodes in the target form match the first
+ IFR opcode in StartOpCodeHandle.
+ 3) EndOpCOde is not NULL, and no IFR opcodes in the
+ target form following a matching start opcode match
+ the first IFR opcode in EndOpCodeHandle.
+ @retval EFI_SUCCESS The matched form is updated by StartOpcode.
+
+**/
+EFI_STATUS
+EFIAPI
+HiiUpdateForm (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid, OPTIONAL
+ IN EFI_FORM_ID FormId,
+ IN VOID *StartOpCodeHandle,
+ IN VOID *EndOpCodeHandle OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_HII_PACKAGE_LIST_HEADER *HiiPackageList;
+ UINT32 PackageListLength;
+ UINT32 Offset;
+ EFI_HII_PACKAGE_LIST_HEADER *UpdatePackageList;
+ UINTN BufferSize;
+ UINT8 *UpdateBufferPos;
+ EFI_HII_PACKAGE_HEADER *Package;
+ EFI_HII_PACKAGE_HEADER *TempPacakge;
+ EFI_HII_PACKAGE_HEADER PackageHeader;
+ BOOLEAN Updated;
+ HII_LIB_OPCODE_BUFFER *OpCodeBufferStart;
+ HII_LIB_OPCODE_BUFFER *OpCodeBufferEnd;
+
+ //
+ // Input update data can't be NULL.
+ //
+ ASSERT (HiiHandle != NULL);
+ ASSERT (StartOpCodeHandle != NULL);
+ UpdatePackageList = NULL;
+ TempPacakge = NULL;
+ HiiPackageList = NULL;
+
+ //
+ // Retrieve buffer data from Opcode Handle
+ //
+ OpCodeBufferStart = (HII_LIB_OPCODE_BUFFER *) StartOpCodeHandle;
+ OpCodeBufferEnd = (HII_LIB_OPCODE_BUFFER *) EndOpCodeHandle;
+
+ if(gHiiDatabase == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **) &gHiiDatabase);
+ if(EFI_ERROR(Status))
+ return Status;
+ }
+
+ //
+ // Get the original package list
+ //
+ BufferSize = 0;
+ HiiPackageList = NULL;
+ Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
+ //
+ // The return status should always be EFI_BUFFER_TOO_SMALL as input buffer's size is 0.
+ //
+ if (Status != EFI_BUFFER_TOO_SMALL) {
+ return Status;
+ }
+
+ HiiPackageList = AllocatePool (BufferSize);
+ if (HiiPackageList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
+ Status = gHiiDatabase->ExportPackageLists (gHiiDatabase, HiiHandle, &BufferSize, HiiPackageList);
+ if (EFI_ERROR (Status)) {
+ goto Finish;
+ }
+
+ //
+ // Calculate and allocate space for retrieval of IFR data
+ //
+ BufferSize += OpCodeBufferStart->Position;
+ UpdatePackageList = AllocateZeroPool (BufferSize);
+ if (UpdatePackageList == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
+ //
+ // Allocate temp buffer to store the temp updated package buffer
+ //
+ TempPacakge = AllocateZeroPool (BufferSize);
+ if (TempPacakge == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Finish;
+ }
+
+ UpdateBufferPos = (UINT8 *) UpdatePackageList;
+
+ //
+ // Copy the package list header
+ //
+ CopyMem (UpdateBufferPos, HiiPackageList, sizeof (EFI_HII_PACKAGE_LIST_HEADER));
+ UpdateBufferPos += sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+ //
+ // Go through each package to find the matched package and update one by one
+ //
+ Updated = FALSE;
+ Offset = sizeof (EFI_HII_PACKAGE_LIST_HEADER);
+
+// PackageListLength = ReadUnaligned32 (&HiiPackageList->PackageLength);
+ PackageListLength = HiiPackageList->PackageLength;
+
+ while (Offset < PackageListLength) {
+ Package = (EFI_HII_PACKAGE_HEADER *) (((UINT8 *) HiiPackageList) + Offset);
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ Offset += Package->Length;
+
+ if (Package->Type == EFI_HII_PACKAGE_FORMS) {
+ //
+ // Check this package is the matched package.
+ //
+ Status = InternalHiiUpdateFormPackageData (FormSetGuid, FormId, Package, OpCodeBufferStart, OpCodeBufferEnd, TempPacakge);
+ //
+ // The matched package is found. Its package buffer will be updated by the input new data.
+ //
+ if (!EFI_ERROR(Status)) {
+ //
+ // Set Update Flag
+ //
+ Updated = TRUE;
+ //
+ // Add updated package buffer
+ //
+ Package = TempPacakge;
+ }
+ }
+
+ //
+ // Add pacakge buffer
+ //
+ CopyMem (&PackageHeader, Package, sizeof (EFI_HII_PACKAGE_HEADER));
+ CopyMem (UpdateBufferPos, Package, PackageHeader.Length);
+ UpdateBufferPos += PackageHeader.Length;
+ }
+
+ if (Updated) {
+ //
+ // Update package list length
+ //
+ BufferSize = UpdateBufferPos - (UINT8 *) UpdatePackageList;
+
+// WriteUnaligned32 (&UpdatePackageList->PackageLength, (UINT32) BufferSize);
+ UpdatePackageList->PackageLength = (UINT32) BufferSize;
+
+ //
+ // Update Package to show form
+ //
+ Status = gHiiDatabase->UpdatePackageList (gHiiDatabase, HiiHandle, UpdatePackageList);
+ } else {
+ //
+ // Not matched form is found and updated.
+ //
+ Status = EFI_NOT_FOUND;
+ }
+
+Finish:
+ if (HiiPackageList != NULL) {
+ FreePool (HiiPackageList);
+ }
+
+ if (UpdatePackageList != NULL) {
+ FreePool (UpdatePackageList);
+ }
+
+ if (TempPacakge != NULL) {
+ FreePool (TempPacakge);
+ }
+
+ return Status;
+}
+
+#pragma warning (default : 4090)
diff --git a/Core/EM/EdkIILib/EdkIIHiiWrap.c b/Core/EM/EdkIILib/EdkIIHiiWrap.c
new file mode 100644
index 0000000..db79ce9
--- /dev/null
+++ b/Core/EM/EdkIILib/EdkIIHiiWrap.c
@@ -0,0 +1,233 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Core/EdkIICompLib/EdkIIHiiWrap.c 2 5/13/11 6:17p Artems $
+//
+// $Revision: 2 $
+//
+// $Date: 5/13/11 6:17p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EdkIICompLib/EdkIIHiiWrap.c $
+//
+// 2 5/13/11 6:17p Artems
+// Bugfix: avoid using uninitialized pointer
+//
+// 1 5/05/11 5:06p Artems
+// EdkII compatibility library
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EdkIIHiiWrap.c
+//
+// Description:
+//
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <AmiDxeLib.h>
+#include <EdkIIHii.h>
+#include <Protocol/HiiString.h>
+
+
+static EFI_HII_STRING_PROTOCOL *HiiString = NULL;
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+
+
+EFI_STRING HiiGetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId,
+ IN CONST CHAR8 *Language OPTIONAL)
+{
+ EFI_STRING String = NULL;
+ UINTN StringSize = 0;
+ EFI_STATUS Status;
+ CHAR8* PlatformLang = NULL;
+ UINTN Size = 0;
+
+ if(HiiString == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
+ if(EFI_ERROR(Status))
+ return NULL;
+ }
+
+ if(Language != NULL) {
+ Status = HiiString->GetString(HiiString, Language, HiiHandle, StringId, String, &StringSize, NULL);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, StringSize, &String);
+ if(!EFI_ERROR(Status))
+ Status = HiiString->GetString(HiiString, Language, HiiHandle, StringId, String, &StringSize, NULL);
+ }
+ if(EFI_ERROR(Status) && Status != EFI_INVALID_LANGUAGE)
+ return NULL; //string not found
+ }
+
+//language not provided - try platform language
+ Status = GetEfiVariable(L"PlatformLang", &EfiVariableGuid, NULL, &Size, &PlatformLang);
+ if(!EFI_ERROR(Status)) {
+ Status = HiiString->GetString(HiiString, PlatformLang, HiiHandle, StringId, String, &StringSize, NULL);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, StringSize, &String);
+ if(!EFI_ERROR(Status))
+ Status = HiiString->GetString(HiiString, PlatformLang, HiiHandle, StringId, String, &StringSize, NULL);
+ }
+ pBS->FreePool(PlatformLang);
+ }
+ return (EFI_ERROR(Status)) ? NULL : String;
+}
+
+
+EFI_STRING_ID HiiSetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId, OPTIONAL
+ IN EFI_STRING String,
+ IN CHAR8 *SupportedLanguages OPTIONAL)
+{
+ EFI_STATUS Status;
+ CHAR8* Languages = NULL;
+ UINTN LangSize = 0;
+ CHAR8* CurrentLanguage;
+ BOOLEAN LastLanguage = FALSE;
+
+ if(HiiString == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
+ if(EFI_ERROR(Status))
+ return 0;
+ }
+
+ if(SupportedLanguages == NULL) {
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, Languages, &LangSize);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, LangSize, &Languages);
+ if(EFI_ERROR(Status))
+ return NULL; //not enough resources to allocate string
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, Languages, &LangSize);
+ }
+ if(EFI_ERROR(Status))
+ return 0;
+ } else {
+ Languages = SupportedLanguages;
+ }
+
+ while(!LastLanguage) {
+ CurrentLanguage = Languages; //point CurrentLanguage to start of new language
+ while(*Languages != ';' && *Languages != 0)
+ Languages++;
+
+ if(*Languages == 0) { //last language in language list
+ LastLanguage = TRUE;
+ if(StringId == 0)
+ Status = HiiString->NewString(HiiString, HiiHandle, &StringId, CurrentLanguage, NULL, String, NULL);
+ else
+ Status = HiiString->SetString(HiiString, HiiHandle, StringId, CurrentLanguage, String, NULL);
+ if(EFI_ERROR(Status))
+ return 0;
+ } else {
+ *Languages = 0; //put null-terminator
+ if(StringId == 0)
+ Status = HiiString->NewString(HiiString, HiiHandle, &StringId, CurrentLanguage, NULL, String, NULL);
+ else
+ Status = HiiString->SetString(HiiString, HiiHandle, StringId, CurrentLanguage, String, NULL);
+ *Languages = ';'; //restore original character
+ Languages++;
+ if(EFI_ERROR(Status))
+ return 0;
+ }
+ }
+ return StringId;
+}
+
+/*
+UINT8* HiiCreateActionOpCode(
+ IN VOID *OpCodeHandle,
+ IN EFI_QUESTION_ID QuestionId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_STRING_ID QuestionConfig)
+{
+ return NULL;
+}
+
+UINT8* HiiCreateGotoOpCode(
+ IN VOID *OpCodeHandle,
+ IN EFI_FORM_ID FormId,
+ IN EFI_STRING_ID Prompt,
+ IN EFI_STRING_ID Help,
+ IN UINT8 QuestionFlags,
+ IN EFI_QUESTION_ID QuestionId)
+{
+ return NULL;
+}
+
+UINT8* HiiCreateGuidOpCode (
+ IN VOID *OpCodeHandle,
+ IN CONST EFI_GUID *Guid,
+ IN CONST VOID *GuidOpCode, OPTIONAL
+ IN UINTN OpCodeSize)
+{
+ return NULL;
+}
+
+
+EFI_STATUS HiiUpdateForm(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_GUID *FormSetGuid, OPTIONAL
+ IN EFI_FORM_ID FormId,
+ IN VOID *StartOpCodeHandle,
+ IN VOID *EndOpCodeHandle OPTIONAL)
+{
+ return EFI_UNSUPPORTED;
+}
+
+VOID* HiiAllocateOpCodeHandle(
+ VOID)
+{
+ return NULL;
+}
+
+VOID HiiFreeOpCodeHandle(
+ VOID *OpCodeHandle)
+{
+ return;
+}
+
+EFI_HII_HANDLE HiiAddPackages(
+ IN CONST EFI_GUID *PackageListGuid,
+ IN EFI_HANDLE DeviceHandle OPTIONAL,
+ ...)
+{
+ return NULL;
+}
+*/
+
+
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/EdkIILib/EdkIILib.cif b/Core/EM/EdkIILib/EdkIILib.cif
new file mode 100644
index 0000000..a1f9547
--- /dev/null
+++ b/Core/EM/EdkIILib/EdkIILib.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Edk II Compatibility library"
+ category = ModulePart
+ LocalRoot = "Core\EM\EdkIILib\"
+ RefName = "EdkIILib"
+[files]
+"EdkIILib.sdl"
+"EdkIILib.mak"
+"EdkIICommonWrap.c"
+"EdkIIHiiWrap.c"
+"EdkIIHiiLib.c"
+"Console.c"
+[parts]
+"EdkII_headers"
+<endComponent>
diff --git a/Core/EM/EdkIILib/EdkIILib.mak b/Core/EM/EdkIILib/EdkIILib.mak
new file mode 100644
index 0000000..feb0af1
--- /dev/null
+++ b/Core/EM/EdkIILib/EdkIILib.mak
@@ -0,0 +1,53 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Core/EdkIICompLib/EdkIILib.mak 1 5/05/11 5:06p Artems $
+#
+# $Revision: 1 $
+#
+# $Date: 5/05/11 5:06p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EdkIICompLib/EdkIILib.mak $
+#
+# 1 5/05/11 5:06p Artems
+# EdkII compatibility library
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: EdkIILib.mak
+#
+# Description:
+#
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+
+#CORE_DXEBin :
+
+
+$(EDK_II_LIB) : $(BUILD_DIR)\EdkIILib.mak EdkIILibBin
+
+$(BUILD_DIR)\EdkIILib.mak : $(EdkIILib_DIR)\EdkIILib.cif $(BUILD_RULES)
+ $(CIF2MAK) $(EdkIILib_DIR)\EdkIILib.cif $(CIF2MAK_DEFAULTS)
+
+EdkIILibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\EdkIILib.mak all\
+ NAME=EdkIILib\
+ MAKEFILE=$(BUILD_DIR)\EdkIILib.mak\
+ TYPE=LIBRARY
diff --git a/Core/EM/EdkIILib/EdkIILib.sdl b/Core/EM/EdkIILib/EdkIILib.sdl
new file mode 100644
index 0000000..cd491cc
--- /dev/null
+++ b/Core/EM/EdkIILib/EdkIILib.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = EdkIILib_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable Edk II compatibility library support in Project"
+End
+
+PATH
+ Name = EdkIILib_DIR
+ Help = "Path to Edk II compatibility library Module in Project"
+End
+
+MODULE
+ Help = "Includes EdkIILib.mak to Project"
+ File = "EdkIILib.mak"
+End
+
+TOKEN
+ Name = "EDK_II_LIB"
+ Value = "$$(LIB_BUILD_DIR)\EdkIILib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End \ No newline at end of file
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c
new file mode 100644
index 0000000..8aea545
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.c
@@ -0,0 +1,603 @@
+//#**********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
+//***********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.c 5 8/13/14 11:14p Walonli $
+//
+// $Revision: 5 $
+//
+// $Date: 8/13/14 11:14p $
+//***********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.c $
+//
+// 5 8/13/14 11:14p Walonli
+// [TAG] EIP180632
+// [Category] New Feature
+// [Description] Support FixedBootOrder to display Uefi OS full name
+// "Windows Boot Manager(Px: DeviceName)".
+// [Files] EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 4 5/23/14 5:08a Dukeyeh
+// [TAG] EIP167957
+// [Category] Bug Fix
+// [RootCause] EIP147262 - The "EFI OS BootOptionNames" module can't
+// support the "FixedBootOrder" module Boot option strings.
+// EIP159984 - Linux UEFI OS boot issue.
+// EIP168792 - Possible heap corruption - EFI OS BootOptionNames
+// [Solution] EIP147262 =>A new token
+// "DISPLAY_FULL_OPTION_NAME_WITH_FBO" is added to control this.
+// EIP159984 =>Should NOT kill the UEFI OS boot option that created by OS.
+// EIP168792 =>NEW_STRING_BUFFER_LENGTH is replaced with the actual size
+// of the allocated memory, NewStringLength.
+//
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOptionNames.chm
+// EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+//***********************************************************************
+//***********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiOsBootOptionNames.c
+//
+// Description: Change the Name of boot Option in Setup into format of
+// "OS Name(Px:HDD name)" or "OS Name(HDD name)" if there
+// is no port or "OS Name" if can't find controller name.
+//
+//<AMI_FHDR_END>
+//***********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Protocol\BlockIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\SimpleFileSystem.h>
+#include <Protocol\PDiskinfo.h>
+#include "boot.h" // Part of TSE Binary
+#include <Token.h>
+
+//
+// External variables (part of AMITSEBin)
+//
+extern UINTN gBootOptionCount;
+extern BOOT_DATA* gBootData;
+
+//
+// External functions
+//
+
+/*
+ This function locates the handle with BlockIo installed that provides block
+ access to the partition containing the Windows boot loader. The load option
+ (BootXXXX variable) created by Windows starts with a HD node instead of a
+ complete device path. The partition signature is used to find the complete
+ device path.
+
+ @param DevicePath
+
+ @retval EFI_DEVICE_PATH_PROTOCOL*
+*/
+EFI_DEVICE_PATH_PROTOCOL* _DiscoverPartition(
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+//
+// DEFINE
+//
+#define CONTROLLER_NAME_BUFFER_LENGTH 100
+
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: GetPhysicalBlockIoHandle
+//
+// Description:
+// Takes a handle with BlockIo providing partition access and returns
+// the handle with the BlockIo providing raw access to the drive that
+// contains the partition.
+//
+// Input:
+// IN EFI_HANDLE BlockIoHandle - Image handle with BlockIo partition access.
+//
+// Output:
+// None.
+//
+// Returns:
+// EFI_HANDLE - Handle with BlockIo that provides raw access to drive
+// containing partition.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// HandleProtocol()
+// DPCut()
+// LocateDevicePath()
+// FreePool()
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+EFI_HANDLE GetPhysicalBlockIoHandle (
+ IN EFI_HANDLE BlockIoHandle
+)
+{
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath, *Dp;
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = BlockIoHandle;
+
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ if (!BlkIo->Media->LogicalPartition) return Handle;
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiDevicePathProtocolGuid, &DevicePath
+ );
+ if (EFI_ERROR(Status)) return Handle;
+ Dp=DevicePath;
+ while(BlkIo->Media->LogicalPartition){
+ EFI_DEVICE_PATH_PROTOCOL *PrevDp=Dp;
+ //We need to cut Devicepath node to get Phisycal Partition
+ Dp=DPCut(PrevDp);
+ if (PrevDp!=DevicePath) pBS->FreePool(PrevDp);
+ if (Dp == NULL) break;
+ PrevDp=Dp;
+ Status=pBS->LocateDevicePath(
+ &gEfiBlockIoProtocolGuid,&PrevDp,&Handle
+ );
+ if(EFI_ERROR(Status)) break;
+ Status=pBS->HandleProtocol(
+ Handle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+ if(EFI_ERROR(Status)) break;
+ }
+ if (Dp!=NULL && Dp!=DevicePath) pBS->FreePool(Dp);
+ //if physical Block I/O handle is not found, return original handle
+ return (BlkIo->Media->LogicalPartition) ? BlockIoHandle : Handle;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: RemoveTrailingSpaces
+//
+// Description:
+// Removes trailing spaces from *Name.
+//
+// Input:
+// IN CHAR16 *Name - String from which trailing spaces should be removed.
+// IN UINTN NumberOfCharacters - Length of string at *Name.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINTN - Length of string after spaces have been removed.
+//
+// Modified:
+// String pointed to by *Name.
+//
+// Referrals:
+// None.
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINTN RemoveTrailingSpaces (
+ IN CHAR16 *Name,
+ IN UINTN NumberOfCharacters
+)
+{
+ //remove trailing spaces
+ while(NumberOfCharacters>0 && Name[NumberOfCharacters-1]==L' ')
+ NumberOfCharacters--;
+ Name[NumberOfCharacters]=0;
+ return NumberOfCharacters;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: ConstructBootOptionNameByHandle
+//
+// Description:
+// Construct controller name from parent Handle.
+//
+// Input:
+// IN EFI_HANDLE Handle - Handle with partition BlockIo.
+// IN CHAR16 *Name - Caller allocated string to store name in.
+// IN UINTN NameSize - Size of string buffer.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINTN - Length of controller name string.
+//
+// Modified:
+// String pointed to by *Name.
+//
+// Referrals:
+// GetPhysicalBlockIoHandle()
+// Swprintf_s()
+// RemoveTrailingSpaces()
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINTN ConstructBootOptionNameByHandle (
+ IN EFI_HANDLE Handle,
+ IN CHAR16 *Name,
+ IN UINTN NameSize
+)
+{
+ CHAR16 *ControllerName;
+ UINTN NumberOfCharacters;
+
+ if (Handle == NULL) return 0;
+
+ //Name from Controller Handle
+ Handle = GetPhysicalBlockIoHandle(Handle);
+ if (!GetControllerName(Handle, &ControllerName)) return 0;
+ NumberOfCharacters = Swprintf_s(Name, NameSize, L"%s", ControllerName);
+ return RemoveTrailingSpaces(Name, NumberOfCharacters);
+}
+
+/**
+ OEM Variable, PLEASE reference SbSetup.c and modify this function to get correct port number.
+*/
+UINT16 gSATA[3][2] = {
+ { 0, 1 },
+ { 2, 3 },
+ { 4, 5 }
+};
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: GetHDDPort
+//
+// Description:
+// Use handle and EFI_DISK_INFO_PROTOCOL to get sata hard disk port.
+//
+// Input:
+// IN EFI_HANDLE - Use in locating EFI_DISK_INFO_PROTOCOL.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINT16 - Sata port number.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// None.
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+UINT16 GetHDDPort( IN EFI_HANDLE Handle )
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath );
+
+ if( !EFI_ERROR( Status ))
+ {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *MessagingDevicePath;
+ PCI_DEVICE_PATH *PciDevicePath;
+
+ DevicePathNode = DevicePath;
+ while (!isEndNode (DevicePathNode))
+ {
+ if ((DevicePathNode->Type == HARDWARE_DEVICE_PATH)
+ && (DevicePathNode->SubType == HW_PCI_DP))
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+ else
+ if (DevicePathNode->Type == MESSAGING_DEVICE_PATH)
+ MessagingDevicePath = DevicePathNode;
+
+ DevicePathNode = NEXT_NODE (DevicePathNode);
+ }
+
+ Status = pBS->HandleProtocol ( Handle, &gEfiDiskInfoProtocolGuid, &DiskInfo );
+ if ( !EFI_ERROR(Status) )
+ {
+ Status = DiskInfo->WhichIde ( DiskInfo, &IdeChannel, &IdeDevice );
+ if( !EFI_ERROR(Status) )
+ {
+ if( MessagingDevicePath->SubType == MSG_ATAPI_DP ) //IDE mode?
+ {
+ if (PciDevicePath->Function == 5)
+ return gSATA[IdeDevice+2][IdeChannel];
+ else
+ return gSATA[IdeDevice][IdeChannel];
+ }
+ else
+ return IdeChannel; //AHCI Port Number
+ }
+ }
+ }
+ return 0xff;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: CreateNameWithUefiOS
+//
+// Description:
+// Create boot option name into format of "OS NAME(Px:HDD Name) or
+// "OS NAME(HDD Name) if there is no port or "OS_NAME" if can't find
+// controller name.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - Use in getting complete
+// device path of partition.
+// IN CHAR16 BootOptionName - Original boot option name.
+//
+// Output:
+// None.
+//
+// Returns:
+// CHAR16* - New boot option name string.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// None.
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+CHAR16* CreateNameWithUefiOS( IN EFI_DEVICE_PATH_PROTOCOL *DevicePath, IN CHAR16 *BootOptionName )
+{
+ EFI_STATUS Status;
+ CHAR16* NewString = NULL;
+ UINTN NewStringLength = 0;
+ BOOLEAN SupportsSimpleFileSystem = FALSE;
+ EFI_DEVICE_PATH_PROTOCOL* FullDevicePath = NULL;
+
+
+ FullDevicePath = _DiscoverPartition(DevicePath);
+
+ // Make sure that handle associated with full
+ // device path supports Simple File System.
+ if (FullDevicePath != NULL)
+ {
+ EFI_DEVICE_PATH_PROTOCOL* pTempDevicePath = FullDevicePath;
+ EFI_HANDLE TempHandle = NULL;
+
+ Status = pBS->LocateDevicePath (
+ &gEfiSimpleFileSystemProtocolGuid,
+ &pTempDevicePath,
+ &TempHandle );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "Does not support Simple File System.\n"));
+ SupportsSimpleFileSystem = FALSE;
+ }
+ else
+ SupportsSimpleFileSystem = TRUE;
+
+ if ( SupportsSimpleFileSystem )
+ {
+ EFI_HANDLE BlkIoPartitionHandle = NULL;
+ EFI_HANDLE ControllerHandle = NULL;
+ CHAR16 ControllerNameBuffer[CONTROLLER_NAME_BUFFER_LENGTH];
+ UINTN ControllerNameLength = 0;
+ UINT16 PortNumber = 0;
+
+ // Locate handle with above device path..
+ Status = pBS->LocateDevicePath (
+ &gEfiBlockIoProtocolGuid,
+ &FullDevicePath,
+ &BlkIoPartitionHandle );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "LocateDevicePath: %r\n", Status));
+ return NULL;
+ }
+
+ ControllerHandle = GetPhysicalBlockIoHandle(BlkIoPartitionHandle);
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "GetPhysicalBlockIoHandle: %r\n", Status));
+ return NULL;
+ }
+
+ ControllerNameLength = ConstructBootOptionNameByHandle (
+ ControllerHandle,
+ ControllerNameBuffer,
+ CONTROLLER_NAME_BUFFER_LENGTH );
+
+ // Allocate proper memory for new string and copy updated string to it.
+ NewStringLength = Wcslen(ControllerNameBuffer) + Wcslen(BootOptionName) + 0xf;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ NewStringLength * sizeof(CHAR16),
+ &NewString );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "AllocatePool: %r\n", Status));
+ return NULL;
+ }
+
+ // Append OS name and update bootdata pointer
+ PortNumber = GetHDDPort( ControllerHandle );
+ if (PortNumber != 0xff)
+ {
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s (P%d: %s)",
+ BootOptionName,
+ PortNumber,
+ ControllerNameBuffer );
+ }
+ else
+ {
+ if( ControllerNameLength == 0)
+ {
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s",
+ BootOptionName );
+ }
+ else
+ {
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s (%s)",
+ BootOptionName,
+ ControllerNameBuffer );
+ }
+ }
+
+ return NewString;
+ }
+ // Could not find drive with matching partition.
+ else
+ {
+ NewStringLength = Wcslen(L" (Drive not present)") + Wcslen(BootOptionName) + 1;
+
+ Status = pBS->AllocatePool ( EfiBootServicesData,
+ NewStringLength * sizeof(CHAR16),
+ &NewString );
+
+ if (EFI_ERROR(Status))
+ {
+ TRACE((-1, "AllocatePool: %r\n", Status));
+ return NULL;
+ }
+
+ Swprintf_s ( NewString,
+ NewStringLength,
+ L"%s (Drive not present)",
+ BootOptionName );
+
+ return NewString;
+ }
+ }// if (FullDevicePath != NULL)
+ return NULL;
+}
+
+//*************************************************************************
+//<AMI_PHDR_START>
+//
+// Name: ChangeUefiBootNames
+//
+// Description:
+// Examines boot options and adds drive information string to them.
+// This function is called at the ProcessEnterSetup hook provided by TSE.
+//
+// Input:
+// None.
+//
+// Output:
+// None.
+//
+// Returns:
+// None.
+//
+// Modified:
+// String used by TSE when displaying Windows Boot Manager boot options.
+//
+// Referrals:
+// _DiscoverPartition()
+// GetSataPortNumber()
+// LocateDevicePath()
+// GetPhysicalBlockIoHandle()
+// ConstructBootOptionNameByHandle()
+// Swprintf_s()
+//
+// Notes:
+// None.
+//
+//<AMI_PHDR_END>
+//*************************************************************************
+VOID ChangeUefiBootNames(
+ VOID
+)
+{
+ UINTN i = 0;
+
+ // Loop through all present boot options
+ for( i = 0; i < gBootOptionCount; i++ )
+ {
+ BOOT_DATA *bootData = NULL;
+
+ bootData = &(gBootData[i]);
+
+ if( bootData->DevicePath->Type == MEDIA_DEVICE_PATH
+ && bootData->DevicePath->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ CHAR16 *NewBootOptionName;
+ NewBootOptionName = CreateNameWithUefiOS( bootData->DevicePath, bootData->Name);
+ if ( NewBootOptionName )
+ {
+ bootData->Name = NewBootOptionName;
+ }
+ }
+ }//for( i = 0; i < gBootOptionCount; i++ )
+ return;
+}
+
+//***********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
+//***********************************************************************
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chm b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chm
new file mode 100644
index 0000000..c972e1e
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.chm
Binary files differ
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif
new file mode 100644
index 0000000..c3a32e3
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "EFI OS BootOptionNames"
+ category = eModule
+ LocalRoot = "Core\EM\EfiOsBootOptionNames\"
+ RefName = "EfiOsBootOptionNames"
+[files]
+"EfiOsBootOptionNames.sdl"
+"EfiOsBootOptionNames.mak"
+"EfiOsBootOptionNames.chm"
+"EfiOsBootOptionNames.sd"
+"EfiOsBootOptionNames.uni"
+"EfiOsBootOptionNames.c"
+"EfiOsBootOrder.c"
+<endComponent>
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak
new file mode 100644
index 0000000..eab36ba
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.mak
@@ -0,0 +1,123 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.mak 5 3/11/15 6:48a Dukeyeh $
+#
+# $Revision: 5 $
+#
+# $Date: 3/11/15 6:48a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.mak $
+#
+# 5 3/11/15 6:48a Dukeyeh
+# [TAG] EIP178808
+# [Category] New Feature
+# [Description] Implement the selection of
+# NEW_UEFI_OS_OPTION_ORDER_POLICY item in Setup.
+# [Files] EfiOsBootOptionNames.sdl
+# EfiOsBootOptionNames.mak
+# EfiOsBootOrder.c
+# EfiOsBootOptionNames.cif
+#
+# 4 3/11/15 3:47a Dukeyeh
+# [TAG] EIP204138
+# [Category] Improvement
+# [Description] Add a CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY
+# token to control whether create
+# "UEFI OS" boot option if can't find any other in specified file paths
+# (default) or just create it.
+# [Files] EfiOsBootOptionNames.sdl
+# EfiOsBootOptionNames.mak
+# EfiOsBootOrder.c
+#
+# 3 5/23/14 5:08a Dukeyeh
+# [TAG] EIP167957
+# [Category] Bug Fix
+# [RootCause] EIP147262 - The "EFI OS BootOptionNames" module can't
+# support the "FixedBootOrder" module Boot option strings.
+# EIP159984 - Linux UEFI OS boot issue.
+# EIP168792 - Possible heap corruption - EFI OS BootOptionNames
+# [Solution] EIP147262 =>A new token
+# "DISPLAY_FULL_OPTION_NAME_WITH_FBO" is added to control this.
+# EIP159984 =>Should NOT kill the UEFI OS boot option that created by OS.
+# EIP168792 =>NEW_STRING_BUFFER_LENGTH is replaced with the actual size
+# of the allocated memory, NewStringLength.
+#
+# [Files] EfiOsBootOptionNames.sdl
+# EfiOsBootOptionNames.mak
+# EfiOsBootOptionNames.chm
+# EfiOsBootOptionNames.c
+# EfiOsBootOrder.c
+# EfiOsBootOptionNames.cif
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: EfiOsBootOptionNames.mak
+#
+# Description:
+# Adds EfiOsBootOptionNames.obj to AMITSEBin dependencies
+# and builds EfiOsBootOptionNames.obj.
+#
+# Adds EfiOsBootOrder.obj to CORE_DXEBin dependencies
+# and builds EfiOsBootOrder.obj.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+#
+# EfiOsBootOrder.c
+#
+CORE_DXEBin : $(BUILD_DIR)\EfiOsBootOrder.obj
+
+$(BUILD_DIR)\EfiOsBootOrder.obj : $(EfiOsBootOptionNames_DIR)\EfiOsBootOrder.c EfiOsFilePathMapElinkList
+ $(CC) $(CFLAGS) /I$(TSEBIN_DIR)\Inc /I$(CORE_DXE_DIR) /Fo$(BUILD_DIR)\ $(EfiOsBootOptionNames_DIR)\EfiOsBootOrder.c $(BUILD_DIR)\EfiOsNamesFilePathMaps.h
+
+EfiOsFilePathMapElinkList:
+ $(SILENT)type << >$(BUILD_DIR)\EfiOsNamesFilePathMaps.h
+#define EfiOsFilePathMaps $(EfiOsBootOptionNamesFilePathItem)
+<<
+
+#
+# EfiOsBootOptionNames.c
+#
+AMITSEBin: $(BUILD_DIR)\EfiOsBootOptionNames.obj
+
+$(BUILD_DIR)\EfiOsBootOptionNames.obj : $(EfiOsBootOptionNames_DIR)\EfiOsBootOptionNames.c
+ $(CC) $(CFLAGS) /I$(TSEBIN_DIR)\Inc /Fo$(BUILD_DIR)\ $(EfiOsBootOptionNames_DIR)\EfiOsBootOptionNames.c
+
+#
+# SDB
+#
+SetupSdbs : $(BUILD_DIR)\EfiOsBootOptionNames.sdb
+
+$(BUILD_DIR)\EfiOsBootOptionNames.sdb : $(EfiOsBootOptionNames_DIR)\$(@B).sd $(EfiOsBootOptionNames_DIR)\$(@B).uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\$(@B).sdb $(EfiOsBootOptionNames_DIR)\$(@B).uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\$(@B).sdb -od $(BUILD_DIR)\$(@B).sdb $(EfiOsBootOptionNames_DIR)\$(@B).sd
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd
new file mode 100644
index 0000000..8f99071
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sd
@@ -0,0 +1,118 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.sd 1 3/11/15 6:45a Dukeyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 3/11/15 6:45a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOptionNames.sd $
+//
+// 1 3/11/15 6:45a Dukeyeh
+// [TAG] EIP178808
+// [Category] Improvement
+// [Description] Setup definition for EfiOsBootOptionNames module.
+// [Files] EfiOsBootOptionNames.sd
+//
+// 6 1/13/10 2:13p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiOsBootOptionNames.sd
+//
+// Description: EfiOsBootOptionNames setup items
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <token.h>
+
+#ifdef SETUP_DATA_DEFINITION
+/***********************************************************/
+/* Put NVRAM data definitions here.
+/* For example: UINT8 Data1;
+/* These definitions will be converted by the build process
+/* to a definitions of SETUP_DATA fields.
+/***********************************************************/
+#endif
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+///
+/// Put control definitions here.
+///
+
+#define EOBON_ONEOF_NEW_OPTION_POLICY\
+ oneof varid = NEW_OPTION_POLICY.NewOptionPolicy,\
+ prompt = STRING_TOKEN(STR_NEW_OPTION_POLICY),\
+ help = STRING_TOKEN(STR_NEW_OPTION_POLICY_HELP),\
+ default = NEW_UEFI_OS_OPTION_ORDER_POLICY,\
+ option text = STRING_TOKEN(STR_NEW_OPTION_POLICY_NOT_OVERRIDE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_NEW_OPTION_POLICY_FIRST), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_NEW_OPTION_POLICY_LAST), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+
+#endif
+
+#ifdef CONTROLS_WITH_DEFAULTS
+///
+/// List macros of all the controls attached to the actual data.
+///
+ //EOBON_ONEOF_NEW_OPTION_POLICY
+#endif
+
+#ifdef BOOT_FORM_SET
+
+ #ifdef FORM_SET_TYPEDEF
+ typedef struct {
+ UINT8 NewOptionPolicy;
+ } NEW_OPTION_POLICY;
+ #endif
+
+ #ifdef FORM_SET_VARSTORE
+ varstore NEW_OPTION_POLICY,
+ key = AUTO_ID(EOBON_NEW_OPTION_POLICY_KEY),
+ name = NewOptionPolicy,
+ guid = {0x69ECC1BE, 0xA981, 0x446D, 0x8E, 0xB6, 0xAF, 0x0E, 0x53, 0xD0, 0x6C, 0xE8}; //EFI_OS_BOOT_OPTION_NAMES_GUID
+ #endif
+
+ #ifdef FORM_SET_ITEM
+
+ EOBON_ONEOF_NEW_OPTION_POLICY
+
+ #endif //#ifdef FORM_SET_FORM
+
+#endif //#ifdef BOOT_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl
new file mode 100644
index 0000000..a4c1635
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.sdl
@@ -0,0 +1,286 @@
+TOKEN
+ Name = "EfiOsBootOptionNames_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable EfiOsBootOptionNames support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "RemoveLegacyGptHddDevice"
+ Value = "0"
+ Help = "On. Filter GPT Format Hard disk of Legacy device."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RemoveBootOptionWithoutFile"
+ Value = "0"
+ Help = "On. Delete Boot Option when the file path in EfiOsBootOptionNamesFilePathItem doesn't exist."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BootOption_x64"
+ Value = "1"
+ Help = "Enable build support for 64 bit(x64/IA64)"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+#TOKEN
+# Name = "NORMALIZE_BOOT_OPTION_NAME"
+# Value = "0"
+# Help = "When the token is on, the Description of the existing boot options is regenerated during the boot option processing.\It is possible to override built time Description normalization policy using NormalizeBootOptionName variable."
+# TokenType = Boolean
+# TargetH = Yes
+#End
+
+#TOKEN
+# Name = "NORMALIZE_BOOT_OPTION_DEVICE_PATH"
+# Value = "0"
+# Help = "When the token is on, the FilePathList of the existing boot options is regenerated during the boot option processing.\It is possible to override built time FilePathList normalization policy using NormalizeBootOptionDevicePath variable."
+# TokenType = Boolean
+# TargetH = Yes
+#End
+
+TOKEN
+ Name = "DefaultFwBootOption"
+ Value = "1"
+ Help = "Boot Option Created by this module, 1 - FW Boot Option , 0 - Non FW Boot Option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "KeepDuplicateNonFWBootOption"
+ Value = "0"
+ Help = "0 - Delete Duplicate Non FW BootOption, 1 - Leave Non FW BootOption."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "DISPLAY_FULL_OPTION_NAME_WITH_FBO"
+ Value = "1"
+ Help = "Display full boot option name with Fixed Boot Order, such as: Windows Boot Manager(P0 DeviceName)."
+ TokenType = Boolean
+ Token = "FIXED_BOOT_ORDER_SUPPORT" "=" "1"
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_UEFI_OS_OPTION_ORDER_POLICY"
+ Value = "0"
+ Help = "The order of new UEFI OS boot option. \0:BoTagUefi order.\1:The Highest order.\2:The Lowest order."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY"
+ Value = "1"
+ Help = "0: Create boot option by EfiOsBootOptionNamesFilePathItem, 1: Create boot option (UEFI OS) if can't find any other"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NAME_OF_UEFI_OS"
+ Value = 'L"UEFI OS"'
+ Help = "Name of UEFI OS, BootX64.efi or BootIa32.efi"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEAL_WITH_EFI_OS_BOOT_OPTION_FUNC_PTR"
+ Value = "SearchBootablePathAndCreateBootOption"
+ Help = "Name of the function pointer of type DEAL_WITH_EFI_OS_BOOT_OPTION."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CREATE_TARGET_EFI_OS_BOOT_OPTION_FUNC_PTR"
+ Value = "CreateTargetEfiOsBootOption"
+ Help = "Name of the function pointer of type CREATE_TARGET_EFI_OS_BOOT_OPTION."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY"
+ Value = "0"
+ Help = "To replace the Elink dependency on BcpBootOrder_SUPPORT token."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY"
+ Value = "1"
+ Help = "To replace the Elink dependency on BcpBootOrder_SUPPORT token."
+ TokenType = Integer
+ TargetH = Yes
+ Token = "BcpBootOrder_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "EfiOsBootOptionNames_DIR"
+ Help = "EfiOsBootOptionNames files source directory"
+End
+
+MODULE
+ Help = "Includes EfiOsBootOptionNames.mak to Project"
+ File = "EfiOsBootOptionNames.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\EfiOsBootOptionNames.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(EfiOsBootOptionNames_DIR)\EfiOsBootOptionNames.sd"
+ Parent = "SETUP_DEFINITIONS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ChangeUefiBootNames,"
+ Parent = "ProcessEnterSetupHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustEfiOsBootOrder,"
+ Parent = "ReadBootOptions,"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "CreateEfiOsBootOption,"
+ Parent = "FilterBootDeviceList,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "EfiOsName_NormalizeBootOptions,"
+ Parent = "NormalizeBootOptions,"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "RemoveLegacyGptHdd,"
+ Parent = "BootOptionBootDeviceFilteringFunctions"
+ Token = "RemoveLegacyGptHddDevice" "=" "1"
+ Token = "CSM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustNewUefiOsOptionPriority,"
+ Parent = "SetBootOptionPriorities,"
+ Token = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "AdjustNewUefiOsOptionPriority,"
+ Parent = "SetDefaultBcpBootOptionPriorities,"
+ Token = "NEW_UEFI_OS_OPTION_ORDER_POLICY_ELINK_DEPENDENCY" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SaveEfiOsBootOrder,"
+ Parent = "SaveBootOptions,"
+ InvokeOrder = AfterParent
+ Token = "DefaultFwBootOption" "=" "0"
+End
+
+ELINK
+ Name = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Microsoft\\Boot\\bootmgfw.efi), TstrW(Windows Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Suse\\elilo.efi), TstrW(Suse Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Ubuntu\\grubx64.efi), TstrW(ubuntu)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Redhat\\elilo.efi), TstrW(RedHat Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Redhat\\grub.efi), TstrW(RedHat Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Redhat\\shim.efi), TstrW(RedHat Boot Manager)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\Centos\\shim.efi), TstrW(CentOS)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\opensuse\\grubx64.efi), TstrW(opensuse)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\BOOT\\BOOTX64.EFI), TstrW(UEFI OS)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ Token = "x64_BUILD" "=" "1"
+ Token = "CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\BOOT\\BOOTIA32.EFI), TstrW(UEFI OS)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ Token = "x64_BUILD" "=" "0"
+ Token = "CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{TstrW(\\EFI\\debian\\grubx64.efi), TstrW(debian)},"
+ Parent = "EfiOsBootOptionNamesFilePathItem"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.uni b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.uni
new file mode 100644
index 0000000..28afbd9
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOptionNames.uni
Binary files differ
diff --git a/Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c b/Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c
new file mode 100644
index 0000000..32087f9
--- /dev/null
+++ b/Core/EM/EfiOsBootOptionNames/EfiOsBootOrder.c
@@ -0,0 +1,1682 @@
+//***********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
+//***********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOrder.c 24 6/11/15 2:42a Dukeyeh $
+//
+// $Revision: 24 $
+//
+// $Date: 6/11/15 2:42a $
+//***********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/EfiOsBootOptionNames/EfiOsBootOrder.c $
+//
+// 24 6/11/15 2:42a Dukeyeh
+// Change IsSpecifiedUefiOsBootOptions function's comment header style
+// from AptioV to 4
+//
+// 23 4/28/15 4:55a Dukeyeh
+// [TAG] EIP213903
+// [Category] Bug Fix
+// [Severity] Normal
+// [RootCause] "UEFI OS" boot option's name/device path being
+// renormalized.
+// [Solution] "UEFI OS" boot option needs to escape name/device path
+// normalization when token CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY
+// is enabled (create "UEFI OS" boot option if can't find any other boot
+// file paths in table).
+// [Files] EfiOsBootOrder.c
+//
+// 22 3/11/15 6:48a Dukeyeh
+// [TAG] EIP178808
+// [Category] New Feature
+// [Description] Implement the selection of
+// NEW_UEFI_OS_OPTION_ORDER_POLICY item in Setup.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 21 3/11/15 3:47a Dukeyeh
+// [TAG] EIP204138
+// [Category] Improvement
+// [Description] Add a CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY
+// token to control whether create
+// "UEFI OS" boot option if can't find any other in specified file paths
+// (default) or just create it.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOrder.c
+//
+// 20 12/24/14 1:11a Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] When deleting the duplicate boot options, synchronized
+// with FIXED_BOOT_ORDER module.
+// [Files] EfiOsBootOrder.c
+//
+// 19 12/23/14 5:45a Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] Add KeepDuplicateNonFWBootOption token to determine
+// whether deletes the duplicated NON-FW boot options or not.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOrder.c
+//
+// 18 12/04/14 4:51a Dukeyeh
+// [TAG] EIP194753
+// [Category] Bug Fix
+// [RootCause] Compiler makes CHAR8 into signed value of 4 bytes in
+// comparison statement, so it fails to comparison with immediate value.
+// [Solution] Change the variable declarations of CHAR8 into UINT8.
+// [Files] EfiOsBootOrder.c
+//
+// 17 12/03/14 10:59p Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] For CppCheck error in AdjustNewUefiOsOptionPriority
+// function that Priority variable didn't have default/initialized value.
+// [Files] EfiOsBootOrder.c
+//
+// 16 11/19/14 2:22a Klzhan
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Add a token to set boot option created by this module
+// is Fw Boot Option or not.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOptionNames.chm
+// EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 15 9/03/14 10:41p Dukeyeh
+// [TAG] EIP_NO
+// [Category] Improvement
+// [Description] 1. Add new token for eLink dependency of
+// BcpBootOrder_SUPPORT.
+// 2. CHM file for version 10.
+// 3. Change NewEfiOsOptionDpListCount variable to zero when return.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.chm
+// EfiOsBootOrder.c
+//
+// 14 9/03/14 1:59a Dukeyeh
+// [TAG] EIP180447
+// [Category] Improvement
+// [Description] Create a token to set the priority of the boot option
+// created by Efi Os Boot Option Name.
+// [Files] EfiOsBootOptionNames.sdl
+// EfiBootOrder.c
+//
+// 13 9/02/14 10:27p Dukeyeh
+// [TAG] EIP178318
+// [Category] Improvement
+// [Description] Sync Boot priority after remove FW Boot Option.
+// [Files] EfiOsBootOrder.c
+//
+// 12 8/13/14 11:14p Walonli
+// [TAG] EIP180632
+// [Category] New Feature
+// [Description] Support FixedBootOrder to display Uefi OS full name
+// "Windows Boot Manager(Px: DeviceName)".
+// [Files] EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+// 11 7/07/14 4:40a Klzhan
+// [TAG] EIPNone
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Duplicated boot option created by module
+// [RootCause] FwBootOption check is incorrect.
+//
+// 10 5/23/14 5:08a Dukeyeh
+// [TAG] EIP167957
+// [Category] Bug Fix
+// [RootCause] EIP147262 - The "EFI OS BootOptionNames" module can't
+// support the "FixedBootOrder" module Boot option strings.
+// EIP159984 - Linux UEFI OS boot issue.
+// EIP168792 - Possible heap corruption - EFI OS BootOptionNames
+// [Solution] EIP147262 =>A new token
+// "DISPLAY_FULL_OPTION_NAME_WITH_FBO" is added to control this.
+// EIP159984 =>Should NOT kill the UEFI OS boot option that created by OS.
+// EIP168792 =>NEW_STRING_BUFFER_LENGTH is replaced with the actual size
+// of the allocated memory, NewStringLength.
+//
+// [Files] EfiOsBootOptionNames.sdl
+// EfiOsBootOptionNames.mak
+// EfiOsBootOptionNames.chm
+// EfiOsBootOptionNames.c
+// EfiOsBootOrder.c
+// EfiOsBootOptionNames.cif
+//
+//***********************************************************************
+//***********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiOsBootOrder.c
+//
+// Description: Deal with UEFI Boot Devices that contain UEFI OS.
+// Create boot option if device is existed, delete
+// boot option if there is a duplicated one and then
+// adjust the BootOrder.
+//
+//<AMI_FHDR_END>
+//***********************************************************************
+
+#include <BootOptions.h>
+#include "EfiOsNamesFilePathMaps.h"
+#include <Protocol\PDiskinfo.h>
+#include <Token.h>
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+#include "Board\em\FixedBootOrder\FixedBootOrder.h"
+#endif
+
+#ifdef BootOption_x64
+#define EFI_BOOT_FILE_NAME L"\\EFI\\BOOT\\BOOTX64.EFI"
+#else
+#define EFI_BOOT_FILE_NAME L"\\EFI\\BOOT\\BOOTIA32.EFI"
+#endif
+
+#define EFI_OS_BOOT_OPTION_NAMES_GUID \
+ {0x69ECC1BE, 0xA981, 0x446D, 0x8E, 0xB6, 0xAF, 0x0E, 0x53, 0xD0, 0x6C, 0xE8}
+
+#define TstrW(s) L#s //(EIP103672+)
+
+#pragma pack(1)
+typedef struct _PARTITION_ENTRY {
+ UINT8 ActiveFlag; // Bootable or not
+ UINT8 StartingTrack; // Not used
+ UINT8 StartingCylinderLsb; // Not used
+ UINT8 StartingCylinderMsb; // Not used
+ UINT8 PartitionType; // 12 bit FAT, 16 bit FAT etc.
+ UINT8 EndingTrack; // Not used
+ UINT8 EndingCylinderLsb; // Not used
+ UINT8 EndingCylinderMsb; // Not used
+ UINT32 StartSector; // Relative sectors
+ UINT32 PartitionLength; // Sectors in this partition
+} PARTITION_ENTRY;
+
+typedef struct
+{
+ CHAR16 *FilePath;
+ CHAR16 *BootOptionName;
+}NAME_MAP;
+#pragma pack()
+
+typedef EFI_STATUS (DEAL_WITH_EFI_OS_BOOT_OPTION) (EFI_HANDLE Handle);
+extern DEAL_WITH_EFI_OS_BOOT_OPTION DEAL_WITH_EFI_OS_BOOT_OPTION_FUNC_PTR;
+DEAL_WITH_EFI_OS_BOOT_OPTION *DealWithEfiOsBootOptionFuncPtr = DEAL_WITH_EFI_OS_BOOT_OPTION_FUNC_PTR;
+
+typedef BOOLEAN (CREATE_TARGET_EFI_OS_BOOT_OPTION) (EFI_HANDLE Handle, NAME_MAP* NameMap);
+extern CREATE_TARGET_EFI_OS_BOOT_OPTION CREATE_TARGET_EFI_OS_BOOT_OPTION_FUNC_PTR;
+CREATE_TARGET_EFI_OS_BOOT_OPTION *CreateTargetEfiOsBootOptionFuncPtr = CREATE_TARGET_EFI_OS_BOOT_OPTION_FUNC_PTR;
+
+/**
+ Arrary of eLinks that contain many OS image paths and their corresponding OS names.
+*/
+NAME_MAP FILE_NAME_MAPS[] = { EfiOsFilePathMaps {NULL,NULL} }; //(EIP103672+)
+
+extern BOOLEAN NormalizeBootOptionName ;
+extern BOOLEAN NormalizeBootOptionDevicePath ;
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+extern EFI_HANDLE GetPhysicalBlockIoHandle (IN EFI_HANDLE BlockIoHandle) ;
+extern UINTN RemoveTrailingSpaces(CHAR16 *Name, UINTN NumberOfCharacters);
+extern UINT16 gSATA[3][2] ;
+#endif
+
+EFI_DEVICE_PATH_PROTOCOL **NewEfiOsOptionDpList = NULL ;
+UINTN NewEfiOsOptionDpListCount = 0 ;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetHdNode
+//
+// Description:
+// Locates HD node in DevicePath associated with Handle.
+//
+// Input:
+// IN EFI_HANDLE Handle - Handle with DevicePath protocol for which HD
+// node should be located.
+//
+// Output:
+// OUT EFI_DEVICE_PATH_PROTOCOL** DevPath - Pointer to HD node, if found.
+//
+// Returns:
+// EFI_SUCCESS - HD node was found and returned.
+// EFI_NOT_FOUND - No HD node was found.
+// Other errors possible if Handle does not have DevicePath protocol.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// HandleProtocol()
+// isEndNode()
+// NEXT_NODE()
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetHdNode (
+ IN EFI_HANDLE Handle,
+ OUT EFI_DEVICE_PATH_PROTOCOL** DevPath
+)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL* DevicePath;
+
+ *DevPath = NULL;
+
+ // Get DevicePath attached to handle.
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "HandleProtocol: %r\n", Status));
+ return Status;
+ }
+
+ // Find hard drive node.
+ while (!isEndNode(DevicePath)) {
+
+ if ((DevicePath->Type == MEDIA_DEVICE_PATH) &&
+ (DevicePath->SubType == MEDIA_HARDDRIVE_DP)) {
+
+ *DevPath = DevicePath;
+ return EFI_SUCCESS;
+ }
+
+ DevicePath = NEXT_NODE(DevicePath);
+ }
+
+ // HD node was not found. Return error.
+ return EFI_NOT_FOUND;
+}
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetHDDPort
+//
+// Description:
+// Use handle and EFI_DISK_INFO_PROTOCOL to get sata hard disk port.
+//
+// Input:
+// IN EFI_HANDLE - Use in locating EFI_DISK_INFO_PROTOCOL.
+//
+// Output:
+// None.
+//
+// Returns:
+// UINT16 - Sata port number.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// HandleProtocol().
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetHDDPort( IN EFI_HANDLE Handle )
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *MessagingDevicePath;
+ PCI_DEVICE_PATH *PciDevicePath;
+
+ DevicePathNode = DevicePath;
+ while (!isEndNode (DevicePathNode))
+ {
+ if ((DevicePathNode->Type == HARDWARE_DEVICE_PATH)
+ && (DevicePathNode->SubType == HW_PCI_DP))
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+ else if (DevicePathNode->Type == MESSAGING_DEVICE_PATH)
+ MessagingDevicePath = DevicePathNode;
+
+ DevicePathNode = NEXT_NODE (DevicePathNode);
+ }
+
+ Status = pBS->HandleProtocol ( Handle, &gEfiDiskInfoProtocolGuid, &DiskInfo );
+ if ( !EFI_ERROR(Status) )
+ {
+ Status = DiskInfo->WhichIde ( DiskInfo, &IdeChannel, &IdeDevice );
+ if ( !EFI_ERROR(Status) )
+ {
+ if ( MessagingDevicePath->SubType == MSG_ATAPI_DP ) //IDE mode?
+ {
+ if (PciDevicePath->Function == 5)
+ return gSATA[IdeDevice+2][IdeChannel];
+ else
+ return gSATA[IdeDevice][IdeChannel];
+ }
+ else
+ return IdeChannel; //AHCI Port Number
+ }
+ }
+ }
+ return 0xff;
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetGptPartitionHandle
+//
+// Description: Search GPT HDD and return Hard disk handle.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath - Search GPT HDD and return Hard disk handle.
+//
+// Output:
+// None.
+//
+// Returns:
+// EFI_HANDLE - Hard Disk handle or NULL.
+//
+// Modified:
+// None.
+//
+// Referrals:
+// LocateHandleBuffer(),
+// HandleProtocol().
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_HANDLE GetGptPartitionHandle(EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle, TempHandle = NULL;
+ UINTN Count, i;
+
+ HARDDRIVE_DEVICE_PATH* BootParitionDevicePath = (HARDDRIVE_DEVICE_PATH*)DevicePath;
+
+ //get list of available Block I/O devices
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiBlockIoProtocolGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return NULL;
+
+ for( i=0; i<Count; i++ )
+ {
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDevicePath, *TmpDevicePath;
+ HARDDRIVE_DEVICE_PATH* PartitionNode;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiBlockIoProtocolGuid,&BlockIo);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // if this is not partition, continue
+ if (!BlockIo->Media->LogicalPartition)
+ continue;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&PartitionDevicePath);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // Get last node of the device path. It should be partition node
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)PartitionDevicePath;
+
+ for( TmpDevicePath = PartitionDevicePath;
+ !isEndNode(TmpDevicePath);
+ TmpDevicePath=NEXT_NODE(TmpDevicePath) )
+ {
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
+ }
+
+ //Check if our partition matches Boot partition
+ if (PartitionNode->Header.Type!=MEDIA_DEVICE_PATH || PartitionNode->Header.SubType!=MEDIA_HARDDRIVE_DP)
+ continue;
+
+ if ( PartitionNode->PartitionNumber==BootParitionDevicePath->PartitionNumber &&
+ PartitionNode->SignatureType==BootParitionDevicePath->SignatureType &&
+ !MemCmp(PartitionNode->Signature,BootParitionDevicePath->Signature,16) )
+ {
+ //Match found
+ TempHandle = Handle[i];
+ break;
+ }
+ }
+
+ pBS->FreePool(Handle);
+ return TempHandle;
+}
+ //(EIP126686+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CompareHddDevicePath
+//
+// Description: Compare whether two HDD device paths are the same.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevDp1 - Device path in comparison.
+// IN EFI_DEVICE_PATH_PROTOCOL *DevDp2 - Device path in comparison.
+//
+// Output:
+// None.
+//
+// Returns:
+// EFI_STATUS
+//
+// Modified:
+// None.
+//
+// Referrals:
+// MemCmp(),
+// NEXT_NODE().
+//
+// Notes:
+// None.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CompareHddDevicePath( EFI_DEVICE_PATH_PROTOCOL *DevDp1, EFI_DEVICE_PATH_PROTOCOL *DevDp2 )
+{
+
+ if ( DevDp1->Type == MEDIA_DEVICE_PATH &&
+ DevDp1->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ if (MemCmp(DevDp1+1, DevDp2+1, sizeof(HARDDRIVE_DEVICE_PATH)-sizeof(EFI_DEVICE_PATH_PROTOCOL)) == 0) //Skip Header EFI_DEVICE_PATH_PROTOCOL.
+ {
+ DevDp1 = NEXT_NODE(DevDp1);
+ if( DevDp1->Type == MEDIA_DEVICE_PATH &&
+ DevDp1->SubType == MEDIA_FILEPATH_DP ) Wcsupr( (CHAR16*)DevDp1+1 );
+
+ DevDp2 = NEXT_NODE(DevDp2);
+ if( DevDp2->Type == MEDIA_DEVICE_PATH &&
+ DevDp2->SubType == MEDIA_FILEPATH_DP ) Wcsupr( (CHAR16*)DevDp2+1 );
+
+ if (MemCmp(DevDp1, DevDp2, DPLength(DevDp2)) == 0)
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+ //<(EIP126686+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckBootOptionMatch
+//
+// Description: Search all BootOptionList and found out the matched HDD device path.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *HdDevPath
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckBootOptionMatch (
+ IN EFI_DEVICE_PATH_PROTOCOL* HdDevPath
+)
+{
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+
+ //(EIP126686+)>
+ if( CompareHddDevicePath(Option->FilePathList, HdDevPath) == EFI_SUCCESS )
+ return EFI_SUCCESS;
+ //<(EIP126686+)
+ }
+ return EFI_NOT_FOUND;
+}
+
+ //(EIP103672+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetEfiOsBootNameItemCount
+//
+// Description: Count the elements in eLink FILE_NAME_MAPS.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *DevicePath
+//
+// Output: EFI_HANDLE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetEfiOsBootNameItemCount(void)
+{
+ UINT16 ItemCount=0;
+
+ do{
+
+ if( FILE_NAME_MAPS[ItemCount].FilePath == NULL )
+ break;
+
+ ItemCount++;
+
+ }while(1);
+
+ return ItemCount;
+}
+ //<(EIP103672+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateTargetEfiOsBootOption
+//
+// Description: Create target efi os boot option
+//
+// Input: EFI_HANDLE FileSystemHandle - Handle to get file system
+// NAME_MAP* DevicePath - Contain boot file name and boot option name
+//
+// Output: TRUE - if find any matched boot option / create boot option successfully
+// FALSE - if one of inputs is invalid / fail to allocate pool / fail to get hdd node
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CreateTargetEfiOsBootOption(EFI_HANDLE FileSystemHandle, NAME_MAP* NameMap)
+{
+ EFI_STATUS Status;
+ UINTN OptionSize;
+ UINT8* BytePtr;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *HdDevPath = NULL;
+ FILEPATH_DEVICE_PATH *FpDevPath = NULL;
+ BOOT_OPTION *Option;
+
+ if(!FileSystemHandle || !NameMap)
+ return FALSE;
+
+ // Find total size of new boot option.
+ OptionSize = sizeof(HARDDRIVE_DEVICE_PATH) + // Partition node
+ sizeof(FILEPATH_DEVICE_PATH) + // FilePath node
+ ((Wcslen(NameMap->FilePath) ) * sizeof(CHAR16)) + //(EIP120976)
+ sizeof(EFI_DEVICE_PATH_PROTOCOL); //+ // End node //(EIP103870)
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ OptionSize,
+ &DevicePath);
+
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "AllocatePool %r\n", Status));
+ return FALSE;
+ }
+
+ // Get HD node of device path associated with handle.
+ Status = GetHdNode (
+ FileSystemHandle,
+ &HdDevPath );
+
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "GetHdNode: %r\n", Status));
+ pBS->FreePool(DevicePath);
+ return FALSE;
+ }
+
+ BytePtr = (UINT8*)DevicePath;
+ // Copy to FilePath.
+ MemCpy(BytePtr, HdDevPath, NODE_LENGTH(HdDevPath));
+
+ // Point to next node.
+ BytePtr += NODE_LENGTH(HdDevPath);
+ FpDevPath = (FILEPATH_DEVICE_PATH*)BytePtr;
+
+ // Set Filepath node.
+ FpDevPath->Header.Type = MEDIA_DEVICE_PATH;
+ FpDevPath->Header.SubType = MEDIA_FILEPATH_DP;
+ SET_NODE_LENGTH(&(FpDevPath->Header), 4 + (UINT16)((Wcslen(NameMap->FilePath) + 1) * sizeof(CHAR16)));
+
+ // Set Filepath PathName.
+ MemCpy(FpDevPath->PathName, NameMap->FilePath, (Wcslen(NameMap->FilePath) + 1) * sizeof(CHAR16));
+
+ // Point to next node.
+ BytePtr += NODE_LENGTH(&(FpDevPath->Header));
+ ((EFI_DEVICE_PATH_PROTOCOL*)BytePtr)->Type = END_DEVICE_PATH;
+ ((EFI_DEVICE_PATH_PROTOCOL*)BytePtr)->SubType = END_ENTIRE_SUBTYPE;
+ SET_NODE_LENGTH((EFI_DEVICE_PATH_PROTOCOL*)BytePtr, END_DEVICE_PATH_LENGTH);
+
+ // Point to signature.
+ BytePtr += END_DEVICE_PATH_LENGTH;
+
+#if DISPLAY_FULL_OPTION_NAME_WITH_FBO
+ //
+ // Uefi OS in Setup as style "OS Name(PX: DeviceName)" because of
+ // EfiOsBootOptionNames module creates it by ChangeUefiBootNames
+ // eLink to change bootData->Name, however, FixedBootOrder module
+ // creates its oneof items with BootXXXX variable's description
+ // which saved according to Option->Description, that makes only
+ // "OS Name" appear in setup, hence we need to use FixedBootOrder
+ // protocol to set new description.
+ //
+ {
+ CHAR16 *ControllerName ;
+ CHAR16 *DeviceName ;
+ UINT16 PortNumber = 0xff ;
+ UINTN NumberOfCharacters = 0, DeviceNameLength = 0;
+ EFI_HANDLE Handle ;
+ EFI_FIXED_BOOT_ORDER_PROTOCOL *Fbo = NULL ;
+ EFI_GUID FixedBootOrderGuid = FIXED_BOOT_ORDER_GUID ;
+
+ Status = pBS->LocateProtocol(&FixedBootOrderGuid, NULL, &Fbo);
+ Handle = GetPhysicalBlockIoHandle(FileSystemHandle);
+ if (GetControllerName(Handle, &ControllerName) && !EFI_ERROR(Status))
+ {
+ DeviceNameLength = (Wcslen(ControllerName)+1)*sizeof(CHAR16) ;
+ DeviceName = MallocZ(DeviceNameLength) ;
+ PortNumber = GetHDDPort( Handle );
+ NumberOfCharacters = Swprintf_s(DeviceName, DeviceNameLength, L"%s", ControllerName);
+ DeviceNameLength = RemoveTrailingSpaces(DeviceName, NumberOfCharacters);
+ if ( DeviceNameLength )
+ {
+ FBO_DEVICE_INFORM *inform ;
+ CHAR16 *String ;
+ UINTN StringLength = DeviceNameLength*sizeof(CHAR16)
+ + Wcslen(NameMap->BootOptionName)*sizeof(CHAR16)
+ + 0xf ;
+ String = MallocZ(StringLength) ;
+ if ( PortNumber != 0xff )
+ {
+ Swprintf_s ( String,
+ StringLength,
+ L"%s (P%d: %s)",
+ NameMap->BootOptionName,
+ PortNumber,
+ DeviceName );
+ TRACE((-1, "EfiOsBootOrder.c Reset the Boot Option Name:%S \n", String)) ;
+ }
+ else // It don't have port number
+ {
+ Swprintf_s ( String,
+ StringLength,
+ L"%s (%s)",
+ NameMap->BootOptionName,
+ DeviceName );
+ TRACE((-1, "EfiOsBootOrder.c Reset the Boot Option Name:%S \n", String)) ;
+ }
+
+ inform = MallocZ(sizeof(FBO_DEVICE_INFORM)) ;
+ inform->DevName = String ;
+ inform->DevPath = MallocZ(DPLength(DevicePath)) ;
+ MemCpy(inform->DevPath, DevicePath, DPLength(DevicePath)) ;
+ Status = Fbo->SetNewDescription(inform) ;
+ if (EFI_ERROR(Status))
+ TRACE((-1, "Can't set new description with fbo protocol")) ;
+ }
+ pBS->FreePool(DeviceName) ;
+ }
+ }
+#endif
+
+ if ( CheckBootOptionMatch( DevicePath ) == EFI_SUCCESS )
+ {
+ TRACE((-1,"CheckBootOptionMatch Matched.....\n" ));
+ pBS->FreePool(DevicePath);
+ return TRUE;
+ }
+
+ Option = CreateBootOption(BootOptionList);
+ Option->Attributes = LOAD_OPTION_ACTIVE; //(EIP138397)
+ Option->FwBootOption = DefaultFwBootOption;
+
+ pBS->AllocatePool (
+ EfiBootServicesData,
+ ((Wcslen(NameMap->BootOptionName) + 1) * sizeof(CHAR16)),
+ &Option->Description);
+
+ MemCpy(Option->Description,
+ NameMap->BootOptionName,
+ ((Wcslen(NameMap->BootOptionName) + 1) * sizeof(CHAR16)) );
+
+
+ Option->FilePathList = DevicePath;
+ Option->FilePathListLength = OptionSize;
+
+ {
+ VOID **ptr = NULL ;
+ ptr = MallocZ(sizeof(VOID**)
+ * (NewEfiOsOptionDpListCount+1)) ;
+ if (ptr)
+ {
+ MemCpy(ptr, NewEfiOsOptionDpList, sizeof(VOID**)
+ * NewEfiOsOptionDpListCount) ;
+ *(ptr+NewEfiOsOptionDpListCount) = Option->FilePathList ;
+
+ NewEfiOsOptionDpListCount++ ;
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+ NewEfiOsOptionDpList = (EFI_DEVICE_PATH_PROTOCOL**)ptr ;
+ }
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateBootOptionWithUefiFileName
+//
+// Description: Create boot option with uefi file name if there is no other matched path.
+//
+// Input: EFI_HANDLE Handle - Handle to locate file system
+// UINT16 MatchedBootablePathCount - Count of matched bootable files
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CreateBootOptionWithUefiFileName(EFI_HANDLE Handle)
+{
+ EFI_STATUS Status;
+ EFI_FILE_PROTOCOL *FileProtocol;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem;
+
+ if(!Handle)
+ return;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem
+ );
+
+ if(!EFI_ERROR(Status))
+ {
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol
+ );
+ if(!EFI_ERROR(Status))
+ {
+ EFI_FILE_PROTOCOL* NewFileProtocol;
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ EFI_BOOT_FILE_NAME,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+ if(!EFI_ERROR(Status))
+ {
+ static NAME_MAP NameMap = {EFI_BOOT_FILE_NAME, NAME_OF_UEFI_OS};
+ CreateTargetEfiOsBootOptionFuncPtr(Handle, &NameMap);
+
+ NewFileProtocol->Close(NewFileProtocol);
+ }
+ }
+ }
+}
+
+/**
+ Search bootable path then create boot option.
+
+ @param Handle Handle to locate file system.
+
+ @retval EFI_SUCCESS Do not encounter any errors.
+ @retval !=EFI_SUCESS Any errors.
+**/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SearchBootablePathAndCreateBootOption
+//
+// Description: Search bootable path then create boot option.
+//
+// Input: EFI_HANDLE Handle - Handle to locate file system
+//
+// Output: EFI_SUCCESS - Do not encounter any errors
+// !=EFI_SUCCESS - Any errors
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SearchBootablePathAndCreateBootOption(EFI_HANDLE Handle)
+{
+ EFI_STATUS Status;
+ UINT16 MatchedBootablePathCount = 0;
+ UINT16 AUTO_BOOT_ENTRY_COUNT = GetEfiOsBootNameItemCount();
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem;
+ EFI_FILE_PROTOCOL *FileProtocol;
+
+ UINTN j;
+
+ if(!Handle) return EFI_INVALID_PARAMETER;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "HandleProtocol(SimpleFileSystem): %r\n", Status));
+ return Status;
+ }
+
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "OpenVolume: %r\n", Status));
+ return Status;
+ }
+
+ for (j = 0; j < AUTO_BOOT_ENTRY_COUNT; j++) {
+
+ EFI_FILE_PROTOCOL* NewFileProtocol;
+
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ FILE_NAME_MAPS[j].FilePath,
+ EFI_FILE_MODE_READ,
+ 0
+ );
+
+ TRACE((-1, "Open(%S): %r\n", FILE_NAME_MAPS[j].FilePath, Status));
+ if (EFI_ERROR(Status)) continue;
+
+ if(CreateTargetEfiOsBootOptionFuncPtr(Handle, &FILE_NAME_MAPS[j]))
+ MatchedBootablePathCount++;
+
+ NewFileProtocol->Close(NewFileProtocol);
+ }
+
+#if CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY == 1
+ if(!MatchedBootablePathCount)
+ CreateBootOptionWithUefiFileName(Handle);
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateEfiOsBootOption
+//
+// Description: Try to find UEFI OSs and create the boot options for them if
+// they haven't been listed in BootOptionList.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS - Do not encounter any errors
+// !=EFI_SUCCESS - Any errors
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateEfiOsBootOption(VOID)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE* HandleBuffer = NULL;
+ UINTN HandleCount;
+ UINTN i;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiSimpleFileSystemProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "LocateHandleBuffer: %r\n", Status));
+ return Status;
+ }
+ // For each handle found, check if eLink files exist.
+ for (i = 0; i < HandleCount; i++) {
+
+ Status=pBS->HandleProtocol( HandleBuffer[i], &gEfiBlockIoProtocolGuid, &BlkIo );
+ if ( EFI_ERROR(Status) || BlkIo->Media->RemovableMedia ) continue; //skip removable device
+
+ DealWithEfiOsBootOptionFuncPtr(HandleBuffer[i]);
+ }
+
+ if ( HandleBuffer )
+ pBS->FreePool(HandleBuffer);
+
+ return EFI_SUCCESS;
+}
+
+ //(EIP138397+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveAmiMaskDevicePath
+//
+// Description: Remove the AMI specific device path from SrcDevicePath.
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *SrcDevicePath - Device Path that has AMI
+// mask device path.
+// UINT16 DevicePathSize - Size of SrcDevicePath.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+RemoveAmiMaskDevicePath( EFI_DEVICE_PATH_PROTOCOL **SrcDevicePath, UINT16 DevicePathSize)
+{
+ EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath = *SrcDevicePath;
+ EFI_GUID AmiMaskedDevicePathGuid = AMI_MASKED_DEVICE_PATH_GUID;
+
+ if( TmpDevicePath->Type == HARDWARE_DEVICE_PATH
+ && TmpDevicePath->SubType == HW_VENDOR_DP
+ && guidcmp(&AmiMaskedDevicePathGuid, &((VENDOR_DEVICE_PATH*)TmpDevicePath)->Guid) == 0 )
+ {
+
+ do{
+
+ if( TmpDevicePath->Type == MEDIA_DEVICE_PATH
+ && TmpDevicePath->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ *(SrcDevicePath) = TmpDevicePath;
+ break;
+ }
+ else
+ {
+ DevicePathSize -= (*(UINT16*)&(TmpDevicePath)->Length[0]);
+ TmpDevicePath = NEXT_NODE( TmpDevicePath );
+ }
+
+ }while( DevicePathSize > 0 );
+ }
+}
+ //<(EIP138397+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsOsCreatedBootOption
+//
+// Description: Check whether input boot option number is created by OS.
+//
+// Input: UINT16 BootOptionNumber - Number to check.
+//
+// Output: BOOLEAN
+// TRUE Created by OS.
+// FALSE Isn't created by OS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsOsCreatedBootOption(UINT16 BootOptionNumber)
+{
+ EFI_STATUS Status;
+ EFI_GUID EfiOsBootOptionNamesGuid = EFI_OS_BOOT_OPTION_NAMES_GUID;
+ UINT16* EfiOsBootOrder = NULL;
+ UINTN Size = 0;
+ BOOLEAN Ret = TRUE;
+
+ Status = GetEfiVariable(
+ L"EfiOsBootOrder",
+ &EfiOsBootOptionNamesGuid,
+ NULL,
+ &Size,
+ &EfiOsBootOrder);
+
+ if(!EFI_ERROR(Status))
+ {
+ UINTN i;
+
+ Size = Size/sizeof(UINT16);
+ for(i = 0; i < Size; i++)
+ {
+ if(EfiOsBootOrder[i] == BootOptionNumber)
+ {
+ Ret = FALSE;
+ break;
+ }
+ }
+
+ pBS->FreePool(EfiOsBootOrder);
+ }
+
+ return Ret;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustEfiOsBootOrder
+//
+// Description: Remove the AMI specific device path from SrcDevicePath.
+//
+// Description: if UEFI OS is existed, kill the duplicated UEFI OS boot options
+// into one and move it to one of their boot order position, and kill
+// all UEFI OS boot options if deivces are disappeared in system.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AdjustEfiOsBootOrder(VOID)
+{
+ UINT16 *NewBootOrder = NULL; //(EIP138397)
+ UINT16 BootIndex=0;
+ UINT16 *BootOrder_Flag = NULL; //(EIP138397)
+ UINT16 *BootOrder = NULL;
+ UINTN BootOrderSize = 0;
+ EFI_STATUS Status;
+ BOOLEAN UpdateBootOrder=FALSE, FwBootOption = FALSE;
+ UINTN i, j;
+ EFI_LOAD_OPTION *NvramOption = NULL;
+ UINTN NvramOptionSize;
+
+ TRACE((-1,"EfiOsBootOrder.....\n"));
+
+ Status=GetEfiVariable(
+ L"BootOrder", &EfiVariableGuid, NULL, &BootOrderSize, &BootOrder);
+
+ if (EFI_ERROR(Status)) return;
+ //(EIP138397)>
+ NewBootOrder = MallocZ( BootOrderSize );
+ if( NewBootOrder == NULL ) return;
+ BootOrder_Flag = MallocZ( BootOrderSize );
+ if( BootOrder_Flag == NULL ) return;
+ //<(EIP138397)
+ for(i=0; i<BootOrderSize/sizeof(UINT16); i++)
+ {
+ UINTN DescriptionSize;
+ EFI_DEVICE_PATH_PROTOCOL *ScrDevicePath;
+ CHAR16 BootStr[9];
+ UINT32 *OptionalData;
+ UINTN OptionalDataSize;
+#if RemoveBootOptionWithoutFile
+ EFI_HANDLE DevHandle;
+#endif
+
+ TRACE((-1,"Get Boot Option Boot%04X\n", BootOrder[i]));
+ if( BootOrder_Flag[i] ) continue; //(EIP138397)
+ FwBootOption = FALSE;
+
+ // Get Boot Option
+ NvramOption = NULL;
+ NvramOptionSize =0;
+ Swprintf(BootStr,L"Boot%04X",BootOrder[i]);
+ Status=GetEfiVariable(
+ BootStr, &EfiVariableGuid, NULL, &NvramOptionSize, &NvramOption
+ );
+ if (EFI_ERROR(Status)) continue;
+
+ DescriptionSize = (Wcslen((CHAR16*)(NvramOption+1))+1)*sizeof(CHAR16);
+ ScrDevicePath =(EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(NvramOption+1)+DescriptionSize);
+
+ OptionalData = (UINT32*)( (UINT8*)ScrDevicePath + NvramOption->FilePathListLength); //(EIP138397+)
+ OptionalDataSize = (UINT8*)NvramOption + NvramOptionSize - (UINT8*)OptionalData; //(EIP138397+)
+
+ // Check is this a non FW boot option
+ if(OptionalDataSize == sizeof(UINT32) &&
+ (*OptionalData == AMI_SIMPLE_BOOT_OPTION_SIGNATURE) ||
+ (*OptionalData == AMI_GROUP_BOOT_OPTION_SIGNATURE) )
+ FwBootOption = TRUE;
+ //(EIP138397+)>
+ RemoveAmiMaskDevicePath(&ScrDevicePath, NvramOption->FilePathListLength);
+ //<(EIP138397+)
+#if RemoveBootOptionWithoutFile
+ // Check the File exist in EfiOsBootOptionNamesFilePathItem or not.
+ // If not exist , remove the variable.
+ if(FwBootOption)
+ {
+ DevHandle = GetGptPartitionHandle(ScrDevicePath);
+
+ if(DevHandle)
+ {
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem = NULL;
+ EFI_FILE_PROTOCOL *FileProtocol = NULL;
+
+ Status = pBS->HandleProtocol (
+ DevHandle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem);
+
+
+ if(!EFI_ERROR(Status))
+ {
+ UINTN j;
+ UINT16 AUTO_BOOT_ENTRY_COUNT = GetEfiOsBootNameItemCount();
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol);
+
+ if (EFI_ERROR(Status))
+ continue;
+
+ for (j = 0; j < AUTO_BOOT_ENTRY_COUNT; j++)
+ {
+ EFI_FILE_PROTOCOL* NewFileProtocol = NULL;
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ EFI_BOOT_FILE_NAME,
+ EFI_FILE_MODE_READ,
+ NULL );
+
+
+ if(!EFI_ERROR(Status))
+ NewFileProtocol->Close(NewFileProtocol);
+
+ if(Status == EFI_NOT_FOUND)
+ {
+ //Clear variable Boot####
+ Status = pRS->SetVariable(
+ BootStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, 0, NULL);
+ BootOrder_Flag[i] = 1;
+ pBS->FreePool(NvramOption);
+ continue;
+ }
+ }
+ }
+ }
+ }
+#endif
+ if( ScrDevicePath->Type == MEDIA_DEVICE_PATH
+ && ScrDevicePath->SubType == MEDIA_HARDDRIVE_DP )
+ {
+ EFI_HANDLE GptHandle;
+ TRACE((-1,"EfiOsBootOrder.c :: BootOrder[%x]=%x %S\n", i, BootOrder[i], (CHAR16*)(NvramOption+1) ));
+ GptHandle = GetGptPartitionHandle(ScrDevicePath);
+ TRACE((-1,"EfiOsBootOrder.c :: GptHandle=%d\n", GptHandle));
+
+ if( GptHandle != NULL)
+ {
+ // Only Non Fw Boot Option Kill Other Boot Option
+ // This module check duplicate Boot Option exist or not when create boot option
+ // So, ignore Fw Boot Option
+ if(FwBootOption)
+ continue;
+ for(j=0; j<BootOrderSize/sizeof(UINT16); j++)
+ {
+ CHAR16 BootStr2[9];
+ UINTN NvramOptionSize2 = 0;
+ EFI_LOAD_OPTION *NvramOption2 = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath = NULL;
+
+ if( BootOrder_Flag[j] || (i == j)) continue;
+
+ TRACE((-1,"EfiOsBootOrder.c :: Search BootOrder[%x]=%x\n", j, BootOrder[j]));
+ // Get Boot Option
+ NvramOption2 = NULL;
+ NvramOptionSize2 =0;
+ Swprintf(BootStr2,L"Boot%04X",BootOrder[j]);
+ Status=GetEfiVariable(
+ BootStr2, &EfiVariableGuid, NULL, &NvramOptionSize2, &NvramOption2
+ );
+ if (EFI_ERROR(Status)) continue;
+
+ DescriptionSize = (Wcslen((CHAR16*)(NvramOption2+1))+1)*sizeof(CHAR16);
+ DevicePath =(EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)(NvramOption2+1)+DescriptionSize);
+#if KeepDuplicateNonFWBootOption
+ OptionalData = (UINT32*)( (UINT8*)DevicePath + NvramOption2->FilePathListLength);
+ OptionalDataSize = (UINT8*)NvramOption2 + NvramOptionSize2 - (UINT8*)OptionalData;
+ TRACE((-1, "OptionalDataSize(%X)\n", (UINT8*)NvramOption2 + NvramOptionSize2 - (UINT8*)OptionalData));
+ // Skip if this is a non FW boot option
+ if(OptionalDataSize != sizeof(UINT32) ||
+ ((*OptionalData != AMI_SIMPLE_BOOT_OPTION_SIGNATURE) &&
+ (*OptionalData != AMI_GROUP_BOOT_OPTION_SIGNATURE)))
+ {
+ pBS->FreePool(NvramOption2);
+ continue;
+ }
+#endif
+ //(EIP138397+)>
+ RemoveAmiMaskDevicePath(&DevicePath, NvramOption2->FilePathListLength);
+ //<(EIP138397+)
+
+ if( CompareHddDevicePath(ScrDevicePath, DevicePath) == EFI_SUCCESS ) //(EIP126686+)
+ {
+ UINTN ReserveIndex;
+ UINTN DeleteIndex;
+ CHAR16 *DeletedStr;
+
+ TRACE((-1,"EfiOsBootOrder.c :: Matched BootOrder[%x]=%x %S\n", j, BootOrder[j], (CHAR16*)(NvramOption2+1) ));
+
+ if(!DefaultFwBootOption && !IsOsCreatedBootOption(BootOrder[i]))
+ {
+ //
+ // BootOrder[i] is not created by OS, but BootOrder[j]
+ //
+ ReserveIndex = j;
+ DeleteIndex = i;
+ DeletedStr = BootStr;
+ }
+ else
+ {
+ ReserveIndex = i;
+ DeleteIndex = j;
+ DeletedStr = BootStr2;
+ }
+ //Delete EfiOsBootOptionNames boot option.
+ //Clear variable Boot####
+ pRS->SetVariable(
+ DeletedStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, 0, NULL);
+
+ BootOrder_Flag[DeleteIndex] = 1;
+ UpdateBootOrder = TRUE;
+
+#if FIXED_BOOT_ORDER_SUPPORT
+ // Handle Fixed Boot Order Priority issue.
+ {
+ UINTN DevOrderSize = 0;
+ UEFI_DEVICE_ORDER *DevOrder = NULL, *DevOrder2 = NULL;
+ EFI_GUID gFixedBootOrderGuid = FIXED_BOOT_ORDER_GUID;
+ UINTN k = 0;
+ UINT32 Attrib = 0;
+
+ Status = GetEfiVariable(L"UefiDevOrder", &gFixedBootOrderGuid, &Attrib, &DevOrderSize, &DevOrder);
+ if(!EFI_ERROR(Status))
+ {
+ DevOrder2 = DevOrder;
+
+ for (DevOrder = DevOrder2
+ ; (UINT8*)DevOrder < (UINT8*)DevOrder2 + DevOrderSize
+ ; DevOrder = (UEFI_DEVICE_ORDER*)((UINT8*)DevOrder + DevOrder->Length + sizeof(DevOrder->Type)))
+ {
+ for (k = 0; k < DEVORDER_COUNT(DevOrder); k++)
+ {
+ TRACE((-1,"DevOrder->Device[%x] %x,BootOrder[DeleteIndex] = %x \n",k,DevOrder->Device[k], BootOrder[DeleteIndex]));
+ if(DevOrder->Device[k] == BootOrder[DeleteIndex])
+ {
+ DevOrder->Device[k] = BootOrder[ReserveIndex];
+ TRACE((-1,"BootOrder[ReserveIndex] %x \n",BootOrder[ReserveIndex]));
+ }
+ }
+ }
+ Status = pRS->SetVariable(L"UefiDevOrder", &gFixedBootOrderGuid, Attrib, DevOrderSize, DevOrder2);
+ pBS->FreePool(DevOrder2);
+ }
+ }
+#endif
+ }
+
+ pBS->FreePool(NvramOption2);
+ } //for (j=0; j<BootOrderSize/sizeof(UINT16); j++)
+ } //if ( GptHandle != NULL)
+ else
+ //GPT HDD NOT FOUND, Remove This BootOrder
+ {
+ if ( (((HARDDRIVE_DEVICE_PATH*)ScrDevicePath)->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) &&
+ FwBootOption)
+ {
+ //Clear variable Boot####
+ Status = pRS->SetVariable(
+ BootStr, &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, 0, NULL);
+
+ UpdateBootOrder = TRUE;
+ BootOrder_Flag[i] = 1;
+ }
+ }
+ }
+
+ pBS->FreePool(NvramOption);
+ }
+
+ if( UpdateBootOrder )
+ {
+ TRACE((-1,"EfiOsBootOrder.c :: Update BootOrder, Dump New BootOrder \n" ));
+ for(i = 0 ; i < BootOrderSize/sizeof(UINT16) ; i++)
+ {
+ if(BootOrder_Flag[i])
+ continue;
+
+ TRACE((-1,"%x ",BootOrder[i]));
+ NewBootOrder[BootIndex++] = BootOrder[i];
+ }
+ TRACE((-1,"\n "));
+ pRS->SetVariable(
+ L"BootOrder", &EfiVariableGuid,
+ BOOT_VARIABLE_ATTRIBUTES, BootIndex * sizeof(UINT16), NewBootOrder);
+ }
+
+ pBS->FreePool(NewBootOrder);
+ pBS->FreePool(BootOrder);
+
+}
+
+#if (CSM_SUPPORT == 1) && (RemoveLegacyGptHddDevice == 1)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveLegacyGptHdd
+//
+// Description: Determine whether boot device is a UEFI HDD(GPT format).
+//
+// Input: BOOT_DEVICE Device - Boot device to be checked.
+//
+// Output: TRUE - Boot Device is a UEFI HDD..
+// FALSE - Boot Device is not a UEFI HDD.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN RemoveLegacyGptHdd(BOOT_DEVICE *Device){
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ EFI_STATUS Status;
+ UINT8 *Buffer = NULL;
+ UINTN index;
+ PARTITION_ENTRY *pEntries;
+
+ if ( Device->DeviceHandle == INVALID_HANDLE
+ || Device->BbsEntry == NULL
+ ) return FALSE;
+
+ if( Device->BbsEntry->DeviceType != BBS_HARDDISK ) return FALSE;
+
+ Status=pBS->HandleProtocol(
+ Device->DeviceHandle, &gEfiBlockIoProtocolGuid, &BlkIo
+ );
+
+ if (EFI_ERROR(Status) || BlkIo->Media->RemovableMedia) return FALSE; //USB device?
+
+ Status = pBS->AllocatePool( EfiBootServicesData, BlkIo->Media->BlockSize, &Buffer );
+ if( Buffer == NULL ) return FALSE;
+
+ // read the first sector
+ BlkIo->ReadBlocks ( BlkIo,
+ BlkIo->Media->MediaId,
+ 0,
+ BlkIo->Media->BlockSize,
+ (VOID*)Buffer);
+
+ if(Buffer[0x1fe]==(UINT8)0x55 && Buffer[0x1ff]==(UINT8)0xaa) //MBR Signature
+ {
+ pEntries=(PARTITION_ENTRY *)(Buffer+0x1be);
+
+ for(index=0;index<4;index++)
+ {
+ if( pEntries[index].PartitionType==0xee) //Check GPT Partition?
+ {
+ pBS->FreePool( Buffer );
+ return TRUE; //Set Can't Boot.
+ }
+ } //for(index=0;index<4;index++)
+ }//if(Buffer[0x1fe]==0x55 && Buffer[0x1ff]==0xaa)
+
+ pBS->FreePool( Buffer );
+ return FALSE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSpecifiedUefiOsBootOption
+//
+// Description: Check whether specified uefi os boot option.
+//
+// Input: BOOT_OPTION Option - boot option to check.
+//
+// Output: TRUE - Is specified uefi os boot option
+// FALSE - Isn't specified uefi os boot option
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSpecifiedUefiOsBootOption(BOOT_OPTION *Option)
+{
+ UINTN i, j;
+ NAME_MAP UefiOsNameMap[] = {{EFI_BOOT_FILE_NAME, NAME_OF_UEFI_OS}, {NULL, NULL}};
+ NAME_MAP* NameMaps[] = {
+ FILE_NAME_MAPS,
+#if CREATE_BOOT_OPTION_WITH_UEFI_FILE_NAME_POLICY == 1
+ UefiOsNameMap,
+#endif
+ NULL
+ };
+
+ if(!Option) return FALSE;
+
+ if(IsLegacyBootOption(Option)) return FALSE;
+
+ for(i = 0; NameMaps[i]; i++)
+ {
+ NAME_MAP *NameMapWalker = NameMaps[i];
+ for (j = 0; NameMapWalker[j].FilePath; j++)
+ {
+ // check option name length, if OptionName < FileNameMaps, don't skip boot option
+ if ( Wcslen(Option->Description) < Wcslen(NameMapWalker[j].BootOptionName))
+ continue ;
+ // check option string
+ if ( !MemCmp( Option->Description, NameMapWalker[j].BootOptionName,
+ Wcslen(NameMapWalker[j].BootOptionName)*sizeof(CHAR16)))
+ {
+ // check option device path.
+ EFI_DEVICE_PATH_PROTOCOL *Dp = Option->FilePathList ;
+ BOOLEAN HardDriveFlag=FALSE, MediaFilePathFlag=FALSE ;
+ while(!isEndNode(Dp))
+ {
+ if (Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_HARDDRIVE_DP)
+ HardDriveFlag = TRUE ;
+ if (Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_FILEPATH_DP)
+ MediaFilePathFlag = TRUE ;
+ Dp = NEXT_NODE(Dp) ;
+ }
+
+ if (HardDriveFlag && MediaFilePathFlag)
+ {
+ TRACE((-1,"%S don't normalize.\n", Option->Description )) ;
+ return TRUE;
+ }
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiOsName_NormalizeBootOptions
+//
+// Description: If normalization is enabled, regenerates all the description strings
+// and/or file path lists. This function override BDS kernel, because Uefi
+// Os Boot Option can't be normalize file path and names.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EfiOsName_NormalizeBootOptions(){
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ // Normalize boot options
+ //(regenerate the description string and the file path list)
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+
+ if ( !Option->FwBootOption || !IsBootOptionWithDevice(Option)
+ || Option->BootOptionNumber == INVALID_BOOT_OPTION_NUMBER
+ ) continue;
+
+ // Skip Uefi Hdd Os boot option
+ if (IsSpecifiedUefiOsBootOption(Option)) continue ;
+
+ if (NormalizeBootOptionDevicePath){
+ EFI_DEVICE_PATH_PROTOCOL *OldFilePathList = Option->FilePathList;
+ UINTN OldFilePathListLength = Option->FilePathListLength;
+ Option->FilePathList = NULL;
+ Option->FilePathListLength = 0;
+ BuildBootOptionFilePath(Option);
+ if (Option->FilePathList == NULL){
+ Option->FilePathList = OldFilePathList;
+ Option->FilePathListLength = OldFilePathListLength;
+ }else if (OldFilePathList != NULL){
+ pBS->FreePool(OldFilePathList);
+ }
+ }
+ if (NormalizeBootOptionName){
+ CHAR16 *OldDescription = Option->Description;
+ Option->Description = NULL;
+ ConstructBootOptionName(Option);
+ if (Option->Description == NULL)
+ Option->Description = OldDescription;
+ else if (OldDescription != NULL)
+ pBS->FreePool(OldDescription);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustNewUefiOsOptionPriority
+//
+// Description: Adjust new UEFI OS boot option priority.
+// Follow the policy NEW_UEFI_OS_OPTION_ORDER_POLICY
+// to change priority with new UEFI OS boot option.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AdjustNewUefiOsOptionPriority()
+{
+ EFI_STATUS Status;
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ UINTN Size;
+ UINTN x = 0;
+ UINT32 Priority = 0;
+ UINT8 NewOptionPolicy;
+ EFI_GUID EfiOsBootOptionNamesGuid = EFI_OS_BOOT_OPTION_NAMES_GUID;
+
+ TRACE((-1,"EfiOsBootOrder.c : Update new Uefi OS option priority\n")) ;
+
+ // if no new EFI OS boot option added, just return.
+ if (!NewEfiOsOptionDpListCount) return ;
+
+ Size = sizeof (UINT8);
+ Status = pRS->GetVariable (
+ L"NewOptionPolicy",
+ &EfiOsBootOptionNamesGuid,
+ NULL,
+ &Size,
+ (VOID *) &NewOptionPolicy
+ );
+
+ if(EFI_ERROR(Status))
+ {
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+ return;
+ }
+
+ if (NewOptionPolicy == 0)
+ {
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+ return;
+ }
+ else if (NewOptionPolicy == 1)
+ {
+ Priority = LOWEST_BOOT_OPTION_PRIORITY ;
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if (Option->Priority < Priority)
+ Priority = Option->Priority ;
+ Option->Priority += (UINT32)NewEfiOsOptionDpListCount ;
+ }
+ }
+ else if (NewOptionPolicy == 2)
+ {
+ Priority = 0 ;
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if (Option->Priority > Priority)
+ Priority = Option->Priority + 1 ;
+ }
+ }
+
+ for ( x=0 ; x<NewEfiOsOptionDpListCount ; x++ )
+ {
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+
+ Dp = *(NewEfiOsOptionDpList+x);
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if (Option->FilePathList == Dp)
+ Option->Priority = Priority++ ;
+ }
+ }
+ NewEfiOsOptionDpListCount = 0 ;
+ pBS->FreePool(NewEfiOsOptionDpList) ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveEfiOsBootOrder
+//
+// Description: Save the boot order to check later,
+// then we can know which one is created by OS.
+//
+// Input: None.
+//
+// Output: None.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SaveEfiOsBootOrder()
+{
+ EFI_STATUS Status;
+ UINTN BootOrderSize = 0;
+ UINT16* BootOrder = NULL;
+
+ Status = GetEfiVariable(
+ L"BootOrder",
+ &EfiVariableGuid,
+ NULL,
+ &BootOrderSize,
+ &BootOrder);
+
+ if(!EFI_ERROR(Status))
+ {
+ EFI_GUID EfiOsBootOptionNamesGuid = EFI_OS_BOOT_OPTION_NAMES_GUID;
+
+ pRS->SetVariable(
+ L"EfiOsBootOrder",
+ &EfiOsBootOptionNamesGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ BootOrderSize,
+ (VOID*)BootOrder);
+
+ pBS->FreePool(BootOrder);
+ }
+}
+
+//***********************************************************************
+//#**********************************************************************
+//#** **
+//#** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//#** **
+//#** All Rights Reserved. **
+//#** **
+//#** 5555 Oak brook Pkwy, Norcorss, GA 30093 **
+//#** **
+//#** Phone: (770)-246-8600 **
+//#** **
+//#**********************************************************************
diff --git a/Core/EM/FastBoot/FastBoot.c b/Core/EM/FastBoot/FastBoot.c
new file mode 100644
index 0000000..1021e72
--- /dev/null
+++ b/Core/EM/FastBoot/FastBoot.c
@@ -0,0 +1,4537 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBoot.c 58 8/06/13 10:42p Simonchen $
+//
+// $Revision: 58 $
+//
+// $Date: 8/06/13 10:42p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBoot.c $
+//
+// 58 8/06/13 10:42p Simonchen
+// [TAG] EIP130731
+// [Category] Improvement
+// [Description] Use file system protocol to check boot loader.
+// [Files] FastBoot.c
+//
+// 57 7/17/13 2:59a Simonchen
+// [TAG] EIP125309
+// [Category] New Feature
+// [Description] Add function to make sure before boot to OS, BIOS is in
+// fastboot path.
+// [Files] FastBoot.sdl
+// FastBootTseHook.c
+// FastBoot.c
+// FastBoot.h
+//
+// 56 7/14/13 10:10p Simonchen
+// [TAG] EIP118901
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The Rumtime Memory Allocation in SmiVariable Module may
+// cause S4 Resume Failure
+// [RootCause] Memory mapping changed between Normal Boot Path and
+// FastBoot Path if SmiVariable is enabled
+// [Solution] Publish HII data in fastboot path.
+// [Files] FastBoot.c
+//
+// 55 7/11/13 10:10p Simonchen
+// [TAG] EIP126196
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] If set two HDD password and use Raid mode, fastboot will
+// fail.
+// [RootCause] Because when AHCI driver unlock first HDD, Raid driver
+// will try to read all HDD, but second HDD is still lock, so access will
+// fail.
+// [Solution] Make sure all HDD unlock then Raid can access HDD.
+// And add "Support Raid Driver" token to control fastboot support Raid
+// feature or not.
+// [Files] FastBoot.c
+// FastBoot.sd
+// FastBoot.sdl
+// FastBootRuntime.c
+// FastBoot.h
+//
+// 54 4/18/13 5:39a Simonchen
+// [TAG] EIP113454
+// [Category] New Feature
+// [Description] This eip is created for implement or experiment for
+// Intel raid mode on fastboot.
+// [Files] FastBoot.sdl
+// FastBootRuntime.c
+// FastBoot.c
+// FastBoot.sd
+// FastBoot.uni
+//
+// 53 1/15/13 1:50a Bibbyyeh
+// Boot variables is in upper case from version 4.6.4.1.
+//
+// 52 1/07/13 2:04a Bibbyyeh
+// [TAG] EIP111095
+// [Category] Improvement
+// [Description] Win8 will create "WINDOWS BOOT MANAGER" and change this
+// boot option as the highest boot priority when first time boot into
+// Win8. It may cause fast boot fail because boot order is changed by OS.
+// To avoid this problem, we check devcie path again if boot option number
+// is check failure.
+// [Files] FastBoot.c
+//
+// 51 12/21/12 2:38a Bibbyyeh
+// [TAG] EIP110027
+// [Category] Improvement
+// [Description] The parameter BootPolicy should NOT set as TRUE when
+// load image if this loading is not for boot.
+// [Files] FastBoot.c
+//
+// 50 12/12/12 2:59a Bibbyyeh
+// [TAG] EIP107729
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When fastboot enable, the floppy disk driver can¡¦t
+// detect by OS(already test on Win7 32 and 64(not UEFI))
+// [RootCause] BIOS didn't install INT13 service for floppy.
+// [Solution] Don't set bbs priority of floppy as BBS_IGNORE_ENTRY,
+// set as BBS_DO_NOT_BOOT_FROM.
+// [Files] FastBoot.c
+//
+// 49 11/29/12 9:30p Bibbyyeh
+// [Description] Fix build error because AMI_AMT_BOOT_OPTION_GUID is not
+// found on non-Intel platforms.
+// [Files] FastBoot.c
+//
+// 48 10/30/12 3:13a Bibbyyeh
+// [TAG] EIP105175
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB controller does not skip in Fast Boot path when set
+// USB support as disabled.
+// [RootCause] The Runtime flag is set too early, and it make USB
+// controller connect again when TSE call ReadKeyStroke.
+// [Solution] Set Runtime flag just before boot into image or legacy
+// environment to make sure the ReadKeyStroke is called by OS, not BIOS.
+// [Files] FastBoot.c
+//
+// 47 10/11/12 2:34a Bibbyyeh
+// [TAG] EIP103422
+// [Category] Improvement
+// [Description] FastBoot behavior is conflict with Fixed boot order.
+// System cannot Enter windows 7 most of the time and will just show the
+// message no bootable device found.
+// [Files] FastBoot.c
+//
+// 46 10/04/12 11:52p Bibbyyeh
+// [TAG] EIP102931
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When issue the Local HDD Boot from WebUI, sometimes the
+// BIOS can't boot from Local Hard Disk drive and enter BIOS setup.
+// [RootCause] It's possible AMT boot device is skipped in fast boot
+// path, and enter setup.
+// [Solution] If AMT boot is request, boot with normal boot path and
+// set Setup boot flow as BOOT_FLOW_CONDITION_NORMAL.
+// [Files] FastBoot.c FastBoot.sdl
+//
+// 45 9/06/12 8:01a Bibbyyeh
+// The definition in USB_SKIP_LIST is changed from bNotUsed to bFlag.
+//
+// 44 9/06/12 6:20a Bibbyyeh
+// [TAG] EIP100342
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs if remove monitor cable (D-SUB\DVI\HDMI)
+// when FastBoot enabled.
+// [RootCause] When monitor cable is removed ,there is no simple text
+// out protocol installed for ConOut service in fastboot mode.
+// [Solution] Signal CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID and
+// install simple text out protocol even if there is no ConOut devcie.
+// [Files] FastBoot.c
+//
+// 43 9/06/12 3:41a Bibbyyeh
+// [TAG] EIP96292
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Bitlock test failure when fast boot enabled and USB
+// support is as "partial initial".
+// [RootCause] Usb key can NOT be connected by Windows successfully.
+// [Solution] Usb module provides the policy control for USB mass
+// storage driver enabled/disabled dynamically.
+//
+// 42 8/28/12 11:58p Bibbyyeh
+// Consider fast boot failed case, chagne boot flow back to
+// BOOT_FLOW_CONDITION_NORMAL.
+//
+// 41 8/27/12 6:08a Bibbyyeh
+// Fixed the logic of IsFastBoot elink. System only enter FastBoot path
+// when all the IsFastBoot elinks return TRUE.
+//
+// 40 8/24/12 1:09a Bibbyyeh
+// Fixed the logic of IsFastBoot elink. System only enter FastBoot path
+// when all the IsFastBoot elinks return TRUE.
+//
+// 39 8/23/12 6:07a Bibbyyeh
+// Modify Dp macro and add a flag "InFastBootPath".
+//
+// 38 8/22/12 5:42a Bibbyyeh
+// [TAG] EIP95568
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SATA HDD device is not found under UEFI Shell when SATA
+// mode is RAID
+// [RootCause] RAID controller is not connected in fast boot path.
+// [Solution] Connect RAID controller in ConnectAllSATADevices
+// procedure.
+// [Files] FastBoot.c
+//
+// 37 8/16/12 1:27a Bibbyyeh
+// Refine the code base and add Dp macro.
+//
+// 36 8/10/12 6:00a Bibbyyeh
+// [TAG] EIP97474
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Some ConIn devices are not workable in fastboot path.
+// [RootCause] Some handles are not connectted in FbConnectEverything.
+// [Solution] Connect all handles and only skip the devices we
+// expected.
+// [Files] FastBoot.c FastBoot.sdl
+//
+// 35 8/10/12 3:23a Bibbyyeh
+// [TAG] EIP96276
+// [Category] New Feature
+// [Description] Function request for PTT_12
+// EIP96276.2 Fixed USB skip table issue.
+// EIP96276.3 Add token ¡¥CONNECT_ALL_SATA_DEVICE_IN_FASTBOOT¡¦ to
+// gFastBootPolicy.
+// EIP96276.4 Add IsValidFBBootOptionPtr support by driver type. Exp : usb
+// type skip or other type
+// EIP96276.5 Add token ¡¥Test mode¡¨ to gFastBootPolicy Setup menu.
+// EIP96276.6 Disable Tse Hotkey support in fastboot path.
+// EIP96276.7 Modify TRACE message.
+// [Files] FastBoot.c FastBoot.sd FastBoot.sdl FastBoot.uni
+// FastBootRuntime.c FastBootProtocol.c
+//
+// 34 8/07/12 4:40a Bibbyyeh
+// [TAG] EIP97545
+// [Category] Improvement
+// [Description] Updated PTT Module to Implement Support for
+// Initializing the Keyboard in First Call of Readkeystroke on Fastboot.
+// [Files] FastBoot.c FastBoot.h FastBootProtocol.h
+//
+// 33 6/27/12 4:21a Bibbyyeh
+// [TAG] EIP93038
+// [Category] New Feature
+// [Description] Ability to customize fast boot boot option selection
+// [Files] FastBoot.c FastBoot.h FastBoot.sdl
+//
+// 32 6/22/12 2:49a Bibbyyeh
+// [TAG] EIP91458
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hangs if USB LAN is first boot priority
+// [RootCause] USB LAN is identified as USB Hdd, and it cause fast
+// boot behavior wrong.
+// [Solution] Add checking rule for USB LAN, this kind of device
+// would not be the fast boot device.
+// [Files] FastBoot.c
+//
+// 31 6/13/12 8:49a Bibbyyeh
+// Add checking Built in Shell device path when building Fast Efi Boot
+// Option.
+//
+// 30 6/12/12 10:15p Bibbyyeh
+// Add a item "Auto" for fastboot "VGA Support". Only install Legacy OpRom
+// only when previous boot is Legacy OS.
+//
+// 29 6/07/12 7:42a Bibbyyeh
+// [TAG] EIP91800
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The USB_SKIP_LIST which in the SBDXE.c in the routing
+// ¡§sbUsbProtocolCallback¡¨ is not working.
+// [RootCause] UsbSkipTable is updated by PTT module
+// [Solution] Backup SkipTable pointer before set new skip table in
+// Fastboot path. If return to normal boot mode, restore the skip table
+// pointer to backup one.
+// [Files] FastBoot.c
+//
+// 28 6/04/12 4:34a Bibbyyeh
+// Compliant with Core 4.6.4.0
+//
+// 27 6/01/12 7:04a Bibbyyeh
+// [TAG] EIP90455
+// [Category] New Feature
+// [Description] PTT improvement - fastboot policy protocol for dynamic
+// control fast boot behavior.
+// [Files] FastBoot.c FastBoot.sdl FastBoot.sd FastBoot.uni
+// FastBootRuntime.c FastBootTseHook.c FastBootProtocol.h FastBoot.h
+//
+// 26 5/29/12 3:19a Bibbyyeh
+// [TAG] EIP87390
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] TCG Bitlocker Driver Encryption error if set the Fast
+// boot enable
+// [RootCause] USB INT13 service is not installed and Pci OpRom is not
+// measured by TPM in fastboot path.
+// [Solution] Set USB device priority as BBS_DO_NOT_BOOT_FROM for
+// install int13 service. Raise TPL as TPL_HIGH_LEVEL for invoking TPM
+// callback function "OnPciIOInstalled".
+// [Files] FastBoot.h
+//
+// 25 4/13/12 4:17a Bibbyyeh
+// [TAG] EIP86159
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] SUT can't be unlock by network when FastBoot enabled,
+// it always needs to input PIN code and recovery key even connected to
+// WDS Server.
+// [RootCause] Network stack protocol didn't install in fastboot path.
+// [Solution] Connect Network device and install network stack
+// protocol.
+// [Files] FastBoot.c
+//
+// 24 4/11/12 6:12a Bibbyyeh
+// [TAG] EIP87526
+// [Category] New Feature
+// [Description] Fastboot from specific device without recording device
+// infomration from previous boot
+// [Files] FastBoot.c
+//
+// 23 4/10/12 9:08a Bibbyyeh
+// Fix a typo for pervious check in.
+//
+// 22 4/10/12 8:47a Bibbyyeh
+// [TAG] EIP87452
+// [Category] Improvement
+// [Description] 1. Create an elink "ReturnNormalMode", OEM/ODM can link
+// their procedure to handle the fastboot failure case. 2. Disconnect USB
+// controller when return to normal mode.
+// [Files] FastBoot.c FastBoot.h FastBoot.mak FastBoot.sdl
+//
+// 21 4/09/12 9:09a Bibbyyeh
+// [Category] Improvement
+// [Description] Replace procedure "FbAllDriverConnect" by elink
+// "CallTheDispatcher" and "SignalAllDriversConnectedEvent".
+// [Files] FastBoot.c FastBoot.sdl
+//
+// 20 3/22/12 6:42a Bibbyyeh
+// [TAG] EIP86042
+// [Category] Improvement
+// [Description] For Win8 seamless boot, BIOS should not clear screen
+// when boot into OS.
+// [Files] FastBoot.c
+//
+// 19 3/22/12 3:19a Bibbyyeh
+// [TAG] EIP85135
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When enabled XHCI support difficult into setup menu
+// [RootCause] Usb addon is not connected successfully when connect
+// Console In devices.
+// [Solution] Create FbConnectEverything procedure to connect usb
+// controller.
+// [Files] FastBoot.c FastBoot.sdl
+//
+// 18 1/29/12 11:34p Bibbyyeh
+// [TAG] EIP75969
+// [Category] Improvement
+// [Description] Moved signaling of ReadyToBoot event on EFI boot path
+// before call to LoadImage as per UEFI spec.
+// [Files] FastBoot.c
+//
+// 17 11/21/11 5:41a Bibbyyeh
+// [TAG] EIP75718
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] After reboot 2 times, system will show error message
+// and hang up if enabled Fast boot with skip VGA
+// [RootCause] In SG mode, fastboot need to consider mutli VGA case.
+// [Solution] Disable PCI VGA device when check or install VGA rom
+// failure.
+// [Files] FastBoot.c
+//
+// 16 10/25/11 2:16a Bibbyyeh
+// [TAG] EIP73019
+// [Category] Improvement
+// [Description] Code logic improvment, 'Index' used on line 1489,
+// conditionally not set
+// [Files] FastBoot.c
+//
+// 15 10/25/11 2:12a Bibbyyeh
+// [TAG] EIP71257
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SugarBay got build errors if TSE is disabled.
+// [RootCause] TSE_MAJOR and TSE_MINOR are not defined when TSE is
+// disabled.
+// [Solution] Add define for TSE_MINOR and TSE_MAJOR if they are not
+// defined.
+// [Files] FastBoot.c
+//
+// 14 9/08/11 5:26a Bibbyyeh
+// [TAG] EIP68329
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] OS can't back to desktop correctly after resumed from
+// S3.
+// [RootCause] TSEIDEPasswordFreezeDevices is skipped in fastboot path
+// if SKIP_TSE_HANDSHAKE is enabled.
+// [Solution] Call TSEIDEPasswordFreezeDevices after ReadyToBoot
+// Event in fastboot path.
+// [Files] FastBoot.c FastBootProtocol.h FastBootTseHook.c
+//
+// 13 8/04/11 8:10a Bibbyyeh
+// [TAG] EIP62845
+// [Category] New Feature
+// [Description] Connect all Sata devices in fastboot path.
+// [Files] FastBoot.c FastBoot.mak FastBoot.sdl
+//
+// 12 7/07/11 10:07a Bibbyyeh
+// [TAG] EIP63924
+// [Category] Improvement
+// [Description]
+// 1. Add elink for FastBoot mode change, default checking rule is check
+// post hotkey.
+// 2. Timer call back for check hotkey is not necessary. Create a protocol
+// for calling checkforkey in TSE.
+// 3. Since EIP68383 improve the performance of ps2 keyboard, we don't
+// need to exchange the initial order of ConIn/ConOut for getting more
+// time to detect hotkey.
+// [Files] FastBoot.sdl FastBoot.mak FastBoot.c FastBootTseHook.c
+// FastBoot.h FastBootProtocol.h
+//
+// 11 6/22/11 11:45p Bibbyyeh
+// [TAG] EIP62683
+// [Category] New Feature
+// [Description] Add an Elink after AllDriverConnect in fastboot path
+// [Files] FastBoot.c FastBoot.sdl FastBoot.mak
+//
+// 10 5/30/11 4:34a Bibbyyeh
+// [TAG] EIP60794
+// [Category] Improvement
+// [Description] Post Time Tuning eModule improvement for CSP.
+// 1. Clear screen before boot into shell and enable
+// cursor.
+// 2. Move Fastboot.h to include folder.
+// [Files] FastBoot.c
+// FastBoot.cif
+// FastBootIncludes.cif
+//
+// 9 3/17/11 7:18a Bibbyyeh
+// [TAG] EIP56151
+// [Category] Improvement
+// [Description] PTT eModule has several compiled errors if CSM eModule
+// is removed, that must be solved.
+// [Files] FastBoot.c FastBoot.sd
+//
+// 8 3/11/11 10:01p Bibbyyeh
+// [TAG] EIP54993
+// [Category] Improvement
+// [Description]
+// 1.Sync with Fastboot_10
+// 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+// 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+// 4.Use SimpleText protocol to detect mode change hotkey instead of
+// pBS->ConIn.
+// 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+// 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+// fastboot path.
+// [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+// FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+// FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+// FastBootSMI.dxs FastBootSMI.mak
+//
+// 7 2/22/11 4:06a Bibbyyeh
+// [TAG] EIP54286
+// [Category] Improvement
+// [Description] Add elink for IsFastBoot Function to overwirte it, it
+// can help OEM/ODM to implement their "FAST BOOT" feature easily.
+// [Files] FastBoot.sdl FastBoot.mak FastBoot.c
+//
+// 6 11/26/10 12:10a Bibbyyeh
+// [TAG] EIP48698
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] CPU exception when all ConIn are skipped.
+// [RootCause] It's side effect of "EIP48698". "FBTimerCallback" is
+// called when pBS-> ConIn is Null.
+// [Solution] Move "FBTimerCallback" to after
+// "InstallDummySimpleTextProtocol" to make sure pBS->Con is not Null.
+// [Files] FastBoot.c
+//
+// 5 11/22/10 7:49a Bibbyyeh
+// [TAG] EIP48698
+// [Category] Improvement
+// [Description] For improving success ratio of mode change by hotkey.
+// Move some work into PTT module, it can make BIOS have more time to
+// detect hotkey. 1.Install and execute VGA OpRom in PTT module. 2.Replace
+// the order of connect ConIn/ConOut.
+// [Files] FastBoot.c
+//
+// 4 11/17/10 9:43a Bibbyyeh
+// [TAG] EIP47397
+// [Category] Improvement
+// [Description] 1. Move all console related functions into PTT module
+// to avoid uncompatible with different core version.
+// 2. Install dumy SimpleTextCoin protocol when pBS->ConIn & pBS-ConOut is
+// Null.
+// 3. Raise timer call back as TPL_HIGH_LEVEL level, it will give BIOS
+// more chance to mode change successfully.
+// 4. Remove FASTBOOT_CONSOLE_SETTING token.Add setup option for fastboot
+// setting, "Skip VGA", "Skip USB", Skip "PS2".
+// [Files] FastBoot.c
+// FastBoot.h
+// FastBoot.sd
+// FastBoot.sdl
+// FastBoot.uni
+//
+// 3 10/22/10 8:26a Bibbyyeh
+// [TAG] EIP46688
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] After dd PTT moduel and enable fast boot, the system will
+// have a CPU exception 0xOD error during POST
+// [RootCause] The root cause is EFI_COMPONENT_NAME_PROTOCOL_GUID and
+// EFI_COMPONENT_NAME2_PROTOCOL_GUID is used in different UEFI version.
+// [Solution] Add UEFU versrion checking rule to avoid this problem.
+// [Files] fastboot.c
+//
+// 2 10/13/10 5:08a Bibbyyeh
+// Replace BeforeFastBoot to BeforeFastBootHook to solve build error
+//
+// 1 10/12/10 9:04a Bibbyyeh
+// Initial check in
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBoot.c
+//
+// Description:
+// Implementation of fast boot functionality
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//============================================================================
+// Includes
+//============================================================================
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/LoadedImage.h>
+
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/ConsoleControl.h>
+#include <Pci.h>
+#include <Protocol/AMIPostMgr.h>
+#include <Protocol/FastBootProtocol.h>
+#include <Protocol/AmiUsbController.h> //(EIP85135+)
+#include <Protocol/UsbPolicy.h>
+
+//#include <PPI\SBPPI.h>
+#include <Protocol\PIDEController.h>
+#include <Protocol\PDiskInfo.h>
+
+#if CSM_SUPPORT
+#include <Protocol/LegacyBios.h>
+#endif
+
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+#include <CmosAccess.h>
+ #endif
+#endif
+
+#include <Protocol\PIDEBus.h>
+#include <Protocol\PAhciBus.h>
+
+#include "FastBoot.h"
+#include "Core\EM\USB\rt\usbdef.h"
+
+#include <Protocol\SimpleFileSystem.h>
+//============================================================================
+// Define
+//============================================================================
+ //(EIP71257+)>
+#if !defined(AMITSE_SUPPORT) || (!AMITSE_SUPPORT)
+ #ifndef TSE_MAJOR
+ #define TSE_MAJOR 0
+ #endif
+ #ifndef TSE_MINOR
+ #define TSE_MINOR 0
+ #endif
+#endif
+ //<(EIP71257+)
+#define AMI_MEDIA_DEVICE_PATH_GUID \
+ { 0x5023b95c, 0xdb26, 0x429b, 0xa6, 0x48, 0xbd, 0x47, 0x66, 0x4c, 0x80, 0x12 }
+
+#define BOOT_IA32 44 //size in bytes of string L"EFI\\BOOT\\BOOTIA32.EFI"
+#define BOOT_X64 42 //size in bytes of string L"EFI\\BOOT\\BOOTx64.EFI"
+
+struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ CHAR16 FileName[22];
+} FilePathNode = {
+ {
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+#ifdef EFIx64
+ BOOT_X64 + 4
+#else
+ BOOT_IA32 + 4
+#endif
+ },
+#ifdef EFIx64
+ { L"EFI\\BOOT\\BOOTx64.EFI"}
+#else
+ { L"EFI\\BOOT\\BOOTIA32.EFI" }
+#endif
+};
+
+struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ CHAR16 FileName[20];
+} TestFilePathNode = {
+ {
+ MEDIA_DEVICE_PATH,
+ MEDIA_FILEPATH_DP,
+#ifdef EFIx64
+ 38 + 4
+#else
+ 40 + 4
+#endif
+ },
+#ifdef EFIx64
+ { L"EFI\\DP\\BOOTx64.EFI"}
+#else
+ { L"EFI\\DP\\BOOTIA32.EFI" }
+#endif
+};
+
+#define BOOT_FLOW_CONDITION_FAST_BOOT 7
+#define BOOT_FLOW_CONDITION_NORMAL 0
+
+#define EFI_SHELL_PROTOCOL_GUID \
+ {0x47C7B223, 0xC42A, 0x11D2, 0x8E, 0x57, 0x00, 0xA0, 0xC9, 0x69, 0x72, 0x3B}
+
+#if CORE_COMBINED_VERSION > 0x40281
+#define gBootName L"Boot%04X"
+#else
+#define gBootName L"Boot%04x"
+#endif
+//============================================================================
+// Globel Variable
+//============================================================================
+static EFI_GUID AmiMediaDevicePathGuid = AMI_MEDIA_DEVICE_PATH_GUID;
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+static EFI_GUID FastBootVariableGuid = FAST_BOOT_VARIABLE_GUID;
+static EFI_GUID gSimpleTextOutProtocolGuid = EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID;
+static EFI_GUID gSimpleTextInProtocolGuid = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
+static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID;
+#if FASTBOOT_NEED_RESTART
+static EFI_GUID FastbootRestartGuid = FAST_BOOT_RESTART_GUID;
+static EFI_GUID FastbootRestartCountGuid = FAST_BOOT_RESTART_COUNT_GUID;
+#endif
+extern EFI_GUID AmiPostMgrProtocolGuid;
+extern EFI_HANDLE ThisImageHandle;
+
+EFI_GUID gUsbPolicyGuid = EFI_USB_POLICY_PROTOCOL_GUID;
+EFI_GUID gEfiPciIoProtocolGuid2 = EFI_PCI_IO_PROTOCOL_GUID;
+EFI_GUID FbConInStartedProtocolGuid = CONSOLE_IN_DEVICES_STARTED_PROTOCOL_GUID;
+EFI_GUID FbConOutStartedProtocolGuid = CONSOLE_OUT_DEVICES_STARTED_PROTOCOL_GUID;
+EFI_GUID FbBdsAllDriversConnectedProtocolGuid = \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93};
+
+FAST_BOOT_TSE_PROTOCOL *gFastBootTseProtocol=NULL; //(EIP63924+)
+
+EFI_HANDLE gDummyConInHdl = NULL;
+EFI_HANDLE gDummyConOutHdl = NULL;
+EFI_HANDLE EFIBootImageHanlde = NULL;
+EFI_HANDLE LegacyBootDeviceHandle = NULL;
+EFI_HANDLE *RootHandles;
+UINTN NumberOfHandles;
+SETUP_DATA FbSetupData;
+static BOOLEAN Runtime = FALSE;
+BOOLEAN StopBlkIo = FALSE;
+EFI_HANDLE gHandle = NULL;
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+EFI_CMOS_ACCESS_INTERFACE *CmosInterface = NULL;
+ #endif
+#endif
+
+static AMI_FAST_BOOT_PROTOCOL FastBootProtocol = {
+ NULL,
+ FbConnectInputDevices,
+ IsRuntime
+};
+
+EFI_SIMPLE_TEXT_INPUT_PROTOCOL DummySimpleInProtocol = {
+ DummyInReset,
+ DummyReadKeyStroke,
+ NULL
+ } ;
+
+SIMPLE_TEXT_OUTPUT_MODE DummyMasterMode =
+ {
+ 1, // MaxMode
+ 0, // Current Mode
+ 0x0F, // Attribute
+ 0, // Column
+ 0, // Row
+ 1 // CursorVisible
+ };
+
+EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL DummySimpleOutProtocol = {
+ DummyReset,
+ DummyOutputString,
+ DummyTestString,
+ DummyQueryMode,
+ DummySetMode,
+ DummySetAttribute,
+ DummyClearScreen,
+ DummySetCursorPosition,
+ DummyEnableCursor,
+ &DummyMasterMode
+ };
+
+typedef BOOLEAN (IsFastBootElink)(
+ IN SETUP_DATA *Setupdata
+);
+
+extern IsFastBootElink IS_FAST_BOOT_LIST EndOfIsFastBootList;
+IsFastBootElink* IsFastBootList[] = {IS_FAST_BOOT_LIST NULL};
+ //(EIP62683+)>
+typedef VOID (AfterAllDrirverConnectElink)();
+extern AfterAllDrirverConnectElink AFTER_ALL_DRIVER_CONNECT_HOOK EndOfList;
+AfterAllDrirverConnectElink* AfterAllDriverConnectList[] = {AFTER_ALL_DRIVER_CONNECT_HOOK NULL};
+ //<(EIP62683+)
+ //(EIP63924+)>
+typedef BOOLEAN (FastBootCheckModeChangeElink)();
+extern FastBootCheckModeChangeElink FAST_BOOT_CHECK_MODE_CHANGE_HOOK EndOfFastBootModeChangeList;
+FastBootCheckModeChangeElink* FastBootModeChange[] = {FAST_BOOT_CHECK_MODE_CHANGE_HOOK NULL};
+ //<(EIP63924+)
+ //<(EIP62845+)
+typedef VOID (BeforeConnectFastBootDeviceElink)(); //(EIP85135+)
+extern BeforeConnectFastBootDeviceElink BEFORE_CONNECT_FAST_BOOT_DEVICE_HOOK EndOfBeforeConnectFastBootDeviceElink;
+BeforeConnectFastBootDeviceElink* BeforeConnectFastBootDeviceHook[] = {BEFORE_CONNECT_FAST_BOOT_DEVICE_HOOK NULL};
+ //<(EIP62845+)
+typedef VOID (ReturnNormalModeElink)();
+extern ReturnNormalModeElink RETURN_NORMAL_MODE_HOOK EndOfReturnNormalModeElink;
+ReturnNormalModeElink* ReturnNormalModeHook[] = {RETURN_NORMAL_MODE_HOOK NULL};
+FAST_BOOT_POLICY *gFastBootPolicy;
+BOOLEAN FBUsbSkipTableIsSet = FALSE;
+UINT8 *BackupSkipTable = NULL;
+
+EFI_USB_POLICY_PROTOCOL *gUsbPolicyProtocol = NULL;
+BOOLEAN BackupUsbMassDriverSupport;
+
+extern IS_VALID_FASTBOOT_BOOT_OPTION_FUNC_PTR IS_VALID_FASTBOOT_BOOT_OPTION_FUNC;
+IS_VALID_FASTBOOT_BOOT_OPTION_FUNC_PTR *IsValidFBBootOptionPtr = IS_VALID_FASTBOOT_BOOT_OPTION_FUNC;
+
+#if FASTBOOT_NEED_RESTART
+#define AMITSE_EVENT_BEFORE_BOOT_GUID \
+ { 0x3677770f, 0xefb2, 0x43b2, 0xb8, 0xae, 0xb3, 0x2, 0xe9, 0x60, 0x48, 0x82 }
+
+#define EFI_AMI_LEGACYBOOT_PROTOCOL_GUID \
+ {0x120d28aa, 0x6630, 0x46f0, 0x81, 0x57, 0xc0, 0xad, 0xc2, 0x38, 0x3b, 0xf5};
+
+EFI_GUID FBBeforeBootProtocolGuid = AMITSE_EVENT_BEFORE_BOOT_GUID;
+EFI_GUID FBBeforeLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+#endif
+
+//============================================================================
+// Function Definitions
+//============================================================================
+
+BOOLEAN CapsulePresent(VOID);
+VOID ReadyToBoot(UINT16 OptionNumber);
+
+VOID ConnectDevicePath(IN EFI_DEVICE_PATH_PROTOCOL *pPath);
+VOID InstallFwLoadFile(VOID);
+EFI_DEVICE_PATH_PROTOCOL* DiscoverPartition(
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+#ifdef EFI_DXE_PERFORMANCE
+VOID SavePerformanceData(IN EFI_EVENT Event, IN VOID *Context);
+#endif
+
+#if CORE_COMBINED_VERSION <= 0x40280 //Core 4.6.4.0
+#if SINGAL_ALL_DRIVERS_CONNECTED_EVENT
+extern VOID SignalProtocolEvent(IN EFI_GUID *ProtocolGuid);
+#endif
+#endif
+
+EFI_STATUS ConnectFastEfiBootDevice();
+EFI_STATUS ConnectFastLegacyBootDevice();
+
+EFI_STATUS ConnectAllSataDevices();
+EFI_STATUS ConnectHddDevices();
+EFI_STATUS ConnectLastHddDevice();
+
+//============================================================================
+// Procedures
+//============================================================================
+
+//<EIP118901+> 2013/06/21 >>>
+VOID BdsLoadStrings()
+{
+ EFI_STATUS Status;
+ EFI_HII_HANDLE HiiHandle = NULL;
+ Status = LoadStrings(TheImageHandle, &HiiHandle);
+}
+//<EIP118901+> 2013/06/21 >>>
+
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+ #else
+UINT8 ReadCMOS(
+ IN UINT8 Address
+)
+{
+ IoWrite8( (UINTN)CMOS_ADDR_PORT, Address );
+ return IoRead8( (UINTN)CMOS_DATA_PORT );
+}
+
+VOID WriteCMOS(
+ IN UINT8 Address,
+ IN UINT8 Data
+)
+{
+ IoWrite8( (UINTN)CMOS_ADDR_PORT, Address );
+ IoWrite8( (UINTN)CMOS_DATA_PORT, Data );
+}
+ #endif
+#endif
+
+
+VOID EnableLegacy16Fastboot()
+{
+#if AMILEGACY16_FASTBOOT_SOLUTION
+
+ UINT8 LastBootedIPLIndex=0;
+
+//clear the 7th bit of cmos index when fast boot is succeded.
+//so that int 19 would not update the cmos index on fast boot path
+//do this only if cmos index has a valid data (non 0xff value)
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+ CmosInterface->Read(
+ CmosInterface,
+ 0x38,//CMOS_FASTBOOT_INDEX_REG,
+ &LastBootedIPLIndex
+ );
+ #else
+ LastBootedIPLIndex = ReadCMOS( 0x38 );
+ #endif
+#endif
+
+ if (LastBootedIPLIndex != 0xff) {
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+ CmosInterface->Write(
+ CmosInterface,
+ 0x38,//CMOS_FASTBOOT_INDEX_REG,
+ LastBootedIPLIndex & 0x7f
+ );
+ #else
+ WriteCMOS( 0x38, LastBootedIPLIndex & 0x7F );
+ #endif
+#endif
+ }
+
+#endif //AMILEGACY16_FASTBOOT_SOLUTION
+}
+
+VOID DisableLegacy16Fastboot()
+{
+#if AMILEGACY16_FASTBOOT_SOLUTION
+
+ UINT8 LastBootedIPLIndex=0;
+
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+ CmosInterface->Read(
+ CmosInterface,
+ 0x38,//CMOS_FASTBOOT_INDEX_REG,
+ &LastBootedIPLIndex
+ );
+ #else
+ LastBootedIPLIndex = ReadCMOS( 0x38 );
+ #endif
+#endif
+
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+ CmosInterface->Write(
+ CmosInterface,
+ 0x38,
+ LastBootedIPLIndex|0x80
+ );
+ #else
+ WriteCMOS( 0x38, LastBootedIPLIndex | 0x80 );
+ #endif
+#endif
+
+#endif //AMILEGACY16_FASTBOOT_SOLUTION
+}
+
+#if CORE_COMBINED_VERSION <= 0x40280 //Core 4.6.4.0
+VOID CallDispatcherAgain()
+{
+ static EFI_GUID guidDXE = DXE_SERVICES_TABLE_GUID;
+ DXE_SERVICES *pDxe;
+ //before boot call dispatcher again.
+ pDxe = GetEfiConfigurationTable(pST,&guidDXE);
+ if (pDxe) pDxe->Dispatch();
+}
+#endif
+//
+// Connect Console realted Procedures ================>
+//
+EFI_DEVICE_PATH_PROTOCOL* FbAddDevicePath(
+ EFI_DEVICE_PATH_PROTOCOL *pDp1,
+ EFI_DEVICE_PATH_PROTOCOL *pDp2
+)
+{
+ if (!pDp2) return pDp1;
+ if (!pDp1)
+ {
+ return DPCopy(pDp2);
+ }
+ else
+ {
+ pDp2 = DPAddInstance(pDp1,pDp2);
+ pBS->FreePool(pDp1);
+ return pDp2;
+ }
+}
+
+EFI_STATUS FbGetPciHandlesByClass(
+ UINT8 Class,
+ UINT8 SubClass,
+ UINTN *NumberOfHandles,
+ EFI_HANDLE **HandleBuffer
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+
+ if (!NumberOfHandles || !HandleBuffer) return EFI_INVALID_PARAMETER;
+ //Get a list of all PCI devices
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciIoProtocolGuid2, NULL, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return Status;
+ *NumberOfHandles = 0;
+ for(i=0; i<Number; i++)
+ {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass[4];
+ Status=pBS->HandleProtocol(Handle[i],&gEfiPciIoProtocolGuid2,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32, PCI_REV_ID_OFFSET, 1, &PciClass);
+ if( PciClass[3]==Class && PciClass[2]==SubClass)
+ Handle[(*NumberOfHandles)++] = Handle[i];
+ }
+ if (*NumberOfHandles == 0){
+ pBS->FreePool(Handle);
+ return EFI_NOT_FOUND;
+ }
+ *HandleBuffer = Handle;
+ return EFI_SUCCESS;
+}
+
+
+VOID FbReportConnectConOutProgressCode()
+{
+ PROGRESS_CODE(DXE_CON_OUT_CONNECT);
+}
+
+VOID FbReportConnectConInProgressCode()
+{
+ PROGRESS_CODE(DXE_CON_IN_CONNECT);
+}
+
+
+VOID FbConnectVgaConOut()
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+ EFI_DEVICE_PATH_PROTOCOL *OnBoard=NULL, *OffBoard=NULL;
+ UINT64 PciAttributes;
+
+ //Get a list of all PCI devices
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciIoProtocolGuid2, NULL, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 PciClass;
+ Status=pBS->HandleProtocol(Handle[i],&gEfiPciIoProtocolGuid2,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+ if (EFI_ERROR(Status)) continue;
+ if (PciClass!=PCI_CL_DISPLAY) continue;
+ Status=pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&Dp);
+ if (EFI_ERROR(Status)) continue;
+ //We found Display adapter
+ // Check if this is on-board device
+ //(EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE is set).
+ Status = PciIo->Attributes(
+ PciIo, EfiPciIoAttributeOperationGet, 0, &PciAttributes
+ );
+ if ( !EFI_ERROR(Status)
+ && (PciAttributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE)
+ ) OnBoard = FbAddDevicePath(OnBoard,Dp);
+ else OffBoard = FbAddDevicePath(OffBoard,Dp);
+ }
+ pBS->FreePool(Handle);
+ //Offboard has a higher priority
+ OffBoard = FbAddDevicePath(OffBoard,OnBoard);
+ if (OffBoard)
+ {
+ ConnectDevicePath(OffBoard);
+ pBS->FreePool(OffBoard);
+ }
+}
+
+#if CSM_SUPPORT
+BOOLEAN FbInstallOnBoardVgaOpRom(
+ UINTN HdlNum,
+ EFI_HANDLE *pHandle,
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios,
+ BOOLEAN OnBoard
+)
+{
+ UINTN i;
+ EFI_STATUS Status;
+ UINT64 PciAttributes;
+ UINTN Flags;
+ UINT64 Capabilities;
+
+ for(i=0; i<HdlNum; i++) {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 PciClass;
+ Status=pBS->HandleProtocol(pHandle[i],&gEfiPciIoProtocolGuid2,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint8, 0xB, 1, &PciClass);
+ if (EFI_ERROR(Status)) continue;
+ if (PciClass!=PCI_CL_DISPLAY) continue;
+
+ Status=pBS->HandleProtocol(pHandle[i],&gEfiDevicePathProtocolGuid,&Dp);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = PciIo->Attributes(
+ PciIo, EfiPciIoAttributeOperationGet, 0, &PciAttributes
+ );
+
+ if ( !EFI_ERROR(Status) && (PciAttributes & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE) && OnBoard)
+ continue;
+
+ //(EIP75718)>
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ if (EFI_ERROR(Status)) continue;
+
+ Status = PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationEnable,
+ //Capabilities & EFI_PCI_DEVICE_ENABLE,
+ Capabilities & (EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO),
+ NULL); // Enable device
+ if (EFI_ERROR(Status)) goto done;
+
+
+ Status = LegacyBios->CheckPciRom ( LegacyBios,
+ pHandle[i],
+ NULL,
+ NULL,
+ &Flags);
+ if (EFI_ERROR(Status) || (Flags != 2)) goto done;
+
+ Status = LegacyBios->InstallPciRom (
+ LegacyBios,
+ pHandle[i],
+ NULL,
+ &Flags,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+ );
+
+done:
+ if (!EFI_ERROR(Status)) return TRUE;
+ else {
+
+ if (PciIo != NULL) {
+ //
+ // Turn off the PCI device and disable forwarding of VGA cycles to this device
+ //
+ PciIo->Attributes (
+ PciIo,
+ EfiPciIoAttributeOperationDisable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
+ NULL);
+ }
+ }
+ //<(EIP75718)
+ }
+ return FALSE;
+}
+#endif
+VOID FbInstallVgaOpRom()
+{
+#if CSM_SUPPORT
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number;
+ BOOLEAN VgaInstalled = FALSE;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+
+ //Locate LegacyBios Protocol
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ if (EFI_ERROR(Status)) return ;
+
+ //Get a list of all PCI devices
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciIoProtocolGuid2, NULL, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+
+
+ VgaInstalled = FbInstallOnBoardVgaOpRom(Number,Handle,LegacyBios,FALSE);
+ if (VgaInstalled == FALSE)
+ VgaInstalled = FbInstallOnBoardVgaOpRom(Number,Handle,LegacyBios,TRUE);
+
+ pBS->FreePool(Handle);
+
+ //If Legacy Vga OpRom is not installed successfully, then try to connect EFI VGA driver
+ if (VgaInstalled == FALSE)
+ FbConnectVgaConOut();
+#endif
+}
+
+
+VOID FbConnectPs2ConIn()
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+
+ //Get a list of all PCI to ISA Bridges
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_BRIDGE, PCI_CL_BRIDGE_SCL_ISA, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ EFI_DEVICE_PATH_PROTOCOL *Dp, *ChildDp;
+ ACPI_HID_DEVICE_PATH Ps2Kbd = {
+ {ACPI_DEVICE_PATH,ACPI_DP,sizeof(ACPI_HID_DEVICE_PATH)},
+ EISA_PNP_ID(0x303),0
+ };
+ ACPI_HID_DEVICE_PATH Ps2Mouse = {
+ {ACPI_DEVICE_PATH,ACPI_DP,sizeof(ACPI_HID_DEVICE_PATH)},
+ EISA_PNP_ID(0xF03),0
+ };
+ Status=pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&Dp);
+ if (EFI_ERROR(Status)) continue;
+ pBS->ConnectController(Handle[i],NULL,NULL,FALSE);
+ ChildDp=DPAddNode(Dp, &Ps2Kbd.Header);
+ ConnectDevicePath(ChildDp);
+ pBS->FreePool(ChildDp);
+ ChildDp=DPAddNode(Dp, &Ps2Mouse.Header);
+ ConnectDevicePath(ChildDp);
+ pBS->FreePool(ChildDp);
+ }
+ pBS->FreePool(Handle);
+
+}
+
+VOID FbConnectUsbConIn()
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+ //Get a list of all USB Controllers
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_SER_BUS, PCI_CL_SER_BUS_SCL_USB, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+ }
+ pBS->FreePool(Handle);
+}
+
+
+VOID FbConnecConsoleVariable(
+ CHAR16* ConVar
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *ConPath=NULL;
+ UINTN Size = 0;
+
+ if (EFI_ERROR(
+ GetEfiVariable(ConVar, &EfiVariableGuid, NULL, &Size, &ConPath)
+ )) return;
+
+ //Connect all active console devices
+ ConnectDevicePath(ConPath);
+ pBS->FreePool(ConPath);
+}
+
+VOID FbConnectConOutVariable()
+{
+ FbConnecConsoleVariable(L"ConOut");
+}
+
+VOID FbConnectConInVariable()
+{
+ FbConnecConsoleVariable(L"ConIn");
+}
+
+VOID FbInstallConsoleStartedProtocol(
+ CHAR16* ConDevVar,
+ EFI_GUID* ProtocolGuid
+)
+{
+ UINTN Size = 0;
+ VOID *Interface;
+
+ //Signal to Console Splitter that all console devices have been started
+ //if at least one console device exists (ConDev variable exists)
+ if (pRS->GetVariable(
+ ConDevVar, &EfiVariableGuid, NULL, &Size, NULL
+ ) == EFI_NOT_FOUND
+ ) return;
+ //if the protocol is already installed, return
+ if (!EFI_ERROR(pBS->LocateProtocol(ProtocolGuid, NULL, &Interface)))
+ return;
+ pBS->InstallProtocolInterface(
+ &TheImageHandle, ProtocolGuid, EFI_NATIVE_INTERFACE, NULL
+ );
+}
+
+
+VOID FbInstallConOutStartedProtocol()
+{
+ FbInstallConsoleStartedProtocol(L"ConOutDev", &FbConOutStartedProtocolGuid);
+}
+
+
+
+VOID FbInstallConInStartedProtocol()
+{
+ FbInstallConsoleStartedProtocol(L"ConInDev", &FbConInStartedProtocolGuid);
+}
+
+VOID InstallDummySimpleTextProtocol()
+{
+ EFI_STATUS Status;
+
+ if (pST->ConOut== NULL)
+ {
+ TRACE((-1,"FB:Install Dummy ConOut\n"));
+
+ Status = pBS->InstallProtocolInterface(&gDummyConOutHdl,
+ &gSimpleTextOutProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &DummySimpleOutProtocol);
+ if (!EFI_ERROR(Status))
+ pST->ConOut= &DummySimpleOutProtocol;
+ }
+
+
+ if (pST->ConIn == NULL)
+ {
+ TRACE((-1,"FB:Install Dummy ConIn\n"));
+
+ Status = pBS->InstallProtocolInterface(&gDummyConInHdl,
+ &gSimpleTextInProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &DummySimpleInProtocol);
+ if (!EFI_ERROR(Status))
+ pST->ConIn = &DummySimpleInProtocol;
+ }
+}
+
+VOID UnInstallDummySimpleTextProtocol()
+{
+ if (gDummyConOutHdl!=NULL)
+ {
+ pBS->UninstallProtocolInterface(gDummyConOutHdl,
+ &gSimpleTextOutProtocolGuid,
+ &DummySimpleOutProtocol);
+ pST->ConOut = 0;
+
+ }
+
+ if (gDummyConInHdl!=NULL)
+ {
+ pBS->UninstallProtocolInterface(gDummyConInHdl,
+ &gSimpleTextInProtocolGuid,
+ &DummySimpleInProtocol);
+ pST->ConIn = 0;
+ }
+}
+ //(EIP85135+)>
+BOOLEAN IsRootBridgeHandle(EFI_HANDLE Handle)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ EFI_GUID PciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if(EFI_ERROR(Status)) return FALSE;
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &PciRootBridgeIoProtocolGuid,
+ &PciRootBridgeIo
+ );
+ if(EFI_ERROR(Status)) return FALSE;
+
+ return TRUE;
+
+}
+
+
+VOID ConnectEveryPciHandles()
+{
+ EFI_STATUS Status;
+ UINTN Number;
+ EFI_HANDLE *Handle;
+ UINTN i,j;
+ SKIP_PCI_LIST *SkipPciList = gFastBootPolicy->SkipPciList;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiPciIoProtocolGuid2, NULL, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+
+ for(i=0; i<Number; i++)
+ {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT8 PciClass[4];
+ Status=pBS->HandleProtocol(Handle[i],&gEfiPciIoProtocolGuid2,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint32, PCI_REV_ID_OFFSET, 1, &PciClass);
+
+ //check skip table
+ for (j=0;j<(gFastBootPolicy->SkipPciListSize/(sizeof(SKIP_PCI_LIST)));j++) {
+
+ if (SkipPciList[j].SubClass == 0xFF && PciClass[3] == SkipPciList[j].Class)
+ break;
+
+ if (PciClass[3] == SkipPciList[j].Class && PciClass[2] == SkipPciList[j].SubClass)
+ break;
+ }
+ if (j<(gFastBootPolicy->SkipPciListSize/(sizeof(SKIP_PCI_LIST))))
+ continue;
+
+ //check fastboot policy
+ if (gFastBootPolicy->UsbSupport == 0 && PciClass[3] == PCI_CL_SER_BUS && PciClass[2] == PCI_CL_SER_BUS_SCL_USB)
+ continue;
+
+ if(PciClass[3] == PCI_CL_NETWORK && gFastBootPolicy->NetWorkStackSupport == 0) {
+ pBS->ConnectController(Handle[i],NULL,NULL,FALSE);
+ continue;
+ }
+
+
+ //all pass, then we connect this controller
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+
+ }
+
+ pBS->FreePool(Handle);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FbConnectEverything
+//
+// Description:
+// This function connects all PCI handles excpet PCI devices in
+// FAST_BOOT_PCI_SKIP_LIST
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FbConnectEverything()
+{
+ UINTN i;
+
+ for(i=0; i<NumberOfHandles; i++) {
+ if(IsRootBridgeHandle(RootHandles[i]))
+ ConnectEveryPciHandles();
+ else
+ pBS->ConnectController(RootHandles[i],NULL,NULL,TRUE);
+ }
+
+ pBS->FreePool(RootHandles);
+
+// Signal it anyway for Consplitter to take care the ConIn/ConOut
+// after everything is connected
+ FbInstallConsoleStartedProtocol(NULL, &FbConOutStartedProtocolGuid);
+ FbInstallConsoleStartedProtocol(NULL, &FbConInStartedProtocolGuid);
+}
+
+VOID BeforeBDSFlow()
+{
+ pBS->LocateHandleBuffer(AllHandles, NULL, NULL, &NumberOfHandles, &RootHandles);
+}
+
+ //<(EIP85135+)
+#if CORE_COMBINED_VERSION <= 0x40280 //Core 4.6.4.0
+VOID FbAllDriverConnect()
+{
+#if CALL_DISPATCHER_AGAIN_IN_FASTBOOT
+ TRACE((-1,"FB: Call dispatcher again\n"));
+ CallDispatcherAgain();
+#endif
+
+#if SINGAL_ALL_DRIVERS_CONNECTED_EVENT
+ SignalProtocolEvent(&FbBdsAllDriversConnectedProtocolGuid);
+#endif
+
+}
+#endif
+
+ //(EIP85135+)>
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 920)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetUsbSkipTable
+//
+// Description:
+// Skip all usb port in fastboot path by setting skip table in usb protocol.
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetUsbSkipTable()
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID gEfiUsbProtocolGuid = EFI_USB_PROTOCOL_GUID;
+ EFI_USB_PROTOCOL *UsbProtocol = NULL;
+ USB_GLOBAL_DATA *UsbData = NULL;
+
+ Status = pBS->LocateProtocol( &gEfiUsbProtocolGuid, \
+ NULL, \
+ &UsbProtocol );
+ if (EFI_ERROR(Status)) return;
+
+//backup skip table pointer
+ UsbData = (USB_GLOBAL_DATA*)UsbProtocol->USBDataPtr;
+
+ BackupSkipTable = UsbData->gUsbSkipListTable;
+
+//Set new skip table
+ UsbProtocol->UsbCopySkipTable( \
+ (USB_SKIP_LIST*)gFastBootPolicy->UsbSkipTable, \
+ (UINT8)gFastBootPolicy->UsbSkipTableSize);
+
+}
+#endif
+ //<(EIP85135+)
+ //(EIP63924)>
+VOID FastConnectConsoles()
+{
+ TRACE((-1,"FB:Connect Console...\n"));
+
+ // Connect Console Out
+ FbReportConnectConOutProgressCode();
+
+ PERF_START(0, L"ConnectVgaConOut", L"FB", 0);
+ if (gFastBootPolicy->VGASupport || gFastBootPolicy->UEfiBoot == TRUE){
+ TRACE((-1,"FB:Connect Vga\n"));
+ FbConnectVgaConOut();
+ } else {
+ TRACE((-1,"FB:Install Vga OpRom Only\n"));
+ FbInstallVgaOpRom();
+ }
+
+ PERF_END(0,L"ConnectVgaConOut",L"FB",0);
+ PERF_START(0,L"InstallConOutStartedProtocol",L"FB",0);
+ FbInstallConOutStartedProtocol();
+ PERF_END(0,L"InstallConOutStartedProtocol",L"FB",0);
+
+ // Connect Console In
+ FbReportConnectConInProgressCode();
+
+ PERF_START(0, L"ConnectUsbConIn", L"FB" , 0);
+ //(EIP85135)>
+ if (gFastBootPolicy->UsbSupport >= 1){
+
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 920)
+ if (gFastBootPolicy->UsbSupport == 2){
+
+ //Disable Usb storage driver support
+ pBS->LocateProtocol(&gUsbPolicyGuid, NULL, &gUsbPolicyProtocol);
+ if (gUsbPolicyProtocol != NULL) {
+ BackupUsbMassDriverSupport = gUsbPolicyProtocol->UsbDevPlcy->UsbMassDriverSupport;
+ gUsbPolicyProtocol->UsbDevPlcy->UsbMassDriverSupport = FALSE;
+ }
+
+
+ TRACE((-1,"FB:Set Usb Skip Table\n"));
+ FBUsbSkipTableIsSet = TRUE;
+ SetUsbSkipTable();
+ }
+#endif
+ TRACE((-1,"FB:Connect Usb\n"));
+ FbConnectUsbConIn();
+ }
+ PERF_END(0, L"ConnectUsbConIn", L"FB", 0);
+ //<(EIP85135)
+ PERF_START(0, L"ConnectPs2ConIn", L"FB", 0);
+ if (gFastBootPolicy->Ps2Support){
+ TRACE((-1,"FB:Connect Ps2\n"));
+ FbConnectPs2ConIn();
+ }
+ PERF_END(0, L"ConnectPs2ConIn", L"FB", 0);
+
+ PERF_START(0, L"InstallConInStartedProtocol",L"FB", 0);
+ FbInstallConInStartedProtocol();
+ PERF_END(0, L"InstallConInStartedProtocol", L"FB", 0);
+ // Install Dumy protocol, if ConIn/ConOut is Null
+ TRACE((-1,"FB:Connect Console...End\n"));
+}
+ //<(EIP63924)
+//
+// <============= Connect Console realted Procedures
+//
+#if FASTBOOT_NEED_RESTART
+VOID ResetForFastboot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ pRS->ResetSystem(EfiResetCold,0,0,NULL);
+}
+
+FastBootEnableRestart(
+ UINTN Flag,
+ UINTN Count )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+ VOID *Registration;
+
+ TRACE((-1,"FB:Normal boot need to restart.\n"));
+ RegisterProtocolCallback(
+ &FBBeforeBootProtocolGuid,
+ ResetForFastboot,
+ NULL, &Event, &Registration
+ );
+ RegisterProtocolCallback(
+ &FBBeforeLegacyBootProtocolGuid,
+ ResetForFastboot,
+ NULL, &Event, &Registration
+ );
+
+ Status = pRS->SetVariable(FAST_BOOT_RESTART,
+ &FastbootRestartGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(Flag),
+ &Flag);
+ Status = pRS->SetVariable(FAST_BOOT_RESTART_COUNT,
+ &FastbootRestartCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(Count),
+ &Count);
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBoot
+//
+// Description: FastBoot entry point
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBoot(VOID)
+{
+ //(EIP63924+)>
+ EFI_STATUS Status;
+ EFI_GUID FastBootTseGuid = FAST_BOOT_TSE_PROTOCOL_GUID;
+
+ Status = pBS->LocateProtocol(&FastBootTseGuid, NULL, &gFastBootTseProtocol);
+ if (EFI_ERROR(Status)) return;
+ //<(EIP63924+)
+ gFastBootPolicy->InFastBootPath = TRUE;
+ FastBootWorker();
+
+//if we're here - fast boot failed
+ ReturnToNormalBoot();
+ gFastBootPolicy->InFastBootPath = FALSE;
+ TRACE((-1,"FB: FastBoot Failure, return to BDS\n"));
+}
+
+VOID RemoveFilePathNode(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp)
+{
+ EFI_DEVICE_PATH_PROTOCOL *FileDpNode = NULL;
+ UINTN FileDpNodeSize;
+ EFI_DEVICE_PATH_PROTOCOL *TempDp = Dp;
+ UINTN DpSize = DPLength(Dp);
+ UINTN RemainingDpLength=0;
+ UINT8 ReaminingDpBuffer[100];
+
+ for( ; !(isEndNode(TempDp)); TempDp = NEXT_NODE(TempDp)) {
+ if(TempDp->Type == MEDIA_DEVICE_PATH &&
+ TempDp->SubType == MEDIA_FILEPATH_DP) {
+ FileDpNode = TempDp;
+ break;
+ }
+ }
+
+ if (FileDpNode == NULL) return;
+
+ RemainingDpLength = DPLength(FileDpNode);
+ FileDpNodeSize = NODE_LENGTH(FileDpNode);
+
+ pBS->SetMem(ReaminingDpBuffer,100,0);
+
+ pBS->CopyMem(ReaminingDpBuffer,FileDpNode,RemainingDpLength);
+
+ pBS->SetMem(FileDpNode,RemainingDpLength,0);
+
+ pBS->CopyMem(FileDpNode,
+ (VOID*)((UINTN)ReaminingDpBuffer+FileDpNodeSize),
+ RemainingDpLength - FileDpNodeSize);
+}
+
+#ifdef EFI_DXE_PERFORMANCE
+VOID UpdatePolicyForTestMode()
+{
+ BOOLEAN UsbMassStorage = FALSE;
+ BOOLEAN HddFilePath = FALSE;
+ EFI_DEVICE_PATH_PROTOCOL *Dp = gFastBootPolicy->FastBootOption;
+ EFI_DEVICE_PATH_PROTOCOL *NewDp=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *TempDp=NULL;
+ UINTN NewDpSize;
+ UINT32 LoadOptionsSize = 0;
+ VOID *LoadOptions;
+ EFI_STATUS Status;
+
+ if(gFastBootPolicy->TestMode == FALSE || gFastBootPolicy->UEfiBoot == FALSE) return;
+
+ if(!IsSupportedDevice(gFastBootPolicy->FastBootOption, &UsbMassStorage,&HddFilePath))
+ return;
+
+ LoadOptions = (UINT8*)Dp + DPLength(Dp);
+ LoadOptionsSize = *(UINT32*)LoadOptions;
+
+ NewDpSize = DPLength(Dp)+ LoadOptionsSize+ sizeof(UINT32)+ \
+ NODE_LENGTH(&TestFilePathNode.Header);
+
+ Status = pBS->AllocatePool(EfiBootServicesData,NewDpSize,&NewDp);
+ if(EFI_ERROR(Status)) return;
+
+ pBS->SetMem(NewDp,NewDpSize,0);
+ pBS->CopyMem(NewDp,Dp,DPLength(Dp));
+
+ //Replace file path from "efi\boot\" to "efi\dp\"
+ RemoveFilePathNode(NewDp);
+ TempDp = DPAddNode(NewDp, &TestFilePathNode.Header);
+
+ pBS->CopyMem(NewDp,TempDp,DPLength(TempDp));
+
+ //Copy optional data
+ pBS->CopyMem( (VOID*)((UINTN)NewDp+DPLength(NewDp)),
+ LoadOptions,
+ LoadOptionsSize+sizeof(UINT32));
+
+
+ gFastBootPolicy->FastBootOption = NewDp;
+ pBS->FreePool(TempDp);
+
+ gFastBootPolicy->CheckBootOptionNumber = FALSE;
+
+}
+#endif
+
+VOID ShowFastBootPolicy()
+{
+ EFI_DEVICE_PATH_PROTOCOL *Dp = gFastBootPolicy->FastBootOption;
+ UINTN FastBootOptionSize=0;
+ VOID *LoadOptions;
+ UINT32 LoadOptionsSize = 0;
+ UINT8 *ptr8=NULL;
+ SKIP_PCI_LIST *PciSkipList=NULL;
+#if SUPPORT_RAID_DRIVER
+ SATA_DEVICE_DATA *SataDevice=NULL;
+#endif
+ UINTN i,j;
+ USB_SKIP_LIST *usbskip = NULL; //(EIP96276.7)+
+
+ TRACE((-1,"FB: ==================================================\n"));
+ TRACE((-1,"FB: FastBootPolicy->FastBootEnable = %x\n",gFastBootPolicy->FastBootEnable));
+ TRACE((-1,"FB: FastBootPolicy->TestMode = %x\n",gFastBootPolicy->TestMode));
+
+ TRACE((-1,"FB: FastBootPolicy->UEfiBoot = %x\n",gFastBootPolicy->UEfiBoot));
+ TRACE((-1,"FB: FastBootPolicy->BootOptionNumber = %x\n",gFastBootPolicy->BootOptionNumber));
+ TRACE((-1,"FB: FastBootPolicy->DevStrCheckSum = %x\n",gFastBootPolicy->DevStrCheckSum));
+
+ FastBootOptionSize = DPLength(Dp);
+ if (gFastBootPolicy->UEfiBoot) {
+ LoadOptions = (UINT8*)Dp + DPLength(Dp);
+ LoadOptionsSize = *(UINT32*)LoadOptions;
+ FastBootOptionSize += LoadOptionsSize+sizeof(UINT32);
+ }
+
+ TRACE((-1,"FB: FastBootPolicy->FastBootOption\n"));
+ ptr8=(UINT8*)Dp;
+ for (i=0;i<FastBootOptionSize;)
+ {
+ for(j=0;j<0x10 && i<FastBootOptionSize;j++)
+ {
+ TRACE((-1,"%02X ",ptr8[i]));
+ i++;
+ }
+ TRACE((-1," \n"));
+ }
+
+ TRACE((-1,"FB: FastBootPolicy->LastBootFailure = %x\n",gFastBootPolicy->LastBootFailure));
+ TRACE((-1,"FB: FastBootPolicy->LastBootVarPresence = %x\n",gFastBootPolicy->LastBootVarPresence));
+ TRACE((-1,"FB: FastBootPolicy->BootCount = %x\n",gFastBootPolicy->BootCount));
+
+#if SUPPORT_RAID_DRIVER
+ SataDevice = gFastBootPolicy->SataDevice;
+ for(i=0;i<MAX_SATA_DEVICE_COUNT && SataDevice[i].BDF!=0;i++)
+ {
+
+ TRACE((-1,"FB: FastBootPolicy->SataDevice[%d],n",i));
+
+ TRACE((-1,"BDF:%x, CalssCode:%x, DveType:%x, PortNum:%x\n",\
+ SataDevice[i].BDF,\
+ SataDevice[i].ClassCode,\
+ SataDevice[i].DevType,\
+ SataDevice[i].PortNum));
+
+ TRACE((-1,"Serial Number: "));
+
+ for(j=0;j<20;j++)
+ {
+ TRACE((-1,"%02X ",SataDevice[i].SerialNum[j]));
+ }
+ TRACE((-1," \n"));
+ }
+#endif
+
+ TRACE((-1,"FB: FastBootPolicy->CheckBootOptionNumber = %x\n",gFastBootPolicy->CheckBootOptionNumber));
+ TRACE((-1,"FB: FastBootPolicy->CheckDevStrCheckSum = %x\n",gFastBootPolicy->CheckDevStrCheckSum));
+ TRACE((-1,"FB: FastBootPolicy->SataSupport = %x\n",gFastBootPolicy->SataSupport));
+ TRACE((-1,"FB: FastBootPolicy->VGASupport = %x\n",gFastBootPolicy->VGASupport));
+ TRACE((-1,"FB: FastBootPolicy->UsbSupport = %x\n",gFastBootPolicy->UsbSupport));
+
+ //(EIP96276.7)>
+ usbskip = gFastBootPolicy->UsbSkipTable;
+ for (i = 0; i < gFastBootPolicy->UsbSkipTableSize; i++)
+ {
+ TRACE((-1,"FB: FastBootPolicy->UsbSkipTable[%d] = {%02X,%02X,%04X,%02X,%08X,%02X}\n",i,usbskip->bSkipType,usbskip->bFlag,usbskip->wBDF,usbskip->bRootPort,usbskip->dRoutePath,usbskip->bBaseClass));
+ usbskip++;
+ }
+ //<(EIP96276.7)
+
+ TRACE((-1,"FB: FastBootPolicy->Ps2Support = %x\n",gFastBootPolicy->Ps2Support));
+ TRACE((-1,"FB: FastBootPolicy->NetWorkStackSupport = %x\n",gFastBootPolicy->NetWorkStackSupport));
+
+ for (i=0,PciSkipList = gFastBootPolicy->SkipPciList;i<gFastBootPolicy->SkipPciListSize/sizeof(SKIP_PCI_LIST);i++)
+ TRACE((-1,"FB: FastBootPolicy->SkipPciList[%d] = Class:%x,SubClass:%x\n",i,PciSkipList[i].Class,PciSkipList[i].SubClass));
+
+ TRACE((-1,"FB: FastBootPolicy->CheckPassword = %x\n",gFastBootPolicy->CheckPassword));
+
+ TRACE((-1,"FB: FastBootPolicy->SkipTSEHandshake = %x\n",gFastBootPolicy->SkipTSEHandshake));
+
+ TRACE((-1,"FB: ==================================================\n"));
+
+}
+ //(EIP96276.4)>>
+BOOLEAN IsValidFastBootOption(
+ IN UINTN BootOrderIndex,
+ IN EFI_LOAD_OPTION *BootOption)
+{
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ CHAR16 *Description;
+ CHAR16 *gWindowsBootManagerStr = L"Windows Boot Manager";
+ BOOLEAN LegacyType = FALSE;
+ BOOLEAN UsbDevice = FALSE;
+ BOOLEAN HardDrive = FALSE;
+ BOOLEAN CDROM = FALSE;
+ BOOLEAN NetWork = FALSE;
+ BOOLEAN WindowsBootManager = FALSE;
+
+//check attribute
+
+ if (!(BootOption->Attributes & LOAD_OPTION_ACTIVE)) return FALSE;
+
+//check windows boot manager
+
+ Description = (CHAR16 *)(BootOption + 1);
+ if(!MemCmp(gWindowsBootManagerStr,Description,Strlen((char*)gWindowsBootManagerStr)))
+ WindowsBootManager = TRUE;
+
+//check device type
+
+ Dp = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8*)Description + (Wcslen(Description) + 1) * sizeof(CHAR16));
+
+ for( ; !(isEndNode(Dp)); Dp = NEXT_NODE(Dp)) {
+ if(Dp->Type == BBS_DEVICE_PATH) LegacyType = TRUE;
+
+ if(Dp->Type == MESSAGING_DEVICE_PATH && Dp->SubType == MSG_USB_DP)
+ UsbDevice = TRUE;
+
+ if(Dp->Type == MESSAGING_DEVICE_PATH && Dp->SubType == MSG_MAC_ADDR_DP)
+ NetWork = TRUE;
+
+ if(Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_HARDDRIVE_DP)
+ HardDrive = TRUE;
+
+ if(Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_CDROM_DP)
+ CDROM = TRUE;
+ }
+
+ TRACE((-1,"FB: BootOrder Index %x\n",BootOrderIndex));
+ TRACE((-1,"FB: Windows Boot Manager: %x\n",WindowsBootManager));
+ TRACE((-1,"FB: Legacy %x,Usb %x, HardDrive %x, CDROM %x, NetWork %x\n", \
+ LegacyType,UsbDevice,HardDrive,CDROM,NetWork));
+
+// there is some samples for selecting a boot option as fast boot device.
+/*
+//Case 1. Fast boot with windows boot manager and it's the highest priority in boot order.
+ if(BootOrderIndex == 0 && WindowsBootManager == 1) return TRUE;
+
+//Case 2. don't support Legacy device
+ if(LegacyType == TRUE) return FALSE;
+
+//Case3. don't support usb type
+ if(UsbDevice == TRUE) return FALSE;
+*/
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsOneOfDP
+//
+// Description: Determines whether a device path, pAll, contains another
+// device path, pOne.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *pAll - The device path to be scanned.
+// IN EFI_DEVICE_PATH_PROTOCOL *pOne - The device path to locate within pAll.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsOneOfDP(
+ IN EFI_DEVICE_PATH_PROTOCOL *pAll,
+ IN EFI_DEVICE_PATH_PROTOCOL *pOne
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *pPath;
+
+ pPath = pOne;
+
+ do{
+ if (isEndNode(pAll)) return FALSE;
+
+ if (DPLength(pAll) < DPLength(pOne)) return FALSE;
+
+ if(!(pAll->Type == pPath->Type && pAll->SubType == pPath->SubType))
+ {
+ pAll = NEXT_NODE(pAll);
+ continue;
+ }
+
+ if (!MemCmp(pAll,pOne,DPLength(pOne)))
+ return TRUE;
+ else
+ pAll = NEXT_NODE(pAll);
+
+ }while(TRUE);
+
+}
+ //<<(EIP96276.4)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindDevicePath
+//
+// Description: Search DevicePath and find out indicated device path node.
+//
+// Input:
+// IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath - Searched device path
+// IN UINT8 Type - Indicated device path type
+// IN UINT8 SubType - Indicated device path sub type
+//
+// Output: EFI_DEVICE_PATH_PROTOCOL - return indicated device path
+// pointer otherwise NULL.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_DEVICE_PATH_PROTOCOL*
+FindDevicePath (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINT8 Type,
+ IN UINT8 SubType
+)
+{
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ while (!isEndNode (DevicePath)) {
+ if (DevicePath->Type == Type && DevicePath->SubType== SubType)
+ return DevicePath;
+
+ DevicePath = NEXT_NODE (DevicePath);
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastConnectSata
+//
+// Description: Connect Sata controller in fast boot path.
+//
+// Input:
+// None
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FastConnectSata()
+{
+
+ TRACE((-1,"FB:Connect Sata\n"));
+
+ switch(gFastBootPolicy->SataSupport)
+ {
+ case 0: // only connect previous boot HDD?
+ return ConnectLastHddDevice();
+ case 1: // connect all sata device
+ ConnectAllSataDevices();
+ break;
+#if SUPPORT_RAID_DRIVER
+ case 2: // only connect HDDs, ODD & Port Multiplier will be skipped.
+ return ConnectHddDevices();
+#endif
+ }
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootWorker
+//
+// Description: FastBoot main function
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBootWorker(VOID)
+{
+ EFI_EVENT FastBootReadyToBootEvent;
+ CHAR16 BootOptionName[9];
+ EFI_LOAD_OPTION *BootOption = NULL;
+ UINTN Size;
+ EFI_STATUS Status;
+ UINT16 *BootOrder = NULL;
+ UINT32 BootFlow;
+ UINT8 i; //(EIP62683+)
+ BOOLEAN VaildBootOption = FALSE;
+ UINTN BootOptionSize; //(EIP96276.4+)
+#if FASTBOOT_NEED_RESTART
+ UINTN Flag = 1;
+ UINTN Count = 0;
+#endif
+
+ TRACE((-1, "FB: FastBoot started\n"));
+ Size = sizeof(BootFlow);
+ Status = pRS->GetVariable(L"BootFlow", &guidBootFlow, NULL, &Size, (VOID *)&BootFlow);
+ if(!EFI_ERROR(Status) && (BootFlow != BOOT_FLOW_CONDITION_NORMAL)) {
+ // Some other driver wants different bootflow - abandon fast boot.
+#if FASTBOOT_NEED_RESTART
+ TRACE((-1,"FB : Normal boot need to notify.\n"));
+ //Initial Reboot Flag
+ Status = pRS->SetVariable(FAST_BOOT_RESTART,
+ &FastbootRestartGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(Flag),
+ &Flag);
+ Status = pRS->SetVariable(FAST_BOOT_RESTART_COUNT,
+ &FastbootRestartCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(Count),
+ &Count);
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK,
+ FastBootReadyToBootNotify,
+ NULL,
+ &FastBootReadyToBootEvent);
+#endif
+ return;
+ }
+ PERF_START(0, L"FastBoot", L"FB", 0);
+
+#if CAPSULE_SUPPORT
+ if(CapsulePresent())
+ return;
+#endif
+
+ if(OemConfigurationChanged())
+ return;
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK,
+ FastBootReadyToBootNotify,
+ NULL,
+ &FastBootReadyToBootEvent);
+ if (EFI_ERROR(Status))
+ return;
+
+ if (!gFastBootPolicy->LastBootVarPresence) return;
+
+#ifdef EFI_DXE_PERFORMANCE
+ UpdatePolicyForTestMode();
+#endif
+
+ ShowFastBootPolicy();
+
+ if (gFastBootPolicy->CheckBootOptionNumber) {
+
+ Size = 0;
+ Status = GetEfiVariable(L"BootOrder", &EfiVariableGuid, NULL, &Size, &BootOrder);
+
+ for (i=0;i<Size/sizeof(UINT16);i++,BootOption = NULL) { //(EIP96276.4)
+
+ Swprintf(BootOptionName, gBootName, BootOrder[i]);
+ Status = GetEfiVariable(BootOptionName, &EfiVariableGuid, NULL, &BootOptionSize, &BootOption);//(EIP96276.4)
+ if(EFI_ERROR(Status))
+ return;
+
+ VaildBootOption = IsValidFBBootOptionPtr(i,BootOption);
+ if (VaildBootOption) break;
+
+ pBS->FreePool(BootOption);
+
+ if (VaildBootOption == FALSE && i == (Size/sizeof(UINT16) -1 )) {
+ TRACE((-1, "FB: There is no valid boot option\n"));
+ pBS->FreePool(BootOrder);
+ return;
+
+ }
+ }
+
+ TRACE((-1, "FB: LastBootOption=%x, BootOrder[%d]=%x\n",gFastBootPolicy->BootOptionNumber,i,BootOrder[i]));
+
+ if(gFastBootPolicy->BootOptionNumber != BootOrder[i])
+ {
+ //
+ // BootOption Number check fail, then check device path.
+ // If device path is also wrong, abort the fast boot.
+ //
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ CHAR16 *Description;
+ Description = (CHAR16 *)(BootOption + 1);
+ Dp = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8*)Description + (Wcslen(Description) + 1) * sizeof(CHAR16));
+
+ if(!IsOneOfDP(gFastBootPolicy->FastBootOption,Dp)) {
+ pBS->FreePool(BootOrder);
+ pBS->FreePool(BootOption);
+ return;
+ }
+
+ TRACE((-1,"FB: Update new boot option number\n"));
+ gFastBootPolicy->BootOptionNumber = BootOrder[i];
+ }
+
+ pBS->FreePool(BootOrder);
+ pBS->FreePool(BootOption);
+ }
+
+
+ PERF_START(0,L"FastBootConnectConsole",L"FB" ,0);
+ FastConnectConsoles();
+ PERF_END(0,L"FastBootConnectConsole",L"FB",0);
+
+//<EIP118901+> 2013/06/21 >>>
+ BdsLoadStrings();
+//<EIP118901+> 2013/06/21 <<<
+
+ PERF_START(0,L"BeforeConnectFbDevElink",L"FB",0);
+ //(EIP62683+)>
+ // before all driver connect elink
+ for (i=0;BeforeConnectFastBootDeviceHook[i]; i++)
+ BeforeConnectFastBootDeviceHook[i](); //(EIP85135)
+
+ //<(EIP62683+)
+ PERF_END(0,L"BeforeConnectFbDevElink",L"FB",0);
+ Status = FastConnectSata();
+ if (EFI_ERROR(Status)) return;
+
+ PERF_START(0,L"ConnectFbDev",L"FB",0);
+ if(gFastBootPolicy->UEfiBoot == TRUE)
+ Status = ConnectFastEfiBootDevice();
+ else
+ Status = ConnectFastLegacyBootDevice();
+ PERF_END(0,L"FB",L"ConnectFbDev",0);
+
+ if(EFI_ERROR(Status)) return;
+
+
+ //(EIP62683+)>
+ PERF_START(0,L"AfterConnectFbDevElink",L"FB",0);
+ // after all driver connect elink
+ for (i=0;AfterAllDriverConnectList[i]; i++)
+ AfterAllDriverConnectList[i]();
+ PERF_END(0,L"AfterConnectFbDevElink",L"FB",0);
+ //<(EIP62683+)
+
+
+#if CORE_COMBINED_VERSION <= 0x40280 //Core 4.6.4.0
+ FbAllDriverConnect();
+#endif
+
+ if((gFastBootPolicy->SkipTSEHandshake == 0) && (TSE_MAJOR >= 0x02) && (TSE_MINOR >= 0x10)) {
+ PERF_START(0,L"TSE",L"FB",0);
+ Status = TseHandShake();
+ if(Status == EFI_ABORTED) //fast boot failed, proceed to full boot
+ return;
+ }
+
+ //(EIP63924+)>
+//Stop CheckForKey callback timer in TSE
+ gFastBootTseProtocol->FastBootStopCheckForKeyTimer();
+ //<(EIP63924+)
+//if we are here, somehow we failed launch fast boot through TSE - do it on our own
+
+ if(gFastBootPolicy->UEfiBoot == TRUE)
+ FastEfiBoot();
+ else
+ FastLegacyBoot();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsBootToShell
+//
+// Description: Function to determine if the boot path is to UEFI Shell
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp - pointer to device path of bootable device
+//
+// Output: TRUE - if it's UEFI Shell boot path, FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsBootToShell(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ if(Dp->Type == MEDIA_DEVICE_PATH &&
+ Dp->SubType == MEDIA_VENDOR_DP &&
+ !guidcmp(&(((VENDOR_DEVICE_PATH *)Dp)->Guid), &AmiMediaDevicePathGuid))
+ return TRUE;
+
+ return FALSE;
+}
+ //(EIP63924+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPostManagerKey
+//
+// Description: Check TSE Post key is pressed or not.
+//
+// Input: None
+//
+// Output: TRUE - Post key is pressed
+// FALSE - Post key is not pressed
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckPostManagerKey()
+{
+ EFI_STATUS CheckForKeyStatus;
+ BOOLEAN EnterSetup;
+ UINT32 BootFlow;
+
+ CheckForKeyStatus = gFastBootTseProtocol->FastBootCheckForKey(&EnterSetup,&BootFlow);
+ if(CheckForKeyStatus == EFI_SUCCESS) return TRUE;
+ return FALSE;
+}
+ //<(EIP63924+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckConnectedHdd
+//
+// Description: Check connected Hdds are as same as previous boot's.
+//
+// Input:
+// IN UINT16 BDF - BDF of previous boot's Hdd
+// IN UINT16 ClassCode - Class of previous boot's Hdd
+// IN UINT8 PortNum - Port Number of previous boot's Hdd
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if SUPPORT_RAID_DRIVER
+EFI_STATUS
+CheckConnectedHdd(
+ IN UINT16 BDF,
+ IN UINT16 ClassCode,
+ IN UINT8 PortNum
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID DiskInfoGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_GUID DiskInfoIdeGuid = EFI_DISK_INFO_IDE_INTERFACE_GUID;
+ EFI_GUID DiskInfoAhciGuid = EFI_DISK_INFO_AHCI_INTERFACE_GUID;
+ EFI_DISK_INFO_PROTOCOL *DiskInfoProtocol;
+ EFI_HANDLE *Handle;
+ UINTN Count;
+ UINTN PciSeg,PciBus,PciDev,PciFun;
+ UINT16 DetectedHddBDF;
+ UINT16 DetectedHddClassCode;
+ UINT8 DetectedHddPortNum;
+ UINT8 *DetectedHddSerialNum = NULL;
+ BOOLEAN StrucFound = FALSE;
+ UINT8 i;
+ SATA_DEVICE_DATA *SataDevice = (SATA_DEVICE_DATA*)gFastBootPolicy->SataDevice;
+
+//
+// Find out sata device structure the from last boot stat devcie list
+//
+ for (i=0;i<MAX_SATA_DEVICE_COUNT && SataDevice->BDF!=0;SataDevice++) {
+ if (BDF == SataDevice->BDF &&\
+ ClassCode == SataDevice->ClassCode &&\
+ PortNum == SataDevice->PortNum)
+ {
+ StrucFound = TRUE;
+ break;
+ }
+ }
+ if (StrucFound == FALSE) return EFI_NOT_FOUND;
+
+//
+// Find out serial number of detected Hdd.
+//
+
+ Status=pBS->LocateHandleBuffer(ByProtocol,&DiskInfoGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return Status;
+
+ for(i=0;i<Count;i++)
+ {
+ Status=pBS->HandleProtocol(Handle[i],&DiskInfoGuid,(VOID**)&DiskInfoProtocol);
+ if(EFI_ERROR(Status)) continue;
+
+ if(!guidcmp(&DiskInfoProtocol->Interface,&DiskInfoIdeGuid)) {
+ //
+ // Ide diskInfo
+ //
+ IDE_BUS_PROTOCOL *IdeInterface = ((IDE_DISK_INFO*)DiskInfoProtocol)->IdeBusInterface;
+ EFI_PCI_IO_PROTOCOL *PciIo = IdeInterface->PciIO;
+
+ Status = PciIo->GetLocation(PciIo, &PciSeg, &PciBus, &PciDev, &PciFun);
+ ASSERT_EFI_ERROR(Status);
+
+ DetectedHddBDF = (UINT16)((PciBus << 8) | (PciDev << 3) | PciFun );
+
+ Status = PciIo->Pci.Read (PciIo,\
+ EfiPciIoWidthUint16,\
+ 0x0A,\
+ 1,\
+ &DetectedHddClassCode);
+ ASSERT_EFI_ERROR(Status);
+
+ DetectedHddPortNum = IdeInterface->IdeDevice.Channel | IdeInterface->IdeDevice.Device<<1;
+
+ if (DetectedHddBDF != BDF ||\
+ DetectedHddClassCode != ClassCode ||\
+ DetectedHddPortNum != PortNum)
+ continue;
+
+ DetectedHddSerialNum = IdeInterface->IdeDevice.IdentifyData.Serial_Number_10;
+ break;
+
+ }else if (!guidcmp(&DiskInfoProtocol->Interface,&DiskInfoAhciGuid)) {
+ //
+ //Devie is detected in Ahci mode
+ //
+ SATA_DEVICE_INTERFACE *SataInterface = ((SATA_DISK_INFO*)DiskInfoProtocol)->SataDevInterface;
+ EFI_PCI_IO_PROTOCOL *PciIo = SataInterface->AhciBusInterface->PciIO;
+
+ Status = PciIo->GetLocation(PciIo, &PciSeg, &PciBus, &PciDev, &PciFun);
+ ASSERT_EFI_ERROR(Status);
+
+ DetectedHddBDF = (UINT16)((PciBus << 8) | (PciDev << 3) | PciFun );
+
+ Status = PciIo->Pci.Read (PciIo,\
+ EfiPciIoWidthUint16,\
+ 0x0A,\
+ 1,\
+ &DetectedHddClassCode);
+ ASSERT_EFI_ERROR(Status);
+
+ DetectedHddPortNum = SataInterface->PortNumber;
+
+ if (DetectedHddBDF != BDF ||\
+ DetectedHddClassCode != ClassCode ||\
+ DetectedHddPortNum != PortNum)
+ continue;
+
+ DetectedHddSerialNum = SataInterface->IdentifyData.Serial_Number_10;
+ break;
+
+ }
+ }
+
+ pBS->FreePool(Handle);
+
+ if (DetectedHddSerialNum == NULL) return EFI_NOT_FOUND;
+
+//
+// Compare Serial number is as same as last boot.
+//
+
+ if(!MemCmp(DetectedHddSerialNum,SataDevice->SerialNum,20))
+ return EFI_SUCCESS;
+
+
+ TRACE((-1,"FB: ConnectedHdd is match with previous boot\n"));
+
+ TRACE((-1,"Detected BDS %x, ClassCode %x, PortNum %x\n",DetectedHddBDF,DetectedHddClassCode,DetectedHddPortNum));
+
+ TRACE((-1,"Detected Serial Number: "));
+
+ for(i=0;i<20;i++)
+ {
+ TRACE((-1,"%02x ",DetectedHddSerialNum[i]));
+ }
+ TRACE((-1," \n"));
+
+
+ TRACE((-1,"Last BDS %x, ClassCode %x, PortNum %x\n",SataDevice->BDF,SataDevice->ClassCode,SataDevice->PortNum));
+
+ TRACE((-1,"Last Serial Number: "));
+
+ for(i=0;i<20;i++)
+ {
+ TRACE((-1,"%02x ",SataDevice->SerialNum[i]));
+ }
+ TRACE((-1," \n"));
+
+ return EFI_DEVICE_ERROR;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSataDevicePath
+//
+// Description: Check device path is for sata devcie or not
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp - Device path need to be checked.
+//
+// Output:
+// BOOLEAN TRUE,the devcie path is for sata devcie, otherwise False.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsSataDevicePath(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDp = NULL;
+
+ TempDp = FindDevicePath(Dp,MESSAGING_DEVICE_PATH,MSG_SATA_DP);
+ if (TempDp != NULL) return TRUE;
+
+ TempDp = FindDevicePath(Dp,MESSAGING_DEVICE_PATH,MSG_ATAPI_DP);
+ if (TempDp != NULL) return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsLegacyRaidDevicePath
+//
+// Description: Check device path is legacy raid device path or not.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp - Device path need to be checked.
+//
+// Output:
+// BOOLEAN TRUE,the devcie path is for legacy raid devcie, otherwise False.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsLegacyRaidDevicePath(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDp = NULL;
+ PCI_DEVICE_PATH *PciDp = NULL;
+#if SUPPORT_RAID_DRIVER
+ SATA_DEVICE_DATA *SataDevice = (SATA_DEVICE_DATA*)gFastBootPolicy->SataDevice;
+ UINT8 i;
+#endif
+ UINT16 BDF;
+
+ if (gFastBootPolicy->UEfiBoot == TRUE) return FALSE;
+
+ TempDp = FindDevicePath(Dp,HARDWARE_DEVICE_PATH,HW_VENDOR_DP);
+ if(TempDp == NULL) return FALSE;
+
+ TempDp = FindDevicePath(Dp,HARDWARE_DEVICE_PATH,HW_PCI_DP);
+ if(TempDp == NULL) return FALSE;
+
+ PciDp = (PCI_DEVICE_PATH*)TempDp;
+ BDF = (UINT16)((0 << 8) | (PciDp->Device << 3) | PciDp->Function );
+#if SUPPORT_RAID_DRIVER
+ for (i=0;i<MAX_SATA_DEVICE_COUNT && SataDevice[i].BDF!=0;i++) {
+ if (BDF == SataDevice[i].BDF)
+ return TRUE;
+ }
+#endif
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectDevicePath_Recursive
+//
+// Description: Connect controller by device path recursively.
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *pPath - Device path want to be connected.
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ConnectDevicePath_Recursive (
+ IN EFI_DEVICE_PATH_PROTOCOL *pPath)
+{
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ while (TRUE)
+ {
+ EFI_DEVICE_PATH_PROTOCOL *pLastPath = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *pFirstNode = pPath;
+
+ if (isEndNode(pPath))
+ {
+ if (pPath->SubType == END_ENTIRE_SUBTYPE) break;
+ pPath++;
+ continue;
+ }
+
+ while (TRUE) {
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 SubType;
+
+ pPath = pFirstNode;
+
+ // LocateDevicePath can not work with multi-instance device paths.
+ // Prepare single instance device path and call LocateDevicePath.
+
+ Dp = DPGetEndNode(pPath);
+ SubType = Dp->SubType;
+ Dp->SubType = END_ENTIRE_SUBTYPE;
+ Status = pBS->LocateDevicePath(&gEfiDevicePathProtocolGuid, \
+ &pPath, &Handle);
+ Dp->SubType = SubType;
+ if (EFI_ERROR(Status)) break;
+
+ if (isEndNode(pPath))
+ {
+ // Last time let's do it recursively.
+
+ pBS->ConnectController(Handle, NULL, NULL, TRUE);
+ break;
+ }
+ if (pPath == pLastPath) break;
+ pLastPath = pPath;
+
+ if (StopBlkIo == TRUE) {
+ gHandle = Handle;
+ Status = pBS->OpenProtocol( Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&DevicePath,
+ ThisImageHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+ } else {
+ Status = pBS->CloseProtocol ( Handle,
+ &gEfiDevicePathProtocolGuid,
+ ThisImageHandle,
+ Handle);
+ }
+
+ if (EFI_ERROR(pBS->ConnectController(Handle, NULL, pPath, TRUE)))
+ break;
+ }
+
+ while (!isEndNode(pPath))
+ pPath = NEXT_NODE(pPath);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectAllAmdRaidController
+//
+// Description: Connect All Amd Raid Controller
+//
+// Input:
+// None
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ConnectAllAmdRaidController(){
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+
+ TRACE((-1,"FB: ConnectAllAmdRaidController\n"));
+
+
+ //Get a list of all USB Controllers
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_MASS_STOR, PCI_CL_MASS_STOR_SCL_RAID, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+ for(i=0; i<Number; i++)
+ {
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINT16 VID;
+ Status=pBS->HandleProtocol(Handle[i],&gEfiPciIoProtocolGuid2,&PciIo);
+ if (EFI_ERROR(Status)) continue;
+ Status=PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, 0x00, 1, &VID);
+ if(VID == 0x1022) {
+ TRACE((-1,"FB: Connect AMD Raid Controller\n"));
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+ }
+
+ }
+ pBS->FreePool(Handle);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectLastHddDevice
+//
+// Description: Connect previous boot Hdd
+//
+// Input:
+// None
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ConnectLastHddDevice()
+{
+ EFI_DEVICE_PATH_PROTOCOL *Dp = gFastBootPolicy->FastBootOption;
+ EFI_DEVICE_PATH_PROTOCOL *TempDp = Dp;
+ EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_STATUS Status;
+ EFI_HANDLE PciHandle;
+ UINT16 RaidDevCnt=0;
+#if SUPPORT_RAID_DRIVER
+ SATA_DEVICE_PATH *SataDp;
+ UINT16 RaidPortNumber;
+ UINT16 i,j;
+#endif
+ UINT16 ClassCode;
+ UINT16 VID;
+
+ if (IsLegacyRaidDevicePath(Dp))
+ {
+ // there is no port information in Legacy Raid device, so decide to
+ // connect all HDDs.
+ TRACE((-1, "FB: ConnectLastHddDevice - Find Legacy raid!\n"));
+ TRACE((-1, "FB: Attempt to connect all Sata Device\n"));
+ ConnectAllSataDevices();
+ return EFI_SUCCESS;
+ }
+
+ TRACE((-1, "FB: ConnectLastHddDevice\n"));
+
+ TempDp = Dp;
+
+ Status = pBS->LocateDevicePath(&PciIoProtocolGuid, &TempDp, &PciHandle);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->HandleProtocol(PciHandle,&PciIoProtocolGuid,&PciIo);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = PciIo->Pci.Read (PciIo,\
+ EfiPciIoWidthUint16,\
+ 0x0A,\
+ 1,\
+ &ClassCode);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = PciIo->Pci.Read (PciIo,\
+ EfiPciIoWidthUint16,\
+ 0x00,\
+ 1,\
+ &VID);
+ ASSERT_EFI_ERROR(Status);
+
+ if (ClassCode != 0x0104 && ClassCode != 0x0106 && ClassCode != 0x0101)
+ return EFI_SUCCESS; //is not sata device, do Not try to connect it.
+
+#if SUPPORT_RAID_DRIVER
+ if(VID == 0x8086 && ClassCode == 0x0104)
+ { //Intel Raid
+ TempDp = Dp;
+ TempDp = FindDevicePath(TempDp,MESSAGING_DEVICE_PATH,MSG_SATA_DP);
+ SataDp = (SATA_DEVICE_PATH*)TempDp;
+ StopBlkIo = TRUE;
+ //check how many raid dev by checking bitmap
+ for (i=0;i<16;i++) {
+ if(SataDp->PortNumber & 1<<i) RaidDevCnt++;
+ }
+ RaidPortNumber = SataDp->PortNumber;
+
+ Status = pBS->AllocatePool(EfiBootServicesData,DPLength(Dp),&TempDp);
+ ASSERT_EFI_ERROR(Status);
+
+ MemCpy(TempDp,Dp,DPLength(Dp));
+
+ //connect each port
+ SataDp = (SATA_DEVICE_PATH*)FindDevicePath(TempDp,MESSAGING_DEVICE_PATH,MSG_SATA_DP);
+ for(j=0;j<16 && RaidDevCnt>0;j++) {
+ if(RaidPortNumber & 1<<j)
+ {
+ SataDp->PortNumber = j;
+ SataDp->MultiplierPortNumber = 0xFF;
+ RaidDevCnt--;
+ if (RaidDevCnt == 0) {
+ StopBlkIo = FALSE;
+ }
+ ConnectDevicePath_Recursive(TempDp);
+ }
+ }
+
+ pBS->FreePool(TempDp);
+
+
+ } else {
+ ConnectDevicePath_Recursive(Dp);
+ }
+#else
+ if(ClassCode == 0x0104) // RAID Mode
+ ConnectAllSataDevices();
+ else
+ ConnectDevicePath_Recursive(Dp);
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectHddDevices
+//
+// Description: Connect all previous boot Hdds.
+//
+// Input:
+// None
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if SUPPORT_RAID_DRIVER
+EFI_STATUS ConnectHddDevices()
+{
+ UINT8 SataPort_DevPath[]= {
+ // ACPI Device Path
+ 0x02,0x01,0x0c,0x00,0xd0,0x41,0x03,0x0a,0x00,0x00,0x00,0x00,
+ //PCI Device Path
+ 0x01,0x01,0x06,0x00,0x02,0x1f,
+ //SATA Device Path
+ 0x03,0x12,0x0a,0x00,0x00,0x00,0xff,0xff,0x00,0x00,
+ //Terminal
+ 0x7f,0xff,0x04,0x00
+ };
+
+ UINT8 IdePort_DevPath[]= {
+ // ACPI Device Path
+ 0x02,0x01,0x0c,0x00,0xd0,0x41,0x03,0x0a,0x00,0x00,0x00,0x00,
+ //PCI Device Path
+ 0x01,0x01,0x06,0x00,0x02,0x1f,
+ //SATA Device Path
+ 0x03,0x01,0x08,0x00,0x00,0x00,0x00,0x00,
+ //Terminal
+ 0x7f,0xff,0x04,0x00
+ };
+
+ EFI_STATUS Status;
+ UINT8 i;
+ EFI_DEVICE_PATH_PROTOCOL *TempDp;
+ UINT8 Device,Function;
+ SATA_DEVICE_DATA *SataDevice = (SATA_DEVICE_DATA*)gFastBootPolicy->SataDevice;
+ EFI_DEVICE_PATH_PROTOCOL *Dp = gFastBootPolicy->FastBootOption;
+
+ if (IsLegacyRaidDevicePath(Dp) && SataDevice[0].ClassCode == 0x0104)
+ {
+ TRACE((-1, "FB: Attempt to connect all Sata Device\n"));
+ ConnectAllSataDevices();
+ return EFI_SUCCESS;
+ }
+ TRACE((-1, "FB: ConnectHddDevices\n"));
+
+ for(i=0;i<MAX_SATA_DEVICE_COUNT && SataDevice[i].BDF!=0;i++)
+ {
+ if (SataDevice[i].DevType == ATAPI || SataDevice[i].DevType == PMPORT)
+ continue;
+
+ if(SataDevice[i].ClassCode == 0x0106 || SataDevice[i].ClassCode == 0x0104)
+ { // AHCI or RAID
+ if(SataDevice[i].ClassCode == 0x0104) {
+
+ StopBlkIo = TRUE;
+ }
+ Function = SataDevice[i].BDF & 0x03;
+ Device = (SataDevice[i].BDF >> 3) & 0x1F;
+ TempDp = FindDevicePath((EFI_DEVICE_PATH_PROTOCOL*)SataPort_DevPath,HARDWARE_DEVICE_PATH,HW_PCI_DP);
+ if (TempDp == NULL) {
+ StopBlkIo = FALSE;
+ continue;
+ }
+ ((PCI_DEVICE_PATH*)TempDp)->Device = Device;
+ ((PCI_DEVICE_PATH*)TempDp)->Function = Function;
+
+ TempDp = FindDevicePath((EFI_DEVICE_PATH_PROTOCOL*)SataPort_DevPath,MESSAGING_DEVICE_PATH,MSG_SATA_DP);
+ ((SATA_DEVICE_PATH*)TempDp)->PortNumber = (UINT16)SataDevice[i].PortNum;
+
+ ConnectDevicePath_Recursive((EFI_DEVICE_PATH_PROTOCOL*)SataPort_DevPath);
+ if (SataDevice[i + 1].BDF == 0) {
+ StopBlkIo = FALSE;
+ pBS->CloseProtocol ( gHandle,
+ &gEfiDevicePathProtocolGuid,
+ ThisImageHandle,
+ gHandle);
+ pBS->ConnectController(gHandle, NULL, NULL, TRUE);
+ }
+ Status = CheckConnectedHdd(SataDevice[i].BDF,SataDevice[i].ClassCode,SataDevice[i].PortNum);
+ if(EFI_ERROR(Status)) {
+ if (StopBlkIo == TRUE) {
+ StopBlkIo = FALSE;
+ pBS->CloseProtocol ( gHandle,
+ &gEfiDevicePathProtocolGuid,
+ ThisImageHandle,
+ gHandle);
+ }
+ return Status;
+ }
+ }
+ else if (SataDevice[i].ClassCode == 0x0101)
+ { //IDE
+
+ Function = SataDevice[i].BDF & 0x03;
+ Device = (SataDevice[i].BDF >> 3) & 0x1F;
+ TempDp = FindDevicePath((EFI_DEVICE_PATH_PROTOCOL*)IdePort_DevPath,HARDWARE_DEVICE_PATH,HW_PCI_DP);
+ if (TempDp == NULL) continue;
+ ((PCI_DEVICE_PATH*)TempDp)->Device = Device;
+ ((PCI_DEVICE_PATH*)TempDp)->Function = Function;
+
+ TempDp = FindDevicePath((EFI_DEVICE_PATH_PROTOCOL*)IdePort_DevPath,MESSAGING_DEVICE_PATH,MSG_ATAPI_DP);
+ ((ATAPI_DEVICE_PATH*)TempDp)->PrimarySecondary = SataDevice[i].PortNum & BIT0;
+ ((ATAPI_DEVICE_PATH*)TempDp)->SlaveMaster = SataDevice[i].PortNum & BIT1;
+
+ ConnectDevicePath_Recursive((EFI_DEVICE_PATH_PROTOCOL*)IdePort_DevPath);
+
+ Status = CheckConnectedHdd(SataDevice[i].BDF,SataDevice[i].ClassCode,SataDevice[i].PortNum);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }
+
+ // Up to here, all recorded sata devcies are connected.
+ //
+ // But AHCIBUS would NOT be run in AMD Raid mode, so we don't know whether all Hdd is connect on Raid controller or not.
+ // Find out all AMD Raid controller and connect it.
+
+ ConnectAllAmdRaidController();
+
+ return EFI_SUCCESS;
+}
+#endif
+
+ //(EIP62845+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectAllSataDevices
+//
+// Description: Connect All Stat Devcies
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConnectAllSataDevices() //(EIP85135)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+// if (gFastBootPolicy->ConnectAllSata == FALSE) return; //(EIP96276.3)+
+
+ TRACE((-1, "FB: ConnectAllSataDevices\n"));
+
+ //Connect all SATA IDE Controllers
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_MASS_STOR, PCI_CL_MASS_STOR_SCL_IDE, &Number, &Handle
+ );
+
+ if(!EFI_ERROR(Status)){
+ for(i=0; i<Number; i++){
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+ }
+ pBS->FreePool(Handle);
+ }
+
+ //Connect all SATA AHCI Controllers
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_MASS_STOR, 0x06, &Number, &Handle
+ );
+
+ if(!EFI_ERROR(Status)){
+ for(i=0; i<Number; i++){
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+ }
+ pBS->FreePool(Handle);
+ }
+
+ //(EIP95568+)>
+ //Connect all SATA RAID Controllers
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_MASS_STOR, PCI_CL_MASS_STOR_SCL_RAID, &Number, &Handle
+ );
+
+ if(!EFI_ERROR(Status)){
+ for(i=0; i<Number; i++){
+ pBS->ConnectController(Handle[i],NULL,NULL,TRUE);
+ }
+ pBS->FreePool(Handle);
+ }
+ //<(EIP95568+)
+ return EFI_SUCCESS; //(EIP85135)
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSataPortPresentHOB
+//
+// Description: Get Sata port present HOB
+//
+// Input:
+// IN OUT SATA_PRESENT_HOB **SataPresentHob
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if SUPPORT_RAID_DRIVER
+EFI_STATUS GetSataPortPresentHOB (
+ IN SATA_PRESENT_HOB **SataPresentHob
+ )
+{
+ EFI_STATUS Status;
+ VOID *pHobList = NULL;
+ EFI_GUID guidHob = HOB_LIST_GUID;
+ EFI_GUID SataPresentHobGuid = AMI_SATA_PRESENT_HOB_GUID;
+// SATA_PRESENT_HOB *pSataPresentHob;
+
+
+ pHobList = GetEfiConfigurationTable(pST, &guidHob);
+ if (!pHobList) return EFI_NOT_READY;
+
+ *SataPresentHob = (SATA_PRESENT_HOB*)pHobList;
+
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, SataPresentHob)))
+ {
+ if (guidcmp(&(*SataPresentHob)->EfiHobGuidType.Name, &SataPresentHobGuid) == 0)
+ break;
+ }
+
+
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectSataDeviceInfo
+//
+// Description: Collect the Sata device information created by Ahci and Ide
+// bus driver
+//
+// Input:
+// IN FAST_BOOT *Var - FastBoot variable
+//
+// Output:
+// None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if SUPPORT_RAID_DRIVER
+VOID CollectSataDeviceInfo(
+ IN FAST_BOOT *Var
+)
+{
+ EFI_GUID DiskInfoGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_GUID DiskInfoIdeGuid = EFI_DISK_INFO_IDE_INTERFACE_GUID;
+ EFI_GUID DiskInfoAhciGuid = EFI_DISK_INFO_AHCI_INTERFACE_GUID;
+ EFI_DISK_INFO_PROTOCOL *DiskInfoProtocol;
+ UINTN Count,i,j;
+ EFI_HANDLE *Handle;
+ EFI_STATUS Status;
+ static BOOLEAN Executed = FALSE;
+ UINTN Seg, Bus, Dev, Fun;
+ UINT8 SataDevCount = 0;
+ SATA_PRESENT_HOB *pSataPresentHob = NULL;
+
+ if (Executed == TRUE) return;
+//
+// Collect the port present information reported by chipset
+//
+
+ Status = GetSataPortPresentHOB(&pSataPresentHob);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1,"FB: Sata port present HOB is not found, need CSP porting for it\n"));
+ return;
+ }
+
+ MemCpy(&Var->ControllerCount,&pSataPresentHob->ControllerCount,sizeof(SATA_PRESENT_HOB)-sizeof(EFI_HOB_GUID_TYPE));
+
+//
+// Collect the Sata device information created by Ahci and Ide bus driver
+//
+ Status=pBS->LocateHandleBuffer(ByProtocol,&DiskInfoGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return;
+
+ for(i=0;i<Count;i++)
+ {
+ Status=pBS->HandleProtocol(Handle[i],&DiskInfoGuid,(VOID**)&DiskInfoProtocol);
+ if(EFI_ERROR(Status)) continue;
+
+ if(!guidcmp(&DiskInfoProtocol->Interface,&DiskInfoIdeGuid)) {
+ //
+ //Devie is detected in Ide mode
+ //
+ IDE_BUS_PROTOCOL *IdeInterface = ((IDE_DISK_INFO*)DiskInfoProtocol)->IdeBusInterface;
+ EFI_PCI_IO_PROTOCOL *PciIo = IdeInterface->PciIO;
+
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Fun);
+ ASSERT_EFI_ERROR(Status);
+
+ Var->SataDevice[SataDevCount].BDF = (UINT16)((Bus << 8) | (Dev << 3) | Fun );
+
+ Status = PciIo->Pci.Read (PciIo,\
+ EfiPciIoWidthUint16,\
+ 0x0A,\
+ 1,\
+ &Var->SataDevice[SataDevCount].ClassCode);
+ ASSERT_EFI_ERROR(Status);
+
+
+ Var->SataDevice[SataDevCount].DevType = IdeInterface->IdeDevice.DeviceType;
+ Var->SataDevice[SataDevCount].PortNum = IdeInterface->IdeDevice.Channel | IdeInterface->IdeDevice.Device<<1;
+
+ MemCpy( &Var->SataDevice[SataDevCount].SerialNum,
+ &IdeInterface->IdeDevice.IdentifyData.Serial_Number_10,20);
+
+ SataDevCount++;
+
+ ASSERT(SataDevCount<MAX_SATA_DEVICE_COUNT);
+
+ }else if (!guidcmp(&DiskInfoProtocol->Interface,&DiskInfoAhciGuid)) {
+ //
+ //Devie is detected in Ahci mode
+ //
+ SATA_DEVICE_INTERFACE *SataInterface = ((SATA_DISK_INFO*)DiskInfoProtocol)->SataDevInterface;
+ EFI_PCI_IO_PROTOCOL *PciIo = SataInterface->AhciBusInterface->PciIO;
+
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Fun);
+ ASSERT_EFI_ERROR(Status);
+
+ Var->SataDevice[SataDevCount].BDF = (UINT16)((Bus << 8) | (Dev << 3) | Fun );
+
+ Status = PciIo->Pci.Read (PciIo,\
+ EfiPciIoWidthUint16,\
+ 0x0A,\
+ 1,\
+ &Var->SataDevice[SataDevCount].ClassCode);
+ ASSERT_EFI_ERROR(Status);
+
+ Var->SataDevice[SataDevCount].DevType = SataInterface->DeviceType;
+ Var->SataDevice[SataDevCount].PortNum = SataInterface->PortNumber;
+
+ MemCpy( &Var->SataDevice[SataDevCount].SerialNum,
+ &SataInterface->IdentifyData.Serial_Number_10,20);
+
+ SataDevCount++;
+
+ ASSERT(SataDevCount<MAX_SATA_DEVICE_COUNT);
+
+ } else {
+ continue;
+ }
+
+ }
+
+//
+// Print out message for Sata Port&Device information.
+//
+
+ for(i=0;i<MAX_SATA_DEVICE_COUNT && Var->SataDevice[i].BDF!=0;i++)
+ {
+ TRACE((-1,"FB: SataDevice[%d] -- BDF:%x, CalssCode:%x, DveType:%x, PortNum:%x\n",\
+ i,Var->SataDevice[i].BDF,Var->SataDevice[i].ClassCode,\
+ Var->SataDevice[i].DevType,Var->SataDevice[i].PortNum));
+
+ TRACE((-1,"Serial Number: "));
+
+ for(j=0;j<20;j++)
+ {
+ TRACE((-1,"%02x ",Var->SataDevice[i].SerialNum[j]));
+ }
+ TRACE((-1," \n"));
+ }
+
+ pBS->FreePool(Handle);
+
+ return;
+}
+#endif
+ //<(EIP62845+)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootReadyToBootNotify
+//
+// Description: FastBoot ReadyToBoot callback
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBootReadyToBootNotify(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ UINTN i,Size;
+ FAST_BOOT Var;
+ UINT16 *BootOrder = NULL;
+ CHAR16 BootOptionName[9];
+ EFI_LOAD_OPTION *BootOption = NULL;
+ UINTN BootOptionSize; //(EIP96276.4+)
+ CHAR16 *Description;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT32 BbsPopup;
+ BOOLEAN VaildBootOption = FALSE;
+#if FASTBOOT_NEED_RESTART
+ UINTN ReBootFlag;
+ UINTN ReBootFlagSize = sizeof(ReBootFlag);
+ UINTN ReBootCount;
+ UINTN ReBootCountSize = sizeof(ReBootCount);
+ UINTN ResetFlag = 1;
+ UINTN ClearCount = 0;
+#endif
+
+//check if we are on bbs-popup boot path
+ Size = sizeof(BbsPopup);
+ Status = pRS->GetVariable(L"BbsPopupCalled", &FastBootVariableGuid, NULL, &Size, (VOID *)&BbsPopup);
+ if(!EFI_ERROR(Status) && (BbsPopup == 0x55aa55aa)) { //we are on bbs-popup boot path
+ ResetFastBootVariable(); //clear variable if it was created on previous boots
+ return;
+ }
+
+ Size = sizeof(Var);
+ pBS->SetMem(&Var,Size,0);
+
+ Status = pRS->GetVariable(L"LastBoot", &FastBootVariableGuid, NULL, &Size, (VOID *)&Var);
+ if(EFI_ERROR(Status)) {
+
+#if FASTBOOT_NEED_RESTART
+ Status = pRS->GetVariable(FAST_BOOT_RESTART,
+ &FastbootRestartGuid,
+ NULL,
+ &ReBootFlagSize,
+ (VOID *)&ReBootFlag
+ );
+
+ Status = pRS->GetVariable(FAST_BOOT_RESTART_COUNT,
+ &FastbootRestartCountGuid,
+ NULL,
+ &ReBootCountSize,
+ (VOID *)&ReBootCount
+ );
+ if(!EFI_ERROR(Status))
+ {
+ TRACE((-1,"FB: ReBootFlag:%d\n",ReBootFlag));
+ TRACE((-1,"FB: ReBootCount:%d\n",ReBootCount));
+
+ if(ReBootFlag == 1 && ReBootCount <1 )
+ FastBootEnableRestart(ReBootFlag,ReBootCount+1);
+ }
+ else
+ FastBootEnableRestart(ResetFlag,ClearCount+1);
+#endif
+
+ //variable not found - create a new one
+
+//
+// Collect Boot Option information for next boot
+//
+ Status = GetEfiVariable(L"BootOrder", &EfiVariableGuid, NULL, &Size, &BootOrder);
+ if(EFI_ERROR(Status)) return;
+
+ for (i=0;i<Size/sizeof(UINT16);i++,BootOption=NULL) { //(EIP96276.4)
+
+ Swprintf(BootOptionName, gBootName, BootOrder[i]);
+
+ Status = GetEfiVariable(BootOptionName, &EfiVariableGuid, NULL, &BootOptionSize, &BootOption); //(EIP96276.4)
+ if(EFI_ERROR(Status)) return;
+
+
+ VaildBootOption = IsValidFBBootOptionPtr(i,BootOption);
+ if (VaildBootOption) break;
+
+ pBS->FreePool(BootOption);
+
+ if (VaildBootOption == FALSE && i == (Size/sizeof(UINT16) -1 )) {
+ TRACE((-1, "FB: There is no valid boot option\n"));
+ pBS->FreePool(BootOrder);
+ return;
+
+ }
+
+ }
+
+ Var.BootOptionNumber = BootOrder[i];
+ Var.BootCount = 0;
+
+ //retrieve device path
+ Description = (CHAR16 *)(BootOption + 1);
+ Dp = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8*)Description + (Wcslen(Description) + 1) * sizeof(CHAR16));
+
+ if(Dp->Type == BBS_DEVICE_PATH) {
+ Var.BootType = FAST_BOOT_TYPE_LEGACY;
+ Status = CreateLegacyFastBootOption(&Var);
+ TRACE((-1,"FB: Create FastBoot Legacy Boot Option %r\n",Status));
+ } else {
+ Var.BootType = FAST_BOOT_TYPE_EFI;
+ Status = CreateEfiFastBootOption(BootOption, BootOptionSize, BootOrder[i]); //(EIP96276.4)
+ TRACE((-1,"FB: Create FastBoot EFI Boot Option %r\n",Status));
+ }
+
+ pBS->FreePool(BootOrder);
+ pBS->FreePool(BootOption);
+
+ if(EFI_ERROR(Status)) return;
+
+//
+// Collect SATA Port&Device information
+//
+#if SUPPORT_RAID_DRIVER
+ CollectSataDeviceInfo(&Var);
+#endif
+
+ } else {
+ Var.BootCount++;
+ Var.BootOptionNumber = gFastBootPolicy->BootOptionNumber;
+ }
+
+ TRACE((-1,"FB: Create LastBoot Variable\n"));
+ pRS->SetVariable(L"LastBoot",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(Var),
+ (VOID *)&Var);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectFastLegacyBoot
+//
+// Description: Connect Legacy FastBoot Device
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ConnectFastLegacyBootDevice()
+{
+#if CSM_SUPPORT
+ EFI_STATUS Status;
+ UINTN Size = 0;
+ UINT8 *BootOption = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ BOOLEAN UsbMassStorage = FALSE;
+ BOOLEAN HddFilePath = FALSE;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *HddInfo;
+ BBS_TABLE *BbsTable;
+ EFI_HANDLE Handle;
+ UINT8 i; //(EIP63924+)
+ TRACE((-1, "FB: Connect Fast LegacyBoot Device\n"));
+
+ Dp = gFastBootPolicy->FastBootOption;
+ if(!IsSupportedDevice(Dp, &UsbMassStorage, &HddFilePath)) //CD-ROM legacy boot not supported
+ return EFI_NOT_FOUND;
+
+ if ( UsbMassStorage && gFastBootPolicy->UsbSupport == 0)
+ return EFI_NOT_FOUND; //If skip usb enable, don't boot into usb mass storage
+
+ if(!IsSataDevicePath(Dp) && !IsLegacyRaidDevicePath(Dp))
+ {
+ TRACE((-1, "FB: Dp connecting\n"));
+ ConnectDevicePath(Dp);
+ }
+
+ Status = pBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &Dp, &Handle);
+ if(EFI_ERROR(Status))
+ return Status;
+ TRACE((-1, "FB: Dp connected Handle %x\n",Handle));
+
+ LegacyBootDeviceHandle = Handle;
+
+ Status = pBS->HandleProtocol(Handle, &gEfiBlockIoProtocolGuid, &BlockIo);
+ if(EFI_ERROR(Status))
+ return Status;
+ TRACE((-1, "FB: BlockIo found\n"));
+
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ if (EFI_ERROR(Status))
+ return Status;
+ TRACE((-1, "FB: Legacybios discovered\n"));
+
+ //(EIP63924)>
+ // check FastBootModeChange
+ for (i=0;FastBootModeChange[i]; i++)
+ if(FastBootModeChange[i]())return EFI_NOT_FOUND;
+ //<(EIP63924)
+
+ Status = LegacyBios->GetBbsInfo(LegacyBios, &HddCount, &HddInfo, &BbsCount, &BbsTable); //install int 13
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastLegacyBoot
+//
+// Description: Legacy FastBoot path
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FastLegacyBoot(VOID)
+{
+#if CSM_SUPPORT
+ UINTN Size = 0;
+ EFI_STATUS Status;
+ UINT8 *BootOption = NULL;
+ UINT8 Index;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *HddInfo;
+ BBS_TABLE *BbsTable;
+ EFI_EVENT FastBootLegacyBootEvent;
+ UINT8 *pDeviceString;
+ UINT8 i;
+ UINT16 StringCheckSum;
+
+ TRACE((-1, "FB: Fast legacy boot started\n"));
+
+ //(EIP87390+)>
+ pBS->RaiseTPL( TPL_HIGH_LEVEL ); // guarantees that RestoreTPL won't ASSERT
+ pBS->RestoreTPL( TPL_APPLICATION );
+ //<(EIP87390+)
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ if (EFI_ERROR(Status))
+ return Status;
+ TRACE((-1, "FB: Legacybios discovered\n"));
+
+ LegacyBios->GetBbsInfo(LegacyBios, &HddCount, &HddInfo, &BbsCount, &BbsTable); //install int 13
+
+ //(EIP87390+)>
+ //Set USB device BootPriority as BBS_DO_NOT_BOOT_FROM, Install USB INT13 service for TCG Bitlocker Driver
+ for (Index=0;Index<BbsCount;Index++){
+
+ //(EIP103422+)>
+ // if BBS table priority have been arranged already
+ // increase one priority to all prioritized BBS table entry
+ if (BbsTable[Index].BootPriority < BBS_DO_NOT_BOOT_FROM) {
+ BbsTable[Index].BootPriority = BbsTable[Index].BootPriority + 1;
+ continue;
+ }
+ //<(EIP103422+)
+
+ // If BBS table priority have not been arranged yet, set device
+ // priority as BBS_DO_NOT_BOOT_FROM.
+ // It means don't boot from this devcie but BIOS still need to install
+ // INT13 service for it.
+
+ if (BbsTable[Index].BootPriority != BBS_IGNORE_ENTRY)
+ BbsTable[Index].BootPriority = BBS_DO_NOT_BOOT_FROM;
+
+ }
+ //<(EIP87390+)
+
+ for (Index=0;Index<BbsCount;Index++){
+
+ if (BbsTable[Index].IBV1 == (UINT32)LegacyBootDeviceHandle) break;
+
+ if (Index == (BbsCount-1)) return Status; //can't find fast device in bbstable
+ }
+
+ if(gFastBootPolicy->CheckDevStrCheckSum) {
+
+ pDeviceString = (UINT8*)((UINTN)((UINTN)BbsTable[Index].DescStringSegment<<4) + BbsTable[Index].DescStringOffset);
+ StringCheckSum =0;
+ for (i=0;i<50;i++) {
+ if (pDeviceString[i] == 0) break;
+ StringCheckSum+=pDeviceString[i];
+ }
+
+ if (StringCheckSum != gFastBootPolicy->DevStrCheckSum) return EFI_DEVICE_ERROR;
+
+ }
+
+ BbsTable[Index].BootPriority = 0;
+
+ Status = CreateLegacyBootEvent(TPL_CALLBACK,
+ FastBootClearBootFailFlag,
+ NULL,
+ &FastBootLegacyBootEvent);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ TRACE((-1,"FB: LEGACY BOOT Singal Ready to Boot\n"));
+
+ ReadyToBoot(0xffff);
+
+ //(EIP68329)>
+ if((SKIP_TSE_HANDSHAKE == 0) && (TSE_MAJOR >= 0x02) && (TSE_MINOR >= 0x10)) {
+ } else {
+ gFastBootTseProtocol->FastBootPasswordFreezeDevices();
+ }
+ //<(EIP68329)
+
+//Set Runtime as TRUE before pass control to OS.
+ Runtime = TRUE;
+
+ LegacyBios->LegacyBoot(LegacyBios, 0, 0, 0);
+
+ return Status;
+#else
+ return EFI_SUCCESS;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckLoaderEx
+//
+// Description: This function use file system protocol to
+// checks if OS loader present on given device
+//
+// Input:
+// IN EFI_HANDLE Handle - Block io handle, used to get file system protocol
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp - pointer to device path of bootable device
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckLoaderEx(
+ IN EFI_HANDLE Handle,
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp)
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL* SimpleFileSystem = NULL;
+ EFI_FILE_PROTOCOL *FileProtocol = NULL;
+ EFI_FILE_PROTOCOL* NewFileProtocol = NULL;
+ FILEPATH_DEVICE_PATH *BootOptionFilePath=NULL;
+
+ for( ; !(isEndNode(Dp)); Dp = NEXT_NODE(Dp)) {
+ if(Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_FILEPATH_DP) {
+ BootOptionFilePath = (FILEPATH_DEVICE_PATH*) (Dp);
+ break;
+ }
+ }
+ if (BootOptionFilePath == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = pBS->HandleProtocol (
+ Handle,
+ &gEfiSimpleFileSystemProtocolGuid,
+ &SimpleFileSystem
+ );
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = SimpleFileSystem->OpenVolume (
+ SimpleFileSystem,
+ &FileProtocol
+ );
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = FileProtocol->Open (
+ FileProtocol,
+ &NewFileProtocol,
+ BootOptionFilePath->PathName,
+ EFI_FILE_MODE_READ,
+ NULL
+ );
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NewFileProtocol->Close(NewFileProtocol);
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConnectFastEfiBootDevice
+//
+// Description: Connect UEFI FastBoot Device
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConnectFastEfiBootDevice()
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *Dp = gFastBootPolicy->FastBootOption;
+ UINT8 *BootOption = NULL;
+ UINTN Size = 0;
+ EFI_HANDLE Handle;
+ UINT8 i; //(EIP63924+)
+ TRACE((-1, "FB: Connect Fast EFIBoot Device\n"));
+
+ if(IsBootToShell(Dp))
+ InstallFwLoadFile();
+ else {
+ if(!IsSataDevicePath(Dp))
+ {
+ TRACE((-1, "FB: Dp connecting\n"));
+ ConnectDevicePath(Dp);
+ }
+
+ Status = pBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &Dp, &Handle);
+ if(EFI_ERROR(Status)) return Status;
+ TRACE((-1, "FB: Dp connected Handle %x\n",Handle));
+ Status = CheckLoaderEx(Handle, gFastBootPolicy->FastBootOption);
+ if(EFI_ERROR(Status)) {
+ TRACE((-1, "FB: Check loader %r\n",Status));
+ return Status;
+ }
+
+ }
+ //(EIP63924)>
+ for (i=0;FastBootModeChange[i]; i++)
+ if(FastBootModeChange[i]())return EFI_NOT_FOUND;
+ //<(EIP63924)
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: _ShellClearScreen
+//
+// Description: Clears the screen for shell boot
+//
+// Input: EFI_EVENT , VOID *
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID _ShellClearScreen (EFI_EVENT Event, VOID *Context)
+{
+ pST->ConOut->ClearScreen (pST->ConOut);
+ pBS->CloseEvent (Event);
+ pST->ConOut->EnableCursor (pST->ConOut, TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: _RegisterShellGuid
+//
+// Description: Registers the shell guid
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID _RegisterShellGuid (VOID)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ VOID *Registration = NULL;
+ EFI_GUID EfiShellInterfaceGuid = EFI_SHELL_PROTOCOL_GUID;
+ EFI_EVENT ShellLaunchEvent;
+ Status = pBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ _ShellClearScreen,
+ NULL,
+ &ShellLaunchEvent);
+ if (!EFI_ERROR (Status))
+ {
+ Status = pBS->RegisterProtocolNotify(
+ &EfiShellInterfaceGuid,
+ ShellLaunchEvent,
+ &Registration
+ );
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastEfiBoot
+//
+// Description: UEFI FastBoot path
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FastEfiBoot(VOID)
+{
+ EFI_STATUS Status;
+ UINT8 *BootOption = NULL;
+ UINTN Size = 0;
+ UINT16 OptionNumber = 0xFFFF;
+ EFI_DEVICE_PATH_PROTOCOL *Dp = NULL;
+ UINTN DpSize;
+ UINT32 LoadOptionsSize;
+ VOID *LoadOptions;
+ EFI_LOADED_IMAGE_PROTOCOL *Image;
+
+ TRACE((-1, "FB: Fast EFI boot started\n"));
+
+ DpSize = DPLength(gFastBootPolicy->FastBootOption);
+ LoadOptionsSize = *(UINT32 *)((UINT8 *)gFastBootPolicy->FastBootOption + DpSize);
+ LoadOptions = (VOID *)((UINT8 *)gFastBootPolicy->FastBootOption + DpSize + sizeof(UINT32));
+
+ // this *MUST* be run a EFI_TPL_APPLICATION
+ pBS->RaiseTPL( TPL_HIGH_LEVEL ); // guarantees that RestoreTPL won't ASSERT (EIP87390)+
+ pBS->RestoreTPL( TPL_APPLICATION );
+
+ TRACE((-1,"FB: EFI BOOT Signal Ready to Boot\n"));
+
+//
+// ReadyToBoot have signaled already in TSE path.
+//
+ if (gFastBootPolicy->SkipTSEHandshake)
+ ReadyToBoot(gFastBootPolicy->BootOptionNumber);
+
+
+ Status = pBS->LoadImage(TRUE, ThisImageHandle, gFastBootPolicy->FastBootOption, NULL, 0, &EFIBootImageHanlde);
+
+ TRACE((-1,"FB: load image %r\n",Status));
+
+ if (EFI_ERROR(Status)) return Status;
+ if(LoadOptionsSize != 0) {
+ Status = pBS->HandleProtocol(EFIBootImageHanlde, &gEfiLoadedImageProtocolGuid, &Image);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Image->LoadOptionsSize = LoadOptionsSize;
+ Image->LoadOptions = LoadOptions;
+ }
+ //(EIP68329)>
+ if((gFastBootPolicy->SkipTSEHandshake == 0) && (TSE_MAJOR >= 0x02) && (TSE_MINOR >= 0x10)) {
+ } else {
+ gFastBootTseProtocol->FastBootPasswordFreezeDevices();
+ }
+ PERF_END(0,L"FastBoot",L"FB",0);
+ PERF_END(0,L"TSE",L"FB",0);
+ //<(EIP68329)
+#ifdef EFI_DXE_PERFORMANCE
+ SavePerformanceData(NULL, NULL);
+#endif
+
+ FastBootClearBootFailFlag(NULL, NULL);
+
+ //(EIP60794+)>
+ if (pST->ConOut != NULL) {
+ pST->ConOut->EnableCursor(pST->ConOut,FALSE);
+ }
+
+ _RegisterShellGuid();
+ //<(EIP60794+)
+
+ TRACE((-1,"FB: EFI BOOT start image\n"));
+
+//enabld usb mass driver, so that OS have chance to connect usb mass storage.
+ if (gUsbPolicyProtocol != NULL)
+ gUsbPolicyProtocol->UsbDevPlcy->UsbMassDriverSupport = TRUE;
+
+//Set Runtime as TRUE before pass control to OS.
+ Runtime = TRUE;
+
+ IoWrite8(0x80,0xFB); //output 80port to show system boot with fast boot path.
+ Status = pBS->StartImage(EFIBootImageHanlde, NULL, NULL);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateLegacyFastBootOption
+//
+// Description: This function creates Legacy fast boot option and save it to NVRAM
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateLegacyFastBootOption(
+ FAST_BOOT *Var
+)
+{
+#if CSM_SUPPORT
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *LegacyBios;
+ UINT16 HddCount;
+ UINT16 BbsCount;
+ HDD_INFO *HddInfo;
+ BBS_TABLE *BbsTable;
+ EFI_HANDLE Handle;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ UINT8 BootOption[200];
+ UINTN DpSize;
+ UINT8 i;
+ UINT8 Index = 0; //(EIP73019+)
+ UINT16 Priority = 0xfffc;
+ UINT8 *pDeviceString;
+ UINT16 StringCheckSum=0;
+
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &LegacyBios);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ LegacyBios->GetBbsInfo(LegacyBios, &HddCount, &HddInfo, &BbsCount, &BbsTable);
+
+//find record with highest priority
+ for(i = 0; i < BbsCount; i++) {
+ if(BbsTable[i].BootPriority < Priority) {
+ Priority = BbsTable[i].BootPriority;
+ Index = i;
+ }
+ }
+
+ if(BbsTable[Index].DeviceType != BBS_HARDDISK)
+ return EFI_UNSUPPORTED;
+
+ Handle = (EFI_HANDLE) *(UINTN*)(&(BbsTable[Index].IBV1));
+ Status = pBS->HandleProtocol(Handle, &gEfiDevicePathProtocolGuid, &Dp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ //save device string check sum
+ pDeviceString = (UINT8*)((UINTN)((UINTN)BbsTable[Index].DescStringSegment<<4) + BbsTable[Index].DescStringOffset);
+
+ for (i=0;i<50;i++) {
+ if (pDeviceString[i] == 0) break;
+ StringCheckSum+=pDeviceString[i];
+ }
+
+ Var->DevStrCheckSum = StringCheckSum;
+
+ DpSize = DPLength(Dp);
+ MemCpy(BootOption, Dp, DpSize);
+
+ Status = pRS->SetVariable(L"FastBootOption",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ DpSize,
+ BootOption);
+
+ return Status;
+#else
+ return EFI_SUCCESS;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSupportedDevice
+//
+// Description: This function detects if FastBoot is supported for given device
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp - pointer to device path of bootable device
+// OUT BOOLEAN *UsbMassStorage - TRUE if device is USB device, FALSE otherwise
+//
+// Output: TRUE if FastBoot is supported for given device, FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsSupportedDevice(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp,
+ OUT BOOLEAN *UsbMassStorage,
+ OUT BOOLEAN *HddFilePath
+
+)
+{
+ BOOLEAN USBDev = FALSE;
+
+
+ for( ; !(isEndNode(Dp)); Dp = NEXT_NODE(Dp)) {
+ if(Dp->Type == BBS_DEVICE_PATH)
+ return FALSE;
+
+ if(Dp->Type == MESSAGING_DEVICE_PATH) {
+ if(Dp->SubType == MSG_USB_DP)
+ USBDev = TRUE;
+
+ if(Dp->SubType == MSG_MAC_ADDR_DP)
+ return FALSE;
+
+ continue;
+ }
+
+ if(Dp->Type == MEDIA_DEVICE_PATH) {
+
+ if(Dp->SubType == MEDIA_HARDDRIVE_DP) {
+
+ if(USBDev == TRUE)
+ *UsbMassStorage = TRUE;
+
+ Dp = NEXT_NODE(Dp);
+ //check whether there is a file path behind hard drive path.
+ if(Dp->SubType == MEDIA_FILEPATH_DP)
+ *HddFilePath = TRUE;
+
+ return TRUE;
+ }
+
+ if(Dp->SubType == MEDIA_CDROM_DP)
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+/*
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckLoader
+//
+// Description: This function checks if OS loader present on given device
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp - pointer to device path of bootable device
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckLoader(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+
+ Status = pBS->LoadImage(FALSE, ThisImageHandle, Dp, NULL, 0, &Handle);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = pBS->UnloadImage(Handle);
+ return Status;
+}
+*/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateEfiFastBootOption
+//
+// Description: This function creates UEFI fast boot option and save it to NVRAM
+//
+// Input:
+// IN EFI_LOAD_OPTION *BootOption - pointer to regular boot option to boot to
+// IN UINTN OptionSize - size of option additional parameters
+// IN UINT16 OptionNumber - number of boot option in BootOrder variable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateEfiFastBootOption(
+ IN EFI_LOAD_OPTION *BootOption,
+ IN UINTN OptionSize,
+ IN UINT16 OptionNumber
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN DpSize;
+ EFI_DEVICE_PATH_PROTOCOL *Dp;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDp;
+ CHAR16 *Description;
+ UINT32 LoadOptionsSize;
+ VOID *LoadOptions;
+ UINT8 *FastBootOption;
+ VOID *SavePtr;
+ BOOLEAN UpdatedDp = FALSE;
+ BOOLEAN UsbMassStorage = FALSE;
+ BOOLEAN HddFilePath = FALSE;
+ EFI_HANDLE Handle;
+
+//retrieve device path
+ Description = (CHAR16 *)(BootOption + 1);
+ Dp = (EFI_DEVICE_PATH_PROTOCOL *)((UINT8*)Description + (Wcslen(Description) + 1) * sizeof(CHAR16));
+
+ if(!IsSupportedDevice(Dp, &UsbMassStorage,&HddFilePath))
+ return EFI_UNSUPPORTED;
+
+ //only hard drive or USB can come here
+
+ LoadOptions = (UINT8*)Dp + BootOption->FilePathListLength;
+ LoadOptionsSize = (UINT32)((UINT8*)BootOption + OptionSize - (UINT8 *)LoadOptions);
+
+ if(Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_HARDDRIVE_DP) { //Windowns boot manager?
+ PartitionDp = DiscoverPartition(Dp);
+ if(PartitionDp == NULL)
+ return EFI_UNSUPPORTED;
+
+ Dp = DPAdd(PartitionDp, NEXT_NODE(Dp));
+ UpdatedDp = TRUE;
+ } else if (Dp->Type == MEDIA_DEVICE_PATH && Dp->SubType == MEDIA_VENDOR_DP) { // bulit in shell?
+
+ } else if (HddFilePath == FALSE) { //add file path for SATA Hdd or USB Hdd without file path
+ Dp = DPAddNode(Dp, &FilePathNode.Header);
+ Status = pBS->LocateDevicePath(&gEfiBlockIoProtocolGuid, &Dp, &Handle);
+ if(EFI_ERROR(Status)) {
+ pBS->FreePool(Dp);
+ return Status;
+ }
+ Status = CheckLoaderEx(Handle, Dp);
+ if(EFI_ERROR(Status)) {
+// pBS->FreePool(Dp);
+ return EFI_UNSUPPORTED;
+ }
+// UpdatedDp = TRUE;
+
+ }
+
+ DpSize = DPLength(Dp);
+
+//prepare data
+ Size = DpSize + sizeof(UINT32) + LoadOptionsSize;
+ Status = pBS->AllocatePool(EfiBootServicesData, Size, &FastBootOption);
+ SavePtr = FastBootOption;
+ MemCpy(FastBootOption, Dp, DpSize);
+ FastBootOption += DpSize;
+ *(UINT32 *)FastBootOption = LoadOptionsSize;
+ FastBootOption += sizeof(UINT32);
+ MemCpy(FastBootOption, LoadOptions, LoadOptionsSize);
+
+ Status = pRS->SetVariable(L"FastBootOption",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ Size,
+ SavePtr);
+
+ pBS->FreePool(SavePtr);
+ if(UpdatedDp)
+ pBS->FreePool(Dp);
+ return Status;
+}
+
+VOID ReturnToNormalBoot(VOID)
+{
+ UINT8 i;
+ for (i=0;ReturnNormalModeHook[i]; i++)
+ ReturnNormalModeHook[i]();
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetFastBootVariable
+//
+// Description: This function resets FastBoot variable if FastBoot path failed
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ResetFastBootVariable(VOID)
+{
+ UINTN Size = sizeof(FAST_BOOT);
+ FAST_BOOT Var;
+
+ Runtime = FALSE;
+
+//clear LastBootFailed variable if present
+ FastBootClearBootFailFlag(NULL, NULL);
+
+ if (!gFastBootPolicy->LastBootVarPresence) return;
+
+ pRS->SetVariable(L"LastBoot",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ &Var);
+
+// Disable legacy16 fastboot support
+ DisableLegacy16Fastboot();
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisconnectUsbController
+//
+// Description: This function resets skip table for Usb driver and disconnect
+// all usb controllers
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DisconnectUsbController(VOID)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_HANDLE *Handle;
+ UINTN Number,i;
+
+ if (gFastBootPolicy->UsbSupport != 2) return;
+
+ //Restore Usb storage driver support
+ if (gUsbPolicyProtocol != NULL)
+ gUsbPolicyProtocol->UsbDevPlcy->UsbMassDriverSupport = BackupUsbMassDriverSupport;
+
+ if (FBUsbSkipTableIsSet == FALSE) return;
+
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 920)
+{
+ EFI_GUID gEfiUsbProtocolGuid = EFI_USB_PROTOCOL_GUID;
+ EFI_USB_PROTOCOL *UsbProtocol = NULL;
+ USB_GLOBAL_DATA *UsbData = NULL;
+
+ Status = pBS->LocateProtocol( &gEfiUsbProtocolGuid, \
+ NULL, \
+ &UsbProtocol );
+ if (EFI_ERROR(Status)) return;
+
+ //restore backup skip table pointer
+ UsbData = (USB_GLOBAL_DATA*)UsbProtocol->USBDataPtr;
+ UsbData->gUsbSkipListTable = BackupSkipTable;
+}
+#endif
+
+ //Get a list of all USB Controllers
+ Status = FbGetPciHandlesByClass(
+ PCI_CL_SER_BUS, PCI_CL_SER_BUS_SCL_USB, &Number, &Handle
+ );
+ if (EFI_ERROR(Status)) return;
+
+ for(i=0; i<Number; i++)
+ {
+ pBS->DisconnectController(Handle[i],NULL,NULL);
+ }
+ pBS->FreePool(Handle);
+
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemConfigurationChanged
+//
+// Description: This function checks if configuration was changed since last boot
+//
+// Input: None
+//
+// Output: TRUE if configuration was changed, FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN OemConfigurationChanged(VOID)
+{
+ EFI_STATUS Status;
+ UINT32 BootFlow;
+ UINTN Size = sizeof(UINT32);
+
+ Status = pRS->GetVariable(L"BootFlow", &guidBootFlow, NULL, &Size, &BootFlow);
+
+ return (!EFI_ERROR(Status) && BootFlow == BOOT_FLOW_CONDITION_FIRST_BOOT) ? TRUE : FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootClearBootFailFlag
+//
+// Description: FastBoot clear boot fail flag callback
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBootClearBootFailFlag(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ UINT32 LastBootFailed;
+ UINTN Size = sizeof(UINT32);
+
+ Status = pRS->GetVariable(L"LastBootFailed", &FastBootVariableGuid, NULL, &Size, &LastBootFailed);
+ if(!EFI_ERROR(Status)) {
+ Status = pRS->SetVariable(L"LastBootFailed",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ &LastBootFailed);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFastBoot
+//
+// Description: This function FastBoot is enabled or disabled by checking
+// elink "IsFastBootList"
+//
+// Input: None
+//
+// Output: TRUE if fast boot is enabled, FALSE otherwise
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsFastBoot(VOID)
+{
+ static EFI_GUID SetupVariableGuid = SETUP_GUID;
+ EFI_STATUS Status;
+ UINTN Size;
+ BOOLEAN Result = TRUE;
+ UINTN i;
+ EFI_GUID FastBootPolicyGuid = FAST_BOOT_POLICY_PROTOCOL_GUID;
+
+ // init globe variable
+#ifdef CMOS_MANAGER_SUPPORT
+ #if CMOS_MANAGER_SUPPORT
+ LOCATE_CMOS_ACCESS_PROTOCOL(Status, CmosInterface);
+ ASSERT_EFI_ERROR (Status);
+ #endif
+#endif
+
+ Status = pBS->LocateProtocol(&FastBootPolicyGuid,NULL,&gFastBootPolicy);
+ if (EFI_ERROR(Status) || gFastBootPolicy->FastBootEnable == FALSE)
+ return FALSE;
+
+ Size = sizeof(FbSetupData);
+ Status = pRS->GetVariable(L"Setup", &SetupVariableGuid, NULL, &Size, &FbSetupData);
+ if (EFI_ERROR(Status)) return FALSE;
+
+
+ // check IsFastBootList
+ for (i=0;IsFastBootList[i] && Result; i++)
+ Result = IsFastBootList[i](&FbSetupData);
+
+
+ if (!Result)
+ ReturnToNormalBoot(); //return to normal boot
+ else
+ EnableLegacy16Fastboot();
+
+ return Result;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFastBootDeafult
+//
+// Description: This function returns the status of Fast boot setup option
+//
+// Input:
+// IN SETUP_DATA *FbSetupData - ptr of SetupData
+//
+// Output: TRUE if fast boot is enabled, FALSE otherwise
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsFastBootDefault (
+ IN SETUP_DATA *FbSetupData
+)
+{
+ static EFI_GUID SetupVariableGuid = SETUP_GUID;
+
+ UINT16 BootNext;
+ UINTN Size;
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ BOOLEAN FastBoot;
+
+ if (!gFastBootPolicy->FastBootEnable) return FALSE;
+
+ BootMode = GetBootMode();
+
+ if (BootMode == BOOT_WITH_MINIMAL_CONFIGURATION)
+ return TRUE;
+
+ if (!gFastBootPolicy->FirstFastBootInS4 && BootMode == BOOT_ON_S4_RESUME) {
+ if (gFastBootPolicy->LastBootVarPresence)
+ return (gFastBootPolicy->BootCount > 0) ? TRUE : FALSE;
+ }
+
+//Check for "BootNext" variable
+ Size = sizeof(BootNext);
+ Status = pRS->GetVariable(L"BootNext", &EfiVariableGuid, NULL, &Size, &BootNext);
+ if(!EFI_ERROR(Status)) {
+ FastBoot = FALSE;
+ } else {
+ FastBoot = gFastBootPolicy->FastBootEnable;
+ }
+
+ return FastBoot;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ChangeSetupBootFlow
+//
+// Description: Changea Setup Boot Flow
+//
+// Input: UINT32 BootFlow
+//
+// Output: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ChangeSetupBootFlow(UINT32 BootFlow)
+{
+ EFI_STATUS Status;
+ EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID;
+
+ Status = pRS->SetVariable(L"BootFlow",
+ &guidBootFlow,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(BootFlow),
+ &BootFlow);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsAmtBoot
+//
+// Description: Do NOT perform FastBoot if AMT boot is request.
+//
+// Input:
+// IN SETUP_DATA *FbSetupData - ptr of SetupData
+//
+// Output: TRUE if fast boot is enabled, FALSE otherwise
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if iME_SUPPORT
+#include "ReferenceCode\ME\Protocol\AlertStandardFormat\AlertStandardFormat.h"
+#include "Board\EM\MeWrapper\AmtWrapper\Protocol\AmtWrapper\AmtWrapper.h"
+BOOLEAN IsAmtBoot(IN SETUP_DATA *FbSetupData)
+{
+ EFI_GUID gEfiAmtWrapperProtocolGuidTse = EFI_AMT_WRAPPER_PROTOCOL_GUID;
+ EFI_GUID gEfiAlertStandardFormatProtocolGuid = EFI_ALERT_STANDARD_FORMAT_PROTOCOL_GUID;
+ AMT_WRAPPER_PROTOCOL *pAmtWrapper = NULL;
+ EFI_STATUS Status;
+ EFI_ALERT_STANDARD_FORMAT_PROTOCOL *AsfCheck;
+ EFI_ASF_BOOT_OPTIONS *mInternalAsfBootOptions;
+
+ if (pAmtWrapper == NULL) {
+ Status = pBS->LocateProtocol(&gEfiAmtWrapperProtocolGuidTse, NULL, &pAmtWrapper);
+ }
+
+ //case IDER
+ if (pAmtWrapper != NULL) {
+ if (pAmtWrapper->ActiveManagementEnableIdeR()||pAmtWrapper->ActiveManagementEnableSol()){
+ ChangeSetupBootFlow(BOOT_FLOW_CONDITION_NORMAL);
+ return FALSE; //Is AMT boot, return FALSE for fast boot disabled.
+ }
+ }
+
+ //case ASF
+ //Get the ASF options
+ //if set then we have to do and Asfboot
+ Status = pBS->LocateProtocol (
+ &gEfiAlertStandardFormatProtocolGuid,
+ NULL,
+ &AsfCheck
+ );
+
+ if (EFI_ERROR (Status)) {
+ //Is not AMT boot, return TRUE for fast boot enabled.
+ return TRUE;
+ }
+
+ Status = AsfCheck->GetBootOptions (AsfCheck, &mInternalAsfBootOptions);
+
+ if (mInternalAsfBootOptions->SubCommand != ASF_BOOT_OPTIONS_PRESENT)
+ return TRUE; //Is not AMT boot, return TRUE for fast boot enabled.
+ else {
+ ChangeSetupBootFlow(BOOT_FLOW_CONDITION_NORMAL);
+ return FALSE; //Is AMT boot, return FALSE for fast boot disabled.
+ }
+
+}
+#else // for order ME version
+
+#define AMI_AMT_BOOT_OPTION_GUID \
+{0x9ba25957, 0x21bf, 0x41d0, 0x81, 0xe7, 0xe7, 0xb6, 0xd8, 0x88, 0x2a, 0x49}
+
+BOOLEAN IsAmtBoot(IN SETUP_DATA *FbSetupData)
+{
+ EFI_GUID gAmtBootOptionGuid = AMI_AMT_BOOT_OPTION_GUID;
+ EFI_STATUS Status;
+ UINT16 AmtBootOption = NULL;
+ UINTN VariableSize = 0;
+
+ // Get Device Type Variable of AMT Boot Option.
+ VariableSize = sizeof(UINT16);
+
+ Status = pRS->GetVariable ( L"AmtBootOption",
+ &gAmtBootOptionGuid,
+ NULL,
+ &VariableSize,
+ &AmtBootOption );
+
+ if (EFI_ERROR(Status))
+//Is not AMT boot, return TRUE for fastboot enabled.
+ return TRUE;
+ else {
+//Is AMT boot, return FALSE for fastboot disabled.
+ ChangeSetupBootFlow(BOOT_FLOW_CONDITION_NORMAL);
+ return FALSE;
+ }
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TseHandShake
+//
+// Description: This function executes FastBoot path via AMI TSE boot manager
+//
+// Input: FAST_BOOT LastBoot - last successful fast boot information
+//
+// Output: EFI_ERROR - if fast boot via AMI TSE cannot be executed
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS TseHandShake()
+{
+ EFI_STATUS Status;
+ AMI_POST_MANAGER_PROTOCOL *AmiPostMgr;
+ UINT32 BootFlow;
+ EFI_HANDLE Handle = NULL;
+
+ Status = pBS->LocateProtocol(&AmiPostMgrProtocolGuid, NULL, &AmiPostMgr);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( gFastBootPolicy->UEfiBoot == TRUE)
+ FastBootProtocol.Launch = FastEfiBoot;
+ else
+ FastBootProtocol.Launch = FastLegacyBoot;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &AmiFastBootProtocolGuid,
+ &FastBootProtocol,
+ NULL);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ BootFlow = BOOT_FLOW_CONDITION_FAST_BOOT;
+ Status = pRS->SetVariable(L"BootFlow",
+ &guidBootFlow,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(BootFlow),
+ &BootFlow);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ TRACE((-1,"FB: TseHandShake\n"));
+
+ Status = AmiPostMgr->Handshake();
+
+//if we're here fast boot failed, change Boot flow back to BOOT_FLOW_CONDITION_NORMAL
+
+ BootFlow = BOOT_FLOW_CONDITION_NORMAL;
+ Status = pRS->SetVariable(L"BootFlow",
+ &guidBootFlow,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(BootFlow),
+ &BootFlow);
+ return EFI_ABORTED;
+}
+
+//
+// Dummy console protocol
+//
+EFI_STATUS DummyInReset(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummyReadKeyStroke(
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummyReset(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN EV
+)
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS DummyOutputString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummyTestString(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN CHAR16 *String)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummyQueryMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum,
+ OUT UINTN *Col,
+ OUT UINTN *Row
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummySetMode(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN ModeNum
+)
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS DummySetAttribute(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Attribute
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummyClearScreen(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummySetCursorPosition(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN UINTN Column,
+ IN UINTN Row
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS DummyEnableCursor(
+ IN EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *This,
+ IN BOOLEAN Visible )
+{
+ return EFI_SUCCESS;
+}
+
+BOOLEAN IsRuntime(
+ VOID
+)
+{
+ return Runtime;
+}
+
+VOID FbConnectInputDevices(
+ VOID
+)
+{
+ FbConnectConInVariable();
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FastBoot/FastBoot.cif b/Core/EM/FastBoot/FastBoot.cif
new file mode 100644
index 0000000..b69358b
--- /dev/null
+++ b/Core/EM/FastBoot/FastBoot.cif
@@ -0,0 +1,22 @@
+<component>
+ name = "Post Time Tuning"
+ category = eModule
+ LocalRoot = "Core\EM\FastBoot\"
+ RefName = "FastBoot"
+[files]
+"FastBoot.sdl"
+"FastBoot.mak"
+"FastBootRuntime.c"
+"FastBootTseHook.c"
+"FastBoot.c"
+"PTT.chm"
+"FastBoot.sd"
+"FastBoot.uni"
+"FastBootDxe.c"
+[parts]
+"FastBootPei"
+"FastBootProtocol"
+"FastBootIncludes"
+"FastBootSMI"
+"FastBootOption"
+<endComponent>
diff --git a/Core/EM/FastBoot/FastBoot.mak b/Core/EM/FastBoot/FastBoot.mak
new file mode 100644
index 0000000..a20ed69
--- /dev/null
+++ b/Core/EM/FastBoot/FastBoot.mak
@@ -0,0 +1,144 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/PTT/FastBoot.mak 7 4/10/12 8:48a Bibbyyeh $
+#
+# $Revision: 7 $
+#
+# $Date: 4/10/12 8:48a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/PTT/FastBoot.mak $
+#
+# 7 4/10/12 8:48a Bibbyyeh
+# [TAG] EIP87452
+# [Category] Improvement
+# [Description] 1. Create an elink "ReturnNormalMode", OEM/ODM can link
+# their procedure to handle the fastboot failure case. 2. Disconnect USB
+# controller when return to normal mode.
+# [Files] FastBoot.c FastBoot.h FastBoot.mak FastBoot.sdl
+#
+# 6 8/04/11 8:11a Bibbyyeh
+# [TAG] EIP62845
+# [Category] New Feature
+# [Description] Connect all Sata devices in fastboot path.
+# [Files] FastBoot.c FastBoot.mak FastBoot.sdl
+#
+# 5 7/07/11 10:04a Bibbyyeh
+# [TAG] EIP63924
+# [Category] Improvement
+# [Description]
+# 1. Add elink for FastBoot mode change, default checking rule is check
+# post hotkey.
+# 2. Timer call back for check hotkey is not necessary. Create a protocol
+# for calling checkforkey in TSE.
+# 3. Since EIP68383 improve the performance of ps2 keyboard, we don't
+# need to exchange the initial order of ConIn/ConOut for getting more
+# time to detect hotkey.
+# [Files] FastBoot.sdl FastBoot.mak FastBoot.c FastBootTseHook.c
+# FastBoot.h FastBootProtocol.h
+#
+# 4 6/22/11 11:44p Bibbyyeh
+# [TAG] EIP62683
+# [Category] New Feature
+# [Description] Add an Elink after AllDriverConnect in fastboot path
+# [Files] FastBoot.c FastBoot.sdl FastBoot.mak
+#
+# 3 3/02/11 2:22a Bibbyyeh
+# [TAG] EIP51391
+# [Category] Bug Fix
+# [Severity] Normal
+# [Symptom] In windows, use DmiEdit to change SMBIOS data, and update.
+# SMBIOS will update failure in next boot.
+# [RootCause] The reason cause this issue is, ROM will copy to ram in
+# end of PEI phase. When SMBIOS Dxe driver update modified data to flash,
+# the firmware volume block protocol is pointer to RAM, not flash. So it
+# will cause update failure.
+# [Solution] Before SMBIOS Dxe driver, restore the Base Address of
+# Firmware Volume Block Protocol from RAM to ROM.
+# [Files] FastBoot.sdl FastBoot.mak FastBoot.cif
+#
+# 2 2/22/11 4:04a Bibbyyeh
+# [TAG] EIP54286
+# [Category] Improvement
+# [Description] Add elink for IsFastBoot Function to overwirte it, it
+# can help OEM/ODM to implement their "FAST BOOT" feature easily.
+# [Files] FastBoot.sdl FastBoot.mak FastBoot.c
+#
+# 1 10/12/10 9:04a Bibbyyeh
+# Initial check in
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FastBoot.mak
+#
+# Description:
+# Make file to build Fastboot library part
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\FastBoot.obj $(BUILD_DIR)\FastBootDxe.obj
+
+RUNTIMEBin : $(BUILD_DIR)\FastBootRuntime.obj
+
+AMITSEBin : $(BUILD_DIR)\FastBootTseHook.obj
+
+#(EIP62683)(EIP63924)(EIP62845)>
+{$(FastBoot_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /I $(FastBoot_DIR) \
+ /D\"IS_FAST_BOOT_LIST=$(IsFastBootList)\" \
+ /D\"AFTER_ALL_DRIVER_CONNECT_HOOK=$(FastBootAfterAllDriverConnctHook)\" \
+ /D\"FAST_BOOT_CHECK_MODE_CHANGE_HOOK=$(FastBootCheckModeChangeList)\" \
+ /D\"BEFORE_CONNECT_FAST_BOOT_DEVICE_HOOK=$(BeforeConnectFastBootDeviceHook)\" \
+ /D\"RETURN_NORMAL_MODE_HOOK=$(ReturnNormalMode)\" \
+ /Fo$(BUILD_DIR)\ $<
+#<(EIP62683)(EIP63924)(EIP62845)
+$(BUILD_DIR)\FastBoot.obj : $(FastBoot_DIR)\FastBoot.c
+
+$(BUILD_DIR)\FastBootRuntime.obj : $(FastBoot_DIR)\FastBootRuntime.c
+
+$(BUILD_DIR)\FastBootTseHook.obj : $(FastBoot_DIR)\FastBootTseHook.c
+
+$(BUILD_DIR)\FastBootDxe.obj : $(FastBoot_DIR)\FastBootDxe.c
+$(BUILD_DIR)\FastBoot.mak : $(FastBoot_DIR)\FastBoot.cif $(BUILD_RULES)
+ $(CIF2MAK) $(FastBoot_DIR)\FastBoot.cif $(CIF2MAK_DEFAULTS)
+
+#---------------------------------------------------------------------------
+# Create FastBoot Setup Component
+#---------------------------------------------------------------------------
+SetupSdbs : FastBootSDB
+
+FastBootSDB : $(BUILD_DIR)\FastBoot.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FastBoot.mak all\
+ TYPE=SDB NAME=FastBoot STRING_CONSUMERS=$(FastBoot_DIR)\FastBoot.sd
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/FastBoot/FastBoot.sd b/Core/EM/FastBoot/FastBoot.sd
new file mode 100644
index 0000000..74609cc
--- /dev/null
+++ b/Core/EM/FastBoot/FastBoot.sd
@@ -0,0 +1,372 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBoot.sd 16 7/11/13 10:13p Simonchen $
+//
+// $Revision: 16 $
+//
+// $Date: 7/11/13 10:13p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBoot.sd $
+//
+// 16 7/11/13 10:13p Simonchen
+// [TAG] EIP126196
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] If set two HDD password and use Raid mode, fastboot will
+// [RootCause] Because when AHCI driver unlock first HDD, Raid driver
+// will try to read all HDD, but second HDD is still lock, so access will
+// fail.
+// [Solution] Make sure all HDD unlock then Raid can access HDD.
+// And add "Support Raid Driver" token to control fastboot support Raid
+// feature or not.
+// [Files] FastBoot.c
+// FastBoot.sd
+// FastBoot.sdl
+// FastBootRuntime.c
+// FastBoot.h
+//
+// 15 4/18/13 5:39a Simonchen
+// [TAG] EIP113454
+// [Category] New Feature
+// [Description] This eip is created for implement or experiment for
+// Intel raid mode on fastboot.
+// [Files] FastBoot.sdl
+// FastBootRuntime.c
+// FastBoot.c
+// FastBoot.sd
+// FastBoot.uni
+//
+// 14 1/28/13 10:10p Bibbyyeh
+// [TAG] EIP113574
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Update the PTT eModule to utilize Setup Customization
+// [Files] FastBoot.sd FastBoot.uni
+//
+// 13 8/10/12 3:23a Bibbyyeh
+// [TAG] EIP96276
+// [Category] New Feature
+// [Description] Function request for PTT_12
+// EIP96276.2 Fixed USB skip table issue.
+// EIP96276.3 Add token ¡¥CONNECT_ALL_SATA_DEVICE_IN_FASTBOOT¡¦ to
+// gFastBootPolicy.
+// EIP96276.4 Add IsValidFBBootOptionPtr support by driver type. Exp : usb
+// type skip or other type
+// EIP96276.5 Add token ¡¥Test mode¡¨ to gFastBootPolicy Setup menu.
+// EIP96276.6 Disable Tse Hotkey support in fastboot path.
+// EIP96276.7 Modify TRACE message.
+// [Files] FastBoot.c FastBoot.sd FastBoot.sdl FastBoot.uni
+// FastBootRuntime.c FastBootProtocol.c
+//
+// 12 6/15/12 6:28a Bibbyyeh
+// Add token "DEFAULT_VGA_SUPPORT_SETTING" ,
+// "DEFAULT_USB_SUPPORT_SETTING", "DEFAULT_PS2_SUPPORT_SETTING", and
+// "DEFAULT_NETWORK_STACK_SUPPORT_SETTING" for Fast Boot default setup
+// option.
+//
+// 11 6/12/12 10:14p Bibbyyeh
+// Add a item "Auto" for fastboot "VGA Support". Only install Legacy OpRom
+// only when previous boot is Legacy OS.
+//
+// 10 6/01/12 6:58a Bibbyyeh
+// [TAG] EIP90455
+// [Category] New Feature
+// [Description] PTT improvement - fastboot policy protocol for dynamic
+// control fast boot behavior.
+// [Files] FastBoot.c FastBoot.sdl FastBoot.sd FastBoot.uni
+// FastBootRuntime.c FastBootTseHook.c FastBootProtocol.h FastBoot.h
+//
+// 9 5/29/12 4:44a Bibbyyeh
+// Fix build fail issue if CSM and CsmOpOut moudle are removed.
+//
+// 8 4/09/12 8:05a Bibbyyeh
+// Modify the default of SETUP_DATA.FastBoot as token DEFAULT_FAST_BOOT.
+//
+// 7 10/18/11 7:47a Bibbyyeh
+// [TAG] EIP68563
+// [Category] Improvement
+// [Description] Manufacturing Mode not set for the FastBoot setup
+// options.
+// [Files] FastBoot.sd
+//
+// 6 8/29/11 4:14a Bibbyyeh
+// [TAG] EIP67571
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] All FastBoot setup options are enabled in manufacturing
+// mode.
+// [RootCause] MANUFACTURING is set in FastBoot Setup option.
+// [Solution] Remove MANUFACTURING flag.
+// [Files] FastBoot.sd
+//
+// 5 3/17/11 8:40a Bibbyyeh
+// [TAG] EIP56151
+// [Category] Improvement
+// [Description] PTT eModule has several compiled errors if CSM eModule
+// is removed, that must be solved.
+// [Files] FastBoot.c FastBoot.sd
+//
+// 4 3/17/11 7:18a Bibbyyeh
+// [TAG] EIP56151
+// [Category] Improvement
+// [Description] PTT eModule has several compiled errors if CSM eModule
+// is removed, that must be solved.
+// [Files] FastBoot.c FastBoot.sd
+//
+// 3 3/11/11 10:01p Bibbyyeh
+// [TAG] EIP54993
+// [Category] Improvement
+// [Description]
+// 1.Sync with Fastboot_10
+// 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+// 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+// 4.Use SimpleText protocol to detect mode change hotkey instead of
+// pBS->ConIn.
+// 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+// 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+// fastboot path.
+// [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+// FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+// FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+// FastBootSMI.dxs FastBootSMI.mak
+//
+// 2 11/17/10 9:44a Bibbyyeh
+// [TAG] EIP47397
+// [Category] Improvement
+// [Description] 1. Move all console related functions into PTT module
+// to avoid uncompatible with different core version.
+// 2. Install dumy SimpleTextCoin protocol when pBS->ConIn & pBS-ConOut is
+// Null.
+// 3. Raise timer call back as TPL_HIGH_LEVEL level, it will give BIOS
+// more chance to mode change successfully.
+// 4. Remove FASTBOOT_CONSOLE_SETTING token.Add setup option for fastboot
+// setting, "Skip VGA", "Skip USB", Skip "PS2".
+// [Files] FastBoot.c
+// FastBoot.h
+// FastBoot.sd
+// FastBoot.sdl
+// FastBoot.uni
+//
+// 1 10/12/10 9:04a Bibbyyeh
+// Initial check in
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBoot.sd
+//
+// Description: FastBoot Setup data definitions, currently go under Boot page
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+ UINT8 FastBoot;
+ UINT8 FbSata;
+ UINT8 FbVga;
+ UINT8 FbUsb;
+ UINT8 FbPs2;
+ UINT8 FbNetWrokStack;
+ UINT8 FbTestMode; //(EIP96276.5+)
+#endif
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+//
+// Put control definitions here.
+//
+
+#define FB_ONEOF_FASTBOOT\
+ oneof varid = SETUP_DATA.FastBoot,\
+ prompt = STRING_TOKEN(STR_FAST_BOOT),\
+ help = STRING_TOKEN(STR_FAST_BOOT_HELP),\
+ default = DEFAULT_FAST_BOOT,\
+ option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#if SUPPORT_RAID_DRIVER
+#define FB_ONEOF_FBSATA\
+ oneof varid = SETUP_DATA.FbSata,\
+ prompt = STRING_TOKEN(STR_FB_SATA),\
+ help = STRING_TOKEN(STR_FB_SATA_HELP),\
+ default = DEFAULT_SATA_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_SATA_LAST_BOOT_ONLY), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_SATA_ALL), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_SATA_HDD_ONLY), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define FB_ONEOF_FBSATA\
+ oneof varid = SETUP_DATA.FbSata,\
+ prompt = STRING_TOKEN(STR_FB_SATA),\
+ help = STRING_TOKEN(STR_FB_SATA_HELP),\
+ default = DEFAULT_SATA_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_SATA_LAST_BOOT_ONLY), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_SATA_ALL), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+#endif
+
+#define FB_ONEOF_FBVGA\
+ oneof varid = SETUP_DATA.FbVga,\
+ prompt = STRING_TOKEN(STR_FB_VGA),\
+ help = STRING_TOKEN(STR_FB_VGA_HELP),\
+ default = DEFAULT_VGA_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_AUTO), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_VGA_DRIVER), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 920)
+
+#define FB_ONEOF_FBUSB\
+ oneof varid = SETUP_DATA.FbUsb,\
+ prompt = STRING_TOKEN(STR_FB_USB),\
+ help = STRING_TOKEN(STR_FB_USB_HELP),\
+ default = DEFAULT_USB_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_FULL_INIT), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PATIAL_INIT), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+
+#else
+
+#define FB_ONEOF_FBUSB\
+ oneof varid = SETUP_DATA.FbUsb,\
+ prompt = STRING_TOKEN(STR_FB_USB),\
+ help = STRING_TOKEN(STR_FB_USB_HELP),\
+ default = DEFAULT_USB_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_FULL_INIT), value = 1, flags = MANUFACTURING | RESET_REQUIRED;
+ endoneof;
+#endif
+
+#define FB_ONEOF_FBPS2\
+ oneof varid = SETUP_DATA.FbPs2,\
+ prompt = STRING_TOKEN(STR_FB_PS2),\
+ help = STRING_TOKEN(STR_FB_PS2_HELP),\
+ default = DEFAULT_PS2_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define FB_ONEOF_FBNETWORKSTACK\
+ oneof varid = SETUP_DATA.FbNetWrokStack,\
+ prompt = STRING_TOKEN(STR_FB_NETWORK_STACK),\
+ help = STRING_TOKEN(STR_FB_NETWORK_STACK_HELP),\
+ default = DEFAULT_NETWORK_STACK_SUPPORT_SETTING,\
+ option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define FB_ONEOF_FBTESTMODE\
+ oneof varid = SETUP_DATA.FbTestMode,\
+ prompt = STRING_TOKEN(STR_FB_TEST),\
+ help = STRING_TOKEN(STR_FB_TEST_HELP),\
+ option text = STRING_TOKEN(STR_DISABLE), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLE), value = 1, flags = RESET_REQUIRED;\
+ endoneof;\
+
+#endif //#ifdef CONTROL_DEFINITION
+
+#ifdef CONTROLS_WITH_DEFAULTS
+//
+// List macros of all the controls attached to the actual data.
+//
+ FB_ONEOF_FASTBOOT
+ FB_ONEOF_FBSATA
+ FB_ONEOF_FBVGA
+ FB_ONEOF_FBUSB
+ FB_ONEOF_FBPS2
+ FB_ONEOF_FBNETWORKSTACK
+ FB_ONEOF_FBTESTMODE
+
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+//Select Top level menu itmem (forset) for you pages
+#ifdef BOOT_FORM_SET
+ #ifndef SUPPRESS_GRAYOUT_ENDIF //old Core
+ #define SUPPRESS_GRAYOUT_ENDIF endif;
+ #endif
+
+#ifdef FORM_SET_ITEM
+
+ FB_ONEOF_FASTBOOT
+
+
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ grayoutif ideqval SETUP_DATA.FastBoot == 0;
+ FB_ONEOF_FBSATA
+ SUPPRESS_GRAYOUT_ENDIF
+
+#if CSM_SUPPORT
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ FB_ONEOF_FBVGA
+ endif;
+#else
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ grayoutif ideqval SETUP_DATA.FastBoot == 1;
+ FB_ONEOF_FBVGA
+ SUPPRESS_GRAYOUT_ENDIF
+#endif //#if CSM_SUPPORT
+
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ grayoutif ideqval SETUP_DATA.FastBoot == 0;
+ FB_ONEOF_FBUSB
+ SUPPRESS_GRAYOUT_ENDIF
+
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ grayoutif ideqval SETUP_DATA.FastBoot == 0;
+ FB_ONEOF_FBPS2
+ SUPPRESS_GRAYOUT_ENDIF
+
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ grayoutif ideqval SETUP_DATA.FastBoot == 0;
+ FB_ONEOF_FBNETWORKSTACK
+ SUPPRESS_GRAYOUT_ENDIF
+
+//(EIP96276.5+)>>
+#if FAST_BOOT_TEST_MODE
+ suppressif ideqval SETUP_DATA.FastBoot == 0;
+ grayoutif ideqval SETUP_DATA.FastBoot == 0;
+ FB_ONEOF_FBTESTMODE
+ SUPPRESS_GRAYOUT_ENDIF
+#endif //#if FAST_BOOT_TEST_MODE
+//<<(EIP96276.5+)
+
+#endif //#ifdef FORM_SET_ITEM
+
+#endif //#ifdef BOOT_FORM_SET
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
diff --git a/Core/EM/FastBoot/FastBoot.sdl b/Core/EM/FastBoot/FastBoot.sdl
new file mode 100644
index 0000000..63af312
--- /dev/null
+++ b/Core/EM/FastBoot/FastBoot.sdl
@@ -0,0 +1,400 @@
+TOKEN
+ Name = "POST_TIME_TUNING_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Post Time Tuning module in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "FAST_BOOT_SUPPORT"
+ Value = "1"
+ Help = "Switch to enable FastBoot support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "PTT_VER"
+ Value = "15"
+ Help = "PTT module version"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "MAX_SATA_DEVICE_COUNT"
+ Value = "8"
+ Help = "Max count of Sata device are stored in LastBoot variable"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "FAST_BOOT_TEST_MODE"
+ Value = "0"
+ Help = "Please enable toekn 'DXE_PERFORMANCE' and 'PEI_PERFORMANCE' before enable this token."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SKIP_TSE_HANDSHAKE"
+ Value = "0"
+ Help = "On: Skip TSE execution on fast boot path, \Logo will not be shown.\Use FASTBOOT_MODE_CHANGE_HOTKEY to change mode.\At least keep one console in and one console out, if user need to support password security during fastboot.\\OFF: Keep TSE execution on fast boot path, "
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ALLOW_FIRST_FASTBOOT_IN_S4"
+ Value = "1"
+ Help = "On: First FastBoot can be start when system power on from S4.\OFF: First FastBoot only can be start when system power on from S0."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_SKIP_TABLE"
+ Value = "{{0, 0, 0, 0, 0, 0}}"
+ Help = "This Table is only used when SetupOption 'Partial Initial' is selected.\This structure must end with zero structure."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FAST_BOOT_PCI_SKIP_LIST"
+ Value = "{{0x01,0xFF},{0x03,0xFF},{0x06,0xFF}}"
+ Help = "(EIP85135)When enabled XHCI support difficult into setup menu in fastboot mode'\{ClassCode,SubClassCode}\{0x01,0xFF} Storage\{0x02,0xFF} NetWrok\{0x03,0xFF} VGA\{0x06,0xFF} Bridge"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FAST_BOOT_TSE_HOTKEY_SUPPORT"
+ Value = "1"
+ Help = "(EIP96276.6)Change FastBoot mode and enter setup by TSE hotkey"
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "LAST_BOOT_FAIL_MECHANISM"
+ Value = "1"
+ Help = "(EIP98617)Enter setup automatically if previous fast boot fail."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_LAST_BOOT_FAIL_COUNT"
+ Value = "2"
+ Help = "Once fast boot fail count is reach this number, system will perform a full boot."
+ TokenType = Integer
+ TargetH = Yes
+ Token = "LAST_BOOT_FAIL_MECHANISM" "=" "0"
+End
+
+TOKEN
+ Name = "OVERRIDE_FastBootLaunch"
+ Value = "1"
+ Help = "Fastboot Modules Overrides the FastBootLaunch() function of TSE"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "SKIP_TSE_HANDSHAKE" "=" "0"
+End
+
+TOKEN
+ Name = "DEFAULT_FAST_BOOT"
+ Value = "0"
+ Help = "Default value of the Fast Boot option"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SATA_SUPPORT_SETTING"
+ Value = "1"
+ Help = "Default value of SATA Support option"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SATA_SUPPORT_SETTING"
+ Value = "2"
+ Help = "Default value of SATA Support option"
+ TokenType = Integer
+ TargetH = Yes
+ Token = "SUPPORT_RAID_DRIVER" "=" "1"
+End
+
+TOKEN
+ Name = "DEFAULT_VGA_SUPPORT_SETTING"
+ Value = "1"
+ Help = "Default value of VGA Support option"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_USB_SUPPORT_SETTING"
+ Value = "2"
+ Help = "Default value of USB Support option"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_PS2_SUPPORT_SETTING"
+ Value = "1"
+ Help = "Default value of the PS2 Devices Support option"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_NETWORK_STACK_SUPPORT_SETTING"
+ Value = "0"
+ Help = "Default value of NetWork Stack Driver Support option"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COPY_ROM_TO_RAM_IN_PEI"
+ Value = "0"
+ Help = "Copy FV_BB and FV_MAIN to memory in PEI Phase, please disable it if PeiRamBoot is available in your project."
+ TokenType = Boolean
+End
+
+TOKEN
+ Name = "CONNECT_EVERYTHING_IN_FASTBOOT"
+ Value = "1"
+ Help = "Connect all Pci Handles on fastboot path except the Pci class in the FAST_BOOT_PCI_SKIP_LIST"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SINGAL_ALL_DRIVERS_CONNECTED_EVENT"
+ Value = "1"
+ Help = "Signal BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID on fastboot path"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+ Value = "1"
+ Help = "Call DXE dispatcher again on fastboot path"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMILEGACY16_FASTBOOT_SOLUTION"
+ Value = "0"
+ Help = "CMOS 0x38 will used to store fastboot flag.\For legacy fast boot some changes in CSM module are required "
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IS_VALID_FASTBOOT_BOOT_OPTION_FUNC"
+ Value = "IsValidFastBootOption"
+ Help = "Function to validate fastboot boot option"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SUPPORT_RAID_DRIVER"
+ Value = "0"
+ Help = "Check if support for raid driver."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FASTBOOT_NEED_RESTART"
+ Value = "0"
+ Help = "Check if need to restart."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "FastBoot_DIR"
+ Help = "Path to FastBoot Module in Project"
+End
+
+MODULE
+ Help = "Includes FastBoot.mak to Project"
+ File = "FastBoot.mak"
+End
+
+MODULE
+ Help = "Includes FastBootPei.mak to Project"
+ File = "FastBootPei.mak"
+End
+
+ELINK
+ Name = "$(FastBoot_DIR)\FastBoot.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 0
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FastBootPei.ffs"
+ Parent = "$(BUILD_DIR)\CPUPEI.ffs"
+ Priority = 0
+ Token = "COPY_ROM_TO_RAM_IN_PEI" "=" "1"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "FastBootEntry,"
+ Parent = "RuntimeInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "FastBootConInAvailHook,"
+ Parent = "ProcessConInAvailability,"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FastBootBbsBootHook,"
+ Parent = "BbsBoot,"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FastBootMinisetupDriverEntryHook,"
+ Parent = "MinisetupDriverEntryHookHook,"
+ Help = "(EIP63924)Add an Elink for install fast boot tse protocol"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FastBoot.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IsFastBootDefault,"
+ Parent = "IsFastBootList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IsAmtBoot,"
+ Parent = "IsFastBootList"
+ InvokeOrder = AfterParent
+ Token = "iAMT_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "CheckPostManagerKey,"
+ Parent = "FastBootCheckModeChangeList"
+ Token = "FAST_BOOT_TSE_HOTKEY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+
+
+ELINK
+ Name = "FbConnectEverything,"
+ Parent = "BeforeConnectFastBootDeviceHook"
+ Help = "(EIP85135)When enabled XHCI support difficult into setup menu in fastboot mode"
+ Token = "CONNECT_EVERYTHING_IN_FASTBOOT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CallTheDispatcher,"
+ Parent = "FastBootAfterAllDriverConnctHook"
+ Token = "CALL_DISPATCHER_AGAIN_IN_FASTBOOT" "=" "1"
+ Token = "CORE_COMBINED_VERSION" ">" "0x40280"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "SignalAllDriversConnectedEvent,"
+ Parent = "FastBootAfterAllDriverConnctHook"
+ Token = "SINGAL_ALL_DRIVERS_CONNECTED_EVENT" "=" "1"
+ Token = "CORE_COMBINED_VERSION" ">" "0x40280"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "FastBootDxeEntry,"
+ Parent = "DxeCoreInitialize"
+ Priority = -255
+ Token = "COPY_ROM_TO_RAM_IN_PEI" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IsFastBootList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FastBootAfterAllDriverConnctHook"
+ Help = "(EIP62683)Add an Elink after all driver connect in PTT module"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FastBootCheckModeChangeList"
+ Help = "(EIP63924)Add an Elink for check mode change in PTT module"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BeforeConnectFastBootDeviceHook"
+ Help = "(EIP62845)Connect all sata devices in fastboot"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ResetFastBootVariable,"
+ Parent = "ReturnNormalMode"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DisconnectUsbController,"
+ Parent = "ReturnNormalMode"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ReturnNormalMode"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "BeforeBDSFlow,"
+ Parent = "BDS_CONTROL_FLOW"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "InitialRebootCount,"
+ Parent = "ProcessEnterSetupHook,"
+ InvokeOrder = AfterParent
+ Token = "FASTBOOT_NEED_RESTART" "=" "1"
+End
diff --git a/Core/EM/FastBoot/FastBoot.uni b/Core/EM/FastBoot/FastBoot.uni
new file mode 100644
index 0000000..1fdd75b
--- /dev/null
+++ b/Core/EM/FastBoot/FastBoot.uni
Binary files differ
diff --git a/Core/EM/FastBoot/FastBootDxe.c b/Core/EM/FastBoot/FastBootDxe.c
new file mode 100644
index 0000000..7c158b2
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootDxe.c
@@ -0,0 +1,184 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootDxe.c 2 4/07/11 8:20a Bibbyyeh $
+//
+// $Revision: 2 $
+//
+// $Date: 4/07/11 8:20a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootDxe.c $
+//
+// 2 4/07/11 8:20a Bibbyyeh
+// [TAG] EIP57430
+// [Category] New Feature
+// [Description] PTT module is not compatible with core 4.6.5.0. Modify
+// it to make build pass.
+// [Files] FastBootDxe.c
+//
+// 1 3/02/11 2:23a Bibbyyeh
+// [TAG] EIP51391
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] In windows, use DmiEdit to change SMBIOS data, and update.
+// SMBIOS will update failure in next boot.
+// [RootCause] The reason cause this issue is, ROM will copy to ram in
+// end of PEI phase. When SMBIOS Dxe driver update modified data to flash,
+// the firmware volume block protocol is pointer to RAM, not flash. So it
+// will cause update failure.
+// [Solution] Before SMBIOS Dxe driver, restore the Base Address of
+// Firmware Volume Block Protocol from RAM to ROM.
+// [Files] FastBoot.sdl FastBoot.mak FastBoot.cif FastBootDxe.c
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBootDxe.c
+//
+// Description:
+// Implementation of fast boot Dxe functionality
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <Protocol\FirmwareVolumeBlock.h>
+#include <FFS.h>
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+typedef struct {
+ UINTN Base;
+ UINTN Length;
+} LBA_CACHE;
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_DEVICE_PATH;
+
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ FV_DEVICE_PATH DevicePath;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
+ UINTN NumBlocks;
+ LBA_CACHE *LbaCache;
+ UINT32 FvbAttributes;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32('_','F','V','B')
+
+#ifndef _CR
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+#endif
+#ifndef CR
+#define CR(Record, TYPE, Field, Signature) _CR (Record, TYPE, Field)
+#endif
+
+#define FVB_DEVICE_FROM_THIS(a) \
+ CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+
+
+//----------------------------------------------------------------------------
+// Local Variables
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FastBootDxeEntry
+//
+// Description: DXE Entry Point for FastBoot Driver.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FastBootDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+
+ EFI_GUID EfiFirmwareVolumeBlockProtocolGuid = FW_VOLUME_BLOCK_PROTOCOL_GUID;
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ UINT8 i;
+
+ EFI_HANDLE *HandleBuffer;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock;
+
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ TRACE((-1,"FB:Restore the Base Address of Firmware Volume Block Protocol from RAM to ROM\n"));
+// Restore the Base Address of Firmware Volume Block Protocol from RAM
+// to ROM.
+ Status = pBS->LocateHandleBuffer ( ByProtocol, \
+ &EfiFirmwareVolumeBlockProtocolGuid, \
+ NULL, \
+ &NumHandles, \
+ &HandleBuffer );
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NumHandles; ++i) {
+ Status = pBS->HandleProtocol ( HandleBuffer[i], \
+ &EfiFirmwareVolumeBlockProtocolGuid, \
+ &FvBlock );
+ if (EFI_ERROR(Status)) continue;
+ FvbDevice = FVB_DEVICE_FROM_THIS (FvBlock);
+#if PI_SPECIFICATION_VERSION < 0x00010000
+ if (!(FvbDevice->FvbAttributes & EFI_FVB_MEMORY_MAPPED)) continue;
+#else
+ if (!(FvbDevice->FvbAttributes & EFI_FVB2_MEMORY_MAPPED)) continue;
+#endif
+ if (FvbDevice->NumBlocks == FV_BB_BLOCKS)
+ FvbDevice->BaseAddress = FV_BB_BASE;
+ else if (FvbDevice->NumBlocks == FV_MAIN_BLOCKS)
+ FvbDevice->BaseAddress = FV_MAIN_BASE;
+
+ }
+
+ return EFI_SUCCESS;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOption.c b/Core/EM/FastBoot/FastBootOption/FastBootOption.c
new file mode 100644
index 0000000..d05d0b9
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOption.c
@@ -0,0 +1,433 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.c 2 7/14/13 10:52p Simonchen $
+//
+// $Revision: 2 $
+//
+// $Date: 7/14/13 10:52p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.c $
+//
+// 2 7/14/13 10:52p Simonchen
+// [TAG] EIP129092
+// [Category] Improvement
+// [Description] Add CloseEvent in OnExitBootServices in
+// FastBootOption.c
+// [Files] FastBootOption.c
+//
+// 1 10/30/12 4:22a Bibbyyeh
+// [TAG] EIP105177
+// [Category] New Feature
+// [Description] Report pseudo boot option for Windows 'Boot To Device'
+// support
+// [Files] FastBootOption.cif FastBootOption.sdl
+// FastBootOption.mak FastBootOption.h FastBootOption.c
+// FastBootOptionBds.c FastBootOption.dxs
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FastBootOption.c
+//
+// Description: FastBootOption Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "FastBootOption.h"
+#include <Setup.h>
+#include <Protocol\FastBootProtocol.h>
+
+#define EFI_TPL_NOTIFY TPL_NOTIFY
+
+#define BOOT_FLOW_CONDITION_FAST_BOOT 7
+#define BOOT_FLOW_CONDITION_NORMAL 0
+
+EFI_EVENT gExitBootServicesEvent;
+EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+
+TempDeviceMap BootOptionTemp[]={
+// { TempUefiHddDevice, "UEFI:Hard Drive" },
+ { TempUefiOddDevice, "UEFI:CD/DVD Drive" },
+ { TempUefiRemDevice, "UEFI:Removable Device" },
+ { TempUefiNetDevice, "UEFI:Network Device" }
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetUEFIBootName
+//
+// Description: Get Variable Boot#### and return data pointer.
+//
+// Input:
+// IN UINT16 BootIndex
+//
+// Output:
+// EFI_LOAD_OPTION
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_LOAD_OPTION* GetUEFIBootName(IN UINT16 BootIndex)
+{
+// EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_STATUS Status;
+ UINTN OptionSize;
+ CHAR16 BootVarName[15];
+ EFI_LOAD_OPTION *BootOption = NULL; //buffer for BootXXX variables
+
+ Swprintf( BootVarName, gBootName, BootIndex); //(EIP35562)
+
+ OptionSize = 0;
+ Status = pRS->GetVariable( BootVarName, &EfiVariableGuid, NULL, &OptionSize, NULL);
+ if(Status != EFI_NOT_FOUND)
+ {
+ BootOption=Malloc( OptionSize );
+ Status = pRS->GetVariable( BootVarName, &EfiVariableGuid, NULL, &OptionSize, BootOption);
+ return BootOption;
+ }
+ else
+ return NULL;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AddBootOption
+//
+// Description: calculate devicepath length
+//
+//
+// Input: IN UINT16 Number
+// IN EFI_DEVICE_PATH_PROTOCOL *Dp
+// IN UINT32 Attributes
+// IN VOID *pOptions
+// IN UINTN OptionsSize
+// IN CHAR16 *DefaultName
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddBootOption(
+ IN UINT16 Number,
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp,
+ IN UINT32 Attributes,
+ IN VOID *pOptions, IN UINTN OptionsSize, IN CHAR16 *DefaultName
+)
+{
+
+ EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_LOAD_OPTION *Option;
+ UINTN Size=0, Length;
+ CHAR16 BootVarName[15]; //Boot0000
+ CHAR16 NameStr[1024];
+ EFI_STATUS Status;
+
+ Length = DPLength(Dp);
+
+ if ( !pOptions )
+ OptionsSize=0;
+ else
+ {
+ Swprintf( NameStr, L"%S", pOptions );
+ Size = (Wcslen(NameStr)+1)*sizeof(CHAR16);
+ }
+ //Size = (EfiStrLen(NameStr)+1)*sizeof(CHAR16);
+ Option = Malloc(sizeof(*Option)+Size+Length);
+ if (!Option) return EFI_OUT_OF_RESOURCES;
+
+ Option->Attributes = Attributes;
+ Option->FilePathListLength = (UINT16)Length;
+
+ if(OptionsSize)
+ pBS->CopyMem(Option+1, NameStr, Size);
+
+ pBS->CopyMem((UINT8*)(Option+1)+Size, Dp, Length);
+
+ Swprintf(BootVarName, gBootName, Number);
+ TRACE((-1,"[FastBootOption] Add %S (%S)\n", BootVarName, NameStr));
+ Status = pRS->SetVariable(
+ BootVarName, &EfiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(*Option)+Size+Length, Option
+ );
+
+ pBS->FreePool(Option);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateBootOption
+//
+// Description: Create variable Boot####
+//
+//
+// Input: IN UINT16 OptionNumber
+// IN UINT16 Index
+// IN UINT16 DevType
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void CreateBootOption(IN UINT16 OptionNumber, IN UINT16 DevType, CHAR8 *Description)
+{
+
+static struct {
+ BBS_BBS_DEVICE_PATH bbs;
+ EFI_DEVICE_PATH_PROTOCOL end;
+} LegacyDp =
+ {
+ {{BBS_DEVICE_PATH,BBS_BBS_DP,sizeof(BBS_BBS_DEVICE_PATH)},0xff,0,0},
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,sizeof(EFI_DEVICE_PATH_PROTOCOL)}
+ };
+
+
+ LegacyDp.bbs.DeviceType = DevType;
+
+ AddBootOption(
+ OptionNumber, &LegacyDp.bbs.Header,
+ LOAD_OPTION_ACTIVE,
+ Description, sizeof(Description) + 1, NULL);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateTempBootOption
+//
+// Description: This function is the entry point for FastBootOption Driver.
+//
+// Input:
+//
+//
+// Output:
+//
+//
+// Notes:
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateTempBootOption()
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 *BootOrder = NULL, NewBootOrder[50];
+ UINTN BootOrderSize = 0;
+ UINT16 MapIndex, i, BootIndex = 1;
+ BOOLEAN TempDeviceFound = FALSE;
+
+ Status = GetEfiVariable( L"BootOrder", &EfiVariableGuid, NULL, &BootOrderSize, &BootOrder);
+
+ if( !EFI_ERROR(Status) )
+ {
+ for( i=0; i<BootOrderSize/sizeof(UINT16); i++)
+ {
+ EFI_LOAD_OPTION *BootOption=NULL;
+ BBS_BBS_DEVICE_PATH *BBSdp;
+ BootOption=GetUEFIBootName( BootOrder[i] );
+
+ if( BootOption )
+ {
+ BBSdp = (BBS_BBS_DEVICE_PATH*) ((UINT8*)(BootOption+1)
+ +(Wcslen((CHAR16*)(BootOption+1))+1)*sizeof(CHAR16));
+
+ if( BBSdp->Header.Type == BBS_DEVICE_PATH )
+ {
+ switch( BBSdp->DeviceType )
+ {
+ case TempUefiHddDevice:
+ case TempUefiOddDevice:
+ case TempUefiRemDevice:
+ case TempUefiNetDevice:
+ TempDeviceFound=TRUE;
+ break;
+ }
+ }
+
+ pBS->FreePool(BootOption);
+ }
+
+ if( TempDeviceFound )
+ break;
+ }
+
+ pBS->CopyMem(NewBootOrder, BootOrder, BootOrderSize);
+ pBS->FreePool(BootOrder);
+
+ //TRACE((-1,"CreateTempBootOption::TempDeviceFound(%d)\n", TempDeviceFound));
+ //already create temp device?
+ if( TempDeviceFound )
+ return EFI_SUCCESS;
+ }
+
+ for( MapIndex=0; MapIndex<sizeof(BootOptionTemp)/sizeof(TempDeviceMap); MapIndex++)
+ {
+ for( i=0; i<BootOrderSize/sizeof(UINT16); i++)
+ {
+ if( NewBootOrder[i] == BootIndex )
+ {
+ BootIndex++;
+ i=-1;
+ continue;
+ }
+ }
+
+ NewBootOrder[i]=BootIndex;
+ BootOrderSize+=sizeof(UINT16);
+
+ CreateBootOption( BootIndex, BootOptionTemp[MapIndex].DeviceTypeId, BootOptionTemp[MapIndex].TempName );
+ }
+
+ //Update Variable "BootOrder".
+ if( BootOrderSize )
+ {
+ pRS->SetVariable(
+ L"BootOrder",
+ &EfiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ BootOrderSize,
+ &NewBootOrder[0]);
+ }
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: OnExitBootServices
+//
+// Description: EXIT_BOOT_SERVICES notification callback function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+OnExitBootServices(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID FastBootPolicyGuid = FAST_BOOT_POLICY_PROTOCOL_GUID;
+ FAST_BOOT_POLICY *gFastBootPolicy;
+ EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID;
+ UINT32 BootFlow;
+ UINTN Size;
+
+ TRACE((-1,"FastBootOption OnExitBootServices event .............\n"));
+ Status = pBS->LocateProtocol(&FastBootPolicyGuid,NULL,&gFastBootPolicy);
+
+ TRACE((-1,"FastBootOption gFastBootPolicy->FastBootEnable = %d\n", gFastBootPolicy->FastBootEnable));
+ if (EFI_ERROR(Status) || gFastBootPolicy->FastBootEnable == FALSE) {
+ pBS->CloseEvent (Event);
+ return;
+ }
+ Status = pRS->GetVariable(L"BootFlow", &guidBootFlow, NULL, &Size, &BootFlow);
+ TRACE((-1,"FastBootOption BootFlow = %d\n", BootFlow));
+
+ if(!EFI_ERROR(Status) && (BootFlow == BOOT_FLOW_CONDITION_FAST_BOOT))
+ CreateTempBootOption();
+
+ pBS->CloseEvent (Event);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootOptionEntryPoint
+//
+// Description: This function is the entry point for FastBootOption Driver.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output:
+// EFI_SUCCESS Security interface installed.
+// EFI_ERROR Security interface not installed or unable to locate
+// some protocol.
+//
+// Notes:
+// Entry Points are used to locate or install protocol interfaces and
+// notification events.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FastBootOptionEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ TRACE((-1,"FastBootOptionEntryPoint.............\n"));
+
+ pBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_NOTIFY,
+ OnExitBootServices,
+ NULL,
+ &gExitBootServicesEvent
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOption.cif b/Core/EM/FastBoot/FastBootOption/FastBootOption.cif
new file mode 100644
index 0000000..1d5c216
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOption.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "FastBootOption"
+ category = ModulePart
+ LocalRoot = "Core\EM\FastBoot\FastBootOption\"
+ RefName = "FastBootOption"
+[files]
+"FastBootOption.sdl"
+"FastBootOption.mak"
+"FastBootOption.h"
+"FastBootOption.c"
+"FastBootOptionBds.c"
+"FastBootOption.dxs"
+<endComponent>
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOption.dxs b/Core/EM/FastBoot/FastBootOption/FastBootOption.dxs
new file mode 100644
index 0000000..49592e6
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOption.dxs
@@ -0,0 +1,66 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.dxs 1 10/30/12 4:22a Bibbyyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 10/30/12 4:22a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.dxs $
+//
+// 1 10/30/12 4:22a Bibbyyeh
+// [TAG] EIP105177
+// [Category] New Feature
+// [Description] Report pseudo boot option for Windows 'Boot To Device'
+// support
+// [Files] FastBootOption.cif FastBootOption.sdl
+// FastBootOption.mak FastBootOption.h FastBootOption.c
+// FastBootOptionBds.c FastBootOption.dxs
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FastBootOption.DXS
+//
+// Description: Dependency expression for FastBootOption driver.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Protocol/PciRootBridgeIo.h>
+
+
+DEPENDENCY_START
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOption.h b/Core/EM/FastBoot/FastBootOption/FastBootOption.h
new file mode 100644
index 0000000..b86eff7
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOption.h
@@ -0,0 +1,96 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.h 1 10/30/12 4:22a Bibbyyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 10/30/12 4:22a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.h $
+//
+// 1 10/30/12 4:22a Bibbyyeh
+// [TAG] EIP105177
+// [Category] New Feature
+// [Description] Report pseudo boot option for Windows 'Boot To Device'
+// support
+// [Files] FastBootOption.cif FastBootOption.sdl
+// FastBootOption.mak FastBootOption.h FastBootOption.c
+// FastBootOptionBds.c FastBootOption.dxs
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: <FastBootOption.h>
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the IdeSecurity driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _FastBootOption_
+#define _FastBootOption_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <Protocol\Devicepath.h>
+
+#if CORE_COMBINED_VERSION > 0x40280 //4.6.4.1 or Last
+#define gBootName L"Boot%04X"
+#else
+#define gBootName L"Boot%04x"
+#endif
+
+#define TempUefiHddDevice 0x80
+#define TempUefiOddDevice 0x81
+#define TempUefiRemDevice 0x82
+#define TempUefiNetDevice 0x83
+
+typedef struct {
+ UINT16 DeviceTypeId;
+ CHAR8 *TempName;
+} TempDeviceMap;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOption.mak b/Core/EM/FastBoot/FastBootOption/FastBootOption.mak
new file mode 100644
index 0000000..b7edc0c
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOption.mak
@@ -0,0 +1,80 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.mak 1 10/30/12 4:21a Bibbyyeh $
+#
+# $Revision: 1 $
+#
+# $Date: 10/30/12 4:21a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOption.mak $
+#
+# 1 10/30/12 4:21a Bibbyyeh
+# [TAG] EIP105177
+# [Category] New Feature
+# [Description] Report pseudo boot option for Windows 'Boot To Device'
+# support
+# [Files] FastBootOption.cif FastBootOption.sdl
+# FastBootOption.mak FastBootOption.h FastBootOption.c
+# FastBootOptionBds.c FastBootOption.dxs
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FastBootOption.mak
+#
+# Description: Make file to build FastBootOption Driver Sources.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : FastBootOption
+
+FastBootOption : $(BUILD_DIR)\FastBootOption.mak FastBootOptionBin
+
+$(BUILD_DIR)\FastBootOption.mak : $(FastBootOption_DIR)\$(@B).cif $(FastBootOption_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FastBootOption_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+FastBootOptionBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FastBootOption.mak all\
+ GUID=A58C5D1D-C22B-4845-90BC-8C94FCE96457\
+ ENTRY_POINT=FastBootOptionEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+ "OBJECTS=$(BUILD_DIR)\$(FastBootOption_DIR)\FastBootOption.obj"
+
+CORE_DXE_LIBBin : $(BUILD_DIR)\FastBootOptionBds.obj
+
+#-----------------------------------------------------------------------
+# AMICSP library files compilation
+#-----------------------------------------------------------------------
+{$(FastBootOption_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /I $(FastBootOption_DIR) /I $(Foundation_DIR) /I $(CORE_DXE_DIR) /Fo$(BUILD_DIR)\ $<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOption.sdl b/Core/EM/FastBoot/FastBootOption/FastBootOption.sdl
new file mode 100644
index 0000000..3e478b4
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOption.sdl
@@ -0,0 +1,40 @@
+TOKEN
+ Name = "FastBootOption_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FastBootOption support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CORE_COMBINED_VERSION" ">=" "0x040281"
+End
+
+
+PATH
+ Name = "FastBootOption_DIR"
+End
+
+MODULE
+ Help = "Includes FastBootOption.mak to Project"
+ File = "FastBootOption.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FastBootOption.ffs"
+ Parent = "FV_MAIN"
+ Token = "FastBootOption_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RemoveFastBootOption,"
+ Parent = "ReadBootOptions,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SetBootNextBootOption,"
+ Parent = "SaveBootOptions,"
+ InvokeOrder = BeforeParent
+End \ No newline at end of file
diff --git a/Core/EM/FastBoot/FastBootOption/FastBootOptionBds.c b/Core/EM/FastBoot/FastBootOption/FastBootOptionBds.c
new file mode 100644
index 0000000..d9a8302
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootOption/FastBootOptionBds.c
@@ -0,0 +1,274 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Archive: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOptionBds.c $
+//
+// $Author: Bibbyyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 10/30/12 4:22a $
+//
+//*****************************************************************//
+//*****************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootOption/FastBootOptionBds.c $
+//
+// 1 10/30/12 4:22a Bibbyyeh
+// [TAG] EIP105177
+// [Category] New Feature
+// [Description] Report pseudo boot option for Windows 'Boot To Device'
+// support
+// [Files] FastBootOption.cif FastBootOption.sdl
+// FastBootOption.mak FastBootOption.h FastBootOption.c
+// FastBootOptionBds.c FastBootOption.dxs
+//
+//
+//*****************************************************************//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FastBootOptionBds.c
+//
+// Description:
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+// Include Files
+//----------------------------------------------------------------------
+#include <efi.h>
+#include <amidxelib.h>
+#include <protocol\blockio.h>
+#include <protocol\devicepath.h>
+#include <BootOptions.h>
+#include "FastBootOption.h"
+//---------------------------------------------------------------------------
+// Global Variable declarations
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+// External functions
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+// Function Definitions
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+// Type definitions
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+// Constant and Variables declarations
+//---------------------------------------------------------------------------
+ BOOLEAN TempDeviceFound=FALSE;
+ UINT16 BootDeviceType=0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetUefiDeviceType
+//
+// Description: Function returns device type
+//
+// Input: EFI_DEVICE_PATH_PROTOCOL *Dp -
+//
+// Output: UINT32 - device type
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetUefiDeviceType(
+ IN EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ EFI_DEVICE_PATH_PROTOCOL *DpPtr = Dp;
+ BOOLEAN IsUSB = FALSE;
+
+ if( Dp == NULL )
+ return 0xffff;
+
+ for( ; !(isEndNode(DpPtr)); DpPtr = NEXT_NODE(DpPtr))
+ {
+ if(DpPtr->Type == MESSAGING_DEVICE_PATH)
+ {
+ if(DpPtr->SubType == MSG_USB_DP)
+ IsUSB = TRUE;
+
+ if(DpPtr->SubType == MSG_MAC_ADDR_DP)
+ return TempUefiNetDevice;
+
+ continue;
+ }
+
+ if(DpPtr->Type == MEDIA_DEVICE_PATH)
+ {
+ if(!IsUSB && DpPtr->SubType == MEDIA_HARDDRIVE_DP)
+ return TempUefiHddDevice;
+ else
+ if(!IsUSB && DpPtr->SubType == MEDIA_CDROM_DP)
+ return TempUefiOddDevice;
+ else
+ if(IsUSB && DpPtr->SubType == MEDIA_HARDDRIVE_DP)
+ {
+ return TempUefiRemDevice;
+ }
+ else
+ if(IsUSB && DpPtr->SubType == MEDIA_CDROM_DP)
+ return TempUefiOddDevice;
+ }
+ }
+ return 0xffff;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetBootNextBootOption
+//
+// Description: Compare Boot device type and re-setting variable "BootNext"
+//
+// Input:
+// NONE
+// Output:
+// NONE
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+SetBootNextBootOption()
+{
+ EFI_STATUS Status;
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ UINT16 BootNext;
+ UINTN Size;
+
+ Size = sizeof(BootNext);
+
+ if( TempDeviceFound )
+ {
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+
+ if( GetUefiDeviceType(Option->FilePathList) == BootDeviceType )
+ {
+ BootNext = Option->BootOptionNumber;
+ Status = pRS->SetVariable(L"BootNext", &EfiVariableGuid, BOOT_VARIABLE_ATTRIBUTES, Size, &BootNext);
+ TRACE((-1,"FastBootOptionBds.c:: SetVariable Status=%r BootNext=%d\n", Status, BootNext));
+ }
+
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckBootNextTempBootOption
+//
+// Description: Check BootNext device and find uefi device, adjust BootNext
+// number.
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CheckBootNextTempBootOption()
+{
+ EFI_STATUS Status;
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ UINT16 BootNext;
+ UINTN Size;
+
+ Size = sizeof(BootNext);
+ Status = pRS->GetVariable(L"BootNext", &EfiVariableGuid, NULL, &Size, &BootNext);
+
+ TRACE((-1,"FastBootOptionBds.c:: Status=%r BootNext=%d\n", Status, BootNext));
+
+ if( !EFI_ERROR( Status ) )
+ {
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ BBS_BBS_DEVICE_PATH *BBSdp;
+
+ if( BootNext == Option->BootOptionNumber )
+ {
+ BBSdp=(BBS_BBS_DEVICE_PATH*)Option->FilePathList;
+ if( BBSdp->Header.Type == BBS_DEVICE_PATH )
+ {
+ BootDeviceType = BBSdp->DeviceType;
+ switch( BootDeviceType )
+ {
+ case TempUefiHddDevice:
+ case TempUefiOddDevice:
+ case TempUefiRemDevice:
+ case TempUefiNetDevice:
+ TempDeviceFound=TRUE;
+ break;
+ }
+ }
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveFastBootOption
+//
+// Description: Remove all TempUefiDevice Bootoption.
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+RemoveFastBootOption()
+{
+
+ DLINK *Link;
+ BOOT_OPTION *Option;
+
+ CheckBootNextTempBootOption();
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option){
+ BBS_BBS_DEVICE_PATH *BBSdp;
+ BBSdp=(BBS_BBS_DEVICE_PATH*)Option->FilePathList;
+
+ if( BBSdp->Header.Type == BBS_DEVICE_PATH )
+ {
+ switch( BBSdp->DeviceType )
+ {
+ case TempUefiHddDevice:
+ case TempUefiOddDevice:
+ case TempUefiRemDevice:
+ case TempUefiNetDevice:
+ Option->FwBootOption = TRUE;
+ break;
+ }
+ }
+
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FastBoot/FastBootPei.c b/Core/EM/FastBoot/FastBootPei.c
new file mode 100644
index 0000000..5082095
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootPei.c
@@ -0,0 +1,180 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootPei.c 2 11/09/10 8:43a Bibbyyeh $
+//
+// $Revision: 2 $
+//
+// $Date: 11/09/10 8:43a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootPei.c $
+//
+// 2 11/09/10 8:43a Bibbyyeh
+// [TAG] EIP47280
+// [Category] New Feature
+// [Description] Currently, BIOS will copy FV_MAIN or FV_BB into memory
+// in DXE phase. If BIOS copy rom before CPU disable flash cache in PEI
+// phase. Some data are in cache already, don't need to read from physical
+// ROM. It can help to save some time.
+// [Files] FastBootPei.c
+//
+// 1 11/02/10 1:47a Bibbyyeh
+// [TAG] EIP47280
+// [Category] New Feature
+// [Description] Currently, BIOS will copy FV_MAIN or FV_BB into memory
+// in DXE phase.
+// If BIOS copy rom before CPU disable flash cache in PEI phase.
+// Some data are in cache already, don't need to read from physical ROM.
+// It can help to save some time.
+// [Files] FastBootPei.cif
+// FastBootPei.mak
+// FastBootPei.c
+// FastBootPei.dxs
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBootPei.c
+//
+// Description:
+// Fast Boot Pei Driver
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//============================================================================
+// Includes
+//============================================================================
+
+#include <AmiPeiLib.h>
+#include <Pei.h>
+#include <Token.h>
+
+//============================================================================
+// Glocal Variable Declaration
+//============================================================================
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+
+EFI_STATUS NotifyAtPeiEnd (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+);
+
+EFI_PEI_NOTIFY_DESCRIPTOR FastBootNotifyDescs = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ NotifyAtPeiEnd
+};
+
+
+//============================================================================
+// Procedure
+//============================================================================
+
+VOID CopyRomImageToRam(EFI_PEI_SERVICES **PeiServices)
+{
+ EFI_STATUS Status;
+ VOID *p;
+ EFI_HOB_FIRMWARE_VOLUME *FvHob;
+ EFI_PHYSICAL_ADDRESS MemoryBuffer;
+ EFI_PHYSICAL_ADDRESS FvHobAddress;
+ UINT64 FvHobLength;
+
+ for( (*PeiServices)->GetHobList(PeiServices,&p)
+ ; !EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_FV,&p))
+ ;
+ )
+ {
+ FvHob = (EFI_HOB_FIRMWARE_VOLUME*)p;
+ FvHobAddress = FvHob->BaseAddress;
+ FvHobLength = FvHob->Length;
+
+ if ( FvHobAddress == FV_MAIN_BASE || FvHobAddress == FV_BB_BASE) {
+
+ // Allocate Memory
+ Status = (*PeiServices)->AllocatePages (
+ PeiServices,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES ((UINT32)FvHobLength),
+ &MemoryBuffer
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ // Copy FV HOB from ROM to RAM
+ (*PeiServices)->CopyMem (
+ (VOID*)MemoryBuffer,
+ (VOID*)FvHobAddress,
+ (UINTN)FvHobLength
+ );
+
+ // Update FV HOB (BaseAddress)
+ FvHob->BaseAddress = MemoryBuffer;
+ } // end for
+ } // end if
+}
+
+
+EFI_STATUS NotifyAtPeiEnd (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *Ppi
+)
+{
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+
+ if ( (BootMode != BOOT_ON_S3_RESUME) && (BootMode != BOOT_IN_RECOVERY_MODE) ) {
+ CopyRomImageToRam(PeiServices);
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+FastBootPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ (*PeiServices)->NotifyPpi(
+ PeiServices,
+ &FastBootNotifyDescs
+ );
+
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FastBoot/FastBootPei.cif b/Core/EM/FastBoot/FastBootPei.cif
new file mode 100644
index 0000000..0243c5c
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootPei.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "FastBootPei"
+ category = ModulePart
+ LocalRoot = "Core\EM\FastBoot"
+ RefName = "FastBootPei"
+[files]
+"FastBootPei.mak"
+"FastBootPei.c"
+"FastBootPei.dxs"
+<endComponent>
+
diff --git a/Core/EM/FastBoot/FastBootPei.dxs b/Core/EM/FastBoot/FastBootPei.dxs
new file mode 100644
index 0000000..1795a0b
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootPei.dxs
@@ -0,0 +1,56 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootPei.dxs 1 11/02/10 1:47a Bibbyyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 11/02/10 1:47a $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootPei.dxs $
+//
+// 1 11/02/10 1:47a Bibbyyeh
+// [TAG] EIP47280
+// [Category] New Feature
+// [Description] Currently, BIOS will copy FV_MAIN or FV_BB into memory
+// in DXE phase.
+// If BIOS copy rom before CPU disable flash cache in PEI phase.
+// Some data are in cache already, don't need to read from physical ROM.
+// It can help to save some time.
+// [Files] FastBootPei.cif
+// FastBootPei.mak
+// FastBootPei.c
+// FastBootPei.dxs
+//
+//**********************************************************************//
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FastBoot/FastBootPei.mak b/Core/EM/FastBoot/FastBootPei.mak
new file mode 100644
index 0000000..197ed46
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootPei.mak
@@ -0,0 +1,95 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/PTT/FastBootPei.mak 1 11/02/10 1:47a Bibbyyeh $
+#
+# $Revision: 1 $
+#
+# $Date: 11/02/10 1:47a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/PTT/FastBootPei.mak $
+#
+# 1 11/02/10 1:47a Bibbyyeh
+# [TAG] EIP47280
+# [Category] New Feature
+# [Description] Currently, BIOS will copy FV_MAIN or FV_BB into memory
+# in DXE phase.
+# If BIOS copy rom before CPU disable flash cache in PEI phase.
+# Some data are in cache already, don't need to read from physical ROM.
+# It can help to save some time.
+# [Files] FastBootPei.cif
+# FastBootPei.mak
+# FastBootPei.c
+# FastBootPei.dxs
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FastBootPei.mak
+#
+# Description:
+# Make file to build FastBootPei FFS
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+# MAK file for the eModule:Platform
+
+all : FastBootPei
+
+#---------------------------------------------------------------------------
+# Generic FastBootPei dependencies
+#---------------------------------------------------------------------------
+
+$(BUILD_DIR)\FastBootPei.mak : $(FastBoot_DIR)\FastBootPei.cif $(BUILD_RULES)
+ $(CIF2MAK) $(FastBoot_DIR)\FastBootPei.cif $(CIF2MAK_DEFAULTS)
+
+
+#---------------------------------------------------------------------------
+# Create FastBoot PEI Component
+#---------------------------------------------------------------------------
+FastBootPei : $(BUILD_DIR)\FastBootPei.mak FastBootPeiBin
+
+
+FastBootPei_OBJECTS = $(BUILD_DIR)\$(FastBoot_DIR)\FastBootPei.obj
+
+FastBootPeiBin : $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FastBootPei.mak all\
+ NAME=FastBootPei\
+ MAKEFILE=$(BUILD_DIR)\FastBootPei.mak \
+ "CFLAGS=$(CFLAGS) /I$(FastBoot_DIR)"\
+ OBJECTS="$(FastBootPei_OBJECTS)" \
+ GUID=333BB2A3-4F20-4CCC-AC38-0672D7412345\
+ ENTRY_POINT=FastBootPeiEntry \
+ TYPE=PEIM \
+ DEPEX1=$(FastBoot_DIR)\FastBootPei.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=0
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/Core/EM/FastBoot/FastBootRuntime.c b/Core/EM/FastBoot/FastBootRuntime.c
new file mode 100644
index 0000000..f8f120d
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootRuntime.c
@@ -0,0 +1,526 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootRuntime.c 9 7/11/13 10:17p Simonchen $
+//
+// $Revision: 9 $
+//
+// $Date: 7/11/13 10:17p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootRuntime.c $
+//
+// 9 7/11/13 10:17p Simonchen
+// [TAG] EIP126196
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] If set two HDD password and use Raid mode, fastboot will
+// fail.
+// [RootCause] Because when AHCI driver unlock first HDD, Raid driver
+// will try to read all HDD, but second HDD is still lock, so access will
+// fail.
+// [Solution] Make sure all HDD unlock then Raid can access HDD.
+// And add "Support Raid Driver" token to control fastboot support Raid
+// feature or not.
+// [Files] FastBoot.c
+// FastBoot.sd
+// FastBoot.sdl
+// FastBootRuntime.c
+// FastBoot.h
+//
+// 8 4/18/13 5:39a Simonchen
+// [TAG] EIP113454
+// [Category] New Feature
+// [Description] This eip is created for implement or experiment for
+// Intel raid mode on fastboot.
+// [Files] FastBoot.sdl
+// FastBootRuntime.c
+// FastBoot.c
+// FastBoot.sd
+// FastBoot.uni
+//
+// 7 9/17/12 5:56a Bibbyyeh
+// [TAG] EIP100456
+// [Category] New Feature
+// [Description] If fast boot failure counter reach a
+// MAX_LAST_BOOT_FAIL_COUNT, system will perform a full boot.
+// [Files] FastBoot.sdl FastBootRuntime.c
+//
+// 6 8/20/12 2:22a Bibbyyeh
+// [TAG] EIP98617
+// [Category] New Feature
+// [Description] Add one token or other disable function to PTT enter
+// Setup.
+// [Files] FastBoot.sdl FastBootRuntime.c
+//
+// 5 8/10/12 3:25a Bibbyyeh
+// [TAG] EIP96276
+// [Category] New Feature
+// [Description] Function request for PTT_12
+// EIP96276.2 Fixed USB skip table issue.
+// EIP96276.3 Add token ¡¥CONNECT_ALL_SATA_DEVICE_IN_FASTBOOT¡¦ to
+// gFastBootPolicy.
+// EIP96276.4 Add IsValidFBBootOptionPtr support by driver type. Exp : usb
+// type skip or other type
+// EIP96276.5 Add token ¡¥Test mode¡¨ to gFastBootPolicy Setup menu.
+// EIP96276.6 Disable Tse Hotkey support in fastboot path.
+// EIP96276.7 Modify TRACE message.
+// [Files] FastBoot.c FastBoot.sd FastBoot.sdl FastBoot.uni
+// FastBootRuntime.c FastBootProtocol.c
+//
+// 4 8/10/12 2:29a Bibbyyeh
+// [TAG] EIP97515
+// [Category] Improvement
+// [Description] According to the existence of user password, PTT can
+// decide to skip "ProcessConInAvailability" automatically.
+// [Files] FastBoot.sdl FastBootRuntime.c
+//
+// 3 6/01/12 6:55a Bibbyyeh
+// [TAG] EIP90455
+// [Category] New Feature
+// [Description] PTT improvement - fastboot policy protocol for dynamic
+// control fast boot behavior.
+// [Files] FastBoot.c FastBoot.sdl FastBoot.sd FastBoot.uni
+// FastBootRuntime.c FastBootTseHook.c FastBootProtocol.h FastBoot.h
+//
+// 2 3/11/11 10:01p Bibbyyeh
+// [TAG] EIP54993
+// [Category] Improvement
+// [Description]
+// 1.Sync with Fastboot_10
+// 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+// 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+// 4.Use SimpleText protocol to detect mode change hotkey instead of
+// pBS->ConIn.
+// 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+// 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+// fastboot path.
+// [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+// FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+// FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+// FastBootSMI.dxs FastBootSMI.mak
+//
+// 1 10/12/10 9:04a Bibbyyeh
+// Initial check in
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBootRuntime.c
+//
+// Description:
+// Implementation of callback when variable services is enabled
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+//============================================================================
+// Includes
+//============================================================================
+
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <Protocol/Variable.h>
+#include "FastBoot.h"
+#include <Protocol/FastBootProtocol.h>
+#include <Protocol/AmiUsbController.h>
+#include <token.h>
+#include <AMIVfr.h>
+
+//============================================================================
+// Define
+//============================================================================
+
+//============================================================================
+// External Golbal Variable Declaration
+//============================================================================
+
+//============================================================================
+// External Function Definitions
+//============================================================================
+
+//============================================================================
+// Golbal Variable Declaration
+//============================================================================
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+static EFI_GUID FastBootVariableGuid = FAST_BOOT_VARIABLE_GUID;
+static EFI_GUID FastBootPolicyGuid = FAST_BOOT_POLICY_PROTOCOL_GUID;
+FAST_BOOT_POLICY gFastBootPolicy;
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 920)
+USB_SKIP_LIST DefaultSkipTable[] = USB_SKIP_TABLE;
+#endif
+
+SKIP_PCI_LIST DeafultSkipPciList[]=FAST_BOOT_PCI_SKIP_LIST;
+#if SUPPORT_RAID_DRIVER
+SATA_DEVICE_DATA SataDeviceData[MAX_SATA_DEVICE_COUNT];
+#endif
+//============================================================================
+// Function Definitions
+//============================================================================
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSataPortPresentHOB
+//
+// Description: Get Sata port present HOB
+//
+// Input:
+// IN OUT SATA_PRESENT_HOB **SataPresentHob
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if SUPPORT_RAID_DRIVER
+EFI_STATUS GetSataPortPresentHOB (
+ IN OUT SATA_PRESENT_HOB **SataPresentHob
+)
+{
+ EFI_STATUS Status;
+ VOID *pHobList = NULL;
+ EFI_GUID guidHob = HOB_LIST_GUID;
+ EFI_GUID SataPresentHobGuid = AMI_SATA_PRESENT_HOB_GUID;
+
+ pHobList = GetEfiConfigurationTable(pST, &guidHob);
+ if (!pHobList) return EFI_NOT_READY;
+
+ *SataPresentHob = (SATA_PRESENT_HOB*)pHobList;
+
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, SataPresentHob)))
+ {
+ if (guidcmp(&(*SataPresentHob)->EfiHobGuidType.Name, &SataPresentHobGuid) == 0)
+ break;
+ }
+
+
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsSataPortPresentChanged
+//
+// Description: Check whether Sata Port Present status is changed.
+//
+// Input:
+// IN FAST_BOOT *FbVariable - Fast Boot Variable pointer
+//
+// Output: BOOLEAN TRUE - Sata port present status is changed.
+// FALSE - Sata port present status is NOT changed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if SUPPORT_RAID_DRIVER
+BOOLEAN IsSataPortPresentChanged(FAST_BOOT *FbVariable)
+{
+ SATA_PRESENT_HOB *pSataPresentHob;
+ EFI_STATUS Status;
+ UINT8 i;
+ Status = GetSataPortPresentHOB(&pSataPresentHob);
+
+ if (EFI_ERROR(Status) && FbVariable->ControllerCount == 0)
+ {
+ TRACE((-1,"FB: Sata port present HOB is not found, need CSP porting for it\n"));
+ return FALSE; //CSP didn't report Sata port present HOB, Sata support policy would not work.
+ }
+
+ // check whether Sata port present HOB is as same as previous boot totally.
+ if(!MemCmp(&pSataPresentHob->ControllerCount,&FbVariable->ControllerCount,sizeof(SATA_PRESENT_HOB)-sizeof(EFI_HOB_GUID_TYPE)))
+ return FALSE;
+
+ TRACE((-1,"FB: Sata port present is changed\n"));
+ TRACE((-1,"Current: Controller count %x\n",pSataPresentHob->ControllerCount));
+ for(i=0;i<4;i++)
+ TRACE((-1,"ClassCode %x,SataInfo %x\n",pSataPresentHob->SataInfo[i].ClassCode,pSataPresentHob->SataInfo[i].PresentPortBitMap));
+
+
+ TRACE((-1,"Last: Controller count %x\n",FbVariable->ControllerCount));
+ for(i=0;i<4;i++)
+ TRACE((-1,"ClassCode %x,SataInfo %x\n",FbVariable->SataInfo[i].ClassCode,FbVariable->SataInfo[i].PresentPortBitMap));
+
+
+ return TRUE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetDefaultFastBootPolicy
+//
+// Description: Fill default Fast Boot Plicy
+//
+// Input:
+// IN SETUP_DATA *SetupData - pointer to SetupData
+// IN FAST_BOOT *FbVariable - pointer to FastBoot variable
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetDefaultFastBootPolicy(SETUP_DATA *SetupData,FAST_BOOT *FbVariable)
+{
+ EFI_STATUS Status;
+ UINT8 *BootOption = NULL;
+ UINTN Size = 0;
+ AMITSESETUP AmiTseData;
+ EFI_GUID AmiTseSetupGuid = AMITSESETUP_GUID;
+ UINTN VariableSize = 0;
+#if SUPPORT_RAID_DRIVER
+ SATA_PRESENT_HOB *pSataPresentHob = NULL;
+#endif
+
+ gFastBootPolicy.TestMode = SetupData->FbTestMode; //(EIP96276.5)
+
+ //
+ //Informatoin for pervious boot
+ //
+ gFastBootPolicy.UEfiBoot = FbVariable->BootType;
+ gFastBootPolicy.BootOptionNumber = FbVariable->BootOptionNumber;
+ gFastBootPolicy.CheckBootOptionNumber = TRUE;
+ gFastBootPolicy.DevStrCheckSum = FbVariable->DevStrCheckSum;
+ gFastBootPolicy.CheckDevStrCheckSum = TRUE;
+ gFastBootPolicy.BootCount = FbVariable->BootCount;
+
+ Status = GetEfiVariable(L"FastBootOption", &FastBootVariableGuid, NULL, &Size, &BootOption);
+ gFastBootPolicy.FastBootOption = (EFI_DEVICE_PATH_PROTOCOL*)BootOption;
+#if SUPPORT_RAID_DRIVER
+ MemCpy(SataDeviceData,FbVariable->SataDevice,sizeof(SATA_DEVICE_DATA)*MAX_SATA_DEVICE_COUNT);
+ gFastBootPolicy.SataDevice = SataDeviceData;
+#endif
+ //
+ //Config Behavior in fastboot path
+ //
+ gFastBootPolicy.SataSupport = SetupData->FbSata;
+ gFastBootPolicy.VGASupport = SetupData->FbVga;
+
+ gFastBootPolicy.UsbSupport = SetupData->FbUsb;
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 920)
+ gFastBootPolicy.UsbSkipTable = DefaultSkipTable;
+ gFastBootPolicy.UsbSkipTableSize = sizeof(DefaultSkipTable)/sizeof(USB_SKIP_LIST); //(EIP96276.2)
+#endif
+
+ gFastBootPolicy.Ps2Support = SetupData->FbPs2;
+ gFastBootPolicy.NetWorkStackSupport = SetupData->FbNetWrokStack;
+
+ gFastBootPolicy.SkipPciList = DeafultSkipPciList;
+ gFastBootPolicy.SkipPciListSize = sizeof(DeafultSkipPciList);
+ gFastBootPolicy.SkipTSEHandshake = SKIP_TSE_HANDSHAKE;
+ gFastBootPolicy.FirstFastBootInS4 = ALLOW_FIRST_FASTBOOT_IN_S4;
+// gFastBootPolicy.ConnectAllSata = CONNECT_ALL_SATA_DEVICE_IN_FASTBOOT; //(EIP113454)-
+
+ //
+ //Check User and Amdin password
+ //
+ VariableSize = sizeof(AMITSESETUP);
+ Status = pRS->GetVariable ( L"AMITSESetup", \
+ &AmiTseSetupGuid, \
+ NULL, \
+ &VariableSize, \
+ &AmiTseData );
+
+ if (!EFI_ERROR(Status)) {
+ if (AmiTseData.UserPassword[0] != 0) {
+ TRACE((-1,"FB: User PW is set\n"));
+ //user password is set
+ gFastBootPolicy.CheckPassword = TRUE;
+ }
+
+ if (AmiTseData.AdminPassword[0] != 0) {
+ TRACE((-1,"FB: Admin PW is set\n"));
+ //Admin password is set, don't do anything now.
+ }
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootGetVarCallback
+//
+// Description: FastBoot runtime callback
+//
+// Input:
+// IN EFI_EVENT Event - Callback event
+// IN VOID *Context - pointer to calling context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBootGetVarCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ UINT32 Variable = 0;
+ FAST_BOOT FbVariable;
+ UINTN Size = sizeof(SETUP_DATA);
+ static EFI_GUID SetupVariableGuid = SETUP_GUID;
+ SETUP_DATA SetupData;
+ EFI_HANDLE Handle = NULL;
+
+ static UINT32 BootFlow = BOOT_FLOW_CONDITION_FIRST_BOOT;
+ static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID;
+
+ //Initial fast boot policy
+
+ pBS->SetMem(&gFastBootPolicy,sizeof(FAST_BOOT_POLICY),0);
+
+ Status=pBS->InstallProtocolInterface(
+ &Handle,
+ &FastBootPolicyGuid,
+ EFI_NATIVE_INTERFACE,
+ &gFastBootPolicy
+ );
+ ASSERT(!EFI_ERROR(Status));
+
+ Status = pRS->GetVariable(L"Setup", &SetupVariableGuid, NULL, &Size, &SetupData);
+ if (EFI_ERROR(Status) || SetupData.FastBoot == 0)
+ gFastBootPolicy.FastBootEnable = FALSE;
+ else if (SetupData.FastBoot == 1)
+ gFastBootPolicy.FastBootEnable = TRUE;
+
+ Size = sizeof(FbVariable);
+ Status = pRS->GetVariable(L"LastBoot", &FastBootVariableGuid, NULL, &Size, (VOID *)&FbVariable);
+ if(EFI_ERROR(Status))
+ gFastBootPolicy.LastBootVarPresence = FALSE;
+ else
+ gFastBootPolicy.LastBootVarPresence = TRUE;
+
+ SetDefaultFastBootPolicy(&SetupData,&FbVariable);
+
+#if SUPPORT_RAID_DRIVER
+ if(gFastBootPolicy.LastBootVarPresence == TRUE && IsSataPortPresentChanged(&FbVariable))
+ {
+ pRS->SetVariable(L"LastBoot",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ &Variable);
+
+ gFastBootPolicy.LastBootVarPresence = FALSE;
+
+ }
+#endif
+
+
+ if (gFastBootPolicy.FastBootEnable == FALSE ||gFastBootPolicy.LastBootVarPresence == FALSE)
+ return;
+
+ //(EIP98617)>>
+
+ Size = sizeof(UINT32);
+ Status = pRS->GetVariable(L"LastBootFailed", &FastBootVariableGuid, NULL, &Size, &Variable);
+ if(EFI_ERROR(Status)) {
+ Variable = 0x55aa55aa;
+ Status = pRS->SetVariable(L"LastBootFailed",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ Size,
+ &Variable);
+ } else {
+#if LAST_BOOT_FAIL_MECHANISM
+ //reset LastBootFailed variable
+ Status = pRS->SetVariable(L"LastBootFailed",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ &Variable);
+ //force setup
+ Status = pRS->SetVariable(L"BootFlow",
+ &guidBootFlow,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(BootFlow),
+ &BootFlow);
+
+ gFastBootPolicy.LastBootFailure = TRUE;
+#else
+ //check the fail count, if reach max count then perform a full boot
+ if (Variable == 0x55aa55aa)
+ Variable = 0x01;
+ else
+ Variable++;
+
+ if (Variable == MAX_LAST_BOOT_FAIL_COUNT) {
+
+ pRS->SetVariable(L"LastBoot",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ &FbVariable);
+
+ gFastBootPolicy.LastBootVarPresence = FALSE;
+
+ Variable = 0x55aa55aa;
+ }
+
+ Status = pRS->SetVariable(L"LastBootFailed",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ Size,
+ &Variable);
+#endif
+ }
+
+ //<<(EIP98617)
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootEntry
+//
+// Description: FastBoot runtime callback entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FastBootEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_EVENT Event;
+ VOID *Registration;
+ static EFI_GUID VariableArchProtocolGuid = EFI_VARIABLE_ARCH_PROTOCOL_GUID;
+
+ RegisterProtocolCallback(&VariableArchProtocolGuid, FastBootGetVarCallback, NULL, &Event, &Registration);
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FastBoot/FastBootSMI.c b/Core/EM/FastBoot/FastBootSMI.c
new file mode 100644
index 0000000..78fe114
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootSMI.c
@@ -0,0 +1,244 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootSMI.c 1 3/11/11 10:07p Bibbyyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 3/11/11 10:07p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootSMI.c $
+//
+// 1 3/11/11 10:07p Bibbyyeh
+// [TAG] EIP54993
+// [Category] Improvement
+// [Description]
+// 1.Sync with Fastboot_10
+// 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+// 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+// 4.Use SimpleText protocol to detect mode change hotkey instead of
+// pBS->ConIn.
+// 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+// 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+// fastboot path.
+// [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+// FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+// FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+// FastBootSMI.dxs FastBootSMI.mak
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBootSMI.c
+//
+// Description:
+// Implementation of fast boot smi functionality
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\SmiFlash.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\SmmGpiDispatch.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include "AmiSmm.h"
+#include <Setup.h>
+#include <token.h>
+
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+EFI_GUID SwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SwSmiHandler
+//
+// Description: SwSmiHandler
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output:
+// VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SwSmiHandler(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+ UINT8 SwSmiNum;
+ UINTN i;
+ UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1;
+ EFI_STATUS Status;
+
+ // Search for software SMI entry
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ // If table found, check for the CPU that caused the software SMI.
+ if (i != pSmst->NumberOfTableEntries) { // found?
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu; // got cpu number
+ }
+
+ pCpuSaveState = pSmst->CpuSaveState;
+
+ SwSmiNum = (UINT8)DispatchContext->SwSmiInputValue;
+
+ // execute according to the software SMI value (from SW_SMI_IO_ADDRESS)
+ switch(SwSmiNum)
+ {
+ case FAST_BOOT_ENABLE_SWSMI: //enable fast boot
+ case FAST_BOOT_DISABLE_SWSMI: //disable fast boot
+
+ {
+ EFI_GUID SetupGuid = SETUP_GUID;
+ UINTN SetupDataSize = sizeof(SETUP_DATA);
+ SETUP_DATA SetupData;
+
+ Status = pRS->GetVariable(
+ L"Setup",
+ &SetupGuid,
+ NULL,
+ &SetupDataSize,
+ &SetupData);
+
+ if (SwSmiNum == FAST_BOOT_ENABLE_SWSMI)
+ SetupData.FastBoot = 1;
+ else if (SwSmiNum == FAST_BOOT_DISABLE_SWSMI)
+ SetupData.FastBoot = 0;
+
+ Status = pRS->SetVariable(
+ L"Setup",
+ &SetupGuid,
+ EFI_VARIABLE_NON_VOLATILE | \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | \
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ SetupDataSize,
+ &SetupData);
+ break;
+ }
+
+
+ default:
+ break;
+
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: InSmmFunction
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwSmiContext1;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwSmiContext2;
+ EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_HANDLE SwSmiHandle;
+ EFI_STATUS Status;
+
+ SwSmiContext1.SwSmiInputValue = FAST_BOOT_ENABLE_SWSMI;
+ SwSmiContext2.SwSmiInputValue = FAST_BOOT_DISABLE_SWSMI;
+
+ Status = pBS->LocateProtocol(&SwDispatchProtocolGuid, NULL, &SwDispatch);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = SwDispatch->Register(
+ SwDispatch,
+ SwSmiHandler,
+ &SwSmiContext1,
+ &SwSmiHandle
+ );
+
+ Status = SwDispatch->Register(
+ SwDispatch,
+ SwSmiHandler,
+ &SwSmiContext2,
+ &SwSmiHandle
+ );
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootSMIEntryPoint
+//
+// Description: FastBootSMIEntryPoint
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FastBootSMIEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle,SystemTable);
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+
diff --git a/Core/EM/FastBoot/FastBootSMI.cif b/Core/EM/FastBoot/FastBootSMI.cif
new file mode 100644
index 0000000..82261c7
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootSMI.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "FastBootSMI"
+ category = ModulePart
+ LocalRoot = "CORE\EM\FastBoot\"
+ RefName = "FastBootSMI"
+[files]
+"FastBootSMI.sdl"
+"FastBootSMI.c"
+"FastBootSMI.dxs"
+"FastBootSMI.mak"
+<endComponent>
+
diff --git a/Core/EM/FastBoot/FastBootSMI.dxs b/Core/EM/FastBoot/FastBootSMI.dxs
new file mode 100644
index 0000000..cfb9393
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootSMI.dxs
@@ -0,0 +1,64 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootSMI.dxs 1 3/11/11 10:07p Bibbyyeh $
+//
+// $Revision: 1 $
+//
+// $Date: 3/11/11 10:07p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootSMI.dxs $
+//
+// 1 3/11/11 10:07p Bibbyyeh
+// [TAG] EIP54993
+// [Category] Improvement
+// [Description]
+// 1.Sync with Fastboot_10
+// 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+// 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+// 4.Use SimpleText protocol to detect mode change hotkey instead of
+// pBS->ConIn.
+// 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+// 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+// fastboot path.
+// [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+// FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+// FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+// FastBootSMI.dxs FastBootSMI.mak
+//
+//
+//*************************************************************************
+
+#include <Protocol\SmmSwDispatch.h>
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FastBoot/FastBootSMI.mak b/Core/EM/FastBoot/FastBootSMI.mak
new file mode 100644
index 0000000..429c9ee
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootSMI.mak
@@ -0,0 +1,82 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/PTT/FastBootSMI.mak 1 3/11/11 10:07p Bibbyyeh $
+#
+# $Revision: 1 $
+#
+# $Date: 3/11/11 10:07p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/PTT/FastBootSMI.mak $
+#
+# 1 3/11/11 10:07p Bibbyyeh
+# [TAG] EIP54993
+# [Category] Improvement
+# [Description]
+# 1.Sync with Fastboot_10
+# 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+# 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+# 4.Use SimpleText protocol to detect mode change hotkey instead of
+# pBS->ConIn.
+# 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+# 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+# fastboot path.
+# [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+# FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+# FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+# FastBootSMI.dxs FastBootSMI.mak
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FastBootSMI.mak
+#
+# Description: Make file for FastBoot SMI.
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+
+all : FastBootSMI
+
+FastBootSMI:$(BUILD_DIR)\FastBootSMI.mak FastBootSMIBin
+
+$(BUILD_DIR)\FastBootSMI.mak : $(FastBootSMI_DIR)\FastBootSMI.cif $(FastBootSMI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FastBootSMI_DIR)\FastBootSMI.cif $(CIF2MAK_DEFAULTS)
+
+
+FastBootSMIBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FastBootSMI.mak all\
+ GUID=D122882C-DA73-438B-A6B3-E07B7D18DB6F\
+ ENTRY_POINT=FastBootSMIEntryPoint\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
diff --git a/Core/EM/FastBoot/FastBootSMI.sdl b/Core/EM/FastBoot/FastBootSMI.sdl
new file mode 100644
index 0000000..755fa0a
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootSMI.sdl
@@ -0,0 +1,40 @@
+TOKEN
+ Name = "FAST_BOOT_SMI_SUPPORT"
+ Value = "0"
+ Help = "Switch to enable FastBootSMI in the project."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "FAST_BOOT_ENABLE_SWSMI"
+ Value = "0xDB"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FAST_BOOT_DISABLE_SWSMI"
+ Value = "0xDC"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "FastBootSMI_DIR"
+End
+
+MODULE
+ Help = "Includes FastBootSMI.mak to Project"
+ File = "FastBootSMI.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FastBootSMI.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/FastBoot/FastBootTseHook.c b/Core/EM/FastBoot/FastBootTseHook.c
new file mode 100644
index 0000000..b300244
--- /dev/null
+++ b/Core/EM/FastBoot/FastBootTseHook.c
@@ -0,0 +1,379 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/PTT/FastBootTseHook.c 8 7/17/13 2:59a Simonchen $
+//
+// $Revision: 8 $
+//
+// $Date: 7/17/13 2:59a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PTT/FastBootTseHook.c $
+//
+// 8 7/17/13 2:59a Simonchen
+// [TAG] EIP125309
+// [Category] New Feature
+// [Description] Add function to make sure before boot to OS, BIOS is in
+// fastboot path.
+// [Files] FastBoot.sdl
+// FastBootTseHook.c
+// FastBoot.c
+// FastBoot.h
+//
+// 7 8/04/12 5:38a Bibbyyeh
+// Fix logic defect in the if statement in procedure
+// "FastBootCheckForKey".
+//
+// 6 6/01/12 6:56a Bibbyyeh
+// [TAG] EIP90455
+// [Category] New Feature
+// [Description] PTT improvement - fastboot policy protocol for dynamic
+// control fast boot behavior.
+// [Files] FastBoot.c FastBoot.sdl FastBoot.sd FastBoot.uni
+// FastBootRuntime.c FastBootTseHook.c FastBootProtocol.h FastBoot.h
+//
+// 5 5/30/12 3:38a Bibbyyeh
+// [TAG] EIP90874
+// [Category] Improvement
+// [Description] Display "Press the DEL or ESC key to enter setup"
+// message in fastboot path.
+// [Files] FastBootTseHook.c
+//
+// 4 9/08/11 5:26a Bibbyyeh
+// [TAG] EIP68329
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] OS can't back to desktop correctly after resumed from
+// S3.
+// [RootCause] TSEIDEPasswordFreezeDevices is skipped in fastboot path
+// if SKIP_TSE_HANDSHAKE is enabled.
+// [Solution] Call TSEIDEPasswordFreezeDevices after ReadyToBoot
+// Event in fastboot path.
+// [Files] FastBoot.c FastBootProtocol.h FastBootTseHook.c
+//
+// 3 7/07/11 10:38a Bibbyyeh
+// [TAG] EIP63924
+// [Category] Improvement
+// [Description]
+// 1. Add elink for FastBoot mode change, default checking rule is check
+// post hotkey.
+// 2. Timer call back for check hotkey is not necessary. Create a protocol
+// for calling checkforkey in TSE.
+// 3. Since EIP68383 improve the performance of ps2 keyboard, we don't
+// need to exchange the initial order of ConIn/ConOut for getting more
+// time to detect hotkey.
+// [Files] FastBoot.sdl FastBoot.mak FastBoot.c FastBootTseHook.c
+// FastBoot.h FastBootProtocol.h
+//
+// 2 3/11/11 10:01p Bibbyyeh
+// [TAG] EIP54993
+// [Category] Improvement
+// [Description]
+// 1.Sync with Fastboot_10
+// 2.Remove token "SAVE_LAST_BOOT_DEVICE_CHECKSUM"
+// 3.Add token "CALL_DISPATCHER_AGAIN_IN_FASTBOOT"
+// 4.Use SimpleText protocol to detect mode change hotkey instead of
+// pBS->ConIn.
+// 5.Simplify the code about "AMILEGACY16_FASTBOOT_SOLUTION".
+// 6.Fixed a bug that SATA device can't be found if keep TSE execution on
+// fastboot path.
+// [Files] PPT.cif FastBoot.sdl FastBootRuntime.c FastBootTseHook.c
+// FastBoot.c FastBoot.h FastBoot.sd FastBootProtocol.cif
+// FastBootProtocol.h FastBootSMI.cif FastBootSMI.sdl FastBootSMI.c
+// FastBootSMI.dxs FastBootSMI.mak
+//
+// 1 10/12/10 9:04a Bibbyyeh
+// Initial check in
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FastBootTseHook.c
+//
+// Description:
+// Implementation of suppress of TSE "Press DEL..." message
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+//============================================================================
+// Includes
+//============================================================================
+
+#include <Efi.h>
+#include <Setup.h>
+#include <Protocol/FastBootProtocol.h>
+#include "FastBoot.h"
+#include "AMITSEStrTokens.h"
+#if FASTBOOT_NEED_RESTART
+#include <AmiDxeLib.h>
+#endif
+//============================================================================
+// Define
+//============================================================================
+#define BOOT_FLOW_CONDITION_NORMAL 0
+
+#if FASTBOOT_NEED_RESTART
+static EFI_GUID FastbootRestartGuid = FAST_BOOT_RESTART_GUID;
+static EFI_GUID FastbootRestartCountGuid = FAST_BOOT_RESTART_COUNT_GUID;
+#endif
+
+//============================================================================
+// External Golbal Variable Declaration
+//============================================================================
+extern EFI_RUNTIME_SERVICES *gRT;
+extern EFI_BOOT_SERVICES *gBS;
+extern UINT32 gBootFlow;
+extern BOOLEAN gEnterSetup;
+extern EFI_EVENT gKeyTimer;
+extern CHAR16 *HiiGetString( VOID* handle, UINT16 token );
+extern EFI_HII_HANDLE gHiiHandle;
+//============================================================================
+// External Function Definitions
+//============================================================================
+EFI_STATUS PostManagerDisplayPostMessage( CHAR16 *message );
+BOOLEAN ProcessConInAvailability(VOID);
+VOID BbsBoot(VOID);
+VOID TSEIDEPasswordFreezeDevices(); //(EIP68329)+
+VOID CheckForKeyHook( EFI_EVENT Event, VOID *Context );
+EFI_STATUS TimerStopTimer( EFI_EVENT *Event );
+//============================================================================
+// Golbal Variable Declaration
+//============================================================================
+FAST_BOOT_POLICY *gFastBootPolicy;
+FAST_BOOT_TSE_PROTOCOL gFastBootTseProtocol = {
+ FastBootCheckForKey,
+ FastBootStopCheckForKeyTimer,
+ TSEIDEPasswordFreezeDevices //(EIP68329)++
+};
+//============================================================================
+// Function Definitions
+//============================================================================
+ //(EIP63924+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootCheckForKey
+//
+// Description: This function check TSE variable,gEnterSetup and gBootFlow.
+//
+// Input:
+// BOOLEAN *EnterSetup
+// UINT32 *BootFlow
+// Output:
+// EFI_SUCCESS - Bootflow is changed or EnterSetup if true
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FastBootCheckForKey(
+ IN BOOLEAN *EnterSetup,
+ IN UINT32 *BootFlow)
+{
+ CheckForKeyHook( (EFI_EVENT)NULL, NULL );
+
+ *EnterSetup = gEnterSetup;
+ *BootFlow = gBootFlow;
+
+ if ((gEnterSetup) || (gBootFlow != BOOT_FLOW_CONDITION_NORMAL)){
+ return EFI_SUCCESS;
+ }
+ else {
+ return EFI_NOT_READY;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootStopCheckForKeyTimer
+//
+// Description: This function stop the timer of CheckForKey callback
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FastBootStopCheckForKeyTimer()
+{
+ return TimerStopTimer(&gKeyTimer);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootMinisetupDriverEntryHook
+//
+// Description: Function that will be called when enter TSE Dxe entry
+//
+// Input:
+// None
+//
+// Output:
+// FALSE - as per TSE requirement, that no password was entered
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBootMinisetupDriverEntryHook(VOID)
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_GUID FastBootTseGuid = FAST_BOOT_TSE_PROTOCOL_GUID;
+ EFI_GUID FastBootPolicyGuid = FAST_BOOT_POLICY_PROTOCOL_GUID;
+ EFI_STATUS Status;
+
+ gBS->InstallProtocolInterface(&Handle,
+ &FastBootTseGuid,
+ EFI_NATIVE_INTERFACE,
+ &gFastBootTseProtocol);
+
+ Status = gBS->LocateProtocol(&FastBootPolicyGuid,NULL,&gFastBootPolicy);
+
+}
+ //<(EIP63924+)
+#if FASTBOOT_NEED_RESTART
+VOID InitialRebootCount(VOID)
+{
+ EFI_STATUS Status;
+ UINTN RebootFlag = 1;
+ UINTN RebootFlagSize = sizeof(RebootFlag);
+ UINTN ClearCount = 0;
+ UINTN ClearCountSize = sizeof(ClearCount);
+ Status = gRT->SetVariable(FAST_BOOT_RESTART_COUNT,
+ &FastbootRestartCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ ClearCountSize,
+ &ClearCount);
+
+ Status = gRT->SetVariable(FAST_BOOT_RESTART,
+ &FastbootRestartGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ RebootFlagSize,
+ &RebootFlag);
+
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootConInAvailHook
+//
+// Description: Function that will be called instead of generic TSE callback
+// on Console Input device is installed event
+//
+// Input:
+// None
+//
+// Output:
+// FALSE - as per TSE requirement, that no password was entered
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FastBootConInAvailHook(VOID)
+{
+// EFI_STATUS Status;
+// UINTN Size = sizeof(SETUP_DATA);
+// static EFI_GUID SetupVariableGuid = SETUP_GUID;
+// SETUP_DATA SetupData;
+//
+// Status = gRT->GetVariable(L"Setup", &SetupVariableGuid, NULL, &Size, &SetupData);
+// if (EFI_ERROR(Status) || SetupData.FastBoot == 0 || ALLOW_CHECKING_PASSWORD)
+// return ProcessConInAvailability();
+
+ if(gFastBootPolicy->FastBootEnable == 0 || gFastBootPolicy->CheckPassword == 1)
+ return ProcessConInAvailability();
+
+#if SETUP_PRINT_ENTER_SETUP_MSG
+{
+ CHAR16 *text = NULL;
+ text = HiiGetString( gHiiHandle, STRING_TOKEN(STR_DEL_ENTER_SETUP) );
+ if ( text != NULL )
+ PostManagerDisplayPostMessage(text);
+ gBS->FreePool(text);
+}
+#endif
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootBbsBootHook
+//
+// Description: Function that will be called instead of generic TSE callback
+// on BBS popup boot path
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FastBootBbsBootHook(VOID)
+{
+ static EFI_GUID FastBootVariableGuid = FAST_BOOT_VARIABLE_GUID;
+ EFI_STATUS Status;
+ UINT32 BbsPopupCalled = 0x55aa55aa;
+ Status = gRT->SetVariable(L"BbsPopupCalled",
+ &FastBootVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(BbsPopupCalled),
+ &BbsPopupCalled);
+ BbsBoot();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FastBootLaunch
+//
+// Description: Function that will be called instead of generic TSE callback
+// on fast boot path
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if OVERRIDE_FastBootLaunch
+EFI_STATUS FastBootLaunch()
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ AMI_FAST_BOOT_PROTOCOL * FastBootProtocol = NULL;
+
+ // do the Fast Boot
+ if (!EFI_ERROR(gBS->LocateProtocol(&AmiFastBootProtocolGuid, NULL, &FastBootProtocol)))
+ Status = FastBootProtocol->Launch();
+
+ // If gFastBootProtocolGuid protocol not found or FastBoot Failed. return
+ return Status;
+}
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FastBoot/PTT.chm b/Core/EM/FastBoot/PTT.chm
new file mode 100644
index 0000000..3560958
--- /dev/null
+++ b/Core/EM/FastBoot/PTT.chm
Binary files differ
diff --git a/Core/EM/FileSystem/DirectoryHandler.c b/Core/EM/FileSystem/DirectoryHandler.c
new file mode 100644
index 0000000..9acd1d2
--- /dev/null
+++ b/Core/EM/FileSystem/DirectoryHandler.c
@@ -0,0 +1,454 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/DirectoryHandler.c 6 7/07/10 2:54p Pats $
+//
+// $Revision: 6 $
+//
+// $Date: 7/07/10 2:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/DirectoryHandler.c $
+//
+// 6 7/07/10 2:54p Pats
+// EIP 38291: Fails Klocwork test.
+// Problem: No error return if short name is null in GenUniqueShortName()
+// Solution: Added error return.
+//
+// 5 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 4 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 3 11/03/05 2:16p Srinin
+// Fixed VC7.1 warning msg.
+//
+// 2 9/08/05 4:41p Pats
+// Fixed problem of short filename having exactly 8 characters in mame and
+// 3 in ext being handled as long file name (and ~ name generated).
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: DirectoryHandler.c
+//
+// Description: Fat File System driver -- Directory Functions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "FileSystem.h"
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetNameComponent
+//
+// Description: Gets the name component from a path
+//
+// Parameters: CHAR16 *Path - Pointer to input path
+// CHAR16 *Name - Pointer to output name
+//
+// Return value: CHAR16 * path truncated to name
+//
+// Modified: None
+//
+// Referral(s): None
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16 *
+GetNameComponent (
+ IN CHAR16 *Path,
+ OUT CHAR16 *Name
+)
+{
+ UINTN Len = 0;
+
+ while (*Path && *Path != '\\') {
+ if (Len < 259) {
+ Name[Len] = *Path;
+ Len += 1;
+ }
+
+ Path += 1;
+ }
+
+ Name[Len] = 0;
+
+// Remove trailing '\'
+ while (*Path == '\\') {
+ Path += 1;
+ }
+
+ return Path;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GenShortFilename
+//
+// Description: Generates a DOS 8.3 name component from a path
+//
+// Parameters: VOLUME_INFO *Vol - Pointer to volume information structure
+// CHAR16 *InPath - Pointer to input path
+// CHAR8 *ShortName - Pointer to generated DOS 8.3 name
+//
+// Return value: EFI_STATUS - Status of operation (EFI_SUCCESS)
+//
+// Modified: None
+//
+// Referral(s): None
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GenShortFilename (
+ IN VOLUME_INFO *Vol,
+ IN CHAR16 *InPath,
+ OUT CHAR8 *ShortName
+)
+{
+ CHAR16 *Ext;
+ CHAR16 *p;
+ CHAR16 CharC;
+
+ MemSet(ShortName, 11, 0x20); // Fill short name with spaces
+
+ // If this is a '.' or '..' name then it's a special form
+ if (InPath[0] == '.' && InPath[1] == 0) {
+ ShortName[0] = '.';
+ goto Done;
+ }
+
+ if (InPath[0] == '.' && InPath[1] == '.' && InPath[2] == 0) {
+ ShortName[0] = '.';
+ ShortName[1] = '.';
+ goto Done;
+ }
+
+// Find the last '.'
+ Ext = NULL;
+
+ for (p = InPath; *p; p++) {
+ if (*p == '.') {
+ Ext = p;
+ }
+ }
+
+ if (!Ext) {
+ Ext = p;
+ }
+
+ // Create 8.3 name. Convert chars to fat values. Skip any '.' or ' '.
+ CharC = *Ext; // Save first char of ext.
+ *Ext = 0; // Zero-terminate name
+ Vol->UnicodeCollationInterface->StrToFat (Vol->UnicodeCollationInterface,
+ InPath,
+ 8,
+ ShortName);
+ *Ext = CharC; // Restore first char of ext.
+ Vol->UnicodeCollationInterface->StrToFat (Vol->UnicodeCollationInterface,
+ Ext,
+ 3,
+ ShortName+8);
+
+Done:
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GenUniqueShortFname
+//
+// Description: Generates a unique DOS 8.3 name from a possible long name
+//
+// Parameters: FILE_HANDLE *fh - Pointer to the file handle structure
+// CHAR16 *LongName - Pointer to the possible long name
+// CHAR8 *ShortName - Pointer to generated DOS 8.3 name
+// BOOLEAN *LfnNeeded - Indicates a long name entry is
+// needed for this input name
+//
+// Return value: EFI_STATUS - EFI_SUCCESS - Unique name generated
+// EFI_ACCESS_DENIED - this name already exists
+// on the volume
+//
+// Modified: None
+//
+// Referral(s): None
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GenUniqueShortFname (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *LongName,
+ OUT CHAR8 *ShortName,
+ OUT BOOLEAN *LfnNeeded
+)
+{
+
+ EFI_STATUS Status;
+ VOLUME_INFO *Vol = fh->VolumeInterface;
+ DIR_ENTRY_LIST *Del;
+ CHAR8 Temp[12];
+ CHAR16 Temp2[13];
+ CHAR16 Temp3[13];
+ CHAR8 CounterString[6];
+ UINTN Counter, CounterStringLen;
+ UINTN k;
+ CHAR8 *s;
+
+ Status = GenShortFilename(Vol, LongName, ShortName);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ // Check for dot or dotdot entries
+ if ((LongName[0] == '.' && LongName[1] == 0) ||
+ (LongName[0] == '.' && LongName[1] == '.' && LongName[2] == 0)) {
+ *LfnNeeded = FALSE;
+ return EFI_SUCCESS;
+ }
+
+ if (!fh->DirList.pHead) {
+ ReadAllDirectoryEntries (fh);
+ }
+
+ // Find out if the input name is already a valid short name -- i.e., no
+ // ~Counter is needed.
+ k = Wcslen(LongName) * sizeof(CHAR16) + 2; // Include Null character
+
+ if (k <= 26) { // If it could be a legal short name...
+ // (13 * 2 including '.' + 2 for NULL)
+ ExtractShortFileName(Vol, Temp2, ShortName);
+ pBS->CopyMem(Temp3, LongName, k);
+ // Make an upper case copy of the input
+ Vol->UnicodeCollationInterface->StrUpr(Vol->UnicodeCollationInterface, Temp3);
+
+ if ( !Wcscmp(Temp2, Temp3 )) {
+ // If the extracted name is same as upper case copy of input...
+ // If the extracted name doesn't equal the non-upper case original,
+ // it must have some lower case letters in it,
+ // so therefore a long name entry is needed.
+ if (!Wcscmp(Temp2, LongName)) *LfnNeeded = FALSE;
+
+ else *LfnNeeded = TRUE;
+
+ if (FindMatchingDirEntry (fh, LongName, &Del)) {
+ return EFI_ACCESS_DENIED; // Name already exists, can't create
+
+ } else {
+ return EFI_SUCCESS; // Name is ok, return
+ }
+ }
+ }
+
+ // Now append "~Counter" to the short name, incrementing "Counter"
+ // until the file name is unique in that Path
+ Zeromemory (CounterString, sizeof(CounterString));
+
+ for (Counter = 1; Counter < 65536; Counter++) {
+ pBS->CopyMem(Temp, ShortName, 11);
+ if (Temp[0] == ' ') return EFI_INVALID_PARAMETER;
+ ItoaEx(Counter, CounterString, 10, FALSE);
+ CounterStringLen = Strlen(CounterString);
+
+ // Right-justify the "~Counter"
+ for (k = 0; k < 7 - CounterStringLen; k += 1) {
+ if (Temp[k] == ' ') {
+ k--; // In case the name is short
+ break;
+ }
+ }
+
+ // Append the "~Counter" to the name
+ Temp[k++] = '~';
+
+ for (s = CounterString; *s; Temp[k++] = *s++) ;
+
+ // Search for the generated name
+ Temp[11] = 0;
+
+ if (!FindMatchingSFNDirEntry (fh, Temp, &Del)) {
+ pBS->CopyMem(ShortName, Temp, 11);
+ *LfnNeeded = TRUE;
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_ACCESS_DENIED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CopyCharsToLfnSlot
+//
+// Description: Copies a character to the appropriate slot of a long name
+// directory structure
+//
+// Parameters: DIR_ENTRY_LFN *Slot - Pointer to long name directory
+// structure
+// UINT32 *SlotPos - Pointer to slot position to fill
+// UINT16 Ch - The character to be placed in the slot
+//
+// Return value: None
+//
+// Modified: None
+//
+// Referral(s): None
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static VOID
+CopyCharsToLfnSlot (
+ DIR_ENTRY_LFN *Slot,
+ UINT32 SlotPos,
+ UINT16 Ch
+)
+{
+ if ((SlotPos >= 0) && (SlotPos <= 4)) Slot->Dir_Name0_4[SlotPos] = Ch;
+
+ else if ((SlotPos >= 5) && (SlotPos <= 10)) Slot->Dir_Name5_10 [SlotPos-5] = Ch;
+
+ else if ((SlotPos >= 11) && (SlotPos <= 12)) Slot->Dir_Name11_12[SlotPos-11] = Ch;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SplitLFN
+//
+// Description: Splits a long file name into long name directory enties.
+//
+// Parameters: CHAR16 *LongName - Pointer to a long file name
+// DIR_ENTRY_32 *ShortEntry - Pointer to the corresponding
+// short directory entry
+// DIR_ENTRY_LFN *Slot - The structure of the long directory
+// entries to be filled
+//
+// Return value: EFI_STATUS - Status of the operation (EFI_SUCCESS)
+//
+// Modified: None
+//
+// Referral(s): None
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SplitLFN (
+ IN CHAR16 *LongName,
+ IN DIR_ENTRY_32 *ShortEntry,
+ OUT DIR_ENTRY_LFN *Slot,
+ OUT UINT32 *NumSlots
+)
+{
+ UINT32 NamePos;
+ UINT32 SlotPos;
+ UINT8 Order;
+ UINT8 Checksum = LfnChecksum((UINT8 *)ShortEntry);
+ UINT32 CharCnt;
+ UINT32 Position;
+ INTN i;
+
+ CharCnt = (UINT32) Wcslen(LongName);
+ *NumSlots = CharCnt / 13;
+
+ if (CharCnt % 13) *NumSlots += 1; // Name not evenly divisible by 13
+
+ Order = *NumSlots;
+ Position = 13 * (Order - 1); // Starting position for extracting characters.
+
+ for (i=0; Order; i++, Order--) {
+ // Fill in the non-name stuff
+ Slot[i].Dir_Order = Order; // 1-based numeration
+ Slot[i].Dir_Attr = (ATTR_LONG_NAME);
+ Slot[i].Dir_Reserved = 0;
+ Slot[i].Dir_Checksum = Checksum;
+ Slot[i].Dir_FstClus = 0;
+ Slot[i].Dir_FstClus = 0;
+ // Fill in the name
+ NamePos = Position;
+ SlotPos = 0;
+
+ while (LongName[NamePos] && SlotPos < 13) {
+ CopyCharsToLfnSlot(&Slot[i], SlotPos++, LongName[NamePos]);
+
+ if (++NamePos == MAX_LFN_LENGTH) return EFI_INVALID_PARAMETER;
+ }
+
+ if (i == 0) { // If last slot
+ // Mark the slot as last
+ Slot[i].Dir_Order |= 0x40;
+ // Insert a Unicode NULL terminator, only if it fits into the slots
+ CopyCharsToLfnSlot(&Slot[i], SlotPos++, 0x0000);
+
+ // Pad the remaining characters of the slot with FFFFh
+ while (SlotPos < 13) CopyCharsToLfnSlot(&Slot[i], SlotPos++, 0xFFFF);
+ }
+
+ Position -= 13; // Back up to next section to process
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/FileFatHandler.c b/Core/EM/FileSystem/FileFatHandler.c
new file mode 100644
index 0000000..1447f62
--- /dev/null
+++ b/Core/EM/FileSystem/FileFatHandler.c
@@ -0,0 +1,898 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/FileSystem/FileFatHandler.c 1 10/25/12 8:53a Wesleychen $
+//
+// $Revision: 1 $
+//
+// $Date: 10/25/12 8:53a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/FileSystem/FileFatHandler.c $
+//
+// 1 10/25/12 8:53a Wesleychen
+// Update it for EIP#104620.
+//
+// 7 10/05/12 5:50p Pats
+// [TAG] EIP99324
+// [Category] Bug Fix
+// [Symptom] Image files used in GUI Version of AMIDiag getting renamed
+// [RootCause] If the long name component of a directory was in a separate
+// cluster from the short name component, it was being over-written.
+// [Solution] Added new function FindLongNamePiece() to FileFatHandler.c.
+// It is called from GetSpaceforDirEntry().
+// [Files] FileFatHandler.c
+//
+// 6 6/11/10 5:40p Pats
+// EIP 39171: Long name sometimes not displayed, only short name.
+// FetchLongName() in Open.c did not handle case where long name spilt
+// over 2 clusters. Function modified to handle the case.
+// Call to FetchLongName() changed here because parameters changed.
+//
+// 5 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 4 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 3 6/21/05 4:00p Pats
+// Modified to call MarkVolumeDirty when EFI_VOLUME_CORRUPTED error
+// occurs. Removed commented-out debug code.
+//
+// 2 6/16/05 4:14p Pats
+// Modified to return error if reading file with premature EOF in fat
+// chain.
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FileFatHndlr.c
+//
+// Description: Fat File System driver -- File Level Fat Handler
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "FileSystem.h"
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LocateFreeDirEntry
+//
+// Description: Locates a free entry in a directory
+//
+// Parameters: FILE_HANDLE *fh - Handle of file requireing entry
+// UINT32 FreeBytesRequired - No. of bytes required for
+// the new entry
+// UINT32 *FreeDirCluster - Returned Cluster of free entry
+// UINT32 *FreeDirClusterOffset - Offset of free entry
+//
+// Returned value: EFI_STATUS - Status of the operation
+//
+// Modified: None
+//
+// Referral(s): None
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LocateFreeDirEntry(
+ IN FILE_HANDLE *fh,
+ IN UINT32 FreeBytesRequired,
+ OUT UINT32 *FreeDirCluster,
+ OUT UINT32 *FreeDirClusterOffset,
+ OUT BOOLEAN *LastDirEntry
+)
+{
+
+ EFI_STATUS Status;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+
+ // If free Dir Entry not found earlier, use the long method
+ if (fh->FreeDirEntryCluster == 0 && fh->FreeDirEntryOffset == 0)
+ return GetSpaceforDirEntry(fh, FreeBytesRequired, FreeDirCluster, FreeDirClusterOffset, LastDirEntry);
+
+ // Use the existing data to speed up the search
+ Status = CheckforValidDirSpace (Vi, fh->ROOTDIR, fh->FreeDirEntryCluster, fh->FreeDirEntryOffset,
+ FreeBytesRequired, FreeDirCluster, FreeDirClusterOffset);
+
+ if (Status == EFI_SUCCESS) *LastDirEntry = TRUE;
+
+ // Above Routine failed. For FAT12/16, limited ROOT directory entries are
+ // available. So go through the entire list.
+ if (EFI_ERROR(Status) && fh->ROOTDIR && (Vi->FatType != FAT32))
+ return GetSpaceforDirEntry(fh, FreeBytesRequired, FreeDirCluster, FreeDirClusterOffset, LastDirEntry);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindLongNamePiece
+//
+// Description: Returns TRUE if there is a valid long name part of a
+// directory entry at Offset position in Buffer.
+//
+// Parameters:
+// UINT8 *Buffer - Buffer to search in
+// UINT32 *Offset - Offset in buffer where entry found
+//
+// Return Value:
+// BOOLEAN - True = Long name piece found
+//
+// Modified:
+//
+// Referrals: GetSpaceforDirEntry
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+FindLongNamePiece (
+ UINT8 *Buffer,
+ UINT32 *Offset
+)
+{
+ DIR_ENTRY_32 *Entry = (DIR_ENTRY_32 *)(Buffer + *Offset);
+
+ if ((Entry->Dir_Name[0] == 0) || (Entry->Dir_Name[0] == 0xE5)) {
+ return FALSE; // not an existing entry.
+ }
+
+ if ( ((Entry->Dir_Attr & ATTR_LONG_NAME_MASK) == (ATTR_LONG_NAME)) &&
+ ((Entry->Dir_Name[0] >> 4) == 0) ||
+ ((Entry->Dir_Name[0] >> 4) >= 4) ) {
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetSpaceforDirEntry
+//
+// Description: Enlarges directory to make space for a new entry
+//
+// Parameters: FILE_HANDLE *fh - Handle of file requireing entry
+// UINT32 FreeBytesRequired - No. of bytes required for
+// the new entry
+// UINT32 *FreeDirCluster - Returned Cluster of free entry
+// UINT32 *FreeDirClusterOffset - Offset of free entry
+// BOOLEAN *LastDirEntry - True if new entry is the last one
+// in the directory
+//
+// Return Value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referrals:
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetSpaceforDirEntry(
+ IN FILE_HANDLE *fh,
+ IN UINT32 FreeBytesRequired,
+ OUT UINT32 *FreeDirCluster,
+ OUT UINT32 *FreeDirClusterOffset,
+ BOOLEAN *LastDirEntry
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 Offset, BufferSize, OrgBufferSize;
+ UINT32 BytesReadPerLoop;
+ UINT8 *Buffer;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+ UINT32 ClusterNumber, Cluster, LastValidCluster;
+ UINT32 CurrentOffset, Slots;
+ UINT16 lfn[256];
+
+
+ // Allocate space for a temp buffer.
+ BytesReadPerLoop = Vi->BytesPerCluster;
+
+ if (fh->ROOTDIR && (Vi->FatType != FAT32))
+ BytesReadPerLoop = Vi->RootDirSectorCount << Vi->BytesPerSecPowerof2;
+
+
+ GetTempBuffer (Vi, &Buffer);
+//###DEBUG
+// Status = fsAllocateMemory (Vi, BytesReadPerLoop, &Buffer, FALSE);
+// Status = fsAllocateMemory (Vi, 256, (VOID**)&lfn, FALSE);
+// if(EFI_ERROR(Status)) return EFI_NOT_FOUND;
+//###DEBUG END
+ LastValidCluster = FIRSTCLUSTER(fh->DirectoryEntry);
+
+ for (ClusterNumber = 0; ClusterNumber < Vi->CountOfDataClusters ; ClusterNumber++) {
+ Cluster = 0;
+ Status = ReadClusterOfDirectoryEntries(fh, ClusterNumber, &Cluster, Buffer, &BytesReadPerLoop);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Status == EFI_SUCCESS && BytesReadPerLoop == 0) {
+
+ if (fh->ROOTDIR && (Vi->FatType != FAT32)) return EFI_ACCESS_DENIED; // Dir. entry cannot be created
+
+//###DEBUG
+ /*
+ #ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"DirName %s Clusters ", fh->FileNameLFN);
+ #endif
+ Status = AllocateAndLinkClusters (Vi, LastValidCluster, Vi->BytesPerCluster, &Cluster, &ClusterCount);
+ #ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"\n");
+ #endif
+ *FreeDirClusterOffset = 0;
+ *FreeDirCluster = Cluster;
+
+ // Zero out the New cluster allocated.
+ Status = ZeroOutdisk(Vi, Cluster, *FreeDirClusterOffset, Vi->BytesPerCluster);
+ */
+//###DEBUG END
+ Status = CheckforValidDirSpace (Vi, fh->ROOTDIR, LastValidCluster, Vi->BytesPerCluster,
+ FreeBytesRequired, FreeDirCluster, FreeDirClusterOffset);
+ *LastDirEntry = TRUE;
+ break;
+ }
+
+ LastValidCluster = Cluster;
+ OrgBufferSize = BytesReadPerLoop;
+ BufferSize = BytesReadPerLoop;
+ CurrentOffset = Offset = 0;
+ *FreeDirCluster = Cluster;
+ Status = EFI_NOT_FOUND;
+
+ for ( ; CurrentOffset < OrgBufferSize; Offset = CurrentOffset, BufferSize = OrgBufferSize - CurrentOffset) {
+
+ if (Buffer[Offset] == 0) {
+ Status = CheckforValidDirSpace (Vi, fh->ROOTDIR, Cluster, Offset,
+ FreeBytesRequired, FreeDirCluster, FreeDirClusterOffset);
+ *LastDirEntry = TRUE;
+ break;
+ }
+
+
+ if (FindShortName (Buffer, &Offset, BufferSize)) {
+ Slots = FetchLongName(fh, (DIR_ENTRY_32 *)(Buffer), Offset, lfn, ClusterNumber, BytesReadPerLoop);
+
+ if (Offset && ((Offset - Slots * sizeof(DIR_ENTRY_32) - CurrentOffset) >= FreeBytesRequired)) {
+ *FreeDirClusterOffset = CurrentOffset;
+ *LastDirEntry = FALSE;
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ CurrentOffset = Offset + sizeof(DIR_ENTRY_32);
+ continue;
+
+ } else {
+
+ if (BufferSize > 0) {
+ while (FindLongNamePiece (Buffer, &CurrentOffset)) {
+ CurrentOffset += sizeof(DIR_ENTRY_32);
+ BufferSize -= sizeof(DIR_ENTRY_32);
+ if (BufferSize == 0) break;
+ }
+ }
+
+ if (BufferSize >= FreeBytesRequired) {
+ *FreeDirClusterOffset = CurrentOffset;
+ *LastDirEntry = FALSE;
+ Status = EFI_SUCCESS;
+ }
+
+ break;
+ }
+ }
+
+ if (Status == EFI_SUCCESS) break;
+
+ }
+
+//###DEBUG
+// fsDeAllocateMemory (Vi, Buffer);
+// fsDeAllocateMemory (Vi, lfn);
+//###DEBUG END
+ ReleaseTempBuffer (Vi);
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckforValidDirSpace
+//
+// Description: Cluster and Offset should point after the last valid directory entry.
+//
+// Parameters:
+// IN VOLUME_INFO *Vi - Volume info structure
+// IN BOOLEAN ROOTDIR - true if root directory
+// IN UINT32 Cluster - Starting cluster
+// IN UINT32 Offset - Offset in cluster
+// IN UINT32 FreeBytesRequired
+// IN UINT32 *FreeDirCluster
+// IN UINT32 *FreeDirClusterOffset
+//
+// Return Value: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: No Directory Entry Will be created which crosses CLUSTER BOUNDRY
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CheckforValidDirSpace (
+ IN VOLUME_INFO *Vi,
+ IN BOOLEAN ROOTDIR,
+ IN UINT32 Cluster,
+ IN UINT32 Offset,
+ IN UINT32 FreeBytesRequired,
+ IN UINT32 *FreeDirCluster,
+ IN UINT32 *FreeDirClusterOffset
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 ByteToCompare = Vi->BytesPerCluster;
+ UINT32 Sector, SectorOffset, ClusterCount;
+ UINT8 BData;
+
+
+ if (ROOTDIR && (Vi->FatType != FAT32)) ByteToCompare = Vi->RootDirSectorCount << Vi->BytesPerSecPowerof2;
+
+ if (ByteToCompare - Offset >= FreeBytesRequired) {
+// Free Entry Found with in the cluster
+ *FreeDirCluster = Cluster;
+ *FreeDirClusterOffset = Offset;
+ return Status;
+ }
+
+// For ROOT and FAT12/16, new clusters cannot be added.
+ if (ROOTDIR && (Vi->FatType != FAT32)) return EFI_ACCESS_DENIED;
+
+// From Cluster/offset to end of Cluster make sure there are no '0' in the first Byte Position of the directory Entry.
+ for ( ; ByteToCompare - Offset; ) {
+ GetAbsSectorInfo(Vi, Cluster, Offset, &Sector, &SectorOffset);
+ Status = FsReadMedia (Vi, &BData, Sector, SectorOffset, 1, DIRECTORY_REGION);
+
+ if (BData == 0) {
+ BData = DIR_ENTRY_ERASE;
+ Status = FsWriteMedia (Vi, &BData, Sector, SectorOffset, 1, DIRECTORY_REGION);
+ }
+
+ Offset += sizeof (DIR_ENTRY_32);
+ }
+
+#ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"Dir Name Not found");
+#endif
+// Allocate a New Cluster
+// Status = AllocateAndLinkNewCluster (Vi, Cluster, FreeDirCluster);
+ Status = AllocateAndLinkClusters (Vi, Cluster, Vi->BytesPerCluster, FreeDirCluster, &ClusterCount);
+#ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"\n");
+#endif
+ *FreeDirClusterOffset = 0;
+
+// Zero out the New cluster allocated.
+ Status = ZeroOutdisk(Vi, *FreeDirCluster, *FreeDirClusterOffset, Vi->BytesPerCluster);
+ return Status;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ZeroOutdisk
+//
+// Description: Zeros out directory region of disk
+//
+// Parameters:
+// IN VOLUME_INFO *Vi - Volume info structure
+// IN UINT32 Cluster - Cluster in directory region to zero
+// IN UINT32 ClusterOffset - Offset in cluster
+// IN UINT32 Size - Size to zero
+//
+// Return value: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ZeroOutdisk (
+ IN VOLUME_INFO *Vi,
+ IN UINT32 Cluster,
+ IN UINT32 ClusterOffset,
+ IN UINT32 Size
+)
+{
+ UINT32 Sector, SectorOffset;
+ UINT8 *Buffer;
+ EFI_STATUS Status;
+
+// fsAllocateMemory (Vi, Size, (void **)&Buffer, TRUE);
+ GetTempBuffer (Vi, &Buffer);
+ Zeromemory (Buffer, Size);
+ GetAbsSectorInfo(Vi, Cluster, ClusterOffset, &Sector, &SectorOffset);
+ Status = FsWriteMedia (Vi, Buffer, Sector, SectorOffset, Size, DIRECTORY_REGION);
+// fsDeAllocateMemory(Vi, Buffer);
+ ReleaseTempBuffer (Vi);
+
+ if (EFI_ERROR(Status)) {
+ HandleDiskIoError (Vi, Status);
+ return Status;
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ExtendFile
+//
+// Description: Extends a file on the disk (it is written to)
+//
+// Parameters:
+// IN FILE_HANDLE_INSTANCE *fhi - File handle instance
+// IN UINT32 Length - Length to extend
+//
+// Return value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ExtendFile (
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN UINT32 Length
+)
+{
+
+ UINT64 OrgPosition;
+ FILE_HANDLE *fh = fhi->pFH;
+ VOLUME_INFO *vi = fhi->pFH->VolumeInterface;
+ EFI_STATUS Status;
+ UINT32 FirstCluster, NewClusterCount, RemainingClusterLength = 0;
+
+#ifdef Debug_WriteFile
+ EfiDebugPrint(-1,"File to be Extended by Length %x \n", Length);
+#endif
+
+// Save the Current Position
+ OrgPosition = fhi->Position;
+
+// Set the Position to the End of the File
+ SetPositionFileHandle (fhi, -1);
+
+// Check if there is remaming space in the current cluster
+ if (fhi->CurrentCluster)
+ RemainingClusterLength = vi->BytesPerCluster - fhi->CurrentClusterOffset;
+
+ if (Length > RemainingClusterLength) {
+ Length = Length - RemainingClusterLength;
+#ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"FileName %s Clusters ", fh->FileNameLFN);
+#endif
+ Status = AllocateAndLinkClusters(vi, fhi->CurrentCluster, Length, &FirstCluster, &NewClusterCount);
+#ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"\n");
+#endif
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ if (fhi->CurrentCluster == 0 && fhi->CurrentClusterOffset == 0) {
+ fh->DirectoryEntry.Dir_FstClusLO = (UINT16) FirstCluster;
+ fh->DirectoryEntry.Dir_FstClusHI = FirstCluster >> 16;
+ }
+
+// Restore File Position
+ SetPositionFileHandle (fhi, OrgPosition);
+
+ fh->DirectoryEntry.Dir_Attr |= ATTR_ARCHIVE;
+ fh->DirEntryChanged = TRUE;
+ return EFI_SUCCESS;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ReadWriteExistingBlock
+//
+// Description: Reads or writes an existing file. If writing, writes
+// only an existing block, with no new allocation.
+//
+// Parameters:
+// IN FILE_HANDLE_INSTANCE *File - File handle instance
+// IN OUT VOID *Buffer - Output biffer
+// IN OUT UINT32 *Size - Size written or read
+// IN REGIONS DataRegion - Region of disk used (dir, fat, normal)
+// IN ACCESS_METHOD Method - Method (read or write)
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ReadWriteExistingBlock (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN OUT VOID *Buffer,
+ IN OUT UINT32 *Size,
+ IN REGIONS DataRegion,
+ IN ACCESS_METHOD Method
+)
+{
+ EFI_STATUS Status;
+ VOLUME_INFO *Vol = File->pFH->VolumeInterface;
+ UINT32 TotalContigousBytes;
+ UINT32 TotalBytesRead = 0;
+ UINT32 NextCluster, ClusterCount, AbsSector, AbsSectorOffset, AccessBytes;
+ UINT32 Position = (UINT32) File->Position;
+
+ do {
+
+ Status = GetContiguousClusters(Vol, *Size + File->CurrentClusterOffset, File->CurrentCluster,
+ &NextCluster, &ClusterCount); // CurrentSector and CurrentSectorOffset
+
+ if (EFI_ERROR(Status)) break;
+
+ if (!ClusterCount) break;
+
+ TotalContigousBytes = (ClusterCount * (UINT32)Vol->VolumeBPB.BPB_SecPerClus) << Vol->BytesPerSecPowerof2;
+ TotalContigousBytes -= File->CurrentClusterOffset;
+
+ if ( TotalContigousBytes > *Size) AccessBytes = *Size;
+
+ else AccessBytes = TotalContigousBytes;
+
+ GetAbsSectorInfo (Vol, File->CurrentCluster, File->CurrentClusterOffset, &AbsSector, &AbsSectorOffset);
+
+ if ((Method == READ_BLOCK) && (AccessBytes == 0)) {
+ MarkVolumeDirty (Vol);
+ return EFI_VOLUME_CORRUPTED; // Will happen if early EOF.
+ }
+
+ if (Method == READ_BLOCK) {
+ Status = FsReadMedia (Vol,
+ Buffer,
+ AbsSector,
+ AbsSectorOffset,
+ AccessBytes,
+ DATA_REGION);
+
+ } else {
+ Status = FsWriteMedia (Vol,
+ Buffer,
+ AbsSector,
+ AbsSectorOffset,
+ AccessBytes,
+ DATA_REGION);
+ }
+
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ (UINT8 *)Buffer += AccessBytes;
+ TotalBytesRead +=AccessBytes;
+ *Size -= AccessBytes;
+ Position += AccessBytes;
+ File->Position = Position;
+//###DEBUG
+//TODO TODO TODO TODO
+//Can call getpositionfilehandle to save some space.
+//TODO TODO TODO TODO
+//###DEBUG END
+ File->CurrentCluster += ((AccessBytes + File->CurrentClusterOffset) / Vol->BytesPerCluster);
+ File->CurrentClusterOffset = (AccessBytes + File->CurrentClusterOffset) % Vol->BytesPerCluster;
+
+ if (!File->CurrentClusterOffset) {
+ if (NextCluster >= Vol->EOCMark) {
+ File->CurrentCluster--;
+ File->CurrentClusterOffset = Vol->BytesPerCluster;
+
+ } else File->CurrentCluster = NextCluster;
+ }
+ } while (*Size);
+
+ *Size = TotalBytesRead;
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ReadFromFile
+//
+// Description: Reads a specified number of bytes from a file into a
+// specified buffer, beginning at a specified position
+// in the file. Updates Size to number of bytes read.
+// Updates Position to position after data read.
+//
+// Parameters:
+// IN FILE_HANDLE_INSTANCE *File - File handle instance
+// IN OUT VOID *Buffer - Buffer to read into
+// IN OUT UINT32 *Size - Size to read (updated with size read)
+// IN REGIONS DataRegion - Region of disk (dir, fat, normal)
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ReadFromFile (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN OUT VOID *Buffer,
+ IN OUT UINT32 *Size,
+ IN REGIONS DataRegion
+)
+{
+ EFI_STATUS Status;
+ UINT32 Position = (UINT32) File->Position;
+ ACCESS_METHOD Method = READ_BLOCK;
+
+
+// If Position (Zero Based) beyond EOF?
+ if (Position >= File->pFH->DirectoryEntry.Dir_FileSize) {
+ *Size = 0;
+
+ if (Position == File->pFH->DirectoryEntry.Dir_FileSize)
+ return EFI_SUCCESS;
+
+ else
+ return EFI_DEVICE_ERROR;
+ }
+
+// If bytes to be read exceed the file size, truncate it.
+ if ((Position + *Size) > File->pFH->DirectoryEntry.Dir_FileSize) *Size = File->pFH->DirectoryEntry.Dir_FileSize - Position;
+
+ Status = ReadWriteExistingBlock (File,
+ Buffer,
+ Size,
+ DataRegion,
+ Method);
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: WriteToFile
+//
+// Description: Writes a specified number of bytes to a file from a
+// specified buffer, beginning at a specified position
+// in the file. Updates Size to number of bytes written.
+// Updates Position to position after data written.
+//
+// Parameters:
+// IN FILE_HANDLE_INSTANCE *File - File handle instance
+// IN OUT VOID *Buffer - Buffer to write from
+// IN OUT UINT32 *Size - Size to write (updated with written)
+// IN REGIONS DataRegion - Data region (dir, fat, normal)
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+WriteToFile (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN OUT VOID *Buffer,
+ IN OUT UINT32 *Size,
+ IN REGIONS DataRegion
+)
+{
+ EFI_STATUS Status;
+ VOLUME_INFO *Vol = File->pFH->VolumeInterface;
+ UINT32 Position = (UINT32) File->Position;
+ ACCESS_METHOD Method = WRITE_BLOCK;
+ UINT32 TempSize, RemainingBytes;
+
+ if (File->pFH->DirectoryEntry.Dir_Attr & ATTR_READ_ONLY) return EFI_ACCESS_DENIED;
+
+ if ((Position + *Size) <= File->pFH->DirectoryEntry.Dir_FileSize) {
+// First case -- Writing to existing portion of file (over-writing existing file).
+ Status = ReadWriteExistingBlock(File, Buffer, Size, DataRegion, Method);
+
+ if ( EFI_ERROR(Status)) return Status; // Or other error processing
+
+#ifdef Debug_WriteFile
+ EfiDebugPrint(-1,"WriteToFile: Position %lx Length %x \n", File->Position, *Size);
+#endif
+
+ } else if (File->pFH->DirectoryEntry.Dir_FileSize == 0) {
+// Second case -- Writing to new unallocated space.
+ Status = ExtendFile (File, *Size);
+
+ if (EFI_ERROR(Status)) return Status; // Or other error processing
+
+ File->pFH->DirectoryEntry.Dir_FileSize = *Size;
+ Status = ReadWriteExistingBlock(File, Buffer, Size, DataRegion, Method);
+
+ if (EFI_ERROR(Status)) return Status; // Or other error processing
+
+#ifdef Debug_WriteFile
+ EfiDebugPrint(-1,"WriteToFile: Position %lx Length %x \n", File->Position, *Size);
+#endif
+
+ } else {
+// Third case -- Overwriting existing file, and extending it to unallocated space.
+ RemainingBytes = *Size;
+
+ if (Position < File->pFH->DirectoryEntry.Dir_FileSize) {
+ TempSize = File->pFH->DirectoryEntry.Dir_FileSize - Position;
+ Status = ReadWriteExistingBlock(File, Buffer, &TempSize, DataRegion, Method);
+
+ if (EFI_ERROR(Status)) return Status; // Or other error processing
+
+#ifdef Debug_WriteFile
+ EfiDebugPrint(-1,"WriteToFile: Position %lx Length %x \n", File->Position, TempSize);
+#endif
+ Position = (UINT32) File->Position;
+ RemainingBytes = *Size - TempSize;
+ }
+
+// TODO TODO TODO TODO
+// if Position is greater than FileSize, the extended buffer should be zerod out
+// TODO TODO TODO TODO
+// Extend the File
+ if (RemainingBytes) {
+ TempSize = Position - File->pFH->DirectoryEntry.Dir_FileSize + RemainingBytes;
+ Status = ExtendFile (File, TempSize);
+
+ if (EFI_ERROR(Status)) return Status; // Or other error processing
+
+ File->pFH->DirectoryEntry.Dir_FileSize += TempSize;
+ Status = ReadWriteExistingBlock(File, Buffer, &RemainingBytes, DataRegion, Method);
+
+ if (EFI_ERROR(Status)) return Status; // Or other error processing
+
+#ifdef Debug_WriteFile
+ EfiDebugPrint(-1,"WriteToFile: Position %lx FileSize %x \n",
+ File->Position, File->pFH->DirectoryEntry.Dir_FileSize);
+#endif
+
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckFileWrite
+//
+// Description: Checks if file can be written to
+//
+// Parameters:
+// FILE_HANDLE_INSTANCE *fhi - File Handle instance
+// BOOLEAN IgnoreOpenMode - If true, ignore mode file was
+// open with
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CheckFileWrite (
+ FILE_HANDLE_INSTANCE *fhi,
+ BOOLEAN IgnoreOpenMode
+)
+{
+
+ FILE_HANDLE *Pfh = fhi->pFH;
+ VOLUME_INFO *vi = Pfh->VolumeInterface;
+
+ // Check for Write Protect
+ if (vi->ReadOnly || Pfh->DirectoryEntry.Dir_Attr & ATTR_READ_ONLY)
+ return EFI_WRITE_PROTECTED;
+
+ if (Pfh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY)
+ return EFI_UNSUPPORTED; // see sec 11-27 For Directory writes
+
+ // Check the attribute of the FILE. Is it opened in Readonly mode
+ if (!IgnoreOpenMode)
+ if (fhi->OpenMode == EFI_FILE_MODE_READ) return EFI_ACCESS_DENIED;
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/FileSYstem.mak b/Core/EM/FileSystem/FileSYstem.mak
new file mode 100644
index 0000000..31872e8
--- /dev/null
+++ b/Core/EM/FileSystem/FileSYstem.mak
@@ -0,0 +1,75 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/FileSystem/FileSYstem.mak 4 12/09/05 11:08a Felixp $
+#
+# $Revision: 4 $
+#
+# $Date: 12/09/05 11:08a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/FileSystem/FileSYstem.mak $
+#
+# 4 12/09/05 11:08a Felixp
+#
+# 2 12/02/05 11:22a Felixp
+#
+# 1 12/01/05 9:44a Felixp
+#
+# 2 5/24/05 11:55a Felixp
+# reference to EfiDebugLib removed
+#
+# 1 4/26/05 6:05p Srinin
+#
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: SIMPLE_FILES_SYSTEM_MAK
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : FILE_SYSTEM
+
+FILE_SYSTEM: $(BUILD_DIR)\FileSystem.mak FileSystemBin
+
+$(BUILD_DIR)\FileSystem.mak : $(FILESYSTEM_DIR)\$(@B).cif $(FILESYSTEM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FILESYSTEM_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+FileSystemBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FileSystem.mak all\
+ GUID=93022F8C-1F09-47EF-BBB2-5814FF609DF5\
+ ENTRY_POINT=SimpleFileSystemEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
diff --git a/Core/EM/FileSystem/FileSystem.c b/Core/EM/FileSystem/FileSystem.c
new file mode 100644
index 0000000..760d55b
--- /dev/null
+++ b/Core/EM/FileSystem/FileSystem.c
@@ -0,0 +1,948 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/FileSystem.c 16 11/03/11 6:20a Rajeshms $
+//
+// $Revision: 16 $
+//
+// $Date: 11/03/11 6:20a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/FileSystem.c $
+//
+// 16 11/03/11 6:20a Rajeshms
+// [TAG] EIP73261
+// [Category] Improvement
+// [Description] FileSystem Driver Follow the UEFI Driver Model as per
+// the UEFI Spec. and STOP function was Verified.
+// [Files] FileSystem.c
+//
+// 15 11/18/10 3:05p Felixp
+// Removable media detection problem(EIP 47788).
+// Symptoms: The "map -r" Shell command didn't detect removable media
+// such as floppy or CD if the media had been removed and than inserted
+// back.
+//
+// 14 8/28/09 12:28p Felixp
+// Support for both UnicodeCollation and UnicodeCollation2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 13 8/28/09 11:59a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 12 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 11 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 10 12/21/06 1:44p Felixp
+// Bug fix in FileSystemInitUnicodeCollation: only first language in the
+// list of UNICODE_COLLATION supported languages was checked.
+//
+// 9 9/13/06 3:42p Pats
+// Corrected validation test comparing Media ID byte to first FAT byte to
+// use Bytes Per Sector instead of Block Size in calculating FAT offset.
+// This corrects problem of it not working on El Torito CD disks.
+//
+// 8 8/16/06 12:03p Markw
+// Fixed UINTN* and UINT32* 64-bit issues.
+//
+// 7 8/15/06 6:30p Markw
+// Reverting back to version 5.
+//
+// 5 3/29/06 2:53p Srinin
+// Memory Deallocation problem fixed.
+//
+// 4 3/13/06 5:08p Pats
+// Removed validation test using BS_BootSig. Added validation test
+// comparing BPB_Media with first FAT byte.
+//
+// 3 3/13/06 2:23a Felixp
+//
+// 2 12/08/05 2:21p Pats
+// Checked in from other directory, will latest fixes.
+//
+// 8 11/29/05 6:07p Pats
+// Fixed problem of partition table being incorrectly recognized as a
+// FAT12 drive boot sector.
+//
+// 7 11/03/05 2:15p Srinin
+// Fixed VC7.1 warning msg.
+//
+// 6 8/15/05 1:16p Srinin
+// SimpleFileSystemStart changed to return proper Status code.
+//
+// 4 6/21/05 4:00p Pats
+// Removed commented-out debug code.
+//
+// 3 5/27/05 10:00a Srinin
+// Volume size and Free space calculation modified.
+//
+// 2 5/24/05 11:56a Felixp
+// reference to EfiDebugLib removed
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FileSystem.c
+//
+// Description: Installs Simple File System Protocol
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "FileSystem.h"
+
+//----------------------------------------------------------------------
+
+EFI_GUID gSimpleFileSystemBusDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+EFI_GUID guidLoadedImage = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#else
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+#endif
+EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+EFI_GUID gEfiDiskIoProtocolGuid = EFI_DISK_IO_PROTOCOL_GUID;
+EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+#ifndef EFI_UNICODE_COLLATION2_PROTOCOL_GUID //old Core
+EFI_GUID gEfiUnicodeCollationProtocolGuid = EFI_UNICODE_COLLATION_PROTOCOL_GUID;
+#else
+EFI_GUID gEfiUnicodeCollationProtocolGuid = EFI_UNICODE_COLLATION2_PROTOCOL_GUID;
+#endif
+EFI_GUID gEfiFileInfoGuid = EFI_FILE_INFO_ID;
+EFI_GUID gEfiFileSystemInfoGuid = EFI_FILE_SYSTEM_INFO_ID;
+EFI_GUID gEfiFileSystemVolumeLabelGuid = EFI_FILE_SYSTEM_VOLUME_LABEL_ID;
+
+EFI_UNICODE_COLLATION_PROTOCOL *gFileSystemUnicodeCollationInterface = NULL;
+
+extern EFI_COMPONENT_NAME_PROTOCOL gSimpleFileSystemDriverName;
+extern EFI_GUID guidFS;
+
+EFI_DRIVER_BINDING_PROTOCOL gSimpleFileSystemDriverBinding = {
+ SimpleFileSystemSupported,
+ SimpleFileSystemStart,
+ SimpleFileSystemStop,
+ SIMPLE_FILE_SYSTEM_DRIVER_VERSION, // version
+ NULL, // ImageHandle
+ NULL // DriverBindingHandle
+};
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SimpleFileSystemEntryPoint
+//
+// Description: Installs gSimpleFileSystemDriverBinding protocol
+//
+// Parameters: EFI_HANDLE ImageHandle - Image handle for this driver
+// image
+// EFI_SYSTEM_TABLE *SystemTable - pointer to the EFI
+// system table
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SimpleFileSystemEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *ThisImage;
+
+ gSimpleFileSystemDriverBinding.DriverBindingHandle=ImageHandle;
+ gSimpleFileSystemDriverBinding.ImageHandle=ImageHandle;
+
+ InitAmiLib(ImageHandle, SystemTable);
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gSimpleFileSystemBusDriverBindingProtocolGuid,&gSimpleFileSystemDriverBinding,
+ &gComponentNameProtocolGuid, &gSimpleFileSystemDriverName,
+ NULL
+ );
+
+
+#ifdef Debug_Level_1
+ EfiDebugPrint(-1," SimpleFileSystemEntryPoint Exit Status %x\n",Status);
+#endif
+
+ Status = pBS->OpenProtocol (
+ ImageHandle,
+ &guidLoadedImage,
+ (VOID **)&ThisImage,
+ ImageHandle,
+ ImageHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status)) return Status;
+
+ ThisImage->Unload = UnloadSimpleFileSystemDriver;
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnloadSimpleFileSystemDriver
+//
+// Description: Unloads this driver
+//
+// Parameters: EFI_HANDLE ImageHandle - Image handle for this driver
+// image
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UnloadSimpleFileSystemDriver (
+ IN EFI_HANDLE ImageHandle
+)
+{
+ EFI_HANDLE *Buffer;
+ UINTN NoOfHandles, i;
+ EFI_STATUS Status;
+
+ Status = pBS->LocateHandleBuffer (AllHandles, NULL, NULL, &NoOfHandles, &Buffer);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NoOfHandles; i++) {
+ pBS->DisconnectController(Buffer[i], ImageHandle, NULL);
+ }
+
+ if (Buffer) pBS->FreePool(Buffer);
+
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ ImageHandle,
+ &gSimpleFileSystemBusDriverBindingProtocolGuid,&gSimpleFileSystemDriverBinding,
+ &gComponentNameProtocolGuid, &gSimpleFileSystemDriverName,
+ NULL);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SimpleFileSystemSupported
+//
+// Description: Checks whether Simple File System Protocol can be
+// installed on the controller or not.
+//
+// Parameters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of driver binding
+// protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S): DiskIO and BlockIO should have been installed on the
+// controller.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SimpleFileSystemSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+
+ EFI_STATUS Status;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+
+// Check if DiskIO can be opened by EFI_OPEN_PROTOCOL_BY_DRIVER
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDiskIoProtocolGuid,
+ (VOID **)&DiskIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+// Close DiskIO Protocol
+ Status = pBS->CloseProtocol (
+ Controller,
+ &gEfiDiskIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+
+// Check if BlockIO can be opened by EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **)&BlkIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ return EFI_SUCCESS;
+
+Error:
+
+ if( Status != (EFI_ALREADY_STARTED || EFI_ACCESS_DENIED) ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return Status;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SimpleFileSystemStart
+//
+// Description: Installs Simple File Ssystem Protocol
+//
+// Parameters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of driver binding
+// protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SimpleFileSystemStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+
+ EFI_STATUS Status;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+
+// Check if DiskIO can be opened by EFI_OPEN_PROTOCOL_BY_DRIVER
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiDiskIoProtocolGuid,
+ (VOID **)&DiskIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (EFI_ERROR (Status)) return EFI_DEVICE_ERROR;
+
+// Check if BlockIO can be opened by EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **)&BlkIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+// Get the UnicodeCollation driver
+ Status = FileSystemInitUnicodeCollation (This, &gFileSystemUnicodeCollationInterface);
+
+ if (EFI_ERROR (Status)) {
+ goto Error;
+ }
+
+ Status = DetectInstallVolume(DiskIo, BlkIo, Controller);
+
+ if (EFI_ERROR(Status)) {
+ goto Error;
+ }
+
+ return EFI_SUCCESS;
+
+Error:
+ //
+ // Close DiskIO Protocol
+ //
+ pBS->CloseProtocol (Controller,
+ &gEfiDiskIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ if( Status == EFI_OUT_OF_RESOURCES ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ return EFI_DEVICE_ERROR;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SimpleFileSystemStop
+//
+// Description: Uninstall Simple File system Protocol
+//
+// Parameters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of driver binding
+// protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SimpleFileSystemStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
+ VOLUME_INFO *vi;
+
+ Status = pBS->OpenProtocol ( Controller,
+ &guidFS,
+ &FileSystem,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ vi = (VOLUME_INFO *)FileSystem;
+
+ if (NumberOfChildren) return EFI_DEVICE_ERROR;
+
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ (vi->VolumeHandle),
+ &guidFS, &(vi->SimpleFileSystemProtocol),
+ NULL);
+
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+// Close DISK_IO Protocol
+ Status = pBS->CloseProtocol (
+ Controller,
+ &gEfiDiskIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ Status = fsDeAllocateMemory(vi, vi->TempBuffer);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ Status = FreeUpResources (vi, EFI_NO_MEDIA);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ Status = pBS->FreePool(vi->CacheBuffer);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ Status = pBS->FreePool(vi);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectInstallVolume
+//
+// Description: Detects whether a valid volume is present or not
+//
+// Parameters: EFI_DISK_IO_PROTOCOL *DiskIo - Pointer to disk IO
+// structure
+// Parameters: EFI_BLOCK_IO_PROTOCOL *DiskIo - Pointer to boock IO
+// structure
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectInstallVolume(
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_BLOCK_IO_PROTOCOL *BlkIo,
+ IN EFI_HANDLE Handle
+)
+{
+
+ EFI_STATUS Status;
+ VOLUME_INFO *vi;
+ UINT32 TempBufferSize, i, Fat_Cache_Blocks, Dir_Cache_Blocks, \
+ TotalCacheMemory, TotalCacheList;
+ UINTN CacheAddress, CacheListAddress;
+ CACHE_HEADER *ch;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof(VOLUME_INFO),
+ (VOID**)&vi);
+
+// No need to close IDE_CONTROLLER_PROTOCOL
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ Zeromemory (vi, sizeof(VOLUME_INFO));
+
+ vi->DiskIo = DiskIo;
+ vi->BlkIo = BlkIo;
+ vi->MediaID = vi->BlkIo->Media->MediaId;
+ Status = DetectVolume(vi, FALSE);
+
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(vi);
+ return Status;
+ }
+
+ vi->UnicodeCollationInterface = gFileSystemUnicodeCollationInterface;
+
+ vi->SimpleFileSystemProtocol.OpenVolume = OpenVolume;
+ vi->SimpleFileSystemProtocol.Revision = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION;
+ vi->VolumeHandle = Handle;
+ DListInit(&(vi->OpenFHs));
+ DListInit(&(vi->OpenFIs));
+ DListInit(&(vi->CacheList));
+
+// Allocate TempBuffer, max. cluster size which is 32KB
+ TempBufferSize = vi->RootDirSectorCount << vi->BytesPerSecPowerof2;
+
+ if (vi->BytesPerCluster > TempBufferSize) TempBufferSize = vi->BytesPerCluster;
+
+ Status = fsAllocateMemory(vi, TempBufferSize, (VOID**)&vi->TempBuffer, FALSE);
+
+// Init the cache Buffers
+ Fat_Cache_Blocks = vi->AllowedFatCacheSize / vi->BytesPerCluster;
+ Dir_Cache_Blocks = vi->AllowedDirCacheSize / vi->BytesPerCluster;
+
+ TotalCacheMemory = Fat_Cache_Blocks * vi->BytesPerCluster +
+ Dir_Cache_Blocks * vi->BytesPerCluster;
+
+ TotalCacheList = Fat_Cache_Blocks * sizeof (CACHE_HEADER) +
+ Dir_Cache_Blocks * sizeof (CACHE_HEADER);
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ TotalCacheMemory + TotalCacheList,
+ (VOID**)&vi->CacheBuffer);
+
+ CacheAddress = (UINTN) (vi->CacheBuffer);
+ CacheListAddress = (UINTN) (vi->CacheBuffer) + TotalCacheMemory;
+
+ for (i = 0; i < Fat_Cache_Blocks + Dir_Cache_Blocks; i++) {
+ ch = (CACHE_HEADER *)CacheListAddress;
+ ch->AbsoluteOffset = 0;
+ ch->AbsoluteOffsetEnd = 0;
+ ch->Buffer = (UINT8 *) CacheAddress;
+ ch->DIRTY_FLAG = FALSE;
+
+ if ( i < Fat_Cache_Blocks) ch->DataRegion = FAT_REGION;
+
+ else ch->DataRegion = DIRECTORY_REGION;
+
+ DListAdd(&(vi->CacheList), &(ch->CacheLink));
+ CacheAddress += vi->BytesPerCluster;
+ CacheListAddress += sizeof (CACHE_HEADER);
+ }
+
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &(vi->VolumeHandle),
+ &guidFS, &(vi->SimpleFileSystemProtocol),
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(vi);
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectVolume
+//
+// Description: Detects the presence of a valid FAT volume
+//
+// Parameters: VOLUME_INFO *vi - Pointer to the volume info structure
+// BOOLEAN StatusCheck - Only reads MBR if true
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectVolume (
+ VOLUME_INFO *vi,
+ BOOLEAN StatusCheck
+)
+{
+
+ EFI_STATUS Status;
+ VOLUME_BPB *Bpb;
+ UINT8 *Buffer;
+ UINT8 *Buffer2;
+ BOOLEAN VALID_FAT = TRUE;
+ UINT64 Offset;
+
+ Status = fsAllocateMemory(vi, vi->BlkIo->Media->BlockSize, (VOID**)&Buffer, FALSE);
+// Status = pBS->AllocatePool (EfiBootServicesData,
+// vi->BlkIo->Media->BlockSize,
+// (VOID**)&Buffer);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES; //No need to close IDE_CONTROLLER_PROTOCOL
+
+// Read Logical Sector 0
+ Status= vi->DiskIo->ReadDisk (vi->DiskIo, vi->MediaID, 0, vi->BlkIo->Media->BlockSize, Buffer);
+
+ // Read Second time if EFI_MEDIA_CHANGED is returned for media changeable devices
+ // (like CDROM/Floppy)
+ if( Status == EFI_MEDIA_CHANGED ) {
+ vi->MediaID = vi->BlkIo->Media->MediaId;
+ Status= vi->DiskIo->ReadDisk (vi->DiskIo, vi->MediaID, 0, vi->BlkIo->Media->BlockSize, Buffer);
+ }
+ if (EFI_ERROR(Status) || StatusCheck) {
+// pBS->FreePool(Buffer);
+ fsDeAllocateMemory(vi, Buffer);
+ vi->VolumeStatus = Status;
+ return Status;
+ }
+
+ Bpb = (VOLUME_BPB *)Buffer;
+
+ vi->FatType = FAT_UNKNOWN;
+
+// Check for 0x55aa at offset 510
+ if ( *(UINT16 *) ((UINT8 *)Buffer + 510) != 0xaa55) {
+// pBS->FreePool(Buffer);
+ fsDeAllocateMemory(vi, Buffer);
+ return EFI_UNSUPPORTED;
+ }
+
+// Check for valid jmp instruction
+ if (Buffer[0] != 0xEB && Buffer[0] != 0xE9 ) VALID_FAT = FALSE;
+
+// Check for valid Bytes per Sector
+ switch (Bpb->BPB_BytePerSec) {
+ case 512:
+ vi->BytesPerSecPowerof2 = 9;
+ break;
+ case 1024:
+ vi->BytesPerSecPowerof2 = 10;
+ break;
+ case 2048:
+ vi->BytesPerSecPowerof2 = 11;
+ break;
+ case 4096:
+ vi->BytesPerSecPowerof2 = 12;
+ break;
+ default:
+ VALID_FAT = FALSE;
+ }
+
+// Check for Valid Sectors per cluster
+ if (Bpb->BPB_SecPerClus != 1 && Bpb->BPB_SecPerClus != 2 &&
+ Bpb->BPB_SecPerClus != 4 && Bpb->BPB_SecPerClus != 8 &&
+ Bpb->BPB_SecPerClus != 16 && Bpb->BPB_SecPerClus != 32 &&
+ Bpb->BPB_SecPerClus != 64 && Bpb->BPB_SecPerClus != 128) VALID_FAT = FALSE;
+
+// Check for Reserved Sector Count and Number of FATS
+ if (Bpb->BPB_RsvdSecCnt == 0 || Bpb->BPB_NumFATs == 0) VALID_FAT = FALSE;
+
+// Both TotSec16 and TotSec32 cannot be zero
+ if (Bpb->BPB_TotSec16 == 0 && Bpb->BPB_TotSec32 == 0) VALID_FAT = FALSE;
+
+// This test removed (3-13-06)
+// If it is a FAT12 or FAT16 disk, and the boot signature is not 29, reject the disk.
+// if (Bpb->BPB_FATSz16 != 0 && Bpb->BPB_FAT.BPB_FAT1216.BS_BootSig != 0x29) VALID_FAT = FALSE;
+
+// This test added (3-13-06)
+// If the media byte doesn't match the first FAT byte, reject the disk.
+ if (VALID_FAT) {
+ Status = fsAllocateMemory(vi, Bpb->BPB_BytePerSec, (VOID**)&Buffer2, FALSE);
+
+ if (EFI_ERROR(Status)) {
+ fsDeAllocateMemory(vi, Buffer);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Offset = Bpb->BPB_RsvdSecCnt * Bpb->BPB_BytePerSec;
+ Status= vi->DiskIo->ReadDisk (vi->DiskIo, vi->MediaID, Offset, Bpb->BPB_BytePerSec, Buffer2);
+
+ if (EFI_ERROR(Status)) {
+ fsDeAllocateMemory(vi, Buffer);
+ fsDeAllocateMemory(vi, Buffer2);
+ return Status;
+ }
+
+ if (Bpb->BPB_Media != Buffer2[0]) VALID_FAT = FALSE;
+
+ fsDeAllocateMemory(vi, Buffer2);
+ }
+
+ if (!VALID_FAT) goto error_check;
+
+ vi->RootDirSectorCount = ((Bpb->BPB_RootEntCnt << 5 ) + (Bpb->BPB_BytePerSec - 1)) / Bpb->BPB_BytePerSec;
+
+ vi->FATSz = Bpb->BPB_FATSz16;
+
+ if (Bpb->BPB_FATSz16 == 0) vi->FATSz = Bpb->BPB_FAT.BPB_FAT32.BPB_FATSz32;
+
+ vi->TotalSectors = Bpb->BPB_TotSec16;
+
+ if (Bpb->BPB_TotSec16 == 0) vi->TotalSectors = Bpb->BPB_TotSec32;
+
+ vi->DataSectors = vi->TotalSectors \
+ - Bpb->BPB_RsvdSecCnt \
+ - vi->FATSz * Bpb->BPB_NumFATs \
+ - vi->RootDirSectorCount;
+
+ vi->CountOfDataClusters = vi->DataSectors / Bpb->BPB_SecPerClus;
+
+// There could be a few sectors at the "end" of the disk that will not completely
+// fill a cluster. Make sure these are not counted in the DataSectors.
+ vi->DataSectors = vi->CountOfDataClusters * Bpb->BPB_SecPerClus;
+
+ if (vi->CountOfDataClusters < 4085) {
+ vi->FatType = FAT12;
+ vi->EOCMark = 0x0ff8;
+
+ } else if (vi->CountOfDataClusters < 65525) {
+ vi->FatType = FAT16;
+ vi->EOCMark = 0x0fff8;
+
+ } else {
+ vi->FatType = FAT32;
+ vi->EOCMark = 0x0ffffff8;
+ }
+
+// Calculate where Root Directory Entries are present
+ if (vi->FatType == FAT32)
+ vi->FirstRootDirSector = Bpb->BPB_FAT.BPB_FAT32.BPB_RootClus * Bpb->BPB_SecPerClus;
+
+ else
+ vi->FirstRootDirSector = Bpb->BPB_RsvdSecCnt + (Bpb->BPB_NumFATs * Bpb->BPB_FATSz16);
+
+// Copy Sector Zero Contends to VOLUME_BPB in vi
+ pBS->CopyMem (&(vi->VolumeBPB), Buffer, sizeof(VOLUME_BPB));
+
+ vi->BytesPerCluster = (UINT32)vi->VolumeBPB.BPB_SecPerClus << vi->BytesPerSecPowerof2;
+
+// Update CacheSize
+ vi->AllowedFatCacheSize = FAT_CACHE_SIZE;
+
+ if (FAT_CACHE_SIZE < vi->BytesPerCluster << 1) vi->AllowedFatCacheSize = vi->BytesPerCluster << 1;
+
+ vi->AllowedDirCacheSize = DIR_CACHE_SIZE;
+
+ if (DIR_CACHE_SIZE < vi->BytesPerCluster << 1) vi->AllowedDirCacheSize = vi->BytesPerCluster << 1;
+
+error_check:
+ fsDeAllocateMemory(vi, Buffer);
+
+ if (vi->FatType == FAT_UNKNOWN) {
+ vi->VolumeStatus = EFI_UNSUPPORTED;
+ return EFI_UNSUPPORTED;
+ }
+
+ vi->VolumeStatus = EFI_SUCCESS;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FileSystemInitUnicodeCollation
+//
+// Description: Find the language Interface
+//
+// Parameters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of driver binding
+// protocol
+// UINT8 *LandCode - Pointer to the language code
+// EFI_UNICODE_COLLATION_PROTOCOL *gFileSystemUnicodeCollationInterface
+// - Pointer to pointer to unicode
+// collation interfact structure
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FileSystemInitUnicodeCollation (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN OUT EFI_UNICODE_COLLATION_PROTOCOL **gFileSystemUnicodeCollationInterface
+)
+{
+ EFI_STATUS Status;
+
+ if (*gFileSystemUnicodeCollationInterface != NULL) return EFI_SUCCESS;
+
+ // Locate all Unicode Collation Protocol
+ Status = pBS->LocateProtocol(
+ &gEfiUnicodeCollationProtocolGuid, NULL,
+ gFileSystemUnicodeCollationInterface
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Zeromemory
+//
+// Description: Zeros the contents of a specified memory location
+//
+// Parameters: VOID *Buffer - location of memory to zero
+// UINT32 Size - Size in bytes to zero
+//
+// Return Value: none
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S): For testing under Aptio and Alaska,
+// This routine has been copied.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+Zeromemory (
+ void *Buffer,
+ UINT32 Size
+)
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rig hts Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/FileSystem.chm b/Core/EM/FileSystem/FileSystem.chm
new file mode 100644
index 0000000..d45524f
--- /dev/null
+++ b/Core/EM/FileSystem/FileSystem.chm
Binary files differ
diff --git a/Core/EM/FileSystem/FileSystem.cif b/Core/EM/FileSystem/FileSystem.cif
new file mode 100644
index 0000000..ebeaf79
--- /dev/null
+++ b/Core/EM/FileSystem/FileSystem.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "FileSystem"
+ category = ModulePart
+ LocalRoot = "Core\EM\FileSystem\"
+ RefName = "FileSystem"
+[files]
+"\FileSystem.sdl"
+"\FileSYstem.mak"
+"\FileSystem.h"
+"\Open.c"
+"\FileSystem.c"
+"\FileFatHandler.c"
+"\Info.c"
+"\DirectoryHandler.c"
+"\VolFatHandler.c"
+"\MediaAccess.c"
+"\FileSystemComponentName.c"
+"\FileSystem.chm"
+<endComponent>
diff --git a/Core/EM/FileSystem/FileSystem.h b/Core/EM/FileSystem/FileSystem.h
new file mode 100644
index 0000000..092eb9d
--- /dev/null
+++ b/Core/EM/FileSystem/FileSystem.h
@@ -0,0 +1,1480 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/FileSystem.h 13 10/24/11 10:56a Artems $
+//
+// $Revision: 13 $
+//
+// $Date: 10/24/11 10:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/FileSystem.h $
+//
+// 13 10/24/11 10:56a Artems
+// EIP 73254: Remove "magic number" from source, added new #define macro
+//
+// 12 5/05/11 3:44p Pats
+// [TAG] - EIP 58999
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - Cannot launch Shell from USB Filesystem device in Debug
+// mode with latest Filesystem driver.
+// [RootCause] - Functions using DISKIO were raising TPL to a fixed level.
+// [Solution] - Modified above functions to check for the higher of the
+// fixed level or current level.
+// [Files] - Info.c, MediaAccess.c, Open.c, FileSystem.h
+//
+// 11 6/11/10 5:41p Pats
+// EIP 39171: Long name sometimes not displayed, only short name.
+// FetchLongName() in Open.c did not handle case where long name spilt
+// over 2 clusters. Function modified to handle the case.
+// Prototype changed here in this file.
+//
+// 10 8/28/09 11:59a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 9 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 8 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FileSystem.h
+//
+// Description: Header file for Simple File System driver
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#ifndef _SimpleFileSystem_
+#define _SimpleFileSystem_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//----------------------------------------------------------------------
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "protocol\DiskIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\SimpleFileSystem.h"
+#include "Protocol\UnicodeCollation.h"
+#include "Protocol\LoadedImage.h"
+#include <Protocol\ComponentName.h>
+
+#define SIMPLE_FILE_SYSTEM_DRIVER_VERSION 0x010000
+#define BS_OEMName_Offset 3
+#define BPB_BytePerSec_Offset 11
+#define BPB_SecPerClus_Offset 13
+#define BPB_RsvdSecCnt_Offset 14
+#define BPB_NumFATs_Offset 16
+#define BPB_RootEntCnt_Offset 17
+#define BPB_TotSec16_Offset 19
+#define BPB_Media_Offset 21
+#define BPB_FATSz16_Offset 22
+#define BPB_SecPerTrk_Offset 24
+#define BPB_NumHeads_Offset 26
+#define BPB_Hiddsec_Offset 28
+#define BPB_TotSec32_Offset 32
+
+
+#define BS_DrvNum_Offset 36
+#define BS_Reserved1_Offset 37
+#define BS_BootSig_Offset 38
+#define BS_VolID_Offset 39
+#define BS_VolLab_Offset 43
+#define BS_FilSysType_Offset 54
+
+#define BPB_FATSz32_Offset 36
+#define BPB_ExtFlags_Offset 40
+#define BPB_FSVer_Offset 42
+#define BPB_RootClus_Offset 44
+#define BPB_FSInfo_Offset 48
+#define BPB_BkBootSec_Offset 50
+#define BPB_Rserved_Offset 52
+#define BS_DrvNum_32_Offset 64
+#define BS_Reserved1_32_Offset 65
+#define BS_BootSig_32_Offset 66
+#define BS_VolID_32_Offset 67
+#define BS_VolLab_32_Offset 71
+#define BS_FilSysType_32_Offset 82
+
+#define ATTR_READ_ONLY 0x01
+#define ATTR_HIDDEN 0x02
+#define ATTR_SYSTEM 0x04
+#define ATTR_VOLUME_ID 0x08
+#define ATTR_DIRECTORY 0x10
+#define ATTR_ARCHIVE 0x20
+#define ATTR_LONG_NAME (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID)
+#define ATTR_LONG_NAME_MASK (ATTR_READ_ONLY | ATTR_HIDDEN | ATTR_SYSTEM | ATTR_VOLUME_ID | ATTR_ARCHIVE | ATTR_DIRECTORY)
+
+#define DIR_ENTRY_ERASE 0xE5
+#define MAX_LFN_LENGTH 255
+#define MAX_TOTAL_PATH_LENGTH 260
+#define MAX_LFN_SLOTS 20
+
+#define MEMBLOCKSIZE 0x8000
+#define MEMALLOCSIZE 0x40
+#define MAX_OPEN_FHS 0x20
+#define FSI_Free_Count 488
+#define FSI_Nxt_Free 492
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FAT_DATE
+//
+// Description: File date structure
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct {
+ UINT16 Day : 5;
+ UINT16 Month : 4;
+ UINT16 Year : 7; // From 1980
+ } FAT_DATE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FAT_TIME
+//
+// Description: File time structure
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct {
+ UINT16 DoubleSecond : 5;
+ UINT16 Minute : 6;
+ UINT16 Hour : 5;
+ } FAT_TIME;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FAT_DATE_TIME
+//
+// Description: Contains FAT_TIME and FAT_DATE
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct {
+ FAT_TIME Time;
+ FAT_DATE Date;
+ } FAT_DATE_TIME;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FAT_TYPE
+//
+// Description: Enumeration of fat types
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef enum {
+ FAT12 = 1,
+ FAT16,
+ FAT32,
+ FAT_UNKNOWN
+ } FAT_TYPE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: REGIONS
+//
+// Description: Enumeration of volume regions
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef enum {
+ RESERVED_REGION,
+ FAT_REGION,
+ DIRECTORY_REGION,
+ DATA_REGION
+ } REGIONS;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: ACCESS_METHOD
+//
+// Description: Enumeration of access methods (read or write)
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef enum {
+ READ_BLOCK,
+ WRITE_BLOCK
+ } ACCESS_METHOD;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DIR_ENTRY_32
+//
+// Description: Structure of a FAT32 directory entry
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _DIR_ENTRY_32 {
+
+ UINT8 Dir_Name[11];
+ UINT8 Dir_Attr;
+ UINT8 Dir_NTRes;
+ UINT8 Dir_CrtTimeTenth;
+ UINT16 Dir_CrtTime;
+ UINT16 Dir_CrtDate;
+ UINT16 Dir_LstAccDate;
+ UINT16 Dir_FstClusHI;
+ UINT16 Dir_WrtTime;
+ UINT16 Dir_WrtDate;
+ UINT16 Dir_FstClusLO;
+ UINT32 Dir_FileSize;
+
+ } DIR_ENTRY_32;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DIR_ENTRY_LFN
+//
+// Description: Structure of a long file name directory entry
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _DIR_ENTRY_LFN {
+ UINT8 Dir_Order; // Sequence number for slot
+ CHAR16 Dir_Name0_4[5]; // First 5 Unicode characters
+ UINT8 Dir_Attr; // Attributes, always 0x0F
+ UINT8 Dir_Reserved; // Reserved, always 0x00
+ UINT8 Dir_Checksum; // Checksum of 8.3 name
+ CHAR16 Dir_Name5_10[6]; // 6 more Unicode characters
+ UINT16 Dir_FstClus; // First cluster number, must be 0
+ CHAR16 Dir_Name11_12[2]; // Last 2 Unicode characters
+ } DIR_ENTRY_LFN;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BPB_COMMON
+//
+// Description: Structure of the common part of the BIOS parameter block
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _BPB_COMMON {
+ UINT8 BS_JmpBoot[3];
+ UINT8 BS_OEMName[8];
+ UINT16 BPB_BytePerSec;
+ UINT8 BPB_SecPerClus;
+ UINT16 BPB_RsvdSecCnt;
+ UINT8 BPB_NumFATs;
+ UINT16 BPB_RootEntCnt;
+ UINT16 BPB_TotSec16;
+ UINT8 BPB_Media;
+ UINT16 BPB_FATSz16;
+ UINT16 BPB_SecPerTrk;
+ UINT16 BPB_NumHeads;
+ UINT32 BPB_Hiddsec;
+ UINT32 BPB_TotSec32;
+ } BPB_COMMON;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BPB_FAT_12_16
+//
+// Description: Structure of the FAT 12 or 16 unique part of the BPB
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _BPB_FAT_12_16 {
+ UINT8 BS_DrvNum;
+ UINT8 BS_Reserved1;
+ UINT8 BS_BootSig;
+ UINT32 BS_VolID;
+ UINT8 BS_VolLab[11];
+ UINT8 BS_FilSysType[8];
+ } BPB_FAT_12_16;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BPB_FAT_32
+//
+// Description: Structure of the FAT 32 unique part of the BPB
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _BPB_FAT_32 {
+ UINT32 BPB_FATSz32;
+ UINT16 BPB_ExtFlags;
+ UINT16 BPB_FSVer;
+ UINT32 BPB_RootClus;
+ UINT16 BPB_FSInfo;
+ UINT16 BPB_BkBootSec;
+ UINT8 BPB_Rserved[12];
+ UINT8 BS_DrvNum_32;
+ UINT8 BS_Reserved1_32;
+ UINT8 BS_BootSig_32;
+ UINT8 BS_VolID_32[4];
+ UINT8 BS_VolLab_32[11];
+ UINT8 BS_FilSysType_32[8];
+ } BPB_FAT_32;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: VOLUME_BPB
+//
+// Description: Structure of the Volume BIOS Parameter Block. Combines common,
+// FAT 12-16, and FAT 32 parts
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _VOLUME_BPB {
+ UINT8 BS_JmpBoot[3];
+ UINT8 BS_OEMName[8];
+ UINT16 BPB_BytePerSec;
+ UINT8 BPB_SecPerClus;
+ UINT16 BPB_RsvdSecCnt;
+ UINT8 BPB_NumFATs;
+ UINT16 BPB_RootEntCnt;
+ UINT16 BPB_TotSec16;
+ UINT8 BPB_Media;
+ UINT16 BPB_FATSz16;
+ UINT16 BPB_SecPerTrk;
+ UINT16 BPB_NumHeads;
+ UINT32 BPB_Hiddsec;
+ UINT32 BPB_TotSec32;
+ union {
+ BPB_FAT_12_16 BPB_FAT1216;
+ BPB_FAT_32 BPB_FAT32;
+ } BPB_FAT;
+ } VOLUME_BPB;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: VOLUME_INFO
+//
+// Description: Structure containing all Volume Information
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _VOLUME_INFO {
+
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFileSystemProtocol; // This should be the first entry in this structure
+ EFI_HANDLE VolumeHandle;
+ EFI_STATUS VolumeStatus; // Global status that can be used by any open handles
+
+ FAT_TYPE FatType;
+ UINT32 EOCMark;
+ VOLUME_BPB VolumeBPB;
+ BOOLEAN ValidVolumeID;
+ CHAR16 VolumeID[12];
+ CHAR16 *FileSystemName;
+ UINT8 BytesPerSecPowerof2;
+ UINT32 BytesPerCluster;
+ UINT32 FirstRootDirSector;
+ UINT32 RootDirSectorCount; // 0 for FAT32
+ UINT32 FATSz; // Size of 1 FAT
+ UINT32 TotalSectors;
+ UINT32 DataSectors;
+ UINT32 CountOfDataClusters;
+
+// Volume information for EFI_FILE_SYSTEM_INFO
+ UINT64 VolumeSize;
+ UINT32 FreeSpaceinClusters;
+ UINT32 FreeSpaceinSector1;
+ UINT32 BlockSize;
+ BOOLEAN ReadOnly;
+ UINT32 LastFreeCluster;
+ UINT32 FreeClusterBlocks;
+
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ UINT32 MediaID;
+ EFI_UNICODE_COLLATION_PROTOCOL *UnicodeCollationInterface;
+
+ UINT32 AllocatedMemorySize;
+ UINT32 TotalDirEntryList;
+ UINT32 AllowedFatCacheSize;
+ UINT32 AllowedDirCacheSize;
+ UINT32 FATCacheSize;
+ UINT32 DirCacheSize;
+ UINT32 *TempBuffer;
+ UINT32 *CacheBuffer;
+ BOOLEAN TempBufferInUse;
+ struct _FILE_HANDLE * RootFH;
+ DLIST OpenFHs;
+ DLIST OpenFIs;
+ DLIST CacheList;
+ DLIST MemList;
+
+ } VOLUME_INFO;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FILE_HANDLE
+//
+// Description: Structure containing File Handle information
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _FILE_HANDLE {
+
+ VOLUME_INFO *VolumeInterface;
+ EFI_STATUS HandleStatus;
+ BOOLEAN ROOTDIR;
+
+ CHAR16 *FileNameLFN; // Points to the long Filename if not points to 8.3
+ DIR_ENTRY_32 DirectoryEntry; // 8.3 entry
+
+ UINT32 DirCluster; // Cluster at which this entry is present. For Root directory (FAT12/16) it is the sector count.
+ UINT32 DirOffset; // Offset with in the cluster
+ UINT16 InstancesCount; // No of Instances opened so far
+ UINT32 SlotNumber; // Same as in DIR_ENTRY_LIST
+ UINT32 FreeDirEntryCluster; // For FAT12/16 and ROOT directory, not valid.
+ UINT32 FreeDirEntryOffset; //
+
+ BOOLEAN DirEntryChanged;
+ BOOLEAN DirListChanged;
+ struct _FILE_HANDLE *Parent; // Points to the parent directory
+ DLIST DirList; // List if Directory Entries
+ DLINK ViFHLink; // This link is for the DLIST OpenFHs in VOLUME_INFO
+
+ DLIST ChildList;
+ DLINK ChildLink;
+
+ } FILE_HANDLE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FILE_HANDLE_INSTANCE
+//
+// Description: Structure containing File Handle Instance information
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct _FILE_HANDLE_INSTANCE {
+
+ EFI_FILE_PROTOCOL FileHandle; // Should be the first entry in the structure
+ EFI_STATUS HandleInstanceStatus;
+ FILE_HANDLE *pFH;
+ UINT64 OpenMode; // Open Modes
+ UINT64 Position; //
+ UINT32 CurrentCluster; // will point to sector number where the position is pointing currently
+ UINT32 CurrentClusterOffset; // will point to sector number where the position is pointing currently
+ BOOLEAN MEDIA_NOT_VALID; // Will be true if for any reason current instances cannot use the volume Eg: Change in Media
+ DLINK ViFILink; // This link is for the DLIST OpenFIs in the VOLUME_INFO
+
+ } FILE_HANDLE_INSTANCE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DIR_ENTRY_LIST
+//
+// Description: Structure containing directory entry information
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct {
+
+ DIR_ENTRY_32 DirectoryEntry; // 8.3 entry
+ CHAR16 *FileNameLFN; // Points to the long Filename if not points to 8.3
+ UINT32 Cluster; // Not valid for FAT12/16 ROOT
+ UINT32 Offset; // For ROOT Fat12/16, offset is from the beginning.
+ UINT32 SlotNumber; // Used for EFI DIR
+ DLINK DirLink; //
+
+ } DIR_ENTRY_LIST;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CACHE_HEADER
+//
+// Description: Structure containing cache header information
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct {
+
+ UINT64 AbsoluteOffset;
+ UINT64 AbsoluteOffsetEnd;
+ UINT8 *Buffer;
+ BOOLEAN DIRTY_FLAG;
+ REGIONS DataRegion;
+ DLINK CacheLink;
+
+ } CACHE_HEADER;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: MEM_HEADER
+//
+// Description: Structure containing memory header information
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+ typedef struct {
+
+ UINTN AddresMap;
+ UINT32 AddresMapLength;
+ UINTN BufferStart;
+ UINTN BufferEnd;
+ DLINK MemLink;
+
+ } MEM_HEADER;
+
+#pragma pack()
+
+#define FIRSTCLUSTER(D) (((UINT32) D.Dir_FstClusHI << 16) + (UINT32) D.Dir_FstClusLO)
+#define CLUSTERSREQUIRED(N) (N + Vol->BytesPerCluster - 1) / Vol->BytesPerCluster
+#define FAT12_EOC(EntryValue) (EntryValue >= 0x0FF8)
+#define FAT16_EOC(EntryValue) (EntryValue >= 0xFFF8)
+#define FAT32_EOC(EntryValue) (EntryValue >= 0x0FFFFFF8)
+
+
+ EFI_STATUS
+ SimpleFileSystemSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+ EFI_STATUS
+ SimpleFileSystemStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+ EFI_STATUS
+ SimpleFileSystemStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+ EFI_STATUS
+ FileSystemInitUnicodeCollation (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN OUT EFI_UNICODE_COLLATION_PROTOCOL **gFileSystemUnicodeCollationInterface
+ );
+
+ EFI_STATUS
+ DetectInstallVolume(
+ IN EFI_DISK_IO_PROTOCOL *DiskIo,
+ IN EFI_BLOCK_IO_PROTOCOL *BlkIo,
+ IN EFI_HANDLE Handle
+ );
+
+ EFI_STATUS
+ DetectVolume (
+ VOLUME_INFO *VolumeInterface,
+ BOOLEAN StatusCheck
+ );
+
+ EFI_STATUS
+ OpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **Root
+ );
+
+ EFI_STATUS
+ OpenRoot(
+ IN VOLUME_INFO *VolumeInfo,
+ IN OUT FILE_HANDLE **Root
+ );
+
+ EFI_STATUS
+ CreateFileHandleInstance (
+ IN FILE_HANDLE *Root,
+ IN OUT FILE_HANDLE_INSTANCE **FileInstance,
+ IN UINT64 OpenMode
+ );
+
+ void
+ InitEFIFileInterface (
+ EFI_FILE_PROTOCOL *EFIFileInterface
+ );
+
+ EFI_STATUS
+ OpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **Root
+ );
+
+ EFI_STATUS
+ OpenFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+ EFI_STATUS
+ CloseFileHandle (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+ EFI_STATUS
+ DeleteFileHandle (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+ EFI_STATUS
+ ReadFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+ EFI_STATUS
+ WriteFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+ );
+
+ EFI_STATUS
+ GetPositionFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 *Position
+ );
+
+ EFI_STATUS
+ SetPositionFileHandleThis (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT UINT64 Position
+ );
+
+
+ EFI_STATUS
+ SetPositionFileHandle (
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN UINT64 Position
+ );
+
+ EFI_STATUS
+ GetInfoFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+
+ EFI_STATUS
+ SetInfoFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ );
+
+ EFI_STATUS
+ FlushFileHandle (
+ IN EFI_FILE_PROTOCOL *This
+ );
+
+ EFI_STATUS
+ ProcessOpenFileHandle(
+ IN FILE_HANDLE_INSTANCE *ParentFi,
+ IN CHAR16 **FileName,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+ );
+
+ EFI_STATUS
+ CreateDirectoryEntry (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *NextCompName,
+ OUT FILE_HANDLE **fh1,
+ IN UINT64 Attributes
+ );
+
+ EFI_STATUS
+ CreateDirEntryInDisk (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *NextCompName,
+ IN UINT64 Attributes,
+ OUT UINT32 *FreeDirCluster,
+ OUT UINT32 *FreeDirClusterOffset,
+ DIR_ENTRY_32 *Entry
+ );
+
+ BOOLEAN
+ FindMatchingFH (
+ IN VOLUME_INFO *Vi,
+ IN CHAR16 *NextCompName,
+ IN FILE_HANDLE *fh,
+ OUT FILE_HANDLE **fh1
+ );
+
+ EFI_STATUS
+ ReadAllDirectoryEntries (
+ IN FILE_HANDLE *fh
+ );
+
+ EFI_STATUS
+ CreateFHFromDirEntryList(
+ IN DIR_ENTRY_LIST *Del,
+ IN FILE_HANDLE *fh,
+ OUT FILE_HANDLE **fh1
+ );
+
+ BOOLEAN
+ FindMatchingDirEntry (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *NextCompName,
+ OUT DIR_ENTRY_LIST **Del
+ );
+
+ BOOLEAN
+ FindMatchingSFNDirEntry (
+ IN FILE_HANDLE *fh,
+ IN CHAR8 *ShortFileName,
+ OUT DIR_ENTRY_LIST **Del
+ );
+
+ EFI_STATUS
+ AddToDirList (
+ FILE_HANDLE *fh,
+ DIR_ENTRY_32 DirectoryEntry,
+ CHAR16 *lfn,
+ UINT32 Cluster,
+ UINT32 Offset,
+ UINT32 SlotNumber
+ );
+
+ EFI_STATUS
+ GetDirListAtPosition(
+ FILE_HANDLE *Pfh,
+ UINT64 Position,
+ DIR_ENTRY_LIST **Del
+ );
+
+ EFI_STATUS
+ GetNextCompName (
+ IN OUT CHAR16 **FileName,
+ IN CHAR16 *NextCompName
+ );
+
+ void
+ RemoveDirEntries (
+ IN FILE_HANDLE *Rfh,
+ IN FILE_HANDLE *fh
+ );
+
+ EFI_STATUS
+ RemoveFH (
+ FILE_HANDLE *fh
+ );
+
+ EFI_STATUS
+ FreeUpDirEntries (
+ VOLUME_INFO *vi,
+ FILE_HANDLE *pfh
+ );
+
+ EFI_STATUS
+ FreeUpFHEntries (
+ VOLUME_INFO *vi,
+ FILE_HANDLE *pfh
+ );
+
+ EFI_STATUS
+ RemoveAllDirList(
+ FILE_HANDLE *lfh
+ );
+
+
+ EFI_STATUS
+ RemoveDirList (
+ FILE_HANDLE *fh,
+ DIR_ENTRY_LIST *Del
+ );
+
+ BOOLEAN
+ FatLfnIsValid (
+ CHAR16 *Name
+ );
+
+ EFI_STATUS
+ fsAllocateMemory (
+ VOLUME_INFO *vi,
+ UINT32 Size,
+ VOID **Buffer,
+ BOOLEAN CLEAR
+ );
+
+ EFI_STATUS
+ fsDeAllocateMemory (
+ VOLUME_INFO *vi,
+ void *Buffer
+ );
+
+ EFI_STATUS
+ GetVolumeLabel (
+ VOLUME_INFO *vi,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+ EFI_STATUS
+ SetVolumeLabel (
+ VOLUME_INFO *vi,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+ EFI_STATUS
+ GetfileInfo (
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+ EFI_STATUS
+ SetfileInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+ );
+
+ EFI_STATUS
+ GetFileInfoFromFH (
+ FILE_HANDLE *Pfh,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+ VOID
+ FatToEfiTime (
+ EFI_TIME *EfiTime,
+ UINT16 Date,
+ UINT16 Time
+ );
+
+ VOID
+ EfiToFatTime (
+ EFI_TIME EfiTime,
+ UINT16 *Date,
+ UINT16 *Time
+ );
+
+ EFI_STATUS
+ GetSystemInfo (
+ IN VOLUME_INFO *vi,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FILE_SYSTEM_INFO *Buffer
+ );
+
+ EFI_STATUS
+ SetSystemInfo (
+ IN VOLUME_INFO *vi,
+ IN UINTN BufferSize,
+ OUT EFI_FILE_SYSTEM_INFO *Buffer
+ );
+
+ UINT32
+ ReturnFreeSpace (
+ IN VOLUME_INFO *vi
+ );
+
+ EFI_STATUS
+ GetVolumeLabel (
+ IN VOLUME_INFO *vi,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+ );
+
+ UINT8
+ LfnChecksum(
+ UINT8 *D
+ );
+
+ UINT8
+ FetchLongName (
+ FILE_HANDLE *fh,
+ DIR_ENTRY_32 *Buffer,
+ UINT32 BufferPos,
+ UINT16 *Name,
+ UINT32 ClusterNumber,
+ UINT32 ClusterSize
+ );
+
+ BOOLEAN
+ FindShortName (
+ UINT8 *Buffer,
+ UINT32 *Offset,
+ UINT32 BufferSize
+ );
+
+ EFI_STATUS
+ FsReadMedia (
+ VOLUME_INFO *vi,
+ UINT8 *Buffer,
+ UINT64 Sector,
+ UINT32 Offset,
+ UINT32 ByteCount,
+ REGIONS DataRegion
+ );
+
+ EFI_STATUS
+ FsWriteMedia (
+ VOLUME_INFO *vi,
+ UINT8 *Buffer,
+ UINT64 SectorCount,
+ UINT32 Offset,
+ UINT32 ByteCount,
+ REGIONS DataRegion
+ );
+
+ void
+ HandleDiskIoError (
+ VOLUME_INFO *vi,
+ EFI_STATUS Status
+
+ );
+
+ ExtractShortFileName (
+ VOLUME_INFO *Vi,
+ CHAR16 *lfn,
+ UINT8 *Buffer
+ );
+
+ EFI_STATUS
+ CheckCached (
+ VOLUME_INFO *vi,
+ UINT64 AbsoluteOffset,
+ UINT32 ByteCount,
+ UINT8 **cBuffer,
+ UINT32 *cBufferLength,
+ CACHE_HEADER **ch,
+ REGIONS DataRegion
+ );
+
+ BOOLEAN
+ IsCacheHit (
+ VOLUME_INFO *vi,
+ REGIONS DataRegion,
+ UINT64 AbsoluteOffset,
+ UINT32 ByteCount,
+ UINT8 **cBuffer,
+ UINT32 *cBufferLength,
+ CACHE_HEADER **ch1
+ );
+
+ void
+ CreateSpaceforCache (
+ VOLUME_INFO *vi,
+ UINT32 ByteCount,
+ REGIONS DataRegion,
+ CACHE_HEADER **ch1
+ );
+
+ EFI_STATUS
+ ReadClusterOfDirectoryEntries (
+ IN FILE_HANDLE *fh,
+ IN UINT32 ClusterNumber,
+ OUT UINT32 *ClusterRead,
+ UINT8 *Buffer,
+ UINT32 *BufferSize
+ );
+
+ EFI_STATUS
+ ReadFatClusterNumber (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT8 FatNumber,
+ OUT UINT32 *Value
+ );
+
+ EFI_STATUS
+ FatClusterNumberLocation (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT8 FatNumber,
+ OUT UINT32 *Sector,
+ OUT UINT32 *SectorOffset
+ );
+
+ EFI_STATUS
+ WriteFatClusterNumber (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT8 FatNumber,
+ IN UINT32 Value
+ );
+
+ EFI_STATUS
+ UnlinkFat (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ OUT UINT32 *ClusterCount
+ );
+
+ EFI_STATUS
+ FindFreeClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 From,
+ IN UINT32 To,
+ OUT UINT32 *StartCluster,
+ IN OUT UINT32 *FreeClusters,
+ OUT UINT32 *TotalFree
+ );
+
+ EFI_STATUS
+ FindNextFreeCluster (
+ IN VOLUME_INFO *Vol,
+ OUT UINT32 *Cluster
+ );
+
+ EFI_STATUS
+ GetFreeClusterCount (
+ IN VOLUME_INFO *Vol,
+ OUT UINT32 *FreeClustersCount,
+ OUT UINT32 *FreeClusterBlock,
+ OUT UINT32 *FreeBlockCount
+ );
+
+ UINT32
+ ClusterToSector (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster
+ );
+
+ UINT32
+ SectorToCluster (
+ IN VOLUME_INFO *Vol,
+ IN OUT UINT32 Sector
+ );
+
+ EFI_STATUS
+ GetClusterCount (
+ IN VOLUME_INFO *Vol,
+ IN OUT UINT32 Cluster
+ );
+
+ int
+ Wcscmpcaseinsensitive(
+ CHAR16 *string1,
+ CHAR16 *string2
+ );
+
+ EFI_STATUS
+ ReadFromFile (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN OUT VOID *Buffer,
+ IN OUT UINT32 *Size,
+ IN REGIONS DataRegion
+ );
+
+ EFI_STATUS
+ WriteToFile (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN OUT VOID *Buffer,
+ IN OUT UINT32 *Size,
+ IN REGIONS DataRegion
+ );
+
+
+ EFI_STATUS
+ AllocateFirstCluster (
+ IN FILE_HANDLE_INSTANCE *File,
+ OUT UINT32 *Cluster
+ );
+
+ EFI_STATUS
+ AllocateAndLinkClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 BeginCluster,
+ IN UINT32 Size,
+ OUT UINT32 *FirstCluster,
+ OUT UINT32 *ClusterCount
+ );
+
+ static int AllocateAndLinkNewCluster (
+ VOLUME_INFO *Vol,
+ IN UINT32 PrevCluster,
+ OUT UINT32 *Cluster
+ );
+
+
+ EFI_STATUS
+ ExtendFile (
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN UINT32 Length
+ );
+
+ EFI_STATUS
+ GetContiguousClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Size,
+ IN OUT UINT32 Cluster,
+ OUT UINT32 *LastCluster,
+ OUT UINT32 *Count
+ );
+
+ VOID
+ GetAbsSectorInfo (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT32 ClusterOffset,
+ OUT UINT32 *Sector,
+ OUT UINT32 *SectorOffset
+ );
+
+ EFI_STATUS
+ GetClusterPosition (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN UINT64 Position,
+ OUT UINT32 *Cluster,
+ OUT UINT32 *ClusterOffset
+ );
+
+ UINT32
+ GetEocValue (
+ IN VOLUME_INFO *Vol
+ );
+
+ EFI_STATUS
+ ValidateCurrentStatus (
+ FILE_HANDLE_INSTANCE *fhi
+ );
+
+ VOID
+ GetSectorAddressDir (
+ FILE_HANDLE *fh,
+ UINT32 Cluster,
+ UINT32 ClusterOffset,
+ UINT32 *Sector,
+ UINT32 *SectorOffset
+ );
+
+ EFI_STATUS
+ UpdateAccAndWriteTime (
+ IN OUT DIR_ENTRY_LIST *del
+ );
+
+ EFI_STATUS
+ UpdateAccDate(
+ IN OUT DIR_ENTRY_LIST *del
+ );
+
+ BOOLEAN
+ UpdateAccDateRequired (
+ IN OUT DIR_ENTRY_LIST *del
+ );
+
+ EFI_STATUS
+ GetSpaceforDirEntry(
+ IN FILE_HANDLE *fh,
+ IN UINT32 FreeBytesRequired,
+ OUT UINT32 *FreeDirCluster,
+ OUT UINT32 *FreeDirClusterOffset,
+ BOOLEAN *LastDirEntry
+ );
+
+ EFI_STATUS
+ CheckforValidDirSpace (
+ IN VOLUME_INFO *Vi,
+ IN BOOLEAN ROOTDIR,
+ IN UINT32 Cluster,
+ IN UINT32 Offset,
+ IN UINT32 FreeBytesRequired,
+ IN UINT32 *FreeDirCluster,
+ IN UINT32 *FreeDirClusterOffset
+ );
+
+ EFI_STATUS
+ LocateFreeDirEntry(
+ IN FILE_HANDLE *fh,
+ IN UINT32 FreeBytesRequired,
+ OUT UINT32 *FreeDirCluster,
+ OUT UINT32 *FreeDirClusterOffset,
+ BOOLEAN *LastDirEntry
+ );
+
+ EFI_STATUS
+ GenShortFilename (
+ IN VOLUME_INFO *Vol,
+ IN CHAR16 *InPath,
+ OUT CHAR8 *ShortName
+ );
+
+ EFI_STATUS
+ UpdateDirListFromFHDir (
+ FILE_HANDLE *fh
+ );
+
+ EFI_STATUS
+ LocateDel (
+ DLINK *dlink,
+ UINT32 Cluster,
+ UINT32 ClusterOffset,
+ DIR_ENTRY_LIST **Del,
+ UINT32 *Position
+ );
+
+ EFI_STATUS
+ GenUniqueShortFname (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *LongName,
+ OUT CHAR8 *ShortName,
+ OUT BOOLEAN *LfnNeeded
+ );
+
+ EFI_STATUS
+ SplitLFN (
+ IN CHAR16 *LongName,
+ IN DIR_ENTRY_32 *ShortEntry,
+ OUT DIR_ENTRY_LFN *Slot,
+ OUT UINT32 *NumSlots
+ );
+
+ EFI_STATUS
+ ZeroOutdisk (
+ IN VOLUME_INFO *Vi,
+ IN UINT32 Cluster,
+ IN UINT32 ClusterOffset,
+ IN UINT32 Size
+ );
+
+ EFI_STATUS
+ ShrinkClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 StartCluster,
+ IN UINT32 ClusterCount
+ );
+
+ UINT32
+ GetClustersRequired (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 N
+ );
+
+ EFI_STATUS
+ UpdateFreeSpace (
+ IN VOLUME_INFO *vi,
+ IN UINT32 Count,
+ IN BOOLEAN Add
+ );
+
+ EFI_STATUS
+ FreeUpResources (
+ VOLUME_INFO *vi,
+ EFI_STATUS Status
+ );
+
+ EFI_STATUS
+ MarkVolumeDirty (
+ IN VOLUME_INFO *vi
+ );
+
+ EFI_STATUS
+ UnloadSimpleFileSystemDriver (
+ IN EFI_HANDLE ImageHandle
+ );
+
+ void
+ Zeromemory (
+ void *Buffer,
+ UINT32 Size
+ );
+
+ EFI_STATUS
+ CheckFileWrite (
+ FILE_HANDLE_INSTANCE *fhi,
+ BOOLEAN IgnoreOpenMode
+ );
+
+ VOID EfiInitializeDriverLib(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+ EFI_STATUS
+ InternalMemAllocate (
+ VOLUME_INFO *vi,
+ UINT32 Size,
+ VOID **Buffer,
+ BOOLEAN CLEAR
+ );
+
+ EFI_STATUS
+ AddBlocktoInternalMemManager (
+ VOLUME_INFO *vi
+ );
+
+ EFI_STATUS
+ GetMemory (
+ MEM_HEADER *Mem,
+ UINT32 Blocks,
+ VOID **Buffer,
+ BOOLEAN CLEAR
+ );
+
+ EFI_STATUS
+ FreeMemory (
+ VOLUME_INFO *vi,
+ VOID *Buffer
+ );
+
+
+ VOID
+ GetTempBuffer (
+ VOLUME_INFO *vi,
+ VOID **Buffer
+ );
+
+ VOID
+ ReleaseTempBuffer (
+ VOLUME_INFO *vi
+ );
+
+ void
+ PrintOpenfhiandfh (
+ VOLUME_INFO *vi
+ );
+
+ VOID Labcpy(
+ CHAR16 *string1,
+ CHAR16 * string2
+ );
+
+ UINTN Lablen(
+ CHAR16 *string
+ );
+
+ EFI_TPL
+ FindNextTpl (
+ EFI_TPL TplLevel
+ );
+
+ VOID EfiDebugPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ );
+
+ /****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/FileSystem.sdl b/Core/EM/FileSystem/FileSystem.sdl
new file mode 100644
index 0000000..43f4467
--- /dev/null
+++ b/Core/EM/FileSystem/FileSystem.sdl
@@ -0,0 +1,49 @@
+TOKEN
+ Name = "FILESYSTEM_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FileSystem Support"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "DIRECTORTY_ENTRIES_CACHED"
+ Value = "100"
+ Help = "Indicate the number of Directory entries \that can be cached."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FAT_CACHE_SIZE"
+ Value = "4000h"
+ Help = "Specifiy the FAT CACHE size for each volume."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DIR_CACHE_SIZE"
+ Value = "4000h"
+ Help = "Specify the DIR Cache size for each volume."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "FILESYSTEM_DIR"
+End
+
+MODULE
+ Help = "Includes FileSystem.mak to Project"
+ File = "FileSystem.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FileSystem.ffs"
+ Parent = "$(CORE_DIR)\FileSystem$(ARCH).ffs"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/FileSystem/FileSystemComponentName.c b/Core/EM/FileSystem/FileSystemComponentName.c
new file mode 100644
index 0000000..f2ac049
--- /dev/null
+++ b/Core/EM/FileSystem/FileSystemComponentName.c
@@ -0,0 +1,271 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/FileSystemComponentName.c 7 8/28/09 11:59a Felixp $
+//
+// $ $
+//
+// $ $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/FileSystemComponentName.c $
+//
+// 7 8/28/09 11:59a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 6 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 5 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 2 7/16/05 2:01p Felixp
+// bug fixes in Component Name implementation
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FileSystemComponentName.c
+//
+// Description: Simple File System controller name functions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "FileSystem.h"
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+#endif
+//----------------------------------------------------------------------
+
+EFI_STATUS
+SimpleFileSystemCtlDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+);
+
+EFI_STATUS
+SimpleFileSystemCtlGetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+);
+
+//----------------------------------------------------------------------
+
+CHAR16 *gFileSystemDriverName = L"AMI File System Driver";
+CHAR16 *gFileSystemControllerName = L"FAT File System";
+extern EFI_GUID guidFS;
+extern EFI_DRIVER_BINDING_PROTOCOL gSimpleFileSystemDriverBinding;
+//==================================================================================
+EFI_COMPONENT_NAME_PROTOCOL gSimpleFileSystemDriverName = {
+ SimpleFileSystemCtlDriverName,
+ SimpleFileSystemCtlGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SimpleFileSystemCtlDriverName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// Parameters:
+// EFI_COMPONENT_NAME_PROTOCOL
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// CHAR8
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// CHAR16
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// Return value:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SimpleFileSystemCtlDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ if (!Language || !DriverName) return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+
+ *DriverName = gFileSystemDriverName;
+ return EFI_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SimpleFileSystemCtlGetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Parameters:
+// EFI_COMPONENT_NAME_PROTOCOL
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// EFI_HANDLE
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// EFI_HANDLE
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// CHAR8
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// CHAR16
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// Return value:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SimpleFileSystemCtlGetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+
+ EFI_STATUS Status;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *FileSystem;
+ VOLUME_INFO *vi;
+
+ if (!Language || !ControllerName) return EFI_INVALID_PARAMETER;
+
+ if (ChildHandle != NULL) return EFI_UNSUPPORTED;
+
+ Status = pBS->OpenProtocol ( Controller,
+ &guidFS,
+ &FileSystem,
+ gSimpleFileSystemDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ vi = (VOLUME_INFO *)FileSystem;
+
+ // Compare the Language
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+
+ if (vi->FileSystemName) *ControllerName = vi->FileSystemName;
+ else *ControllerName = gFileSystemControllerName;
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/Info.c b/Core/EM/FileSystem/Info.c
new file mode 100644
index 0000000..9435c34
--- /dev/null
+++ b/Core/EM/FileSystem/Info.c
@@ -0,0 +1,1313 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/Info.c 15 5/05/11 3:44p Pats $
+//
+// $Revision: 15 $
+//
+// $Date: 5/05/11 3:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/Info.c $
+//
+// 15 5/05/11 3:44p Pats
+// [TAG] - EIP 58999
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - Cannot launch Shell from USB Filesystem device in Debug
+// mode with latest Filesystem driver.
+// [RootCause] - Functions using DISKIO were raising TPL to a fixed level.
+// [Solution] - Modified above functions to check for the higher of the
+// fixed level or current level.
+// [Files] - Info.c, MediaAccess.c, Open.c, FileSystem.h
+//
+// 14 2/25/11 2:44p Pats
+// [TAG] - EIP 54399
+// [Category]- BUG FIX
+// [Severity] - Urgent
+// [Symptom] - SCT 2.3 fails Bootable Image Support Test\Simple File
+// System Protocol
+// [RootCause] - Does not check for matching name when attempting to
+// change file name.
+// [Solution] - Modified function SetfileInfo() to check for matching
+// name.
+// [Files] - info.c
+//
+// 13 1/19/11 4:56p Pats
+// [TAG] - EIP 52430
+// [Category]- BUG FIX
+// [Severity] - Normal
+// [Symptom] - When a directory is moved, the long name of the old
+// directory is not deleted.
+// [RootCause] - Only the short name component was being deleted in
+// SetFileInfo().
+// [Solution] - Modified function SetfileInfo() to delete the long name
+// component also.
+// [Files] - info.c
+//
+// 12 1/14/11 2:59p Pats
+// [TAG] - EIP 51754
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - The shell "mv" command makes directories dissapear.
+// [RootCause] - Directorys were not removed from cache when deleted..
+// [Solution] - Modified function SetfileInfo() to remove directories from
+// cache when deleted.
+// [Files] - info.c
+//
+// 11 1/06/11 5:54p Oleksiyy
+// [TAG] EIP28607
+// [Category] Improvement
+// [Description] System was hanging for some time if Floppy Media
+// removed while writing in meda in progress.
+// EFI_TPL_CALLBACK priority level rised during media related calls.
+//
+// [Files] DiskIo.c, Info.c, MediaAccess.c, Open.c, Partition.c
+//
+// 10 1/22/10 4:39p Yul
+// Refer to EIP 32983.
+//
+// 9 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 8 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 7 8/16/06 12:03p Markw
+// Fixed UINTN* and UINT32* 64-bit issues.
+//
+// 10 11/03/05 2:16p Srinin
+// Fixed VC7.1 warning msg.
+//
+// 9 8/08/05 3:55p Markw
+// In SetVolumeLabel, after CreateDirectoryEntry, check if valid file
+// handle before removing.
+//
+// 6 6/22/05 4:29p Pats
+// Added function Labcpy() to replace Wcscpy() so that volume labels are
+// copied correctly. Dumps period added by ExtractShortFileName.
+//
+// 4 6/21/05 9:51a Pats
+// Fixed GetVolumeLabel so that it properly handles the case when there is
+// no label on the volume, to pass SCT tests.
+//
+// 3 6/16/05 4:17p Pats
+// Modified to mark both long and short name entries deleted when a file
+// is deleted, instead of just short name entries.
+//
+// 2 4/27/05 5:30p Srinin
+// 'MV' command supported (Move file/Directories in a volume)
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Info.c
+//
+// Description: Simple File System driver information handling functions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+
+#include "FileSystem.h"
+#define EFI_TPL_CALLBACK TPL_CALLBACK
+//----------------------------------------------------------------------
+
+extern EFI_GUID gEfiFileSystemVolumeLabelGuid;
+extern EFI_GUID gEfiFileInfoGuid;
+extern EFI_GUID gEfiFileSystemInfoGuid;
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateAccAndWriteTime
+//
+// Description: Updates access and write times in a directory entry
+//
+// Parameters: DIR_ENTRY_LIST *del - pointer to the directory entry list
+// structure
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateAccAndWriteTime (
+ DIR_ENTRY_LIST *del
+)
+{
+
+ EFI_TIME EfiTime;
+ EFI_TIME_CAPABILITIES Capabilities;
+ UINT16 DummyTime;
+
+ pRS->GetTime(&EfiTime, &Capabilities);
+ EfiToFatTime (EfiTime, &del->DirectoryEntry.Dir_LstAccDate, &DummyTime);
+ EfiToFatTime (EfiTime, &del->DirectoryEntry.Dir_WrtDate, &del->DirectoryEntry.Dir_WrtTime);
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateAccDate
+//
+// Description: Updates the access date in a directory entry
+//
+// Parameters: DIR_ENTRY_LIST *del - pointer to the directory entry list
+// structure
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateAccDate(
+ DIR_ENTRY_LIST *del
+)
+{
+
+ EFI_TIME EfiTime;
+ EFI_TIME_CAPABILITIES Capabilities;
+ UINT16 DummyTime;
+
+ pRS->GetTime(&EfiTime, &Capabilities);
+ EfiToFatTime (EfiTime, &del->DirectoryEntry.Dir_LstAccDate, &DummyTime);
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateAccDateRequired
+//
+// Description: Indicates when update of the access date of a file is
+// required
+//
+// Parameters: DIR_ENTRY_LIST *del - pointer to the directory entry list
+// structure
+//
+// Return value: BOOLEAN - True if update required
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+UpdateAccDateRequired (
+ DIR_ENTRY_LIST *del
+)
+{
+
+ EFI_TIME EfiTime;
+ EFI_TIME_CAPABILITIES Capabilities;
+ UINT16 DummyTime;
+ UINT16 DummyDate;
+
+ pRS->GetTime(&EfiTime, &Capabilities);
+ EfiToFatTime (EfiTime, &DummyDate, &DummyTime);
+
+ if (DummyDate == del->DirectoryEntry.Dir_LstAccDate) return FALSE;
+
+ del->DirectoryEntry.Dir_LstAccDate = DummyDate;
+ return TRUE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetInfoFileHandle
+//
+// Description: Returns file info, system info, or the label of a volume
+// depending on information type specified
+//
+// Parameters: EFI_FILE_PROTOCOL *This - Pointer to this instance of
+// file protocol
+// EFI_GUID *InformationType - Pointer to information type
+// requested
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Pointer to buffer for returned info
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetInfoFileHandle(
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+ FILE_HANDLE *Pfh;
+ VOLUME_INFO *vi;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+
+ Status = ValidateCurrentStatus (fhi);
+
+ if (EFI_ERROR(Status)) return Status;
+ Pfh = fhi->pFH;
+ vi = Pfh->VolumeInterface;
+// Compare the GUID
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+ if (!guidcmp(InformationType, &gEfiFileInfoGuid))
+ Status = GetfileInfo (fhi, BufferSize, Buffer);
+
+ else {
+ if (!guidcmp(InformationType, &gEfiFileSystemInfoGuid))
+ Status = GetSystemInfo (vi, BufferSize, (EFI_FILE_SYSTEM_INFO *)Buffer);
+
+ else {
+ if (!guidcmp(InformationType, &gEfiFileSystemVolumeLabelGuid))
+ Status = GetVolumeLabel (vi, BufferSize, Buffer);
+
+ else{
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetfileInfo
+//
+// Description: Returns information on a file
+//
+// Parameters: FILE_HANDLE_INSTANCE *fh1 - Pointer to file handle
+// instance
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer for returned data
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetfileInfo (
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ FILE_HANDLE *Pfh = fhi->pFH;
+ return (GetFileInfoFromFH (Pfh, BufferSize, Buffer));
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetSystemInfo
+//
+// Description: Returns file system info on a volume
+//
+// Parameters: VOLUME_INFO *vi - Pointer to volume info structure
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer for returned data
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetSystemInfo (
+ IN VOLUME_INFO *vi,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_FILE_SYSTEM_INFO *Buffer
+)
+{
+
+ UINTN Length = 0;
+ GetVolumeLabel (vi, &Length, Buffer);
+
+ if (*BufferSize < Length + EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel)) {
+
+#ifdef Debug_GetSystemInfo
+ EfiDebugPrint(TRACE_ALWAYS,"GetSystemInfo: I/P BufferSize %x O/P BufferSize %x\n", *BufferSize, Length + EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel));
+#endif
+
+ *BufferSize = Length + EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel);
+ return EFI_BUFFER_TOO_SMALL;
+
+ }
+
+ Buffer->Size = Length + EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel);
+ Buffer->ReadOnly = vi->ReadOnly;
+ Buffer->VolumeSize = vi->VolumeSize;
+ Buffer->FreeSpace = Mul64(ReturnFreeSpace(vi), vi->BytesPerCluster);
+ Buffer->BlockSize = vi->BytesPerCluster;
+ GetVolumeLabel (vi, BufferSize, ((UINT8 *)Buffer) + EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel));
+ *BufferSize += EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel);
+
+#ifdef Debug_GetSystemInfo
+ EfiDebugPrint(TRACE_ALWAYS,"GetSystemInfo: VolumeLabel %s, BufferSize %x\n", Buffer->VolumeLabel, *BufferSize);
+ EfiDebugPrint(TRACE_ALWAYS,"Size %lx, ReadOnly %x, VolumeSize %lx, FreeSpace %lx, BlockSize %x\n", Buffer->Size, Buffer->ReadOnly, Buffer->VolumeSize, Buffer->FreeSpace, Buffer->BlockSize);
+#endif
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetVolumeLabel
+//
+// Description: Returns label of a volume
+//
+// Parameters: VOLUME_INFO *vi - Pointer to volume info structure
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer for returned data
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetVolumeLabel (
+ IN VOLUME_INFO *vi,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ EFI_STATUS Status;
+ EFI_STATUS LocalStatus;
+ FILE_HANDLE *fh = vi->RootFH;
+ UINTN Length;
+ DLINK *dlink;
+ DIR_ENTRY_LIST *del=NULL;
+
+ if (vi->ValidVolumeID) {
+ Length = Wcslen (vi->VolumeID) << 1;
+
+#ifdef Debug_GetVolumeLabel
+ EfiDebugPrint(-1,"GetVolumeLabel: VolLabel %s I/P BufferSize %x O/P BufferSize %x\n", vi->VolumeID, *BufferSize, Length + 2);
+#endif
+
+ if (*BufferSize < (Length + 2)) {
+ *BufferSize = Length + 2;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Wcscpy (Buffer, vi->VolumeID);
+ *BufferSize = Length + 2;
+ return EFI_SUCCESS;
+
+ } else {
+ if (*BufferSize < 2) {
+ Status = EFI_BUFFER_TOO_SMALL; // To pass SCT test.
+
+ } else Status = EFI_NOT_FOUND;
+ }
+
+
+// See if the Linked List is Valid
+ if (!fh->DirList.pHead) ReadAllDirectoryEntries (fh);
+
+ dlink = fh->DirList.pHead;
+ LocalStatus = EFI_UNSUPPORTED;
+
+ if (!dlink) return EFI_UNSUPPORTED;
+
+ for ( ; dlink; ) {
+ del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+
+ if ((del->DirectoryEntry.Dir_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) == ATTR_VOLUME_ID) {
+ LocalStatus = EFI_SUCCESS;
+ break;
+ }
+
+ dlink = dlink->pNext;
+ }
+
+ if (LocalStatus == EFI_SUCCESS) {
+ Length = Lablen (del->FileNameLFN) << 1;
+
+ if (Length <= 22) {
+ Zeromemory (vi->VolumeID, sizeof (vi->VolumeID));
+ Labcpy (vi->VolumeID, del->FileNameLFN); // Don't put "." in name
+ vi->ValidVolumeID = TRUE;
+ }
+
+ if (*BufferSize < (Length + 2)) {
+
+#ifdef Debug_GetVolumeLabel
+ EfiDebugPrint(-1,"GetVolumeLabel: VolLabel %s I/P BufferSize %x O/P BufferSize %x\n", vi->VolumeID, *BufferSize, Length + 2);
+#endif
+
+ *BufferSize = Length + 2;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ Status = EFI_SUCCESS;
+ Labcpy (Buffer, del->FileNameLFN);
+ *BufferSize = Length >> 1;
+
+#ifdef Debug_GetVolumeLabel
+ EfiDebugPrint(-1,"GetVolumeLabel: VolLabel %s I/P BufferSize %x O/P BufferSize %x\n", Buffer, *BufferSize, Length + 2);
+#endif
+
+ }
+
+// If there is no volume label, we must return a null label of size 2.
+ else if (Status == EFI_NOT_FOUND) {
+ if (*BufferSize >= 2) Zeromemory (Buffer, 2);
+
+ *BufferSize = 2;
+ Status = EFI_SUCCESS;
+
+ } else if (Status == EFI_BUFFER_TOO_SMALL) *BufferSize = 2;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetfileInfo
+//
+// Description: Sets the information on a file (updates dir entry)
+//
+// Parameters: FILE_HANDLE_INSTANCE *fh1 - Pointer to file handle
+// instance
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer containing new data
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetfileInfo (
+ IN EFI_FILE_PROTOCOL *This,
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN OUT UINTN BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ EFI_STATUS Status;
+ EFI_FILE_PROTOCOL *NewHandle;
+ FILE_HANDLE *fh = fhi->pFH;
+ FILE_HANDLE *ParentFh = fh->Parent;
+ DIR_ENTRY_LIST *Del = NULL;
+ FILE_HANDLE_INSTANCE *Newfhi;
+ VOLUME_INFO *vi = fh->VolumeInterface;
+ EFI_FILE_INFO *buffer = Buffer;
+ UINT16 Dummy;
+ UINT32 Length;
+ UINT32 OldClusterCount, NewClusterCount;
+ UINT8 DirErase = DIR_ENTRY_ERASE;
+ CHAR16 *NewFileName;
+ BOOLEAN IsSizeChange = fh->DirectoryEntry.Dir_FileSize != (UINT32)(buffer->FileSize) ? TRUE : FALSE;
+ BOOLEAN IsNameChange = (BOOLEAN)Wcscmpcaseinsensitive(buffer->FileName, fh->FileNameLFN);
+
+#ifdef Debug_SetFileInfo
+ EfiDebugPrint(-1,"SetFileInfo: %S I/P BufferSize %x\n", fh->FileNameLFN, BufferSize);
+ EfiDebugPrint(-1,"FileSize %lx, Physical %lx Attribute %lx\n", buffer->FileSize, buffer->PhysicalSize, buffer->Attribute);
+#endif
+
+ Length = EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName);
+
+ if (BufferSize < Length) return EFI_BAD_BUFFER_SIZE;
+
+// Is it a Directory Entry, attr can't be set
+// For a file, it cannot be set as Directory
+ if ((fh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY) ^
+ ((UINT8)(buffer->Attribute) & ATTR_DIRECTORY)) return EFI_ACCESS_DENIED;
+
+// For Root Directory no entries can be modified
+ if (fh->ROOTDIR) return EFI_ACCESS_DENIED;
+
+ if (buffer->Attribute & ~EFI_FILE_VALID_ATTR) return EFI_INVALID_PARAMETER;
+
+ if (fh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY && IsSizeChange) return EFI_ACCESS_DENIED;
+
+ if (vi->ReadOnly) return EFI_WRITE_PROTECTED;
+
+ if ((fh->DirectoryEntry.Dir_Attr & ATTR_READ_ONLY ||
+ fhi->OpenMode == EFI_FILE_MODE_READ) && (IsSizeChange || IsNameChange))
+ return EFI_ACCESS_DENIED;
+
+// Update Attribute
+#ifdef Debug_SetFileInfo
+ EfiDebugPrint(-1, "Updated Attribute %x\n", fh->DirectoryEntry.Dir_Attr);
+#endif
+
+ fh->DirectoryEntry.Dir_Attr = (UINT8) buffer->Attribute;
+
+// Rename File/Directory?
+ if (IsNameChange) {
+
+#ifdef Debug_SetFileInfo
+ EfiDebugPrint(-1,"SetFileInfo: New File Name %S Old FileName %S \n", buffer->FileName, fh->FileNameLFN);
+#endif
+
+// Copy the Input FileName
+ Length = (UINT32) (Wcslen(buffer->FileName) * sizeof (CHAR16))+ 2;
+ Status = fsAllocateMemory (vi, Length, &NewFileName, FALSE);
+ pBS->CopyMem (NewFileName, buffer->FileName, Length);
+
+ if (FindMatchingDirEntry (ParentFh, NewFileName, &Del)) {
+ fsDeAllocateMemory (vi, NewFileName);
+ return EFI_ACCESS_DENIED; // Name already exists, can't rename to it
+ }
+
+ Status = ProcessOpenFileHandle (fhi, &NewFileName, &NewHandle, EFI_FILE_MODE_CREATE | 3, 0);
+ fsDeAllocateMemory (vi, NewFileName);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Newfhi = (FILE_HANDLE_INSTANCE *) NewHandle;
+
+// Delete the old Entry
+ if (fh->DirCluster || fh->DirOffset) {
+ fh->DirectoryEntry.Dir_Name[0] = DirErase;
+ Status = UpdateDirListFromFHDir(fh);
+ if (EFI_ERROR(Status)) return Status;
+ //Remove directory list from cache when deleted.
+ RemoveAllDirList(fh);
+ }
+
+// Other than FileName, copy all the directory entries.
+ pBS->CopyMem (&(Newfhi->pFH->DirectoryEntry.Dir_Attr), &(fh->DirectoryEntry.Dir_Attr), 32 - 11);
+
+// Transfer Information from New to Old
+ fhi->pFH = Newfhi->pFH;
+
+// Release the NewFileHandle Instance Created.
+ DListDelete (&(vi->OpenFIs), &(Newfhi->ViFILink));
+ fsDeAllocateMemory (vi, Newfhi);
+
+ RemoveAllDirList(fh->Parent); // Dir Listing for OLD File Handle
+ RemoveAllDirList(Newfhi->pFH->Parent); // Dir Listing for New File Handle
+ fh->InstancesCount--;
+ RemoveFH(fh); // Remove old File Handle
+ fh = Newfhi->pFH; // fh points to new FH
+//###DEBUG
+ /*
+ // For Directories, ".." entry should point to the new Parent.
+ if (fh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY) {
+ // Read 40h Bytes
+ GetTempBuffer (vi, &TempBuffer);
+ GetSectorAddressDir(fh, FIRSTCLUSTER(fh->DirectoryEntry), 0, &Sector, &SectorOffset);
+ Status = FsReadMedia (vi, TempBuffer, Sector, SectorOffset, 0x40, DIRECTORY_REGION);
+ if (EFI_ERROR(Status)) return Status;
+
+ if (TempBuffer [0] == '.' && TempBuffer[0x20] == '.' && TempBuffer[0x21] == '.') {
+ (UINT32) TempBuffer += sizeof (DIR_ENTRY_32);
+ ((DIR_ENTRY_32 *) TempBuffer)->Dir_FstClusLO = fh->Parent->DirectoryEntry.Dir_FstClusLO;
+ ((DIR_ENTRY_32 *) TempBuffer)->Dir_FstClusHI = fh->Parent->DirectoryEntry.Dir_FstClusHI;
+ Status = FsWriteMedia (vi, TempBuffer, Sector, SectorOffset, 0x40, DIRECTORY_REGION);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ ReleaseTempBuffer(vi);
+ }
+ */
+//###DEBUG END
+ fh->DirectoryEntry.Dir_Attr |= ATTR_ARCHIVE;
+
+ }
+
+// Update the Date and Time?
+ if (*(UINT32 *)&(buffer->CreateTime) != 0)
+ EfiToFatTime(buffer->CreateTime, &fh->DirectoryEntry.Dir_CrtDate, &fh->DirectoryEntry.Dir_CrtTime);
+
+ if (*(UINT32 *)&(buffer->LastAccessTime) != 0)
+ EfiToFatTime(buffer->LastAccessTime, &fh->DirectoryEntry.Dir_LstAccDate, &Dummy);
+
+ if (*(UINT32 *)&(buffer->ModificationTime) != 0)
+ EfiToFatTime(buffer->ModificationTime, &fh->DirectoryEntry.Dir_WrtDate, &fh->DirectoryEntry.Dir_WrtTime);
+
+// Newsize smaller than Original size?
+ if (fh->DirectoryEntry.Dir_FileSize > (UINT32)(buffer->FileSize)) {
+
+ Status = CheckFileWrite (fhi, FALSE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+#ifdef Debug_SetFileInfo
+ EfiDebugPrint(-1,"SetFileInfo: File Name %S New Size %x Old Size %x\n", buffer->FileName, buffer->FileSize, fh->DirectoryEntry.Dir_FileSize);
+#endif
+
+ Length = fh->DirectoryEntry.Dir_FileSize - (UINT32)(buffer->FileSize);
+ OldClusterCount = GetClustersRequired(vi, fh->DirectoryEntry.Dir_FileSize);
+ NewClusterCount = GetClustersRequired(vi, (UINT32)(buffer->FileSize));
+
+ if (NewClusterCount < OldClusterCount)
+ ShrinkClusters (vi, FIRSTCLUSTER(fh->DirectoryEntry), NewClusterCount);
+
+ fh->DirectoryEntry.Dir_FileSize = (UINT32)(buffer->FileSize);
+ fh->DirectoryEntry.Dir_Attr |= ATTR_ARCHIVE;
+
+ if (buffer->FileSize == 0 ) {
+ fh->DirectoryEntry.Dir_FstClusLO = 0;
+ fh->DirectoryEntry.Dir_FstClusHI = 0;
+ SetPositionFileHandle (fhi, 0);
+ }
+
+ if (fhi->Position > buffer->FileSize) {
+ SetPositionFileHandle (fhi, 0);
+ }
+ }
+
+// Newsize bigger than Original size?
+ if (fh->DirectoryEntry.Dir_FileSize < buffer->FileSize) {
+
+#ifdef Debug_SetFileInfo
+ EfiDebugPrint(-1,"SetFileInfo: File Name %S New Size %x Old Size %x\n", buffer->FileName, buffer->FileSize, fh->DirectoryEntry.Dir_FileSize);
+#endif
+
+ Status = CheckFileWrite (fhi, FALSE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+// Get the Size in Bytes to be grown
+ Length = (UINT32) (buffer->FileSize) - fh->DirectoryEntry.Dir_FileSize;
+ Status = ExtendFile (fhi, Length);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+// Update New File Size
+ fh->DirectoryEntry.Dir_FileSize = (UINT32)(buffer->FileSize);
+
+ }
+
+
+ Status = UpdateDirListFromFHDir(fh);
+ fhi->pFH->DirEntryChanged = FALSE;
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateDirListFromFHDir
+//
+// Description: Updates directory list from file handle directory entry
+//
+// Parameters: FILE_HANDLE *fh - Pointer to file handle structure
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S): Updates DIR list from FH Directory Entry and also writes
+// to the disk.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateDirListFromFHDir (
+ FILE_HANDLE *fh
+)
+{
+ EFI_STATUS Status;
+ DIR_ENTRY_LIST *Del;
+ UINT32 Sector, SectorOffset, Position;
+ UINT8 TempDirEntry[32];
+ UINT32 TempOffset, TempSector;
+ UINTN i;
+
+#ifdef Debug_CloseFileHandle
+// EfiDebugPrint(-1,"Update Dir Entry: %s, Dir Cluster %x, Dir Offset %x\n", fh->FileNameLFN, fh->DirCluster, fh->DirOffset);
+#endif
+
+ Status = LocateDel (fh->Parent->DirList.pHead, fh->DirCluster, fh->DirOffset, &Del, &Position);
+
+ if (!EFI_ERROR(Status)) {
+ pBS->CopyMem (&(Del->DirectoryEntry), &fh->DirectoryEntry, sizeof(DIR_ENTRY_32));
+ Del->Cluster = fh->DirCluster;
+ Del->Offset = fh->DirOffset;
+ Del->SlotNumber = fh->SlotNumber;
+ }
+
+ GetSectorAddressDir(fh->Parent, fh->DirCluster, fh->DirOffset, &Sector, &SectorOffset);
+
+ if (fh->DirectoryEntry.Dir_Name[0] == DIR_ENTRY_ERASE) {
+ TempSector = Sector;
+ TempOffset = SectorOffset;
+
+ if (TempOffset == 0) {
+ TempSector--;
+ TempOffset = fh->VolumeInterface->VolumeBPB.BPB_BytePerSec;
+ }
+
+ for (i = 0; i < MAX_LFN_SLOTS; i++) {
+ TempOffset -= sizeof(DIR_ENTRY_LFN);
+ Status = FsReadMedia (fh->VolumeInterface, (void *)&TempDirEntry, TempSector, TempOffset, sizeof(DIR_ENTRY_32), DIRECTORY_REGION);
+
+ if (TempDirEntry[11] == (ATTR_LONG_NAME)) {
+ TempDirEntry[0] = DIR_ENTRY_ERASE; // Mark long entry erased.
+ Status = FsWriteMedia (fh->VolumeInterface, (void *)&TempDirEntry, TempSector, TempOffset, sizeof(DIR_ENTRY_32), DIRECTORY_REGION);
+
+ } else break;
+
+ if (TempOffset == 0) {
+ TempSector--;
+ TempOffset = fh->VolumeInterface->VolumeBPB.BPB_BytePerSec;
+ }
+ }
+ }
+
+ return FsWriteMedia (fh->VolumeInterface, (void *)&fh->DirectoryEntry, Sector,SectorOffset, sizeof(DIR_ENTRY_32), DIRECTORY_REGION);
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: LocateDel
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+LocateDel (
+ DLINK *dlink,
+ UINT32 Cluster,
+ UINT32 ClusterOffset,
+ DIR_ENTRY_LIST **Del,
+ UINT32 *Position
+)
+{
+
+ EFI_STATUS Status = EFI_NOT_FOUND;
+// DLINK *dlink = fh->Parent->DirList.pHead;
+ DIR_ENTRY_LIST *del;
+
+ *Del = NULL;
+ *Position = 0;
+
+// Copy this info to DIR_LIST if Present
+ for ( ; dlink; dlink = dlink->pNext, ++*Position) {
+ del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+
+// if (del->Cluster == fh->DirCluster && del->Offset == fh->DirOffset) {
+ if (del->Cluster == Cluster && del->Offset == ClusterOffset) {
+ *Del = del;
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetSystemInfo
+//
+// Description: Sets the information in a volume label
+//
+// Parameters: VOLUME_INFO *vi - Pointer to volume info structure
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer containing new data
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetSystemInfo (
+ IN VOLUME_INFO *vi,
+ IN UINTN BufferSize,
+ OUT EFI_FILE_SYSTEM_INFO *Buffer
+)
+{
+
+ EFI_STATUS Status;
+ EFI_FILE_SYSTEM_INFO *buffer = Buffer;
+ UINT32 Length = (UINT32)Wcslen(Buffer->VolumeLabel) + 2;
+
+#ifdef Debug_SetSystemInfo
+ Length += EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel);
+
+ EfiDebugPrint(-1,"SetSystemInfo: VolumeLabel %s, BufferSize %x BufferRequired %x\n", Buffer->VolumeLabel, BufferSize, Length);
+ EfiDebugPrint(-1,"Size %lx, ReadOnly %x, VolumeSize %lx, FreeSpace %lx, BlockSize %x\n", Buffer->Size, Buffer->ReadOnly, Buffer->VolumeSize, Buffer->FreeSpace, Buffer->BlockSize);
+#endif
+
+ if (BufferSize < (EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_INFO, VolumeLabel) + 2) || buffer->Size > BufferSize) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+// if (BufferSize < Length) return EFI_BAD_BUFFER_SIZE;
+
+// Only Volume Label can be set
+ Status = SetVolumeLabel (vi, Length, &Buffer->VolumeLabel);
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetVolumeLabel
+//
+// Description: Updates the label on a volume
+//
+// Parameters: VOLUME_INFO *vi - Pointer to volume info structure
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer containing new label
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetVolumeLabel (
+ IN VOLUME_INFO *vi,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 VolumeLabel[12];
+ UINT32 Sector, SectorOffset, Length;
+ FILE_HANDLE *fh = vi->RootFH, *fh1;
+ DLINK *dlink;
+ DIR_ENTRY_LIST *del;
+ UINT8 i;
+
+// Convert the Unicode string to English
+// Shell Doen't support remove of LABEL right now.
+// if (!BufferSize ) return EFI_BAD_BUFFER_SIZE;
+
+ Length = (UINT32)Wcslen(Buffer) * sizeof (CHAR16) + 2;
+
+#ifdef Debug_SetVolumeLabel
+ EfiDebugPrint(-1,"SetVolumeLabel: VolumeLabel %s BufferSize %x Length %x\n", Buffer, BufferSize, Length);
+#endif
+
+ Length = EFI_FIELD_OFFSET(EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel);
+
+ if (BufferSize < Length + 2) return EFI_BAD_BUFFER_SIZE;
+
+ MemSet(VolumeLabel, 11, 0x20); // Fill short name with spaces
+ vi->UnicodeCollationInterface->StrToFat (vi->UnicodeCollationInterface,
+ Buffer,
+ 11,
+ VolumeLabel);
+ VolumeLabel[11] = 0;
+
+// Update volume Label in vi->Volume
+ if (Strlen(VolumeLabel) > 11) return EFI_BAD_BUFFER_SIZE;
+
+ vi->UnicodeCollationInterface->FatToStr(vi->UnicodeCollationInterface, 11, VolumeLabel, vi->VolumeID);
+
+ for (i=0; i<11; i++) {
+ if (vi->VolumeID[i] == 0x20) break;
+ }
+
+ vi->VolumeID[i] = 0;
+ vi->ValidVolumeID = TRUE;
+
+// Check if Volume ID Directory Entry is present. If so Modify it.
+ if (!fh->DirList.pHead) ReadAllDirectoryEntries (fh);
+
+ dlink = fh->DirList.pHead;
+ Status = EFI_NOT_FOUND;
+
+ for ( ; dlink; dlink = dlink->pNext) {
+ del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+
+ if ((del->DirectoryEntry.Dir_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) == ATTR_VOLUME_ID) {
+
+ pBS->CopyMem(&del->DirectoryEntry.Dir_Name, VolumeLabel, 11);
+
+// Update LastAcc date and Wrtdate/Time and the Attribute
+ UpdateAccAndWriteTime (del);
+ del->DirectoryEntry.Dir_Attr |= ATTR_ARCHIVE;
+
+ if (VolumeLabel[0] == 0x20) del->DirectoryEntry.Dir_Name[0] = 0xE5;
+
+ GetSectorAddressDir (fh, del->Cluster, del->Offset, &Sector, &SectorOffset);
+ Status = FsWriteMedia (vi, (void *)&del->DirectoryEntry, Sector, SectorOffset, sizeof(DIR_ENTRY_32), DIRECTORY_REGION);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (VolumeLabel[0] == 0x20) RemoveDirList(fh, del);
+
+ break;
+ }
+ }
+
+
+ if (Status == EFI_NOT_FOUND && VolumeLabel[0] != 0x20) {
+ fh1 = 0;
+ CreateDirectoryEntry (fh, vi->VolumeID, &fh1, ATTR_VOLUME_ID |ATTR_ARCHIVE);
+
+ if (fh1) RemoveFH(fh1); // FILE_HANDLE Created is not needed.
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFileInfoFromFH
+//
+// Description: Returns information on a file from it's handle
+//
+// Parameters: FILE_HANDLE_INSTANCE *fh1 - Pointer to file handle
+// instance
+// UINTN *BufferSize - Pointer to size of buffer
+// VOID *Buffer - Ponter to buffer for returned data
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFileInfoFromFH (
+ FILE_HANDLE *Pfh,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+)
+{
+ VOLUME_INFO *vi = Pfh->VolumeInterface;
+ EFI_FILE_INFO *buffer = Buffer;
+ UINTN Length;
+
+ Length = (UINT32)Wcslen(Pfh->FileNameLFN) * sizeof (CHAR16) + 2;
+ Length += EFI_FIELD_OFFSET(EFI_FILE_INFO,FileName);
+
+// Length += sizeof(EFI_FILE_INFO);
+ if (*BufferSize < Length) {
+#ifdef Debug_GetFileInfo_1
+ EfiDebugPrint(-1,"GetFileInfo: %S BufferSize %x LengthRequired %x Status: EFI_BUFFER_TOO_SMALL\n", Pfh->FileNameLFN, *BufferSize, Length + 2);
+#endif
+ *BufferSize = Length;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = Length;
+ buffer->Size = Length;
+ buffer->FileSize = Pfh->DirectoryEntry.Dir_FileSize;
+ buffer->PhysicalSize = buffer->FileSize;
+
+ Length = (Pfh->DirectoryEntry.Dir_FileSize % vi->BytesPerCluster);
+
+ if (Length)
+ buffer->PhysicalSize += vi->BytesPerCluster - (Pfh->DirectoryEntry.Dir_FileSize % vi->BytesPerCluster);
+
+ FatToEfiTime (&(buffer->CreateTime), Pfh->DirectoryEntry.Dir_CrtDate, Pfh->DirectoryEntry.Dir_CrtTime);
+ FatToEfiTime (&(buffer->LastAccessTime), Pfh->DirectoryEntry.Dir_LstAccDate, 0);
+ FatToEfiTime (&(buffer->ModificationTime), Pfh->DirectoryEntry.Dir_WrtDate, Pfh->DirectoryEntry.Dir_WrtTime);
+ buffer->Attribute = Pfh->DirectoryEntry.Dir_Attr & EFI_FILE_VALID_ATTR;
+ Wcscpy (buffer->FileName, Pfh->FileNameLFN);
+#ifdef Debug_GetFileInfo_0
+ EfiDebugPrint(-1,"GetFileInfo: %S File Size %lx \n", Pfh->FileNameLFN, buffer->FileSize);
+#endif
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FatToEfiTime
+//
+// Description: Converts time/date in FAT format to EFI format
+//
+// Parameters: EFI_TIME *EfiTime - Ponter to returned time in EFI format
+// UINT16 Date - Date in FAT format
+// UINT16 Time - Time in FAT format
+//
+// Return value: None
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+FatToEfiTime (
+ EFI_TIME *EfiTime,
+ UINT16 Date,
+ UINT16 Time
+)
+{
+
+ EfiTime->Year = (UINT16) (((FAT_DATE*) &Date)->Year + 1980);
+ EfiTime->Month = (UINT8 ) ((FAT_DATE*) &Date)->Month;
+ EfiTime->Day = (UINT8) ((FAT_DATE*) &Date)->Day;
+ EfiTime->Hour = (UINT8) ((FAT_TIME*) &Time)->Hour;
+ EfiTime->Minute = (UINT8) ((FAT_TIME*) &Time)->Minute;
+ EfiTime->Second = (UINT8) ((FAT_TIME*) &Time)->DoubleSecond;
+ EfiTime->Nanosecond = 0;
+ EfiTime->TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+ EfiTime->Pad1 = 0;
+ EfiTime->Daylight = 0;
+ EfiTime->Pad2 = 0;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EfiToFatTime
+//
+// Description: Converts date/time in EFI format to FAT format
+//
+// Parameters: EFI_TIME EfiTime - Time in EFI format
+// UINT16 *Date - Pointer to returned date in FAT format
+// UINT16 *Time - Pointer to returned time in FAT format
+//
+// Return value: None
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EfiToFatTime (
+ EFI_TIME EfiTime,
+ UINT16 *Date,
+ UINT16 *Time
+)
+{
+
+ ((FAT_DATE*)Date)->Year = EfiTime.Year - 1980;
+ ((FAT_DATE*)Date)->Month = EfiTime.Month;
+ ((FAT_DATE*)Date)->Day = EfiTime.Day;
+ ((FAT_TIME*)Time)->Hour = EfiTime.Hour;
+ ((FAT_TIME*)Time)->Minute = EfiTime.Minute;
+ ((FAT_TIME*)Time)->DoubleSecond = EfiTime.Second;
+
+}
+
+// Special string copy for volume labels.
+// Skips the "." that ExtractShortFileName puts in. Replaces Wcscpy().
+VOID Labcpy(
+ CHAR16 *string1,
+ CHAR16 * string2
+)
+{
+ while (*string2) {
+ if ((CHAR8)*string2 != '.') {
+ *string1++ = *string2++;
+
+ } else *string2++;
+ }
+}
+
+// Special string length counter for volume labels.
+// Skips the "." that ExtractShortFileName puts in. Replaces Wcslen().
+UINTN Lablen(
+ CHAR16 *string
+)
+{
+ UINTN length=0;
+
+ while (*string++) {
+ if ((CHAR8)*string != '.') length++;
+ }
+
+ return length;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindNextTpl
+//
+// Description: Returns the higher of a desired TPL level or the current
+// next higher TPL level
+//
+// Parameters: EFI_TPL TplLevel -- desired level to raise to
+//
+// Return Value: EFI_TPL
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_TPL
+FindNextTpl (
+ EFI_TPL TplLevel
+ )
+{
+ EFI_TPL NextTpl;
+
+ NextTpl = pBS->RaiseTPL (TPL_HIGH_LEVEL);
+ pBS->RestoreTPL(NextTpl);\
+ if(NextTpl<=TplLevel) NextTpl = TplLevel;
+ return NextTpl;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/MediaAccess.c b/Core/EM/FileSystem/MediaAccess.c
new file mode 100644
index 0000000..f87fb15
--- /dev/null
+++ b/Core/EM/FileSystem/MediaAccess.c
@@ -0,0 +1,1479 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/MediaAccess.c 11 10/24/11 10:55a Artems $
+//
+// $Revision: 11 $
+//
+// $Date: 10/24/11 10:55a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/MediaAccess.c $
+//
+// 11 10/24/11 10:55a Artems
+// EIP 73254: Remove "magic number" from source
+//
+// 10 5/05/11 3:44p Pats
+// [TAG] - EIP 58999
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - Cannot launch Shell from USB Filesystem device in Debug
+// mode with latest Filesystem driver.
+// [RootCause] - Functions using DISKIO were raising TPL to a fixed level.
+// [Solution] - Modified above functions to check for the higher of the
+// fixed level or current level.
+// [Files] - Info.c, MediaAccess.c, Open.c, FileSystem.h
+//
+// 9 1/06/11 5:55p Oleksiyy
+// [TAG] EIP28607
+// [Category] Improvement
+// [Description] System was hanging for some time if Floppy Media
+// removed while writing in meda in progress.
+// EFI_TPL_CALLBACK priority level rised during media related calls.
+//
+// [Files] DiskIo.c, Info.c, MediaAccess.c, Open.c, Partition.c
+//
+// 8 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 7 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 6 8/25/06 12:10p Felixp
+// Bug fix in GetNextCompName
+//
+// 5 8/25/06 12:06p Felixp
+// Bug fix in GetNextCompName
+//
+// 5 11/03/05 2:17p Srinin
+// Fixed VC7.1 warning msg.
+//
+// 4 7/06/05 11:25a Pats
+// Modified function RemoveFH to delete child Dlist only if the parent is
+// valid. Fixes problem of booting to floppy failing under certain
+// conditions.
+//
+// 2 5/27/05 10:01a Srinin
+// Fix for Media change and SCT long file name handling.
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: MediaAccess.c
+//
+// Description: Handles all Media access
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "FileSystem.h"
+#define EFI_TPL_CALLBACK TPL_CALLBACK
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FsReadMedia
+//
+// Description: Reads a specified no. of bytes from media at a specified
+// location (abs. sector and offset in sector)
+//
+// Parameters:
+// VOLUME_INFO *vi, Pointer to Volume Info structure
+// UINT8 *Buffer, Valid Buffer pointer should be Passed
+// UINT64 Sector, Start Sector number
+// UINT32 Offset, Offset within the sector to read from
+// UINT32 ByteCount, Number of bytes to read from the offset
+// REGIONS DataRegion See descriptions of REGION. Primarily
+// used to dtermine caching algorithm.
+//typedef enum {
+// RESERVED_REGION,
+// FAT_REGION,
+// DIRECTORY_REGION,
+// DATA_REGION
+//} REGIONS;
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FsReadMedia (
+ VOLUME_INFO *vi,
+ UINT8 *Buffer,
+ UINT64 Sector,
+ UINT32 Offset,
+ UINT32 ByteCount,
+ REGIONS DataRegion
+)
+{
+
+ EFI_STATUS Status;
+ UINT64 AbsoluteOffset;
+ UINT8 *cBuffer;
+ UINT32 cBufferLength;
+ CACHE_HEADER *ch = NULL;
+
+// Convert Sector number to Absolute offset.
+ AbsoluteOffset = Shl64 (Sector, vi->BytesPerSecPowerof2) + Offset;
+
+ if (DataRegion == DATA_REGION) {
+ Status= vi->DiskIo->ReadDisk (vi->DiskIo, vi->MediaID, AbsoluteOffset, ByteCount, Buffer);
+
+ if (EFI_ERROR(Status)) HandleDiskIoError(vi, Status);
+
+ return Status;
+ }
+
+// DATA_REGION is FAT or DIRECTORY
+ for ( ; ByteCount; ) {
+ Status = CheckCached(vi, AbsoluteOffset, ByteCount, &cBuffer, &cBufferLength, &ch, DataRegion);
+
+ if (EFI_ERROR(Status)) {
+ HandleDiskIoError(vi, Status);
+ return Status;
+ }
+
+ pBS->CopyMem(Buffer, cBuffer, cBufferLength);
+ ByteCount -= cBufferLength;
+ Buffer += cBufferLength;
+ AbsoluteOffset += cBufferLength;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckCached
+//
+// Description: Checks to see if the media data we're working with is
+// cached
+//
+// Parameters:
+// VOLUME_INFO *vi, Pointer to volume info structure
+// UINT64 AbsoluteOffset, Absolute offset of data
+// UINT32 ByteCount, Byte Count of data
+// UINT8 **cBuffer, Cache buffer
+// UINT32 *cBufferLength Cache buffer length
+// CACHE_HEADER **ch Cache header stucture
+// REGIONS DataRegion See descriptions of REGION. Primarily
+// used to dtermine caching algorithm.
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckCached (
+ VOLUME_INFO *vi,
+ UINT64 AbsoluteOffset,
+ UINT32 ByteCount,
+ UINT8 **cBuffer,
+ UINT32 *cBufferLength,
+ CACHE_HEADER **ch,
+ REGIONS DataRegion
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 Mask;
+ UINT64 AlignedAbsoluteOffset;
+ UINT32 AlignedBytecount;
+ CACHE_HEADER *ch1 = NULL;
+
+ if (!IsCacheHit(vi, DataRegion, AbsoluteOffset, ByteCount, cBuffer, cBufferLength, &ch1)) {
+
+// No match found for AbsoluteOffset
+ Mask = 0x80000000;
+ Mask -= vi->BytesPerCluster;
+ Mask |= 0xf0000000;
+ AlignedAbsoluteOffset = AbsoluteOffset;
+ *(UINT32 *)&AlignedAbsoluteOffset = *(UINT32 *)&AbsoluteOffset & Mask;
+ AlignedBytecount = vi->BytesPerCluster;
+
+ CreateSpaceforCache (vi, AlignedBytecount, DataRegion, &ch1);
+ Status= vi->DiskIo->ReadDisk (vi->DiskIo, vi->MediaID, AlignedAbsoluteOffset, AlignedBytecount, ch1->Buffer);
+
+ if (EFI_ERROR(Status)) {
+ HandleDiskIoError(vi, Status);
+ return Status;
+ }
+
+ ch1->AbsoluteOffset = AlignedAbsoluteOffset;
+ ch1->AbsoluteOffsetEnd = AlignedAbsoluteOffset + AlignedBytecount;
+ ch1->DIRTY_FLAG = FALSE;
+ ch1->DataRegion = DataRegion;
+ DListDelete (&(vi->CacheList), &(ch1->CacheLink));
+ DListAdd(&(vi->CacheList), &(ch1->CacheLink));
+
+#ifdef Debug_Caching
+ EfiDebugPrint(-1,"Caching Offset %lx End Offset %lx MemAddress %x\n", ch1->AbsoluteOffset, ch1->AbsoluteOffsetEnd, ch1->Buffer);
+#endif
+
+ if (!(IsCacheHit(vi, DataRegion, AbsoluteOffset, ByteCount, cBuffer, cBufferLength, &ch1))) {
+ Status = EFI_DEVICE_ERROR;
+ ASSERT_EFI_ERROR(Status); // something wrong in the algorithm
+ }
+ }
+
+ *ch = ch1;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IsCacheHit
+//
+// Description:
+//
+// Parameters:
+// VOLUME_INFO *vi, Pointer to volume info structure
+// UINT64 AbsoluteOffset, Absolute offset of data
+// UINT32 ByteCount, Byte Count of data
+// UINT8 **cBuffer, Cache buffer
+// UINT32 *cBufferLength Cache buffer length
+//
+// Return value: BOOLEAN - True if cache hit
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsCacheHit (
+ VOLUME_INFO *vi,
+ REGIONS DataRegion,
+ UINT64 AbsoluteOffset,
+ UINT32 ByteCount,
+ UINT8 **cBuffer,
+ UINT32 *cBufferLength,
+ CACHE_HEADER **ch1
+)
+{
+
+ DLINK *dlink = vi->CacheList.pTail;
+ CACHE_HEADER *ch;
+
+ for ( ; dlink; ) {
+
+ ch = OUTTER(dlink, CacheLink, CACHE_HEADER);
+
+ if (ch->DataRegion == DataRegion && AbsoluteOffset >= ch->AbsoluteOffset && AbsoluteOffset < ch->AbsoluteOffsetEnd) {
+
+ *cBuffer = (UINT8 *)(ch->Buffer + (UINT32) (AbsoluteOffset - ch->AbsoluteOffset));
+ *cBufferLength = (UINT32) (ch->AbsoluteOffsetEnd - AbsoluteOffset);
+
+ if (*cBufferLength > ByteCount) *cBufferLength = ByteCount;
+
+// Important. Remove the link and add it to the end.
+// As least used data area will be moved to the front of the LIST
+ DListDelete (&(vi->CacheList), &(ch->CacheLink));
+ DListAdd(&(vi->CacheList), &(ch->CacheLink));
+ *ch1 = ch;
+ return TRUE;
+ }
+
+ dlink = dlink->pPrev;
+
+ }
+
+ return FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CreateSpaceforCache
+//
+// Description: Creates space on media for cache
+//
+// Parameters:
+// VOLUME_INFO *vi, Volume info structure
+// UINT32 ByteCount, Bytes of space to create
+// REGIONS DataRegion See descriptions of REGION. Primarily used
+// to dtermine caching algorithm.
+//
+// Return value: None
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+CreateSpaceforCache (
+ VOLUME_INFO *vi,
+ UINT32 ByteCount,
+ REGIONS DataRegion,
+ CACHE_HEADER **ch1
+)
+{
+
+ EFI_STATUS Status;
+ DLINK *dlink = vi->CacheList.pHead;
+ CACHE_HEADER *ch;
+
+ for ( ; dlink; ) {
+
+ ch = OUTTER(dlink, CacheLink, CACHE_HEADER);
+ dlink = dlink->pNext;
+
+ if (ch->DataRegion != DataRegion) continue;
+
+ if (ch->DIRTY_FLAG) {
+ Status= vi->DiskIo->WriteDisk (vi->DiskIo, vi->MediaID, ch->AbsoluteOffset, (UINT32) (ch->AbsoluteOffsetEnd - ch->AbsoluteOffset), ch->Buffer);
+
+ if (EFI_ERROR(Status)) HandleDiskIoError(vi, Status);
+
+ ch->DIRTY_FLAG = FALSE;
+ }
+
+ *ch1 = ch;
+ break;
+
+ }
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FsWriteMedia
+//
+// Description: Writes a specified no. of bytes to media at a specified
+// location (abs. sector and offset in sector)
+//
+// Parameters:
+// VOLUME_INFO *vi,
+// UINT8 *Buffer, Valid Buffer pointer should be Passed
+// UINT64 Sector, Start Sector number
+// UINT32 Offset, Offset within the sector to read from
+// UINT32 ByteCount, Number of bytes to read from the offset
+// REGIONS DataRegion See descriptions of REGION. Primarily used
+// to dtermine caching algorithm.
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FsWriteMedia (
+ VOLUME_INFO *vi,
+ UINT8 *Buffer,
+ UINT64 Sector,
+ UINT32 Offset,
+ UINT32 ByteCount,
+ REGIONS DataRegion
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT64 AbsoluteOffset;
+ UINT8 *cBuffer = NULL;
+ UINT32 cBufferLength;
+ CACHE_HEADER *ch = NULL;
+
+// Convert Sector number to Absolute offset.
+ AbsoluteOffset = Shl64 (Sector, vi->BytesPerSecPowerof2) + Offset;
+
+ if (DataRegion == DATA_REGION) {
+ Status= vi->DiskIo->WriteDisk (vi->DiskIo, vi->MediaID, AbsoluteOffset, ByteCount, Buffer);
+
+ if (EFI_ERROR(Status)) HandleDiskIoError(vi, Status);
+
+ return Status;
+ }
+
+//###DEBUG
+ /*
+ // Check for cache hit
+ do {
+ if (!IsCacheHit (vi, DataRegion, AbsoluteOffset, ByteCount, &cBuffer, &cBufferLength, &ch)) {
+ // Cache the region, before writing it
+ for (AbsoluteOffset1 = AbsoluteOffset, ByteCount1 = ByteCount; ByteCount1; ) {
+ Status = CheckCached(vi, AbsoluteOffset1, ByteCount1, &cBuffer1, &cBufferLength1, DataRegion);
+ if (EFI_ERROR(Status)) {
+ HandleDiskIoError(vi, Status);
+ return Status;
+ }
+ ByteCount1 -= cBufferLength1;
+ AbsoluteOffset1 += cBufferLength1;
+ }
+ continue;
+ }
+ // Copy i/p buffer to the cache. Update the flag
+ pBS->CopyMem(cBuffer, Buffer, cBufferLength);
+ Buffer += cBufferLength;
+ ByteCount -= cBufferLength;
+ ch->DIRTY_FLAG = TRUE;
+ }
+ while (ByteCount);
+ */
+//###DEBUG END
+ do {
+ Status = CheckCached(vi, AbsoluteOffset, ByteCount, &cBuffer, &cBufferLength, &ch, DataRegion);
+
+ if (EFI_ERROR(Status)) {
+ HandleDiskIoError(vi, Status);
+ return Status;
+ }
+
+ pBS->CopyMem(cBuffer, Buffer, cBufferLength);
+ ByteCount -= cBufferLength;
+ Buffer += cBufferLength;
+ AbsoluteOffset += cBufferLength;
+ ch->DIRTY_FLAG = TRUE;
+ } while (ByteCount);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: HandleDiskIoError
+//
+// Description: Handles disk read/write error
+//
+// Parameters:
+// VOLUME_INFO *vi, Volume Info Structure
+//
+// Return value: None
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+HandleDiskIoError (
+ VOLUME_INFO *vi,
+ EFI_STATUS Status
+
+)
+{
+
+//###DEBUG
+// We may need some error handling here
+//###DEBUG END
+ if (Status == EFI_MEDIA_CHANGED || Status == EFI_NO_MEDIA)
+ FreeUpResources (vi, Status);
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FreeUpResources
+//
+// Description: Frees up resouces when volumes opened/closed
+//
+// Parameters:
+// VOLUME_INFO *vi, Volume info structure
+// EFI_STATUS Status Status to update file handles with
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FreeUpResources (
+ VOLUME_INFO *vi,
+ EFI_STATUS Status
+)
+{
+
+ DLINK *dlink = vi->OpenFIs.pHead;
+ FILE_HANDLE *fh;
+ FILE_HANDLE_INSTANCE *fhi;
+ CACHE_HEADER *ch;
+
+
+// Go through the list of Open File Handles Instances and update the status
+ while (dlink) {
+ fhi = OUTTER(dlink, ViFILink, FILE_HANDLE_INSTANCE);
+ fhi->HandleInstanceStatus = Status;
+ fhi->pFH = NULL;
+ DListDelete (&(vi->OpenFIs), &(fhi->ViFILink));
+
+ if (!dlink->pNext) break;
+
+ dlink = dlink->pNext;
+ }
+
+
+// Release all File_Handles/DirList
+ dlink = vi->OpenFHs.pHead;
+
+ while (dlink) {
+ fh = OUTTER(dlink, ViFHLink, FILE_HANDLE);
+ fh->InstancesCount = 0;
+ dlink = dlink->pNext;
+
+ if (fh->DirList.pHead) RemoveAllDirList(fh);
+
+ if (fh->ROOTDIR) vi->RootFH = NULL;
+
+ RemoveFH(fh);
+ }
+
+// Update the Status in VOLUME_INFO
+ vi->VolumeStatus = Status;
+ vi->ValidVolumeID = FALSE;
+
+ if (vi->FileSystemName) pBS->FreePool (vi->FileSystemName);
+
+ vi->FileSystemName = NULL;
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+ dlink = vi->CacheList.pTail;
+
+ if (!dlink) return FALSE;
+
+ for ( ; dlink; ) {
+ ch = OUTTER(dlink, CacheLink, CACHE_HEADER);
+ ch->AbsoluteOffset = 0;
+ ch->AbsoluteOffsetEnd = 0;
+ ch->DIRTY_FLAG = FALSE;
+ dlink = dlink->pPrev;
+ }
+
+////////////////////////////////////////////////////////////////////////////////////////
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ValidateCurrentStatus
+//
+// Description: Validates status if file handle instance
+//
+// Parameters:
+// FILE_HANDLE_INSTANCE *fhi
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ValidateCurrentStatus (
+ FILE_HANDLE_INSTANCE *fhi
+)
+{
+ FILE_HANDLE *Pfh = fhi->pFH;
+
+ if (fhi->HandleInstanceStatus != EFI_SUCCESS) return fhi->HandleInstanceStatus;
+
+ if (!Pfh) return EFI_NOT_FOUND;
+
+ if (Pfh->HandleStatus != EFI_SUCCESS) return Pfh->HandleStatus;
+
+ if (EFI_ERROR(Pfh->VolumeInterface->VolumeStatus)) return Pfh->VolumeInterface->VolumeStatus;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetPositionFileHandle
+//
+// Description: Gets position in an open file handle
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This,
+// IN UINT64 *Position
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetPositionFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 *Position
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+ FILE_HANDLE *Pfh = fhi->pFH;
+ VOLUME_INFO *vi = Pfh->VolumeInterface;
+
+ Status = ValidateCurrentStatus (fhi);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (fhi->HandleInstanceStatus | Pfh->HandleStatus | vi->VolumeStatus) return EFI_UNSUPPORTED;
+
+ if (Pfh->DirectoryEntry.Dir_Attr & (ATTR_VOLUME_ID | ATTR_DIRECTORY)) return EFI_UNSUPPORTED;
+
+ *Position = fhi->Position;
+
+#ifdef Debug_GetPosition
+ EfiDebugPrint(-1,"GetPosition: File Name %s Position %x\n", Pfh->FileNameLFN, buffer->FileSize, Position);
+#endif
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetPositionFileHandleThis
+//
+// Description: Sets position in current file handle instance
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This,
+// IN UINT64 Position
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetPositionFileHandleThis (
+ IN EFI_FILE_PROTOCOL *This,
+ IN UINT64 Position
+)
+{
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+
+ Status = ValidateCurrentStatus (fhi);
+
+ if (EFI_ERROR(Status)) return Status;
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+ Status = SetPositionFileHandle (fhi, Position);
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetPositionFileHandle
+//
+// Description: Sets position in an open file handle
+//
+// Parameters:
+// IN FILE_HANDLE_INSTANCE *fhi,
+// IN UINT64 Position
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetPositionFileHandle (
+ IN FILE_HANDLE_INSTANCE *fhi,
+ IN UINT64 Position
+)
+{
+
+ FILE_HANDLE *Pfh = fhi->pFH;
+ VOLUME_INFO *vi = Pfh->VolumeInterface;
+
+#ifdef Debug_SetPosition
+ EfiDebugPrint(-1,"SetPosition: %s Pos %lx", fhi->pFH->FileNameLFN, Position);
+#endif
+
+ if (fhi->HandleInstanceStatus | Pfh->HandleStatus | vi->VolumeStatus) return EFI_UNSUPPORTED;
+
+ if (Pfh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY) {
+ if (Position != 0) return EFI_UNSUPPORTED;
+ }
+
+ fhi->Position = Position;
+
+//TODO TODO TODO
+// If Position is beyond the filesize, update the file position.
+// For reads issues Device_error. While writing, extend the file.
+//TODO TODO TODO
+
+// Update internal data Area
+ if (fhi->Position == -1) fhi->Position = Pfh->DirectoryEntry.Dir_FileSize;
+
+ if (fhi->Position == 0) {
+ fhi->CurrentCluster = FIRSTCLUSTER(fhi->pFH->DirectoryEntry);
+ fhi->CurrentClusterOffset = 0;
+
+ } else {
+ GetClusterPosition(fhi, fhi->Position, &fhi->CurrentCluster, &fhi->CurrentClusterOffset);
+ }
+
+#ifdef Debug_SetPosition
+ EfiDebugPrint(-1," Clus %x ClusOffset %x\n", fhi->CurrentCluster, fhi->CurrentClusterOffset);
+#endif
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RemoveFH
+//
+// Description: Romoves file handle (closed file)
+//
+// Parameters:
+// FILE_HANDLE *fh
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveFH (
+ FILE_HANDLE *fh
+)
+{
+
+ VOLUME_INFO *vi = fh->VolumeInterface;
+
+#ifdef Debug_RemoveFH
+ EfiDebugPrint(-1,"RemoveFH: %s\n", fh->FileNameLFN);
+#endif
+
+// Check if there any open instances for this FH
+ if (fh->InstancesCount) return EFI_ACCESS_DENIED;
+
+// Check if DLIST is NULL.
+ if (fh->DirList.pHead) return EFI_ACCESS_DENIED;
+
+ fsDeAllocateMemory(vi, fh->FileNameLFN);
+ DListDelete (&(vi->OpenFHs), &(fh->ViFHLink));
+
+// Delete child Dlist only if parent is valid.
+ if (fh->Parent) DListDelete (&(fh->Parent->ChildList), &(fh->ChildLink));
+
+ fsDeAllocateMemory(vi, fh);
+
+#ifdef Debug_RemoveFH
+ EfiDebugPrint(-1,"RemoveFH Success\n");
+#endif
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetNextCompName
+//
+// Description: Gets next component name in path
+//
+// Parameters:
+// IN OUT CHAR16 **FileName,
+// IN CHAR16 *NextCompName
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetNextCompName (
+ IN OUT CHAR16 **FileName,
+ IN CHAR16 *NextCompName
+)
+{
+
+ UINT32 Index = 0;
+ NextCompName[Index] = (*FileName)[Index];
+
+ while ((*FileName)[Index] !=0 && (*FileName)[Index] != '\\') {
+ NextCompName[Index] = (*FileName)[Index];
+ Index++;
+
+ if (Index >= MAX_TOTAL_PATH_LENGTH) return EFI_INVALID_PARAMETER;
+ }
+
+ NextCompName[Index] = 0;
+
+// Point *FileName beyond the trailing '\\'
+ if ((*FileName)[Index] == '\\') {
+ Index++;
+ }
+
+// After '\\' it should not be 0.
+ if (Index != 0 && (*FileName)[Index - 1] == '\\' &&
+ (*FileName)[Index] == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *FileName = (*FileName) + Index;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: fsAllocateMemory
+//
+// Description: Allocates memory for use by file system driver
+//
+// Parameters:
+// VOLUME_INFO *vi
+// VOID **Buffer
+// UINT32 Size
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+fsAllocateMemory (
+ VOLUME_INFO *vi,
+ UINT32 Size,
+ VOID **Buffer,
+ BOOLEAN CLEAR
+)
+{
+
+ EFI_STATUS Status;
+ UINTN Address = (UINTN) Buffer;
+ UINT32 Length;
+
+
+ if (Size <= 1024) {
+ Status = InternalMemAllocate (vi, Size, Buffer, CLEAR);
+ return Status;
+ }
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ Size,
+ (VOID**)Buffer);
+
+ Address = (UINTN) *Buffer;
+ Address -=0xc; // Point to the Size
+ Length = *(UINT32 *)Address; // Get the size
+
+ if (Status == EFI_SUCCESS) vi->AllocatedMemorySize += Length;
+
+ if (Status == EFI_SUCCESS && CLEAR) Zeromemory (*Buffer, Size);
+
+#ifdef Debug_Allocatememory
+ EfiDebugPrint(-1,"AllocateMemory : %x Total mememory Allocated : %x\n", Length, vi->AllocatedMemorySize);
+#endif
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: fsDeAllocateMemory
+//
+// Description: De-allocates memory used by file system driver
+//
+// Parameters:
+// VOLUME_INFO *vi,
+// void *Buffer
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+fsDeAllocateMemory (
+ VOLUME_INFO *vi,
+ void *Buffer
+)
+{
+ UINTN Address = (UINTN) Buffer;
+ UINT32 Size;
+ EFI_STATUS Status;
+
+
+ Status = FreeMemory (vi, Buffer);
+
+ if (Status == EFI_SUCCESS) return EFI_SUCCESS;
+
+ Address -=0xc; // Point to the Size
+ Size = *(UINT32 *)Address; // Get the size
+ vi->AllocatedMemorySize -= Size;
+ Status = pBS->FreePool(Buffer);
+
+ if (Status == EFI_SUCCESS) Buffer = NULL;
+
+#ifdef Debug_Allocatememory
+ EfiDebugPrint(-1,"DeAllocateMemory : %x Total mememory Allocated : %x\n", Size, vi->AllocatedMemorySize);
+#endif
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InternalMemAllocate
+//
+// Description: Adds allocated memory to internal manager
+//
+// Parameters:
+// VOLUME_INFO *vi,
+// UINT32 Size,
+// VOID **Buffer,
+// BOOLEAN CLEAR
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InternalMemAllocate (
+ VOLUME_INFO *vi,
+ UINT32 Size,
+ VOID **Buffer,
+ BOOLEAN CLEAR
+)
+{
+ EFI_STATUS Status = EFI_OUT_OF_RESOURCES;
+ DLINK *dlink = vi->MemList.pTail;
+ MEM_HEADER *Mem;
+ UINT32 Blocks;
+
+ Blocks = Size / MEMALLOCSIZE;
+
+ if (Size % MEMALLOCSIZE) Blocks++;
+
+ for ( ; ; ) {
+ if (!dlink) {
+ Status = AddBlocktoInternalMemManager (vi);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ dlink = vi->MemList.pTail;
+ }
+
+ Mem = OUTTER(dlink, MemLink, MEM_HEADER);
+ Status = GetMemory (Mem, Blocks, Buffer, CLEAR);
+
+ if (Status == EFI_SUCCESS) return Status;
+
+ dlink = dlink->pPrev;
+ }
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetMemory
+//
+// Description: Gets memory for a buffer
+//
+// Parameters:
+// MEM_HEADER *Mem,
+// UINT32 Blocks,
+// VOID **Buffer,
+// BOOLEAN CLEAR
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetMemory (
+ MEM_HEADER *Mem,
+ UINT32 Blocks,
+ VOID **Buffer,
+ BOOLEAN CLEAR
+)
+{
+ UINT32 i, FreeBlockCounts = 0, StartBlock, Count;
+ UINT8 *MemMap = (UINT8 *)(Mem->AddresMap);
+ EFI_STATUS Status = EFI_NOT_FOUND;
+
+ for (i = 0; i < MEMBLOCKSIZE / MEMALLOCSIZE; i++) {
+ if (!MemMap[i]) {
+ if (!FreeBlockCounts) StartBlock = i;
+
+ FreeBlockCounts++;
+
+ if (FreeBlockCounts >= Blocks) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ } else FreeBlockCounts = 0;
+ }
+
+ if (Status == EFI_SUCCESS) {
+ *Buffer = (void *)(Mem->BufferStart + StartBlock * MEMALLOCSIZE);
+
+ for (i = 0, Count = 1; i < Blocks; i++, StartBlock++, Count++)
+ MemMap[StartBlock] = Count;
+
+ if (CLEAR) Zeromemory (*Buffer, MEMALLOCSIZE * Blocks);
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FreeMemory
+//
+// Description:
+//
+// Parameters:
+// VOLUME_INFO *Vi,
+// VOID *Buffer
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FreeMemory (
+ VOLUME_INFO *vi,
+ VOID *Buffer
+)
+{
+
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ DLINK *dlink = vi->MemList.pHead;
+ MEM_HEADER *Mem;
+ UINT32 StartBlock, Count;
+
+ for ( ; dlink ; ) {
+ Mem = OUTTER(dlink, MemLink, MEM_HEADER);
+
+ if (Buffer >= (void *)(Mem->BufferStart) && Buffer < (void *)(Mem->BufferEnd)) {
+
+ StartBlock = (UINT32) (((UINTN)Buffer - Mem->BufferStart) / MEMALLOCSIZE);
+
+ Status = EFI_SUCCESS;
+
+ for (Count = 1; ; Count++, StartBlock++)
+ if (((UINT8 *)(Mem->AddresMap))[StartBlock] == Count) ((UINT8 *)(Mem->AddresMap))[StartBlock] = 0;
+
+ else break;
+
+ }
+
+ if (Status == EFI_SUCCESS) break;
+
+ dlink = dlink->pNext;
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InternalMemAllocate
+//
+// Description:
+//
+// Parameters:
+// VOLUME_INFO *Vi,
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AddBlocktoInternalMemManager (
+ VOLUME_INFO *vi
+)
+{
+ EFI_STATUS Status;
+ UINT32 *Buffer;
+ MEM_HEADER *Mem;
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ MEMBLOCKSIZE + MEMBLOCKSIZE / MEMALLOCSIZE,
+ (VOID**)&Buffer);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ vi->AllocatedMemorySize += MEMBLOCKSIZE + MEMBLOCKSIZE / MEMALLOCSIZE;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (MEM_HEADER),
+ (VOID**)&Mem);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ vi->AllocatedMemorySize += sizeof (MEM_HEADER);
+
+ Mem->AddresMap = (UINTN) Buffer;
+ Mem->AddresMapLength = MEMBLOCKSIZE / MEMALLOCSIZE;
+ Mem->BufferStart = (UINTN) (Buffer) + MEMBLOCKSIZE / MEMALLOCSIZE;
+ Mem->BufferEnd = Mem->BufferStart + MEMBLOCKSIZE;
+ DListAdd(&(vi->MemList), &(Mem->MemLink));
+ Zeromemory (Buffer, MEMBLOCKSIZE / MEMALLOCSIZE);
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FatLfnIsValid
+//
+// Description: Checks for valid long file name
+//
+// Parameters:
+// CHAR16 *Name
+//
+// Return value: BOOLEAN - True if long file name is valid
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+FatLfnIsValid (
+ CHAR16 *Name
+)
+{
+ CHAR16 *p1, *p2;
+ BOOLEAN IsAllDot;
+
+ IsAllDot = TRUE;
+
+ p1 = Name;
+
+ do {
+ if (*p1 != '.') {
+ IsAllDot = FALSE;
+ }
+
+ p1++;
+ } while (*p1);
+
+ if (IsAllDot) {
+ return TRUE;
+ }
+
+ //
+ // Strip off starting/trailing spaces and trailing periods
+ //
+ for (p1 = Name; *p1 && *p1 == ' '; p1++) {
+ ;
+ }
+
+ p2 = Name;
+
+ while (*p1) {
+ *p2 = *p1;
+ p1++;
+ p2++;
+ }
+
+ *p2 = 0;
+
+ for (p1 = Name + Wcslen(Name) - 1;
+ p1 >= Name && (*p1 == ' ' || *p1 == '.');
+ p1--) {
+ ;
+ }
+
+ *(p1 + 1) = 0;
+
+ //
+ // We don't allow zero length name
+ //
+ if (*Name == 0) {
+ return FALSE;
+ }
+
+ //
+ // See if there is any illegal characters within the name
+ //
+ while (*Name) {
+ if ( *Name < 0x20 ||
+ *Name == '\"' ||
+ *Name == '*' ||
+ *Name == '/' ||
+ *Name == ':' ||
+ *Name == '<' ||
+ *Name == '>' ||
+ *Name == '?' ||
+ *Name == '\\' ||
+ *Name == '|' ) {
+ return FALSE;
+ }
+
+ Name++;
+ }
+
+ return TRUE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ExtractShortFileName
+//
+// Description: Extracts short file name from buffer
+//
+// Parameters:
+// VOLUME_INFO *Vi,
+// CHAR16 *lfn,
+// UINT8 *Buffer
+//
+// Return value: EFI_STATUS - Status of the operation
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+ExtractShortFileName (
+ VOLUME_INFO *Vi,
+ CHAR16 *lfn,
+ UINT8 *Buffer
+)
+{
+
+ CHAR16 *p1;
+
+// Copy 8 characters
+ Vi->UnicodeCollationInterface->FatToStr (Vi->UnicodeCollationInterface,
+ 8,
+ Buffer,
+ lfn);
+
+
+// Remove trailing Spaces
+ for (p1 = lfn + 7; p1 >= lfn && (*p1 == ' '); p1--) {
+ ;
+ }
+
+ p1++;
+// P1 Points to the first Space in the 8 character sequence
+ Vi->UnicodeCollationInterface->FatToStr (Vi->UnicodeCollationInterface,
+ 3,
+ Buffer + 8,
+ p1 + 1); // leave space for '.'
+
+ *(p1 + 4) = 0; // if all three characters are valid
+
+ if (*(p1 + 1) != ' ') {
+ *p1 = '.'; // extension is valid
+
+ if (*(p1 + 3) == ' ') *(p1 + 3) = 0;
+
+ if (*(p1 + 2) == ' ') *(p1 + 2) = 0;
+
+ if (*(p1 + 1) == ' ') *(p1 + 1) = 0;
+
+ } else {
+ *p1 = 0; // No extension
+ }
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/Open.c b/Core/EM/FileSystem/Open.c
new file mode 100644
index 0000000..cdfdabf
--- /dev/null
+++ b/Core/EM/FileSystem/Open.c
@@ -0,0 +1,2601 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/Open.c 25 4/30/12 2:02p Pats $
+//
+// $Revision: 25 $
+//
+// $Date: 4/30/12 2:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/Open.c $
+//
+// 25 4/30/12 2:02p Pats
+// [TAG] EIP87352
+// [Category] Bug Fix
+// [Symptom] FAT Direcotry Opean/Creation Issue
+// [RootCause] If a directory open was attempted with EFI_FILE_MODE_CREATE
+// set, check for existing directory was not done.
+// [Solution] Check for existing directory if opened with
+// EFI_FILE_MODE_CREATE set in ProcessOpenFileHandle().
+// [Files] Open.c
+//
+// 24 11/28/11 11:09a Pats
+// [TAG] - EIP 75631
+// [Category] - BUG FIX
+// [Severity] - Major
+// [Symptom] - If an application name includes a path, it won't run.
+// [Root Cause] - In the function ProcessOpenFileHandle(), the driver
+// attempts to replace "\" in the path with a zero, but the code was one
+// off, and the character past the "\" was being replaced.
+// [Solution] - Modified the function ProcessOpenFileHandle() to replace
+// the proper character.
+// [Files] - Open.c
+//
+// 23 10/24/11 10:55a Artems
+// EIP 73254: Remove "magic number" from source
+//
+// 22 5/05/11 3:44p Pats
+// [TAG] - EIP 58999
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - Cannot launch Shell from USB Filesystem device in Debug
+// mode with latest Filesystem driver.
+// [RootCause] - Functions using DISKIO were raising TPL to a fixed level.
+// [Solution] - Modified above functions to check for the higher of the
+// fixed level or current level.
+// [Files] - Info.c, MediaAccess.c, Open.c, FileSystem.h
+//
+// 21 2/05/11 3:20p Artems
+// Bug fix - restore original TPL in all branches of OpenFileHandle
+// function
+//
+// 20 1/13/11 12:24p Pats
+// [TAG] - EIP 51705
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - If the volume label is the same name as a directory or
+// file, the directory or file cannot be accessed. Also, a new directory
+// cannot be created with the same name as the volume.
+// [RootCause] - The functions FindMatchingFH() and FindMatchingDirEntry()
+// did not check for ATTR_VOLUME_ID.
+// [Solution] - Modified above functions to check for ATTR_VOLUME_ID.
+// [Files] - open.c
+//
+// 19 1/06/11 5:53p Oleksiyy
+// [TAG] EIP28607
+// [Category] Improvement
+// [Description] System was hanging for some time if Floppy Media
+// removed while writing in meda in progress.
+// EFI_TPL_CALLBACK priority level rised during media related calls.
+//
+// [Files] DiskIo.c, Info.c, MediaAccess.c, Open.c, Partition.c
+//
+// 18 1/06/11 5:03p Pats
+// [TAG] - EIP 49934
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - The new EDKII shell was not displaying filesystem devices
+// properly.
+// [RootCause] - Root directory file name was "\", with a size of one.
+// Shell expected a null name for the root directory.
+// [Solution] - Changed root directory name to null.
+// [Files] - open.c, function OpenRoot().
+//
+// 17 12/03/10 10:08a Pats
+// EIP 44532: USB key is not returning file list as expected.
+// Problem: ReadFIleHandle was not resetting pointers when a directory
+// read returned an error.
+// Solution. Changed ReadFileHandle to reset pointers on error condition.
+//
+// 16 7/07/10 3:00p Pats
+// EIP 38291: Fails Klocwork test.
+// Problem: No error return if file handle is null in
+// ProcessOpenFileHandle()
+// Solution: Added error return.
+// Problem: Variable vi initialized improperly.
+// Solution: Changed initialization (moved to after possible error exit).
+//
+// 15 6/11/10 5:39p Pats
+// EIP 39171: Long name sometimes not displayed, only short name.
+// FetchLongName() in Open.c did not handle case where long name spilt
+// over 2 clusters. Function modified to handle the case.
+//
+// 14 1/22/10 4:39p Yul
+// Refer to EIP 32983.
+//
+// 13 12/17/09 12:44p Felixp
+// SCT workaround: CloseFileHandle function is updated to validate input
+// parameter before using it (EIP 32474).
+// SCT passes handle of the deleted file.
+//
+// 12 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 11 7/30/08 11:36a Pats
+// Bug fix for file renaming.
+//
+// 10 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 9 8/24/06 9:32a Felixp
+// bug fix in CreateDirEntryInDisk
+//
+// 8 8/16/06 12:03p Markw
+// Fixed UINTN* and UINT32* 64-bit issues.
+//
+// Fixed VC7.1 warning msg.
+//
+// 4 6/21/05 4:00p Pats
+// Modified to call MarkVolumeDirty when EFI_VOLUME_CORRUPTED error
+// occurs. Removed commented-out debug code.
+//
+// 3 6/21/05 9:57a Pats
+// Corrected some spelling to match changes in Info.c.
+//
+// 2 5/27/05 10:02a Srinin
+// Fix for Media change and free space calculation.
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Open.c
+//
+// Description: Handles Opening File Handles.
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "FileSystem.h"
+#define EFI_TPL_CALLBACK TPL_CALLBACK
+//----------------------------------------------------------------------
+
+extern EFI_GUID gEfiFileSystemVolumeLabelGuid;
+extern EFI_GUID gEfiFileInfoGuid;
+extern EFI_GUID gEfiFileSystemInfoGuid;
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OpenVolume
+//
+// Description: Opens a file system Volume.
+//
+// Parameters:
+// IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This - File System Protocol Instance
+// OUT EFI_FILE_PROTOCOL **Root
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+OpenVolume (
+ IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **Root
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE *RootHandle = NULL;
+ FILE_HANDLE_INSTANCE *RootInstance = NULL;
+ VOLUME_INFO *VolumeInfo = (VOLUME_INFO *)This;
+ FAT_TYPE Old_FAT_Type = VolumeInfo->FatType;
+ UINT32 Length;
+
+ if (VolumeInfo->RootFH && (VolumeInfo->VolumeStatus == EFI_MEDIA_CHANGED || VolumeInfo->VolumeStatus == EFI_NO_MEDIA)) {
+ FreeUpResources (VolumeInfo, VolumeInfo->VolumeStatus); // Media changed occurred earlier
+ }
+
+ if (VolumeInfo->RootFH) {
+ if (VolumeInfo->BlkIo->Media->RemovableMedia) {
+ Status = DetectVolume(VolumeInfo, TRUE); // Just reads the sector 0
+
+ if (EFI_ERROR(Status)) {
+ FreeUpResources (VolumeInfo, Status);
+ goto ContinueOpen;
+ }
+ }
+
+ RootHandle = VolumeInfo->RootFH; // Everything is fine
+
+ } else {
+ContinueOpen:
+ VolumeInfo->VolumeStatus = EFI_UNSUPPORTED;
+ VolumeInfo->BlockSize = VolumeInfo->BlkIo->Media->BlockSize;
+ VolumeInfo->ReadOnly = VolumeInfo->BlkIo->Media->ReadOnly;
+ VolumeInfo->MediaID = VolumeInfo->BlkIo->Media->MediaId;
+ Status = DetectVolume(VolumeInfo, FALSE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Old_FAT_Type && Old_FAT_Type != VolumeInfo->FatType) return EFI_UNSUPPORTED;
+
+// Create a FILE_HANDLE for Root Directory. Called for the first time.
+// VolumeInfo->VolumeSize = VolumeInfo->TotalSectors * VolumeInfo->VolumeBPB.BPB_BytePerSec;
+// Only count Data Sectors when determining Volume Size, to match DOS
+ VolumeInfo->VolumeSize = Mul64((UINT64)VolumeInfo->DataSectors, (UINT32)VolumeInfo->VolumeBPB.BPB_BytePerSec);
+ VolumeInfo->FreeSpaceinClusters = (UINTN)-1; // Means not calculated yet
+ VolumeInfo->FreeSpaceinSector1 = (UINTN)-1;
+ Status= OpenRoot(VolumeInfo, &RootHandle);
+ VolumeInfo->LastFreeCluster = (UINTN)-1;
+
+ if (EFI_ERROR(Status)) return Status;
+
+ VolumeInfo->RootFH = RootHandle;
+ DListAdd((DLIST *)(UINTN)&(VolumeInfo->OpenFHs),(DLINK *)(UINTN)&(RootHandle->ViFHLink));
+ }
+
+ if (!VolumeInfo->FileSystemName) {
+ Status = pBS->AllocatePool (EfiBootServicesData, 80, (VOID**)&VolumeInfo->FileSystemName);
+ Wcscpy (VolumeInfo->FileSystemName, L"FAT");
+ Length = (UINT32) Wcslen(VolumeInfo->FileSystemName);
+
+ switch (VolumeInfo->FatType) {
+ case FAT12:
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"12 ");
+ break;
+ case FAT16:
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"16 ");
+ break;
+ case FAT32:
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"32 ");
+ break;
+ default:
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"UnKnown ");
+ };
+
+ Length = (UINT32) Wcslen(VolumeInfo->FileSystemName);
+
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"File System [");
+
+ Length = (UINT32) Wcslen(VolumeInfo->FileSystemName);
+
+ if (VolumeInfo->VolumeSize < 0x100000) { //Less than 1MB
+ ItowEx(Shr64 (VolumeInfo->VolumeSize, 10), VolumeInfo->FileSystemName + Length, 10, FALSE);
+ Length = (UINT32) Wcslen(VolumeInfo->FileSystemName);
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"KB]");
+
+ } else if (VolumeInfo->VolumeSize < 0x40000000) { //Less than 1GB
+ ItowEx(Shr64 (VolumeInfo->VolumeSize, 20), VolumeInfo->FileSystemName + Length, 10, FALSE);
+ Length = (UINT32) Wcslen(VolumeInfo->FileSystemName);
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"MB]");
+
+ } else {
+ ItowEx(Shr64 (VolumeInfo->VolumeSize, 30), VolumeInfo->FileSystemName + Length, 10, FALSE);
+ Length = (UINT32) Wcslen(VolumeInfo->FileSystemName);
+ Wcscpy (VolumeInfo->FileSystemName + Length, L"GB]");
+ }
+ }
+
+
+// Create a FILE_HANDLE_INSTANCE
+ Status = CreateFileHandleInstance(RootHandle, &RootInstance, EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE);
+
+// Return FILE_HANDLE_INSTANCE
+ if (Status == EFI_SUCCESS) *Root = (EFI_FILE_PROTOCOL *)RootInstance;
+
+ VolumeInfo->VolumeStatus = Status;
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OpenRoot
+//
+// Description: Opens the Root Directory on the Volume.
+//
+// Parameters:
+// IN VOLUME_INFO *VolumeInfo - Volume Info Structure
+// IN OUT FILE_HANDLE **Root - Root directory handle
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+OpenRoot(
+ IN VOLUME_INFO *VolumeInfo,
+ IN OUT FILE_HANDLE **Root
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE *RootHandle;
+
+ Status = fsAllocateMemory(VolumeInfo, sizeof(FILE_HANDLE), (VOID**)&RootHandle, TRUE);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ Status = fsAllocateMemory(VolumeInfo, 4, (VOID**)&(RootHandle->FileNameLFN), FALSE);
+
+ RootHandle->FileNameLFN[0]= 0;
+ RootHandle->ROOTDIR = TRUE;
+ RootHandle->VolumeInterface = VolumeInfo;
+ RootHandle->DirectoryEntry.Dir_Attr = EFI_FILE_DIRECTORY;
+ RootHandle->HandleStatus= EFI_SUCCESS;
+
+ if (VolumeInfo->FatType == FAT32) {
+ RootHandle->DirCluster = VolumeInfo->VolumeBPB.BPB_FAT.BPB_FAT32.BPB_RootClus;
+ RootHandle->DirOffset = 0;
+ }
+
+ DListInit((DLIST *)(UINTN)&(RootHandle->DirList));
+ *Root = RootHandle;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CreateFileHandleInstance
+//
+// Description: Creates an instance of a file handle
+//
+// Parameters:
+// IN FILE_HANDLE *fh - Handle of the file to work on
+// IN OUT FILE_HANDLE_INSTANCE **fhi - File handle instance
+// IN UINT64 OpenMode - Open mode (read, write, both)
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateFileHandleInstance (
+ IN FILE_HANDLE *fh,
+ IN OUT FILE_HANDLE_INSTANCE **fhi,
+ IN UINT64 OpenMode
+)
+{
+
+ EFI_STATUS Status;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+ FILE_HANDLE_INSTANCE *nfi;
+
+ Status = fsAllocateMemory(Vi, sizeof(FILE_HANDLE_INSTANCE), (VOID**)&nfi, TRUE);
+
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ nfi->Position = 0;
+ nfi->HandleInstanceStatus = EFI_SUCCESS;
+ nfi->CurrentCluster = FIRSTCLUSTER(fh->DirectoryEntry);
+ nfi->pFH = fh;
+ nfi->OpenMode = OpenMode;
+ InitEFIFileInterface(&(nfi->FileHandle));
+ fh->InstancesCount++;
+ DListAdd((DLIST *)(UINTN)&(Vi->OpenFIs), (DLINK *)(UINTN)&(nfi->ViFILink));
+ *fhi = nfi;
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitEFIFileInterface
+//
+// Description: Initializes the EFI_FILE_PROTOCOL interface
+//
+// Parameters:
+// EFI_FILE_PROTOCOL *EFIFileInterface - Interface structure
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+InitEFIFileInterface (
+ EFI_FILE_PROTOCOL *EFIFileInterface
+)
+{
+
+ EFIFileInterface->Revision = SIMPLE_FILE_SYSTEM_DRIVER_VERSION;
+ EFIFileInterface->Open = OpenFileHandle;
+ EFIFileInterface->Close = CloseFileHandle;
+ EFIFileInterface->Delete = DeleteFileHandle;
+ EFIFileInterface->Read = ReadFileHandle;
+ EFIFileInterface->Write = WriteFileHandle;
+ EFIFileInterface->GetPosition = GetPositionFileHandle;
+ EFIFileInterface->SetPosition = SetPositionFileHandleThis;
+ EFIFileInterface->GetInfo = GetInfoFileHandle;
+ EFIFileInterface->SetInfo = SetInfoFileHandle;
+ EFIFileInterface->Flush = FlushFileHandle;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OpenFileHandle
+//
+// Description: Opens a file handle (when a file is opened)
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This - File System Protocol instance
+// OUT EFI_FILE_PROTOCOL **NewHandle - Handle of open file
+// IN CHAR16 *FileName - Unicode name of file
+// IN UINT64 OpenMode - Open mode (read, write, both)
+// IN UINT64 Attributes - Attributes of open file
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+OpenFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN CHAR16 *FileName,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *Fi= (FILE_HANDLE_INSTANCE *) This;
+ FILE_HANDLE *ParentFh;
+ VOLUME_INFO *Vi;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+#ifdef Debug_OpenFile
+ EfiDebugPrint(-1,"OpenFile: %S OpenMode %lx Attribute %lx\n", FileName, OpenMode, Attributes);
+#endif
+
+// Validate Inputs
+ switch (OpenMode) {
+ case (EFI_FILE_MODE_READ):
+ case (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE):
+ case (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE):
+ break;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+ Status = ValidateCurrentStatus (Fi);
+ if (EFI_ERROR(Status))
+ {
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+ ParentFh = Fi->pFH;
+ Vi = ParentFh->VolumeInterface;
+ if (Vi->ReadOnly && OpenMode & EFI_FILE_MODE_WRITE)
+ {
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_WRITE_PROTECTED;
+ }
+ if (FileName == NULL)
+ {
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_NOT_FOUND;
+ }
+ if ( Attributes & ~EFI_FILE_VALID_ATTR)
+ {
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_NOT_FOUND;
+ }
+ Status = ProcessOpenFileHandle (Fi, &FileName, NewHandle, OpenMode, Attributes);
+ pBS->RestoreTPL(SaveTpl);
+#ifdef Debug_OpenFile
+ EfiDebugPrint(-1,"OpenFile Status: %x\n", Status);
+#endif
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadFileHandle
+//
+// Description: Read from a file (normal file or directory)
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This - File System Protocol instance
+// IN OUT UINTN *BufferSize - Size of read buffer
+// OUT VOID *Buffer - Points to read buffer
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ReadFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+ FILE_HANDLE *Pfh;
+ FILE_HANDLE *fh1;
+ DIR_ENTRY_LIST *Del;
+ UINT32 Position;
+ FILE_HANDLE_INSTANCE TempFhi;
+ FILE_HANDLE TempPfh;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+
+ if (*BufferSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+
+ TempFhi = *fhi;
+ Status = ValidateCurrentStatus (fhi);
+ if (EFI_ERROR(Status)) return Status;
+ Pfh = fhi->pFH;
+ TempPfh = *Pfh;
+#ifdef Debug_ReadFile
+ EfiDebugPrint(TRACE_ALWAYS,"ReadFile: %S Position %lx Length %x \n", Pfh->FileNameLFN, fhi->Position, *BufferSize);
+#endif
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+
+// Check if this Instance is a Directory.
+ if (Pfh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY) {
+
+// Check if Dir List has been changed. If so, release the list and read it again.
+ if (Pfh->DirListChanged == TRUE) {
+ RemoveAllDirList (Pfh);
+ Pfh->DirListChanged = FALSE;
+ }
+
+// Check if the file Handle has a valid DIR_ENTRY_LIST
+ if (!Pfh->DirList.pHead) {
+ Status = ReadAllDirectoryEntries (Pfh);
+
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+ }
+
+// If Dir_List has been changed, this should take care of it.
+ if (fhi->Position != 0) {
+ Status = LocateDel (Pfh->DirList.pHead, fhi->CurrentCluster, fhi->CurrentClusterOffset, &Del, &Position);
+ fhi->Position = Position;
+ }
+
+
+ for (;; fhi->Position++) {
+ Status = GetDirListAtPosition (Pfh, fhi->Position, &Del);
+
+ if (!Del) {
+ *BufferSize = 0; // End of entries
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_SUCCESS;
+ }
+
+// Check whether it is a Label
+ if ((Del->DirectoryEntry.Dir_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) != ATTR_VOLUME_ID)
+ break;
+ }
+
+///////////////////////////////////////////////
+//A long Process. Do we need to reduce it
+ Status = CreateFHFromDirEntryList(Del, Pfh, &fh1);
+
+ if (EFI_ERROR(Status)){
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ Status = GetFileInfoFromFH (fh1, BufferSize, Buffer);
+
+ if (EFI_ERROR(Status)) {
+ *fhi = TempFhi;
+ *Pfh = TempPfh;
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+//A long Process. Do we need to reduce it
+///////////////////////////////////////////////
+
+ fhi->Position++;
+
+// Make sure CurrentCluster and CurrentClusterOffset gets updated to the new position
+ for (;; fhi->Position++) {
+ Status = GetDirListAtPosition (Pfh, fhi->Position, &Del);
+
+ if (!Del) break;
+
+// Check whether it is a Label
+ if ((Del->DirectoryEntry.Dir_Attr & (ATTR_DIRECTORY | ATTR_VOLUME_ID)) != ATTR_VOLUME_ID)
+ break;
+ }
+
+// Update the CurrentCluster, CurrentClusterOffset for the new position
+ if (Del) {
+ fhi->CurrentCluster = Del->Cluster;
+ fhi->CurrentClusterOffset = Del->Offset;
+
+ } else {
+ fhi->CurrentCluster = (UINTN) -1;
+ fhi->CurrentClusterOffset = (UINTN)-1;
+ Status = EFI_SUCCESS;
+ }
+
+ RemoveFH(fh1);
+
+ } else {
+// It is File.
+ //Buffer size is on input is required to be less than 4G.
+ Status = ReadFromFile (fhi, Buffer, (UINT32*)BufferSize, DATA_REGION);
+ }
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteFileHandle
+//
+// Description: Writes to a file
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This,
+// IN OUT UINTN *BufferSize,
+// IN VOID *Buffer
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+WriteFileHandle (
+ IN EFI_FILE_PROTOCOL *This,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer
+)
+{
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+
+#ifdef Debug_WriteFile
+ FILE_HANDLE *Pfh;
+ VOLUME_INFO *vi;
+#endif
+
+ if (*BufferSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+
+ Status = ValidateCurrentStatus (fhi);
+ if (EFI_ERROR(Status)) return Status;
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+#ifdef Debug_WriteFile
+ Pfh = fhi->pFH;
+ vi = Pfh->VolumeInterface;
+ EfiDebugPrint(TRACE_ALWAYS,"WriteFile: %S FSize %x Pos %lx Len %x LoCluster %x\n",
+ Pfh->FileNameLFN, Pfh->DirectoryEntry.Dir_FileSize, fhi->Position, *BufferSize, Pfh->DirectoryEntry.Dir_FstClusLO);
+#endif
+
+ Status = CheckFileWrite (fhi, FALSE);
+ if (EFI_ERROR(Status)){
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ //Buffer size is on input is required to be less than 4G.
+ Status = WriteToFile (fhi, Buffer, (UINT32*)BufferSize, DATA_REGION);
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetInfoFileHandle
+//
+// Description: Sets file info
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This,
+// IN EFI_GUID *InformationType,
+// IN UINTN BufferSize,
+// IN VOID *Buffer
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetInfoFileHandle(
+ IN EFI_FILE_PROTOCOL *This,
+ IN EFI_GUID *InformationType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+)
+{
+
+
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+ FILE_HANDLE *Pfh;
+ VOLUME_INFO *vi;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+
+ Status = ValidateCurrentStatus (fhi);
+ if (EFI_ERROR(Status)) return Status;
+ Pfh = fhi->pFH;
+ vi = Pfh->VolumeInterface;
+ if (vi->ReadOnly) return EFI_WRITE_PROTECTED;
+
+// Compare the GUID
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+ if (!guidcmp(InformationType, &gEfiFileInfoGuid)) {
+ Status = SetfileInfo (This, fhi, BufferSize, Buffer);
+
+ if (EFI_ERROR(Status)){
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+ }
+
+ else {
+ if (!guidcmp(InformationType, &gEfiFileSystemInfoGuid)) {
+ Status = SetSystemInfo (vi, BufferSize, (EFI_FILE_SYSTEM_INFO *)Buffer);
+
+ if (EFI_ERROR(Status)){
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ Status = FlushFileHandle(This);
+
+ if (EFI_ERROR(Status)){
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ } else {
+ if (!guidcmp(InformationType, &gEfiFileSystemVolumeLabelGuid)) {
+ Status = SetVolumeLabel (vi, BufferSize, Buffer);
+
+ if (EFI_ERROR(Status)){
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ Status = FlushFileHandle(This);
+
+ if (EFI_ERROR(Status)) {
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ } else {
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_UNSUPPORTED;
+ }
+ }
+ }
+
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DeleteFileHandle
+//
+// Description: Deletes a file
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This - File Protocol instance
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: For FAT32, Cluster(s) occupied by root directory will not be released
+// as Del/rm command will not give a call to delete RootHandle.
+// In a empty FAt32 disk, free space will be less by clusters occupied by ROOT Directory
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DeleteFileHandle (
+ IN EFI_FILE_PROTOCOL *This
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This, *fhi1;
+ FILE_HANDLE *fh;
+ FILE_HANDLE *PPfh;
+ VOLUME_INFO *vi;
+ UINT32 ClusterCount;
+// UINT32 Sector, SectorOffset, ClusterCount;
+ UINT8 DirErase = DIR_ENTRY_ERASE;
+ DLINK *dlink;
+ DIR_ENTRY_LIST *Del;
+ UINT32 Position;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+
+ Status = ValidateCurrentStatus (fhi);
+ if (EFI_ERROR(Status)) return Status;
+
+ fh = fhi->pFH;
+ vi = fh->VolumeInterface;
+ PPfh = fh->Parent;
+ dlink = PPfh->DirList.pHead ;
+
+#ifdef Debug_DeleteFile
+ EfiDebugPrint(TRACE_ALWAYS,"Del File: %S Dir Cluster %x Dir Offset %x\n", fh->FileNameLFN, fh->DirCluster, fh->DirOffset);
+#endif
+
+
+ if ( vi->ReadOnly || fh->ROOTDIR
+ || fh->DirectoryEntry.Dir_Attr & ATTR_READ_ONLY
+ || !(fhi->OpenMode & EFI_FILE_MODE_WRITE)){
+
+ CloseFileHandle (This);
+
+#ifdef Debug_DeleteFile
+ EfiDebugPrint(-1,"DEL WARN FAILURE Instances Open %x\n", fh->InstancesCount);
+#endif
+ return EFI_WARN_DELETE_FAILURE;
+ }
+
+ if (fh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY) {
+ if (fh->DirList.Size > 2) {
+ CloseFileHandle (This);
+#ifdef Debug_DeleteFile
+ EfiDebugPrint(-1,"DEL WARN FAILURE Dir Not Empty\n");
+#endif
+ return EFI_WARN_DELETE_FAILURE;
+ }
+
+//###DEBUG
+// TODO TODO TODO
+// Before removing the Directory Entry, check if it is empty.
+// TODO TODO TODO
+//##DEBUG END
+// Release all Dir_List
+ RemoveAllDirList(fh);
+ }
+
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+
+ if (fh->DirCluster || fh->DirOffset) {
+ fh->DirectoryEntry.Dir_Name[0] = DirErase;
+ fh->DirEntryChanged = TRUE;
+// Update the FAT Chain
+ UnlinkFat(vi, FIRSTCLUSTER(fh->DirectoryEntry), &ClusterCount);
+ }
+
+// Check if DIR_LIST is valid. If yes, remove from the list.
+ Status = LocateDel (fh->Parent->DirList.pHead, fh->DirCluster, fh->DirOffset, &Del, &Position);
+
+ if (!EFI_ERROR(Status)) RemoveDirList(PPfh, Del);
+
+// Force next Scan for the parent directory to begin from the beginning
+ fh->Parent->FreeDirEntryCluster = 0;
+ fh->Parent->FreeDirEntryOffset = 0;
+
+// Remove File Handle and File List
+ CloseFileHandle (This);
+
+// Check for multiple instances
+ if (fh->InstancesCount ) {
+ dlink = vi->OpenFIs.pHead;
+
+ for ( ; dlink; ) {
+ fhi1 = OUTTER(dlink, ViFILink, FILE_HANDLE_INSTANCE);
+
+ if (fhi1->pFH == fh) {
+ fhi1->HandleInstanceStatus = EFI_NOT_FOUND;
+ fhi1->pFH = NULL;
+ fh->InstancesCount--;
+ }
+
+ dlink = dlink->pNext;
+ }
+ }
+
+ Status = RemoveFH(fh);
+ pBS->RestoreTPL(SaveTpl);
+#ifdef Debug_DeleteFile
+ EfiDebugPrint(-1,"Del File Success\n");
+#endif
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FlushFileHandle
+//
+// Description: Flushes a file (writes any portion left in cache)
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This - File Protocol instance
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FlushFileHandle (
+ IN EFI_FILE_PROTOCOL *This
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+ FILE_HANDLE *Pfh;
+ VOLUME_INFO *vi;
+ DLINK *dlink;
+ CACHE_HEADER *ch;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+
+ Status = ValidateCurrentStatus (fhi);
+ if (EFI_ERROR(Status)) return Status;
+
+ Pfh =fhi->pFH;
+ vi = Pfh->VolumeInterface;
+ dlink = vi->CacheList.pHead;
+ if (fhi->OpenMode == EFI_FILE_MODE_READ) return EFI_ACCESS_DENIED;
+
+ if (vi->ReadOnly) return EFI_ACCESS_DENIED;
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+ for ( ; dlink; ) {
+
+ ch = OUTTER(dlink, CacheLink, CACHE_HEADER);
+
+ if (ch->DIRTY_FLAG) {
+ Status= vi->DiskIo->WriteDisk (vi->DiskIo, vi->MediaID, ch->AbsoluteOffset, (UINT32) (ch->AbsoluteOffsetEnd - ch->AbsoluteOffset), ch->Buffer);
+
+ if (EFI_ERROR(Status)) {
+ HandleDiskIoError(vi, Status);
+ pBS->RestoreTPL(SaveTpl);
+ return Status;
+ }
+
+ ch->DIRTY_FLAG = FALSE;
+ }
+
+ dlink = dlink->pNext;
+
+ }
+ pBS->RestoreTPL(SaveTpl);
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessOpenFileHandle
+//
+// Description: Performs whatever is needed to process an open handle
+// (create dir. entry, create instance, allocate clusters)
+//
+// Parameters:
+// IN FILE_HANDLE_INSTANCE *ParentFi - Parent file handle instance
+// IN CHAR16 **FileName - Unicode file name
+// OUT EFI_FILE_PROTOCOL **NewHandle - New file handle
+// IN UINT64 OpenMode - Open mode (read, write, both)
+// IN UINT64 Attributes - File attributes
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ProcessOpenFileHandle(
+ IN FILE_HANDLE_INSTANCE *Fi,
+ IN CHAR16 **FileName,
+ OUT EFI_FILE_PROTOCOL **NewHandle,
+ IN UINT64 OpenMode,
+ IN UINT64 Attributes
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE *fh = Fi->pFH, *fh1;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+ CHAR16 *Next;
+ UINT32 Length;
+ CHAR16 NextCompName[MAX_TOTAL_PATH_LENGTH];
+ FILE_HANDLE_INSTANCE *fhi;
+ DIR_ENTRY_LIST *Del;
+ CHAR16 CurrentDir[] = {'.', 0};
+ CHAR16 ParentDir[] = {'.', '.', 0};
+ UINT8 *Buffer;
+ BOOLEAN DirFound = FALSE;
+
+ if (EFI_ERROR(fh->HandleStatus)) return fh->HandleStatus;
+
+ Next = *FileName;
+
+ if ((*FileName)[0] == '\\') {
+ fh = Vi->RootFH;
+ (*FileName) += 1;
+ }
+
+// Check for '\\' at the end of the FileName. If so remove it. Eg: \windows\system
+ Length = (UINT32) Wcslen(*FileName);
+
+ if (Length > 2 && (*FileName)[Length-1] == '\\') (*FileName)[Length-1] = 0;
+
+ Status = EFI_SUCCESS;
+
+ while (! EFI_ERROR(Status)) {
+
+ if ( EFI_ERROR(GetNextCompName (FileName, NextCompName))) return EFI_NOT_FOUND;
+
+ if (NextCompName[0] == 0) break;
+
+ if (!FatLfnIsValid (NextCompName)) return EFI_NOT_FOUND;
+
+ if (!Wcscmp(NextCompName, CurrentDir)) continue;
+
+ if (!Wcscmp(NextCompName, ParentDir)) {
+ if (fh == Vi->RootFH) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ fh = fh->Parent;
+
+ if (!fh) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ continue;
+ }
+
+// A component name is present. Parent should be directory. Else return error
+ if (!(fh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY)) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+// Check whether a match can be found for nextcompname
+ if (FindMatchingFH(Vi, NextCompName, fh, &fh1)) {
+ fh = fh1;
+ Status = EFI_SUCCESS;
+ continue;
+ }
+
+// See if the Linked List is Valid
+ if (!fh->DirList.pHead) {
+ ReadAllDirectoryEntries (fh);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+ DirFound = FALSE;
+ if (FindMatchingDirEntry (fh, NextCompName, &Del)) {
+ DirFound = TRUE; // Flag existing directory found
+ Status = CreateFHFromDirEntryList(Del, fh, &fh1);
+
+ // Add to the List in Volume Interface
+ if (Status == EFI_SUCCESS) {
+ fh = fh1;
+ }
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+
+// Make sure NextCompName is the last compname.
+ if ((*FileName[0]) != 0) return EFI_NOT_FOUND;
+
+// If it is a file that needs to be openend, and not found create one. For directories return error.
+ if (OpenMode & EFI_FILE_MODE_CREATE) {
+
+ if (!fh) return EFI_NOT_FOUND;
+
+ if (!(fh->DirectoryEntry.Dir_Attr & ATTR_DIRECTORY)) {
+ // if this is not a directory then the input is just a filename. So get the parent handle of this instance
+ fh = fh->Parent;
+ }
+
+// Create a file entry in the parent directory
+ Status = CreateDirectoryEntry (fh, NextCompName, &fh1, Attributes);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ fh = fh1;
+
+ } else return EFI_NOT_FOUND;
+ }
+
+// Create an instance
+ Status = CreateFileHandleInstance (fh, &fhi, OpenMode);
+ *NewHandle = (EFI_FILE_PROTOCOL *) fhi;
+
+// If asked to create a directory, and it already exists, the UEFI spec says to
+// just open and return EFI_SUCCESS.
+ if (DirFound && (OpenMode & EFI_FILE_MODE_CREATE)) {
+ return EFI_SUCCESS;
+ }
+
+ if ((fhi->pFH->DirectoryEntry.Dir_Attr == ATTR_DIRECTORY) &&
+ (OpenMode & EFI_FILE_MODE_CREATE)) { // If creating a new directory, create dot and dotdot entries
+
+// Allocate Cluster for the sub Directory that was created before.
+// The new allocated cluster should be cleared.
+// fsAllocateMemory (Vi, Vi->BytesPerCluster, (void **)&Buffer, TRUE);
+ GetTempBuffer (Vi, &Buffer);
+ Zeromemory (Buffer, Vi->BytesPerCluster);
+ Length = Vi->BytesPerCluster;
+ Status = WriteToFile (fhi, Buffer, &Length, DIRECTORY_REGION);
+
+ if (EFI_ERROR(Status)) return Status;
+
+// fsDeAllocateMemory(Vi, Buffer);
+ ReleaseTempBuffer(Vi);
+
+ fhi->Position = 0;
+ fhi->pFH->DirectoryEntry.Dir_FileSize = 0;
+
+ if (fhi->pFH->DirEntryChanged == TRUE) UpdateDirListFromFHDir(fhi->pFH);
+
+ fhi->pFH->DirEntryChanged = FALSE;
+ fhi->pFH->FreeDirEntryCluster = FIRSTCLUSTER(fh->DirectoryEntry);
+ fhi->pFH->FreeDirEntryOffset = 0;
+
+// Create '.' entry
+ Status = CreateDirectoryEntry(fh, CurrentDir, &fh1, ATTR_DIRECTORY);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ RemoveFH(fh1);
+
+// Create'..' entry
+ Status = CreateDirectoryEntry(fh, ParentDir, &fh1, ATTR_DIRECTORY);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ RemoveFH(fh1);
+
+ }
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadAllDirectoryEntries
+//
+// Description: Reads entries in a directory
+//
+// Parameters:
+// IN FILE_HANDLE *fh - File handle structure
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadFileHandle, ProcessOpenFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ReadAllDirectoryEntries (
+ IN FILE_HANDLE *fh
+)
+{
+
+ EFI_STATUS Status;
+ CHAR16 lfn[256], *lfnBuffer;
+ UINT32 Offset, SlotNumber = 0, BufferSize, OrgBufferSize, Slots;
+ UINT32 BytesReadPerLoop;
+ UINT8 *Buffer;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+ UINT32 ClusterNumber, Cluster;
+
+ if (Vi->TotalDirEntryList > DIRECTORTY_ENTRIES_CACHED) FreeUpDirEntries (Vi, NULL);
+
+// Allocate space for a temp buffer.
+ BytesReadPerLoop = Vi->BytesPerCluster;
+
+ if (fh->ROOTDIR && (Vi->FatType != FAT32))
+ BytesReadPerLoop = Vi->RootDirSectorCount << Vi->BytesPerSecPowerof2;
+
+ GetTempBuffer (Vi, &Buffer);
+
+ for (ClusterNumber = 0; ; ClusterNumber++, Cluster = 0) {
+
+ Status = ReadClusterOfDirectoryEntries(fh, ClusterNumber, &Cluster, Buffer, &BytesReadPerLoop);
+
+ if (Status == EFI_SUCCESS && BytesReadPerLoop == 0) {
+ break; // Empty Directory or End of Directory reached
+ }
+
+ if (EFI_ERROR(Status)) break;
+
+ OrgBufferSize = BytesReadPerLoop;
+ BufferSize = BytesReadPerLoop;
+ Offset = 0;
+
+ for ( ; BufferSize; Offset += sizeof (DIR_ENTRY_32), BufferSize = OrgBufferSize - Offset) {
+
+ if (!(FindShortName (Buffer, &Offset, BufferSize))) break;
+
+// Find a matching LFN
+ Slots = FetchLongName(fh, (DIR_ENTRY_32 *)(Buffer), Offset, lfn, ClusterNumber, BytesReadPerLoop);
+
+ if (Slots == 0) ExtractShortFileName (Vi, lfn, Buffer + Offset);
+
+ Status = fsAllocateMemory (Vi, (UINT32)((Wcslen(lfn) * sizeof (CHAR16))+ 2), (VOID**)&lfnBuffer, FALSE);
+ pBS->CopyMem (lfnBuffer, lfn, (Wcslen(lfn) * sizeof (CHAR16))+ 2);
+
+// Create a Dir Entry List and add it to the Parent File Handle
+// Valid Entry has been found. *lfn, DirectoryEntry, Offset
+ AddToDirList (fh, *(DIR_ENTRY_32 *)(Buffer + Offset), lfnBuffer, Cluster, Offset, SlotNumber);
+ SlotNumber++;
+ }
+
+ if (Offset == -1) break; // No more directory Entries.
+
+ if (fh->ROOTDIR && (Vi->FatType != FAT32)) break; // Only one loop.
+ }
+
+ ReleaseTempBuffer (Vi);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadClusterOfDirectoryEntries
+//
+// Description: Reads one cluster of directory entries
+//
+// Parameters:
+// IN FILE_HANDLE *fh,
+// IN UINT32 ClusterNumber -- 0-based number of which cluster to read
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadAllDirectoryEntries
+//
+// Notes: For end of cluster, BufferSize = 0 and EFI_SUCCESS returned.
+// For FAT12/16, All the Root Directories are read in one shot.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ReadClusterOfDirectoryEntries (
+ IN FILE_HANDLE *fh,
+ IN UINT32 ClusterNumber,
+ OUT UINT32 *ClusterRead,
+ UINT8 *Buffer,
+ UINT32 *BufferSize
+)
+{
+ EFI_STATUS Status;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+ UINT32 Cluster;
+ UINT32 Sector;
+ UINT32 i;
+
+// Find the starting sector of the cluster to read.
+ Cluster = FIRSTCLUSTER(fh->DirectoryEntry);
+
+ if (fh->ROOTDIR && (Vi->FatType != FAT32)) {
+// Offset = ClusterNumber * (UINT32)Vi->VolumeBPB.BPB_SecPerClus;
+// if(Offset >= Vi->RootDirSectorCount) return EFI_NOT_FOUND; // Requested cluster is beyond directory
+ if (ClusterNumber) {
+ *BufferSize = 0;
+ return EFI_SUCCESS; // For FAT12/16 root dir, Clusternumber should be always zero.
+ }
+
+ Sector = Vi->VolumeBPB.BPB_RsvdSecCnt + Vi->FATSz * Vi->VolumeBPB.BPB_NumFATs;
+ *ClusterRead = Sector;
+
+ } else {
+ if (Vi->FatType == FAT32 && fh->ROOTDIR) Cluster = Vi->VolumeBPB.BPB_FAT.BPB_FAT32.BPB_RootClus;
+
+ if (ClusterNumber != 0) {
+ for (i=0; i<ClusterNumber ; i++) { // Follow the fat chain to find the desired cluster
+ Status = ReadFatClusterNumber(Vi, Cluster, 0, &Cluster);
+
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ if (Cluster < 2) {
+ MarkVolumeDirty (Vi);
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ if (Cluster >= Vi->EOCMark) {
+ *BufferSize = 0; // End of Directory reached.
+ return EFI_SUCCESS; // Requested cluster is beyond directory end
+ }
+ }
+ }
+
+// Convert this cluster to a sector.
+ Sector = ClusterToSector(Vi, Cluster);
+ *ClusterRead = Cluster;
+ }
+
+// Read one cluster of the directory into the temp buffer.
+ Status = FsReadMedia (Vi,
+ Buffer,
+ (UINT64)Sector,
+ 0,
+ *BufferSize,
+ DIRECTORY_REGION);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AddToDirList
+//
+// Description: Adds a directory entry to DirList
+//
+// Parameters:
+// IN FILE_HANDLE *fh - File Handle
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadAllDirectoryEntries
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AddToDirList (
+ FILE_HANDLE *fh,
+ DIR_ENTRY_32 DirectoryEntry,
+ CHAR16 *lfn,
+ UINT32 Cluster,
+ UINT32 Offset,
+ UINT32 SlotNumber
+
+)
+{
+ DIR_ENTRY_LIST *Del;
+ EFI_STATUS Status;
+
+ Status = fsAllocateMemory(fh->VolumeInterface, sizeof(DIR_ENTRY_LIST), (VOID**)&Del, FALSE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->CopyMem (&(Del->DirectoryEntry), &DirectoryEntry, sizeof(DIR_ENTRY_32));
+ Del->FileNameLFN = lfn;
+ Del->Cluster = Cluster;
+ Del->Offset= Offset;
+ Del->SlotNumber= SlotNumber;
+ DListAdd((DLIST *)(UINTN)&(fh->DirList), (DLINK *)(UINTN)&(Del->DirLink));
+ fh->VolumeInterface->TotalDirEntryList++;
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CreateFHFromDirEntryList
+//
+// Description: Creates a file handle from directory entry list
+//
+// Parameters:
+// IN DIR_ENTRY_LIST *Del - Directory entry list
+// IN FILE_HANDLE *fh - Directory file handle
+// OUT FILE_HANDLE **fh1 - New file handle
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadFileHandle, ProcessOpenFileHandle
+//
+// Notes: Should not link the FH to any LIST
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateFHFromDirEntryList(
+ IN DIR_ENTRY_LIST *Del,
+ IN FILE_HANDLE *fh,
+ OUT FILE_HANDLE **fh1
+)
+{
+
+ FILE_HANDLE *nfh;
+ EFI_STATUS Status;
+
+ Status = fsAllocateMemory(fh->VolumeInterface, sizeof(FILE_HANDLE), (VOID**)&nfh, TRUE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = fsAllocateMemory(fh->VolumeInterface, (UINT32)((Wcslen(Del->FileNameLFN) * sizeof(CHAR16)) + 2), (VOID**)&(nfh->FileNameLFN), FALSE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+// Initialize FILE_HANDLE_STRUCTURE
+ nfh->VolumeInterface = fh->VolumeInterface;
+ nfh->HandleStatus = EFI_SUCCESS;
+ nfh->ROOTDIR = FALSE;
+ pBS->CopyMem (&(nfh->DirectoryEntry), &(Del->DirectoryEntry), sizeof(DIR_ENTRY_32));
+ Wcscpy(nfh->FileNameLFN, Del->FileNameLFN);
+ nfh->DirCluster = Del->Cluster;
+ nfh->DirOffset = Del->Offset;
+ nfh->SlotNumber = Del->SlotNumber;
+ nfh->Parent = fh;
+ *fh1 = nfh;
+
+// Add the new FH to the parent's Child List
+ DListAdd((DLIST *)(UINTN)&(fh->ChildList), (DLINK *)(UINTN)&(nfh->ChildLink));
+
+// Add to VolumeInterface List
+ DListAdd((DLIST *)(UINTN)&(fh->VolumeInterface->OpenFHs), (DLINK *)(UINTN)&(nfh->ViFHLink));
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindMatchingFH
+//
+// Description: Finds the Child FH, whose name matches with the input.
+// In the Attributes, check whther both are file or Directory
+//
+// Parameters:
+// IN VOLUME_INFO *Vi - Volume info structure
+// IN CHAR16 *NextCompName - Unicode name to compare
+// IN FILE_HANDLE *fh - Parent file handle
+// OUT FILE_HANDLE **fh1 - Child file handle
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ProcessOpenFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+FindMatchingFH (
+ IN VOLUME_INFO *Vi,
+ IN CHAR16 *NextCompName,
+ IN FILE_HANDLE *fh,
+ OUT FILE_HANDLE **fh1
+)
+{
+
+
+ DLINK *fhlink = fh->ChildList.pHead;
+ FILE_HANDLE *fh2;
+
+ for ( ; fhlink; ) {
+ fh2 = OUTTER(fhlink, ChildLink, FILE_HANDLE);
+
+ if (!Wcscmpcaseinsensitive (fh2->FileNameLFN, NextCompName)) {
+ if (!(fh2->DirectoryEntry.Dir_Attr & ATTR_VOLUME_ID)) {
+ if (fh2->HandleStatus == EFI_SUCCESS) {
+ *fh1 = fh2;
+ return TRUE;
+ }
+ }
+ }
+
+ fhlink = fhlink->pNext;
+ }
+
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindMatchingDirEntry
+//
+// Description: Finds a directory entry matching the input name
+//
+// Parameters:
+// IN FILE_HANDLE *fh - Directory file handle
+// IN CHAR16 *NextCompName - Unicode name to match
+// OUT DIR_ENTRY_LIST **Del - Directory list where found
+//
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ProcessOpenFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+FindMatchingDirEntry (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *NextCompName,
+ OUT DIR_ENTRY_LIST **Del
+)
+{
+
+ DLINK *dlink = fh->DirList.pHead;
+ DIR_ENTRY_LIST *del;
+
+ for ( ; dlink; ) {
+ del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+
+ if (!Wcscmpcaseinsensitive (del->FileNameLFN, NextCompName)) {
+ if (!(del->DirectoryEntry.Dir_Attr & ATTR_VOLUME_ID)) {
+ *Del = del;
+ return TRUE;
+ }
+ }
+
+ dlink = dlink->pNext;
+ }
+
+ return FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindMatchingSFNDirEntry
+//
+// Description: Finds short file name directory entry matching input
+//
+// Parameters:
+// IN FILE_HANDLE *fh - Directory file handle
+// IN CHAR8 *ShortFileName - Name to find
+// OUT DIR_ENTRY_LIST **Del - Directory list where found
+//
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+FindMatchingSFNDirEntry (
+ IN FILE_HANDLE *fh,
+ IN CHAR8 *ShortFileName,
+ OUT DIR_ENTRY_LIST **Del
+)
+{
+
+ DLINK *dlink = fh->DirList.pHead;
+ DIR_ENTRY_LIST *del;
+ UINT8 Attrb;
+
+ for ( ; dlink; ) {
+ del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+ Attrb = del->DirectoryEntry.Dir_Attr;
+ del->DirectoryEntry.Dir_Attr = 0; // Generate a NULL terminated string
+
+ if (!Strcmp((CHAR8 *)&del->DirectoryEntry, ShortFileName)) {
+ del->DirectoryEntry.Dir_Attr = Attrb; // restore Attribute
+ *Del = del;
+ return TRUE;
+ }
+
+ del->DirectoryEntry.Dir_Attr = Attrb; // restore Attribute
+ dlink = dlink->pNext;
+ }
+
+ return FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Wcscmpcaseinsensitive
+//
+// Description: Case insensitive unicode string compare
+//
+// Parameters:
+// CHAR16 *string1 - First string
+// CHAR16 *string2 - Second string
+//
+// Return Value:
+// INT - Difference where mis-matched
+//
+// Modified:
+//
+// Referrals: FindMatchingFH, FindMatchingDirEntry
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int Wcscmpcaseinsensitive(
+ CHAR16 *string1,
+ CHAR16 *string2
+)
+{
+
+ CHAR16 ch1, ch2;
+
+ while (*string1) {
+ if (*string1 >=0x61 && *string1<=0x7a) ch1 = *string1 - 0x20;
+
+ else ch1 = *string1;
+
+ if (*string2 >=0x61 && *string2<=0x7a) ch2 = *string2 - 0x20;
+
+ else ch2 = *string2;
+
+ if (ch1 != ch2) break;
+
+ *string1++;
+ *string2++;
+ }
+
+ return *string1 - *string2; // Don't use ch1 - ch2
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetDirListAtPosition
+//
+// Description: Get directory list at current position in directory file
+//
+// Parameters:
+// FILE_HANDLE *Pfh - Parent file handle
+// UINT64 Position - Current position
+// DIR_ENTRY_LIST **Del - Directory entry list
+//
+// Return Value:
+//
+// Modified:
+//
+// Referrals: ReadFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetDirListAtPosition(
+ FILE_HANDLE *Pfh,
+ UINT64 Position,
+ DIR_ENTRY_LIST **Del
+)
+{
+
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ DLINK *dlink = Pfh->DirList.pHead;
+
+ *Del = NULL;
+
+ if (!dlink) return Status;
+
+ while (Position && dlink) {
+ if (!dlink->pNext) break;
+
+ dlink = dlink->pNext;
+ Position--;
+ };
+
+ if (Position == 0 && dlink) {
+ Status = EFI_SUCCESS;
+ *Del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CloseFileHandle
+//
+// Description: Closes an open file
+//
+// Parameters:
+// IN EFI_FILE_PROTOCOL *This - File Protocol instance
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: DeleteFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CloseFileHandle (
+ IN EFI_FILE_PROTOCOL *This
+)
+{
+
+ EFI_STATUS Status;
+ FILE_HANDLE_INSTANCE *fhi = (FILE_HANDLE_INSTANCE *)This;
+ FILE_HANDLE *Pfh = fhi->pFH;
+ VOLUME_INFO *vi;
+ void *Buffer;
+ UINT32 BufferSize, Difference;
+ EFI_TPL SaveTpl;
+ EFI_TPL NextTpl;
+
+ Status = ValidateCurrentStatus (fhi);
+ if (EFI_ERROR(Status)) return Status;
+
+#ifdef Debug_CloseFileHandle
+ EfiDebugPrint(-1,"CloseFileHandle: %S Dir Cluster %x Dir Offset %x\n", Pfh->FileNameLFN, Pfh->DirCluster, Pfh->DirOffset);
+#endif
+
+// Device Removal or Media Not Present
+ if (!Pfh) {
+ Status = pBS->FreePool(fhi);
+ return EFI_SUCCESS;
+ }
+ NextTpl = FindNextTpl (EFI_TPL_CALLBACK);
+ SaveTpl = pBS->RaiseTPL (NextTpl);
+ vi = Pfh->VolumeInterface;
+
+// Check if FreeSpace and Last Free Cluster needs to be updated for FAT32
+ if (vi->FatType == FAT32 && vi->FreeSpaceinClusters != -1) {
+ Difference = vi->FreeSpaceinSector1 - vi->FreeSpaceinClusters;
+
+ if (vi->FreeSpaceinSector1 < vi->FreeSpaceinClusters) Difference = vi->FreeSpaceinClusters - vi->FreeSpaceinSector1;
+
+ if (Difference > 0x100) {
+// ReadFSInfo
+ BufferSize = vi->VolumeBPB.BPB_BytePerSec;
+ GetTempBuffer (vi, &Buffer);
+
+ Status = FsReadMedia (vi, Buffer, (UINT64)vi->VolumeBPB.BPB_FAT.BPB_FAT32.BPB_FSInfo, FSI_Free_Count, 8, FAT_REGION);
+
+ if (EFI_ERROR(Status)) goto Memallocate_error;
+
+ *(UINT32 *) ((UINT8 *)Buffer) = vi->FreeSpaceinClusters;
+ *(UINT32 *) ((UINT8 *)Buffer + 4) = vi->LastFreeCluster;
+ Status = FsWriteMedia (vi, Buffer, (UINT64)vi->VolumeBPB.BPB_FAT.BPB_FAT32.BPB_FSInfo, FSI_Free_Count, 8, FAT_REGION);
+ vi->FreeSpaceinSector1 = vi->FreeSpaceinClusters;
+ ReleaseTempBuffer(vi);
+ }
+ }
+
+Memallocate_error:
+
+ if (Pfh->DirEntryChanged == TRUE) {
+ UpdateDirListFromFHDir(Pfh);
+ Pfh->DirEntryChanged = FALSE;
+ }
+
+ DListDelete ((DLIST *)(UINTN)&(vi->OpenFIs), (DLINK *)(UINTN)&(fhi->ViFILink));
+ fsDeAllocateMemory (vi, fhi);
+
+ if (vi->TotalDirEntryList > DIRECTORTY_ENTRIES_CACHED) {
+ if (vi->OpenFHs.Size > MAX_OPEN_FHS) FreeUpFHEntries (vi, NULL);
+
+ FreeUpDirEntries (vi, Pfh->Parent);
+ }
+
+// This should be always after FreeUpDirEntries. When called from
+// DeleteFileHandle will have problem otherwise.
+ if (Pfh) Pfh->InstancesCount -= 1;
+
+ FlushFileHandle(This);
+
+ pBS->RestoreTPL(SaveTpl);
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FreeUpFHEntries
+//
+// Description: Release all file handles whose instance count is 0
+//
+// Parameters:
+// VOLUME_INFO *vi - Volume info
+// FILE_HANDLE *pfh - Parent file handle
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: CloseFileHandle
+//
+// Notes:
+// Don't remove pfh
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FreeUpFHEntries (
+ VOLUME_INFO *vi,
+ FILE_HANDLE *pfh
+)
+{
+
+ DLINK *dlink = vi->OpenFHs.pHead;
+ FILE_HANDLE *lfh;
+
+// Go through all the FHs in Volume Interface and release all whose Instance
+// count is 0, no DIR list is present and childlist is NULL
+// Don't delete:
+// 1. If Instance count is more than 0
+// 2. If Dir List is present,
+// 3. If it is a Root Dir,
+// 4. If Child List is present,
+// 5. If it is a i/p fh
+// 6. If the i/p FH is the parent of the fh.
+ for ( ; dlink; ) {
+ lfh = OUTTER(dlink, ViFHLink, FILE_HANDLE);
+ dlink = dlink->pNext;
+
+ if (lfh->InstancesCount == 0 && !(lfh->DirList.pHead) &&
+ !(lfh->ROOTDIR) && !(lfh->ChildList.pHead) && lfh != pfh) RemoveFH(lfh);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FreeUpDirEntries
+//
+// Description: Free up cached directory entries
+//
+// Parameters:
+// VOLUME_INFO *vi - Volume info
+// FILE_HANDLE *pfh - Parent file handle
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadAllDirectoryEntries, CloseFileHandle
+//
+// Notes:
+// Don't remove pfh
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FreeUpDirEntries (
+ VOLUME_INFO *vi,
+ FILE_HANDLE *pfh
+)
+{
+
+ DLINK *dlink = vi->OpenFHs.pHead;
+ FILE_HANDLE *lfh;
+
+ for ( ; dlink; ) {
+ if (vi->TotalDirEntryList <= DIRECTORTY_ENTRIES_CACHED) break;
+
+ lfh = OUTTER(dlink, ViFHLink, FILE_HANDLE);
+
+ if (lfh != pfh && lfh->DirList.pHead) RemoveAllDirList(lfh);
+
+ dlink = dlink->pNext;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RemoveAllDirList
+//
+// Description: Removes all directory lists from cache (needs to be re-read)
+//
+// Parameters:
+// FILE_HANDLE *lfh - list file handle
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadFileHandle, DeleteFileHandle, FreeUpDirEntries
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveAllDirList(
+ FILE_HANDLE *lfh
+)
+{
+
+ DLINK *dlink = lfh->DirList.pHead;
+ DIR_ENTRY_LIST *Del;
+
+ for ( ; dlink; ) {
+ Del = OUTTER(dlink, DirLink, DIR_ENTRY_LIST);
+ dlink = dlink->pNext;
+ RemoveDirList (lfh, Del);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RemoveDirList
+//
+// Description: Removes a directory list from cache
+//
+// Parameters:
+// FILE_HANDLE *fh - Directory file handle
+// DIR_ENTRY_LIST *Del - Directory list
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: DeleteFileHandle, RemoveAllDirList
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveDirList (
+ FILE_HANDLE *fh,
+ DIR_ENTRY_LIST *Del
+)
+{
+
+ fh->VolumeInterface->TotalDirEntryList--;
+
+ fsDeAllocateMemory (fh->VolumeInterface, Del->FileNameLFN);
+ DListDelete ((DLIST *)(UINTN)&(fh->DirList), (DLINK *)(UINTN)&(Del->DirLink));
+ fsDeAllocateMemory (fh->VolumeInterface, Del);
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FetchLongName
+//
+// Description: Fetch a long name from a directory entry
+//
+// Parameters:
+// FILE_HANDLE *fh - File handle of the directory
+// DIR_ENTRY_32 *Buffer - Buffer containing directory entry
+// UINT32 BufferPos - Position in buffer
+// UINT16 *Name - Unicode name placed here
+// UINT32 ClusterNumber - Current directory cluster
+// UINT32 ClusterSize - Cluster size in bytes
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ReadAllDirectoryEntries
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+FetchLongName (
+ FILE_HANDLE *fh,
+ DIR_ENTRY_32 *Buffer,
+ UINT32 BufferPos,
+ UINT16 *Name,
+ UINT32 ClusterNumber,
+ UINT32 ClusterSize
+)
+{
+
+ DIR_ENTRY_LFN *LfnSlot = (DIR_ENTRY_LFN *) ((UINT8 *)Buffer + BufferPos);
+ UINT8 Checksum = LfnChecksum((UINT8 *) Buffer + BufferPos);
+ CHAR8 Order = 0;
+ UINT32 NamePos = 0;
+ UINT32 k;
+ UINT32 Cluster = 0;
+ EFI_STATUS Status;
+ BOOLEAN Backup = FALSE;
+
+ do {
+ if (--LfnSlot < (DIR_ENTRY_LFN *) Buffer) { // Long name is split over 2 clusters
+ Status = ReadClusterOfDirectoryEntries(fh, ClusterNumber-1, &Cluster, (UINT8*)Buffer, &ClusterSize);
+ Backup = TRUE; // We had to back up into the previous cluster to get the whole name
+ if (EFI_ERROR(Status) || (Status == EFI_SUCCESS && ClusterSize == 0)) { Order = 0; goto exit; };
+ LfnSlot = (DIR_ENTRY_LFN *) ((UINT8 *)Buffer + ClusterSize);
+ LfnSlot--;
+ }
+ if (Order > MAX_LFN_SLOTS) { Order = 0; goto exit; }; // Max of 20 LFN slots are possible 255 chars max.
+
+ if ((LfnSlot->Dir_Attr & ATTR_LONG_NAME_MASK) != (ATTR_LONG_NAME)) { Order = 0; goto exit; };
+
+ if (++Order != (LfnSlot->Dir_Order & 0x1F)) { Order = 0; goto exit; };
+
+ if (Checksum != LfnSlot->Dir_Checksum) { Order = 0; goto exit; };
+
+ // Ok, the LFN slot is valid, attach it to the long name
+ for (k = 0; k < 5; k++) Name[NamePos++] = LfnSlot->Dir_Name0_4[k];
+
+ for (k = 0; k < 6; k++) Name[NamePos++] = LfnSlot->Dir_Name5_10[k];
+
+ for (k = 0; k < 2; k++) Name[NamePos++] = LfnSlot->Dir_Name11_12[k];
+ } while (!(LfnSlot->Dir_Order & 0x40));
+
+// If the name was exactly 13 characters long in the last slot, add a terminating zero.
+// Otherwise, it will already end in a zero.
+ if (Name[NamePos - 1] != 0x0000) Name[NamePos] = 0x0000;
+exit:
+ if (Backup) { // Re-read the old cluster if we had to back up
+ Status = ReadClusterOfDirectoryEntries(fh, ClusterNumber, &Cluster, (UINT8*)Buffer, &ClusterSize);
+ if (EFI_ERROR(Status)) Order = 0;
+ }
+ return Order;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LfnChecksum
+//
+// Description: Calculate long file name entry section checksum
+//
+// Parameters:
+// UINT8 *D - Pointer to long name entry
+//
+//
+// Return Value:
+// UINT8 - Checksum
+//
+// Modified:
+//
+// Referrals: FetchLongName
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+LfnChecksum(
+ UINT8 *D
+)
+{
+ UINT8 Sum = 0;
+ UINT8 i;
+
+ for (i = 11; i != 0; i--) {
+ Sum = ((Sum & 1) ? 0x80 : 0) + (Sum >> 1) + *D++;
+ }
+
+ return Sum;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindShortName
+//
+// Description: Return a valid short name Directory Entry from DirCluster
+// beginning from ReadPosition.
+//
+// Parameters:
+// UINT8 *Buffer - Buffer to search in
+// UINT32 *Offset - Offset in buffer where entry found
+// UINT32 BufferSize - Size of buffer
+//
+//
+// Return Value:
+// BOOLEAN - True = name found
+//
+// Modified:
+//
+// Referrals: ReadAllDirectoryEntries
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+FindShortName (
+ UINT8 *Buffer,
+ UINT32 *Offset,
+ UINT32 BufferSize
+)
+{
+ DIR_ENTRY_32 *Entry = (DIR_ENTRY_32 *)(Buffer + *Offset);
+ UINT32 i;
+
+ for (i = *Offset; BufferSize; i+=sizeof(DIR_ENTRY_32),BufferSize-=sizeof(DIR_ENTRY_32)) {
+ if (Entry->Dir_Name[0] == 0) {
+ *Offset = (UINTN)-1;
+ return FALSE; // no more directory Entries.
+ }
+
+ if (((Entry->Dir_Attr & ATTR_LONG_NAME_MASK) != (ATTR_LONG_NAME)) &&
+ (Entry->Dir_Name[0] > 0x1f) &&
+ (Entry->Dir_Name[0] != 0xe5)) {
+ *Offset = i; // Point offset to short name found
+
+ return TRUE;
+ }
+
+ Entry++;
+ }
+
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CreateDirectoryEntry
+//
+// Description: Creates a directory entry
+//
+// Parameters:
+// IN FILE_HANDLE *fh - File handle
+// IN CHAR16 *NextCompName - Unicode name to create
+// OUT FILE_HANDLE **fh1 - File handle for new name
+// IN UINT64 Attributes
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ProcessOpenFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateDirectoryEntry (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *NextCompName,
+ OUT FILE_HANDLE **fh1,
+ IN UINT64 Attributes
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 DirCluster, DirClusterOffset;
+ UINT32 Length;
+ CHAR8 DirEntry[32];
+ DIR_ENTRY_32 *Entry = (DIR_ENTRY_32 *) &DirEntry;
+ CHAR16 *lfn;
+ DIR_ENTRY_LIST *Del;
+
+ Status = CreateDirEntryInDisk (fh, NextCompName, Attributes, &DirCluster, &DirClusterOffset, Entry);
+
+ if (EFI_ERROR(Status)) return Status;
+
+// Create a Dir_List Entry
+ Length = (UINT32)(Wcslen(NextCompName) * sizeof(CHAR16)) + 2;
+ Status = fsAllocateMemory(fh->VolumeInterface, (UINT32) Length, (VOID**)&lfn, FALSE);
+ pBS->CopyMem(lfn, NextCompName, Length);
+ AddToDirList (fh, *Entry, lfn, DirCluster, DirClusterOffset, (UINTN)-1);
+
+ Del = OUTTER(fh->DirList.pTail, DirLink, DIR_ENTRY_LIST);
+// Create a File Handle
+ Status = CreateFHFromDirEntryList(Del, fh, fh1);
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CreateDirEntryInDisk
+//
+// Description: Creates a directory entry on the disk
+//
+// Parameters:
+// IN FILE_HANDLE *fh - File handle
+// IN CHAR16 *NextCompName - Name to create
+// IN UINT64 Attributes - Attributes for entry
+// OUT UINT32 *DirCluster - Cluster of entry created
+// OUT UINT32 *DirClusterOffset - Offset in cluster
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: CreateDirectoryEntry
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateDirEntryInDisk (
+ IN FILE_HANDLE *fh,
+ IN CHAR16 *NextCompName,
+ IN UINT64 Attributes,
+ OUT UINT32 *DirCluster,
+ OUT UINT32 *DirClusterOffset,
+ DIR_ENTRY_32 *Entry
+)
+{
+
+ EFI_STATUS Status;
+ VOLUME_INFO *Vi = fh->VolumeInterface;
+ CHAR8 ShortFileName[11];
+ EFI_TIME EfiTime;
+ EFI_TIME_CAPABILITIES Capabilities;
+ UINT32 Sector, SectorOffset;
+ BOOLEAN LastDirEntry = FALSE;
+ UINT32 Length;
+ BOOLEAN LfnNeeded = FALSE;
+ UINT8 *Slots;
+ UINT32 NumSlots = 0;
+
+ if (Vi->ReadOnly) return EFI_WRITE_PROTECTED;
+
+ Status = GenUniqueShortFname (fh, NextCompName, ShortFileName, &LfnNeeded);
+
+ if (EFI_ERROR(Status)) return Status;
+
+// Create Short Directory entry
+ Zeromemory (Entry, sizeof(DIR_ENTRY_32));
+ pBS->CopyMem(Entry, ShortFileName, 11);
+ Entry->Dir_Attr = (UINT8)Attributes;
+ pRS->GetTime(&EfiTime, &Capabilities);
+ EfiToFatTime (EfiTime, &Entry->Dir_CrtDate, &Entry->Dir_CrtTime);
+ Entry->Dir_LstAccDate = Entry->Dir_CrtDate;
+ Entry->Dir_WrtTime = Entry->Dir_CrtTime;
+ Entry->Dir_WrtDate = Entry->Dir_CrtDate;
+
+// Update the Cluster number in case of '.' entry.
+ if (NextCompName[0] == '.' && NextCompName[1] == 0) {
+ Length = FIRSTCLUSTER(fh->DirectoryEntry);
+ Entry->Dir_FstClusHI = (UINT16) (Length >> 16);
+ Entry->Dir_FstClusLO = (UINT16) Length;
+ }
+
+
+ fsAllocateMemory (Vi, (MAX_LFN_SLOTS + 2) * sizeof(DIR_ENTRY_32), (void **)&Slots, FALSE);
+
+ if (LfnNeeded) {
+ Status = SplitLFN (NextCompName, Entry, (DIR_ENTRY_LFN *)Slots, &NumSlots);
+
+ if (EFI_ERROR(Status)) goto Error;
+ }
+
+// Assuming a short filename FILENAME.EXT (FILENAMEEXT), generate a
+// name in the form FILENA~1.EXT, where n is a count beginning with 1.
+// GenUniqueFileName(fh, NextCompName, &ShortFileName);
+
+// Append Short Directory Entry at the End of Long File Name slots
+ Length = NumSlots * sizeof(DIR_ENTRY_32);
+ pBS->CopyMem(Slots + Length, Entry, sizeof(DIR_ENTRY_32));
+ Length += sizeof(DIR_ENTRY_32); // This is the total length
+
+ Status = LocateFreeDirEntry(fh, Length, DirCluster,
+ DirClusterOffset, &LastDirEntry);
+
+ if (EFI_ERROR(Status)) goto Error;
+
+ GetSectorAddressDir(fh, *DirCluster, *DirClusterOffset, &Sector, &SectorOffset);
+ Status = FsWriteMedia (Vi, Slots, Sector, SectorOffset, Length, DIRECTORY_REGION);
+
+ if (EFI_ERROR(Status)) goto Error;
+
+ *DirClusterOffset += Length;
+
+ if (LastDirEntry == TRUE) {
+ fh->FreeDirEntryCluster = *DirCluster;
+ fh->FreeDirEntryOffset = *DirClusterOffset;
+
+ } else {
+ fh->DirListChanged = TRUE;
+ }
+
+ *DirClusterOffset -= sizeof(DIR_ENTRY_32);
+
+Error:
+
+ fsDeAllocateMemory (Vi, Slots);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetTempBuffer
+//
+// Description: Gets a temporary buffer
+//
+// Parameters:
+// VOLUME_INFO *Vi - Volume info
+// VOID **Buffer - Buffer
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ProcessOpenFileHandle, ReadAllDirectoryEntries, CloseFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+GetTempBuffer (
+ VOLUME_INFO *Vi,
+ VOID **Buffer
+)
+{
+
+ *Buffer = (UINT8 *)(Vi->TempBuffer);
+ Vi->TempBufferInUse = TRUE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReleaseTempBuffer
+//
+// Description: Releases a temporary buffer
+//
+// Parameters:
+// VOLUME_INFO *Vi - Volume Info
+//
+// Return Value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ProcessOpenFileHandle, ReadAllDirectoryEntries, CloseFileHandle
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ReleaseTempBuffer (
+ VOLUME_INFO *Vi
+)
+{
+ Vi->TempBufferInUse = FALSE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FileSystem/VolFatHandler.c b/Core/EM/FileSystem/VolFatHandler.c
new file mode 100644
index 0000000..ce73b6b
--- /dev/null
+++ b/Core/EM/FileSystem/VolFatHandler.c
@@ -0,0 +1,1419 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FileSystem/VolFatHandler.c 9 12/02/09 9:29a Pats $
+//
+// $Revision: 9 $
+//
+// $Date: 12/02/09 9:29a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FileSystem/VolFatHandler.c $
+//
+// 9 12/02/09 9:29a Pats
+// EIP 32115: The fat driver in aptio does not calculate free space
+// correctly.
+// Solution: AllocateAndLinkClusters() changed to calculate new cluster
+// for free space differently, and to fix error path.
+//
+// 8 7/02/09 5:47p Pats
+// Updated to latest coding standard. No code changes.
+//
+// 7 5/17/07 4:00p Srinin
+// Uninitialized varaible FreeClusters in UpdateFreeSpace initialized.
+//
+// 6 4/13/07 7:07p Pats
+// Edited to conform with coding standards. No code changes.
+//
+// 5 4/05/07 12:14p Pats
+// Fixed GetFreeClusterCount function. BufferSize variable was not being
+// handled properly on large disks.
+//
+// 4 9/13/06 5:57p Pats
+// Fixed problem of free space reported incorrectly on El Torito CD.
+//
+// 7 11/03/05 2:16p Srinin
+// Fixed VC7.1 warning msg.
+//
+// 6 9/14/05 4:30p Pats
+// Fixed problem of free disk space being calculated incorrectly in some
+// cases.
+//
+// 5 7/19/05 2:58p Pats
+// Removed a little unnecessary code and added comments.
+//
+// 4 6/21/05 3:45p Pats
+// Added function MarkVolumeDirty, to mark FAT16 and FAT32 volumes if any
+// EFI_VOLUME_CORRUPTED error occurs.
+//
+// 3 6/16/05 4:18p Pats
+// Fixed problem in UnlinkFat -- did not unlink FAT12 files properly in
+// every case.
+//
+// 2 5/27/05 10:02a Srinin
+// Fix for free space calculation.
+//
+// 1 4/26/05 6:05p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: VolFatHndlr.c
+//
+// Description: Fat File System driver -- Volume Level Fat Handler
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "FileSystem.h"
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetSectorAddressDir
+//
+// Description: Gets the absolute sector of a directory
+//
+// Parameters:
+// FILE_HANDLE *fh - File Handle
+// UINT32 Cluster - Cluster of directory
+// UINT32 ClusterOffset - Offset in cluster
+// UINT32 *Sector - Absolute sector of directory
+// UINT32 *SectorOffset - Offset in sector
+//
+// Return value: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Use this routine if DIR region neeeds to be Read/Written.
+// For Data Region or FAT32 ROOT dir use GetAbsSectorInfo
+// For FAT12/16 root dir, Cluster is not valid. ClusterOffset
+// is the relative offset within the Root Dir Region.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+GetSectorAddressDir (
+ FILE_HANDLE *fh,
+ UINT32 Cluster,
+ UINT32 ClusterOffset,
+ UINT32 *Sector,
+ UINT32 *SectorOffset
+)
+{
+ VOLUME_INFO *vi = fh->VolumeInterface;
+
+ if (fh->ROOTDIR && (vi->FatType != FAT32)) {
+ *Sector = ClusterOffset / vi->VolumeBPB.BPB_BytePerSec + vi->FirstRootDirSector;
+ *SectorOffset = ClusterOffset % vi->VolumeBPB.BPB_BytePerSec;
+
+ } else {
+ GetAbsSectorInfo (vi, Cluster, ClusterOffset, Sector, SectorOffset);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FatClusterNumberLocation
+//
+// Description: Returns the location (sector and offset) of a valid cluster
+// number in the specified FAT.
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN UINTN Cluster, A cluster number
+// IN UINTN FatNumber, The fat number (0 or 1)
+//
+// Return value:
+// EFI_STATUS
+// EFI_SUCCESS - Cluster located
+// OUT UINT32 *Sector, Fat sector in which cluster is located
+// OUT UINT32 *SectorOffset Offset in the sector where cluster is
+// other - Cluster not located
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FatClusterNumberLocation (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT8 FatNumber,
+ OUT UINT32 *Sector,
+ OUT UINT32 *SectorOffset
+)
+{
+ UINT32 FatOffset;
+
+ if (Cluster > Vol->CountOfDataClusters + 2) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Vol->FatType) {
+ case FAT12:
+ FatOffset = Cluster + (Cluster / 2);
+ break;
+ case FAT16:
+ FatOffset = Cluster * 2;
+ break;
+ case FAT32:
+ FatOffset = Cluster * 4;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ *Sector = FatNumber * Vol->FATSz + Vol->VolumeBPB.BPB_RsvdSecCnt
+ + FatOffset / Vol->VolumeBPB.BPB_BytePerSec;
+ *SectorOffset = FatOffset % Vol->VolumeBPB.BPB_BytePerSec;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadFatClusterNumber
+//
+// Description: Reads a single cluster number from the specified fat table
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN UINTN Cluster, A cluster number
+// IN UINT8 FatNumber, The fat number (0 or 1)
+// OUT UINT32 *Value The returned cluster number
+//
+// Return value:
+// EFI_STATUS
+// EFI_SUCCESS - Cluster read
+// other - Cluster not read
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ReadFatClusterNumber (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT8 FatNumber,
+ OUT UINT32 *Value
+)
+{
+ EFI_STATUS Status;
+ UINT32 Sector = 0;
+ UINT32 SectorOffset = 0;
+ UINT32 ValueSize;
+
+ Status = FatClusterNumberLocation(Vol, Cluster, FatNumber, &Sector, &SectorOffset);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Vol->FatType == FAT32) ValueSize = sizeof(UINT32);
+
+ else ValueSize = sizeof(UINT16);
+
+ Status = FsReadMedia (Vol,
+ (UINT8 *)Value,
+ (UINT64)Sector,
+ SectorOffset,
+ ValueSize,
+ FAT_REGION);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ switch (Vol->FatType) {
+ case FAT12:
+
+ if (Cluster & 0x0001) *Value >>= 4;
+
+ *Value &= 0x0fff;
+ break;
+ case FAT16:
+ *Value &= 0x0ffff;
+ break;
+ case FAT32:
+ *Value &= 0x0fffffff; // FAT32 actually uses 28 bits
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteFatClusterNumber
+//
+// Description: Writes a single cluster number into the specified FAT table
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN UINTN Cluster, A cluster number
+// IN UINT8 FatNumber, The fat number (0 or 1)
+// IN UINT32 Value The cluster value to be written
+//
+// Return value:
+// EFI_STATUS
+// EFI_SUCCESS - Cluster written
+// other - Cluster not written
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+WriteFatClusterNumber (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT8 FatNumber,
+ IN UINT32 Value
+)
+{
+ EFI_STATUS Status;
+ UINT32 Sector = 0;
+ UINT32 SectorOffset = 0;
+ UINT32 TempValue;
+ UINT32 ValueSize;
+
+ Status = FatClusterNumberLocation(Vol, Cluster, FatNumber, &Sector, &SectorOffset);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Vol->FatType == FAT32) ValueSize = sizeof(UINT32);
+
+ else ValueSize = sizeof(UINT16);
+
+ switch (Vol->FatType) {
+ case FAT12:
+ Status = FsReadMedia (Vol,
+ (UINT8 *)&TempValue,
+ (UINT64)Sector,
+ SectorOffset,
+ ValueSize,
+ FAT_REGION);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Cluster & 0x0001) {
+ Value <<= 4;
+ TempValue &= 0x000f;
+
+ } else {
+ Value &= 0x0FFF;
+ TempValue &= 0xf000;
+ }
+
+ TempValue |= (UINT16)Value;
+ break;
+ case FAT16:
+ TempValue = (UINT16)Value;
+ break;
+ case FAT32:
+ Value &= 0x0fffffff;
+ TempValue = Value;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = FsWriteMedia (Vol,
+ (UINT8 *)&TempValue,
+ (UINT64)Sector,
+ SectorOffset,
+ ValueSize,
+ FAT_REGION);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AllocateAndLinkClusters
+//
+// Description: Allocates clusters for use in a file
+//
+// Parameters:
+// IN VOLUME_INFO *Vol - Volume info
+// IN UINT32 BeginCluster - Beginning cluster no.
+// IN UINT32 Size - Size to allocate
+// OUT UINT32 *FirstCluster - First cluster allocated
+// OUT UINT32 *ClusterCount - Count of clusters allocated
+//
+// Return value: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AllocateAndLinkClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 BeginCluster,
+ IN UINT32 Size,
+ OUT UINT32 *FirstCluster,
+ OUT UINT32 *ClusterCount
+)
+{
+
+ UINT32 ClustersRequired, NewCluster = 2, Dummy, NewBlocks, k, j;
+ EFI_STATUS Status;
+
+ *FirstCluster = 0;
+ *ClusterCount = 0;
+
+// Calculate the # of Clusters required.
+ ClustersRequired = GetClustersRequired (Vol, Size);
+
+ if (Vol->FreeSpaceinClusters != -1 && Vol->FreeSpaceinClusters < ClustersRequired)
+ return EFI_VOLUME_FULL;
+
+ do {
+
+ NewBlocks = ClustersRequired;
+
+ if (Vol->LastFreeCluster != -1) NewCluster = Vol->LastFreeCluster;
+ else {
+ Status = ReturnFreeSpace(Vol);
+ NewCluster = Vol->LastFreeCluster;
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ Status = FindFreeClusters(Vol, NewCluster, Vol->CountOfDataClusters+2, &NewCluster, &NewBlocks, &Dummy);
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_NOT_FOUND && NewCluster != 2) {
+// No cluster found after the current one, try from the start of the disk.
+ NewBlocks = ClustersRequired;
+ Status = FindFreeClusters(Vol, 2, Vol->CountOfDataClusters+2, &NewCluster, &NewBlocks, &Dummy);
+ if (EFI_ERROR(Status)) {
+ if (Status == EFI_NOT_FOUND) return EFI_VOLUME_FULL; else return Status;
+ }
+ }
+ else if (Status == EFI_NOT_FOUND) return EFI_VOLUME_FULL;
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ if (!*FirstCluster) *FirstCluster = NewCluster;
+
+// Add new cluster(s) to fat chain.
+ for (k=1; k <= NewBlocks; k++) {
+
+ for (j=0; j < Vol->VolumeBPB.BPB_NumFATs; j++) { // Update all fats.
+// Chain the new cluster
+ if (BeginCluster >=2) {
+ Status = WriteFatClusterNumber(Vol, BeginCluster, j, NewCluster);
+ if (EFI_ERROR(Status)) return Status;
+ }
+// Update the EOCfot the Last Block
+ Status = WriteFatClusterNumber(Vol, NewCluster, j, Vol->EOCMark);
+ if (EFI_ERROR(Status)) return Status;
+ } // end of j
+
+#ifdef Debug_AllocateClusters
+ EfiDebugPrint(-1,"%x", NewCluster);
+#endif
+
+ BeginCluster = NewCluster;
+ NewCluster++;
+ } // end for (k)
+ *ClusterCount += NewBlocks;
+ ClustersRequired -= NewBlocks;
+ UpdateFreeSpace (Vol, NewBlocks, FALSE); // Subtract from Free space
+ }while (ClustersRequired);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnlinkFat
+//
+// Description: Unlinks (marks as free) all the clusters of the chain
+// starting from cluster Cluster (that must be part of a valid
+// chain) until the EOC.
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN UINTN Cluster A cluster number
+//
+// Return value:
+// EFI_STATUS
+// EFI_SUCCESS - Chain unlinked.
+// other - Chain not unlinked
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UnlinkFat (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ OUT UINT32 *ClusterCount
+)
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT32 Next;
+
+ *ClusterCount = 0;
+
+ do {
+ if (!Cluster) return EFI_NOT_FOUND;
+
+ Status = ReadFatClusterNumber(Vol, Cluster, 0, &Next);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Next < 2) {
+ MarkVolumeDirty (Vol);
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ /* Update every FAT in the volume */
+ for (i = 0; i < Vol->VolumeBPB.BPB_NumFATs; i++) {
+ Status = WriteFatClusterNumber(Vol, Cluster, i, 0);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ Cluster = Next;
+ ++*ClusterCount;
+ } while (Next < Vol->EOCMark); // Repeat till end of chain found.
+
+ UpdateFreeSpace (Vol, *ClusterCount, TRUE); // Add to Free space
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindFreeClusters
+//
+// Description: Searches a volume for a free cluster in the specified range
+// of clusters.
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN UINT32 From, Cluster to start search at
+// IN UINT32 To, End of search range
+// OUT UINT32 *StartCluster Free cluster found
+// IN OUT UINT32 *FreeClusters In - free clustere requested.
+// Out - Free clusters found
+// OUT UINT32 *TotalFree Total free clusters found in this
+// search
+//
+// Return value:
+// EFI_STATUS
+// EFI_SUCCESS - Free cluster found, Vol->LastFreeCluster updated.
+// EFI_NOT_FOUND - Free cluster not found.
+// other - any other error.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+FindFreeClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 From,
+ IN UINT32 To,
+ OUT UINT32 *StartCluster,
+ IN OUT UINT32 *FreeClusters,
+ OUT UINT32 *TotalFree
+)
+{
+ EFI_STATUS Status;
+ UINT32 Count = 0;
+ UINT32 FreeCount = 0;
+ UINT32 LastFree = 0;
+ UINT32 FreeBlock = 0;
+ UINT32 PrevFreeCount, PrevFreeBlock;
+ UINT32 i;
+ UINT32 Value;
+
+// if (From == 0) return (FindNextFreeCluster (Vol, Cluster));
+
+ for (i = From; i < To; i++) {
+ Status = ReadFatClusterNumber(Vol, i, 0, &Value);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (Value == 0) {
+ Count++;
+
+ if (i != (LastFree + 1)) {
+ PrevFreeBlock = FreeBlock;
+ PrevFreeCount = FreeCount;
+ FreeBlock = i; // Reset free block if not contiguous
+ FreeCount = 0; // Restart free count
+ }
+
+ LastFree = i;
+ FreeCount++;
+
+ if (FreeCount >= *FreeClusters) { // If we found the requested count
+ *FreeClusters = FreeCount;
+ *StartCluster = Vol->LastFreeCluster = FreeBlock;
+ *TotalFree = Count;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+
+ if (Count) {
+ *TotalFree = Count;
+
+ if (FreeCount > PrevFreeCount) { // in case the last free block is not the largest.
+ *StartCluster = FreeBlock;
+ *FreeClusters = FreeCount;
+
+ } else {
+ *StartCluster = PrevFreeBlock;
+ *FreeClusters = PrevFreeCount;
+ }
+
+ return EFI_SUCCESS;
+
+ } else return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ClusterToSector
+//
+// Description: Converts a custer number to an absolute sector number
+// (relative to the beginning of the volume).
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// OUT UINTN Cluster The cluster to be converted
+//
+// Return value:
+// Returns the sector number.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+ClusterToSector (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster
+)
+{
+ UINT32 Offset;
+ UINT32 Sector;
+
+ Offset = Vol->VolumeBPB.BPB_RsvdSecCnt + Vol->FATSz * Vol->VolumeBPB.BPB_NumFATs +
+ Vol->RootDirSectorCount;
+
+ if (Cluster) Sector = (Cluster - 2) * (UINT32)Vol->VolumeBPB.BPB_SecPerClus + Offset;
+
+ else Sector = Offset;
+
+ return Sector;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SectorToCluster
+//
+// Description: Converts an absolute sector number (relative to the beginning
+// of a volume) to a cluster number, and the sector within that
+// cluster.
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// OUT UINTN Sector The sector to be converted
+//
+// Return value:
+// Sector - The sector offset in the returned cluster.
+// Returns the sector number.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+SectorToCluster (
+ IN VOLUME_INFO *Vol,
+ IN OUT UINT32 Sector
+)
+{
+ UINT32 Temp1;
+ UINT32 Temp2;
+
+ // Calculate offset to 1st data sector
+ Temp1 = Vol->VolumeBPB.BPB_RsvdSecCnt + Vol->FATSz * Vol->VolumeBPB.BPB_NumFATs +
+ Vol->RootDirSectorCount;
+ Temp2 = Sector - Temp1; // "Normalize" the sector
+ Temp1 = Temp2 / (UINT32)Vol->VolumeBPB.BPB_SecPerClus; // Calculate the cluster number
+ Sector = Temp2 % (UINT32)Vol->VolumeBPB.BPB_SecPerClus; // Get sector within cluster
+ return Temp1 + 2; // Account for first cluster being no. 2
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetClusterCount
+//
+// Description: Gets the cluster count of a file (usually a directory,
+// because Dir_FileSize is zero for these, and we need to
+// know the file size).
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN OUT UINT32 Cluster In - the first cluster. Out - count
+//
+// Return value:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetClusterCount (
+ IN VOLUME_INFO *Vol,
+ IN OUT UINT32 Cluster
+)
+{
+ UINT32 Count = 0;
+ UINT32 TempCluster = 0;
+
+ // If the first cluster is EOC, return a count of 0.
+ if (Cluster >= Vol->EOCMark) {
+ Cluster = Count;
+ return EFI_SUCCESS;
+ }
+
+ // Follow the chain and count the clusters until EOC.
+ do {
+ ReadFatClusterNumber(Vol, Cluster, 0, &TempCluster);
+
+ if (TempCluster < 2) {
+ MarkVolumeDirty (Vol);
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ Count++;
+ Cluster = TempCluster;
+ } while (Cluster < Vol->EOCMark);
+
+ // Return the count in Cluster.
+ Cluster = Count;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetClustersRequired
+//
+// Description: Gets the amount of clusters required to store N blocks.
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN UINT32 N A byte count
+//
+// Return value:
+// Returns the required clusters.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+GetClustersRequired (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 N
+)
+{
+ return (N + Vol->BytesPerCluster - 1) / (Vol->BytesPerCluster);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetContiguousClusters
+//
+// Description: Gets the nunber of contiguous clusters starting from the
+// specified cluster
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN OUT UINT32 Cluster The cluster to start with
+//
+// Return value:
+// Returns the number of contiguous clusters in Cluster.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetContiguousClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Size,
+ IN UINT32 Cluster,
+ OUT UINT32 *NextCluster,
+ OUT UINT32 *Count
+)
+{
+ EFI_STATUS Status;
+ UINT32 TotalBytes;
+
+ if (Cluster == Vol->EOCMark) {
+ *Count = 0;
+ return EFI_SUCCESS;
+ }
+
+ *Count = 1;
+
+ TotalBytes = Vol->BytesPerCluster;
+
+ do {
+ Status = ReadFatClusterNumber(Vol, Cluster, 0, NextCluster);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (TotalBytes >= Size) break;
+
+ if (*NextCluster >= Vol->EOCMark) break;
+
+ if (*NextCluster < 2) {
+ MarkVolumeDirty (Vol);
+ return EFI_VOLUME_CORRUPTED;
+ }
+
+ if (*NextCluster == (Cluster + 1)) {
+ ++*Count;
+ TotalBytes += Vol->BytesPerCluster;
+ Cluster = *NextCluster;
+ }
+ } while (Cluster == *NextCluster);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetClusterPosition
+//
+// Description: Gets the nunber of contiguous clusters starting from the
+// specified cluster
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN OUT UINT32 Cluster The cluster to start with
+//
+// Return value:
+// Returns the number of contiguous clusters in Cluster.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetClusterPosition (
+ IN FILE_HANDLE_INSTANCE *File,
+ IN UINT64 Position,
+ OUT UINT32 *Cluster,
+ OUT UINT32 *ClusterOffset
+)
+{
+ EFI_STATUS Status;
+ VOLUME_INFO *Vol = File->pFH->VolumeInterface;
+ UINT32 ClusterCount;
+ UINT32 TempCluster, NextCluster;
+ UINT32 i;
+
+
+ NextCluster = TempCluster = FIRSTCLUSTER(File->pFH->DirectoryEntry);
+// Get the count of clusters that Position is from the beginning of the file.
+ ClusterCount = (UINT32)Position / Vol->BytesPerCluster;
+ *Cluster = 0;
+ *ClusterOffset = 0;
+
+ if (TempCluster) {
+ for (i=0; i<ClusterCount; i++, TempCluster = NextCluster) {
+ Status = ReadFatClusterNumber(Vol, TempCluster, 0, &NextCluster);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ if (NextCluster >= Vol->EOCMark) break;
+ }
+
+// Is the Position is set to EOF, then cluster will be the last valid
+// cluster and offset set to Vol->BytesPerCluster
+// else Cluster and cluster offset will be a valid pointer to the
+// Position
+ *Cluster = NextCluster;
+ *ClusterOffset = (UINT32)Position % Vol->BytesPerCluster;
+
+ if (!*ClusterOffset) {
+ if (NextCluster >= Vol->EOCMark) {
+ File->CurrentCluster = TempCluster;
+ File->CurrentClusterOffset = Vol->BytesPerCluster;
+ }
+ }
+ }
+
+//TODO TODO
+// Should be removed later
+// if (*Cluster >= Vol->EOCMark) {
+// _asm jmp $
+// }
+//TODO TODO
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetAbsSectorInfo
+//
+// Description: Gets the nunber of contiguous clusters starting from the
+// specified cluster
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// IN OUT UINT32 Cluster The cluster to start with
+//
+// Return value:
+// Returns the number of contiguous clusters in Cluster.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+GetAbsSectorInfo (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 Cluster,
+ IN UINT32 ClusterOffset,
+ OUT UINT32 *Sector,
+ OUT UINT32 *SectorOffset
+)
+{
+ *Sector = ClusterToSector(Vol, Cluster) + (ClusterOffset / (UINT32)Vol->VolumeBPB.BPB_BytePerSec);
+ *SectorOffset = ClusterOffset % (UINT32)Vol->VolumeBPB.BPB_BytePerSec;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ShrinkClusters
+//
+// Description: Reduces the number of clusters used by a file
+// (part of it deleted).
+//
+// Parameters:
+// IN VOLUME_INFO *Vol,
+// IN UINT32 StartCluster,
+// IN UINT32 ClusterCount
+//
+// Return value: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// ClusterCount : Total number of Final clusters starting from StartCluster
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ShrinkClusters (
+ IN VOLUME_INFO *Vol,
+ IN UINT32 StartCluster,
+ IN UINT32 ClusterCount
+)
+{
+ EFI_STATUS Status;
+ UINT32 LastCluster, NextCluster = StartCluster;
+ UINT32 i;
+
+// Get to the particular Cluster#
+ for ( i = 0; i < ClusterCount; i++, StartCluster = NextCluster) {
+ LastCluster = StartCluster;
+ Status = ReadFatClusterNumber (Vol, StartCluster, 0, &NextCluster);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+// Truncate it
+ if (ClusterCount) {
+ for (i = 0; i < Vol->VolumeBPB.BPB_NumFATs; i++) {
+ Status = WriteFatClusterNumber(Vol, LastCluster, i, Vol->EOCMark);
+
+ if (EFI_ERROR(Status)) return Status;
+ }
+ }
+
+// Free Up the remaining
+ Status = UnlinkFat (Vol, NextCluster, &ClusterCount); // Unlink From this Cluster
+ return Status;
+
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFreeClusterCount
+//
+// Description: Gets the count of free clusters on a disk.
+//
+// Parameters:
+// IN VOLUME_INFO *Vol, The volume structure
+// OUT UINT32 *FreeClusters Free clusters on volume
+// OUT UINT32 *FreeClusterBlock First cluster in a block of free clusters
+// OUT UINT32 *FreeBlockCount Number of clusters in the free block.
+//
+// Return value:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFreeClusterCount (
+ IN VOLUME_INFO *Vol,
+ OUT UINT32 *FreeClustersCount,
+ OUT UINT32 *FreeClusterBlock,
+ OUT UINT32 *FreeBlockCount
+)
+{
+ EFI_STATUS Status;
+ UINT32 Count = 0;
+ UINT32 FreeCount = 1;
+ UINT32 LastFree = 2;
+ UINT32 FreeBlock = 0;
+ UINT32 PrevFreeCount = 0, PrevFreeBlock;
+ UINT32 i,j;
+ UINT32 Value;
+ UINT8 *Buffer;
+ UINT32 BufferSize;
+ UINT32 BufferOffset = 0;
+ UINT32 FatSize;
+ UINT32 FatOffset;
+ UINT32 CountSize, CompareSize;
+ UINT32 TotalClusters;
+ UINT32 Sector;
+
+// Read in a maximum of 1 megabyte of the fat at a time for this calcuation
+ FatSize = Vol->FATSz * (UINT32)Vol->VolumeBPB.BPB_BytePerSec;
+
+ if (FatSize > 0xfffff) BufferSize = 0x100000;
+
+ else BufferSize = FatSize;
+
+ Status = fsAllocateMemory (Vol, BufferSize, &Buffer, FALSE);
+
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ TotalClusters = Vol->CountOfDataClusters;
+ j = i = 2; // For the first round start from Cluster 2
+
+ while (TotalClusters) {
+
+// Sector = Vol->FATSz + Vol->VolumeBPB.BPB_RsvdSecCnt + BufferOffset / (UINT32)Vol->VolumeBPB.BPB_BytePerSec;
+ Sector = Vol->VolumeBPB.BPB_RsvdSecCnt + BufferOffset / (UINT32)Vol->VolumeBPB.BPB_BytePerSec;
+ Status = FsReadMedia (Vol,
+ (UINT8 *)Buffer,
+ (UINT64)Sector,
+ 0,
+ BufferSize,
+ DATA_REGION);
+
+ if ( EFI_ERROR(Status)) goto GetFreeClusterCount_Error;
+
+// FAT12 or FAT16 will never have FAT size larger than 1MB
+// if (Vol->FatType != FAT32) CountSize = BufferSize/2; else CountSize = BufferSize/4;
+ if (BufferSize == FatSize) {
+ CountSize = TotalClusters;
+
+ } else {
+ CountSize = BufferSize / 4; // We could only have CountSize exceeding TotalClusters if FAT32
+ }
+
+// if (CountSize > TotalClusters) CountSize = TotalClusters;
+ if (i == 2) CompareSize = CountSize + 2;
+
+ else CompareSize = CountSize;
+
+ for (; i < CompareSize; i++, j++) {
+// Status = ReadFatClusterNumber(Vol, i, 0, &Value);
+ switch (Vol->FatType) {
+ case FAT12:
+ FatOffset = i + (i / 2);
+ (UINT16)Value = *(UINT16 *)((UINT8 *)Buffer + FatOffset);
+
+ if (i & 0x0001) Value >>= 4;
+
+ else Value &= 0x0fff;
+
+ break;
+ case FAT16:
+ FatOffset = i * 2;
+ (UINT16)Value = *(UINT16 *)((UINT8 *)Buffer + FatOffset);
+ Value &= 0x0ffff;
+ break;
+ case FAT32:
+ FatOffset = i * 4;
+ Value = *(UINT32 *)((UINT8 *)Buffer + FatOffset);
+ Value &= 0x0fffffff; // FAT32 actually uses 28 bits
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+
+ if (EFI_ERROR(Status)) goto GetFreeClusterCount_Error;
+
+ if (Value == 0) {
+ Count++;
+
+ if (j != (LastFree + 1)) {
+ if (FreeCount > PrevFreeCount) { // in case the last free block found is not the largest.
+ PrevFreeBlock = FreeBlock;
+ PrevFreeCount = FreeCount;
+ }
+
+ FreeBlock = j; // Reset free block if not contiguous
+ FreeCount = 0; // Restart free count
+ }
+
+ LastFree = j;
+ FreeCount++;
+ }
+ }
+
+ BufferOffset += BufferSize;
+ FatSize -= BufferSize;
+
+ if (FatSize > 0xfffff) BufferSize = 0x100000;
+
+ else BufferSize = FatSize;
+
+// Check for last group of clusters.
+ if (TotalClusters >= CountSize) {
+ TotalClusters -= CountSize;
+
+ } else {
+ CountSize = TotalClusters; // Adjust count size and buffer size if in last cluster group
+ BufferSize = TotalClusters * 4;
+ }
+
+// It's possible that the original Total Cluster count could have been incorrect.
+// Check that here.
+ if (TotalClusters && (BufferSize > FatSize)) {
+ TRACE((TRACE_ALWAYS, "TotalClusters was incorrect -- fixing it.\n"));
+ BufferSize = FatSize;
+ CountSize = TotalClusters = (BufferSize / 4);
+ TRACE((TRACE_ALWAYS, "Buffer adjusted to 0x%X bytes\n", BufferSize));
+ }
+
+ i = 0; // From Second round, start from Cluster 0
+ }
+
+ fsDeAllocateMemory (Vol, Buffer);
+
+ if (Count) {
+ *FreeClustersCount = Count;
+
+ if (FreeCount > PrevFreeCount) { // in case the last free block is not the largest.
+ *FreeClusterBlock = FreeBlock;
+ *FreeBlockCount = FreeCount;
+
+ } else {
+ *FreeClusterBlock = PrevFreeBlock;
+ *FreeBlockCount = PrevFreeCount;
+ }
+
+ return EFI_SUCCESS;
+
+ } else return EFI_NOT_FOUND;
+
+GetFreeClusterCount_Error:
+ fsDeAllocateMemory (Vol, Buffer);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReturnFreeSpace
+//
+// Description: Returns the amount of free space (in clusters) on a volume
+//
+// Parameters:
+// IN VOLUME_INFO *vi - Volume info structure
+//
+// Return value: UINT32 - free space in clusters
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+ReturnFreeSpace (
+ IN VOLUME_INFO *vi
+)
+{
+
+ UINT32 FreeClusterCount, StartFreeClusterBlock, nClusterBlocks;
+
+ if (vi->FreeSpaceinClusters != -1 && vi->LastFreeCluster != -1) return vi->FreeSpaceinClusters;
+
+ GetFreeClusterCount(vi, &FreeClusterCount, &StartFreeClusterBlock, &nClusterBlocks);
+
+ if (FreeClusterCount > vi->CountOfDataClusters) FreeClusterCount = 0;
+
+ vi->FreeSpaceinClusters = FreeClusterCount;
+ vi->LastFreeCluster = StartFreeClusterBlock;
+ vi->FreeClusterBlocks = nClusterBlocks;
+ return vi->FreeSpaceinClusters;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateFreeSpace
+//
+// Description: Updates the volume info free space in clusters
+//
+// Parameters:
+// IN VOLUME_INFO *vi - Volume info structure
+//
+// Return value: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateFreeSpace (
+ IN VOLUME_INFO *vi,
+ IN UINT32 Count,
+ IN BOOLEAN Add
+)
+{
+
+ UINT32 FreeClusters = vi->FreeSpaceinClusters;
+
+ if (vi->FreeSpaceinClusters == -1 ) FreeClusters = ReturnFreeSpace (vi);
+
+ if (Add) vi->FreeSpaceinClusters += Count;
+
+ else if (FreeClusters) vi->FreeSpaceinClusters -= Count;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MarkVolumeDirty
+//
+// Description: Marks a volume as dirty so that the OS will know to fix it.
+//
+// Parameters:
+// IN VOLUME_INFO *vi - Volume info structure
+//
+// Return value:
+//
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+MarkVolumeDirty (
+ IN VOLUME_INFO *vi
+)
+{
+ EFI_STATUS Status;
+ UINT32 Temp;
+
+ Status = ReadFatClusterNumber (vi, 1, 0, &Temp);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ switch (vi->FatType) {
+ case FAT12:
+ return EFI_SUCCESS; // Not supported in FAT21 -- ignore.
+ case FAT16: {
+ Temp &= ~0x8000; // Set dirty bit in FAT header.
+ break;
+ }
+ case FAT32: {
+ Temp &= ~0x08000000;
+ break;
+ }
+ default:
+ return EFI_SUCCESS;
+ }
+
+ Status = WriteFatClusterNumber (vi, 1, 0, Temp);
+
+ if (EFI_ERROR(Status)) return Status;
+
+// We don't have to write the 2nd fat, since the volume is dirty anyway, and
+// Windows or DOS will fix it. This saves a little code.
+// Status = WriteFatClusterNumber (vi, 1, 1, Temp);
+// if (EFI_ERROR(Status)) return Status;
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FirmwareManagement/FirmwareManagement.c b/Core/EM/FirmwareManagement/FirmwareManagement.c
new file mode 100644
index 0000000..8ea4a8f
--- /dev/null
+++ b/Core/EM/FirmwareManagement/FirmwareManagement.c
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/FirmwareManagement/FirmwareManagement.c 2 4/11/12 5:03p Artems $
+//
+// $Revision: 2 $
+//
+// $Date: 4/11/12 5:03p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/FirmwareManagement/FirmwareManagement.c $
+//
+// 2 4/11/12 5:03p Artems
+// [TAG] EIP87144
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Aptio4.6.5.3...SCT Execution test failed.(Firmware
+// Management Test\Firmware Management Protocol)
+// [RootCause] Firmware management protocol is not supported
+// [Solution] Added fix to pass conformance SCT test
+// [Files] FirmwareManagement.c
+//
+// 1 5/02/11 5:49p Artems
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FirmwareManagement.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Protocol\FirmwareManagement.h>
+
+EFI_STATUS FmGetImageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN OUT UINTN *ImageInfoSize,
+ IN OUT EFI_FIRMWARE_IMAGE_DESCRIPTOR *ImageInfo,
+ OUT UINT32 *DescriptorVersion,
+ OUT UINT8 *DescriptorCount,
+ OUT UINTN *DescriptorSize,
+ OUT UINT32 *PackageVersion,
+ OUT CHAR16 **PackageVersionName
+)
+{
+ if(ImageInfoSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(*ImageInfoSize < sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR)) {
+ *ImageInfoSize = sizeof(EFI_FIRMWARE_IMAGE_DESCRIPTOR);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS FmGetImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN OUT VOID *Image,
+ IN OUT UINTN *ImageSize
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS FmSetImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode,
+ IN EFI_FIRMWARE_MANAGEMENT_UPDATE_IMAGE_PROGRESS Progress,
+ OUT CHAR16 **AbortReason
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS FmCheckImage (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN UINT8 ImageIndex,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ OUT UINT32 *ImageUpdatable
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS FmGetPackageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ OUT UINT32 *PackageVersion,
+ OUT CHAR16 **PackageVersionName,
+ OUT UINT32 *PackageVersionNameMaxLen,
+ OUT UINT64 *AttributesSupported,
+ OUT UINT64 *AttributesSetting
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS FmSetPackageInfo (
+ IN EFI_FIRMWARE_MANAGEMENT_PROTOCOL *This,
+ IN CONST VOID *Image,
+ IN UINTN ImageSize,
+ IN CONST VOID *VendorCode,
+ IN UINT32 PackageVersion,
+ IN CONST CHAR16 *PackageVersionName
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_FIRMWARE_MANAGEMENT_PROTOCOL EfiFirmwareManagementProtocol = {
+ FmGetImageInfo,
+ FmGetImage,
+ FmSetImage,
+ FmCheckImage,
+ FmGetPackageInfo,
+ FmSetPackageInfo
+};
+
+EFI_STATUS FirmwareManagementEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiFirmwareManagementProtocolGuid,
+ &EfiFirmwareManagementProtocol,
+ NULL);
+
+
+ return Status;
+}
+
+
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/FirmwareManagement/FirmwareManagement.cif b/Core/EM/FirmwareManagement/FirmwareManagement.cif
new file mode 100644
index 0000000..b275d80
--- /dev/null
+++ b/Core/EM/FirmwareManagement/FirmwareManagement.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "FirmwareManagement"
+ category = ModulePart
+ LocalRoot = "Core\EM\FirmwareManagement"
+ RefName = "FirmwareManagement"
+[files]
+"FirmwareManagement.sdl"
+"FirmwareManagement.mak"
+"FirmwareManagement.c"
+<endComponent>
diff --git a/Core/EM/FirmwareManagement/FirmwareManagement.mak b/Core/EM/FirmwareManagement/FirmwareManagement.mak
new file mode 100644
index 0000000..7e35d84
--- /dev/null
+++ b/Core/EM/FirmwareManagement/FirmwareManagement.mak
@@ -0,0 +1,57 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/FirmwareManagement/FirmwareManagement.mak 1 5/02/11 5:49p Artems $
+#
+# $Revision: 1 $
+#
+# $Date: 5/02/11 5:49p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/FirmwareManagement/FirmwareManagement.mak $
+#
+# 1 5/02/11 5:49p Artems
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FirmwareManagement.mak
+#
+# Description: Make file to create FirmwareManagement Driver
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\FirmwareManagement.obj
+
+$(BUILD_DIR)\FirmwareManagement.obj : $(FirmwareManagement_DIR)\FirmwareManagement.c
+
+{$(FirmwareManagement_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/FirmwareManagement/FirmwareManagement.sdl b/Core/EM/FirmwareManagement/FirmwareManagement.sdl
new file mode 100644
index 0000000..f24feb3
--- /dev/null
+++ b/Core/EM/FirmwareManagement/FirmwareManagement.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "FirmwareManagementr_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FirmwareManagement support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "FirmwareManagement_DIR"
+ Help = "Path to FirmwareManagement Module in Project"
+End
+
+MODULE
+ Help = "Includes FirmwareManagement.mak to Project"
+ File = "FirmwareManagement.mak"
+End
+
+ELINK
+ Name = "FirmwareManagementEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/FlashSmi/FlashSmi.c b/Core/EM/FlashSmi/FlashSmi.c
new file mode 100644
index 0000000..8616758
--- /dev/null
+++ b/Core/EM/FlashSmi/FlashSmi.c
@@ -0,0 +1,804 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.c 1 1/20/15 1:36a Tristinchou $
+//
+// $Revision: 1 $
+//
+// $Date: 1/20/15 1:36a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.c $
+//
+// 1 1/20/15 1:36a Tristinchou
+// [TAG] EIP196554
+// [Category] New Feature
+// [Description] Initial check-in
+// [Files] FlashSmi.cif
+// FlashSmi.chm
+// FlashSmi.sdl
+// FlashSmi.mak
+// FlashSmi.c
+// FlashSmi.dxs
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashSmi.c
+//
+// Description: FLASH SMI DXE driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\FlashProtocol.h>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmCommunication.h>
+#endif
+
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+
+typedef struct
+{
+ UINT32 Signature;
+ UINT32 FlashAddress;
+ EFI_GUID VarGuid;
+ UINTN Size;
+ EFI_STATUS Status;
+ UINT16 Subfunction;
+ CHAR16 DummyName[50];
+ UINT32 DataBuffer;
+
+} SMI_FLASH_UPDATE;
+
+typedef struct
+{
+ BOOLEAN Busy;
+ UINT8 IntState[2];
+
+} FLASH_SMI_CRITICAL_SECTION;
+
+#define FSMI_SIGNATURE ('F'+('S'<<8)+(('M'+('I'<<8))<<16))//FSMI
+//----------------------------------------------------------------------------
+// Local Variables
+#define FLASH_SMI_GUID \
+{0x4052ACA8, 0x8D90, 0x4F5A, 0xBF, 0xE8, 0xB8, 0x95, 0xB1, 0x64, 0xE4, 0x82}
+#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \
+{0x3aa83745, 0x9454, 0x4f7a, 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e}
+
+EFI_GUID gFlashSmmProtocolGuid = FLASH_SMM_PROTOCOL_GUID;
+EFI_GUID gFlashProtocolGuid = FLASH_PROTOCOL_GUID;
+EFI_GUID gFlashSmiGuid = FLASH_SMI_GUID;
+EFI_GUID gBdsConnectDriversProtocolGuid = BDS_CONNECT_DRIVERS_PROTOCOL_GUID;
+VOID *gFlashBuffer = NULL;
+FLASH_PROTOCOL *gFlash, *gFlashSmm;
+FLASH_SMI_CRITICAL_SECTION FlashSmiCs = {FALSE, {0, 0}};
+FLASH_ERASE gSavedFlashErase;
+FLASH_READ_WRITE gSavedFlashWrite, gSavedFlashUpdate;
+FLASH_ERASE gSavedFlashEraseSmm;
+FLASH_READ_WRITE gSavedFlashWriteSmm;
+FLASH_READ_WRITE gSavedFlashUpdateSmm;
+
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+VOID FlashSmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+);
+
+EFI_SMM_COMMUNICATION_PROTOCOL *gSmmCommunicate = NULL;
+
+VOID
+SmmCommunicationReady(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+
+ pBS->CloseEvent(Event);
+
+ Status = pBS->LocateProtocol(
+ &gEfiSmmCommunicationProtocolGuid,
+ NULL,
+ &gSmmCommunicate );
+}
+
+EFI_STATUS
+GenerateFlashSmi(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_SMM_COMMUNICATE_HEADER SmmCommunicateHdr;
+ UINTN SmmCommunicateHdrSize;
+
+ MemCpy( &SmmCommunicateHdr.HeaderGuid, &gFlashSmiGuid, sizeof(EFI_GUID) );
+ SmmCommunicateHdr.MessageLength = 1;
+ SmmCommunicateHdr.Data[0] = 0;
+ SmmCommunicateHdrSize = sizeof(EFI_SMM_COMMUNICATE_HEADER);
+
+ Status = gSmmCommunicate->Communicate(
+ gSmmCommunicate,
+ &SmmCommunicateHdr,
+ &SmmCommunicateHdrSize );
+
+ return Status;
+}
+
+EFI_STATUS FlashSmiHandlerDummy (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+
+ SwContext.SwSmiInputValue = FLASH_SW_SMI;
+ FlashSmiHandler( DispatchHandle, &SwContext );
+
+ if( gFlashBuffer )
+ Status = ((SMI_FLASH_UPDATE*)gFlashBuffer)->Status;
+ else
+ Status = EFI_DEVICE_ERROR;
+
+ return Status;
+}
+
+EFI_STATUS SmmCommunicateFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_SMM_BASE2_PROTOCOL *pEfiSmmBase2Protocol = NULL;
+ EFI_SMM_SYSTEM_TABLE2 *Smst2 = NULL;
+ UINTN VariableSize;
+ EFI_HANDLE Handle = NULL;
+
+ Status = pBS->LocateProtocol(
+ &gEfiSmmBase2ProtocolGuid,
+ NULL,
+ &pEfiSmmBase2Protocol );
+ if( !EFI_ERROR(Status) )
+ {
+ Status = pEfiSmmBase2Protocol->GetSmstLocation(
+ pEfiSmmBase2Protocol,
+ &Smst2 );
+ if( EFI_ERROR(Status) ) return Status;
+ }
+
+ // Locate SmmFlashProtocol.
+ Status = pBS->LocateProtocol ( &gFlashSmmProtocolGuid, NULL, &gFlashSmm );
+ if (EFI_ERROR(Status)) gFlashSmm = NULL;
+
+ if( gFlashSmm != NULL )
+ {
+ gSavedFlashEraseSmm = gFlashSmm->Erase;
+ gSavedFlashWriteSmm = gFlashSmm->Write;
+ gSavedFlashUpdateSmm = gFlashSmm->Update;
+ }
+
+ // Get Flash SMI runimte memory buffer.
+ VariableSize = sizeof(gFlashBuffer);
+ Status = pRS->GetVariable ( L"FlashSmiBuffer", \
+ &gFlashSmiGuid, \
+ NULL, \
+ &VariableSize, \
+ &gFlashBuffer );
+ if ((EFI_ERROR(Status)) || (gFlashBuffer == NULL)) return Status;
+
+ // Register Flash Software SMI.
+ Status = Smst2->SmiHandlerRegister(
+ FlashSmiHandlerDummy,
+ &gFlashSmiGuid,
+ &Handle );
+
+ return Status;
+}
+#endif
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeginCriticalSection
+//
+// Description: This function calls when critical section begins. It disables interupts,
+// and Smi and fills CRITICAL_SECTION structure fields
+//
+// Input: CRITICAL_SECTION *Cs - pointer to CRITICAL_SECTION structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FlashSmiBeginCriticalSection (
+ FLASH_SMI_CRITICAL_SECTION *Cs
+)
+{
+ if (Cs->Busy) return EFI_ACCESS_DENIED;
+ Cs->IntState[0] = IoRead8(0x21);
+ Cs->IntState[1] = IoRead8(0xa1);
+ IoWrite8 (0x21, 0xff);
+ IoWrite8 (0xa1, 0xff);
+ Cs->Busy = TRUE;
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EndCriticalSection
+//
+// Description: This function calls when critical section ends. It enable interupts,
+// and Smi and fills CRITICAL_SECTION structure fields
+//
+// Input: CRITICAL_SECTION *Cs - pointer to CRITICAL_SECTION structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FlashSmiEndCriticalSection (
+ FLASH_SMI_CRITICAL_SECTION *Cs
+)
+{
+ Cs->Busy = FALSE;
+ IoWrite8 (0x21, Cs->IntState[0]);
+ IoWrite8 (0xa1, Cs->IntState[1]);
+ return EFI_SUCCESS;
+}
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverUpdate
+//
+// Description: Implementation of the Update Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash to update (must
+// be aligned to FlashBlockSize)
+// UINTN Size Size to update (must be multiple of FlashBlockSize)
+// VOID* DataBuffer - pointer to data to write to the flash part
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR depending on result
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS EFIAPI FlashDriverUpdateSmi (
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ SMI_FLASH_UPDATE *Buffer;
+
+ Status = EFI_NO_RESPONSE;
+ if ((gFlashBuffer != NULL) && (gFlash != NULL)) {
+ if (EFI_ERROR(FlashSmiBeginCriticalSection(&FlashSmiCs)))
+ return EFI_ACCESS_DENIED;
+ Buffer = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ MemSet (Buffer, sizeof(SMI_FLASH_UPDATE), 0);
+ Buffer->Subfunction = 'Fu';
+ Buffer->Signature = FSMI_SIGNATURE;
+ Buffer->FlashAddress = (UINT32)FlashAddress;
+ Buffer->Size = Size;
+ Buffer->DataBuffer = (UINT32)DataBuffer;
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+ GenerateFlashSmi();
+#else
+ IoWrite8 (SW_SMI_IO_ADDRESS, FLASH_SW_SMI);
+#endif
+ Status = Buffer->Status;
+ MemSet (Buffer, sizeof(SMI_FLASH_UPDATE), 0);
+ FlashSmiEndCriticalSection (&FlashSmiCs);
+ }
+ if (Status == EFI_NO_RESPONSE) {
+ Status = gSavedFlashUpdate (FlashAddress, Size, DataBuffer);
+ }
+ return Status;
+}
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverWrite
+//
+// Description: Implementation of the Write Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash to write to
+// UINTN Size Size to write
+// VOID* DataBuffer - pointer to data to write to the flash part
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR depending on result
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS EFIAPI FlashDriverWriteSmi (
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ SMI_FLASH_UPDATE *Buffer;
+
+ Status = EFI_NO_RESPONSE;
+ if ((gFlashBuffer != NULL) && (gFlash != NULL)) {
+ if (EFI_ERROR(FlashSmiBeginCriticalSection(&FlashSmiCs)))
+ return EFI_ACCESS_DENIED;
+ Buffer = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ MemSet (Buffer, sizeof(SMI_FLASH_UPDATE), 0);
+ Buffer->Subfunction = 'Fw';
+ Buffer->Signature = FSMI_SIGNATURE;
+ Buffer->FlashAddress = (UINT32)FlashAddress;
+ Buffer->Size = Size;
+ Buffer->DataBuffer = (UINT32)DataBuffer;
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+ GenerateFlashSmi();
+#else
+ IoWrite8 (SW_SMI_IO_ADDRESS, FLASH_SW_SMI);
+#endif
+ Status = Buffer->Status;
+ MemSet (Buffer, sizeof(SMI_FLASH_UPDATE), 0);
+ FlashSmiEndCriticalSection (&FlashSmiCs);
+ }
+ if (Status == EFI_NO_RESPONSE) {
+ Status = gSavedFlashWrite (FlashAddress, Size, DataBuffer);
+ }
+ return Status;
+}
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverErase
+//
+// Description: Implementation of the Erase Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash to erase
+// UINTN Size Size to erase
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR depending on result
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS EFIAPI FlashDriverEraseSmi (
+ VOID* FlashAddress, UINTN Size
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ SMI_FLASH_UPDATE *Buffer;
+
+ Status = EFI_NO_RESPONSE;
+ if ((gFlashBuffer != NULL) && (gFlash != NULL)) {
+ if (EFI_ERROR(FlashSmiBeginCriticalSection(&FlashSmiCs)))
+ return EFI_ACCESS_DENIED;
+ Buffer = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ MemSet (Buffer, sizeof(SMI_FLASH_UPDATE), 0);
+ Buffer->Subfunction = 'Fe';
+ Buffer->Signature = FSMI_SIGNATURE;
+ Buffer->FlashAddress = (UINT32)FlashAddress;
+ Buffer->Size = Size;
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+ GenerateFlashSmi();
+#else
+ IoWrite8 (SW_SMI_IO_ADDRESS, FLASH_SW_SMI);
+#endif
+ Status = Buffer->Status;
+ MemSet (Buffer, sizeof(SMI_FLASH_UPDATE), 0);
+ FlashSmiEndCriticalSection (&FlashSmiCs);
+ }
+ if (Status == EFI_NO_RESPONSE) {
+ gSavedFlashErase (FlashAddress, Size);
+ }
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlashSmiConnectDrivers
+//
+// Description: This function will be called when Connect Drivers Protocol is
+// installed and will update FlashProtocol function in RunTime.
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FlashSmiConnectDrivers (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ pBS->CloseEvent(Event);
+ if (gFlashBuffer == NULL) return;
+
+ if (gFlash != NULL)
+ {
+ gSavedFlashUpdate = gFlash->Update;
+ gSavedFlashErase = gFlash->Erase;
+ gSavedFlashWrite = gFlash->Write;
+ gFlash->Update = FlashDriverUpdateSmi;
+ gFlash->Erase = FlashDriverEraseSmi;
+ gFlash->Write = FlashDriverWriteSmi;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlashSmiReadyToBoot
+//
+// Description: This function will be called when Ready To Boot and will
+// restore oringinal FlashProtocol function.
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FlashSmiReadyToBoot (
+ EFI_EVENT Event,
+ VOID *Handle
+ )
+{
+ pBS->CloseEvent(Event);
+ gFlash->Update = gSavedFlashUpdate;
+ gFlash->Erase = gSavedFlashErase;
+ gFlash->Write = gSavedFlashWrite;
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlashSmiVirtualFixup
+//
+// Description:
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FlashSmiVirtualFixup (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ pRS->ConvertPointer (0, &gFlashBuffer);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NotInSmmFunction
+//
+// Description:
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_EVENT EvtVirtualFixup, EvtConnectDrivers;
+ EFI_EVENT EvtReadyToBoot;
+ VOID *RegConnectDrivers = NULL;
+
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+ EFI_EVENT EvtSmmCommunicationReady;
+ VOID *RegSmmCommunicationReady;
+
+ Status = pBS->LocateProtocol(
+ &gEfiSmmCommunicationProtocolGuid,
+ NULL,
+ &gSmmCommunicate );
+ if( EFI_ERROR(Status) )
+ {
+ Status = RegisterProtocolCallback(
+ &gEfiSmmCommunicationProtocolGuid,
+ SmmCommunicationReady,
+ NULL,
+ &EvtSmmCommunicationReady,
+ &RegSmmCommunicationReady );
+ }
+#endif
+
+ // Locate FlashProtocol.
+ Status = pBS->LocateProtocol ( &gFlashProtocolGuid, NULL, &gFlash );
+ if (EFI_ERROR(Status)) return Status;
+
+ gFlashBuffer = NULL;
+ Status = pBS->AllocatePool ( EfiRuntimeServicesData, \
+ sizeof(SMI_FLASH_UPDATE), \
+ &gFlashBuffer );
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ MemSet (gFlashBuffer, sizeof(SMI_FLASH_UPDATE), 0);
+
+ Status = pRS->SetVariable ( L"FlashSmiBuffer", \
+ &gFlashSmiGuid, \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS, \
+ sizeof(gFlashBuffer), \
+ &gFlashBuffer );
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pBS->CreateEvent ( EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE, \
+ TPL_CALLBACK, \
+ FlashSmiVirtualFixup, \
+ NULL, \
+ &EvtVirtualFixup );
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = RegisterProtocolCallback ( &gBdsConnectDriversProtocolGuid, \
+ FlashSmiConnectDrivers, \
+ NULL, \
+ &EvtConnectDrivers, \
+ &RegConnectDrivers );
+
+ Status = CreateReadyToBootEvent( TPL_CALLBACK, FlashSmiReadyToBoot, \
+ NULL, &EvtReadyToBoot );
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FlashSmiHandler
+//
+// Description:
+//
+// Input:
+//
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FlashSmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ SMI_FLASH_UPDATE *SmmFlashUpdate;
+ EFI_STATUS Status;
+
+ if ((gFlashBuffer == NULL) || \
+ ((UINT8)DispatchContext->SwSmiInputValue != FLASH_SW_SMI)) return;
+
+ SmmFlashUpdate = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ if (SmmFlashUpdate->Signature != FSMI_SIGNATURE) return;
+
+ switch (SmmFlashUpdate->Subfunction)
+ {
+ // FlashUpdate call
+ case 'Fu':
+ {
+ if (gFlashSmm == NULL) return;
+ SmmFlashUpdate = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ Status = gSavedFlashUpdateSmm ((VOID*)(SmmFlashUpdate->FlashAddress), \
+ SmmFlashUpdate->Size, \
+ (VOID*)(SmmFlashUpdate->DataBuffer));
+ }
+ break;
+
+ // FlashErase call
+ case 'Fe':
+ {
+ if (gFlashSmm == NULL) return;
+ SmmFlashUpdate = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ Status = gSavedFlashEraseSmm ((VOID*)(SmmFlashUpdate->FlashAddress), \
+ SmmFlashUpdate->Size);
+ }
+ break;
+
+ // FlashWrite call
+ case 'Fw':
+ {
+ if (gFlashSmm == NULL) return;
+ SmmFlashUpdate = (SMI_FLASH_UPDATE*)gFlashBuffer;
+ Status = gSavedFlashWriteSmm ((VOID*)(SmmFlashUpdate->FlashAddress), \
+ SmmFlashUpdate->Size, \
+ (VOID*)(SmmFlashUpdate->DataBuffer));
+ }
+ break;
+
+ // WriteEnable call
+ case 'We':
+ {
+ if (gFlashSmm == NULL) return;
+ Status = gFlashSmm->DeviceWriteEnable ();
+ }
+ break;
+
+ default: return;
+ }
+
+ SmmFlashUpdate->Status = Status;
+ SmmFlashUpdate->Subfunction = 0;
+ // Invalidate Flash SMI Buffer.
+ SmmFlashUpdate->Signature = ~FSMI_SIGNATURE;
+ return;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FlashSmiSmmSwDispatchCallback
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FlashSmiSmmSwDispatchCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+ UINTN VariableSize;
+
+ Status = pBS->LocateProtocol ( &gEfiSmmSwDispatchProtocolGuid, \
+ NULL, \
+ &pSwDispatch );
+ if (EFI_ERROR(Status)) return;
+
+ // Locate SmmFlashProtocol.
+ Status = pBS->LocateProtocol ( &gFlashSmmProtocolGuid, NULL, &gFlashSmm );
+ if (EFI_ERROR(Status)) gFlashSmm = NULL;
+
+ if( gFlashSmm != NULL )
+ {
+ gSavedFlashEraseSmm = gFlashSmm->Erase;
+ gSavedFlashWriteSmm = gFlashSmm->Write;
+ gSavedFlashUpdateSmm = gFlashSmm->Update;
+ }
+
+ // Get Flash SMI runimte memory buffer.
+ VariableSize = sizeof(gFlashBuffer);
+ Status = pRS->GetVariable ( L"FlashSmiBuffer", \
+ &gFlashSmiGuid, \
+ NULL, \
+ &VariableSize, \
+ &gFlashBuffer );
+ if ((EFI_ERROR(Status)) || (gFlashBuffer == NULL)) return ;
+
+ // Register Flash Software SMI.
+ SwContext.SwSmiInputValue = FLASH_SW_SMI;
+ Status = pSwDispatch->Register ( pSwDispatch, \
+ FlashSmiHandler, \
+ &SwContext, \
+ &Handle );
+ pBS->CloseEvent(Event);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InSmmFunction
+//
+// Description:
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_EVENT EvtFlashSmi;
+ VOID *RegFlashSmi;
+
+ Status = RegisterProtocolCallback ( &gEfiSmmSwDispatchProtocolGuid, \
+ FlashSmiSmmSwDispatchCallback, \
+ NULL, \
+ &EvtFlashSmi, \
+ &RegFlashSmi );
+ FlashSmiSmmSwDispatchCallback (EvtFlashSmi, RegFlashSmi);
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FlashSmiEntryPoint
+//
+// Description: DXE Entry Point for FlashSmi Driver.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FlashSmiEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_BOOT_MODE Bootmode;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Bootmode = GetBootMode();
+ if( (Bootmode == BOOT_ON_FLASH_UPDATE) ||
+ (Bootmode == BOOT_IN_RECOVERY_MODE) )
+ {
+ return InitSmmHandlerEx(
+ ImageHandle,
+ SystemTable,
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+ SmmCommunicateFunction,
+#else
+ InSmmFunction,
+#endif
+ NotInSmmFunction );
+ }
+ else
+ {
+ return EFI_SUCCESS;
+ }
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/FlashSmi/FlashSmi.chm b/Core/EM/FlashSmi/FlashSmi.chm
new file mode 100644
index 0000000..a1f6325
--- /dev/null
+++ b/Core/EM/FlashSmi/FlashSmi.chm
Binary files differ
diff --git a/Core/EM/FlashSmi/FlashSmi.cif b/Core/EM/FlashSmi/FlashSmi.cif
new file mode 100644
index 0000000..c6a3562
--- /dev/null
+++ b/Core/EM/FlashSmi/FlashSmi.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "FLASH SMI"
+ category = eModule
+ LocalRoot = "Core\EM\FlashSmi"
+ RefName = "Flash_SMI"
+[files]
+"FlashSmi.chm"
+"FlashSmi.sdl"
+"FlashSmi.mak"
+"FlashSmi.c"
+"FlashSmi.dxs"
+<endComponent>
diff --git a/Core/EM/FlashSmi/FlashSmi.dxs b/Core/EM/FlashSmi/FlashSmi.dxs
new file mode 100644
index 0000000..be55890
--- /dev/null
+++ b/Core/EM/FlashSmi/FlashSmi.dxs
@@ -0,0 +1,82 @@
+\//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.dxs 1 1/20/15 1:36a Tristinchou $
+//
+// $Revision: 1 $
+//
+// $Date: 1/20/15 1:36a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.dxs $
+//
+// 1 1/20/15 1:36a Tristinchou
+// [TAG] EIP196554
+// [Category] New Feature
+// [Description] Initial check-in
+// [Files] FlashSmi.cif
+// FlashSmi.chm
+// FlashSmi.sdl
+// FlashSmi.mak
+// FlashSmi.c
+// FlashSmi.dxs
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FlashSmi.dxs
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <token.h>
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/FlashProtocol.h>
+#include <Protocol/AmiDigitalSignature.h>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmCommunication.h>
+#endif
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+#if defined(USE_SMM_COMMUNICATION)&&(USE_SMM_COMMUNICATION==1)
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+#else
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+#endif
+ FLASH_SMM_PROTOCOL_GUID AND
+ AMI_SMM_DIGITAL_SIGNATURE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/FlashSmi/FlashSmi.mak b/Core/EM/FlashSmi/FlashSmi.mak
new file mode 100644
index 0000000..1f53cfd
--- /dev/null
+++ b/Core/EM/FlashSmi/FlashSmi.mak
@@ -0,0 +1,89 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.mak 1 1/20/15 1:36a Tristinchou $
+#
+# $Revision: 1 $
+#
+# $Date: 1/20/15 1:36a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.mak $
+#
+# 1 1/20/15 1:36a Tristinchou
+# [TAG] EIP196554
+# [Category] New Feature
+# [Description] Initial check-in
+# [Files] FlashSmi.cif
+# FlashSmi.chm
+# FlashSmi.sdl
+# FlashSmi.mak
+# FlashSmi.c
+# FlashSmi.dxs
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FlashSmi.mak
+#
+# Description: Make file for FlashSmi.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : FlashSmi
+
+#---------------------------------------------------------------------------
+# Create FlashSmi dependencies
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\FlashSmi.mak : $(FlashSmi_DIR)\$(@B).cif $(FlashSmi_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FlashSmi_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+#---------------------------------------------------------------------------
+# Create FlashSmi DXE Component
+#---------------------------------------------------------------------------
+FlashSmi: $(BUILD_DIR)\FlashSmi.mak FlashSmiBin
+
+FlashSmiObjs =\
+$(BUILD_DIR)\$(FlashSmi_DIR)\FlashSmi.obj
+
+FlashSmiBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FlashSmi.mak all\
+ NAME=FlashSmi\
+ GUID=755877a6-4f10-4a5c-9b2e-852123b9682c\
+ "CFLAGS=$(CFLAGS) /I$(FlashSmi_DIR)"\
+ OBJECTS="$(FlashSmiObjs)"\
+ ENTRY_POINT=FlashSmiEntry\
+ TYPE=RT_DRIVER\
+ DEPEX1=$(FlashSmi_DIR)\FlashSmi.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ COMPRESS=1
+
+#---------------------------------------------------------------------------
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/Core/EM/FlashSmi/FlashSmi.sdl b/Core/EM/FlashSmi/FlashSmi.sdl
new file mode 100644
index 0000000..223cf7b
--- /dev/null
+++ b/Core/EM/FlashSmi/FlashSmi.sdl
@@ -0,0 +1,87 @@
+#****************************************************************************
+#****************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 **
+#** **
+#** Phone (770)-246-8600 **
+#** **
+#****************************************************************************
+#****************************************************************************
+#****************************************************************************
+# $Header: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.sdl 1 1/20/15 1:36a Tristinchou $
+#
+# $Revision: 1 $
+#
+# $Date: 1/20/15 1:36a $
+#
+#****************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/FlashSmi/FlashSmi.sdl $
+#
+# 1 1/20/15 1:36a Tristinchou
+# [TAG] EIP196554
+# [Category] New Feature
+# [Description] Initial check-in
+# [Files] FlashSmi.cif
+# FlashSmi.chm
+# FlashSmi.sdl
+# FlashSmi.mak
+# FlashSmi.c
+# FlashSmi.dxs
+#
+#
+#****************************************************************************
+TOKEN
+ Name = "FlashSmiSupport"
+ Value = "1"
+ Help = "Main switch to enable Flash SMI support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "FLASH_SW_SMI"
+ Value = "0x2C"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USE_SMM_COMMUNICATION"
+ Value = "1"
+ TokenType = Integer
+ TargetH = Yes
+ Token = "SMM_COMMUNICATE_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "FlashSmi_DIR"
+End
+
+MODULE
+ Help = "Includes FlashSmi.mak to Project"
+ File = "FlashSmi.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FlashSmi.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+ Token = "SecSMIFlash_SUPPORT" "=" "0"
+
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FlashSmi.ffs"
+ Parent = "$(BUILD_DIR)\SecSMIFlash.ffs"
+ InvokeOrder = BeforeParent
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+End \ No newline at end of file
diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.c b/Core/EM/FloppyCtrl/FloppyCtrl.c
new file mode 100644
index 0000000..e096e72
--- /dev/null
+++ b/Core/EM/FloppyCtrl/FloppyCtrl.c
@@ -0,0 +1,2792 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.c 47 11/03/11 6:13a Rajeshms $
+//
+// $Revision: 47 $
+//
+// $Date: 11/03/11 6:13a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.c $
+//
+// 47 11/03/11 6:13a Rajeshms
+// [TAG] EIP73253
+// [Category] Improvement
+// [Description] Floppy Driver Follow the UEFI Driver Model as per the
+// UEFI Spec.
+// [Files] FloppyCtrl.c
+//
+// 46 10/27/09 12:24p Pats
+// EIP21981: enable RAID module hangs on checkpoint 99
+// Solution: Small delay in DMAChInit()
+//
+// 45 8/28/09 10:29a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 44 7/02/09 12:40p Yul
+// Syns to coding standards
+//
+// 43 7/02/09 10:14a Yul
+// Update Header and Tailer and syns with coding standards
+//
+// 42 6/24/09 11:12a Yul
+// Fix for the EIP 14848 AMIDIAG issue.
+// Instead of reading flag directly, check drive status and update the
+// flag.
+//
+// 41 4/13/07 1:37p Ambikas
+// Coding standards changes: added a couple of AMI_PHDRs; moved mPpiList
+// before FDCPeimEntryPoint declaration.
+//
+// 40 4/13/07 12:02p Ambikas
+//
+// 39 4/13/07 11:57a Ambikas
+// Coding standard changes: updated year in AMI copyright header and
+// footer; removed commented out function GetFloppyModel.
+//
+// 38 4/10/07 10:01a Felixp
+// LookupHID routine renamed to LookupFloppyHid to avoid linking issue
+// when linking with PS2CTRL module
+//
+// 37 3/29/07 2:53p Yakovlevs
+// Excluded GetFloppy_DP from PEI build path
+//
+// 36 3/29/07 2:09p Yakovlevs
+// Replaced Device Path manipulation with Lib function call.
+//
+// 35 1/19/07 1:04p Yakovlevs
+// Fixes for Legacy Free system EIP issue 8888
+//
+// 34 10/04/06 12:24p Markw
+// Add x64 support.
+//
+// 33 6/04/06 10:43p Ambikas
+//
+// 32 5/23/06 4:12a Felixp
+// Bug fix: missing CloseProtocol calls added
+//
+// 31 5/20/06 9:30p Felixp
+// minor bug fix: parameter was missing in ASSERT_PEI_ERROR
+//
+// 30 5/19/06 10:33p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH macros to remove
+// direct access to the Length field
+//
+// 29 5/05/06 5:21p Ambikas
+//
+// 28 4/03/06 3:55p Felixp
+// Converted to support new Super I/O infrastructure
+//
+// 27 3/13/06 2:22a Felixp
+//
+// 26 12/21/05 11:42a Ambikas
+// BIOS Recovery using floppy didn't work. The Fix:
+// -Added function CheckMRQBit_NoDelay.
+// -FddReadWriteFn: After initializing DMA registers and sending command
+// packet, we wait for the result packet. Instead of calling CheckMRQBit,
+// we call CheckMRQBit_NoDelay. Comment in that spot explains the reason
+// why.
+//
+// 25 12/20/05 10:50p Ambikas
+// Edited Revision History header part 24.
+//
+// 24 12/20/05 10:47p Ambikas
+// Minor changes:
+// -Added gPeiStall. Delay(): no longer use Locate Ppi every time for Stall Ppi.
+// -Got rid of unused bit defs for FloppyInterface->FdcFlag and consolidated remaining bit defs with bit defs for global var FdcFlag.
+// Eliminated FdcFlag. Added global var gPeiToDxeFloppyDrive0Status, which will pass state of floppy at end of pei to dxe, as FdcFlag did.
+// Replaced constants (e.g. BIT00) with names.
+// -UINT8 MediaType replaced with FLOPPY_DISK_FORMAT FloppyDiskFormat. -Added InitFloppyBlockIOLastBlockAndMaxSectors().
+// -FddReadWriteFn: For command packet, only check MRQ bit; don't check DIO bit. Got rid of other unnnessary checking of DIO/MRQ bits. Changed error message.
+// -DmaInitTable: got rid of lines writing nonexistent registers 9 and 0xd2. (This is Ich7).
+// -DmaInitForFloppy: write the clear byte register (DMA1_RESET_REG) before writing the count value.
+// -SetDataRate: Configuration Control Register is 0x3f7, not 0x3f4.
+//
+// 23 11/23/05 11:30a Felixp
+// When floppy driver is not connected, stop SIO driver
+//
+// 21 9/30/05 4:03p Felixp
+// VC7.1 warnings removed
+//
+// 20 9/28/05 12:00p Felixp
+// bug fix in UpdateIOST
+//
+// 19 8/22/05 5:32p Felixp
+// Disable Floppy when controller is not detected
+// (update vIOST variable)
+//
+// 18 8/10/05 1:06p Mandal
+// FDCReset function - Considering the return status of FloopyDriveInit
+// function.
+//
+// 17 5/14/05 5:13p Eswark
+//
+// 16 5/14/05 5:07p Eswark
+// MotorOff function included in FdcReset Function.
+//
+// 15 7/18/05 3:51p Felixp
+//
+// 14 4/01/05 4:13p Eswark
+//
+// 13 4/01/05 11:54a Eswark
+// Interface structure is getting the proper media change value from
+// "CheckMediaChange" function.
+//
+// 12 3/25/05 6:39p Felixp
+//
+// 11 3/25/05 6:09p Eswark
+// Moved code from "FDCPeimEntryPoint" to "GetBlockDeviceMediaInfo".
+//
+// 9 3/25/05 8:27a Felixp
+//
+// 8 3/25/05 7:58a Felixp
+//
+// 7 3/24/05 6:28p Felixp
+//
+// 6 3/24/05 11:51a Eswark
+// Added Floppy peim code based on recovery specifixcation.
+//
+// 4 3/22/05 4:47p Eswark
+// Added pei support.
+//
+// 3 3/04/05 11:28a Mandal
+//
+// 2 2/07/05 4:03p Yakovlevs
+//
+// 1 2/01/05 1:12a Felixp
+//
+// 7 2/01/05 12:30a Felixp
+//
+// 6 1/22/05 12:41p Felixp
+// Bug fix:
+// Last parameter to AllocatePages was UINT8* instead of
+// EFI_PHYSICAL_ADDRESS*, which
+// resulted in a stack corruption.
+//
+// 5 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 4 1/04/05 11:20a Felixp
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 8 12/17/04 7:38p Olegi
+//
+// 7 12/17/04 6:59p Felixp
+// DEBUG_MSG renamed to TRACE
+//
+// 6 12/17/04 9:39a Olegi
+//
+// 5 12/16/04 10:38a Eswark
+// Added header for the floppy driver.
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FloppyCtrl.c - Floppy Controller DXE driver
+//
+// Description:
+// This driver initializes floppy controller and produces block IO protocol
+// for floppy read and write access.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//======================================================================
+// Module specific Includes
+#include "FloppyCtrl.h"
+#include <Protocol/PCIIO.h>
+
+//======================================================================
+// GUID Definitions
+static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+static EFI_GUID gEfiAmiSioProtocolGuid = EFI_AMI_SIO_PROTOCOL_GUID;
+static EFI_GUID gDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+static EFI_GUID gEfiPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#else
+static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+#endif
+static EFI_GUID gPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+
+extern EFI_COMPONENT_NAME_PROTOCOL gFloppyCtlDriverName;
+
+static EFI_SYSTEM_TABLE *gSysTable = NULL;
+static EFI_PEI_SERVICES **PeiServices = NULL;
+
+EFI_PEI_STALL_PPI *gPeiStall = NULL;
+
+// gPeiToDxeFloppyDrive0Status:
+// The last thing Pei Recovery function GetBlockDeviceMediaInfo does is to
+// set gPeiToDxeFloppyDrive0Status to the current value of
+// FloppyInterface->FdcFlag
+// The dxe entry point FloppyCtrlStart copies gPeiToDxeFloppyDrive0Status
+// to its FloppyInterface->FdcFlag for floppy drive 0.
+// This way, FloppyCtrlStart can check if floppy drive0 has been initialized
+// in pei and if so, can bypass initialization in dxe.
+//
+UINT8 gPeiToDxeFloppyDrive0Status = FDC_FLAG_NOT_INTIALIZED;
+
+// PEIM specific code start
+static EFI_GUID guidBlockIo = EFI_PEI_VIRTUAL_BLOCK_IO_PPI;
+
+// PPI that are installed
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidBlockIo,
+ NULL
+}; //initialized by the entry point
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FDCPeimEntryPoint
+//
+// Description:
+// This is the entry point of PEIM FDC
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+#ifdef PEI_FLOPPY_CTRL
+EFI_STATUS FDCPeimEntryPoint(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **pPeiServices )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface;
+
+ PeiServices = pPeiServices;
+
+ //Allocate Storage for FLOPPY_CTRL_PROTOCOL;
+ Status = (**PeiServices).AllocatePool( PeiServices, \
+ sizeof(FLOPPY_CTRL_PROTOCOL), (VOID**)&FloppyInterface );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+ //Clear data
+ MemSet((void*)FloppyInterface, sizeof(FLOPPY_CTRL_PROTOCOL), 0 );
+
+ FloppyInterface->PeimRecBlk.GetNumberOfBlockDevices
+ = GetNumberOfBlockDevices;
+ FloppyInterface->PeimRecBlk.GetBlockDeviceMediaInfo
+ = GetBlockDeviceMediaInfo;
+ FloppyInterface->PeimRecBlk.ReadBlocks = PeimReadBlocks;
+
+ mPpiList[0].Ppi = &FloppyInterface->PeimRecBlk;
+ Status = (*PeiServices)->InstallPpi( PeiServices, &mPpiList[0] );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = (*PeiServices)->LocatePpi( PeiServices, &gEfiPeiStallPpiGuid, \
+ 0, NULL, &gPeiStall );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ return Status;
+}
+
+#endif
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetNumberOfBlockDevices
+//
+// Description:
+// This is the function to get the number of Block Devices
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This
+//
+// Output:
+// OUT UINTN *NumberBlockDevices
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS GetNumberOfBlockDevices(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices )
+{
+ *NumberBlockDevices = 01;
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetBlockDeviceMediaInfo
+//
+// Description:
+// This is the function to get the Media information of Block Devices
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+// IN UINTN DeviceIndex
+//
+// Output:
+// OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS GetBlockDeviceMediaInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo )
+{
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface \
+ = OUTTER( This, PeimRecBlk, FLOPPY_CTRL_PROTOCOL );
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ( FloppyInterface->FdcFlag & FDC_FLAG_DRIVE_INIT_ERROR ) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ else if ((FloppyInterface->FdcFlag & FDC_FLAG_DRIVE_INIT_SUCCESS) \
+ || (FloppyInterface->FdcFlag == FDC_FLAG_NOT_INTIALIZED))
+ {
+ FloppyInterface->BlkIo.Media = &(FloppyInterface->BlkIoMedia);
+ MediaInfo->DeviceType = LegacyFloppy; // Legacy Floppy
+ MediaInfo->BlockSize = 512; // SECTOR_SIZE
+ FloppyInterface->DriveNum = 00;
+ FloppyInterface->BaseAddr = 0x3F0;
+ FloppyInterface->FloppyDiskFormat = HighDensity1_44Mb;
+
+ InitFloppyBlockIOLastBlockAndMaxSectors( FloppyInterface );
+
+ // Initilize DMA channels
+ if ( FloppyInterface->FdcFlag == FDC_FLAG_NOT_INTIALIZED ) {
+ DMAChInit( );
+ }
+
+ // Initilize floppy controller
+ Status = FloppyDriveInit( FloppyInterface );
+
+ MediaInfo->MediaPresent = FloppyInterface->BlkIoMedia.MediaPresent;
+
+ if ( !(EFI_ERROR( Status ))) {
+ FloppyInterface->FdcFlag = FDC_FLAG_DRIVE_INIT_SUCCESS;
+ FloppyInterface->BlkIoMedia.BlockSize = 512;
+
+ // FloppyInterface->DMABuffer:
+ // We don't allocate a buffer because we can't get memory at
+ // an address which meets the DMA requirement of being 24 bits
+ // or less in length. Instead, we set the DMA buffer
+ // to address 0x0 as nothing is there currently.
+
+ FloppyInterface->DMABuffer = 0;
+ }
+ else {
+ FloppyInterface->TimerFlag = 01;
+ MotorOff( FloppyInterface->Event, FloppyInterface );
+ FloppyInterface->FdcFlag |= FDC_FLAG_DRIVE_INIT_ERROR;
+ }
+ }
+
+ gPeiToDxeFloppyDrive0Status = FloppyInterface->FdcFlag;
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PeimReadBlocks
+//
+// Description:
+// This is the function to Read Blocks in PEIM
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+// IN UINTN DeviceIndex,
+// IN EFI_PEI_LBA StartLBA,
+// IN UINTN BufferSize
+//
+// Output:
+// OUT VOID *Buffer
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS PeimReadBlocks(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ FLOPPY_CTRL_PROTOCOL *pFloppyInterface = OUTTER( This, PeimRecBlk, \
+ FLOPPY_CTRL_PROTOCOL );
+
+ return FdcBlkRead((EFI_BLOCK_IO_PROTOCOL*)pFloppyInterface, \
+ (UINT32)DeviceIndex, StartLBA, BufferSize, Buffer );
+}
+
+// PEIM specific code end
+//==================================================================================
+
+//==================================================================================
+// Function Prototypes for Driver Binding Protocol Interface
+//==================================================================================
+#ifdef DXE_FLOPPY_CTRL
+
+EFI_STATUS
+EFIAPI FloppyCtrlSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS
+EFIAPI FloppyCtrlStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS
+EFIAPI FloppyCtrlStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer );
+
+//==================================================================================
+// Driver binding protocol instance for Floppy Controller Driver
+//==================================================================================
+EFI_DRIVER_BINDING_PROTOCOL gFloppyCtrlDriverBindingProtocol = {
+ FloppyCtrlSupported,
+ FloppyCtrlStart,
+ FloppyCtrlStop,
+ 0x10,
+ NULL,
+ NULL
+};
+#endif
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: IsPei
+//
+// Description:
+// This is the function to check whether in PEI phase
+//
+// Input:
+// IN VOID **PeiServices,
+// IN VOID *FfsHeader
+//
+// Output:
+// OUT BOOLEAN
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN IsPei(
+ VOID *FfsHeader,
+ IN VOID *PeiServices )
+{
+ if ( !FfsHeader ) {
+ return TRUE;
+ }
+
+ if ( FfsHeader <= (VOID*)IsPei
+ || ((EFI_FFS_FILE_HEADER*)FfsHeader)->Type != \
+ EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
+ ) {
+ return FALSE;
+ }
+
+ if ( *(UINT64*)PeiServices == EFI_SYSTEM_TABLE_SIGNATURE ) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FloppyCtrlEntryPoint
+//
+// Description: Installs gIdeBusDriverBinding protocol
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS FloppyCtrlEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ #ifdef PEI_FLOPPY_CTRL
+
+ if ( IsPei( ImageHandle, SystemTable )) {
+ return FDCPeimEntryPoint((VOID*)ImageHandle, (VOID*)SystemTable );
+ }
+ #endif
+
+ #ifdef DXE_FLOPPY_CTRL
+ InitAmiLib( ImageHandle, SystemTable );
+
+ // Initialize global variable for use in this driver
+ gSysTable = SystemTable;
+
+ // initiaize the ImageHandle and DriverBindingHandle
+ gFloppyCtrlDriverBindingProtocol.DriverBindingHandle = NULL;
+ gFloppyCtrlDriverBindingProtocol.ImageHandle = ImageHandle;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gFloppyCtrlDriverBindingProtocol.DriverBindingHandle,
+ &gDriverBindingProtocolGuid,
+ &gFloppyCtrlDriverBindingProtocol,
+ &gComponentNameProtocolGuid, &gFloppyCtlDriverName,
+ NULL );
+ #endif
+ return Status;
+}
+
+#ifdef DXE_FLOPPY_CTRL
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FloppyCtrlSupported
+//
+// Description: Floppy Controller Driver Supported function
+// This function is a part of DriverBinfing protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE ControllerHandle,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+EFIAPI FloppyCtrlSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ ACPI_HID_DEVICE_PATH * acpiDP;
+ EFI_STATUS Status;
+
+ if ( !EFI_ERROR( Status = GetFloppy_DP( This, ControllerHandle, \
+ &acpiDP, EFI_OPEN_PROTOCOL_BY_DRIVER, TRUE ))
+ && LookupFloppyHid( acpiDP->HID, acpiDP->UID )) {
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FloppyCtrlStart
+//
+// Description: Floppy Controller Driver Start function
+// This function initializes floppy controller and installs
+// Floppy BlkIO protocol.
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE ControllerHandle,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+EFIAPI FloppyCtrlStart(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_STATUS Status;
+ UINT16 BaseAddr = 0;
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface;
+ AMI_SIO_PROTOCOL *AmiSio;
+ T_ITEM_LIST *ResList;
+ UINT16 FdcBase = 0;
+ UINT8 FdcDma = 0;
+ UINTN i;
+ ASLRF_S_HDR *hdr;
+ EFI_DEVICE_PATH_PROTOCOL *FloppyDevPath;
+ EFI_PHYSICAL_ADDRESS Address;
+
+ if ( !EFI_ERROR( GetFloppy_DP( This, ControllerHandle, &acpiDP, \
+ EFI_OPEN_PROTOCOL_BY_DRIVER, TRUE ))
+ && LookupFloppyHid( acpiDP->HID, acpiDP->UID ))
+ {
+ if ( acpiDP->UID == 00 )
+ {
+ if ( gPeiToDxeFloppyDrive0Status & FDC_FLAG_DRIVE_INIT_SUCCESS ) {
+ return EFI_SUCCESS;
+ }
+
+ if ( gPeiToDxeFloppyDrive0Status & FDC_FLAG_DRIVE_INIT_ERROR ) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ Status = pBS->OpenProtocol( ControllerHandle,
+ &gEfiAmiSioProtocolGuid,
+ (VOID**)&AmiSio,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if ( !(EFI_ERROR( Status )))
+ {
+ Status = AmiSio->CurrentRes( AmiSio, 00, &ResList );
+
+ if ( ResList != NULL )
+ {
+ //FDC uses 8 io ports but ports 3F6 or 376 are reserved
+ //in FDC and been used by Legacy IDE mode to avoid resource
+ //collision ASL code has 2 IO resource descriptors there
+ //
+ BOOLEAN ioset = FALSE;
+
+ //----------------
+ for ( i = 0; i < ResList->ItemCount; i++ )
+ {
+ // We need only DMA chnl and Base Addr
+ hdr = (ASLRF_S_HDR*)ResList->Items[i];
+
+ switch ( hdr->Name )
+ {
+ case ASLV_RT_FixedIO:
+
+ if ( !ioset ) {
+ FdcBase = ((ASLR_FixedIO*)hdr)->_BAS;
+ ioset = TRUE;
+ }
+ break;
+ case ASLV_RT_DMA:
+ FdcDma = ((ASLR_DMA*)hdr)->_DMA;
+ break;
+ case ASLV_RT_IO:
+
+ if ( !ioset ) {
+ FdcBase = ((ASLR_IO*)hdr)->_MIN;
+ ioset = TRUE;
+ }
+ break;
+ }
+ }
+ BaseAddr = FdcBase;
+ }
+ else {
+ Status = EFI_DEVICE_ERROR;
+ goto Error;
+ }
+ }
+ else {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // added code for DMA controller reset
+ //dma init only needs to be done once; so even if this is drive 1,
+ // we can look at gPeiToDxeFloppyDrive0Status
+ if ( gPeiToDxeFloppyDrive0Status == FDC_FLAG_NOT_INTIALIZED ) {
+ DMAChInit( );
+ }
+
+ // Allocate memory for FLOPPY_CTRL_PROTOCOL
+ FloppyInterface = MallocZ( sizeof(FLOPPY_CTRL_PROTOCOL));
+
+ if ( !FloppyInterface ) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ FloppyInterface->DriveNum = acpiDP->UID;
+
+ if ( BaseAddr == 00 )
+ {
+ if ( FloppyInterface->DriveNum == 00 ) {
+ BaseAddr = 0x3F0;
+ }
+ else if ( FloppyInterface->DriveNum == 01 )
+ {
+ BaseAddr = 0x3f0;
+ }
+ else {
+ Status = EFI_UNSUPPORTED;
+ goto Error;
+ }
+ }
+ FloppyInterface->BaseAddr = BaseAddr;
+ FloppyInterface->FloppyDiskFormat = HighDensity1_44Mb;
+
+ if ( FloppyInterface->DriveNum == 0 ) {
+ FloppyInterface->FdcFlag = gPeiToDxeFloppyDrive0Status;
+ }
+ else {
+ FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED;
+ }
+
+ // Do Floppy drive initlization (includes controller reset also.)
+
+ // Initilize floppy controller
+ Status = FloppyDriveInit( FloppyInterface );
+
+ if ( Status != EFI_DEVICE_ERROR )
+ {
+ InitFloppyBlockIO( FloppyInterface );
+ Address = DMA_MAX_ADDR_LIMIT;
+ // Allocate memory for DMA buffer
+ Status = pBS->AllocatePages( AllocateMaxAddress, \
+ EfiBootServicesData, NUM_PAGES, &Address );
+
+ // adjust memory.
+ if ( !EFI_ERROR( Status ))
+ {
+ FloppyInterface->DmaFlag = BIT00;
+
+ if (((Address + FloppyInterface->MaxSectors * SECTOR_SIZE) \
+ & 0xff0000) != (Address & 0xff0000))
+ {
+ pBS->FreePages( Address, (UINTN)NUM_PAGES );
+ Address = DMA_MAX_ADDR_LIMIT;
+ Status = pBS->AllocatePages( AllocateMaxAddress, \
+ EfiBootServicesData, NUM_PAGES * 2, &Address );
+
+ if ( EFI_ERROR( Status )) {
+ Status = pBS->FreePages( Address, NUM_PAGES * 2 );
+ }
+ else {
+ FloppyInterface->DmaFlag |= BIT01;
+
+ if (((Address + FloppyInterface->MaxSectors \
+ * SECTOR_SIZE) & 0xff0000) != (Address & 0xff0000)) {
+ Address = Address & 0xff0000;
+ }
+ }
+ }
+ }
+ FloppyInterface->DMABuffer = (UINT8*)Address;
+ }
+
+ FloppyInterface->TimerFlag = 01;
+ MotorOff( FloppyInterface->Event, FloppyInterface );
+
+ if ( EFI_ERROR( Status ))
+ {
+ pBS->FreePool( FloppyInterface );
+ FloppyInterface->FdcFlag |= FDC_FLAG_DRIVE_INIT_ERROR;
+ TRACE((-1, "FDC :Floppy driver start function - Drive initialization error\n"));
+ Status = pBS->HandleProtocol( ControllerHandle, \
+ &gDevicePathProtocolGuid, &FloppyDevPath );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ //TODO: Intel DxeMain does not like this trick
+ //Let's comments it out temporary
+ //
+ //EFI_HANDLE Handle;
+ //Status=pBS->LocateDevicePath(&gPciIoProtocolGuid, &FloppyDevPath,&Handle);
+ //if (!EFI_ERROR(Status)) pBS->DisconnectController(Handle,NULL,ControllerHandle);
+ }
+ Status = EFI_DEVICE_ERROR;
+ goto Error;
+ }
+
+ Status = pBS->CreateEvent(
+ EVT_TIMER | EVT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ (EFI_EVENT_NOTIFY)MotorOff,
+ (void*)FloppyInterface,
+ &(FloppyInterface->Event));
+
+ if ( EFI_ERROR( Status )) {
+ goto Error;
+ }
+
+ //Status = pBS->OpenProtocol(ControllerHandle, &gDevicePathProtocolGuid,
+ // (void **)&FloppyDevPath,
+ // This->DriverBindingHandle,
+ // ControllerHandle,
+ // EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ //if(EFI_ERROR(Status)) return Status;
+
+ // Install Block IO protocol for floppy controller
+ Status = pBS->InstallMultipleProtocolInterfaces( &ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ &(FloppyInterface->BlkIo),
+ NULL );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((-1, "FDC :Floppy driver start function - Out of Resources for Block IO protocol\n"));
+ goto Error;
+ }
+
+ if ( gSysTable ) {
+ pBS->SetTimer( FloppyInterface->Event, TimerRelative, 20000000 );
+ }
+ return EFI_SUCCESS;
+ }
+ Status = EFI_UNSUPPORTED;
+ goto Error;
+
+Error:
+ pBS->CloseProtocol( ControllerHandle,
+ &gEfiAmiSioProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle );
+ if( Status == EFI_OUT_OF_RESOURCES ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FloppyCtrlStop
+//
+// Description: Floppy Controller Driver Stop function
+// This functiuon uninstalls Floppy BlkIO protocol and driver
+// binding protocol.
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE ControllerHandle,
+// IN UINTN NumberOfChildren,
+// IN EFI_HANDLE *ChildHandleBuffer
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+EFIAPI FloppyCtrlStop(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer )
+{
+ EFI_STATUS Status;
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface;
+
+ if(NumberOfChildren) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = pBS->OpenProtocol( ControllerHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&FloppyInterface,
+ This->DriverBindingHandle,
+ ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // uninstall block io protocol
+ Status = pBS->UninstallMultipleProtocolInterfaces( &ControllerHandle,
+ &gEfiBlockIoProtocolGuid, &(FloppyInterface->BlkIo),
+ NULL );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ pBS->CloseProtocol( ControllerHandle,
+ &gEfiAmiSioProtocolGuid,
+ This->DriverBindingHandle,
+ ControllerHandle );
+ pBS->CloseProtocol( ControllerHandle,&gDevicePathProtocolGuid,
+ This->DriverBindingHandle,ControllerHandle);
+
+ // deallocate DMA buffer
+ if ( FloppyInterface->DmaFlag & BIT01 ) {
+ pBS->FreePages((EFI_PHYSICAL_ADDRESS)( FloppyInterface->DMABuffer ), \
+ (UINTN)NUM_PAGES * 2 );
+ }
+ pBS-> FreePages((EFI_PHYSICAL_ADDRESS)( FloppyInterface->DMABuffer ), \
+ (UINTN)NUM_PAGES );
+
+ // reset the status flag
+ FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED;
+
+ pBS->CloseEvent(FloppyInterface->Event);
+
+ // Free memory pool used by floppy interface structure
+ pBS->FreePool( FloppyInterface );
+
+ // uninstall driver binding protocol
+ //###DEBUGThis needs to be done in the Unload routine
+ //Status = pBS->UninstallMultipleProtocolInterfaces(
+ // &gFloppyCtrlDriverBindingProtocol.DriverBindingHandle,
+ // &gDriverBindingProtocolGuid, &gFloppyCtrlDriverBindingProtocol,
+ // &gComponentNameProtocolGuid, &gFloppyCtlDriverName,
+ // NULL);
+ //DEBUG END
+ return EFI_SUCCESS;
+}
+
+#endif
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FloppyDriveInit
+//
+// Description: This function initializes the floppy driver
+// Do FDC reset, turn on the motor and checks for media change
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS FloppyDriveInit(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 BaseAddr;
+ UINT16 DataReg;
+
+ FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED;
+ FloppyInterface->PrCyl = 0x0F0;
+ BaseAddr = FloppyInterface->BaseAddr;
+ DataReg = FloppyInterface->BaseAddr + 05;
+
+ CtrlReset( FloppyInterface );
+ SetDataRate( FloppyInterface );
+
+ if ( EFI_ERROR( MotorOn( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( Specify( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ FloppyInterface->BlkIoMedia.MediaPresent = TRUE;
+
+ if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED ) {
+ Status = EFI_MEDIA_CHANGED;
+ }
+
+ if ( EFI_ERROR( Calibrate( FloppyInterface )))
+ {
+ Delay( 10000 );
+
+ if ( EFI_ERROR( Calibrate( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ FloppyInterface->PrCyl = 00;
+
+ if ( Status == EFI_MEDIA_CHANGED )
+ {
+ Status = EFI_SUCCESS;
+
+ if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 )))
+ {
+ Delay( 5000 );
+
+ if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ FloppyInterface->PrCyl = 01;
+
+ if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED )
+ {
+ FloppyInterface->BlkIoMedia.MediaPresent = FALSE;
+ Status = EFI_NO_MEDIA;
+ }
+ }
+
+ FloppyInterface->FdcFlag |= FDC_FLAG_DRIVE_INIT_SUCCESS;
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitFloppyBlockIO
+//
+// Description: Initilizes the data required for floppy block IO protocol
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Refferals: EFI 1.1 specification, Chapter 11.6.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS InitFloppyBlockIO(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ FloppyInterface->BlkIo.Revision = 01;
+ FloppyInterface->BlkIo.Reset = FdcReset;
+ FloppyInterface->BlkIo.ReadBlocks = FdcBlkRead;
+ FloppyInterface->BlkIo.WriteBlocks = FdcBlkWrite;
+ FloppyInterface->BlkIo.FlushBlocks = FdcBlkFlush;
+
+ FloppyInterface->BlkIo.Media = &(FloppyInterface->BlkIoMedia);
+ FloppyInterface->BlkIoMedia.MediaId = FloppyInterface->DriveNum;
+ FloppyInterface->BlkIoMedia.RemovableMedia = TRUE;
+ FloppyInterface->BlkIoMedia.LogicalPartition = FALSE;
+ FloppyInterface->BlkIoMedia.ReadOnly = FALSE;
+ FloppyInterface->BlkIoMedia.WriteCaching = FALSE;
+ FloppyInterface->BlkIoMedia.BlockSize = 512;
+
+ InitFloppyBlockIOLastBlockAndMaxSectors( FloppyInterface );
+
+ FloppyInterface->BlkIoMedia.IoAlign = 0;
+ return Status;
+}
+
+VOID InitFloppyBlockIOLastBlockAndMaxSectors(
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ // parameters change based on floppy type
+ // LastBlock = 2 heads * MaxSectors * NumTracks - 1
+ // corresponding to 720KB drive
+ if ( FloppyInterface->FloppyDiskFormat == DoubleDensity720Kb )
+ {
+ FloppyInterface->BlkIoMedia.LastBlock = 1339; //(2*9*80-1)
+ FloppyInterface->MaxSectors = 0x09;
+ }
+ // corresponding to 1.44 MB drive
+ else if ( FloppyInterface->FloppyDiskFormat == HighDensity1_44Mb )
+ {
+ FloppyInterface->BlkIoMedia.LastBlock = 2779; //(2 * 18 * 80 -1)
+ FloppyInterface->MaxSectors = 18;
+ }
+ // corresponding to 2.88 MB drive
+ else {
+ FloppyInterface->BlkIoMedia.LastBlock = 5759; //(2 * 36 * 80 -1)
+ FloppyInterface->MaxSectors = 36;
+ }
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FdcReset
+//
+// Description: FDC reset function.
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN BOOLEAN ExtendedVerification
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS FdcReset(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ #ifdef DXE_FLOPPY_CTRL
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface = (FLOPPY_CTRL_PROTOCOL*)This;
+ BOOLEAN ErrorFlag = TRUE;
+
+ if ( EFI_ERROR( FloppyDriveInit((FLOPPY_CTRL_PROTOCOL*)This )) == \
+ EFI_DEVICE_ERROR ) {
+ ErrorFlag = FALSE;
+ }
+ pBS->SetTimer(((FLOPPY_CTRL_PROTOCOL*)This)->Event, TimerRelative, \
+ 20000000 );
+
+ // MotorOff(((FLOPPY_CTRL_PROTOCOL *)This)->Event, FloppyInterface);
+ if ( ErrorFlag == FALSE ) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+ #else
+ return EFI_UNSUPPORTED;
+ #endif
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FdcBlkRead
+//
+// Description: The ReadBlocks() function reads the requested number of
+// blocks from the device. All the blocks are read, or an
+// error is returned.
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+//
+// Output:
+// OUT VOID *Buffer
+// EFI_STATUS -
+// EFI_SUCCESS- The data was read correctly from the device.
+// EFI_DEVICE_ERROR- The device reported an error while attempting to
+// perform the read operation.
+// EFI_NO_MEDIA- There is no media in the device.
+// EFI_MEDIA_CHANGED- The MediaId is not for the current media.
+// EFI_BAD_BUFFER_SIZE- The BufferSize parameter is not a multiple
+// of the intrinsic block size of the device.
+// EFI_INVALID_PARAMETER- The read request contains LBAs that are not valid,
+// or the buffer is not on proper alignment.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS FdcBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ UINT8 RWFlag = READ_OPERATION;
+ EFI_STATUS Status;
+
+ Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, RWFlag, Buffer );
+
+ if ( Status == EFI_DEVICE_ERROR )
+ {
+ if ( EFI_ERROR( FloppyDriveInit((FLOPPY_CTRL_PROTOCOL*)This ))) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ else {
+ Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, \
+ RWFlag, Buffer );
+ }
+ }
+ ((FLOPPY_CTRL_PROTOCOL*)This)->TimerFlag = 01;
+ #ifdef DXE_FLOPPY_CTRL
+
+ if ( gSysTable ) {
+ pBS->SetTimer(((FLOPPY_CTRL_PROTOCOL*)This)->Event, TimerRelative, \
+ 20000000 );
+ }
+ #endif
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FdcBlkWrite
+//
+// Description: The WriteBlocks() function reads the requested number of
+// blocks from the device. All the blocks are read, or an
+// error is returned.
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+//
+// Output:
+// OUT VOID *Buffer
+// EFI_STATUS -
+// EFI_SUCCESS- The data was read correctly from the device.
+// EFI_DEVICE_ERROR- The device reported an error while attempting to
+// perform the read operation.
+// EFI_NO_MEDIA- There is no media in the device.
+// EFI_MEDIA_CHANGED- The MediaId is not for the current media.
+// EFI_BAD_BUFFER_SIZE- The BufferSize parameter is not a multiple
+// of the intrinsic block size of the device.
+// EFI_INVALID_PARAMETER- The read request contains LBAs that are not valid,
+// or the buffer is not on proper alignment.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS FdcBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ UINT8 RWFlag = WRITE_OPERATION;
+ EFI_STATUS Status;
+
+ Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, RWFlag, Buffer );
+
+ if ( Status == EFI_DEVICE_ERROR )
+ {
+ if ( EFI_ERROR( FloppyDriveInit((FLOPPY_CTRL_PROTOCOL*)This ))) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ else {
+ Status = FddReadWriteFn( This, MediaId, LBA, BufferSize, RWFlag, Buffer );
+ }
+ }
+ ((FLOPPY_CTRL_PROTOCOL*)This)->TimerFlag = 01;
+ #ifdef DXE_FLOPPY_CTRL
+
+ if ( gSysTable ) {
+ pBS->SetTimer(((FLOPPY_CTRL_PROTOCOL*)This)->Event, TimerRelative, \
+ 20000000 );
+ }
+ #endif
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FdcBlkFlush
+//
+// Description: The FlushBlocks() function flushes all modified data to
+// the physical block device.
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS FdcBlkFlush(
+ IN EFI_BLOCK_IO_PROTOCOL *This )
+{
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FdcBlkWrite
+//
+// Description: The WriteBlocks() function reads the requested number of
+// blocks from the device. All the blocks are read, or an
+// error is returned.
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// IN UINT8 RWFlag
+//
+// Output:
+// OUT VOID *Buffer
+// EFI_STATUS -
+// EFI_SUCCESS- The data was read correctly from the device.
+// EFI_DEVICE_ERROR- The device reported an error while attempting to
+// perform the read operation.
+// EFI_NO_MEDIA- There is no media in the device.
+// EFI_MEDIA_CHANGED- The MediaId is not for the current media.
+// EFI_BAD_BUFFER_SIZE- The BufferSize parameter is not a multiple
+// of the intrinsic block size of the device.
+// EFI_INVALID_PARAMETER- The read request contains LBAs that are not valid,
+// or the buffer is not on proper alignment.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS FddReadWriteFn(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN UINT8 RWFlag,
+ OUT VOID *Buffer )
+{
+ UINT8 Offset;
+ UINT8 Head;
+ UINT8 Cylinder;
+ UINT8 Sector;
+ UINT8 MaxSectors;
+ UINT8 *LocalBuffer;
+ UINT8 *SavedBuffer = Buffer;
+ UINT8 St2 = 0xff;
+ UINT16 DataReg;
+ UINTN Remainder;
+ UINT64 Result;
+ UINTN TrackLength;
+ UINTN NumBlks;
+ EFI_LBA LocalLBA = LBA;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface = (FLOPPY_CTRL_PROTOCOL*)This;
+ FDD_CMD_PKT *FdcRWCmdPkt = &(FloppyInterface->CmdRdWrSect);
+ UINT8 *ResultPacket = (UINT8*)(&FloppyInterface->ResultPacket);
+ UINTN CommandPacketSize = sizeof(FDD_CMD_PKT);
+ UINTN ResultPacketSize = sizeof(FDD_RESULT_PACKET);
+
+ FloppyInterface->TimerFlag = 00;
+ #ifdef DXE_FLOPPY_CTRL
+
+ if ( gSysTable ) {
+ pBS->SetTimer( FloppyInterface->Event, TimerCancel, 00 );
+ }
+ #endif
+
+ DataReg = FloppyInterface->BaseAddr + 05;
+
+ // 1. Check the correctness of the input before r/w operation
+ if ( gSysTable )
+ {
+ if ( MediaId != FloppyInterface->BlkIoMedia.MediaId ) {
+ return EFI_MEDIA_CHANGED;
+ }
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((BufferSize % BlkMedia->BlockSize) != 0 ) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ if ((((BufferSize / BlkMedia->BlockSize) + LBA - 1) > BlkMedia->LastBlock)
+ || (LBA > BlkMedia->LastBlock)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //2. Check Motor is ON or OFF
+ if ( !(FloppyInterface->FdcFlag & FDC_FLAG_MOTOR_ON))
+ {
+ SetDataRate( FloppyInterface );
+
+ // Turn on the motor
+ if ( EFI_ERROR( MotorOn( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( Specify( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ // 3. check for media change
+ if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED )
+ {
+ FloppyInterface->FdcFlag = FDC_FLAG_NOT_INTIALIZED;
+
+ if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 )))
+ {
+ Delay( 5000 );
+
+ if ( EFI_ERROR( Seek( FloppyInterface, 00, 01 ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ if ( EFI_ERROR( Seek( FloppyInterface, 00, 00 )))
+ {
+ Delay( 5000 );
+
+ if ( EFI_ERROR( Seek( FloppyInterface, 00, 00 ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ FloppyInterface->PrCyl = 00;
+
+ if ( CheckMediaChange( FloppyInterface ) == EFI_MEDIA_CHANGED )
+ {
+ FloppyInterface->BlkIoMedia.MediaPresent = FALSE;
+ return EFI_NO_MEDIA;
+ }
+ FloppyInterface->BlkIoMedia.MediaPresent = TRUE;
+ (FloppyInterface->BlkIoMedia.MediaId)++;
+ FloppyInterface->BlkIoMedia.ReadOnly = FALSE;
+ }
+
+ if ( FloppyInterface->BlkIoMedia.MediaPresent == TRUE )
+ {
+ NumBlks = BufferSize / (BlkMedia->BlockSize);
+
+ if ( RWFlag == WRITE_OPERATION )
+ {
+ if ( ChkDrSts( FloppyInterface, 00 ) != EFI_WRITE_PROTECTED )
+ {
+ // Corresponds to write operation
+ if ( EFI_ERROR( ChkDrSts( FloppyInterface, 00 )) == \
+ EFI_WRITE_PROTECTED )
+ {
+ FloppyInterface->BlkIoMedia.ReadOnly = TRUE;
+ return EFI_WRITE_PROTECTED;
+ }
+ }
+ else {
+ FloppyInterface->BlkIoMedia.ReadOnly = TRUE;
+ return EFI_WRITE_PROTECTED;
+ }
+ }
+
+ for (; NumBlks > 0;)
+ {
+ //7. Prepare Read or Write packet
+ FdcRWCmdPkt = &(FloppyInterface->CmdRdWrSect);
+
+ if ( RWFlag == READ_OPERATION ) {
+ FdcRWCmdPkt->CommandCode = RD_SECTOR_CMD \
+ + M_COMMAND_BIT_MULTITRACK_OPERATION \
+ + F_COMMAND_BIT_MFM_RECORDING_METHOD \
+ + S_COMMAND_BIT_SKIP_MODE;
+ }
+ else {
+ FdcRWCmdPkt->CommandCode = WR_SECTOR_CMD \
+ + F_COMMAND_BIT_MFM_RECORDING_METHOD;
+ }
+
+ MaxSectors = FloppyInterface->MaxSectors;
+ Result = Div64( LocalLBA, (UINT32)MaxSectors, &Remainder );
+ Head = (UINT8)( Result ) % 02;
+ Sector = (UINT8)Remainder + 01;
+ Cylinder = (UINT8)Div64( LocalLBA, (UINT32)( MaxSectors * 2 ), NULL );
+
+ //7a. Seek to the perticular cylinder
+ // Delay(4000);
+ // Standard delay =3MilliSec for Track to track change
+ if ((FloppyInterface->PrCyl != Cylinder) || (St2 == 0xFF))
+ {
+ if ( EFI_ERROR( Seek( FloppyInterface, Head, Cylinder )))
+ {
+ // Standard delay =3MilliSec for Track to track change
+ Delay( 4000 );
+
+ if ( EFI_ERROR( Seek( FloppyInterface, Head, Cylinder ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ St2 = 00;
+ FloppyInterface->PrCyl = Cylinder;
+ }
+
+ FdcRWCmdPkt->HeadDdrSel = (UINT8)( Head << 02 ) \
+ + FloppyInterface->DriveNum;
+ FdcRWCmdPkt->Cylinder = Cylinder;
+ FdcRWCmdPkt->Head = Head;
+ FdcRWCmdPkt->Sector = Sector;
+ // Sector size: 00-128Bytes, 01-256Bytes, 02-512Bytes ...07-16Kbytes
+ FdcRWCmdPkt->Size = 02;
+ FdcRWCmdPkt->TrackLength = MaxSectors;
+
+ if ((Sector + NumBlks - 1) <= MaxSectors )
+ {
+ TrackLength = NumBlks;
+ NumBlks = 00;
+ }
+ //###DEBUG
+ //else if((Head == 0 ) && (Sector == 1) && (NumBlks >= (UINTN)MaxSectors *2))
+ //{
+ // LocalLBA += (MaxSectors * 2) ;
+ // NumBlks -= (MaxSectors * 2) ;
+ // TrackLength = MaxSectors * 2;
+ // FdcRWCmdPkt->TrackLength = MaxSectors * 2;
+ //}
+ //DEBUG END
+ else if ((Sector == 1) && (NumBlks >= (UINTN)MaxSectors))
+ {
+ LocalLBA += MaxSectors;
+ NumBlks -= MaxSectors;
+ TrackLength = MaxSectors;
+ //if(RWFlag == READ_OPERATION)
+ //FdcRWCmdPkt->CommandCode= RD_TRACK_CMD + BIT06 + BIT05;
+ }
+ else {
+ LocalLBA += (MaxSectors - Sector + 1);
+ NumBlks -= (MaxSectors - Sector + 1);
+ //FdcRWCmdPkt->TrackLength = MaxSectors - Sector +1;
+ TrackLength = MaxSectors - Sector + 1;
+ }
+ // TRACE((-1,"FDC RWFunction: RWFlag:%x, Head :%x,Track :%x,Sector :%x,NBlks :%x\n",(UINT16)RWFlag, (UINT16)Head, (UINT16)Cylender, (UINT16)Sector, (UINT16)TrackLength));
+ // Standard value = 27 - 3 1/2Floppy, = 42 - 5 1/4 Floppy;
+ FdcRWCmdPkt->GapLength = 0x1b;
+ // = FF if sector size not equal to 00;
+ FdcRWCmdPkt->DataLength = 0Xff;
+
+ if ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \
+ + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE ))
+ > (EFI_PHYSICAL_ADDRESS)DMA_BUFFER_LIMIT)
+ || ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \
+ + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )) & 0xff0000)
+ != ((EFI_PHYSICAL_ADDRESS)SavedBuffer & 0xff0000)))
+ {
+ LocalBuffer = FloppyInterface->DMABuffer;
+
+ if ( RWFlag == WRITE_OPERATION ) {
+ CopyBuffer( SavedBuffer, LocalBuffer, TrackLength \
+ * SECTOR_SIZE );
+ }
+ }
+ else {
+ LocalBuffer = (UINT8*)SavedBuffer;
+ }
+
+ // 7b. Set DMA cotroller
+ DMAInitForFloppy( LocalBuffer, TrackLength, RWFlag );
+
+ // 7c. send R/W command
+ for ( Offset = 0; Offset < CommandPacketSize; Offset++ )
+ {
+ if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, ((UINT8*)FdcRWCmdPkt)[Offset] );
+ }
+
+ //7d. Get the R/W command result packet
+ for ( Offset = 0; Offset < ResultPacketSize; Offset++ )
+ {
+ // We have initialized the DMA registers and sent the command packet.
+ // Now, we wait for the result packet. We use CheckMRQBit_NoDelay instead
+ // of CheckMRQBit. This is because of the following problem, observed on
+ // the Lakeport board with South Bridge Ich7: CheckMRQBit has a loop in
+ // which it checks the MRQ bit and if it isn't set calls Delay() with a
+ // certain amount of time. CheckMRQBit_NoDelay just checks the MRQ bit
+ // continuously until it is set. The Delay function isn't used. The Delay
+ // function uses the Stall Ppi, which is in ROM. When this Stall Ppi
+ // is used while waiting for the result packet, the floppy controller
+ // always returns a DMA timeout error. That is, the floppy controller
+ // doesn't receive certain signals from the DMA controller within a required
+ // time period. The DMA transaction doesn't get started. This problem doesn't
+ // occur if we don't use the Delay function. Alternately, the problem also
+ // doesn't occur if the Stall Ppi is re-installed in RAM.
+
+ if ( EFI_ERROR( CheckMRQBit_NoDelay( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ ResultPacket[Offset] = IoRead8( DataReg );
+ }
+
+ //7d. Check for error condition
+ if ( !((*ResultPacket) & (IC1_STATUS0_BIT_INTERRUPT_CODE \
+ + IC0_STATUS0_BIT_INTERRUPT_CODE)))
+ {
+ // Read Write success
+ if ( RWFlag == READ_OPERATION )
+ { // Copy Buffer
+ if ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \
+ + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE ))
+ > (EFI_PHYSICAL_ADDRESS)DMA_BUFFER_LIMIT)
+ || ((((EFI_PHYSICAL_ADDRESS)SavedBuffer \
+ + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE )) \
+ & 0xff0000)
+ != ((EFI_PHYSICAL_ADDRESS)SavedBuffer & 0xff0000))) {
+ CopyBuffer( LocalBuffer, SavedBuffer, TrackLength \
+ * SECTOR_SIZE );
+ }
+ }
+ SavedBuffer = (UINT8*)((EFI_PHYSICAL_ADDRESS)SavedBuffer \
+ + (EFI_PHYSICAL_ADDRESS)( TrackLength * SECTOR_SIZE ));
+ }
+ else {
+ #ifdef EFI_DEBUG
+
+ if ( gSysTable ) {
+ #ifdef DXE_FLOPPY_CTRL
+ TRACE((-1, "FddReadWriteFn Error: \n"));
+ TRACE((-1, "ST0: %x, ST1: %x, ST2: %x\n", FloppyInterface->ResultPacket.Status0, FloppyInterface->ResultPacket.Status1, FloppyInterface->ResultPacket.Status2));
+ TRACE((-1, "Cylinder: %x, Head: %x, Sector Number: %x, Sector Size: %x\n", FloppyInterface->ResultPacket.Cylinder, FloppyInterface->ResultPacket.Head, FloppyInterface->ResultPacket.SectorNumber, FloppyInterface->ResultPacket.SectorSize));
+ #endif
+ }
+ else {
+ #ifdef PEI_FLOPPY_CTRL
+ PEI_TRACE((-1, PeiServices, "FddReadWriteFn: \n"));
+ PEI_TRACE((-1, PeiServices, "ST0: %x, ST1: %x, ST2: %x\n", FloppyInterface->ResultPacket.Status0, FloppyInterface->ResultPacket.Status1, FloppyInterface->ResultPacket.Status2));
+ PEI_TRACE((-1, PeiServices, "Cylinder: %x, Head: %x, Sector Number: %x, Sector Size: %x\n", FloppyInterface->ResultPacket.Cylinder, FloppyInterface->ResultPacket.Head, FloppyInterface->ResultPacket.SectorNumber, FloppyInterface->ResultPacket.SectorSize));
+ #endif
+ }
+ #endif
+ return EFI_DEVICE_ERROR;
+ }
+ } // Read command end
+ return EFI_SUCCESS;
+ }
+ return EFI_NO_MEDIA;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CopyBuffer
+//
+// Description: Copie source to destination of required size
+//
+// Input:
+// IN VOID *InBuffer,
+// IN VOID *OutBuffer,
+// IN UINTN Count
+//
+// Output:
+// VOID
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void CopyBuffer(
+ IN VOID *InBuffer,
+ IN VOID *OutBuffer,
+ IN UINTN Count )
+{
+ UINT32 *SrcBuffer = (UINT32*)InBuffer;
+ UINT32 *DestBuffer = (UINT32*)OutBuffer;
+ UINTN i = 0;
+ UINTN size = Count / 4;
+
+ for ( i = 0; i < size; i++ )
+ {
+ DestBuffer[i] = SrcBuffer[i];
+ }
+}
+
+static DMA_INIT DmaInitTable [] = {
+ // Core8 DMAC.ASM file (Fn-init_8237)
+ 0x00C, 0x000, // Reset DMA Controller 1
+ 0x008, 0x000, // Enable DMA controller 1
+
+ 0x0D8, 0x000, // Reset DMA Controller 2
+ 0x0D0, 0x000, // Enable DMA controller 2
+
+ 0x00B, 0x040, // DMA contr. 1 Ch0 single mode, addr. increment, disable auto init.
+ 0x00A, 0x000, // Enable DREQs for channel
+
+ 0x00B, 0x041, // DMA contr. 1 Ch1 single mode, addr. increment, disable auto init.
+ 0x00A, 0x001, // Enable DREQs for channel
+
+ 0x00B, 0x042, // DMA contr. 1 Ch2 single mode, addr. increment, disable auto init.
+ 0x00A, 0x002, // Enable DREQs for channel
+
+ 0x00B, 0x043, // DMA contr. 1 CH3 single mode, addr. increment, disable auto init.
+ 0x00A, 0x003, // Enable DREQs for channel
+
+ 0x0D6, 0x0c0, // DMA contr. 2 Ch4 Cascade mode, addr. increment, disable auto init.
+ 0x0d4, 0x000, // Enable DREQs for channel
+
+ 0x0D6, 0x041, // DMA contr. 2 Ch5 single mode, addr. increment, disable auto init.
+ 0x0D4, 0x001, // Enable DREQs for channel
+
+ 0x0D6, 0x042, // DMA contr. 2 Ch6 single mode, addr. increment, disable auto init.
+ 0x0D4, 0x002, // Enable DREQs for channel
+
+ 0x0D6, 0x043, // DMA contr. 2 Ch7 single mode, addr. increment, disable auto init.
+ 0x0D4, 0x003 // Enable DREQs for channel
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DMAChInit
+//
+// Description: DMA controller reset function
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void DMAChInit( )
+{
+ UINTN Index;
+
+ // DMA controller initialize
+ for ( Index = 0; Index < (sizeof(DmaInitTable) / sizeof(DMA_INIT)); Index++ )
+ {
+ IoWrite8( DmaInitTable[Index].PortAddr, DmaInitTable[Index].Value );
+ Delay(10); // Delay 10us
+ }
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DMAInitForFloppy
+//
+// Description: This function program sthe DMA-1 channel-2 for floppy read
+// and write operations
+//
+// Input:
+// IN VOID *Buffer,
+// IN UINTN NumBlks,
+// IN BOOLEAN RWFlag
+//
+// Output:
+// VOID
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void DMAInitForFloppy(
+ IN VOID *Buffer,
+ IN UINTN NumBlks,
+ IN BOOLEAN RWFlag )
+{
+ UINTN Count;
+
+ IoWrite8( DMA1_CH_MASK_REG, 0x06 );
+
+ // set mode
+ if ( RWFlag == READ_OPERATION ) {
+ IoWrite8( DMA1_MODE_REG, 0x46 );
+ }
+ else {
+ IoWrite8( DMA1_MODE_REG, 0x4a );
+ }
+
+ // set base address and page register
+ IoWrite8( DMA1_RESET_REG, 0x00 );
+ IoWrite8( DMA1_ADDR_REG, (UINT8)( UINTN ) Buffer );
+ IoWrite8( DMA1_ADDR_REG, (UINT8)((UINTN)Buffer >> 8 ));
+ IoWrite8( DMA1_PAGE_REG, (UINT8)((UINTN)Buffer >> 16 ));
+
+ // set count register
+ IoWrite8( DMA1_RESET_REG, 0x00 );
+ Count = SECTOR_SIZE * NumBlks - 1;
+ IoWrite8( DMA1_COUNT_REG, (UINT8)Count );
+ Count >>= 8;
+ IoWrite8( DMA1_COUNT_REG, (UINT8)Count );
+
+ // clear channel 2 mask
+ IoWrite8( DMA1_CH_MASK_REG, 0x02 );
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// FLOPPY COMMANDS //
+//////////////////////////////////////////////////////////////////////////////
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ChkDrSts
+//
+// Description: This function in the result phase provides the status
+// information concerning the connected drives
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface,
+// IN UINT8 HeadNum
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS ChkDrSts(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface,
+ IN UINT8 HeadNum )
+{
+ EFI_STATUS Status3;
+ UINT16 DataReg;
+
+ DataReg = FloppyInterface->BaseAddr + 05;
+
+ // Command phase
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, CHECK_DRV_STATUS_CMD );
+
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, (UINT8)((HeadNum << (UINT8)02) \
+ + FloppyInterface->DriveNum ));
+
+ // Result phase
+ if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ Status3 = IoRead8( DataReg );
+
+ if ( Status3 & BIT06 )
+ {
+ FloppyInterface->FdcFlag |= FDC_FLAG_WRITE_PROTECTED;
+ return EFI_WRITE_PROTECTED;
+ }
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Specify
+//
+// Description: This function passes the controller mechanical control
+// of the data of the connected drives.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface,
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS Specify(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ FDD_SPECIFY_CMD *FdcSpecifyCmd;
+ UINT8 Offset;
+ UINT16 DataReg;
+
+ DataReg = FloppyInterface->BaseAddr + 05;
+ FdcSpecifyCmd = &(FloppyInterface->CmdSpecify);
+
+ FdcSpecifyCmd->CommandCode = SPECIFY_CMD;
+
+ // corresponding to 720KB drive
+ if ( FloppyInterface->FloppyDiskFormat == DoubleDensity720Kb )
+ {
+ FdcSpecifyCmd->Ctrldata1 = 0xaF;
+ FdcSpecifyCmd->Ctrldata2 = 02;
+ }
+ // corresponding to 1.44 MB drive
+ else if ( FloppyInterface->FloppyDiskFormat == HighDensity1_44Mb )
+ {
+ //FdcSpecifyCmd->Ctrldata1 = 0xbF;
+ FdcSpecifyCmd->Ctrldata1 = 0xDF;
+ FdcSpecifyCmd->Ctrldata2 = 02;
+ }
+ else { // corresponding to 2.88 MB drive
+ FdcSpecifyCmd->Ctrldata1 = 0xDF;
+ FdcSpecifyCmd->Ctrldata2 = 02;
+ }
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ for ( Offset = 0; Offset < sizeof (FDD_SPECIFY_CMD); Offset++ )
+ {
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, *(((UINT8*)FdcSpecifyCmd)++));
+ }
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Calibrate
+//
+// Description: This function moves the read/write head to cylinder 0.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface,
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS Calibrate(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ EFI_STATUS Status;
+ FDD_CALIBRATE_CMD *FdcCalibrateCmd;
+ UINT8 Offset;
+ UINT8 DriveNum;
+ UINT16 DataReg;
+
+ DriveNum = FloppyInterface->DriveNum;
+ DataReg = FloppyInterface->BaseAddr + 05;
+ FdcCalibrateCmd = &(FloppyInterface->CmdCalibrate);
+
+ FdcCalibrateCmd->CommandCode = CALIBRATE_CMD;
+ FdcCalibrateCmd->HeadDdrSel = DriveNum;
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ for ( Offset = 0; Offset < sizeof (FDD_CALIBRATE_CMD); Offset++ )
+ {
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, *(((UINT8*)FdcCalibrateCmd)++));
+ }
+ Delay( 200000 );
+
+ // Send CHECK_INT_STATUS command
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, (UINT8)CHECK_INT_STATUS_CMD );
+
+ if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ Status = IoRead8( DataReg );
+
+ if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoRead8( DataReg );
+
+ if ((Status & 0xf0) == 0x20 )
+ {
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface )))
+ {
+ #ifdef EFI_DEBUG
+
+ if ( gSysTable ) {
+ #ifdef DXE_FLOPPY_CTRL
+ TRACE((-1, "FDC: CalibrateFn1 Status: %x\n", Status));
+ #endif
+ }
+ else {
+ #ifdef PEI_FLOPPY_CTRL
+ PEI_TRACE((-1, PeiServices, "FDC: CalibrateFn1 Status: %x\n", Status));
+ #endif
+ }
+ #endif
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+ }
+
+ #ifdef EFI_DEBUG
+
+ if ( gSysTable ) {
+ #ifdef DXE_FLOPPY_CTRL
+ TRACE((-1, "FDC: CalibrateFn2 Status: %x\n", Status));
+ #endif
+ }
+ else {
+ #ifdef PEI_FLOPPY_CTRL
+ PEI_TRACE((-1, PeiServices, "FDC: CalibrateFn2 Status: %x\n", Status));
+ #endif
+ }
+ #endif
+ return EFI_DEVICE_ERROR;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Seek
+//
+// Description: This function moves the read/write head to the park cylinder.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface,
+// IN UINT8 HeadNum,
+// IN UINT8 CylNum
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS Seek(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface,
+ IN UINT8 HeadNum,
+ IN UINT8 CylNum )
+{
+ EFI_STATUS Status;
+ FDD_SEEK_CMD *FdcSeekCmd;
+ UINT8 Offset;
+ UINT8 DriveNum;
+ UINT16 DataReg;
+
+ DriveNum = FloppyInterface->DriveNum;
+ DataReg = FloppyInterface->BaseAddr + 05;
+ FdcSeekCmd = &(FloppyInterface->CmdSeek);
+
+ FdcSeekCmd->CommandCode = SEEK_CMD;
+ FdcSeekCmd->DiskHeadSel = (HeadNum << 02) + DriveNum;
+ FdcSeekCmd->NewCylinder = CylNum;
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ for ( Offset = 0; Offset < sizeof (FDD_SEEK_CMD); Offset++ )
+ {
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, *(((UINT8*)FdcSeekCmd)++));
+ }
+
+ if ( FloppyInterface->PrCyl > CylNum ) {
+ Delay((FloppyInterface->PrCyl - CylNum + 1) * 4000 );
+ }
+ else {
+ Delay((CylNum - FloppyInterface->PrCyl + 1) * 4000 );
+ }
+
+ // Send CHECK_INT_STATUS command
+ if ( EFI_ERROR( CheckMSRDOBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ IoWrite8( DataReg, (UINT8)CHECK_INT_STATUS_CMD );
+
+ if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ // Delay(5000);
+ Status = IoRead8( DataReg );
+
+ //EK1123 if(EFI_ERROR(CheckMRQBit(FloppyInterface)))
+ //EK1123 return EFI_DEVICE_ERROR;
+ //EK1123 START
+ if ( EFI_ERROR( CheckMSRDIBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ //EK1123 END
+ IoRead8( DataReg );
+
+ if ((Status & 0xf0) == 0x20 ) {
+ return EFI_SUCCESS;
+ }
+ #ifdef EFI_DEBUG
+
+ if ( gSysTable ) {
+ #ifdef DXE_FLOPPY_CTRL
+ TRACE((-1, "FDC: SeekFn2 Status: %x\n", Status));
+ #endif
+ }
+ else {
+ #ifdef PEI_FLOPPY_CTRL
+ PEI_TRACE((-1, PeiServices, "FDC: SeekFn2 Status: %x\n", Status));
+ #endif
+ }
+ #endif
+ return EFI_DEVICE_ERROR;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Delay
+//
+// Description: This function introduce delay.
+//
+// Input:
+// IN UINT32 MicroSec
+//
+// Output:
+// VOID
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+static void Delay(
+ IN UINT32 MicroSec )
+{
+ if ( gSysTable ) {
+ gSysTable->BootServices->Stall( MicroSec );
+ }
+ else {
+ gPeiStall-> Stall( PeiServices, gPeiStall, MicroSec );
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// MOTOR ON/OFF FUNCTIONS //
+//////////////////////////////////////////////////////////////////////////////
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: MotorOn
+//
+// Description: This function turns the motor on, selects a perticular drive
+// and enables the DMA controller
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS MotorOn(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Data;
+ UINT16 DOR;
+ UINT8 DriveNum;
+
+ DriveNum = FloppyInterface->DriveNum;
+ DOR = FloppyInterface->BaseAddr + 02;
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ // Check motor is alredy on
+ Data = IoRead8( DOR );
+
+ if ( Data & (MOTORA_START_BIT << DriveNum)) {
+ return EFI_SUCCESS;
+ }
+
+ // Select drive and enable controller
+ Data = CTRL_EN_BIT | DMA_IRQEN_BIT;
+
+ IoWrite8( DOR, Data );
+ Delay( 10000 );
+
+ // Turn on the motor
+ if ( DriveNum == 00 )
+ {
+ Data |= DriveNum | MOTORA_START_BIT;
+ }
+ else {
+ Data |= DriveNum | MOTORB_START_BIT;
+ }
+ IoWrite8( DOR, Data );
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ FloppyInterface->FdcFlag |= FDC_FLAG_MOTOR_ON;
+ Delay( 20000 );
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: MotorOff
+//
+// Description: This function turns off the motor.
+//
+// Input:
+// IN EFI_EVENT Event,
+// IN VOID *Context
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS MotorOff(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ UINT8 Data;
+ UINT16 DOR;
+ UINT8 DriveNum;
+
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface = Context;
+
+ // create timer event
+ if ( FloppyInterface->TimerFlag != 01 ) {
+ return EFI_SUCCESS;
+ }
+
+ DriveNum = FloppyInterface->DriveNum;
+ DOR = FloppyInterface->BaseAddr + 02;
+ // Check motor is alredy on
+ //###DEBUG if(EFI_ERROR(CheckBusyBit(FloppyInterface)))
+ // return EFI_DEVICE_ERROR;
+ //if(EFI_ERROR(CheckMRQBit(FloppyInterface)))
+ // return EFI_DEVICE_ERROR;
+ //Data = IoRead8(DOR);
+ //###DEBUG END
+ // Turn OFF the motor
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ Data = IoRead8( DOR );
+
+ if ( Data & (MOTORA_START_BIT << DriveNum))
+ {
+ if ( DriveNum == 00 )
+ {
+ Data &= 0xEF;
+ IoWrite8( DOR, Data );
+ }
+
+ if ( DriveNum == 01 )
+ {
+ Data &= 0xDF;
+ IoWrite8( DOR, Data );
+ }
+ Delay( 20000 );
+ }
+ FloppyInterface->FdcFlag &= ~(FDC_FLAG_MOTOR_ON);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CtrlReset
+//
+// Description: This function resets the controller and enables the
+// Floppy disk controller and DMA controller.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS CtrlReset(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Data;
+ UINT16 DOR;
+ UINT8 DriveNum;
+
+ DriveNum = FloppyInterface->DriveNum;
+ DOR = FloppyInterface->BaseAddr + 02;
+
+ Data = 00 + DriveNum;
+
+ IoWrite8( DOR, Data );
+ Delay( 1000 );
+ Data = CTRL_EN_BIT | DMA_IRQEN_BIT | DriveNum;
+ IoWrite8( DOR, Data );
+ Delay( 1000 );
+ return EFI_SUCCESS;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// FLOPPY DRIVE PARAMETERS //
+// & //
+// TESTING FUNCTONS //
+//////////////////////////////////////////////////////////////////////////////
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SetDataRate
+//
+// Description: This function programs the data transmit rate for
+// the floppy controller.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// VOID
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void SetDataRate(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Data;
+ UINT16 CCR;
+
+ //CCR: Configuration Control Register
+ CCR = FloppyInterface->BaseAddr + 07;
+
+ if ( FloppyInterface->FloppyDiskFormat == DoubleDensity720Kb ) {
+ Data = 10; // 01 -720kbps/s-720KByte floppy in 1.44MB drive
+ }
+ else if ( FloppyInterface->FloppyDiskFormat == HighDensity1_44Mb )
+ {
+ Data = 00; // 00 -500kbits/s-1.44MB floppy in 1.44MB drive
+ }
+ else {
+ Data = 00;
+ }
+ IoWrite8( CCR, Data );
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckBusyBit
+//
+// Description: This function checks the main status register BIT04
+// to find whether controller is cutrrently is executing a
+// command or not?
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS CheckBusyBit(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Status;
+ UINT16 Count = 30000;
+ UINT16 MSR;
+
+ MSR = FloppyInterface->BaseAddr + 04;
+
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( !(Status & BUSY_BIT)) {
+ return EFI_SUCCESS;
+ }
+ Delay( 100 );
+ }
+ return EFI_TIMEOUT;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckMRQBit
+//
+// Description: This function checks the main status register BIT04 to find
+// whether data register is free to receive or provide commands.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS CheckMRQBit(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Status;
+ UINT16 Count = 30000;
+ UINT16 MSR;
+
+ MSR = FloppyInterface->BaseAddr + 04;
+
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( Status & MRQ_BIT ) {
+ return EFI_SUCCESS;
+ }
+ Delay( 100 );
+ }
+ return EFI_TIMEOUT;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckMRQBit_NoDelay
+//
+// Description: This function checks the main status register BIT04 to find
+// whether data register is free to receive or provide commands.
+// It does not use the Delay function.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS CheckMRQBit_NoDelay(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Status;
+ UINT32 Count = 500000;
+ UINT16 MSR;
+
+ MSR = FloppyInterface->BaseAddr + 04;
+
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( Status & MRQ_BIT ) {
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_TIMEOUT;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckMSRDIBit
+//
+// Description: This function checks the main status register DIO bit6.
+// Using DIO the controller indicates whether it expects data
+// from the CPU or it wants to handover staus information to it.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS CheckMSRDIBit(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ EFI_STATUS Status;
+ UINT16 Count = 20000;
+ UINT16 MSR;
+
+ MSR = FloppyInterface->BaseAddr + 04;
+
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( Status & BIT06 )
+ {
+ Count = 20000;
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( Status & MRQ_BIT ) {
+ return EFI_SUCCESS;
+ }
+ Delay( 100 );
+ }
+ return EFI_SUCCESS;
+ }
+ Delay( 100 );
+ }
+ return EFI_TIMEOUT;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckMSRDOBit
+//
+// Description: This function checks the main status register DIO bit6.
+// Using DIO the controller indicates whether it expects data
+// from the CPU or it wants to handover staus information to it.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS CheckMSRDOBit(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ EFI_STATUS Status;
+ UINT16 Count = 20000;
+ UINT16 MSR;
+
+ MSR = FloppyInterface->BaseAddr + 04;
+
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( !(Status & BIT06))
+ {
+ Count = 20000;
+ while ( Count-- )
+ {
+ Status = IoRead8( MSR );
+
+ if ( Status & MRQ_BIT ) {
+ return EFI_SUCCESS;
+ }
+ Delay( 100 );
+ }
+ return EFI_SUCCESS;
+ }
+ Delay( 100 );
+ }
+ return EFI_TIMEOUT;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CheckMediaChange
+//
+// Description: This function reads the DIR register to determine the
+// Disk change.
+//
+// Input:
+// IN FLOPPY_CTRL_PROTOCOL *FloppyInterface
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS CheckMediaChange(
+ IN FLOPPY_CTRL_PROTOCOL *FloppyInterface )
+{
+ UINT8 Data;
+ UINT16 DIR;
+
+ DIR = FloppyInterface->BaseAddr + 07;
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+ Data = IoRead8( DIR );
+
+ if ( EFI_ERROR( CheckBusyBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( CheckMRQBit( FloppyInterface ))) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( !(Data & DISK_CHG_STS_BIT))
+ {
+ FloppyInterface->BlkIoMedia.MediaPresent = TRUE;
+ return EFI_SUCCESS;
+ }
+
+ // if(gSysTable)
+ // FloppyInterface->BlkIoMedia.MediaPresent = FALSE;
+ // else
+ // FloppyInterface->PeimBlkIo.MediaPresent = FALSE;
+ return EFI_MEDIA_CHANGED;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: LookupFloppyHid
+//
+// Description: This fuction searches the Floppy device in table that
+// matches given HID and UID
+//
+// Input:
+// UINT32 hid - HID to look for
+// UINT32 uid - UID to look for
+//
+// Output:
+// TRUE if match is found, FALSE otherwise
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN LookupFloppyHid(
+ IN UINT32 hid,
+ IN UINT32 uid )
+{
+ UINT8 FloppyUid;
+
+ for ( FloppyUid = 0; FloppyUid <= 3; FloppyUid++ )
+ {
+ if ( hid == EISA_PNP_ID( 0x604 ) && uid == FloppyUid ) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+#ifdef DXE_FLOPPY_CTRL
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetFloppy_DP
+//
+// Description: This fuction returns the last node in the device
+// path for the given controller.
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN ACPI_HID_DEVICE_PATH** Floppydp,
+// IN UINT32 Attributes,
+// IN BOOLEAN Close
+//
+// Output:
+// EFI_SUCCESS or EFI_UNSUPPORTED
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS GetFloppy_DP(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN ACPI_HID_DEVICE_PATH ** Floppydp,
+ IN UINT32 Attributes,
+ IN BOOLEAN Close )
+{
+ EFI_STATUS Status;
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ EFI_DEVICE_PATH_PROTOCOL * FloppyDevPath;
+
+ // Get device path from Controller handle.
+ Status = pBS->OpenProtocol( Controller, &gDevicePathProtocolGuid,
+ (void**)&FloppyDevPath, This->DriverBindingHandle, Controller, Attributes );
+
+ if ( EFI_ERROR( Status )) {
+ if( Status == (EFI_ALREADY_STARTED || EFI_ACCESS_DENIED)){
+ return Status;
+ }
+ return EFI_UNSUPPORTED;
+ }
+
+ // FloppyDevPath is now the last node
+ acpiDP = *Floppydp = (ACPI_HID_DEVICE_PATH*)DPGetLastNode( FloppyDevPath );
+
+ Status = (acpiDP->Header.Type == ACPI_DEVICE_PATH
+ && acpiDP->Header.SubType == ACPI_DP) ? EFI_SUCCESS : EFI_UNSUPPORTED;
+
+ if ( Close ) {
+ pBS->CloseProtocol( Controller, &gDevicePathProtocolGuid,
+ This->DriverBindingHandle, Controller );
+ }
+
+ return Status;
+}
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.cif b/Core/EM/FloppyCtrl/FloppyCtrl.cif
new file mode 100644
index 0000000..fc3ca4f
--- /dev/null
+++ b/Core/EM/FloppyCtrl/FloppyCtrl.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "FloppyCtrl"
+ category = ModulePart
+ LocalRoot = "Core\EM\FloppyCtrl\"
+ RefName = "FloppyCtrl"
+[files]
+"FloppyCtrl.sdl"
+"FloppyCtrl.mak"
+"FloppyCtrl.h"
+"FloppyCtrl.c"
+"Names.c"
+"FloppyCtrlPei.dxs"
+<endComponent>
diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.h b/Core/EM/FloppyCtrl/FloppyCtrl.h
new file mode 100644
index 0000000..bf99e16
--- /dev/null
+++ b/Core/EM/FloppyCtrl/FloppyCtrl.h
@@ -0,0 +1,441 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.h 17 7/02/09 12:54p Yul $
+//
+// $Revision: 17 $
+//
+// $Date: 7/02/09 12:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.h $
+//
+// 17 7/02/09 12:54p Yul
+// Syns to coding standards
+//
+// 16 7/02/09 10:14a Yul
+// Update Header and Tailer and syns with coding standards
+//
+// 15 4/13/07 1:37p Ambikas
+// Coding standards changes: changed spaces, dashes, etc.
+//
+// 14 4/13/07 11:58a Ambikas
+//
+// 13 4/13/07 11:56a Ambikas
+// Coding standard changes: updated the year in the AMI copyright header and footer;
+// removed two commented out function headers (MotorOff, GetFloppyModel).
+//
+// 12 4/10/07 10:01a Felixp
+// LookupHID routine renamed to LookupFloppyHid to avoid linking issue
+// when linking with PS2CTRL module
+//
+// 11 9/13/06 10:08a Felixp
+//
+// 10 3/13/06 2:22a Felixp
+//
+// 9 12/21/05 11:39a Ambikas
+// Added function prototype CheckMRQBit_NoDelay.
+//
+// 8 12/20/05 10:27p Ambikas
+// Minor changes: Added new bit definitions for FLOPP_CTRL_PROTOCOL field
+// UINT8 FdcFlag. FLOPPY_CTRL_PROTOCOL: FLOPPY_DISK_FORMAT
+// FloppyDiskFormat replaces field UINT8 MediaType. Added various bit
+// other definitions.
+//
+// 7 3/25/05 6:20p Felixp
+//
+// 6 3/25/05 7:58a Felixp
+//
+// 5 3/24/05 6:29p Felixp
+// Included stall.h file.
+//
+// 4 3/24/05 11:52a Eswark
+// Added Floppy peim code based on recovery specifixcation.
+//
+// 3 3/22/05 4:47p Eswark
+// Added Pei support.
+//
+// 2 3/04/05 11:27a Mandal
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FloppyCtrl.h
+//
+// Description: FloppyCtrl deader file -
+// function delcarations, structs, constants
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#ifndef __FLOPPY_CTRL_H__
+#define __FLOPPY_CTRL_H__
+
+#if !defined(PEI_FLOPPY_CTRL) && !defined(DXE_FLOPPY_CTRL)
+ #define PEI_FLOPPY_CTRL
+ #define DXE_FLOPPY_CTRL
+#endif
+
+//----------------------------------------------------------------------
+
+#include <Efi.h>
+#include <AmiDxeLib.h>
+#include <AmiPeiLib.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimplePointer.h>
+#include <token.h>
+#include "ppi\DeviceRecoveryBlockIo.h"
+#include <Ppi\Stall.h>
+#include "protocol\BlockIo.h"
+#include "protocol\AmiSio.h"
+#include <Protocol\ComponentName.h>
+#include <Dxe.h>
+#include <AcpiRes.h>
+#include "pei.h"
+
+//----------------------------------------------------------------------
+
+#define EFI_FLOPPY_CTRL_INTERFACE_REVISION 0x00010000
+extern EFI_SYSTEM_TABLE *gSysTable;
+
+//----------------------------------------------------------------------
+
+// PEIM specific code start
+
+EFI_STATUS
+EFIAPI FdcBlkRead (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_FDC_BLK_RESET)(
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ );
+
+
+EFI_STATUS PeimReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS GetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices );
+
+EFI_STATUS GetBlockDeviceMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo );
+
+// PEIM specific code end
+//----------------------------------------------------------------------
+
+// Floppy Disk Controller Commands
+typedef struct FDD_CMD_PKT_tag
+{
+ UINT8 CommandCode;
+ UINT8 HeadDdrSel;
+ UINT8 Cylinder;
+ UINT8 Head;
+ UINT8 Sector;
+ UINT8 Size;
+ UINT8 TrackLength;
+ UINT8 GapLength;
+ UINT8 DataLength;
+} FDD_CMD_PKT;
+
+typedef struct
+{
+ UINT8 CommandCode;
+ UINT8 HeadDdrSel;
+} FDD_CALIBRATE_CMD;
+
+typedef struct
+{
+ UINT8 CommandCode;
+ UINT8 Ctrldata1;
+ UINT8 Ctrldata2;
+} FDD_SPECIFY_CMD;
+
+typedef struct
+{
+ UINT8 CommandCode;
+ UINT8 DiskHeadSel;
+ UINT8 NewCylinder;
+} FDD_SEEK_CMD;
+
+typedef struct
+{
+ UINT8 CommandCode;
+ UINT8 DiskHeadSel;
+ UINT8 Cylinder;
+ UINT8 Head;
+ UINT8 Sector;
+ UINT8 EndOfTrack;
+ UINT8 GapLength;
+ UINT8 ScanTestPause;
+} FDD_SCAN_CMD;
+
+typedef struct
+{
+ UINT8 Status0;
+ UINT8 Status1;
+ UINT8 Status2;
+ UINT8 Cylinder;
+ UINT8 Head;
+ UINT8 SectorNumber;
+ UINT8 SectorSize;
+} FDD_RESULT_PACKET;
+
+typedef enum
+{
+ DoubleDensity720Kb,
+ HighDensity1_44Mb,
+ ExtraHighDensity2_88Mb
+} FLOPPY_DISK_FORMAT;
+
+typedef struct FLOPPY_CTRL_PROTOCOL_tag
+{
+ //Don't add any member of this structure before this place add it at the end
+ EFI_BLOCK_IO_PROTOCOL BlkIo;
+ EFI_BLOCK_IO_MEDIA BlkIoMedia;
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI PeimRecBlk;
+ FDD_CMD_PKT CmdRdWrSect;
+ FDD_SEEK_CMD CmdSeek;
+ FDD_CALIBRATE_CMD CmdCalibrate;
+ FDD_SPECIFY_CMD CmdSpecify;
+ FDD_RESULT_PACKET ResultPacket;
+ UINT8 FdcFlag;
+ //Bit0 Drive initilization success
+ //Bit1 Drive initilization failure
+ //Bit2 Drive motor on
+ //Bit3 Drive write protected
+ UINT8 PrCyl; //ek1123
+ UINT8 TimerFlag; //ek1122
+ EFI_EVENT Event; //ek1122
+ UINT8 DmaFlag;
+ UINT8 DriveNum;
+ UINT8 FloppyType;
+ UINT16 BaseAddr;
+ FLOPPY_DISK_FORMAT FloppyDiskFormat;
+ UINT8 MaxSectors;
+ UINT8 *DMABuffer;
+ UINT8 *TempBuffer;
+} FLOPPY_CTRL_PROTOCOL;
+
+typedef struct DMA_INIT_tag
+{
+ UINT8 PortAddr;
+ UINT8 Value;
+} DMA_INIT;
+
+//FLOPPY_CTRL_PROTOCOL FdcFlag bit definitions
+#define FDC_FLAG_NOT_INTIALIZED 0
+#define FDC_FLAG_DRIVE_INIT_SUCCESS BIT00
+#define FDC_FLAG_DRIVE_INIT_ERROR BIT01
+#define FDC_FLAG_MOTOR_ON BIT02
+#define FDC_FLAG_WRITE_PROTECTED BIT03
+
+#define DXE_FLAG 0xAB
+#define PEI_FLAG 0xCD
+
+#define FLOPPY_DMA_CHANNAL 0x02
+#define FLOPPY_IRQ 0x06
+#define START_MOTOR 0x01
+#define STOP_MOTOR 0x00
+#define DMA_IRQ_CHAN_EN 0x01
+#define DMA_IRQ_CHAN_DIS 0x00
+#define FLOPPY_INTR 0x0e
+
+// Digital output register bits
+#define DRVA_SEL 00 // 00 =Drive0(A)
+#define DRVB_SEL 01 // 01 =Drive0(B)
+#define DRVC_SEL 02 // 02 =Drive0(C)
+#define DRVD_SEL 03 // 03 =Drive0(D)
+#define CTRL_EN_BIT BIT02
+#define DMA_IRQEN_BIT BIT03
+#define MOTORA_START_BIT BIT04
+#define MOTORB_START_BIT BIT05
+#define MOTORC_START_BIT BIT06
+#define MOTORD_START_BIT BIT07
+
+// Main Status register bits
+#define DRVA_ACT 00 // DriveA in positioning mode
+#define DRVB_ACT 01 // DriveB in positioning mode
+#define DRVC_ACT 02 // DriveC in positioning mode
+#define DRVD_ACT 03 // DriveD in positioning mode
+#define BUSY_BIT BIT04
+#define NDMA_BIT BIT05
+#define DIO_BIT BIT06
+#define MRQ_BIT BIT07
+
+// Digital Input Register bits
+#define DISK_CHG_STS_BIT BIT07
+
+// FDC Data Transfer commands
+#define RD_SECTOR_CMD 0x06
+#define RD_TRACK_CMD 0x02
+#define WR_SECTOR_CMD 0x05
+#define WR_DEL_SECTOR_CMD 0x09
+#define RD_DEL_SECTOR_CMD 0x0C
+#define RD_TRACK_CMD 0x02
+#define FORMAT_TRACK_CMD 0x0D
+
+//Bits for Read/Write Sector Command
+#define M_COMMAND_BIT_MULTITRACK_OPERATION BIT07
+#define F_COMMAND_BIT_MFM_RECORDING_METHOD BIT06
+#define S_COMMAND_BIT_SKIP_MODE BIT05
+
+//Bits for Result Status 0
+#define IC1_STATUS0_BIT_INTERRUPT_CODE BIT07
+#define IC0_STATUS0_BIT_INTERRUPT_CODE BIT06
+
+// ControlCommands
+#define RD_SECTOR_ID 0x0A
+#define CALIBRATE_CMD 0x07
+#define SPECIFY_CMD 0x03
+#define FIX_DRIVE_DATA_CMD 0x03
+#define CHECK_INT_STATUS_CMD 0x08
+#define CHECK_DRV_STATUS_CMD 0x04
+#define SEEK_CMD 0x0F
+#define PARK_RW_HEAD_CMD 0x0F
+#define INVALID_CMD 0x00
+
+// Extended commands
+#define VERIFY_COMMAND 0x16
+
+// temp remove
+#define SCAN_EQU_CMD 0x11
+#define SCAN_LOW_EQU_CMD 0x19
+#define SCAN_HIGH_EQU_CMD 0x1D
+
+// DMA registers
+
+#define DMA1_ADDR_REG 0x04
+#define DMA1_COUNT_REG 0x05
+#define DMA1_STS_REG 0x08
+#define DMA1_CMD_REG 0x08
+#define DMA1_REQ_REG 0x09
+#define DMA1_CH_MASK_REG 0x0A
+#define DMA1_MODE_REG 0x0B
+#define DMA1_RESET_REG 0x0C
+#define DMA1_INTER_REG 0x0D
+#define DMA1_MASK_REG 0x0F
+#define DMA1_PAGE_REG 0x81
+
+
+#define DMA_MAX_ADDR_LIMIT 0xFB0000
+#define DMA_BUFFER_LIMIT 0xFFFFFF
+#define READ_OPERATION 0x0F
+#define WRITE_OPERATION 0x00
+#define SECTOR_SIZE 512
+#define NUM_PAGES 05
+
+// Function declarations
+BOOLEAN LookupFloppyHid( UINT32, UINT32 );
+EFI_STATUS GetFloppy_DP( EFI_DRIVER_BINDING_PROTOCOL *, EFI_HANDLE, ACPI_HID_DEVICE_PATH * *, UINT32, BOOLEAN );
+EFI_STATUS FloppyDriveInit (
+ FLOPPY_CTRL_PROTOCOL* );
+void DriveReady (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS CheckBusyBit (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS CheckMRQBit (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS CheckMRQBit_NoDelay (
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface );
+void DMAInitForFloppy (
+ IN VOID*,
+ IN UINTN,
+ IN BOOLEAN );
+EFI_STATUS InitFloppyBlockIO ( );
+VOID InitFloppyBlockIOLastBlockAndMaxSectors (
+ FLOPPY_CTRL_PROTOCOL *FloppyInterface );
+EFI_STATUS MotorOn (
+ FLOPPY_CTRL_PROTOCOL* );
+void SetDataRate (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS CheckMediaChange (
+ FLOPPY_CTRL_PROTOCOL* );
+void Delay( UINT32 );
+EFI_STATUS Specify (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS Calibrate (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS MotorOff( EFI_EVENT, VOID* );
+EFI_STATUS FdcBlkRead (
+ IN EFI_BLOCK_IO_PROTOCOL*,
+ IN UINT32,
+ IN EFI_LBA,
+ IN UINTN,
+ OUT VOID* );
+EFI_STATUS FdcBlkWrite (
+ IN EFI_BLOCK_IO_PROTOCOL*,
+ IN UINT32,
+ IN EFI_LBA,
+ IN UINTN,
+ OUT VOID* );
+EFI_STATUS Seek( FLOPPY_CTRL_PROTOCOL *, UINT8, UINT8 );
+EFI_STATUS FddReadWriteFn (
+ IN EFI_BLOCK_IO_PROTOCOL*,
+ IN UINT32,
+ IN EFI_LBA,
+ IN UINTN,
+ IN UINT8,
+ OUT VOID* );
+EFI_STATUS FdcReset (
+ IN EFI_BLOCK_IO_PROTOCOL*,
+ IN BOOLEAN );
+EFI_STATUS FdcBlkFlush (
+ IN EFI_BLOCK_IO_PROTOCOL* );
+EFI_STATUS CtrlReset (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS ChkDrSts( FLOPPY_CTRL_PROTOCOL *, UINT8 );
+void CopyBuffer( VOID *, VOID *, UINTN );
+EFI_STATUS CheckMSRDOBit (
+ FLOPPY_CTRL_PROTOCOL* );
+EFI_STATUS CheckMSRDIBit (
+ FLOPPY_CTRL_PROTOCOL* );
+void DMAChInit ( );
+#endif // __FLOPPY_CTRL_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.mak b/Core/EM/FloppyCtrl/FloppyCtrl.mak
new file mode 100644
index 0000000..e093097
--- /dev/null
+++ b/Core/EM/FloppyCtrl/FloppyCtrl.mak
@@ -0,0 +1,94 @@
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.mak 6 4/13/07 1:36p Ambikas $
+#
+# $Revision: 6 $
+#
+# $Date: 4/13/07 1:36p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrl.mak $
+#
+# 6 4/13/07 1:36p Ambikas
+# Coding standards changes: Updated year in AMI copyright header and
+# footer;
+#
+# changed AMI_FHDR a bit.
+#
+# 5 10/13/06 4:40p Felixp
+#
+# 4 9/13/06 10:08a Felixp
+# x64 support
+#
+#**********************************************************************
+
+
+#<AMI_FHDR_START>
+#----------------------------------------------------------------------
+#
+# Name: FloppyCtrl.mak
+#
+# Description: Floppy Controller component make file
+#
+#----------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+
+all : FloppyCtrl
+
+FloppyCtrl : $(BUILD_DIR)\FloppyCtrl.mak FloppyCtrlBin
+
+$(BUILD_DIR)\FloppyCtrl.mak : $(FLOPPY_CTRL_DIR)\$(@B).cif $(FLOPPY_CTRL_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(FLOPPY_CTRL_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(x64_BUILD)"!="1"
+FloppyCtrlBin : $(AMIDXELIB) $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FloppyCtrl.mak all\
+ GUID=8B9D3EE0-4BA4-433b-9C48-4E830B3B40FD\
+ ENTRY_POINT=FloppyCtrlEntryPoint\
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX\
+ TYPE=COMBINED COMPRESS=1\
+!ELSE
+
+RecoverySrcPeiBin : $(BUILD_DIR)\FloppyCtrlPei.lib
+CORE_DXE_LIBBin : $(BUILD_DIR)\FloppyCtrlDxe.lib
+
+$(BUILD_DIR)\FloppyCtrlPei.lib $(BUILD_DIR)\FloppyCtrlDxe.lib : FloppyCtrl
+
+FloppyCtrlBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FloppyCtrl.mak all\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ "CFLAGS=$(CFLAGS) /DPEI_FLOPPY_CTRL"\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(BUILD_DIR)\FloppyCtrlPei.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\FloppyCtrl.mak all\
+ "CFLAGS=$(CFLAGS) /DDXE_FLOPPY_CTRL"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\FloppyCtrlDxe.lib
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/FloppyCtrl/FloppyCtrl.sdl b/Core/EM/FloppyCtrl/FloppyCtrl.sdl
new file mode 100644
index 0000000..26fdbf7
--- /dev/null
+++ b/Core/EM/FloppyCtrl/FloppyCtrl.sdl
@@ -0,0 +1,40 @@
+TOKEN
+ Name = "FLOPPY_CTRL_SRC_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable FloppyCtrl sources in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "FLOPPY_CTRL_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "FLOPPY_CTRL_DIR"
+End
+
+MODULE
+ Help = "Includes FloppyCtrl.mak to Project"
+ File = "FloppyCtrl.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FloppyCtrl.ffs"
+ Parent = "$(CORE_DIR)\FloppyCtrl.ffs"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FDCPeimEntryPoint,"
+ Parent = "RecoveryInitialize"
+ Token = "x64_BUILD" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = " "
+ Parent = "$(BUILD_DIR)\FloppyCtrl.ffs"
+ Token = "x64_BUILD" "=" "1"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/FloppyCtrl/FloppyCtrlPei.dxs b/Core/EM/FloppyCtrl/FloppyCtrlPei.dxs
new file mode 100644
index 0000000..339e6f2
--- /dev/null
+++ b/Core/EM/FloppyCtrl/FloppyCtrlPei.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrlPei.dxs 2 4/13/07 1:38p Ambikas $
+//
+// $Revision: 2 $
+//
+// $Date: 4/13/07 1:38p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/FloppyCtrlPei.dxs $
+//
+// 2 4/13/07 1:38p Ambikas
+// Coding standards changes: Updated year in AMI copyright header and
+// footer;
+//
+// changed spaces, dashes, etc.
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FloppyCtrlPei.dxs
+//
+// Description: PEI Dependancy expression for FloppyCtrl component
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//----------------------------------------------------------------------
+
+#include <PPI/LoadFile.h>
+
+//----------------------------------------------------------------------
+
+DEPENDENCY_START
+EFI_PEI_FV_FILE_LOADER_GUID
+AND
+EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+AND
+EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/FloppyCtrl/Names.c b/Core/EM/FloppyCtrl/Names.c
new file mode 100644
index 0000000..61d921a
--- /dev/null
+++ b/Core/EM/FloppyCtrl/Names.c
@@ -0,0 +1,240 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/Names.c 10 8/28/09 10:29a Felixp $
+//
+// $Revision: 10 $
+//
+// $Date: 8/28/09 10:29a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/FloppyCtrl/Names.c $
+//
+// 10 8/28/09 10:29a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 9 7/02/09 12:54p Yul
+// Syns to coding standards
+//
+// 8 7/02/09 10:14a Yul
+// Update Header and Tailer and syns with coding standards
+//
+// 7 4/13/07 1:38p Ambikas
+// Coding standards changes: changed spaces, dashes, etc.
+//
+// 6 4/13/07 11:59a Ambikas
+//
+// 5 4/13/07 11:53a Ambikas
+// Coding standard changes: updated the year in the AMI copyright header
+// and footer; removed commented out _asm jmp $.
+//
+// 4 4/10/07 10:01a Felixp
+// LookupHID routine renamed to LookupFloppyHid to avoid linking issue
+// when linking with PS2CTRL module
+//
+// 3 3/13/06 2:22a Felixp
+//
+// 2 3/04/05 11:31a Mandal
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Names.c
+//
+// Description: Definitions for EFI_COMPONENT_NAME_PROTOCOL
+// (GetDriverName, GetControllerName) for FloppyCtrl driver.
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//----------------------------------------------------------------------
+
+#include "FloppyCtrl.h"
+
+//----------------------------------------------------------------------
+
+EFI_STATUS FloppyGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName );
+
+EFI_STATUS FloppyGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName );
+
+extern EFI_DRIVER_BINDING_PROTOCOL gFloppyCtrlDriverBindingProtocol;
+
+CHAR16 *gFloppyDriverName = L"AMI Floppy Driver";
+CHAR16 *gFloppyCtrlName = L"Floppy Controller";
+
+//==========================================================================
+// Driver component name instance for FloppyCtl Driver
+//==========================================================================
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+#endif
+EFI_COMPONENT_NAME_PROTOCOL gFloppyCtlDriverName = {
+ FloppyGetDriverName,
+ FloppyGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: FloppyGetDriverName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// Input:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - Pointer to a three character ISO 639-2 language identifier
+// This is language of the driver name that that the caller
+// is requesting, must match one of the languages specified
+// in SupportedLanguages. Number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. Unicode string
+// is the name of the driver specified by This in the
+// language specified by Language.
+//
+// Output:
+// EFI_SUCCES - Unicode string for the Driver specified by This
+// and the language specified by Language was
+// returned in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FloppyGetDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName )
+{
+ if ( !Language || !DriverName ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) {
+ return EFI_UNSUPPORTED;
+ }
+ *DriverName = gFloppyDriverName;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: FloppyGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Input:
+// IN EFI_COMPONENT_NAME_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_HANDLE ChildHandle OPTIONAL,
+// IN CHAR8 *Language,
+//
+// Output:
+// OUT CHAR16 **ControllerName
+// A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+// EFI_SUCCESS - Unicode string for the user readable name in
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support
+// the language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FloppyGetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ ACPI_HID_DEVICE_PATH * acpiDP;
+
+ if ( !Language || !ControllerName ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Find the last device node in the device path and return "Supported"
+ // for mouse and/or keyboard depending on the SDL switches.
+ //
+ if ( !EFI_ERROR( GetFloppy_DP( &gFloppyCtrlDriverBindingProtocol, \
+ Controller, &acpiDP, EFI_OPEN_PROTOCOL_GET_PROTOCOL, FALSE ))
+ && LookupFloppyHid( acpiDP->HID, acpiDP->UID )) {
+ *ControllerName = gFloppyCtrlName;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HardwareSignature/HardwareChangeDetect.c b/Core/EM/HardwareSignature/HardwareChangeDetect.c
new file mode 100644
index 0000000..e8d50c6
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareChangeDetect.c
@@ -0,0 +1,1159 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareChangeDetect.c 9 4/22/13 8:39a Albertlin $
+//
+// $Revision: 9 $
+//
+// $Date: 4/22/13 8:39a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareChangeDetect.c $
+//
+// 9 4/22/13 8:39a Albertlin
+// [TAG] EIP121317
+// [Category] Not Specified
+// [Description] Can not enter Safe mode via PBR with onboard graphics
+// on SharkBay platform.
+// [Files] HardwareChangeDetect.c
+//
+// 8 3/01/13 3:30a Albertlin
+// [TAG] EIP115994
+// [Category] Improvement
+// [Description] Add CRC32 description.
+// [Files] HardwareChangeDetect.c
+//
+// 7 1/10/13 10:19p Albertlin
+// [TAG] EIP109014
+// [Category] Improvement
+// [Description] Currently, HardwareSignature module report signature by
+// changed count.But it cause the same hardware may have different
+// signature.
+// For solve this issue, BIOS should report signature by hardware config.
+// [Files] HardwareChangeDetect.c HardwareSignatureManagement.c
+// HardwareSignatureManagement.sdl HardwareChangeProtocol.h
+//
+// 6 12/11/12 1:46a Sophiachen
+// [TAG] EIP105523
+// [Category] New Feature
+// [Description] Record the disk configuration data to check the
+// connection change of disk.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 5 12/07/12 8:02a Sophiachen
+// [TAG] EIP108596
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] There is a build error when x64_build is off.
+// [RootCause] Fail to do the shift operation of 64 bits in IA32 mode.
+// [Solution] Use the functions Shl64() and Shr64() to do the shift
+// operation.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c
+//
+// 4 11/21/12 1:42a Sophiachen
+// [TAG] EIP105154
+// [Category] Improvement
+// [Description] Do the error check early in the function
+// GetResolutionData().
+// [Files] HardwareChangeDetect.c
+//
+// 3 11/20/12 8:27a Sophiachen
+// [TAG] EIP105154
+// [Category] New Feature
+// [Description] Record the video configuration data to check the
+// connection change of monitor.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 2 10/26/12 3:04a Sophiachen
+// Use PciIo protocol to get Vendor ID and Device ID.
+//
+// 1 9/25/12 8:57a Sophiachen
+// [TAG] EIP96258
+// [Category] New Feature
+// [Description] Update the Hardware Signature of the ACPI table FACS
+// field can notify ACPI OS whether any hardware configuration change.
+// [Files] HardwareSignatureManagement.cif
+// HardwareSignatureManagement.mak
+// HardwareSignatureManagement.dxs
+// HardwareSignatureManagement.sdl
+// HardwareSignatureManagement.c
+// HardwareChangeDetect.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HardwareChangeDetect.c
+//
+// Description: This file will detect the current Hardware configuration.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//---------------------------------------------------------------------------
+#include <Efi.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <token.h>
+#include <Protocol\HardwareChangeProtocol.h>
+#include "GenericSio.h"
+#include <Protocol\PciIo.h>
+#include <AmiCspLib.h>
+#include <Protocol\UsbIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\GraphicsOutput.h>
+#include <Protocol\EdidDiscovered.h>
+#include <Protocol\PDiskInfo.h>
+#include <Protocol\BlockIo.h>
+#include <Protocol\PIDEController.h>
+#include <Protocol\PIDEBus.h>
+
+//---------------------------------------------------------------------------
+#define IsRestoreMemoryType(MemoryType) \
+ ((MemoryType) == EfiACPIReclaimMemory || \
+ (MemoryType) == EfiACPIMemoryNVS || \
+ (MemoryType) == EfiRuntimeServicesCode || \
+ (MemoryType) == EfiRuntimeServicesData || \
+ (MemoryType) == EfiReservedMemoryType )
+
+#define VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE 128
+//---------------------------------------------------------------------------
+
+#if HARDWARE_SIGNATURE_DEBUG_MESSAGES
+CHAR8 *gMemMapType[] = {
+ "reserved ",
+ "LoaderCode",
+ "LoaderData",
+ "BS_code ",
+ "BS_data ",
+ "RT_code ",
+ "RT_data ",
+ "available ",
+ "Unusable ",
+ "ACPI_recl ",
+ "ACPI_NVS ",
+ "MemMapIO ",
+ "MemPortIO ",
+ "PAL_code "
+};
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IsDifferentMemorySize
+//
+// Description:
+// This function compares the current and previous memory sizes.
+//
+// Input:
+// IN UINT32 CurMemorySizeMb - Current memory size (MB)
+// IN UINT32 PreMemorySizeMb - Previous memory size (MB)
+//
+// Output:
+// BOOLEAN
+// TRUE - Memory sizes are different.
+// FALSE - Memory sizes are similar.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsDifferentMemorySize (
+ IN UINT32 CurMemorySizeMb,
+ IN UINT32 PreMemorySizeMb )
+{
+ BOOLEAN bDifferent = FALSE;
+
+ HWSIG_TRACE((-1,"Diff Mem Size - Cur:0x%x MB, Pre:0x%x MB\n", CurMemorySizeMb, PreMemorySizeMb));
+
+ if(CurMemorySizeMb > PreMemorySizeMb)
+ {
+ if((CurMemorySizeMb - PreMemorySizeMb) >=
+ THRESHOLD_OF_DIFFERENT_MEMORY_SIZE)
+ {
+ bDifferent = TRUE;
+ }
+ }
+ else if(CurMemorySizeMb < PreMemorySizeMb)
+ {
+ if((PreMemorySizeMb - CurMemorySizeMb) >=
+ THRESHOLD_OF_DIFFERENT_MEMORY_SIZE)
+ {
+ bDifferent = TRUE;
+ }
+ }
+
+ return bDifferent;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetMemMapData
+//
+// Description:
+// This function detects the current memory size and memory map data.
+//
+// Input:
+// IN OUT HW_MEMORY_MAP_DATA *pMemMapConfigData - Current memory map data
+// and memory size(MB)
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Detect the current memory map data successfully.
+// Other - Get MemoryMap failed or allocate pool failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetMemMapData (
+ IN OUT HW_MEMORY_MAP_DATA *pMemMapConfigData )
+{
+ EFI_STATUS Status = EFI_NOT_READY;
+ UINTN MemMapSize = 0;
+ EFI_MEMORY_DESCRIPTOR *MemMap = NULL;
+ EFI_MEMORY_DESCRIPTOR *OrigMemMap = NULL;
+ UINT64 PageCount[EfiMaxMemoryType] = {0};
+ UINTN MapKey = 0;
+ UINTN DescriptorSize = 0;
+ UINT32 DescriptorVersion = 0;
+ UINTN Index = 0;
+ UINT64 TotalMemory = 0;
+ UINTN AllocateMemMapSize = 0;
+ EFI_PHYSICAL_ADDRESS EndAddress = 0;
+ EFI_PHYSICAL_ADDRESS StartAddress = 0;
+ UINT64 EntrySize = 0;
+ UINT8 EndAddrCheckSum = 0;
+ UINT8 StartAddrCheckSum = 0;
+ UINT32 AddrData = 0;
+ UINT8 MemCheckSum = 0;
+ //Detect the memory map only once.
+ static BOOLEAN IsMemoryMapDetected = FALSE;
+ static HW_MEMORY_MAP_DATA DetectMemMapConfigData;
+ UINT32 LogVal = 0;
+
+ if(pMemMapConfigData == NULL)
+ {
+ Status = EFI_INVALID_PARAMETER;
+ goto GetMemSizeFinish;
+ }
+
+ //To detect the memory map only once
+ if(!IsMemoryMapDetected)
+ {
+ MemSet(&DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+ MemSet(pMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+ }
+ else
+ {
+ MemCpy(pMemMapConfigData, &DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA));
+ Status = EFI_SUCCESS;
+ goto GetMemSizeFinish;
+ }
+
+ Status = pBS->GetMemoryMap (&MemMapSize,
+ MemMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion);
+
+ if (Status != EFI_BUFFER_TOO_SMALL)
+ {
+ Status = EFI_NOT_READY;
+ goto GetMemSizeFinish;
+ }
+
+ MemMapSize += EFI_PAGE_SIZE;
+ AllocateMemMapSize = MemMapSize;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ AllocateMemMapSize,
+ (VOID**)&MemMap
+ );
+
+ if (EFI_ERROR (Status))
+ {
+ goto GetMemSizeFinish;
+ }
+
+ OrigMemMap = MemMap;
+ if (OrigMemMap == NULL)
+ {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto GetMemSizeFinish;
+ }
+
+ Status = pBS->GetMemoryMap (&MemMapSize,
+ MemMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion);
+
+ if (EFI_ERROR (Status))
+ {
+ goto GetMemSizeFinish;
+ }
+
+ for (Index = 0; Index < EfiMaxMemoryType; Index++)
+ {
+ PageCount[Index] = 0;
+ }
+
+ StartAddrCheckSum = 0;
+ EndAddrCheckSum = 0;
+ MemCheckSum =0;
+ for (Index = 0; Index < MemMapSize/DescriptorSize; Index++)
+ {
+ if( IsRestoreMemoryType(MemMap->Type) )
+ {
+
+ EntrySize = Shl64(MemMap->NumberOfPages, EFI_PAGE_SHIFT);
+ StartAddress = MemMap->PhysicalStart;
+ EndAddress = MemMap->PhysicalStart + EntrySize -1;
+
+ AddrData = 0;
+ AddrData = (UINT32)( Shr64(EndAddress, EFI_PAGE_SHIFT));
+ EndAddrCheckSum += (UINT8)(AddrData);
+ EndAddrCheckSum += (UINT8)(AddrData >> 8);
+ EndAddrCheckSum += (UINT8)(AddrData >> 16);
+
+ AddrData = 0;
+ AddrData = (UINT32)( Shr64(StartAddress, EFI_PAGE_SHIFT));
+ StartAddrCheckSum += (UINT8)AddrData;
+ StartAddrCheckSum += (UINT8)(AddrData >> 8);
+ StartAddrCheckSum += (UINT8)(AddrData >> 16);
+
+// HWSIG_TRACE ((-1,"%a %016lX - %016lX: # %08lX %016lX\n", gMemMapType[MemMap->Type % EfiMaxMemoryType], StartAddress, EndAddress, MemMap->NumberOfPages, MemMap->Attribute));
+
+ }
+
+ PageCount[MemMap->Type % EfiMaxMemoryType] += MemMap->NumberOfPages;
+ MemMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemMap + DescriptorSize);
+ }
+
+ MemCheckSum = (UINT8)(StartAddrCheckSum+EndAddrCheckSum);
+ HWSIG_TRACE((-1,"MemCheckSum:0x%x\n", MemCheckSum));
+
+ DetectMemMapConfigData.MemMapCheckSum = MemCheckSum;
+
+ for (Index = 0, TotalMemory = 0; Index < EfiMaxMemoryType; Index++)
+ {
+#if HARDWARE_SIGNATURE_DEBUG_MESSAGES
+ HWSIG_TRACE((-1,"%a : 0x%lx Pages\n", gMemMapType[Index], PageCount[Index]));
+#endif
+ if (PageCount[Index] == 0)
+ continue;
+
+ if ((Index == EfiLoaderCode) || (Index == EfiLoaderData) ||
+ (Index == EfiBootServicesCode) || (Index == EfiBootServicesData) ||
+ (Index == EfiRuntimeServicesCode) || (Index == EfiRuntimeServicesData) ||
+ (Index == EfiConventionalMemory) || (Index == EfiACPIReclaimMemory) ||
+ (Index == EfiACPIMemoryNVS) || (Index == EfiPalCode))
+ {
+ // Count total memory
+ TotalMemory += PageCount[Index];
+ }
+
+ }
+
+ TotalMemory += PageCount[EfiReservedMemoryType];
+ DetectMemMapConfigData.MemoryMbSize = \
+ (UINT32)(Shr64(TotalMemory, 8));//MB
+
+ //When all of the DetectMemMapConfigData are saved, this variable is
+ //changed to "TRUE"
+ IsMemoryMapDetected = TRUE;
+
+ MemCpy(pMemMapConfigData, &DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA));
+
+ HWSIG_TRACE((-1,"GetMemMapData - MemoryMbSize:0x%lx MB\n", pMemMapConfigData->MemoryMbSize));
+
+ //get log2 value for memory size and set it to memory
+ while(pMemMapConfigData->MemoryMbSize)
+ {
+ LogVal++;
+ (pMemMapConfigData->MemoryMbSize) >>= 1;
+ }
+
+ pMemMapConfigData->MemoryMbSize = 1<<LogVal;
+
+GetMemSizeFinish:
+ if (OrigMemMap != NULL)
+ {
+ pBS->FreePool(OrigMemMap);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectPS2KeyboardMouseState
+//
+// Description:
+// This function gets the SIO variable from NVRAM. It records the PS2 KB/
+// Mouse are present or not.
+//
+// Input:
+// IN HW_CONFIG_TYPE ConfigType- Current Type is PS2 KB or PS2 Mouse
+// IN OUT BOOLEAN *bPresent - Current Type is present or not.
+//
+// Output:
+// EFI_STATUS
+// EFI_NOT_FOUND - SIO variable doesn't exist.
+// EFI_SUCCESS - Get SIO variable successfully.
+//
+// Notes:
+// The tokens "DETECT_PS2_MOUSE" and "DETECT_PS2_KEYBOARD" need to enable.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectPS2KeyboardMouseState (
+ IN HW_CONFIG_TYPE ConfigType,
+ IN OUT BOOLEAN *bPresent )
+{
+ EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ SIO_DEV_STATUS SioDevStatus;
+ UINT32 SioDevStatusVarAttributes = 0;
+ EFI_STATUS Status;
+
+ //
+ // Get the SIO variable.
+ //
+ Status = pRS->GetVariable( SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ &SioDevStatusVarAttributes,
+ &SioDevStatusVarSize,
+ &SioDevStatus.DEV_STATUS);
+
+
+ if(Status == EFI_NOT_FOUND)
+ {
+ if(ConfigType == Ps2KeyboardConfigType)
+ {
+ *bPresent = FALSE;
+ }
+
+ if(ConfigType == Ps2MouseConfigType)
+ {
+ *bPresent = FALSE;
+ }
+ return Status;
+ }
+
+ if(ConfigType == Ps2KeyboardConfigType)
+ {
+ HWSIG_TRACE((-1,"SioDevStatus.Key60_64:%d, %r\n",SioDevStatus.Key60_64, Status));
+
+ if(SioDevStatus.Key60_64 == 1)
+ { //PS2 Keyboard is present
+ *bPresent = TRUE;
+ }
+ else
+ {
+ //no PS2 Keyboard
+ *bPresent = FALSE;
+ }
+ }
+
+ if(ConfigType == Ps2MouseConfigType)
+ {
+ HWSIG_TRACE((-1,"SioDevStatus.Ps2Mouse:%d, %r\n", SioDevStatus.Ps2Mouse, Status));
+
+ if(SioDevStatus.Ps2Mouse == 1)
+ { //PS2 Mouse is present
+ *bPresent = TRUE;
+ }
+ else
+ {
+ //no PS2 Mouse
+ *bPresent = FALSE;
+ }
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetPciDeviceData
+//
+// Description:
+// This function detects the current PCI number and calculate the checksum
+// of Bus number/Device number/Function number, VID/DID.
+//
+// Input:
+// IN OUT HW_PCI_DATA *pHardwarePciData -Get current PCI data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Detect the current PCI data successfully.
+// EFI_INVALID_PARAMETER - input data pHardwarePciData is NULL
+// Other - Get PCI data failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetPciDeviceData (
+ IN OUT HW_PCI_DATA *pHardwarePciData )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount = 0;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_GUID PciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+ UINT8 DevNum;
+ UINT8 FuncNum;
+ UINT16 BusNum = 0;
+ UINT16 PciNum = 0;
+ UINT16 Index;
+ UINTN PciSeg, PciBus, PciDev, PciFun;
+ UINT16 Vid, Did;
+ UINT8 BdfChecksum, VidDidChecksum;
+ UINT32 VidDid;
+
+ if(pHardwarePciData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ MemSet(pHardwarePciData, sizeof(HW_PCI_DATA), 0);
+
+ // Locate handle buffer for PCI Io Protocol.
+ Status = pBS->LocateHandleBuffer( ByProtocol, \
+ &PciIoProtocolGuid, \
+ NULL, \
+ &HandleCount, \
+ &HandleBuffer );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Vid = 0;
+ Did = 0;
+ BdfChecksum = 0;
+ VidDidChecksum = 0;
+
+ for ( Index=0; Index < HandleCount; Index++ ) {
+
+ // Handle PCI Io Protocol.
+ Status = pBS->HandleProtocol ( HandleBuffer[Index], \
+ &PciIoProtocolGuid, \
+ &PciIo );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Get PCI Io location.
+ Status = PciIo->GetLocation(PciIo, &PciSeg, &PciBus, &PciDev, &PciFun);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Skip on-board device.
+ if (PciBus == 0)
+ continue;
+
+ Status=PciIo->Pci.Read( PciIo, EfiPciIoWidthUint32, 0, 1, &VidDid);
+
+ if (EFI_ERROR (Status))
+ continue;
+
+ BusNum = (UINT16)PciBus;
+ DevNum = (UINT8)PciDev;
+ FuncNum = (UINT8)PciFun;
+ BdfChecksum += ((UINT8)PciBus + (UINT8)PciDev + (UINT8)PciFun);
+
+ // Record the PCI Vendor ID.
+ Vid = (UINT16)(VidDid);
+ // Record the PCI Device ID.
+ Did = (UINT16)(VidDid >> 16);
+
+ VidDidChecksum += ((UINT8)Vid + (UINT8)(Vid >> 8));
+ VidDidChecksum += ((UINT8)Did + (UINT8)(Did >> 8));
+
+ HWSIG_TRACE ((-1, "GetPciDeviceData: B: %X , D: %X, F: %X, Vid:%X, Did:%X\n", PciBus, PciDev, PciFun, Vid, Did));
+
+ PciNum++;
+ }
+
+ pHardwarePciData->PciNum = PciNum;
+ pHardwarePciData->BdfChecksum = 0x100 - BdfChecksum;
+ pHardwarePciData->VidDidChecksum = 0x100 - VidDidChecksum;
+
+ HWSIG_TRACE ((-1, "Pci#:%d, Checksum - BDF:%x, VID DID:%x \n",pHardwarePciData->PciNum, pHardwarePciData->BdfChecksum, pHardwarePciData->VidDidChecksum));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetUsbDeviceData
+//
+// Description:
+// This function detects the current number of the USB devices and calculate
+// the checksum of Parent Port Num/Interface Num, and VID/PID.
+//
+// Input:
+// IN OUT HW_USB_DATA *pHardwareUsbData -Get current USB data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Detect the current USB data successfully.
+// EFI_INVALID_PARAMETER - input data pHardwareUsbData is NULL
+// Other - Get USB data failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetUsbDeviceData (
+ IN OUT HW_USB_DATA *pHardwareUsbData )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCount = 0;
+ EFI_GUID EfiUsbIoProtocolGuid = EFI_USB_IO_PROTOCOL_GUID;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ EFI_USB_DEVICE_DESCRIPTOR DevDes;
+ UINT16 Vid, Pid;
+ UINT8 VidPidChecksum;
+ EFI_GUID EfiDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ UINT8 PortNumInterfaceNumChecksum = 0;
+ UINT8 InterfaceNumber, ParentPortNumber;
+ UINT16 UsbNum = 0;
+ UINT16 Index;
+
+ if(pHardwareUsbData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ MemSet(pHardwareUsbData, sizeof(HW_USB_DATA), 0);
+
+ // Locate handle buffer for USB Io Protocol
+ Status = pBS->LocateHandleBuffer( ByProtocol, \
+ &EfiUsbIoProtocolGuid, \
+ NULL, \
+ &HandleCount, \
+ &HandleBuffer );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Vid = 0;
+ Pid = 0;
+ InterfaceNumber = 0;
+ ParentPortNumber = 0;
+ VidPidChecksum = 0;
+ PortNumInterfaceNumChecksum = 0;
+
+ for ( Index=0; Index < HandleCount; Index++ ) {
+
+ // Handle USB Io Protocol
+ Status = pBS->HandleProtocol ( HandleBuffer[Index], \
+ &EfiUsbIoProtocolGuid, \
+ &UsbIo );
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Get USB Io Descriptor
+ Status = UsbIo->UsbGetDeviceDescriptor(UsbIo, &DevDes);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Vid = DevDes.IdVendor;
+ Pid = DevDes.IdProduct;
+
+ VidPidChecksum += ((UINT8)Vid + (UINT8)(Vid >> 8));
+ VidPidChecksum += ((UINT8)Pid + (UINT8)(Pid >> 8));
+
+ UsbNum++;
+ // Get USB DevicePath
+ Status = pBS->HandleProtocol ( HandleBuffer[Index], \
+ &EfiDevicePathProtocolGuid, \
+ (VOID *)&DevicePath );
+
+ if (EFI_ERROR(Status))
+ continue;
+
+ // Is USB Device Path ?
+ DevicePathNode = DevicePath;
+ while ( !isEndNode ( DevicePathNode ) ) {
+
+ if(DevicePathNode->Type == MESSAGING_DEVICE_PATH) {
+ if(DevicePathNode->SubType == MSG_USB_DP) {
+
+ ParentPortNumber = ((USB_DEVICE_PATH*)DevicePathNode)->ParentPortNumber;
+ InterfaceNumber = ((USB_DEVICE_PATH*)DevicePathNode)->InterfaceNumber;
+
+ PortNumInterfaceNumChecksum += (UINT8)(ParentPortNumber + InterfaceNumber);
+ HWSIG_TRACE ((-1, "Index:%x - USB(0x%x, 0x%x)\n", Index, ParentPortNumber, InterfaceNumber));
+ }
+
+ }
+ DevicePathNode = NEXT_NODE ( DevicePathNode );
+ }
+
+ }
+
+ pHardwareUsbData->UsbNum = UsbNum;
+ pHardwareUsbData->VidPidChecksum= 0x100 - VidPidChecksum;
+ pHardwareUsbData->PortNumInterfaceNumChecksum= 0x100 - PortNumInterfaceNumChecksum;
+
+ HWSIG_TRACE ((-1, "Usb#:%d, Checksum -VID DID:%x , PortNum_InterNum:%x\n",pHardwareUsbData->UsbNum, pHardwareUsbData->VidPidChecksum, pHardwareUsbData->PortNumInterfaceNumChecksum));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetEdidData
+//
+// Description:
+// This function gets the checksum data of EDID.
+//
+// Input:
+// IN OUT HW_VIDEO_DATA *pHardwareVideoData - Record the EdidCheckNum of
+// current Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Get the checksum data of EDID successfully.
+// EFI_NOT_FOUND - EfiEdidDiscoveredProtocolGuid interface not found.
+// EFI_INVALID_PARAMETER - Invalid parameter.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetEdidData(
+ IN OUT HW_VIDEO_DATA *pHardwareVideoData )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT8 EdidCheckSum = 0;
+ UINT32 index = 0;
+ EFI_GUID EfiEdidDiscoveredProtocolGuid = EFI_EDID_DISCOVERED_PROTOCOL_GUID;
+ EFI_EDID_DISCOVERED_PROTOCOL *EdidDiscoveredProtocol;
+
+ pHardwareVideoData->EdidCheckNum = 0;
+
+ Status = pBS->LocateProtocol (
+ &EfiEdidDiscoveredProtocolGuid,
+ NULL,
+ &EdidDiscoveredProtocol
+ );
+
+ HWSIG_TRACE((-1,"Locate EDID discovered protocol:%r\n", Status));
+
+ if (EFI_ERROR (Status))
+ return Status;
+
+ HWSIG_TRACE((-1,"EDID Size:%d\n", EdidDiscoveredProtocol->SizeOfEdid));
+
+ Status = EFI_NOT_FOUND;
+ if(EdidDiscoveredProtocol->SizeOfEdid != 0 && EdidDiscoveredProtocol->Edid != NULL){
+ if( EdidDiscoveredProtocol->SizeOfEdid == VESA_BIOS_EXTENSIONS_EDID_BLOCK_SIZE){
+ index = EdidDiscoveredProtocol->SizeOfEdid -1;
+ EdidCheckSum = EdidDiscoveredProtocol->Edid[index];
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ if(!EFI_ERROR(Status)){
+ pHardwareVideoData->EdidCheckNum = EdidCheckSum;
+ HWSIG_TRACE((-1,"EdidCheckNum:0x%x\n", EdidCheckSum));
+
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetResolutionData
+//
+// Description:
+// This function gets all resolution data and calculates the the checksum of
+// resolution data.
+//
+// Input:
+// IN OUT HW_VIDEO_DATA *pHardwareVideoData -Record the ResolutionChecksum of
+// current Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Get all resolution data and calculate checksum successfully.
+// EFI_NOT_FOUND - EfiGraphicsOutputProtocolGuid interface not found.
+// EFI_INVALID_PARAMETER - Invalid parameter.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetResolutionData(
+ IN OUT HW_VIDEO_DATA *pHardwareVideoData )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT8 TotalCheckSum = 0;
+ UINT8 CheckSum = 0;
+ UINT8 k;
+ EFI_GUID EfiGraphicsOutputProtocolGuid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
+ EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
+ UINT32 TmpSum = 0;
+ BOOLEAN bGetData = TRUE;
+
+ pHardwareVideoData->ResolutionChecksum = 0;
+
+
+ Status = pBS->LocateProtocol (
+ &EfiGraphicsOutputProtocolGuid,
+ NULL,
+ &GraphicsOutput
+ );
+
+
+ if(EFI_ERROR (Status))
+ {
+ bGetData = FALSE;
+ }
+ else
+ {
+ // 1. TmpSum: Sum of HorizontalResolution + VerticalResolution
+ // 2. CheckSum: the checksum of TmpSum
+ // 3. TotalCheckSum: sum of CheckSum
+ TmpSum = GraphicsOutput->Mode->Info->HorizontalResolution + \
+ GraphicsOutput->Mode->Info->VerticalResolution;
+
+ CheckSum = (UINT8)TmpSum;
+ for( k = 1; k < sizeof(TmpSum); k++) {
+ TmpSum = TmpSum >> 8;
+ CheckSum = CheckSum + (UINT8)TmpSum;
+ }
+
+ TotalCheckSum = TotalCheckSum + CheckSum;
+ }
+
+ if(bGetData)
+ {
+ TotalCheckSum = 0x100 - TotalCheckSum;
+ HWSIG_TRACE((-1,"Resolution TotalCheckSum:0x%x\n", TotalCheckSum));
+ pHardwareVideoData->ResolutionChecksum = TotalCheckSum;
+ Status = EFI_SUCCESS;
+ }
+ else
+ {
+ Status = EFI_NOT_FOUND;
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetVideoData
+//
+// Description:
+// This function gets the checksum of EDID and calculates the checksum
+// of all resolution data.
+//
+// Input:
+// IN OUT HW_VIDEO_DATA *pHardwareVideoData -Get current Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Get the current Video data successfully.
+// EFI_UNSUPPORTED - Get the current Video data failed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetVideoData(
+ OUT HW_VIDEO_DATA *pHardwareVideoData )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ BOOLEAN bSuccess = FALSE;
+
+ Status = GetEdidData(pHardwareVideoData);
+ HWSIG_TRACE((-1,"GetEdidData: %r\n", Status));
+
+ if(!EFI_ERROR(Status))
+ bSuccess = TRUE;
+
+ Status = GetResolutionData(pHardwareVideoData);
+ HWSIG_TRACE((-1,"GetResolutionData: %r\n", Status));
+
+ if(!EFI_ERROR(Status))
+ bSuccess = TRUE;
+
+ if(bSuccess)
+ return EFI_SUCCESS;
+
+ return EFI_UNSUPPORTED;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CRC32
+//
+// Description: A cyclic redundancy check (CRC) is an error-detecting code
+// commonly used in storage devices to detect accidental changes to raw data.
+//
+// Input:
+// IN UINT8 *fpData - Pointer to the start of data that will be calculated.
+// IN UINT16 Length - The length of data
+// IN UINT8 ExtenData - The count(byte) of zero data that will be included
+// when calculate CRC32.
+//
+// Output:
+// UINT32 CRC32 checksum
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+CRC32 (
+ IN UINT8 *fpData,
+ IN UINT16 Length,
+ IN UINT8 ExtenData )
+{
+ UINT32 CRC32Table[256] = {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d };
+
+ UINT32 CRC = 0xFFFFFFFF;
+ UINT16 i;
+
+ for ( i=0; i<Length; i++)
+ CRC = CRC32Table[(CRC^(*(fpData+i)))& 0xff] ^ (CRC>>8);
+
+ // include pad into checksum, pad value is 0
+ for ( i=0; i<ExtenData; i++)
+ CRC = CRC32Table[(CRC^0)& 0xff] ^ (CRC>>8);
+
+ return ~CRC;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDiskInfoData
+//
+// Description: Calculate the disk checksum , include port number and serial number.
+// Calculate the CRC32 checksum with port number and serial number of all disks.
+//
+// Input:
+// OUT HW_DISK_DATA *pHardwareDiskData - Get current Disk data.
+//
+// Output:
+// HW_DISK_DATA *pHardwareDiskData
+// CRC32 checksum - Get the current Disk data successfully.
+// ~(CDSchecksum of previous disk data) - Get the current Disk data failure.
+//
+// EFI_STATUS
+// EFI_SUCCESS - Get the current Disk data successfully.
+// EFI_NOT_READY - Get the current Disk data unsuccessfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetDiskInfoData(
+ OUT HW_DISK_DATA *pHardwareDiskData)
+{
+ EFI_GUID EfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+ EFI_HANDLE *HandleBuffer;
+ EFI_DISK_INFO_PROTOCOL *DiskInfo;
+ IDENTIFY_DATA *IdentifyDriveInfo = NULL;
+ DISK_STRUCTURE *DiskStructure;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINTN NumberOfDISKHandles = 0;
+ UINT8 Index;
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+ UINT32 BufferSize;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &EfiDiskInfoProtocolGuid,
+ NULL,
+ &NumberOfDISKHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ return EFI_NOT_READY;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof (IDENTIFY_DATA),
+ &IdentifyDriveInfo
+ );
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ return EFI_NOT_READY;
+ }
+
+ DiskStructure = MallocZ (NumberOfDISKHandles*sizeof (DISK_STRUCTURE));
+
+ BufferSize = sizeof (IDENTIFY_DATA);
+
+ for (Index = 0; Index < NumberOfDISKHandles; Index++)
+ {
+ Status = pBS->HandleProtocol (
+ HandleBuffer[Index],
+ &EfiDiskInfoProtocolGuid,
+ &DiskInfo
+ );
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ pBS->FreePool(DiskStructure);
+ return EFI_NOT_READY;
+ }
+
+ Status = DiskInfo->WhichIde(DiskInfo,&IdeChannel,&IdeDevice);
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ pBS->FreePool(DiskStructure);
+ return EFI_NOT_READY;
+ }
+
+ Status = DiskInfo->Identify(DiskInfo,IdentifyDriveInfo,&BufferSize);
+ if (EFI_ERROR(Status))
+ {
+ pHardwareDiskData->CDSchecksum = 0xff;
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+ pBS->FreePool(DiskStructure);
+ return EFI_NOT_READY;
+ }
+
+ DiskStructure[Index].Portnumber = IdeChannel;
+
+ MemCpy( &DiskStructure[Index].Serialnumber[0], &IdentifyDriveInfo->Serial_Number_10[0], 20);
+
+ }
+ pHardwareDiskData->CDSchecksum = CRC32(&DiskStructure[0].Portnumber,(UINT16)(NumberOfDISKHandles*sizeof(DISK_STRUCTURE)),0);
+
+ pBS->FreePool(DiskStructure);
+ pBS->FreePool(HandleBuffer);
+ pBS->FreePool(IdentifyDriveInfo);
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.c b/Core/EM/HardwareSignature/HardwareSignatureManagement.c
new file mode 100644
index 0000000..83d0494
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.c
@@ -0,0 +1,1874 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.c 12 1/15/14 2:27a Albertlin $
+//
+// $Revision: 12 $
+//
+// $Date: 1/15/14 2:27a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.c $
+//
+// 12 1/15/14 2:27a Albertlin
+// [TAG] EIP147244
+// [Category] Not Specified
+// [Description] Delay the HardwareSignature excutes sequence after
+// function UpdateAml().
+// [Files] HardwareSignatureManagement.c
+//
+// 11 1/13/14 3:42a Albertlin
+// [TAG] EIP147244
+// [Category] Not Specified
+// [Description] Correct the SetupCount variable.
+// [Files] HardwareSignatureManagement.c
+//
+// 10 1/09/14 7:59a Albertlin
+//
+// 9 8/27/13 4:28a Albertlin
+// [TAG] EIP133658
+// [Category] Not Specified
+// [Description] "UpdateHardwareSignatureData" elink doesn't run only
+// once on readytoboot event.
+// [Files] HardwareSignatureManagement.c
+//
+// 8 1/10/13 10:24p Albertlin
+// [TAG] EIP109014
+// [Category] Improvement
+// [Description] Currently, HardwareSignature module report signature by
+// changed count.But it cause the same hardware may have different
+// signature.
+// For solve this issue, BIOS should report signature by hardware config.
+// [Files] HardwareChangeDetect.c HardwareSignatureManagement.c
+// HardwareSignatureManagement.sdl HardwareChangeProtocol.h
+//
+// 7 12/12/12 3:40a Sophiachen
+// [TAG] EIP106129
+// [Category] New Feature
+// [Description] After BIOS firmware update, the hardware signature will
+// be changed.
+// [Files] HardwareSignatureManagement.c,
+// HardwareSignatureManagement.mak, HardwareSignatureManagement.sdl
+//
+// 6 12/11/12 1:48a Sophiachen
+// [TAG] EIP105523
+// [Category] New Feature
+// [Description] Record the disk configuration data to check the
+// connection change of disk.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 5 12/07/12 8:10a Sophiachen
+// [TAG] EIP108596
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] There is a build error when x64_build is off.
+// [RootCause] Fail to do the shift operation of 64 bits in IA32 mode.
+// [Solution] Use the functions Shl64() and Shr64() to do the shift
+// operation.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c
+//
+// 4 11/20/12 8:25a Sophiachen
+// [TAG] EIP105154
+// [Category] New Feature
+// [Description] Record the video configuration data to check the
+// connection change of monitor.
+// [Files] HardwareChangeDetect.c, HardwareSignatureManagement.c,
+// HardwareChangeProtocol.h
+//
+// 3 10/18/12 7:51a Sophiachen
+//
+// 2 9/27/12 11:48p Sophiachen
+// [TAG] EIP102484
+// [Category] New Feature
+// [Description] Update the CHM file
+// [Files] HardwareSignatureManagement.c
+// HardwareSignatureManagement.cif
+//
+// 1 9/25/12 8:57a Sophiachen
+// [TAG] EIP96258
+// [Category] New Feature
+// [Description] Update the Hardware Signature of the ACPI table FACS
+// field can notify ACPI OS whether any hardware configuration change.
+// [Files] HardwareSignatureManagement.cif
+// HardwareSignatureManagement.mak
+// HardwareSignatureManagement.dxs
+// HardwareSignatureManagement.sdl
+// HardwareSignatureManagement.c
+// HardwareChangeDetect.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HardwareSignatureManagement.c
+//
+// Description: This file will install the HardwareChange protocol. The
+// hardware signature data of the FACS table will be
+// updated when the ReadyToBoot event is signaled.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//---------------------------------------------------------------------------
+#include <Efi.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <token.h>
+#include <Acpi.h>
+#include <Acpi20.h>
+#include <Protocol\AcpiSupport.h>
+#include <Protocol\HardwareChangeProtocol.h>
+
+//---------------------------------------------------------------------------
+
+#define HARDWARE_CONFIG_DATA_VARIABLE L"HardwareConfigData"
+
+#define FIRMWARE_UPDATE_COUNT_VARIABLE L"FirmwareUpdateCountVar"
+
+#define AMITSE_EVENT_BEFORE_BOOT_GUID \
+ { 0x3677770f, 0xefb2, 0x43b2, 0xb8, 0xae, 0xb3, 0x2, 0xe9, 0x60, 0x48, 0x82 }
+
+#define EFI_AMI_LEGACYBOOT_PROTOCOL_GUID \
+ {0x120d28aa, 0x6630, 0x46f0, 0x81, 0x57, 0xc0, 0xad, 0xc2, 0x38, 0x3b, 0xf5};
+
+//---------------------------------------------------------------------------
+
+EFI_GUID gHardwareChangeProtocolGuid = HARDWARE_CHANGE_PROTOCOL_GUID;
+EFI_GUID gHardwareConfigDataGuid = HARDWARE_CONFIG_DATA_GUID;
+EFI_GUID gFirmwareUpdateCountGuid = FIRMWARE_UPDATE_COUNT_GUID;
+EFI_GUID HSBeforeBootProtocolGuid = AMITSE_EVENT_BEFORE_BOOT_GUID;
+EFI_GUID HSBeforeLegacyBootProtocolGuid = EFI_AMI_LEGACYBOOT_PROTOCOL_GUID;
+
+
+//Record the hardware change flag if there are some hardware
+//configurations changed.
+UINT32 gHardwareConfigChangeFlag = 0;
+//Record the current hardware configuration data.
+HW_CONFIG_DATA gCurHardwareConfigData;
+//Record firmware update times
+UINT32 gFwUpdateCount = 0;
+//Record called times if other module called this protocol
+UINT32 gExternalFunCallCount = 0;
+
+//---------------------------------------------------------------------------
+//Function prototype
+EFI_STATUS
+SetHardwareConfigDataToNvram (
+ IN HW_CONFIG_DATA *HardwareConfigData );
+
+EFI_STATUS
+GetFirmwareUpdateCountFromNvram (
+ IN OUT UINT32 *ChangeTime );
+
+EFI_STATUS
+SetFirmwareUpdateCountToNvram (
+ IN UINT32 *ChangeTime );
+//---------------------------------------------------------------------------
+
+//Functions defined in HardwareChangeDetect.c
+BOOLEAN
+IsDifferentMemorySize(
+ UINT32 CurMemorySizeMb,
+ UINT32 PreMemorySizeMb);
+
+EFI_STATUS
+GetMemMapData(
+ IN OUT HW_MEMORY_MAP_DATA *pMemMapConfigData);
+
+EFI_STATUS
+GetPciDeviceData(
+ IN OUT HW_PCI_DATA *pHardwarePciData);
+
+EFI_STATUS
+GetUsbDeviceData(
+ IN OUT HW_USB_DATA *pHardwareUsbData);
+
+EFI_STATUS
+GetDiskInfoData(
+ OUT HW_DISK_DATA *pHardwareDiskData);
+
+EFI_STATUS
+DetectPS2KeyboardMouseState(
+ IN HW_CONFIG_TYPE ConfigType,
+ IN OUT BOOLEAN *bPresent);
+
+EFI_STATUS
+GetVideoData(
+ OUT HW_VIDEO_DATA *pHardwareVideoData );
+//Functions to detect and set Hardware configurations
+EFI_STATUS
+DetectAndSetPs2KeyboardConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetPs2MouseConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetMemorySizeConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetMemoryMapConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+EFI_STATUS
+DetectAndSetPciConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+
+#if HARDWARE_SIGNATURE_USB_CHANGE
+EFI_STATUS
+DetectAndSetUsbConfig(
+ IN UINTN BufferSize,
+ IN VOID *Buffer);
+#endif
+
+EFI_STATUS
+DetectAndSetVideoConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer );
+
+EFI_STATUS
+DetectAndSetDiskConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer );
+
+EFI_STATUS
+UpdateHardwareSignatureData(
+ IN EFI_EVENT Event,
+ IN VOID *Context);
+
+VOID
+QuickSort(
+ IN OUT UINT32 *ChecksumData,
+ IN UINT32 LChecksumPosition,
+ IN UINT32 RChecksumPosition);
+
+//---------------------------------------------------------------------------
+
+EFI_HARDWARE_CHANGE_PROTOCOL gHardwareChangeProtocol =
+{
+ SetHardwareConfigData,
+ GetHardwareConfigDataFromNvram,
+ SignalHardwareSignatureChange
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: HardwareSignatureUpdateEntryPoint
+//
+// Description:
+// This function is a driver entry point that installs a protocol to set the
+// hardware configurations. These hardware configurations will determine the
+// hardware ignature of the FACS table.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Function executed successfully.
+// Other - Function executed unsuccessfully.
+//
+// Notes:
+// This function also creates ReadyToBoot event to update the hardware
+// signature of the FACS table.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+HardwareSignatureEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+
+ EFI_STATUS Status;
+ EFI_EVENT ReadyToBootEvent;
+ EFI_HANDLE HardwareChangeHandle = NULL;
+ UINT8 i;
+ VOID *Registration;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //clear the global variable first
+ MemSet(&gCurHardwareConfigData, sizeof(HW_CONFIG_DATA),0);
+
+ //Initial ReturnChecksum
+ for(i=0;i<LIMIT_PROTOCOL_CALLED;i++)
+ gCurHardwareConfigData.ReturnChecksum[i] = 0;
+
+ Status = pBS->InstallProtocolInterface(
+ &HardwareChangeHandle,
+ &gHardwareChangeProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gHardwareChangeProtocol
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ RegisterProtocolCallback(
+ &HSBeforeBootProtocolGuid,
+ UpdateHardwareSignatureData,
+ NULL,
+ &ReadyToBootEvent,
+ &Registration
+ );
+
+ RegisterProtocolCallback(
+ &HSBeforeLegacyBootProtocolGuid,
+ UpdateHardwareSignatureData,
+ NULL,
+ &ReadyToBootEvent,
+ &Registration
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetHardwareConfigData
+//
+// Description:
+// This function sets the hardware configuration data for each configuration
+// type.
+//
+// Input:
+// IN HW_CONFIG_TYPE ConfigType - the hardware configuration type
+// IN UINTN BufferSize - Size of buffer for recording the
+// configuration data.
+// IN VOID *Buffer - Buffer for recording the config. data.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ConfigType is incorrect. Buffer is NULL and
+// BufferSize is not zero.
+// EFI_SUCCESS - Set the hardware configuration data successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetHardwareConfigData (
+ IN HW_CONFIG_TYPE ConfigType,
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+
+ if( (Buffer == NULL && BufferSize != 0) || ConfigType >= MaxConfigType )
+ return EFI_INVALID_PARAMETER;
+
+ switch(ConfigType)
+ {
+ case Ps2KeyboardConfigType:
+ Status = DetectAndSetPs2KeyboardConfig(BufferSize, Buffer);
+ break;
+
+ case Ps2MouseConfigType:
+ Status = DetectAndSetPs2MouseConfig(BufferSize, Buffer);
+ break;
+
+ case MemorySizeConfigType:
+ Status = DetectAndSetMemorySizeConfig(BufferSize, Buffer);
+ break;
+
+
+ case MemoryMapConfigType:
+ Status = DetectAndSetMemoryMapConfig(BufferSize, Buffer);
+ break;
+
+ case PciConfigType:
+ Status = DetectAndSetPciConfig(BufferSize, Buffer);
+ break;
+#if HARDWARE_SIGNATURE_USB_CHANGE
+ case UsbConfigType:
+ Status = DetectAndSetUsbConfig(BufferSize, Buffer);
+ break;
+#endif
+ case VideoConfigType:
+ Status = DetectAndSetVideoConfig(BufferSize, Buffer);
+ break;
+ case DiskConfigType:
+ Status = DetectAndSetDiskConfig(BufferSize, Buffer);
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetHardwareConfigDataFromNvram
+//
+// Description:
+// This function gets the hardware configuration data from NVRAM.
+//
+// Input:
+// IN OUT HW_CONFIG_DATA *HardwareConfigData - The hardware configuration data of NVRAM.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - HardwareConfigData is NULL.
+// EFI_NOT_FOUND - It is the first boot. There is no Hardware
+// configuration data.
+// EFI_SUCCESS - Get the hardware configuration data successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetHardwareConfigDataFromNvram(
+ IN OUT HW_CONFIG_DATA *HardwareConfigData )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(HW_CONFIG_DATA);
+
+ if(HardwareConfigData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->GetVariable(
+ HARDWARE_CONFIG_DATA_VARIABLE,
+ &gHardwareConfigDataGuid,
+ NULL,
+ &VarSize,
+ HardwareConfigData );
+
+ if( EFI_ERROR(Status) )
+ {
+ MemSet(HardwareConfigData,sizeof(HW_CONFIG_DATA),0);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetFirmwareUpdateCountFromNvram
+//
+// Description:
+// This function gets the firmware update times from NVRAM.
+//
+// Input:
+// IN OUT UINT32 *ChangeTime - The firmware update times.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ChangeTime is NULL.
+// EFI_SUCCESS - Get the firmware update change times successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFirmwareUpdateCountFromNvram(
+ IN OUT UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->GetVariable(
+ FIRMWARE_UPDATE_COUNT_VARIABLE,
+ &gFirmwareUpdateCountGuid,
+ NULL,
+ &VarSize,
+ ChangeTime );
+
+ if( EFI_ERROR(Status) )
+ {
+ MemSet(ChangeTime,sizeof(UINT32),0);
+ }
+
+ return Status;
+}
+
+//<EIP147244 >
+EFI_GUID gSetupUpdateCountGuid = SETUP_UPDATE_COUNT_GUID;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetSetupUpdateCountFromNvram
+//
+// Description:
+// This function gets the setup update times from NVRAM.
+//
+// Input:
+// IN OUT UINT32 *ChangeTime - The setup update times.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ChangeTime is NULL.
+// EFI_SUCCESS - Get the firmware update change times successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetSetupCountFromNvram(
+ IN OUT UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->GetVariable(
+ SETUP_UPDATE_COUNT_VARIABLE,
+ &gSetupUpdateCountGuid,
+ NULL,
+ &VarSize,
+ ChangeTime );
+
+ if( EFI_ERROR(Status) )
+ {
+ MemSet(ChangeTime,sizeof(UINT32),0);
+ }
+
+ return Status;
+}
+//<EIP147244 >
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SignalHardwareSignatureChange
+//
+// Description:
+// This function will update the global variable 'gExternalFunCallCount' and
+// save the checksum value in the global variable
+// gCurHardwareConfigData(ReturnChecksum array).
+//
+// Modified: gExternalFunCallCount, gCurHardwareConfigData.ReturnChecksum
+//
+// Input:
+// IN UINT32 ReturnChecksum - The checksum value that external function gives.
+//
+// Output:
+// EFI_STATUS
+// EFI_OUT_OF_RESOURCES - The global variable 'gExternalFunCallCount' is
+// larger than and equal to LIMIT_PROTOCOL_CALLED.
+// EFI_SUCCESS - Record the checksum which external function gives successfully
+//
+// Notes:
+// The global variable gExternalFunCallCount will be increased.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SignalHardwareSignatureChange (
+ IN UINT32 ReturnChecksum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (gExternalFunCallCount >= LIMIT_PROTOCOL_CALLED)
+ return EFI_OUT_OF_RESOURCES;
+ else
+ {
+ gCurHardwareConfigData.ReturnChecksum[gExternalFunCallCount]= ReturnChecksum;
+ gExternalFunCallCount++;
+ return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveFwUpdateCountToMemory
+//
+// Description:
+// This function gets update counts from NVRAM and copy this data to the
+// global variable 'gFwUpdateCount' before updating the firmware. The NVRAM
+// data could erase during firmware update, so we need to save the data to
+// memory first.
+//
+// Modified: gFwUpdateCount
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SaveFwUpdateCountToMemory ( VOID )
+{
+ EFI_STATUS Status;
+ UINT32 ChangeCount = 0;
+
+ Status = GetFirmwareUpdateCountFromNvram(&ChangeCount);
+ gFwUpdateCount = ChangeCount+1;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SaveCountToNvramAfterFwUpdate
+//
+// Description:
+// This function saves the global variable 'gFwUpdateCount' to NVRAM after
+// the firmware updated.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SaveCountToNvramAfterFwUpdate( VOID )
+{
+ EFI_STATUS Status;
+
+ Status = SetFirmwareUpdateCountToNvram(&gFwUpdateCount);
+ if (EFI_ERROR(Status))
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetPs2KeyboardState
+//
+// Description:
+// This function sets the PS2 Keyboard configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN BOOLEAN bPresent - If valuse is TRUE, PS2 Keyboard is present.
+// If valuse is FALSE, PS2 Keyboard is not present.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetPs2KeyboardState (
+ IN BOOLEAN bPresent )
+{
+ if( bPresent )
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_KEYBOARD;
+
+ gCurHardwareConfigData.bPs2Keyboard = TRUE;
+ }
+ else
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_KEYBOARD;
+ //no PS2 Keyboard
+ gCurHardwareConfigData.bPs2Keyboard = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetPs2MouseState
+//
+// Description:
+// This function sets the PS2 Mouse configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN BOOLEAN bPresent - If valuse is TRUE, PS2 Mouse is present.
+// If valuse is FALSE, PS2 Mouse is not present.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetPs2MouseState (
+ IN BOOLEAN bPresent )
+{
+ if( bPresent )
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_MOUSE;
+ gCurHardwareConfigData.bPs2Mouse = TRUE;
+ }
+ else
+ {
+ gHardwareConfigChangeFlag |= HW_CHANGE_PS2_MOUSE;
+ //no PS2 Mouse
+ gCurHardwareConfigData.bPs2Mouse = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetMemorySizeConfigState
+//
+// Description:
+// This function sets the memory size configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN UINT32 MemorySizeMb - Current memory size (MB)
+// IN UINTN BufferSize - Size of buffer for recording the memory size.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - Buffer size is too small to record the memory
+// size.
+// EFI_SUCCESS - Memory size config. is set successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetMemorySizeConfigState (
+ IN UINT32 MemorySizeMb,
+ IN UINTN BufferSize )
+{
+
+ if(BufferSize < sizeof(UINT32)){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ gHardwareConfigChangeFlag |= HW_CHANGE_MEMORY_SIZE_CONFIG;
+
+ gCurHardwareConfigData.MemMapData.MemoryMbSize = MemorySizeMb;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetMemoryMapConfigState
+//
+// Description:
+// This function sets the memory map configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_MEMORY_MAP_DATA MemMapConfig - Current memory map data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetMemoryMapConfigState (
+ IN HW_MEMORY_MAP_DATA MemMapConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_MEMORY_MAP_CONFIG;
+ gCurHardwareConfigData.MemMapData.MemMapCheckSum = MemMapConfig.MemMapCheckSum;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetPciConfigState
+//
+// Description:
+// This function sets the PCI configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_PCI_DATA PciConfig - Current PCI data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetPciConfigState (
+ IN HW_PCI_DATA PciConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_PCI_CONFIG;
+
+ gCurHardwareConfigData.PciData.PciNum = PciConfig.PciNum;
+ gCurHardwareConfigData.PciData.BdfChecksum = PciConfig.BdfChecksum;
+ gCurHardwareConfigData.PciData.VidDidChecksum = PciConfig.VidDidChecksum;
+}
+
+#if HARDWARE_SIGNATURE_USB_CHANGE
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetUsbConfigState
+//
+// Description:
+// This function sets the USB configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_USB_DATA UsbConfig - Current USB data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetUsbConfigState (
+ IN HW_USB_DATA UsbConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_USB_CONFIG;
+
+ gCurHardwareConfigData.UsbData.UsbNum = UsbConfig.UsbNum;
+ gCurHardwareConfigData.UsbData.VidPidChecksum = UsbConfig.VidPidChecksum;
+ gCurHardwareConfigData.UsbData.PortNumInterfaceNumChecksum = UsbConfig.PortNumInterfaceNumChecksum;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetVideoConfigState
+//
+// Description:
+// This function sets the Video configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_VIDEO_DATA VideoConfig - Current Video data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetVideoConfigState (
+ IN HW_VIDEO_DATA VideoConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_VIDEO_CONFIG;
+
+ gCurHardwareConfigData.VideoData.EdidCheckNum = VideoConfig.EdidCheckNum;
+ gCurHardwareConfigData.VideoData.ResolutionChecksum = VideoConfig.ResolutionChecksum;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: SetDiskConfigState
+//
+// Description:
+// This function sets the Disk configurations to global variable
+// gCurHardwareConfigData.
+//
+// Input:
+// IN HW_DISK_DATA DiskConfig - Current Disk data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetDiskConfigState (
+ IN HW_DISK_DATA DiskConfig )
+{
+ gHardwareConfigChangeFlag |= HW_CHANGE_DISK_CONFIG;
+
+ gCurHardwareConfigData.DiskData.CDSchecksum = DiskConfig.CDSchecksum;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetPs2KeyboardConfig
+//
+// Description:
+// This function detects the PS2 Keyboard configurations and sets this
+// configuration to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the PS2 Keyboard
+// configuration. It should be one byte.
+// IN VOID *Buffer - Buffer for recording the PS2 Keyboard configuration.
+// If *Buffer is 1, it means the PS2 Keyboard is present.
+// If *Buffer is 0, the PS2 Keyboard is not present
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - PS2 Keyboard config. is set successfully.
+// Other - Set PS2 Keyboard config. failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected data to gCurHardwareConfigData. Otherwise, it will compare the
+// input data and the detected data to determine the PS2 Keyboard is
+// present or not.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetPs2KeyboardConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ BOOLEAN bPs2KeyboardPresent = FALSE;
+ BOOLEAN DetectPs2KeyboardPresent = FALSE;
+
+ Status = DetectPS2KeyboardMouseState( Ps2KeyboardConfigType,
+ &DetectPs2KeyboardPresent);
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ bPs2KeyboardPresent = DetectPs2KeyboardPresent;
+ }
+ else
+ {
+ if((*(BOOLEAN *)Buffer) == 0 && DetectPs2KeyboardPresent == 0)
+ bPs2KeyboardPresent = FALSE;
+ else
+ bPs2KeyboardPresent = TRUE;
+ }
+
+ SetPs2KeyboardState(bPs2KeyboardPresent);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetPs2MouseConfig
+//
+// Description:
+// This function detects the PS2 Mouse configurations and sets this config.
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the PS2 Mouse config.
+// It should be one byte.
+// IN VOID *Buffer - Buffer for recording the PS2 Mouse configuration. If
+// *Buffer is 1, it means the PS2 Mouse is present. If
+// *Buffer is 0, the PS2 Mouse is not present
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - PS2 Mouse config. is set successfully.
+// Other - Set PS2 Mouse configuration failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected data to gCurHardwareConfigData. Otherwise, it will compare
+// the input data and the detected data to determine the PS2 Mouse is
+// present or not.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DetectAndSetPs2MouseConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ BOOLEAN bPs2MousePresent = FALSE;
+ BOOLEAN DetectPs2MousePresent = FALSE;
+
+ Status = DetectPS2KeyboardMouseState( Ps2MouseConfigType,
+ &DetectPs2MousePresent);
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ bPs2MousePresent = DetectPs2MousePresent;
+ }
+ else
+ {
+ if((*(BOOLEAN *)Buffer) == 0 && DetectPs2MousePresent == 0)
+ bPs2MousePresent = FALSE;
+ else
+ bPs2MousePresent = TRUE;
+ }
+
+
+ SetPs2MouseState(bPs2MousePresent);
+
+ return Status;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetMemorySizeConfig
+//
+// Description:
+// This function detects the memory size configurations and sets this
+// configuration to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the memory size.
+// IN VOID *Buffer - Buffer for recording the memory size.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Memory size config. is set successfully.
+// Other - Detect the memory size failed or set the memory size
+// configuration failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected size(DetectMemSize) to gCurHardwareConfigData. Otherwise, it
+// will compare the input data(Buffer) and the detected size(DetectMemSize)
+// to determine which one should be saved.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetMemorySizeConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINT32 CurrentMemSize= 0;
+ UINTN BuffSize = 0;
+ UINT32 DetectMemSize = 0;
+ BOOLEAN bDifferent = FALSE;
+ HW_MEMORY_MAP_DATA DetectMemMapConfigData;
+
+ MemSet(&DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+
+ Status = GetMemMapData (&DetectMemMapConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ DetectMemSize = DetectMemMapConfigData.MemoryMbSize;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ CurrentMemSize = DetectMemSize;
+ BuffSize = sizeof (CurrentMemSize);
+ }
+ else
+ {
+ bDifferent = IsDifferentMemorySize( DetectMemSize, (*(UINT32 *)Buffer) );
+
+ if(bDifferent)
+ CurrentMemSize = DetectMemSize;
+ else
+ CurrentMemSize = (*(UINT32 *)Buffer);
+
+ BuffSize = BufferSize;
+ }
+
+ Status = SetMemorySizeConfigState(CurrentMemSize, BuffSize);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetMemoryMapConfig
+//
+// Description:
+// This function detects the memory map configurations and sets this
+// configuration to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the memory map data.
+// IN VOID *Buffer - Buffer for recording the memory map data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Memory map config. is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get memory map data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected memory map data to gCurHardwareConfigData. Otherwise, it will
+// save the input data(Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetMemoryMapConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_MEMORY_MAP_DATA DetectMemMapConfigData;
+ HW_MEMORY_MAP_DATA CurMemMapConfigData;
+
+ MemSet(&DetectMemMapConfigData, sizeof(HW_MEMORY_MAP_DATA), 0);
+
+ Status = GetMemMapData (&DetectMemMapConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(DetectMemMapConfigData.MemMapCheckSum);
+ MemCpy(&CurMemMapConfigData, &DetectMemMapConfigData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(DetectMemMapConfigData.MemMapCheckSum);
+ if(BufferSize < BuffSize || BufferSize > sizeof(HW_MEMORY_MAP_DATA))
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ BuffSize = BufferSize;
+ MemCpy(&CurMemMapConfigData, Buffer, BuffSize);
+ }
+
+ SetMemoryMapConfigState(CurMemMapConfigData);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetPciConfig
+//
+// Description:
+// This function detects the PCI configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the PCI data.
+// IN VOID *Buffer - Buffer for recording the PCI data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - PCI config. is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get PCI data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected PCI data to gCurHardwareConfigData. Otherwise, it will save
+// the input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetPciConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_PCI_DATA DetectPciConfigData;
+ HW_PCI_DATA CurrentPciConfigData;
+
+ Status = GetPciDeviceData (&DetectPciConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_PCI_DATA);
+ MemCpy(&CurrentPciConfigData, &DetectPciConfigData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_PCI_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentPciConfigData, Buffer, BuffSize);
+ }
+
+ SetPciConfigState(CurrentPciConfigData);
+
+ return Status;
+
+}
+#if HARDWARE_SIGNATURE_USB_CHANGE
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: DetectAndSetUsbConfig
+//
+// Description:
+// This function detects the USB configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording USB data.
+// IN VOID *Buffer - Buffer for recording the USB data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - USB config. is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get USB data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected USB data to gCurHardwareConfigData. Otherwise, it will save the
+// input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetUsbConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_USB_DATA DetectUsbConfigData;
+ HW_USB_DATA CurrentUsbConfigData;
+
+ Status = GetUsbDeviceData (&DetectUsbConfigData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_USB_DATA);
+ MemCpy(&CurrentUsbConfigData, &DetectUsbConfigData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_USB_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentUsbConfigData, Buffer, BuffSize);
+ }
+
+ SetUsbConfigState(CurrentUsbConfigData);
+
+ return Status;
+
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetVideoConfig
+//
+// Description:
+// This function detects the Video configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the Video data.
+// IN VOID *Buffer - Buffer for recording the Video data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Video configuration is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get Video data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected Video data to gCurHardwareConfigData. Otherwise, it will save
+// the input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetVideoConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_VIDEO_DATA DetectVideoData;
+ HW_VIDEO_DATA CurrentVideoData;
+
+ Status = GetVideoData( &DetectVideoData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_VIDEO_DATA);
+ MemCpy(&CurrentVideoData, &DetectVideoData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_VIDEO_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentVideoData, Buffer, BuffSize);
+ }
+
+ SetVideoConfigState(CurrentVideoData);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: DetectAndSetDiskConfig
+//
+// Description:
+// This function detects the Disk configurations and sets this configuration
+// to global variable gCurHardwareConfigData.
+//
+// Input:
+// IN UINTN BufferSize - Size of buffer for recording the Disk data.
+// IN VOID *Buffer - Buffer for recording the Disk data.
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - Disk configuration is set successfully.
+// EFI_INVALID_PARAMETER - BufferSize is incorrect.
+// Other - Get Disk data failed.
+//
+// Notes:
+// If Buffer is NULL and BufferSize is 0, the function will save the
+// detected Disk data to gCurHardwareConfigData. Otherwise, it will save
+// the input data (Buffer).
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DetectAndSetDiskConfig (
+ IN UINTN BufferSize,
+ IN VOID *Buffer)
+{
+ EFI_STATUS Status;
+ UINTN BuffSize = 0;
+ HW_DISK_DATA DetectDiskData;
+ HW_DISK_DATA CurrentDiskData;
+
+ Status = GetDiskInfoData( &DetectDiskData);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if( BufferSize == 0 && Buffer == NULL)
+ {
+ BuffSize = sizeof(HW_DISK_DATA);
+ MemCpy(&CurrentDiskData, &DetectDiskData, BuffSize);
+ }
+ else
+ {
+ BuffSize = sizeof(HW_DISK_DATA);
+ if(BufferSize != BuffSize )
+ {
+ Status = EFI_INVALID_PARAMETER;
+ return Status;
+ }
+
+ MemCpy(&CurrentDiskData, Buffer, BuffSize);
+ }
+
+ SetDiskConfigState(CurrentDiskData);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetHardwareConfigDataToNvram
+//
+// Description:
+// This function writes the hardware configurations to NVRAM.
+//
+// Input:
+// IN HW_CONFIG_DATA *HardwareConfigData - current HW config. data
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - HardwareConfigData is invalid
+// EFI_SUCCESS - HW Config. is written successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetHardwareConfigDataToNvram (
+ IN HW_CONFIG_DATA *HardwareConfigData )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(HW_CONFIG_DATA);
+
+ if(HardwareConfigData == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->SetVariable(
+ HARDWARE_CONFIG_DATA_VARIABLE,
+ &gHardwareConfigDataGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ VarSize,
+ HardwareConfigData
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SetFirmwareUpdateCountToNvram
+//
+// Description:
+// This function saves the firmware update times into NVRAM.
+//
+// Input:
+// IN UINT32 *ChangeTime - Firmware update times.
+//
+// Output:
+// EFI_STATUS
+// EFI_INVALID_PARAMETER - ChangeTime is invalid
+// EFI_SUCCESS - ChangeTime is written successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SetFirmwareUpdateCountToNvram (
+ IN UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->SetVariable(
+ FIRMWARE_UPDATE_COUNT_VARIABLE,
+ &gFirmwareUpdateCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ VarSize,
+ ChangeTime
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: GetFacsTable
+//
+// Description:
+// This function returns address of memory where FACS ACPI table resides
+//
+// Input:
+// IN OUT EFI_PHYSICAL_ADDRESS *AcpiFacsTable - address of FACS table
+//
+// Output:
+// EFI_STATUS
+// EFI_NOT_READY - Can't find the EfiAcpiSupportGuid protocol
+// EFI_NOT_FOUND - Can't find the FADT table
+// EFI_SUCCESS - Table was found successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFacsTable (
+ IN OUT EFI_PHYSICAL_ADDRESS *AcpiFacsTable )
+{
+ EFI_STATUS Status;
+ EFI_GUID EfiAcpiSupportGuid = EFI_ACPI_SUPPORT_GUID;
+ EFI_ACPI_SUPPORT_PROTOCOL *AcpiSupport;
+ EFI_ACPI_TABLE_VERSION Version;
+ FACP_20 *Table = NULL;
+ UINT8 FacpFlag = 0;
+ UINTN Index;
+ UINTN Handle;
+
+ Status = pBS->LocateProtocol(&EfiAcpiSupportGuid, NULL, &AcpiSupport);
+ if(EFI_ERROR(Status))
+ {
+ return EFI_NOT_READY;
+ }
+
+ for(Index = 0; Index < 3; Index++)
+ {
+ AcpiFacsTable[Index] = 0;
+ }
+
+ //Find DSDT, XSDT ACPI table
+ Index = 0;
+ do
+ {
+ Status = AcpiSupport->GetAcpiTable(AcpiSupport,
+ Index,
+ &Table,
+ &Version,
+ &Handle);
+ if (EFI_ERROR(Status))
+ break;//no more tables left
+
+ if ((Table->Header.Signature == FACP_SIG))
+ {
+ if( Version == EFI_ACPI_TABLE_VERSION_1_0B )
+ {
+ AcpiFacsTable[0] = (EFI_PHYSICAL_ADDRESS)Table->FIRMWARE_CTRL;
+ FacpFlag |= BIT0;
+ }
+ else
+ {
+ AcpiFacsTable[1] = (EFI_PHYSICAL_ADDRESS)Table->FIRMWARE_CTRL;
+ AcpiFacsTable[2] = (EFI_PHYSICAL_ADDRESS)Table->X_FIRMWARE_CTRL;
+ FacpFlag |= BIT1;
+ }
+
+ }
+
+ if(FacpFlag == 3)
+ break;
+
+ Index++;
+ }while(1);
+
+ if(FacpFlag == 0)
+ return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: Swap
+//
+// Description:
+// This function swaps the two input data.
+//
+// Input:
+// IN OUT UINT32 *LChecksumPosition - Left checksum position
+// IN OUT UINT32 *RChecksumPosition - Right checksum position
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+Swap(
+ IN OUT UINT32 *LChecksumPosition,
+ IN OUT UINT32 *RChecksumPosition )
+{
+ UINT32 Temp = *LChecksumPosition;
+ *LChecksumPosition = *RChecksumPosition;
+ *RChecksumPosition = Temp;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: QuickSort
+//
+// Description:
+// This function sorts the external checksum in ascending order.
+//
+// Input:
+// IN OUT UINT32 *ChecksumData - all checksum data
+// IN UINT32 LChecksumPosition - the first position of checksum data
+// IN UINT32 RChecksumPosition - the last position of checksum data
+//
+// Output:
+// None
+//
+// Notes:
+// The sorted data will be saved in ChecksumData.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+QuickSort(
+ IN OUT UINT32 *ChecksumData,
+ IN UINT32 LChecksumPosition,
+ IN UINT32 RChecksumPosition )
+{
+ UINT32 Pivot;
+ UINT32 LeftIncPosition;
+ UINT32 RightDecPostion;
+
+ if (LChecksumPosition >= RChecksumPosition) { return; }
+
+ Pivot = ChecksumData[LChecksumPosition];
+
+ LeftIncPosition = LChecksumPosition + 1;
+ RightDecPostion = RChecksumPosition;
+
+ while (1)
+ {
+ while (LeftIncPosition <= RChecksumPosition)
+ {
+ if (ChecksumData[LeftIncPosition] > Pivot)
+ break;
+ LeftIncPosition = LeftIncPosition + 1;
+ }
+
+ while (RightDecPostion > LChecksumPosition)
+ {
+ if (ChecksumData[RightDecPostion] < Pivot)
+ break;
+ RightDecPostion = RightDecPostion - 1;
+ }
+
+ if (LeftIncPosition > RightDecPostion)
+ break;
+
+ Swap(&ChecksumData[LeftIncPosition], &ChecksumData[RightDecPostion]);
+ }
+
+ Swap(&ChecksumData[LChecksumPosition], &ChecksumData[RightDecPostion]);
+
+ QuickSort(ChecksumData, LChecksumPosition, RightDecPostion - 1);
+ QuickSort(ChecksumData, RightDecPostion + 1, RChecksumPosition);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateHardwareSignatureData
+//
+// Description:
+// This function will be called when ReadyToBoot event will be signaled and
+// will update the hardware signature data of the FACS table.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output:
+// EFI_STATUS
+// EFI_NOT_READY - GetFacsTable() can't find the EfiAcpiSupportGuid protocol.
+// EFI_NOT_FOUND - GetFacsTable() can't find the FADT table.
+// EFI_SUCCESS - Hardware Signature was updated successfully.
+// Other - Hardware Signature could't be updated.
+//
+// Notes:
+// This function also writes the hardware configurations to NVRAM.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateHardwareSignatureData (
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ FACS_20 *FacsPtr = NULL;
+ BOOLEAN bDifferent = FALSE;
+ BOOLEAN bFirstBoot = FALSE;
+ EFI_PHYSICAL_ADDRESS AcpiFacsTable[3];
+ UINT8 Index =0;
+ UINTN VarSize = sizeof(HW_CONFIG_DATA);
+ BOOLEAN bPs2MousePresent = FALSE;
+ UINTN BufferSize = 0;
+ UINT32 FacsSignature = 0;
+ UINT32 ChangeCount = 0;
+ UINT32 SetupCount=0;
+ UINTN i;
+ static UINT8 UpdateCount = 0;
+
+ if(UpdateCount == 0)//To update the signature only once
+ UpdateCount++;
+ else
+ return EFI_SUCCESS;
+
+ //clear table address
+ for(Index = 0; Index < 3; Index++)
+ {
+ AcpiFacsTable[Index] = 0;
+ }
+ //Get Facs table address. (RSDT, XSDT)
+ Status = GetFacsTable(&AcpiFacsTable[0]);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ SetHardwareConfigData( Ps2KeyboardConfigType,0,NULL );
+
+ BufferSize = sizeof(bPs2MousePresent);
+ SetHardwareConfigData( Ps2MouseConfigType,BufferSize,(VOID *)&bPs2MousePresent );
+
+ SetHardwareConfigData( MemorySizeConfigType,0,NULL);
+
+ SetHardwareConfigData( MemoryMapConfigType,0,NULL);
+
+ SetHardwareConfigData( PciConfigType,0,NULL);
+
+#if HARDWARE_SIGNATURE_USB_CHANGE
+ SetHardwareConfigData( UsbConfigType,0,NULL);
+#endif
+ SetHardwareConfigData( DiskConfigType,0,NULL);
+
+ SetHardwareConfigData( VideoConfigType,0,NULL);
+
+ HWSIG_TRACE((-1,"bPs2KB:%x, bPs2Mouse:%x\n", gCurHardwareConfigData.bPs2Keyboard, gCurHardwareConfigData.bPs2Mouse));
+ HWSIG_TRACE((-1,"MemMapCheckSum:%x\n", gCurHardwareConfigData.MemMapData.MemMapCheckSum));
+ HWSIG_TRACE((-1,"MemorySize:%x\n", gCurHardwareConfigData.MemMapData.MemoryMbSize));
+ HWSIG_TRACE((-1,"Pci#:%x, BDF:%x, VID:%x\n", gCurHardwareConfigData.PciData.PciNum, gCurHardwareConfigData.PciData.BdfChecksum, gCurHardwareConfigData.PciData.VidDidChecksum));
+#if HARDWARE_SIGNATURE_USB_CHANGE
+ HWSIG_TRACE((-1,"Usb#:%x,VID:%x, Port:%x\n", gCurHardwareConfigData.UsbData.UsbNum, gCurHardwareConfigData.UsbData.VidPidChecksum, gCurHardwareConfigData.UsbData.PortNumInterfaceNumChecksum));
+#endif
+ HWSIG_TRACE((-1,"Edid Chk:0x%x, Resolution Chk:0x%x\n", gCurHardwareConfigData.VideoData.EdidCheckNum, gCurHardwareConfigData.VideoData.ResolutionChecksum));
+ HWSIG_TRACE((-1,"CDSchecksum:%x\n", gCurHardwareConfigData.DiskData.CDSchecksum));
+
+ Status = GetFirmwareUpdateCountFromNvram(&ChangeCount);
+ if(!EFI_ERROR(Status)){
+ HWSIG_TRACE((-1,"Update Change Count:%x\n", ChangeCount));
+ }
+ else {
+ ChangeCount = 0;
+ }
+
+ gCurHardwareConfigData.FirmwareUpdateCount = ChangeCount;
+//<EIP147244 >
+ Status = GetSetupCountFromNvram(&SetupCount);
+
+ gCurHardwareConfigData.SetupUpdateCount = SetupCount;
+
+ TRACE((-1,"Setup Update Count:%d\n",SetupCount));
+//<EIP147244 >
+
+ if(gExternalFunCallCount !=0)
+ {
+ for(i=0;i<gExternalFunCallCount;i++)
+ {
+ TRACE((-1,"Used Protocol Checksum:%x\n",gCurHardwareConfigData.ReturnChecksum[i]));
+ }
+
+ QuickSort( gCurHardwareConfigData.ReturnChecksum ,0 , gExternalFunCallCount-1 );
+
+ for(i=0;i<gExternalFunCallCount;i++)
+ {
+ TRACE((-1,"After Sorting :%x\n",gCurHardwareConfigData.ReturnChecksum[i]));
+ }
+ }
+
+ FacsSignature = CRC32(&gCurHardwareConfigData.bPs2Keyboard,(UINT16)(sizeof(HW_CONFIG_DATA)),0);
+ HWSIG_TRACE((-1,"Update curFacsSigVar:%x\n", FacsSignature));
+
+ //Update Hardware Signature of FACS table
+ for(Index = 0; Index < 3; Index++)
+ {
+ if(AcpiFacsTable[Index] == 0)
+ continue;
+
+ FacsPtr = (FACS_20 *)(UINTN)AcpiFacsTable[Index];
+ FacsPtr->HardwareSignature = FacsSignature;
+ }
+
+ pBS->CloseEvent(Event);
+
+ return Status;
+}
+
+//<EIP147244 >
+EFI_STATUS
+SetSetupCountToNvram (
+ IN UINT32 *ChangeTime )
+{
+ EFI_STATUS Status;
+ UINTN VarSize = sizeof(UINT32);
+
+ if(ChangeTime == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = pRS->SetVariable(
+ SETUP_UPDATE_COUNT_VARIABLE,
+ &gSetupUpdateCountGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_RUNTIME_ACCESS,
+ VarSize,
+ ChangeTime
+ );
+
+ return Status;
+}
+
+VOID SetupChangeCount(VOID)
+{
+ UINT32 SetupCount;
+
+ SetupCount=0;
+ GetSetupCountFromNvram(&SetupCount);
+ SetupCount++;
+ SetSetupCountToNvram(&SetupCount);
+}
+//<EIP147244 >
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.chm b/Core/EM/HardwareSignature/HardwareSignatureManagement.chm
new file mode 100644
index 0000000..db92b95
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.chm
Binary files differ
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.cif b/Core/EM/HardwareSignature/HardwareSignatureManagement.cif
new file mode 100644
index 0000000..60c907a
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "Hardware Signature Management"
+ category = eModule
+ LocalRoot = "Core\EM\HardwareSignature\"
+ RefName = "HardwareSignatureManagement"
+[files]
+"HardwareSignatureManagement.chm"
+"HardwareSignatureManagement.mak"
+"HardwareSignatureManagement.dxs"
+"HardwareSignatureManagement.sdl"
+"HardwareSignatureManagement.c"
+"HardwareChangeDetect.c"
+[parts]
+"HardwareChangeProtocols"
+<endComponent>
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.dxs b/Core/EM/HardwareSignature/HardwareSignatureManagement.dxs
new file mode 100644
index 0000000..bfeb790
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.dxs
@@ -0,0 +1,42 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HardwareSignatureManagement.dxs
+//
+// Description: Dependency expression file for Hardware Signature update Driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <protocol\AcpiSupport.h>
+
+DEPENDENCY_START
+ EFI_ACPI_SUPPORT_GUID
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.mak b/Core/EM/HardwareSignature/HardwareSignatureManagement.mak
new file mode 100644
index 0000000..b6263c8
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.mak
@@ -0,0 +1,109 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.mak 3 1/09/14 8:02a Albertlin $
+#
+# $Date: 1/09/14 8:02a $
+#
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/HardwareSignatureManagement/HardwareSignatureManagement.mak $
+#
+# 3 1/09/14 8:02a Albertlin
+# [TAG] EIP147244
+# [Category] Not Specified
+# [Description] BIOS need to report changed hardware signature when
+# BIOS setup was modified.
+# [Files] HardwareSignatureManagement.mak
+#
+# 2 12/12/12 3:42a Sophiachen
+# [TAG] EIP106129
+# [Category] New Feature
+# [Description] After BIOS firmware update, the hardware signature will
+# be changed.
+# [Files] HardwareSignatureManagement.c,
+# HardwareSignatureManagement.mak, HardwareSignatureManagement.sdl
+#
+# 1 9/25/12 8:57a Sophiachen
+# [TAG] EIP96258
+# [Category] New Feature
+# [Description] Update the Hardware Signature of the ACPI table FACS
+# field can notify ACPI OS whether any hardware configuration change.
+# [Files] HardwareSignatureManagement.cif
+# HardwareSignatureManagement.mak
+# HardwareSignatureManagement.dxs
+# HardwareSignatureManagement.sdl
+# HardwareSignatureManagement.c
+# HardwareChangeDetect.c
+#
+#**********************************************************************
+
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: HardwareSignatureManagement.mak
+#
+# Description: Make file for the Hardware signature Management component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : HwSignatureManagement
+
+HwSignatureManagement : $(BUILD_DIR)\HardwareSignatureManagement.mak HwSignatureManagementBin
+
+$(BUILD_DIR)\HardwareSignatureManagement.mak : $(HARDWARE_SIGNATURE_DIR)\$(@B).cif $(HARDWARE_SIGNATURE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(HARDWARE_SIGNATURE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+HwSignatureManagementBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\HardwareSignatureManagement.mak all\
+ GUID=B7EE4835-84CE-4b15-BF52-2D11574CE470 \
+ ENTRY_POINT=HardwareSignatureEntryPoint\
+ DEPEX1=$(HARDWARE_SIGNATURE_DIR)\HardwareSignatureManagement.dxs \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+SMIFlashBin : $(BUILD_DIR)\HardwareSignatureManagement.obj $(BUILD_DIR)\HardwareChangeDetect.obj
+
+{$(HARDWARE_SIGNATURE_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /I $(HARDWARE_SIGNATURE_DIR) \
+ /Fo$(BUILD_DIR)\ $<
+
+$(BUILD_DIR)\HardwareSignatureManagement.obj : $(HARDWARE_SIGNATURE_DIR)\HardwareSignatureManagement.c
+
+$(BUILD_DIR)\HardwareChangeDetect.obj : $(HARDWARE_SIGNATURE_DIR)\HardwareChangeDetect.c
+
+#<EIP147244 >
+#---------------------------------------------------------------------------
+# Link Callback Lib to Setup
+#---------------------------------------------------------------------------
+AMITSEBin : $(BUILD_DIR)\HardwareSignatureManagement.obj $(BUILD_DIR)\HardwareChangeDetect.obj
+#<EIP147244 >
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HardwareSignature/HardwareSignatureManagement.sdl b/Core/EM/HardwareSignature/HardwareSignatureManagement.sdl
new file mode 100644
index 0000000..0360449
--- /dev/null
+++ b/Core/EM/HardwareSignature/HardwareSignatureManagement.sdl
@@ -0,0 +1,72 @@
+TOKEN
+ Name = HARDWARE_SIGNATURE_MANAGEMENT_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable HardwareSignatureManagement support in Project"
+End
+
+MODULE
+ Help = "Includes HardwareSignatureManagement.mak to Project"
+ File = "HardwareSignatureManagement.mak"
+End
+
+PATH
+ Name = "HARDWARE_SIGNATURE_DIR"
+ Path = "Core\EM\HardwareSignature"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\HardwareSignatureManagement.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "HARDWARE_SIGNATURE_DEBUG_MESSAGES"
+ Value = "1"
+ Help = "A switch to enable HardwareSignatureManagement Driver Debug messages over Serial Port."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_CODE" "=" "1"
+End
+
+TOKEN
+ Name = "HARDWARE_SIGNATURE_USB_CHANGE"
+ Value = "0"
+ Help = "A switch to enable detect the change of the USB devices"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "THRESHOLD_OF_DIFFERENT_MEMORY_SIZE"
+ Value = "128"
+ Help = "The threshold of the different memory size. If memory map is changed, the total memory size will be little different."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+ELINK
+ Name = "SaveFwUpdateCountToMemory,"
+ Parent = "SMIFlashPreUpdateList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SaveCountToNvramAfterFwUpdate,"
+ Parent = "SMIFlashEndUpdateList"
+ InvokeOrder = AfterParent
+End
+
+#<EIP147244 >
+ELINK
+ Name = "SetupChangeCount,"
+ Parent = "SavedConfigChanges,"
+ InvokeOrder = AfterParent
+End
+#<EIP147244 > \ No newline at end of file
diff --git a/Core/EM/HashService/HashService.c b/Core/EM/HashService/HashService.c
new file mode 100644
index 0000000..7518355
--- /dev/null
+++ b/Core/EM/HashService/HashService.c
@@ -0,0 +1,277 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/HashService/HashService.c 2 8/28/12 4:28p Artems $
+//
+// $Revision: 2 $
+//
+// $Date: 8/28/12 4:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/HashService/HashService.c $
+//
+// 2 8/28/12 4:28p Artems
+// [TAG] EIP N/A
+// [Category] New Feature
+// [Description] Implementation of hash protocol
+// [Files] HasService.c HashService.sdl
+//
+// 1 5/24/12 3:33p Artems
+// [TAG] EIP N/A
+// [Category] New Feature
+// [Description] Added HashService protocol infrastructure
+// [Files] HashService.cif
+// HashService.sdl
+// HashService.mak
+// HashService.c
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HashService.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Protocol\Hash.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\ServiceBinding.h>
+#include <Protocol\AmiDigitalSignature.h>
+
+
+/* Dummy DriverBinding protocol */
+EFI_STATUS HashServiceDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{ return EFI_UNSUPPORTED; }
+
+EFI_STATUS HashServiceDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{ return EFI_UNSUPPORTED; }
+
+EFI_STATUS HashServiceDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer)
+{ return EFI_UNSUPPORTED; }
+
+EFI_DRIVER_BINDING_PROTOCOL HashServiceDriverBindingProtocol = {
+ HashServiceDriverBindingSupported,
+ HashServiceDriverBindingStart,
+ HashServiceDriverBindingStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+static EFI_GUID AmiDigitalSignatureProtocolGuid = AMI_DIGITAL_SIGNATURE_PROTOCOL_GUID;
+static AMI_DIGITAL_SIGNATURE_PROTOCOL *AmiDigitalSignatureProtocol = NULL;
+static DLIST HashChildList;
+
+typedef struct {
+ DLINK Link;
+ EFI_HANDLE Handle;
+ EFI_HASH_PROTOCOL Protocol;
+} HASH_CHILD_LINK;
+
+/* Hash service binding protocol */
+EFI_STATUS HashServiceCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN OUT EFI_HANDLE *ChildHandle
+);
+
+EFI_STATUS HashServiceDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL*This,
+ IN EFI_HANDLE ChildHandle
+);
+
+EFI_SERVICE_BINDING_PROTOCOL HashServiceBindingProtocol = {
+ HashServiceCreateChild,
+ HashServiceDestroyChild
+};
+
+EFI_STATUS HsGetHashSize(
+ IN CONST EFI_HASH_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ OUT UINTN *HashSize
+)
+{
+ if(HashSize == NULL || This == NULL || HashAlgorithm == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1Guid)) {
+ *HashSize = SHA1_DIGEST_SIZE;
+ } else if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256Guid)) {
+ *HashSize = SHA256_DIGEST_SIZE;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS HsHash(
+ IN CONST EFI_HASH_PROTOCOL *This,
+ IN CONST EFI_GUID *HashAlgorithm,
+ IN BOOLEAN Extend,
+ IN CONST UINT8 *Message,
+ IN UINT64 MessageSize,
+ IN OUT EFI_HASH_OUTPUT *Hash
+)
+{
+ UINTN Count;
+ UINTN Size[2];
+ UINT8 *Chunks[2];
+ UINTN HashSize;
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+
+ if(Message == NULL || Hash == NULL || This == NULL || HashAlgorithm == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha1Guid)) {
+ Buffer = *(Hash->Sha1Hash);
+ HashSize = SHA1_DIGEST_SIZE;
+ } else if(!guidcmp((EFI_GUID*)HashAlgorithm, &gEfiHashAlgorithmSha256Guid)) {
+ Buffer = *(Hash->Sha256Hash);
+ HashSize = SHA256_DIGEST_SIZE;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ if(Extend) {
+/*
+ Count = 2;
+ Size[0] = (UINTN)MessageSize;
+ Chunks[0] = (UINT8*)Message;
+*/
+ return EFI_UNSUPPORTED;
+ } else {
+ Count = 1;
+ Size[0] = (UINTN)MessageSize;
+ Chunks[0] = (UINT8*)Message;
+ }
+
+ Status = AmiDigitalSignatureProtocol->Hash(AmiDigitalSignatureProtocol,
+ HashAlgorithm,
+ Count,
+ Chunks,
+ Size,
+ Buffer);
+
+ return Status;
+}
+
+
+EFI_STATUS HashServiceEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ Status = pBS->LocateProtocol(&AmiDigitalSignatureProtocolGuid, NULL, &AmiDigitalSignatureProtocol);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ DListInit(&HashChildList);
+
+ HashServiceDriverBindingProtocol.ImageHandle = ImageHandle;
+ HashServiceDriverBindingProtocol.DriverBindingHandle = NULL;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &HashServiceDriverBindingProtocol.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &HashServiceDriverBindingProtocol,
+ &gEfiHashServiceBindingProtocolGuid,
+ &HashServiceBindingProtocol,
+ NULL);
+
+
+ return Status;
+}
+
+EFI_STATUS HashServiceCreateChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL *This,
+ IN OUT EFI_HANDLE *ChildHandle
+)
+{
+ EFI_STATUS Status;
+ HASH_CHILD_LINK *NewLink;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(HASH_CHILD_LINK), &NewLink);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ NewLink->Handle = *ChildHandle;
+ NewLink->Protocol.GetHashSize = HsGetHashSize;
+ NewLink->Protocol.Hash = HsHash;
+
+ DListAdd(&HashChildList, (DLINK *)NewLink);
+
+ Status = pBS->InstallMultipleProtocolInterfaces(&(NewLink->Handle), &gEfiHashProtocolGuid, &(NewLink->Protocol), NULL);
+ if(!EFI_ERROR(Status) && *ChildHandle == NULL)
+ *ChildHandle = NewLink->Handle;
+
+ return Status;
+}
+
+EFI_STATUS HashServiceDestroyChild (
+ IN EFI_SERVICE_BINDING_PROTOCOL*This,
+ IN EFI_HANDLE ChildHandle
+)
+{
+ EFI_STATUS Status;
+ EFI_HASH_PROTOCOL *Instance;
+ VOID *Start;
+
+ Status = pBS->HandleProtocol(ChildHandle, &gEfiHashProtocolGuid, &Instance);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Status = pBS->UninstallMultipleProtocolInterfaces(ChildHandle, &gEfiHashProtocolGuid, Instance);
+ if(!EFI_ERROR(Status)) {
+ Start = OUTTER(Instance, Protocol, HASH_CHILD_LINK);
+ DListDelete(&HashChildList, (DLINK *)Start);
+ pBS->FreePool(Start);
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HashService/HashService.cif b/Core/EM/HashService/HashService.cif
new file mode 100644
index 0000000..101f7af
--- /dev/null
+++ b/Core/EM/HashService/HashService.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "HashService"
+ category = ModulePart
+ LocalRoot = "Core\EM\HashService"
+ RefName = "HashService"
+[files]
+"HashService.sdl"
+"HashService.mak"
+"HashService.c"
+<endComponent>
diff --git a/Core/EM/HashService/HashService.mak b/Core/EM/HashService/HashService.mak
new file mode 100644
index 0000000..1b747a1
--- /dev/null
+++ b/Core/EM/HashService/HashService.mak
@@ -0,0 +1,65 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/HashService/HashService.mak 1 5/24/12 3:33p Artems $
+#
+# $Revision: 1 $
+#
+# $Date: 5/24/12 3:33p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/HashService/HashService.mak $
+#
+# 1 5/24/12 3:33p Artems
+# [TAG] EIP N/A
+# [Category] New Feature
+# [Description] Added HashService protocol infrastructure
+# [Files] HashService.cif
+# HashService.sdl
+# HashService.mak
+# HashService.c
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: HashService.mak
+#
+# Description: Make file to create Hash Service Binding Driver
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\HashService.obj
+
+$(BUILD_DIR)\HashService.obj : $(HashService_DIR)\HashService.c
+
+{$(HashService_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/HashService/HashService.sdl b/Core/EM/HashService/HashService.sdl
new file mode 100644
index 0000000..9b193bd
--- /dev/null
+++ b/Core/EM/HashService/HashService.sdl
@@ -0,0 +1,28 @@
+TOKEN
+ Name = "HashService_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable hash service support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CryptoAPI_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "HashService_DIR"
+ Help = "Path to PlatformToDriver Module in Project"
+End
+
+MODULE
+ Help = "Includes HashService.mak to Project"
+ File = "HashService.mak"
+End
+
+ELINK
+ Name = "HashServiceEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+
diff --git a/Core/EM/HddSecurity/Hddpassword/ForceHddPassword.c b/Core/EM/HddSecurity/Hddpassword/ForceHddPassword.c
new file mode 100644
index 0000000..90c9a4d
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/ForceHddPassword.c
@@ -0,0 +1,158 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/ForceHddPassword.c 2 10/11/10 6:19p Krishnakumarg $
+//
+// $Revision: 2 $
+//
+// $Date: 10/11/10 6:19p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/ForceHddPassword.c $
+//
+// 2 10/11/10 6:19p Krishnakumarg
+// [TAG] - EIP 45593
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Build Errors in ForceHDDPassword.c on new core 4.6.4.1
+// label
+// [RootCause]- IDE_CONTROLLER_PROTOCOL structure defined header not
+// included
+// [Solution] - Include the respective header(PIDEController.h)
+// [Files] - ForceHddPassword.c
+//
+// 1 8/19/10 2:44a Rameshr
+// Issue:Need do HDD PSW reset when warmboot
+// EIP 40528
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ForceHddPassword.c
+//
+// Description: Send Disable Software Preservation command when the
+// FORCE_HDD_PASSWORD_PROMPT token is set to 1
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include "Protocol\PAhciBus.h"
+#include "Protocol\PIDEBus.h"
+
+
+EFI_RUNTIME_SERVICES *gRT;
+EFI_BOOT_SERVICES *gBS;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableSoftwarePreservation
+//
+// Description: Send the Disable software Preservation
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DisableSoftwarePreservation ( )
+{
+#if FORCE_HDD_PASSWORD_PROMPT
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINT8 i;
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+ EFI_GUID gEfiAhciBusProtocolGuid = AHCI_BUS_INIT_PROTOCOL_GUID;
+ SATA_DEVICE_INTERFACE *SataDeviceInterface;
+ DLINK *dlink;
+ COMMAND_STRUCTURE CommandStructure = {0};
+ EFI_STATUS Status;
+
+
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiAhciBusProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+
+ if(EFI_ERROR(Status) || HandleCount == 0 ) {
+ return;
+ }
+
+ //
+ // Issue Disable Software Preservation command all the Sata Devices connected.
+ //
+ for (i = 0; i < HandleCount; i++) {
+ Status = gBS->HandleProtocol (HandleBuffer[i], &gEfiAhciBusProtocolGuid, &AhciBusInterface);
+ if (!EFI_ERROR(Status)) {
+ dlink = AhciBusInterface->SataDeviceList.pHead;
+ if (dlink){
+ do {
+ SataDeviceInterface = OUTTER(dlink, SataDeviceLink, SATA_DEVICE_INTERFACE);
+
+ if ((SataDeviceInterface->IdentifyData.Reserved_76_79[0] != 0xFFFF )&&
+ (SataDeviceInterface->IdentifyData.Reserved_76_79[2] & 0x0040)&& // Software Preservation support
+ (SataDeviceInterface->IdentifyData.Security_Status_128 & 0x0002)&& // Security enabled
+ (!(SataDeviceInterface->IdentifyData.Security_Status_128 & 0x0004))) { // Security not locked
+
+ //
+ // Send Disable Software Preservation command.
+ //
+ CommandStructure.Features = DISABLE_SATA2_SOFTPREV;
+ CommandStructure.SectorCount = 6;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ Status = AhciBusInterface->ExecuteNonDataCommand(SataDeviceInterface, CommandStructure);
+ }
+ dlink = dlink-> pNext;
+ }while (dlink);
+ }
+ }
+ }
+#endif
+ return;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HddSecurity/Hddpassword/HddPassword.c b/Core/EM/HddSecurity/Hddpassword/HddPassword.c
new file mode 100644
index 0000000..1de9072
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddPassword.c
@@ -0,0 +1,2631 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddPassword.c 43 3/26/15 2:01a Rameshr $
+//
+// $Revision: 43 $
+//
+// $Date: 3/26/15 2:01a $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddPassword.c $
+//
+// 43 3/26/15 2:01a Rameshr
+// [TAG] EIP208331
+// [Category] New Feature
+// [Description] Avoid sending freeze Lock command to the device if the
+// HDD already in frozen state
+// [Files] HddPassword.c
+//
+// 42 3/16/15 5:51a Rameshr
+// [TAG] EIP208331
+// [Category] Improvement
+// [Description] Avoid sending freeze Lock command to the device if the
+// HDD already in frozen state
+// [Files] IdeSecurity.c, HddPassword.c
+//
+// 41 9/10/14 3:07a Divyac
+// [TAG] EIP182213
+// [Category] Improvement
+// [Description] Use System table conout Clearscreen instead of
+// ClearScreen() from TSE to avoid active buffer updation.
+// [Files] HddPassword.c
+//
+// 40 9/10/14 2:58a Divyac
+// [TAG] EIP181548
+// [Category] Improvement
+// [Description] Implement event signaling during HDD Passwords Prompt.
+// [Files] HddPassword.c
+// HddPassword.h
+//
+// 39 12/18/13 4:09a Srikantakumarp
+// [TAG] EIP127356
+// [Category] Improvement
+// [Description] Flash NVRAM seems to cause HDD can't be unlocked when
+// S3 resume.
+// [Files] IdeSecurity.c, IDESMM.c, HddPassword.c, AhciBus.c, AhciBus.h
+//
+// 38 6/06/13 4:10a Rameshr
+// [TAG] EIP106423
+// [Category] Improvement
+// [Description] HddPassword Support in UEFI Raid and Legacy Raid. And
+// also taken care where there is no Conin Device avilable in the post
+// [Files] IdeSecurity.cif,IdeSecurity.sdl,IdeSecurity.mak,IdeSecurityB
+// dsCall.c,HddPassword.c, Ahcibus.c, Pidebus.h
+//
+// 37 5/29/13 8:08a Srikantakumarp
+// [TAG] EIP123088
+// [Category] Improvement
+// [Description] Added the Wrapper function to pass HDD status and flag
+// to show maximum unlocking attempt is reached.
+// [Files] HddPassword.c
+//
+// 36 4/29/13 2:30a Kapilporwal
+// fixing build errors, when tse soruce is not present, from last check-in
+//
+// 35 4/25/13 9:28a Kapilporwal
+// [TAG] EIP108583
+// [Category] New Feature
+// [Description] support set HDD password in same page
+// [Files] IdeSecurity.cif, IdeSecurity.mak, IdeSecurity.sdl,
+// IdeSecurity.uni, IdeSecurityCommon.sd, IdeSecuritySetup.c,
+// HddPassword.c, HddPassword.h, HddPassword.mak, HddPassword.sdl
+//
+// 34 3/25/13 6:01a Rameshr
+// [TAG] EIP113655
+// [Category] Improvement
+// [Description] Invoke TSEIDEPasswordCheck() function only if password
+// is set to the HDD and also to remove the unnecessary save screen in
+// IDEPasswordCheck() of HDD security module.
+// [Files] HddPassword.c
+//
+// 33 3/25/13 5:14a Rameshr
+// [TAG] EIP117159
+// [Category] Improvement
+// [Description] Proper error message displayed when the Password count
+// expired
+// [Files] HddPassword.c, HddPassword.uni, HddSecTokens.c
+//
+// 32 9/03/12 1:49a Srilathasc
+// [TAG] EIP99649
+// [Category] Improvement
+// [Description] Made IDEPasswordUpdateHdd() symmetric with
+// IDEPasswordAuthenticateHdd() when
+// token SETUP_PASSWORD_NON_CASE_SENSITIVE is set
+//
+//
+// [Files] HddPassword.c
+//
+// 31 6/07/12 12:34a Jittenkumarp
+// [TAG] EIP89271
+// [Category] Bug Fix
+// [Symptom] HDD Security string not displayed properly on multilanguage
+// [RootCause] Languages not initilized by AMITSE
+// [Solution] Languages is now initilized .Hddsecurity string is
+// displayed properly for multilanguage.
+//
+// [Files] HddPassword.c
+//
+// 30 2/13/12 1:39a Deepthins
+// [TAG] EIP81680
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The password set for DEFAULT_MASTER_PASSWORD_TAG token is
+// not authenticated when the token SETUP_PASSWORD_NON_CASE_SENSITIVE is
+// set to 1.
+// [RootCause] When the master password is not installed, Master
+// password Prompt window should not displayed
+// [Solution] Removed master password prompt window, when the master
+// password is not installed
+// [Files] HddPassword.c
+//
+// 29 1/10/12 4:41a Deepthins
+// [TAG] EIP76872
+// [Category] Improvement
+// [Description] If user password are all wrong, then try master
+// password(no need to press 'ESC').
+// [Files] HddPassword.c, HddPassword.sdl
+//
+// 28 11/16/11 1:19a Rameshr
+// [TAG] EIP75245
+// [Category] Improvement
+// [Description] RegisterHddNotification does not match AMITSE hook
+// return values. Modified the function to match the AMITSE hook return
+// values.
+// [Files] Hddpassword.c
+//
+// 27 11/09/11 12:30a Rameshr
+// [TAG] EIP62381
+// [Category] Improvement
+// [Description] SB template version checking added to avoid the build
+// error on old SB template project
+// [Files] HddPassword.c
+//
+// 26 11/08/11 3:33a Rameshr
+// [TAG] EIP72999
+// [Category] Improvement
+// [Description] Modified the function to support the
+// OVERRIDE_TSEIDEPasswordCheck SDL token
+// [Files] Hddpassword.c
+//
+// 25 10/11/11 1:41a Rameshr
+// [TAG] EIP69244
+// [Category] Improvement
+// [Description] The number of retry count for user and master password
+// added based on the MAXIMUM_HDD_UNLOCK_ATTEMPTS SDL token value.
+// [Files] HddPassword.c , HddPassword.Sdl
+//
+// 24 10/07/11 7:01a Rajeshms
+// [TAG] EIP71205
+// [Description] Idesecurity module throws build error with AMITSE
+// Bootonly flavour.
+// [Files] HddPassword.c
+//
+// 23 9/09/11 4:58a Rameshr
+// [TAG] - EIP 69521
+// [Category]- IMPROVEMENT
+// [Description]- Idesecurity module to be compatible with AMITSE BootOnly
+// flavor
+// [Files] - HddPassword.c
+//
+// 22 9/02/11 4:07a Rameshr
+// [TAG] - EIP 67674
+// [Category]- IMPROVEMENT
+// [Description]- All buffers allocated from heap during password checking
+// should be zeroed before freeing - security requirement
+// [Files] - HddPassword.c
+//
+// 21 7/15/11 7:26a Rameshr
+// [TAG] - EIP 63320
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Port1 HDD's password setting item is disappeared, if the
+// device is connected to another controller.
+// [RootCause]- When the second controller HDD detected and comes for the
+// Password verfication, the already password validated HDD information is
+// lost.
+// [Solution] - Saved the existing data if it's already password verified
+// and added to the new data
+// [Files] - Hddpassword.c
+//
+// 20 6/28/11 6:31a Anandv
+// [TAG] EIP62381
+// [Category] Improvement
+// [Description] In IdeSecurity Module, display HDD number in Setup
+// based on
+// results from WhichIde() function of DiskInfoProtocol.
+// [Files] HddPassword.c, HddPassword.h, SBDxe.c, PIDEController.h
+//
+// 19 2/18/11 5:45a Rameshr
+// [TAG]- EIP 37975
+// [Category]-IMPROVEMENT
+// [Description]- Klocwork Issues II - IDE/Ahci module
+// [Files]- HddPassword.c
+//
+// 18 2/01/11 6:22a Lavanyap
+// [TAG] - EIP52585
+// [Category] - BUG FIX
+// [Severity] - N/A
+// [Symptom] - HDD password can not be disabled in setup menu when turn on
+// token "ALL_HDD_SAME_PW"
+// [RootCause] - Authenticate HDD only if it is locked,which fails when
+// ALL_HDD_SAME_PW is set.
+// [Solution] - Removed the code that checks HDD locked state in
+// IDEPasswordAuthenticateAllHdd().
+// [Files] - HddPassword.c
+//
+// 17 1/10/11 9:54a Rameshr
+// [TAG] EIP49732
+// [Category] Improvement
+// [Description] Build problem Resolved with Old AMITSE version.
+// [Files] Build problem Resolved with Old AMITSE version.
+//
+// 16 1/07/11 12:08a Rameshr
+// [TAG]- EIP 49732
+// [Category]-IMPROVEMENT
+// [Description]- Supported added for SETUP_PASSWORD_NON_CASE_SENSITIVE
+// [Files]- Hddpassword.c
+//
+// 15 12/28/10 4:31a Lavanyap
+// [TAG] - EIP50988
+// [Category] - BUG FIX
+// [Severity] - Important
+// [Symptom] - Hddpassword doesn't work properly with more than 1 HDD with
+// ALL_HDD_SAME_PW set to 0.
+// [RootCause] - Not added the AMITSE changes for the implementation of
+// ALL_HDD_SAME_PW token.
+// [Solution] - Changes in AMITSE module for the implementation of token
+// ALL_HDD_SAME_PW moved to AmitseHddpassword.
+// [Files] - HddPassword.c
+//
+// 14 12/07/10 6:36a Rameshr
+// [TAG] - EIP 46116
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - When enter the BIOS Setup :"security" page ,it will hang
+// up.
+// [RootCause]- 1. Freepool function doesn't have proper input
+// 2. Size variable not initilized.
+// [Solution] - 1. Removed using gBs pointer and used Lib Function
+// 2. Size variable initilized with 0.
+// [Files] - Hddpassword.c
+//
+// 13 8/27/10 2:30p Yul
+// [TAG] EIP40151
+// [Category] NEW FEATURE
+// [Description] If system has two HDDs, User need set two HDDs password
+// separately with master and user password.
+// We want to simply the procedure, if user set master or user password,
+// it will set two HDDs with same password.
+// While un-lock the HDD password, user just need input one Master/User
+// password to un-lock HDD.
+// [Files] HddPassword.c
+// HddPassword.sdl
+// IdeSecurity.sd
+// IdeSecurity.uni
+// Same as v12. No code update.
+//
+// 12 8/27/10 10:05a Yul
+// EIP 40151 - One Master/User password for all attach HDDs
+//
+// 11 8/27/10 12:15a Rameshr
+// [TAG] - EIP 43059
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom]- Build Errors in HddPassword.c on non INTEL_IDE_PROTOCOL
+// Projects.
+// [RootCause]- Hddpassword.c included the PIdebus.h . PIdebus.h uses the
+// IDE_CONTROLLER_PROTOCOL protocol.
+// [Solution]- Before Pidebus.h included, included the PIDEController.h
+// also. .
+// [Files] - Hddpassword.c
+//
+// 10 8/26/10 2:43a Rameshr
+// [TAG] - EIP42594
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom]- [IdeSecurity]IdeSecConfig variable not set when there is on
+// HDD connected
+// [RootCause]- IdeSecConfig variable is not set when no HDD is present,
+// thus the HDD count value (IdeSecConfig.Count) checking fails in
+// IdeSecurity.sd and displays the label always.
+// [Solution]- Initialised the structure IdeSecConfig to zero if no HDD is
+// present.
+// [Files]- HddPassword.c
+//
+// 9 6/07/10 7:20p Krishnakumarg
+// Build error in "4.6.3_HddSecurity_011" label.EIP#39531
+//
+// 8 5/21/10 2:58p Aaronp
+// Fix for EIP 38473 - Device names are not displayed when built in UEFI
+// 2.1 mode
+//
+// 7 5/11/10 3:57p Krishnakumarg
+// Coding standard.
+//
+// 6 3/29/10 2:24p Yul
+// Refer to EIP 36288.
+// Once SETUP_SAME_SYS_HDD_PW is ON, AHCI mode fails to boot OS
+// with specific Hard Drive.
+//
+// 5 3/26/10 5:42p Krishnakumarg
+// UEFI2.1 compliance change EIP#34744.
+//
+// 4 3/11/10 3:49a Rameshr
+// Issue: Same Structure definied in Hddpassword and Amitse.
+// Solution: Amitse created tsecommon.h with all the common definition.
+// EIP: 27339
+//
+// 3 1/15/10 10:10a Yul
+// Coding Standard
+//
+// 2 9/28/09 4:59p Rameshr
+// The data structure AMI_IFR_MSGBOX in HddPassword.h and MessageBox.h are
+// not the same
+// EIP 27157
+//
+// 1 5/01/09 11:09a Rameshr
+// Initial Check-in
+//*****************************************************************************//
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Hddpassword.c
+//
+// Description: Provides the Hddpassword Screen support in the setup.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "AmiDxeLib.h"
+#include "token.h"
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#include "Include\UefiHii.h"
+#include "Protocol\HiiDatabase.h"
+#include "Protocol\HiiString.h"
+#else
+#include <Protocol/Hii.h>
+#endif
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+#include "minisetup.h"
+#endif
+#include "Protocol\PciIo.h"
+#include "Protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include "Protocol\PAhciBus.h"
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextOut.h>
+#include <Protocol/AMIPostMgr.h>
+#include "AMITSEStrTokens.h"
+#include "AmiVfr.h"
+#include "HddPassword.h"
+#include "Protocol\DevicePath.h"
+#if SETUP_SAME_SYS_HDD_PW
+#include "Core\EM\AMITSE\Inc\PwdLib.h"
+#include "Core\EM\AMITSE\Inc\Variable.h"
+#endif
+
+#ifdef SB_TEMPLATE_VER
+#if SB_TEMPLATE_VER > 6
+SB_HDD_POLICY_PROTOCOL *gSbHddPolicyPtr=NULL;
+EFI_GUID gSbHddPolicyProtocolGuid = SB_HDD_POLICY_PROTOCOL_GUID;
+#endif
+#endif
+
+
+EFI_GUID gDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+EFI_GUID gHddSecurityEndProtocolGuid = HDD_SECURITY_END_PROTOCOL_GUID;
+EFI_GUID gHddPasswordVerifiedGuid = HDD_PASSWORD_VERIFIED_GUID;
+EFI_GUID gIDESecGuid = IDE_SECURITY_CONFIG_GUID;
+EFI_GUID gIDESecurityProtocolGuid = IDE_SECURITY_INTERFACE_GUID;
+EFI_GUID gHddPasswordPromptEnterGuid = HDD_PASSWORD_PROMPT_ENTER_GUID;
+EFI_GUID gHddPasswordPromptExitGuid = HDD_PASSWORD_PROMPT_EXIT_GUID;
+
+static EFI_HII_STRING_PROTOCOL *HiiString = NULL;
+static CHAR8 *SupportedLanguages=NULL;
+
+
+typedef struct
+{
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity;
+ UINT16 NameToken;
+ UINT16 PromptToken;
+ BOOLEAN Locked;
+ BOOLEAN LoggedInAsMaster;
+ BOOLEAN Validated;
+ UINT8 PWD[IDE_PASSWORD_LENGTH + 1];
+} IDE_SECURITY_DATA;
+
+#if TSE_BUILD > 0x1206
+BOOLEAN IsPasswordSupportNonCaseSensitive();
+VOID UpdatePasswordToNonCaseSensitive(CHAR16 *Password, UINTN PwdLength);
+#endif
+
+VOID HddNotificationFunction(EFI_EVENT Event, VOID *HddRegContext);
+VOID IDEPasswordCheck(VOID);
+UINT16 IDEPasswordGetName(UINT16 Index);
+UINT16 IDESecurityProtocolInit();
+BOOLEAN HddPasswordGetDeviceName(EFI_HANDLE Controller,CHAR16 **wsName);
+BOOLEAN CheckSecurityStatus (
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity,
+ BOOLEAN *Locked,
+ UINT16 Mask );
+EFI_STATUS IDEPasswordAuthenticateHdd(
+ CHAR16 *Password,
+ VOID * Ptr,
+ BOOLEAN bCheckUser );
+
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+VOID IDEUpdateConfig(
+ VOID *TempideSecConfig,
+ UINTN value );
+
+VOID SearchTseHardDiskField (
+ BOOLEAN *pbCheckUser, BOOLEAN *pEnabledBit,
+ UINT8 *pHardDiskNumber, VOID *data );
+
+EFI_STRING_ID ConfigPromptToken = 0;
+extern UINTN gInvalidPasswordFailMsgBox;
+#else
+UINTN gCurrIDESecPage;
+#endif
+
+IDE_SECURITY_DATA *IDEPasswordSecurityData = NULL;
+EFI_HANDLE gHddSecEndHandle = NULL;
+EFI_HANDLE HddNotifyHandle;
+static EFI_HANDLE *gHandleBuffer = NULL;
+EFI_EVENT HddNotifyEvent;
+VOID *HddNotifyRegistration;
+BOOLEAN HddFreeze = FALSE;
+UINT16 gIDESecurityCount = 0;
+BOOLEAN gFlag = FALSE;
+
+
+VOID EfiStrCpy (IN CHAR16 *Destination,IN CHAR16 *Source);
+UINTN EfiStrLen (IN CHAR16 *String);
+extern VOID TSEIDEPasswordCheck();
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddSecuritySignalProtocolEvent
+//
+// Description: Internal function that installs/uninstall protocol
+// with a specified GUID and NULL interface.
+// Such protocols can be used as event signaling mechanism.
+//
+//
+// Input: ProtocolGuid Pointer to the protocol GUID.
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+HddSecuritySignalProtocolEvent (
+ IN EFI_GUID *ProtocolGuid
+)
+{
+
+ EFI_HANDLE Handle = NULL;
+
+ pBS->InstallProtocolInterface (
+ &Handle,
+ ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL );
+
+ pBS->UninstallProtocolInterface (
+ Handle,
+ ProtocolGuid,
+ NULL);
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RegisterHddNotification
+//
+// Description: Register the Protocol call back event
+//
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN RegisterHddNotification( VOID )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+ Status = gBS->CreateEvent( EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ HddNotificationFunction,
+ &HddNotifyRegistration,
+ &HddNotifyEvent);
+
+ Status = gBS->RegisterProtocolNotify( &gHddSecurityEndProtocolGuid,
+ HddNotifyEvent,
+ &HddNotifyRegistration);
+
+ //
+ // get any of these events that have occured in the past
+ //
+ gBS->SignalEvent( HddNotifyEvent );
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddNotificationFunction
+//
+// Description: Hdd notification function gets called when HddSecurityEnd Protocol get installed.
+//
+// Input:
+// EFI_EVENT Event - Event to signal
+// void HddRegContext - Event specific context (pointer to NotifyRegisteration
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID HddNotificationFunction( EFI_EVENT Event, VOID *HddRegContext )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer = NULL;
+ IDE_SECURITY_CONFIG *IdeSecConfig = NULL;
+ IDE_SECURITY_CONFIG ideSecConfig;
+ IDE_SECURITY_DATA *DataPtr=NULL;
+ UINTN NumHandles;
+ UINTN IdeSecConfigSize = 0;
+ UINTN Index=0;
+
+ if ( HddRegContext == NULL )
+ return;
+ //
+ // Initialise IdeSecConfig information if this variable is not set already.
+ //
+ IdeSecConfig = VarGetNvramName( L"IDESecDev", &gIDESecGuid, NULL, &IdeSecConfigSize );
+
+ if ( !IdeSecConfig ) {
+
+ IdeSecConfig = EfiLibAllocateZeroPool( sizeof(IDE_SECURITY_CONFIG));
+
+ if ( IdeSecConfig == NULL ) {
+ return;
+ }
+ MemSet( IdeSecConfig, sizeof(IDE_SECURITY_CONFIG), 0);
+ VarSetNvramName( L"IDESecDev",
+ &gIDESecGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ IdeSecConfig,
+ sizeof(IDE_SECURITY_CONFIG));
+ } else {
+ MemFreePointer( (VOID **)&IdeSecConfig );
+ }
+
+ //
+ //Locate the handle
+ //
+ Status = gBS->LocateHandleBuffer( ByRegisterNotify,
+ NULL,
+ *(VOID**)HddRegContext,
+ &NumHandles,
+ &HandleBuffer);
+
+ //
+ // If protocol not installed return
+ //
+ if ( EFI_ERROR( Status ))
+ return;
+
+ gHddSecEndHandle = HandleBuffer[0];
+
+ //
+ //Locate the Security Protocols
+ //
+ gIDESecurityCount = IDESecurityProtocolInit();
+
+ for(Index=0; Index<gIDESecurityCount; Index++){
+ //
+ //Initialize the DataPtr
+ //
+ DataPtr = (IDE_SECURITY_DATA *) IDEPasswordGetDataPtr(Index);
+
+ //
+ // Search for locked Hard disc and not password verification done
+ //
+ if(DataPtr->Locked && !DataPtr->Validated){
+ break;
+ }
+ }
+
+ //
+ // Validate the password only if HDD is locked
+ //
+ if( (gIDESecurityCount != 0 ) && (NULL != DataPtr ) &&
+ (DataPtr->Locked ) && (!DataPtr->Validated ) ){
+ TSEIDEPasswordCheck();
+ } else {
+ //
+ // Update the IdeSecConfig information .
+ //
+ MemSet( &ideSecConfig, sizeof(ideSecConfig), 0 );
+ ideSecConfig.Count = gIDESecurityCount;
+ VarSetNvramName( L"IDESecDev",
+ &gIDESecGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ &ideSecConfig,
+ sizeof(ideSecConfig));
+ }
+
+ //
+ // Install the Unlocked Protocol to nitify HDD has been unlocked
+ //
+ if ( gHddSecEndHandle != NULL ) {
+ Status = gBS->InstallProtocolInterface( &gHddSecEndHandle,
+ &gHddPasswordVerifiedGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL);
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrivateHiiAddString
+//
+// Description: Add the String to Hii Database using HiiString Protocol
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle,
+// IN CHAR16 * String
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STRING_ID PrivateHiiAddString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR16 * String)
+{
+ EFI_STATUS Status;
+ CHAR8* Languages = NULL;
+ UINTN LangSize = 0;
+ CHAR8* CurrentLanguage;
+ BOOLEAN LastLanguage = FALSE;
+ EFI_STRING_ID StringId = 0;
+
+ if(HiiString == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
+ if(EFI_ERROR(Status)) {
+ return 0;
+ }
+ }
+
+ if(SupportedLanguages == NULL) {
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, Languages, &LangSize);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, LangSize, &Languages);
+ if(EFI_ERROR(Status)) {
+ //
+ //not enough resources to allocate string
+ //
+ return NULL;
+ }
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, Languages, &LangSize);
+ }
+ SupportedLanguages=Languages;
+ } else {
+ Languages=SupportedLanguages;
+ }
+
+ while(!LastLanguage) {
+ //
+ //point CurrentLanguage to start of new language
+ //
+ CurrentLanguage = Languages;
+ while(*Languages != ';' && *Languages != 0)
+ Languages++;
+
+ //
+ //Last language in language list
+ //
+ if(*Languages == 0) {
+ LastLanguage = TRUE;
+ if(StringId == 0) {
+ Status = HiiString->NewString(HiiString, HiiHandle, &StringId, CurrentLanguage, NULL, String, NULL);
+ } else {
+ Status = HiiString->SetString(HiiString, HiiHandle, StringId, CurrentLanguage, String, NULL);
+ }
+ if(EFI_ERROR(Status)) {
+ return 0;
+ }
+ } else {
+ //
+ //put null-terminator
+ //
+ *Languages = 0;
+ if(StringId == 0) {
+ Status = HiiString->NewString(HiiString, HiiHandle, &StringId, CurrentLanguage, NULL, String, NULL);
+ } else {
+ Status = HiiString->SetString(HiiString, HiiHandle, StringId, CurrentLanguage, String, NULL);
+ }
+ *Languages = ';'; //restore original character
+ Languages++;
+ if(EFI_ERROR(Status)) {
+ return 0;
+ }
+ }
+ }
+ return StringId;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PasswordHiiAddString
+//
+// Description: Add the String to HiiDatabase
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle,
+// IN CHAR16 * String
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STRING_ID PasswordHiiAddString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN CHAR16 * String )
+{
+ EFI_STRING_ID StringId = 0;
+
+ StringId=PrivateHiiAddString( HiiHandle, String );
+
+ //
+ // Error in Adding String. Try with Default function that AMITSE has.
+ //
+ if(StringId == 0) {
+ StringId= HiiAddString( HiiHandle, String );
+ }
+
+ return StringId;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDESecurityProtocolInit
+//
+// Description: Locate the Security Protocols and return the information
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 IDESecurityProtocolInit( )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer = NULL;
+ UINT16 i, j, HDDCount = 0;
+ UINTN Count;
+ CHAR16 * Name, *Temp1;
+ CHAR16 Temp[60];
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity = NULL;
+ IDE_SECURITY_DATA *DataPtr = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ PCI_DEVICE_PATH *PciDevicePath;
+ SECURITY_PROTOCOL *Security = NULL;
+ UINT32 HddPortNumber;
+ CHAR16 *Buff=L"P";
+ EFI_DISK_INFO_PROTOCOL *DiskInfoPtr=NULL;
+ UINT32 PortNumber;
+ UINT32 PMPortNumber;
+ IDE_SECURITY_DATA *TempIDEPasswordSecurityData = NULL;
+
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+ if(ConfigPromptToken == 0)
+ ConfigPromptToken = PasswordHiiAddString( gHiiHandle, L"HDD Security Configuration" );
+#endif
+
+ Status = gBS->LocateHandleBuffer( ByProtocol,
+ &gIDESecurityProtocolGuid,
+ NULL,
+ &Count,
+ &HandleBuffer);
+
+ //
+ // If already data has been found return with that information
+ //
+ if ( gIDESecurityCount != 0 && IDEPasswordSecurityData != NULL ) {
+ if ( gIDESecurityCount == Count ) {
+ return gIDESecurityCount; //the IDE struct is valid
+ }
+
+ //
+ // New HDD device found. Need to validate the password for the new HDD
+ // and skip the HDD that has been already validated.
+ //
+ TempIDEPasswordSecurityData = IDEPasswordSecurityData;
+ IDEPasswordSecurityData = EfiLibAllocateZeroPool( Count * sizeof(IDE_SECURITY_DATA));
+ //
+ // Copy the Existing HDD data
+ //
+ MemCopy( IDEPasswordSecurityData, TempIDEPasswordSecurityData, sizeof(IDE_SECURITY_DATA) * gIDESecurityCount );
+ MemFreePointer((VOID**)&TempIDEPasswordSecurityData );
+ DataPtr = IDEPasswordSecurityData;
+ //
+ // DataPtr moved to free Entry
+ //
+ DataPtr+=gIDESecurityCount;
+ HDDCount=gIDESecurityCount;
+
+ } else {
+ //
+ // Allocate the buffer for DataPtr
+ //
+ IDEPasswordSecurityData = EfiLibAllocateZeroPool( Count * sizeof(IDE_SECURITY_DATA));
+ DataPtr = IDEPasswordSecurityData;
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return 0;
+ }
+
+
+ if(DataPtr == NULL) {
+ return 0;
+ }
+
+
+ if ( gHandleBuffer != NULL ) {
+ MemFreePointer( (VOID **)&gHandleBuffer );
+ }
+
+ gHandleBuffer = EfiLibAllocateZeroPool( sizeof(EFI_HANDLE) * Count );
+
+ for ( i = 0; i < Count; i++ ) {
+ //
+ // Check if already Validate or not. If already validate don't verify the password again.
+ //
+ if ( gHandleBuffer != NULL && gIDESecurityCount != 0 ) {
+ j = gIDESecurityCount;
+
+ do {
+ if ( HandleBuffer[i] == gHandleBuffer[j - 1] ) {
+ break;
+ }
+ j--;
+ } while ( j != 0 );
+
+ if ( j != 0 )
+ continue;
+ }
+
+ //
+ // Get the PasswordSecurity Protocol
+ //
+ Status = gBS->OpenProtocol( HandleBuffer[i],
+ &gIDESecurityProtocolGuid,
+ (VOID**) &IDEPasswordSecurity,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if ( EFI_ERROR( Status ))
+ continue;
+ //
+ // Handle the DiskInfo Protocol
+ //
+ Status = gBS->OpenProtocol( HandleBuffer[i],
+ &gDiskInfoProtocolGuid,
+ (VOID**) &DiskInfoPtr,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if ( EFI_ERROR( Status )){
+ continue;
+ }
+ //
+ // Locate the device path Protocol
+ //
+ Status = gBS->OpenProtocol( HandleBuffer[i],
+ &gDevicePathProtocolGuid,
+ (VOID**)&DevicePath,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if ( EFI_ERROR( Status )){
+ continue;
+ }
+
+ DevicePathNode = DevicePath;
+
+ //
+ // Traverse the Device Path structure till we reach HARDWARE_DEVICE_PATH
+ //
+ while (!isEndNode (DevicePathNode)) {
+
+ if ((DevicePathNode->Type == HARDWARE_DEVICE_PATH) &&
+ (DevicePathNode->SubType == HW_PCI_DP)){
+
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+ break;
+ }
+
+ DevicePathNode = NEXT_NODE (DevicePathNode);
+ }
+
+ if (PciDevicePath == NULL) continue;
+
+ Security=(SECURITY_PROTOCOL *)IDEPasswordSecurity;
+
+ if(Security->ModeFlag){
+ //
+ // Controller is in Ahci Mode, Call WhichIde function to find out Port Number
+ //
+ DiskInfoPtr->WhichIde(DiskInfoPtr,&PortNumber,&PMPortNumber);
+ //
+ // Assign the PortNumber to HddPortNumber.This Port Number is displayed in Setup.
+ //
+ HddPortNumber=PortNumber;
+
+ gFlag=TRUE;
+
+ }else{
+
+#ifdef SB_TEMPLATE_VER
+#if SB_TEMPLATE_VER > 6
+{
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+
+ if(gSbHddPolicyPtr==NULL){
+ Status=gBS->LocateProtocol(&gSbHddPolicyProtocolGuid,
+ NULL, \
+ &gSbHddPolicyPtr);
+ }
+
+ if(gSbHddPolicyPtr!=NULL){
+
+ //
+ // Find out the Primary/Secondary,Master/Slave Info from WhichIde function
+ //
+ DiskInfoPtr->WhichIde(DiskInfoPtr,&IdeChannel,&IdeDevice);
+ //
+ // Get the Port Number to which the HDD is connected
+ //
+ gSbHddPolicyPtr->GeneratePortNumber(PciDevicePath->Device,PciDevicePath->Function,
+ IdeChannel,IdeDevice,&PortNumber);
+
+ HddPortNumber=PortNumber;
+
+ gFlag=TRUE;
+
+ }else{
+
+ //
+ // SB HDD Policy Protocol is not Present.
+ //
+ gFlag=FALSE;
+ }
+}
+#endif
+#endif
+
+ }
+ if ( CheckSecurityStatus( IDEPasswordSecurity, &(DataPtr->Locked), SecurityLockedMask )) {
+ DataPtr->IDEPasswordSecurity = IDEPasswordSecurity;
+
+ if ( HddPasswordGetDeviceName( HandleBuffer[i], &Name )) {
+ DataPtr->NameToken = PasswordHiiAddString( gHiiHandle, Name );
+ Name[12] = 0;
+ if(gFlag){
+ //
+ // Display the the Port Number in Setup
+ //
+ SPrint( Temp, 60, L"%s%d:%s", Buff, HddPortNumber, Name );
+ DataPtr->PromptToken = PasswordHiiAddString( gHiiHandle, Temp );
+ }else{
+ //
+ // If SB HDD Policy Protocol is not Installed Use STR_IDE_SECURITY_PROMPT
+ // token to display the String Information.
+ //
+ Temp1 = HiiGetString( gHiiHandle, STRING_TOKEN( STR_IDE_SECURITY_PROMPT ));
+ SPrint( Temp, 60, L"%s%d:%s", Temp1,HDDCount,Name);
+ DataPtr->PromptToken = PasswordHiiAddString( gHiiHandle, Temp );
+ }
+ } else {
+ if(gFlag){
+ //
+ // Display the the Port Number in Setup
+ //
+ SPrint( Temp, 60, L"%s%d", Buff, HddPortNumber );
+ DataPtr->NameToken = PasswordHiiAddString( gHiiHandle, Temp );
+ DataPtr->PromptToken = PasswordHiiAddString( gHiiHandle, Temp );
+ }else{
+ //
+ // If SB HDD Policy Protocol is not Installed Use STR_IDE_SECURITY_PROMPT
+ // token to display the String Information.
+ //
+ Temp1 = HiiGetString( gHiiHandle, STRING_TOKEN( STR_IDE_SECURITY_PROMPT ));
+ SPrint( Temp, 60, L"%s%d", Temp1, HDDCount);
+ DataPtr->NameToken = PasswordHiiAddString( gHiiHandle, Temp );
+ DataPtr->PromptToken = PasswordHiiAddString( gHiiHandle, Temp );
+ }
+ }
+ DataPtr->Validated = FALSE;
+
+ if(DataPtr->Locked) {
+ gHandleBuffer[i]=HandleBuffer[i];
+ }
+
+ DataPtr++;
+ HDDCount++;
+ }// end if
+
+ }// end of for
+
+ //
+ //if no hd is supported
+ //
+ if ( HDDCount == 0 ) {
+ MemFreePointer((VOID**)&IDEPasswordSecurityData );
+ IDEPasswordSecurityData=NULL;
+ }
+
+ MemFreePointer((VOID**)&HandleBuffer );
+
+ return HDDCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordGetLocked
+//
+// Description: Return Hdd Locked Information
+//
+// Input: UINTN Index
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IDEPasswordGetLocked(
+ UINTN Index )
+{
+ IDE_SECURITY_DATA *DataPtr = (IDE_SECURITY_DATA*)IDEPasswordGetDataPtr( Index );
+
+ if(DataPtr == NULL) {
+ return 0;
+ }
+ return DataPtr->Locked;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckSecurityStatus
+//
+// Description: return the Security Status Information
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckSecurityStatus(
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity,
+ BOOLEAN *ReqStatus,
+ UINT16 Mask )
+{
+ UINT16 SecurityStatus = 0;
+ EFI_STATUS Status;
+
+ //
+ //get the security status of the device
+ //
+ Status = IDEPasswordSecurity->ReturnSecurityStatus( IDEPasswordSecurity, &SecurityStatus );
+
+ if ( EFI_ERROR( Status ))
+ return FALSE;
+
+ *ReqStatus = (BOOLEAN)((SecurityStatus & Mask) ? TRUE : FALSE );
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddPasswordDPLength
+//
+// Description: return the Device path Length
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN HddPasswordDPLength( EFI_DEVICE_PATH_PROTOCOL *pDp )
+{
+ UINTN Size = 0;
+
+ for (; !(IsDevicePathEnd( pDp )); pDp = NextDevicePathNode( pDp ))
+ Size += DevicePathNodeLength( pDp );
+
+ //
+ // add size of END_DEVICE_PATH node
+ //
+ return Size + END_DEVICE_PATH_LENGTH;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddPasswordDPGetLastNode
+//
+// Description: Returns pointer on very last DP node before END_OF_DEVICE_PATH node
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* HddPasswordDPGetLastNode( EFI_DEVICE_PATH_PROTOCOL *pDp )
+{
+ EFI_DEVICE_PATH_PROTOCOL *dp = NULL;
+
+ for (; !IsDevicePathEnd( pDp ); pDp = NextDevicePathNode( pDp ))
+ dp = pDp;
+
+ return dp;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddPasswordDPCopy
+//
+// Description: Copy the Device path to another Memory buffer
+//
+// Input:
+// EFI_DEVICE_PATH_PROTOCOL *pDp
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* HddPasswordDPCopy( EFI_DEVICE_PATH_PROTOCOL *pDp )
+{
+ UINTN l = HddPasswordDPLength( pDp );
+ UINT8 *p = EfiLibAllocateZeroPool( l );
+
+ MemCopy( p, pDp, l );
+ return p;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddPasswordGetDeviceName
+//
+// Description: Return the Drive String Name
+//
+// Input: EFI_HANDLE Controller - the handle of the drive
+// CHAR16 **wsName - returned pointer to the drive string
+//
+// Output: BOOLEAN - TRUE - drive string has been found and is in wsName
+// - FALSE - drive string has not been found
+//
+// Notes: it is the caller's responsibility to deallocate the space used for
+// wsName
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN HddPasswordGetDeviceName(EFI_HANDLE Controller, CHAR16 **wsName)
+{
+ EFI_STATUS Status;
+ SECURITY_PROTOCOL *Security = NULL;
+
+ CHAR16 *DeviceName;
+ BOOLEAN ReturnStatus = FALSE;
+
+ // Get the SECURITY_PROTOCOL (actually getting the IDE_SECURITY_PROTOCOL, but
+ // the SECURITY_PROTOCOL is an extended version with more information)
+ Status = gBS->HandleProtocol(Controller, &gIDESecurityProtocolGuid, &Security);
+ if ( !EFI_ERROR(Status) ) {
+ // Check the SATA controller operating mode, and based on the mode, get the UnicodeString
+ // name of the device
+ if ( Security->ModeFlag ) {
+ DeviceName = ((SATA_DEVICE_INTERFACE*)Security->BusInterface)->UDeviceName->UnicodeString;
+ } else {
+ DeviceName = ((IDE_BUS_PROTOCOL*)Security->BusInterface)->IdeDevice.UDeviceName->UnicodeString;
+ }
+
+ // Allocate space to copy the unicode device name string
+ *wsName = EfiLibAllocateZeroPool( sizeof(CHAR16)*(EfiStrLen(DeviceName)+1));
+
+ if ( *wsName!=NULL ) {
+ EfiStrCpy( *wsName, DeviceName);
+ ReturnStatus = TRUE;
+ }
+ }
+
+ // Return true to signify that a device name was discovered
+ return ReturnStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AMI_CheckIDEPassword
+//
+// Description: Get the password and Validate the HDD password
+//
+// Input:
+// UINT16 PromptToken,
+// VOID *DataPtr
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AMI_CheckIDEPassword(UINT16 PromptToken, VOID *DataPtr)
+{
+ UINTN CurrXPos, CurrYPos, i;
+ CHAR16 *PasswordEntered;
+ EFI_STATUS Status = EFI_ACCESS_DENIED;
+ UINT32 IdePasswordFlags = 0;
+ UINTN BoxLength = IDE_PASSWORD_LENGTH;
+ CHAR16 *DescToken = NULL;
+
+ UINT16 SecurityStatus=0;
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity = NULL;
+ CHAR16 *UnlckHddCBToken = NULL;
+ UINTN CB_BoxLength=0;
+
+ CheckForKeyHook((EFI_EVENT)NULL, NULL );
+ gST->ConIn->Reset( gST->ConIn, FALSE );
+ DescToken = HiiGetString( gHiiHandle, STRING_TOKEN( STR_IDE_ENTER_USER ));
+
+ if ( DescToken ) {
+ if ( (TestPrintLength( DescToken ) / NG_SIZE) > BoxLength ) {
+ BoxLength = TestPrintLength( DescToken ) / NG_SIZE;
+ }
+ }
+ MemFreePointer((VOID**) &DescToken );
+
+ UnlckHddCBToken = HiiGetString( gHiiHandle, STRING_TOKEN(STR_IDE_UNLCK_COLD));
+ if ( UnlckHddCBToken ) {
+ if ( (TestPrintLength( UnlckHddCBToken ) / NG_SIZE) > CB_BoxLength ) {
+ CB_BoxLength = TestPrintLength( UnlckHddCBToken ) / NG_SIZE;
+ }
+ }
+ MemFreePointer((VOID**) &UnlckHddCBToken );
+
+
+ HddSecuritySignalProtocolEvent(&gHddPasswordPromptEnterGuid);
+ //
+ //Draw password window
+ //
+#if ALL_HDD_SAME_PW
+ PromptToken = STRING_TOKEN( STR_IDE_SECURITY_PROMPT );
+#endif
+
+ _DrawPasswordWindow( PromptToken, BoxLength, &CurrXPos, &CurrYPos );
+ PasswordEntered = EfiLibAllocateZeroPool((IDE_PASSWORD_LENGTH + 1) * sizeof(CHAR16));
+ IDEPasswordSecurity=((IDE_SECURITY_DATA* )DataPtr)->IDEPasswordSecurity;
+ //
+ //Give four chances to enter user password
+ //
+ for ( i = 0; i < USER_PASSWORD_RETRY_ATTEMPTS; i++ ) {
+ Status = IDEPasswordSecurity->ReturnSecurityStatus(IDEPasswordSecurity, &SecurityStatus );
+ if(Status == EFI_SUCCESS && (SecurityStatus>>4)& 0x1){
+ _DrawPasswordWindow( PromptToken, CB_BoxLength, &CurrXPos, &CurrYPos );
+ _ReportInBox(CB_BoxLength,STRING_TOKEN(STR_IDE_UNLCK_COLD),CurrXPos,CurrYPos,TRUE);
+ HddSecuritySignalProtocolEvent(&gHddPasswordPromptExitGuid);
+ if (gST->ConOut != NULL) {
+ //Disable cursor, set desired attributes and clear screen
+ gST->ConOut->EnableCursor( gST->ConOut, FALSE );
+ gST->ConOut->SetAttribute( gST->ConOut, (EFI_BACKGROUND_BLACK | EFI_WHITE));
+ gST->ConOut->ClearScreen( gST->ConOut);
+ }
+ return ;
+ }
+ _ReportInBox( BoxLength, STRING_TOKEN(STR_IDE_ENTER_USER), CurrXPos, CurrYPos - 1, FALSE );
+
+ if ( EFI_SUCCESS !=_GetPassword(
+ PasswordEntered,
+ IDE_PASSWORD_LENGTH,
+ CurrXPos,
+ CurrYPos,
+ NULL )) {
+ break;
+ } // end if
+
+ //
+ // Validate the Password
+ //
+ Status = IDEPasswordAuthenticate( PasswordEntered, DataPtr, TRUE );
+
+ if ( EFI_SUCCESS == Status ) {
+ break;
+ } else if ((i + 1) != USER_PASSWORD_RETRY_ATTEMPTS ) {
+ _ReportInBox( IDE_PASSWORD_LENGTH, STRING_TOKEN(STR_ERROR_PSWD), CurrXPos, CurrYPos, TRUE );
+ }
+ }// end of for
+
+
+ #if SETUP_ASK_MASTER_PASSWORD
+
+ if ( EFI_SUCCESS != Status ) {
+ _ReportInBox( IDE_PASSWORD_LENGTH, STRING_TOKEN(STR_ERROR_PSWD), CurrXPos, CurrYPos, TRUE );
+ //
+ // Checking if the master password is installed
+ //
+ Status=((IDE_SECURITY_DATA*)DataPtr)->IDEPasswordSecurity->ReturnIdePasswordFlags(
+ ((IDE_SECURITY_DATA*)DataPtr)->IDEPasswordSecurity,
+ &IdePasswordFlags );
+
+ if((Status == EFI_SUCCESS)&&((IdePasswordFlags>>16)&1)) {
+ if ( i < MAXIMUM_HDD_UNLOCK_ATTEMPTS ) {
+ BoxLength = IDE_PASSWORD_LENGTH;
+ DescToken = HiiGetString( gHiiHandle, STRING_TOKEN( STR_IDE_ENTER_MASTER ));
+
+ if ( DescToken ) {
+ if (( TestPrintLength( DescToken ) / NG_SIZE) > BoxLength ) {
+ BoxLength = TestPrintLength( DescToken ) / NG_SIZE;
+ }
+ }
+ MemFreePointer((VOID**) &DescToken );
+
+ ClearScreen( EFI_BACKGROUND_BLACK | EFI_LIGHTGRAY );
+
+ //
+ //Draw password window
+ //
+ _DrawPasswordWindow( PromptToken, BoxLength, &CurrXPos, &CurrYPos );
+ }
+
+ //
+ //Give remaining chances to enter Master password
+ //
+ for (; i < MAXIMUM_HDD_UNLOCK_ATTEMPTS; i++ ) {
+ Status = IDEPasswordSecurity->ReturnSecurityStatus(IDEPasswordSecurity, &SecurityStatus );
+ if(Status == EFI_SUCCESS && (SecurityStatus>>4)& 0x1){
+ _DrawPasswordWindow( PromptToken, CB_BoxLength, &CurrXPos, &CurrYPos );
+ _ReportInBox(CB_BoxLength,STRING_TOKEN(STR_IDE_UNLCK_COLD),CurrXPos,CurrYPos,TRUE);
+ HddSecuritySignalProtocolEvent(&gHddPasswordPromptExitGuid);
+ if (gST->ConOut != NULL) {
+ //Disable cursor, set desired attributes and clear screen
+ gST->ConOut->EnableCursor( gST->ConOut, FALSE );
+ gST->ConOut->SetAttribute( gST->ConOut, (EFI_BACKGROUND_BLACK | EFI_WHITE));
+ gST->ConOut->ClearScreen( gST->ConOut);
+ }
+ return ;
+ }
+ _ReportInBox( BoxLength, STRING_TOKEN(
+ STR_IDE_ENTER_MASTER ), CurrXPos, CurrYPos - 1,
+ FALSE );
+
+ if ( EFI_SUCCESS !=
+ _GetPassword( PasswordEntered, IDE_PASSWORD_LENGTH, CurrXPos,
+ CurrYPos, NULL )) {
+ break;
+ }
+
+ //
+ // Vaidate the Master password
+ //
+ Status = IDEPasswordAuthenticate( PasswordEntered, DataPtr, FALSE );
+
+ if ( EFI_SUCCESS == Status ) {
+ break;
+ } else {
+ if ( (i + 1) != MAXIMUM_HDD_UNLOCK_ATTEMPTS ) {
+ _ReportInBox( IDE_PASSWORD_LENGTH,
+ STRING_TOKEN(
+ STR_ERROR_PSWD ), CurrXPos, CurrYPos,
+ TRUE );
+ }
+ }
+ }// end of for
+ }// end if
+ }// end if
+ #endif
+
+ MemSet( PasswordEntered, (IDE_PASSWORD_LENGTH + 1) * sizeof(CHAR16), 0);
+
+ MemFreePointer((VOID**)&PasswordEntered );
+
+ if ( EFI_SUCCESS != Status ) {
+ //Report Invalid password
+ _ReportInBox( IDE_PASSWORD_LENGTH, STRING_TOKEN(
+ STR_IDE_ERROR_PSWD ), CurrXPos, CurrYPos, TRUE );
+ // Unlock failed.
+ EfiLibReportStatusCode( EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ DXE_INVALID_IDE_PASSWORD,
+ 0,
+ NULL,
+ NULL );
+ }
+
+ HddSecuritySignalProtocolEvent(&gHddPasswordPromptExitGuid);
+ if (gST->ConOut != NULL) {
+ //Disable cursor, set desired attributes and clear screen
+ gST->ConOut->EnableCursor( gST->ConOut, FALSE );
+ gST->ConOut->SetAttribute( gST->ConOut, (EFI_BACKGROUND_BLACK | EFI_WHITE));
+ gST->ConOut->ClearScreen( gST->ConOut);
+ }
+
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordvices
+//
+// Description: Send Frezze command all the HDD
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IDEPasswordFreezeDevices( )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer;
+ UINT16 i;
+ UINTN Count;
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity = NULL;
+
+ // Return if Hdd FreezeLock command is already sent
+ if( HddFreeze ) {
+ return;
+ }
+
+ if(IDEPasswordSecurityData != NULL) {
+ //
+ // Clear the Password
+ //
+ MemSet( IDEPasswordSecurityData, sizeof(IDE_SECURITY_DATA) * gIDESecurityCount, 0);
+ //
+ // Free up the Memory
+ //
+ MemFreePointer((VOID**)&IDEPasswordSecurityData );
+ IDEPasswordSecurityData=NULL;
+ }
+
+ Status = gBS->LocateHandleBuffer(
+ ByProtocol,
+ &gIDESecurityProtocolGuid,
+ NULL,
+ &Count,
+ &HandleBuffer
+ );
+
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ for ( i = 0; i < Count; i++ ) {
+ //
+ // get password security protocol
+ //
+ Status = gBS->OpenProtocol(
+ HandleBuffer[i],
+ &gIDESecurityProtocolGuid,
+ (VOID**) &IDEPasswordSecurity,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if ( EFI_ERROR( Status )) {
+ continue;
+ }
+
+ //
+ //Send Freeze lock command
+ //
+ Status=IDEPasswordSecurity->SecurityFreezeLock( IDEPasswordSecurity );
+
+ if(Status == EFI_SUCCESS) {
+ HddFreeze = TRUE;
+ }
+
+ }// end of for
+ MemFreePointer((VOID**)&HandleBuffer );
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordUpdateHdd
+//
+// Description: Updates the HDD password for the current HDD alone.
+//
+// Input:
+// UINT32 Index,
+// CHAR16 *Password,
+// BOOLEAN bCheckUser
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IDEPasswordUpdateHdd(UINT32 Index,CHAR16 *Password,BOOLEAN bCheckUser)
+{
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity = NULL;
+ UINT16 Control = bCheckUser ? 0 : 1;
+ UINT8 RevisionCode = 0;
+ BOOLEAN Locked, Enabled;
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ UINT8 Buffer[IDE_PASSWORD_LENGTH + 1];
+ UINT8 Selection;
+ #if !SETUP_SAME_SYS_HDD_PW
+ UINTN ii;
+ #endif
+ IDE_SECURITY_DATA *DataPtr;
+
+//
+// While password is set via hook in tse to perfom some OEM feature
+// and SETUP_PASSWORD_NON_CASE_SENSITIVE is set, even then the
+// password will be updated as if it is case sensitive but Authenticates
+// as non case sensitive so in order to avoid such situation making
+// IDEPasswordUpdateHdd() symmetric with IDEPasswordAuthenticateHdd()
+// to update case sensivity {EIP99649}
+//
+#if TSE_BUILD > 0x1206
+{
+ UINTN NewPwLen = 0;
+ if( IsPasswordSupportNonCaseSensitive() ) {
+ NewPwLen = EfiStrLen(Password);
+ UpdatePasswordToNonCaseSensitive(Password, NewPwLen);
+ }
+}
+#endif
+
+ DataPtr = (IDE_SECURITY_DATA*)IDEPasswordGetDataPtr( Index );
+
+ if ( DataPtr == NULL ) {
+ ShowPostMsgBox(
+ NULL,
+ HiiGetString(
+ gHiiHandle,
+ STRING_TOKEN(STR_IDE_SECURITY_UNSUPPORTED)
+ ),
+ MSGBOX_TYPE_OK,
+ &Selection
+ ); // ShowPostMsgBox
+
+ return FALSE;
+ }
+ IDEPasswordSecurity = DataPtr->IDEPasswordSecurity;
+
+ //
+ //get the status of the device
+ //
+ if ( !(
+ CheckSecurityStatus(
+ IDEPasswordSecurity, &Locked,
+ SecurityLockedMask )
+ && CheckSecurityStatus( IDEPasswordSecurity, &Enabled,
+ SecurityEnabledMask ))) {
+ return FALSE;
+ }
+
+ if ( !Locked ) {
+ if ( Password[0] == 0 ) {
+ //
+ //empty string is entered -> disable password
+ //
+ Status = IDEPasswordSecurity->SecurityDisablePassword(
+ IDEPasswordSecurity,
+ Control,
+ IDEPasswordSecurityData[Index].PWD );
+ } else {
+ //
+ //set new password
+ //
+ MemSet( &Buffer, IDE_PASSWORD_LENGTH + 1, 0 );
+ #if !SETUP_SAME_SYS_HDD_PW
+
+ for ( ii = 0; ii < IDE_PASSWORD_LENGTH + 1; ii++ ) {
+ Buffer[ii] = (UINT8)Password[ii];
+
+ if ( Password[ii] == L'\0' ) {
+ break;
+ }
+ }// end of for
+ #else
+ MemCopy( Buffer, Password, IDE_PASSWORD_LENGTH + 1 );
+ #endif
+
+ Status = IDEPasswordSecurity->SecuritySetPassword(
+ IDEPasswordSecurity,
+ Control,
+ Buffer,
+ RevisionCode );
+ }
+ }// end if(!Locked)
+
+ if ( EFI_ERROR( Status )) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordUpdateAllHdd
+//
+// Description: Updates the HDD password for all the HDDs present.
+//
+// Input:
+// UINT32 Index,
+// CHAR16 *Password,
+// BOOLEAN bCheckUser
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IDEPasswordUpdateAllHdd(
+ UINT32 Index,
+ CHAR16 *Password,
+ BOOLEAN bCheckUser )
+{
+ UINTN i;
+ BOOLEAN Status = FALSE;
+ for ( i = 0; i < gIDESecurityCount; i++ ) {
+ Status = IDEPasswordUpdateHdd( (UINT32)i, Password, bCheckUser);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordUpdate
+//
+// Description: Hook function to update the password for the HDDs based
+// on the token ALL_HDD_SAME_PW.
+// Input:
+// UINT32 Index,
+// CHAR16 *Password,
+// BOOLEAN bCheckUser
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IDEPasswordUpdate(
+ UINT32 Index,
+ CHAR16 *Password,
+ BOOLEAN bCheckUser )
+{
+ #if ALL_HDD_SAME_PW
+ return IDEPasswordUpdateAllHdd( Index, Password, bCheckUser);
+ #else
+ return IDEPasswordUpdateHdd( Index, Password, bCheckUser);
+ #endif
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UnlockHDD
+//
+// Description: Unlock the HDD
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UnlockHDD(
+ VOID )
+{
+ #if SETUP_SAME_SYS_HDD_PW
+ UINTN Size=0, i;
+ AMITSESETUP *TSESetup;
+ IDE_SECURITY_DATA *DataPtr;
+ EFI_STATUS Status;
+ EFI_GUID AmiTseSetupGuid = AMITSESETUP_GUID;
+
+ //
+ //Do not proceed if admin pssword is not set
+ //
+ if ( !(AMI_PASSWORD_USER & PasswordCheckInstalled()) ) {
+ return;
+ }
+
+ //
+ //Get password from NVRAM
+ //
+ Size = 0;
+ TSESetup = VarGetNvramName (L"AMITSESetup", &AmiTseSetupGuid, NULL, &Size);
+
+ if ( Size ) {
+ //
+ //For all drives
+ //
+ DataPtr = IDEPasswordSecurityData;
+
+ for ( i = 0; i < gIDESecurityCount; i++ ) {
+ if ( DataPtr->Locked ) {
+ //
+ //ask fot the password if locked
+ //
+ Status = IDEPasswordAuthenticateHdd( TSESetup->UserPassword,
+ DataPtr,
+ TRUE );
+
+ if ( EFI_SUCCESS != Status ) {
+ //
+ // Unlock failed.
+ //
+ EfiLibReportStatusCode( EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ DXE_INVALID_IDE_PASSWORD,
+ 0,
+ NULL,
+ NULL );
+ }
+ }
+ DataPtr++;
+ } // end of for
+ } // end if
+
+ MemFreePointer((VOID**) &TSESetup );
+ return;
+ #endif //#if SETUP_SAME_SYS_HDD_PW
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetHDDPassword
+//
+// Description: Set the HDD password
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetHDDPassword(VOID)
+{
+ #if SETUP_SAME_SYS_HDD_PW
+ UINTN Size=0, i;
+ AMITSESETUP *TSESetup;
+ BOOLEAN Status;
+ EFI_GUID AmiTseSetupGuid = AMITSESETUP_GUID;
+
+ //
+ //Get password from NVRAM
+ //
+ Size = 0;
+ TSESetup = VarGetNvramName (L"AMITSESetup", &AmiTseSetupGuid, NULL, &Size);
+
+ if ( Size ) {
+ //
+ //For all drives
+ //
+ for ( i = 0; i < gIDESecurityCount; i++ ) {
+ Status = IDEPasswordUpdateHdd( (UINT32)i, TSESetup->UserPassword, TRUE);
+ }
+ }
+
+ MemFreePointer((VOID**) &TSESetup );
+ #endif //#if SETUP_SAME_SYS_HDD_PW
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordCheck
+//
+// Description: Validate the HDD password
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IDEPasswordCheck()
+{
+ #if !SETUP_SAME_SYS_HDD_PW
+ IDE_SECURITY_DATA *DataPtr;
+#if !ALL_HDD_SAME_PW
+ UINT16 i;
+#endif
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+ UINTN IDE_idex = 0;
+#endif
+ BOOLEAN ScreenCorrupted = FALSE;
+ #endif
+ IDE_SECURITY_CONFIG ideSecConfig;
+
+ //
+ // build IDESecurity data
+ //
+
+ gIDESecurityCount = IDESecurityProtocolInit( );
+
+ if ( IDEPasswordSecurityData == NULL || gIDESecurityCount == 0 ) {
+ return;
+ }
+
+ #if SETUP_SAME_SYS_HDD_PW
+ UnlockHDD();
+ #else
+ DataPtr = IDEPasswordSecurityData;
+#if !ALL_HDD_SAME_PW
+ for ( i = 0; i < gIDESecurityCount; i++ ) {
+#endif
+ if ( DataPtr->Locked && (!DataPtr->Validated)) {
+ //
+ //ask fot the password if locked
+ //
+ DataPtr->Validated = TRUE;
+ AMI_CheckIDEPassword( DataPtr->PromptToken, (VOID*)DataPtr );
+ ScreenCorrupted = TRUE;
+ }
+#if !ALL_HDD_SAME_PW
+ DataPtr++;
+ }// end of for
+#endif
+ //
+ // If the Screen Corrupted , Redraw the Screen
+ //
+ // if(ScreenCorrupted) {
+ // DrawScreenAgain(OldScreen);
+ // }
+ #endif
+
+ MemSet( &ideSecConfig, sizeof(ideSecConfig), 0 );
+ ideSecConfig.Count = gIDESecurityCount;
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+ for( IDE_idex = 0 ; IDE_idex < gIDESecurityCount ; IDE_idex++ )
+ {
+ IDEUpdateConfig( &ideSecConfig, IDE_idex );
+ }
+#endif
+ VarSetNvramName( L"IDESecDev",
+ &gIDESecGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ &ideSecConfig,
+ sizeof(ideSecConfig));
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEUpdateConfigHdd
+//
+// Description: Initializes the structure IDE_SECURITY_CONFIG for the current
+// HDD if the data pointer to the structure IDE_SECURITY_DATA is
+// initialized already.
+//
+// Input:
+// IDE_SECURITY_CONFIG *ideSecConfig
+// UINTN value
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IDEUpdateConfigHdd(
+ VOID *TempideSecConfig,
+ UINTN value )
+{
+ IDE_SECURITY_DATA *DataPtr = NULL;
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity = NULL;
+ BOOLEAN Status;
+ UINT32 IdePasswordFlags = 0;
+ EFI_STATUS ReturnStatus;
+ IDE_SECURITY_CONFIG *ideSecConfig
+ = (IDE_SECURITY_CONFIG*)TempideSecConfig;
+
+
+ //
+ //Set current IDE security page
+ //
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+
+ DataPtr = (IDE_SECURITY_DATA*)IDEPasswordGetDataPtr( value );
+
+ if ( DataPtr ) {
+ IDEPasswordSecurity = DataPtr->IDEPasswordSecurity;
+
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecuritySupportedMask );
+ ideSecConfig->Supported[value] = Status ? 1 : 0;
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecurityEnabledMask );
+ ideSecConfig->Enabled[value] = Status ? 1 : 0;
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecurityLockedMask );
+ ideSecConfig->Locked[value] = Status ? 1 : 0;
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecurityFrozenMask );
+ ideSecConfig->Frozen[value] = Status ? 1 : 0;
+ ReturnStatus = IDEPasswordSecurity->ReturnIdePasswordFlags(
+ IDEPasswordSecurity,
+ &IdePasswordFlags );
+
+ if ( EFI_ERROR( ReturnStatus )) {
+ return;
+ }
+
+ ideSecConfig->UserPasswordStatus[value]
+ = (IdePasswordFlags & 0x00020000) ? 1 : 0;
+ ideSecConfig->MasterPasswordStatus[value]
+ = (IdePasswordFlags & 0x00010000) ? 1 : 0;
+
+ ideSecConfig->ShowMaster[value] = 0x0000;
+
+ if ( ideSecConfig->Locked[value] ) {
+ ideSecConfig->ShowMaster[value] = 0x0001;
+ } else if ( (DataPtr->LoggedInAsMaster)) {
+ ideSecConfig->ShowMaster[value] = 0x0001;
+ } else if ( !(ideSecConfig->UserPasswordStatus[value])) {
+ ideSecConfig->ShowMaster[value] = 0x0001;
+ }
+ }// end if
+#else
+ gCurrIDESecPage = value;
+
+ DataPtr = (IDE_SECURITY_DATA*)IDEPasswordGetDataPtr( value );
+
+ if ( DataPtr ) {
+ IDEPasswordSecurity = DataPtr->IDEPasswordSecurity;
+
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecuritySupportedMask );
+ ideSecConfig->Supported = Status ? 1 : 0;
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecurityEnabledMask );
+ ideSecConfig->Enabled = Status ? 1 : 0;
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecurityLockedMask );
+ ideSecConfig->Locked = Status ? 1 : 0;
+ CheckSecurityStatus(
+ IDEPasswordSecurity,
+ &Status,
+ SecurityFrozenMask );
+ ideSecConfig->Frozen = Status ? 1 : 0;
+ ReturnStatus = IDEPasswordSecurity->ReturnIdePasswordFlags(
+ IDEPasswordSecurity,
+ &IdePasswordFlags );
+
+ if ( EFI_ERROR( ReturnStatus )) {
+ return;
+ }
+
+ ideSecConfig->UserPasswordStatus
+ = (IdePasswordFlags & 0x00020000) ? 1 : 0;
+ ideSecConfig->MasterPasswordStatus
+ = (IdePasswordFlags & 0x00010000) ? 1 : 0;
+
+ ideSecConfig->ShowMaster = 0x0000;
+
+ if ( ideSecConfig->Locked ) {
+ ideSecConfig->ShowMaster = 0x0001;
+ } else if ( (DataPtr->LoggedInAsMaster)) {
+ ideSecConfig->ShowMaster = 0x0001;
+ } else if ( !(ideSecConfig->UserPasswordStatus)) {
+ ideSecConfig->ShowMaster = 0x0001;
+ }
+ }// end if
+#endif
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEUpdateConfigAllHdd
+//
+// Description: Initializes the structure IDE_SECURITY_CONFIG for all the
+// HDDs present if the data pointer to the structure
+// IDE_SECURITY_DATA is initialized already.
+//
+// Input:
+// IDE_SECURITY_CONFIG *ideSecConfig
+// UINTN value
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IDEUpdateConfigAllHdd(
+ VOID *TempideSecConfig,
+ UINTN value )
+{
+ UINTN i;
+
+ for ( i = 0; i < gIDESecurityCount; i++ ) {
+ IDEUpdateConfigHdd( TempideSecConfig, i);
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEUpdateConfig
+//
+// Description: Hook function to Initialize the structure IDE_SECURITY_CONFIG
+// for the HDDs based on the token ALL_HDD_SAME_PW.
+//
+// Input:
+// IDE_SECURITY_CONFIG *ideSecConfig
+// UINTN value
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IDEUpdateConfig(
+ VOID *TempideSecConfig,
+ UINTN value )
+{
+ #if ALL_HDD_SAME_PW
+ IDEUpdateConfigAllHdd( TempideSecConfig, value);
+ #else
+ IDEUpdateConfigHdd( TempideSecConfig, value);
+ #endif
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordGetName
+//
+// Description: Get the Hdd name
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 IDEPasswordGetName(
+ UINT16 Index )
+{
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+ // workaround for code in special.c which fills "goto string" token with
+ // hdd name string token. In our case we dont need that.
+ return ConfigPromptToken;
+#else
+ UINTN size=0;
+ IDE_SECURITY_CONFIG *ideSecConfig;
+ IDE_SECURITY_DATA *DataPtr;
+
+ ideSecConfig = VarGetNvramName (L"IDESecDev", &gIDESecGuid, NULL, &size);
+ IDEUpdateConfigHdd (ideSecConfig, Index);
+ VarSetNvramName (L"IDESecDev",
+ &gIDESecGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ ideSecConfig,
+ size);
+
+ MemFreePointer((VOID **)&ideSecConfig);
+
+ DataPtr = (IDE_SECURITY_DATA*)IDEPasswordGetDataPtr( Index );
+
+ if(DataPtr == NULL) {
+ return 0;
+ }
+
+ return DataPtr->PromptToken;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordAuthenticateHdd
+//
+// Description: Validates the Ide password for the current HDD alone.
+//
+// Input:
+// CHAR16 *Password,
+// VOID* Ptr,
+// BOOLEAN bCheckUser
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IDEPasswordAuthenticateHdd(
+ CHAR16 *Password,
+ VOID * Ptr,
+ BOOLEAN bCheckUser )
+{
+ UINT16 Control = 0;
+ EFI_STATUS Status;
+ UINT8 Buffer[IDE_PASSWORD_LENGTH + 1];
+
+ #if !SETUP_SAME_SYS_HDD_PW
+ UINTN i;
+ #endif
+
+ IDE_SECURITY_DATA * DataPtr = (IDE_SECURITY_DATA*)Ptr;
+
+ MemSet( &Buffer, IDE_PASSWORD_LENGTH + 1, 0 );
+
+#if TSE_BUILD > 0x1206
+{
+ UINTN NewPwLen = 0;
+ if( IsPasswordSupportNonCaseSensitive() ) {
+ NewPwLen = EfiStrLen(Password);
+ UpdatePasswordToNonCaseSensitive(Password, NewPwLen);
+ }
+}
+#endif
+
+ #if !SETUP_SAME_SYS_HDD_PW
+
+ for ( i = 0; i < IDE_PASSWORD_LENGTH + 1; i++ ) {
+ Buffer[i] = (UINT8)Password[i];
+
+ if ( Password[i] == L'\0' ) {
+ break;
+ }
+ }
+ #else
+ MemCopy( Buffer, Password, IDE_PASSWORD_LENGTH + 1 );
+ #endif
+
+ Control = bCheckUser ? 0 : 1;
+
+ Status = (DataPtr->IDEPasswordSecurity)->SecurityUnlockPassword(
+ DataPtr->IDEPasswordSecurity,
+ Control,
+ Buffer );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ //save password in case we need to disable it during the setup
+ //
+ MemCopy( &(DataPtr->PWD), &Buffer, IDE_PASSWORD_LENGTH + 1 );
+// DataPtr->Locked = FALSE;
+
+ if ( !bCheckUser ) {
+ DataPtr->LoggedInAsMaster = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordAuthenticateAllHdd
+//
+// Description: Validates the Ide password for all the HDDs Present.
+//
+// Input:
+// CHAR16 *Password,
+// VOID* Ptr,
+// BOOLEAN bCheckUser
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IDEPasswordAuthenticateAllHdd(
+ CHAR16 *Password,
+ VOID * Ptr,
+ BOOLEAN bCheckUser )
+{
+ IDE_SECURITY_DATA *DataPtr;
+ UINTN i;
+ EFI_STATUS Status=EFI_NOT_FOUND;
+
+ //
+ //For all drives
+ //
+ DataPtr = IDEPasswordSecurityData;
+
+ if(DataPtr == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ for ( i = 0; i < gIDESecurityCount; i++ ) {
+
+ Status = IDEPasswordAuthenticateHdd( Password,
+ DataPtr,
+ bCheckUser );
+ if ( EFI_SUCCESS != Status ) {
+ //
+ // Unlock failed.
+ //
+ EfiLibReportStatusCode( EFI_ERROR_CODE | EFI_ERROR_MAJOR,
+ DXE_INVALID_IDE_PASSWORD,
+ 0,
+ NULL,
+ NULL );
+ }
+ DataPtr++;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordAuthenticate
+//
+// Description: Hook function to validate IDE Password for the HDDs based on
+// the token ALL_HDD_SAME_PW
+// Input:
+// CHAR16 *Password,
+// VOID* Ptr,
+// BOOLEAN bCheckUser
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IDEPasswordAuthenticate(
+ CHAR16 *Password,
+ VOID * Ptr,
+ BOOLEAN bCheckUser )
+{
+ #if ALL_HDD_SAME_PW
+ return IDEPasswordAuthenticateAllHdd( Password, Ptr, bCheckUser);
+ #else
+ return IDEPasswordAuthenticateHdd( Password, Ptr, bCheckUser);
+ #endif
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IDEPasswordGetDataPtr
+//
+// Description: Get the Ide password Data pointer
+//
+// Input: none
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* IDEPasswordGetDataPtr( UINTN Index )
+{
+ IDE_SECURITY_DATA *DataPtr;
+
+ if ( gIDESecurityCount == 0 || IDEPasswordSecurityData == NULL ) {
+ //
+ //try to initialize, if not initialized
+ //
+ gIDESecurityCount = IDESecurityProtocolInit( );
+ }
+
+ if ( gIDESecurityCount == 0 || IDEPasswordSecurityData == NULL || Index >=
+ gIDESecurityCount ) {
+ return NULL;
+ }
+
+ DataPtr = (IDE_SECURITY_DATA*)IDEPasswordSecurityData;
+
+ if(DataPtr == NULL) {
+ return 0;
+ }
+
+ return (VOID*)&DataPtr[Index];
+}
+
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FramePwdCallbackIdePasswordUpdate
+//
+// Description: function to update the ide password
+//
+// Input: CONTROL_DATA *control : Selected password control data,
+// VOID *saveData : New password
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FramePwdCallbackIdePasswordUpdate ( CONTROL_DATA *control, CHAR16 *saveData)
+{
+ BOOLEAN bCheckUser = FALSE;
+ VOID * data =control->ControlData.ControlPtr;
+ UINT8 HardDiskNumber = 0xFF;
+
+ // Check whether selected password control is a HDD Password control
+ if (control->ControlData.ControlVariable == VARIABLE_ID_IDE_SECURITY )
+ {
+ // find index of currently selected HDD and type of password(user/master) to update
+ SearchTseHardDiskField( &bCheckUser, NULL, &HardDiskNumber, data );
+
+ if( HardDiskNumber != 0xFF ) // If HDD index is valid
+ {
+ IDEPasswordUpdate( (UINT32)HardDiskNumber, (CHAR16*) saveData, bCheckUser ); //update it
+ }
+ return EFI_SUCCESS;
+ }
+ else
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PopupPwdAuthenticateIDEPwd
+//
+// Description: Function to authenticate the IDE password
+//
+// Input: POPUP_PASSWORD_DATA *popuppassword,
+// BOOLEAN *AbortUpdate,
+// VOID *data
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PopupPwdAuthenticateIDEPwd(POPUP_PASSWORD_DATA *popuppassword, BOOLEAN *AbortUpdate,VOID *data)
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ CHAR16 *Text=NULL;
+ UINT8 HardDiskNumber = 0xFF;
+
+ // Check whether selected password control is a HDD Password control
+ if(popuppassword->ControlData.ControlVariable == VARIABLE_ID_IDE_SECURITY )
+ {
+ BOOLEAN bCheckUser = FALSE;
+ BOOLEAN EnabledBit = FALSE;
+ UINTN size = 0;
+ IDE_SECURITY_CONFIG *ideSecConfig;
+
+ ideSecConfig = VarGetVariable( VARIABLE_ID_IDE_SECURITY, &size ); // Get the data from setup page
+ if (NULL == ideSecConfig) {
+ return EFI_NOT_FOUND;
+ }
+ // find index of currently selected HDD and type of password(user/master) to authenticate
+ SearchTseHardDiskField( &bCheckUser, &EnabledBit, &HardDiskNumber, data );
+ // Check if password has been set for selected HDD
+ if( ( HardDiskNumber != 0xFF ) && ideSecConfig->Enabled[HardDiskNumber] )
+ {
+ EnabledBit = TRUE;
+ }
+
+ // If password has been set then proceed
+ if(EnabledBit)
+ {
+ if( bCheckUser || ideSecConfig->MasterPasswordStatus[HardDiskNumber] )
+ {
+ // Ask for the password
+ Status = _DoPopupEdit( popuppassword, STRING_TOKEN(STR_OLD_PSWD), &Text);
+ if(EFI_SUCCESS != Status )
+ {
+ *AbortUpdate = TRUE; // Status: Password not updated
+ }
+ else
+ {
+ // Get IDE_SECURITY_PROTOCOL instance for current HDD
+ void* DataPtr = TSEIDEPasswordGetDataPtr( HardDiskNumber );
+ Status = TSEIDEPasswordAuthenticate( Text, DataPtr, bCheckUser ); //Authenticate it
+ if(EFI_ERROR( Status ))
+ {
+ // Show error message if password is wrong
+ CallbackShowMessageBox( (UINTN)gInvalidPasswordFailMsgBox, MSGBOX_TYPE_OK );
+ *AbortUpdate = TRUE; // Status: Password not updated
+ }
+ StringZeroFreeMemory ((VOID **)&Text); // Erase string and free allocated memory
+ }
+ }
+ }
+
+ MemFreePointer((VOID **) &ideSecConfig); // Free setup data memory
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PopupPwdUpdateIDEPwd
+//
+// Description: function to update the setup config page after IDE password update
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PopupPwdUpdateIDEPwd (VOID)
+{
+ UINTN size = 0;
+ IDE_SECURITY_CONFIG *ideSecConfig;
+ UINT8 HardDiskNumber = 0xFF;
+
+ // Get the old setup config data
+ ideSecConfig = VarGetVariable( VARIABLE_ID_IDE_SECURITY, &size );
+ if (NULL == ideSecConfig) {
+ return;
+ }
+ // Update setup data for all HDDs
+ for( HardDiskNumber = 0 ; HardDiskNumber < ideSecConfig->Count ; HardDiskNumber++ )
+ {
+ IDEUpdateConfig( (VOID*)ideSecConfig, HardDiskNumber );
+ }
+ // Set the new setup config data
+ VarSetValue (VARIABLE_ID_IDE_SECURITY, 0, size, ideSecConfig);
+ if (gApp != NULL)
+ gApp->CompleteRedraw = TRUE; // redraw setup config page to reflect updated configuration
+ MemFreePointer((VOID **)&ideSecConfig);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SearchTseHardDiskField
+//
+// Description: function to search TSE hard disk field.
+//
+// Input: IN OUT BOOLEAN *pbCheckUser : Password type - User/Master,
+// IN OUT BOOLEAN *pEnabledBit : Password is set / not,
+// IN OUT UINT8 *pHardDiskNumber : HDD index,
+// IN VOID *data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SearchTseHardDiskField (
+ IN OUT BOOLEAN *pbCheckUser, IN OUT BOOLEAN *pEnabledBit,
+ IN OUT UINT8 *pHardDiskNumber, IN VOID *data
+ )
+{
+ UINTN size = 0;
+ IDE_SECURITY_CONFIG *ideSecConfig;
+
+ ideSecConfig = VarGetVariable( VARIABLE_ID_IDE_SECURITY, &size );
+
+ //
+ // Check if User password field is selected, if yes then set HDD index
+ //
+ if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEUserPassword) )
+ {
+ *pHardDiskNumber = 0;
+ *pbCheckUser = TRUE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEUserPassword_HDD2) )
+ {
+ *pHardDiskNumber = 1;
+ *pbCheckUser = TRUE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEUserPassword_HDD3) )
+ {
+ *pHardDiskNumber = 2;
+ *pbCheckUser = TRUE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEUserPassword_HDD4) )
+ {
+ *pHardDiskNumber = 3;
+ *pbCheckUser = TRUE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEUserPassword_HDD5) )
+ {
+ *pHardDiskNumber = 4;
+ *pbCheckUser = TRUE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEUserPassword_HDD6) )
+ {
+ *pHardDiskNumber = 5;
+ *pbCheckUser = TRUE;
+ }
+ //
+ // Check if Master password field is selected, if yes then set HDD index
+ //
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEMasterPassword) )
+ {
+ *pHardDiskNumber = 0;
+ *pbCheckUser = FALSE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEMasterPassword_HDD2) )
+ {
+ *pHardDiskNumber = 1;
+ *pbCheckUser = FALSE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEMasterPassword_HDD3) )
+ {
+ *pHardDiskNumber = 2;
+ *pbCheckUser = FALSE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEMasterPassword_HDD4) )
+ {
+ *pHardDiskNumber = 3;
+ *pbCheckUser = FALSE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEMasterPassword_HDD5) )
+ {
+ *pHardDiskNumber = 4;
+ *pbCheckUser = FALSE;
+ }
+ else if( UefiGetQuestionOffset(data) /*data->QuestionId*/
+ == STRUCT_OFFSET(IDE_SECURITY_CONFIG,IDEMasterPassword_HDD6) )
+ {
+ *pHardDiskNumber = 5;
+ *pbCheckUser = FALSE;
+ }
+ else // Question offset is not from any of the password fields
+ {
+ *pHardDiskNumber = 0xFF; // No HDD selected
+ if( pEnabledBit != NULL )
+ {
+ *pEnabledBit = FALSE; // No HDD ie no password is set
+ }
+ }
+ // if HDD index is invalid, set it to 0xFF
+ if( *pHardDiskNumber >= ideSecConfig->Count )
+ {
+ *pHardDiskNumber = 0xFF;
+ }
+
+ MemFreePointer( (VOID **) &ideSecConfig );
+ return;
+}
+
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HDDStatus
+//
+// Description: Returns EFI_SUCCESS and sets *bHddStatus = TRUE if number of
+// attempt to unlock HDD has reached MAXIMUM_HDD_UNLOCK_ATTEMPTS.
+//
+// Input: VOID *DataPtr
+//
+// Output: BOOLEAN *bHddStatus
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS HDDStatus(VOID *DataPtr, BOOLEAN *bHddStatus)
+{
+ EFI_STATUS Status = 0;
+ UINT16 SecurityStatus = 0;
+ IDE_SECURITY_DATA *Ptr = (IDE_SECURITY_DATA *)DataPtr;
+
+ *bHddStatus = FALSE;
+
+ Status = Ptr->IDEPasswordSecurity->ReturnSecurityStatus( Ptr->IDEPasswordSecurity, &SecurityStatus );
+ if ( EFI_ERROR( Status ))
+ return Status;
+
+ if (SecurityStatus & 0x10) {
+ *bHddStatus = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/HddSecurity/Hddpassword/HddPassword.cif b/Core/EM/HddSecurity/Hddpassword/HddPassword.cif
new file mode 100644
index 0000000..5529e64
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddPassword.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "AmiTseHddPassword"
+ category = ModulePart
+ LocalRoot = "Core\EM\HddSecurity\Hddpassword"
+ RefName = "AmiTseHddPassword"
+[files]
+"HddPassword.mak"
+"HddPassword.sdl"
+"HddPassword.c"
+"HddPassword.h"
+"HddPassword.uni"
+"HddSecTokens.c"
+"ForceHddPassword.c"
+<endComponent>
diff --git a/Core/EM/HddSecurity/Hddpassword/HddPassword.h b/Core/EM/HddSecurity/Hddpassword/HddPassword.h
new file mode 100644
index 0000000..ccfdffb
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddPassword.h
@@ -0,0 +1,185 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddPassword.h 11 9/10/14 2:59a Divyac $
+//
+// $Revision: 11 $
+//
+// $Date: 9/10/14 2:59a $
+//
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddPassword.h $
+//
+// 11 9/10/14 2:59a Divyac
+// [TAG] EIP181548
+// [Category] Improvement
+// [Description] Implement event signaling during HDD Passwords Prompt.
+// [Files] HddPassword.c
+// HddPassword.h
+//
+// 10 4/29/13 2:30a Kapilporwal
+// fixing build errors, when tse soruce is not present, from last check-in
+//
+// 9 4/25/13 9:28a Kapilporwal
+// [TAG] EIP108583
+// [Category] New Feature
+// [Description] support set HDD password in same page
+// [Files] IdeSecurity.cif, IdeSecurity.mak, IdeSecurity.sdl,
+// IdeSecurity.uni, IdeSecurityCommon.sd, IdeSecuritySetup.c,
+// HddPassword.c, HddPassword.h, HddPassword.mak, HddPassword.sdl
+//
+// 8 6/28/11 6:24a Anandv
+// [TAG] EIP62381
+// [Category] Improvement
+// [Description] In IdeSecurity Module, display HDD number in Setup
+// based
+// on results from WhichIde() function of
+// DiskInfo Protocol.
+//
+// [Files] HddPassword.c, HddPassword.h, SBDxe.c, PIDEController.h
+//
+// 7 5/21/10 2:58p Aaronp
+// Fix for EIP 38473 - Device names are not displayed when built in UEFI
+// 2.1 mode
+//
+// 6 3/11/10 3:50a Rameshr
+// Issue: Same Structure definied in Hddpassword and Amitse.
+// Solution: Amitse created tsecommon.h with all the common definition.
+// EIP: 27339
+//
+// 5 1/15/10 10:11a Yul
+// Coding Standard
+//
+// 4 9/28/09 4:59p Rameshr
+//
+// 3 9/21/09 3:48p Rameshr
+// The data structure AMI_IFR_MSGBOX in HddPassword.h and MessageBox.h are
+// not the same
+// EIP 27157
+//
+// 2 7/27/09 5:37p Pats
+// EIP 22925: Request to set HDD password length by token.
+// Solution: Token added to IdeSecurity.sdl, and definition removed from
+// HddPassword.h
+//
+// 1 5/01/09 11:09a Rameshr
+// Initial Check-in
+//*****************************************************************************//
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: HddPassword.h
+//
+// Description: Header file for the HddPassword
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _IDEPASSWORD_H_
+#define _IDEPASSWORD_H_
+
+#include "AmiStatusCodes.h"
+
+#define IDE_SECURITY_INTERFACE_GUID \
+ { 0xF4F63529, 0x281E, 0x4040, 0xA3, 0x13, 0xC1, 0xD6, 0x76, 0x63, 0x84,\
+ 0xBE }
+
+#define HDD_SECURITY_END_PROTOCOL_GUID \
+ { 0xad77ae29, 0x4c20, 0x4fdd, 0x85, 0x04, 0x81, 0x76, 0x61, 0x9b, 0x67,\
+ 0x6a }
+
+#define HDD_UNLOCKED_GUID \
+ { 0x1fd29be6, 0x70d0, 0x42a4, 0xa6, 0xe7, 0xe5, 0xd1, 0xe, 0x6a, 0xc3, 0x76};
+
+#define HDD_PASSWORD_PROMPT_ENTER_GUID \
+ { 0x8e8d584a, 0x6e32, 0x44bf, { 0xb9, 0x6e, 0x1d, 0x27, 0x7, 0xc4, 0xeb, 0x5c } }
+
+#define HDD_PASSWORD_PROMPT_EXIT_GUID \
+ { 0xe22af903, 0xfd6f, 0x4d22, { 0x94, 0xce, 0xf8, 0x49, 0xc6, 0x14, 0xc3, 0x45 } }
+
+#define SECURITY_SET_PASSWORD 0xF1
+#define SECURITY_UNLOCK 0xF2
+#define SECURITY_ERASE_PREPARE 0xF3
+#define SECURITY_ERASE_UNIT 0xF4
+#define SECURITY_FREEZE_LOCK 0xF5
+#define SECURITY_DISABLE_PASSWORD 0xF6
+#define SECURITY_BUFFER_LENGTH 512 // Bytes
+
+#define SecuritySupportedMask 0x0001
+#define SecurityEnabledMask 0x0002
+#define SecurityLockedMask 0x0004
+#define SecurityFrozenMask 0x0008
+
+
+#ifndef AMI_DXE_BS_EC_INVALID_IDE_PASSWORD
+ #define AMI_DXE_BS_EC_INVALID_IDE_PASSWORD (AMI_STATUS_CODE_CLASS\
+ | 0x00000005)
+#endif
+
+#ifndef DXE_INVALID_IDE_PASSWORD
+ #define DXE_INVALID_IDE_PASSWORD (EFI_SOFTWARE_DXE_BS_DRIVER\
+ | AMI_DXE_BS_EC_INVALID_IDE_PASSWORD)
+#endif
+
+#define NG_SIZE 19
+#define VARIABLE_ID_AMITSESETUP 5
+#if !defined(SECUITY_SETUP_ON_SAME_PAGE) || SECUITY_SETUP_ON_SAME_PAGE == 0
+#define INVALID_HANDLE ((VOID*)-1)
+#endif
+#include "tsecommon.h"
+
+#define EFI_DP_TYPE_MASK 0x7F
+#define EFI_DP_TYPE_UNPACKED 0x80
+#if !defined(SECUITY_SETUP_ON_SAME_PAGE) || SECUITY_SETUP_ON_SAME_PAGE == 0
+#define END_DEVICE_PATH_TYPE 0x7f
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+
+#define DevicePathType( a ) (((a)->Type) & EFI_DP_TYPE_MASK)
+#define DevicePathSubType( a ) ((a)->SubType)
+#define DevicePathNodeLength( a ) (((a)->Length[0]) | ((a)->Length[1] << 8))
+#define NextDevicePathNode( a ) ((EFI_DEVICE_PATH_PROTOCOL*) (((UINT8*) (\
+ a))\
+ +\
+ DevicePathNodeLength( a )))
+#define IsDevicePathEndType( a ) (\
+ DevicePathType( \
+ a ) == END_DEVICE_PATH_TYPE)
+#define IsDevicePathEndSubType( a ) ((a)->SubType ==\
+ END_ENTIRE_DEVICE_PATH_SUBTYPE)
+#define IsDevicePathEnd( a ) (IsDevicePathEndType( a )\
+ && IsDevicePathEndSubType( a ))
+VOID
+HddSecuritySignalProtocolEvent (
+ IN EFI_GUID *ProtocolGuid
+);
+
+#endif
+
+#endif /* _PASSWORD_H_ */
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/HddSecurity/Hddpassword/HddPassword.mak b/Core/EM/HddSecurity/Hddpassword/HddPassword.mak
new file mode 100644
index 0000000..445a4a8
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddPassword.mak
@@ -0,0 +1,96 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddPassword.mak 5 4/25/13 9:29a Kapilporwal $
+#
+# $Revision: 5 $
+#
+# $Date: 4/25/13 9:29a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddPassword.mak $
+#
+# 5 4/25/13 9:29a Kapilporwal
+# [TAG] EIP108583
+# [Category] New Feature
+# [Description] support set HDD password in same page
+# [Files] IdeSecurity.cif, IdeSecurity.mak, IdeSecurity.sdl,
+# IdeSecurity.uni, IdeSecurityCommon.sd, IdeSecuritySetup.c,
+# HddPassword.c, HddPassword.h, HddPassword.mak, HddPassword.sdl
+#
+# 4 8/19/10 2:46a Rameshr
+# Issue:Need do HDD PSW reset when warmboot
+# EIP 40528
+#
+# 3 6/30/10 4:15a Rameshr
+# Modified the Hddpassword build procedure, so that customer can add
+# their password oem files and build without modifying the Mak file
+#
+# 2 3/11/10 3:50a Rameshr
+# Issue: Same Structure definied in Hddpassword and Amitse.
+# Solution: Amitse created tsecommon.h with all the common definition.
+# EIP: 27339
+#
+# 1 5/01/09 11:09a Rameshr
+# Initial Check-in
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: HddPassword.mak
+#
+# Description: Make file for the Hddpassword.obj
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+EDK_TSE_INCLUDES = \
+ -I EDK\MiniSetup\TseLite \
+ -I EDK\MiniSetup\Ezport \
+ -I EDK\MiniSetup\BootOnly \
+ -I EDK\MiniSetup\BootOnly\AMILogo \
+ -I EDK\MiniSetup\uefi2.1 \
+ /DTSE_FOR_APTIO_4_50
+
+AMITSEBin : $(BUILD_DIR)\HddPassword.obj $(BUILD_DIR)\ForceHddPassword.obj
+
+{$(AMITSE_HDD_PASSWORD_DIR)}.c{$(BUILD_DIR)}.obj ::
+ $(CC) $(CFLAGS) $(EDK_TSE_INCLUDES) -I $(TSEBIN_DIR)\Inc -I $(TSEBIN_DIR) /Fo$(BUILD_DIR)\ $<
+
+$(BUILD_DIR)\HddPassword.mak : $(AMITSE_HDD_PASSWORD_DIR)\$(@B).cif $(AMITSE_HDD_PASSWORD_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AMITSE_HDD_PASSWORD_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+AMITSESDB : HddPassWordSDB
+
+HddPassWordSDB : $(BUILD_DIR)\HddPassword.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\HddPassword.mak all\
+ "UNI_INCLUDE_PATH=$(TSEBIN_DIR) $(TSE_UNI_INCLUDE_PATH)"\
+ "STRING_CONSUMERS=$(AMITSE_HDD_PASSWORD_DIR)\HddSecTokens.c"\
+ TYPE=SDB NAME=HddPassword
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/HddSecurity/Hddpassword/HddPassword.sdl b/Core/EM/HddSecurity/Hddpassword/HddPassword.sdl
new file mode 100644
index 0000000..a020c63
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddPassword.sdl
@@ -0,0 +1,136 @@
+TOKEN
+ Name = "SETUP_IDE_SECURITY_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Hdd password Screen in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SETUP_ASK_MASTER_PASSWORD"
+ Value = "0"
+ Help = "Enable / Disable IDE Master password support"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SETUP_SAME_SYS_HDD_PW"
+ Value = "0"
+ Help = "Enable to have User password as IDE password"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "USER_PASSWORD_RETRY_ATTEMPTS"
+ Value = "3"
+ Help = "Maximum number of attempts allowed to the HDD User Password. This token value should be less than or equal to MAXIMUM_HDD_UNLOCK_ATTEMPTS token. If all the attempts by user password failed then (MAXIMUM_HDD_UNLOCK_ATTEMPTS - USER_PASSWORD_RETRY_ATTEMPTS) attempts will be given to Master password"
+ TokenType = Integer
+ TargetH = Yes
+ TargetMAK = Yes
+ Range = "1 - MAXIMUM_HDD_UNLOCK_ATTEMPTS"
+End
+
+TOKEN
+ Name = "MAXIMUM_HDD_UNLOCK_ATTEMPTS"
+ Value = "5"
+ Help = "Maximum number of attempts in POST in which the user has to enter the HDD User Password/Master Password to unlock the HDD.This token value should not exceed 5 times because the ATA SECURITY UNLOCK command fails even if the correct User/Master password is entered on the sixth time because the ATA Security Expire Count is 5"
+ TokenType = Integer
+ TargetH = Yes
+ TargetMAK = Yes
+ Range = "1 - 5"
+End
+
+TOKEN
+ Name = "ALL_HDD_SAME_PW"
+ Value = "0"
+ Help = "1-Enable to have one password for all HDD drives,0-Different HDD could have different password"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+PATH
+ Name = "AMITSE_HDD_PASSWORD_DIR"
+End
+
+MODULE
+ Help = "Includes HddPassword.mak to Project"
+ File = "HddPassword.mak"
+End
+
+ELINK
+ Name = "RegisterHddNotification,"
+ Parent = "ProcessConInAvailability,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\HddPassword.obj"
+ Parent = "AMITSE_Objects"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(AMITSE_HDD_PASSWORD_DIR)\HddSecTokens.c"
+ Parent = "TSE_STRING_CONSUMERS_LIST"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-i $(AMITSE_HDD_PASSWORD_DIR)"
+ Parent = "TSE_UNI_INCLUDE_PATH"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\HddPassword.sdb"
+ Parent = "TSE_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DisableSoftwarePreservation,"
+ Parent = "PreSystemResetHookHook,"
+ InvokeOrder = AfterParent
+ Token = "FORCE_HDD_PASSWORD_PROMPT" "=" "1"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\ForceHddPassword.obj"
+ Parent = "AMITSE_Objects"
+ InvokeOrder = AfterParent
+ Token = "FORCE_HDD_PASSWORD_PROMPT" "=" "1"
+End
+
+TOKEN
+ Name = "OVERRIDE_FramePwdCallbackIdePasswordUpdate"
+ Value = "1"
+ Help = "set to 1 if oem wants to override the FramePwdCallbackIdePasswordUpdate function from Board module."
+ TokenType = Boolean
+ Token = "SECUITY_SETUP_ON_SAME_PAGE" "=" "1"
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPwdAuthenticateIDEPwd"
+ Value = "1"
+ Help = "set to 1 if oem wants to override the PopupPwdAuthenticateIDEPwd function from Board module."
+ TokenType = Boolean
+ Token = "SECUITY_SETUP_ON_SAME_PAGE" "=" "1"
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_PopupPwdUpdateIDEPwd"
+ Value = "1"
+ Help = "set to 1 if oem wants to override the PopupPwdUpdateIDEPwd function from Board module."
+ TokenType = Boolean
+ Token = "SECUITY_SETUP_ON_SAME_PAGE" "=" "1"
+ TargetH = Yes
+End
diff --git a/Core/EM/HddSecurity/Hddpassword/HddPassword.uni b/Core/EM/HddSecurity/Hddpassword/HddPassword.uni
new file mode 100644
index 0000000..8fdd12d
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddPassword.uni
Binary files differ
diff --git a/Core/EM/HddSecurity/Hddpassword/HddSecTokens.c b/Core/EM/HddSecurity/Hddpassword/HddSecTokens.c
new file mode 100644
index 0000000..082fae5
--- /dev/null
+++ b/Core/EM/HddSecurity/Hddpassword/HddSecTokens.c
@@ -0,0 +1,79 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddSecTokens.c 2 3/25/13 5:16a Rameshr $
+//
+// $Revision: 2 $
+//
+// $Date: 3/25/13 5:16a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/HddPassword/HddSecTokens.c $
+//
+// 2 3/25/13 5:16a Rameshr
+// [TAG] EIP117159
+// [Category] Improvement
+// [Description] Proper error message displayed when the Password count
+// expired
+// [Files] HddPassword.c, HddPassword.uni, HddSecTokens.c
+//
+// 1 3/11/10 3:51a Rameshr
+// Issue: Same Structure definied in Hddpassword and Amitse.
+// Solution: Amitse created tsecommon.h with all the common definition.
+// EIP: 27339
+//
+// Initial check-in
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HddSecTokens.c
+//
+// Description:
+// This file does not add any code. It has, all the string tokens that
+// are used by Minisetup, to fake the usage to strgather.exe. Add to
+// this list, the new string tokens that are defined in
+// AmiTSEStrstr.uni and to be used by Minisetup
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+//Following code is to force strgatherer to include these strings
+#if 0
+
+STRING_TOKEN(STR_IDE_SECURITY_UNSUPPORTED)
+STRING_TOKEN(STR_IDE_SECURITY_LOCKED)
+STRING_TOKEN(STR_IDE_ERROR_PSWD)
+STRING_TOKEN(STR_IDE_SECURITY_PROMPT)
+STRING_TOKEN(STR_IDE_ENTER_USER)
+STRING_TOKEN(STR_IDE_ENTER_MASTER)
+STRING_TOKEN(STR_IDE_UNLCK_COLD)
+
+#endif
+
+//*****************************************************************//
+//*****************************************************************//
+//** **//
+//** (C)Copyright 2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Norcross, Georgia 30093 **//
+//** **//
+//** Phone (770)-246-8600 **//
+//** **//
+//*****************************************************************//
+//*****************************************************************//
diff --git a/Core/EM/HddSecurity/IDESMM.DXS b/Core/EM/HddSecurity/IDESMM.DXS
new file mode 100644
index 0000000..26ab424
--- /dev/null
+++ b/Core/EM/HddSecurity/IDESMM.DXS
@@ -0,0 +1,84 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.DXS 4 1/08/13 12:40a Rameshr $
+//
+// $Revision: 4 $
+//
+// $Date: 1/08/13 12:40a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.DXS $
+//
+// 4 1/08/13 12:40a Rameshr
+// [TAG] EIP109495
+// [Category] Improvement
+// [Description] HddSecurity driver needs to be updated for PI
+// specification 1.2
+// [Files] IdeSmm.c, IdeSmm.dxs, IdeSmm.h, IdeSmm.cif
+//
+// 3 6/01/10 7:11p Krishnakumarg
+// Removed Tab spaces
+//
+// 2 4/28/09 6:56p Rameshr
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+// 2 13/04/07 3:07p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 1 12/14/05 2:57p Srinin
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IDESMM.DXS
+//
+// Description: Dependency file for the IDE SMM
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IDESMM.h"
+
+DEPENDENCY_START
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+#else
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSecurity/IDESMM.c b/Core/EM/HddSecurity/IDESMM.c
new file mode 100644
index 0000000..f898455
--- /dev/null
+++ b/Core/EM/HddSecurity/IDESMM.c
@@ -0,0 +1,1553 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.c 24 4/29/15 3:41a Anbuprakashp $
+//
+// $Revision: 24 $
+//
+// $Date: 4/29/15 3:41a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.c $
+//
+// 24 4/29/15 3:41a Anbuprakashp
+// [TAG] EIP215937
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hang while SmmCommunication SMI trigger after enable
+// SmmChkEn bit
+// [RootCause] Bootservice call is used inside IDESMM driver
+// [Solution] Avoided using BootService call inide IDESMM driver
+// [Files] IDESMM.c
+//
+// 23 4/22/15 4:01a Anbuprakashp
+// [TAG] EIP212319
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang while SW_SMI_AHCI_LOCATE_AHCI_SMM SMI trigger
+// after enable SmmChkEn bit
+// [RootCause] Bootservice call used inside IdeSmm driver which causes
+// the Exception
+// [Solution] Changes made not to use BootService calls inside IdeSmm
+// driver
+// [Files] IdeSecurity.h
+// IdeSecurity.c
+// IDESMM.c
+//
+// 22 12/09/14 1:41a Anbuprakashp
+// [TAG] EIP193600
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in HddSecurity
+// module
+// [Files] IDESMM.mak, IDESMM.h, IDESMM.c
+//
+// 21 8/11/14 6:54a Anbuprakashp
+// [TAG] EIP178239
+// [Category] Improvement
+// [Description] S3 Resume fails when HDD password is set where platform
+// have more than one AHCI controller
+// [Files] AhciSmm.c,AhciSmm.sdl,IDESMM.c
+//
+// 20 12/18/13 4:07a Srikantakumarp
+// [TAG] EIP127356
+// [Category] Improvement
+// [Description] Flash NVRAM seems to cause HDD can't be unlocked when
+// S3 resume.
+// [Files] IdeSecurity.c, IDESMM.c, HddPassword.c, AhciBus.c, AhciBus.h
+//
+// 19 1/08/13 12:39a Rameshr
+// [TAG] EIP109495
+// [Category] Improvement
+// [Description] HddSecurity driver needs to be updated for PI
+// specification 1.2
+// [Files] IdeSmm.c, IdeSmm.dxs, IdeSmm.h, IdeSmm.cif
+//
+// 18 8/22/11 2:06a Anandakrishnanl
+// [TAG] EIP67738
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] IdeSmm.c File has been changed in the previous version to
+// remove AHCI Controller Init programming that issue controller reset in
+// S3. This causes various AMD platforms to not resume from S3 properly.
+// [RootCause] IdeSmm.c File has been changed in the previous version to
+// remove AHCI Controller Init programming that issue controller reset in
+// S3. This causes various AMD platforms to not resume from S3 properly.
+// [Solution] Reverted the Idesmm.c file to previous version that will
+// bring back the Ahci Controller initialization by issuing Controller
+// reset
+// [Files] IDESMM.C
+//
+// 17 12/22/10 11:52a Krishnakumarg
+// [TAG] - EIP 46081
+// [Category] - Action Item
+// [Description] - 64 bit PCI config space exception in AHCI driver.
+// [Files] - IDESmm.c
+//
+// 16 10/11/10 11:02a Krishnakumarg
+// [TAG]- EIP 43249
+// [Category]-IMPROVEMENT
+// [Description]- Non-Ascii character in comments causing build problem in
+// japanese XP
+// [Files]- IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 15 9/20/10 4:19a Rameshr
+// [TAG]- EIP 44182
+// [Category]-IMPROVEMENT
+// [Description]- Unable to build the project with HDDSecurity module and
+// without AHCI module.
+// [Files]- IdeSecurity.h, IdeSmm.c
+//
+// 14 9/13/10 1:40a Rameshr
+// [TAG]- EIP 43299
+// [Category]-IMPROVEMENT
+// [Description]- About IdeSecurity module. It use soft smi port 0xb2
+// directly.It will need to re-modify on all of AMD project.
+// 1) Added the SDL token for Sw SMI port address.
+// 2) Used Pciio protocol to get the device location and passed this
+// information to SMM driver.
+// [Files]- IdeSecurity.c, IdeSmm.c, PideBus.h
+//
+// 13 6/01/10 7:07p Krishnakumarg
+// Removed Tab spaces.
+//
+// 12 1/15/10 10:14a Yul
+// Coding Standard
+//
+// 11 11/02/09 6:04p Davidd
+// - Correct S3 resume hanging problem when IDE_PASSWORD_LENGTH is set to
+// some value other than 32 (EIP 27989).
+// - Correct S3 resume hanging problem in AHCI mode (EIP 29827).
+//
+// 10 6/05/09 2:47p Rameshr
+// x64 mode compilation error Resolved.
+// Eip:22710
+//
+// 9 5/11/09 9:39a Rameshr
+// Symptom: Unable to clear the HDD password.
+// Solution: SmmProtocols located on the remove HDD password SMI also.
+// EIP: 21668
+//
+// 8 4/28/09 6:56p Rameshr
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 7 3/31/09 6:52p Davidd
+// Added Device Configuration Freeze Lock programming.
+//
+// 6 3/05/09 11:34a Rameshr
+// RemovedHddpassword doesn't work for Ahci mode- EIP 19935.
+//
+// 5 4/11/08 4:26p Rameshraju
+// s3 Resume time improved when is security not enabled.
+//
+// 2 3/24/08 6:37p Fasihm
+// Updated some missed protocols inside the build switchs.
+//
+// 4 24/03/08 6:34p Anandakrishnanl
+// Removed unwanted comment.
+//
+// 3 24/03/08 6:31p Anandakrishnanl
+// Corrected the SMM Thunk Protocols to Extended Thunk Protocols.
+//
+// 1 3/11/08 2:40p Fasihm
+// Changed the structure names to match with the new SMM module labeled.
+// Will have to remove this after updating the IdeSecurity module with
+// this change.
+//
+// 2 10/03/08 6:47p Anandakrishnanl
+// Removed FreezeLock related code from SMI for improving the S3 resume
+// time.
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+// 1 2/20/08 8:13p Fasihm
+// Added the code to fix the SATA freeze problem.
+//
+// 8 22/06/07 12:44p Anandakrishnanl
+// HardDisk Security Support Module Added.
+// Need ACPI Module and SB Module and under Core\Include we updated
+// Setup.h.
+// Also New IdeBus bin module.
+//
+// 7 13/04/07 3:06p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 6 12/18/06 11:53a Srinin
+// Fixed issues with unlocking HDD password during S3 resume.
+//
+// 5 8/24/06 5:08p Felixp
+//
+// 4 8/24/06 5:07p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 3 8/24/06 9:31a Felixp
+// x64 support (asm code removed)
+//
+// 2 1/04/06 9:36a Srinin
+// Access to Boot services during Runtime removed.
+//
+// 1 12/14/05 2:57p Srinin
+//
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IdeSMM.C
+//
+// Description: Provide functions to unlock HDD password during S3 resume
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IDESMM.h"
+
+#if ( defined(AhciSrc_SUPPORT) && (AhciSrc_SUPPORT != 0) )
+EFI_GUID gAhciSmmProtocolGuid = AHCI_SMM_PROTOCOL_GUID;
+UINT8 *AhciSecurityBuffer = NULL;
+AHCI_BUS_SMM_PROTOCOL *mAhciSmm = NULL;
+#endif
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+#define RETURN(status) {return status;}
+#else
+#define RETURN(status) {return ;}
+#endif
+
+EFI_GUID gSecurityModeProtocolGuid = IDE_SECURITY_INTERFACE_GUID;
+DLIST gPasswordList;
+
+COMMAND_BUFFER *mCmdBuffer;
+UINT8 *mDataBuffer = NULL;
+UINT8 *mDataSmmBuffer = NULL;
+UINT8 *SecurityBuffer = NULL;
+BOOLEAN AhciInit = FALSE;
+
+SECURITY_PROTOCOL *IdeSecurityInterface = NULL;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ EFI_SMM_SYSTEM_TABLE2 *gSmst;
+#else
+ EFI_SMM_SYSTEM_TABLE *gSmst;
+#endif
+
+#define PCI_CFG_ADDR( bus, dev, func, reg ) \
+ ((VOID*)(UINTN) (PCIEX_BASE_ADDRESS\
+ + ((bus) << 20) + ((dev) << 15) + ((func) << 12) + reg))
+
+#define AHCI_BAR 0x24
+#define PCI_SCC 0x000A // Sub Class Code Register
+
+
+#if defined(EFI64) || defined(EFIx64)
+static UINT64 DivU64x32(
+ IN UINT64 Dividend,
+ IN UINTN Divisor,
+ OUT UINTN*Remainder OPTIONAL )
+{
+ UINT64 Result = Dividend / Divisor;
+
+ if ( Remainder )
+ {
+ *Remainder = Dividend % Divisor;
+ }
+ return Result;
+}
+
+#else
+
+static UINT64 DivU64x32(
+ IN UINT64 Dividend,
+ IN UINTN Divisor, //Can only be 31 bits.
+ OUT UINTN*Remainder OPTIONAL )
+{
+ UINT64 Result;
+ UINT32 Rem;
+
+ _asm
+ {
+ mov eax, dword ptr Dividend[0]
+ mov edx, dword ptr Dividend[4]
+ mov esi, Divisor
+ xor edi, edi ; Remainder
+ mov ecx, 64 ; 64 bits
+Div64_loop:
+ shl eax, 1 ;Shift dividend left. This clears bit 0.
+ rcl edx, 1
+ rcl edi, 1 ;Shift remainder left. Bit 0 = previous dividend bit 63.
+
+ cmp edi, esi ; If Rem >= Divisor, don't adjust
+ cmc ; else adjust dividend and subtract divisor.
+ sbb ebx, ebx ; if Rem >= Divisor, ebx = 0, else ebx = -1.
+ sub eax, ebx ; if adjust, bit 0 of dividend = 1
+ and ebx, esi ; if adjust, ebx = Divisor, else ebx = 0.
+ sub edi, ebx ; if adjust, subtract divisor from remainder.
+ loop Div64_loop
+
+ mov dword ptr Result[0], eax
+ mov dword ptr Result[4], edx
+ mov Rem, edi
+ }
+
+ if (Remainder) *Remainder = Rem;
+
+ return Result;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Stall
+//
+// Description: Stalls for the Required Amount of MicroSeconds
+//
+// Input:
+// UINTN Usec // Number of microseconds to delay
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+Stall (
+ UINTN Usec
+ )
+{
+ UINTN Counter, i;
+ UINT32 Data32, PrevData;
+ UINTN Remainder;
+
+ Counter = (UINTN)DivU64x32 ((Usec * 10), 3, &Remainder);
+
+ if (Remainder != 0) {
+ Counter++;
+ }
+
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ZeromemorySmm
+//
+// Description: Clears the buffer
+//
+// Input: void *Buffer,
+// UINTN Size
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void
+ZeroMemorySmm (
+ void *Buffer,
+ UINTN Size
+ )
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMMWaitforBitClear
+//
+// Description: Waits for the given bit to be clear
+//
+// Input: HDD_PASSWORD *pHddPassword,
+// UINT8 BitClear,
+// UINT32 Timeout
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SMMWaitforBitClear (
+ HDD_PASSWORD *pHddPassword,
+ UINT8 BitClear,
+ UINT32 Timeout
+ )
+{
+ UINT8 Delay;
+ UINT8 Data8;
+
+ for ( ; Timeout > 0; Timeout--) {
+ for ( Delay = 100; Delay > 0; Delay--) {
+ Data8 = IoRead8(pHddPassword->DeviceControlReg);
+ if (!(Data8 & BitClear)) return EFI_SUCCESS;
+ Stall(10); // 10 Usec
+ }
+ }
+ return EFI_TIMEOUT;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMMWaitforBitSet
+//
+// Description: Checks for a particular Bit to be set for a given amount
+// of time
+//
+// Input: HDD_PASSWORD *pHddPassword,
+// UINT8 BitSet,
+// UINT32 Timeout
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SMMWaitforBitSet (
+ HDD_PASSWORD *pHddPassword,
+ UINT8 BitSet,
+ UINT32 TimeOut
+ )
+{
+ UINT8 Delay;
+ UINT8 Data8;
+
+ for ( ; TimeOut > 0; TimeOut--) {
+ for ( Delay = 100; Delay > 0; Delay--) {
+ Data8 = IoRead8(pHddPassword->DeviceControlReg);
+ if (Data8 & BitSet) return EFI_SUCCESS;
+ Stall(10); // 10 Usec
+ }
+ }
+ return EFI_TIMEOUT;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMMWaitForCmdCompletion
+//
+// Description: Waits for BSY bit to get clear
+//
+// Input: HDD_PASSWORD *pHddPassword
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Wait for BSY bit to get clear. Check for any errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SMMWaitForCmdCompletion (
+ HDD_PASSWORD *pHddPassword
+ )
+{
+ UINT8 Data8;
+ EFI_STATUS Status;
+
+// Read ATL_STATUS and ignore the result. Just a delay
+ Data8 = IoRead8(pHddPassword->DeviceControlReg);
+
+// Check for BSY bit to be clear
+ Status = SMMWaitforBitClear ( pHddPassword,
+ BSY,
+ DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT);
+
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+// Check for errors.
+ Data8 = IoRead8(pHddPassword->BaseAddress + 7);
+
+ if (Data8 & (ERR | DF)) return EFI_DEVICE_ERROR;
+
+ return EFI_SUCCESS;
+}
+
+#if ( defined(AhciSrc_SUPPORT) && (AhciSrc_SUPPORT != 0) )
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMMAhciSecurityUnlockCommand
+//
+// Description: This Function unlocks HDD password during S3 resume in
+// Ahci Mode Using Int 13.
+//
+// Input: HDD_PASSWORD *pHddPassword
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SMMAhciSecurityUnlockCommand (
+ HDD_PASSWORD *pHddPassword
+ )
+{
+ UINT8 i;
+ UINT64 AhciBar = 0;
+ UINT8 SccReg;
+ BOOLEAN ControllerinAhciMode = FALSE;
+ UINT32 GlobalControl;
+ COMMAND_STRUCTURE CommandStructure;
+ UINT32 NoofPorts=0;
+
+ if(mAhciSmm == NULL || !AhciSecurityBuffer) {
+ return EFI_NOT_FOUND;
+ }
+
+ // 1. Check if Controller is in AHCI Mode.
+ // 2. Read ABAR Offset and Get HbaAddress.
+ // 3. Disable AHCI_ENABLE.
+ // 4. Issue Controller Reset.
+ // 5. Wait for HBA Reset to Complete.
+ // 6. Enable AHCI_ENABLE.
+
+ AhciBar = *(UINT32*)PCI_CFG_ADDR( pHddPassword->BusNo,
+ pHddPassword->DeviceNo,
+ pHddPassword->FunctionNo,
+ AHCI_BAR);
+ AhciBar &= 0xFFFFFFF0;
+
+ // Store AhciBase address of HDD Drive before calling AhciSmmInitPortOnS3Resume() function
+ // of the "AHCI_BUS_SMM_PROTOCOL"
+ mAhciSmm->AhciBaseAddress=AhciBar;
+
+ // Find Number of Ports from BIT0:BIT4 of the HBA_CAP register
+ NoofPorts = ((MMIO_READ32(AhciBar + HBA_CAP)) & HBA_CAP_NP_MASK) + 1;
+
+ // Check if AHCI MMIO address space resides in SMRAM region. If yes, don't proceed.
+ if( AmiValidateMmioBuffer( (VOID*)mAhciSmm->AhciBaseAddress, HBA_PORTS_START + (NoofPorts * HBA_PORTS_REG_WIDTH) ) ) {
+ return EFI_NOT_FOUND;
+ }
+
+ if(!AhciInit) {
+ SccReg = *(UINT8*)PCI_CFG_ADDR(pHddPassword->BusNo,
+ pHddPassword->DeviceNo,
+ pHddPassword->FunctionNo,
+ PCI_SCC); // Get Scc Register;
+
+ if((SccReg & 0x06) || (SccReg & 0x04)) {
+ ControllerinAhciMode = TRUE;
+ }
+
+ if(ControllerinAhciMode) {
+
+ GlobalControl = MMIO_READ32(AhciBar + 0x04);
+
+ GlobalControl &= 0x7FFFFFFF;
+ MMIO_WRITE32(AhciBar + 0x04, GlobalControl);
+
+ GlobalControl = 0x01;
+ MMIO_WRITE32(AhciBar + 0x04, GlobalControl);
+
+ Stall(5000); // 5 milli Sec Delay
+
+ GlobalControl = 0x80000000;
+ MMIO_WRITE32(AhciBar + 0x04, GlobalControl);
+
+ Stall(1000000); // 1 Sec Delay
+ }
+ AhciInit=TRUE;
+ }
+
+ // Clear the Buffer
+ ZeroMemorySmm (AhciSecurityBuffer, 512);
+ AhciSecurityBuffer[0] = pHddPassword->Control & 1;;
+ if(AhciSecurityBuffer[0]) {
+ //Copy 32 Bytes of Password
+ for (i = 0; i < IDE_PASSWORD_LENGTH; i++) {
+ ((UINT8 *)AhciSecurityBuffer)[i + 2] = pHddPassword->MasterPassword[i];
+ }
+ } else {
+ //Copy 32 Bytes of Password
+ for (i = 0; i < IDE_PASSWORD_LENGTH; i++) {
+ ((UINT8 *)AhciSecurityBuffer)[i + 2] = pHddPassword->UserPassword[i];
+ }
+ }
+ //
+ //Resuming from S3. So bring back the AHCI controller to working state
+ //
+ mAhciSmm->AhciSmmInitPortOnS3Resume(mAhciSmm,pHddPassword->PortNumber);
+
+ //
+ //Setup the Unlock command
+ //
+ ZeroMemorySmm(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.SectorCount = 1;
+ CommandStructure.LBALow = 0;
+ CommandStructure.LBAMid = 0;
+ CommandStructure.LBAHigh = 0;
+ CommandStructure.Device = 0x40;
+ CommandStructure.Command = SECURITY_UNLOCK;
+ CommandStructure.Buffer = AhciSecurityBuffer;
+ CommandStructure.ByteCount = 512;
+ //
+ //Issue the unlock command
+ //
+ mAhciSmm->AhciSmmExecutePioDataCommand( mAhciSmm,
+ &CommandStructure,
+ pHddPassword->PortNumber,
+ 0xFF,
+ ATA,
+ TRUE);
+
+#if DISABLE_SOFT_SET_PREV
+ ZeroMemorySmm (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = DISABLE_SATA2_SOFTPREV; // Disable Software Preservation
+ CommandStructure.SectorCount = 6;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+
+ mAhciSmm->AhciSmmExecuteNonDataCommand( mAhciSmm,
+ CommandStructure,
+ pHddPassword->PortNumber,
+ 0xFF,
+ ATA
+ );
+#endif
+
+ //
+ //Issue the Security Freeze lock command
+ //
+ ZeroMemorySmm(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SECURITY_FREEZE_LOCK;
+ mAhciSmm->AhciSmmExecuteNonDataCommand( mAhciSmm,
+ CommandStructure,
+ pHddPassword->PortNumber,
+ 0xFF,
+ ATA
+ );
+
+ //
+ //Issue the Device config Freeze lock command
+ //
+ ZeroMemorySmm (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = DEV_CONFIG_FREEZE_LOCK;
+ CommandStructure.Features = DEV_CONFIG_FREEZE_LOCK_FEATURES;
+ mAhciSmm->AhciSmmExecuteNonDataCommand( mAhciSmm,
+ CommandStructure,
+ pHddPassword->PortNumber,
+ 0xFF,
+ ATA
+ );
+
+ return EFI_SUCCESS;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMMSecurityUnlockCommand
+//
+// Description: This Function unlocks HDD password during S3 resume.
+//
+// Input: HDD_PASSWORD *pHddPassword
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SMMSecurityUnlockCommand (
+ HDD_PASSWORD *pHddPassword
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Data8;
+ UINT8 i;
+ UINT16 Reg;
+
+ // Disable Interrupt
+ IoWrite8(pHddPassword->DeviceControlReg, 2);
+
+ // Select the drive
+ IoWrite8(pHddPassword->BaseAddress + 6, pHddPassword->Device << 4);
+
+ // Wait for BSY to go low
+ Status = SMMWaitforBitClear (pHddPassword, BSY, S3_BUSY_CLEAR_TIMEOUT);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ // Clear the Buffer
+ ZeroMemorySmm (SecurityBuffer, 512);
+
+ SecurityBuffer[0] = pHddPassword->Control & 1;;
+
+ if(SecurityBuffer[0]) {
+
+ // Copy 32 Bytes of Password
+
+ for (i = 0; i < IDE_PASSWORD_LENGTH; i++) {
+ ((UINT8 *)SecurityBuffer)[i + 2] = pHddPassword->MasterPassword[i];
+ }
+ } else {
+
+ // Copy 32 Bytes of Password
+ for (i = 0; i < IDE_PASSWORD_LENGTH; i++) {
+ ((UINT8 *)SecurityBuffer)[i + 2] = pHddPassword->UserPassword[i];
+ }
+ }
+
+ Status = SMMIdeNonDataCommand (pHddPassword,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ SECURITY_UNLOCK);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ // Wait for Command completion
+ Status = SMMWaitForCmdCompletion (pHddPassword);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ // Check for DRQ
+ Status = SMMWaitforBitSet(pHddPassword, DRQ, DRQ_TIMEOUT);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ Reg = pHddPassword->BaseAddress;
+
+ // Status = IdeWriteMultipleWord (pHddPassword->BaseAddress, 256, &SecurityBuffer);
+ IoWrite(
+ CpuIoWidthFifoUint16,
+ Reg,
+ 256,
+ SecurityBuffer
+ );
+
+ // Check for errors
+ Status = SMMWaitForCmdCompletion (pHddPassword);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ // Check for errors.
+ Data8 = IoRead8 ( pHddPassword->BaseAddress + 7);
+ if(Data8 & 0x21) { // ERR OR DF bit set ?
+ return EFI_DEVICE_ERROR;
+ }
+
+//IA32_DEBUG
+#if DISABLE_SOFT_SET_PREV || FORCE_HDD_PASSWORD_PROMPT
+ Status = SMMIdeNonDataCommand (pHddPassword,
+ DISABLE_SATA2_SOFTPREV,
+ 6,
+ 0,
+ 0,
+ 0,
+ SET_FEATURE_COMMAND);
+
+ // Check for errors
+ Status = SMMWaitForCmdCompletion (pHddPassword);
+ if (EFI_ERROR(Status)) return Status;
+#endif
+
+ Status = SMMIdeNonDataCommand (pHddPassword,
+ DEV_CONFIG_FREEZE_LOCK_FEATURES,
+ 0,
+ 0,
+ 0,
+ 0,
+ DEV_CONFIG_FREEZE_LOCK);
+
+ // Check for errors
+ Status = SMMWaitForCmdCompletion (pHddPassword);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SMMIdeNonDataCommand
+//
+// Description: Issues Set Feature command (Non Data)
+//
+// Input: HDD_PASSWORD *pHddPassword
+// UINT8 Command
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SMMIdeNonDataCommand (
+ HDD_PASSWORD *pHddPassword,
+ IN UINT8 Features,
+ IN UINT8 SectorCount,
+ IN UINT8 LBALow,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAHigh,
+ IN UINT8 Command
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 Data8;
+
+// Select the drive
+ IoWrite8(pHddPassword->BaseAddress + 6, pHddPassword->Device << 4);
+
+// Check for Controller presence
+ Data8 = IoRead8(pHddPassword->DeviceControlReg);
+ if (Data8 == 0xFF) {
+ ASSERT(Data8 == 0xFF);
+ return EFI_DEVICE_ERROR;
+ }
+
+// Before Writing to Sector Count Reg, BSY and DRQ bit should be zero
+ Status = SMMWaitforBitClear(pHddPassword, BSY, S3_BUSY_CLEAR_TIMEOUT);
+ if (EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+// Check for DRDY
+ Status = SMMWaitforBitSet(pHddPassword, DRDY, DRDY_TIMEOUT);
+ if (EFI_ERROR(Status)) return EFI_TIMEOUT;
+
+// Issue command
+
+ IoWrite8 ( pHddPassword->BaseAddress + 1, Features);
+ IoWrite8 ( pHddPassword->BaseAddress + 2, SectorCount);
+ IoWrite8 ( pHddPassword->BaseAddress + 3, LBALow);
+ IoWrite8 ( pHddPassword->BaseAddress + 4, LBAMid);
+ IoWrite8 ( pHddPassword->BaseAddress + 5, LBAHigh);
+ IoWrite8 ( pHddPassword->BaseAddress + 7, Command);
+
+ return EFI_SUCCESS;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateSMMServices
+//
+// Description: This function Locates the AhciSmm protocl from the Smm
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LocateSMMServices(
+ IN EFI_GUID *VariableGuid,
+ IN VOID **VariablePointer
+)
+{
+ UINTN Index;
+
+ for (Index = 0; Index < gSmst->NumberOfTableEntries; ++Index) {
+ if (guidcmp(&gSmst->SmmConfigurationTable[Index].VendorGuid,VariableGuid) == 0) {
+ break;
+ }
+ }
+
+ if (Index != gSmst->NumberOfTableEntries) {
+ *VariablePointer = gSmst->SmmConfigurationTable[Index].VendorTable;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateIdeSmmProtocols
+//
+// Description: This function Locates the protocols and saves in global pointe
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LocateIdeSmmProtocols()
+{
+
+#if ( defined(AhciSrc_SUPPORT) && (AhciSrc_SUPPORT != 0) )
+ if(mAhciSmm == NULL && gSmst ) {
+ LocateSMMServices(&gAhciSmmProtocolGuid,(VOID **)&mAhciSmm);
+ }
+#endif
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveHDDPassword
+//
+// Description: This function saves the HDD password and other information
+// necessary to unlock HDD password during S3 Resume.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS SaveHDDPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID SaveHDDPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+)
+{
+
+ HDD_PASSWORD *pHddPassword=NULL, *StoredHDDList;
+ DLINK *dlink;
+ UINT8 i;
+ BOOLEAN UserOrMaster = FALSE;
+ BOOLEAN CheckFlag;
+ EFI_STATUS Status=EFI_SUCCESS;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ pHddPassword = (HDD_PASSWORD *)CommBuffer;
+#else
+ Status = pBS->LocateProtocol(&gSecurityModeProtocolGuid, NULL, &IdeSecurityInterface);
+ if(!EFI_ERROR(Status)) {
+ pHddPassword = IdeSecurityInterface->pHDDPasswordBuffer;
+ }
+#endif
+
+ if (!pHddPassword) {
+ RETURN(Status);
+ }
+
+ // Check if signature is present or not
+ if ((UINT32) pHddPassword->Signature != '$HDD') {
+ RETURN(Status);
+ }
+
+ // Check whether info about the HDD is already present
+ dlink = gPasswordList.pHead;
+ for ( ; dlink; dlink = dlink->pNext) {
+ StoredHDDList = OUTTER(dlink, LinkList, HDD_PASSWORD);
+ CheckFlag = FALSE;
+ if(StoredHDDList->ModeFlag) {
+ if (StoredHDDList->PortNumber == pHddPassword->PortNumber) {
+ CheckFlag = TRUE;
+ }
+ } else {
+ if ((StoredHDDList->BaseAddress == pHddPassword->BaseAddress) &&
+ (StoredHDDList->Device == pHddPassword->Device)) {
+ CheckFlag = TRUE;
+ }
+ }
+
+ if (CheckFlag) {
+ UserOrMaster = (BOOLEAN)((pHddPassword->Control) & 0x01);
+
+ if(UserOrMaster){
+ // Match has been found. Just copy the Password buffer
+ for (i = 0; i < sizeof (pHddPassword->MasterPassword); i++) {
+ StoredHDDList->MasterPassword[i] = pHddPassword->MasterPassword[i];
+ }
+ } else {
+ // Match has been found. Just copy the Password buffer
+ for (i = 0; i < sizeof (pHddPassword->UserPassword); i++) {
+ StoredHDDList->UserPassword[i] = pHddPassword->UserPassword[i];
+ }
+ }
+ RETURN(Status);
+ }
+ }
+
+ // Allocate memory needed while unlocking the Password. Done only once.
+ // Same buffer will be reused.
+ if (SecurityBuffer == NULL) {
+ pSmst->SmmAllocatePool(0, 512, &SecurityBuffer);
+ }
+
+ // Match has not been found. Allocate memory and copy the buffer.
+ if (pSmst->SmmAllocatePool(0, sizeof(HDD_PASSWORD), &StoredHDDList) != EFI_SUCCESS) {
+ RETURN(Status);
+ }
+ for (i = 0; i < sizeof (HDD_PASSWORD); i++) ((UINT8 *)StoredHDDList)[i] = ((UINT8 *)pHddPassword)[i];
+ DListAdd(&gPasswordList, &StoredHDDList->LinkList);
+
+ RETURN(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UnlockHDDPassword
+//
+// Description: This Function unlocks HDD password during S3 resume.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS UnlockHDDPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID UnlockHDDPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+)
+{
+ HDD_PASSWORD *StoredHDDList;
+ DLINK *dlink;
+ EFI_STATUS Status=EFI_SUCCESS;
+
+ dlink = gPasswordList.pHead;
+ for ( ; dlink; dlink = dlink->pNext) {
+ StoredHDDList = OUTTER(dlink, LinkList, HDD_PASSWORD);
+ if (StoredHDDList->Signature == '$HDD') {
+ if(!StoredHDDList->ModeFlag) {
+ SMMSecurityUnlockCommand (StoredHDDList);
+ } else {
+#if ( defined(AhciSrc_SUPPORT) && (AhciSrc_SUPPORT != 0) )
+ SMMAhciSecurityUnlockCommand (StoredHDDList);
+#endif
+ }
+ }
+ }
+ AhciInit=FALSE;
+
+ RETURN(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveHDDPassword
+//
+// Description: This Function removes HDD password from the internal database
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS RemoveHDDPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID RemoveHDDPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+)
+{
+ HDD_PASSWORD *pHddPassword, *StoredHDDList;
+ DLINK *dlink;
+ EFI_STATUS Status=EFI_SUCCESS;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ pHddPassword = (HDD_PASSWORD *)CommBuffer;
+#else
+ Status = pBS->LocateProtocol(&gSecurityModeProtocolGuid, NULL, &IdeSecurityInterface);
+ if(!EFI_ERROR(Status)) {
+ pHddPassword = IdeSecurityInterface->pHDDPasswordBuffer;
+ }
+#endif
+
+ if (!pHddPassword) {
+ RETURN(Status);
+ }
+
+// Check if signature is present or not
+ if ((UINT32) pHddPassword->Signature != '$HDD') {
+ RETURN(Status);
+ }
+
+// Check whether info about the HDD is already present
+ dlink = gPasswordList.pHead;
+ for ( ; dlink; dlink = dlink->pNext) {
+ StoredHDDList = OUTTER(dlink, LinkList, HDD_PASSWORD);
+ if(StoredHDDList->ModeFlag) {
+ if (StoredHDDList->PortNumber == pHddPassword->PortNumber) {
+ DListDelete(&gPasswordList, &StoredHDDList->LinkList);
+ }
+ } else {
+ if ((StoredHDDList->BaseAddress == pHddPassword->BaseAddress) &&
+ (StoredHDDList->Device == pHddPassword->Device)) {
+ DListDelete(&gPasswordList, &StoredHDDList->LinkList);
+ }
+ }
+
+ }
+ RETURN(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IdeSmmMiscSmiPassword
+//
+// Description: This Function Freeze locks HDD, Issues Disable/Enable Software
+// Settings preservation Feature for Security Supported HDDs.
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS IdeSmmMiscSmiPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID IdeSmmMiscSmiPassword (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+)
+{
+ EFI_STATUS Status;
+ HDD_PASSWORD *StoredHDDList;
+ DLINK *dlink;
+
+ dlink = gPasswordList.pHead;
+ for ( ; dlink; dlink = dlink->pNext) {
+ StoredHDDList = OUTTER(dlink, LinkList, HDD_PASSWORD);
+ if (StoredHDDList->Signature == '$HDD') {
+
+ Status = SMMIdeNonDataCommand (StoredHDDList,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ SECURITY_FREEZE_LOCK);
+
+ // Check for errors
+ Status = SMMWaitForCmdCompletion (StoredHDDList);
+ if (EFI_ERROR(Status)) {
+ RETURN(Status);
+ }
+
+#if DISABLE_SOFT_SET_PREV || FORCE_HDD_PASSWORD_PROMPT
+
+ Status = SMMIdeNonDataCommand (StoredHDDList,
+ DISABLE_SATA2_SOFTPREV,
+ 6,
+ 0,
+ 0,
+ 0,
+ SET_FEATURE_COMMAND);
+
+ // Check for errors
+ Status = SMMWaitForCmdCompletion (StoredHDDList);
+ if (EFI_ERROR(Status)) {
+ RETURN(Status);
+ }
+#endif
+ }
+ }
+
+ RETURN(Status);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateAhciSMM
+//
+// Description: This function Locates the AhciSMM driver and save pointer globally.
+//
+// Input: DispatchHandle Handle to the Dispatcher
+// DispatchContext SW SMM dispatcher context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS LocateAhciSMM (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID LocateAhciSMM (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ // Unlock command Buffer
+ AhciSecurityBuffer = (UINT8 *)(*(UINTN *)CommBuffer);
+#else
+ if(!AhciSecurityBuffer) {
+ Status = pBS->AllocatePool ( EfiReservedMemoryType,
+ 512,
+ (VOID**)&AhciSecurityBuffer );
+ }
+#endif
+
+ LocateIdeSmmProtocols();
+ RETURN(Status);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IdeSmmInSmmFunction
+//
+// Description: Called from InstallSmiHandler
+//
+// Input:
+//
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeSmmInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ EFI_SMM_SW_REGISTER_CONTEXT Unlock_HDD_Password = {SW_SMI_HDD_UNLOCK_PASSWORD};
+ EFI_SMM_SW_REGISTER_CONTEXT IdeSmm_MiscSmi_Password = {SW_SMI_HDD_MISC_SMM_FEATURES};
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ EFI_SMM_BASE2_PROTOCOL *pSmmBase2;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch = NULL;
+
+#else
+ EFI_SMM_BASE_PROTOCOL *pSmmBase;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch = NULL;
+#endif
+
+#if defined(PI_SPECIFICATION_VERSION)&&!(PI_SPECIFICATION_VERSION>=0x00010014)
+ EFI_SMM_SW_REGISTER_CONTEXT Save_HDD_Password = {SW_SMI_HDD_PASSWORD_SAVE};
+ EFI_SMM_SW_REGISTER_CONTEXT Remove_HDD_Password = {SW_SMI_HDD_PASSWORD_REMOVE};
+ EFI_SMM_SW_REGISTER_CONTEXT Locate_Ahci_SMM = {SW_SMI_AHCI_LOCATE_AHCI_SMM};
+#endif
+
+ InitAmiBufferValidationLib(ImageHandle, SystemTable);
+ Status = InitAmiSmmLib( ImageHandle, SystemTable );
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &pSmmBase2);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // We are in SMM, retrieve the pointer to SMM System Table
+ //
+ Status = pSmmBase2->GetSmstLocation( pSmmBase2, &gSmst);
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gSmst->SmmLocateProtocol( &gEfiSmmSwDispatch2ProtocolGuid, \
+ NULL, \
+ &pSwDispatch );
+
+#else
+
+ Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pSmmBase->GetSmstLocation(pSmmBase,&gSmst);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+#endif
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ DListInit(&gPasswordList);
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+
+ Status = gSmst->SmiHandlerRegister(
+ (VOID *)SaveHDDPassword,
+ &gSaveHddPasswordGuid,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSmst->SmiHandlerRegister(
+ (VOID *)RemoveHDDPassword,
+ &gRemoveHddPasswordGuid,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = gSmst->SmiHandlerRegister(
+ (VOID *)LocateAhciSMM,
+ &gLocateIdeAhciSmmProtocolGuid,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#else
+ Status = pSwDispatch->Register(
+ pSwDispatch,
+ SaveHDDPassword,
+ &Save_HDD_Password,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = pSwDispatch->Register(
+ pSwDispatch,
+ RemoveHDDPassword,
+ &Remove_HDD_Password,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status = pSwDispatch->Register(
+ pSwDispatch,
+ LocateAhciSMM ,
+ &Locate_Ahci_SMM ,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+#endif
+
+ Status = pSwDispatch->Register(
+ pSwDispatch,
+ UnlockHDDPassword,
+ &Unlock_HDD_Password,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+
+ Status = pSwDispatch->Register(
+ pSwDispatch,
+ IdeSmmMiscSmiPassword ,
+ &IdeSmm_MiscSmi_Password ,
+ &Handle
+ );
+
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IdeHDDPasswordSMMInit
+//
+// Description: Initializes HDD Password SMM Drivers.
+//
+// Input:
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Here is the control flow of this function:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+IdeHDDPasswordSMMInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ InitAmiLib(ImageHandle,SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, IdeSmmInSmmFunction, NULL);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/EM/HddSecurity/IDESMM.cif b/Core/EM/HddSecurity/IDESMM.cif
new file mode 100644
index 0000000..f64fdff
--- /dev/null
+++ b/Core/EM/HddSecurity/IDESMM.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "IDESMM"
+ category = ModulePart
+ LocalRoot = "Core\EM\HddSecurity\"
+ RefName = "IDESMM"
+[files]
+"IDESMM.sdl"
+"IDESMM.mak"
+"IDESMM.h"
+"IDESMM.c"
+"IDESMM.DXS"
+<endComponent>
diff --git a/Core/EM/HddSecurity/IDESMM.h b/Core/EM/HddSecurity/IDESMM.h
new file mode 100644
index 0000000..e3850a4
--- /dev/null
+++ b/Core/EM/HddSecurity/IDESMM.h
@@ -0,0 +1,198 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.h 7 12/09/14 1:41a Anbuprakashp $
+//
+// $Revision: 7 $
+//
+// $Date: 12/09/14 1:41a $
+//
+//*********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.h $
+//
+// 7 12/09/14 1:41a Anbuprakashp
+// [TAG] EIP193600
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in HddSecurity
+// module
+// [Files] IDESMM.mak, IDESMM.h, IDESMM.c
+//
+// 6 1/08/13 12:41a Rameshr
+// [TAG] EIP109495
+// [Category] Improvement
+// [Description] HddSecurity driver needs to be updated for PI
+// specification 1.2
+// [Files] IdeSmm.c, IdeSmm.dxs, IdeSmm.h, IdeSmm.cif
+//
+// 5 9/27/11 3:04a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 4 3/24/11 5:24a Rameshr
+// [TAG] - EIP 56827
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Buld error from IdeSmm.h
+// [RootCause]- Invalid characters in IdeSmm.h
+// [Solution] - Removed the Invalid Charater from IdeSmm.h
+// [Files] - IdeSmm.h
+//
+// 3 1/15/10 10:16a Yul
+// Coding Standard
+//
+// 2 4/28/09 6:57p Rameshr
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+// 2 22/06/07 12:44p Anandakrishnanl
+// HardDisk Security Support Module Added.
+// Need ACPI Module and SB Module and under Core\Include we updated
+// Setup.h.
+// Also New IdeBus bin module.
+//
+// 1 13/04/07 3:08p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+//*********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: <IDESMM.h>
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the IDESMM Component
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _IDESMM_H_
+#define _IDESMM_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+#include <Protocol\SmmCpu.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+#include "IdeSecurity.h"
+#include <AmiBufferValidationLib.h>
+
+#ifndef DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT
+#define DMA_ATAPI_COMMAND_COMPLETE_TIMEOUT 16000 // 16Sec
+#endif
+
+#ifndef S3_BUSY_CLEAR_TIMEOUT
+#define S3_BUSY_CLEAR_TIMEOUT 10000 // 10Sec
+#endif
+
+#ifndef HBA_CAP
+#define HBA_CAP 0x0000
+#endif
+
+#ifndef HBA_CAP_NP_MASK
+#define HBA_CAP_NP_MASK 0x1F
+#endif
+
+#ifndef HBA_PORTS_START
+#define HBA_PORTS_START 0x0100
+#endif
+
+#ifndef HBA_PORTS_REG_WIDTH
+#define HBA_PORTS_REG_WIDTH 0x0080
+#endif
+
+#define BUSY_CLEAR_TIMEOUT 1000 // 1Sec
+#define DRDY_TIMEOUT 1000 // 1Sec
+#define DRQ_TIMEOUT 10 // 10msec
+#pragma pack(1)
+
+typedef struct
+{
+ UINT8 bFeature;
+ UINT8 bSectorCount;
+ UINT8 bLbaLow;
+ UINT8 bLbaMid;
+ UINT8 bLbaHigh;
+ UINT8 bDevice;
+ UINT8 bCommand;
+} COMMAND_BUFFER;
+
+#pragma pack()
+
+EFI_STATUS SMMSecurityUnlockCommand (
+ HDD_PASSWORD *pHddPassword
+);
+
+EFI_STATUS SMMIdeNonDataCommand (
+ HDD_PASSWORD *pHddPassword,
+ IN UINT8 Features,
+ IN UINT8 SectorCount,
+ IN UINT8 LBALow,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAHigh,
+ IN UINT8 Command );
+
+void ZeroMemorySmm (
+ void *Buffer,
+ UINTN Size );
+
+EFI_STATUS
+IdeSmmInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif // _IDESMM_H_
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSecurity/IDESMM.mak b/Core/EM/HddSecurity/IDESMM.mak
new file mode 100644
index 0000000..723b4f4
--- /dev/null
+++ b/Core/EM/HddSecurity/IDESMM.mak
@@ -0,0 +1,95 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2005, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.mak 4 12/09/14 1:41a Anbuprakashp $
+#
+# $Revision: 4 $
+#
+# $Date: 12/09/14 1:41a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSmm/IDESMM.mak $
+#
+# 4 12/09/14 1:41a Anbuprakashp
+# [TAG] EIP193600
+# [Category] Improvement
+# [Description] Security Enhancement for SMIHandler in HddSecurity
+# module
+# [Files] IDESMM.mak, IDESMM.h, IDESMM.c
+#
+# 3 6/06/13 2:24a Rameshr
+# [TAG] EIP122239
+# [Category] Improvement
+# [Description] IdeSmm should be part of the SMM driver
+# [Files] IdeSmm.mak
+#
+# 2 6/01/10 12:28p Krishnakumarg
+# Removed Tab spaces
+#
+# 1 28/02/08 6:40p Anandakrishnanl
+# Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+# IdeBus driver to be compatable with the AHCI Bus driver.
+#
+# 2 13/04/07 3:08p Anandakrishnanl
+# Ide Bus Module - Update source files to comply with “AMI coding
+# standard"!!!
+#
+# 1 12/14/05 2:57p Srinin
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IDESMM.mak
+#
+# Description: Make file for the Idesmm component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : IdeSMM
+
+IdeSMM : $(BUILD_DIR)\IdeSMM.mak IdeSMMBin
+
+$(BUILD_DIR)\IdeSMM.mak : $(IDESMM_DIR)\$(@B).cif $(IDESMM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IDESMM_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IDE_SMM_INCLUDES = $(AMIDXELIB) \
+ $(BUILD_DIR)\AmiBufferValidationLib.lib
+
+IdeSMMBin : $(IDE_SMM_INCLUDES)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\IdeSMM.mak all\
+ GUID=316B1230-0500-4592-8C09-EABA0FB6B07F\
+ ENTRY_POINT=IdeHDDPasswordSMMInit\
+!IF $(PI_SPECIFICATION_VERSION)<0x00001000A
+ TYPE=BS_DRIVER\
+!ELSE
+ TYPE=SMM_DRIVER\
+!ENDIF
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2005, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HddSecurity/IDESMM.sdl b/Core/EM/HddSecurity/IDESMM.sdl
new file mode 100644
index 0000000..d6ddda5
--- /dev/null
+++ b/Core/EM/HddSecurity/IDESMM.sdl
@@ -0,0 +1,66 @@
+TOKEN
+ Name = "IDESMM_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IDESMM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "HDD_SECURITY_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SW_SMI_HDD_PASSWORD_SAVE"
+ Value = "0D0h"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_HDD_UNLOCK_PASSWORD"
+ Value = "0D1h"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_HDD_PASSWORD_REMOVE"
+ Value = "0D2h"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_HDD_MISC_SMM_FEATURES"
+ Value = "0D3h"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_AHCI_LOCATE_AHCI_SMM"
+ Value = "0D4h"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "IDESMM_DIR"
+End
+
+MODULE
+ Help = "Includes IDESMM.mak to Project"
+ File = "IDESMM.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IDESMM.ffs"
+ Parent = "FV_MAIN"
+ Token = "IDESMM_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/HddSecurity/IdeSecurity.c b/Core/EM/HddSecurity/IdeSecurity.c
new file mode 100644
index 0000000..cfa9d89
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.c
@@ -0,0 +1,2939 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.c 43 4/22/15 3:57a Anbuprakashp $
+//
+// $Revision: 43 $
+//
+// $Date: 4/22/15 3:57a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.c $
+//
+// 43 4/22/15 3:57a Anbuprakashp
+// [TAG] EIP212319
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang while SW_SMI_AHCI_LOCATE_AHCI_SMM SMI trigger
+// after enable SmmChkEn bit
+// [RootCause] Bootservice call used inside IdeSmm driver which causes
+// the Exception
+// [Solution] Changes made not to use BootService calls inside IdeSmm
+// driver
+// [Files] IdeSecurity.h
+// IdeSecurity.c
+// IDESMM.c
+//
+// 42 3/16/15 5:50a Rameshr
+// [TAG] EIP208331
+// [Category] Improvement
+// [Description] Avoid sending freeze Lock command to the device if the
+// HDD already in frozen state
+// [Files] IdeSecurity.c, HddPassword.c
+//
+// 41 6/09/14 9:30a Anbuprakashp
+// [TAG] EIP172445
+// [Category] Improvement
+// [Description] Runtime attribute set for the some of the variable used
+// by Aptio-4 HddSecurity driver and needs to be reviewed
+// [Files] IdeSecurity.c
+//
+// 40 4/07/14 2:39a Nimishsv
+// [TAG] EIP151848
+// [Category] Improvement
+// [Description] [HDD security]Clear HDD security data related variable
+// when secuirty disabled
+// [Files] IdeSecurity.c
+//
+// 39 3/25/14 6:21a Rameshr
+// [TAG] EIP160499
+// [Category] Improvement
+// [Description] Do not get HDD password variable if HDD is in lock
+// state
+// [Files] IdeSecurity.c
+//
+// 38 3/25/14 6:12a Rameshr
+// [TAG] EIP124591
+// [Category] Improvement
+// [Description] Before sending the freeze lock command for the HDD,
+// check the Hdd security status (locked or unlocked) and if the hdd is
+// unlocked state, send the freeze lock command to hdd
+// [Files] IdeSecurity.c
+//
+// 37 12/18/13 4:05a Srikantakumarp
+// [TAG] EIP127356
+// [Category] Improvement
+// [Description] Flash NVRAM seems to cause HDD can't be unlocked when
+// S3 resume.
+// [Files] IdeSecurity.c, IDESMM.c, HddPassword.c, AhciBus.c, AhciBus.h
+//
+// 36 1/17/12 12:50a Jittenkumarp
+// [TAG] EIP78432
+// [Category] Bug Fix
+// [Symptom] The password set for OEM_MASTER_PASSWORD_TAG token is not
+// authenticated when the token SETUP_PASSWORD_NON_CASE_SENSITIVE is set
+// to 1.
+// [RootCause] When SETUP_PASSWORD_NON_CASE_SENSITIVE token is 1, input
+// password is always converted to Uppercase but OEM_MASTER_PASSWORD_TAG
+// is in lower case.
+// [Solution] OEM_MASTER_PASSWORD_TAG is converted into Uppercase before
+// storing in memory.
+// [Files] IdSecurity.c
+//
+// 35 1/05/12 6:25a Anandakrishnanl
+// [TAG] EIP79637
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Enhanced Erase Mode not Working
+// [RootCause] IdeSecurity Module SecurityEraseUnit did not handle Bit1
+// of Control Word to identify if it is a normal erase or Enhanced erase
+// [Solution] [IdeSecurity Module]SIECURITY ERASE UNIT command needs
+// Enhanced mode support
+// Code changed from Control &= 0x1; // Bit0 is valid to Control &= 0x3;
+// // Bit0 and Bit 1 is valid
+// to make EnhancedErase functional.
+// [Files] IdeSecurity.c
+//
+// 34 12/19/11 1:06a Rameshr
+// [TAG] EIP77527
+// [Category] Improvement
+// [Description] IdeSecurity, IdeAcoustic and IdeSmart changes should be
+// done based on the Core Version checking.
+// [Files] IdeSecurity.c, IdeSmart.c , Acoustic.c
+//
+// 33 12/05/11 6:24p Rajkumarkc
+// [TAG] EIP77142
+// [Category] Improvement
+// [Description] Added the function 'IdeNonDataCommandExp' in the
+// 'IDE_BUS_PROTOCOL' and removed the existing function
+// 'IdeNonDataCommand' for supporting the upper 24bits of LBA.
+// [Files]
+// Ata.c, IdeBus.c, Idebus.h, PIDEBus.h, Acoustic.c, IdeSecurity.c,
+// IdeSMART.c
+//
+// 32 10/21/11 4:11a Rameshr
+// [TAG] EIP69247
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Several IdeSecurity.sdl tokens are not working properly
+// [RootCause] Several IdeSecurity.sdl tokens are not working properly
+// [Solution] Removed unwanted SDL token and verified all the SDL token
+// function.
+// [Files] IdeSecurity.c, IdeSecurity.sdl, IdeSecurity.sdl
+//
+// 31 10/21/11 2:22a Rameshr
+// [TAG] EIP70395
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] When an Empty Master Password string is entered for the
+// first time(when no password was installed before), the
+// IDEPasswordUpdateHdd returns a Boolean "TRUE"
+// [RootCause] SecurityDisablePassword function returns the status of
+// SetDefaultMasterPassword function which is EFI_SUCCESS instead of
+// returning the status of SecurityCommonRoutine which will fail.
+// [Solution] SecurityCommonRoutine function status returned as the
+// status for SecurityDisablePassword function.
+// [Files] IdeSecurity.c
+//
+// 30 10/11/11 1:54a Rameshr
+// [TAG] EIP69246
+// [Category] Improvement
+// [Description] Made the SECURITY_SUPPORT as the Master token and
+// removed the IdeSecurity_Support token.
+//
+// [Files] IdeSecurity.c, IdeSecurity.h, IdeSecurity.mak,
+// IdeSecurity.sdl
+//
+// 29 10/11/11 1:34a Rameshr
+// [TAG] EIP70918
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] On S3 resume system will throw blue screen error, when HDD
+// password is set
+// [RootCause] Ld assume that the data is UINT64. But the actual data is
+// UINT32.
+// [Solution] To display d should be enough as the DataId is UINT32
+// [Files] IdeSecurity.c
+//
+// 28 4/27/11 6:03a Anandakrishnanl
+// [TAG] EIP54315
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] SugarBay IdeSecurity increase S3 Resume time
+// [RootCause] Setting the MASTER_PASSWORD_ENABLE sdl token in Ide
+// security Module saves the password in Smm all the time in reboots. This
+// causes the system to ask for master password even when it is not locked
+// which causes Long Timeout in S3 resume.
+// [Solution] Fix by not saving the master pasword in SMM at the time
+// of Set password. Only Unlock password will save validated password in
+// SMM area.
+// [Files] IdeSecurity.c
+//
+// 27 4/06/11 12:52a Rameshr
+// [TAG]- EIP 57341
+// [Category]-IMPROVEMENT
+// [Description]- Added Support for SMM PI 1.1 in HDDSecurity eModule.
+// [Files]- IdeSecurity.c , IdeSecurity.h, IdeSecurity.dxs
+//
+// 26 12/03/10 12:23a Rameshr
+// [TAG] - EIP 48770
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - HddSecurity build error when disable the IDEBUS module..
+// [RootCause]- IdebusLib used with IdeSecurity Module.
+// [Solution] - Removed IdebusLib usage from source and mak file.
+// [Files] - Idesecurity.c, IdeSecurity.mak
+//
+// 25 10/20/10 2:49a Rameshr
+// [TAG]- EIP 43492
+// [Category]-IMPROVEMENT
+// [Description]- Added the INTEL_IDE_PROTOCOL also to support old Core
+// and drivers.
+// [Files]- IdeSecurity.c
+//
+// 24 10/11/10 6:36p Krishnakumarg
+// [TAG] - EIP 44603
+// [Category] - Enhancement
+// [Severity] - Minor
+// [Symptom] - No Hdd Password in Nvram once enable
+// FORCE_HDD_PASSWORD_PROMPT
+// [RootCause]- Password not stored in NVRAM on enabling the
+// FORCE_HDD_PASSWORD_PROMPT token.
+// [Solution] - Password will be stored in nvram based on
+// HDD_PASSWORD_ON_NVRAM token.
+// [Files] - IdeSecurity.c, IdeSecurity.sdl
+//
+// 23 10/11/10 10:59a Krishnakumarg
+// [TAG]- EIP 43249
+// [Category]-IMPROVEMENT
+// [Description]- Non-Ascii character in comments causing build problem in
+// japanese XP
+// [Files]- IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 22 9/13/10 1:37a Rameshr
+// [TAG]- EIP 43299
+// [Category]-IMPROVEMENT
+// [Description]- About IdeSecurity module. It use soft smi port 0xb2
+// directly.It will need to re-modify on all of AMD project.
+// 1) Added the SDL token for Sw SMI port address.
+// 2) Used Pciio protocol to get the device location and
+// passed this information to SMM driver.
+// [Files]- IdeSecurity.c, IdeSmm.c, PideBus.h
+//
+// 21 9/13/10 1:31a Rameshr
+// [TAG]- EIP 43492
+// [Category]-IMPROVEMENT
+// [Description]- Change the INTEL_IDE_PROTOCOL into EFI_IDE_PROTOCOL in
+// IdeSecurity.c
+// [Files]- IdeSecurity.c
+//
+// 20 6/07/10 7:18p Krishnakumarg
+// Build error in "4.6.3_HddSecurity_011" label.EIP#39531
+//
+// 19 5/06/10 4:39p Yul
+// Refer to EIP 37975 IdeSecurity related fixes.
+//
+// 18 2/19/10 12:47p Yul
+// Delete the comment out codes
+//
+// 17 1/21/10 12:06p Yul
+// Refer to EIP 33848.
+// LegacyBios protocol is not needed here.
+//
+// 16 1/15/10 10:20a Yul
+// Coding Standard
+//
+// 15 12/22/09 3:22p Krishnakumarg
+// Update for chm file. Added some more comments in function headers
+//
+// 14 12/09/09 12:17p Krishnakumarg
+// EIP 31797 : IDE Security API documentation. Added comments whereever
+// possible and modified files for coding standard
+//
+// 13 11/25/09 6:02p Krishnakumarg
+// Updated the file with comments to comply with AMI coding standard.
+//
+// 12 10/14/09 12:49p Krishnakumarg
+// CloseEvent funtion used instead of a static variable in callback
+// routines - EIP 27065
+//
+// 11 7/09/09 4:52p Fasihm
+// Update Identify Data before checking the Security Status of the Hard
+// Disk.
+//
+// 10 4/28/09 6:52p Rameshr
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 9 3/31/09 7:02p Davidd
+// Added FORCE_HDD_PASSWORD_PROMPT token and Device Configuration Freeze
+// Lock programming.
+//
+// 8 3/29/09 11:11a Rameshr
+// Security Erase command timeout value should be from the Identify packet
+// command word 89. Added code in Ahci and IDE drivers. So removed the
+// Extra timeout checking code from here.
+// EIP 20630
+//
+// 7 3/18/09 11:24a Fredericko
+// EIP19618 removed dependency on foundation.lib
+//
+// 6 3/13/09 3:41p Fredericko
+//
+// 1 10/17/08 7:28p Fasihm
+// This is the Initial check-in for the complete AMI Aptio source for the
+// Calpella Crb platform based on Clarksfield and Ibex Peak - M chipsets.
+//
+// 5 9/15/08 9:01p Rameshraju
+// Password Buffer is cleard before saving the password.
+//
+// 4 4/11/08 4:24p Rameshraju
+// 1)Enter the Emptry string for the master password, will set the default
+// OEM password and in setup password status will be not installed.
+// 2)If the revision code is not 0, then SecuritySetPassword will use
+// revision code from the input parameters.
+// 3)HddSecutiyData Nvram variable master password cleared when we set
+// user password and user password cleared when we set master password.
+// 4)When we disable the password, HddSecutiyData Nvram variable also
+// updated properly.
+// 5)Password lenght stored in HddSecData structure.
+//
+// 3 4/09/08 4:22p Rameshraju
+// Build error resolved when the MASTER_PASSWORD_ENABLED.
+//
+// 2 10/03/08 6:47p Anandakrishnanl
+// Removed FreezeLock related code from SMI for improving the S3 resume
+// time.
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+// 15 10/23/07 4:17p Felixp
+// IDE Security support moved from Sources to Binary
+//
+// 14 9/25/07 3:24p Rameshraju
+// Set the OEM default master password when the HDD is in unlocked and Not
+// Frozen State
+//
+// 13 14/08/07 1:57p Anandakrishnanl
+// Changes made for:
+// 1. Prompt for current password inside setup.
+// 2. Display HardDisk Security Status information.
+// 3. Master Password Verification Logic modified.
+// 4. Added Password install status in ReturnIdePasswordFlags
+// protocol function.
+//
+// 12 22/06/07 12:40p Anandakrishnanl
+// HardDisk Security Support Module Added.
+// Need ACPI Module and SB Module and under Core\Include we updated
+// Setup.h.
+// Also New IdeBus bin module.
+//
+// 11 13/04/07 3:05p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 10 12/20/06 1:25p Felixp
+// Warning fixed
+//
+// 9 12/18/06 11:59a Srinin
+// Moved CreateReadytoBootEvent little later so that Ide Controller is
+// restored first before HDD is unlocked during S3 Resume.
+//
+// 8 11/17/06 3:41p Ambikas
+//
+// 7 10/12/06 9:42a Felixp
+// UEFI2.0 compliance: use CreateReadyToBootEvent instead of CreateEvent
+//
+// 6 3/21/06 4:47p Srinin
+// Build error fixed.
+//
+// 5 3/13/06 2:21a Felixp
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:09p Srinin
+// HDD password unlock during S3 resume support added.
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 6 3/04/05 11:35a Mandal
+//
+// 5 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 3 1/13/05 4:25p Srinin
+// Procedure names modified.
+//
+// 2 1/10/05 11:31a Srinin
+// IDESecurity Interface changed.
+//
+// 1 1/05/05 11:22a Srinin
+// IDE Password Support added.
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IDESecurityServices.c
+//
+// Description: IDE Security Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IdeSecurity.h"
+
+
+
+static EFI_GUID gHddSecurityInitProtocolGuid
+ = HDD_SECURITY_INIT_PROTOCOL_GUID;
+static EFI_GUID gEfiBootScriptSaveGuid
+ = EFI_BOOT_SCRIPT_SAVE_GUID;
+static EFI_GUID gIdeSecurityPwNvguid
+ = IDE_SECURITY_PWNV_GUID;
+static EFI_GUID gSecurityModeProtocolGuid
+ = IDE_SECURITY_INTERFACE_GUID;
+static EFI_GUID gEfiBlockIoProtocolGuid
+ = EFI_BLOCK_IO_PROTOCOL_GUID;
+
+extern EFI_DRIVER_BINDING_PROTOCOL gIdeBusDriverBinding;
+extern EFI_EVENT gIDEBusEvtMiscSmmFeatures;
+EFI_EVENT BootEvent = NULL;
+EFI_EVENT gIDEBusEvtBootScript = NULL;
+
+const CHAR16 *sOemMasterPasswordTag
+ = CONVERT_TO_WSTRING( OEM_MASTER_PASSWORD_TAG );
+const CHAR16 *sDefaultMasterPasswordTag
+ = CONVERT_TO_WSTRING( DEFAULT_MASTER_PASSWORD_TAG );
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+EFI_SMM_CONTROL2_PROTOCOL *mSmmCtl=NULL;
+#else
+EFI_SMM_CONTROL_PROTOCOL *mSmmCtl=NULL;
+#endif
+
+HDD_PASSWORD *gHDDPasswordBuffer = NULL;
+EFI_SMM_COMMUNICATION_PROTOCOL *gSmmCommunication = NULL;
+
+#ifdef SW_SMI_IO_ADDRESS
+UINT8 SwSmiPort=SW_SMI_IO_ADDRESS;
+#else
+//
+// Default Sw Smi port
+//
+UINT8 SwSmiPort=0xB2;
+#endif
+
+EFI_STATUS
+HDDPortReset(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag
+);
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallSecurityInterface
+//
+// Description: Checks whether the device supports Security mode or not.
+// If yes, installs SecurityProtocol.
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : Security Mode supported.
+// EFI_DEVICE_ERROR/EFI_UNSUPPORTED : Not supported.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallSecurityInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ SECURITY_PROTOCOL *IdeSecurityInterface;
+ EFI_HANDLE IdeDeviceHandle;
+ IDENTIFY_DATA IdentifyData;
+
+ #if MASTER_PASSWORD_ENABLE
+ UINT32 IdePasswordFlags = 0;
+ #endif
+
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ IdeDeviceHandle = IdeBusInterface->IdeDeviceHandle;
+ }
+ else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ IdeDeviceHandle = SataDevInterface->IdeDeviceHandle;
+ }
+
+ if ((IdentifyData.Command_Set_Supported_82 & 0x2) == 0 )
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(SECURITY_PROTOCOL),
+ (VOID**)&IdeSecurityInterface );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ //
+ // gHDDPasswordBuffer is allocated only once. The same buffer will be used for all devices.
+ //
+ if ( gHDDPasswordBuffer == NULL )
+ {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(HDD_PASSWORD),
+ (VOID**)&gHDDPasswordBuffer );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+ }
+
+ if ( ModeFlag == FALSE )
+ {
+ IdeBusInterface->IdeSecurityInterface = IdeSecurityInterface;
+ IdeSecurityInterface->BusInterface = IdeBusInterface;
+ }
+ else {
+ SataDevInterface->IdeSecurityInterface = IdeSecurityInterface;
+ IdeSecurityInterface->BusInterface = SataDevInterface;
+ }
+
+ IdeSecurityInterface->ReturnSecurityStatus = ReturnSecurityStatus;
+ IdeSecurityInterface->SecuritySetPassword = SecuritySetPassword;
+ IdeSecurityInterface->SecurityUnlockPassword = SecurityUnlockPassword;
+ IdeSecurityInterface->SecurityDisablePassword = SecurityDisablePassword;
+ IdeSecurityInterface->SecurityFreezeLock = SecurityFreezeLock;
+ IdeSecurityInterface->SecurityEraseUnit = SecurityEraseUnit;
+ IdeSecurityInterface->ReturnIdePasswordFlags = ReturnIdePasswordFlags;
+ IdeSecurityInterface->pHDDPasswordBuffer = gHDDPasswordBuffer;
+
+ //
+ // Set ModeFlag to FALSE if IdeBus else TRUE for Ahci Bus.
+ //
+ IdeSecurityInterface->ModeFlag = ModeFlag; // Ide Bus
+
+ //
+ // Install the protocol on the device
+ //
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &IdeDeviceHandle,
+ &gSecurityModeProtocolGuid, IdeSecurityInterface,
+ NULL );
+
+ if ( gIDEBusEvtBootScript == NULL )
+ {
+ //
+ // Create event for boot script
+ //
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK,
+ IdeBusCallbackBootScript,
+ NULL,
+ &gIDEBusEvtBootScript
+ );
+ ASSERT_EFI_ERROR( Status );
+ }
+
+ //
+ // Install the Readytoboot event to locate the AhciSMM protocol interface for IdeSmm driver.
+ // AhciSmm protocol is valid only on AHCI mode. Other mode Callback is not needed
+ //
+ if ((BootEvent == NULL) && (ModeFlag))
+ {
+
+ // Send data to SMM.
+ Status = pBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &gSmmCommunication);
+ if (EFI_ERROR(Status)) {
+ gSmmCommunication=NULL;
+ }
+
+ //
+ // Create event for boot script
+ //
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK,
+ LocateAhciSmmServiceEvent,
+ NULL,
+ &BootEvent
+ );
+ ASSERT_EFI_ERROR( Status );
+ }
+
+ #if MASTER_PASSWORD_ENABLE
+ //
+ // Check if OEM_DEFAULT_MASTER_PASSWORD is enabled and
+ // DISPLAY_MASTER_PASSWORD is Disabled
+ //
+ Status = ReturnIdePasswordFlags(
+ (IDE_SECURITY_PROTOCOL*)IdeSecurityInterface,
+ &IdePasswordFlags
+ );
+
+ ASSERT_EFI_ERROR( Status );
+
+ if ((IdePasswordFlags & 0x0800) && (!(IdePasswordFlags & 0x0008)))
+ {
+ Status = OEMSetMasterPassword(
+ (IDE_SECURITY_PROTOCOL*)IdeSecurityInterface );
+ ASSERT_EFI_ERROR( Status );
+ }
+ #endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StopSecurityModeSupport
+//
+// Description: Stops the security mode support by uninstalling the
+// security interface.
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : Security Mode supported
+// EFI_DEVICE_ERROR : Not supported
+//
+// Referrals: ReturnSecurityStatus
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StopSecurityModeSupport(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE IdeDeviceHandle;
+ SECURITY_PROTOCOL *IdeSecurityInterface;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ IdeSecurityInterface = IdeBusInterface->IdeSecurityInterface;
+ IdeDeviceHandle = IdeBusInterface->IdeDeviceHandle;
+ }
+ else {
+ IdeSecurityInterface = SataDevInterface->IdeSecurityInterface;
+ IdeDeviceHandle = SataDevInterface->IdeDeviceHandle;
+ }
+
+ if ( IdeSecurityInterface == NULL )
+ {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Install Devicepath and BLOCK_IO on a new handle
+ //
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ IdeDeviceHandle,
+ &gSecurityModeProtocolGuid,
+ IdeSecurityInterface,
+ NULL );
+
+ if ( Status == EFI_SUCCESS )
+ {
+ pBS->FreePool( IdeSecurityInterface );
+ IdeSecurityInterface = NULL;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusCallbackBootScript
+//
+// Description: Saves the IDE registers in a boot script.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// None
+//
+// Referrals: SmmHDDPasswordInterface
+//
+// Notes: Will be called only if HDD loses power in S3 state. A SW SMI will
+// be created during S3 resume, to unlock the HDD and put it in
+// Freeze state.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IdeBusCallbackBootScript(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave;
+ EFI_STATUS Status;
+ UINT8 Value = SW_SMI_HDD_UNLOCK_PASSWORD;
+
+
+ Status = pBS->LocateProtocol(
+ &gEfiBootScriptSaveGuid,
+ NULL,
+ &BootScriptSave
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return;
+ }
+
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(
+ BootScriptSave,
+ EfiBootScriptWidthUint8,
+ SwSmiPort,
+ 1,
+ &Value
+ );
+
+ //
+ //Kill the Event
+ //
+ pBS->CloseEvent( Event );
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusMiscSmmFeatureCallback
+//
+// Description: Saves the IDE registers in a boot script.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// None
+//
+// Referrals: SmmHDDPasswordInterface
+//
+// Notes: Will be called only if HDD is in AHCI Mode or SWSP is Disabled
+// A SW SMI will be created during S3 resume, to Freeze the HDD in AHCI
+// or Disable SWSP command through Set feature command is Issued.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID IdeBusMiscSmmFeatureCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_BOOT_SCRIPT_SAVE_PROTOCOL *BootScriptSave;
+ EFI_STATUS Status;
+ UINT8 Value = SW_SMI_HDD_MISC_SMM_FEATURES;
+
+ static BOOLEAN S3DataSaved = FALSE;
+
+ if ( S3DataSaved )
+ {
+ return;
+ }
+
+ Status = pBS->LocateProtocol(
+ &gEfiBootScriptSaveGuid,
+ NULL,
+ &BootScriptSave
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return;
+ }
+
+ BOOT_SCRIPT_S3_IO_WRITE_MACRO(
+ BootScriptSave,
+ EfiBootScriptWidthUint8,
+ SwSmiPort,
+ 1,
+ &Value
+ );
+
+ S3DataSaved = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IdeSecurityEntryPoint
+//
+// Description: This function is the entry point for IDE SECURITY Driver.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output:
+// EFI_SUCCESS Security interface installed.
+// EFI_ERROR Security interface not installed or unable to locate
+// some protocol.
+//
+// Notes:
+// Entry Points are used to locate or install protocol interfaces and
+// notification events.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS IdeSecurityEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(HDD_SECURITY_INIT_PROTOCOL),
+ (VOID**)&gHddSecurityInitProtocol );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ Status = pBS->LocateProtocol(&gEfiSmmControl2ProtocolGuid, NULL, &mSmmCtl);
+#else
+ Status = pBS->LocateProtocol(&gEfiSmmControlProtocolGuid, NULL, &mSmmCtl);
+#endif
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+ gHddSecurityInitProtocol->InstallSecurityInterface
+ = InstallSecurityInterface;
+ gHddSecurityInitProtocol->StopSecurityModeSupport
+ = StopSecurityModeSupport;
+
+ Status = pBS->InstallProtocolInterface(
+ &Handle,
+ &gHddSecurityInitProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gHddSecurityInitProtocol
+ );
+ ASSERT_EFI_ERROR( Status );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReturnSecurityStatus
+//
+// Description: Returns whether the Device supports Security Mode or not.
+// If supported, the current status of the device is returned.
+// Security status information will be retrieved from buffer
+// updated by IDENTIFY DEVICE(Command Code : 0xEC) command.
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT16 *SecurityStatus
+//
+// Output:
+// EFI_SUCCESS : Security Mode supported
+// EFI_UNSUPPORTED : Not supported
+//
+// UINT16 *SecurityStatus
+// Bit 0 : Security Supported
+// Bit 1 : Security Enabled
+// Bit 2 : Security Locked
+// Bit 3 : Security Frozen
+// Bit 4 : Security Count Expired
+// Bit 5 : Enhanced Security Erase supported
+// Bit 6 : Enhanced Security Erase supported
+// Bit 8 : Security Level 0:High, 1:Maximum
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReturnSecurityStatus(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 *SecurityStatus )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ IDENTIFY_DATA IdentifyData;
+ VOID *BusInterface
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ }
+ else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ }
+
+ //
+ // Check if Word 82 Bit 1 is set
+ //
+ if ( IdentifyData.Command_Set_Supported_82 & 0x2 )
+ {
+ Status = EFI_SUCCESS;
+ *SecurityStatus = IdentifyData.Security_Status_128;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecuritySetPassword
+//
+// Description: Sets User/Master Password using SECURITY_SET_PASSWORD
+// (Commnd Code : 0xF1) security command.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT16 Control,
+// UINT8 *Buffer (32 Bytes)
+// UINT8 RevisionCode (Valid when Control
+// Bit 0 = 1 of Master Password)
+//
+// Control : Bit 0 : 0/1 User/Master Password
+// Bit 8 : 0/1 High/Maximum Security level
+//
+// Output:
+// EFI_SUCCESS : Password set.
+// EFI_ERROR : Error in setting Password.
+//
+// Notes:
+// 1. Buffer should be 32 bytes long (Mandatory). Even if Password is not 32
+// bytes long,pad it with zeros to create a buffer of 32 bytes.
+// 2. If a MasterPassword with a valid Revision code(0x0001 through 0xFFFE)
+// already exists, a new MasterPassword with a different revisioncode
+// cannot be installed.MasterPassword needs to be unlocked, disabled and
+// then a new password can be installed.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SecuritySetPassword(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT16 RevisionCode )
+{
+ EFI_STATUS Status;
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ UINT32 HddDataId = 0;
+ UINT16 UserMaster = 0;
+ #endif
+ UINT16 Temp = 1;
+
+ VOID *BusInterface
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ IDENTIFY_DATA IdentifyData;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ Control &= 0x0101; // Bit0 and Bit 8 are valid
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ if ( ModeFlag == FALSE )
+ {
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ }
+ else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ }
+
+ if ((Control & 1) && (RevisionCode == 0))
+ {
+ RevisionCode = DEFAULT_MASTER_PASSWORD_REVISION;
+
+ #if MASTER_PASSWORD_REVISION_SWITCH == 1
+ RevisionCode = CHANGED_MASTER_PASSWORD_REVISION;
+ #endif
+
+ #if MASTER_PASSWORD_REVISION_SWITCH == 2
+ Temp = (IdentifyData.Master_Password_Rev_92)++;
+
+ if ((Temp == 0) || (Temp == 0xFFFF))
+ {
+ Temp++;
+
+ if ( Temp == 0xFFFF )
+ {
+ Temp++;
+ }
+ }
+ RevisionCode = Temp;
+ #endif
+
+ if ( RevisionCode == DISABLED_MASTER_PASSWORD_REVISION )
+ {
+ RevisionCode++;
+
+ if ((RevisionCode == 0) || (RevisionCode == 0xFFFF))
+ {
+ RevisionCode++;
+
+ if ( RevisionCode == 0xFFFF )
+ {
+ RevisionCode++;
+ }
+ }
+ }
+ }
+
+ Status = SecurityCommonRoutine(
+ BusInterface,
+ Control,
+ Buffer,
+ SECURITY_SET_PASSWORD,
+ RevisionCode,
+ ModeFlag
+ );
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ //
+ // If Password is set successfully, save it.
+ //
+ if ( !EFI_ERROR( Status ))
+ {
+ if(!(Control & 1)) {
+ SmmHDDPasswordInterface( This,
+ Control,
+ Buffer,
+ SW_SMI_HDD_PASSWORD_SAVE );
+ }
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ Status = GatherIdeInfo( BusInterface, ModeFlag, &HddDataId );
+ ASSERT_EFI_ERROR( Status );
+
+ Status = SetHddSecDataInNvram( BusInterface,
+ &HddDataId,
+ Control,
+ Buffer );
+ ASSERT_EFI_ERROR( Status );
+ #endif
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecurityUnlockPassword
+//
+// Description: Unlocks the devices for media access using
+// SECURITY_UNLOCK(Command Code : 0xF2) security command.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT16 Control,
+// UINT8 *Buffer (32 Bytes).
+//
+// Control : Bit 0 : 0/1 User/Master Password
+// Buffer : Pointer to password buffer which will be used to unlock the
+// drive.
+//
+// Output:
+// EFI_SUCCESS : Hard disk is unlocked.
+// EFI_DEVICE_ERROR : Failed to unlock the drive.
+//
+// Notes:
+// 1. Buffer should be 32 bytes long (Mandatory). Even if Password is not
+// 32 bytes long, pad it with zeros to create a buffer of 32 bytes.
+// 2. If the password compare fails then the device returns command aborted
+// to the host and decrements the unlock counter. This counter is initially
+// set to five and is decremented for each password mismatch when SECURITY
+// UNLOCK is issued and the device is locked. When this counter reaches
+// zero then SECURITY UNLOCK and SECURITY ERASE UNIT commands are command
+// aborted until a power-on reset or a hardware reset.SECURITY UNLOCK
+// commands issued when the device is unlocked have no effect on the unlock
+// counter.
+// 3. SECURITY_DISABLE_PASSWORD and SECURITY_SET_PASSWORD commands used when
+// security password is set and HDD is in unlocked state. This is done to
+// have consistency of output from this function.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SecurityUnlockPassword(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer )
+{
+ EFI_STATUS Status;
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ UINT32 HddDataId = 0;
+ UINT16 UserMaster = 0;
+ #endif
+ UINT16 RevisionCode = 0;
+ EFI_STATUS Status1;
+ VOID *BusInterface \
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag \
+ = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ UINT16 SecurityStatus = 0;
+ #if MASTER_PASSWORD_ENABLE
+ UINT32 IdePasswordFlags = 0;
+ #endif
+
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ Status = ReturnSecurityStatus( This, &SecurityStatus );
+
+ Control &= 0x1; // Bit0 is valid
+ //
+ // When in Setup, Current Password is prompted for consistency when Setting a New Password
+ // Or Disabling the Existing Password. Follow a Special Path only in this case.
+ //*****This Case Applies on only when (1)Password is Set & Security Enabled
+ // (2)Unlocked
+
+
+ if ((SecurityStatus & BIT01) && (!(SecurityStatus & BIT02)))
+ {
+ if ( !(Control & 1))
+ {
+ //
+ // (a)For Changing or Clearing User Password.
+ // 1.Send a disable Password Command from the String Obtained from user.
+ // 2.If Success Set the Password Same Password.
+ // 3.Suitable if Logged in as Both User or Master
+ //
+ Status = SecurityCommonRoutine(
+ BusInterface,
+ Control,
+ Buffer,
+ SECURITY_DISABLE_PASSWORD,
+ 0,
+ ModeFlag
+ );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ SecurityCommonRoutine(
+ BusInterface,
+ Control,
+ Buffer,
+ SECURITY_SET_PASSWORD,
+ RevisionCode,
+ ModeFlag
+ );
+ }
+ return Status;
+ }
+
+ }
+
+ Status = SecurityCommonRoutine(
+ BusInterface,
+ Control,
+ Buffer,
+ SECURITY_UNLOCK,
+ 0,
+ ModeFlag
+ );
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ //
+ // Save the Password if unlocked Successfully.
+ //
+ SmmHDDPasswordInterface( This,
+ Control,
+ Buffer,
+ SW_SMI_HDD_PASSWORD_SAVE );
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ Status = GatherIdeInfo( BusInterface, ModeFlag, &HddDataId );
+ ASSERT_EFI_ERROR( Status );
+
+ Status = SetHddSecDataInNvram( BusInterface,
+ &HddDataId,
+ Control,
+ Buffer );
+ ASSERT_EFI_ERROR( Status );
+ #endif
+
+ //
+ // After unlock the HDD set the OEM default master password
+ // Check if OEM_DEFAULT_MASTER_PASSWORD is enabled and
+ // DISPLAY_MASTER_PASSWORD is Disabled.
+ //
+ #if MASTER_PASSWORD_ENABLE
+ Status = ReturnIdePasswordFlags( This, &IdePasswordFlags );
+ ASSERT_EFI_ERROR( Status );
+
+ if ((IdePasswordFlags & 0x0800) && (!(IdePasswordFlags & 0x0008)))
+ {
+ Status = OEMSetMasterPassword( This );
+ ASSERT_EFI_ERROR( Status );
+ }
+ #endif
+
+ if ( ModeFlag == FALSE ) {
+
+ //
+ // Check if BlockIO Protocol is already present on this device.
+ //
+ Status1 = pBS->HandleProtocol(IdeBusInterface->IdeDeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ &BlockIo
+ );
+
+ //
+ // Connect only if BloCkIO protocol is not installed on the device.
+ //
+ if ( EFI_ERROR( Status1 )) {
+ #if EFI_IDE_PROTOCOL || INTEL_IDE_PROTOCOL
+ pBS->ConnectController(
+ IdeBusInterface->IdeControllerInterfaceHandle,
+ NULL,
+ NULL,
+ TRUE
+ );
+ #else
+ pBS->ConnectController(
+ IdeBusInterface->IdeControllerInterface->ControllerHandle,
+ NULL,
+ NULL,
+ TRUE
+ );
+ #endif
+ }
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecurityDisablePassword
+//
+// Description: Disables Password authentification before media access.
+// SECURITY_DISABLE_PASSWORD(Command Code : 0xF6) security
+// command is used to remove the user password.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT16 Control,
+// UINT8 *Buffer (32 Bytes)
+//
+// Control : Bit 0 : 0/1 User/Master Password
+//
+// Buffer : Pointer to password buffer which will be used to when sending
+// SECURITY_DISABLE_PASSWORD command.
+//
+//
+// Output:
+// EFI_SUCCESS : Security mode feature disabled.
+// EFI_DEVICE_ERROR : Security command failed.
+//
+// Notes:
+// 1. Buffer should be 32 bytes long (Mandatory). Even if Password is not
+// 32 bytes long,pad it with zeros to create a buffer of 32 bytes.
+// 2. Password should be unlocked before disabling it.
+// 3. SECURITY_DISABLE_PASSWORD command does not change the Master password
+// that may be reactivated later by setting a User password.
+// 4. Normal erase mode is selected, the SECURITY ERASE UNIT command writes
+// binary zeroes to all user data areas.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SecurityDisablePassword(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer )
+{
+ EFI_STATUS Status;
+ VOID *BusInterface \
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag \
+ = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ UINT32 HddDataId = 0;
+ UINT8 EmptyBuffer[IDE_PASSWORD_LENGTH];
+ #endif
+
+ Control &= 0x1; // Bit0 is valid
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ //
+ //Update the Nvram buffer with NULL string.
+ //
+ pBS->SetMem( EmptyBuffer, IDE_PASSWORD_LENGTH, 0 );
+
+ Status = GatherIdeInfo( BusInterface, ModeFlag, &HddDataId );
+ ASSERT_EFI_ERROR( Status );
+
+ Status = SetHddSecDataInNvram( BusInterface, &HddDataId, Control, EmptyBuffer );
+ ASSERT_EFI_ERROR( Status );
+ #endif
+
+ Status = SecurityCommonRoutine( BusInterface,
+ Control,
+ Buffer,
+ SECURITY_DISABLE_PASSWORD,
+ 0,
+ ModeFlag
+ );
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ SmmHDDPasswordInterface( This,
+ Control,
+ Buffer,
+ SW_SMI_HDD_PASSWORD_REMOVE );
+ }
+
+ //
+ // If the Empty string entered for the master password, Set the OEM
+ // disable password with Disabled revision code.
+ //
+ if ( Control & 01 )
+ {
+ EFI_STATUS DefaultStatus;
+ DefaultStatus = SetDefaultMasterPassword( This );
+ ASSERT_EFI_ERROR( DefaultStatus );
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetDefaultMasterPassword
+//
+// Description: Sets the Default Password String provided by OEM as
+// Master Password.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This
+//
+// Output:
+// EFI_SUCCESS : Default master password is set.
+// EFI_ERROR : Default master password is not set.
+//
+// Notes:
+// DEFAULT_MASTER_PASSWORD_TAG token string will be set as master password.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetDefaultMasterPassword(
+ IN IDE_SECURITY_PROTOCOL *This )
+{
+ EFI_STATUS Status;
+ UINT8 Buffer[IDE_PASSWORD_LENGTH];
+ UINT16 Control = 1;
+ UINT16 RevisionCode = DISABLED_MASTER_PASSWORD_REVISION;
+ UINTN i;
+ UINT16 SecurityStatus = 0;
+
+ MemSet( &Buffer, IDE_PASSWORD_LENGTH, 0 );
+
+ for ( i = 0; i < IDE_PASSWORD_LENGTH; i++ )
+ {
+ Buffer[i] = (UINT8)sDefaultMasterPasswordTag[i];
+
+ if ( sDefaultMasterPasswordTag[i] == L'\0' )
+ {
+ break;
+ }
+ }
+ //
+ // Set the OEM master password if the HDD is not in Frozen or locked state.
+ //
+ Status = ReturnSecurityStatus( This, &SecurityStatus );
+
+ if ( !((SecurityStatus & 0x04) || (SecurityStatus & 0x08)))
+ {
+ Status = SecuritySetDefaultMasterPassword( This,
+ Control,
+ Buffer,
+ RevisionCode );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecuritySetDefaultMasterPassword
+//
+// Description: Sets default Master Password with disabled revision code.
+// SECURITY_SET_PASSWORD(Command code : 0xF1) security command
+// used to set default master password.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *This,
+// UINT16 Control,
+// UINT8 *Buffer (32 Bytes)
+// UINT8 RevisionCode (Valid when
+// Control Bit 0 = 1 of Master Password)
+//
+// Control : Bit 0 : 0/1 User/Master Password
+// Bit 8 : 0/1 High/Maximum Security level
+//
+// Output:
+// EFI_SUCCESS : Password set
+// EFI_ERROR : Error in setting Password
+//
+// Notes:
+// 1. Buffer should be 32 bytes long (Mandatory). Even if Password is not
+// 32 bytes long,pad it with zeros to create a buffer of 32 bytes.
+//
+// 2. If a MasterPassword with a valid Revision code already exists, a new
+// MasterPassword with a different revisioncode cannot be installed.
+// MasterPassword needs to be unlocked, disabled and then a new password
+// can be installed.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SecuritySetDefaultMasterPassword(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT16 RevisionCode )
+{
+ VOID *BusInterface = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ EFI_STATUS Status;
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ UINT32 HddDataId = 0;
+ UINT16 UserMaster = 0;
+ #endif
+
+ Control &= 0x0101; // Bit0 and Bit 8 are valid
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ Status = SecurityCommonRoutine(
+ BusInterface,
+ Control,
+ Buffer,
+ SECURITY_SET_PASSWORD,
+ RevisionCode,
+ ModeFlag
+ );
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ //
+ // If Password is set successfully, save it.
+ //
+ if ( !EFI_ERROR( Status ))
+ {
+ SmmHDDPasswordInterface(
+ This,
+ Control,
+ Buffer,
+ SW_SMI_HDD_PASSWORD_SAVE
+ );
+
+ #if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+ Status = GatherIdeInfo( BusInterface, ModeFlag, &HddDataId );
+ ASSERT_EFI_ERROR( Status );
+
+ Status = SetHddSecDataInNvram( BusInterface,
+ &HddDataId,
+ Control,
+ Buffer );
+ ASSERT_EFI_ERROR( Status );
+ #endif
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecurityFreezeLock
+//
+// Description: Prevents any further alteration of security status on the
+// device leaving the hard disk in Frozen mode. Frozen mode is
+// disabled by power-off or hardware reset. SECURITY_FREEZE_LOCK
+// (Command Code : 0xF5)security command is used to freeze hard disk.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+//
+// Output:
+// EFI_SUCCESS : Hard disk is successdully kept in FROZEN state.
+// EFI_ERROR : Security Freeze command failed.
+//
+// Notes:
+// Commands disabled by SECURITY FREEZE LOCK are:
+// - SECURITY SET PASSWORD
+// - SECURITY UNLOCK
+// - SECURITY DISABLE PASSWORD
+// - SECURITY ERASE PREPARE
+// - SECURITY ERASE UNIT
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SecurityFreezeLock(
+ IN IDE_SECURITY_PROTOCOL *This )
+{
+ EFI_STATUS Status;
+ VOID *BusInterface
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag
+ = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ UINT16 SecurityStatus = 0;
+
+ COMMAND_STRUCTURE CommandStructure;
+#if !DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT
+ IDENTIFY_DATA IdentifyData;
+#endif
+
+ Status=ReturnSecurityStatus( This, &SecurityStatus );
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Freeze Lock command will not work with the HDD is in Locked State.
+ // So return with success if the HDD is locked state or already frozen state
+ if ( SecurityStatus & 0xc ) {
+ return EFI_SUCCESS;
+ }
+
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SECURITY_FREEZE_LOCK;
+
+#if !DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT
+ if ( ModeFlag == FALSE ) {
+ IdentifyData = ((IDE_BUS_PROTOCOL*)BusInterface)->IdeDevice.IdentifyData;
+ } else {
+ IdentifyData = ((SATA_DEVICE_INTERFACE*)BusInterface)->IdentifyData;
+ }
+ if ( SecurityStatus & 2 )
+ {
+ if ( IdentifyData.Reserved_76_79[3] & 0x0040 )
+ {
+ Status = TransferPwDataFromNvramToSmram( This );
+ ASSERT_EFI_ERROR( Status );
+ }
+ }
+#endif
+
+ Status = CommonNonDataHook( BusInterface,
+ CommandStructure,
+ ModeFlag );
+ ASSERT_EFI_ERROR (Status);
+ CommandStructure.Features = DEV_CONFIG_FREEZE_LOCK_FEATURES;
+ CommandStructure.Command = DEV_CONFIG_FREEZE_LOCK;
+ Status = CommonNonDataHook( BusInterface,
+ CommandStructure,
+ ModeFlag );
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecurityEraseUnit
+//
+// Description: Erases the Device content.SECURITY_ERASE_UNIT
+// (Command code : 0xF4) security command is used for device
+// erasing.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT16 Control,
+// UINT8 *Buffer
+//
+// Control : Bit 0 : 0/1 User/Master Password
+// Bit 1 : 0/1 Normal Erase/ Enhanced Erase
+// Buffer : Pointer to password buffer which will be used to when sending
+// SECURITY_ERASE_UNIT command.
+//
+// Output:
+// EFI_SUCCESS : Successfull completion of Erase command.
+// EFI_DEVICE_ERROR : EraseUnit command failed to complete.
+//
+// Notes:
+// If a device is locked with USER PASSWORD and Maximum security level set
+// then only way to unlock the device with MASTER password is to erase the
+// contents of the device.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SecurityEraseUnit(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer )
+{
+ EFI_STATUS Status;
+
+ VOID *BusInterface \
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag \
+ = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ COMMAND_STRUCTURE CommandStructure;
+
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Command = SECURITY_ERASE_PREPARE;
+
+ Status = CommonNonDataHook( BusInterface, CommandStructure, ModeFlag );
+
+ //
+ // Issue Security Erase Unit
+ //
+ Control &= 0x3; // Bit0 and Bit 1 is valid
+ Status = SecurityCommonRoutine(
+ BusInterface,
+ Control,
+ Buffer,
+ SECURITY_ERASE_UNIT,
+ 0,
+ ModeFlag
+ );
+
+ //
+ // Update the Identify device buffer
+ //
+ UpdateIdentifyData( BusInterface, ModeFlag );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReturnIdePasswordFlags
+//
+// Description: Returns Ide Password Variables and Flags.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT32 *IdePasswordFlags
+//
+// Output:
+// EFI_SUCCESS : IDEPassword Status Flag is returned in IdePasswordFlags.
+// EFI_ERROR : Error while retrieving the SecurityStatus.
+//
+//
+// Referrals:
+//
+// IdePasswordFlags:
+// **TBD Only Bit0, Bit03, Bit11, Bit16, Bit17 are Supported Currently
+//
+// BIT0 User Password Support;
+// BIT1 Master Password Support;
+// BIT2 Display User Password;
+// BIT3 Display Master Password;
+// BIT4 Display User Password Status;
+// BIT5 Display Master Password Status;
+// BIT6 Freeze Lock Hdds;
+// BIT7 Single User Password;
+// BIT8 Single Master Password;
+// BIT9 System User Password as Hdd User Password;
+// BIT10 System Admin Password as Hdd Master Password;
+// BIT11 OEM Default Master Password
+// BIT12 Prompt for User Password in Post
+// BIT13 Prompt for Master Password in Post
+// BIT14 Display Security Status in Setup
+// BIT15 DUMMY Security Token.
+// BIT16 MasterPassword Set Status.
+// BIT17 UserPassword Set Status.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReturnIdePasswordFlags(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT32 *IdePasswordFlags )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 Temp = 0;
+ UINT16 MasterPwdRev = 0;
+ UINT16 SecurityStatus = 0;
+ VOID *BusInterface
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag
+ = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ IDENTIFY_DATA IdentifyData;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ }
+ else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ }
+
+
+
+ #if MASTER_PASSWORD_ENABLE
+ Temp |= BIT01;
+ #endif
+
+
+ #if DISPLAY_MASTER_PASSWORD
+ Temp |= BIT03;
+ #endif
+
+ #if OEM_DEFAULT_MASTER_PASSWORD
+ Temp |= BIT11;
+ #endif
+
+
+ MasterPwdRev = IdentifyData.Master_Password_Rev_92;
+
+ if ((MasterPwdRev != 0x0000) && (MasterPwdRev != 0xFFFF) \
+ && (MasterPwdRev != DISABLED_MASTER_PASSWORD_REVISION))
+ {
+ Temp |= BIT16;
+ }
+
+ Status = ReturnSecurityStatus( This, &SecurityStatus );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ if ( SecurityStatus & BIT01 )
+ {
+ Temp |= BIT17;
+ }
+
+ *IdePasswordFlags = (UINT32)Temp;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SecurityCommonRoutine
+//
+// Description: This is common security routine which will be called from
+// security routines. It is from this routine most of the security
+// commands are sent to the drive.
+//
+// Input:
+// IN VOID *BusInterface,
+// UINT16 Control,
+// UINT8 *Buffer (32 Bytes),
+// UINT8 SecurityCommand
+// UINT8 RevisionCode
+// (Valid for Master password)
+//
+// Control : Bit 0 : 0/1 User/Master Password
+// Bit 1 : 0/1 Normal/Enhanced Erase
+// Bit 8 : 0/1 High/Maximum Security level
+//
+// Buffer : Pointer to password buffer which will be used to when sending
+// SecurityCommand.
+//
+//
+// Output:
+// EFI_STATUS : EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Notes:
+// 1. Buffer should be 32 bytes long (Mandatory). Even if Password is not
+// 32 bytes long, pad it with zeros to create a buffer of 32 bytes.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SecurityCommonRoutine(
+ IN VOID *BusInterface,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT8 SecurityCommand,
+ UINT16 RevisionCode,
+ BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ UINT16 *SecurityBuffer;
+
+ //
+ // Allocate 512 Bytes
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ SECURITY_BUFFER_LENGTH,
+ (VOID**)&SecurityBuffer );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ //
+ // Clear the Buffer
+ //
+ ZeroMemory( SecurityBuffer, SECURITY_BUFFER_LENGTH );
+
+ SecurityBuffer[0] = Control;
+
+ //
+ // Copy 32 Bytes
+ //
+ pBS->CopyMem( &(SecurityBuffer[1]), Buffer, IDE_PASSWORD_LENGTH );
+
+ //
+ // If Security Set password command is for Master, then update the
+ // revision code.
+ //
+ if ((SecurityCommand == SECURITY_SET_PASSWORD) & (Control & 1))
+ {
+ if ((RevisionCode != 0) || (RevisionCode != 0xFFFF))
+ {
+ SecurityBuffer[17] = RevisionCode;
+ }
+ }
+
+ //
+ // Write 512 Bytes
+ //
+ Status = CommonReadWritePioHook(
+ BusInterface,
+ SecurityBuffer,
+ SECURITY_BUFFER_LENGTH,
+ 0,
+ SecurityCommand,
+ TRUE,
+ ModeFlag
+ );
+
+ pBS->FreePool( SecurityBuffer );
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmHDDPasswordInterface
+//
+// Description: Manages HDD Password in SMM area.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+// UINT16 Control,
+// UINT8 *Buffer
+// UINT8 Action
+//
+//
+// Control : Bit 0 : 0/1 User/Master Password
+//
+// Buffer : Pointer to password buffer which will be used to when sending
+// SecurityCommand.
+//
+// Output:
+// EFI_SUCCESS : Password saved which will be used to unlock the drive
+// during S3 resume.
+// EFI_DEVICE_ERROR : Error in saving Password.
+//
+// Notes:
+// 1. Buffer should be 32 bytes long (Mandatory). Even if Password is not
+// 32 bytes long, pad it with zeros to create a buffer of 32 bytes.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmHDDPasswordInterface(
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT8 Action )
+{
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ UINT8 DataSize = 1;
+#else
+ UINTN DataSize = 1;
+#endif
+ UINT8 SwSmiValue = Action;
+ UINTN i;
+ HDD_PASSWORD *HDDPasswordBuffer = gHDDPasswordBuffer;
+ VOID *BusInterface \
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag \
+ = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ EFI_STATUS Status;
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicationHeader;
+ UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(HDD_PASSWORD)];
+ UINTN CommBufferSize;
+#endif
+
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ //
+ // If HDD is not going to lose power in S3, no need to unlock password and put it in
+ // Freeze state during S3 resume.
+ //
+ if ( !(IdeBusInterface->IdeBusInitInterface->Flags \
+ & S3_RESUME_UNLOCK_HDD_PASSWORD))
+ {
+ return EFI_SUCCESS;
+ }
+
+ HDDPasswordBuffer->BaseAddress
+ = IdeBusInterface->IdeDevice.Regs.CommandBlock.DataReg;
+ HDDPasswordBuffer->Device = IdeBusInterface->IdeDevice.Device;
+ HDDPasswordBuffer->DeviceControlReg
+ = IdeBusInterface->IdeDevice.Regs.ControlBlock.DeviceControlReg;
+ PciIo = IdeBusInterface->PciIO;
+
+ }
+ else {
+
+ PciIo=SataDevInterface->AhciBusInterface->PciIO;
+ HDDPasswordBuffer->PortNumber = SataDevInterface->PortNumber;
+ HDDPasswordBuffer->PMPortNumber = SataDevInterface->PMPortNumber;
+ }
+
+ //
+ // Get PCI Bus/Device/Function number
+ //
+ Status = PciIo->GetLocation ( PciIo,
+ &SegNum,
+ &BusNum,
+ &DevNum,
+ &FuncNum
+ );
+
+ //
+ // Save it for IdeSmm to initilize the controller.
+ //
+ HDDPasswordBuffer->BusNo=(UINT8)BusNum;
+ HDDPasswordBuffer->DeviceNo=(UINT8)DevNum;
+ HDDPasswordBuffer->FunctionNo=(UINT8)FuncNum;
+
+ HDDPasswordBuffer->Signature = '$HDD'; // 0x44444824; //
+ HDDPasswordBuffer->Control = Control;
+ HDDPasswordBuffer->ModeFlag = ModeFlag;
+
+ //
+ // HDDPasswordBuffer->RevisionCode = RevisionCode;
+ //
+ if ( Control & 0x01 )
+ {
+ for ( i = 0; i < sizeof (HDDPasswordBuffer->MasterPassword); i++ )
+ {
+ HDDPasswordBuffer->MasterPassword[i] = Buffer[i];
+ } // end of for
+ }
+ else {
+ for ( i = 0; i < sizeof (HDDPasswordBuffer->UserPassword); i++ )
+ {
+ HDDPasswordBuffer->UserPassword[i] = Buffer[i];
+ } // end of for
+ }
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+
+ if(!gSmmCommunication) {
+ Status = pBS->LocateProtocol (
+ &gEfiSmmCommunicationProtocolGuid,
+ NULL,
+ (VOID **)&gSmmCommunication
+ );
+ if (EFI_ERROR (Status)) {
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+ }
+ }
+
+ SmmCommunicationHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
+
+ if(SwSmiValue == SW_SMI_HDD_PASSWORD_SAVE) {
+ pBS->CopyMem( &SmmCommunicationHeader->HeaderGuid, &gSaveHddPasswordGuid, sizeof( EFI_GUID ) );
+ } else if( SwSmiValue == SW_SMI_HDD_PASSWORD_REMOVE ) {
+ pBS->CopyMem( &SmmCommunicationHeader->HeaderGuid, &gRemoveHddPasswordGuid, sizeof( EFI_GUID ) );
+ } else {
+ // Unknown SwSmiValue
+ return EFI_UNSUPPORTED;
+ }
+
+ SmmCommunicationHeader->MessageLength = sizeof(HDD_PASSWORD);
+ pBS->CopyMem( &SmmCommunicationHeader->Data, HDDPasswordBuffer, sizeof(HDD_PASSWORD) );
+
+ CommBufferSize = sizeof(CommBuffer);
+ Status = gSmmCommunication->Communicate (gSmmCommunication, &CommBuffer[0], &CommBufferSize);
+#else
+ // Now Generate a SW SMI to log this data
+ mSmmCtl->Trigger( mSmmCtl, &SwSmiValue, &DataSize, 0, 0 );
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UpdateIdentifyData
+//
+// Description: Updates Identify command data.IDENTIFY_DATA(Command Code: 0xEC)
+// command used to update the Identifydata buffer.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : Identifydata updated successfully.
+// EFI_ERROR : Failed to update the identifydata.
+//
+// Notes: ATA/ATAPI device type should have beeen known already.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateIdentifyData(
+ IN IDE_BUS_PROTOCOL *BusInterface,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ CommandStructure.ByteCount = sizeof(IDENTIFY_DATA);
+ CommandStructure.Command = IDENTIFY_COMMAND;
+
+ Status = CommonPioDataHook( BusInterface, CommandStructure, ModeFlag );
+
+ return Status;
+}
+
+#if MASTER_PASSWORD_ENABLE
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OEMSetMasterPassword
+//
+// Description: Sets the Default Password String provided by OEM as
+// Master Password. SECURITY_SET_PASSWORD(Command Code : 0xF1)
+// security command is used to set the master password.
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+//
+// Output:
+// EFI_SUCCESS : OEM Master password set successfully.
+// EFI_ERROR : Failed to set OEM Master passord to the hard disk.
+//
+// Notes:
+// OEM_MASTER_PASSWORD_TAG token string will be set as oem master password.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OEMSetMasterPassword(
+ IN IDE_SECURITY_PROTOCOL *This )
+{
+ EFI_STATUS Status = 0;
+ UINT8 Buffer[IDE_PASSWORD_LENGTH];
+ UINT16 Control = 1;
+ UINT16 RevisionCode = 0xFFFE;
+ UINTN i;
+ UINT16 SecurityStatus = 0;
+
+ MemSet( &Buffer, IDE_PASSWORD_LENGTH, 0 );
+
+ for ( i = 0; i < IDE_PASSWORD_LENGTH; i++ )
+ {
+ Buffer[i] = (UINT8)sOemMasterPasswordTag[i];
+
+#if defined SETUP_PASSWORD_NON_CASE_SENSITIVE && SETUP_PASSWORD_NON_CASE_SENSITIVE
+ Buffer[i] = ((Buffer[i]>='a')&&(Buffer[i]<='z'))?(Buffer[i]+'A'-'a'):Buffer[i];
+#endif
+ if ( sOemMasterPasswordTag[i] == L'\0' )
+ {
+ break;
+ }
+ }
+
+ //
+ //Set the OEM master password if the HDD is not in Frozen or locked state.
+ //
+ ReturnSecurityStatus( This, &SecurityStatus );
+
+ if ( !((SecurityStatus & 0x04) || (SecurityStatus & 0x08)))
+ {
+ Status = SecuritySetPassword( This, Control, Buffer, RevisionCode );
+ }
+
+ return Status;
+}
+
+#endif
+
+#if (!DISABLE_SOFT_SET_PREV && !FORCE_HDD_PASSWORD_PROMPT ) || HDD_PASSWORD_ON_NVRAM
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GatherIdeInfo
+//
+// Description: Gathers Ide Device's Bus,Func,Device & PM/PS/SM/SS Info.
+//
+// Input:
+// IN VOID *BusInterface,
+// OUT UINT32 *HddDataId
+//
+// Output:
+// EFI_SUCCESS : IDE info retrieved successfully.
+// EFI_ERROR : Failed to get IDE info.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GatherIdeInfo(
+ IN VOID *BusInterface,
+ BOOLEAN ModeFlag,
+ OUT UINT32 *HddDataId )
+{
+ EFI_STATUS Status;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ UINT16 wBDF;
+ UINT16 wPortPMModeFlag;
+ UINT8 ChannelorPort;
+ UINT8 DeviceorPMPort;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ PciIo = IdeBusInterface->PciIO;
+ ChannelorPort = IdeBusInterface->IdeDevice.Channel;
+ DeviceorPMPort = IdeBusInterface->IdeDevice.Device;
+ }
+ else {
+ PciIo = SataDevInterface->AhciBusInterface->PciIO;
+ ChannelorPort = SataDevInterface->PortNumber;
+ DeviceorPMPort = SataDevInterface->PMPortNumber;
+ }
+
+ Status = PciIo->GetLocation( PciIo, &SegNum, &BusNum, &DevNum, &FuncNum );
+
+ wBDF = (UINT16)((BusNum << 8) | (DevNum << 3) | FuncNum );
+ wPortPMModeFlag = (UINT16)((ChannelorPort << 12) \
+ | (DeviceorPMPort << 4) \
+ | ((UINT8)ModeFlag));
+
+ *HddDataId = (UINT32)(((UINT16)wBDF << 16) + ((UINT16)wPortPMModeFlag));
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetHddSecDataInNvram
+//
+// Description: Sets Hdd Security Data in NVRAM Area.
+//
+// Input:
+// IN VOID *BusInterface,
+// UINT32 *HddDataId
+// UINT16 Control,
+// UINT8 *Buffer
+//
+// Control : Bit 0 : 0/1 User/Master Password
+//
+// Buffer : Pointer to password buffer which will be used to when sending
+// SecurityCommand.
+// Output:
+// EFI_SUCCESS : HDDPassword saved in NVram which later will be transfered to
+// SMRAM.
+// EFI_ERROR : Failed to save the HDD password in nvram.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetHddSecDataInNvram(
+ IN VOID *BusInterface,
+ UINT32 *HddDataId,
+ UINT16 Control,
+ UINT8 *Buffer )
+{
+ EFI_STATUS Status;
+ HDDSECDATA *HddSecData=NULL;
+ UINTN i;
+ CHAR16 *HddSecutiyData = NULL;
+ UINT8 CryptBuffer[IDE_PASSWORD_LENGTH];
+ UINTN HddSecDataSize = sizeof (HDDSECDATA);
+ UINT32 ParseIndex;
+ UINT32 Attribute = 0;
+
+ pBS->AllocatePool( EfiBootServicesData, sizeof (HDDSECDATA), &HddSecData );
+ pBS->SetMem( HddSecData, sizeof(HDDSECDATA), 0 );
+ pBS->AllocatePool( EfiBootServicesData,
+ IDE_PASSWORD_LENGTH,
+ &HddSecutiyData );
+ pBS->SetMem( HddSecutiyData, IDE_PASSWORD_LENGTH, 0 );
+ ConvertHddDataIdToString( *HddDataId, HddSecutiyData );
+
+ //
+ // Get the password variable so that other password will be
+ // maintained in the nvram variable.
+ //
+ Status = pRS->GetVariable(
+ HddSecutiyData,
+ &gIdeSecurityPwNvguid,
+ &Attribute,
+ &HddSecDataSize,
+ HddSecData
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ pBS->SetMem( HddSecData, sizeof(HDDSECDATA), 0 );
+ if(Attribute == 0) {
+ Attribute = (UINT32)(EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ }
+ }
+
+
+ for ( ParseIndex = 0; ParseIndex < IDE_PASSWORD_LENGTH; ParseIndex++ )
+ {
+ if ( Buffer[ParseIndex] == 0 )
+ {
+ break;
+ }
+ }
+
+ HddSecData->UserMaster = Control;
+ HddSecData->PasswordLength = ParseIndex;
+
+ if ( Control & 0x01 )
+ {
+ EncodeDecodePassword( Buffer, CryptBuffer, ParseIndex );
+
+ for ( i = 0; i < ParseIndex; i++ )
+ {
+ HddSecData->HddMasterPassword[i] = CryptBuffer[i];
+ }
+
+ for ( i = ParseIndex; i < sizeof (HddSecData->HddMasterPassword); i++ )
+ {
+ HddSecData->HddMasterPassword[i] = 00;
+ }
+ }
+ else {
+ EncodeDecodePassword( Buffer, CryptBuffer, ParseIndex );
+
+ for ( i = 0; i < ParseIndex; i++ )
+ {
+ HddSecData->HddUserPassword[i] = CryptBuffer[i];
+ }
+
+ for ( i = ParseIndex; i < sizeof (HddSecData->HddUserPassword); i++ )
+ {
+ HddSecData->HddUserPassword[i] = 00;
+ }
+ }
+
+ Status = pRS->SetVariable(
+ HddSecutiyData,
+ &gIdeSecurityPwNvguid,
+ Attribute,
+ HddSecDataSize,
+ HddSecData
+ );
+
+ ASSERT_EFI_ERROR( Status );
+ pBS->FreePool( HddSecData );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: TransferPwDataFromNvramToSmram
+//
+// Description: Transfers Stored Data from NVRAM to SMRAM.
+//
+// Input:
+// IN IDE_SECURITY_PROTOCOL *This,
+//
+// Output:
+// EFI_SUCCESS : Password saved in SMRAM.
+// EFI_DEVICE_ERROR : Password not saved in SMRAM.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TransferPwDataFromNvramToSmram(
+ IN IDE_SECURITY_PROTOCOL *This
+)
+{
+ UINT32 HddDataId = 0;
+ UINT16 UserMaster = 0;
+ CHAR16 *HddSecutiyData = NULL;
+ HDDSECDATA *HddSecData = NULL;
+ VOID *BusInterface \
+ = ((SECURITY_PROTOCOL* )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SECURITY_PROTOCOL* )This)->ModeFlag;
+ EFI_STATUS Status;
+ UINT16 Control;
+ UINTN i;
+ UINTN HddSecDataSize = sizeof (HDDSECDATA);
+ UINT8 CryptBuffer[IDE_PASSWORD_LENGTH];
+ UINT8 Buffer[IDE_PASSWORD_LENGTH];
+ UINT16 SecurityStatus = 0;
+
+ Status=ReturnSecurityStatus( This, &SecurityStatus );
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Hdd Password Nvram Variable will not be avilable if the HDD is in locked state.
+ // So return without copying the password to Smram as the password
+ // data is not avilable
+
+ if ( SecurityStatus & 4 ) {
+ return EFI_SUCCESS;
+ }
+
+ Status = GatherIdeInfo( BusInterface, ModeFlag, &HddDataId );
+ ASSERT_EFI_ERROR( Status );
+
+ pBS->AllocatePool( EfiBootServicesData,
+ IDE_PASSWORD_LENGTH,
+ &HddSecutiyData );
+ pBS->SetMem( HddSecutiyData, IDE_PASSWORD_LENGTH, 0 );
+ ConvertHddDataIdToString( HddDataId, HddSecutiyData );
+
+ pBS->AllocatePool( EfiBootServicesData, sizeof (HDDSECDATA), &HddSecData );
+ pBS->SetMem( HddSecData, sizeof(HDDSECDATA), 0 );
+
+ pBS->SetMem( Buffer, IDE_PASSWORD_LENGTH, 0 );
+
+ Status = pRS->GetVariable(
+ HddSecutiyData,
+ &gIdeSecurityPwNvguid,
+ NULL,
+ &HddSecDataSize,
+ HddSecData
+ );
+
+ if(Status){
+ Status = HDDPortReset(BusInterface,ModeFlag);
+ return Status;
+ }
+
+ Control = HddSecData->UserMaster;
+
+ if ( Control & 0x01 )
+ {
+ for ( i = 0; i < sizeof (HddSecData->HddMasterPassword); i++ )
+ {
+ CryptBuffer[i] = HddSecData->HddMasterPassword[i];
+ }
+
+ EncodeDecodePassword( CryptBuffer, Buffer, HddSecData->PasswordLength );
+ }
+ else {
+ for ( i = 0; i < sizeof (HddSecData->HddUserPassword); i++ )
+ {
+ CryptBuffer[i] = HddSecData->HddUserPassword[i];
+ }
+
+ EncodeDecodePassword( CryptBuffer, Buffer, HddSecData->PasswordLength );
+ }
+
+ SmmHDDPasswordInterface( This,
+ Control,
+ Buffer,
+ SW_SMI_HDD_PASSWORD_SAVE );
+
+ pBS->FreePool( HddSecData );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ConvertHddDataIdToString
+//
+// Description: Converts Integer HDD Data Id to String.
+//
+// Input:
+// IN UINT32 DataId,
+// OUT CHAR16 *String
+// Output:
+// None
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ConvertHddDataIdToString(
+ IN UINT32 DataId,
+ OUT CHAR16 *String )
+{
+ Swprintf( String, L"%*d", 0, DataId );
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EncodeDecodePassword
+//
+// Description: Encodes/Decodes Password.
+//
+// Input:
+// IN UINT8 *InputString,
+// OUT UINT8 *OutputString,
+// IN UINT32 StringLen
+// Output:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EncodeDecodePassword(
+ IN UINT8 *InputString,
+ OUT UINT8 *OutputString,
+ IN UINT32 StringLength )
+{
+ UINT8 *Key;
+ UINT32 i;
+ UINT32 KeyIndex;
+ UINT32 KeyLength;
+
+ if ((InputString == NULL) || (StringLength == 0))
+ {
+ return;
+ }
+
+ KeyLength = (UINT32)( Strlen( HDD_PWD_ENCRYPTION_KEY ));
+ pBS->AllocatePool( EfiBootServicesData, KeyLength, (VOID**)&Key );
+ pBS->SetMem( Key, KeyLength, 0 );
+ pBS->CopyMem( Key, HDD_PWD_ENCRYPTION_KEY, KeyLength );
+ ASSERT( Key != NULL );
+
+ for ( i = 0, KeyIndex = 0; i < StringLength; i++, KeyIndex++ )
+ {
+ if ( KeyIndex == (KeyLength - 1))
+ {
+ KeyIndex = 0;
+ }
+ OutputString[i] = (UINT8) ( InputString[i] ^ Key[KeyIndex] );
+ }
+
+ pBS->FreePool( Key );
+ return;
+}
+
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CommonNonDataHook
+//
+// Description: Common Hook which Calls Non Data Command.
+//
+// Input: IN VOID* BusInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : Non Data command completed successfully.
+// EFI_DEVICE_ERROR/EFI_UNSUPPORTED : Not supported.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CommonNonDataHook(
+ IN VOID *BusInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+
+ //
+ // Idebus API changed from Core 4.6.5.2. Added Core Version check for the OLD
+ // Core support.
+ //
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028b)
+ Status = IdeBusInterface->IdeNonDataCommand(
+ IdeBusInterface,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ (UINT8)(CommandStructure.SectorCount >> 8),
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Device,
+ CommandStructure.Command
+ );
+#else
+ Status = IdeBusInterface->IdeNonDataCommand(
+ IdeBusInterface,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAHigh,
+ CommandStructure.Device,
+ CommandStructure.Command
+ );
+
+#endif
+ }
+ else {
+ Status = SataDevInterface->AhciBusInterface->ExecuteNonDataCommand(
+ SataDevInterface,
+ CommandStructure
+ );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CommonPioDataHook
+//
+// Description: Common Hook which Calls Pio Data Command.
+//
+// Input: IN VOID* BusInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : Pio data command completed.
+// EFI_DEVICE_ERROR/EFI_UNSUPPORTED : Not supported.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CommonPioDataHook(
+ IN VOID *BusInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ VOID *IdentifyBuffer = NULL;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(IDENTIFY_DATA),
+ (VOID**)&IdentifyBuffer
+ );
+ //
+ // Read Identifydata
+ //
+ CommandStructure.Buffer = IdentifyBuffer;
+
+ if ( ModeFlag == FALSE )
+ {
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+ Status = IdeBusInterface->AtaPioDataIn(
+ IdeBusInterface,
+ CommandStructure
+ .Buffer,
+ CommandStructure
+ .ByteCount,
+ CommandStructure
+ .Features,
+ (UINT8)
+ CommandStructure.SectorCount,
+ CommandStructure
+ .LBALow,
+ CommandStructure
+ .LBAMid,
+ CommandStructure
+ .LBAHigh,
+ CommandStructure
+ .Device,
+ CommandStructure
+ .Command,
+ FALSE
+ );
+ //
+ // Copy Identify Data
+ //
+ pBS->CopyMem( &(IdeBusInterface->IdeDevice.IdentifyData),
+ IdentifyBuffer,
+ sizeof(IDENTIFY_DATA)
+ );
+ }
+ else {
+ Status = SataDevInterface->AhciBusInterface->ExecutePioDataCommand(
+ SataDevInterface,
+ &CommandStructure,
+ FALSE
+ );
+
+ //
+ // Copy Identify Data
+ //
+ pBS->CopyMem( &(SataDevInterface->IdentifyData),
+ IdentifyBuffer,
+ sizeof(IDENTIFY_DATA)
+ );
+ }
+
+ pBS->FreePool( IdentifyBuffer );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+//
+// Procedure: CommonReadWritePioHook
+//
+// Description: Common Hook which Calls Read Write PIO.
+//
+// Input:
+// IN VOID *BusInterface,
+// VOID *Buffer,
+// UINTN ByteCount,
+// UINT64 LBA
+// IN UINT8 ReadWriteCommand,
+// IN BOOLEAN ReadWrite Read/Write = 0/1
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// *Buffer updated from PIO command.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CommonReadWritePioHook(
+ IN VOID *BusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN ReadWrite,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE )
+ {
+ Status = IdeBusInterface->AtaReadWritePio(
+ IdeBusInterface,
+ Buffer,
+ ByteCount,
+ 0,
+ ReadWriteCommand,
+ TRUE
+ );
+ }
+ else {
+ Status = SataDevInterface->AhciBusInterface->SataReadWritePio(
+ SataDevInterface,
+ Buffer,
+ ByteCount,
+ 0,
+ ReadWriteCommand,
+ TRUE
+ );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: LocateAhciSmmServiceEvent
+//
+// Description: Generates the SwSMI to Locate the AhciSMM Protocol
+// that is used by IdeSMM.
+//
+// Input:
+// EFI_EVENT Event,
+// VOID *Context
+//
+// Output:
+// None
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID LocateAhciSmmServiceEvent(
+ EFI_EVENT Event,
+ VOID *Context )
+{
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+ EFI_SMM_COMMUNICATE_HEADER *SmmCommunicateHeader;
+ UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(UINT8*)];
+ UINTN CommBufferSize;
+ EFI_STATUS Status;
+#elif defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ UINT8 DataSize = 1;
+#else
+ UINTN DataSize = 1;
+#endif
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010014)
+
+ if(gSmmCommunication != NULL) {
+ Status = pBS->LocateProtocol (&gEfiSmmCommunicationProtocolGuid, NULL, (VOID **) &gSmmCommunication);
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return ;
+ }
+ }
+
+ // Copy Smm Communicate Header Here
+ SmmCommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommBuffer;
+ pBS->CopyMem( &SmmCommunicateHeader->HeaderGuid, &gLocateIdeAhciSmmProtocolGuid, sizeof( EFI_GUID ) );
+ SmmCommunicateHeader->MessageLength = sizeof(UINT8 *);
+
+ // Allocate the Buffer for the Passing the Password Data to
+ // Unlock command in SMM
+ Status = pBS->AllocatePool( EfiReservedMemoryType,
+ 512,
+ (VOID**)&SmmCommunicateHeader->Data );
+
+ // Calculate Size of Communication buffer
+ CommBufferSize = sizeof (CommBuffer);
+
+ // Send data to SMM.
+ Status = gSmmCommunication->Communicate (gSmmCommunication, &CommBuffer[0], &CommBufferSize);
+ ASSERT_EFI_ERROR(Status);
+
+#else
+ UINT8 SwSmiValue = SW_SMI_AHCI_LOCATE_AHCI_SMM;
+
+ // Now Generate a SW SMI to Locate all the SMM protocols used by IDESMM
+ mSmmCtl->Trigger( mSmmCtl, &SwSmiValue, &DataSize, 0, 0 );
+#endif
+
+ return;
+}
+
+
+EFI_STATUS
+HDDPortReset(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag
+)
+{
+
+ EFI_STATUS Status;
+ AHCI_BUS_PROTOCOL *AhciBusInterface;
+ SATA_DEVICE_INTERFACE *SataDeviceInterface;
+ DLINK *dlink;
+ COMMAND_STRUCTURE CommandStructure = {0};
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Entries = NULL;
+
+
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+ AhciBusInterface = SataDevInterface->AhciBusInterface;
+
+ if ( ModeFlag == FALSE ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Issue Disable Software Preservation command all the Sata Devices connected.
+ dlink = AhciBusInterface->SataDeviceList.pHead;
+ if (dlink){
+ do {
+ SataDeviceInterface = OUTTER(dlink, SataDeviceLink, SATA_DEVICE_INTERFACE);
+ if(SataDevInterface->PortNumber == SataDeviceInterface->PortNumber &&
+ SataDevInterface->PMPortNumber == SataDeviceInterface->PMPortNumber) {
+
+ // Send Disable Software Preservation command.
+ CommandStructure.Features = DISABLE_SATA2_SOFTPREV;
+ CommandStructure.SectorCount = 6;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ Status = AhciBusInterface->ExecuteNonDataCommand(SataDeviceInterface,
+ CommandStructure);
+ break;
+ }
+ dlink = dlink-> pNext;
+ }while (dlink);
+ }
+
+ // Reset the port to restore the initial State
+ Status = AhciBusInterface->GeneratePortReset(
+ AhciBusInterface,
+ SataDevInterface,
+ SataDevInterface->PortNumber,
+ SataDevInterface->PMPortNumber,
+ 0,
+ 0
+ );
+
+
+ // Disconnect the Controller Handle
+ Status = pBS->DisconnectController(
+ AhciBusInterface->ControllerHandle,
+ NULL,
+ NULL);
+
+ // Connect Controller handle again to invoke the HDD Password Verfication
+ Status = pBS->ConnectController(
+ AhciBusInterface->ControllerHandle,
+ NULL,
+ NULL,
+ TRUE);
+
+ // Send Enable Software Preservation command.
+ CommandStructure.Features = 0x10;
+ CommandStructure.SectorCount = 6;
+ CommandStructure.Command = SET_FEATURE_COMMAND;
+ Status = AhciBusInterface->ExecuteNonDataCommand(SataDeviceInterface,
+ CommandStructure);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSecurity/IdeSecurity.chm b/Core/EM/HddSecurity/IdeSecurity.chm
new file mode 100644
index 0000000..abc643a
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.chm
Binary files differ
diff --git a/Core/EM/HddSecurity/IdeSecurity.cif b/Core/EM/HddSecurity/IdeSecurity.cif
new file mode 100644
index 0000000..bcdd7df
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.cif
@@ -0,0 +1,22 @@
+<component>
+ name = "IdeSecurity"
+ category = eModule
+ Rank = 31
+ LocalRoot = "Core\EM\HddSecurity\"
+ RefName = "IdeSecurity"
+[files]
+"IdeSecurity.sdl"
+"IdeSecurity.mak"
+"IdeSecurity.h"
+"IdeSecurity.c"
+"IdeSecuritySetup.c"
+"IdeSecurityBdsCall.c"
+"IdeSecurity.sd"
+"IdeSecurity.uni"
+"IdeSecurity.dxs"
+"IdeSecurity.chm"
+"IdeSecurityCommon.sd"
+[parts]
+"IDESMM"
+"AmiTseHddPassword"
+<endComponent>
diff --git a/Core/EM/HddSecurity/IdeSecurity.dxs b/Core/EM/HddSecurity/IdeSecurity.dxs
new file mode 100644
index 0000000..0d3347d
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.dxs
@@ -0,0 +1,86 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.dxs 5 4/06/11 12:53a Rameshr $
+//
+// $Revision: 5 $
+//
+// $Date: 4/06/11 12:53a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.dxs $
+//
+// 5 4/06/11 12:53a Rameshr
+// [TAG]- EIP 57341
+// [Category]-IMPROVEMENT
+// [Description]- Added Support for SMM PI 1.1 in HDDSecurity eModule.
+// [Files]- IdeSecurity.c , IdeSecurity.h, IdeSecurity.dxs
+//
+// 4 2/19/10 12:51p Yul
+// Delete comment out codes
+//
+// 3 1/21/10 12:08p Yul
+// Refer to EIP 33848
+// LegacyBios is not needed here.
+//
+// 2 12/09/09 12:19p Krishnakumarg
+// EIP 31797 : IDE Security API documentation. Added comments whereever
+// possible and modified files for coding standard
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IdeSecurity.DXS
+//
+// Description: Dependency expression for IDESecurity driver.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol/SmmControl2.h>
+#else
+#include <Protocol/SmmControl.h>
+#endif
+
+DEPENDENCY_START
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ EFI_SMM_CONTROL2_PROTOCOL_GUID
+#else
+ EFI_SMM_CONTROL_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSecurity/IdeSecurity.h b/Core/EM/HddSecurity/IdeSecurity.h
new file mode 100644
index 0000000..dbc6a18
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.h
@@ -0,0 +1,470 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.h 13 4/22/15 3:57a Anbuprakashp $
+//
+// $Revision: 13 $
+//
+// $Date: 4/22/15 3:57a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.h $
+//
+// 13 4/22/15 3:57a Anbuprakashp
+// [TAG] EIP212319
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hang while SW_SMI_AHCI_LOCATE_AHCI_SMM SMI trigger
+// after enable SmmChkEn bit
+// [RootCause] Bootservice call used inside IdeSmm driver which causes
+// the Exception
+// [Solution] Changes made not to use BootService calls inside IdeSmm
+// driver
+// [Files] IdeSecurity.h
+// IdeSecurity.c
+// IDESMM.c
+//
+// 12 10/11/11 1:54a Rameshr
+// [TAG] EIP69246
+// [Category] Improvement
+// [Description] Made the SECURITY_SUPPORT as the Master token and
+// removed the IdeSecurity_Support token.
+// [Files] IdeSecurity.c, IdeSecurity.h, IdeSecurity.mak,
+// IdeSecurity.sdl
+//
+// 11 4/06/11 12:53a Rameshr
+// [TAG]- EIP 57341
+// [Category]-IMPROVEMENT
+// [Description]- Added Support for SMM PI 1.1 in HDDSecurity eModule.
+// [Files]- IdeSecurity.c , IdeSecurity.h, IdeSecurity.dxs
+//
+// 10 10/13/10 4:26a Rameshr
+// [TAG] - EIP 43790
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - The IDE_SECURITY_PWNV_GUID in IdeSecurity.h will cause
+// compile failed in some case
+// [RootCause] - The definition of IDE_SECURITY_PWNV_GUID contains a
+// semicolon in the end of line
+// [Solution] - Removed the SemiColon in the end of line
+// [Files] - IdeSecurity.h
+//
+// 9 9/20/10 4:16a Rameshr
+// [TAG]- EIP 44182
+// [Category]-IMPROVEMENT
+// [Description]- Unable to build the project with HDDSecurity module and
+// without AHCI module.
+// [Files]- IdeSecurity.h, IdeSmm.c
+//
+// 8 2/19/10 12:48p Yul
+// Delete the comment out codes.
+//
+// 7 1/21/10 12:07p Yul
+// Refer to EIP 33848
+// LegacyBios protocol is not needed here.
+//
+// 6 1/15/10 10:21a Yul
+// Coding Standard
+//
+// 5 11/25/09 6:03p Krishnakumarg
+// Removed Tab spaces to comply with AMI coding standard.
+//
+// 4 7/14/09 1:55p Pats
+// EIP 22925: Request to set HDD password length by token.
+// Solution: Token added to IdeSecurity.sdl, and definition removed from
+// IdeSecurity.h
+//
+// 3 4/28/09 6:46p Rameshr
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 2 4/11/08 4:28p Rameshraju
+// 1)Enter the Emptry string for the master password, will set the default
+// OEM password and in setup password status will be not installed.
+// 2)If the revision code is not 0, then SecuritySetPassword will use
+// revision code from the input parameters.
+// 3)HddSecutiyData Nvram variable master password cleared when we set
+// user password and user password cleared when we set master password.
+// 4)When we disable the password, HddSecutiyData Nvram variable also
+// updated properly.
+// 5)Password lenght stored in HddSecData structure.
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: <IdeSecurity.h>
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the IdeSecurity driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _IdeSecurity_
+#define _IdeSecurity_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include "Protocol\PAhciBus.h"
+#include <Protocol\ComponentName.h>
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmCommunication.h>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol\SmmControl2.h>
+#else
+#include <Protocol\SmmControl.h>
+#endif
+#if ( defined(AhciSrc_SUPPORT) && (AhciSrc_SUPPORT != 0) )
+#include <Protocol\AhciSmmProtocol.h>
+#endif
+
+#define IDE_SECURITY_PWNV_GUID \
+{ 0x69967a8c, 0x1159, 0x4522, 0xaa, 0x89, 0x74, 0xcd, 0xc6, 0xe5, 0x99, 0xa0}
+
+#define EFI_SMM_SAVE_HDD_PASSWORD_GUID \
+ { 0xeedcf975, 0x4dd3, 0x4d94, 0x96, 0xff, 0xaa, 0xca, 0x83, 0x53, 0xb8, 0x7b }
+
+#define EFI_SMM_REMOVE_HDD_PASSWORD_GUID \
+ { 0xc2b1e795, 0xf9c5, 0x4829, 0x8a, 0x42, 0xc0, 0xb3, 0xfe, 0x57, 0x15, 0x17 }
+
+#define AMI_LOCATE_IDE_AHCI_PROTOCOL_GUID \
+ { 0xb3f096e9, 0x2d46, 0x4e8e, 0xa2, 0x2c, 0x7d, 0xe8, 0xb1, 0x6b, 0x3a, 0x5b }
+
+#define HDD_PWD_ENCRYPTION_KEY "H?p1mA*k920_84o3d^!z@L.x4$kY64"
+
+#define EFI_SEGMENT( _Adr ) (UINT16) ((UINT16) (((UINTN) (_Adr))\
+ >> 4) & 0xf000)
+#define EFI_OFFSET( _Adr ) (UINT16) (((UINT16) ((UINTN) (_Adr))) & 0xffff)
+
+
+//###DEBUG Uncomment the following for Required Debug Level.
+
+//#define TRACE_IDESMM TRACE
+
+//###DEBUG END
+
+#define TRACE_IDESMM
+
+#define ZeroMemory( Buffer, Size ) pBS->SetMem( Buffer, Size, 0 )
+
+// Forward reference for pure ANSI compatability
+typedef struct _IDE_BUS_PROTOCOL IDE_BUS_PROTOCOL;
+
+HDD_SECURITY_INIT_PROTOCOL *gHddSecurityInitProtocol;
+
+EFI_GUID gSaveHddPasswordGuid=EFI_SMM_SAVE_HDD_PASSWORD_GUID;
+EFI_GUID gRemoveHddPasswordGuid=EFI_SMM_REMOVE_HDD_PASSWORD_GUID;
+EFI_GUID gLocateIdeAhciSmmProtocolGuid=AMI_LOCATE_IDE_AHCI_PROTOCOL_GUID;
+EFI_GUID gEfiSmmCommunicationProtocolGuid=EFI_SMM_COMMUNICATION_PROTOCOL_GUID;
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+ UINT8 Controller;
+ UINT32 Reserved;
+} EDD_PCI;
+
+typedef struct
+{
+ UINT16 Base;
+ UINT16 Reserved;
+ UINT32 Reserved2;
+} EDD_LEGACY;
+
+typedef union
+{
+ EDD_PCI Pci;
+ EDD_LEGACY Legacy;
+} EDD_INTERFACE_PATH;
+
+typedef struct
+{
+ UINT8 Master;
+ UINT8 Reserved[15];
+} EDD_ATA;
+
+typedef struct
+{
+ UINT8 Master;
+ UINT8 Lun;
+ UINT8 Reserved[14];
+} EDD_ATAPI;
+
+typedef struct
+{
+ UINT16 TargetId;
+ UINT64 Lun;
+ UINT8 Reserved[6];
+} EDD_SCSI;
+
+typedef struct
+{
+ UINT64 SerialNumber;
+ UINT64 Reserved;
+} EDD_USB;
+
+typedef struct
+{
+ UINT64 Guid;
+ UINT64 Reserved;
+} EDD_1394;
+
+typedef struct
+{
+ UINT64 Wwn;
+ UINT64 Lun;
+} EDD_FIBRE;
+
+typedef struct
+{
+ UINT8 bPortNum;
+ UINT8 Reserved[15];
+} EDD_SATA;
+
+typedef union
+{
+ EDD_ATA Ata;
+ EDD_ATAPI Atapi;
+ EDD_SCSI Scsi;
+ EDD_USB Usb;
+ EDD_1394 FireWire;
+ EDD_FIBRE FibreChannel;
+ EDD_SATA Sata;
+} EDD_DEVICE_PATH;
+
+typedef struct
+{
+ UINT16 StructureSize;
+ UINT16 Flags;
+ UINT32 MaxCylinders;
+ UINT32 MaxHeads;
+ UINT32 SectorsPerTrack;
+ UINT64 PhysicalSectors;
+ UINT16 BytesPerSector;
+ UINT32 FDPT;
+ UINT16 Key;
+ UINT8 DevicePathLength;
+ UINT8 Reserved1;
+ UINT16 Reserved2;
+ CHAR8 HostBusType[4];
+ CHAR8 InterfaceType[8];
+ EDD_INTERFACE_PATH InterfacePath;
+ EDD_DEVICE_PATH DevicePath;
+ UINT8 Reserved3;
+ UINT8 Checksum;
+} EDD_DRIVE_PARAMETERS;
+
+typedef struct _HDDSECDATA
+{
+ UINT16 UserMaster;
+ UINT32 PasswordLength;
+ UINT8 HddUserPassword[IDE_PASSWORD_LENGTH];
+ UINT8 HddMasterPassword[IDE_PASSWORD_LENGTH];
+} HDDSECDATA;
+
+#pragma pack()
+
+
+
+EFI_STATUS InstallSecurityInterface (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS StopSecurityModeSupport (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS ReturnSecurityStatus (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 *SecurityStatus );
+
+EFI_STATUS SecuritySetPassword (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT16 RevisionCode );
+
+EFI_STATUS SecurityUnlockPassword (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer );
+
+EFI_STATUS SecurityDisablePassword (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer );
+
+EFI_STATUS SetDefaultMasterPassword (
+ IN IDE_SECURITY_PROTOCOL *This );
+
+EFI_STATUS SecuritySetDefaultMasterPassword (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT16 RevisionCode );
+
+EFI_STATUS SecurityFreezeLock (
+ IN IDE_SECURITY_PROTOCOL *This );
+
+EFI_STATUS SecurityEraseUnit (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer );
+
+EFI_STATUS ReturnIdePasswordFlags (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT32 *IdePasswordFlags );
+
+EFI_STATUS SecurityCommonRoutine (
+ IN VOID *IdeBusInterface,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT8 SecurityCommand,
+ UINT16 RevisionCode,
+ BOOLEAN ModeFlag );
+
+EFI_STATUS ConnectController (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE*DriverImageHandle OPTIONAL,
+ IN EFI_DEVICE_PATH_PROTOCOL*RemainingDevicePath OPTIONAL,
+ IN BOOLEAN Recursive );
+
+EFI_STATUS GatherIdeInfo (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag,
+ OUT UINT32 *HddDataId );
+
+EFI_STATUS UpdateIdentifyData (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS SetHddSecDataInNvram (
+ IN VOID *BusInterface,
+ UINT32 *HddDataId,
+ UINT16 Control,
+ UINT8 *Buffer );
+
+EFI_STATUS TransferPwDataFromNvramToSmram (
+ IN IDE_SECURITY_PROTOCOL *This );
+
+VOID ConvertHddDataIdToString (
+ IN UINT32 DataId,
+ OUT CHAR16 *String );
+
+VOID EncodeDecodePassword (
+ IN UINT8 *InputString,
+ OUT UINT8 *OutputString,
+ IN UINT32 StringLength );
+
+EFI_STATUS OEMSetMasterPassword (
+ IN IDE_SECURITY_PROTOCOL *This );
+
+EFI_STATUS SmmHDDPasswordInterface (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 Control,
+ UINT8 *Buffer,
+ UINT8 Action );
+
+VOID IdeBusCallbackBootScript (
+ IN EFI_EVENT Event,
+ IN VOID *Context );
+
+VOID IdeBusMiscSmmFeatureCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context );
+
+BOOLEAN CheckAhciMode (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+UINTN EfiValueToString (
+ IN OUT CHAR16 *Buffer,
+ IN INT64 Value,
+ IN UINTN Flags,
+ IN UINTN Width );
+
+EFI_STATUS CommonNonDataHook (
+ IN VOID *BusInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS CommonPioDataHook (
+ IN VOID *BusInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS CommonReadWritePioHook (
+ IN VOID *BusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN ReadWrite,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS CommonWfccHook (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+VOID LocateAhciSmmServiceEvent (
+ EFI_EVENT Event,
+ VOID *Context );
+
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSecurity/IdeSecurity.mak b/Core/EM/HddSecurity/IdeSecurity.mak
new file mode 100644
index 0000000..479a803
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.mak
@@ -0,0 +1,173 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.mak 9 8/11/13 11:58p Srikantakumarp $
+#
+# $Revision: 9 $
+#
+# $Date: 8/11/13 11:58p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.mak $
+#
+# 9 8/11/13 11:58p Srikantakumarp
+# [TAG] EIP123442
+# [Category] Improvement
+# [Description] Create a new Plug-In way in the IdeSecurity Module for
+# OEM append sd file into
+# [Files] IdeSecurity.sdl, IdeSecurity.mak
+#
+# 8 6/06/13 4:04a Rameshr
+# [TAG] EIP106423
+# [Category] Improvement
+# [Description] HddPassword Support in UEFI Raid and Legacy Raid. And
+# also taken care where there is no Conin Device avilable in the post
+# [Files] IdeSecurity.cif,IdeSecurity.sdl,IdeSecurity.mak,IdeSecurityB
+# dsCall.c,HddPassword.c, Ahcibus.c, Pidebus.h
+#
+# 7 4/25/13 9:22a Kapilporwal
+# [TAG] EIP108583
+# [Category] New Feature
+# [Description] support set HDD password in same page
+# [Files] IdeSecurity.cif, IdeSecurity.mak, IdeSecurity.sdl,
+# IdeSecurity.uni, IdeSecurityCommon.sd, IdeSecuritySetup.c,
+# HddPassword.c, HddPassword.h, HddPassword.mak, HddPassword.sdl
+#
+# 6 10/11/11 1:55a Rameshr
+# [TAG] EIP69246
+# [Category] Improvement
+# [Description] Made the SECURITY_SUPPORT as the Master token and
+# removed the IdeSecurity_Support token.
+# [Files] IdeSecurity.c, IdeSecurity.h, IdeSecurity.mak,
+# IdeSecurity.sdl
+#
+# 5 12/03/10 12:24a Rameshr
+# [TAG] - EIP 48770
+# [Category]- BUG FIX
+# [Severity]- Minor
+# [Symptom] - HddSecurity build error when disable the IDEBUS module..
+# [RootCause]- IdebusLib used with IdeSecurity Module.
+# [Solution] - Removed IdebusLib usage from source and mak file.
+# [Files] - Idesecurity.c, IdeSecurity.mak
+#
+# 4 12/09/09 12:17p Krishnakumarg
+# EIP 31797 : IDE Security API documentation. Added comments whereever
+# possible and modified files for coding standard
+#
+# 3 3/18/09 11:26a Fredericko
+# EIP19618 removed dependency on foundation.lib
+#
+# 2 3/13/09 3:43p Fredericko
+#
+# 1 28/02/08 6:40p Anandakrishnanl
+# Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+# IdeBus driver to be compatable with the AHCI Bus driver.
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IdeSecurity_mak
+#
+# Description: Make file to build IDESecurity Driver Sources.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : IdeSecurity
+
+IdeSecurity : $(BUILD_DIR)\IdeSecurity.mak IdeSecurityBin
+
+$(BUILD_DIR)\IdeSecurity.mak : $(IDESECURITY_DIR)\$(@B).cif $(IDESECURITY_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IDESECURITY_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+IdeSecurityBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\IdeSecurity.mak all\
+ GUID=A9B700CF-019E-4d8b-A3A7-88E1EA01699E\
+ ENTRY_POINT=IdeSecurityEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+ "OBJECTS=$(BUILD_DIR)\$(IDESECURITY_DIR)\IdeSecurity.obj"
+
+#---------------------------------------------------------------------------
+# Create IDE Bus Setup Screens
+#---------------------------------------------------------------------------
+SetupSdbs : $(BUILD_DIR)\IdeSecurity.Sdb
+SetupBin : $(BUILD_DIR)\IdeSecuritySetup.obj
+
+#IdeSecuritySdb :
+# $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+# /f $(BUILD_DIR)\IdeSecurity.mak all\
+# MAKEFILE=$(IDESECURITY_DIR)\IdeSecurity.mak \
+# TYPE=SDB STRING_CONSUMERS=$(IDESECURITY_DIR)\IdeSecurity.sd
+#$(BUILD_DIR)\IdeSecuritySetup.obj : $(IDESECURITY_DIR)\IdeSecuritySetup.c $(BUILD_DIR)\SetupStrTokens.h
+# $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(IDESECURITY_DIR)\IdeSecuritySetup.c
+
+!IF (DEFINED(IDE_SECURITY_PLUG_IN) && "$(IDE_SECURITY_PLUG_IN)" == "1")
+
+$(BUILD_DIR)\IdeSecurity.sdb : $(IDESECURITY_PLUG_IN_SD) $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\IdeSecurity.sdb -od $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_PLUG_IN_SD)
+
+!ELSE # !IF (DEFINED(IDE_SECURITY_PLUG_IN) && "$(IDE_SECURITY_PLUG_IN)" == "1")
+
+!IFNDEF "$(SECUITY_SETUP_ON_SAME_PAGE)"
+
+!IF "$(SECUITY_SETUP_ON_SAME_PAGE)" == "1"
+
+$(BUILD_DIR)\IdeSecurity.sdb : $(IDESECURITY_DIR)\IdeSecurityCommon.sd $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\IdeSecurity.sdb -od $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurityCommon.sd
+
+!ELSE
+
+$(BUILD_DIR)\IdeSecurity.sdb : $(IDESECURITY_DIR)\IdeSecurity.sd $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\IdeSecurity.sdb -od $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurity.sd
+
+!ENDIF # !IF SECUITY_SETUP_ON_SAME_PAGE = "1"
+
+!ELSE # !IFNDEF "$(SECUITY_SETUP_ON_SAME_PAGE)"
+
+$(BUILD_DIR)\IdeSecurity.sdb : $(IDESECURITY_DIR)\IdeSecurity.sd $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurity.uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\IdeSecurity.sdb -od $(BUILD_DIR)\IdeSecurity.sdb $(IDESECURITY_DIR)\IdeSecurity.sd
+
+!ENDIF # !IFNDEF SECUITY_SETUP_ON_SAME_PAGE
+
+!ENDIF # !IF (DEFINED(IDE_SECURITY_PLUG_IN) && "$(IDE_SECURITY_PLUG_IN)" == "1")
+
+$(BUILD_DIR)\IdeSecuritySetup.obj : $(IDESECURITY_DIR)\IdeSecuritySetup.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(IDESECURITY_DIR)\IdeSecuritySetup.c
+
+CORE_DXEBin : $(BUILD_DIR)\IdeSecurityBdsCall.obj
+
+$(BUILD_DIR)\IdeSecurityBdsCall.obj : $(IDESECURITY_DIR)\IdeSecurityBdsCall.c
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(IDESECURITY_DIR)\IdeSecurityBdsCall.c
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/HddSecurity/IdeSecurity.sd b/Core/EM/HddSecurity/IdeSecurity.sd
new file mode 100644
index 0000000..47980b5
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.sd
@@ -0,0 +1,525 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.sd 17 1/30/14 9:16a Divyac $
+//
+// $Revision: 17 $
+//
+// $Date: 1/30/14 9:16a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurity.sd $
+//
+// 17 1/30/14 9:16a Divyac
+// [TAG] EIP152490
+// [Category] Improvement
+// [Description] Resolved the build Error in HddSecurity module when
+// enabling DISPLAY_MASTER_PASSWORD sdl token
+// [Files] IdeSecurity.sd
+//
+// 16 12/06/13 8:49a Divyac
+// [TAG] EIP143275
+// [Category] Improvement
+// [Description] Aptio 4.x - Gray out option for the user password when
+// the HDD is in frozen state
+// [Files] IdeSecurity.c, IdeSecurity.uni
+//
+// 15 6/13/12 9:12a Anandakrishnanl
+// [TAG] EIP92050
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] In setup, Hdd Security User and Master password status
+// string displayed as Set or Not Set instead of Installed or Not
+// Installed.
+// [RootCause] In setup, Hdd Security User and Master password status
+// string displayed as Set or Not Set instead of Installed or Not
+// Installed.
+// [Solution] Changed the sd and UNI string tokens to be unique to
+// Module
+// [Files] IdeSecuirty.sd
+// IdeSecuirty.uni
+//
+// 14 1/03/12 1:42a Jittenkumarp
+// [TAG] EIP78274
+// [Category] Bug Fix
+// [Symptom] When the the token ALL_HDD_SAME_PW is set to 1 and no HDD
+// is connected to SUT, Set User Password and Set Master Password links
+// are displayed in security page.
+// [RootCause] When ALL_HDD_SAME_PW token is 1 ,not checking the
+// presence of hard disk.
+// [Solution] When ALL_HDD_SAME_PW token is 1,checking harddisk is
+// present or not and if not present suppress the links.
+// [Files] IdeSecurity.sd
+//
+// 13 10/21/11 4:12a Rameshr
+// [TAG] EIP69247
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Several IdeSecurity.sdl tokens are not working properly
+// [RootCause] Several IdeSecurity.sdl tokens are not working properly
+// [Solution] Removed unwanted SDL token and verified all the SDL token
+// function.
+// [Files] IdeSecurity.c, IdeSecurity.sdl, IdeSecurity.sdl
+//
+// 12 2/01/11 3:48a Rameshr
+// [TAG] - EIP 52221
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Under Aptio4.6.4.1, the HddSecurity "4.6.3_HddSecurity_016"
+// will build failed.
+// [RootCause]- Goto Form error in UEFI2.0
+// [Solution] - Moved Goto Form inside the FormSet.
+// [Files] - IdeSecurity.sd
+//
+// 11 1/20/11 12:22a Rameshr
+// [TAG] - EIP 52221
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Under Aptio4.6.4.1, the HddSecurity "4.6.3_HddSecurity_016"
+// will build failed.
+// [RootCause]- All the Control Items included in the main formset also.
+// [Solution] - moved the whole #ifdef FORM_SET_VARSTORE section outside
+// of the #ifdef SECURITY_FORM_SET
+// [Files] - IdeSecurity.sd
+//
+// 10 1/10/11 12:52a Rameshr
+// [TAG] EIP48180
+// [Category] Improvement
+// [Description] Update the IdeSecurity eModule to utilize Setup
+// Customization
+// [Files] IdeSecurity.sd
+//
+// 8 8/27/10 2:27p Yul
+// [TAG] EIP40151
+// [Category] NEW FEATURE
+// [Description] If system has two HDDs, User need set two HDDs password
+// separately with master and user password.
+// We want to simply the procedure, if user set master or user password,
+// it will set two HDDs with same password.
+// While un-lock the HDD password, user just need input one Master/User
+// password to un-lock HDD.
+// [Files] HddPassword.c
+// HddPassword.sdl
+// IdeSecurity.sd
+// IdeSecurity.uni
+// Same as v7. No code update.
+//
+// 7 8/27/10 10:01a Yul
+// EIP 40151 - One Master/User password for all attach HDDs
+//
+// 6 4/13/10 10:29a Davidd
+// Removed setup questions when SETUP_SAME_SYS_HDD_PW is on. They are not
+// used in this case.
+//
+// 5 3/26/10 5:44p Krishnakumarg
+// UEFI2.1 compliance change. EIP#34744
+//
+// 4 12/09/09 12:18p Krishnakumarg
+// EIP 31797 : IDE Security API documentation. Added comments whereever
+// possible and modified files for coding standard
+//
+// 3 7/27/09 3:30p Pats
+// EIP 22925: Request to set HDD password length by token.
+// Solution: Changed definitions for IDEUserPassword and IDEMasterPassword
+// to use the token value instead of 32.
+//
+//
+// 2 8/12/08 10:30a Fasihm
+// Added the Manufacturing flag to all the setup questions.
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+// 1 10/23/07 4:18p Felixp
+
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+// Name: IdeSecurity.sd
+//
+// Description: Ide Security in Setup.
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#ifdef FORM_SET_VARSTORE
+ varstore IDE_SECURITY_CONFIG,
+ key = IDE_SECURITY_HD_1_KEY_ID,
+ name = IDESecDev,
+ guid = IDE_SECURITY_CONFIG_GUID;
+#endif
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+
+#if (SETUP_SAME_SYS_HDD_PW != 1)
+ #if ALL_HDD_SAME_PW
+ #define IDE_SECURITY_GET_USER_PASSWORD\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ endif;
+ #define IDE_SECURITY_GET_MASTER_PASSWORD\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ endif;
+
+ #define IDE_SECURITY_GET_IDE_USER_PASSWORD
+ #define IDE_SECURITY_GET_IDE_MASTER_PASSWORD
+
+ #else
+ #define IDE_SECURITY_GET_USER_PASSWORD
+ #define IDE_SECURITY_GET_MASTER_PASSWORD
+
+ #define IDE_SECURITY_GET_IDE_USER_PASSWORD\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+
+ #define IDE_SECURITY_GET_IDE_MASTER_PASSWORD\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+
+ #endif
+
+ #define IDE_SECURITY_CONFIG_COUNT\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_HDD_SECURITY_CONFIG),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_SUPPORTED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_SUPPORTED),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_NOT_SUPPORTED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_SUPPORTED),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+
+ #define IDE_SECURITY_CONFIG_ENABLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_ENABLED),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_NOT_ENABLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_ENABLED),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+
+ #define IDE_SECURITY_CONFIG_LOCKED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_LOCKED),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+
+ #define IDE_SECURITY_CONFIG_NOT_LOCKED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_LOCKED),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_FROZEN\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_FROZEN),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_NOT_FROZEN\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_FROZEN),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_USER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_USER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_NOT_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_NOT_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+#else
+
+ #define IDE_SECURITY_GET_USER_PASSWORD
+ #define IDE_SECURITY_GET_MASTER_PASSWORD
+ #define IDE_SECURITY_CONFIG_COUNT
+ #define IDE_SECURITY_CONFIG_SUPPORTED
+ #define IDE_SECURITY_CONFIG_NOT_SUPPORTED
+ #define IDE_SECURITY_CONFIG_ENABLED
+ #define IDE_SECURITY_CONFIG_NOT_ENABLED
+ #define IDE_SECURITY_CONFIG_LOCKED
+ #define IDE_SECURITY_CONFIG_NOT_LOCKED
+ #define IDE_SECURITY_CONFIG_FROZEN
+ #define IDE_SECURITY_CONFIG_NOT_FROZEN
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED
+ #define IDE_SECURITY_GET_IDE_USER_PASSWORD
+ #define IDE_SECURITY_GET_IDE_MASTER_PASSWORD
+#endif
+#endif
+
+
+#ifdef CONTROLS_WITH_DEFAULTS
+ IDE_SECURITY_GET_USER_PASSWORD
+ IDE_SECURITY_GET_MASTER_PASSWORD
+ IDE_SECURITY_CONFIG_COUNT
+ IDE_SECURITY_CONFIG_SUPPORTED
+ IDE_SECURITY_CONFIG_NOT_SUPPORTED
+ IDE_SECURITY_CONFIG_ENABLED
+ IDE_SECURITY_CONFIG_NOT_ENABLED
+ IDE_SECURITY_CONFIG_LOCKED
+ IDE_SECURITY_CONFIG_NOT_LOCKED
+ IDE_SECURITY_CONFIG_FROZEN
+ IDE_SECURITY_CONFIG_NOT_FROZEN
+ IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS
+ IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED
+ IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS
+ IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED
+ IDE_SECURITY_GET_IDE_USER_PASSWORD
+ IDE_SECURITY_GET_IDE_MASTER_PASSWORD
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+#if (SETUP_SAME_SYS_HDD_PW != 1)
+ #ifdef SECURITY_FORM_SET
+
+ #if EFI_SPECIFICATION_VERSION > 0x20000
+ #ifndef SUPPRESS_GRAYOUT_ENDIF //old Core
+ #define SUPPRESS_GRAYOUT_ENDIF endif;
+ #endif
+ #endif
+
+
+ #ifdef FORM_SET_ITEM
+ SEPARATOR
+
+ #if ALL_HDD_SAME_PW
+
+ grayoutif ideqvallist IDE_SECURITY_CONFIG.Frozen == 1;
+ IDE_SECURITY_GET_USER_PASSWORD
+ endif;
+
+ #if DISPLAY_MASTER_PASSWORD
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster == 0 OR ideqval IDE_SECURITY_CONFIG.Frozen == 1;
+ IDE_SECURITY_GET_MASTER_PASSWORD
+ endif;
+ #endif
+ #endif
+ #endif
+
+ #ifdef FORM_SET_GOTO
+ SEPARATOR
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;
+ IDE_SECURITY_CONFIG_COUNT
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0xFFFF;
+ goto IDE_SECURITY_FORM,
+ prompt = STRING_TOKEN(STR_EMPTY),
+ help = STRING_TOKEN(STR_IDE_SECURITY_HELP);
+ endif;
+
+ #endif
+
+ #ifdef FORM_SET_FORM
+
+ form
+ formid = AUTO_ID(IDE_SECURITY_FORM),
+ title = STRING_TOKEN(STR_IDE_SECURITY_HD);
+
+#if !ALL_HDD_SAME_PW
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_PWD_DESC))
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_ONE))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_TWO))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_THREE))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_FOUR))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_FIVE))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_SIX))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_SEVEN))
+ SUBTITLE(STRING_TOKEN(STR_SECURITY_HDD_BANNER_EIGHT))
+
+#endif
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_HDD_PASSWORD_CONFIG))
+ SEPARATOR
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Supported == 0;
+ IDE_SECURITY_CONFIG_SUPPORTED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Supported == 1;
+ IDE_SECURITY_CONFIG_NOT_SUPPORTED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Enabled == 0;
+ IDE_SECURITY_CONFIG_ENABLED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Enabled == 1;
+ IDE_SECURITY_CONFIG_NOT_ENABLED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Locked == 0;
+ IDE_SECURITY_CONFIG_LOCKED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Locked == 1;
+ IDE_SECURITY_CONFIG_NOT_LOCKED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen == 0;
+ IDE_SECURITY_CONFIG_FROZEN
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen == 1;
+ IDE_SECURITY_CONFIG_NOT_FROZEN
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.UserPasswordStatus == 0;
+ IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.UserPasswordStatus == 1;
+ IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.MasterPasswordStatus == 0;
+ IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS
+ endif;
+
+ suppressif ideqvallist IDE_SECURITY_CONFIG.MasterPasswordStatus == 1;
+ IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED
+ endif;
+
+ SEPARATOR
+
+ #if !ALL_HDD_SAME_PW
+ grayoutif ideqvallist IDE_SECURITY_CONFIG.Frozen == 1;
+ IDE_SECURITY_GET_IDE_USER_PASSWORD
+ endif;
+ #if DISPLAY_MASTER_PASSWORD
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster == 0 OR ideqval IDE_SECURITY_CONFIG.Frozen == 1;
+ IDE_SECURITY_GET_IDE_MASTER_PASSWORD
+ endif;
+ #endif
+ #endif
+
+ endform;
+
+ #endif
+ #endif
+#endif
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HddSecurity/IdeSecurity.sdl b/Core/EM/HddSecurity/IdeSecurity.sdl
new file mode 100644
index 0000000..4df0d75
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.sdl
@@ -0,0 +1,240 @@
+TOKEN
+ Name = "HDD_SECURITY_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Hdd Security support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SECURITY_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IdeSecurity support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "HDD_SECURITY_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "MASTER_PASSWORD_ENABLE"
+ Value = "0"
+ Help = "Enables support for Master passwords."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IDE_PASSWORD_LENGTH"
+ Value = "32"
+ Help = "Default maximum IDE password length."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "DISPLAY_MASTER_PASSWORD"
+ Value = "0"
+ Help = "Displays Master Password in the Setup Security Page"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OEM_MASTER_PASSWORD_TAG"
+ Help = "Tag Contains the Default Password String provided by OEM to set as Master Password"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OEM_DEFAULT_MASTER_PASSWORD"
+ Value = "0"
+ Help = "OFF - (Default) Master Password is set by the user through Setup Interface \ ON - Master Password for all HDDs are set from the OEM_MASTER_PASSWORD_TAG which contains the string provided by the OEM.(Only Applicable when DISPLAY_MASTER_PASSWORD is Disabled)"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_MASTER_PASSWORD_REVISION"
+ Value = "0xFFFE"
+ Help = "Master password revision code to be used as default.\0000h/0FFFFh - Not supported "
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DISABLED_MASTER_PASSWORD_REVISION"
+ Value = "0x1"
+ Help = "Disabled Master password revision code to be set.\0000h/0FFFFh - Not supported "
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_MASTER_PASSWORD_TAG"
+ Value = "amim"
+ Help = "Tag Contains the Default Password String provided by OEM to set as Master Password when disabled"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MASTER_PASSWORD_REVISION_SWITCH"
+ Value = "0"
+ Help = "0 - (Default) Use DEFAULT_MASTER_PASSWORD_REVISION as Revision Code.\ 1 - Set Master Password Revision Code from CHANGED_MASTER_PASSWORD_REVISION value\ 2 - Increment Master Revision Code if Set Everytime\"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CHANGED_MASTER_PASSWORD_REVISION"
+ Value = "0xFFFE"
+ Help = "Changed Master password revision code to be set.\0000h/0FFFFh - Not supported "
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DISABLE_SOFT_SET_PREV"
+ Value = "0"
+ Help = "ON - Disable SATA Software Setting Preservation feature so that it will not preserve the state after hardware reset. i.e. After a hardware reset HDD will change security state as power-on.\OFF - Do not change it in POST, leave it as default (enabled)."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DSSP"
+ Value = "$(DISABLE_SOFT_SET_PREV)"
+ TokenType = Integer
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "FORCE_HDD_PASSWORD_PROMPT"
+ Value = "0"
+ Help = "Set to 1 to always prompt for HDD password (in AHCI mode)."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HDD_PASSWORD_ON_NVRAM"
+ Value = "0"
+ Help = "Save the Hdd Password on Nvram."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SECUITY_SETUP_ON_SAME_PAGE"
+ Value = "0"
+ Help = "Multiple HDD Security setting displayed on same page. To enable this token, AMITSE Source should be present in the project."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "FHPP"
+ Value = "$(FORCE_HDD_PASSWORD_PROMPT)"
+ TokenType = Integer
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "IDE_SECURITY_PLUG_IN"
+ Value = "0"
+ Help = "If this token value is 1, OEM .sd file will be added. Default value should be 0"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "IDESECURITY_DIR"
+End
+
+MODULE
+ Help = "Includes IdeSecurity.mak to Project"
+ File = "IdeSecurity.mak"
+End
+
+ELINK
+ Name = "IDESECURITY_PLUG_IN_SD"
+ Help = "List of SD files of the IdeSecurity plug-ins"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IdeSecurity.sdb"
+ Parent = "SETUP_SDBS"
+ Token = "HDD_SECURITY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InitIdeSecurityStrings,"
+ Parent = "SetupStringInit"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDESECURITY_DIR)\IdeSecurity.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Token = "HDD_SECURITY_SUPPORT" "=" "1"
+ Token = "SECUITY_SETUP_ON_SAME_PAGE" "=" "0"
+ Token = "IDE_SECURITY_PLUG_IN" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDESECURITY_DIR)\IdeSecurityCommon.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Token = "SECURITY_SUPPORT" "=" "1"
+ Token = "SECUITY_SETUP_ON_SAME_PAGE" "=" "1"
+ Token = "IDE_SECURITY_PLUG_IN" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDESECURITY_PLUG_IN_SD)"
+ Parent = "SETUP_DEFINITIONS"
+ Token = "HDD_SECURITY_SUPPORT" "=" "1"
+ Token = "IDE_SECURITY_PLUG_IN" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDESECURITY_DIR)\IdeSecurity$(ARCH).ffs"
+ Parent = "FV_MAIN"
+ Token = "HDD_SECURITY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IdeSecurity.ffs"
+ Parent = "$(IDESECURITY_DIR)\IdeSecurity$(ARCH).ffs"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "IdeConnectControllerAfterConnectEverthing,"
+ Parent = "InitConVars,"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/HddSecurity/IdeSecurity.uni b/Core/EM/HddSecurity/IdeSecurity.uni
new file mode 100644
index 0000000..eb9d0ad
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurity.uni
Binary files differ
diff --git a/Core/EM/HddSecurity/IdeSecurityBdsCall.c b/Core/EM/HddSecurity/IdeSecurityBdsCall.c
new file mode 100644
index 0000000..7aaf8bc
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurityBdsCall.c
@@ -0,0 +1,261 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurityBdsCall.c 2 6/09/14 9:53a Anbuprakashp $
+//
+// $Revision: 2 $
+//
+// $Date: 6/09/14 9:53a $
+//
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurityBdsCall.c $
+//
+// 2 6/09/14 9:53a Anbuprakashp
+// [TAG] EIP 172443
+// [Category] Improvement
+// [Description] "RaidDriverBlockingStatus" is using
+// gEfiGlobalVariableGuid that violates UEFI 2.4 spec in
+// IdeSecurityBdsCall.c and Runtime attribute set of this variable need to
+// be removed
+// [Files] IdeSecurityBdsCall.c, AhciBus.c
+//
+// 1 6/06/13 4:03a Rameshr
+// [TAG] EIP106423
+// [Category] Improvement
+// [Description] HddPassword Support in UEFI Raid and Legacy Raid. And
+// also taken care where there is no Conin Device avilable in the post
+// [Files] IdeSecurity.cif
+// IdeSecurity.sdl
+// IdeSecurity.mak
+// IdeSecurity.h
+// IdeSecurity.c
+// IdeSecuritySetup.c
+// IdeSecurityBdsCall.c
+// IdeSecurity.sd
+// IdeSecurity.uni
+// IdeSecurity.dxs
+// IdeSecurity.chm
+//
+//
+//*************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IdeSecurityBdsCall.c
+//
+// Description: This function will connect the handle's of RAID Controllers and
+// the IDE/AHCI Devices( the handle whose DiskIo was not opened by any one.)
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include <PCI.h>
+#include "Protocol\DiskIo.h"
+#include <Protocol\IdeControllerInit.h>
+#include <AmiDxeLib.h>
+#include <Protocol\DevicePath.h>
+
+static EFI_GUID gAmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+
+
+extern EFI_STATUS GetPciHandlesByClass(
+ UINT8 Class, UINT8 SubClass, UINTN *NumberOfHandles, EFI_HANDLE **HandleBuffer
+);
+
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IdeConnectControllerAfterConnectEverthing
+//
+// Description:
+// This function will connect the handle's of RAID Controllers and the IDE/AHCI
+// Devices( the handle whose DiskIo was not opened by any one.)
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+//
+// Notes:
+// If Conin Devices are not Present, RAID Option ROM will not be launched
+// by CSM BlockIo as RegisterHddNotification fucntion would get control after
+// connectEverything() is called from BDS. Rather it would be launched by
+// ShadowAllLegacyOproms() and UEFI Boot option for RAID will not be formed as
+// blockIo will not be installed by csm BlockIo driver. So Connect the RAID handle
+// so that CSM BlockIo starts. And also if Password is installed the above said case
+// will happen when no con in device is present.
+//
+// Check for any device in IDE/AHCI mode not unlocked when no ConIn Device is not present.
+// If found Connecting that Device using ConnectController() after the Device is unlocked.
+// as read would fail and FileSystem would not be formedOpen gEfiIdeControllerInitProtocolGuid
+// which will be installed on each controller. This will be opened as
+// EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER by each device handle.Connect that Handle where
+// DiskIo will be installed and not opened by another driver.
+//
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID IdeConnectControllerAfterConnectEverthing( )
+{
+
+ UINT8 Index;
+ UINT8 Index1;
+ UINTN DiskIoCount;
+ UINTN Count;
+ UINTN Count1;
+ EFI_HANDLE *HandleBuffer = NULL;
+ UINTN NumHandles;
+ EFI_STATUS Status;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *DiskIoEntries = NULL;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *Entries = NULL;
+ BOOLEAN RaidDriverBlocked=FALSE;
+ UINTN VarSize=sizeof(RaidDriverBlocked);
+
+
+
+ // If Conin Devices are not Present, RAID Option ROM will not be launched
+ // by CSM BlockIo as RegisterHddNotification fucntion would get control after
+ // connectEverything() is called from BDS. Rather it would be launched by
+ // ShadowAllLegacyOproms() and UEFI Boot option for RAID will not be formed as
+ // blockIo will not be installed by csm BlockIo driver. So Connect the RAID handle
+ // so that CSM BlockIo starts. And also if Password is installed the above said case
+ // will happen when no con in device is present.
+
+ Status = GetPciHandlesByClass(PCI_CL_MASS_STOR,
+ PCI_CL_MASS_STOR_SCL_RAID,
+ &NumHandles,
+ &HandleBuffer
+ );
+
+ // Connect the handle so that CSM BlockIo Launches RAID Option Rom.
+ if(!EFI_ERROR(Status)){
+
+ Status = pRS->GetVariable( L"RaidDriverBlockingStatus",
+ &gAmiGlobalVariableGuid,
+ NULL,
+ &VarSize,
+ &RaidDriverBlocked );
+
+
+ if((EFI_ERROR(Status)) || (RaidDriverBlocked == FALSE)) {
+ return;
+ }
+
+ for(Index=0; Index<NumHandles; Index++){
+
+ // We have blocked the Raid driver until password verification is done.
+ // Now we need to un block and connect the Raid driver after HddPassword verification is done
+ Status = pBS->OpenProtocolInformation(HandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ &Entries,
+ &Count1
+ );
+
+ if(!EFI_ERROR(Status)) {
+ for(Index1=0; Index1 < Count1; Index1++) {
+ if (Entries[Index1].Attributes!=EFI_OPEN_PROTOCOL_BY_DRIVER) {
+ continue;
+ }
+
+ Status = pBS->CloseProtocol (
+ HandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ Entries[Index1].AgentHandle,
+ Entries[Index1].ControllerHandle
+ );
+ }
+ }
+
+ pBS->ConnectController(HandleBuffer[Index],NULL,NULL,TRUE);
+ }
+
+ } else {
+
+ // Check for any device in IDE/AHCI mode not unlocked when no ConIn Device is not present.
+ // If found Connecting that Device using ConnectController() after the Device is unlocked.
+ // Open gEfiIdeControllerInitProtocolGuid which will be installed on each controller.
+ // This will be opened as EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER by each device handle.
+ // Connect that Handle where DiskIo will be installed and not opened by another driver.
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiIdeControllerInitProtocolGuid,
+ NULL,
+ &Count,
+ &HandleBuffer);
+
+ if(!EFI_ERROR(Status)){
+ for(Index=0; Index < Count; Index++) {
+ Status = pBS->OpenProtocolInformation(HandleBuffer[Index],
+ &gEfiIdeControllerInitProtocolGuid,
+ &Entries,
+ &Count1
+ );
+ if(!EFI_ERROR(Status)) {
+ for(Index1=0; Index1 < Count1; Index1++) {
+ if (Entries[Index1].Attributes!=EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {
+ continue;
+ }
+ Status = pBS->OpenProtocolInformation(Entries[Index1].ControllerHandle,
+ &gEfiDiskIoProtocolGuid,
+ &DiskIoEntries,
+ &DiskIoCount
+ );
+ if(!EFI_ERROR(Status)) {
+ if( DiskIoCount == 0 ) {
+ Status = pBS->ConnectController(Entries[Index1].ControllerHandle,
+ NULL,
+ NULL,
+ TRUE);
+ }
+ pBS->FreePool(DiskIoEntries);
+ }
+ }
+ pBS->FreePool(Entries);
+ }
+ }
+ }
+ }
+
+ if(HandleBuffer) {
+ pBS->FreePool(HandleBuffer);
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSecurity/IdeSecurityCommon.sd b/Core/EM/HddSecurity/IdeSecurityCommon.sd
new file mode 100644
index 0000000..f30be83
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecurityCommon.sd
@@ -0,0 +1,653 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurityCommon.sd 1 4/25/13 9:21a Kapilporwal $
+//
+// $Revision: 1 $
+//
+// $Date: 4/25/13 9:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecurityCommon.sd $
+//
+// 1 4/25/13 9:21a Kapilporwal
+// [TAG] EIP108583
+// [Category] New Feature
+// [Description] support set HDD password in same page
+// [Files] IdeSecurity.cif, IdeSecurity.mak, IdeSecurity.sdl,
+// IdeSecurity.uni, IdeSecurityCommon.sd, IdeSecuritySetup.c,
+// HddPassword.c, HddPassword.h, HddPassword.mak, HddPassword.sdl
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+// Name: IdeSecurityCommon.sd
+//
+// Description: Ide Security in Setup.
+//**********************************************************************
+//<AMI_FHDR_END>
+
+
+#ifdef FORM_SET_VARSTORE
+ varstore IDE_SECURITY_CONFIG,
+ key = IDE_SECURITY_HD_1_KEY_ID,
+ name = IDESecDev,
+ guid = IDE_SECURITY_CONFIG_GUID;
+#endif // end of FORM_SET_VARSTORE
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+
+ #define IDE_SECURITY_DUMMY_DEFINITION\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_SECURITY_PROMPT),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_HDD_NAME1\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SECURITY_HDD_ONE),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_HDD_NAME2\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SECURITY_HDD_TWO),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_HDD_NAME3\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SECURITY_HDD_THREE),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_HDD_NAME4\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SECURITY_HDD_FOUR),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_HDD_NAME5\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SECURITY_HDD_FIVE),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_HDD_NAME6\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SECURITY_HDD_SIX),\
+ text = STRING_TOKEN(STR_EMPTY),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_SUPPORTED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_SUPPORTED),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_NOT_SUPPORTED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_SUPPORTED),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+
+ #define IDE_SECURITY_CONFIG_ENABLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_ENABLED),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_NOT_ENABLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_ENABLED),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+
+ #define IDE_SECURITY_CONFIG_LOCKED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_LOCKED),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+
+ #define IDE_SECURITY_CONFIG_NOT_LOCKED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_LOCKED),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_FROZEN\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_FROZEN),\
+ text = STRING_TOKEN(STR_YES),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_NOT_FROZEN\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_SEC_FROZEN),\
+ text = STRING_TOKEN(STR_NO),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_USER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_USER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_NOT_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED\
+ text\
+ help = STRING_TOKEN(STR_EMPTY),\
+ text = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_STS),\
+ text = STRING_TOKEN(STR_NOT_HDDS_INSTALLED),\
+ flags = 0,\
+ key = 0;\
+
+ #define IDE_SECURITY_NONSUPPORTED_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Supported[HDD_NUM] == 0;\
+ IDE_SECURITY_CONFIG_SUPPORTED\
+ endif;
+
+ #define IDE_SECURITY_SUPPORTED_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Supported[HDD_NUM] == 1;\
+ IDE_SECURITY_CONFIG_NOT_SUPPORTED\
+ endif;
+
+ #define IDE_SECURITY_NONENABLED_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Enabled[HDD_NUM] == 0;\
+ IDE_SECURITY_CONFIG_ENABLED\
+ endif;
+
+ #define IDE_SECURITY_ENABLED_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Enabled[HDD_NUM] == 1;\
+ IDE_SECURITY_CONFIG_NOT_ENABLED\
+ endif;
+
+
+ #define IDE_SECURITY_NONLOCKED_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Locked[HDD_NUM] == 0;\
+ IDE_SECURITY_CONFIG_LOCKED\
+ endif;
+
+ #define IDE_SECURITY_LOCKED_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Locked[HDD_NUM] == 1;\
+ IDE_SECURITY_CONFIG_NOT_LOCKED\
+ endif;\
+
+ #define IDE_SECURITY_NONFROZEN_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 0;\
+ IDE_SECURITY_CONFIG_FROZEN\
+ endif;\
+
+ #define IDE_SECURITY_FROZEN_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ IDE_SECURITY_CONFIG_NOT_FROZEN\
+ endif;\
+
+ #define IDE_SECURITY_USERPASSWORD_NONSTATUS_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.UserPasswordStatus[HDD_NUM] == 0;\
+ IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS\
+ endif;\
+
+ #define IDE_SECURITY_USERPASSWORD_STATUS_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.UserPasswordStatus[HDD_NUM] == 1;\
+ IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED\
+ endif;
+
+ #define IDE_SECURITY_MASTERPASSWORD_NONSTATUS_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.MasterPasswordStatus[HDD_NUM] == 0;\
+ IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS\
+ endif;
+
+
+ #define IDE_SECURITY_MASTERPASSWORD_STATUS_FEATURES(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.MasterPasswordStatus[HDD_NUM] == 1;\
+ IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED\
+ endif;
+
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES1(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF
+
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES1(HDD_NUM)\
+ suppressif ideqval IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster[HDD_NUM] == 0;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF\
+ endif;
+
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES2(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword_HDD2,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF
+
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES2(HDD_NUM)\
+ suppressif ideqval IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster[HDD_NUM] == 0;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword_HDD2,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF\
+ endif;
+
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES3(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword_HDD3,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF
+
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES3(HDD_NUM)\
+ suppressif ideqval IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster[HDD_NUM] == 0;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword_HDD3,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF\
+ endif;
+
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES4(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword_HDD4,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF
+
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES4(HDD_NUM)\
+ suppressif ideqval IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster[HDD_NUM] == 0;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword_HDD4,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF\
+ endif;
+
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES5(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword_HDD5,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF
+
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES5(HDD_NUM)\
+ suppressif ideqval IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster[HDD_NUM] == 0;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword_HDD5,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF\
+ endif;
+
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES6(HDD_NUM)\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEUserPassword_HDD6,\
+ prompt = STRING_TOKEN(STR_IDE_USER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_USER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF
+
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES6(HDD_NUM)\
+ suppressif ideqval IDE_SECURITY_CONFIG.Frozen[HDD_NUM] == 1;\
+ grayoutif ideqval IDE_SECURITY_CONFIG.ShowMaster[HDD_NUM] == 0;\
+ suppressif ideqvallist IDE_SECURITY_CONFIG.Count == 0;\
+ password varid = IDE_SECURITY_CONFIG.IDEMasterPassword_HDD6,\
+ prompt = STRING_TOKEN(STR_IDE_MASTER_PASSWORD),\
+ help = STRING_TOKEN(STR_IDE_MASTER_PASSWORD_HELP),\
+ flags = 0,\
+ key = 0,\
+ minsize = 0,\
+ maxsize = IDE_PASSWORD_LENGTH,\
+ encoding = 1,\
+ endpassword;\
+ SUPPRESS_GRAYOUT_ENDIF\
+ endif;
+
+ #define IDE_SECURITY_FEATURES(HDD_NUM)\
+ IDE_SECURITY_NONSUPPORTED_FEATURES(HDD_NUM)\
+ IDE_SECURITY_SUPPORTED_FEATURES(HDD_NUM)\
+ IDE_SECURITY_NONENABLED_FEATURES(HDD_NUM)\
+ IDE_SECURITY_ENABLED_FEATURES(HDD_NUM)\
+ IDE_SECURITY_NONLOCKED_FEATURES(HDD_NUM)\
+ IDE_SECURITY_LOCKED_FEATURES(HDD_NUM)\
+ IDE_SECURITY_NONFROZEN_FEATURES(HDD_NUM)\
+ IDE_SECURITY_FROZEN_FEATURES(HDD_NUM)\
+ IDE_SECURITY_USERPASSWORD_NONSTATUS_FEATURES(HDD_NUM)\
+ IDE_SECURITY_USERPASSWORD_STATUS_FEATURES(HDD_NUM)\
+ IDE_SECURITY_MASTERPASSWORD_NONSTATUS_FEATURES(HDD_NUM)\
+ IDE_SECURITY_MASTERPASSWORD_STATUS_FEATURES(HDD_NUM)
+#endif
+
+#ifdef CONTROLS_WITH_DEFAULTS
+ #define IDE_SECURITY_HDD_NAME1
+ #define IDE_SECURITY_HDD_NAME2
+ #define IDE_SECURITY_HDD_NAME3
+ #define IDE_SECURITY_HDD_NAME4
+ #define IDE_SECURITY_HDD_NAME5
+ #define IDE_SECURITY_HDD_NAME6
+ #define IDE_SECURITY_CONFIG_SUPPORTED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_NOT_SUPPORTED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_ENABLED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_NOT_ENABLED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_LOCKED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_NOT_LOCKED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_FROZEN(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_NOT_FROZEN(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_USER_PASSWORD_STATUS_NOT_INSTALLED(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS(HDD_NUM)
+ #define IDE_SECURITY_CONFIG_MASTER_PASSWORD_STATUS_NOT_INSTALLED(HDD_NUM)
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES1(HDD_NUM)
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES1(HDD_NUM)
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES2(HDD_NUM)
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES2(HDD_NUM)
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES3(HDD_NUM)
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES3(HDD_NUM)
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES4(HDD_NUM)
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES4(HDD_NUM)
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES5(HDD_NUM)
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES5(HDD_NUM)
+ #define IDE_SECURITY_GET_USERPASSWORD_FEATURES6(HDD_NUM)
+ #define IDE_SECURITY_GET_MASTERPASSWORD_FEATURES6(HDD_NUM)
+ #define IDE_SECURITY_FEATURES(HDD_NUM)
+#endif
+
+#ifdef SECURITY_FORM_SET
+ #ifdef FORM_SET_ITEM
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 1 2 3 4 5 6;
+ SEPARATOR
+ SEPARATOR
+ endif;
+ #endif
+
+
+ #ifdef FORM_SET_GOTO
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 1 2 3 4 5 6;
+ goto HDD_PASSWORD_FORM_ID,
+ prompt = STRING_TOKEN(STR_HDD_SECURITY_CONFIG),
+ help = STRING_TOKEN(STR_IDE_SECURITY_HELP);
+ endif;
+ #endif// end of FORM_SET_GOTO
+
+ #ifdef FORM_SET_FORM
+ //
+ // Define forms
+ //
+ form formid = AUTO_ID(HDD_PASSWORD_FORM_ID),
+ title = STRING_TOKEN(STR_HDD_SECURITY_CONFIG);
+
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_HDD_PASSWORD_CONFIG))
+ SEPARATOR
+
+
+ //******************************************
+ //*************** HDD 1nd ******************
+ //******************************************
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 1 2 3 4 5 6;
+ IDE_SECURITY_HDD_NAME1
+ endif;
+
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 1 2 3 4 5 6;
+ IDE_SECURITY_FEATURES(0)
+ IDE_SECURITY_GET_USERPASSWORD_FEATURES1(0)
+ #if DISPLAY_MASTER_PASSWORD
+ IDE_SECURITY_GET_MASTERPASSWORD_FEATURES1(0)
+ #endif
+ SEPARATOR
+ SEPARATOR
+ endif;
+
+
+ //******************************************
+ //*************** HDD 2nd ******************
+ //******************************************
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 2 3 4 5 6;
+ IDE_SECURITY_HDD_NAME2
+ endif;
+
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 2 3 4 5 6;
+ IDE_SECURITY_FEATURES(1)
+ IDE_SECURITY_GET_USERPASSWORD_FEATURES2(1)
+ #if DISPLAY_MASTER_PASSWORD
+ IDE_SECURITY_GET_MASTERPASSWORD_FEATURES2(1)
+ #endif
+ SEPARATOR
+ SEPARATOR
+ endif;
+
+ //******************************************
+ //*************** HDD 3rd ******************
+ //******************************************
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 3 4 5 6;
+ IDE_SECURITY_HDD_NAME3
+ endif;
+
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 3 4 5 6;
+ IDE_SECURITY_FEATURES(2)
+ IDE_SECURITY_GET_USERPASSWORD_FEATURES3(2)
+ #if DISPLAY_MASTER_PASSWORD
+ IDE_SECURITY_GET_MASTERPASSWORD_FEATURES3(2)
+ #endif
+ SEPARATOR
+ SEPARATOR
+ endif;
+
+ //******************************************
+ //*************** HDD 4th ******************
+ //******************************************
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 4 5 6;
+ IDE_SECURITY_HDD_NAME4
+ endif;
+
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 4 5 6;
+ IDE_SECURITY_FEATURES(3)
+ IDE_SECURITY_GET_USERPASSWORD_FEATURES4(3)
+ #if DISPLAY_MASTER_PASSWORD
+ IDE_SECURITY_GET_MASTERPASSWORD_FEATURES4(3)
+ #endif
+ SEPARATOR
+ SEPARATOR
+ endif;
+
+ //******************************************
+ //*************** HDD 5th ******************
+ //******************************************
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 5 6;
+ IDE_SECURITY_HDD_NAME5
+ endif;
+
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 5 6;
+ IDE_SECURITY_FEATURES(4)
+ IDE_SECURITY_GET_USERPASSWORD_FEATURES5(4)
+ #if DISPLAY_MASTER_PASSWORD
+ IDE_SECURITY_GET_MASTERPASSWORD_FEATURES5(4)
+ #endif
+ SEPARATOR
+ SEPARATOR
+ endif;
+
+ //******************************************
+ //*************** HDD 6th ******************
+ //******************************************
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 6;
+ IDE_SECURITY_HDD_NAME6
+ endif;
+
+ suppressif NOT ideqvallist IDE_SECURITY_CONFIG.Count == 6;
+ IDE_SECURITY_FEATURES(5)
+ IDE_SECURITY_GET_USERPASSWORD_FEATURES6(5)
+ #if DISPLAY_MASTER_PASSWORD
+ IDE_SECURITY_GET_MASTERPASSWORD_FEATURES6(5)
+ #endif
+ SEPARATOR
+ SEPARATOR
+ endif;
+
+ endform;
+ #endif // FORM_SET_FORM
+#endif // SECURITY_FORM_SET
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HddSecurity/IdeSecuritySetup.c b/Core/EM/HddSecurity/IdeSecuritySetup.c
new file mode 100644
index 0000000..ba1f57b
--- /dev/null
+++ b/Core/EM/HddSecurity/IdeSecuritySetup.c
@@ -0,0 +1,434 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSecurity/IdeSecuritySetup.c 4 4/25/13 9:22a Kapilporwal $
+//
+// $Revision: 4 $
+//
+// $Date: 4/25/13 9:22a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSecurity/IdeSecuritySetup.c $
+//
+// 4 4/25/13 9:22a Kapilporwal
+// [TAG] EIP108583
+// [Category] New Feature
+// [Description] support set HDD password in same page
+// [Files] IdeSecurity.cif, IdeSecurity.mak, IdeSecurity.sdl,
+// IdeSecurity.uni, IdeSecurityCommon.sd, IdeSecuritySetup.c,
+// HddPassword.c, HddPassword.h, HddPassword.mak, HddPassword.sdl
+//
+// 3 1/15/10 10:22a Yul
+// Coding Standard
+//
+// 2 12/09/09 12:18p Krishnakumarg
+// EIP 31797 : IDE Security API documentation. Added comments whereever
+// possible and modified files for coding standard
+//
+// 1 28/02/08 6:40p Anandakrishnanl
+// Created new HddSecurity module. Isolated IdeSecurity and IdeSmm from
+// IdeBus driver to be compatable with the AHCI Bus driver.
+//
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IdeSecuritySetup.c
+//
+// Description: Ide Security Setup Routines
+//
+// NOTE: Use this hook to dynamically change Ide Security Driver Setup screen
+// Strings.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+#include "Protocol\PciIo.h"
+#include "Protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include "Protocol\PAhciBus.h"
+#include "Protocol\DevicePath.h"
+#include "Protocol\HiiString.h"
+#endif
+
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+
+EFI_GUID gDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+EFI_GUID gIDESecurityProtocolGuid = IDE_SECURITY_INTERFACE_GUID;
+
+// Store the names of HDDs present in the system. Dynamically updated.
+STRING_REF gHddSecurityName[6] =
+{
+ STRING_TOKEN(STR_SECURITY_HDD_ONE), STRING_TOKEN(STR_SECURITY_HDD_TWO),
+ STRING_TOKEN(STR_SECURITY_HDD_THREE), STRING_TOKEN(STR_SECURITY_HDD_FOUR),
+ STRING_TOKEN(STR_SECURITY_HDD_FIVE), STRING_TOKEN(STR_SECURITY_HDD_SIX)
+};
+
+static EFI_HII_STRING_PROTOCOL *HiiString = NULL;
+static EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckSecurityStatus
+//
+// Description: return the Security Status Information
+//
+// Input: IN IDE_SECURITY_PROTOCOL *IDEPasswordSecurity,
+// IN OUT BOOLEAN *ReqStatus,
+// IN UINT16 Mask
+//
+// Output: BOOLEAN status in ReqStatus is valid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckSecurityStatus(
+ IN IDE_SECURITY_PROTOCOL *IDEPasswordSecurity,
+ IN OUT BOOLEAN *ReqStatus,
+ IN UINT16 Mask )
+{
+ UINT16 SecurityStatus = 0;
+ EFI_STATUS Status;
+
+ //
+ //get the security status of the device
+ //
+ Status = IDEPasswordSecurity->ReturnSecurityStatus( IDEPasswordSecurity, &SecurityStatus );
+
+ if ( EFI_ERROR( Status ))
+ return FALSE; // Unable to get IDE security status
+ // Mask security status based on supplied mask data
+ *ReqStatus = (BOOLEAN)((SecurityStatus & Mask) ? TRUE : FALSE );
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HiiGetString
+//
+// Description: return the String based on StringId
+//
+// Input: IN EFI_HII_HANDLE HiiHandle,
+// IN EFI_STRING_ID StringId,
+//
+// Output: EFI_STRING
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STRING HiiGetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN EFI_STRING_ID StringId)
+{
+ EFI_STRING String = NULL;
+ UINTN StringSize = 0;
+ EFI_STATUS Status;
+ CHAR8* PlatformLang = NULL;
+ UINTN Size = 0;
+
+ if(HiiString == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
+ if(EFI_ERROR(Status))
+ return NULL;
+ }
+
+//language not provided - try platform language
+ Status = GetEfiVariable(L"PlatformLang", &EfiVariableGuid, NULL, &Size, &PlatformLang);
+ if(!EFI_ERROR(Status)) {
+ Status = HiiString->GetString(HiiString, PlatformLang, HiiHandle, StringId, String, &StringSize, NULL);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, StringSize, &String);
+ if(!EFI_ERROR(Status))
+ Status = HiiString->GetString(HiiString, PlatformLang, HiiHandle, StringId, String, &StringSize, NULL);
+ }
+ pBS->FreePool(PlatformLang);
+ }
+ return (EFI_ERROR(Status)) ? NULL : String;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HddPasswordGetDeviceName
+//
+// Description: Return the Drive String Name
+//
+// Input: IN EFI_HANDLE Controller - the handle of the drive
+// OUT CHAR16 **wsName - Pointer to the drive string
+//
+// Output: BOOLEAN - TRUE - drive string has been found and is in wsName
+// - FALSE - drive string has not been found
+//
+// Notes: it is the caller's responsibility to deallocate the space used for
+// wsName
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN HddPasswordGetDeviceName(IN EFI_HANDLE Controller, OUT CHAR16 **wsName)
+{
+ EFI_STATUS Status;
+ SECURITY_PROTOCOL *Security = NULL;
+ CHAR16 *DeviceName;
+ BOOLEAN ReturnStatus = FALSE;
+
+ // Get the SECURITY_PROTOCOL (actually getting the IDE_SECURITY_PROTOCOL, but
+ // the SECURITY_PROTOCOL is an extended version with more information)
+ Status = pBS->HandleProtocol(Controller, &gIDESecurityProtocolGuid, &Security);
+ if ( !EFI_ERROR(Status) ) {
+ // Check the SATA controller operating mode, and based on the mode, get the UnicodeString
+ // name of the device
+ if ( Security->ModeFlag ) {
+ DeviceName = ((SATA_DEVICE_INTERFACE*)Security->BusInterface)->UDeviceName->UnicodeString;
+ } else {
+ DeviceName = ((IDE_BUS_PROTOCOL*)Security->BusInterface)->IdeDevice.UDeviceName->UnicodeString;
+ }
+
+ // Allocate space to copy the unicode device name string
+ *wsName = MallocZ(sizeof(CHAR16)*(Wcslen(DeviceName)+1));
+ if ( *wsName!=NULL ) {
+ Wcscpy( *wsName, DeviceName);
+ ReturnStatus = TRUE;
+ }
+ }
+
+ // Return true to signify that a device name was discovered
+ return ReturnStatus;
+}
+
+#endif
+
+// Function Definitions
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitIdeSecurityStrings
+//
+// Description: This function initializes the IdeSecurity setup option values
+//
+// Input: HiiHandle Handle to HII database
+// Class Indicates the setup class
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitIdeSecurityStrings(
+ EFI_HII_HANDLE HiiHandle,
+ UINT16 Class )
+{
+#if defined(SECUITY_SETUP_ON_SAME_PAGE) && SECUITY_SETUP_ON_SAME_PAGE
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer = NULL;
+ UINT16 i, HDDCount = 0;
+ UINTN Count;
+ CHAR16 * Name, *Temp1;
+ BOOLEAN Locked;
+ IDE_SECURITY_PROTOCOL *IDEPasswordSecurity = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ PCI_DEVICE_PATH *PciDevicePath;
+ SECURITY_PROTOCOL *Security = NULL;
+ UINT32 HddPortNumber;
+ CHAR16 *Buff=L"P";
+ EFI_DISK_INFO_PROTOCOL *DiskInfoPtr=NULL;
+ UINT32 PortNumber;
+ UINT32 PMPortNumber;
+ BOOLEAN Flag = FALSE;
+
+ // Locate all handles with IDE_SECURITY_PROTOCOL installled
+ Status = pBS->LocateHandleBuffer( ByProtocol,
+ &gIDESecurityProtocolGuid,
+ NULL,
+ &Count,
+ &HandleBuffer);
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ // For each handle in HandleBuffer
+ for ( i = 0; i < Count; i++ ) {
+ //
+ // Get the PasswordSecurity Protocol
+ //
+ Status = pBS->OpenProtocol( HandleBuffer[i],
+ &gIDESecurityProtocolGuid,
+ (VOID**) &IDEPasswordSecurity,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if ( EFI_ERROR( Status ))
+ continue;
+ //
+ // Get the DiskInfo Protocol
+ //
+ Status = pBS->OpenProtocol( HandleBuffer[i],
+ &gDiskInfoProtocolGuid,
+ (VOID**) &DiskInfoPtr,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if ( EFI_ERROR( Status )){
+ continue;
+ }
+ //
+ // Locate the device path Protocol
+ //
+ Status = pBS->OpenProtocol( HandleBuffer[i],
+ &gDevicePathProtocolGuid,
+ (VOID**)&DevicePath,
+ NULL,
+ HandleBuffer[i],
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+ if ( EFI_ERROR( Status )){
+ continue;
+ }
+
+ DevicePathNode = DevicePath;
+
+ //
+ // Traverse the Device Path structure till we reach HARDWARE_DEVICE_PATH
+ //
+ while (!isEndNode (DevicePathNode)) {
+
+ if ((DevicePathNode->Type == HARDWARE_DEVICE_PATH) &&
+ (DevicePathNode->SubType == HW_PCI_DP)){
+
+ PciDevicePath = (PCI_DEVICE_PATH *) DevicePathNode;
+ break;
+ }
+
+ DevicePathNode = NEXT_NODE (DevicePathNode);
+ }
+ // Check whether valid DevicePath found
+ if (PciDevicePath == NULL) continue;
+
+ Security=(SECURITY_PROTOCOL *)IDEPasswordSecurity;
+
+ if(Security->ModeFlag){
+ //
+ // Controller is in Ahci Mode, Call WhichIde function to find out Port Number
+ //
+ DiskInfoPtr->WhichIde(DiskInfoPtr,&PortNumber,&PMPortNumber);
+ //
+ // Assign the PortNumber to HddPortNumber.This Port Number is displayed in Setup.
+ //
+ HddPortNumber=PortNumber;
+ Flag=TRUE;
+
+ }else{
+
+#ifdef SB_TEMPLATE_VER
+#if SB_TEMPLATE_VER > 6
+{
+ UINT32 IdeChannel;
+ UINT32 IdeDevice;
+
+ if(gSbHddPolicyPtr==NULL){
+ Status=gBS->LocateProtocol(&gSbHddPolicyProtocolGuid,
+ NULL, \
+ &gSbHddPolicyPtr);
+ }
+
+ if(gSbHddPolicyPtr!=NULL){
+
+ //
+ // Find out the Primary/Secondary,Master/Slave Info from WhichIde function
+ //
+ DiskInfoPtr->WhichIde(DiskInfoPtr,&IdeChannel,&IdeDevice);
+ //
+ // Get the Port Number to which the HDD is connected
+ //
+ gSbHddPolicyPtr->GeneratePortNumber(PciDevicePath->Device,PciDevicePath->Function,
+ IdeChannel,IdeDevice,&PortNumber);
+
+ HddPortNumber=PortNumber;
+ Flag=TRUE;
+
+ }else{
+ //
+ // SB HDD Policy Protocol is not Present.
+ //
+ Flag=FALSE;
+ }
+}
+#endif
+#endif
+
+ }
+
+ if ( CheckSecurityStatus( IDEPasswordSecurity, &Locked, 0x0004 )) {
+ if ( HddPasswordGetDeviceName( HandleBuffer[i], &Name )) {
+ Name[12] = 0;
+ if(Flag){
+ //
+ // Display the the Port Number in Setup
+ //
+ InitString(HiiHandle, gHddSecurityName[i], L"%s%d:%s", L"P", HddPortNumber, Name);
+ }else{
+ //
+ // If SB HDD Policy Protocol is not Installed Use STR_IDE_SECURITY_PROMPT
+ // token to display the String Information.
+ //
+ Temp1 = HiiGetString( HiiHandle, STRING_TOKEN( STR_IDE_SECURITY_PROMPT ));
+ InitString(HiiHandle, gHddSecurityName[i], L"%s%d:%s",Temp1,HDDCount,Name);
+ }
+ } else {
+ if(Flag){
+ //
+ // Display the the Port Number in Setup
+ //
+ InitString(HiiHandle, gHddSecurityName[i], L"%s%d", L"P", HddPortNumber);
+ }else{
+ //
+ // If SB HDD Policy Protocol is not Installed Use STR_IDE_SECURITY_PROMPT
+ // token to display the String Information.
+ //
+ Temp1 = HiiGetString( HiiHandle, STRING_TOKEN( STR_IDE_SECURITY_PROMPT ));
+ InitString(HiiHandle, gHddSecurityName[i], L"%s%d", Temp1, HDDCount);
+ }
+ }
+ HDDCount++;
+ }// end if
+
+ }// end of for
+#endif
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/HddSmart/IdeSMART.c b/Core/EM/HddSmart/IdeSMART.c
new file mode 100644
index 0000000..4212b0f
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.c
@@ -0,0 +1,1665 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.c 26 12/22/11 4:29a Lavanyap $
+//
+// $Revision: 26 $
+//
+// $Date: 12/22/11 4:29a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.c $
+//
+// 26 12/22/11 4:29a Lavanyap
+// [TAG] EIP77259
+// [Category] Improvement
+// [Description] Included rollbacked check-ins from ver 14, 15, 16, 17
+// and made it compatible with core 4.6.5.3.
+// [Files] IdeSMART.c, IdeSMART.h, IdeSMART.mak, IdeSMART.uni,
+// IdeSMART.dxs
+//
+// 25 12/19/11 1:10a Rameshr
+// [TAG] EIP77527
+// [Category] Improvement
+// [Description] IdeSecurity, IdeAcoustic and IdeSmart changes should be
+// done based on the Core Version checking.
+// [Files] IdeSecurity.c, IdeSmart.c , Acoustic.c
+//
+// 24 12/07/11 1:29a Rameshr
+// EIP 77142 changes checked-in.
+//
+// 22 12/05/11 6:25p Rajkumarkc
+// [TAG] EIP77142
+// [Category] Improvement
+// [Description] Added the function 'IdeNonDataCommandExp' in the
+// 'IDE_BUS_PROTOCOL' and removed the existing function
+// 'IdeNonDataCommand' for supporting the upper 24bits of LBA.
+// [Files]
+// Ata.c, IdeBus.c, Idebus.h, PIDEBus.h, Acoustic.c, IdeSecurity.c,
+// IdeSMART.c
+//
+// 21 11/16/11 1:40a Lavanyap
+// [TAG] EIP45383
+// [Category] New Feature
+// [Description] Added Setup option in Advanced setup page to Check HDD
+// SMART status in POST.
+// [Files] IdeSMART.c, IdeSMART.sdl, IdeSMART.uni, IdeSMART.sd,
+// IdeSMART.cif
+//
+// 20 4/28/11 9:24a Mirk
+// [TAG] EIP55708
+// [Category] Improvement
+// [Description] If IdeSmart Error is detected and Quiet Boot is
+// enabled,the system waits for F1, while Quiet Boot Logo is displayed.
+// [Solution] If the IdeSmart error found, switch to PostScreen and
+// display the error msg.
+// [Files] - IdeSmart.c
+//
+// 18 3/17/11 10:37a Krishnakumarg
+// [TAG] - EIP 55534
+// [Category]- Defect
+// [Symptom] - Component HddSmart not labeled for CORE 4.6.4.1
+// [Solution] - IdeSmart is updated for Core 4.6.4.1
+// [Files] - IdeSmart.c,Idesmart.h,IdeSmart.mak,IdeSmart.dxs,IdeSmart.uni,
+// IdeSmart.chm
+//
+// 13 8/20/10 4:30p Krishnakumarg
+// Ide Smart doesn't support the ATA 8 Read Smart Data. EIP#42492
+// Corrected datasize for PollPeriod in Selftest funtion
+//
+// 12 8/13/10 4:47p Krishnakumarg
+// Ide Smart doesn't support the ATA 8 Read Smart Data. EIP#42492
+//
+// 11 6/13/10 4:14p Krishnakumarg
+// Ide Smart Protocol reports errors and prompts for continuing when
+// SMARTReturnStatus function is called. EIP#39414
+//
+// 10 5/07/10 11:20a Krishnakumarg
+// Added ELINK for OEM to override SMART error handling. EIP#31559
+// Also has coding standard changes
+//
+// 9 5/05/10 5:23p Yul
+// EIP 37065
+// System hang or reset when set AHCI mode and install a SMART failed HDD
+// with AHCI mode.
+//
+// 8 5/03/10 11:03a Krishnakumarg
+// Request additional generic functionality to be added to the IdeSMART
+// component.EIP#31559
+//
+// 7 3/26/10 5:41p Krishnakumarg
+// UEFI2.1 compliance change EIP#34744.
+//
+// 6 1/15/10 9:56a Yul
+// coding standard
+//
+// 5 3/30/09 9:24a Fredericko
+//
+// 4 3/11/09 6:49p Fredericko
+// EIP19618 removed dependency on foundation.lib functions
+//
+// 3 4/18/08 10:04a Rameshraju
+// Updated proper comments.
+//
+// 2 10/03/08 6:56p Anandakrishnanl
+// Fixed the Left Shift, which was accidently checked in with extra LT
+// symbol.
+//
+// 1 7/03/08 5:19p Anandakrishnanl
+// Added IdeSmart Module after removing IdeSmart.c from Idebus Src Module
+//
+// 2 13/04/07 3:05p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with "AMI coding
+// standard"!!!
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 5 8/22/05 4:32p Srinin
+// ATA/ATAPI identification changed.
+//
+// 5 8/17/05 3:28p Srinin
+// ATA/ATAPI device identification modified.
+//
+// 4 3/04/05 11:34a Mandal
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/10/05 11:30a Srinin
+// SMART support added.
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IDESMART.c
+//
+// Description: IDE SMART Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IdeSMART.h"
+#include "IdeSMARTStrTokens.h"
+#include <Setup.h>
+
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#include "Include\UefiHii.h"
+#include "Protocol\HiiDatabase.h"
+#include "Protocol\HiiString.h"
+#endif
+
+static EFI_GUID gHddSmartInitProtocolGuid = HDD_SMART_INIT_PROTOCOL_GUID;
+EFI_GUID gSMARTProtocolGuid = IDE_SMART_INTERFACE_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#else
+EFI_GUID gEfiHiiProtocolGuid = EFI_HII_PROTOCOL_GUID;
+#endif
+
+EFI_GUID gAmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+
+EFI_HII_HANDLE HiiPostHandle;
+
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#define LANGUAGE_CODE_ENGLISH "en-US"
+
+EFI_HII_STRING_PROTOCOL *HiiString=NULL;
+CHAR8 Language[] = LANGUAGE_CODE_ENGLISH;
+
+#else
+#define LANGUAGE_CODE_ENGLISH "eng"
+
+EFI_HII_PROTOCOL *pHii;
+#endif
+
+AMI_POST_MANAGER_PROTOCOL *pAmiPostMgr;
+SETUP_DATA gSetupData;
+
+// Generic function in this file that will call function specified via elink
+VOID ReportSmartFailure(BOOLEAN Mode, VOID *Interface);
+
+// ELINK defined function that will be called. Function name 'OemReportSmartFailureFunction'
+// is #defined via the makefile /D to be the ELINK function name
+VOID OemReportSmartFailureFunction(BOOLEAN Mode, VOID *Interface);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IdeSMARTEntryPoint
+//
+// Description: This function is the entry point for IDE SMART Driver.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+//
+// Notes:
+// Entry Points are used to locate or install protocol interfaces and
+// notification events.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS IdeSMARTEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ Status = LoadStrings( ImageHandle, &HiiPostHandle );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(HDD_SMART_INIT_PROTOCOL),
+ (VOID**)&gHddSmartInitProtocol );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ gHddSmartInitProtocol->InstallSMARTInterface = InstallSMARTInterface;
+ gHddSmartInitProtocol->UnInstallSMARTInterface = UnInstallSMARTInterface;
+ gHddSmartInitProtocol->InitSMARTSupport = InitSMARTSupport;
+ gHddSmartInitProtocol->SmartDiagonasticFlag = FALSE;
+ #if SMART_DIAGNOSTICS_SUPPORT
+ gHddSmartInitProtocol->SmartDiagonasticFlag = TRUE;
+ #endif
+
+ Status = pBS->InstallProtocolInterface(
+ &Handle,
+ &gHddSmartInitProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gHddSmartInitProtocol
+ );
+ ASSERT_EFI_ERROR( Status );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitSMARTSupport
+//
+// Description: Initialize SMART functionality
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals: ConfigureIdeDeviceAndController, ConfigureIdeDevice
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitSMARTSupport(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag )
+
+{
+ UINT8 bData;
+ EFI_STATUS Status;
+ IDENTIFY_DATA IdentifyData;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ DEVICE_TYPE DeviceType;
+ COMMAND_STRUCTURE CommandStructure;
+ UINTN SetupDataSize = sizeof(SETUP_DATA);
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE ){
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ DeviceType = IdeBusInterface->IdeDevice.DeviceType;
+ } else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ DeviceType = SataDevInterface->DeviceType;
+ }
+
+ //
+ // Check for ATA device
+ //
+ if ( DeviceType == ATA ){
+ //
+ // Check if SMART is supported, if no exit
+ //
+ if ( IdentifyData.Command_Set_Supported_82 & 0x1 ){
+ //
+ // Whether to Enable or Disable SMART Support
+ //
+ bData = ENABLE_SMART == 1 ? SMART_ENABLE_CMD : SMART_DISABLE_CMD;
+
+ //
+ // Check if current SMART status is what is required
+ //
+ Status = EFI_SUCCESS;
+
+ if ( !((IdentifyData.Command_Set_Enabled_85 & 0x1) == ENABLE_SMART)) {
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = bData;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ Status = CommonNonDataHook( BusInterface,
+ CommandStructure,
+ ModeFlag );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ }
+
+ //
+ // Enable Autosave feature
+ //
+ if ((Status == EFI_SUCCESS) && (bData == SMART_ENABLE_CMD)) {
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SMART_AUTOSAVE;
+ CommandStructure.SectorCount = 0xF1;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ Status = CommonNonDataHook( BusInterface,
+ CommandStructure,
+ ModeFlag );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ // Get SMART Self test setup option
+ //
+ Status = pRS->GetVariable(L"Setup", &gSetupGuid, NULL,
+ &SetupDataSize, &gSetupData);
+
+ if (EFI_ERROR(Status)) {
+ //
+ // If Setup Variable is not found, set Default values
+ //
+ gSetupData.SmartSelfTest = DEFAULT_SMART_SELFTEST;
+ }
+
+ if (gSetupData.SmartSelfTest) {
+
+ //
+ // If SMART threshold exceeded, report it to the user.
+ //
+ Status = SMARTReturnStatusWrapper( BusInterface, ModeFlag );
+
+ if (EFI_ERROR(Status)) {
+ ERROR_CODE( DXE_IDE_SMART_ERROR, EFI_ERROR_MAJOR );
+ ReportSmartFailure(ModeFlag, BusInterface);
+ }
+ }
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SMARTReturnStatusWrapper
+//
+// Description: Return SMART Status
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals: ConfigureIdeDeviceAndController, ConfigureIdeDevice
+//
+// Notes: Returns EFI_SUCCESS if threshold is not exceeded.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SMARTReturnStatusWrapper(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag )
+{
+ UINT8 bData;
+ UINT16 wData = THRESHOLD_NOT_EXCEEDED;
+ EFI_STATUS Status;
+ COMMAND_STRUCTURE CommandStructure;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ //
+ // Read the SMART return Status
+ //
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SMART_RETURN_STATUS;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ Status = CommonNonDataHook( BusInterface, CommandStructure, ModeFlag );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if ( ModeFlag == FALSE ){
+ if ( !EFI_ERROR( Status )){
+ PciIo = IdeBusInterface->PciIO;
+
+ PciIo->Io.Read(
+ IdeBusInterface->PciIO,
+ EfiPciIoWidthFifoUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.
+ LBAHighReg,
+ 1,
+ &bData
+ );
+
+ //
+ // Get the LBA Mid/High register contends.
+ //
+ wData = bData << 8;
+ PciIo->Io.Read(
+ IdeBusInterface->PciIO,
+ EfiPciIoWidthFifoUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.
+ LBAMidReg,
+ 1,
+ &bData
+ );
+ wData |= bData;
+ }
+ }else{
+ volatile AHCI_RECEIVED_FIS *FISReceiveAddress;
+ FISReceiveAddress = (AHCI_RECEIVED_FIS*)SataDevInterface->PortFISBaseAddr;
+
+ // Get the pointer to RFIS
+ if ( !EFI_ERROR( Status ) && (FISReceiveAddress->Ahci_Rfis[0] == FIS_REGISTER_D2H))
+ wData = (FISReceiveAddress->Ahci_Rfis[6] << 8) + FISReceiveAddress->Ahci_Rfis[5];
+ }
+
+ if ( wData == THRESHOLD_NOT_EXCEEDED )
+ Status = EFI_SUCCESS;
+ else
+ Status = EFI_DEVICE_ERROR;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmartErrorThresholdExceeded
+//
+// Description: Default function to report SMART failures to the POST screen
+//
+// Input: BOOLEAN Mode - TRUE - Device is in IDE mode
+// FALSE - Device is in AHCI mode
+// VOID *Interface - Interface. Should be cast into SATA_DEVICE_INTERFACE
+// or IDE_BUS_PROTOCOL depending on Mode parameter
+//
+// Output: none
+//
+// Returns: none
+//
+// Referrals: SMARTReturnStatusWrapper
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SmartErrorThresholdExceeded(BOOLEAN ModeFlag, VOID *Interface)
+{
+ EFI_STATUS Status;
+
+ UINTN StringSize = 0;
+ CHAR16 *StrBuffer = NULL;
+
+ CHAR16 *Str1 = NULL;
+ CHAR16 *Str2 = NULL;
+ CHAR16 *DeviceName = NULL;
+
+ UINT8 ChannelorPort;
+ UINT8 DeviceorPMPort;
+
+ STRING_REF Token;
+
+ EFI_INPUT_KEY Key;
+
+ // Get the Port/Channel information from the interface
+ if(ModeFlag){
+ // Sata Mode
+ DeviceName = ((SATA_DEVICE_INTERFACE*)Interface)->UDeviceName->UnicodeString;
+ ChannelorPort = ((SATA_DEVICE_INTERFACE*)Interface)->PortNumber;
+ DeviceorPMPort = ((SATA_DEVICE_INTERFACE*)Interface)->PMPortNumber;
+ }else{
+ // IDE Mode
+ DeviceName = ((IDE_BUS_PROTOCOL*)Interface)->IdeDevice.UDeviceName->UnicodeString;
+ ChannelorPort = ((IDE_BUS_PROTOCOL*)Interface)->IdeDevice.Channel;
+ DeviceorPMPort = ((IDE_BUS_PROTOCOL*)Interface)->IdeDevice.Device;
+ }
+
+ // Locate the Hii Protocol for Getting strings from our string package
+#if EFI_SPECIFICATION_VERSION > 0x20000
+ Status = pBS->LocateProtocol( &gEfiHiiStringProtocolGuid, NULL, &HiiString);
+#else
+ Status = pBS->LocateProtocol( &gEfiHiiProtocolGuid, NULL, &pHii );
+#endif
+ ASSERT_EFI_ERROR (Status);
+
+ // Locate the AMI Post Manger protocol for displaying information on the post screen
+ Status = pBS->LocateProtocol( &gAmiPostManagerProtocolGuid,
+ NULL,
+ &pAmiPostMgr );
+
+ // Check if we could locate the ami post manager
+ if(!EFI_ERROR(Status) && pST->ConOut != NULL){
+ // Depending on the mode, get different strings to identify the port the failing
+ // device is connected to
+ if(ModeFlag){
+ // Sata Mode
+
+ // Print the SATA port that the device is connected
+ // so get the "Port" string
+ Status = GetHiiString( HiiPostHandle,
+ STRING_TOKEN( STR_SMART_PORT ),
+ &StringSize,
+ &Str2);
+
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ // allocate enough space to print the "port %d" string
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(CHAR16)*(Wcslen(Str2)+4), &Str1);
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ // Create the "Port <0|1|2|3|4|5>" string in Str1
+ Swprintf(Str1, L"%s %01d", Str2, ChannelorPort);
+
+ // Fill string 2 with a null
+ Str2[0] = L'\0';
+ } else {
+ // IDE Mode
+
+ // Determine if we need to get the "Primary" or "Secondary" string
+ if (ChannelorPort == PRIMARY_CHANNEL) Token = STRING_TOKEN(STR_PRIMARY);
+ else Token = STRING_TOKEN(STR_SECONDARY);
+
+ // Get the string out of the Hiidatabase into Str1
+ Status = GetHiiString( HiiPostHandle,
+ Token,
+ &StringSize,
+ &Str1);
+
+ if ( EFI_ERROR( Status )) {
+ return ;
+ }
+
+ // Determine if we need to get the "Master" or "Slave" string
+ if (DeviceorPMPort == MASTER_DRIVE) Token = STRING_TOKEN(STR_MASTER);
+ else Token = STRING_TOKEN(STR_SLAVE);
+
+ // Get the string out of the Hiidatabase into Str1
+ Status = GetHiiString( HiiPostHandle,
+ Token,
+ &StringSize,
+ &Str2);
+ if ( EFI_ERROR( Status )) {
+ return ;
+ }
+ }
+
+ // Determine the size of all the compents we are trying to print
+ // and additional spaces for the newline, Carrage return, the two spaces
+ // the colon and the null terminiation
+ StringSize = Wcslen(Str1) + Wcslen(Str2) + Wcslen(DeviceName) + 7;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, StringSize*sizeof(CHAR16), &StrBuffer);
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ // Build the string for IDE or SATA:
+ // ide string looks like - "<Primary|Secondary> <Master|Slave> : <Device Name String>"
+ // sata string looks like - "Port <0|1|2|3|4|5> : <Device Name String>"
+ Swprintf(StrBuffer, L"\n\r%s %s: %s", Str1, Str2, DeviceName);
+
+ // free the helper buffers
+ pBS->FreePool(Str1);
+ Str1 = NULL;
+ pBS->FreePool(Str2);
+ Str2 = NULL;
+
+ // Display the post message
+ pAmiPostMgr->SwitchToPostScreen();
+ pAmiPostMgr->DisplayPostMessage(StrBuffer);
+
+ // and free the buffer that was used
+ pBS->FreePool(StrBuffer);
+ StrBuffer = NULL;
+
+ // get the smart failure string from the Hii Database
+ Status = GetHiiString(HiiPostHandle,
+ STRING_TOKEN(STR_SMART_FAILURE),
+ &StringSize,
+ &Str1);
+
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ // And display it below the drive information strings, then free the space allocated
+ pAmiPostMgr->DisplayPostMessage(Str1);
+ pBS->FreePool(Str1);
+ Str1 = NULL;
+
+ // If keyboard input is available, pause for user input
+ if(pST->ConIn != NULL){
+ // Get the pause string from the Hii Database
+ Status = GetHiiString(HiiPostHandle,
+ STRING_TOKEN(STR_SMART_FAILURE_PROMPT),
+ &StringSize,
+ &Str1);
+
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+
+ // Display the pause message on the screen
+ pAmiPostMgr->DisplayPostMessage( Str1 );
+
+ // Free the space allocated by GetHiiString
+ pBS->FreePool(Str1);
+
+ // And wait for the user to press the input key
+ Key.UnicodeChar = 0;
+ do
+ {
+ // Pause for 1/2 a second between key press reads
+ pBS->Stall(50000);
+
+ pST->ConIn->ReadKeyStroke( pST->ConIn, &Key );
+ } while ( Key.ScanCode != WAIT_FOR_ERROR_KEY );
+ }//if(pST->ConIn != NULL)
+ }//if(!EFI_ERROR(Status) && pST->ConOut != NULL)
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallSMARTInterface
+//
+// Description: Installs SMARTInterface Protocol
+//
+// Input:
+// IN VOID *BusInterface
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Already SMART support capability has been established.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallSMARTInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ SMART_INTERFACE *SMARTInterface;
+ UINT8 *Buffer;
+ IDENTIFY_DATA IdentifyData;
+ EFI_HANDLE IdeDeviceHandle;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ DEVICE_TYPE DeviceType;
+ COMMAND_STRUCTURE CommandStructure;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE ){
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ DeviceType = IdeBusInterface->IdeDevice.DeviceType;
+ IdeDeviceHandle = IdeBusInterface->IdeDeviceHandle;
+ } else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ DeviceType = SataDevInterface->DeviceType;
+ IdeDeviceHandle = SataDevInterface->IdeDeviceHandle;
+ }
+
+ //
+ // Check for HDD and SMART support
+ //
+ if ((DeviceType == ATA) // It is HDD
+ && (IdentifyData.Command_Set_Supported_82 & 0x1) // SMART supported
+ && (IdentifyData.Command_Set_Supported_84 & 0x2)) // SMART Enabled
+
+ {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 512,
+ (VOID**)&Buffer );
+
+ if ( EFI_ERROR( Status )){
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = Buffer;
+ CommandStructure.ByteCount = 512;
+ CommandStructure.Features = SMART_READ_DATA;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ if ( ModeFlag == FALSE ){
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+ Status = IdeBusInterface->AtaPioDataIn(
+ IdeBusInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAHigh,
+ CommandStructure.Device,
+ CommandStructure.Command,
+ FALSE);
+ } else {
+ Status = SataDevInterface->AhciBusInterface->ExecutePioDataCommand(
+ SataDevInterface,
+ &CommandStructure,
+ FALSE );
+ }
+
+ if ( EFI_ERROR( Status )){
+ pBS->FreePool( Buffer );
+ return Status;
+ }
+
+ //
+ // Install the Interface
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(SMART_INTERFACE),
+ (VOID**)&SMARTInterface );
+
+ if ( EFI_ERROR( Status )){
+ pBS->FreePool( Buffer );
+ return Status;
+ }
+
+ SMARTInterface->SMARTSelfTest = SMARTSelfTest;
+ SMARTInterface->SMARTSelfTestStatus = SMARTSelfTestStatus;
+ SMARTInterface->SMARTReturnStatus = SMARTReturnStatus;
+ SMARTInterface->SendSmartCommand = SendSmartCommand;
+ SMARTInterface->SmartReadData = SmartReadData;
+ SMARTInterface->SmartWriteData = SmartWriteData;
+ SMARTInterface->SMARTAbortSelfTest = SMARTAbortSelfTest;
+ SMARTInterface->SMARTGetSmartData = SMARTGetSmartData;
+ SMARTInterface->ShortPollingTime = Buffer[372];
+ if(Buffer[373] == 0xFF)
+ SMARTInterface->ExtPollingTime = (UINT16)(Buffer[376]<<8 | Buffer[375]);
+ else
+ SMARTInterface->ExtPollingTime = (UINT16)Buffer[373];
+
+ if ( ModeFlag == FALSE ){
+ IdeBusInterface->SMARTInterface = SMARTInterface;
+ SMARTInterface->BusInterface = IdeBusInterface;
+ }else{
+ SataDevInterface->SMARTInterface = SMARTInterface;
+ SMARTInterface->BusInterface = SataDevInterface;
+ }
+
+ //
+ // Set ModeFlag to FALSE if IdeBus else TRUE for Ahci Bus.
+ //
+ SMARTInterface->ModeFlag = ModeFlag; // Ide Bus
+
+ Status = pBS->InstallMultipleProtocolInterfaces(&IdeDeviceHandle,
+ &gSMARTProtocolGuid,
+ SMARTInterface,
+ NULL );
+
+ pBS->FreePool( Buffer );
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UnInstallSMARTInterface
+//
+// Description: Uninstall SMARTInterface Protocol
+//
+// Input:
+// IN VOID *BusInterface
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals: IdeBusStop
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UnInstallSMARTInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ SMART_INTERFACE *SMARTInterface;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ EFI_HANDLE IdeDeviceHandle;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE ){
+ SMARTInterface = IdeBusInterface->SMARTInterface;
+ IdeDeviceHandle = IdeBusInterface->IdeDeviceHandle;
+ }else{
+ SMARTInterface = SataDevInterface->SMARTInterface;
+ IdeDeviceHandle = SataDevInterface->IdeDeviceHandle;
+ }
+
+ if ( SMARTInterface == NULL ){
+ return EFI_SUCCESS;
+ }
+ Status = pBS->UninstallMultipleProtocolInterfaces(IdeDeviceHandle,
+ &gSMARTProtocolGuid,
+ SMARTInterface,
+ NULL );
+
+ if ( Status == EFI_SUCCESS ){
+ pBS->FreePool( SMARTInterface );
+ SMARTInterface = NULL;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SMARTSelfTest
+//
+// Description: Starts SMART SelfTest. SelfTestType will indicate whether to run
+// short or extended selftest.
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This,
+// IN UINT8 SelfTestType, ( 0 : short, 1 :extended)
+// OUT UINT16 *PollPeriod (Minutes)
+//
+// Output:
+// EFI_STATUS
+// PollPeriod will indicate the recommended time interval between polling.
+// Frequent polling will either abort the self test or may prolong it.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SMARTSelfTest(
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SelfTestType,
+ OUT UINT16 *PollPeriod )
+{
+ EFI_STATUS Status;
+ UINT8 bData;
+
+ VOID *BusInterface = ((SMART_INTERFACE* )This)->BusInterface;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE*)This;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE* )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ //
+ // Check for Short or Extended
+ //
+ bData = SelfTestType == 0 ? 1 : 2;
+ Status = SendSmartCommand( This, SMART_EXECUTE_OFFLINE_IMMEDIATE, NULL, bData);
+
+ *PollPeriod = SelfTestType == 0 ? SMARTInterface->ShortPollingTime : SMARTInterface->ExtPollingTime;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SMARTAbortSelfTest
+//
+// Description: Aborts SMART Self Test.
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SMARTAbortSelfTest (
+ IN IDE_SMART_INTERFACE *This
+ )
+{
+ VOID *BusInterface = ((SMART_INTERFACE * )This)->BusInterface;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE *)This;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE * )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ COMMAND_STRUCTURE CommandStructure;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL *)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE *)BusInterface;
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SMART_EXECUTE_OFFLINE_IMMEDIATE;
+ CommandStructure.LBALow = SMART_ABORT_SELF_TEST_SUBROUTINE;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ return CommonNonDataHook (BusInterface, CommandStructure, ModeFlag);
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SMARTGetSmartData
+//
+// Description: Get SMART data of the harddisk.
+//
+// Input:
+// IN IDE_SMART_INTERFACE This
+//
+// Output:
+// OUT UINT8 **SmartData
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SMARTGetSmartData (
+ IN IDE_SMART_INTERFACE *This,
+ OUT UINT8 **SmartData
+)
+{
+ EFI_STATUS Status;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE *)This;
+ VOID *BusInterface = ((SMART_INTERFACE * )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE * )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ COMMAND_STRUCTURE CommandStructure;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL *)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE *)BusInterface;
+
+ Status = pBS->AllocatePool (EfiBootServicesData, 512, (VOID**)SmartData);
+
+ if (EFI_ERROR(Status)){
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = *SmartData;
+ CommandStructure.ByteCount = 512;
+ CommandStructure.Features = SMART_READ_DATA;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ if (ModeFlag == FALSE) {
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+ Status = IdeBusInterface->AtaPioDataIn( IdeBusInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAHigh,
+ CommandStructure.Device,
+ CommandStructure.Command,
+ FALSE
+ );
+
+ } else {
+ Status = SataDevInterface->AhciBusInterface->ExecutePioDataCommand(
+ SataDevInterface,
+ &CommandStructure,
+ FALSE
+ );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SMARTSelfTestStatus
+//
+// Description: Starts SMART SelfTest. SelfTestType will indicate whether to run
+// short or extended selftest.
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This,
+// OUT UINT8 *TestStatus
+//
+// Output:
+// EFI_STATUS : TestStatus is valid only when EFI_STATUS is EFI_SUCCESS
+// TestStatus : Will indicate the % of test completed.
+// TestStatus = 0xFF Indicates Self Test Failed and EFI_STATUS = EFI_ERROR
+// Example: When TestStatus = 10, 10% of the test has been done.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SMARTSelfTestStatus(
+ IN IDE_SMART_INTERFACE *This,
+ OUT UINT8 *TestStatus )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE*)This;
+ VOID *BusInterface = ((SMART_INTERFACE* )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE* )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ COMMAND_STRUCTURE CommandStructure;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 512,
+ (VOID**)&Buffer );
+
+ if ( EFI_ERROR( Status )){
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = Buffer;
+ CommandStructure.ByteCount = 512;
+ CommandStructure.Features = SMART_READ_DATA;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ if ( ModeFlag == FALSE ){
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+ Status = IdeBusInterface->AtaPioDataIn(IdeBusInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAHigh,
+ CommandStructure.Device,
+ CommandStructure.Command,
+ FALSE);
+ }else{
+ Status = SataDevInterface->AhciBusInterface->ExecutePioDataCommand(
+ SataDevInterface,
+ &CommandStructure,
+ FALSE );
+ }
+
+ if ( EFI_ERROR( Status )){
+ *TestStatus = 0xff;
+ pBS->FreePool( Buffer );
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // If Bits 7:4 is not equal to 0 or 0xf then there was an error
+ // in the previous selftest.
+ //
+ if (((Buffer[363] >> 4) != 0) && ((Buffer[363] >> 4) != 0xf)) {
+ *TestStatus = 0xff;
+ Status = EFI_DEVICE_ERROR;
+ }else{
+ *TestStatus = Buffer[363] & 0xf;
+ *TestStatus = 10 - (*TestStatus);
+ *TestStatus = 10 * (*TestStatus);
+ }
+ pBS->FreePool( Buffer );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SMARTReturnStatus
+//
+// Description: Returns SMART status
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: Returns EFI_SUCCESS if threshold is not exceeded.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SMARTReturnStatus(
+ IN IDE_SMART_INTERFACE *This )
+{
+ VOID *BusInterface = ((SMART_INTERFACE* )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE* )This)->ModeFlag;
+
+ return (SMARTReturnStatusWrapper( BusInterface, ModeFlag ));
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SendSMARTCommand
+//
+// Description: Sends any Non-Data SMART Command.
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This
+// IN UINT8 SubCommand,
+// IN UINT8 AutoSaveEnable, //OPTIONAL
+// IN UINT8 SelfTestType //OPTIONAL
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals: IdeNonDataCommand, ExecuteNonDataCommand
+//
+// Notes: Returns EFI_UNSUPPORTED when SMART feature is not enabled.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SendSmartCommand (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SubCommand,
+ IN UINT8 AutoSaveEnable,
+ IN UINT8 SelfTestType
+)
+{
+ EFI_STATUS Status;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE *)This;
+ VOID *BusInterface = ((SMART_INTERFACE * )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE * )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ COMMAND_STRUCTURE CommandStructure;
+ IDENTIFY_DATA IdentifyData;
+ BOOLEAN EnableSmart;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE ){
+ IdentifyData = IdeBusInterface->IdeDevice.IdentifyData;
+ } else {
+ IdentifyData = SataDevInterface->IdentifyData;
+ }
+
+ EnableSmart = SubCommand == SMART_ENABLE_CMD ? 1 : 0;
+
+ if(!((IdentifyData.Command_Set_Enabled_85 & 0x1) == EnableSmart)) {
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Features = SubCommand;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ switch (SubCommand) {
+
+ case SMART_AUTOSAVE:
+ CommandStructure.SectorCount = AutoSaveEnable;
+ break;
+
+ case SMART_EXECUTE_OFFLINE_IMMEDIATE:
+ CommandStructure.LBALow = SelfTestType;
+ break;
+
+ default:
+ break;
+ }
+
+ if ( ModeFlag == FALSE ){
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+
+ //
+ // Idebus API changed from Core 4.6.5.2. Added Core Version check for the OLD
+ // Core support.
+ //
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028b)
+ Status = IdeBusInterface->IdeNonDataCommand(IdeBusInterface,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ (UINT8)(CommandStructure.SectorCount >> 8),
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Device,
+ CommandStructure.Command);
+#else
+ Status = IdeBusInterface->IdeNonDataCommand(IdeBusInterface,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAHigh,
+ CommandStructure.Device,
+ CommandStructure.Command);
+#endif
+ } else {
+ Status = SataDevInterface->AhciBusInterface->ExecuteNonDataCommand(
+ SataDevInterface,
+ CommandStructure );
+ }
+ return Status;
+
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmartReadData
+//
+// Description: Sends any Data In SMART command.
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This
+// IN UINT8 SubCommand,
+// IN VOID *Buffer,
+// IN UINT8 LogAddress, //OPTIONAL
+// IN UINT8 SectorCount //OPTIONAL
+// Output:
+// EFI_STATUS
+//
+// Referrals: AtaPioDataIn, SataPioDataOut
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmartReadData (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SubCommand,
+ OUT VOID *Buffer,
+ IN UINT8 LogAddress,
+ IN UINT8 SectorCount
+)
+{
+ EFI_STATUS Status;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE *)This;
+ VOID *BusInterface = ((SMART_INTERFACE * )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE * )This)->ModeFlag;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ COMMAND_STRUCTURE CommandStructure;
+ BOOLEAN MultipleSectors = FALSE;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL *)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE *)BusInterface;
+
+ //
+ //If SubCommand = SMART_READ_DATA then set SectorCount to 1
+ //
+ if (SectorCount == NULL) {
+ SectorCount = 1;
+ }
+
+ ZeroMemory(&CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = Buffer;
+
+ if ( SubCommand == SMART_READLOG ) {
+ CommandStructure.LBALow = LogAddress ; // LOG Address to read
+ CommandStructure.SectorCount = SectorCount; // No.of sectors to read
+ CommandStructure.ByteCount = SectorCount*ATA_SECTOR_BYTES;
+ if ( SectorCount>1 ) {
+ MultipleSectors = TRUE;
+ }
+ } else {
+ //
+ // SubCommand SMART_READ_DATA reads only 512 bytes.
+ //
+ CommandStructure.ByteCount = 512;
+ }
+ CommandStructure.Features = SubCommand;
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ if (ModeFlag == FALSE) {
+
+ Status = IdeBusInterface->AtaPioDataOut (
+ IdeBusInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Device,
+ CommandStructure.Command,
+ FALSE,
+ MultipleSectors );
+
+ } else {
+
+ Status = SataDevInterface->AhciBusInterface->SataPioDataOut(
+ SataDevInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Command,
+ FALSE );
+ }
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(Buffer);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmartWriteData
+//
+// Description: Sends any Data Out SMART command.
+//
+// Input:
+// IN IDE_SMART_INTERFACE *This
+// IN UINT8 SubCommand,
+// IN VOID *Buffer,
+// IN UINT8 LogAddress,
+// IN UINT8 SectorCount
+// Output:
+// EFI_STATUS
+//
+// Referrals: AtaPioDataOut, SataPioDataOut
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmartWriteData (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SubCommand,
+ IN VOID *Buffer,
+ IN UINT8 LogAddress,
+ IN UINT8 SectorCount
+)
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+ COMMAND_STRUCTURE CommandStructure;
+ SMART_INTERFACE *SMARTInterface = (SMART_INTERFACE *)This;
+ VOID *BusInterface = ((SMART_INTERFACE * )This)->BusInterface;
+ BOOLEAN ModeFlag = ((SMART_INTERFACE * )This)->ModeFlag;
+ BOOLEAN MultipleSectors = FALSE;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL *)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE *)BusInterface;
+
+ ZeroMemory( &CommandStructure, sizeof(COMMAND_STRUCTURE));
+ CommandStructure.Buffer = Buffer;
+ CommandStructure.Features = SubCommand;
+ CommandStructure.ByteCount = SectorCount * ATA_SECTOR_BYTES;
+ CommandStructure.SectorCount = SectorCount;
+ CommandStructure.LBALow = LogAddress; //LOG address to write on
+ CommandStructure.LBAMid = 0x4F;
+ CommandStructure.LBAHigh = 0xC2;
+ CommandStructure.Command = SMART_COMMAND;
+
+ if ( SectorCount>1 )
+ MultipleSectors = TRUE;
+
+ if (ModeFlag == FALSE) {
+ Status = IdeBusInterface->AtaPioDataOut (
+ IdeBusInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Device,
+ CommandStructure.Command,
+ TRUE,
+ MultipleSectors );
+ } else {
+
+ Status = SataDevInterface->AhciBusInterface->SataPioDataOut (
+ SataDevInterface,
+ CommandStructure.Buffer,
+ CommandStructure.ByteCount,
+ CommandStructure.Features,
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Command,
+ TRUE );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CommonNonDataHook
+//
+// Description: Common Hook which Calls Non Data Command.
+//
+// Input: IN VOID* BusInterface,
+// IN COMMAND_STRUCTURE CommandStructure,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CommonNonDataHook(
+ IN VOID *BusInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN BOOLEAN ModeFlag )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ SATA_DEVICE_INTERFACE *SataDevInterface;
+
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)BusInterface;
+ SataDevInterface = (SATA_DEVICE_INTERFACE*)BusInterface;
+
+ if ( ModeFlag == FALSE ){
+ CommandStructure.Device = IdeBusInterface->IdeDevice.Device << 4;
+ //
+ // Idebus API changed from Core 4.6.5.2. Added Core Version check for the OLD
+ // Core support.
+ //
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028b)
+ Status = IdeBusInterface->IdeNonDataCommand(IdeBusInterface,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ (UINT8)(CommandStructure.SectorCount >> 8),
+ CommandStructure.LBALow,
+ CommandStructure.LBALowExp,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAMidExp,
+ CommandStructure.LBAHigh,
+ CommandStructure.LBAHighExp,
+ CommandStructure.Device,
+ CommandStructure.Command);
+#else
+ Status = IdeBusInterface->IdeNonDataCommand(IdeBusInterface,
+ CommandStructure.Features,
+ (UINT8)CommandStructure.SectorCount,
+ CommandStructure.LBALow,
+ CommandStructure.LBAMid,
+ CommandStructure.LBAHigh,
+ CommandStructure.Device,
+ CommandStructure.Command);
+#endif
+ }else {
+ Status = SataDevInterface->AhciBusInterface->ExecuteNonDataCommand(
+ SataDevInterface,
+ CommandStructure );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHiiString
+//
+// Description: This function Reads a String from HII
+//
+// Input: HiiHandle - Efi Hii Handle
+// Token - String Token
+//
+// Output: Returns Pointer to allocated String Buffer
+// NULL - if could not get the data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetHiiString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF Token,
+ IN OUT UINTN *pDataSize,
+ OUT EFI_STRING *ppData )
+{
+ EFI_STATUS Status;
+
+ if ( !*ppData ){
+ *pDataSize = 0;
+ }
+
+#if EFI_SPECIFICATION_VERSION>0x20000
+ Status = HiiString->GetString (HiiString,
+ (CHAR8*) &Language,
+ HiiHandle,
+ Token,
+ *ppData,
+ pDataSize,
+ NULL);
+
+#else
+ Status = pHii->GetString ( pHii,
+ HiiHandle,
+ Token,
+ TRUE,
+ L" ",
+ pDataSize,
+ *ppData);
+#endif
+
+ if ( !EFI_ERROR( Status )){
+ return Status;
+ }
+
+ if ( Status == EFI_BUFFER_TOO_SMALL ){
+
+ if ( *ppData ){
+ pBS->FreePool( *ppData );
+ }
+
+ if ( !(*ppData = Malloc( *pDataSize ))){
+ return EFI_OUT_OF_RESOURCES;
+ }
+#if EFI_SPECIFICATION_VERSION>0x20000
+ Status = HiiString->GetString (HiiString,
+ (CHAR8*) &Language,
+ HiiHandle,
+ Token,
+ *ppData,
+ pDataSize,
+ NULL);
+
+#else
+ Status = pHii->GetString ( pHii,
+ HiiHandle,
+ Token,
+ TRUE,
+ L" ",
+ pDataSize,
+ *ppData);
+#endif
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportSmartFailure
+//
+// Description: Wrapper Function to call a ELINKed function
+//
+// Input: BOOLEAN Mode - TRUE - Device is in IDE mode
+// FALSE - Device is in AHCI mode
+// VOID *Interface - Interface. Should be cast into SATA_DEVICE_INTERFACE
+// or IDE_BUS_PROTOCOL depending on Mode parameter
+//
+// Output: none
+//
+// Returns: none
+//
+// Referrals: SmartErrorThresholdExceeded
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ReportSmartFailure(BOOLEAN Mode, VOID *Interface)
+{
+ OemReportSmartFailureFunction(Mode, Interface);
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/HddSmart/IdeSMART.chm b/Core/EM/HddSmart/IdeSMART.chm
new file mode 100644
index 0000000..903e6bf
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.chm
Binary files differ
diff --git a/Core/EM/HddSmart/IdeSMART.cif b/Core/EM/HddSmart/IdeSMART.cif
new file mode 100644
index 0000000..d960084
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "IdeSMART"
+ category = eModule
+ LocalRoot = "Core\EM\HddSmart\"
+ RefName = "IdeSMART"
+[files]
+"IdeSMART.sdl"
+"IdeSMART.mak"
+"IdeSMART.h"
+"IdeSMART.c"
+"IdeSMART.dxs"
+"IdeSMART.uni"
+"IdeSMART.chm"
+"IdeSMART.sd"
+<endComponent>
diff --git a/Core/EM/HddSmart/IdeSMART.dxs b/Core/EM/HddSmart/IdeSMART.dxs
new file mode 100644
index 0000000..56d2a53
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.dxs
@@ -0,0 +1,87 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.dxs 7 12/22/11 4:33a Lavanyap $
+//
+// $Revision: 7 $
+//
+// $Date: 12/22/11 4:33a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.dxs $
+//
+// 7 12/22/11 4:33a Lavanyap
+// [TAG] EIP77259
+// [Category] Improvement
+// [Description] Included rollbacked check-ins from ver 4, 5 and made it
+// compatible with core 4.6.5.3.
+// [Files] IdeSMART.c, IdeSMART.h, IdeSMART.mak, IdeSMART.uni,
+// IdeSMART.dxs
+//
+// 6 3/17/11 10:37a Krishnakumarg
+// [TAG] - EIP 55534
+// [Category]- Defect
+// [Symptom] - Component HddSmart not labeled for CORE 4.6.4.1
+// [Solution] - IdeSmart is updated for Core 4.6.4.1
+// [Files] - IdeSmart.c,Idesmart.h,IdeSmart.mak,IdeSmart.dxs,IdeSmart.uni,
+// IdeSmart.chm
+//
+// 3 5/07/10 11:32a Krishnakumarg
+// Updated the AMI header
+//
+// 2 3/26/10 5:39p Krishnakumarg
+// UEFI2.1 compliance change EIP#34744.
+//
+// 1 7/03/08 5:19p Anandakrishnanl
+// Added IdeSmart Module after removing IdeSmart.c from Idebus Src Module
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IdeSMART.DXS
+//
+// Description: This file is the dependency file for the IdeSmart driver
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#include "Protocol\HiiString.h"
+#else
+#include <Protocol/HII.h>
+#endif
+
+DEPENDENCY_START
+#if EFI_SPECIFICATION_VERSION > 0x20000
+ EFI_HII_STRING_PROTOCOL_GUID
+#else
+ EFI_HII_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/HddSmart/IdeSMART.h b/Core/EM/HddSmart/IdeSMART.h
new file mode 100644
index 0000000..e40d14d
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.h
@@ -0,0 +1,216 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.h 10 12/22/11 4:35a Lavanyap $
+//
+// $Revision: 10 $
+//
+// $Date: 12/22/11 4:35a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.h $
+//
+// 10 12/22/11 4:35a Lavanyap
+// [TAG] EIP77259
+// [Category] Improvement
+// [Description] Included rollbacked check-ins from ver 6, 7, 8 and made
+// it compatible with core 4.6.5.3.
+// [Files] IdeSMART.c, IdeSMART.h, IdeSMART.mak, IdeSMART.uni,
+// IdeSMART.dxs
+//
+// 9 3/17/11 10:37a Krishnakumarg
+// [TAG] - EIP 55534
+// [Category]- Defect
+// [Symptom] - Component HddSmart not labeled for CORE 4.6.4.1
+// [Solution] - IdeSmart is updated for Core 4.6.4.1
+// [Files] - IdeSmart.c,Idesmart.h,IdeSmart.mak,IdeSmart.dxs,IdeSmart.uni,
+// IdeSmart.chm
+//
+// 5 8/20/10 4:29p Krishnakumarg
+// Ide Smart doesn't support the ATA 8 Read Smart Data. EIP#42492
+// Corrected datasize for PollPeriod in Selftest funtion
+//
+// 4 5/03/10 11:03a Krishnakumarg
+// Request additional generic functionality to be added to the IdeSMART
+// component.EIP#31559
+//
+// 3 1/22/10 10:32a Yul
+// Refer to EIP 34207
+//
+// 2 1/15/10 9:57a Yul
+// coding standard
+//
+// 1 7/03/08 5:19p Anandakrishnanl
+// Added IdeSmart Module after removing IdeSmart.c from Idebus Src Module
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: <IdeSMART.h>
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the IdeSMART driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _IdeSMART_
+#define _IdeSMART_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include "Protocol\PAhciBus.h"
+#include <Protocol/AMIPostMgr.h>
+#include <Protocol/SimpleTextIn.h>
+
+HDD_SMART_INIT_PROTOCOL *gHddSmartInitProtocol;
+
+#define ZeroMemory( Buffer, Size ) pBS->SetMem( Buffer, Size, 0 )
+
+#define FIS_REGISTER_D2H 0x34 // Device To Host
+
+#pragma pack(1)
+typedef struct
+{
+ UINT8 Ahci_Dsfis[0x1C]; // DMA Setup Fis
+ UINT8 Ahci_Dsfis_Rsvd[0x04];
+ UINT8 Ahci_Psfis[0x14]; // PIO Setip Fis
+ UINT8 Ahci_Psfis_Rsvd[0x0C];
+ UINT8 Ahci_Rfis[0x14]; // D2H Register Fis
+ UINT8 Ahci_Rfis_Rsvd[0x04];
+ UINT64 Ahci_Sdbfis; // Set Device Bits Fis
+ UINT8 Ahci_Ufis[0x40]; // Unkonw FIS
+ UINT8 Ahci_Ufis_Rsvd[0x60];
+} AHCI_RECEIVED_FIS;
+#pragma pack()
+
+UINTN EfiValueToString (
+ IN OUT CHAR16 *Buffer,
+ IN INT64 Value,
+ IN UINTN Flags,
+ IN UINTN Width );
+
+EFI_STATUS GetHiiString (
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF Token,
+ IN OUT UINTN *pDataSize,
+ OUT EFI_STRING *ppData );
+
+EFI_STATUS CommonNonDataHook (
+ IN VOID *BusInterface,
+ IN COMMAND_STRUCTURE CommandStructure,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS InitSMARTSupport (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS SMARTReturnStatusWrapper (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS InstallSMARTInterface (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS UnInstallSMARTInterface (
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+//---------------------------------------------------------------------------
+// SMART DIAGNOSTICS SUPPORT START
+//---------------------------------------------------------------------------
+//#if SMART_DIAGNOSTICS_SUPPORT
+
+EFI_STATUS SMARTSelfTest (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SelfTestType,
+ OUT UINT16 *PollPeriod );
+
+EFI_STATUS SMARTSelfTestStatus (
+ IN IDE_SMART_INTERFACE *This,
+ OUT UINT8 *TestStatus );
+
+EFI_STATUS SMARTReturnStatus (
+ IN IDE_SMART_INTERFACE *This );
+
+EFI_STATUS SendSmartCommand (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SubCommand,
+ IN UINT8 AutoSaveEnable, //OPTIONAL
+ IN UINT8 SelfTestType //OPTIONAL
+ );
+EFI_STATUS SmartReadData (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SubCommand,
+ OUT VOID *Buffer,
+ IN UINT8 LogAddress, //OPTIONAL
+ IN UINT8 SectorCount //OPTIONAL
+);
+
+EFI_STATUS SmartWriteData (
+ IN IDE_SMART_INTERFACE *This,
+ IN UINT8 SubCommand,
+ IN VOID *Buffer,
+ IN UINT8 LogAddress,
+ IN UINT8 SectorCount
+);
+
+EFI_STATUS SMARTAbortSelfTest (
+ IN IDE_SMART_INTERFACE *This
+);
+
+EFI_STATUS SMARTGetSmartData (
+ IN IDE_SMART_INTERFACE *This,
+ OUT UINT8 **SmartData
+);
+
+//#endif /* SMART DIAGNOSTICS SUPPORT END */
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/HddSmart/IdeSMART.mak b/Core/EM/HddSmart/IdeSMART.mak
new file mode 100644
index 0000000..3c716ae
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.mak
@@ -0,0 +1,111 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.mak 8 12/22/11 4:36a Lavanyap $
+#
+# $Revision: 8 $
+#
+# $Date: 12/22/11 4:36a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.mak $
+#
+# 8 12/22/11 4:36a Lavanyap
+# [TAG] EIP77259
+# [Category] Improvement
+# [Description] Included rollbacked check-ins from ver 5, 6 and made it
+# compatible with core 4.6.5.3.
+# [Files] IdeSMART.c, IdeSMART.h, IdeSMART.mak, IdeSMART.uni,
+# IdeSMART.dxs
+#
+# 7 3/17/11 10:37a Krishnakumarg
+# [TAG] - EIP 55534
+# [Category]- Defect
+# [Symptom] - Component HddSmart not labeled for CORE 4.6.4.1
+# [Solution] - IdeSmart is updated for Core 4.6.4.1
+# [Files] - IdeSmart.c,Idesmart.h,IdeSmart.mak,IdeSmart.dxs,IdeSmart.uni,
+# IdeSmart.chm
+#
+# 4 5/07/10 11:23a Krishnakumarg
+# Added ELINK for OEM to override SMART error handling. EIP#31559
+#
+# 3 3/18/09 11:32a Fredericko
+# EIP19618 removed dependency on foundation.lib
+#
+# 2 3/11/09 6:48p Fredericko
+# EIP19618 removed dependency on foundation.lib functions
+#
+# 1 7/03/08 5:19p Anandakrishnanl
+# Added IdeSmart Module after removing IdeSmart.c from Idebus Src Module
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IdeSMART_mak
+#
+# Description: Make file to build IdeSmart module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : IdeSMART
+
+IdeSMART : $(BUILD_DIR)\IdeSMART.mak IdeSMARTBin
+
+$(BUILD_DIR)\IdeSMART.mak : $(IDESMART_DIR)\$(@B).cif $(IDESMART_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IDESMART_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IF "$(OemReportSmartFailureFunction: =X)"!="$(OemReportSmartFailureFunction)"
+!MESSAGE +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+!MESSAGE + Multiple items detected for ELINK OemReportSmartFailureFunction +
+!MESSAGE + Only one function name should be present for this ELINK +
+!MESSAGE +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+!ERROR Too many function names: $(OemReportSmartFailureFunction)
+!ENDIF
+
+IDESMART_DEFINES = /DOemReportSmartFailureFunction=$(OemReportSmartFailureFunction)
+
+IdeSMARTBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\IdeSmart.mak all\
+ GUID=D57C852E-809F-45cf-A377-D77BC0CB78EE\
+ ENTRY_POINT=IdeSMARTEntryPoint \
+ TYPE=BS_DRIVER \
+ "MY_DEFINES=$(IDESMART_DEFINES)"\
+ COMPRESS=1 HAS_RESOURCES=1\
+ "OBJECTS=$(BUILD_DIR)\$(IDESMART_DIR)\IdeSMART.obj"
+
+SetupSdbs : IdeSmartSDB
+
+IdeSmartSDB : $(BUILD_DIR)\IdeSMART.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\IdeSMART.mak all\
+ TYPE=SDB NAME=IdeSmart
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
diff --git a/Core/EM/HddSmart/IdeSMART.sd b/Core/EM/HddSmart/IdeSMART.sd
new file mode 100644
index 0000000..31b75b2
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.sd
@@ -0,0 +1,126 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.sd 1 11/16/11 1:31a Lavanyap $
+//
+// $Revision: 1 $
+//
+// $Date: 11/16/11 1:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/HddSmart/IdeSMART.sd $
+//
+// 1 11/16/11 1:31a Lavanyap
+// [TAG] EIP45383
+// [Category] New Feature
+// [Description] Added Setup option in Advanced setup page to Check HDD
+// SMART status in POST.
+// [Files] IdeSMART.c, IdeSMART.sdl, IdeSMART.uni, IdeSMART.sd,
+// IdeSMART.cif
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: IdeSMART.sd
+//
+// Description: IdeSMART related setup definitions.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+// Put NVRAM data definitions here.
+// For example: UINT8 Data1;
+// These definitions will be converted by the build process
+// to a definitions of SETUP_DATA fields.
+ UINT8 SmartSelfTest;
+#endif
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+
+ #define SMART_CHECKBOX_SMART_SELFTEST\
+ checkbox varid = SETUP_DATA.SmartSelfTest,\
+ prompt = STRING_TOKEN(STR_SMART_SELFTEST),\
+ help = STRING_TOKEN(STR_SMART_SELFTEST_HELP),\
+ flags = DEFAULT_SMART_SELFTEST | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+#endif //#ifdef CONTROL_DEFINITION
+
+#ifdef CONTROLS_WITH_DEFAULTS
+
+ SMART_CHECKBOX_SMART_SELFTEST
+
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+#ifdef ADVANCED_FORM_SET //CHIPSET_FORM_SET
+
+ #ifdef FORM_SET_TYPEDEF
+ // Add any additional type definitions here
+ #endif
+
+ #ifdef FORM_SET_VARSTORE
+ // Define custom varstore's here
+ #endif
+
+ #ifdef FORM_SET_ITEM
+ // Define controls to be added to the main page of the formset
+ #endif
+
+ #ifdef FORM_SET_GOTO
+ // Define goto commands for the forms defined in this file
+ goto SMART_FORM_ID,
+ prompt = STRING_TOKEN(STR_SMART_FORM),
+ help = STRING_TOKEN(STR_SMART_FORM_HELP);
+ #endif
+
+ #ifdef FORM_SET_FORM
+
+ #ifndef SMART_FORM_MAIN
+ #define SMART_FORM_MAIN
+
+ // Define forms
+ form formid = AUTO_ID(SMART_FORM_ID),
+ title = STRING_TOKEN(STR_SMART_FORM);
+
+ SUBTITLE(STRING_TOKEN(STR_SMART_FORM))
+ SEPARATOR
+
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ SMART_CHECKBOX_SMART_SELFTEST
+ endif;
+
+ endform; // SMART_FORM_ID
+ #endif // SMART_FORM_MAIN
+ #endif // FORM_SET_FORM
+#endif // ADVANCED_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/HddSmart/IdeSMART.sdl b/Core/EM/HddSmart/IdeSMART.sdl
new file mode 100644
index 0000000..40d028d
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.sdl
@@ -0,0 +1,91 @@
+TOKEN
+ Name = "IdeSMART_Support"
+ Value = "1"
+ Help = "Main switch to enable IdeSMART support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "IDESMART_DIR"
+End
+
+TOKEN
+ Name = "ENABLE_SMART"
+ Value = "1"
+ Help = "1 : Enable SMART \ 0 : Disable SMART"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SMART_DIAGNOSTICS_SUPPORT"
+ Value = "0"
+ Help = "Installs SMARTInterface protocol for running SMART diagnostics."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "ENABLE_SMART" "=" "1"
+End
+
+TOKEN
+ Name = "WAIT_FOR_ERROR_KEY"
+ Value = "EFI_SCAN_F1"
+ Help = "After post error message, wait for the key"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SMART_SELFTEST"
+ Value = "0"
+ Help = "Default setup value of HDD SMART status check:\1 - Check SMART status during POST\0 - Do not Check SMART status during POST "
+ TokenType = Integer
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes IdeSMART.mak to Project"
+ File = "IdeSMART.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IdeSMART.sdb"
+ Parent = "SETUP_SDBS"
+ Priority = 31
+ Help = "Includes SMART setup options into the project"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDESMART_DIR)\IdeSMART.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 31
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDESMART_DIR)\IdeSMART$(ARCH).ffs"
+ Parent = "FV_MAIN"
+ Token = "ENABLE_SMART" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IdeSMART.ffs"
+ Parent = "$(IDESMART_DIR)\IdeSMART$(ARCH).ffs"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OemReportSmartFailureFunction"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SmartErrorThresholdExceeded"
+ Parent = "OemReportSmartFailureFunction"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/HddSmart/IdeSMART.uni b/Core/EM/HddSmart/IdeSMART.uni
new file mode 100644
index 0000000..04bc881
--- /dev/null
+++ b/Core/EM/HddSmart/IdeSMART.uni
Binary files differ
diff --git a/Core/EM/IdeBus/Ata.c b/Core/EM/IdeBus/Ata.c
new file mode 100644
index 0000000..00cabb0
--- /dev/null
+++ b/Core/EM/IdeBus/Ata.c
@@ -0,0 +1,2986 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/Ata.c 34 1/03/12 11:22p Rajkumarkc $
+//
+// $Revision: 34 $
+//
+// $Date: 1/03/12 11:22p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/Ata.c $
+//
+// 34 1/03/12 11:22p Rajkumarkc
+// // [TAG] EIP 79612 & 80003
+// // [Category] Bug Fix
+// // [Description]System hangs with Blue screen during Win8 installation
+// // in IDE Mode (AMD Platforms)
+// // Use PLATFORM_IDE_PROTOCOL data instead of hard coded
+// // macro POWERON_BUSY_CLEAR_TIMEOUT in Ata.c file
+// // [Files] Ata.c
+//
+// 33 12/05/11 6:12p Rajkumarkc
+// [TAG] EIP77142
+// [Category] Improvement
+// [Description] Added the function 'IdeNonDataCommandExp' in the
+// 'IDE_BUS_PROTOCOL' and removed
+// the existing function 'IdeNonDataCommand' for supporting
+// the upper 24bits of LBA.
+// [Files]
+// Ata.c
+// IdeBus.c
+// Idebus.h
+// PIDEBus.h
+//
+// 32 11/08/11 5:15a Deepthins
+// [TAG] EIP74607
+// [Category] Improvement
+// [Description] Block IO Read/Write function, the allignment should be
+// proper. IoAlign value is 0 or 1 means that the buffer can be placed
+// anywhere in memory. Otherwise, IoAlign must be a power of 2, and the
+// requirement is that the start address of a buffer must be evenly
+// divisible by IoAlign with no remainder.
+// [Files] Ata.c, Atapi.c, AhciController.c
+//
+// 31 11/07/11 4:25a Deepthins
+// [TAG] EIP74607
+// [Category] Improvement
+// [Description] IoAlign values is 0 or 1 means that the buffer can be
+// placed anywhere in memory. Otherwise, IoAlign must be a power of 2, and
+// the requirement is that the start address of a buffer must be evenly
+// divisible by 2 to the power of IoAlign with no remainder.
+// [Files] Ata.c
+//
+// 30 11/07/11 12:37a Deepthins
+// [TAG] EIP73941
+// [Category] Improvement
+// [Description] BufferSize is 0 , ReadBlock function should return
+// EFI_SUCCESS without actual reading.
+// [Files] Ata.c
+//
+// 29 9/27/11 3:10a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 28 8/12/11 4:12a Lavanyap
+// [TAG] EIP66476
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AtaPioDataOut fails for data write commands
+// [RootCause] TempBuffer pointer has been assigned for both data read
+// and write commands.
+// [Solution] TempBuffer pointer has to be assigned only for data read
+// commands.
+// [Files] Ata.c
+//
+// 27 3/28/11 4:44p Artems
+// EIP 53849: fixed bug with build error in 32-bit debug mode
+//
+// 26 12/23/10 3:54a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 25 11/02/10 12:01a Rameshr
+// [TAG] - EIP 45266
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - E-SATA card will hang up on post and debug card show "AE
+// [RootCause]- Device doesn't support any of the UDMA mode and function
+// ReturnMsbbit returns incorrect values
+// [Solution] - If any of the bit is not set in Input value, ReturnMsbbit
+// returns 0xFF.
+// [Files] - Ata.c, AhciBus.c
+//
+// 24 10/11/10 11:27a Krishnakumarg
+// [TAG] - EIP 43249
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Non-Ascii character in comments causing build problem in
+// japanese XP
+// [RootCause]- Presence of Non-Ascii character
+// [Solution] - Remove Non-Ascii character present in the file
+// [Files] - IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 23 9/24/10 12:47a Rameshr
+// [TAG] - EIP 44713
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - SECURITY_ERASE_UNIT command is not working
+// [RootCause] - Security Erase unit command timeout value is not proper.
+// So getting Timeout error for this command.
+// [Solution] - Security Erase command timeout value should be from the
+// Identify packet command word 89
+// [Files] - Ata.c
+//
+// 22 8/25/10 4:07a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: All.
+//
+// 21 4/16/10 4:05p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 20 7/01/09 12:23p Rameshr
+// Coding Standard and File header updated.
+//
+// 19 6/16/09 10:13a Rameshr
+// if the Erase command timeout value is 0 or 255, wait for the Erase
+// command completion without timeout value
+// EIP:20630
+//
+// 18 3/29/09 11:13a Rameshr
+// Security Erase command timeout value should be from the Identify packet
+// command word 89
+// EIP 20630
+//
+// 17 4/22/08 2:02p Felixp
+// DXE_IDE_DETECT progress code moved from ATA.c to IdeBus.c
+// DXE_IDE_ENABLE progress code added
+//
+// 16 3/06/08 4:42p Ambikas
+//
+// 15 3/04/08 7:51p Felixp
+//
+// 13 28/02/08 7:06p Anandakrishnanl
+// Changed timeout values and DMA capability logic for DisableIdeInterrupt
+// routine.
+//
+// 12 13/04/07 2:59p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 11 5/03/07 11:40a Anandakrishnanl
+// Fix in Check Controller presence to detect Hard disk above 400 GB.
+//
+// 10 2/12/07 3:41p Pats
+// Eliminated Check Drive Ready to reduce boot time on reset.
+//
+// 9 10/27/06 4:20p Felixp
+// Reverted back to the previous version
+//
+// 7 10/12/06 2:02p Srinin
+// Fixed problem in multiple read/Write word in PIO mode.
+//
+// 6 8/24/06 9:30a Felixp
+// x64 support (bug fixes)
+//
+// 5 3/13/06 2:20a Felixp
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:06p Srinin
+// Idedevice detection logic modified.
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 11 9/27/05 4:41p Olegi
+// DisableIdeInterrupt is modified, added code to clear interrupt request.
+//
+// 10 8/22/05 4:31p Srinin
+// ATA/ATAPI identification changed.
+//
+// 9 7/18/05 4:31p Felixp
+// 64-bit compatibility warnings removed
+//
+// 8 4/25/05 9:55a Felixp
+// bug fix in IssueAtaReadWriteCommand
+//
+// 7 3/04/05 11:33a Mandal
+//
+// 6 2/24/05 12:21p Felixp
+// bug fix in AtaBlkRead and AtaBlkWrite functions:
+// EFI_INVALID_PARAMETER was returned when last block is read or written
+// to
+//
+// 5 2/01/05 12:59p Srinin
+// IDE HotPlug Support added.
+//
+// 4 1/28/05 1:19p Felixp
+// IdeBus is linked together with CORE_DXE
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 1/05/05 11:21a Srinin
+// BusMaster and Password Support added.
+//
+// 1 12/10/04 1:01p Srinin
+// Initial Checkin of IdeBus Driver.
+//
+//
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Ata.c
+//
+// Description: ATA Services
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "IdeBus.h"
+#include <Protocol\IdeBusBoard.h>
+
+extern PLATFORM_IDE_PROTOCOL *gPlatformIdeProtocol;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: DetectIdeDevice
+//
+// Description: Detects the ATA/ATAPI device
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeBusStart
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If controller not present return EFI_NOT_FOUND
+// 2. If BSY bit not clear and DRDY not set, return EFI_DEVICE_ERROR
+// 3. If Identify command fails, return EFI_NOT_FOUND
+// 4. Else return Success
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DetectIdeDevice(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+ UINT16 Index;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+
+ //
+ // Check if the controller is present
+ //
+ Status = ControllerPresence( IdeBusInterface );
+
+ if ( Status == EFI_NOT_FOUND ) {
+ //
+ // Status Reg is 0xff
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ if ( Status == EFI_DEVICE_ERROR ) {
+ IdeSoftReset( IdeBusInterface );
+
+ //
+ //3 Sec loop
+ //
+ for ( Index = 0; Index < 300; Index++ ) {
+ //
+ //check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ BSY,
+ 1 ); // 1 msec
+
+ if ( Status == EFI_SUCCESS ) {
+ break;
+ }
+ pBS->Stall( 10000 ); // 10Msec
+ }
+
+ Status = ControllerPresence( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ //
+ // Device couldn't be detected
+ //
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ //
+ //Disable Interrupt
+ //
+ DisableIdeInterrupt( IdeBusInterface );
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ IdeBusInterface->IdeDevice.Device << 4 );
+
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ BSY,
+ gPlatformIdeProtocol->PoweonBusyClearTimeout ); // 10 sec
+
+ //
+ //Check Drive ready. ATAPI devices will not set DRDY bit after reset
+ //
+ Status = CheckDriveReady( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ Status = AtapiIdentifyCommand( IdeBusInterface,
+ &(IdeBusInterface->IdeDevice.IdentifyData));
+ IdeBusInterface->IdeDevice.DeviceType = ATAPI;
+ return Status;
+ }
+
+ //
+ //Detect ATA device
+ //
+ Status = AtaIdentifyCommand( IdeBusInterface,
+ &(IdeBusInterface->IdeDevice.IdentifyData));
+ IdeBusInterface->IdeDevice.DeviceType = ATA;
+
+ if ( Status == EFI_SUCCESS ) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ //Detect ATAPI Device. After failing the ATA Identify command, ATAPI device if present,
+ //should have the signature EB14h
+ //
+ Status = EFI_NOT_FOUND;
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAMidReg,
+ &Data8 );
+
+ if ( Data8 == (ATAPI_SIGNATURE & 0xff)) {
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAHighReg,
+ &Data8 );
+
+ if ( Data8 == (ATAPI_SIGNATURE >> 8)) {
+ IdeBusInterface->IdeDevice.DeviceType = ATAPI;
+ Status = AtapiIdentifyCommand( IdeBusInterface,
+ &(IdeBusInterface->IdeDevice.
+ IdentifyData));
+ }
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ControllerPresence
+//
+// Description: Detects the ATA/ATAPI Controller
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: DetectIdeDevice
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Select the drive
+// 2. Read status Register
+// 3. If Status_Reg = 0xff, return Not_Found
+// 4. Check if Busy bit is clear, return Found
+// 5. If the BUS is not floating return EFI_DEVICE_ERROR
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ControllerPresence(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT8 Device = IdeBusInterface->IdeDevice.Device;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+ UINT8 Temp;
+ UINT16 Index;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ Device << 4 );
+
+ //
+ //Read the status Register
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.StatusReg, &Data8 );
+
+ if ( Data8 == 0xff ) {
+ return EFI_NOT_FOUND;
+ }
+
+ Index = 0;
+
+ do
+ {
+ //
+ // Status Register is not 0xff.
+ //
+ Temp = Data8;
+
+ //60 usec delay
+ pBS->Stall( 60 );
+
+ //
+ //Read the status Register
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ &Data8 );
+
+ //
+ //Return Success if controller present
+ //
+ if ( !(Data8 & 0x80)) {
+ return EFI_SUCCESS;
+ }
+
+ Data8 |= Temp;
+ //
+ //Keep bits 7,6,3 and 0
+ //
+ Data8 &= 0xc9;
+
+ if ( Data8 == 0xc9 ) {
+ //Check for Bus Floating
+ //Select the drive
+ Data8 = (Device & 1) ? 0xA0 : 0xB0;
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ Data8 );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.SectorCountReg,
+ 0xff );
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ &Temp );
+ //Decide Controller Present or Not
+ return (Temp == Data8) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+ }
+ Index++;
+ } while ( Index < 350 );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaReset
+//
+// Description: Reset ATA device
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaReset(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaBlkRead
+//
+// Description: Read from ATA device
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO, AtaReadWritePio
+//
+// Notes:
+// 1. Check for error conditions.
+// 2. Call AtaReadWritePio.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ UINTN DataN;
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ UINT32 BlockSize = BlkMedia->BlockSize;
+ UINTN BufferAddress;
+
+ //
+ //Check if Media ID matches
+ //
+ if ( BlkMedia->MediaId != MediaId ) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if ( BlkMedia->MediaPresent == FALSE ) {
+ return EFI_NO_MEDIA;
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((BlkMedia->IoAlign > 1 ) && (BufferAddress % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check whether the block size is multiple of BlkMedia->BlockSize
+ //
+ DataN = BufferSize % BlkMedia->BlockSize;
+
+ if ( DataN ) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
+ //Check for Valid start LBA #
+ //
+ if ( LBA > BlkMedia->LastBlock ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check for Valid End LBA #
+ //
+ DataN = BufferSize / BlkMedia->BlockSize;
+
+ if ( LBA + DataN > BlkMedia->LastBlock + 1 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( gPlatformIdeProtocol->IdeBusMasterSupport ) {
+ if ( DMACapable( IdeBusInterface )) {
+ Status = AtaReadWriteBusMaster( IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.ReadCommand,
+ 0 );
+ return Status;
+ }
+ }
+
+
+ Status = AtaReadWritePio( IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.ReadCommand,
+ 0 );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaBlkWrite
+//
+// Description: Write to ATA device
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO, AtaReadWritePio
+//
+// Notes:
+// 1. Check for error conditions.
+// 2. Call AtaReadWritePio.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ UINTN DataN;
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ UINT32 BlockSize = BlkMedia->BlockSize;
+ UINTN BufferAddress;
+
+ //
+ //Check if Media ID matches
+ //
+ if ( BlkMedia->MediaId != MediaId ) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((BlkMedia->IoAlign > 1 ) && (BufferAddress % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check whether the block size is multiple of BlkMedia->BlockSize
+ //
+ DataN = BufferSize % BlkMedia->BlockSize;
+
+ if ( DataN ) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
+ //Check for Valid start LBA #
+ //
+ if ( LBA > BlkMedia->LastBlock ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check for Valid End LBA #
+ //
+ DataN = BufferSize / BlkMedia->BlockSize;
+
+ if ( LBA + DataN > BlkMedia->LastBlock + 1 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( gPlatformIdeProtocol->IdeBusMasterSupport ) {
+ if ( DMACapable( IdeBusInterface )) {
+ Status = AtaReadWriteBusMaster( IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.WriteCommand,
+ 1 );
+ return Status;
+ }
+ }
+
+ Status = AtaReadWritePio( IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.WriteCommand,
+ 1 );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaBlkFlush
+//
+// Description: Flush the cache
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaBlkFlush(
+ IN EFI_BLOCK_IO_PROTOCOL *This )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaReadWritePio
+//
+// Description: Issues Read/Write Command and Read/Write the data from/to the ATA device
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINTN ByteCount,
+// UINT64 LBA
+// IN UINT8 ReadWriteCommand,
+// IN BOOLEAN ReadWrite Read/Write = 0/1
+//
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals: AtaBlkWrite, AtaBlkRead
+//
+// Notes:
+// 1. Check if Multiple sectors can be read/written to the ATA device.
+// 2. Check for 48-bit LBA support.
+// 3. Issue the command based on step 1 and step 2 results.
+// 4. check for errors.
+// 5. If success read/write data.
+// 6. Based on step 1 results, complete the read/write sequence
+// 7. If all sectors are not completed, goto step 3.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaReadWritePio(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN ReadWrite )
+{
+ EFI_STATUS Status;
+ INT32 WordCount;
+ UINT32 SectorCount;
+ UINTN Remainder;
+ UINT8 Data8;
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ UINT8 BlockSize = 1; // 1 sector Default
+ VOID *TempBuffer;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ INT64 LoopCount;
+ INT64 MaxSectorCount;
+ INT64 Total_Number_Of_Sectors;
+ UINT32 EraseCommandTimeout = 0;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+ BOOLEAN SectorGTBytes = FALSE;
+
+ //
+ //Check if the device supports Multiple sector Read/Write
+ //
+ if ( IdeDevice->IdentifyData.Valid_Bits_59 & 0x100 ) {
+ BlockSize = (UINT8) IdeDevice->IdentifyData.Valid_Bits_59;
+ }
+
+ //
+ // Error Checking
+ //
+ if ( BlockSize == 0 ) {
+ BlockSize = 1;
+ }
+
+ if((IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[13] + \
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+ //
+ // Disable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ if ( Check48BitCommand( ReadWriteCommand )) {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO_48BIT;
+ }
+ else {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO;
+ }
+
+ //
+ //Calculate the total number of Sectors to be transferred
+ //
+ Total_Number_Of_Sectors = ByteCount / SectorSize; //512
+ // If the caller is requesting less bytes than one sector, we need to
+ // allocate space for one sector.
+ if ((ByteCount < SectorSize) && (ByteCount > 0)) {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ SectorSize,
+ (VOID**)&TempBuffer );
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SectorGTBytes = TRUE;
+ Total_Number_Of_Sectors = 1;
+ } else {
+ TempBuffer = Buffer;
+ }
+
+ for (;
+ Total_Number_Of_Sectors > 0;
+ Total_Number_Of_Sectors -= MaxSectorCount )
+ {
+ if ( Total_Number_Of_Sectors > MaxSectorCount ) {
+ SectorCount = 0;
+ } else {
+ SectorCount = (UINT32) Total_Number_Of_Sectors;
+ }
+
+ Status = IssueAtaReadWriteCommand( IdeBusInterface,
+ LBA,
+ SectorCount,
+ ReadWriteCommand,
+ NULL );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Update LBA for next loop
+ //
+ if ( SectorCount ) {
+ LBA += SectorCount;
+ LoopCount = (SectorCount / BlockSize);
+ LoopCount += ((SectorCount % BlockSize) > 0 ? 1 : 0);
+ }
+ else {
+ LBA += MaxSectorCount;
+ LoopCount = Div64( MaxSectorCount, BlockSize, &Remainder );
+ LoopCount += (Remainder > 0 ? 1 : 0);
+ }
+
+ //
+ //For Security Erase command the time out value comes from Identify Data.
+ //
+ if ( ReadWriteCommand == SECURITY_ERASE_UNIT ) {
+ EraseCommandTimeout = (UINT32)( IdeBusInterface->IdeDevice.IdentifyData.Time_security_Earse_89 );
+
+ if ( EraseCommandTimeout <= 254 ) {
+ EraseCommandTimeout = EraseCommandTimeout * 2 * 1000 * 60; //Value * 2Minitues
+ }
+ else {
+ EraseCommandTimeout = 0; // No Timeout Value
+ }
+ }
+
+ //
+ //Read Data
+ //
+ for (; LoopCount > 0; LoopCount -= 1 ) {
+ //
+ //Wait for Command completion
+ //
+ if ( ReadWriteCommand == SECURITY_ERASE_UNIT ) {
+ Status = WaitForCmdCompletionWithTimeOutValue( IdeBusInterface,
+ EraseCommandTimeout );
+ }
+ else {
+ Status = WaitForCmdCompletion( IdeBusInterface );
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for DRQ
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ DRQ,
+ DRQ_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Caluculate # of Words to be read/written
+ //
+ if ( SectorCount ) {
+ if ( SectorCount >= BlockSize ) {
+ WordCount = (BlockSize * SectorSize) / 2;
+ }
+ else {
+ WordCount = (SectorCount * SectorSize) / 2; // Partial Block will be transferred
+ }
+ }
+ else {
+ WordCount = (BlockSize * SectorSize) / 2;
+ }
+
+ if ( BlockSize == 1 ) {
+ WordCount = (SectorSize) / 2;
+ }
+
+ if ( ReadWrite ) {
+ Status = IdeWriteMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ WordCount,
+ TempBuffer );
+ } else {
+ Status = IdeReadMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ WordCount,
+ TempBuffer );
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for errors.
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ &Data8 );
+
+ if ( Data8 & 0x21 ) { // ERR OR DF bit set ?
+ return EFI_DEVICE_ERROR;
+ }
+
+ ((UINT8*)TempBuffer) += (WordCount * 2);
+
+ if ( SectorCount ) {
+ SectorCount -= (WordCount * 2) / SectorSize;
+ }
+ else {
+ SectorCount = (UINT32) ( MaxSectorCount - ((WordCount * 2) / SectorSize));
+ }
+ }
+ }
+ if (SectorGTBytes) {
+ pBS->CopyMem( Buffer, TempBuffer, ByteCount);
+ pBS->FreePool( TempBuffer );
+ }
+
+ //
+ // Check for errors
+ //
+ if ( ReadWriteCommand == SECURITY_ERASE_UNIT ) {
+ Status = WaitForCmdCompletionWithTimeOutValue( IdeBusInterface,
+ EraseCommandTimeout );
+ } else {
+ Status = WaitForCmdCompletion( IdeBusInterface );
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaPioDataIn
+//
+// Description: Issues command which require data to be read
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINT32 ByteCount,
+// UINT8 SectorCount,
+// UINT8 LBALow,
+// UINT8 LBAMid,
+// UINT8 LBAHigh,
+// UINT8 Device,
+// UINT8 Command,
+// BOOLEAN Multiple // to determine the block size
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Used to get Identify command data etc.
+// 1. Issue the command
+// 2. Check for errors.
+// 3. Check if Data is ready. If yes, read it else return error.
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaPioDataIn(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ OUT VOID *Buffer,
+ IN UINT32 ByteCount,
+ IN UINT8 Features,
+ IN UINT8 SectorCount,
+ IN UINT8 LBALow,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAHigh,
+ IN UINT8 Device,
+ IN UINT8 Command,
+ IN BOOLEAN Multiple )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ EFI_STATUS Status;
+ UINT8 Data8;
+ UINT32 BlockSize;
+ VOID *TempBuffer = Buffer;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+ INT64 TempByteCount;
+
+
+ if((IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[13] + \
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+
+ if ( Multiple ) {
+ BlockSize = SectorSize * (IdeBusInterface->IdeDevice.IdentifyData.Valid_Bits_59 & 0x0f);
+ }
+ else {
+ //
+ // Only one block of data to read
+ //
+ BlockSize = SectorSize;
+ }
+
+ if (ByteCount < SectorSize) BlockSize = ByteCount;
+
+ // Make the byte count a signed number.
+ TempByteCount = (INT64)ByteCount;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ Device );
+
+ //
+ // Issue the Command
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.FeatureReg,
+ Features );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.SectorCountReg,
+ SectorCount );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBALowReg,
+ LBALow );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAMidReg,
+ LBAMid );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAHighReg,
+ LBAHigh );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.CommandReg,
+ Command );
+
+ for (; TempByteCount > 0; TempByteCount -= BlockSize ) {
+
+ //
+ //Wait for 400nsec before reading the status. To accomplish it, read ATL_STATUS and ignore the result
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY,
+ COMMAND_COMPLETE_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check if DRQ is set else it is an error
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ &Data8 );
+
+ //
+ // DRQ bit set ?
+ //
+ if ( !(Data8 & 0x08)) {
+ //
+ // Handle Error condition
+ //
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( Data8 & 0x21 ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = IdeReadMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ BlockSize / 2,
+ TempBuffer );
+ //
+ // Wait for DRQ to go low
+ //
+ WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ DRQ,
+ DRQ_CLEAR_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+ ((UINT8*)TempBuffer) += BlockSize;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaPioDataOut
+//
+// Description: Issues Read/Write Command and Read/Write the data from/to the ATA device
+// with SubCommand Support.
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINTN ByteCount,
+// UINT8 Features,
+// UINT32 SectorCountIn,
+// UINT8 LBALow,
+// UINT8 LBALowExp,
+// UINT8 LBAMid,
+// UINT8 LBAMidExp,
+// UINT8 LBAHigh,
+// UINT8 LBAHighExp,
+// UINT8 Device,
+// UINT8 Command,
+// BOOLEAN ReadWrite, // Read/Write = 0/1
+// BOOLEAN Multiple // to determine the block size
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check if Multiple sectors can be read/written to the ATA device.
+// 2. Check for 48-bit LBA support.
+// 3. Issue the command based on step 1 and step 2 results.
+// 4. check for errors.
+// 5. If success read/write data.
+// 6. Based on step 1 results, complete the read/write sequence
+// 7. If all sectors are not completed, goto step 3.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtaPioDataOut(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT8 Features,
+ IN UINT32 SectorCountIn,
+ IN UINT8 LBALow,
+ IN UINT8 LBALowExp,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAMidExp,
+ IN UINT8 LBAHigh,
+ IN UINT8 LBAHighExp,
+ IN UINT8 Device,
+ IN UINT8 Command,
+ IN BOOLEAN ReadWrite,
+ IN BOOLEAN Multiple )
+{
+ EFI_STATUS Status;
+ INT32 WordCount;
+ UINT32 SectorCount;
+ UINTN Remainder;
+ UINT8 Data8;
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ UINT8 BlockSize = 1; // 1 sector Default
+ VOID *TempBuffer;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ INT64 LoopCount;
+ INT64 MaxSectorCount;
+ INT64 Total_Number_Of_Sectors;
+ UINT32 EraseCommandTimeout = 0;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+ BOOLEAN SectorGTBytes = FALSE;
+ UINT64 LBA = 0;
+ UINT64 LBAHighDword = 0;
+ INT64 i;
+
+ //
+ // Check if the device supports Multiple sector Read/Write
+ //
+ if ( IdeDevice->IdentifyData.Valid_Bits_59 & 0x100 ) {
+ BlockSize = (UINT8) IdeDevice->IdentifyData.Valid_Bits_59;
+ }
+
+ //
+ // Error Checking
+ //
+ if ( BlockSize == 0 ) {
+ BlockSize = 1;
+ }
+
+ if((IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[13] + \
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+ //
+ // Disable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ if ( Check48BitCommand( Command )) {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO_48BIT;
+ //
+ // if 48 Bit LBA form Upper Dword
+ //
+ LBAHighDword |= LBAHighExp;
+ LBAHighDword = ( Shl64(( Shl64( LBAHighDword, 8)| LBAMidExp), 8)| LBALowExp);
+ }
+ else {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO;
+ }
+ //
+ // Complete LBA
+ //
+ LBA |= LBAHigh;
+ LBA = (( Shl64(( Shl64( LBA, 8) | LBAMid ), 8)| LBALow)| Shl64( LBAHighDword, 24 ));
+
+ //
+ //Calculate the total number of Sectors to be transferred
+ //
+ Total_Number_Of_Sectors = ByteCount / SectorSize; //512
+ // If the caller is requesting less bytes than one sector, we need to
+ // allocate space for one sector.
+ if (!ReadWrite && ((ByteCount < SectorSize) && (ByteCount > 0))) {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ SectorSize,
+ (VOID**)&TempBuffer );
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SectorGTBytes = TRUE;
+ Total_Number_Of_Sectors = 1;
+ } else {
+ TempBuffer = Buffer;
+ }
+
+ for (;
+ Total_Number_Of_Sectors > 0;
+ Total_Number_Of_Sectors -= MaxSectorCount )
+ {
+ if ( Total_Number_Of_Sectors > MaxSectorCount ) {
+ SectorCount = 0;
+ } else {
+ SectorCount = (UINT32) Total_Number_Of_Sectors;
+ }
+
+ Status = IssueAtaReadWriteCommand( IdeBusInterface,
+ LBA,
+ SectorCount,
+ Command,
+ Features );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Update LBA for next loop
+ //
+ if ( SectorCount ) {
+ LBA += SectorCount;
+ LoopCount = (SectorCount / BlockSize);
+ LoopCount += ((SectorCount % BlockSize) > 0 ? 1 : 0);
+ }
+ else {
+ LBA += MaxSectorCount;
+ LoopCount = Div64( MaxSectorCount, BlockSize, &Remainder );
+ LoopCount += (Remainder > 0 ? 1 : 0);
+ }
+
+ //
+ //Read Data
+ //
+ for (; LoopCount > 0; LoopCount -= 1 ) {
+ //
+ //Wait for Command completion
+ //
+ Status = WaitForCmdCompletion( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ //Check for DRQ
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ DRQ,
+ DRQ_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Calculate # of Words to be read/written
+ //
+
+ WordCount = SectorSize / 2;
+
+ if ( ReadWrite ) {
+
+ for ( i=0 ; i<Total_Number_Of_Sectors ;i++ ) {
+
+ Status = IdeWriteMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ WordCount,
+ TempBuffer );
+ ((UINT8*)TempBuffer) += SectorSize;
+ pBS->Stall(100); //10ms Delay after 1 sector write
+ }
+
+ } else {
+
+ for ( i=0 ; i<Total_Number_Of_Sectors ;i++ ) {
+
+ Status = IdeReadMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ WordCount,
+ TempBuffer );
+ (UINT8 *)TempBuffer += SectorSize;
+ pBS->Stall(100); //10ms Delay after 1 sector read
+
+ }
+ ((UINT8*)TempBuffer) -= Mul64( Total_Number_Of_Sectors, SectorSize);
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for errors.
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ &Data8 );
+
+ if ( Data8 & 0x21 ) { // ERR OR DF bit set ?
+ return EFI_DEVICE_ERROR;
+ }
+
+// ((UINT8*)TempBuffer) += (WordCount * 2);
+
+ if ( SectorCount ) {
+ SectorCount -= (WordCount * 2) / SectorSize;
+ }
+ else {
+ SectorCount = (UINT32) ( MaxSectorCount - ((WordCount * 2) / SectorSize));
+ }
+ }
+ }
+ if (SectorGTBytes) {
+ pBS->CopyMem( Buffer, TempBuffer, ByteCount);
+ pBS->FreePool( TempBuffer );
+ }
+
+ //
+ // Check for errors
+ //
+ Status = WaitForCmdCompletion( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IssueAtaReadWriteCommand
+//
+// Description: Issues ATA Read/Write Command
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// UINT64 LBA,
+// INT32 SectorCount,
+// UINT8 Command
+// UINT8 Features OPTIONAL
+//
+// Output:
+// EFI_STATUS
+// Modified:
+//
+// Referrals: AtaReadWritePio
+//
+// Notes:
+// 1. Select the drive.
+// 2. check if BSY and DRQ bits are zero.
+// 3. Issue the command.
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IssueAtaReadWriteCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT64 LBA,
+ IN INT32 SectorCount,
+ IN UINT8 Command,
+ IN UINT8 Features )
+{
+ EFI_STATUS Status;
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Device = (IdeDevice->Device << 4);
+
+ //
+ // Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.DeviceReg, Device );
+
+ //
+ //Before Writing to Sector Count Reg, BSY and DRQ bit should be zero
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY | DRQ,
+ DRQ_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for DRDY
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ DRDY,
+ DRDY_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_TIMEOUT;
+ }
+
+ if ( Check48BitCommand( Command )) {
+ // 48 Bit LBA
+ // Write the Upper LBA DWORD and Upper byte of Sector Count
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.SectorCountReg,
+ (UINT8)( SectorCount >> 8 ));
+
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBALowReg,
+ (UINT8)Shr64( LBA, 24 ));
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAMidReg,
+ (UINT8) Shr64( LBA, 32 ));
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAHighReg,
+ (UINT8) Shr64( LBA, 40 ));
+
+ Device = (IdeDevice->Device << 4) | 0x40; // 48Bit LBA
+ }
+ else { // 28 Bit LBA
+ Device = ((UINT8) ((UINT32) LBA >> 24 ) & 0x0f) | (IdeDevice->Device << 4) | 0x40;
+ }
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ Device );
+
+ //
+ //Issue command
+ //
+ if ( Features ) {
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.FeatureReg, //SubCommand
+ Features );
+ }
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.SectorCountReg,
+ (UINT8) SectorCount );
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBALowReg,
+ (UINT8)LBA );
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAMidReg,
+ (UINT8) (((UINT32)LBA >> 8) & 0xff ));
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAHighReg,
+ (UINT8) (((UINT32)LBA >> 16) & 0xff ));
+
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.CommandReg,
+ Command );
+
+ //
+ //Wait for 400nsec for status to be available
+ //
+ pBS->Stall( 1 );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeNonDataCommand
+//
+// Description: Issues command where no data transfer takes place
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINT32 ByteCount,
+// UINT8 SectorCount,
+// UINT8 LBALow,
+// UINT8 LBAMid,
+// UINT8 LBAHigh,
+// UINT8 Device,
+// UINT8 Command,
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals: IdeSetFeatureCommand
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeNonDataCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT8 Features,
+ IN UINT8 SectorCount,
+ IN UINT8 LBALow,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAHigh,
+ IN UINT8 Device,
+ IN UINT8 Command )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ EFI_STATUS Status;
+ UINT8 Data8;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.DeviceReg, Device );
+
+ //
+ //Wiat for DRDY to be set
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ DRDY,
+ DRDY_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_TIMEOUT;
+ }
+
+ //
+ //Issue the Command
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.FeatureReg,
+ Features );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.SectorCountReg,
+ SectorCount );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBALowReg,
+ LBALow );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAMidReg,
+ LBAMid );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAHighReg,
+ LBAHigh );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.CommandReg,
+ Command );
+
+ //
+ //Wait for 400nsec before reading the status. To accomplish it, read ATL_STATUS and ignore the result
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY | DRQ,
+ gPlatformIdeProtocol->PoweonBusyClearTimeout );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for any errors
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.StatusReg, &Data8 );
+
+ if ( Data8 & (DF | ERR)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeNonDataCommandExp
+//
+// Description: Issues command where no data transfer takes place
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINT32 ByteCount,
+// UINT8 SectorCount,
+// UINT8 SectorCountExp,
+// UINT8 LBALow,
+// UINT8 LBALowExp,
+// UINT8 LBAMid,
+// UINT8 LBAMidExp,
+// UINT8 LBAHigh,
+// UINT8 LBAHighExp,
+// UINT8 Device,
+// UINT8 Command,
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals: IdeSetFeatureCommand
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeNonDataCommandExp(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT8 Features,
+ IN UINT8 SectorCount,
+ IN UINT8 SectorCountExp,
+ IN UINT8 LBALow,
+ IN UINT8 LBALowExp,
+ IN UINT8 LBAMid,
+ IN UINT8 LBAMidExp,
+ IN UINT8 LBAHigh,
+ IN UINT8 LBAHighExp,
+ IN UINT8 Device,
+ IN UINT8 Command )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ EFI_STATUS Status;
+ UINT8 Data8;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.DeviceReg, Device );
+
+ //
+ //Wiat for DRDY to be set
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ DRDY,
+ DRDY_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_TIMEOUT;
+ }
+
+ // 48 Bit LBA
+ // Write the Upper LBA DWORD and Upper byte of Sector Count
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.SectorCountReg,
+ SectorCountExp);
+
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBALowReg,
+ LBALowExp);
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAMidReg,
+ LBAMidExp);
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAHighReg,
+ LBAHighExp);
+
+ //
+ //Issue the Command
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.FeatureReg,
+ Features );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.SectorCountReg,
+ SectorCount );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBALowReg,
+ LBALow );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAMidReg,
+ LBAMid );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAHighReg,
+ LBAHigh );
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.CommandReg,
+ Command );
+
+ //
+ //Wait for 400nsec before reading the status. To accomplish it, read ATL_STATUS and ignore the result
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY | DRQ,
+ gPlatformIdeProtocol->PoweonBusyClearTimeout );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for any errors
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.StatusReg, &Data8 );
+
+ if ( Data8 & (DF | ERR)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtaIdentifyCommand
+//
+// Description: Issues IDENTIFY DATA command (0xEC)
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN OUT VOID *Buffer
+//
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals: AtaPioDataIn
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaIdentifyCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer )
+{
+ EFI_STATUS Status = AtaPioDataIn(
+ IdeBusInterface,
+ Buffer,
+ 512,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ IDENTIFY_COMMAND,
+ FALSE );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AtapiIdentifyCommand
+//
+// Description: Issues IDENTIFY PACKET DATA command (0xA1)
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN OUT VOID *Buffer
+//
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals: AtaPioDataIn
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtapiIdentifyCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer )
+{
+ return AtaPioDataIn(
+ IdeBusInterface,
+ Buffer,
+ 512, // Byte Count
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ IDENTIFY_PACKET_COMMAND,
+ FALSE );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetIdentifyData
+//
+// Description: Gets Identify command data.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: ATA/ATAPI device type should have beeen known already.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetIdentifyData(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer )
+{
+ //
+ //check whether it is a ATA or ATAPI device
+ //
+ if ( IdeBusInterface->IdeDevice.DeviceType == ATAPI ) {
+ return AtaPioDataIn(
+ IdeBusInterface,
+ Buffer,
+ 512, // Byte Count
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ IDENTIFY_PACKET_COMMAND,
+ FALSE );
+ }
+ else {
+ EFI_STATUS Status = AtaPioDataIn(
+ IdeBusInterface,
+ Buffer,
+ 512,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ IDENTIFY_COMMAND,
+ FALSE );
+
+ return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeSetFeatureCommand
+//
+// Description: Issue a ATA Non-Data Command
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeNonDataCommand
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeSetFeatureCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 SubCommand,
+ UINT8 Mode )
+{
+ return IdeNonDataCommand(
+ IdeBusInterface,
+ SubCommand,
+ Mode,
+ 0,
+ 0,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ SET_FEATURE_COMMAND );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeSoftReset
+//
+// Description: Issue a Soft Reset
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: DetectIdeDevice
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeSoftReset(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT8 Device = IdeBusInterface->IdeDevice.Device;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+
+ PROGRESS_CODE( DXE_IDE_RESET );
+
+ //
+ //Select the drive. Not needed.
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ Device << 4 );
+
+ //
+ //Read the status Register
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.StatusReg, &Data8 );
+
+ //
+ //If BSY bit set, don't issue Soft reset
+ //
+ if ( Data8 & 0x80 ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Assert SRST, disable nIEN
+ //
+ Data8 = SRST | nIEN;
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.DeviceControlReg,
+ Data8 );
+ pBS->Stall( 100 ); // 100 usec
+
+ //
+ //Deassert SRST
+ //
+ Data8 = nIEN;
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.DeviceControlReg,
+ Data8 );
+ pBS->Stall( 10000 ); // 10 msec
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitForCmdCompletionWithTimeOutValue
+//
+// Description: Waits for BSY bit to get clear
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+// IN UINT32 TimeOutValue
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AtaReadWritePio
+//
+// Notes: Wait for BSY bit to get clear. Check for any errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitForCmdCompletionWithTimeOutValue(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT32 TimeOutvalue )
+{
+ UINT8 Data8;
+ EFI_STATUS Status;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+
+ // Read ATL_STATUS and ignore the result. Just a delay
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ // if the Timeout Value is 0, check Busy bit to clear without Timeout Value.
+ // Otherwise Use the Timeout value to check the Busy bit to clear.
+ if ( TimeOutvalue == 0 ) {
+ //
+ //Check for BSY bit to be clear without Timout value
+ //
+ Status = WaitforBitClearWithoutTimeout(
+ IdeBusInterface->PciIO,
+ Regs.ControlBlock.
+ AlternateStatusReg,
+ BSY );
+ }
+ else {
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY,
+ TimeOutvalue );
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //Check for errors.
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ &Data8 );
+
+ if ( Data8 & (ERR | DF)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitForCmdCompletion
+//
+// Description: Waits for BSY bit to get clear
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AtaReadWritePio
+//
+// Notes: Wait for BSY bit to get clear. Check for any errors.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitForCmdCompletion(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT8 Data8;
+ EFI_STATUS Status;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+
+ //
+ //Read ATL_STATUS and ignore the result. Just a delay
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY,
+ COMMAND_COMPLETE_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for errors.
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.StatusReg, &Data8 );
+
+ if ( Data8 & (ERR | DF)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: DisableIdeInterrupt
+//
+// Description: Disabled Interrupt generation feature
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void DisableIdeInterrupt(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8, Flags;
+
+ //
+ // Disable IEN
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ //
+ //Clear interrupt status
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.BusMasterBlock.BMStatusRegister,
+ &Data8 );
+ Flags = Data8;
+ //
+ // Preserve DMA capabilities and set Interrupt bit
+ //
+ Data8 = (Data8 & 0x60);
+
+ if ( Flags & BM_INTERRUPT ) {
+ Data8 |= BM_INTERRUPT;
+ }
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.BusMasterBlock.BMStatusRegister,
+ Data8 );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CheckDriveReady
+//
+// Description: Check if BSY is cleared and DRDY set
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckDriveReady(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ IdeBusInterface->IdeDevice.Device << 4 );
+
+ //
+ //Read Alt Status
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.DeviceControlReg,
+ &Data8 );
+
+ if ((Data8 & 0xc0) == 0x40 ) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitforBitSet
+//
+// Description: Checks for a particular Bit to be set for a given amount of time
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// UINT16 AlternateStatusReg,
+// UINT8 BitSet,
+// UINT32 TimeOut
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitforBitSet(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ UINT16 AlternateStatusReg,
+ UINT8 BitSet,
+ UINT32 TimeOut )
+{
+ UINT8 Delay;
+ UINT8 Data8;
+
+ for (; TimeOut > 0; TimeOut-- )
+ {
+ for ( Delay = 100; Delay > 0; Delay-- )
+ {
+ IdeReadByte( PciIO, AlternateStatusReg, &Data8 );
+
+ if ( Data8 & BitSet ) {
+ return EFI_SUCCESS;
+ }
+ pBS->Stall( 10 ); // 10usec
+ }
+ }
+ return EFI_TIMEOUT;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitforBitClear
+//
+// Description: Waits for the given bit to be clear
+//
+// Input:
+// UINT16 AlternateStatus,
+// UINT8 BitClear
+// UINT32 BUSY_CLEAR_TIMEOUT // Millisecond
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitforBitClear(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ UINT16 AlternateStatus,
+ UINT8 BitClear,
+ UINT32 Timeout )
+{
+ UINT8 Delay;
+ UINT8 Data8;
+
+ for (; Timeout > 0; Timeout-- )
+ {
+ for ( Delay = 100; Delay > 0; Delay-- )
+ {
+ IdeReadByte( PciIO, AlternateStatus, &Data8 );
+
+ if ( !(Data8 & BitClear)) {
+ return EFI_SUCCESS;
+ }
+ pBS->Stall( 10 ); // 10 Usec
+ }
+ }
+ return EFI_TIMEOUT;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: WaitforBitClearWithoutTimeout
+//
+// Description: Waits for the given bit to be clear
+//
+// Input:
+// UINT16 AlternateStatus,
+// UINT8 BitClear
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitforBitClearWithoutTimeout(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ UINT16 AlternateStatus,
+ UINT8 BitClear )
+{
+ UINT8 Data8;
+
+ do
+ {
+ IdeReadByte( PciIO, AlternateStatus, &Data8 );
+
+ if ( !(Data8 & BitClear)) {
+ return EFI_SUCCESS;
+ }
+ pBS->Stall( 10 ); // 10 Usec
+ } while ( 1 );
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ReturnMSBset
+//
+// Description: Returns the MOST significant Bit set.
+//
+// Input:
+// UINT32 Data
+//
+// Output:
+// UINT8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 ReturnMSBset(
+ UINT32 Data )
+{
+ UINT8 Index;
+ UINT8 Value = 0xFF;
+
+ for ( Index = 0; Index < 32; Index++ )
+ {
+ if ( Data & 1 ) {
+ Value = Index;
+ }
+ Data >>= 1;
+ }
+
+ return Value;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeReadByte
+//
+// Description: Reads 1 Byte of data from the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// OUT UINT8 *Data8
+//
+// Output:
+// OUT UINT8 *Data8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeReadByte(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ OUT UINT8 *Data8 )
+{
+ PciIO->Io. Read(
+ PciIO,
+ EfiPciIoWidthFifoUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ 1,
+ Data8 );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeReadMultipleByte
+//
+// Description: Reads N Bytes of data from the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// IN UINT64 Count
+// OUT UINT8 *Data8
+//
+// Output:
+// OUT UINT8 *Data8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeReadMultipleByte(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ OUT UINT8 *Data8 )
+{
+ EFI_STATUS Status;
+
+ Status = PciIO->Io.Read(
+ PciIO,
+ EfiPciIoWidthFifoUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ Count,
+ Data8 );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeReadWord
+//
+// Description: Reads 1 Word of data from the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// OUT UINT16 *Data16
+//
+// Output:
+// OUT UINT16 *Data16
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeReadWord(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ OUT UINT16 *Data16 )
+{
+ EFI_STATUS Status;
+
+ Status = PciIO->Io.Read(
+ PciIO,
+ EfiPciIoWidthFifoUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ 1,
+ Data16 );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeReadMultipleWord
+//
+// Description: Reads N Word of data from the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// IN UINT32 Count (Count in WORDS)
+// OUT UINT8 *Data16
+//
+// Output:
+// OUT UINT16 *Data16
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeReadMultipleWord(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ OUT UINT16 *Data16 )
+{
+ EFI_STATUS Status;
+ UINT16 *Buffer = Data16;
+ BOOLEAN MemoryAllocated = FALSE;
+
+ //
+ //Allocate memory only if ADDRESS is not WORD aligned
+ //
+ if ((UINTN)Data16 & 1 ) {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ Count * sizeof(UINT16),
+ (VOID**)&Buffer );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemoryAllocated = TRUE;
+ }
+
+ Status = PciIO->Io.Read(
+ PciIO,
+ EfiPciIoWidthFifoUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ Count,
+ Buffer );
+
+ if ( MemoryAllocated ) {
+ pBS->CopyMem( Data16, Buffer, Count * sizeof(UINT16));
+ pBS->FreePool( Buffer );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeWriteByte
+//
+// Description: Writes 1 Byte of data to the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// OUT UINT8 Data8
+//
+// Output:
+// OUT UINT8 *Data8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeWriteByte(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT8 Data8 )
+{
+ PciIO->Io.Write(
+ PciIO,
+ EfiPciIoWidthFifoUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ 1,
+ &Data8 );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeWriteMultipleByte
+//
+// Description: Writes N Bytes of data to the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// IN UINT32 Count (Count in BYTES)
+// IN UINT8 *Data8
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeWriteMultipleByte(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ IN UINT8 *Data8 )
+{
+ EFI_STATUS Status;
+
+ Status = PciIO->Io.Write(
+ PciIO,
+ EfiPciIoWidthFifoUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ Count,
+ Data8 );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeWriteWord
+//
+// Description: Writes 1 word of data to the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// OUT UINT16 *Data16
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeWriteWord(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT16 Data16 )
+{
+ PciIO->Io.Write(
+ PciIO,
+ EfiPciIoWidthFifoUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ 1,
+ &Data16 );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeWriteMultipleWord
+//
+// Description: Writes N Words of data to the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// IN UINT64 Count (Count in WORDS)
+// IN UINT16 *Data16
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Count : # of WORDs to write
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeWriteMultipleWord(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ IN UINT16 *Data16 )
+{
+ EFI_STATUS Status;
+ UINT16 *Buffer = Data16;
+ BOOLEAN MemoryAllocated = FALSE;
+
+ //
+ // Allocate memory only if ADDRESS is not WORD aligned
+ //
+ if ((UINTN)Data16 & 1 ) {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ Count * sizeof(UINT16),
+ (VOID**)&Buffer );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemoryAllocated = TRUE;
+
+ pBS->CopyMem( Buffer, Data16, Count * sizeof(UINT16));
+ }
+
+ Status = PciIO->Io.Write(
+ PciIO,
+ EfiPciIoWidthFifoUint16,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ Count,
+ Buffer );
+
+ if ( MemoryAllocated ) {
+ pBS->FreePool( Buffer );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IdeWriteDword
+//
+// Description: Writes 1 Dword of data to the IO port
+//
+// Input:
+// IN EFI_PCI_IO_PROTOCOL *PciIO,
+// IN UINT16 Register,
+// OUT UINT16 *Data16
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeWriteDword(
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Data32 )
+{
+ PciIO->Io.Write(
+ PciIO,
+ EfiPciIoWidthFifoUint32,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ Register,
+ 1,
+ &Data32 );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Check48BitCommand
+//
+// Description: Checks if the command is for 48-bit LBA
+//
+// Input:
+// IN UINT8 Command
+//
+// Output:
+// TRUE/FLASE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN Check48BitCommand(
+ IN UINT8 Command )
+{
+ if ( Command == READ_SECTORS_EXT
+ || Command == READ_MULTIPLE_EXT
+ || Command == WRITE_SECTORS_EXT
+ || Command == WRITE_MULTIPLE_EXT
+ || Command == READ_DMA_EXT
+ || Command == WRITE_DMA_EXT ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/Atapi.c b/Core/EM/IdeBus/Atapi.c
new file mode 100644
index 0000000..7230aac
--- /dev/null
+++ b/Core/EM/IdeBus/Atapi.c
@@ -0,0 +1,1811 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/Atapi.c 23 8/16/12 3:24a Rajeshms $
+//
+// $Revision: 23 $
+//
+// $Date: 8/16/12 3:24a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/Atapi.c $
+//
+// 23 8/16/12 3:24a Rajeshms
+// [TAG] EIP97048
+// [Category] New Feature
+// [Description] ATAPI PassThru Support using
+// EFI_EXT_SCSI_PASS_THRU_PROTOCOL.
+// [Files] AhciBus.c, AhciController.c, IdeBus.c, Atapi.c, PIDEBus.h,
+// PAhciBus.h, ScsiPassThruAtapi.sdl, ScsiPassThruAtapi.mak,
+// ScsiPassThruAtapi.c, ScsiPassThruAtapiSupport.h, ScsiPassThruAtapi.chm,
+// ScsiPassThruExt.h
+//
+// 22 11/08/11 5:16a Deepthins
+// [TAG] EIP74607
+// [Category] Improvement
+// [Description] Block IO Read/Write function, the alignment should be
+// proper. IoAlign value is 0 or 1 means that the buffer can be placed
+// anywhere in memory. Otherwise, IoAlign must be a power of 2, and the
+// requirement is that the start address of a buffer must be evenly
+// divisible by IoAlign with no remainder.
+// [Files] Ata.c, Atapi.c and AhciController.c
+//
+// 21 11/07/11 4:27a Deepthins
+// [TAG] EIP74607
+// [Category] Improvement
+// [Description] IoAlign values is 0 or 1 means that the buffer can be
+// placed anywhere in memory. Otherwise, IoAlign must be a power of 2, and
+// the requirement is that the start address of a buffer must be evenly
+// divisible by 2 to the power of IoAlign with no remainder.
+// [Files] Atapi.c
+//
+// 20 9/27/11 3:11a Rajeshms
+// [TAG] EIP69295
+// [Category] New Feature
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 19 5/02/11 12:23a Rameshr
+// [TAG]- EIP 58686
+// [Category]-IMPROVEMENT
+// [Description]- Update implementation of EFI_BLOCK_IO_PROTOCOL as
+// described in UEFI specification Version 2.3.1, page 12.8
+// [Files]- Idebus.c, Atapi.c
+//
+// 18 4/12/11 4:05a Rameshr
+// [TAG]- EIP 53710
+// [Category]- New Feature
+// [Description]- ATAPI ODD loading type information added into ATAPI
+// device structure
+// [Files]- Atapi.c, Idebus.c, IdeBus.h
+//
+// 17 10/11/10 11:28a Krishnakumarg
+// [TAG] - EIP 43249
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Non-Ascii character in comments causing build problem in
+// japanese XP
+// [RootCause]- Presence of Non-Ascii character
+// [Solution] - Remove Non-Ascii character present in the file
+// [Files] - IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 16 8/25/10 4:08a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: All.
+//
+// 15 7/01/09 12:23p Rameshr
+// Coding Standard and File header updated.
+//
+// 14 6/22/09 11:38a Rameshr
+// Odd Type information Saved in Atapi Device Structure.
+// EIP:21548
+//
+// 13 9/30/08 4:43p Felixp
+// Bug fix(EIP 15310):Invalid error code (EFI_DEVICE_ERROR instead of
+// EFI_NO_MEDIA) was returned for removable devices with no media
+//
+// 11 8/07/08 10:05a Rameshraju
+// Interrupt cleared properly on Atapihandleerror.
+//
+// 10 4/22/08 4:29p Felixp
+// New status codes added
+//
+// 9 3/06/08 4:42p Ambikas
+//
+// 8 13/04/07 3:00p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 7 3/13/06 2:21a Felixp
+//
+// 6 3/07/06 8:41a Srinin
+// AtapiReset function returns EFI_SUCCESS
+//
+// 5 3/03/06 11:28a Srinin
+// To detect Media not found error, check for Sense key = 2, ASC = 3A
+// and ASCQ = 0/1/2.
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:07p Srinin
+// For Read Capacity command, available Buffer size is set to 8.
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 9 10/21/05 1:38p Srinin
+// Fixed Media detection problem with slow CDROM.
+//
+// 8 10/06/05 12:59p Felixp
+//
+// 7 7/25/05 12:52p Srinin
+// Delay between successive "TestUnitReady" command changed to 10msec.
+//
+// 6 7/18/05 4:31p Felixp
+// 64-bit compatibility warnings removed
+//
+// 5 3/04/05 11:34a Mandal
+//
+// 4 2/24/05 12:21p Felixp
+// bug fix in AtapiBlkRead and AtapiBlkWrite functions:
+// EFI_INVALID_PARAMETER was returned when last block is read or written
+// to
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 1/05/05 11:21a Srinin
+// BusMaster and Password Support added.
+//
+// 1 12/10/04 1:01p Srinin
+// Initial Checkin of IdeBus Driver.
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ATAPI.C
+//
+// Description: Supports ATAPI devices
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "IdeBus.h"
+#include <Protocol\IdeBusBoard.h>
+
+//
+//External variables
+//
+extern PLATFORM_IDE_PROTOCOL *gPlatformIdeProtocol;
+extern EFI_GUID gEfiBlockIoProtocolGuid;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiReset
+//
+// Description: Issues ATAPI Reset command.
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN BOOLEAN ExtendedVerification
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IssueAtapiReset, InitIdeBlockIO
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiReset(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiBlkRead
+//
+// Description: Read from the Atapi Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AtapiReadWritePio, InitIdeBlockIO
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiBlkRead(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ UINTN DataN;
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ UINT32 BlockSize = BlkMedia->BlockSize;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ UINTN BufferAddress;
+
+ //
+ //Check if Media Present
+ //
+ if ( BlkMedia->MediaPresent == FALSE ) {
+ Status = DetectAtapiMedia( IdeBusInterface );
+
+ if ( Status == EFI_SUCCESS ) {
+ return EFI_MEDIA_CHANGED;
+ }
+ return Status;
+ }
+
+ //
+ //Check if Media ID matches
+ //
+ if ( BlkMedia->MediaId != MediaId ) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((BlkMedia->IoAlign > 1 ) && (BufferAddress % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check whether the block size is multiple of BlkMedia->BlockSize
+ //
+ DataN = BufferSize % BlkMedia->BlockSize;
+
+ if ( DataN ) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ // Check for Valid start LBA #
+ if ( LBA > BlkMedia->LastBlock ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check for Valid End LBA #
+ //
+ DataN = BufferSize / BlkMedia->BlockSize;
+
+ if ( LBA + DataN > BlkMedia->LastBlock + 1 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( ( gPlatformIdeProtocol->IdeBusMasterSupport ) && ( gPlatformIdeProtocol->AtapiBusMasterSupport ) ) {
+ if ( DMACapable( IdeBusInterface )) {
+ Status = AtapiReadWriteBusMaster(
+ IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.ReadCommand,
+ FALSE );
+ return Status;
+ }
+ }
+
+
+ Status = AtapiReadWritePio( IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.ReadCommand,
+ FALSE );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiBlkWrite
+//
+// Description: Write to the Atapi Device
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AtapiReadWritePio, InitIdeBlockIO
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiBlkWrite(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer )
+{
+ UINTN DataN;
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = This->Media;
+ UINT32 BlockSize = BlkMedia->BlockSize;
+ UINTN BufferAddress;
+
+ //
+ // Check if Media Present
+ //
+ if ( BlkMedia->MediaPresent == FALSE ) {
+ Status = DetectAtapiMedia( IdeBusInterface );
+
+ if ( Status == EFI_SUCCESS ) {
+ return EFI_MEDIA_CHANGED;
+ }
+ return Status;
+ }
+
+ //
+ //Check if Media ID matches
+ //
+ if ( BlkMedia->MediaId != MediaId ) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ (VOID *)BufferAddress = Buffer;
+ if((BlkMedia->IoAlign > 1 ) && (BufferAddress % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check whether the block size is multiple of BlkMedia->BlockSize
+ //
+ DataN = BufferSize % BlkMedia->BlockSize;
+
+ if ( DataN ) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ //
+ //Check for Valid start LBA #
+ //
+ if ( LBA > BlkMedia->LastBlock ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ //Check for Valid End LBA #
+ //
+ DataN = BufferSize / BlkMedia->BlockSize;
+
+ if ( LBA + DataN > BlkMedia->LastBlock + 1 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( ( gPlatformIdeProtocol->IdeBusMasterSupport ) && ( gPlatformIdeProtocol->AtapiBusMasterSupport ) ) {
+ if ( DMACapable( IdeBusInterface )) {
+ Status = AtapiReadWriteBusMaster(
+ IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.WriteCommand,
+ TRUE );
+ return Status;
+ }
+ }
+
+
+ Status = AtapiReadWritePio( IdeBusInterface,
+ Buffer,
+ BufferSize,
+ LBA,
+ IdeBusInterface->IdeDevice.WriteCommand,
+ TRUE );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiBlkFlush
+//
+// Description: Flush the cache
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiBlkFlush(
+ IN EFI_BLOCK_IO_PROTOCOL *This )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DetectAtapiMedia
+//
+// Description: Detects whether a Media is present in the ATAPI Removable device or not.
+//
+// Input:
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO
+//
+// Notes:
+// 1. Issue Read Capacity command for CDROM or Read Format command for other ATAPI devices.
+// 2. If step 1 is successfull, update last LBA, Block Size, Read/Write capable, Media ID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectAtapiMedia(
+ IN OUT IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT8 *InputData, *PacketBuffer, LoopCount;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ UINT8 Current_Channel = IdeBusInterface->IdeDevice.Channel;
+ UINT8 Current_Device = IdeBusInterface->IdeDevice.Device;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = IdeBusInterface->IdeBlkIo->BlkIo.Media;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINT16 ByteCount = 256, Data16;
+ BOOLEAN ReadCapacity = FALSE;
+
+ PROGRESS_CODE( DXE_REMOVABLE_MEDIA_DETECT );
+
+ //
+ //Default Values
+ //
+ BlkMedia->MediaPresent = FALSE;
+ BlkMedia->LastBlock = 0x100; // Dummy value
+ IdeBusInterface->IdeDevice.ReadCommand = ATAPI_READ_10;
+ IdeBusInterface->IdeDevice.WriteCommand = ATAPI_WRITE_10;
+
+ Status = TestUnitReady( IdeBusInterface );
+
+ if ((Status != EFI_MEDIA_CHANGED) && (Status != EFI_SUCCESS)) {
+ return Status;
+ }
+
+ //
+ //Issue Read Capacity command
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ ByteCount,
+ (VOID**)&InputData );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&PacketBuffer );
+
+ if ( EFI_ERROR( Status )) {
+ pBS->FreePool( InputData );
+ return Status;
+ }
+
+ ZeroMemory( PacketBuffer, 16 );
+
+ //
+ //For CDROM use Read Capacity command else use Read Format Command
+ //
+ if ( AtapiDevice->DeviceType == CDROM_DEVICE ) {
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE;
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ PacketBuffer[0] = ATAPI_READ_CAPACITY;
+ PacketBuffer[1] = AtapiDevice->Lun << 5;
+ Data16 = 8;
+ }
+ else {
+ BlkMedia->BlockSize = LS120_BLOCK_SIZE;
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ PacketBuffer[0] = ATAPI_READ_FORMAT_CAPACITIES;
+ PacketBuffer[1] = AtapiDevice->Lun << 5;
+ PacketBuffer[7] = ByteCount >> 8;
+ PacketBuffer[8] = ByteCount & 0xff;
+ Data16 = ByteCount;
+ }
+
+ for ( LoopCount = 0; LoopCount < 5; LoopCount++ ) {
+ ByteCount = Data16;
+ ZeroMemory( InputData, ByteCount );
+ Status = GeneralAtapiCommandAndData( IdeBusInterface,
+ PacketBuffer,
+ InputData,
+ &ByteCount );
+
+ if ( PacketBuffer[0] == ATAPI_READ_FORMAT_CAPACITIES
+ && AtapiDevice->Atapi_Status == ILLEGAL_REQUEST ) {
+ //
+ //If the Read Format Capacities not supported by device, try
+ //ReadCapacity command
+ //
+ ZeroMemory( PacketBuffer, 16 );
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE; // Default size
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ PacketBuffer[0] = ATAPI_READ_CAPACITY;
+ PacketBuffer[1] = AtapiDevice->Lun << 5;
+ Data16 = 8;
+ ReadCapacity = TRUE;
+ }
+
+ if ( AtapiDevice->Atapi_Status == EFI_SUCCESS ) {
+ break;
+ }
+
+ if ( AtapiDevice->Atapi_Status == MEDIUM_NOT_PRESENT ) {
+ break;
+ }
+ }
+
+ if ( Status == EFI_SUCCESS ) {
+ if ( ReadCapacity == TRUE ) {
+ BlkMedia->LastBlock = InputData[0] << 24 | InputData[1] << 16
+ | InputData[2] << 8 | InputData[3];
+
+ BlkMedia->LastBlock--;
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->MediaId++;
+ BlkMedia->BlockSize = InputData[4] << 24 | InputData[5] << 16
+ | InputData[6] << 8 | InputData[7];
+
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ BlkMedia->ReadOnly = FALSE;
+ }
+ else if ( AtapiDevice->DeviceType == CDROM_DEVICE )
+ {
+ BlkMedia->LastBlock = InputData[0] << 24 | InputData[1] << 16
+ | InputData[2] << 8 | InputData[3];
+ BlkMedia->LastBlock--;
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE;
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->MediaId++;
+ BlkMedia->ReadOnly = TRUE;
+ }
+ else if ( InputData[8] != 3 ) // No media present
+ {
+ BlkMedia->LastBlock = InputData[4] << 24 | InputData[5] << 16
+ | InputData[6] << 8 | InputData[7];
+ BlkMedia->LastBlock--;
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->MediaId++;
+ BlkMedia->BlockSize = InputData[9] << 16 | InputData[10] << 8
+ | InputData[11];
+ BlkMedia->ReadOnly = FALSE;
+ AtapiDevice->BlockSize = BlkMedia->BlockSize;
+ }
+
+ //
+ // Update ReadOnly Status
+ //
+ if ( AtapiDevice->DeviceType != CDROM_DEVICE ) {
+ ByteCount = 256;
+ ZeroMemory( PacketBuffer, 16 );
+ ZeroMemory( InputData, ByteCount );
+ PacketBuffer[0] = ATAPI_MODE_SENSE;
+ PacketBuffer[2] = RETURN_ALL_PAGES;
+ PacketBuffer[7] = ByteCount >> 8;
+ PacketBuffer[8] = ByteCount & 0xff;
+ Status = GeneralAtapiCommandAndData( IdeBusInterface,
+ PacketBuffer,
+ InputData,
+ &ByteCount );
+
+ if ((Status == EFI_SUCCESS) && (ByteCount > 8)) {
+ BlkMedia->ReadOnly = (InputData[3] & 0x80) != 0 ? TRUE : FALSE;
+ }
+ }
+
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ //
+ // For Atapi Devices, Default set the 1 for logical blocks per PhysicalBlock
+ //
+ BlkMedia->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // For Atapi Devices, Default value set to 0 for Lowest Aligned LBA
+ //
+ BlkMedia->LowestAlignedLba=0;
+
+ BlkMedia->OptimalTransferLengthGranularity=BlkMedia->BlockSize;
+ }
+ }
+
+ pBS->FreePool( InputData );
+ pBS->FreePool( PacketBuffer );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiInquiryData
+//
+// Description: Issues Atapi Inquiry Command and returns the DATA.
+//
+// Input:
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface
+// UINT8 *InquiryData,
+// UINT32 *InquiryDataSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeBlockIO
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiInquiryData(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ OUT UINT8 *InquiryData,
+ IN OUT UINT16 *InquiryDataSize )
+{
+ EFI_STATUS Status;
+ UINT8 *PacketBuffer;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+
+
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&PacketBuffer );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ ZeroMemory( PacketBuffer, 16 );
+ PacketBuffer[0] = ATAPI_INQUIRY;
+ PacketBuffer[1] = AtapiDevice->Lun << 5;
+ PacketBuffer[4] = (UINT8) *InquiryDataSize;
+ Status = GeneralAtapiCommandAndData( IdeBusInterface,
+ PacketBuffer,
+ InquiryData,
+ InquiryDataSize );
+ pBS->FreePool( PacketBuffer );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiReadWritePio
+//
+// Description: Read/Write data from/to the ATAPI device
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINTN ByteCount,
+// UINT64 LBA,
+// UINT8 ReadWriteCommand,
+// BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AtapiBlkRead, AtapiBlkWrite
+//
+// Notes:
+// 1. Prepare ATAPI Command Packet
+// 2. Check for errors. If Media_Change, detect the new atapi media if present and return status accordingly.
+// 3. Read/write data if the command packet is issues successfully.
+// 4. Repeat from step 1 untill all data has been read/written.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiReadWritePio(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE )
+{
+ EFI_STATUS Status;
+ INTN TotalNumberofBlocks;
+ INTN TransferLength;
+ UINT16 BytesRead;
+ UINTN BytesRemainingTobeRead;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ VOID *TempBuffer = Buffer;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+
+ //
+ //Disable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ //
+ //Check for CHK bit in status register before proceeding, if set give ATAPI reset
+ //
+ Status = CheckCHKonEntry( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ TotalNumberofBlocks = ByteCount / AtapiDevice->BlockSize;
+
+ for (; TotalNumberofBlocks > 0; TotalNumberofBlocks -= TransferLength ) {
+ //
+ //Clear the buffer
+ //
+ ZeroMemory( AtapiDevice->PacketBuffer, AtapiDevice->PacketSize );
+
+ //
+ //Calculate # of blocks to be transferred
+ //
+ if ( TotalNumberofBlocks > 0xffff ) {
+ TransferLength = 0xffff;
+ } else {
+ TransferLength = TotalNumberofBlocks;
+ }
+
+ // If the ATAPI device is old, below "ATAPI-3" standard, use one block
+ // per transfer. Some of the old devices don't update the ByteCount value
+ // before setting the DRQ bit. Instead of adding delay, we will transfer 1 block at a time.
+ // Even If this enabled, do it only for CDROM. LS120 write will be very slow if 1 block at time is written.
+ // if (IdeBusInterface->IdeDevice.IdentifyData.Major_Revision_80 < 3) TransferLength = 1;
+
+ // Update the buffer
+ AtapiDevice->PacketBuffer[0] = ReadWriteCommand;
+ AtapiDevice->PacketBuffer[1] = AtapiDevice->Lun << 5;
+ AtapiDevice->PacketBuffer[2] = ((UINT32) LBA) >> 24;
+ AtapiDevice->PacketBuffer[3] = ((UINT32) LBA) >> 16;
+ AtapiDevice->PacketBuffer[4] = ((UINT16) LBA) >> 8;
+ AtapiDevice->PacketBuffer[5] = ((UINT8) LBA) & 0xff;
+
+ AtapiDevice->PacketBuffer[7] = (UINT8)( TransferLength >> 8 ); // MSB
+ AtapiDevice->PacketBuffer[8] = (UINT8)( TransferLength & 0xff ); // LSB
+
+ BytesRemainingTobeRead = TransferLength * AtapiDevice->BlockSize;
+ Status = IssueAtapiPacketCommand( IdeBusInterface,
+ (UINT16*) AtapiDevice->PacketBuffer,
+ 0,
+ 0xffff );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ do
+ {
+ //
+ //Check for errors
+ //
+ Status = HandleAtapiError( IdeBusInterface );
+
+ if ( Status != EFI_SUCCESS ) {
+ //
+ //Check if Device is getting ready. If yes, wait till it gets ready
+ //
+ if ( AtapiDevice->Atapi_Status == BECOMING_READY ) {
+ Status = TestUnitReady( IdeBusInterface );
+ }
+
+ if ( Status == EFI_MEDIA_CHANGED ) {
+ Status = DetectAtapiMedia( IdeBusInterface );
+
+ // This may happen during initial power-up also. If ReinstallProtocol needs to be done,
+ // then differentiate between power-up nad other cases.
+ if ( Status == EFI_SUCCESS ) {
+ return EFI_MEDIA_CHANGED; // Return Media Change
+ }
+ }
+ return Status;
+ }
+
+ //Check if DRQ asserted, else DEVICE error. Since BSY is cleared (HandleAtapiError) when control comes to this
+ //place, a small delay is enough.
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ DRQ,
+ DRQ_SET_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( READWRITE ) {
+ Status = WriteAtapiData( IdeBusInterface,
+ TempBuffer,
+ &BytesRead );
+ }
+ else {
+ Status = ReadAtapiData( IdeBusInterface, TempBuffer, &BytesRead );
+ }
+
+ //
+ //Update pointer
+ //
+ (UINT8*) TempBuffer += BytesRead;
+ BytesRemainingTobeRead -= BytesRead;
+ } while ( BytesRemainingTobeRead );
+
+ LBA += TransferLength;
+ //
+ //Check for errors
+ //
+ Status = HandleAtapiError( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GeneralAtapiCommandAndData
+//
+// Description: Issues the ATAPI cammand and reads the data
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// UINT8 *PacketBuffer,
+// UINT8 *Buffer,
+// IN OUT UINT16 *ByteCount
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GeneralAtapiCommandAndData(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 *PacketBuffer,
+ UINT8 *Buffer,
+ IN OUT UINT16 *ByteCount )
+{
+ EFI_STATUS Status;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+
+ Status = IssueAtapiPacketCommand( IdeBusInterface,
+ (UINT16*)PacketBuffer,
+ 0,
+ *ByteCount );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ //Check for errors
+ //
+ Status = HandleAtapiError( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if ( *ByteCount ) {
+ //
+ //Check if DRQ asserted, else DEVICE error
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ DRQ,
+ DRQ_TIMEOUT );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Read the data
+ //
+ Status = ReadAtapiData( IdeBusInterface, Buffer, ByteCount );
+ //
+ //Check for errors
+ //
+ Status = HandleAtapiError( IdeBusInterface );
+ return Status;
+ } else {
+ *ByteCount = 0;
+ return Status;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssueAtapiPacketCommand
+//
+// Description: Issues ATAPI Packet command and send the packet.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// UINT16 *PacketBuffer, // Pointer to packet
+// UINT16 ByteCount // Byte count Limit
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: The Packet Command and the packet are sent. Error is not analysed in this
+// Routine. Once the packet is sent successfully, EFI_SUCCESS is returned.
+// It is the callers responsibilty to check the status.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IssueAtapiPacketCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT16 *PacketBuffer,
+ IN UINT8 Features,
+ IN UINT16 ByteCount )
+{
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+ UINT16 Data16;
+ EFI_STATUS Status;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+
+ //
+ // Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ IdeDevice->Device << 4 );
+ //
+ // Before Writing to any register check for BSY and DRQ bit. Should be zero
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY | DRQ,
+ gPlatformIdeProtocol->AtaPiBusyClearTimeout );
+
+ if ( EFI_ERROR( Status )) {
+ Status = IssueAtapiReset( IdeBusInterface, TRUE );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ //
+ // Write Feature register. No OVL and DMA
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.FeatureReg,
+ Features );
+
+ //
+ //Write Byte Count
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAMidReg,
+ (ByteCount & 0xff));
+
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAHighReg,
+ (ByteCount >> 8));
+
+ //
+ //Write Command Register
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.CommandReg,
+ PACKET_COMMAND );
+
+ // Wait for 400nsec before reading the status. To accomplish it, read ATL_STATUS and ignore the result.
+ // Assumption is, this call will take atleast 400nsec to complete.
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+ //
+ // Check for BSY bit to be clear 30msec
+ //
+ Data16 = 30;
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ BSY,
+ (UINT32) Data16 );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Check for DRQ set
+ //
+ Status = WaitforBitSet( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ DRQ,
+ (UINT32) Data16 );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Write the Data
+ Status = IdeWriteMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ AtapiDevice->PacketSize / 2,
+ PacketBuffer );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssueAtapiReset
+//
+// Description: Issues ATAPI Reset command
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+// IN BOOLEAN TESTUNITREADY
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// If TESTUNITREADY is TRUE, after ATAPI Reset, TestUnitReady command is issued.
+// Generally after DEVICE RESET command, ATAPI device respond to and command with
+// POWER ON RESET OCCURRED and followed by MEDIA CHANGE.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IssueAtapiReset(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN BOOLEAN TESTUNITREADY )
+
+{
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+ EFI_STATUS Status;
+
+ PROGRESS_CODE( DXE_REMOVABLE_MEDIA_RESET );
+
+ //
+ // Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ IdeDevice->Device << 4 );
+
+ //
+ //Disable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ //
+ //Issue Device reset Command
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.CommandReg,
+ DEVICE_RESET );
+
+ //
+ //Wait for 400nsec before reading the status. To accomplish it, read ATL_STATUS and ignore the result
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check for BSY bit to be clear
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ BSY,
+ gPlatformIdeProtocol->AtaPiResetCommandTimeout );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAMidReg,
+ &Data8 );
+
+ if ( Data8 == (ATAPI_SIGNATURE & 0xff)) {
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.LBAHighReg,
+ &Data8 );
+
+ if ( Data8 == (ATAPI_SIGNATURE >> 8)) {
+ if ( TESTUNITREADY ) {
+ return TestUnitReady( IdeBusInterface );
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: HandleAtapiError
+//
+// Description: Handle Atapi error if any.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: If DF and CHK bits are not set, return EFI_SUCCESS. If either
+// one of the bits are set, analyse the error and return appropraite
+// error message.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HandleAtapiError(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ UINT8 Data8;
+ EFI_STATUS Status;
+ UINT8 *SenseData;
+ UINT8 *SensePacket;
+ UINT16 BytesRead;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ IdeDevice->Device << 4 );
+
+ //
+ //Read the status register
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check if BSY clear else DEVICE error
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ BSY,
+ gPlatformIdeProtocol->AtaPiBusyClearTimeout );
+
+ IdeBusInterface->AtapiSenseDataLength = 0;
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Read the status register
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ //
+ //Check for DF
+ //
+ if ( Data8 & DF ) {
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check for CHK
+ //
+ if ( Data8 & CHK ) {
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 256,
+ (VOID**)&SenseData
+ );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 16,
+ (VOID**)&SensePacket
+ );
+
+ if ( EFI_ERROR( Status )) {
+ pBS->FreePool( SenseData );
+ return Status;
+ }
+
+ //
+ //Update the buffer
+ //
+ ZeroMemory( SenseData, 256 );
+ ZeroMemory( SensePacket, 16 );
+
+ SensePacket[0] = ATAPI_REQUEST_SENSE;
+ SensePacket[4] = 0xff;
+
+ Status = IssueAtapiPacketCommand( IdeBusInterface,
+ (UINT16*) SensePacket,
+ 0,
+ 256 );
+
+ if ( EFI_ERROR( Status )) {
+ goto exit_HandleAtapiError;
+ }
+
+
+ //
+ //Wait for BSY to get cleared
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO,
+ Regs.CommandBlock.StatusReg,
+ BSY,
+ gPlatformIdeProtocol->AtaPiBusyClearTimeout );
+
+ if ( EFI_ERROR( Status )) {
+ goto exit_HandleAtapiError;
+ }
+
+ //
+ //read the status register
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ Status = EFI_DEVICE_ERROR;
+
+ //
+ //Check for DF and CHK
+ //
+ if ( Data8 & (DF | CHK)) {
+ goto exit_HandleAtapiError_with_Reset;
+ }
+
+ //
+ //Check if DRQ asserted, else DEVICE error
+ //
+ if ( !(Data8 & DRQ)) {
+ goto exit_HandleAtapiError_with_Reset;
+ }
+
+ //
+ //Read the data
+ //
+ Status = ReadAtapiData( IdeBusInterface, (UINT16*)SenseData, &BytesRead );
+
+ Status = EFI_DEVICE_ERROR; // Default Value
+ AtapiDevice->Atapi_Status = DEVICE_ERROR;
+
+ //
+ // Store the SenseData whcih would be used by ScsiPassThruAtapi PassThru Interface.
+ //
+ pBS->CopyMem( IdeBusInterface->AtapiSenseData, SenseData, BytesRead);
+ IdeBusInterface->AtapiSenseDataLength = (UINT8)BytesRead;
+
+ if (((SenseData[2] & 0xf) == 2) && (SenseData[12] == 0x3a)) {
+ Status = EFI_NO_MEDIA;
+ AtapiDevice->Atapi_Status = MEDIUM_NOT_PRESENT;
+ }
+
+ if (((SenseData[2] & 0xf) == 2) && (SenseData[12] == 0x04)
+ && (SenseData[13] == 0x01)) {
+ Status = EFI_MEDIA_CHANGED;
+ AtapiDevice->Atapi_Status = BECOMING_READY;
+ }
+
+ if (((SenseData[2] & 0xf) == 6) && (SenseData[12] == 0x28)) {
+ Status = EFI_MEDIA_CHANGED;
+ AtapiDevice->Atapi_Status = MEDIA_CHANGED;
+ }
+
+ if (((SenseData[2] & 0xf) == 7) && (SenseData[12] == 0x27)) {
+ Status = EFI_WRITE_PROTECTED;
+ AtapiDevice->Atapi_Status = WRITE_PROTECTED_MEDIA;
+ }
+
+ if (((SenseData[2] & 0xf) == 6) && (SenseData[12] == 0x29)) {
+ AtapiDevice->Atapi_Status = POWER_ON_OR_DEVICE_RESET;
+ }
+
+ if (((SenseData[2] & 0xf) == 5) && (SenseData[0] == 0x70)) {
+ AtapiDevice->Atapi_Status = ILLEGAL_REQUEST;
+ }
+
+exit_HandleAtapiError:
+ pBS->FreePool( SenseData );
+ pBS->FreePool( SensePacket );
+ return Status;
+
+exit_HandleAtapiError_with_Reset:
+ IssueAtapiReset( IdeBusInterface, TRUE );
+ goto exit_HandleAtapiError;
+ }
+
+ AtapiDevice->Atapi_Status = EFI_SUCCESS;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: TestUnitReady
+//
+// Description: Issues Start/Stop unit Command
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS EFI_SUCCESS : If Media is accessible
+// EFI_NO_MEDIA
+// EFI_MEDIA_CHANGED
+// EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TestUnitReady(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+ UINT8 *Packet;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ UINT16 ByteCount = 0;
+ UINT16 LoopCount;
+
+
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&Packet );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ ZeroMemory( Packet, 16 );
+ Packet[0] = ATAPI_TEST_UNIT_READY;
+ Packet[1] = AtapiDevice->Lun << 5;
+
+ for ( LoopCount = 0; LoopCount < 1000; LoopCount++ )
+ {
+ Status = GeneralAtapiCommandAndData( IdeBusInterface,
+ Packet,
+ NULL,
+ &ByteCount );
+
+ if ( Status == EFI_SUCCESS ) {
+ break;
+ }
+
+ if ( AtapiDevice->Atapi_Status == MEDIUM_NOT_PRESENT ) {
+ break;
+ }
+
+ if ( AtapiDevice->Atapi_Status == MEDIA_CHANGED ) {
+ break;
+ }
+ pBS->Stall( 10000 ); // 10msec
+ }
+
+ pBS->FreePool( Packet );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetOddType
+//
+// Description: Find the ODD device Type and return it
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// OUT UINT16 *OddType
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetOddType(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT UINT16 *OddType )
+{
+ EFI_STATUS Status;
+ UINT8 *PacketBuffer;
+ UINT8 *ProfileData;
+ UINT16 ProfileDataSize = 16;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&PacketBuffer );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&ProfileData );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ ZeroMemory( ProfileData, 16 );
+ ZeroMemory( PacketBuffer, 16 );
+ PacketBuffer[0] = ATAPI_GET_CONFIGURATION;
+ //
+ // Get the Feature Discriptor.
+ //
+ PacketBuffer[1] = FEATURE_DISCRIPTOR;
+ //
+ // Get the Profile list
+ //
+ PacketBuffer[3] = GET_PROFILE_LIST;
+ //
+ // Responce Data Size
+ //
+ PacketBuffer[8] = 0x10;
+
+ Status = GeneralAtapiCommandAndData( IdeBusInterface,
+ PacketBuffer,
+ ProfileData,
+ &ProfileDataSize );
+
+ if ( !EFI_ERROR( Status )) {
+ //
+ // Get the Profile Number
+ //
+ *OddType = (UINT16 )(((ProfileData[sizeof(GET_CONFIGURATION_HEADER) + 4]) << 8)
+ + ProfileData[sizeof(GET_CONFIGURATION_HEADER) + 5] );
+ }
+
+ pBS->FreePool( PacketBuffer );
+ pBS->FreePool( ProfileData );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetOddLoadingType
+//
+// Description: Find the ODD Loading Type information and return it
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// OUT UINT16 *OddLoadingType
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetOddLoadingType(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT UINT8 *OddLoadingType )
+{
+ EFI_STATUS Status;
+ UINT8 *PacketBuffer;
+ UINT8 *ProfileData;
+ UINT16 ProfileDataSize = 16;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&PacketBuffer );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Status = pBS->AllocatePool( EfiBootServicesData, 16, (VOID**)&ProfileData );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ ZeroMemory( ProfileData, 16 );
+ ZeroMemory( PacketBuffer, 16 );
+ PacketBuffer[0] = ATAPI_GET_CONFIGURATION;
+ //
+ // Get the Feature Discriptor.
+ //
+ PacketBuffer[1] = FEATURE_DISCRIPTOR;
+ //
+ // Get the Removable Medium feature
+ //
+ PacketBuffer[3] = GET_REMOVEABLE_MEDIUM_FEATURE;
+ //
+ // Responce Data Size
+ //
+ PacketBuffer[8] = 0x10;
+
+ Status = GeneralAtapiCommandAndData( IdeBusInterface,
+ PacketBuffer,
+ ProfileData,
+ &ProfileDataSize );
+
+ if ( !EFI_ERROR( Status )) {
+ //
+ // Get the ODD Loading Type
+ //
+ *OddLoadingType=(UINT8 )(((ProfileData[sizeof(GET_CONFIGURATION_HEADER)+4]) & 0xE0) >> 5);
+ }
+
+ pBS->FreePool( PacketBuffer );
+ pBS->FreePool( ProfileData );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckCHKonEntry
+//
+// Description: Check for CHK bit. If set Issue ATAPI reset.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckCHKonEntry(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ IDE_DEVICE_INTERFACE *IdeDevice = &(IdeBusInterface->IdeDevice);
+ UINT8 Data8;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DeviceReg,
+ IdeDevice ->Device << 4 );
+
+ //
+ //Disable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ //
+ //Read Status
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ Regs.ControlBlock.AlternateStatusReg,
+ &Data8 );
+
+ if ( Data8 & CHK ) {
+ return (IssueAtapiReset( IdeBusInterface, TRUE ));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ReadAtapiData
+//
+// Description: Read data from the data port based on Byte count value
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// OUT UINT8 AtapiCommand
+// OUT UINT16 *BytesRead
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadAtapiData(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ OUT void *Data,
+ OUT UINT16 *BytesRead )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+ UINT16 ByteCount = 0;
+ EFI_STATUS Status;
+
+ //
+ //Get the number of Bytes to read
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAHighReg, &Data8 );
+ ByteCount = Data8 << 8;
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAMidReg, &Data8 );
+ ByteCount |= Data8;
+
+ *BytesRead = ByteCount;
+ Status = IdeReadMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ ByteCount / 2,
+ Data );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: WriteAtapiData
+//
+// Description: Write data to the data port based on Byte count value
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// OUT UINT8 AtapiCommand
+// OUT UINT16 *BytesRead
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteAtapiData(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ OUT void *Data,
+ OUT UINT16 *BytesRead )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+ UINT16 ByteCount = 0;
+ EFI_STATUS Status;
+
+ //
+ //Get the number of Bytes to Write
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAHighReg, &Data8 );
+ ByteCount = Data8 << 8;
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.LBAMidReg, &Data8 );
+ ByteCount |= Data8;
+
+ *BytesRead = ByteCount;
+ Status = IdeWriteMultipleWord( IdeBusInterface->PciIO,
+ Regs.CommandBlock.DataReg,
+ ByteCount / 2,
+ Data );
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/IDEBusComponentName.c b/Core/EM/IdeBus/IDEBusComponentName.c
new file mode 100644
index 0000000..95b8a2f
--- /dev/null
+++ b/Core/EM/IdeBus/IDEBusComponentName.c
@@ -0,0 +1,374 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IDEBusComponentName.c 17 10/11/10 11:29a Krishnakumarg $
+//
+// $Revision: 17 $
+//
+// $Date: 10/11/10 11:29a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IDEBusComponentName.c $
+//
+// 17 10/11/10 11:29a Krishnakumarg
+// [TAG] - EIP 43249
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Non-Ascii character in comments causing build problem in
+// japanese XP
+// [RootCause]- Presence of Non-Ascii character
+// [Solution] - Remove Non-Ascii character present in the file
+// [Files] - IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 16 8/25/10 4:13a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+// IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+// IdeHpa.c, IdePowerManagement.c
+//
+// 15 8/28/09 11:21a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 14 7/01/09 12:24p Rameshr
+// Coding Standard and File header updated.
+//
+// 13 3/04/08 7:51p Felixp
+//
+// 11 28/02/08 7:01p Anandakrishnanl
+// Changed the Protocol member as defined for IdeSecurity.
+//
+// 10 4/30/07 1:16p Srinin
+// Check for valid Child Controller handle added.
+//
+// 9 4/20/07 6:13p Felixp
+//
+// 8 13/04/07 3:02p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 7 4/10/07 9:05a Felixp
+// Bug fix: undeclared identifier
+//
+// 6 4/05/07 12:54p Srinin
+// IdeBusCtlGetControllerName modified to check for valid controller and
+// Child Handles.
+//
+// 5 3/13/06 2:21a Felixp
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:11p Srinin
+// Component name will be returned if either BLOCK_IO or SECURITY
+// Protocol is installed on the device.
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 7 3/04/05 11:36a Mandal
+//
+// 6 2/02/05 2:10p Felixp
+//
+// 5 2/01/05 1:01p Srinin
+// Fixed Build errors when library is not used.
+//
+// 4 1/31/05 11:06a Srinin
+// Return proper ComponentName for IDE devices.
+//
+// 3 1/28/05 1:19p Felixp
+// IdeBus is linked together with CORE_DXE
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/10/04 1:01p Srinin
+// Initial Checkin of IdeBus Driver.
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IDEBusComponentName.c
+//
+// Description: Component Name Protocol Member Functions for IDE Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include "IdeBus.h"
+#include <Protocol\IdeBusBoard.h>
+
+//
+//External variables
+//
+
+extern EFI_DRIVER_BINDING_PROTOCOL gIdeBusDriverBinding;
+extern PLATFORM_IDE_PROTOCOL *gPlatformIdeProtocol;
+extern EFI_GUID gSecurityModeProtocolGuid;
+static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+
+extern BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2 );
+
+EFI_STATUS IdeBusCtlDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName );
+
+EFI_STATUS IdeBusCtlGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName );
+
+
+CHAR16 *gIdeBusDriverName = L"AMI IDE BUS Driver";
+CHAR16 *gIdeBusControllerName = L"PCI IDE Mass Storage Device";
+
+
+EFI_COMPONENT_NAME_PROTOCOL gIdeBusControllerDriverName = {
+ IdeBusCtlDriverName,
+ IdeBusCtlGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: IdeBusCtlDriverName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// RETURN:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS IdeBusCtlDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName )
+{
+ //
+ //Supports only English
+ //
+ if ( !Language || !DriverName ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) {
+ return EFI_UNSUPPORTED;
+ }
+ *DriverName = gIdeBusDriverName;
+ return EFI_SUCCESS;
+}
+
+//---------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// FUNCTION: IdeBusCtlGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// RETURNS:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//---------------------------------------------------------------------------
+EFI_STATUS IdeBusCtlGetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ SECURITY_PROTOCOL *IdeSecurityInterface;
+ UINTN j, InfoCount;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *pInfo;
+
+ Status = pBS->OpenProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ NULL,
+ gIdeBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if ( Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Supports only English
+ //
+ if ( !Language || !ControllerName ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ( ChildHandle == NULL ) {
+ *ControllerName = gIdeBusControllerName;
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Make sure the CHILD handle is really a child of controller
+ //
+ Status = pBS->OpenProtocolInformation(
+ Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ &pInfo, &InfoCount
+ );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+ for ( j = 0; j < InfoCount; j++ )
+ {
+ if ( pInfo[j].Attributes != EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ) {
+ continue;
+ }
+
+ if ( pInfo[j].ControllerHandle == ChildHandle ) {
+ break;
+ }
+ }
+
+ if ( InfoCount ) {
+ pBS->FreePool( pInfo );
+ }
+
+ if ( j >= InfoCount ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Open the BLOCK_IO protocol installed on the child device.
+ //
+ Status = pBS->OpenProtocol( ChildHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID**)&BlkIo,
+ gIdeBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if ( EFI_ERROR( Status )) {
+ //
+ //If BLKIO protocol is not installed, maybe Securitymode protocol is installed.
+ //
+ Status = pBS->OpenProtocol( ChildHandle,
+ &gSecurityModeProtocolGuid,
+ (VOID**)&IdeSecurityInterface,
+ gIdeBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ //
+ //Return Error.
+ //
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+ IdeBusInterface = IdeSecurityInterface->BusInterface;
+ }
+ else {
+ IdeBusInterface = ((IDE_BLOCK_IO*)BlkIo)->IdeBusInterface;
+ }
+
+ if ( IdeBusInterface->IdeDeviceHandle != ChildHandle ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *ControllerName = IdeBusInterface->IdeDevice.UDeviceName->UnicodeString;
+ return EFI_SUCCESS;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/IdeBus.c b/Core/EM/IdeBus/IdeBus.c
new file mode 100644
index 0000000..9a91cc7
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBus.c
@@ -0,0 +1,3607 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBus.c 65 8/16/12 3:01a Rajeshms $
+//
+// $Revision: 65 $
+//
+// $Date: 8/16/12 3:01a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBus.c $
+//
+// 65 8/16/12 3:01a Rajeshms
+// [TAG] EIP97048
+// [Category] New Feature
+// [Description] ATAPI PassThru Support using
+// EFI_EXT_SCSI_PASS_THRU_PROTOCOL.
+// [Files] AhciBus.c, AhciController.c, IdeBus.c, Atapi.c, PIDEBus.h,
+// PAhciBus.h, ScsiPassThruAtapi.sdl, ScsiPassThruAtapi.mak,
+// ScsiPassThruAtapi.c, ScsiPassThruAtapiSupport.h, ScsiPassThruAtapi.chm,
+// ScsiPassThruExt.h
+//
+// 64 8/16/12 2:25a Anandakrishnanl
+// [TAG] EIP97113
+// [Category] Improvement
+// [Description] AtaPassThru - Module Enhancement
+// [Files] AtaPassThru.c,
+// AtaPassThruSupport.h,AtaPassThru.mak,IdeBus.c,AhciBus.c
+//
+// 63 8/13/12 10:19a Artems
+// [TAG] EIP97928
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System doesn't detect drives in IDE mode
+// [RootCause] Ide driver returns EFI_ERROR if AtaPassThru protocol is
+// absent
+// [Solution] Make driver to return EFI_SUCCESS as long as there are no
+// IDE-related errors
+// [Files] Idebus.c
+//
+// 62 7/20/12 6:13a Anandakrishnanl
+// [TAG] EIP88683
+// [Category] New Feature
+// [Description] EFI_ATA_PASS_THRU_PROTOCOL Support for Aptio IDE
+// [Files] AhciBus.c
+// AhciBus.h
+// AInt13.h
+// IdeBus.c
+// IdeBus.h
+// PIDEBus.h
+// PAhciBus.h
+// AtaPassThru.sdl
+// AtaPassThru.mak
+// AtaPassThru.c
+// AtaPassThruSupport.h
+// AtaPassThru.chm
+//
+// 61 6/13/12 8:49a Anandakrishnanl
+// [TAG] EIP92381
+// [Category] Improvement
+// [Description] A slip of pen in function IdeBusStart
+// [Files] IdeBus.c
+//
+// 60 12/05/11 6:12p Rajkumarkc
+// [TAG] EIP77142
+// [Category] Improvement
+// [Description] Added the function 'IdeNonDataCommandExp' in the
+// 'IDE_BUS_PROTOCOL' and removed
+// the existing function 'IdeNonDataCommand' for supporting
+// the upper 24bits of LBA.
+// [Files]
+// Ata.c
+// IdeBus.c
+// Idebus.h
+// PIDEBus.h
+//
+// 59 11/16/11 12:35a Rameshr
+// [TAG] EIP74970
+// [Category] Improvement
+// [Description] Generic GUID variables should be defined as static, or
+// not used at all
+// [Files] Idebus.c
+//
+// 57 11/04/11 5:45a Rameshr
+// [TAG] EIP73035
+// [Category] Improvement
+// [Description] Status used on line 2561, conditionally not set.
+// Initilized to EFI_SUCCESS to avoid Junk values.
+// [Files] Idebus.c
+//
+// 56 11/03/11 6:07a Rajeshms
+// [TAG] EIP73260
+// [Category] Improvement
+// [Description] IDE Driver Follow the UEFI Driver Model as per the UEFI
+// Spec. and STOP function was Verified.
+// [Files] IdeBus.c
+//
+// 55 9/27/11 3:13a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 54 8/22/11 2:56a Anandakrishnanl
+// [TAG] EIP62912
+// [Category] Improvement
+// [Description] Opal Security Definitions Should be Moved to PIDEBUS.h
+// from StorageSecurityProtocol.h
+// StorageSecurityProtocol.h included in OPAL security driver module will
+// give build error when disabled without sdl token #if
+// OpalSecurity_SUPPORT properly placed in Ahcibus and IdeBus drivers. But
+// Bus driver should not depend on any tokens. For this reason need to
+// move OPAL_SEC_INIT_PROTOCOL_GUID in Pidebus.h
+// [Files] IdeBus.c
+// Pidebus.h
+// OpalSecurity.cif
+// OpalSecurity.h
+// IdeOpalSec.c
+// AhciOpalSec.c
+//
+// 53 7/07/11 2:04a Lavanyap
+// [TAG] EIP60503
+// [Description] Added proper comment in InitAcousticSupport() function
+// header
+// [Files] IdeBus.c
+//
+// 52 7/07/11 1:56a Lavanyap
+// [TAG] EIP55207
+// [Category] Improvement
+// [Description] Ide Bus Drive Component Name does not remove trailing
+// spaces from drive name
+// [Files] IdeBus.c
+//
+// 51 6/13/11 1:27p Artems
+// Made file build when OpalSecurity module is absent
+//
+// 50 5/19/11 3:10a Anandakrishnanl
+// [TAG] EIP53565
+// [Category] New Feature
+// [Description] UEFI2.3+ Specifications defines Storage Security
+// protocol which needs to be implemented.
+// [Files] AhciBus.c,IdeBus.c,AHCIOpalSec.c,IDEOpalSec.c,OpalSecurity.c
+// ,OpalSecurity.chm,OpalSecurity.cif,OpalSecurity.h,OpalSecurity.mak,Opal
+// Security.sdl,PIDEBus.h,StorageSecurityProtocol.CIF,StorageSecurityProto
+// col.h
+//
+// 49 5/02/11 12:38a Rameshr
+// [TAG]- EIP 58703
+// [Category]-IMPROVEMENT
+// [Description]- Implement correct behavior when RemainingDevicePath
+// passed to Supported() function consist only of end node, as described
+// in UEFI specification Version 2.3.1, page 10.1
+// EFI_DRIVER_BINDING_PROTOCOL.Supported() and Start()
+// [Files]- Idebus.c
+//
+// 48 5/02/11 12:23a Rameshr
+// [TAG]- EIP 58686
+// [Category]-IMPROVEMENT
+// [Description]- Update implementation of EFI_BLOCK_IO_PROTOCOL as
+// described in UEFI specification Version 2.3.1, page 12.8
+// [Files]- Idebus.c, Atapi.c
+//
+// 47 4/12/11 4:05a Rameshr
+// [TAG]- EIP 53710
+// [Category]- New Feature
+// [Description]- ATAPI ODD loading type information added into ATAPI
+// device structure
+// [Files]- Atapi.c, Idebus.c, IdeBus.h
+//
+// 46 12/23/10 3:54a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 45 9/24/10 2:43a Rameshr
+// [TAG]- EIP 42817
+// [Category]-IMPROVEMENT
+// [Description]- Ide Smart checks HDDs for errors moved after Idebus
+// Device path has been installed.
+// [Files]- AhciBus.c, IdeBus.c
+//
+// 44 8/25/10 4:16a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+// IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+// IdeHpa.c, IdePowerManagement.c
+//
+// 43 7/20/10 4:18p Pats
+// EIP 38384: Sytem will get halt with the P-ATA to S-ATA transfer card on
+// APTIO 4.6.4.
+// Problem: Feature and Sector Count values are reversed in the invocation
+// of IdeNonDataCommand to set DEV_CONFIG_FREEZE_LOCK.
+// Solution: Fixed Feature and Sector Count values.
+//
+// 42 5/26/10 6:02a Rameshr
+// Checked the Device Configuration Overlay feature set supported status
+// before sending the DEV_CONFIG_FREEZE_LOCK
+// EIP 38384
+//
+// 41 4/16/10 4:05p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 40 1/11/10 12:10p Krishnakumarg
+// Update for Eip 11835 - To implement Acoustic Management function
+// Eip 30041 - Aptio 4 Device Initiated Power Management (DipM) support
+// for SATA devices
+//
+// 39 9/04/09 3:29p Krishnakumarg
+// Acoustic Management function updated to set acoustic level according to
+// setup option EIP:11835
+// CreateIdeDevicePath will now use EFI_OPEN_PROTOCOL_GET_PROTOCOL instead
+// of EFI_OPEN_PROTOCOL_BY_DRIVER in openprotocol function.
+//
+// 38 8/28/09 11:21a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 37 7/01/09 12:23p Rameshr
+// Coding Standard and File header updated.
+//
+// 36 6/22/09 11:38a Rameshr
+// Odd Type information Saved in Atapi Device Structure.
+// EIP:21548
+//
+// 35 5/01/09 11:01a Rameshr
+// Symptom: Disconnect the IDE controller, make system to hang on debug
+// mode
+// Solution: IdeBlockIoDev pointer has wrong address, that make Freepool
+// to hang the system. Corrected the IdeBlockIoDev address
+//
+// 34 4/28/09 7:17p Rameshr
+// HDD password support in RAID mode
+// EIP:20421
+//
+// 33 4/14/09 1:01p Rameshr
+// When INTEL_IDE_PROTOCOL = 1, the IdeBus driver does not check if modes
+// are valid in the SupportedModes data before assigning them to
+// IdeBusInterface
+// EIP 21195
+//
+// 32 11/02/09 11:16a Anandakrishnanl
+// BUGFIX: Removed ASSERT Since AhciBus Driver presence may return Status
+// Other than Success
+//
+// 31 12/31/08 3:07p Rameshraju
+// BugFix- Validate the PIO mode before programming the PIO mode into the
+// device EIP:17885
+//
+// 30 14/08/08 10:52a Anandakrishnanl
+// Compatible Mode AHCI Support Added and Sdl Token Added in IdeBusSrc.sdl
+//
+// 29 8/06/08 10:37a Rameshraju
+// Corrected problem in debug info print.
+//
+// 28 5/14/08 4:43p Rameshraju
+// Error code added if error happens while configuring device or
+// controller.
+//
+// 27 4/22/08 2:02p Felixp
+// DXE_IDE_DETECT progress code moved from ATA.c to IdeBus.c
+// DXE_IDE_ENABLE progress code added
+//
+// 26 3/27/08 11:21a Srinin
+// CreateIdeDevicePath() modified to create a devicepath
+// even if Remaining devicepath is not NULL.
+//
+// 25 7/03/08 5:45p Anandakrishnanl
+// Added Smart related Changes since Smart is a seperate driver now and
+// smart calls are now made protocol driven. Removed Sdl tokens that are
+// used previously
+//
+// 24 3/06/08 5:20p Ambikas
+//
+// 23 3/06/08 4:41p Ambikas
+//
+// 22 3/04/08 7:51p Felixp
+//
+// 20 28/02/08 7:07p Anandakrishnanl
+// Added HddSecurity Protocol to support security module as a separate
+// driver.
+//
+// 19 10/23/07 4:17p Felixp
+// IDE Security support moved from Sources to Binary
+//
+// 18 22/06/07 12:40p Anandakrishnanl
+// HardDisk Security Support Module Added.
+// Need ACPI Module and SB Module and under Core\Include we updated
+// Setup.h.
+// Also New IdeBus bin module.
+//
+// 17 5/04/07 12:53p Srinin
+// In AHCI and RAID mode, PI reg is ignored. Always controller is in
+// Native mode.
+//
+// 16 4/19/07 12:55p Felixp
+// - Minor bug fix: initialize block size by default with
+// CDROM_BLOCK_SIZE for ATAPI devices (along with DiskIo.c changes
+// resolves SCT failure)
+// - File reformatted to comply with AMI coding standards
+//
+// 13 4/16/07 6:29p Felixp
+// Minor bug fix: initialize block size by default with CDROM_BLOCK_SIZE
+// for ATAPI devices
+//
+// 12 13/04/07 3:01p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 11 12/19/06 6:12p Srinin
+// Software setting Preserve bit set for SATA devices.
+//
+// 10 11/17/06 3:05p Ambikas
+//
+// 9 10/27/06 4:20p Felixp
+// enable IDE interrupts at the exit boot services event handler
+// (required to boot EFI vista)
+//
+// 8 8/09/06 3:34p Pavell
+//
+// 7 5/19/06 10:30p Felixp
+// Device Path code updated to use NODE_LENGTH macros to remove direct
+// access to the Length field
+//
+// 6 3/21/06 4:42p Srinin
+// Build error Fixed.
+//
+// 5 3/13/06 2:20a Felixp
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:04p Srinin
+// CallBack added to support HDD password support during S3 Resume.
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 16 11/03/05 10:55a Srinin
+// For Busmaster transfer, Buffer should be DWORD aligned.
+//
+// 15 10/21/05 1:39p Srinin
+// Removed Media detection for Atapi devices during Detection process.
+//
+// 14 8/22/05 4:31p Srinin
+// ATA/ATAPI identification changed.
+//
+// 13 2/11/05 6:16p Felixp
+// - Cleanup (duplication of library functions removed)
+// - Code optimized by using DPAddNode instead of DPAdd
+// - AllocatePool + ZeroMem replaced with MallocZ
+//
+// 12 2/01/05 12:58p Srinin
+// IDE HotPlug Support added.
+//
+// 11 1/31/05 11:14a Srinin
+// Fixed ComponentName display issue for IDE devices.
+//
+// 10 1/28/05 1:19p Felixp
+// IdeBus is linked together with CORE_DXE
+//
+// 9 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 8 1/13/05 4:23p Srinin
+// Host Protection Area Support added.
+//
+// 7 1/11/05 2:26p Srinin
+// IDE Power Management Support added.
+//
+// 5 1/10/05 11:29a Srinin
+// SMART Support added.
+//
+// 4 1/05/05 3:55p Srinin
+// Acoustic management Support added.
+//
+// 3 1/05/05 11:21a Srinin
+// BusMaster and Password Support added.
+//
+// 2 12/21/04 4:57p Markw
+// Modified device path defines for consistency.
+//
+// 1 12/10/04 1:01p Srinin
+// Initial Checkin of IdeBus Driver.
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IdeBus.c
+//
+// Description: Provides IDE Block IO protocol
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "IdeBus.h"
+#include <Protocol\IdeBusBoard.h>
+
+static EFI_GUID gEfiIdeBusInitProtocolGuid = IDE_BUS_INIT_PROTOCOL_GUID;
+static EFI_GUID gIdeBusDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+static EFI_GUID gEfiIdeDiskInfoProtocolGuid = EFI_DISK_INFO_IDE_INTERFACE_GUID;
+static EFI_GUID gIdeSetupProtocolguid = IDE_SETUP_PROTOCOL_GUID;
+static EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+static EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+static EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+static EFI_GUID gHddSecurityInitProtocolGuid = HDD_SECURITY_INIT_PROTOCOL_GUID;
+static EFI_GUID gHddSmartInitProtocolGuid = HDD_SMART_INIT_PROTOCOL_GUID;
+static EFI_GUID gHddSecurityEndProtocolGuid = HDD_SECURITY_END_PROTOCOL_GUID;
+static EFI_GUID gPlatformIdeProtocolGuid = PLATFORM_IDE_PROTOCOL_GUID;
+static EFI_GUID gOpalSecInitProtocolGuid = OPAL_SEC_INIT_PROTOCOL_GUID;
+static EFI_GUID gSMARTProtocolGuid = IDE_SMART_INTERFACE_GUID;
+static EFI_GUID gAtaPassThruInitProtocolGuid = ATA_PASS_THRU_INIT_PROTOCOL_GUID;
+static EFI_GUID gScsiPassThruAtapiInitProtocolGuid = SCSI_PASS_THRU_ATAPI_INIT_PROTOCOL_GUID;
+
+EFI_GUID gSecurityModeProtocolGuid = IDE_SECURITY_INTERFACE_GUID;
+EFI_GUID gPowerMgmtProtocolGuid = IDE_POWER_MGMT_INTERFACE_GUID;
+EFI_GUID gHPAProtocolGuid = IDE_HPA_INTERFACE_GUID;
+
+
+EFI_EVENT gIDEBusEvtBootScript = NULL;
+EFI_EVENT gIDEBusEvtMiscSmmFeatures = NULL;
+
+SCSI_PASS_THRU_ATAPI_INIT_PROTOCOL *gScsiPassThruAtapiInitProtocol;
+ATA_PASS_THRU_INIT_PROTOCOL *AtaPassThruInitProtocol;
+OPAL_SECURITY_INIT_PROTOCOL *OpalSecInitProtocol;
+HDD_SECURITY_INIT_PROTOCOL *HddSecurityInitProtocol;
+HDD_SMART_INIT_PROTOCOL *HddSmartInitProtocol;
+IDE_SETUP_PROTOCOL *gIdeSetupProtocol;
+PLATFORM_IDE_PROTOCOL *gPlatformIdeProtocol;
+
+extern EFI_COMPONENT_NAME_PROTOCOL gIdeBusControllerDriverName;
+
+//
+// Instantiate PLATFORM_IDE_PROTOCOL with default SDL Token values
+//
+
+PLATFORM_IDE_PROTOCOL gPlatformIdeProtocolInstance = {
+ 2, //Protocol Revision
+ 1, //MasterSlaveEnumeration
+ 1, //IdeBusMasterSupport
+ 1, //AtapiBusMasterSupport
+ 1, //AcousticManagementSupport
+ 0, //IdePowerManagementSupport
+ 5, //StandbyTimeout
+ 0, //AdvPowerManagementSupport
+ 1, //AdvPowerManagementLevel
+ 0, //PowerupInStandbySupport
+ 0, //PowerupInStandbyMode
+ 0, //IdePwrManagementInterfaceSupport
+ 0, //HostProtectedAreaSupport
+ 0, //IdeHPSupport
+ 1, //EfiIdeProtocol
+ 0, //AhciCompatibleMode
+ 0, //SBIdeSupport
+ 1, //HddPowerLossInS3
+ 0, //DiPMSupport
+ 0, //DisableSoftSetPrev
+ 0, //ForceHddPasswordPrompt
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL_GUID, //gIdeControllerProtocolGuid
+ EFI_COMPONENT_NAME_PROTOCOL_GUID, //gComponentNameProtocolGuid
+ 10000, //S3BusyClearTimeout
+ 5000, //DmaAtaCompleteCommandTimeout
+ 16000, //DmaAtaPiCompleteCommandTimeout
+ 5000, //AtaPiResetCommandTimeout
+ 16000, //AtaPiBusyClearTimeout
+ 10000 //PoweonBusyClearTimeout
+};
+
+EFI_DRIVER_BINDING_PROTOCOL gIdeBusDriverBinding = {
+ IdeBusSupported,
+ IdeBusStart,
+ IdeBusStop,
+ IDE_BUS_DRIVER_VERSION, // version
+ NULL, // ImageHandle
+ NULL // DriverBindingHandle
+};
+
+// Global Buffer pointer used for Bus Mastering
+VOID *gDescriptorBuffer = NULL;
+
+VOID InitMiscConfig (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface
+);
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusExitBootServices
+//
+// Description: Enables IDE controller interrupt on ExitBootServices
+//
+// Input:
+// Event - The Event that is being processed
+// Context - Event Context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EFIAPI IdeBusExitBootServices(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ UINTN Count;
+ EFI_HANDLE Buffer[0x100];
+ UINTN BufferSize = sizeof(Buffer);
+ UINT8 i;
+ UINT8 j;
+ UINT8 k;
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitProtocol;
+ IDE_BUS_PROTOCOL *pIdeBusProtocol;
+ UINT64 IdeDevControlReg;
+ UINT64 IdeDevReg;
+ UINT8 Data8 = 0;
+
+ Status = pBS->LocateHandle(
+ ByProtocol,
+ &gEfiIdeBusInitProtocolGuid,
+ NULL,
+ &BufferSize,
+ Buffer
+ );
+
+ if ( !EFI_ERROR( Status )) {
+ Count = BufferSize / sizeof(EFI_HANDLE);
+
+ for ( i = 0; i < Count; i++ )
+ {
+ Status = pBS->HandleProtocol( Buffer[i], &gEfiIdeBusInitProtocolGuid, &IdeBusInitProtocol );
+
+ if ( !Status ) {
+ for ( j = 0; j < 2; j++ )
+ {
+ for ( k = 0; k < 2; k++ )
+ {
+ if ( IdeBusInitProtocol->pIdeBusProtocol[j][k] ) {
+ if ( IdeBusInitProtocol->IdeBusInitData[j][k] == DEVICE_CONFIGURED_SUCCESSFULLY ) {
+ pIdeBusProtocol = IdeBusInitProtocol->pIdeBusProtocol[j][k];
+
+ //
+ //Dev select
+ //
+ Data8 = pIdeBusProtocol->IdeDevice.Device << 4;
+ IdeDevReg = (UINT64)pIdeBusProtocol->IdeDevice.Regs.CommandBlock.DeviceReg;
+ pIdeBusProtocol->PciIO->Io.Write(
+ pIdeBusProtocol->PciIO,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ IdeDevReg,
+ 1,
+ &Data8
+ );
+
+
+ Data8 = 0;
+ //
+ //Enable IDE Controller interrupt
+ //
+ IdeDevControlReg = (UINT64)pIdeBusProtocol->IdeDevice.Regs.ControlBlock.AlternateStatusReg;
+ pIdeBusProtocol->PciIO->Io.Write(
+ pIdeBusProtocol->PciIO,
+ EfiPciIoWidthUint8,
+ EFI_PCI_IO_PASS_THROUGH_BAR,
+ IdeDevControlReg,
+ 1,
+ &Data8
+ );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusEntryPoint
+//
+// Description: Installs gIdeBusDriverBinding protocol
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeBusEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_EVENT ExitBootServicesNotifyEvent;
+
+ gIdeBusDriverBinding.DriverBindingHandle = NULL;
+ gIdeBusDriverBinding.ImageHandle = ImageHandle;
+
+ InitAmiLib( ImageHandle, SystemTable );
+ //
+ //Register our ExitBootServices () callback function
+ //
+ Status = pBS->CreateEvent(
+ EFI_EVENT_SIGNAL_EXIT_BOOT_SERVICES,
+ TPL_CALLBACK,
+ IdeBusExitBootServices,
+ NULL,
+ &ExitBootServicesNotifyEvent
+ );
+ ASSERT_EFI_ERROR( Status );
+
+ Status = pBS->LocateProtocol(
+ &gPlatformIdeProtocolGuid,
+ NULL,
+ &gPlatformIdeProtocol
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // if EFI_ERROR then Assign Default values Instance to gPlatformIdeProtocol.
+ //
+ gPlatformIdeProtocol = (PLATFORM_IDE_PROTOCOL *)&gPlatformIdeProtocolInstance;
+ }
+ //
+ // Assert when PLATFORM_IDE_PROTOCOL's revision is not supported
+ //
+ ASSERT(!(gPlatformIdeProtocol->Revision > PLATFORM_IDE_PROTOCOL_SUPPORTED_REVISION))
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gIdeBusDriverBinding.DriverBindingHandle,
+ &gIdeBusDriverBindingProtocolGuid, &gIdeBusDriverBinding,
+ &(gPlatformIdeProtocol->gComponentNameProtocolGuid), &gIdeBusControllerDriverName,
+ NULL
+ );
+
+#ifdef Debug_Level_1
+ EfiDebugPrint( -1, "IdeBusEntryPoint Exit Status %x\n", Status );
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusSupported
+//
+// Description: Checks whether IDE_PROTOCOL_INTERFACE is installed on the controller.
+// If 'yes', return SUCCESS else ERROR
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If Devicepath is NULL, check "gEfiIdeControllerProtocolGuid" is installed by IdeController device driver,
+// if yes, it is the IDE controller that this Bus will manage. Then return Success.
+// 2. If Devicepath is valid, check if "gEfiIdeBusInitProtocolGuid" is already installed by this BUS driver,
+// if yes, check whether it is OK to configure this device. if not installed goto step 1.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeBusSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_STATUS Status;
+
+ VOID *IdeControllerInterface = NULL ;
+ ATAPI_DEVICE_PATH *AtapiRemainingDevicePath = (ATAPI_DEVICE_PATH*) RemainingDevicePath;
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ UINT8 PciConfig[256];
+
+#ifdef Debug_Level_1
+ EfiDebugPrint( -1, "IdeBusSupported Entry\n" );
+#endif
+
+ //
+ //Check for Valid ATAPI Device Path. If no return UNSUPPORTED
+ //
+ if ( !(AtapiRemainingDevicePath == NULL)) {
+
+ //
+ // RemainingDevicePath is not NULL and begins with the End of Device Path node,
+ // then the driver must not enumerate any of the children of Controller nor create any child device handle.
+ // Only the controller initialization should be performed. UEFI specification V 2.3.1, P. 10.1
+ //
+ if(isEndNode(RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check if the AtapiRemainingDevicePath is valid 8.3.4.1
+ //
+ if ( AtapiRemainingDevicePath->Header.Type != MESSAGING_DEVICE_PATH
+ || AtapiRemainingDevicePath->Header.SubType != MSG_ATAPI_DP
+ && NODE_LENGTH( &AtapiRemainingDevicePath->Header ) != ATAPI_DEVICE_PATH_LENGTH ) {
+#ifdef Debug_Level_3
+ EfiDebugPrint( -1, "AtapiRemainingDevicePath not Valid\n" );
+#endif
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Now check whether it is OK to enumerate the specified device.
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ (VOID**)&IdeBusInitInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if ( Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED ) {
+ pBS->CloseProtocol(
+ Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == PRIMARY_CHANNEL && AtapiRemainingDevicePath->SlaveMaster == MASTER_DRIVE ) {
+ if ( IdeBusInitInterface->IdeBusInitData[PRIMARY_CHANNEL][MASTER_DRIVE] >= DEVICE_DETECTION_FAILED ) {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == PRIMARY_CHANNEL && AtapiRemainingDevicePath->SlaveMaster == SLAVE_DRIVE ) {
+ if ( IdeBusInitInterface->IdeBusInitData[PRIMARY_CHANNEL][SLAVE_DRIVE] >= DEVICE_DETECTION_FAILED ) {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == SECONDARY_CHANNEL && AtapiRemainingDevicePath->SlaveMaster == MASTER_DRIVE ) {
+ if ( IdeBusInitInterface->IdeBusInitData[SECONDARY_CHANNEL][MASTER_DRIVE] >= DEVICE_DETECTION_FAILED ) {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == SECONDARY_CHANNEL && AtapiRemainingDevicePath->SlaveMaster == SLAVE_DRIVE ) {
+ if ( IdeBusInitInterface->IdeBusInitData[SECONDARY_CHANNEL][SLAVE_DRIVE] >= DEVICE_DETECTION_FAILED ) {
+ return EFI_ALREADY_STARTED;
+ }
+ }
+ }
+ }
+
+ //
+ //Check whether IDE_CONTROLLER_PROTOCOL has been installed on this controller
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ (VOID**)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+#ifdef Debug_Level_3
+
+ if ( EFI_ERROR( Status )) {
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ EfiDebugPrint( -1, "Error opening gEfiIdeControllerInitProtocolGuid\n" );
+ else
+ EfiDebugPrint( -1, "Error opening gEfiIdeControllerProtocolGuid\n" );
+ }
+#endif
+
+ //
+ //IDE_CONTROLLER_PROTOCOL will be opened by each device. So EFI_ALREADY_STARTED is not an error
+ //
+ if ( !(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Close IDE_CONTROLLER_PROTOCOL
+ //
+ pBS->CloseProtocol(
+ Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ This->DriverBindingHandle,
+ Controller
+ );
+
+#ifdef Debug_Level_1
+ EfiDebugPrint( -1, "IdeBusSupported Exit Success\n" );
+#endif
+ //
+ // Check if Controller is in AHCI mode or not?
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID**)&PciIO,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIO->Pci.Read( PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig
+ );
+
+ if ((PciConfig [IDE_SUB_CLASS_CODE] == SCC_AHCI_CONTROLLER) || (PciConfig [IDE_SUB_CLASS_CODE] == SCC_RAID_CONTROLLER)) {
+ if ( !(gPlatformIdeProtocol->AhciCompatibleMode) )
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusStart
+//
+// Description: Installs IDE Block IO Protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol InstallProtocolInterface AllocatePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Check if "gEfiIdeBusInitProtocolGuid" is already installed. If not, install it "InstallBusInitProtocol".
+// 2. If Devicepath is valid, initialize so that only particular device will be detected and
+// confgiured, else all devices will be detected and configured.
+// 3. check whether the device has not been already detected. If yes, skip it and go for next device
+// 4. IdeBusInterface is initialized for this device. Update Base address.
+// 5. Do the detection "DetectIdeDevice". Update the status in "IdeBusInitProtocol". If failure undo the process "IdeBusInterface".
+// 6. Repeat for all devices from step 3.
+// 7. Start the configuration process for devices which are detected successfully "DEVICE_DETECTED_SUCCESSFULLY".
+// 8. "ConfigureIdeDeviceAndController" will do the configuration.
+// 9. If above step is success, build Devicepath "CreateIdeDevicePath"
+// 10. Create the Block_io_Protocol"InitIdeBlockIO". Install it only if Device is not Password protected.
+// 11. Create the DISK_INFO_PROTOCOL "InitIdeDiskInfo". Install it only if Device is not Password protected.
+// 12. Install a child device with the above three protocols.
+// 13. Open "gEfiIdeControllerProtocolGuid" with the child handle.
+// 14. Repeat from step 8 for the remaining devices.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeBusStart(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+
+ IDE_BLK_IO_DEV *IdeBlockIoDev = NULL;
+ VOID *IdeControllerInterface = NULL ;
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface;
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ UINT8 Enumeration_Process = ENUMERATE_ALL;
+ ATAPI_DEVICE_PATH *AtapiRemainingDevicePath = (ATAPI_DEVICE_PATH*)RemainingDevicePath;
+
+ UINT8 Start_Channel = PRIMARY_CHANNEL;
+ UINT8 End_Channel = SECONDARY_CHANNEL;
+ UINT8 Start_Device = MASTER_DRIVE;
+ UINT8 End_Device = SLAVE_DRIVE;
+
+ INT8 TotalDevice = 0;
+ INT8 Current_Channel;
+ INT8 Current_Device;
+ UINT16 SecurityStatus = 0;
+
+#ifdef Debug_Level_1
+ EfiDebugPrint( -1, "IdeBusStart Entry\n" );
+#endif
+
+ PROGRESS_CODE( DXE_IDE_BEGIN );
+
+ //
+ //Open IDE_CONTROLLER_PROTOCOL. If success or Already opened, It is OK to proceed.
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ (VOID**)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if ( !(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Get the PciIO interface
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID**)&PciIO,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+
+ //
+ //Check if IDE_BUS_INIT_PROTOCOL installed.
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ (VOID**)&IdeBusInitInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+
+ if ( !(Status == EFI_SUCCESS || Status == EFI_ALREADY_STARTED)) {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(IDE_BUS_INIT_PROTOCOL),
+ (VOID**)&IdeBusInitInterface
+ );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Status = InstallBusInitProtocol( Controller, IdeBusInitInterface, IdeControllerInterface );
+
+ if ( EFI_ERROR( Status )) {
+ if ( Status == EFI_OUT_OF_RESOURCES) {
+ return EFI_OUT_OF_RESOURCES;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ }
+
+ //
+ // Check if AtapiRemainingDevicePath is valid or not
+ //
+ if ( !(AtapiRemainingDevicePath == NULL)) {
+
+ //
+ // RemainingDevicePath is not NULL and begins with the End of Device Path node,
+ // then the driver must not enumerate any of the children of Controller nor create any child device handle.
+ // Only the controller initialization should be performed. UEFI specification V 2.3.1, P. 10.1
+ //
+ if(isEndNode(RemainingDevicePath)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Check if the AtapiRemainingDevicePath is valid 8.3.4.1
+ //
+ if ( AtapiRemainingDevicePath->Header.Type != MESSAGING_DEVICE_PATH
+ || AtapiRemainingDevicePath->Header.SubType != MSG_ATAPI_DP
+ && NODE_LENGTH( &AtapiRemainingDevicePath->Header ) != ATAPI_DEVICE_PATH_LENGTH ) {
+#ifdef Debug_Level_3
+ EfiDebugPrint( -1, "AtapiRemainingDevicePath not Valid\n" );
+#endif
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == PRIMARY_CHANNEL
+ && AtapiRemainingDevicePath->SlaveMaster == MASTER_DRIVE ) {
+ Enumeration_Process = ENUMERATE_PRIMARY_MASTER;
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == PRIMARY_CHANNEL
+ && AtapiRemainingDevicePath->SlaveMaster == SLAVE_DRIVE ) {
+ Enumeration_Process = ENUMERATE_PRIMARY_SLAVE;
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == SECONDARY_CHANNEL
+ && AtapiRemainingDevicePath->SlaveMaster == MASTER_DRIVE ) {
+ Enumeration_Process = ENUMERATE_SECONDARY_MASTER;
+ }
+
+ if ( AtapiRemainingDevicePath->PrimarySecondary == SECONDARY_CHANNEL
+ && AtapiRemainingDevicePath->SlaveMaster == SLAVE_DRIVE ) {
+ Enumeration_Process = ENUMERATE_SECONDARY_SLAVE;
+ }
+
+ switch ( Enumeration_Process )
+ {
+ case ENUMERATE_PRIMARY_MASTER:
+ Start_Channel = PRIMARY_CHANNEL;
+ End_Channel = PRIMARY_CHANNEL;
+ Start_Device = MASTER_DRIVE;
+ End_Device = MASTER_DRIVE;
+ break;
+ case ENUMERATE_PRIMARY_SLAVE:
+ Start_Channel = PRIMARY_CHANNEL;
+ End_Channel = PRIMARY_CHANNEL;
+ Start_Device = SLAVE_DRIVE;
+ End_Device = SLAVE_DRIVE;
+ break;
+ case ENUMERATE_SECONDARY_MASTER:
+ Start_Channel = SECONDARY_CHANNEL;
+ End_Channel = SECONDARY_CHANNEL;
+ Start_Device = MASTER_DRIVE;
+ End_Device = MASTER_DRIVE;
+ break;
+ case ENUMERATE_SECONDARY_SLAVE:
+ Start_Channel = SECONDARY_CHANNEL;
+ End_Channel = SECONDARY_CHANNEL;
+ Start_Device = SLAVE_DRIVE;
+ End_Device = SLAVE_DRIVE;
+ break;
+ default:
+ break;
+ }
+ }
+
+
+#ifdef Debug_Level_3
+ EfiDebugPrint( -1, "Enumerate = %x\n", Enumeration_Process );
+#endif
+
+ //---------------------------------------------------------------------------------------------------------
+ // Device Detection Begins
+ //---------------------------------------------------------------------------------------------------------
+ PROGRESS_CODE( DXE_IDE_DETECT );
+
+ for ( Current_Channel = Start_Channel; Current_Channel <= End_Channel; Current_Channel++ )
+ {
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ ( (EFI_IDE_CONTROLLER_INIT_PROTOCOL*)IdeControllerInterface )->NotifyPhase( (EFI_IDE_CONTROLLER_INIT_PROTOCOL*)IdeControllerInterface, EfiIdeBeforeChannelEnumeration, Current_Channel );
+ }
+ //
+ // Calculate the Number of Devices to be detected in single Channel
+ //
+ TotalDevice = ( End_Device - Start_Device ) + 1;
+
+ if ( gPlatformIdeProtocol->MasterSlaveEnumeration ) {
+ Current_Device = Start_Device;
+ } else {
+ Current_Device = End_Device;
+ }
+
+ while ( TotalDevice )
+ {
+ //
+ // Check whether the given device is disabled by USER OR already processed
+ //
+ if ( IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_DISABLED
+ || IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_DETECTED_SUCCESSFULLY
+ || IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_CONFIGURED_SUCCESSFULLY
+ || IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_DETECTION_FAILED
+ || IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_REMOVED ) {
+
+ if ( gPlatformIdeProtocol->MasterSlaveEnumeration ) {
+ Current_Device++;
+ } else {
+ Current_Device--;
+ }
+ TotalDevice--;
+ continue;
+ }
+
+ //
+ // Allocate memory for IDE_BUS_PROTOCOL
+ //
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ IdeBlockIoDev = MallocZ( sizeof(IDE_BLK_IO_DEV));
+
+ if ( !IdeBlockIoDev ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ IdeBlockIoDev->Signature = IDE_BLK_IO_DEV_SIGNATURE;
+ IdeBusInterface = (IDE_BUS_PROTOCOL*)&(IdeBlockIoDev->BlkIo);
+ } else {
+ IdeBusInterface = MallocZ( sizeof(IDE_BUS_PROTOCOL));
+
+ if ( !IdeBusInterface ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ //
+ // Initialize the fields
+ //
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ IdeBusInterface->EfiIdeControllerInterface =(EFI_IDE_CONTROLLER_INIT_PROTOCOL*) IdeControllerInterface;
+ IdeBusInterface->IdeControllerInterfaceHandle = Controller;
+ } else {
+ IdeBusInterface->IdeControllerInterface =(IDE_CONTROLLER_PROTOCOL*) IdeControllerInterface;
+ }
+ IdeBusInterface->IdeBusInitInterface = IdeBusInitInterface;
+ IdeBusInterface->PciIO = PciIO;
+ IdeBusInterface->IdeDevice.PciIO = PciIO;
+ IdeBusInterface->IdeDevice.Channel = Current_Channel;
+ IdeBusInterface->IdeDevice.Device = Current_Device;
+ IdeBusInterface->AtaReadWritePio = AtaReadWritePio;
+ IdeBusInterface->AtaPioDataIn = AtaPioDataIn;
+ IdeBusInterface->AtaPioDataOut = AtaPioDataOut;
+ IdeBusInterface->IdeNonDataCommand = IdeNonDataCommandExp;
+ IdeBusInterface->WaitForCmdCompletion = WaitForCmdCompletion;
+ IdeBusInterface->GeneralAtapiCommandAndData = GeneralAtapiCommandAndData;
+ Status = UpdateBaseAddress( IdeBusInterface );
+
+ if ( Status == EFI_SUCCESS ) {
+ Status = DetectIdeDevice( IdeBusInterface );
+ }
+
+ if ( EFI_ERROR( Status ) ) {
+ //
+ // Update IdeBusInitInterface
+ //
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_DETECTION_FAILED;
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+
+ if ( gPlatformIdeProtocol->MasterSlaveEnumeration ) {
+ Current_Device++;
+ } else {
+ Current_Device--;
+ }
+ TotalDevice--;
+ continue;
+ } else {
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_DETECTED_SUCCESSFULLY;
+ IdeBusInitInterface->pIdeBusProtocol[Current_Channel][Current_Device] = IdeBusInterface; // Save the Pointer
+ }
+
+ if ( gPlatformIdeProtocol->MasterSlaveEnumeration ) {
+ Current_Device++;
+ } else {
+ Current_Device--;
+ }
+ TotalDevice--;
+ } // Loop for Master/Slave
+ } // Loop for Primary/Secondary
+
+ //---------------------------------------------------------------------------------------------------------
+ // Device Detection Ends
+ //---------------------------------------------------------------------------------------------------------
+ // Configuration Starts
+ //---------------------------------------------------------------------------------------------------------
+ PROGRESS_CODE( DXE_IDE_ENABLE );
+
+ for ( Current_Channel = Start_Channel; Current_Channel <= End_Channel; Current_Channel++ )
+ {
+ for ( Current_Device = Start_Device; Current_Device <= End_Device; Current_Device++ )
+ {
+
+ //
+ //Check whether the given device is detected successfully
+ //
+ if ( IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_DETECTED_SUCCESSFULLY ) {
+ IdeBusInterface = IdeBusInitInterface->pIdeBusProtocol[Current_Channel][Current_Device];
+
+ Status = ConfigureIdeDeviceAndController( IdeBusInterface, IdeControllerInterface, IdeBusInitInterface );
+
+ if ( EFI_ERROR( Status )) {
+ ERROR_CODE( DXE_IDE_DEVICE_FAILURE, EFI_ERROR_MAJOR );
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+
+ IdeBusInitInterface->pIdeBusProtocol[Current_Channel][Current_Device] = NULL;
+ continue;
+ }
+
+ //
+ //Device has been successfully detected and configured.
+ //
+
+ //
+ //Create the Devicepath
+ //
+ Status = CreateIdeDevicePath( This, Controller, IdeBusInitInterface, IdeBusInterface, RemainingDevicePath, Current_Channel, Current_Device );
+
+ if ( EFI_ERROR( Status )) {
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+ continue;
+ }
+
+ //
+ //Initialize Block_IO Protocol
+ //
+ Status = InitIdeBlockIO( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+ continue;
+ }
+
+ //
+ //Initialize IDE EFI_DISK_INFO_PROTOCOL
+ //
+ Status = InitIdeDiskInfo( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+ continue;
+ }
+
+ //
+ //Install Devicepath
+ //
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &(IdeBusInterface->IdeDeviceHandle),
+ &gDevicePathProtocolGuid, IdeBusInterface->DevicePathProtocol,
+ NULL );
+
+ if ( EFI_ERROR( Status )) {
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_DETECTION_FAILED;
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+ continue;
+ }
+
+ //
+ //Open IdeControllerProtocol
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ (VOID**)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ IdeBusInterface->IdeDeviceHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+
+ //
+ //Install other optional Protocols - Hdd Security
+ //
+ Status = pBS->LocateProtocol(
+ &gHddSecurityInitProtocolGuid,
+ NULL,
+ &HddSecurityInitProtocol
+ );
+
+ if ( !EFI_ERROR( Status )) {
+ if ( HddSecurityInitProtocol != NULL ) {
+ HddSecurityInitProtocol->InstallSecurityInterface( IdeBusInterface, FALSE );
+ }
+ } else {
+ //
+ // If Security Feature support is not enabled, always freeze lock the security feature
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_82 & 0x2 ) {
+ Status = IdeNonDataCommand( IdeBusInterface, 0, 0,
+ 0, 0, 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ SECURITY_FREEZE_LOCK );
+ //
+ // if Device Configuration Overlay feature set supported then issue the
+ // Dev config Free lock command.
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x800 ) {
+ Status = IdeNonDataCommand( IdeBusInterface, DEV_CONFIG_FREEZE_LOCK_FEATURES, 0,
+ 0, 0, 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ DEV_CONFIG_FREEZE_LOCK );
+ }
+ // Update the Identify device buffer
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+ }
+ }
+
+ //
+ // Install other optional Protocols - OpalSecurity
+ //
+
+ Status = pBS->LocateProtocol (
+ &gOpalSecInitProtocolGuid,
+ NULL,
+ &OpalSecInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(OpalSecInitProtocol != NULL) {
+ OpalSecInitProtocol->InstallOpalSecurityInterface(IdeBusInterface, FALSE);
+ }
+ }
+
+ //
+ //Install other optional Protocols - SMART
+ //
+ Status = pBS->LocateProtocol(
+ &gHddSmartInitProtocolGuid,
+ NULL,
+ &HddSmartInitProtocol
+ );
+
+ if ( !EFI_ERROR( Status )) {
+ if ( HddSmartInitProtocol != NULL ) {
+ HddSmartInitProtocol->InitSMARTSupport( IdeBusInterface, FALSE );
+ //
+ //Get the updated IdentifyData
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+ if ( HddSmartInitProtocol->SmartDiagonasticFlag ) {
+ HddSmartInitProtocol->InstallSMARTInterface( IdeBusInterface, FALSE );
+ }
+ }
+ }
+
+ if ( gPlatformIdeProtocol->IdePwrManagementInterfaceSupport ) {
+ InstallIDEPowerMgmtInterface( IdeBusInterface );
+ }
+
+ if ( gPlatformIdeProtocol->HostProtectedAreaSupport ) {
+ InstallHPAInterface( IdeBusInterface );
+ }
+
+#ifdef Debug_Level_3
+ PrintIdeDeviceInfo( IdeBusInterface );
+#endif
+ } // DEVICE_CONFIGURED_SUCCESSFULLY
+
+ //Before installing BlockIO and DiskInfo protocol, check whether the device has been
+ //password protected. If yes, BlockIO and DiskInfo will not be installed.
+ IdeBusInterface = IdeBusInitInterface->pIdeBusProtocol[Current_Channel][Current_Device];
+
+ if ( IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_CONFIGURED_SUCCESSFULLY ) {
+ //
+ //Check BlockIO has been installed or not.
+ //
+ Status = pBS->OpenProtocol( IdeBusInterface->IdeDeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ IdeBusInterface->IdeDeviceHandle,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if ( EFI_ERROR( Status )) {
+ //
+ //BLOCKIO not installed and device has been configured successfully
+ //
+ Status = EFI_UNSUPPORTED;
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &(IdeBusInterface->IdeDeviceHandle),
+ &gEfiBlockIoProtocolGuid, (EFI_BLOCK_IO_PROTOCOL*)(IdeBusInterface->IdeBlkIo),
+ &gEfiDiskInfoProtocolGuid, (EFI_DISK_INFO_PROTOCOL*)(IdeBusInterface->IdeDiskInfo),
+ NULL );
+ } // If BlockIO not Installed
+ } // End of installing BlockIO and DiskInfo
+ } // Loop for Master/Slave
+ } // Loop for Primary/Secondary
+
+ //---------------------------------------------------------------------------------------------------------
+ // Configuration Ends
+ //---------------------------------------------------------------------------------------------------------
+
+ // Check HP Support and Ide Controller protocol to create an HP event
+ if ( gPlatformIdeProtocol->IdeHPSupport == 1 && gPlatformIdeProtocol->EfiIdeProtocol == 0 ) {
+
+ //
+ // Check whether already HP Event has been created and also HP is supported
+ //
+ if ( IdeBusInitInterface->HPEvent == NULL && IdeBusInitInterface->HPMask ) {
+ //
+ // Create and Event
+ //
+ Status = pBS->CreateEvent( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ IdeHPTimer,
+ IdeBusInitInterface,
+ &(IdeBusInitInterface->HPEvent));
+
+ if ( Status == EFI_SUCCESS ) {
+ pBS->SetTimer( IdeBusInitInterface->HPEvent, TimerPeriodic, 20000000 ); // 2sec
+ }
+ }
+ }
+
+ Status = pBS->LocateProtocol (
+ &gAtaPassThruInitProtocolGuid,
+ NULL,
+ &AtaPassThruInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(AtaPassThruInitProtocol != NULL) {
+ AtaPassThruInitProtocol->InstallAtaPassThru(Controller, FALSE);
+ }
+ }
+
+ // SCSIPassThruAtapi install
+ Status = pBS->LocateProtocol (
+ &gScsiPassThruAtapiInitProtocolGuid,
+ NULL,
+ &gScsiPassThruAtapiInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(gScsiPassThruAtapiInitProtocol != NULL) {
+ gScsiPassThruAtapiInitProtocol->InstallScsiPassThruAtapi(Controller, FALSE);
+ }
+ }
+
+ //
+ // This will notify AMITSE to invoke the HDD password Screen
+ //
+ Status = pBS->InstallProtocolInterface(
+ &Controller,
+ &gHddSecurityEndProtocolGuid, EFI_NATIVE_INTERFACE, NULL
+ );
+
+#ifdef Debug_Level_1
+ EfiDebugPrint( -1, "IdeBusStart Exit Success\n" );
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeBusStop
+//
+// Description: Uninstall all devices installed in start procedure.
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Check whether "gEfiIdeBusInitProtocolGuid" is installed on this controller. If not exit with error.
+// 2. If "NumberOfChildren" is zero, check wether all child devices have been stopped. If not exit with error.
+// if all child devices have been stopped, then close "gEfiIdeControllerProtocolGuid" and "gEfiIdeBusInitProtocolGuid",
+// uninstall "gEfiIdeBusInitProtocolGuid" and then exit with success.
+// 3. If "NumberOfChildren" is non-zero, close "gEfiIdeControllerProtocolGuid" opened by the child device in start function.
+// uninstall all protocols installed on this child device in start function,
+// free up all resources allocated in start function. Repeat step 3 for all child devices and return success at the end.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IdeBusStop(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer )
+{
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface;
+ IDE_BUS_PROTOCOL *IdeBusInterface = NULL;
+ EFI_STATUS Status;
+ IDE_BLK_IO_DEV *IdeBlockIoDev = NULL;
+ VOID *IdeControllerInterface = NULL ;
+
+ UINT8 Current_Channel = 0xff;
+ UINT8 Current_Device = 0xff;
+ UINT8 Index = 0;
+ BOOLEAN Flag = TRUE;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ //Check if IDE_BUS_INIT_PROTOCOL is installed on the Controller.
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ (VOID**)&IdeBusInitInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Check if ChildHandleBuffer is valid
+ //
+ if ( NumberOfChildren ) {
+ while ( NumberOfChildren )
+ {
+ Status = pBS->OpenProtocol(
+ ChildHandleBuffer[Index],
+ &gDevicePathProtocolGuid,
+ (VOID**)&DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ //Lookout for ATAPI device path
+ //ACPI_DEVICE path, PCI Device path and then ATAPI device path will be the sequence
+ do
+ {
+ if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_ATAPI_DP)) {
+ Current_Channel = ((ATAPI_DEVICE_PATH*)DevicePath)->PrimarySecondary;
+ Current_Device = ((ATAPI_DEVICE_PATH*)DevicePath)->SlaveMaster;
+ break;
+ } else {
+ DevicePath = NEXT_NODE( DevicePath );
+ }
+ } while ( DevicePath->Type != END_DEVICE_PATH );
+
+ if ( Current_Channel == 0xff || Current_Device == 0xff ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Get the pointer to IDE_BUS_PROTOCOL
+ //
+ IdeBusInterface = IdeBusInitInterface->pIdeBusProtocol[Current_Channel][Current_Device];
+
+ //
+ //Close all the protocols opened by this Child Device
+ //
+ pBS->CloseProtocol(
+ Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index] );
+
+ //Before uninstalling BLOCKIO check whether it is installed or not
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if ( Status == EFI_SUCCESS ) {
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ ChildHandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid, (EFI_BLOCK_IO_PROTOCOL*)(IdeBusInterface->IdeBlkIo),
+ &gEfiDiskInfoProtocolGuid, (EFI_DISK_INFO_PROTOCOL*)(IdeBusInterface->IdeDiskInfo),
+ NULL );
+ }
+
+ Status = pBS-> UninstallMultipleProtocolInterfaces(
+ ChildHandleBuffer[Index],
+ &gDevicePathProtocolGuid, IdeBusInterface->DevicePathProtocol,
+ NULL );
+
+ if ( EFI_ERROR( Status )) {
+ pBS->OpenProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ (VOID**)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+ return EFI_DEVICE_ERROR;
+ } else {
+ //
+ //Now free up all resources allocated.
+ //
+ if ( IdeBusInterface->IdeDevice.AtapiDevice != NULL ) {
+ pBS->FreePool( IdeBusInterface->IdeDevice.AtapiDevice->PacketBuffer );
+ pBS->FreePool( IdeBusInterface->IdeDevice.AtapiDevice->InquiryData );
+ pBS->FreePool( IdeBusInterface->IdeDevice.AtapiDevice );
+ }
+
+ //
+ //Freeup resources allocated for component names
+ //
+ if ( IdeBusInterface->IdeDevice.UDeviceName != NULL ) {
+ pBS->FreePool( IdeBusInterface->IdeDevice.UDeviceName->Language );
+ pBS->FreePool( IdeBusInterface->IdeDevice.UDeviceName->UnicodeString );
+ pBS->FreePool( IdeBusInterface->IdeDevice.UDeviceName );
+ }
+
+ // Uninstall optional protocols
+
+ //
+ //Before uninstalling HDD security check whether it is installed or not
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gHddSecurityInitProtocolGuid,
+ (VOID**)&HddSecurityInitProtocol,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if ( !EFI_ERROR( Status )) {
+ if ( HddSecurityInitProtocol != NULL ) {
+ HddSecurityInitProtocol->StopSecurityModeSupport( IdeBusInterface, FALSE );
+ }
+ }
+
+ //
+ //Before uninstalling Hdd Smart check whether it is installed or not
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gHddSmartInitProtocolGuid,
+ (VOID**)&HddSmartInitProtocol,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if ( !EFI_ERROR( Status )) {
+ if ( HddSmartInitProtocol != NULL ) {
+ if ( HddSmartInitProtocol->SmartDiagonasticFlag ) {
+ HddSmartInitProtocol->UnInstallSMARTInterface( IdeBusInterface, FALSE );
+ }
+ }
+ }
+
+ //
+ //Before uninstalling OPAL security Interface check whether it is installed or not.
+ //
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gOpalSecInitProtocolGuid,
+ (VOID**)&OpalSecInitProtocol,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if ( !EFI_ERROR( Status )) {
+ if ( OpalSecInitProtocol != NULL ) {
+ OpalSecInitProtocol->UnInstallOpalSecurityInterface( IdeBusInterface, FALSE );
+ }
+ }
+
+ if ( gPlatformIdeProtocol->IdePwrManagementInterfaceSupport ) {
+ StopIDEPowerMgmtInterface( IdeBusInterface );
+ }
+
+ if ( gPlatformIdeProtocol->HostProtectedAreaSupport ) {
+ StopHPAInterface( IdeBusInterface );
+ }
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ IdeBlockIoDev = IDE_BLOCK_IO_DEV_FROM_THIS( &(IdeBusInterface->IdeBlkIo));
+ }
+ pBS->FreePool( IdeBusInterface->IdeBlkIo->BlkIo.Media );
+ pBS->FreePool( IdeBusInterface->IdeBlkIo );
+ pBS->FreePool( IdeBusInterface->IdeDiskInfo );
+ Current_Channel = IdeBusInterface->IdeDevice.Channel;
+ Current_Device = IdeBusInterface->IdeDevice.Device;
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_IN_RESET_STATE;
+ pBS->FreePool( IdeBusInterface->DevicePathProtocol );
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+ }
+ NumberOfChildren--;
+ Index++;
+ }
+
+ return EFI_SUCCESS;
+ } else {
+ //
+ //Check if IDE_BUS_INIT_PROTOCOL can be removed
+ //
+ for ( Current_Channel = PRIMARY_CHANNEL; Current_Channel <= SECONDARY_CHANNEL; Current_Channel++ )
+ {
+ for ( Current_Device = MASTER_DRIVE; Current_Device <= SLAVE_DRIVE; Current_Device++ )
+ {
+ if ( IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] == DEVICE_CONFIGURED_SUCCESSFULLY ) {
+ Flag = FALSE;
+ }
+ }
+ }
+
+ //
+ // Can't uninstall IDE_BUS_INIT_PROTOCOL if any one of the IDE devices are in "CONFIGURED" state.
+ //
+ if ( Flag == TRUE ) {
+ if ( gPlatformIdeProtocol->IdeHPSupport ) {
+
+ //
+ // Check whether already HP Event has been created and also HP is supported
+ //
+ if ( IdeBusInitInterface->HPEvent != NULL ) {
+ pBS->CloseEvent( IdeBusInitInterface->HPEvent );
+ }
+ }
+ //
+ //Close all the protocols opened in Start Function
+ //
+ Status = pBS->CloseProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ This->DriverBindingHandle,
+ Controller );
+ //
+ // AtaPass Thru uninstall
+ //
+ Status = pBS->LocateProtocol (
+ &gAtaPassThruInitProtocolGuid,
+ NULL,
+ &AtaPassThruInitProtocol
+ );
+
+ if(!EFI_ERROR(Status)) {
+ if(AtaPassThruInitProtocol != NULL) {
+ AtaPassThruInitProtocol->StopAtaPassThruSupport(Controller, FALSE);
+ }
+ }
+ //
+ // ScsiPassThruAtapi uninstall
+ //
+ Status = pBS->LocateProtocol (
+ &gScsiPassThruAtapiInitProtocolGuid,
+ NULL,
+ &gScsiPassThruAtapiInitProtocol);
+
+ if(!EFI_ERROR(Status)) {
+ if(gScsiPassThruAtapiInitProtocol != NULL) {
+ gScsiPassThruAtapiInitProtocol->StopScsiPassThruAtapiSupport(Controller, FALSE);
+ }
+ }
+
+
+ Status = pBS->CloseProtocol( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ This->DriverBindingHandle,
+ Controller );
+
+ Status = pBS->UninstallProtocolInterface( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ IdeBusInitInterface );
+
+ if ( EFI_ERROR( Status )) {
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ (VOID**)&IdeBusInitInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ Status = pBS->OpenProtocol( Controller,
+ &(gPlatformIdeProtocol->gIdeControllerProtocolGuid),
+ (VOID**)&IdeControllerInterface,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ pBS->FreePool( IdeBlockIoDev );
+ else
+ pBS->FreePool( IdeBusInterface );
+
+ if ( gDescriptorBuffer != NULL ) {
+ pBS->FreePool( gDescriptorBuffer );
+ }
+ gDescriptorBuffer = NULL;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallBusInitProtocol
+//
+// Description: Installs BUS Init Protocol on the IDE controller Handle
+//
+// Input:
+// IN EFI_HANDLE Controller,
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface;
+// IDE_CONTROLLER_PROTOCOL *IdeControllerInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool, InstallProtocolInterface, IdeGetControllerInfo
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Call "IdeGetControllerInfo", to get channel information from IdeController driver.
+// 2. Install "gEfiIdeBusInitProtocolGuid" on the IDE controller.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InstallBusInitProtocol(
+ IN EFI_HANDLE Controller,
+ IN OUT IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface,
+ IN VOID *IdeControllerInterfaceIn
+ )
+{
+ CONTROLLER_INFO *ControllerInfo;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *EfiIdeControllerInterface = NULL ;
+ IDE_CONTROLLER_PROTOCOL *IdeControllerInterface = NULL ;
+ EFI_STATUS Status;
+
+ //
+ // Initialize IdeControllerInterface
+ //
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ EfiIdeControllerInterface = ( EFI_IDE_CONTROLLER_INIT_PROTOCOL *) IdeControllerInterfaceIn;
+ else
+ IdeControllerInterface = ( IDE_CONTROLLER_PROTOCOL *) IdeControllerInterfaceIn;
+
+ //
+ //Initialize the default Values
+ //
+ ZeroMemory( IdeBusInitInterface, sizeof(IDE_BUS_INIT_PROTOCOL));
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(CONTROLLER_INFO),
+ (VOID**)&ControllerInfo
+ );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ ZeroMemory( ControllerInfo, sizeof(CONTROLLER_INFO));
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ ControllerInfo->Flags = 0; // ACOUSTIC_SUPPORT_DISABLE
+
+ if ( gPlatformIdeProtocol->SBIdeSupport ) {
+ Status = pBS->LocateProtocol(&gIdeSetupProtocolguid, NULL, &gIdeSetupProtocol);
+
+ if ( gPlatformIdeProtocol->AcousticManagementSupport ) {
+
+ if (!EFI_ERROR(Status)) {
+
+ if(gIdeSetupProtocol->AcousticPwrMgmt)
+ ControllerInfo->Flags |= ACOUSTIC_SUPPORT_ENABLE;
+ else
+ ControllerInfo->Flags &= ~ACOUSTIC_SUPPORT_ENABLE;
+ ControllerInfo->Acoustic_Management_Level = gIdeSetupProtocol->AcousticLevel;
+ } else {
+ ControllerInfo->Flags &= ~ACOUSTIC_SUPPORT_ENABLE ;
+ ControllerInfo->Acoustic_Management_Level = ACOUSTIC_LEVEL_BYPASS;
+ }
+ } //End of ACOUSTIC_MANAGEMENT_SUPPORT
+ } //End of SBIDE_SUPPORT
+
+ if ( gPlatformIdeProtocol->HddPowerLossInS3 ) {
+ ControllerInfo->Flags |= S3_RESUME_UNLOCK_HDD_PASSWORD;
+ }
+
+ ControllerInfo->PrimaryChannel = PRIMARY_CHANNEL_ENABLE;
+ ControllerInfo->PrimaryMasterDevice = PRIMARY_MASTER_DRIVE_ENABLE;
+ ControllerInfo->PrimarySlaveDevice = PRIMARY_SLAVE_DRIVE_ENABLE;
+ ControllerInfo->SecondaryChannel = SECONDARY_CHANNEL_ENABLE;
+ ControllerInfo->SecondaryMasterDevice = SECONDARY_MASTER_DRIVE_ENABLE;
+ ControllerInfo->SecondarySlaveDevice = SECONDARY_SLAVE_DRIVE_ENABLE;
+ ControllerInfo->BusMasterEnable = BUSMASTER_ENABLE;
+ ControllerInfo->HPMask = 0; // Hot Plug Mask
+
+ } else {
+ IdeControllerInterface->IdeGetControllerInfo( Controller, ControllerInfo );
+ }
+
+ if ( ControllerInfo->PrimaryChannel == DEVICE_DISABLED ) {
+ IdeBusInitInterface->IdeBusInitData[PRIMARY_CHANNEL][MASTER_DRIVE] = DEVICE_DISABLED;
+ IdeBusInitInterface->IdeBusInitData[PRIMARY_CHANNEL][SLAVE_DRIVE] = DEVICE_DISABLED;
+ } else {
+ IdeBusInitInterface->IdeBusInitData[PRIMARY_CHANNEL][MASTER_DRIVE] = ControllerInfo->PrimaryMasterDevice;
+ IdeBusInitInterface->IdeBusInitData[PRIMARY_CHANNEL][SLAVE_DRIVE] = ControllerInfo->PrimarySlaveDevice;
+ }
+
+ if ( ControllerInfo->SecondaryChannel == DEVICE_DISABLED ) {
+ IdeBusInitInterface->IdeBusInitData[SECONDARY_CHANNEL][MASTER_DRIVE] = DEVICE_DISABLED;
+ IdeBusInitInterface->IdeBusInitData[SECONDARY_CHANNEL][SLAVE_DRIVE] = DEVICE_DISABLED;
+ } else {
+ IdeBusInitInterface->IdeBusInitData[SECONDARY_CHANNEL][MASTER_DRIVE] = ControllerInfo->SecondaryMasterDevice;
+ IdeBusInitInterface->IdeBusInitData[SECONDARY_CHANNEL][SLAVE_DRIVE] = ControllerInfo->SecondarySlaveDevice;
+ }
+
+ IdeBusInitInterface->BusMasterSelection = ControllerInfo->BusMasterEnable;
+ IdeBusInitInterface->HPMask = ControllerInfo->HPMask;
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ IdeBusInitInterface->EfiIdeControllerInterface = EfiIdeControllerInterface;
+ else
+ IdeBusInitInterface->IdeControllerInterface = IdeControllerInterface;
+
+ IdeBusInitInterface->Flags = ControllerInfo->Flags;
+ IdeBusInitInterface->Acoustic_Management_Level = ControllerInfo->Acoustic_Management_Level;
+
+ Status = pBS->FreePool( ControllerInfo );
+
+ // Initialize PrevPortNum and PrevPortMultiplierPortNum for AtaPassThru to 0xFFFF
+
+ IdeBusInitInterface->PrevPortNum = 0xffff;
+ IdeBusInitInterface->PrevPortMultiplierPortNum = 0xffff;
+
+ Status = pBS->InstallProtocolInterface(
+ &Controller,
+ &gEfiIdeBusInitProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ IdeBusInitInterface );
+
+ if ((IdeBusInitInterface->BusMasterSelection) && gDescriptorBuffer == NULL ) {
+ //Since the PRD table need to be aligned at 64KB to create maximum # of tables
+ //allocate 128KB and use the 64KB aligned address,
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 2 * 64 * 1024,
+ (VOID**)&gDescriptorBuffer
+ );
+
+ if ( EFI_ERROR( Status )) {
+ IdeBusInitInterface->BusMasterSelection = 0;
+ }
+ }
+
+#ifdef Debug_Level_3
+ EfiDebugPrint( -1, "Installed IDE_BUS_INIT_PROTOCOL\n" );
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ConfigureIdeDeviceAndController
+//
+// Description: PIO and DMA mode programming both on the Controller as well as on the Device is done
+//
+// Input:
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface
+// IDE_CONTROLLER_PROTOCOL *IdeControllerInterface
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ConfigureIdeDevice, GetIdentifyData
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get the Best PIO and DMA mode supported by the device from Identify Data
+// 2. Set the PIO and DMA mode in the IDE controller.
+// 3. Configure the IDE device with the PIO and DMA mode.
+// 4. Update the Identify Data.
+// 5. Based on the IDE device select the proper Read/Write commands.
+// 6. Construct a unicode string for the IDE device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConfigureIdeDeviceAndController(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN VOID *IdeControllerInterfaceIn,
+ IN IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface )
+{
+ EFI_STATUS Status;
+ UINT8 Current_Channel = IdeBusInterface->IdeDevice.Channel;
+ UINT8 Current_Device = IdeBusInterface->IdeDevice.Device;
+
+ EFI_ATA_COLLECTIVE_MODE *SupportedModes = NULL;
+ EFI_IDE_CONTROLLER_INIT_PROTOCOL *EfiIdeControllerInterface = NULL ;
+ IDE_CONTROLLER_PROTOCOL *IdeControllerInterface = NULL ;
+
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol )
+ EfiIdeControllerInterface = (EFI_IDE_CONTROLLER_INIT_PROTOCOL*) IdeControllerInterfaceIn;
+ else
+ IdeControllerInterface = (IDE_CONTROLLER_PROTOCOL *) IdeControllerInterfaceIn;
+
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+ Status = EfiIdeControllerInterface->SubmitData( EfiIdeControllerInterface, IdeBusInterface->IdeDevice.Channel,
+ IdeBusInterface->IdeDevice.Device, (EFI_IDENTIFY_DATA*)&(IdeBusInterface->IdeDevice.IdentifyData));
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Status = EfiIdeControllerInterface->CalculateMode( EfiIdeControllerInterface, IdeBusInterface->IdeDevice.Channel,
+ IdeBusInterface->IdeDevice.Device, &SupportedModes );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Status = EfiIdeControllerInterface->SetTiming( EfiIdeControllerInterface, IdeBusInterface->IdeDevice.Channel,
+ IdeBusInterface->IdeDevice.Device, SupportedModes );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ IdeBusInterface->IdeDevice.PIOMode = 0xff;
+ IdeBusInterface->IdeDevice.SWDma = 0xff;
+ IdeBusInterface->IdeDevice.MWDma = 0xff;
+ IdeBusInterface->IdeDevice.UDma = 0xff;
+
+ if ( SupportedModes->PioMode.Valid ) {
+ IdeBusInterface->IdeDevice.PIOMode = SupportedModes->PioMode.Mode;
+ }
+
+ if ( SupportedModes->SingleWordDmaMode.Valid ) {
+ IdeBusInterface->IdeDevice.SWDma = SupportedModes->SingleWordDmaMode.Mode;
+ }
+
+ if ( SupportedModes->MultiWordDmaMode.Valid ) {
+ IdeBusInterface->IdeDevice.MWDma = SupportedModes->MultiWordDmaMode.Mode;
+ }
+
+ if ( SupportedModes->UdmaMode.Valid ) {
+ IdeBusInterface->IdeDevice.UDma = SupportedModes->UdmaMode.Mode;
+ }
+
+ IdeBusInterface->IdeDevice.IORdy = ((EFI_IDENTIFY_DATA*)&(IdeBusInterface->IdeDevice.IdentifyData))->AtaData.capabilities & 0x800;
+
+ } else {
+ //
+ // Get the best PIO and DMA mode from the IDE device
+ //
+ IdeControllerInterface->GetbestPioDmaMode( &(IdeBusInterface->IdeDevice));
+
+ //
+ // Program PIO mode Timing in the controller
+ //
+ IdeControllerInterface->IdeSetPioMode( &(IdeBusInterface->IdeDevice));
+
+ // See if Bus Master has been enabled
+ IdeControllerInterface->IdeSetDmaMode( &(IdeBusInterface->IdeDevice));
+ }
+
+ // Issue SET feature command to set the PIO and DMA mode
+ Status = ConfigureIdeDevice( IdeBusInterface, IdeBusInitInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ } else {
+ //
+ //Get the updated IdentifyData
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+
+ //
+ //Check if UDMA and MWDMA are programmed successfully
+ //
+ if ( IdeBusInterface->IdeDevice.UDma != 0xff ) {
+ if ( !(ReturnMSBset((IdeBusInterface->IdeDevice.IdentifyData.UDMA_Mode_88 >> 8)) == IdeBusInterface->IdeDevice.UDma)) {
+ IdeBusInterface->IdeDevice.UDma = ReturnMSBset((IdeBusInterface->IdeDevice.IdentifyData.UDMA_Mode_88 >> 8));
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ SupportedModes->UdmaMode.Mode = IdeBusInterface->IdeDevice.UDma;
+ EfiIdeControllerInterface->SetTiming( EfiIdeControllerInterface, IdeBusInterface->IdeDevice.Channel,
+ IdeBusInterface->IdeDevice.Device, SupportedModes );
+ } else {
+ IdeControllerInterface->IdeSetDmaMode( &(IdeBusInterface->IdeDevice));
+ }
+ }
+ } else {
+ if ( IdeBusInterface->IdeDevice.MWDma != 0xff ) {
+ if ( !(ReturnMSBset( IdeBusInterface->IdeDevice.IdentifyData.MultiWord_DMA_63 >> 8 ) == IdeBusInterface->IdeDevice.MWDma)) {
+ IdeBusInterface->IdeDevice.MWDma = ReturnMSBset( (IdeBusInterface->IdeDevice.IdentifyData.MultiWord_DMA_63 >> 8));
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ SupportedModes->MultiWordDmaMode.Mode = IdeBusInterface->IdeDevice.MWDma;
+ EfiIdeControllerInterface-> SetTiming( EfiIdeControllerInterface, IdeBusInterface->IdeDevice.Channel,
+ IdeBusInterface->IdeDevice.Device, SupportedModes );
+ } else {
+ IdeControllerInterface->IdeSetDmaMode( &(IdeBusInterface->IdeDevice));
+ }
+ }
+ }
+ }
+
+ // Check for ATA
+ if ( IdeBusInterface->IdeDevice.DeviceType == ATA ) {
+ // Update IDE Read/Write Command
+ if ((IdeBusInterface->IdeDevice.IdentifyData.Valid_Bits_59 & 0x100)
+ && (IdeBusInterface->IdeDevice.IdentifyData.Valid_Bits_59 & 0xff)) { // Check if Multiple Read/Write
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ // 48Bit LBA supported
+ IdeBusInterface->IdeDevice.ReadCommand = READ_MULTIPLE_EXT;
+ IdeBusInterface->IdeDevice.WriteCommand = WRITE_MULTIPLE_EXT;
+ } else {
+ IdeBusInterface->IdeDevice.ReadCommand = READ_MULTIPLE;
+ IdeBusInterface->IdeDevice.WriteCommand = WRITE_MULTIPLE;
+ }
+ } else { // 1 Block = 1 Sector
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ // 48Bit LBA supported
+ IdeBusInterface->IdeDevice.ReadCommand = READ_SECTORS_EXT;
+ IdeBusInterface->IdeDevice.WriteCommand = WRITE_SECTORS_EXT;
+ } else {
+ IdeBusInterface->IdeDevice.ReadCommand = READ_SECTORS;
+ IdeBusInterface->IdeDevice.WriteCommand = WRITE_SECTORS;
+ }
+ }
+
+ if ( DMACapable( IdeBusInterface )) {
+ if ( gPlatformIdeProtocol->IdeBusMasterSupport ) {
+ IdeBusInterface->IdeDevice.ReadCommand = READ_DMA;
+ IdeBusInterface->IdeDevice.WriteCommand = WRITE_DMA;
+
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ //
+ // 48Bit LBA supported
+ //
+ IdeBusInterface->IdeDevice.ReadCommand = READ_DMA_EXT;
+ IdeBusInterface->IdeDevice.WriteCommand = WRITE_DMA_EXT;
+ }
+ }
+ }
+ }
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_CONFIGURED_SUCCESSFULLY;
+ }
+
+ if ( gPlatformIdeProtocol->DisableSoftSetPrev || gPlatformIdeProtocol->ForceHddPasswordPrompt ) {
+
+ //
+ // Software settings preserved
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.Reserved_76_79[0] != 0xFFFF)
+ && (IdeBusInterface->IdeDevice.IdentifyData.Reserved_76_79[2] & 0x0040)) {
+ Status = IdeSetFeatureCommand( IdeBusInterface, DISABLE_SATA2_SOFTPREV, 6 );
+ //
+ // Get the updated IdentifyData
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitIdeBlockIO
+//
+// Description: Initializes IDE Block IO interface
+//
+// Input:
+//
+// IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool, OpenProtocol, DetectAtapiMedia, AtapiInquiryData
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize EFI_BLOCK_IO_PROTOCOL Protocol.
+// 2. In case of Removable devices, detect Media presence.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitIdeBlockIO(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ IDE_BLOCK_IO *IdeBlkIo;
+ EFI_BLOCK_IO_MEDIA *BlkMedia;
+ ATAPI_DEVICE *AtapiDevice;
+ UINT8 *Data;
+ UINT8 *InquiryData;
+ UINT16 InquiryDataSize;
+ UINT8 Current_Channel;
+ UINT8 Current_Device;
+ UINT8 bTemp;
+ UINT16 OddType = 0;
+ UINT8 OddLoadingType =0xFF;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(IDE_BLOCK_IO),
+ (VOID**)&IdeBlkIo );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+
+ BlkMedia = MallocZ( sizeof(EFI_BLOCK_IO_MEDIA));
+
+ if ( !BlkMedia ) {
+ pBS->FreePool( IdeBlkIo );
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ //Initialize the IdeBlkIo pointer in IDE_BUS_PROTOCOL (IdeBusInterface)
+ //
+ IdeBusInterface->IdeBlkIo = IdeBlkIo;
+
+ //
+ //Initialize the fields in IdeBlkIo (IDE_BLOCK_IO)
+ //
+ IdeBlkIo->IdeBusInterface = IdeBusInterface;
+
+ if ( IdeBusInterface->IdeDevice.DeviceType == ATA ) {
+ //
+ //ATA
+ //
+ BlkIo = &(IdeBlkIo->BlkIo);
+ //
+ // UEFI2.3.1 Supports the BlockIo Revision 3
+ //
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ BlkIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ } else {
+ BlkIo->Revision = BLKIO_REVISION;
+ }
+ BlkIo->Media = BlkMedia;
+ BlkIo->Reset = AtaReset;
+ BlkIo->ReadBlocks = AtaBlkRead;
+ BlkIo->WriteBlocks = AtaBlkWrite;
+ BlkIo->FlushBlocks = AtaBlkFlush;
+
+ BlkMedia->MediaId = 0;
+ BlkMedia->RemovableMedia = (IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 0x80) == 0x80 ? TRUE : FALSE;
+
+ //Check if Hot plug supported for this device
+ Current_Channel = IdeBusInterface->IdeDevice.Channel;
+ Current_Device = IdeBusInterface->IdeDevice.Device;
+ bTemp = Current_Channel == 0 ? 1 : 4; // BIT MASK
+
+ if ( Current_Device ) {
+ bTemp <<= 1;
+ }
+
+ if ( bTemp & IdeBusInterface->IdeBusInitInterface->HPMask ) {
+ BlkMedia->RemovableMedia = TRUE;
+ }
+
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->LogicalPartition = FALSE;
+ BlkMedia->ReadOnly = FALSE;
+ BlkMedia->WriteCaching = FALSE;
+
+
+ if((IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[13] + \
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+
+ BlkMedia->BlockSize = SectorSize;
+
+ //If BusMaster Support is Enabled for the device, IO Alignment should be DWORD
+
+ if ( DMACapable( IdeBusInterface )) {
+ BlkMedia->IoAlign = 4;
+ } else {
+ BlkMedia->IoAlign = 0;
+ }
+
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ BlkMedia->LastBlock = IdeBusInterface->IdeDevice.IdentifyData.LBA_48 - 1;
+ } else {
+ BlkMedia->LastBlock = IdeBusInterface->IdeDevice.IdentifyData.Addressable_Sector_60 - 1;
+ }
+
+ if(pST->Hdr.Revision >= 0x0002001F) {
+
+ BlkMedia->OptimalTransferLengthGranularity=BlkMedia->BlockSize;
+ //
+ // bit 14 of word 106 is set to one and bit 15 of word 106 is cleared to zero,
+ // then the contents of word 106 contain valid information .
+ // Otherwise, information is not valid in this word.
+ //
+ if ( (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & 0xC000) == 0x4000 ) {
+ //
+ // If bit 13 of word 106 is set to one, then the device has more than one
+ // logical sector per physical sector and bits (3:0) of word 106 are valid
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & 0x2000 ) {
+
+ BlkMedia->LogicalBlocksPerPhysicalBlock = 1 <<
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & 0xF);
+
+ //
+ // Bits 13:0 of word 209 indicate the Logical sector offset within the first physical
+ // sector where the first logical sector is placed
+ //
+ BlkMedia->LowestAlignedLba =IdeBusInterface->IdeDevice.IdentifyData.Reserved_206_254[3] & 0x3FFF;
+
+ } else {
+ //
+ // Default set the 1 logical blocks per PhysicalBlock
+ //
+ BlkMedia->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ BlkMedia->LowestAlignedLba=0;
+ }
+ } else {
+ //
+ // Default set the 1 logical blocks per PhysicalBlock
+ //
+ BlkMedia->LogicalBlocksPerPhysicalBlock=1;
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ BlkMedia->LowestAlignedLba=0;
+ }
+ }
+ } else {
+ //
+ //If it is an ATAPI device, check whether it is a CDROM or not. Currently only CDROM/Direct access Devices are supported.
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 0x1f00) == (CDROM_DEVICE << 8)
+ || (IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 0x1f00) == (DIRECT_ACCESS_DEVICE << 8)
+ || (IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 0x1f00) == (OPTICAL_MEMORY_DEVICE << 8)) {
+ AtapiDevice = MallocZ( sizeof (ATAPI_DEVICE));
+
+ if ( !AtapiDevice ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ IdeBusInterface->IdeDevice.AtapiDevice = AtapiDevice;
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 16,
+ (VOID**)&Data
+ );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ AtapiDevice->PacketBuffer = Data;
+ AtapiDevice->DeviceType = (IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 0x1f00) >> 8;
+ AtapiDevice->PacketSize = (IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 3) == 1 ? 16 : 12;
+
+ BlkIo = &(IdeBlkIo->BlkIo);
+ //
+ // UEFI2.3.1 Supports the BlockIo Revision 3
+ //
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ BlkIo->Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ } else {
+ BlkIo->Revision = BLKIO_REVISION;
+ }
+ BlkIo->Media = BlkMedia;
+ BlkIo->Reset = AtapiReset;
+ BlkIo->ReadBlocks = AtapiBlkRead;
+ BlkIo->WriteBlocks = AtapiBlkWrite;
+ BlkIo->FlushBlocks = AtapiBlkFlush;
+ //
+ //Initialize with default value. Later on it will be updated if needed.
+ //
+ BlkMedia->BlockSize = CDROM_BLOCK_SIZE;
+
+
+ //
+ //Update Inquiry Data
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ INQUIRY_DATA_LENGTH,
+ (VOID**)&InquiryData );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ InquiryDataSize = INQUIRY_DATA_LENGTH;
+ AtapiInquiryData( IdeBusInterface, InquiryData, &InquiryDataSize );
+ AtapiDevice->InquiryData = InquiryData;
+ AtapiDevice->InquiryDataSize = InquiryDataSize;
+
+ //
+ // Get the ATAPI drive Type information and save it ATAPI_DEVICE
+ //
+ Status = GetOddType( IdeBusInterface, &OddType );
+
+ if ( !EFI_ERROR( Status )) {
+ AtapiDevice->OddType = GetEnumOddType( OddType );
+ }
+
+ //
+ // Get the ATAPI drive Loading information and save it ATAPI_DEVICE
+ //
+ Status = GetOddLoadingType( IdeBusInterface, &OddLoadingType );
+
+ if ( !EFI_ERROR( Status )) {
+ AtapiDevice->OddLoadingType = (ODD_LOADING_TYPE)OddLoadingType;
+ } else {
+ AtapiDevice->OddLoadingType = (ODD_LOADING_TYPE)0xFF;
+ }
+
+ BlkMedia->RemovableMedia = (IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 0x80) == 0x80 ? TRUE : FALSE;
+ BlkMedia->LogicalPartition = FALSE;
+ BlkMedia->WriteCaching = FALSE;
+
+ //
+ //If BusMaster Support is Enabled for the device, IO Alignment should be DWORD
+ //
+ if ( DMACapable( IdeBusInterface )) {
+ BlkMedia->IoAlign = 4;
+ } else {
+ BlkMedia->IoAlign = 0;
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetEnumOddType
+//
+// Description: Get the Enum value for ODD type found on profile
+//
+// Input:
+//
+// UINT16 Oddtype
+// Output:
+// ODD_TYPE EnumValue
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ODD_TYPE GetEnumOddType(
+ UINT16 OddType )
+{
+ switch ( OddType )
+ {
+ case 1:
+ case 3:
+ case 4:
+ case 5:
+ return Obsolete;
+
+ case 2:
+ return Removabledisk;
+
+ case 8:
+ return CDROM;
+
+ case 9:
+ return CDR;
+
+ case 0xa:
+ return CDRW;
+
+ case 0x10:
+ return DVDROM;
+
+ case 0x11:
+ return DVDRSequentialrecording;
+
+ case 0x12:
+ return DVDRAM;
+
+ case 0x13:
+ return DVDRWRestrictedOverwrite;
+
+ case 0x15:
+ return DVDRWSequentialrecording;
+
+ case 0x16:
+ return DVDRDualLayerJumprecording;
+
+ case 0x17:
+ return DVDRWDualLayer;
+
+ case 0x18:
+ return DVDDownloaddiscrecording;
+
+ case 0x1a:
+ return DVDRW;
+
+ case 0x1b:
+ return DVDR;
+
+ case 0x40:
+ return BDROM;
+
+ case 0x41:
+ return BDRSequentialRecording;
+
+ case 0x42:
+ return BDRRandomRecordingMode;
+
+ case 0x43:
+ return BDRE;
+
+ case 0x50:
+ return HDDVDROM;
+
+ case 0x51:
+ return HDDVDR;
+
+ case 0x52:
+ return HDDVDRAM;
+
+ case 0x53:
+ return HDDVDRW;
+
+ case 0x58:
+ return HDDVDRDualLayer;
+
+ case 0x5a:
+ return HDDVDRWDualLayer;
+
+ default:
+ return UnknownType;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitIdeDiskInfo
+//
+// Description: Initializes IDE DiskInfo Interface
+//
+// Input:
+//
+// IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool OpenProtocol
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitIdeDiskInfo(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+ IDE_DISK_INFO *IdeDiskInfo;
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(IDE_DISK_INFO),
+ (VOID**)&IdeDiskInfo );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ //Initialize the IdeBlkIo pointer in IDE_BUS_PROTOCOL (IdeBusInterface)
+ //
+ IdeBusInterface->IdeDiskInfo = IdeDiskInfo;
+
+ //
+ //Initialize the fields in IdeDiskInfo (IDE_DISK_INFO)
+ //
+ IdeDiskInfo->IdeBusInterface = IdeBusInterface;
+
+ pBS->CopyMem( &(IdeDiskInfo->DiskInfo.Interface), &gEfiIdeDiskInfoProtocolGuid, sizeof (EFI_GUID));
+ IdeDiskInfo->DiskInfo.Inquiry = DiskInfoInquiry;
+ IdeDiskInfo->DiskInfo.Identify = DiskInfoIdentify;
+ IdeDiskInfo->DiskInfo.SenseData = DiskInfoSenseData;
+ IdeDiskInfo->DiskInfo.WhichIde = DiskInfoWhichIDE;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateIdeDevicePath
+//
+// Description: Creates a IDE device devicepath and adds it to IdeBusInterface
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface;
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+// UINT8 Current_Channel
+// UINT8 Current_Device
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePool, OpenProtocol, IdeBusStart
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If Remaining Devicepath is not NULL, we have already verified that it is a
+// valid Atapi device path in IdeBusStart. So nothing to do. Just exit.
+// 2. Build a Atapi devicepath and a End devce path.
+// 3. Get the Devicepath for the IDE controller.
+// 3. Append Atapi devicepath to IDE controller devicepath.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateIdeDevicePath(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface,
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ IN UINT8 Current_Channel,
+ IN UINT8 Current_Device )
+{
+ EFI_STATUS Status;
+ ATAPI_DEVICE_PATH NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+
+ NewDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+ NewDevicePath.Header.SubType = MSG_ATAPI_DP;
+ SET_NODE_LENGTH( &NewDevicePath.Header, ATAPI_DEVICE_PATH_LENGTH );
+ NewDevicePath.PrimarySecondary = Current_Channel;
+ NewDevicePath.SlaveMaster = Current_Device;
+ NewDevicePath.Lun = 0;
+
+ //
+ //Append the Device Path
+ //
+ Status = pBS->OpenProtocol( Controller,
+ &gDevicePathProtocolGuid,
+ (VOID**)&TempDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ IdeBusInterface->DevicePathProtocol = DPAddNode( TempDevicePath, &NewDevicePath.Header );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ConfigureIdeDevice
+//
+// Description: Issues SET FEATURE Command
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface,
+// IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ConfigureIdeDeviceAndController, IdeSetFeatureCommand
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Issue Set feature commend to set PIO mode if needed.
+// 2. Set Multiple Mode command for ATA devices if needed.
+// 3. Issue Set feature commend to set UDMA/MWDMA. If it fails, disable Busmaster support.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ConfigureIdeDevice(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface )
+{
+ EFI_STATUS Status= EFI_SUCCESS;
+ UINT8 DMACapability;
+ UINT8 Data8;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT16 DeviceName[41];
+ UINT16 Index;
+
+ EFI_UNICODE_STRING_TABLE *tempUnicodeTable;
+ CHAR8 Language[] = "Eng";
+
+ //
+ //Check if Device need spin-up
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.General_Config_0 & 4)
+ && (IdeBusInterface->IdeDevice.IdentifyData.Special_Config_2 == SPIN_UP_REQUIRED1
+ || IdeBusInterface->IdeDevice.IdentifyData.Special_Config_2 == SPIN_UP_REQUIRED2)) {
+ Status = IdeSetFeatureCommand( IdeBusInterface, SET_DEVICE_SPINUP, 0 );
+
+ if ( EFI_ERROR( Status )) {
+ //
+ //Some HDD may take a long time to spin up. Wait for additional time
+ //
+ Status = WaitforBitClear( IdeBusInterface->PciIO, Regs.ControlBlock.AlternateStatusReg, BSY | DRQ, gPlatformIdeProtocol->PoweonBusyClearTimeout );
+ }
+ //
+ //Get the Identify Command once more
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+ }
+
+ //
+ // Check if PIO mode needs to be programmed
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.Valid_Bits_53 & 0x2) && (IdeBusInterface->IdeDevice.PIOMode != 0xff)) {
+ Status = IdeSetFeatureCommand( IdeBusInterface, SET_TRANSFER_MODE, PIO_FLOW_CONTROL | IdeBusInterface->IdeDevice.PIOMode );
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Issue Set Multiple Mode Command only for ATA device
+ //
+ if ( IdeBusInterface->IdeDevice.DeviceType == ATA ) {
+ Data8 = IdeBusInterface->IdeDevice.IdentifyData.Maximum_Sector_Multiple_Command_47 & 0xff;
+
+ if ( Data8 & 0x2 ) {
+ Data8 = 2;
+ }
+
+ if ( Data8 & 0x4 ) {
+ Data8 = 0x4;
+ }
+
+ if ( Data8 & 0x8 ) {
+ Data8 = 0x8;
+ }
+
+ if ( Data8 & 0x10 ) {
+ Data8 = 0x10;
+ }
+
+ if ( Data8 & 0x20 ) {
+ Data8 = 0x20;
+ }
+
+ if ( Data8 & 0x40 ) {
+ Data8 = 0x40;
+ }
+
+ if ( Data8 & 0x80 ) {
+ Data8 = 0x80;
+ }
+
+ if ( Data8 > 1 ) {
+ Status = IdeNonDataCommand(
+ IdeBusInterface,
+ 0, // Features
+ Data8, // Sector Count
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ SET_MULTIPLE_MODE ); // Command
+ }
+ }
+
+ //Check if Busmaster Enabled
+ //Status = EFI_NOT_FOUND;
+ //Check if UDMA is supported
+ if ( IdeBusInterface->IdeDevice.UDma != 0xff ) {
+ Status = IdeSetFeatureCommand( IdeBusInterface, SET_TRANSFER_MODE, UDMA_MODE | IdeBusInterface->IdeDevice.UDma );
+ } else {
+ if ( IdeBusInterface->IdeDevice.MWDma != 0xff ) {
+ Status = IdeSetFeatureCommand( IdeBusInterface, SET_TRANSFER_MODE, MWDMA_MODE | IdeBusInterface->IdeDevice.MWDma );
+ }
+ }
+
+ if ( EFI_ERROR( Status )) {
+ //
+ //No DMA support
+ //
+ IdeBusInterface->IdeDevice.UDma = 0xff;
+ IdeBusInterface->IdeDevice.MWDma = 0xff;
+ } else {
+ //
+ //Enable DMA capable bit
+ //
+ DMACapability = 0x20;
+
+ if ( IdeBusInterface->IdeDevice.Device ) {
+ DMACapability = 0x40;
+ }
+
+ if ( DMACapable( IdeBusInterface )) {
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister,
+ &Data8 );
+ Data8 |= DMACapability;
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister,
+ Data8 );
+ }
+ }
+
+ //
+ //Convert the Device string from Engligh to Unicode
+ //
+ IdeBusInterface->IdeDevice.UDeviceName = NULL;
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ IdeBusInterface->ControllerNameTable = IdeBusInterface->IdeDevice.UDeviceName;
+ }
+
+ for ( Index = 0; Index < 40; Index += 2 ) {
+
+ DeviceName[Index] = ((UINT8*)IdeBusInterface->IdeDevice.IdentifyData.Model_Number_27)[Index + 1];
+ DeviceName[Index + 1] = ((UINT8*)IdeBusInterface->IdeDevice.IdentifyData.Model_Number_27)[Index];
+ }
+
+ for ( Index = 39; Index >= 0; Index-- ) {
+ if ( DeviceName[Index] == 0x20 )
+ continue;
+ else
+ break;
+ }
+
+ DeviceName[Index + 1] = 0; // Terminate string
+ Index += 2;
+
+ //
+ //This is a patch to make it work for both in Aptio and Alaska
+ //
+ tempUnicodeTable = MallocZ( sizeof (EFI_UNICODE_STRING_TABLE) * 2 );
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof (Language),
+ (VOID**)&tempUnicodeTable[0].Language
+ );
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ Index * (sizeof (UINT16)),
+ (VOID**)&tempUnicodeTable[0].UnicodeString
+ );
+
+
+ pBS->CopyMem( tempUnicodeTable[0].Language, &Language, sizeof(Language));
+ pBS->CopyMem( tempUnicodeTable[0].UnicodeString, DeviceName, Index * (sizeof (UINT16)));
+ tempUnicodeTable[1].Language = NULL;
+ tempUnicodeTable[1].UnicodeString = NULL;
+ IdeBusInterface->IdeDevice.UDeviceName = tempUnicodeTable;
+ if ( gPlatformIdeProtocol->EfiIdeProtocol ) {
+ IdeBusInterface->ControllerNameTable = IdeBusInterface->IdeDevice.UDeviceName;
+ }
+ if ( gPlatformIdeProtocol->SBIdeSupport ) {
+ InitMiscConfig(IdeBusInterface);
+ }
+
+ if ( gPlatformIdeProtocol->IdePowerManagementSupport ) {
+ Status = InitIDEPowerManagement( IdeBusInterface );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitMiscConfig
+//
+// Description: Initialize misc IDE configurations.
+//
+// Input:
+// IN SATA_DEVICE_INTERFACE *SataDevInterface
+//
+// Output:
+// None
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID InitMiscConfig (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface
+)
+{
+ if ( gPlatformIdeProtocol->DiPMSupport ) {
+
+ if(IdeBusInterface->IdeDevice.IdentifyData.Reserved_76_79[2] & \
+ IDENTIFY_DiPM__SUPPORT) { // DiPM supported?
+ //
+ // Always disable DiPM in IDE mode
+ //
+ IdeSetFeatureCommand (IdeBusInterface, DiPM_DISABLE, DiPM_SUB_COMMAND);
+ }
+ }
+ if ( gPlatformIdeProtocol->AcousticManagementSupport ) {
+ InitAcousticSupport (IdeBusInterface);
+ }
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitAcousticSupport
+//
+// Description: Initializes Acoustic Management Support functionality
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeSetFeatureCommand
+//
+// Notes:
+// 1. Check if the device support Acoustic management.
+// 2. Check the desired state Vs the current state.
+// 3. If both are equal nothing to do exit else program the desired level
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitAcousticSupport(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT8 Data8;
+
+ //
+ // Check if the device supports Acoustic Management
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x200 ) {
+ //
+ //Check if Acoustic Level need to be enabled or Disabled
+ //
+ if ( IdeBusInterface->IdeBusInitInterface->Flags & ACOUSTIC_SUPPORT_ENABLE ) {
+ Data8 = IdeBusInterface->IdeBusInitInterface->Acoustic_Management_Level;
+
+ //
+ // Do we need to program the recommended value
+ //
+ if ( Data8 == ACOUSTIC_LEVEL_BYPASS ) {
+ //
+ // Get the rcommended value
+ //
+ Data8 = (UINT8)(IdeBusInterface->IdeDevice.IdentifyData.Acoustic_Level_94 >> 8);
+ }
+
+ IdeSetFeatureCommand (IdeBusInterface, ACOUSTIC_MANAGEMENT_ENABLE, Data8);
+ } else {
+ //
+ // If already disabled, nothing to do
+ //
+ if (IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_86 & 0x200)
+ IdeSetFeatureCommand (IdeBusInterface, ACOUSTIC_MANAGEMENT_DISABLE, 0);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdateBaseAddress
+//
+// Description: Updates Command and Control reg address.
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeBusStart
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Using PCI_IO_PROTOCOL, update the Command, control and Busmaster reg address.
+// Make use of Channel number while updating. Also check whether controller is running in Legacy/Native mode
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UpdateBaseAddress(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ UINT8 PciConfig[0x40];
+ UINT16 CommandReg;
+ UINT16 ControlReg;
+ UINT16 BusMasterReg;
+
+
+ PciIO = IdeBusInterface->PciIO;
+ PciIO->Pci.Read(
+ PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig );
+
+ if ((PciConfig [PROGRAMMING_INTERFACE_OFFSET] & (IdeBusInterface->IdeDevice.Channel == 0 ? 1 : 4))
+ || (PciConfig [IDE_SUB_CLASS_CODE] == SCC_AHCI_CONTROLLER)
+ || (PciConfig [IDE_SUB_CLASS_CODE] == SCC_RAID_CONTROLLER)) {
+ //
+ //Native Mode Secondary
+ //
+ if ( IdeBusInterface->IdeDevice.Channel ) {
+ CommandReg = (*(UINT16*)(PciConfig + SECONDARY_COMMAND_BLOCK_OFFSET)) & 0xfffe;
+ ControlReg = ((*(UINT16*)(PciConfig + SECONDARY_CONTROL_BLOCK_OFFSET)) & 0xfffe) + 2;
+ BusMasterReg = ((*(UINT16*)(PciConfig + LEGACY_BUS_MASTER_OFFSET)) & 0xfffe) + 8;
+ } else {
+ //
+ // Native mode Primary
+ //
+ CommandReg = (*(UINT16*)(PciConfig + PRIMARY_COMMAND_BLOCK_OFFSET)) & 0xfffe;
+ ControlReg = ((*(UINT16*)(PciConfig + PRIMARY_CONTROL_BLOCK_OFFSET)) & 0xfffe) + 2;
+ BusMasterReg = (*(UINT16*)(PciConfig + LEGACY_BUS_MASTER_OFFSET)) & 0xfffe;
+ }
+ } else {
+ //
+ //Legacy Mode Secondary
+ //
+ if ( IdeBusInterface->IdeDevice.Channel ) {
+ CommandReg = SECONDARY_COMMAND_BLOCK;
+ ControlReg = SECONDARY_CONTROL_BLOCK;
+ BusMasterReg = (*(UINT16*)(PciConfig + LEGACY_BUS_MASTER_OFFSET) & 0xfffe) + 8;
+ } else {
+ //
+ //Legacy mode Primary
+ //
+ CommandReg = PRIMARY_COMMAND_BLOCK;
+ ControlReg = PRIMARY_CONTROL_BLOCK;
+ BusMasterReg = (*(UINT16*)(PciConfig + LEGACY_BUS_MASTER_OFFSET) & 0xfffe);
+ }
+ }
+
+ //
+ // Validate the Address
+ //
+ if ( CommandReg == 0 || ControlReg == 0 ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( CommandReg == 0xfffe || ControlReg == 0xfffe ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ //Update the Command block registers
+ //
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.DataReg = CommandReg;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.FeatureReg = CommandReg + 1;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.ErrorReg = CommandReg + 1;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.SectorCountReg = CommandReg + 2;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBALowReg = CommandReg + 3;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAMidReg = CommandReg + 4;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAHighReg = CommandReg + 5;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.DeviceReg = CommandReg + 6;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.CommandReg = CommandReg + 7;
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.StatusReg = CommandReg + 7;
+
+ //
+ //Update the Control Block Register address
+ //
+ IdeBusInterface->IdeDevice.Regs.ControlBlock.DeviceControlReg = ControlReg;
+ IdeBusInterface->IdeDevice.Regs.ControlBlock.AlternateStatusReg = ControlReg;
+
+
+ //
+ //Update the Bus Master register address
+ //
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMCommandRegister = BusMasterReg;
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister = BusMasterReg + 2;
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMDescriptorTablePointerReg = BusMasterReg + 4;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DMACapable
+//
+// Description: Check if DMA is supported
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// TRUE : DMA Capable
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN DMACapable(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ if ( IdeBusInterface->IdeDevice.DeviceType == ATAPI ) {
+ //
+ // For Atapi Devices check Bit 8 in Word 49 = DMA Supported or not
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.Capabilities_49 & 0x100) == 0 ) {
+ return FALSE;
+ }
+ }
+
+ if ((IdeBusInterface->IdeDevice.UDma != 0xff)
+ || (IdeBusInterface->IdeDevice.MWDma != 0xff)) {
+ return TRUE;
+ } else {
+ return FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DiskInfoInquiry
+//
+// Description:
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This,
+// IN OUT VOID *InquiryData,
+// IN OUT UINT32 *InquiryDataSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeDiskInfo
+//
+// Notes:
+// 1. Check for Atapi Device. If not exit
+// 2. COpy the Inquiry Data from AtapiDevice->InquiryData to the input pointer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DiskInfoInquiry(
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *InquiryData,
+ IN OUT UINT32 *InquiryDataSize )
+{
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+
+
+ //
+ // Check for ATAPI device. If not return EFI_NOT_FOUND
+ //
+ if ( IdeBusInterface->IdeDevice.DeviceType == ATA ) {
+ return EFI_NOT_FOUND;
+ } else {
+ if ( *InquiryDataSize < AtapiDevice->InquiryDataSize ) {
+ *InquiryDataSize = AtapiDevice->InquiryDataSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ if ( AtapiDevice->InquiryData != NULL ) {
+ pBS->CopyMem( InquiryData, AtapiDevice->InquiryData, AtapiDevice->InquiryDataSize );
+ *InquiryDataSize = AtapiDevice->InquiryDataSize;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_FOUND;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DiskInfoIdentify
+//
+// Description: Return Identify Data
+//
+// Input:
+// EFI_DISK_INFO_PROTOCOL *This,
+// IN OUT VOID *IdentifyData,
+// IN OUT UINT32 *IdentifyDataSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeDiskInfo
+//
+// Notes:
+// 1. Return the Identify command data.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DiskInfoIdentify(
+ EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *IdentifyData,
+ IN OUT UINT32 *IdentifyDataSize )
+{
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+
+ if ( *IdentifyDataSize < sizeof (IDENTIFY_DATA)) {
+ *IdentifyDataSize = sizeof (IDENTIFY_DATA);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ pBS->CopyMem( IdentifyData, &(IdeBusInterface->IdeDevice.IdentifyData), sizeof (IDENTIFY_DATA));
+ *IdentifyDataSize = sizeof (IDENTIFY_DATA);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DiskInfoSenseData
+//
+// Description: Return InfoSenseData.
+//
+// Input:
+// EFI_DISK_INFO_PROTOCOL *This,
+// VOID *SenseData,
+// UINT32 *SenseDataSize,
+// UINT8 *SenseDataNumber
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeDiskInfo
+//
+// Notes:
+// 1. Return the Sense data for the Atapi device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DiskInfoSenseData(
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT VOID *SenseData,
+ OUT UINT32 *SenseDataSize,
+ OUT UINT8 *SenseDataNumber )
+{
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: DiskInfoWhichIDE
+//
+// Description: Returns whether the device is PM/PS/SM/SS
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This,
+// OUT UINT32 *IdeChannel,
+// OUT UINT32 *IdeDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitIdeDiskInfo
+//
+// Notes:
+// 1. Return information about the Primary/Secondary channel and Master/Slave information.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DiskInfoWhichIDE(
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT UINT32 *IdeChannel,
+ OUT UINT32 *IdeDevice )
+{
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((IDE_BLOCK_IO*)This)->IdeBusInterface;
+
+ *IdeChannel = IdeBusInterface->IdeDevice.Channel;
+ *IdeDevice = IdeBusInterface->IdeDevice.Device;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdeHPTimer
+//
+// Description: Checks for any HP IDE device
+//
+// Input:
+// IN EFI_EVENT Event,
+// IN VOID *Context
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IdeHPTimer(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ UINT8 DeviceStatus;
+ UINT8 CurrentState;
+ UINT8 Current_Channel;
+ UINT8 Current_Device;
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface = (IDE_BUS_INIT_PROTOCOL*)Context;
+
+ IDE_BUS_PROTOCOL *IdeBusInterface;
+ IN IDE_CONTROLLER_PROTOCOL *IdeControllerInterface = IdeBusInitInterface->IdeControllerInterface;
+
+ IdeControllerInterface->HPCheckForDeviceChange( IdeControllerInterface->PciIO,
+ IdeBusInitInterface->HPMask,
+ &DeviceStatus );
+
+ for ( Current_Channel = PRIMARY_CHANNEL; Current_Channel <= SECONDARY_CHANNEL; Current_Channel++ )
+ {
+ for ( Current_Device = MASTER_DRIVE; Current_Device <= SLAVE_DRIVE; Current_Device++ )
+ {
+ CurrentState = IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device];
+ IdeBusInterface = IdeBusInitInterface->pIdeBusProtocol[Current_Channel][Current_Device];
+
+ if ((CurrentState == DEVICE_CONFIGURED_SUCCESSFULLY) && ((DeviceStatus & 01) == 0)) {
+ //
+ //Handle Device Removal
+ //
+ Status = pBS->DisconnectController( IdeControllerInterface->ControllerHandle, NULL, IdeBusInterface->IdeDeviceHandle );
+
+
+ if ( Status == EFI_SUCCESS ) {
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_IN_RESET_STATE;
+ }
+ }
+
+ if ((CurrentState != DEVICE_CONFIGURED_SUCCESSFULLY) && ((DeviceStatus & 01) == 1)) {
+ //Handle device insertion
+ //Force IdeBusStart to Enumerate this device.
+ IdeBusInitInterface->IdeBusInitData[Current_Channel][Current_Device] = DEVICE_IN_RESET_STATE;
+
+ pBS->ConnectController( IdeControllerInterface->ControllerHandle, NULL, NULL, TRUE );
+ }
+ DeviceStatus >>= 1;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckHPControllerPresence
+//
+// Description: A quick check to see if ports are still decoded.
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckHPControllerPresence(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT8 Device = IdeBusInterface->IdeDevice.Device;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.DeviceReg, Device << 4 );
+
+ //
+ //Read the status Register
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.CommandBlock.StatusReg, &Data8 );
+
+ if ( Data8 == 0xff ) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ( Data8 == 0x7f ) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+ // IDE_HP_SUPPORT
+//---------------------------------------------------------------------------
+
+#ifdef Debug_Level_3
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PrintIdeDeviceInfo
+//
+// Description: Prints Debug Level 3 Trace Messages
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void PrintIdeDeviceInfo(
+ IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ UINT16 Data8;
+ UINT16 *pIdentifyData;
+
+ // Print the Channel and Device Number
+ EfiDebugPrint( -1, "-----------------IDE Device Info Start-----------------\n" );
+ EfiDebugPrint( -1, "Channel : %x Device : %x\n", IdeBusInterface->IdeDevice.Channel, IdeBusInterface->IdeDevice.Device );
+ EfiDebugPrint( -1, "PIOMode : %x UDMAMode : %x\n", IdeBusInterface->IdeDevice.PIOMode, IdeBusInterface->IdeDevice.UDma );
+ EfiDebugPrint( -1, "SWDMAMode : %x MWDMAMode : %x\n", IdeBusInterface->IdeDevice.SWDma, IdeBusInterface->IdeDevice.MWDma );
+ EfiDebugPrint( -1, "IORDY : %x \n", IdeBusInterface->IdeDevice.IORdy );
+ pIdentifyData = (UINT16*) &(IdeBusInterface->IdeDevice.IdentifyData);
+
+ for ( Data8 = 0; Data8 < 0xff; Data8 += 4 )
+ {
+ EfiDebugPrint( -1, "%X %X %X %X\n", pIdentifyData[Data8 + 0], pIdentifyData[Data8 + 1], pIdentifyData[Data8 + 2], pIdentifyData[Data8 + 3] );
+ }
+ EfiDebugPrint( -1, "-----------------IDE Device Info End-------------------\n" );
+}
+
+#endif /* Debug_Level_3 */
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckAhciMode
+//
+// Description: Checks If the controller is in AHCI MODE.
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// BOOLEAN TRUE - AHCI Mode
+// FALSE - IDE Mode
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckAhciMode(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ UINT8 PciConfig[0x40];
+ BOOLEAN AhciFlag = FALSE;
+
+ PciIO = IdeBusInterface->PciIO;
+ PciIO->Pci.Read(
+ PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PciConfig),
+ PciConfig );
+
+ AhciFlag = (BOOLEAN)((PciConfig [IDE_SUB_CLASS_CODE] & SCC_AHCI_CONTROLLER) ? TRUE : FALSE );
+
+ return AhciFlag;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssueFreezeLockCommand
+//
+// Description: Issue the Freeze lock command.
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS IssueFreezeLockCommand(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_82 & 0x2 ) {
+ Status = IdeNonDataCommand( IdeBusInterface, 0, 0,
+ 0, 0, 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ SECURITY_FREEZE_LOCK );
+ //
+ //Update the Identify device buffer
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+ }
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/IdeBus.chm b/Core/EM/IdeBus/IdeBus.chm
new file mode 100644
index 0000000..5b8094a
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBus.chm
Binary files differ
diff --git a/Core/EM/IdeBus/IdeBus.cif b/Core/EM/IdeBus/IdeBus.cif
new file mode 100644
index 0000000..73a732d
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBus.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "IdeBus"
+ category = ModulePart
+ LocalRoot = "Core\EM\IdeBus\"
+ RefName = "IdeBus"
+[files]
+"IdeBus.sdl"
+"IdeBus.mak"
+"IdeBus.chm"
+[parts]
+"IDEBusProtocol"
+"IdeBusBoard"
+<endComponent>
diff --git a/Core/EM/IdeBus/IdeBus.h b/Core/EM/IdeBus/IdeBus.h
new file mode 100644
index 0000000..7b77dbf
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBus.h
@@ -0,0 +1,821 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBus.h 29 7/20/12 6:14a Anandakrishnanl $
+//
+// $Revision: 29 $
+//
+// $Date: 7/20/12 6:14a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBus.h $
+//
+// 29 7/20/12 6:14a Anandakrishnanl
+// [TAG] EIP88683
+// [Category] New Feature
+// [Description] EFI_ATA_PASS_THRU_PROTOCOL Support for Aptio IDE
+// [Files] AhciBus.c
+// AhciBus.h
+// AInt13.h
+// IdeBus.c
+// IdeBus.h
+// PIDEBus.h
+// PAhciBus.h
+// AtaPassThru.sdl
+// AtaPassThru.mak
+// AtaPassThru.c
+// AtaPassThruSupport.h
+// AtaPassThru.chm
+//
+// 28 12/05/11 6:12p Rajkumarkc
+// [TAG] EIP77142
+// [Category] Improvement
+// [Description] Added the function 'IdeNonDataCommandExp' in the
+// 'IDE_BUS_PROTOCOL' and removed
+// the existing function 'IdeNonDataCommand' for supporting
+// the upper 24bits of LBA.
+// [Files]
+// Ata.c
+// IdeBus.c
+// Idebus.h
+// PIDEBus.h
+//
+// 27 9/27/11 3:14a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 26 4/12/11 4:06a Rameshr
+// [TAG]- EIP 53710
+// [Category]- New Feature
+// [Description]- ATAPI ODD loading type information added into ATAPI
+// device structure
+// [Files]- Atapi.c, Idebus.c, IdeBus.h
+//
+// 25 12/23/10 3:55a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 24 11/08/10 6:11p Felixp
+// The Core source files are updated to remove upper ASCII characters
+// (above 128)
+// from the comment blocks. The characters caused build errors
+// with Japanese version of Microsoft compiler.
+//
+// 23 8/25/10 4:14a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+// IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+// IdeHpa.c, IdePowerManagement.c
+//
+// 22 7/01/09 12:22p Rameshr
+// Coding Standard and File header updated.
+//
+// 21 6/22/09 11:39a Rameshr
+// Odd Type information Saved in Atapi Device Structure.
+// EIP:21548
+//
+// 20 5/01/09 5:17p Felixp
+// Prototype for WaitForCmdCompletionWithTimeOutValue is added to resolve
+// compilation error.
+//
+// 19 7/03/08 5:40p Anandakrishnanl
+// Removed Smart related Definitions and Function Prototypes since Smart
+// feature is in Seperate Driver Now.
+//
+// 16 28/02/08 7:00p Anandakrishnanl
+// Removed few definitions and function declarations and moved to
+// IdeSecurity module.
+//
+// 15 10/23/07 4:16p Felixp
+// IDE Security support moved from Sources to Binary
+//
+// 14 14/08/07 1:51p Anandakrishnanl
+// Changes made for password storing in NVRAM which converts HDD dataInfo
+// to string in ConvertHddDataIdToString function.
+//
+// 13 22/06/07 12:40p Anandakrishnanl
+// HardDisk Security Support Module Added.
+// Need ACPI Module and SB Module and under Core\Include we updated
+// Setup.h.
+// Also New IdeBus bin module.
+//
+// 12 13/04/07 3:02p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with "AMI coding
+// standard"!!!
+//
+// 11 2/12/07 3:39p Pats
+// Increased POWERON_BUSY_CLEAR_TIMEOUT to 10 sec.
+//
+// 10 11/17/06 2:58p Ambikas
+//
+// 9 10/27/06 4:20p Felixp
+// Reverted back to the previous version
+//
+// 7 8/24/06 9:30a Felixp
+// x64 support (bug fixes)
+//
+// 5 3/13/06 2:20a Felixp
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:02p Srinin
+// HDD password related equates added.
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 10 11/03/05 10:41a Srinin
+// VC7 compilation error fixed.
+//
+// 9 3/04/05 11:33a Mandal
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IdeBus.h
+//
+// Description: This file contains the Includes, Definitions, typedefs,
+// Variable and External Declarations, Structure and
+// function prototypes needed for the IdeBus driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#ifndef _IdeBus_
+#define _IdeBus_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include <Protocol\ComponentName.h>
+#include <Protocol\BootScriptSave.h>
+#include <protocol\AtaPassThru.h>
+
+
+#define IDE_BUS_DRIVER_VERSION 0x01
+
+#define PRIMARY_COMMAND_BLOCK 0x1F0
+#define PRIMARY_CONTROL_BLOCK 0x3F6
+#define SECONDARY_COMMAND_BLOCK 0x170
+#define SECONDARY_CONTROL_BLOCK 0x376
+
+#define BUSY_CLEAR_TIMEOUT 1000 // 1Sec
+#define DRDY_TIMEOUT 1000 // 1Sec
+#define DRQ_TIMEOUT 10 // 10msec
+#define DRQ_CLEAR_TIMEOUT 1000 // 1sec
+#define DRQ_SET_TIMEOUT 10 // 10msec
+#define HP_COMMAND_COMPLETE_TIMEOUT 2000 // 2Sec
+#define COMMAND_COMPLETE_TIMEOUT 5000 // 5Sec
+
+#define BLKIO_REVISION 1
+
+#define DEVICE_DISABLED 0
+#define DEVICE_IN_RESET_STATE 1
+#define DEVICE_DETECTION_FAILED 2
+#define DEVICE_DETECTED_SUCCESSFULLY 3
+#define DEVICE_CONFIGURED_SUCCESSFULLY 4
+#define DEVICE_REMOVED 5
+#define CONTROLLER_NOT_PRESENT 0xff
+
+#define ENUMERATE_ALL 0xff
+#define ENUMERATE_PRIMARY_MASTER 0x0
+#define ENUMERATE_PRIMARY_SLAVE 0x1
+#define ENUMERATE_SECONDARY_MASTER 0x2
+#define ENUMERATE_SECONDARY_SLAVE 0x3
+#define INQUIRY_DATA_LENGTH 0x96
+#define READ_CAPACITY_DATA_LENGTH 0x08
+
+// PCI Config Space equates
+#define PROGRAMMING_INTERFACE_OFFSET 0x09
+#define IDE_SUB_CLASS_CODE 0x0A
+#define SCC_IDE_CONTROLLER 0x01
+#define SCC_AHCI_CONTROLLER 0x06
+#define SCC_RAID_CONTROLLER 0x04
+#define IDE_BASE_CLASS_CODE 0x0B
+#define BASE_CODE_IDE_CONTROLLER 0x01
+#define PRIMARY_COMMAND_BLOCK_OFFSET 0x10
+#define PRIMARY_CONTROL_BLOCK_OFFSET 0x14
+#define SECONDARY_COMMAND_BLOCK_OFFSET 0x18
+#define SECONDARY_CONTROL_BLOCK_OFFSET 0x1C
+#define LEGACY_BUS_MASTER_OFFSET 0x20
+
+#define EFI_SUCCESS_ACTIVE_SET 0x80000000
+#define ZeroMemory( Buffer, Size ) pBS->SetMem( Buffer, Size, 0 )
+
+
+//###DEBUG Uncomment the following for Required Debug Level.
+
+//#define Debug_Level_1
+//#define Debug_Level_2
+//#define Debug_Level_3
+
+//###DEBUG END
+
+// Forward reference for pure ANSI compatability
+typedef struct _IDE_BUS_PROTOCOL IDE_BUS_PROTOCOL;
+
+typedef struct
+{
+ UINT32 Lowdword;
+ UINT32 Upperdword;
+} STRUCT_U64_U32;
+
+VOID EfiDebugPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ... );
+
+EFI_STATUS CreateIdeDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface,
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ UINT8 Current_Channel,
+ UINT8 Current_Device );
+
+EFI_STATUS InitIdeBlockIO (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS InitIdeDiskInfo (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS
+InstallBusInitProtocol(
+ IN EFI_HANDLE Controller,
+ IDE_BUS_INIT_PROTOCOL * IdeBusInitInterface,
+ VOID * IdeControllerInterface
+ );
+
+EFI_STATUS
+ConfigureIdeDeviceAndController(
+ IDE_BUS_PROTOCOL * IdeBusInterface,
+ VOID * IdeControllerInterface,
+ IDE_BUS_INIT_PROTOCOL * IdeBusInitInterface
+ );
+
+UINT8 ReturnMSBset (
+ UINT32 Data );
+
+EFI_STATUS IdeReadByte (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ OUT UINT8 *Data8 );
+
+EFI_STATUS IdeReadMultipleByte (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ OUT UINT8 *Data8 );
+
+EFI_STATUS IdeReadWord (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ OUT UINT16 *Data16 );
+
+EFI_STATUS IdeReadMultipleWord (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ OUT UINT16 *Data16 );
+
+EFI_STATUS IdeWriteByte (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT8 Data8 );
+
+EFI_STATUS IdeWriteMultipleByte (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ IN UINT8 *Data8 );
+
+EFI_STATUS IdeWriteWord (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT16 Data16 );
+
+EFI_STATUS IdeWriteMultipleWord (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Count,
+ IN UINT16 *Data16 );
+
+EFI_STATUS IdeWriteDword (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ IN UINT16 Register,
+ IN UINT32 Data32 );
+
+EFI_STATUS AtaReadWritePio (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ VOID *Buffer,
+ UINTN ByteCount,
+ UINT64 LBA,
+ UINT8 readWriteCommand,
+ BOOLEAN ReadWrite );
+
+EFI_STATUS IssueAtaReadWriteCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT64 LBA,
+ INT32 SectorCount,
+ UINT8 Command,
+ UINT8 Features );
+
+EFI_STATUS AtaPioDataIn (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ VOID *Buffer,
+ UINT32 ByteCount,
+ UINT8 Features,
+ UINT8 SectorCount,
+ UINT8 LBALow,
+ UINT8 LBAMid,
+ UINT8 LBAHigh,
+ UINT8 DeviceReg,
+ UINT8 Command,
+ BOOLEAN Multiple );
+
+EFI_STATUS AtaPioDataOut (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ VOID *Buffer,
+ UINTN ByteCount,
+ UINT8 Features,
+ UINT32 SectorCountIn,
+ UINT8 LBALow,
+ UINT8 LBALowExp,
+ UINT8 LBAMid,
+ UINT8 LBAMidExp,
+ UINT8 LBAHigh,
+ UINT8 LBAHighExp,
+ UINT8 Device,
+ UINT8 Command,
+ BOOLEAN ReadWrite,
+ BOOLEAN Multiple );
+
+EFI_STATUS IdeNonDataCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 Features,
+ UINT8 SectorCount,
+ UINT8 LBALow,
+ UINT8 LBAMid,
+ UINT8 LBAHigh,
+ UINT8 Device,
+ UINT8 Command );
+
+EFI_STATUS IdeNonDataCommandExp (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 Features,
+ UINT8 SectorCount,
+ UINT8 SectorCountExp,
+ UINT8 LBALow,
+ UINT8 LBALowExp,
+ UINT8 LBAMid,
+ UINT8 LBAMidExp,
+ UINT8 LBAHigh,
+ UINT8 LBAHighExp,
+ UINT8 Device,
+ UINT8 Command );
+
+EFI_STATUS AtaIdentifyCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer );
+
+EFI_STATUS AtapiIdentifyCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer );
+
+EFI_STATUS GetIdentifyData (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer );
+
+EFI_STATUS IdeSetFeatureCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 SubCommand,
+ UINT8 Mode );
+
+EFI_STATUS IdeSoftReset (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS WaitForCmdCompletion (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS WaitForCmdCompletionWithTimeOutValue (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT32 TimeOutvalue );
+
+EFI_STATUS CheckDriveReady (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS WaitforBitSet (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ UINT16 AlternateStatusReg,
+ UINT8 BitSet,
+ UINT32 TimeOut );
+
+EFI_STATUS WaitforBitClear (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ UINT16 AlternateStatus,
+ UINT8 BitSet,
+ UINT32 Timeout );
+
+EFI_STATUS WaitforBitClearWithoutTimeout (
+ IN EFI_PCI_IO_PROTOCOL *PciIO,
+ UINT16 AlternateStatus,
+ UINT8 BitClear );
+
+EFI_STATUS ControllerPresence (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+void DisableIdeInterrupt (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS DetectIdeDevice (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS ConfigureIdeDevice (
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ IDE_BUS_INIT_PROTOCOL *IdeBusInitInterface );
+
+EFI_STATUS InitAcousticSupport (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS UpdateBaseAddress (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS IdeBusSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS IdeBusStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS IdeBusStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer );
+
+EFI_STATUS AtaReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification );
+
+EFI_STATUS AtaBlkRead (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS AtaBlkWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer );
+
+EFI_STATUS AtaBlkFlush (
+ IN EFI_BLOCK_IO_PROTOCOL *This );
+
+EFI_STATUS AtapiReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification );
+
+EFI_STATUS AtapiBlkRead (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS AtapiBlkWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer );
+
+EFI_STATUS AtapiBlkFlush (
+ IN EFI_BLOCK_IO_PROTOCOL *This );
+
+EFI_STATUS DetectAtapiMedia (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS AtapiInquiryData (
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 *InquiryData,
+ IN OUT UINT16 *InquiryDataSize );
+
+EFI_STATUS AtapiReadWritePio (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ VOID *Buffer,
+ UINTN ByteCount,
+ UINT64 LBA,
+ UINT8 ReadWriteCommand,
+ BOOLEAN READWRITE );
+
+EFI_STATUS AtapiWritePio (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ VOID *Buffer,
+ UINTN ByteCount,
+ UINT64 LBA,
+ UINT8 WriteCommand );
+
+EFI_STATUS GeneralAtapiCommandAnddData (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 *Buffer,
+ UINT16 ByteCount );
+
+EFI_STATUS IssueAtapiPacketCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT16 *PacketBuffer,
+ UINT8 Features,
+ UINT16 ByteCount );
+
+EFI_STATUS IssueAtapiReset (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN BOOLEAN TESTUNITREADY );
+
+EFI_STATUS HandleAtapiError (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS DiskInfoInquiry (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *InquiryData,
+ IN OUT UINT32 *InquiryDataSize );
+
+EFI_STATUS DiskInfoIdentify (
+ EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *IdentifyData,
+ IN OUT UINT32 *IdentifyDataSize );
+
+EFI_STATUS DiskInfoSenseData (
+ EFI_DISK_INFO_PROTOCOL *This,
+ VOID *SenseData,
+ UINT32 *SenseDataSize,
+ UINT8 *SenseDataNumber );
+
+EFI_STATUS DiskInfoWhichIDE (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT UINT32 *IdeChannel,
+ OUT UINT32 *IdeDevice );
+
+EFI_STATUS GetOddType (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT UINT16 *OddType );
+
+EFI_STATUS GetOddLoadingType(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT UINT8 *OddLoadingType );
+
+ODD_TYPE GetEnumOddType (
+ IN UINT16 OddType );
+
+BOOLEAN Check48BitCommand (
+ UINT8 Command );
+
+EFI_STATUS StartStopUnitCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINT8 LoEjStart );
+
+EFI_STATUS TestUnitReady (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS CheckCHKonEntry (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS ReadAtapiData (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ void *Data,
+ UINT16 *BytesRead );
+
+EFI_STATUS WriteAtapiData (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ OUT void *Data,
+ OUT UINT16 *BytesRead );
+
+EFI_STATUS GeneralAtapiCommandAndData (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 *PacketBuffer,
+ UINT8 *Buffer,
+ UINT16 *ByteCount );
+
+EFI_STATUS AtaReadWriteBusMaster (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN ReadWrite );
+
+EFI_STATUS AtapiReadWriteBusMaster (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE );
+
+EFI_STATUS CreateDescriptorTable (
+ IN OUT UINTN *DescriptorBuffer,
+ IN UINT8 *StartAddress,
+ IN UINTN ByteCount,
+ OUT UINTN *RemainingByteCount );
+
+EFI_STATUS InitBusMasterRegisters (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT UINTN DescriptorBuffer,
+ IN BOOLEAN ReadWrite );
+
+EFI_STATUS StartStopBusMastering (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN BOOLEAN StartStop );
+
+EFI_STATUS WaitforDMAtoCompletion (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINTN TimeDelay );
+
+BOOLEAN DMACapable (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS HandleATABMErrors (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS MaskandSaveInterrupt (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS RestoreInterrupt (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+void PrintIdeDeviceInfo (
+ IDE_BUS_PROTOCOL *IdeBusInterface );
+
+//---------------------------------------------------------------------------
+// IDE POWER MANAGEMENT SUPPORT START
+//---------------------------------------------------------------------------
+
+
+EFI_STATUS InitIDEPowerManagement (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+UINT8 ConvertStanbyTimeoutValue (
+ IN UINT8 StandbyTimeout );
+
+EFI_STATUS InstallIDEPowerMgmtInterface (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS StopIDEPowerMgmtInterface (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+
+// IDE POWER MANAGEMENT INTERFACE SUPPORT START
+//---------------------------------------------------------------------------
+
+EFI_STATUS CheckPowerMode (
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN OUT UINT8 *PowerMode );
+
+EFI_STATUS IdleMode (
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN UINT8 StandbyTimeout );
+
+EFI_STATUS StandbyMode (
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN UINT8 StandbyTimeout );
+
+EFI_STATUS AdvancePowerMgmtMode (
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN UINT8 AdvPowerMgmtLevel );
+
+// IDE POWER MANAGEMENT INTERFACE SUPPORT END
+//---------------------------------------------------------------------------
+// IDE POWER MANAGEMENT SUPPORT END
+//---------------------------------------------------------------------------
+
+// HOST PROTECTED AREA SUPPORT START
+//---------------------------------------------------------------------------
+
+
+EFI_STATUS InstallHPAInterface (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS StopHPAInterface (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS GetNativeMaxAddress (
+ IN IDE_HPA_INTERFACE *This,
+ OUT UINT64 *LBA );
+
+EFI_STATUS SetMaxAddress (
+ IN IDE_HPA_INTERFACE *This,
+ OUT UINT64 LBA,
+ IN BOOLEAN Volatile );
+
+EFI_STATUS HPADisabledLastLBA (
+ IN IDE_HPA_INTERFACE *This,
+ OUT UINT64 *LBA
+);
+
+EFI_STATUS SetMaxPassword (
+ IN IDE_HPA_INTERFACE *This,
+ IN UINT8 *PasswordBuffer );
+
+EFI_STATUS SetMaxLock (
+ IN IDE_HPA_INTERFACE *This );
+
+EFI_STATUS SetMaxUnLock (
+ IN IDE_HPA_INTERFACE *This,
+ IN UINT8 *PasswordBuffer );
+
+EFI_STATUS SetMaxFreezeLock (
+ IN IDE_HPA_INTERFACE *This );
+
+EFI_STATUS IssueSetMaxPasswordCmd (
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 *PasswordBuffer,
+ UINT8 Cmd );
+
+// HOST PROTECTED AREA SUPPORT END
+//---------------------------------------------------------------------------
+
+// IDE HP SUPPORT START
+//---------------------------------------------------------------------------
+
+VOID IdeHPTimer (
+ IN EFI_EVENT Event,
+ IN VOID *Context );
+
+EFI_STATUS CheckHPControllerPresence (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+EFI_STATUS FlagDeviceRemoval (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+// IDE HP SUPPORT END
+//---------------------------------------------------------------------------
+EFI_STATUS IssueFreezeLockCommand (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+EFI_STATUS ReturnSecurityStatusWrapper (
+ IN IDE_SECURITY_PROTOCOL *This,
+ UINT16 *SecurityStatus );
+
+EFI_STATUS InstallIdeFeatures (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+VOID UnInstallIdeFeatures (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface );
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/IdeBus.mak b/Core/EM/IdeBus/IdeBus.mak
new file mode 100644
index 0000000..e904cc9
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBus.mak
@@ -0,0 +1,114 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/IdeBus/IdeBus.mak 8 8/25/10 5:35a Rameshr $
+#
+# $Revision: 8 $
+#
+# $Date: 8/25/10 5:35a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/IdeBus/IdeBus.mak $
+#
+# 8 8/25/10 5:35a Rameshr
+# New Feature: EIP 37748
+# Description: Move all the IDEBus Source driver SDL token into IdeBus
+# Bin Driver.
+# FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+# IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+# IdeHpa.c, IdePowerManagement.c
+#
+# 7 7/01/09 12:25p Rameshr
+# Coding Standard and File header updated.
+#
+# 6 3/04/08 7:50p Felixp
+#
+# 4 28/02/08 7:10p Anandakrishnanl
+# Moved the files from IdeBus to the Security module.
+#
+# 3 10/24/07 2:53p Felixp
+#
+# 2 10/23/07 4:18p Felixp
+# IDE Security support moved from Sources to Binary
+# IDE Security Setup screen added
+#
+# 1 12/01/05 9:38a Felixp
+#
+# 2 2/11/05 5:49p Felixp
+# Binary files organization improved:
+# - extra layer of sub-component removed
+# - macros initialization moved to SDL tokens to eliminate undefined
+# macros situation
+# - debug and release binaries have different names now (workaround for
+# VeB limitation)
+# - binaries reside in the component home directory (eliminates
+# hardcoded paths)
+#
+# 1 1/28/05 12:45p Felixp
+#
+# 4 1/18/05 3:22p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 3 12/24/04 3:25p Felixp
+#
+# 2 12/24/04 3:24p Felixp
+#
+# 1 12/10/04 1:01p Srinin
+# Initial Checkin of IdeBus Driver.
+#
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IDEBUS_mak
+#
+# Description:IdeBus BIN make file.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\IdeBusBin.lib
+
+$(BUILD_DIR)\IdeBusBin.lib : IdeBusBin
+
+IdeBusBin : $(BUILD_DIR)\IdeBus.mak IdeBusBinBin
+
+$(BUILD_DIR)\IdeBus.mak : $(IDEBUS_DIR)\IdeBus.cif Board\EM\IdeBusBoard\IdeBusBoard.cif $(IDEBUS_DIR)\IdeBus.mak $(BUILD_RULES)
+ $(CIF2MAK) $(IDEBUS_DIR)\IdeBus.cif $(CIF2MAK_DEFAULTS) Board\EM\IdeBusBoard\IdeBusBoard.cif
+
+IDEBUS_BOARD_OBJECTS = $(BUILD_DIR)\Board\EM\IdeBusBoard\IdeBusBoard.obj
+
+IdeBusBinBin : $(IdeBusSrc_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\IdeBus.mak all\
+ MAKEFILE=$(IDEBUS_DIR)\IdeBus.mak \
+ OBJECTS="$(IDEBUS_BOARD_OBJECTS)" \
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\IdeBusBin.lib LIBRARIES=\
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
diff --git a/Core/EM/IdeBus/IdeBus.sdl b/Core/EM/IdeBus/IdeBus.sdl
new file mode 100644
index 0000000..2faa756
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBus.sdl
@@ -0,0 +1,195 @@
+TOKEN
+ Name = "IdeBus_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Legacy8259 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "MASTER_SLAVE_ENUMERATION"
+ Value = "1"
+ Help = "When off, Slave device is detected first and \then Master is detected."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IDEBUSMASTER_SUPPORT"
+ Value = "1"
+ Help = "Master Switch to enable ATA and ATAPI \Busmaster support.\For ATAPI devices, ATAPI_BUSMASTER_SUPPORT \also needs to be enabled.\MWDMA and UDMA programming in devices \and the controller will be done irrespective of \this switch."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ATAPI_BUSMASTER_SUPPORT"
+ Value = "1"
+ Help = "Enable/Disable ATAPI Busmaster Support.\If Enabled, Busmastering will be used for ATAPI \devices else PIO transfer. "
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "IDEBUSMASTER_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "ACOUSTIC_MANAGEMENT_SUPPORT"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IDE_POWER_MANAGEMENT_SUPPORT"
+ Value = "0"
+ Help = "Enables IDE Power Management support."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "STANDBY_TIMEOUT"
+ Value = "5"
+ Help = "Standby Timeout value in MINUTES.\A value of ZERO, disables Standby Timer"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - 480"
+ Token = "IDE_POWER_MANAGEMENT_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "ADVANCED_POWER_MANAGEMENT_SUPPORT"
+ Value = "0"
+ Help = "Enables Advanced Power Managment Support."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "IDE_POWER_MANAGEMENT_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "ADVANCED_POWER_MANAGEMENT_LEVEL"
+ Value = "1"
+ Help = "Disable : 0\Minimum Power Consumption : 1\Intermediate level with Standy : 2 - 7Fh\Minimum Power Consumption with out Standby : 80h\Intermediate level without Standy : 81 - FDh\Maximum Performance : 0FEh"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 - 0FEh"
+End
+
+TOKEN
+ Name = "POWERUP_IN_STANDBY_SUPPORT"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "IDE_POWER_MANAGEMENT_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "POWERUP_IN_STANDBY_MODE"
+ Value = "0"
+ Help = "ON : Device Spins up when powered on.\0FF: Device will not spinup when powered on"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IDE_POWER_MANAGEMENT_INTERFACE_SUPPORT"
+ Value = "0"
+ Help = "Installs IDE power Management Interface"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "IDE_POWER_MANAGEMENT_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "HOST_PROTECTED_AREA_SUPPORT"
+ Value = "0"
+ Help = "Enables HOST Protected Area Interface."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IDE_HP_SUPPORT"
+ Value = "0"
+ Help = "Enables IDE Hot Plug Support."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EFI_IDE_PROTOCOL"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INTEL_IDE_PROTOCOL"
+ Value = "$(EFI_IDE_PROTOCOL)"
+ Help = "For backward compatibility, will keep this token value same as EFI_IDE_PROTOCOL."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "AHCI_COMPATIBLE_MODE"
+ Value = "0"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "IDEBUS_DIR"
+End
+
+MODULE
+ Help = "Includes IdeBus.mak to Project"
+ File = "IdeBus.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IDEBusSrc.ffs"
+ Parent = "FV_MAIN"
+ Disable = Yes
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IdeBusEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(IDEBUS_DIR)\IdeBusSrc$(ARCH).lib"
+ Parent = "IdeBusSrc_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IdeBusSrc_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "IdeBusBoardEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IdeBusBin.lib"
+ Parent = "IdeBus_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IdeBus_LIB"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/IdeBus/IdeBusMaster.c b/Core/EM/IdeBus/IdeBusMaster.c
new file mode 100644
index 0000000..da234af
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBusMaster.c
@@ -0,0 +1,836 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBusMaster.c 11 9/27/11 3:16a Rajeshms $
+//
+// $Revision: 11 $
+//
+// $Date: 9/27/11 3:16a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBusMaster.c $
+//
+// 11 9/27/11 3:16a Rajeshms
+// [TAG] EIP69295
+// [Category] Improvement
+// [Description] The Timeout values used by IDE and AHCI drivers are
+// made as SDL tokens, so that the timeout values can be varied.
+// [Files] IdeBusBoard.c, CORE_DXE.sdl, AhciSmm.h, AhciBus.h, IDESMM.h,
+// Ata.c, Atapi.c, IdeBus.c, IdeBus.h, IdeBusMaster.c, IdeBusBoard.h
+//
+// 10 12/23/10 3:56a Lavanyap
+// [TAG] - EIP41445
+// [Category] - NEW FEATURE
+// [Description] - Created SataPioDataOut and AtaPioDataOut protocol
+// function that can accept additional input parameters.
+// [Files] - AhciBus.h, AhciBus.c, AhciController.c, Ata.c, IdeBus.c,
+// IdeBus.h, IdeBusMaster.c,PAhciBus.h, PIdeBus.h
+//
+// 9 10/11/10 11:30a Krishnakumarg
+// [TAG] - EIP 43249
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Non-Ascii character in comments causing build problem in
+// japanese XP
+// [RootCause]- Presence of Non-Ascii character
+// [Solution] - Remove Non-Ascii character present in the file
+// [Files] - IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 8 8/25/10 4:13a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+// IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+// IdeHpa.c, IdePowerManagement.c
+//
+// 7 4/16/10 4:05p Pats
+// EIP 30719: Support for the HDD with sector size more than 512bytes.
+//
+// 6 7/01/09 12:23p Rameshr
+// Coding Standard and File header updated.
+//
+// 5 1/08/09 4:55p Rameshraju
+// Symptom: When we have HDD and CD-ROM connected, system hangs while
+// booting through Cd-ROM
+// RootCause: Interrupt is not cleared properly on Bus master Atapi
+// read/write, that cause further interrupts not to be generated.
+// Solution: Clear the Bus master interrupt status if set
+//
+// 4 9/30/08 4:43p Felixp
+// Bug fix(EIP 15310):Invalid error code (EFI_DEVICE_ERROR instead of
+// EFI_NO_MEDIA) was returned for removable devices with no media
+//
+// 2 13/04/07 3:02p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 8 11/03/05 10:53a Srinin
+// VC7 compilation error fixed. 64KB buffer alignment removed for
+// Busmaster.
+// It should be Dword aligned.
+//
+// 7 9/27/05 4:38p Olegi
+// Change in AtaReadWriteBusMaster routine - clear interrupt status after
+// every read/write.
+//
+// 6 3/04/05 11:34a Mandal
+//
+// 5 2/11/05 6:17p Felixp
+// Bug fix: data corruption during DMA write operation
+//
+// 4 2/10/05 6:15p Felixp
+// Bug fix (in case of transfer of 64K*N bytes, the last 64K block was
+// lost)
+//
+// 3 1/28/05 12:10p Srinin
+// Before Setting up Busmater registers select the device.
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/05/05 11:21a Srinin
+// IDE BusMaster Support added.
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IDEBusMaster.c
+//
+// Description: BusMaster Services
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IdeBus.h"
+#include <Protocol\IdeBusBoard.h>
+
+extern PLATFORM_IDE_PROTOCOL *gPlatformIdeProtocol;
+extern VOID *gDescriptorBuffer;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtaReadWriteBusMaster
+//
+// Description: Issues Read/Write Command and Read/Write the data from/to the ATA device
+// using BusMaster
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINT32 ByteCount,
+// UINT64 LBA
+//
+// Output:
+// *Buffer
+//
+// Modified:
+//
+// Referrals: AtaBlkWrite, AtaBlkRead
+//
+// Notes:
+// 1. Create Descriptor Table
+// 2. Issue ATA Read/Write command. Enable BusMastering
+// 3. Wait for Data Transfer
+// 4. Check for errors
+// 5. If success, check if any more data need to transferred, if yes, goto step 1
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaReadWriteBusMaster(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE )
+{
+ EFI_STATUS Status;
+ EFI_STATUS DMAStatus;
+ UINTN RemaingByteCount;
+ UINTN Total_Number_Of_Sectors;
+ UINTN MaxSectorCount;
+ UINTN CurrentSectorCount;
+ UINTN CurrentByteCount;
+ UINT8 *TempBuffer;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINTN DMATimeout;
+ UINTN DescriptorBuffer;
+ UINT8 Data8;
+ UINT32 SectorSize = ATA_SECTOR_BYTES;
+ BOOLEAN SectorGTBytes = FALSE;
+ //
+ //Select the drive
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.CommandBlock.DeviceReg, IdeBusInterface->IdeDevice.Device << 4 );
+
+ if ( Check48BitCommand( ReadWriteCommand )) {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO_48BIT;
+ }
+ else {
+ MaxSectorCount = MAX_SECTOR_COUNT_PIO;
+ }
+
+ //
+ // Calculate Sector Size
+ //
+ if((IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT14) && // WORD 106 valid? - BIT 14 - 1
+ (!(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT15)) && // WORD 106 valid? - BIT 15 - 0
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[2] & BIT12)) { // WORD 106 bit 12 - Sectorsize > 256 words
+ // The sector size is in words 117-118.
+ SectorSize = (UINT32)(IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[13] + \
+ (IdeBusInterface->IdeDevice.IdentifyData.Reserved_104_126[14] << 16)) * 2;
+ }
+
+ Total_Number_Of_Sectors = ByteCount / SectorSize; //512
+
+ // If the caller is requesting less bytes than one sector, we need to
+ // allocate space for one sector.
+ if ((ByteCount < SectorSize) && (ByteCount > 0)) {
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ SectorSize,
+ (VOID**)&TempBuffer );
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ SectorGTBytes = TRUE;
+ Total_Number_Of_Sectors = 1;
+ } else {
+ TempBuffer = Buffer;
+ }
+
+ do
+ {
+ if ( Total_Number_Of_Sectors > MaxSectorCount ) {
+ CurrentSectorCount = 0;
+ }
+ else {
+ CurrentSectorCount = Total_Number_Of_Sectors;
+ }
+ CurrentByteCount = (CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount) * SectorSize;
+
+ DescriptorBuffer = (UINTN) gDescriptorBuffer;
+ Status = CreateDescriptorTable( &DescriptorBuffer, TempBuffer, CurrentByteCount, &RemaingByteCount );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Status = InitBusMasterRegisters( IdeBusInterface, DescriptorBuffer, READWRITE );
+
+ MaskandSaveInterrupt( IdeBusInterface );
+ //
+ //Enable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 0 );
+
+ StartStopBusMastering( IdeBusInterface, TRUE );
+
+ Status = IssueAtaReadWriteCommand( IdeBusInterface, LBA, (UINT32)CurrentSectorCount, ReadWriteCommand, NULL );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //Timeout = 5000msec + Number of Sectors * 2
+ DMATimeout = ((CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount) << 1) + gPlatformIdeProtocol->DmaAtaCompleteCommandTimeout;
+
+ DMAStatus = WaitforDMAtoCompletion( IdeBusInterface, DMATimeout );
+
+ Status = HandleATABMErrors( IdeBusInterface );
+
+ StartStopBusMastering( IdeBusInterface, FALSE );
+ //
+ //Disable Interrupt
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+ //
+ //Clear interrupt status
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister,
+ &Data8 );
+
+ if ( Data8 & 4 ) {
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister,
+ Data8 );
+ }
+
+ RestoreInterrupt( IdeBusInterface );
+
+ //
+ //Check the status from WaitforDMAtoCompletion. More Descriptors are never formed. So EFI_SUCCESS_ACTIVE_SET is an error.
+ //
+ if ( EFI_ERROR( DMAStatus )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TempBuffer += CurrentByteCount;
+ Total_Number_Of_Sectors -= (CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount);
+ LBA += (CurrentSectorCount == 0 ? MaxSectorCount : CurrentSectorCount);
+ } while ( Total_Number_Of_Sectors );
+
+ if (SectorGTBytes) {
+ pBS->CopyMem( Buffer, TempBuffer, ByteCount);
+ pBS->FreePool( TempBuffer );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AtapiReadWriteBusMaster
+//
+// Description: Read/Write data from/to the ATAPI device
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// VOID *Buffer,
+// UINTN ByteCount,
+// UINT64 LBA,
+// UINT8 ReadWriteCommand,
+// BOOLEAN READWRITE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AtapiBlkRead, AtapiBlkWrite
+//
+// Notes:
+// 1. Prepare ATAPI Command Packet
+// 2. Check for errors. If Media_Change, detect the new atapi media if present and return status accordingly.
+// 3. Read/write data if the command packet is issues successfully.
+// 4. Repeat from step 1 untill all data has been read/written.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AtapiReadWriteBusMaster(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT VOID *Buffer,
+ IN UINTN ByteCount,
+ IN UINT64 LBA,
+ IN UINT8 ReadWriteCommand,
+ IN BOOLEAN READWRITE )
+{
+ EFI_STATUS Status;
+ EFI_STATUS DMAStatus;
+ INTN TotalNumberofBlocks;
+ INTN TransferLength;
+ UINTN BytesRemainingTobeRead;
+ UINTN RemaingByteCount;
+ ATAPI_DEVICE *AtapiDevice = IdeBusInterface->IdeDevice.AtapiDevice;
+ VOID *TempBuffer = Buffer;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+ UINTN DescriptorBuffer = (UINTN)gDescriptorBuffer;
+
+ //
+ //Check for CHK bit in status register before proceeding, if set give ATAPI reset
+ //
+ Status = CheckCHKonEntry( IdeBusInterface );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ TotalNumberofBlocks = ByteCount / AtapiDevice->BlockSize;
+
+ for (; TotalNumberofBlocks > 0; TotalNumberofBlocks -= TransferLength )
+ {
+ //
+ //Clear the buffer
+ //
+ ZeroMemory( AtapiDevice->PacketBuffer, AtapiDevice->PacketSize );
+
+ //
+ //Calculate # of blocks to be transferred
+ //
+ if ( TotalNumberofBlocks > 0xffff ) {
+ TransferLength = 0xffff;
+ }
+ else {
+ TransferLength = TotalNumberofBlocks;
+ }
+
+ //Update the buffer
+ AtapiDevice->PacketBuffer[0] = ReadWriteCommand;
+ AtapiDevice->PacketBuffer[1] = AtapiDevice->Lun << 5;
+ AtapiDevice->PacketBuffer[2] = ((UINT32) LBA) >> 24;
+ AtapiDevice->PacketBuffer[3] = ((UINT32) LBA) >> 16;
+ AtapiDevice->PacketBuffer[4] = ((UINT16) LBA) >> 8;
+ AtapiDevice->PacketBuffer[5] = ((UINT8) LBA) & 0xff;
+
+ AtapiDevice->PacketBuffer[7] = (UINT8) ( TransferLength >> 8 ); // MSB
+ AtapiDevice->PacketBuffer[8] = (UINT8) ( TransferLength & 0xff ); // LSB
+
+ BytesRemainingTobeRead = TransferLength * AtapiDevice->BlockSize;
+
+ Status = CreateDescriptorTable( &DescriptorBuffer, TempBuffer, BytesRemainingTobeRead, &RemaingByteCount );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Status = InitBusMasterRegisters( IdeBusInterface, DescriptorBuffer, READWRITE );
+
+ MaskandSaveInterrupt( IdeBusInterface );
+
+ //Enable Interrupt
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 0 );
+
+ StartStopBusMastering( IdeBusInterface, TRUE );
+
+ Status = IssueAtapiPacketCommand( IdeBusInterface, (UINT16*) AtapiDevice->PacketBuffer, DMA, 0xffff );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ DMAStatus = WaitforDMAtoCompletion( IdeBusInterface, gPlatformIdeProtocol->DmaAtaPiCompleteCommandTimeout );
+
+ //Check for errors
+ Status = HandleAtapiError( IdeBusInterface );
+
+ StartStopBusMastering( IdeBusInterface, FALSE );
+
+ //Disable Interrupt
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.ControlBlock.DeviceControlReg, 2 );
+
+ //Clear interrupt status
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister,
+ &Data8 );
+
+ if ( Data8 & 4 ) {
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.BusMasterBlock.BMStatusRegister,
+ Data8 );
+ }
+
+ RestoreInterrupt( IdeBusInterface );
+
+ if ( Status != EFI_SUCCESS ) {
+ //Some error has occured
+ //Check if Device is getting ready. If yes, wait till it gets ready
+ if ( AtapiDevice->Atapi_Status == BECOMING_READY ) {
+ Status = TestUnitReady( IdeBusInterface );
+ }
+
+ if ( Status == EFI_MEDIA_CHANGED ) {
+ Status = DetectAtapiMedia( IdeBusInterface );
+
+ // This may happen during initial power-up also. If ReinstallProtocol needs to be done,
+ // then differentiate between power-up nad other cases.
+ if ( Status == EFI_SUCCESS ) {
+ return EFI_MEDIA_CHANGED; // Return Media Change
+ }
+ }
+ return Status;
+ }
+
+ //
+ //If WaitforDMAtoCompletion returns a error, read the status register again to make sure it is indeed a failure.
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMStatusRegister, &Data8 );
+
+ if ( Data8 & (BM_ERROR | BM_ACTIVE)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //Update pointer
+ (UINT8*) TempBuffer += BytesRemainingTobeRead;
+ LBA += TransferLength;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CreateDescriptorTable
+//
+// Description: Creates a IDE BUS master Descriptor Table
+//
+// Input:
+// IN OUT VOID **DescriptorBuffer // 128KB buffer
+// IN UINT32 StartAddress
+// IN UINT32 ByteCount
+// OUT UINTN *FinalByteCount
+//
+// Output:
+// DescriptorBuffer, EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Create a Physical Region Descriptor for IDE Bus Master.
+// 2. FinalByteCount will be the total # of Bytes that can be transferred
+// using this Descriptor. Most of the time FinalByteCount will be equal to ByteCount.
+/// If the Descriptor Buffer exceeds 64K, then partial transfer will take place.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CreateDescriptorTable(
+ IN OUT UINTN *DescriptorBuffer,
+ IN UINT8 *StartAddress,
+ IN UINTN ByteCount,
+ OUT UINTN *RemainingByteCount )
+{
+ UINT16 Index;
+ UINTN Address = (UINTN) &(*StartAddress);
+ BUS_MASTER_DESCRIPTOR_TABLE *DescriptorTable;
+
+ //64KB alignment
+ *DescriptorBuffer &= 0xffff0000;
+ *DescriptorBuffer += 0x10000;
+ DescriptorTable = (BUS_MASTER_DESCRIPTOR_TABLE*)(*DescriptorBuffer);
+
+
+ //Address should be DWORD aligned
+ if ( Address & 0x3 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Restore Address
+ Address = (UINTN) &(*StartAddress);
+
+ for ( Index = 0; Index < 0x10000 / 8; Index++ )
+ {
+ DescriptorTable[Index].BaseAddress = (UINT32) Address;
+ DescriptorTable[Index].Flag = 0;
+ //
+ // if Start address is not 64KB aligned, then bytecount cannot be 64KB (Data tranfer cannot cross 64KB boundry
+ //
+ if ( Address & 0xffff ) {
+ DescriptorTable[Index].ByteCount = 0x10000 - (UINT16)( Address & 0xffff );
+
+ if ( DescriptorTable[Index].ByteCount > ByteCount ) {
+ DescriptorTable[Index].ByteCount = (UINT16)ByteCount;
+ }
+ ByteCount -= DescriptorTable[Index].ByteCount;
+ Address += DescriptorTable[Index].ByteCount;
+
+ if ( ByteCount == 0 ) {
+ break;
+ }
+ }
+ else { // address is 64KB aligned
+ if ( ByteCount >= 0x10000 ) {
+ DescriptorTable[Index].ByteCount = 0;
+ ByteCount -= 0x10000;
+ Address += 0x10000;
+
+ if ( ByteCount == 0 ) {
+ break;
+ }
+ }
+ else {
+ DescriptorTable[Index].ByteCount = (UINT16) ByteCount;
+ ByteCount = 0;
+ break;
+ }
+ }
+ }
+
+ //
+ //Update EOT
+ //
+ DescriptorTable[Index].Flag = 0x8000;
+
+ *RemainingByteCount = ByteCount;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBusMasterRegisters
+//
+// Description: Initialize Bus Master registers
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN OUT VOID *DescriptorBuffer
+// IN BOOLEAN ReadWrite
+//
+// Output:
+// DescriptorBuffer, EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Create a Physical Region Descriptor for IDE Bus Master.
+// 2. FinalByteCount will be the total # of Bytes that can be transferred
+// using this Descriptor. Most of the time FinalByteCount will be equal to ByteCount.
+/// If the Descriptor Buffer exceeds 64K, then partial transfer will take place.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBusMasterRegisters(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN OUT UINTN DescriptorBuffer,
+ IN BOOLEAN ReadWrite )
+
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+
+ //
+ //Update Read/Write Control and clear Start/Stop bit
+ //
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMCommandRegister, (ReadWrite == FALSE ? 1 : 0) << 3 );
+
+ //
+ //Clear the status
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMStatusRegister, &Data8 );
+ Data8 |= BM_INTERRUPT | BM_ERROR;
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMStatusRegister, Data8 );
+
+ //
+ //Update Descriptor Table Pointer
+ //
+ IdeWriteDword( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMDescriptorTablePointerReg, (UINT32) DescriptorBuffer );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StartStopBusMastering
+//
+// Description: Start/Stop Bus mAstering
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN BOOLEAN StartStop // Start = TRUE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Don't destroy Read/Write Control bit
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StartStopBusMastering(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN BOOLEAN StartStop )
+{
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+ UINT8 Data8;
+
+ //
+ //Update Start/Stop bit in Command Register
+ //
+ IdeReadByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMCommandRegister, &Data8 );
+ Data8 &= 0xFE;
+ Data8 |= (StartStop == TRUE ? 1 : 0);
+ IdeWriteByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMCommandRegister, Data8 );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: WaitforDMAtoCompletion
+//
+// Description: Start/Stop Bus mAstering
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+// IN UINT32 TimeDelay (msec)
+//
+// Output:
+// EFI_STATUS Success : If DMA completes with or with out Error.
+// EFI_DEVICE_ERROR : If timed out.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// 1. Check for Interrupt bit set. If yes, command completed.
+// 2. Check for Active bit to go Zero. If yes, command completed.
+// 3. Waits for a max. of TimeDelay/10,000 sec for the command to get completed.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitforDMAtoCompletion(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface,
+ IN UINTN TimeDelay )
+{
+ UINT8 Data8;
+ UINT8 Index2;
+ UINT32 Index;
+ IO_REGS Regs = IdeBusInterface->IdeDevice.Regs;
+
+ for ( Index = 0; Index < TimeDelay; Index++ )
+ {
+ for ( Index2 = 0; Index2 < 10; Index2++ )
+ {
+ IdeReadByte( IdeBusInterface->PciIO, Regs.BusMasterBlock.BMStatusRegister, &Data8 );
+
+ if ((Data8 & (BM_INTERRUPT | BM_ACTIVE)) == 4 ) {
+ return EFI_SUCCESS;
+ }
+
+ if ((Data8 & (BM_INTERRUPT | BM_ACTIVE)) == 5 ) {
+ return EFI_SUCCESS_ACTIVE_SET;
+ }
+
+ if ((Data8 & BM_ERROR) == 2 ) {
+ return EFI_DEVICE_ERROR;
+ }
+ pBS->Stall( 100 ); // 100 usec
+ }
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: HandleATABMErrors
+//
+// Description: Check for any errors
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HandleATABMErrors(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+
+ Status = WaitForCmdCompletion( IdeBusInterface );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: MaskandSaveInterrupt
+//
+// Description: Mask IDE interrupt
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+//
+// Modified:
+//
+// Referrals: AtaReadWriteBusMaster
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MaskandSaveInterrupt(
+ IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RestoreInterrupt
+//
+// Description: Restore the Interrupt mask
+//
+// Input:
+// IN IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+//
+// Modified:
+//
+// Referrals: AtaReadWriteBusMaster
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RestoreInterrupt(
+ IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ return EFI_SUCCESS;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/IdeBusSrc.chm b/Core/EM/IdeBus/IdeBusSrc.chm
new file mode 100644
index 0000000..96bb270
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBusSrc.chm
Binary files differ
diff --git a/Core/EM/IdeBus/IdeBusSrc.cif b/Core/EM/IdeBus/IdeBusSrc.cif
new file mode 100644
index 0000000..052afc0
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBusSrc.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "IdeBus Sources"
+ category = ModulePart
+ LocalRoot = "Core\em\IdeBus\"
+ RefName = "IdeBusSrc"
+[files]
+"IdeBusSrc.sdl"
+"IdeBusSrc.mak"
+"IdeBus.h"
+"IdeBus.c"
+"Ata.c"
+"Atapi.c"
+"IdeBusMaster.c"
+"IdePowerManagement.c"
+"IdeHPA.c"
+"IDEBusComponentName.c"
+"IdeBusSrc.chm"
+<endComponent>
diff --git a/Core/EM/IdeBus/IdeBusSrc.mak b/Core/EM/IdeBus/IdeBusSrc.mak
new file mode 100644
index 0000000..488f0ee
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBusSrc.mak
@@ -0,0 +1,98 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBusSrc.mak 5 8/25/10 4:11a Rameshr $
+#
+# $Revision: 5 $
+#
+# $Date: 8/25/10 4:11a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IdeBusSrc.mak $
+#
+# 5 8/25/10 4:11a Rameshr
+# New Feature: EIP 37748
+# Description: Move all the IDEBus Source driver SDL token into IdeBus
+# Bin Driver.
+# FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+# IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+# IdeHpa.c, IdePowerManagement.c
+#
+# 4 7/01/09 12:22p Rameshr
+# Coding Standard and File header updated.
+#
+# 3 12/02/05 11:21a Felixp
+#
+# 2 12/02/05 11:21a Felixp
+#
+# 1 12/01/05 9:43a Felixp
+#
+# 3 11/22/05 12:56p Felixp
+# dependency from token.h added
+#
+# 2 2/01/05 1:02p Srinin
+# Idebus.mak changed to Idebussrc.mak
+#
+# 1 1/28/05 12:45p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IdeBusSrc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : IDEBus
+
+
+IDEBus : $(BUILD_DIR)\IdeBusSrc.mak IDEBusSrcBin
+
+$(BUILD_DIR)\IdeBusSrc.mak : $(IDEBUS_DIR)\$(@B).cif $(IDEBUS_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(IDEBUS_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+$(IdeBusSrc_LIB) : IDEBus
+
+IDEBusSrcBin:
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\IDEBusSrc.mak all\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=LIBRARY LIBRARY_NAME=$(IdeBusSrc_LIB)
+
+# to build as a separete binary:
+# 1. Uncomment next block
+# 2. Disable IdeBusEntryPoint eLink
+# 3. Enable $(BUILD_DIR)\IDEBus.ffs eLink
+#IDEBusSrcBin: $(AMIDXELIB)
+# $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+# /f $(BUILD_DIR)\IdeBusSrc.mak all\
+# GUID=59B90A53-461B-4C50-A79F-A32773C319AE\
+# ENTRY_POINT=IdeBusEntryPoint \
+# TYPE=BS_DRIVER \
+# COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/IdeBus/IdeBusSrc.sdl b/Core/EM/IdeBus/IdeBusSrc.sdl
new file mode 100644
index 0000000..76cad32
--- /dev/null
+++ b/Core/EM/IdeBus/IdeBusSrc.sdl
@@ -0,0 +1,22 @@
+TOKEN
+ Name = "IdeBusSrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable IdeBusSrc support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+
+MODULE
+ Help = "Includes IdeBusSrc.mak to Project"
+ File = "IdeBusSrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IdeBusSrc.lib"
+ Parent = "$(IDEBUS_DIR)\IdeBusSrc$(ARCH).lib"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/IdeBus/IdeHPA.c b/Core/EM/IdeBus/IdeHPA.c
new file mode 100644
index 0000000..273cbd2
--- /dev/null
+++ b/Core/EM/IdeBus/IdeHPA.c
@@ -0,0 +1,792 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IdeHPA.c 6 10/11/10 11:31a Krishnakumarg $
+//
+// $Revision: 6 $
+//
+// $Date: 10/11/10 11:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IdeHPA.c $
+//
+// 6 10/11/10 11:31a Krishnakumarg
+// [TAG] - EIP 43249
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Non-Ascii character in comments causing build problem in
+// japanese XP
+// [RootCause]- Presence of Non-Ascii character
+// [Solution] - Remove Non-Ascii character present in the file
+// [Files] - IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 5 8/25/10 4:10a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+// IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+// IdeHpa.c, IdePowerManagement.c
+//
+// 4 7/01/09 12:24p Rameshr
+// Coding Standard and File header updated.
+//
+// 3 13/04/07 3:03p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 2 8/24/06 9:30a Felixp
+// x64 support (bug fixes)
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 4 3/04/05 11:35a Mandal
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/13/05 4:25p Srinin
+// Host Protection Area Support added.
+//
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IdeHPA.c
+//
+// Description: Host Protection Area Support
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IdeBus.h"
+
+extern EFI_GUID gHPAProtocolGuid;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallHPAInterface
+//
+// Description: Checks whether Host Protcted Area feature is supported or not.
+// If Supported, installs HPAProtocol.
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS : EFI_UNSUPPORTED/EFI_SUCCESS/EFI_OUT_OF_RESOURCES
+//
+// Modified:
+//
+// Referrals: IdeBusStart
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallHPAInterface(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+ HPA_INTERFACE *HPAInterface;
+
+ //
+ //Check if HPA is supported or not
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_82 & 0x400) == 0 ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Install the Interface
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(HPA_INTERFACE),
+ (VOID**)&HPAInterface );
+
+ if ( EFI_ERROR( Status )) {
+ pBS->FreePool( HPAInterface );
+ return Status;
+ }
+
+ HPAInterface->IdeBusInterface = IdeBusInterface;
+ IdeBusInterface->HPAInterface = HPAInterface;
+ HPAInterface->GetNativeMaxAddress = GetNativeMaxAddress;
+ HPAInterface->SetMaxAddress = SetMaxAddress;
+ HPAInterface->HPADisabledLastLBA = HPADisabledLastLBA;
+ HPAInterface->SetMaxPassword = SetMaxPassword;
+ HPAInterface->SetMaxLock = SetMaxLock;
+ HPAInterface->SetMaxUnLock = SetMaxUnLock;
+ HPAInterface->SetMaxFreezeLock = SetMaxFreezeLock;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &(IdeBusInterface->IdeDeviceHandle),
+ &gHPAProtocolGuid, HPAInterface,
+ NULL );
+
+ if ( EFI_ERROR( Status )) {
+ pBS->FreePool( HPAInterface );
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StopHPAInterface
+//
+// Description: Uninstall HPA Protocol
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeBusStop
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS StopHPAInterface(
+ IN IDE_BUS_PROTOCOL *IdeBusInterface )
+{
+ EFI_STATUS Status;
+
+ if ( IdeBusInterface->HPAInterface == NULL ) {
+ return EFI_SUCCESS;
+ }
+
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ IdeBusInterface->IdeDeviceHandle,
+ &gHPAProtocolGuid, IdeBusInterface->HPAInterface,
+ NULL );
+
+ if ( Status == EFI_SUCCESS ) {
+ pBS->FreePool( IdeBusInterface->HPAInterface );
+ IdeBusInterface->HPAInterface = NULL;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetNativeMaxAddress
+//
+// Description: Returns the Native Max LBA address supported by the device
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+// OUT UINT64 *LBA
+//
+// Output: LBA : Returns Native MAX LBA address.
+// EFI_STATUS : EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetNativeMaxAddress(
+ IN IDE_HPA_INTERFACE *This,
+ OUT UINT64 *LBA )
+{
+ EFI_STATUS Status;
+ BOOLEAN Ext48BitSupport = FALSE;
+ UINT8 ReadNativeMaxAddressCmd = READ_NATIVE_MAX_ADDRESS;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+ UINT32 dData;
+ UINT8 bData;
+
+ *LBA = 0;
+
+ //
+ //Check for 48 Bit Mode Support
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ ReadNativeMaxAddressCmd = READ_NATIVE_MAX_ADDRESS_EXT;
+ }
+
+ //
+ //Get Native Max Address.
+ //
+ Status = IdeNonDataCommand( IdeBusInterface,
+ 0, // Features
+ 0, // Sector Count
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ 0x40 | IdeBusInterface->IdeDevice.Device << 4, // Device
+ ReadNativeMaxAddressCmd ); // Command
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+
+ //
+ //Read Bits 47:24 if 48Bit LBA is supported
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ //
+ //Set HOB to 1 to read the upper DWROD
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.ControlBlock.DeviceControlReg,
+ HOB | nIEN );
+ dData = 0;
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAHighReg,
+ &bData );
+
+ dData = bData; // LBA 47:40
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAMidReg,
+ &bData );
+ dData <<= 8;
+ dData |= bData; // LBA 39:32
+
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBALowReg,
+ &bData );
+ dData <<= 8;
+ dData |= bData; // LBA 31:24
+
+ *LBA = dData;
+ //
+ //Shift Left *LBA by 24 Bits
+ //
+ *LBA = Shl64(*LBA, 24);
+ //
+ //Set HOB to 0 to read the Lower DWROD
+ //
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.ControlBlock.DeviceControlReg,
+ nIEN );
+ }
+
+ //
+ //Read 27:24 only when 48Bit LBA is not supported
+ //
+ if ((IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400) == 0 ) {
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.DeviceReg,
+ &bData );
+ bData &= 0xf;
+ dData = bData; // LBA 27:24
+ }
+
+ //
+ //Read 23:0 bits of LBA address
+ //
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAHighReg,
+ &bData );
+ dData <<= 8; // LBA 23:16
+ dData |= bData;
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAMidReg,
+ &bData );
+ dData <<= 8;
+ dData |= bData; // LBA 15:8
+ IdeReadByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBALowReg,
+ &bData );
+ dData <<= 8;
+ dData |= bData; // LBA 7:0
+
+ ((UINT32) *LBA) |= dData;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetMaxAddress
+//
+// Description: Set the Max LBA address
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+// OUT UINT64 LBA,
+// IN BOOLEAN Volatile
+//
+// Output:
+// EFI_STATUS :
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: if Volatile = TRUE, Values will not be preserved across resets.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetMaxAddress(
+ IN IDE_HPA_INTERFACE *This,
+ OUT UINT64 LBA,
+ IN BOOLEAN Volatile )
+{
+ EFI_STATUS Status;
+ UINT32 dData;
+ UINT32 Cmd;
+ UINT64 NativeMaxLBA;
+ UINT8 bData;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+ BOOLEAN Ext48BitSupport = FALSE;
+
+
+ //
+ //Issue Read MAX Native command before issuing a SET MAX Address command
+ //
+ Status = GetNativeMaxAddress( This, &NativeMaxLBA );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Check for 48 Bit Mode Support
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ Ext48BitSupport = TRUE;
+ }
+
+ //
+ //If 48Bit LBA is supported write LBA bits 47:24
+ //
+ if ( Ext48BitSupport ) {
+ // Enable HOB
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.ControlBlock.DeviceControlReg,
+ HOB | nIEN );
+ //get Bits 47:24 from LBA to dData
+ dData = (UINT32)Shr64(LBA, 24);
+
+ //dDATA has LBA bits 47:24
+ bData = dData >> 16; // LBA 47:40
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAHighReg,
+ bData );
+
+ bData = dData >> 8; // LBA 39:32
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBAMidReg,
+ bData );
+
+ bData = dData; // LBA 31:24
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.LBALowReg,
+ bData );
+
+ //Reset HOB
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.ControlBlock.DeviceControlReg,
+ nIEN );
+ }
+
+ //
+ // Write Bits 23:0
+ //
+ dData = (UINT32) LBA;
+
+ //
+ // if 48Bit LBA is not supported, write bits 27:24 to Device register
+ //
+ if ( Ext48BitSupport == FALSE ) {
+ bData = dData >> 24;
+ }
+ else {
+ bData = 0;
+ }
+
+ bData &= 0xf;
+ bData |= 0x40 | IdeBusInterface->IdeDevice.Device << 4;
+ Cmd = Ext48BitSupport == FALSE ? SET_MAX_ADDRESS : SET_MAX_ADDRESS_EXT;
+
+ //
+ //Set Max Address.
+ //
+ Status = IdeNonDataCommand( IdeBusInterface,
+ 0, // Features
+ Volatile == TRUE ? 0 : 1, // Sector Count
+ (UINT8)dData, // LBA Low
+ (UINT8)( dData >> 8 ), // LBA Mid
+ (UINT8)( dData >> 16 ), // LBA High
+ bData, // Device
+ Cmd ); // Command
+
+ //
+ // Update Identify Data
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+
+ //
+ //Update the LAST LBA number
+ //
+ if ( Ext48BitSupport ) {
+ IdeBusInterface->IdeBlkIo->BlkIo.Media->LastBlock = IdeBusInterface->IdeDevice.IdentifyData.LBA_48 - 1;
+ }
+ else {
+ IdeBusInterface->IdeBlkIo->BlkIo.Media->LastBlock = IdeBusInterface->IdeDevice.IdentifyData.Addressable_Sector_60 - 1;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: HPADisabledLastLBA
+//
+// Description: Returns the valid last LBA # when HPA is disabled.
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+// OUT UINT64 *LBA
+//
+// Output:
+// EFI_STATUS : EFI_SUCCESS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: The LBA returned will be the maximum valid LBA number an OS can make use of.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS HPADisabledLastLBA(
+ IN IDE_HPA_INTERFACE *This,
+ OUT UINT64 *LBA )
+{
+ BOOLEAN Ext48BitSupport = FALSE;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+
+ //
+ //Check for 48 Bit Mode Support
+ //
+ if ( IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x400 ) {
+ Ext48BitSupport = TRUE;
+ }
+
+ //
+ //Update the LAST LBA number
+ //
+ if ( Ext48BitSupport ) {
+ *LBA = IdeBusInterface->IdeDevice.IdentifyData.LBA_48 - 1;
+ }
+ else {
+ *LBA = IdeBusInterface->IdeDevice.IdentifyData.Addressable_Sector_60 - 1;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetMaxPassword
+//
+// Description: Sets the Password
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+// IN UINT8 *PasswordBuffer, (32 Bytes of Password)
+//
+// Output:
+// EFI_STATUS : EFI_UNSUPPORTED/EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: READ NATIVE MAX ADDRESS should not have immediatley PRECEEDED this command.
+// To take care of this situation, a Dummy Identify Device Command will be given before
+// issuing a SET MAX PASSWORD command
+// Once the device is locked, it should be unlocked with the password before
+// issuing any SETMAXADDRESS.
+// After issuing this command device will be in UNLOCKED state.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetMaxPassword(
+ IN IDE_HPA_INTERFACE *This,
+ IN UINT8 *PasswordBuffer )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+
+ //
+ //Check for HPA feature set security extensions are implemented or not?
+ //
+ if ( !(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x100)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = IssueSetMaxPasswordCmd( IdeBusInterface, PasswordBuffer, SET_MAX_SET_PASSWORD );
+
+ //
+ //Update the Identify Device Data buffer
+ //
+ GetIdentifyData( IdeBusInterface, &(IdeBusInterface->IdeDevice));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetMaxLock
+//
+// Description: Locks the device from accepting commands except UNLOCK and FREEZELOCK
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+//
+// Output:
+// EFI_STATUS : EFI_UNSUPPORTED/EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: READ NATIVE MAX ADDRESS should not have immediatley PRECEED this command.
+// To take care of this situation, a Dummy Identify Device Command will be given before
+// issuing a SET MAX LOCK/UNLOCK command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetMaxLock(
+ IN IDE_HPA_INTERFACE *This )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+
+ //Check for HPA feature set security extensions are implemented or not? AND
+ //Check whether SET MAX PASSWORD command has been issued before or not?
+ if ((!(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x100))
+ || (!(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_86 & 0x100))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = IdeNonDataCommand(
+ IdeBusInterface,
+ SET_MAX_LOCK, // Features
+ 0, // Sector Count
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ SET_MAX_ADDRESS ); // Command
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetMaxUnLock
+//
+// Description: Unlocks the device and allows it to accept all SET MAX commands
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+// IN UINT8 *PasswordBuffer
+//
+// Output:
+// EFI_STATUS : EFI_UNSUPPORTED/EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: READ NATIVE MAX ADDRESS should not have immediatley PRECEED this command.
+// To take care of this situation, a Dummy Identify Device Command will be given before
+// issuing a SET MAX LOCK/UNLOCK command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetMaxUnLock(
+ IN IDE_HPA_INTERFACE *This,
+ IN UINT8 *PasswordBuffer )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+
+ //Check for HPA feature set security extensions are implemented or not? AND
+ //Check whether SET MAX PASSWORD command has been issued before or not?
+ if ((!(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x100))
+ || (!(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_86 & 0x100))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = IssueSetMaxPasswordCmd( IdeBusInterface, PasswordBuffer, SET_MAX_UNLOCK );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SetMaxFreezeLock
+//
+// Description: Locks all SET MAX ADDRESS/PASSWORD/LOCK/UNLOCK command untill
+// next power cycle. GetNativeMaxAddress is allowed.
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+//
+// Output:
+// EFI_STATUS : EFI_UNSUPPORTED/EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: READ NATIVE MAX ADDRESS should not have immediatley PRECEED this command.
+// To take care of this situation, a Dummy Identify Device Command will be given before
+// issuing a SET MAX FREEZELOCK command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SetMaxFreezeLock(
+ IN IDE_HPA_INTERFACE *This )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((HPA_INTERFACE*)This)->IdeBusInterface;
+
+ //Check for HPA feature set security extensions are implemented or not? AND
+ //Check whether SET MAX PASSWORD command has been issued before or not?
+ if ((!(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x100))
+ || (!(IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_86 & 0x100))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = IdeNonDataCommand(
+ IdeBusInterface,
+ SET_MAX_FREEZE_LOCK, // Features
+ 0, // Sector Count
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ SET_MAX_ADDRESS ); // Command
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssueSetMaxPasswordCmd
+//
+// Description: Sets the Password to Lock/Unlock use of SETMAXADDRESS command
+//
+// Input:
+// IN IDE_HPA_INTERFACE *This,
+// IN BOOLEAN LockUnLock (TRUE : LOCK, FALSE :UNLOCK
+//
+// Output:
+// EFI_STATUS : EFI_UNSUPPORTED/EFI_SUCCESS/EFI_DEVICE_ERROR
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: READ NATIVE MAX ADDRESS should not have immediatley PRECEED this command.
+// To take care of this situation, a Dummy Identify Device Command will be given before
+// issuing a SET MAX LOCK/UNLOCK command
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS IssueSetMaxPasswordCmd(
+ IDE_BUS_PROTOCOL *IdeBusInterface,
+ UINT8 *PasswordBuffer,
+ UINT8 Cmd )
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer;
+
+ //Issues Identify Device Command
+ //Allocate 512 Bytes
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ 512,
+ (VOID**)&Buffer );
+
+ if ( EFI_ERROR( Status )) {
+ pBS->FreePool( Buffer );
+ return Status;
+ }
+
+ Status = GetIdentifyData( IdeBusInterface, Buffer );
+
+ //
+ //Clear the Buffer
+ //
+ ZeroMemory( Buffer, 512 );
+
+ //
+ //Copy 32 bytes to Password starting from offset 2
+ //
+ pBS->CopyMem( &(Buffer[2]), PasswordBuffer, 32 );
+
+ // Issue SET MAX PASSWORD Command
+ // Update the Feature Register
+ IdeWriteByte( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.FeatureReg,
+ Cmd );
+ Status = AtaReadWritePio( IdeBusInterface, Buffer, 512, 0, SET_MAX_ADDRESS, TRUE );
+
+ pBS->FreePool( Buffer );
+ return Status;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/IdeBus/IdePowerManagement.c b/Core/EM/IdeBus/IdePowerManagement.c
new file mode 100644
index 0000000..4275d29
--- /dev/null
+++ b/Core/EM/IdeBus/IdePowerManagement.c
@@ -0,0 +1,546 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/IdeBus/IdePowerManagement.c 11 10/11/10 11:32a Krishnakumarg $
+//
+// $Revision: 11 $
+//
+// $Date: 10/11/10 11:32a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/IdeBus/IdePowerManagement.c $
+//
+// 11 10/11/10 11:32a Krishnakumarg
+// [TAG] - EIP 43249
+// [Category] - IMPROVEMENT
+// [Severity] - Minor
+// [Symptom] - Non-Ascii character in comments causing build problem in
+// japanese XP
+// [RootCause]- Presence of Non-Ascii character
+// [Solution] - Remove Non-Ascii character present in the file
+// [Files] - IdeSecurity.c,IDESMM.c, InstallIdeSmi, Ata.c, Atapi.c,
+// IDEBusComponentName.c, IdeBusMaster.c, IdeHPA.c, IdePowerManagement.c
+//
+// 10 8/25/10 4:10a Rameshr
+// New Feature: EIP 37748
+// Description: Move all the IDEBus Source driver SDL token into IdeBus
+// Bin Driver.
+// FilesModified: Ata.c, Atapi.c, idebus.c, IdeBus.h,
+// IdebuscomponentName.c, IdeBusmaster.c IdeBusSrc.mak IdebusSrc.sdl
+// IdeHpa.c, IdePowerManagement.c
+//
+// 9 8/31/09 10:40a Felixp
+// IDLE_CMD is used instead of STANDBY_CMD if standby time is zero to
+// avoid HDD spin up and down-EIP 22135
+//
+
+//
+// 6 7/01/09 12:23p Rameshr
+// Coding Standard and File header updated.
+//
+// 5 13/04/07 3:05p Anandakrishnanl
+// Ide Bus Module - Update source files to comply with AMI coding
+// standard"!!!
+//
+// 4 1/09/06 11:36a Felixp
+//
+// 2 12/14/05 3:10p Srinin
+//
+// 1 12/01/05 9:43a Felixp
+//
+// 4 3/04/05 11:35a Mandal
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 1/11/05 2:26p Srinin
+// IDE Power Management Support added.
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IDEPOWERMANAGEMENT.c
+//
+// Description: IDE Power Management Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "IdeBus.h"
+#include <Protocol\IdeBusBoard.h>
+
+//
+//External variables
+//
+extern PLATFORM_IDE_PROTOCOL *gPlatformIdeProtocol;
+extern EFI_GUID gPowerMgmtProtocolGuid;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitIDEPowerManagement
+//
+// Description: Initializes IDE power Management
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: ConfigureIdeDevice
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitIDEPowerManagement (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface
+ )
+{
+
+ UINT8 bData = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ //
+ //Check if POWER Managmentfeature is enabled
+ //
+ if (IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_85 & 0x8) {
+
+ //
+ //Enable/Disable STANDBY Timer
+ //
+ bData = ConvertStanbyTimeoutValue ((UINT8)gPlatformIdeProtocol->StandbyTimeout);
+ if ( (gPlatformIdeProtocol->StandbyTimeout) == 0 ) {
+ Status = IdeNonDataCommand (
+ IdeBusInterface,
+ 0, // Features
+ bData, // Sector Count
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ IDLE_CMD); // IDLE_CMD when StandbyTimeout = 0
+ } else {
+ Status = IdeNonDataCommand (
+ IdeBusInterface,
+ 0, // Features
+ bData, // Sector Count
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ STANDBY_CMD); // STANDBY_CMD when StandbyTimeout > 0
+ }
+ //
+ //Enable/Disable STANDBY Timer
+ //
+
+ }
+
+ //
+ //Check Advanced Power Management Mode
+ //
+ if ( gPlatformIdeProtocol->AdvPowerManagementSupport ) {
+ if (IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x8){
+ //
+ //Enable/Disable Advanced Power Management
+ //
+ bData = ( gPlatformIdeProtocol->AdvPowerManagementLevel ) == 0 ? DISABLE_ADV_POWER_MANAGEMENT : ADV_POWER_MANAGEMENT;
+ IdeSetFeatureCommand (IdeBusInterface, bData, gPlatformIdeProtocol->AdvPowerManagementLevel );
+ }
+ }
+
+
+ if ( gPlatformIdeProtocol->PowerupInStandbySupport ) {
+ //
+ //Check Power-up in Standby Mode Support
+ //
+ if (IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x20){
+ //
+ //Check if the desires state is already present or not
+ //
+ if (!((IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_86 & 0x20) == (gPlatformIdeProtocol->PowerupInStandbyMode))){
+ bData = ( gPlatformIdeProtocol->PowerupInStandbyMode ) == 0 ? DISABLE_POWERUP_IN_STANDBY : ENABLE_POWERUP_IN_STANDBY;
+ IdeSetFeatureCommand (IdeBusInterface, bData, 0);
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallIDEPowerMgmtInterface
+//
+// Description: Install IDE power Management Interface
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeBusStart
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallIDEPowerMgmtInterface (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface
+ )
+{
+
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ POWER_MGMT_INTERFACE *PowerMgmtInterface;
+
+
+ //
+ //Check if Power Management is Supported or not
+ //
+ if (IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Enabled_85 & 0x8){
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (POWER_MGMT_INTERFACE),
+ (VOID**)&PowerMgmtInterface);
+ if (EFI_ERROR(Status)) return Status;
+
+ PowerMgmtInterface->CheckPowerMode = CheckPowerMode;
+ PowerMgmtInterface->IdleMode = IdleMode;
+ PowerMgmtInterface->StandbyMode = StandbyMode;
+ PowerMgmtInterface->AdvancePowerMgmtMode = AdvancePowerMgmtMode;
+ PowerMgmtInterface->IdeBusInterface = IdeBusInterface;
+ IdeBusInterface->PowerMgmtInterface = PowerMgmtInterface;
+
+ //
+ //Install the protocol on the device
+ //
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &(IdeBusInterface->IdeDeviceHandle),
+ &gPowerMgmtProtocolGuid, IdeBusInterface->PowerMgmtInterface,
+ NULL);
+
+ if (EFI_ERROR(Status)) pBS->FreePool(PowerMgmtInterface);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StopIDEPowerMgmtInterface
+//
+// Description: Uninstall IDE power Management Interface
+//
+// Input:
+// IDE_BUS_PROTOCOL *IdeBusInterface;
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: IdeBusStop
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+StopIDEPowerMgmtInterface (
+ IN IDE_BUS_PROTOCOL *IdeBusInterface
+ )
+{
+
+ EFI_STATUS Status;
+ POWER_MGMT_INTERFACE *PowerMgmtInterface = IdeBusInterface->PowerMgmtInterface;
+
+ if (IdeBusInterface->PowerMgmtInterface == NULL) return EFI_SUCCESS;
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ IdeBusInterface->IdeDeviceHandle,
+ &gPowerMgmtProtocolGuid, IdeBusInterface->PowerMgmtInterface,
+ NULL);
+ if (Status == EFI_SUCCESS) {
+ pBS->FreePool(IdeBusInterface->PowerMgmtInterface);
+ IdeBusInterface->PowerMgmtInterface = NULL;
+ }
+
+ return Status;
+}
+ //IDE_POWER_MANAGEMENT_INTERFACE_SUPPORT ends
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------//
+// Procedure: ConvertStanbyTimeoutValue
+//
+// Description: Initializes IDE power Managment
+//
+// Input:
+// IN UINT8 StandbyTimeout (In Minutes)
+//
+// Output:
+// UINT8 StandbyTimeout (Converted Timeout period)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+ConvertStanbyTimeoutValue (
+ IN UINT8 StandbyTimeout
+ )
+{
+
+ if ( StandbyTimeout ) {
+ if ( StandbyTimeout < 30 ) {
+ if ( StandbyTimeout > 20 ) {
+ StandbyTimeout = 20;
+ }
+ return StandbyTimeout * 60 / 5;
+ }
+ if ( StandbyTimeout < 16 * 30 ) {
+ return StandbyTimeout / 30;
+ }
+ }
+ return 0; // Standby Timer Disabled
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckPowerMode
+//
+// Description: Returns the Current State of the device
+//
+// Input:
+//
+//
+// Output:
+// EFI_STATUS, Current state of the Device,
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: PowerMode : 00 Standby Mode, 80h : Idle Mode, FF : Active/Idle Mode
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckPowerMode (
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN OUT UINT8 *PowerMode
+ )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((POWER_MGMT_INTERFACE *)IdePowerMgmtInterface)->IdeBusInterface;
+
+ Status = IdeNonDataCommand (
+ IdeBusInterface,
+ 0, // Features
+ 0, // SectorCount
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ CHECK_POWER_MODE); // Command
+
+ if (Status == EFI_SUCCESS) {
+ IdeReadByte ( IdeBusInterface->PciIO,
+ IdeBusInterface->IdeDevice.Regs.CommandBlock.SectorCountReg,
+ PowerMode);
+ }
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IdleMode
+//
+// Description: Puts the device in Idle Mode
+//
+// Input: StandbyTimeout : Value in Minutes. (0 : Disabled)
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+IdleMode(
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN UINT8 StandbyTimeout
+ )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((POWER_MGMT_INTERFACE *)IdePowerMgmtInterface)->IdeBusInterface;
+ UINT8 bData;
+
+ bData = ConvertStanbyTimeoutValue (StandbyTimeout);
+ Status = IdeNonDataCommand (
+ IdeBusInterface,
+ 0, // Features
+ bData, // SectorCount
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ IDLE_CMD); // Command
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StandbyMode
+//
+// Description: Puts the device in StandbyMode
+//
+// Input: StandbyTimeout : Value in Minutes. (0 : Disabled)
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+StandbyMode(
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN UINT8 StandbyTimeout
+ )
+{
+ EFI_STATUS Status;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((POWER_MGMT_INTERFACE *)IdePowerMgmtInterface)->IdeBusInterface;
+ UINT8 bData;
+
+ bData = ConvertStanbyTimeoutValue (StandbyTimeout);
+ Status = IdeNonDataCommand (
+ IdeBusInterface,
+ 0, // Features
+ bData, // SectorCount
+ 0, // LBA Low
+ 0, // LBA Mid
+ 0, // LBA High
+ IdeBusInterface->IdeDevice.Device << 4, // Device
+ STANDBY_CMD); // Command
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AdvancePowerMgmtMode
+//
+// Description: Enables Adavance Power Management
+//
+// Input: AdvPowerMgmtLevel ( 0 : Disable, FEh : Max. Performance, 81h - FDh Intermediate performance without Standby
+// 80h : Min. Power Consumption without Standby, 02h - 7Fh Intermediate Performance with Standby
+// 01h : Min. Power Consumption with Standby)
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AdvancePowerMgmtMode(
+ IN IDE_POWER_MGMT_INTERFACE *IdePowerMgmtInterface,
+ IN UINT8 AdvPowerMgmtLevel
+ )
+{
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+ IDE_BUS_PROTOCOL *IdeBusInterface = ((POWER_MGMT_INTERFACE *)IdePowerMgmtInterface)->IdeBusInterface;
+ UINT8 bData;
+
+ if (IdeBusInterface->IdeDevice.IdentifyData.Command_Set_Supported_83 & 0x8){
+ //
+ //Enable/Disable Advanced Power Management
+ //
+ bData = AdvPowerMgmtLevel == 0 ? DISABLE_ADV_POWER_MANAGEMENT : ADV_POWER_MANAGEMENT;
+ Status = IdeSetFeatureCommand (IdeBusInterface, bData, AdvPowerMgmtLevel);
+ }
+
+ return Status;
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/Ap4x.c b/Core/EM/KbcEmul/Ap4x.c
new file mode 100644
index 0000000..8a483ad
--- /dev/null
+++ b/Core/EM/KbcEmul/Ap4x.c
@@ -0,0 +1,81 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.c 3 2/10/11 1:09a Rameshr $
+//
+// $Revision: 3 $
+//
+// $Date: 2/10/11 1:09a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.c $
+//
+// 3 2/10/11 1:09a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 2 6/30/09 11:32a Rameshr
+// Coding Standard and File header updated.
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: Ap4x.c
+//
+// Description: It has the Aptio4.x compatibility function
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+
+EFI_SMM_CPU_IO_INTERFACE* gCpuIo = 0;
+EFI_SMM_BASE_PROTOCOL* gSMM = 0;
+EFI_SMM_SYSTEM_TABLE* gSmst = 0;
+
+extern EFI_GUID gEfiSmmBaseProtocolGuid;
+
+initializeLib(IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+
+ EfiInitializeSmmDriverLib (ImageHandle, SystemTable);
+
+ gBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &gSMM);
+ gSMM->GetSmstLocation (gSMM, &gSmst);
+ gCpuIo = &gSmst->SmmIo;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/Ap4x.h b/Core/EM/KbcEmul/Ap4x.h
new file mode 100644
index 0000000..73caa7c
--- /dev/null
+++ b/Core/EM/KbcEmul/Ap4x.h
@@ -0,0 +1,130 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.h 7 1/06/12 3:50a Rameshr $
+//
+// $Revision: 7 $
+//
+// $Date: 1/06/12 3:50a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Ap4x.h $
+//
+// 7 1/06/12 3:50a Rameshr
+// [TAG] EIP78617
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] When KBCEmulation is enabled during OS runtime phase,
+// system reboots
+// [RootCause] if the SMI happens from AP, Kbcemulation driver unable to
+// handle it.
+// [Solution] Added logic in KbcCore.c to find the CPU that cause SMI
+// and access the corresponding AL register.
+// [Files] Ap4x.h, KbcCore.c
+//
+// 6 1/06/12 3:21a Rameshr
+// EIP78617 check-in removed.
+//
+// 4 4/11/11 2:56a Rameshr
+// [TAG]- EIP 57436
+// [Category]-IMPROVEMENT
+// [Description]- PI1.1 Support.
+// [Files]- Ap4x.h, KbcEmul.c
+//
+// 3 2/10/11 1:09a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+//
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 2 6/30/09 11:32a Rameshr
+// Coding Standard and File header updated.
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: Ap4x.h
+//
+// Description: It has the Aptio4.x compatibility include files and headers
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+#include <efi.h>
+#include <AmiDxeLib.h>
+
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmUsbDispatch.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\Emul6064MsInput.h>
+#include <Protocol\Emul6064KbdInput.h>
+#include <Protocol\Emul6064Trap.h>
+
+extern EFI_GUID gEfiSmmUsbDispatchProtocolGuid;
+
+#define EFI_DRIVER_ENTRY_POINT(x)
+
+
+#define EfiInitializeSmmDriverLib(ImageHandle, SystemTable) InitAmiLib(ImageHandle, SystemTable)
+#define EfiInitializeDriverLib(ImageHandle, SystemTable) InitAmiLib(ImageHandle,SystemTable)
+#define gBS pBS
+#define gRT pRS
+#define EfiDuplicateDevicePath DPCopy
+#define AppendDevicePath DPAdd
+#define dp_len(x) (x)
+#define GET_CPUSAVESTATE_REG(x, y) gSmst->CpuSaveState[x].Ia32SaveState.y
+
+extern EFI_SMM_BASE_PROTOCOL* gSMM;
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+#define VA_LIST va_list
+#define VA_START va_start
+#define VA_ARG va_arg
+#define VA_END va_end
+#define EfiDebugVPrint(EFI_D_ERROR, Message, ArgList) PrintDebugMessageVaList(-1, Message, ArgList)
+
+#define USBDEVPATH_END 0xFF, 0xFF
+
+#ifdef TRACE
+#undef TRACE
+#endif
+
+#ifdef EFI_DEBUG
+void PrintDebugMsg (char *, ...);
+#define TRACE PrintDebugMsg
+#else
+void PrintDebugMsg (char *, ...);
+#define TRACE 1?0:PrintDebugMsg
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/Kbc.h b/Core/EM/KbcEmul/Kbc.h
new file mode 100644
index 0000000..9ae5c9b
--- /dev/null
+++ b/Core/EM/KbcEmul/Kbc.h
@@ -0,0 +1,195 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbc.h 5 2/10/11 1:01a Rameshr $
+//
+// $Revision: 5 $
+//
+// $Date: 2/10/11 1:01a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbc.h $
+//
+// 5 2/10/11 1:01a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 4 12/23/09 1:30a Rameshr
+// Symptom: KbcEmulation can't install FreeBSD
+// Solution: Implemented command 0xAA (Controller self-test) and 0xAB
+// (Keyboard interface test)
+// EIP: 26451
+//
+// 3 6/30/09 11:29a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 12/27/07 4:54p Rameshraju
+// KBC reset command added
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+//
+// Name: Kbc.h
+//
+// Description: KBC Header file has the structure defination for Virtual and Legacy devices
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#ifndef __INC_KBC_H__
+#define __INC_KBC_H__
+
+#ifdef FRAMEWORK_AP4
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+
+typedef struct _KBC KBC;
+typedef struct _PS2SINK PS2SINK;
+
+typedef enum {
+ PS2DEV_KBD = 0x0,
+ PS2DEV_MOUSE = 0x1,
+} PS2DEV_TYPE;
+#define KBC_SENDQUEUE_SIZE 15
+
+struct _PS2SINK {
+ //
+ //notify about a command from application
+ //
+ void (*onCommand)(PS2SINK* dev, UINT8 cmd );
+
+ //
+ //notify that queue is empty; pull streaming data
+ //
+ void (*onQueueFree)(PS2SINK* dev);
+
+ KBC* kbc;
+ BOOLEAN present_;
+ BOOLEAN presence_detected_;
+};
+
+struct _KBC{
+ void (*kbc_write_command)(KBC* kbc, UINT8 cmd );
+ void (*kbc_write_data)(KBC* kbc, UINT8 data );
+ UINT8 (*kbc_read_status)(KBC* kbc );
+ UINT8 (*kbc_read_data)(KBC* kbc );
+
+ BOOLEAN (*send_outb1)( KBC* kbc, PS2DEV_TYPE devtype, BOOLEAN ovrd, UINT8 data );
+ UINT8 (*read_ccb)(KBC* kbc);
+ PS2SINK* mouse_dev;
+ PS2SINK* kbd_dev;
+ UINT8 send_queue[KBC_SENDQUEUE_SIZE];
+ UINT8 send_queue_aux[KBC_SENDQUEUE_SIZE];
+ UINT8* sqHead[2];
+ UINT8* sqTail[2];
+
+ int nSeq;
+ UINT8 aux_en; // aux interface enabled/disabled (value is a KBC command)
+ UINT8 kbd_en; // kbd interface enabled/disabled (value is a KBC command)
+};
+
+
+#define KBC_STATUS_REG 0x64
+#define KBC_COMMAND_REG 0x64
+#define KBC_DATA_REG 0x60
+#define KBCTIMEOUT 0x1000
+//
+// KBC Status bits definition
+//
+#define KBC_STATUS_OBF 0x1
+#define KBC_STATUS_IBF 0x2
+#define KBC_STATUS_SYS 0x4
+#define KBC_STATUS_A2 0x8
+#define KBC_STATUS_INH 0x10
+#define KBC_STATUS_AUXB 0x20
+#define KBC_STATUS_TO 0x40 //Timeout detected
+#define KBC_STATUS_PERR 0x80 //Parity error detected
+
+//
+// KBC CCB bits definition
+//
+#define KBC_CCB_INT 0x01
+#define KBC_CCB_INT2 0x02
+#define KBC_CCB_SYS 0x04
+#define KBC_CCB_EN 0x10
+#define KBC_CCB_EN2 0x20
+#define KBC_CCB_XLAT 0x40
+
+
+//
+//KBC output bits definition
+//
+#define CCB_KEYBOARD_DISABLED 0x10
+#define CCB_MOUSE_DISABLED 0x20
+#define CCB_TRANSLATE_SCAN_CODE_BIT_MASK 0x40
+
+
+//
+// KBC Commands
+//
+#define KBCCMD_WriteAuxBuffer 0xD3
+#define KBCCMD_WriteKbdBuffer 0xD2
+#define KBCCMD_WriteAuxDev 0xD4
+#define KBCCMD_READ_CCB 0x20
+#define KBCCMD_WRITE_CCB 0x60
+#define KBCCMD_LOCK USB_SEND_COMMAND_TO_KBC
+#define KBCCMD_AUXENBL 0xA8
+#define KBCCMD_AUXDSBL 0xA7
+#define KBCCMD_KBDENBL 0xAE
+#define KBCCMD_KBDDSBL 0xAD
+#define KBCCMD_CheckAux 0xA9
+#define KBCCMD_CheckKbd 0xAB
+#define KBCCMD_SelfTest 0xAA
+#define KBCCMD_ReadInPort 0xC0
+#define KBCCMD_ReadOutPortL 0xC1
+#define KBCCMD_ReadOutPortH 0xC2
+#define KBCCMD_ReadOutPort 0xD0
+#define KBCCMD_WriteOutPort 0xD1
+#define KBCCMD_ResetSystem 0xFE
+
+//
+// KBC Command Status Response
+//
+#define KBCCMD_RES_SelfTestOk 0x55
+#define KBCCMD_RES_KBInterfaceOk 0
+
+
+#endif // __INC_KBC_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**************************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/KbcDevEmul.h b/Core/EM/KbcEmul/KbcDevEmul.h
new file mode 100644
index 0000000..d420aad
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcDevEmul.h
@@ -0,0 +1,193 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcDevEmul.h 7 9/30/11 12:45a Rameshr $
+//
+// $Revision: 7 $
+//
+// $Date: 9/30/11 12:45a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcDevEmul.h $
+//
+// 7 9/30/11 12:45a Rameshr
+// [TAG] EIP71408
+// [Category] Improvement
+// [Description] Remove the customer name reference from the
+// KbcEmulation module.
+// [Files] KbcDevEmul.h,VirtualKbc.c
+//
+// 6 2/10/11 1:01a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 5 7/08/10 1:56a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 4 2/03/10 1:14a Rameshr
+// Install Netware6.5 SP8 Fail.
+// EIP 28411
+// Single byte and two Byte command is identified properly and handled.
+//
+// 3 6/30/09 11:30a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 10/30/08 10:49a Rameshraju
+// Keyboard & Mouse enable/disable command handled
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+//
+// Name: KbcDevEmul.h
+//
+// Description: Devices header file
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#ifndef __INC_VKBC_H__
+#define __INC_VKBC_H__
+
+#include "Kbc.h"
+
+#define KBD_MOUSE_INTR_DISABLE 0x75
+#define MOUSE_INTR_DISABLE 0x65
+#define MOUSE_INTR_ENABLE 0x47
+
+//
+//Virtual KBC
+//
+typedef struct _VIRTKBC VIRTKBC;
+
+struct _VIRTKBC{
+ KBC kbc;
+ UINT8 ccb_;
+ UINT8 kbc_command_;
+ UINT8 st_;
+ UINT8 outb_;
+ BOOLEAN TwoByteCmd;
+ BOOLEAN DelaySendingDataCmd;
+ BOOLEAN fCcb_loaded;
+};
+
+void InitVirtualKBC(VIRTKBC* vkbc, PS2SINK* kbd, PS2SINK* mouse );
+
+//
+//Legacy KBC. Keep both _VIRTKBC and _LEGACYKBC synced up till DelaySendingDataCmd
+//
+typedef struct _LEGACYKBC LEGACYKBC;
+
+struct _LEGACYKBC {
+ KBC kbc_;
+ UINT8 ccb_;
+ UINT8 kbc_command_;
+ UINT8 st_;
+ UINT8 outb_;
+ BOOLEAN TwoByteCmd;
+ BOOLEAN DelaySendingDataCmd;
+ BOOLEAN fCcb_loaded;
+};
+void InitLegacyKBC(LEGACYKBC* kbc, PS2SINK* kbd, PS2SINK* mouse );
+
+//
+//Virtual KBD & Legacy KBD
+//
+
+typedef struct _VIRTKBD VIRTKBD;
+typedef struct _VIRTKBD LEGACYKBD;
+
+#define KBDQUEUE_SIZE 10
+
+typedef struct _VIRTKBD{
+ PS2SINK sink;
+
+ EFI_EMUL6064KBDINPUT_PROTOCOL kbdInput_;
+
+ UINT8 queue[KBDQUEUE_SIZE];
+ UINT8* qhead;
+ UINT8* qtail;
+
+
+ UINT8* option_ptr;
+ UINT8 read_code_action;
+ UINT8 typematicRateDelay;
+ UINT8 scancodepage;
+ BOOLEAN Enabled;
+};
+
+void InitVirtualKbd(KBC* , VIRTKBD* );
+void InitLegacyKbd(KBC* , LEGACYKBD* );
+
+//
+//Virtual Mouse & Legacy Mouse
+//
+
+#define MOUSE_PACKET_SIZE 3
+
+typedef struct _VIRTMOUSE VIRTMOUSE;
+typedef struct _VIRTMOUSE LEGACYMOUSE;
+
+
+#define MOUSEQUEUE_SIZE 12
+
+typedef struct _VIRTMOUSE{
+ PS2SINK sink;
+
+ EFI_EMUL6064MSINPUT_PROTOCOL msInput_;
+
+ UINT8 queue[MOUSEQUEUE_SIZE];
+ UINT8* qhead;
+ UINT8* qtail;
+
+ UINT8* option_ptr;
+ UINT8 samplingRate_;
+ UINT8 resolution_;
+
+ int x, y;
+ int fFreshPacket;
+ BOOLEAN Enabled;
+ int streaming;
+ PS2MouseData dataPacket;
+};
+
+void InitVirtualMouse(KBC* kbc, VIRTMOUSE* mouse );
+void InitLegacyMouse(KBC* kbc, LEGACYMOUSE* mouse );
+
+
+#endif // __INC_VKBC_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/KbcEmul.c b/Core/EM/KbcEmul/KbcEmul.c
new file mode 100644
index 0000000..ddcd165
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmul.c
@@ -0,0 +1,481 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.c 14 12/04/14 12:49a Rajeshms $
+//
+// $Revision: 14 $
+//
+// $Date: 12/04/14 12:49a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.c $
+//
+// 14 12/04/14 12:49a Rajeshms
+// [TAG] EIP193601
+// [Category] New Feature
+// [Description] Aptio4.x - Security Enhancement for SMIHandler in
+// KbcEmulation module, Checks if BAR address access is inside SMRAM, if
+// yes, return.
+// [Files] KbcEmul.mak, KbcEmul.c, KbcOhci.c
+//
+// 13 9/16/13 6:50a Srikantakumarp
+// [TAG] EIP135441
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Option ROM was not getting dispatched in AMD Platforms
+// [RootCause] Setting the IRQ1 in the Entry Point of the KbcEmulation
+// Driver
+// [Solution] Setting the IRQ1 only if KbcEmulation is Enabled
+// [Files] KbcEmul.c
+//
+// 12 1/09/12 1:24a Rameshr
+// [TAG] EIP74128
+// [Category] Improvement
+// [Description] Disable the KbcEmulation Smi’s on ACPI enable and
+// Disable SMI call
+// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif,
+// KbcEmul.h, KbcEmul.sdl
+//
+// 11 5/02/11 12:16a Rameshr
+// [TAG] - EIP 58434
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - IRQ1 not enabled on LegacyFree(No KBC) system while booting
+// to Legacy OS.
+// [RootCause]- As there is no KBC, IRQ1 not used by system and it's not
+// enabled.
+// [Solution] - When the Emulation module enabled, IRQ1 is added to the
+// used IRQ list.So it's enabled while booting to Legacy OS.
+// [Files] - KbcEmul.c
+//
+// 10 4/11/11 2:46a Rameshr
+// [TAG]- EIP 57436
+// [Category]-IMPROVEMENT
+// [Description]- PI1.1 Support.
+// [Files]- Ap4x.h, KbcEmul.c
+//
+// 9 2/10/11 12:57a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 8 7/08/10 1:57a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 7 6/30/09 11:28a Rameshr
+// Coding Standard and File header updated.
+//
+// 6 2/05/09 9:37a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 5 10/24/08 11:55a Rameshraju
+// KBC presence done only based on 0xFF value.
+//
+// 3 8/11/08 12:33p Vasudevans
+//
+// 4 8/07/08 10:21a Rameshraju
+// Removed the IRQ1 changes
+//
+// 3 7/08/08 11:09a Rameshraju
+// IRQ1 unmasked.
+//
+// 2 12/27/07 4:53p Rameshraju
+// Detect the KBC presence by reading port 64
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: KbcEmul.c
+//
+// Description: KBC emulation driver entry point and initilize the SMI for port 6064
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "Kbc.h"
+#include "KbcDevEmul.h"
+#ifdef FRAMEWORK_AP4
+#include "token.h"
+#include "protocol/usbpolicy.h"
+#else
+#include "tokens.h"
+#endif
+
+#include <AmiBufferValidationLib.h>
+
+extern EFI_GUID gEfiLoadedImageProtocolGuid;
+extern EFI_GUID gEfiDevicePathProtocolGuid;
+extern EFI_GUID gEfiSetupGuid;
+
+
+EFI_CPU_IO_PROTOCOL *CpuIo;
+KBC* gVirtualKBC = NULL;
+void Emulation_Init();
+void Smm_Register();
+
+//
+//KBC Emulation TRAP protocol.
+//
+BOOLEAN Emulation6064TrapEnable(EFI_EMUL6064TRAP_PROTOCOL *This);
+BOOLEAN Emulation6064TrapDisable(EFI_EMUL6064TRAP_PROTOCOL *This);
+UINT32 KbcEmulationFeature (EFI_EMUL6064TRAP_PROTOCOL * This);
+BOOLEAN NonSmmEmulation6064TrapEnable(EFI_EMUL6064TRAP_PROTOCOL *This);
+BOOLEAN NonSmmEmulation6064TrapDisable(EFI_EMUL6064TRAP_PROTOCOL *This);
+
+EFI_EMUL6064TRAP_PROTOCOL Emulation6064Trap= {
+ Emulation6064TrapEnable,
+ Emulation6064TrapDisable,
+ KbcEmulationFeature
+};
+
+EFI_EMUL6064TRAP_PROTOCOL NonSmmEmulation6064Trap= {
+ NonSmmEmulation6064TrapEnable,
+ NonSmmEmulation6064TrapDisable,
+ KbcEmulationFeature
+};
+
+EFI_HANDLE EmulationTrapHandle=NULL;
+
+
+EFI_DRIVER_ENTRY_POINT(EmulationEntryPoint)
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EmulationEntryPoint
+//
+// Description: Entry point for Emulation driver. If the port 6064 emulation enabled by setup
+// it enables the SMI event for port 6064 and install the Trap handle protocol.
+//
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+//
+// Output: Status: EFI_SUCCESS = Success
+// EFI_ERROR = Failure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+EmulationEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status = 0;
+ UINTN VariableSize;
+ BOOLEAN InSmm = 0;
+ USB_SUPPORT_SETUP SetupData;
+
+ //
+ // Initialize the EFI Runtime Library
+ //
+ initializeLib(ImageHandle, SystemTable);
+
+
+ //
+ //Check the setup option, if the emulation disabled in setup return with EFI_SUCCESS
+ //
+ VariableSize = sizeof(USB_SUPPORT_SETUP);
+ Status = pRS->GetVariable( L"UsbSupport", &gEfiSetupGuid, NULL, &VariableSize, &SetupData );
+
+ if (EFI_ERROR(Status) || (SetupData.UsbEmul6064 == 0)) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Save the system table pointer
+ //
+ gSMM->GetSmstLocation (gSMM, &gSmst);
+
+ //
+ // Find out whether we're in SMM
+ //
+ gSMM->InSmm (gSMM, &InSmm);
+
+ if (!InSmm) {
+ EFI_HANDLE hSmmCode = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_DEVICE_PATH_PROTOCOL *ImageDevicePath;
+
+ //
+ // Load this driver's image to memory
+ //
+
+ Status = gBS->HandleProtocol(
+ ImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = gBS->HandleProtocol(
+ LoadedImage->DeviceHandle, &gEfiDevicePathProtocolGuid, (VOID*)&ImageDevicePath
+ );
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = gBS->LocateProtocol (&gEfiCpuIoProtocolGuid, NULL, &CpuIo);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ gBS->InstallProtocolInterface(&EmulationTrapHandle,
+ &gNonSmmEmul6064TrapProtocolGuid,EFI_NATIVE_INTERFACE,&NonSmmEmulation6064Trap);
+
+ FilePath = AppendDevicePath(
+ ImageDevicePath, LoadedImage->FilePath
+ );
+
+ //
+ // Load the image in memory to SMRAM; it will automatically generate SMI.
+ //
+ Status = gSMM->Register(gSMM, FilePath, NULL, 0, &hSmmCode, FALSE);
+ }else {
+ //
+ // We're now in SMM, registering all USB SMM callback functions
+ //
+#if OHCI_EMUL_SUPPORT
+ InitAmiBufferValidationLib(ImageHandle, SystemTable);
+#endif
+ Emulation_Init();
+
+ gBS->InstallProtocolInterface(&EmulationTrapHandle,
+ &gEmul6064TrapProtocolGuid,EFI_NATIVE_INTERFACE,&Emulation6064Trap);
+ RegisterAcpiEnableCallBack();
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Emulation_Init
+//
+// Description: Initilize the Keyboard Controller, Keyboard and Mouse device.Regsiter the SMI for port 6064
+// access.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Emulation_Init()
+{
+ static VIRTKBC VirtualKBC;
+ static VIRTMOUSE VirtualMouse;
+ static VIRTKBD VirtualKbd;
+ static LEGACYKBC LegacyKbc;
+ static LEGACYKBD LegacyKbd;
+ static LEGACYMOUSE LegacyMouse;
+ BOOLEAN KbcPresent=FALSE;
+ UINT8 port64 = IoRead8(0x64);
+
+
+ //
+ //Detect the KBC presence by reading port 64.
+ //
+ KbcPresent = ((port64==0xFF))? 0 : 1;
+
+ if(KbcPresent) {
+
+ gVirtualKBC = &LegacyKbc.kbc_;
+
+ //
+ //Initialize the Legacy Mouse Device
+ //
+ InitLegacyMouse(gVirtualKBC,&LegacyMouse);
+
+ //
+ //Initialize the Legacy Keyboard Device
+ //
+ InitLegacyKbd(gVirtualKBC,&LegacyKbd);
+
+ //
+ //Initialize the Legacy Keyboard Controller
+ //
+ InitLegacyKBC(&LegacyKbc,&LegacyKbd.sink,&LegacyMouse.sink);
+
+
+ } else {
+
+ gVirtualKBC = &VirtualKBC.kbc;
+
+ //
+ //Initialize the Virtual Mouse Device
+ //
+ InitVirtualMouse(gVirtualKBC,&VirtualMouse);
+
+ //
+ //Initialize the Virtual Keyboard Device
+ //
+ InitVirtualKbd(gVirtualKBC,&VirtualKbd);
+
+ //
+ //Initialize the Virtual Keyboard Controller
+ //
+ InitVirtualKBC(&VirtualKBC,&VirtualKbd.sink,&VirtualMouse.sink);
+
+ }
+
+ //
+ // Hardware specific SMM registration
+ Smm_Register();
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Emulation6064TrapEnable
+//
+// Description: Enable the SMI source for port 6064
+//
+// Input: None
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+Emulation6064TrapEnable (
+ EFI_EMUL6064TRAP_PROTOCOL * This
+ )
+{
+ return TrapEnable(TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Emulation6064TrapDisable
+//
+// Description: Disable the SMI source for port 6064
+//
+// Input: None
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+Emulation6064TrapDisable (
+ EFI_EMUL6064TRAP_PROTOCOL * This
+ )
+{
+ return TrapEnable(FALSE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmEmulation6064TrapEnable
+//
+// Description: Enable the SMI source for port 6064 in Non SMM
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+NonSmmEmulation6064TrapEnable (
+ EFI_EMUL6064TRAP_PROTOCOL * This
+ )
+{
+ UINT16 IrqMask;
+ EFI_STATUS Status;
+
+ //
+ // Reserve IRQ1 if the Emulation enabled
+ //
+ Status=AmiIsaIrqMask(&IrqMask, TRUE);
+
+ if(Status==EFI_NOT_FOUND){
+ IrqMask=ISA_IRQ_MASK;
+ IrqMask |= 2;
+ AmiIsaIrqMask(&IrqMask, FALSE);
+ } else {
+ IrqMask |= 2;
+ AmiIsaIrqMask(&IrqMask, FALSE);
+ }
+
+ return NonSmmTrapEnable(TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmEmulation6064TrapDisable
+//
+// Description: Disable the SMI source for port 6064 in Non SMM
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+NonSmmEmulation6064TrapDisable (
+ EFI_EMUL6064TRAP_PROTOCOL * This
+ )
+{
+ return NonSmmTrapEnable(FALSE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: KbcEmulationFeature
+//
+// Description: Returns all the feature supported by Emulation
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+KbcEmulationFeature (
+ EFI_EMUL6064TRAP_PROTOCOL * This
+ )
+{
+ UINT32 KbcEmulFeature=0;
+
+#if IRQ_EMUL_SUPPORT
+ KbcEmulFeature |= IRQ_SUPPORTED;
+#endif
+ return KbcEmulFeature;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcEmul.cif b/Core/EM/KbcEmul/KbcEmul.cif
new file mode 100644
index 0000000..11ac603
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmul.cif
@@ -0,0 +1,31 @@
+<component>
+ name = "KbcEmulation"
+ category = eModule
+ LocalRoot = "core\em\KbcEmul"
+ RefName = "KbcEmul"
+[files]
+"KbcEmul.sdl"
+"KbcEmul.mak"
+"KbcEmul.dxs"
+"KbcEmul.c"
+"KbcEmul.h"
+"KbcEmulLib.h"
+"KbcEmulLib.c"
+"KbcEmulAcpi.c"
+"Kbc.h"
+"KbcDevEmul.h"
+"Kbccore.c"
+"Legacykbc.c"
+"Legacykbd.c"
+"LegacyMouse.c"
+"VirtualKbc.c"
+"VirtualKbd.c"
+"VirtualMouse.c"
+"Ap4x.h"
+"Ap4x.c"
+"KbcEmulation.chm"
+[parts]
+"KbcUhci"
+"KbcEmulIrq"
+"KbcOhci"
+<endComponent>
diff --git a/Core/EM/KbcEmul/KbcEmul.dxs b/Core/EM/KbcEmul/KbcEmul.dxs
new file mode 100644
index 0000000..d73952f
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmul.dxs
@@ -0,0 +1,71 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.dxs 3 2/10/11 12:56a Rameshr $
+//
+// $Revision: 3 $
+//
+// $Date: 2/10/11 12:56a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.dxs $
+//
+// 3 2/10/11 12:56a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 2 6/30/09 11:27a Rameshr
+// Coding Standard and File header updated.
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: KbcEmul.dxs
+//
+// Description: DXS file for the Kbc Emulation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmUsbDispatch.h>
+#include <Protocol/PciRootBridgeIo.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID AND
+ EFI_SMM_USB_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcEmul.h b/Core/EM/KbcEmul/KbcEmul.h
new file mode 100644
index 0000000..59d6484
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmul.h
@@ -0,0 +1,129 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.h 6 1/09/12 1:25a Rameshr $
+//
+// $Revision: 6 $
+//
+// $Date: 1/09/12 1:25a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.h $
+//
+// 6 1/09/12 1:25a Rameshr
+// [TAG] EIP74128
+// [Category] Improvement
+// [Description] Disable the KbcEmulation Smi’s on ACPI enable and
+// Disable SMI call
+// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif,
+// KbcEmul.h, KbcEmul.sdl
+//
+// 5 2/10/11 12:58a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 4 7/08/10 1:57a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 3 6/30/09 11:28a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 2/05/09 9:38a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: KbcEmul.h
+//
+// Description: KBC emulation header file
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#ifdef FRAMEWORK_AP4
+#include "Ap4x.h"
+#include "token.h"
+#else
+#include "Ap3x.h"
+#include "tokens.h"
+#endif
+
+#include <protocol\devicepath.h>
+#include <Protocol\Cpuio.h>
+
+initializeLib(IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable);
+
+
+#define MAX_DEBUG_LEVEL 8
+
+#define DEBUG_LEVEL_8 8
+#define DEBUG_LEVEL_7 7
+#define DEBUG_LEVEL_6 6
+#define DEBUG_LEVEL_5 5
+#define DEBUG_LEVEL_4 4
+#define DEBUG_LEVEL_3 3
+#define DEBUG_LEVEL_2 2
+#define DEBUG_LEVEL_1 1
+#define DEBUG_LEVEL_0 0
+
+
+typedef struct _HC_DEV_STRUC {
+ UINT16 wPCIDev;
+ UINT16 wHCType;
+} HC_DEV_STRUC;
+
+extern EFI_SMM_SYSTEM_TABLE *gSmst;
+extern EFI_CPU_IO_PROTOCOL *CpuIo;
+
+//
+//Checks if Trap status is set
+//
+BOOLEAN hasTrapStatus();
+BOOLEAN TrapEnable(BOOLEAN );
+BOOLEAN NonSmmTrapEnable(BOOLEAN );
+
+#if OHCI_EMUL_SUPPORT == 1
+void SetHceOutput (UINT8);
+#endif
+
+EFI_STATUS
+RegisterAcpiEnableCallBack();
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcEmul.mak b/Core/EM/KbcEmul/KbcEmul.mak
new file mode 100644
index 0000000..87c282e
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmul.mak
@@ -0,0 +1,197 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.mak 10 12/04/14 12:50a Rajeshms $
+#
+# $Revision: 10 $
+#
+# $Date: 12/04/14 12:50a $
+#
+#****************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmul.mak $
+#
+# 10 12/04/14 12:50a Rajeshms
+# [TAG] EIP193601
+# [Category] New Feature
+# [Description] Aptio4.x - Security Enhancement for SMIHandler in
+# KbcEmulation module, Checks if BAR address access is inside SMRAM, if
+# yes, return.
+# [Files] KbcEmul.mak, KbcEmul.c, KbcOhci.c
+#
+# 9 9/16/13 6:53a Srikantakumarp
+# [TAG] EIP136515
+# [Category] Bug Fix
+# [Severity] Normal
+# [Symptom] Build error in AMD platform when enabling Emul6064_Support
+# [RootCause] OHCI_EMUL_LIB was not inluded while making KbcEmulBin
+# [Solution] Added OHCI_EMUL_LIB while making KbcEmulBin
+# [Files] KbcEmul.mak
+#
+# 8 5/13/13 2:48a Rameshr
+# [TAG] EIP119870
+# [Category] Improvement
+# [Description] Build error with KbcEmulation module if update USB
+# module label 4.6.3_USB_08.10.26
+# [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c
+#
+# 7 2/10/11 12:55a Rameshr
+# [TAG] EIP53687
+# [Category] Improvement
+# [Description] AMI headers update for KbcEmulation Module
+# [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+# EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+# use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+# KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+#
+# 6 7/08/10 1:59a Rameshr
+# Ohci Emulation support Added.
+# EIP 39712
+#
+# 5 8/19/09 2:25p Rameshr
+# Sb module component created to support SB porting for Emulation module.
+# EIP:25184
+#
+# 4 6/30/09 11:27a Rameshr
+# Coding Standard and File header updated.
+#
+# 3 6/01/09 10:01a Rameshr
+# Added Emulation Support for RMH enable/Disable
+# EIP 21131
+#
+# 2 12/27/07 6:45p Rameshraju
+#
+# 1 12/14/07 10:26a Rameshraju
+# Initial Check-in
+#****************************************************************************
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: KbcEmul.mak
+#
+# Description: Mak file the KBC Emulation
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!if $(UHCI_EMUL_SUPPORT)
+UHCI_EMUL = KbcUhci
+UHCI_EMUL_LIB= $(BUILD_DIR)\KbcUhciEmulBin.lib
+!else
+UHCI_EMUL =
+UHCI_EMUL_LIB=
+!endif
+
+!if $(OHCI_EMUL_SUPPORT)
+OHCI_EMUL = KbcOhci
+OHCI_EMUL_LIB= $(BUILD_DIR)\KbcOhciEmulBin.lib $(BUILD_DIR)\AmiBufferValidationLib.lib
+!else
+OHCI_EMUL =
+OHCI_EMUL_LIB=
+!endif
+!if $(IRQ_EMUL_SUPPORT)
+IRQ_EMUL = KbcEmulIrq
+IRQ_EMUL_LIB = $(BUILD_DIR)\KbcEmulIrq.lib
+!else
+IRQ_EMUL =
+IRQ_EMUL_LIB =
+!endif
+
+all: $(IRQ_EMUL) $(UHCI_EMUL) $(OHCI_EMUL) KbcEmul
+
+#-----------------------------------------------------------------------
+# Build script for IRQ Based Eumlation
+#-----------------------------------------------------------------------
+KbcEmulIrq : $(BUILD_DIR)\KbcEmulIrq.mak $(BUILD_DIR)\KbcEmulIrq.lib
+
+$(BUILD_DIR)\KbcEmulIrq.mak : $(KBCEMUL_DIR)\KbcEmulIrq.cif $(KBCEMUL_DIR)\KbcEmul.mak $(BUILD_RULES)
+ $(CIF2MAK) $(KBCEMUL_DIR)\KbcEmulIrq.cif $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\KbcEmulIrq.lib : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\
+ /f $(BUILD_DIR)\KbcEmulIrq.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcEmulIrq.lib
+
+#-----------------------------------------------------------------------
+# Build script for Uhci Based Eumlation
+#-----------------------------------------------------------------------
+KbcUhci : $(BUILD_DIR)\KbcUhci.mak $(BUILD_DIR)\KbcUhciEmulBin.lib
+
+$(BUILD_DIR)\KbcUhci.mak : $(KBCEMUL_DIR)\KbcUhci.cif $(KBCEMUL_DIR)\KbcEmul.mak $(BUILD_RULES)
+ $(CIF2MAK) $(KBCEMUL_DIR)\KbcUhci.cif $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\KbcUhciEmulBin.lib : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\
+ /f $(BUILD_DIR)\KbcUhci.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcUhciEmulBin.lib
+
+#-----------------------------------------------------------------------
+# Build script for Ohci Based Eumlation
+#-----------------------------------------------------------------------
+KbcOhci : $(BUILD_DIR)\KbcOhci.mak $(BUILD_DIR)\KbcOhciEmulBin.lib
+
+$(BUILD_DIR)\KbcOhci.mak : $(KBCEMUL_DIR)\KbcOhci.cif $(KBCEMUL_DIR)\KbcEmul.mak $(BUILD_RULES)
+ $(CIF2MAK) $(KBCEMUL_DIR)\KbcOhci.cif $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\KbcOhciEmulBin.lib : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\
+ /f $(BUILD_DIR)\KbcOhci.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcOhciEmulBin.lib
+
+
+#-----------------------------------------------------------------------
+# Build script for KBC Emulation
+#-----------------------------------------------------------------------
+KbcEmul : $(BUILD_DIR)\KbcEmul.mak KbcEmulBin
+
+$(BUILD_DIR)\KbcEmul.mak : $(KBCEMUL_DIR)\$(@B).cif $(KBCEMUL_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(KBCEMUL_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\KbcEmul.lib : $(BUILD_DIR)\debug.obj $(BUILD_DIR)\guids.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\KbcEmul.mak all\
+ "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\KbcEmul.lib
+
+KbcEmulBin : $(AMIDXELIB) $(UHCI_EMUL_LIB) $(OHCI_EMUL_LIB) $(IRQ_EMUL_LIB) $(BUILD_DIR)\KbcEmul.lib
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\KbcEmul.mak all\
+ GUID=3b24f79d-91a0-46ff-be29-458ae211fac5 \
+ ENTRY_POINT=EmulationEntryPoint \
+ "CFLAGS=$(CFLAGS) /I$(KBCEMUL_DIR) /DFRAMEWORK_AP4"\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ "EXT_HEADERS=$(EXT_HEADERS)"\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+ DEPEX1=$(KBCEMUL_DIR)\KbcEmul.dxs \
+
+IMAGE_ENTRY_POINT = EmulationEntryPoint
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcEmul.sdl b/Core/EM/KbcEmul/KbcEmul.sdl
new file mode 100644
index 0000000..996e149
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmul.sdl
@@ -0,0 +1,102 @@
+TOKEN
+ Name = "EMUL6064_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable KBC Emulation support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "AMIUSB_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "KBCEMUL_DIR"
+End
+
+PATH
+ Name = "KBC_SB_BOARD_DIR"
+ Path = "Board\Em\KbcSbBoard\"
+End
+
+MODULE
+ Help = "Includes Emul6064.mak into project"
+ File = "KbcEmul.mak"
+End
+
+TOKEN
+ Name = "UHCI_EMUL_SUPPORT"
+ Value = "1"
+ Help = "Switch to enable UHCI based Emulation support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UHCI_EMUL_PCI_DEVICES"
+ Help = "List of supported UHCI controllers in the following format: {dev1, ITF, SCC, BCC, offset}, {dev2, ITF, SCC, BCC, offset},...,{devN, ITF, SCC, BCC, offset}\dev represents the location of UHCI controller on PCI bus: dev = Bus << 8 + Dev << 3 + Func.\ITF represents the interface type of PCI device, for UHCI it must be 0.\SCC represents the sub class code of PCI device, for UHCI it must be 0x03.\BCC represents the base class code of PCI device, for UHCI it must be 0x0C.\offset represents the offset of legacy support register, for UHCI it must be 0xC0."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "UHCI_EMUL_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "OHCI_EMUL_SUPPORT"
+ Value = "0"
+ Help = "Switch to enable OHCI based Emulation support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OHCI_EMUL_PCI_DEVICES"
+ Help = "List of supported OHCI controllers in the following format: {type1, dev1, addr1}, {type2, dev2, addr2},...,{typeN, devN, addrN}\type represents the device type of emulation device is PceDevice or FixedMemory.\dev represents the location of OHCI controller on PCI bus: dev = Bus << 8 + Dev << 3 + Func.\addr represents the address of emulation registers if type is FixedMemory."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "OHCI_EMUL_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "ICH10_WORKAROUND"
+ Value = "0"
+ Help = "Switch to enable ICH10 Workaround. Emulation enabled and one of the USB controller disabled, We must clear the SMI status on disabled USB controller also"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IRQ_EMUL_SUPPORT"
+ Value = "1"
+ Help = "Switch to enable software method of IRQ generation in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SW_IRQ_GENERATION_REG"
+ Value = "$(PM_BASE_ADDRESS)+0x70"
+ Help = "Software IRQ generation regsiter from SB to generate the IRQ12 and IRQ1."
+ TokenType = Integer
+ TargetH = Yes
+ Token = "IRQ_EMUL_SUPPORT" "=" "1"
+ Token = "UHCI_EMUL_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "EMULATION_ACPI_ENABLE_DISPATCH"
+ Value = "0"
+ Help = "1-Emulation SMI's will be disabled in the USB controller."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\KbcEmul.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/KbcEmul/KbcEmulAcpi.c b/Core/EM/KbcEmul/KbcEmulAcpi.c
new file mode 100644
index 0000000..c926707
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmulAcpi.c
@@ -0,0 +1,156 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulAcpi.c 2 4/10/14 2:28a Rameshr $
+//
+// $Revision: 2 $
+//
+// $Date: 4/10/14 2:28a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulAcpi.c $
+//
+// 2 4/10/14 2:28a Rameshr
+// [TAG] EIP160392
+// [Category] Improvement
+// [Description] Junk Character from check-in History removed.
+// [Files] KbcEmulAcpi.c
+//
+// 1 1/09/12 1:22a Rameshr
+// [TAG] EIP74128
+// [Category] Improvement
+// [Description] Disable the KbcEmulation Smis on ACPI enable and
+// Disable SMI call
+// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif,
+// KbcEmul.h, KbcEmul.sdl
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: KbcEmulAcpi.c
+//
+// Description: This file contains Emulation SMI disable function on ACPI
+// enable/Disable SMI
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//----------------------------------------------------------------------------
+// Include(s)
+//----------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <Protocol\SmmSwDispatch.h>
+#include "KbcEmul.h"
+
+#ifdef EMULATION_ACPI_ENABLE_DISPATCH
+#include <Chipset\SB\AcpiModeEnable.h>
+EFI_GUID gEfiAcpiEnDispatchProtocolGuid = EFI_ACPI_EN_DISPATCH_PROTOCOL_GUID;
+EFI_GUID gEfiAcpiDisDispatchProtocolGuid = EFI_ACPI_DIS_DISPATCH_PROTOCOL_GUID;
+#endif
+
+extern BOOLEAN AcpiEmulationDisable;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: KbcEmulationDisable
+//
+// Description: This routine will be called when ACPI enabled or disabled SMI happens.
+//
+// Input: DispatchHandle - Handle to the Dispatcher
+//
+// Output: None
+//
+// Notes: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID KbcEmulationDisable (
+ IN EFI_HANDLE DispatchHandle
+)
+{
+ AcpiEmulationDisable=TRUE;
+ TrapEnable(FALSE);
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: RegisterAcpiEnableCallBack
+//
+// Description: This routine will be called by KbcEmulation Init
+// to register the callback function on Acpi Enable/Disable SMI.
+//
+// Input: None
+//
+// Output: None
+//
+// Notes: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RegisterAcpiEnableCallBack(
+)
+{
+#ifdef EMULATION_ACPI_ENABLE_DISPATCH
+ EFI_STATUS Status;
+ EFI_HANDLE EnableHandle;
+ EFI_HANDLE DisableHandle;
+ EFI_ACPI_DISPATCH_PROTOCOL *AcpiEnDispatch;
+ EFI_ACPI_DISPATCH_PROTOCOL *AcpiDisDispatch;
+
+ Status = pBS->LocateProtocol(&gEfiAcpiEnDispatchProtocolGuid, NULL, &AcpiEnDispatch);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = AcpiEnDispatch->Register(AcpiEnDispatch, KbcEmulationDisable, &EnableHandle);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&gEfiAcpiDisDispatchProtocolGuid, NULL, &AcpiDisDispatch);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = AcpiDisDispatch->Register(AcpiDisDispatch, KbcEmulationDisable, &DisableHandle);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+#else
+ return EFI_SUCCESS;
+#endif
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/KbcEmul/KbcEmulIrq.c b/Core/EM/KbcEmul/KbcEmulIrq.c
new file mode 100644
index 0000000..f43cbcc
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmulIrq.c
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulIrq.c 5 2/10/11 1:13a Rameshr $
+//
+// $Revision: 5 $
+//
+// $Date: 2/10/11 1:13a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulIrq.c $
+//
+// 5 2/10/11 1:13a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 4 7/08/10 2:00a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 3 6/30/09 11:37a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 8/07/08 10:20a Rameshraju
+// IRQ1 enabled before generating IRQ1
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: KbcEmulIrq.c
+//
+// Description: Handles the IRQ1 and IRQ12 generation
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#ifdef FRAMEWORK_AP4
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+#include "KbcEmul.h"
+#include "KbcEmulLib.h"
+#include "KbcDevEmul.h"
+#if OHCI_EMUL_SUPPORT
+#include "KbcOhci.h"
+#endif
+
+VOID GenerateIRQ12(VIRTKBC*);
+VOID GenerateIRQ1(VIRTKBC*);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GenerateIRQ12
+//
+// Description: Generate IRQ1
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GenerateIRQ12(VIRTKBC* vkbc)
+{
+
+#if UHCI_EMUL_SUPPORT
+ UINT8 Value8;
+
+ Value8=ByteReadIO(SW_IRQ_GENERATION_REG);
+ ByteWriteIO(SW_IRQ_GENERATION_REG, 0);
+ ByteWriteIO(SW_IRQ_GENERATION_REG, 2);
+ return;
+
+#else
+
+ if (GetHceStatus() & HCE_STS_OUTPUTFULL ){
+ SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE));
+ } else {
+ SetHceStatus((GetHceStatus() | HCE_STS_OUTPUTFULL | HCE_STS_AUXOUTPUTFULL));
+ SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE));
+ }
+ return;
+#endif
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GenerateIRQ1
+//
+// Description: Generate IRQ1
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GenerateIRQ1(VIRTKBC* vkbc)
+{
+
+#if UHCI_EMUL_SUPPORT
+ UINT8 Value8;
+ UINT8 IrqMask;
+
+ //
+ //Enable IRQ1 before generating the IRQ1.
+ //
+ IrqMask = ByteReadIO(0x21);
+ if (IrqMask & 0x02) {
+ IrqMask &= 0xFD;
+ ByteWriteIO (0x21, IrqMask);
+ }
+
+ Value8=ByteReadIO(SW_IRQ_GENERATION_REG);
+ ByteWriteIO(SW_IRQ_GENERATION_REG, 0);
+ ByteWriteIO(SW_IRQ_GENERATION_REG, 1);
+ return;
+
+#else
+ UINT8 IrqMask;
+ //
+ //Enable IRQ1 before generating the IRQ1.
+ //
+ IrqMask = ByteReadIO(0x21);
+ if (IrqMask & 0x02) {
+ IrqMask &= 0xFD;
+ ByteWriteIO (0x21, IrqMask);
+ }
+
+ if (GetHceStatus() & HCE_STS_OUTPUTFULL ){
+ SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE));
+ } else {
+ vkbc->st_ |= KBC_STATUS_OBF;
+ SetHceStatus((GetHceStatus() | KBC_STATUS_OBF));
+ SetHceControl((GetHceControl() | HCE_CNTRL_IRQ_ENABLE));
+ }
+ return;
+#endif
+
+}
+
+//****************************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcEmulIrq.cif b/Core/EM/KbcEmul/KbcEmulIrq.cif
new file mode 100644
index 0000000..6a5fe4c
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmulIrq.cif
@@ -0,0 +1,8 @@
+<component>
+ name = "KbcEmulIrq"
+ category = ModulePart
+ LocalRoot = "core\em\KbcEmul"
+ RefName = "KbcEmulIrq"
+[files]
+"KbcEmulIrq.c"
+<endComponent>
diff --git a/Core/EM/KbcEmul/KbcEmulLib.c b/Core/EM/KbcEmul/KbcEmulLib.c
new file mode 100644
index 0000000..8e84535
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmulLib.c
@@ -0,0 +1,572 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.c 4 2/10/11 1:00a Rameshr $
+//
+// $Revision: 4 $
+//
+// $Date: 2/10/11 1:00a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.c $
+//
+// 4 2/10/11 1:00a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 3 6/30/09 11:29a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 2/05/09 9:40a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+// Name: KbcEmullib.c
+//
+// Description: KBC emulation lib file that used in other files
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "KbcEmulLib.h"
+
+UINT16 WritePCIConfig(UINT16, UINT8);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ByteReadIO
+//
+// Description: This routine reads a Byte from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+ByteReadIO(UINT16 wIOAddr)
+{
+ UINT8 value;
+ gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT8, (UINT64)wIOAddr, 1, &value);
+ return value;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ByteWriteIO
+//
+// Description: This routine writes a byte to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// bValue Byte value to write
+//
+// Output: None
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+ByteWriteIO (UINT16 wIOAddr, UINT8 bValue)
+{
+ gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT8, (UINT64)wIOAddr, 1, &bValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WordReadIO
+//
+// Description: This routine reads a Word from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+WordReadIO(UINT16 wIOAddr)
+{
+ UINT16 value;
+ gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT16, (UINT64)wIOAddr, 1, &value);
+ return value;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WordWriteIO
+//
+// Description: This routine writes a word to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// wValue Word value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+WordWriteIO (UINT16 wIOAddr, UINT16 wValue)
+{
+ gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT16, (UINT64)wIOAddr, 1, &wValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordReadIO
+//
+// Description: This routine reads a dword from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+DwordReadIO(UINT16 wIOAddr)
+{
+ UINT32 value;
+ gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT32, (UINT64)wIOAddr, 1, &value);
+ return value;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordWriteIO
+//
+// Description: This routine writes a double word to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// dValue Double word value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+DwordWriteIO(UINT16 wIOAddr, UINT32 dValue)
+{
+ gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT32, (UINT64)wIOAddr, 1, &dValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadPCIConfig
+//
+// Description: This routine reads from the PCI configuration space register
+// the value can be typecasted to 8bits - 32bits
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register)
+{
+ UINT32 data;
+ DwordWriteIO(0xCF8, (UINT32)(0x80000000 | (BusDevFunc<<8) | (Register & 0xFC)));
+ data = DwordReadIO(0xCFC);
+ return (data >> ((Register & 3) << 3)); // Adjust uneven register
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ByteWritePCIConfig
+//
+// Description: This routine writes a byte value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+ByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = WritePCIConfig(BusDevFunc, Register);
+ ByteWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WordWritePCIConfig
+//
+// Description: This routine writes a byte value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+WordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = WritePCIConfig(BusDevFunc, Register);
+ WordWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordWritePCIConfig
+//
+// Description: This routine writes a Dword value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+DwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = WritePCIConfig(BusDevFunc, Register);
+ DwordWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WritePCIConfig
+//
+// Description: This function opens PCI configuration for a given register
+//
+// Input: wBDF - Bus, device and function number
+// bReg - Register number to read
+//
+// Output: IO register to write the value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+WritePCIConfig(UINT16 wBDF, UINT8 bReg)
+{
+ DwordWriteIO(0xCF8, (UINT32)(0x80000000 | (wBDF<<8) | (bReg & 0xFC)));
+ return (UINT16)(0xCFC+(bReg & 3));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmByteReadIO
+//
+// Description: This routine reads a Byte from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+NonSmmByteReadIO(UINT16 wIOAddr)
+{
+ UINT8 value;
+ CpuIo->Io.Read(CpuIo, EfiCpuIoWidthUint8, wIOAddr, 1, &value);
+ return value;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmByteWriteIO
+//
+// Description: This routine writes a byte to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// bValue Byte value to write
+//
+// Output: None
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+NonSmmByteWriteIO (UINT16 wIOAddr, UINT8 bValue)
+{
+ CpuIo->Io.Write(CpuIo, EfiCpuIoWidthUint8, wIOAddr, 1, &bValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmWordReadIO
+//
+// Description: This routine reads a Word from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+NonSmmWordReadIO(UINT16 wIOAddr)
+{
+ UINT16 value;
+ CpuIo->Io.Read(CpuIo, EfiCpuIoWidthUint16, wIOAddr, 1, &value);
+ return value;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmWordWriteIO
+//
+// Description: This routine writes a word to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// wValue Word value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+NonSmmWordWriteIO (UINT16 wIOAddr, UINT16 wValue)
+{
+ CpuIo->Io.Write(CpuIo, EfiCpuIoWidthUint16, wIOAddr, 1, &wValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmDwordReadIO
+//
+// Description: This routine reads a dword from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+NonSmmDwordReadIO(UINT16 wIOAddr)
+{
+ UINT32 value;
+ CpuIo->Io.Read(CpuIo, EfiCpuIoWidthUint32, wIOAddr, 1, &value);
+ return value;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmDwordWriteIO
+//
+// Description: This routine writes a double word to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// dValue Double word value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+NonSmmDwordWriteIO(UINT16 wIOAddr, UINT32 dValue)
+{
+ CpuIo->Io.Write(CpuIo, EfiCpuIoWidthUint32, wIOAddr, 1, &dValue);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmWritePCIConfig
+//
+// Description: This function opens PCI configuration for a given register
+//
+// Input: wBDF - Bus, device and function number
+// bReg - Register number to read
+//
+// Output: IO register to write the value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+NonSmmWritePCIConfig(UINT16 wBDF, UINT8 bReg)
+{
+ NonSmmDwordWriteIO(0xCF8, (UINT32)(0x80000000 | (wBDF<<8) | (bReg & 0xFC)));
+ return (UINT16)(0xCFC+(bReg & 3));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmReadPCIConfig
+//
+// Description: This routine reads from the PCI configuration space register
+// the value can be typecasted to 8bits - 32bits
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+NonSmmReadPCIConfig(UINT16 BusDevFunc, UINT8 Register)
+{
+ UINT32 data;
+ NonSmmDwordWriteIO(0xCF8, (UINT32)(0x80000000 | (BusDevFunc<<8) | (Register & 0xFC)));
+ data = NonSmmDwordReadIO(0xCFC);
+ return (data >> ((Register & 3) << 3)); // Adjust uneven register
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmByteWritePCIConfig
+//
+// Description: This routine writes a byte value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+NonSmmByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = NonSmmWritePCIConfig(BusDevFunc, Register);
+ NonSmmByteWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmWordWritePCIConfig
+//
+// Description: This routine writes a word value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to write
+// Value - Value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+NonSmmWordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = NonSmmWritePCIConfig(BusDevFunc, Register);
+ NonSmmWordWriteIO (wIOAddr, Value);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmDwordWritePCIConfig
+//
+// Description: This routine writes a Dword value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+// Output: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+NonSmmDwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = NonSmmWritePCIConfig(BusDevFunc, Register);
+ NonSmmDwordWriteIO (wIOAddr, Value);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/KbcEmulLib.h b/Core/EM/KbcEmul/KbcEmulLib.h
new file mode 100644
index 0000000..edd5a4e
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmulLib.h
@@ -0,0 +1,96 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.h 4 2/10/11 12:59a Rameshr $
+//
+// $Revision: 4 $
+//
+// $Date: 2/10/11 12:59a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcEmulLib.h $
+//
+// 4 2/10/11 12:59a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 3 6/30/09 11:29a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 2/05/09 9:41a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+// Name: KbcEmullib.h
+//
+// Description: KBC emulation Lib header file used in other files
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#ifndef _EMUL6064LIB_H_INC_
+
+UINT8 ByteReadIO(UINT16 wIOAddr);
+void ByteWriteIO (UINT16 wIOAddr, UINT8 bValue);
+UINT16 WordReadIO(UINT16 wIOAddr);
+void WordWriteIO (UINT16 wIOAddr, UINT16 wValue);
+UINT32 DwordReadIO(UINT16 wIOAddr);
+void DwordWriteIO(UINT16 wIOAddr, UINT32 dValue);
+UINT32 ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register);
+void ByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value);
+void WordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value);
+void DwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value);
+UINT32 ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register);
+
+UINT8 NonSmmByteReadIO(UINT16 wIOAddr);
+void NonSmmByteWriteIO (UINT16 wIOAddr, UINT8 bValue);
+UINT16 NonSmmWordReadIO(UINT16 wIOAddr);
+void NonSmmWordWriteIO (UINT16 wIOAddr, UINT16 wValue);
+UINT32 NonSmmDwordReadIO(UINT16 wIOAddr);
+void NonSmmDwordWriteIO(UINT16 wIOAddr, UINT32 dValue);
+UINT32 NonSmmReadPCIConfig(UINT16 BusDevFunc, UINT8 Register);
+void NonSmmByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value);
+void NonSmmWordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value);
+void NonSmmDwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value);
+UINT32 NonSmmReadPCIConfig(UINT16 BusDevFunc, UINT8 Register);
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/KbcEmulation.chm b/Core/EM/KbcEmul/KbcEmulation.chm
new file mode 100644
index 0000000..c229519
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcEmulation.chm
Binary files differ
diff --git a/Core/EM/KbcEmul/KbcOhci.c b/Core/EM/KbcEmul/KbcOhci.c
new file mode 100644
index 0000000..05f82b3
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcOhci.c
@@ -0,0 +1,1051 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.c 7 12/04/14 12:51a Rajeshms $
+//
+// $Revision: 7 $
+//
+// $Date: 12/04/14 12:51a $
+//
+//***********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.c $
+//
+// 7 12/04/14 12:51a Rajeshms
+// [TAG] EIP193601
+// [Category] New Feature
+// [Description] Aptio4.x - Security Enhancement for SMIHandler in
+// KbcEmulation module, Checks if BAR address access is inside SMRAM, if
+// yes, return.
+// [Files] KbcEmul.mak, KbcEmul.c, KbcOhci.c
+//
+// 6 12/05/13 12:46a Srikantakumarp
+// [TAG] EIP145881
+// [Category] Improvement
+// [Description] Ohci Emulation support needs to be extended for the
+// chipset , where the HCE registers defined in some fixed Memory for
+// Aptio 4.x
+// [Files] KbcEmul.sdl, KbcOhci.c, KbcOhci.h
+//
+// 5 5/13/13 2:52a Rameshr
+// [TAG] EIP119870
+// [Category] Improvement
+// [Description] Build error with KbcEmulation module if update USB
+// module label 4.6.3_USB_08.10.26
+// [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c
+//
+// 4 2/02/12 12:36a Rameshr
+// [TAG] EIP80605
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] It can not boot to DOS, If to disable 1st TOKEN report OHCI
+// by setup on legacy free system(must add KBC Emulation module).
+// [RootCause] gOHCIBar gets value from disabled controller and its not
+// valid value
+// [Solution] Added condition to check to have valid value in gOHCIBar
+// [Files] KbcOhci.c
+//
+// 3 7/14/11 12:28a Rameshr
+// [TAG] - EIP 62672
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - USB PEI (enable KBC emulation) can't boot from USB
+// [RootCause]- KbcEmulation gets the wrong BAR address that was
+// initilized by USB PEI driver
+// [Solution] - Ohci Base address reading should be done after the PCIbus
+// driver allocates the resource for the OHCI controller
+// [Files] - KbcOhci.c
+//
+// 2 2/10/11 1:14a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 1 7/08/10 2:07a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// Initial Check-in
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: KbcOhci.c
+//
+// Description: Handles the SMI events for port 60/64
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef FRAMEWORK_AP4
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+#include "KbcOhci.h"
+#include "KbcEmulLib.h"
+#include "Kbc.h"
+
+#include <AmiBufferValidationLib.h>
+
+extern KBC* gVirtualKBC;
+
+//Carries the LEGKEY status information saved before enable/disable trapping from outside trap handler is
+//performed; The saving of the status allows recovering legacy I/O accesss event in case when multiple
+//sources are serviced at signle SMI# ( legacy I/O and USB keyboard interupt, for example)
+
+static BOOLEAN gInTrapHandler = FALSE;
+BOOLEAN KBDDisabled = FALSE;
+
+OHCI_EMUL_DEVICE Ohci_Hc_Array[] = { OHCI_EMUL_PCI_DEVICES };
+UINTN Ohci_Hc_Array_Size = sizeof(Ohci_Hc_Array) / sizeof(Ohci_Hc_Array[0]);
+
+volatile OHCI_LEG_SUP_REGS *gLegSupRegs = NULL;
+
+void DisableLegKeyRegs();
+void trap64w();
+void trap60w();
+void trap64r();
+void trap60r();
+UINT8 GetHceInput();
+void SetHceOutput (UINT8 Data);
+BOOLEAN KBC_WaitForOutputBufferToBeFilled();
+BOOLEAN CheckPS2KBDMouseIRQEnabled();
+void CheckNumberofResponseBytes ();
+void WaitForOBFSMM();
+void SerialOutput (UINT8 Data);
+BOOLEAN gClearCharacterPending = FALSE;
+BOOLEAN MouseCmdInProgress = FALSE;
+
+// cmd, response, cmd, response ... 0
+UINT8 KBDCmdResponse[] = {0xF2, 3, 0xFF, 2, 0xF0, 1, 0xF3, 1, 0xF4, 1, 0xF5, 1, 0xF6, 1, 0xF7, 1, 0xF8, 1, 0xF9, 1, 0xFA, 1, 0xFB, 1, 0xFC, 1, 0xFD, 1, 0};
+UINT8 MouseCmdResponse[] = {0xFF, 3, 0xF2, 2, 0xE9, 4, 0xEb, 4, 0xE6, 1, 0xE7, 1, 0xE8, 1, 0xEA, 1, 0xEE, 1, 0xF0, 1, 0xF3, 1, 0xF4, 1, 0xF5, 1, 0};
+UINT8 ResponseBytes = 0;
+
+//status bits for SMI#, parenthesis is needed for ~ or other conversion
+#define OHCI_TRAPBY_MASK (HCE_CNTRL_EMULATION_INTERRUPT)
+
+//enable bits for traps
+#define OHCI_TRAPEN_MASK (HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_EXT_IRQ_ENABLE)
+
+void Trap6064_Handler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext
+ );
+
+void Trap6064_Handler_LegFree (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Smm_Register
+//
+// Description: Enable the SMI for port 6064 access.
+//
+// Input: None
+//
+// Output: None
+//
+// Note : Called inside SMM
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Smm_Register()
+{
+ EFI_SMM_USB_DISPATCH_CONTEXT context;
+ EFI_SMM_USB_DISPATCH_PROTOCOL* pDispatch;
+ EFI_HANDLE hDisp;
+ EFI_STATUS Status;
+ static FULL_USB_DEVICE_PATH hc_dp = USB1_1_DEVICE_PATH;
+ UINTN OhciCount;
+
+ //
+ // Register the USB HW SMI handler
+ //
+ Status = gBS->LocateProtocol(&gEfiSmmUsbDispatchProtocolGuid, NULL, &pDispatch);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // SMI registration routines will install the handlers, set enable bit
+ // and clear status in PM IO space.
+ //
+ for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){
+ hc_dp.pci.Device=(Ohci_Hc_Array[OhciCount].BusDevFunc >> 3);
+ hc_dp.pci.Function=(Ohci_Hc_Array[OhciCount].BusDevFunc & 07);
+ context.Type = UsbLegacy;
+ context.Device = (EFI_DEVICE_PATH_PROTOCOL *)&hc_dp;
+ if (IoRead8(0x64) == 0xFF) {
+ Status = pDispatch->Register(pDispatch,Trap6064_Handler_LegFree, &context, &hDisp);
+ } else {
+ Status = pDispatch->Register(pDispatch,Trap6064_Handler, &context, &hDisp);
+ }
+ }
+
+ //The SMI source for the port6064 is disabled. it will be enabled when we are in legacy enviorment.
+ //EFI enviorment Emulation is Disabled.
+ DisableLegKeyRegs();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableLegKeyRegs
+//
+// Description: Disable the port6064 SMI source based on the Trap enable mask.
+//
+// Input: None
+//
+// Output: None
+//
+// Note : Called inside SMM
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void DisableLegKeyRegs()
+{
+
+ if (gLegSupRegs != NULL) {
+ gLegSupRegs->HceControl = 0;
+ }
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HandleGA20Sequence
+//
+// Description: SMI triggered becauase of GA20 sequence change
+//
+// Input: None
+//
+// Output: None
+//
+// Note : Called inside SMM
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID HandleGA20Sequence()
+{
+ UINT8 Data;
+
+ if (IoRead8(0x64) == 0xFF) {
+ //
+ //Legacy Free system. Handle it using PORT 92
+ //
+ Data = GetHceInput();
+ IoWrite8(0x92, (IoRead8(0x92) & 0xFD) | (Data & 0x2));
+ SetHceControl(GetHceControl() & 0xFFFFFE3F | ((Data & 0x2) << 7));
+ }
+ else {
+ //
+ //Legacy Free system. Handle it using PORT 92. Maybe need to be chnaged if KBC needs to be used.
+ //
+ Data = GetHceInput();
+ IoWrite8(0x92, (IoRead8(0x92) & 0xFD) | (Data & 0x2));
+ SetHceControl(GetHceControl() & 0xFFFFFE3F | ((Data & 0x2) << 7));
+ }
+ ((VIRTKBC* )gVirtualKBC)->st_ = 0x1c;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Trap6064_Handler_LegFree
+//
+// Description: SMI handler to handle the 64write, 64read, 60 write and 60 read SMI.
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+// Output: None
+//
+// Note : Called inside SMM
+// Used only when KBC is NOT present on the system
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Trap6064_Handler_LegFree (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext
+ )
+{
+ UINT8 LegacyStatus;
+ UINTN OhciCount;
+ volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0;
+ VIRTKBD* kbd = (VIRTKBD*)gVirtualKBC->kbd_dev;
+ VIRTMOUSE* mouse = (VIRTMOUSE*)gVirtualKBC->mouse_dev;
+
+ ((VIRTKBC* )gVirtualKBC)->DelaySendingDataCmd = FALSE;
+
+ //
+ // check if gOHCIBar has a valid address
+ //
+ if (gLegSupRegs == NULL) {
+ for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){
+ if (Ohci_Hc_Array[OhciCount].Type == PciDevice) {
+ OHCIBar = ReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ;
+ if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL);
+ break;
+ }
+ } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr;
+ break;
+ }
+ }
+ if (gLegSupRegs == NULL) {
+ return;
+ } else {
+ // Check if MMIO address space of Legacy Support registers resides in SMRAM region. If yes, don't proceed.
+ if( AmiValidateMemoryBuffer( (VOID*)gLegSupRegs, sizeof(OHCI_LEG_SUP_REGS) ) ) {
+ return;
+ }
+ }
+ }
+
+ //
+ // Check emulation is enabled if not exit.
+ //
+ if ((GetHceControl() & (HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_EMULATION_INTERRUPT)) !=
+ (HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_EMULATION_INTERRUPT)) {
+ return;
+ }
+
+ LegacyStatus = GetHceStatus();
+
+
+ //
+ // Set the variable that we are processing the Trap
+ //
+ gInTrapHandler = TRUE;
+
+ //
+ // Disable Emulation ( in responce to i/o handler can try to access a real KBC)
+ //
+ SetHceControl(GetHceControl() & (~(HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_IRQ_ENABLE)));
+
+ //
+ // if Character Pending interrupt is enabled and OBF is not set, handle Port read 60
+ //
+ if (GetHceControl() & HCE_CNTRL_CHARACTER_PENDING && !(LegacyStatus & HCE_STS_OUTPUTFULL)){
+ trap60r();
+ } else {
+ //
+ //Clear OBF in internal structure
+ //
+ ((VIRTKBC*)gVirtualKBC)->st_ &= (~(KBC_STATUS_OBF | KBC_STATUS_AUXB));
+ // OBF is not full, clear AUX BUF also
+ if (!(LegacyStatus & KBC_STATUS_OBF)) {
+ LegacyStatus &= ~KBC_STATUS_AUXB;
+ }
+ //
+ // Update the Internal stucture with the correct value
+ //
+ ((VIRTKBC*)gVirtualKBC)->st_ |= LegacyStatus & (KBC_STATUS_OBF | KBC_STATUS_AUXB);
+ }
+
+ //
+ //Check for GA20 Sequence change
+ //
+ if ((LegacyStatus & HCE_STS_INPUTFULL) && GetHceControl() & HCE_CNTRL_GA20_SEQ){
+ HandleGA20Sequence();
+ } else {
+ // Dispatch the interrupt depending on saved status
+ if (LegacyStatus & HCE_STS_INPUTFULL) {
+ if (LegacyStatus & HCE_STS_CMDDATA) {
+ trap64w();
+ } else {
+ trap60w();
+ }
+ }
+ }
+
+ // Update Status
+ SetHceStatus(((VIRTKBC* )gVirtualKBC)->st_);
+
+ // If more data needs to be sent set Character Pending interrupt
+ if (kbd->qhead != kbd->qtail || mouse->qhead != mouse->qtail) {
+ SetHceControl(GetHceControl() | HCE_CNTRL_CHARACTER_PENDING);
+ gClearCharacterPending = FALSE;
+ } else {
+ if (gClearCharacterPending == TRUE){
+ SetHceControl(GetHceControl() & (~HCE_CNTRL_CHARACTER_PENDING));
+ gClearCharacterPending = FALSE;
+ } else {
+ // Clear Character Pending bit and OBF in next SMI
+ gClearCharacterPending = TRUE;
+ }
+ }
+
+ //
+ // Enable Traps
+ //
+ SetHceControl(GetHceControl() | HCE_CNTRL_EMULATION_ENABLE);
+ gInTrapHandler = FALSE;
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Trap6064_Handler
+//
+// Description: SMI handler to handle the 64write, 64read, 60 write and 60 read SMI.
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+// Output: None
+//
+// Note : Called inside SMM
+// Used only when KBC is present on the system
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Trap6064_Handler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext
+ )
+{
+ UINT8 EmulationStatus;
+ UINTN OhciCount;
+ volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0;
+ UINT8 Data;
+ VIRTMOUSE* mouse = (VIRTMOUSE*)gVirtualKBC->mouse_dev;
+
+ //
+ // check if gOHCIBar has a valid address
+ //
+ if (gLegSupRegs == NULL) {
+ for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){
+ if (Ohci_Hc_Array[OhciCount].Type == PciDevice) {
+ OHCIBar = ReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ;
+ if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL);
+ break;
+ }
+ } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr;
+ break;
+ }
+ }
+ if (gLegSupRegs == NULL) {
+ return;
+ } else {
+ // Check if MMIO address space of Legacy Support registers resides in SMRAM region. If yes, don't proceed.
+ if( AmiValidateMemoryBuffer( (VOID*)gLegSupRegs, sizeof(OHCI_LEG_SUP_REGS) ) ) {
+ return;
+ }
+ }
+ }
+
+ //
+ // Check emulation is enabled if not exit.
+ //
+ if (!( GetHceControl() & HCE_CNTRL_EMULATION_ENABLE)) {
+ return;
+ }
+
+ ((VIRTKBC*)gVirtualKBC)->st_ = EmulationStatus = GetHceStatus();
+
+ // Set the variable that we are processing the Trap
+ gInTrapHandler = TRUE;
+
+ //
+ // Disable Emulation ( in response to i/o handler can try to access a real KBC)
+ //
+ SetHceControl(GetHceControl() & (~(HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE)));
+
+ //
+ // Check if IRQ1 and IRQ12 is active
+ //
+ if (GetHceControl() & (HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE )){
+
+ // Update Status
+ Data = ByteReadIO(KBC_STATUS_REG);
+
+ if (Data & (KBC_STATUS_OBF | KBC_STATUS_AUXB)) {
+ // Update Data
+ SetHceOutput(ByteReadIO(KBC_DATA_REG));
+ ((VIRTKBC* )gVirtualKBC)->DelaySendingDataCmd = TRUE;
+ SerialOutput(GetHceOutput());
+ } else {
+ // No data but only IRQ, then use emulation status
+ Data = EmulationStatus;
+ }
+
+ //
+ // Clear the IRQ12/IRQ1 Active bit. Enable IRQEn only if data is pending
+ //
+ if ((Data & (KBC_STATUS_OBF | KBC_STATUS_AUXB)) == (KBC_STATUS_OBF | KBC_STATUS_AUXB)) {
+ SetHceControl (GetHceControl() | HCE_CNTRL_IRQ12_ACTIVE | HCE_CNTRL_IRQ_ENABLE);
+ } else if ((Data & (KBC_STATUS_OBF | KBC_STATUS_AUXB)) == KBC_STATUS_OBF ) {
+ SetHceControl (GetHceControl() | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ_ENABLE);
+ }
+
+ //
+ // This is a catch all condition. If IRQ generatd with out data just clear the status.
+ //
+ if (!(Data & KBC_STATUS_OBF)) {
+ SetHceControl (GetHceControl() | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE | HCE_CNTRL_IRQ_ENABLE);
+ }
+
+ SetHceStatus(Data);
+ SerialOutput(Data);
+ } else {
+
+ //
+ // Enable HCE_CNTRL_EXT_IRQ_ENABLE
+ //
+ SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE | HCE_CNTRL_IRQ_ENABLE) | HCE_CNTRL_EXT_IRQ_ENABLE);
+ ((VIRTKBC* )gVirtualKBC)->DelaySendingDataCmd = FALSE;
+
+
+ //
+ // if Character Pending interrupt is enabled and OBF is not set, handle Port read 60
+ //
+ if (GetHceControl() & HCE_CNTRL_CHARACTER_PENDING && !(EmulationStatus & HCE_STS_OUTPUTFULL)){
+ if (ResponseBytes){
+ if (!mouse->sink.present_) {
+ trap60r();
+ } else {
+ WaitForOBFSMM();
+ }
+ }
+ Data=ByteReadIO(KBC_STATUS_REG);
+ if (Data & KBC_STATUS_OBF) {
+ ResponseBytes--;
+ SetHceOutput(ByteReadIO(KBC_DATA_REG));
+ SerialOutput(GetHceOutput());
+ ((VIRTKBC* )gVirtualKBC)->st_ = Data;
+ }
+ }
+
+ //Check for GA20 Sequence change
+ if ((EmulationStatus & HCE_STS_INPUTFULL) && GetHceControl() & HCE_CNTRL_GA20_SEQ){
+ HandleGA20Sequence();
+ // Clear the i/p full bit once the cmd/data is processed
+ ((VIRTKBC*)gVirtualKBC)->st_ = ((VIRTKBC*)gVirtualKBC)->st_ & ~(HCE_STS_INPUTFULL);
+ } else {
+ // Dispatch the interrupt depending on saved status
+ if (EmulationStatus & HCE_STS_INPUTFULL) {
+ if (EmulationStatus & HCE_STS_CMDDATA) {
+ MouseCmdInProgress = FALSE;
+ if (GetHceInput() == 0xD4) {
+ MouseCmdInProgress = TRUE;
+ }
+ SerialOutput(GetHceInput());
+ trap64w();
+ } else {
+ SerialOutput(GetHceInput());
+ trap60w();
+ CheckNumberofResponseBytes();
+ if (!CheckPS2KBDMouseIRQEnabled() && ResponseBytes) {
+ WaitForOBFSMM();
+ }
+ MouseCmdInProgress = FALSE;
+ Data=ByteReadIO(KBC_STATUS_REG);
+ if (!(Data & KBC_STATUS_OBF)) {
+ ResponseBytes = 0;
+ }
+ //
+ // if no data in emulation o/p register then update it
+ //
+ if (!(GetHceStatus() & KBC_STATUS_OBF) && (Data & KBC_STATUS_OBF)){
+ // Update Data
+ SetHceOutput(ByteReadIO(KBC_DATA_REG));
+ SerialOutput(GetHceOutput());
+ ((VIRTKBC* )gVirtualKBC)->st_ = Data;
+ if (ResponseBytes) {
+ ResponseBytes--;
+ }
+ }
+ }
+ // Clear the i/p full bit once the cmd/data is processed
+ ((VIRTKBC*)gVirtualKBC)->st_ = ((VIRTKBC*)gVirtualKBC)->st_ & ~(HCE_STS_INPUTFULL);
+ }
+ }
+
+ // Update Status
+ SetHceStatus(((VIRTKBC* )gVirtualKBC)->st_);
+
+ if (ResponseBytes) {
+ SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) | HCE_CNTRL_CHARACTER_PENDING);
+ } else {
+ SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) & (~HCE_CNTRL_CHARACTER_PENDING));
+ }
+ }
+
+ //
+ // Enable Traps
+ //
+ SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) | HCE_CNTRL_EMULATION_ENABLE);
+ gInTrapHandler = FALSE;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Ohci_TrapEnable
+//
+// Description: Enable/Disable traping in OHCI HC.
+//
+// Input: Boolean
+//
+// Output: TRUE/FALSE
+//
+// Note : Called inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN Ohci_TrapEnable(BOOLEAN TrapEnable)
+{
+ UINTN OhciCount;
+ volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0;
+
+ if(gInTrapHandler)
+ return FALSE;
+
+ // The idea is, since data has not been pushed, don't let USB module to send more data. By keeping emulation enabled
+ // emulation status will be sent, which will return O/P full so next byte will not be sent from USB
+ if (GetHceStatus() & KBC_STATUS_OBF) {
+ return FALSE;
+ }
+
+ if (gLegSupRegs == NULL) {
+ for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){
+ if (Ohci_Hc_Array[OhciCount].Type == PciDevice) {
+ OHCIBar = ReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ;
+ if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL);
+ break;
+ }
+ } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr;
+ break;
+ }
+ }
+ if (gLegSupRegs == NULL) {
+ return FALSE;
+ } else {
+ // Check if MMIO address space of Legacy Support registers resides in SMRAM region. If yes, don't proceed.
+ if( AmiValidateMemoryBuffer( (VOID*)gLegSupRegs, sizeof(OHCI_LEG_SUP_REGS) ) ) {
+ return FALSE;
+ }
+ }
+ }
+
+ if(TrapEnable){
+ //
+ // Enable Traps
+ //
+ SetHceControl(GetHceControl() & ~(HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE) | HCE_CNTRL_EMULATION_ENABLE);
+ } else {
+ //
+ // Disable Traps;
+ //
+ SetHceControl((GetHceControl() & ~HCE_CNTRL_EMULATION_ENABLE) | HCE_CNTRL_IRQ1_ACTIVE | HCE_CNTRL_IRQ12_ACTIVE);
+ }
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Ohci_HasTrapStatus
+//
+// Description: Return whether Emulation Interrupt has been generated or not
+//
+// Input: None
+//
+// Output: BOOLEAN
+//
+// Note : Called inside SMM. No usage for now. Present for compatible reason with OHCI.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN Ohci_HasTrapStatus()
+{
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmOhci_TrapEnable
+//
+// Description: Enable/Disable traping in OHCI HC.
+//
+// Input: Boolean
+//
+// Output: TRUE/FALSE
+//
+// Note: Called outside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN NonSmmOhci_TrapEnable(BOOLEAN TrapEnable)
+{
+ UINTN OhciCount;
+ volatile EFI_PHYSICAL_ADDRESS OHCIBar = 0;
+ EFI_TPL OldTpl;
+
+ if (gLegSupRegs == NULL) {
+ for( OhciCount = 0; OhciCount < Ohci_Hc_Array_Size; ++OhciCount ){
+ if (Ohci_Hc_Array[OhciCount].Type == PciDevice) {
+ OHCIBar = NonSmmReadPCIConfig( Ohci_Hc_Array[OhciCount].BusDevFunc, 0x10) ;
+ if (OHCIBar != 0xFFFFFFFF && OHCIBar != 0) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)((OHCIBar & 0xFFFFFF00) + OHCI_HCE_CONTROL);
+ break;
+ }
+ } else if (Ohci_Hc_Array[OhciCount].Type == FixedMemory) {
+ gLegSupRegs = (OHCI_LEG_SUP_REGS*)Ohci_Hc_Array[OhciCount].MemAddr;
+ break;
+ }
+ }
+ if (gLegSupRegs == NULL) {
+ return FALSE;
+ }
+ }
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ if (TrapEnable) {
+ // Initialize the status to default value
+ gLegSupRegs->HceStatus = 0x1C;
+
+ // Enable Traps and clear status(es) that might be asserted by our handlers
+ if (IoRead8(0x64) == 0xFF) {
+ gLegSupRegs->HceControl = HCE_CNTRL_EMULATION_ENABLE | HCE_CNTRL_A20_STATE;
+ } else {
+ gLegSupRegs->HceControl = OHCI_TRAPEN_MASK | HCE_CNTRL_A20_STATE;
+ }
+ } else {
+ // Disable Traps; Clear the status
+ gLegSupRegs->HceControl &= ~OHCI_TRAPEN_MASK;
+ }
+ pBS->RestoreTPL(OldTpl);
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHceInput
+//
+// Description: Reads the HceInput register which holds the data written to port 60/64
+//
+// Input: None
+//
+// Output: UINT8
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetHceInput()
+{
+ return (UINT8)(gLegSupRegs->HceInput & 0xFF);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHceOutput
+//
+// Description: Reads the HceOutPut register in OHCI controller
+//
+// Input: None
+//
+// Output: UINT8
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetHceOutput()
+{
+ return (UINT8)(gLegSupRegs->HceOutput & 0xFF);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHceStatus
+//
+// Description: Reads the HceStatus register in OHCI controller
+//
+// Input: None
+//
+// Output: UINT8
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetHceStatus()
+{
+ return (UINT8)(gLegSupRegs->HceStatus & 0xFF);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetHceStatus
+//
+// Description: Writes to HceStatus in OHCI controller
+//
+// Input: UINT8
+//
+// Output: None
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void SetHceStatus (UINT8 Data)
+{
+ gLegSupRegs->HceStatus = (UINT32)Data;
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetHceOutput
+//
+// Description: Writes to HceOutput which is returned on IO port 60h read
+//
+// Input: UINT8
+//
+// Output: None
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void SetHceOutput (UINT8 Data)
+{
+ gLegSupRegs->HceOutput = (UINT32)Data;
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetHceControl
+//
+// Description: Writes to HceControl in OHCI controller
+//
+// Input: UINT8
+//
+// Output: None
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void SetHceControl (UINT16 Data)
+{
+ gLegSupRegs->HceControl = (UINT32)Data;
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetHceControl
+//
+// Description: Reads the HceStatus register in OHCI controller
+//
+// Input: None
+//
+// Output: UINT8
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 GetHceControl()
+{
+ return (UINT16)(gLegSupRegs->HceControl & 0x1FF);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WaitForOBFSMM
+//
+// Description: Wait till O/P buffer is full
+//
+// Input: None
+//
+// Output: None
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void
+WaitForOBFSMM()
+{
+ UINT8 bCount = 8;
+ UINT8 bStatus;
+ UINT32 wCount;
+ do {
+ wCount = 0xffff;
+ bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT0);
+ while (!bStatus) {
+ if(wCount == 0) break;
+ bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT0);
+ wCount--;
+ }
+ bCount--;
+ } while (bCount && (!bStatus));
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPS2KBDMousePresence
+//
+// Description: Check whether PS2 KBD/Mouse IRQ has been enabled or not
+//
+// Input: None
+//
+// Output: TRUE: if PS2 KBD/MOUSE IRQ enabled
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+CheckPS2KBDMouseIRQEnabled()
+{
+
+
+ LEGACYKBC* legkbc = _CR(gVirtualKBC,LEGACYKBC,kbc_);
+
+ // If the device and IRQ is enabled in CCB return TRUE else return FALSE
+ // The idea being, we don't have to wait for the response after the cmd is issued to the device.
+ // IRQ will be generated when the response is ready.
+
+ if (!legkbc->fCcb_loaded) {
+ return FALSE;
+ }
+
+ if (MouseCmdInProgress){
+ if (!(legkbc->ccb_ & KBC_CCB_EN2) && (legkbc->ccb_ & KBC_CCB_INT2)) {
+ return TRUE;
+ }
+ } else {
+ if (!(legkbc->ccb_ & KBC_CCB_EN) && (legkbc->ccb_ & KBC_CCB_INT)) {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckNumberofResponseBytes
+//
+// Description: Based on KBD/Mouse cmd, determine how many response bytes should be provided
+//
+// Input: None
+//
+// Output: Updates ResponseBytes
+//
+// Note : Called only inside SMM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void CheckNumberofResponseBytes ()
+{
+
+ UINT8 bData;
+ UINT8* CmdResponseArray;
+
+ ResponseBytes = 0;
+ bData = GetHceInput();
+ if (MouseCmdInProgress) {
+ ResponseBytes = 1;
+ CmdResponseArray = MouseCmdResponse;
+ } else {
+ CmdResponseArray = KBDCmdResponse;
+ }
+
+ do {
+ if (*CmdResponseArray == bData) {
+ ResponseBytes = *(CmdResponseArray +1);
+ break;
+ }
+ CmdResponseArray+=2;
+ } while (*CmdResponseArray);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SerialOutput
+//
+// Description: Directly writes to 3F8 COM port. Using this routine will be faster and
+// debug output delay will have no impact on debugging time sensitive routines
+// O/P the byte and give a space after that;
+//
+// Input: Byte to output
+//
+// Output: None
+//
+// Note :
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+//
+void SerialOutput (
+ UINT8 Data
+)
+{
+/*
+ UINT8 HigherNibble = Data >> 4;
+ UINT8 LowerBibble = Data & 0xF;
+
+ HigherNibble = HigherNibble > 9 ? HigherNibble + 0x37 : HigherNibble + 0x30;
+ IoWrite8 (0x3f8, HigherNibble);
+
+ LowerBibble = LowerBibble > 9 ? LowerBibble + 0x37 : LowerBibble + 0x30;
+ IoWrite8 (0x3f8, LowerBibble);
+
+ // Space
+ IoWrite8 (0x3f8, 0x20);
+*/
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcOhci.cif b/Core/EM/KbcEmul/KbcOhci.cif
new file mode 100644
index 0000000..d7b8585
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcOhci.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "KbcOhci"
+ category = ModulePart
+ LocalRoot = "core\em\KbcEmul"
+ RefName = "KbcOhci"
+[files]
+"KbcOhci.c"
+"KbcOhci.h"
+<endComponent> \ No newline at end of file
diff --git a/Core/EM/KbcEmul/KbcOhci.h b/Core/EM/KbcEmul/KbcOhci.h
new file mode 100644
index 0000000..fa8f0b6
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcOhci.h
@@ -0,0 +1,184 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.h 3 12/05/13 12:46a Srikantakumarp $
+//
+// $Revision: 3 $
+//
+// $Date: 12/05/13 12:46a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcOhci.h $
+//
+// 3 12/05/13 12:46a Srikantakumarp
+// [TAG] EIP145881
+// [Category] Improvement
+// [Description] Ohci Emulation support needs to be extended for the
+// chipset , where the HCE registers defined in some fixed Memory for
+// Aptio 4.x
+// [Files] KbcEmul.sdl, KbcOhci.c, KbcOhci.h
+//
+// 2 2/10/11 1:15a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 1 7/08/10 2:07a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// Initial Check-in
+//
+//**********************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: KbcOhci.h
+//
+// Description: Header file for OCHI controller for Emulation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+typedef enum {
+ UNSUPPORTED = -1,
+ USB1_1 = 0,
+ USB1_2,
+ USB1_3,
+ USB1_4,
+ USB2_1,
+ NUMBER_USB_CONTROLLERS
+} SUPPORTED_USB_CONTROLLERS;
+
+typedef enum {
+ PciDevice,
+ FixedMemory
+} EMUL_DEV_TYPE;
+
+typedef struct {
+ EMUL_DEV_TYPE Type;
+ UINT16 BusDevFunc;
+ UINTN MemAddr;
+} OHCI_EMUL_DEVICE;
+
+typedef struct _FULL_USB_DEVICE_PATH
+{
+ ACPI_HID_DEVICE_PATH acpi;
+ PCI_DEVICE_PATH pci;
+ EFI_DEVICE_PATH_PROTOCOL end;
+} FULL_USB_DEVICE_PATH;
+
+#define ACPI_PATH_MACRO \
+ {{ACPI_DEVICE_PATH,ACPI_DP,ACPI_DEVICE_PATH_LENGTH}, EISA_PNP_ID(0x0A03),0}
+
+#define PCI_PATH_MACRO(Device,Function) \
+ {{HARDWARE_DEVICE_PATH, HW_PCI_DP, HW_PCI_DEVICE_PATH_LENGTH}, (Function),(Device)}
+
+#define END_PATH_MACRO \
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,END_DEVICE_PATH_LENGTH}
+
+#define USB1_1_DEVICE_PATH \
+ { ACPI_PATH_MACRO, PCI_PATH_MACRO(0x1d, 0), END_PATH_MACRO }
+
+//
+// Trap Dispatcher
+//
+//
+typedef struct _TRAPDISPATCH {
+ UINT16 status_bit;
+ void (* trap_function)();
+} TRAPDISPATCH;
+
+
+#define PCIBUS(x) ( x << 16)
+#define PCIDEV(x) ( x << 11)
+#define PCIFUNC(x) ( x << 8)
+
+
+#define PCIOFF_MASK 0x000000FF
+#define PCIFUNC_MASK 0x0000FF00
+#define PCIDEV_MASK 0x00FF0000
+#define PCIBUS_MASK 0xFF000000
+
+// OHCI emulation register equates
+#define OHCI_HCE_CONTROL 0x100
+#define OHCI_HCE_INPUT 0x104
+#define OHCI_HCE_OUTPUT 0x108
+#define OHCI_HCE_STATUS 0x10C
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 HceControl;
+ UINT32 HceInput;
+ UINT32 HceOutput;
+ UINT32 HceStatus;
+} OHCI_LEG_SUP_REGS;
+
+#pragma pack(pop)
+
+// Bit definitions for emulation registers
+#define HCE_CNTRL_EMULATION_ENABLE BIT0
+#define HCE_CNTRL_EMULATION_INTERRUPT BIT1
+#define HCE_CNTRL_CHARACTER_PENDING BIT2
+#define HCE_CNTRL_IRQ_ENABLE BIT3
+#define HCE_CNTRL_EXT_IRQ_ENABLE BIT4
+#define HCE_CNTRL_GA20_SEQ BIT5
+#define HCE_CNTRL_IRQ1_ACTIVE BIT6
+#define HCE_CNTRL_IRQ12_ACTIVE BIT7
+#define HCE_CNTRL_A20_STATE BIT8
+
+
+#define HCE_STS_OUTPUTFULL BIT0
+#define HCE_STS_INPUTFULL BIT1
+#define HCE_STS_FLAG BIT2
+#define HCE_STS_CMDDATA BIT3
+#define HCE_STS_INHIBIT_SWITCH BIT4
+#define HCE_STS_AUXOUTPUTFULL BIT5
+#define HCE_STS_TIMEOUT BIT6
+#define HCE_STS_PARITY BIT7
+
+
+BOOLEAN Ohci_HasTrapStatus();
+BOOLEAN Ohci_TrapEnable(BOOLEAN);
+BOOLEAN NonSmmOhci_TrapEnable(BOOLEAN);
+BOOLEAN GetRMhStatus ();
+
+UINT16 GetHceControl();
+void SetHceControl (UINT16);
+void SetHceOutput (UINT8);
+UINT8 GetHceOutput();
+UINT8 GetHceStatus();
+void SetHceStatus (UINT8);
+UINT8 GetHceInput();
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/KbcUhci.c b/Core/EM/KbcEmul/KbcUhci.c
new file mode 100644
index 0000000..98b9824
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcUhci.c
@@ -0,0 +1,707 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.c 11 5/13/13 2:51a Rameshr $
+//
+// $Revision: 11 $
+//
+// $Date: 5/13/13 2:51a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.c $
+//
+// 11 5/13/13 2:51a Rameshr
+// [TAG] EIP119870
+// [Category] Improvement
+// [Description] Build error with KbcEmulation module if update USB
+// module label 4.6.3_USB_08.10.26
+// [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c
+//
+// 10 2/10/11 1:10a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 9 7/12/10 7:38a Rameshr
+// Ich10 Workaround added.
+//
+// 8 7/12/10 6:58a Rameshr
+// Workaround added when the Emulation enabled and Another USB controller
+// is disabled in ICH10.
+// EIP 39755
+//
+// 7 7/08/10 2:07a Rameshr
+// Function Output parameter changed for OHCI emulation support.
+//
+// 6 2/02/10 4:28a Rameshr
+// Before Regsiter the SMI call back for the USB PCI device, check the USB
+// PCI device presence
+// EIP 34601
+//
+// 5 6/30/09 11:36a Rameshr
+// Coding Standard and File header updated.
+//
+// 4 6/01/09 10:03a Rameshr
+// Added Emulation Support for RMH enable/Disable
+// EIP 21131
+//
+// 3 2/05/09 9:44a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 2 8/07/08 10:21a Rameshraju
+// All UHCI controller registed for the SMI handler
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: KbcUhci.c
+//
+// Description: Handles the SMI events for port 60/64
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+#ifdef FRAMEWORK_AP4
+#include "token.h"
+#else
+#include "tokens.h"
+#endif
+#include "KbcEmul.h"
+#include "KbcUhci.h"
+#include "KbcEmulLib.h"
+#include "Kbc.h"
+
+extern KBC* gVirtualKBC;
+
+#if ICH10_WORKAROUND
+EFI_STATUS EnableAllUhciController();
+EFI_STATUS RestoreUhciControllerStatus();
+#endif
+
+//Carries the LEGKEY status information saved before enable/disable trapping from outside trap handler is
+//performed; The saving of the status allows recovering legacy I/O accesss event in case when multiple
+//sources are serviced at signle SMI# ( legacy I/O and USB keyboard interupt, for example)
+
+static UINT16 SavedLegcyStatus = 0;
+
+static BOOLEAN gInTrapHandler = FALSE;
+
+
+UHCI_EMUL_DEVICE Uhci_Hc_Array[] = { UHCI_EMUL_PCI_DEVICES };
+UINTN Uhci_Hc_Array_Size = sizeof(Uhci_Hc_Array) / sizeof(Uhci_Hc_Array[0]);
+
+void DisableLegKeyRegs();
+void trap64w();
+void trap60w();
+void trap64r();
+void trap60r();
+
+TRAPDISPATCH trap_dispatcher[] = {
+ { UHCI_TRAPBY64W, trap64w },
+ { UHCI_TRAPBY64R, trap64r },
+ { UHCI_TRAPBY60W, trap60w },
+ { UHCI_TRAPBY60R, trap60r },
+};
+
+#define trap_dispatcher_size (sizeof(trap_dispatcher)/sizeof(trap_dispatcher[0]))
+
+//status bits for SMI#, parenthesis is needed for ~ or other conversion
+#define UHCI_TRAPBY_MASK (UHCI_TRAPBY64W | UHCI_TRAPBY64R | UHCI_TRAPBY60W | UHCI_TRAPBY60R | UHCI_SMIBYENDPS)
+//#define UHCI_TRAPBY_MASK (UHCI_TRAPBY64W | UHCI_TRAPBY60W | UHCI_TRAPBY60R | UHCI_SMIBYENDPS)
+
+//enable bits for traps
+#define UHCI_TRAPEN_MASK (UHCI_64WEN | UHCI_60WEN | UHCI_64REN | UHCI_60REN | UHCI_A20PASSEN )
+//#define UHCI_TRAPEN_MASK (UHCI_64WEN | UHCI_60WEN | UHCI_60REN | UHCI_A20PASSEN )
+
+void Trap6064_Handler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ValidateUhc
+//
+// Description: Validate the UHCI controller.
+//
+// Input: Boolean
+//
+// Output: Boolean
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+ValidateUhc (
+ UHCI_EMUL_DEVICE *Uhc
+)
+{
+ UINT32 Data32 = 0;
+
+ if (ReadPCIConfig (Uhc->BusDevFunc, 0) == 0xFFFFFFFF) {
+ return FALSE;
+ }
+
+ Data32 = ReadPCIConfig (Uhc->BusDevFunc, 8) >> 8;
+ if (Data32 != (*((UINT32*)&Uhc->InterfaceType) & 0x00FFFFFF)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Smm_Register
+//
+// Description: Enable the SMI for port 6064 access.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Smm_Register()
+{
+ EFI_SMM_USB_DISPATCH_CONTEXT context;
+ EFI_SMM_USB_DISPATCH_PROTOCOL* pDispatch;
+ EFI_HANDLE hDisp;
+ EFI_STATUS Status;
+ static FULL_USB_DEVICE_PATH hc_dp = USB1_1_DEVICE_PATH;
+ UINTN UhciCount;
+
+ //
+ // Register the USB HW SMI handler
+ //
+ Status = gBS->LocateProtocol(&gEfiSmmUsbDispatchProtocolGuid, NULL, &pDispatch);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // SMI registration routines will install the handlers, set enable bit
+ // and clear status in PM IO space.
+ //
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ //
+ //Validate the PCI device before regsiter the SMI callback.
+ //
+ if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+ hc_dp.pci.Device=(Uhci_Hc_Array[UhciCount].BusDevFunc >> 3);
+ hc_dp.pci.Function=(Uhci_Hc_Array[UhciCount].BusDevFunc & 07);
+ context.Type = UsbLegacy;
+ context.Device = (EFI_DEVICE_PATH_PROTOCOL *)&hc_dp;
+ Status = pDispatch->Register(pDispatch,Trap6064_Handler, &context, &hDisp);
+ }
+
+ SavedLegcyStatus = 0;
+ //
+ //The SMI source for the port6064 is disabled. it will be enabled when we are in legacy enviorment. EFI enviorment Emulation is
+ //Disabled.
+ //
+ DisableLegKeyRegs();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteLegKeyReg
+//
+// Description: Write the Value in to all the UHCI controller Legacy Regsiters.
+//
+// Input: UINT8 Value
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void WriteLegKeyReg ( UINT16 Value)
+{
+ UINTN UhciCount;
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ClearLegKeyStatusReg
+//
+// Description: Clear the Port6064 SMI Status Reg
+//
+// Input: UINT8 Value
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void ClearLegKeyStatusReg ( UINT16 Value)
+{
+ UINTN UhciCount;
+
+#if ICH10_WORKAROUND
+ //
+ // Enable all the UCHI controller
+ // In ICH10 chipset, we need to clear the Port 6064 SMI status in disabled controller
+ // also. Otherwise it's keep on generating SMI
+ //
+ EnableAllUhciController();
+#endif
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value);
+ }
+
+
+#if ICH10_WORKAROUND
+ //
+ // Restore the UCHI controller's in RCBA Reg
+ //
+ RestoreUhciControllerStatus();
+#endif
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableLegKeyRegs
+//
+// Description: Disable the port6064 SMI source based on the Trap enable mask.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void DisableLegKeyRegs()
+{
+ UINT16 legkeyStatus;
+ UINTN UhciCount;
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+
+ //
+ // Skip for Invalid Pci Devices
+ //
+ if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+
+ //
+ //Read the Legacy Keyboard and mouse control register
+ //
+ legkeyStatus =(UINT16) ReadPCIConfig(Uhci_Hc_Array[UhciCount].BusDevFunc ,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset ); // Read the status
+
+ //
+ //Clear the enable bits
+ //
+
+ WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc ,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset, legkeyStatus & ~UHCI_TRAPEN_MASK);
+
+ //
+ //Disable the trap
+ //
+ WordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset, legkeyStatus & (~UHCI_TRAPEN_MASK));
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Trap6064_Handler
+//
+// Description: SMI handler to handle the 64write, 64read, 60 write and 60 read SMI.
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Trap6064_Handler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT * DispatchContext
+ )
+{
+ UINT16 LegcyKeyStatus;
+ UINT32 TrapFunCount;
+ UINTN UhciCount;
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+
+ if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+
+ //
+ // Read UHCI_PCI_LEGKEY
+ //
+ LegcyKeyStatus = (UINT16) ReadPCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc ,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset );
+ SavedLegcyStatus |= LegcyKeyStatus;
+
+ if(SavedLegcyStatus==0xFFFF) {
+ SavedLegcyStatus=0;
+ continue;
+ }
+
+ if( (SavedLegcyStatus & UHCI_TRAPBY_MASK) != 0 ) {
+ break;
+ }
+
+ SavedLegcyStatus=0;
+ }
+
+ if(UhciCount >=Uhci_Hc_Array_Size) {
+ return;
+ }
+ //
+ // External application has chaned UHCI trap enable configuration, exit
+ //
+ if ((LegcyKeyStatus & UHCI_TRAPEN_MASK) != UHCI_TRAPEN_MASK)
+ return;
+
+ //
+ // Set the variable that we are processing the Trap
+ //
+ gInTrapHandler = TRUE;
+
+ //
+ // Clear the status
+ //
+ ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK);
+
+ //
+ // Disable Traps ( in responce to i/o handler can try to access a real KBC)
+ //
+ WriteLegKeyReg( (LegcyKeyStatus & ~UHCI_TRAPEN_MASK));
+
+ //
+ // Dispatch the interrupt depending on saved status
+ //
+ for( TrapFunCount = 0; TrapFunCount < trap_dispatcher_size; ++TrapFunCount ){
+ if( (LegcyKeyStatus & trap_dispatcher[TrapFunCount].status_bit ) != 0){
+ (*trap_dispatcher[TrapFunCount].trap_function)();
+ }
+ }
+
+ //
+ // Clear the Status
+ //
+ ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK);
+
+ //
+ // Enable Traps
+ //
+ WriteLegKeyReg( LegcyKeyStatus | UHCI_TRAPEN_MASK);
+
+ SavedLegcyStatus = 0;
+ gInTrapHandler = FALSE;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Uhci_HasTrapStatus
+//
+// Description: Check if trap status is set in UHCI HC.
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN Uhci_HasTrapStatus()
+{
+ UINT16 LegcyKeyStatus = 0;
+ UINTN UhciCount;
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+
+ LegcyKeyStatus |= (UINT16) ReadPCIConfig(Uhci_Hc_Array[UhciCount].BusDevFunc,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset );
+ }
+ return ((LegcyKeyStatus & UHCI_TRAPBY_MASK) != 0 );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Uhci_TrapEnable
+//
+// Description: Enable/Disable traping in UHCI HC.
+//
+// Input: Boolean
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN Uhci_TrapEnable(BOOLEAN TrapEnable)
+{
+ UINT16 LegcyKeyStatus;
+ UINTN UhciCount;
+
+ if(gInTrapHandler)
+ return FALSE;
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ if (!ValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+
+ LegcyKeyStatus =(UINT16) ReadPCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc ,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset );
+
+ //
+ //Record first time that trapping is disabled. Record only trap status bits handled by Trap handler
+ //
+ if( (LegcyKeyStatus & UHCI_TRAPEN_MASK)== UHCI_TRAPEN_MASK &&
+ ( LegcyKeyStatus & UHCI_TRAPBY_MASK) != 0 ){
+ //If legacy I/O caused SMI# and this is first time we are in uhci_trapEnable
+ //then trapping in LEGKEY reg must have been enabled and one trap status is set.
+ //Any port 60/64 operation within SMI# must be wrapped into
+ //enable/ disable&clear status. So subsequent trapEnable will not produce any
+ //trap statuses
+ SavedLegcyStatus |= LegcyKeyStatus;
+ }
+ if(TrapEnable){
+
+ //
+ //clear status(es) that might be asserted by our handlers
+ //
+ ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK);
+ //
+ // Enable Traps
+ //
+ WriteLegKeyReg( LegcyKeyStatus | UHCI_TRAPEN_MASK);
+ } else {
+
+ //
+ //clear status(es) that might be asserted by our handlers
+ //
+ ClearLegKeyStatusReg( LegcyKeyStatus | UHCI_TRAPBY_MASK);
+ //
+ // Disable Traps
+ //
+ WriteLegKeyReg( (LegcyKeyStatus & ~UHCI_TRAPEN_MASK) );
+ }
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmValidateUhc
+//
+// Description: Validate the UHCI controller.
+//
+// Input: Boolean
+//
+// Output: Boolean
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+NonSmmValidateUhc (
+ UHCI_EMUL_DEVICE *Uhc
+)
+{
+ UINT32 Data32 = 0;
+
+ if (NonSmmReadPCIConfig (Uhc->BusDevFunc, 0) == 0xFFFFFFFF) {
+ return FALSE;
+ }
+
+ Data32 = NonSmmReadPCIConfig (Uhc->BusDevFunc, 8) >> 8;
+ if (Data32 != (*((UINT32*)&Uhc->InterfaceType) & 0x00FFFFFF)) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmWriteLegKeyReg
+//
+// Description: Write the Value in to all the UHCI controller Legacy Regsiters.
+//
+// Input: UINT8 Value
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void NonSmmWriteLegKeyReg ( UINT16 Value)
+{
+ UINTN UhciCount;
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ if (!NonSmmValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+ NonSmmWordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value);
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmClearLegKeyStatusReg
+//
+// Description: Clear the Port6064 SMI Status
+//
+// Input: UINT8 Value
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void NonSmmClearLegKeyStatusReg ( UINT16 Value)
+{
+
+ UINTN UhciCount;
+
+#if ICH10_WORKAROUND
+ //
+ // Enable all the UCHI controller
+ // In ICH10 chipset, we need to clear the Port 6064 SMI status in disabled controller
+ // also. Otherwise it's keep on generating SMI
+ //
+ EnableAllUhciController();
+#endif
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ if (!NonSmmValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+ NonSmmWordWritePCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset, Value);
+ }
+
+#if ICH10_WORKAROUND
+ //
+ // Restore the UCHI controller's in RCBA Reg
+ //
+ RestoreUhciControllerStatus();
+#endif
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmUhci_TrapEnable
+//
+// Description: Enable/Disable traping in UHCI HC.
+//
+// Input: Boolean
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN NonSmmUhci_TrapEnable(BOOLEAN TrapEnable)
+{
+
+ UINT16 LegcyKeyStatus;
+ EFI_TPL OldTpl;
+ UINT16 UhciCount;
+
+ for( UhciCount = 0; UhciCount < Uhci_Hc_Array_Size; ++UhciCount ){
+ if (!NonSmmValidateUhc(&Uhci_Hc_Array[UhciCount])) {
+ continue;
+ }
+
+ LegcyKeyStatus =(UINT16) NonSmmReadPCIConfig( Uhci_Hc_Array[UhciCount].BusDevFunc ,
+ Uhci_Hc_Array[UhciCount].LegacyRegOffset );
+ //
+ //Record first time that trapping is disabled. Record only trap status bits handled by Trap handler
+ //
+ if( (LegcyKeyStatus & UHCI_TRAPEN_MASK)== UHCI_TRAPEN_MASK &&
+ ( LegcyKeyStatus & UHCI_TRAPBY_MASK) != 0 ){
+ //If legacy I/O caused SMI# and this is first time we are in uhci_trapEnable
+ //then trapping in LEGKEY reg must have been enabled and one trap status is set.
+ //Any port 60/64 operation within SMI# must be wrapped into
+ //enable/ disable&clear status. So subsequent trapEnable will not produce any
+ //trap statuses
+ SavedLegcyStatus |= LegcyKeyStatus;
+ }
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ if(TrapEnable){
+ //
+ // Clear the status
+ //
+ NonSmmClearLegKeyStatusReg(LegcyKeyStatus | UHCI_TRAPBY_MASK);
+ //
+ // Enable Traps
+ //
+ NonSmmWriteLegKeyReg( LegcyKeyStatus | UHCI_TRAPEN_MASK);
+ } else {
+ //
+ // Clear the status
+ //
+ NonSmmClearLegKeyStatusReg(LegcyKeyStatus | UHCI_TRAPBY_MASK);
+
+ //
+ // Disable the Trap
+ //
+ NonSmmWriteLegKeyReg( (LegcyKeyStatus & ~UHCI_TRAPEN_MASK) );
+ }
+ pBS->RestoreTPL(OldTpl);
+ }
+
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/KbcUhci.cif b/Core/EM/KbcEmul/KbcUhci.cif
new file mode 100644
index 0000000..5665a8b
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcUhci.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "KbcUhci"
+ category = ModulePart
+ LocalRoot = "core\em\KbcEmul"
+ RefName = "KbcUhci"
+[files]
+"KbcUhci.c"
+"KbcUhci.h"
+<endComponent>
diff --git a/Core/EM/KbcEmul/KbcUhci.h b/Core/EM/KbcEmul/KbcUhci.h
new file mode 100644
index 0000000..f584741
--- /dev/null
+++ b/Core/EM/KbcEmul/KbcUhci.h
@@ -0,0 +1,153 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.h 7 5/13/13 2:51a Rameshr $
+//
+// $Revision: 7 $
+//
+// $Date: 5/13/13 2:51a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/KbcUhci.h $
+//
+// 7 5/13/13 2:51a Rameshr
+// [TAG] EIP119870
+// [Category] Improvement
+// [Description] Build error with KbcEmulation module if update USB
+// module label 4.6.3_USB_08.10.26
+// [Files] KbcEmul.Mak, KbcEmul.SDl, KbcUhci.c, KbcUhci.h, KbcOhci.c
+//
+// 6 2/10/11 1:11a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 5 7/08/10 2:07a Rameshr
+// Function Output parameter changed for OHCI emulation support.
+//
+// 4 6/30/09 11:36a Rameshr
+// Coding Standard and File header updated.
+//
+// 3 6/01/09 10:03a Rameshr
+// Added Emulation Support for RMH enable/Disable
+// EIP 21131
+//
+// 2 2/05/09 9:44a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: KbcUhci.c
+//
+// Description: Header file for UCHI controller for Emulation
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+typedef enum {
+ UNSUPPORTED = -1,
+ USB1_1 = 0,
+ USB1_2,
+ USB1_3,
+ USB1_4,
+ USB2_1,
+ NUMBER_USB_CONTROLLERS
+} SUPPORTED_USB_CONTROLLERS;
+
+typedef struct {
+ UINT16 BusDevFunc;
+ UINT8 InterfaceType;
+ UINT8 SubClassCode;
+ UINT8 BaseClassCode;
+ UINT8 LegacyRegOffset;
+} UHCI_EMUL_DEVICE;
+
+typedef struct _FULL_USB_DEVICE_PATH
+{
+ ACPI_HID_DEVICE_PATH acpi;
+ PCI_DEVICE_PATH pci;
+ EFI_DEVICE_PATH_PROTOCOL end;
+} FULL_USB_DEVICE_PATH;
+
+#define ACPI_PATH_MACRO \
+ {{ACPI_DEVICE_PATH,ACPI_DP,ACPI_DEVICE_PATH_LENGTH}, EISA_PNP_ID(0x0A03),0}
+
+#define PCI_PATH_MACRO(Device,Function) \
+ {{HARDWARE_DEVICE_PATH, HW_PCI_DP, HW_PCI_DEVICE_PATH_LENGTH}, (Function),(Device)}
+
+#define END_PATH_MACRO \
+ {END_DEVICE_PATH,END_ENTIRE_SUBTYPE,END_DEVICE_PATH_LENGTH}
+
+#define USB1_1_DEVICE_PATH \
+ { ACPI_PATH_MACRO, PCI_PATH_MACRO(0x1d, 0), END_PATH_MACRO }
+
+//
+// Trap Dispatcher
+//
+//
+typedef struct _TRAPDISPATCH {
+ UINT16 status_bit;
+ void (* trap_function)();
+} TRAPDISPATCH;
+
+
+#define UHCI_SMIBYENDPS (UINT16)(1U << 15)
+#define UHCI_USBPIRQEN (UINT16)(1U << 13)
+#define UHCI_SMIBYUSB (UINT16)(1U << 12)
+#define UHCI_TRAPBY64W (UINT16)(1U << 11)
+#define UHCI_TRAPBY64R (UINT16)(1U << 10)
+#define UHCI_TRAPBY60W (UINT16)(1U << 9)
+#define UHCI_TRAPBY60R (UINT16)(1U << 8)
+#define UHCI_SMIATENDPS (UINT16)(1U << 7)
+#define UHCI_PSTATE (UINT16)(1U << 6)
+#define UHCI_A20PASSEN (UINT16)(1U << 5)
+#define UHCI_USBSMIEN (UINT16)(1U << 4)
+#define UHCI_64WEN (UINT16)(1U << 3)
+#define UHCI_64REN (UINT16)(1U << 2)
+#define UHCI_60WEN (UINT16)(1U << 1)
+#define UHCI_60REN (UINT16)(1U )
+
+#define PCIBUS(x) ( x << 16)
+#define PCIDEV(x) ( x << 11)
+#define PCIFUNC(x) ( x << 8)
+
+BOOLEAN Uhci_HasTrapStatus();
+BOOLEAN Uhci_TrapEnable(BOOLEAN);
+BOOLEAN NonSmmUhci_TrapEnable(BOOLEAN);
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/Kbccore.c b/Core/EM/KbcEmul/Kbccore.c
new file mode 100644
index 0000000..51516de
--- /dev/null
+++ b/Core/EM/KbcEmul/Kbccore.c
@@ -0,0 +1,341 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbccore.c 9 1/09/12 1:30a Rameshr $
+//
+// $Revision: 9 $
+//
+// $Date: 1/09/12 1:30a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Kbccore.c $
+//
+// 9 1/09/12 1:30a Rameshr
+// [TAG] EIP74128
+// [Category] Improvement
+// [Description] Disable the KbcEmulation Smi’s on ACPI enable and
+// Disable SMI call
+// [Files] Kbccore.c, KbcEmuulAcpi.c, KbcEmul.c, KbcEmul.cif,
+// KbcEmul.h, KbcEmul.sdl
+//
+// 8 1/06/12 3:51a Rameshr
+// [TAG] EIP78617
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] When KBCEmulation is enabled during OS runtime phase,
+// system reboots
+// [RootCause] if the SMI happens from AP, Kbcemulation driver unable to
+// handle it.
+// [Solution] Added logic in KbcCore.c to find the CPU that cause SMI
+// and access the corresponding AL register.
+// [Files] Ap4x.h, KbcCore.c
+//
+// 7 1/06/12 3:21a Rameshr
+// EIP78617 check-in removed.
+//
+// 5 2/10/11 1:02a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 4 7/08/10 1:56a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 3 6/30/09 11:30a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 2/05/09 9:35a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+//
+// Name: Kbccore.c
+//
+// Description: It has function for port 60 read, 60 write, 64 read and 64 write
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "kbc.h"
+#if UHCI_EMUL_SUPPORT
+#include "KbcUhci.h"
+#else
+#include "KbcOhci.h"
+#endif
+
+BOOLEAN AcpiEmulationDisable=FALSE;
+extern KBC* gVirtualKBC;
+
+#define SYNC_SMI_BIT (1 << 0)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindSMICpu
+//
+// Description: In a Multiprocessor environment, any logical CPU can generate
+// the SMI. This function finds the CPU that generates SMI by accessing
+// IO 60/64 Ports
+//
+// Input: None
+//
+// Output: UINT8 CpuIndex
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 FindSMICpu ( ) {
+ UINT8 CpuIndex;
+ UINT32 SmmIoMiscInfo;
+ UINT16 IOAddress;
+ UINT32 Smbase=0;
+
+ for (CpuIndex = 0; CpuIndex < gSmst->NumberOfCpus; CpuIndex++) {
+ //
+ // Find which CPU caused the SMI
+ //
+ Smbase = gSmst->CpuSaveState[CpuIndex].Ia32SaveState.SMBASE;
+ SmmIoMiscInfo = *(UINT32 *) (((UINT8 *) (UINTN) Smbase) + 0x8000 + 0x7FA4);
+ IOAddress = SmmIoMiscInfo >> 16;
+ if (((IOAddress == 0x60) || (IOAddress == 0x64)) && (SmmIoMiscInfo & SYNC_SMI_BIT)) {
+ return CpuIndex;
+ }
+ }
+
+ return 0xFF;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: getTrapAL
+//
+// Description: Get the port 60 or 64 input value from the CPU save reg
+//
+// Input: None
+//
+// Output: UINT8 Value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 GetTrapAL()
+{
+
+#if UHCI_EMUL_SUPPORT
+ UINT8 CpuIndex;
+
+ CpuIndex = FindSMICpu ();
+ ASSERT (CpuIndex != 0xFF);
+ return (UINT8)GET_CPUSAVESTATE_REG(CpuIndex, EAX);
+#else
+ return GetHceInput();
+#endif
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: setTrapAL
+//
+// Description: Set the port 60 or 64 output value to the CPU save reg
+//
+// Input: UINT8 Data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void SetTrapAL(UINT8 data)
+{
+
+#if UHCI_EMUL_SUPPORT
+ UINT8 CpuIndex;
+
+ CpuIndex = FindSMICpu();
+ ASSERT (CpuIndex != 0xFF);
+ *(UINT8*)&GET_CPUSAVESTATE_REG(CpuIndex, EAX) = data;
+#endif
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: trap64w
+//
+// Description: This function handles the Port64 write command
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void trap64w()
+{
+ (*gVirtualKBC->kbc_write_command)( gVirtualKBC,GetTrapAL() );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: setTrapAL
+//
+// Description: This function handles the Port60 write command
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void trap60w()
+{
+ (*gVirtualKBC->kbc_write_data)( gVirtualKBC,GetTrapAL() );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: setTrapAL
+//
+// Description: This function handles the Port64 Read command
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void trap64r()
+{
+ SetTrapAL((*gVirtualKBC->kbc_read_status)(gVirtualKBC));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: setTrapAL
+//
+// Description: This function handles the Port60 Read command
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void trap60r()
+{
+ SetTrapAL((*gVirtualKBC->kbc_read_data)(gVirtualKBC));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: hasTrapStatus
+//
+// Description: return the port 6064 trap status
+//
+// Input: None
+//
+// Output: TRUE: Trab enabled for port 6064
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN hasTrapStatus()
+{
+ BOOLEAN TrapStatus=FALSE;
+#if UHCI_EMUL_SUPPORT
+ TrapStatus=Uhci_HasTrapStatus();
+#endif
+#if OHCI_EMUL_SUPPORT
+ TrapStatus=Ohci_HasTrapStatus();
+#endif
+ return TrapStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TrapEnable
+//
+// Description: Enable/disable the port6064 trap
+//
+// Input: TRUE : enable the trap.
+// FALSE: Disable the trap.
+//
+// Output: TRUE : when suucessfully done else FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN TrapEnable(BOOLEAN b)
+{
+
+ if(AcpiEmulationDisable) {
+ return FALSE;
+ }
+
+#if UHCI_EMUL_SUPPORT
+ return Uhci_TrapEnable(b);
+#endif
+#if OHCI_EMUL_SUPPORT
+ return Ohci_TrapEnable(b);
+#endif
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NonSmmTrapEnable
+//
+// Description: Enable/disable the port6064 trap in Non SMM
+//
+// Input: TRUE : enable the trap.
+// FALSE: Disable the trap.
+//
+// Output: TRUE/FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NonSmmTrapEnable(BOOLEAN b)
+{
+#if UHCI_EMUL_SUPPORT
+ return NonSmmUhci_TrapEnable(b);
+#endif
+#if OHCI_EMUL_SUPPORT
+ return NonSmmOhci_TrapEnable(b);
+#endif
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/LegacyMouse.c b/Core/EM/KbcEmul/LegacyMouse.c
new file mode 100644
index 0000000..3c8cef8
--- /dev/null
+++ b/Core/EM/KbcEmul/LegacyMouse.c
@@ -0,0 +1,553 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/LegacyMouse.c 6 2/16/11 4:05a Rameshr $
+//
+// $Revision: 6 $
+//
+// $Date: 2/16/11 4:05a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/LegacyMouse.c $
+//
+// 6 2/16/11 4:05a Rameshr
+//
+// 5 2/10/11 1:05a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 4 7/08/10 2:01a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 3 6/30/09 11:31a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 10/30/08 10:47a Rameshraju
+// Keyboard & Mouse enable/disable command handled
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: LegacyMouse.c
+//
+// Description: LegacyMouse functions
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+
+#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
+
+static UINT8 resetResp[] = {0xFA, 0xAA, 0x00 } ;
+static UINT8 statusResp[] = {0xFA, 0x20, 0x02, 0x64 } ;
+static UINT8 dataResp[] = {0xFA, 0x08, 0x00, 0x0 } ;
+static UINT8 ackResp[] = {0xFA};
+static UINT8 idResp[] = {0xFA, 0};
+static UINT8 unknResp[] = {0xFE };
+
+void Legacymouse_reciev_option(PS2SINK* mouse, UINT8 cmd );
+void Legacymouse_initParams(LEGACYMOUSE* mouse);
+void Legacymouse_flushBuffer(LEGACYMOUSE* mouse);
+void Legacymouse_send_resp(LEGACYMOUSE* mouse, UINT8* data, int count );
+void Legacymouse_echo(PS2SINK* mouse, UINT8 cmd );
+BOOLEAN SendLegacyMouseBuffer(LEGACYMOUSE* mouse, UINT8* packet, UINTN Count );
+void Legacymouse_pumpQueue(PS2SINK* ps2dev);
+void KBC_WriteCommandByte(UINT8);
+UINT8 KBC_ReadDataByte();
+void KBC_WriteSubCommandByte(UINT8);
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_idle
+//
+// Description: Handle commands sent from KBC to PS2 Mouse. Mouse idle, waiting for command or key
+//
+// Input: ps2dev - pointer to the Mouse structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_idle(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev;
+ UINT8 CCB;
+
+ switch(cmd){
+ //
+ //reset
+ //
+ case 0xFF:
+ Legacymouse_initParams(mouse);
+ Legacymouse_send_resp(mouse, resetResp,COUNTOF(resetResp));
+ break;
+ //
+ //report status
+ //
+ case 0xE9:
+ Legacymouse_send_resp(mouse, statusResp,COUNTOF(statusResp));
+ break;
+ //
+ //read data
+ //
+ case 0xEB:
+ MemCpy(dataResp+1,&mouse->dataPacket,sizeof(mouse->dataPacket));
+ Legacymouse_flushBuffer(mouse);
+ Legacymouse_send_resp(mouse, dataResp,COUNTOF(dataResp));
+ break;
+ //
+ //Enable Mouse
+ //
+ case 0xF4:
+ //
+ //if mouse is not present then atleast CCB needs to be enabled
+ //
+ if(!mouse->sink.present_ ){
+ //
+ // Since mouse is not present, Update CCB to enable Mouse. KBC is present if control comes here.
+ //
+ KBC_WriteCommandByte(0x20);
+ CCB = KBC_ReadDataByte();
+ CCB &= 0xDF;
+ KBC_WriteCommandByte(0x60);
+ KBC_WriteSubCommandByte(CCB);
+ }
+ mouse->Enabled = TRUE;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Disable Mouse
+ //
+ case 0xF5:
+ if(!mouse->sink.present_ ){
+ //
+ // Since mouse is not present, Update CCB to Disable Mouse. KBC is present if control comes here.
+ //
+ KBC_WriteCommandByte(0x20);
+ CCB = KBC_ReadDataByte();
+ CCB = CCB | 0x20;
+ KBC_WriteCommandByte(0x60);
+ KBC_WriteSubCommandByte(CCB);
+ }
+ mouse->Enabled = TRUE;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Streaming
+ //
+ case 0xEA:
+ mouse->streaming = 1;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Remote
+ //
+ case 0xF0:
+ mouse->streaming = 0;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Standard, Set Scaling and Reset Scaling
+ //
+ case 0xF6:
+ case 0xE6:
+ case 0xE7:
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Identify
+ //
+ case 0xF2:
+ Legacymouse_send_resp(mouse, idResp,COUNTOF(idResp));
+ break;
+
+ //
+ // set resolution
+ //
+ case 0xE8:
+ mouse->option_ptr = &mouse->resolution_;
+ ps2dev->onCommand = Legacymouse_reciev_option;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ // set sampling rate
+ //
+ case 0xF3:
+ mouse->option_ptr = &mouse->samplingRate_;
+ ps2dev->onCommand = Legacymouse_reciev_option;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ case 0xEE:
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ ps2dev->onCommand = Legacymouse_echo;
+ break;
+ //
+ ////unknown command; send FE
+ //
+ default:
+ Legacymouse_send_resp(mouse, unknResp,COUNTOF(unknResp));
+ break;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_echo
+//
+// Description: Mouse Echo command
+//
+// Input: ps2dev - pointer to the Mouse structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_echo(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev;
+ if( cmd == 0xEC ){
+ ps2dev->onCommand = Legacymouse_idle;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ } else
+ Legacymouse_send_resp(mouse, &cmd,1);
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_reciev_option
+//
+// Description: Mouse reciev command
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_reciev_option(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev;
+ *(mouse->option_ptr) = cmd;
+ ps2dev->onCommand = Legacymouse_idle;
+ Legacymouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: msInput_Send
+//
+// Description: Mouse Input source sends data. Put the data into the buffer, attempt to send the first byte.
+// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden
+//
+// Input: P - pointer to the Emulation Protocol
+// Data - Ps2 mouse Data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI LegacymsInput_Send(
+ IN EFI_EMUL6064MSINPUT_PROTOCOL * This,
+ IN PS2MouseData* data
+ )
+{
+ LEGACYMOUSE* mouse = _CR(This,LEGACYMOUSE,msInput_);
+
+ //
+ //clear all previous flags except overflow
+ //
+ mouse->dataPacket.flags &= (PS2MSFLAGS_XO|PS2MSFLAGS_YO);
+ //
+ //copy overflow and button flags from new packet
+ //
+ mouse->dataPacket.flags |= data->flags & ~(PS2MSFLAGS_XSIGN|PS2MSFLAGS_YSIGN);
+ mouse->dataPacket.flags |= 0x8;
+ if( (mouse->dataPacket.flags & PS2MSFLAGS_XO) == 0){
+ if(data->flags & PS2MSFLAGS_XSIGN){
+ mouse->x += (signed short)((UINT8)data->x | 0xFF00);
+ } else {
+ mouse->x += data->x;
+ }
+ mouse->dataPacket.x = (UINT8)(UINT32)(mouse->x);
+ if( mouse->x < 0 ){
+ mouse->dataPacket.flags |= PS2MSFLAGS_XSIGN;
+ if( mouse->x < -256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_XO;
+ } else {
+ if( mouse->x > 256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_XO;
+ }
+ }
+
+ if( (mouse->dataPacket.flags & PS2MSFLAGS_YO) == 0){
+ if(data->flags & PS2MSFLAGS_YSIGN){
+ mouse->y += (signed short)((UINT8)data->y | 0xFF00);
+ } else {
+ mouse->y += data->y;
+ }
+ mouse->dataPacket.y = (UINT8)(UINT32)(mouse->y);
+ if( mouse->y < 0 ){
+ mouse->dataPacket.flags |= PS2MSFLAGS_YSIGN;
+ if( mouse->y < -256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_YO;
+ } else{
+ if( mouse->y > 256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_YO;
+ }
+ }
+
+ mouse->fFreshPacket = 1;
+ if( mouse->Enabled && mouse->streaming ){
+ if( SendLegacyMouseBuffer(mouse,(UINT8*)&mouse->dataPacket,sizeof(mouse->dataPacket)))
+ {
+ Legacymouse_flushBuffer(mouse);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SendLegacyMouseBuffer
+//
+// Description: Send the mouse packet to KBC
+//
+// Input: Mouse - pointer to the Mouse Structure
+// Packetr - Mouse Data
+// Count - Data Length
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SendLegacyMouseBuffer(LEGACYMOUSE* mouse, UINT8* packet, UINTN Count )
+{
+ UINTN FreeQueue = 0;
+
+ //
+ // count of free items in the queue
+ //
+ if( mouse->qtail >= mouse->qhead )
+ FreeQueue = MOUSEQUEUE_SIZE - (mouse->qtail - mouse->qhead);
+ else
+ FreeQueue = mouse->qhead - mouse->qtail;
+
+ if(FreeQueue < Count )
+ return TRUE;
+
+ //
+ //place the Mouse data in mouse buffer
+ //
+ for( ; Count > 0; --Count ){
+ *mouse->qtail++ = *packet++;
+ if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qtail = mouse->queue;
+ }
+
+ //
+ //Place the dummy 4th byte in mouse buffer,
+ //
+// *mouse->qtail++ = 0;
+// if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE)
+// mouse->qtail = mouse->queue;
+
+ //
+ // Disable trap to access real harware
+ //
+ TrapEnable(FALSE);
+ //
+ //Put the first byte in the KBC buffer
+ //
+ Legacymouse_pumpQueue(&mouse->sink);
+ //
+ // Enable trap back and clear statuses
+ //
+ TrapEnable(TRUE);
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Legacymouse_pumpQueue
+//
+// Description: KBC has empty queue; Legacy I/O trapping is being processed.If mouse has data to push into KBC,
+// now is a good time to do it
+//
+// Input: ps2dev - pointer to the Mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_pumpQueue(PS2SINK* ps2dev)
+{
+ LEGACYMOUSE* mouse = (LEGACYMOUSE*)ps2dev;
+
+ //
+ //Put the data into KBC
+ //
+ if((mouse->qhead != mouse->qtail) && (ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_MOUSE,FALSE,*mouse->qhead))) {
+ if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qhead = mouse->queue;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Legacymouse_send_resp
+//
+// Description: Place the Responce bytes in the keyboard buffer.
+//
+// Input: Mousev - pointer to the Mouse structure
+// Data - Pointer to the Data
+// count - Length of the data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_send_resp(LEGACYMOUSE* mouse, UINT8* data, int count )
+{
+ //
+ //When there is no PS2 mouse present in the system, Emulation should send the responce byte for the mouse command.
+ //If PS2 mouse present, it will send the responce to the KBC. So Emulation code doesn't need to responce it.
+ //
+ if(!mouse->sink.present_ ){
+ //
+ // Emulation must provide the responce. Override any previos mouse data queued to KBC
+ //
+ mouse->qtail = mouse->qhead = mouse->queue;
+ for( ; count > 0; --count ){
+ *mouse->qtail++ = *data++;
+ }
+
+ ///
+ // push the first byte to the KBC
+ //
+ if( mouse->qhead != mouse->qtail &&
+ mouse->sink.kbc->send_outb1(mouse->sink.kbc,PS2DEV_MOUSE,TRUE,*mouse->qhead))
+ {
+ if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qhead = mouse->queue;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Legacymouse_flushBuffer
+//
+// Description: Clear the mouse data buffer that tracks the mouse changes; after the data is cleared any data read
+// will return zero (x,y) and current buttons state.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_flushBuffer(LEGACYMOUSE* mouse)
+{
+ mouse->x = mouse->y = 0;
+ mouse->dataPacket.x = mouse->dataPacket.y = 0;
+ mouse->dataPacket.flags &= (PS2MSFLAGS_LBUTTON|PS2MSFLAGS_RBUTTON);
+ mouse->fFreshPacket = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_initParams
+//
+// Description: Initialize the mouse data
+//
+// Input: kbd - Pointer to the mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacymouse_initParams(LEGACYMOUSE* mouse)
+{
+ mouse->samplingRate_ = 0x64;
+ mouse->resolution_ = 2;
+ mouse->option_ptr = 0;
+ mouse->Enabled = FALSE;
+ mouse->streaming = 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitLegacyMouse
+//
+// Description: Initialize the Mouse data
+//
+// Input: kbc - pointer to the KBC Structure
+// Mouse - Pointer to the Mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitLegacyMouse(KBC* kbc, LEGACYMOUSE* mouse )
+{
+ EFI_HANDLE hEmulationService = 0;
+
+ mouse->qhead = mouse->qtail = mouse->queue;
+ mouse->sink.kbc = kbc;
+ mouse->sink.onCommand = Legacymouse_idle;
+ mouse->sink.onQueueFree = Legacymouse_pumpQueue;
+ mouse->msInput_.Send = LegacymsInput_Send;
+ mouse->x = mouse->y = 0;
+ mouse->dataPacket.flags = 0x8;
+ mouse->dataPacket.x = 0;
+ mouse->dataPacket.y = 0;
+ mouse->fFreshPacket = 0;
+ Legacymouse_initParams(mouse);
+ VERIFY_EFI_ERROR(
+ gBS->InstallProtocolInterface(&hEmulationService,
+ &gEmul6064MsInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&mouse->msInput_));
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/Legacykbc.c b/Core/EM/KbcEmul/Legacykbc.c
new file mode 100644
index 0000000..46e8f9f
--- /dev/null
+++ b/Core/EM/KbcEmul/Legacykbc.c
@@ -0,0 +1,821 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbc.c 9 7/19/11 6:26a Rameshr $
+//
+// $Revision: 9 $
+//
+// $Date: 7/19/11 6:26a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbc.c $
+//
+// 9 7/19/11 6:26a Rameshr
+//
+//
+// [TAG] - EIP 58220
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Remote Keyboard doesn't work when the Ps2 Keyboard not
+// attached in the system
+// [RootCause]- Write Keyboard Data command D2 is not handled
+// [Solution] - When the Ps2 device connected we are writting the data to
+// data port. But when the device is not connected we are not sending the
+// data. As this is KBC controller command data, we need to send the data
+// even though device is not connected
+// [Files] - LegacyKbc.c
+//
+// 8 2/10/11 1:03a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 7 10/14/10 12:45a Rameshr
+// [TAG] - EIP 45498
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - In KbcEmulation module, function kbc_kbd_wdata() of
+// Legacykbc.c can cause system to hang in SMM.
+// [RootCause]- For loop variable not decremented
+// [Solution] - For loop variable decremented to avoid the deadloop
+// [Files] - LegacyKbc.c
+//
+// 6 7/08/10 2:00a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 5 12/23/09 5:08a Rameshr
+// The Keyboard data wrongly pushed to Mouse device. That makes keyboard
+// stops working. Corrected this problem.
+//
+// 4 6/30/09 11:30a Rameshr
+// Coding Standard and File header updated.
+//
+// 3 2/05/09 9:44a Rameshr
+// Symptom : With Latest CSM Emulation doesn't work.
+// Solution: Added Emulation enable code in outside SMM. This is called
+// from Uhcd.c when ever USB mode changes to Legacy
+// EIP:18730
+//
+// 2 10/30/08 10:48a Rameshraju
+// Keyboard & Mouse enable/disable command handled
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: LegacyKbc.c
+//
+// Description: LegacyKBC handles the with KBC model
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+#include "Kbc.h"
+#include "KbcEmulLib.h"
+
+#define AUXOBF (KBC_STATUS_AUXB|KBC_STATUS_OBF)
+
+void kbc_passthrough_wdata( KBC* kbc, UINT8 data );
+void kbc_mouse_wdata( KBC* kbc, UINT8 data );
+void kbc_wccb( KBC* kbc, UINT8 data );
+void on_kbc_write_command( KBC* kbc, UINT8 cmd );
+UINT8 kbc_passthrough_rstatus( KBC* kbc );
+void legkbc_updateCCB(LEGACYKBC* legkbc, UINT8 set, UINT8 mask );
+void kbc_kbd_wdata( KBC* kbc, UINT8 data );
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: KBC_WaitForInputBufferToBeFree
+//
+// Description: This routine checks the input buffer free bit and waits till
+// it is set by the keyboard controller
+//
+// Input: None
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN KBC_WaitForInputBufferToBeFree ()
+{
+ UINT32 count ;
+ UINT8 status;
+
+ for( count = KBCTIMEOUT, status = 1; status != 0 && count != 0;
+ status= ByteReadIO(KBC_STATUS_REG) & KBC_STATUS_IBF, --count );
+
+ return ( status & KBC_STATUS_IBF)==0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: KBC_WaitForOutputBufferToBeFilled
+//
+// Description: This routine checks the output buffer full bit and waits till
+// it is set by the keyboard controller
+//
+// Input: None
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN KBC_WaitForOutputBufferToBeFilled ()
+{
+ UINT32 count ;
+ UINT8 status;
+ for( count = KBCTIMEOUT, status = 0; status == 0 && count != 0;
+ status = ByteReadIO(KBC_STATUS_REG) & KBC_STATUS_OBF,
+ --count );
+ return ( status & KBC_STATUS_OBF)!=0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: KBC_ReadDataByte
+//
+// Description: This routine till the keyboard controller sends a data byte
+//
+// Input: None
+//
+// Output: Data byte received from the keyboard controller
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 KBC_ReadDataByte ()
+{
+ KBC_WaitForOutputBufferToBeFilled();
+ return ByteReadIO(KBC_DATA_REG);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: KBC_WriteCommandByte
+//
+// Description: This routine writes the command to the keyboard controller
+//
+// Input: KBC Command
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void KBC_WriteCommandByte(UINT8 bCmd)
+{
+ KBC_WaitForInputBufferToBeFree();
+ ByteWriteIO(KBC_COMMAND_REG, bCmd);
+ KBC_WaitForInputBufferToBeFree();
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: KBC_WriteSubCommandByte
+//
+// Description: This routine writes the command to the keyboard controller
+//
+// Input: KBC Command
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void KBC_WriteSubCommandByte(UINT8 bCmd)
+{
+ KBC_WaitForInputBufferToBeFree();
+ ByteWriteIO(KBC_DATA_REG, bCmd);
+ KBC_WaitForInputBufferToBeFree();
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: KBC_WriteSubCommandByte
+//
+// Description: Return current CCB stored in KBC .Traping and tracking KBC ports I/O
+// allow to cache the ccb value. Still at the initial value must be
+// loaded by reading CCB from KBC (command 20). Care is taken not to
+// damage whatever data is stored in KBC
+//
+// Input: KBC
+//
+// Output: CCB value
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 kegkbc_readCCB( KBC* kbc )
+{
+ LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_);
+ UINT8 stSave;
+ UINT8 bSave;
+
+ if( legkbc->fCcb_loaded )
+ return legkbc->ccb_;
+
+ //
+ //Call can come from outside of Trap handler (EFI protocol invoked).We must disable trapping for this case
+ //
+ TrapEnable(FALSE);
+
+ //
+ // lock the KBC
+ //
+ KBC_WriteCommandByte(KBCCMD_LOCK);
+
+ //
+ //Get the Status regsiter value and Data from Data register
+ //
+ stSave = ByteReadIO(KBC_STATUS_REG);
+ bSave = ByteReadIO(KBC_DATA_REG);
+ KBC_WriteCommandByte(KBCCMD_READ_CCB);
+
+ //
+ //Get the CCB value and store it and set CCB has been read already.
+ //
+ legkbc->ccb_ = KBC_ReadDataByte();
+ legkbc->fCcb_loaded = TRUE;
+
+ //
+ //Push the Data to back to Keyboard Controller.
+ //
+ if(stSave & KBC_STATUS_OBF){
+ if( stSave & KBC_STATUS_AUXB )
+ KBC_WriteCommandByte(KBCCMD_WriteAuxBuffer);
+ else
+ KBC_WriteCommandByte(KBCCMD_WriteKbdBuffer);
+ ByteWriteIO(KBC_DATA_REG, bSave);
+ }
+
+ //
+ //Enable the trap again.
+ //
+ TrapEnable(TRUE);
+ return legkbc->ccb_;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_mouse_wdata
+//
+// Description: Handle write to port 60. Previouse command written to port 64 was "Send to auxilary device"
+// (0xD4). The data is passed to the Mouse emulation machine.
+// Next state is: accepting keyboard data on port 60.
+//
+// Input: KBC, Mouse data
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbc_mouse_wdata( KBC* kbc, UINT8 data )
+{
+ LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_);
+
+ //
+ //enable Aux interface
+ //
+ legkbc_updateCCB(legkbc,0,KBC_CCB_EN2);
+
+ if(kbc->mouse_dev->present_) {
+ KBC_WaitForInputBufferToBeFree();
+ ByteWriteIO( KBC_DATA_REG, data );
+ }
+
+ //
+ //Detect if real PS/2 mouse is present, Wait till responce comes
+ //
+
+ if(!kbc->mouse_dev->presence_detected_)
+ {
+ int c;
+ UINT8 st;
+ UINT8 mouseData;
+
+ //
+ //Mouse detection happens here
+ //
+ kbc->mouse_dev->presence_detected_= TRUE;
+
+ KBC_WaitForInputBufferToBeFree();
+
+ for( st = 0,c = 0x10000; c != 0 && (st & AUXOBF )!= AUXOBF;c--){
+ int c1;
+ st = ByteReadIO(KBC_STATUS_REG);
+ for( c1 = 0x10000; c1 != 0 && (st & AUXOBF) == KBC_STATUS_OBF; --c1 )
+ st = ByteReadIO(KBC_STATUS_REG);
+ if((st & AUXOBF) == KBC_STATUS_OBF ){
+ //not a mouse data; trash it (we can trash a keyboard key)
+ //TODO: a better detection alg. may be needed
+ //at least we can avoid trashing keyboard key: if non-mouse
+ //data is found (which must not accure for a correct application)
+ //get out of here assuming mouse present for the time (do not send)
+ //the responce; enable read port 64 and detect a mouse at the next
+ //trapped I/O
+ ByteReadIO(KBC_DATA_REG);
+ }
+ }
+
+ kbc->mouse_dev->present_ = FALSE;
+ if( (st & AUXOBF )== AUXOBF ){
+ //
+ //Mouse responce reached
+ //
+ mouseData = ByteReadIO(KBC_DATA_REG);
+ //
+ //Whatever command was it, good responce can not be 0xFE
+ //
+ kbc->mouse_dev->present_ = mouseData != 0xFE;
+
+ if( kbc->mouse_dev->present_ ){
+ //put the mouse responce back to KBC
+ KBC_WriteCommandByte( KBCCMD_WriteAuxBuffer);
+ ByteWriteIO(KBC_DATA_REG,mouseData);
+ KBC_WaitForInputBufferToBeFree();
+ }
+ }
+ }
+
+ (*kbc->mouse_dev->onCommand)(kbc->mouse_dev, data );
+
+ kbc->kbc_write_data = kbc_kbd_wdata;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_kbd_wdata
+//
+// Description: Handle write to port 60. The data is passed to the Keyboard emulation machine
+// Next state is: accepting keyboard data on port 60.
+//
+// Input: KBC, Keyboard data
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbc_kbd_wdata( KBC* kbc, UINT8 data )
+{
+ LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_);
+
+ legkbc_updateCCB(legkbc,0,KBC_CCB_EN); //enable KBD interface
+
+ if(kbc->kbd_dev->present_) {
+ KBC_WaitForInputBufferToBeFree();
+ ByteWriteIO( KBC_DATA_REG, data );
+ }
+
+ //
+ //Detect if real PS/2 Keyboard is present, Wait till responce comes
+ //
+ if(!kbc->kbd_dev->presence_detected_ && (data != 0xDD) && (data !=0xDF) )
+ {
+ int c;
+ UINT8 st;
+ UINT8 kbdData;
+
+ kbc->kbd_dev->presence_detected_= TRUE;
+ KBC_WaitForInputBufferToBeFree();
+
+ for( st = 0,c = 0x10000; c != 0 && (st & AUXOBF )!= KBC_STATUS_OBF;c-- ){
+ st = ByteReadIO(KBC_STATUS_REG);
+ if( st & KBC_STATUS_TO ){
+ break;
+ }
+ }
+ kbc->kbd_dev->present_ = FALSE;
+ if( (st & AUXOBF )== KBC_STATUS_OBF ){
+ //
+ //Keyboard responce reached
+ //
+ kbdData = ByteReadIO(KBC_DATA_REG);
+ //
+ //Whatever command was it, good responce can not be 0xFE
+ //
+ kbc->kbd_dev->present_ = kbdData != 0xFE;
+ if( kbc->kbd_dev->present_ ){
+ //
+ //put the responce back to KBC
+ //
+ KBC_WriteCommandByte( KBCCMD_WriteKbdBuffer);
+ ByteWriteIO(KBC_DATA_REG,kbdData);
+ KBC_WaitForInputBufferToBeFree();
+ }
+ }
+ }
+ (*kbc->kbd_dev->onCommand)(kbc->kbd_dev, data );
+ kbc->kbc_write_data = kbc_kbd_wdata;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_kbd_wdata2
+//
+// Description: Handle write to port 60. This function handles the data specfic the
+// KBC controller. Next state is: accepting keyboard data on port 60.
+//
+// Input: KBC, Keyboard data
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbc_kbd_wdata2( KBC* kbc, UINT8 data )
+{
+
+ LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_);
+ BOOLEAN DeviceStatus;
+ UINT8 ccb;
+
+ ccb = kegkbc_readCCB(kbc);
+ DeviceStatus = (ccb & KBC_CCB_EN);
+
+ //
+ //If the device disable, don't put data in KBC
+ //
+ if(DeviceStatus) {
+ return ;
+ }
+
+ KBC_WaitForInputBufferToBeFree();
+ //
+ //Write the Keyboard Data.
+ //
+ ByteWriteIO( KBC_DATA_REG, data );
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: legkbc_updateCCB
+//
+// Description: Update cached CCB in responce to trapped KBC command.If CCB wasn't loaded before, the new CCB cache is
+// still unkknown.
+//
+// Input: KBC, Set and Mask value
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void legkbc_updateCCB(LEGACYKBC* legkbc, UINT8 set, UINT8 mask )
+{
+ if(legkbc->fCcb_loaded){
+ //
+ //CCB value
+ //
+ legkbc->ccb_ = (legkbc->ccb_ & ~mask ) | (set & mask);
+ }
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_wccb
+//
+// Description: Handle write to port 60. Previouse command written to port 64 was "Write CCB (60h)"
+// The data is a new ccb. Next state is: accepting keyboard data on port 60.
+//
+// Input: KBC, CCB Data
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbc_wccb( KBC* kbc, UINT8 data )
+{
+ LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_);
+
+ // TODO: wait for IBF?
+ // to accept a data as a new value of ccb we must be sure that
+ // KBC will take it.
+ // Alternative is to check that IBF is clear only once. If IBF is
+ // not clear then set fCcb_loaded = FALSE. That will force next
+ // legkbc_readCCB to read a value from KBC, but we will not spend
+ // time in SMI# (or delay this wait until CCB is needed for emulation)
+ for( ;(ByteReadIO(KBC_STATUS_REG) & KBC_STATUS_IBF ) != 0 ; );
+ legkbc->ccb_ = data;
+ legkbc->fCcb_loaded = TRUE;
+
+ //
+ //Send the CCB to KBC
+ //
+ ByteWriteIO( KBC_DATA_REG, data );
+ kbc->kbc_write_data = kbc_kbd_wdata;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: on_kbc_write_command
+//
+// Description: Handle write to port 64. New command always aborts previous (no state dependency). This function
+// will always get called on port 64 write.Parse the incomming command and change the state accoringly
+//
+// Input: KBC, Port 64 Command
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void on_kbc_write_command( KBC* kbc, UINT8 cmd )
+{
+ LEGACYKBC* legkbc = _CR(kbc,LEGACYKBC,kbc_);
+ LEGACYMOUSE* Mouse = (LEGACYMOUSE*)kbc->mouse_dev;
+
+ ByteWriteIO(KBC_COMMAND_REG, cmd);
+ //
+ //If the command has data, it goes to Keyboard device
+ //
+ kbc->kbc_write_data = kbc_kbd_wdata;
+ switch(cmd){
+ case KBCCMD_WriteAuxDev:
+ //
+ //next data is a mouse data. So send it to mouse device
+ //
+ kbc->kbc_write_data = kbc_mouse_wdata;
+ break;
+ case KBCCMD_AUXENBL:
+ Mouse->Enabled = TRUE;
+ legkbc_updateCCB( legkbc, 0, KBC_CCB_EN2);
+ break;
+ case KBCCMD_AUXDSBL:
+ Mouse->Enabled = FALSE;
+ legkbc_updateCCB( legkbc, KBC_CCB_EN2, KBC_CCB_EN2);
+ break;
+ case KBCCMD_KBDENBL:
+ legkbc_updateCCB( legkbc, 0, KBC_CCB_EN);
+ break;
+ case KBCCMD_KBDDSBL:
+ legkbc_updateCCB( legkbc, KBC_CCB_EN, KBC_CCB_EN);
+ break;
+ case KBCCMD_WRITE_CCB:
+ kbc->kbc_write_data = kbc_wccb;
+ break;
+ case KBCCMD_WriteKbdBuffer:
+ case KBCCMD_WriteAuxBuffer:
+ kbc->kbc_write_data = kbc_kbd_wdata2;
+ break;
+ default:
+ break;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_passthrough_wdata
+//
+// Description: Handle write to port 60.The emulation doesn't process this write and the access is passed to the KBC
+//
+// Input: KBC, Port 60 Data
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbc_passthrough_wdata( KBC* kbc, UINT8 data )
+{
+ ByteWriteIO( KBC_DATA_REG, data );
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_passthrough_wcmd
+//
+// Description: Handle write to port 64.The emulation doesn't process this write and
+// the access is passed to the KBC
+//
+// Input: KBC, Port 64 command
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbc_passthrough_wcmd( KBC* kbc, UINT8 data )
+{
+ ByteWriteIO( KBC_STATUS_REG,data );
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_passthrough_wcmd
+//
+// Description: Handle read from port 64.The emulation doesn't process this read and
+// the access is passed to the KBC
+//
+// Input: KBC
+//
+// Output: KBC status
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 kbc_passthrough_rstatus( KBC* kbc )
+{
+ return ByteReadIO( KBC_STATUS_REG );
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: kbc_passthrough_wcmd
+//
+// Description: Handle read from port 60.The access is passed to the KBC. Emulation tracks the read to pump the
+// KBC output buffer (in case if there is more data in the queue)
+
+// Input: KBC
+//
+// Output: KBC Data
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 kbc_passthrough_rdata( KBC* kbc )
+{
+ UINT8 data;
+
+ //
+ //Get the data from KBC
+ //
+ data = ByteReadIO( KBC_DATA_REG );
+
+ //
+ //Push the Keyboard Data to KBC if it has any
+ //
+ (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev);
+
+ //
+ //Push the Mouse data to KBC , if it has any
+ //
+ (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev);
+
+ return data;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: legkbc_sendout
+//
+// Description: Implementation of the "send_outb1" for the case of legacy KBC present. Data is put into output buffer
+// of legacy KBC which sets OBF and generates IRQ. Application gets a chance to handle the interrupt and
+// read the data from legacy KBC.
+//
+// Notes: condition is checked: OBF is cleard (previous data was processed)
+//
+// Input: KBC, Device type, Data or Reponce data, Data
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN legkbc_sendout(KBC* kbc, PS2DEV_TYPE devtype, BOOLEAN ovrd, UINT8 data)
+{
+ UINT8 ccb;
+ BOOLEAN DeviceStatus;
+
+ ccb = kegkbc_readCCB(kbc);
+ DeviceStatus = (ccb & (devtype == PS2DEV_MOUSE ? KBC_CCB_EN2 : KBC_CCB_EN))==0;
+
+ //
+ //If the device disable, don't put data in KBC
+ //
+ if(!DeviceStatus)
+ return FALSE;
+
+
+ if( KBC_WaitForInputBufferToBeFree()){
+ UINT8 st;
+
+ KBC_WriteCommandByte(KBCCMD_LOCK); // lock the KBC
+ st = ByteReadIO(KBC_STATUS_REG);
+
+ //
+ //If the KBC , if already has data (OBF set) return, If it's free , then place data to KBC
+ //
+ if( ((st & KBC_STATUS_OBF) != 0) && !ovrd ){
+ //Output buffer is full - it's not a time to push our data
+
+ //unlock KBC by sending some command that doesn't trash the Output buffer
+ // since we see data from device, we assume that this interface is
+ //enabled in KBC. So there is no harm to enable it again. The exception to
+ //the rule is a sequence of data that emulation code is pushing into the KBC:
+ //to isolate sequence from asichncronose input from a real device, we disable
+ //the interface in KBC but still the data will appear in buffer. aux_en and kbd_en
+ //track the disabling/enabling interface by emulation code.
+ KBC_WriteCommandByte( (st & KBC_STATUS_AUXB) != 0? kbc->aux_en : kbc->kbd_en );
+ return FALSE;
+ }
+ //
+ //OBF is not set and KBC is ready to get the data.\
+ //
+ KBC_WriteCommandByte( devtype == PS2DEV_MOUSE ? KBCCMD_WriteAuxBuffer:KBCCMD_WriteKbdBuffer );
+ ByteWriteIO(KBC_DATA_REG,data);
+ KBC_WaitForInputBufferToBeFree();
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: initLegacyKBC
+//
+// Description: Initilize the KBC structure
+//
+// Input: KBC, KBD and Mouse
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void initLegacyKBC(KBC* kbc, PS2SINK* kbd, PS2SINK* mouse )
+{
+ kbc->mouse_dev = mouse;
+ kbc->kbd_dev = kbd;
+ kbc->sqTail[PS2DEV_KBD] = kbc->sqHead[PS2DEV_KBD] = kbc->send_queue;
+ kbc->sqTail[PS2DEV_MOUSE] = kbc->sqHead[PS2DEV_MOUSE] = kbc->send_queue_aux;
+ kbc->aux_en = KBCCMD_AUXENBL;
+ kbc->kbd_en = KBCCMD_KBDENBL;
+ kbd->present_ = TRUE;
+ kbd->presence_detected_ = FALSE;
+ mouse->presence_detected_ = FALSE;
+ mouse->present_ = TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: initLegacyKBC
+//
+// Description: Initialize Legacy KBC object
+//
+// Input: KBC, KBD and Mouse
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitLegacyKBC(LEGACYKBC* legkbc, PS2SINK* kbd, PS2SINK* mouse )
+{
+ initLegacyKBC(&legkbc->kbc_,kbd,mouse);
+ legkbc->kbc_.kbc_write_command = on_kbc_write_command;
+ legkbc->kbc_.kbc_write_data = kbc_kbd_wdata;
+ legkbc->kbc_.kbc_read_status = kbc_passthrough_rstatus;
+ legkbc->kbc_.kbc_read_data = kbc_passthrough_rdata;
+ legkbc->kbc_.send_outb1 = legkbc_sendout;
+ legkbc->kbc_.read_ccb = kegkbc_readCCB;
+ legkbc->ccb_ = 0;
+ legkbc->fCcb_loaded = FALSE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/Legacykbd.c b/Core/EM/KbcEmul/Legacykbd.c
new file mode 100644
index 0000000..3519098
--- /dev/null
+++ b/Core/EM/KbcEmul/Legacykbd.c
@@ -0,0 +1,479 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbd.c 4 6/27/12 1:30a Jittenkumarp $
+//
+// $Revision: 4 $
+//
+// $Date: 6/27/12 1:30a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/Legacykbd.c $
+//
+// 4 6/27/12 1:30a Jittenkumarp
+// [TAG] EIP89838
+// [Category] Improvement
+// [Description] KbcEmulation module can't changed NUM LOCK ,CAPS
+// LOCK,Scroll lock LED.
+// [Files] Legacykbd.c
+//
+// 3 2/10/11 1:04a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 2 6/30/09 11:31a Rameshr
+// Coding Standard and File header updated.
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: LegacyKbd.c
+//
+// Description: Legacy Keyboard functions
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+#include "KbcEmulLib.h"
+
+void LegacyKbd_initParams(LEGACYKBD* kbd);
+void LegacyKbd_read_codes(PS2SINK* ps2dev, UINT8 cmd );
+void LegacyKbd_read_option(PS2SINK* ps2dev, UINT8 cmd );
+void LegacyKbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd );
+void LegacyKbd_send_resp(LEGACYKBD* mouse, UINT8* data, int count );
+
+BOOLEAN KBC_WaitForInputBufferToBeFree ();
+BOOLEAN KBC_WaitForOutputBufferToBeFilled ();
+UINT8 KBC_ReadDataByte ();
+void KBC_WriteSubCommandByte(UINT8 bCmd);
+void KBC_WriteCommandByte(UINT8 bCmd);
+
+#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
+
+static UINT8 ackResp[] = {0xFA};
+static UINT8 ResetResp[] = {0xFA,0xAA};
+static UINT8 IdResp[] = {0xFA,0xAB, 0x41};
+static UINT8 ScanCodePageResp[] = {0xFA, 0x00};
+static UINT8 CmdED = 0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Legacykbd_scanning
+//
+// Description: Handle commands sent from KBC to PS2 Keyboard. Keyboard is scanning or idle, waiting for command
+// or key
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void Legacykbd_scanning(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink);
+ switch(cmd){
+ case 0xFF: //reset
+ LegacyKbd_initParams(kbd);
+ LegacyKbd_send_resp(kbd, ResetResp,COUNTOF(ResetResp));
+ break;
+ case 0xFD:
+ case 0xFC:
+ case 0xFB:
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->read_code_action = cmd;
+ kbd->sink.onCommand = LegacyKbd_read_codes;
+ break;
+ case 0xFA:
+ case 0xF9:
+ case 0xF8:
+ case 0xF7:
+ case 0xF6:
+ case 0xF5: //Disable
+ case 0xF4: //Enable
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ break;
+ case 0xF3: //Set Typeatic Rate/Delay
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->sink.onCommand = LegacyKbd_read_option;
+ kbd->option_ptr = &kbd->typematicRateDelay;
+ break;
+ case 0xF2:
+ LegacyKbd_send_resp(kbd, IdResp,COUNTOF(IdResp));
+ break;
+ case 0xF0:
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->sink.onCommand = LegacyKbd_rw_scancode;
+ kbd->option_ptr = &kbd->scancodepage;
+ break;
+
+ case 0xEE: //Echo
+ LegacyKbd_send_resp(kbd, &cmd,1);
+ break;
+
+ case 0xED: //LED
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->sink.onCommand = LegacyKbd_read_option;
+ kbd->option_ptr = &kbd->typematicRateDelay;
+ CmdED = 1;
+ break;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyKbd_read_codes
+//
+// Description: Keyboard Read Codes.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void LegacyKbd_read_codes(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink);
+ if( cmd >= 0xED ){
+ kbd->sink.onCommand = Legacykbd_scanning;
+ Legacykbd_scanning(ps2dev,cmd);
+ } else
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyKbd_read_option
+//
+// Description: Keyboard Read option.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void LegacyKbd_read_option(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink);
+ UINT8* fPtr;
+
+ kbd->sink.onCommand = Legacykbd_scanning;
+
+ if (CmdED == 1) {
+ fPtr = (UINT8*)(UINTN)0x417;
+ *fPtr &= ~0x70;
+ *fPtr |= ((cmd & 0x07) << 4);
+ CmdED = 0;
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ } else {
+ if (cmd > 0xED) {
+ Legacykbd_scanning(ps2dev,cmd);
+ } else {
+ *(kbd->option_ptr) = cmd;
+ LegacyKbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ }
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyKbd_rw_scancode
+//
+// Description: Keyboard Read write Scan code.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void LegacyKbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd )
+{
+ LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink);
+ if(cmd != 0 )
+ LegacyKbd_read_option(ps2dev,cmd);
+ else {
+ kbd->sink.onCommand = Legacykbd_scanning;
+ ScanCodePageResp[1] = kbd->scancodepage;
+ LegacyKbd_send_resp(kbd, ScanCodePageResp,COUNTOF(ScanCodePageResp));
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyKbd_send_resp
+//
+// Description: Place the Responce bytes in the keyboard buffer.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Data - Pointer to the Data
+// count - Length of the data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void LegacyKbd_send_resp(LEGACYKBD* kbd, UINT8* data, int count )
+{
+ //
+ //When there is no PS2 Keyboard present in the system, Emulation should send the responce byte for the keyboard command.
+ //If PS2 Keyboard present, it will send the responce to the KBC. So Emulation code doesn't need to responce it.
+ //
+ if(!kbd->sink.present_ ){
+ //
+ // Emulation must provide the responce. Override any previos kbd data queued to KBC
+ //
+ kbd->qtail = kbd->qhead = kbd->queue;
+ for( ; count > 0; --count ){
+ *kbd->qtail++ = *data++;
+ }
+
+ //
+ // push the first byte to the KBC
+ //
+ if( kbd->qhead != kbd->qtail &&
+ kbd->sink.kbc->send_outb1(kbd->sink.kbc,
+ PS2DEV_KBD,TRUE,*kbd->qhead))
+ {
+ if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE)
+ kbd->qhead = kbd->queue; }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyKbd_pumpQueue
+//
+// Description: KBC has empty queue; Legacy I/O trapping is being processed.If Kbd has data to push into KBC,
+// now is a good time to do it
+//
+// Input: ps2dev - pointer to the KBD structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void LegacyKbd_pumpQueue(PS2SINK* ps2dev)
+{
+ LEGACYKBD* kbd = _CR(ps2dev,LEGACYKBD,sink);
+ //
+ //send the Keyboard data to the KBC
+ //
+ if( kbd->qhead != kbd->qtail &&
+ ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_KBD,FALSE,*kbd->qhead))
+ {
+ if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE)
+ kbd->qhead = kbd->queue;
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacykbdInput_Send
+//
+// Description: Keyboard Input source sends data. Put the data into the buffer, attempt to send the first byte.
+// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden
+//
+// Input: P - pointer to the Emulation Protocol
+// Buffer - Data buffer
+// Count - Buffer Length
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LegacykbdInput_Send(EFI_EMUL6064KBDINPUT_PROTOCOL* p, UINT8* buffer, UINT32 count)
+{
+ LEGACYKBD* kbd = _CR(p,LEGACYKBD,kbdInput_);
+ UINTN c = 0;
+
+ //
+ // count of free items in the queue
+ //
+ if( kbd->qtail >= kbd->qhead )
+ c = KBDQUEUE_SIZE - (kbd->qtail - kbd->qhead);
+ else
+ c = kbd->qhead - kbd->qtail -1;
+
+ if(c < count )
+ return EFI_NOT_AVAILABLE_YET;
+
+ for( ; count > 0; --count ){
+ *kbd->qtail++ = *buffer++;
+ if(kbd->qtail >= kbd->queue+KBDQUEUE_SIZE)
+ kbd->qtail = kbd->queue;
+ }
+
+ //
+ // Disable trap to access real harware
+ //
+ TrapEnable(FALSE);
+ LegacyKbd_pumpQueue(&kbd->sink);
+ //
+ // Enable trap back and clear statuses
+ //
+ TrapEnable(TRUE);
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacykbdInput_GetTranslation
+//
+// Description: KBC translation
+//
+// Input: P - pointer to the Emulation Protocol
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LegacykbdInput_GetTranslation(
+ EFI_EMUL6064KBDINPUT_PROTOCOL* p,
+ OUT KBC_KBDTRANSLATION* outTrans )
+{
+ LEGACYKBD* kbd = _CR(p,LEGACYKBD,kbdInput_);
+ *outTrans = (kbd->sink.kbc->read_ccb(kbd->sink.kbc) & KBC_CCB_XLAT) != 0?
+ KBC_KBDTRANS_PCXT : KBC_KBDTRANS_AT;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacykbdInput_updateLED
+//
+// Description: Update the keyboard LED's
+//
+// Input: P - pointer to the Emulation Protocol
+// Data - LED data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LegacykbdInput_updateLED(
+ EFI_EMUL6064KBDINPUT_PROTOCOL* p,
+ IN UINT8 data )
+{
+ UINT8 bKBData = 0;
+ UINT8 bSave;
+
+ //
+ // Disable trap to access real harware
+ //
+ TrapEnable(FALSE);
+ //
+ // Wait for input buffer to be free
+ //
+ KBC_WaitForInputBufferToBeFree();
+ KBC_WriteCommandByte(KBCCMD_LOCK);
+ bSave = ByteReadIO(KBC_STATUS_REG);
+
+ //
+ // Data is pending. Read it in AL
+ //
+ if(bSave & KBC_STATUS_OBF)
+ {
+ bKBData = ByteReadIO(KBC_DATA_REG);
+ }
+ KBC_WriteCommandByte(0xAE);
+ KBC_WriteSubCommandByte(0xED);
+ KBC_ReadDataByte();
+ KBC_WriteSubCommandByte(data);
+ KBC_ReadDataByte();
+
+ if(bSave & KBC_STATUS_OBF){
+ KBC_WriteCommandByte(bSave & KBC_STATUS_AUXB? 0xD3: 0xD2);
+ KBC_WriteSubCommandByte(bKBData);
+ }
+ //
+ // Enable trap back and clear statuses
+ //
+ TrapEnable(TRUE);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyKbd_initParams
+//
+// Description: Initialize the KBD data
+//
+// Input: kbd - Pointer to the KBD structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void LegacyKbd_initParams(LEGACYKBD* kbd)
+{
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitLegacyKbd
+//
+// Description: Initialize the KBD data
+//
+// Input: kbc - pointer to the KBC Structure
+// kbd - Pointer to the KBD structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitLegacyKbd(KBC* kbc, LEGACYKBD* kbd )
+{
+ EFI_HANDLE hEmulationService = 0;
+ kbd->qhead = kbd->qtail = kbd->queue;
+ kbd->sink.kbc = kbc;
+ kbd->sink.onCommand = Legacykbd_scanning;
+ kbd->sink.onQueueFree = LegacyKbd_pumpQueue;
+ kbd->kbdInput_.Send = LegacykbdInput_Send;
+ kbd->kbdInput_.GetTranslation = LegacykbdInput_GetTranslation;
+ kbd->kbdInput_.UpdateLEDState = LegacykbdInput_updateLED;
+ VERIFY_EFI_ERROR(
+ gBS->InstallProtocolInterface(&hEmulationService,
+ &gEmul6064KbdInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&kbd->kbdInput_));
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/KbcEmul/VirtualKbc.c b/Core/EM/KbcEmul/VirtualKbc.c
new file mode 100644
index 0000000..23f900e
--- /dev/null
+++ b/Core/EM/KbcEmul/VirtualKbc.c
@@ -0,0 +1,639 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbc.c 14 2/11/13 12:45a Rameshr $
+//
+// $Revision: 14 $
+//
+// $Date: 2/11/13 12:45a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbc.c $
+//
+// 14 2/11/13 12:45a Rameshr
+// [TAG] EIP114926
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Write CCB command doesn't enable the keyboard interface
+// [RootCause] Data bytes are not decoded properly.
+// [Solution] Data bytes are decoded properly and device interface and
+// IRQ state values are set properly.
+// [Files] VirtualKbc.c
+//
+// 13 9/30/11 12:45a Rameshr
+// [TAG] EIP71408
+// [Category] Improvement
+// [Description] Remove the customer name reference from the
+// KbcEmulation module.
+// [Files] KbcDevEmul.h,VirtualKbc.c
+//
+// 12 2/10/11 1:06a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 11 1/19/11 4:45a Rameshr
+// [TAG] - EIP 52171
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - System gives Assert when Keyboard Reset Command issued.
+// [RootCause]- KBC Emulation Module SMI handler is using EFI Runtime
+// services for Reset() Instead of SMM RunTime Services
+// [Solution] - Smm Runtime Services used to reset the system
+// [Files] - VirtualKbc.c
+//
+// 10 7/08/10 2:01a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 9 2/10/10 7:03p Davidd
+// Corrected the USB KB stopped working in DOS after "net init" utility is
+// run - EIP 33687.
+//
+// 8 2/03/10 1:16a Rameshr
+// Install Netware6.5 SP8 Fail.
+// EIP 28411
+// Single byte and two Byte command is identified properly and handled.
+//
+// 7 12/23/09 1:31a Rameshr
+// Symptom: KbcEmulation can't install FreeBSD
+// Solution: Implemented command 0xAA (Controller self-test) and 0xAB
+// (Keyboard interface test)
+// EIP: 26451
+//
+// 6 6/30/09 11:31a Rameshr
+// Coding Standard and File header updated.
+//
+// 5 10/30/08 10:45a Rameshraju
+// Keyboard & Mouse enable/disable command handled
+//
+// 4 10/24/08 11:56a Rameshraju
+// IRQ1 or IRQ12 generated again if there is pending data.
+//
+// 3 5/01/08 10:40a Rameshraju
+// Keyboard command D2 support added
+//
+// 2 12/27/07 4:54p Rameshraju
+// KBC reset command added
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+// Name: VirtualKbc.c
+//
+// Description: Handles the Virtual KBC(Without KBC system) function
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+#include "Kbc.h"
+
+void vkbc_write_command( KBC* kbc, UINT8 cmd );
+UINT8 vkbc_read_status( KBC* kbc );
+void vkbc_write_data( KBC* kbc, UINT8 cmd );
+UINT8 vkbc_read_data( KBC* kbc );
+BOOLEAN virtkbc_sendout(KBC* kbc, PS2DEV_TYPE devtype,BOOLEAN ovrd, UINT8 data);
+void initKBC(KBC* kbc, PS2SINK* kbd, PS2SINK* mouse );
+
+//
+//Depend on the KBC command generate IRQ12
+//
+BOOLEAN MouseIrq= TRUE;
+
+//
+//Depend on the KBC command generate IRQ1
+//
+BOOLEAN KeyboardIrq= TRUE;
+
+//
+//To hold the keyboard outport Status.
+//
+UINT8 OutPortStatus= 0xDF;
+
+//
+//To hold the number of Mouse byte already send
+//
+UINT8 PacketSize=00;
+
+
+extern EFI_EMUL6064KBDINPUT_PROTOCOL *gKbdProtocol;
+
+#if IRQ_EMUL_SUPPORT
+extern GenerateIRQ12(VIRTKBC*);
+extern GenerateIRQ1(VIRTKBC*);
+#endif
+
+#if OHCI_EMUL_SUPPORT
+UINT8 GetHceStatus(void);
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbc_write_command
+//
+// Description: Handle write to command port of virtual KBC
+//
+// Input: kbc - pointer to the KBC structure
+// cmd - keyboard controller command
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbc_write_command( KBC* kbc, UINT8 cmd )
+{
+ VIRTKBC* vkbc = (VIRTKBC*)kbc;
+ VIRTMOUSE* Mouse = (VIRTMOUSE*)kbc->mouse_dev;
+ VIRTKBD* Kbd = (VIRTKBD*)kbc->kbd_dev;
+ EFI_RUNTIME_SERVICES *SmmRuntimeVar;
+ EFI_GUID SmmRsTableGuid = EFI_SMM_RUNTIME_SERVICES_TABLE_GUID;
+ UINT8 Index;
+
+ SmmRuntimeVar = NULL;
+
+ //
+ //Save the KBC command
+ //
+ vkbc->kbc_command_ = cmd;
+ vkbc->st_ |= KBC_STATUS_A2;
+ vkbc->TwoByteCmd = FALSE;
+
+ //
+ //Process the KBC command
+ //
+ switch( vkbc->kbc_command_ ){
+ case KBCCMD_READ_CCB:
+ //move ccb into the ouput buffer
+ virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,vkbc->ccb_);
+ break;
+ case KBCCMD_KBDDSBL:
+ vkbc->ccb_|=CCB_KEYBOARD_DISABLED;
+ Kbd->Enabled= FALSE;
+ break;
+ case KBCCMD_KBDENBL:
+ vkbc->ccb_&=(~CCB_KEYBOARD_DISABLED);
+ Kbd->Enabled= TRUE;
+ break;
+ case KBCCMD_AUXDSBL:
+ vkbc->ccb_|=CCB_MOUSE_DISABLED;
+ Mouse->Enabled = FALSE;
+ break;
+ case KBCCMD_AUXENBL:
+ vkbc->ccb_&=(~CCB_MOUSE_DISABLED);
+ Mouse->Enabled = TRUE;
+ break;
+ case KBCCMD_ReadOutPort:
+ virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,OutPortStatus);
+ break;
+ //
+ //Selft Test- Returns 0x55 if okay
+ //
+ case KBCCMD_SelfTest:
+ virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,KBCCMD_RES_SelfTestOk);
+ break;
+ //
+ //Returns 0x00 if okay, 0x01 if Clock line stuck low, 0x02 if clock line stuck high,
+ //0x03 if data line stuck low, and 0x04 if data line stuck high
+ //
+ case KBCCMD_CheckKbd:
+ virtkbc_sendout(kbc,PS2DEV_KBD,TRUE,KBCCMD_RES_KBInterfaceOk);
+ break;
+ //
+ //Reset the System for KBC command 0xFE
+ //
+ case KBCCMD_ResetSystem:
+
+ for (Index = 0; Index < gSmst->NumberOfTableEntries; ++Index) {
+ if (guidcmp(&gSmst->SmmConfigurationTable[Index].VendorGuid, \
+ &SmmRsTableGuid) == 0) {
+ break;
+ }
+ }
+ if (Index != gSmst->NumberOfTableEntries) {
+ SmmRuntimeVar =(EFI_RUNTIME_SERVICES *) gSmst->SmmConfigurationTable[Index].VendorTable;
+
+ }
+ if(SmmRuntimeVar){
+ SmmRuntimeVar->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+ break;
+ //
+ //Below are 2 byte commands. Next byte expected in Port 60.
+ //
+ case KBCCMD_WriteAuxDev:
+ case KBCCMD_WRITE_CCB:
+ case KBCCMD_WriteAuxBuffer:
+ case KBCCMD_WriteKbdBuffer:
+ case KBCCMD_WriteOutPort:
+ vkbc->TwoByteCmd = TRUE;
+ break;
+
+ default:
+ break;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbc_read_status
+//
+// Description: Handle read from status port of virtual KBC
+//
+// Input: kbc - pointer to the KBC structure
+//
+//
+// Output: Status - keyboard controller Status
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 vkbc_read_status( KBC* kbc )
+{
+ VIRTKBC* vkbc = (VIRTKBC*)kbc;
+
+ //
+ //If we send 1 byte of mouse already , then try to send the remaining 2 bytes of data first and process the keyboard data.
+ //
+
+ if(PacketSize >0 && PacketSize < MOUSE_PACKET_SIZE) {
+ //
+ //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev);
+ }
+
+ //
+ //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev);
+ }
+ } else {
+ //
+ //Try to process the keyboard data first.
+ //
+
+ PacketSize=0;
+ //
+ //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev);
+ }
+
+ //
+ //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev);
+ }
+ }
+
+ return vkbc->st_;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbc_write_data
+//
+// Description: Handle write to data port of virtual KBC
+//
+// Input: kbc - pointer to the KBC structure
+// Data - keyboard controller Data
+//
+// Output: Status - keyboard controller Status
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbc_write_data( KBC* kbc, UINT8 cmd )
+{
+ VIRTKBC* vkbc = (VIRTKBC*)kbc;
+ VIRTMOUSE* Mouse = (VIRTMOUSE*)kbc->mouse_dev;
+ VIRTKBD* Kbd = (VIRTKBD*)kbc->kbd_dev;
+
+ //
+ //Check that perviously we got command in port64, if yes then we got data byte for the pervious command
+ //
+ if (vkbc->TwoByteCmd) {
+ vkbc->TwoByteCmd = FALSE;
+ switch( vkbc->kbc_command_ ){
+ case KBCCMD_WriteAuxDev:
+ if(kbc->mouse_dev)
+ (*kbc->mouse_dev->onCommand)(kbc->mouse_dev,cmd);
+ vkbc->st_ |= KBC_STATUS_AUXB | KBC_STATUS_OBF;
+ break;
+ case KBCCMD_WRITE_CCB:
+ KeyboardIrq = cmd & BIT0 ? TRUE : FALSE;
+ MouseIrq = cmd & BIT1 ? TRUE : FALSE;
+ Kbd->Enabled = cmd & BIT4 ? FALSE : TRUE;
+ Mouse->Enabled = cmd & BIT5 ? FALSE : TRUE;
+ vkbc->ccb_ = cmd;
+ break;
+ case KBCCMD_WriteAuxBuffer:
+ vkbc->st_ |= KBC_STATUS_AUXB | KBC_STATUS_OBF;
+ vkbc->outb_ = cmd;
+ break;
+ case KBCCMD_WriteKbdBuffer:
+ gKbdProtocol->Send(gKbdProtocol, (UINT8 *)&cmd,1);
+ break;
+ case KBCCMD_WriteOutPort:
+ OutPortStatus=cmd;
+ break;
+ default:
+ break;
+ }
+ } else {
+ //
+ // We got data byte here and process the data byte
+ //
+ if(kbc->kbd_dev)
+ (*kbc->kbd_dev->onCommand)(kbc->kbd_dev,cmd);
+ }
+
+ //
+ //reset the command and status that command has been processed.
+ //
+ vkbc->kbc_command_ = 0;
+ vkbc->st_ &= ~KBC_STATUS_A2;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbc_read_data
+//
+// Description: Handle read from data port of virtual KBC
+//
+// Input: kbc - pointer to the KBC structure
+//
+//
+// Output: Data - Data from the keyboard controller
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 vkbc_read_data( KBC* kbc )
+{
+ VIRTKBC* vkbc = (VIRTKBC*)kbc;
+ UINT8 Data;
+
+ Data = vkbc->outb_;
+
+ if(vkbc->st_ & KBC_STATUS_OBF) {
+ //
+ //Reset the OBF flag
+ //
+ vkbc->st_ &= (~(KBC_STATUS_AUXB | KBC_STATUS_OBF));
+ }
+
+ //
+ //If we send 1 byte of mouse already , then try to send the remaining 2 bytes of data first and process the keyboard data.
+ //
+
+ if(PacketSize >0 && PacketSize < MOUSE_PACKET_SIZE) {
+
+ //
+ //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev);
+ }
+
+ //
+ //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev);
+ }
+ } else {
+ //
+ //Try to process the keyboard data first.
+ //
+
+ PacketSize=0;
+ //
+ //Check the OBF, If it's empty , check KBD queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->kbd_dev->onQueueFree)(kbc->kbd_dev);
+ }
+
+ //
+ //Check the OBF, If it's empty , check Mouse queue , if it's has the data push the data to KBC.
+ //
+ if(!(vkbc->st_ & KBC_STATUS_OBF)) {
+ (*kbc->mouse_dev->onQueueFree)(kbc->mouse_dev);
+ }
+ }
+
+ return Data;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: virtkbc_sendout
+//
+// Description: Keep the data in the output buffer and set the OBF bit set. Based on device set the status bit also.
+//
+// Input: kbc - pointer to the KBC structure
+// Devtype - Data from which device (KBD or Mouse)
+// orvd -
+// Data - Data to the kbc buffer
+//
+// Output: True: Placed the data successfully.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN virtkbc_sendout(KBC* kbc, PS2DEV_TYPE devtype,BOOLEAN ovrd, UINT8 data)
+{
+ VIRTKBC* vkbc = (VIRTKBC*)kbc;
+ VIRTKBD* Kbd = (VIRTKBD*)kbc->kbd_dev;
+
+#if OHCI_EMUL_SUPPORT
+ //
+ // Actual OBF status is maintained by the OHCI controller.
+ // Update the internal structure
+ //
+ vkbc->st_ &= (~(KBC_STATUS_OBF | KBC_STATUS_AUXB));
+ vkbc->st_ |= GetHceStatus() & (KBC_STATUS_OBF | KBC_STATUS_AUXB);
+#endif
+
+ if( vkbc->st_ & KBC_STATUS_OBF) {
+ if(vkbc->st_ & KBC_STATUS_AUXB) {
+ if(MouseIrq) {
+ #if IRQ_EMUL_SUPPORT
+ GenerateIRQ12(vkbc);
+ #endif
+ }
+ } else {
+ #if IRQ_EMUL_SUPPORT
+ GenerateIRQ1(vkbc);
+ #endif
+ }
+ //
+ //KBC already has the data.
+ //
+ return FALSE;
+ }
+ //
+ //Save the data in the KBC buffer
+ //
+ vkbc->outb_ = data;
+
+ //
+ //Set the OBF full
+ //
+ vkbc->st_ |= KBC_STATUS_OBF;
+
+#if OHCI_EMUL_SUPPORT
+ //
+ // This is the write place to do. Code flow may take IRQ disabled path or
+ // Trap6064_Handler won't get control because of USB SMI
+ //
+ SetHceOutput(data);
+#endif
+ //
+ //Set the device type ( from which device data is out)
+ //
+ if( devtype == PS2DEV_MOUSE) {
+ vkbc->st_ |= KBC_STATUS_AUXB;
+ //
+ //Generate the IRQ12, as AUX OBF is set.
+ //
+ if(MouseIrq) {
+#if IRQ_EMUL_SUPPORT
+ GenerateIRQ12(vkbc);
+#endif
+ //
+ //If the input is Mouse data, increment the Packet size, otherwise (responce byte) initlize to 0
+ //
+ if(ovrd)
+ PacketSize=0;
+ else
+ PacketSize++;
+ }
+ }else {
+ vkbc->st_ &= ~KBC_STATUS_AUXB;
+ //
+ //Generate IRQ1
+ //
+#if IRQ_EMUL_SUPPORT
+ GenerateIRQ1(vkbc);
+#endif
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbc_readCCB
+//
+// Description: Return the CCB data from the KBC buffer
+//
+// Input: kbc - pointer to the KBC structure
+//
+// Output: Data: CCB data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 vkbc_readCCB(KBC* kbc)
+{
+ VIRTKBC* vkbc = (VIRTKBC*)kbc;
+ return vkbc->ccb_;
+}
+
+//
+// Initialize KBC structure
+//
+void initKBC(KBC* kbc, PS2SINK* kbd, PS2SINK* mouse )
+{
+ kbc->mouse_dev = mouse;
+ kbc->kbd_dev = kbd;
+ kbc->sqTail[PS2DEV_KBD] = kbc->sqHead[PS2DEV_KBD] = kbc->send_queue;
+ kbc->sqTail[PS2DEV_MOUSE] = kbc->sqHead[PS2DEV_MOUSE] = kbc->send_queue_aux;
+ kbc->aux_en = KBCCMD_AUXENBL;
+ kbc->kbd_en = KBCCMD_KBDENBL;
+ kbd->present_ = TRUE;
+ kbd->presence_detected_ = FALSE;
+ mouse->presence_detected_ = FALSE;
+ mouse->present_ = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitVirtualKBC
+//
+// Description: Initialize KBC structure. Set initial state of the emulated KBC
+//
+// Input: kbc - pointer to the KBC structure
+// kbd - Pointer to the KBD structure
+// mouse - Pointer to the Mouse Structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitVirtualKBC(VIRTKBC* vkbc, PS2SINK* kbd, PS2SINK* mouse )
+{
+ initKBC(&vkbc->kbc,kbd,mouse);
+
+ //
+ //Initialize the KBC Structure
+ //
+ vkbc->kbc.kbc_write_command = vkbc_write_command;
+ vkbc->kbc.kbc_write_data = vkbc_write_data;
+ vkbc->kbc.kbc_read_status = vkbc_read_status;
+ vkbc->kbc.kbc_read_data = vkbc_read_data;
+ vkbc->kbc.send_outb1 = virtkbc_sendout;
+ vkbc->kbc.read_ccb = vkbc_readCCB;
+
+ //
+ //Initialize the CCB
+ //
+ vkbc->ccb_ = 0;
+ //
+ //Initialize the Port64 Status
+ //
+ vkbc->st_ = 0x1c;
+ //
+ //Initialize the Port64 command regsiter
+ //
+ vkbc->kbc_command_ = 0;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/VirtualKbd.c b/Core/EM/KbcEmul/VirtualKbd.c
new file mode 100644
index 0000000..48c4e35
--- /dev/null
+++ b/Core/EM/KbcEmul/VirtualKbd.c
@@ -0,0 +1,456 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbd.c 6 2/10/11 1:07a Rameshr $
+//
+// $Revision: 6 $
+//
+// $Date: 2/10/11 1:07a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualKbd.c $
+//
+// 6 2/10/11 1:07a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 5 2/19/10 3:50p Davidd
+// Corrected arrow keys not working properly during Netware 6.5
+// installation - EIP 28411
+//
+// 4 6/30/09 11:31a Rameshr
+// Coding Standard and File header updated.
+//
+// 3 10/30/08 10:47a Rameshraju
+// Keyboard & Mouse enable/disable command handled
+//
+// 2 5/01/08 10:43a Rameshraju
+// Keyboard command D2 support added
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: VirtualKbd.c
+//
+// Description: Virtual keyboard functions
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+
+#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
+
+void vkbd_initParams(VIRTKBD* kbd);
+void vkbd_read_codes(PS2SINK* ps2dev, UINT8 cmd );
+void vkbd_read_option(PS2SINK* ps2dev, UINT8 cmd );
+void vkbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd );
+void vkbd_send_resp(VIRTKBD* mouse, UINT8* data, int count );
+
+static UINT8 ackResp[] = {0xFA};
+static UINT8 ResetResp[] = {0xFA,0xAA};
+static UINT8 IdResp[] = {0xFA,0xAB, 0x41};
+static UINT8 ScanCodePageResp[] = {0xFA, 0x00};
+EFI_EMUL6064KBDINPUT_PROTOCOL *gKbdProtocol=NULL;
+static UINT8 CmdED = 0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: kbd_scanning
+//
+// Description: Handle commands sent from KBC to PS2 Keyboard. Keyboard is scanning or idle, waiting for command or key
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void kbd_scanning(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink);
+
+ switch(cmd){
+ //
+ //Reset
+ //
+ case 0xFF:
+ vkbd_initParams(kbd);
+ vkbd_send_resp(kbd, ResetResp,COUNTOF(ResetResp));
+ break;
+ case 0xFD:
+ case 0xFC:
+ case 0xFB:
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->read_code_action = cmd;
+ kbd->sink.onCommand = vkbd_read_codes;
+ break;
+ case 0xFA:
+ case 0xF9:
+ case 0xF8:
+ case 0xF7:
+ case 0xF6:
+ case 0xF5:
+ case 0xF4: //Enable
+ kbd->Enabled=TRUE;
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Typeatic Rate/Delay
+ //
+ case 0xF3:
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->sink.onCommand = vkbd_read_option;
+ kbd->option_ptr = &kbd->typematicRateDelay;
+ break;
+ case 0xF2:
+ vkbd_send_resp(kbd, IdResp,COUNTOF(IdResp));
+ break;
+ case 0xF0:
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ kbd->sink.onCommand = vkbd_rw_scancode;
+ kbd->option_ptr = &kbd->scancodepage;
+ break;
+ //
+ //Ehco
+ //
+ case 0xEE:
+ vkbd_send_resp(kbd, &cmd, 1);
+ break;
+
+ //
+ //Led
+ //
+ case 0xED:
+ vkbd_send_resp(kbd, ackResp, COUNTOF(ackResp));
+ kbd->sink.onCommand = vkbd_read_option;
+ kbd->option_ptr = &kbd->typematicRateDelay;
+ CmdED = 1;
+ break;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbd_read_codes
+//
+// Description: Keyboard Read Codes.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbd_read_codes(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink);
+ if( cmd >= 0xED ){
+ kbd->sink.onCommand = kbd_scanning;
+ kbd_scanning(ps2dev,cmd);
+ } else
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbd_read_option
+//
+// Description: Keyboard Read option.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbd_read_option(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink);
+ UINT8* fPtr;
+
+ kbd->sink.onCommand = kbd_scanning;
+
+ if (CmdED == 1) {
+ fPtr = (UINT8*)(UINTN)0x417;
+ *fPtr &= ~0x70;
+ *fPtr |= ((cmd & 0x07) << 4);
+ CmdED = 0;
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ }
+ else {
+ if (cmd > 0xED) {
+ kbd_scanning(ps2dev,cmd);
+ } else {
+ *(kbd->option_ptr) = cmd;
+ vkbd_send_resp(kbd, ackResp,COUNTOF(ackResp));
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbd_rw_scancode
+//
+// Description: Keyboard Read write Scan code.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbd_rw_scancode(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink);
+ if(cmd != 0 )
+ vkbd_read_option(ps2dev,cmd);
+ else {
+ kbd->sink.onCommand = kbd_scanning;
+ ScanCodePageResp[1] = kbd->scancodepage;
+ vkbd_send_resp(kbd, ScanCodePageResp,COUNTOF(ScanCodePageResp));
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbd_send_resp
+//
+// Description: Place the Responce bytes in the keyboard buffer.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Data - Pointer to the Data
+// count - Length of the data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbd_send_resp(VIRTKBD* kbd, UINT8* data, int count )
+{
+ if( kbd->sink.present_ ){
+ //
+ // Emulation must provide the responce. Override any pervious kbd data queued to KBC
+ //
+ kbd->qtail = kbd->qhead = kbd->queue;
+ for( ; count > 0; --count ){
+ *kbd->qtail++ = *data++;
+ }
+
+ //
+ // push the first byte to the KBC
+ //
+ if( kbd->qhead != kbd->qtail &&
+ kbd->sink.kbc->send_outb1(kbd->sink.kbc,
+ PS2DEV_KBD,TRUE,*kbd->qhead))
+ {
+ if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE)
+ kbd->qhead = kbd->queue;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbd_pumpQueue
+//
+// Description: KBC has empty queue; Legacy I/O trapping is being processed.If Kbd has data to push into KBC,
+// now is a good time to do it
+//
+// Input: ps2dev - pointer to the KBD structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void vkbd_pumpQueue(PS2SINK* ps2dev)
+{
+ VIRTKBD* kbd = _CR(ps2dev,VIRTKBD,sink);
+ //
+ //send the Keyboard data to the KBC
+ //
+ if( kbd->qhead != kbd->qtail &&
+ ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_KBD,FALSE,*kbd->qhead))
+ {
+ if(++kbd->qhead >= kbd->queue+KBDQUEUE_SIZE)
+ kbd->qhead = kbd->queue;
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: kbdInput_Send
+//
+// Description: Keyboard Input source sends data. Put the data into the buffer, attempt to send the first byte.
+// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden
+//
+// Input: P - pointer to the Emulation Protocol
+// Buffer - Data buffer
+// Count - Buffer Length
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS kbdInput_Send(EFI_EMUL6064KBDINPUT_PROTOCOL* p, UINT8* buffer, UINT32 count)
+{
+ VIRTKBD* kbd = _CR(p,VIRTKBD,kbdInput_);
+ UINTN c = 0;
+
+ //
+ //Keyboard is disabled by KBC command
+ //
+ if(!kbd->Enabled) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // count of free items in the queue
+ //
+ if( kbd->qtail >= kbd->qhead )
+ c = KBDQUEUE_SIZE - (kbd->qtail - kbd->qhead);
+ else
+ c = kbd->qhead - kbd->qtail;
+
+ if(c < count )
+ return EFI_NOT_AVAILABLE_YET;
+
+ for( ; count > 0; --count ){
+ *kbd->qtail++ = *buffer++;
+ if(kbd->qtail >= kbd->queue+KBDQUEUE_SIZE)
+ kbd->qtail = kbd->queue;
+ }
+ //
+ //Place the first data into the KBC buffer
+ //
+ vkbd_pumpQueue(&kbd->sink);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: kbdInput_GetTranslation
+//
+// Description: KBC translation
+//
+// Input: P - pointer to the Emulation Protocol
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS kbdInput_GetTranslation(
+ EFI_EMUL6064KBDINPUT_PROTOCOL* p,
+ OUT KBC_KBDTRANSLATION* outTrans )
+{
+ *outTrans=KBC_KBDTRANS_PCXT;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: kbdInput_updateLED
+//
+// Description: Update the keyboard LED's
+//
+// Input: P - pointer to the Emulation Protocol
+// Data - LED data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS kbdInput_updateLED(
+ EFI_EMUL6064KBDINPUT_PROTOCOL* p,
+ IN UINT8 data )
+{
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vkbd_initParams
+//
+// Description: Initialize the KBD data
+//
+// Input: kbd - Pointer to the KBD structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vkbd_initParams(VIRTKBD* Kbd)
+{
+ Kbd->Enabled = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitVirtualKbd
+//
+// Description: Initialize the KBD data
+//
+// Input: kbc - pointer to the KBC Structure
+// kbd - Pointer to the KBD structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitVirtualKbd(KBC* kbc, VIRTKBD* kbd )
+{
+ EFI_HANDLE hEmulationService = 0;
+ kbd->qhead = kbd->qtail = kbd->queue;
+ kbd->sink.kbc = kbc;
+ kbd->sink.onCommand = kbd_scanning;
+ kbd->sink.onQueueFree = vkbd_pumpQueue;
+ kbd->kbdInput_.Send = kbdInput_Send;
+ kbd->kbdInput_.GetTranslation = kbdInput_GetTranslation;
+ kbd->kbdInput_.UpdateLEDState = kbdInput_updateLED;
+ gKbdProtocol=&kbd->kbdInput_;
+ vkbd_initParams(kbd);
+ VERIFY_EFI_ERROR(
+ gBS->InstallProtocolInterface(&hEmulationService,
+ &gEmul6064KbdInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&kbd->kbdInput_));
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/KbcEmul/VirtualMouse.c b/Core/EM/KbcEmul/VirtualMouse.c
new file mode 100644
index 0000000..00af801
--- /dev/null
+++ b/Core/EM/KbcEmul/VirtualMouse.c
@@ -0,0 +1,553 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualMouse.c 6 3/04/14 6:19a Nimishsv $
+//
+// $Revision: 6 $
+//
+// $Date: 3/04/14 6:19a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/KbcEmulation/ALASKA/KBCEMUL/VirtualMouse.c $
+//
+// 6 3/04/14 6:19a Nimishsv
+// [TAG] EIP156041
+// [Category] Improvement
+// [Description] Aptio 4.x, KbcEmulation: Send the mouse data to EBDA
+// and only the last data through KBC
+// [Files] VirtualMouse.c
+//
+// 5 2/10/11 1:08a Rameshr
+// [TAG] EIP53687
+// [Category] Improvement
+// [Description] AMI headers update for KbcEmulation Module
+//
+// [Files] KbcEmul.mak,KbcEmul.dxs,KbcEmul.c,KbcEmul.h,KbcEmulLib.h,Kbc
+// EmulLib.c,Kbc.h,KbcDevEmul.h,Kbccore.c,Legacykbc.c,Legacykbd.c,LegacyMo
+// use.c,VirtualKbc.c,VirtualKbd.c,VirtualMouse.c,Ap4x.h,Ap4x.c,KbcUhci.c,
+// KbcUhci.h,KbcEmulIrq.c, KbcOhci.c, Kbcohci.h
+//
+// 4 7/08/10 2:02a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 3 6/30/09 11:32a Rameshr
+// Coding Standard and File header updated.
+//
+// 2 10/30/08 10:47a Rameshraju
+// Keyboard & Mouse enable/disable command handled
+//
+// 1 12/14/07 10:26a Rameshraju
+// Initial Check-in
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+// Name: VirtualMouse.c
+//
+// Description: Handles the Virtual mouse functions
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+#include "KbcEmul.h"
+#include "KbcDevEmul.h"
+
+#define COUNTOF(x) (sizeof(x)/sizeof(x[0]))
+
+static UINT8 resetResp[] = {0xFA, 0xAA, 0x00 } ;
+static UINT8 statusResp[] = {0xFA, 0x20, 0x02, 0x64 } ;
+static UINT8 dataResp[] = {0xFA, 0x08, 0x00, 0x0 } ;
+static UINT8 ackResp[] = {0xFA};
+static UINT8 idResp[] = {0xFA, 0};
+static UINT8 unknResp[] = {0xFE };
+
+void mouse_reciev_option(PS2SINK* mouse, UINT8 cmd );
+void mouse_initParams(VIRTMOUSE* mouse);
+void vmouse_flushBuffer(VIRTMOUSE* mouse);
+void vmouse_send_resp(VIRTMOUSE* mouse, UINT8* data, int count );
+void mouse_echo(PS2SINK* mouse, UINT8 cmd );
+BOOLEAN SendMouseBuffer(VIRTMOUSE* mouse, UINT8* packet, UINTN Count );
+void vmouse_pumpQueue(PS2SINK* ps2dev);
+extern GenerateIRQ12(VIRTKBC*);
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_idle
+//
+// Description: Handle commands sent from KBC to PS2 Mouse. Mouse idle, waiting for command or key
+//
+// Input: ps2dev - pointer to the Mouse structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void mouse_idle(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev;
+
+ switch(cmd){
+ //
+ //reset
+ //
+ case 0xFF:
+ mouse_initParams(mouse);
+ vmouse_send_resp(mouse, resetResp,COUNTOF(resetResp));
+ break;
+ //
+ //report status
+ //
+ case 0xE9:
+ vmouse_send_resp(mouse, statusResp,COUNTOF(statusResp));
+ break;
+ //
+ //read data
+ //
+ case 0xEB:
+ MemCpy(dataResp+1,&mouse->dataPacket,sizeof(mouse->dataPacket));
+ vmouse_flushBuffer(mouse);
+ vmouse_send_resp(mouse, dataResp,COUNTOF(dataResp));
+ break;
+ //
+ //Enable Mouse
+ //
+ case 0xF4:
+ mouse->Enabled = TRUE;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Disable Mouse
+ //
+ case 0xF5:
+ mouse->Enabled = FALSE;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Streaming
+ //
+ case 0xEA:
+ mouse->streaming = 1;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Remote
+ //
+ case 0xF0:
+ mouse->streaming = 0;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Set Standard, Set Scaling and Reset Scaling
+ //
+ case 0xF6:
+ case 0xE6:
+ case 0xE7:
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ //Identify
+ //
+ case 0xF2:
+ vmouse_send_resp(mouse, idResp,COUNTOF(idResp));
+ break;
+
+ //
+ // set resolution
+ //
+ case 0xE8:
+ mouse->option_ptr = &mouse->resolution_;
+ ps2dev->onCommand = mouse_reciev_option;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ //
+ // set sampling rate
+ //
+ case 0xF3:
+ mouse->option_ptr = &mouse->samplingRate_;
+ ps2dev->onCommand = mouse_reciev_option;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ break;
+ case 0xEE:
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ ps2dev->onCommand = mouse_echo;
+ break;
+ //
+ //unknown command; send FE
+ //
+ default:
+ vmouse_send_resp(mouse, unknResp,COUNTOF(unknResp));
+ break;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_echo
+//
+// Description: Mouse Echo command
+//
+// Input: ps2dev - pointer to the Mouse structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void mouse_echo(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev;
+ if( cmd == 0xEC ){
+ ps2dev->onCommand = mouse_idle;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+ } else
+ vmouse_send_resp(mouse, &cmd,1);
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_reciev_option
+//
+// Description: Mouse reciev command
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void mouse_reciev_option(PS2SINK* ps2dev, UINT8 cmd )
+{
+ VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev;
+ *(mouse->option_ptr) = cmd;
+ ps2dev->onCommand = mouse_idle;
+ vmouse_send_resp(mouse, ackResp,COUNTOF(ackResp));
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: msInput_Send
+//
+// Description: Mouse Input source sends data. Put the data into the buffer, attempt to send the first byte.
+// The call comes outside of Trapping Leg access. Check that Trapping status will not be overriden
+//
+// Input: P - pointer to the Emulation Protocol
+// Data - Ps2 mouse Data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI msInput_Send(
+ IN EFI_EMUL6064MSINPUT_PROTOCOL * This,
+ IN PS2MouseData* data
+ )
+{
+ VIRTMOUSE* mouse = _CR(This,VIRTMOUSE,msInput_);
+#if USB_MOUSE_UPDATE_EBDA_DATA
+ UINT16 ebdaSeg = *(UINT16*)0x40E;
+ UINT8 *ebda = (UINT8*)((UINTN)ebdaSeg<<4);
+
+ // Return EFI NOT READY if EBDA has some data.
+ // Let USB resend the data if the EBDA is not empty
+ if ( 0 != ebda[0x26] ) {
+ return EFI_NOT_READY;
+ }
+#endif
+ //
+ //clear all previous flags except overflow
+ //
+ mouse->dataPacket.flags &= (PS2MSFLAGS_XO|PS2MSFLAGS_YO);
+ //
+ //copy overflow and button flags from new packet
+ //
+ mouse->dataPacket.flags |= data->flags & ~(PS2MSFLAGS_XSIGN|PS2MSFLAGS_YSIGN);
+ mouse->dataPacket.flags |= 0x8;
+ if( (mouse->dataPacket.flags & PS2MSFLAGS_XO) == 0){
+ if(data->flags & PS2MSFLAGS_XSIGN){
+ mouse->x += (signed short)((UINT8)data->x | 0xFF00);
+ } else {
+ mouse->x += data->x;
+ }
+ mouse->dataPacket.x = (UINT8)(UINT32)(mouse->x);
+ if( mouse->x < 0 ){
+ mouse->dataPacket.flags |= PS2MSFLAGS_XSIGN;
+ if( mouse->x < -256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_XO;
+ } else {
+ if( mouse->x > 256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_XO;
+ }
+ }
+
+ if( (mouse->dataPacket.flags & PS2MSFLAGS_YO) == 0){
+ if(data->flags & PS2MSFLAGS_YSIGN){
+ mouse->y += (signed short)((UINT8)data->y | 0xFF00);
+ } else {
+ mouse->y += data->y;
+ }
+ mouse->dataPacket.y = (UINT8)(UINT32)(mouse->y);
+ if( mouse->y < 0 ){
+ mouse->dataPacket.flags |= PS2MSFLAGS_YSIGN;
+ if( mouse->y < -256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_YO;
+ } else{
+ if( mouse->y > 256 )
+ mouse->dataPacket.flags |= PS2MSFLAGS_YO;
+ }
+ }
+
+ mouse->fFreshPacket = 1;
+ if( mouse->Enabled && mouse->streaming ){
+ if( SendMouseBuffer(mouse,(UINT8*)&mouse->dataPacket,sizeof(mouse->dataPacket)))
+ {
+ vmouse_flushBuffer(mouse);
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SendMouseBuffer
+//
+// Description: Send the mouse packet to KBC
+//
+// Input: Mouse - pointer to the Mouse Structure
+// Packetr - Mouse Data
+// Count - Data Length
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SendMouseBuffer(VIRTMOUSE* mouse, UINT8* packet, UINTN Count )
+{
+ UINTN FreeQueue = 0;
+#if USB_MOUSE_UPDATE_EBDA_DATA
+ UINT16 ebdaSeg = *(UINT16*)0x40E;
+ UINT8 *ebda = (UINT8*)((UINTN)ebdaSeg<<4);
+ UINT8 packageSize = ebda[0x27] & 7;
+ UINT8 index=0;
+#endif
+ //
+ // count of free items in the queue
+ //
+ if( mouse->qtail >= mouse->qhead )
+ FreeQueue = MOUSEQUEUE_SIZE - (mouse->qtail - mouse->qhead);
+ else
+ FreeQueue = mouse->qhead - mouse->qtail;
+
+ if(FreeQueue < Count )
+ return TRUE;
+
+ //
+ //place the Mouse data in mouse buffer
+ //
+ for( ; Count > 0; --Count ){
+ *mouse->qtail++ = *packet++;
+ if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qtail = mouse->queue;
+ }
+
+ //
+ //Place the dummy 4th byte in mouse buffer,
+ //
+// *mouse->qtail++ = 0;
+// if(mouse->qtail >= mouse->queue+MOUSEQUEUE_SIZE)
+// mouse->qtail = mouse->queue;
+
+#if USB_MOUSE_UPDATE_EBDA_DATA
+ // Write the 1st two bytes of mouse packet to EBDA and last byte to KBC
+ for (; index<=packageSize; index++) {
+ if (index == 0) {
+ ebda[0x28+index] = *mouse->qhead;
+ ebda[0x26]++;
+ if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qhead = mouse->queue;
+ }
+ if (index == 1) {
+ ebda[0x28+index] = *mouse->qhead;
+ ebda[0x26]++;
+ if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qhead = mouse->queue;
+ }
+ if (index == 2) {
+ vmouse_pumpQueue(&mouse->sink);
+ }
+ }
+#else
+ //Put the first byte in the KBC buffer
+ vmouse_pumpQueue(&mouse->sink);
+#endif
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vmouse_pumpQueue
+//
+// Description: KBC has empty queue; Legacy I/O trapping is being processed.If mouse has data to push into KBC,
+// now is a good time to do it
+//
+// Input: ps2dev - pointer to the Mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vmouse_pumpQueue(PS2SINK* ps2dev)
+{
+ VIRTMOUSE* mouse = (VIRTMOUSE*)ps2dev;
+
+ //
+ //Put the data into KBC
+ //
+ if((mouse->qhead != mouse->qtail) && (ps2dev->kbc->send_outb1(ps2dev->kbc,PS2DEV_MOUSE,FALSE,*mouse->qhead))) {
+ if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qhead = mouse->queue;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vmouse_send_resp
+//
+// Description: Place the Response bytes in the keyboard buffer.
+//
+// Input: Mousev - pointer to the Mouse structure
+// Data - Pointer to the Data
+// count - Length of the data
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vmouse_send_resp(VIRTMOUSE* mouse, UINT8* data, int count )
+{
+ if(mouse->sink.present_ ){
+ //
+ // Emulation must provide the response. Override any previos mouse data queued to KBC
+ //
+ mouse->qtail = mouse->qhead = mouse->queue;
+ for( ; count > 0; --count ){
+ *mouse->qtail++ = *data++;
+ }
+
+ ///
+ // push the first byte to the KBC
+ //
+ if( mouse->qhead != mouse->qtail &&
+ mouse->sink.kbc->send_outb1(mouse->sink.kbc,
+ PS2DEV_MOUSE,TRUE,*mouse->qhead))
+ {
+ if(++mouse->qhead >= mouse->queue+MOUSEQUEUE_SIZE)
+ mouse->qhead = mouse->queue; }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: vmouse_flushBuffer
+//
+// Description: Clear the mouse data buffer that tracks the mouse changes; after the data is cleared any data read
+// will return zero (x,y) and current buttons state.
+//
+// Input: ps2dev - pointer to the KBD structure
+// Cmd - Data from the kbc buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void vmouse_flushBuffer(VIRTMOUSE* mouse)
+{
+ mouse->x = mouse->y = 0;
+ mouse->dataPacket.x = mouse->dataPacket.y = 0;
+ mouse->dataPacket.flags &= (PS2MSFLAGS_LBUTTON|PS2MSFLAGS_RBUTTON);
+ mouse->fFreshPacket = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: mouse_initParams
+//
+// Description: Initialize the mouse data
+//
+// Input: kbd - Pointer to the mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void mouse_initParams(VIRTMOUSE* mouse)
+{
+ mouse->samplingRate_ = 0x64;
+ mouse->resolution_ = 2;
+ mouse->option_ptr = 0;
+ mouse->Enabled = FALSE;
+ mouse->streaming = 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitVirtualMouse
+//
+// Description: Initialize the Mouse data
+//
+// Input: kbc - pointer to the KBC Structure
+// Mouse - Pointer to the Mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void InitVirtualMouse(KBC* kbc, VIRTMOUSE* mouse )
+{
+ EFI_HANDLE hEmulationService = 0;
+
+ mouse->qhead = mouse->qtail = mouse->queue;
+ mouse->sink.kbc = kbc;
+ mouse->sink.onCommand = mouse_idle;
+ mouse->sink.onQueueFree = vmouse_pumpQueue;
+ mouse->msInput_.Send = msInput_Send;
+ mouse->x = mouse->y = 0;
+ mouse->dataPacket.flags = 0x8;
+ mouse->dataPacket.x = 0;
+ mouse->dataPacket.y = 0;
+ mouse->fFreshPacket = 0;
+ mouse_initParams(mouse);
+ VERIFY_EFI_ERROR(
+ gBS->InstallProtocolInterface(&hEmulationService,
+ &gEmul6064MsInputProtocolGuid,EFI_NATIVE_INTERFACE,(void*)&mouse->msInput_));
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/NVRAM/NVRAM.chm b/Core/EM/NVRAM/NVRAM.chm
new file mode 100644
index 0000000..19c9c5b
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAM.chm
Binary files differ
diff --git a/Core/EM/NVRAM/NVRAM.cif b/Core/EM/NVRAM/NVRAM.cif
new file mode 100644
index 0000000..b17adef
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAM.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "NVRAM"
+ category = ModulePart
+ LocalRoot = "Core\EM\NVRAM\"
+ RefName = "NVRAM"
+[files]
+"NVRAM.chm"
+"NVRAM.sdl"
+"NVRAM.mak"
+"NVRAM.h"
+"NVRAMRead.c"
+"NVRAMPEI.c"
+"NVRAMDXE.c"
+<endComponent>
diff --git a/Core/EM/NVRAM/NVRAM.h b/Core/EM/NVRAM/NVRAM.h
new file mode 100644
index 0000000..a7a892b
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAM.h
@@ -0,0 +1,490 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAM.h 28 11/29/12 5:10p Felixp $
+//
+// $Revision: 28 $
+//
+// $Date: 11/29/12 5:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAM.h $
+//
+// 28 11/29/12 5:10p Felixp
+// Minor improvement: Since UEFI Specification versions prior to 2.1
+// (0x2000A) are no longer supported,
+// all the "#if EFI_SPECIFICATION_VERSION >= 0x2000A" conditional
+// compilation statements are removed.
+// Files modified: NVRAM.h, NVRAMRead.c, NVRAMDXE.c
+//
+// 27 11/29/12 3:27p Felixp
+// Nvram.h, NvramDxe.c:
+// 1. Bug Fix (EIP106441): The Authenticated Variable SCT test was
+// failing due to a
+// bug in UpdateVariable function. The function was skipping the
+// update if new variable data
+// is equal to the old variable data. The update should not be skipped
+// in case of the append operation
+// (when EFI_VARIABLE_APPEND_WRITE attribute is set).
+// The function is updated accordingly.
+// 2. Bug fix: External declaration for the FlashEmpty variable declared
+// variable type as UINT32,
+// even though the variable is defined in Tokenc.c as UINTN.
+//
+// 26 11/07/12 4:13p Oleksiyy
+// [TAG] EIP99114
+// [Category] New Feature
+// [Description] Please make state of "Runtime" variable used in
+// NvramDxe.c globally available
+// [Files] NVRAM.h and NVRAMDXE.c
+//
+// 25 7/13/11 9:24a Justinj
+// [TAG] EIP62762
+// [Category] Improvement
+// [Description] Optimize NVRAM cache index so that the entire linked
+// list is not walked every time a variable is set or retrieved.
+// [Files] NVRAM.h
+// NVRAMRead.c
+// NVRAMDXE.c
+//
+// 24 5/13/11 5:44p Artems
+// Added CheckStore function definition
+//
+// 23 5/13/11 5:22p Artems
+// Minor code beautification change
+//
+// 22 5/11/11 6:34p Oleksiyy
+// [TAG] EIP60206
+// [Category] Improvement
+// [Description] Authenticated Variables improvement.
+// NV_CACHE_SUPPORT == O support added.
+// [Files] NVRAMDXE.c and NVRAM.h
+//
+// 21 5/09/11 11:04a Artems
+// Minor code beautification change
+//
+// 19 9/30/10 4:35p Oleksiyy
+// Issue Number: 40356 and 39462
+//
+// Category: New Feature
+//
+// Description: Support for EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+// Small fix of previously checked in code.
+//
+// Files: NVRAM. h, NVRAMRead.c, NVRAMDXE.c
+//
+// 18 9/22/10 6:39p Felixp
+// Enhancement(EIP 39462 and EIP 40356):
+// Support of the authenticated update of the NVRAM variables
+// as described in UEFI specification version 2.1 and above.
+// NOTE: The actual authentication is performed by the external SecureMod
+// eModule,
+// which must be in the proejct to use this feature.
+//
+// 17 12/04/09 12:27p Felixp
+// NvarEqNvar function is added
+//
+// 16 11/23/09 4:44p Felixp
+// Code to validate NVRAM header fields used by the NVRAM driver is added.
+// If problem is found, the header fields are updated with the correct
+// values.
+//
+// 15 11/20/09 4:06p Felixp
+// NVRAM driver is updated to support UEFI2.1
+// EFI_VARIABLE_HARDWARE_ERROR_RECORD attribue.
+//
+// 14 8/25/09 4:11p Felixp
+// NVRAM Record Checksum Support(EIP 23825) is added.
+// Disabled by default. Enable using NVRAM_RECORD_CHECKSUM_SUPPORT SDL
+// token.
+//
+// 13 6/26/09 3:28p Felixp
+//
+// 12 6/26/09 3:27p Felixp
+// New IsMainNvramStoreValid function is added.
+// The function detects is main NVRAM or backup NVRAM is currently active
+// (returns FALSE when backup is active).
+//
+// 11 10/09/08 11:47a Felixp
+// 1. Fault tolerant NVRAM garbage collection support is added.
+// Use FAULT_TOLERANT_NVRAM_UPDATE SDL token to enable/disable (disabled
+// by default).
+// NOTE: This feature requires upgrade of the Board module.
+// NOTE: This feature requires porting:
+// Fault tolerant update requires reserved flash area of size NVRAM_SIZE
+// used for back up during NVRAM garbage collection.
+// The address of the area is defined by NVRAM_BACKUP_ADDRESS SDL token
+// defined in Board.sdl.
+// Size and Base addresses of other firmware volumes may need to be
+// adjusted to free up space for the NVRAM back up area.
+// Default ROM layout expects NVRAM back up area immediately below the
+// main NVRAM area.
+// For projects with the customized ROM layout Core.mak has to be updated.
+// 2. Top level NVRAM function updated to be reentrance-safe.
+// NOTE: This feature requires upgrade of the SB module.
+// 3. Improved recovery from the flash programming failures and
+// corruptions within NVRAM area.
+// 4. More reliable non-fault tolerant garbage collection.
+//
+// 10 9/06/07 12:14a Felixp
+//
+// 9 8/31/07 3:44p Felixp
+// NVRAM code has been significantly changed to introduce the following
+// improvements:
+// 1. The code is chaned to always use the same amount of memory.
+// Previous implementation allocated memory as needed, which caused
+// occasional S4 problems.
+// Plus S4 resume never worked during the very first boot after the
+// firmware update.
+// 2. Support for NVRAM defaults added.
+// NVRAM image with the default values for the Setup variables is now
+// generated by the build process.
+// The image is generated by the HpkTool (included into AMITSE module
+// part).
+// In addition to standard Setup defaults it is also possible
+// to generate manufactoring defaults. Support for the manufactoring
+// defaults
+// is disabled by default and can be enabled using
+// MANUFACTURING_MODE_SUPPORT SDL token.
+// 3. Support for boot with alternative configurations is added.
+// Decision to switch to the alternative configuration
+// (alternative set of values for NVRAM variables)
+// is based on values returned by the porintg routine in OemPort.c.
+// During boot with alternative configurations GetVariable service
+// returns alternative values for the setup-related variables.
+// If variable does not have an alternative value, current value is
+// returned.
+// Two alternative configurations are supported:
+// Boot with manufactoring settings(activated when IsMfgMode routine in
+// OemPort.c returns TRUE).
+// Boot with default settings(activated when IsDefaultConfigMode routine
+// in OemPort.c returns TRUE).
+// NOTE: This feature requires of the Board module
+// 4.NVRAM reset option is added.
+// If porting routine IsResetConfigMode in OemPort.c returns TRUE in PEI
+// phase,
+// NVRAM content will be reset during initialization of the DXE NVRAM
+// driver.
+// During reset operation all setup-related variables are reset to their
+// default values.
+// All other variables are deleted.
+// NOTE: This feature requires upgrade of the Board module
+// 5.Detection of NVRAM update added.
+// NVRAM implementation detects if NVRAM has been updated since the last
+// NVRAM call.
+// This provides ability to use variables services before and after
+// firmware update.
+// 6.Overall code clean up and simplification.
+// 7.Core Sources are no longer required in order to use NV_SIMULATION
+// option.
+// 8.PI 1.0 support.
+// Support for a PI 1.0 complient variable PPI is added. Old PPI is still
+// preserved in this label for backward compatibility.
+// New library routines PeiGetVariable and PeiGetNextVariableName are
+// created in order to hide the differences between two PPIs.
+// It is recommended to update existing code to use new library routines.
+// Support of the old PPI may be dropped in the future versions of Core.
+// 9. NVRAM is now packaged as a raw FFS file embedded into the standard
+// FV (used to be non-standard FV with raw NVRAM image).
+// Validation: New NVRAM code has been validated using SCT and EFI version
+// of Windows Server 2008
+// Files modified: Core.sdl, Core.mak, AmiPeiLib.h, PeiLib.c,
+// ReadOnlyVariable.h, , Token.c, HpkTool.exe, AMITSE.mak, Setup.ini,
+// NVRAM.sdl, NVRAM.mak, NVRAM.h, NVRAMRead.c, NVRAMPEI.c,
+// NVRAMDXE.c
+//
+// 8 5/01/07 6:06p Felixp
+// Clean up
+//
+// 7 3/18/07 4:08p Felixp
+// 1. IsNvramBlock function declaration added
+// 2. Clean up
+//
+// 6 12/29/06 3:02p Felixp
+// Update to use new flash interface
+//
+// 5 12/20/06 1:33p Felixp
+// Bug fix in BLOCK macro
+//
+// 4 10/27/06 11:45a Felixp
+//
+// 3 10/27/06 10:42a Felixp
+// Bug fixes for correct work in Virtual Address Space.
+//
+// 2 10/23/06 7:03p Felixp
+// 1. Virtual address space fixup of the global variables added
+// 2. NVRAM simulation support
+//
+// 1 8/24/06 12:38p Felixp
+//
+// 4 3/22/05 9:51p Felixp
+// sAmiRomFile added
+//
+// 3 3/22/05 8:59p Felixp
+// FlashSize variable added
+//
+// 2 3/04/05 9:40a Mandal
+//
+// 1 1/28/05 12:44p Felixp
+//
+// 3 1/20/05 11:37a Felixp
+// Component restructurized to support release in binary format
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/27/04 4:08p Felixp
+//
+// 8 12/09/04 9:02p Felixp
+// minor iprovements
+//
+// 7 8/28/04 1:49a Felixp
+// NVRAM Routines fixes
+//
+//
+// 1 3/29/04 2:32a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NVRAM.h
+//
+// Description: NVRAM Definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __NVRAM__H__
+#define __NVRAM__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <AmiLib.h>
+#include <Flash.h>
+#include <Hob.h>
+#include <Ffs.h>
+
+#define FLASH_EMPTY_BYTE ((UINT8)FlashEmpty)
+#define FLASH_EMPTY_FLAG FLASH_EMPTY_BYTE
+#define FLASH_EMPTY_NEXT FlashEmptyNext
+#define FLASH_EMPTY_SIGNATURE ((UINT32)FlashEmpty)
+#define FLASH_EMPTY_SIZE ((VAR_SIZE_TYPE)FlashEmpty)
+
+#define NVRAM_FLAG_VALID 0x80
+#define NVRAM_FLAG_RUNTIME 1
+#define NVRAM_FLAG_ASCII_NAME 2
+#define NVRAM_FLAG_GUID 4
+#define NVRAM_FLAG_DATA_ONLY 8
+#define NVRAM_FLAG_EXT_HEDER 0x10
+#define NVRAM_FLAG_AUTH_WRITE 0x40
+#define NVRAM_FLAG_HARDWARE_ERROR_RECORD 0x20
+#define UEFI21_SPECIFIC_NVRAM_FLAGS (NVRAM_FLAG_HARDWARE_ERROR_RECORD | NVRAM_FLAG_AUTH_WRITE)
+#define UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES \
+ (EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
+
+#define NVRAM_EXT_FLAG_CHECKSUM 1
+
+#define NVRAM_eFLAG_AUTH_WRITE EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS //0x10
+#define NVRAM_eFLAG_TIME_BASED_AUTH_WRITE EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS //0x20
+
+#define ALL_FLAGS (NVRAM_FLAG_VALID | NVRAM_FLAG_RUNTIME |\
+ NVRAM_FLAG_ASCII_NAME | NVRAM_FLAG_GUID|\
+ NVRAM_FLAG_DATA_ONLY | NVRAM_FLAG_EXT_HEDER|\
+ UEFI21_SPECIFIC_NVRAM_FLAGS\
+ )
+
+#define NVAR_SIGNATURE ('N'+('V'<<8)+(('A'+('R'<<8))<<16))//NVAR
+
+// {C0EC00FD-C2F8-4e47-90EF-9C8155285BEC}
+#define NVRAM_HOB_GUID \
+ { 0xc0ec00fd, 0xc2f8, 0x4e47, { 0x90, 0xef, 0x9c, 0x81, 0x55, 0x28, 0x5b, 0xec } }
+
+#define NVRAM_MODE_MANUFACTORING 1
+#define NVRAM_MODE_RESET_CONFIGURATION 2
+#define NVRAM_MODE_DEFAULT_CONFIGURATION 4
+#define NVRAM_MODE_SIMULATION 8
+
+#define NVRAM_STORE_FLAG_NON_VALATILE 1
+#define NVRAM_STORE_FLAG_READ_ONLY 2
+#define NVRAM_STORE_FLAG_DO_NOT_ENUMERATE 4
+
+extern const UINTN FlashEmpty;
+extern const UINT32 FlashEmptyNext;
+extern const EFI_GUID AmiDefaultsVariableGuid;
+extern const EFI_GUID AmiNvramHobGuid;
+extern const CHAR16 MfgDefaults[];
+extern const CHAR16 StdDefaults[];
+extern const UINT32 NvramHeaderLength;
+
+typedef UINT16 VAR_SIZE_TYPE;
+#define NEXT_OFFSET (EFI_FIELD_OFFSET(NVAR,size)+sizeof(VAR_SIZE_TYPE))
+#define NEXT_SIZE 3
+#define FLAG_SIZE 1
+#define FLAG_OFFSET (NEXT_OFFSET + NEXT_SIZE)
+#define MAX_NVRAM_VARIABLE_SIZE ((1<<(sizeof(VAR_SIZE_TYPE)<<3))-1)
+#pragma pack(push)
+#pragma pack(1)
+typedef struct{
+ UINT32 signature;
+ VAR_SIZE_TYPE size;
+ UINT32 next:24;
+ UINT32 flags:8;
+// guid and name are there only if NVRAM_FLAG_DATA_ONLY is not set
+// UINT8 guid;
+// CHAR8 or CHAR16 name[...];
+// UINT8 data[...];
+// if NVRAM_FLAG_EXT_HEDER is set
+// UINT8 extflags;
+// UINT8 extdata[...];
+// VAR_SIZE_TYPE extsize;
+}NVAR;
+
+typedef struct {
+ EFI_HOB_GUID_TYPE Header;
+ EFI_PHYSICAL_ADDRESS NvramAddress;
+ EFI_PHYSICAL_ADDRESS BackupAddress;
+ UINT32 NvramSize;
+ UINT32 HeaderLength;
+ UINT32 NvramMode;
+} NVRAM_HOB;
+#pragma pack(pop)
+
+typedef struct {
+ UINT8 *NvramAddress;
+ UINTN NvramSize;
+ EFI_GUID* NvramGuidsAddress;
+ UINT8 *pEndOfVars, *pFirstVar;
+ INT16 NextGuid;
+ VAR_SIZE_TYPE LastVarSize;
+ NVAR *pLastReturned;
+ UINT8 Flags;
+} NVRAM_STORE_INFO;
+
+//Low level access routines
+EFI_GUID* NvGetGuid(NVAR* pVar, NVRAM_STORE_INFO *pInfo);
+VOID* NvGetName(NVAR* pVar);
+NVAR* NvGetDataNvar(NVAR *pVar, NVRAM_STORE_INFO *pInfo);
+VOID* NvGetData(NVAR* pVar, UINTN NameLength, UINTN* pDataSize, NVRAM_STORE_INFO *pInfo);
+
+//Validation routines
+BOOLEAN NvIsVariable(NVAR *pVar, NVRAM_STORE_INFO *pInfo);
+BOOLEAN NvIsValid(NVAR* pVar);
+
+//Iteration routines
+NVAR* NvGetNextNvar(NVAR* pVar, NVRAM_STORE_INFO *pInfo);
+NVAR* NvGetNextValid(NVAR* pVar, NVRAM_STORE_INFO *pInfo);
+
+//Comparison routines
+BOOLEAN NvAttribEq(NVAR* pNvar, UINT32 Attributes, NVRAM_STORE_INFO *pInfo);
+BOOLEAN NvVarEq(NVAR* pNvar, CHAR16* sName, EFI_GUID* pGuid, UINTN* pNameSize, NVRAM_STORE_INFO *pInfo);
+BOOLEAN NvarEqNvar(NVAR *Nvar1, NVRAM_STORE_INFO *Info1, NVAR *Nvar2, NVRAM_STORE_INFO *Info2);
+
+//High level routines that work with a single NV store
+VOID* NvFindVariable(CHAR16* sName, EFI_GUID* pGuid, UINTN* pNameSize, NVRAM_STORE_INFO *pInfo);
+EFI_STATUS NvGetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ NVRAM_STORE_INFO *pInfo, OUT NVAR **Var OPTIONAL
+);
+EFI_STATUS NvGetNextVariableName(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ NVRAM_STORE_INFO *pInfo, BOOLEAN Runtime
+);
+
+//High level routines that work with a multiple NV stores
+EFI_STATUS NvGetVariable2(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ UINT32 InfoCount, NVRAM_STORE_INFO *pInfo
+);
+EFI_STATUS NvGetNextVariableName2(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ UINT32 InfoCount, NVRAM_STORE_INFO *pInfo, UINT32 *LastInfoIndex,
+ BOOLEAN Runtime
+);
+
+//Service routines
+VOID NvInitInfoBuffer(IN NVRAM_STORE_INFO *pInfo, UINTN HeaderSize, UINT8 Flags);
+NVRAM_STORE_INFO* NvGetDefaultsInfo(
+ IN const CHAR16* DefaultsVar,
+ IN NVRAM_STORE_INFO *pInInfo, OUT NVRAM_STORE_INFO *pOutInfo
+);
+EFI_STATUS NvGetAttributesFromNvar(
+ IN NVAR *pNvar, IN NVRAM_STORE_INFO *pInfo,
+ OUT UINT32 *Attributes
+);
+EFI_STATUS NvGetVariableFromNvar(
+ NVAR *pNvar, UINTN NameSize, OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ IN NVRAM_STORE_INFO *pInfo, OUT UINT8 *Flags OPTIONAL
+);
+EFI_FFS_FILE_STATE* GetNvramFfsFileStatePtr(NVRAM_STORE_INFO *Info);
+EFI_FFS_FILE_STATE GetNvramFfsFileState(NVRAM_STORE_INFO *Info);
+BOOLEAN IsMainNvramStoreValid(
+ NVRAM_STORE_INFO *MainInfo, VOID *BackUpAddress,
+ BOOLEAN *BackupStoreValid
+);
+
+UINT8 NvCalculateNvarChecksum(NVAR* pVar);
+UINT8* NvGetExtFlags (NVAR* pVar);
+
+// Shared with AuthVariable service
+typedef struct {
+ UINT8 AuthFlags; // AuthWriteAccess = 0x10 and TimeWriteAccess = 0x20
+ UINT64 Mc;
+ UINT8 KeyHash[32]; // sha256
+}EXT_SEC_FLAGS;
+
+VOID
+GetVarAuthExtFlags(
+ IN NVAR *Var,
+ IN NVRAM_STORE_INFO *pInfo,
+ OUT EXT_SEC_FLAGS *ExtFlags
+);
+
+EFI_STATUS FindVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes ,
+ IN OUT UINTN *DataSize, OUT VOID **Data
+);
+
+VOID CheckStore(
+ IN BOOLEAN Recover
+);
+
+BOOLEAN IsNvramRuntime();
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/NVRAM/NVRAM.mak b/Core/EM/NVRAM/NVRAM.mak
new file mode 100644
index 0000000..43d544b
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAM.mak
@@ -0,0 +1,225 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAM.mak 12 1/14/14 5:45p Oleksiyy $
+#
+# $Revision: 12 $
+#
+# $Date: 1/14/14 5:45p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAM.mak $
+#
+# 12 1/14/14 5:45p Oleksiyy
+# [TAG] EIP121524
+# [Category] New Feature
+# [Description] Extended Aptio functionality for clearing or restoring
+# NVRAM to factory default state (preserving only selected Vars).
+# [Files] NVRAM.sdl
+# NVRAM.mak
+# NVRAMDXE.c
+# NVRAM.cif
+#
+# 11 11/07/12 5:42p Oleksiyy
+# [TAG] EIP98678
+# [Category] Improvement
+# [Description] GetVariable() response slow. Added token to process
+# only SetVariable through SMI.
+# [Files] NvramSmi.c, NvramSmi.sdl and NVRAM.mak
+#
+# 10 11/11/11 3:23p Felixp
+# Set DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME macro when NvramSmi
+# eModule is in the project.
+#
+# 9 2/04/10 3:58p Felixp
+# Hook eLinks are renamed
+#
+# 8 2/02/10 5:14p Oleksiyy
+# EIP 33263 : Hooks for SetVariable, GetVariable and GetNextVarName
+# added
+#
+# 7 5/01/09 6:13p Felixp
+# Bug fix(EIP 19816). $(AMICSPLib) is no longer linked with NVRAM
+# libraries.
+# (it caused problems on systems without Core Sources).
+# $(AMICSPLib) is linked with Runtime and CORE_PEI instead.
+#
+# 6 10/09/08 11:47a Felixp
+# 1. Fault tolerant NVRAM garbage collection support is added.
+# Use FAULT_TOLERANT_NVRAM_UPDATE SDL token to enable/disable (disabled
+# by default).
+# NOTE: This feature requires upgrade of the Board module.
+# NOTE: This feature requires porting:
+# Fault tolerant update requires reserved flash area of size NVRAM_SIZE
+# used for back up during NVRAM garbage collection.
+# The address of the area is defined by NVRAM_BACKUP_ADDRESS SDL token
+# defined in Board.sdl.
+# Size and Base addresses of other firmware volumes may need to be
+# adjusted to free up space for the NVRAM back up area.
+# Default ROM layout expects NVRAM back up area immediately below the
+# main NVRAM area.
+# For projects with the customized ROM layout Core.mak has to be updated.
+# 2. Top level NVRAM function updated to be reentrance-safe.
+# NOTE: This feature requires upgrade of the SB module.
+# 3. Improved recovery from the flash programming failures and
+# corruptions within NVRAM area.
+# 4. More reliable non-fault tolerant garbage collection.
+#
+# 5 9/06/07 12:14a Felixp
+#
+# 4 8/31/07 3:44p Felixp
+# NVRAM code has been significantly changed to introduce the following
+# improvements:
+# 1. The code is chaned to always use the same amount of memory.
+# Previous implementation allocated memory as needed, which caused
+# occasional S4 problems.
+# Plus S4 resume never worked during the very first boot after the
+# firmware update.
+# 2. Support for NVRAM defaults added.
+# NVRAM image with the default values for the Setup variables is now
+# generated by the build process.
+# The image is generated by the HpkTool (included into AMITSE module
+# part).
+# In addition to standard Setup defaults it is also possible
+# to generate manufactoring defaults. Support for the manufactoring
+# defaults
+# is disabled by default and can be enabled using
+# MANUFACTURING_MODE_SUPPORT SDL token.
+# 3. Support for boot with alternative configurations is added.
+# Decision to switch to the alternative configuration
+# (alternative set of values for NVRAM variables)
+# is based on values returned by the porintg routine in OemPort.c.
+# During boot with alternative configurations GetVariable service
+# returns alternative values for the setup-related variables.
+# If variable does not have an alternative value, current value is
+# returned.
+# Two alternative configurations are supported:
+# Boot with manufactoring settings(activated when IsMfgMode routine in
+# OemPort.c returns TRUE).
+# Boot with default settings(activated when IsDefaultConfigMode routine
+# in OemPort.c returns TRUE).
+# NOTE: This feature requires of the Board module
+# 4.NVRAM reset option is added.
+# If porting routine IsResetConfigMode in OemPort.c returns TRUE in PEI
+# phase,
+# NVRAM content will be reset during initialization of the DXE NVRAM
+# driver.
+# During reset operation all setup-related variables are reset to their
+# default values.
+# All other variables are deleted.
+# NOTE: This feature requires upgrade of the Board module
+# 5.Detection of NVRAM update added.
+# NVRAM implementation detects if NVRAM has been updated since the last
+# NVRAM call.
+# This provides ability to use variables services before and after
+# firmware update.
+# 6.Overall code clean up and simplification.
+# 7.Core Sources are no longer required in order to use NV_SIMULATION
+# option.
+# 8.PI 1.0 support.
+# Support for a PI 1.0 complient variable PPI is added. Old PPI is still
+# preserved in this label for backward compatibility.
+# New library routines PeiGetVariable and PeiGetNextVariableName are
+# created in order to hide the differences between two PPIs.
+# It is recommended to update existing code to use new library routines.
+# Support of the old PPI may be dropped in the future versions of Core.
+# 9. NVRAM is now packaged as a raw FFS file embedded into the standard
+# FV (used to be non-standard FV with raw NVRAM image).
+# Validation: New NVRAM code has been validated using SCT and EFI version
+# of Windows Server 2008
+# Files modified: Core.sdl, Core.mak, AmiPeiLib.h, PeiLib.c,
+# ReadOnlyVariable.h, , Token.c, HpkTool.exe, AMITSE.mak, Setup.ini,
+# NVRAM.sdl, NVRAM.mak, NVRAM.h, NVRAMRead.c, NVRAMPEI.c,
+# NVRAMDXE.c
+#
+# 3 10/13/06 1:27a Felixp
+#
+# 2 8/25/06 10:59a Felixp
+#
+# 1 8/24/06 12:38p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: NVRAM.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : NvramPei NvramDxe
+
+NVRAM_PEI_OBJECTS=\
+$$(BUILD_DIR)\$(NVRAM_DIR)\NVRAMRead.obj\
+$$(BUILD_DIR)\$(NVRAM_DIR)\NVRAMPEI.obj
+
+NVRAM_DXE_OBJECTS=\
+$$(BUILD_DIR)\$(NVRAM_DIR)\NVRAMRead.obj\
+$$(BUILD_DIR)\$(NVRAM_DIR)\NVRAMDXE.obj
+
+$(BUILD_DIR)\NVRAM.mak : $(NVRAM_DIR)\$(@B).cif $(NVRAM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(NVRAM_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+Runtime_LIBBin : $(BUILD_DIR)\NVRAMDXE.lib
+CORE_PEI_LIBBin : $(BUILD_DIR)\NVRAMPEI.lib
+
+$(BUILD_DIR)\NVRAMDXE.lib : NvramDxe
+$(BUILD_DIR)\NVRAMPEI.lib : NvramPei
+
+NvramDxe : $(BUILD_DIR)\NVRAM.mak NvramDxeBin
+NvramPei : $(BUILD_DIR)\NVRAM.mak NvramPeiBin
+
+NvramDxeBin :
+ $(ECHO) #define NVRAM_PRESERVE_VARIABLES_LIST $(NvramPreserveVariables) > $(BUILD_DIR)\NvramPreserveList.h
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NVRAM.mak all\
+ "OBJECTS=$(NVRAM_DXE_OBJECTS)"\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h\
+ $(BUILD_DIR)\NvramPreserveList.h" \
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\NVRAMDXE.lib\
+ "MY_DEFINES=/D\"GET_VAR_LIST=$(GetVariableHook)\"\
+ /D\"GET_NEXT_VAR_NAME_LIST=$(GetNextVariableNameHook)\"\
+!IF "$(NvramSmiSupport)"=="1" && "$(NVRAM_SMI_FULL_PROTECTION)"=="1"
+ /D\"DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME=1\"\
+!ENDIF
+ /D\"SET_VAR_LIST=$(SetVariableHook)\""
+
+NvramPeiBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NVRAM.mak all\
+!IF "$(x64_BUILD)"=="1"
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+!ELSE
+ BUILD_DIR=$(BUILD_DIR)\
+!ENDIF
+ "OBJECTS=$(NVRAM_PEI_OBJECTS)"\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(BUILD_DIR)\NVRAMPEI.lib\
+ "MY_DEFINES=/D\"PEI_GET_VAR_LIST=$(PeiGetVariableHook)\"\
+ /D\"PEI_GET_NEXT_VAR_NAME_LIST=$(PeiGetNextVariableNameHook)\""
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/NVRAM/NVRAM.sdl b/Core/EM/NVRAM/NVRAM.sdl
new file mode 100644
index 0000000..e7a9214
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAM.sdl
@@ -0,0 +1,65 @@
+TOKEN
+ Name = "NVRAM_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable NVRAM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "NVRAM_DIR"
+End
+
+MODULE
+ Help = "Includes NVRAM.mak to Project"
+ File = "NVRAM.mak"
+End
+
+ELINK
+ Name = "GetVariableHook"
+ Help = "Called before GetVariable"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "GetNextVariableNameHook"
+ Help = "Called before GetNextVariableName"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SetVariableHook"
+ Help = "Called before SetVariable"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiGetVariableHook"
+ Help = "Called before GetVariable in PEI"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiGetNextVariableNameHook"
+ Help = "Called before GetNextVariableName in PEI"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "NvramPreserveVariables"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = '{L"Setup", { 0xEC87D643, 0xEBA4, 0x4BB5, 0xA1, 0xE5, 0x3F, 0x3E, 0x36, 0xB2, 0x0D, 0xA9 }},'
+ Parent = "NvramPreserveVariables"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = '{L"AMITSESetup", { 0xc811fa38, 0x42c8, 0x4579, 0xa9, 0xbb, 0x60, 0xe9, 0x4e, 0xdd, 0xfb, 0x34 }},'
+ Parent = "NvramPreserveVariables"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/NVRAM/NVRAMDXE.c b/Core/EM/NVRAM/NVRAMDXE.c
new file mode 100644
index 0000000..ef43629
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAMDXE.c
@@ -0,0 +1,5719 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMDXE.c 117 6/11/14 3:12p Oleksiyy $
+//
+// $Revision: 117 $
+//
+// $Date: 6/11/14 3:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMDXE.c $
+//
+// 117 6/11/14 3:12p Oleksiyy
+// [TAG] EIP173026
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] With AMITSE 2.17.1245 windows 8.1 (UEFI) does not install
+// [RootCause] GetNextVariableName was in certain cases returning name
+// and GUID of a boot time variable
+// [Solution] Variable name and GUID of a boot time variable X were
+// returned at runtime under the following conditions:
+// - The variable X was present in the default var.store and not
+// present in the main var.store
+// - The variable immediately before variable X in the default
+// var.store was present in the main var.store
+// The default var.store is a var.store generated at build time that
+// contains default values for all setup variables
+// (variables associated with setup controls).
+// The main var.store is the main NVRAM area. Variable is added into a
+// main var.store when somebody
+// calls SetVariable.
+// [Files] NVRAMRead.c
+// NVRAMDXE.c
+// NVRAM.cif
+//
+// 116 3/28/14 5:25p Oleksiyy
+// [TAG] EIP159166
+// [Category] Improvement
+// [Description] Set Auth Variable behaivour when AuthVariable_SUPPORT
+// is not present in project made up to speck.
+// [Files] NVRAMDXE.c
+//
+// 115 3/28/14 3:01p Oleksiyy
+// [TAG] EIP159166
+// [Category] Improvement
+// [Description] When SetVariable is called with gEfiGlobalVariableGuid
+// and Variable Name, which is not in the list of Efi Global Variables,
+// EFI_INVALID_PARAMETER must be returned according to recent changes to
+// UEFI spec.
+// [Files] NVRAMDXE.c
+//
+// 114 3/10/14 4:46p Oleksiyy
+// [TAG] EIP156697
+// [Category] Improvement
+// [Description] Multiple copies of the same variable through
+// GetNextVariableName resolved for Default and Manufactoring modes.
+// [Files] NVRAMDXE.c
+//
+// 113 3/05/14 4:41p Oleksiyy
+// [TAG] EIP154299
+// [Category] Improvement
+// [Description] Integer + heap potential overflow in SetVariable
+// patched.
+// [Files] NVRAMDXE.c
+//
+// 112 1/30/14 10:57a Oleksiyy
+// [TAG] EIP148909
+// [Category] Improvement
+// [Description] Variable creation on Default Configuration fixed.
+// [Files] NVRAMDXE.c
+//
+// 111 1/14/14 5:45p Oleksiyy
+// [TAG] EIP121524
+// [Category] New Feature
+// [Description] Extended Aptio functionality for clearing or restoring
+// NVRAM to factory default state (preserving only selected Vars).
+// [Files] NVRAM.sdl
+// NVRAM.mak
+// NVRAMDXE.c
+// NVRAM.cif
+//
+// 110 9/24/13 4:42p Oleksiyy
+// [TAG] EIP132754
+// [Category] Improvement
+// [Description] Removing #ifdef statement as unnecessary.
+// [Files] NVRAMDXE.c
+//
+// 109 8/28/13 6:46p Oleksiyy
+// [TAG] EIP132754
+// [Category] Improvement
+// [Description] NVRAM modifications for Legacy2Efi module. Sequrity
+// update.
+// [Files] NVRAMDXE.c
+//
+// 108 8/27/13 7:45p Oleksiyy
+// [TAG] EIP129423
+// [Category] Improvement
+// [Description] Setup items behaviour on first and second boot unified.
+// [Files] NVRAMDXE.c
+//
+// 107 8/15/13 12:38p Oleksiyy
+// [TAG] EIP132754
+// [Category] New Feature
+// [Description] NVRAM modifications for Legacy2Efi module
+// [Files] NVRAMDXE.c
+//
+// 106 2/22/13 4:42p Oleksiyy
+// [TAG] EIP115154
+// [Category] Improvement
+// [Description] System hangs or resets when all SetVariable calls
+// fails.
+// Do not return EFI_OUT_OF_RESOURCES if Mailbox failed to save.
+//
+// [Files] NVRAMDXE.c
+//
+// 105 1/04/13 5:40p Felixp
+// Code clean up: redundant if statements are consolidated.
+//
+// 104 1/04/13 10:40a Felixp
+// [TAG] EIP109422
+// [Category] Improvement
+// [Description] Issues found by CppCheck in NVRAM Module part
+// InstallNvramControlSmmProtocol call that has been accidently
+// deleted by previous check in is restored.
+//
+// 103 12/13/12 6:16p Oleksiyy
+// [TAG] EIP109422
+// [Category] Improvement
+// [Description] Issues found by CppCheck in NVRAM Module part
+// [Files] NVRAMDXE.c and NVRAMPEI.c
+//
+// 102 12/13/12 6:12p Felixp
+// [TAG] EIP103562
+// [Category] New Feature
+// [Description] A mechanism to preserve non-runtime (NV+BS) variables
+// across firmware update.
+// This feature is required to support
+// item 29 of the System.Fundamentals.Firmware.UEFISecureBoot WIN8 Logo
+// requirement.
+// [Files] NvramDxe.c, SMIFlashLinks.c
+//
+// 101 11/29/12 5:10p Felixp
+// Minor improvement: Since UEFI Specification versions prior to 2.1
+// (0x2000A) are no longer supported,
+// all the "#if EFI_SPECIFICATION_VERSION >= 0x2000A" conditional
+// compilation statements are removed.
+// Files modified: NVRAM.h, NVRAMRead.c, NVRAMDXE.c
+//
+// 100 11/29/12 4:20p Felixp
+// [TAG] EIP106617
+// [Category] Bug Fix
+// [Symptom] BeginCriticalSection/EndCriticalSection primitives are not
+// really thread safe
+// [RootCause] The main problem with the previous implementation was
+// that the Critical Section object ("cs") itself was not
+// also protected by the critical section, meaning that code must not
+// write to this object when interrupts are
+// enabled.
+// If BeginCriticalSection() is interrupted before the "Busy" flag is set,
+// and the interrupt handler attempts to
+// re-enter the critical section, interrupt masks and SMI enable state
+// will become permanently corrupted.
+// Likewise, if EndCriticalSection is interrupted at the wrong time, the
+// saved interrupt masks and SMI enable
+// state will be overwritten by the interrupt handler re- entering the
+// critical section.
+// [Solution] By introducing a local temp context, the problem is
+// completely solved.
+// [Files] NvramDxe.c
+//
+// 99 11/29/12 3:41p Felixp
+// IsStoreOk bug fix (introduced by previous check in)
+//
+// 98 11/29/12 3:27p Felixp
+// Nvram.h, NvramDxe.c:
+// 1. Bug Fix (EIP106441): The Authenticated Variable SCT test was
+// failing due to a
+// bug in UpdateVariable function. The function was skipping the
+// update if new variable data
+// is equal to the old variable data. The update should not be skipped
+// in case of the append operation
+// (when EFI_VARIABLE_APPEND_WRITE attribute is set).
+// The function is updated accordingly.
+// 2. Bug fix: External declaration for the FlashEmpty variable declared
+// variable type as UINT32,
+// even though the variable is defined in Tokenc.c as UINTN.
+//
+// 97 11/07/12 4:15p Oleksiyy
+// [TAG] EIP99114
+// [Category] New Feature
+// [Description] Please make state of "Runtime" variable used in
+// NvramDxe.c globally available
+// [Files] 99114
+//
+// 96 9/18/12 10:57a Felixp
+// [TAG] EIP91311
+// [Category] Bug Fix
+// [Symptom] The variable defaults are missing at runtime when NvramSmi
+// module is used.
+// [RootCause] The defaults variable store data structure where not
+// updated with the new buffer address.
+// It was still pointing to the old address.
+// [Solution] ReallocateHybridVarstoreToSmm function is updated to fix
+// the main NVRAM store and all the nested variable stores.
+// [Files] NvramDxe.c
+//
+// 95 6/06/12 3:46p Oleksiyy
+// [TAG] EIP88436
+// [Category] Improvement
+// [Description] Windows 8 feature test UEFI PXE Boot - System hangs.
+// [Files] NVRAMDXE.c
+//
+// 94 5/25/12 4:33p Felixp
+// [TAG] EIP88550
+// [Category] Bug Fix
+// [Symptom] On Rose City label 17, sometimes setup entry is very slow
+// [RootCause] The system occasionally became very slow during start up
+// of the setup client.
+// The problem was caused missynchronization of the global data used by
+// NVRAM DXE and NVRAM SMM drivers.
+//
+// [Solution] The code is updated to make sure NvramMailBox data is up
+// to date at the time of NVRAM SMM driver initialization.
+// [Files] NvramDxe.c
+//
+// 93 5/22/12 6:00p Oleksiyy
+// [TAG] EIP90318
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail, improper variable MonotonicCounter in
+// NVRAM module
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c and NVRAMDXE.c
+//
+// 92 3/22/12 5:31p Oleksiyy
+// [TAG] EIP85222
+// [Category] Improvement
+// [Description] NVRAM hooks needs virtualization
+// [Files] NVRAMDXE.c
+//
+// 91 3/20/12 10:43a Felixp
+// [TAG] EIP85396
+// [Category] Bug Fix
+// [Symptom] Loading SETUP defaults using IsResetConfigMode()
+// [RootCause] The NVRAM reset happens very early in the NVRAM driver
+// initialization process.
+// The hybrid interface functions, used during NVRAM reset,
+// were accessing global data that has not yet been initialized.
+// [Solution] The NVRAM reset is now performed using direct flash access
+// (without hybrid interface).
+// The hybrid interface is initialized after the NVRAM reset.
+//
+// 90 3/13/12 10:29a Felixp
+// Bug fix in HybridGetAddressDelta:
+// Symptoms: The system was hanging during initialization of the NVRAM DXE
+// driver
+// when NVRAM FV header was corrupted.
+// Details: NvramInitialize detects FV header corruption and calls
+// NvResetConfiguration to fix it.
+// NvResetConfiguration call other functions and control eventually goes
+// to HybridGetAddressDelta,
+// which didn't work properly since it used VarStoreInfo global data
+// structure that had not been initialized yet.
+// HybridGetAddressDelta is updated to work properly before VarStoreInfo
+// has been initialized.
+//
+// 89 3/03/12 2:48p Felixp
+// Bug fixes in DxeSetVariable:
+// Return EFI_INVALID parameter when:
+// - Illegal attribute bits are set
+// - Boot time variable is being set at runtime
+//
+// 88 2/22/12 4:07p Oleksiyy
+// [TAG] EIP83723
+// [Category] Improvement
+// [Description] Review commnts from EIP 82122 applied.
+// [Files] NVRAMDXE.c
+//
+// 87 2/17/12 6:27p Oleksiyy
+// [TAG] EIP82122
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] "Secure Boot Manual Logo Test" fails
+// [RootCause] If Garbage Collection happens during append operation -
+// after garbage collection previous data will be lost after GC.
+// [Solution] Append after Garbage collection treated in special way.
+// [Files] NVRAMDXE.c
+//
+// 86 1/30/12 2:17p Felixp
+// [TAG] EIP81531
+// [Category] Bug Fix
+// [Symptom] ASSERT in debug mode during boot with default configuration
+// [RootCause] HybridGetAddressDelta() checks bounds against the wrong
+// NVRAM region
+// [Solution] HybridGetAddressDelta() is updated to use NvInfo pointer
+// instead of NvramInfo
+//
+// 85 11/11/11 3:19p Felixp
+// 1.Performance of the NVRAM driver has been improved by creation of the
+// in-memory cache of the
+// NVRAM data (older code accessed ROM directly). The feature can be
+// disabled by commenting out
+// definition of the HYBRID_NV_INTERFACE macro in NvramDxe.c
+// 2. Support for isolation of the SMM NVRAM services at runtime (no data
+// access outside of SMM).
+// The isolation of the SMM NVRAM driver implies migration of the NVRAM
+// API into SMM. The DXE
+// portion of the NVRAM driver is getting shut down. It is replaced by
+// the NvramSmi driver (external
+// eModule; not part of the Core) that redirects NVRAM calls into SMM.
+// The feature should be used
+// when flash part is locked at runtime. The support is automatically
+// enabled when NvramSmi module
+// is in the project (by defining
+// DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME macro).
+//
+// 84 7/13/11 9:24a Justinj
+// [TAG] EIP62762
+// [Category] Improvement
+// [Description] Optimize NVRAM cache index so that the entire linked
+// list is not walked every time a variable is set or retrieved.
+// [Files] NVRAM.h
+// NVRAMRead.c
+// NVRAMDXE.c
+//
+// 83 7/08/11 3:31p Oleksiyy
+// [TAG] EIP64390
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Repetitive SetVariables calls cause UEFI OS crash
+// [RootCause] When NVRAM_RT_GARBAGE_COLLECTION_SUPPORT is off,
+// CopyVarStoreToMemStore does not do anything (immediately returns error)
+// but SelectiveFree was still trying to free memory at uninitialized
+// address (NewInfo.NvramAddress is not initialized).
+//
+// [Solution] Added check for Rintime before going to BS.
+// [Files] NVRAMDXE.c
+//
+// 82 6/16/11 10:23a Artems
+// Bugfix in authenticated variable support
+//
+// 81 6/16/11 8:58a Felixp
+// Bug fix in the IndexInit function: VarIndexPtr->BufferSize was not
+// initialized.
+//
+// 80 6/13/11 6:42p Artems
+// Added changes to support Authenticated Variable
+//
+// 79 5/11/11 6:33p Oleksiyy
+// [TAG] EIP60206
+// [Category] Improvement
+// [Description] Authenticated Variables improvement.
+// NV_CACHE_SUPPORT == O support added.
+// [Files] NVRAMDXE.c and NVRAM.h
+//
+// 78 5/06/11 6:15p Oleksiyy
+// [TAG] EIP53253
+// [Category] Improvement
+// [Description] To comply with UEFI 2.3.1
+// EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS and
+// EFI_VARIABLE_APPEND_WRITE attributes handling added.
+// [Files] NVRAM.h, NVRAMRead.c and NVRAMDXE.c
+//
+// 77 3/09/11 6:18p Artems
+// Undo previous changes, as they are unnecessary since SCT fixed bug on
+// their side
+//
+// 76 2/25/11 3:01p Artems
+// EIP 53749: SCT variable test fails. Here included partial fix. SCT uses
+// wrong guid
+// in its test - this part not included in generic source and available as
+// patch for sole purpose
+// of passing SCT test
+//
+// 75 2/11/11 11:08a Artems
+//
+// 74 2/02/11 3:09p Oleksiyy
+// [TAG] EIP42253
+// [Category] Improvement
+// [Description] Convert Flash Pointer added.
+// [Files] NVRAMDXE.c
+//
+// 73 1/25/11 12:46p Oleksiyy
+// [TAG] EIP42253
+// [Category] New Feature
+// [Description] Added support for platforms, where flash part is not
+// memory mapped while write enabled, controlled by
+// NO_MMIO_FLASH_ACCESS_DURING_UPDATE sdl token. Flash protocol used to
+// access flash in that case.
+// [Files] NVRAMDXE.c, Flash.c, Tokens.c and Runtime.sdl
+//
+// 72 1/19/11 6:04p Oleksiyy
+// [TAG] EIP52517
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NVRAM inconsistency when updating Setup first time in 32
+// bit mode
+// [RootCause] DxeSetVariable function in NVRAMDXE.c passes wrong
+// Interface to UpdateVariable.
+// [Solution] DxeSetVariable function in NVRAMDXE.c modified.
+// [Files] NVRAMDXE.c
+//
+// 71 11/17/10 12:04p Oleksiyy
+// [TAG] EIP39460
+// [Category] New Feature
+// [Description] Runtime Garbage Collection potential bug fix.
+// Initialization of Mailbox updated.
+// [Files] NVRAMDXE.c
+//
+// 70 11/11/10 7:40a Felixp
+// Bug fix: updated to compile in UEFI 2.0 mode.
+//
+// 69 11/08/10 5:58p Felixp
+// Bug fixes in the RT Garbage Collection Support implementation
+// (EIP39460).
+//
+// 68 11/08/10 5:29p Felixp
+// Depdency from SecureMod_SUPPORT SDL token is removed
+//
+// 67 11/08/10 5:23p Felixp
+// Bug fixes in the Runtime Garbage Collection Support implementation (EIP
+// 39460).
+//
+// 66 11/05/10 2:14p Felixp
+// Bug Fix in QueryVariableInfo.
+// QueryVariableInfo was always reporting MaximumVariableSize of 8 bytes.
+//
+// 65 9/30/10 4:53p Oleksiyy
+// Issue Number: 45053
+//
+// Category: Improvement
+//
+// Description: If update on Next field in NVAR failed, the NVRAM
+// recovery was not triggered. Problem fix now.
+//
+// Files: NVRAMDXE.c
+//
+// 64 9/30/10 4:38p Oleksiyy
+// Issue Number: 40356 and 39462
+//
+// Category: New Feature
+//
+// Description: Support for EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+// Small fix of previously checked in code.
+//
+// Files: NVRAM. h, NVRAMRead.c, NVRAMDXE.c
+//
+// 63 9/24/10 8:00a Felixp
+// Minor bug fix in initialization of NvramCs variable
+//
+// 62 9/24/10 7:57a Felixp
+// Improvement( EIP 40257):
+// BeginCriticalSection/EndCriticalSection are updated to enable/disable
+// interrupts using
+// PIC interrupt mask registers (ports 0x21 and oxa1) instead of just
+// setting the CPU interrupt flag (CLI/STI).
+//
+// 61 9/22/10 6:39p Felixp
+// Enhancement(EIP 39462 and EIP 40356):
+// Support of the authenticated update of the NVRAM variables
+// as described in UEFI specification version 2.1 and above.
+// NOTE: The actual authentication is performed by the external SecureMod
+// eModule,
+// which must be in the proejct to use this feature.
+//
+// 60 9/22/10 5:47p Felixp
+// Enhancement(EIP 39460): Runtime Garbage Collection Support.
+// (controlled by the NVRAM_RT_GARBAGE_COLLECTION_SUPPORT SDL token ).
+//
+// 59 6/30/10 4:32p Felixp
+//
+// 58 6/30/10 2:19p Felixp
+// Switching to simulation in recovery modue is disabled.
+//
+// 57 4/26/10 2:56p Felixp
+//
+// 56 4/26/10 11:57a Felixp
+// Clean up of the trace messages.
+//
+// 55 4/23/10 5:32p Felixp
+// 1. NVRAM Reset Policy is updated.
+// Don't reset configuration if defaults are not available.
+// Restore defaults is they disappeared from the NVRAM.
+// 2. Turn on NVRAM simulation in Recovery mode (to protect main FV before
+// main BIOS is updated)
+//
+// 54 4/22/10 11:50p Felixp
+// Bug fix in the NvramInitialize. NvResetConfiguration after the
+// DxeIsNvramCompatible was called with the wrong argument.
+// This caused problems when fault tolerant NVRAM update was enabled.
+//
+// 53 4/22/10 11:47p Felixp
+// EnumerateStore function is updated to skip incomplete
+// NVAR record (if any) at the end of the NVRAM data area.
+//
+// 52 3/05/10 11:52a Felixp
+// Bug fix:
+// Symptoms: When FAULT_TOLERANT_NVRAM_UPDATE is enabled,
+// UEFI Windows crashes with blue screen 1E during start up.
+// Details: The VarStoreInfo.BackupAddress was not virtualized during
+// virtual mode transition.
+//
+// 51 2/02/10 5:16p Oleksiyy
+// EIP 33263 : Hooks for SetVariable, GetVariable and GetNextVarName
+// added
+//
+// 50 12/04/09 12:29p Felixp
+// NvarEqNvar moved to NvramRead.c
+//
+// 49 11/24/09 4:40p Felixp
+// Minor bug fixes
+//
+// 48 11/23/09 11:00p Felixp
+//
+// 47 11/23/09 4:44p Felixp
+// Code to validate NVRAM header fields used by the NVRAM driver is added.
+// If problem is found, the header fields are updated with the correct
+// values.
+//
+// 46 11/20/09 4:06p Felixp
+// NVRAM driver is updated to support UEFI2.1
+// EFI_VARIABLE_HARDWARE_ERROR_RECORD attribue.
+//
+// 45 11/20/09 9:27a Felixp
+// NVRAM record corruption check is added to IndexFindVariable and
+// IndexUpdateVariable functions.
+//
+// 44 8/25/09 4:11p Felixp
+// NVRAM Record Checksum Support(EIP 23825) is added.
+// Disabled by default. Enable using NVRAM_RECORD_CHECKSUM_SUPPORT SDL
+// token.
+//
+// 43 7/30/09 3:38p Felixp
+// Bug fix:
+// Symptoms: systems were occasionally hanging during first boot after
+// flashing,
+// when SetVariable call from SMM was followed by the GetVariable call
+// from outside of SMM.
+// Details: VarIndex data structure updated to save varstore indexes
+// within VarStoreInfo.NvramInfo
+// instead of pointers to varstore information (pointers cannot be used
+// because VarIndex information is used by both SMM and non-SMM NVRAM
+// services,
+// which have independent copies of VarStoreInfo global variable).
+//
+// 42 7/10/09 8:53a Felixp
+//
+// 41 7/10/09 8:51a Felixp
+// New NVRAM_MONOTONIC_COUNTER_SUPPORT SDL token is created. The token can
+// be used
+// to disable Core NVRAM-based implementation of the monotonic counter
+// architectural protocol and
+// to use stand alone monotonic counter driver instead.
+// Code clean up; comments and function header added.
+//
+// 40 6/26/09 3:33p Felixp
+// Bug fix (EIP 23329):
+// 1. CheckStore function: Auto detect active NVRAM area (main or backup)
+// before NVRAM access.
+// 2. DxeSetVariable: Bug fix in parameter validation
+// 3. Additional debug messages added
+//
+// 39 5/21/09 5:38p Felixp
+// 1. Reset NVRAM content to defaults (loaded from FFS file in FV_MAIN or
+// other FV)
+// if it has been corrupted during failed BIOS update.
+// 2. Validate compatibility of the NVRAM content using external hook
+// (DxeIsNvramDataCompatible).
+// It NVRAM content is incompatible, reset it to defaults
+// (loaded from FFS file in FV_MAIN or other FV).
+//
+// 38 5/14/09 9:36a Felixp
+// New feature: SMM version of Runtime Services
+// NVRAM driver is updated to populate SMM runtime table
+// with the pointers to SMM version of variable services.
+//
+// 37 5/04/09 2:26p Felixp
+//
+// 36 5/04/09 11:24a Felixp
+// Make sure code compiles with NV_CACHE_SUPPORT set to zero
+//
+// 35 5/04/09 11:07a Felixp
+// Bug fix. NVRAM DXE will crash if defaults are reset on first boot(EIP
+// 20149).
+// Symptoms: If TRUE is returned by IsResetConfig() on the first boot
+// after a fresh flash, system hangs in the NVRAM DXE driver.
+// Function updated: IndexReset
+//
+// 34 3/23/09 2:20p Felixp
+// Bug fix: EIP 20442.
+// Symptoms: USB mass storage device is sometimes missing from the BBS
+// popup menu
+// when F12 is pressed continuously on USB keyboard.
+// Details: the problem was caused by the fact that timer interrupt
+// handler was running with SMI disabled.
+// BeginCriticalSection/EndCriticalSection updated to enable SMI's
+// before interrupts.
+// The change provides support for interrupt handlers depending upon
+// processing performed by the SMI handler
+//
+// 33 1/02/09 2:19p Felixp
+// Improved handling of the variables with default values.
+// When variable is deleted, return EFI_WRITE_PROTECTED instead of
+// EFI_NOT_FOUND
+// if only default value (which can not be deleted) exists.
+// When volatile variable is created, return EFI_INVALID_PARAMETER if
+// default value exists
+// (If default value exists, the variable is non volatile. Attributes
+// for existing variable can not be changed).
+//
+// 32 11/21/08 2:13p Felixp
+// Bug fix in IsClean routine.
+//
+// 31 11/20/08 6:17p Felixp
+// Bug fin in CreateVariable (proper handling of the GUID index overflow).
+//
+// 30 11/20/08 2:23p Felixp
+// Bug fix in the NextGuid detection logic within EnumerateStore routine.
+//
+// 29 10/17/08 9:40a Felixp
+// Bug fix in IndexUpdateVariable (caused blue screen during UEFI Vista
+// installation).
+//
+// 28 10/09/08 11:47a Felixp
+// 1. Fault tolerant NVRAM garbage collection support is added.
+// Use FAULT_TOLERANT_NVRAM_UPDATE SDL token to enable/disable (disabled
+// by default).
+// NOTE: This feature requires upgrade of the Board module.
+// NOTE: This feature requires porting:
+// Fault tolerant update requires reserved flash area of size NVRAM_SIZE
+// used for back up during NVRAM garbage collection.
+// The address of the area is defined by NVRAM_BACKUP_ADDRESS SDL token
+// defined in Board.sdl.
+// Size and Base addresses of other firmware volumes may need to be
+// adjusted to free up space for the NVRAM back up area.
+// Default ROM layout expects NVRAM back up area immediately below the
+// main NVRAM area.
+// For projects with the customized ROM layout Core.mak has to be updated.
+// 2. Top level NVRAM function updated to be reentrance-safe.
+// NOTE: This feature requires upgrade of the SB module.
+// 3. Improved recovery from the flash programming failures and
+// corruptions within NVRAM area.
+// 4. More reliable non-fault tolerant garbage collection.
+//
+// 27 8/01/08 3:23p Felixp
+// Bug fix in UpdateVariable routine (Index was not properly updated if
+// NvCompact happened in the UpdateVariable)
+//
+// 26 7/14/08 3:16p Felixp
+//
+// 25 7/08/08 5:31p Felixp
+// Don't do NvCompact at runtime
+//
+// 24 4/21/08 11:32p Felixp
+// Bug fix in the NVRAM corruption recovery logic
+//
+// 23 3/12/08 2:52p Felixp
+// Error code reporting when flash update failed added
+//
+// 22 2/19/08 11:11p Felixp
+// 1. NvProgram updated: code added to verify if data have been programmed
+// correctly
+// 2. Minor bug fix in NvCompact
+// 3. CreateVariable/UpdateVariable updated with the code that handles
+// failed flash write operations
+// 4. Bug fix in DxeSetVariable: during boot with default configuration,
+// current value was not properly updated
+// 5. Update in init routine VarStoreDiscovery: during boot with default
+// configuration, main NVRAM store is also exposed. This is needed to
+// provide current value for variables without defaults.
+//
+// 21 11/07/07 3:09p Felixp
+// Bug fixes:
+// 1. GetVariable/SetVariable crashed or returned EFI_NOT_FOUND after
+// ExitBootServices and before SetVartualAddressMap
+// 2. During first boot or boot with default values updated value of the
+// variable did not show up until system reset (GetVariable was returning
+// old value)
+//
+// 20 10/15/07 3:00p Felixp
+// Bug fix in NvramInitialize: defaults were ignored in simulation mode.
+//
+// 19 10/12/07 3:06p Felixp
+// Bug fix(EIP issue 10480): NVRAM initialization routine is updated to
+// properly handle NV simulation.
+//
+// 18 9/13/07 10:18a Felixp
+// Bug fix in DxeNvramInit routine.
+// NVRAM area descriptor was not properly reinitialized
+// during calls to DxeNvramInit with ResetVolatileStore set FALSE
+//
+// 17 9/06/07 12:14a Felixp
+//
+// 16 8/31/07 3:44p Felixp
+// NVRAM code has been significantly changed to introduce the following
+// improvements:
+// 1. The code is chaned to always use the same amount of memory.
+// Previous implementation allocated memory as needed, which caused
+// occasional S4 problems.
+// Plus S4 resume never worked during the very first boot after the
+// firmware update.
+// 2. Support for NVRAM defaults added.
+// NVRAM image with the default values for the Setup variables is now
+// generated by the build process.
+// The image is generated by the HpkTool (included into AMITSE module
+// part).
+// In addition to standard Setup defaults it is also possible
+// to generate manufactoring defaults. Support for the manufactoring
+// defaults
+// is disabled by default and can be enabled using
+// MANUFACTURING_MODE_SUPPORT SDL token.
+// 3. Support for boot with alternative configurations is added.
+// Decision to switch to the alternative configuration
+// (alternative set of values for NVRAM variables)
+// is based on values returned by the porintg routine in OemPort.c.
+// During boot with alternative configurations GetVariable service
+// returns alternative values for the setup-related variables.
+// If variable does not have an alternative value, current value is
+// returned.
+// Two alternative configurations are supported:
+// Boot with manufactoring settings(activated when IsMfgMode routine in
+// OemPort.c returns TRUE).
+// Boot with default settings(activated when IsDefaultConfigMode routine
+// in OemPort.c returns TRUE).
+// NOTE: This feature requires of the Board module
+// 4.NVRAM reset option is added.
+// If porting routine IsResetConfigMode in OemPort.c returns TRUE in PEI
+// phase,
+// NVRAM content will be reset during initialization of the DXE NVRAM
+// driver.
+// During reset operation all setup-related variables are reset to their
+// default values.
+// All other variables are deleted.
+// NOTE: This feature requires upgrade of the Board module
+// 5.Detection of NVRAM update added.
+// NVRAM implementation detects if NVRAM has been updated since the last
+// NVRAM call.
+// This provides ability to use variables services before and after
+// firmware update.
+// 6.Overall code clean up and simplification.
+// 7.Core Sources are no longer required in order to use NV_SIMULATION
+// option.
+// 8.PI 1.0 support.
+// Support for a PI 1.0 complient variable PPI is added. Old PPI is still
+// preserved in this label for backward compatibility.
+// New library routines PeiGetVariable and PeiGetNextVariableName are
+// created in order to hide the differences between two PPIs.
+// It is recommended to update existing code to use new library routines.
+// Support of the old PPI may be dropped in the future versions of Core.
+// 9. NVRAM is now packaged as a raw FFS file embedded into the standard
+// FV (used to be non-standard FV with raw NVRAM image).
+// Validation: New NVRAM code has been validated using SCT and EFI version
+// of Windows Server 2008
+// Files modified: Core.sdl, Core.mak, AmiPeiLib.h, PeiLib.c,
+// ReadOnlyVariable.h, , Token.c, HpkTool.exe, AMITSE.mak, Setup.ini,
+// NVRAM.sdl, NVRAM.mak, NVRAM.h, NVRAMRead.c, NVRAMPEI.c,
+// NVRAMDXE.c
+//
+// 15 8/07/07 2:42p Felixp
+// Additional Status Codes added
+//
+// 14 4/25/07 6:02p Felixp
+// MemSetVariable improvements: don't do memory deallocation/allocation
+// when variable is updated with the data of the same size.
+//
+// 13 3/29/07 1:06p Felixp
+// SCT workarounds removed (the issues have been fixed in the new version
+// of SCT).
+//
+// 12 12/29/06 3:02p Felixp
+// Update to use new flash interface
+//
+// 11 12/19/06 12:39p Felixp
+// Bug fixes in Variable Services
+//
+// 10 12/18/06 3:00p Robert
+// Updated for change in IsProgramCompleted parameters
+//
+// 9 11/01/06 4:40p Robert
+// Added changes that are updates for the source to work with the new
+// Flash module
+//
+// 8 10/27/06 10:42a Felixp
+// Bug fixes for correct work in Virtual Address Space.
+//
+// 7 10/23/06 7:03p Felixp
+// 1. Virtual address space fixup of the global variables added
+// 2. NVRAM simulation support
+//
+// 6 10/12/06 9:07p Felixp
+//
+// 5 10/12/06 9:44a Felixp
+// UEFI2.0 compliance: use CreateLegacyBootEvent instead of CreateEvent
+//
+// 3 10/09/06 10:08a Felixp
+// UEFI2.0 support (QueryVariableInfo funciton added)
+//
+// 2 9/20/06 10:38a Felixp
+// 1. Bug fix in MemSetVariable: cached variable data was not updated
+// during variable update in Runtime
+// 2. Legacy boot event handler added to switch to runtime mode in case of
+// legacy boot
+//
+// 10 7/17/06 7:50p Felixp
+// changes so that module can be compiled in NV_SIMULATION mode without
+// Flash.lib
+//
+// 9 12/06/05 2:36p Felixp
+// bug fixes in NVCompact and NVSetVariable
+//
+// 8 9/23/05 5:44p Felixp
+// bug fix in NVSetVariable (when update of the variable causes NVCompact,
+// NameSize is uninitialized)
+//
+// 5 7/22/05 2:19a Felixp
+// 1. NVRAM enclosed into Firmware volume.
+// 2. bug fixes (mostly in NVCompact)
+//
+// 4 4/07/05 12:09p Felixp
+// bug fixing
+//
+// 3 1/20/05 11:37a Felixp
+// Component restructurized to support release in binary format
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 21 11/18/04 6:08p Felixp
+// checkpoint(0x99) removed
+//
+// 19 8/28/04 1:49a Felixp
+// NVRAM Routines fixes
+//
+// 15 7/16/04 1:00p Markw
+// Check max tpl.
+//
+// 1 3/29/04 2:32a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NVRAMDXE.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "NVRAM.h"
+#include <AmiDxeLib.h>
+#include "token.h"
+
+#include <Protocol/Variable.h>
+#include <Protocol/MonotonicCounter.h>
+#include <Protocol/FlashProtocol.h>
+#include <AmiCspLib.h>
+#include "NvramPreserveList.h"
+
+#define HYBRID_NV_INTERFACE
+
+#define HASH_SHA256_LEN 32
+
+#define UEFI21_SPECIFIC_VARIABLE_ATTRIBUTES (EFI_VARIABLE_HARDWARE_ERROR_RECORD |\
+ EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS)
+
+#define UEFI23_1_SPECIFIC_VARIABLE_ATTRIBUTES (EFI_VARIABLE_HARDWARE_ERROR_RECORD |\
+ EFI_VARIABLE_APPEND_WRITE |\
+ UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES)
+
+//##### Security ######
+#if AuthVariable_SUPPORT
+VOID AuthVariableServiceInit (VOID);
+VOID AuthVariableServiceInitSMM (VOID);
+VOID AuthServiceVirtualFixup(VOID);
+EFI_STATUS VerifyVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 *Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+);
+#else
+VOID AuthVariableServiceInit (VOID) {};
+VOID AuthVariableServiceInitSMM (VOID) {};
+VOID AuthServiceVirtualFixup(VOID) {};
+EFI_STATUS VerifyVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 *Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+){
+//UEFI 2.3.1 requres to return SECURITY_VIOLATION error if no Auth Var support present
+ if (*Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES)
+ return EFI_SECURITY_VIOLATION;
+ else
+ return EFI_SUCCESS;
+}
+#endif //#if AuthVariable_SUPPORT
+
+#define ALL_VARIABLE_ATTRIBUTES ( EFI_VARIABLE_NON_VOLATILE |\
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |\
+ EFI_VARIABLE_RUNTIME_ACCESS|\
+ UEFI23_1_SPECIFIC_VARIABLE_ATTRIBUTES)
+
+#define VALATILE_VARIABLE_STORE_SIZE 0x10000
+
+#define BEGIN_CRITICAL_SECTION(Cs) \
+ { if ((Cs)->Busy) return EFI_ACCESS_DENIED;\
+ BeginCriticalSection(Cs);\
+ }
+#define END_CRITICAL_SECTION(Cs) EndCriticalSection(Cs)
+#ifdef EFI_DEBUG
+
+#define NVRAM_TRACE(Arguments) { if (!Runtime) TRACE(Arguments); }
+#else
+#define NVRAM_TRACE(Arguments)
+#endif
+
+//============================================================================
+// Type definitions
+typedef BOOLEAN (*NVRAM_UPDATE_ROUTINE)(IN VOID *Address, UINTN Size);
+typedef BOOLEAN (*NVRAM_PROGRAM_ROUTINE)(IN VOID *Address, UINTN Size, VOID *Data);
+typedef BOOLEAN (*COPY_VAR_STORE_FILTER)(
+ IN VOID *Context, CHAR16* VarName, EFI_GUID* VarGuid,
+ NVRAM_STORE_INFO *Info
+);
+
+typedef struct
+{
+ NVRAM_UPDATE_ROUTINE EnableUpdate;
+ NVRAM_UPDATE_ROUTINE DisableUpdate;
+ NVRAM_UPDATE_ROUTINE EraseBytes;
+ NVRAM_PROGRAM_ROUTINE WriteBytes;
+} VARIABLE_INTERFACE;
+
+typedef struct
+{
+ UINT32 Mode;
+ UINT32 HeaderLength;
+ UINT32 NvramMode;
+ UINT32 InfoCount, LastInfoIndex;
+ NVRAM_STORE_INFO NvramInfo[10];
+ NVRAM_STORE_INFO *NvInfo, *MemInfo;
+ VARIABLE_INTERFACE *NvInterface, *MemInterface;
+ UINT8 *BackupAddress;
+#ifdef HYBRID_NV_INTERFACE
+ UINTN AddressDelta;
+ UINT8* NvramFlashAddress;
+#endif
+} VARSTORE_INFO;
+
+typedef struct
+{
+ BOOLEAN Busy;
+ BOOLEAN SmiState;
+ UINT8 IntState[2];
+} CRITICAL_SECTION;
+
+typedef EFI_STATUS (HOOK_GET_VARIABLE)(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+);
+typedef EFI_STATUS (HOOK_SET_VARIABLE)(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+);
+
+typedef EFI_STATUS (HOOK_GET_NEXT_VARIABLE_NAME)(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+);
+
+typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+
+typedef struct{
+ SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables;
+} AMI_NVRAM_CONTROL_PROTOCOL;
+
+#define LTEB_GUID \
+ {0xC8BCA618, 0xBFC6, 0x46B7, 0x8D, 0x19, 0x83, 0x14, 0xE2, 0xE5, 0x6E, 0xC1}
+
+typedef struct {
+ CHAR16 *Name;
+ EFI_GUID Guid;
+} SDL_VAR_ENTRY;
+
+typedef struct {
+ CHAR16 *Name;
+ UINT32 Attributes;
+} STD_EFI_VAR_ENTRY;
+
+//======================================================================
+//Function Prototypes
+EFI_STATUS NvramReinitialize();
+EFI_STATUS InitVolatileStore(
+ NVRAM_STORE_INFO *Info, UINTN Size,
+ UINTN HeaderLength, UINT8 Flags,
+ BOOLEAN Runtime
+);
+BOOLEAN CheckTheHeader(NVRAM_STORE_INFO *Info, UINT32 HeaderLength, BOOLEAN Update);
+
+//======================================================================
+// Global and extern variables
+extern const BOOLEAN NvramMonotonicCounterSupport;
+extern BOOLEAN NvramChecksumSupport;
+extern const BOOLEAN FlashNotMemoryMapped;
+static BOOLEAN Runtime = FALSE;
+static BOOLEAN HideBtVariables = TRUE;
+static EFI_GUID gAmiNvramControlProtocolGuid = { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } };
+static BOOLEAN SaveOnlyPreservedVars = FALSE;
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+BOOLEAN NoAccessOutsideofSmm = FALSE;
+#endif
+
+VARSTORE_INFO VarStoreInfo;
+CRITICAL_SECTION NvramCs = {FALSE, FALSE, {0,0} };
+CRITICAL_SECTION *NvramCsPtr = &NvramCs;
+
+const static UINT32 NvramSignature = NVAR_SIGNATURE;
+extern const BOOLEAN NvramRtGarbageCollectionSupport;
+EFI_PHYSICAL_ADDRESS NvramDriverBuffer = 0; // Runtime buffer for use in Runtime with the size of 3 times NVRAM_SIZE
+// First part (2 times NVRAM_SIZE) usialy used for TmpBuffer, while last part for VolatileStore.
+UINT32 NvramDriverBufferSize = 0;
+BOOLEAN FirstPartAlloc = FALSE;
+BOOLEAN SecondPartAlloc = FALSE;
+
+static FLASH_PROTOCOL *Flash = NULL;
+extern HOOK_GET_VARIABLE GET_VAR_LIST EndOfGetVariableHook;
+extern HOOK_SET_VARIABLE SET_VAR_LIST EndOfSetVariableHook;
+extern HOOK_GET_NEXT_VARIABLE_NAME GET_NEXT_VAR_NAME_LIST EndOfGetNextVarNameHook;
+
+HOOK_GET_VARIABLE* GetVariableHookList[]=
+ {GET_VAR_LIST NULL};
+HOOK_SET_VARIABLE* SetVariableHookList[]=
+ {SET_VAR_LIST NULL};
+HOOK_GET_NEXT_VARIABLE_NAME* GetNextVarNameHookList[]=
+ {GET_NEXT_VAR_NAME_LIST NULL};
+// Build time array of variables to be preserved.
+SDL_VAR_ENTRY gSdlVarLst[] = {
+ NVRAM_PRESERVE_VARIABLES_LIST {NULL, {0,0,0,0,0,0,0,0,0,0,0}}
+};
+
+STD_EFI_VAR_ENTRY gStdEfiVarList[] = {
+ {L"LangCodes", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"Lang", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"Timeout", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"PlatformLangCodes", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"PlatformLang", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"ConIn", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"ConOut", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"ErrOut", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"ConInDev", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"ConOutDev", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"ErrOutDev", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"BootOrder", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"BootNext", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"BootCurrent", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"BootOptionSupport", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"DriverOrder", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"HwErrRecSupport", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"SetupMode", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"KEK", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS},
+ {L"PK", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS},
+ {L"SignatureSupport", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"SecureBoot", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"KEKDefault", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"PKDefault", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"dbDefault", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"dbxDefault", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"dbtDefault", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"OsIndicationsSupported", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {L"OsIndications", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"VendorKeys", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS},
+ {NULL, 0}
+};
+
+STD_EFI_VAR_ENTRY gStdEfiVarListWildCard[] = {
+ {L"Boot****", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"Driver****", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {L"Key****", EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE},
+ {NULL, 0}
+};
+
+EFI_STATUS ShowBootTimeVariables (BOOLEAN Show);
+AMI_NVRAM_CONTROL_PROTOCOL NvramControl = {ShowBootTimeVariables };
+
+EFI_STATUS GetVariableHook(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+){
+ UINTN i;
+ EFI_STATUS Result = EFI_UNSUPPORTED;
+ for(i=0; GetVariableHookList[i] && (Result == EFI_UNSUPPORTED); i++)
+ Result = GetVariableHookList[i](VariableName, VendorGuid, Attributes, DataSize, Data);
+ return Result;
+}
+
+EFI_STATUS SetVariableHook(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+){
+ UINTN i;
+ EFI_STATUS Result = EFI_UNSUPPORTED;
+ for(i=0; SetVariableHookList[i] && (Result == EFI_UNSUPPORTED); i++)
+ Result = SetVariableHookList [i](VariableName, VendorGuid, Attributes, DataSize, Data);
+ return Result;
+}
+
+EFI_STATUS GetNextVarNameHook(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+){
+ UINTN i;
+ EFI_STATUS Result = EFI_UNSUPPORTED;
+ for(i=0; GetNextVarNameHookList[i] && (Result == EFI_UNSUPPORTED); i++)
+ Result = GetNextVarNameHookList [i](VariableNameSize, VariableName, VendorGuid);
+ return Result;
+}
+//--- GetVariable, SetVariable and GetNextVarName Hooks END ------
+
+//Update Interfaces:
+//Memory-based
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DummyUpdateRoutine
+//
+// Description: This function is dummy function doing nothing and always returning TRUE
+//
+// Input: IN VOID *Address - Memory address
+// UINTN Size - Size
+//
+// Output: TRUE always
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN DummyUpdateRoutine(IN VOID *Address, UINTN Size) {return TRUE;}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemErase
+//
+// Description: This function sets Size amount memory starting from Address to FLASH_EMPTY_BYTE
+//
+// Input: IN VOID *Address - Memory address
+// UINTN Size - Size
+//
+// Output: TRUE always
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MemErase(IN VOID *Address, UINTN Size)
+{
+ MemSet(Address,Size,FLASH_EMPTY_BYTE);
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemProgram
+//
+// Description: This function writs Data to memory starting from Address
+//
+// Input: IN VOID *Address - Memory address
+// UINTN Size - Size of data to write
+// VOID *Data - pointer to data to write
+//
+// Output: TRUE always
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN MemProgram(IN VOID *Address, UINTN Size, VOID *Data)
+{
+ MemCpy(Address,Data,Size);
+ return TRUE;
+}
+
+//Flash-based
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvEnableWrites
+//
+// Description: This function enables writes to flash starting from Address
+//
+// Input: IN VOID *Address - Start address
+// UINTN Size - Size of flash to be write enabled
+//
+// Output: TRUE always
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvEnableWrites(IN VOID *Address, UINTN Size)
+{
+ UINT8* Start = (UINT8*)Address;
+ UINT8* p;
+ Flash->DeviceWriteEnable();
+
+ for (p=(UINT8*)BLOCK(Start); p<Start+Size; p+=FlashBlockSize) FlashBlockWriteEnable(p);
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvDisableWrites
+//
+// Description: This function disables writes to flash starting from Address
+//
+// Input: IN VOID *Address - Start address
+// UINTN Size - Size of flash to be write disable
+//
+// Output: TRUE always
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvDisableWrites(IN VOID *Address, UINTN Size)
+{
+ UINT8* Start = (UINT8*)Address;
+ UINT8* p;
+
+ for (p=(UINT8*)BLOCK(Start); p<Start+Size; p+=FlashBlockSize) FlashBlockWriteDisable(p);
+
+ Flash->DeviceWriteDisable();
+ return TRUE;
+}
+
+#define INT_SIZE sizeof(INTN)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsProgrammableOrEqual
+//
+// Description: This function checks if defined memory chunks are the same and if destenation is programmable
+//
+// Input: IN UINT8 *pDest - pointer to memory to check
+// IN UINT8 *pSource - pointer to the source to compare with
+// IN UINTN Size - size of the chunk
+// OUT BOOLEAN *pIsProgrammable - Will be set to TRUE if pDest is programable
+// OUT BOOLEAN *pIsEqual - Will be set to TRUE if pDest and pSource has the same content
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IsProgrammableOrEqual(
+ IN UINT8 *pDest,
+ IN UINT8 *pSource,
+ IN UINTN Size,
+ OUT BOOLEAN *pIsProgrammable,
+ OUT BOOLEAN *pIsEqual
+)
+{
+ *pIsEqual = TRUE;
+ *pIsProgrammable = TRUE;
+
+ // loops through the destination looking to see if the data is the same
+ // as the source, or if the Destination has already bee erased
+ if (!( (UINTN)pDest & (INT_SIZE-1) || (UINTN)pSource & (INT_SIZE-1) ))
+ {
+ UINTN *Dest = (UINTN*)pDest, *Source = (UINTN*)pSource;
+
+ for ( ; Size >= INT_SIZE; Size -= INT_SIZE)
+ {
+ UINTN s,d;
+
+ if (FLASH_EMPTY_BYTE==0)
+ {
+ s=~*Source;
+ if (FlashNotMemoryMapped)
+ Flash->Read((UINT8 *)Dest, INT_SIZE, &(UINT8)d);
+ else
+ d=*Dest;
+ }
+
+ else
+ {
+ s=*Source;
+ if (FlashNotMemoryMapped)
+ {
+ Flash->Read((UINT8 *)Dest, INT_SIZE, &(UINT8)d);
+ d=~d;
+ }
+ else
+ d=~*Dest;
+ }
+
+ if ((d&s)!=0)
+ {
+ *pIsProgrammable = FALSE;
+ *pIsEqual = FALSE;
+ return;
+ }
+ if (FlashNotMemoryMapped)
+ {
+ Flash->Read((UINT8 *)Dest, INT_SIZE, &(UINT8)d);
+ if (d != *Source++) *pIsEqual = FALSE;
+ Dest++;
+ }
+ else
+ if (*Dest++ != *Source++) *pIsEqual = FALSE;
+
+ }
+ }
+
+ // since the address may not be INT_SIZE aligned, this checks
+ // the rest of the data
+ for ( ; Size > 0; Size--)
+ {
+ UINT8 s,d;
+
+ if (FLASH_EMPTY_BYTE==0)
+ {
+ s=~*pSource;
+ if (FlashNotMemoryMapped)
+ Flash->Read(pDest, 1, &d);
+ else
+ d=*pDest;
+
+ }
+ else
+ {
+ s=*pSource;
+ if (FlashNotMemoryMapped)
+ {
+ Flash->Read(pDest, 1, &d);
+ d=~d;
+ }
+ else
+ d=~*pDest;
+
+ }
+
+ if ((d&s)!=0)
+ {
+ *pIsProgrammable = FALSE;
+ *pIsEqual = FALSE;
+ return;
+ }
+ if (FlashNotMemoryMapped)
+ {
+ Flash->Read(pDest, 1, &d);
+ if ( d != *pSource++) *pIsEqual = FALSE;
+ pDest++;
+ }
+ else
+ if (*pDest++ != *pSource++)
+ *pIsEqual = FALSE;
+
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsClean
+//
+// Description: This function checks if defined memory chunk is clean
+//
+// Input: IN UINT8 *pDest - pointer to memory to check
+// IN UINTN Size - size of the chunk
+//
+// Output: BOOLEAN - TRUE if pDest is clean, otherwice FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static BOOLEAN IsClean(
+ IN UINT8 *pDest,
+ IN UINTN Size
+)
+{
+ // loops through the destination looking to see if the buffer is empty
+ if (!( (UINTN)pDest & (INT_SIZE-1) ))
+ {
+ for ( ; Size >= INT_SIZE; Size -= INT_SIZE, pDest += INT_SIZE)
+ {
+ if (FlashNotMemoryMapped)
+ {
+ UINTN nData=0;
+ Flash->Read(pDest, INT_SIZE, &(UINT8)nData);
+ if (nData != FlashEmpty) return FALSE;
+ }
+ else
+ if (*(UINTN*)pDest != FlashEmpty) return FALSE;
+ }
+ }
+
+ // since the address may not be INT_SIZE aligned, this checks
+ // the rest of the data
+ for ( ; Size > 0; Size--, pDest++)
+ {
+ if (FlashNotMemoryMapped)
+ {
+ UINT8 nData=0;
+ Flash->Read(pDest, 1, &(UINT8)nData);
+ if (nData != FLASH_EMPTY_BYTE) return FALSE;
+ }
+ else
+ if (*pDest != FLASH_EMPTY_BYTE) return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvProgram
+//
+// Description: This function programms Size amount of flash starting with Address
+//
+// Input: IN VOID *Address - pointer to flash to programm
+// IN UINTN Size - size of the data to programm
+// VOID *Data - pointer to the data to be programed
+//
+// Output: BOOLEAN - TRUE if pDest is clean, otherwice FALSE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvProgram(IN VOID *Address, UINTN Size, VOID *Data)
+{
+ BOOLEAN Status;
+ BOOLEAN Programmable,Equal;
+
+ if (Size==0) return TRUE;
+
+ IsProgrammableOrEqual(Address,Data,Size,&Programmable,&Equal);
+
+ if (Equal) return TRUE;
+
+ if (!Programmable) return FALSE;
+
+ Status = FlashProgram(Address,Data,(UINT32)Size);
+
+ if (Status)
+ {
+ if (FlashNotMemoryMapped)
+ {
+ UINT8 nData=0;
+ UINTN Count=0;
+ for ( Count=0; Count<Size; Count++)
+ {
+ Flash->Read((UINT8 *)Address+Count, 1, &nData );
+ Status = ( nData == *((UINT8 *)Data+Count) );
+ if (!Status) break;
+ }
+ }
+ else
+ Status = ( MemCmp(Address,Data,Size) == 0 );
+
+ }
+
+ if (!Runtime && !Status) ERROR_CODE(DXE_FLASH_UPDATE_FAILED,EFI_ERROR_MAJOR);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SelectiveAllocate
+//
+// Description: This function returns pointer to allocated memory to use as
+// temp buffer for any occasions. If NvramDriverBuffer is not 0 -
+// memory allocated previously will be used. If not - function will
+// allocate memory with the Size - and return pointer to it.
+//
+// Input: IN BOOLEAN FirstPart - if TRUE - first part of NvramDriverBuffer
+// will be used.
+// IN UINTN Size - size of memory to allocate.
+//
+// Output: UINT8* - pointer to allocated memory.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8* SelectiveAllocate (BOOLEAN FirstPart, UINTN Size)
+{
+ if (NvramDriverBuffer){
+ if (FirstPart){
+ if (!FirstPartAlloc){
+ FirstPartAlloc = TRUE;
+ return (UINT8*)NvramDriverBuffer;
+ }else return NULL;
+ }else{
+ if (!SecondPartAlloc){
+ SecondPartAlloc = TRUE;
+ return (UINT8*)(NvramDriverBuffer + NvramDriverBufferSize / 3 * 2);
+ }else return NULL;
+ }
+ }else{
+ if (!Runtime){
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ if (NoAccessOutsideofSmm){
+ UINT8 *Buffer;
+ EFI_STATUS Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,Size, &Buffer
+ );
+ if (EFI_ERROR(Status)) return NULL;
+ return Buffer;
+ }
+ else
+#endif
+ return (UINT8*)Malloc(Size);
+ }
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SelectiveFree
+//
+// Description: This function free memory allocated for temp buffer
+// for any occasions. If address passed to this function fits
+// (NvramDriverBuffer + it's size) range memory allocated in
+// NvramDriverBuffer will be released. If not - function will
+// call FreePool routine.
+//
+// Input: UINT8* Target - pointer to the begining of memory to free
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SelectiveFree (UINT8* Target)
+{
+ if (NvramDriverBuffer){
+ if (Target == (UINT8*) NvramDriverBuffer){
+ FirstPartAlloc = FALSE;
+ return;
+ }
+ if (Target == (UINT8*) (NvramDriverBuffer + NvramDriverBufferSize / 3 * 2)){
+ SecondPartAlloc = FALSE;
+ return;
+ }
+ }
+ if (!Runtime){
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ if (NoAccessOutsideofSmm) pSmst->SmmFreePool (Target);
+ else
+#endif
+ pBS->FreePool(Target);
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvErase
+//
+// Description: This function erases Size amount of flash starting with Address
+//
+// Input: IN VOID *Address - pointer to flash to erase
+// IN UINTN Size - size of the flash to erase
+//
+// Output: BOOLEAN - TRUE or FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvErase(IN VOID *Address, UINTN Size)
+{
+ UINT8* pStart = (UINT8*)Address;
+ UINT8* pEnd = pStart+Size;
+ UINT8* pStartBlock = (UINT8*)BLOCK(pStart);
+ UINT8* pEndBlock = (UINT8*)BLOCK(pEnd-1)+FlashBlockSize;
+ UINTN PrologSize = pStart - pStartBlock;
+ UINTN EpilogSize = pEndBlock-pEnd;
+ UINT8* pBuffer=NULL;
+ UINT8* p;
+ BOOLEAN ok;
+
+ if ( Size==0 || IsClean(Address,Size) ) return TRUE;
+
+ if (PrologSize+EpilogSize)
+ {
+ pBuffer = SelectiveAllocate (TRUE, (PrologSize + EpilogSize));
+ if (pBuffer == NULL) return FALSE;
+ MemCpy(pBuffer,pStartBlock,PrologSize);
+ MemCpy(pBuffer+PrologSize,pEnd,EpilogSize);
+ }
+
+ //erase first block
+ if (ok=FlashEraseBlock(pStartBlock))
+ {
+ if (PrologSize) ok=NvProgram(pStartBlock,PrologSize,pBuffer);
+
+ if (ok)
+ {
+ //erase other blocks
+ for (p=pStartBlock+=FlashBlockSize; p!=pEndBlock; p+=FlashBlockSize)
+ {
+ if (!(ok=FlashEraseBlock(p))) break;
+ }
+
+ if (ok && EpilogSize) ok=NvProgram(pEnd,EpilogSize,pBuffer+PrologSize);
+ }
+ }
+
+ if (pBuffer) SelectiveFree (pBuffer);
+
+ if (!ok) ERROR_CODE(DXE_FLASH_UPDATE_FAILED,EFI_ERROR_MAJOR);
+
+ return ok;
+}
+
+VARIABLE_INTERFACE MemInterface = {DummyUpdateRoutine, DummyUpdateRoutine, MemErase, MemProgram};
+VARIABLE_INTERFACE NvInterface = {NvEnableWrites, NvDisableWrites, NvErase, NvProgram};
+
+#ifdef HYBRID_NV_INTERFACE
+
+UINTN HybridGetAddressDelta(UINT8 *Address, UINTN Size){
+ if (VarStoreInfo.NvInfo == 0) return VarStoreInfo.AddressDelta;
+//Sometimes VarStoreInfo.NvInterface is used to update
+//store other than VarStoreInfo.NvramInfo.
+//For example during UpdateFtVarstore it is used to update backup store.
+//This function is used to fall-back to non-hybrid interface if varstore other than
+//VarStoreInfo.NvramInfo is being updated.
+ return
+ ( Address >= VarStoreInfo.NvInfo->NvramAddress
+ && Address+Size
+ <= VarStoreInfo.NvInfo->NvramAddress
+ + VarStoreInfo.NvInfo->NvramSize
+ ) ? VarStoreInfo.AddressDelta : 0;
+}
+
+BOOLEAN HybridEnableWrites(IN VOID *Address, UINTN Size){
+ UINTN Delta = HybridGetAddressDelta(Address,Size);
+ return NvEnableWrites(Delta+(UINT8*)Address, Size);
+}
+
+BOOLEAN HybridDisableWrites(IN VOID *Address, UINTN Size){
+ UINTN Delta = HybridGetAddressDelta(Address,Size);
+ return NvDisableWrites(Delta+(UINT8*)Address, Size);
+}
+
+BOOLEAN HybridErase(IN VOID *Address, UINTN Size){
+ BOOLEAN ok;
+ UINTN Delta = HybridGetAddressDelta(Address,Size);
+ ok = NvErase(Delta+(UINT8*)Address, Size);
+ // Zero Delta implies that there is no memory buffer
+ if (Delta==0) return ok;
+ if (ok) return MemErase(Address, Size);
+ // Flash update operation has failed.
+ // The memory buffer is out of synch with the flash device.
+ // Re-synchronize the mememory buffer by reading flash device.
+ if (FlashNotMemoryMapped)
+ Flash->Read(Delta+(UINT8*)Address, Size, Address);
+ else
+ MemCpy(Address, Delta+(UINT8*)Address, Size);
+ return FALSE;
+}
+
+BOOLEAN HybridProgram(IN VOID *Address, UINTN Size, VOID *Data){
+ BOOLEAN ok;
+ UINTN Delta = HybridGetAddressDelta(Address,Size);
+ ok = NvProgram(Delta+(UINT8*)Address, Size, Data);
+ // Zero Delta implies that there is no memory buffer
+ if (Delta==0) return ok;
+ if (ok) return MemProgram(Address, Size, Data);
+ // Flash update operation has failed.
+ // The memory buffer is out of synch with the flash device.
+ // Re-synchronize the mememory buffer by reading flash device.
+ if (FlashNotMemoryMapped)
+ Flash->Read(Delta+(UINT8*)Address, Size, Address);
+ else
+ MemCpy(Address, Delta+(UINT8*)Address, Size);
+ return FALSE;
+}
+
+VARIABLE_INTERFACE HybridInterface = {HybridEnableWrites, HybridDisableWrites, HybridErase, HybridProgram};
+
+VOID InitHybridInterface(NVRAM_STORE_INFO *NvStore){
+ EFI_STATUS Status;
+ //We can't use InitVolatileStore here because it will screw up SelectiveAllocate/SelectiveFree logic.
+
+ //TODO: When DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME is defined, we assume that
+ //DXE Variable services will be replaced prior to transitioning to runtime.
+ //If this will not happen, the NVRAM driver may not work properly.
+ //It may either crash (or crash the Windows), or generate false garbage collections.
+ //To support fall back scenario the memory allocation below and registration of the virtual address change event must be changed
+ VarStoreInfo.NvramFlashAddress = NvStore->NvramAddress;
+ Status = pBS->AllocatePool (
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ EfiBootServicesData,
+#else
+ EfiRuntimeServicesData,
+#endif
+ NvStore->NvramSize, &NvStore->NvramAddress
+ );
+ if (!EFI_ERROR(Status)){
+ VarStoreInfo.NvInterface=&HybridInterface;
+ MemCpy(NvStore->NvramAddress,VarStoreInfo.NvramFlashAddress,NvStore->NvramSize);
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM: working in hybrid mode\n"));
+ }else{
+ VarStoreInfo.NvInterface=&NvInterface;
+ NvStore->NvramAddress = VarStoreInfo.NvramFlashAddress;
+ }
+ //We altered content of the varstore. Let's reinitialize it.
+ NvInitInfoBuffer(
+ NvStore, VarStoreInfo.HeaderLength,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ );
+ VarStoreInfo.AddressDelta=VarStoreInfo.NvramFlashAddress-NvStore->NvramAddress;
+}
+
+BOOLEAN SwapVarstoresInHybridMode(NVRAM_STORE_INFO *BackupInfo){
+ UINT8* OriginalNvramFlashAddress;
+ if ( VarStoreInfo.NvramFlashAddress == 0 ) return FALSE;
+ OriginalNvramFlashAddress=VarStoreInfo.NvramFlashAddress;
+
+ VarStoreInfo.NvramFlashAddress = VarStoreInfo.BackupAddress;
+ // Zero AddressDelta implies that the memory buffer is no longer used.
+ if (VarStoreInfo.AddressDelta!=0){
+ VarStoreInfo.AddressDelta=VarStoreInfo.NvramFlashAddress-VarStoreInfo.NvInfo->NvramAddress;
+
+ MemCpy(
+ VarStoreInfo.NvInfo->NvramAddress,VarStoreInfo.BackupAddress,
+ VarStoreInfo.NvInfo->NvramSize
+ );
+ }
+ BackupInfo->NvramAddress = VarStoreInfo.NvInfo->NvramAddress;
+ BackupInfo->NvramSize = VarStoreInfo.NvInfo->NvramSize;
+ NvInitInfoBuffer(
+ BackupInfo, VarStoreInfo.HeaderLength, VarStoreInfo.NvInfo->Flags
+ );
+ VarStoreInfo.BackupAddress = OriginalNvramFlashAddress;
+ return TRUE;
+}
+
+VOID HybridStoreToRealStore(NVRAM_STORE_INFO *InInfo, NVRAM_STORE_INFO *OutInfo){
+ *OutInfo = *InInfo;
+ OutInfo->NvramAddress = VarStoreInfo.NvramFlashAddress;
+ OutInfo->NvramGuidsAddress = (EFI_GUID*)((UINT8*)OutInfo->NvramGuidsAddress + VarStoreInfo.AddressDelta);
+ OutInfo->pEndOfVars += VarStoreInfo.AddressDelta;
+ OutInfo->pFirstVar += VarStoreInfo.AddressDelta;
+ OutInfo->pLastReturned=0;
+}
+
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+VOID ReallocateHybridVarstoreToSmm(){
+ NVRAM_STORE_INFO *Info = VarStoreInfo.NvInfo;
+ UINT8* SmmBuffer;
+ UINT32 i;
+ UINT8* NvramAddress;
+ UINT8* EndOfVars;
+
+ EFI_STATUS Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ Info->NvramSize, &SmmBuffer
+ );
+ if (EFI_ERROR(Status)){
+ // Zero AddressDelta implies that the memory buffer is no longer used.
+ VarStoreInfo.AddressDelta=0;
+ return;
+ }
+ MemCpy(
+ SmmBuffer,Info->NvramAddress,Info->NvramSize
+ );
+ VarStoreInfo.AddressDelta=SmmBuffer-Info->NvramAddress;
+ NvramAddress = Info->NvramAddress;
+ EndOfVars= Info->pEndOfVars;
+ // Fix up the main NVRAM store and nested variable stores.
+ // An example of a nested store is the defaults store.
+ for (i=0; i<VarStoreInfo.InfoCount; i++){
+ // If a store is embedded into the main NVRAM store,
+ // fix it up with the SMM buffer address
+ if ( VarStoreInfo.NvramInfo[i].NvramAddress >= NvramAddress
+ && VarStoreInfo.NvramInfo[i].pEndOfVars <= EndOfVars
+ ){
+ VarStoreInfo.NvramInfo[i].NvramAddress += VarStoreInfo.AddressDelta;
+ VarStoreInfo.NvramInfo[i].NvramGuidsAddress = (EFI_GUID*)((UINT8*)VarStoreInfo.NvramInfo[i].NvramGuidsAddress + VarStoreInfo.AddressDelta);
+ VarStoreInfo.NvramInfo[i].pEndOfVars += VarStoreInfo.AddressDelta;
+ VarStoreInfo.NvramInfo[i].pFirstVar += VarStoreInfo.AddressDelta;
+ VarStoreInfo.NvramInfo[i].pLastReturned=0;
+ }
+ }
+ VarStoreInfo.AddressDelta=VarStoreInfo.NvramFlashAddress-SmmBuffer;
+}
+#endif // DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+#endif
+
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+VOID ReallocateVolatileVarstoreToSmm(){
+ NVRAM_STORE_INFO *Info = VarStoreInfo.MemInfo;
+ UINT8* SmmBuffer;
+ UINTN Delta;
+
+ EFI_STATUS Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ Info->NvramSize, &SmmBuffer
+ );
+ if (EFI_ERROR(Status)){
+ //TODO: Shutdown non-valatile services;
+ ASSERT(FALSE);
+ return;
+ }
+ MemCpy(
+ SmmBuffer,Info->NvramAddress,Info->NvramSize
+ );
+ Delta=SmmBuffer-Info->NvramAddress;
+ Info->NvramAddress = SmmBuffer;
+ Info->NvramGuidsAddress = (EFI_GUID*)((UINT8*)Info->NvramGuidsAddress + Delta);
+ Info->pEndOfVars += Delta;
+ Info->pFirstVar += Delta;
+ Info->pLastReturned=0;
+}
+#endif
+
+///////////////////////////////////////////////////////////////////////////
+//Cache operations
+#define NV_CACHE_SUPPORT 1
+
+typedef struct
+{
+ DLINK Link;
+ NVAR *Nvar;
+ NVAR *FinalDataNvar;
+ UINT32 InfoIndex;
+ CHAR16 Name[8];
+} VAR_INDEX_ENTRY;
+
+typedef struct
+{
+ DLIST LetterIndex['z'-'a'+1];
+ DLIST OtherIndex;
+ DLIST Blanks;
+ UINT8 *Buffer;
+ UINTN UsedSize;
+ UINTN BufferSize;
+} VAR_INDEX;
+
+#if !NV_CACHE_SUPPORT
+VAR_INDEX *VarIndexPtr=NULL;
+#else
+#define VARIABLE_INDEX_SIZE 0x10000
+
+VAR_INDEX VarIndex;
+VAR_INDEX *VarIndexPtr=&VarIndex;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsNvramRuntime
+//
+// Description: This function returns the value of Runtime local variable
+//
+// Input: None
+//
+// Output: BOOLEAN - current value of Runtime local variable
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsNvramRuntime()
+{
+ return Runtime;
+}
+
+BOOLEAN AreBtVariablesHidden()
+{
+ return HideBtVariables && Runtime;
+}
+EFI_STATUS ShowBootTimeVariables (BOOLEAN Show){
+ HideBtVariables = !Show;
+ TRACE((-1,"Setting HideBtVariables to %d\n",HideBtVariables));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS InstallNvramControlSmmProtocol(){
+ return pSmst->SmmInstallConfigurationTable(
+ pSmst, &gAmiNvramControlProtocolGuid, &NvramControl, sizeof(NvramControl)
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexGetList
+//
+// Description: This function gets list of variables starting with FirstLetter
+//
+// Input: CHAR16 FirstLetter - letter to search
+//
+// Output: DLIST* - pointer to list of Var starting with FirstLetter
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+DLIST* IndexGetList(CHAR16 FirstLetter)
+{
+ //convert to lower case
+ if (FirstLetter>='A'&&FirstLetter<='Z') FirstLetter -= 'A';
+ else if (FirstLetter>='a'&&FirstLetter<='z') FirstLetter -= 'a';
+ else return &VarIndexPtr->OtherIndex;
+
+ return &VarIndexPtr->LetterIndex[FirstLetter];
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexGetListNvar
+//
+// Description: This function gets list of variables starting with First Letter of Nvar
+//
+// Input: NVAR *Nvar - pointer to Var
+//
+// Output: DLIST* - pointer to list of Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+DLIST* IndexGetListNvar(NVAR *Nvar)
+{
+ VOID *NamePtr;
+ CHAR16 FirstLetter;
+
+ NamePtr = NvGetName(Nvar);
+ FirstLetter = (Nvar->flags&NVRAM_FLAG_ASCII_NAME) ? *(CHAR8*)NamePtr : *(CHAR16*)NamePtr;
+ return IndexGetList(FirstLetter);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexFindVariableEntry
+//
+// Description: This function searches for Var with specific GUID
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OUT UINTN *VariableNameSize - size of Var name
+// OUT NVRAM_STORE_INFO **Info - double pointer to NVRAM_STORE_INFO structure
+// OUT BOOLEAN *UnindexedExists - indicator, that there is unindexed variables
+//
+// Output: VAR_INDEX_ENTRY* - pointer to Var's Index entry found; NULL if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VAR_INDEX_ENTRY* IndexFindVariableEntry(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINTN *VariableNameSize,
+ OUT NVRAM_STORE_INFO **Info, OUT BOOLEAN *UnindexedExists
+)
+{
+ DLINK *Link;
+ VAR_INDEX_ENTRY* Entry;
+ UINTN Count;
+ DLIST *List;
+ BOOLEAN CorruptedEntryFound;
+
+ if (VarIndexPtr==NULL)
+ {
+ *UnindexedExists=TRUE;
+ return NULL;
+ }
+
+ List = IndexGetList(VariableName[0]);
+ CorruptedEntryFound = FALSE;
+
+ for (Link=List->pHead, Count=0; Link!=NULL; Link=Link->pNext, Count++)
+ {
+ UINTN i;
+ Entry = OUTTER(Link,Link, VAR_INDEX_ENTRY);
+
+ for (i=0; i<sizeof(Entry->Name)/sizeof(CHAR16)&&Entry->Name[i]; i++)
+ if (Entry->Name[i]!=VariableName[i+1]) break;
+
+ if (Entry->Name[i]&&Entry->Name[i]!=VariableName[i+1]) continue;
+
+ if(!NvIsVariable( Entry->Nvar,
+ &VarStoreInfo.NvramInfo[Entry->InfoIndex]
+ )
+ ){
+ CorruptedEntryFound = TRUE;
+ continue;
+ }
+
+ if (NvVarEq(
+ Entry->Nvar,VariableName,VendorGuid,
+ VariableNameSize,&VarStoreInfo.NvramInfo[Entry->InfoIndex]
+ )
+ ) break;
+ }
+
+ //entry found
+ if (Link!=NULL)
+ {
+ *Info=&VarStoreInfo.NvramInfo[Entry->InfoIndex];
+ //VariableNameSize has already been initialized by the NvVarEq call
+ //Make sure the cached final data Nvar is valid
+ if (Entry->FinalDataNvar==NULL)
+ Entry->FinalDataNvar=NvGetDataNvar(Entry->Nvar, *Info);
+
+ return Entry;
+ }
+
+ *UnindexedExists=CorruptedEntryFound || Count<List->Size;
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexFindVariable
+//
+// Description: This function searches for Var with specific GUID
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OUT UINTN *VariableNameSize - size of Var name
+// OUT NVRAM_STORE_INFO **Info - double pointer to NVRAM_STORE_INFO structure
+// OUT BOOLEAN *UnindexedExists - indicator, that there is unindexed variables
+//
+// Output: NVAR* - pointer to Var found; NULL if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* IndexFindVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINTN *VariableNameSize,
+ OUT NVRAM_STORE_INFO **Info, OUT BOOLEAN *UnindexedExists
+)
+{
+ VAR_INDEX_ENTRY* Entry = IndexFindVariableEntry(
+ VariableName, VendorGuid,
+ VariableNameSize,
+ Info, UnindexedExists
+ );
+ if (Entry != NULL) return Entry->Nvar;
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexGetBlankEntry
+//
+// Description: This function searches for the blank entry in VarIndexPtr structure
+//
+// Input: NONE
+//
+// Output: VAR_INDEX_ENTRY* - pointer to the blank entry, NUUL if no space
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VAR_INDEX_ENTRY* IndexGetBlankEntry()
+{
+ VAR_INDEX_ENTRY* Entry;
+ //---Check if there is space in buffer-----
+ if (VarIndexPtr->UsedSize<=VarIndexPtr->BufferSize-sizeof(VAR_INDEX_ENTRY))
+ {
+ Entry = (VAR_INDEX_ENTRY*)(VarIndexPtr->Buffer+VarIndexPtr->UsedSize);
+ VarIndexPtr->UsedSize+=sizeof(VAR_INDEX_ENTRY);
+ }
+ //---If not - check in blanks--------
+ else if (!DListEmpty(&VarIndexPtr->Blanks))
+ {
+ Entry = OUTTER(
+ VarIndexPtr->Blanks.pTail,
+ Link, VAR_INDEX_ENTRY
+ );
+ DListDelete(&VarIndexPtr->Blanks,&Entry->Link);
+ }
+
+ else
+ {
+ Entry = NULL;
+ }
+
+ return Entry;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexAddVariable
+//
+// Description: This function adds new Var
+//
+// Input: NVAR *Nvar - pointer to Var
+// IN NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexAddVariable(
+ IN NVAR *Nvar, IN NVRAM_STORE_INFO *Info
+)
+{
+ DLIST *List;
+ VAR_INDEX_ENTRY *Entry;
+ UINTN i;
+ VOID *NamePtr;
+
+ if (VarIndexPtr==NULL) return ;
+
+ List = IndexGetListNvar(Nvar);
+ Entry = IndexGetBlankEntry();
+
+ if (Entry==NULL)
+ {
+ List->Size++;
+ return;
+ }
+
+ Entry->Nvar=Nvar;
+ Entry->FinalDataNvar=NULL;
+ Entry->InfoIndex= (UINT32)(Info-&VarStoreInfo.NvramInfo[0]);
+ ASSERT(Entry->InfoIndex<VarStoreInfo.InfoCount)
+ NamePtr=NvGetName(Nvar);
+
+ if (Nvar->flags&NVRAM_FLAG_ASCII_NAME)
+ {
+ CHAR8 *N = (CHAR8*)NamePtr+1;
+
+ for (i=0; i<sizeof(Entry->Name)/sizeof(CHAR16)-1&&N[i]!=0; i++)
+ Entry->Name[i]=N[i];
+ }
+
+ else
+ {
+ CHAR16 *N = (CHAR16*)NamePtr+1;
+
+ for (i=0; i<sizeof(Entry->Name)/sizeof(CHAR16)-1&&N[i]!=0; i++)
+ Entry->Name[i]=N[i];
+ }
+
+ Entry->Name[i]=0;
+ DListAdd(List,&Entry->Link);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexUpdateVariable
+//
+// Description: This function searces for Var and if it is found updates it, or add new var otherwise
+//
+// Input: NVAR *Nvar - pointer to Var
+// IN NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexUpdateVariable(
+ IN NVAR *Nvar, IN NVRAM_STORE_INFO *Info
+)
+{
+ VAR_INDEX_ENTRY *Entry=NULL;
+ DLIST *List = IndexGetListNvar(Nvar);
+ DLINK *Link;
+
+ if (VarIndexPtr==NULL) return ;
+
+ for (Link=List->pHead; Link!=NULL; Link=Link->pNext)
+ {
+ VAR_INDEX_ENTRY *TmpEntry = OUTTER(Link,Link, VAR_INDEX_ENTRY);
+
+ if(!NvIsVariable(TmpEntry->Nvar,
+ &VarStoreInfo.NvramInfo[TmpEntry->InfoIndex]
+ )
+ ) continue;
+
+ if (NvarEqNvar(TmpEntry->Nvar,&VarStoreInfo.NvramInfo[TmpEntry->InfoIndex],Nvar,Info))
+ {
+ Entry=TmpEntry;
+ break;
+ }
+ }
+
+ if (Entry==NULL)
+ {
+ IndexAddVariable(Nvar,Info);
+ }
+ else
+ {
+ Entry->Nvar=Nvar;
+ Entry->FinalDataNvar=NULL;
+ Entry->InfoIndex= (UINT32)(Info-&VarStoreInfo.NvramInfo[0]);
+ ASSERT(Entry->InfoIndex<VarStoreInfo.InfoCount)
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexDeleteVariable
+//
+// Description: This function deletes Var and adds it's entry in VarIndexPtr to blanks
+//
+// Input: NVAR *Nvar - pointer to Var to delete
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexDeleteVariable(NVAR *Nvar)
+{
+ VAR_INDEX_ENTRY *Entry=NULL;
+ DLIST *List = IndexGetListNvar(Nvar);
+ DLINK *Link;
+
+ if (VarIndexPtr==NULL) return ;
+
+ for (Link=List->pHead; Link!=NULL; Link=Link->pNext)
+ {
+ Entry = OUTTER(Link,Link, VAR_INDEX_ENTRY);
+
+ if (Entry->Nvar==Nvar)
+ {
+ DListDelete(List,&Entry->Link);
+ DListAdd(&VarIndexPtr->Blanks,&Entry->Link);
+ return;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexDeleteVariableEntry
+//
+// Description: This function deletes Var and adds it's entry in VarIndexPtr to blanks
+//
+// Input: VAR_INDEX_ENTRY *Entry - pointer to Entry to delete
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexDeleteVariableEntry(VAR_INDEX_ENTRY *Entry)
+{
+ DLIST *List;
+ if (Entry == NULL) return;
+
+ List = IndexGetListNvar(Entry->Nvar);
+
+ if (VarIndexPtr==NULL) return ;
+
+ DListDelete(List,&Entry->Link);
+ DListAdd(&VarIndexPtr->Blanks,&Entry->Link);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexReset
+//
+// Description: This function resets the VarIndexPtr and updates VarStoreInfo structures
+//
+// Input: NONE
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexReset()
+{
+ INTN i;
+
+ if (VarIndexPtr==NULL) return ;
+
+ VarIndexPtr->UsedSize=0;
+
+ for (i=0; i<='z'-'a'; i++) DListInit(&VarIndexPtr->LetterIndex[i]);
+ //---Reset fields in VarIndexPtr---------------
+ DListInit(&VarIndexPtr->OtherIndex);
+ DListInit(&VarIndexPtr->Blanks);
+
+ for (i=(INTN)VarStoreInfo.InfoCount-1; i>=0; i--)
+ {
+ NVRAM_STORE_INFO *Info = &VarStoreInfo.NvramInfo[i];
+ NVAR *Nvar=(NVAR*)Info->pFirstVar;
+
+ if (!NvIsVariable(Nvar,Info)) continue;
+
+ for (; Nvar!=NULL; Nvar=NvGetNextValid(Nvar,Info))
+ IndexUpdateVariable(Nvar,Info);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexInit
+//
+// Description: This function allocates memory for Var Index Buffer and fils pointer to it in
+// VarIndexPtr stucture
+//
+// Input: NONE
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexInit()
+{
+ EFI_STATUS Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ VARIABLE_INDEX_SIZE,
+ &VarIndexPtr->Buffer
+ );
+
+ if (EFI_ERROR(Status))
+ {
+ VarIndexPtr=NULL;
+ return;
+ }
+ VarIndexPtr->BufferSize = VARIABLE_INDEX_SIZE;
+ IndexReset();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IndexExitBs
+//
+// Description: This function resets VarIndexPtr to NULL on Exit BS
+//
+// Input: NONE
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID IndexExitBs()
+{
+ VarIndexPtr = NULL;
+}
+
+VOID IndexVirtualFixup()
+{
+
+}
+#endif
+///////////////////////////////////////////////////////////////////////////
+//Basic operations
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsEnoughSpace
+//
+// Description: This function checks is there is Size space avaiable in NVRAM_STORE_INFO
+//
+// Input: NVRAM_STORE_INFO* Info - pointer to NVRAM_STORE_INFO stucture
+// UINTN Size - Size to check for
+//
+// Output: BOOLEAN - TRUE if space avaiable, FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsEnoughSpace(NVRAM_STORE_INFO* Info, UINTN Size)
+{
+ return ( Info->pEndOfVars + Size
+ <= Info->NvramAddress+Info->NvramSize - sizeof(EFI_GUID)*(Info->NextGuid+1) - sizeof(NVAR)
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecoverFromFlashUpdateFailure
+//
+// Description: This function checks is there was a flash update failure and signal about it
+// to CheckStore
+//
+// Input: NVRAM_STORE_INFO* Info - pointer to NVRAM_STORE_INFO stucture
+// VOID *EndOfVars - End of Vars pointer
+// UINTN DataSize - Size of data, that was programed
+// NVAR *PrevVar - pointer to previous instance of Var
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RecoverFromFlashUpdateFailure(
+ NVRAM_STORE_INFO *Info, VOID *EndOfVars, UINTN DataSize, NVAR *PrevVar
+)
+{
+ UINT8 *p;
+ NVAR *NewVar;
+
+ //Nothing has been programmed. Just return
+ if (EndOfVars==Info->pEndOfVars) return;
+
+ NewVar = (NVAR*)Info->pEndOfVars;
+ //Check if variable size has been programmed correctly
+ if (NewVar->size==DataSize)
+ {
+ // Let's see if the signature is correct.
+ // If the signature is correct, let's see if
+ // the 'next' field has been properly updated.
+ if ( NewVar->signature==NvramSignature
+ && NvGetDataNvar(PrevVar, Info) != NewVar
+ ){
+ // if we are here, the next field has not been properly udpated
+ // leave pInfo->pEndOfVars at the address of the last record.
+ Info->LastVarSize=(VAR_SIZE_TYPE)DataSize;
+ return;
+ }
+ //Yes, the size has been programmed correctly.
+ //NvGetNextNvar routine is smart enough to skip
+ //invalid records with valid size.
+ Info->pEndOfVars+=DataSize;//Update Info->pEndOfVars
+ Info->LastVarSize=0;//Opearaion failed, set Info->LastVarSize to zero
+ return;
+ }
+
+ //check if something has actually been programmed
+ for (p=Info->pEndOfVars; p<(UINT8*)EndOfVars && *p==FLASH_EMPTY_BYTE; p++) ;
+
+ //if nothing has been programmed, just return
+ if (p==EndOfVars) return;
+
+ //if we reached this point, NVRAM store is corruped
+ //Set pInfo->pEndOfVars at the address of corruption.
+ //This will trigger recovery operation
+ //(See 'Error Recovery' section at the end of the DxeSetVariable routine).
+ Info->pEndOfVars = p;
+ Info->LastVarSize=(VAR_SIZE_TYPE)DataSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetVarAuthExtFlags
+//
+// Description: This function returns Security fields Mc and KeyHash form existing
+// Var in Var store
+// It is called called every time variable with one of
+// UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES is being verified.
+//
+// Input: NVAR *Var pointer to the 1st instance of Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT EXT_SEC_FLAGS->MonotonicCount - value of MC or TIME stamp
+// OUT EXT_SEC_FLAGS->KeyHash - pointer to memory, allocated by caller,
+// where Hash of PublicKeyDigest will be returned.
+//
+// Output: *EXT_SEC_FLAGS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetVarAuthExtFlags(
+ IN NVAR *Var,
+ IN NVRAM_STORE_INFO *pInfo,
+ OUT EXT_SEC_FLAGS *ExtFlags
+)
+{
+ if(Var==NULL || pInfo==NULL || ExtFlags==NULL)
+ return;
+// Return Authenticate attributes along with NonVolitile attrib
+ if ( pInfo->Flags & NVRAM_STORE_FLAG_NON_VALATILE )
+ ExtFlags->AuthFlags |=EFI_VARIABLE_NON_VOLATILE;
+
+ if(Var->flags & (NVRAM_FLAG_AUTH_WRITE | NVRAM_FLAG_EXT_HEDER)) {
+ ExtFlags->AuthFlags |= (UINT8)(*NvGetExtFlags (Var) & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES) ;//(NVRAM_eFLAG_TIME_BASED_AUTH_WRITE | NVRAM_eFLAG_AUTH_WRITE));
+ ExtFlags->Mc = (*(UINT64*)(NvGetExtFlags (NvGetDataNvar(Var, pInfo)) + 1));
+ MemCpy(&ExtFlags->KeyHash[0], (VOID*)(NvGetExtFlags (Var) + 1 + 8), HASH_SHA256_LEN);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlashMemFlashWrite
+//
+// Description: This function used to copy some information from one part of
+// flash to another, when flash is not memory mapped. It uses temporary
+// buffer one or more times.
+//
+// Input: IN VARIABLE_INTERFACE *Interface - pointer to Variable interface
+// IN OUT UINT8 **PointerTo - Destination
+// IN VOID *From - Source
+// IN UINTN SizeToWrite - in bytes.
+// IN NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO stucture
+//
+// Output: *EXT_SEC_FLAGS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FlashMemFlashWrite(
+ IN VARIABLE_INTERFACE *Interface,
+ IN OUT UINT8 **PointerTo,
+ IN VOID *From,
+ IN UINTN SizeToWrite,
+ IN NVRAM_STORE_INFO *Info
+)
+{
+ UINT8 TempMemory [256];
+ UINT8 *TempFrom = (UINT8*)From;
+ UINT16 TempSize;
+ BOOLEAN Result;
+
+ do
+ {
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+ if (SizeToWrite <= 256)
+ TempSize = (UINT16) SizeToWrite;
+ else
+ {
+ TempSize = 256;
+ SizeToWrite -= 256;
+ }
+ MemCpy(TempMemory, TempFrom, TempSize);
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+ Result = Interface->WriteBytes(*PointerTo, TempSize, TempMemory);
+ *PointerTo += TempSize;
+ if ((TempSize < 256) || (SizeToWrite == 0) || !Result) break;
+ TempFrom += TempSize;
+ }
+ while (TRUE);
+ return Result;
+}
+#if AuthVariable_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindVariable
+//
+// Description: This function searches for Var with specific GUID and Name
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var is loacted
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes ,
+ IN OUT UINTN *DataSize, OUT VOID **Data
+)
+{
+ UINTN VariableNameSize;
+ NVRAM_STORE_INFO *Info;
+ NVAR *Nvar;
+
+ Info = VarStoreInfo.NvInfo;
+ Nvar = (NVAR*)NvFindVariable(VariableName,VendorGuid,&VariableNameSize,Info);
+
+ if ((Nvar != NULL) && (Data != NULL))
+ {
+// if (Runtime && !(Nvar->flags & NVRAM_FLAG_RUNTIME)) return EFI_NOT_FOUND;
+ if (Attributes)
+ if (EFI_ERROR(NvGetAttributesFromNvar(Nvar, Info, Attributes)))
+ return EFI_NOT_FOUND;
+
+ *Data = (UINT8*)NvGetData(Nvar, VariableNameSize, DataSize, Info);
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateVariableEx
+//
+// Description: This function adds new variable to Varstore
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINT32 Attributes - attributes of Variable
+// IN UINTN DataSize - size of Var data
+// IN VOID *Data - pointer to the Var data
+// OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+// (OPTIONAL) NVAR* OldVar - in case of garbage collection pointer to the first i
+// nstance of variable to get Monotonic Counter and Flags from
+// (OPTIONAL) NVRAM_STORE_INFO *FromInfo - in case of garbage collection pointer to the
+// store info strucrure - to get Public Key from
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateVariableEx(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data,
+ NVRAM_STORE_INFO *Info, VARIABLE_INTERFACE *Interface, OPTIONAL NVAR* OldVar, EXT_SEC_FLAGS *ExtSecFlags,
+ OPTIONAL VOID *AppendData, OPTIONAL UINTN AppendDataSize
+)
+{
+ UINTN Size=sizeof(NVAR) + AppendDataSize, ExtSize = 0;
+ NVAR Var = {FLASH_EMPTY_SIGNATURE,0,FLASH_EMPTY_NEXT,NVRAM_FLAG_VALID};
+ CHAR16* s;
+ EFI_GUID* Guid;
+ INT16 guid=0;
+ BOOLEAN ok;
+ UINT8 *p, *p1, Dummy, ExtFlags = 0;
+
+ if (Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
+ Var.flags |= NVRAM_FLAG_RUNTIME;
+#if AuthVariable_SUPPORT
+ if ( Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD )
+ Var.flags |= NVRAM_FLAG_HARDWARE_ERROR_RECORD;
+ if (Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES/*EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS*/)
+ {
+ Var.flags |= NVRAM_FLAG_EXT_HEDER | NVRAM_FLAG_AUTH_WRITE;
+ ExtSize = 1 + 8 + HASH_SHA256_LEN + 2; //ExtFlags + Monotonic Counter + PublicKeyDigest Hash + ExtSize
+ ExtFlags |= Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES;
+ // We store PublicKeyDigest Hash only in the first instance of Var in store to save space
+ }
+#endif
+ if (NvramChecksumSupport)
+ {
+ Var.flags |= NVRAM_FLAG_EXT_HEDER;
+ if (ExtSize == 0) ExtSize += 4; // ExtSize - Ext Flag, Checksumm and Size
+ else ExtSize += 1; // Add Checksumm Feild
+ ExtFlags |= NVRAM_EXT_FLAG_CHECKSUM;
+ }
+
+ //find GUID in the GUID area
+ for ( Guid=Info->NvramGuidsAddress
+ ; Guid>Info->NvramGuidsAddress-Info->NextGuid
+ && guidcmp(Guid,VendorGuid)
+ ; Guid--
+ ) guid++;
+
+ if (((OldVar != NULL) && (OldVar->flags & NVRAM_FLAG_GUID)) || (Info->NextGuid>255 && guid>=Info->NextGuid))
+ {
+ Var.flags |= NVRAM_FLAG_GUID;
+ Size+=sizeof(EFI_GUID);
+ }
+
+ else
+ {
+ Size+=1;
+ }
+
+ //Alalize the name. Check if it has non basic Latin characters
+ for (s=VariableName; *s&&!*((CHAR8*)s+1); s++) ;
+
+ if (!*s)
+ {
+ Var.flags |= NVRAM_FLAG_ASCII_NAME;
+ Size+=s-VariableName+1;
+ }
+
+ else
+ {
+ while (*s++);
+
+ Size+=(UINT8*)s-(UINT8*)VariableName;
+ }
+ if ((UINTN)(~0) - Size < DataSize + ExtSize)
+ return EFI_OUT_OF_RESOURCES;
+
+ Size += DataSize + ExtSize;
+
+ if (!IsEnoughSpace(Info,Size)) return EFI_OUT_OF_RESOURCES;
+
+ Var.size=(VAR_SIZE_TYPE)Size;
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+ p = Info->pEndOfVars;
+
+ do
+ {
+ //Program Var at pEndOfVars
+ ok=Interface->WriteBytes(p,sizeof(NVAR),&Var);
+ p += sizeof(NVAR);
+
+ if (!ok) break;
+
+ //Program Guid
+ if (Var.flags&NVRAM_FLAG_GUID)
+ {
+ //program the whole guid
+ ok=Interface->WriteBytes(p,sizeof(EFI_GUID),VendorGuid);
+ p+=sizeof(EFI_GUID);
+ }
+
+ else
+ {
+ //program the whole guid at NVRAM_GUIDS_ADDRESS - NextGuid
+ if (guid==Info->NextGuid)
+ {
+ ok=Interface->WriteBytes(
+ (UINT8*)(Info->NvramGuidsAddress-Info->NextGuid),
+ sizeof(EFI_GUID),VendorGuid
+ );
+ Info->NextGuid++;
+
+ if (!ok) break;
+ }
+
+ //program guid(1 byte) at pEndOfVars+sizeof(NVAR);
+ ok=Interface->WriteBytes(p++,1,&guid);
+ }
+
+ if (!ok) break;
+
+ //Program name and data
+ if (Var.flags&NVRAM_FLAG_ASCII_NAME)
+ {
+ UINT8* q;
+
+ for (q=(UINT8*)VariableName; *(CHAR16*)q && ok ; q+=2,p++)
+ ok = Interface->WriteBytes(p,1,q);
+
+ if (ok) ok = Interface->WriteBytes(p++,1,q); //zero at end
+ }
+
+ else
+ {
+ UINT16* q;
+
+ for (q=VariableName; *q && ok ; q++,p+=2)
+ ok = Interface->WriteBytes(p,2,q);
+
+ if (ok)
+ {
+ ok = Interface->WriteBytes(p,2,q); //zero at end
+ p+=2;
+ }
+ }
+
+ if (!ok) break;
+
+ //AppendWrite after Garbage collection
+ if (Attributes & EFI_VARIABLE_APPEND_WRITE) {
+ if (FlashNotMemoryMapped){
+ ok=FlashMemFlashWrite(Interface, &p, AppendData, AppendDataSize, Info);
+ }
+ else
+ {
+ ok=Interface->WriteBytes(p,AppendDataSize,AppendData);
+ p+=AppendDataSize;
+ }
+ if (!ok) break;
+ }
+
+ //Program data
+ ok=Interface->WriteBytes(p,DataSize,Data);
+ p+=DataSize;
+ p1=p;
+
+ if (!ok) break;
+
+ //---Fill Ext area---
+ if (Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES/*EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS*/)
+ {
+ ok=Interface->WriteBytes(p, 1, &ExtFlags);//--Ext Flag
+ if (!ok) break;
+ p += 1;
+ ok=Interface->WriteBytes(p, 8, &ExtSecFlags->Mc);//--Monotonic counter
+ if (!ok) break;
+ p += 8;
+ ok=Interface->WriteBytes(p, HASH_SHA256_LEN, &ExtSecFlags->KeyHash[0]);//--Public Key Hash
+ if (!ok) break;
+ p = Info->pEndOfVars + Size - 2;
+ ok=Interface->WriteBytes(p, 2,&ExtSize);//--Ext Size
+ if (!ok) break;
+ }
+ if (NvramChecksumSupport)
+ {
+ if (!(Var.flags & NVRAM_FLAG_AUTH_WRITE)) // ???NVRAM_FLAG_EXT_HEDER
+ {
+ p = p1 + ExtSize;
+ //write ExtSize
+ ok=Interface->WriteBytes(p-sizeof(VAR_SIZE_TYPE),sizeof(VAR_SIZE_TYPE),&ExtSize);
+ if (!ok) break;
+ //write ExtFlags
+ ok=Interface->WriteBytes(p1, 1, &ExtFlags);
+ if (!ok) break;
+ //write checksum
+ if (FlashNotMemoryMapped)
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ Dummy = NvCalculateNvarChecksum((NVAR*)Info->pEndOfVars);
+
+ if (FlashNotMemoryMapped)
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ //adjust to exclude empty checksum field
+ Dummy += FLASH_EMPTY_BYTE;
+ ok=Interface->WriteBytes(p-3, 1, &Dummy);
+ if (!ok) break;
+ }
+ else
+ {
+ p = p1 + ExtSize;
+ if (FlashNotMemoryMapped)
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ Dummy = NvCalculateNvarChecksum((NVAR*)Info->pEndOfVars);
+
+ if (FlashNotMemoryMapped)
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+ //adjust to exclude empty checksum field
+ Dummy += FLASH_EMPTY_BYTE;
+ ok=Interface->WriteBytes(p-3, 1, &Dummy);
+ if (!ok) break;
+ }
+ }
+ //write a signature
+ ok=Interface->WriteBytes(
+ Info->pEndOfVars,sizeof(NvramSignature),(VOID*)&NvramSignature
+ );
+
+ }
+ while (FALSE);
+
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ if (ok)
+ {
+ Info->pEndOfVars += Size;
+ Info->LastVarSize=(VAR_SIZE_TYPE)Size;
+ }
+
+ else
+ {
+ RecoverFromFlashUpdateFailure(Info,p,Size,(NVAR*)Info->pEndOfVars);
+ }
+
+ return (ok) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+EFI_STATUS CreateVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data,
+ NVRAM_STORE_INFO *Info, VARIABLE_INTERFACE *Interface, OPTIONAL NVAR* OldVar, EXT_SEC_FLAGS *ExtSecFlags
+)
+{
+ return CreateVariableEx(VariableName, VendorGuid, Attributes, DataSize,
+ Data, Info, Interface, OldVar, ExtSecFlags, NULL, 0);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateVariable
+//
+// Description: This function updates variable
+//
+// Input: IN NVAR *OldVar - pointer to the old Var
+// IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN UINTN NameSize - size of the Var mane
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINT32 Attributes - attributes of Variable
+// IN UINTN DataSize - size of Var data
+// IN VOID *Data - pointer to the Var data
+// OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateVariable(
+ IN NVAR *OldVar, IN CHAR16 *VariableName, IN UINTN NameSize,
+ IN EFI_GUID *VendorGuid, IN UINT32 Attributes,
+ IN UINTN DataSize, IN VOID *Data,
+ IN OUT VAR_INDEX_ENTRY *OldVarEntry OPTIONAL,
+ IN EXT_SEC_FLAGS *ExtSecFlags,
+ NVRAM_STORE_INFO *Info, VARIABLE_INTERFACE *Interface
+)
+{
+ UINTN OldDataSize;
+ VOID *OldData;
+ BOOLEAN ok;
+ UINTN Size, ExtSize = 0;
+ NVAR Var = {FLASH_EMPTY_SIGNATURE,0,FLASH_EMPTY_NEXT,NVRAM_FLAG_VALID|NVRAM_FLAG_DATA_ONLY};
+ UINT8 *p, *p1, Dummy, ExtFlags = 0;
+
+ if (!NvAttribEq(OldVar,Attributes,Info)) return EFI_INVALID_PARAMETER;
+
+ if (OldVarEntry != NULL && OldVarEntry->FinalDataNvar != NULL)
+ OldData = NvGetData( OldVarEntry->FinalDataNvar, NameSize, &OldDataSize, Info );
+ else
+ OldData = NvGetData( OldVar, NameSize, &OldDataSize, Info );
+
+ if (Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES/*EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS*/)
+ {
+ Var.flags |= NVRAM_FLAG_EXT_HEDER | NVRAM_FLAG_AUTH_WRITE;
+ ExtSize = 1 + 8 + 2; //ExtFlags + Monotonic Counter + ExtSize
+ // AuthFlags only set in 1st instance
+ // ExtFlags |= Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES;
+ }
+ //if new data equal to the old data don't do anything
+ if (NvramChecksumSupport)
+ { ExtFlags |= NVRAM_EXT_FLAG_CHECKSUM;
+ if (ExtSize == 0) ExtSize += 4; // ExtSize - Ext Flag, Checksumm and Size
+ else ExtSize += 1; // Add Checksumm Feild
+ if ( (Attributes & EFI_VARIABLE_APPEND_WRITE) == 0
+ && OldDataSize == DataSize && !MemCmp(OldData, Data, DataSize)
+ && (OldVar->flags & NVRAM_FLAG_EXT_HEDER))
+ return EFI_SUCCESS;
+ else Var.flags |= NVRAM_FLAG_EXT_HEDER;
+ }
+ else
+ if ( (Attributes & EFI_VARIABLE_APPEND_WRITE) == 0
+ && OldDataSize == DataSize && !MemCmp(OldData, Data, DataSize))
+ return EFI_SUCCESS;
+
+ // Append write implementation
+ if (Attributes & EFI_VARIABLE_APPEND_WRITE)
+ Size=sizeof(NVAR)+ OldDataSize + DataSize + ExtSize;
+ else
+ Size=sizeof(NVAR)+ DataSize + ExtSize;
+
+ if (!IsEnoughSpace(Info,Size)) return EFI_OUT_OF_RESOURCES;
+
+ Var.size=(VAR_SIZE_TYPE)Size;
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+ p = Info->pEndOfVars;
+
+ //Program Var at pEndOfVars
+ do
+ {
+ ok=Interface->WriteBytes(p,sizeof(NVAR),&Var);
+ p += sizeof(NVAR);
+
+ if (!ok) break;
+
+ //Program data
+ //AppendWrite
+ if (Attributes & EFI_VARIABLE_APPEND_WRITE) {
+ if (FlashNotMemoryMapped){
+ ok=FlashMemFlashWrite(Interface, &p, OldData, OldDataSize, Info);
+ }
+ else
+ {
+ ok=Interface->WriteBytes(p,OldDataSize,OldData);
+ p+=OldDataSize;
+ }
+ if (!ok) break;
+ }
+ // end Append write
+ ok=Interface->WriteBytes(p,DataSize,Data);
+ p+=DataSize;
+ p1 = p;
+ if (!ok) break;
+
+ //---Fill Ext area---
+ if (Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES/*EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS*/)
+ {
+ ok=Interface->WriteBytes(p, 1, &ExtFlags);//--Ext Flag
+ if (!ok) break;
+ p += 1;
+ ok=Interface->WriteBytes(p, 8, &ExtSecFlags->Mc);//--Monotonic counter
+ if (!ok) break;
+ p = Info->pEndOfVars + Size - 2;
+ ok=Interface->WriteBytes(p, 2,&ExtSize);//--Ext Size
+ if (!ok) break;
+ }
+ if (NvramChecksumSupport)
+ {
+ if (!(Var.flags & NVRAM_FLAG_AUTH_WRITE)) // ??? should be ExtFlags?
+ {
+ p = p1 + ExtSize;
+ //write ExtSize
+ ok=Interface->WriteBytes(p-sizeof(VAR_SIZE_TYPE),sizeof(VAR_SIZE_TYPE),&ExtSize);
+ if (!ok) break;
+ //write ExtFlags
+ ok=Interface->WriteBytes(p-ExtSize, 1, &ExtFlags);
+ if (!ok) break;
+ //write checksum
+ if (FlashNotMemoryMapped)
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ Dummy = NvCalculateNvarChecksum((NVAR*)Info->pEndOfVars);
+
+ if (FlashNotMemoryMapped)
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ //adjust to exclude empty checksum field
+ Dummy += FLASH_EMPTY_BYTE;
+ ok=Interface->WriteBytes(p-3, 1, &Dummy);
+ if (!ok) break;
+ }
+ else
+ {
+ p = p1 + ExtSize;
+ if (FlashNotMemoryMapped)
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ Dummy = NvCalculateNvarChecksum((NVAR*)Info->pEndOfVars);
+
+ if (FlashNotMemoryMapped)
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ //adjust to exclude empty checksum field
+ Dummy += FLASH_EMPTY_BYTE;
+ ok=Interface->WriteBytes(p-3, 1, &Dummy);
+ if (!ok) break;
+ }
+ }
+ //write a signature
+ ok=Interface->WriteBytes(Info->pEndOfVars,sizeof(NvramSignature),(VOID*)&NvramSignature);
+
+ if (!ok) break;
+ //set Var.next;
+
+ if (FlashNotMemoryMapped)
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ if (OldVarEntry != NULL && OldVarEntry->FinalDataNvar != NULL)
+ OldVar=OldVarEntry->FinalDataNvar;
+ else
+ OldVar=NvGetDataNvar(OldVar,Info);
+
+ if (FlashNotMemoryMapped)
+ Interface->EnableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ Var.next=(UINT32)(Info->pEndOfVars-(UINT8*)OldVar);
+ ok=Interface->WriteBytes((UINT8*)OldVar+NEXT_OFFSET,NEXT_SIZE,(UINT8*)&Var+NEXT_OFFSET);
+ }
+ while (FALSE);
+
+ Interface->DisableUpdate(Info->NvramAddress,Info->NvramSize);
+
+ if (ok)
+ {
+ if (OldVarEntry != NULL)
+ OldVarEntry->FinalDataNvar = (NVAR*)Info->pEndOfVars;
+ Info->pEndOfVars += Size;
+ Info->LastVarSize=(VAR_SIZE_TYPE)Size;
+ }
+
+ else
+ {
+ RecoverFromFlashUpdateFailure(Info,p,Size,OldVar);
+ }
+
+ return (ok) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteVariable
+//
+// Description: This function delets variable
+//
+// Input: IN NVAR *Var - pointer to the Var to be deleted
+// OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DeleteVariable(IN NVAR *Var, NVRAM_STORE_INFO *Info, VARIABLE_INTERFACE *Interface)
+{
+ UINT8 flag = Var->flags^NVRAM_FLAG_VALID;//invert validity bit
+ BOOLEAN ok;
+ CHAR8 *WriteAddress = (UINT8*)Var+FLAG_OFFSET;
+ UINTN WriteSize = FLAG_SIZE;
+ Interface->EnableUpdate(WriteAddress,WriteSize);
+ ok=Interface->WriteBytes(WriteAddress,WriteSize,&flag);
+ Interface->DisableUpdate(WriteAddress,WriteSize);
+ return (ok) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyVariable
+//
+// Description: This function copyes variable from one Nvram store to another
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINTN DataSize - size of Var data
+// IN VOID *Data - pointer to the Var data temprary storadge
+// OUT NVRAM_STORE_INFO *FromInfo - pointer to NVRAM_STORE_INFO structure to copy from
+// OUT NVRAM_STORE_INFO *ToInfo - pointer to NVRAM_STORE_INFO structure to copy to
+// VARIABLE_INTERFACE *ToInterface - pointer to the interface with the Variable routins
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CopyVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+//Buffer used for temporary variable data storage
+ IN UINTN DataSize, IN VOID *Data,
+ NVRAM_STORE_INFO *FromInfo, NVRAM_STORE_INFO *ToInfo,
+ VARIABLE_INTERFACE *ToInterface
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes;
+ NVAR *nVar;
+ EXT_SEC_FLAGS ExtSecFlags = {0,0,{0}};
+
+ Status = NvGetVariable(
+ VariableName, VendorGuid, &Attributes, &DataSize, Data,
+ FromInfo, &nVar
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ GetVarAuthExtFlags(nVar, FromInfo, &ExtSecFlags);
+
+ if (nVar->flags & NVRAM_FLAG_AUTH_WRITE)
+ return CreateVariable(
+ VariableName, VendorGuid, Attributes, DataSize, Data,
+ ToInfo, ToInterface, nVar, &ExtSecFlags);
+ else
+ return CreateVariable(
+ VariableName, VendorGuid, Attributes, DataSize, Data,
+ ToInfo, ToInterface, nVar, NULL);
+}
+
+//Varstore maintenance
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarNotInPreserveList
+//
+// Description: Looks for the provided variable in the preserved list.
+//
+// Input: IN CHAR16 *VarName - Variable name to be found.
+// IN EFI_GUID *Guid - Variable GUID to be found.
+//
+// Output: BOOLEAN - Depending on result.
+// TRUE - if not in list, FALSE - if in list.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN VarNotInPreserveList(
+ IN CHAR16 *VarName,
+ IN EFI_GUID *Guid
+)
+{
+ SDL_VAR_ENTRY *Entry;
+ UINTN Index;
+ if (VarName == NULL || Guid == NULL)
+ return TRUE; // If it has no name or GUID - it is not in the list
+ // Determine the size in bytes of the variable name string.
+
+
+ // Scan list
+ for (Index = 0, Entry = gSdlVarLst;
+ Entry->Name != NULL;
+ Entry = &gSdlVarLst[++Index] )
+ {
+ // Check the GUID's for a match.
+ if (!guidcmp(&Entry->Guid, Guid)) {
+ //NVRAM_TRACE((TRACE_DXE_CORE,"VarNotInPreserveList: GUID Match found.\n"));
+ // Compare variable name strings.
+ if (Wcscmp(Entry->Name, VarName) == 0){
+ //NVRAM_TRACE((TRACE_DXE_CORE,"VarNotInPreserveList: Compleat Match found!!!.\n"));
+ // Match found!
+ return FALSE;
+ }
+ }
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarNotInEfiGlobalVarList
+//
+// Description: Searches for the passed variable in the EFI Global Var lists and
+// if found, makes sure, that it has the same attributes.
+//
+// Input: IN CHAR16 *VarName - Variable name to be found.
+// IN UINT32 Attributes - Variable attributes.
+//
+// Output: BOOLEAN - Depending on result.
+// TRUE - if not in list, FALSE - if in list.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN VarNotInEfiGlobalVarList (
+ IN CHAR16 *VariNameToTest,
+ IN UINT32 Attributes
+ )
+{
+ UINT32 i, j;
+ UINTN CommonLength;
+
+
+ // Search through list where names are strictly predefined
+ for (i = 0; gStdEfiVarList[i].Name != NULL; i ++)
+ {
+ if ((Wcscmp(gStdEfiVarList[i].Name, VariNameToTest) == 0) &&
+ (gStdEfiVarList[i].Attributes == Attributes || Attributes == 0))
+ return FALSE;
+ }
+
+ // Look in the list where names could have 4 different hexadecimal numbers at the end
+ CommonLength = Wcslen(VariNameToTest) - 4; // Subtract 4 last characters, that can be different from those, that are in list
+ for (i = 0; gStdEfiVarListWildCard[i].Name != NULL; i ++)
+ {
+ if ((CommonLength + 4 == Wcslen(gStdEfiVarListWildCard[i].Name)) &&
+ (MemCmp(gStdEfiVarListWildCard[i].Name, VariNameToTest, CommonLength * sizeof(CHAR16)) == 0) &&
+ (gStdEfiVarListWildCard[i].Attributes == Attributes || Attributes == 0))
+ {
+
+ for (j = 0; j < 4;)
+ {
+ // if 4 lasrt characters are not hexadecimal numbers - this is not a legal Efi Global Variable
+ if ((VariNameToTest[CommonLength + j] >= L'0' && VariNameToTest[CommonLength + j] <= L'9') ||
+ (VariNameToTest[CommonLength + j] >= L'a' && VariNameToTest[CommonLength + j] <= L'f') ||
+ (VariNameToTest[CommonLength + j] >= L'A' && VariNameToTest[CommonLength + j] <= L'F'))
+ j ++;
+ else
+ return TRUE;
+
+ }
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SkipSpecificNvar
+//
+// Description: Helper varstore filtering function.
+// Skips the variable that corresponds to the passed in NVAR.
+//
+// Output: BOOLEAN
+// TRUE - skip the variable
+// FALSE - do not skip the variable
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SkipSpecificNvar(
+ NVAR *SkipVar, CHAR16* VarName, EFI_GUID* VarGuid,
+ NVRAM_STORE_INFO *Info
+){
+ return SkipVar!=NULL && NvVarEq(SkipVar, VarName, VarGuid, NULL, Info);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SkipVarsWithDefaults
+//
+// Description: Helper varstore filtering function.
+// Skips the variables that have defaults.
+//
+// Output: BOOLEAN
+// TRUE - skip the variable
+// FALSE - do not skip the variable
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SkipVarsWithDefaults(
+ NVRAM_STORE_INFO *DefInfo, CHAR16* VarName, EFI_GUID* VarGuid,
+ NVRAM_STORE_INFO *Info
+){
+ return DefInfo!=NULL
+ && ( Wcscmp(VarName, (CHAR16*)StdDefaults)==0
+ || Wcscmp(VarName, (CHAR16*)MfgDefaults)==0
+ || NvFindVariable(VarName, VarGuid, NULL, DefInfo) != NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyVariables
+//
+// Description: This function copies variables from one varstore to another
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure to copy from
+// OUT NVRAM_STORE_INFO *NewInfo - pointer to NVRAM_STORE_INFO structure to copy to
+// VARIABLE_INTERFACE *NewInterface - pointer to the interface with the update routins
+// COPY_VAR_STORE_FILTER FilterFunction - filtering function
+// VOID *FilterContext - filtering function context
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CopyVariables(
+ IN NVRAM_STORE_INFO* Info,
+ OUT NVRAM_STORE_INFO *NewInfo,
+ VARIABLE_INTERFACE *NewInterface,
+ COPY_VAR_STORE_FILTER FilterFunction,
+ VOID *FilterContext
+)
+{
+ EFI_STATUS Status;
+ VOID *TmpBuffer, *TmpData;
+ CHAR16 *TmpName;
+ UINTN NvramSize = Info->NvramSize;
+ EFI_GUID Guid;
+
+ TmpBuffer = SelectiveAllocate (TRUE, NvramSize*2);
+
+ if (TmpBuffer==NULL) return EFI_OUT_OF_RESOURCES;
+
+ TmpName = TmpBuffer; TmpData = (UINT8*)TmpBuffer+NvramSize;
+ TmpName[0]=0;
+
+ //Copy variables
+ do
+ {
+ UINTN Size = NvramSize;
+ Status = NvGetNextVariableName(
+ &Size, TmpName, &Guid, Info, FALSE
+ );
+
+ if (EFI_ERROR(Status)) break;
+
+ //check if the variable needs to be skipped
+ if ( FilterFunction!=NULL
+ && FilterFunction(FilterContext, TmpName, &Guid, Info)
+ ) continue;
+ if (SaveOnlyPreservedVars && VarNotInPreserveList(TmpName, &Guid))
+ continue;
+ Status=CopyVariable(
+ TmpName, &Guid, NvramSize, TmpData, Info, NewInfo, NewInterface
+ );
+
+ if (EFI_ERROR(Status))
+ {
+ if (Status==EFI_NOT_FOUND) continue;
+ SelectiveFree (TmpBuffer);
+ SaveOnlyPreservedVars = FALSE;
+ return Status;
+ }
+ }
+ while (TRUE);
+
+ SelectiveFree (TmpBuffer);
+
+ if (Status==EFI_NOT_FOUND) Status=EFI_SUCCESS;
+ SaveOnlyPreservedVars = FALSE;
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyVarStore
+//
+// Description: This function copyes varstore to a new location
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure to copy from
+// OUT NVRAM_STORE_INFO *NewInfo - pointer to NVRAM_STORE_INFO structure to copy to
+// VARIABLE_INTERFACE *NewInterface - pointer to the interface with the update routins
+// COPY_VAR_STORE_FILTER FilterFunction - filtering function
+// VOID *FilterContext - filtering function context
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CopyVarStore(
+ IN NVRAM_STORE_INFO* Info,
+ OUT NVRAM_STORE_INFO *NewInfo,
+ VARIABLE_INTERFACE *NewInterface,
+ COPY_VAR_STORE_FILTER FilterFunction,
+ VOID *FilterContext
+)
+{
+ BOOLEAN ok;
+
+ //This function assumes that the following
+ //fields of NewInfo have been initialized:
+ // NvramAddress, NvramSize, NvramGuidsAddress, Flags
+ if ((Runtime) && (!NvramDriverBuffer)) return EFI_OUT_OF_RESOURCES;
+
+ NewInterface->EnableUpdate(NewInfo->NvramAddress,NewInfo->NvramSize);
+ ok=NewInterface->EraseBytes(NewInfo->NvramAddress,NewInfo->NvramSize);
+ NewInterface->DisableUpdate(NewInfo->NvramAddress,NewInfo->NvramSize);
+ NewInfo->pFirstVar = NewInfo->NvramAddress + VarStoreInfo.HeaderLength;
+ NewInfo->pEndOfVars = NewInfo->pFirstVar;
+ NewInfo->LastVarSize = 0;
+ NewInfo->pLastReturned = NULL;
+ NewInfo->NextGuid = 0;
+
+ if (!ok) return EFI_DEVICE_ERROR;
+
+ //Copy the header
+ NewInterface->EnableUpdate(NewInfo->NvramAddress,NewInfo->NvramSize);
+ ok=NewInterface->WriteBytes(
+ NewInfo->NvramAddress,
+ VarStoreInfo.HeaderLength,
+ Info->NvramAddress
+ );
+ NewInterface->DisableUpdate(NewInfo->NvramAddress,NewInfo->NvramSize);
+
+ if (!ok) return EFI_DEVICE_ERROR;
+
+
+ return CopyVariables(Info,NewInfo,NewInterface,FilterFunction,FilterContext);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CopyVarStoreToMemStore
+//
+// Description: This function allocates memory copyes varstore to a new location
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure to copy from
+// IN NVAR* SkipVar - pointer to var to be skiped
+// OUT NVRAM_STORE_INFO *NewInfo - pointer to NVRAM_STORE_INFO structure which was created
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CopyVarStoreToMemStore(
+ IN NVRAM_STORE_INFO* Info,
+ IN NVAR* SkipVar, OUT NVRAM_STORE_INFO *NewInfo
+)
+{
+ EFI_STATUS Status;
+
+ if ((Runtime) && (!NvramDriverBuffer)) return EFI_OUT_OF_RESOURCES;
+ if (!Runtime) PROGRESS_CODE(DXE_NVRAM_CLEANUP);
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM Garbage Collection\n"));
+
+ Status = InitVolatileStore(
+ NewInfo, Info->NvramSize, VarStoreInfo.HeaderLength, Info->Flags, FALSE
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = CopyVarStore(
+ Info,NewInfo,&MemInterface,SkipSpecificNvar,SkipVar
+ );
+
+ if (EFI_ERROR(Status)) SelectiveFree (NewInfo->NvramAddress);
+ else CheckTheHeader(NewInfo, VarStoreInfo.HeaderLength, TRUE);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetNvramFfsFileState
+//
+// Description: This function updates State of Ffs file with new bits described by NewState
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+// EFI_FFS_FILE_STATE NewState - New state to update to
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetNvramFfsFileState(
+ NVRAM_STORE_INFO *Info, VARIABLE_INTERFACE *Interface,
+ EFI_FFS_FILE_STATE NewState
+)
+{
+ BOOLEAN ok;
+ EFI_FFS_FILE_STATE *StatePtr = GetNvramFfsFileStatePtr(Info);
+
+ if (StatePtr==NULL) return EFI_DEVICE_ERROR;
+
+ if (FlashEmpty!=0) NewState = ~NewState & *StatePtr;
+ else NewState |= *StatePtr;
+
+ Interface->EnableUpdate(StatePtr,sizeof(NewState));
+ ok = Interface->WriteBytes(StatePtr,sizeof(NewState),&NewState);
+ Interface->DisableUpdate(StatePtr,sizeof(NewState));
+ return (ok) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetFfsFileStateInMemory
+//
+// Description: This function sets State of Ffs file to new value described by NewState
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// EFI_FFS_FILE_STATE NewState - New state to set
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ResetFfsFileStateInMemory(
+ NVRAM_STORE_INFO *Info, EFI_FFS_FILE_STATE NewState
+)
+{
+ EFI_FFS_FILE_STATE *StatePtr = GetNvramFfsFileStatePtr(Info);
+
+ if (StatePtr==NULL) return EFI_DEVICE_ERROR;
+
+ if (FlashEmpty!=0) NewState = ~NewState;
+
+ *StatePtr = NewState;
+ return (*StatePtr == NewState) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckTheHeader
+//
+// Description: This function validates correctness of the header fields used by the driver
+// and fixes them if Update parameter is TRUE
+//
+// Input: IN NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure to check
+// IN UINT32 HeaderLength - length of the NVRAM header
+// IN BOOLEAN Update - If TRUE, invalid header will be updated to fix the problem
+//
+// Output: BOOLEAN
+// TRUE - No problems detected
+// FALSE - Problem(s) detected
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckTheHeader(NVRAM_STORE_INFO *Info, UINT32 HeaderLength, BOOLEAN Update){
+ BOOLEAN HeaderValid = TRUE;
+ EFI_FIRMWARE_VOLUME_HEADER *Fv = (EFI_FIRMWARE_VOLUME_HEADER*)Info->NvramAddress;
+
+ //check the signature
+ if ( Fv->Signature!=FV_SIGNATURE
+ || Fv->FvLength!=Info->NvramSize
+ || Fv->HeaderLength!=HeaderLength-sizeof(EFI_FFS_FILE_HEADER)
+ ){
+ if (Update){
+ Fv->Signature=FV_SIGNATURE;
+ Fv->FvLength=Info->NvramSize;
+ Fv->HeaderLength=(UINT16)(HeaderLength-sizeof(EFI_FFS_FILE_HEADER));
+ }
+ HeaderValid = FALSE;
+ }
+ if (!IsMainNvramStoreValid(Info, VarStoreInfo.BackupAddress, NULL)){
+ if (Update){
+ ResetFfsFileStateInMemory(
+ Info,
+ EFI_FILE_HEADER_CONSTRUCTION
+ | EFI_FILE_HEADER_VALID
+ | EFI_FILE_DATA_VALID
+ );
+ }
+ HeaderValid = FALSE;
+ }
+ return HeaderValid;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateFtVarstore
+//
+// Description: This function copyes Varstore to a new location and makes this copy main Varstore
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+// NVRAM_STORE_INFO* NewInfo - pointer to the new NVRAM_STORE_INFO Varstore
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateFtVarstore(
+ NVRAM_STORE_INFO* Info, VARIABLE_INTERFACE *Interface, NVRAM_STORE_INFO* NewInfo
+)
+{
+ NVRAM_STORE_INFO BackupInfo;
+ EFI_STATUS Status;
+
+ BackupInfo.NvramAddress = VarStoreInfo.BackupAddress;
+ BackupInfo.NvramSize = Info->NvramSize;
+ NvInitInfoBuffer(
+ &BackupInfo, VarStoreInfo.HeaderLength, Info->Flags
+ );
+// State Transitions:
+// Main Backup Valid Store
+// = Initial State After Firmware Flashing
+// 1. DATA_VALID HEADER_INVALID Main
+// = Update Cycle 1
+// 2. DATA_VALID HEADER_VALID Main
+// 3. MARKED_FOR_UPDATE HEADER_VALID Main
+// 4. MARKED_FOR_UPDATE DATA_VALID Backup
+// = Update Cycle 1 is Over
+// = Update Cycle 2
+// 5. HEADER_VALID DATA_VALID Backup
+// 6. HEADER_VALID MARKED_FOR_UPDATE Backup
+// 7. DATA_VALID MARKED_FOR_UPDATE Main
+// = Update Cycle 2 is Over
+// = Update Cycle 3
+// 8. DATA_VALID HEADER_VALID Main
+// Stae 8 == State 2
+ Status=ResetFfsFileStateInMemory(
+ NewInfo, EFI_FILE_HEADER_CONSTRUCTION|EFI_FILE_HEADER_VALID
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = CopyVarStore(NewInfo,&BackupInfo,Interface,NULL,NULL);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status=SetNvramFfsFileState(Info, Interface, EFI_FILE_MARKED_FOR_UPDATE);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ Status=SetNvramFfsFileState(&BackupInfo, Interface, EFI_FILE_DATA_VALID);
+
+ if (EFI_ERROR(Status)) return Status;
+#ifdef HYBRID_NV_INTERFACE
+ if (!SwapVarstoresInHybridMode(&BackupInfo)){
+#endif
+ VarStoreInfo.BackupAddress = Info->NvramAddress;
+#ifdef HYBRID_NV_INTERFACE
+ }
+#endif
+ *Info = BackupInfo;
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM areas swapped(NVRAM address: %X; Backup address: %X).\n", Info->NvramAddress, VarStoreInfo.BackupAddress));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateVarstore
+//
+// Description: This function copyes Varstore to a new location and makes this copy main Varstore
+// if old varstore flag has NVRAM_STORE_FLAG_NON_VALATILE and Backupadress is valid, else it
+// just copy Varstor to new location
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+// NVRAM_STORE_INFO* NewInfo - pointer to the new NVRAM_STORE_INFO Varstore
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateVarstore(
+ NVRAM_STORE_INFO* Info, VARIABLE_INTERFACE *Interface, NVRAM_STORE_INFO* NewInfo
+)
+{
+ EFI_STATUS Status;
+
+ if ( (Info->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ && VarStoreInfo.BackupAddress!=0
+ && CheckTheHeader(Info, VarStoreInfo.HeaderLength, FALSE)
+ )
+ {
+ Status = UpdateFtVarstore(Info,Interface,NewInfo);
+ }
+
+ else
+ {
+ Status = CopyVarStore(NewInfo,Info,Interface,NULL,NULL);
+ }
+
+ if (!EFI_ERROR(Status))
+ {
+ if (Info==VarStoreInfo.NvInfo) NvramReinitialize();
+
+#if NV_CACHE_SUPPORT
+ else IndexReset();
+
+#endif
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvResetConfiguration
+//
+// Description: This function resets NvRam configuration
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+// VARIABLE_INTERFACE *Interface - pointer to the interface with the Variable routins
+// BOOLEAN ExternalDefaults - if TRUE - use external defaults
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvResetConfiguration(
+ NVRAM_STORE_INFO* Info, VARIABLE_INTERFACE *Interface,
+ BOOLEAN ExternalDefaults, BOOLEAN PreserveVariablesWithNoDefaults
+)
+{
+ UINT16 HeaderLength = VarStoreInfo.HeaderLength;
+ NVRAM_STORE_INFO NewInfo;
+ NVRAM_STORE_INFO DefaultsInfo;
+ NVRAM_STORE_INFO *DefInfo = NULL;
+ EFI_STATUS Status;
+ VOID *TmpBuffer;
+ UINTN NvramSize = Info->NvramSize;
+ BOOLEAN HeaderIsValid;
+
+ PROGRESS_CODE(DXE_CONFIGURATION_RESET);
+ NVRAM_TRACE((TRACE_DXE_CORE,
+ "NVRAM Reset: ExternalDefaults=%d; PreserveVariablesWithNoDefaults=%d\n",
+ ExternalDefaults,PreserveVariablesWithNoDefaults
+ ));
+
+ Status = InitVolatileStore(
+ &NewInfo, Info->NvramSize, VarStoreInfo.HeaderLength, Info->Flags, FALSE
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ MemCpy(NewInfo.NvramAddress, Info->NvramAddress, HeaderLength);
+ HeaderIsValid = CheckTheHeader(&NewInfo, HeaderLength, TRUE);
+ if (!HeaderIsValid){
+ PreserveVariablesWithNoDefaults=FALSE;
+ NVRAM_TRACE((TRACE_DXE_CORE, "NVRAM Reset: NVRAM FV header is corrupted\n"));
+ }
+ if (ExternalDefaults)
+ {
+ // {9221315B-30BB-46b5-813E-1B1BF4712BD3}
+#define SETUP_DEFAULTS_FFS_GUID { 0x9221315b, 0x30bb, 0x46b5, { 0x81, 0x3e, 0x1b, 0x1b, 0xf4, 0x71, 0x2b, 0xd3 } }
+ static EFI_GUID SetupDefaultsFfsGuid = SETUP_DEFAULTS_FFS_GUID;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ EFI_HANDLE *FvHandle;
+ UINTN Number,i;
+ UINT32 Authentication;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,&gEfiFirmwareVolumeProtocolGuid, NULL, &Number, &FvHandle
+ );
+
+ for (i=0; i<Number; i++)
+ {
+ Status=pBS->HandleProtocol(FvHandle[i], &gEfiFirmwareVolumeProtocolGuid, &Fv);
+
+ if (EFI_ERROR(Status)) continue;
+
+ DefaultsInfo.NvramAddress=NULL;
+ DefaultsInfo.NvramSize=0;
+ Status=Fv->ReadSection (
+ Fv,&SetupDefaultsFfsGuid,
+ EFI_SECTION_RAW, 0,
+ &DefaultsInfo.NvramAddress, &DefaultsInfo.NvramSize,
+ &Authentication
+ );
+
+ if (!EFI_ERROR(Status))
+ {
+ NVRAM_TRACE((TRACE_DXE_CORE, "NVRAM: External Defaults Found: Size=%X\n",DefaultsInfo.NvramSize));
+ NvInitInfoBuffer(
+ &DefaultsInfo, 0,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ | NVRAM_STORE_FLAG_READ_ONLY
+ | NVRAM_STORE_FLAG_DO_NOT_ENUMERATE
+ );
+ DefInfo = &DefaultsInfo;
+ break;
+ }
+ }
+ }
+
+ else
+ {
+ DefaultsInfo.NvramAddress = NULL;
+ DefInfo = Info;
+ }
+
+ if (DefInfo!=NULL)
+ {
+ TmpBuffer = SelectiveAllocate (TRUE, NvramSize);
+
+ if (TmpBuffer==NULL)
+ {
+ SelectiveFree (NewInfo.NvramAddress);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ Status=CopyVariable(
+ (CHAR16*)StdDefaults, (EFI_GUID*)&AmiDefaultsVariableGuid,
+ NvramSize,TmpBuffer,DefInfo,&NewInfo,&MemInterface
+ );
+
+ if (Status!=EFI_OUT_OF_RESOURCES)
+ {
+ Status=CopyVariable(
+ (CHAR16*)MfgDefaults, (EFI_GUID*)&AmiDefaultsVariableGuid,
+ NvramSize,TmpBuffer,DefInfo,&NewInfo,&MemInterface
+ );
+ }
+
+ SelectiveFree (TmpBuffer);
+
+ if (PreserveVariablesWithNoDefaults){
+ NVRAM_STORE_INFO DefVarInfo;
+ if (NvGetDefaultsInfo(StdDefaults,DefInfo,&DefVarInfo) != NULL)
+ Status=CopyVariables(
+ Info, &NewInfo, &MemInterface, SkipVarsWithDefaults ,&DefVarInfo
+ );
+ }
+ if (DefaultsInfo.NvramAddress!=NULL )
+ {
+ pBS->FreePool(DefaultsInfo.NvramAddress);
+ }
+ // don't reset NVRAM if no defaults found
+ if (NewInfo.pEndOfVars == NewInfo.pFirstVar) DefInfo=NULL;
+ }
+
+ if ( Status!=EFI_OUT_OF_RESOURCES
+ && ( DefInfo!=NULL || !HeaderIsValid )
+ && ( Info->pEndOfVars - Info->NvramAddress!= NewInfo.pEndOfVars - NewInfo.NvramAddress
+ || DefInfo!=Info
+ )
+ ) Status=UpdateVarstore(Info,Interface,&NewInfo);
+
+ SelectiveFree (NewInfo.NvramAddress);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsStoreOk
+//
+// Description: This function checks is Varstore is correct
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+//
+// Output: BOOLEAN - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsStoreOk(NVRAM_STORE_INFO *Info)
+{
+ return
+ ( Info->LastVarSize==0
+ || NvIsVariable((NVAR*)(Info->pEndOfVars-Info->LastVarSize),Info)
+ )
+ && *(UINT32*)Info->pEndOfVars==(UINT32)FlashEmpty
+ && ((NVAR*)Info->pEndOfVars)->size==FLASH_EMPTY_SIZE
+ && *(UINT32*)(Info->NvramGuidsAddress-Info->NextGuid)==(UINT32)FlashEmpty;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckStore
+//
+// Description: This function checks if Varstore is correct and otherwise tries to
+// Reinitialize NvRam, copy Varstore to memory and prints messages
+// based on situation.
+//
+// Input: OUT NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure
+//
+// Output: BOOLEAN - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CheckStore(BOOLEAN Recover)
+{
+ NVRAM_STORE_INFO *Info = VarStoreInfo.NvInfo;
+ NVRAM_STORE_INFO NewInfo;
+ EFI_STATUS Status;
+ BOOLEAN MainStoreValid;
+ BOOLEAN BackupStoreValid;
+#ifdef HYBRID_NV_INTERFACE
+ NVRAM_STORE_INFO FlashInfo;
+ HybridStoreToRealStore(Info,&FlashInfo);
+#endif
+ MainStoreValid = IsMainNvramStoreValid(
+#ifdef HYBRID_NV_INTERFACE
+ &FlashInfo,
+#else
+ VarStoreInfo.NvInfo,
+#endif
+ VarStoreInfo.BackupAddress, &BackupStoreValid
+ );
+ if (!MainStoreValid){
+ if (BackupStoreValid){
+ NVRAM_STORE_INFO BackupInfo;
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM Store is not valid. Switching to Backup Store.\n"));
+#ifdef HYBRID_NV_INTERFACE
+ if (!SwapVarstoresInHybridMode(&BackupInfo)){
+#endif
+ BackupInfo.NvramAddress = VarStoreInfo.BackupAddress;
+ BackupInfo.NvramSize = VarStoreInfo.NvInfo->NvramSize;
+ NvInitInfoBuffer(
+ &BackupInfo, VarStoreInfo.HeaderLength, VarStoreInfo.NvInfo->Flags
+ );
+ VarStoreInfo.BackupAddress = VarStoreInfo.NvInfo->NvramAddress;
+#ifdef HYBRID_NV_INTERFACE
+ }
+#endif
+ *VarStoreInfo.NvInfo = BackupInfo;
+ NvramReinitialize();
+ MainStoreValid = TRUE;
+#ifdef HYBRID_NV_INTERFACE
+ HybridStoreToRealStore(Info,&FlashInfo);
+#endif
+ }else{//both main and backup stores are invliad; force the recovery.
+ Recover = TRUE;
+ }
+ }
+#ifdef HYBRID_NV_INTERFACE
+ if (MainStoreValid && IsStoreOk(&FlashInfo)) return;
+#else
+ if (MainStoreValid && IsStoreOk(Info)) return;
+#endif
+
+ if (!Recover)
+ {
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM inconsistency detected. Reinitializing.\n"));
+#ifdef HYBRID_NV_INTERFACE
+ //When inconsystency is detected, re-read the flash content into the memory buffer
+ //(they may be out of synchronization)
+ MemCpy(
+ VarStoreInfo.NvInfo->NvramAddress,
+ VarStoreInfo.NvramFlashAddress,
+ VarStoreInfo.NvInfo->NvramSize
+ );
+#endif
+ NvramReinitialize();
+
+ if (IsStoreOk(Info)) return;
+ }
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM corruption detected.\n"));
+
+ Status = CopyVarStoreToMemStore(Info,NULL,&NewInfo);
+
+ if (EFI_ERROR(Status)){
+ SelectiveFree (NewInfo.NvramAddress);
+ return ;
+ }
+
+ UpdateVarstore(Info,VarStoreInfo.NvInterface,&NewInfo);
+ SelectiveFree (NewInfo.NvramAddress);
+}
+
+//High level routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeGetVariable
+//
+// Description: This function searches for Var with specific GUID and Name
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeGetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attrib;
+
+ if (!VariableName || !VendorGuid || !DataSize || !Data && *DataSize)
+ return EFI_INVALID_PARAMETER;
+ Status = GetVariableHook (
+ VariableName,VendorGuid,Attributes,DataSize,Data
+ );
+ if (Status != EFI_UNSUPPORTED) return Status;
+ CheckStore(FALSE);
+#if NV_CACHE_SUPPORT
+ {
+ UINTN VariableNameSize;
+ NVRAM_STORE_INFO *Info;
+ BOOLEAN UnindexedExists;
+ NVAR *Nvar = NULL;
+ VAR_INDEX_ENTRY *NvarEntry = IndexFindVariableEntry(
+ VariableName,VendorGuid,&VariableNameSize,
+ &Info, &UnindexedExists
+ );
+
+ if (NvarEntry!=NULL)
+ {
+ Nvar = NvarEntry->Nvar;
+ if (AreBtVariablesHidden() && !(Nvar->flags & NVRAM_FLAG_RUNTIME)) return EFI_NOT_FOUND;
+
+ // Get the attributes from the first entry, data-only entries do not store attribs
+ if (Attributes)
+ if (EFI_ERROR(NvGetAttributesFromNvar(Nvar, Info, Attributes)))
+ return EFI_NOT_FOUND;
+
+ // Get the data using the cached data-only entry, if possible
+ return NvGetVariableFromNvar(
+ NvarEntry->FinalDataNvar,VariableNameSize,NULL,DataSize,Data,Info, NULL
+ );
+ }
+
+ if (!UnindexedExists) return EFI_NOT_FOUND;
+ }
+#endif
+ Status = NvGetVariable2(
+ VariableName, VendorGuid, &Attrib,
+ DataSize, Data,
+ VarStoreInfo.InfoCount, VarStoreInfo.NvramInfo
+ );
+
+ if (!EFI_ERROR(Status) || Status == EFI_BUFFER_TOO_SMALL)
+ {
+ if (AreBtVariablesHidden() && !(Attrib & EFI_VARIABLE_RUNTIME_ACCESS)) return EFI_NOT_FOUND;
+
+ if (Status != EFI_BUFFER_TOO_SMALL && Attributes) *Attributes=Attrib;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeGetNextVariableName
+//
+// Description: This function searches for next Var after Var with specific name and GUID and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeGetNextVariableName(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+)
+{
+ EFI_STATUS Status;
+
+ if ( !VariableNameSize || !VariableName || !VendorGuid)
+ return EFI_INVALID_PARAMETER;
+ Status = GetNextVarNameHook (
+ VariableNameSize, VariableName, VendorGuid
+ );
+ if (Status != EFI_UNSUPPORTED) return Status;
+ CheckStore(FALSE);
+ Status = NvGetNextVariableName2(
+ VariableNameSize, VariableName, VendorGuid,
+ VarStoreInfo.InfoCount, VarStoreInfo.NvramInfo,
+ &VarStoreInfo.LastInfoIndex,AreBtVariablesHidden()
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeSetVariable
+//
+// Description: This function sets Var with specific GUID, Name and attributes
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINT32 Attributes - Attributes of the Var
+// IN UINTN DataSize - size of Var
+// IN VOID *Data - Pointer to memory where Var data is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeSetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+)
+{
+ NVAR *Var = NULL;
+ UINTN NameSize;
+ BOOLEAN NvVariableFound;
+ NVRAM_STORE_INFO *Info=NULL;
+ VARIABLE_INTERFACE *Interface;
+ EFI_STATUS Status;
+ NVRAM_STORE_INFO NewInfo;
+#if NV_CACHE_SUPPORT
+ BOOLEAN UnindexedExists;
+ BOOLEAN UpdateIndex;
+ VAR_INDEX_ENTRY *VarEntry;
+#endif
+ UINTN OldDataSize=0;
+ VOID *OldData=NULL;
+ EXT_SEC_FLAGS ExtSecFlags = {0, 0,{0}};
+ EFI_GUID EfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+ if (
+ !VariableName || VariableName[0]==0 || !VendorGuid
+ || ( Attributes & ~ALL_VARIABLE_ATTRIBUTES)
+ || (Attributes & EFI_VARIABLE_RUNTIME_ACCESS) && !(Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS )
+ || DataSize && !Data
+ || Runtime && Attributes && (
+ !(Attributes & EFI_VARIABLE_NON_VOLATILE)
+ || !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS) && AreBtVariablesHidden()
+ )
+ ) return EFI_INVALID_PARAMETER;
+ if (guidcmp(VendorGuid, & EfiGlobalVariableGuid) == 0)
+ {
+ if (VarNotInEfiGlobalVarList (VariableName, Attributes))
+ {
+ NVRAM_TRACE((TRACE_DXE_CORE, "Variable with EfiGlobalVariableGuid has illegal name: %S or attributes: %x ! Please use different GUID. \n", VariableName, Attributes));
+ ASSERT(FALSE);
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ Status = SetVariableHook (
+ VariableName,VendorGuid,Attributes,DataSize,Data
+ );
+ if (Status != EFI_UNSUPPORTED) return Status;
+ if (DataSize>MAX_NVRAM_VARIABLE_SIZE) return EFI_OUT_OF_RESOURCES;
+
+ CheckStore(FALSE);
+#if NV_CACHE_SUPPORT
+ //UpdateIndex defines if indexed address has to be updated.
+ //Typically we don't have to update index because
+ //index contains address of the first NVAR for a particular variable,
+ //which does not change when we update variable data.
+ //However, there is one exception from the rule.
+ //We need to update the index, when indexed address points to the default value of the variable.
+ //In this case UpdateIndex will be set to TRUE
+ UpdateIndex = FALSE;
+ VarEntry = IndexFindVariableEntry(
+ VariableName,VendorGuid,&NameSize,
+ &Info, &UnindexedExists
+ );
+
+ if (VarEntry!=NULL)
+ {
+ Var = VarEntry->Nvar;
+ if (Info==VarStoreInfo.NvInfo) NvVariableFound=TRUE;
+ else if (Info==VarStoreInfo.MemInfo) NvVariableFound=FALSE;
+ else
+ {
+ //We are setting UnindexedExists to TRUE because
+ //there may be other variable instances in varstores with lower priority
+ Var=NULL; VarEntry=NULL; UpdateIndex=TRUE; UnindexedExists=TRUE;
+ }
+ }
+
+ if (Var==NULL && UnindexedExists)
+ {
+ NvVariableFound=TRUE;
+ Var = NvFindVariable(VariableName,VendorGuid, &NameSize, VarStoreInfo.NvInfo);
+
+ if (Var==NULL)
+ {
+ NvVariableFound=FALSE;
+ Var = NvFindVariable(VariableName,VendorGuid, &NameSize, VarStoreInfo.MemInfo);
+ }
+ }
+
+#else
+ NvVariableFound=TRUE;
+ Var = NvFindVariable(VariableName,VendorGuid, &NameSize, VarStoreInfo.NvInfo);
+
+ if (Var==NULL)
+ {
+ NvVariableFound=FALSE;
+ Var = NvFindVariable(VariableName,VendorGuid, &NameSize, VarStoreInfo.MemInfo);
+ }
+
+#endif
+ if( Var!=NULL )
+ {
+ // It's illegal to set boot time variable at run time.
+ if (AreBtVariablesHidden() && !(Var->flags & NVRAM_FLAG_RUNTIME)) return EFI_INVALID_PARAMETER;
+ if (NvVariableFound)
+ {
+ Info = VarStoreInfo.NvInfo;
+ Interface = VarStoreInfo.NvInterface;
+ }
+ else
+ {
+ Info = VarStoreInfo.MemInfo;
+ Interface = VarStoreInfo.MemInterface;
+ }
+ GetVarAuthExtFlags(Var, Info, &ExtSecFlags);
+#if NV_CACHE_SUPPORT
+ if (VarEntry != NULL && VarEntry->FinalDataNvar != NULL)
+ OldData = NvGetData( VarEntry->FinalDataNvar, NameSize, &OldDataSize, Info);
+ else
+#endif
+ OldData = NvGetData( Var, NameSize, &OldDataSize, Info);
+ } else {
+ if (Attributes & EFI_VARIABLE_NON_VOLATILE)
+ {
+ Info = VarStoreInfo.NvInfo;
+ Interface = VarStoreInfo.NvInterface;
+ }
+ else
+ {
+#if NV_CACHE_SUPPORT
+ //if UpdateIndex is TRUE, default value exists
+ //If default value exists, the variable is non valatile
+ //Attributes for existing variable can not be changed
+ if (UpdateIndex) return EFI_INVALID_PARAMETER;
+#endif
+ Info = VarStoreInfo.MemInfo;
+ Interface = VarStoreInfo.MemInterface;
+ }
+ OldDataSize = 0;
+ OldData = NULL;
+ }
+
+ Status = VerifyVariable(VariableName, VendorGuid, &Attributes, &Data, &DataSize, OldData, OldDataSize, &ExtSecFlags);
+ if (EFI_ERROR(Status)) {
+ // case for SigDb Append mode. EFI_ALREADY_STARTED treat as Ok to exit SetVar
+ if(Status == EFI_ALREADY_STARTED)
+ Status = EFI_SUCCESS;
+ return Status;
+ }
+
+// Function called with empty access attributes - the variable shall be erased.
+ if(!Attributes)
+ DataSize = 0;
+ //
+ // Verification passed.
+ //
+ if ((!(Attributes & EFI_VARIABLE_APPEND_WRITE) && !DataSize) ||
+ !(Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS) )
+ {
+ //delete
+ if (Var==NULL) return
+#if NV_CACHE_SUPPORT
+ //if UpdateIndex is TRUE, default value (which can not be deleted ) exists
+ (UpdateIndex) ? EFI_WRITE_PROTECTED :
+#endif
+ EFI_NOT_FOUND;
+
+ if (Runtime && !NvVariableFound) return EFI_INVALID_PARAMETER;
+
+ Status = DeleteVariable(Var,Info,Interface);
+#if NV_CACHE_SUPPORT
+
+ if (!EFI_ERROR(Status))
+ {
+ //The variable has just been deleted from the primary varstore.
+ //However, we may still have variable instance in other stores.
+ INT32 i;
+ NVAR *v;
+
+ if (NvVariableFound)
+ {
+ for (i=VarStoreInfo.InfoCount-1; i>=0; i--)
+ {
+ if ( Info == &VarStoreInfo.NvramInfo[i]
+ || (Info->Flags & NVRAM_STORE_FLAG_NON_VALATILE)==0
+ ) continue;
+
+ v = NvFindVariable(
+ VariableName,VendorGuid, &NameSize,
+ &VarStoreInfo.NvramInfo[i]
+ );
+
+ if (v!=NULL)
+ {
+ IndexUpdateVariable(v,&VarStoreInfo.NvramInfo[i]);
+ return Status;
+ }
+ }
+ }
+
+ //If other instances are not found, delete the index entry
+ IndexDeleteVariableEntry(VarEntry);
+ }
+
+#endif
+ return Status;
+ }
+
+ if (Var==NULL)
+ {
+ //create new
+ Status = CreateVariable(
+ VariableName,VendorGuid,Attributes,
+ DataSize, Data, Info,Interface, NULL, &ExtSecFlags// NULL
+ );
+#if NV_CACHE_SUPPORT
+ if (!EFI_ERROR(Status))
+ {
+ if (UpdateIndex)
+ {
+ if ( ( !( VarStoreInfo.NvramMode & (NVRAM_MODE_DEFAULT_CONFIGURATION|NVRAM_MODE_MANUFACTORING) ) )
+ || Info!=VarStoreInfo.NvInfo )
+ {
+ IndexUpdateVariable(
+ (NVAR*)(Info->pEndOfVars-Info->LastVarSize),Info
+ );
+
+ }
+ }
+ else
+ IndexAddVariable(
+ (NVAR*)(Info->pEndOfVars-Info->LastVarSize),Info
+ );
+ }
+
+#endif
+ }
+
+ else
+ {
+ //update existing
+ Status = UpdateVariable(
+ Var,VariableName,NameSize,VendorGuid,Attributes,
+ DataSize, Data,
+#if NV_CACHE_SUPPORT
+ VarEntry,
+#else
+ NULL,
+#endif
+
+ &ExtSecFlags,
+ Info, Interface
+ );
+ }
+
+ //Error Recovery
+ if ( Status==EFI_OUT_OF_RESOURCES
+ || Status==EFI_DEVICE_ERROR && !IsStoreOk(Info)
+ )
+ {
+ BOOLEAN FirstPass=TRUE;
+ do{
+ if (!SaveOnlyPreservedVars)
+ {
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM: SetVariable failed. Status=%r. Starting Recovery...\n",Status));
+ }
+ else
+ {
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM: SetVariable failed After Recovery. Clearing NVRAM...\n"));
+ }
+ NewInfo.NvramAddress = NULL;
+ if (EFI_ERROR(CopyVarStoreToMemStore(Info,Var,&NewInfo))){
+ if (NewInfo.NvramAddress!=NULL) SelectiveFree (NewInfo.NvramAddress);
+ return Status;
+ }
+ if (Attributes & EFI_VARIABLE_APPEND_WRITE)
+ Status = CreateVariableEx(
+ VariableName,VendorGuid,Attributes,
+ DataSize, Data, &NewInfo, &MemInterface, NULL, &ExtSecFlags,
+ OldData, OldDataSize
+ );
+ else
+ Status = CreateVariable(
+ VariableName,VendorGuid,Attributes,
+ DataSize, Data, &NewInfo, &MemInterface, NULL, &ExtSecFlags
+ );
+
+ if (!EFI_ERROR(Status))
+ {
+ Status = UpdateVarstore(Info,Interface,&NewInfo);
+ }
+
+ else
+ {
+ if ((Status==EFI_OUT_OF_RESOURCES) && (FirstPass)) SaveOnlyPreservedVars = TRUE;
+
+ CheckStore(TRUE);
+ }
+
+ SelectiveFree (NewInfo.NvramAddress);
+
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM: SetVariable Status after recovery=%r.\n",Status));
+ FirstPass = FALSE;
+ }
+ while (SaveOnlyPreservedVars);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeginCriticalSection
+//
+// Description: This function calls when critical section begins. It disables interupts,
+// and Smi and fills CRITICAL_SECTION structure fields
+//
+// Input: CRITICAL_SECTION *Cs - pointer to CRITICAL_SECTION structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BeginCriticalSection(CRITICAL_SECTION *Cs)
+{
+ CRITICAL_SECTION TempCs;
+
+ TempCs.IntState[0] = IoRead8(0x21);
+ TempCs.IntState[1] = IoRead8(0xa1);
+ TempCs.SmiState = SbLib_GetSmiState();
+
+ IoWrite8(0x21, 0xff);
+ IoWrite8(0xa1, 0xff);
+ SbLib_SmiDisable();
+
+ Cs->Busy = TRUE;
+
+ Cs->IntState[0] = TempCs.IntState[0];
+ Cs->IntState[1] = TempCs.IntState[1];
+ Cs->SmiState = TempCs.SmiState;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EndCriticalSection
+//
+// Description: This function calls when critical section ends. It enable interupts,
+// and Smi and fills CRITICAL_SECTION structure fields
+//
+// Input: CRITICAL_SECTION *Cs - pointer to CRITICAL_SECTION structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EndCriticalSection(CRITICAL_SECTION *Cs)
+{
+ CRITICAL_SECTION TempCs;
+
+ TempCs.IntState[0] = Cs->IntState[0];
+ TempCs.IntState[1] = Cs->IntState[1];
+ TempCs.SmiState = Cs->SmiState;
+
+ Cs->Busy = FALSE;
+
+ if (TempCs.SmiState) SbLib_SmiEnable();
+ IoWrite8(0x21, TempCs.IntState[0]);
+ IoWrite8(0xa1, TempCs.IntState[1]);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeGetVariableSafe
+//
+// Description: This function searches for Var with specific GUID and Name
+// beginning and ending critical section
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeGetVariableSafe(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+)
+{
+ EFI_STATUS Status;
+ BEGIN_CRITICAL_SECTION(NvramCsPtr);
+ Status = DxeGetVariable(
+ VariableName,VendorGuid,Attributes,DataSize,Data
+ );
+ END_CRITICAL_SECTION(NvramCsPtr);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeGetNextVariableNameSafe
+//
+// Description: This function searches for Var folowing after Var with specific name and GUID
+// and returns it's Name, beginning and ending critical section .
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeGetNextVariableNameSafe(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+)
+{
+ EFI_STATUS Status;
+ BEGIN_CRITICAL_SECTION(NvramCsPtr);
+ Status = DxeGetNextVariableName(
+ VariableNameSize,VariableName,VendorGuid
+ );
+ END_CRITICAL_SECTION(NvramCsPtr);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeSetVariableSafe
+//
+// Description: This function sets Var with specific GUID, Name and attributes
+// beginning and ending critical section.
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINT32 Attributes - Attributes of the Var
+// IN UINTN DataSize - size of Var
+// IN VOID *Data - Pointer to memory where Var data is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeSetVariableSafe(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+)
+{
+ EFI_STATUS Status;
+ BEGIN_CRITICAL_SECTION(NvramCsPtr);
+ Status = DxeSetVariable(
+ VariableName,VendorGuid,Attributes,DataSize,Data
+ );
+ END_CRITICAL_SECTION(NvramCsPtr);
+ return Status;
+}
+
+//Initialization
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitVolatileStore
+//
+// Description: This function allocates memory and inits NVRAM_STORE_INFO structure.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// UINTN HeaderSize - Size of the header
+// UINT8 Flags - default Flags
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitVolatileStore(
+ NVRAM_STORE_INFO *Info, UINTN Size,
+ UINTN HeaderLength, UINT8 Flags,
+ BOOLEAN Runtime
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ((NvramDriverBuffer) && (Flags & NVRAM_STORE_FLAG_NON_VALATILE)) {
+ Info->NvramAddress = SelectiveAllocate (FALSE, Size);
+ if (Info->NvramAddress == NULL) return EFI_OUT_OF_RESOURCES;
+ }else{
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ if (NoAccessOutsideofSmm){
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,Size, &Info->NvramAddress
+ );
+ if (EFI_ERROR(Status)) return Status;
+ }
+ else
+#endif
+ {
+ Status = pBS->AllocatePool (
+ (Runtime) ? EfiRuntimeServicesData : EfiBootServicesData,
+ Size, &Info->NvramAddress
+ );
+ if (EFI_ERROR(Status)) return Status;
+ }
+ }
+
+ Info->NvramSize = Size;
+ MemSet(Info->NvramAddress,Info->NvramSize,FLASH_EMPTY_BYTE);
+ NvInitInfoBuffer(
+ Info,HeaderLength,Flags
+ );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnumerateStore
+//
+// Description: This function searches for last Ver and fills the NVRAM_STORE_INFO structure.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EnumerateStore(NVRAM_STORE_INFO *Info)
+{
+ NVAR *Var, *LastVar;
+ INT16 NextGuid;
+ //Init NextGuid and pEndOfVars
+ Var = (NVAR*)Info->pFirstVar;
+ LastVar = Var;
+ NextGuid=0;
+
+ if (NvIsVariable(Var,Info))
+ {
+ //We assume that the first variable pInfo->pFirstVar is always valid
+ //It's OK since we checked for pInfo->pFirstVar validity
+ //during during NVRAM_STORE_INFO initialization in NvInitInfoBuffer routine
+ for (; Var; Var=NvGetNextNvar(Var,Info))
+ {
+ if ( ( Var->flags&(NVRAM_FLAG_DATA_ONLY|NVRAM_FLAG_GUID) ) == 0 )
+ {
+ INT16 guid = *(UINT8*)(Var+1);
+
+ if (guid>NextGuid) NextGuid=guid;
+ }
+
+ LastVar = Var;
+ }
+
+ NextGuid++;
+ Info->LastVarSize = LastVar->size;
+ Info->pEndOfVars = (UINT8*)LastVar+LastVar->size;
+ Info->NextGuid = NextGuid;
+
+ // Skip incomplete NVAR record at the end of the NVRAM area (if any)
+ LastVar = (NVAR*)Info->pEndOfVars;
+ if ( LastVar->size != FLASH_EMPTY_SIZE
+ && LastVar->size
+ <= (UINT8*)(Info->NvramGuidsAddress-NextGuid) - Info->pEndOfVars
+ ){
+ Info->LastVarSize += LastVar->size;
+ Info->pEndOfVars += LastVar->size;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarStoreDiscovery
+//
+// Description: This function searches for nested Verstores and adds them to the NVRAM_STORE_INFO structure.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// NVRAM_STORE_INFO *MemInfo - pointer to NVRAM store structure in memory
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID VarStoreDiscovery(NVRAM_STORE_INFO *NvInfo, NVRAM_STORE_INFO *MemInfo)
+{
+ VarStoreInfo.InfoCount = 0;
+ VarStoreInfo.LastInfoIndex = 0;
+
+ //Handle Manufacturing mode
+ if ( VarStoreInfo.NvramMode & NVRAM_MODE_MANUFACTORING
+ && NvGetDefaultsInfo(
+ MfgDefaults,NvInfo,&VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount]
+ ) != NULL
+ )
+ {
+ VarStoreInfo.InfoCount++;
+ }
+
+ //Handle Default config mode
+ if (!(VarStoreInfo.NvramMode & NVRAM_MODE_DEFAULT_CONFIGURATION))
+ {
+ //add regular NVRAM
+ VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount]=*NvInfo;
+ VarStoreInfo.NvInfo = &VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount];
+ if (VarStoreInfo.NvramMode & NVRAM_MODE_MANUFACTORING)
+ VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount].Flags |= NVRAM_STORE_FLAG_DO_NOT_ENUMERATE;
+ VarStoreInfo.InfoCount++;
+
+ //add defaults
+ if (NvGetDefaultsInfo(
+ StdDefaults,NvInfo,&VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount]
+ ) != NULL
+ )
+ {
+ VarStoreInfo.InfoCount++;
+ }
+ }
+
+ else
+ {
+ //add defaults
+ if (NvGetDefaultsInfo(
+ StdDefaults,NvInfo,&VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount]
+ ) != NULL
+ )
+ {
+ VarStoreInfo.InfoCount++;
+ }
+
+ //add regular NVRAM
+ VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount]=*NvInfo;
+ VarStoreInfo.NvInfo = &VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount];
+ VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount].Flags |= NVRAM_STORE_FLAG_DO_NOT_ENUMERATE;
+ VarStoreInfo.InfoCount++;
+ }
+
+ VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount] = *MemInfo;
+ VarStoreInfo.MemInfo=&VarStoreInfo.NvramInfo[VarStoreInfo.InfoCount];
+ VarStoreInfo.InfoCount++;
+ //Init NextGuid and pEndOfVars
+ EnumerateStore(VarStoreInfo.NvInfo);
+}
+
+//--- Hook to chek NvRam data
+BOOLEAN DxeIsNvramDataCompatible(IN EFI_GET_VARIABLE GetVariable);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramInitialize
+//
+// Description: This function initializes Varstore
+//
+// Input: NONE
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvramInitialize()
+{
+ static EFI_GUID guidHobList = HOB_LIST_GUID;
+ NVRAM_STORE_INFO NvStore, MemStore;
+ NVRAM_HOB *NvramHob = (NVRAM_HOB*)GetEfiConfigurationTable(pST,&guidHobList);
+ NVRAM_STORE_INFO DefaultsInfo;
+ BOOLEAN UseExternalDefaults=FALSE;
+ BOOLEAN PreserveVariablesWithNoDefaults=FALSE;
+
+ if (!NvramHob) return EFI_NOT_FOUND;
+
+ if (EFI_ERROR(FindNextHobByGuid((EFI_GUID*)&AmiNvramHobGuid, &NvramHob)))
+ return EFI_NOT_FOUND;
+
+ if (NvramRtGarbageCollectionSupport) {
+ NvramDriverBufferSize = NvramHob->NvramSize * 3;
+ if( EFI_ERROR( pBS->AllocatePages(
+ AllocateAnyPages, EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(NvramDriverBufferSize),
+ &NvramDriverBuffer )
+ )) NvramDriverBuffer = 0;
+ }
+
+ MemSet(&VarStoreInfo,sizeof(VarStoreInfo),0);
+ VarStoreInfo.HeaderLength = NvramHob->HeaderLength;
+ VarStoreInfo.NvramMode = NvramHob->NvramMode;
+ VarStoreInfo.BackupAddress = (UINT8*)NvramHob->BackupAddress;
+#ifdef EFI_DEBUG
+ if (VarStoreInfo.BackupAddress)
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM back up address: %X\n", VarStoreInfo.BackupAddress));
+#endif
+ VarStoreInfo.MemInterface=&MemInterface;
+ InitVolatileStore(
+ &MemStore,
+ VALATILE_VARIABLE_STORE_SIZE,
+ VarStoreInfo.HeaderLength,0,TRUE
+ );
+ //TODO: comment out the code below for now.
+ // Switching to simulation during recovery is not necessarily a good idea.
+ // For example, it can cause endless reboot if recovery is enabled during the
+ // very first boot after BIOS flashing. Ideally we should switch to simulation
+ // only when NVRAM is incompatible with the FV_MAIN drivers
+ // (which is checked later in this function). While enabling the simulation
+ // we should also "notify" (notification mechanism TBD) the reflash module
+ // that if FV_MAIN is updated, NVRAM must also be updated.
+/*
+ BootMode = GetBootMode();
+ if (BootMode==BOOT_IN_RECOVERY_MODE)
+ VarStoreInfo.NvramMode |= NVRAM_MODE_SIMULATION;
+*/
+ //If we are in the simulation mode let's create new
+ //memory based variable store and initialze it with
+ //content of the NVRAM flash area.
+ if (VarStoreInfo.NvramMode & NVRAM_MODE_SIMULATION)
+ {
+ VarStoreInfo.NvInterface=&MemInterface;
+ InitVolatileStore(
+ &NvStore, NvramHob->NvramSize,
+ VarStoreInfo.HeaderLength,
+ NVRAM_STORE_FLAG_NON_VALATILE,TRUE
+ );
+ MemCpy(NvStore.NvramAddress,(UINT8*)NvramHob->NvramAddress,NvStore.NvramSize);
+ //We altered content of the varstore. Let's reinitialize it.
+ NvInitInfoBuffer(
+ &NvStore, VarStoreInfo.HeaderLength,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ );
+ //no backup in the simulation mode
+ VarStoreInfo.BackupAddress=0;
+ NVRAM_TRACE((TRACE_DXE_CORE,"NVRAM: working in simulation mode\n"));
+ }
+
+ else
+ {
+ VarStoreInfo.NvInterface=&NvInterface;
+ NvStore.NvramAddress = (UINT8*)NvramHob->NvramAddress;
+ NvStore.NvramSize = NvramHob->NvramSize;
+ NvInitInfoBuffer(
+ &NvStore,
+ VarStoreInfo.HeaderLength,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ );
+ }
+
+ //If FV header is corrupted or built-in defaults are not found,
+ //reset NVRAM data; use external defaults.
+ if ( ((EFI_FIRMWARE_VOLUME_HEADER*)NvStore.NvramAddress)->Signature!=FV_SIGNATURE
+ || NvGetDefaultsInfo(StdDefaults, &NvStore, &DefaultsInfo) == NULL
+ ){
+ UseExternalDefaults = TRUE;
+ PreserveVariablesWithNoDefaults = TRUE;
+ VarStoreInfo.NvramMode |= NVRAM_MODE_RESET_CONFIGURATION;
+ }
+ //Handle NVRAM reset
+ if (VarStoreInfo.NvramMode & NVRAM_MODE_RESET_CONFIGURATION)
+ {
+ NvResetConfiguration(
+ &NvStore,VarStoreInfo.NvInterface,
+ UseExternalDefaults, PreserveVariablesWithNoDefaults
+ );
+ VarStoreInfo.NvramMode&=~NVRAM_MODE_RESET_CONFIGURATION;
+ }
+#ifdef HYBRID_NV_INTERFACE
+ if (!(VarStoreInfo.NvramMode & NVRAM_MODE_SIMULATION))
+ InitHybridInterface(&NvStore);
+#endif
+ VarStoreDiscovery(&NvStore,&MemStore);
+#if NV_CACHE_SUPPORT
+ IndexInit();
+#endif
+
+ if (!DxeIsNvramDataCompatible(DxeGetVariableSafe))
+ {
+ NVRAM_TRACE((TRACE_DXE_CORE, "NVRAM DXE: Incompactible NVRAM detected\n"));
+ NvResetConfiguration(
+ VarStoreInfo.NvInfo, VarStoreInfo.NvInterface,
+ TRUE, TRUE
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS NvramReinitialize()
+{
+ NVRAM_STORE_INFO NvStore, MemStore;
+
+ NvStore.NvramAddress = VarStoreInfo.NvInfo->NvramAddress;
+ NvStore.NvramSize = VarStoreInfo.NvInfo->NvramSize;
+ MemStore = *VarStoreInfo.MemInfo;
+ NvInitInfoBuffer(
+ &NvStore,
+ VarStoreInfo.HeaderLength,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ );
+ VarStoreDiscovery(&NvStore,&MemStore);
+#if NV_CACHE_SUPPORT
+ IndexReset();
+#endif
+ return EFI_SUCCESS;
+}
+////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////
+static EFI_GUID guidVariable = EFI_VARIABLE_ARCH_PROTOCOL_GUID;
+static EFI_GUID guidVariableWrite = EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID;
+static EFI_GUID guidMonotonicCounter = EFI_MONOTONIC_COUNTER_ARCH_PROTOCOL_GUID;
+extern EFI_GUID gAmiGlobalVariableGuid;
+UINT32 CounterLo=0, CounterHi=0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNextHighMonotonicCount
+//
+// Description: This function gets Next High Monotonic Count
+//
+// Input: OUT UINT32 *HighCount - pointer to where result will be stored
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetNextHighMonotonicCount(OUT UINT32 *HighCount)
+{
+ EFI_STATUS Status;
+ UINTN Size = sizeof(UINT32);
+
+ if (!HighCount) return EFI_INVALID_PARAMETER;
+
+ if (!CounterHi)
+ {
+ Status = pRS->GetVariable(L"MonotonicCounter", &gAmiGlobalVariableGuid,
+ NULL, &Size, &CounterHi
+ );
+
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND)
+ return Status;
+ }
+
+ ++CounterHi;
+ Status = pRS->SetVariable(
+ L"MonotonicCounter", &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE|EFI_VARIABLE_BOOTSERVICE_ACCESS|EFI_VARIABLE_RUNTIME_ACCESS,
+ Size, &CounterHi
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ *HighCount = CounterHi;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNextMonotonicCount
+//
+// Description: This function gets Next low and high Monotonic Count
+//
+// Input: OUT UINT64 *Count - pointer to where result will be stored
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetNextMonotonicCount(OUT UINT64 *Count)
+{
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ ((UINT32*)Count)[0] = CounterLo++;
+ //--- If low counter overflovs - GetNextHighMonotonicCount
+ if (!CounterLo) return GetNextHighMonotonicCount(&((UINT32*)Count)[1]);
+ //--- If not - get current HighMonotonicCount
+ else ((UINT32*)Count)[1] = CounterHi;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: QueryVariableInfo
+//
+// Description: This function returns parameters of VarStore with passed attributes
+//
+// Input: IN UINT32 Attributes - Atributes to search for
+// OUT UINT64 *MaximumVariableStorageSize - Maximum Variable Storage Size
+// OUT UINT64 *RemainingVariableStorageSize - Remaining Variable Storage Size
+// OUT UINT64 *MaximumVariableSize - Maximum Variable Size
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS QueryVariableInfo (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+)
+{
+ UINT64 StorageSize,RemainingStorage,MaxVarSize;
+ NVRAM_STORE_INFO *Info;
+ UINTN SizeOfVarSizeType = MAX_NVRAM_VARIABLE_SIZE;
+
+ if ( !Attributes || (Attributes & ~ALL_VARIABLE_ATTRIBUTES)
+ ||(Attributes & EFI_VARIABLE_RUNTIME_ACCESS) && !(Attributes & EFI_VARIABLE_BOOTSERVICE_ACCESS )
+ || !MaximumVariableStorageSize || !RemainingVariableStorageSize || !MaximumVariableSize
+ )
+ return EFI_INVALID_PARAMETER;
+
+ Info = (Attributes & EFI_VARIABLE_NON_VOLATILE)
+ ? VarStoreInfo.NvInfo : VarStoreInfo.MemInfo;
+ StorageSize=Info->NvramSize;
+ RemainingStorage=(UINT8*)(
+ (EFI_GUID*)(Info->NvramAddress+Info->NvramSize)
+ - Info->NextGuid-1
+ )-Info->pEndOfVars;
+ MaxVarSize= (SizeOfVarSizeType>RemainingStorage)
+ ? RemainingStorage : SizeOfVarSizeType;
+ MaxVarSize -= sizeof(NVAR) + sizeof(EFI_GUID);
+
+ if ((INTN)MaxVarSize<0) MaxVarSize=0;
+
+ *MaximumVariableStorageSize = StorageSize;
+ *RemainingVariableStorageSize = RemainingStorage;
+ *MaximumVariableSize = MaxVarSize;
+ return EFI_SUCCESS;
+}
+
+VOID NvramNotInSmmExitBs();
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarExitBS
+//
+// Description: This function will be called when Exit BS will signaled
+// will update data to work in RunTime.
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID VarExitBS (IN EFI_EVENT Event, IN VOID *Context)
+{
+ Runtime = TRUE;
+#if NV_CACHE_SUPPORT
+ IndexExitBs();
+#endif
+ //When we call this function from SMM, Event is NULL
+ if (Event!=NULL) NvramNotInSmmExitBs();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarStoreVirtualFixup
+//
+// Description: This function will be invoked to convert
+// runtime pointers to virtual address
+//
+// Input: NVRAM_STORE_INFO *Info - pointer to NVRAM_STORE_INFO structure to fixup
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID VarStoreVirtualFixup(NVRAM_STORE_INFO *Info)
+{
+ pRS->ConvertPointer(0,&Info->pFirstVar);
+ pRS->ConvertPointer(0,&Info->pEndOfVars);
+ pRS->ConvertPointer(0,&Info->NvramGuidsAddress);
+ pRS->ConvertPointer(0,&Info->NvramAddress);
+ Info->pLastReturned=NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarInterfaceVirtualFixup
+//
+// Description: This function will be invoked to convert
+// runtime pointers to virtual address
+//
+// Input: VARIABLE_INTERFACE *Interface - pointer to VARIABLE_INTERFACE structure to fixup
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID VarInterfaceVirtualFixup(VARIABLE_INTERFACE *Interface)
+{
+ pRS->ConvertPointer(0,(VOID**)&Interface->EnableUpdate);
+ pRS->ConvertPointer(0,(VOID**)&Interface->DisableUpdate);
+ pRS->ConvertPointer(0,(VOID**)&Interface->EraseBytes);
+ pRS->ConvertPointer(0,(VOID**)&Interface->WriteBytes);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarVirtAddressChange
+//
+// Description: This function will be invoked to convert whole Var infrustructure
+// and pRS runtime pointers to virtual address
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID VarVirtAddressChange (IN EFI_EVENT Event, IN VOID *Context)
+{
+ UINTN i;
+ VarStoreVirtualFixup(VarStoreInfo.NvInfo);
+#ifdef HYBRID_NV_INTERFACE
+ pRS->ConvertPointer(0,&VarStoreInfo.NvramFlashAddress);
+ VarStoreInfo.AddressDelta=VarStoreInfo.NvramFlashAddress-VarStoreInfo.NvInfo->NvramAddress;
+#endif
+ for (i=0; i< VarStoreInfo.InfoCount; i++)
+ if (VarStoreInfo.NvInfo!=&VarStoreInfo.NvramInfo[i])
+ VarStoreVirtualFixup(&VarStoreInfo.NvramInfo[i]);
+
+ for (i=0; GetVariableHookList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(GetVariableHookList[i]));
+ }
+
+ for (i=0; SetVariableHookList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(SetVariableHookList[i]));
+ }
+
+ for (i=0; GetNextVarNameHookList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(GetNextVarNameHookList[i]));
+ }
+
+ pRS->ConvertPointer(0,&VarStoreInfo.NvInfo);
+ pRS->ConvertPointer(0,&VarStoreInfo.MemInfo);
+ VarInterfaceVirtualFixup(VarStoreInfo.NvInterface);
+ VarInterfaceVirtualFixup(VarStoreInfo.MemInterface);
+ pRS->ConvertPointer(0,&VarStoreInfo.NvInterface);
+ pRS->ConvertPointer(0,&VarStoreInfo.MemInterface);
+ if (VarStoreInfo.BackupAddress!=NULL)
+ pRS->ConvertPointer(0,&VarStoreInfo.BackupAddress);
+ if (NvramDriverBuffer)
+ pRS->ConvertPointer(0,(VOID**)&NvramDriverBuffer);
+ VarStoreInfo.LastInfoIndex = 0;
+ pRS->ConvertPointer(0, &Flash);
+#if NV_CACHE_SUPPORT
+ IndexVirtualFixup();
+#endif
+ //Fixup global data for for a virtual address space.
+ FlashVirtualFixup(pRS);
+ //pRS is converted by the library
+ //(call to InitAmiRuntimeLib initiates the processes)
+ AuthServiceVirtualFixup();
+}
+
+///////////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MonotonicCounterInit
+//
+// Description: This function initialize pBS MonotonicCount servicies and installs
+// corresponding protocols
+//
+// Input: IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to System Table
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MonotonicCounterInit(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle = NULL;
+ UINT32 HighCount;
+ InitAmiLib(ImageHandle,SystemTable);
+ pRS->GetNextHighMonotonicCount = GetNextHighMonotonicCount;
+ pBS->GetNextMonotonicCount = GetNextMonotonicCount;
+ //Init Hi part of the monotonic counter
+ GetNextHighMonotonicCount(&HighCount);
+ pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &guidMonotonicCounter, NULL,
+ NULL
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvRamInit
+//
+// Description: This function initialize pRS Var servicies and MonotonicCount servicies
+// (if MONOTONIC_COUNT_IN_NVRAM token is set) installs
+// corresponding protocols
+//
+// Input: IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to System Table
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvRamInit(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+
+ //TODO: When DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME is defined, we assume that
+ //DXE Variable services will be replaced prior to transitioning to runtime.
+ //If this will not happen, the NVRAM driver may not work properly.
+ //It may either crash (or crash the Windows), or generate false garbage collections.
+ //If support fall back scenario the memory registration of the virtual address change event
+ //and cdoe that allocates hybrid mode buffer must be changed
+ //TODO: When DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME is defined, we can allocate MemStore buffer in boot time memory.
+ InitAmiRuntimeLib(
+ ImageHandle, SystemTable, VarExitBS,
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ NULL
+#else
+ VarVirtAddressChange
+#endif
+ );
+ PROGRESS_CODE(DXE_NVRAM_INIT);
+
+ Status = pBS->LocateProtocol(&gFlashProtocolGuid, NULL, &Flash);
+ ASSERT_EFI_ERROR(Status);
+
+ NvramInitialize();
+// We need to know when to switch to the Runtime mode.
+// Switch to runtime happens on exit boot services or legacy boot event.
+// exit boot services callabck is installed by the InitAmiRuntimeLib function.
+// Let's install legacy boot callbakc here.
+ CreateLegacyBootEvent(TPL_CALLBACK, &VarExitBS, NULL, &Event);
+ pRS->GetNextVariableName = DxeGetNextVariableNameSafe;
+ pRS->GetVariable = DxeGetVariableSafe;
+ pRS->SetVariable = DxeSetVariableSafe;
+ pRS->QueryVariableInfo = QueryVariableInfo;
+
+ pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &guidVariable, NULL,
+ &guidVariableWrite, NULL,
+ NULL
+ );
+ //--- Install MonotonicCount servicies (if NVRAM_MONOTONIC_COUNTER_SUPPORT token is set)
+ if (NvramMonotonicCounterSupport) MonotonicCounterInit(ImageHandle, SystemTable);
+}
+
+
+//**********************************************************************
+// NVRAM SMM BEGIN
+//**********************************************************************
+//when this type is changed, initialization of the NvRamMailboxBuffer variable must also be changed.
+typedef struct
+{
+//TODO: StopRtDataAccess - must be the first field; NvramSmi driver is using it
+ BOOLEAN StopRtDataAccess;
+ VARSTORE_INFO *VarStoreInfoPtr;
+ VAR_INDEX *VarIndexPtr;
+ BOOLEAN SwitchToRuntime;
+ CRITICAL_SECTION *NvramCsPtr;
+ EFI_PHYSICAL_ADDRESS NvramDriverBuffer;
+ UINT32 NvramBuffSize;
+} NVRAM_MAILBOX;
+
+#define NVRAM_MAILBOX_ADDRESS_VARIABLE_GUID \
+ {0x54913a6d, 0xf4ee, 0x4cdb, 0x84, 0x75, 0x74, 0x6, 0x2b, 0xfc, 0xec, 0xf5}
+
+EFI_GUID NvRamMailboxVariableGuid = NVRAM_MAILBOX_ADDRESS_VARIABLE_GUID;
+NVRAM_MAILBOX *NvRamMailbox;
+
+/*************** OUTSIDE SMM **********************************/
+
+NVRAM_MAILBOX NvRamMailboxBuffer = {FALSE, &VarStoreInfo, NULL, FALSE, NULL, 0, 0};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacyToEfiFn
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+LegacyToEfiFn (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ // NvramCsPtr = &NvramCs;
+ Runtime = FALSE;
+ NvRamMailbox->SwitchToRuntime = FALSE;
+
+
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramNotInSmmInit
+//
+// Description: This function initialize pRS Var, MonotonicCount servicies
+// (if MONOTONIC_COUNT_IN_NVRAM token is set) and installs
+// corresponding protocols and sets NvRamMailbox Var not in SMM
+//
+// Input: IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvramNotInSmmInit(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+
+ EFI_GUID pLTEBGuid = LTEB_GUID;
+ EFI_EVENT Event;
+
+ EFI_STATUS Status;
+
+ NvRamInit(ImageHandle, SystemTable);
+ NvRamMailboxBuffer.VarIndexPtr = VarIndexPtr;
+ NvRamMailboxBuffer.NvramCsPtr = NvramCsPtr;
+ if (NvramRtGarbageCollectionSupport) {
+ NvRamMailboxBuffer.NvramDriverBuffer = NvramDriverBuffer;
+ NvRamMailboxBuffer.NvramBuffSize = NvramDriverBufferSize;
+ }
+ NvRamMailbox = &NvRamMailboxBuffer;
+
+ AuthVariableServiceInit ();
+
+ Status = pBS->CreateEventEx( EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ LegacyToEfiFn,
+ NULL,
+ &pLTEBGuid,
+ &Event);
+
+ Status = pRS->SetVariable(
+ L"NvRamMailbox",&NvRamMailboxVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(NvRamMailbox), &NvRamMailbox
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+/*************** INSIDE SMM **********************************/
+VARSTORE_INFO *RtVarStoreInfoPtr;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SynchronizeVarStore
+//
+// Description: This function synchronizes NVRAM_STORE_INFO structure after enterin SMM
+//
+// Input: NVRAM_STORE_INFO *Source - source NVRAM_STORE_INFO structure
+// NVRAM_STORE_INFO *Target - synchronized NVRAM_STORE_INFO structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SynchronizeVarStore(NVRAM_STORE_INFO *Source, NVRAM_STORE_INFO *Target)
+{
+ UINTN Delta = Target->NvramAddress - Source->NvramAddress;
+ Target->pFirstVar = Source->pFirstVar + Delta;
+ Target->pEndOfVars = Source->pEndOfVars + Delta;
+ Target->NextGuid = Source->NextGuid;
+ Target->LastVarSize = Source->LastVarSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SynchronizeVarStoreInfo
+//
+// Description: This function synchronizes all NVRAM_STORE_INFO structures in VARSTORE_INFO after enterin SMM
+//
+// Input: VARSTORE_INFO *From - source VARSTORE_INFO structure
+// VARSTORE_INFO *To - synchronized VARSTORE_INFO structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SynchronizeVarStoreInfo(VARSTORE_INFO *From, VARSTORE_INFO *To)
+{
+ UINT32 i;
+ To->InfoCount = From->InfoCount;
+
+ for (i=0; i<From->InfoCount; i++)
+ {
+ SynchronizeVarStore(&From->NvramInfo[i], &To->NvramInfo[i]);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SynchronizeBeforeOperation
+//
+// Description: This function synchronizes Runtime and non Runtime Var Structures after enterin SMM
+// before each operation with Variables
+//
+// Input: NONE
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SynchronizeBeforeOperation()
+{
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+if (!NoAccessOutsideofSmm)
+#endif
+{
+ SynchronizeVarStoreInfo(
+ RtVarStoreInfoPtr,&VarStoreInfo
+ );
+ VarStoreInfo.NvInfo = (NVRAM_STORE_INFO*)(
+ (UINT8*)RtVarStoreInfoPtr->NvInfo - (UINT8*)NvRamMailbox->VarStoreInfoPtr
+ + (UINT8*)&VarStoreInfo
+ );
+ VarStoreInfo.MemInfo = (NVRAM_STORE_INFO*)(
+ (UINT8*)RtVarStoreInfoPtr->MemInfo - (UINT8*)NvRamMailbox->VarStoreInfoPtr
+ + (UINT8*)&VarStoreInfo
+ );
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ if (NvRamMailbox->StopRtDataAccess){
+ NoAccessOutsideofSmm=TRUE;
+#if NV_CACHE_SUPPORT
+//TODO: This has to be reviewed if RT Index support is added
+ //Shutdown the index
+ IndexExitBs();
+#endif
+ ReallocateVolatileVarstoreToSmm();
+#ifdef HYBRID_NV_INTERFACE
+ ReallocateHybridVarstoreToSmm();
+#endif
+ NvramCs = *NvramCsPtr;
+ NvramCsPtr->Busy = FALSE;
+ NvramCsPtr = &NvramCs; // switch to local CS
+ }
+#endif
+}
+ if (!Runtime && NvRamMailbox->SwitchToRuntime){
+ VarExitBS(NULL,NULL);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SynchronizeAfterOperation
+//
+// Description: This function synchronizes Runtime and non Runtime Var Structures after enterin SMM
+// after each operation with Variables
+//
+// Input: NONE
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SynchronizeAfterOperation()
+{
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+if (!NoAccessOutsideofSmm)
+#endif
+{
+ SynchronizeVarStoreInfo(
+ &VarStoreInfo, RtVarStoreInfoPtr
+ );
+ RtVarStoreInfoPtr->NvInfo = (NVRAM_STORE_INFO*)(
+ (UINT8*)VarStoreInfo.NvInfo - (UINT8*)&VarStoreInfo
+ + (UINT8*)NvRamMailbox->VarStoreInfoPtr
+ );
+ RtVarStoreInfoPtr->MemInfo = (NVRAM_STORE_INFO*)(
+ (UINT8*)VarStoreInfo.MemInfo - (UINT8*)&VarStoreInfo
+ + (UINT8*)NvRamMailbox->VarStoreInfoPtr
+ );
+}
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmGetVariable
+//
+// Description: This function searches for Var with specific GUID and Name in SMM
+// synchronizing Varstors before and after operation
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SmmGetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+)
+{
+ EFI_STATUS Status;
+ BEGIN_CRITICAL_SECTION(NvramCsPtr);
+ SynchronizeBeforeOperation();
+ Status = DxeGetVariable(
+ VariableName, VendorGuid, Attributes, DataSize, Data
+ );
+ SynchronizeAfterOperation();
+ END_CRITICAL_SECTION(NvramCsPtr);
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmSetVariable
+//
+// Description: This function sets Var with specific GUID, Name and attributes in SMM
+// synchronizing Varstors before and after operation
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINT32 Attributes - Attributes of the Var
+// IN UINTN DataSize - size of Var
+// IN VOID *Data - Pointer to memory where Var data is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SmmSetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+)
+{
+ EFI_STATUS Status;
+
+ BEGIN_CRITICAL_SECTION(NvramCsPtr);
+ SynchronizeBeforeOperation();
+ Status = DxeSetVariable(
+ VariableName, VendorGuid, Attributes, DataSize, Data
+ );
+ SynchronizeAfterOperation();
+ END_CRITICAL_SECTION(NvramCsPtr);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmGetNextVariableName
+//
+// Description: This function searches for next Var after Var with specific name and GUID and returns it's Name
+// in SMM synchronizing Varstors before and after operation.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SmmGetNextVariableName (
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+)
+{
+ EFI_STATUS Status;
+
+ BEGIN_CRITICAL_SECTION(NvramCsPtr);
+ SynchronizeBeforeOperation();
+ Status = DxeGetNextVariableName(
+ VariableNameSize, VariableName, VendorGuid
+ );
+ SynchronizeAfterOperation();
+ END_CRITICAL_SECTION(NvramCsPtr);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmQueryVariableInfo
+//
+// Description: This function returns parameters of VarStore with passed attributes in SMM
+// synchronizing Varstors before operation.
+//
+// Input: IN UINT32 Attributes - Atributes to search for
+// OUT UINT64 *MaximumVariableStorageSize - Maximum Variable Storage Size
+// OUT UINT64 *RemainingVariableStorageSize - Remaining Variable Storage Size
+// OUT UINT64 *MaximumVariableSize - Maximum Variable Size
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SmmQueryVariableInfo (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+)
+{
+ EFI_STATUS Status;
+
+ SynchronizeBeforeOperation();
+ Status = QueryVariableInfo(
+ Attributes, MaximumVariableStorageSize,
+ RemainingVariableStorageSize, MaximumVariableSize
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramSmmInit
+//
+// Description: This function gets NvRamMailbox and initialize pRS Var servicies and
+// corresponding structures
+//
+// Input: IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to System Table
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvramSmmInit(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ UINTN Size=sizeof(NvRamMailbox);
+
+ Status = pST->RuntimeServices->GetVariable(
+ L"NvRamMailbox",&NvRamMailboxVariableGuid,
+ NULL, &Size, &NvRamMailbox
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ RtVarStoreInfoPtr = NvRamMailbox->VarStoreInfoPtr;
+ VarStoreInfo=*RtVarStoreInfoPtr;
+ VarIndexPtr=NvRamMailbox->VarIndexPtr;
+ NvramCsPtr=NvRamMailbox->NvramCsPtr;
+
+ if (NvramRtGarbageCollectionSupport){
+ NvramDriverBuffer = NvRamMailbox->NvramDriverBuffer;
+ NvramDriverBufferSize = NvRamMailbox->NvramBuffSize;
+ }
+
+ VarStoreInfo.MemInterface=&MemInterface;
+ VarStoreInfo.NvInfo =
+ &VarStoreInfo.NvramInfo[
+ RtVarStoreInfoPtr->NvInfo - RtVarStoreInfoPtr->NvramInfo
+ ];
+ VarStoreInfo.MemInfo =
+ &VarStoreInfo.NvramInfo[
+ RtVarStoreInfoPtr->MemInfo - RtVarStoreInfoPtr->NvramInfo
+ ];
+#ifdef HYBRID_NV_INTERFACE
+ VarStoreInfo.NvInterface=&HybridInterface;
+#else
+ VarStoreInfo.NvInterface=&NvInterface;
+#endif
+
+ pRS->GetNextVariableName = SmmGetNextVariableName;
+ pRS->GetVariable = SmmGetVariable;
+ pRS->SetVariable = SmmSetVariable;
+ pRS->QueryVariableInfo = SmmQueryVariableInfo;
+ Status = pBS->LocateProtocol(&gFlashSmmProtocolGuid, NULL, &Flash);
+ ASSERT_EFI_ERROR (Status);
+ AuthVariableServiceInitSMM();
+ InstallNvramControlSmmProtocol();
+ return EFI_SUCCESS;
+}
+
+/*************** INSIDE and OUSIDE SMM ************************/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramNotInSmmExitBs
+//
+// Description: This function signals that exit BS event was taken place and switches
+// SwitchToRuntime field in NvRamMailbox
+//
+// Input: NONE
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvramNotInSmmExitBs()
+{
+ NvRamMailbox->SwitchToRuntime = !NvRamMailbox->SwitchToRuntime;
+#ifdef DO_NOT_ACCESS_DATA_OUTSIDE_OF_SMM_AT_RUNTIME
+ //Make a dummy SMM GetVariable call to process SwitchToRuntime
+ //make sure GetVariable is substituted
+ if (pRS->GetVariable!=DxeGetVariableSafe){
+ static EFI_GUID DummyGuid={0};
+ UINTN Size = 0;
+ UINTN Dummy;
+ pRS->GetVariable(L"Dummy", &DummyGuid,NULL, &Size, &Dummy);
+ }
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvRamSmmEntry
+//
+// Description: This function is the entry point for this DXE. This function
+// installs NvRam services in and outside SMM.
+//
+// Input: IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - Pointer to the system table
+//
+// Output: EFI_STATUS - Status based on errors that occurred while waiting for
+// time to expire.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvRamSmmEntry(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle,SystemTable);
+ return InitSmmHandlerEx(
+ ImageHandle, SystemTable, NvramSmmInit, NvramNotInSmmInit
+ );
+}
+//**********************************************************************
+// NVRAM SMM END
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/NVRAM/NVRAMPEI.c b/Core/EM/NVRAM/NVRAMPEI.c
new file mode 100644
index 0000000..53ebd2b
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAMPEI.c
@@ -0,0 +1,584 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMPEI.c 19 5/22/14 6:05p Oleksiyy $
+//
+// $Revision: 19 $
+//
+// $Date: 5/22/14 6:05p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMPEI.c $
+//
+// 19 5/22/14 6:05p Oleksiyy
+// [TAG] EIP170545
+// [Category] Improvement
+// [Description] Spelling errors corrected.
+// [Files] NVRAMPEI.c
+//
+// 18 1/04/13 10:35a Felixp
+// Minor improvement in PeiInitNV: when CreateHob fails, still install the
+// PPI.
+//
+// 17 12/13/12 6:17p Oleksiyy
+// [TAG] EIP109422
+// [Category] Improvement
+// [Description] Issues found by CppCheck in NVRAM Module part
+// [Files] NVRAMDXE.c and NVRAMPEI.c
+//
+// 16 8/12/11 12:15p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+//
+// 15 2/02/10 5:15p Oleksiyy
+// EIP 33263 : Hooks for SetVariable, GetVariable and GetNextVarName
+// added
+//
+// 14 11/24/09 4:05p Oleksiyy
+// EIP 26085: Added support to read All the NVRAM variable (including
+// defoults) with GetNextVariable in PEI and DXE.
+//
+// 13 11/23/09 6:25p Felixp
+//
+// 12 11/23/09 4:44p Felixp
+// Code to validate NVRAM header fields used by the NVRAM driver is added.
+// If problem is found, the header fields are updated with the correct
+// values.
+//
+// 11 7/10/09 8:50a Felixp
+// Code clean up; comments and function header added
+//
+// 10 6/26/09 3:29p Felixp
+// Active varstore detection is moved into new IsMainNvramStoreValid
+// function in NvramRead.c
+//
+// 9 5/21/09 5:39p Felixp
+// 1. Disable NVRAM content if it has been corrupted during failed BIOS
+// update
+// 2. Validate compatibility of the NVRAM data using external hook
+// (IsNvramDataCompatible).
+// Disable incompatible NVRAM content.
+//
+// 8 1/16/09 3:39p Felixp
+// New Feature. EIP 18483. Interface of the hooks that detect NVRAM
+// operational mode is extended.
+// NVRAM driver uses platform hooks(IsMfgMode, IsResetConfigMode,
+// IsDefaultConfigMode) to detect, which set of configuration values
+// are to be used. In some cases the mode is detected based on value of
+// the NVRAM variable.
+// Interface of the hook functions is extended. New parameter is added.
+// Pointer to EFI_PEI_READ_ONLY_VARIABLE2_PPI PPI is passed to the hook
+// functions.
+// The pointer can be used to read and enumerate existing NVRAM variables.
+//
+// 7 10/09/08 11:47a Felixp
+// 1. Fault tolerant NVRAM garbage collection support is added.
+// Use FAULT_TOLERANT_NVRAM_UPDATE SDL token to enable/disable (disabled
+// by default).
+// NOTE: This feature requires upgrade of the Board module.
+// NOTE: This feature requires porting:
+// Fault tolerant update requires reserved flash area of size NVRAM_SIZE
+// used for back up during NVRAM garbage collection.
+// The address of the area is defined by NVRAM_BACKUP_ADDRESS SDL token
+// defined in Board.sdl.
+// Size and Base addresses of other firmware volumes may need to be
+// adjusted to free up space for the NVRAM back up area.
+// Default ROM layout expects NVRAM back up area immediately below the
+// main NVRAM area.
+// For projects with the customized ROM layout Core.mak has to be updated.
+// 2. Top level NVRAM function updated to be reentrance-safe.
+// NOTE: This feature requires upgrade of the SB module.
+// 3. Improved recovery from the flash programming failures and
+// corruptions within NVRAM area.
+// 4. More reliable non-fault tolerant garbage collection.
+//
+// 6 6/06/08 11:01a Felixp
+//
+// 4 2/19/08 11:07p Felixp
+// Update in init routine PeiInitNV: during boot with default
+// configuration, main NVRAM store is also exposed. This is needed to
+// provide current value for variables without defaults.
+//
+// 3 9/06/07 12:14a Felixp
+//
+// 2 8/31/07 3:44p Felixp
+// NVRAM code has been significantly changed to introduce the following
+// improvements:
+// 1. The code is chaned to always use the same amount of memory.
+// Previous implementation allocated memory as needed, which caused
+// occasional S4 problems.
+// Plus S4 resume never worked during the very first boot after the
+// firmware update.
+// 2. Support for NVRAM defaults added.
+// NVRAM image with the default values for the Setup variables is now
+// generated by the build process.
+// The image is generated by the HpkTool (included into AMITSE module
+// part).
+// In addition to standard Setup defaults it is also possible
+// to generate manufactoring defaults. Support for the manufactoring
+// defaults
+// is disabled by default and can be enabled using
+// MANUFACTURING_MODE_SUPPORT SDL token.
+// 3. Support for boot with alternative configurations is added.
+// Decision to switch to the alternative configuration
+// (alternative set of values for NVRAM variables)
+// is based on values returned by the porintg routine in OemPort.c.
+// During boot with alternative configurations GetVariable service
+// returns alternative values for the setup-related variables.
+// If variable does not have an alternative value, current value is
+// returned.
+// Two alternative configurations are supported:
+// Boot with manufactoring settings(activated when IsMfgMode routine in
+// OemPort.c returns TRUE).
+// Boot with default settings(activated when IsDefaultConfigMode routine
+// in OemPort.c returns TRUE).
+// NOTE: This feature requires of the Board module
+// 4.NVRAM reset option is added.
+// If porting routine IsResetConfigMode in OemPort.c returns TRUE in PEI
+// phase,
+// NVRAM content will be reset during initialization of the DXE NVRAM
+// driver.
+// During reset operation all setup-related variables are reset to their
+// default values.
+// All other variables are deleted.
+// NOTE: This feature requires upgrade of the Board module
+// 5.Detection of NVRAM update added.
+// NVRAM implementation detects if NVRAM has been updated since the last
+// NVRAM call.
+// This provides ability to use variables services before and after
+// firmware update.
+// 6.Overall code clean up and simplification.
+// 7.Core Sources are no longer required in order to use NV_SIMULATION
+// option.
+// 8.PI 1.0 support.
+// Support for a PI 1.0 complient variable PPI is added. Old PPI is still
+// preserved in this label for backward compatibility.
+// New library routines PeiGetVariable and PeiGetNextVariableName are
+// created in order to hide the differences between two PPIs.
+// It is recommended to update existing code to use new library routines.
+// Support of the old PPI may be dropped in the future versions of Core.
+// 9. NVRAM is now packaged as a raw FFS file embedded into the standard
+// FV (used to be non-standard FV with raw NVRAM image).
+// Validation: New NVRAM code has been validated using SCT and EFI version
+// of Windows Server 2008
+// Files modified: Core.sdl, Core.mak, AmiPeiLib.h, PeiLib.c,
+// ReadOnlyVariable.h, , Token.c, HpkTool.exe, AMITSE.mak, Setup.ini,
+// NVRAM.sdl, NVRAM.mak, NVRAM.h, NVRAMRead.c, NVRAMPEI.c,
+// NVRAMDXE.c
+//
+// 1 8/24/06 12:38p Felixp
+//
+// 3 10/09/05 11:25a Felixp
+// Performance measurements added.
+//
+// 2 3/04/05 9:42a Mandal
+//
+// 1 1/28/05 12:44p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/27/04 4:08p Felixp
+//
+// 3 4/05/04 1:10a Felixp
+//
+// 2 4/04/04 2:58p Felixp
+//
+// 1 3/29/04 2:32a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NVRAMPEI.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <PPI/ReadOnlyVariable2.h>
+#include <PPI/ReadOnlyVariable.h>
+#include <AmiPeiLib.h>
+#include "NVRAM.h"
+
+//Defined in CSPLib(OEMPort.c)
+BOOLEAN IsMfgMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadVariablePpi
+);
+BOOLEAN IsResetConfigMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadVariablePpi
+);
+BOOLEAN IsDefaultConfigMode(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadVariablePpi
+);
+BOOLEAN IsNvramDataCompatible(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadVariablePpi
+);
+
+//Defined in Tokens.c
+extern UINTN NvramAddress;
+extern UINTN NvramBackupAddress;
+extern const UINTN NvramSize;
+extern const BOOLEAN NvSimulation;
+
+typedef struct{
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI Ppi;
+ UINT32 InfoCount;
+ UINT32 LastInfoIndex;
+ NVRAM_STORE_INFO NvramInfo[3];
+ NVRAM_STORE_INFO *MainInfo;
+} VARIABLE_PPI;
+
+//--- GetVariable and GetNextVarName Hooks ------
+//============================================================================
+// Type definitions
+typedef EFI_STATUS (PEI_HOOK_GET_VARIABLE)(
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN CONST CHAR16 *VariableName, IN CONST EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes, IN OUT UINTN *DataSize, OUT VOID *Data
+);
+
+typedef EFI_STATUS (PEI_HOOK_GET_NEXT_VARIABLE_NAME)(
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+);
+
+//======================================================================
+// Global extern variables
+
+extern PEI_HOOK_GET_VARIABLE PEI_GET_VAR_LIST EndOfGetVariableHook;
+extern PEI_HOOK_GET_NEXT_VARIABLE_NAME PEI_GET_NEXT_VAR_NAME_LIST EndOfGetNextVarNameHook;
+
+PEI_HOOK_GET_VARIABLE* PeiGetVariableHookList[]=
+ {PEI_GET_VAR_LIST NULL};
+PEI_HOOK_GET_NEXT_VARIABLE_NAME* PeiGetNextVarNameHookList[]=
+ {PEI_GET_NEXT_VAR_NAME_LIST NULL};
+
+EFI_STATUS PeiGetVariableHook(
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN CONST CHAR16 *VariableName, IN CONST EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes, IN OUT UINTN *DataSize, OUT VOID *Data
+){
+ UINTN i;
+ EFI_STATUS Result = EFI_UNSUPPORTED;
+ for(i=0; PeiGetVariableHookList[i] && (Result == EFI_UNSUPPORTED); i++)
+ Result = PeiGetVariableHookList[i](This,VariableName, VendorGuid,Attributes, DataSize, Data);
+ return Result;
+}
+
+EFI_STATUS PeiGetNextVarNameHook(
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+){
+ UINTN i;
+ EFI_STATUS Result = EFI_UNSUPPORTED;
+ for(i=0; PeiGetNextVarNameHookList[i] && (Result == EFI_UNSUPPORTED); i++)
+ Result = PeiGetNextVarNameHookList [i](This,VariableNameSize,VariableName, VendorGuid);
+ return Result;
+}
+//---GetVariable and GetNextVarName Hooks END------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarPpiGetVariable
+//
+// Description: This function searches for a Variable with specific GUID and Name
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices - Double pointer to Pei Services instance
+// IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VarPpiGetVariable(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+)
+{
+ return PeiGetVariable(
+ PeiServices, VariableName, VendorGuid, Attributes, DataSize, Data
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarPpiGetNextVariableName
+//
+// Description: This function searches for Var folowed by the Var with specific name (optional)
+// and GUID and returns it's Name.
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices - Double pointer to Pei Services instance
+// IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VarPpiGetNextVariableName(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+)
+{
+ return PeiGetNextVariableName(
+ PeiServices, VariableNameSize, VariableName, VendorGuid
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VarPpi2GetVariable
+//
+// Description: This function searches for Var with specific GUID
+//
+// Input: IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This - pointer to FI_PEI_READ_ONLY_VARIABLE2_PPI
+// IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VarPpi2GetVariable(
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN CONST CHAR16 *VariableName, IN CONST EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes, IN OUT UINTN *DataSize, OUT VOID *Data
+)
+{
+ EFI_STATUS Status;
+ VARIABLE_PPI *VarPpi = (VARIABLE_PPI*)This;
+ Status = PeiGetVariableHook (
+ This, VariableName, VendorGuid, Attributes, DataSize, Data
+ );
+ if (Status != EFI_UNSUPPORTED) return Status;
+ Status = NvGetVariable2(
+ (CHAR16*)VariableName, (EFI_GUID*)VendorGuid, Attributes,
+ DataSize, Data, VarPpi->InfoCount, VarPpi->NvramInfo
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableName2
+//
+// Description: This function searches for Var with specific GUID and Enty number
+// not betwin LastInfoIndex - InfoCount parameter and returns it's Name.
+//
+// Input: IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This - pointer to FI_PEI_READ_ONLY_VARIABLE2_PPI
+// IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VarPpi2GetNextVariableName(
+ IN CONST EFI_PEI_READ_ONLY_VARIABLE2_PPI *This,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+)
+{
+ EFI_STATUS Status;
+ VARIABLE_PPI *VarPpi = (VARIABLE_PPI*)This;
+ Status = PeiGetNextVarNameHook (
+ This, VariableNameSize, VariableName, VendorGuid
+ );
+ if (Status != EFI_UNSUPPORTED) return Status;
+ Status = NvGetNextVariableName2(
+ VariableNameSize, VariableName, VendorGuid,
+ VarPpi->InfoCount, VarPpi->NvramInfo,
+ &(VarPpi->LastInfoIndex),FALSE
+ );
+ return Status;
+}
+
+// PPI interface definition
+EFI_PEI_READ_ONLY_VARIABLE_PPI VariablePpi = {VarPpiGetVariable, VarPpiGetNextVariableName};
+EFI_PEI_READ_ONLY_VARIABLE2_PPI Variable2Ppi = {VarPpi2GetVariable, VarPpi2GetNextVariableName};
+
+// PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR VariablePpiListTemplate[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiPeiReadOnlyVariable2PpiGuid, &Variable2Ppi
+ },
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiReadOnlyVariablePpiGuid, &VariablePpi
+ }
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiInitNV
+//
+// Description: This function inits NVRAM
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader - pointer to FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices - double pointer to the Pei Sevices structure
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PeiInitNV (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *VariablePpiList;
+ VARIABLE_PPI *VarPpi;
+ UINT32 NvramMode=0;
+ NVRAM_HOB *pHob;
+ BOOLEAN ResetConfigMode;
+ NVRAM_STORE_INFO MainNvram;
+ VARIABLE_PPI TmpVarPpi;
+ VOID *BackupNvramAddress = (VOID*)NvramBackupAddress;
+ BOOLEAN BackupStoreValid;
+ BOOLEAN NvramIsCorrupted = FALSE;
+
+ Status = (*PeiServices)->AllocatePool(PeiServices, sizeof(VariablePpiListTemplate)+sizeof(VARIABLE_PPI), &VariablePpiList);
+ if (EFI_ERROR(Status)) return Status;
+ VariablePpiList[0]=VariablePpiListTemplate[0];
+ VariablePpiList[1]=VariablePpiListTemplate[1];
+ VarPpi = (VARIABLE_PPI*)(VariablePpiList + 2);
+ VariablePpiList[0].Ppi = VarPpi;
+ VarPpi->Ppi = Variable2Ppi;
+ VarPpi->InfoCount = 0;
+ VarPpi->LastInfoIndex = 0;
+ MainNvram.NvramAddress = (UINT8*)NvramAddress;
+ MainNvram.NvramSize = NvramSize;
+ if (!IsMainNvramStoreValid(&MainNvram, BackupNvramAddress,&BackupStoreValid)){
+ if (BackupStoreValid){
+ VOID *Tmp = BackupNvramAddress;
+ BackupNvramAddress = MainNvram.NvramAddress;
+ MainNvram.NvramAddress = Tmp;
+ }else{
+ NvramIsCorrupted = TRUE;
+ }
+ }
+ NvInitInfoBuffer(
+ &MainNvram,
+ NvramHeaderLength,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ );
+ //Check if FV signature is valid
+ NvramIsCorrupted = NvramIsCorrupted
+ || ((EFI_FIRMWARE_VOLUME_HEADER*)MainNvram.NvramAddress)->Signature!=FV_SIGNATURE;
+ if (NvramIsCorrupted){
+ VarPpi->MainInfo = NULL;
+ NvramMode=NVRAM_MODE_RESET_CONFIGURATION;
+ PEI_TRACE((-1, PeiServices, "PEI: NVRAM header corruption is detected\n"));
+ }else{
+ TmpVarPpi = *VarPpi;
+ TmpVarPpi.NvramInfo[0]=MainNvram;
+ TmpVarPpi.MainInfo = &TmpVarPpi.NvramInfo[0];
+ TmpVarPpi.InfoCount=1;
+
+ if ( IsMfgMode(PeiServices,&TmpVarPpi.Ppi)
+ && NvGetDefaultsInfo(
+ MfgDefaults,&MainNvram,&VarPpi->NvramInfo[VarPpi->InfoCount]
+ ) != NULL
+ ){
+ VarPpi->InfoCount++;
+ NvramMode|=NVRAM_MODE_MANUFACTORING;
+ }
+ ResetConfigMode = IsResetConfigMode(PeiServices,&TmpVarPpi.Ppi);
+ if (!ResetConfigMode && !IsDefaultConfigMode(PeiServices,&TmpVarPpi.Ppi)){
+ VarPpi->NvramInfo[VarPpi->InfoCount]=MainNvram;
+ VarPpi->MainInfo = &VarPpi->NvramInfo[VarPpi->InfoCount];
+ VarPpi->InfoCount++;
+ if (NvGetDefaultsInfo(
+ StdDefaults,&MainNvram,&VarPpi->NvramInfo[VarPpi->InfoCount]
+ ) != NULL
+ ){
+ VarPpi->InfoCount++;
+ }
+ }else{
+ if (NvGetDefaultsInfo(
+ StdDefaults,&MainNvram,&VarPpi->NvramInfo[VarPpi->InfoCount]
+ ) != NULL
+ ){
+ VarPpi->InfoCount++;
+ }
+ if (ResetConfigMode){
+ VarPpi->MainInfo = NULL;
+ NvramMode|=NVRAM_MODE_RESET_CONFIGURATION;
+ }else{
+ VarPpi->NvramInfo[VarPpi->InfoCount]=MainNvram;
+ VarPpi->MainInfo = &VarPpi->NvramInfo[VarPpi->InfoCount];
+ VarPpi->InfoCount++;
+ NvramMode|=NVRAM_MODE_DEFAULT_CONFIGURATION;
+ }
+ }
+ if (!IsNvramDataCompatible(PeiServices, &VarPpi->Ppi)){
+ PEI_TRACE((-1, PeiServices, "PEI: Incompatible NVRAM detected\n"));
+ VarPpi->MainInfo = NULL;
+ VarPpi->InfoCount=0;
+ }
+ }
+ Status=(*PeiServices)->CreateHob(PeiServices, EFI_HOB_TYPE_GUID_EXTENSION, sizeof(NVRAM_HOB),&pHob);
+ ASSERT_PEI_ERROR(PeiServices,Status)
+ if (!EFI_ERROR(Status)){
+ pHob->Header.Name=AmiNvramHobGuid;
+ pHob->NvramAddress=(EFI_PHYSICAL_ADDRESS)(UINTN)MainNvram.NvramAddress;
+ pHob->BackupAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)BackupNvramAddress;
+ pHob->NvramSize = MainNvram.NvramSize;
+ if (NvSimulation) NvramMode|=NVRAM_MODE_SIMULATION;
+ pHob->NvramMode = NvramMode;
+ pHob->HeaderLength = NvramHeaderLength;
+ }
+ return (*PeiServices)->InstallPpi(PeiServices,VariablePpiList);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/NVRAM/NVRAMRead.c b/Core/EM/NVRAM/NVRAMRead.c
new file mode 100644
index 0000000..463ed5b
--- /dev/null
+++ b/Core/EM/NVRAM/NVRAMRead.c
@@ -0,0 +1,1508 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMRead.c 32 6/11/14 3:12p Oleksiyy $
+//
+// $Revision: 32 $
+//
+// $Date: 6/11/14 3:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/NVRAM/NVRAMRead.c $
+//
+// 32 6/11/14 3:12p Oleksiyy
+// [TAG] EIP173026
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] With AMITSE 2.17.1245 windows 8.1 (UEFI) does not install
+// [RootCause] GetNextVariableName was in certain cases returning name
+// and GUID of a boot time variable
+// [Solution] Variable name and GUID of a boot time variable X were
+// returned at runtime under the following conditions:
+// - The variable X was present in the default var.store and not
+// present in the main var.store
+// - The variable immediately before variable X in the default
+// var.store was present in the main var.store
+// The default var.store is a var.store generated at build time that
+// contains default values for all setup variables
+// (variables associated with setup controls).
+// The main var.store is the main NVRAM area. Variable is added into a
+// main var.store when somebody
+// calls SetVariable.
+// [Files] NVRAMRead.c
+// NVRAMDXE.c
+// NVRAM.cif
+//
+// 31 4/11/14 5:13p Oleksiyy
+// [TAG] EIP162446
+// [Category] Improvement
+// [Description] Chm file added.
+// [Files] NVRAMRead.c
+// NVRAM.cif
+//
+// 30 1/08/14 5:34p Oleksiyy
+// [TAG] EIP125555
+// [Category] Improvement
+// [Description] A Work-around provided for NvGetNextVariableName2() to
+// preserve the original VariableName when returning an
+// EFI_BUFFER_TOO_SMALL error from NvGetNameFromNvar().
+// [Files] NVRANRead.c
+//
+// 29 11/29/12 5:10p Felixp
+// Minor improvement: Since UEFI Specification versions prior to 2.1
+// (0x2000A) are no longer supported,
+// all the "#if EFI_SPECIFICATION_VERSION >= 0x2000A" conditional
+// compilation statements are removed.
+// Files modified: NVRAM.h, NVRAMRead.c, NVRAMDXE.c
+//
+// 28 7/13/11 9:24a Justinj
+// [TAG] EIP62762
+// [Category] Improvement
+// [Description] Optimize NVRAM cache index so that the entire linked
+// list is not walked every time a variable is set or retrieved.
+// [Files] NVRAM.h
+// NVRAMRead.c
+// NVRAMDXE.c
+//
+// 27 5/06/11 6:14p Oleksiyy
+// [TAG] EIP53253
+// [Category] Improvement
+// [Description] To comply with UEFI 2.3.1
+// EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS and
+// EFI_VARIABLE_APPEND_WRITE attributes handling added.
+// [Files] NVRAM.h, NVRAMRead.c and NVRAMDXE.c
+//
+// 26 9/30/10 4:36p Oleksiyy
+// Issue Number: 40356 and 39462
+//
+// Category: New Feature
+//
+// Description: Support for EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS
+// Small fix of previously checked in code.
+//
+// Files: NVRAM. h, NVRAMRead.c, NVRAMDXE.c
+//
+// 25 9/22/10 6:39p Felixp
+// Enhancement(EIP 39462 and EIP 40356):
+// Support of the authenticated update of the NVRAM variables
+// as described in UEFI specification version 2.1 and above.
+// NOTE: The actual authentication is performed by the external SecureMod
+// eModule,
+// which must be in the proejct to use this feature.
+//
+// 24 8/18/10 11:08a Oleksiyy
+// [TAG] EIP42324
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] NVRAM checksum at EFI Variable deletion
+// [RootCause] Deleted variables also were checksummed when NVRAM
+// consistency is checked.
+// [Solution] Deleted variables not checksummed any more.
+// [Files] NVRAMRead.c
+//
+// 23 12/16/09 5:55p Oleksiyy
+// EIP 26085: Added support to read All the NVRAM variable. Final version.
+//
+// 22 12/04/09 2:27p Felixp
+// NvarEqNvar moved from NvramDxe.c to NvramRead.c
+//
+// 21 11/25/09 4:42p Felixp
+// NvGetNextVariableName2 changes are rolled back
+//
+// 20 11/25/09 4:38p Felixp
+// NvGetNextVariableName2 updated.
+//
+// 19 11/24/09 4:40p Felixp
+// Minor bug fixes
+//
+// 18 11/24/09 4:04p Oleksiyy
+// EIP 26085: Added support to read All the NVRAM variable (including
+// defoults) with GetNextVariable in PEI and DXE.
+//
+// 17 11/23/09 11:00p Felixp
+//
+// 16 11/23/09 4:44p Felixp
+// Code to validate NVRAM header fields used by the NVRAM driver is added.
+// If problem is found, the header fields are updated with the correct
+// values.
+//
+// 15 11/20/09 4:06p Felixp
+// NVRAM driver is updated to support UEFI2.1
+// EFI_VARIABLE_HARDWARE_ERROR_RECORD attribue.
+//
+// 14 11/19/09 4:30p Felixp
+//
+// 13 11/18/09 12:10p Oleksiyy
+// EIP 30751: Bug fix in the NVRAM record checksum implementation
+//
+// 12 8/25/09 4:11p Felixp
+// NVRAM Record Checksum Support(EIP 23825) is added.
+// Disabled by default. Enable using NVRAM_RECORD_CHECKSUM_SUPPORT SDL
+// token.
+//
+// 11 7/10/09 8:50a Felixp
+// Code clean up; comments and function header added
+//
+// 10 6/26/09 3:28p Felixp
+// New IsMainNvramStoreValid function is added.
+// The function detects is main NVRAM or backup NVRAM is currently active
+// (returns FALSE when backup is active).
+//
+// 9 5/14/09 9:36a Felixp
+// New feature: SMM version of Runtime Services
+// NVRAM driver is updated to populate SMM runtime table
+// with the pointers to SMM version of variable services.
+//
+// 8 11/18/08 5:45p Felixp
+// Bug fix in NvIsVariable and NvGetNextNvar functions.
+// Symptoms: False NVRAM corruption detection on systems with
+// NVRAM larger than 64KB during creation or update of the large
+// variables.
+// Reason: overflow during validation of record size
+//
+// 7 10/09/08 11:47a Felixp
+// 1. Fault tolerant NVRAM garbage collection support is added.
+// Use FAULT_TOLERANT_NVRAM_UPDATE SDL token to enable/disable (disabled
+// by default).
+// NOTE: This feature requires upgrade of the Board module.
+// NOTE: This feature requires porting:
+// Fault tolerant update requires reserved flash area of size NVRAM_SIZE
+// used for back up during NVRAM garbage collection.
+// The address of the area is defined by NVRAM_BACKUP_ADDRESS SDL token
+// defined in Board.sdl.
+// Size and Base addresses of other firmware volumes may need to be
+// adjusted to free up space for the NVRAM back up area.
+// Default ROM layout expects NVRAM back up area immediately below the
+// main NVRAM area.
+// For projects with the customized ROM layout Core.mak has to be updated.
+// 2. Top level NVRAM function updated to be reentrance-safe.
+// NOTE: This feature requires upgrade of the SB module.
+// 3. Improved recovery from the flash programming failures and
+// corruptions within NVRAM area.
+// 4. More reliable non-fault tolerant garbage collection.
+//
+// 6 9/06/07 12:14a Felixp
+//
+// 5 8/31/07 3:44p Felixp
+// NVRAM code has been significantly changed to introduce the following
+// improvements:
+// 1. The code is chaned to always use the same amount of memory.
+// Previous implementation allocated memory as needed, which caused
+// occasional S4 problems.
+// Plus S4 resume never worked during the very first boot after the
+// firmware update.
+// 2. Support for NVRAM defaults added.
+// NVRAM image with the default values for the Setup variables is now
+// generated by the build process.
+// The image is generated by the HpkTool (included into AMITSE module
+// part).
+// In addition to standard Setup defaults it is also possible
+// to generate manufactoring defaults. Support for the manufactoring
+// defaults
+// is disabled by default and can be enabled using
+// MANUFACTURING_MODE_SUPPORT SDL token.
+// 3. Support for boot with alternative configurations is added.
+// Decision to switch to the alternative configuration
+// (alternative set of values for NVRAM variables)
+// is based on values returned by the porintg routine in OemPort.c.
+// During boot with alternative configurations GetVariable service
+// returns alternative values for the setup-related variables.
+// If variable does not have an alternative value, current value is
+// returned.
+// Two alternative configurations are supported:
+// Boot with manufactoring settings(activated when IsMfgMode routine in
+// OemPort.c returns TRUE).
+// Boot with default settings(activated when IsDefaultConfigMode routine
+// in OemPort.c returns TRUE).
+// NOTE: This feature requires of the Board module
+// 4.NVRAM reset option is added.
+// If porting routine IsResetConfigMode in OemPort.c returns TRUE in PEI
+// phase,
+// NVRAM content will be reset during initialization of the DXE NVRAM
+// driver.
+// During reset operation all setup-related variables are reset to their
+// default values.
+// All other variables are deleted.
+// NOTE: This feature requires upgrade of the Board module
+// 5.Detection of NVRAM update added.
+// NVRAM implementation detects if NVRAM has been updated since the last
+// NVRAM call.
+// This provides ability to use variables services before and after
+// firmware update.
+// 6.Overall code clean up and simplification.
+// 7.Core Sources are no longer required in order to use NV_SIMULATION
+// option.
+// 8.PI 1.0 support.
+// Support for a PI 1.0 complient variable PPI is added. Old PPI is still
+// preserved in this label for backward compatibility.
+// New library routines PeiGetVariable and PeiGetNextVariableName are
+// created in order to hide the differences between two PPIs.
+// It is recommended to update existing code to use new library routines.
+// Support of the old PPI may be dropped in the future versions of Core.
+// 9. NVRAM is now packaged as a raw FFS file embedded into the standard
+// FV (used to be non-standard FV with raw NVRAM image).
+// Validation: New NVRAM code has been validated using SCT and EFI version
+// of Windows Server 2008
+// Files modified: Core.sdl, Core.mak, AmiPeiLib.h, PeiLib.c,
+// ReadOnlyVariable.h, , Token.c, HpkTool.exe, AMITSE.mak, Setup.ini,
+// NVRAM.sdl, NVRAM.mak, NVRAM.h, NVRAMRead.c, NVRAMPEI.c,
+// NVRAMDXE.c
+//
+// 4 4/27/07 7:12p Pavell
+// Bug fix in NVGetNextVariableName: GetNextVariable did not return
+// EFI_NOT_FOUND after the last variable if the very first operation after
+// ExitBootServices was update of the existing NV variable.
+//
+// 3 3/18/07 4:08p Felixp
+// 1. IsNvramBlock function added
+// 2. Clean up
+//
+// 2 10/27/06 10:42a Felixp
+// Bug fixes for correct work in Virtual Address Space.
+//
+// 3 1/20/05 11:37a Felixp
+// Component restructurized to support release in binary format
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/27/04 4:08p Felixp
+//
+// 11 12/09/04 9:02p Felixp
+// minor improvements
+//
+// 10 8/28/04 1:49a Felixp
+// NVRAM Routines fixes
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NVRAMRead.c
+//
+// Description: NVRAM data area access API
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "NVRAM.h"
+
+#define VALID_STATE_FLAGS (\
+ EFI_FILE_HEADER_CONSTRUCTION | EFI_FILE_HEADER_VALID |\
+ EFI_FILE_DATA_VALID | EFI_FILE_MARKED_FOR_UPDATE)
+
+//Definitions for Variables that are used
+//to store nested defaults images
+// {4599D26F-1A11-49b8-B91F-858745CFF824}
+const EFI_GUID AmiDefaultsVariableGuid =
+ { 0x4599d26f, 0x1a11, 0x49b8, { 0xb9, 0x1f, 0x85, 0x87, 0x45, 0xcf, 0xf8, 0x24 } };
+const CHAR16 MfgDefaults[] = L"MfgDefaults";
+const CHAR16 StdDefaults[] = L"StdDefaults";
+const EFI_GUID AmiNvramHobGuid = NVRAM_HOB_GUID;
+
+//Low level access routines
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetGuid
+//
+// Description: This function returns GUID of specified variable.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: EFI_GUID* - pionter to the Var GUID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_GUID* NvGetGuid(NVAR* pVar, NVRAM_STORE_INFO *pInfo)
+{
+ if (pVar->flags&NVRAM_FLAG_GUID) return (EFI_GUID*)(pVar+1);
+ else return pInfo->NvramGuidsAddress-*(UINT8*)(pVar+1);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetName
+//
+// Description: This function returns pointer to the Var name.
+//
+// Input: NVAR* pVar - pointer to the Var
+//
+// Output: VOID* - pionter to the Var name
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvGetName(NVAR* pVar)
+{
+ return (INT8*)(pVar+1)+(pVar->flags&NVRAM_FLAG_GUID ? sizeof(EFI_GUID) : 1);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetDataNvar
+//
+// Description: This function returns last variable in NVRAM storage.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to the last Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetDataNvar(NVAR *pVar, NVRAM_STORE_INFO *pInfo)
+{
+ NVAR *pLastVar=NULL;
+
+ for (
+ ; NvIsVariable(pVar,pInfo) //--Check if pVar reccord is correct
+ ; pVar = (NVAR*)((UINT8*)pVar + pVar->next)
+ )
+ {
+ if (pVar->next==FLASH_EMPTY_NEXT) return pVar;
+
+ pLastVar=pVar;
+ }
+
+ return pLastVar;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetExtSize
+//
+// Description: This function returs pointer to Ext Size feild in Var
+//
+// Input: NVAR* NvStart - pointer to the Var to checksumm
+//
+// Output:
+// UINT16* Pointer to Ext Size feild in Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VAR_SIZE_TYPE* NvGetExtSize (NVAR* pVar)
+{
+ return (VAR_SIZE_TYPE*) (((UINT8*) pVar + pVar->size) - sizeof(VAR_SIZE_TYPE));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetExtFlags
+//
+// Description: This function returs pointer to Ext Flags feild in Var
+//
+// Input: NVAR* NvStart - pointer to the Var to checksumm
+//
+// Output:
+// UINT8* Pointer to Ext Flags feild in Var
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8* NvGetExtFlags (NVAR* pVar)
+{
+ return (UINT8*) ((UINT8*) NvGetExtSize (pVar) - *NvGetExtSize (pVar) + sizeof(VAR_SIZE_TYPE));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvCalculateNvarChecksum
+//
+// Description: This function calculates and Checks the checksum of the Var
+//
+// Input: NVAR* NvStart - pointer to the Var to checksumm
+// BOOLEAN Calculate - if TRUE - skeep checksumm feild in Var
+//
+// Output:
+// UINT8 Checksum value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 NvCalculateNvarChecksum(NVAR* pVar)
+{
+ UINT8 *p, *Start;
+ UINT8 Checksum = 0;
+
+ if ( !(pVar->flags & NVRAM_FLAG_EXT_HEDER)
+ || !(*NvGetExtFlags(pVar) & NVRAM_EXT_FLAG_CHECKSUM)
+ ) return 0;
+
+ //calculate checksum of the variable excluding the header
+ Start = (UINT8*)(pVar+1);
+ for(p=Start; p < Start+pVar->size - sizeof(NVAR); p++)
+ {
+ Checksum += *p;
+ }
+ //add variable size
+ Start = (UINT8*)&pVar->size;
+ for(p=Start; p < Start+sizeof(VAR_SIZE_TYPE); p++)
+ {
+ Checksum += *p;
+ }
+ //add flags except NVRAM_FLAG_VALID
+ Checksum += pVar->flags;
+
+ return 0 - Checksum;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetData
+//
+// Description: This function returns last variable in NVRAM storage.
+//
+// Input: NVAR* pVar - pointer to Var
+// UINTN NameLength - Length of the Var name
+// UINTN* pDataSize - pointer to where the site of data returned will be store
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: VOID* - pointer to the Data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvGetData(NVAR* pVar, UINTN NameLength, UINTN* pDataSize, NVRAM_STORE_INFO *pInfo)
+{
+ UINTN DataOffset;
+ UINTN ExtSize;
+
+ pVar = NvGetDataNvar(pVar,pInfo);
+
+ if (pVar==NULL) return NULL;
+
+ DataOffset = sizeof(NVAR);
+
+ if (!(pVar->flags&NVRAM_FLAG_DATA_ONLY))
+ {
+ DataOffset += NameLength
+ + ( pVar->flags&NVRAM_FLAG_GUID
+ ? sizeof(EFI_GUID) : 1
+ );
+ }
+
+ if (pDataSize)
+ { // if Ext. Header present - get its size
+ if (pVar->flags & NVRAM_FLAG_EXT_HEDER) ExtSize = *NvGetExtSize (pVar);
+ else ExtSize = 0;
+ *pDataSize = pVar->size - DataOffset - ExtSize;
+ }
+
+ return (INT8*)pVar+DataOffset;
+}
+
+//Validation routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvIsValid
+//
+// Description: This function checks if passed Var is valid.
+//
+// Input: NVAR* pVar - pointer to the Var
+//
+// Output: BOOLEAN - TRUE of FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvIsValid(NVAR* pVar)
+{
+ return ((pVar->flags^~FLASH_EMPTY_FLAG)&NVRAM_FLAG_VALID) &&
+ !(pVar->flags&NVRAM_FLAG_DATA_ONLY);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvIsVariable
+//
+// Description: This function checks if pVar reccord is correct.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: BOOLEAN - TRUE of FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvIsVariable(NVAR *pVar, NVRAM_STORE_INFO *pInfo)
+{
+ return
+ pVar->signature==NVAR_SIGNATURE
+ && pVar->flags!=FLASH_EMPTY_FLAG
+ && !(pVar->flags&~ALL_FLAGS)
+ && pVar->size!=FLASH_EMPTY_SIZE && pVar->size>sizeof(NVAR)
+ && pVar->size<=(pInfo->pEndOfVars-(UINT8*)pVar)
+ && ( pVar->next==FLASH_EMPTY_NEXT
+ || pVar->next>=pVar->size
+ && pVar->next<=(UINT32)(pInfo->pEndOfVars-(UINT8*)pVar)
+ )
+ && ( !(pVar->flags & NVRAM_FLAG_EXT_HEDER)
+ || !(*NvGetExtFlags (pVar) & NVRAM_EXT_FLAG_CHECKSUM)
+ || !(pVar->flags & NVRAM_FLAG_VALID)
+ || !NvCalculateNvarChecksum(pVar)
+ )
+ ;
+}
+
+//Iteration routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextNvar
+//
+// Description: This function returns the next valid Var after pVar.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to next valid Var after pVar, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetNextNvar(NVAR* pVar, NVRAM_STORE_INFO *pInfo)
+{
+ if (!pVar || pVar >= (NVAR*)pInfo->pEndOfVars) return NULL;
+
+ if (NvIsVariable(pVar,pInfo))
+ {
+ pVar = (NVAR*)((UINT8*)pVar+pVar->size);
+
+ if (pVar >= (NVAR*)pInfo->pEndOfVars) return NULL;
+ }
+
+ do
+ {
+ if (pVar >= (NVAR*)pInfo->pEndOfVars) return NULL;
+
+ //If we found a variable, we are done
+ if (NvIsVariable(pVar,pInfo)) return pVar;
+
+ //Otherwise, let's check if record size seems valid
+ //If size is valid, skip corrupted NVAR
+ //Otherwise give up and return NULL
+ if ( pVar->size!=FLASH_EMPTY_SIZE
+ && pVar->size>sizeof(NVAR)
+ && pVar->size<=(pInfo->pEndOfVars-(UINT8*)pVar)
+ ) pVar = (NVAR*)((UINT8*)pVar+pVar->size);
+ else return NULL;
+ }
+ while (TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextNvar
+//
+// Description: This function returns the next valid Var after pVar.
+//
+// Input: NVAR* pVar - pointer to Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to next valid Var after pVar, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetNextValid(NVAR* pVar, NVRAM_STORE_INFO *pInfo)
+{
+ do
+ {
+ pVar = NvGetNextNvar(pVar,pInfo);
+ }
+ while (pVar && !NvIsValid(pVar));
+
+ return pVar;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetFirstValid
+//
+// Description: This function returns the first valid Var in NVRAM.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to first valid Var in NVRAM, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVAR* NvGetFirstValid(NVRAM_STORE_INFO *pInfo)
+{
+ NVAR* pNvar = (NVAR*)pInfo->pFirstVar;
+
+ //We assume that the first variable pInfo->pFirstVar is non-corrupted.
+ //We checked for pInfo->pFirstVar validity
+ //during NVRAM_STORE_INFO initialization in NvInitInfoBuffer routine.
+ if (!NvIsVariable(pNvar,pInfo)) return NULL;
+
+ if (NvIsValid(pNvar)) return pNvar;
+
+ return NvGetNextValid(pNvar,pInfo);
+}
+
+//Comparison routines
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvAttribEq
+//
+// Description: This function checks if pNvar attributes ara same with Attributes passed.
+//
+// Input: NVAR* pNVar - pointer to Var
+// UINT32 Attributes - Attributes of Var
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: NVAR* - pointer to next valid Var after pVar, NULL - if none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvAttribEq(NVAR* pNvar, UINT32 Attributes, NVRAM_STORE_INFO *pInfo)
+{
+ //--- By ! we convert integer to boolean
+ return !(pNvar->flags & NVRAM_FLAG_RUNTIME)
+ == !(Attributes & EFI_VARIABLE_RUNTIME_ACCESS)
+ && !(pInfo->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ == !(Attributes & EFI_VARIABLE_NON_VOLATILE)
+ && !(pNvar->flags & NVRAM_FLAG_HARDWARE_ERROR_RECORD)
+ == !(Attributes & EFI_VARIABLE_HARDWARE_ERROR_RECORD)
+ && !(pNvar->flags & NVRAM_FLAG_AUTH_WRITE)
+ == !(Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES)
+ ;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvarEqNvar
+//
+// Description: This function verifies if two Var are the same
+//
+// Input: NVAR *Nvar1 - pointer to the first Var
+// IN NVRAM_STORE_INFO *Info1 - pointer to the first NVRAM_STORE_INFO structure
+// NVAR *Nvar2 - pointer to the second Var
+// IN NVRAM_STORE_INFO *Info2 - pointer to the second NVRAM_STORE_INFO structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvarEqNvar(
+ NVAR *Nvar1, NVRAM_STORE_INFO *Info1,
+ NVAR *Nvar2, NVRAM_STORE_INFO *Info2
+)
+{
+ EFI_GUID *Guid1, *Guid2;
+ UINT8 *Name1, *Name2;
+ BOOLEAN AsciiName = Nvar1->flags&NVRAM_FLAG_ASCII_NAME;
+
+ if (AsciiName != (Nvar2->flags&NVRAM_FLAG_ASCII_NAME)) return FALSE;
+
+ if ( (Info1->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ != (Info2->Flags & NVRAM_STORE_FLAG_NON_VALATILE)
+ ) return FALSE;
+
+ Guid1=NvGetGuid(Nvar1,Info1);
+ Guid2=NvGetGuid(Nvar2,Info2);
+
+ if (guidcmp(Guid1,Guid2)) return FALSE;
+
+ Name1=(UINT8*)NvGetName(Nvar1);
+ Name2=(UINT8*)NvGetName(Nvar2);
+
+ if (AsciiName)
+ {
+ while (*Name1 && *Name1==*Name2) {Name1++; Name2++;}
+
+ if (*Name1!=*Name2) return FALSE;
+ }
+
+ else
+ {
+ CHAR16 *N1 = (CHAR16*)Name1;
+ CHAR16 *N2 = (CHAR16*)Name2;
+
+ while (*N1 && *N1==*N2) {N1++; N2++;}
+
+ if (*N1!=*N2) return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvVarEq
+//
+// Description: This function checks if pNvar GUID and Name ara same with passed one.
+//
+// Input: NVAR* pNVar - pointer to Var
+// CHAR16* sName - Name of the Var to compare
+// EFI_GUID* pGuid - pointer to GUID to compare with
+// UINTN* pNameSize - Pointer to memory where Nane size will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: BOOLEAN - TRUE of FALSE based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NvVarEq(NVAR* pNvar, CHAR16* sName, EFI_GUID* pGuid, UINTN* pNameSize, NVRAM_STORE_INFO *pInfo)
+{
+ UINT8 *pVarGuid, *pNameStart, *pN;
+ pVarGuid=(UINT8*)NvGetGuid(pNvar,pInfo);
+ pN=(UINT8*)NvGetName(pNvar);
+ pNameStart=pN;
+ //-- Check name if ASCII
+ if (pNvar->flags&NVRAM_FLAG_ASCII_NAME)
+ {
+ while (*pN && *pN==*sName) {pN++; sName++;}
+
+ if (*pN!=*sName) return FALSE;
+
+ pN++;
+ }
+
+ else //-- Check name if Unicode
+ {
+ CHAR16 *sN=(CHAR16*)pN;
+
+ while (*sN && *sN==*sName) {sN++; sName++;}
+
+ if (*sN!=*sName) return FALSE;
+
+ pN=(UINT8*)++sN;
+ }
+
+ if (!guidcmp(pVarGuid,pGuid))//---Check GUID
+ {
+ if (pNameSize) *pNameSize=pN-pNameStart;
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+//High level routines that work with a single NV store
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvFindVariable
+//
+// Description: This function searches for Var with specific GUID and Name.
+//
+// Input: CHAR16* sName - Name of the Var to search
+// EFI_GUID* pGuid - pointer to GUID to search
+// UINTN* pNameSize - Pointer to memory where Nane size will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: VOID* - Pointer to found Var, NULL - if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvFindVariable(
+ CHAR16* sName, EFI_GUID* pGuid,
+ UINTN* pNameSize, NVRAM_STORE_INFO *pInfo
+)
+{
+ NVAR* pNvar = NvGetFirstValid(pInfo);
+
+ for (; pNvar; pNvar=NvGetNextValid(pNvar,pInfo))
+ {
+ if (NvVarEq(pNvar,sName,pGuid,pNameSize,pInfo)) return pNvar;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvFindVariableByNvar
+//
+// Description: This function searches for Var equal to one passed.
+//
+// Input: NVAR* SourceNvar - pointer to Var, which need to be found
+// NVRAM_STORE_INFO* SourceInfo - pointer to source NVRAM store structure
+// NVRAM_STORE_INFO* DestInfo - pointer to NVRAM store structure where to search
+//
+// Output: VOID* - Pointer to found Var, NULL - if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* NvFindVariableByNvar(NVAR* SourceNvar,
+ NVRAM_STORE_INFO *SourceInfo, NVRAM_STORE_INFO *DestInfo
+)
+{
+ NVAR* pNvar = NvGetFirstValid(DestInfo);
+
+ for (; pNvar; pNvar=NvGetNextValid(pNvar,DestInfo))
+ {
+ if (NvarEqNvar(SourceNvar, SourceInfo, pNvar, DestInfo)) return pNvar;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetAttributesFromNvar
+//
+// Description: This function returns the attributes from a given Nvar
+//
+// Input: NVAR* pNVar - pointer to Var
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetAttributesFromNvar(
+ IN NVAR *pNvar, IN NVRAM_STORE_INFO *pInfo,
+ OUT UINT32 *Attributes
+)
+{
+ if (!pNvar || !pInfo || !Attributes) return EFI_INVALID_PARAMETER;
+
+ *Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ if ( pNvar->flags & NVRAM_FLAG_RUNTIME )
+ *Attributes|=EFI_VARIABLE_RUNTIME_ACCESS;
+ if ( pInfo->Flags & NVRAM_STORE_FLAG_NON_VALATILE )
+ *Attributes|=EFI_VARIABLE_NON_VOLATILE;
+ if ( pNvar->flags & NVRAM_FLAG_HARDWARE_ERROR_RECORD )
+ *Attributes|=EFI_VARIABLE_HARDWARE_ERROR_RECORD;
+ if ( pNvar->flags & NVRAM_FLAG_AUTH_WRITE )
+ *Attributes|= (UINT8)(*NvGetExtFlags (pNvar) & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetVariableFromNvar
+//
+// Description: This function searches for Var with specific GUID and Name.
+//
+// Input: NVAR* pNVar - pointer to Var
+// UINTN NameSize - size of the Var name
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT UINT8 *Flags - Pointer to memory where Var Flags will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetVariableFromNvar(
+ NVAR *pNvar, UINTN NameSize, OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ IN NVRAM_STORE_INFO *pInfo, OUT UINT8 *Flags
+)
+{
+ UINT8* pN;
+ UINTN Size;
+
+ if (!pNvar || !NvIsVariable(pNvar,pInfo)) return EFI_NOT_FOUND;
+
+ if (Attributes)
+ NvGetAttributesFromNvar(pNvar, pInfo, Attributes);
+
+ // Data
+ pN = (UINT8*)NvGetData(pNvar,NameSize,&Size,pInfo);
+
+ if (*DataSize<Size) { *DataSize=Size; return EFI_BUFFER_TOO_SMALL;}
+
+ *DataSize=Size;
+ MemCpy(Data,pN,Size);
+
+ if (Flags) *Flags=pNvar->flags;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetVariable
+//
+// Description: This function searches for a Var after Var with specific GUID and Name.
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT NVAR **Var - pointer to found Var variable
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ IN NVRAM_STORE_INFO *pInfo, OUT NVAR **Var
+)
+{
+ UINTN NameSize;
+ NVAR* pNvar;
+
+ if (!VariableName || !VendorGuid || !DataSize || !Data && *DataSize)
+ return EFI_INVALID_PARAMETER;
+
+ pNvar = (NVAR*)NvFindVariable(VariableName,VendorGuid,&NameSize,pInfo);
+ if ((Var != NULL) && (pNvar != NULL))
+ *Var = pNvar;
+ return NvGetVariableFromNvar(pNvar,NameSize,Attributes,DataSize,Data,pInfo, NULL);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNameFromNvar
+//
+// Description: This function searches for a Var after Var with specific GUID and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNameFromNvar(
+ IN NVAR *pNvar, IN OUT CHAR16 *VariableName,
+ IN OUT UINTN *VariableNameSize,
+ IN OUT EFI_GUID *VendorGuid, NVRAM_STORE_INFO *pInfo
+)
+{
+ UINTN NameSize;
+ UINT8 *pN, *pNameStart;
+ EFI_GUID* pVarGuid;
+
+ if (!pNvar || !VariableNameSize || !VariableName || !VendorGuid) return EFI_INVALID_PARAMETER;
+
+
+ pN = pNameStart = (UINT8*)NvGetName(pNvar);
+
+ if (pNvar->flags&NVRAM_FLAG_ASCII_NAME)
+ {
+ while (*pN++);
+
+ NameSize = (pN - pNameStart)*2;
+ }
+
+ else
+ {
+ CHAR16* sN=(CHAR16*)pN;
+
+ while (*sN++);
+
+ pN=(UINT8*)sN;
+ NameSize = pN - pNameStart;
+ }
+
+ if (NameSize>*VariableNameSize)
+ {
+ *VariableNameSize=NameSize;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *VariableNameSize=NameSize;
+ pVarGuid=NvGetGuid(pNvar,pInfo);
+
+ if (pNvar->flags&NVRAM_FLAG_ASCII_NAME) while (*VariableName++=*pNameStart++);
+ else
+ {
+ CHAR16* sN = (CHAR16*)pNameStart;
+
+ while (*VariableName++=*sN++);
+ }
+
+ MemCpy(VendorGuid,pVarGuid,sizeof(EFI_GUID));
+ pInfo->pLastReturned = pNvar;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableNvar
+//
+// Description: This function searches for a Var after Var with specific GUID and returns
+// pointer to is using NextNvar parameter
+//
+// Input:
+// IN CHAR16 *VariableName - pointer to a Var Name in Unicode
+// IN OUT EFI_GUID *VendorGuid - pointer to Var GUID
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+// NVAR **NextNvar - pointer to the next varaible's NVAR
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNextVariableNvar(
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ NVRAM_STORE_INFO *pInfo, BOOLEAN Runtime, NVAR **NextNvar
+)
+{
+ NVAR* pNvar;
+
+ if (!VariableName || !VendorGuid) return EFI_INVALID_PARAMETER;
+
+ if (VariableName[0]==0)
+ {
+ pNvar = NvGetFirstValid(pInfo);
+ }
+
+ else
+ {
+ if ( pInfo->pLastReturned!=NULL
+ && NvIsVariable(pInfo->pLastReturned, pInfo)
+ && NvVarEq(pInfo->pLastReturned,VariableName,VendorGuid,NULL, pInfo)
+ )
+ {
+ pNvar=pInfo->pLastReturned;
+ }
+
+ else
+ {
+ UINTN NameSize;
+ pNvar=(NVAR*)NvFindVariable(VariableName,VendorGuid,&NameSize,pInfo);
+
+ if (!pNvar) return EFI_INVALID_PARAMETER;
+ }
+ if (Runtime && !(pNvar->flags & NVRAM_FLAG_RUNTIME) ) return EFI_INVALID_PARAMETER;
+ pNvar=NvGetNextValid(pNvar,pInfo);
+ }
+
+ if (!pNvar)
+ {
+ pInfo->pLastReturned = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ if (Runtime)
+ {
+ while (pNvar && !(pNvar->flags & NVRAM_FLAG_RUNTIME))
+ pNvar=NvGetNextValid(pNvar,pInfo);
+
+ if (!pNvar)
+ {
+ pInfo->pLastReturned = NULL;
+ return EFI_NOT_FOUND;
+ }
+ }
+ if (NextNvar) *NextNvar = pNvar;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableName
+//
+// Description: This function searches for a Var after Var with specific GUID and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNextVariableName(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ NVRAM_STORE_INFO *pInfo, BOOLEAN Runtime
+)
+{
+ NVAR* pNvar;
+ EFI_STATUS Status;
+
+ Status=NvGetNextVariableNvar(VariableName,VendorGuid,pInfo,Runtime,&pNvar);
+ if (EFI_ERROR(Status)) return Status;
+ return NvGetNameFromNvar(
+ pNvar, VariableName, VariableNameSize, VendorGuid, pInfo
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvInitInfoBuffer
+//
+// Description: This function inits NVRAM_STORE_INFO structure.
+//
+// Input: NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// UINTN HeaderSize - Size of the header
+// UINT8 Flags - default Flags
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvInitInfoBuffer(IN NVRAM_STORE_INFO *pInfo, UINTN HeaderSize, UINT8 Flags)
+{
+ NVAR *pVar;
+ pInfo->NvramGuidsAddress = (EFI_GUID*)(pInfo->NvramAddress+pInfo->NvramSize-sizeof(EFI_GUID));
+ pInfo->pFirstVar = pInfo->NvramAddress+HeaderSize;
+ pInfo->NextGuid = 0;
+ pInfo->Flags = Flags;
+ pInfo->LastVarSize = 0;
+ pInfo->pLastReturned = NULL;
+
+ if (!(Flags & NVRAM_STORE_FLAG_NON_VALATILE))
+ {
+ pInfo->pEndOfVars = pInfo->pFirstVar;
+ return;
+ }
+
+ pInfo->pEndOfVars = pInfo->NvramAddress+pInfo->NvramSize;
+ pVar = NvGetFirstValid(pInfo);
+
+ if ((NVAR*)pInfo->pFirstVar!=pVar)
+ {
+ if (pVar!=NULL)
+ {
+ pInfo->pFirstVar=(UINT8*)pVar;
+ }
+
+ else //if pVar==NULL
+ {
+ //there are no valid variables
+ //set pEndOfVars equal to pFirstVar to indicate that variable store is empty
+ pInfo->pEndOfVars = pInfo->pFirstVar;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetDefaultsInfo
+//
+// Description: This function returns Default Variables info.
+//
+// Input: IN const CHAR16* DefaultsVar - name of the defaults Vars
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// OUT NVRAM_STORE_INFO *pOutInfo - pointer to memory where defaults vill be stored
+// NULL - if not found
+//
+// Output: NVRAM_STORE_INFO*
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+NVRAM_STORE_INFO* NvGetDefaultsInfo(IN const CHAR16* DefaultsVar, IN NVRAM_STORE_INFO *pInInfo, OUT NVRAM_STORE_INFO *pOutInfo)
+{
+ UINTN NameSize;
+ NVAR* pNvar;
+ pNvar = (NVAR*)NvFindVariable(
+ (CHAR16*)DefaultsVar, (EFI_GUID*)&AmiDefaultsVariableGuid,
+ &NameSize,pInInfo
+ );
+
+ if (!pNvar) return NULL;
+
+ pOutInfo->NvramAddress = (UINT8*)NvGetData(
+ pNvar,NameSize,
+ &pOutInfo->NvramSize,pInInfo
+ );
+
+ if (pOutInfo->NvramAddress==NULL) return NULL;
+
+ NvInitInfoBuffer(
+ pOutInfo, 0,
+ NVRAM_STORE_FLAG_NON_VALATILE
+ | NVRAM_STORE_FLAG_READ_ONLY
+ | NVRAM_STORE_FLAG_DO_NOT_ENUMERATE
+ );
+ return pOutInfo;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetVariable2
+//
+// Description: This function searches for Var with specific GUID, Name and Enty number
+// not bigger than InfoCount parameter.
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+// UINT32 InfoCount - Max NVRAM entry number
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetVariable2(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data,
+ UINT32 InfoCount, NVRAM_STORE_INFO *Info
+)
+{
+ UINT32 i;
+
+ for (i=0; i<InfoCount; i++)
+ {
+ EFI_STATUS Status = NvGetVariable(
+ VariableName,VendorGuid,Attributes,DataSize,Data,&Info[i],NULL
+ );
+
+ if (Status!=EFI_NOT_FOUND) return Status;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvGetNextVariableName2
+//
+// Description: This function searches for Var with specific GUID and Enty number
+// not betwin LastInfoIndex - InfoCount parameter and returns it's Name.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID will be stored
+// UINT32 InfoCount - Max NVRAM entry number
+// NVRAM_STORE_INFO *pInfo - pointer to NVRAM store structure
+// UINT32 *LastInfoIndex - NVRAM entry number to starf from
+// BOOLEAN Runtime - search for Var with NVRAM_FLAG_RUNTIME set
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NvGetNextVariableName2(
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid,
+ UINT32 InfoCount, NVRAM_STORE_INFO *pInfo, UINT32 *LastInfoIndex,
+ BOOLEAN Runtime
+)
+{
+ UINT32 i;
+ EFI_STATUS Status;
+ NVAR* Nvar;
+ CHAR16 OrgName;
+
+ OrgName = VariableName[0];
+ // Preserve first letter of passed Var name, for the case when NvGetNameFromNvar returns EFI_BUFFER_TOO_SMALL right
+ // after setting first letter of name to 0 for search in the next Varstore
+ if (VariableName[0]==0 && LastInfoIndex) *LastInfoIndex=0;
+
+ for ( i=(LastInfoIndex) ? *LastInfoIndex : 0
+ ; i<InfoCount; i++
+ )
+ {
+ Status=NvGetNextVariableNvar(VariableName,VendorGuid,&pInfo[i],Runtime,&Nvar);
+ if (!EFI_ERROR(Status) && pInfo[i].Flags & NVRAM_STORE_FLAG_DO_NOT_ENUMERATE){
+ while ( Nvar ){
+ UINT32 j;
+ for (j = 0; j < i; j++)
+ if (NvFindVariableByNvar(Nvar, &pInfo[i], &pInfo[j] ))
+ break;
+ if (j==i) break;
+ Nvar=NvGetNextValid(Nvar,&pInfo[i]);
+ if ( Runtime ){
+ while (Nvar && !(Nvar->flags & NVRAM_FLAG_RUNTIME))
+ Nvar=NvGetNextValid(Nvar,&pInfo[i]);
+ }
+ }
+ if (!Nvar)
+ {
+ pInfo[i].pLastReturned = NULL;
+ Status=EFI_NOT_FOUND;
+ }
+ }
+
+ if (!EFI_ERROR(Status))
+ {
+ if (LastInfoIndex) *LastInfoIndex=i;
+ Status = NvGetNameFromNvar(
+ Nvar, VariableName, VariableNameSize, VendorGuid, &pInfo[i]
+ );
+ if (EFI_ERROR(Status)) {
+ VariableName[0] = OrgName; //Restore first letter in case it was set to 0 before going to new Varstore
+ }
+ return Status;
+ }
+
+ //When variable with VariableName/VendorGuid
+ //is not is the store EFI_INVALID_PARAMETER is returned
+ //and we have to keep searching.
+ //EFI_NOT_FOUND is returned when variable with VariableName/VendorGuid
+ //is found but it's the last variable in the store.
+ //In this case we have to return first variable from the next store
+ //In order to do that we need to reset the name
+ if (Status==EFI_NOT_FOUND)
+ {
+ VariableName[0]=0;
+ }
+
+ else
+ {
+ //If we are here the Status should be EFI_INVALID_PARAMETER,
+ //which means the variable with VariableName/VendorGuid has not been found.
+ //If we were using LastInfoIndex, the fact that variable has not been found
+ //indicates that LastInfoIndex is invalid and we have to restart the search.
+ //The condition below checks if LastInfoIndex has been used during this iteration.
+ //Seting i to -1 in conjunction with i++ at the end of the iteration restarts
+ //the search from 0.
+ if (LastInfoIndex && i!=0 && i==*LastInfoIndex){
+ i=(UINT32)-1;
+ *LastInfoIndex = 0;
+ }
+ }
+ }
+
+ if (LastInfoIndex) *LastInfoIndex=0;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNvramFfsFileStatePtr
+//
+// Description: This function searches for firmvare vol header and returns pointer to its State field
+//
+// Input: NVRAM_STORE_INFO *Info - pointer to NVRAM store structure
+//
+// Output: EFI_FFS_FILE_STATE* - pointer to Ffs header State field
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_FFS_FILE_STATE* GetNvramFfsFileStatePtr(NVRAM_STORE_INFO *Info)
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)Info->NvramAddress;
+
+ if (FwVolHeader->FvLength == Info->NvramSize)
+ {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(
+ Info->NvramAddress + FwVolHeader->HeaderLength
+ );
+ return &FfsFileHeader->State;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNvramFfsFileState
+//
+// Description: This function searches for the header of the NVRAM image FFS file and returns the value of its State field
+//
+// Input: NVRAM_STORE_INFO *Info - pointer to NVRAM store structure
+//
+// Output: EFI_FFS_FILE_STATE - Ffs header State
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_FFS_FILE_STATE GetNvramFfsFileState(NVRAM_STORE_INFO *Info)
+{
+ EFI_FFS_FILE_STATE State;
+ EFI_FFS_FILE_STATE *StatePtr = GetNvramFfsFileStatePtr(Info);
+ if (StatePtr==NULL) return EFI_FILE_HEADER_INVALID;
+ State = (FlashEmpty==0) ? *StatePtr : ~*StatePtr;
+ if (State==0) State = EFI_FILE_HEADER_INVALID;
+ return State;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMainNvramStoreValid
+//
+// Description: This function verifies if main NVRAM storage is valid
+//
+// Input:
+// NVRAM_STORE_INFO *MainInfo - pointer to Main NVRAM storage descriptor
+// VOID *BackUpAddress - address of the back up storage
+//
+// Output: BOOLEAN
+// TRUE - the main NVRAM storage is valid
+// FALSE - the main NVRAM storage is invalid. Back up srorage should be used.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsMainNvramStoreValid(
+ NVRAM_STORE_INFO *MainInfo, VOID *BackUpAddress,
+ BOOLEAN *BackupStoreValid
+){
+ NVRAM_STORE_INFO BackupNvram;
+ EFI_FFS_FILE_STATE MainState;
+ EFI_FFS_FILE_STATE BackupState;
+
+ if (BackUpAddress==NULL) return TRUE;
+ BackupNvram.NvramAddress = BackUpAddress;
+ BackupNvram.NvramSize = MainInfo->NvramSize;
+ MainState = GetNvramFfsFileState(MainInfo);
+ BackupState = GetNvramFfsFileState(&BackupNvram);
+// State Transitions:
+// Main Backup Valid Store
+// = Initial State After Firmware Flashing
+// 1. DATA_VALID HEADER_INVALID Main
+// = Update Cycle 1
+// 2. DATA_VALID HEADER_VALID Main
+// 3. MARKED_FOR_UPDATE HEADER_VALID Main
+// 4. MARKED_FOR_UPDATE DATA_VALID Backup
+// = Update Cycle 1 is Over
+// = Update Cycle 2
+// 5. HEADER_VALID DATA_VALID Backup
+// 6. HEADER_VALID MARKED_FOR_UPDATE Backup
+// 7. DATA_VALID MARKED_FOR_UPDATE Main
+// = Update Cycle 2 is Over
+// = Update Cycle 3
+// 8. DATA_VALID HEADER_VALID Main
+// Stae 8 == State 2
+ if ( (MainState & EFI_FILE_DATA_VALID)==0
+ || (MainState & EFI_FILE_MARKED_FOR_UPDATE)!=0
+ &&(BackupState & EFI_FILE_DATA_VALID)!=0
+ ||(MainState & ~VALID_STATE_FLAGS)!=0
+ ){
+ if (BackupStoreValid)
+ *BackupStoreValid=
+ ((BackupState & EFI_FILE_DATA_VALID)!=0)
+ &&((BackupState & ~VALID_STATE_FLAGS)==0)
+ ;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/Nvme.chm b/Core/EM/Nvme/Nvme.chm
new file mode 100644
index 0000000..1d8fee0
--- /dev/null
+++ b/Core/EM/Nvme/Nvme.chm
Binary files differ
diff --git a/Core/EM/Nvme/Nvme.cif b/Core/EM/Nvme/Nvme.cif
new file mode 100644
index 0000000..0b43f6e
--- /dev/null
+++ b/Core/EM/Nvme/Nvme.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "Nvme"
+ category = eModule
+ LocalRoot = "Core\EM\Nvme\"
+ RefName = "Nvme"
+[files]
+"Nvme.sdl"
+"Nvme.mak"
+"Nvme.sd"
+"Nvme.uni"
+"Nvme.chm"
+"NvmeSetup.c"
+"NvmeBus.c"
+"NvmePassthru.c"
+"NvmeComponentName.c"
+"NvmeIncludes.h"
+"NvmeBus.h"
+"NvmePassthru.h"
+[parts]
+"NvmeControllerLib"
+"NvmeSmm"
+"NVMEINT13"
+"NvmeProtocol"
+<endComponent>
diff --git a/Core/EM/Nvme/Nvme.mak b/Core/EM/Nvme/Nvme.mak
new file mode 100644
index 0000000..4e9feb6
--- /dev/null
+++ b/Core/EM/Nvme/Nvme.mak
@@ -0,0 +1,170 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/NVMe/Nvme.mak 4 5/18/15 2:52a Karthikar $
+#
+# $Date: 5/18/15 2:52a $
+#
+# $Log: /Alaska/SOURCE/Modules/NVMe/Nvme.mak $
+#
+# 4 5/18/15 2:52a Karthikar
+# [TAG] EIP216763
+# [Category] Improvement
+# [Description] Update the Aptio 4.x Nvme driver to Aptio 5.x Nvme driver
+# Label 05
+# [Files] Nvme.mak,NvmeBus.c, NvmeBus.h, NvmeController.c,
+# NvmePassthru.c,NvmePassthru.h, NvmeSmm.c, NvmExpressPassThru.h
+#
+# 3 5/14/15 2:38a Karthikar
+#
+# 2 9/04/14 7:31a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files]
+# Nvme.cif
+# Nvme.mak
+# Nvme.uni
+# Nvme.chm
+# NvmeSetup.c
+# NvmeBus.c
+# NvmeComponentName.c
+# NvmeIncludes.h
+# NvmeBus.h
+# [NvmeControllerLib]
+# [NvmeSmm]
+# [NVMEINT13]
+# [NvmeProtocol]
+#
+# 1 6/20/14 6:27a Anandakrishnanl
+# [TAG] EIP172958
+# [Category] New Feature
+# [Description] Nvme Driver Intial Checkin
+# [Files] Nvme.cif
+# Nvme.sdl
+# Nvme.mak
+# Nvme.sd
+# Nvme.uni
+# Nvme.chm
+# NvmeSetup.c
+# NvmeBus.c
+# NvmeController.c
+# NvmeComponentName.c
+# NvmeIncludes.h
+# NvmeBus.h
+# NvmeController.h
+#
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NVMe/Nvme.mak $
+#
+# 4 5/18/15 2:52a Karthikar
+# [TAG] EIP216763
+# [Category] Improvement
+# [Description] Update the Aptio 4.x Nvme driver to Aptio 5.x Nvme driver
+# Label 05
+# [Files] Nvme.mak,NvmeBus.c, NvmeBus.h, NvmeController.c,
+# NvmePassthru.c,NvmePassthru.h, NvmeSmm.c, NvmExpressPassThru.h
+#
+# 3 5/14/15 2:38a Karthikar
+#
+# 2 9/04/14 7:31a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files]
+# Nvme.cif
+# Nvme.mak
+# Nvme.uni
+# Nvme.chm
+# NvmeSetup.c
+# NvmeBus.c
+# NvmeComponentName.c
+# NvmeIncludes.h
+# NvmeBus.h
+# [NvmeControllerLib]
+# [NvmeSmm]
+# [NVMEINT13]
+# [NvmeProtocol]
+#
+# 1 6/20/14 6:27a Anandakrishnanl
+# [TAG] EIP172958
+# [Category] New Feature
+# [Description] Nvme Driver Intial Checkin
+# [Files] Nvme.cif
+# Nvme.sdl
+# Nvme.mak
+# Nvme.sd
+# Nvme.uni
+# Nvme.chm
+# NvmeSetup.c
+# NvmeBus.c
+# NvmeController.c
+# NvmeComponentName.c
+# NvmeIncludes.h
+# NvmeBus.h
+# NvmeController.h
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Nvme.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#************************************************************************
+all : Nvme
+
+Nvme : $(BUILD_DIR)\Nvme.mak NvmeBin
+
+$(BUILD_DIR)\Nvme.mak : $(NVME_DIR)\$(@B).cif $(NVME_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(NVME_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+NvmeBin: $(AMIDXELIB) $(NVMECONTROLLERLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Nvme.mak all\
+ GUID=634E8DB5-C432-43BE-A653-9CA2922CC458\
+ ENTRY_POINT=NvmeBusEntryPoint \
+ TYPE=BS_DRIVER \
+ COMPRESS=1 HAS_RESOURCES=1\
+ "OBJECTS=$(BUILD_DIR)\$(NVME_DIR)\NvmeBus.obj\
+ $(BUILD_DIR)\$(NVME_DIR)\NvmeComponentName.obj\
+ $(BUILD_DIR)\$(NVME_DIR)\NvmePassthru.obj"
+
+SetupSdbs :$(BUILD_DIR)\Nvme.mak NVMESDB
+SetupBin : $(BUILD_DIR)\NvmeSetup.obj
+
+NVMESDB :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Nvme.mak all\
+ TYPE=SDB NAME=Nvme MAKEFILE=$(BUILD_DIR)\Nvme.mak\
+ "STRING_CONSUMERS=$(NVME_DIR)\Nvme.sd $(NVME_DIR)\NvmeSetup.c "
+
+$(BUILD_DIR)\NvmeSetup.obj : $(NVME_DIR)\NvmeSetup.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(NVME_DIR)\NvmeSetup.c
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/Nvme/Nvme.sd b/Core/EM/Nvme/Nvme.sd
new file mode 100644
index 0000000..327bf96
--- /dev/null
+++ b/Core/EM/Nvme/Nvme.sd
@@ -0,0 +1,170 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/Nvme.sd 2 5/19/15 5:03a Ksudarsanan $
+//
+// $Date: 5/19/15 5:03a $
+//
+// $Log: /Alaska/SOURCE/Modules/NVMe/Nvme.sd $
+//
+// 2 5/19/15 5:03a Ksudarsanan
+// [TAG] EIP218818
+// [Category] Improvement
+// [Description] Aptio 4.x: When NVMe device is not connect then in BIOS
+// Setup should display "No Nvme device found"
+// [Files] Nvme.sd, Nvme.uni, NvmeSetup.c
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/Nvme.sd $
+//
+// 2 5/19/15 5:03a Ksudarsanan
+// [TAG] EIP218818
+// [Category] Improvement
+// [Description] Aptio 4.x: When NVMe device is not connect then in BIOS
+// Setup should display "No Nvme device found"
+// [Files] Nvme.sd, Nvme.uni, NvmeSetup.c
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//*************************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Nvme.sd
+//
+// Description: Nvme Driver Setup Page
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef FORM_SET_TYPEDEF
+#include "Token.h"
+#endif
+
+#ifdef SETUP_DATA_DEFINITION
+// These definitions will be converted by the build process
+// to a definitions of SETUP_DATA fields.
+ UINT8 ShowNVMeDrive[4];
+ UINT8 DeviceCount;
+#endif
+
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+ #define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+ #define NVMe_INFO_DISPLAY(HELP_STRING, CONTROLLER_STRING, DEVICE_STRING,INDEX)\
+ suppressif ideqval SETUP_DATA.ShowNVMeDrive[INDEX] == 0; \
+ text \
+ help = HELP_STRING, \
+ text = CONTROLLER_STRING, \
+ text = DEVICE_STRING, \
+ flags = 0, \
+ key = 0;\
+ endif;
+#endif
+
+//Select Top level menu itmem (forset) for you pages
+#ifdef ADVANCED_FORM_SET
+
+ #ifdef FORM_SET_GOTO
+ // Define forms
+
+ // Define goto commands for the forms defined in this file
+ goto NVME_CONFIG_FORM_ID,
+ prompt = STRING_TOKEN (STR_NVME_CONFIG_FORM),
+ help = STRING_TOKEN (STR_NVME_CONFIG_FORM_HELP);
+
+ #endif
+
+ #ifdef FORM_SET_FORM
+
+ #ifndef NVME_FORM_NVME_CONFIG
+ #define NVME_FORM_NVME_CONFIG
+
+ form formid = AUTO_ID(NVME_CONFIG_FORM_ID),
+ title = STRING_TOKEN (STR_NVME_CONFIG_FORM);
+
+ SUBTITLE(STRING_TOKEN(STR_NVME_SUBTITLE_STRING))
+ SEPARATOR
+
+ NVMe_INFO_DISPLAY( STRING_TOKEN(STR_NVME_HELP_STRING), STRING_TOKEN(STR_NVME0_CONTROLLER), STRING_TOKEN(STR_NVME0_NAME),0)
+ NVMe_INFO_DISPLAY( STRING_TOKEN(STR_NVME_HELP_STRING), STRING_TOKEN(STR_NVME1_CONTROLLER), STRING_TOKEN(STR_NVME1_NAME),1)
+ NVMe_INFO_DISPLAY( STRING_TOKEN(STR_NVME_HELP_STRING), STRING_TOKEN(STR_NVME2_CONTROLLER), STRING_TOKEN(STR_NVME2_NAME),2)
+ NVMe_INFO_DISPLAY( STRING_TOKEN(STR_NVME_HELP_STRING), STRING_TOKEN(STR_NVME3_CONTROLLER), STRING_TOKEN(STR_NVME3_NAME),3)
+
+ suppressif NOT ideqval SETUP_DATA.DeviceCount == 0;
+ SUBTITLE(STRING_TOKEN(STR_NO_NVME_DEVICE))
+ endif;
+
+ endform; // End of NVME_CONFIG_FORM_ID
+
+ #endif // End of NVME_FORM_NVME_CONFIG
+
+ #endif // End of FORM_SET_FORM
+
+#endif // End of ADVANCED_FORM_SET
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Nvme/Nvme.sdl b/Core/EM/Nvme/Nvme.sdl
new file mode 100644
index 0000000..982578f
--- /dev/null
+++ b/Core/EM/Nvme/Nvme.sdl
@@ -0,0 +1,83 @@
+TOKEN
+ Name = "NVMe_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable NVMe support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "NVME_VERBOSE_PRINT"
+ Value = "0"
+ Help = "Token to Enable/Disable Versbose Mode."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "NVME_DIR"
+End
+
+TOKEN
+ Name = "NVME_SETUP"
+ Value = "1"
+ Help = "Enable if NVMe setup controls from NVME eModule needs to be displayd in setup"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NVME_BUS_DRIVER_VERSION"
+ Value = "1"
+ Help = "NVMe Bus driver version # reported in Driver Binding Protocol"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes Nvme.mak to Project"
+ File = "Nvme.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Nvme.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Nvme.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(NVME_DIR)\Nvme.sd"
+ Parent = "SETUP_DEFINITIONS"
+ InvokeOrder = AfterParent
+ Token = "NVME_SETUP" "=" "1"
+End
+
+ELINK
+ Name = "$(NVME_DIR)\NvmeSetup.c"
+ Parent = "SetupCallbackFiles"
+ InvokeOrder = AfterParent
+ Token = "NVME_SETUP" "=" "1"
+End
+
+ELINK
+ Name = "InitNvmeStrings,"
+ Parent = "SetupStringInit"
+ InvokeOrder = AfterParent
+ Token = "NVME_SETUP" "=" "1"
+End
+
+ELINK
+ Name = "$(NVME_DIR)\Nvme.uni"
+ Parent = "SetupStringFiles"
+ InvokeOrder = AfterParent
+ Token = "NVME_SETUP" "=" "1"
+End
+
diff --git a/Core/EM/Nvme/Nvme.uni b/Core/EM/Nvme/Nvme.uni
new file mode 100644
index 0000000..4f931cb
--- /dev/null
+++ b/Core/EM/Nvme/Nvme.uni
Binary files differ
diff --git a/Core/EM/Nvme/NvmeBus.c b/Core/EM/Nvme/NvmeBus.c
new file mode 100644
index 0000000..dd921fc
--- /dev/null
+++ b/Core/EM/Nvme/NvmeBus.c
@@ -0,0 +1,2793 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeBus.c 8 12/08/16 4:17a Karthikar $
+//
+// $Revision: 8 $
+//
+// $Date: 12/08/16 4:17a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeBus.c $
+//
+// 8 12/08/16 4:17a Karthikar
+// [TAG] EIP307568
+// [Category] Bug Fix
+// [Symptom] Legacy Installation and booting fails in
+// (INT)_a_4.6.5.5_NVMe_006
+// [RootCause] Since this NvmeSmm_Support token is not included in
+// Token.h, TransferNvmeDataToSmram() dint get control.
+// [Solution] Added NvmeSmm_Support token in Token.h
+// [Files] NvmeBus.c
+//
+// 7 3/17/16 10:25a Anbuprakashp
+// [TAG] EIP258388
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error when disable CSM_SUPPORT token
+// [RootCause] NvmeSmm driver is dependent on NvmeInt13 driver which is
+// disabled if CSM_SUPPORT token is off.
+// [Solution] NvmeSmm driver will be disabled if CSM_SUPPORT,
+// NVMEINT13_SUPPORT sdl tokens are OFF.
+// [Files] NvmeSmm.sdl,
+// NvmeBus.c
+//
+// 6 5/14/15 2:38a Karthikar
+//
+// 5 4/08/15 10:21a Anbuprakashp
+// [TAG] EIP212320
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] CPU exception in Nvme Driver if
+// PcdCpuSmmCodeAccessCheckEnable is enabled
+// [RootCause] BootService call shouldn't be used inside SMM function.
+// if PcdCpuSmmCodeAccessCheckEnable is enabled, It causes CPU exception.
+// [Solution] Changes made to avoid BootService call inside SMM function
+// [Files] NvmeSmm.c
+// NvmeBus.c
+// AmiNvmeController.h
+//
+// 4 3/09/15 2:51a Rameshr
+// [TAG] EIP202328
+// [Category] Improvement
+// [Description] IO Completion Size decided based on the size reported
+// by device.
+// [Files] NvmeBus.c
+//
+// 3 9/23/14 2:28a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Add Legacy Boot support in Aptio 4.x Nvme driver - NON
+// PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+//
+// 2 9/04/14 7:34a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files]
+// Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeBus.c
+//
+// Description: Provides Nvme Block IO protocol
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "NvmeIncludes.h"
+#include "NvmeBus.h"
+#include "NvmePassthru.h"
+#include <EFI.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\BlockIo.h>
+
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#else
+EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+#endif
+
+// Used by NVMe legacy boot support
+UINT8 gInt13DeviceAddress = 1;
+VOID *gLegacyNvmeBuffer = NULL;
+
+#if (EFI_SPECIFICATION_VERSION > 0x00020000)
+extern EFI_COMPONENT_NAME2_PROTOCOL gNvmeBusControllerDriverName;
+#else
+extern EFI_COMPONENT_NAME_PROTOCOL gNvmeBusControllerDriverName;
+#endif
+
+EFI_GUID gEfiDiskInfoNvmeInterfaceGuid = EFI_DISK_INFO_NVME_INTERFACE_GUID;
+EFI_GUID gEfiDiskInfoProtocolGuid = EFI_DISK_INFO_PROTOCOL_GUID;
+static EFI_GUID gAmiNvmeControllerProtocolGuid = AMI_NVME_CONTROLLER_PROTOCOL_GUID;
+static EFI_GUID gAmiNvmePassThruProtocolGuid = AMI_NVME_PASS_THRU_PROTOCOL_GUID;
+static EFI_GUID gAmiNvmeLegacyProtocolGuid = AMI_NVME_LEGACY_PROTOCOL_GUID;
+static EFI_GUID gAmiSmmNvmeCommunicationGuid = AMI_SMM_NVME_COMMUNICATION_GUID;
+EFI_GUID gEfiNvmExpressPassThruProtocolGuid = EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL_GUID;
+
+EFI_DRIVER_BINDING_PROTOCOL gNvmeBusDriverBinding = {
+ NvmeBusSupported,
+ NvmeBusStart,
+ NvmeBusStop,
+ NVME_BUS_DRIVER_VERSION, // version
+ NULL, // ImageHandle
+ NULL // DriverBindingHandle
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeBusEntryPoint
+//
+// Description: Installs gNvmeBusDriverBinding protocol
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InitAmiLib InstallMultipleProtocolInterfaces DListInit
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Initialize Ami Lib.
+// 2. Install Driver Binding Protocol
+// 3. Return EFI_SUCCESS.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeBusEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ // Print Verbose messages
+ // Enable NVME_VERBOSE_PRINT in SDL file. Make sure PcdDebugPrintErrorLevel
+ // is set to PcdsPatchableInModule. Sometime is it is overridden in Platform SDL.
+ // So change it accordingly.
+
+
+ gNvmeBusDriverBinding.DriverBindingHandle = NULL;
+ gNvmeBusDriverBinding.ImageHandle=ImageHandle;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gNvmeBusDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,&gNvmeBusDriverBinding,
+ &gEfiComponentName2ProtocolGuid, &gNvmeBusControllerDriverName,
+ NULL
+ );
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeBusSupported
+//
+// Description: Checks whether it is a Nvme controller or not.
+// If 'yes', return SUCCESS else ERROR
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeBusSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ PCI_TYPE00 PciConfig;
+
+ // Check for Valid SATA Device Path. If no return UNSUPPORTED
+ // Check if Controller is Nvme or not?
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIO,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = PciIO->Pci.Read ( PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PCI_TYPE00),
+ &PciConfig
+ );
+
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Check for MASS Storage controller, Non-Volatile and NVMHCI interface
+ if (IS_CLASS3 (&PciConfig,
+ PCI_CLASS_MASS_STORAGE,
+ PCI_CLASS_MASS_STORAGE_SOLID_STATE,
+ PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMHCI)) {
+
+ return EFI_SUCCESS;
+
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeBusStart
+//
+// Description: Installs Nvme Block IO Protocol
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeBusStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+)
+{
+
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController = NULL;
+ IDENTIFY_CONTROLLER_DATA *IdentifyData = NULL;
+ UINT32 *ActiveNameSpaceIDs = NULL;
+ UINT32 i;
+ AMI_NVME_PASS_THRU_PROTOCOL *AmiNvmePassThru;
+ NVM_EXPRESS_PASS_THRU_INSTANCE *NvmePassthruInstance = NULL;
+ EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *EfiNvmExpressPassThru;
+
+ PROGRESS_CODE(EFI_IO_BUS_ATA_ATAPI | EFI_IOB_PC_INIT);
+
+ // Get the PciIO interface
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIO,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TRACE((-1,"\nNVMe Driver Detection and Configuratiion starts\n"));
+
+ // Do Controller Init
+ Status = InitializeNvmeController(Controller, This->DriverBindingHandle, &NvmeController);
+
+ if (EFI_ERROR(Status)) {
+ goto Error_Path;
+ }
+
+ // Get the IdentifyData
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (IDENTIFY_CONTROLLER_DATA),
+ (VOID**)&IdentifyData
+ );
+
+ if (EFI_ERROR(Status)) {
+ goto Error_Path_1;
+ }
+
+ pBS->SetMem(IdentifyData, sizeof(IDENTIFY_CONTROLLER_DATA), 0);
+ NvmeController->IdentifyControllerData = IdentifyData;
+
+ // Get IdentifyController Data Structure
+ Status = GetIdentifyData (NvmeController, (UINT8 *)IdentifyData, 1, 0);
+ if (EFI_ERROR(Status)) {
+ goto Error_Path_1;
+ }
+
+ // Get the list of Active Namespace IDs
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(4096),
+ (EFI_PHYSICAL_ADDRESS*)&(ActiveNameSpaceIDs));
+
+ if (EFI_ERROR(Status)) {
+ goto Error_Path_1;
+ }
+
+ pBS->SetMem(ActiveNameSpaceIDs, 4096, 0);
+
+ NvmeController->ActiveNameSpaceIDs = ActiveNameSpaceIDs;
+
+ // Since "Get list of Active NameSpace IDs" isn't working
+ // use alternate method to get the active name space. Zero is reserved
+ for (i=1; i < IdentifyData->NN + 1; i++ ) {
+ ActiveNameSpaceIDs[i] = i;
+ }
+
+ Status = EnumerateActiveNameSpace (NvmeController);
+ if (EFI_ERROR(Status)) {
+ goto Error_Path_1;
+ }
+
+ // Is there any active name space discovered
+ if(IsListEmpty(&NvmeController->ActiveNameSpaceList)) {
+ goto exit_NvmeBusStart;
+ }
+
+ // Create Submission and Completion Queue1
+ NvmeController->NVMQueueNumber = 1;
+ Status = CreateAdditionalSubmissionCompletionQueue(NvmeController,
+ NvmeController->NvmeCmdWrapper,
+ NvmeController->NVMQueueNumber,
+ NvmeController->MaxQueueEntrySupported >= QUEUE1_SIZE ? QUEUE1_SIZE : NvmeController->MaxQueueEntrySupported
+ );
+ if (EFI_ERROR(Status)) {
+ goto Error_Path;
+ }
+ Status = InstallBlockIoDiskInfo(This, NvmeController);
+ if (EFI_ERROR(Status)) {
+ goto Error_Path_1;
+ }
+
+ // Install NvmePassThru protocol
+ Status = pBS->OpenProtocol(
+ Controller,
+ &gAmiNvmePassThruProtocolGuid,
+ (VOID **)&AmiNvmePassThru,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR(Status)) {
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(AMI_NVME_PASS_THRU_PROTOCOL),
+ (VOID**)&AmiNvmePassThru
+ );
+ if (!EFI_ERROR(Status)) {
+ AmiNvmePassThru->ExecuteNvmeCmd = ExecuteNvmeCmd;
+ pBS->InstallMultipleProtocolInterfaces(
+ &Controller,
+ &gAmiNvmePassThruProtocolGuid,
+ AmiNvmePassThru,
+ NULL
+ );
+ }
+
+ }
+ // Installing EfiNvmExpressPassthru protocol
+ Status = pBS->OpenProtocol(
+ Controller,
+ &gEfiNvmExpressPassThruProtocolGuid,
+ (VOID **)&EfiNvmExpressPassThru,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if ( EFI_ERROR(Status) ) {
+ // Allocate memory for NVM_EXPRESS_PASS_THRU_INSTANCE structure
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(NVM_EXPRESS_PASS_THRU_INSTANCE),
+ (VOID**)&NvmePassthruInstance
+ );
+
+ if( !EFI_ERROR(Status) ) {
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(EFI_NVM_EXPRESS_PASS_THRU_MODE),
+ (VOID**)&NvmePassthruInstance->EfiNvmExpressPassThru.Mode
+ );
+ if(EFI_ERROR(Status)) {
+ pBS->FreePool(NvmePassthruInstance);
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+
+ EfiNvmExpressPassThru = (EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL*)&(NvmePassthruInstance->EfiNvmExpressPassThru);
+
+ NvmePassthruInstance->NvmeControllerProtocol = NvmeController;
+ NvmePassthruInstance->ControllerHandle = Controller;
+
+ EfiNvmExpressPassThru->Mode->Attributes = EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_PHYSICAL |
+ EFI_NVM_EXPRESS_PASS_THRU_ATTRIBUTES_CMD_SET_NVME;
+ EfiNvmExpressPassThru->Mode->IoAlign = 2; // DWORD aligned
+ EfiNvmExpressPassThru->Mode->NvmeVersion = 0;
+ EfiNvmExpressPassThru->PassThru = NvmePassThru;
+ EfiNvmExpressPassThru->GetNextNamespace = GetNextNamespace;
+ EfiNvmExpressPassThru->BuildDevicePath = BuildDevicePath;
+ EfiNvmExpressPassThru->GetNameSpace = GetNamespace;
+
+ pBS->InstallMultipleProtocolInterfaces( &NvmePassthruInstance->ControllerHandle,
+ &gEfiNvmExpressPassThruProtocolGuid,
+ &NvmePassthruInstance->EfiNvmExpressPassThru,
+ NULL
+ );
+ }
+ }
+
+exit_NvmeBusStart:
+ TRACE((-1,"\nNVMe Driver Detection and Configuratiion Ends with Status = EFI_SUCCESS\n"));
+ return EFI_SUCCESS;
+Error_Path_1:
+ // Uninstall NvmeController
+ pBS->UninstallMultipleProtocolInterfaces(
+ Controller,
+ &gAmiNvmeControllerProtocolGuid,
+ NvmeController,
+ NULL
+ );
+Error_Path:
+ pBS->CloseProtocol ( Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ TRACE((-1,"\nNVMe Driver Detection and Configuratiion Ends with Status %r\n", Status));
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeBusStop
+//
+// Description: Uninstall all devices installed in start procedure.
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN EFI_HANDLE Controller,
+// IN UINTN NumberOfChildren,
+// IN EFI_HANDLE *ChildHandleBuffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: OpenProtocol CloseProtocol
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeBusStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+
+ EFI_STATUS Status;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace;
+ UINTN Index = 0;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ NVME_DEVICE_PATH *NvmeDevicePath;
+ EFI_LIST_ENTRY *LinkData;
+ EFI_LIST_ENTRY *ForwardLink;
+ AMI_NVME_PASS_THRU_PROTOCOL *AmiNvmePassThru;
+ EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *NvmExpressPassthruProtocol;
+ NVM_EXPRESS_PASS_THRU_INSTANCE *NvmePassthruInstance = NULL;
+
+ // Check if gAmiNvmeControllerProtocolGuid is installed on the device
+ Status = pBS->OpenProtocol( Controller,
+ &gAmiNvmeControllerProtocolGuid,
+ (VOID **)&NvmeController,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check if ChildHandleBuffer is valid
+ //
+ if (NumberOfChildren) {
+ while (NumberOfChildren) {
+ // Does the child handle have the correct devicepath
+ Status = pBS->OpenProtocol(
+ ChildHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ // Locate Nvme devicepath
+ NvmeDevicePath = (NVME_DEVICE_PATH *) DevicePath;
+
+ while (!isEndNode((EFI_DEVICE_PATH_PROTOCOL *)NvmeDevicePath)) {
+
+ //NvmeDevicePath = (NVME_DEVICE_PATH *)DPNextInstance (&((EFI_DEVICE_PATH_PROTOCOL *)(NvmeDevicePath)), NULL);
+ if (NvmeDevicePath && NvmeDevicePath->Header.Type == MESSAGING_DEVICE_PATH && \
+ NvmeDevicePath->Header.SubType == MSG_NVME_DP){
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink; \
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ ) {
+
+ ActiveNameSpace = _CR(LinkData, ACTIVE_NAMESPACE_DATA, Link);
+
+ // Is it the correct ActiveNameSpace
+ if (ActiveNameSpace->IdentifyNamespaceData.EUI64 == NvmeDevicePath->EUI64 && \
+ ActiveNameSpace->ActiveNameSpaceID == NvmeDevicePath->Nsid ) {
+
+ // Uninstall and close the protocols
+ Status = pBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index]);
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ // Check if BlockIO is installed
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL);
+
+ if (Status == EFI_SUCCESS) {
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid,
+ &(ActiveNameSpace->NvmeBlockIO),
+ NULL);
+ }
+ // Check if DiskInfo is installed
+ Status = pBS->OpenProtocol( ChildHandleBuffer[Index],
+ &gEfiDiskInfoProtocolGuid,
+ NULL,
+ This->DriverBindingHandle,
+ ChildHandleBuffer[Index],
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (Status == EFI_SUCCESS) {
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDiskInfoProtocolGuid,
+ &(ActiveNameSpace->NvmeDiskInfo),
+ NULL);
+ }
+
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ ChildHandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ ActiveNameSpace->EfiDevicePath,
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ // Delete from the list
+// RemoveEntryList(&(ActiveNameSpace->Link));
+
+ // Free up all the memory
+ NvmeController->PciIO->Unmap(NvmeController->PciIO,
+ ActiveNameSpace->PRP2ListUnMap
+ );
+
+ if (ActiveNameSpace->PRP2List) {
+ NvmeController->PciIO->FreeBuffer (NvmeController->PciIO,
+ EFI_SIZE_TO_PAGES(NvmeController->MemoryPageSize),\
+ ActiveNameSpace->PRP2List
+ );
+ }
+
+ pBS->FreePool (ActiveNameSpace->NvmeBlockIO.Media);
+ pBS->FreePool (ActiveNameSpace->EfiDevicePath);
+
+ if (ActiveNameSpace->UDeviceName) {
+ pBS->FreePool (ActiveNameSpace->UDeviceName->Language);
+ pBS->FreePool (ActiveNameSpace->UDeviceName->UnicodeString);
+ pBS->FreePool (ActiveNameSpace->UDeviceName);
+ }
+
+ ForwardLink = LinkData->ForwardLink;
+ RemoveEntryList (LinkData);
+ LinkData = ForwardLink;
+ pBS->FreePool (ActiveNameSpace);
+ }
+ }
+
+ }
+
+ break;
+ }
+
+ (EFI_DEVICE_PATH_PROTOCOL *)NvmeDevicePath = NEXT_NODE ((EFI_DEVICE_PATH_PROTOCOL *)NvmeDevicePath);
+ }
+ Index++;
+ NumberOfChildren --;
+ }
+ } else {
+ // Check if all Active namespace has been stopped
+ if(!IsListEmpty(&NvmeController->ActiveNameSpaceList)) {
+ return EFI_DEVICE_ERROR;
+ }
+ // No child is active.
+ // Stop the controller. This will delete all the Queues.
+ CONTROLLER_REG32_AND(NvmeController->NvmeBarOffset, Offset_CC, 0xFFFFFFFE);
+
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gAmiNvmeControllerProtocolGuid,
+ NvmeController,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ Status = pBS->OpenProtocol( Controller,
+ &gAmiNvmePassThruProtocolGuid,
+ (VOID **)&AmiNvmePassThru,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ Controller,
+ &gAmiNvmePassThruProtocolGuid,
+ AmiNvmePassThru,
+ NULL
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ }
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiNvmExpressPassThruProtocolGuid,
+ (VOID **)&NvmExpressPassthruProtocol,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (!EFI_ERROR(Status)) {
+
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ Controller,
+ &gEfiNvmExpressPassThruProtocolGuid,
+ NvmExpressPassthruProtocol,
+ NULL
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ NvmePassthruInstance = _CR( NvmExpressPassthruProtocol ,NVM_EXPRESS_PASS_THRU_INSTANCE, EfiNvmExpressPassThru);
+ pBS->FreePool (NvmePassthruInstance->EfiNvmExpressPassThru.Mode);
+ pBS->FreePool (NvmePassthruInstance);
+ }
+
+ // Uninstall and close the protocols
+ Status = pBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ ASSERT_EFI_ERROR(Status);
+
+ // Free up all the memory allocated
+ if (NvmeController->IdentifyControllerData) {
+ pBS->FreePool (NvmeController->IdentifyControllerData);
+ }
+
+ if (NvmeController->IdentifyControllerData) {
+ pBS->FreePages ((EFI_PHYSICAL_ADDRESS)NvmeController->ActiveNameSpaceIDs,
+ EFI_SIZE_TO_PAGES(4096)
+ );
+ }
+
+ if (NvmeController->AdminSubmissionQueueUnMap) {
+ NvmeController->PciIO->Unmap (NvmeController->PciIO,
+ NvmeController->AdminSubmissionQueueUnMap
+ );
+ }
+ if (NvmeController->AdminSubmissionUnAligned) {
+ NvmeController->PciIO->FreeBuffer (NvmeController->PciIO, \
+ EFI_SIZE_TO_PAGES(NvmeController->AdminSubmissionUnAlignedSize), \
+ (VOID *)NvmeController->AdminSubmissionUnAligned
+ );
+ }
+
+ if (NvmeController->AdminCompletionQueueUnMap) {
+ NvmeController->PciIO->Unmap (NvmeController->PciIO,
+ NvmeController->AdminCompletionQueueUnMap
+ );
+ }
+ if (NvmeController->AdminCompletionUnAligned) {
+ NvmeController->PciIO->FreeBuffer (NvmeController->PciIO, \
+ EFI_SIZE_TO_PAGES(NvmeController->AdminCompletionUnAlignedSize), \
+ (VOID *)NvmeController->AdminCompletionUnAligned
+ );
+ }
+
+ if (NvmeController->Queue1SubmissionQueueUnMap) {
+ NvmeController->PciIO->Unmap (NvmeController->PciIO,
+ NvmeController->Queue1SubmissionQueueUnMap
+ );
+ }
+ if (NvmeController->Queue1SubmissionUnAligned) {
+ NvmeController->PciIO->FreeBuffer (NvmeController->PciIO, \
+ EFI_SIZE_TO_PAGES(NvmeController->Queue1SubmissionUnAlignedSize), \
+ (VOID *)NvmeController->Queue1SubmissionUnAligned
+ );
+ }
+
+ if (NvmeController->Queue1CompletionQueueUnMap) {
+ NvmeController->PciIO->Unmap (NvmeController->PciIO,
+ NvmeController->Queue1CompletionQueueUnMap
+ );
+ }
+ if (NvmeController->Queue1CompletionUnAligned) {
+ NvmeController->PciIO->FreeBuffer (NvmeController->PciIO, \
+ EFI_SIZE_TO_PAGES(NvmeController->Queue1CompletionUnAlignedSize), \
+ (VOID *)NvmeController->Queue1CompletionUnAligned
+ );
+ }
+
+ if (NvmeController->NvmeCmdWrapper) {
+ pBS->FreePool (NvmeController->NvmeCmdWrapper);
+ }
+
+ if (NvmeController) {
+ pBS->FreePool (NvmeController);
+ }
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitializeNvmeController
+//
+// Description: Initialize Nvme controller and ADMIN submission and Completion queues
+//
+// Input:
+// IN EFI_HANDLE Controller,
+// IN EFI_HANDLE DriverBindingHandle,
+// OUT AMI_NVME_CONTROLLER_PROTOCOL **NvmeControllerReturnAddress
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InitializeNvmeController(
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE DriverBindingHandle,
+ OUT AMI_NVME_CONTROLLER_PROTOCOL **NvmeControllerReturnAddress
+)
+{
+
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ PCI_TYPE00 PciConfig;
+ UINT64 ControllerCapabilities;
+ UINT32 Delay;
+ UINT32 ProgramCC = 0;
+ EFI_PHYSICAL_ADDRESS AdminQueueAddress = 0;
+ UINTN AllocatePageSize;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController = NULL;
+ UINT64 PciAttributes;
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof(AMI_NVME_CONTROLLER_PROTOCOL),
+ (VOID**)&NvmeController
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ *NvmeControllerReturnAddress = NvmeController;
+
+ // Clear memory
+ pBS->SetMem(NvmeController, sizeof(AMI_NVME_CONTROLLER_PROTOCOL), 0);
+
+ InitializeListHead (&NvmeController->ActiveNameSpaceList);
+
+ // Get the PciIO interface
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIO,
+ DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Enable PCI Cmd register
+ Status = PciIO->Attributes(PciIO, EfiPciIoAttributeOperationSupported, 0, &PciAttributes);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = PciIO->Attributes(PciIO, EfiPciIoAttributeOperationEnable, PciAttributes & EFI_PCI_DEVICE_ENABLE, NULL);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = PciIO->Pci.Read ( PciIO,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof (PCI_TYPE00),
+ &PciConfig
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ NvmeController->NvmeBarOffset = Shl64(PciConfig.Device.Bar[1], 32) + (PciConfig.Device.Bar[0] & ~(0x07));
+ NvmeController->PciIO = PciIO;
+ NvmeController->ControllerHandle = Controller;
+
+ ControllerCapabilities = Shl64(CONTROLLER_REG32(NvmeController->NvmeBarOffset, 4), 32) +
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, 0);
+
+ // Initialize various capability values
+
+ NvmeController->RawControllerCapabilities = ControllerCapabilities;
+ NvmeController->MaxQueueEntrySupported = (ControllerCapabilities & 0xFFFF) + 1;
+ NvmeController->ContiguousQueueRequired = (BOOLEAN)(Shr64((ControllerCapabilities & 0x10000), 16));
+ NvmeController->ArbitrationMechanismSupport = (BOOLEAN)(Shr64((ControllerCapabilities & 0x60000), 17));
+ NvmeController->TimeOut = (UINT8)(Shr64((ControllerCapabilities & 0xFF000000), 24)); // 500msec units
+ NvmeController->DoorBellStride = (UINT8)(UINTN) (Shr64((ControllerCapabilities & 0xF00000000), 32));
+ NvmeController->NVMResetSupport = (BOOLEAN) (Shr64((ControllerCapabilities & 0x1000000000), 36));
+ NvmeController->CmdSetsSupported = (UINT8)(UINTN) (Shr64((ControllerCapabilities & 0x1FE000000000), 37));
+ NvmeController->MemoryPageSizeMin = (UINT32)(UINTN) Shl64(1, (UINT8)(UINTN)(Shr64((ControllerCapabilities & 0xF000000000000), 48) + 12)); // In Bytes
+ NvmeController->MemoryPageSizeMax = (UINT32)(UINTN) Shl64(1, (UINT8)(UINTN)(Shr64((ControllerCapabilities & 0xF0000000000000), 52) + 12)); // In Bytes
+
+ PrintNvmeCapability(NvmeController);
+
+ // Is NVM command set supported
+ if (!(NvmeController->CmdSetsSupported & 0x1)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Check if the controller is already running. If yes stop it.
+ Delay = NvmeController->TimeOut * 500;
+
+ // Check if the controller is still in shutdown process occuring state
+ do {
+
+ if ((CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CSTS) & 0xC) != 4) {
+ break;
+ }
+ pBS->Stall(1000); // 1msec delay
+
+ }while (--Delay);
+
+ if (!Delay) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Delay = NvmeController->TimeOut * 500;
+ if (CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CC) & 0x1) {
+
+ // Disable Enable bit
+ CONTROLLER_REG32_AND (NvmeController->NvmeBarOffset, Offset_CC, ~0x01);
+ do {
+ if (!(CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CSTS) & 0x1)) {
+ break;
+ }
+ pBS->Stall(1000); // 1msec delay
+ }while (--Delay);
+ }
+
+ if (!Delay) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Initialize Controller configuration register.
+ // Select Round Robin and NVM Command Set (both values are zero)
+ // Max Page Size
+ NvmeController->MemoryPageSize = NvmeController->MemoryPageSizeMin;
+ ProgramCC |= (UINT32) Shl64((UINTN)Shr64(NvmeController->MemoryPageSize, 13), 7);
+
+
+ // Initialize with default value. Later it can be modified
+ ProgramCC |= Shl64(6, 16); // I/O Submission Queue Entry Size
+ ProgramCC |= Shl64(4, 20); // I/O Completion Queue Entry Size
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CC) = ProgramCC;
+
+ // Allocate memory for Admin Queue. Each entry is 64bytes long and queue should be aligned on MemoryPageSize
+ AllocatePageSize = NvmeController->MemoryPageSize +
+ ADMIN_QUEUE_SIZE * sizeof (NVME_ADMIN_COMMAND);
+
+#if Nvme_VERBOSE_PRINT
+ TRACE((-1, "Value programmed in Control register : %08X\n", ProgramCC));
+#endif
+
+ Status = NvmeController->PciIO->AllocateBuffer (NvmeController->PciIO,
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize),
+ (VOID **)&(AdminQueueAddress),
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NvmeController->AdminSubmissionUnAligned = AdminQueueAddress;
+ NvmeController->AdminSubmissionUnAlignedSize = EFI_SIZE_TO_PAGES(AllocatePageSize);
+ NvmeController->AdminSubmissionQueue = (AdminQueueAddress & ~(NvmeController->MemoryPageSize - 1)) +
+ NvmeController->MemoryPageSize;
+
+ Status = NvmeController->PciIO->Map ( NvmeController->PciIO,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID *)NvmeController->AdminSubmissionQueue,
+ &AllocatePageSize,
+ &NvmeController->AdminSubmissionQueueMappedAddr,
+ &NvmeController->AdminSubmissionQueueUnMap
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = NvmeController->PciIO->AllocateBuffer (NvmeController->PciIO,
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize),
+ (VOID **)&(AdminQueueAddress),
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NvmeController->AdminCompletionUnAligned = AdminQueueAddress;
+ NvmeController->AdminCompletionUnAlignedSize = EFI_SIZE_TO_PAGES(AllocatePageSize);
+ NvmeController->AdminCompletionQueue = (AdminQueueAddress & ~(NvmeController->MemoryPageSize - 1)) +
+ NvmeController->MemoryPageSize;
+
+ Status = NvmeController->PciIO->Map ( NvmeController->PciIO,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID *)NvmeController->AdminCompletionQueue,
+ &AllocatePageSize,
+ &NvmeController->AdminCompletionQueueMappedAddr,
+ &NvmeController->AdminCompletionQueueUnMap
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NvmeController->AdminSubmissionQueueSize = ADMIN_QUEUE_SIZE;
+ NvmeController->AdminCompletionQueueSize = ADMIN_QUEUE_SIZE;
+
+ // Clear memory
+ pBS->SetMem((VOID *)NvmeController->AdminSubmissionQueue, NvmeController->AdminSubmissionQueueSize, 0);
+ pBS->SetMem((VOID *)NvmeController->AdminCompletionQueue, NvmeController->AdminCompletionQueueSize, 0);
+
+ // Program Admin Queue Size and Base Address
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Aqa) =
+ (UINT32)(Shl64((NvmeController->AdminCompletionQueueSize - 1),16) +
+ (NvmeController->AdminSubmissionQueueSize - 1));
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Asq) =
+ (UINT32) NvmeController->AdminSubmissionQueueMappedAddr;
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Asq + 4) =
+ (UINT32)Shr64(NvmeController->AdminSubmissionQueueMappedAddr, 32);
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Acq) =
+ (UINT32)NvmeController->AdminCompletionQueueMappedAddr;
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Acq + 4) =
+ (UINT32)Shr64(NvmeController->AdminCompletionQueueMappedAddr, 32);
+
+#if NVME_VERBOSE_PRINT
+ TRACE ((-1, "Admin Submission Queue Size : %08X\n", NvmeController->AdminSubmissionQueueSize));
+ TRACE ((-1, "Admin Completion Queue Size : %08X\n", NvmeController->AdminCompletionQueueSize));
+ TRACE ((-1, "Admin Submission Queue Offset : %08X\n", NvmeController->AdminSubmissionQueue));
+ TRACE ((-1, "Admin Completion Queue Offset : %08X\n", NvmeController->AdminCompletionQueue));
+#endif
+
+ NvmeController->AdminPhaseTag = FALSE;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(NVME_COMMAND_WRAPPER),
+ (VOID**)&(NvmeController->NvmeCmdWrapper)
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Enable Controller
+ CONTROLLER_REG32_OR(NvmeController->NvmeBarOffset, Offset_CC, 0x1);
+
+ // Wait for the controller to get ready
+ // Check if the cobtroller is already running. If yes stop it.
+ Delay = NvmeController->TimeOut * 500;
+ do {
+ if ((CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CSTS) & 0x1)) {
+ break;
+ }
+ pBS->Stall(1000); // 1msec delay
+ } while (--Delay);
+
+ if (!Delay) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = SetNumberOfQueues (NvmeController);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Install NvmeController
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Controller,
+ &gAmiNvmeControllerProtocolGuid,
+ NvmeController,
+ NULL
+ );
+
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetIdentifyData
+//
+// Description: Issue Nvme Admin Identify cmd
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// OUT UINT8 *IdentifyData,
+// IN UINT8 ControllerNameSpaceStructure,
+// IN UINT32 NameSpaceID
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// ControllerNameSpaceStructure can take 0/1/2 : See Figure 81 NVM Express 1.1 Spec
+// NameSpaceID can be 0 or specific NameSpace ID. See Figure 38 NVM Express 1.1 Spec
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+GetIdentifyData (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ OUT UINT8 *IdentifyData,
+ IN UINT8 ControllerNameSpaceStructure,
+ IN UINT32 NameSpaceID
+)
+{
+
+ EFI_STATUS Status;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper = NULL;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(NVME_COMMAND_WRAPPER),
+ (VOID**)&(NvmeCmdWrapper)
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Clear memory
+ pBS->SetMem(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = IDENTIFY;
+ NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.PSDT = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierAdmin;
+ NvmeCmdWrapper->NvmCmd.NSID = NameSpaceID;
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)IdentifyData;
+
+ // If PRP1 isn't aligned on MemoryPageSize, then PRP2 will also be used.
+ NvmeCmdWrapper->NvmCmd.PRP2 = ((UINT64)IdentifyData & ~((UINT64)NvmeController->MemoryPageSize-1)) +
+ NvmeController->MemoryPageSize;
+
+ NvmeCmdWrapper->NvmCmd.CDW10 = ControllerNameSpaceStructure;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
+ NvmeCmdWrapper->SQIdentifier = 0; // Queue 0 for Admin cmds
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+
+ if (!EFI_ERROR(Status)) {
+ PrintIdentifyDataStructure (IdentifyData, ControllerNameSpaceStructure);
+ }
+
+ pBS->FreePool(NvmeCmdWrapper);
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SetNumberOfQueues
+//
+// Description: Issue Set feature cmd to set the # if queues to 1
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+SetNumberOfQueues (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+ EFI_STATUS Status;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper = NvmeController->NvmeCmdWrapper;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+
+ // Issue Set Feature cmd to initilaize # of queues to 1
+ pBS->SetMem(NvmeController->NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = SET_FEATURES;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierAdmin;
+
+ NvmeCmdWrapper->NvmCmd.CDW10 = 0x7;
+ NvmeCmdWrapper->NvmCmd.CDW11 = 0x10001;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
+ NvmeCmdWrapper->SQIdentifier = 0; // Queue 0 for Admin cmds
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EnumerateActiveNameSpace
+//
+// Description: Detects active Namespavce and adds it into a linked list
+//
+// Input:
+// IN OUT AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EnumerateActiveNameSpace (
+ IN OUT AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+ EFI_STATUS Status;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData = 0;
+ UINT32 i;
+ UINT32 Index;
+ UINT16 DeviceName[41];
+ CHAR8 Language[] = LANGUAGE_CODE_ENGLISH;
+ EFI_UNICODE_STRING_TABLE *tempUnicodeTable;
+
+ NvmeController->ActiveNameSpaceList.ForwardLink = &(NvmeController->ActiveNameSpaceList);
+ NvmeController->ActiveNameSpaceList.BackLink = &(NvmeController->ActiveNameSpaceList);
+
+ // Get Identify NameSpace Data for each Namespace
+ for (i = 1; (i < 1024) && NvmeController->ActiveNameSpaceIDs[i]; i++){
+
+ // Get the list of Active Namespace IDs
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (ACTIVE_NAMESPACE_DATA),
+ (VOID**)&ActiveNameSpaceData
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->SetMem(ActiveNameSpaceData, sizeof(ACTIVE_NAMESPACE_DATA), 0);
+
+ ActiveNameSpaceData->Link.ForwardLink = &(ActiveNameSpaceData->Link);
+ ActiveNameSpaceData->Link.BackLink = &(ActiveNameSpaceData->Link);
+
+ ActiveNameSpaceData->Signature = ACTIVE_NAME_SPACE_SIG;
+ ActiveNameSpaceData->NvmeController = NvmeController;
+ ActiveNameSpaceData->ActiveNameSpaceID = NvmeController->ActiveNameSpaceIDs[i];
+
+ Status = DetectActiveNameSpace (NvmeController, ActiveNameSpaceData);
+
+ if (!EFI_ERROR(Status)) {
+
+ TRACE((-1,"NameSpace %02X detected %lx\n", ActiveNameSpaceData->ActiveNameSpaceID, ActiveNameSpaceData));
+ InsertTailList (&NvmeController->ActiveNameSpaceList, &ActiveNameSpaceData->Link);
+
+ } else {
+
+ pBS->FreePool(ActiveNameSpaceData);
+ // First instance of zero marks the end of valid namespace IDs
+ if (!NvmeController->ActiveNameSpaceIDs[i+1]) {
+ break;
+ }
+ continue;
+ }
+
+ //
+ // Convert the Device string from Engligh to Unicode
+ //
+ ActiveNameSpaceData->UDeviceName = NULL;
+
+ pBS->SetMem(DeviceName, sizeof(DeviceName), 0);
+
+ for (Index = 0; Index < 40; Index ++) {
+ DeviceName[Index] = ((UINT8 *)NvmeController->IdentifyControllerData->ModelNumber)[Index];
+ }
+ DeviceName[40] = 0; // Word
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (EFI_UNICODE_STRING_TABLE) * 2,
+ (VOID**)&tempUnicodeTable
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->SetMem(tempUnicodeTable, sizeof(EFI_UNICODE_STRING_TABLE) * 2, 0);
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (Language),
+ (VOID**)&tempUnicodeTable[0].Language
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ sizeof (DeviceName),
+ (VOID**)&tempUnicodeTable[0].UnicodeString
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->CopyMem(tempUnicodeTable[0].Language, &Language, sizeof(Language));
+ pBS->CopyMem(tempUnicodeTable[0].UnicodeString, DeviceName, sizeof (DeviceName));
+ tempUnicodeTable[1].Language = NULL;
+ tempUnicodeTable[1].UnicodeString = NULL;
+ ActiveNameSpaceData->UDeviceName = tempUnicodeTable;
+
+ // First instance of zero marks the end of valid namespace IDs
+ if (!NvmeController->ActiveNameSpaceIDs[i+1]) {
+ break;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InstallBlockIoDiskInfo
+//
+// Description: Install BlockIo and DevicePath protocol for Active namespace
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InstallBlockIoDiskInfo (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace;
+ EFI_LIST_ENTRY *LinkData;
+ EFI_BLOCK_IO_MEDIA *BlkMedia;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ UINT32 BlockSize;
+ UINTN AllocatePageSize;
+ UINT8 *Buffer;
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink;
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ ActiveNameSpace = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (EFI_BLOCK_IO_MEDIA),
+ (VOID**)&BlkMedia
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SetMem(BlkMedia, sizeof(EFI_BLOCK_IO_MEDIA), 0);
+
+ // PRP2List will be cleared when used
+ AllocatePageSize = NvmeController->MemoryPageSize;
+ Status = NvmeController->PciIO->AllocateBuffer (NvmeController->PciIO,
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize),
+ (VOID**)&ActiveNameSpace->PRP2List,
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = NvmeController->PciIO->Map ( NvmeController->PciIO,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID *)ActiveNameSpace->PRP2List,
+ &AllocatePageSize,
+ &ActiveNameSpace->PRP2ListMappedAddr,
+ &ActiveNameSpace->PRP2ListUnMap
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+
+ BlkMedia->MediaId = 0;
+ BlkMedia->RemovableMedia = FALSE;
+ BlkMedia->MediaPresent = TRUE;
+ BlkMedia->LogicalPartition = FALSE;
+ BlkMedia->ReadOnly = FALSE;
+ BlkMedia->WriteCaching = FALSE;
+ BlockSize = ActiveNameSpace->IdentifyNamespaceData.LBAF[ActiveNameSpace->IdentifyNamespaceData.FLBAS & 0xF].LBADS;
+ BlkMedia->BlockSize = (UINT32) Shl64(1, BlockSize);
+ BlkMedia->IoAlign = 2; // NvmeController->MemoryPageSize;
+ BlkMedia->LastBlock = (EFI_LBA) (ActiveNameSpace->IdentifyNamespaceData.NSIZE - 1); // Name space Size
+ BlkMedia->LowestAlignedLba = 0;
+ BlkMedia->LogicalBlocksPerPhysicalBlock = 1;
+ BlkMedia->OptimalTransferLengthGranularity = BlkMedia->BlockSize;
+
+ ActiveNameSpace->NvmeBlockIO.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ ActiveNameSpace->NvmeBlockIO.Media = BlkMedia;
+ ActiveNameSpace->NvmeBlockIO.Reset = NvmeReset;
+ ActiveNameSpace->NvmeBlockIO.ReadBlocks = NvmeReadBlocks;
+ ActiveNameSpace->NvmeBlockIO.WriteBlocks = NvmeWriteBlocks;
+ ActiveNameSpace->NvmeBlockIO.FlushBlocks = NvmeFlushBlocks;
+
+ // DiskInfo Protocol
+ pBS->CopyMem (&(ActiveNameSpace->NvmeDiskInfo.Interface), &gEfiDiskInfoNvmeInterfaceGuid, sizeof (EFI_GUID));
+
+ ActiveNameSpace->NvmeDiskInfo.Inquiry = NvmeDiskInfoInquiry;
+ ActiveNameSpace->NvmeDiskInfo.Identify = NvmeDiskInfoIdentify;
+ ActiveNameSpace->NvmeDiskInfo.SenseData = NvmeDiskInfoSenseData;
+ ActiveNameSpace->NvmeDiskInfo.WhichIde = NvmeDiskInfoWhichIde;
+
+ // Create DevicePath Protocol
+ Status = CreateNvmeDevicePath (This, ActiveNameSpace);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ // Install Devicepath and Block IO protocol
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &(ActiveNameSpace->NvmeDeviceHandle),
+ &gEfiDevicePathProtocolGuid, ActiveNameSpace->EfiDevicePath,
+ &gEfiBlockIoProtocolGuid, &(ActiveNameSpace->NvmeBlockIO),
+ &gEfiDiskInfoProtocolGuid, &(ActiveNameSpace->NvmeDiskInfo),
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ // Open PCI IO protocol by CHILD
+ Status = pBS->OpenProtocol (
+ NvmeController->ControllerHandle,
+ &gEfiPciIoProtocolGuid,
+ (VOID **)&PciIO,
+ This->DriverBindingHandle,
+ ActiveNameSpace->NvmeDeviceHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+
+ ASSERT_EFI_ERROR(Status);
+
+ ActiveNameSpace->Configured = TRUE;
+
+ // Check if the drive ready to return data
+
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ EFI_SIZE_TO_PAGES(ActiveNameSpace->NvmeBlockIO.Media->BlockSize),
+ (EFI_PHYSICAL_ADDRESS*)&(Buffer));
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+
+ Status = ReadBlock (NvmeController, ActiveNameSpace, Buffer);
+ if (!EFI_ERROR(Status)) {
+ // No error check for Int13 installation
+ InstallNvmeLegacyDevice(NvmeController, ActiveNameSpace, Buffer);
+ }
+
+ pBS->FreePages((EFI_PHYSICAL_ADDRESS)Buffer, EFI_SIZE_TO_PAGES(ActiveNameSpace->NvmeBlockIO.Media->BlockSize));
+ }
+
+#if NvmeSmm_SUPPORT
+ if( gLegacyNvmeBuffer == NULL ) {
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(ActiveNameSpace->NvmeBlockIO.Media->BlockSize),
+ (EFI_PHYSICAL_ADDRESS*)&(gLegacyNvmeBuffer ));
+ if (EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+ }
+ NvmeController->LegacyNvmeBuffer=gLegacyNvmeBuffer;
+
+ // Move the Controller and ActiveName Space data into SMM also.
+ // This will done for each controller in the system
+ TransferNvmeDataToSmram(NvmeController);
+#endif
+
+ return Status;
+}
+
+#if NvmeSmm_SUPPORT
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TransferNvmeDataToSmram
+//
+// Description: Transfer the Nvme Controller information to SMRAM area that would be used
+// by the Nvme SMM driver
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+TransferNvmeDataToSmram (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+ EFI_STATUS SmmStatus;
+ UINTN NvmeControllerAddress = 0;
+ static EFI_GUID gNvmeSmmGuid = NVME_SMM_GUID;
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommunication;
+ EFI_SMM_COMMUNICATE_HEADER *CommHeader;
+ UINT8 CommBuffer[sizeof(EFI_GUID) + sizeof(UINTN) + sizeof(NvmeController)];
+ UINTN CommSize = 0;
+
+ // Get needed resource
+ SmmStatus = pBS->LocateProtocol (
+ &gEfiSmmCommunicationProtocolGuid,
+ NULL,
+ (VOID **)&SmmCommunication
+ );
+
+ ASSERT_EFI_ERROR (SmmStatus);
+
+ if (EFI_ERROR (SmmStatus)) {
+ return;
+ }
+
+ CommHeader = (EFI_SMM_COMMUNICATE_HEADER *)&CommBuffer[0];
+ pBS->CopyMem (&CommHeader->HeaderGuid, &gAmiSmmNvmeCommunicationGuid, sizeof(gAmiSmmNvmeCommunicationGuid));
+ CommHeader->MessageLength = sizeof(NvmeController);
+ pBS->CopyMem (&(CommHeader->Data[0]), &NvmeController, sizeof(NvmeController));
+
+ // Send command
+ CommSize = sizeof(CommBuffer);
+ SmmStatus = SmmCommunication->Communicate (
+ SmmCommunication,
+ &CommBuffer[0],
+ &CommSize
+ );
+#else
+
+ NvmeControllerAddress = (UINT64)(NvmeController);
+
+ // Save ComBuffer in NvmeSmmBuffer to use in SMM
+ SmmStatus = pRS->SetVariable ( L"NvmeSmmBuffer",
+ &gNvmeSmmGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINTN),
+ &NvmeControllerAddress);
+
+ TRACE((-1, "CommHeader Data inNvmeBus = %x\n", NvmeControllerAddress));
+
+ IoWrite8 (SW_SMI_IO_ADDRESS, NVME_INIT_SMM_SWSMI);
+#endif
+
+ return;
+
+}
+#endif
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CreateNVMeDevicePath
+//
+// Description: Allocate memory and create a NVMe devicepath
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This,
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CreateNvmeDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace
+ )
+{
+
+ EFI_STATUS Status;
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController = ActiveNameSpace->NvmeController;
+ NVME_DEVICE_PATH NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+
+ NewDevicePath.Header.Type = MESSAGING_DEVICE_PATH;
+ NewDevicePath.Header.SubType = MSG_NVME_DP;
+ SetDevicePathNodeLength(&(NewDevicePath.Header), sizeof(NVME_DEVICE_PATH));
+ NewDevicePath.Nsid = ActiveNameSpace->ActiveNameSpaceID;
+ NewDevicePath.EUI64 = ActiveNameSpace->IdentifyNamespaceData.EUI64;
+
+ //
+ // Append the Device Path
+ //
+ Status = pBS->OpenProtocol (
+ NvmeController->ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **)&TempDevicePath,
+ This->DriverBindingHandle,
+ NvmeController->ControllerHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ ActiveNameSpace->EfiDevicePath = DPAddNode(TempDevicePath, &NewDevicePath.Header);
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DetectActiveNameSpace
+//
+// Description: Issue GetIdentifyData cmd to get the list of active name space.
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+DetectActiveNameSpace (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData
+)
+{
+
+ EFI_STATUS Status;
+
+ // Get list of Active NameSpace Data
+ Status = GetIdentifyData (NvmeController,
+ (UINT8*)&(ActiveNameSpaceData->IdentifyNamespaceData),
+ 0,
+ ActiveNameSpaceData->ActiveNameSpaceID
+ );
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InstallNvmeLegacyDevice
+//
+// Description: Add the NVMe active partition as a legacy device
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData
+// IN UINT8 *Buffer
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+VOID
+InstallNvmeLegacyDevice (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN UINT8 *Buffer
+)
+{
+
+ EFI_STATUS Status;
+ AMI_NVME_LEGACY_PROTOCOL *AmiNvmeLegacyProtocol = NULL;
+ NVME_LEGACY_MASS_DEVICE *NvmeLegacyMassDevice;
+ NVME_MASS_DEV_INFO *NvmeMassDevInfo;
+ CHAR8 *NewString;
+ UINTN PciSeg, PciBus, PciDev, PciFunc;
+
+
+ //If block size is not 512 do install INT13
+ if (ActiveNameSpace->NvmeBlockIO.Media->BlockSize != 0x200) {
+ return;
+ }
+
+ Status = pBS->LocateProtocol(&gAmiNvmeLegacyProtocolGuid, NULL, (VOID**)&AmiNvmeLegacyProtocol);
+ // Legacy Support disabled.
+ if(EFI_ERROR(Status) || AmiNvmeLegacyProtocol == NULL ) {
+ return;
+ }
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (NVME_LEGACY_MASS_DEVICE),
+ (VOID**)&NvmeLegacyMassDevice
+ );
+
+ if (EFI_ERROR(Status)){
+ return;
+ }
+
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof (NVME_MASS_DEV_INFO),
+ (VOID**)&NvmeMassDevInfo
+ );
+
+ if (EFI_ERROR(Status)){
+ pBS->FreePool (NvmeLegacyMassDevice);
+ return;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ 256,
+ (VOID *) &NewString);
+ ASSERT_EFI_ERROR (Status);
+
+ // Read the first sector of the device
+ ActiveNameSpace->dMaxLBA = ActiveNameSpace->NvmeBlockIO.Media->LastBlock;
+ GetNvmeGeometryData(ActiveNameSpace, NvmeMassDevInfo, Buffer);
+
+ NvmeMassDevInfo->wBlockSize=ActiveNameSpace->NvmeBlockIO.Media->BlockSize;
+ NvmeMassDevInfo->dMaxLba=ActiveNameSpace->dMaxLBA;
+ NvmeMassDevInfo->bHeads=ActiveNameSpace->NumHeads;
+ NvmeMassDevInfo->bSectors=ActiveNameSpace->NumSectors;
+ NvmeMassDevInfo->wCylinders=ActiveNameSpace->NumCylinders;
+ NvmeMassDevInfo->bNonLBAHeads=ActiveNameSpace->LBANumHeads;
+ NvmeMassDevInfo->bNonLBASectors=ActiveNameSpace->LBANumSectors;
+ NvmeMassDevInfo->wNonLBACylinders=ActiveNameSpace->LBANumCyls;
+
+ PrintNvmeMassDevInfo (NvmeMassDevInfo);
+
+ // Get the NVMe controller Bus,Dev and Fun
+ NvmeController->PciIO->GetLocation (NvmeController->PciIO, &PciSeg, &PciBus, &PciDev, &PciFunc);
+ UnicodeStrToAsciiStr (ActiveNameSpace->UDeviceName->UnicodeString, NewString);
+
+ NvmeLegacyMassDevice->PciBDF=(UINT16)((PciBus << 8)+(PciDev << 3) + PciFunc);
+ NvmeLegacyMassDevice->DevString=NewString;
+ NvmeLegacyMassDevice->DevInfo=(VOID*)NvmeMassDevInfo;
+ ActiveNameSpace->Int13DeviceAddress = gInt13DeviceAddress;
+ NvmeLegacyMassDevice->LogicalAddress=ActiveNameSpace->Int13DeviceAddress;
+ gInt13DeviceAddress++;
+ NvmeLegacyMassDevice->StorageType = NVME_MASS_DEV_HDD;
+ NvmeLegacyMassDevice->Handle=ActiveNameSpace->NvmeDeviceHandle;
+
+ AmiNvmeLegacyProtocol->AddNvmeLegacyDevice(NvmeLegacyMassDevice);
+
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetNvmeGeometryData
+//
+// Description: Get drive geometry data for INT13 support
+//
+// Input:
+// IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+// IN OUT NVME_MASS_DEV_INFO *NvmeMassDevInfo,
+// IN UINT8 *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+GetNvmeGeometryData (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN OUT NVME_MASS_DEV_INFO *NvmeMassDevInfo,
+ IN UINT8 *Buffer
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 *ActPartAddr;
+ UINT32 dHS;
+
+
+ ActiveNameSpace->bStorageType = NVME_MASS_DEV_HDD;
+ ActiveNameSpace->bEmuType = 0;
+
+ ActiveNameSpace->bHiddenSectors = 0;
+ //
+ // Check for validity of Boot Record
+ //
+ if ( *(UINT16*)(Buffer + 0x1FE) != 0xAA55 ) {
+ NvmeSetDefaultGeometry(ActiveNameSpace);
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Check for validity of the partition table
+ //
+ if ( NvmeValidatePartitionTable( Buffer, ActiveNameSpace->dMaxLBA, &ActPartAddr) == EFI_SUCCESS ) {
+
+ //
+ // Read boot sector, set the LBA number to boot record LBA number
+ //
+ dHS = *((UINT32*)(ActPartAddr + 8));
+ ActiveNameSpace->bHiddenSectors = (UINT8)dHS; // Save hidden sector value
+
+ Status = NvmeReadWriteBlocks (ActiveNameSpace, ActiveNameSpace->NvmeBlockIO.Media->MediaId, (EFI_LBA)dHS, 512, Buffer, NULL, NVME_READ);
+
+ if ( EFI_ERROR(Status) ) {
+ return EFI_NOT_FOUND;
+ }
+
+ if ( NvmeUpdateCHSFromBootRecord(ActiveNameSpace, Buffer) == EFI_SUCCESS) {
+ return EFI_SUCCESS;
+ } else {
+ NvmeSetDefaultGeometry(ActiveNameSpace);
+ ActiveNameSpace->bHiddenSectors = 0; // Reset hidden sector value
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeSetDefaultGeometry
+//
+// Description: This procedure sets the default geometry for mass storage devices
+//
+// Input:
+// IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeSetDefaultGeometry (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace
+)
+{
+ ActiveNameSpace->NumHeads = 0xFF;
+ ActiveNameSpace->LBANumHeads = 0xFF;
+ ActiveNameSpace->NumSectors = 0x3F;
+ ActiveNameSpace->LBANumSectors = 0x3F;
+
+ NvmeMassUpdateCylinderInfo(ActiveNameSpace);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassUpdateCylinderInfo
+//
+// Description: This procedure updates cylinder parameter for device geometry.
+// head and sector parameters are required before invoking this
+// function.
+//
+// Input:
+// IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassUpdateCylinderInfo (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace
+)
+{
+ UINT32 data = (UINT32)(Div64(ActiveNameSpace->dMaxLBA,(ActiveNameSpace->NumSectors * ActiveNameSpace->NumHeads), NULL));
+
+ if (data <= 1) data++;
+ if (data > 0x3FF) data = 0x3FF; // DOS workaround
+
+ ActiveNameSpace->NumCylinders = (UINT16)data;
+ ActiveNameSpace->LBANumCyls = (UINT16)data;
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeValidatePartitionTable
+//
+// Description: This procedure checks whether the partition table is valid.
+//
+// Input:
+// IN UINT8 *Buffer,
+// IN UINT64 dMaxLBA,
+// OUT UINT8 **ActPartAddr
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeValidatePartitionTable (
+ IN UINT8 *Buffer,
+ IN UINT64 dMaxLBA,
+ OUT UINT8 **ActPartAddr
+)
+{
+
+ UINT8 *PartPtr;
+ UINT8 PartNo = 0;
+ UINT8 *ActPart = NULL;
+ UINT8 ValidEntryCount = 0;
+
+ //
+ // Drive has a partition table, start from 1st bootable partition
+ //
+ PartPtr = Buffer + 0x1BE;
+
+ for (; PartNo<4; PartNo++, PartPtr+=0x10 ) {
+
+ if (*PartPtr & 0x7F ) {
+ return EFI_NOT_FOUND; //BootFlag should be 0x0 or 0x80
+ }
+ //
+ // Check whether beginning LBA is reasonable
+ //
+ if (*(UINT32*)(PartPtr + 8) > dMaxLBA) {
+ return EFI_NOT_FOUND;
+ }
+
+ ValidEntryCount++; // Update valid entry count
+ //
+ // Update active entry offset
+ //
+ if (!(*PartPtr & 0x80)) continue;
+ if (ActPart) continue;
+ ActPart = PartPtr;
+ }
+
+ if (ValidEntryCount < 1) return EFI_NOT_FOUND; // At least one valid partition is found
+ //
+ // If no active partition table entry found use first entry
+ //
+ if (ActPart == NULL) ActPart = Buffer + 0x1BE;
+
+ *ActPartAddr = ActPart;
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeUpdateCHSFromBootRecord
+//
+// Description: This function parses the boot record and extract the CHS
+// information of the formatted media from the boot record.
+// This routine checks for DOS & NTFS formats only
+//
+// Input:
+// IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+// IN UINT8* BootRecord
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: The amount of data that will get printed can be controlled
+// using DEBUG_ERROR_LEVEL_MASK SDL token. Make sure
+// PcdDebugPrintErrorLevel is properly cloned and set to
+// PcdsPatchableInModule in the project.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeUpdateCHSFromBootRecord (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN UINT8* BootRecord
+)
+{
+ UINT32 OemName;
+ UINT8 Heads;
+ UINT8 SecPerTrack;
+ UINT16 SecTimesHeads;
+ UINT16 TotalSect;
+
+ if (*((UINT16*)(BootRecord + 0x1FE)) != 0xAA55) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Read succeeded so the drive is formatted
+ // Check for valid MSDOS/MSWIN/NTFS boot record
+ //
+ OemName = *(UINT32*)(BootRecord + 3);
+
+ if ((OemName != 0x4F44534D) && // 'ODSM' for MSDO
+ (OemName != 0x4957534D) && // 'IWSM' for MSWI
+ (OemName != 0x5346544E)) { // 'SFTN' for NTFS
+ //
+ // Check for valid FAT,FAT16,FAT32 boot records
+ //
+ *(BootRecord + 0x36 + 3) = 0x20; // Ignore the 4th byte and fill it with space
+ if ((*(UINT32*)(BootRecord + 0x36) != 0x20544146) && // " TAF" for FATx
+ (*(UINT32*)(BootRecord + 0x52) != 0x33544146)) { // "3TAF" for FAT3
+ //
+ // Boot Record is invalid. Return with error
+ //
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ Heads = *(BootRecord + 0x1A); // Number of heads
+ SecPerTrack = *(BootRecord + 0x18); // Sectors/track
+ SecTimesHeads = Heads * SecPerTrack;
+
+ // Zero check added to prevent invalid sector/head information in BPB
+ if (SecTimesHeads == 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ TotalSect = *(UINT16*)(BootRecord + 0x13);
+ if ( TotalSect ) {
+ ActiveNameSpace->dMaxLBA = TotalSect;
+ }
+
+ ActiveNameSpace->NumHeads = Heads;
+ ActiveNameSpace->LBANumHeads = Heads;
+ ActiveNameSpace->NumSectors = SecPerTrack;
+ ActiveNameSpace->LBANumSectors = SecPerTrack;
+
+
+ NvmeMassUpdateCylinderInfo(ActiveNameSpace);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PrintIdentifyDataStructure
+//
+// Description: Prints Identify data structure
+//
+// Input:
+// UINT8 *IdentifyData,
+// UINT8 ControllerNameSpaceStructure
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+PrintIdentifyDataStructure (
+ IN UINT8 *IdentifyData,
+ IN UINT8 ControllerNameSpaceStructure
+)
+{
+
+
+#if NVME_VERBOSE_PRINT
+
+ IDENTIFY_CONTROLLER_DATA *IdentifyControllerData = (IDENTIFY_CONTROLLER_DATA *)IdentifyData;
+ IDENTIFY_NAMESPACE_DATA *IdentifyNameSpaceData = (IDENTIFY_NAMESPACE_DATA *)IdentifyData;
+ UINT32 *ActiveNameSapceID = (UINT32 *)IdentifyData;
+ UINT32 i;
+ UINT64 FirmwareVersion;
+
+ switch (ControllerNameSpaceStructure){
+
+ case 1:
+
+ FirmwareVersion = *(UINT64 *)(IdentifyControllerData->FirmwareRevision);
+ TRACE((-1,"\nIdentify Controller Data Structure\n"));
+ TRACE((-1, "Vendor ID : %08X\n", IdentifyControllerData->VID));
+ TRACE((-1, "SubSystem Vendor ID : %08X\n", IdentifyControllerData->SSVID));
+ TRACE((-1, "Firmware Version : %16lX\n", FirmwareVersion));
+ TRACE((-1, "NameSpace Sharing Capability : %08X\n", IdentifyControllerData->CMIC));
+ TRACE((-1, "Max. Data Transfer Size : %08X\n", IdentifyControllerData->MDTS));
+ TRACE((-1, "Controller ID : %08X\n", IdentifyControllerData->ControllerID));
+ TRACE((-1, "Optional Admin Cmd Support : %08X\n", IdentifyControllerData->OACS));
+ TRACE((-1, "Abort Command Limit : %08X\n", IdentifyControllerData->ACL));
+ TRACE((-1, "Asyn. Event Request Limit : %08X\n", IdentifyControllerData->AERL));
+ TRACE((-1, "Firmware Updates : %08X\n", IdentifyControllerData->FRMW));
+ TRACE((-1, "Log Page Attribute : %08X\n", IdentifyControllerData->LPA));
+ TRACE((-1, "# of Power state supported : %08X\n", IdentifyControllerData->NPSS));
+ TRACE((-1, "Admin Vendor Specific cmd : %08X\n", IdentifyControllerData->AVSCC));
+ TRACE((-1, "Autonomous Power state attrib : %08X\n", IdentifyControllerData->APSTA));
+ TRACE((-1, "Submission queue Entry Size : %08X\n", IdentifyControllerData->SQES));
+ TRACE((-1, "Completion queue Entry Size : %08X\n", IdentifyControllerData->CQES));
+ TRACE((-1, "Number of NameSpace : %08X\n", IdentifyControllerData->NN));
+ TRACE((-1, "Optional NVM Command Support : %08X\n", IdentifyControllerData->ONCS));
+ TRACE((-1, "Fused Operation Support : %08X\n", IdentifyControllerData->FUSES));
+ TRACE((-1, "Format NVM Attribute : %08X\n", IdentifyControllerData->FNA));
+ TRACE((-1, "Volatile Write Cache : %08X\n", IdentifyControllerData->VWC));
+ TRACE((-1, "Atomic Write Unit Normal : %08X\n", IdentifyControllerData->AWUN));
+ TRACE((-1, "Atomic Write Unit Power Fail : %08X\n", IdentifyControllerData->AWUPF));
+ TRACE((-1, "NVM VS CMD Config : %08X\n", IdentifyControllerData->NVSCC));
+ TRACE((-1, "Atomic Compare & Write Unit : %08X\n", IdentifyControllerData->ACWU));
+ TRACE((-1, "SGL Support : %08X\n", IdentifyControllerData->SGLS));
+ break;
+
+ case 0:
+ TRACE((-1, "\nIdentify NameSpace Data Structure\n"));
+ TRACE((-1, "NameSpace Size : %08X\n", IdentifyNameSpaceData->NSIZE));
+ TRACE((-1, "NameSpace Capacity : %08X\n", IdentifyNameSpaceData->NCAP));
+ TRACE((-1, "NameSpace Utilization : %08X\n", IdentifyNameSpaceData->NUSE));
+ TRACE((-1, "NameSpace Features : %08X\n", IdentifyNameSpaceData->NSFEAT));
+ TRACE((-1, "No. of LBA Formats (0 Based) : %08X\n", IdentifyNameSpaceData->NLBAF));
+ TRACE((-1, "Formatted LBA Size : %08X\n", IdentifyNameSpaceData->FLBAS));
+ TRACE((-1, "Metadata Capabilities : %08X\n", IdentifyNameSpaceData->MC));
+ TRACE((-1, "End-to-end data Protection cap : %08X\n", IdentifyNameSpaceData->DPC));
+ TRACE((-1, "End-to-end data Protection settings : %08X\n", IdentifyNameSpaceData->DPS));
+ TRACE((-1, "NameSpace Sharing : %08X\n", IdentifyNameSpaceData->NMIC));
+ TRACE((-1, "Reservation Capabilites : %08X\n", IdentifyNameSpaceData->RESCAP));
+ TRACE((-1, "IEEE Extended Unique Identifier : %016lx\n", IdentifyNameSpaceData->EUI64));
+ for (i=0; i<16; i++){
+ TRACE((-1, "LBA Format %02X Support : %08X\n", i, *(UINT32 *)&(IdentifyNameSpaceData->LBAF[i])));
+ }
+ break;
+
+ case 2:
+ TRACE((-1,"\nActive NameSpace IDs\n"));
+ for (i=0; i<1024 && ActiveNameSapceID[i]; i++){
+ TRACE((-1, " %08X\n", i, ActiveNameSapceID[i]));
+ }
+
+ }
+#endif
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PrintNvmeCapability
+//
+// Description: Prints Controller capabilities
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: The amount of data that will get printed can be controlled using DEBUG_ERROR_LEVEL_MASK SDL token.
+// Make sure PcdDebugPrintErrorLevel is properly cloned and set to PcdsPatchableInModule in the project.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+PrintNvmeCapability (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+#if NVME_VERBOSE_PRINT
+ TRACE ((-1, "Controller Capabilitites Reg Value : %16lx\n", NvmeController->RawControllerCapabilities));
+ TRACE ((-1, "Max. Queue Entrys Supported : %08X\n", NvmeController->MaxQueueEntrySupported));
+ TRACE ((-1, "Contiguous Queue Required : %08X\n", NvmeController->ContiguousQueueRequired));
+ TRACE ((-1, "Arbitration Mode Supported : %08X\n", NvmeController->ArbitrationMechanismSupport));
+ TRACE ((-1, "TimeOut in 500msec unit : %08X\n", NvmeController->TimeOut));
+ TRACE ((-1, "Doorbell Stride : %08X\n", NvmeController->DoorBellStride));
+ TRACE ((-1, "NVM Subsystem Reset Support : %08X\n", NvmeController->NVMResetSupport));
+ TRACE ((-1, "Command Sets Supported : %08X\n", NvmeController->CmdSetsSupported));
+ TRACE ((-1, "Memory Page Size Min.in Bytes : %08X\n", NvmeController->MemoryPageSizeMin));
+ TRACE ((-1, "Memory Page Size Max.in Bytes : %08X\n", NvmeController->MemoryPageSizeMax));
+#endif
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ReadBlock
+//
+// Description: Read the Data from device
+//
+// Input:
+// AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// ACTIVE_NAMESPACE_DATA *ActiveNameSpace
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ReadBlock (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ OUT UINT8 *Buffer
+
+)
+{
+
+ EFI_STATUS Status;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper = NvmeController->NvmeCmdWrapper;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+ UINT64 DataAddress = (UINTN)Buffer;
+ UINT32 LBANumber = 0;
+ UINT32 Retries = 0x800;
+
+ do {
+
+ // Clear memory
+ pBS->SetMem(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = NVME_READ;
+ NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.PSDT = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierQueue1;
+ NvmeCmdWrapper->NvmCmd.NSID = 1;
+
+ NvmeCmdWrapper->NvmCmd.MPTR = 0;
+ NvmeCmdWrapper->NvmCmd.PRP1 = DataAddress;
+ NvmeCmdWrapper->NvmCmd.PRP2 = 0;
+ NvmeCmdWrapper->NvmCmd.CDW10 = LBANumber; // LBA 0
+ NvmeCmdWrapper->NvmCmd.CDW11 = 0;
+ NvmeCmdWrapper->NvmCmd.CDW12 = 0x80000000;
+ NvmeCmdWrapper->NvmCmd.CDW13 = 0;
+ NvmeCmdWrapper->NvmCmd.CDW14 = 0;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = FALSE;
+ NvmeCmdWrapper->SQIdentifier = 1; // Cmd issued in Queue0
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+
+ } while (Retries-- && Status != EFI_SUCCESS);
+
+ return Status;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeReadBlocks
+//
+// Description: Reads data from the given LBA address
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = ACTIVE_NAMESPACE_DATA_FROM_THIS(This);
+
+ return NvmeReadWriteBlocks (ActiveNameSpace, MediaId, LBA, BufferSize, Buffer, NULL, NVME_READ);
+
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeWriteBlocks
+//
+// Description: Write data from the given LBA address
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+)
+{
+
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = ACTIVE_NAMESPACE_DATA_FROM_THIS(This);
+
+ return NvmeReadWriteBlocks (ActiveNameSpace, MediaId, LBA, BufferSize, Buffer, NULL, NVME_WRITE);
+
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeReset
+//
+// Description: Resets Nvme Controller
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This,
+// IN BOOLEAN ExtendedVerification
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ return Status;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeFlushBlocks
+//
+// Description: Flushes the data
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+)
+{
+
+ EFI_STATUS Status;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = ACTIVE_NAMESPACE_DATA_FROM_THIS(This);
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController = ActiveNameSpace->NvmeController;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper = NvmeController->NvmeCmdWrapper;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+
+ TRACE((-1,"NvmeFlushBlocks \n"));
+
+ pBS->SetMem(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = NVME_FLUSH;
+ NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.PSDT = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierQueue1;
+ NvmeCmdWrapper->NvmCmd.NSID = ActiveNameSpace->ActiveNameSpaceID;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = FALSE;
+ NvmeCmdWrapper->SQIdentifier = NvmeController->NVMQueueNumber;
+ NvmeCmdWrapper->CmdTimeOut = 1000; // 1secs
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+
+ TRACE((-1,"NvmeFlushBlocks Status %r \n", Status));
+
+ return Status;
+
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeDiskInfoInquiry
+//
+// Description: Return Nvme device Inquiry data
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This
+// IN VOID *InquiryData,
+// IN UINT32 *InquiryDataSize
+// Output:
+// EFI_STATUS /EFI_NOT_FOUND
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeDiskInfoInquiry (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *InquiryData,
+ IN OUT UINT32 *InquiryDataSize
+)
+{
+
+ return EFI_NOT_FOUND;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeDiskInfoIdentify
+//
+// Description: Return Identify Data
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This
+// IN VOID *IdentifyData,
+// IN UINT32 *IdentifyDataSize
+// Output:
+// EFI_STATUS
+// Note:
+// Return the Nvme device Identify command data.
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeDiskInfoIdentify (
+ EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *IdentifyData,
+ IN OUT UINT32 *IdentifyDataSize
+)
+{
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = ACTIVE_NAMESPACE_DATA_FROM_THIS_FOR_DISKINFO(This);
+
+ if (*IdentifyDataSize < sizeof (IDENTIFY_NAMESPACE_DATA)) {
+ *IdentifyDataSize = sizeof (IDENTIFY_NAMESPACE_DATA);
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ pBS->CopyMem (IdentifyData, &(ActiveNameSpace->IdentifyNamespaceData), sizeof (IDENTIFY_NAMESPACE_DATA));
+ *IdentifyDataSize = sizeof (IDENTIFY_NAMESPACE_DATA);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeDiskInfoSenseData
+//
+// Description: Return InfoSenseData.
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This
+// IN VOID *SenseData,
+// IN UINT32 *SenseDataSize
+// IN UINT8 *SenseDataNumber
+// Output:
+// EFI_STATUS / EFI_NOT_FOUND
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeDiskInfoSenseData (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT VOID *SenseData,
+ OUT UINT32 *SenseDataSize,
+ OUT UINT8 *SenseDataNumber
+)
+{
+ return EFI_NOT_FOUND;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeDiskInfoWhichIde
+//
+// Description: Returns info about where the device is connected.
+//
+// Input:
+// IN EFI_DISK_INFO_PROTOCOL *This
+// IN UINT32 *IdeChannel
+// IN UINT32 *IdeDevice
+// Output:
+// EFI_STATUS
+// Note:
+// Return Port and PMPort
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeDiskInfoWhichIde (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT UINT32 *IdeChannel,
+ OUT UINT32 *IdeDevice
+)
+{
+
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = ACTIVE_NAMESPACE_DATA_FROM_THIS_FOR_DISKINFO(This);
+
+ *IdeChannel = ActiveNameSpace->ActiveNameSpaceID;
+ *IdeDevice = 0;
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PrintNvmeMassDevInfo
+//
+// Description: Prints Nvme Mass Device Information
+//
+// Input:
+// NVME_MASS_DEV_INFO *NvmeMassDevInfo
+//
+// Output:
+// None
+//
+// Modified:
+//
+// Referrals:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+PrintNvmeMassDevInfo (
+ NVME_MASS_DEV_INFO *NvmeMassDevInfo
+)
+{
+
+#if NVME_VERBOSE_PRINT
+ TRACE((-1,"********** NvmeMassDevInfo **********\n"));
+ TRACE((-1, "wBlockSize : %08X\n", NvmeMassDevInfo->wBlockSize));
+ TRACE((-1, "dMaxLba : %lX\n", NvmeMassDevInfo->dMaxLba));
+ TRACE((-1, "bHeads : %08X\n", NvmeMassDevInfo->bHeads));
+ TRACE((-1, "bSectors : %08X\n", NvmeMassDevInfo->bSectors));
+ TRACE((-1, "wCylinders : %08X\n", NvmeMassDevInfo->wCylinders));
+ TRACE((-1, "bNonLBAHeads : %08X\n", NvmeMassDevInfo->bNonLBAHeads));
+ TRACE((-1, "bNonLBASectors : %08X\n", NvmeMassDevInfo->bNonLBASectors));
+ TRACE((-1, "wNonLBACylinders : %08X\n", NvmeMassDevInfo->wNonLBACylinders));
+#endif
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeBus.h b/Core/EM/Nvme/NvmeBus.h
new file mode 100644
index 0000000..9e4af09
--- /dev/null
+++ b/Core/EM/Nvme/NvmeBus.h
@@ -0,0 +1,539 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeBus.h 5 5/18/15 2:50a Karthikar $
+//
+// $Revision: 5 $
+//
+// $Date: 5/18/15 2:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeBus.h $
+//
+// 5 5/18/15 2:50a Karthikar
+// [TAG] EIP216763
+// [Category] Improvement
+// [Description] Update the Aptio 4.x Nvme driver to Aptio 5.x Nvme
+// driver Label 05
+// [Files] [Files] Nvme.mak,NvmeBus.c, NvmeBus.h, NvmeController.c,
+// NvmePassthru.c,NvmePassthru.h, NvmeSmm.c, NvmExpressPassThru.h.
+//
+// 4 5/14/15 2:38a Karthikar
+//
+// 3 9/23/14 2:29a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description]
+// Add Legacy Boot support in Aptio 4.x Nvme driver - NON PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+//
+//
+//
+//
+//
+//
+// 2 9/04/14 7:35a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files]
+// Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeBus.h
+//
+// Description: Header file for the Nvme Bus Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _NVME_BUS_H_
+#define _NVME_BUS_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "NvmeController.h"
+#include "NvmeIncludes.h"
+#include <Protocol/pDiskInfo.h>
+#include <Protocol/AmiNvmeController.h>
+#include <Protocol/AmiNvmePassThru.h>
+
+#define ADMIN_QUEUE_SIZE 0x100
+#define QUEUE1_SIZE 0x100
+
+#define EFI_SIGNATURE_16( A, B ) ( (A) | (B << 8) )
+#define EFI_SIGNATURE_32( A, B, C, D ) ( EFI_SIGNATURE_16( A, B ) | (EFI_SIGNATURE_16( C, D ) << 16))
+
+#define ACTIVE_NAME_SPACE_SIG EFI_SIGNATURE_32('N','V','M','E')
+
+#define PCI_CLASS_MASS_STORAGE 0x01
+#define PCI_CLASS_MASS_STORAGE_SOLID_STATE 0x08
+#define PCI_IF_MASS_STORAGE_SOLID_STATE 0x00
+#define PCI_IF_MASS_STORAGE_SOLID_STATE_NVMHCI 0x01
+#define PCI_IF_MASS_STORAGE_SOLID_STATE_ENTERPRISE_NVMHCI 0x02
+
+#define IS_CLASS1(_p, c) ((_p)->Hdr.ClassCode[2] == (c))
+#define IS_CLASS2(_p, c, s) (IS_CLASS1 (_p, c) && ((_p)->Hdr.ClassCode[1] == (s)))
+#define IS_CLASS3(_p, c, s, p) (IS_CLASS2 (_p, c, s) && ((_p)->Hdr.ClassCode[0] == (p)))
+
+#ifndef CR
+#define CR(record, TYPE, field, signature) _CR(record, TYPE, field)
+#endif
+
+#ifndef _CR
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+#endif
+
+#define SetDevicePathNodeLength(a,l) { \
+ (a)->Length[0] = (UINT8) (l); \
+ (a)->Length[1] = (UINT8) ((l) >> 8); \
+ }
+
+#define EFI_DISK_INFO_NVME_INTERFACE_GUID { 0x3ab14680, 0x5d3f, 0x4a4d, 0xbc, 0xdc, 0xcc, 0x38, 0x0, 0x18, 0xc7, 0xf7 }
+#define NVME_SMM_GUID {0x1b30f467, 0xbf8b, 0x43b0, 0x81, 0x62, 0x29, 0xa, 0x27, 0xfd, 0x10, 0xcc}
+
+typedef struct {
+ CHAR8 *Language;
+ CHAR16 *UnicodeString;
+} EFI_UNICODE_STRING_TABLE;
+
+typedef struct {
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ UINT16 Command;
+ UINT16 Status;
+ UINT8 RevisionID;
+ UINT8 ClassCode[3];
+ UINT8 CacheLineSize;
+ UINT8 LatencyTimer;
+ UINT8 HeaderType;
+ UINT8 BIST;
+} PCI_DEVICE_INDEPENDENT_REGION;
+
+typedef struct {
+ UINT32 Bar[6];
+ UINT32 CISPtr;
+ UINT16 SubsystemVendorID;
+ UINT16 SubsystemID;
+ UINT32 ExpansionRomBar;
+ UINT8 CapabilityPtr;
+ UINT8 Reserved1[3];
+ UINT32 Reserved2;
+ UINT8 InterruptLine;
+ UINT8 InterruptPin;
+ UINT8 MinGnt;
+ UINT8 MaxLat;
+} PCI_DEVICE_HEADER_TYPE_REGION;
+
+typedef struct {
+ PCI_DEVICE_INDEPENDENT_REGION Hdr;
+ PCI_DEVICE_HEADER_TYPE_REGION Device;
+} PCI_TYPE00;
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL Header;
+ UINT32 Nsid;
+ UINT64 EUI64;
+} NVME_DEVICE_PATH;
+
+
+typedef struct {
+ UINT32 Signature;
+ EFI_HANDLE NvmeDeviceHandle;
+ BOOLEAN Configured; // Updated after installing BLOCK_IO_PROTOCOL
+ UINT32 ActiveNameSpaceID;
+
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+
+ UINT64 *PRP2List; // if the data transfer size is more than twice the max. page size
+ EFI_PHYSICAL_ADDRESS PRP2ListMappedAddr;
+ VOID *PRP2ListUnMap; // if the data transfer size is more than twice the max. page size
+ // then PRP List is used.
+ IDENTIFY_NAMESPACE_DATA IdentifyNamespaceData;
+
+ EFI_BLOCK_IO_PROTOCOL NvmeBlockIO;
+ EFI_DISK_INFO_PROTOCOL NvmeDiskInfo;
+ EFI_DEVICE_PATH_PROTOCOL *EfiDevicePath;
+ EFI_UNICODE_STRING_TABLE *UDeviceName;
+ UINT8 Int13DeviceAddress; // Used only for legacy Support
+ UINT16 wEmulationOption; // For INT13 support
+ UINT8 bHiddenSectors;
+ UINT8 NumHeads;
+ UINT8 LBANumHeads;
+ UINT16 NumCylinders;
+ UINT16 LBANumCyls;
+ UINT8 NumSectors;
+ UINT8 LBANumSectors;
+ UINT64 dMaxLBA;
+ UINT16 wBlockSize;
+ UINT8 bStorageType;
+ UINT8 bEmuType;
+ UINT8 PNM[27];
+ UINT8 NvmeManufactureId[NVME_MANUFACTUREID_LENGTH];
+
+ EFI_LIST_ENTRY Link; // Links to parent NVM Controller
+
+} ACTIVE_NAMESPACE_DATA;
+
+#define ACTIVE_NAMESPACE_DATA_FROM_THIS(a) \
+ CR(a, ACTIVE_NAMESPACE_DATA, NvmeBlockIO, ACTIVE_NAME_SPACE_SIG)
+
+#define ACTIVE_NAMESPACE_DATA_FROM_THIS_FOR_DISKINFO(a) \
+ CR(a, ACTIVE_NAMESPACE_DATA, NvmeDiskInfo, ACTIVE_NAME_SPACE_SIG)
+
+typedef struct _NVME_MASS_DEV_INFO NVME_MASS_DEV_INFO;
+
+EFI_STATUS
+NvmeBusSupported(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS
+NvmeBusStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+);
+
+EFI_STATUS
+NvmeBusStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+);
+
+EFI_STATUS
+InitializeNvmeController(
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE DriverBindingHandle,
+ OUT AMI_NVME_CONTROLLER_PROTOCOL **NvmeController
+);
+
+EFI_STATUS
+InstallBlockIoDiskInfo (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+EFI_STATUS
+CreateAdditionalSubmissionCompletionQueue (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+ IN UINT16 QueueNumber,
+ IN UINT32 QueueSize
+);
+
+EFI_STATUS
+ExecuteNvmeCmd (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+ OUT COMPLETION_QUEUE_ENTRY *CmdCompletionData
+);
+
+EFI_STATUS
+GetIdentifyData (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ OUT UINT8 *IdentifyData,
+ IN UINT8 ControllerNameSpaceStructure,
+ IN UINT32 NameSpaceID
+);
+
+VOID
+PrintNvmeCapability (
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+
+VOID
+PrintNvmeMassDevInfo (
+ NVME_MASS_DEV_INFO *NvmeMassDevInfo
+);
+
+EFI_STATUS
+AddToAdminSubmissionQueue (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+);
+
+EFI_STATUS
+AddToQueue1SubmissionQueue (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+);
+
+
+EFI_STATUS
+UpdateDoorBellRegister (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN UINT16 QueueNumber,
+ IN UINT32 Value
+);
+
+EFI_STATUS
+WaitForCompletionQueueUpdate (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+ OUT COMPLETION_QUEUE_ENTRY *CmdCompletionData
+);
+
+EFI_STATUS
+SetNumberOfQueues (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+EFI_STATUS
+EnumerateActiveNameSpace (
+ IN OUT AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+EFI_STATUS
+DetectActiveNameSpace (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData
+);
+
+
+VOID
+PrintIdentifyDataStructure (
+ IN UINT8 *IdentifyData,
+ IN UINT8 ControllerNameSpaceStructure
+);
+
+VOID
+PrintCommandCompletionData (
+ IN COMPLETION_QUEUE_ENTRY *pCmdCompletionData
+);
+
+VOID
+PrintNvmeCmdWrapper(
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+);
+
+EFI_STATUS
+ReadBlock (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ OUT UINT8 *Buffer
+);
+
+EFI_STATUS
+CreateNvmeDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData
+);
+
+EFI_STATUS
+RecreateQueue1 (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+EFI_STATUS
+RecreateAllQueues (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+EFI_STATUS
+NvmeReadBlocks(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+NvmeWriteBlocks(
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+NvmeReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS
+NvmeFlushBlocks(
+ IN EFI_BLOCK_IO_PROTOCOL *This
+);
+
+EFI_STATUS
+ProgramPRP2List (
+ IN UINT64 *PRP2List,
+ IN UINT32 PageSize,
+ IN UINTN BufferAddress,
+ IN UINTN BufferSize,
+ IN UINTN *PRP2TransferSize
+);
+
+EFI_STATUS
+NvmeReadWriteBlocks(
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer,
+ OUT COMPLETION_QUEUE_ENTRY *NvmeCompletionData,
+ IN UINT8 ReadWriteOpCode
+);
+
+EFI_STATUS
+ExperimentWithAsyncEvents (
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+VOID
+InstallNvmeLegacyDevice (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN UINT8 *Buffer
+);
+
+EFI_STATUS
+NvmeSetDefaultGeometry (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace
+);
+
+VOID
+NvmeMassUpdateCylinderInfo (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace
+);
+
+EFI_STATUS
+NvmeValidatePartitionTable (
+ IN UINT8 *Buffer,
+ IN UINT64 dMaxLBA,
+ OUT UINT8 **ActPartAddr
+);
+
+EFI_STATUS
+NvmeUpdateCHSFromBootRecord (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN UINT8* BootRecord
+);
+
+EFI_STATUS
+GetNvmeGeometryData (
+ IN OUT ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN OUT NVME_MASS_DEV_INFO *NvmeMassDevInfo,
+ IN UINT8 *Buffer
+);
+
+VOID
+TransferNvmeDataToSmram (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+);
+
+EFI_STATUS
+NvmeDiskInfoWhichIde (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT UINT32 *IdeChannel,
+ OUT UINT32 *IdeDevice
+);
+
+EFI_STATUS
+NvmeDiskInfoSenseData (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ OUT VOID *SenseData,
+ OUT UINT32 *SenseDataSize,
+ OUT UINT8 *SenseDataNumber
+);
+
+EFI_STATUS
+NvmeDiskInfoIdentify (
+ EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *IdentifyData,
+ IN OUT UINT32 *IdentifyDataSize
+);
+
+EFI_STATUS
+NvmeDiskInfoInquiry (
+ IN EFI_DISK_INFO_PROTOCOL *This,
+ IN OUT VOID *InquiryData,
+ IN OUT UINT32 *InquiryDataSize
+);
+
+
+extern EFI_GUID gEfiSmmCommunicationProtocolGuid;
+extern EFI_GUID gAmiSmmNvmeCommunicationGuid;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeComponentName.c b/Core/EM/Nvme/NvmeComponentName.c
new file mode 100644
index 0000000..b75ea5d
--- /dev/null
+++ b/Core/EM/Nvme/NvmeComponentName.c
@@ -0,0 +1,270 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeComponentName.c 2 9/04/14 7:36a Anandakrishnanl $
+//
+// $Revision: 2 $
+//
+// $Date: 9/04/14 7:36a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeComponentName.c $
+//
+// 2 9/04/14 7:36a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files]
+// Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeComonentName.c
+//
+// Description: Provides Controller and device Name information
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "NvmeIncludes.h"
+#include "NvmeBus.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+
+extern EFI_DRIVER_BINDING_PROTOCOL gNvmeBusDriverBinding;
+static EFI_GUID gAmiNvmeControllerProtocolGuid = AMI_NVME_CONTROLLER_PROTOCOL_GUID;
+
+EFI_STATUS
+NvmeBusCtlDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+);
+
+EFI_STATUS
+NvmeBusCtlGetControllerName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+);
+
+
+CHAR16 *gNvmeBusDriverName = L"AMI NVMe BUS Driver";
+CHAR16 *gNvmeBusControllerName = L"NVMe Mass Storage Controller";
+
+//==================================================================================
+EFI_COMPONENT_NAME2_PROTOCOL gNvmeBusControllerDriverName = {
+ NvmeBusCtlDriverName,
+ NvmeBusCtlGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// FUNCTION: NvmeBusCtlDriverName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// RETURN:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeBusCtlDriverName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ //
+ //Supports only English
+ //
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (Strcmp( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+ *DriverName = gNvmeBusDriverName;
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// FUNCTION: NvmeBusCtlGetControllerName
+//
+// DESCRIPTION: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// PARAMETERS:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// RETURNS:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeBusCtlGetControllerName(
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+
+ EFI_STATUS Status;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace;
+ EFI_LIST_ENTRY *LinkData;
+
+ // Check if gAmiNvmeControllerProtocolGuid is installed on the device
+ Status = pBS->OpenProtocol( Controller,
+ &gAmiNvmeControllerProtocolGuid,
+ (VOID **)&NvmeController,
+ gNvmeBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ //Supports only "en-US"
+ //
+ if(!Language || !ControllerName || !Controller) return EFI_INVALID_PARAMETER;
+ if (Strcmp( Language, LANGUAGE_CODE_ENGLISH)) return EFI_UNSUPPORTED;
+
+ if (ChildHandle == NULL) {
+ *ControllerName = gNvmeBusControllerName;
+ return EFI_SUCCESS;
+ } else {
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink; \
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ ActiveNameSpace = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+
+ if (ActiveNameSpace->NvmeDeviceHandle == ChildHandle){
+ *ControllerName = ActiveNameSpace->UDeviceName->UnicodeString;
+ return EFI_SUCCESS;
+
+ }
+ }
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeController.c b/Core/EM/Nvme/NvmeController.c
new file mode 100644
index 0000000..de54d60
--- /dev/null
+++ b/Core/EM/Nvme/NvmeController.c
@@ -0,0 +1,1446 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeController.c 3 5/14/15 2:39a Karthikar $
+//
+// $Revision: 3 $
+//
+// $Date: 5/14/15 2:39a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeController.c $
+//
+// 3 5/14/15 2:39a Karthikar
+// [TAG] EIP216763
+// [Category] Improvement
+// [Description] Update the Aptio 4.x Nvme driver to Aptio 5.x Nvme
+// driver Label 05
+// [Files] Nvme.mak,NvmeBus.c, NvmeBus.h, NvmeController.c,
+// NvmePassthru.c,NvmePassthru.h, NvmeSmm.c, NvmExpressPassThru.h,
+// PDiskInfo.h
+//
+// 2 9/04/14 7:47a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeController.c
+//
+// Description: Provides Access to Nvme Controller
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "NvmeIncludes.h"
+#include "NvmeBus.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\BlockIo.h>
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SmmStall
+//
+// Description: Stall Function
+//
+// Input:
+// UINTN Usec
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+SmmStall (
+ UINTN Usec
+ )
+{
+ UINTN Counter, i;
+ UINT32 Data32, PrevData;
+ UINTN Remainder;
+
+ Counter = (UINTN)Div64((Usec * 10), 3, &Remainder);
+
+ if (Remainder != 0) {
+ Counter++;
+ }
+
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CreateAdditionalSubmissionCompletionQueue
+//
+// Description: Creates Submission and Completion Queue
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+// IN UINT16 QueueNumber,
+// IN UINT32 QueueSize
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Can be called recursively
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+CreateAdditionalSubmissionCompletionQueue (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+ IN UINT16 QueueNumber,
+ IN UINT32 QueueSize
+)
+{
+
+ EFI_STATUS Status;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+ UINTN AllocatePageSize;
+ UINT64 QueueAddress = 0;
+
+ // Clear memory
+ MemSet(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Allocate memory only if the pointer is NULL
+ if (NvmeController->Queue1CompletionUnAligned == 0) {
+ AllocatePageSize = NvmeController->MemoryPageSize + QueueSize * sizeof(COMPLETION_QUEUE_ENTRY);
+
+ Status = NvmeController->PciIO->AllocateBuffer (NvmeController->PciIO,
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize),
+ (VOID **)&(QueueAddress),
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NvmeController->Queue1CompletionUnAligned = QueueAddress;
+ NvmeController->Queue1CompletionUnAlignedSize = EFI_SIZE_TO_PAGES(AllocatePageSize);
+ NvmeController->Queue1CompletionQueue = (QueueAddress & ~(NvmeController->MemoryPageSize - 1)) +
+ NvmeController->MemoryPageSize;
+
+ NvmeController->Queue1CompletionQueueSize = QueueSize;
+
+ MemSet((VOID *)NvmeController->Queue1CompletionQueue, \
+ NvmeController->Queue1CompletionQueueSize * sizeof (COMPLETION_QUEUE_ENTRY), 0);
+
+ Status = NvmeController->PciIO->Map ( NvmeController->PciIO,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID *)NvmeController->Queue1CompletionQueue,
+ &AllocatePageSize,
+ &NvmeController->Queue1CompletionQueueMappedAddr,
+ &NvmeController->Queue1CompletionQueueUnMap
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = CREATE_IO_COMPLETION_QUEUE;
+ NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.PSDT = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierAdmin;
+ NvmeCmdWrapper->NvmCmd.NSID = 0;
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)NvmeController->Queue1CompletionQueueMappedAddr;
+ NvmeCmdWrapper->NvmCmd.PRP2 = 0;
+ NvmeCmdWrapper->NvmCmd.CDW10 = ((QueueSize - 1) << 16 )+ QueueNumber;
+ NvmeCmdWrapper->NvmCmd.CDW11 = 1; // Contiguous
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
+ NvmeCmdWrapper->SQIdentifier = 0; // Cmd issued in Queue0
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+
+ if (EFI_ERROR(Status)) {
+ goto CreateAdditionalSubmissionCompletionQueue_Exit;
+ }
+
+ // Allocate memory only if the pointer is NULL
+ if (NvmeController->Queue1SubmissionUnAligned == 0) {
+
+ AllocatePageSize = NvmeController->MemoryPageSize +
+ QueueSize * sizeof(NVME_ADMIN_COMMAND);
+
+ Status = NvmeController->PciIO->AllocateBuffer (NvmeController->PciIO,
+ AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(AllocatePageSize),
+ (VOID **)&(QueueAddress),
+ EFI_PCI_IO_ATTRIBUTE_MEMORY_CACHED | EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NvmeController->Queue1SubmissionUnAligned = QueueAddress;
+ NvmeController->Queue1SubmissionUnAlignedSize = EFI_SIZE_TO_PAGES(AllocatePageSize);
+ NvmeController->Queue1SubmissionQueue = (QueueAddress & ~(NvmeController->MemoryPageSize - 1)) +
+ NvmeController->MemoryPageSize;
+
+ NvmeController->Queue1SubmissionQueueSize = QueueSize;
+ MemSet((VOID *)NvmeController->Queue1SubmissionQueue, \
+ NvmeController->Queue1SubmissionQueueSize * sizeof(NVME_ADMIN_COMMAND), 0);
+
+ Status = NvmeController->PciIO->Map ( NvmeController->PciIO,
+ EfiPciIoOperationBusMasterCommonBuffer,
+ (VOID *)NvmeController->Queue1SubmissionQueue,
+ &AllocatePageSize,
+ &NvmeController->Queue1SubmissionQueueMappedAddr,
+ &NvmeController->Queue1SubmissionQueueUnMap
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ }
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = CREATE_IO_SUBMISSION_QUEUE;
+ NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.PSDT = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierAdmin;
+ NvmeCmdWrapper->NvmCmd.NSID = 0;
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)NvmeController->Queue1SubmissionQueueMappedAddr;
+ NvmeCmdWrapper->NvmCmd.PRP2 = 0;
+ NvmeCmdWrapper->NvmCmd.CDW10 = ((QueueSize - 1) << 16 )+ QueueNumber;
+ NvmeCmdWrapper->NvmCmd.CDW11 = (QueueNumber << 16) + 1; // Contiguous
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
+ NvmeCmdWrapper->SQIdentifier = 0; // Cmd issued to admin queue
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+
+ CreateAdditionalSubmissionCompletionQueue_Exit:
+
+ NvmeController->Queue1PhaseTag = FALSE;
+
+ NvmeController->Queue1SubmissionQueueTailPtr = 0;
+ NvmeController->Queue1SubmissionQueueHeadPtr = 0;
+
+ NvmeController->Queue1CompletionQueueTailPtr = 0;
+ NvmeController->Queue1CompletionQueueHeadPtr = 0;
+
+ return Status;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ProgramPRP2List
+//
+// Description: Programs PRP2 with the list of page address for data transfer
+//
+// Input:
+// IN EFI_BLOCK_IO_PROTOCOL *This
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ProgramPRP2List (
+ IN UINT64 *PRP2List,
+ IN UINT32 PageSize,
+ IN UINTN BufferAddress,
+ IN UINTN BufferSize,
+ IN UINTN *PRP2TransferSize
+)
+{
+
+ UINTN TotalNumberOfEntries = PageSize / 8; // Each entry 64 bytes long
+
+ *PRP2TransferSize = 0;
+
+ do {
+
+ *PRP2List++ = BufferAddress;
+ if (BufferSize >= PageSize) {
+ *PRP2TransferSize += PageSize;
+ BufferAddress += PageSize;
+ BufferSize -= PageSize;
+ } else {
+ *PRP2TransferSize = *PRP2TransferSize + (UINT32)BufferSize;
+ BufferAddress += BufferSize;
+ BufferSize = 0;
+ }
+
+ } while (--TotalNumberOfEntries && (BufferSize > 0));
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeReadWriteBlocks
+//
+// Description: Read/Write data from the given LBA address
+//
+// Input:
+// IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+// IN UINT32 MediaId,
+// IN EFI_LBA LBA,
+// IN UINTN BufferSize,
+// OUT VOID *Buffer
+// IN UINT8 ReadWriteOpCode
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+NvmeReadWriteBlocks(
+ IN ACTIVE_NAMESPACE_DATA *ActiveNameSpace,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer,
+ OUT COMPLETION_QUEUE_ENTRY *NvmeCompletionData,
+ IN UINT8 ReadWriteOpCode
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController = ActiveNameSpace->NvmeController;
+ EFI_BLOCK_IO_MEDIA *BlkMedia = ActiveNameSpace->NvmeBlockIO.Media;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper = NvmeController->NvmeCmdWrapper;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+ COMPLETION_QUEUE_ENTRY *pCompletionData = &CompletionData;
+ UINTN DataN;
+ UINT32 LBACountInOneTransfer;
+ UINTN PRP1TransferSize;
+ UINTN PRP2TransferSize;
+ UINTN MappedBufferSize = BufferSize;
+ EFI_PHYSICAL_ADDRESS MappedBuffer;
+ VOID *BufferUnMap;
+
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1,"LBA : %lx BufferSize : %lx Buffer : %lx Opcode : %x", LBA, BufferSize, Buffer, ReadWriteOpCode));
+ }
+
+ // Check if Media ID matches
+ if (BlkMedia->MediaId != MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (BufferSize == 0) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ if((BlkMedia->IoAlign > 1 ) && ((UINTN)Buffer % BlkMedia->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check whether the block size is multiple of BlkMedia->BlockSize
+ DataN = BufferSize % BlkMedia->BlockSize;
+ if (DataN){
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ // Check for Valid start LBA #
+ if (LBA > BlkMedia->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check for Valid End LBA #
+ DataN = BufferSize / BlkMedia->BlockSize;
+ if (LBA + DataN > BlkMedia->LastBlock + 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do {
+ // Limit the transfer size to MDTS value
+ if (NvmeController->IdentifyControllerData->MDTS && (MappedBufferSize > (UINTN)(Mul64(Shl64(1, NvmeController->IdentifyControllerData->MDTS), NvmeController->MemoryPageSizeMin)))){
+ MappedBufferSize = (UINTN)Mul64(Shl64(1, NvmeController->IdentifyControllerData->MDTS), NvmeController->MemoryPageSizeMin);
+ }
+
+
+ // After MAP, Mapped BufferSize may not be same as input.
+ // So need to complete the transfer in multiple loops.
+ // When the call originates from SMM, don't call Map function
+ MappedBuffer = (EFI_PHYSICAL_ADDRESS) Buffer;
+ if (!NvmeController->NvmeInSmm) {
+
+ Status = NvmeController->PciIO->Map ( NvmeController->PciIO,
+ ((ReadWriteOpCode == NVME_READ) || (ReadWriteOpCode == NVME_COMPARE)) ? EfiPciIoOperationBusMasterWrite : EfiPciIoOperationBusMasterRead,
+ Buffer,
+ &MappedBufferSize,
+ &MappedBuffer,
+ &BufferUnMap
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ MemSet(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+ LBACountInOneTransfer = 0;
+
+ PRP2TransferSize = 0;
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64) MappedBuffer;
+ PRP1TransferSize = NvmeController->MemoryPageSize -
+ (MappedBuffer & ((UINTN)(NvmeController->MemoryPageSize) - 1));
+
+ // If all data can be transferred using only PRP1 then do that.
+ if (PRP1TransferSize >= MappedBufferSize) {
+ PRP1TransferSize = MappedBufferSize;
+ }
+
+ // Do we need PRP2
+ if (MappedBufferSize - PRP1TransferSize) {
+
+ // Do we need either a PRP2 pointer or a List
+ if (MappedBufferSize - PRP1TransferSize <= NvmeController->MemoryPageSize) {
+ NvmeCmdWrapper->NvmCmd.PRP2 = NvmeCmdWrapper->NvmCmd.PRP1 + PRP1TransferSize;
+ PRP2TransferSize = MappedBufferSize - PRP1TransferSize;
+ } else {
+ // We need PRP2 List
+ Status = ProgramPRP2List (ActiveNameSpace->PRP2List, NvmeController->MemoryPageSize, \
+ (UINTN)MappedBuffer + PRP1TransferSize, \
+ MappedBufferSize - PRP1TransferSize, &PRP2TransferSize
+ );
+
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ NvmeCmdWrapper->NvmCmd.PRP2 = (UINT64) ActiveNameSpace->PRP2ListMappedAddr;
+ }
+ }
+
+ LBACountInOneTransfer = (UINT32)((PRP1TransferSize + PRP2TransferSize) / BlkMedia->BlockSize);
+
+ // Build NVME command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = ReadWriteOpCode;
+ NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.PSDT = 0;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierQueue1;
+ NvmeCmdWrapper->NvmCmd.NSID = ActiveNameSpace->ActiveNameSpaceID;
+
+ NvmeCmdWrapper->NvmCmd.MPTR = 0;
+ NvmeCmdWrapper->NvmCmd.CDW10 = (UINT32)LBA;
+ NvmeCmdWrapper->NvmCmd.CDW11 = (UINT32)Shr64(LBA, 32);
+ NvmeCmdWrapper->NvmCmd.CDW12 = 0x80000000 + (LBACountInOneTransfer - 1);
+ NvmeCmdWrapper->NvmCmd.CDW13 = 0;
+ NvmeCmdWrapper->NvmCmd.CDW14 = 0;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = FALSE;
+ NvmeCmdWrapper->SQIdentifier = NvmeController->NVMQueueNumber;
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ // If caller has passed buffer to return controller status, use it.
+ if (NvmeCompletionData) {
+ pCompletionData = NvmeCompletionData;
+ }
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, pCompletionData);
+
+ if (EFI_ERROR(Status)) {
+ if (!NvmeController->NvmeInSmm) {
+ NvmeController->PciIO->Unmap(NvmeController->PciIO, BufferUnMap);
+ }
+ break;
+ }
+
+ // Remaining Bytes to be transferred
+ MappedBufferSize -= (LBACountInOneTransfer * BlkMedia->BlockSize);
+
+ // Update LBA # for next transfer if needed
+ LBA += LBACountInOneTransfer;
+
+ // Adjust the Buffer address
+ Buffer =(VOID*) ((UINTN) Buffer + (LBACountInOneTransfer * BlkMedia->BlockSize));
+ BufferSize -= (LBACountInOneTransfer * BlkMedia->BlockSize);
+
+ // When PciIO->Map is called, it might not map the complete buffer.
+ // After the complete MappedBufferSize is transferred, if there is a left over do that transfer also
+ if (MappedBufferSize == 0) {
+ MappedBufferSize = BufferSize;
+ }
+
+ if (!NvmeController->NvmeInSmm) {
+ NvmeController->PciIO->Unmap(NvmeController->PciIO, BufferUnMap);
+ }
+
+ } while (MappedBufferSize);
+
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1,"%r \n", Status));
+ }
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ExecuteNvmeCmd
+//
+// Description: Execute Admin and Nvme cmds
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+// OUT COMPLETION_QUEUE_ENTRY *CmdCompletionData
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: If the cmd needs to be retried due to a failure, caller can initialize the RetryCount.
+// Can be called recursively.
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+ExecuteNvmeCmd (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+ OUT COMPLETION_QUEUE_ENTRY *CmdCompletionData
+)
+
+{
+ EFI_STATUS Status;
+
+ do {
+ // Because of recursive nature and retry mechnism, cmd identifer needs to be updated just before giving the call.
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->CommandIdentifierAdmin : \
+ NvmeController->CommandIdentifierQueue1;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet ? (Status = AddToAdminSubmissionQueue(NvmeController, NvmeCmdWrapper)) : \
+ (Status = AddToQueue1SubmissionQueue(NvmeController, NvmeCmdWrapper));
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = UpdateDoorBellRegister(NvmeController,
+ NvmeCmdWrapper->SQIdentifier,
+ NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->AdminSubmissionQueueTailPtr :
+ NvmeController->Queue1SubmissionQueueTailPtr
+ );
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ //Wait for cmd to complete
+ if (NvmeCmdWrapper->NvmCmd.CMD0.Opcode != ASYNC_EVENT_REQUEST) {
+ Status = WaitForCompletionQueueUpdate(NvmeController, NvmeCmdWrapper, CmdCompletionData);
+ }
+
+ } while (EFI_ERROR(Status) && NvmeCmdWrapper->RetryCount--);
+
+ return Status;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AddToAdminSubmissionQueue
+//
+// Description: Submits the cmd to the Admin Submission queue
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AddToAdminSubmissionQueue (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+)
+{
+ EFI_STATUS Status;
+ UINT64 DestinationAddress;
+
+ // Is Admin Queue full?
+ if (NvmeController->AdminSubmissionQueueHeadPtr) { // Non-zero value
+ if ((NvmeController->AdminSubmissionQueueTailPtr - 1) == NvmeController->AdminSubmissionQueueHeadPtr){
+
+ // In this design, queue should never get filled up.
+ // If it does something is wrong. Delete and start all over again.
+
+ Status = RecreateAllQueues (NvmeController);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ }
+ } else {
+ // If Head is at the start and Tail is at the end, then queue is full
+ if (NvmeController->AdminSubmissionQueueTailPtr == (NvmeController->AdminSubmissionQueueHeadPtr +
+ NvmeController->AdminSubmissionQueueSize - 1)) {
+
+ // In this design, queue should never get filled up.
+ // If it does something is wrong. Delete and start all over again.
+ Status = RecreateAllQueues (NvmeController);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ // Copy cmd to Admin Queue
+ DestinationAddress = NvmeController->AdminSubmissionQueue + (
+ NvmeController->AdminSubmissionQueueTailPtr * sizeof(NVME_ADMIN_COMMAND));
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Destination Address for Cmd : %016lx\n", DestinationAddress));
+ }
+#endif
+
+ MemCpy ((VOID *)DestinationAddress, &(NvmeCmdWrapper->NvmCmd), sizeof(NVME_ADMIN_COMMAND));
+
+ NvmeController->AdminSubmissionQueueTailPtr++;
+
+ // Check if there is a roller over
+ if (NvmeController->AdminSubmissionQueueTailPtr >= (NvmeController->AdminSubmissionQueueSize)) {
+ NvmeController->AdminSubmissionQueueTailPtr = 0;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AddToQueue1SubmissionQueue
+//
+// Description: Submits the Nvme cmd to the Queue1 Submission queue
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AddToQueue1SubmissionQueue (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+)
+{
+ EFI_STATUS Status;
+ UINT64 DestinationAddress;
+
+ // Is Queue full? If Tail is one less than the Head queue is full.
+ if (NvmeController->Queue1SubmissionQueueHeadPtr) { // Non-zero value
+ if ((NvmeController->Queue1SubmissionQueueTailPtr - 1) == NvmeController->Queue1SubmissionQueueHeadPtr){
+
+ // In this design, queue should never get filled up.
+ // If it does something is wrong. Delete and start all over again.
+ Status = RecreateQueue1 (NvmeController);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ }
+ } else {
+ // If Head is at the start and Tail is at the end, then queue is full
+ if (NvmeController->Queue1SubmissionQueueTailPtr == (NvmeController->Queue1SubmissionQueueHeadPtr +
+ NvmeController->Queue1SubmissionQueueSize - 1)) {
+
+ // In this design, queue should never get filled up.
+ // If it does something is wrong. Delete and start all over again.
+
+ Status = RecreateQueue1 (NvmeController);
+ if (EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+
+ // Copy cmd to Admin Queue
+ DestinationAddress = NvmeController->Queue1SubmissionQueue +
+ (NvmeController->Queue1SubmissionQueueTailPtr * sizeof(NVME_ADMIN_COMMAND));
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Destination Address for Cmd : %016lx\n", DestinationAddress));
+ }
+#endif
+
+ MemCpy ((VOID *)DestinationAddress, &(NvmeCmdWrapper->NvmCmd), sizeof(NVME_ADMIN_COMMAND));
+
+ NvmeController->Queue1SubmissionQueueTailPtr++;
+
+ // Check if there is a roller over
+ if (NvmeController->Queue1SubmissionQueueTailPtr >= NvmeController->Queue1SubmissionQueueSize) {
+ NvmeController->Queue1SubmissionQueueTailPtr = 0;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: UpdateDoorBellRegister
+//
+// Description: Update door bell register for the controller to start executing the cmd
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN UINT16 QueueNumber,
+// IN UINT32 Value
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+UpdateDoorBellRegister (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN UINT16 QueueNumber,
+ IN UINT32 Value
+)
+{
+
+ UINT32 Offset;
+
+ // Update Door Bell Register
+ Offset = QUEUE_DOORBELL_OFFSET(QueueNumber, 0, NvmeController->DoorBellStride);
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "\nDoorBell Offset %016lx Value %08X\n", NvmeController->NvmeBarOffset + Offset, Value));
+ }
+#endif
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset) = Value;
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: WaitForCompletionQueueUpdate
+//
+// Description: Checks for the completion queue for the correct PhaseTag, Queue Identified and Cmd Identifier
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+// IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+// OUT COMPLETION_QUEUE_ENTRY *CmdCompletionData
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+WaitForCompletionQueueUpdate (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ IN NVME_COMMAND_WRAPPER *NvmeCmdWrapper,
+ OUT COMPLETION_QUEUE_ENTRY *CmdCompletionData
+)
+{
+
+ EFI_STATUS Status;
+ UINT32 TimeOut = NvmeCmdWrapper->CmdTimeOut;
+ UINT32 Offset;
+ COMPLETION_QUEUE_ENTRY *pCmdCompletionData;
+ UINT16 CommandIdentifier = NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->CommandIdentifierAdmin : \
+ NvmeController->CommandIdentifierQueue1;
+
+ UINT64 CompletionQueueStart = NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->AdminCompletionQueue : \
+ NvmeController->Queue1CompletionQueue;
+
+ UINT16 CompletionQueueHeadPtr = NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->AdminCompletionQueueHeadPtr :\
+ NvmeController->Queue1CompletionQueueHeadPtr;
+
+ // Toggle extected phasetag on every rollover
+ if (CompletionQueueHeadPtr == 0) {
+ NvmeCmdWrapper->AdminOrNVMCmdSet ? (NvmeController->AdminPhaseTag = ~NvmeController->AdminPhaseTag) : \
+ (NvmeController->Queue1PhaseTag = ~NvmeController->Queue1PhaseTag);
+ }
+
+ // Get the offset to the Command Completion Queue Head Ptr
+ pCmdCompletionData = (COMPLETION_QUEUE_ENTRY *)(CompletionQueueStart + CompletionQueueHeadPtr * sizeof(COMPLETION_QUEUE_ENTRY));
+
+ do {
+ // Check whether Command Identifier, SQ ID matches and Phase Tag matches with the cmd issued.
+ if ((pCmdCompletionData->CommandIdentifier == CommandIdentifier) && \
+ (pCmdCompletionData->SQIdentifier == NvmeCmdWrapper->SQIdentifier) && \
+ (pCmdCompletionData->PhaseTag == (NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->AdminPhaseTag : NvmeController->Queue1PhaseTag)))
+ {
+ break;
+ }
+
+ // check if there are any fatal errors
+ if (CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CSTS) & CSTS_CFS){
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Nvme Fatal Error\n"));
+ }
+ return EFI_DEVICE_ERROR;
+
+ }
+
+ if (!NvmeController->NvmeInSmm) {
+ pBS->Stall(1000); // 1msec delay
+ } else {
+ SmmStall (1000);
+ }
+ } while (--TimeOut);
+
+ if (!NvmeController->NvmeInSmm) {
+ PrintCommandCompletionData (pCmdCompletionData);
+ }
+
+ if (!TimeOut) {
+
+ // This is a fatal condition. We should expect some kind of response from the controller.
+ // If not we have to either wait for more time or delete and recreate the queue
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->CommandIdentifierAdmin++ : \
+ NvmeController->CommandIdentifierQueue1++;
+
+ if (NvmeCmdWrapper->AdminOrNVMCmdSet) {
+ Status = RecreateAllQueues(NvmeController);
+ } else {
+ Status = RecreateQueue1(NvmeController);
+ }
+
+ if (EFI_ERROR(Status)) {
+ // If recreating the queue gets an error. nothing can be done.
+ NvmeCmdWrapper->RetryCount = 0;
+ } else {
+ // Retry the cmd one more time
+ NvmeCmdWrapper->RetryCount++;
+ }
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Update HeadPtr from Completion Queue.
+ // Check what Queue was cmd posted to and then update the corresponding Head/Tail ptr
+ if (NvmeCmdWrapper->AdminOrNVMCmdSet) {
+ NvmeController->AdminSubmissionQueueHeadPtr = pCmdCompletionData->SQHeadPointer;
+ NvmeController->AdminCompletionQueueHeadPtr = NvmeController->AdminSubmissionQueueHeadPtr;
+ Offset = QUEUE_DOORBELL_OFFSET(NvmeCmdWrapper->SQIdentifier, 1, NvmeController->DoorBellStride);
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset) = NvmeController->AdminCompletionQueueHeadPtr;
+ } else {
+ NvmeController->Queue1SubmissionQueueHeadPtr = pCmdCompletionData->SQHeadPointer;
+ NvmeController->Queue1CompletionQueueHeadPtr = NvmeController->Queue1SubmissionQueueHeadPtr;
+ Offset = QUEUE_DOORBELL_OFFSET(NvmeCmdWrapper->SQIdentifier, 1, NvmeController->DoorBellStride);
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset) = NvmeController->Queue1CompletionQueueHeadPtr;
+ }
+
+ // Todo Todo
+ // Check whether all cmds submitted has been completed. CompletionQueue Head Ptr should give a clue on
+ // how many cmds where executed.
+ if (pCmdCompletionData->StatusCode || pCmdCompletionData->StatusCodeType) {
+ Status = EFI_DEVICE_ERROR;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ if (NvmeCmdWrapper->AdminOrNVMCmdSet) {
+ TRACE((-1, "AdminSubmissionQueueHeadPtr %08X\n", NvmeController->AdminSubmissionQueueHeadPtr));
+ TRACE((-1, "AdminSubmissionQueueTailPtr %08X\n", NvmeController->AdminSubmissionQueueTailPtr));
+ TRACE((-1, "AdminCompletionQueueHeadPtr %08X\n", NvmeController->AdminCompletionQueueHeadPtr));
+ TRACE((-1, "AdminCompletionQueueTailPtr %08X\n", NvmeController->AdminCompletionQueueTailPtr));
+ } else {
+ TRACE((-1, "Queue1SubmissionQueueHeadPtr %08X\n", NvmeController->Queue1SubmissionQueueHeadPtr));
+ TRACE((-1, "Queue1SubmissionQueueTailPtr %08X\n", NvmeController->Queue1SubmissionQueueTailPtr));
+ TRACE((-1, "Queue1CompletionQueueHeadPtr %08X\n", NvmeController->Queue1CompletionQueueHeadPtr));
+ TRACE((-1, "Queue1CompletionQueueTailPtr %08X\n", NvmeController->Queue1CompletionQueueTailPtr));
+ }
+ }
+#endif
+
+ // Update o/p buffer
+ MemCpy ((VOID *)CmdCompletionData, pCmdCompletionData, sizeof(COMPLETION_QUEUE_ENTRY));
+ NvmeCmdWrapper->AdminOrNVMCmdSet ? NvmeController->CommandIdentifierAdmin++ : NvmeController->CommandIdentifierQueue1++;
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RecreateAllQueues
+//
+// Description: Delete Admin and other Completion/Submission queue and create it back again.
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: This procedure will be called if the queue gets filled up. This situation shouldn't generally happen as each cmd
+// is completed in our case. So both Head and Tail should point to the same location before and after cmd is executed.
+// One possibility for calling this routine will be when the cmd doesn't get completed and Completion Queue doesn't get updated
+// by the controller. Also any Set Feature cmd that was issued during initilization should be re-issued here.
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+RecreateAllQueues (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 ProgramCC = 0;
+ UINT32 Delay;
+
+
+ // In SMM, this function is not supported
+ if (NvmeController->NvmeInSmm) {
+ return EFI_DEVICE_ERROR;
+ }
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Recreate Admin Queue : "));
+ }
+#endif
+
+ ProgramCC = CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CC);
+
+ // Check if the controller is already running. If yes stop it.
+ Delay = NvmeController->TimeOut * 500;
+ if (CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CC) & 0x1) {
+
+ // Clear Control register
+ CONTROLLER_REG32 (NvmeController->NvmeBarOffset, Offset_CC) = 0;
+ do {
+ if (!(CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CSTS) & 0x1)) {
+ break;
+ }
+
+ if (!NvmeController->NvmeInSmm) {
+ pBS->Stall(1000); // 1msec delay
+ }
+ else {
+ SmmStall (1000);
+ }
+
+ } while (--Delay);
+
+ }
+
+ if (!Delay) {
+ goto RecreateAllQueues_Error;
+ }
+
+ // Program Admin Queue Size and Base Address
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Aqa) =
+ (UINT32)(Shl64((NvmeController->AdminCompletionQueueSize - 1), 16) + (NvmeController->AdminSubmissionQueueSize - 1));
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Asq) =
+ (UINT32) NvmeController->AdminSubmissionQueue;
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Asq + 4) =
+ (UINT32)Shr64(NvmeController->AdminSubmissionQueue, 32);
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Acq) =
+ (UINT32)NvmeController->AdminCompletionQueue;
+
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_Acq + 4) =
+ (UINT32)Shr64(NvmeController->AdminCompletionQueue, 32);
+
+ NvmeController->AdminPhaseTag = FALSE;
+
+ // Enable Controller
+ CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CC) = (ProgramCC | 1);
+
+ // Wait for the controller to get ready
+ // Check if the cobtroller is already running. If yes stop it.
+ Delay = NvmeController->TimeOut * 500;
+ do {
+ if ((CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset_CSTS) & 0x1)) {
+ break;
+ }
+
+ if (!NvmeController->NvmeInSmm) {
+ pBS->Stall(1000); // 1msec delay
+ }
+ else {
+ SmmStall (1000);
+ }
+
+ } while (--Delay);
+
+RecreateAllQueues_Error:
+
+ if (!Delay) {
+ Status = EFI_DEVICE_ERROR;
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Status %r\n", Status));
+ }
+#endif
+
+ return Status;
+ }
+
+ NvmeController->AdminSubmissionQueueHeadPtr = 0;
+ NvmeController->AdminSubmissionQueueTailPtr = 0;
+ NvmeController->AdminCompletionQueueHeadPtr = 0;
+ NvmeController->AdminCompletionQueueTailPtr = 0;
+ NvmeController->AdminPhaseTag = FALSE;
+
+ if (!NvmeController->ReInitializingQueue1) {
+ Status = RecreateQueue1 (NvmeController);
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RecreateQueue1
+//
+// Description: Delete Completion and Submission queue and create it back again.
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: This procedure will be called if the queue gets filled up. This situation shouldn't generally happen as each cmd
+// is completed in our case. So both Head and Tail should point to the same location before and after cmd is executed.
+// One possibility for calling this routine will be when the cmd doesn't get completed and Completion Queue doesn't get updated
+// by the controller. Can be called recursively.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+RecreateQueue1 (
+ IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+)
+{
+
+ EFI_STATUS Status;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper;
+ COMPLETION_QUEUE_ENTRY CompletionData;
+
+ // In SMM, this function not supported
+ if (NvmeController->NvmeInSmm) {
+ return EFI_DEVICE_ERROR;
+ }
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Recreate Queue1 : "));
+ }
+#endif
+
+ NvmeController->ReInitializingQueue1 = TRUE;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(NVME_COMMAND_WRAPPER),
+ (VOID**)&NvmeCmdWrapper
+ );
+
+ if (EFI_ERROR(Status)) {
+ NvmeController->ReInitializingQueue1 = FALSE;
+ return Status;
+ }
+
+ // Clear memory
+ MemSet(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Build NVME command to delete Submission queue
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = DELETE_IO_SUBMISSION_QUEUE;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierAdmin;
+ NvmeCmdWrapper->NvmCmd.CDW10 = NvmeController->NVMQueueNumber;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
+ NvmeCmdWrapper->SQIdentifier = 0; // Queue 0 for Admin cmds
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+ if (EFI_ERROR(Status)) {
+ goto RecreateQueue1_Error;
+ }
+
+ // Build NVME command to delete Completion queue
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = DELETE_IO_COMPLETION_QUEUE;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = NvmeController->CommandIdentifierAdmin;
+ NvmeCmdWrapper->NvmCmd.CDW10 = NvmeController->NVMQueueNumber;
+
+ NvmeCmdWrapper->AdminOrNVMCmdSet = TRUE;
+ NvmeCmdWrapper->SQIdentifier = 0; // Queue 0 for Admin cmds
+ NvmeCmdWrapper->CmdTimeOut = 1000;
+
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, &CompletionData);
+ if (EFI_ERROR(Status)) {
+ goto RecreateQueue1_Error;
+ }
+
+ // Create Submission and Completion Queue1
+ Status = CreateAdditionalSubmissionCompletionQueue(
+ NvmeController,
+ NvmeCmdWrapper,
+ NvmeController->NVMQueueNumber,
+ NvmeController->Queue1SubmissionQueueSize
+ );
+
+RecreateQueue1_Error:
+
+ NvmeController->ReInitializingQueue1 = FALSE;
+
+ pBS->FreePool (NvmeCmdWrapper);
+
+#if NVME_VERBOSE_PRINT
+ if (!NvmeController->NvmeInSmm) {
+ TRACE((-1, "Status %r\n", Status));
+ }
+#endif
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PrintCommandCompletionData
+//
+// Description: Prints the cmd completion status
+//
+// Input:
+// IN COMPLETION_QUEUE_ENTRY *pCmdCompletionData
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: The amount of data that will get printed can be controlled
+// using DEBUG_ERROR_LEVEL_MASK SDL token.
+// Make sure PcdDebugPrintErrorLevel is properly cloned and set to
+// PcdsPatchableInModule in the project.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+VOID
+PrintCommandCompletionData (
+ IN COMPLETION_QUEUE_ENTRY *pCmdCompletionData
+)
+{
+
+#if NVME_VERBOSE_PRINT
+ // Fig 25 NVM Express 1.1 spec
+ // Print Completion Cmd Data
+ TRACE((-1, "Completion Queue DW2 : %08X\n", *((UINT32 *)pCmdCompletionData + 2)));
+ TRACE((-1, "Completion Queue DW3 : %08X\n", *((UINT32 *)pCmdCompletionData + 3)));
+ TRACE((-1, "Completion Queue DW0 : %08X\n", pCmdCompletionData->DW0));
+ TRACE((-1, "Completion Queue Reserved : %08X\n", pCmdCompletionData->DW1));
+#endif
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: PrintNvmeCmdWrapper
+//
+// Description: Prints Nvme cmd parameters
+//
+// Input:
+// NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: The amount of data that will get printed can be controlled
+// using DEBUG_ERROR_LEVEL_MASK SDL token.
+// Make sure PcdDebugPrintErrorLevel is properly cloned and set to
+// PcdsPatchableInModule in the project.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+PrintNvmeCmdWrapper (
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper
+)
+{
+
+
+#if NVME_VERBOSE_PRINT
+ TRACE((-1,"\nCMD DW0 : %08X\n", *(UINT32 *)&(NvmeCmdWrapper->NvmCmd)));
+ TRACE((-1, "MPTR : %016lX\n", NvmeCmdWrapper->NvmCmd.MPTR));
+ TRACE((-1, "PRP1 : %016lX\n", NvmeCmdWrapper->NvmCmd.PRP1));
+ TRACE((-1, "PRP2 : %016lX\n", NvmeCmdWrapper->NvmCmd.PRP2));
+ TRACE((-1, "CDW10 : %08X\n", NvmeCmdWrapper->NvmCmd.CDW10));
+ TRACE((-1, "CDW11 : %08X\n", NvmeCmdWrapper->NvmCmd.CDW11));
+ TRACE((-1, "CDW12 : %08X\n", NvmeCmdWrapper->NvmCmd.CDW12));
+ TRACE((-1, "CDW13 : %08X\n", NvmeCmdWrapper->NvmCmd.CDW13));
+ TRACE((-1, "CDW14 : %08X\n", NvmeCmdWrapper->NvmCmd.CDW14));
+ TRACE((-1, "CDW15 : %08X\n", NvmeCmdWrapper->NvmCmd.CDW15));
+ TRACE((-1, "Cmd sent to Queue : %08X\n", NvmeCmdWrapper->SQIdentifier));
+#endif
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Procedure: UnicodeStrToAsciiStr
+//
+// Description: This function converts the content of the Unicode string Source
+// to the ASCII string Destination by copying the lower 8 bits of
+// each Unicode character and returns Destination
+//
+// Input: Source A pointer to a Null-terminated Unicode string.
+// Destination A pointer to a Null-terminated ASCII string.
+//
+// Output: None
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+CHAR8*
+UnicodeStrToAsciiStr (
+ IN CONST CHAR16 *Source,
+ OUT CHAR8 *Destination
+ )
+{
+ CHAR8 *ReturnValue;
+ UINTN TempReturnValue;
+ UINTN TempSource;
+
+ ASSERT (Destination != NULL);
+ //
+ // ASSERT if Source is long than PcdMaximumUnicodeStringLength.
+ // Length tests are performed inside StrLen().
+ //
+ TempSource = (Wcslen ((CHAR16 *)Source) + 1) * sizeof (*Source);
+ ASSERT (TempSource != 0);
+ //
+ // Source and Destination should not overlap
+ //
+ ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > Wcslen ((CHAR16 *)Source));
+ ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > Wcslen ((CHAR16 *)Source));
+
+
+ ReturnValue = Destination;
+ while (*Source != '\0') {
+ //
+ // If any Unicode characters in Source contain
+ // non-zero value in the upper 8 bits, then ASSERT().
+ //
+ ASSERT (*Source < 0x100);
+ *(Destination++) = (CHAR8) *(Source++);
+ }
+
+ *Destination = '\0';
+
+ //
+ // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.
+ // Length tests are performed inside AsciiStrLen().
+ //
+ TempReturnValue = (Strlen((CHAR8 *)ReturnValue) + 1) * sizeof (*ReturnValue);
+ ASSERT (TempReturnValue!= 0);
+
+ return ReturnValue;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeController.cif b/Core/EM/Nvme/NvmeController.cif
new file mode 100644
index 0000000..b0f81a1
--- /dev/null
+++ b/Core/EM/Nvme/NvmeController.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "NvmeControllerLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\Nvme\"
+ RefName = "NvmeControllerLib"
+
+[files]
+"NvmeController.sdl"
+"NvmeController.mak"
+"NvmeController.c"
+"NvmeController.h"
+<endComponent>
diff --git a/Core/EM/Nvme/NvmeController.h b/Core/EM/Nvme/NvmeController.h
new file mode 100644
index 0000000..00ebff7
--- /dev/null
+++ b/Core/EM/Nvme/NvmeController.h
@@ -0,0 +1,235 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeController.h 3 5/19/15 7:59a Deepthins $
+//
+// $Revision: 3 $
+//
+// $Date: 5/19/15 7:59a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeController.h $
+//
+// 3 5/19/15 7:59a Deepthins
+// [TAG] EIP218059
+// [Category] Improvement
+// [Description] Update Aptio4 NVME module to spec v1.2
+// [Files] AmiNvmeController.h, NvmeController.h
+//
+// 2 9/04/14 7:48a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeController.h
+//
+// Description: Nvme Controller related defination
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _NVME_CONTROLLER_H_
+#define _NVME_CONTROLLER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(1)
+
+// Refer to NVM Spec second 3.1 NVMe 1.1 which describes the register map for the controller
+#define Offset_Cap 0x0
+#define Offset_Version 0x8
+#define Offset_Intms 0xC
+#define Offset_Intmc 0x10
+#define Offset_CC 0x14
+#define Offset_CSTS 0x1C
+#define CSTS_RDY 0x1
+#define CSTS_CFS 0x2
+#define Offset_Nssrs 0x20
+#define Offset_Aqa 0x24
+#define Offset_Asq 0x28
+#define Offset_Acq 0x30
+#define Offset_CMBLOC 0x38
+#define Offset_CMBSZ 0x3C
+#define Offset_Admin_Submission_Queue_Tail_DoorBell 0x1000
+
+// Admin Cmd Set Figure 38 NVM Express 1.1
+#define DELETE_IO_SUBMISSION_QUEUE 0x00
+#define CREATE_IO_SUBMISSION_QUEUE 0x01
+#define GET_LOG_PAGE 0x02
+#define DELETE_IO_COMPLETION_QUEUE 0x04
+#define CREATE_IO_COMPLETION_QUEUE 0x05
+#define IDENTIFY 0x06
+#define ABORT 0x08
+#define SET_FEATURES 0x09
+#define GET_FEATURES 0x0A
+#define ASYNC_EVENT_REQUEST 0x0C
+#define NAMESPACE_MANAGEMENT 0x0D
+#define FIRMWARE_ACTIVATE 0x10
+#define FIRMWARE_IMAGE_DOWNLOAD 0x11
+#define NAMESPACE_ATTACHMENT 0x15
+#define FORMAT_NVM 0x80
+#define SECURITY_SEND 0x81
+#define SECURITY_RECEIVE 0x82
+
+//Figure 149: Opcodes for NVM Commands NVM Express 1.2
+#define NVME_FLUSH 0x00
+#define NVME_WRITE 0x01
+#define NVME_READ 0x02
+#define NVME_WRITE_UNCORRECTABLE 0x04
+#define NVME_COMPARE 0x05
+#define NVME_WRITE_ZEROES 0x08
+#define NVME_DATASET_MANAGEMENT 0x09
+#define NVME_RESERVATION_REGISTER 0x0D
+#define NVME_RESERVATION_REPORT 0x0E
+#define NVME_RESERVATION_ACQUIRE 0x11
+#define NVME_RESERVATION_RELEASE 0x15
+
+
+#define QUEUE_DOORBELL_OFFSET(QUEUE_NUM, TAIL_HEAD, DoorBellStride) \
+ (0x1000 + (((QUEUE_NUM * 2) + TAIL_HEAD) * (4 << DoorBellStride)))
+
+//MMIO Access
+
+#define MmAddress( BaseAddr, Register ) \
+ ((UINT64)(BaseAddr) + \
+ (UINTN)(Register) \
+ )
+#define Mm32Ptr( BaseAddr, Register ) \
+ ((volatile UINT32 *)MmAddress (BaseAddr, Register ))
+
+#define Mm16Ptr( BaseAddr, Register ) \
+ ((volatile UINT16 *)MmAddress (BaseAddr, Register ))
+
+#define Mm8Ptr( BaseAddr, Register ) \
+ ((volatile UINT8 *)MmAddress (BaseAddr, Register ))
+
+//Controller Generic Registers
+
+#define CONTROLLER_REG32( BaseAddr, Register ) \
+ (*Mm32Ptr ((BaseAddr), (Register)))
+
+#define CONTROLLER_REG16( BaseAddr, Register ) \
+ (*Mm16Ptr ((BaseAddr), (Register)))
+
+#define CONTROLLER_REG8( BaseAddr, Register ) \
+ (*Mm8Ptr ((BaseAddr), (Register)))
+
+#define CONTROLLER_WRITE_REG32( BaseAddr, Register, Data ) \
+ (CONTROLLER_REG32 ((BaseAddr), (Register))) = ((UINT32) (Data))
+
+#define CONTROLLER_WRITE_REG16( BaseAddr, Register, Data ) \
+ (CONTROLLER_REG16 ((BaseAddr), (Register))) = ((UINT16) (Data))
+
+#define CONTROLLER_WRITE_REG8( BaseAddr, Register, Data ) \
+ (CONTROLLER_REG8 ((BaseAddr), (Register))) = ((UINT8) (Data))
+
+#define CONTROLLER_REG8_OR( BaseAddr, Register, OrData) \
+ (CONTROLLER_REG8 ((BaseAddr), (Register))) |= ((UINT8) (OrData))
+
+#define CONTROLLER_REG16_OR( BaseAddr, Register, OrData) \
+ (CONTROLLER_REG16 ((BaseAddr), (Register))) |= ((UINT16) (OrData))
+
+#define CONTROLLER_REG32_OR( BaseAddr, Register, OrData) \
+ (CONTROLLER_REG32 ((BaseAddr), (Register))) = (CONTROLLER_REG32 ((BaseAddr), (Register))) | ((UINT32) (OrData))
+
+#define CONTROLLER_REG8_AND( BaseAddr, Register, AndData) \
+ (CONTROLLER_REG8 ((BaseAddr), (Register))) = (CONTROLLER_REG8 ((BaseAddr), (Register))) & ((UINT8) (AndData))
+
+#define CONTROLLER_REG16_AND( BaseAddr, Register, AndData) \
+ (CONTROLLER_REG16 ((BaseAddr), (Register))) &= ((UINT16) (AndData))
+
+#define CONTROLLER_REG32_AND( BaseAddr, Register, AndData) \
+ (CONTROLLER_REG32 ((BaseAddr), (Register))) = (CONTROLLER_REG32 ((BaseAddr), (Register))) & ((UINT32) (AndData))
+
+#define CONTROLLER_REG8_AND_OR( BaseAddr, Register, AndData, OrData) \
+ (CONTROLLER_REG8 ((BaseAddr), (Register)) = \
+ (((CONTROLLER_REG8 ((BaseAddr), (Register))) & ((UINT8) (AndData))) | ((UINT8) (OrData))))
+
+#define CONTROLLER_REG16_AND_OR( BaseAddr, Register, AndData, OrData) \
+ (CONTROLLER_REG16 ((BaseAddr), (Register)) = \
+ (((CONTROLLER_REG16 ((BaseAddr), (Register))) & ((UINT16) AndData)) | ((UINT16) (OrData))))
+
+#define CONTROLLER_REG32_AND_OR( BaseAddr, Register,AndData, OrData) \
+ (CONTROLLER_REG32 ((BaseAddr), (Register)) = \
+ (((CONTROLLER_REG32 ((BaseAddr), (Register))) & ((UINT32) (AndData))) | ((UINT32) (OrData))))
+
+#define AMI_NVME_CONTROLLER_PROTOCOL_GUID { 0xAFA4CF3F, 0xAF71, 0x4C30, 0xA4, 0xFB, 0x29, 0x10, 0xE7, 0x71, 0xF9, 0xB0 }
+#define AMI_NVME_PASS_THRU_PROTOCOL_GUID { 0x4B215191, 0x9A25, 0x43FD, 0x86, 0xB5, 0x74, 0xE7, 0xAF, 0x72, 0x33, 0x15 }
+#define AMI_NVME_LEGACY_PROTOCOL_GUID { 0xD4E79DAE, 0xAAFC, 0x4382, 0x95, 0x40, 0x3E, 0x3F, 0xA4, 0x2D, 0x42, 0x55 }
+#define AMI_SMM_NVME_COMMUNICATION_GUID { 0xEC2BD1FD, 0xE3B0, 0x429B, 0xAD, 0xDF, 0x96, 0x57, 0x93, 0x5A, 0x36, 0x84 }
+
+CHAR8*
+UnicodeStrToAsciiStr (
+ IN CONST CHAR16 *Source,
+ OUT CHAR8 *Destination
+);
+#pragma pack()
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeController.mak b/Core/EM/Nvme/NvmeController.mak
new file mode 100644
index 0000000..41f4d46
--- /dev/null
+++ b/Core/EM/Nvme/NvmeController.mak
@@ -0,0 +1,86 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/NVMe/NvmeController.mak 1 9/04/14 7:45a Anandakrishnanl $
+#
+# $Date: 9/04/14 7:45a $
+#
+# $Log: /Alaska/SOURCE/Modules/NVMe/NvmeController.mak $
+#
+# 1 9/04/14 7:45a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files] NvmeController.cif
+# NvmeController.sdl
+# NvmeController.mak
+# NvmeController.c
+# NvmeController.h
+#
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NVMe/NvmeController.mak $
+#
+# 1 9/04/14 7:45a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files] NvmeController.cif
+# NvmeController.sdl
+# NvmeController.mak
+# NvmeController.c
+# NvmeController.h
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: NvmeController.mak
+#
+# Description: Make file for NvmeController Lib
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : NvmeController
+
+NVMECONTROLLERLIB_OBJECTS=\
+$(BUILD_DIR)\$(NVME_DIR)\NvmeController.obj\
+
+$(NVMECONTROLLERLIB) : NvmeController
+
+NvmeController : $(BUILD_DIR)\NvmeController.mak NvmeControllerBin
+
+$(BUILD_DIR)\NvmeController.mak : $(NVME_DIR)\NvmeController.cif $(NVME_DIR)\NvmeController.mak $(BUILD_RULES)
+ $(CIF2MAK) $(NVME_DIR)\NvmeController.cif $(CIF2MAK_DEFAULTS)
+
+NvmeControllerBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NvmeController.mak all\
+ MAKEFILE=$(NVME_DIR)\NvmeController.mak\
+ "OBJECTS=$(NVMECONTROLLERLIB_OBJECTS)"\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=LIBRARY LIBRARY_NAME=$(NVMECONTROLLERLIB)
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/Nvme/NvmeController.sdl b/Core/EM/Nvme/NvmeController.sdl
new file mode 100644
index 0000000..49891ee
--- /dev/null
+++ b/Core/EM/Nvme/NvmeController.sdl
@@ -0,0 +1,31 @@
+TOKEN
+ Name = "NvmeController_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable NVMe Controller Library support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "NVME_DIR"
+End
+
+MODULE
+ Help = "Includes NvmeController.mak to Project"
+ File = "NvmeController.mak"
+End
+
+ELINK
+ Name = "NVMECONTROLLERLIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NvmeController.lib"
+ Parent = "NVMECONTROLLERLIB"
+ InvokeOrder = AfterParent
+End
+
+
diff --git a/Core/EM/Nvme/NvmeIncludes.h b/Core/EM/Nvme/NvmeIncludes.h
new file mode 100644
index 0000000..acb4464
--- /dev/null
+++ b/Core/EM/Nvme/NvmeIncludes.h
@@ -0,0 +1,120 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeIncludes.h 2 9/04/14 7:37a Anandakrishnanl $
+//
+// $Revision: 2 $
+//
+// $Date: 9/04/14 7:37a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeIncludes.h $
+//
+// 2 9/04/14 7:37a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+//
+// [Files]
+// Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeIncludes.h
+//
+// Description: Common header file for the Nvme Driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _NVME_INCLUDES_H_
+#define _NVME_INCLUDES_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Token.h>
+
+#include <Efi.h>
+#include <AmiLib.h>
+#include <Pci.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/DriverBinding.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/PDiskInfo.h>
+#include <Protocol/ComponentName2.h>
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmControl2.h>
+#include <Protocol/SmmCommunication.h>
+#include "NvmeInt13/NvmeInt13.h"
+
+
+#define LANGUAGE_CODE_ENGLISH "en-US"
+#define MSG_NVME_DP 23
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.c b/Core/EM/Nvme/NvmeInt13/NvmeInt13.c
new file mode 100644
index 0000000..b58c1f0
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.c
@@ -0,0 +1,474 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.c 2 2/02/16 1:31a Karthikar $
+//
+// $Revision: 2 $
+//
+// $Date: 2/02/16 1:31a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.c $
+//
+// 2 2/02/16 1:31a Karthikar
+// [TAG] EIP254245
+// [Category] Bug Fix
+// [Symptom] Static code analysis issues found in Aptio4 Nvme module
+// [RootCause] In for loop comma operator is used instead of && for
+// mutiple test conditions.
+// [Solution] Replaced comma operator with &&.
+// [Files] NvmeInt13.c
+//
+// 1 9/04/14 7:56a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeInt13.cif
+// NvmeInt13.c
+// NvmeInt13.h
+// NvmeInt13.sdl
+// NvmeInt13.mak
+// NvmeInt13.inf
+// NvmeInt13.dxs
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeInt13.c
+//
+// Description: Nvme Driver for Legacy Mode. It installs the Int13
+// support for the Nvme devices
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "Token.h"
+#include "AmiDxeLib.h"
+#include "NvmeInt13.h"
+#include <Protocol/ComponentName.h>
+#include <Protocol/LegacyBiosExt.h>
+#include <Protocol/LegacyBios.h>
+#include <Protocol/PciIo.h>
+#include <Protocol/BlockIo.h>
+
+EFI_LEGACY_BIOS_EXT_PROTOCOL *gBiosExtensions = NULL;
+NVME_INT13_DATA *gNvmeInt13BinData = NULL;
+AMI_NVME_LEGACY_PROTOCOL gNvmeLegacyProtocol;
+
+static EFI_GUID gAmiNvmeLegacyProtocolGuid = AMI_NVME_LEGACY_PROTOCOL_GUID;
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeInt13EntryPoint
+//
+// Description: NVMe INT13 driver entry point. Installs call back
+// notification on gAmiNvmeLegacyProtocolGuid installation.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeInt13EntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE NvmeInt13Handle=NULL;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = InitInt13RuntimeImage();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ gNvmeLegacyProtocol.AddNvmeLegacyDevice = NvmeInstallLegacyDevice;
+
+ Status = pBS->InstallProtocolInterface (
+ &NvmeInt13Handle,
+ &gAmiNvmeLegacyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gNvmeLegacyProtocol
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitInt13RuntimeImage
+//
+// Description: Initialization of data structures and placement of runtime
+//
+// Input:
+// NONE
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InitInt13RuntimeImage()
+{
+ EFI_STATUS Status;
+ VOID *Image;
+ UINTN ImageSize = 0;
+
+
+ //
+ // Get the NVMe INT13 runtime image
+ //
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosExtProtocolGuid, NULL, &gBiosExtensions);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = gBiosExtensions->GetEmbeddedRom(
+ CSM16_MODULEID, CSM16_VENDORID, CSM16_NVME_RT_DID, &Image, &ImageSize);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Do the necessary RT data initialization here using Image before it is shadowed
+ //..............................
+ {
+#pragma pack(push, 1)
+ // Update NVMe SMI information
+ typedef struct _NVME_SMM_RTS {
+ UINT8 MiscInfo;
+ UINT16 SmmAttr;
+ UINT32 SmmPort;
+ UINT32 SmmData;
+ } NVME_SMM_RTS;
+
+ static NVME_SMM_RTS NvmeSmmRt = {1, 0, SW_SMI_IO_ADDRESS, NVME_SWSMI};
+
+ *(NVME_SMM_RTS*)((UINTN)Image + ((NVME_INT13_DATA*)Image)->NvmeSmmDataOffset) = NvmeSmmRt;
+#pragma pack(pop)
+ }
+
+ // Copy image to shadow E000/F000 area
+ (UINTN)gNvmeInt13BinData = gBiosExtensions->CopyLegacyTable(Image, (UINT16)ImageSize, 0x10, 2);
+
+ TRACE((-1, "gNvmeInt13BinData : %lX\n", gNvmeInt13BinData));
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CreateDeviceName
+//
+// Description: This function retrieves NVMe device name, copies it into
+// lower memory and returns a pointer to the string
+//
+// Input:
+// UINT8 DevIndex,
+// UINT8 *DevNameStringSrc,
+// UINT16 *StringDestinationSegment,
+// UINT16 *StringDestinationOffset,
+// UINT16 *MfgStringDestinationSegment,
+// UINT16 *MfgStringDestinationOffset
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CreateDeviceName (
+ UINT8 DevIndex,
+ UINT8 *DevNameStringSrc,
+ UINT16 *StringDestinationSegment,
+ UINT16 *StringDestinationOffset,
+ UINT16 *MfgStringDestinationSegment,
+ UINT16 *MfgStringDestinationOffset
+)
+{
+ UINT8 *DevName = (gNvmeInt13BinData->NvmeMassI13Dev)[DevIndex].DeviceNameString;
+ UINT8 i;
+
+ //
+ // Copy the string, compact it on the way (no more that one ' ' in a row)
+ //
+ for (i=0; i<31 && *DevNameStringSrc != 0; i++, DevNameStringSrc++)
+ {
+ if ((*DevNameStringSrc == 0x20) && (*(DevNameStringSrc-1) == 0x20)) continue;
+ *DevName++ = *DevNameStringSrc; // DevNameStringSrc incremented unconditionally
+ }
+ *DevName = 0; // string terminator
+
+ DevName = (gNvmeInt13BinData->NvmeMassI13Dev)[DevIndex].DeviceNameString;
+
+ *StringDestinationSegment = (UINT16)(((UINTN)DevName & 0xf0000) >> 4);
+ *StringDestinationOffset = (UINT16)((UINTN)DevName & 0xffff);
+
+ *MfgStringDestinationSegment = (UINT16)(((UINTN)gNvmeInt13BinData->MfgGenericName & 0xf0000) >> 4);
+ *MfgStringDestinationOffset = (UINT16)((UINTN)gNvmeInt13BinData->MfgGenericName & 0xffff);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CreateBbsEntry
+//
+// Description: This function takes the device index within NVMEMASS_INT13_DEV
+// list and prepares BBS entry for this device
+//
+// Input:
+// UINT8 DevIndex,
+// IN NVME_LEGACY_MASS_DEVICE *NvmeLegacyMassDevice,
+// OUT BBS_TABLE *BbsEntry
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CreateBbsEntry (
+ UINT8 DevIndex,
+ IN NVME_LEGACY_MASS_DEVICE *NvmeLegacyMassDevice,
+ OUT BBS_TABLE *BbsEntry
+)
+{
+ EFI_STATUS Status;
+ UINT8 Handle;
+ UINT8 DevAndSysType;
+ UINT8 BaidDeviceType;
+ BBS_STATUS_FLAGS StatusFlags;
+
+ ASSERT(DevIndex < NVMEDEVS_MAX_ENTRIES);
+
+ if (gBiosExtensions == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ pBS->SetMem(BbsEntry, sizeof(BBS_TABLE), 0);
+
+ //
+ // Get the HC PCI location
+ //
+ BbsEntry->Bus = (UINT32)(NvmeLegacyMassDevice->PciBDF >> 8);
+ BbsEntry->Device = (UINT32)((NvmeLegacyMassDevice->PciBDF & 0xFF) >> 3);
+ BbsEntry->Function = (UINT32)(NvmeLegacyMassDevice->PciBDF & 7);
+
+ //
+ // Update class/subclass information
+ //
+ BbsEntry->Class = PCI_CLASS_MASS_STORAGE;
+ BbsEntry->SubClass = PCI_CLASS_MASS_STORAGE_SOLID_STATE;
+
+ StatusFlags.Enabled = 1; StatusFlags.MediaPresent = 1;
+ BbsEntry->StatusFlags = StatusFlags; // Enabled, Unknown media
+
+ //
+ // Copy the device name string into low memory at gLegacyMemoryAddress, and
+ // update the string pointer in BBS table entry
+ //
+ Status = CreateDeviceName(
+ DevIndex,
+ NvmeLegacyMassDevice->DevString,
+ &BbsEntry->DescStringSegment,
+ &BbsEntry->DescStringOffset,
+ &BbsEntry->MfgStringSegment,
+ &BbsEntry->MfgStringOffset
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ DevAndSysType = (SYSTYPE_ATA << 4)+DEVTYPE_SYS;
+ Handle = (UINT8)NvmeLegacyMassDevice->LogicalAddress;
+
+ switch (NvmeLegacyMassDevice->StorageType) {
+
+ case NVME_MASS_DEV_HDD:
+ BbsEntry->DeviceType = BBS_HARDDISK;
+ BaidDeviceType = BAID_TYPE_HDD;
+ Handle |= 0x80;
+ BbsEntry->BootHandlerSegment = (UINT16)((UINTN)gNvmeInt13BinData >> 4);
+ BbsEntry->BootHandlerOffset = gNvmeInt13BinData->BcvOffset + DevIndex*4;
+ break;
+
+ default:
+ BbsEntry->DeviceType = BBS_UNKNOWN;
+ }
+
+ BbsEntry->InitPerReserved = ((UINT32)BaidDeviceType<<24)
+ +((UINT32)Handle<<8)
+ +(UINT32)DevAndSysType;
+
+ *(UINTN*)(&BbsEntry->IBV1) = (UINTN)NvmeLegacyMassDevice->Handle;
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeInstallLegacyDevice
+//
+// Description: This API is called by NVMe bus driver. The device is added into CSM16
+// data area for legacy boot
+//
+// Input:
+// NVME_LEGACY_MASS_DEVICE *NvmeLegacyMassDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeInstallLegacyDevice (
+ NVME_LEGACY_MASS_DEVICE *NvmeLegacyMassDevice
+)
+{
+ BBS_TABLE BbsEntry;
+ EFI_STATUS Status;
+ UINT8 EntryNumber = 0xff;
+ UINT8 Index;
+ NVME_MASS_DEV_INFO *Device;
+ NVME_DEV_PCI_LOCATION *NvmePciDataOffset;
+
+ TRACE((-1, "Installing NVMe INT13 device %lx\n", NvmeLegacyMassDevice));
+
+ //
+ // See if device is already in the list, if yes - return error.
+ //
+ for (Index = 0; Index < NVMEDEVS_MAX_ENTRIES; Index++) {
+ if ((gNvmeInt13BinData->NvmeMassI13Dev)[Index].Handle == (UINT8)NvmeLegacyMassDevice->LogicalAddress) {
+ ASSERT(FALSE); // ERROR: Device already exists
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Look for an empty slot in BcvLookupTable
+ //
+ for (Index=0; Index<NVMEDEVS_MAX_ENTRIES; Index++) {
+ if ((gNvmeInt13BinData->NvmeMassI13Dev)[Index].Handle == 0) {
+ break;
+ }
+ }
+
+ ASSERT(Index<NVMEDEVS_MAX_ENTRIES);
+
+ if (Index==NVMEDEVS_MAX_ENTRIES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = gBiosExtensions->UnlockShadow(0, 0, 0, 0);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CreateBbsEntry(Index, NvmeLegacyMassDevice, &BbsEntry);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBiosExtensions->InsertBbsEntryAt(gBiosExtensions,
+ &BbsEntry,
+ &EntryNumber);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Entry has been successfully added, update the lookup table
+ //
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].Handle = (UINT8)NvmeLegacyMassDevice->LogicalAddress;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].BbsEntryNo = EntryNumber;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].DevBaidType = (UINT8)(BbsEntry.InitPerReserved>>24);
+
+ //
+ // Update device geometry related information
+ //
+ Device = (NVME_MASS_DEV_INFO*)NvmeLegacyMassDevice->DevInfo;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].NumHeads = Device->bNonLBAHeads;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].LBANumHeads = Device->bHeads;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].NumCylinders = Device->wNonLBACylinders;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].LBANumCyls = Device->wCylinders;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].NumSectors = Device->bNonLBASectors;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].LBANumSectors = Device->bSectors;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].BytesPerSector = Device->wBlockSize;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].LastLBA = Device->dMaxLba;
+ (gNvmeInt13BinData->NvmeMassI13Dev)[Index].BpbMediaDesc = 0;
+
+ // Update PCI Bus#
+ NvmePciDataOffset = (NVME_DEV_PCI_LOCATION *)((UINTN)gNvmeInt13BinData + gNvmeInt13BinData->NvmePciDataOffset);
+ NvmePciDataOffset[Index].Handle = (UINT8)NvmeLegacyMassDevice->LogicalAddress;
+ NvmePciDataOffset[Index].PciBDF = NvmeLegacyMassDevice->PciBDF;
+
+ Status = gBiosExtensions->LockShadow(0, 0);
+ ASSERT_EFI_ERROR(Status);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.cif b/Core/EM/Nvme/NvmeInt13/NvmeInt13.cif
new file mode 100644
index 0000000..e2c2bb6
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Nvme Int13"
+ category = ModulePart
+ LocalRoot = "Core\EM\Nvme\NvmeInt13\"
+ RefName = "NVMEINT13"
+
+[files]
+"NvmeInt13.c"
+"NvmeInt13.h"
+"NvmeInt13.sdl"
+"NvmeInt13.mak"
+"NvmeInt13.inf"
+"NvmeInt13.dxs"
+[parts]
+"NVME_I13_BINARY"
+<endComponent>
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.dxs b/Core/EM/Nvme/NvmeInt13/NvmeInt13.dxs
new file mode 100644
index 0000000..ae03d50
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.dxs
@@ -0,0 +1,71 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.dxs 1 9/04/14 7:56a Anandakrishnanl $
+//
+// $Revision: 1 $
+//
+// $Date: 9/04/14 7:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.dxs $
+//
+// 1 9/04/14 7:56a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeInt13.cif
+// NvmeInt13.c
+// NvmeInt13.h
+// NvmeInt13.sdl
+// NvmeInt13.mak
+// NvmeInt13.inf
+// NvmeInt13.dxs
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeInt13.dxs
+//
+// Description: This file is the dependency file for the NvmeInt13 driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "token.h"
+#ifdef CSM_SUPPORT
+#include <Protocol\LegacyBiosExt.h>
+#include <Protocol/LegacyBios.h>
+#endif
+
+DEPENDENCY_START
+#if CSM_SUPPORT
+ EFI_LEGACY_BIOS_EXT_PROTOCOL_GUID AND
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.h b/Core/EM/Nvme/NvmeInt13/NvmeInt13.h
new file mode 100644
index 0000000..c8d48a0
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.h
@@ -0,0 +1,161 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.h 1 9/04/14 7:56a Anandakrishnanl $
+//
+// $Revision: 1 $
+//
+// $Date: 9/04/14 7:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.h $
+//
+// 1 9/04/14 7:56a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeInt13.cif
+// NvmeInt13.c
+// NvmeInt13.h
+// NvmeInt13.sdl
+// NvmeInt13.mak
+// NvmeInt13.inf
+// NvmeInt13.dxs
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeInt13.h
+//
+// Description: Definitions and structures for NVMe INT13
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef __NVMEI13_H__
+#define __NVMEI13_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Protocol/AmiNvmeLegacy.h>
+#include "NvmeBus.h"
+
+#define BAID_TYPE_HDD 1
+#define BAID_TYPE_RMD_HDD 2
+#define BAID_TYPE_CDROM 3
+#define BAID_TYPE_RMD_FDD 4
+#define BAID_TYPE_FDD 5
+
+#define CSM16_NVME_RT_DID 5
+
+#define SYSTYPE_ATA 0
+#define DEVTYPE_SYS 1
+
+// Values for Mass Storage Device type
+//-------------------------------------
+#define NVME_MASS_DEV_HDD 1
+#define MAX_NVME_DEVICES 16
+#define NVMEDEVS_MAX_ENTRIES 8
+
+#pragma pack(1)
+
+typedef struct _NVME_MASS_DEV_INFO{
+ UINT16 wBlockSize;
+ UINT64 dMaxLba;
+ UINT8 bHeads;
+ UINT8 bSectors;
+ UINT16 wCylinders;
+ UINT8 bNonLBAHeads;
+ UINT8 bNonLBASectors;
+ UINT16 wNonLBACylinders;
+} NVME_MASS_DEV_INFO;
+
+struct _NVME_LEGACY_MASS_DEVICE {
+ VOID *DevInfo;
+ UINT16 LogicalAddress;
+ EFI_HANDLE Handle;
+ UINT16 PciBDF;
+ UINT8 *DevString;
+ UINT8 StorageType;
+};
+
+typedef struct {
+ UINT8 Handle;
+ UINT16 PciBDF;
+} NVME_DEV_PCI_LOCATION;
+
+
+typedef struct {
+ UINT8 Handle;
+ UINT8 BbsEntryNo;
+ UINT8 DevBaidType;
+ UINT8 NumHeads;
+ UINT8 LBANumHeads;
+ UINT16 NumCylinders;
+ UINT16 LBANumCyls;
+ UINT8 NumSectors;
+ UINT8 LBANumSectors;
+ UINT16 BytesPerSector;
+ UINT8 MediaType;
+ UINT64 LastLBA;
+ UINT8 BpbMediaDesc;
+ UINT8 DeviceNameString[32];
+} NVMEMASS_INT13_DEV;
+
+//
+// The following data structure is located in NvmeI13.BIN
+//
+typedef struct {
+ NVMEMASS_INT13_DEV NvmeMassI13Dev[NVMEDEVS_MAX_ENTRIES];
+ UINT8 MfgGenericName[13]; // "NVME Storage", 0
+ UINT16 BcvOffset;
+ UINT16 NvmeSmmDataOffset;
+ UINT16 NvmePciDataOffset;
+} NVME_INT13_DATA;
+
+#pragma pack()
+
+EFI_STATUS
+NvmeInstallLegacyDevice (
+ NVME_LEGACY_MASS_DEVICE *NvmeLegacyMassDevice
+);
+
+EFI_STATUS
+InitInt13RuntimeImage();
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.inf b/Core/EM/Nvme/NvmeInt13/NvmeInt13.inf
new file mode 100644
index 0000000..3a75d3d
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.inf
@@ -0,0 +1,5 @@
+[MODULE]
+ModuleID = 1
+VendorID = 0
+DeviceID = 5
+File = Addon\NvmeI13.BIN
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.mak b/Core/EM/Nvme/NvmeInt13/NvmeInt13.mak
new file mode 100644
index 0000000..54c9372
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.mak
@@ -0,0 +1,84 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.mak 1 9/04/14 7:56a Anandakrishnanl $
+#
+# $Revision: 1 $
+#
+# $Date: 9/04/14 7:56a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NVMe/NvmeInt13/NvmeInt13.mak $
+#
+# 1 9/04/14 7:56a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files] NvmeInt13.cif
+# NvmeInt13.c
+# NvmeInt13.h
+# NvmeInt13.sdl
+# NvmeInt13.mak
+# NvmeInt13.inf
+# NvmeInt13.dxs
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: NvmeInt13.mak
+#
+# Description: Make file for NvmeInt13
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all: NVMEINT13
+
+$(BUILD_DIR)\NvmeInt13.mak: $(NVME_INT13_DIR)\NvmeInt13.cif $(NVME_INT13_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(NVME_INT13_DIR)\NvmeInt13.cif
+
+NVMEINT13: $(BUILD_DIR)\NvmeInt13.mak NVMEINT13BIN
+
+NVME_INT13_INCLUDES=\
+ /I$(NVME_DIR)\
+
+NVME_OBJECTS = \
+$(BUILD_DIR)\$(NVME_INT13_DIR)\NvmeInt13.obj \
+
+NVMEINT13BIN: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NvmeInt13.mak all\
+ GUID=C9A6DE36-FDFF-4FAF-8343-85D9E3470F43\
+ "OBJECTS=$(NVME_OBJECTS)"\
+ "MY_INCLUDES=$(NVME_INT13_INCLUDES)"\
+ ENTRY_POINT=NvmeInt13EntryPoint\
+ TYPE=BS_DRIVER\
+ COMPRESS=1\
+ DEPEX1=$(NVME_INT13_DIR)\NvmeInt13.dxs \
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Nvme/NvmeInt13/NvmeInt13.sdl b/Core/EM/Nvme/NvmeInt13/NvmeInt13.sdl
new file mode 100644
index 0000000..b4c6cb1
--- /dev/null
+++ b/Core/EM/Nvme/NvmeInt13/NvmeInt13.sdl
@@ -0,0 +1,48 @@
+TOKEN
+ Name = "NVMEINT13_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Sdio Int13 support in the project."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "NVME_INT13_DIR"
+ Path = "Core\EM\Nvme\NvmeInt13"
+End
+
+MODULE
+ Help = "Includes NvmeInt13.mak"
+ File = "NvmeInt13.mak"
+End
+
+TOKEN
+ Name = "NVME_SWSMI"
+ Value = "0x42"
+ Help = "Data to be written to SW SMI port to invoke NVME SW SMI handler."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NvmeInt13.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+
+TOKEN
+ Name = "NVMEI13_BIN"
+ Value = "addon\NvmeI13.bin"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+ELINK
+ Name = "$(NVME_INT13_DIR)\NvmeInt13.inf"
+ Parent = "CSM_CUSTOM_INFS"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/Nvme/NvmePassthru.c b/Core/EM/Nvme/NvmePassthru.c
new file mode 100644
index 0000000..837de1d
--- /dev/null
+++ b/Core/EM/Nvme/NvmePassthru.c
@@ -0,0 +1,619 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmePassthru.c 1 5/14/15 2:36a Karthikar $
+//
+// $Revision: 1 $
+//
+// $Date: 5/14/15 2:36a $
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmePassthru.c
+//
+// Description: Contain Nvme Express passthru protocol APIs definition
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "NvmeIncludes.h"
+#include "NvmeController.h"
+#include "NvmeBus.h"
+#include "Protocol/AmiNvmeController.h"
+#include "NvmePassthru.h"
+#include <Protocol\DevicePath.h>
+#include <Protocol\BlockIo.h>
+
+// Global Declaration
+EFI_BOOT_SERVICES *pBS;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetActiveNameSpace
+//
+// Description:
+// Routine to get the Active NameSpace
+//
+// Input:
+// IN AMI_NVME_CONTROLLER_PROTOCOL *NvmeController
+// IN UINT32 NamespaceId
+// Output:
+// ACTIVE_NAMESPACE_DATA pointer for the NamespaceId
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+ACTIVE_NAMESPACE_DATA*
+GetActiveNameSpace (
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController,
+ UINT32 NamespaceId
+)
+{
+ LIST_ENTRY *LinkData;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = NULL;
+
+ if(!NvmeController) {
+ return NULL;
+ }
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink;
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ ActiveNameSpace = _CR(LinkData, ACTIVE_NAMESPACE_DATA, Link);
+
+ if(ActiveNameSpace->ActiveNameSpaceID == NamespaceId) {
+ return ActiveNameSpace;
+ }
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: NvmePassThru
+//
+// Description:
+// Sends an NVM Express Command Packet to an NVM Express controller or namespace
+//
+// Input:
+// IN This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance
+// IN NamespaceId A 32 bit namespace ID as defined in the NVMe specification
+// to which the NVM Express Command Packet will be sent.
+// IN Packet A pointer to the NVM Express Command Packet to send to
+// the NVMe namespace specified by NamespaceId.
+// IN Event Event to be signaled when the NVM Express Command Packet completes
+// and non-blocking I/O is supported
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+NvmePassThru (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet,
+ IN EFI_EVENT Event
+)
+{
+ EFI_STATUS Status;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = NULL;
+ NVME_COMMAND_WRAPPER *NvmeCmdWrapper = NULL;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ UINT32 AlignmentBoundry;
+ VOID *BufferUnMap = NULL;
+ COMPLETION_QUEUE_ENTRY *NvmeCompletionData = NULL;
+ UINT8 NvmeOpcode;
+ UINT64 LBA;
+
+ if( !This || !Packet || !Packet->NvmeCmd ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NvmeOpcode = Packet->NvmeCmd->Cdw0.OpCode;
+
+ // Return if QueueType is invalid
+ if (Packet->QueueType != NVME_ADMIN_SUBMISSION_QUEUE && Packet->QueueType != NVME_IO_SUBMISSION_QUEUE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check Transfer buffer is NULL, if not,Check its memory is properly alligned or not
+ if( Packet->TransferBuffer && ( This->Mode->IoAlign > 1 ) ) {
+
+ // Should be align in 2's power
+ AlignmentBoundry = 1 << This->Mode->IoAlign;
+ //
+ //Get what is the number in 2 to the power Mode->IoAlign
+ //
+ if((0 != ((UINTN)((UINTN)(Packet->TransferBuffer) % AlignmentBoundry) ) ||
+ (0 != ((UINTN)( Packet->TransferLength % AlignmentBoundry))) )) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ NvmeController = NVME_CONTROLLER_PROTOCOL_FROM_THIS(This);
+
+ if(!Packet->NvmeCompletion) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ NvmeCompletionData = (COMPLETION_QUEUE_ENTRY*)Packet->NvmeCompletion;
+
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(NVME_COMMAND_WRAPPER),
+ (VOID**)&NvmeCmdWrapper
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ // Clear memory
+ pBS->SetMem(NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER), 0);
+
+ // Fill Common values of command
+ NvmeCmdWrapper->NvmCmd.CMD0.Opcode = NvmeOpcode;
+ (UINT8)NvmeCmdWrapper->NvmCmd.CMD0.FusedOperation = Packet->NvmeCmd->Cdw0.FusedOperation;
+ NvmeCmdWrapper->NvmCmd.CMD0.CommandIdentifier = Packet->QueueType? NvmeController->CommandIdentifierQueue1 : NvmeController->CommandIdentifierAdmin;
+ NvmeCmdWrapper->NvmCmd.NSID = Packet->NvmeCmd->Nsid;
+ NvmeCmdWrapper->NvmCmd.MPTR = 0;
+ NvmeCmdWrapper->AdminOrNVMCmdSet = Packet->QueueType ? FALSE : TRUE;
+ NvmeCmdWrapper->SQIdentifier = Packet->QueueType; // Queue 0 for Admin cmds,1 for I/O command
+ NvmeCmdWrapper->CmdTimeOut = (UINT32)Packet->CommandTimeout;
+
+ if(Packet->NvmeCmd->Flags & CDW10_VALID) {
+ NvmeCmdWrapper->NvmCmd.CDW10 = Packet->NvmeCmd->Cdw10;
+ }
+ if(Packet->NvmeCmd->Flags & CDW11_VALID) {
+ NvmeCmdWrapper->NvmCmd.CDW11 = Packet->NvmeCmd->Cdw11;
+ }
+ if(Packet->NvmeCmd->Flags & CDW12_VALID) {
+ NvmeCmdWrapper->NvmCmd.CDW12 = Packet->NvmeCmd->Cdw12;
+ }
+ if(Packet->NvmeCmd->Flags & CDW13_VALID) {
+ NvmeCmdWrapper->NvmCmd.CDW13 = Packet->NvmeCmd->Cdw13;
+ }
+ if(Packet->NvmeCmd->Flags & CDW14_VALID) {
+ NvmeCmdWrapper->NvmCmd.CDW14 = Packet->NvmeCmd->Cdw14;
+ }
+ if(Packet->NvmeCmd->Flags & CDW15_VALID) {
+ NvmeCmdWrapper->NvmCmd.CDW15 = Packet->NvmeCmd->Cdw15;
+ }
+
+ // if QueueType is 0, Admin Command
+ // if QueueType is 1, I/O Command
+ if ( Packet->QueueType == NVME_ADMIN_SUBMISSION_QUEUE ) {
+
+ Status = EFI_SUCCESS;
+ switch(NvmeOpcode)
+ {
+ case DELETE_IO_SUBMISSION_QUEUE:
+ case CREATE_IO_SUBMISSION_QUEUE:
+ case DELETE_IO_COMPLETION_QUEUE:
+ case CREATE_IO_COMPLETION_QUEUE:
+ case ABORT:
+ case ASYNC_EVENT_REQUEST:
+ Status = EFI_UNSUPPORTED;
+ break;
+ case IDENTIFY:
+
+ if( !( (Packet->NvmeCmd->Flags & CDW10_VALID) && Packet->TransferBuffer ) ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto PassthruErrorExit;
+ }
+
+ if( Packet->TransferLength < sizeof(IDENTIFY_CONTROLLER_DATA) ) {
+ Status = EFI_BAD_BUFFER_SIZE;
+ goto PassthruErrorExit;
+ }
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)Packet->TransferBuffer;
+
+ // If PRP1 isn't aligned on MemoryPageSize, then PRP2 will also be used.
+ NvmeCmdWrapper->NvmCmd.PRP2 = ((UINT64)Packet->TransferBuffer & ~((UINT64)NvmeController->MemoryPageSize-1)) +
+ NvmeController->MemoryPageSize;
+ break;
+
+ case GET_FEATURES:
+ case SET_FEATURES:
+ if( (Packet->NvmeCmd->Flags & (CDW10_VALID | CDW11_VALID)) != (CDW10_VALID | CDW11_VALID)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto PassthruErrorExit;
+ }
+ if( Packet->TransferBuffer ) {
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)Packet->TransferBuffer;
+
+ // If PRP1 isn't aligned on MemoryPageSize, then PRP2 will also be used.
+ NvmeCmdWrapper->NvmCmd.PRP2 = ((UINT64)Packet->TransferBuffer & ~((UINT64)NvmeController->MemoryPageSize-1)) +
+ NvmeController->MemoryPageSize;
+ }
+ break;
+
+ case GET_LOG_PAGE:
+ if( !( (Packet->NvmeCmd->Flags & CDW10_VALID) && Packet->TransferBuffer) ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto PassthruErrorExit;
+ }
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)Packet->TransferBuffer;
+
+ // If PRP1 isn't aligned on MemoryPageSize, then PRP2 will also be used.
+ NvmeCmdWrapper->NvmCmd.PRP2 = ((UINT64)Packet->TransferBuffer & ~((UINT64)NvmeController->MemoryPageSize-1)) +
+ NvmeController->MemoryPageSize;
+ break;
+
+ case FORMAT_NVM:
+ if( !(Packet->NvmeCmd->Flags & CDW10_VALID) ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto PassthruErrorExit;
+ }
+ break;
+
+ case SECURITY_SEND:
+ case SECURITY_RECEIVE:
+ if( ( (Packet->NvmeCmd->Flags & (CDW10_VALID | CDW11_VALID)) != (CDW10_VALID | CDW11_VALID)) ) {
+ Status = EFI_INVALID_PARAMETER;
+ goto PassthruErrorExit;
+ }
+
+ NvmeCmdWrapper->NvmCmd.PRP1 = (UINT64)Packet->TransferBuffer;
+
+ // If PRP1 isn't aligned on MemoryPageSize, then PRP2 will also be used.
+ NvmeCmdWrapper->NvmCmd.PRP2 = ((UINT64)Packet->TransferBuffer & ~((UINT64)NvmeController->MemoryPageSize-1)) +
+ NvmeController->MemoryPageSize;
+ break;
+
+ case FIRMWARE_ACTIVATE:
+ case FIRMWARE_IMAGE_DOWNLOAD:
+ default:
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ if( Status != EFI_UNSUPPORTED ) {
+ // Send Nvme Command
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, (COMPLETION_QUEUE_ENTRY*)NvmeCompletionData);
+ }
+ } else { // Send NVM command to Valid Namespace ID
+
+ Status = EFI_INVALID_PARAMETER;
+ switch(NvmeOpcode)
+ {
+ case NVME_READ:
+ case NVME_WRITE:
+ case NVME_COMPARE:
+
+ // LBA value is passed through Command Dword 10 & 11, return error if either CDW10 or CDW11 is invalid
+ if( ((Packet->NvmeCmd->Flags & (CDW10_VALID | CDW11_VALID)) != (CDW10_VALID | CDW11_VALID)) ) {
+ break;
+ }
+
+ LBA = Packet->NvmeCmd->Cdw11;
+ LBA = Shl64(LBA, 32) | ( (UINT64)Packet->NvmeCmd->Cdw10 & 0x0FFFFFFFF );
+
+ ActiveNameSpace = GetActiveNameSpace( NvmeController, Packet->NvmeCmd->Nsid );
+
+ if( !ActiveNameSpace ) {
+ goto PassthruErrorExit;
+ }
+ Status = NvmeReadWriteBlocks ( ActiveNameSpace,
+ 0, // MediaId = 0
+ LBA,
+ (UINT64)Packet->TransferLength, // BufferSize,
+ (VOID*)(Packet->TransferBuffer), // Buffer,
+ (COMPLETION_QUEUE_ENTRY*)NvmeCompletionData,
+ NvmeOpcode // ReadWriteOpCode
+ );
+ break;
+
+ case NVME_WRITE_ZEROES:
+ // LBA value is passed through Command Dword 10,11,12,13,14 and 15, return error if any one of the
+ // Command Dword is invalid
+ if( (Packet->NvmeCmd->Flags & (CDW14_VALID|CDW15_VALID)) != (CDW14_VALID|CDW15_VALID)) {
+ break;
+ }
+
+ case NVME_WRITE_UNCORRECTABLE:
+ // LBA value is passed through Command Dword 10,11 and 12, return error if any one of the
+ // Command Dword is invalid
+ if( !(Packet->NvmeCmd->Flags & CDW12_VALID)) {
+ break;
+ }
+ case NVME_DATASET_MANAGEMENT:
+ // LBA value is passed through Command Dword 10,11 return error if any one of the
+ // Command Dword is invalid
+ if( (Packet->NvmeCmd->Flags & (CDW10_VALID |CDW11_VALID)) != (CDW10_VALID |CDW11_VALID)) {
+ break;
+ }
+ case NVME_FLUSH:
+ // Send Nvme Command
+ Status = ExecuteNvmeCmd (NvmeController, NvmeCmdWrapper, (COMPLETION_QUEUE_ENTRY*)NvmeCompletionData);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ }
+PassthruErrorExit:
+
+ if( NvmeCmdWrapper ) {
+ pBS->FreePool ( NvmeCmdWrapper );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetNextNamespace
+//
+// Description:
+// API to get next valid NameSpace ID of the Nvme Device
+//
+// Input:
+// IN This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance
+// IN NamespaceId A pointer to a valid Namespace ID on this NVM Express controller
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetNextNamespace(
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT32 *NamespaceId
+)
+{
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData;
+ LIST_ENTRY *LinkData;
+ BOOLEAN ReturnNextNameSpaceId = FALSE;
+
+ if(!NamespaceId || !This) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if( 0xFFFFFFFF == *NamespaceId) {
+ ReturnNextNameSpaceId = TRUE;
+ }
+
+ NvmeController = NVME_CONTROLLER_PROTOCOL_FROM_THIS(This);
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink;
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ ActiveNameSpaceData = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+
+ if( TRUE == ReturnNextNameSpaceId) {
+ *NamespaceId = ActiveNameSpaceData->ActiveNameSpaceID;
+ return EFI_SUCCESS;
+ }
+
+ if(ActiveNameSpaceData->ActiveNameSpaceID == *NamespaceId) {
+ ReturnNextNameSpaceId = TRUE;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SearchDevicePathNode
+//
+// Description:
+// Routine Searches device path by specific Type and SubType
+//
+// Input:
+// IN DevicePath A pointer to the device path protocol
+// IN Type Device path Node Type
+// IN SubType Device path node subtype
+//
+// Output:
+// EFI_DEVICE_PATH_PROTOCOL*
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_DEVICE_PATH_PROTOCOL*
+SearchDevicePathNode (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINT8 Type,
+ IN UINT8 SubType
+)
+{
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ while (!isEndNode (DevicePath)) {
+ if ((DevicePathType (DevicePath) == Type) && (DevicePathSubType (DevicePath) == SubType)) {
+ return DevicePath;
+ }
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: BuildDevicePath
+//
+// Description:
+// Used to allocate and build a device path node for an NVM Express namespace
+// on an NVM Express controller
+//
+// Input:
+// IN This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance
+// IN NamespaceId The NVM Express namespace ID for which a device path node is
+// to be allocated and built
+// IN DevicePath A pointer to a single device path node that describes the
+// NVM Express namespace specified by NamespaceId.
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+BuildDevicePath (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+)
+{
+ EFI_STATUS Status;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ LIST_ENTRY *LinkData;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpaceData;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol;
+ NVME_DEVICE_PATH *NvmeDevicePathNode = NULL;
+
+ if( !DevicePath || !This ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(NVME_DEVICE_PATH),
+ (void**)DevicePath );
+ if(EFI_ERROR(Status)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NvmeController = NVME_CONTROLLER_PROTOCOL_FROM_THIS(This);
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink;
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ ActiveNameSpaceData = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+
+ if(ActiveNameSpaceData->ActiveNameSpaceID == NamespaceId) {
+
+ Status = pBS->HandleProtocol (
+ ActiveNameSpaceData->NvmeDeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePathProtocol );
+
+ NvmeDevicePathNode = (NVME_DEVICE_PATH*)SearchDevicePathNode ( DevicePathProtocol, MESSAGING_DEVICE_PATH, MSG_NVME_DP);
+
+ pBS->CopyMem( (UINT8*)*DevicePath, (UINT8*)NvmeDevicePathNode, sizeof(NVME_DEVICE_PATH) );
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetNamespace
+//
+// Description:
+// Used to translate a device path node to a Namespace ID
+//
+//
+// Input:
+// IN This A pointer to the EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL instance
+// IN DevicePath A pointer to the device path node that describes an NVM
+// Express namespace on the NVM Express controller.
+// IN NamespaceId The NVM Express namespace ID contained in the device path node
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetNamespace (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT UINT32 *NamespaceId
+)
+{
+ UINT16 DevicePathLength = 0;
+
+ if(!DevicePath || !This || !NamespaceId) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DevicePathLength = (DevicePath)->Length[0] | (DevicePath)->Length[1] << 8;
+
+ if ((DevicePath->Type != MESSAGING_DEVICE_PATH) ||
+ (DevicePath->SubType != MSG_NVME_DP) ||
+ (DevicePathLength != sizeof(NVME_DEVICE_PATH))) {
+ return EFI_UNSUPPORTED;
+ }
+
+ *NamespaceId = ((NVME_DEVICE_PATH* )DevicePath)->Nsid;
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmePassthru.h b/Core/EM/Nvme/NvmePassthru.h
new file mode 100644
index 0000000..2f61000
--- /dev/null
+++ b/Core/EM/Nvme/NvmePassthru.h
@@ -0,0 +1,107 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmePassthru.h 1 5/14/15 2:36a Karthikar $
+//
+// $Revision: 1 $
+//
+// $Date: 5/14/15 2:36a $
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmePassthru.h
+//
+// Description: Header file for NvmePassthru.h file
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+#ifndef __NVM_PASS_THRU_H__
+#define __NVM_PASS_THRU_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include "Protocol/AmiNvmeController.h"
+#include "Protocol/NvmExpressPassThru.h"
+#include "EdkIICommon.h"
+
+#define LIST_ENTRY EFI_LIST_ENTRY
+
+
+#define NVME_ADMIN_SUBMISSION_QUEUE 0x00
+#define NVME_IO_SUBMISSION_QUEUE 0x01
+
+#define NVME_CONTROLLER_PROTOCOL_FROM_THIS(NvmePassthruProtocol) \
+ ((_CR( NvmePassthruProtocol ,NVM_EXPRESS_PASS_THRU_INSTANCE, EfiNvmExpressPassThru))->NvmeControllerProtocol)
+
+typedef
+struct _NVM_EXPRESS_PASS_THRU_INSTANCE {
+ EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL EfiNvmExpressPassThru; // Instance of EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeControllerProtocol;
+ EFI_HANDLE ControllerHandle;
+} NVM_EXPRESS_PASS_THRU_INSTANCE;
+
+EFI_STATUS
+NvmePassThru (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN OUT EFI_NVM_EXPRESS_PASS_THRU_COMMAND_PACKET *Packet,
+ IN EFI_EVENT Event
+);
+
+EFI_STATUS
+GetNextNamespace(
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN OUT UINT32 *NamespaceId
+);
+
+EFI_STATUS
+BuildDevicePath (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN UINT32 NamespaceId,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath
+);
+
+EFI_STATUS
+GetNamespace (
+ IN EFI_NVM_EXPRESS_PASS_THRU_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT UINT32 *NamespaceId
+);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // __NVM_PASS_THRU_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/EM/Nvme/NvmeSetup.c b/Core/EM/Nvme/NvmeSetup.c
new file mode 100644
index 0000000..e1ddd13
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSetup.c
@@ -0,0 +1,473 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSetup.c 5 5/19/15 5:08a Ksudarsanan $
+//
+// $Revision: 5 $
+//
+// $Date: 5/19/15 5:08a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSetup.c $
+//
+// 5 5/19/15 5:08a Ksudarsanan
+// [TAG] EIP218818
+// [Category] Improvement
+// [Description] Aptio 4.x: When NVMe device is not connect then in BIOS
+// Setup should display "No Nvme device found"
+// [Files] Nvme.sd, Nvme.uni, NvmeSetup.c
+//
+// 4 9/04/14 7:37a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+//
+// [Files]
+// Nvme.cif
+// Nvme.mak
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// [NvmeControllerLib]
+// [NvmeSmm]
+// [NVMEINT13]
+// [NvmeProtocol]
+//
+// 2 7/02/14 8:31a Anandakrishnanl
+// [TAG] EIP175772
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AMI Nvme Driver setup tries to display the devices detected
+// by UEFI option rom
+// [RootCause] Display to Nvme devices information did not chack for
+// ontroller handle to confirm if gAmiNvmeControllerProtocol is present
+// [Solution] Added checking in the controller handle to confirm if
+// gAmiNvmeControllerProtocol is present or not.
+// [Files] NvmeSetup.c
+//
+// 1 6/20/14 6:27a Anandakrishnanl
+// [TAG] EIP172958
+// [Category] New Feature
+// [Description] Nvme Driver Intial Checkin
+// [Files] Nvme.cif
+// Nvme.sdl
+// Nvme.mak
+// Nvme.sd
+// Nvme.uni
+// Nvme.chm
+// NvmeSetup.c
+// NvmeBus.c
+// NvmeController.c
+// NvmeComponentName.c
+// NvmeIncludes.h
+// NvmeBus.h
+// NvmeController.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSetup.c
+//
+// Description: Display the Nvme Controller and device information in the Setup
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include <Protocol\DevicePath.h>
+#include <Token.h>
+#include "NvmeIncludes.h"
+#include "NvmeBus.h"
+
+#define MSG_NVME_DP 23
+#define DRIVEMAXCOUNT 4
+
+extern EFI_RUNTIME_SERVICES *pRS;
+
+typedef struct {
+ STRING_REF ControllerString;
+ STRING_REF DeviceString;
+} NVME_SETUP_STRUC;
+
+NVME_SETUP_STRUC NVMeSetupStruc[] = {
+ {STRING_TOKEN(STR_NVME0_CONTROLLER), STRING_TOKEN(STR_NVME0_NAME)},
+ {STRING_TOKEN(STR_NVME1_CONTROLLER), STRING_TOKEN(STR_NVME1_NAME)},
+ {STRING_TOKEN(STR_NVME2_CONTROLLER), STRING_TOKEN(STR_NVME2_NAME)},
+ {STRING_TOKEN(STR_NVME3_CONTROLLER), STRING_TOKEN(STR_NVME3_NAME)},
+};
+
+static EFI_GUID gAmiNvmeControllerProtocolGuid = AMI_NVME_CONTROLLER_PROTOCOL_GUID;
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: UnicodeStrToAsciiStr
+//
+// Description: This function converts the content of the Unicode string Source
+// to the ASCII string Destination by copying the lower 8 bits of
+// each Unicode character and returns Destination
+//
+// Input:
+// Source A pointer to a Null-terminated Unicode string.
+// Destination A pointer to a Null-terminated ASCII string.
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+CHAR8*
+UnicodeStrToAsciiStr (
+ IN CONST CHAR16 *Source,
+ OUT CHAR8 *Destination
+ )
+{
+ CHAR8 *ReturnValue;
+ UINTN TempReturnValue;
+ UINTN TempSource;
+
+ ASSERT (Destination != NULL);
+
+ //
+ // ASSERT if Source is long than PcdMaximumUnicodeStringLength.
+ // Length tests are performed inside StrLen().
+ //
+ TempSource = (Wcslen ((CHAR16 *)Source) + 1) * sizeof (*Source);
+ ASSERT (TempSource != 0);
+
+ //
+ // Source and Destination should not overlap
+ //
+ ASSERT ((UINTN) ((CHAR16 *) Destination - Source) > Wcslen ((CHAR16 *)Source));
+ ASSERT ((UINTN) ((CHAR8 *) Source - Destination) > Wcslen ((CHAR16 *)Source));
+
+
+ ReturnValue = Destination;
+ while (*Source != '\0') {
+ //
+ // If any Unicode characters in Source contain
+ // non-zero value in the upper 8 bits, then ASSERT().
+ //
+ ASSERT (*Source < 0x100);
+ *(Destination++) = (CHAR8) *(Source++);
+ }
+
+ *Destination = '\0';
+
+ //
+ // ASSERT Original Destination is less long than PcdMaximumAsciiStringLength.
+ // Length tests are performed inside AsciiStrLen().
+ //
+ TempReturnValue = (Strlen((CHAR8 *)ReturnValue) + 1) * sizeof (*ReturnValue);
+ ASSERT (TempReturnValue!= 0);
+
+ return ReturnValue;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitNvmeStrings
+//
+// Description: This function initializes the SB related setup option values
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle - Handle to HII database
+// IN UINT16 Class - Indicates the setup class
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+InitNvmeStrings(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN UINT16 Class
+)
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ UINTN HandleCountPciIo;
+ EFI_HANDLE *HandleBufferPciIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_PCI_IO_PROTOCOL *PciIO;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController = NULL;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo;
+ UINTN OpenInfoCount;
+ UINTN IndexPciIo;
+ UINTN IndexOpenInfo;
+ EFI_HANDLE DeviceHandle;
+ EFI_HANDLE ControllerHandle;
+ EFI_HANDLE DriverBindingHandle;
+ EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2Protocol;
+ CHAR16 *DriveNameUni;
+ CHAR8 *NewString;
+ UINTN SegmentNumber;
+ UINTN BusNumber;
+ UINTN DeviceNumber;
+ UINTN FunctionNumber;
+ UINT8 DrivePresence[DRIVEMAXCOUNT] = {0};
+ UINT8 DriveIndex = 0;
+ SETUP_DATA *SetupData;
+ EFI_GUID SetupGuid = SETUP_GUID;
+ UINTN SetupSize = sizeof(SETUP_DATA);
+ UINT32 Attribute = 0;
+
+
+ if (Class == ADVANCED_FORM_SET_CLASS) {
+ // Collect all DevicePath protocol and check for NVMe Controller
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gEfiDevicePathProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+
+ if (EFI_ERROR(Status)) return;
+
+ for (Index = 0; Index < HandleCount; Index++) {
+
+ Status = pBS->HandleProtocol(
+ HandleBuffer[Index],
+ &gEfiDevicePathProtocolGuid,
+ (VOID *)&DevicePath
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ continue;
+ }
+
+ DevicePathNode = DevicePath;
+ while (!isEndNode (DevicePathNode)) {
+ if ((DevicePathNode->Type == MESSAGING_DEVICE_PATH) &&
+ (DevicePathNode->SubType == MSG_NVME_DP)) {
+ break;
+ }
+
+ DevicePathNode = NEXT_NODE(DevicePathNode);
+ }
+
+ if (DevicePathNode == NULL || isEndNode (DevicePathNode)) {
+ continue;
+ }
+
+ // NVMe Device Handle is found.
+ DeviceHandle = HandleBuffer[Index];
+
+ // NVMe device is found. Now get the CONTROLLER. Check all the PCIio handles.
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gEfiPciIoProtocolGuid,
+ NULL,
+ &HandleCountPciIo,
+ &HandleBufferPciIo
+ );
+
+ for (IndexPciIo = 0; IndexPciIo < HandleCountPciIo; IndexPciIo++) {
+ Status = pBS->HandleProtocol(
+ HandleBufferPciIo[IndexPciIo],
+ &gEfiPciIoProtocolGuid,
+ (VOID *)&PciIO
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = pBS->HandleProtocol(
+ HandleBufferPciIo[IndexPciIo],
+ &gAmiNvmeControllerProtocolGuid,
+ (VOID *)&NvmeController
+ );
+
+ // If Ami Nvme Controller Protocol not found on the Controller handle ( PciIo handle)
+ // do not process the Pci Io Handle
+ if(EFI_ERROR(Status)) {
+ continue;
+ }
+
+ OpenInfoCount = 0;
+ Status = pBS->OpenProtocolInformation(
+ HandleBufferPciIo[IndexPciIo],
+ &gEfiPciIoProtocolGuid,
+ &OpenInfo,
+ &OpenInfoCount
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ continue;
+ }
+
+ for (IndexOpenInfo = 0; IndexOpenInfo < OpenInfoCount; IndexOpenInfo++) {
+
+ //Check if the handle is opened BY_CHILD and also comnpare the device handle.
+ if ((OpenInfo[IndexOpenInfo].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) &&
+ (OpenInfo[IndexOpenInfo].ControllerHandle == DeviceHandle)){
+
+ DriverBindingHandle = OpenInfo[IndexOpenInfo].AgentHandle;
+ // Get the handle for the Controller
+ ControllerHandle = HandleBufferPciIo[IndexPciIo];
+
+ // Now PCI controller and DriverBinding handle is found. Get the Component2Protocol now.
+ Status = pBS->HandleProtocol(
+ DriverBindingHandle,
+ &gEfiComponentName2ProtocolGuid,
+ (VOID *)&ComponentName2Protocol
+ );
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = ComponentName2Protocol->GetControllerName (
+ ComponentName2Protocol,
+ ControllerHandle,
+ DeviceHandle,
+ LANGUAGE_CODE_ENGLISH,
+ &DriveNameUni
+ );
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ 256,
+ (VOID *) &NewString);
+ ASSERT_EFI_ERROR (Status);
+
+ UnicodeStrToAsciiStr (DriveNameUni, NewString);
+
+ InitString(
+ HiiHandle,
+ NVMeSetupStruc[DriveIndex].DeviceString,
+ L"%S",
+ NewString
+ );
+
+ Status = PciIO->GetLocation (
+ PciIO,
+ &SegmentNumber,
+ &BusNumber,
+ &DeviceNumber,
+ &FunctionNumber
+ );
+
+ Sprintf(NewString, "Bus:%X Dev:%x Func:%x", BusNumber, DeviceNumber, FunctionNumber);
+
+ InitString(
+ HiiHandle,
+ NVMeSetupStruc[DriveIndex].ControllerString,
+ L"%S",
+ NewString
+ );
+
+ //Enable the string to be displayed in setup
+ DrivePresence[DriveIndex] = 1;
+ DriveIndex++;
+
+ pBS->FreePool(NewString);
+ }
+ }
+ pBS->FreePool(OpenInfo);
+ }
+ pBS->FreePool(HandleBufferPciIo);
+ }
+
+ pBS->FreePool(HandleBuffer);
+
+ // Update setupdata to show whether strings need to be displayed or not
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof (SETUP_DATA),(VOID *) &SetupData);
+ ASSERT_EFI_ERROR (Status);
+
+ SetupSize = sizeof (SETUP_DATA);
+
+ Status = pRS->GetVariable (
+ L"Setup",
+ &SetupGuid,
+ &Attribute,
+ &SetupSize,
+ SetupData
+ );
+
+ if(!EFI_ERROR(Status)){
+ SetupData->DeviceCount = DriveIndex;
+ for (DriveIndex = 0; DriveIndex < DRIVEMAXCOUNT; DriveIndex++){
+ SetupData->ShowNVMeDrive[DriveIndex] = DrivePresence[DriveIndex];
+ }
+
+ Status = pRS->SetVariable (
+ L"Setup",
+ &SetupGuid,
+ Attribute,
+ sizeof (SETUP_DATA),
+ SetupData
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ }
+ pBS->FreePool(SetupData);
+ }
+
+ return;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeDef.h b/Core/EM/Nvme/NvmeSmm/NvmeDef.h
new file mode 100644
index 0000000..3bcc083
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeDef.h
@@ -0,0 +1,253 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeDef.h 1 9/04/14 7:54a Anandakrishnanl $
+//
+// $Revision: 1 $
+//
+// $Date: 9/04/14 7:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeDef.h $
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeDef.h
+//
+// Description: Nvme Smm and Non Smm interface Definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _AMI_NVME_DEF_H_
+#define _AMI_NVME_DEF_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define NVME_DATA_EBDA_OFFSET 0x104
+
+#define NVME_API_MASS_DEVICE_REQUEST 0x27
+
+//----------------------------------------------------------------------------
+// NVME Mass Storage Related Data Structures and Equates
+//----------------------------------------------------------------------------
+#define NVME_EMU_NONE 0
+#define NVME_EMU_FLOPPY_ONLY 1
+#define NVME_EMU_HDD_ONLY 2
+#define NVME_EMU_FORCED_FDD 3
+
+// Error returned from API handler
+#define NVME_SUCCESS 0x000
+#define NVME_PARAMETER_ERROR 0x010
+#define NVME_NOT_SUPPORTED 0x020
+#define NVME_INVALID_FUNCTION 0x0F0
+#define NVME_ERROR 0x0FF
+
+#pragma pack(1)
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Controller Info
+
+ @param TransferBufferAddress
+ @param NVMEBaseAddress
+ @param PciBus
+ @param PciDevice
+ @param PciFunc
+ @param Port
+ @param DeviceDetected
+ @param DeviceAddress
+ @param NumHeads
+ @param LBANumHeads
+ @param NumCylinders
+ @param LBANumCyls
+ @param NumSectors
+ @param LBANumSectors
+ @param MaxLBA
+ @param BlockSize
+ @param StorageType
+ @param PNM[27]
+ @param NVMEDevice
+ @param NVMEManufactureId[NVME_MANUFACTUREID_LENGTH]
+
+**/
+
+typedef struct {
+ UINT32 TransferBufferAddress;
+ UINT64 NVMEBaseAddress;
+ UINT8 PciBus;
+ UINT8 PciDevice;
+ UINT8 PciFunc;
+ UINT8 Port;
+ BOOLEAN DeviceDetected;
+ UINT8 DeviceAddress;
+ UINT8 NumHeads;
+ UINT8 LBANumHeads;
+ UINT16 NumCylinders;
+ UINT16 LBANumCyls;
+ UINT8 NumSectors;
+ UINT8 LBANumSectors;
+ UINT64 MaxLBA;
+ UINT16 BlockSize;
+ UINT8 StorageType;
+ UINT8 PNM[27];
+ BOOLEAN NVMEDevice;
+ UINT8 NVMEManufactureId[NVME_MANUFACTUREID_LENGTH];
+} CONTROLLER_INFO;
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Reset NVME
+
+ @param DeviceAddress
+**/
+
+typedef struct {
+ UINT8 DeviceAddress;
+} RESET_NVME;
+
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Read
+
+ @param DeviceAddress
+ @param Port
+ @param LBA
+ @param NumBlks
+ @param BufferAddress
+
+**/
+
+typedef struct {
+ UINT8 DeviceAddress;
+ UINT8 Port;
+ UINT64 LBA; // Starting LBA address
+ UINT16 NumBlks; // Number of blocks to read
+ UINT32 BufferAddress; // Far buffer pointer
+} READ_DATA;
+
+
+/**
+ This is a URP (NVME Request Packet) structure for the BIOS
+ API call Device Geometry
+
+ @param DeviceAddress
+ @param NumHeads
+ @param NumCylinders
+ @param NumSectors
+ @param LBANumHeads
+ @param LBANumCyls
+ @param LBANumSectors
+ @param BlockSize
+ @param MediaType
+ @param MaxLBA
+ @param Int13FunctionNo
+ @param BpbMediaDesc
+
+**/
+typedef struct {
+ UINT8 DeviceAddress;
+ UINT8 NumHeads;
+ UINT16 NumCylinders;
+ UINT8 NumSectors;
+ UINT8 LBANumHeads;
+ UINT16 LBANumCyls;
+ UINT8 LBANumSectors;
+ UINT16 BlockSize;
+ UINT8 MediaType;
+ UINT64 MaxLBA;
+ UINT8 Int13FunctionNo;
+ UINT8 BpbMediaDesc;
+} DEVICE_GEO;
+
+
+/**
+ This is a union data type of all the API related data
+
+ @param Reset
+ @param ControllerInfo
+ @param Read
+ @param DeviceGeo
+**/
+
+typedef union {
+ RESET_NVME Reset;
+ CONTROLLER_INFO ControllerInfo;
+ READ_DATA Read;
+ DEVICE_GEO DeviceGeo;
+} NVME_API_DATA;
+
+
+/**
+ This structure is the URP structure
+
+ @param bFuncNumber
+ @param bSubFunc
+ @param bRetValue
+ @param ApiData
+
+ @note Fields:Name Type Description
+ --------------------------------------------------
+ bFuncNumber UINT8 Function number of the URP
+ bSubFunc UINT8 Sub-func number of the URP
+ bRetValue UINT8 Return value
+ ApiData API_DATA Refer structure definition
+**/
+
+typedef struct {
+ UINT8 bFuncNumber;
+ UINT8 bSubFunc;
+ UINT8 bRetValue;
+ NVME_API_DATA ApiData;
+} NVME_STRUC;
+
+#pragma pack()
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.c b/Core/EM/Nvme/NvmeSmm/NvmeSmm.c
new file mode 100644
index 0000000..538a7f0
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.c
@@ -0,0 +1,1127 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.c 10 12/08/16 4:21a Karthikar $
+//
+// $Revision: 10 $
+//
+// $Date: 12/08/16 4:21a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.c $
+//
+// 10 12/08/16 4:21a Karthikar
+// [TAG] EIP307568
+// [Category] Bug Fix
+// [Symptom] Legacy Installation and booting fails in
+// (INT)_a_4.6.5.5_NVMe_006
+// [RootCause] Since this NvmeSmm_Support token is not included in
+// Token.h, TransferNvmeDataToSmram() dint get control.
+// [Solution] Added NvmeSmm_Support token in Token.h
+// [Files] NvmeBus.c,NvmeSmm.c,NvmeSmm.sdl
+//
+// 9 11/03/16 5:29a Karthikar
+// [TAG] EIP300640
+// [Category] Improvement
+// [Description] NvmeSmm: Security vulnerability in the NvmeSmm driver
+//
+// 8 2/03/16 2:13a Lavanyap
+// [TAG] EIP254133
+// [Category] New Feature
+// [Description] Modify NVMe driver to avoid repeated FALSE THREAT issue
+// report in Security Advisory.
+// [Files] NvmeSmm.c
+//
+// 7 2/02/16 1:24a Karthikar
+// [TAG] EIP254245
+// [Category] Bug Fix
+// [Symptom] Static code analysis issues found in Aptio4 Nvme module
+// [RootCause] In if condition variable is intialized without proper
+// braces.
+// [Solution] Removed wrong variable initialization
+// from if condition.
+// [Files] NvmeSmm.c
+//
+// 6 5/14/15 2:39a Karthikar
+// [TAG] EIP216763
+// [Category] Improvement
+// [Description] Update the Aptio 4.x Nvme driver to Aptio 5.x Nvme
+// driver Label 05
+// [Files] Nvme.mak,NvmeBus.c, NvmeBus.h, NvmeController.c,
+// NvmePassthru.c,NvmePassthru.h, NvmeSmm.c, NvmExpressPassThru.h,
+// PDiskInfo.h
+//
+// 5 4/20/15 8:52a Anbuprakashp
+// [TAG] EIP214300
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Nvme device with legacy OS can not resume from S4
+// [RootCause] In Aptio 4.x NvmeSmm Driver, Media buffer in
+// EFI_BLOCK_IO_MEDIA holds invalid memory address( i.e. The memory is not
+// allocated in SMRAM ).
+// [Solution] Memory for Media buffer(EFI_BLOCK_IO_MEDIA) is allocated
+// in SMRAM region
+// [Files] NvmeSmm.c
+//
+// 4 4/08/15 10:07a Anbuprakashp
+// [TAG] EIP212320
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] CPU exception in Nvme Driver if
+// PcdCpuSmmCodeAccessCheckEnable is enabled
+// [RootCause] BootService call shouldn't be used inside SMM function.
+// if PcdCpuSmmCodeAccessCheckEnable is enabled, It causes CPU exception.
+// [Solution] Changes made to avoid BootService call inside SMM function
+// [Files] NvmeSmm.c
+// NvmeBus.c
+// AmiNvmeController.h
+//
+// 3 12/10/14 5:14a Lavanyap
+// [TAG] EIP185327
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in Aptio4.x NVMe
+// Driver
+// [Files] NvmeSmm.mak, NvmeSmm.c, NvmeSmm.h
+//
+// 2 9/23/14 2:32a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description]
+// Add Legacy Boot support in Aptio 4.x Nvme driver - NON PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSmm.c
+//
+// Description: Nvme SMM driver to handle the Nvme device access
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "NvmeSmm.h"
+
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
+EFI_SMM_SYSTEM_TABLE2 *pSmst2;
+NVME_GLOBAL_DATA *gNvmeData;
+AMI_NVME_CONTROLLER_PROTOCOL *gNvmeController[MAX_NVME_DEVICES] = {0};
+BOOLEAN gFirstAPICall = FALSE;
+
+static EFI_GUID gAmiSmmNvmeCommunicationGuid = AMI_SMM_NVME_COMMUNICATION_GUID;
+
+// ]ApiTable - NVMe API Function Dispatch Table
+
+API_FUNC NvmeMassApiTable[] = {
+ NvmeMassAPIGetDeviceInformation, // Nvme Mass API Sub-Func 00h
+ NvmeMassAPIGetDeviceGeometry, // Nvme Mass API Sub-Func 01h
+ NvmeMassAPIResetDevice, // Nvme Mass API Sub-Func 02h
+ NvmeMassAPIReadDevice, // Nvme Mass API Sub-Func 03h
+ NvmeMassAPIWriteDevice, // Nvme Mass API Sub-Func 04h
+ NvmeMassAPIPass, // Nvme Mass API Sub-Func 05h VerifyDevice
+ NvmeMassAPIPass, // Nvme Mass API Sub-Func 06h FormatDevice
+ NvmeMassAPINotSupported, // Nvme Mass API Sub-Func 07h CommandPassThru
+ NvmeMassAPINotSupported, // Nvme BIOS API function 08h AssignDriveNumber
+ NvmeMassAPINotSupported, // Nvme BIOS API function 09h CheckDevStatus
+ NvmeMassAPINotSupported, // Nvme BIOS API function 0Ah GetDevStatus
+ NvmeMassAPINotSupported // Nvme BIOS API function 0Bh GetDeviceParameters
+};
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ZeroMemorySmm
+//
+// Description: Clears input Buffer to zero
+//
+// Input:
+// void *Buffer
+// UINTN Size
+//
+// Output:
+// NONE
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void
+ZeroMemorySmm (
+ void *Buffer,
+ UINTN Size
+ )
+{
+ UINT8 *Ptr;
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetDevEntry
+//
+// Description: Get the Index# for the DeviceAddress
+//
+// Input:
+// UINT8 DeviceAddress,
+// ACTIVE_NAMESPACE_DATA **ActiveNameSpace
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+VOID
+GetDevEntry (
+ UINT8 DeviceAddress,
+ ACTIVE_NAMESPACE_DATA **ActiveNameSpace
+)
+{
+
+ UINT8 Count;
+ EFI_LIST_ENTRY *LinkData;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+
+ // Locate a free slot to copy the pointer
+ for (Count = 0; Count < MAX_NVME_DEVICES; Count++ ){
+ if (gNvmeController[Count]) {
+ NvmeController = gNvmeController[Count];
+
+ if(IsListEmpty(&NvmeController->ActiveNameSpaceList)) {
+ continue;
+ }
+
+ for (LinkData = NvmeController->ActiveNameSpaceList.ForwardLink; \
+ LinkData != &NvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ *ActiveNameSpace = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+ if ((*ActiveNameSpace)->Int13DeviceAddress == DeviceAddress) {
+ return;
+ }
+ }
+ }
+ }
+
+ ActiveNameSpace = NULL;
+ return ;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIGetDeviceInformation
+//
+// Description: Return Device information
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIGetDeviceInformation (
+ NVME_STRUC *NvmeURP
+)
+{
+
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIGetDeviceGeometry
+//
+// Description: Return Device Geometry
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIGetDeviceGeometry (
+ NVME_STRUC *NvmeURP
+)
+{
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIResetDevice
+//
+// Description: Reset device
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIResetDevice (
+ NVME_STRUC *NvmeURP
+)
+{
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIReadDevice
+//
+// Description: Read data from the device
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIReadDevice (
+ NVME_STRUC *NvmeURP
+)
+{
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = NULL;
+ EFI_STATUS Status;
+ EFI_LBA Lba;
+ UINT16 NumBlks;
+ UINT16 BlksPerTransfer;
+ VOID *Buffer = NULL;
+ VOID *ReadBuffer;
+ UINTN BufferSize;
+ BOOLEAN UnalignedTransfer = FALSE;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ UINT32 Offset;
+ COMPLETION_QUEUE_ENTRY *pCmdCompletionData;
+
+ GetDevEntry(NvmeURP->ApiData.Read.DeviceAddress, &ActiveNameSpace);
+
+ if(ActiveNameSpace == NULL) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ // Validate if input Buffer address is an non-SMRAM region to avoid SMRAM data
+ // corruption through SMI handlers.
+ // NOTE: As DMA transfer isn't supported inside SMM, Buffer validation is not needed for
+ // NVMe. But below validation code is added to avoid repeated Security False Threat reports.
+
+ Status = AmiValidateMemoryBuffer((VOID*)NvmeURP->ApiData.Read.BufferAddress,
+ NvmeURP->ApiData.Read.NumBlks *
+ ActiveNameSpace->NvmeBlockIO.Media->BlockSize );
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ NvmeController = ActiveNameSpace->NvmeController;
+ if (NvmeController->Queue1SubmissionQueueTailPtr == 0xFFFF) {
+ Offset = QUEUE_DOORBELL_OFFSET( NvmeController->NVMQueueNumber, 1, NvmeController->DoorBellStride);
+ NvmeController->Queue1CompletionQueueHeadPtr = CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset);
+ NvmeController->Queue1SubmissionQueueHeadPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ NvmeController->Queue1SubmissionQueueTailPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ // Check if there is a roller over
+ if (NvmeController->Queue1SubmissionQueueTailPtr >= NvmeController->Queue1SubmissionQueueSize) {
+ NvmeController->Queue1SubmissionQueueTailPtr = 0;
+ }
+
+ // Update the phase tag from the Completion queue
+ pCmdCompletionData = (COMPLETION_QUEUE_ENTRY *)NvmeController->Queue1CompletionQueueMappedAddr;
+ NvmeController->Queue1PhaseTag = (UINT8)pCmdCompletionData->PhaseTag;
+ NvmeController->CommandIdentifierQueue1 = 0;
+ NvmeController->CommandIdentifierAdmin = 0;
+ }
+
+
+ Lba=NvmeURP->ApiData.Read.LBA;
+ NumBlks=NvmeURP->ApiData.Read.NumBlks;
+
+ (UINT32)Buffer= NvmeURP->ApiData.Read.BufferAddress;
+
+ BlksPerTransfer = NumBlks;
+ ReadBuffer = Buffer;
+
+ //If Buffer isn't aligned use internal buffer
+ if ((UINTN)NvmeURP->ApiData.Read.BufferAddress & ((1 << ActiveNameSpace->NvmeBlockIO.Media->IoAlign)-1)) {
+ BlksPerTransfer = 1;
+ ReadBuffer = NvmeController->LegacyNvmeBuffer;
+ UnalignedTransfer = TRUE;
+ }
+
+ BufferSize = BlksPerTransfer * ActiveNameSpace->NvmeBlockIO.Media->BlockSize;
+
+ for ( ; NumBlks; NumBlks -= BlksPerTransfer){
+ Status = NvmeReadWriteBlocks (ActiveNameSpace, ActiveNameSpace->NvmeBlockIO.Media->MediaId, Lba, BufferSize, ReadBuffer, NULL, NVME_READ);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ if (UnalignedTransfer) {
+ MemCpy (Buffer, ReadBuffer, BufferSize);
+ }
+ (UINTN)Buffer = (UINTN)Buffer + BufferSize;
+ Lba += BlksPerTransfer;
+
+ }
+
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_READ_ERR;
+ } else {
+ NvmeURP->bRetValue = NVME_SUCCESS;
+ }
+
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIWriteDevice
+//
+// Description: Write data to the device
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIWriteDevice (
+ NVME_STRUC *NvmeURP
+)
+{
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace = NULL;
+ EFI_STATUS Status;
+ EFI_LBA Lba;
+ UINT16 NumBlks;
+ UINT16 BlksPerTransfer;
+ VOID *Buffer = NULL;
+ VOID *ReadBuffer;
+ UINTN BufferSize;
+ BOOLEAN UnalignedTransfer = FALSE;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ UINT32 Offset;
+ COMPLETION_QUEUE_ENTRY *pCmdCompletionData;
+
+ GetDevEntry(NvmeURP->ApiData.Read.DeviceAddress, &ActiveNameSpace);
+
+ if(ActiveNameSpace == NULL) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ // Validate if input Buffer address is an non-SMRAM region to avoid SMRAM data
+ // corruption through SMI handlers.
+ // NOTE: As DMA transfer isn't supported inside SMM, Buffer validation is not needed for
+ // NVMe. But below validation code is added to avoid repeated Security False Threat reports.
+
+ Status = AmiValidateMemoryBuffer((VOID*)NvmeURP->ApiData.Read.BufferAddress,
+ NvmeURP->ApiData.Read.NumBlks *
+ ActiveNameSpace->NvmeBlockIO.Media->BlockSize );
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return;
+ }
+
+ NvmeController = ActiveNameSpace->NvmeController;
+ if (NvmeController->Queue1SubmissionQueueTailPtr == 0xFFFF) {
+ Offset = QUEUE_DOORBELL_OFFSET( NvmeController->NVMQueueNumber, 1, NvmeController->DoorBellStride);
+ NvmeController->Queue1CompletionQueueHeadPtr = CONTROLLER_REG32(NvmeController->NvmeBarOffset, Offset);
+ NvmeController->Queue1SubmissionQueueHeadPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ NvmeController->Queue1SubmissionQueueTailPtr = NvmeController->Queue1CompletionQueueHeadPtr;
+ // Check if there is a roller over
+ if (NvmeController->Queue1SubmissionQueueTailPtr >= NvmeController->Queue1SubmissionQueueSize) {
+ NvmeController->Queue1SubmissionQueueTailPtr = 0;
+ }
+
+ // Update the phase tag from the Completion queue
+ pCmdCompletionData = (COMPLETION_QUEUE_ENTRY *)NvmeController->Queue1CompletionQueueMappedAddr;
+ NvmeController->Queue1PhaseTag = (UINT8)pCmdCompletionData->PhaseTag;
+ NvmeController->CommandIdentifierQueue1 = 0;
+ NvmeController->CommandIdentifierAdmin = 0;
+
+ }
+
+
+ Lba=NvmeURP->ApiData.Read.LBA;
+ NumBlks=NvmeURP->ApiData.Read.NumBlks;
+
+ (UINT32)Buffer= NvmeURP->ApiData.Read.BufferAddress;
+
+ BlksPerTransfer = NumBlks;
+ ReadBuffer = Buffer;
+
+ //If Buffer isn't aligned use internal buffer
+ if ((UINTN)NvmeURP->ApiData.Read.BufferAddress & ((1 << ActiveNameSpace->NvmeBlockIO.Media->IoAlign)-1)) {
+ BlksPerTransfer = 1;
+ ReadBuffer = NvmeController->LegacyNvmeBuffer;
+ UnalignedTransfer = TRUE;
+ }
+
+ BufferSize = BlksPerTransfer * ActiveNameSpace->NvmeBlockIO.Media->BlockSize;
+
+ for ( ; NumBlks; NumBlks -= BlksPerTransfer){
+
+ if (UnalignedTransfer) {
+ MemCpy (ReadBuffer, Buffer, BufferSize);
+ }
+
+ Status = NvmeReadWriteBlocks (ActiveNameSpace, ActiveNameSpace->NvmeBlockIO.Media->MediaId, Lba, BufferSize, ReadBuffer, NULL, NVME_WRITE);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ (UINTN)Buffer = (UINTN)Buffer + BufferSize;
+ Lba += BlksPerTransfer;
+
+ }
+
+ if (EFI_ERROR(Status)) {
+ NvmeURP->bRetValue = NVME_WRITE_ERR;
+ }
+ else {
+ NvmeURP->bRetValue = NVME_SUCCESS;
+ }
+
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPIPass
+//
+// Description: Dummy handler to return NVME_SUCCESS
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPIPass(
+ NVME_STRUC *NvmeURP
+)
+{
+
+ NvmeURP->bRetValue = NVME_SUCCESS;
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeMassAPINotSupported
+//
+// Description: Dummy handler to return NVME_NOT_SUPPORTED
+//
+// Input:
+// NVME_STRUC *NvmeURP
+//
+// Output:
+// NONE
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID
+NvmeMassAPINotSupported (
+ NVME_STRUC *NvmeURP
+)
+{
+
+ NvmeURP->bRetValue = NVME_NOT_SUPPORTED;
+ return;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeInitSmmData
+//
+// Description: Initialize NVMe SMM data area
+//
+// Input:
+//
+//
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+EFI_STATUS
+EFIAPI
+NvmeInitSmmData (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+ )
+#else
+EFI_STATUS
+NvmeInitSmmData (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+#endif
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ ACTIVE_NAMESPACE_DATA *OrgActiveNameSpace;
+ ACTIVE_NAMESPACE_DATA *ActiveNameSpace;
+ AMI_NVME_CONTROLLER_PROTOCOL *NvmeController;
+ AMI_NVME_CONTROLLER_PROTOCOL *OrgNvmeController;
+ UINT8 Count;
+ EFI_LIST_ENTRY *LinkData;
+ UINTN NvmeComBuffer = 0;
+ static EFI_GUID gNvmeSmmGuid = NVME_SMM_GUID;
+ UINTN VariableSize = sizeof(UINTN);
+ EFI_BLOCK_IO_MEDIA *Media = NULL;
+
+ // After the first API call is invoked, don't initialize SMM data area. This is an additional
+ // Security check so that data won't get corrupted.
+ if (gFirstAPICall) {
+ return EFI_SUCCESS;
+ }
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+
+ // If input is invalid, stop processing this SMI
+ if (CommBuffer == NULL || CommBufferSize == NULL) {
+ return EFI_SUCCESS;
+ }
+ (UINTN)OrgNvmeController = *(UINTN *)CommBuffer;
+#else
+
+ Status = pRS->GetVariable ( L"NvmeSmmBuffer",
+ &gNvmeSmmGuid,
+ NULL,
+ &VariableSize,
+ &NvmeComBuffer );
+
+// TRACE((-1, "NvmeComBuffer in NvmeInitSmmData = %x\n", NvmeComBuffer));
+
+ (UINTN)OrgNvmeController = NvmeComBuffer;
+
+#endif
+
+
+ // Locate a free slot to copy the pointer
+ for (Count = 0; Count < MAX_NVME_DEVICES; Count++ ){
+ if (!gNvmeController[Count]) {
+ break;
+ }
+ }
+
+ if (Count == MAX_NVME_DEVICES) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (AMI_NVME_CONTROLLER_PROTOCOL),
+ (VOID**)&NvmeController);
+ ASSERT_EFI_ERROR(Status);
+
+ // Copy input NvmeController passed in OrgNvmeController into SMM
+ MemCpy ((VOID *)NvmeController, OrgNvmeController, sizeof (AMI_NVME_CONTROLLER_PROTOCOL));
+
+
+ // Copy IDENTIFY_CONTROLLER_DATA
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (IDENTIFY_CONTROLLER_DATA),
+ (VOID**)&(NvmeController->IdentifyControllerData));
+ ASSERT_EFI_ERROR(Status);
+
+ MemCpy (NvmeController->IdentifyControllerData, OrgNvmeController->IdentifyControllerData, sizeof(IDENTIFY_CONTROLLER_DATA));
+
+ gNvmeController[Count] = NvmeController;
+
+
+ // Initialize some of the pointers to NULL which aren't applicable during runtime
+ NvmeController->PciIO = NULL;
+ NvmeController->NvmeInSmm = TRUE;
+ NvmeController->Queue1SubmissionQueueTailPtr = 0xFFFF;
+
+ InitializeListHead (&NvmeController->ActiveNameSpaceList);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (NVME_COMMAND_WRAPPER),
+ (VOID**)&(NvmeController->NvmeCmdWrapper));
+
+ // Clear memory
+ ZeroMemorySmm (NvmeController->NvmeCmdWrapper, sizeof(NVME_COMMAND_WRAPPER));
+
+ // use original NVMe buffer for this as original address value is used.
+ // Update the NvmeController pointer inside ActiveNameSpace
+ for (LinkData = OrgNvmeController->ActiveNameSpaceList.ForwardLink;
+ LinkData != &OrgNvmeController->ActiveNameSpaceList;
+ LinkData = LinkData->ForwardLink) {
+
+ OrgActiveNameSpace = _CR(LinkData ,ACTIVE_NAMESPACE_DATA, Link);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (ACTIVE_NAMESPACE_DATA),
+ (VOID**)&(ActiveNameSpace));
+ if(EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ MemCpy (ActiveNameSpace, OrgActiveNameSpace, sizeof(ACTIVE_NAMESPACE_DATA));
+
+ ActiveNameSpace->NvmeController = NvmeController;
+ ActiveNameSpace->EfiDevicePath = NULL;
+ ActiveNameSpace->UDeviceName = NULL;
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ Status = pSmst2->SmmAllocatePool (
+#else
+ Status = pSmst->SmmAllocatePool (
+#endif
+ EfiRuntimeServicesData,
+ sizeof (EFI_BLOCK_IO_MEDIA),
+ (VOID**)&(Media) );
+ if(EFI_ERROR(Status)) {
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ MemCpy ( Media, OrgActiveNameSpace->NvmeBlockIO.Media, sizeof(EFI_BLOCK_IO_MEDIA) );
+ ActiveNameSpace->NvmeBlockIO.Media = Media;
+
+ InsertTailList (&NvmeController->ActiveNameSpaceList, &ActiveNameSpace->Link);
+
+ }
+
+ return Status;
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeSWSMIHandler
+//
+// Description: Handle SWSMI generated from NVMe CSM16 module
+//
+// Input:
+//
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+#else
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+#endif
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ NVME_STRUC *NvmeURP=NULL;
+ UINT8 bFuncIndex;
+ UINT8 bNumberOfFunctions;
+ UINT16 EbdaSeg;
+
+ gFirstAPICall = TRUE;
+
+ //
+ // Get the fpURP pointer from EBDA
+ //
+
+ EbdaSeg = *((UINT16*)0x40E);
+ NvmeURP = *(NVME_STRUC**)(UINTN)(((UINT32)EbdaSeg << 4) + NVME_DATA_EBDA_OFFSET);
+ NvmeURP = (NVME_STRUC*)((UINTN)NvmeURP & 0xFFFFFFFF);
+
+ // Validate if URP address is an non-SMRAM region to avoid SMRAM data
+ // corruption through SMI handlers
+ Status = AmiValidateMemoryBuffer((VOID*)NvmeURP, sizeof(NVME_STRUC));
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ if (NvmeURP->bFuncNumber != NVME_API_MASS_DEVICE_REQUEST) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return Status;
+ }
+
+ bFuncIndex = NvmeURP->bSubFunc;
+ bNumberOfFunctions = sizeof NvmeMassApiTable / sizeof (API_FUNC *);
+
+ //
+ // Make sure function number is valid; if function number is not zero
+ // check for valid extended SDIO API function
+ //
+ if (bFuncIndex >= bNumberOfFunctions ) {
+ NvmeURP->bRetValue = NVME_PARAMETER_FAILED;
+ return Status;
+ }
+
+ //
+ // Call the appropriate function
+ //
+
+ NvmeMassApiTable[bFuncIndex](NvmeURP);
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InSmmFunction
+//
+// Description: Nvme InSmmFunction
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE SwHandle = NULL;
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+ EFI_HANDLE DispatchHandle;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch = NULL;
+#else
+ EFI_SMM_BASE_PROTOCOL *pSmmBase;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch = NULL;
+ EFI_SMM_SYSTEM_TABLE *pSmst;
+ EFI_SMM_SW_DISPATCH_CONTEXT NvmeSmmSwContext = { NVME_SWSMI };
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+#endif
+
+ InitAmiBufferValidationLib(ImageHandle, SystemTable);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+
+ // PI_1.2 -->>
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gSmmBase2->GetSmstLocation (gSmmBase2, &pSmst2);
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ Status = pSmst2->SmmLocateProtocol(&gEfiSmmSwDispatch2ProtocolGuid,
+ NULL,
+ &pSwDispatch);
+ if (EFI_ERROR(Status)) {
+ return EFI_SUCCESS;
+ }
+
+ SwContext.SwSmiInputValue = NVME_SWSMI;
+ Status = pSwDispatch->Register (pSwDispatch,
+ NvmeSWSMIHandler,
+ &SwContext,
+ &SwHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ //Allocate Memory for NVMe global Data.
+ //
+ Status = pSmst2->SmmAllocatePool(EfiRuntimeServicesData,sizeof(NVME_GLOBAL_DATA), &gNvmeData);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Clear the Buffer
+ //
+ pBS->SetMem((VOID*)gNvmeData, sizeof(NVME_GLOBAL_DATA), 0);
+
+
+ //
+ // Register Nvme handler to transfer data from DXE driver to SMM
+ //
+ Status = pSmst2->SmiHandlerRegister (
+ NvmeInitSmmData,
+ &gAmiSmmNvmeCommunicationGuid,
+ &DispatchHandle
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ // PI_1.2 <<--
+#else
+
+ // NON PI 1.2 -->>
+
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiSmmBaseProtocolGuid, NULL, &pSmmBase);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pSmmBase->GetSmstLocation (pSmmBase, &pSmst);
+
+ Status = pSwDispatch->Register (pSwDispatch,
+ NvmeSWSMIHandler,
+ &NvmeSmmSwContext,
+ &SwHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ //Allocate Memory for NVMe global Data.
+ //
+ Status = pSmst->SmmAllocatePool(EfiRuntimeServicesData,sizeof(NVME_GLOBAL_DATA), &gNvmeData);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Clear the Buffer
+ //
+ pBS->SetMem((VOID*)gNvmeData, sizeof(NVME_GLOBAL_DATA), 0);
+
+ SwContext.SwSmiInputValue = NVME_INIT_SMM_SWSMI;
+ Status = pSwDispatch->Register (pSwDispatch,
+ NvmeInitSmmData,
+ &SwContext,
+ &SwHandle);
+
+ // NON PI_1.2 <<--
+
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NvmeSmmDriverEntryPoint
+//
+// Description: Loads NVMe SMM module into SMM and registers SMI handler
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+NvmeSmmDriverEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler (ImageHandle, SystemTable, InSmmFunction, NULL);
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.cif b/Core/EM/Nvme/NvmeSmm/NvmeSmm.cif
new file mode 100644
index 0000000..56d3f22
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "NvmeSmm"
+ category = ModulePart
+ LocalRoot = "Core\EM\Nvme\NvmeSmm\"
+ RefName = "NvmeSmm"
+[files]
+"NvmeSmm.mak"
+"NvmeSmm.dxs"
+"NvmeSmm.sdl"
+"NvmeSmm.c"
+"NvmeSmm.h"
+"NvmeDef.h"
+<endComponent>
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs b/Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs
new file mode 100644
index 0000000..e2e23f9
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.dxs
@@ -0,0 +1,89 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.dxs 2 9/23/14 2:33a Anandakrishnanl $
+//
+// $Revision: 2 $
+//
+// $Date: 9/23/14 2:33a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.dxs $
+//
+// 2 9/23/14 2:33a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Add Legacy Boot support in Aptio 4.x Nvme driver - NON
+// PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSmm.dxs
+//
+// Description: This file is the dependency file for the NvmeSmm driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+
+DEPENDENCY_START
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+#else
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.h b/Core/EM/Nvme/NvmeSmm/NvmeSmm.h
new file mode 100644
index 0000000..20d13f4
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.h
@@ -0,0 +1,222 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.h 3 12/10/14 5:15a Lavanyap $
+//
+// $Revision: 3 $
+//
+// $Date: 12/10/14 5:15a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.h $
+//
+// 3 12/10/14 5:15a Lavanyap
+// [TAG] EIP185327
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in Aptio4.x NVMe
+// Driver
+// [Files] NvmeSmm.mak, NvmeSmm.c, NvmeSmm.h
+//
+// 2 9/23/14 2:34a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Add Legacy Boot support in Aptio 4.x Nvme driver - NON
+// PI 1.2 Support
+// [Files] NvmeBus.c
+// NvmeBus.h
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+//
+// 1 9/04/14 7:54a Anandakrishnanl
+// [TAG] EIP180861
+// [Category] Improvement
+// [Description] Legacy Boot support in Aptio 4.x Nvme driver
+// [Files] NvmeSmm.cif
+// NvmeSmm.mak
+// NvmeSmm.dxs
+// NvmeSmm.sdl
+// NvmeSmm.c
+// NvmeSmm.h
+// NvmeDef.h
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvmeSmm.h
+//
+// Description: Header file for the NvmeSmm
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _AMI_NVME_SMM_DRIVER_H_
+#define _AMI_NVME_SMM_DRIVER_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <EFI.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+#include "NvmeIncludes.h"
+#include "NvmeBus.h"
+#include "NvmeDef.h"
+#include <AmiBufferValidationLib.h>
+
+typedef VOID (*API_FUNC)(NVME_STRUC*);
+
+//-----------------------------------------------
+// ERROR CODE REPORTED TO CALLER
+//-----------------------------------------------
+#define NVME_WRITE_PROTECT_ERR 0x003 // Write protect error
+#define NVME_TIME_OUT_ERR 0x080 // Command timed out error
+#define NVME_DRIVE_NOT_READY_ERR 0x0AA // Drive not ready error
+#define NVME_DATA_CORRECTED_ERR 0x011 // Data corrected error
+#define NVME_PARAMETER_FAILED 0x007 // Bad parameter error
+#define NVME_MARK_NOT_FOUND_ERR 0x002 // Address mark not found error
+#define NVME_NO_MEDIA_ERR 0x031 // No media in drive
+#define NVME_READ_ERR 0x004 // Read error
+#define NVME_WRITE_ERR 0x005 // Write error
+#define NVME_UNCORRECTABLE_ERR 0x010 // Uncorrectable data error
+#define NVME_BAD_SECTOR_ERR 0x00A // Bad sector error
+#define NVME_GENERAL_FAILURE 0x020 // Controller general failure
+
+
+//-----------------------------------------------------------------------;
+// NVME_GLOBAL_DATA
+//-----------------------------------------------------------------------;
+typedef struct{
+ UINT32 TransferBufferAddress;
+ UINT8 NvmeMassEmulationOptionTable[MAX_NVME_DEVICES];
+ ACTIVE_NAMESPACE_DATA NvmeDev[MAX_NVME_DEVICES];
+} NVME_GLOBAL_DATA;
+
+//
+//NVME Setup fields
+//
+
+typedef struct {
+ UINT8 NvmeMode;
+ UINT8 NvmeEmu1;
+ UINT8 NvmeEmu2;
+ UINT8 NvmeEmu3;
+ UINT8 NvmeEmu4;
+ UINT8 NvmeEmu5;
+ UINT8 NvmeEmu6;
+ UINT8 NvmeEmu7;
+ UINT8 NvmeEmu8;
+ UINT8 NvmeMassDevNum;
+} NVME_DEV_CONFIGURATION;
+
+
+EFI_STATUS
+NotInSmmFunction (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+);
+
+EFI_STATUS
+NvmeInSmmFunction (
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+);
+
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010014)
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+);
+#else
+EFI_STATUS
+NvmeSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+);
+#endif
+
+VOID
+ZeroMemorySmm (
+ VOID *Buffer,
+ UINTN Size
+ );
+
+VOID
+NvmeMassAPIGetDeviceInformation (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIGetDeviceGeometry (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIResetDevice (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIReadDevice (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIWriteDevice (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPINotSupported (
+ NVME_STRUC *NvmeURP
+);
+
+VOID
+NvmeMassAPIPass(
+ NVME_STRUC *NvmeURP
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.mak b/Core/EM/Nvme/NvmeSmm/NvmeSmm.mak
new file mode 100644
index 0000000..3c3636b
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.mak
@@ -0,0 +1,95 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.mak 3 7/15/15 5:04a Deepthins $
+#
+# $Revision: 3 $
+#
+# $Date: 7/15/15 5:04a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NVMe/NvmeSmm/NvmeSmm.mak $
+#
+# 3 7/15/15 5:04a Deepthins
+# [TAG] EIP228506
+# [Description] Legacy Os installation failing for NVME device in AMD
+# platform
+# [Files] NvmeSmm.mak
+#
+# 2 12/10/14 5:16a Lavanyap
+# [TAG] EIP185327
+# [Category] Improvement
+# [Description] Security Enhancement for SMIHandler in Aptio4.x NVMe
+# Driver
+# [Files] NvmeSmm.mak, NvmeSmm.c, NvmeSmm.h
+#
+# 1 9/04/14 7:54a Anandakrishnanl
+# [TAG] EIP180861
+# [Category] Improvement
+# [Description] Legacy Boot support in Aptio 4.x Nvme driver
+# [Files] NvmeSmm.cif
+# NvmeSmm.mak
+# NvmeSmm.dxs
+# NvmeSmm.sdl
+# NvmeSmm.c
+# NvmeSmm.h
+# NvmeDef.h
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: NvmeSmm.mak
+#
+# Description: Make file for NvmeSmm
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : NvmeSmm
+
+NvmeSmm : $(BUILD_DIR)\NvmeSmm.mak NvmeSmmBin
+
+$(BUILD_DIR)\NvmeSmm.mak : $(NVME_SMM_DIR)\NvmeSmm.cif $(NVME_SMM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(NVME_SMM_DIR)\NvmeSmm.cif $(CIF2MAK_DEFAULTS)
+
+NVME_SMM_LIB = $(AMIDXELIB) \
+ $(NVMECONTROLLERLIB) \
+ $(BUILD_DIR)\AmiBufferValidationLib.lib
+
+NVME_SMM_INCLUDES=\
+ /I$(NVME_DIR)\
+
+NvmeSmmBin : $(NVME_SMM_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NvmeSmm.mak all\
+ GUID=E5E2C9D9-5BF5-497E-8860-94F81A09ADE0\
+ ENTRY_POINT=NvmeSmmDriverEntryPoint\
+ "MY_INCLUDES=$(NVME_SMM_INCLUDES)"\
+ TYPE=SMM_DRIVER\
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl b/Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl
new file mode 100644
index 0000000..e9ab0e7
--- /dev/null
+++ b/Core/EM/Nvme/NvmeSmm/NvmeSmm.sdl
@@ -0,0 +1,35 @@
+TOKEN
+ Name = "NvmeSmm_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable NvmeSmm support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+ Token = "NVMEINT13_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "NVME_SMM_DIR"
+End
+
+TOKEN
+ Name = "NVME_INIT_SMM_SWSMI"
+ Value = "0x45"
+ Help = "Data to be written to SW SMI port to Init NVME Smm Data."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes NvmeSmm.mak to Project"
+ File = "NvmeSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NvmeSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/NvramSmi/NvramSmi.c b/Core/EM/NvramSmi/NvramSmi.c
new file mode 100644
index 0000000..851f2dc
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmi.c
@@ -0,0 +1,1155 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/NvramSmi/NvramSmi.c 3 4/16/14 3:02a Chaseliu $
+//
+// $Revision: 3 $
+//
+// $Date: 4/16/14 3:02a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/NvramSmi/NvramSmi.c $
+//
+// 3 4/16/14 3:02a Chaseliu
+// [TAG] EIP161860
+// [Category] Improvement
+// [Description] Upadte NvramSmi 05 Handle initialized with NULL.
+// [Files]
+// Core\EM\NvramSmi\NvramSmi.c
+//
+// 18 4/02/14 10:33a Oleksiyy
+// [TAG] EIP161860
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Dummy protocol do not installs
+// [RootCause] DummyHandle was not preinitialized with NULL.
+// [Solution] Initialize Handle with NULL.
+// [Files] NvramSmi.c
+//
+// 17 3/05/14 4:52p Oleksiyy
+// [TAG] EIP154299
+// [Category] Improvement
+// [Description] Integer + heap potential overflow in SetVariable
+// patched.
+// [Files] NvramSmi.c
+//
+// 16 4/02/13 6:19p Oleksiyy
+// [TAG] EIP119970
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] NvramSmi handling of very big variable bug
+// [RootCause] Out of resources status returned without enabling
+// interrupts and Smi (previously disabled by call to
+// NvSmiBeginCriticalSection).
+// [Solution] Check for size and retutning out of resources moved prior
+// to disablig interrupts and Smi in NvSmiBeginCriticalSection.
+// [Files] NvramSmi.c
+//
+// 15 12/13/12 4:39p Oleksiyy
+// [TAG] EIP109427
+// [Category] Improvement
+// [Description] Issues found by CppCheck in NvramSmi eModule.
+// [Files] NvramSmi.c
+//
+// 14 11/28/12 3:19p Oleksiyy
+// [TAG] EIP106304
+// [Category] Improvement
+// [Description] Do not need to publish Dummy protocoll if
+// PI_SPECIFICATION_VERSION<0x1000A.
+// [Files] NvramSmi.c
+//
+// 13 11/07/12 5:41p Oleksiyy
+// [TAG] EIP98678
+// [Category] Improvement
+// [Description] GetVariable() response slow. Added token to process
+// only SetVariable through SMI.
+// [Files] NvramSmi.c, NvramSmi.sdl and NVRAM.mak
+//
+// 12 10/29/12 4:04p Oleksiyy
+// [TAG] EIP102428
+// [Category] Improvement
+// [Description] Suse 11 SP2 can't boot successfully with uEFI mode and
+// Xen kernel.
+// Os cant handle optimized comands. Switch back to Memcopy.
+// [Files] NvramSmi.c
+//
+// 11 8/09/12 11:14a Oleksiyy
+// [TAG] EIP96125
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System will hang on when GetVariable in SMM
+// [RootCause] pSmmBase->InSmm was destriyed during RT.
+// [Solution] Check for Legacy Boot Event added.
+// [Files] NvramSmi.c
+//
+// 10 5/22/12 3:46p Oleksiyy
+// [TAG] EIP89155
+// [Category] Improvement
+// [Description] Implementing review comments
+// [Files] NvraSmi.c and NvramSmi.sdl
+//
+// 9 5/08/12 5:54p Oleksiyy
+// [TAG] EIP89155
+// [Category] Improvement
+// [Description] NVRAM SMI module does not boot in PI 1.2
+// [Files] NvramSmi.c, NvramSmi.sdl and NvramSmi.dxs
+//
+// 8 4/20/12 5:26p Oleksiyy
+// [TAG] EIP88363
+// [Category] Bug Fix
+// [Symptom] Build error in NvramSmi when
+// PI_SPECIFICATION_VERSION<0x0001000A
+// [RootCause] Variable Virtual was declared dependent from
+// PI_SPECIFICATION_VERSION by mistake.
+// [Solution] Dependency from PI_SPECIFICATION_VERSION removed.
+// [Files] NvramSmi.c
+//
+// 7 4/10/12 12:29p Oleksiyy
+// [TAG] EIP86642
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] bios post will hang after add the NVRAMSMI module on
+// Mahobay CRB19
+// [RootCause] pSmmBase do not exist in PI mode during runtime.
+// [Solution] Do not acces pSmmBase after going Virtual.
+// [Files] NvramSmi.c
+//
+// 6 3/29/12 11:06a Oleksiyy
+// [TAG] EIP85100
+// [Category] Improvement
+// [Description] Added handling of using
+// gST->RuntimeServices->GetVariable from SMM
+//
+//
+// [Files] NvramSmi.c
+//
+// 5 1/13/12 12:27p Oleksiyy
+// [TAG] EIP80096
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] EFI Shell 'time' command hangs on Rose City CRB with label
+// 15 BIOS
+// [RootCause] Memory overwriten if too long VariableLength parameter is
+// passed to GatVariable function in NvramSmi.c.
+// [Solution] Implementing review comments.
+// [Files] NvramSmi.c
+//
+// 4 1/10/12 5:26p Oleksiyy
+// [TAG] EIP80096
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] EFI Shell 'time' command hangs on Rose City CRB with label
+// 15 BIOS
+// [RootCause] Memory overwriten if too long VariableLength parameter is
+// passed to GatVariable function in NvramSmi.c.
+// [Solution] Check for too long VariableLength parameter is added to
+// GatVariable function in NvramSmi.c. too long VariableLength parameter
+// is added to GatVariable function in NvramSmi.c.
+// [Files] NvramSmi.c, NvramSmi.sdl
+//
+// 3 12/09/11 4:02p Oleksiyy
+// [TAG] EIP77762
+// [Category] Improvement
+// [Description] Create a initial label for a created NvramSmi eModule.
+// [Files] All files in eModule.
+//
+// 2 11/14/11 5:14p Oleksiyy
+// Dependency from Core Ver added.
+//
+// 1 11/11/11 3:41p Oleksiyy
+// Initial CheckIn
+//
+// 1 11/11/11 3:33p Oleksiyy
+//
+// 3 6/27/11 6:46p Alexp
+//
+// 2 6/24/11 5:03p Alexp
+// add SecFlash OFBD module
+// upgrade Security modules. use individual module label histories for
+// detalis
+//
+// 1 6/10/11 1:01p Alexp
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvramSmi.c
+//
+// Description: NVRAM SMI DXE driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include "NVRAM.h"
+
+EFI_RUNTIME_SERVICES *SmmpRs = NULL;
+EFI_GUID SmmRtServTableGuid = EFI_SMM_RUNTIME_SERVICES_TABLE_GUID;
+BOOLEAN ExitBS = FALSE;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmCommunication.h>
+EFI_HANDLE VarSmiHandle = NULL;
+EFI_SMM_COMMUNICATION_PROTOCOL *SmmCommProtocol = NULL;
+EFI_GUID gEfiSmmCommunicationProtocolGuid = EFI_SMM_COMMUNICATION_PROTOCOL_GUID;
+
+EFI_SMM_BASE2_PROTOCOL *InternalSmmBase2 = NULL;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateCommunicateProt
+//
+// Description: This function will be called to locate Smm Communication Protocol
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LocateCommunicateProt (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+
+ if (SmmCommProtocol != NULL)
+ return EFI_SUCCESS;
+
+ return (pBS->LocateProtocol ( &gEfiSmmCommunicationProtocolGuid,
+ NULL,
+ &SmmCommProtocol ));
+
+}
+
+#endif
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+typedef struct
+{
+ UINT32 Signature;
+ UINT32 VarAttrib;
+ EFI_GUID VarGuid;
+ UINTN VarSize;
+ EFI_STATUS Status;
+ UINT8 Subfunction;
+ UINT64 MaxVarStorageSize;
+ UINT64 RemVarStorageSize;
+ UINT64 MaxVarSize;
+ UINT8 VarData;
+
+} SMI_VARIABLE;
+
+typedef struct
+{
+ BOOLEAN Busy;
+ UINT8 IntState[2];
+
+} NVRAM_SMI_CRITICAL_SECTION;
+
+//----------------------------------------------------------------------------
+// Local Variables
+#define NVRAM_SMI_GUID \
+{0x29C31B9F, 0xD2B9, 0x4900, 0xBD, 0x2A, 0x58, 0x4F, 0x29, 0x12, 0xE3, 0x86}
+#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \
+{0x3aa83745, 0x9454, 0x4f7a, 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e}
+
+#define NVRAM_SW_SMI 0x2b
+#define SMI_SET_VARIABLE 2
+#if NVRAM_SMI_FULL_PROTECTION == 1
+#define SMI_GET_VARIABLE 1
+#define SMI_GET_NEXT_VAR_NAME 3
+#define SMI_QUERY_VAR_INFO 4
+#endif
+EFI_GUID gNvramSmiGuid = NVRAM_SMI_GUID;
+VOID *gNvramBuffer = NULL;
+EFI_EVENT EvtNvramSmi;
+VOID *RegNvramSmi;
+NVRAM_SMI_CRITICAL_SECTION NvramSmiCs = {FALSE, {0, 0}};
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+EFI_SMM_COMMUNICATE_HEADER CommHeader = {NVRAM_SMI_GUID, 1 , {0}};
+VOID *CommHeaderPtr;
+#endif
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeginCriticalSection
+//
+// Description: This function calls when critical section begins. It disables interupts,
+// and Smi and fills CRITICAL_SECTION structure fields
+//
+// Input: CRITICAL_SECTION *Cs - pointer to CRITICAL_SECTION structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NvSmiBeginCriticalSection (
+ NVRAM_SMI_CRITICAL_SECTION *Cs
+)
+{
+ if (Cs->Busy) return EFI_ACCESS_DENIED;
+ Cs->IntState[0] = IoRead8(0x21);
+ Cs->IntState[1] = IoRead8(0xa1);
+ IoWrite8 (0x21, 0xff);
+ IoWrite8 (0xa1, 0xff);
+ Cs->Busy = TRUE;
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EndCriticalSection
+//
+// Description: This function calls when critical section ends. It enable interupts,
+// and Smi and fills CRITICAL_SECTION structure fields
+//
+// Input: CRITICAL_SECTION *Cs - pointer to CRITICAL_SECTION structure
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NvSmiEndCriticalSection (
+ NVRAM_SMI_CRITICAL_SECTION *Cs
+)
+{
+ Cs->Busy = FALSE;
+ IoWrite8 (0x21, Cs->IntState[0]);
+ IoWrite8 (0xa1, Cs->IntState[1]);
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EndCriticalSection
+//
+// Description: TThis function initiates communication between VAR services outside
+// of SMM and SMI handlers inside of SMM. With the help of Smm Communication
+// Protocol, if it is present, or direct I/O write, if not.
+//
+// Input: None
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitCommunicate ()
+{
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+ UINTN CommSize = sizeof(EFI_SMM_COMMUNICATE_HEADER);
+
+
+ if (SmmCommProtocol)
+ SmmCommProtocol->Communicate (SmmCommProtocol, CommHeaderPtr, &CommSize);
+ else
+#endif
+ IoWrite8 (SW_SMI_IO_ADDRESS, NVRAM_SW_SMI);
+ return;
+}
+
+VOID GetSmmRsPtr()
+{
+ if (SmmpRs == NULL)
+ SmmpRs = GetSmstConfigurationTable(&SmmRtServTableGuid);
+ return;
+}
+
+#if NVRAM_SMI_FULL_PROTECTION == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetVariableToSmi
+//
+// Description: This function searches for Var with specific GUID and Name
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// OPTIONAL OUT UINT32* Attributes - Pointer to memory where Attributes will be returned
+// IN OUT UINTN *DataSize - size of Var - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// OUT VOID *Data - Pointer to memory where Var will be returned
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetVariableToSmi (
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ SMI_VARIABLE *Buffer;
+ BOOLEAN InSmm = FALSE;
+ //TRACE((-1,"GetVariableToSmi. Name %S\n", VariableName));
+ if (!VariableName || !VendorGuid || !DataSize || !Data && *DataSize)
+ return EFI_INVALID_PARAMETER;
+ Length = (Wcslen(VariableName) + 1)*sizeof(CHAR16);
+ if ((NVRAM_SIZE - sizeof(SMI_VARIABLE)) <= Length)
+ return EFI_OUT_OF_RESOURCES;
+ Status = EFI_NO_RESPONSE;
+ if (gNvramBuffer != NULL) {
+ if (EFI_ERROR(NvSmiBeginCriticalSection(&NvramSmiCs)))
+ return EFI_ACCESS_DENIED;
+ Buffer = (SMI_VARIABLE*)gNvramBuffer;
+
+ Buffer->Subfunction = SMI_GET_VARIABLE;
+ Buffer->Signature = NVAR_SIGNATURE;
+ if (Attributes) Buffer->VarAttrib = *Attributes;
+ Buffer->VarSize = *DataSize;
+ Buffer->Status = Status;
+ MemCpy(&Buffer->VarGuid, VendorGuid, sizeof(EFI_GUID));
+ MemCpy((UINT8*)&Buffer->VarData, (UINT8*)VariableName, Length);
+ if (!ExitBS)
+ pSmmBase->InSmm(pSmmBase, &InSmm);
+ if (!InSmm)
+ InitCommunicate ();
+ else
+ {
+ Status = EFI_SECURITY_VIOLATION;
+ if (pRS->GetVariable == GetVariableToSmi)
+ {
+ if (pSmst==NULL)
+ {
+ pSmmBase->GetSmstLocation(pSmmBase,&pSmst);
+ }
+ GetSmmRsPtr();
+ if (SmmpRs != NULL)
+ {
+ Status = SmmpRs->GetVariable(VariableName, VendorGuid,
+ Attributes, DataSize, Data);
+ }
+ }
+ NvSmiEndCriticalSection (&NvramSmiCs);
+ return Status;
+ }
+ Status = Buffer->Status;
+ if (Status != EFI_NO_RESPONSE) {
+
+ if (Status == EFI_BUFFER_TOO_SMALL) *DataSize = Buffer->VarSize;
+ if (!EFI_ERROR(Status)) {
+
+ if (Attributes) *Attributes = Buffer->VarAttrib;
+ *DataSize = Buffer->VarSize;
+ MemCpy((UINT8*)Data, &Buffer->VarData, Buffer->VarSize);
+ }
+ }
+
+ NvSmiEndCriticalSection (&NvramSmiCs);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNextVariableNameToSmi
+//
+// Description: This function searches for next Var after Var with specific name and GUID and returns it's Name
+// in SMM synchronizing Varstors before and after operation.
+//
+// Input: IN OUT UINTN *VariableNameSize - size of Varname - if smaller than actual EFI_BUFFER_TOO_SMALL
+// will be returned and DataSize will be set to actual size needed
+// IN OUT CHAR16 *VariableName - pointer where Var Name in Unicode will be stored
+// IN OUT EFI_GUID *VendorGuid - pointer to menory where Var GUID is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetNextVariableNameToSmi (
+ IN OUT UINTN *VariableNameSize,
+ IN OUT CHAR16 *VariableName, IN OUT EFI_GUID *VendorGuid
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ SMI_VARIABLE *Buffer;
+ BOOLEAN InSmm = FALSE;
+ //TRACE((-1,"GetNextVariableNameToSmi. Name %S\n", VariableName));
+ if ( !VariableNameSize || !VariableName || !VendorGuid)
+ return EFI_INVALID_PARAMETER;
+ Status = EFI_NO_RESPONSE;
+ if (gNvramBuffer != NULL) {
+ if (EFI_ERROR(NvSmiBeginCriticalSection(&NvramSmiCs)))
+ return EFI_ACCESS_DENIED;
+
+ Length = (Wcslen(VariableName) + 1)*sizeof(CHAR16);
+ Buffer = (SMI_VARIABLE*)gNvramBuffer;
+ Buffer->Subfunction = SMI_GET_NEXT_VAR_NAME;
+ Buffer->Signature = NVAR_SIGNATURE;
+ Buffer->VarSize = *VariableNameSize;
+ Buffer->Status = Status;
+ MemCpy(&Buffer->VarGuid, VendorGuid, sizeof(EFI_GUID));
+
+ MemCpy((UINT8*)&Buffer->VarData, (UINT8*)VariableName, Length);
+ if (!ExitBS)
+ pSmmBase->InSmm(pSmmBase, &InSmm);
+ if (!InSmm)
+ InitCommunicate ();
+ else
+ {
+ Status = EFI_SECURITY_VIOLATION;
+ if (pRS->GetNextVariableName == GetNextVariableNameToSmi)
+ {
+ if (pSmst==NULL)
+ {
+ pSmmBase->GetSmstLocation(pSmmBase,&pSmst);
+ }
+ GetSmmRsPtr();
+ if (SmmpRs != NULL)
+ {
+ Status = SmmpRs->GetNextVariableName(VariableNameSize, VariableName,VendorGuid);
+ }
+ }
+ NvSmiEndCriticalSection (&NvramSmiCs);
+ return Status;
+ }
+
+ Status = Buffer->Status;
+ if (Status != EFI_NO_RESPONSE) {
+
+ *VariableNameSize = Buffer->VarSize;
+ if (!EFI_ERROR(Status)) {
+
+ MemCpy((UINT8*)VariableName, &Buffer->VarData, Buffer->VarSize);
+ MemCpy((UINT8*)VendorGuid, (UINT8*)&Buffer->VarGuid, sizeof(EFI_GUID));
+ }
+ }
+
+ NvSmiEndCriticalSection (&NvramSmiCs);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: QueryVariableInfoToSmi
+//
+// Description: This function returns parameters of VarStore with passed attributes
+//
+// Input: IN UINT32 Attributes - Atributes to search for
+// OUT UINT64 *MaximumVariableStorageSize - Maximum Variable Storage Size
+// OUT UINT64 *RemainingVariableStorageSize - Remaining Variable Storage Size
+// OUT UINT64 *MaximumVariableSize - Maximum Variable Size
+//
+// Output: EFI_STATUS based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS QueryVariableInfoToSmi (
+ IN UINT32 Attributes,
+ OUT UINT64 *MaximumVariableStorageSize,
+ OUT UINT64 *RemainingVariableStorageSize,
+ OUT UINT64 *MaximumVariableSize
+)
+{
+
+ EFI_STATUS Status;
+ SMI_VARIABLE *Buffer;
+ BOOLEAN InSmm = FALSE;
+ if (!Attributes || !MaximumVariableStorageSize || !RemainingVariableStorageSize || !MaximumVariableSize)
+ return EFI_INVALID_PARAMETER;
+ //TRACE((-1, "QueryVariableInfoToSmi.\n"));
+ Status = EFI_NO_RESPONSE;
+ if (gNvramBuffer != NULL) {
+ if (EFI_ERROR(NvSmiBeginCriticalSection(&NvramSmiCs)))
+ return EFI_ACCESS_DENIED;
+ Buffer = (SMI_VARIABLE*)gNvramBuffer;
+
+ Buffer->Subfunction = SMI_QUERY_VAR_INFO;
+ Buffer->Signature = NVAR_SIGNATURE;
+ Buffer->VarAttrib = Attributes;
+ if (!ExitBS)
+ pSmmBase->InSmm(pSmmBase, &InSmm);
+ if (!InSmm)
+ InitCommunicate ();
+ else
+ {
+ Status = EFI_SECURITY_VIOLATION;
+ if (pRS->QueryVariableInfo == QueryVariableInfoToSmi)
+ {
+ if (pSmst==NULL)
+ {
+ pSmmBase->GetSmstLocation(pSmmBase,&pSmst);
+ }
+ GetSmmRsPtr();
+ if (SmmpRs != NULL)
+ {
+ Status = SmmpRs->QueryVariableInfo(Attributes, MaximumVariableStorageSize,
+ RemainingVariableStorageSize, MaximumVariableSize);
+ }
+ }
+ NvSmiEndCriticalSection (&NvramSmiCs);
+ return Status;
+ }
+
+ Status = Buffer->Status;
+ if (!EFI_ERROR(Status)) {
+ *MaximumVariableStorageSize = Buffer->MaxVarStorageSize;
+ *RemainingVariableStorageSize = Buffer->RemVarStorageSize;
+ *MaximumVariableSize = Buffer->MaxVarSize;
+ }
+
+ NvSmiEndCriticalSection(&NvramSmiCs);
+ }
+
+ return Status;
+}
+
+#endif //#if NVRAM_SMI_FULL_PROTECTION == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetVariableToSmi
+//
+// Description: This function sets Var with specific GUID, Name and attributes
+// beginning and ending critical section.
+//
+// Input: IN CHAR16 *VariableName - pointer to Var Name in Unicode
+// IN EFI_GUID *VendorGuid - pointer to Var GUID
+// IN UINT32 Attributes - Attributes of the Var
+// IN UINTN DataSize - size of Var
+// IN VOID *Data - Pointer to memory where Var data is stored
+//
+// Output: EFI_STATUS - based on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetVariableToSmi (
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+)
+{
+ EFI_STATUS Status;
+ UINTN Length;
+ SMI_VARIABLE *Buffer;
+ BOOLEAN InSmm = FALSE;
+ //TRACE((-1,"SetVariableToSmi. Name %S\n", VariableName));
+ if (!VariableName || VariableName[0]==0 || !VendorGuid || (DataSize && !Data))
+ return EFI_INVALID_PARAMETER;
+
+ Length = (Wcslen(VariableName) + 1)*sizeof(CHAR16);
+ if (((UINTN)(~0) - DataSize) < Length)
+ return EFI_OUT_OF_RESOURCES; // Prevent whole variable size overflow (if DataSize + Length > UINTN)
+
+ if ((DataSize + Length) > (NVRAM_SIZE - sizeof(SMI_VARIABLE)))
+ return EFI_OUT_OF_RESOURCES;
+
+ Status = EFI_NO_RESPONSE;
+ if (gNvramBuffer != NULL) {
+
+ if (EFI_ERROR(NvSmiBeginCriticalSection(&NvramSmiCs)))
+ return EFI_ACCESS_DENIED;
+
+ Buffer = (SMI_VARIABLE*)gNvramBuffer;
+
+ Buffer->Subfunction = SMI_SET_VARIABLE;
+ Buffer->Signature = NVAR_SIGNATURE;
+ Buffer->VarAttrib = Attributes;
+ Buffer->VarSize = DataSize;
+ Buffer->Status = Status;
+ MemCpy(&Buffer->VarGuid, VendorGuid, sizeof(EFI_GUID));
+
+ MemCpy(((UINT8*)&Buffer->VarData + DataSize), (UINT8*)VariableName, Length);
+ MemCpy(&Buffer->VarData, (UINT8*)Data, DataSize);
+ if (!ExitBS)
+ pSmmBase->InSmm(pSmmBase, &InSmm);
+ if (!InSmm)
+ InitCommunicate ();
+ else
+ {
+ Status = EFI_SECURITY_VIOLATION;
+ if (pRS->SetVariable == SetVariableToSmi)
+ {
+ if (pSmst==NULL)
+ {
+ pSmmBase->GetSmstLocation(pSmmBase,&pSmst);
+ }
+ GetSmmRsPtr();
+ if (SmmpRs != NULL)
+ {
+ Status = SmmpRs->SetVariable(VariableName, VendorGuid,
+ Attributes, DataSize, Data);
+ }
+ }
+ NvSmiEndCriticalSection (&NvramSmiCs);
+ return Status;
+ }
+
+ Status = Buffer->Status;
+
+ NvSmiEndCriticalSection(&NvramSmiCs);
+//TRACE((-1, "[ SmiSetVariable - %S %r , Data=%x]\n",VariableName, Status, Data));
+ }
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramSmiReadyToBoot
+//
+// Description: This function will be called when Ready To Boot will signaled
+// will update data to work in RunTime.
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvramSmiReadyToBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ UINT32 CRC32=0;
+#if NVRAM_SMI_FULL_PROTECTION == 1
+#if CORE_COMBINED_VERSION > 0x4028b
+ typedef struct
+ {
+ BOOLEAN StopRtDataAccess;
+ //TODO: there are more field inthe mailbox.
+ // we assume that StopRtDataAccess will always be the first field.
+ } NVRAM_MAILBOX;
+
+ #define NVRAM_MAILBOX_ADDRESS_VARIABLE_GUID \
+ {0x54913a6d, 0xf4ee, 0x4cdb, 0x84, 0x75, 0x74, 0x6, 0x2b, 0xfc, 0xec, 0xf5}
+
+ static EFI_GUID NvRamMailboxVariableGuid = NVRAM_MAILBOX_ADDRESS_VARIABLE_GUID;
+ NVRAM_MAILBOX *NvRamMailbox;
+ EFI_STATUS Status;
+ UINTN Size=sizeof(NvRamMailbox);
+
+ Status = pRS->GetVariable(
+ L"NvRamMailbox",&NvRamMailboxVariableGuid,
+ NULL, &Size, &NvRamMailbox
+ );
+ if (EFI_ERROR(Status)) return ;
+
+ NvRamMailbox->StopRtDataAccess = TRUE;
+ //Make a dummy SMM GetVariable call to process StopRtDataAccess
+ GetVariableToSmi(
+ L"NvRamMailbox",&NvRamMailboxVariableGuid,
+ NULL, &Size, &NvRamMailbox
+ );
+#endif
+#endif //#if NVRAM_SMI_FULL_PROTECTION == 1
+
+ //Init CommHeaderPtr----
+
+ if (gNvramBuffer == NULL) return;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ CommHeaderPtr = &CommHeader;
+#endif
+ TRACE((-1, "[ NvramSmi-ReadyToLock ]\n"));
+ pRS->SetVariable = SetVariableToSmi;
+#if NVRAM_SMI_FULL_PROTECTION == 1
+ pRS->GetVariable = GetVariableToSmi;
+ pRS->GetNextVariableName = GetNextVariableNameToSmi;
+ pRS->QueryVariableInfo = QueryVariableInfoToSmi;
+#endif //#if NVRAM_SMI_FULL_PROTECTION == 1
+ pRS->Hdr.CRC32 = 0;
+ pBS->CalculateCrc32(pRS, sizeof(*pRS), &CRC32);
+ pRS->Hdr.CRC32 = CRC32;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramSmiVirtualFixup
+//
+// Description: Called on Virtual address change event and converts
+// SmmCommProtocol pointer.
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvramSmiVirtualFixup (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ //TRACE((-1, "NvramSmi-Go Virtual\n"));
+ pRS->ConvertPointer (0, &gNvramBuffer);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (SmmCommProtocol != NULL)
+ pRS->ConvertPointer (0, (VOID**)&SmmCommProtocol);
+#endif
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NvramSmiVirtualFixup
+//
+// Description: Called on Exit BS and updates ExitBS variable
+//
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvramSmiExitBs (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ ExitBS = TRUE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NotInSmmFunction
+//
+// Description: This is the "NotInSmmFunction" parameter for the
+// InitSmmHandler function in the entry point. It allocates
+// memory for parameters buffer, saves its location, etc.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_EVENT EvtReadyToBoot, EvtExitBS;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ EFI_EVENT EvtComm;
+#endif
+ VOID *RegReadyToBoot, *RegComm;
+ static EFI_GUID StartNvramSmiServicesGuid = NVRAM_START_SMI_SERVICES_GUID;
+ static EFI_GUID DummyProtocolGuid = { 0xc35f952, 0x5791, 0x4667, { 0xad, 0xe4, 0x1c, 0xfd, 0xa8, 0x37, 0x72, 0x2d } };
+ EFI_HANDLE DummyHandle = NULL;
+
+ //TRACE((-1,"SmiNVRAM NotInSmmFunction.\n"));
+ gNvramBuffer = NULL;
+ Status = pBS->AllocatePool ( EfiRuntimeServicesData,
+ NVRAM_SIZE,
+ &gNvramBuffer );
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pRS->SetVariable ( L"NvramSmiBuffer",
+ &gNvramSmiGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(gNvramBuffer),
+ &gNvramBuffer );
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ InitAmiRuntimeLib(
+ ImageHandle, SystemTable, NvramSmiExitBs, NvramSmiVirtualFixup
+ );
+ CreateLegacyBootEvent(TPL_CALLBACK, &NvramSmiExitBs, NULL, &EvtExitBS);
+ Status = RegisterProtocolCallback ( &StartNvramSmiServicesGuid,
+ NvramSmiReadyToBoot,
+ NULL,
+ &EvtReadyToBoot,
+ &RegReadyToBoot );
+ ASSERT_EFI_ERROR (Status);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Status = LocateCommunicateProt (NULL, NULL);
+
+ if (EFI_ERROR(Status)){
+
+ Status = RegisterProtocolCallback ( &gEfiSmmCommunicationProtocolGuid,
+ LocateCommunicateProt,
+ NULL,
+ &EvtComm,
+ &RegComm );
+ }
+ //---Installing a Dummy protocol, on which Smm part is relying to make sure
+ //---InSmm function will start after NotInSmm
+ pBS->InstallProtocolInterface (
+ &DummyHandle, &DummyProtocolGuid, EFI_NATIVE_INTERFACE, NULL
+ );
+#endif
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NvramSmiHandler
+//
+// Description: The SMI handler for Nvram services.
+//
+// Input: NONE
+//
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS NvramSmiHandler ()
+{
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ SMI_VARIABLE *SmmVarBuffer;
+
+ SmmVarBuffer = (SMI_VARIABLE*)gNvramBuffer;
+
+ if (SmmVarBuffer->Signature != NVAR_SIGNATURE) return Status;
+
+ switch (SmmVarBuffer->Subfunction){
+
+ case SMI_SET_VARIABLE:
+ //TRACE((-1,"SmiNVRAM Handler. SMI_SET_VARIABLE \n"));
+ Status = pRS->SetVariable ( (CHAR16*)((UINT8*)&SmmVarBuffer->VarData + SmmVarBuffer->VarSize),
+ &SmmVarBuffer->VarGuid,
+ SmmVarBuffer->VarAttrib,
+ SmmVarBuffer->VarSize,
+ &SmmVarBuffer->VarData);
+ break;
+#if NVRAM_SMI_FULL_PROTECTION == 1
+ case SMI_GET_VARIABLE:
+ //TRACE((-1,"SmiNVRAM Handler. SMI_GET_VARIABLE \n"));
+
+ Status = pRS->GetVariable ( (CHAR16*) &SmmVarBuffer->VarData,
+ &SmmVarBuffer->VarGuid,
+ &SmmVarBuffer->VarAttrib,
+ &SmmVarBuffer->VarSize,
+ &SmmVarBuffer->VarData);
+ break;
+
+ case SMI_GET_NEXT_VAR_NAME:
+ //TRACE((-1,"SmiNVRAM Handler. SMI_GET_NEXT_VAR_NAME \n"));
+ Status = pRS->GetNextVariableName ( &SmmVarBuffer->VarSize,
+ (CHAR16*) &SmmVarBuffer->VarData,
+ &SmmVarBuffer->VarGuid);
+ break;
+
+ case SMI_QUERY_VAR_INFO:
+ //TRACE((-1,"SmiNVRAM Handler. SMI_QUERY_VAR_INFO \n"));
+ Status = pRS->QueryVariableInfo ( SmmVarBuffer->VarAttrib,
+ &SmmVarBuffer->MaxVarStorageSize,
+ &SmmVarBuffer->RemVarStorageSize,
+ &SmmVarBuffer->MaxVarSize);
+ break;
+#endif //#if NVRAM_SMI_FULL_PROTECTION == 1
+ default: return Status;
+ }
+ //TRACE((-1,"SmiNVRAM Handler. END\n"));
+ SmmVarBuffer->Status = Status;
+ SmmVarBuffer->Subfunction = 0;
+ SmmVarBuffer->Signature = ~NVAR_SIGNATURE;
+
+ return Status;
+}
+
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+EFI_STATUS NvramSmiHandler1 (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommBufferSize
+ )
+{
+
+ if (gNvramBuffer == NULL)
+ return EFI_DEVICE_ERROR;
+
+ return NvramSmiHandler();
+
+}
+#endif
+
+
+EFI_STATUS NvramSmiHandler2 (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+
+{
+
+ if ((gNvramBuffer == NULL) || ((UINT8)DispatchContext->SwSmiInputValue != NVRAM_SW_SMI))
+ return EFI_DEVICE_ERROR;
+ return NvramSmiHandler();
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NvramSmiSmmSwDispatchCallback
+//
+// Description: This function registers SMI Handler for Nvram services
+//
+// Input: IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output: NONE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NvramSmiSmmSwDispatchCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+ UINTN VariableSize = sizeof(gNvramBuffer);
+
+ if(gNvramBuffer) return; // already came here once...
+
+ Status = pBS->LocateProtocol ( &gEfiSmmSwDispatchProtocolGuid,
+ NULL,
+ &pSwDispatch );
+ if (EFI_ERROR(Status)) return;
+
+ Status = pRS->GetVariable ( L"NvramSmiBuffer",
+ &gNvramSmiGuid,
+ NULL,
+ &VariableSize,
+ &gNvramBuffer );
+ if ((EFI_ERROR(Status)) || (gNvramBuffer == NULL)) return;
+
+ SwContext.SwSmiInputValue = NVRAM_SW_SMI;
+ Status = pSwDispatch->Register ( pSwDispatch,
+ NvramSmiHandler2,
+ &SwContext,
+ &Handle );
+ pBS->CloseEvent (Event);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InSmmFunction
+//
+// Description: Registration of the SMI function.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+ EFI_SMM_SYSTEM_TABLE2 *pSmst2 = NULL;
+
+#endif
+
+ //TRACE((-1, "In NvramSmi InSmmFunction\n"));
+ NvramSmiSmmSwDispatchCallback (EvtNvramSmi, RegNvramSmi);
+
+ Status = RegisterProtocolCallback ( &gEfiSmmSwDispatchProtocolGuid,
+ NvramSmiSmmSwDispatchCallback,
+ NULL,
+ &EvtNvramSmi,
+ &RegNvramSmi );
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+ Status = SystemTable->BootServices->LocateProtocol (
+ &gEfiSmmBase2ProtocolGuid,
+ NULL,
+ (VOID **)&InternalSmmBase2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = InternalSmmBase2->GetSmstLocation (InternalSmmBase2, &pSmst2);
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (pSmst2 != NULL);
+ Status = pSmst2->SmiHandlerRegister(&NvramSmiHandler1, &gNvramSmiGuid, &VarSmiHandle);
+ ASSERT_EFI_ERROR (Status);
+
+#endif
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NvramSmiEntryPoint
+//
+// Description: DXE Entry Point for NvramSmi Driver.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NvramSmiEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ return InitSmmHandlerEx(
+ ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction
+ );
+
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/NvramSmi/NvramSmi.chm b/Core/EM/NvramSmi/NvramSmi.chm
new file mode 100644
index 0000000..c973a8c
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmi.chm
Binary files differ
diff --git a/Core/EM/NvramSmi/NvramSmi.cif b/Core/EM/NvramSmi/NvramSmi.cif
new file mode 100644
index 0000000..ba46269
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmi.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "NVRAM SMI"
+ category = eModule
+ LocalRoot = "Core\EM\NvramSmi"
+ RefName = "NvramSmi"
+[files]
+"NvramSmi.sdl"
+"NvramSmi.mak"
+"NvramSmi.c"
+"NvramSmi.dxs"
+"NvramSmiPi1.dxs"
+"NvramSmiDxe.dxs"
+"NvramSmi.chm"
+<endComponent>
diff --git a/Core/EM/NvramSmi/NvramSmi.dxs b/Core/EM/NvramSmi/NvramSmi.dxs
new file mode 100644
index 0000000..cf3cd4a
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmi.dxs
@@ -0,0 +1,79 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NvramSmi/NvramSmi.dxs 4 5/08/12 5:54p Oleksiyy $
+//
+// $Revision: 4 $
+//
+// $Date: 5/08/12 5:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NvramSmi/NvramSmi.dxs $
+//
+// 4 5/08/12 5:54p Oleksiyy
+// [TAG] EIP89155
+// [Category] Improvement
+// [Description] NVRAM SMI module does not boot in PI 1.2
+// [Files] NvramSmi.c, NvramSmi.sdl and NvramSmi.dxs
+//
+// 3 4/04/12 5:26p Oleksiyy
+// [TAG] EIP86730
+// [Category] Improvement
+// [Description] Update chm file for NvramSmi module - Header
+// description added.
+// [Files] NvramSmi.dxs, NvramSmiDxe.dxs and NvramSmi.mak.
+//
+// 2 12/09/11 4:02p Oleksiyy
+// [TAG] EIP77762
+// [Category] Improvement
+// [Description] Create a initial label for a created NvramSmi eModule.
+// [Files] All files in eModule.
+//
+// 1 11/11/11 3:41p Oleksiyy
+// Initial CheckIn
+//
+// 1 11/11/11 3:33p Oleksiyy
+//
+// 1 8/11/11 7:08p Alexp
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvramSMI_dxs
+//
+// Description: Dependency expression for the NvramSmi module.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol/SmmSwDispatch.h>
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+ {0xc35f952, 0x5791, 0x4667, 0xad, 0xe4, 0x1c, 0xfd, 0xa8, 0x37, 0x72, 0x2d}
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/NvramSmi/NvramSmi.mak b/Core/EM/NvramSmi/NvramSmi.mak
new file mode 100644
index 0000000..f44dcac
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmi.mak
@@ -0,0 +1,108 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/NvramSmi/NvramSmi.mak 4 11/28/12 3:37p Oleksiyy $
+#
+# $Revision: 4 $
+#
+# $Date: 11/28/12 3:37p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NvramSmi/NvramSmi.mak $
+#
+# 4 11/28/12 3:37p Oleksiyy
+# [TAG] EIP106304
+# [Category] Improvement
+# [Description] Separate dxs file added for
+# PI_SPECIFICATION_VERSION<0x1000A scenario.
+# [Files] NvramSmi.mak
+#
+# 3 4/04/12 5:27p Oleksiyy
+# [TAG] EIP86730
+# [Category] Improvement
+# [Description] Update chm file for NvramSmi module - Header
+# description added.
+# [Files] NvramSmi.dxs, NvramSmiDxe.dxs and NvramSmi.mak.
+#
+# 2 12/09/11 4:01p Oleksiyy
+# [TAG] EIP77762
+# [Category] Improvement
+# [Description] Create a initial label for a created NvramSmi eModule.
+# [Files] All files in eModule.
+#
+# 1 11/11/11 3:41p Oleksiyy
+# Initial CheckIn
+#
+# 1 11/11/11 3:33p Oleksiyy
+#
+# 2 8/12/11 12:19p Alexp
+#
+# 1 6/10/11 1:01p Alexp
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: NvramSmi.mak
+#
+# Description: Make file to build NvramSmi module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all: NvramSmi
+
+NvramSmi: $(BUILD_DIR)\NvramSmi.mak NvramSmiBin
+
+#---------------------------------------------------------------------------
+# Create PEI RAM BOOT dependencies
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\NvramSmi.mak : $(NvramSmi_DIR)\$(@B).cif $(NvramSmi_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(NvramSmi_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+#---------------------------------------------------------------------------
+
+NvramSmiBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NvramSmi.mak all\
+ GUID=842A454A-75E5-408B-8B1C-36420E4E3F21\
+ ENTRY_POINT=NvramSmiEntry\
+ "CFLAGS=$(CFLAGS) /I$(NvramSmi_DIR) /I$(NVRAM_DIR)"\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+!IF $(PI_SPECIFICATION_VERSION)<0x1000A
+ DEPEX1=$(NvramSmi_DIR)\NvramSmiPi1.DXS \
+ TYPE=RT_DRIVER \
+!ELSE
+ TYPE=DXESMM_DRIVER PE_TYPE=RT_DRIVER \
+ DEPEX1=$(NvramSmi_DIR)\NvramSmi.DXS \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ DEPEX2=$(NvramSmi_DIR)\NvramSmiDxe.DXS \
+ DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \
+!ENDIF
+ COMPRESS=1\
+#---------------------------------------------------------------------------
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/Core/EM/NvramSmi/NvramSmi.sdl b/Core/EM/NvramSmi/NvramSmi.sdl
new file mode 100644
index 0000000..a41940a
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmi.sdl
@@ -0,0 +1,111 @@
+#****************************************************************************
+#****************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 **
+#** **
+#** Phone (770)-246-8600 **
+#** **
+#****************************************************************************
+#****************************************************************************
+#****************************************************************************
+# $Header: /Alaska/SOURCE/Modules/NvramSmi/NvramSmi.sdl 5 11/07/12 5:41p Oleksiyy $
+#
+# $Revision: 5 $
+#
+# $Date: 11/07/12 5:41p $
+#
+#****************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/NvramSmi/NvramSmi.sdl $
+#
+# 5 11/07/12 5:41p Oleksiyy
+# [TAG] EIP98678
+# [Category] Improvement
+# [Description] GetVariable() response slow. Added token to process
+# only SetVariable through SMI.
+# [Files] NvramSmi.c, NvramSmi.sdl and NVRAM.mak
+#
+# 4 5/22/12 3:46p Oleksiyy
+# [TAG] EIP89155
+# [Category] Improvement
+# [Description] Implementing review comments
+# [Files] NvraSmi.c and NvramSmi.sdl
+#
+# 3 5/08/12 5:54p Oleksiyy
+# [TAG] EIP89155
+# [Category] Improvement
+# [Description] NVRAM SMI module does not boot in PI 1.2
+# [Files] NvramSmi.c, NvramSmi.sdl and NvramSmi.dxs
+#
+# 2 1/10/12 5:26p Oleksiyy
+# [TAG] EIP80096
+# [Category] Bug Fix
+# [Severity] Normal
+# [Symptom] EFI Shell 'time' command hangs on Rose City CRB with label
+# 15 BIOS
+# [RootCause] Memory overwriten if too long VariableLength parameter is
+# passed to GatVariable function in NvramSmi.c.
+# [Solution] Check for too long VariableLength parameter is added to
+# GatVariable function in NvramSmi.c. too long VariableLength parameter
+# is added to GatVariable function in NvramSmi.c.
+# [Files] NvramSmi.c, NvramSmi.sdl
+#
+# 1 11/11/11 3:41p Oleksiyy
+# Initial CheckIn
+#
+# 1 11/11/11 3:33p Oleksiyy
+#
+# 2 8/12/11 12:19p Alexp
+#
+# 1 6/10/11 1:01p Alexp
+#
+#
+#****************************************************************************
+TOKEN
+ Name = "NvramSmiSupport"
+ Value = "1"
+ Help = "Main switch to enable NVRAM SMI support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "NVRAM_SMI_FULL_PROTECTION"
+ Value = "0"
+ Help = "Switch to enable full SMI protection. If ON all NVRAM services will be handled through SMIs (maximum protection but slowest speed). If OFF only SetVariable will processed through SMI (minimum requirement for Secure Flash)."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NVRAM_START_SMI_SERVICES_GUID"
+ Value = "{0x3aa83745, 0x9454, 0x4f7a, 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e}"
+ Help = "This guid is used to register callback on which NVRAM services will transfered to SMI. (By default it is BDS_CONNECT_DRIVERS_PROTOCOL_GUID"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+PATH
+ Name = "NvramSmi_DIR"
+End
+
+MODULE
+ Help = "Includes NvramSmi.mak to Project"
+ File = "NvramSmi.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NvramSmi.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/NvramSmi/NvramSmiDxe.dxs b/Core/EM/NvramSmi/NvramSmiDxe.dxs
new file mode 100644
index 0000000..6f5b517
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmiDxe.dxs
@@ -0,0 +1,72 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NvramSmi/NvramSmiDxe.dxs 3 4/04/12 5:28p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 4/04/12 5:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NvramSmi/NvramSmiDxe.dxs $
+//
+// 3 4/04/12 5:28p Oleksiyy
+// [TAG] EIP86730
+// [Category] Improvement
+// [Description] Update chm file for NvramSmi module - Header
+// description added.
+// [Files] NvramSmi.dxs, NvramSmiDxe.dxs and NvramSmi.mak.
+//
+// 2 12/09/11 4:02p Oleksiyy
+// [TAG] EIP77762
+// [Category] Improvement
+// [Description] Create a initial label for a created NvramSmi eModule.
+// [Files] All files in eModule.
+//
+// 1 11/11/11 3:41p Oleksiyy
+// Initial CheckIn
+//
+// 1 11/11/11 3:33p Oleksiyy
+//
+// 1 8/11/11 7:08p Alexp
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvramSmiDxe_dxs
+//
+// Description: DXE Dependency expression for the NvramSmi module.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol\SmmBase2.h>
+DEPENDENCY_START
+ EFI_SMM_BASE2_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/NvramSmi/NvramSmiPi1.dxs b/Core/EM/NvramSmi/NvramSmiPi1.dxs
new file mode 100644
index 0000000..4a63cb5
--- /dev/null
+++ b/Core/EM/NvramSmi/NvramSmiPi1.dxs
@@ -0,0 +1,66 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/NvramSmi/NvramSmiPi1.dxs 2 11/28/12 3:02p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 11/28/12 3:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/NvramSmi/NvramSmiPi1.dxs $
+//
+// 2 11/28/12 3:02p Oleksiyy
+// [TAG] EIP106304
+// [Category] Improvement
+// [Description] Fixing Headers.
+// [Files] NvramSmiPi1.dxs
+//
+// 1 11/28/12 2:47p Oleksiyy
+// [TAG] EIP106304
+// [Category] Improvement
+// [Description] Create a new label of NvramSmi eModule.
+// [Files] NvramSmiPi1.dxs
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NvramSmiPi1.dxs
+//
+// Description: Dependency expression for the NvramSmi module used if
+// PI_SPECIFICATION_VERSION<0x1000A.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol/SmmSwDispatch.h>
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.c b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.c
new file mode 100644
index 0000000..ff9a63a
--- /dev/null
+++ b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.c
@@ -0,0 +1,176 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/BATTERYCHECK/BATTERYCHECK.c 1 10/11/12 2:27a Terrylin $
+//
+// $Revision: 1 $
+//
+// $Date: 10/11/12 2:27a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/BATTERYCHECK/BATTERYCHECK.c $
+//
+// 1 10/11/12 2:27a Terrylin
+// Initial check-in for OEM can control AC/Battery status check rule
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: BATTERYCHECK.c
+//
+// Description:
+//
+// This function is used for OEM can decided AFU flash behavior, when
+// AC/Battery is under warning status and can output the OEM String message
+// to the flash utility.
+//
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "BATTERYCHECK.h"
+#include "..\OFBD.h"
+
+//#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDBATTERYCHECK
+//
+// Description: OFBD AC/Battery check
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDBatteryCheck(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if BATTERYCHECK_SAMPLE_TEST
+
+ UINT8 *pOFBDTblEnd;
+ OFBD_TC_5B_AC_BATTERY_STRUCT *AC_BatteryPtr;
+
+ char *ErrorMsg_1 = "AC adapter is not connected.For an update, the AC adapter has to be connected.";
+ char *ErrorMsg_2 = "There is no installed battery or the remaining charge level of the battery is lower than 60%%.Check your battery.";
+ char *ErrorMsg_3 = "There is no installed battery or the remaining charge level of the battery is lower than 30%%.Check your battery.";
+ char *ErrorMsg_4 = "No support this version of flash Common Interface.";
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ AC_BatteryPtr = (OFBD_TC_5B_AC_BATTERY_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ switch(AC_BatteryPtr->dbGetSts)
+ {
+ //
+ // Please add your code here +>>>
+ //
+ case OFBD_TC_AC_BAT_INFO_REQ:
+ /*
+ //+>>>if AC/Battery has an issue please add your message here
+ Strcpy (pOFBDTblEnd , ErrorMsg_1);
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ AC_BatteryPtr->dbRetSts |= OFBD_RS_AC_BAT_ERR ;
+ //<<<
+ */
+ AC_BatteryPtr->dbRetSts |= OFBD_RS_AC_BAT_OK;
+ break;
+
+ default:
+ AC_BatteryPtr->dbRetSts |= OFBD_RS_AC_BAT_OK;
+ break;
+ //
+ // Please add your code here <<<+
+ //
+
+ }
+
+
+#endif // #ifdef BATTERYCHECK_SAMPLE_TEST
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BatteryCheckEntry
+//
+// Description: OFBD Battery Check Header Handle Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BatteryCheckEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_AC_BAT)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_AC_BAT)
+ {
+ if(OFBDBatteryCheck(pOFBDHdr) == EFI_SUCCESS)
+ {
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.cif b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.cif
new file mode 100644
index 0000000..291c5db
--- /dev/null
+++ b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "AC/Battery checking"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\BATTERYCHECK\"
+ RefName = "OFBD_BATTERYCHECK"
+[files]
+"BATTERYCHECK.sdl"
+"BATTERYCHECK.mak"
+"BATTERYCHECK.h"
+"BATTERYCHECK.c"
+<endComponent>
diff --git a/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.h b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.h
new file mode 100644
index 0000000..2903f92
--- /dev/null
+++ b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.h
@@ -0,0 +1,64 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/BATTERYCHECK/BATTERYCHECK.h 1 10/11/12 2:27a Terrylin $
+//
+// $Revision: 1 $
+//
+// $Date: 10/11/12 2:27a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/BATTERYCHECK/BATTERYCHECK.h $
+//
+// 1 10/11/12 2:27a Terrylin
+// Initial check-in for OEM can control AC/Battery status check rule
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: BATTERYCHECK.h
+//
+// Description: Header file for the BATTERYCHECK
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_EC_BATTERY_CHECK_STATUS_H_
+#define _EFI_EC_BATTERY_CHECK_STATUS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.mak b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.mak
new file mode 100644
index 0000000..eb28d80
--- /dev/null
+++ b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.mak
@@ -0,0 +1,68 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/BATTERYCHECK/BATTERYCHECK.mak 1 10/11/12 2:27a Terrylin $
+#
+# $Revision: 1 $
+#
+# $Date: 10/11/12 2:27a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/BATTERYCHECK/BATTERYCHECK.mak $
+#
+# 1 10/11/12 2:27a Terrylin
+# Initial check-in for OEM can control AC/Battery status check rule
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: BATTERYCHECK.mak
+#
+# Description: Make file for the BatteryCheck.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : BATTERYCHECK
+
+BATTERYCHECK : $(BUILD_DIR)\BATTERYCHECK.mak BATTERYCHECKBin
+
+$(BUILD_DIR)\BATTERYCHECK.mak : $(OFBD_BATTERYCHECK_DIR)\$(@B).cif $(OFBD_BATTERYCHECK_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_BATTERYCHECK_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+BATTERYCHECKBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\BATTERYCHECK.mak all\
+ NAME=BATTERYCHECK \
+ TYPE=LIBRARY LIBRARY_NAME=$(BATTERYCHECKLIB)
+
+$(BATTERYCHECKLIB) : BATTERYCHECK
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+
diff --git a/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.sdl b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.sdl
new file mode 100644
index 0000000..2aa5df0
--- /dev/null
+++ b/Core/EM/OFBD/BATTERYCHECK/BATTERYCHECK.sdl
@@ -0,0 +1,55 @@
+TOKEN
+ Name = "AC_BATTERY_CHECK_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable AC/Battery Check support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "BATTERYCHECKLIB"
+ Value = "$(BUILD_DIR)\BATTERYCHECK.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[AC/Battery Check Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "BATTERYCHECK_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test AC/Battery Check Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "AC_BATTERY_CHECK_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "OFBD_BATTERYCHECK_DIR"
+End
+
+MODULE
+ Help = "Includes BATTERYCHECK.mak to Project"
+ File = "BATTERYCHECK.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\BATTERYCHECK.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BatteryCheckEntry,"
+ Parent = "OFBDPartsList"
+ Token = "AC_BATTERY_CHECK_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.c b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.c
new file mode 100644
index 0000000..80889d9
--- /dev/null
+++ b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.c
@@ -0,0 +1,259 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/CleanErrorLog/CleanErrorLog.c 3 10/06/11 1:28a Terrylin $
+//
+// $Revision: 3 $
+//
+// $Date: 10/06/11 1:28a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/CleanErrorLog/CleanErrorLog.c $
+//
+// 3 10/06/11 1:28a Terrylin
+// Fix the build error, when Gpnv Error Logging module didn't enable.
+//
+// 2 3/16/11 10:32p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] CleanErrorLog.mak
+// CleanErrorLog.h
+// CleanErrorLog.c
+//
+// 1 1/17/11 3:56a Terrylin
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CleanErrorLog.c
+//
+// Description:
+// This function is used to Clean Error Log. For example,AFU will call this function to clean error log when
+// /CLNEVNLOG is issued.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include <Protocol\SmiFlash.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "CleanErrorLog.h"
+#include "..\OFBD.h"
+
+//#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+
+EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+EFI_SMI_FLASH_PROTOCOL *mSmiFlash = NULL;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CleanErrorLogCallback
+//
+// Description: Locate SmiFlash protocol callback
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CleanErrorLogCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+
+ pBS->LocateProtocol (&gEfiSmiFlashProtocolGuid, NULL, &mSmiFlash);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CleanErrorLogInSmm
+//
+// Description: OFBD Clear event log InSmm Function
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CleanErrorLogInSmm(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+
+ Status = pBS->LocateProtocol (&gEfiSmiFlashProtocolGuid, NULL, &mSmiFlash);
+ if (EFI_ERROR(Status)){
+ EFI_EVENT SmiFlashCallbackEvt;
+ VOID *Reg;
+ RegisterProtocolCallback(
+ &gEfiSmiFlashProtocolGuid, CleanErrorLogCallback,
+ NULL,&SmiFlashCallbackEvt, &Reg
+ );
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDCleanErrorLogHandle
+//
+// Description: OFBD Clean Gpnv Error Log Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDCleanErrorLogHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if CLEAN_GPNV_ERROR_LOG_SAMPLE_TEST
+
+ UINT8 *pOFBDTblEnd;
+ OFBD_TC_58_CEL_STRUCT *CELStructPtr;
+ #if defined(FV_ERROR_LOGGING_BASE) && defined(FV_ERROR_LOGGING_SIZE)
+ FUNC_BLOCK FuncBlock;
+ UINT8 pType1Header[16];
+ #endif
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ CELStructPtr = (OFBD_TC_58_CEL_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ // Is need to Clean Gpnv Error Log
+ if (CELStructPtr->dwFunSts == OFBD_TC_CEL_FUNC_REQ)
+ {
+ // Check Gpnv Error Logging module whether support or not
+ #if !defined(FV_ERROR_LOGGING_BASE) || !defined(FV_ERROR_LOGGING_SIZE)
+ CELStructPtr->dwRetSts = OFBD_TC_CEL_BIOS_NOT_SUPPORT;
+ #else
+ //
+ // Reference from "ErrorLogging/SmiGpnv/SmiGpnv.c" file code +>>>
+ //
+ // SS: Alaska;$/Alaska/SOURCE/Modules/ErrorLogging;
+ //
+ // Label 4.6.3.6_GPNV_ERRLOG_2.1a
+ //
+ // Enable Flash Write.
+ Status = mSmiFlash->EnableFlashWrite(&FuncBlock);
+ // Read flash to preserve EFI_GPNV_ERROR_HEADER_TYPE1 header.
+ FuncBlock.BufAddr = (UINTN)&pType1Header;
+ FuncBlock.BlockSize = 0x10; // EFI_GPNV_ERROR_HEADER_TYPE1
+ FuncBlock.BlockAddr = ((UINT32)FV_ERROR_LOGGING_BASE & \
+ (FLASH_SIZE - 1)); //0 starts at 0xfff0_0000
+ FuncBlock.ErrorCode = 0;
+ Status = mSmiFlash->ReadFlash(&FuncBlock);
+ // Erase Error Logging GPNV.
+ FuncBlock.BlockSize = FV_ERROR_LOGGING_SIZE; //max size 0xffff
+ FuncBlock.BufAddr = 0;
+ Status = mSmiFlash->EraseFlash(&FuncBlock); // Write Flash
+ // Restore EFI_GPNV_ERROR_HEADER_TYPE1 header.
+ FuncBlock.BlockSize = 0x10; //EFI_GPNV_ERROR_HEADER_TYPE1
+ FuncBlock.BufAddr = (UINTN)&pType1Header;
+ Status = mSmiFlash->WriteFlash(&FuncBlock); // Write Flash
+ // Disable Flash Write.
+ Status = mSmiFlash->DisableFlashWrite(&FuncBlock);
+ //
+ // <<<+
+ //
+ if (EFI_ERROR (Status))
+ CELStructPtr->dwRetSts = OFBD_TC_CEL_ERROR;
+ else
+ CELStructPtr->dwRetSts = OFBD_TC_CEL_OK;
+ #endif
+ }
+
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CleanErrorLogEntry
+//
+// Description: OFBD Clean Gpnv Error Log Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CleanErrorLogEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_58_CEL_STRUCT *CELStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ CELStructPtr = (OFBD_TC_58_CEL_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_ERR_LOG)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_CLN_ERR_LOG)
+ {
+ if(OFBDCleanErrorLogHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM Default Command Configuration Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.cif b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.cif
new file mode 100644
index 0000000..a04fe75
--- /dev/null
+++ b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Clean Gpnv Error Log"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\CleanErrorLog\"
+ RefName = "OFBD_CLEANERRORLOG"
+[files]
+"CleanErrorLog.sdl"
+"CleanErrorLog.mak"
+"CleanErrorLog.h"
+"CleanErrorLog.c"
+<endComponent>
diff --git a/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.h b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.h
new file mode 100644
index 0000000..466a1ff
--- /dev/null
+++ b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.h
@@ -0,0 +1,71 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/CleanErrorLog/CleanErrorLog.h 2 3/16/11 10:32p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:32p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/CleanErrorLog/CleanErrorLog.h $
+//
+// 2 3/16/11 10:32p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] CleanErrorLog.mak
+// CleanErrorLog.h
+// CleanErrorLog.c
+//
+// 1 1/17/11 3:56a Terrylin
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: CleanErrorLog.h
+//
+// Description: Header file for the CleanErrorLog
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_CLEANERRORLOG_H_
+#define _EFI_CLEANERRORLOG_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.mak b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.mak
new file mode 100644
index 0000000..1055d73
--- /dev/null
+++ b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.mak
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/CleanErrorLog/CleanErrorLog.mak 2 3/16/11 10:32p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:32p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/CleanErrorLog/CleanErrorLog.mak $
+#
+# 2 3/16/11 10:32p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] CleanErrorLog.mak
+# CleanErrorLog.h
+# CleanErrorLog.c
+#
+# 1 1/17/11 3:56a Terrylin
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: CleanErrorLog.mak
+#
+# Description: Make file for the CleanErrorLog.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : CLEANERRORLOG
+
+CLEANERRORLOG : $(BUILD_DIR)\CLEANERRORLOG.mak CLEANERRORLOGBin
+
+$(BUILD_DIR)\CLEANERRORLOG.mak : $(OFBD_CLEANERRORLOG_DIR)\$(@B).cif $(OFBD_CLEANERRORLOG_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_CLEANERRORLOG_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CLEANERRORLOGBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\CLEANERRORLOG.mak all\
+ NAME=CLEANERRORLOG \
+ TYPE=LIBRARY LIBRARY_NAME=$(CLEANERRORLOGLIB)
+
+$(CLEANERRORLOGLIB) : CLEANERRORLOG
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+
diff --git a/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.sdl b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.sdl
new file mode 100644
index 0000000..4a26863
--- /dev/null
+++ b/Core/EM/OFBD/CleanErrorLog/CleanErrorLog.sdl
@@ -0,0 +1,63 @@
+TOKEN
+ Name = "CLEAN_ERROR_LOG_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable Clean Gpnv Error Log support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "CLEANERRORLOGLIB"
+ Value = "$(BUILD_DIR)\CLEANERRORLOG.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[Clean Gpnv Error Log Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "CLEAN_GPNV_ERROR_LOG_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test Clean Gpnv Error Log Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "CLEAN_ERROR_LOG_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "OFBD_CLEANERRORLOG_DIR"
+End
+
+MODULE
+ Help = "Includes CleanErrorLog.mak to Project"
+ File = "CleanErrorLog.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\CLEANERRORLOG.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CleanErrorLogEntry,"
+ Parent = "OFBDPartsList"
+ Token = "CLEAN_ERROR_LOG_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CleanErrorLogInSmm,"
+ Parent = "OFBDInSmmFuncList"
+ Token = "CLEAN_ERROR_LOG_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/DEFCFG/DefCfg.c b/Core/EM/OFBD/DEFCFG/DefCfg.c
new file mode 100644
index 0000000..5923a0b
--- /dev/null
+++ b/Core/EM/OFBD/DEFCFG/DefCfg.c
@@ -0,0 +1,269 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/DEFCFG/DefCfg.c 9 8/16/13 3:13a Terrylin $
+//
+// $Revision: 9 $
+//
+// $Date: 8/16/13 3:13a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/DEFCFG/DefCfg.c $
+//
+// 9 8/16/13 3:13a Terrylin
+// [Description] Correct the description error.
+//
+// 8 8/07/13 11:21p Terrylin
+// [Description] Add more description.
+//
+// 7 7/31/13 4:49a Terrylin
+// [TAG] EIP125898
+// [Category] New Feature
+// [Description] Add the AFU's /Kn and /Ln two commands status control.
+//
+// 6 8/06/12 7:00a Terrylin
+// [TAG] EIP96286
+// [Category] Improvement
+// [Description] Add the template codes for SMBIOS module DMI data
+// preserve support.
+// [Files] DefCfg.sdl
+// DefCfg.c
+//
+// 5 2/22/12 4:37a Terrylin
+// Add the GAN command support sample
+//
+// 4 3/16/11 10:37p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] DefCfg.mak
+// DefCfg.h
+// DefCfg.c
+//
+// 3 12/17/10 3:21a Terrylin
+// Fix sample code is wrong problem.
+//
+// 2 6/07/10 11:22p Terrylin
+// Fix sample code is wrong problem.
+//
+// 1 5/06/10 2:22a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DefCfg.c
+//
+// Description:
+// OFBD Default Command Configuration provides BIOS an oppertunity to override end user issued command in AFU.
+//
+// For example, BIOS could disable /k command even user issued it in AFU, or automatically enable /b when /p
+// is issued.
+//
+// For AFU¡¦s "/Ln" and "/Kn" two commands parameter identify. That AFU will replace the OFBD_EXT_TBL_END data
+// from 0xFFFF55AA to OFBD_TC_51_DC_EXT_STRUCT. Therefore, BIOS can through the "ddIndexCfg" flag to identify
+// who is this command structure. (The AFU version 3.05.1 or later supports.)
+//
+// Please reference OFBDDEFCFGHandle for more details.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "DefCfg.h"
+#include "..\OFBD.h"
+
+//#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDDEFCFGHandle
+//
+// Description: OFBD Default Command Configuration Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDDEFCFGHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ UINT8 *pOFBDTblEnd;
+ OFBD_TC_51_DC_STRUCT *DCStructPtr;
+ OFBD_TC_51_DC_EXT_STRUCT *DCExtStructPtr;
+ UINT32 ExtAddr;
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ DCStructPtr = (OFBD_TC_51_DC_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ DCExtStructPtr = (OFBD_TC_51_DC_EXT_STRUCT *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size) - sizeof(OFBD_END));
+ ExtAddr = *(UINT32 *)((UINT8 *)pOFBDTblEnd - sizeof(OFBD_END));
+ if (ExtAddr == OFBD_EXT_TBL_END)
+ DCExtStructPtr = NULL;
+
+#if SMBIOS_DMIEDIT_DATA_LOC == 2
+
+ if ((DCStructPtr->ddRetSts & OFBD_TC_CFG_N) && (DCStructPtr->ddRetSts & OFBD_TC_CFG_R) && (DCStructPtr->ddRetSts & OFBD_TC_CFG_CAPSULE))
+ {
+ EFI_GUID gEfiSmbiosNvramGuid = {0x4b3082a3, 0x80c6, 0x4d7e, { 0x9c, 0xd0, 0x58, 0x39, 0x17, 0x26, 0x5d, 0xf1 }};
+ CHAR16 *PreserveSmbiosNvramVar = L"PreserveSmbiosNvramVar";
+ UINTN Size = sizeof (UINT8);
+ UINT32 PreserveSmbiosNvram;
+
+ // Set PreserveSmbiosNvram
+ pRS->SetVariable (
+ PreserveSmbiosNvramVar,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ Size,
+ &PreserveSmbiosNvram
+ );
+ }
+
+#endif
+
+#if DEF_CFG_SAMPLE_TEST
+ //
+ // OEM add
+ //
+
+ // Sample : always cancel /K command
+ if (DCStructPtr->ddRetSts & OFBD_TC_CFG_K)
+ {
+ DCStructPtr->ddExtCfg |= OFBD_TC_CFG_K;
+ }
+
+ // Sample : add new /B command when /P has issued
+ if (DCStructPtr->ddRetSts & OFBD_TC_CFG_P)
+ {
+ DCStructPtr->ddRetSts |= OFBD_TC_CFG_B;
+ }
+
+ // Sample : For GAN command
+ // If ddRetSts equals to "0xFFFFFFFF", this means BIOS supply "/GAN" command.
+ if (DCStructPtr->ddRetSts & OFBD_TC_CFG_GAN)
+ {
+ DCStructPtr->ddRetSts = 0xFFFFFFFF;
+ }
+
+ // Sample : For /Ln or /Kn command status setting
+ if (DCExtStructPtr)
+ {
+ OFBD_TC_51_DC_EXT_STRUCT *NStructPtr = DCExtStructPtr;
+
+ do
+ {
+ // Check current struct is Ln command or not
+ if (NStructPtr->ddIndexCfg == OFBD_TC_CFG_LN)
+ {
+ // Sample : add new /L1 command when /L0 command is issued
+ if (NStructPtr->ddExtCfg & BIT00)
+ {
+ NStructPtr->ddExtCfg |= BIT01;
+ }
+ }
+
+ // Check current struct is Kn command or not
+ if (NStructPtr->ddIndexCfg == OFBD_TC_CFG_KN)
+ {
+ // Sample : always cancel /K0 command
+ if (NStructPtr->ddExtCfg & BIT00)
+ {
+ NStructPtr->ddIgnCfg |= BIT00;
+ }
+ }
+ // Ponit to next structure
+ NStructPtr++;
+ ExtAddr = *(UINT32 *)NStructPtr;
+ }while(ExtAddr && ExtAddr != 0xFFFFFFFF);
+ }
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DEFCFGEntry
+//
+// Description: OFBD Default Command Configuration Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DEFCFGEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_51_DC_STRUCT *DCStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ DCStructPtr = (OFBD_TC_51_DC_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_CFG)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_AFUDEFCFG)
+ {
+ if(OFBDDEFCFGHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM Default Command Configuration Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/DEFCFG/DefCfg.cif b/Core/EM/OFBD/DEFCFG/DefCfg.cif
new file mode 100644
index 0000000..a4f0d7b
--- /dev/null
+++ b/Core/EM/OFBD/DEFCFG/DefCfg.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "AFU Default Command Configuration"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\DEFCFG\"
+ RefName = "OFBD_DEFCFG"
+[files]
+"DefCfg.sdl"
+"DefCfg.mak"
+"DefCfg.h"
+"DefCfg.c"
+<endComponent>
diff --git a/Core/EM/OFBD/DEFCFG/DefCfg.h b/Core/EM/OFBD/DEFCFG/DefCfg.h
new file mode 100644
index 0000000..06f9cfe
--- /dev/null
+++ b/Core/EM/OFBD/DEFCFG/DefCfg.h
@@ -0,0 +1,72 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/DEFCFG/DefCfg.h 2 3/16/11 10:37p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:37p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/DEFCFG/DefCfg.h $
+//
+// 2 3/16/11 10:37p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] DefCfg.mak
+// DefCfg.h
+// DefCfg.c
+//
+// 1 5/06/10 2:21a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DefCfg.h
+//
+// Description: Header file for the DefCfg
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_DEFCFG_H_
+#define _EFI_DEFCFG_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/DEFCFG/DefCfg.mak b/Core/EM/OFBD/DEFCFG/DefCfg.mak
new file mode 100644
index 0000000..060d5d5
--- /dev/null
+++ b/Core/EM/OFBD/DEFCFG/DefCfg.mak
@@ -0,0 +1,76 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/DEFCFG/DefCfg.mak 2 3/16/11 10:37p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:37p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/DEFCFG/DefCfg.mak $
+#
+# 2 3/16/11 10:37p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] DefCfg.mak
+# DefCfg.h
+# DefCfg.c
+#
+# 1 5/06/10 2:21a Lawrencechang
+# Initial check-in.
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: DefCfg.mak
+#
+# Description: Make file for the DefCfg.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : DEFCFG
+
+DEFCFG : $(BUILD_DIR)\DEFCFG.mak DEFCFGBin
+
+$(BUILD_DIR)\DEFCFG.mak : $(OFBD_DEFCFG_DIR)\$(@B).cif $(OFBD_DEFCFG_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_DEFCFG_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+DEFCFGBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\DEFCFG.mak all\
+ NAME=DEFCFG \
+ TYPE=LIBRARY LIBRARY_NAME=$(DEFCFGLIB)
+
+$(DEFCFGLIB) : DEFCFG
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+
diff --git a/Core/EM/OFBD/DEFCFG/DefCfg.sdl b/Core/EM/OFBD/DEFCFG/DefCfg.sdl
new file mode 100644
index 0000000..d19994f
--- /dev/null
+++ b/Core/EM/OFBD/DEFCFG/DefCfg.sdl
@@ -0,0 +1,56 @@
+TOKEN
+ Name = "DEFCFG_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AFU Default Command Configuration support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "DEFCFGLIB"
+ Value = "$(BUILD_DIR)\DEFCFGLIB.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[AFU Default Command Configuration Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "DEF_CFG_SAMPLE_TEST"
+ Value = "0"
+ Help = "Test AFU Default Command Configuration Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "DEFCFG_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "OFBD_DEFCFG_DIR"
+End
+
+MODULE
+ Help = "Includes DefCfg.mak to Project"
+ File = "DefCfg.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\DEFCFGLIB.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DEFCFGEntry,"
+ Parent = "OFBDPartsList"
+ Token = "DEFCFG_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/MEUD/InitMEUDString.c b/Core/EM/OFBD/MEUD/InitMEUDString.c
new file mode 100644
index 0000000..00c0ac2
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/InitMEUDString.c
@@ -0,0 +1,243 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/InitMEUDString.c 6 11/01/11 2:54a Klzhan $
+//
+// $Revision: 6 $
+//
+// $Date: 11/01/11 2:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/InitMEUDString.c $
+//
+// 6 11/01/11 2:54a Klzhan
+// [TAG] EIP73028
+// [Category] Improvement
+// [Description] Pointer might be used without initial.
+//
+// 5 2/10/11 4:04a Klzhan
+// Improvement : Update output string for SPS FW when disabled ME.
+//
+// 4 12/27/10 3:15a Klzhan
+// Improvement : Output message for Disabled ME setup item.
+//
+// 3 6/10/10 5:54a Klzhan
+// Improvement : Implement Setup call back by Elink.
+//
+// 2 10/30/09 6:43a Klzhan
+// 1. Remove un-used function.
+//
+// 1 10/20/09 3:31a Klzhan
+// Initail check-in.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: InitMEUDString.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "..\OFBD.h"
+#include "MEUD.h"
+#if EFI_SPECIFICATION_VERSION>0x20000
+#include <Protocol/HiiString.h>
+#include <Protocol/HiiDatabase.h>
+#else
+#include <Protocol\Hii.h>
+#endif
+#include <Setup.h>
+#include <Protocol/AMIPostMgr.h>
+
+extern EFI_GUID guidHII;
+#if EFI_SPECIFICATION_VERSION>0x20000
+EFI_STATUS MEUDSetupCallbackFunction(
+ EFI_HII_HANDLE HiiHandle,
+ UINT16 Class,
+ UINT16 SubClass,
+ UINT16 Key);
+#else
+EFI_STATUS MEUDSetupCallbackFunction(
+ IN EFI_FORM_CALLBACK_PROTOCOL *This,
+ IN UINT16 KeyValue,
+ IN EFI_IFR_DATA_ARRAY *Data,
+ OUT EFI_HII_CALLBACK_PACKET **Packet );
+EFI_FORM_CALLBACK_PROTOCOL MEUDSetupCallBack = { NULL,NULL,MEUDSetupCallbackFunction };
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MEUDSetupCallbackFunction
+//
+// Description: TSE Callbeck Function.
+// To make ME enter Disable Mode.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if EFI_SPECIFICATION_VERSION>0x20000
+EFI_STATUS MEUDSetupCallbackFunction(
+ EFI_HII_HANDLE HiiHandle,
+ UINT16 Class,
+ UINT16 SubClass,
+ UINT16 Key)
+#else
+EFI_STATUS MEUDSetupCallbackFunction(
+ IN EFI_FORM_CALLBACK_PROTOCOL *This,
+ IN UINT16 KeyValue,
+ IN EFI_IFR_DATA_ARRAY *Data,
+ OUT EFI_HII_CALLBACK_PACKET **Packet )
+#endif
+{
+ UINTN VariableSize = 1;
+ UINT8 Flag,MsgBoxSel;
+ EFI_GUID gMEUDErrorguid = MEUD_ERROR_GUID;
+ EFI_GUID AmiPostMgrProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+ EFI_STATUS Status;
+ CHAR16 *OutputString = L"Disable ME fail !!";
+
+ IoWrite8(0xB2,Disable_ME_SW_SMI);
+
+ Status = pRS->GetVariable( L"ShowMEUDFailMSG", &gMEUDErrorguid,
+ NULL, &VariableSize, &Flag);
+
+ // In SPS, BIOS doesn't send reset message.
+ // Add message for User to know what happened.
+ if(!EFI_ERROR(Status))
+ {
+ AMI_POST_MANAGER_PROTOCOL *AmiPostMgr = NULL;
+
+ switch(Flag)
+ {
+ case 0:
+#ifdef CSP_SPSUD_SUPPORT
+#if CSP_SPSUD_SUPPORT
+ OutputString = L"ME been Disabled !! Please boot your system to OS for updating ME!!";
+#endif
+#endif
+#ifdef CSP_MEUD_SUPPORT
+#if CSP_MEUD_SUPPORT
+ OutputString = L"ME been Disabled !! Please reboot your system !!";
+#endif
+#endif
+ break;
+
+ default:
+ OutputString = L"Disable ME fail !!";
+ break;
+ }
+ if (!EFI_ERROR(pBS->LocateProtocol
+ (&AmiPostMgrProtocolGuid, NULL, &AmiPostMgr)))
+ {
+ AmiPostMgr->DisplayMsgBox(
+ L"ME Update Info",
+ OutputString,
+ MSGBOX_TYPE_NULL,
+ &MsgBoxSel
+ );
+
+ }
+ }
+
+ return EFI_SUCCESS ;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitMEUDInfo
+//
+// Description: Register a Setup Item CallBack Info.
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle
+// IN UINT16 Class
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitMEUDInfo(EFI_HII_HANDLE HiiHandle, UINT16 Class)
+{
+/*
+ EFI_GUID guidFormCallback = EFI_FORM_CALLBACK_PROTOCOL_GUID;
+ EFI_HANDLE Handle=0;
+ EFI_GUID guidHii = EFI_HII_PROTOCOL_GUID;
+ EFI_HII_PROTOCOL *MEUDHii = NULL;
+ EFI_HII_UPDATE_DATA UpdateData;
+ UINT16 RegData = 0;
+ EFI_STATUS Status;
+
+ if (Class != EXIT_FORM_SET_CLASS)
+ return EFI_NOT_FOUND ;
+
+ Status = pBS->LocateProtocol(&guidHii,NULL,&MEUDHii);
+ if( EFI_ERROR(Status) )
+ {
+ TRACE((0x800,"ERROR=%X Locate HII",Status));
+ }
+
+ // Install a form callback
+ TRACE((0x800,"Installing form callback\n"));
+ if (EFI_ERROR(
+ Status = pBS->InstallProtocolInterface (
+ &Handle,
+ &guidFormCallback,
+ EFI_NATIVE_INTERFACE,
+ &MEUDSetupCallBack
+ )
+ ))
+ {
+ TRACE((0x800,"ERROR=%X - InstallProtocolInterface",Status));
+ }
+
+
+ UpdateData.FormSetUpdate = TRUE; // Flag update pending in FormSet
+ UpdateData.FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) Handle; // Register CallbackHandle data for FormSet
+ UpdateData.FormUpdate = FALSE;
+ UpdateData.FormTitle = 0;
+ UpdateData.DataCount = 0;
+ Status = MEUDHii->UpdateForm(MEUDHii, HiiHandle, (EFI_FORM_LABEL)0x0000, FALSE, &UpdateData);
+ if( EFI_ERROR(Status) )
+ {
+ TRACE((0x800,"ERROR=%X UpdateForm",Status));
+ }
+*/
+ return EFI_SUCCESS;
+
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.c b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.c
new file mode 100644
index 0000000..0c16ea6
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.c
@@ -0,0 +1,519 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.c 3 10/04/11 5:08a Klzhan $
+//
+// $Revision: 3 $
+//
+// $Date: 10/04/11 5:08a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.c $
+//
+// 3 10/04/11 5:08a Klzhan
+// Support update OPR region with auto update.
+//
+// 2 9/09/11 7:25a Klzhan
+// Fix system hang issue.
+//
+// 1 8/30/11 8:17a Klzhan
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AutoUpdate.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/LoadedImage.h>
+#include <Flash.h>
+#include "AutoUpdate.h"
+#include <Protocol/SimpleTextOut.h>
+#include <Core\EM\OFBD\MEUD\MEUD.h>
+
+UINT32 FlashCapacity;
+
+EFI_GUID guidConsoleControl = EFI_CONSOLE_CONTROL_PROTOCOL_GUID;
+EFI_GUID guidLoadedImage = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+
+//defined in Tokens.c
+extern const UINT32 FlashBlockSize;
+
+//defined in CSP_MEUD module
+extern EFI_STATUS GET_FW_VERSION(
+ UINT16 *MeFwVersionData
+);
+extern UINT32 GetHFS(VOID);
+
+extern UINT32 GetFlashCapacity(VOID);
+
+extern EFI_STATUS
+GetRegionOffset(
+ UINT8 Region,
+ UINT32* Offset,
+ UINT32* Length
+);
+
+extern OFBD_TC_55_ME_PROCESS_STRUCT *StructPtr;
+
+extern EFI_STATUS UpdateRegions(
+ UINT8* Buffer,
+ BOOLEAN InSmm
+);
+
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ { 0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93 }
+EFI_GUID gBdsAllDriversConnectedProtocolGuid = \
+ BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID;
+EFI_GUID gMEAUVariableGuid = MEAU_VAR_GUID;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NeedtoUpdate
+//
+// Description: Check ME version.
+//
+// Input:
+// VOID
+//
+// Output:
+// TRUE - Update ME in this BOOT.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+NeedtoUpdate(
+ VOID
+)
+{
+ ME_FW_VERSION Image_MEversion = IMAGE_ME_FW_VERSION, CurrentMEVersion;
+ EFI_STATUS Status;
+
+ if(REFLASH_UPDATE_FORCE)
+ {
+ UINTN SetupVariableSize = 1;
+ UINT8 Data8;
+ Status = pRS->GetVariable (
+ L"MEAU",
+ &gMEAUVariableGuid,
+ NULL,
+ &SetupVariableSize,
+ &Data8);
+
+ // Flag Not Found, just return TRUE
+ if(Status == EFI_NOT_FOUND)
+ return TRUE;
+ }
+ Status = GET_FW_VERSION((UINT16*)&CurrentMEVersion);
+
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ // Check version
+#if ME_UPDATE_DOWNGRADE
+ // Downgrade allow, update when the version is different.
+ if(MemCmp(&Image_MEversion, &CurrentMEVersion, sizeof(ME_FW_VERSION)) == 0)
+ return FALSE;
+ else
+ return TRUE;
+#else
+ // Because parameters in ME verions are words
+ // so check version in 2 parts
+ if(ME_VERSION_VALUE(CurrentMEVersion) < ME_VERSION_VALUE(Image_MEversion))
+ return TRUE;
+
+ if((ME_VERSION_VALUE(CurrentMEVersion) == ME_VERSION_VALUE(Image_MEversion))
+ && (ME_VERSION_VALUE1(CurrentMEVersion) < ME_VERSION_VALUE1(Image_MEversion)))
+ return TRUE;
+
+#endif
+
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetRawImage
+//
+// Description: Find ME binary in FV_MAIN.
+//
+// Input:
+// NameGuid - Guid of FFS need to find.
+// Buffer - Input buffer
+// Size - Size of Input buffer
+//
+// Output:
+// Status
+// Buffer - FFS data
+// Size - Size of Output buffer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetRawImage (
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *Size
+ )
+
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ EFI_HANDLE *HandleBuff;
+ UINT32 AuthenticationStatus;
+
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuff
+ );
+
+ if (EFI_ERROR (Status) || HandleCount == 0) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Find desired image in all Fvs
+ //
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = pBS->HandleProtocol (
+ HandleBuff[Index],
+ &gEfiFirmwareVolumeProtocolGuid,
+ &Fv
+ );
+
+ if (EFI_ERROR (Status)) {
+ if (HandleBuff != NULL) {
+ pBS->FreePool (HandleBuff);
+ }
+
+ return EFI_LOAD_ERROR;
+ }
+ //
+ // Try a raw file
+ //
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+
+ if (!EFI_ERROR (Status)) {
+ break;
+ }
+ }
+
+ if (HandleBuff != NULL) {
+ pBS->FreePool (HandleBuff);
+ }
+
+ if (Index >= HandleCount) {
+
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProgressMEUpdate
+//
+// Description: Do ME update
+//
+// Input:
+// NameGuid - Guid of FFS need to find.
+// Buffer - Input buffer
+// Size - Size of Input buffer
+//
+// Output:
+// Status
+// Buffer - FFS data
+// Size - Size of Output buffer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ProgressMEUpdate(
+ IN UINT8* Buffer,
+ IN UINTN Size
+)
+{
+ EFI_STATUS Status;
+ UINTN SetupVariableSize;
+ UINT8 Data8 = 0;
+ UINT32 TempReg, i;
+ OFBD_TC_55_ME_PROCESS_STRUCT MEProcessStructPtr;
+ CHAR8 String[256];
+ CHAR8* StringBuffer = String;
+ CHAR16 wString[256];
+
+ // Init Global variable
+ MEProcessStructPtr.ddMessageBuffer = (UINT32)StringBuffer;
+ StructPtr = &MEProcessStructPtr;
+
+ FlashCapacity = GetFlashCapacity();
+ if((Size) != FlashCapacity)
+ return;
+
+#ifdef CSP_MEUD_SUPPORT
+#if CSP_MEUD_SUPPORT == 1
+ // For Desktop and Mobile
+ if (((GetHFS() >> 16) & 0x0F) == 0)
+ IoWrite8(SW_SMI_IO_ADDRESS, Disable_ME_SW_SMI);
+ // Comes here, System should be in Disabled mode.
+ // If not, just return
+ if (((GetHFS() >> 16) & 0x0F) != 5)
+ return;
+#endif
+#endif
+
+ // Get ME Region.
+ if(REFLASH_UPDATE_ME)
+ {
+ // Prepare Buffer
+ if(DIRECT_FW_UPDATE)
+ StructPtr->bBlockType = ME_OPR_BLK;
+ else
+ StructPtr->bBlockType = ME_BLK;
+
+ StructPtr->bHandleRequest = BIT02;
+
+ pST->ConOut->OutputString (pST->ConOut,
+ L"ME is updated now ... \r\n");
+
+ pST->ConOut->OutputString (pST->ConOut,
+ L"Please don't shut down or reset system \r\n");
+
+ do{
+ Status = UpdateRegions(Buffer, FALSE);
+ // Request to continue
+ if((StructPtr->UpdateResult & BIT01))
+ StructPtr->bHandleRequest = BIT03;
+
+ // Show string
+ if((StructPtr->UpdateResult & BIT02))
+ {
+ StructPtr->bHandleRequest = BIT03;
+ MemSet(wString, 512, 0);
+ for(i = 0 ; String[i] ; (CHAR8)wString[i] = String[i], i++);
+ wString[i] = 0;
+ pST->ConOut->OutputString (pST->ConOut,wString);
+ pST->ConOut->OutputString (pST->ConOut,L"\r\n");
+ }
+ // End
+ if((StructPtr->UpdateResult & BIT03))
+ break;
+ // TODO : Error Handle
+ }while(1);
+ }
+
+ if(REFLASH_UPDATE_GBE)
+ {
+ // Prepare Buffer
+ StructPtr->bBlockType = GBE_BLK;
+ StructPtr->bHandleRequest = BIT02;
+
+ pST->ConOut->OutputString (pST->ConOut,
+ L"GBE region is updated now ... \r\n");
+
+ Status = UpdateRegions(Buffer, FALSE);
+
+ // Show string
+ if((StructPtr->UpdateResult & BIT02))
+ {
+ StructPtr->bHandleRequest = BIT03;
+ MemSet(wString, 512, 0);
+ for(i = 0 ; String[i] ; (CHAR8)wString[i] = String[i], i++);
+ wString[i] = 0;
+ pST->ConOut->OutputString (pST->ConOut,wString);
+ pST->ConOut->OutputString (pST->ConOut,L"\r\n");
+ }
+ }
+
+ if(REFLASH_UPDATE_MEDS)
+ {
+ // Prepare Buffer
+ StructPtr->bBlockType = GBE_BLK;
+ StructPtr->bHandleRequest = BIT02;
+
+ pST->ConOut->OutputString (pST->ConOut,
+ L"GBE region is updated now ... \r\n");
+
+ Status = UpdateRegions(Buffer, FALSE);
+
+ // Show string
+ if((StructPtr->UpdateResult & BIT02))
+ {
+ StructPtr->bHandleRequest = BIT03;
+ MemSet(wString, 512, 0);
+ for(i = 0 ; String[i] ; (CHAR8)wString[i] = String[i], i++);
+ wString[i] = 0;
+ pST->ConOut->OutputString (pST->ConOut,wString);
+ pST->ConOut->OutputString (pST->ConOut,L"\r\n");
+ }
+ }
+
+ // Update Finish, update Flag
+ if(REFLASH_UPDATE_FORCE)
+ {
+ SetupVariableSize = 1;
+ Status = pRS->SetVariable (
+ L"MEAU",
+ &gMEAUVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS
+ | EFI_VARIABLE_RUNTIME_ACCESS,
+ SetupVariableSize,
+ &Data8);
+ }
+ // Reset System and ME
+ IoWrite32(0xCF8, 0x8000F8AC);
+ TempReg = IoRead32(0xCFC);
+
+ if(!(TempReg & BIT20))
+ {
+ IoWrite32(0xCF8, 0x8000F8AC);
+ IoWrite32(0xCFC, TempReg | BIT20);
+ }
+
+ pRS->ResetSystem( EfiResetCold, EFI_SUCCESS, 0, NULL );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MEAutoUpdate
+//
+// Description: System updaete ME in POST.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+MEAutoUpdate(
+ VOID
+)
+{
+ UINTN Size;
+ EFI_PHYSICAL_ADDRESS ImageLocation;
+ UINT8* ImageBuffer;
+ EFI_STATUS Status;
+ EFI_GUID gMEUDfileguid = MEUD_FILE_GUID;
+
+ if(!NeedtoUpdate())
+ return EFI_SUCCESS;
+
+
+ Size = ME_UPDATE_BINARY_SIZE * 0x100000 / 0x1000;
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiBootServicesData,
+ Size,
+ &ImageLocation );
+
+ ImageBuffer = (UINT8*)ImageLocation;
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Size = Size * 0x1000;
+ Status = GetRawImage (&gMEUDfileguid, &ImageBuffer, &Size);
+
+ ProgressMEUpdate(ImageBuffer, Size);
+
+ pBS->FreePages(ImageLocation, Size );
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AllDriverConnectEvent
+//
+// Description: This routine for reset the TPM Establishment flag.
+//
+// Input: EFI_EVENT - Efi event.
+// VOID* - Image handle.
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+MEAUAllDriverConnectEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ MEAutoUpdate();
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReFlashEntry
+//
+// Description: This is the standard EFI driver entry point called for
+// Recovery flash module initlaization
+// Input: IN EFI_HANDLE ImageHandle - ImageHandle of the loaded driver
+// IN EFI_SYSTEM_TABLE SystemTable - Pointer to the System Table
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AUTOUPDEntry (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_EVENT AllDriverConnectEvent;
+ VOID *Registration;
+
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //---Set up Callback----------------
+ Status = RegisterProtocolCallback ( &gBdsAllDriversConnectedProtocolGuid, \
+ MEAUAllDriverConnectEvent, \
+ NULL, \
+ &AllDriverConnectEvent, \
+ &Registration );
+
+ return EFI_SUCCESS;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.cif b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.cif
new file mode 100644
index 0000000..a32e4ad
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "MEAU"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\MEUD\MEAU"
+ RefName = "AutoUpdate"
+[files]
+"AutoUpdate.sdl"
+"AutoUpdate.mak"
+"AutoUpdate.c"
+"AutoUpdate.dxs"
+"AutoUpdate.h"
+"MERegion.bin"
+<endComponent>
diff --git a/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.dxs b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.dxs
new file mode 100644
index 0000000..b150b49
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.dxs
@@ -0,0 +1,53 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.dxs 1 8/30/11 8:17a Klzhan $
+//
+// $Revision: 1 $
+//
+// $Date: 8/30/11 8:17a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.dxs $
+//
+// 1 8/30/11 8:17a Klzhan
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AutoUpdate.dxs
+//
+// Description: Dependancy expression for the component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.h b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.h
new file mode 100644
index 0000000..00a5718
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.h
@@ -0,0 +1,98 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.h 1 8/30/11 8:17a Klzhan $
+//
+// $Revision: 1 $
+//
+// $Date: 8/30/11 8:17a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.h $
+//
+// 1 8/30/11 8:17a Klzhan
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AutoUpdate.h
+//
+// Description: Header file for component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __AUTOUPDATE__H__
+#define __AUTOUPDATE__H__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#include <Token.h>
+
+// {80E1202E-2697-4264-9CC9-80762C3E5863}
+#define MEAU_VAR_GUID { 0xC87690DC, 0x9005, 0x47EA, 0xAC, 0x34, 0x12, 0xF, 0xD8, 0x36, 0x33, 0x7D}
+
+
+#define MEUD_FILE_GUID \
+{ 0xfeaaa7a6, 0xcb95, 0x4670, 0xb4, 0x99, 0x87, 0x7f, 0xa6, 0xca, 0x6b, 0xae }
+
+#define ME_VERSION_VALUE(a) \
+(UINT32)((a.CoreMajor << 16) + (a.CoreMinor))
+
+#define ME_VERSION_VALUE1(a) \
+(UINT32)((a.CoreBuild << 16) + (a.CorePatch))
+
+#define FLASH_BASE_ADDRESS(a) (UINTN)(0xFFFFFFFF - GetFlashCapacity() + 1 + (UINTN)a)
+
+
+#pragma pack(1)
+typedef struct
+{
+ UINT8 UpdateGBE;
+ UINT8 UpdateME;
+ UINT8 UpdateMEDS;
+ UINT8 ForceME;
+} MEAUTOUpdate;
+
+#pragma pack()
+
+#define MEAUTOUPD_MAIN 1
+#define MEAUTOUPD_FLASH 2
+
+#define FLASH_PROGRESS_KEY 100
+#define FLASH_START_KEY 101
+
+#include <Setup.h>
+ /****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.mak b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.mak
new file mode 100644
index 0000000..dd1d567
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.mak
@@ -0,0 +1,78 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.mak 1 8/30/11 8:17a Klzhan $
+#
+# $Revision: 1 $
+#
+# $Date: 8/30/11 8:17a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/AutoUpdate.mak $
+#
+# 1 8/30/11 8:17a Klzhan
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AutoUpdate.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : MEAUTOUPD
+
+SetupData : MEAUTOUPD
+
+MEAUTOUPD : $(BUILD_DIR)\AutoUpdate.mak MEAUTOUPDBin $(BUILD_DIR)\MERegion.ffs
+
+$(BUILD_DIR)\AutoUpdate.mak : $(MEAUPD_DIR)\$(@B).cif $(MEAUPD_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(MEAUPD_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+MEUDMSG_CFLAGS=$(CFLAGS) \
+ -I $(TSEBIN_DIR)\Inc \
+ -I $(TSEBIN_DIR)\
+
+MEAUTOUPDBin : $(AMIDXELIB) $(FLASHLIB) $(CSP_MEUDLIB) $(BUILD_DIR)\MELib.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AutoUpdate.mak all\
+ GUID=39d1830f-259b-4d7e-b1a3-074135b4c934\
+ ENTRY_POINT=AUTOUPDEntry\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+$(BUILD_DIR)\MERegion.ffs: $(ME_UPDATE_BINARY_FILE)
+ $(MAKE) /$(MAKEFLAGS) /f Core\FFS.mak \
+ GUID=feaaa7a6-cb95-4670-b499-877fa6ca6bae \
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ BINFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.sdl b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.sdl
new file mode 100644
index 0000000..050e758
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/AutoUpdate.sdl
@@ -0,0 +1,103 @@
+TOKEN
+ Name = "ME_AUTO_UPDATE_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable ReFlash support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "MEAUPD_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AutoUpdate.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+MODULE
+ Help = "Includes ReFlash.mak to Project"
+ File = "AutoUpdate.mak"
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_ME"
+ Value = "1"
+ Help = "Enables/Disables update of the NVRAM flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_NVRAM_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DIRECT_FW_UPDATE"
+ Value = "1"
+ Help = "1 = Support Direct ME FW Update , 0 = ME FW full image updated."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "REFLASH_UPDATE_ME" "=" "1"
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_GBE"
+ Value = "1"
+ Help = "Enables/Disables update of the NVRAM flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_NVRAM_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_MEDS"
+ Value = "1"
+ Help = "Enables/Disables update of the NVRAM flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_NVRAM_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_FORCE"
+ Value = "1"
+ Help = "Enables/Disables update of the NVRAM flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_NVRAM_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ME_UPDATE_BINARY_SIZE"
+ Value = "8"
+ TokenType = Integer
+ TargetH = Yes
+ Help = "Size in MB of Image."
+End
+
+TOKEN
+ Name = "ME_UPDATE_BINARY_FILE"
+ Value = "$(MEAUPD_DIR)\MERegion.BIN"
+ Help = "Eaglelake BIOS Authenticated Code Module - Production/Release Version."
+ TokenType = File
+ TargetMAK = Yes
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MERegion.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "IMAGE_ME_FW_VERSION"
+ Value = "{{2},{2},{0},{5}}"
+ TokenType = Expression
+ TargetH = Yes
+ Help = "ME version, {Major, Minor, Patch, Build}."
+End
+
+TOKEN
+ Name = "ME_UPDATE_DOWNGRADE"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Help = "Set to 1, System will auto-update ME even the image in BIOS is old version."
+End
diff --git a/Core/EM/OFBD/MEUD/MEAU/MERegion.bin b/Core/EM/OFBD/MEUD/MEAU/MERegion.bin
new file mode 100644
index 0000000..36bb9c8
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEAU/MERegion.bin
Binary files differ
diff --git a/Core/EM/OFBD/MEUD/MEUD.c b/Core/EM/OFBD/MEUD/MEUD.c
new file mode 100644
index 0000000..1d1cb68
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.c
@@ -0,0 +1,746 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.c 28 5/14/14 1:54a Tristinchou $
+//
+// $Revision: 28 $
+//
+// $Date: 5/14/14 1:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.c $
+//
+// 28 5/14/14 1:54a Tristinchou
+// [TAG] EIP167375
+// [Category] Improvement
+// [Description] Remove the variables' RT attribute
+//
+// 27 5/16/13 4:05a Klzhan
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Fix system hangs when BIOS is not on the top of ROM
+//
+// 26 5/16/13 1:54a Klzhan
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Remove Flash Device Enable/Disable.
+// Report BIOS information to AFU.
+//
+// 25 3/08/12 5:32a Klzhan
+// Report error when CSP_ReportMEInfo return error.
+//
+// 24 8/30/11 4:24a Klzhan
+// Remove Un-use code.
+//
+// 23 8/15/11 5:06a Klzhan
+// Fix can't update Ignition FW.
+//
+// 22 8/05/11 6:44a Klzhan
+// [TAG] EIP63481
+// [Category] Improvement
+// [Description] AFU support commands for each regions update.
+//
+// 21 7/15/11 4:54a Klzhan
+// Remove un used comment.
+//
+// 20 7/15/11 4:52a Klzhan
+// [TAG] EIP60754
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Support Direct FW Update.
+//
+// 19 6/14/11 3:42a Klzhan
+// Support SPS spec to 1.1.
+//
+// 18 5/31/11 5:01a Klzhan
+// [TAG] EIP60991
+// [Category] New Feature
+// [Description] Read whole Flash image.
+//
+// 17 5/09/11 3:55a Klzhan
+// Remove Debug include.
+//
+// 16 5/09/11 3:24a Klzhan
+// Add Setup Item in Advanced Page to select regions to update.
+//
+// 15 4/22/11 5:53a Klzhan
+// Fix Build Error.
+//
+// 14 4/22/11 4:36a Klzhan
+// Add error handler when restore MAC.
+//
+// 13 4/22/11 4:15a Klzhan
+// Resotre MAC address when update GBE.
+//
+// 12 4/22/11 2:30a Klzhan
+// Remove the code related to ME AUTO UPDATE.
+// Add OFBD version control for update ME though OFBD.
+//
+// 11 2/10/11 5:52a Klzhan
+// [TAG] EIP52968
+// [Category] New Feature
+// [Description] Update ME through OFBD not SMIFlash.
+// [Files] MEUD.sdl
+// MEUD.h
+// MEUD.c
+//
+// 10 1/12/11 10:34p Klzhan
+// Fix build error when ME_AUTO_UPDATE is disabled.
+//
+// 9 12/27/10 4:42a Klzhan
+// Improvement : ME auto update.
+//
+// 8 11/16/10 4:38a Klzhan
+// Correct behavior of ME update.
+//
+// 7 11/16/10 1:44a Klzhan
+// Fill all parameters in MEUDStructPtr.
+//
+// 6 11/11/10 4:46a Klzhan
+// Correct error check when report MEInfo.
+//
+// 5 6/10/10 11:25p Klzhan
+// BugFix : FIx Compiler Error when ME_Ignition_FW_MSG_SUPPORT is
+// disabled.
+//
+// 4 6/10/10 4:21a Klzhan
+// Improvement : Correct "ME_IGNITION_FW_MSG_SUPPORT" behavior.
+//
+// 3 11/18/09 5:07a Klzhan
+// Improvement : Restore FlashCapacity after program for AFUWin.
+//
+// 2 10/13/09 3:33a Klzhan
+// Updated for Aptio Source Enhancement.
+//
+// 1 9/30/09 11:15p Lawrencechang
+// Move Intel ME update module part to an independent SS path.
+//
+// 5 8/31/09 9:04a Klzhan
+// Update Procedure name to support Capella.
+//
+// 4 7/10/09 4:19a Klzhan
+// Improvement: Command /ME support flash entire image when Ignition FW.
+//
+// 3 7/03/09 5:04a Klzhan
+// Bug fix: Update ME Ignition FW fail.
+// Severity: Critical
+// Symptom: System will write wrong address when Ignition update.
+// Root Cause: Coding Error
+// Improvement: Add a token for showing ME Ignition status message
+//
+// 2 7/02/09 8:25a Klzhan
+//
+// 1 4/13/09 5:47a Lawrencechang
+// Initial check-in.
+//
+// 1 3/25/05 5:37p Markw
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: MEUD.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "MEUD.h"
+#include "Flash.h"
+#include "..\OFBD.h"
+#include <Protocol\smiflash.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\SmmBase2.h>
+#include "Setup.h"
+
+EFI_SMI_FLASH_PROTOCOL *mSmiFlash;
+UINT32 FlashCapacity;
+// Skip Area, Now there are only 5 regions(FD, ME, GBE, PDR and BIOS)
+
+UINT8 MacAddr[6];
+
+VOID MEUDSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+);
+
+// SMM Nvram Control Protocol Definitions
+typedef
+EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+
+typedef struct{
+ SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables;
+}AMI_NVRAM_CONTROL_PROTOCOL;
+
+AMI_NVRAM_CONTROL_PROTOCOL *gNvramControl = NULL;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LocateNvramControlSmmProtocol
+//
+// Description: Locate NvramControlProtocol
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+AMI_NVRAM_CONTROL_PROTOCOL*
+LocateNvramControlSmmProtocol()
+{
+ EFI_STATUS Status;
+ static EFI_GUID AmiNvramControlProtocolGuid = { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } };
+ EFI_GUID EfiSmmBase2ProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
+ EFI_SMM_BASE2_PROTOCOL *SmmBase2 = NULL;
+ EFI_SMM_SYSTEM_TABLE2 *Smst2 = NULL;
+ EFI_CONFIGURATION_TABLE *Table = NULL;
+ UINTN Count = 0;
+
+ Status = pBS->LocateProtocol( &EfiSmmBase2ProtocolGuid, NULL, &SmmBase2 );
+ if( !EFI_ERROR(Status) )
+ {
+ Status = SmmBase2->GetSmstLocation( SmmBase2, &Smst2 );
+ if( EFI_ERROR(Status) || Smst2 == NULL )
+ return NULL;
+ }
+
+ Table = Smst2->SmmConfigurationTable;
+ Count = Smst2->NumberOfTableEntries;
+
+ for( ; Count ; --Count, ++Table )
+ {
+ if( guidcmp( &Table->VendorGuid, &AmiNvramControlProtocolGuid ) == 0 )
+ return Table->VendorTable;
+ }
+
+ return NULL;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MEUDCallback
+//
+// Description: Locate SmiFlash protocol callback
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MEUDCallback(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+
+ pBS->LocateProtocol (&gEfiSmiFlashProtocolGuid, NULL, &mSmiFlash);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MEUDInSmm
+//
+// Description: OFBD ME Firmware Update InSmm Function
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MEUDInSmm(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+ EFI_GUID gMEUDErrorGuid = MEUD_ERROR_GUID;
+ UINT8 FW_Usage = 0, MeResetFlag;
+ UINT32 VariableAttr;
+ UINTN VariableSize;
+ FlashCapacity = GetFlashCapacity();
+
+ Status = pBS->LocateProtocol (&gEfiSmiFlashProtocolGuid, NULL, &mSmiFlash);
+ if (EFI_ERROR(Status)){
+ EFI_EVENT SmiFlashCallbackEvt;
+ VOID *MEUDReg;
+ RegisterProtocolCallback(
+ &gEfiSmiFlashProtocolGuid, MEUDCallback,
+ NULL,&SmiFlashCallbackEvt, &MEUDReg
+ );
+ }
+
+ gNvramControl = LocateNvramControlSmmProtocol();
+
+ CSP_MEUDInSmm();
+ VariableSize = sizeof(UINT8);
+ Status = pRS->GetVariable( L"MEUpdateResetFlag", &gMEUDErrorGuid,
+ &VariableAttr, &VariableSize, &MeResetFlag);
+
+
+ if((!EFI_ERROR(Status)) && (MeResetFlag == 1))
+ {
+ UINT32 TempReg;
+
+ // Reset ME
+ IoWrite32(0xCF8, 0x8000F8AC);
+ TempReg = IoRead32(0xCFC);
+
+ if(!(TempReg & BIT20))
+ {
+ IoWrite32(0xCF8, 0x8000F8AC);
+ IoWrite32(0xCFC, TempReg | BIT20);
+ }
+
+ // Clear Flag
+ VariableSize = 0;
+ pRS->SetVariable( L"MEUpdateResetFlag", &gMEUDErrorGuid,
+ VariableAttr,
+ VariableSize, &MeResetFlag);
+
+ pRS->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+
+
+ // If HFS is NULL, return.
+#if ME_IGNITION_FW_MSG_SUPPORT
+ if(GetHFS() == 0)
+ return;
+
+ FW_Usage = (GetHFS() >> 24);
+ if(((GetHFS() >> 16) & 0x0F) == 1)
+ // Set A variable as Flag or Link many lib to AMITSE.
+ pRS->SetVariable( L"ShowMEUDFailMSG", &gMEUDErrorGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT8), &FW_Usage);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MEUDEntry
+//
+// Description: OFBD ME Firmware Update Entry point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MEUDEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_55_MEUD_STRUCT *MEUDStructPtr;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 Buffer1, Buffer2;
+ OFBD_TC_55_ME_INFO_STRUCT *MEInfoStructPtr;
+ OFBD_TC_55_ME_PROCESS_STRUCT *MEProcessStructPtr;
+#ifdef CSP_SPSUD_SUPPORT
+#if CSP_SPSUD_SUPPORT
+ UINT8 Timer = 0;
+ UINT8 MeResetFlag = 0;
+ EFI_GUID gMEUDErrorGuid = MEUD_ERROR_GUID;
+#endif
+#endif
+#if (OFBD_VERSION >= 0x0210)
+ UINT32 Length, Offset;
+ BOOLEAN FlashStatus = TRUE;
+ UINT8 *Address;
+ UINT32 Size;
+ UINT8* Data;
+#endif
+ if (*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + \
+ (pOFBDHdr->OFBD_HDR_SIZE));
+ MEUDStructPtr = (OFBD_TC_55_MEUD_STRUCT *)((UINT8 *)pOFBDExtHdr + \
+ sizeof(OFBD_EXT_HDR));
+ MEInfoStructPtr = (OFBD_TC_55_ME_INFO_STRUCT*)MEUDStructPtr;
+ MEProcessStructPtr = (OFBD_TC_55_ME_PROCESS_STRUCT*)MEUDStructPtr;
+
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if (pOFBDHdr->OFBD_FS & OFBD_FS_MEUD)
+ {
+ //Check Type Code ID
+ if (pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_MEUD)
+ {
+ switch (MEUDStructPtr->bSubFunction)
+ {
+ case 0 :
+
+ Status = CSP_ReportMEInfo(0 , \
+ &(MEUDStructPtr->dMERuntimeBase), \
+ &(MEUDStructPtr->dMERuntimeLength));
+
+ MEUDStructPtr->dMEBiosRegionBase = \
+ FlashCapacity - FLASH_SIZE;
+ MEUDStructPtr->dMEBiosRegionLength = (UINT32)FLASH_SIZE;
+
+ if ((FlashCapacity == 0) || EFI_ERROR(Status))
+ {
+ // Fail , Return
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ return;
+ case 3 :
+ Status = CSP_ReportMEInfo(3, \
+ &(MEUDStructPtr->dMERuntimeBase), \
+ &(MEUDStructPtr->dMERuntimeLength));
+
+ MEUDStructPtr->dMEBiosRegionBase = \
+ FlashCapacity - FLASH_SIZE;
+ MEUDStructPtr->dMEBiosRegionLength = (UINT32)FLASH_SIZE;
+
+ // If FlashCapacity == 0, Not support ME Update
+ if (FlashCapacity == 0)
+ {
+ // Fail , Return
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ return;
+ case 1 :
+ // Send this again to check is this suppoet.
+ Status = CSP_ReportMEInfo(0, \
+ &Buffer1, \
+ &Buffer2);
+
+ if (!EFI_ERROR(Status))
+ Status = HMRFPO_ENABLE_MSG();
+
+ if (EFI_ERROR(Status))
+ {
+ // Fail , Return
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ *pOFBDDataHandled = 0xFF;
+ mSmiFlash->FlashCapacity = FlashCapacity;
+ return;
+ case 4 :
+ // Send this again to check is this suppoet.
+ Status = CSP_ReportMEInfo(3, \
+ &Buffer1, \
+ &Buffer2);
+ if (EFI_ERROR(Status))
+ {
+ // Fail , Return
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ *pOFBDDataHandled = 0xFF;
+ mSmiFlash->FlashCapacity = FlashCapacity;
+#if (OFBD_VERSION >= 0x0210)
+ // Get GBE Region for Restore MAC address
+ Status = GetRegionOffset(3, &Offset, &Length);
+
+ // Before Erase, Get mac address
+ if(Length)
+ {
+#if (OFBD_VERSION >= 0x0220)
+ DoNotConvert = TRUE;
+#endif
+ Address = (UINT8*)FLASH_BASE_ADDRESS(Offset);
+ FlashRead(Address, MacAddr, 6);
+#if (OFBD_VERSION >= 0x0220)
+ DoNotConvert = FALSE;
+#endif
+ }
+#endif
+ return;
+ case 2 :
+ Status = HMRFPO_LOCK_MSG();
+ if (EFI_ERROR(Status))
+ {
+ // Fail , Return
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ case 5 :
+ mSmiFlash->FlashCapacity = FLASH_SIZE;
+#if defined (CSP_SPSUD_SUPPORT) && (CSP_SPSUD_SUPPORT == 1)
+/*
+ do{
+ Status = HMRFPO_LOCK_MSG();
+ if(!EFI_ERROR(Status))
+ break;
+ Timer ++;
+ }while(Timer < 3);
+*/
+ //reset ME.
+ MeResetFlag = 1;
+
+ if( gNvramControl )
+ gNvramControl->ShowBootTimeVariables( TRUE );
+ Status = pRS->SetVariable(
+ L"MEUpdateResetFlag",
+ &gMEUDErrorGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE,
+ sizeof(UINT8),
+ &MeResetFlag );
+ if( gNvramControl )
+ gNvramControl->ShowBootTimeVariables( FALSE );
+ if (EFI_ERROR(Status))
+ {
+ // Fail , Return
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+#endif
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ *pOFBDDataHandled = 0xFF;
+ return;
+
+ default :
+ *pOFBDDataHandled = 0xFE;
+ break;
+// =============== OFBD Version 2.1 and AFU version 2.37 or newer ===============
+#if (OFBD_VERSION >= 0x0210)
+ // earse
+ case 6 :
+
+ Size = MEUDStructPtr->ddBlockSize;
+
+ Address = (UINT8*)FLASH_BASE_ADDRESS(MEUDStructPtr->ddBlockAddr);
+
+
+
+ for (; FlashStatus && Size > 0; Address += 0x1000, Size -= 0x1000)
+ {
+ FlashBlockWriteEnable(Address);
+ FlashStatus = FlashEraseBlock(Address);
+ FlashBlockWriteDisable(Address);
+ }
+
+ if(FlashStatus)
+ {
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ }
+ break;
+ // program
+ case 7 :
+ Size = MEUDStructPtr->ddBlockSize;
+ Data = (UINT8*)pOFBDHdr;
+ Status = CSP_ReportMEInfo(3, \
+ &Buffer1,
+ &Buffer2);
+ (UINTN)Address = FLASH_BASE_ADDRESS(MEUDStructPtr->ddBlockAddr);
+ Status = GetRegionOffset(3, &Offset, &Length);
+
+ (UINTN)Data += MEUDStructPtr->ddFlashBufOffset;
+ // Restore MAC Address
+ if((MEUDStructPtr->ddBlockAddr == Offset) && (Length != 0))
+ MemCpy(Data,MacAddr,6);
+
+ FlashDeviceWriteEnable();
+
+ FlashBlockWriteEnable(Address);
+ FlashStatus = FlashProgram(Address, Data, Size);
+ FlashBlockWriteDisable(Address);
+
+ FlashDeviceWriteDisable();
+ if(FlashStatus)
+ {
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ }
+ break;
+
+ // Read
+ case 8 :
+ (UINTN)Address = FLASH_BASE_ADDRESS(MEUDStructPtr->ddBlockAddr);
+ Data = (UINT8*)pOFBDHdr;
+ (UINTN)Data += MEUDStructPtr->ddFlashBufOffset;
+
+ FlashRead(Address, Data, MEUDStructPtr->ddBlockSize);
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ break;
+
+ case 9 :
+ // Get Info
+ {
+ UINT16 TotalBlocks = 0;
+
+ // Get FD
+ Status = GetRegionOffset(0 ,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].StartAddress,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize);
+
+ // Fill FD Info
+ if(!EFI_ERROR(Status))
+ {
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Command,"FDR",4);
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Description,
+ "Flash Flash-Descriptor Region",64);
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Type = FDT_BLK;
+ // Status = 1 means Protect
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Status = 0;
+ TotalBlocks += 1;
+ }
+ // Get GBE
+ Status = GetRegionOffset(3 ,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].StartAddress,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize);
+
+ // Fill GBE Info
+ if(!EFI_ERROR(Status))
+ {
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Command,"GBER",4);
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Description,
+ "Flash GBE Region",64);
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Type = GBE_BLK;
+ // Status = 1 means Protect
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Status = 0;
+ TotalBlocks += 1;
+ }
+
+ // Get PDR
+ Status = GetRegionOffset(4 ,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].StartAddress,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize);
+
+ // Fill PDR Info
+ if(!EFI_ERROR(Status))
+ {
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Command,"PDR",4);
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Description,
+ "Flash PDR Region",64);
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Type = PDR_BLK;
+ // Status = 1 means Protect
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Status = 0;
+ TotalBlocks += 1;
+ }
+
+ // Get ME
+ Status = GetRegionOffset(2 ,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].StartAddress,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize);
+
+ // Fill ME Info
+ if(!EFI_ERROR(Status))
+ {
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Command,"MER",4);
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Description,
+ "Flash Entire ME Region",64);
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Type = ME_BLK;
+ // Status = 1 means Protect
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Status = 0;
+ TotalBlocks += 1;
+ }
+
+ // Get BIOS
+ Status = GetRegionOffset(1 ,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].StartAddress,
+ &MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize);
+
+ // Fill BIOS Info
+ if(!EFI_ERROR(Status))
+ {
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Command,"MER",4);
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Description,
+ "Flash Entire ME Region",64);
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Type = BIOS_BLK;
+ // Status = 1 means Protect
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Status = 0;
+ TotalBlocks += 1;
+ }
+#if defined (CSP_SPSUD_SUPPORT) && (CSP_SPSUD_SUPPORT == 1)
+ //
+ // Fill SPS Partition Info
+ //
+
+ // OPR1
+ MEInfoStructPtr->BlockInfo[TotalBlocks].StartAddress = OPR1_START;
+ MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize = OPR1_LENGTH;
+ // OPR2
+ if(OPR2_LENGTH != 0)
+ MEInfoStructPtr->BlockInfo[TotalBlocks].BlockSize += OPR2_LENGTH;
+
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Command,"OPR",4);
+ MemCpy(MEInfoStructPtr->BlockInfo[TotalBlocks].Description,
+ "Flash Operation Region of SPS",64);
+
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Type = ME_OPR_BLK;
+ // Status = 1 means Protect
+ MEInfoStructPtr->BlockInfo[TotalBlocks].Status = 0;
+ TotalBlocks += 1;
+#endif
+ MEInfoStructPtr->TotalBlocks = TotalBlocks;
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+
+ }
+ break;
+ case 10 :
+ // ME Process Handle
+ // In CSP_MEUD.c
+ MEProcessHandler(&MEProcessStructPtr);
+ *pOFBDDataHandled = 0xFF;
+ MEUDStructPtr->bReturnStatus = OFBD_TC_MEUD_OK;
+ break;
+#endif //#if (OFBD_VERSION >= 0x0210)
+ }// End of Switch
+ }
+
+ }
+
+ }
+ return;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OFBD/MEUD/MEUD.chm b/Core/EM/OFBD/MEUD/MEUD.chm
new file mode 100644
index 0000000..6b977bc
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.chm
Binary files differ
diff --git a/Core/EM/OFBD/MEUD/MEUD.cif b/Core/EM/OFBD/MEUD/MEUD.cif
new file mode 100644
index 0000000..1f91c24
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "On Flash Block Description (APTIO) - Intel ME Update"
+ category = eModule
+ LocalRoot = "Core\EM\OFBD\MEUD\"
+ RefName = "OFBD_MEUD"
+[files]
+"MEUD.sdl"
+"MEUD.mak"
+"MEUD.h"
+"MEUD.c"
+"MEUD_MSG.c"
+"MEUD.uni"
+"MEUD.sd"
+"InitMEUDString.c"
+"MEUD.chm"
+[parts]
+"CSP_MEUD"
+"AutoUpdate"
+<endComponent>
diff --git a/Core/EM/OFBD/MEUD/MEUD.h b/Core/EM/OFBD/MEUD/MEUD.h
new file mode 100644
index 0000000..7485c57
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.h
@@ -0,0 +1,198 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.h 7 5/16/13 2:00a Klzhan $
+//
+// $Revision: 7 $
+//
+// $Date: 5/16/13 2:00a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.h $
+//
+// 7 5/16/13 2:00a Klzhan
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Support OFBD_VERSION is 0x220.
+//
+// 6 9/09/11 7:27a Klzhan
+// Fix build Error when enable MEAU
+//
+// 5 8/05/11 6:43a Klzhan
+// [TAG] EIP63481
+// [Category] New Feature
+// [Description] AFU support commands for each regions update.
+//
+// 4 2/10/11 5:52a Klzhan
+// [TAG] EIP52968
+// [Category] New Feature
+// [Description] Update ME through OFBD not SMIFlash.
+// [Files] MEUD.sdl
+// MEUD.h
+// MEUD.c
+//
+// 3 12/27/10 4:42a Klzhan
+// Improvement : ME auto update.
+//
+// 2 10/13/09 3:33a Klzhan
+// Updated for Aptio Source Enhancement.
+//
+// 1 9/30/09 11:15p Lawrencechang
+// Move Intel ME update module part to an independent SS path.
+//
+// 3 8/31/09 9:03a Klzhan
+// Update Procedure name to support Capella.
+//
+// 2 7/02/09 8:25a Klzhan
+//
+// 1 4/13/09 5:47a Lawrencechang
+// Initial check-in.
+//
+// 1 3/13/06 1:16a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: MEUD.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_MEUD_H_
+#define _EFI_MEUD_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+UINT32 GetFlashCapacity(VOID);
+UINT32 GetHFS(VOID);
+EFI_STATUS HMRFPO_LOCK_MSG(VOID);
+EFI_STATUS HMRFPO_ENABLE_MSG(VOID);
+VOID CSP_MEUDInSmm(VOID);
+EFI_STATUS CSP_ReportMEInfo(UINT8 Func_Num, UINT32* BASE_Address, UINT32* Length);
+EFI_STATUS GET_FW_VERSION(UINT16* MeFwVersionData);
+EFI_STATUS
+GetRegionOffset(
+ IN UINT8 Region,
+ IN OUT UINT32* Offset,
+ IN OUT UINT32* Length
+);
+#if OFBD_VERSION >= 0x220
+extern BOOLEAN DoNotConvert;
+#endif
+
+#define MEUD_ERROR_GUID \
+{ 0x732BD39, 0xD6B0, 0x4039, 0xB6, 0xC2, 0x96, 0x54, 0x46, 0x6D, 0xE5, 0x25 }
+
+#define MEUD_FILE_GUID \
+{ 0xfeaaa7a6, 0xcb95, 0x4670, 0xb4, 0x99, 0x87, 0x7f, 0xa6, 0xca, 0x6b, 0xae }
+
+#define ME_VERSION_VALUE(a) \
+(UINT32)((a.CoreMajor << 16) + (a.CoreMinor))
+
+#define ME_VERSION_VALUE1(a) \
+(UINT32)((a.CoreBuild << 16) + (a.CorePatch))
+
+// Override for new ME.
+#if OFBD_VERSION >= 0x220
+#define FLASH_BASE_ADDRESS(a) (UINTN)((UINT64)a)
+#else
+#define FLASH_BASE_ADDRESS(a) (UINTN)(0xFFFFFFFF - GetFlashCapacity() + 1 + (UINTN)a)
+#endif
+
+#ifdef PCIEX_BASE_ADDRESS
+#define PCIE_CFG_ADDRESS(bus, dev, func, reg) \
+ ((UINTN)(PCIEX_BASE_ADDRESS + ((UINT8)(bus) << 20) + \
+ ((UINT8)(dev) << 15) + ((UINT8)(func) << 12) + (reg)))
+#endif
+#define ME_BLK_PROTECT BIT00
+
+typedef enum
+{
+ FDT_BLK,
+ PDR_BLK,
+ GBE_BLK,
+ ME_BLK,
+ ME_OPR_BLK,
+ BIOS_BLK,
+ MAX_BLK
+}ME_BLOCK_TYPE;
+
+#pragma pack(1)
+typedef struct
+{
+ CHAR8 Command[4];
+ CHAR8 Description[64];
+ UINT32 StartAddress;
+ UINT32 BlockSize;
+ UINT8 Type;
+ UINT8 Status;
+}ME_BLOCK_T;
+
+typedef struct
+{
+ UINT8 bReturnStatus;
+ UINT8 bSubFunction;
+ UINT16 TotalBlocks;
+ ME_BLOCK_T BlockInfo[MAX_BLK];
+}OFBD_TC_55_ME_INFO_STRUCT;
+
+typedef struct
+{
+ UINT8 bReturnStatus;
+ UINT8 bSubFunction;
+ UINT32 TotalBlocks;
+ UINT32 BlockIndex;
+ UINT8 bHandleRequest;
+ UINT8 bBlockType;
+ UINT16 UpdateResult;
+ UINT32 ddMeDataBuffer;
+ UINT32 ddMeDataSize;
+ UINT32 ddMeDataChecksum;
+ UINT32 ddMessageBuffer;
+}OFBD_TC_55_ME_PROCESS_STRUCT;
+
+typedef struct
+{
+ UINT16 CoreMajor;
+ UINT16 CoreMinor;
+ UINT16 CoreBuild;
+ UINT16 CorePatch;
+}ME_FW_VERSION;
+#pragma pack()
+VOID
+MEProcessHandler(
+ IN OUT OFBD_TC_55_ME_PROCESS_STRUCT **MEProcessStructPtr
+);
+ /****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OFBD/MEUD/MEUD.mak b/Core/EM/OFBD/MEUD/MEUD.mak
new file mode 100644
index 0000000..0c8305a
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.mak
@@ -0,0 +1,123 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.mak 9 5/09/11 3:24a Klzhan $
+#
+# $Revision: 9 $
+#
+# $Date: 5/09/11 3:24a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.mak $
+#
+# 9 5/09/11 3:24a Klzhan
+# Add Setup Item in Advanced Page to select regions to update.
+#
+# 8 4/22/11 2:29a Klzhan
+# Remove the code related to ME AUTO UPDATE.
+#
+# 7 12/27/10 4:38a Klzhan
+# Improvement : ME auto update.
+#
+# 6 11/09/10 10:26p Klzhan
+# Fix Build warming.
+#
+# 5 10/30/09 6:40a Klzhan
+# BugFix : Fix compile Fail.
+#
+# 4 10/20/09 3:43a Klzhan
+# Improvement : Replace TSE2.0 callback by formset callback.
+#
+# 3 10/13/09 6:13a Klzhan
+# Improvement : Add a token for ME SECOVR setup item.
+#
+# 2 10/13/09 3:32a Klzhan
+# 1. Support TSE2.0 Exit page callback for ME update(SECOVR_MEI_MSG
+# mode).
+#
+# 1 9/30/09 11:15p Lawrencechang
+# Move Intel ME update module part to an independent SS path.
+#
+# 2 7/02/09 8:25a Klzhan
+#
+# 1 4/13/09 5:47a Lawrencechang
+# Initial check-in.
+#
+# 1 3/18/07 5:23p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: MEUD.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : MEUD
+
+MEUD : $(BUILD_DIR)\MEUD.mak MEUDBin
+
+$(BUILD_DIR)\MEUD.mak : $(OFBD_MEUD_DIR)\$(@B).cif $(OFBD_MEUD_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_MEUD_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+MEUDBin : $(FLASHLIB)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\MEUD.mak all\
+ NAME=MEUD \
+ TYPE=LIBRARY LIBRARY_NAME=$(MEUDLIB)
+
+$(MEUDLIB) : MEUD
+
+#---------------------------------------------------------------------------
+# Compile Password customization file
+#---------------------------------------------------------------------------
+MEUDMSG_CFLAGS=$(CFLAGS) \
+ -I $(TSEBIN_DIR)\Inc \
+ -I $(TSEBIN_DIR)\
+
+AMITSE.mak : $(BUILD_DIR)\$(OFBD_MEUD_DIR)\MEUD_MSG.obj
+
+$(BUILD_DIR)\$(OFBD_MEUD_DIR)\MEUD_MSG.obj : $(OFBD_MEUD_DIR)\MEUD_MSG.c
+ $(CC) $(MEUDMSG_CFLAGS) $(ME_INCLUDES) /Fo$@ $**
+#----------------------------------------------------------------------------
+# Create ME Setup Screens
+#----------------------------------------------------------------------------
+SetupSdbs : $(MELIB) $(BUILD_DIR)\MEUD.mak MEUDSDB
+SetupBin : $(BUILD_DIR)\InitMEUDString.obj
+
+MEUDSDB :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\MEUD.mak all\
+ TYPE=SDB NAME=MEUD STRING_CONSUMERS=$(OFBD_MEUD_DIR)\MEUD.sd
+
+$(BUILD_DIR)\InitMEUDString.obj : $(PROJECT_DIR)\$(OFBD_MEUD_DIR)\InitMEUDString.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(PROJECT_DIR)\$(OFBD_MEUD_DIR)\InitMEUDString.c
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/OFBD/MEUD/MEUD.sd b/Core/EM/OFBD/MEUD/MEUD.sd
new file mode 100644
index 0000000..f551364
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.sd
@@ -0,0 +1,112 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.sd 7 8/30/11 5:38a Klzhan $
+//
+// $Revision: 7 $
+//
+// $Date: 8/30/11 5:38a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD.sd $
+//
+// 7 8/30/11 5:38a Klzhan
+// Remove un-used setup item.
+// SPS FW doesn't need setup item to disabled ME FW.
+//
+// 6 6/14/11 3:43a Klzhan
+// Set Update ME Item to default Enable.
+//
+// 5 5/09/11 3:24a Klzhan
+// Add Setup Item in Advanced Page to select regions to update.
+//
+// 4 11/16/10 4:36a Klzhan
+// Support SPS FW update.
+//
+// 3 5/27/10 3:44a Klzhan
+// Improvement : ME_SECOVR_MEI_MSG_SUPPORT control setup item
+// enable/disable.
+//
+// 2 10/20/09 3:38a Klzhan
+// Improvement : Replace TSE2.0 callback by formset callback.
+//
+// 1 10/13/09 3:28a Klzhan
+// 1. Support TSE2.0 Exit page callback for ME update(SECOVR_MEI_MSG
+// mode).
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: MEUD.sd
+//
+// Description: Setup definition for MEUD.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifdef SETUP_DATA_DEFINITION
+
+#endif
+#ifdef FORM_SET_TYPEDEF
+
+#endif
+
+#ifdef FORM_SET_VARSTORE
+
+#endif
+
+#ifdef ADVANCED_FORM_SET
+#if ME_SECOVR_MEI_MSG_SUPPORT
+#ifdef FORM_SET_GOTO
+ //
+ // this grayout is always false, but ensures that callback function will receive pointer to ICC_VOLATILE_SETUP_DATA instead SETUP_DATA
+ //
+ goto MEUD_FORM_ID,
+ prompt = STRING_TOKEN(STR_MEUD_PROMPT),
+ help = STRING_TOKEN(STR_MEUD_PROMPT_HELP);
+#endif
+
+#ifdef FORM_SET_FORM
+ form formid = AUTO_ID(MEUD_FORM_ID),
+ title = STRING_TOKEN(STR_MEUD_PROMPT);
+
+
+#if defined(CSP_MEUD_SUPPORT) && (CSP_MEUD_SUPPORT == 1)
+ goto MEUD_FORM_ID,
+ prompt = STRING_TOKEN(STR_ME_TODISABLE_MODE_PROMPT),
+ help = STRING_TOKEN(STR_ME_TODISABLE_MODE_PROMPT_HELP),
+ flags = INTERACTIVE,
+ key = AMITSESETUP_KEY;
+#endif
+
+ endform;
+#endif //FORM_SET_FORM
+#endif // ME_SECOVR_MEI_MSG_SUPPORT
+#endif //ADVANCED_FORM_SET
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/OFBD/MEUD/MEUD.sdl b/Core/EM/OFBD/MEUD/MEUD.sdl
new file mode 100644
index 0000000..468a210
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.sdl
@@ -0,0 +1,121 @@
+TOKEN
+ Name = MEUD_SUPPORT
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable ME Ignition Firmware Update support in Project"
+End
+
+TOKEN
+ Name = ME_IGNITION_FW_MSG_SUPPORT
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+ Help = "Enable this Token to Show Ignition FW status during POST"
+End
+
+TOKEN
+ Name = "MEUDLIB"
+ Value = "$(BUILD_DIR)\MEUD.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OFBD ME Firmware Update]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+PATH
+ Name = "OFBD_MEUD_DIR"
+End
+
+MODULE
+ Help = "Includes MEUD.mak to Project"
+ File = "MEUD.mak"
+End
+
+TOKEN
+ Name = ME_SECOVR_MEI_MSG_SUPPORT
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Help = "Support ME update when ME in SECOVR_MEI_MSG mode,MPG or RC please disable this."
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MEUD.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MEUDEntry,"
+ Parent = "OFBDPartsList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "MEUDInSmm,"
+ Parent = "OFBDInSmmFuncList"
+ Token = "MEUD_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ShowMEUDErrors,"
+ Parent = "ProcessConInAvailabilityHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\$(OFBD_MEUD_DIR)\MEUD_MSG.obj"
+ Parent = "AMITSE_Objects"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MEUD.lib"
+ Parent = "MINISETUPLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\MEUD.sdb"
+ Parent = "SETUP_SDBS"
+ Priority = 40
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(OFBD_MEUD_DIR)\MEUD.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 40
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "Disable_ME_SW_SMI"
+ Value = "0x29"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+ELINK
+ Name = "InitMEUDInfo,"
+ Parent = "SetupStringInit"
+ Token = "ME_SECOVR_MEI_MSG_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(ADVANCED_FORM_SET_CLASS,0,AMITSESETUP_KEY,MEUDSetupCallbackFunction),"
+ Parent = "SetupItemCallbacks"
+ Token = "ME_SECOVR_MEI_MSG_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/OFBD/MEUD/MEUD.uni b/Core/EM/OFBD/MEUD/MEUD.uni
new file mode 100644
index 0000000..aad1fc5
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD.uni
Binary files differ
diff --git a/Core/EM/OFBD/MEUD/MEUD_MSG.c b/Core/EM/OFBD/MEUD/MEUD_MSG.c
new file mode 100644
index 0000000..619eb90
--- /dev/null
+++ b/Core/EM/OFBD/MEUD/MEUD_MSG.c
@@ -0,0 +1,119 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD_MSG.c 3 10/20/09 3:44a Klzhan $
+//
+// $Revision: 3 $
+//
+// $Date: 10/20/09 3:44a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Intel ME Update/MEUD_MSG.c $
+//
+// 3 10/20/09 3:44a Klzhan
+// Improvement : Replace TSE2.0 callback by formset callback.
+//
+// 2 10/13/09 3:35a Klzhan
+// 1. Support TSE2.0 Exit page callback for ME update(SECOVR_MEI_MSG
+// mode).
+// 2. Updated for Aptio Source Enhancement.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: MEUD_MSG.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "..\OFBD.h"
+#include "MEUD.h"
+#include <Protocol\SimpleTextOut.h>
+
+extern EFI_BOOT_SERVICES *gBS;
+extern EFI_SYSTEM_TABLE *gST;
+extern EFI_RUNTIME_SERVICES *gRT;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ShowMEUDErrors
+//
+// Description: Show Message on Screen If Ignition FW runs on Factory Default
+//
+// Input:
+// VOID
+//
+// Output: BOOLEAN. Should return TRUE if the screen was used to
+// ask password; FALSE if the screen was not used to ask
+// password.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ShowMEUDErrors(VOID)
+{
+ EFI_GUID gMEUDErrorGuid = MEUD_ERROR_GUID;
+ UINTN DataSize;
+ UINT8 Data;
+ EFI_STATUS Status;
+ DataSize = sizeof(UINT8);
+
+ Status = gRT->GetVariable( L"ShowMEUDFailMSG", &gMEUDErrorGuid,
+ NULL,
+ &DataSize, &Data);
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+
+ gST->ConOut->OutputString(gST->ConOut,
+ L"\n\rMe Ignition FW Data Paritition Usage :" );
+ if(Data & 0x4)
+ gST->ConOut->OutputString(gST->ConOut, \
+ L"[Runtime Image]\n\r" );
+ else
+ gST->ConOut->OutputString(gST->ConOut, \
+ L"[Factory Default]\n\r" );
+
+
+ gST->ConOut->OutputString(gST->ConOut,
+ L"Me Ignition FW Code Paritition Usage :" );
+ if(Data & 0x8)
+ gST->ConOut->OutputString(gST->ConOut, \
+ L"[Runtime Image]\n\r" );
+ else
+ gST->ConOut->OutputString(gST->ConOut, \
+ L"[Factory Default]\n\r" );
+
+ return FALSE;
+
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OFBD/OEMCMD/OEMCMD.c b/Core/EM/OFBD/OEMCMD/OEMCMD.c
new file mode 100644
index 0000000..c7613e3
--- /dev/null
+++ b/Core/EM/OFBD/OEMCMD/OEMCMD.c
@@ -0,0 +1,368 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMCMD/OEMCMD.c 4 4/12/11 10:28p Terrylin $
+//
+// $Revision: 4 $
+//
+// $Date: 4/12/11 10:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMCMD/OEMCMD.c $
+//
+// 4 4/12/11 10:28p Terrylin
+// Fix sample code is wrong problem.
+//
+// 3 3/16/11 10:36p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMCMD.mak
+// OEMCMD.h
+// OEMCMD.c
+//
+// 2 1/26/11 3:52a Terrylin
+// [Category] Improvement
+// [Description] Add /CMD: command description and its sample code.
+//
+// 1 5/06/10 2:23a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMCMD.c
+//
+// Description:
+//By OEMCMD module, OEM engineers define customized commands to extend AFU functions. AFU sends OEM defined commands
+// to BIOS if user issued /oemcmd:<command>. Then BIOS reacts by these customized commands.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "OEMCMD.h"
+#include "..\OFBD.h"
+
+//#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDOEMCMDHandle
+//
+// Description: OFBD OEM CMD Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDOEMCMDHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_CMD_CHECKING_SAMPLE_TEST
+
+ UINT8 *pOFBDTblEnd;
+ UINT8 *pCMDBufferStr;
+ UINT32 ddCMDLength = 0;
+ char *DisOemBFStr = "Sample Message: OEM CMD Before Flash Run is OK !!";
+ char *DisOemAFStr = "Sample Message: OEM CMD After Flash Run is OK !!";
+ char *DisOemBEStr = "Sample Message: OEM CMD Before End Run is OK !!";
+ char *DisOemSFStr = "Sample Message: OEM CMD Start to Flash Run is OK !!";
+
+ OFBD_TC_57_OEM_CMD_STRUCT *OCStructPtr;
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ OCStructPtr = (OFBD_TC_57_OEM_CMD_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ //
+ // OEM add start here >>>+
+ //
+
+ //--------------------------------------------------------------------------------------
+ //
+ // OEM Notice :
+ //
+ // case 1:
+ // OCStructPtr->ddCMD is parse by AFU, according "/OEMCMD:x" to given Hex value.
+ //
+ // case 2:
+ // OCStructPtr->ddCMD is "/CMD:{xxx}" command string offset.
+ // OCStructPtr->ddReserve is command string length.
+ //
+ //--------------------------------------------------------------------------------------
+
+ // IoWrite32(0x1080, OCStructPtr->ddCMD); //debug
+
+ //------------------------------------------------------------------------------------------
+ // Case 1
+ //------------------------------------------------------------------------------------------
+
+ // 01. Before Flash
+ if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_BF) {
+ //--------------------------------------------------------------------------------------
+ //
+ // OEM Command sample definition:
+ //
+ //--------------------------------------------------------------------------------------
+ // Bit 0 : Restart
+ // Bit 1 : Shutdown
+ // Bit 2 : Wait
+ // ...
+ // Bit 5 : No Check AC adapter
+ // Bit 6 : OEM function 01
+ // Bit 7 : OEM function 02
+ // ...
+ //
+ // 01. /OEMCMD:1 , OCStructPtr->ddCMD = 0x1 (Hex). ("Restart")
+ // 02. /OEMCMD:5 , OCStructPtr->ddCMD = 0x5 (Hex). ("Restart" + "Wait")
+ // 03. /OEMCMD:11 , OCStructPtr->ddCMD = 0x11 (Hex). ("No Check AC adapter" + "Restart")
+ // 04. /OEMCMD:A2 , OCStructPtr->ddCMD = 0xA2 (Hex). ("OEM function 02" + "No Check AC adapter" + "Shutdown")
+ // 05. /OEMCMD:123 , OCStructPtr->ddCMD = 0x123(Hex). ...
+ // 06. /OEMCMD:AABB , OCStructPtr->ddCMD = 0xAABB(Hex). ...
+ //--------------------------------------------------------------------------------------
+
+ //
+ // OCStructPtr->ddCMD
+ //
+
+ // Check Bit 0
+ if (OCStructPtr->ddCMD & 0x1) {
+ // Restart code
+ }
+
+ // Check Bit 1
+ if (OCStructPtr->ddCMD >> 1 & 0x1) {
+ // Shutdown code
+ }
+
+ // Check Bit 2
+ if (OCStructPtr->ddCMD >> 2 & 0x1) {
+ // Wait code
+ }
+
+ // Check Bit 5
+ if (OCStructPtr->ddCMD >> 5 & 0x1) {
+ // No Check AC adapter code
+ }
+
+ // Check Bit 7
+ if (OCStructPtr->ddCMD >> 7 & 0x1) {
+ // OEM function 02 code
+ }
+
+ // << debug >>
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemBFStr);
+
+
+ // 02. After Flash
+ } else if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_AF) {
+
+ //
+ // Display OEM String Usage +>>>
+ //
+
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemAFStr);
+
+ //
+ // Display OEM String Usage <<<+
+ //
+
+ // 03. Before End
+ } else if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_BE) {
+
+ // OEM add ...
+
+ // << debug >>
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemBEStr);
+
+ } else if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_SF) {
+ // << debug >>
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemSFStr);
+
+ }
+
+ //------------------------------------------------------------------------------------------
+ // Case 2
+ //------------------------------------------------------------------------------------------
+ // 05. Before Flash
+ if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_BUF) {
+ //--------------------------------------------------------------------------------------
+ //
+ // OEM Command sample definition:
+ //
+ //--------------------------------------------------------------------------------------
+ //
+ // 01. /CMD:{123} , OCStructPtr->ddCMD = 0x400(Hex), OCStructPtr->ddReserve = 3 (Bytes)
+ // 02. /CMD:{Reset} , OCStructPtr->ddCMD = 0x400(Hex), OCStructPtr->ddReserve = 5 (Bytes)
+ // 03. /CMD:{NoVer} , OCStructPtr->ddCMD = 0x400(Hex), OCStructPtr->ddReserve = 5 (Bytes)
+ // 04. /CMD:{NoAC} , OCStructPtr->ddCMD = 0x400(Hex), OCStructPtr->ddReserve = 4 (Bytes)
+ // 05. /CMD:{Battery} , OCStructPtr->ddCMD = 0x400(Hex), OCStructPtr->ddReserve = 7 (Bytes)
+ // 06. /CMD:{NoAc Battery NoVer} , OCStructPtr->ddCMD = 0x400(Hex), OCStructPtr->ddReserve = 18 (Bytes)
+ //--------------------------------------------------------------------------------------
+
+ //
+ // Get Command String Offset
+ //
+
+ pCMDBufferStr = (UINT8 *)((UINT8 *)pOFBDHdr + (OCStructPtr->ddCMD));
+
+
+ //
+ // Get Command String Length
+ //
+
+ ddCMDLength = OCStructPtr->ddReserve;
+
+ // << debug >>
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemBFStr);
+
+
+ // 06. After Flash
+ } else if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_BUF_AF) {
+
+ //
+ // Display OEM String Usage +>>>
+ //
+
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemAFStr);
+
+ //
+ // Display OEM String Usage <<<+
+ //
+
+ // 07. Before End
+ } else if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_BUF_BE) {
+
+ // OEM add ...
+
+ // << debug >>
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemBEStr);
+
+ } else if (OCStructPtr->dwFlaSts == OFBD_TC_OEM_CMD_BUF_SF) {
+ // << debug >>
+ // set oem string flag for AFU to know
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ // copy the oem string ptr for AFU
+ Strcpy((char *)pOFBDTblEnd, DisOemSFStr);
+
+ }
+
+ //
+ // OEM add start here <<<+
+ //
+
+ // Setting Return Status is '1' for AFU to know OFBD has supported OEM CMD module.
+ OCStructPtr->dwRetSts = 1;
+
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMCMDEntry
+//
+// Description: OFBD OEM CMD CHECKING Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OEMCMDEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_57_OEM_CMD_STRUCT *OCStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ OCStructPtr = (OFBD_TC_57_OEM_CMD_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_OEM_CMD)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_OEM_CMD)
+ {
+ if(OFBDOEMCMDHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM CMD CHECKING Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OEMCMD/OEMCMD.cif b/Core/EM/OFBD/OEMCMD/OEMCMD.cif
new file mode 100644
index 0000000..6491426
--- /dev/null
+++ b/Core/EM/OFBD/OEMCMD/OEMCMD.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "OEM CMD Checking"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\OEMCMD\"
+ RefName = "OFBD_OEMCMD"
+[files]
+"OEMCMD.sdl"
+"OEMCMD.mak"
+"OEMCMD.h"
+"OEMCMD.c"
+<endComponent>
diff --git a/Core/EM/OFBD/OEMCMD/OEMCMD.h b/Core/EM/OFBD/OEMCMD/OEMCMD.h
new file mode 100644
index 0000000..a92d5e6
--- /dev/null
+++ b/Core/EM/OFBD/OEMCMD/OEMCMD.h
@@ -0,0 +1,72 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMCMD/OEMCMD.h 2 3/16/11 10:36p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:36p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMCMD/OEMCMD.h $
+//
+// 2 3/16/11 10:36p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMCMD.mak
+// OEMCMD.h
+// OEMCMD.c
+//
+// 1 5/06/10 2:23a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMCMD.h
+//
+// Description: Header file for the OEMCMD
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OEMCMD_H_
+#define _EFI_OEMCMD_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OEMCMD/OEMCMD.mak b/Core/EM/OFBD/OEMCMD/OEMCMD.mak
new file mode 100644
index 0000000..8cb2617
--- /dev/null
+++ b/Core/EM/OFBD/OEMCMD/OEMCMD.mak
@@ -0,0 +1,74 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OEMCMD/OEMCMD.mak 2 3/16/11 10:36p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:36p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OEMCMD/OEMCMD.mak $
+#
+# 2 3/16/11 10:36p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] OEMCMD.mak
+# OEMCMD.h
+# OEMCMD.c
+#
+# 1 5/06/10 2:23a Lawrencechang
+# Initial check-in.
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OEMCMD.mak
+#
+# Description: Make file for the OEMCMD.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : OEMCMD
+
+OEMCMD : $(BUILD_DIR)\OEMCMD.mak OEMCMDBin
+
+$(BUILD_DIR)\OEMCMD.mak : $(OFBD_OEMCMD_DIR)\$(@B).cif $(OFBD_OEMCMD_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_OEMCMD_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OEMCMDBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OEMCMD.mak all\
+ NAME=OEMCMD \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEMCMDLIB)
+
+$(OEMCMDLIB) : OEMCMD
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
diff --git a/Core/EM/OFBD/OEMCMD/OEMCMD.sdl b/Core/EM/OFBD/OEMCMD/OEMCMD.sdl
new file mode 100644
index 0000000..43be6ca
--- /dev/null
+++ b/Core/EM/OFBD/OEMCMD/OEMCMD.sdl
@@ -0,0 +1,56 @@
+TOKEN
+ Name = "OEMCMD_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable OEM CMD Checking support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEMCMDLIB"
+ Value = "$(BUILD_DIR)\OEMCMD.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OEM CMD Checking Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_CMD_CHECKING_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test OEM CMD CHECKING Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEMCMD_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "OFBD_OEMCMD_DIR"
+End
+
+MODULE
+ Help = "Includes OEMCMD.mak to Project"
+ File = "OEMCMD.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMCMD.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OEMCMDEntry,"
+ Parent = "OFBDPartsList"
+ Token = "OEMCMD_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.c b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.c
new file mode 100644
index 0000000..f995c2e
--- /dev/null
+++ b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.c
@@ -0,0 +1,233 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMOAHandle/OEMOAHandle.c 1 10/24/11 3:03a Terrylin $
+//
+// $Revision: 1 $
+//
+// $Date: 10/24/11 3:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMOAHandle/OEMOAHandle.c $
+//
+// 1 10/24/11 3:03a Terrylin
+// Add for EIP 66385
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemOAHandle.c
+//
+// Description:
+//
+// This function is used for OEM can receive the OA data, and then decide what to do.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include <Protocol\SmiFlash.h>
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "OemOAHandle.h"
+#include "..\OFBD.h"
+
+//#define CONVERT_TO_STRING(a) #a
+#define STR(a) CONVERT_TO_STRING(a)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDOemOADataHandle
+//
+// Description: OFBD Oem OA Data Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDOemOADataHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_OA_DATA_HANDLE_SAMPLE_TEST
+
+ char *TestOemOAStr = " [DBG] OA function is called !!";
+
+ UINT8 *pOFBDTblEnd;
+ OFBD_TC_5A_OA_HANDLE_STRUCT *OAStructPtr;
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ OAStructPtr = (OFBD_TC_5A_OA_HANDLE_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ //
+ // OA Structure Description:
+ //
+ /*
+ UINT8 dbOASts; // Bit 0: Notification BIOS, utility is now ready to update the OA data. - OFBD_TC_OA_UPDATE_NOTIFY
+ // Bit 1~7: Reserved
+
+ UINT8 dbErrorID; // 0~255 : Filled by O.E.M.
+
+ UINT16 dwRetSts; // Bit 0: OA data is invalid, tell the utility stop the flash procedure - OFBD_RS_OA_DATA_IS_INVALID
+ // Bit 1: OA data has been modified, tell the utility use the new data to update - OFBD_RS_OA_DATA_IS_MODIFIED
+ // Bit 2: BIOS has updated the OA, so tell the utility doesn't to update - OFBD_RS_OA_UPDATE_SKIPPED
+ // Bit 3: BIOS doesn't allow the OA update, tell the utility stop the flash procedure - OFBD_RS_OA_UPDATE_DECLINED
+ // Bit 4~14: Reserved
+ // Bit 15: Use dbErrorID field for utility return OEM specific error code, when this Bit is set to 1. - OFBD_RS_OA_USE_OEM_ERROR_ID
+ UINT32 ddOABlockAddr; // OA Block Address of BIOS ROM (For NCB mode to use)
+ UINT64 ddOADataBuffer; // OA Data Buffer
+ UINT32 dwOADataSize; // OA Data Buffer Size
+ */
+
+ //
+ // Please add your code here +>>>
+ //
+ if (OAStructPtr->dbOASts == OFBD_TC_OA_UPDATE_NOTIFY)
+ {
+ //
+ // Please set the dwRetSts for utility to know the process is success or fail
+ //
+
+ //
+ // Case 1: OA Data is invalid
+ //
+
+ // OAStructPtr->dwRetSts = OFBD_RS_OA_DATA_IS_INVALID;
+
+
+ //
+ // Case 2: OA Data has been modified, tell the utility use the new data to update
+ //
+
+ // OAStructPtr->dwRetSts = OFBD_RS_OA_DATA_IS_MODIFIED;
+
+
+ //
+ // Case 3: BIOS has updated the OA, so tell the utility doesn't to update
+ //
+
+ // OAStructPtr->dwRetSts = OFBD_RS_OA_UPDATE_SKIPPED;
+
+
+ //
+ // Case 4: BIOS doesn't allow the OA update, tell the utility stop the flash procedure
+ //
+
+ // OAStructPtr->dwRetSts = OFBD_RS_OA_UPDATE_DECLINED;
+
+
+ //
+ // Case X: OEM want to use their error code definition for /A update command status
+ //
+
+
+ // Step 1: Set Bit 15 to 1
+ //
+ // OAStructPtr->dwRetSts = OFBD_RS_OA_USE_OEM_ERROR_ID;
+ //
+ // Step 2: Use dbErrorID field for utility return OEM specific error code
+ //
+ // OAStructPtr->dbErrorID = 0~255;
+
+
+ //
+ // Tell the utility to show the OEM message, if needed. +>>>
+ //
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ Strcpy((char *)pOFBDTblEnd, TestOemOAStr);
+ //
+ // <<<+
+ //
+
+ }
+
+ //
+ // Please add your code here <<<+
+ //
+
+#endif // #ifdef OEM_OA_DATA_HANDLE_SAMPLE_TEST
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OemOAHandleEntry
+//
+// Description: OFBD Oem OA Data Handle Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemOAHandleEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_5A_OA_HANDLE_STRUCT *OAStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ OAStructPtr = (OFBD_TC_5A_OA_HANDLE_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_OA)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_OA_HANDLE)
+ {
+ if(OFBDOemOADataHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //Oem OA Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.cif b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.cif
new file mode 100644
index 0000000..07aadc1
--- /dev/null
+++ b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "OEM OA Data Handle"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\OEMOAHandle\"
+ RefName = "OFBD_OA_DATA_HANDLE"
+[files]
+"OEMOAHandle.sdl"
+"OEMOAHandle.mak"
+"OEMOAHandle.h"
+"OEMOAHandle.c"
+<endComponent>
diff --git a/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.h b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.h
new file mode 100644
index 0000000..a816d2c
--- /dev/null
+++ b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.h
@@ -0,0 +1,64 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMOAHandle/OEMOAHandle.h 1 10/24/11 3:02a Terrylin $
+//
+// $Revision: 1 $
+//
+// $Date: 10/24/11 3:02a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMOAHandle/OEMOAHandle.h $
+//
+// 1 10/24/11 3:02a Terrylin
+// Add for EIP 66385
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemOAHandle.h
+//
+// Description: Header file for the OemOAHandle
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OEMOAHANDLE_H_
+#define _EFI_OEMOAHANDLE_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.mak b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.mak
new file mode 100644
index 0000000..54563e0
--- /dev/null
+++ b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.mak
@@ -0,0 +1,68 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OEMOAHandle/OEMOAHandle.mak 1 10/24/11 3:02a Terrylin $
+#
+# $Revision: 1 $
+#
+# $Date: 10/24/11 3:02a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OEMOAHandle/OEMOAHandle.mak $
+#
+# 1 10/24/11 3:02a Terrylin
+# Add for EIP 66385
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OemOAHandle.mak
+#
+# Description: Make file for the OemOAHandle.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : OEMOAHANDLE
+
+OEMOAHANDLE : $(BUILD_DIR)\OEMOAHANDLE.mak OEMOAHANDLEBin
+
+$(BUILD_DIR)\OEMOAHANDLE.mak : $(OFBD_OEM_OA_HANDLE_DIR)\$(@B).cif $(OFBD_OEM_OA_HANDLE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_OEM_OA_HANDLE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OEMOAHANDLEBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OEMOAHANDLE.mak all\
+ NAME=OEMOAHANDLE \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEMOAHANDLELIB)
+
+$(OEMOAHANDLELIB) : OEMOAHANDLE
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+
diff --git a/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.sdl b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.sdl
new file mode 100644
index 0000000..7e8a474
--- /dev/null
+++ b/Core/EM/OFBD/OEMOAHandle/OEMOAHandle.sdl
@@ -0,0 +1,56 @@
+TOKEN
+ Name = "OEM_OA_DATA_HANDLE_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable OEM OA Data Handle support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEMOAHANDLELIB"
+ Value = "$(BUILD_DIR)\OEMOAHANDLE.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OEM OA Data Handle Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_OA_DATA_HANDLE_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test OEM OA Data Handle Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_OA_DATA_HANDLE_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "OFBD_OEM_OA_HANDLE_DIR"
+End
+
+MODULE
+ Help = "Includes OemOAHandle.mak to Project"
+ File = "OemOAHandle.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMOAHANDLE.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemOAHandleEntry,"
+ Parent = "OFBDPartsList"
+ Token = "OEM_OA_DATA_HANDLE_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.c b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.c
new file mode 100644
index 0000000..99afa2a
--- /dev/null
+++ b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.c
@@ -0,0 +1,250 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMPWDCK/OEMPwdCk.c 2 3/16/11 10:34p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:34p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMPWDCK/OEMPwdCk.c $
+//
+// 2 3/16/11 10:34p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMPwdCk.mak
+// OEMPwdCk.c
+// OEMPwdCk.h
+//
+// 1 4/13/09 5:47a Lawrencechang
+// Initial check-in.
+//
+// 1 3/25/05 5:37p Markw
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMPwdCk.c
+//
+// Description:
+// Password Check protocol is for BIOS to indicate AFU that BIOS password exists and needs to initiate password
+// checking before flashing BIOS. AFU will set OEM_PC_CK in dbGetCkSts field and send OFBD data to BIOS to report
+// password checking is required or not.
+//
+// If password check function is requested then BIOS should fill out password length in dwPwdLen field. Afterward AFU
+// asks user to input password with specified password length given from BIOS in field dwPwdLen and fill user input
+// password in memory buffer after signature of OFBD_EXT_TBL_END for BIOS to do the comparison.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "OEMPwdCk.h"
+#include "..\OFBD.h"
+
+static int ErrorNum = 0;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDPwdGetHandle
+//
+// Description: OFBD Password Get Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDPwdGetHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_PWDCK_SAMPLE_TEST
+ char *DisOemStrPwd1 = "Password";
+ char *DisOemStrPwd2 = "Password Retry count exceeded!";
+ UINT8 *pOFBDTblEnd;
+ OFBD_TC_52_PC_STRUCT *PwdCkStructPtr;
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ PwdCkStructPtr = (OFBD_TC_52_PC_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ PwdCkStructPtr->dbRetSts = OEM_RS_PC_REQ;
+ PwdCkStructPtr->dwPwdLen = 7;
+ if(ErrorNum < PASSWORD_RETRY_NUM)
+ {
+ //pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ //Strcpy((char *)pOFBDTblEnd, DisOemStrPwd1);
+ }
+ else
+ {
+ PwdCkStructPtr->dbRetSts |= OEM_RS_PC_TIMES_EXCEEDED;
+ //pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ //Strcpy((char *)pOFBDTblEnd, DisOemStrPwd2);
+ }
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDPwdCheckHandle
+//
+// Description: OFBD Password Check Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDPwdCheckHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_PWDCK_SAMPLE_TEST
+ char *DisOemStrPwdOK = "Password Comparison successes!";
+ char *DisOemStrPwdErr = "Password Comparison error!";
+ char *DisOemStrPwdErr2 = "Password Retry count exceeded!";
+ char *Password = "0123456";
+ UINT8 *pOFBDTblEnd;
+ OFBD_TC_52_PC_STRUCT *PwdCkStructPtr;
+
+ PwdCkStructPtr = (OFBD_TC_52_PC_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ if(!MemCmp(pOFBDTblEnd, Password, PwdCkStructPtr->dwPwdLen))
+ {
+ PwdCkStructPtr->dbRetSts |= OEM_RS_PC_CK_OK;
+ //pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ //Strcpy((char *)pOFBDTblEnd, DisOemStrPwdOK);
+ }
+ else
+ {
+ ErrorNum++;
+ PwdCkStructPtr->dbRetSts |= 0;
+ if(ErrorNum < PASSWORD_RETRY_NUM)
+ {
+ //pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ //Strcpy((char *)pOFBDTblEnd, DisOemStrPwdErr);
+ }
+ else
+ {
+ PwdCkStructPtr->dbRetSts |= OEM_RS_PC_TIMES_EXCEEDED;
+ //pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ //Strcpy((char *)pOFBDTblEnd, DisOemStrPwdErr2);
+ }
+ }
+
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDEntryPoint
+//
+// Description: OFBD OEM Password CHECK Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OEMPWDCKEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_52_PC_STRUCT *PwdCkStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ PwdCkStructPtr = (OFBD_TC_52_PC_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ //TRACE((-1,"pOFBDHdr address is:%x ------\n",pOFBDHdr));
+ //TRACE((-1,"pOFBDTblEnd address is:%x ------\n",*(UINT64 *)((UINT8 *)pOFBDTblEnd -sizeof(OFBD_END))));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_PWD)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_PWD)
+ {
+ //IoWrite32(0x300, *(UINT32 *)((UINT8 *)pOFBDTblEnd -4)); //debug
+ if(PwdCkStructPtr->dbGetCkSts == OFBD_TC_OPC_GET)
+ {
+ if(OFBDPwdGetHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM ROM ID Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ else if(PwdCkStructPtr->dbGetCkSts == OFBD_TC_OPC_CHECK)
+ {
+ if(OFBDPwdCheckHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM ROM ID Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ /*//Not OEM ROM ID Data.
+ *pOFBDDataHandled = 0;
+ return;*/
+ }
+ //else
+ //{
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ //}
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.cif b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.cif
new file mode 100644
index 0000000..080fa36
--- /dev/null
+++ b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "OEM Password Checking"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\OEMPWDCK\"
+ RefName = "OFBD_OEMPWDCK"
+[files]
+"OEMPwdCk.sdl"
+"OEMPwdCk.mak"
+"OEMPwdCk.c"
+"OEMPwdCk.h"
+<endComponent>
diff --git a/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.h b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.h
new file mode 100644
index 0000000..a53a8fc
--- /dev/null
+++ b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.h
@@ -0,0 +1,74 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMPWDCK/OEMPwdCk.h 2 3/16/11 10:34p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:34p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMPWDCK/OEMPwdCk.h $
+//
+// 2 3/16/11 10:34p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMPwdCk.mak
+// OEMPwdCk.c
+// OEMPwdCk.h
+//
+// 1 4/13/09 5:47a Lawrencechang
+// Initial check-in.
+//
+// 1 3/13/06 1:16a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMPwdCk.h
+//
+// Description: Header file for the OEMPwdCk
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OEMPWDCK_H_
+#define _EFI_OEMPWDCK_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.mak b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.mak
new file mode 100644
index 0000000..2926ec5
--- /dev/null
+++ b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.mak
@@ -0,0 +1,76 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OEMPWDCK/OEMPwdCk.mak 2 3/16/11 10:34p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:34p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OEMPWDCK/OEMPwdCk.mak $
+#
+# 2 3/16/11 10:34p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] OEMPwdCk.mak
+# OEMPwdCk.c
+# OEMPwdCk.h
+#
+# 1 4/13/09 5:47a Lawrencechang
+# Initial check-in.
+#
+# 1 3/18/07 5:23p Felixp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OEMPwdCk.mak
+#
+# Description: Make file for the OEMPwdCk.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : OEMPWDCK
+
+OEMPWDCK : $(BUILD_DIR)\OEMPwdCk.mak OEMPWDCKBin
+
+$(BUILD_DIR)\OEMPwdCk.mak : $(OFBD_OEMPWDCK_DIR)\$(@B).cif $(OFBD_OEMPWDCK_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_OEMPWDCK_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OEMPWDCKBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OEMPwdCk.mak all\
+ NAME=OEMPWDCK \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEMPWDCKLIB)
+
+$(OEMPWDCKLIB) : OEMPWDCK
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
diff --git a/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.sdl b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.sdl
new file mode 100644
index 0000000..0d3a8d7
--- /dev/null
+++ b/Core/EM/OFBD/OEMPWDCK/OEMPwdCk.sdl
@@ -0,0 +1,65 @@
+TOKEN
+ Name = "OEMPWDCK_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable OEM Password Checking support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEMPWDCKLIB"
+ Value = "$(BUILD_DIR)\OEMPWDCK.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OFBD OEM Password Checking]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_PWDCK_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test Supervisor password checking Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PASSWORD_RETRY_NUM"
+ Value = "3"
+ Help = "Password Retry Num."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_PWDCK_SAMPLE_TEST" "=" "1"
+End
+
+PATH
+ Name = "OFBD_OEMPWDCK_DIR"
+End
+
+MODULE
+ Help = "Includes OEMPwdCk.mak to Project"
+ File = "OEMPwdCk.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMPWDCK.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OEMPWDCKEntry,"
+ Parent = "OFBDPartsList"
+ Token = "OEMPWDCK_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.c b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.c
new file mode 100644
index 0000000..a129d72
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.c
@@ -0,0 +1,253 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMROMHOLE/OEMROMHOLE.c 3 3/16/11 10:33p Terrylin $
+//
+// $Revision: 3 $
+//
+// $Date: 3/16/11 10:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMROMHOLE/OEMROMHOLE.c $
+//
+// 3 3/16/11 10:33p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMROMHOLE.mak
+// OEMROMHOLE.c
+// OEMROMHOLE.h
+//
+// 2 1/11/10 4:00a Lawrencechang
+// Solve compiling warning about type casting from UINTN to UINT16.
+//
+// 1 12/16/09 12:51a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMROMHOLE.c
+//
+// Description:
+// Unlike the same name module in CORE8. Due to AFUAPTIO has ability to identify ROM hole location and size in ROM
+// file. This function is only used to provide AFU the messages to show on screen if user tries to flash sesitive data
+// in ROM hole.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "OEMROMHOLE.h"
+#include "..\OFBD.h"
+
+static UINT16 dwOFBDTblEndOffset = 0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDOemStrHandle
+//
+// Description: OFBD OEM STRING Handle
+//
+// This routine will output the OEM String message to the flash utility.
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// IN char *OEMSTR
+// IN EFI_GUID *ROMHOLEGUID
+// IN BOOLEAN IsAppend
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDOemStrHandle(
+ IN OUT OFBD_HDR *pOFBDHdr,
+ IN char *OEMSTR,
+ IN EFI_GUID * ROMHOLEGUID,
+ IN BOOLEAN IsAppend)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ OFBD_TC_50_RH_STRUCT *RomHoleStructPtr;
+ UINT8 *pOFBDTblEnd;
+
+ RomHoleStructPtr = (OFBD_TC_50_RH_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+
+ if (MemCmp(&(RomHoleStructPtr->HoleGuid), ROMHOLEGUID, sizeof(EFI_GUID)) == 0)
+ {
+ if (IsAppend == 0 && dwOFBDTblEndOffset > 0) {
+ Strcpy((char *)pOFBDTblEnd+dwOFBDTblEndOffset, "\n");
+ dwOFBDTblEndOffset += (UINT16)Strlen("\n");
+ Strcpy((char *)pOFBDTblEnd+dwOFBDTblEndOffset, OEMSTR);
+ }else
+ Strcpy((char *)pOFBDTblEnd+dwOFBDTblEndOffset, OEMSTR);
+ dwOFBDTblEndOffset += (UINT16)Strlen(OEMSTR);
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ }
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDRomHoleCheckHandle
+//
+// Description: OFBD Rom Hole Check Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDRomHoleCheckHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ //
+ // About OEM RomHole Message, PLEASE FOLLOW BELOW 3 Steps TO DO. +>>> <OEM_STR>
+ //
+#if OEM_ROM_HOLE_SAMPLE_TEST
+
+ OFBD_TC_50_RH_STRUCT *RHPtr;
+//
+// Step 1: Add your RomHole OEM string message for AFU to display
+//
+ char *DisOemStr0Protect = "RomHole 0 is Protected!";
+ char *DisOemStr0Program = "RomHole 0 is Programming!";
+ char *DisOemStr1Protect = "RomHole 1 is Protected!";
+ char *DisOemStr1Program = "RomHole 1 is Programming!";
+ char *DisOemStrNewLine = "After next line ";
+ char *DisOemStrAppend = "& Test!";
+//
+// Step 2: Add your RomHole GUID definition here for AFU to compare
+//
+// For example :
+// EFI_GUID gEfiRomHoleX = OEM_ROM_HOLE_X_GUID; // Specific Rom Hole X Guid
+//
+// Notice: X range should be 0~7. ( Max of 8 RomHole support )
+//
+ EFI_GUID gEfiRomHole0 = OEM_ROM_HOLE_0_GUID; // Specific Rom Hole 0 Guid
+ EFI_GUID gEfiRomHole1 = OEM_ROM_HOLE_1_GUID; // Specific Rom Hole 1 Guid
+
+ // --------------------------------------------------------------------------------------------------
+ // DO NOT MODIFY +>>>>
+ // --------------------------------------------------------------------------------------------------
+ RHPtr = (OFBD_TC_50_RH_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ dwOFBDTblEndOffset = 0;
+ // --------------------------------------------------------------------------------------------------
+ // DO NOT MODIFY <<<<+
+ // --------------------------------------------------------------------------------------------------
+
+//
+// Step 3: Define your RomHole message to the corresponding AFU commands.
+//
+// Notice: OFBD_TC_CFG_XXX reference from OFBD.H file (Type Code 51 Return Status)
+//
+ //
+ // Sample 1: AFU issued the /Hole command to update the specific Rom Hole
+ //
+ if (RHPtr->ddExtCmd == OFBD_TC_CFG_ROMHOLE)
+ {
+ // Display the OEM message
+ OFBDOemStrHandle(pOFBDHdr, DisOemStr0Program, &gEfiRomHole0, 0);
+ OFBDOemStrHandle(pOFBDHdr, DisOemStr1Program, &gEfiRomHole1, 0);
+ }
+ //
+ // Sample 2: AFU issued the /P or /B command to update the FV_MAIN or FV_BB region (default the Rom Hole is been protected.)
+ //
+ if (RHPtr->ddExtCmd == OFBD_TC_CFG_P || RHPtr->ddExtCmd == OFBD_TC_CFG_B)
+ {
+ // Display the OEM message
+ OFBDOemStrHandle(pOFBDHdr, DisOemStr0Protect, &gEfiRomHole0, 0);
+ OFBDOemStrHandle(pOFBDHdr, DisOemStr1Protect, &gEfiRomHole1, 0);
+ OFBDOemStrHandle(pOFBDHdr, DisOemStrNewLine, &gEfiRomHole0, 0);
+ OFBDOemStrHandle(pOFBDHdr, DisOemStrAppend, &gEfiRomHole0, 1);
+ }
+
+#endif // #if OEM_ROM_HOLE_SAMPLE_TEST
+ // About OEM RomHole Message, PLEASE FOLLOW ABOVE 3 Steps TO DO. <<<+ <OEM_STR>
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMROMHOLEEntry
+//
+// Description: OFBD OEM ROM HOLE Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OEMROMHOLEEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_ROMH)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_ROMHOLE)
+ {
+ if(OFBDRomHoleCheckHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM ROM HOLE Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.cif b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.cif
new file mode 100644
index 0000000..c22a98a
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "OEM ROM HOLE Checking"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\OEMROMHOLE\"
+ RefName = "OFBD_OEMROMHOLE"
+[files]
+"OEMROMHOLE.sdl"
+"OEMROMHOLE.mak"
+"OEMROMHOLE.c"
+"OEMROMHOLE.h"
+<endComponent>
diff --git a/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.h b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.h
new file mode 100644
index 0000000..5ab9f62
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.h
@@ -0,0 +1,72 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMROMHOLE/OEMROMHOLE.h 2 3/16/11 10:33p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMROMHOLE/OEMROMHOLE.h $
+//
+// 2 3/16/11 10:33p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMROMHOLE.mak
+// OEMROMHOLE.c
+// OEMROMHOLE.h
+//
+// 1 12/16/09 12:50a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMROMHOLE.h
+//
+// Description:Header file for the OEMROMHOLE
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OEMROMHOLE_H_
+#define _EFI_OEMROMHOLE_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.mak b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.mak
new file mode 100644
index 0000000..368350f
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.mak
@@ -0,0 +1,74 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OEMROMHOLE/OEMROMHOLE.mak 2 3/16/11 10:33p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:33p $
+##*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OEMROMHOLE/OEMROMHOLE.mak $
+#
+# 2 3/16/11 10:33p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] OEMROMHOLE.mak
+# OEMROMHOLE.c
+# OEMROMHOLE.h
+#
+# 1 12/16/09 12:50a Lawrencechang
+# Initial check-in.
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OEMROMHOLE.mak
+#
+# Description: Make file for the OEMROMHOLE.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : OEMROMHOLE
+
+OEMROMHOLE : $(BUILD_DIR)\OEMROMHOLE.mak OEMROMHOLEBin
+
+$(BUILD_DIR)\OEMROMHOLE.mak : $(OFBD_OEMROMHOLE_DIR)\$(@B).cif $(OFBD_OEMROMHOLE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_OEMROMHOLE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OEMROMHOLEBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OEMROMHOLE.mak all\
+ NAME=OEMROMHOLE \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEMROMHOLELIB)
+
+$(OEMROMHOLELIB) : OEMROMHOLE
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
diff --git a/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.sdl b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.sdl
new file mode 100644
index 0000000..5fc97b1
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMHOLE/OEMROMHOLE.sdl
@@ -0,0 +1,76 @@
+TOKEN
+ Name = "OEMROMHOLE_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable OEM ROM HOLE Checking support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEMROMHOLELIB"
+ Value = "$(BUILD_DIR)\OEMROMHOLE.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OEM ROM HOLE Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_ROM_HOLE_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test OEM ROM HOLE Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEMROMHOLE_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ROM_HOLE_0_GUID"
+ Value = "{0x05ca01fc, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8}"
+ Help = "OEM ROM HOLE 0 GUID."
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+ Token = "OEM_ROM_HOLE_SAMPLE_TEST" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ROM_HOLE_1_GUID"
+ Value = "{0x05ca01fd, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8}"
+ Help = "OEM ROM HOLE 1 GUID."
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+ Token = "OEM_ROM_HOLE_SAMPLE_TEST" "=" "1"
+End
+
+PATH
+ Name = "OFBD_OEMROMHOLE_DIR"
+End
+
+MODULE
+ Help = "Includes OEMROMHOLE.mak to Project"
+ File = "OEMROMHOLE.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMROMHOLE.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OEMROMHOLEEntry,"
+ Parent = "OFBDPartsList"
+ Token = "OEMROMHOLE_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/OEMROMID/OEMROMID.c b/Core/EM/OFBD/OEMROMID/OEMROMID.c
new file mode 100644
index 0000000..3fdae23
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMID/OEMROMID.c
@@ -0,0 +1,220 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMROMID/OEMROMID.c 2 3/16/11 10:35p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:35p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMROMID/OEMROMID.c $
+//
+// 2 3/16/11 10:35p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMROMID.mak
+// OEMROMID.h
+// OEMROMID.c
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 3/25/05 5:37p Markw
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMROMID.c
+//
+// Description:
+// OEM Rom ID Check protocol is for Flash utility to send customer defined specific ROM ID for BIOS to ID version
+// checking uses.
+//
+// BIOS should provide inserted ROM file's specific ROM ID location and then check it, when ID is given by Flash
+// Utility after OFBD_EXT_TBL_END.
+//
+// Moreover, Flash utility will have corresponding action, either stop flashing BIOS.
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "OEMROMID.h"
+#include "..\OFBD.h"
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDORIGetHandle
+//
+// Description: OFBD OEM ROM ID Get Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDORIGetHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_ROM_ID_SAMPLE_TEST
+ OFBD_TC_53_ORI_STRUCT *ORIStructPtr;
+ ORIStructPtr = (OFBD_TC_53_ORI_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ ORIStructPtr->dwRetSts = OFBD_TC_ORI_REQ + OFBD_TC_ORI_ROM;
+ ORIStructPtr->ddStartAddrLow = OEM_ROM_ID_Address;
+ ORIStructPtr->ddSize = OEM_ROM_ID_SIZE;
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDORICheckHandle
+//
+// Description: OFBD OEM ROM ID Check Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDORICheckHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_ROM_ID_SAMPLE_TEST
+ UINT8 *pOFBDTblEnd;
+ char *DisOemStrOK = "Sample Message: OEM ROM ID Check OK";
+ char *DisOemStrFail = "Sample Message: OEM ROM ID Check Fail";
+ UINT32 OIDLengthMajMin = 0x0c; // hard coded
+
+ pOFBDTblEnd = (UINT8 *)((UINT8 *)pOFBDHdr + (pOFBDHdr->OFBD_Size));
+ if(*(UINT32 *)(pOFBDTblEnd + OIDLengthMajMin) >= OEM_ROM_ID_SUB)
+ {
+ pOFBDHdr->OFBD_RS |= OFBD_RS_DIS_OEMSTR;
+ //pOFBDHdr->OFBD_RS |= 0; //comparison passed and do nothing
+ Strcpy((char *)pOFBDTblEnd, DisOemStrOK);
+ }
+ else
+ {
+ pOFBDHdr->OFBD_RS |= OFBD_RS_ERR_OUT + OFBD_RS_DIS_OEMSTR;
+ //pOFBDHdr->OFBD_RS |= 0; //comparison failed and do nothing
+ Strcpy((char *)pOFBDTblEnd, DisOemStrFail);
+ }
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDEntryPoint
+//
+// Description: OFBD OEM ROMID CHECK Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OEMROMIDEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_53_ORI_STRUCT *ORIStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ ORIStructPtr = (OFBD_TC_53_ORI_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ //TRACE((-1,"pOFBDHdr address is:%x ------\n",pOFBDHdr));
+ //TRACE((-1,"pOFBDTblEnd address is:%x ------\n",*(UINT64 *)((UINT8 *)pOFBDTblEnd -sizeof(OFBD_END))));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_ORI)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_ORI)
+ {
+ //IoWrite32(0x300, *(UINT32 *)((UINT8 *)pOFBDTblEnd -4)); //debug
+ if(ORIStructPtr->dwGetCkSts == OFBD_TC_ORI_GET)
+ {
+ if(OFBDORIGetHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM ROM ID Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ else if(ORIStructPtr->dwGetCkSts == OFBD_TC_ORI_CHECK)
+ {
+ if(OFBDORICheckHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM ROM ID Data Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ /*//Not OEM ROM ID Data.
+ *pOFBDDataHandled = 0;
+ return;*/
+ }
+ //else
+ //{
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ //}
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OEMROMID/OEMROMID.cif b/Core/EM/OFBD/OEMROMID/OEMROMID.cif
new file mode 100644
index 0000000..a6c9f68
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMID/OEMROMID.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "OEM ROM ID Checking"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\OEMROMID\"
+ RefName = "OFBD_OEMROMID"
+[files]
+"OEMROMID.sdl"
+"OEMROMID.mak"
+"OEMROMID.h"
+"OEMROMID.c"
+<endComponent>
diff --git a/Core/EM/OFBD/OEMROMID/OEMROMID.h b/Core/EM/OFBD/OEMROMID/OEMROMID.h
new file mode 100644
index 0000000..2432de7
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMID/OEMROMID.h
@@ -0,0 +1,74 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMROMID/OEMROMID.h 2 3/16/11 10:35p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:35p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMROMID/OEMROMID.h $
+//
+// 2 3/16/11 10:35p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMROMID.mak
+// OEMROMID.h
+// OEMROMID.c
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 3/13/06 1:16a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMROMID.h
+//
+// Description: Header file for the OEMROMID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OEMROMID_H_
+#define _EFI_OEMROMID_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OEMROMID/OEMROMID.mak b/Core/EM/OFBD/OEMROMID/OEMROMID.mak
new file mode 100644
index 0000000..08ab4cc
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMID/OEMROMID.mak
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OEMROMID/OEMROMID.mak 2 3/16/11 10:35p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:35p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OEMROMID/OEMROMID.mak $
+#
+# 2 3/16/11 10:35p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] OEMROMID.mak
+# OEMROMID.h
+# OEMROMID.c
+#
+# 1 4/13/09 5:46a Lawrencechang
+# Initial check-in.
+#
+# 1 3/18/07 5:23p Felixp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OEMROMID.mak
+#
+# Description: Make file for the OEMROMID.obj
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : OEMROMID
+
+OEMROMID : $(BUILD_DIR)\OEMROMID.mak OEMROMIDBin
+
+$(BUILD_DIR)\OEMROMID.mak : $(OFBD_OEMROMID_DIR)\$(@B).cif $(OFBD_OEMROMID_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_OEMROMID_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OEMROMIDBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OEMROMID.mak all\
+ NAME=OEMROMID \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEMROMIDLIB)
+
+$(OEMROMIDLIB) : OEMROMID
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/OFBD/OEMROMID/OEMROMID.sdl b/Core/EM/OFBD/OEMROMID/OEMROMID.sdl
new file mode 100644
index 0000000..043df08
--- /dev/null
+++ b/Core/EM/OFBD/OEMROMID/OEMROMID.sdl
@@ -0,0 +1,102 @@
+TOKEN
+ Name = "OEMROMID_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable OEM ROM ID Checking support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEMROMIDLIB"
+ Value = "$(BUILD_DIR)\OEMROMID.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OEM ROM ID Sample Code Section]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_ROM_ID_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test OEM ROM ID Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OEM_ROM_ID_Address"
+ Value = "083000h"
+ Help = "OEM ROM ID Address."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ROM_ID_SAMPLE_TEST" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ROM_ID_MAJOR"
+ Value = "ORI_AAAA"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ROM_ID_SAMPLE_TEST" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ROM_ID_MINOR"
+ Value = "K101"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ROM_ID_SAMPLE_TEST" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ROM_ID_SUB"
+ Value = "00001h"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ROM_ID_SAMPLE_TEST" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ROM_ID_SIZE"
+ Value = "10h"
+ Help = "OEM ROM ID Length depends on size of Major, Minor, Sub version IDs."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ROM_ID_SAMPLE_TEST" "=" "1"
+End
+
+PATH
+ Name = "OFBD_OEMROMID_DIR"
+End
+
+MODULE
+ Help = "Includes OEMROMID.mak to Project"
+ File = "OEMROMID.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMROMID.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OEMROMIDEntry,"
+ Parent = "OFBDPartsList"
+ Token = "OEMROMID_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/OEMSETUP/OEMSETUP.c b/Core/EM/OFBD/OEMSETUP/OEMSETUP.c
new file mode 100644
index 0000000..398c8ab
--- /dev/null
+++ b/Core/EM/OFBD/OEMSETUP/OEMSETUP.c
@@ -0,0 +1,361 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMSETUP/OEMSETUP.c 3 3/16/11 10:33p Terrylin $
+//
+// $Revision: 3 $
+//
+// $Date: 3/16/11 10:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMSETUP/OEMSETUP.c $
+//
+// 3 3/16/11 10:33p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMSETUP.mak
+// OEMSETUP.h
+// OEMSETUP.c
+//
+// 2 5/06/10 2:12a Lawrencechang
+// Add the DMI store/restore function sample code.
+//
+// 1 4/13/09 5:47a Lawrencechang
+// Initial check-in.
+//
+// 1 3/25/05 5:37p Markw
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMSETUP.c
+//
+// Description:
+// Basically this function is not always necessary for all projects, because there is a more direct method to achieve
+// the same target. Two E-Links exposed by SMIFlash module, SMIFlashPreUpdateList and SMIFlashEndUpdateList, are made
+// for doing the same thing as this OFBD module.
+//
+// We prefer you make use of E-Links than this OFBD module. The only advantage of this OFBD module is you don't have
+// to link your code with SMIFlash module.If DMI data is stored in the NVRAM, you have two ways to preserve DMI data
+// when updating NVRAM.
+//
+// 1. Controlled by SMBIOS module: SMBIOS module can set SMBIOS_PRESERVE_NVRAM token to preserves DMI data through
+// e-Link PreserveDmiEditData and RestoreDmiEditData.
+//
+// 2. Controlled By Flash utility: AFU will call into OEMSETUP.c only when user issues /r or /sp command. When
+// SMBIOS_PRESERVE_NVRAM token is disable, OEM enginner can set OEMSETUP_SUPPORT token to handle the duty of DMI data
+// preservation through OEM NVRAM/Setup Variable Preserve module. Thus user can decide to clear DMI data or not.
+// In this case, /n parameter will clear NVRAM, and /r parameter is required to preserve DMI data in NVRAM. When /n is
+// triggered, without /r all DMI data in NVRAM will be cleared.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "OEMSETUP.h"
+#include "..\OFBD.h"
+
+// EIP 37169 ->
+#if (SMBIOS_DMIEDIT_DATA_LOC == 2) && (SMBIOS_PRESERVE_NVRAM != 1)
+VOID PreserveDmiEditData (VOID);
+VOID RestoreDmiEditData (VOID);
+#endif
+// <- EIP 37169
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDSETUPSupportHandle
+//
+// Description: OFBD SETUP Store/Restore Support Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDSETUPSupportHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_SETUP_SAMPLE_TEST
+ OFBD_TC_56_SETUP_STRUCT *SETUPStructPtr;
+ SETUPStructPtr = (OFBD_TC_56_SETUP_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_OK;
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDSETUPStoreHandle
+//
+// Description: OFBD SETUP Store Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDSETUPStoreHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_SETUP_SAMPLE_TEST || OEM_DMI_SAMPLE_TEST
+ OFBD_TC_56_SETUP_STRUCT *SETUPStructPtr;
+ SETUPStructPtr = (OFBD_TC_56_SETUP_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ //OEM add ...
+
+ if (!EFI_ERROR(Status))
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_OK;
+ else
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_STORE_ERROR;
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDSETUPRestoreHandle
+//
+// Description: OFBD SETUP Restore Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDSETUPRestoreHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_SETUP_SAMPLE_TEST
+ OFBD_TC_56_SETUP_STRUCT *SETUPStructPtr;
+ SETUPStructPtr = (OFBD_TC_56_SETUP_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ //OEM add ...
+
+ if (!EFI_ERROR(Status))
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_OK;
+ else
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_RESTORE_ERROR;
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDDMIStoreHandle
+//
+// Description: OFBD DMI Data Store Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDDMIStoreHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_DMI_SAMPLE_TEST
+ OFBD_TC_56_SETUP_STRUCT *SETUPStructPtr;
+ SETUPStructPtr = (OFBD_TC_56_SETUP_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ // OEM add ...
+ // Store the DMI data
+// EIP 37169 ->
+#if (SMBIOS_DMIEDIT_DATA_LOC == 2) && (SMBIOS_PRESERVE_NVRAM != 1)
+ PreserveDmiEditData ();
+#endif
+// <- EIP 37169
+
+ if (!EFI_ERROR(Status))
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_OK;
+ else
+ SETUPStructPtr->dbRetSts = OFBD_TC_DMI_STORE_ERROR;
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDDMIRestoreHandle
+//
+// Description: OFBD DMI Data Restore Handle
+//
+// Input:
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDDMIRestoreHandle(
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if OEM_DMI_SAMPLE_TEST
+ OFBD_TC_56_SETUP_STRUCT *SETUPStructPtr;
+ SETUPStructPtr = (OFBD_TC_56_SETUP_STRUCT *)((UINT8 *)pOFBDHdr + pOFBDHdr->OFBD_HDR_SIZE + sizeof(OFBD_EXT_HDR));
+
+ // OEM add ...
+ // Restore the DMI data
+// EIP 37169 ->
+#if (SMBIOS_DMIEDIT_DATA_LOC == 2) && (SMBIOS_PRESERVE_NVRAM != 1)
+ RestoreDmiEditData ();
+#endif
+// <- EIP 37169
+
+ if (!EFI_ERROR(Status))
+ SETUPStructPtr->dbRetSts = OFBD_TC_SETUP_OK;
+ else
+ SETUPStructPtr->dbRetSts = OFBD_TC_DMI_RESTORE_ERROR;
+#endif
+
+ return(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OEMSETUPEntry
+//
+// Description: OFBD NVRAM/SETUP Store/Restore Entry point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OEMSETUPEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_56_SETUP_STRUCT *SETUPStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ SETUPStructPtr = (OFBD_TC_56_SETUP_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_SETUP)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_SETUP)
+ {
+ //IoWrite32(0x300, *(UINT32 *)((UINT8 *)pOFBDTblEnd -4)); //debug
+ if(SETUPStructPtr->dbGetSts == OFBD_TC_SETUP_SUPPORT)
+ {
+ if(OFBDSETUPSupportHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM SETUP SUPPORT Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ else if(SETUPStructPtr->dbGetSts == OFBD_TC_SETUP_STORE)
+ {
+ if(OFBDSETUPStoreHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM SETUP STORE Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ else if(SETUPStructPtr->dbGetSts == OFBD_TC_SETUP_RESTORE)
+ {
+ if(OFBDSETUPRestoreHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM SETUP RESTORE Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ else if(SETUPStructPtr->dbGetSts == OFBD_TC_DMI_STORE)
+ {
+ if(OFBDDMIStoreHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM DMI STORE Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ else if(SETUPStructPtr->dbGetSts == OFBD_TC_DMI_RESTORE)
+ {
+ if(OFBDDMIRestoreHandle(pOFBDHdr) == EFI_SUCCESS)
+ {
+ //OEM DMI RESTORE Handled.
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ }
+ }
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OEMSETUP/OEMSETUP.cif b/Core/EM/OFBD/OEMSETUP/OEMSETUP.cif
new file mode 100644
index 0000000..712b31a
--- /dev/null
+++ b/Core/EM/OFBD/OEMSETUP/OEMSETUP.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "OEM NVRAM/Setup Variable Preserve"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\OEMSETUP\"
+ RefName = "OFBD_OEMSETUP"
+[files]
+"OEMSETUP.sdl"
+"OEMSETUP.mak"
+"OEMSETUP.h"
+"OEMSETUP.c"
+<endComponent>
diff --git a/Core/EM/OFBD/OEMSETUP/OEMSETUP.h b/Core/EM/OFBD/OEMSETUP/OEMSETUP.h
new file mode 100644
index 0000000..3ab063a
--- /dev/null
+++ b/Core/EM/OFBD/OEMSETUP/OEMSETUP.h
@@ -0,0 +1,74 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OEMSETUP/OEMSETUP.h 2 3/16/11 10:33p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OEMSETUP/OEMSETUP.h $
+//
+// 2 3/16/11 10:33p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] OEMSETUP.mak
+// OEMSETUP.h
+// OEMSETUP.c
+//
+// 1 4/13/09 5:47a Lawrencechang
+// Initial check-in.
+//
+// 1 3/13/06 1:16a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OEMSETUP.h
+//
+// Description: Header file for the OEMSETUP
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OEMSETUP_H_
+#define _EFI_OEMSETUP_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OEMSETUP/OEMSETUP.mak b/Core/EM/OFBD/OEMSETUP/OEMSETUP.mak
new file mode 100644
index 0000000..5a84667
--- /dev/null
+++ b/Core/EM/OFBD/OEMSETUP/OEMSETUP.mak
@@ -0,0 +1,87 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OEMSETUP/OEMSETUP.mak 3 3/16/11 10:33p Terrylin $
+#
+# $Revision: 3 $
+#
+# $Date: 3/16/11 10:33p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OEMSETUP/OEMSETUP.mak $
+#
+# 3 3/16/11 10:33p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] OEMSETUP.mak
+# OEMSETUP.h
+# OEMSETUP.c
+#
+# 2 5/06/10 2:15a Lawrencechang
+# Add a different rule for storing DMI in NVRAM.
+#
+# 1 4/13/09 5:47a Lawrencechang
+# Initial check-in.
+#
+# 1 3/18/07 5:23p Felixp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OEMSETUP.mak
+#
+# Description: Make file for the OEMSETUP.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : OEMSETUP
+
+OEMSETUP : $(BUILD_DIR)\OEMSETUP.mak OEMSETUPBin
+
+$(BUILD_DIR)\OEMSETUP.mak : $(OFBD_OEMSETUP_DIR)\$(@B).cif $(OFBD_OEMSETUP_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_OEMSETUP_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+# EIP 37169
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"=="2" && "$(SMBIOS_PRESERVE_NVRAM)"!="1"
+$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj : $(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.c
+ mkdir $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)
+ $(CC) $(CFLAGS:/W4=/W3) /Fo$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\ $(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.c
+
+OEMSETUPBin : $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+!ELSE
+OEMSETUPBin :
+!ENDIF
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OEMSETUP.mak all\
+ NAME=OEMSETUP \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEMSETUPLIB)
+
+$(OEMSETUPLIB) : OEMSETUP
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/Core/EM/OFBD/OEMSETUP/OEMSETUP.sdl b/Core/EM/OFBD/OEMSETUP/OEMSETUP.sdl
new file mode 100644
index 0000000..a8d09d4
--- /dev/null
+++ b/Core/EM/OFBD/OEMSETUP/OEMSETUP.sdl
@@ -0,0 +1,71 @@
+TOKEN
+ Name = "OEMSETUP_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable OEM SETUP Preserve support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEMSETUPLIB"
+ Value = "$(BUILD_DIR)\OEMSETUP.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OFBD OEM SETUP Preserve]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_SETUP_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test BIOS Setting preserve Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "[OFBD OEM DMI Data Preserve]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+TOKEN
+ Name = "OEM_DMI_SAMPLE_TEST"
+ Value = "1"
+ Help = "Test BIOS DMI Data preserve Function"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "OFBD_OEMSETUP_DIR"
+End
+
+MODULE
+ Help = "Includes OEMSETUP.mak to Project"
+ File = "OEMSETUP.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OEMSETUP.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OEMSETUPEntry,"
+ Parent = "OFBDPartsList"
+ Token = "OEMSETUP_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OFBD/OFBD.c b/Core/EM/OFBD/OFBD.c
new file mode 100644
index 0000000..4a0c265
--- /dev/null
+++ b/Core/EM/OFBD/OFBD.c
@@ -0,0 +1,415 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OFBD.c 10 1/22/16 12:52a Terrylin $
+//
+// $Revision: 10 $
+//
+// $Date: 1/22/16 12:52a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OFBD.c $
+//
+// 10 1/22/16 12:52a Terrylin
+// [TAG] EIP253222
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Update for AMISV035 SMM vulnerability
+// [RootCause] BufAddr is an embedded input pointer which has not been
+// validated to be outside of SMRAM.
+// [Solution] Change the SMRAM corruption validation rules to use
+// AmiBufferValidationLib module.
+// [Files] OFBD.sdl
+// OFBD.c
+// OFBD_Help.chm
+//
+// 9 8/15/13 5:35a Terrylin
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Build Error
+// [Files] OFBD.mak
+// OFBD.c
+//
+// 8 8/06/13 6:32a Terrylin
+// [TAG] EIP131682
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] System BIOS will hang up, when AFU run in Windows or Linux.
+//
+// 7 7/31/13 4:55a Terrylin
+// [TAG] EIP125898
+// [Category] Improvement
+// [Description] 1. Update modules to compliant with PI 1.2 and UEFI
+// 2.3.1 specifications.
+// 2. Add OFBD_TC_51_DC_EXT_STRUCT new structure definition.
+// [Files] OFBD.c
+// OFBD.h
+//
+// 6 7/02/13 3:18a Terrylin
+// [TAG] EIP126656
+// [Category] Improvement
+// [Description] Limited write into SMRAM via OFBD SMM driver - BugID
+// 305380
+//
+// 5 6/14/13 3:54a Terrylin
+// [Category] Improvement
+// [Description] Add the Not InSmmFuncList support.
+// [Files] OFBD.sdl
+// OFBD.mak
+// OFBD.c
+//
+// 4 3/16/11 10:39p Terrylin
+// Correct Copyright information.
+//
+// 3 3/16/11 10:13p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description of each file for user more
+// clearly.
+// [Files] OFBD.mak
+// OFBD.dxs
+// OFBD.c
+// OFBD.h
+//
+// 2 7/02/09 5:54a Klzhan
+// Improvement: Add an E-Link in SMM.
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 3/25/05 5:37p Markw
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OFBD.c
+//
+// Description:
+// This is the main file of OFBD module. We setup OFBD SMI handler here. Please also refer to Aptio SMM Module Porting
+// guide.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+#include <Protocol\SmmCpu.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#define RETURN(status) {return status;}
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+#include <Protocol\DevicePath.h>
+#include <AmiHobs.h>
+#include <AmiSmm.h>
+#include <Include\AmiBufferValidationLib.h>
+#include "OFBD.h"
+
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID;
+EFI_GUID gEfiSmmBase2ProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
+EFI_GUID gEfiSmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
+EFI_SMM_CPU_PROTOCOL *gSmmCpu;
+#else
+EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+#endif
+
+SMM_HOB gSmmHob;
+
+VOID InitParts(VOID *pOFBDBuffer, UINT8 *pOFBDDataHandled);
+
+typedef VOID (OFBD_SMM) (VOID);
+extern OFBD_SMM OFBD_SMM_FUNC_LIST EndOfOFBDSMMList;
+extern OFBD_SMM OFBD_NOT_SMM_FUNC_LIST EndOfOFBDSMMList;
+OFBD_SMM* OFBDInSMMFunc[] = {OFBD_SMM_FUNC_LIST NULL};
+OFBD_SMM* OFBDNotInSMMFunc[] = {OFBD_NOT_SMM_FUNC_LIST NULL};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckAddressRange
+//
+// Description: Check address to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Range - length of the area
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// EFI_ACCESS_DENIED - Access denied!
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckAddressRange( IN UINT8 *Address, IN UINTN Range )
+{
+ // Check the size and range
+ if ( ((EFI_PHYSICAL_ADDRESS)Address >= gSmmHob.Tseg) &&
+ ((EFI_PHYSICAL_ADDRESS)Address <= (gSmmHob.Tseg + gSmmHob.TsegLength)) )
+ return EFI_ACCESS_DENIED;
+
+ if ( (((EFI_PHYSICAL_ADDRESS)Address + Range) >= gSmmHob.Tseg) &&
+ (((EFI_PHYSICAL_ADDRESS)Address + Range) <= (gSmmHob.Tseg + gSmmHob.TsegLength)) )
+ return EFI_ACCESS_DENIED;
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: OFBDSMIHandler
+//
+// Description: OFBD SMI Handlers.
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+EFI_STATUS
+OFBDSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+#else
+VOID OFBDSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+#endif
+{
+#if PI_SPECIFICATION_VERSION < 0x1000A
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState = NULL;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger = NULL;
+ UINTN i;
+#endif
+ UINT8 Data;
+ UINT64 BuffAddr;
+ UINT32 HighBufferAddress = 0;
+ UINT32 LowBufferAddress = 0;
+ UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1;
+ OFBD_HDR *OFBDHeader;
+ UINT8 OFBDDataHandled = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+
+ Cpu = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->SwSmiCpuIndex;
+ //
+ // Found Invalid CPU number, return
+ //
+ if(Cpu == (UINTN)-1) RETURN(Status);
+
+ Status = gSmmCpu->ReadSaveState ( gSmmCpu, \
+ 4, \
+ EFI_SMM_SAVE_STATE_REGISTER_RBX, \
+ Cpu, \
+ &LowBufferAddress );
+ Status = gSmmCpu->ReadSaveState ( gSmmCpu, \
+ 4, \
+ EFI_SMM_SAVE_STATE_REGISTER_RCX, \
+ Cpu, \
+ &HighBufferAddress );
+
+ Data = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->CommandPort;
+
+#else
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid, \
+ &gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+ Data = (UINT8)DispatchContext->SwSmiInputValue;
+
+ pCpuSaveState = pSmst->CpuSaveState;
+ HighBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.ECX;
+ LowBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.EBX;
+#endif
+ BuffAddr = HighBufferAddress;
+ BuffAddr = Shl64(BuffAddr, 32);
+ BuffAddr += LowBufferAddress;
+
+ //TRACE((-1,"\nOFBD address is:%x ------\n",BuffAddr));
+
+ OFBDHeader = (OFBD_HDR *)BuffAddr;
+ if ((Data == OFBD_SW_SMI_VALUE) && (OFBDHeader->OFBD_SIG == 'DBFO'))
+ {
+ //Status = CheckAddressRange((UINT8*)(UINTN)OFBDHeader, OFBDHeader->OFBD_Size);
+ if(EFI_ERROR(AmiValidateMemoryBuffer ((UINT8*)(UINTN)OFBDHeader, \
+ OFBDHeader->OFBD_Size))) return EFI_ACCESS_DENIED;
+ //if (!EFI_ERROR(Status)) {
+ OFBDHeader->OFBD_VER = OFBD_VERSION;
+ OFBDHeader->OFBD_RS |= OFBD_RS_SUPPORT;
+
+ InitParts((VOID *)BuffAddr,&OFBDDataHandled);
+ //}
+ }
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ RETURN(Status);
+#endif
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InSmmFunction
+//
+// Description: Install OFBD SMI Handlers.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// OUT EFI_SYSTEM_TABLE *SystemTable
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch = NULL;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext = {OFBD_SW_SMI_VALUE};
+#else
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext = {OFBD_SW_SMI_VALUE};
+#endif
+
+ EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ UINT8 i;
+ SMM_HOB *SmmHob;
+ EFI_GUID SmmHobGuid = SMM_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ Status = InitAmiBufferValidationLib(ImageHandle, SystemTable);
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ Status = InitAmiSmmLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pSmmBase->GetSmstLocation (gSmmBase2, &pSmst);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pSmst->SmmLocateProtocol( \
+ &gEfiSmmSwDispatch2ProtocolGuid, NULL, &pSwDispatch);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pSmst->SmmLocateProtocol(&gEfiSmmCpuProtocolGuid, NULL, &gSmmCpu);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+#else
+ VERIFY_EFI_ERROR(pBS->LocateProtocol(
+ &gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch));
+#endif
+
+ SmmHob = (SMM_HOB*)GetEfiConfigurationTable(pST, &HobListGuid);
+ if (SmmHob == NULL) return EFI_NOT_FOUND;
+
+ Status = FindNextHobByGuid(&SmmHobGuid,(VOID**)&SmmHob);
+ if (EFI_ERROR(Status)) return Status;
+
+ MemCpy( &gSmmHob, SmmHob, sizeof(SMM_HOB) );
+
+ Status = pSwDispatch->Register(pSwDispatch, OFBDSMIHandler, &SwContext, \
+ &Handle);
+ ASSERT_EFI_ERROR(Status);
+
+ for (i = 0; OFBDInSMMFunc[i] != NULL; i++) OFBDInSMMFunc[i]();
+ return Status;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NotInSmmFunction
+//
+// Description: Install OFBD SMI Handlers.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// OUT EFI_SYSTEM_TABLE *SystemTable
+// Output:
+// EFI_STATUS
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS NotInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ UINT8 i;
+ for (i = 0; OFBDNotInSMMFunc[i] != NULL; i++) OFBDNotInSMMFunc[i]();
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDEntryPoint
+//
+// Description: The main entry point of OFBD module.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// OUT EFI_SYSTEM_TABLE *SystemTable
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OFBDEntryPoint (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ InitAmiLib(ImageHandle, SystemTable);
+
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OFBD.cif b/Core/EM/OFBD/OFBD.cif
new file mode 100644
index 0000000..bd88325
--- /dev/null
+++ b/Core/EM/OFBD/OFBD.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "On Flash Block Description (APTIO)"
+ category = eModule
+ LocalRoot = "Core\EM\OFBD\"
+ RefName = "OFBD_eModule"
+[files]
+"OFBD.sdl"
+"OFBD.mak"
+"OFBD.dxs"
+"OFBD.c"
+"OFBD.h"
+"OFBD_Help.chm"
+[parts]
+"OFBD_DEFCFG"
+"OFBD_OEMCMD"
+"OFBD_STDEC"
+"OFBD_OEMROMID"
+"OFBD_OEMPWDCK"
+"OFBD_OEMSETUP"
+"OFBD_OEMROMHOLE"
+"OFBD_CLEANERRORLOG"
+"OFBD_OA_DATA_HANDLE"
+"OFBD_BATTERYCHECK"
+<endComponent>
diff --git a/Core/EM/OFBD/OFBD.dxs b/Core/EM/OFBD/OFBD.dxs
new file mode 100644
index 0000000..07ef653
--- /dev/null
+++ b/Core/EM/OFBD/OFBD.dxs
@@ -0,0 +1,84 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OFBD.dxs 4 3/16/11 10:39p Terrylin $
+//
+// $Revision: 4 $
+//
+// $Date: 3/16/11 10:39p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OFBD.dxs $
+//
+// 4 3/16/11 10:39p Terrylin
+// Correct Copyright information.
+//
+// 3 3/16/11 10:13p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description of each file for user more
+// clearly.
+// [Files] OFBD.mak
+// OFBD.dxs
+// OFBD.c
+// OFBD.h
+//
+// 2 4/01/10 3:22a Lawrencechang
+// Add dependency for USB.
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 5/11/07 1:47p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OFBD_dxs
+//
+// Description: Dependency expression for OFBD driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#if defined(AMIUSB_SUPPORT) && AMIUSB_SUPPORT == 1
+#include <Protocol/AmiUsbController.h>
+#endif
+
+DEPENDENCY_START
+#if defined(AMIUSB_SUPPORT) && AMIUSB_SUPPORT == 1
+ EFI_USB_PROTOCOL_GUID AND
+#endif
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/OFBD.h b/Core/EM/OFBD/OFBD.h
new file mode 100644
index 0000000..b85eb6c
--- /dev/null
+++ b/Core/EM/OFBD/OFBD.h
@@ -0,0 +1,647 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/OFBD.h 20 7/31/13 4:55a Terrylin $
+//
+// $Revision: 20 $
+//
+// $Date: 7/31/13 4:55a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/OFBD.h $
+//
+// 20 7/31/13 4:55a Terrylin
+// [TAG] EIP125898
+// [Category] Improvement
+// [Description] 1. Update modules to compliant with PI 1.2 and UEFI
+// 2.3.1 specifications.
+// 2. Add OFBD_TC_51_DC_EXT_STRUCT new structure definition.
+// [Files] OFBD.c
+// OFBD.h
+//
+// 19 10/11/12 2:34a Terrylin
+// [Category] New Feature
+// [Description] Add BatteryCheck component for OEM can use this to
+// replace Legacy ECB table check support in Non-CSM environment.
+// [Files] OFBD.sdl
+// OFBD.h
+// OFBD.cif
+//
+// 18 7/24/12 3:59a Terrylin
+// [Category] Improvement
+// [Description] Add new Return Statuses of Type Code 51 for AFU general
+// commands.
+//
+// 17 2/22/12 4:39a Terrylin
+// Add new command status for GAN support
+//
+// 16 10/27/11 5:01a Terrylin
+// Add new command status of Secure Update.
+//
+// 15 10/24/11 2:47a Terrylin
+// Adjust the OEM OA module part definitions.
+//
+// 14 10/13/11 11:23p Terrylin
+// [TAG] EIP72332
+// [Category] Improvement
+// [Description] Add new Return Statuses of Type Code 51 for AFU general
+// commands.
+//
+// 13 9/19/11 5:03a Terrylin
+// Added OEM OA module part definitions.
+//
+// 12 9/15/11 11:43p Calvinchen
+// Added Secure Update OFBD definitions.
+//
+// 11 7/21/11 5:54a Terrylin
+// [TAG] EIP46069
+// [Category] Improvement
+// [Description] Support Runtime secure flash update mode
+//
+// 10 7/07/11 1:52a Terrylin
+// [TAG] EIP46069
+// [Category] New Feature
+// [Description] Support Secure Flash Update interface via OFBD
+// protocols
+// [Files] OFBD.h
+// OFBD.cif
+//
+// 9 4/20/11 6:46a Terrylin
+// [TAG] EIP52968
+// [Category] Improvement
+// [Description] Adjust OFBD_TC_55_MEUD_STRUCT structure, for new ME
+// firmware update rule.
+//
+// 8 3/16/11 10:39p Terrylin
+// Correct Copyright information.
+//
+// 7 3/16/11 10:13p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description of each file for user more
+// clearly.
+// [Files] OFBD.mak
+// OFBD.dxs
+// OFBD.c
+// OFBD.h
+//
+// 6 1/17/11 4:01a Terrylin
+// [TAG] EIP51076
+// [Category] New Feature
+// [Description] Add some new statuses for "/CLNEVNLOG" command of AFU.
+//
+// 5 8/11/10 11:13p Terrylin
+// Add some new statuses for /CMD: command.
+//
+// 4 5/06/10 2:10a Lawrencechang
+// 1. Modify the Type Code 51 Structure and Return Status.
+// 2. Add some new statuses for /ECX command.
+// 3. Add new DMI flags for /R command.
+//
+// 3 1/11/10 3:45a Lawrencechang
+// Modify Type#50 ROM hole structure.
+//
+// 2 12/01/09 4:35a Lawrencechang
+// Add a new status for /ECX command.
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 3/13/06 1:16a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OFBD.h
+//
+// Description: Header file for the OFBD
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_OFBD_H_
+#define _EFI_OFBD_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//----------------------------------------------------------------------------
+// On Flash Block Structure Definition
+//----------------------------------------------------------------------------
+//=======================
+// OFBD Header structure
+//=======================
+#pragma pack(1)
+typedef struct
+{
+ UINT32 OFBD_SIG; //'OFBD'
+ UINT16 OFBD_VER; //0200
+ UINT16 OFBD_Size;
+ UINT32 OFBD_FS;
+ UINT16 OFBD_RS;
+ UINT16 OFBD_HDR_SIZE;
+ UINT16 OFBD_OS;
+}OFBD_HDR;
+#pragma pack()
+
+//=================
+// On Flash Status
+//=================
+#define OFBD_FS_VC BIT00
+#define OFBD_FS_BBLK BIT01
+#define OFBD_FS_NVRAM BIT02
+#define OFBD_FS_MAIN BIT03
+#define OFBD_FS_NCB BIT04
+#define OFBD_FS_ROMH BIT05
+#define OFBD_FS_SFU BIT06
+#define OFBD_FS_OA BIT07
+#define OFBD_FS_AC_BAT BIT16
+#define OFBD_FS_SECURUD BIT22
+#define OFBD_FS_ERR_LOG BIT23
+#define OFBD_FS_OEM_CMD BIT24
+#define OFBD_FS_SETUP BIT25
+#define OFBD_FS_MEUD BIT26
+#define OFBD_FS_EC BIT27
+#define OFBD_FS_ORI BIT28
+#define OFBD_FS_PWD BIT29
+#define OFBD_FS_CFG BIT30
+
+//================
+// Return Status
+//================
+#define OFBD_RS_SUPPORT BIT00
+#define OFBD_RS_PROTECT BIT01
+#define OFBD_RS_PROTECT_PART BIT02
+#define OFBD_RS_ERR_OUT BIT03
+#define OFBD_RS_DIS_OEMSTR BIT04
+
+//================
+// OS environment
+//================
+#define OFBD_OS_DOS BIT00
+#define OFBD_OS_WIN BIT01
+#define OFBD_OS_LINUX BIT02
+#define OFBD_OS_FREEBSD BIT03
+#define OFBD_OS_EFI BIT04
+
+//===============================
+// Extended Table Header Status
+//===============================
+#pragma pack(1)
+typedef struct
+{
+ UINT8 TypeCodeID;
+ UINT8 NumTCStruct;
+ UINT16 TCStructSize;
+}OFBD_EXT_HDR;
+
+typedef struct
+{
+ UINT32 OFBD_END;
+}OFBD_END;
+#pragma pack()
+
+#define OFBD_EXT_TBL_END 0x0FFFF55AA
+
+//================
+// Type Code ID
+//================
+#define OFBD_EXT_TC_ROMHOLE 0x50
+#define OFBD_EXT_TC_AFUDEFCFG 0x51
+#define OFBD_EXT_TC_PWD 0x52
+#define OFBD_EXT_TC_ORI 0x53
+#define OFBD_EXT_TC_EC 0x54
+#define OFBD_EXT_TC_MEUD 0x55
+#define OFBD_EXT_TC_SETUP 0x56
+#define OFBD_EXT_TC_OEM_CMD 0x57
+#define OFBD_EXT_TC_CLN_ERR_LOG 0x58
+#define OFBD_EXT_TC_SECURE_UD 0x59
+#define OFBD_EXT_TC_OA_HANDLE 0x5A
+#define OFBD_EXT_TC_AC_BAT 0x5B
+#define OFBD_EXT_TC_SFU 0x70
+
+//----------------------------------------------------------------------------
+// On Flash Block Type Code Structure Section
+//----------------------------------------------------------------------------
+#pragma pack(1)
+//===============================
+// Type Code 50 Struct ROM HOLE
+//===============================
+typedef struct
+{
+ UINT32 ddExtCmd;
+ EFI_GUID HoleGuid;
+}OFBD_TC_50_RH_STRUCT;
+
+//===============================
+// Type Code 51 Struct Def Cfg
+//===============================
+typedef struct
+{
+ UINT32 ddExtCfg;
+ UINT32 ddRetSts;
+}OFBD_TC_51_DC_STRUCT;
+
+typedef struct
+{
+ UINT32 ddIndexCfg;
+ UINT16 ddExtCfg;
+ UINT16 ddIgnCfg;
+}OFBD_TC_51_DC_EXT_STRUCT;
+
+//=======================
+// Type Code 52 Struct
+//=======================
+typedef struct
+{
+ UINT16 dwPwdLen; //Password Length
+ UINT8 dbGetCkSts; //Get Check Status
+ UINT8 dbRetSts; //Return Status
+}OFBD_TC_52_PC_STRUCT;
+
+//=================================
+// Type Code 53 Struct OEM ROM ID
+//=================================
+typedef struct
+{
+ UINT8 dwGetCkSts;
+ UINT8 dwRetSts;
+ UINT32 ddStartAddrLow;
+ UINT32 ddStartAddrHigh;
+ UINT32 ddSize;
+}OFBD_TC_53_ORI_STRUCT;
+
+//=======================================
+// Type Code 54 Struct Standard EC Flash
+//=======================================
+typedef struct
+{
+ UINT8 dbFlaSts; //EC Set & Check Status
+ UINT16 dwRetSts; //EC Return Status
+ UINT32 ddChkSum; //EC Data CheckSum
+ UINT32 ddSize; //EC Data Size
+}OFBD_TC_54_STD_EC_STRUCT;
+
+//=======================================
+// Type Code 55 - ME Ignition Firmware Update Structure
+
+//=======================================
+typedef struct
+{
+ UINT8 bReturnStatus;
+ UINT8 bSubFunction;
+ UINT32 dMERuntimeBase;
+ UINT32 dMERuntimeLength;
+ UINT32 dMEBiosRegionBase;
+ UINT32 dMEBiosRegionLength;
+#if (OFBD_VERSION >= 0x0210)
+ UINT32 ddFlashBufOffset;
+ UINT32 ddBlockAddr;
+ UINT32 ddBlockSize;
+#endif
+}OFBD_TC_55_MEUD_STRUCT;
+
+//=======================================
+// Type Code 56 Struct
+//=======================================
+typedef struct
+{
+ UINT8 dbGetSts; //Get Status
+ UINT8 dbRetSts; //Return Status
+}OFBD_TC_56_SETUP_STRUCT;
+
+//=======================================
+// Type Code 57 Struct
+//=======================================
+typedef struct
+{
+ UINT16 dwFlaSts; // 0: Before Flash, 1: After Flash, 2: Before End
+ UINT16 dwRetSts; // 0: Failure, 1: Successfully
+ UINT32 ddCMD; // Bit 0~15: OEM CMD
+ UINT32 ddReserve; // Reserve
+} OFBD_TC_57_OEM_CMD_STRUCT;
+
+
+//=======================================
+// Type Code 58 Struct
+//=======================================
+typedef struct
+{
+ UINT16 dwFunSts; // 0: Do nothing 1: Clean Event Log
+ UINT16 dwRetSts; // 0: Failure, 1: Successfully
+} OFBD_TC_58_CEL_STRUCT;
+
+//=======================================
+// Type Code 59 Struct
+//=======================================
+typedef struct
+{
+ UINT64 BufAddr;
+ UINT32 BlockAddr; //0 starts at 0xfff0_0000
+ UINT32 BlockSize;
+ UINT8 ErrorCode;
+ UINT8 bSubFunction;
+} OFBD_TC_59_SECURE_UD;
+
+//=======================================
+// Type Code 5A Struct
+//=======================================
+typedef struct
+{
+ UINT8 dbOASts; // Bit 0: Notification BIOS, utility is now ready to update the OA data. - OFBD_TC_OA_UPDATE_NOTIFY
+ // Bit 1~7: Reserved
+
+ UINT8 dbErrorID; // 0~255 : Filled by O.E.M.
+
+ UINT16 dwRetSts; // Bit 0: OA data is invalid, tell the utility stop the flash procedure - OFBD_RS_OA_DATA_IS_INVALID
+ // Bit 1: OA data has be modified, tell the utility use the new data to update - OFBD_RS_OA_DATA_IS_MODIFIED
+ // Bit 2: BIOS has updated the OA, so tell the utility doesn't to update - OFBD_RS_OA_UPDATE_SKIPPED
+ // Bit 3: BIOS doesn't allow the OA update, tell the utility stop the flash procedure - OFBD_RS_OA_UPDATE_DECLINED
+ // Bit 4~14: Reserved
+ // Bit 15: Use dbErrorID field for utility return OEM specific error code, when this Bit is set to 1. - OFBD_RS_OA_USE_OEM_ERROR_ID
+ UINT32 ddOABlockAddr; // OA Block Address of BIOS ROM (For NCB mode to use)
+ UINT64 ddOADataBuffer; // OA Data Buffer
+ UINT32 dwOADataSize; // OA Data Buffer Size
+} OFBD_TC_5A_OA_HANDLE_STRUCT;
+
+//=======================================
+// Type Code 5B Struct
+//=======================================
+typedef struct
+{
+ UINT8 dbGetSts; // Get Status
+ UINT8 dbRetSts; // Return Status
+
+} OFBD_TC_5B_AC_BATTERY_STRUCT;
+
+//=======================================
+// Type Code 70 Struct
+//=======================================
+typedef struct
+{
+ UINT8 Command;
+ UINT8 Status;
+} OFBD_TC_70_SFU_STRUCT;
+#pragma pack()
+
+//=============================
+// Type Code Specific Status
+//=============================
+//=============================
+// Type Code 50 Return Status
+//=============================
+#define OFBD_TC_GRS_PROTECT BIT00
+
+//===============================
+// Type Code 50 Hole Description
+//===============================
+#define OFBD_TC_RH_HD_ROMHOLE BIT00
+#define OFBD_TC_RH_HD_NCB BIT01
+
+//=============================
+// Type Code 51 Return Status
+//=============================
+#define OFBD_TC_CFG_P BIT00
+#define OFBD_TC_CFG_B BIT01
+#define OFBD_TC_CFG_N BIT02
+#define OFBD_TC_CFG_K BIT03
+#define OFBD_TC_CFG_E BIT04
+#define OFBD_TC_CFG_Q BIT05
+#define OFBD_TC_CFG_REBOOT BIT06
+#define OFBD_TC_CFG_X BIT07
+#define OFBD_TC_CFG_S BIT08
+#define OFBD_TC_CFG_ECUF BIT09
+#define OFBD_TC_CFG_SHUTDOWN BIT10
+#define OFBD_TC_CFG_SETUPRESERVE BIT11
+#define OFBD_TC_CFG_ROMHOLE BIT12
+#define OFBD_TC_CFG_NCB BIT13
+#define OFBD_TC_CFG_CLNEVNLOG BIT14
+#define OFBD_TC_CFG_R BIT15
+#define OFBD_TC_CFG_O BIT16
+#define OFBD_TC_CFG_GAN BIT17 //Patch for EIP 75281
+#define OFBD_TC_CFG_KN BIT18
+#define OFBD_TC_CFG_L BIT19
+#define OFBD_TC_CFG_LN BIT20
+#define OFBD_TC_CFG_A BIT21
+#define OFBD_TC_CFG_OAD BIT22
+#define OFBD_TC_CFG_CAPSULE BIT23
+#define OFBD_TC_CFG_RECOVERY BIT24
+#define OFBD_TC_CFG_CAF BIT25
+
+//===============================
+// Type Code 52 Get Check Status
+// See OFBD Spec 5.2, 6.3 for detail
+//===============================
+#define OFBD_TC_OPC_GET BIT00
+#define OFBD_TC_OPC_CHECK BIT01
+
+//============================
+// Type Code 52 Return Status
+// See OFBD Spec 5.2, 6.3 for detail
+//============================
+#define OEM_RS_PC_REQ BIT00
+#define OEM_RS_PC_CK_OK BIT01
+#define OEM_RS_PC_TIMES_EXCEEDED BIT02
+
+//========================================
+// Type Code 53 Get & Check Status
+// See OFBD Spec 5.4, 6.4 for detail
+//========================================
+#define OFBD_TC_ORI_GET BIT00
+#define OFBD_TC_ORI_CHECK BIT01
+
+//========================================
+// Type Code 53 Return Status
+// See OFBD Spec 5.4, 6.4 for detail
+//========================================
+#define OFBD_TC_ORI_REQ BIT00
+#define OFBD_TC_ORI_ROM BIT01
+#define OFBD_TC_ORI_MOD BIT02
+#define OFBD_TC_ORI_GUID BIT03
+#define OFBD_TC_ORI_CK_OK BIT04
+
+//=======================================
+// Type Code 54 Set Status
+// See OFBD Spec 5.5, 6.5 for detail
+//=======================================
+#define OFBD_TC_STD_EC_START BIT00
+#define OFBD_TC_STD_EC_FLASH BIT01
+#define OFBD_TC_STD_EC_END BIT02
+#define OFBD_TC_ECX_SIZE BIT03 //(EIP31739+) Andy+
+#define OFBD_TC_ECX_ERASE BIT04
+#define OFBD_TC_ECX_VERIFY BIT05
+#define OFBD_TC_ECX_RETRY BIT06
+
+//=======================================
+// Type Code 54 Return Status
+// See OFBD Spec 5.5, 6.5 for detail
+//=======================================
+#define OFBD_RS_EC_OK BIT00
+#define OFBD_RS_EC_CHKSUM BIT01
+#define OFBD_RS_EC_ENTRY BIT02
+#define OFBD_RS_EC_ERASE BIT03
+#define OFBD_RS_EC_INIT BIT04
+#define OFBD_RS_EC_START BIT05
+#define OFBD_RS_EC_WRITE BIT06
+#define OFBD_RS_EC_EXIT BIT07
+#define OFBD_RS_EC_CHIPID BIT08
+
+//===============================
+// Type Code 55 SubFunction
+//===============================
+#define OFBD_TC_MEUD_GETINFO 0
+#define OFBD_TC_MEUD_START BIT00
+
+//============================
+// Type Code 55 Return Status
+//============================
+#define OFBD_TC_MEUD_OK BIT00
+#define OFBD_TC_MEUD_ERROR BIT01
+
+//===============================
+// Type Code 56 Get Check Status
+//===============================
+#define OFBD_TC_SETUP_SUPPORT BIT00
+#define OFBD_TC_SETUP_STORE BIT01
+#define OFBD_TC_SETUP_RESTORE BIT02
+#define OFBD_TC_DMI_STORE BIT03
+#define OFBD_TC_DMI_RESTORE BIT04
+
+//============================
+// Type Code 56 Return Status
+//============================
+#define OFBD_TC_SETUP_OK BIT00
+#define OFBD_TC_SETUP_NOT_SUPPORT BIT01
+#define OFBD_TC_SETUP_STORE_ERROR BIT02
+#define OFBD_TC_SETUP_RESTORE_ERROR BIT03
+#define OFBD_TC_DMI_STORE_ERROR BIT04
+#define OFBD_TC_DMI_RESTORE_ERROR BIT05
+
+//===================================//
+// Type Code 57 Flash & Return Status//
+//===================================//
+// OEM CMD - Flash Status.
+#define OFBD_TC_OEM_CMD_BF 1
+#define OFBD_TC_OEM_CMD_AF 2
+#define OFBD_TC_OEM_CMD_BE 3
+#define OFBD_TC_OEM_CMD_SF 4
+#define OFBD_TC_OEM_CMD_BUF 5 // For /CMD:"" to use (EIP40787+)
+#define OFBD_TC_OEM_CMD_BUF_SF 6
+#define OFBD_TC_OEM_CMD_BUF_AF 7
+#define OFBD_TC_OEM_CMD_BUF_BE 8
+
+// OEM CMD - Return Status.
+#define OFBD_TC_OEM_CMD_OK BIT00
+#define OFBD_TC_OEM_CMD_NOT_SUPPORT BIT01
+#define OFBD_TC_OEM_CMD_ERROR BIT02
+
+//===============================
+// Type Code 58 Func Status
+//===============================
+#define OFBD_TC_CEL_FUNC_REQ BIT00
+
+//============================
+// Type Code 58 Return Status
+//============================
+#define OFBD_TC_CEL_OK BIT00
+#define OFBD_TC_CEL_ERROR BIT01
+#define OFBD_TC_CEL_BIOS_NOT_SUPPORT BIT02
+
+//===============================
+// Type Code 59 SubFunction
+//===============================
+#define OFBD_TC_SECUREUD_LOAD2SMM BIT00
+#define OFBD_TC_SECUREUD_VERIFY_SMM BIT01
+#define OFBD_TC_SECUREUD_DONE BIT02
+
+//===============================
+// Type Code 5A Func Status
+//===============================
+#define OFBD_TC_OA_UPDATE_NOTIFY BIT00
+
+//============================
+// Type Code 5A Return Status
+//============================
+#define OFBD_RS_OA_DATA_IS_INVALID BIT00
+#define OFBD_RS_OA_DATA_IS_MODIFIED BIT01
+#define OFBD_RS_OA_UPDATE_SKIPPED BIT02
+#define OFBD_RS_OA_UPDATE_DECLINED BIT03
+#define OFBD_RS_OA_USE_OEM_ERROR_ID BIT15
+
+//===============================
+// Type Code 5B Func Status
+//===============================
+#define OFBD_TC_AC_BAT_INFO_REQ BIT00
+
+//============================
+// Type Code 5B Return Status
+//============================
+#define OFBD_RS_AC_BAT_OK BIT00
+#define OFBD_RS_AC_BAT_ERR BIT01
+
+//===================================//
+// Type Code 70 Get & Set Status //
+//===================================//
+#define OFBD_TC_SFU_GET_FLASH_INFO BIT00
+#define OFBD_TC_SFU_LOAD_FIRMWARE_IMAGE BIT01
+#define OFBD_TC_SFU_GET_FLASH_UPDATE_POLICY BIT02
+#define OFBD_TC_SFU_SET_FLASH_UPDATE_METHOD BIT03
+#define OFBD_TC_SFU_RUNTIME_FLASH BIT04
+
+//==============================//
+// Type Code 70 Return Status //
+//==============================//
+#define OFBD_TC_SFU_OK BIT00
+#define OFBD_TC_SFU_NOT_SUPPORTED BIT01
+#define OFBD_TC_SFU_FW_AUTH_FAILED BIT02
+#define OFBD_TC_SFU_INVALID_FW_CAPSULE_HDR BIT03
+#define OFBD_TC_SFU_SIGNING_KEYS_DONT_MATCH BIT04
+#define OFBD_TC_SFU_UNSUPPORTED_CERTIFICATE_HDR_FORMAT BIT05
+
+//----------------------------------------------------------------------------
+// OFBD ROM HOLE CORE SERVICE ROUTINE - INVOKE FUNCTION - Function Driven Token
+//----------------------------------------------------------------------------
+#define OFBD_RH_HOLE_EXIST_CK 0 // This token is to check OEM's ROM Hole's existance.
+#define OFBD_RH_GET_HOLE_PHY_ADDR 1 // Pass Addr, Size, then Get Phy Addr. Notice: If NULL means AFU Does not support
+#define OFBD_RH_HOLE_PROTECT 2 // Protect Sts, Addr, Size
+
+//----------------------------------------------------------------------------
+// ROM HOLE - INVOKE FUNCTION RTN STS
+//----------------------------------------------------------------------------
+#define OFBD_RH_RTN_SUCCESSFUL 0
+#define OFBD_RH_RTN_SERVICE_NOT_FOUND BIT00
+#define OFBD_RH_RTN_SERVICE_PARAMETER_ERROR BIT01
+#define OFBD_RH_RTN_HOLE_NOT_EXIST BIT02
+#define OFBD_RH_RTN_PHY_ADDR_NOT_VALID BIT03
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/OFBD.mak b/Core/EM/OFBD/OFBD.mak
new file mode 100644
index 0000000..0fe4c0b
--- /dev/null
+++ b/Core/EM/OFBD/OFBD.mak
@@ -0,0 +1,111 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/OFBD.mak 6 8/15/13 5:35a Terrylin $
+#
+# $Revision: 6 $
+#
+# $Date: 8/15/13 5:35a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/OFBD.mak $
+#
+# 6 8/15/13 5:35a Terrylin
+# [Category] Bug Fix
+# [Severity] Important
+# [Symptom] Build Error
+# [Files] OFBD.mak
+# OFBD.c
+#
+# 5 6/14/13 3:54a Terrylin
+# [Category] Improvement
+# [Description] Add the Not InSmmFuncList support.
+# [Files] OFBD.sdl
+# OFBD.mak
+# OFBD.c
+#
+# 4 3/16/11 10:39p Terrylin
+# Correct Copyright information.
+#
+# 3 3/16/11 10:13p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description of each file for user more
+# clearly.
+# [Files] OFBD.mak
+# OFBD.dxs
+# OFBD.c
+# OFBD.h
+#
+# 2 7/02/09 5:53a Klzhan
+# Improvement: Add an E-Link in SMM.
+#
+# 1 4/13/09 5:46a Lawrencechang
+# Initial check-in.
+#
+# 1 3/18/07 5:23p Felixp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OFBD.mak
+#
+# Description: Make file for the OFBD.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : OFBD
+
+OFBD : $(BUILD_DIR)\OFBD.mak OFBDBin
+
+$(BUILD_DIR)\OFBD.mak : $(OFBD_DIR)\$(@B).cif $(OFBD_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OFBD_ELINK_LISTS = \
+/D\"OFBD_SMM_FUNC_LIST=$(OFBDInSmmFuncList)\"\
+/D\"OFBD_NOT_SMM_FUNC_LIST=$(OFBDNotInSmmFuncList)\"
+
+OFBDBin : $(AMIDXELIB) $(OFBDLISTLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OFBD.mak all\
+ NAME=OFBD\
+ GUID=57E56594-CE95-46ad-9531-3C49310CA7CE\
+ ENTRY_POINT=OFBDEntryPoint\
+ "INIT_LIST=$(OFBDPartsList)"\
+!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A
+ TYPE=DXESMM_DRIVER\
+ DEPEX1=$(OFBD_DIR)\OFBD.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+!ELSE
+ TYPE=BS_DRIVER\
+ DEPEX1=$(OFBD_DIR)\OFBD.dxs \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+!ENDIF
+ "CFLAGS=$(CFLAGS) /DVFRCOMPILE $(OFBD_ELINK_LISTS)"\
+ COMPRESS=1\
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/OFBD/OFBD.sdl b/Core/EM/OFBD/OFBD.sdl
new file mode 100644
index 0000000..268a56a
--- /dev/null
+++ b/Core/EM/OFBD/OFBD.sdl
@@ -0,0 +1,68 @@
+TOKEN
+ Name = OFBD_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable On Flash Block Description support in Project"
+End
+
+TOKEN
+ Name = "OFBD_SW_SMI_VALUE"
+ Value = "0x26"
+ Help = "Sw SMI value of OFBD item change"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-0xff"
+End
+
+TOKEN
+ Name = "OFBD_VERSION"
+ Value = "0x0210"
+ Help = "OFBD Version"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes OFBD.mak to Project"
+ File = "OFBD.mak"
+End
+
+PATH
+ Name = "OFBD_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OFBD.ffs"
+ Parent = "FV_MAIN"
+ Help = "OFBD component"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AmiBufferValidationLib.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OFBDLISTLIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OFBDPartsList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OFBDInSmmFuncList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OFBDNotInSmmFuncList"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/EM/OFBD/OFBD_Help.chm b/Core/EM/OFBD/OFBD_Help.chm
new file mode 100644
index 0000000..0ec5f4a
--- /dev/null
+++ b/Core/EM/OFBD/OFBD_Help.chm
Binary files differ
diff --git a/Core/EM/OFBD/SecureFlash/SecureFlash.c b/Core/EM/OFBD/SecureFlash/SecureFlash.c
new file mode 100644
index 0000000..f787d33
--- /dev/null
+++ b/Core/EM/OFBD/SecureFlash/SecureFlash.c
@@ -0,0 +1,343 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Secure Flash/SecureFlash.c 7 1/17/12 10:24p Lawrencechang $
+//
+// $Revision: 7 $
+//
+// $Date: 1/17/12 10:24p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Secure Flash/SecureFlash.c $
+//
+// 7 1/17/12 10:24p Lawrencechang
+// Remove unnecessary header file.
+//
+// 6 1/04/12 7:14a Lawrencechang
+// Remove runtime flash codes, which will be done by SMIFlash protocol.
+//
+// 5 12/21/11 8:17a Lawrencechang
+// 1. Check if SMIFlash module exists or enables before install SMIFlash
+// protocol.
+// 2. Add WriteBlockEx() for SMIFlash protocol compatibility.
+// WriteBlockEx() will be only used in SMIFlash protocol but no exposed to
+// flash ROM interface.
+//
+// 4 10/29/11 5:26a Lawrencechang
+// Modified for adding SMIFlash protocol compatibility.
+//
+// 3 10/28/11 4:28a Lawrencechang
+// Add GetFlashInfo() for compatibility with SMIFlash protocol. Only works
+// with 4.6.3.2_OFBD.1.0.2.
+//
+// 2 10/18/11 3:11a Lawrencechang
+// Force LoadFirmwareImage(), GetFlashUpdatePolicy() and
+// SetFlashUpdateMethod() to return correct error code.
+//
+// 1 9/16/11 4:25a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SecureFlash.c
+//
+// Description: This file provides OFBD Secure Flash function.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <EFI.h>
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Protocol/SecSmiFlash.h>
+#include <Protocol/FlashProtocol.h>
+
+#include <OFBD.h>
+#include <SecureFlash.h>
+
+// GUIDs of consumed protocols
+static EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+static EFI_GUID gEfiSecSmiFlashProtocolGuid = EFI_SEC_SMI_FLASH_GUID;
+
+// Consumed protocols
+EFI_SEC_SMI_FLASH_PROTOCOL *SecSmiFlash = NULL;
+FLASH_PROTOCOL *Flash = NULL;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadFirmwareImage
+//
+// Description: Transfer ROM image from AFU's buffer to Secure Flash Module
+// through EFI_SEC_SMI_FLASH_PROTOCOL.
+//
+// Input:
+// IN VOID *Data The data is a memory buffer. Its content is FUNC_BLOCK
+// defined in SmiFlash.h. The member function
+// LOAD_FLASH_IMAGE in EFI_SEC_SMI_FLASH_PROTOCOL only
+// accepts this type of parameter.
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LoadFirmwareImage (
+ VOID *Data
+)
+{
+ EFI_STATUS Status;
+
+ if (NULL == SecSmiFlash) return EFI_UNSUPPORTED;
+
+ Status = SecSmiFlash->LoadFwImage((FUNC_BLOCK *)Data);
+
+ ((FUNC_BLOCK *)Data)->ErrorCode = (EFI_ERROR(Status) ? 1 : 0);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashUpdatePolicy
+//
+// Description: Get Flash Update Policy from Secure Flash module.
+//
+// Input:
+// IN VOID *Data The data is a memory buffer. Its content is
+// FLASH_POLICY_INFO_BLOCK defined in SecSmiFlash.h.
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFlashUpdatePolicy (
+ VOID *Data
+)
+{
+ EFI_STATUS Status;
+ FLASH_POLICY_INFO_BLOCK *pFlashPolicy = (FLASH_POLICY_INFO_BLOCK *)Data;
+
+ if (NULL == SecSmiFlash) return EFI_UNSUPPORTED;
+
+ Status = SecSmiFlash->GetFlUpdPolicy(pFlashPolicy);
+
+ pFlashPolicy->ErrorCode = (EFI_ERROR(Status) ? 1 : 0);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetFlashUpdateMethod
+//
+// Description: Set Flash Update Policy to Secure Flash module.
+//
+// Input:
+// IN VOID *Data The data is a memory buffer. Its content is
+// FUNC_FLASH_SESSION_BLOCK defined in SecSmiFlash.h.
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetFlashUpdateMethod (
+ VOID *Data
+)
+{
+ EFI_STATUS Status;
+ FUNC_FLASH_SESSION_BLOCK *pFlashSessionBlock = (FUNC_FLASH_SESSION_BLOCK *)Data;
+
+ if (NULL == SecSmiFlash) return EFI_UNSUPPORTED;
+
+ Status = SecSmiFlash->SetFlUpdMethod(pFlashSessionBlock);
+
+ pFlashSessionBlock->ErrorCode = (EFI_ERROR(Status) ? 1 : 0);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SecureFlashProtocolCallback
+//
+// Description: Locate SecSmiFlash protocol callback
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SecureFlashProtocolCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ pBS->LocateProtocol(&gEfiSecSmiFlashProtocolGuid, NULL, &SecSmiFlash);
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmFlashProtocolCallback
+//
+// Description: Locate Flash protocol callback
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SmmFlashProtocolCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ pBS->LocateProtocol(&gFlashSmmProtocolGuid, NULL, &Flash);
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: ASFUInSmm
+//
+// Description: This function installs the ASFU Protocol.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ASFUInSmm (
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DummyHandle = NULL;
+
+ Status = pBS->LocateProtocol(&gEfiSecSmiFlashProtocolGuid, NULL, &SecSmiFlash);
+ if (EFI_ERROR(Status)) {
+ EFI_EVENT SecFlashCallbackEvt;
+ VOID *Reg;
+ RegisterProtocolCallback(
+ &gEfiSecSmiFlashProtocolGuid,
+ SecureFlashProtocolCallback,
+ NULL,
+ &SecFlashCallbackEvt,
+ &Reg);
+ }
+
+ Status = pBS->LocateProtocol(&gFlashSmmProtocolGuid, NULL, &Flash);
+ if (EFI_ERROR(Status)) {
+ EFI_EVENT SmmFlashCallbackEvt;
+ VOID *Reg;
+ RegisterProtocolCallback(
+ &gFlashSmmProtocolGuid,
+ SmmFlashProtocolCallback,
+ NULL,
+ &SmmFlashCallbackEvt,
+ &Reg);
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ASFUEntry
+//
+// Description: OFBD Secure Flash Update Entry point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ASFUEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled
+)
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_70_SFU_STRUCT *ASFUStructPtr;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (*pOFBDDataHandled == 0) {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ ASFUStructPtr = (OFBD_TC_70_SFU_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ if (pOFBDHdr->OFBD_FS & OFBD_FS_SFU) {
+ //Check Type Code ID
+ if (pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_SFU) {
+ switch (ASFUStructPtr->Command) {
+ case OFBD_TC_SFU_LOAD_FIRMWARE_IMAGE :
+ Status = LoadFirmwareImage(pOFBDTblEnd);
+ break;
+ case OFBD_TC_SFU_GET_FLASH_UPDATE_POLICY :
+ Status = GetFlashUpdatePolicy(pOFBDTblEnd);
+ break;
+ case OFBD_TC_SFU_SET_FLASH_UPDATE_METHOD :
+ Status = SetFlashUpdateMethod(pOFBDTblEnd);
+ break;
+ default :
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ if (EFI_ERROR(Status)) {
+ *pOFBDDataHandled = 0xFE;
+ ASFUStructPtr->Status = OFBD_TC_SFU_NOT_SUPPORTED;
+ } else {
+ *pOFBDDataHandled = 0xFF;
+ ASFUStructPtr->Status = OFBD_TC_SFU_OK;
+ }
+ }
+ }
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/SecureFlash/SecureFlash.chm b/Core/EM/OFBD/SecureFlash/SecureFlash.chm
new file mode 100644
index 0000000..1d3bd8d
--- /dev/null
+++ b/Core/EM/OFBD/SecureFlash/SecureFlash.chm
Binary files differ
diff --git a/Core/EM/OFBD/SecureFlash/SecureFlash.cif b/Core/EM/OFBD/SecureFlash/SecureFlash.cif
new file mode 100644
index 0000000..feed7f2
--- /dev/null
+++ b/Core/EM/OFBD/SecureFlash/SecureFlash.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "On Flash Block Description (APTIO) - Secure Flash"
+ category = eModule
+ LocalRoot = "Core\EM\OFBD\SecureFlash\"
+ RefName = "OFBD_SECURE_FLASH"
+[files]
+"SecureFlash.sdl"
+"SecureFlash.mak"
+"SecureFlash.h"
+"SecureFlash.c"
+"SecureFlash.chm"
+<endComponent>
diff --git a/Core/EM/OFBD/SecureFlash/SecureFlash.h b/Core/EM/OFBD/SecureFlash/SecureFlash.h
new file mode 100644
index 0000000..99b251e
--- /dev/null
+++ b/Core/EM/OFBD/SecureFlash/SecureFlash.h
@@ -0,0 +1,68 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD Secure Flash/SecureFlash.h 3 1/04/12 7:12a Lawrencechang $
+//
+// $Revision: 3 $
+//
+// $Date: 1/04/12 7:12a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD Secure Flash/SecureFlash.h $
+//
+// 3 1/04/12 7:12a Lawrencechang
+// Remove SMIFlash related codes.
+//
+// 2 10/29/11 5:29a Lawrencechang
+// Modified for adding SMIFlash protocol compatibility.
+//
+// 1 9/16/11 4:25a Lawrencechang
+// Initial check-in.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SecureFlash.h
+//
+// Description: Header file for OFBD Secure Flash module.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_ASFU_H_
+#define _EFI_ASFU_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/SecureFlash/SecureFlash.mak b/Core/EM/OFBD/SecureFlash/SecureFlash.mak
new file mode 100644
index 0000000..337cf61
--- /dev/null
+++ b/Core/EM/OFBD/SecureFlash/SecureFlash.mak
@@ -0,0 +1,76 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD Secure Flash/SecureFlash.mak 4 1/04/12 7:11a Lawrencechang $
+#
+# $Revision: 4 $
+#
+# $Date: 1/04/12 7:11a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD Secure Flash/SecureFlash.mak $
+#
+# 4 1/04/12 7:11a Lawrencechang
+# Remove SMIFlash related make rules.
+#
+# 3 10/29/11 5:30a Lawrencechang
+# Modified for adding SMIFlash protocol compatibility.
+#
+# 2 10/03/11 2:36a Lawrencechang
+# Modify path of SecSMIFlashHook.obj to adapt the latest version
+# SecureFlashPkg.
+#
+# 1 9/16/11 4:25a Lawrencechang
+# Initial check-in.
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: SecureFlash.mak
+#
+# Description: Make file for OFBD Secure Flash module.
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+
+$(OFBD_SECUREFLASH_LIB) : $(BUILD_DIR)\SecureFlash.mak OFBD_SECUREFLASH_BIN
+
+OFBD_SECFLASH_EXT_INCLUDES = \
+ /I $(OFBD_DIR)\
+ /I $(OFBD_SECURE_FLASH_DIR)
+
+$(BUILD_DIR)\SecureFlash.mak : $(OFBD_SECURE_FLASH_DIR)\$(@B).cif
+ $(CIF2MAK) $(OFBD_SECURE_FLASH_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OFBD_SECUREFLASH_BIN : $(AMIDXELIB) $(FLASHLIB) $(OFBD_EXT_OBJS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecureFlash.mak all\
+ "MY_INCLUDES=$(OFBD_SECFLASH_EXT_INCLUDES)"\
+ NAME=SecureFlash TYPE=LIBRARY LIBRARY_NAME=$(OFBD_SECUREFLASH_LIB)
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/OFBD/SecureFlash/SecureFlash.sdl b/Core/EM/OFBD/SecureFlash/SecureFlash.sdl
new file mode 100644
index 0000000..da1b3c5
--- /dev/null
+++ b/Core/EM/OFBD/SecureFlash/SecureFlash.sdl
@@ -0,0 +1,51 @@
+TOKEN
+ Name = SECURE_FLASH_SUPPORT
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable Security Flash in Project"
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "OFBD_SECUREFLASH_LIB"
+ Value = "$(BUILD_DIR)\OfbdSecureFlash.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "[OFBD Security Update]"
+ Help = "See detail description in each token's help box."
+ TokenType = Expression
+ Lock = Yes
+End
+
+PATH
+ Name = "OFBD_SECURE_FLASH_DIR"
+End
+
+MODULE
+ Help = "Includes SecureFlash.mak to Project"
+ File = "SecureFlash.mak"
+End
+
+ELINK
+ Name = "$(OFBD_SECUREFLASH_LIB)"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ASFUEntry,"
+ Parent = "OFBDPartsList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ASFUInSmm,"
+ Parent = "OFBDInSmmFuncList"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/OFBD/StdEC/StdEC.c b/Core/EM/OFBD/StdEC/StdEC.c
new file mode 100644
index 0000000..7fd87fa
--- /dev/null
+++ b/Core/EM/OFBD/StdEC/StdEC.c
@@ -0,0 +1,531 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/StdEC/StdEC.c 2 3/16/11 10:36p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:36p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/StdEC/StdEC.c $
+//
+// 2 3/16/11 10:36p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] StdEC.mak
+// StdEC.c
+// StdEC.h
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 3/25/05 5:37p Markw
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StdEC.c
+//
+// Description:
+// This function is used to support flashing AMI EC firmware.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "Efi.h"
+#include "token.h"
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include "StdEC.h"
+#include "..\OFBD.h"
+
+
+UINT8 PMBase30 = 0 ; // (for Intel ICHx)
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ObFullRead
+//
+// Description: Waits for Output Buffer Full and then reads the data port
+//
+// Input: None
+//
+// Output: KBC Data port data
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+UINT8 ObFullRead()
+{
+ for (;;) {
+ if (IoRead8(EC_KBC_CMD_PORT) & EC_KBC_OBF) {
+ return IoRead8(EC_KBC_DATA_PORT);
+ }
+ }
+}
+
+void IbFree()
+{
+ for (;;) {
+ if (!(IoRead8(EC_KBC_CMD_PORT) & EC_KBC_IBF)) {
+ break;
+ }
+ }
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: WriteKeyboardCommand
+//
+// Description: Writes command to KBC.
+//
+// Input: Command to send to KBC
+//
+// Output: None
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void WriteKeyboardCommand(UINT8 bCmd)
+{
+ IbFree();
+ IoWrite8(EC_KBC_CMD_PORT, bCmd);
+ IbFree();
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: WriteKeyboardData
+//
+// Description: Writes data to KBC.
+//
+// Input: Data to send to KBC
+//
+// Output: None
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+void WriteKeyboardData(UINT8 bData)
+{
+ IbFree();
+ IoWrite8(EC_KBC_DATA_PORT, bData);
+ IbFree();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDECCommand
+//
+// Description: EC command
+//
+// Input:
+// IN UINT8 bCmd
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDECCommand(IN UINT8 bCmd)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ WriteKeyboardCommand(bCmd);
+ if(ObFullRead() != EC_NO_ERROR_FM_ACK)
+ Status = RETURN_ERR;
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDECCheckSum
+//
+// Description: computes EC data checksum
+//
+// Input:
+// IN UINT8 *BuffPtr
+// IN UINT32 Size
+// Output:
+// UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+OFBDECCheckSum(IN UINT8 *BuffPtr, IN UINT32 Size)
+{
+ UINT32 CheckSum = 0;
+ UINT32 i = 0;
+
+ for (i = 0; i < Size / sizeof (UINT32); i++)
+ CheckSum += *(UINT32*)(BuffPtr + i * sizeof (UINT32));
+
+ return (~CheckSum);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBKeyboardMouseDisable
+//
+// Description: USB Keyboard Mouse Disable
+//
+// Input:
+// IN OFBD_TC_54_STD_EC_STRUCT *ECStructPtr
+// OUT UINT8 *ReturnErr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBKeyboardMouseDisable(
+ IN OFBD_TC_54_STD_EC_STRUCT *ECStructPtr,
+ OUT UINT8 *ReturnErr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(ECStructPtr->dbFlaSts & OFBD_TC_STD_EC_START)
+ {
+ *ReturnErr = 0;
+ // Disable Legacy USB SMI
+ //for example (for Intel ICHx)
+ //PMBase30 = IoRead8 (PM_BASE_ADDRESS + 0x30) ;
+ //IoWrite8 ( (PM_BASE_ADDRESS + 0x30), (PMBase30 & ~8));
+ }
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBKeyboardMouseEnable
+//
+// Description: USB Keyboard Mouse Enable
+//
+// Input:
+// IN OFBD_TC_54_STD_EC_STRUCT *ECStructPtr,
+// IN UINT8 *ReturnErr)
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBKeyboardMouseEnable(
+ IN OFBD_TC_54_STD_EC_STRUCT *ECStructPtr,
+ IN UINT8 *ReturnErr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if((ECStructPtr->dbFlaSts & OFBD_TC_STD_EC_END) | (*ReturnErr != 0))
+ {
+ // Restore Legacy USB SMI
+ //for example (for Intel ICHx)
+ //IoWrite8 ( (PM_BASE_ADDRESS + 0x30), PMBase30 ) ;
+ }
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDStdECStart
+//
+// Description: for EC firmware entry flash mode and start transmit data
+//
+// Input:
+// IN OUT OFBD_TC_54_STD_EC_STRUCT *ECStructPtr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDStdECStart(
+ IN OUT OFBD_TC_54_STD_EC_STRUCT *ECStructPtr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 ChipID = 0;
+ VOID *pOFBDTblEnd = (VOID *)((UINT8 *)ECStructPtr + sizeof(OFBD_TC_54_STD_EC_STRUCT) + sizeof(OFBD_END));
+
+ WriteKeyboardCommand(EC_CMD_DISABLE_KBD); //0xAD
+
+ //Identify Chip ID
+ WriteKeyboardCommand(EC_CMD_GET_CHIPID); //0xA3
+ ChipID = ObFullRead() << 8; //Chip ID HiByte
+ ChipID |= ObFullRead(); //save Chip ID LowByte
+ if(*(UINT16 *)pOFBDTblEnd != ChipID)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_CHIPID;
+ WriteKeyboardCommand(EC_CMD_ENABLE_KBD); //0xAE
+ return(RETURN_ERR);
+ }
+
+ WriteKeyboardCommand(EC_CMD_ENABLE_KBD); //0xAE
+
+ //Entry Flash Mode 0xDF
+ if(OFBDECCommand(EC_CMD_ENTRY_FLASHMODE) != EFI_SUCCESS)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_ENTRY;
+ return(RETURN_ERR);
+ }
+
+ //Erase Flash Memory 0x01
+ if(OFBDECCommand(EC_CMD_ERASE_MEMORY) != EFI_SUCCESS)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_ERASE;
+ WriteKeyboardCommand(EC_CMD_EXIT_FLASHMODE); //0xFE
+ return(RETURN_ERR);
+ }
+
+ //Initial Programming Mode 0x02
+ if(OFBDECCommand(EC_CMD_INITIAL_PM) != EFI_SUCCESS)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_INIT;
+ WriteKeyboardCommand(EC_CMD_EXIT_FLASHMODE); //0xFE
+ return(RETURN_ERR);
+ }
+
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_OK;
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDStdECFlash
+//
+// Description: for EC firmware to transmit data
+//
+// Input:
+// IN OFBD_TC_54_STD_EC_STRUCT *ECStructPtr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDStdECFlash(IN OFBD_TC_54_STD_EC_STRUCT *ECStructPtr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 CheckSum = 0;
+ UINT8 ByteCheckSum = 0;
+ VOID *pOFBDTblEnd = (VOID *)((UINT8 *)ECStructPtr + sizeof(OFBD_TC_54_STD_EC_STRUCT) + sizeof(OFBD_END));
+ UINT8 *DataPtr = (UINT8 *)(*(UINT64 *)((UINT8 *)pOFBDTblEnd - sizeof(OFBD_END)));
+ UINT32 i, j;
+
+ //calc Check Sum
+ CheckSum = OFBDECCheckSum(DataPtr, ECStructPtr->ddSize);
+ if(ECStructPtr->ddChkSum != CheckSum)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_CHKSUM;
+ return(RETURN_ERR);
+ }
+
+ for(i=0; i < ECStructPtr->ddSize; i += 0x80)
+ {
+ //Start Flash Data Transmit
+ if(OFBDECCommand(EC_CMD_START_TRANS) != EFI_SUCCESS)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_START;
+ WriteKeyboardCommand(EC_CMD_EXIT_FLASHMODE); //0xFE
+ return(RETURN_ERR);
+ }
+ ByteCheckSum = 0;
+ for(j = 0; j < 0x80; j++)
+ {
+ WriteKeyboardData(*(DataPtr + i + j));
+ ByteCheckSum += *(DataPtr + i + j);
+ }
+ if(ObFullRead() == ByteCheckSum)
+ {
+ //Write Flash Data 0x04
+ if(OFBDECCommand(EC_CMD_WRITE_DATA) != EFI_SUCCESS)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_WRITE;
+ WriteKeyboardCommand(EC_CMD_EXIT_FLASHMODE); //0xFE
+ return(RETURN_ERR);
+ }
+ }
+ else
+ {
+ i -= 0x80;
+ }
+ }
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_OK;
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDStdECEnd
+//
+// Description: for EC firmware leave flash mode and finished transmit data
+//
+// Input:
+// IN OUT OFBD_TC_54_STD_EC_STRUCT *ECStructPtr
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDStdECEnd(
+ IN OUT OFBD_TC_54_STD_EC_STRUCT *ECStructPtr,
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ //Exit Programming Mode 0x05
+ if(OFBDECCommand(EC_CMD_EXIT_PM) != EFI_SUCCESS)
+ {
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_EXIT;
+ WriteKeyboardCommand(EC_CMD_EXIT_FLASHMODE); //0xFE
+ return(RETURN_ERR);
+ }
+
+ if(pOFBDHdr->OFBD_OS & OFBD_OS_DOS)
+ WriteKeyboardCommand(EC_CMD_RESTART); //0xFF
+ else
+ WriteKeyboardCommand(EC_CMD_EXIT_FLASHMODE); //0xFE
+
+ ECStructPtr->dwRetSts |= OFBD_RS_EC_OK;
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDStdECFlashHandle
+//
+// Description: OFBD Standard EC Flash Handle
+//
+// Input:
+// IN OUT OFBD_TC_54_STD_EC_STRUCT *ECStructPtr
+// IN OUT OFBD_HDR *pOFBDHdr
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+OFBDStdECFlashHandle(
+ IN OUT OFBD_TC_54_STD_EC_STRUCT *ECStructPtr,
+ IN OUT OFBD_HDR *pOFBDHdr)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 ReturnErr = 0;
+
+ USBKeyboardMouseDisable(ECStructPtr, &ReturnErr);
+
+ if(ECStructPtr->dbFlaSts & OFBD_TC_STD_EC_START)
+ {
+ //Entry flash mode
+ ReturnErr = (UINT8)OFBDStdECStart(ECStructPtr);
+ }
+ else if(ECStructPtr->dbFlaSts & OFBD_TC_STD_EC_FLASH)
+ {
+ //Transmit data
+ ReturnErr = (UINT8)OFBDStdECFlash(ECStructPtr);
+ }
+ else if(ECStructPtr->dbFlaSts & OFBD_TC_STD_EC_END)
+ {
+ //Leave flash mode
+ ReturnErr = (UINT8)OFBDStdECEnd(ECStructPtr, pOFBDHdr);
+ }
+ else
+ {
+ Status = RETURN_ERR;
+ }
+
+ USBKeyboardMouseEnable(ECStructPtr, &ReturnErr);
+
+ return(Status);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OFBDEntryPoint
+//
+// Description: OFBD Standard EC Flash Entry Point
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StdECEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ OFBD_HDR *pOFBDHdr;
+ OFBD_EXT_HDR *pOFBDExtHdr;
+ VOID *pOFBDTblEnd;
+ OFBD_TC_54_STD_EC_STRUCT *ECStructPtr;
+
+ if(*pOFBDDataHandled == 0)
+ {
+ pOFBDHdr = (OFBD_HDR *)Buffer;
+ pOFBDExtHdr = (OFBD_EXT_HDR *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_HDR_SIZE));
+ ECStructPtr = (OFBD_TC_54_STD_EC_STRUCT *)((UINT8 *)pOFBDExtHdr + sizeof(OFBD_EXT_HDR));
+ pOFBDTblEnd = (VOID *)((UINT8 *)Buffer + (pOFBDHdr->OFBD_Size));
+
+ //TRACE((-1,"pOFBDHdr address is:%x ------\n",pOFBDHdr));
+ //TRACE((-1,"pOFBDTblEnd address is:%x ------\n",*(UINT64 *)((UINT8 *)pOFBDTblEnd -sizeof(OFBD_END))));
+
+ if(pOFBDHdr->OFBD_FS & OFBD_FS_EC)
+ {
+ //Check Type Code ID
+ if(pOFBDExtHdr->TypeCodeID == OFBD_EXT_TC_EC)
+ {
+ //IoWrite32(0x300, *(UINT32 *)((UINT8 *)pOFBDTblEnd -4)); //debug
+
+ if(OFBDStdECFlashHandle(ECStructPtr, pOFBDHdr) == EFI_SUCCESS)
+ {
+ //Standard EC Flash Handled
+ *pOFBDDataHandled = 0xFF;
+ return;
+ }
+ else
+ {
+ //Not Standard EC Flash Data
+ *pOFBDDataHandled = 0;
+ return;
+ }
+ }
+ else
+ {
+ //Error occured
+ *pOFBDDataHandled = 0xFE;
+ return;
+ }
+ }
+ }
+
+ return;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/OFBD/StdEC/StdEC.cif b/Core/EM/OFBD/StdEC/StdEC.cif
new file mode 100644
index 0000000..07273a2
--- /dev/null
+++ b/Core/EM/OFBD/StdEC/StdEC.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Embedded Controller Flash"
+ category = ModulePart
+ LocalRoot = "Core\EM\OFBD\StdEC\"
+ RefName = "OFBD_STDEC"
+[files]
+"StdEC.sdl"
+"StdEC.mak"
+"StdEC.c"
+"StdEC.h"
+<endComponent>
diff --git a/Core/EM/OFBD/StdEC/StdEC.h b/Core/EM/OFBD/StdEC/StdEC.h
new file mode 100644
index 0000000..c126f0c
--- /dev/null
+++ b/Core/EM/OFBD/StdEC/StdEC.h
@@ -0,0 +1,102 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OFBD/StdEC/StdEC.h 2 3/16/11 10:36p Terrylin $
+//
+// $Revision: 2 $
+//
+// $Date: 3/16/11 10:36p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OFBD/StdEC/StdEC.h $
+//
+// 2 3/16/11 10:36p Terrylin
+// [TAG] EIP51285
+// [Category] Improvement
+// [Description] Fill the description for user more clearly.
+// [Files] StdEC.mak
+// StdEC.c
+// StdEC.h
+//
+// 1 4/13/09 5:46a Lawrencechang
+// Initial check-in.
+//
+// 1 3/13/06 1:16a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StdEC.h
+//
+// Description: Header file for the StdEC
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef _EFI_STDEC_H_
+#define _EFI_STDEC_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define RETURN_ERR 1
+//===============================
+// Standard EC Flash Port define
+//===============================
+#define EC_KBC_DATA_PORT 0x60
+#define EC_KBC_CMD_PORT 0x64
+
+//===============================
+// Standard EC status bits definition
+//===============================
+#define EC_KBC_OBF 0x01
+#define EC_KBC_IBF 0x02
+
+//===========================
+// Standard EC Flash Command
+//===========================
+#define EC_CMD_ERASE_MEMORY 0x01
+#define EC_CMD_INITIAL_PM 0x02
+#define EC_CMD_START_TRANS 0x03
+#define EC_CMD_WRITE_DATA 0x04
+#define EC_CMD_EXIT_PM 0x05
+#define EC_CMD_ENTRY_FLASHMODE 0x0DF
+#define EC_CMD_EXIT_FLASHMODE 0x0FE
+#define EC_CMD_RESTART 0x0FF
+#define EC_NO_ERROR_FM_ACK 0x0FA
+#define EC_CMD_GET_CHIPID 0x0A3
+#define EC_CMD_DISABLE_KBD 0x0AD
+#define EC_CMD_ENABLE_KBD 0x0AE
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/OFBD/StdEC/StdEC.mak b/Core/EM/OFBD/StdEC/StdEC.mak
new file mode 100644
index 0000000..a3d3624
--- /dev/null
+++ b/Core/EM/OFBD/StdEC/StdEC.mak
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OFBD/StdEC/StdEC.mak 2 3/16/11 10:35p Terrylin $
+#
+# $Revision: 2 $
+#
+# $Date: 3/16/11 10:35p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OFBD/StdEC/StdEC.mak $
+#
+# 2 3/16/11 10:35p Terrylin
+# [TAG] EIP51285
+# [Category] Improvement
+# [Description] Fill the description for user more clearly.
+# [Files] StdEC.mak
+# StdEC.c
+# StdEC.h
+#
+# 1 4/13/09 5:46a Lawrencechang
+# Initial check-in.
+#
+# 1 3/18/07 5:23p Felixp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: StdEC.mak
+#
+# Description: Make file for the StdEC.obj
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : StdEC
+
+StdEC : $(BUILD_DIR)\StdEC.mak StdECBin
+
+$(BUILD_DIR)\StdEC.mak : $(OFBD_StdEC_DIR)\$(@B).cif $(OFBD_StdEC_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OFBD_StdEC_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+StdECBin :
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\StdEC.mak all\
+ NAME=StdEC \
+ TYPE=LIBRARY LIBRARY_NAME=$(STDECLIB)
+
+$(STDECLIB) : StdEC
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/OFBD/StdEC/StdEC.sdl b/Core/EM/OFBD/StdEC/StdEC.sdl
new file mode 100644
index 0000000..1d2caf8
--- /dev/null
+++ b/Core/EM/OFBD/StdEC/StdEC.sdl
@@ -0,0 +1,39 @@
+TOKEN
+ Name = "StdEC_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable Embedded Controller Flash support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "STDECLIB"
+ Value = "$(BUILD_DIR)\StdEC.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "OFBD_StdEC_DIR"
+End
+
+MODULE
+ Help = "Includes StdEC.mak to Project"
+ File = "StdEC.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\StdEC.lib"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "StdECEntry,"
+ Parent = "OFBDPartsList"
+ Token = "StdEC_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/OemActivation/OemActivation.c b/Core/EM/OemActivation/OemActivation.c
new file mode 100644
index 0000000..efc55f6
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.c
@@ -0,0 +1,505 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/OemActivation.c 19 5/22/12 4:27p Vyacheslava $
+//
+// $Revision: 19 $
+//
+// $Date: 5/22/12 4:27p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/OemActivation.c $
+//
+// 19 5/22/12 4:27p Vyacheslava
+// [TAG] EIP90324
+// [Description] The OA3MSDMvariable variable has improper GUID.
+//
+// 18 2/23/12 12:19p Vyacheslava
+// Fixed build error for 32 bit mode.
+//
+// 17 1/12/12 9:20a Vyacheslava
+// [TAG] EIP80094
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] There are duplicated MSDM published in the ACPI in PI 1.2
+//
+// 16 10/28/11 5:37p Vyacheslava
+// [TAG] EIP64110
+// [Category] Improvement
+//
+// 15 9/26/11 11:19a Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] changed protocol SmmCpuState to SmmCpuProtocol
+//
+// 14 9/23/11 3:16p Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Changed according to Aptio 4.6.5.x Components Porting
+// Guide (Conversion of the SMM Drivers).
+//
+// 13 8/08/11 10:15a Vyacheslava
+//
+// 12 8/03/11 2:24p Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Updated to be compliant with PI 1.2, and UEFI 2.3.1
+// specifications.
+//
+// 11 7/07/11 11:12a Vyacheslava
+// [TAG] EIP62009
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] if OEM_ACTIVATION_TABLE_LOCATION is not zero, the code does
+// not compile.
+//
+// 10 6/16/11 10:55a Vyacheslava
+// [TAG] EIP62009
+// [Category] New Feature
+// [Description] Preserve the OA30 key during the BIOS recovery path.
+//
+// 9 6/10/11 11:00a Vyacheslava
+//
+// 8 5/24/11 3:53p Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Changed SW SMI protocol according to request from the
+// Utility.
+//
+// 7 5/20/11 12:34p Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Added code that updates ACPI table in OS Runtime.
+//
+// 6 5/18/11 11:21a Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Implementation according comment#8 in the EIP#59717.
+//
+// 5 4/29/11 12:44p Vyacheslava
+// [TAG] EIP58139
+// [Category] New Feature
+// [Description] Added code to place Oem Activation Key in NCB.
+//
+// 4 12/17/10 1:46p Vyacheslava
+// [TAG] EIP48520
+// [Category] Improvement
+// [Description] - Deleted temporary structure for testing FID;
+// - Simplified MSDM structure;
+//
+// 3 12/16/10 5:02p Vyacheslava
+// - Added checking for FID version;
+// - Fixed bug with structure overflow;
+//
+// 2 11/19/10 4:18p Vyacheslava
+// [TAG] EIP48520
+// [Category] Improvement
+// [Description] - $FID structure should not be redefined but updated
+// where it belong: FwVersion.h in CSPLIB component
+// - the 49 bytes of $FID should be intialized with 0xff
+// - the loading of the MSDM from $FID should be done based on the length
+// of the MSDM field as specified in the $FID structure and not hardcoded
+// to 49 bytes
+// - checksum field should be initilized to 0x0 not 0x88 (which is the
+// checksum value of the example of the Microsoft spec)
+//
+// 1 11/18/10 1:15p Vyacheslava
+// Initial creation
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemActivation.c
+//
+// Description: Microsoft OEM Activation 3.0
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+
+#include <AmiDxeLib.h>
+#include <Protocol/AcpiTable.h>
+#include <PPI/FwVersion.h>
+#include <AmiHobs.h>
+#include "OemActivation.h"
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: LocateSectionResource
+//
+// Description: This function locate resource binary by GUID.
+//
+// Input:
+// pResourceGuid - pointer to recourse GUID
+// pResourceSectionGuid - pointer to recourse section GUID
+// Address - pointer to returning address of the resource
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LocateSectionResource(
+ IN EFI_GUID *pResourceGuid,
+ IN EFI_GUID *pResourceSectionGuid,
+ OUT UINT8 **Address )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer = NULL;
+ UINTN NumberOfHandles;
+ UINTN Index;
+ UINT32 Authentication;
+ UINTN i;
+ EFI_GUID *pGuid = NULL;
+ UINTN SectionSize;
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+ EFI_GUID EfiFirmwareVolumeProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVolumeProtocol = NULL;
+#else
+ EFI_GUID EfiFirmwareVolumeProtocolGuid = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *FwVolumeProtocol = NULL;
+#endif
+
+ // Locate the Firmware volume protocol
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &EfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer
+ );
+ if (EFI_ERROR(Status))
+ return EFI_NOT_FOUND;
+
+ // Find and read raw data
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+
+ Status = pBS->HandleProtocol(
+ HandleBuffer[Index],
+ &EfiFirmwareVolumeProtocolGuid,
+ &FwVolumeProtocol
+ );
+ if (EFI_ERROR(Status))
+ continue;
+
+ i = 0;
+ while(1) {
+ SectionSize = 0;
+ Status = FwVolumeProtocol->ReadSection(
+ FwVolumeProtocol,
+ pResourceGuid,
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,
+ i++,
+ &pGuid,
+ &SectionSize,
+ &Authentication
+ );
+ if (EFI_ERROR(Status))
+ break;
+ else if ( !guidcmp(pGuid, pResourceSectionGuid ) ) {
+ *Address = (UINT8*)pGuid;
+ goto LocateSectionResource_exit;
+ }
+ pBS->FreePool(pGuid);
+ pGuid = NULL;
+ }
+ }
+
+LocateSectionResource_exit:
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetProductKey
+//
+// Description: This function locates the Product Key.
+//
+// Input: Address - pointer to returning address of the Product Key structure.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetProductKey(
+ IN EFI_PHYSICAL_ADDRESS StartAddr,
+ IN EFI_PHYSICAL_ADDRESS EndAddr,
+ OUT UINT8 **Address )
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ EFI_GUID FidTableSectionGuid = FID_TABLE_SECTION_GUID;
+ EFI_PHYSICAL_ADDRESS i;
+
+ for ( i = StartAddr; i < EndAddr; i++ )
+ if ( !MemCmp((UINT8*)i, &FidTableSectionGuid, sizeof(EFI_GUID)) ) {
+
+ // skip the GUID
+ i += sizeof(EFI_GUID);
+
+ // Check version of the FID table
+ if ( ((FW_VERSION*)i)->StructVersion < FID_SUPPORTED_VERSION ) {
+ TRACE((TRACE_ALWAYS, "OEM Activation: FID table version %d unsupported!!!\n",((FW_VERSION*)i)->StructVersion));
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+
+ // skip the ACPI header
+ *Address = (UINT8*)((FW_VERSION*)i)->OemActivationKey;
+ TRACE((TRACE_ALWAYS, "OEM Activation: Product Key Address %X\n",*Address));
+
+ Status = EFI_SUCCESS;
+ break;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PreserveProductKey
+//
+// Description: This function preserves the Product Key.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PreserveProductKey(VOID)
+{
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ RECOVERY_IMAGE_HOB *RecoveryHob;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ EFI_CONFIGURATION_TABLE *Table = pST->ConfigurationTable;
+ UINTN i;
+ UINT8 *ProductKey;
+ UINT8 *ProductKeyPreserve;
+
+ // Find the Product Key place in the recovery HOB
+ for( i = 0; i < pST->NumberOfTableEntries; i++, Table++ ) {
+
+ if ( !MemCmp(&Table->VendorGuid, &HobListGuid, sizeof(EFI_GUID)) ) {
+
+ RecoveryHob = Table->VendorTable;
+ Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob);
+ if (!EFI_ERROR(Status)) {
+
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ // Get the Product Key pointer in the recovery HOB
+ Status = GetProductKey(
+ RecoveryHob->Address + FLASH_SIZE - FV_BB_SIZE,
+ RecoveryHob->Address + FLASH_SIZE - sizeof(EFI_GUID),
+ &ProductKeyPreserve
+ );
+ if (!EFI_ERROR(Status)) {
+ // Get the Product Key pointer in the Flash memory
+ Status = GetProductKey(FV_BB_BASE, FV_BB_END_ADDR, &ProductKey);
+ if (EFI_ERROR(Status))
+ break;
+ MemCpy( ProductKeyPreserve, ProductKey, sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR) );
+ }
+#else
+ ProductKeyPreserve = (UINT8*)(RecoveryHob->Address + FLASH_SIZE - OEM_ACTIVATION_TABLE_OFFSET);
+ ProductKey = (UINT8*)OEM_ACTIVATION_TABLE_ADDRESS;
+ MemCpy( ProductKeyPreserve, ProductKey, sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR) );
+ Status = EFI_SUCCESS;
+#endif
+ }
+ }
+ }
+ TRACE((TRACE_ALWAYS,"PreserveProductKey: Status %r\n",Status));
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OemActivation_EntryPoint
+//
+// Description: This function is the entry point of the eModule.
+//
+// Input:
+// ImageHandle - Image handle
+// *SystemTable - Pointer to the system table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI OemActivation_EntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_GUID FidTableGuid = FID_TABLE_GUID;
+ EFI_GUID FidTableSectionGuid = FID_TABLE_SECTION_GUID;
+ FW_VERSION *Fid;
+ UINT8 *FidSection = NULL;
+ EFI_ACPI_MSDM_TABLE *Msdm = NULL;
+ EFI_OA3_MSDM_STRUCTURE MsdmVariable = {0};
+ EFI_GUID AmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+ UINTN i;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // Check if it's a Recovery Mode then preserve the Product Key
+ if (GetBootMode() == BOOT_IN_RECOVERY_MODE) {
+ Status = PreserveProductKey();
+ return Status;
+ }
+
+ // Locate the $FID table
+ Status = LocateSectionResource(
+ &FidTableGuid,
+ &FidTableSectionGuid,
+ &FidSection
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((TRACE_ALWAYS, "OEM Activation: FID table Not Found!!!\n"));
+ return Status;
+ }
+ Fid = (FW_VERSION*)(FidSection + sizeof(EFI_GUID)); // skip the GUID
+
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ // Check version of the FID table
+ if ( Fid->StructVersion < FID_SUPPORTED_VERSION ) {
+ TRACE((TRACE_ALWAYS, "OEM Activation: FID table version %d is unsupported!!!\n",Fid->StructVersion));
+ return EFI_UNSUPPORTED;
+ }
+#endif
+
+ // Create MSDM table
+ Status = pBS->AllocatePool( EfiACPIMemoryNVS, sizeof(EFI_ACPI_MSDM_TABLE), &Msdm );
+ if (EFI_ERROR(Status))
+ return Status;
+ Msdm->Header.Signature = MSDM_SIG;
+ Msdm->Header.Length = sizeof(EFI_ACPI_MSDM_TABLE);
+ Msdm->Header.Revision = MSDM_REVISION;
+ Msdm->Header.OemRev = ACPI_OEM_REV;
+ Msdm->Header.CreatorId = CREATOR_ID_AMI;
+ Msdm->Header.CreatorRev = CREATOR_REV_MS;
+
+ // Copy OEM ID and OEM Table ID
+ MemCpy(
+ (UINT8*)&Msdm->Header.OemId,
+ (UINT8*)&Fid->OemId,
+ sizeof(Fid->OemId)
+ );
+ MemCpy(
+ (UINT8*)&Msdm->Header.OemTblId,
+ (UINT8*)&Fid->OemTableId,
+ sizeof(Fid->OemTableId)
+ );
+
+ // Copy OEM Activation Key
+ MemCpy(
+ (UINT8*)&Msdm->Version,
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ (UINT8*)&Fid->OemActivationKey, // Copy Key from the FID structure
+#else
+ (UINT8*)OEM_ACTIVATION_TABLE_ADDRESS, // Copy Key from the NCB
+#endif
+ sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR)
+ );
+ pBS->FreePool(FidSection);
+
+ // Check if there is empty Product Key
+ for ( i = 0; i < sizeof(Msdm->Data); i++ ) {
+
+ if ( Msdm->Data[i] != 0xFF ) {
+
+ EFI_ACPI_TABLE_PROTOCOL *AcpiTableProtocol = NULL;
+ UINTN TableKey = 0;
+
+ // Locate the ACPI support protocol
+ Status = pBS->LocateProtocol(
+ &gEfiAcpiTableProtocolGuid,
+ NULL,
+ &AcpiTableProtocol
+ );
+ if (EFI_ERROR(Status))
+ TRACE((TRACE_ALWAYS, "OEM Activation: Unable to locate AcpiSupportProtocol!\n"));
+
+ else {
+ // Publish MSDM ACPI table
+ Status = AcpiTableProtocol->InstallAcpiTable(
+ AcpiTableProtocol,
+ Msdm,
+ sizeof(EFI_ACPI_MSDM_TABLE),
+ &TableKey
+ );
+ if (EFI_ERROR(Status))
+ TRACE((TRACE_ALWAYS, "OEM Activation: SetAcpiTable failed!\n"));
+ else
+ TRACE((TRACE_ALWAYS, "OEM Activation: MSDM table has been published.\n"));
+ }
+ pBS->FreePool(Msdm);
+ return Status;
+ }
+ }
+
+ TRACE((TRACE_ALWAYS, "OEM Activation: Found empty Product Key.\n"));
+
+ MsdmVariable.MsdmAddress = (EFI_PHYSICAL_ADDRESS)Msdm;
+#if OEM_ACTIVATION_TABLE_LOCATION == 1
+ MsdmVariable.ProductKeyAddress = (EFI_PHYSICAL_ADDRESS)OEM_ACTIVATION_TABLE_ADDRESS;
+#endif
+
+ Status = pRS->SetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &AmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(EFI_OA3_MSDM_STRUCTURE),
+ &MsdmVariable
+ );
+ ASSERT_EFI_ERROR(Status);
+ TRACE((TRACE_ALWAYS, "OEM Activation: MsdmAddress=%X\n",MsdmVariable.MsdmAddress));
+
+ return Status;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/OemActivation/OemActivation.chm b/Core/EM/OemActivation/OemActivation.chm
new file mode 100644
index 0000000..b19ecde
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.chm
Binary files differ
diff --git a/Core/EM/OemActivation/OemActivation.cif b/Core/EM/OemActivation/OemActivation.cif
new file mode 100644
index 0000000..bdf742e
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "OemActivation"
+ category = eModule
+ LocalRoot = "Core\EM\OemActivation\"
+ RefName = "OemActivation"
+[files]
+"OemActivation.mak"
+"OemActivation.sdl"
+"OemActivation.c"
+"OemActivation.h"
+"OemActivation.dxs"
+"OemActivation.chm"
+"OemActivationHook.c"
+[parts]
+"SmmOemActivation"
+<endComponent>
diff --git a/Core/EM/OemActivation/OemActivation.dxs b/Core/EM/OemActivation/OemActivation.dxs
new file mode 100644
index 0000000..ccd2490
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.dxs
@@ -0,0 +1,93 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/OemActivation.dxs 6 1/12/12 9:21a Vyacheslava $
+//
+// $Revision: 6 $
+//
+// $Date: 1/12/12 9:21a $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/OemActivation.dxs $
+//
+// 6 1/12/12 9:21a Vyacheslava
+// Removed dependency on SMM protocols.
+//
+// 5 10/03/11 11:04a Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] (7) IsRoceveryOverSerial, NetBootHotkey, OpromTxT,
+// SimpleBootFlag, SLP10, SlpSupport, SmiVariable
+//
+// 4 9/22/11 11:13a Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Changed according to Aptio 4.6.5.x Components Porting
+// Guide (Conversion of the SMM Drivers).
+//
+// 3 8/08/11 10:14a Vyacheslava
+// [TAG] EIP64110
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] Updated to be compliant with PI 1.2, and UEFI 2.3.1
+// specifications.
+//
+// 2 5/20/11 12:35p Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Added SMM dependency.
+//
+// 1 11/22/10 10:10a Vyacheslava
+//
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemActivation.dxs
+//
+// Description: This file is the dependency file for OemActivation eModule.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+//---------------------------------------------------------------------------
+// Header files for GUID definitions
+//---------------------------------------------------------------------------
+
+
+#include <Protocol/AcpiTable.h>
+
+DEPENDENCY_START
+ EFI_ACPI_TABLE_PROTOCOL_GUID
+DEPENDENCY_END
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/OemActivation/OemActivation.h b/Core/EM/OemActivation/OemActivation.h
new file mode 100644
index 0000000..a325b5b
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.h
@@ -0,0 +1,194 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/OemActivation.h 13 5/22/12 4:28p Vyacheslava $
+//
+// $Revision: 13 $
+//
+// $Date: 5/22/12 4:28p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/OemActivation.h $
+//
+// 13 5/22/12 4:28p Vyacheslava
+// Added AMI_GLOBAL_VARIABLE_GUID definition.
+//
+// 12 1/12/12 9:22a Vyacheslava
+// The SW_SMI_OA3_FUNCTION_NUMBER token removed to SDL file.
+//
+// 11 9/29/11 4:18p Vyacheslava
+// [TAG] EIP70134
+// [Description] Changed definition of the SW_SMI_OA3_FUNCTION_NUMBER to
+// 0xDF.
+//
+// 10 8/08/11 10:14a Vyacheslava
+//
+// 9 6/16/11 10:56a Vyacheslava
+// [TAG] EIP62009
+// [Category] New Feature
+// [Description] Preserve the OA30 key during the BIOS recovery path.
+//
+// 8 6/10/11 10:57a Vyacheslava
+//
+// 7 5/26/11 11:10a Vyacheslava
+//
+// 6 5/20/11 12:35p Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] added structure for updating ACPI.
+//
+// 5 5/18/11 11:34a Vyacheslava
+// [TAG] EIP59717
+// [Category] New Feature
+// [Description] Implementation according comment#8 in the EIP#59717.
+//
+// 4 12/17/10 1:45p Vyacheslava
+// [TAG] EIP48520
+// [Category] Improvement
+// [Description] - Deleted temporary structure for testing FID;
+// - Simplified MSDM structure;
+//
+// 3 12/16/10 5:03p Vyacheslava
+// Added definition for FID table version
+//
+// 2 11/19/10 4:19p Vyacheslava
+// [TAG] EIP48520
+// [Category] Improvement
+// [Description] EIP#48520 comment#2
+//
+// 1 11/18/10 1:15p Vyacheslava
+// Initial creation
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemActivation.h
+//
+// Description: Header file for OEM Activation eModule.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+#ifndef __MS_OEM_ACTIVATION_H
+#define __MS_OEM_ACTIVATION_H
+
+//----------------------------------------------------------------------------
+
+#include <EFI.h>
+#include <ACPI.h>
+
+//----------------------------------------------------------------------------
+
+#define MSDM_SIG 0x4D44534D // "MSDM" - M$ Digital Marker
+#define MSDM_REVISION 0x03 //
+#define MSDM_VERSION 0x01 //
+#define MSDM_DATA_TYPE 0x01 //
+#define FID_SUPPORTED_VERSION 0x04 // Supported version of the FID table
+
+#define FID_TABLE_GUID \
+ { 0x3fd1d3a2, 0x99f7, 0x420b, 0xbc, 0x69, 0x8b, 0xb1, 0xd4, 0x92, 0xa3, 0x32 }
+
+#define FID_TABLE_SECTION_GUID \
+ { 0x2ebe0275, 0x6458, 0x4af9, 0x91, 0xed, 0xd3, 0xf4, 0xed, 0xb1, 0x00, 0xaa }
+
+// This GUID should be defined in the next Core label (4.6.5.4 or greater)
+#ifndef AMI_GLOBAL_VARIABLE_GUID
+#define AMI_GLOBAL_VARIABLE_GUID \
+ {0x1368881,0xc4ad,0x4b1d,0xb6,0x31,0xd5,0x7a,0x8e,0xc8,0xdb,0x6b}
+#endif
+
+#define EFI_OA3_MSDM_VARIABLE L"OA3MSDMvariable"
+
+// if Product Key located in the NBC
+#if OEM_ACTIVATION_TABLE_LOCATION == 1
+#define FLASH_DEVICE_BASE_ADDRESS (0xFFFFFFFF-FLASH_SIZE+1)
+#define OEM_ACTIVATION_BLOCK_ADDRESS (OEM_ACTIVATION_TABLE_ADDRESS-FLASH_DEVICE_BASE_ADDRESS)
+#define OEM_ACTIVATION_BLOCK_END (OEM_ACTIVATION_BLOCK_ADDRESS+OEM_ACTIVATION_TABLE_SIZE)
+#define OEM_ACTIVATION_TABLE_OFFSET (0xFFFFFFFF-OEM_ACTIVATION_TABLE_ADDRESS+1)
+#endif
+
+#ifndef FV_BB_END_ADDR
+#define FV_BB_END_ADDR (0xFFFFFFFF-16-sizeof(EFI_GUID)+1)
+#endif
+
+#ifndef FV_BB_SIZE
+#define FV_BB_SIZE (0xFFFFFFFF-FV_BB_BASE+1)
+#endif
+
+//----------------------------------------------------------------------------
+
+#pragma pack (1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: MSDM_STRUCTURE
+//
+// Description: This structure comes out of the document "M$ Digital Marker Pilot"
+//
+// Fields:
+// Name Length Description
+// ------------------------------------------------------------------
+// Header - Standard ACPI header
+// Version 4 0x1
+// Reserved 4 0x0
+// DataType 4 0x1
+// DataReserved 4 0x0
+// DataLength 4 0x1D
+// Data 29 5x5 Product Key, including "-" (BH3RN-B7FDM-C7WGT-4CR4X-6CKHM)
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _EFI_ACPI_MSDM_TABLE {
+ ACPI_HDR Header;
+ UINT32 Version;
+ UINT32 Reserved;
+ UINT32 DataType;
+ UINT32 DataReserved;
+ UINT32 DataLength;
+ UINT8 Data[29];
+} EFI_ACPI_MSDM_TABLE;
+
+
+typedef struct _EFI_OA3_MSDM_STRUCTURE {
+ EFI_PHYSICAL_ADDRESS XsdtAddress;
+ EFI_PHYSICAL_ADDRESS MsdmAddress;
+ EFI_PHYSICAL_ADDRESS ProductKeyAddress;
+} EFI_OA3_MSDM_STRUCTURE;
+
+
+#pragma pack()
+
+//---------------------------------------------------------------------------
+
+#endif
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/OemActivation/OemActivation.mak b/Core/EM/OemActivation/OemActivation.mak
new file mode 100644
index 0000000..e149a85
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.mak
@@ -0,0 +1,159 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OemActivation/OemActivation.mak 9 1/12/12 9:24a Vyacheslava $
+#
+# $Revision: 9 $
+#
+# $Date: 1/12/12 9:24a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OemActivation/OemActivation.mak $
+#
+# 9 1/12/12 9:24a Vyacheslava
+# Removed dependency on SMM protocols. Changed type of module to
+# BS_DRIVER
+#
+# 8 10/18/11 10:00a Vyacheslava
+# [TAG] EIP70134
+# [Description] Changed GUID to let AFU know that SW SMI number is
+# changed.
+#
+# 7 10/03/11 11:04a Vyacheslava
+# [TAG] EIP64110
+# [Category] Spec Update
+# [Severity] Normal
+# [Description] (7) IsRoceveryOverSerial, NetBootHotkey, OpromTxT,
+# SimpleBootFlag, SLP10, SlpSupport, SmiVariable
+#
+# 6 9/22/11 11:22a Vyacheslava
+# [TAG] EIP64110
+# [Category] Spec Update
+# [Severity] Normal
+# [Description] Changed according to Aptio 4.6.5.x Components Porting
+# Guide.
+#
+# 5 7/07/11 11:18a Vyacheslava
+#
+# 4 5/26/11 11:33a Vyacheslava
+#
+# 3 4/29/11 12:42p Vyacheslava
+# [TAG] EIP58139
+# [Category] New Feature
+# [Description] Added macros to place Oem Activation Key in NCB.
+#
+# 2 12/17/10 1:43p Vyacheslava
+# [TAG] EIP48520
+# [Category] Improvement
+# [Description] Added checking for version of the CSP Library.
+#
+# 1 11/18/10 1:15p Vyacheslava
+# Initial creation
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OemActivation.mak
+#
+# Description: Make file for OemActivation eModule.
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+
+!IF "$(OEM_ACTIVATION_TABLE_LOCATION)"=="0" && "$(CSP_LIB_MAJOR_VER)"=="00" && "$(CSP_LIB_MINOR_VER)"<"17"
+!ERROR To use OEM Activation 3.0 CSP Library must have version 00.17 or newer.
+!ENDIF
+
+!IFNDEF PI_SPECIFICATION_VERSION
+PI_SPECIFICATION_VERSION = 0
+!ENDIF
+
+all : OemActivation
+
+OemActivation : $(BUILD_DIR)\OemActivation.mak OemActivationBin
+
+$(BUILD_DIR)\OemActivation.mak : $(OemActivation_DIR)\$(@B).cif $(OemActivation_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OemActivation_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+
+!IF "$(OEM_ACTIVATION_TABLE_LOCATION)"=="0"
+
+OemActivationBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OemActivation.mak all\
+ GUID=76D5CF91-0C55-434E-97C2-D2825C82E610\
+ ENTRY_POINT=OemActivation_EntryPoint\
+ TYPE=BS_DRIVER\
+ DEPEX1=$(OemActivation_DIR)\OemActivation.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.h"\
+ COMPRESS=1
+
+!ELSE
+
+OemActivationObjs = $(BUILD_DIR)\$(OemActivation_DIR)\OemActivation.obj
+
+OemActivationBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OemActivation.mak all\
+ OBJECTS="$(OemActivationObjs)" \
+ GUID=76D5CF91-0C55-434E-97C2-D2825C82E610\
+ ENTRY_POINT=OemActivation_EntryPoint\
+ TYPE=BS_DRIVER\
+ DEPEX1=$(OemActivation_DIR)\OemActivation.dxs\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.h"\
+ COMPRESS=1
+
+#---------------------------------------------------------------------------
+# Create Launch SCLEAN Pei Component
+#---------------------------------------------------------------------------
+OemActivationHook : $(BUILD_DIR)\OemActivation.mak OemActivationHookBin
+
+OemActivationHookObjs = $(BUILD_DIR)\$(OemActivation_DIR)\OemActivationHook.obj
+
+OemActivationHookBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OemActivation.mak all\
+ "CFLAGS=$(CFLAGS:/W4=/W3) /I$(OFBD_DIR)" \
+ OBJECTS="$(OemActivationHookObjs)" \
+ NAME=OemActivation \
+ TYPE=LIBRARY LIBRARY_NAME=$(OEM_ACTIVATION_LIB)
+
+$(OEM_ACTIVATION_LIB) : OemActivationHook
+
+OEM_ACTIVATION_DESCRIPTOR=HOLE(\
+name=OEM_ACTIVATION, address=$(OEM_ACTIVATION_TABLE_ADDRESS),\
+offset=$(OEM_ACTIVATION_TABLE_ADDRESS)-$(FLASH_BASE),\
+size=$(OEM_ACTIVATION_TABLE_SIZE)\
+)
+
+!ENDIF
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/OemActivation/OemActivation.sdl b/Core/EM/OemActivation/OemActivation.sdl
new file mode 100644
index 0000000..2da7d1b
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivation.sdl
@@ -0,0 +1,79 @@
+TOKEN
+ Name = "OemActivation_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable OemActivation support in Project"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "OEM_ACTIVATION_TABLE_LOCATION"
+ Value = "0"
+ Help = "OEM Activation Table location: \0 = FID Table.\1 = Non-Critical Block."
+ TokenType = Integer
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "OEM_ACTIVATION_TABLE_ADDRESS"
+ Value = "0xFFE10000"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ACTIVATION_TABLE_LOCATION" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ACTIVATION_TABLE_SIZE"
+ Value = "0x10000"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "OEM_ACTIVATION_TABLE_LOCATION" "=" "1"
+End
+
+TOKEN
+ Name = "OEM_ACTIVATION_LIB"
+ Value = "$(BUILD_DIR)\OemActivation.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "OemActivation_DIR"
+End
+
+MODULE
+ Help = "Includes OemActivation.mak to Project"
+ File = "OemActivation.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OemActivation.lib"
+ Parent = "PRESERVE_LIB"
+ Token = "OEM_ACTIVATION_TABLE_LOCATION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OemActivation.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(OEM_ACTIVATION_DESCRIPTOR)"
+ Parent = "ROM_IMAGE"
+ Token = "OEM_ACTIVATION_TABLE_LOCATION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemActivationUpdateBlockTypeId,"
+ Parent = "SMIFlashEndHandlerList"
+ Token = "OEM_ACTIVATION_TABLE_LOCATION" "=" "1"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/OemActivation/OemActivationHook.c b/Core/EM/OemActivation/OemActivationHook.c
new file mode 100644
index 0000000..9211bc4
--- /dev/null
+++ b/Core/EM/OemActivation/OemActivationHook.c
@@ -0,0 +1,116 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/OemActivationHook.c 3 6/10/11 10:57a Vyacheslava $
+//
+// $Revision: 3 $
+//
+// $Date: 6/10/11 10:57a $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/OemActivationHook.c $
+//
+// 3 6/10/11 10:57a Vyacheslava
+//
+// 2 5/26/11 11:34a Vyacheslava
+//
+// 1 4/29/11 12:39p Vyacheslava
+// [TAG] EIP58139
+// [Category] New Feature
+// [Description] Added SW SMI hook to place Oem Activation Key in NCB.
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: OemActivationHook.c
+//
+// Description: SW SMI hook.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+
+#include <AmiDxeLib.h>
+#include <Protocol/SmiFlash.h>
+#include "OemActivation.h"
+
+//----------------------------------------------------------------------------
+
+
+#if OEM_ACTIVATION_TABLE_LOCATION == 1
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OemActivationUpdateBlockTypeId
+//
+// Description: This function is SW SMI hook that sets Flash Block Description
+// type for AMI AFU utility. (EIP#58139)
+//
+// Input:
+// SwSmiNum - SW SMI value number
+// Buffer - Flash descriptor address
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID OemActivationUpdateBlockTypeId (
+ IN UINT8 SwSmiNum,
+ IN UINT64 Buffer )
+{
+ BLOCK_DESC *BlockDesc;
+ UINTN i;
+
+ // return if SW SMI value is not "Get Flash Info"
+ if (SwSmiNum != SMIFLASH_GET_FLASH_INFO)
+ return;
+
+ BlockDesc = (BLOCK_DESC*)&((INFO_BLOCK*)Buffer)->Blocks;
+
+ for (i = 0; i < ((INFO_BLOCK*)Buffer)->TotalBlocks; i++) {
+
+ TRACE((TRACE_ALWAYS,"OemActivationUpdateBlockTypeId: %08X(%08X), Block %08X\n",OEM_ACTIVATION_BLOCK_ADDRESS,OEM_ACTIVATION_BLOCK_END,BlockDesc[i].StartAddress));
+
+ if (BlockDesc[i].StartAddress < OEM_ACTIVATION_BLOCK_ADDRESS)
+ continue;
+
+ if (BlockDesc[i].StartAddress >= OEM_ACTIVATION_BLOCK_END)
+ continue;
+
+ TRACE((TRACE_ALWAYS,"OemActivationUpdateBlockTypeId: Found Blocks %08X\n",BlockDesc[i].StartAddress));
+
+ BlockDesc[i].Type = OA3_FLASH_BLOCK_DESC_TYPE;
+ }
+}
+
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/OemActivation/SmmOemActivation.c b/Core/EM/OemActivation/SmmOemActivation.c
new file mode 100644
index 0000000..df9502d
--- /dev/null
+++ b/Core/EM/OemActivation/SmmOemActivation.c
@@ -0,0 +1,491 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/SmmOemActivation.c 6 6/14/13 9:48a Vyacheslava $
+//
+// $Revision: 6 $
+//
+// $Date: 6/14/13 9:48a $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/SmmOemActivation.c $
+//
+// 6 6/14/13 9:48a Vyacheslava
+// [TAG] EIP125798
+// [Category] Improvement
+// [Description] Added security check for Runtime injection of Product
+// Key through SMI
+//
+// 5 5/22/12 4:31p Vyacheslava
+// The OA3MSDMvariable variable has improper GUID.
+//
+// 4 4/27/12 2:41p Vyacheslava
+//
+// 3 4/20/12 2:43p Vyacheslava
+// There is additional pointer to MSDM ACPI will be added to XSDT for each
+// time AFU used to inject the product key. This issue is only actual if
+// there is empty product key in the in the firmware.
+//
+// 2 1/31/12 11:46a Vyacheslava
+// Changed SMM SW Context pointer according with changes in the
+// SmmChildDispatcher.
+//
+// 1 1/12/12 9:36a Vyacheslava
+// Separated to the module part.
+//
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SmmOemActivation.c
+//
+// Description: This part of code allows to update ACPI in the OS Runtime through
+// the SW SMI for OEM Activation without rebooting the system.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+
+#include <AmiDxeLib.h>
+#include <AmiSmm.h>
+#include "OemActivation.h"
+#include <AmiHobs.h>
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+ #include <Protocol/SmmSwDispatch.h>
+ #include <Protocol/SmmControl.h>
+#else
+ #include <Protocol/SmmSwDispatch2.h>
+ #include <Protocol/SmmControl2.h>
+ #include <Protocol/SmmCpu.h>
+#endif
+
+//---------------------------------------------------------------------------
+
+static EFI_PHYSICAL_ADDRESS gTsegAddress_ = 0;
+static UINT32 gTsegSize_ = 0;
+
+//---------------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//--------------------------------------------------------------------------
+//
+// Procedure: GetTsegVar
+//
+// Description: This function stores TSEG address and size.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//--------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID GetTsegVar(VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ CPUINFO_HOB *CpuInfoHob = (CPUINFO_HOB*)GetEfiConfigurationTable(pST,&HobListGuid);
+
+ if (CpuInfoHob == NULL)
+ return;
+
+ Status = FindNextHobByGuid(&CpuInfoHobGuid,&CpuInfoHob);
+ if (EFI_ERROR(Status))
+ return;
+
+ gTsegAddress_ = CpuInfoHob->TsegAddress;
+ gTsegSize_ = CpuInfoHob->TsegSize;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckAddressRange
+//
+// Description: Check address range to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Range - length of the area
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// EFI_SECURITY_VIOLATION - Access denied!
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CheckAddressRange( IN UINT8 *Address, IN UINTN Range )
+{
+ // if TSEG variables are not initialized then do not validate the access.
+ if ( gTsegAddress_ == 0 || gTsegSize_ == 0 )
+ return EFI_SUCCESS;
+
+ if ( ((EFI_PHYSICAL_ADDRESS)Address >= gTsegAddress_) &&
+ ((EFI_PHYSICAL_ADDRESS)Address <= (gTsegAddress_ + gTsegSize_)) )
+ return EFI_SECURITY_VIOLATION;
+
+ if ( (((EFI_PHYSICAL_ADDRESS)Address + Range) >= gTsegAddress_) &&
+ (((EFI_PHYSICAL_ADDRESS)Address + Range) <= (gTsegAddress_ + gTsegSize_)) )
+ return EFI_SECURITY_VIOLATION;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ChsumTbl
+//
+// Description: This function calculates a checksum of table starting at
+// TblStart of length BytesCount and returns the checksum value.
+//
+// Input:
+// *TblStart - Starting address of the memory area to checksum.
+// BytesCount - Length in bytes of the memory area to checksum.
+//
+// Output:
+// Checksum value starting from TblStart and ending at TblStart + BytesCount.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 ChsumTbl( IN UINT8* TblStart, IN UINT32 BytesCount )
+{
+ UINT8 Result = *TblStart;
+ UINTN i;
+
+ for ( i = 1; i < BytesCount; i++ )
+ Result += TblStart[i];
+ return 0 - Result;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Oa3UpdateAcpiTable
+//
+// Description: This function will update ACPI table for OA3.
+//
+// Input: ProductKey - pointer to the Product Key
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS Oa3UpdateAcpiTable( IN UINT8 *ProductKey )
+{
+ EFI_STATUS Status;
+ EFI_OA3_MSDM_STRUCTURE MsdmVariable = {0};
+ EFI_GUID AmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+ UINTN Size = sizeof(EFI_OA3_MSDM_STRUCTURE);
+ EFI_ACPI_MSDM_TABLE *MsdmTable;
+ ACPI_HDR *AcpiHdr;
+ UINT8 *Ptr;
+ EFI_PHYSICAL_ADDRESS *AcpiPtr;
+
+ if (ProductKey == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ Status = CheckAddressRange(ProductKey, sizeof(MsdmTable->Data));
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = pRS->GetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &AmiGlobalVariableGuid,
+ NULL,
+ &Size,
+ &MsdmVariable
+ );
+ TRACE((TRACE_ALWAYS,"Oa3UpdateAcpiTable: XsdtAddr=%X, MsdmAddr=%X\n",MsdmVariable.XsdtAddress,MsdmVariable.MsdmAddress));
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ if ( MsdmVariable.XsdtAddress == 0 || MsdmVariable.MsdmAddress == 0 )
+ return EFI_INVALID_PARAMETER;
+
+ // Validate MSDM table signature
+ MsdmTable = (EFI_ACPI_MSDM_TABLE*)(UINTN)MsdmVariable.MsdmAddress;
+ if (MsdmTable->Header.Signature != MSDM_SIG)
+ return EFI_INVALID_PARAMETER;
+
+ // Validate XSDT table signature
+ AcpiHdr = (ACPI_HDR*)(UINTN)MsdmVariable.XsdtAddress;
+ if (AcpiHdr->Signature != XSDT_SIG)
+ return EFI_INVALID_PARAMETER;
+
+ // Copy a new Product Key to MSDM Data array
+ MemCpy(
+ (UINT8*)&MsdmTable->Version,
+#if OEM_ACTIVATION_TABLE_LOCATION == 0
+ ProductKey,
+#else
+ (UINT8*)OEM_ACTIVATION_TABLE_ADDRESS, // Copy Key from the NCB
+#endif
+ sizeof(EFI_ACPI_MSDM_TABLE) - sizeof(ACPI_HDR) );
+
+ // Updates MSDM table checksum
+ MsdmTable->Header.Checksum = 0;
+ MsdmTable->Header.Checksum = ChsumTbl((UINT8*)MsdmTable, sizeof(EFI_ACPI_MSDM_TABLE));
+
+ // Check if pointer to MSDM ACPI table has been set already
+ Ptr = (UINT8*)AcpiHdr + AcpiHdr->Length - sizeof(EFI_PHYSICAL_ADDRESS);
+ AcpiPtr = (EFI_PHYSICAL_ADDRESS*)Ptr;
+ if ( *AcpiPtr != (EFI_PHYSICAL_ADDRESS)MsdmTable ) {
+
+ // Validate ACPI header's length. Check a range to avoid SMM
+ Ptr = (UINT8*)AcpiHdr + AcpiHdr->Length;
+ Status = CheckAddressRange(Ptr, sizeof(EFI_PHYSICAL_ADDRESS));
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Check destination if it's cleared by zero
+ AcpiPtr = (EFI_PHYSICAL_ADDRESS*)Ptr;
+ if (*AcpiPtr != 0)
+ return EFI_SECURITY_VIOLATION;
+
+ // Add address of MSDM table as the last pointer in XSDT
+ *AcpiPtr = (EFI_PHYSICAL_ADDRESS)MsdmTable;
+
+ // Updates Length filed of the XSDT table (increments by 8)
+ AcpiHdr->Length += sizeof(EFI_PHYSICAL_ADDRESS);
+
+ // Updates XSDT checksum
+ AcpiHdr->Checksum = 0;
+ AcpiHdr->Checksum = ChsumTbl((UINT8*)AcpiHdr, AcpiHdr->Length);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SwSmiOa3Function
+//
+// Description:
+// Calling the SMI Interface
+// The caller will write AL (the value 0xee) to the SMI Command Port as
+// defined in the ACPI FADT.
+// The SMI handler will update the callers' buffer(s) and return.
+//
+// Input:
+// DispatchHandle
+// DispatchContext
+//
+// Output: VOID
+//
+// Notes:
+// The function will clear the carry bit if it is successful (CF = 0).
+// If the function is unsuccessful, it will set the carry bit and set the
+// error code in the AH register as indicated by the error table below.
+// The function returns the following data in the provided parameter block.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+VOID SwSmiOa3Function(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+ EFI_GUID SwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+ UINTN CpuIndex = pSmst->CurrentlyExecutingCpu - 1;
+ UINTN Index;
+
+ // determine which CPU triggered SMI
+ for (Index = 0; Index < pSmst->NumberOfTableEntries; Index++)
+ if ( !guidcmp(&pSmst->SmmConfigurationTable[Index].VendorGuid, &SwSmiCpuTriggerGuid) ) {
+ CpuIndex = ((SW_SMI_CPU_TRIGGER*)pSmst->SmmConfigurationTable[Index].VendorTable)->Cpu;
+ break;
+ }
+
+ // Update the ACPI table
+ Oa3UpdateAcpiTable((UINT8*)(EFI_PHYSICAL_ADDRESS)pSmst->CpuSaveState[CpuIndex].Ia32SaveState.EBX);
+}
+
+#else
+
+EFI_STATUS SwSmiOa3Function(
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL )
+{
+ EFI_STATUS Status;
+ EFI_SMM_SW_CONTEXT *SmmSwContext = ((EFI_SMM_SW_CONTEXT*)CommBuffer);
+ EFI_GUID EfiSmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+ EFI_SMM_CPU_PROTOCOL *SmmCpuProtocol = NULL;
+ EFI_PHYSICAL_ADDRESS Register = 0;
+
+ Status = pSmst->SmmLocateProtocol(
+ &EfiSmmCpuProtocolGuid,
+ NULL,
+ &SmmCpuProtocol
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ // Read the RBX register
+ Status = SmmCpuProtocol->ReadSaveState(
+ SmmCpuProtocol,
+ sizeof(UINT32),
+ EFI_SMM_SAVE_STATE_REGISTER_RBX,
+ SmmSwContext->SwSmiCpuIndex,
+ &Register
+ );
+ if (!EFI_ERROR(Status))
+ Oa3UpdateAcpiTable((UINT8*)Register); // Update the ACPI table
+
+ return Status;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InSmmFunction
+//
+// Description: Registration of the SMI function
+//
+// Input:
+// ImageHandle - Image handle
+// SystemTable - Pointer to the system table
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = 0;
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+ EFI_GUID EfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch = NULL;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ Status = pBS->LocateProtocol(
+#else
+ EFI_GUID EfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID;
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *SwDispatch = NULL;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+ Status = pSmst->SmmLocateProtocol(
+#endif
+ &EfiSmmSwDispatchProtocolGuid,
+ NULL,
+ &SwDispatch
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ SwContext.SwSmiInputValue = SW_SMI_OA3_FUNCTION_NUMBER;
+ Status = SwDispatch->Register(
+ SwDispatch,
+ SwSmiOa3Function,
+ &SwContext,
+ &Handle
+ );
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmOemActivation_EntryPoint
+//
+// Description: This function is the entry point of the module.
+//
+// Input:
+// ImageHandle - Image handle
+// *SystemTable - Pointer to the system table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI SmmOemActivation_EntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_OA3_MSDM_STRUCTURE MsdmVariable;
+ EFI_GUID AmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+ UINTN Size = sizeof(EFI_OA3_MSDM_STRUCTURE);
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // Get TSEG address and TSEG size
+ GetTsegVar();
+
+ // Check if OA3 MSDM variable does exist
+ Status = pRS->GetVariable(
+ EFI_OA3_MSDM_VARIABLE,
+ &AmiGlobalVariableGuid,
+ NULL,
+ &Size,
+ &MsdmVariable
+ );
+ if (!EFI_ERROR(Status)) {
+
+ // then install the SMI handler
+ Status = InitSmmHandler(
+ ImageHandle,
+ SystemTable,
+ InSmmFunction,
+ NULL
+ );
+ TRACE((TRACE_ALWAYS,"OEM Activation: InitSmmHandler Status=%r\n",Status));
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/OemActivation/SmmOemActivation.cif b/Core/EM/OemActivation/SmmOemActivation.cif
new file mode 100644
index 0000000..d803008
--- /dev/null
+++ b/Core/EM/OemActivation/SmmOemActivation.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmmOemActivation"
+ category = ModulePart
+ LocalRoot = "Core\EM\OemActivation\"
+ RefName = "SmmOemActivation"
+[files]
+"SmmOemActivation.mak"
+"SmmOemActivation.sdl"
+"SmmOemActivation.c"
+"SmmOemActivation.dxs"
+<endComponent>
diff --git a/Core/EM/OemActivation/SmmOemActivation.dxs b/Core/EM/OemActivation/SmmOemActivation.dxs
new file mode 100644
index 0000000..01c5836
--- /dev/null
+++ b/Core/EM/OemActivation/SmmOemActivation.dxs
@@ -0,0 +1,83 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//*****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OemActivation/SmmOemActivation.dxs 3 1/12/12 9:35a Vyacheslava $
+//
+// $Revision: 3 $
+//
+// $Date: 1/12/12 9:35a $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OemActivation/SmmOemActivation.dxs $
+//
+// 3 1/12/12 9:35a Vyacheslava
+//
+//
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SmmOemActivation.dxs
+//
+// Description: This file is the dependency file for OemActivation module.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+//---------------------------------------------------------------------------
+// Header files for GUID definitions
+//---------------------------------------------------------------------------
+
+#if PI_SPECIFICATION_VERSION<0x0001000A
+//---------------------------------------------------------------------------
+
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//---------------------------------------------------------------------------
+#else
+//---------------------------------------------------------------------------
+
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmSwDispatch2.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+DEPENDENCY_END
+
+//---------------------------------------------------------------------------
+#endif
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/OemActivation/SmmOemActivation.mak b/Core/EM/OemActivation/SmmOemActivation.mak
new file mode 100644
index 0000000..50b3663
--- /dev/null
+++ b/Core/EM/OemActivation/SmmOemActivation.mak
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/OemActivation/SmmOemActivation.mak 1 1/12/12 9:36a Vyacheslava $
+#
+# $Revision: 1 $
+#
+# $Date: 1/12/12 9:36a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OemActivation/SmmOemActivation.mak $
+#
+# 1 1/12/12 9:36a Vyacheslava
+# Separated to the module part.
+#
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: SmmOemActivation.mak
+#
+# Description: Make file for SmmOemActivation module.
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+
+all : SmmOemActivation
+
+SmmOemActivation : $(BUILD_DIR)\SmmOemActivation.mak SmmOemActivationBin
+
+$(BUILD_DIR)\SmmOemActivation.mak : $(OemActivation_DIR)\$(@B).cif $(OemActivation_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OemActivation_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SmmOemActivationBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmmOemActivation.mak all\
+ GUID=8434DA1F-5CEB-402e-A93C-038CBE0F3F0E\
+ ENTRY_POINT=SmmOemActivation_EntryPoint\
+!IF $(PI_SPECIFICATION_VERSION)<0x00001000A
+ TYPE=BS_DRIVER\
+!ELSE
+ TYPE=SMM_DRIVER\
+!ENDIF
+ DEPEX1=$(OemActivation_DIR)\SmmOemActivation.dxs\
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX\
+ "EXT_HEADERS=$(BUILD_DIR)\Token.h"\
+ COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/OemActivation/SmmOemActivation.sdl b/Core/EM/OemActivation/SmmOemActivation.sdl
new file mode 100644
index 0000000..3234943
--- /dev/null
+++ b/Core/EM/OemActivation/SmmOemActivation.sdl
@@ -0,0 +1,32 @@
+TOKEN
+ Name = "SmmOemActivation_SUPPORT"
+ Value = "0"
+ Help = "Switch to enable Update ACPI in the OS Runtime through the SW SMI for OEM Activation without rebooting the system."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SW_SMI_OA3_FUNCTION_NUMBER"
+ Value = "0xDF"
+ TokenType = Integer
+ TargetH = Yes
+ Token = "SmmOemActivation_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "OemActivation_DIR"
+End
+
+MODULE
+ Help = "Includes SmmOemActivation.mak to Project"
+ File = "SmmOemActivation.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmmOemActivation.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/OpalSecurity/AHCIOpalSec.c b/Core/EM/OpalSecurity/AHCIOpalSec.c
new file mode 100644
index 0000000..998181d
--- /dev/null
+++ b/Core/EM/OpalSecurity/AHCIOpalSec.c
@@ -0,0 +1,312 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/AHCIOpalSec.c 5 12/21/11 8:32p Rajkumarkc $
+//
+// $Revision: 5 $
+//
+// $Date: 12/21/11 8:32p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/AHCIOpalSec.c $
+//
+// 5 12/21/11 8:32p Rajkumarkc
+// [TAG] EIP77142
+// [Category] BUG FIX & IMPROVEMENT
+// [Description] BUG FIX - Changed Little Endian format to Big Endian
+// format while sending commands.
+// IMPROVEMENT - Added support to Lock the Opal hdd
+// if it's unlocked on Bios POST.
+// [Files] IdeOpalSec.c, AhciOpalSec.c, OpalSecurity.c,
+// OpalSecurity.h, OpalSecurity.sdl
+//
+// 4 8/22/11 4:09a Anandakrishnanl
+// [TAG] EIP64040
+// [Category] Improvement
+// [Description] Opal Security - Changes requested for CodeReview by
+// customer
+// [Files] IdeOpalSec.c
+// AhciOpalSec.c
+//
+// 3 8/22/11 3:04a Anandakrishnanl
+// [TAG] EIP62912
+// [Category] Improvement
+// [Description] Opal Security Definitions Should be Moved to PIDEBUS.h
+// from StorageSecurityProtocol.h
+// StorageSecurityProtocol.h included in OPAL security driver module will
+// give build error when disabled without sdl token #if
+// OpalSecurity_SUPPORT properly placed in Ahcibus and IdeBus drivers. But
+// Bus driver should not depend on any tokens. For this reason need to
+// move OPAL_SEC_INIT_PROTOCOL_GUID in Pidebus.h
+// [Files] IdeBus.c
+// Pidebus.h
+// OpalSecurity.cif
+// OpalSecurity.h
+// IdeOpalSec.c
+// AhciOpalSec.c
+//
+// 2 5/19/11 5:58a Anandakrishnanl
+// [TAG] EIP53565
+// [Category] New Feature
+// [Description] UEFI2.3+ Specifications defines Storage Security
+// protocol which needs to be implemented
+// [Files] AhciBus.c,IdeBus.c,AHCIOpalSec.c,IDEOpalSec.c,OpalSecurity.c
+// ,OpalSecurity.chm,OpalSecurity.cif,OpalSecurity.h,OpalSecurity.mak,Opal
+// Security.sdl,PIDEBus.h,StorageSecurityProtocol.CIF,StorageSecurityProto
+// col.h
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AHCIOpalSec.c
+//
+// Description: Opal Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "OpalSecurity.h"
+
+#define ZeroMemory(Buffer,Size) pBS->SetMem(Buffer,Size,0)
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AhciSendData
+//
+// Description: Send a security protocol command to a device.
+//
+// Input:
+// This - Indicates a pointer to the calling context. Type
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL is defined in the
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL description.
+// MediaId - ID of the medium to send data to.
+// Timeout - The timeout, in 100ns units, to use for the execution of the
+// security protocol command. A Timeout value of 0 means that this function
+// will wait indefinitely for the security protocol command to execute.
+// If Timeout is greater than zero, then this function will return
+// EFI_TIMEOUT if the time required to execute the receive data command
+// is greater than Timeout.
+// SecurityProtocolId - Security protocol ID of the security protocol
+// command to be sent.
+// SecurityProtocolSpecificData - Security protocol specific portion of
+// the security protocol command.
+// PayloadBufferSize - Size in bytes of the payload data buffer.
+// PayloadBuffer - A pointer to a buffer containing the security protocol
+// command specific payload data for the security protocol command.
+//
+// Output:
+// EFI_SUCCESS - The security protocol command completed successfully.
+// EFI_UNSUPPORTED - The given MediaId does not support security protocol
+// commands.
+// EFI_DEVICE_ERROR - The security protocol command completed with an error.
+// EFI_INVALID_PARAMETER - The PayloadBuffer or PayloadTransferSize is
+// NULL and PayloadBufferSize is non-zero.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+AhciSendData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ IN VOID *PayloadBuffer
+)
+{
+ EFI_STATUS Status;
+ UINT8 SectorCountL = 0;
+ UINT8 SectorCountH = 0;
+ COMMAND_STRUCTURE CommandStructure;
+ STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurityProtocol = (STORAGE_SECURITY_COMMAND_PROTOCOL*)This;
+ SATA_DEVICE_INTERFACE *SataDevInterface = (SATA_DEVICE_INTERFACE *)StorageSecurityProtocol->BusInterface;
+ SATA_BLOCK_IO *SataBlkIo = SataDevInterface->SataBlkIo;
+
+ // Check for BlkIo presence
+ if(SataBlkIo == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Check for Media change
+ if(SataBlkIo->BlkIo.Media->MediaId != MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ SectorCountL = (UINT8)(PayloadBufferSize / SataBlkIo->BlkIo.Media->BlockSize);
+ SectorCountH = (UINT8)((PayloadBufferSize / SataBlkIo->BlkIo.Media->BlockSize)/0x100);
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ if(PayloadBufferSize != 0){
+ Status = SataDevInterface->AhciBusInterface->SataPioDataOut(
+ SataDevInterface,
+ PayloadBuffer,
+ (UINT32)PayloadBufferSize,
+ SecurityProtocolId,
+ SectorCountH,//TransferLength
+ 0,
+ (UINT8)(SecurityProtocolSpecificData >> 8) , //Com ID
+ 0,
+ (UINT8)SecurityProtocolSpecificData,
+ 0,
+ TRUSTED_SEND,
+ TRUE);
+
+ }else{
+ // For PayloadBufferSize zero, Trusted Non Data command should be used
+ // BIT 24 indicates Trusted Receive/Send
+ CommandStructure.LBAMid = (UINT8)(SecurityProtocolSpecificData >> 8);
+ CommandStructure.LBAHigh = (UINT8)SecurityProtocolSpecificData;
+ CommandStructure.Command = TRUSTED_NON_DATA;
+ CommandStructure.Features = SecurityProtocolId;
+ CommandStructure.Buffer = PayloadBuffer;
+ CommandStructure.ByteCount = (UINT32)PayloadBufferSize;
+ Status = SataDevInterface->AhciBusInterface->ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ReceiveData
+//
+// Description: Send a security protocol command to a device that receives
+// data and/or the result of one or more commands sent by
+// SendData.
+//
+// Input:
+// This -Indicates a pointer to the calling context. Type
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL is defined in the
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL description.
+// MediaId - ID of the medium to receive data from.
+// Timeout - The timeout, in 100ns units, to use for the execution of the
+// security protocol command. A Timeout value of 0 means that this
+// function will wait indefinitely for the security protocol command
+// to execute. If Timeout is greater than zero, then this function
+// will return.
+// SecurityProtocolId - Security protocol ID of the security protocol
+// command to be sent.
+// SecurityProtocolSpecificData - Security protocol specific portion of
+// the security protocol command.
+// PayloadBufferSize - Size in bytes of the payload data buffer.
+// PayloadBuffer - A pointer to a destination buffer to store the
+// security protocol command specific payload data for the
+// security protocol command. The caller is responsible
+// for either having implicit or explicit ownership of
+// the buffer.
+// PayloadTransferSize - A pointer to a buffer to store the size in bytes
+// of the data written to the payload data buffer.
+//
+// Output:
+// EFI_SUCCESS - The security protocol command completed successfully.
+// EFI_UNSUPPORTED - The given MediaId does not support security
+// protocol commands.
+// EFI_DEVICE_ERROR - The security protocol command completed with an error.
+// EFI_INVALID_PARAMETER - The PayloadBuffer or PayloadTransferSize is
+// NULL and PayloadBufferSize is non-zero.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+AhciReceiveData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ OUT VOID *PayloadBuffer,
+ OUT UINTN *PayloadTransferSize
+)
+{
+ EFI_STATUS Status;
+ UINT8 SectorCountL = 0;
+ UINT8 SectorCountH = 0;
+ COMMAND_STRUCTURE CommandStructure;
+ STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurityProtocol = (STORAGE_SECURITY_COMMAND_PROTOCOL*)This;
+ SATA_DEVICE_INTERFACE *SataDevInterface = (SATA_DEVICE_INTERFACE *)StorageSecurityProtocol->BusInterface;
+ SATA_BLOCK_IO *SataBlkIo = SataDevInterface->SataBlkIo;
+
+ // Check for BlkIo presence
+ if(SataBlkIo==NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Check for Media change
+ if(SataBlkIo->BlkIo.Media->MediaId != MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ SectorCountL = (UINT8)(PayloadBufferSize / SataBlkIo->BlkIo.Media->BlockSize);
+ SectorCountH = (UINT8)((PayloadBufferSize / SataBlkIo->BlkIo.Media->BlockSize)/0x100);
+
+ ZeroMemory (&CommandStructure, sizeof(COMMAND_STRUCTURE));
+
+ if(PayloadBufferSize != 0){
+ // For PayloadBufferSize non zero, Trusted Receive command should be used
+
+ if(PayloadTransferSize == NULL || PayloadBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CommandStructure.SectorCount = (UINT16)SectorCountL;
+ CommandStructure.LBALow = (UINT8)SectorCountH;
+ CommandStructure.LBAMid = (UINT8)(SecurityProtocolSpecificData >> 8);
+ CommandStructure.LBAHigh = (UINT8)SecurityProtocolSpecificData;
+ CommandStructure.Command = TRUSTED_RECEIVE;
+ CommandStructure.Features = SecurityProtocolId;
+ CommandStructure.Buffer = PayloadBuffer;
+ CommandStructure.ByteCount = (UINT32)PayloadBufferSize ;
+ Status = SataDevInterface->AhciBusInterface->ExecutePioDataCommand (SataDevInterface, &CommandStructure, FALSE);
+ }else{
+ // For PayloadBufferSize zero, Trusted Non Data command should be used
+ // BIT 24 indicates Trusted Receive/Send
+ CommandStructure.LBAMid = (UINT8)(SecurityProtocolSpecificData >> 8);
+ CommandStructure.LBAHigh = (UINT8)SecurityProtocolSpecificData;
+ CommandStructure.LBALowExp = 0x01; // Trusted Receive
+ CommandStructure.Command = TRUSTED_NON_DATA;
+ CommandStructure.Features = SecurityProtocolId;
+ CommandStructure.Buffer = PayloadBuffer;
+ CommandStructure.ByteCount = (UINT32)PayloadBufferSize;
+ Status = SataDevInterface->AhciBusInterface->ExecuteNonDataCommand (SataDevInterface, CommandStructure);
+ }
+
+ if (!EFI_ERROR( Status) ) {
+ *PayloadTransferSize = CommandStructure.ByteCount;
+ } else {
+ *PayloadTransferSize = 0;
+ }
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OpalSecurity/IDEOpalSec.c b/Core/EM/OpalSecurity/IDEOpalSec.c
new file mode 100644
index 0000000..a478e63
--- /dev/null
+++ b/Core/EM/OpalSecurity/IDEOpalSec.c
@@ -0,0 +1,321 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/IDEOpalSec.c 4 12/21/11 8:33p Rajkumarkc $
+//
+// $Revision: 4 $
+//
+// $Date: 12/21/11 8:33p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/IDEOpalSec.c $
+//
+// 4 12/21/11 8:33p Rajkumarkc
+// [TAG] EIP77142
+// [Category] BUG FIX & IMPROVEMENT
+// [Description] BUG FIX - Changed Little Endian format to Big Endian
+// format while sending commands.
+// IMPROVEMENT - Added support to Lock the Opal hdd if it's
+// unlocked on Bios POST.
+// [Files] IdeOpalSec.c, AhciOpalSec.c, OpalSecurity.c,
+// OpalSecurity.h, OpalSecurity.sdl
+//
+// 3 8/22/11 4:03a Anandakrishnanl
+// [TAG] EIP64040
+// [Category] Improvement
+// [Description] Opal Security - Changes requested for CodeReview by
+// customer
+// [Files] IdeOpalSec.c
+// AhciOpalSec.c
+//
+// 2 8/22/11 3:03a Anandakrishnanl
+// [TAG] EIP62912
+// [Category] Improvement
+// [Description] Opal Security Definitions Should be Moved to PIDEBUS.h
+// from StorageSecurityProtocol.h
+// StorageSecurityProtocol.h included in OPAL security driver module will
+// give build error when disabled without sdl token #if
+// OpalSecurity_SUPPORT properly placed in Ahcibus and IdeBus drivers. But
+// Bus driver should not depend on any tokens. For this reason need to
+// move OPAL_SEC_INIT_PROTOCOL_GUID in Pidebus.h
+// [Files] IdeBus.c
+// Pidebus.h
+// OpalSecurity.cif
+// OpalSecurity.h
+// IdeOpalSec.c
+// AhciOpalSec.c
+//
+// 1 5/19/11 2:07a Anandakrishnanl
+// Opal Security Module Initial Check In
+//
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IDEOpalSec.c
+//
+// Description: IDE Opal Security Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "OpalSecurity.h"
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: IdeSendData
+//
+// Description: Send a security protocol command to a device.
+//
+// Input:
+// This - Indicates a pointer to the calling context. Type
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL is defined in the
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL description.
+// MediaId - ID of the medium to send data to.
+// Timeout - The timeout, in 100ns units, to use for the execution of the
+// security protocol command. A Timeout value of 0 means that this
+// function will wait indefinitely for the security protocol command
+// to execute. If Timeout is greater than zero, then this function
+// will return EFI_TIMEOUT if the time required to execute the
+// receive data command is greater than Timeout.
+// SecurityProtocolId - Security protocol ID of the security protocol
+// command to be sent.
+// SecurityProtocolSpecificData - Security protocol specific portion of
+// the security protocol command.
+// PayloadBufferSize - Size in bytes of the payload data buffer.
+// PayloadBuffer - A pointer to a buffer containing the security protocol
+// command specific payload data for the security protocol command.
+// Output:
+// EFI_SUCCESS - The security protocol command completed successfully.
+// EFI_UNSUPPORTED - The given MediaId does not support security
+// protocol commands.
+// EFI_DEVICE_ERROR - The security protocol command completed with an error.
+// EFI_INVALID_PARAMETER - The PayloadBuffer or PayloadTransferSize is
+// NULL and PayloadBufferSize is non-zero.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS IdeSendData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ IN VOID *PayloadBuffer )
+{
+ EFI_STATUS Status;
+ UINT8 SectorCountL = 0;
+ UINT8 SectorCountH = 0;
+ STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurityProtocol = (STORAGE_SECURITY_COMMAND_PROTOCOL*)This;
+ IDE_BUS_PROTOCOL *IdeBusInterface = (IDE_BUS_PROTOCOL*)StorageSecurityProtocol->BusInterface;
+ EFI_BLOCK_IO_PROTOCOL *Blockio = &(IdeBusInterface->IdeBlkIo->BlkIo);
+
+ // Check for BlkIo presence
+ if(Blockio == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Check for Media change
+ if(Blockio->Media->MediaId != MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ SectorCountL = (UINT8)(PayloadBufferSize / Blockio->Media->BlockSize);
+ SectorCountH = (UINT8)((PayloadBufferSize / Blockio->Media->BlockSize)/0x100);
+
+ if(PayloadBufferSize != 0){
+ // For PayloadBufferSize non zero, Trusted Send command should be used
+ if(PayloadBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ Status = IdeBusInterface->AtaPioDataOut(
+ IdeBusInterface,
+ PayloadBuffer,
+ (UINT32)PayloadBufferSize,
+ SecurityProtocolId,
+ SectorCountL, // Sector count - 512 bytes multiples
+ SectorCountH,//TransferLength
+ 0,
+ (UINT8)(SecurityProtocolSpecificData >> 8) , //Com ID
+ 0,
+ (UINT8)SecurityProtocolSpecificData,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ TRUSTED_SEND,
+ TRUE,
+ FALSE );
+ }else{
+ // For PayloadBufferSize zero, Trusted Non Data command should be used
+ // BIT 24 indicates Trusted Receive/Send
+ Status = IdeBusInterface->IdeNonDataCommand(IdeBusInterface,
+ SecurityProtocolId,
+ 0, // Reserved if command is Trusted Non-Data
+ 0, // Reserved if command is Trusted Non-Data
+ 0, // Reserved if command is Trusted Non-Data
+ 0, // Reserved if command is Trusted Non-Data
+ (UINT8)(SecurityProtocolSpecificData >> 8),//Com Id
+ 0,
+ (UINT8)SecurityProtocolSpecificData,
+ 0,
+ IdeBusInterface->IdeDevice.Device << 4,
+ TRUSTED_NON_DATA
+ );
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: IdeReceiveData
+//
+// Description: Send a security protocol command to a device that receives
+// data and/or the result of one or more commands sent by
+// SendData.
+//
+// Input:
+// This -Indicates a pointer to the calling context. Type
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL is defined in the
+// EFI_STORAGE_SECURITY_COMMAND_PROTOCOL description.
+// MediaId - ID of the medium to receive data from.
+// Timeout - The timeout, in 100ns units, to use for the execution of the
+// security protocol command. A Timeout value of 0 means that this
+// function will wait indefinitely for the security protocol command to
+// execute. If Timeout is greater than zero, then this function will
+// return.
+// SecurityProtocolId - Security protocol ID of the security protocol
+// command to be sent.
+// SecurityProtocolSpecificData - Security protocol specific portion of
+// the security protocol command.
+// PayloadBufferSize - Size in bytes of the payload data buffer.
+// PayloadBuffer - A pointer to a destination buffer to store the security
+// protocol command specific payload data for the security protocol
+// command. The caller is responsible for either having implicit or
+// explicit ownership of the buffer.
+// PayloadTransferSize - A pointer to a buffer to store the size in bytes
+// of the data written to the payload data buffer.
+//
+// Output:
+// EFI_SUCCESS - The security protocol command completed successfully.
+// EFI_UNSUPPORTED - The given MediaId does not support security
+// protocol commands.
+// EFI_DEVICE_ERROR - The security protocol command completed with an error.
+// EFI_INVALID_PARAMETER - The PayloadBuffer or PayloadTransferSize is
+// NULL and PayloadBufferSize is non-zero.
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS IdeReceiveData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ OUT VOID *PayloadBuffer,
+ OUT UINTN *PayloadTransferSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 Device = 0;
+ UINT8 SectorCountL = 0;
+ UINT8 SectorCountH = 0;
+ STORAGE_SECURITY_COMMAND_PROTOCOL *StorageSecurityProtocol = (STORAGE_SECURITY_COMMAND_PROTOCOL*)This;
+ IDE_BUS_PROTOCOL *IdeBusInterface = (IDE_BUS_PROTOCOL*)StorageSecurityProtocol->BusInterface;
+ EFI_BLOCK_IO_PROTOCOL *Blockio = &(IdeBusInterface->IdeBlkIo->BlkIo);
+
+ // Check for BlkIo presence
+ if(Blockio == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if(Blockio->Media->MediaId != MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ SectorCountL = (UINT8)(PayloadBufferSize / Blockio->Media->BlockSize);
+ SectorCountH = (UINT8)((PayloadBufferSize / Blockio->Media->BlockSize)/0x100);
+
+ if(PayloadBufferSize != 0){
+ // For PayloadBufferSize non zero, Trusted Receive command should be used
+
+ if(PayloadTransferSize == NULL || PayloadBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = IdeBusInterface->AtaPioDataIn(
+ IdeBusInterface,
+ PayloadBuffer,
+ (UINT32)PayloadBufferSize,
+ SecurityProtocolId,
+ SectorCountL, // Sector count - 512 bytes multiples
+ SectorCountH,//TransferLength
+ (UINT8)(SecurityProtocolSpecificData >> 8) , //Com ID
+ (UINT8)SecurityProtocolSpecificData,
+ IdeBusInterface->IdeDevice.Device << 4,
+ TRUSTED_RECEIVE,
+ FALSE );
+ }else{
+
+ // For PayloadBufferSize zero, Trusted Non Data command should be used
+ // BIT 24 indicates Trusted Receive/Send
+ UINT32 LBA = 0;
+
+ // IdeNonDataCommand supports only for 24 bits of LBA(Low, Mid and High). For 28 bit LBA
+ // we use device to fill remanining 4 bits (24:27).
+ // Needed since bit 24 indicates Trusted Receive/Send.
+ LBA = (SecurityProtocolSpecificData << 8) | (1 << 24);
+ Device = ((UINT8) ((UINT32) LBA >> 24 ) & 0x0f) | (IdeBusInterface->IdeDevice.Device << 4) | 0x40;
+
+ Status = IdeBusInterface->IdeNonDataCommand(
+ IdeBusInterface,
+ SecurityProtocolId,
+ 0, // Reserved if command is Trusted Non-Data
+ 0, // Reserved if command is Trusted Non-Data
+ 0, // Reserved if command is Trusted Non-Data
+ 0x01, // Trusted Receive
+ (UINT8)(SecurityProtocolSpecificData >> 8) , //Com ID - Discovery 0
+ 0,
+ (UINT8)SecurityProtocolSpecificData,
+ 0,
+ Device,
+ TRUSTED_NON_DATA );
+ }
+
+ if (!EFI_ERROR( Status) ) {
+ *PayloadTransferSize = PayloadBufferSize;
+ } else {
+ *PayloadTransferSize = 0;
+ }
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OpalSecurity/OpalSecurity.c b/Core/EM/OpalSecurity/OpalSecurity.c
new file mode 100644
index 0000000..f06d77a
--- /dev/null
+++ b/Core/EM/OpalSecurity/OpalSecurity.c
@@ -0,0 +1,553 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/OpalSecurity.c 3 12/21/11 8:36p Rajkumarkc $
+//
+// $Revision: 3 $
+//
+// $Date: 12/21/11 8:36p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/OpalSecurity.c $
+//
+// 3 12/21/11 8:36p Rajkumarkc
+// [TAG] EIP77142
+// [Category] BUG FIX & IMPROVEMENT
+// [Description] BUG FIX - Changed Little Endian format to Big Endian
+// format while sending commands.
+// IMPROVEMENT - Added support to Lock the Opal hdd if
+// it's unlocked on Bios POST.
+// [Files] IdeOpalSec.c, AhciOpalSec.c, OpalSecurity.c,
+// OpalSecurity.h, OpalSecurity.sdl
+//
+// 2 5/19/11 5:59a Anandakrishnanl
+// [TAG] EIP53565
+// [Category] New Feature
+// [Description] UEFI2.3+ Specifications defines Storage Security
+// protocol which needs to be implemented.
+// [Files] AhciBus.c,IdeBus.c,AHCIOpalSec.c,IDEOpalSec.c,OpalSecurity.c
+// ,OpalSecurity.chm,OpalSecurity.cif,OpalSecurity.h,OpalSecurity.mak,Opal
+// Security.sdl,PIDEBus.h,StorageSecurityProtocol.CIF,StorageSecurityProto
+// col.h
+//
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: OpalSecurity.c
+//
+// Description: Opal Security Support
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "OpalSecurity.h"
+
+static EFI_GUID gOpalSecInitProtocolGuid = OPAL_SEC_INIT_PROTOCOL_GUID;
+static EFI_GUID gStorageSecurityProtocolGuid = EFI_STORAGE_SECURITY_COMMAND_PROTOCOL_GUID;
+
+OPAL_SECURITY_INIT_PROTOCOL *gOpalSecInitProtocol;
+STORAGE_SECURITY_COMMAND_PROTOCOL *gStorageSecurityProtocol;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OpalSecEntryPoint
+//
+// Description: This function is the entry point for OpalSecurity
+// Driver.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output:
+// EFI_SUCCESS : OpalSecurity Interface successfully installed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+OpalSecEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(OPAL_SECURITY_INIT_PROTOCOL),
+ (VOID**)&gOpalSecInitProtocol );
+
+ if ( EFI_ERROR( Status )){
+ return Status;
+ }
+
+ gOpalSecInitProtocol->InstallOpalSecurityInterface = InstallOpalSecurityInterface;
+ gOpalSecInitProtocol->UnInstallOpalSecurityInterface = UnInstallOpalSecurityInterface;
+
+ Status = pBS->InstallProtocolInterface(
+ &Handle,
+ &gOpalSecInitProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gOpalSecInitProtocol
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InstallOpalSecurityInterface
+//
+// Description: Installs StorageSecurityProtocol if the drive supports
+// Trusted commands
+//
+// Input:
+// IN VOID *BusInterface
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : StorageSecurity supported.
+// Others : Not supported.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallOpalSecurityInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag
+)
+{
+ EFI_STATUS Status ;
+ IDENTIFY_DATA IdentifyData;
+ EFI_HANDLE IdeDeviceHandle = NULL;
+
+ if ( ModeFlag == FALSE ){
+ IdentifyData = ((IDE_BUS_PROTOCOL*)BusInterface)->IdeDevice.IdentifyData;
+ IdeDeviceHandle = ((IDE_BUS_PROTOCOL*)BusInterface)->IdeDeviceHandle;
+ }else{
+ IdentifyData = ((SATA_DEVICE_INTERFACE*)BusInterface)->IdentifyData;
+ IdeDeviceHandle = ((SATA_DEVICE_INTERFACE*)BusInterface)->IdeDeviceHandle;
+ }
+
+ if(!(IdentifyData.Trusted_Computing_Support & 0x01)){
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // StorageSecurity Protocol
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(EFI_STORAGE_SECURITY_COMMAND_PROTOCOL),
+ (VOID**)&gStorageSecurityProtocol );
+
+ if ( ModeFlag == FALSE ){
+ gStorageSecurityProtocol->ReceiveData = IdeReceiveData;
+ gStorageSecurityProtocol->SendData = IdeSendData;
+ }else{
+ gStorageSecurityProtocol->ReceiveData = AhciReceiveData;
+ gStorageSecurityProtocol->SendData = AhciSendData;
+ }
+ gStorageSecurityProtocol->BusInterface = BusInterface;
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &IdeDeviceHandle,
+ &gStorageSecurityProtocolGuid, gStorageSecurityProtocol,
+ NULL );
+
+// TPer Lock On Reset Feature Support
+#if TPer_LOCK_ON_RESET
+
+ // Below error status check is to determine if gStorageSecurityProtocol has been
+ // installed successfully or not. In case if code inserted in between, this check
+ // has to be handled properly.
+
+ if (!EFI_ERROR(Status)) {
+ GetAndStoreSecurityProtocolInformation(
+ (EFI_STORAGE_SECURITY_COMMAND_PROTOCOL*)gStorageSecurityProtocol,
+ BusInterface
+ );
+ IssueLockOnResetCommand(
+ (EFI_STORAGE_SECURITY_COMMAND_PROTOCOL*)gStorageSecurityProtocol,
+ BusInterface,
+ ModeFlag
+ );
+ }
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UnInstallOpalSecurityInterface
+//
+// Description: Uninstalls the Opal Security Init Protocol.
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output:
+// EFI_SUCCESS : Security Mode supported.
+// EFI_DEVICE_ERROR/EFI_UNSUPPORTED : Not supported.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UnInstallOpalSecurityInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_HANDLE IdeDeviceHandle;
+
+ if ( ModeFlag == FALSE ){
+ IdeDeviceHandle = ((IDE_BUS_PROTOCOL*)BusInterface)->IdeDeviceHandle;
+ }else{
+ IdeDeviceHandle = ((SATA_DEVICE_INTERFACE*)BusInterface)->IdeDeviceHandle;
+ }
+
+ //
+ // Install Devicepath and BLOCK_IO on a new handle
+ //
+ Status = pBS->UninstallMultipleProtocolInterfaces(
+ IdeDeviceHandle,
+ &gOpalSecInitProtocolGuid,
+ gOpalSecInitProtocol,
+ NULL );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetAndStoreSecurityProtocolInformation
+//
+// Description: Get and store Security Protocol Information
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output: NONE
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetAndStoreSecurityProtocolInformation(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN VOID *BusInterface
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ SP0_TRUSTED_RECEIVE_PARAMETER_DATA *QueryBuffer = NULL;
+ UINT16 ListLength = 0;
+ UINT8 SpByte = 0;
+
+ UINTN QueryBufferSize = sizeof(SP0_TRUSTED_RECEIVE_PARAMETER_DATA);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(UINT8)*QueryBufferSize, (VOID**)&QueryBuffer);
+ if(EFI_ERROR(Status))return EFI_OUT_OF_RESOURCES;
+
+ Status = GetSecurityProtocolInformation(This, QueryBuffer, &QueryBufferSize);
+ // GetSecurityProtocolInformation returns error Status. Unsupported Security Protocol.
+ if(EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ // The List Length field indicates the total length, in bytes, of the supported security protocol list.
+ ListLength = QueryBuffer->ListLengthHigh << 8 | QueryBuffer->ListLengthLow;
+
+ ((STORAGE_SECURITY_COMMAND_PROTOCOL*)This)->SupportedProtocolList = QueryBuffer;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetSecurityProtocolInformation
+//
+// Description: Get Security Protocol Information
+//
+// Input: IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+// OUT VOID *QueryBuffer,
+// OUT UINTN *QueryBufferSize
+//
+//
+// Output: NONE
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetSecurityProtocolInformation(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN OUT VOID *QueryBuffer,
+ IN OUT UINTN *QueryBufferSize
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = This->ReceiveData( This,
+ 0,
+ 0,
+ SECURITY_PROTOCOL_INFORMATION, // Security Protocol ID
+ 0x00, // SP specific id
+ 0x200, // TranferLength
+ QueryBuffer,
+ QueryBufferSize
+ );
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssueLockOnResetCommand
+//
+// Description: Issues LockOnReset Command.
+//
+// Input:
+// IN VOID *BusInterface,
+// IN BOOLEAN ModeFlag
+//
+// Output: NONE
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+IssueLockOnResetCommand(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ IDENTIFY_DATA IdentifyData;
+ EFI_HANDLE IdeDeviceHandle = NULL;
+
+ UINT16 ListLength = 0;
+ UINT8 SpByte = 0;
+ SP0_TRUSTED_RECEIVE_PARAMETER_DATA *SupportedProtocolList = ((STORAGE_SECURITY_COMMAND_PROTOCOL*)This)->SupportedProtocolList;
+
+ if ( ModeFlag == FALSE ){
+ IdentifyData = ((IDE_BUS_PROTOCOL*)BusInterface)->IdeDevice.IdentifyData;
+ IdeDeviceHandle = ((IDE_BUS_PROTOCOL*)BusInterface)->IdeDeviceHandle;
+ }else{
+ IdentifyData = ((SATA_DEVICE_INTERFACE*)BusInterface)->IdentifyData;
+ IdeDeviceHandle = ((SATA_DEVICE_INTERFACE*)BusInterface)->IdeDeviceHandle;
+ }
+
+ // The List Length field indicates the total length, in bytes, of the supported security protocol list.
+ ListLength = SupportedProtocolList->ListLengthHigh << 8 | SupportedProtocolList->ListLengthLow;
+ if(ListLength == 0) return EFI_UNSUPPORTED;
+
+ // Check the Secutiy supported Protocol List is 0xEE for IEEE 1667 or 0x02 for Native TCG
+ for(SpByte = 0; SpByte < ListLength; SpByte++){
+
+ if(SupportedProtocolList->SupportedSPList[SpByte] == SECURITY_PROTOCOL_2) {
+ // Found Supported Security Protocol list NativeTcg.Issue Tcg TPer Reset
+ Status = NativeTcgTPerReset(This);
+ break;
+ }
+
+ if(SupportedProtocolList->SupportedSPList[SpByte] == SECURITY_PROTOCOL_IEEE1667) {
+ // Found Supported Security Protocol list IEEE 1667. Issue Silo TPer Reset
+ // Check if IEEE 1667 bit (bit 7) set in the AdditionalSupported field to
+ // determine whether the device supports Trusted Send/Receive.
+
+ if(!(IdentifyData.Reserved_69_74[0] & 0x80)){
+ Status = IEEE67TPerReset(This);
+ break;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: NativeTcgTPerReset
+//
+// Description: Native Tcg TPer Reset
+//
+// Input: IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+//
+// Output: NONE
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NativeTcgTPerReset(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ VOID *TcgResetDataBuffer = NULL;
+ UINT32 BufferSize = 0x200;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, BufferSize, (VOID**)&TcgResetDataBuffer);
+ if(EFI_ERROR(Status))return EFI_OUT_OF_RESOURCES;
+
+ pBS->SetMem(TcgResetDataBuffer, BufferSize, 0);
+
+ // Determined the device supports Native TCG Security Support Protocol 2. Issue TPer Reset.
+ Status = This->SendData( This,
+ 0,
+ 0,
+ SECURITY_PROTOCOL_2, // Security Protocol 2 ID
+ 0x0400, // SP specific id
+ 0x200, // TranferLength - Non zero Value
+ TcgResetDataBuffer
+ );
+ pBS->FreePool(TcgResetDataBuffer);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IEEE67TPerReset
+//
+// Description: IEEE67 TPer Reset
+//
+// Input: IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+//
+//
+// Output: NONE
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+IEEE67TPerReset(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 SiloTypeIdentifier = 0;
+ UINT16 IeeeSilo = 0;
+ TCG_SILO_TYPE_IDENTIFIER *ProbeHostDataBuffer = NULL;
+ TCG_SILO_TYPE_IDENTIFIER *SupportedSilosArrayBuffer = NULL;
+
+ UINTN SupportedSilosArrayBufferSize = sizeof(TCG_SILO_TYPE_IDENTIFIER);
+ UINTN ProbeHostDataBufferSize = sizeof(TCG_SILO_TYPE_IDENTIFIER);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(UINT8)*ProbeHostDataBufferSize, (VOID**)&ProbeHostDataBuffer);
+ if(EFI_ERROR(Status))return EFI_OUT_OF_RESOURCES;
+
+ // Check if TPer has TCG silo by sending probe command to PROBE SILO
+ Status = This->SendData( This,
+ 0,
+ 0,
+ SECURITY_PROTOCOL_IEEE1667, // Security Protocol ID
+ 0x0100, // SP specific id
+ 0x200, // TranferLength
+ ProbeHostDataBuffer
+ );
+ if(!EFI_ERROR(Status)) {
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(UINT8)*SupportedSilosArrayBufferSize, (VOID**)&SupportedSilosArrayBuffer);
+ if(EFI_ERROR(Status))return EFI_OUT_OF_RESOURCES;
+
+ // Followed by Trusted Receive Probe command to PROBE SILO
+ Status = This->ReceiveData( This,
+ 0,
+ 0,
+ SECURITY_PROTOCOL_IEEE1667, // Security Protocol ID
+ 0x0100, // SP specific id
+ 0x200, // TranferLength
+ SupportedSilosArrayBuffer,
+ &SupportedSilosArrayBufferSize
+ );
+
+ if(!EFI_ERROR(Status)) {
+ // Scan for Silo Identifier(0x0104) available to send TPer Reset silo command payload to Tcg Silo
+ SiloTypeIdentifier = SupportedSilosArrayBuffer->SiloTypeIdentifierHigh << 8 | SupportedSilosArrayBuffer->SiloTypeIdentifierLow;
+ // Search for IEEE std allocated identifiers only to find 0x0104 present: IEEE - 0100h to 01FFh
+ for(IeeeSilo = 0x100; IeeeSilo < 0x200; IeeeSilo++) {
+ if(IeeeSilo == SiloTypeIdentifier) {
+ Status = IssueTPerResetTcgSilo(This);
+ return Status;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssueTPerResetTcgSilo
+//
+// Description: Issue TPer Reset
+//
+// Input: IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+//
+//
+// Output: NONE
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+IssueTPerResetTcgSilo(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_SILO_TYPE_IDENTIFIER *IeeeResetDataBuffer = NULL;
+
+ UINTN IeeeResetDataBufferSize = sizeof(TCG_SILO_TYPE_IDENTIFIER);
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(UINT8)*IeeeResetDataBufferSize, (VOID**)&IeeeResetDataBuffer);
+ if(EFI_ERROR(Status))return EFI_OUT_OF_RESOURCES;
+
+ // Determined the device supports TCG silo. Issue TPer Reset silo command payload to the TCG silo
+ Status = This->SendData( This,
+ 0,
+ 0,
+ SECURITY_PROTOCOL_IEEE1667, // Security Protocol ID
+ 0x0500, // SP specific id
+ 0x200, // TranferLength
+ IeeeResetDataBuffer
+ );
+ pBS->FreePool(IeeeResetDataBuffer);
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/OpalSecurity/OpalSecurity.chm b/Core/EM/OpalSecurity/OpalSecurity.chm
new file mode 100644
index 0000000..f94ae98
--- /dev/null
+++ b/Core/EM/OpalSecurity/OpalSecurity.chm
Binary files differ
diff --git a/Core/EM/OpalSecurity/OpalSecurity.cif b/Core/EM/OpalSecurity/OpalSecurity.cif
new file mode 100644
index 0000000..350a299
--- /dev/null
+++ b/Core/EM/OpalSecurity/OpalSecurity.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "OpalSecurity"
+ category = eModule
+ LocalRoot = "core\em\OpalSecurity\"
+ RefName = "OpalSecurity"
+[files]
+"OpalSecurity.sdl"
+"OpalSecurity.mak"
+"OpalSecurity.c"
+"OpalSecurity.h"
+"IDEOpalSec.c"
+"AHCIOpalSec.c"
+"OpalSecurity.chm"
+<endComponent>
diff --git a/Core/EM/OpalSecurity/OpalSecurity.h b/Core/EM/OpalSecurity/OpalSecurity.h
new file mode 100644
index 0000000..3c78710
--- /dev/null
+++ b/Core/EM/OpalSecurity/OpalSecurity.h
@@ -0,0 +1,227 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/OpalSecurity.h 3 12/21/11 8:37p Rajkumarkc $
+//
+// $Revision: 3 $
+//
+// $Date: 12/21/11 8:37p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/OpalSecurity.h $
+//
+// 3 12/21/11 8:37p Rajkumarkc
+// [TAG] EIP77142
+// [Category] BUG FIX & IMPROVEMENT
+// [Description] BUG FIX - Changed Little Endian format to Big Endian
+// format while sending commands.
+// IMPROVEMENT - Added support to Lock the Opal hdd if
+// it's unlocked on Bios POST.
+// [Files] IdeOpalSec.c, AhciOpalSec.c, OpalSecurity.c,
+// OpalSecurity.h, OpalSecurity.sdl
+//
+// 2 8/22/11 3:02a Anandakrishnanl
+// [TAG] EIP62912
+// [Category] Improvement
+// [Description] Opal Security Definitions Should be Moved to PIDEBUS.h
+// from StorageSecurityProtocol.h
+// StorageSecurityProtocol.h included in OPAL security driver module will
+// give build error when disabled without sdl token #if
+// OpalSecurity_SUPPORT properly placed in Ahcibus and IdeBus drivers. But
+// Bus driver should not depend on any tokens. For this reason need to
+// move OPAL_SEC_INIT_PROTOCOL_GUID in Pidebus.h
+// [Files] IdeBus.c
+// Pidebus.h
+// OpalSecurity.cif
+// OpalSecurity.h
+// IdeOpalSec.c
+// AhciOpalSec.c
+//
+// 1 5/19/11 2:07a Anandakrishnanl
+// Opal Security Module Initial Check In
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: OpalSecurity.h
+//
+// Description: This file contains the Includes, Definitions, typedefs, Variable
+// and External Declarations, Structure and function prototypes needed for the
+// OpalSecurity driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _OpalSecurity_
+#define _OpalSecurity_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+#include <Token.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include "Protocol\PciIo.h"
+#include "Protocol\DevicePath.h"
+#include "protocol\DriverBinding.h"
+#include "protocol\BlockIo.h"
+#include "Protocol\PDiskInfo.h"
+#include "Protocol\PIDEController.h"
+#include "Protocol\PIDEBus.h"
+#include "Protocol\StorageSecurityCommand.h"
+#include "Protocol\PAhciBus.h"
+
+//
+// TCG Storage Security Protocol
+//
+#define SECURITY_PROTOCOL_INFORMATION 0x00
+#define SECURITY_PROTOCOL_1 0x01
+#define SECURITY_PROTOCOL_2 0x02
+#define SECURITY_PROTOCOL_SDCARD_TRUSTED_FLASH 0xED
+#define SECURITY_PROTOCOL_IEEE1667 0xEE
+
+EFI_STATUS InstallOpalSecurityInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS UnInstallOpalSecurityInterface(
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag );
+
+EFI_STATUS IdeSendData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ IN VOID *PayloadBuffer );
+
+EFI_STATUS IdeReceiveData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ OUT VOID *PayloadBuffer,
+ OUT UINTN *PayloadTransferSize
+ );
+
+EFI_STATUS AhciReceiveData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ OUT VOID *PayloadBuffer,
+ OUT UINTN *PayloadTransferSize
+ );
+
+EFI_STATUS AhciSendData(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN UINT64 Timeout,
+ IN UINT8 SecurityProtocolId,
+ IN UINT16 SecurityProtocolSpecificData,
+ IN UINTN PayloadBufferSize,
+ IN VOID *PayloadBuffer
+);
+
+EFI_STATUS
+IssueLockOnResetCommand(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN VOID *BusInterface,
+ IN BOOLEAN ModeFlag
+);
+
+EFI_STATUS
+GetAndStoreSecurityProtocolInformation(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN VOID *BusInterface
+);
+
+EFI_STATUS
+GetSecurityProtocolInformation(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This,
+ IN OUT VOID *QueryBuffer,
+ IN OUT UINTN *QueryBufferSize
+);
+
+EFI_STATUS
+IEEE67TPerReset(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This
+);
+
+EFI_STATUS
+IssueTPerResetTcgSilo(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This
+);
+
+EFI_STATUS
+NativeTcgTPerReset(
+ IN EFI_STORAGE_SECURITY_COMMAND_PROTOCOL *This
+);
+
+typedef
+struct _SP0_TRUSTED_RECEIVE_PARAMETER_DATA {
+ UINT8 Reserved[6];
+ UINT8 ListLengthHigh;
+ UINT8 ListLengthLow;
+ UINT8 SupportedSPList[502];
+ UINT8 PadBytesHigh;
+ UINT8 PadBytesLow;
+}SP0_TRUSTED_RECEIVE_PARAMETER_DATA;
+
+typedef
+struct _TCG_SILO_TYPE_IDENTIFIER {
+ UINT8 Reserved[2];
+ UINT8 SiloTypeIdentifierHigh;
+ UINT8 SiloTypeIdentifierLow;
+}TCG_SILO_TYPE_IDENTIFIER;
+
+typedef
+struct _STORAGE_SECURITY_COMMAND_PROTOCOL {
+// Any new member field should be added at bottom of the structure below BusInterface
+ EFI_STORAGE_SECURITY_RECEIVE_DATA ReceiveData;
+ EFI_STORAGE_SECURITY_SEND_DATA SendData;
+ VOID *BusInterface;
+ SP0_TRUSTED_RECEIVE_PARAMETER_DATA *SupportedProtocolList;
+}STORAGE_SECURITY_COMMAND_PROTOCOL;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/OpalSecurity/OpalSecurity.mak b/Core/EM/OpalSecurity/OpalSecurity.mak
new file mode 100644
index 0000000..5a0b346
--- /dev/null
+++ b/Core/EM/OpalSecurity/OpalSecurity.mak
@@ -0,0 +1,66 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/OpalSecurity.mak 1 5/19/11 2:07a Anandakrishnanl $
+#
+# $Revision: 1 $
+#
+# $Date: 5/19/11 2:07a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/OpalSecurity/OPALSECURITY/OpalSecurity.mak $
+#
+# 1 5/19/11 2:07a Anandakrishnanl
+# Opal Security Module Initial Check In
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: OpalSecurity.mak
+#
+# Description: Make file to build OpalSecurity module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : OpalSecurity
+
+OpalSecurity : $(BUILD_DIR)\OpalSecurity.mak OpalSecurityBin
+
+$(BUILD_DIR)\OpalSecurity.mak : $(OpalSecurity_DIR)\$(@B).cif $(OpalSecurity_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(OpalSecurity_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+OpalSecurityBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\OpalSecurity.mak all\
+ GUID=59AF16B0-661D-4865-A381-38DE68385D8D\
+ ENTRY_POINT=OpalSecEntryPoint\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/OpalSecurity/OpalSecurity.sdl b/Core/EM/OpalSecurity/OpalSecurity.sdl
new file mode 100644
index 0000000..946531d
--- /dev/null
+++ b/Core/EM/OpalSecurity/OpalSecurity.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = OpalSecurity_SUPPORT
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Help = "Main switch to enable OpalSecurity support in Project"
+End
+
+TOKEN
+ Name = "TPer_LOCK_ON_RESET"
+ Value = "0"
+ Help = "Issue eDrive Lock On Reset"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+MODULE
+ Help = "Includes OpalSecurity.mak to Project"
+ File = "OpalSecurity.mak"
+End
+
+PATH
+ Name = "OpalSecurity_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\OpalSecurity.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/PCI/DeviceIo.c b/Core/EM/PCI/DeviceIo.c
new file mode 100644
index 0000000..c9c9605
--- /dev/null
+++ b/Core/EM/PCI/DeviceIo.c
@@ -0,0 +1,696 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/PciBus/DeviceIo.c 1 3/12/07 12:02p Yakovlevs $
+//
+// $Revision: 1 $
+//
+// $Date: 3/12/07 12:02p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/PciBus/DeviceIo.c $
+//
+// 1 3/12/07 12:02p Yakovlevs
+//
+// 3 4/03/06 5:17p Felixp
+// Updated to support new PCI infrastructure
+//
+// 1 4/01/05 12:45p Robert
+// Initial Checkin
+//
+// 1 1/21/05 6:27p Sivagarn
+// NB Chipset Template Initial Checkin - Based on template version 0001
+//
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//
+// Name: DeviceIo_c
+//
+// Description: This file contains the DeviceIo Protocol and its construction.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+
+#include <Token.h>
+#if AMI_ROOT_BRIDGE_SUPPORT == 1
+/****** DO NOT WRITE ABOVE THIS LINE *******/
+
+#include "PciHostBridge.h"
+#include <Protocol\PciIo.h>
+#include <Protocol\DevicePath.h>
+
+typedef struct {
+ EFI_DEVICE_IO_INTERFACE DeviceIo;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+} PRIVATE_DEVICE_IO;
+
+EFI_GUID gPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+EFI_GUID gEfiDevicePathProtocolGuid=EFI_DEVICE_PATH_PROTOCOL_GUID;
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoMemRead
+//
+// Description: Read memory into a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: PciMemRead
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Validate width parameter. The parameter is a subset of the one used by RootBridgeIo.
+// 2. Call PciRootBridgeIo PciMemRead and return its Status.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoMemRead (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ if (Width >= IO_UINT64) return EFI_INVALID_PARAMETER;
+ return PciMemRead (((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Width,Address,Count,Buffer);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoMemWrite
+//
+// Description: Write memory from a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: PciMemWrite
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Validate width parameter. The parameter is a subset of the one used by RootBridgeIo.
+// 2. Call PciRootBridgeIo PciMemWrite and return its Status.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoMemWrite (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ if (Width >= IO_UINT64) return EFI_INVALID_PARAMETER;
+ return PciMemWrite (((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Width,Address,Count,Buffer);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoIoRead
+//
+// Description: Read Io into a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: PciIoRead
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Validate width parameter. The parameter is a subset of the one used by RootBridgeIo.
+// 2. Call PciRootBridgeIo PciIoRead and return its Status.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoIoRead (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ if (Width >= IO_UINT64) return EFI_INVALID_PARAMETER;
+ return PciIoRead (((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Width,Address,Count,Buffer);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoIoWrite
+//
+// Description: Write Io from a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+/// IN EFI_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: PciIoWrite
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Validate width parameter. The parameter is a subset of the one used by RootBridgeIo.
+// 2. Call PciRootBridgeIo PciIoWrite and return its Status.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoIoWrite (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ if (Width >= IO_UINT64) return EFI_INVALID_PARAMETER;
+ return PciIoWrite (((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Width,Address,Count,Buffer);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoPciRead
+//
+// Description: Read Pci registers into a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: PciRead
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Validate width parameter. The parameter is a subset of the one used by RootBridgeIo.
+// 2. Call PciRootBridgeIo PciRead and return its Status.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoPciRead (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ if (Width >= IO_UINT64) return EFI_INVALID_PARAMETER;
+ return PciRead (((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Width,Address,Count,Buffer);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoPciWrite
+//
+// Description: Write Pci registers from a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: PciWrite
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Validate width parameter. The parameter is a subset of the one used by RootBridgeIo.
+// 2. Call PciRootBridgeIo PciWrite and return its Status.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoPciWrite (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ if (Width >= IO_UINT64) return EFI_INVALID_PARAMETER;
+ return PciWrite (((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Width,Address,Count,Buffer);
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoPciDevicePath
+//
+// Description: Get a device path for a Pci Bus/Device/Function.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN UINT64 PciAddress
+// IN OUT EFI_DEVICE_PATH **PciDevicePath
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: LocateHandleBuffer HandleProtocol GetLocation DPCopy FreePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Locate handes of the PciIo Protocol.
+// 2. Call the PciIo function GetLocation to find the matching PciDevicePath.
+// 3. If match found, copy the the DevicePath on the same handle as the PciIo
+// Protocol. Otherwise, return EFI_UNSUPPORTED.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoPciDevicePath (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN UINT64 PciAddress,
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **PciDevicePath
+)
+{
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *Path;
+
+ UINTN Segment, Bus, Device, Function;
+ EFI_STATUS Status;
+ UINTN NoHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN i;
+
+ EFI_PCI_CONFIGURATION_ADDRESS PciAddr;
+ *(UINT64*)&PciAddr = PciAddress;
+
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gPciIoProtocolGuid,
+ NULL,
+ &NoHandles,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for(i = 0; i < NoHandles; ++i)
+ {
+ Status = pBS->HandleProtocol(
+ HandleBuffer[i],
+ &gPciIoProtocolGuid,
+ &PciIo
+ );
+ if (EFI_ERROR(Status)) goto Exit; //Should never get an error here.
+
+ Status = PciIo->GetLocation(PciIo,
+ &Segment,
+ &Bus,
+ &Device,
+ &Function
+ );
+ if (EFI_ERROR(Status)) goto Exit; //Should never get an error here.
+
+
+ //Note: Difference in DeviceIo and PciRootBridgeIo defintion of PciAddress for bits [64:32].
+ //DeviceIo [39:32] = Segment and PciRootBridgeIo [64:32] = Extended register
+ if (Segment != (PciAddr.ExtendedRegister&0xff)) continue;
+ if (Bus != PciAddr.Bus || Device != PciAddr.Device || Function != PciAddr.Function) continue;
+
+ Status = pBS->HandleProtocol(
+ HandleBuffer[i],
+ &gEfiDevicePathProtocolGuid,
+ &Path
+ );
+ if (EFI_ERROR(Status))
+ {
+ Status = EFI_UNSUPPORTED; //Should never get an error here. Should always have a device path.
+ goto Exit;
+ }
+
+ *PciDevicePath = DPCopy(Path); //Copy device path.
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ Status = EFI_UNSUPPORTED;
+Exit:
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoMap
+//
+// Description: Map a device address to a host address.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_IO_OPERATION_TYPE Operation
+// IN EFI_PHYSICAL_ADDRESS *HostAddress
+// IN OUT UINTN *NumberOfBytes
+// OUT EFI_PHYSICAL_ADDRESS *DeviceAddress
+// OUT VOID **Mapping
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: Map
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Verify Operation. It is a subset of the PciRootBridgeIo Map Operation.
+// 2. Verify valid map address range. Can not map any addresses over 4G.
+// 3. Call PciRootBridgeIo Map.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoMap (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_IO_OPERATION_TYPE Operation,
+ IN EFI_PHYSICAL_ADDRESS *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping
+)
+{
+ if ((unsigned)Operation > EfiBusMasterCommonBuffer) return EFI_INVALID_PARAMETER;
+ if ((*HostAddress + *NumberOfBytes) > 0xffffffff) return EFI_UNSUPPORTED;
+
+ return Map(
+ ((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,
+ Operation,
+ (VOID*)(*HostAddress),
+ NumberOfBytes,
+ DeviceAddress,
+ Mapping);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoUnmap
+//
+// Description: Unmap a device.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN VOID *Mapping
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: Unmap
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Call PciRootBridgeIo UnMap.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoUnmap (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN VOID *Mapping
+)
+{
+ return Unmap(((PRIVATE_DEVICE_IO*)This)->RootBridgeIo, Mapping);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoAllocateBuffer
+//
+// Description: Allocate a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN EFI_ALLOCATE_TYPE Type
+// IN EFI_MEMORY_TYPE MemoryType
+// IN UINTN Pages
+// IN OUT EFI_PHYSICAL_ADDRESS *HostAddress
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: AllocatePages
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Verify inputs to function.
+// 2. If allocate type is AllocateAnyPages, change max address of 4G-1.
+// 3. If allocate type is AllocateMaxAddress of 4G, change max address to 4G-1.
+// 4. If allocate type is AllocateAddress, verify address is les than 4G.
+// 3. Call BootServices Alloate.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoAllocateBuffer (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ IN OUT EFI_PHYSICAL_ADDRESS *HostAddress
+)
+{
+ EFI_STATUS Status;
+ EFI_ALLOCATE_TYPE AllocateType = Type; //May be changed in the code below.
+
+
+ if (HostAddress == NULL) return EFI_INVALID_PARAMETER;
+ if (AllocateType >= MaxAllocateType) return EFI_INVALID_PARAMETER;
+
+ // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+ if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData)
+ return EFI_INVALID_PARAMETER;
+
+ if (AllocateType == AllocateAnyPages)
+ {
+ AllocateType = AllocateMaxAddress;
+ *HostAddress = 0xffffffff;
+ } else if (AllocateType == AllocateMaxAddress && *HostAddress > 0xffffffff)
+ {
+ *HostAddress = 0xffffffff;
+ } else //AllocateAddress
+ {
+ if (*HostAddress + 4096 * Pages > 0xffffffff) return EFI_UNSUPPORTED;
+ }
+
+
+ Status = pBS->AllocatePages (AllocateType, MemoryType, Pages, HostAddress);
+ if (EFI_ERROR(Status)) return Status;
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoFlush
+//
+// Description: Flush cache lines.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: Flush
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Call PciRootBridgeIo Flush.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoFlush (
+ IN EFI_DEVICE_IO_INTERFACE *This
+)
+{
+ return Flush(((PRIVATE_DEVICE_IO*)This)->RootBridgeIo);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: DeviceIoFreeBuffer
+//
+// Description: Free a buffer.
+//
+// Input:
+// IN EFI_DEVICE_IO_INTERFACE *This
+// IN UINTN Pages
+// IN EFI_PHYSICAL_ADDRESS HostAddress
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: FreeBuffer
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Call PciRootBridgeIo FreeBuffer.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS DeviceIoFreeBuffer (
+ IN EFI_DEVICE_IO_INTERFACE *This,
+ IN UINTN Pages,
+ IN EFI_PHYSICAL_ADDRESS HostAddress
+)
+{
+ return FreeBuffer(((PRIVATE_DEVICE_IO*)This)->RootBridgeIo,Pages,(VOID*)HostAddress);
+}
+
+
+EFI_DEVICE_IO_INTERFACE gDeviceIo = {
+ {DeviceIoMemRead,DeviceIoMemWrite},
+ {DeviceIoIoRead,DeviceIoIoWrite},
+ {DeviceIoPciRead,DeviceIoPciWrite},
+ DeviceIoMap,
+ DeviceIoPciDevicePath,
+ DeviceIoUnmap,
+ DeviceIoAllocateBuffer,
+ DeviceIoFlush,
+ DeviceIoFreeBuffer
+};
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ConstructDeviceIoProtocol
+//
+// Description: Construct a DeviceIo protocol.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RootBridgeIo
+// IN EFI_DEVICE_PATH *Path
+//
+// Output:
+// EFI_DEVICE_IO_INTERFACE *
+//
+// Modified:
+//
+// Referrals: AllocatePool
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Allocate moemory for Private DeviceIo.
+// 2. Copy DeviceIo functions to private structure.
+// 3. Copy pointer RootBridgeIo to private structure.
+// 4. Copy pointer to RootBridgeIo path to private structure.
+// 5. Return pointer to private structure.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_DEVICE_IO_INTERFACE * ConstructDeviceIoProtocol(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * RootBridgeIo, EFI_DEVICE_PATH_PROTOCOL *Path)
+{
+ EFI_STATUS Status;
+ PRIVATE_DEVICE_IO *PrivateDeviceIo;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, sizeof(PRIVATE_DEVICE_IO),&PrivateDeviceIo);
+ if (EFI_ERROR(Status)) return 0;
+
+ PrivateDeviceIo->DeviceIo = gDeviceIo;
+ PrivateDeviceIo->RootBridgeIo = RootBridgeIo;
+ PrivateDeviceIo->DevicePath = Path;
+
+ return (EFI_DEVICE_IO_INTERFACE*)PrivateDeviceIo;
+}
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#endif //#if AMI_ROOT_BRIDGE_SUPPORT == 1
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PCI/PciBus.c b/Core/EM/PCI/PciBus.c
new file mode 100644
index 0000000..bbd51a8
--- /dev/null
+++ b/Core/EM/PCI/PciBus.c
@@ -0,0 +1,13734 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/PCI/PciBus.c 3 12/19/12 7:07a Wesleychen $
+//
+// $Revision: 3 $
+//
+// $Date: 12/19/12 7:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/PCI/PciBus.c $
+//
+// 3 12/19/12 7:07a Wesleychen
+// Update to rev#152 for EIP107491.
+//
+// 152 11/26/12 4:23p Yakovlevs
+// [TAG] EIP107491
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] PciBus can not detect some pcie card (LSI).
+// [RootCause] A config write is required in order for the device to
+// re-capture the Bus number
+// [Solution] Add a dummy config write to VID/DID register offset 0
+// [Files] PciBus.c
+//
+// 150 9/20/12 12:15p Yakovlevs
+// [TAG] EIP100249
+// [Category] New Feature
+// [Description] Token to set PCIE capabilities Clock PM default value.
+// Clock PM Settings was excluded for GEN1 devices.
+//
+// [Files] PciBus.c
+//
+// 149 9/12/12 11:55a Yakovlevs
+// Restoring overrided Artem's changes.
+//
+// 148 9/12/12 11:51a Yakovlevs
+// [TAG] EIP99393
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] I350 Powerville LOM UEFI driver is not loading
+// [RootCause] Issue in invocation following function.
+// DoubleCheckOpRom((VOID*)&PciRomHdr, &Pcir);
+// variable PciRomHd was defined as buffer in stack but function requeres
+// actual pointer at the ROM
+// [Solution] Replace Parameters passing from PciRomHd to (base + trs)
+// [Files] PciBus,c
+//
+// 146 9/10/12 12:51p Yakovlevs
+// [TAG] EIP93341
+// [Category] Improvement
+// [Description] Preserve PCI DEV/LNK/SLT control register in S3 resume
+// path.
+// [Files] PciBus.c PciBus.sd PciBus.uni PciSetup.h PciPort.c
+//
+// 145 7/20/12 12:50p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Call GetOptRom before installing PciIO protocol, so ROM
+// pointer has valid vaule
+// [Files] Pcibus.c
+//
+// 144 7/13/12 5:14p Yakovlevs
+// [TAG] EIP94699
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Coding error in PciBus.c
+// [RootCause] Typo
+// [Solution] fixing typo replace tBarMmio64 with tBarMmio64pf
+// [Files] PciBus.c
+//
+// 143 6/26/12 5:53p Yakovlevs
+// [TAG] EIP93341
+// [Category] Improvement
+// [Description] Preserve PCI DEV/LNK/SLT control register in S3 resume
+// path.
+// [Files] PciBus.c
+//
+// 142 6/20/12 12:25p Olegi
+// [TAG] EIP93141
+// [Description] PCI_IO_PROTOCOL.Attributes may fail
+//
+// 141 5/22/12 4:49p Yakovlevs
+// Removing wrong comment
+//
+// 140 5/21/12 3:39p Artems
+// [TAG] EIP86097
+// [Category] Improvement
+// [Description] Separate control for loading UEFI Oprom Driver
+// Added porting hook to CsmOptOut to enable/disable UEFI
+// OpROM execution for particular PCI device, identified by PCI handle
+// [Files] PciBus.c CsmOptOut.c
+//
+// 139 5/01/12 5:07p Yakovlevs
+// [TAG] EIP84986
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Yellow mark issue in windows device manager on
+// PCIe slots if only 2 CPU for potter city platform.
+// [RootCause] For multy root system where root socets partialy
+// populated SDL data interfered with
+// Actual Hardware configuration.
+// [Solution] Allow control flow keep going when certain
+// ERROR_STATUS received.
+// [Files] PciBus.c; PciHostBridge.c
+//
+// 138 5/01/12 4:25p Yakovlevs
+// [TAG] EIP88259
+// [Category] Improvement
+// [Description] Have valid PCI handle before processing OpROM
+// [Files] PciBus.c
+//
+// 137 4/10/12 10:16a Yakovlevs
+// [TAG] EIP87005
+// [Category] Bug Fix
+// [Symptom] Aptio4.6.5.3...SCT Execution test failed.(PCI Bus Support
+// Test\PCI IO Protocol Test)
+// [RootCause] In DevAttributes() function we have masking
+// Platform specific attributes since they don't affect
+// functionality but may hung the system when somebody ties
+// to set or reset it.
+// [Solution] Remove code masking attributes 0x2000 0x4000
+// [Files] PciBus.c
+//
+// 136 12/19/11 2:08p Yakovlevs
+// [TAG] EIP73172
+// [Category] Bug Fix
+// [RootCause] It tires to read the PCI ROM header in DWORD unit.
+// However the size of PCI_STD_OPT_ROM_HEADER is 26 which can not be
+// divided by 4 without reminders.
+// After this change it will only read 24 bytes, the last 2 bytes
+// (PCI_STD_OPT_ROM_HEADER.PcirOffset) will not be read.
+// The code then read memory from the PcirOffset pointer which is
+// undefined....
+//
+// [Solution] Roll back changes keeping 1 Byte access to the opt ROM
+// header
+// [Files] PCiBus.c
+//
+// 135 12/19/11 11:06a Yakovlevs
+//
+// 134 12/19/11 11:05a Yakovlevs
+// [TAG] EIP73172
+// [Description] (JPJP000D) It stops POST Code 94h, when connected PCIE
+// media read/write device.
+// [Files] Added 4 byte alligned structure definition to handle 4 byte
+// header read.
+//
+// 133 12/14/11 6:44p Yakovlevs
+// [TAG] EIP73172
+// [Description] (JPJP000D) It stops POST Code 94h, when connected PCIE
+// media read/write device.
+// Also: fixed Init pci_address var in SetSlotProprties();
+// Fixed reconnect -r issue in PciBusStart()
+// Changed size of access to the ROM BAR register in GetOpRom() from 1
+// byte to 4 - some cards could hang the system if 1 byte is used
+//
+// [Files] PciBus.c
+//
+// 132 12/07/11 11:00a Yakovlevs
+// Fixed potential bug in PcieSetSlotProperties() routine. It was using
+// uninitialized ADDRESS var.
+//
+// 131 12/02/11 2:30p Yakovlevs
+// According to AMD GOP Driver GetBarAttributes() must return _GRA field
+// set as a bar type NOT A RESOURCE TYPE.
+//
+// 130 11/09/11 2:03p Yakovlevs
+// [TAG] EIP71380
+// [Category] New Feature
+// [Description] Core support for CSM opt-out feature
+// [Files] PciBus.c; PciPort.c; PciBus.sd; PciBus.uni; PciSetup.h;
+// PciBusSetup.c;
+//
+// 129 11/08/11 11:03a Yakovlevs
+// [TAG] EIP72803
+// [Category] Improvement
+// [Description] Small fixes of previous checkin
+// [Files] PciBus.c
+//
+// 128 11/03/11 5:59p Yakovlevs
+// Added some debug messages.
+//
+// 127 11/03/11 5:39p Yakovlevs
+// [TAG] EIP72803
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Incorrect Max Payload setting
+// [RootCause] The issue was that recorded MPL value was updated before
+// PcieProgramPayloadUp() function was invoked.
+// In that function we check condition again since it was needed to
+// maintain loop exit.
+// But control newer enter the loop since conditions were not met at that
+// point for reason stated above.
+//
+// [Solution] Move code that updates recorded MPL with a new value
+// after call to PcieProgramPayloadUp().
+// [Files] PciBus.c
+//
+// 126 10/17/11 2:39p Yakovlevs
+// [TAG] EIP71694
+// [Category] Bug Fix
+// [Symptom] Option ROM is corrupted when copied from device on Rosecity
+// Core 4.6.5.1.
+// [RootCause] MemCopy routine was updated to use 64 bit access but PCI
+// BAR
+// Copy cannot handle this
+//
+// [Solution] Introduced MemCpy32 routine to handle fast copy 4 byte at
+// a time
+// [Files] PciBus.c; MemCpy32.asm; AmiLib.h
+//
+// 124 8/03/11 2:19p Artems
+// Added changes discarded by previous check-in
+//
+// 123 8/03/11 1:14p Artems
+// EIP 64107: Added changes for module to be compliant with UEFI
+// specification v 2.3.1
+// 122 8/02/11 3:51p Yakovlevs
+// [TAG] EIP66216
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Hotplug resource padding not working for ROOT bridges other
+// than 0
+// [RootCause] Hot plug slots was incorrectly associated alvays withthe
+// RootBridge #0
+// [Solution] Changed algorithm to beter distinguish between Root
+// Bridges.
+// Added debug messagers to monitor HPC_LOCATION_DATA.
+// [Files] PciBus.c; PciHostBridge.c.
+//
+// 121 7/20/11 11:59a Yakovlevs
+// Added IO 3C0-3DF reservation when VGA attributes set.
+//
+// 120 7/06/11 11:52a Yakovlevs
+// Fixed build issue when PCI_EXPRESS_GEN2_SUPPORT token set to OFF.
+//
+// 119 6/28/11 5:33p Yakovlevs
+// [TAG] EIP63430; 61101
+// [Category] Improvement
+// [Description] 1. Replace use of PciIo->MemRead with MemCpy() for
+// Option ROMs.
+// 2.The secondary bus reset in the link retraining code causes downstream
+// PLX bridges to disappear.
+// [Files] PciBus.c
+//
+// 118 6/11/11 1:24p Yakovlevs
+// [TAG] EIP 61311
+// [Category] Improvement
+// [Description] PCI Express controllers may not be correctly
+// initialized, because of missing delays, while resetting the link.
+//
+// [Files] Added delay code and tokens PCI_T_RST and PCI_T_RST_RECOVERY
+// to fine tune delay.
+//
+// 117 6/11/11 1:05p Yakovlevs
+// [TAG] EIP 61310
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Unable to enter OpROM on Adaptec 1430 card. OpROM executes,
+// attached drives will boot but pressing Ctrl A to enter utility hangs
+// system
+// [RootCause] Card option ROM has 2 images The second one was a BOOT
+// AGENT which does not have MATCHING DID in PCIR Header.
+// [Solution] Considered DID==0 as a valid option meaning all devices.
+//
+//
+// [Files] PciBus.c
+//
+// 116 5/12/11 11:30a Yakovlevs
+// Fixed bug in PcieRetrainLink function it was not doing other attempts
+// to retrain link because of missing else statement.
+//
+// 115 5/05/11 12:27p Yakovlevs
+// Added LinkSpeed trace when link reset or retrain called.
+//
+// 114 5/04/11 6:18p Yakovlevs
+// [TAG] EIP53475; 54911
+// [Category] New Feature
+// [Description] PCI Express support issue fixed.
+// Reconnect -r issue fixed.
+// [Files] PCIBus.c
+//
+// 113 4/25/11 4:26p Yakovlevs
+// Revert back changes in DeviceAttributes() function it was done by
+// mistake.
+//
+// 112 4/21/11 6:04p Yakovlevs
+// [TAG] EIP54911
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Calling Stop function was causing ASSERT
+// [RootCause] Incorrect setting of the attributes and handling Stop
+// function for Device of Type tRootBridge.
+// [Solution] Change functions DeviceAttribute StopPciDevice.
+// [Files] PciBus.c
+//
+// 111 4/20/11 11:54a Yakovlevs
+//
+// 110 4/19/11 5:39p Yakovlevs
+// [TAG] EIP58702
+// [Category] New Feature
+// [Description] Aptio PI 1.2; UEFI 2.3.1 Support
+// Changes in Bus Drivers protocols (PCI bus driver)
+//
+// [Files] PciBus.c
+//
+// 109 4/19/11 11:02a Yakovlevs
+// [TAG] EIP 57664
+// [Category] New Feature
+// [Description] Aptio PI 1.2; UEFI 2.3.1 Support Extended PCI bus
+// driver functionality
+// Genericaly supported PCI_DEV_REVERSE_SCAN_ORDER.
+// [Files] DevicePath.h; LoadFile2.h; PciBus.h; PciBus.c.
+//
+// 108 4/05/11 11:36a Yakovlevs
+// [TAG] EIP 38174 EIP 53475;
+// [Category] New Feature
+// [Description] 38174 Generic support to handle PCI OUT OF RESOURDCES
+// added.
+// 53475 PCI Express 3.0 support added.
+//
+// [Files] PciBus.c; PciHostBridge.c;
+//
+// 107 2/02/11 3:42p Yakovlevs
+//
+// 106 1/28/11 4:26p Yakovlevs
+// [TAG] EIP48290
+// [Category] New Feature
+// [Description] Added PCI_AMI_COMBINE_MEM_PMEM32 token that tells to
+// map 32 bit sized PF MMIO BARs trough NON PF MMIO Bridge registers.
+//
+// [Files] PciBus.c; PciBus.sdl;
+//
+// 105 1/28/11 2:55p Yakovlevs
+// [TAG] EIP43879
+// [Category] New Feature
+// [Description] Added PciPortOemGetOptRom() OEM Hook to override
+// content of the PCI Device Option ROM.
+// [Files] PciBus.c; PciPort.c; PciPort.h; PciBus.mak; PciBus.sdl
+//
+// 104 1/20/11 3:07p Yakovlevs
+// [TAG] EIP45278
+// [Category] Improvement
+// [Description] Added PCI_MMIO_RES_TOP_ALLIGN token to control Resource
+// allocation algorithm selection.
+// [Files] PciBus.c; PciHostBridge.c; PciBus.sdl.
+//
+// 103 1/14/11 10:50a Yakovlevs
+// [TAG] EIPEIP49743
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Incorrect initialization complicated PCI infrastructure
+// [RootCause] wrong condition to breake {do while loop}.
+// [Solution] Change conditions
+// [Files] PciBus.c
+//
+// 102 1/13/11 2:59p Yakovlevs
+// [TAG] EIP49743
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] In the PcieCalcLatency(), the do-while loop condition have
+// issue in this.
+// [RootCause] It may be a condition when while loop in function
+// PcieCalcLatency(), will never break.
+// [Solution] Cahnge conditiondn iinstead of logical OR use AND.
+// [Files] PciBus.c
+//
+// 101 1/13/11 1:31p Yakovlevs
+// [TAG] EIP45278
+// [Category] Improvement
+// [Description] Changed default resource allocation algorithm to work
+// more efficiently.
+// [Files] PciBus.c; PciHostBridge.c.
+//
+// 100 1/13/11 1:21p Yakovlevs
+// [TAG] EIP49743
+// [Category] Improvement
+// [Description] Workaround for devices which having Link Retrain bit
+// "sticky"
+// [Files] PciBus.c
+//
+// 99 1/13/11 1:14p Yakovlevs
+// [TAG] EIP50097
+// [Category] Improvement
+// [Description] Fixed issue when with PCI_FIXED_BUS_ASSIGNMENT==1
+// system was ASSERTING.
+// Reason was that with complicated PCI structure next bridge XLAT entry
+// that used to determine Subordinate bus #, selected incorrectly.
+//
+// [Files] PciBus.c
+//
+// 98 12/09/10 2:53p Yakovlevs
+// Fixed bug in PcieCalcLatency() function. It was not calculating L1
+// latency correctly.
+//
+// 97 12/08/10 3:17p Yakovlevs
+// Removed Setup Option "Selectable DeEmphasis" since it is HwInit Bit.
+//
+// 96 11/18/10 3:50p Yakovlevs
+// 1.Changed Install Option ROM debug messages to make it more precise.
+// 2. Added call to DoubleCheckOpRom() to verify ROM size before
+// processing UEFI OpROM.
+//
+// 95 11/12/10 6:37p Yakovlevs
+// PcieDoubleCheckCard() routine added to support cards that slowly
+// respond on CFG transactions.
+//
+// 94 11/08/10 6:16p Felixp
+//
+// 93 11/08/10 6:13p Felixp
+// The Core source files are updated to remove upper ASCII characters
+// (above 128)
+// from the comment blocks. The characters caused build errors
+// with Japanese version of Microsoft compiler.
+//
+// 92 11/05/10 5:06p Yakovlevs
+// Changed if Default (AUTO) MaxReadRequest selected don't change value
+// sitting there.
+// Removed assert in PcieConvertLatency function.
+//
+// 90 10/07/10 12:13p Felixp
+// PEI_TRACE on TPL_HIGH is removed.
+// Headers updated.
+//
+// 89 10/05/10 4:46p Yakovlevs
+// Changed Default (AUTO) MaxReadRequest Size value from == MPL to spec.
+// default == 512.
+//
+// 88 10/01/10 6:05p Yakovlevs
+// Fixed issue with low level PciCfgXX() access functions. When
+// ExtendedRgister used.
+//
+// 87 9/01/10 11:52a Yakovlevs
+// Improved Override ASPM Porting hook, now it called for UPSTREAM as well
+// as DOWNSTREAM port.
+//
+// 86 8/16/10 1:05p Yakovlevs
+// New Incompatibility Type Sypport: icBad64BitBar - Device has a bar that
+// is 64bit capable, but the card does not function properly when it is
+// allocated.
+//
+// 85 7/08/10 6:00p Yakovlevs
+// Removed EFI_EADLOOP() left in InstallEfiRom() function
+//
+// 84 7/08/10 3:12p Yakovlevs
+// Fixed UEFI Option ROM Size miscalculation.
+//
+// 83 6/30/10 11:11a Yakovlevs
+// Fixed WDK Build Issue EIP 40554
+//
+// 82 6/08/10 3:31p Yakovlevs
+// Minor fix for EIP 38289 Klocwork Issues II.
+//
+// 81 6/07/10 3:36p Yakovlevs
+// Improved logic to select matching PCI Bus Xlat table entry.
+//
+// 80 5/25/10 3:16p Yakovlevs
+// Fixed condition to disable device using 64 bit resource threshold
+//
+// 79 5/19/10 12:43p Yakovlevs
+//
+// 78 5/07/10 12:24p Yakovlevs
+// Bug fix in PcieProgramPayloadUp() function. canged order when recording
+// calculated PayLoad.
+// It use to recursive call was made after reduced value of MPL was
+// recorded. It was preventing function to program MPL correctly.
+//
+// 77 4/28/10 11:33a Yakovlevs
+// Fixed bug in DoubleCheckOpRom() when OpROM is a Single Image ROM.
+//
+// 76 4/20/10 5:46p Yakovlevs
+// Fixed build error with SRIOV token ON; Fixed InitDevCahain() function
+// Logic.
+//
+// 75 4/15/10 4:28p Yakovlevs
+// Fixed issue with PCIe Switches and MPL programming UP
+//
+// 74 4/14/10 4:43p Yakovlevs
+// Fixed Possible issue with incorrect MPL Programming.
+//
+// 73 3/03/10 12:46p Yakovlevs
+// Fixed bug in IsFunc0() function.
+//
+// 72 3/01/10 6:18p Yakovlevs
+// PCI Express V2.1 support added.
+//
+// 68 12/24/09 10:45a Yakovlevs
+// Fixed issue when removing unused entries from IRQ routing tables, PIC
+// and APIC.
+//
+// 67 9/24/09 1:51p Yakovlevs
+// Fixed EIP 26787. If P2P Bridge has ExpROM BAR, value that has to go
+// there was programmed as Secondary Interface Forward Range.
+//
+// 66 9/22/09 6:09p Yakovlevs
+// 6. Fixed conditions in ApplyAcpiResources() where function assumes
+// validity of Resource Range. In case of Fixed Resource Allocation
+// Resource window allocated by custom unction might be bigger than actual
+// hardware resource request
+//
+// 65 9/08/09 12:57p Yakovlevs
+// Fixed ~0LU statement to 0ULL. This is correct statement for 64 bit
+// Value
+// Made QueryPciDevice() routine set Interrupt Line register(0x3C) to 0xFF
+//
+// 64 8/28/09 10:27a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 63 8/21/09 3:53p Yakovlevs
+// Fixed: EIP 19106 If 1 Bus set to be paded in Setup, PCI Bus driver
+// still creates 1 BUS for this bridge instead of 2.
+//
+//
+// 62 7/07/09 12:39p Yakovlevs
+// Moved DisableBridgeDecoding() call before Disable device decoding since
+// it could decode 0-4K of IO and 0-1M of Mem.
+//
+// 61 5/22/09 2:16p Yakovlevs
+//
+// 60 5/05/09 5:46p Yakovlevs
+// Fixed build issue in IA32 mode with SRIOV_SUPPORT == ON.
+//
+// 59 4/24/09 11:49a Yakovlevs
+//
+// 58 4/23/09 8:28p Yakovlevs
+// Fixed some minor issues related to PCI IRQ entries usage and updating.
+//
+// 57 4/23/09 2:02p Yakovlevs
+// Fixed potentiial Memory Coruption issue when assigning Ext->XlatEntry
+// ->BusRun
+// for bridges who doesnot have it's XlatTbl Entry.
+//
+// 56 4/19/09 2:14p Yakovlevs
+// Fixed issue with Multiple Root Bridges, when PCI Bus Driver was
+// incorrectly calculating ranges buses to scan.
+//
+// 55 4/17/09 6:38p Yakovlevs
+// Fixed issue EIP 21366 with OptimizeBrgResource() function see EIP for
+// more details.
+//
+// 54 4/16/09 1:49p Yakovlevs
+// Fixed issue where for Second Root Bridge Bus numbers were assifned
+// started fron LAST ROOT_0_BUS + 1
+//
+// 53 4/01/09 9:57a Yakovlevs
+// Minor fixes
+//
+// 52 3/30/09 5:23p Yakovlevs
+// Fixed issue in AssignBridgeResources function when there are no bars to
+// program function was returning ERROR Status.
+//
+// 51 3/27/09 7:02p Yakovlevs
+// Fixed Uninitialized PCI DB issue.
+//
+// 50 3/27/09 11:47a Yakovlevs
+// Fixed some issues with re starting driver.
+//
+// 49 3/25/09 11:02a Yakovlevs
+// ADDED Generic implementation of #PERR, #SERR; and VGA Palette Snoop.
+//
+// 48 3/23/09 2:27p Yakovlevs
+// ADDED support for VGA_16_BIT_DECODE. VGA aliasing support pending.
+//
+// 47 2/04/09 4:03p Yakovlevs
+// Fixed PciPortSkipThisDevice() function was not preserving PCI.CMD
+// register.
+//
+// 46 2/04/09 4:01p Yakovlevs
+//
+// 45 2/03/09 3:27p Yakovlevs
+// Added fixes for EIP 19144. Break the PCI Express Extended Capability
+// header access routine if read of offset 0x100 returns 0xFFFF
+//
+// 44 1/30/09 1:03p Yakovlevs
+// Minor bug fixes and improuvements EIP 8874; EIP 17947
+//
+// 43 11/26/08 3:55p Yakovlevs
+//
+// 42 11/26/08 3:54p Yakovlevs
+// Start function NOW returns EFI_ALREADY_STARTED, when all PCI devices
+// installed PciIo interface.
+//
+// 41 11/26/08 11:37a Yakovlevs
+// Fixed connect -r issue when shell was hunging in infinite loop.
+//
+// 40 11/14/08 3:34p Yakovlevs
+// Removed EFI_DEADLOOP() used for debug
+//
+// 39 11/14/08 1:21p Yakovlevs
+// Introduced AMI Board Info Protocol which has *.inc OUTPUTS generated
+// by AMISDL tool. To keep it in one place and Make PciBus Driver use it.
+//
+// 38 10/31/08 6:10p Yakovlevs
+//
+// 36 10/15/08 10:45a Yakovlevs
+// Fixed EIP 16990 CsmVideo can't work
+//
+// 35 10/14/08 1:15p Yakovlevs
+// Rearrange Function order to support ROM BARs as PCI incompatible BARs
+//
+// 33 10/10/08 5:40p Yakovlevs
+// Added Pci Compliance tests workarounds
+//
+// 32 10/01/08 7:12p Yakovlevs
+// Updated AMI FUNC HEADER information
+//
+// 31 9/24/08 6:41p Yakovlevs
+// New features and bug fixes:
+// New features.
+// 1. Make PCI Bus Driver use VeB generated structures.
+// 2. Added SRIOV support
+// 3. Added Fixed Bus Allocation (Buses for the bridges will be allocated
+// same way as in Build time)
+// 4. Scan full bus ranges.
+// 5. Added support for UEFI 2.1 PCI requirements.
+// 6. Added Token to disable PCI Bus Driver Debug Messages.
+// 7. Removed dependency from SETUP_DATA fields layout.
+// 8. Progress/Error codes.
+// 9. Support for S3 Video Repost.
+//
+// Bug fixes:
+// 1. Attribute function.
+// 2. If device decodes only PFMMIO Bridge MMIO Base and Limit register
+// was initialized with 0 making it decode space from 0x10000.
+// 3. OptimizeBridgeResources() function was not working correctly in some
+// rare cases.
+//
+// 29 5/13/08 11:59a Felixp
+// ComponentName protocol converted to ComponentName2
+//
+// 28 4/29/08 6:55p Yakovlevs
+// Generic S3 Video Repost support added.
+// Added mechanism to suppress PCI BUs driver debug messages(Latest
+// PciBus.sdl and PciBus.h required).
+//
+// 27 4/24/08 12:19p Yakovlevs
+// Added generic support for S3 VIDEO Repost feature.
+//
+// 26 4/18/08 3:53p Yakovlevs
+// Added missing function headers
+//
+// 25 4/17/08 6:23p Yakovlevs
+// fixed potencial issue in OptimizeBridgeResources.
+//
+// 24 3/12/08 12:45p Felixp
+// Progress/Error codes reporting added
+//
+// 23 2/21/08 4:37p Felixp
+// 1. Bug fix in StartPciChildDevice. Handling of remaining device path
+// has changed.
+// 2. Handling of setup data structure in PciBusStart updated to work fine
+// without PCI sources
+//
+// 22 1/31/08 8:31p Yakovlevs
+// Fixed issue with hotplug resource padding.
+//
+// 21 1/31/08 2:51p Yakovlevs
+// 1. Fixed resource allocation issue on bridges only branches.
+// 2. Cahnged Default Padding routine for Card bus bridges.
+//
+// 20 12/10/07 4:15p Yakovlevs
+// 1.Fixed bug in OprimizeBrgResources() function, (it might hung in
+// infinite loop).
+// 2.Corrected ApplyCrdPadding () implementation to take care of
+// EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM allocation attribute.
+//
+// 19 11/08/07 4:51p Felixp
+// Code updated to compile and work without CSM.
+//
+// 18 10/23/07 5:28p Felixp
+// VC8 warnings fixed
+//
+// 17 10/18/07 11:22a Felixp
+// ASPN SDL tokens replaced with external constants defined in PciPort.c
+//
+// 16 10/15/07 4:11p Yakovlevs
+// Fixed bug in OptimizeResources function.
+//
+// 15 10/08/07 5:26p Yakovlevs
+// Fix to handle not compliant PCI Option Roms.
+//
+// 4 9/21/07 6:38p Yakovlevs
+// Sinchronize with recent PCI Bus updates
+//
+// 14 9/21/07 6:24p Yakovlevs
+// Fixed ASPM related bugs.
+//
+// 13 9/18/07 5:23p Yakovlevs
+// Inplemented Intel's recomendation of calculating EP Acceptable ASPM
+// Latency.
+//
+// 12 8/31/07 11:18a Yakovlevs
+// Improuvements in PCI Resource Allocation Algorithm.
+//
+// 10 7/25/07 12:54p Felixp
+// AMI Debugger-related code is updated to enable Debugger in non-debug
+// mode.
+// The code is enabled when USB_DEBUG_TRANSPORT or EFI_DEBUG is on.
+//
+// 9 7/17/07 6:29p Felixp
+// Minor bug fix in GetOptRom: GetEmbeddedRom was called with UINT32 image
+// size pointer instead of UINTN
+//
+// 8 7/04/07 5:51a Yakovlevs
+// Version of this file will work with 4.5.3_CSM.6.37_51 label of CSM,
+// which requires USB module upgrade to Label 4.05.03_USB_08.07.11.
+// 1. Fixed Disabling VGA attributes for Devices behind multiple bridges.
+// 2. Added some debug messages for Installing Devices PciIo interface.
+// 3. Changed GetOptRom() function to search for Embeded ROMs(onboard) as
+// well and populate PciIo.OptionRom*.
+//
+// 7 5/23/07 5:32p Yakovlevs
+// Previouse fix had some side effects on protocol installation side -
+// this one fixes these.
+// Also some debug messages at protocol installation phase was added.
+//
+// 6 5/18/07 6:30p Yakovlevs
+// Fixed Issue with incorrect Status returning from StartPciChildDevice().
+//
+// 5 5/14/07 7:49p Yakovlevs
+// Somehow changes to impruve PCI Config Acces were lost. Resored them.
+//
+// 4 5/04/07 3:50p Yakovlevs
+//
+// 3 5/04/07 11:51a Yakovlevs
+//
+// 2 5/02/07 4:41p Yakovlevs
+//
+// 1 3/12/07 12:02p Yakovlevs
+//
+// 48 12/28/06 7:16p Yakovlevs
+// In ActivateOptRom function removed upate of OptROM size where
+// PciIo->OptionRom points
+// It is not needed.
+//
+// 47 12/22/06 9:42p Yakovlevs
+// Code Cleanup and CHM headers added
+//
+// 46 12/21/06 5:13p Yakovlevs
+// Code cleanup. Added CHM headers.
+//
+// 44 12/19/06 11:54a Yakovlevs
+// Fixed Padding for the bridge if CombineMemPmem Allocation Attribute is
+// set
+//
+// 43 12/05/06 3:27p Yakovlevs
+// Fixed SCT 2.0 PciIo Disable Attributes ISSUE.
+//
+// 42 12/05/06 11:54a Felixp
+//
+// 41 11/22/06 10:27a Olegi
+//
+// 40 11/22/06 10:26a Olegi
+// InstallPciDevice is modified so that the device with DebugPort
+// enumeration will not be skipped.
+//
+// 39 10/20/06 5:50p Yakovlevs
+//
+// 38 10/13/06 4:42p Yakovlevs
+//
+// 37 10/13/06 4:10p Yakovlevs
+// Function Headers Added!!!!! IDE Attributes support added, Hotplug
+// support fix (NULL pointer).
+//
+// 36 9/11/06 11:51a Yakovlevs
+// Fixed CacheLineSize rergister programming issue
+//
+// 35 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 34 8/09/06 5:08p Yakovlevs
+// VC initialization and boot sript support for PCI Express.
+// This fixes NVIDIA 7800 GT issue
+//
+// 31 6/04/06 9:06p Yakovlevs
+// Fixed issue when PciBus driver was writting in IRQ Line Reg some junk.
+//
+// 30 6/04/06 8:22p Yakovlevs
+// Fixed PCI_EXPRESS_SUPPORT and HOTPLUG_SUPPORT featueses.
+// Added some debug messages during PCI bus enumeration process.
+//
+// 29 6/01/06 12:21p Yakovlevs
+// Changes to accomodate HbCspAdjustMemoryMmioOverlap function in PciRB.
+//
+// 28 5/19/06 10:45p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 27 4/25/06 4:49p Stacyh
+//
+// 26 4/03/06 3:52p Felixp
+// Major changes in PCI and Super I/O:
+// PCI - Root Bridge Resource Allocation Sepcification support
+// Super I/O - multiple Super I/O support; SIO Setup page added;
+//
+// 25 3/20/06 9:26a Felixp
+// Bug fix in attribute clearing logic.
+//
+// 24 3/13/06 10:07a Felixp
+//
+// 21 11/08/05 4:08a Felixp
+// AMI Debugger ifdefs changed from AMI_DEBUGGER_SUPPORT to EFI_DEBUG
+//
+// 20 10/27/05 5:39p Felixp
+//
+// 19 10/12/05 7:19p Felixp
+// AMI Debugger support added
+//
+// 18 7/18/05 3:25p Felixp
+//
+// 17 6/26/05 6:50p Olegi
+// Incompatible PCI device list updated.
+//
+// 16 6/26/05 6:43p Yakovlevs
+// Card Bus Support Added
+// Some other bug fixes
+// Incompatibility list extended with icBarFixedSize.
+//
+// 15 5/25/05 6:26p Yakovlevs
+//
+// 14 5/11/05 3:09p Yakovlevs
+// Fixed: CacheLine Size register Latency timer Reg, gets programmed,
+// IO resource lesser than 16 bytes padded to 16 bytes.
+//
+// 13 4/21/05 2:03p Sivagarn
+// - Option ROM signature is validated before copying into the memory
+// - Option ROM size is obtained from the header instead of using size
+// calculated from PCI base register
+//
+// 12 4/06/05 10:33a Felixp
+// Bug fix in StartPciDevices
+//
+// 11 3/29/05 5:16p Olegi
+// Problem with ATI Video fixed.
+//
+// 10 3/23/05 6:17p Yakovlevs
+//
+// 9 3/23/05 5:48p Yakovlevs
+// Changes to avoid clearing HostBridge Command register.
+//
+// 8 3/15/05 5:23p Yakovlevs
+// Option ROM issue for on bord device with implemented ROM BAR and ROM
+// image at ROM BIOS fixed.
+// Now if ActivateOptionRom routine fails to validate option rom it frees
+// OptROM buffer.
+//
+// 7 3/04/05 9:26a Mandal
+//
+// 6 2/14/05 7:36p Yakovlevs
+// Handled situation when Start Function calls multiple times for every
+// next DP node.
+// Fixed Option Rom Size issue
+//
+// 5 2/14/05 6:12p Yakovlevs
+//
+// 4 2/13/05 4:54p Yakovlevs
+// Fixed issue with 64 bit width BARs; PCI incompatible device support
+// added.
+//
+// 3 2/11/05 7:48p Yakovlevs
+// Incompatible Pci Device Support added.
+//
+// 2 2/01/05 1:16a Felixp
+//
+// 1 1/28/05 12:45p Felixp
+//
+// 8 1/21/05 7:00p Yakovlevs
+//
+// 7 1/21/05 5:19p Yakovlevs
+// Fixed some stuff from TODO list:
+// 1.Made ajustments to exchange information with RB Driver.
+// 2.Support of 64 bit resources on P2P Brg (EnableBrgPfmmDecoding)
+// routine,
+//
+// 4 1/13/05 8:26p Yakovlevs
+//
+// 3 1/11/05 5:25p Yakovlevs
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 55 12/21/04 4:20p Markw
+// Renamed hardware device path definition for consistency.
+//
+// 54 12/06/04 5:14p Yakovlevs
+//
+// 53 12/06/04 4:51p Robert
+// PciIoCheckConfig - the comparison for the buffer length should not
+// exceed 256 bytes. Therefore it should be > not >=
+//
+// 52 10/22/04 7:26p Yakovlevs
+//
+// 51 10/20/04 3:02p Yakovlevs
+//
+// 50 10/20/04 11:43a Yakovlevs
+// InstallMultipleProtocol and Close Protocol opened by Child Controller
+// added
+//
+// 49 10/20/04 9:28a Yakovlevs
+//
+// 48 10/04/04 1:44p Yakovlevs
+// Make use of AcpuRes.h resource Tamplete Definitions
+//
+// 47 9/24/04 9:31p Yakovlevs
+// Uncachable Attributes set for PCI Bus MMIO regions
+//
+// 46 9/22/04 6:51p Yakovlevs
+//
+// 45 9/16/04 10:24a Yakovlevs
+//
+// 44 9/15/04 6:01p Yakovlevs
+//
+// 43 9/15/04 9:42a Yakovlevs
+//
+// 42 9/09/04 3:06p Yakovlevs
+// Bug fixes:
+// 1. Handling of RemainingDevicePath in Start routine
+// 2. Option ROM handling
+// Path:
+// Temporary patch to make Cirrus Logic and some other Add-On cards work
+//
+// 41 9/03/04 11:58a Yakovlevs
+//
+// 40 8/27/04 6:36p Yakovlevs
+//
+// 39 8/26/04 7:47p Yakovlevs
+// SCT PCI Bus Support -> OK!
+//
+// 38 8/24/04 1:01p Yakovlevs
+//
+// 37 8/15/04 7:32p Yakovlevs
+//
+// 36 8/13/04 9:21a Yakovlevs
+//
+// 35 7/13/04 10:42a Felixp
+//
+// 34 5/27/04 10:30a Yakovlevs
+//
+// 33 5/06/04 8:20p Felixp
+//
+// 32 5/06/04 6:31p Felixp
+//
+// 31 5/06/04 10:25a Yakovlevs
+//
+// 30 5/05/04 8:14p Yakovlevs
+//
+// 28 5/03/04 8:13p Felixp
+//
+// 27 5/03/04 6:15p Yakovlevs
+//
+// 26 5/03/04 6:04p Yakovlevs
+//
+// 25 5/03/04 12:24p Yakovlevs
+//
+// 24 5/03/04 11:52a Yakovlevs
+// Changes to avoid hardcoded Array size and accomodate all resource types
+//
+// 23 4/23/04 5:43p Felixp
+//
+// 22 4/23/04 3:20p Felixp
+//
+// 21 4/23/04 2:36p Felixp
+//
+// 20 4/23/04 12:08p Felixp
+//
+// 19 4/22/04 12:27p Yakovlevs
+//
+// 18 4/21/04 8:33p Yakovlevs
+//
+// 17 4/21/04 12:49p Yakovlevs
+//
+// 16 4/20/04 9:19p Yakovlevs
+//
+// 15 4/20/04 11:51a Yakovlevs
+//
+// 14 4/19/04 11:56a Yakovlevs
+//
+// 13 4/18/04 4:05p Felixp
+//
+// 12 4/16/04 7:12p Felixp
+//
+// 11 4/12/04 4:59p Yakovlevs
+//
+// 10 4/12/04 4:12p Yakovlevs
+//
+// 9 4/09/04 6:40p Yakovlevs
+//
+// 8 4/02/04 6:28p Yakovlevs
+//
+// 7 4/02/04 6:23p Yakovlevs
+//
+// 6 4/02/04 6:05p Yakovlevs
+//
+// 5 3/28/04 2:11p Felixp
+// 1. PE Loader and some other commonly used code moved to the Library
+// 2. Warnings fixed (from now on warning will be treated as error)
+//
+// 4 3/26/04 1:50p Yakovlevs
+//
+// 3 3/26/04 1:19p Felixp
+//
+// 2 3/22/04 10:29a Yakovlevs
+//
+// 1 3/15/04 11:20a Felixp
+//
+// 1 3/12/04 6:47p Yakovlevs
+//
+// 3 2/04/04 6:50p Yakovlevs
+//
+// 2 2/04/04 4:22p Yakovlevs
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <PciBus.c>
+//
+// Description: EFI PCI Bus Generic Driver.
+//
+// Tabsize: 4
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//---------------------------------------------------------------------------
+// Include Files
+//---------------------------------------------------------------------------
+#include <Efi.h>
+#include <Token.h>
+#include <Protocol\PciRootBridgeIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\BusSpecificDriverOverride.h>
+#include <Protocol\Decompress.h>
+#include <Protocol\ComponentName2.h>
+#include <Protocol\PciHostBridgeResourceAllocation.h>
+#include <Protocol\PciHotplugInit.h>
+#include <Protocol\PciPlatform.h>
+#include <Protocol\IncompatiblePciDeviceSupport.h>
+#include <Protocol\BootScriptSave.h>
+#include <Dxe.h>
+#include <AmiDxeLib.h>
+#include <AMIHobs.h>
+#include <PciBus.h>
+#include <PciBusEx.h>
+#include <AcpiRes.h>
+#include <AmiLoadCsmPolicy.h>
+
+#if PCI_OUT_OF_RESOURCE_SETUP_SUPPORT
+#include <Setup.h>
+#endif
+#include "PciPort.h"
+
+#if CSM_SUPPORT
+#include <Protocol\LegacyBiosExt.h>
+#endif
+
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+#include <AmiDebugPort.h>
+#endif
+
+#include "PciSetup.h"
+
+//==================================================================================
+//Function Prototypes for Driver Binding Protocol Interface
+//==================================================================================
+EFI_STATUS PciBusSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS PciBusStart(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS PciBusStop(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer);
+
+EFI_STATUS EnumerateAll(EFI_HANDLE Controller);
+
+EFI_STATUS StartPciDevices(IN EFI_HANDLE ControllerHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+//-------------------------------------------------------
+//Forward declarations for Extended PCI Bus Protocol
+EFI_STATUS PciExtIsPciExpresss(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCIE_DATA **PciExpData OPTIONAL
+);
+
+EFI_STATUS PciExtIsPciX(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCIX_DATA **PciXData OPTIONAL
+);
+
+EFI_STATUS PciExtIsPciBrg(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_BRG_EXT **BrgData OPTIONAL
+);
+
+
+EFI_STATUS PciExtIsCrdBrg(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_BRG_EXT **BrgData OPTIONAL
+);
+
+
+EFI_STATUS PciExtIsDevice(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL
+);
+
+
+EFI_STATUS PciExtClassCodes(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_DEV_CLASS *CassCodes
+);
+
+
+EFI_STATUS PciExtPicIrqRout (
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_IRQ_PIC_ROUTE **PicIrqTblEntry,
+ OUT EFI_PCI_CONFIGURATION_ADDRESS **ParentDevices,
+ OUT UINTN *EntryCount
+);
+
+EFI_STATUS PciExtApicIrqRout (
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_IRQ_APIC_ROUTE **ApicIrqTblEntry,
+ OUT EFI_PCI_CONFIGURATION_ADDRESS **ParentDevices,
+ OUT UINTN *EntryCount
+);
+
+EFI_STATUS ReadEfiRom(PCI_DEV_INFO *Dev, PCI_ROM_IMAGE_DATA *RomData, VOID **ImgBase, UINT32 *ImgSize);
+
+//==================================================================================
+//Some Protocole GUIDs needed here
+//==================================================================================
+static EFI_GUID gDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+static EFI_GUID gPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+static EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+static EFI_GUID gPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+static EFI_GUID gBusSpecificDriverOverrideProtocolGuid = EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL_GUID;
+static EFI_GUID gEfiDecompressProtocolGuid = EFI_DECOMPRESS_PROTOCOL_GUID;
+static EFI_GUID gEfiPciHostBrgResAllocProtocolGuid = EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GUID;
+static EFI_GUID gEfiPciHotPlugInitProtocolGuid = EFI_PCI_HOT_PLUG_INIT_PROTOCOL_GUID;
+static EFI_GUID gEfiPciPlatformProtocolGuid = EFI_PCI_PLATFORM_PROTOCOL_GUID;
+static EFI_GUID gEfiIncompatiblePciDeviceProtocolGuid = EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL_GUID;
+static EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+static EFI_GUID gAmiExtPciBusProtocolGuid = AMI_PCI_BUS_EXT_PROTOCOL_GUID;
+static EFI_GUID gAmiBoardInfoProtocolGuid = AMI_BOARD_INFO_PROTOCOL_GUID;
+
+#if CSM_SUPPORT
+static EFI_GUID gEfiLegacyBiosExtProtocolGuid = EFI_LEGACY_BIOS_EXT_PROTOCOL_GUID;
+#endif
+
+
+#if PCI_EXPRESS_SUPPORT
+static T_ITEM_LIST gPcieEpList = {0,0,NULL};
+#endif
+
+
+//=============================================================================
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gBadPciDevList
+//
+// Description: Incompatible PCI Devices List known so far.
+//
+// Notes:
+// See PCI_BAD_BAR for field names and usage details.
+// If BarType field == tBarMaxType then BarOffset field should be used.
+// For "BarType" field only tBarIo, tBarMem and tBarMaxType allowed!
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+PCI_BAD_BAR gBadPciDevList[]={
+//-----------------------------------------------------------------------------------------------------------------------
+//enum UINT16 UINT16 UINT16 UINT16 PCI_BAR_TYPE UINTN UINT64 UINT64
+//IncompType; VendorId; DeviceId; DevIdMask; Reserved; BarType; BarOffset; BarBase; BarLength;
+//-----------------------------------------------------------------------------------------------------------------------
+//Device Adaptec 9004
+{ icBarBad, 0x9004, 0xFFFF, 0x0000, 0x0000, tBarIo, 0x0000, 0, 0 },
+//Device Adaptec 9005
+{ icBarBad, 0x9005, 0xFFFF, 0x0000, 0x0000, tBarIo, 0x0000, 0, 0 },
+//Device QLogic 1007
+{ icBarBad, 0x1007, 0xFFFF, 0x0000, 0x0000, tBarIo, 0x0000, 0, 0 },
+//Device Agilent 103C
+{ icBarBad, 0x103C, 0xFFFF, 0x0000, 0x0000, tBarIo, 0x0000, 0, 0 },
+//Device Agilent 15BC
+{ icBarBad, 0x15BC, 0xFFFF, 0x0000, 0x0000, tBarIo, 0x0000, 0, 0 },
+//Device AMI Mega RAID 493
+{icBarFixedSize,0x1077, 0x1216, 0xFFFF, 0x0000, tBarMaxType,0x0014, 0, 0x400000 },
+//ICH8 smbus controller
+{icNotBar, 0x8086, 0x283E, 0xFFFF, 0x0000, tBarMaxType,0x0014, 0, 0 },
+//RTL8111E
+{ icNotBar, 0x10EC, 0x8168, 0xFFFF, 0x0000, tBarMaxType,0x0030, 0, 0 },
+//NVIDIA 7200 GS
+{icBad64BitBar, 0x10de, 0x01d3, 0xFFFF, 0x0000, tBarMaxType,0x0014, 0, 0 }
+};
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gBadPciDevCount
+//
+// Description: Number or records in gBadPciDevList table.
+// Notes: UINTN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINTN gBadPciDevCount=sizeof(gBadPciDevList)/sizeof(PCI_BAD_BAR);
+
+
+//==================================================================================
+// PCI Bus Driver Global Variables
+//==================================================================================
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gAllocationAttributes
+//
+// Description: Root Bridge Allocation Attributes
+// Notes: UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT64 gAllocationAttributes=0;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciOutOfRes
+//
+// Description: Indicates Out Of Resources Condition.
+// Notes: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+BOOLEAN gPciOutOfRes=FALSE;
+
+BOOLEAN gPciOutOfResHit=FALSE;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gLowResType
+//
+// Description: Indicates what type of resource has Out Of Resources Condition.
+// Notes: MRES_TYPE
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+MRES_TYPE gLowResType=rtMaxRes;
+
+AMI_OUT_OF_RES_VAR gPciOutOfResData={0};
+
+
+//----------------------------------------------------------------------------------
+//EfiDBE Key field definition used to sort resources by size
+//Function prototypes used for Compare keys we will use a custom way.
+//We will be using combination UINT64 Length (LS64) + UINT64 Granularity (MS64).
+INTN Cmp128IntRR(IN VOID *pContext, VOID *pRecord1, VOID *pRecord2);
+INTN Cmp128IntKR(IN DBE_OFFSET_KEY_CONTEXT *pContext, VOID *pKey, VOID *pRecord);
+//Initialize BAR DataBase KeyField Structure
+DBE_OFFSET_KEY_CONTEXT BarKeyInfo = { EFI_FIELD_OFFSET(PCI_BAR,Length),
+ EFI_FIELD_SIZE(PCI_BAR,Length)+EFI_FIELD_SIZE(PCI_BAR,Gran)};
+DBE_KEY_FIELD gBarKey = {&Cmp128IntRR, &Cmp128IntKR, &BarKeyInfo};
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciBusDb
+//
+// Description: Bus order Data Base if fixed bus allocation selected we need
+// to know how many buses does this bridge suppose to decode
+// Notes: T_ITEM_LIST
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+T_ITEM_LIST gPciBusDb={0,0,NULL};
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: *gPciSetupData
+//
+// Description: Global Setup Variable to get the setup settings pointer.
+//
+// Notes: PCI_SETUP_DATA
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+PCI_SETUP_DATA *gPciSetupData=NULL;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: mMaxBusFound; mMaxBusScan; mMaxBusReport.
+//
+// Description: Global counter of buses found.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 mMaxBusFound;
+UINTN mMaxBusScan;
+UINT8 mMaxBusReport=0;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gHostCnt
+//
+// Description: Initial Global Variable to store Host Bridge Count.
+//
+// Notes: UINTN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINTN gHostCnt;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciHost
+//
+// Description: Initial Global Variable to store pointer on PCI Subsystem
+// Host (This is very ROOT of the PCI Bus Driver Data).
+//
+// Notes: PCI_HOST_INFO
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+PCI_HOST_INFO *gPciHost=NULL;
+
+//----------------------------------------------------------------------------------
+//Bot script save protocol interface
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL *gBootScriptSave=NULL;
+
+//----------------------------------------------------------------------------------
+#if CSM_SUPPORT
+EFI_LEGACY_BIOS_EXT_PROTOCOL *gLegacyBiosExt=NULL;
+#endif
+
+//----------------------------------------------------------------------------------
+#if S3_VIDEO_REPOST_SUPPORT == 1
+EFI_EVENT gVgaS3Event=NULL;
+#endif
+
+//----------------------------------------------------------------------------------
+//Initial Global Variable to store RootBridge info
+UINT16 gCpuCaheLineSize=0x10;
+UINT8 gPciCaheLineSize=0;
+
+//----------------------------------------------------------------------------------
+//To Avoid Enumerating AmiDebug Port Usb Device
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+AMI_DEBUGPORT_INFORMATION_HOB *gDbgPortHob=NULL;
+DEBUG_PORT_INFO gDbgPortInfo={0,0,0,0,0,0,0,0};
+#endif
+
+//==================================================================================
+//Externals produced by VeB used by Pci Bus Driver
+//==================================================================================
+//Legacy IRQ routing table delivered from oempir.inc and PCIBoard.ASM
+//IOAPIC IRQ routing table delivered from mppciirq.inc and PCIBoard.ASM
+//PCI Buses Xlate Table
+//Instead we have now AMI_BOARD_INFO_PROTOCOL
+AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfo=NULL;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciBusDriverBinding
+//
+// Description: Extended PCI Bus Protocol instance for PciBus Driver
+//
+// Notes: AMI_PCI_EXT_PROTOCOL
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+AMI_PCI_EXT_PROTOCOL gAmiExtPciBusProtocol = {
+ PciExtIsPciExpresss,
+ PciExtIsPciX,
+ PciExtIsPciBrg,
+ PciExtIsCrdBrg,
+ PciExtIsDevice,
+ PciExtClassCodes,
+ PciExtPicIrqRout,
+ PciExtApicIrqRout,
+ NULL
+};
+
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciBusDriverBinding
+//
+// Description: Driver binding protocol instance for PciBus Driver
+//
+// Notes: EFI_DRIVER_BINDING_PROTOCOL
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
+ PciBusSupported, //Supported
+ PciBusStart, //PciBusDrvStart,
+ PciBusStop, //PciBusDrvStop,
+ ((PCI_BUS_MAJOR_VER<<16)|(PCI_BUS_MINOR_VER<<8)|(PCI_BUS_REVISION)), //Version
+ NULL, //Image Handle
+ NULL //DriverBindingHandle
+};
+
+#ifdef EFI_DEBUG
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+static EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+//---------------------------------------------------------------------------
+//Driver Name Interface of the PCI Bus Driver
+//---------------------------------------------------------------------------
+static UINT16 *gDriverName=L"AMI PCI Bus Driver";
+
+
+//---------------------------------------------------------------------------
+// Function Definitions
+//---------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ComponentNameGetControllerName()
+//
+// Description: This function is the one of interface functions of the
+// OPTIONAL, EFI_COMPONENT_NAME_PROTOCOL. Suppose to retun Controller
+// Name String. Currently returning EFI_UNSUPPORTED.
+//
+// Input:
+// EFI_COMPONENT_NAME_PROTOCOL
+// *This Pointer to EFI_COMPONENT_NAME_PROTOCOL.
+// EFI_HANDLE ControllerHandle EFI_HANDLE of the device which to return.
+// EFI_HANDLE ChildHandle OPTIONAL, an EFI_HANDLE of child device.
+// CHAR8 *Language Pointer to 3 char Language name.
+// CHAR16 **ControllerName Pointer to the data buffer for Name Sring.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When feature not supported by the Driver.
+//
+// Reference: EFI_COMPONENT_NAME2_PROTOCOL
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ComponentNameGetDriverName()
+//
+// Description: This function is the one of interface functions of the OPTIONAL
+// EFI_COMPONENT_NAME_PROTOCOL. Retuning Driver Name String of the PCI BUS Driver.
+//
+// Input:
+// EFI_COMPONENT_NAME_PROTOCOL
+// *This Pointer to EFI_COMPONENT_NAME_PROTOCOL.
+// CHAR8 *Language Pointer to 3 char Language name.
+// CHAR16 **ControllerName Pointer to the data buffer for Name Sring.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When feature not supported by the Driver.
+//
+// Reference: EFI_COMPONENT_NAME_PROTOCOL
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS ComponentNameGetDriverName(IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName)
+{
+ //Supports only English
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gComponentName
+//
+// Description: Declaration of the EFI_COMPONENT_NAME_PROTOCOL
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------------
+// ComponentNameGetDriverName, F_PTR DriverName function pointer.
+// ComponentNameGetControllerName, F_PTR ControllerName function pointer.
+// "eng" CHAR8 Language list Buffer.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName = {
+ ComponentNameGetDriverName,
+ ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+#endif
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//PCI BUS Driver Entry Point
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciBusEntryPoint()
+//
+// Description: This function is the entry point for PCI BUS Driver.
+// Since PCI BUS Driver follows EFI 1.1 driver model in it's entry point
+// it will initialize some global data and install
+// EFI_DRIVER_BINDING_PROTOCOL.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When something required is not found!
+// EFI_DEVICE_ERROR When the device is not responding!
+//
+// Notes:
+// Entry Points are used to locate or install protocol interfaces and
+// notification events.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciBusEntryPoint(IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ static EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+ static EFI_GUID DbgPortHobGuid = AMI_DEBUGPORT_HOB_GUID;
+#endif
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ CPUINFO_HOB *CpuInfoHob;
+ EFI_STATUS Status;
+//--------------------------------------------------------------------
+
+ //Init some Global Data
+ InitAmiLib(ImageHandle,SystemTable);
+ gPciBusDriverBinding.DriverBindingHandle=NULL;
+ gPciBusDriverBinding.ImageHandle=ImageHandle;
+
+ //Get CPU Cache Line Size
+ CpuInfoHob=(CPUINFO_HOB*)GetEfiConfigurationTable(pST,&HobListGuid);
+ if(CpuInfoHob==NULL) Status=EFI_UNSUPPORTED;
+ else Status=FindNextHobByGuid(&CpuInfoHobGuid,(VOID**)&CpuInfoHob);
+
+ if(!EFI_ERROR(Status)){
+ gCpuCaheLineSize=CpuInfoHob->CacheLineSize; //in bytes
+ gPciCaheLineSize=(UINT8)gCpuCaheLineSize/4; //in DWORDs
+ PCI_TRACE((TRACE_PCI,"PciBus: Find CpuInfo HOB! gCpuCaheLineSize=%X; gPciCaheLineSize=%X;\n", gCpuCaheLineSize, gPciCaheLineSize));
+ } else {
+ PCI_TRACE((TRACE_PCI,"PciBus: Unable to find CpuInfo HOB! Setting default CacheLineSize -> %X\n", gCpuCaheLineSize));
+ }
+
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+//Get Ami Debug Port Settings
+ gDbgPortHob=(AMI_DEBUGPORT_INFORMATION_HOB*)GetEfiConfigurationTable(pST,&HobListGuid);
+ if(gDbgPortHob) Status=FindNextHobByGuid(&DbgPortHobGuid,(VOID**)&gDbgPortHob);
+ if(EFI_ERROR(Status)) gDbgPortHob=NULL;
+ else {
+ Status=gDbgPortHob->GetDebugPortProperties(gDbgPortHob, &gDbgPortInfo);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ //Install Multiple Prot Drv. Binding and Comp. Name
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gPciBusDriverBinding.DriverBindingHandle,
+ &gDriverBindingProtocolGuid,&gPciBusDriverBinding,
+#ifdef EFI_DEBUG
+ &gEfiComponentName2ProtocolGuid,&gComponentName,
+#endif
+ NULL);
+ //Here we can set up notification events if needed
+
+
+ //------------------------------------
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFunc0OfMfDev()
+//
+// Description: Checks if PCI_DEV_INFO data passed belongs to Function 0 of
+// Multy-Functional device.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: BOOLEAN
+// TRUE Device is Function 0 of Mulifunctional device.
+// FALSE Device is not Function 0 of Mulifunctional device.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsFunc0OfMfDev(PCI_DEV_INFO *Device ){
+ //If (Func0==NULL && FuncCount==0) function is a single function device, following fields are not used and reserved;
+ //If (Func0!=NULL && FuncCount==0) function is one of the Func1..Func7 of multyfunc device Func0 points on DevFunc0;
+ //If (Func0!=NULL && (FuncCount!=0 || FuncInitCnt!=0)) function is Func0 of multyfunc device DevFunc holds pointers at all other Func1..7 found
+ //If (Func0==NULL && FuncCount!=0) Illehgal combination - reserved!
+ if((Device->Func0!=NULL) && ((Device->FuncInitCnt!=0)||(Device->FuncCount!=0))) return TRUE;
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFunc0()
+//
+// Description: Checks if PCI_DEV_INFO is Function 0 of PCI device.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: BOOLEAN
+// TRUE Device is Function 0 of Mulifunctional device.
+// FALSE Device is not Function 0 of Mulifunctional device.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsFunc0(PCI_DEV_INFO *Device ){
+ //If (Func0==NULL && FuncCount==0) function is a single function device, following fields are not used and reserved;
+ //If (Func0!=NULL && FuncCount==0) function is one of the Func1..Func7 of multyfunc device Func0 points on DevFunc0;
+ //If (Func0!=NULL && (FuncCount!=0 || FuncInitCnt!=0)) function is Func0 of multyfunc device DevFunc holds pointers at all other Func1..7 found
+ //If (Func0==NULL && FuncCount!=0) Illehgal combination - reserved!
+ if(IsFunc0OfMfDev(Device)) return TRUE;
+ if((Device->Func0==NULL) && (Device->FuncInitCnt==0) && (Device->FuncCount==0)) return TRUE;
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpyItemLst()
+//
+// Description: Creates a copy of T_ITEM_LST structure.
+//
+// Input:
+// T_ITEM_LIST *Lst Pointer to the structure to copy.
+// T_ITEM_LIST **NewLstPtr Double Pointer to the copied data (Memory allocation is done by this function).
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpyItemLst(T_ITEM_LIST *Lst, T_ITEM_LIST **NewLstPtr)
+{
+ T_ITEM_LIST *NewLst;
+//--------------------------
+ if(*NewLstPtr == NULL) *NewLstPtr = MallocZ(sizeof(T_ITEM_LIST));
+
+ if (*NewLstPtr==NULL) return EFI_OUT_OF_RESOURCES;
+
+ NewLst = *NewLstPtr;
+ NewLst->InitialCount = Lst->InitialCount;
+ if (Lst->InitialCount == 0) return EFI_SUCCESS;
+
+ NewLst->Items = MallocZ( Lst->InitialCount * sizeof(VOID*) );
+ if (!NewLst->Items) return EFI_OUT_OF_RESOURCES;
+
+ pBS->CopyMem((VOID*)NewLst->Items,(VOID*)Lst->Items,sizeof(VOID*)*Lst->ItemCount);
+
+ NewLst->ItemCount = Lst->ItemCount;
+
+ return EFI_SUCCESS;
+}
+
+
+#if HOTPLUG_SUPPORT
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//Following function to initialize PCI Root Hotplug Controller
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckRootHotplug()
+//
+// Description: This function will update pointer to PCI_RHPC_INFO of
+// Bridge Type device which creates a hot plug bus. Also if "Device"
+// creates the 'home bus' for Root HPC it will initialize Root HPC and
+// record the HPC state;
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckRootHotplug(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_SUCCESS;
+ EFI_DEVICE_PATH_PROTOCOL *dp=NULL;
+ PCI_HPC_INFO *rhpc;
+ UINTN i;
+//---------------
+ if(Device->Type==tPci2PciBrg || Device->Type==tPci2CrdBrg || Device->Type==tPciRootBrg){
+ //we have identify and Init all the Root Hpc and HPB
+ if(Device->HostData->InitRhpcCount==Device->HostData->RhpcCount) return EFI_SUCCESS;
+ PROGRESS_CODE(DXE_PCI_BUS_HPC_INIT);
+ //here we must check if 2 things:
+ // 1.If "Device" Device Path mutches with one of Root Hpc Device pathes
+ // 2.If "Device" Device Path mutches with one of Root Hpb Device pathes
+ for(i=0; i<Device->HostData->RhpcCount; i++){
+ rhpc=Device->HostData->RhpcList[i];
+ //if this controller already has been initialized - keep going
+ if(rhpc->Initialized && rhpc->BusFound) continue;
+
+
+ //check if it is a secondary interface of the bridge where RHPC is sitting
+ if(!rhpc->BusFound){
+ if(!DPCmp(Device->DevicePath, rhpc->HpcLocation->HpbDevicePath)){
+ rhpc->HpbBridge=Device;
+ rhpc->BusFound=TRUE;
+ Device->HotPlug=rhpc;
+ PCI_TRACE((TRACE_PCI,"PciBus: Found HP Bus Bridge @ B%X|D%X|F%X \n\n", Device->Address.Addr.Bus,Device->Address.Addr.Device, Device->Address.Addr.Function));
+ }
+ }
+
+ if(!rhpc->Initialized){
+ //We will cut the last node of the HPC device path
+ //resulting Device Path will correspond to the ParentBridge.DevicePath of the HPC
+ dp=DPCut(rhpc->HpcLocation->HpcDevicePath);
+ //if the HPC sits behind this bridge get the secondary I/F bus number
+ if(!DPCmp(Device->DevicePath,dp)){
+ EFI_DEVICE_PATH_PROTOCOL *tdp;
+ //-----------------------------------
+ rhpc->HpcPciAddr.Addr.Bus=mMaxBusFound;
+ tdp=DPGetLastNode(rhpc->HpcLocation->HpcDevicePath);
+
+ rhpc->HpcPciAddr.Addr.Device=((PCI_DEVICE_PATH*)tdp)->Device;
+ rhpc->HpcPciAddr.Addr.Function=((PCI_DEVICE_PATH*)tdp)->Function;
+
+ //we will not set up an event to signal when HPC initialization is ready
+ //that will give us a possibility to enumerate PCI BUS in one pass
+ Status=Device->HostData->HpInitProt->InitializeRootHpc(
+ Device->HostData->HpInitProt, rhpc->HpcLocation->HpcDevicePath,
+ rhpc->HpcPciAddr.ADDR, NULL, &rhpc->HpcState);
+
+ ASSERT_EFI_ERROR(Status);
+ rhpc->Owner=Device;
+ rhpc->Initialized=TRUE;
+ PCI_TRACE((TRACE_PCI,"PciBus: Found RHPC @ B%X|D%X|F%X \n", Device->Address.Addr.Bus,Device->Address.Addr.Device, Device->Address.Addr.Function));
+ }
+ }
+
+ //if we come here we did some step of the initialization process
+ //let's check if this controller has been completly initialized.
+ //if so we did our job. there are no reasons to stay in this loop any longer
+ if(rhpc->Initialized && rhpc->BusFound) {
+ Device->HostData->InitRhpcCount++;
+ break;
+ }
+
+ }//for
+ }
+ if(dp)pBS->FreePool(dp);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsHpb()
+//
+// Description: This function will check if "Device" passed is the Bridge
+// Type Device with hotplug support.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: BOOLEAN
+// TRUE If "Device" is a Bridge with HPC on it.
+// FALSE Otherwice.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsHpb(PCI_DEV_INFO *Device){
+
+ //check if it is the right type of device to have Hotplug capabilities
+ if(!((Device->Type==tPci2PciBrg)||(Device->Type==tPci2CrdBrg)||(Device->Type==tPciRootBrg))) return FALSE;
+
+ //Check if it has Root Hpc or PciExpress capabilities
+ if(!Device->HotPlug && !Device->PciExpress) return FALSE;
+
+ //If Device is PciExpress, check if SLOT CAPABILITIES Register supports Hotplug
+ if(Device->PciExpress && (!Device->PciExpress->SlotCap.HpCapable))return FALSE;
+
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHpbResPadding()
+//
+// Description: This function will get and apply resource padding
+// requirements for the PCI to PCI Bridge or Card Bus Bridge, if this
+// Bridge is supports hot plug.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetHpbResPadding(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=0;
+//-----------------------------
+ if(IsHpb(Device)){
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Device+1);
+ ASLR_QWORD_ASD *cnf, *res;
+ PCI_BAR *bar;
+ //----------------------------
+ Status=Device->HostData->HpInitProt->GetResourcePadding(Device->HostData->HpInitProt,
+ Device->HotPlug->HpcLocation->HpcDevicePath, Device->HotPlug->HpcPciAddr.ADDR,
+ &Device->HotPlug->HpcState,&cnf,&ext->PaddAttr);
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ if(ext->PaddAttr==EfiPaddingPciRootBridge){
+ pBS->FreePool(cnf);
+ return Status;
+ }
+
+ //Check if we got a valid descriptors in cfg buffer
+ if(!ValidateDescriptorBlock(cnf, tResAll, FALSE))return EFI_INVALID_PARAMETER;
+
+ res=cnf;
+ while(res->Hdr.HDR!=ASLV_END_TAG_HDR) {
+ bar=NULL;
+ switch(res->Type){
+ case ASLRV_SPC_TYPE_BUS :
+ bar=&ext->Pad[rtBus];
+ break;
+ case ASLRV_SPC_TYPE_IO :
+ bar=&ext->Pad[rtIo16];
+ bar->Type=tBarIo16;
+ if(res->_GRA==32){
+ bar=&ext->Pad[rtIo32];
+ bar->Type=tBarIo32;
+ }
+ break;
+ case ASLRV_SPC_TYPE_MEM :
+ if(res->_GRA==32){
+ if(res->TFlags.MEM_FLAGS._MEM==ASLRV_MEM_CEPF) {
+ bar=&ext->Pad[rtMmio32p];
+ bar->Type=tBarMmio32pf;
+ } else {
+ bar=&ext->Pad[rtMmio32];
+ bar->Type=tBarMmio32;
+ }
+ } else {
+ if(res->_GRA==64){
+ if(res->TFlags.MEM_FLAGS._MEM==ASLRV_MEM_CEPF){
+ bar=&ext->Pad[rtMmio64p];
+ bar->Type=tBarMmio64pf;
+ } else {
+ bar=&ext->Pad[rtMmio64];
+ bar->Type=tBarMmio64;
+ }
+ } else return EFI_INVALID_PARAMETER; //no other options alloud
+ }
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ } //switch
+
+ bar->Length=res->_LEN;
+ bar->Gran=res->_MAX;
+ res++;
+ } //while
+ pBS->FreePool(cnf);
+ }
+ return Status;
+}
+
+//==============================================================================
+#endif
+
+//==============================================================================
+// Device Handle Helper Functions
+//==============================================================================
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MakePciDevicePath()
+//
+// Description: This function will take Parent DevPath and extand it with
+// Current ""Dev", Device Path and update pointer of the "Dev->DevPath"
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MakePciDevicePath(PCI_DEV_INFO *Dev)
+{
+ static PCI_DEVICE_PATH pcidp;
+//-------------------------------------------
+ //we have a wonderful Lib function DPAddNode - use it!
+ pcidp.Header.SubType=HW_PCI_DP;
+ pcidp.Header.Type=HARDWARE_DEVICE_PATH;
+ SET_NODE_LENGTH(&pcidp.Header,HW_PCI_DEVICE_PATH_LENGTH);
+
+ pcidp.Function=Dev->Address.Addr.Function;
+ pcidp.Device=Dev->Address.Addr.Device;
+
+ Dev->DevicePath=DPAddNode(Dev->ParentBrg->DevicePath, &pcidp.Header);
+ if(Dev->DevicePath)return EFI_SUCCESS;
+ else return EFI_OUT_OF_RESOURCES;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindRbHandle()
+//
+// Description: This function will finds Root Bridge Device Handle for
+// the "Device".
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_HANDLE
+// !=NULL When everything is going on fine!
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_HANDLE FindRbHandle(PCI_DEV_INFO *Device){
+ EFI_HANDLE rbh=NULL;
+ PCI_DEV_INFO *dev=Device;
+//---------------------
+ while(dev->Type!=tPciRootBrg)dev=dev->ParentBrg;
+ rbh=dev->Handle;
+ return rbh;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindPciDeviceByHandleBrg()
+//
+// Description: This function Searches PCI Bridge Subsystem Database to find
+// device which have passed "Handle"
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Bridge Device Private Data structure.
+// EFI_HANDLE Handle Device Handle to search for.
+//
+// Output: PCI_DEV_INFO
+// !=NULL When everything is going on fine!
+// ==NULL Not Found.
+//
+// Notes: This is a subordinate function of FindPciDeviceByHandle()
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PCI_DEV_INFO *FindPciDeviceByHandleBrg(PCI_BRG_INFO *Brg, EFI_HANDLE Handle)
+{
+ PCI_DEV_INFO *dev, *res=NULL;
+ INTN i;
+//--------------------------------------------------------------------
+ if(Brg->Common.Handle==Handle) return &Brg->Common;
+
+ for(i=0; i<(INTN)Brg->Bridge.ChildCount; i++){
+ dev=Brg->Bridge.ChildList[i];
+ res=NULL;
+ if(dev->Handle==Handle) {
+ res=dev;
+ break;
+ }
+
+ if(dev->Type==tPci2PciBrg) res=FindPciDeviceByHandleBrg((PCI_BRG_INFO*)dev,Handle);
+
+ if(res) break;
+ }
+ return res;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindPciDeviceByHandle()
+//
+// Description: This function finds Pci Device by "Handle" passed
+//
+// Input:
+// EFI_HANDLE Handle PCI Device Handle.
+//
+// Output: PCI_DEV_INFO
+// !=NULL When everything is going on fine!
+// ==NULL Not Found.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PCI_DEV_INFO *FindPciDeviceByHandle(EFI_HANDLE Handle)
+{
+ PCI_BRG_INFO *brg;
+ UINTN i,j;
+ PCI_HOST_INFO *lhst;
+ PCI_DEV_INFO *res;
+//--------------------------------------------------------------------
+ for(j=0; j<gHostCnt; j++){
+ lhst=&gPciHost[j];
+ for(i=0; i<lhst->RbCount; i++){
+ brg=(PCI_BRG_INFO*)lhst->RootBridges[i];
+ res=FindPciDeviceByHandleBrg(brg, Handle);
+ if(res) return res;
+ }
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DoPrepController()
+//
+// Description: This function will follow the rules of calling seqence of
+// Platform Preprocess Controller it will call:
+// 1.Platform PreprocessController with ChipsetEntery
+// 2.Host Brg Preprocess Controller
+// 3.Platform PreprocessController with ChipsetExit
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DoPrepController(PCI_DEV_INFO* Device)
+{
+ EFI_STATUS Status=0;
+ EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE ph;
+ EFI_HANDLE rbh=FindRbHandle(Device);
+//-----------
+ if(Device->Type==tPci2PciBrg) ph=EfiPciBeforeChildBusEnumeration;
+ else ph=EfiPciBeforeResourceCollection;
+
+ //If System has PciPlatform protocol installed
+ if(Device->HostData->PlatformProt){
+ Status=Device->HostData->PlatformProt->PlatformPrepController(
+ Device->HostData->PlatformProt, Device->HostData->HostHandle,
+ rbh,Device->Address.Addr, ph, ChipsetEntry);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ Status=Device->HostData->ResAllocProt->PreprocessController(
+ Device->HostData->ResAllocProt,rbh,Device->Address.Addr, ph);
+ ASSERT_EFI_ERROR(Status);
+
+ if(Device->HostData->PlatformProt){
+ Status=Device->HostData->PlatformProt->PlatformPrepController(
+ Device->HostData->PlatformProt, Device->HostData->HostHandle,
+ rbh, Device->Address.Addr, ph, ChipsetExit);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DoPciNotify()
+//
+// Description: This function will follow the rules of calling seqence of
+// Platform Notify it will call:
+// 1.Platform NotifyPhase with ChipsetEntery
+// 2.Host Brg NotifyPhase
+// 3.Platform NotifyPhase with ChipsetExit
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DoPciNotify(PCI_HOST_INFO *Host, EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase)
+{
+ EFI_STATUS Status=0;
+//-----------
+ if(Host->PlatformProt){
+ Status=Host->PlatformProt->PhaseNotify(Host->PlatformProt,Host->HostHandle,Phase,ChipsetEntry);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ Status=Host->ResAllocProt->NotifyPhase(Host->ResAllocProt,Phase);
+ ASSERT_EFI_ERROR(Status);
+
+ if(Host->PlatformProt){
+ Status=Host->PlatformProt->PhaseNotify(Host->PlatformProt,Host->HostHandle,Phase,ChipsetExit);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciCfg8()
+//
+// Description: Will do PCI Configuration Space Access 8 bit width
+//
+// Input:
+// ROOT_BRIDGE_IO_PROTOCOL *RbIo Pointer to PciRootBridgeIO Protocol.
+// PCI_CFG_ADDR addr PCI_CFG_ADDR filled by caller
+// BOOLEAN wr TRUE = Write FALSE = Read
+// UINT8 *buff Pointer Data Buffer.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Referals:PCI_CFG_ADDR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciCfg8(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RbIo, PCI_CFG_ADDR addr, BOOLEAN wr, UINT8 *buff){
+ if(wr)return RbIo->Pci.Write(RbIo, EfiPciWidthUint8, addr.ADDR, 1, (VOID*)buff);
+ else return RbIo->Pci.Read(RbIo, EfiPciWidthUint8, addr.ADDR, 1, (VOID*)buff);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciCfg16()
+//
+// Description: Will do PCI Configuration Space Access 16 bit width
+//
+// Input:
+// ROOT_BRIDGE_IO_PROTOCOL *RbIo Pointer to PciRootBridgeIO Protocol.
+// PCI_CFG_ADDR addr PCI_CFG_ADDR filled by caller
+// BOOLEAN wr TRUE = Write FALSE = Read
+// UINT16 *buff Pointer Data Buffer.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Referals:PCI_CFG_ADDR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciCfg16(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RbIo, PCI_CFG_ADDR addr, BOOLEAN wr, UINT16 *buff){
+ EFI_STATUS Status;
+//------------
+ if(wr)Status=RbIo->Pci.Write(RbIo, EfiPciWidthUint16, addr.ADDR, 1, (VOID*)buff);
+ else Status=RbIo->Pci.Read(RbIo, EfiPciWidthUint16, addr.ADDR, 1, (VOID*)buff);
+ //it might be a Width issue on Pci Root bridge level
+ if(Status==EFI_INVALID_PARAMETER) {
+ UINT8 *b=(UINT8*)buff;
+ //--------------------
+ Status=PciCfg8(RbIo, addr, wr, b);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Check if Extended register used then Addr.Register is ignored.
+ if( addr.Addr.ExtendedRegister != 0) addr.Addr.ExtendedRegister += 1;
+ else addr.Addr.Register += 1;
+
+ b++;
+ Status=PciCfg8(RbIo, addr, wr, b);
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciCfg32()
+//
+// Description: Will do PCI Configuration Space Access 32 bit width
+//
+// Input:
+// ROOT_BRIDGE_IO_PROTOCOL *RbIo Pointer to PciRootBridgeIO Protocol.
+// PCI_CFG_ADDR addr PCI_CFG_ADDR filled by caller
+// BOOLEAN wr TRUE = Write FALSE = Read
+// UINT32 *buff Pointer Data Buffer.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Referals:PCI_CFG_ADDR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciCfg32(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RbIo, PCI_CFG_ADDR addr, BOOLEAN wr, UINT32 *buff){
+ EFI_STATUS Status;
+//------------
+ if(wr)Status=RbIo->Pci.Write(RbIo, EfiPciWidthUint32, addr.ADDR, 1, (VOID*)buff);
+ else Status=RbIo->Pci.Read(RbIo, EfiPciWidthUint32, addr.ADDR, 1, (VOID*)buff);
+ //it might be a Width issue on Pci Root bridge level
+ if(Status==EFI_INVALID_PARAMETER) {
+ UINT16 *b=(UINT16*)buff;
+ //--------------------
+ Status=PciCfg16(RbIo, addr, wr, b);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Check if Extended register used then Addr.Register is ignored.
+ if( addr.Addr.ExtendedRegister != 0) addr.Addr.ExtendedRegister += 2;
+ else addr.Addr.Register += 2;
+
+ b++;
+ Status=PciCfg16(RbIo, addr, wr, b);
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciCfg64()
+//
+// Description: Will do PCI Configuration Space Access 64 bit width
+//
+// Input:
+// ROOT_BRIDGE_IO_PROTOCOL *RbIo Pointer to PciRootBridgeIO Protocol.
+// PCI_CFG_ADDR addr PCI_CFG_ADDR filled by caller
+// BOOLEAN wr TRUE = Write FALSE = Read
+// UINT64 *buff Pointer Data Buffer.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Referals:PCI_CFG_ADDR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciCfg64(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *RbIo, PCI_CFG_ADDR addr, BOOLEAN wr, UINT64 *buff){
+ EFI_STATUS Status;
+//------------
+ if(wr)Status=RbIo->Pci.Write(RbIo, EfiPciWidthUint64, addr.ADDR, 1, (VOID*)buff);
+ else Status=RbIo->Pci.Read(RbIo, EfiPciWidthUint64, addr.ADDR, 1, (VOID*)buff);
+ //it might be a Width issue on Pci Root bridge level
+ if((Status==EFI_INVALID_PARAMETER) && (buff!=NULL)) {
+ UINT32 *b=(UINT32*)buff;
+ //--------------------
+ Status=PciCfg32(RbIo, addr, wr, b);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Check if Extended register used then Addr.Register is ignored.
+ if( addr.Addr.ExtendedRegister != 0) addr.Addr.ExtendedRegister += 4;
+ else addr.Addr.Register += 4;
+
+ b++;
+ Status=PciCfg32(RbIo, addr, wr, b);
+ }
+ return Status;
+}
+
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+// PCI IO Protocol Functions Implementation Protocol
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//==================================================================================
+// PciIoProtocol Supporting Functions
+//==================================================================================
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BarCheckType()
+//
+// Description:
+// This helper function will check if Base Address Register(BAR) selected
+// for PciIo operation is of valid type and has been initialized;
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PciDevice Info structure.
+// UINT8 BarIndex Index of the BAR within PCI device
+// PCI_BAR_TYPE BarType Indicating what to check - IO or Memory.
+//
+// Output: BOOLEAN
+// TRUE BAR supports selected transaction.
+// FALSE BAR does not support selected transaction.
+//
+// Referals: PCI_DEV_INFO; PCI_BAR_TYPE
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN BarCheckType(PCI_DEV_INFO *Dev, UINT8 BarIndex, PCI_BAR_TYPE BarType)
+{
+ PCI_BAR *bar=&Dev->Bar[BarIndex];
+//-------------------------------------
+ switch(BarType){
+ case tBarMem:
+ if (bar->Type != tBarMmio32 &&
+ bar->Type != tBarMmio32pf &&
+ bar->Type != tBarMmio64 &&
+ bar->Type != tBarMmio64pf ) return FALSE;
+ break;
+
+ case tBarIo:
+ if (bar->Type != tBarIo32 && bar->Type != tBarIo16)
+ return FALSE;
+ break;
+ default: return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoCheckBar()
+//
+// Description: This helper function will check if parameters passed to the
+// PCI IO Protocol to read or write a PCI resources are correct.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PciDevice Info structure.
+// UINT8 BarInd Index of the BAR within PCI device.
+// PCI_BAR_TYPE BarType Indicating what to check - IO or Memory.
+// EFI_PCI_IO_PROTOCOL_WIDTH Width Width of transaction.
+// UINTN Count Number of bytes been transfered.
+// UINT64 *Offset Offset within BAR address space to start from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BAR_TYPE;EFI_PCI_IO_PROTOCOL_WIDTH
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoCheckBar(PCI_DEV_INFO *Dev, UINT8 BarInd, PCI_BAR_TYPE Type,
+ EFI_PCI_IO_PROTOCOL_WIDTH Width, UINTN Count, UINT64 *Offset)
+{
+ if ( Width<0 || Width>=EfiPciIoWidthMaximum ) return EFI_INVALID_PARAMETER;
+
+ if (BarInd==0xFF) return EFI_SUCCESS;
+
+ if (BarInd>=MAX_PCI_BAR) return EFI_INVALID_PARAMETER;
+
+ if (!BarCheckType(Dev,BarInd,Type))return EFI_INVALID_PARAMETER;
+
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
+ if (Width >= EfiPciWidthFifoUint8 && Width <= EfiPciWidthFifoUint64) Count = 1;
+ Width &= 0x03;
+
+ if((*Offset+Count*((UINTN)1<<Width))-1 >= Dev->Bar[BarInd].Length) return EFI_INVALID_PARAMETER;
+
+ *Offset = *Offset+(UINTN)Dev->Bar[BarInd].Base;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoCheckConfig()
+//
+// Description: This helper function will check if parameters passed to the
+// PCI IO Protocol to made a PCI Config Space Access are correct
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PciDevice Info structure.
+// EFI_PCI_IO_PROTOCOL_WIDTH Width Width of transaction been performed.
+// UINTN Count Number of bytes been transfered.
+// UINT64 *Offset Offset to start from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BAR_TYPE; EFI_PCI_IO_PROTOCOL_WIDTH
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS PciIoCheckConfig(PCI_DEV_INFO *Dev, EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ UINTN Count, UINT64 *Offset)
+{
+ if(Width<0 || Width>= EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ // If Width is EfiPciIoWidthFillUintX then convert to EfiPciIoWidthUintX
+ Width &= 0x03;
+ if((*Offset + Count * ((UINTN)1 << Width)) - 1 > 0xFF) return EFI_UNSUPPORTED;
+
+ *Offset=PCI_ASSEMBLE_ADDR(Dev->Address.Addr.Bus,
+ Dev->Address.Addr.Device,Dev->Address.Addr.Function,*Offset);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetIdeDevMode()
+//
+// Description: This function will Change IDE Device Mode LEGACY/NATIVE
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+// BOOLEAN Primary Indicate Primary/Secondary controller
+// BOOLEAN Legacy Indicate Mode to programm
+// UINT8 *Override If not NULL value to programm in PI register
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When device does not support mode programming.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO;
+//
+// Notes:
+// This function does not check if SecIde/PriIde Property of the Dev->HostData
+// is tacken already caller must do that before call;
+// This function does not update SecIde/PriIde Property of the Dev->HostData
+// object. Caller must do that upon successfull return.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetIdeDevMode(PCI_DEV_INFO *Dev, BOOLEAN Primary, BOOLEAN Legacy, UINT8 *Override){
+
+ PCI_CFG_ADDR addr;
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINT8 newpi=0, oldpi=Dev->Class.ProgInterface, tmp=oldpi=Dev->Class.ProgInterface;
+ BOOLEAN canprog=FALSE, needprog=FALSE;
+//--------
+ if(Dev->Class.BaseClassCode!=PCI_CL_MASS_STOR && Dev->Class.SubClassCode!=PCI_CL_MASS_STOR_SCL_IDE)
+ return EFI_INVALID_PARAMETER;
+
+ addr.ADDR=Dev->Address.ADDR;
+ addr.Addr.Register=PCI_PI_OFFSET;
+
+
+ if(Override!=NULL){
+ Status=PciCfg8(Dev->RbIo,addr,TRUE,Override);
+ if(!EFI_ERROR(Status)) {
+ UINT8 b=0;
+ //----------------
+ //read back what we have write there
+ Status=PciCfg8(Dev->RbIo,addr,FALSE,&b);
+ if(b==(*Override))Dev->Class.ProgInterface=(*Override);
+ else Status=EFI_UNSUPPORTED;
+ PCI_TRACE((TRACE_PCI, "\nPciBus: SetIdeMode(Pri=N/A, Legacy=N/A, PciPI=0x%X) @ B%X|D%X|F%X = %r,\n",*Override,
+ Dev->Address.Addr.Bus,Dev->Address.Addr.Device,Dev->Address.Addr.Function, Status));
+ }
+ } else {
+ if(Primary){
+ canprog=(Dev->Class.ProgInterface & 0x02);
+ oldpi&=(~0x01);
+ tmp&=0x01;
+ if(!Legacy) newpi|=0x01;
+ } else {
+ canprog=(Dev->Class.ProgInterface & 0x08);
+ oldpi&=(~0x04);
+ tmp&=0x04;
+ if(!Legacy) newpi|=0x04;
+ }
+ needprog = (tmp ^ newpi);
+ if(needprog){
+ if(canprog){
+ newpi|=oldpi;
+ Status=PciCfg8(Dev->RbIo,addr,TRUE,&newpi);
+ if(!EFI_ERROR(Status)) Dev->Class.ProgInterface=newpi;
+ } else Status=EFI_UNSUPPORTED;
+ }
+ PCI_TRACE((TRACE_PCI, "\nPciBus: SetIdeMode(Pri=%d, Legacy=%d, PciPI=0x%X) @ B%X|D%X|F%X = %r,\n", Primary, Legacy,
+ newpi,Dev->Address.Addr.Bus,Dev->Address.Addr.Device,Dev->Address.Addr.Function, Status));
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InCurVgaChain()
+//
+// Description: Helper function to check if device referenced as "Dev" sits
+// within Current VGA device parents bridges.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PciDevice Info structure.
+//
+// Output: BOOLEAN
+// TRUE "Dev" in Current VGA device parents bridges.
+// FALSE "Dev" is not in Current VGA device parents bridges.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN InCurVgaChain(PCI_DEV_INFO *Dev)
+{
+ PCI_DEV_INFO *d=Dev->HostData->VgaDev;
+//------------------------------------
+ if(!d) return FALSE;
+ while (d->Type!=tPciRootBrg){
+ if(d==Dev) return TRUE;
+ d=d->ParentBrg;
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeviceAttributes()
+//
+// Description: Protocol Function Sets or resets PCI Device Arttributs.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PciDevice Info structure.
+// UINT64 Attributes Attributes bitmask which caller whants to change.
+// BOOLEAN Set Specifies weathere to set or reset given "Attributes".
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When some of the "Attributes" not supported by the "Dev".
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DeviceAttributes(PCI_DEV_INFO *Dev, UINT64 Attributes, BOOLEAN Set)
+{
+ EFI_STATUS Status=0;
+ UINT16 tmp=0;
+ PCI_CMD_REG cmd;
+ PCI_BRG_CNT_REG bc;
+ PCI_CFG_ADDR addr;
+ UINT64 newattr=0, capab=Dev->Capab; //| PCI_ALLOWED_ATTRIBUTES;
+//------------------------------
+
+ addr.ADDR=Dev->Address.ADDR;
+ bc.BRG_CNT_REG=0;
+ cmd.CMD_REG=0;
+
+ //Remove platform specific attributes...
+ //Attributes&=(~(PCI_ALLOWED_ATTRIBUTES));
+
+ //If Devices for special attributes has been selected already we can't set it for different device
+ if(Dev->HostData->VgaDev != NULL){
+ if(Dev != Dev->HostData->VgaDev){
+ if(!InCurVgaChain(Dev) ) capab&=(~PCI_VGA_ATTRIBUTES);
+ }
+ }
+
+ if((Dev->HostData->PriIde!=NULL)&& (Dev!=Dev->HostData->PriIde))
+ capab&=(~EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO);
+ if((Dev->HostData->SecIde!=NULL)&& (Dev!=Dev->HostData->SecIde))
+ capab&=(~EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO);
+
+ //If OEMs want to add some more filters...
+ Status=PciPortOemAttributes(Dev, &Attributes, capab, Set);
+
+ //if Attributes requested NOT SUPPORTED by the device...
+ if((capab & Attributes)!=Attributes) {
+ Status=EFI_UNSUPPORTED;
+ goto Exit;
+ }
+
+ //if requested Attributes already match Device current Attributes
+ if( (((Dev->Attrib & Attributes)==Attributes) && Set ) || (((Dev->Attrib & Attributes)==0) && (!Set)) )
+ {
+ Status=EFI_SUCCESS;
+ goto Exit;
+ }
+
+ //So far so good - apply attributes
+
+ //For IDE controller it is a special case
+ if( Attributes & (EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO)){
+ BOOLEAN Primary=(BOOLEAN)(Attributes & EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO);
+ //--------------
+ Status=SetIdeDevMode(Dev, Primary, Set, NULL);
+ if(EFI_ERROR(Status))goto Exit;
+
+ if(Set){
+ if(Primary) Dev->HostData->PriIde=Dev;
+ else Dev->HostData->SecIde=Dev;
+ } else {
+ if(Primary) Dev->HostData->PriIde=Dev;
+ else Dev->HostData->SecIde=Dev;
+ }
+ }
+
+ //the
+ if(Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO ||
+ Attributes & EFI_PCI_IO_ATTRIBUTE_ISA_IO) bc.IsaEnable=1;
+
+ if(Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY ||
+ Attributes & EFI_PCI_IO_ATTRIBUTE_VGA_IO){
+ DXE_SERVICES *dxe;
+ EFI_PHYSICAL_ADDRESS addr=0x3C0;
+ //-----------------------------
+ Status=LibGetDxeSvcTbl(&dxe);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ bc.VgaEnable=1;
+ if (gPciSetupData->VgaPallete) cmd.VgaPaletteSnoop=1;
+
+ if(Set) Status=dxe->AllocateIoSpace(EfiGcdAllocateAddress,
+ EfiGcdIoTypeIo,
+ 0,
+ 0x20,
+ &addr,
+ gPciBusDriverBinding.ImageHandle,
+ gPciBusDriverBinding.DriverBindingHandle);
+ else Status=dxe->FreeIoSpace(addr,0x20);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI, "\nPciBus: Fail to allocate/free IO 0x3C0 ~ 0x3DF; Set=%d; Status=%r,\n", Set, Status));
+ //If it was allocated - fine just keep going.
+ Status=EFI_SUCCESS;
+ }
+ }
+
+ if(Attributes & EFI_PCI_IO_ATTRIBUTE_IO) cmd.IoSpace=1;
+
+ if(Attributes & EFI_PCI_IO_ATTRIBUTE_MEMORY) cmd.MemSpace=1;
+
+ if(Attributes & EFI_PCI_IO_ATTRIBUTE_BUS_MASTER) cmd.BusMaster=1;
+
+ //Recoursevely Set attributes to all parents
+ //if Parent bridge is the RootBrg use it native function to set Attributes
+ //keep in mind that per UIEFI 2.1 Spec Bridges are suppose to be always open,
+ //so we will filter Device Enable attributes from setting/resetting them for bridges.
+ newattr=(Attributes & (~(EFI_PCI_IO_ATTRIBUTE_IO|EFI_PCI_IO_ATTRIBUTE_MEMORY|EFI_PCI_IO_ATTRIBUTE_BUS_MASTER|PCI_ALLOWED_ATTRIBUTES)));
+ if(Dev->ParentBrg->Type == tPciRootBrg )Status=Dev->RbIo->SetAttributes(Dev->RbIo,newattr,NULL,NULL);
+ else Status=DeviceAttributes(Dev->ParentBrg,newattr,Set);
+ if(EFI_ERROR(Status))goto Exit;
+
+ //bridge control register for P2P and P2C at the same place
+ if((Dev->Type==tPci2PciBrg || Dev->Type==tPci2CrdBrg) && bc.BRG_CNT_REG){
+ //update bridge control reg if we have to
+ addr.Addr.Register=PCI_BRIDGE_CNTL; //brg controll reg
+
+ //read what it has
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&tmp);
+ if(EFI_ERROR(Status)) goto Exit;
+
+ if(Set) bc.BRG_CNT_REG=bc.BRG_CNT_REG|tmp;
+ else bc.BRG_CNT_REG=tmp&(~bc.BRG_CNT_REG);
+
+ //write updated value
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&bc.BRG_CNT_REG);
+ if(EFI_ERROR(Status)) goto Exit;
+ }
+
+ if(cmd.CMD_REG){
+ //update PCI command reg if we have to
+ addr.Addr.Register=PCI_CMD; //command reg
+
+ //read what it has
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&tmp);
+ if(EFI_ERROR(Status)) goto Exit;
+
+ if(Set) cmd.CMD_REG=cmd.CMD_REG|tmp;
+ else cmd.CMD_REG=tmp&(~cmd.CMD_REG);
+
+ //write updated value
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&cmd.CMD_REG);
+ if(EFI_ERROR(Status)) goto Exit;
+ }
+ //Update Recorded Attributes
+ if(Set)Dev->Attrib|=Attributes;
+ else Dev->Attrib&=(~Attributes);
+
+Exit:
+ PCI_TRACE((TRACE_PCI, "\nPciBus: SetAttributes(%d) @ B%X|D%X|F%X Attr=0x%lX; Capab=0x%lX; Status=%r,\n", Set,
+ Dev->Address.Addr.Bus,Dev->Address.Addr.Device,Dev->Address.Addr.Function, Attributes, capab, Status));
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoPollMem()
+//
+// Description: Protocol Function Poll PCI Memmory
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoPollMem(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//----------------------------------------------------------------------
+
+ if (((UINT32)Width) > ((UINT32)EfiPciIoWidthUint64)) return EFI_INVALID_PARAMETER;
+
+ Status = PciIoCheckBar(dev, BarIndex, tBarMem, Width, 1, &Offset);
+ if(EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status=dev->RbIo->PollMem(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,Offset,
+ Mask,Value,Delay,Result);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoPollIo()
+//
+// Description: Protocol Function Poll PCI IO
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoPollIo (IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result )
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//----------------------------------
+ if (((UINT32)Width) > ((UINT32)EfiPciIoWidthUint64)) return EFI_INVALID_PARAMETER;
+
+ Status=PciIoCheckBar(dev, BarIndex, tBarIo, Width, 1, &Offset);
+ if(EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ if (Width > EfiPciIoWidthUint64) return EFI_INVALID_PARAMETER;
+
+ Status=dev->RbIo->PollIo(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Offset, Mask, Value, Delay, Result);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoMemRead()
+//
+// Description: Protocol Function Performs a PCI Memory Read Cycle
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoMemRead(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//---------------------------------------------
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ Status=PciIoCheckBar(dev, BarIndex, tBarMem, Width, Count, &Offset);
+ if(EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status=dev->RbIo->Mem.Read(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Offset, Count, Buffer);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoMemWrite()
+//
+// Description: Protocol Function Performs a PCI Memory Write Cycle
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoMemWrite(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//-------------------------------------------
+
+ if(Width<0 || Width>=EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ Status = PciIoCheckBar(dev, BarIndex, tBarMem, Width, Count, &Offset);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status=dev->RbIo->Mem.Write(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Offset, Count, Buffer);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoIoRead()
+//
+// Description: Protocol Function Performs a PCI I/O Read Cycle
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoIoRead(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//----------------------------------------------------
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ Status=PciIoCheckBar(dev, BarIndex, tBarIo, Width, Count, &Offset);
+ if (EFI_ERROR(Status))return EFI_UNSUPPORTED;
+
+ Status=dev->RbIo->Io.Read(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Offset, Count, Buffer);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoIoWrite()
+//
+// Description: Protocol Function Performs a PCI I/O Write Cycle
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoIoWrite(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 BarIndex,
+ IN UINT64 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//----------------------------------------------------
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ Status=PciIoCheckBar(dev, BarIndex, tBarIo, Width, Count, &Offset);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status=dev->RbIo->Io.Write(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Offset, Count, Buffer);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoConfigRead()
+//
+// Description: Protocol Function Performs a PCI Configuration Read Cycle
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoConfigRead(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+ UINT64 Address;
+//---------------------------------------------------
+ Address = Offset;
+ Status = PciIoCheckConfig(dev, Width, Count, &Address);
+ if(EFI_ERROR(Status))return Status;
+
+ Status=dev->RbIo->Pci.Read(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Address, Count, Buffer);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoConfigWrite()
+//
+// Description: Protocol Function Performs a PCI Configuration Write Cycle
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoConfigWrite(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT32 Offset,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+ UINT64 Address;
+//---------------------------------------------------
+ Address = Offset;
+ Status = PciIoCheckConfig(dev, Width, Count, &Address);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status=dev->RbIo->Pci.Write(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ Address, Count, Buffer);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoCopyMem()
+//
+// Description: Protocol Function Copyes PCI Memory
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoCopyMem(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
+ IN UINT8 DestBarIndex,
+ IN UINT64 DestOffset,
+ IN UINT8 SrcBarIndex,
+ IN UINT64 SrcOffset,
+ IN UINTN Count)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//---------------------------------------------------
+
+ if (Width < 0 || Width >= EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ if(Width == EfiPciIoWidthFifoUint8 ||
+ Width == EfiPciIoWidthFifoUint16 ||
+ Width == EfiPciIoWidthFifoUint32 ||
+ Width == EfiPciIoWidthFifoUint64 ||
+ Width == EfiPciIoWidthFillUint8 ||
+ Width == EfiPciIoWidthFillUint16 ||
+ Width == EfiPciIoWidthFillUint32 ||
+ Width == EfiPciIoWidthFillUint64) return EFI_INVALID_PARAMETER;
+
+ Status=PciIoCheckBar(dev, DestBarIndex, tBarMem, Width, Count, &DestOffset);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status=PciIoCheckBar(dev, SrcBarIndex, tBarMem, Width, Count, &SrcOffset);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status=dev->RbIo->CopyMem(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
+ DestOffset, SrcOffset, Count);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoMap()
+//
+// Description: Protocol Function Maps a memory region for DMA
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoMap(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//---------------------------------------------------
+
+ if(Operation<0 || Operation>=EfiPciIoOperationMaximum) return EFI_INVALID_PARAMETER;
+
+ if(HostAddress==NULL || NumberOfBytes==NULL || DeviceAddress==NULL || Mapping==NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if (dev->Attrib & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE)
+ Operation = Operation + EfiPciOperationBusMasterRead64;
+
+ Status=dev->RbIo->Map(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION)Operation,
+ HostAddress, NumberOfBytes, DeviceAddress, Mapping);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoUnmap()
+//
+// Description: Protocol Function Unmaps a memory region for DMA
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoUnmap(IN EFI_PCI_IO_PROTOCOL *This,
+ IN VOID *Mapping)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//---------------------------------------------------
+
+ Status=dev->RbIo->Unmap(dev->RbIo,Mapping);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoAllocateBuffer()
+//
+// Description: Protocol Function Allocates a common buffer for DMA
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoAllocateBuffer(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//---------------------------------------------------
+
+ if (Attributes & (~(EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE | EFI_PCI_ATTRIBUTE_MEMORY_CACHED)))
+ return EFI_UNSUPPORTED;
+
+ if (dev->Attrib & EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE)
+ Attributes|=EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+
+ Status=dev->RbIo->AllocateBuffer(dev->RbIo,Type,MemoryType,Pages,HostAddress,Attributes);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoFreeBuffer()
+//
+// Description: Protocol Function Frees a common buffer
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoFreeBuffer(IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//---------------------------------------------------
+
+ Status=dev->RbIo->FreeBuffer(dev->RbIo,Pages,HostAddress);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoFlush()
+//
+// Description: Protocol Function Flushes a DMA buffer
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoFlush (IN EFI_PCI_IO_PROTOCOL *This)
+{
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//--------------------------------------------
+ return dev->RbIo->Flush(dev->RbIo);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoGetLocation()
+//
+// Description: Protocol Function Proides Device Address on PCI BUS like
+// Bus#, Dev#, Fun# for the device who has PciIoProtocol == "This".
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoGetLocation(IN EFI_PCI_IO_PROTOCOL *This,
+ OUT UINTN *Segment,
+ OUT UINTN *Bus,
+ OUT UINTN *Device,
+ OUT UINTN *Function)
+{
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+//--------------------------------------------
+
+ if(Segment==NULL || Bus==NULL || Device==NULL || Function==NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *Segment = dev->RbIo->SegmentNumber;
+ *Bus = dev->Address.Addr.Bus;
+ *Device = dev->Address.Addr.Device;
+ *Function = dev->Address.Addr.Function;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoAttributes()
+//
+// Description: Protocol Function Provides Arttribute operation for the PCI device
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoAttributes(IN EFI_PCI_IO_PROTOCOL *This,
+ IN EFI_PCI_IO_PROTOCOL_ATTRIBUTE_OPERATION Operation,
+ IN UINT64 Attributes,
+ OUT UINT64 *Result OPTIONAL )
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+ BOOLEAN f=FALSE;
+ UINT64 capab=dev->Capab;
+//--------------------------------------------
+
+ switch (Operation) {
+ case EfiPciIoAttributeOperationGet:
+ case EfiPciIoAttributeOperationSupported:
+ if (Result == NULL) return EFI_INVALID_PARAMETER;
+ if(Operation==EfiPciIoAttributeOperationGet)*Result = dev->Attrib;
+ else {
+
+ if(dev->HostData->VgaDev != NULL){
+ if(dev != dev->HostData->VgaDev){
+ if(!InCurVgaChain(dev) ) capab&=(~PCI_VGA_ATTRIBUTES);
+ }
+ }
+ *Result=capab;
+ }
+ return EFI_SUCCESS;
+ break;
+ case EfiPciIoAttributeOperationSet:
+ case EfiPciIoAttributeOperationEnable:
+ //only one VGA legacy resources may be decoded
+ if(Attributes&PCI_VGA_ATTRIBUTES){ //special case for VGA attr
+ if(dev->HostData->VgaDev==NULL)f=TRUE;
+ }
+ //else if (dev!=dev->HostData->VgaDev) return EFI_UNSUPPORTED;
+ Status=DeviceAttributes(dev, Attributes,TRUE);
+ if((!EFI_ERROR(Status))&& f) dev->HostData->VgaDev=dev;
+ break;
+ case EfiPciIoAttributeOperationDisable:
+ if(Attributes&PCI_VGA_ATTRIBUTES) {//special case for VGA attr
+ if(dev->HostData->VgaDev==dev)f=TRUE;
+ }
+ Status=DeviceAttributes(dev, Attributes,FALSE);
+ if((!EFI_ERROR(Status))&& f ) dev->HostData->VgaDev=NULL; //clear default VGA Device ptr somebody reset it's status
+ break;
+ default : return EFI_INVALID_PARAMETER;
+ }//switch
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoGetBarAttributes()
+//
+// Description: Protocol Function Gets respective BAR Attributes
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoGetBarAttributes(IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT8 BarIndex,
+ OUT UINT64 *Supports, OPTIONAL
+ OUT VOID **Resources OPTIONAL )
+{
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+ ASLR_QWORD_ASD *resdsc;
+ ASLR_EndTag *enddsc;
+//--------------------------------------------
+
+ if(Supports==NULL && Resources == NULL) return EFI_INVALID_PARAMETER;
+ if(BarIndex>=MAX_PCI_BAR) return EFI_UNSUPPORTED;
+
+ if(Supports!=NULL) {
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//implement changing attributes for BAR using Cpu Protocol
+ *Supports = (dev->Capab & (BAR_ATTR));
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+ }
+ if(Resources != NULL) {
+ UINTN sz=sizeof(ASLR_EndTag);
+ //------------------------------------------------
+ if(dev->Bar[BarIndex].Type!=tBarUnused)sz+=sizeof(ASLR_QWORD_ASD);
+
+ resdsc=MallocZ(sz);
+ if(!resdsc) return EFI_OUT_OF_RESOURCES;
+
+
+ if(dev->Bar[BarIndex].Type!=tBarUnused){
+
+ enddsc=(ASLR_EndTag*)(resdsc+1);
+
+ //fill BAR descriptor
+ resdsc->Hdr.Name=ASLV_RT_QWORD_ASD;
+ resdsc->Hdr.Type=ASLV_LARGE_RES;
+ resdsc->Hdr.Length=sizeof(ASLR_QWORD_ASD)-sizeof(ASLRF_L_HDR);
+ resdsc->_MIN=dev->Bar[BarIndex].Base;
+ resdsc->_LEN=dev->Bar[BarIndex].Length;
+ resdsc->_MAX=resdsc->_MIN+resdsc->_LEN-1;
+
+ switch (dev->Bar[BarIndex].DiscoveredType) {
+ case tBarIo16:
+ case tBarIo32:
+ resdsc->Type=ASLRV_SPC_TYPE_IO; // Io
+ break;
+ case tBarMmio32:
+ resdsc->Type=ASLRV_SPC_TYPE_MEM; // Mem
+ resdsc->_GRA=32; // 32 bit
+ break;
+ case tBarMmio32pf:
+ resdsc->Type=ASLRV_SPC_TYPE_MEM; // Mem
+ resdsc->TFlags.TFLAGS=0x6; // prefechable
+ resdsc->_GRA=32; // 32 bit
+ break;
+ case tBarMmio64:
+ resdsc->Type=ASLRV_SPC_TYPE_MEM; // Mem
+ resdsc->_GRA=64; // 32 bit
+ break;
+ case tBarMmio64pf:
+ resdsc->Type=ASLRV_SPC_TYPE_MEM; // Mem
+ resdsc->TFlags.TFLAGS=0x6; // prefechable
+ resdsc->_GRA=64; // 32 bit
+ break;
+ }//switch
+ } else enddsc=(ASLR_EndTag*)(resdsc);
+ //fix End tag
+ enddsc->Hdr.Name=ASLV_SR_EndTag;
+ enddsc->Hdr.Type=ASLV_SMALL_RES;
+ enddsc->Hdr.Length=sizeof(ASLR_EndTag)-sizeof(ASLRF_S_HDR);
+ enddsc->Chsum=0;
+ *Resources = resdsc;
+ }//if(Resources!=NULL)
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciIoSetBarAttributes()
+//
+// Description: Protocol Function Sets respective BAR Attributes
+//
+// Notes: See EFI Specification for detail description
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoSetBarAttributes(IN EFI_PCI_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN UINT8 BarIndex,
+ IN OUT UINT64 *Offset,
+ IN OUT UINT64 *Length)
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
+ UINT64 offs, attr;
+//--------------------------------------------------
+
+ if(Offset==NULL || Length==NULL) return EFI_INVALID_PARAMETER;
+
+ if(dev->Bar[BarIndex].Type==tBarUnused) return EFI_UNSUPPORTED;
+
+ // This driver does not support setting the WRITE_COMBINE or the CACHED attributes.
+ // If Attributes is not 0, then return EFI_UNSUPPORTED.
+ attr = Attributes & (~BAR_ATTR);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+//implement changing attributes for bar trough Cpu Protocol
+ if (attr)return EFI_UNSUPPORTED;
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+
+ //Make sure the BAR range describd by BarIndex, Offset, and Length are valid for this PCI device.
+ offs = *Offset;
+ Status=PciIoCheckBar(dev, BarIndex, tBarMem, EfiPciIoWidthUint8, (UINT32)*Length, &offs);
+
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ return Status;
+}
+
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//============================================================================
+// Pci Io Protocol Interface
+//============================================================================
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciIoInstance
+//
+// Description: PCI IO Protocol Instance for Child Devices of the PciBus Driver.
+//
+// Notes: EFI_PCI_IO_PROTOCOL
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+static EFI_PCI_IO_PROTOCOL gPciIoInstance = {
+ PciIoPollMem,
+ PciIoPollIo,
+ {
+ PciIoMemRead,
+ PciIoMemWrite
+ },
+ {
+ PciIoIoRead,
+ PciIoIoWrite
+ },
+ {
+ PciIoConfigRead,
+ PciIoConfigWrite
+ },
+ PciIoCopyMem,
+ PciIoMap,
+ PciIoUnmap,
+ PciIoAllocateBuffer,
+ PciIoFreeBuffer,
+ PciIoFlush,
+ PciIoGetLocation,
+ PciIoAttributes,
+ PciIoGetBarAttributes,
+ PciIoSetBarAttributes,
+ 0, //RomSize;
+ NULL //RomImage
+};
+
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//======================================================================
+// Here follows worker functions used for
+// PCI Bus Enumeration and Resource Allocation
+//======================================================================
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnableDeviceDecoding()
+//
+// Description: Enables PCI Device Decoding.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+// PCI_SPACE_TYPE WhatSpace Type of PCI Device Space for Action.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_SPACE_TYPE.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EnableDeviceDecoding(PCI_DEV_INFO *Dev, PCI_SPACE_TYPE WhatSpace)
+{
+ EFI_STATUS Status;
+ UINT16 b16;
+ PCI_CFG_ADDR addr;
+//------------------
+
+ if(Dev->Type<tPci2PciBrg) return EFI_SUCCESS;
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+ if(Dev->DebugPort) return EFI_SUCCESS;
+#endif
+
+ addr.ADDR=Dev->Address.ADDR;
+ //first read Command reg contents
+ addr.Addr.Register=PCI_COMMAND_REGISTER_OFFSET;
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&b16);
+ if(EFI_ERROR(Status)) return Status;
+
+ switch (WhatSpace){
+ case stOptRomSpace:
+ case stMemSpace: b16|=(PCI_CMD_MEMORY_SPACE); break;
+ case stIoSpace: b16|=(PCI_CMD_IO_SPACE); break;
+ case stMemIoSpace: b16|=(PCI_CMD_IO_SPACE | PCI_CMD_MEMORY_SPACE); break;
+ default: return EFI_INVALID_PARAMETER;
+ } //switch
+ //if Enabling PCI ROM space
+ if(WhatSpace==stOptRomSpace && Dev->Bar[PCI_MAX_BAR_NO].Type!=tBarUnused){
+ UINT32 b32;
+ //----------------------
+ addr.Addr.Register=Dev->Bar[PCI_MAX_BAR_NO].Offset;
+
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,&b32);
+ if(EFI_ERROR(Status)) return Status;
+
+ b32|=1;
+ Status=PciCfg32(Dev->RbIo,addr,TRUE,&b32);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ //Write Data to the Command Register
+ addr.Addr.Register=PCI_COMMAND_REGISTER_OFFSET;
+ return PciCfg16(Dev->RbIo,addr,TRUE,&b16);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableDeviceDecoding()
+//
+// Description: Disables PCI Device Decoding.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+// PCI_SPACE_TYPE WhatSpace Type of PCI Device Space for Action.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_SPACE_TYPE.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisableDeviceDecoding(PCI_DEV_INFO *Dev, PCI_SPACE_TYPE WhatSpace)
+{
+ EFI_STATUS Status;
+ UINT16 b16;
+ PCI_CFG_ADDR addr;
+//------------------
+ //Don't toch Host brg device as a PCI Device
+ if(Dev->Type==tPciHostDev || Dev->Type==tUncompatibleDevice) return EFI_SUCCESS;
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+ if(Dev->DebugPort) return EFI_SUCCESS;
+#endif
+
+ addr.ADDR=Dev->Address.ADDR;
+ //first read Command reg contents
+ addr.Addr.Register=PCI_COMMAND_REGISTER_OFFSET;
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&b16);
+ if(EFI_ERROR(Status)) return Status;
+
+ switch (WhatSpace){
+ case stOptRomSpace:
+ case stMemSpace:
+ b16 &= (~PCI_CMD_MEMORY_SPACE);
+ break;
+ case stIoSpace:
+ b16 &= (~PCI_CMD_IO_SPACE);
+ break;
+ case stMemIoSpace:
+ b16 &= (~(PCI_CMD_IO_SPACE | PCI_CMD_MEMORY_SPACE));
+ break;
+ case stDisableAll:
+ b16 &= (~(PCI_CMD_IO_SPACE | PCI_CMD_MEMORY_SPACE | PCI_CMD_BUS_MASTER));
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ } //switch
+
+ //if Disabling PCI ROM space
+ if( (WhatSpace == stOptRomSpace ) && (Dev->Bar[PCI_MAX_BAR_NO].Type!=tBarUnused)){
+ UINT32 b32;
+ //----------------------
+ addr.Addr.Register=Dev->Bar[PCI_MAX_BAR_NO].Offset;
+
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,&b32);
+ if(EFI_ERROR(Status)) return Status;
+
+ b32&=(~1);
+ Status=PciCfg32(Dev->RbIo,addr,TRUE,&b32);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ //Write Data to the Command Register
+ addr.Addr.Register=PCI_COMMAND_REGISTER_OFFSET;
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&b16);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnableBridgeIoDecoding()
+//
+// Description: Enables PCI Bridge I/O Space Decoding.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Bridge Private Data structure.
+// UINT64 Base Base Address of the Bridge I/O Window.
+// UINT64 Length Length of the Bridge I/O Window.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EnableBridgeIoDecoding(PCI_DEV_INFO *Brg, UINT64 Base, UINT64 Length)
+{
+ PCI_CFG_ADDR BrgDevAddr;
+ UINT64 buff;
+ EFI_STATUS Status;
+//----------------------------------------
+ PCI_TRACE((TRACE_PCI,"PciBus: Enabling Brg I/O @ B%X|D%X|F%X\n, B=%lX; L=%lX\n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device,Brg->Address.Addr.Function,
+ Base, Length));
+
+ BrgDevAddr.ADDR=Brg->Address.ADDR;
+ //Set IObase to 0xFF and IO limit to 0
+ BrgDevAddr.Addr.Register=0x1C;
+ buff=Shr64(Base,8);
+
+ Status = PciCfg8(Brg->RbIo, BrgDevAddr,TRUE,(UINT8*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ buff=Shr64(Base,16);
+ BrgDevAddr.Addr.Register=0x30; //Upper 16 Base Reg
+
+ Status = PciCfg16(Brg->RbIo, BrgDevAddr,TRUE,(UINT16*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ //Set IO limit
+ buff=Shr64(Base+(Length-1),8);
+ BrgDevAddr.Addr.Register=0x1D;
+
+ Status = PciCfg8(Brg->RbIo, BrgDevAddr,TRUE,(UINT8*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ //Set IO limit Upper 16
+ buff=Shr64(Base+(Length-1),16);
+ BrgDevAddr.Addr.Register=0x32;
+
+ return PciCfg16(Brg->RbIo, BrgDevAddr,TRUE,(UINT16*)&buff);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableBridgeIoDecoding()
+//
+// Description: Disables PCI Bridge I/O Space Decoding.
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Bridge Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_BRG_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisableBridgeIoDecoding(PCI_BRG_INFO *Brg)
+{
+ PCI_CFG_ADDR BrgDevAddr;
+ UINT32 buff=0x00FF;
+ EFI_STATUS Status;
+//----------------------------------------
+ BrgDevAddr.ADDR=Brg->Common.Address.ADDR;
+ //Set IObase to 0xFF and IO limit to 0
+ BrgDevAddr.Addr.Register=0x1C;
+ Status = PciCfg16(Brg->Common.RbIo, BrgDevAddr,TRUE,(UINT16*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ //Set IO limit upper 32 base and limit to 0
+ BrgDevAddr.Addr.Register=0x30;
+ return PciCfg32(Brg->Common.RbIo, BrgDevAddr,TRUE,&buff);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnableBridgeMmioDecoding()
+//
+// Description: Enables PCI Bridge MMIO Space Decoding.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Bridge Private Data structure.
+// UINT64 Base Base Address of the Bridge I/O Window.
+// UINT64 Length Length of the Bridge I/O Window.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EnableBridgeMmioDecoding(PCI_DEV_INFO *Brg, UINT64 Base, UINT64 Length)
+{
+ PCI_CFG_ADDR BrgDevAddr;
+ UINT64 buff;
+ EFI_STATUS Status;
+//----------------------------------------
+ PCI_TRACE((TRACE_PCI,"PciBus: Enabling Brg MMIO @ [B%X|D%X|F%X] --> B=%lX; L=%lX\n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device,Brg->Address.Addr.Function,
+ Base, Length));
+
+ BrgDevAddr.ADDR=Brg->Address.ADDR;
+ //Set Memory Base
+ BrgDevAddr.Addr.Register=PCI_MEMBASE;
+ //buff=Base>>16;
+ buff=Shr64(Base,16);
+
+ Status=PciCfg16(Brg->RbIo, BrgDevAddr,TRUE,(UINT16*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ //Set Memory limt
+ BrgDevAddr.Addr.Register=PCI_MEMLIMIT;
+ buff=Shr64(Base+(Length-1),16);
+ return PciCfg16(Brg->RbIo, BrgDevAddr,TRUE,(UINT16*)&buff);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableBridgeMmioDecoding()
+//
+// Description: Disables PCI Bridge MMIO Space Decoding.
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Bridge Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_BRG_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisableBridgeMmioDecoding(PCI_BRG_INFO *Brg)
+{
+ PCI_CFG_ADDR BrgDevAddr;
+ UINT32 buff=0x0000FFFF;
+//----------------------------------------
+ BrgDevAddr.ADDR=Brg->Common.Address.ADDR;
+ //Set Memory Base to FFFF and Limit to 0;
+ BrgDevAddr.Addr.Register=0x20;
+ return PciCfg32(Brg->Common.RbIo, BrgDevAddr,TRUE,&buff);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnableBridgePfmmDecoding()
+//
+// Description: Enables PCI Bridge Prefetchable MMIO Space Decoding.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Bridge Private Data structure.
+// UINT64 Base Base Address of the Bridge I/O Window.
+// UINT64 Length Length of the Bridge I/O Window.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EnableBridgePfmmDecoding(PCI_DEV_INFO *Brg, UINT64 Base, UINT64 Length)
+{
+ PCI_CFG_ADDR BrgDevAddr;
+ UINT64 buff;
+ EFI_STATUS Status;
+//----------------------------------------
+ PCI_TRACE((TRACE_PCI,"PciBus: Enabling Brg PFMM @ B%X|D%X|F%X\n, B=%lX; L=%lX\n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device,Brg->Address.Addr.Function,
+ Base, Length));
+
+ BrgDevAddr.ADDR=Brg->Address.ADDR;
+
+ //Set Pf Memory Base
+ BrgDevAddr.Addr.Register=0x24;
+ buff=Shr64(Base,16);
+
+ Status = PciCfg16(Brg->RbIo, BrgDevAddr, TRUE,(UINT16*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ //Set PF Memory Limit
+ BrgDevAddr.Addr.Register=0x26;
+ buff=Shr64(Base+(Length-1),16);
+
+ Status = PciCfg16(Brg->RbIo, BrgDevAddr, TRUE, (UINT16*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ buff=Shr64(Base,32);
+ //Set Pf Memory Upper 32 Base
+ BrgDevAddr.Addr.Register=0x28;
+ Status = PciCfg32(Brg->RbIo, BrgDevAddr,TRUE,(UINT32*)&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ buff=Shr64(Base+(Length-1),32);
+ //Set Pf Memory Upper 32 Limit
+ BrgDevAddr.Addr.Register=0x2C;
+ return PciCfg32(Brg->RbIo, BrgDevAddr,TRUE,(UINT32*)&buff);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableBridgePfmmDecoding()
+//
+// Description: Disables PCI Bridge Prefetchable MMIO Space Decoding.
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Bridge Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_BRG_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisableBridgePfmmDecoding(PCI_BRG_INFO *Brg)
+{
+ PCI_CFG_ADDR BrgDevAddr;
+ UINT32 buff=0x0000FFFF;
+ EFI_STATUS Status;
+//----------------------------------------
+ BrgDevAddr.ADDR=Brg->Common.Address.ADDR;
+
+ //Set Pf Memory Base to FFFF Limit to 0;
+ BrgDevAddr.Addr.Register=0x24;
+ Status = PciCfg32(Brg->Common.RbIo, BrgDevAddr,TRUE,&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ buff=0;
+ //Set Pf Memory Upper 32 Base to 0;
+ BrgDevAddr.Addr.Register=0x28;
+ Status = PciCfg32(Brg->Common.RbIo, BrgDevAddr,TRUE,&buff);
+ if(EFI_ERROR(Status))return Status;
+
+ //Set Pf Memory Upper 32 Limit to 0;
+ BrgDevAddr.Addr.Register=0x2c;
+ return PciCfg32(Brg->Common.RbIo, BrgDevAddr,TRUE,&buff);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DisableBridgeDecoding()
+//
+// Description: Disables PCI Bridge Decoding of ALL resources.
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Bridge Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_BRG_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisableBridgeDecoding(PCI_BRG_INFO *Brg)
+{
+ EFI_STATUS Status;
+//---------------------------------------
+
+ PCI_TRACE((TRACE_PCI,"PciBus: Disabling Brg @ B%X|D%X|F%X\n",
+ Brg->Common.Address.Addr.Bus, Brg->Common.Address.Addr.Device,Brg->Common.Address.Addr.Function));
+ Status=DisableBridgeIoDecoding(Brg);
+ if(EFI_ERROR(Status))return Status;
+
+ Status=DisableBridgeMmioDecoding(Brg);
+ if(EFI_ERROR(Status))return Status;
+
+ return DisableBridgePfmmDecoding(Brg);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetSubBus()
+//
+// Description: Programm SubordinateBusNumber Register of PCI Bridge.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Bridge Private Data structure.
+// UINT8 SubBusNo Number to programm.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_BRG_INFO.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetSubBus(PCI_DEV_INFO *Brg, UINT8 SubBusNo)
+{
+ PCI_CFG_ADDR addr;
+//---------------------------------------
+ addr.ADDR=Brg->Address.ADDR;
+ addr.Addr.Register=PCI_BRIDGE_SUBORDINATE_BUS_REGISTER_OFFSET; //Sub Bus No reg
+
+ return PciCfg8(Brg->RbIo, addr,TRUE,&SubBusNo);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddBusDbEntry()
+//
+// Description: Fills gPciBusDb Array in ascending order.
+//
+// Input:
+// PCI_BRG_EXT *Ext Pointer to PCI Bridge Extension Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddBusDbEntry(PCI_BUS_XLAT_HDR *BusHdr, T_ITEM_LIST *BusDb){
+ EFI_STATUS Status;
+ UINTN i;
+ PCI_BUS_XLAT_HDR *xhdr;
+//--------------------------
+
+ if(BusDb->ItemCount==0) {
+ Status=AppendItemLst(BusDb, BusHdr);
+ } else {
+ for(i=0; i<BusDb->ItemCount; i++){
+ xhdr = (PCI_BUS_XLAT_HDR*)BusDb->Items[i];
+ if(xhdr->BusBuild > BusHdr->BusBuild){
+ return InsertItemLst(BusDb, BusHdr, i);
+ }
+ }//for
+ // if we here and didn't returned yet - BusHdr->BusBuild is the bidggest one.
+ Status = AppendItemLst(BusDb, BusHdr);
+ }
+#if AMI_BOARD_VER_COMBINED >= 100
+ //Increase BusXlatTable entry count...
+ if(!EFI_ERROR(Status)) gAmiBoardInfo->BusXlatEntries++;
+#endif
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PopulateBusDb()
+//
+// Description: Fills gPciBusDb Array in ascending order.
+//
+// Input: Nothing;
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PopulateBusDb(){
+ PCI_BUS_XLAT_HDR *xhdr=gAmiBoardInfo->BusXlatTable;
+ PCI_DEV_FUN *devf = (PCI_DEV_FUN*)(xhdr+1);
+ EFI_STATUS Status=EFI_SUCCESS;
+//--------------------------------
+ while((UINTN)devf<=(UINTN)(gAmiBoardInfo->BusXlatTable) + gAmiBoardInfo->BusXlatLength){
+ if(devf->DEV_FUN == 0xFF){
+ //if we are looking for host device it shouldn't be any other guys in it's chain.
+ Status=AddBusDbEntry(xhdr, &gPciBusDb);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ //Advance to the next record in BusXlatTbl.
+#if AMI_BOARD_VER_COMBINED >= 100
+ //Now we have AslName[5] following devf data (sizeof(PCI_DEV_FUN)==1 byte)
+ xhdr=(PCI_BUS_XLAT_HDR*)(devf+1+5);
+#else
+ xhdr=(PCI_BUS_XLAT_HDR*)(devf+1);
+#endif
+ devf = (PCI_DEV_FUN*)(xhdr+1);
+ continue;
+ } else {
+ devf++;
+ }
+ }
+ return Status;
+}
+
+/*
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindRootXlatEntry()
+//
+// Description: Finds corresponded BusXlatTable entry for the bridge.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Bridge Private Data structure.
+// PCI_BUS_XLAT_HDR *XlatHdr Double Pointer to XLAT_HEADER will be initialized by this function
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BRG_INFO; PCI_BRG_EXT.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindRootXlatEntry(PCI_DEV_INFO *Dev, PCI_BUS_XLAT_HDR **XlatHdr){
+ PCI_DEV_INFO *brg=Dev;
+ PCI_BRG_EXT *ext=NULL;
+//-------------------------
+ while(brg->Type==tPciRootBrg){
+ brg=brg->ParentBrg;
+ //this code just to double check the loop will be exited.
+ //
+ if(brg->ParentBrg==NULL){
+ ext=(PCI_BRG_EXT*)(brg+1);
+
+ if(ext->XlatTblEntry==NULL) return EFI_NOT_FOUND;
+
+ *XlatHdr=ext->XlatTblEntry;
+
+ break;
+ }
+ }
+
+ if(ext==NULL) return EFI_NOT_FOUND;
+
+ return EFI_SUCCESS;
+
+}
+*/
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindBridgeXlatEntry()
+//
+// Description: Finds corresponded BusXlatTable entry for the bridge.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Bridge Private Data structure.
+// PCI_BRG_EXT *Ext Pointer to PCI Bridge Extension Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BRG_INFO; PCI_BRG_EXT.
+//
+// Notes:
+// BaseBus = PCI_DEV_INFO->Address.Addr.Bus;
+// SecondaryBus = PCI_BRG_EXT->Res[rtBus].Base;
+// SubordinateBus = PCI_BRG_EXT->Res[rtBus].Base + PCI_BRG_EXT->Res[rtBus].Length-1;
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindBridgeXlatEntry(PCI_DEV_INFO *Dev, PCI_BRG_EXT *Ext){
+ PCI_BUS_XLAT_HDR *xhdr;
+ PCI_DEV_FUN *devf;
+ UINTN i, chncnt; //Xlat Tbl Elemnts count (number of Dev/Fn instances)
+ PCI_BRG_EXT *ext;
+//-----------------------------
+ //Now we will go trough BusXlatTbl entryes.
+ for(i=0; i<gPciBusDb.ItemCount; i++){
+ xhdr=gPciBusDb.Items[i];
+ devf = (PCI_DEV_FUN*)(xhdr+1);
+ for (chncnt=0; ; devf++,chncnt++){
+ //Got to the end of PCI device chain
+ if(devf->DEV_FUN == 0xFF){
+ //if we are looking for host device it shouldn't be any other guys in it's chain.
+ if((Dev->ParentBrg == NULL) && (chncnt==1) && (Dev->Type==tPciRootBrg)){
+ //Check first if it is a correct host.
+ if( (xhdr->BusBuild == Dev->Address.Addr.Bus) )
+ {
+ //xhdr->BusRun = Dev->Address.Addr.Bus;
+ Ext->XlatTblEntry=xhdr;
+ Ext->ChainNumber=(UINT8)chncnt;
+ Ext->ItemNumber=(UINT8)i;
+
+ PCI_TRACE((TRACE_PCI,"PciBus: Found BusXlat for Host [B%X|D%X|F%X] BusBuild=%X\n",
+ Dev->Address.Addr.Bus,Dev->Address.Addr.Device, Dev->Address.Addr.Function, xhdr->BusBuild));
+
+ return EFI_SUCCESS;
+ }
+ } else {
+ //NOT HOST Device !((Dev->ParentBrg == NULL) && (chncnt==1))
+ PCI_DEV_FUN *df=devf-1;
+ //----------------------
+ if(Dev->ParentBrg!=NULL){
+
+ //Here we will define a criteria when XLAT TBL entrie considered a match..
+ //1. ParentBrg->Ext->XlatTblEntry must be initialized
+ //2. ParentBrg->ChainNumber must be (chncnt-1) so this one will be the same elememnt
+ //3. ParentBrg->Ext->XlatTblEntry->BusBuild must not exceed THIS xhdr->BusBuild
+ //4. df->Dev==Dev->Address.Addr.Device AND df->Fun==Dev->Address.Addr.Function
+ //5. THIS Dev->Ext->XlatTbEntry must not be initialized yet..
+
+ //Get Parent Bridge ext of this device.
+ ext=(PCI_BRG_EXT*)(Dev->ParentBrg+1);
+
+ //1. ParentBrg->Ext->XlatTblEntry must be initialized
+ //2. ParentBrg->Ext->ChainNumber must be (chncnt-1) so this one will be the same elememnt in it's Chain
+ //5. THIS Dev->Ext->XlatTbEntry must not be initialized yet...
+ if((Ext->XlatTblEntry==NULL)&&(ext->XlatTblEntry!=NULL) && (ext->ChainNumber == (UINT8)chncnt-1)){
+
+ //3. ParentBrg->Ext->XlatTblEntry->BusBuild must not exceed THIS xhdr->BusBuild
+ if( xhdr->BusBuild > ext->XlatTblEntry->BusBuild ) {
+
+ //4. df->Dev==Dev->Address.Addr.Device AND df->Fun==Dev->Address.Addr.Function
+ if((Dev->Address.Addr.Device == df->Dev)&&(Dev->Address.Addr.Function == df->Fun)){
+
+ if(MemCmp((VOID*)(ext->XlatTblEntry+1),(VOID*)(xhdr+1), ext->ChainNumber)==0){
+ //xhdr->BusRun = Dev->Address.Addr.Bus;
+ Ext->XlatTblEntry=xhdr;
+ Ext->ChainNumber=(UINT8)chncnt;
+ Ext->ItemNumber=(UINT8)i;
+ PCI_TRACE((TRACE_PCI,"PciBus: Found BusXlat for Brg [B%X|D%X|F%X] BusBuild=%X\n",
+ Dev->Address.Addr.Bus,Dev->Address.Addr.Device, Dev->Address.Addr.Function, xhdr->BusBuild));
+ return EFI_SUCCESS;
+ }
+ }//Cond 4
+
+ }//cond 3;
+
+ }//cond 1;2;5;
+ }//if(Dev->ParentBrg!=NULL)
+ } //else
+ break;
+ }//devf->DEV_FUN == 0xFF
+ } //for chncnt
+ } //for i
+
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindBridgeXlatEntry()
+//
+// Description: Finds corresponded BusXlatTable entry for the next bridge
+// of the same level (same number of nodes/chain-counts).
+//
+// Input:
+// PCI_BRG_EXT *Ext Pointer to PCI Bridge Extension Private Data structure.
+//
+// Output: UINT8 Number of buses decoded by the Bridge which "Ext" passed.
+//
+// Notes:
+// BaseBus = PCI_DEV_INFO->Address.Addr.Bus;
+// SecondaryBus = PCI_BRG_EXT->Res[rtBus].Base;
+// SubordinateBus = PCI_BRG_EXT->Res[rtBus].Base + PCI_BRG_EXT->Res[rtBus].Length-1;
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 FindNextSameLevelBrgXlatEntry(PCI_BRG_EXT *Ext){
+ PCI_BUS_XLAT_HDR *xhdr;
+ PCI_DEV_FUN *devf;
+ UINTN i, chncnt; //Xlat Tbl Elemnts count (number of Dev/Fn instances)
+//-----------------------------
+ //Now we will go trough BusXlatTbl entryes.
+ if(gPciBusDb.ItemCount <= (UINTN)(Ext->ItemNumber+1) ) return (UINT8)mMaxBusScan;
+
+ for(i=Ext->ItemNumber+1; i<gPciBusDb.ItemCount; i++){
+ xhdr=gPciBusDb.Items[i];
+ devf = (PCI_DEV_FUN*)(xhdr+1);
+ for (chncnt=0; ; devf++,chncnt++){
+ //Got to the end of PCI device chain
+ if(devf->DEV_FUN == 0xFF) break;
+ } //for chncnt
+ //here we found record terminator
+ //go and check the following.
+ //1. if this Xlat node of the same or less
+ if(chncnt<=Ext->ChainNumber) return (UINT8)(xhdr->BusBuild-1);
+ } //for i
+
+ return (UINT8)mMaxBusScan;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindDevIrqEntry()
+//
+// Description: Finds corresponded BusXlatTable entry for the bridge.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Bridge Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BRG_INFO; PCI_BRG_EXT.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindDevIrqEntry(PCI_DEV_INFO *Dev){
+ UINTN i, cnt;
+ PCI_DEV_INFO *brg=Dev->ParentBrg;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(brg+1);
+ PCI_BUS_XLAT_HDR *xhdr=ext->XlatTblEntry;
+ PCI_IRQ_PIC_ROUTE *pic;
+ PCI_IRQ_APIC_ROUTE *apic;
+//-----------------------------------
+
+ //Find Matching IRQ Routing entry for PIC
+ //cnt=((UINTN)gPicIrqTblEnd-(UINTN)gPicIrqRoutTbl)/sizeof(PCI_IRQ_PIC_ROUTE)-1;
+ cnt=gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE);
+
+ for(i=0; i<cnt; i++){
+ pic=&gAmiBoardInfo->PicRoutTable[i];
+ if(xhdr->BusBuild==pic->PciBusNumber){
+ //pic->PciBusNumber=xhdr->BusRun;
+
+ if( pic->DevFun.Dev == Dev->Address.Addr.Device){
+ Dev->PicIrqEntry = pic;
+ break;
+ }
+ }
+ }
+ //Find Matching IRQ Routing entry for APIC
+ //cnt=((UINTN)gApicIrqTblEnd-(UINTN)gApicIrqRoutTbl)/sizeof(PCI_IRQ_APIC_ROUTE)-1;
+ cnt=gAmiBoardInfo->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE);
+
+ for(i=0; i<cnt; i++){
+ apic=&gAmiBoardInfo->ApicRoutTable[i];
+ if(xhdr->BusBuild==apic->PciBusNumber){
+ //apic->PciBusNumber=xhdr->BusRun;
+
+ if( apic->DeviceNumber == Dev->Address.Addr.Device){
+ Dev->ApicIrqEntry = apic;
+ break;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: *mPicIrqSta[]; *mPicIrqSta[]
+//
+// Description: To make sure we are not updating entries we have updated
+// already, we would need array of BBOLEANs to mark updated entries.
+//
+// NOTE: BOOLEAN Aarray [IrqRoiting Table enytries Number]
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+BOOLEAN *mPicIrqSta = NULL;
+BOOLEAN *mApicIrqSta= NULL;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateItqTbl()
+//
+// Description: Updtaes all matching entries in Irqrouting tables with
+// runtime values.
+//
+// Input:
+// PCI_BUS_XLAT_HDR *XlatHdr Updated BusTranslate table entry.
+//
+// Output: NOTHING
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateIrqTables(PCI_BUS_XLAT_HDR *XlatHdr){
+ UINTN i;
+ PCI_IRQ_PIC_ROUTE *pic;
+ PCI_IRQ_APIC_ROUTE *apic;
+//------------------------------
+
+ if(mPicIrqSta==NULL) mPicIrqSta=MallocZ(gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE));
+ if(mApicIrqSta==NULL) mApicIrqSta=MallocZ(gAmiBoardInfo->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE));
+
+ for(i=0; i<gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE); i++){
+ pic=&gAmiBoardInfo->PicRoutTable[i];
+ if(pic->PciBusNumber==XlatHdr->BusBuild && mPicIrqSta[i]==FALSE) {
+ pic->PciBusNumber=XlatHdr->BusRun;
+ mPicIrqSta[i]=TRUE;
+ }
+ }
+
+ //Not likely but who knows... it could be that gAmiBoardInfo->PicRoutLength
+ //different from gAmiBoardInfo->ApicRoutLength... so teke care of that!
+ for(i=0; i<gAmiBoardInfo->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE); i++){
+ apic=&gAmiBoardInfo->ApicRoutTable[i];
+ if(apic->PciBusNumber==XlatHdr->BusBuild && mApicIrqSta[i]==FALSE) {
+ apic->PciBusNumber=XlatHdr->BusRun;
+ mApicIrqSta[i]=TRUE;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveUnusedIrqEntries()
+//
+// Description: Removes IRQ routing entries which got there by porting mistake
+// in order not to confuse other consumers of AmiBoardInfoProtocol...
+//
+// Input: NOTHING
+//
+// Output: NOTHING
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RemoveUnusedIrqEntries(){
+ UINTN i, j, cnt;
+ PCI_IRQ_PIC_ROUTE *tmpp;
+ PCI_IRQ_APIC_ROUTE *tmpa;
+//------------------------------
+ cnt=gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE);
+ tmpp=(PCI_IRQ_PIC_ROUTE*)Malloc(gAmiBoardInfo->PicRoutLength);
+ ASSERT(tmpp);
+
+ for(j=0,i=0; j<cnt; j++){
+ if(mPicIrqSta[j]==TRUE){
+ MemCpy(&tmpp[i],&gAmiBoardInfo->PicRoutTable[j],sizeof(PCI_IRQ_PIC_ROUTE));
+ i++;
+ } else {
+ gAmiBoardInfo->PicRoutLength -= sizeof(PCI_IRQ_PIC_ROUTE);
+ PCI_TRACE((TRACE_PCI,"PciBus: Removing unused entry #%d from PIC Routing Table\n", j));
+ }
+ }
+ //Copy updated tabe from tmp buffer to AmiBoardInfo Location
+ MemCpy(&gAmiBoardInfo->PicRoutTable[0], &tmpp[0], gAmiBoardInfo->PicRoutLength);
+
+ //Not likely but who knows... it could be that gAmiBoardInfo->PicRoutLength
+ //different from gAmiBoardInfo->ApicRoutLength... so teke care of that!
+ cnt=gAmiBoardInfo->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE);
+ tmpa=(PCI_IRQ_APIC_ROUTE*)Malloc(gAmiBoardInfo->ApicRoutLength);
+ ASSERT(tmpa);
+
+ for(j=0,i=0; j<cnt;j++){
+ if(mApicIrqSta[j]==TRUE){
+ MemCpy(&tmpa[i],&gAmiBoardInfo->ApicRoutTable[j],sizeof(PCI_IRQ_APIC_ROUTE));
+ i++;
+ } else {
+ gAmiBoardInfo->ApicRoutLength -= sizeof(PCI_IRQ_APIC_ROUTE);
+ PCI_TRACE((TRACE_PCI,"PciBus: Removing unused entry #%d from APIC Routing Table\n", j));
+ }
+ }
+ //Copy updated tabe from tmp buffer to AmiBoardInfo Location
+ MemCpy(&gAmiBoardInfo->ApicRoutTable[0], &tmpa[0], gAmiBoardInfo->ApicRoutLength);
+
+ //free buffers allocated, functions depending on it
+ //not suppose to be called anymore.
+ if(mPicIrqSta!=NULL){
+ pBS->FreePool(mPicIrqSta);
+ mPicIrqSta=NULL;
+ }
+ if(mApicIrqSta!=NULL){
+ pBS->FreePool(mApicIrqSta);
+ mApicIrqSta=NULL;
+ }
+ if(tmpp!=NULL) pBS->FreePool(tmpp);
+ if(tmpa!=NULL) pBS->FreePool(tmpa);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MapBridgeBuses()
+//
+// Description: Maps Bridge's Primary Secondary Subordinate Bus Numbers
+// according information stored in PCI_DEV_INFO and PCI_BRG_EXT structures
+// of the PCI Bridge.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Bridge Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BRG_INFO; PCI_BRG_EXT.
+//
+// Notes:
+// BaseBus = PCI_DEV_INFO->Address.Addr.Bus;
+// SecondaryBus = PCI_BRG_EXT->Res[rtBus].Base;
+// SubordinateBus = PCI_BRG_EXT->Res[rtBus].Base + PCI_BRG_EXT->Res[rtBus].Length-1;
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS MapBridgeBuses(PCI_DEV_INFO *Brg)
+{
+ EFI_STATUS Status;
+ PCI_CFG_ADDR addr;
+ UINT8 bus;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Brg+1);
+//--------------------------------
+ //Get Bridge Initial Address
+ addr.ADDR=Brg->Address.ADDR;
+ //Primary bus;
+ addr.Addr.Register=PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET; //Primary BusNo
+ bus=Brg->Address.Addr.Bus;
+ Status=PciCfg8(Brg->RbIo,addr,TRUE,&bus);
+ if(EFI_ERROR(Status))return Status;
+
+ //SecondaryBus Register
+ addr.Addr.Register=PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET; //Secondary BusNo
+
+ bus=(UINT8)ext->Res[rtBus].Base;
+ Status=PciCfg8(Brg->RbIo,addr,TRUE,&bus);
+ if(EFI_ERROR(Status))return Status;
+
+ //Now Programm SubordinateBusNo reg
+ bus=(UINT8)(ext->Res[rtBus].Base+ext->Res[rtBus].Length-1);
+ return SetSubBus(Brg, bus);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPciCompatibility()
+//
+// Description: This function will check if PCI "Device" listed in Bad PCI
+// Device Table - gBadPciDevList[].
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// PCI_BAR_TYPE BarType Type of Bar Register.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO; PCI_BAR_TYPE.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PCI_BAD_BAR *CheckPciCompatibility(PCI_DEV_INFO *Device, PCI_BAR *Bar, PCI_BAR_TYPE BarType) //(EIP41687)
+{
+ UINTN i;
+ PCI_BAD_BAR *bbp;
+ PCI_DEV_ID d,t;
+//-----------------------
+ d.DEV_VEN_ID=Device->DevVenId.DEV_VEN_ID;
+ for(i=0; i<gBadPciDevCount; i++){
+ bbp=&gBadPciDevList[i];
+ //(EIP41687)>
+ if(Bar) {
+ if (bbp->BarOffset) {
+ if (Bar->Offset != bbp->BarOffset) continue;
+ }
+ }
+ //<(EIP41687)
+ t.VenId=bbp->VendorId;
+ t.DevId=bbp->DeviceId & bbp->DevIdMask;
+ d.DevId=Device->DevVenId.DevId & bbp->DevIdMask;
+ if(d.DEV_VEN_ID==t.DEV_VEN_ID){
+ if(BarType) {
+ if(BarType==bbp->BarType) return bbp;
+ } else return bbp;
+ }
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AdjustBarGra()
+//
+// Description: This function will Check and Adjust PCI Device's BAR
+// Granularity according information found in gBadPciDevList[].
+//
+// Input:
+// PCI_BAR Bar Type of Bar Register.
+//
+// Output: NOTHING
+//
+// Referals: PCI_BAR; PCI_BAR_TYPE; gBadPciDevList.
+//
+// Notes:
+// This function will be invoked only if PCI Device owning this BAR is in
+// gBadPciDevList.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AdjustBarGra(PCI_BAR *Bar){
+ UINTN i,s,e;
+ PCI_BAR_TYPE bt;
+ PCI_BAD_BAR *bbp;
+ UINT64 t=0,g=~(Bar->Gran);
+//----------------------------
+ switch(Bar->Type){
+ case tBarIo16: //2
+ case tBarIo32: //3
+ bt=tBarIo;
+ s=2;
+ break;
+ case tBarMmio32: //4
+ case tBarMmio32pf: //5
+ case tBarMmio64: //6
+ case tBarMmio64pf: //7
+ bt=tBarMem;
+ s=4;
+ break;
+ default:
+ bt=tBarUnused;
+ s=0;
+ }
+
+ bbp=CheckPciCompatibility(Bar->Owner,Bar,bt); //(EIP41687)
+ if(!bbp)bbp=CheckPciCompatibility(Bar->Owner,Bar,tBarMaxType); //(EIP41687)
+ //this function will be called only if compatibility issue exists with the device
+ //so bbp must be valid or this is not the BAR which needs Adjustment;
+ if(!bbp) return;
+ if(bbp->BarType==tBarMaxType && Bar->Offset!=bbp->BarOffset) return;
+
+ //Here let's do the adjustment...
+ switch(bbp->IncompType){
+ case icBarBad:
+ for(i=s; i<64; i++){
+ //find the very first bit set as 1;
+ t=Shl64(1,(UINT8)i);
+ if(g&t)break;
+ }
+ //Assume that all other bits must be 1
+ e=i;
+ t=0;
+ //Generate Granularity value for this BAR
+ for(i=0;i<e;i++)t|=Shl64(1,(UINT8)i);
+ if(Bar->Type!= tBarMmio64pf && Bar->Type!=tBarMmio64) t&=0xFFFFFFFF;
+ Bar->Gran=t;
+ break;
+
+ case icBarFixedSize:
+ Bar->Length=bbp->BarLength;
+ Bar->Gran=bbp->BarLength-1;
+ break;
+
+ case icNotBar :
+ Bar->Type=tBarUnused;
+ Bar->Length=0;
+ Bar->Gran=0;
+ break;
+
+ case icBad64BitBar :
+ if(Bar->Type == tBarMmio64pf) Bar->Type=tBarMmio32pf;
+ else if (Bar->Type == tBarMmio64) Bar->Type=tBarMmio32;
+ break;
+ }//switch
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OptionRom()
+//
+// Description: This function will detect PCI Option ROMs BAR requirements.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OptionRom(PCI_DEV_INFO *Device)
+{
+ PCI_CFG_ADDR devaddr;
+ EFI_STATUS Status=0;
+ UINT32 b32;
+ PCI_BAR *rombar;
+//---------------------------------
+ //Our Device still in disable decoding mode which it entered in
+ //Now Query Expansion ROM reg
+ // the bit0 is 0 to prevent the enabling of the Rom address decoder
+ devaddr.ADDR=Device->Address.ADDR;
+ switch (Device->Type){
+ case tPci2PciBrg : devaddr.Addr.Register=PCI_P2P_ROM_BAR;
+ break;
+ case tPciDevice :
+ case tPciHostDev :
+ devaddr.Addr.Register=PCI_DEV_ROM_BAR;
+ break;
+ case tPci2CrdBrg : //this one doesnot have ROM BAR
+ default : return EFI_SUCCESS; //other devices not suppose to be examined
+ }
+
+ rombar=&Device->Bar[PCI_MAX_BAR_NO];
+ rombar->Offset=devaddr.Addr.Register;
+
+ b32=0xFFFFFFFE;
+
+ //Write query pattern to PCI Rom Bar Register
+ Status=PciCfg32(Device->RbIo,devaddr,TRUE,&b32);
+ if(EFI_ERROR (Status)) return Status;
+
+ Status=PciCfg32(Device->RbIo,devaddr,FALSE,&b32);
+ if(EFI_ERROR (Status)) return Status;
+
+ b32&=0xFFFFFFFE;
+ if ((b32 != 0) && (b32 != 0xFFFFFFFE)){
+ rombar->Type=tBarMmio32;
+ rombar->Gran=~b32;
+ rombar->Length=(~b32)+1;
+ }
+
+ if(Device->Incompatible) AdjustBarGra(rombar);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDeviceCapabilities()
+//
+// Description: This function will detect PCI Device Capabilities of the Device's
+// Command Cegister and Bridge Command register (if any).
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters are invalid.
+//
+// Referals: PCI_DEV_INFO.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetDeviceCapabilities(PCI_DEV_INFO *Dev)
+{
+ PCI_CFG_ADDR addr;
+ EFI_STATUS Status;
+ UINT16 oldcmd, tstcmd, oldbc, tstbc=0;
+ EFI_TPL OldTpl;
+ UINT8 z, tcls;
+//--------------------------------
+
+ if(Dev->ParentBrg)Dev->Capab=Dev->ParentBrg->Capab;
+
+ addr.ADDR=Dev->Address.ADDR;
+ tstcmd=(PCI_CMD_IO_SPACE | PCI_CMD_MEMORY_SPACE | PCI_CMD_MEMORY_WRITE_AND_INVALIDATE |
+ PCI_CMD_BUS_MASTER | PCI_CMD_VGA_PALETTE_SNOOP);
+
+ OldTpl=pBS->RaiseTPL(TPL_HIGH_LEVEL);
+
+ //Set Latency Timer to 20 and Cacheline size to 0 - just in case
+ addr.Addr.Register=0x0c;//Cacheline size & Latency Timer
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&oldcmd);
+ //PciX devices upon reset initialize Latency Timer reg with value of 0x40
+ //regular PCI devices initialize it with 0
+ if(!(oldcmd&0xff00)){//so we will program it only for Regular PCI devices
+ oldcmd=0x2000;
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&oldcmd);
+ if(EFI_ERROR(Status))return Status;
+ }
+ addr.Addr.Register=0x04;//Command Reg
+
+ //Read initial value
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&oldcmd);
+ if(EFI_ERROR(Status))return Status;
+
+ //Write cmdval there and see if it supports it;
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&tstcmd);
+ if(EFI_ERROR(Status))return Status;
+
+ //Read it back and see which bits remains set
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&tstcmd);
+ if(EFI_ERROR(Status))return Status;
+
+ //Restore what was there
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&oldcmd);
+ if(EFI_ERROR(Status))return Status;
+
+ if(Dev->Type==tPci2PciBrg){
+ //Set Latency Timer to 20 and Cacheline size to 0 - just in case
+ addr.Addr.Register=0x1b;//Secondary Latency Timer
+ oldcmd=0x20;
+ Status=PciCfg8(Dev->RbIo,addr,TRUE,(UINT8*)&oldcmd);
+ if(EFI_ERROR(Status))return Status;
+
+ addr.Addr.Register=0x3E; //Bridge controll reg
+ tstbc=(P2P_BRG_CONTROL_ISA | P2P_BRG_CONTROL_VGA | P2P_BRG_CONTROL_VGA_16);
+
+ //Read initial value
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&oldbc);
+ if(EFI_ERROR(Status))return Status;
+
+ //Write cmdval there and see if it supports it;
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&tstbc);
+ if(EFI_ERROR(Status))return Status;
+
+ //Read it back and see which bits remains set
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,&tstbc);
+ if(EFI_ERROR(Status))return Status;
+
+ //Restore what was there
+ Status=PciCfg16(Dev->RbIo,addr,TRUE,&oldbc);
+ if(EFI_ERROR(Status))return Status;
+ }
+
+ //Analize tstcmd Value and update Device->Capab;
+ if(tstcmd & PCI_CMD_IO_SPACE)Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_IO;
+ else Dev->Capab&=(~EFI_PCI_IO_ATTRIBUTE_IO);
+
+ if(tstcmd & PCI_CMD_MEMORY_SPACE)Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_MEMORY;
+ else Dev->Capab&=(~EFI_PCI_IO_ATTRIBUTE_MEMORY);
+
+ if(tstcmd & PCI_CMD_BUS_MASTER)Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
+ else Dev->Capab&=(~EFI_PCI_IO_ATTRIBUTE_BUS_MASTER);
+
+ if(tstcmd & PCI_CMD_VGA_PALETTE_SNOOP)Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+ else Dev->Capab&=(~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);
+
+//BUG//BUG//BUG//BUG//BUG//BUG//BUG
+// This bits in cmd register does not identically maps to EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE
+// if( (tstcmd & PCI_CMD_MEMORY_WRITE_AND_INVALIDATE)||(tstcmd & PCI_CMD_FAST_BACK_TO_BACK) )
+// Dev->Capab|= EFI_PCI_IO_ATTRIBUTE_MEMORY_WRITE_COMBINE;
+
+ //Check Device Capability on CacheLine Size Register
+ Dev->Capab|=MY_PCI_IO_ATTRIBUTE_MEM_WR_INVALIDATE;
+ addr.Addr.Register=0x0c;//Cacheline size & Latency Timer
+
+ //probe Cache Line Size register if it will accept proposed Cache line size
+ tcls=0xFF;
+ Status=PciCfg8(Dev->RbIo,addr,TRUE,&tcls);
+ if(EFI_ERROR(Status))return Status;
+
+ //Read it back and see which bits remains set
+ Status=PciCfg8(Dev->RbIo,addr,FALSE,&z);
+ if(EFI_ERROR(Status))return Status;
+
+ tcls=gPciCaheLineSize;
+
+ //we have tested CLS register it will not accept any value we are proposing
+ if(!( z && (z&(tcls-1)) ))Dev->Capab&=(~MY_PCI_IO_ATTRIBUTE_MEM_WR_INVALIDATE);
+ else{
+ while(!(tcls&z)) tcls=tcls>>1; //same as div 2
+ if(tcls<gPciCaheLineSize) gPciCaheLineSize=tcls;
+ }
+ //clear the register we will program it later when resources will be allocated
+ tcls=0;
+ Status=PciCfg8(Dev->RbIo,addr,TRUE,&tcls);
+ if(EFI_ERROR(Status))return Status;
+
+ //we have additional work to do if Device is P2P bridge
+ if(Dev->Type==tPci2PciBrg){
+ if(tstbc & P2P_BRG_CONTROL_ISA)Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_ISA_IO;
+ else Dev->Capab&=(~EFI_PCI_IO_ATTRIBUTE_ISA_IO);
+
+ if(tstbc & P2P_BRG_CONTROL_VGA)Dev->Capab|=( EFI_PCI_IO_ATTRIBUTE_VGA_IO |
+ EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY|EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);
+ else Dev->Capab&=(~(EFI_PCI_IO_ATTRIBUTE_VGA_IO |
+ EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY|EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO));
+ if(tstbc & P2P_BRG_CONTROL_VGA_16) Dev->Capab|=( EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 |
+ EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16);
+ else Dev->Capab&=(~(EFI_PCI_IO_ATTRIBUTE_VGA_IO_16 | EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO_16));
+
+ //bridge should support IDE attributes
+ Dev->Capab|=(EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO | EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO);
+ } else {
+ //Some special atributes could be supported by PCI devices based on class code
+ switch (Dev->Class.BaseClassCode){
+ case PCI_CL_OLD :
+ if (Dev->Class.SubClassCode==PCI_CL_OLD_SCL_VGA)
+ Dev->Capab|=(EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO);
+ else
+ Dev->Capab&=(~(EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO));
+ break;
+ case PCI_CL_DISPLAY:
+ if (Dev->Class.SubClassCode==PCI_CL_DISPLAY_SCL_VGA)
+ Dev->Capab|=(EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO);
+ else
+ Dev->Capab&=(~(EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO));
+
+ if (Dev->Class.SubClassCode==PCI_CL_DISPLAY_SCL_OTHER) //GFX device can snoop pallete
+ Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO;
+ else Dev->Capab&=(~EFI_PCI_IO_ATTRIBUTE_VGA_PALETTE_IO);
+ break;
+ case PCI_CL_MASS_STOR :
+ if(Dev->Class.SubClassCode==PCI_CL_MASS_STOR_SCL_IDE){
+ UINT8 pib=Dev->Class.ProgInterface, pif=0;
+ //---------------
+ Dev->Capab|=(EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO|EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO);
+ //Now if device is IDE controller check PI on order determine how it was programmed
+ //Just in case overwrite bus master capab if IDE device sets bit 7 in PI Reg
+ if(Dev->Class.ProgInterface & 0x80) Dev->Capab|=EFI_PCI_IO_ATTRIBUTE_BUS_MASTER;
+
+ //primary Controller in LEGACY mode?
+ if( !(Dev->Class.ProgInterface & 0x01)){
+ if(Dev->HostData->PriIde==NULL){
+ //Set the current PCI Device attributes to LEGACY
+ Dev->Attrib|=EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO;
+ Dev->HostData->PriIde=Dev;
+ } else {
+ //set native mode bit since this Legacy IO space has been taken already
+ pif++;
+ pib |= 0x01;
+ }
+ }
+
+ //secondary Controller in LEGACY mode?
+ if( !(Dev->Class.ProgInterface & 0x04) ){
+ if(Dev->HostData->SecIde==NULL){
+ //Set the current PCI Device attributes to LEGACY
+ Dev->Attrib|=EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO;
+ Dev->HostData->SecIde=Dev;
+ } else {
+ //set native mode bit since this Legacy IO space has been taken already
+ pif++;
+ pib |= 0x04;
+ }
+ }
+ if(pif){
+ Status=SetIdeDevMode(Dev, 0,0, &pib);
+ if(!EFI_ERROR(Status)) Dev->Class.ProgInterface = pib;
+ }
+ } else Dev->Capab&=(~(EFI_PCI_IO_ATTRIBUTE_IDE_SECONDARY_IO|EFI_PCI_IO_ATTRIBUTE_IDE_PRIMARY_IO));
+
+ break;
+ }//switch;
+ }
+
+ //device caps should not exsceed parent;
+ if(Dev->Capab & EFI_PCI_IO_ATTRIBUTE_IO)
+ Dev->Capab|=(EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO);
+ else
+ Dev->Capab&=(~(EFI_PCI_IO_ATTRIBUTE_ISA_MOTHERBOARD_IO | EFI_PCI_IO_ATTRIBUTE_ISA_IO));
+
+ pBS->RestoreTPL(OldTpl);
+ PCI_TRACE((TRACE_PCI, "Supported Attributes -> 0x%lX\n", Dev->Capab));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFirstBit(UINT64 Value, BOOLEAN Set, BOOLEAN Right2Left)
+//
+// Description: This function will find first bit Set or Reset
+// going Left to Right.
+//
+// Input:
+// UINT64 Value Value to scan.
+// BOOLEAN Set What condition to test
+// Output:
+// UINT8 First bit set/reset
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 FindFirstBit(UINT64 Value, BOOLEAN Set){
+ UINT64 msk=1, iv=~Value;
+ UINT8 bit;
+//---------------------
+ for(bit=0;bit<64;bit++){
+ msk=Shl64(1,bit);
+ if(Set) {
+ if( (Value & msk) == msk ) break;
+ } else {
+ if(( iv & msk ) == msk ) break;
+ }
+ }
+ if(bit==64) bit=0xFF;
+ return bit;
+}
+
+///////////////////////////////////////////////////////////////
+// Capability pointers operation Including PCI Express...
+///////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPciCapPtrs()
+//
+// Description: This function will collect information about PCI "Device"
+// Capability Headers (Including PCI Express, Hot Plug and PCI-X/X2) and
+// record them.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When Device not present in the system.
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When some of the parameters - invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetPciCapPtrs(PCI_DEV_INFO *Device)
+{
+ PCI_CFG_ADDR devaddr;
+ EFI_STATUS Status=0;
+ EFI_PCI_CAPABILITY_HDR cp;
+ UINT16 sr;
+//-------------------------------
+ devaddr.ADDR=Device->Address.ADDR;
+ devaddr.Addr.Register=0x06; //Status Register;
+ //bit 4 in status register is set if device supports capabilities pointer
+ Status=PciCfg16(Device->RbIo,devaddr,FALSE,&sr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ if(!(sr&0x10)) return Status; //no reason to continue - capabilities is not supported!
+
+ //if device Supports Capabilityes
+ cp.CAP_HDR=0;
+ if(Device->Type==tPci2CrdBrg) devaddr.Addr.Register=EFI_PCI_CARDBUS_BRIDGE_CAPABILITY_PTR;
+ else devaddr.Addr.Register=EFI_PCI_CAPABILITY_PTR;
+
+ Status=PciCfg8(Device->RbIo,devaddr,FALSE,&cp.NextItemPtr);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //we got something here.
+ while(cp.NextItemPtr)
+ {
+ devaddr.Addr.Register=cp.NextItemPtr;
+
+ Status=PciCfg16(Device->RbIo,devaddr,FALSE,&cp.CAP_HDR);
+ ASSERT_EFI_ERROR(Status);
+ if(cp.CapabilityID==PCI_CAP_ID_PMI) Device->PmiCapOffs=devaddr.Addr.Register;
+
+//Enables PCI Express Handling only if PCI Express Base is Defined and !=0
+#if PCI_EXPRESS_SUPPORT
+
+ if(cp.CapabilityID==PCI_CAP_ID_PCIEXP){
+ Device->PciExpress=MallocZ(sizeof(PCIE_DATA));
+ ASSERT(Device->PciExpress);
+ if(!Device->PciExpress) return EFI_OUT_OF_RESOURCES;
+
+ //Save Current Offset of PCIE Std Compatibility Registers Block
+ Device->PciExpress->PcieOffs=devaddr.Addr.Register;
+ Device->PciExpress->Owner=Device;
+ }
+#endif
+
+#if HOTPLUG_SUPPORT
+ if(cp.CapabilityID==PCI_CAP_ID_HOTPLUG){
+ //we may process this controller as root HPC so check that.
+ if(!Device->HotPlug){
+ Device->HotPlug=MallocZ(sizeof(PCI_HPC_INFO));
+ ASSERT(Device->HotPlug);
+ if(!Device->HotPlug) return EFI_OUT_OF_RESOURCES;
+
+ //Save Current Offset of PCIE Std Compatibility Registers Block
+ Device->HotPlug->HpcLocation->HpcDevicePath=Device->DevicePath;
+ Device->HotPlug->HpcLocation->HpcDevicePath=Device->DevicePath;
+ Device->HotPlug->HpcPciAddr.ADDR=Device->Address.ADDR;
+ Device->HotPlug->HpbBridge=Device;
+ Device->HotPlug->BusFound=TRUE;
+ //For SHPC it must be initialized and enabled by hardware
+ Device->HotPlug->HpcState=EFI_HPC_STATE_INITIALIZED|EFI_HPC_STATE_ENABLED;
+ Device->HotPlug->HpcOffs=devaddr.Addr.Register;
+ Device->HotPlug->Owner=Device;
+ }
+ }
+#endif
+
+//this is for feautufe use if we will support BootTime hotplug events
+#if PCI_X_SUPPORT
+ if(cp.CapabilityID==PCI_CAP_ID_PCIX){
+
+ Device->PciX=MallocZ(sizeof(PCIX_DATA));
+ ASSERT(Device->PciX);
+ if(!Device->PciX) return EFI_OUT_OF_RESOURCES;
+
+ //fill out fields within PciX structure
+ devaddr.Addr.Register=Device->PciX->PcixOffs+PCIX_DEV_STA_OFFSET;
+ Status=PciCfg32(Device->RbIo, devaddr, FALSE, &Device->PciX->PcixDevStatus.DEV_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ devaddr.Addr.Register=Device->PciX->PcixOffs+PCIX_SEC_STA_OFFSET;
+ Status=PciCfg16(Device->RbIo, devaddr, FALSE, &Device->PciX->PcixSecStatus.SEC_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ Device->PciX->PcixOffs=devaddr.Addr.Register;
+ Device->PciX->Owner=Device;
+
+ }
+#endif
+ }
+ return Status;
+}
+
+//----------------------------------------------------------------------------
+//Enable PCI Express Handling only if PCI Express Base is Defined and !=0
+#if PCI_EXPRESS_SUPPORT
+//////////////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------
+// PCI Express Helper Functions
+//----------------------------------------------------------------------------
+//////////////////////////////////////////////////////////////////////////////
+EFI_STATUS PcieDoubleCheckCard(PCI_DEV_INFO *Brg, PCI_CFG_ADDR *DevAddr, UINT32 *VenDevId){
+ EFI_STATUS Status;
+ PCI_CFG_ADDR addr;
+ PCIE_SLT_STA_REG slts;
+// PCIE_LNK_STA_REG lnks;
+// PCIE_DEV_STA_REG devs;
+//------------------------
+
+
+ //Read PCIe.DEV_STA_REG;
+ addr.ADDR=Brg->Address.ADDR;
+/*
+ addr.Addr.Register=Brg->PciExpress->PcieOffs+PCIE_DEV_STA_OFFSET;
+ Status=PciCfg16(Brg->RbIo, addr, FALSE, &devs.DEV_STA);
+ ASSERT_EFI_ERROR(Status);
+
+ //Read PCIe.LNK_STA_REG;
+ addr.Addr.Register=Brg->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+ Status=PciCfg16(Brg->RbIo, addr, FALSE, &lnks.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+*/
+ //Read PCIe.SLT_STA_REG;
+ addr.Addr.Register=Brg->PciExpress->PcieOffs+PCIE_SLT_STA_OFFSET;
+ Status=PciCfg16(Brg->RbIo, addr, FALSE, &slts.SLT_STA);
+ ASSERT_EFI_ERROR(Status);
+
+/*
+ TRACE((-1, "\n!!!!!!DEV_STA[ 0x%X ].TrasactPend(5)=%d;\n",devs.DEV_STA, devs.TrasactPend));
+ TRACE((-1, "!!!!!!LNK_STA[0x%X].LnkTraining(11)=%d;\n",lnks.LNK_STA, lnks.LnkTraining));
+ TRACE((-1, "!!!!!!SLT_STA[%X].CardPresent(6)=%d;\n",slts.SLT_STA, slts.CardPresent));
+ TRACE((-1, "!!!!!!for the BRIDGE @ [B%X|D%X|F%X];\n",Brg->Address.Addr.Bus,Brg->Address.Addr.Device, Brg->Address.Addr.Function));
+ TRACE((-1, "!!!!!!VID/DID=%X of [B%X|D0|F0]\n",*VenDevId, addr.Addr.Bus));
+*/
+
+ //if we are here that means card did not come up first time...
+ //so try to read it one more time, before taking some invasive actions.
+ addr.ADDR = DevAddr->ADDR;
+ addr.Addr.Register=0;
+
+ //SOMETHING present there, but need some time to completely come up
+ if(slts.CardPresent != 0 || slts.PresenceDet !=0 ){
+ UINTN i;
+ //---------
+ for(i=0; i<=gPciSetupData->LnkTrRetry; i++){
+
+ Status=PciCfg32(Brg->RbIo, addr, FALSE, VenDevId);
+ ASSERT_EFI_ERROR(Status);
+ if( (*VenDevId) != 0xFFFFFFFF ) break;
+
+ //Use same setup value for retry timeut and number
+ pBS->Stall(gPciSetupData->LnkTrTimeout*100);
+ }
+// TRACE((-1, "!!!!!!VID/DID=%X after %d retry (timeout=%d) \n",*VenDevId, i+1, gPciSetupData->LnkTrTimeout*100));
+ }
+
+ //If nothing workeded just exit...
+ return Status;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+//Exclude support fot PCIe GEN2 to save space in projects w/o PCIE_GEN2
+#if PCI_EXPRESS_GEN2_SUPPORT
+
+
+///////////////////////////////////////////////////////////////////////////////
+//Exclude support fot PCIe GEN3 to save space in projects w/o PCIE_GEN3
+#if PCI_EXPRESS_GEN3_SUPPORT //GEN3 support is a subset of GEN2 support!!!
+
+EFI_STATUS Pcie3EqualizeLink(PCI_DEV_INFO *Device, BOOLEAN *LnkRetrain){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_CFG_ADDR addr;
+ PCIE_LNK_CNT3_REG LnkCnt3;
+ PCIE_LNK_STA2_REG LnkSta2;
+//-----------------------------
+
+ //If device don't have GEN 3 Cap Hdr, or link is operating on lell then 8.0 GT/s speed - just exit...
+ if(Device->PciExpress->Pcie3==NULL) return EFI_SUCCESS;
+
+ //Get LNK_STA2 regiser
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_STA2_OFFSET;
+ Status=PciCfg16(Device->RbIo, addr, FALSE,&LnkSta2.LNK_STA2);
+ ASSERT_EFI_ERROR(Status);
+
+ //Display Content of the LNK_STA2 register.
+ PCI_TRACE((TRACE_PCI," LNK_STA2-> [R=%X|EqReq=%X|EqP3=%X|EqP2=%X|EqP1=%X|EqCompl=%X|SelDeEmp=%X]\n",
+ LnkSta2.Reserved,
+ LnkSta2.EqRequest,
+ LnkSta2.EqPhase3Ok,
+ LnkSta2.EqPhase2Ok,
+ LnkSta2.EqPhase1Ok,
+ LnkSta2.EqComplete,
+ LnkSta2.SelDeEmphasis));
+
+ //Check if equalization was requested or we are about to enter lLNK training session...
+ if(LnkSta2.EqRequest || *LnkRetrain){
+
+ PCI_TRACE((TRACE_PCI," PciE3: Equalization for Device @ [B%X|D%X|F%X] LnkRetrain=%X Before\n",
+ addr.Addr.Bus,addr.Addr.Device,addr.Addr.Function, *LnkRetrain));
+ //read Lnk Control 3 register in Sec PCIe Ext Cap Header.
+ addr.Addr.ExtendedRegister=Device->PciExpress->Pcie3->SecPcieCapOffs+PCIE_LNK_CNT3_OFFSET;
+ Status=PciCfg32(Device->RbIo, addr, FALSE,&LnkCnt3.LNK_CNT3);
+ ASSERT_EFI_ERROR(Status);
+
+ //Set Prform Equalization bit and disable Equalization Request Interrupt, just in case.
+ LnkCnt3.LnkEqReqIntEn=0;
+ LnkCnt3.PerformEqualiz=1;
+
+ //Write it back into LNK_CNT3 register.
+ Status=PciCfg32(Device->RbIo, addr, TRUE, &LnkCnt3.LNK_CNT3);
+ ASSERT_EFI_ERROR(Status);
+
+ *LnkRetrain=TRUE;
+
+ //Display Content of the LNK_CNT3 register.
+ PCI_TRACE((TRACE_PCI," LNK_CNT3-> [R=%X|LnkEqReqIntEn=%X|DoEq=%X] LnkRetrain=%X After\n",
+ LnkCnt3.Reserved,
+ LnkCnt3.LnkEqReqIntEn,
+ LnkCnt3.PerformEqualiz,
+ *LnkRetrain));
+
+ }
+ return Status;
+}
+
+
+EFI_STATUS Pcie3GetEqualizationStatus(PCI_DEV_INFO *Device){
+ PCI_CFG_ADDR addr;
+ PCIE_LNK_STA2_REG LnkSta2;
+ EFI_STATUS Status=EFI_SUCCESS;
+//-----------------------------
+
+ //If device don't have GEN 3 Cap Hdr, or link is operating on lell then 8.0 GT/s speed - just exit...
+ if(Device->PciExpress->Pcie3==NULL) return EFI_SUCCESS;
+
+ //Get LNK_STA2 regiser
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_STA2_OFFSET;
+ Status=PciCfg16(Device->RbIo, addr, FALSE,&LnkSta2.LNK_STA2);
+ ASSERT_EFI_ERROR(Status);
+
+ //Display Content of the LNK_STA2 register.
+ PCI_TRACE((TRACE_PCI,"Pcie3-> Checking Equalization Status...\n LNK_STA2-> [R=%X|EqReq=%X|EqP3=%X|EqP2=%X|EqP1=%X|EqCompl=%X|SelDeEmp=%X]\n",
+ LnkSta2.Reserved,
+ LnkSta2.EqRequest,
+ LnkSta2.EqPhase3Ok,
+ LnkSta2.EqPhase2Ok,
+ LnkSta2.EqPhase1Ok,
+ LnkSta2.EqComplete,
+ LnkSta2.SelDeEmphasis));
+
+ //Check equalization sesults...
+ if (LnkSta2.EqComplete) return EFI_SUCCESS;
+
+ //Check if any of the equalization phases were completed...
+ if(LnkSta2.LNK_STA2 & 0x1C) return EFI_NOT_AVAILABLE_YET;
+
+ return EFI_DEVICE_ERROR;
+}
+
+#endif //GEN3
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Pcie2GetGen2Info()
+//
+// Description: This function will collect information about PCIE GEN2 Device
+// and initialize PCIE2_DATA structure based on information collected.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Pcie2GetGen2Info(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_CFG_ADDR addr;
+//-----------------------------
+ addr.ADDR=Device->Address.ADDR;
+ //PCI_TRACE((TRACE_PCI," PciE2: Device @ [B%X|D%X|F%X] is PCIE GEN2 Device:\n",
+ // addr.Addr.Bus,addr.Addr.Device,addr.Addr.Function));
+
+ //Get PCI Express Device CAP2 - 32 bit
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_DEV_CAP2_OFFSET;
+ Status=PciCfg32(Device->RbIo, addr, FALSE,&Device->PciExpress->Pcie2->DeviceCap2.DEV_CAP2);
+ ASSERT_EFI_ERROR(Status);
+
+ PCI_TRACE((TRACE_PCI," DEV_CAP2-> [R2=%X|MEEP=%X|EETP=%X|EFF=%X|R1=%X|TPH=%X|LTR=%X|NRP=%X|C128=%X|AtC64=%X|AtC32=%X|AtR=%X|Ari=%d|CTD=%X|CmTO=%X]\n",
+ Device->PciExpress->Pcie2->DeviceCap2.Reserved2,
+ Device->PciExpress->Pcie2->DeviceCap2.MaxEndEndPrefix,
+ Device->PciExpress->Pcie2->DeviceCap2.EndEndTlpPrefix,
+ Device->PciExpress->Pcie2->DeviceCap2.ExtFmtField,
+ Device->PciExpress->Pcie2->DeviceCap2.Reserved1,
+ Device->PciExpress->Pcie2->DeviceCap2.TphCompleter,
+ Device->PciExpress->Pcie2->DeviceCap2.LtrMechanism,
+ Device->PciExpress->Pcie2->DeviceCap2.NoRoPrPrPassing,
+ Device->PciExpress->Pcie2->DeviceCap2.Cas128Completer,
+ Device->PciExpress->Pcie2->DeviceCap2.AtomicOpCompl64,
+ Device->PciExpress->Pcie2->DeviceCap2.AtomicOpCompl32,
+ Device->PciExpress->Pcie2->DeviceCap2.AtomicOpRouting,
+ Device->PciExpress->Pcie2->DeviceCap2.AriForwarding,
+ Device->PciExpress->Pcie2->DeviceCap2.ComplToutDisable,
+ Device->PciExpress->Pcie2->DeviceCap2.ComplToutRanges));
+
+ //Get PCI Express Link CAP2 - 32 bit
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CAP2_OFFSET;
+ Status=PciCfg32(Device->RbIo, addr, FALSE,&Device->PciExpress->Pcie2->LinkCap2.LNK_CAP2);
+ ASSERT_EFI_ERROR(Status);
+
+ if(Device->PciExpress->PcieCap.SlotImpl){
+ //Get PCI Express Link SLOT2 - 32 bit
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_SLT_CAP2_OFFSET;
+ Status=PciCfg32(Device->RbIo, addr, FALSE,&Device->PciExpress->Pcie2->SlotCap2.SLT_CAP2);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#if PCI_EXPRESS_GEN3_SUPPORT
+ //Do some additional checks if device has GEN 3 Secondary PCIe Cap Header.
+ //At that point if we have discovered Sec PCIe Cap HDR Defice->PciExpress->Pcie3 must be initializad.
+ if(Device->PciExpress->Pcie3 != NULL){
+
+
+ //Update Speed encoding it is defined differently for devices Supporting V3.0 spec.
+
+ Device->PciExpress->Pcie3->MaxLanesCount=Device->PciExpress->LinkCap.MaxLnkWidth;
+
+ //Display first LNK_CAP2_REG
+ PCI_TRACE((TRACE_PCI,"PCIe3 -> Device is PCIe v3.0 Compliant!!! LNK_CAP2 present!!! \n LNK_CAP2-> [R2=%X|CrossL=%X|SuppLnkSpeedVect=%X|R1=%X]; LANE_ERR_STA->[%X]; MaxLanes=%X\n",
+ Device->PciExpress->Pcie2->LinkCap2.Reserved2,
+ Device->PciExpress->Pcie2->LinkCap2.CrossLnk,
+ Device->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds,
+ Device->PciExpress->Pcie2->LinkCap2.Reserved1,
+ Device->PciExpress->Pcie3->LaneErrSts,
+ Device->PciExpress->Pcie3->MaxLanesCount));
+
+ }
+#endif
+
+ Device->PciExpress->Pcie2->Owner=Device;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Pcie2EnableAri()
+//
+// Description: This function will Enable ARI Forwarding in DownSream Port of
+// the device passed if
+// 1.Device referenced is an ARI device;
+// 2.Parenting Bridge supports ARI Forwarding.
+// 3.ARI Firvarding Setup Question Set to "Enabled"
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When Device or Parenting Bridge does not support ARI
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Pcie2EnableAri(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_DEV_INFO *brg;
+ PCI_CFG_ADDR addr;
+ PCIE_DEV_CNT2_REG dcnt2;
+//-----------------------------------
+ //Setup Don't have it enabled
+ if(gPciSetupData->AriFwd == 0) {
+ PCI_TRACE((TRACE_PCI," -> Setup=%d", gPciSetupData->AriFwd));
+ return EFI_UNSUPPORTED;
+ }
+
+ if(Device->Type != tPciDevice) {
+ PCI_TRACE((TRACE_PCI," -> not tDevice Type", gPciSetupData->AriFwd));
+ return EFI_UNSUPPORTED;
+ }
+
+ if(Device->PciExpress == NULL) {
+ PCI_TRACE((TRACE_PCI," -> not PCIe Device", gPciSetupData->AriFwd));
+ return EFI_UNSUPPORTED;
+ }
+
+ //Device don't have ARI Ext Cap
+ if(Device->PciExpress->AriData==NULL){
+ PCI_TRACE((TRACE_PCI," -> non-ARI Device"));
+ return EFI_UNSUPPORTED;
+ }
+ //If we are here - device is an ARI Device. Now check if Parenting Bridge can do it...
+ brg=Device->ParentBrg;
+ //Check if Parenting Brg is Gen 2 device
+ if(brg->PciExpress->Pcie2==NULL){
+ PCI_TRACE((TRACE_PCI," -> ParentBrg non-GEN2"));
+ return EFI_UNSUPPORTED;
+ }
+
+ //Check if bridge can do ARI Forvarding
+ if(brg->PciExpress->Pcie2->DeviceCap2.AriForwarding==0){
+ PCI_TRACE((TRACE_PCI," -> ParentBrg.Cap.AriFwd=0"));
+ return EFI_UNSUPPORTED;
+ }
+
+ //Now check if this bridge has ARI Forwarding Enabled allready
+ if(brg->PciExpress->Pcie2->AriEnabled==TRUE){
+ //Set Device ARI Falg
+ Device->PciExpress->Pcie2->AriEnabled=brg->PciExpress->Pcie2->AriEnabled;
+ PCI_TRACE((TRACE_PCI," -> Parent Bridge AriEnabled=1"));
+ return EFI_SUCCESS;
+ }
+
+ //At that Point we must enable ARI.
+ addr.ADDR=brg->Address.ADDR;
+ addr.Addr.Register=brg->PciExpress->PcieOffs+PCIE_DEV_CNT2_OFFSET;
+ Status=PciCfg16(brg->RbIo, addr, FALSE,&dcnt2.DEV_CNT2);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ dcnt2.AriForwarding=TRUE;
+ PCI_TRACE((TRACE_PCI," ARI -> Enabling ARI for Parent Bridge!"));
+ Status=PciCfg16(Device->RbIo, addr, TRUE,&dcnt2.DEV_CNT2);
+ ASSERT_EFI_ERROR(Status);
+
+
+ if(EFI_ERROR(Status)) return Status;
+
+ Device->PciExpress->Pcie2->AriEnabled=(BOOLEAN)dcnt2.AriForwarding;
+ brg->PciExpress->Pcie2->AriEnabled=(BOOLEAN)dcnt2.AriForwarding;
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Pcie2CheckAri()
+//
+// Description: This function will Enable ARI Forwarding in DownSream Port of
+// the device passed if
+// 1.Device referenced is an ARI device;
+// 2.Parenting Bridge supports ARI Forwarding.
+// 3.ARI Firvarding Setup Question Set to "Enabled"
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// BOOLEAN *MultiFunc Pointer to a Flag to modify if Device is MF Device
+// BOOLEAN *AriEnabled Pointer to a Flag to modify if this function was able to ENABLE ARI.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Pcie2CheckAri(PCI_DEV_INFO *Device, BOOLEAN *MultiFunc, BOOLEAN *AriEnabled){
+ EFI_STATUS Status;
+//--------------------
+ PCI_TRACE((TRACE_PCI," PciE2: Checking ARI @ [B%X|D%X|F%X]:",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function));
+
+ Status=Pcie2EnableAri(Device);
+ PCI_TRACE((TRACE_PCI," Status=%r\n",Status));
+
+ if((!EFI_ERROR(Status)) &&
+ (Device->PciExpress->AriData!=NULL) &&
+ (Device->PciExpress->Pcie2->AriEnabled==TRUE))
+ {
+ *MultiFunc=TRUE;
+ *AriEnabled=TRUE;
+ } else {
+ if(Status==EFI_UNSUPPORTED){
+ *AriEnabled=FALSE;
+ Status=EFI_SUCCESS;
+ }
+ }
+
+ //PCI_TRACE((TRACE_PCI," AriEn=%d %r\n\n",*AriEnabled, Status));
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Pcie2SetLnkProperties()
+//
+// Description: This function will Select values for Link Control2 register on
+// both sides of the LINK based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *DnStreamPort Pointer to PCI Device Private Data of Downstream Port of the link.
+// PCIE_LNK_CNT2_REG *DnLnkCnt2 Pointer to the LNK_CNT2 Reg of the Downstream Port of the link.
+// PCI_DEV_INFO *UpStreamPort Pointer to PCI Device Private Data of Upwnstream Port of the link.
+// PCIE_LNK_CNT2_REG *UpLnkCnt2 Pointer to the LNK_CNT2 Reg of the Downstream Port of the link.
+// BOOLEAN *LinkHotResetRequired Flag to modify if Link will need HOT RESET after programming.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Pcie2SetLnkProperties(PCI_DEV_INFO *DnStreamPort,
+ PCIE_LNK_CNT2_REG *DnLnkCnt2,
+ PCI_DEV_INFO *UpStreamPort,
+ PCIE_LNK_CNT2_REG *UpLnkCnt2,
+ BOOLEAN *LinkHotResetRequired,
+ BOOLEAN *LinkRetrainRequired )
+{
+ EFI_STATUS Status;
+ PCIE_LNK_STA_REG dnls, upls; //link status reg content of up and down side of the link
+ PCI_CFG_ADDR addr;
+ UINT16 ls, maxls, curls;//link speed variables
+//------------------------------
+
+ PCI_TRACE((TRACE_PCI,"PciE2: Pcie2SetLnkProperties() ENTRY:\n"));
+
+ //Get DownStream Port Properties
+ addr.ADDR=DnStreamPort->Address.ADDR;
+
+ PCI_TRACE((TRACE_PCI," DN STREAM PORT -> [B%X|D%X|F%X] <--> [B%X|D%X|F%X] <- UP STREAM PORT\n",
+ DnStreamPort->Address.Addr.Bus,DnStreamPort->Address.Addr.Device, DnStreamPort->Address.Addr.Function,
+ UpStreamPort->Address.Addr.Bus,UpStreamPort->Address.Addr.Device, UpStreamPort->Address.Addr.Function));
+
+ addr.Addr.Register=DnStreamPort->PciExpress->PcieOffs+PCIE_LNK_CNT2_OFFSET;
+ Status=PciCfg16(DnStreamPort->RbIo,addr,FALSE, &DnLnkCnt2->LNK_CNT2);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT2-> [CmDe=%X|CmSOS=%X|ECm=%X|TrM=%X|SlDe=%X|AuSp=%X|EnCm=%X|TLS=%X]\n",
+ DnLnkCnt2->ComplDeEmphasis,
+ DnLnkCnt2->ComplianceSos,
+ DnLnkCnt2->EnterModCompl,
+ DnLnkCnt2->TrsMargin,
+ DnLnkCnt2->SelDeEmphasis,
+ DnLnkCnt2->HwAutoSpeedDis,
+ DnLnkCnt2->EnterCompliance,
+ DnLnkCnt2->TargetLnkSpeed));
+
+
+ addr.Addr.Register=DnStreamPort->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+ Status=PciCfg16(DnStreamPort->RbIo,addr,FALSE, &dnls.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Get UpStream Stream Port Properties
+ addr.ADDR=UpStreamPort->Address.ADDR;
+
+ //PCI_TRACE((TRACE_PCI," UP STREAM PORT @ [B%X|D%X|F%X]:\n",
+ // addr.Addr.Bus,addr.Addr.Device, addr.Addr.Function));
+
+ addr.Addr.Register=UpStreamPort->PciExpress->PcieOffs+PCIE_LNK_CNT2_OFFSET;
+ Status=PciCfg16(UpStreamPort->RbIo,addr,FALSE, &UpLnkCnt2->LNK_CNT2);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT2-> [CmDe=%X|CmSOS=%X|ECm=%X|TrM=%X|SlDe=%X|AuSp=%X|EnCm=%X|TLS=%X]\n ....... UPDATINNG .......\n",
+ UpLnkCnt2->ComplDeEmphasis,
+ UpLnkCnt2->ComplianceSos,
+ UpLnkCnt2->EnterModCompl,
+ UpLnkCnt2->TrsMargin,
+ UpLnkCnt2->SelDeEmphasis,
+ UpLnkCnt2->HwAutoSpeedDis,
+ UpLnkCnt2->EnterCompliance,
+ UpLnkCnt2->TargetLnkSpeed));
+
+ //Get Lnk Status Content...
+ addr.Addr.Register=UpStreamPort->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+ Status=PciCfg16(UpStreamPort->RbIo,addr,FALSE, &upls.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ //Check link Speed selected in Setup and calculate applcable Link speed...
+ //get max possible link speed
+ maxls=DnStreamPort->PciExpress->LinkCap.MaxLnkSpeed;
+ if(maxls>UpStreamPort->PciExpress->LinkCap.MaxLnkSpeed) maxls=UpStreamPort->PciExpress->LinkCap.MaxLnkSpeed;
+
+ //get the current speed of the link...
+ curls=DnStreamPort->PciExpress->CurrLnkSpeed;
+ //must be the same on both sides of the link
+ ASSERT(curls==UpStreamPort->PciExpress->CurrLnkSpeed);
+
+ if(maxls>=PCIE_LINK_SPEED_80G){
+ if(DnStreamPort->PciExpress->Pcie3==NULL || UpStreamPort->PciExpress->Pcie3==NULL)
+ maxls=PCIE_LINK_SPEED_50G;
+ }
+
+ //Check Link Speed setup options...
+ //AUTO==55
+ ls=curls;
+ if(gPciSetupData->LnkSpeed==55)ls=maxls;
+
+ //Force 5.0GT/s == 2
+ if(gPciSetupData->LnkSpeed==2){
+ //check if it is supported
+ if(DnStreamPort->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds!=0){
+ //if device is compatible with V3.0 spec it must report supported speeds
+ if(DnStreamPort->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds & PCIE_LINK_SPEED_VECT_50G) ls=PCIE_LINK_SPEED_50G;
+ } else {
+ //for devices compliand to spec v 2.1 check maxls value
+ if(maxls>=PCIE_LINK_SPEED_50G) ls=PCIE_LINK_SPEED_50G;
+ }
+ }
+
+ //Force 2.5GT/s == 1
+ if(gPciSetupData->LnkSpeed==1){
+ //check if it is supported
+ if(DnStreamPort->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds!=0){
+ //if device is compatible with V3.0 spec it must report supported speeds
+ if(DnStreamPort->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds & PCIE_LINK_SPEED_VECT_25G)ls=PCIE_LINK_SPEED_25G;
+ } else {
+ //for devices compliand to spec v 2.1 check maxls value
+ if(maxls>=PCIE_LINK_SPEED_25G) ls=PCIE_LINK_SPEED_25G;
+ }
+ }
+
+ PCI_TRACE((TRACE_PCI," LNK SPEED SETTINGS: MaxLS=%X; CurrentLS=%X; SelectedLS=%X; Setup=%d\n",
+ maxls,curls,ls, gPciSetupData->LnkSpeed ));
+
+ //Call porting hook to override link speed settings.
+ Status=PciPortOemSetLnkSpeed(DnStreamPort, (UINT8*)&ls, (UINT8)DnStreamPort->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds);
+ //one more time for Upstreamport
+ Status=PciPortOemSetLnkSpeed(UpStreamPort, (UINT8*)&ls, (UINT8)UpStreamPort->PciExpress->Pcie2->LinkCap2.SuppLnkSpeeds);
+
+ //now check if curls different from ls
+ if(ls<curls){
+// DnLnkCnt2->EnterCompliance=TRUE;
+// UpLnkCnt2->EnterCompliance=TRUE;
+// *LinkHotResetRequired=TRUE;
+ *LinkRetrainRequired=TRUE;
+ }
+
+ if(ls>curls){
+ *LinkRetrainRequired=TRUE;
+// *LinkHotResetRequired=TRUE;
+ }
+
+ //Set selected speed on both sides of the link
+ DnLnkCnt2->TargetLnkSpeed=ls;
+ UpLnkCnt2->TargetLnkSpeed=ls;
+
+ //Check; HwAutoSpeedDis; HwAutoWidth settings
+ DnLnkCnt2->HwAutoSpeedDis=gPciSetupData->HwAutoSpeed;
+ UpLnkCnt2->HwAutoSpeedDis=gPciSetupData->HwAutoSpeed;
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT2-> [CmDe=%X|CmSOS=%X|ECm=%X|TrM=%X|SlDe=%X|AuSp=%X|EnCm=%X|TLS=%X]\n",
+ DnLnkCnt2->ComplDeEmphasis,
+ DnLnkCnt2->ComplianceSos,
+ DnLnkCnt2->EnterModCompl,
+ DnLnkCnt2->TrsMargin,
+ DnLnkCnt2->SelDeEmphasis,
+ DnLnkCnt2->HwAutoSpeedDis,
+ DnLnkCnt2->EnterCompliance,
+ DnLnkCnt2->TargetLnkSpeed));
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT2-> [CmDe=%X|CmSOS=%X|ECm=%X|TrM=%X|SlDe=%X|AuSp=%X|EnCm=%X|TLS=%X]\n\n",
+ UpLnkCnt2->ComplDeEmphasis,
+ UpLnkCnt2->ComplianceSos,
+ UpLnkCnt2->EnterModCompl,
+ UpLnkCnt2->TrsMargin,
+ UpLnkCnt2->SelDeEmphasis,
+ UpLnkCnt2->HwAutoSpeedDis,
+ UpLnkCnt2->EnterCompliance,
+ UpLnkCnt2->TargetLnkSpeed));
+
+
+#if PCI_EXPRESS_GEN3_SUPPORT
+ if(DnStreamPort->PciExpress->Pcie3!=NULL && UpStreamPort->PciExpress->Pcie3!=NULL){
+
+ if(ls >=PCIE_LINK_SPEED_80G) {
+ Status=Pcie3EqualizeLink(DnStreamPort, LinkRetrainRequired);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ //Equalize link must be set for Upstream Port if it has closslink
+ if(UpStreamPort->PciExpress->Pcie2->LinkCap2.CrossLnk){
+ Status=Pcie3EqualizeLink(UpStreamPort, LinkRetrainRequired);
+ ASSERT_EFI_ERROR(Status);
+ }
+ }
+ }
+#endif
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Pcie2SelectComplTimeOut()
+//
+// Description: This function will select appropriate Completion Timeout range
+// from supported by the device.
+//
+// Input:
+// UINT32 Support Supported by Device Completion Timeout ranges.
+// BOOLEAN Short A Flag to Indicate wahat type of ranges to select Biggest or Smallest
+//
+// Output: UINT16
+// Value to be programmed in DEV_CNT2 Register.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 Pcie2SelectComplTimeOut(UINT32 Support, BOOLEAN Short){
+ //Completion Timeout Programability is not supported by HW.
+ if(Support==0) return 0;
+
+ if(Short){
+ //It is strongly recommended that the Completion Timeout
+ //mechanism not expire in less than 10 ms
+
+ //Values available if Range A (50 mks to 10 ms) programmability range is supported:
+ // 0001b 50 mks to 100 mks; 0010b; 1 ms to 10 ms
+ if(Support & PCIE_CAP2_RANGE_A) return 0x2;
+
+ //Values available if Range B (10 ms to 250 ms) programmability range is supported:
+ // 0101b 16 ms to 55 ms; 0110b 65 ms to 210 ms
+ if(Support & PCIE_CAP2_RANGE_B) return 0x5;
+
+ //Values available if Range C (250 ms to 4 s) programmability range is supported:
+ // 1001b 260 ms to 900 ms; 1010b 1 s to 3.5 s
+ if(Support & PCIE_CAP2_RANGE_C) return 0x9;
+
+ //Values available if the Range D (4 s to 64 s) programmability range is supported:
+ // 1101b 4 s to 13 s; 1110b 17 s to 64 s
+ if(Support & PCIE_CAP2_RANGE_D) return 0xD;
+
+ } else {
+ //Values available if the Range D (4 s to 64 s) programmability range is supported:
+ // 1101b 4 s to 13 s; 1110b 17 s to 64 s
+ if(Support & PCIE_CAP2_RANGE_D) return 0xE;
+
+ //Values available if Range C (250 ms to 4 s) programmability range is supported:
+ // 1001b 260 ms to 900 ms; 1010b 1 s to 3.5 s
+ if(Support & PCIE_CAP2_RANGE_C) return 0xA;
+
+ //Values available if Range B (10 ms to 250 ms) programmability range is supported:
+ // 0101b 16 ms to 55 ms; 0110b 65 ms to 210 ms
+ if(Support & PCIE_CAP2_RANGE_B) return 0x6;
+
+ //Values available if Range A (50 mks to 10 ms) programmability range is supported:
+ // 0001b 50 mks to 100 mks; 0010b; 1 ms to 10 ms
+ if(Support & PCIE_CAP2_RANGE_A) return 0x2;
+ }
+ return 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Pcie2SetDevProperties()
+//
+// Description: This function will Select values for DEVICE CCONTROL2 register
+// based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *DnStreamPort Pointer to PCI Device Private Data of Downstream Port of the link.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Pcie2SetDevProperties(PCI_DEV_INFO *Device){
+ EFI_STATUS Status;
+ PCI_CFG_ADDR addr;
+ PCIE_DEV_CNT2_REG dcnt2;
+//------------------------------
+
+ //Get Device Properties
+ addr.ADDR=Device->Address.ADDR;
+
+ PCI_TRACE((TRACE_PCI,"PciE2: Pcie2SetDevProperties() Device @ [B%X|D%X|F%X] ENTRY:\n",
+ addr.Addr.Bus,addr.Addr.Device, addr.Addr.Function));
+
+ if (Device->PciExpress == NULL)
+ return EFI_SUCCESS;
+
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_DEV_CNT2_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr, FALSE, &dcnt2.DEV_CNT2);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI," DEV_CNT2-> [EEPrB=%X|R=%X|LTR=%X|IDOCm=%X|IDORq=%X|AtEgB=%X|AtRq=%X|ARI=%X|CToD=%X|CTo=%X]\n ....... UPDATINNG .......\n",
+ dcnt2.EndEndTlpBlk,
+ dcnt2.Reserved,
+ dcnt2.LtrEn,
+ dcnt2.IdoComplEn,
+ dcnt2.IdoRequestEn,
+ dcnt2.AtomicOpEgresBlk,
+ dcnt2.AtomicOpRequer,
+ dcnt2.AriForwarding,
+ dcnt2.ComplToutDisable,
+ dcnt2.ComplToutRanges));
+
+ //Now check setup settingds and apply it. But do't touch ARI Forwarding it was updated earlier.
+ dcnt2.EndEndTlpBlk=gPciSetupData->E2ETlpPrBlk;
+ dcnt2.LtrEn=gPciSetupData->LtrReport;
+ dcnt2.IdoComplEn=gPciSetupData->IDOCompl;
+ dcnt2.IdoRequestEn=gPciSetupData->IDOReq;
+ dcnt2.AtomicOpEgresBlk=gPciSetupData->AtomOpEgressBlk;
+ dcnt2.AtomicOpRequer=gPciSetupData->AtomOpReq;
+
+ //Now check what ompletion Timeout ranges to select?
+ dcnt2.ComplToutDisable=FALSE;
+ dcnt2.ComplToutRanges=0; //set to default
+
+ //In Setup 0=Disable;0x55=SHORT; 0xAA=LONG; 0xFF=DEFAULT
+ if(gPciSetupData->ComplTimeOut == 0) dcnt2.ComplToutDisable=TRUE;
+ else {
+ if(gPciSetupData->ComplTimeOut == 0xFF) dcnt2.ComplToutRanges=0;
+ else{
+ //use SHORT timeout srom supported ranges option.
+ if(gPciSetupData->ComplTimeOut == 0x55)
+ dcnt2.ComplToutRanges=Pcie2SelectComplTimeOut(Device->PciExpress->Pcie2->DeviceCap2.ComplToutRanges, TRUE);
+ //use LONG timeout srom supported ranges option.
+ else
+ dcnt2.ComplToutRanges=Pcie2SelectComplTimeOut(Device->PciExpress->Pcie2->DeviceCap2.ComplToutRanges, FALSE);
+ }
+ }
+
+
+ Status=PciCfg16(Device->RbIo,addr, TRUE, &dcnt2.DEV_CNT2);
+
+ PCI_TRACE((TRACE_PCI," DEV_CNT2-> [EEPrB=%X|R=%X|LTR=%X|IDOCm=%X|IDORq=%X|AtEgB=%X|AtRq=%X|ARI=%X|CToD=%X|CTo=%X]\n\n",
+ dcnt2.EndEndTlpBlk,
+ dcnt2.Reserved,
+ dcnt2.LtrEn,
+ dcnt2.IdoComplEn,
+ dcnt2.IdoRequestEn,
+ dcnt2.AtomicOpEgresBlk,
+ dcnt2.AtomicOpRequer,
+ dcnt2.AriForwarding,
+ dcnt2.ComplToutDisable,
+ dcnt2.ComplToutRanges));
+// PCI_TRACE((TRACE_PCI,"Status = %r.\n",Status));
+
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+
+
+
+
+
+
+
+
+
+#endif
+//GEN 2 Helper Functions END
+///////////////////////////////////////////////////////////////////////////////
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieUpdateClockPm()
+//
+// Description: This function will update Device's referenced as "Func0"
+// Clock Power Management based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *Func0 Pointer to PCI Device Private Data structure.
+// CNT_REG *LnkCnt Pointer to the Device's LNK_CNT register data.
+//
+// Output: NOTHING
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PcieUpdateClockPm(PCI_DEV_INFO *Func0, PCIE_LNK_CNT_REG *LnkCnt){
+ UINTN i;
+ PCI_DEV_INFO *dev;
+//------------------------
+ //Check if Clock PM was set for F0 than we need not to scam caps of the other devices.
+ if(LnkCnt->ClockPm == FALSE) return;
+ //we will come here if we get a multifunction NON-ARI device and Device Points @ Function 0
+ //"LnkCnt" has parameters filled in calculated for Func0 of a MF device.
+ //Func0->DevFunc[] includes all other functions except Func 0;
+ for(i=0; i<Func0->FuncCount; i++){
+ dev=Func0->DevFunc[i];
+ //For a non-ARI multi-Function device, power-managementconfiguration
+ //software must only Set this bit if all Functions of
+ //the multi-Function device indicate a 1b in the Clock Power
+ //Management bit of the Link Capabilities register. The
+ //component is permitted to use the CLKREQ# signal to power
+ //manage Link clock only if this bit is Set for all Functions.
+
+ //For ARI Devices, Clock Power Management is enabled solely by
+ //the setting in Function 0. The settings in the other Functions
+ //always return whatever value software programmed for each,
+ //but otherwise are ignored by the component.
+ if(dev->PciExpress->LinkCap.ClockPm == FALSE) {
+ LnkCnt->ClockPm=FALSE;
+ return;
+ }
+ }
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieDisableLink()
+//
+// Description: This function will Disable Link of DNSTREAM port referenced as
+// "Device" based on Setup Settings and hardware STATUS. Used to disable "EMPTY"
+// links to save some POWER or "Force" LINK to Disable state if Link can not be
+// trained correctly.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// BOOLEAN Force Flag to indicate to disable link unconditionally.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieDisableLink(PCI_DEV_INFO *Device, BOOLEAN Force){
+ EFI_STATUS Status=0;
+ PCI_CFG_ADDR addr;
+ PCIE_LNK_CNT_REG lcnt;
+ BOOLEAN val;
+//------------------------------------------
+
+ //Get Device Link Control Register
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+
+ Status=PciCfg16(Device->RbIo, addr, FALSE, &lcnt.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ if(Force)val=TRUE;
+ else val=gPciSetupData->LnkDisable;
+
+ //Program Link only if it different from what we have.
+ if((UINT8)lcnt.LnkDisable!=val){
+ lcnt.LnkDisable=val;
+ Status=PciCfg16(Device->RbIo, addr, TRUE, &lcnt.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieProgramLink()
+//
+// Description: This function will Program Link with provided VALUEs
+// trained correctly.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// UINT16 Data Value to put in LNK_CNT register
+// BOOLEAN Reg2 Flag to select LNK_CNT or LNK_CNT2 register.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PcieProgramLink(PCI_DEV_INFO *Device, UINT16 Data, BOOLEAN Reg2){
+ EFI_STATUS Status=0;
+ PCI_CFG_ADDR addr;
+//------------------------------------------
+
+ //Get DownStream Port Properties
+ addr.ADDR=Device->Address.ADDR;
+ if(Reg2)addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CNT2_OFFSET;
+ else addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+
+ Status=PciCfg16(Device->RbIo, addr, TRUE, &Data);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieResetLink()
+//
+// Description: This function will issue HOT RESET on a LINK referenced by "Device".
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieResetLink(PCI_DEV_INFO *Device, UINT8 LnkSpeed){
+ EFI_STATUS Status=0;
+ PCI_CFG_ADDR addr;
+ PCI_BRG_CNT_REG bcnt;
+ BOOLEAN lnkrst=TRUE;
+//--------------------------------
+ //For any Root or Switch Downstream Port, setting the Secondary Bus Reset bit of the Bridge
+ //Control register associated with the Port must cause a hot reset to be sent (see Section 4.2.4.7).
+
+ PCI_TRACE((TRACE_PCI," Link RESETING (LnkSpeed=0x%X)... ",LnkSpeed));
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.Register=PCI_BRIDGE_CNTL;
+
+#if PCI_EXPRESS_GEN3_SUPPORT
+ if(LnkSpeed>=PCIE_LINK_SPEED_80G){
+ Status=Pcie3EqualizeLink(Device, &lnkrst);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ //Read BRG_CNT_REG
+ Status=PciCfg16(Device->RbIo, addr, FALSE, &bcnt.BRG_CNT_REG);
+ ASSERT_EFI_ERROR(Status);
+
+ //ASSERT reset Signal
+ bcnt.SecBusReset=TRUE;
+ Status=PciCfg16(Device->RbIo, addr, TRUE, &bcnt.BRG_CNT_REG);
+ ASSERT_EFI_ERROR(Status);
+ pBS->Stall(PCI_T_RST);
+
+ //DE-ASSERT reset Signal
+ bcnt.SecBusReset=FALSE;
+ Status=PciCfg16(Device->RbIo, addr, TRUE, &bcnt.BRG_CNT_REG);
+ ASSERT_EFI_ERROR(Status);
+ PCI_TRACE((TRACE_PCI,"Status = %r.\n",Status));
+ pBS->Stall(PCI_T_RST_RECOVERY);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieRetrainLink()
+//
+// Description: This function will initiate LINK training of the
+// Down Stream Port referenced as "Device".
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// UINT16 Data Value to put in LNK_CNT register
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieRetrainLink(PCI_DEV_INFO *Device, UINT16 Data, UINT8 LnkSpeed){
+ EFI_STATUS Status=0;
+ PCI_CFG_ADDR staa, cnta;
+ PCIE_LNK_STA_REG sta;
+ PCIE_LNK_CNT_REG cnt;
+ UINTN i=0, j=0;
+ BOOLEAN ltok, lnkrt=TRUE;
+//-------------------------------------
+
+ PCI_TRACE((TRACE_PCI," Link RETRAINING...(LnkSpeed=0x%X); # of retry %d ",LnkSpeed, gPciSetupData->LnkTrRetry));
+
+ staa.ADDR=Device->Address.ADDR;
+ cnta.ADDR=Device->Address.ADDR;
+ cnta.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ staa.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+
+ Status=PciCfg16(Device->RbIo, cnta, FALSE, &cnt.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+#if PCI_EXPRESS_GEN3_SUPPORT
+ if(LnkSpeed>=PCIE_LINK_SPEED_80G){
+ Status=Pcie3EqualizeLink(Device, &lnkrt);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ //The above algorithm guarantees that Link training will be based on the Link control parameter
+ //settings that software intends.
+ for(i=0, ltok=FALSE; i<=gPciSetupData->LnkTrRetry; i++){
+ //1. Software sets the relevant Link control parameters to the desired settings without writing a 1b to
+ // the Retrain Link bit. (Was done before in PcieProgramLink routine)...
+
+ //2. Software polls the Link Training bit in the Link Status register until the value returned is 0b.
+ Status=PciCfg16(Device->RbIo, staa, FALSE, &sta.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto rEXIT;
+
+ if(sta.LnkTraining!=0){
+ for(j=0; j<=gPciSetupData->LnkTrRetry; j++){
+ Status=PciCfg16(Device->RbIo, staa, FALSE, &sta.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(sta.LnkTraining==0) break;
+ pBS->Stall(gPciSetupData->LnkTrTimeout);
+ }
+ }
+
+ //if stll link did not come from Recovery State
+ if(sta.LnkTraining!=0 && i>=gPciSetupData->LnkTrRetry){
+ PCI_TRACE((TRACE_PCI,"PciE: TRAINING FAILURE! Link can't exit Recovery State. Disabling Link!\n"));
+ Status=PcieDisableLink(Device, TRUE);
+ Status=EFI_DEVICE_ERROR;
+ ASSERT_EFI_ERROR(Status);
+ goto rEXIT;
+ } else PCI_TRACE((TRACE_PCI,"%d, ",i));
+
+
+ //3. Software writes a 1b to the Retrain Link bit without changing any other fields in the Link
+ // Control register.
+ cnt.RetrainLnk=TRUE;
+
+ Status=PciCfg16(Device->RbIo, cnta, TRUE, &cnt.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Workaround for devices which having Link Retrain bit "sticky"
+ //Spec says it always reads as "0".
+ Status=PciCfg16(Device->RbIo, cnta, FALSE, &cnt.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ if(cnt.RetrainLnk==TRUE){
+ cnt.RetrainLnk=FALSE;
+ Status=PciCfg16(Device->RbIo, cnta, TRUE, &cnt.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ //Pool link Status back again to make sure it trained well.
+ Status=PciCfg16(Device->RbIo, staa, FALSE, &sta.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto rEXIT;
+
+ if(sta.LnkTraining!=0){
+ for(j=0; j<gPciSetupData->LnkTrRetry; j++){
+ Status=PciCfg16(Device->RbIo, staa, FALSE, &sta.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(sta.LnkTraining==0) {
+ ltok=TRUE;
+ break;
+ }
+ pBS->Stall(gPciSetupData->LnkTrTimeout);
+ }
+ } else ltok=TRUE;
+
+
+ if(ltok) break;
+ }
+
+#if PCI_EXPRESS_GEN3_SUPPORT
+ if(LnkSpeed>=PCIE_LINK_SPEED_80G){
+ Status=Pcie3GetEqualizationStatus(Device);
+ if(EFI_ERROR(Status)){
+ //if equalization did not went trough retry it
+ if(Status==EFI_DEVICE_ERROR) {
+ PCI_TRACE((TRACE_PCI," EQ_STS=%r; ", Status));
+ }
+ Status=EFI_SUCCESS;
+ }
+ }
+#endif
+
+rEXIT:
+ PCI_TRACE((TRACE_PCI," %r\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieSetSlotProperties()
+//
+// Description: This function will Initialize SLT_CNT and SLT_STA registers
+// of the "Device".
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieSetSlotProperties(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_CFG_ADDR addr;
+ PCIE_SLT_CNT_REG sltc;
+ PCIE_SLT_STA_REG slts;
+//--------------------------------
+
+ PCI_TRACE((TRACE_PCI," PciE: PcieSetSlotProperties() SlotImpl=%d -> ",Device->PciExpress->PcieCap.SlotImpl));
+
+ if(Device->PciExpress->PcieCap.SlotImpl==TRUE){
+ addr.ADDR=Device->Address.ADDR;
+
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_SLT_CNT_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&sltc.SLT_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_SLT_STA_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&slts.SLT_STA);
+ ASSERT_EFI_ERROR(Status);
+
+ sltc.AttnBtnPress=0;
+ sltc.PowerFaul=0;
+ sltc.MrlSensor=0;
+ sltc.PresenceDet=0;
+ sltc.CmdCompleted=0;
+ sltc.HpIntEnable=0;
+ sltc.DllStatChEn=0;
+
+
+ //Clear all RW1C bits in status reg...
+ slts.AttnBtnPress=1;
+ slts.PowerFaul=1;
+ slts.MrlSensor=1;
+ slts.PresenceDet=1;
+ slts.CmdCompleted=1;
+ slts.DllStateChg=1;
+
+
+ //Power Up slot and set all possible indication on...
+ if(Device->PciExpress->SlotCap.AttnInd) sltc.AttnIndCnt=PCIE_SLT_INDICATOR_ON;
+ if(Device->PciExpress->SlotCap.PowerInd)sltc.PowerIndCnt=PCIE_SLT_INDICATOR_ON;
+ if(Device->PciExpress->SlotCap.PwrCntler)sltc.PowerOff=PCIE_SLT_PWR_ON;
+
+ Status=PciCfg16(Device->RbIo,addr,TRUE,&slts.SLT_STA);
+
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_SLT_CNT_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,TRUE,&sltc.SLT_CNT);
+ }
+ PCI_TRACE((TRACE_PCI,"%r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieGetCaps()
+//
+// Description: This function will Collect PCI Express Capabilities Data
+// of the "Device".
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieGetCaps(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=0;
+ PCI_CFG_ADDR addr;
+//-------------------------------
+ addr.ADDR=Device->Address.ADDR;
+
+ PCI_TRACE((TRACE_PCI,"\n PciE: Collecting CAPs for [B%X|D%X|F%X]\n",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function));
+
+ PCI_TRACE((TRACE_PCI," PCIE_CAP-> [R=%X|IntMsgNo=%X|SlotImpl=%X|PortType=%X|CapVer=%X]\n",
+ Device->PciExpress->PcieCap.Reserved,
+ Device->PciExpress->PcieCap.IntMsgNo,
+ Device->PciExpress->PcieCap.SlotImpl,
+ Device->PciExpress->PcieCap.PortType,
+ Device->PciExpress->PcieCap.CapVersion
+ ));
+
+ //Get PCI Express Device CAPs - 32 bit after setting clock configuration
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_DEV_CAP_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&Device->PciExpress->DeviceCap.DEV_CAP);
+ ASSERT_EFI_ERROR(Status);
+
+
+ //Print Content of DEV_CAP and DEV_CNT register..
+ PCI_TRACE((TRACE_PCI," DEV_CAP -> [R2=%X|FR=%X|PwrS=%X|PwrV=%X|R1=%X|RBE=%X|PI=%X|AI=%X|AB=%X|EpL1=%X|EpL0=%X|ExT=%X|PhF=%X|MPL=%X]\n",
+ Device->PciExpress->DeviceCap.Reserved2,
+ //Added in PCIe Base V2.0
+ Device->PciExpress->DeviceCap.FuncResetCap,
+ Device->PciExpress->DeviceCap.SlotPwrLimS,
+ Device->PciExpress->DeviceCap.SlotPwrLimV,
+ Device->PciExpress->DeviceCap.Reserved1,
+ //Added in PCIe Base V2.0
+ Device->PciExpress->DeviceCap.RoleBasedErr,
+ Device->PciExpress->DeviceCap.PowerInd,
+ Device->PciExpress->DeviceCap.AttnInd,
+ Device->PciExpress->DeviceCap.AttnBtn,
+ Device->PciExpress->DeviceCap.EpL1Latency,
+ Device->PciExpress->DeviceCap.EpL0Latency,
+ Device->PciExpress->DeviceCap.ExtTagFld,
+ Device->PciExpress->DeviceCap.PhantomFunc,
+ Device->PciExpress->DeviceCap.MaxPayload
+ ));
+
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CAP_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&Device->PciExpress->LinkCap.LNK_CAP);
+ ASSERT_EFI_ERROR(Status);
+
+ PCI_TRACE((TRACE_PCI," LNK_CAP -> [P#=%X|R=%X|BwN=%X|DllL=%X|SDE=%X|ClkPM=%X|L1=%X|L0=%X|ASPM=%X|MaxW=%X|MaxS=%X]\n",
+ Device->PciExpress->LinkCap.PortNum,
+ Device->PciExpress->LinkCap.Reserved,
+ //Added in PCIe Base V2.0
+ Device->PciExpress->LinkCap.BandwNotify,
+ Device->PciExpress->LinkCap.DllLnkActive,
+ Device->PciExpress->LinkCap.SurpDownErr,
+ Device->PciExpress->LinkCap.ClockPm,
+ //---------------------------------
+ Device->PciExpress->LinkCap.ExL1Latency,
+ Device->PciExpress->LinkCap.ExL0Latency,
+ Device->PciExpress->LinkCap.AspmSupport,
+ Device->PciExpress->LinkCap.MaxLnkWidth,
+ Device->PciExpress->LinkCap.MaxLnkSpeed
+ ));
+
+ //Get PCI Express Slot CAPs - 32 bit it is valid only for Ports Switches and Bridges
+ if((Device->Type==tPci2PciBrg || Device->Type==tPci2CrdBrg) &&
+ Device->PciExpress->PcieCap.SlotImpl )
+ {
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_SLT_CAP_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&Device->PciExpress->SlotCap.SLT_CAP);
+ ASSERT_EFI_ERROR(Status);
+
+ PCI_TRACE((TRACE_PCI," SLT_CAP -> [S#=%X|NoCmdC=%X|EmLck=%X|PwrS=%X|PwrV=%X|HpC=%X|HpS=%X|PI=%X|AI=%X|MrlS=%X|PwC=%X|AB=%X]\n",
+ Device->PciExpress->SlotCap.PhisSlotNum,
+ //Added in PCIe Base V2.0
+ Device->PciExpress->SlotCap.NoCmdCompl,
+ Device->PciExpress->SlotCap.EmInterlock,
+ //----------------------------
+ Device->PciExpress->SlotCap.PwrLimScale,
+ Device->PciExpress->SlotCap.PwrLimVal,
+ Device->PciExpress->SlotCap.HpCapable,
+ Device->PciExpress->SlotCap.HpSurprise,
+ Device->PciExpress->SlotCap.PowerInd,
+ Device->PciExpress->SlotCap.AttnInd,
+ Device->PciExpress->SlotCap.MrlSensor,
+ Device->PciExpress->SlotCap.PwrCntler,
+ Device->PciExpress->SlotCap.AttnBtn
+ ));
+
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieSetLnkProperties()
+//
+// Description: This function will Select values for Link Control2 register on
+// both sides of the LINK based on Setup Settiongs and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *DnStreamPort Pointer to PCI Device Private Data of Downstream Port of the link.
+// PCIE_LNK_CNT2_REG *DnLnkCnt Pointer to the LNK_CNT Reg of the Downstream Port of the link.
+// PCI_DEV_INFO *UpStreamPort Pointer to PCI Device Private Data of Upwnstream Port of the link.
+// PCIE_LNK_CNT2_REG *UpLnkCnt Pointer to the LNK_CNT Reg of the Downstream Port of the link.
+// BOOLEAN *LinkTrainingRequired Flag to modify if Link will need RETRAINING after programming.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieSetLnkProperties( PCI_DEV_INFO *DnStreamPort,
+ PCIE_LNK_CNT_REG *DnLnkCnt,
+ PCI_DEV_INFO *UpStreamPort,
+ PCIE_LNK_CNT_REG *UpLnkCnt,
+ BOOLEAN *LinkTrainingRequired)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCIE_LNK_STA_REG dnls, upls; //link status reg content of up and down side of the link
+ PCI_CFG_ADDR addr;
+ BOOLEAN cc=FALSE;
+//------------------------------
+
+ PCI_TRACE((TRACE_PCI,"PciE: PcieSetLnkProperties() ENTRY:\n"));
+
+ PCI_TRACE((TRACE_PCI," DN STREAM PORT -> [B%X|D%X|F%X] <--> [B%X|D%X|F%X] <- UP STREAM PORT\n",
+ DnStreamPort->Address.Addr.Bus,DnStreamPort->Address.Addr.Device, DnStreamPort->Address.Addr.Function,
+ UpStreamPort->Address.Addr.Bus,UpStreamPort->Address.Addr.Device, UpStreamPort->Address.Addr.Function));
+
+ //Get DownStream Port Properties
+ addr.ADDR=DnStreamPort->Address.ADDR;
+ addr.Addr.Register=DnStreamPort->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ Status=PciCfg16(DnStreamPort->RbIo,addr,FALSE, &DnLnkCnt->LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT -> [BwI=%X|BwMI=%X|AuWi=%X|CkPM=%X|ExS=%X|CCk=%X|Rtr=%X|LDis=%X|RCB=%X|ASPM=%X]\n",
+ DnLnkCnt->AutoBandwInt,
+ DnLnkCnt->BandwMgmtInt,
+ DnLnkCnt->HwAutoWdtDis,
+ DnLnkCnt->ClockPm,
+ DnLnkCnt->ExtSynch,
+ DnLnkCnt->CommonClk,
+ DnLnkCnt->RetrainLnk,
+ DnLnkCnt->LnkDisable,
+ DnLnkCnt->RdComplBound,
+ DnLnkCnt->AspmControl));
+
+
+
+ addr.Addr.Register=DnStreamPort->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+ Status=PciCfg16(DnStreamPort->RbIo,addr,FALSE, &dnls.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Get UpStream Stream Port Properties
+ addr.ADDR=UpStreamPort->Address.ADDR;
+
+ addr.Addr.Register=UpStreamPort->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ Status=PciCfg16(UpStreamPort->RbIo,addr,FALSE, &UpLnkCnt->LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT -> [BwI=%X|BwMI=%X|AuWi=%X|CkPM=%X|ExS=%X|CCk=%X|Rtr=%X|LDis=%X|RCB=%X|ASPM=%X]\n ....... UPDATINNG .......\n",
+ UpLnkCnt->AutoBandwInt,
+ UpLnkCnt->BandwMgmtInt,
+ UpLnkCnt->HwAutoWdtDis,
+ UpLnkCnt->ClockPm,
+ UpLnkCnt->ExtSynch,
+ UpLnkCnt->CommonClk,
+ UpLnkCnt->RetrainLnk,
+ UpLnkCnt->LnkDisable,
+ UpLnkCnt->RdComplBound,
+ UpLnkCnt->AspmControl));
+
+ //Get Lnk Status Content... from DownSteam and UpStream Ports
+ addr.Addr.Register=UpStreamPort->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+ Status=PciCfg16(UpStreamPort->RbIo,addr,FALSE, &upls.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //1.Disable ASPM for now we will set it later starting from Endpoints!
+ DnLnkCnt->AspmControl=0;
+ UpLnkCnt->AspmControl=0;
+
+ //2. Check Clock Config
+ //Check if Lnk Clk config programmed correctly by CSP Code.
+ //see if both sides can use Common Clock (Power up Default == 0)
+ if(dnls.CommonClk && upls.CommonClk) cc=TRUE;
+
+ //Verify if ClkConfig is set correctly and detect if link training is needed
+ if((DnLnkCnt->CommonClk != cc) || (UpLnkCnt->CommonClk!=cc)) *LinkTrainingRequired=TRUE;
+ DnLnkCnt->CommonClk=cc;
+ UpLnkCnt->CommonClk=cc;
+
+ //3.Extended Sinch
+ DnLnkCnt->ExtSynch=gPciSetupData->ExtendedSynch;
+ UpLnkCnt->ExtSynch=gPciSetupData->ExtendedSynch;
+
+ //4. Clock PM
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if((UpStreamPort->PciExpress->LinkCap.ClockPm) && (gPciSetupData->ClockPm))
+ {
+ DnLnkCnt->ClockPm=TRUE;
+ UpLnkCnt->ClockPm=TRUE;
+ } else {
+ DnLnkCnt->ClockPm=FALSE;
+ UpLnkCnt->ClockPm=FALSE;
+ }
+#endif
+ //5. Clear Some interupt related bits.
+ DnLnkCnt->BandwMgmtInt=FALSE;
+ DnLnkCnt->AutoBandwInt=FALSE;
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT -> [BwI=%X|BwMI=%X|AuWi=%X|CkPM=%X|ExS=%X|CCk=%X|Rtr=%X|LDis=%X|RCB=%X|ASPM=%X]\n",
+ DnLnkCnt->AutoBandwInt,
+ DnLnkCnt->BandwMgmtInt,
+ DnLnkCnt->HwAutoWdtDis,
+ DnLnkCnt->ClockPm,
+ DnLnkCnt->ExtSynch,
+ DnLnkCnt->CommonClk,
+ DnLnkCnt->RetrainLnk,
+ DnLnkCnt->LnkDisable,
+ DnLnkCnt->RdComplBound,
+ DnLnkCnt->AspmControl));
+
+ PCI_TRACE((TRACE_PCI," LNK_CNT -> [BwI=%X|BwMI=%X|AuWi=%X|CkPM=%X|ExS=%X|CCk=%X|Rtr=%X|LDis=%X|RCB=%X|ASPM=%X]\n\n",
+ UpLnkCnt->AutoBandwInt,
+ UpLnkCnt->BandwMgmtInt,
+ UpLnkCnt->HwAutoWdtDis,
+ UpLnkCnt->ClockPm,
+ UpLnkCnt->ExtSynch,
+ UpLnkCnt->CommonClk,
+ UpLnkCnt->RetrainLnk,
+ UpLnkCnt->LnkDisable,
+ UpLnkCnt->RdComplBound,
+ UpLnkCnt->AspmControl));
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieIsDownStreamPort()
+//
+// Description: This function will check if *PCI_DEV_INFO passed belongs to
+// PCI Express DOWNSTREAM PORT:
+// - RootPort of PCIe Root Complex;
+// - DownStream Port of PCIe Switch;
+// - PCI/PCI-X to PCIe Bridge.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+//
+// Output: BOOLEAN
+// TRUE When PCI_DEV_INFO passed belongs to DOWNSTREAM PORT
+// FALSE All other cases...
+//
+// NOTE: Must be called only for PCI Express devices (Device->PciExpress!=NULL)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN PcieIsDownStreamPort(PCI_DEV_INFO *Device){
+
+ if((Device->PciExpress->PcieCap.PortType == PCIE_TYPE_ROOTPORT) ||
+ (Device->PciExpress->PcieCap.PortType == PCIE_TYPE_DNS_PORT) ||
+ (Device->PciExpress->PcieCap.PortType == PCIE_TYPE_PCI_PCIE))
+ return TRUE;
+ else
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieSetSlotPower()
+//
+// Description: This function will power ON or OFF PCI Express Slot
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+// BOOLEAN PwrOn Tells to turn slot power ON or OFF
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieSetSlotPower(PCI_DEV_INFO* Device, BOOLEAN PwrOn){
+ PCI_CFG_ADDR addr;
+ PCIE_SLT_CNT_REG sltc;
+ EFI_STATUS Status=0;
+ UINT16 pwr=PCIE_SLT_PWR_OFF;
+//--------------------------------------------
+ if(!Device->PciExpress) return EFI_SUCCESS;
+
+ if(Device->PciExpress->SlotCap.PwrCntler){
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_SLT_CNT_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&sltc.SLT_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(PwrOn){
+ if(Device->PciExpress->SlotCap.PowerInd) sltc.PowerIndCnt=PCIE_SLT_INDICATOR_ON;
+ sltc.PowerOff=PCIE_SLT_PWR_ON;
+ } else {
+ if(Device->PciExpress->SlotCap.PowerInd) sltc.PowerIndCnt=PCIE_SLT_INDICATOR_OFF;
+ sltc.PowerOff=PCIE_SLT_PWR_OFF;
+ }
+ Status=PciCfg16(Device->RbIo,addr,TRUE,&sltc.SLT_CNT);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreBridgeBuses()
+//
+// Description: This function will Reprogram Primary Secondary and Subordinate
+// bus numbers for the downsteram bridges after SEC BUS reset signal assertion.
+//
+// Input:
+// PCI_DEV_INFO *DnPort Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RestoreBridgeBuses(PCI_DEV_INFO *DnPort){
+ UINTN i;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(DnPort+1);
+ PCI_DEV_INFO *dev;
+ EFI_STATUS Status=EFI_SUCCESS;
+//---------------------
+ for(i=0; i< ext->ChildCount; i++){
+ dev=ext->ChildList[i];
+ if(dev->Type==tPci2PciBrg){
+ Status=MapBridgeBuses(dev);
+ if(EFI_ERROR(Status)) return Status;
+ //call recoursively to cover all hierarchy
+ Status=RestoreBridgeBuses(dev);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieInitLink()
+//
+// Description: This function will Initialize Pcie Link on both sides starting
+// fronm DownStream Port.
+//
+// Input:
+// PCI_DEV_INFO *DnPort Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieInitLink(PCI_DEV_INFO *DnPort){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_DEV_INFO *dn, *up, *f0;
+ PCI_BRG_EXT *ext;
+ PCIE_LNK_CNT_REG dnlc, uplc;
+ BOOLEAN lr=FALSE,lt=FALSE, pe2=FALSE, mf=FALSE;
+ UINT16 mpl, l0, l1;//calculated link speed
+ UINTN i=0,r=1;
+ T_ITEM_LIST *chldlst=NULL;
+ UINT8 lnkspeed=0;
+#if PCI_EXPRESS_GEN2_SUPPORT
+ PCIE_LNK_CNT2_REG dnlc2, uplc2;
+#endif
+//-------------------------------
+
+ if(DnPort->PciExpress==NULL) return EFI_SUCCESS;
+
+ //Going from DOWN STREAM PORT to EP
+ dn=DnPort;
+ ext=(PCI_BRG_EXT*)(dn+1);
+
+
+ PCI_TRACE((TRACE_PCI,"\n PciE: InitLink DNSP @ [B%X|D%X|F%X] has 0x%X Childs",
+ dn->Address.Addr.Bus,dn->Address.Addr.Device,dn->Address.Addr.Function, ext->ChildCount));
+ if(ext->ChildCount==0){
+ Status=PcieDisableLink(dn, FALSE);
+ PCI_TRACE((TRACE_PCI," - Disabe Inactive Link=%d: %r\n", gPciSetupData->LnkDisable, Status));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ //Check if we need to initialize Pcie2 features as well
+ //it will happened if both sides of the link supports PcieGen2 spec
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if(dn->PciExpress->Pcie2!=NULL)pe2=TRUE;
+ else pe2=FALSE;
+#endif
+
+ if(pe2)PCI_TRACE((TRACE_PCI," ARI=%d; ",dn->PciExpress->Pcie2->AriEnabled));
+ else PCI_TRACE((TRACE_PCI," ARI=0; "));
+
+ Status=CpyItemLst((T_ITEM_LIST*)&ext->InitialCount, &chldlst);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Went trough Bridge's Childs and...
+ for(i=0,f0=NULL; i<chldlst->ItemCount; i++){
+ up=(PCI_DEV_INFO*)chldlst->Items[i];
+
+ if(up->PciExpress==NULL)return EFI_SUCCESS;
+
+ if(IsFunc0(up)){
+ f0=up;
+ mf=IsFunc0OfMfDev(up);
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Set PCIe GEN2 Properties first it ia applicable only for Func0
+ //if both sides of the link supports it...
+ if((up->PciExpress->Pcie2!=NULL) && (pe2==TRUE)){
+ PCI_TRACE((TRACE_PCI,"GEN2=%d.\n",pe2));
+ Status=Pcie2SetLnkProperties(dn, &dnlc2, up, &uplc2, &lr, &lt);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ } else pe2 = FALSE;
+#endif
+ if(pe2==FALSE)PCI_TRACE((TRACE_PCI,"GEN2=%d.\n",pe2));
+
+ //Now Set PCIe GEN1 properties.
+ Status=PcieSetLnkProperties(dn, &dnlc, up, &uplc, &lt);
+
+ //Now remove pointer to the func 0 from DOWN STREAM PORT Child's List
+ Status=DeleteItemLst(chldlst, i, FALSE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ break;
+ }
+ }
+
+ //It must be a Child with Function == 0 there...
+ ASSERT(f0!=NULL);
+
+ //now we are here and have prepared content of LNK_CNT and LNK_CNT2 for programming.
+ //there are some rules for link initialization that differes for ARI devices and regular ones.
+ //1. If device is ARI devise (has ARI compatibility header) all programming is applicable for Function0 only.
+ // all other Link control Register bits are reserved for the functions other than 0.
+ //2. If Device is NON-ARI than:
+ // a) all functions must report same value in capabilities except ClockPM bit -
+ // it is independent but will work only if all Functions of the device reports same capability.
+ // b) all functions mus have same values in LNK_CNT for feature to work.
+ // except same old ClockPM - it can be set only if all functions support it.
+
+ //Check some condition which suppose to be true for PCI Express Devices.
+ ASSERT(chldlst->ItemCount == f0->FuncCount); //it must be the same number as FuncCount of Func0 device
+
+ //If device id NON-ARI we must programm all functions to the same values
+ if((f0!=NULL) && (f0->PciExpress->AriData == NULL) && (mf==TRUE)){
+
+ PcieUpdateClockPm(f0,&uplc);
+ //Apply Settings for each child if device is MF
+ for(i=0; i<f0->FuncCount; i++){
+ up=f0->DevFunc[i];
+
+ if(up->PciExpress==NULL) continue;
+
+ Status=PcieProgramLink(up,uplc.LNK_CNT, FALSE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if(pe2){
+ Status=PcieProgramLink(up,uplc2.LNK_CNT2,TRUE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+#endif
+
+ }
+ }
+
+ //Now Program the link ....
+ //Func 0 of Upstrem port...
+ Status=PcieProgramLink(f0,uplc.LNK_CNT, FALSE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if(pe2){
+ Status=PcieProgramLink(f0,uplc2.LNK_CNT2, TRUE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+#endif
+
+ //Downstream port...
+ Status=PcieProgramLink(dn,dnlc.LNK_CNT, FALSE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if(pe2){
+ Status=PcieProgramLink(dn,dnlc2.LNK_CNT2, TRUE);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ //All soft instances of PCIe registers updated
+ //now check update lnkspeed variable
+ if(pe2)lnkspeed=(UINT8)(dnlc2.TargetLnkSpeed);
+ else lnkspeed=1;
+#else
+ lnkspeed=1;
+#endif
+
+ //And now see do we need to Retrain link or issue a Hot Reset.
+ //If Link Speed was changed we need to do a Hot Reset of a Link.
+ //When Hot Reset issued with New Link Parameters link will be retrained anyway.
+ if(lr){
+ Status=PcieResetLink(dn, lnkspeed);
+ Status=RestoreBridgeBuses(dn);
+ }
+
+ if(lt) Status=PcieRetrainLink(dn,dnlc.LNK_CNT, lnkspeed);
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Update Internal Data now once we have applied all link settings
+ //It might affect some capablities of the PCIe Device.
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if(pe2){
+ dn->PciExpress->Pcie2->LnkSpeed=(UINT8)dnlc2.TargetLnkSpeed;
+ f0->PciExpress->Pcie2->LnkSpeed=(UINT8)uplc2.TargetLnkSpeed;
+ }
+#endif
+
+ //Set Flag that link was progranmmed!
+ dn->PciExpress->LinkSet=TRUE;
+ f0->PciExpress->LinkSet=TRUE;
+
+
+ //If link was reseted or retrained update link capabilities
+ //since it might change besause of clock config and speed change.
+ if(lt || lr ){
+ PCI_TRACE((TRACE_PCI,"Pcie: Refresh CAPs for DNSTREAM; UPSTREAM + ALL FUNC\n"));
+ Status=PcieGetCaps(dn);
+ ASSERT_EFI_ERROR(Status);
+
+ Status=PcieGetCaps(f0);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //For all devices interfacing with DownStream port
+ //update MaxPayLoad and L0s L1 exit Latencies once we are already here.
+ //We will use it later to Program Pcie Device Chain
+ mpl=dn->PciExpress->DeviceCap.MaxPayload;
+
+ //value of 0xFFFE indicates corresponded Lx state is not supported)
+ //value of 0xFFFF indicates corresponded Lx latency was not calculated yet.
+ if(dn->PciExpress->LinkCap.AspmSupport & PCIE_ASPM_L0_ENABLE) l0=dn->PciExpress->LinkCap.ExL0Latency;
+ if(dn->PciExpress->LinkCap.AspmSupport & PCIE_ASPM_L1_ENABLE) l1=dn->PciExpress->LinkCap.ExL1Latency;
+
+ if(mpl > f0->PciExpress->DeviceCap.MaxPayload)mpl=f0->PciExpress->DeviceCap.MaxPayload;
+ //It is stated in spec "Multi-Function devices associated with an Upstream Port must
+ //report the same value in this field for all Functions"
+ if(l0!=0xFFFF && (l0 < f0->PciExpress->LinkCap.ExL0Latency)) l0=f0->PciExpress->LinkCap.ExL0Latency;
+ if(l1 < f0->PciExpress->LinkCap.ExL1Latency) l1=f0->PciExpress->LinkCap.ExL1Latency;
+
+ for(i=0; i<f0->FuncCount; i++){
+ up=f0->DevFunc[i];
+
+ if(up->PciExpress==NULL)continue;
+
+ up->PciExpress->LinkSet=TRUE;
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if(pe2) up->PciExpress->Pcie2->LnkSpeed=(UINT8)uplc2.TargetLnkSpeed;
+#endif
+ //Link Retraining or Hot Reset might change Latency values...
+ if(lt || lr ){
+ Status=PcieGetCaps(up);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //Update MaxPL for all other functions,....spec says
+ // "The Functions of a multi-Function device are permitted to
+ // report different values for this field."
+ if(mpl>up->PciExpress->DeviceCap.MaxPayload)mpl=up->PciExpress->DeviceCap.MaxPayload;
+ up->PciExpress->MaxL0Lat=l0;
+ up->PciExpress->MaxL1Lat=l1;
+ }
+
+ //found smallest one and record it in MaxPayload field of DOWNSTREAM PORT and UPSTREAM PORT's F0;
+ f0->PciExpress->MaxPayload=mpl;
+ f0->PciExpress->MaxL0Lat=l0;
+ f0->PciExpress->MaxL1Lat=l1;
+
+ dn->PciExpress->MaxPayload=mpl;
+ dn->PciExpress->MaxL0Lat=l0;
+ dn->PciExpress->MaxL1Lat=l1;
+
+ //some house keeping;
+ ClearItemLst(chldlst, FALSE);
+ if(chldlst)pBS->FreePool(chldlst);
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CollectDeviceExtCap()
+//
+// Description: This function will Fill out structure of PciE Ext Cap data
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CollectDeviceExtCap(PCI_DEV_INFO *Device, VOID **DataPtr, UINTN DataSize, UINT32 CapHdrOffset, BOOLEAN Cap16, UINTN OffsetFromCapHdr){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_CFG_ADDR addr;
+ PCIE_EXT_DATA_HDR *dhdr;
+//---------------------------------------
+
+ //Pointer must be empty at the beginning.
+ if(*DataPtr!=NULL) {
+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *DataPtr=MallocZ(DataSize);
+
+ if(*DataPtr==NULL) {
+ ASSERT_EFI_ERROR(EFI_OUT_OF_RESOURCES);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ dhdr=(PCIE_EXT_DATA_HDR*)(*DataPtr);
+
+ dhdr->CapHdrOffset=CapHdrOffset;
+
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.ExtendedRegister=CapHdrOffset+(sizeof(PCIE_EXT_CAP_HDR))+(UINT32)OffsetFromCapHdr;
+
+ if(Cap16)Status=PciCfg16(Device->RbIo, addr, FALSE,(UINT16*)&dhdr->CapReg);
+ else Status=PciCfg32(Device->RbIo, addr, FALSE,(UINT32*)&dhdr->CapReg);
+
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieProgramPayloadUp()
+//
+// Description: This function will reprogram Max Payload and Read Request Size
+// in upstream link if initialization code founds that one of Nodes down stream
+// has lesser Max Pay load size than currently programmed
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// UINT32 Payload Reduced Max Payload Value.
+// UINT32 ReadRequest Reduced Read Request Value.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Notes:
+// RootPortComplex<=>Switch0...<=>...SwitchN<=>EndPoint
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieProgramPayloadUp(PCI_DEV_INFO *Device, UINT16 MaxPayload, UINT16 MaxReadReq){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_DEV_INFO *dev=Device;
+//-------------------------
+
+ //It has to be PCIE Switch device so it must have PCI2PCI Bridge Header structure.
+ if(dev->Type!=tPci2PciBrg) return EFI_DEVICE_ERROR;
+
+ //We are cominng here if Payload and MaxReadRequest been set for the device and
+ //Device is NOT ENDPOINT Device. Means we hit switch here and it handling more then
+ //one ENDPOINT Devices. So check if MPL and MRRS is Bigger or Equal then passed Payload parameter.
+ if(dev->PciExpress->MaxPayload > MaxPayload){
+ UINTN i;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(dev+1);
+ PCI_CFG_ADDR addr;
+ PCIE_DEV_CNT_REG devc;
+ //-------------
+ //if condition met: one or some of the upstream device(s) are capable and programmed
+ //to generate TLP bigger than current proposed programming stored in "mrr" and "mpl".
+
+ //Select Device Control Register
+ addr.ADDR= dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_DEV_CNT_OFFSET;
+ //Read what we have there
+ Status=PciCfg16(dev->RbIo,addr,FALSE,&devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ PCI_TRACE((TRACE_PCI,"PciE: Going UP @ [B%X|D%X|F%X] Updating: MPL %X to %X\n",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device, Device->Address.Addr.Function,
+ devc.MaxPayload, MaxPayload));
+
+ for(i=0;i<ext->ChildCount; i++){
+ dev=(PCI_DEV_INFO*)ext->ChildList[i];
+ if(dev->PciExpress!=NULL){
+ //Reprogram only devices we have programmed already.
+ if(dev->PciExpress->DevSet){
+ //If we have other switches in upstream link call this function recursively.
+ if(dev->Type==tPci2PciBrg) {
+ PcieProgramPayloadUp(dev, MaxPayload, MaxReadReq);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ //Select Device Control Register
+ addr.ADDR = dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_DEV_CNT_OFFSET;
+ //Read what we have there
+ Status=PciCfg16(dev->RbIo,addr,FALSE,&devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI,"PciE: Reprogram Payload @ [B%X|D%X|F%X] Updating: MPL %X to %X\n",
+ dev->Address.Addr.Bus,dev->Address.Addr.Device, dev->Address.Addr.Function,
+ devc.MaxPayload, MaxPayload));
+
+ devc.MaxPayload=MaxPayload;
+ //Leave CHIPSET INIT value if AUTO selected.
+ if(MaxReadReq != 55) devc.MaxReadReq=MaxReadReq;
+
+ Status=PciCfg16(dev->RbIo,addr,TRUE, &devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ dev->PciExpress->MaxPayload=MaxPayload;
+
+ }
+ } else {
+ //Such condition MUST NOT happened, since Parent is UPSTREAM PORT and childs must be a PciE only!
+ PCI_TRACE((TRACE_PCI, "PciE: ERROR! PciE Data Uninitialized! Child#=%d. TotalChlds=%d.\n", i, ext->ChildCount));
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ } else {
+ PCI_TRACE((TRACE_PCI,"PciE: NOT Going UP @ [B%X|D%X|F%X] Device's Link MPL %X <= New MPL %X\n",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device, Device->Address.Addr.Function,
+ dev->PciExpress->MaxPayload, MaxPayload));
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieConvertLatency()
+//
+// Description: This function will convert Latency value from Values read from.
+// PPCIe.LNK_CNT_REG to Nanoseconds and opposite.
+//
+// Input:
+// UINTN Latency Latency Value to convert
+// BOOLEAN L0s Tells if L0s or L1 Exit latency
+// BOOLEAN ToNs Tells how to convert:
+// TRUE - to the units of nano Seconds;
+// FALSE - to the LNK_CNT_REG.LxExitLat register value
+//
+// Output: EFI_STATUS
+// UINTN Converted Value (-1) - means Invalid Value passed;
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//Return value in nS of Max L0s, L1 Exit latency .
+UINTN PcieConvertLatency(UINTN Latency, BOOLEAN L0s, BOOLEAN ToNs){
+ UINTN l0s[]={64,128,256,512,1000,2000,4000,8000};
+ UINTN l1[]= {1000, 2000, 4000, 8000, 16000,32000,64000,128000};
+ UINTN *a, max,i=0;
+//---------------------
+ //Init stuff
+ if(L0s) a=&l0s[0];
+ else a=&l1[0];
+
+ if (ToNs) max=7;
+ else{
+ if(L0s) max=8000;
+ else max=128000;
+ }
+
+ //Check parameters;
+ if (Latency > max){
+ return max;
+ }
+
+ if(ToNs) return a[Latency];
+ else {
+ while(i<8){
+ if(a[i]<Latency)i++;
+ else break;
+ }
+ if(i==8) i=7;
+
+ return i;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieRemoveEpFromLst()
+//
+// Description: This function will removed Device referencesd as EndPoint from
+// the gPcieEpLst data structure used as a database of available EndPoint devices.
+//
+// Input:
+// PCI_DEV_INFO *EndPoint Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND EndPoint not in the gPcieEpLst.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieRemoveEpFromLst(PCI_DEV_INFO *EndPoint){
+ PCI_DEV_INFO *dev;
+ UINTN i;
+//-------------------------
+ for(i=0; i<gPcieEpList.ItemCount; i++){
+ dev=(PCI_DEV_INFO*)gPcieEpList.Items[i];
+
+ if(dev==EndPoint){
+ DeleteItemLst(&gPcieEpList, i, FALSE);
+ PCI_TRACE((TRACE_PCI,"PciE: Removing Device [B%X|D%X|F%X] from gPcieEpList[%d]\n",
+ EndPoint->Address.Addr.Bus,EndPoint->Address.Addr.Device, EndPoint->Address.Addr.Function, i));
+ return EFI_SUCCESS;
+ }
+ }
+ PCI_TRACE((TRACE_PCI,"PciE: Can't find device [B%X|D%X|F%X] in gPcieEpList[%d]\n",
+ EndPoint->Address.Addr.Bus,EndPoint->Address.Addr.Device, EndPoint->Address.Addr.Function, gPcieEpList.ItemCount));
+
+ return EFI_NOT_FOUND;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieCalcMaxPayLoad()
+//
+// Description: This function will calculate MAX PayLoad Size needed to work
+// correctly.
+//
+// Input:
+// PCI_DEV_INFO *EndPoint Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16 PcieCalcMaxPayLoad(PCI_DEV_INFO *EndPoint){
+ UINT16 tmpl=0xFFFF, lmpl;
+ PCI_DEV_INFO *dn, *up;
+ BOOLEAN progup;
+#if EFI_DEBUG == 1 //debug
+ UINTN i=1;
+#endif
+//--------------------
+ up=EndPoint;
+ PCI_TRACE((TRACE_PCI," Calculate MPL :\n"));
+ //Down steam port and F0 holds optimal MPL for all elements on this link
+ do{
+ if(up==NULL || up->ParentBrg==NULL)break;
+ progup=FALSE;
+
+ if(!IsFunc0(up)) up=up->Func0;
+ //Init this link mpl var (dn<->up)
+ lmpl=up->PciExpress->MaxPayload;
+
+ dn=up->ParentBrg;
+ if(dn->PciExpress->MaxPayload<lmpl){
+ //if UP link has bigger MPL value then DN link
+ //Update UP link recoded value...
+ lmpl=dn->PciExpress->MaxPayload;
+
+ //set the Flag that we have to reprogramm MPL since downstream MPL has been reduced
+ progup=TRUE;
+ }
+
+ //Here lmpl holds smallest value of the link check if accomulated MPL exceeds MPL of this link...
+ if(tmpl!=lmpl) progup=TRUE;
+ if(tmpl>lmpl) tmpl=lmpl;
+
+ //PcieProgramPayloadUp has double check if MPL needs to be programmed
+ if(progup && up->PciExpress->PcieCap.PortType==PCIE_TYPE_UPS_PORT && up->PciExpress->DevSet){
+ if(gPciSetupData->MaxReadRequest!=55) PcieProgramPayloadUp(up, tmpl,gPciSetupData->MaxReadRequest);
+ else PcieProgramPayloadUp(up, tmpl, PCIE_MAXPL_512B);
+ }
+
+ up->PciExpress->MaxPayload=tmpl;
+
+#if EFI_DEBUG == 1 //debug
+ PCI_TRACE((TRACE_PCI," Link # %d, Link MPL=%X; Total MPL=%X dn->[B%X|D%X|F%X]<->[B%X|D%X|F%X]<-up;\n", i,lmpl, tmpl,
+ dn->Address.Addr.Bus,dn->Address.Addr.Device, dn->Address.Addr.Function,
+ up->Address.Addr.Bus,up->Address.Addr.Device, up->Address.Addr.Function ));
+ i++;
+#endif
+ up=dn->ParentBrg;
+ } while (up->ParentBrg->PciExpress!=NULL && up->ParentBrg->Type!=tPciRootBrg); //(EIP49743)
+
+ PCI_TRACE((TRACE_PCI," Calculated MPL %X\n\n", tmpl));
+
+ return tmpl;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieCalcLatency()
+//
+// Description: This function will calculate MAX Latency needed to exit from
+// ome of the ASPM Sattes L0s or L1.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// BOOLEAN L0s Tells which ASPM state Latency we are calculating
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN PcieCalcLatency(PCI_DEV_INFO *EndPoint, BOOLEAN L0s){
+ PCI_DEV_INFO *dn, *up;
+ UINT16 *ll;
+ UINTN i=0, tmp=0, lat=0;
+//--------------------
+ up=EndPoint;
+ PCI_TRACE((TRACE_PCI," Calculate "));
+ if(L0s)PCI_TRACE((TRACE_PCI,"L0s:\n"));
+ else PCI_TRACE((TRACE_PCI,"L1 :\n"));
+ //Down steam port and F0 holds optimal MPL for all elements on this link
+ do{
+ if(!IsFunc0(up)) up=up->Func0;
+ dn=up->ParentBrg;
+ if(L0s)ll=&dn->PciExpress->MaxL0Lat;
+ else ll=&dn->PciExpress->MaxL1Lat;
+
+ //if PciExpress->MaxL0Lat==0xFFFF means Link does not support ASPM
+ if(*ll!=0xFFFF ) {
+ if(L0s) {
+ tmp=PcieConvertLatency(dn->PciExpress->MaxL0Lat, L0s, TRUE);
+ lat+=tmp;
+ } else {
+ tmp=PcieConvertLatency(dn->PciExpress->MaxL1Lat, L0s, TRUE);
+ if(tmp>lat) lat=tmp;
+ }
+ }
+
+ PCI_TRACE((TRACE_PCI," Link# %d Lat=%d(nS) dn->[B%X|D%X|F%X]<->[B%X|D%X|F%X]<-up;\n", i, tmp,
+ dn->Address.Addr.Bus,dn->Address.Addr.Device, dn->Address.Addr.Function,
+ up->Address.Addr.Bus,up->Address.Addr.Device, up->Address.Addr.Function ));
+ i++;
+
+ //Advance to the next link.
+ up=dn->ParentBrg;
+ } while (dn->ParentBrg->PciExpress!=NULL && dn->ParentBrg->Type!=tPciRootBrg);//(EIP49743)
+
+ //Internal delay on each Upstream Port (per spec.) MUST BE NO MORE than 1uS.
+ //so next UPSTREAM Link will start transition from L1 to L0 state in 1uS (worst case)
+ // to calculate L1 exit Latency we will use (MAX lat + 1000nS * (i-1)) where i number of links on the packet path.
+ if(!L0s && i>0) lat+=1000*(i-1);
+
+ PCI_TRACE((TRACE_PCI," Total Calclulated latency: %d (nS)\n", lat ));
+
+ return lat;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieInitVc()
+//
+// Description: This function will Initialize "Device"'s Virtual Channel properties
+// based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieInitVc(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_CFG_ADDR addr;
+ VC_RES_DATA *vcrd;
+ PCIE_VC_RESCNT_REG vcrc;
+ UINTN c;
+//-------------------------
+ //Program VC configuration
+ //Limit VC TC to TC0 mapped trough VC0 and Disable all Extended VC resources on the way of the LINK.
+ //This is a device driver responcibility to allow different TCs and enable Extended VCs if link has it.
+
+ addr.ADDR=Device->Address.ADDR;
+ //Arbitration Table has to be loaded by the Chipset specific code
+ //in NBDxe.c or SBDxe.c or by device specific driver. So don't bother
+ for(c=0; c<Device->PciExpress->VcData->VcCount; c++){
+ vcrd=Device->PciExpress->VcData->VcResData[c];
+
+ //Locate VC Resource CNT reg
+ addr.Addr.ExtendedRegister=vcrd->VcResOffset+4;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&vcrc.VC_RESCNT);
+ ASSERT_EFI_ERROR(Status);
+
+ //Disable VC and TC mapping except default mapping TC0 VC0
+ if(c){
+ vcrc.Tc_VcMap=0;
+ vcrc.VcEnable=0;
+ } else {
+ //for Channel0(Default VC this bits must be RO but who knows...)
+ vcrc.Tc_VcMap=1;
+ vcrc.VcEnable=1;
+ }
+ vcrc.VcId=(UINT8)c;
+
+ //write it back
+ Status=PciCfg32(Device->RbIo,addr,TRUE,&vcrc.VC_RESCNT);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieSetDevProperties()
+//
+// Description: This function will Select values for DEVICE CONTROL register
+// based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data.
+// UINT16 *MaxPayload Pointer to the MaxPayload value.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieSetDevProperties(PCI_DEV_INFO *Device, UINT16 MaxPayload){
+ EFI_STATUS Status;
+ PCI_CFG_ADDR addr;
+ PCI_DEV_INFO *dev=Device;
+ PCIE_DEV_CNT_REG devc;
+//-------------------------
+
+ addr.ADDR=Device->Address.ADDR;
+
+ PCI_TRACE((TRACE_PCI,"PciE: PcieSetDevProperties() Device @ [B%X|D%X|F%X] ENTRY:\n",
+ addr.Addr.Bus,addr.Addr.Device, addr.Addr.Function));
+
+ if (Device->PciExpress == NULL)
+ return EFI_SUCCESS;
+
+ //Select Device Control Register
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_DEV_CNT_OFFSET;
+ //Read what we have there
+ Status=PciCfg16(dev->RbIo,addr,FALSE,&devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ PCI_TRACE((TRACE_PCI," DEV_CNT -> [FrBr=%X|MRR=%X|NS=%X|APPM=%X|PhF=%X|ETg=%X|MPL=%X|RO=%X|UpRR=%X|FtEr=%X|NfEr=%X|CEr=%X]\n ....... UPDATINNG .......\n",
+ devc.FnRstBrgRtry,
+ devc.MaxReadReq,
+ devc.NoSnoop,
+ devc.AuxPwrPm,
+ devc.PhantomFunc,
+ devc.ExtTagFld,
+ devc.MaxPayload,
+ devc.RelaxOrder,
+ devc.UsupReqRep,
+ devc.FatalErrRep,
+ devc.NfErrRep,
+ devc.CorrErrRep));
+
+ //Set some bits:
+ //1.Get Maximum PayLoad Size
+ //Don't allow overwrite if it is more than supported
+ if(gPciSetupData->MaxPayload!=55 && gPciSetupData->MaxPayload < MaxPayload) devc.MaxPayload=gPciSetupData->MaxPayload;
+ else devc.MaxPayload=MaxPayload;
+
+ //2.Get Max Read Request Size
+ if(gPciSetupData->MaxReadRequest!=55) devc.MaxReadReq=gPciSetupData->MaxReadRequest;
+ //if "AUTO" selected use value already sitting there...
+// else devc.MaxReadReq=PCIE_MAXPL_512B;
+
+ //3.Enable/Disable extended tagfld per Setup Option
+ devc.ExtTagFld=0; //use 5 bit tag.
+ if(dev->PciExpress->DeviceCap.ExtTagFld)devc.ExtTagFld=gPciSetupData->ExtTagField;
+
+ //4. Set No Snoop bit per Setup Option
+ devc.RelaxOrder=gPciSetupData->RelaxedOrdering;
+ devc.NoSnoop=gPciSetupData->NoSnoop;
+
+ //Write it back
+ Status=PciCfg16(dev->RbIo,addr,TRUE,&devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ //Init device's VC
+ //if we have a virtual channel capability
+ if(Device->PciExpress->VcData) Status=PcieInitVc(Device);
+
+
+/*
+ //Print Content of DEV_CAP and DEV_CNT register..
+ PCI_TRACE((TRACE_PCI," DEV_CAP -> [R2=%X|FR=%X|PwrS=%X|PwrV=%X|R1=%X|RBE=%X|PI=%X|AI=%X|AB=%X|EpL1=%X|EpL0=%X|ExT=%X|PhF=%X|MPL=%X]\n",
+ dev->PciExpress->DeviceCap.Reserved2,
+ //Added in PCIe Base V2.0
+ dev->PciExpress->DeviceCap.FuncResetCap,
+ dev->PciExpress->DeviceCap.SlotPwrLimS,
+ dev->PciExpress->DeviceCap.SlotPwrLimV,
+ dev->PciExpress->DeviceCap.Reserved1,
+ //Added in PCIe Base V2.0
+ dev->PciExpress->DeviceCap.RoleBasedErr,
+ dev->PciExpress->DeviceCap.PowerInd,
+ dev->PciExpress->DeviceCap.AttnInd,
+ dev->PciExpress->DeviceCap.AttnBtn,
+ dev->PciExpress->DeviceCap.EpL1Latency,
+ dev->PciExpress->DeviceCap.EpL0Latency,
+ dev->PciExpress->DeviceCap.ExtTagFld,
+ dev->PciExpress->DeviceCap.PhantomFunc,
+ dev->PciExpress->DeviceCap.MaxPayload
+ ));
+*/
+ PCI_TRACE((TRACE_PCI," DEV_CNT -> [FrBr=%X|MRR=%X|NS=%X|APPM=%X|PhF=%X|ETg=%X|MPL=%X|RO=%X|UpRR=%X|FtEr=%X|NfEr=%X|CEr=%X]\n\n",
+ devc.FnRstBrgRtry,
+ devc.MaxReadReq,
+ devc.NoSnoop,
+ devc.AuxPwrPm,
+ devc.PhantomFunc,
+ devc.ExtTagFld,
+ devc.MaxPayload,
+ devc.RelaxOrder,
+ devc.UsupReqRep,
+ devc.FatalErrRep,
+ devc.NfErrRep,
+ devc.CorrErrRep));
+
+/*
+ PCI_TRACE((TRACE_PCI," LNK_CAP -> [P#=%X|R=%X|BwN=%X|DllL=%X|SDE=%X|ClkPM=%X|L1=%X|L0=%X|ASPM=%X|MaxW=%X|MaxS=%X]\n",
+ dev->PciExpress->LinkCap.PortNum,
+ dev->PciExpress->LinkCap.Reserved,
+ //Added in PCIe Base V2.0
+ dev->PciExpress->LinkCap.BandwNotify,
+ dev->PciExpress->LinkCap.DllLnkActive,
+ dev->PciExpress->LinkCap.SurpDownErr,
+ dev->PciExpress->LinkCap.ClockPm,
+ //---------------------------------
+ dev->PciExpress->LinkCap.ExL1Latency,
+ dev->PciExpress->LinkCap.ExL0Latency,
+ dev->PciExpress->LinkCap.AspmSupport,
+ dev->PciExpress->LinkCap.MaxLnkWidth,
+ dev->PciExpress->LinkCap.MaxLnkSpeed
+ ));
+
+#if EFI_DEBUG
+ if (Device->PciExpress->PcieCap.SlotImpl){
+
+ PCI_TRACE((TRACE_PCI," SLT_CAP -> [S#=%X|NoCmdC=%X|EmLck=%X|PwrS=%X|PwrV=%X|HpC=%X|HpS=%X|PI=%X|AI=%X|MrlS=%X|PwC=%X|AB=%X]\n",
+ dev->PciExpress->SlotCap.PhisSlotNum,
+ //Added in PCIe Base V2.0
+ dev->PciExpress->SlotCap.NoCmdCompl,
+ dev->PciExpress->SlotCap.EmInterlock,
+ //----------------------------
+ dev->PciExpress->SlotCap.PwrLimScale,
+ dev->PciExpress->SlotCap.PwrLimVal,
+ dev->PciExpress->SlotCap.HpCapable,
+ dev->PciExpress->SlotCap.HpSurprise,
+ dev->PciExpress->SlotCap.PowerInd,
+ dev->PciExpress->SlotCap.AttnInd,
+ dev->PciExpress->SlotCap.MrlSensor,
+ dev->PciExpress->SlotCap.PwrCntler,
+ dev->PciExpress->SlotCap.AttnBtn
+ ));
+ }
+#endif
+*/
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieSetAspm()
+//
+// Description: This function will Select values for Link Control2 register on
+// both sides of the LINK based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *DnPort Pointer to PCI Device Private Data of Downstream Port of the link.
+// PCI_DEV_INFO *UpPort Pointer to PCI Device Private Data of Upwnstream Port of the link.
+// UINT16 Aspm ASPM value to programm.
+// BOOLEAN *LinkHotResetRequired Flag to modify if Link will need HOT RESET after programming.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieSetAspm(PCI_DEV_INFO *DnPort,PCI_DEV_INFO *UpPort,UINT16 Aspm){
+ EFI_STATUS Status;
+ PCIE_LNK_CNT_REG lnkc;
+ PCI_CFG_ADDR addr;
+ UINT16 aspm=0, dnaspm, upaspm;
+//-------------------------
+
+
+ PCI_TRACE((TRACE_PCI,"\n Setting ASPM for Link...\n UP STREAM PORT -> [B%X|D%X|F%X] <--> [B%X|D%X|F%X] <- DN STREAM PORT\n",
+ UpPort->Address.Addr.Bus,UpPort->Address.Addr.Device, UpPort->Address.Addr.Function,
+ DnPort->Address.Addr.Bus,DnPort->Address.Addr.Device, DnPort->Address.Addr.Function ));
+
+ //We are coming here with UpPort as Function 0 already.
+ addr.ADDR=UpPort->Address.ADDR;
+
+ //Select lnk Control Register
+ addr.Addr.Register=UpPort->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ //Read what we have there
+ Status=PciCfg16(UpPort->RbIo,addr,FALSE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Spec tells: "ASPM L1 must be enabled by software in the Upstream
+ //component on a Link prior to enabling ASPM L1 in the
+ //Downstream component on that Link. When disabling ASPM
+ //L1, software must disable ASPM L1 in the Downstream
+ //component on a Link prior to disabling ASPM L1 in the
+ //Upstream component on that Link. ASPM L1 must only be
+ //enabled on the Downstream component if both components on
+ //a Link support ASPM L1."
+
+ //We have recorded in MaxLxLat field of the PciExpres Data Structure
+ //Link capability to support certain Lx states.
+ //value of 0xFFFF indicates corresponded Lx state is not supported.
+ //It must be the same on both sides of the link!
+ ASSERT(DnPort->PciExpress->MaxL0Lat == UpPort->PciExpress->MaxL0Lat);
+ ASSERT(DnPort->PciExpress->MaxL1Lat == UpPort->PciExpress->MaxL1Lat);
+ //If some links on the Pcie Packet Path does not support certain Lx states,
+ //they will remain in L0 state all the time. Mean while ones that supports,
+ //will transition to Lx power saving state.
+ if( (UpPort->PciExpress->MaxL0Lat == 0xFFFF) ||
+ !(UpPort->PciExpress->LinkCap.AspmSupport & PCIE_ASPM_L0_ENABLE) ||
+ !(DnPort->PciExpress->LinkCap.AspmSupport & PCIE_ASPM_L0_ENABLE) ) Aspm &=(~PCIE_ASPM_L0_ENABLE);
+ if( (UpPort->PciExpress->MaxL1Lat == 0xFFFF) ||
+ !(UpPort->PciExpress->LinkCap.AspmSupport & PCIE_ASPM_L1_ENABLE) ||
+ !(DnPort->PciExpress->LinkCap.AspmSupport & PCIE_ASPM_L1_ENABLE) ) Aspm &=(~PCIE_ASPM_L1_ENABLE);
+
+ aspm=Aspm;
+
+ //Check Setup settings "Force to L0s" must clear calculated PCIE_ASPM_L1_ENABLE;
+ //But should not affect OVERWRITE capabilities.
+ //[Disable]==0\ Auto==55 \ Force L0s==1
+ if(gPciSetupData->AspmMode == 1) aspm &= (~PCIE_ASPM_L1_ENABLE);
+ if(gPciSetupData->AspmMode == 0) aspm = 0;
+ //Now "Aspm" has calculated MAX supported ASPM value
+ //and "aspm" has Updated accordingly to setup
+ dnaspm=aspm;
+ Status=PciPortOemSetAspm(DnPort, &dnaspm);
+ PCI_TRACE((TRACE_PCI," Getting Overwr Aspm Settings for DNSTREAM PORT: Calc ASPM = %X ... Setup ASPM = %X \n",Aspm, aspm));
+
+ upaspm=aspm;
+ Status=PciPortOemSetAspm(UpPort, &upaspm);
+ PCI_TRACE((TRACE_PCI," Getting Overwr Aspm Settings for UPSTREAM PORT: Calc ASPM = %X ... Setup ASPM = %X \n",Aspm, aspm));
+
+ //check UP and DN STREAM ASPM override settings.
+ //and pick smallest one...
+ if(dnaspm<upaspm) aspm=dnaspm;
+ else aspm=upaspm;
+ PCI_TRACE((TRACE_PCI," Status = %r : Calc ASPM = %X ... Overwr ASPM = %X \n",Status,Aspm, aspm));
+
+ //Check if ASPM settings were correctly overwritten
+ //It can't be more than calculated... otherwice system might hung!
+ if (aspm>Aspm){
+ PCI_TRACE((TRACE_PCI," !![Calc ASPM = %X] LESSER THAN [Ovr ASPM = %X] - System Might HUNG. Reset to Calculated!!\n", Aspm, aspm));
+ aspm=Aspm;
+ }
+
+ PCI_TRACE((TRACE_PCI,"\n"));
+
+ if(aspm) {
+ lnkc.AspmControl=aspm;
+
+ //Set ASPM in UpStream Port First for Function 0
+ Status=PciCfg16(UpPort->RbIo,addr,TRUE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //It is recommended to programm all functions even in
+ //case of ARI device Func0 is in charge for link behavior.
+ if(IsFunc0OfMfDev(UpPort)){
+ UINTN i;
+ PCI_DEV_INFO *dev;
+ //--------------------------
+ for(i=0; i<UpPort->FuncCount; i++){
+ dev=UpPort->DevFunc[i];
+
+ if(dev->PciExpress==NULL) continue;
+
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ //Read what we have there
+ Status=PciCfg16(dev->RbIo,addr,FALSE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ lnkc.AspmControl=aspm;
+
+ Status=PciCfg16(dev->RbIo,addr,TRUE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ }
+
+ //Select lnk Control Register of Down Stream port
+ addr.ADDR=DnPort->Address.ADDR;
+ addr.Addr.Register=DnPort->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ //Read what we have there
+ Status=PciCfg16(DnPort->RbIo,addr,FALSE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Set ASPM for Downstream Port
+ lnkc.AspmControl=aspm;
+
+ //Write Back
+ Status=PciCfg16(DnPort->RbIo,addr,TRUE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+ }//if(Aspm)
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieApplyDevSettings()
+//
+// Description: This function will Select values for DEVICE CONTROL register
+// based on Setup Settings and hardware capabilities.
+//
+// Input:
+// PCI_DEV_INFO *EndPoint Pointer to PCI Device Private Data.
+// UINT16 MaxPayload MaxPayload value.
+// UINT16 LatencyL0s Latency L0s value.
+// UINT16 LatencyL1 Latency L1 value.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieApplyDevSettings(PCI_DEV_INFO *EndPoint, UINT16 MaxPayLoad, UINT16 LatencyL0s, UINT16 LatencyL1){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_DEV_INFO *dn, *up, *f0=NULL;
+ UINTN i;
+ UINT16 aspmc=0, mpl=0;
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ BOOLEAN pe2=FALSE;
+#endif
+//--------------------
+ up=EndPoint;
+ if(!IsFunc0(up)) up=up->Func0;
+
+ if(up->PciExpress->DeviceCap.EpL0Latency >= LatencyL0s) aspmc |= PCIE_ASPM_L0_ENABLE;
+ if(up->PciExpress->DeviceCap.EpL1Latency >= LatencyL1) aspmc |= PCIE_ASPM_L1_ENABLE;
+
+
+ PCI_TRACE((TRACE_PCI,"\nPciE: PcieApplyDevSettings() -> Starting with Device [B%X|D%X|F%X]\n",
+ up->Address.Addr.Bus,up->Address.Addr.Device, up->Address.Addr.Function));
+
+
+ //Check if we need to initialize Pcie2 features as well
+ //it will happened if both sides of the link supports PcieGen2 spec
+#if PCI_EXPRESS_GEN2_SUPPORT
+ if((up->ParentBrg->PciExpress->Pcie2!=NULL)&&(up->PciExpress->Pcie2!=NULL))pe2=TRUE;
+#endif
+
+ do{
+ if(up==NULL || up->ParentBrg==NULL)break;
+ f0=NULL;
+ dn=up->ParentBrg;
+ //optimal MPL calculated and passed here;
+ mpl=MaxPayLoad;
+
+ //Set fetures selected in SETUP
+ PCI_TRACE((TRACE_PCI,"#---> EndPoint/UPSTREAM @ [B%X|D%X|F%X] ASPM=%X; MPL=%X;\n",
+ up->Address.Addr.Bus,up->Address.Addr.Device, up->Address.Addr.Function, aspmc, mpl));
+
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ if(pe2){
+ //If applicable
+ //Set Device fetures for GEN2 devices
+ Status=Pcie2SetDevProperties(up);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+#endif
+
+ Status=PcieSetDevProperties(up, mpl);
+
+ //SetFlag DevProgrammed FLAG..
+ up->PciExpress->DevSet=TRUE;
+
+ //Remove processed entrie from EndPoint Database...
+ Status=PcieRemoveEpFromLst(up);
+
+
+ //If we got an EndPoint and it is a Multy Func device - go and update all it's functions...
+ if(up->PciExpress->PcieCap.PortType == PCIE_TYPE_ENDPOINT ||
+ up->PciExpress->PcieCap.PortType == PCIE_TYPE_PCIE_PCI ||
+ up->PciExpress->PcieCap.PortType == PCIE_TYPE_LEGACYEP ||
+ up->PciExpress->PcieCap.PortType == PCIE_TYPE_UPS_PORT )
+ {
+ f0=up;
+ for (i=0; i<f0->FuncCount; i++){
+ up=f0->DevFunc[i];
+
+ PCI_TRACE((TRACE_PCI,"#---> EndPoint/UPSTREAM Function @ [B%X|D%X|F%X] ASPM=%X; MPL=%X;\n",
+ up->Address.Addr.Bus,up->Address.Addr.Device, up->Address.Addr.Function, aspmc, mpl));
+
+ if(up->PciExpress==NULL) continue;
+
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ if(pe2){
+ //If applicable
+ //Set Device fetures for GEN2 devices
+ Status=Pcie2SetDevProperties(up);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+#endif
+
+ //Set fetures selected in SETUP
+ Status=PcieSetDevProperties(up, mpl);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //SetFlag DevProgrammed FLAG..
+ up->PciExpress->DevSet=TRUE;
+
+ //Remove processed entrie from EndPoint Database...
+ Status=PcieRemoveEpFromLst(up);
+ } //for
+ }//if Mf endpoint
+
+ //Restore "up" var
+ if(f0!=NULL) up=f0;
+
+ PCI_TRACE((TRACE_PCI,"<---# RootComp/DNSTREAM @ [B%X|D%X|F%X] ASPM=%X; MPL=%X;\n",
+ dn->Address.Addr.Bus,dn->Address.Addr.Device, dn->Address.Addr.Function, aspmc, mpl));
+
+ //now do the DownStream Port... it always ONLY one device!
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ if(pe2){
+ //If applicable
+ //Set Device fetures for GEN2 devices
+ Status=Pcie2SetDevProperties(dn);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+#endif
+ Status=PcieSetDevProperties(dn,mpl);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ //Aspm is off at that point.
+ //We should turn it on first in UPSTREAM PORT, than IN DOWNSTREAM port.
+ //Since we can owerwrite Settings
+ Status=PcieSetAspm(dn,up,aspmc);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //SetFlag DevProgrammed FLAG..
+ dn->PciExpress->DevSet=TRUE;
+
+ //Remove processed entrie from EndPoint Database...
+ //Status=PcieRemoveEpFromLst(dn);
+
+ //Go to the next link if any...
+ up=dn->ParentBrg;
+ } while (up!=NULL && up->ParentBrg!=NULL && up->ParentBrg->Type!=tPciRootBrg && up->ParentBrg->PciExpress!=NULL); //(EIP49743)
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieInitDevChain()
+//
+// Description: This function will detect optimal settings and programm -
+// MaxPayLoadSize, ReadRequestSize, ASPM settings and Virtual Channels
+// for all devices in the PCIE Links Chain.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Notes:
+// RootPortComplex<=>Switch0...<=>...SwitchN<=>EndPoint
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieInitDevChain(PCI_DEV_INFO* Device ){
+ EFI_STATUS Status=0;
+ UINT16 mpl=-1,mrr=-1;
+ UINTN lt0=0,lt1=0; //Latency in Nano Seconds.
+ UINT16 reg_lt0=0,reg_lt1=0;//Latency to be written into Register.
+#if EFI_DEBUG == 1 //debug
+//------------------------------
+ PCIE_PCIE_CAP_REG pciecap;
+ PCIE_DEV_CAP_REG devcap;
+ PCIE_LNK_CAP_REG lnkcap;
+ PCIE_SLT_CAP_REG sltcap;
+
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ PCIE_DEV_CAP2_REG devcap2;
+ PCIE_LNK_CAP2_REG lnkcap2;
+#endif
+//-----------------------------
+#endif //debug
+//-----------------------
+
+ //Now we will programm clock config when exiting from the bridge
+ //Collect Min Supported feature at the length of the PCIE Devices Chain
+#if EFI_DEBUG == 1 //debug
+ pciecap.PCIE_CAP=Device->PciExpress->PcieCap.PCIE_CAP;
+ devcap.DEV_CAP=Device->PciExpress->DeviceCap.DEV_CAP;
+ lnkcap.LNK_CAP=Device->PciExpress->LinkCap.LNK_CAP;
+ sltcap.SLT_CAP=Device->PciExpress->SlotCap.SLT_CAP;
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ devcap2.DEV_CAP2=Device->PciExpress->Pcie2->DeviceCap2.DEV_CAP2;
+ lnkcap2.LNK_CAP2=Device->PciExpress->Pcie2->LinkCap2.LNK_CAP2;
+#endif
+#endif//debug
+
+ //Get MaxPayLoad
+ mpl=PcieCalcMaxPayLoad(Device);
+
+ //After PcieCalcMaxPayLoad() Payload has to be adjusted DOWN STREAM already (towards EP Device)...
+ //When We come here ASPM already disabled by PcieProbeDevice() function.
+ //Since we are going to use Porting Hook to overwrite ASPM settings Calculate Latency OLWAYS
+ //and Enable it only if Setup says so...- will be done in PcieSetAspm()
+
+
+ //Get L0s L1 exit Latencies if needed...
+// if(gPciSetupData->AspmMode!=0){
+
+ lt0=PcieCalcLatency(Device,TRUE);
+
+ //now we should add CIPSET internal L0s Exit Latency to the total value
+ //For NB if any
+ if( (NbDmiAspmSupport & PCIE_ASPM_L0_ENABLE ) && (SbDmiAspmSupport & PCIE_ASPM_L0_ENABLE )){
+ if(NbDmiL0ExitLatency > SbDmiL0ExitLatency) lt0 += NbDmiL0ExitLatency;
+ else lt0 += SbDmiL0ExitLatency;
+ }
+ //and SB if any
+ reg_lt0+=(UINT16) PcieConvertLatency(lt0, TRUE, FALSE);
+
+// if(gPciSetupData->AspmMode > 1){
+ lt1=PcieCalcLatency(Device,FALSE);
+
+ //now we should add CIPSET L1 Exit Latency to the total value
+ if( (NbDmiAspmSupport & PCIE_ASPM_L1_ENABLE ) && (SbDmiAspmSupport & PCIE_ASPM_L1_ENABLE )){
+ if(NbDmiL1ExitLatency > SbDmiL1ExitLatency) lt1 += NbDmiL1ExitLatency;
+ else lt1 += SbDmiL1ExitLatency;
+ }
+ //and SB
+ lt1+=SbInternalDelay;
+ reg_lt1+=(UINT16) PcieConvertLatency(lt1, FALSE, FALSE);
+
+// } else reg_lt1=0xFFFF;
+// } else reg_lt0=0xFFFF;
+
+ //Apply collected values to the devices
+ Status=PcieApplyDevSettings(Device, mpl, reg_lt0, reg_lt1);
+
+ return Status;
+}
+
+#if SRIOV_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProbeSriovDevice()
+//
+// Description: This function will collect information about SRIOV PCIE Device
+// and initialize it based on information collected.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProbeSriovDevice(PCI_DEV_INFO *Device, UINT32 SriovCapBaseOffset){
+ EFI_STATUS Status;
+ PCIE_SRIOV_CNT_REG SrIoVControl;
+ UINT32 PageSize, i=0, incr, maxbar;
+ UINT16 InitialFv;
+ UINT16 FirstVfOffset;
+ UINT16 VfStride;
+ UINT16 RoutingId;
+ UINT8 VfMaxBus;
+
+ PCI_BAR *Bar;
+ PCI_CFG_ADDR addr;
+
+ addr.ADDR=Device->Address.ADDR;
+ addr.Addr.ExtendedRegister = SriovCapBaseOffset;
+ PCI_TRACE((TRACE_PCI,"PciBus: Found SRIOV Device @ B%X|D%X|F%X; ", addr.Addr.Bus, addr.Addr.Device, addr.Addr.Function));
+
+// Device->PciExpress->SriovData = MallocZ(sizeof(PCIE_SRIOV_DATA));
+// ASSERT(Device->PciExpress->SriovData!=NULL);
+
+ //Disable VFs before any further manipulations
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_CNT_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&SrIoVControl.SRIOV_CNT);
+ ASSERT_EFI_ERROR(Status);
+ SrIoVControl.VfEnable = 0;
+ SrIoVControl.VfMse = 0;
+ Status=PciCfg16(Device->RbIo,addr,TRUE,&SrIoVControl.SRIOV_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ //Initislize System Page Size
+ //get supported page sizes
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_SUPPORTED_PAGE_SIZES_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&PageSize);
+ ASSERT_EFI_ERROR(Status);
+ PCI_TRACE((TRACE_PCI,"PageSize: Sup=0x%X; ", PageSize));
+ if(PageSize){
+ //find the leftmost non-zero bit
+ for(i=1; (PageSize&i)==0 && i!=0; i<<=1) ;
+ ASSERT(i!=0);
+ //set page size
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_SYSTEM_PAGE_SIZE_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,TRUE,&i);
+ ASSERT_EFI_ERROR(Status);
+ PageSize = 1<<(i+11);
+ }
+ PCI_TRACE((TRACE_PCI,"Progr=0x%X(0x%X); ", i, PageSize));
+
+ //Read InitialFv (number of initially associated VFs)
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_INITIAL_VF_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&InitialFv);
+ ASSERT_EFI_ERROR(Status);
+ PCI_TRACE((TRACE_PCI,"InitialFv=%X; ", InitialFv));
+
+ //Calculate number of buses conumed by VF
+ //Read FirstVfOffset
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_FIRST_VF_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&FirstVfOffset);
+ ASSERT_EFI_ERROR(Status);
+ PCI_TRACE((TRACE_PCI,"FirstVfOffset=%X; ", FirstVfOffset));
+ //Read VfStride
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_VF_STRIDE_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&VfStride);
+ ASSERT_EFI_ERROR(Status);
+ PCI_TRACE((TRACE_PCI,"VfStride=%X; ", VfStride));
+ //Calculate number of busses conusmed by all VF
+ RoutingId = //Request ID of PF
+ (addr.Addr.Bus << 8 ) +
+ (addr.Addr.Device << 3 ) +
+ addr.Addr.Function +
+ FirstVfOffset + (InitialFv-1)*VfStride;
+ VfMaxBus = (UINT8)(RoutingId>>8);
+ PCI_TRACE((TRACE_PCI,"VfMaxBus=%X; ", VfMaxBus));
+ //reserve additional buses consumed by VF
+ mMaxBusFound=VfMaxBus;
+
+ //Read VF BARs
+ addr.Addr.ExtendedRegister=SriovCapBaseOffset+PCIE_SRIOV_VF_BAR0_OFFSET;
+ incr=0;
+ Bar = &Device->PciExpress->SriovData->Bar[0];
+ maxbar = PCI_MAX_BAR_NO;
+ for(i=0; i<maxbar; i++){
+ UINT32 old32, val32;
+ UINT64 old64, val64;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&val32);
+ if(EFI_ERROR(Status)) return Status;
+ ASSERT((val32 & 1)==0) //VF BAR must be MMIO
+ switch (val32 & 0x0F) {
+ case 0x0 :
+ Bar[i].Type=tBarMmio32;
+ Bar[i].DiscoveredType=tBarMmio32;
+ incr=4;
+ break;
+ case 0x4 :
+ Bar[i].Type=tBarMmio64;
+ Bar[i].DiscoveredType=tBarMmio64;
+ incr=8;
+ maxbar--;
+ break;
+ case 0x8 :
+#if PCI_AMI_COMBINE_MEM_PMEM32 == 1
+ Bar[i].Type=tBarMmio32;
+#else
+ Bar[i].Type=tBarMmio32pf;
+#endif
+ Bar[i].DiscoveredType=tBarMmio32pf;
+ incr=4;
+ break;
+ case 0xc :
+ Bar[i].Type=tBarMmio64pf;
+ Bar[i].DiscoveredType=tBarMmio64pf;
+ incr=8;
+ maxbar--;
+ break;
+ default : return EFI_UNSUPPORTED;
+ } //switch
+ Bar[i].ExtOffset=addr.Addr.ExtendedRegister;
+
+ val32=(~0); val64=(~0);
+
+ switch (Bar[i].Type){
+
+ case tBarMmio64pf :
+ case tBarMmio64 :
+ Status=PciCfg64(Device->RbIo,addr,FALSE,&old64);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg64(Device->RbIo,addr,TRUE,&val64);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg64(Device->RbIo,addr,FALSE,&val64);
+ if(EFI_ERROR(Status)) return Status;
+ val64&=(~0x0F); //Mask don't care bits
+ if(val64){
+ Bar[i].Gran=(UINTN)(~val64);
+ Bar[i].Length=Mul64((Bar[i].Gran+1),(UINT32)InitialFv);
+ } else {
+ Bar[i].Type=tBarUnused;
+ }
+ break;
+
+ case tBarMmio32pf :
+ case tBarMmio32 :
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&old32);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg32(Device->RbIo,addr,TRUE,&val32);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&val32);
+ if(EFI_ERROR(Status)) return Status;
+ val32&=(~0x0F);
+ if(val32){
+ Bar[i].Gran=(~val32);
+ Bar[i].Length=Mul64((Bar[i].Gran+1),(UINT32)InitialFv);
+ } else{
+ Bar[i].Type=tBarUnused;
+ }
+ break;
+
+ default : Bar[i].Type=tBarUnused;
+ }//switch
+
+ //Restore Original Value value
+ if(Bar[i].Type!=tBarUnused){
+ if(Bar[i].Type==tBarMmio64pf || Bar[i].Type==tBarMmio64) Status=PciCfg64(Device->RbIo,addr,TRUE,&old64);
+ else Status=PciCfg32(Device->RbIo,addr,TRUE,&old32);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ Bar[i].Owner = Device;
+ addr.Addr.ExtendedRegister+=incr;
+ } // Bar enumeration loop
+ PCI_TRACE((TRACE_PCI,"\n"));
+ return EFI_SUCCESS;
+}
+#endif
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitDeviceVc()
+//
+// Description: This function will Init VC_DATA structure of the "Device".
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data.
+// PCI_CFG_ADDR *DevAddr Pointer to Device Address value.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitDeviceVc(PCI_DEV_INFO *Device, PCI_CFG_ADDR *DevAddr){
+ EFI_STATUS Status;
+ VC_DATA *vcd=MallocZ(sizeof(VC_DATA));
+ VC_RES_DATA *vcrd;
+ UINTN i;
+ PCI_CFG_ADDR addr;
+//-----------------
+ addr.ADDR=DevAddr->ADDR;
+ if(!vcd) return EFI_OUT_OF_RESOURCES;
+
+ Device->PciExpress->VcData=vcd;
+ vcd->VcOffset=addr.Addr.ExtendedRegister;
+ //Read and store VC Cap 1 reg
+ addr.Addr.ExtendedRegister=vcd->VcOffset+PCIE_PORTVC_CAP1_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&vcd->VcCap1.PORTVC_CAP1);
+ ASSERT_EFI_ERROR(Status);
+
+ //Read and store VC Cap 2 reg
+ addr.Addr.ExtendedRegister=vcd->VcOffset+PCIE_PORTVC_CAP2_OFFSET;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&vcd->VcCap2.PORTVC_CAP2);
+ ASSERT_EFI_ERROR(Status);
+
+ //Collect VC resource info...
+ for(i=0; i<vcd->VcCap1.ExtVcCnt+vcd->VcCap1.LPExtVcCnt+1; i++){
+ vcrd=MallocZ(sizeof(VC_RES_DATA));
+ if(!vcrd) return EFI_OUT_OF_RESOURCES;
+ addr.Addr.ExtendedRegister=(UINT32)(vcd->VcOffset+PCIE_VC_RES_CAP_OFFSET(i));
+ //Record Offset of the VC resource capability register
+ vcrd->VcResOffset=addr.Addr.ExtendedRegister;
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&vcrd->VcResCap.VC_RESCAP);
+ ASSERT_EFI_ERROR(Status);
+
+ Status=AppendItemLst((T_ITEM_LIST*)&vcd->InitCnt, vcrd);
+ if(EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ }
+ return Status;
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieProbeDevice()
+//
+// Description: This function will collect information about PCIE Device
+// and initialize it based on information collected.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Notes: The function will do the following steps
+// 1.disable ASPM if any;
+// 2.disable PMI Generation if any;
+// 3.power up PCIE Slot (if capable) if the slot has device behind it;
+// 4.if nothing connected to slot, power it down to make it HOTPLUG READY;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PcieProbeDevice(PCI_DEV_INFO *Device){
+ PCI_CFG_ADDR addr;
+ PCIE_DEV_CNT_REG devc;
+ PCIE_LNK_CNT_REG lnkc;
+ PCIE_EXT_CAP_HDR extcap;
+ PCIE_LNK_STA_REG lnks;
+ EFI_STATUS Status=0;
+//-------------------------------------
+
+ //init fields that not suppose to be 0
+ Device->PciExpress->MaxL0Lat=0xFFFF;
+ Device->PciExpress->MaxL1Lat=0xFFFF;
+
+ addr.ADDR=Device->Address.ADDR;
+
+ //Get PCI Express CAPs - 16 bit
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_CAP_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&Device->PciExpress->PcieCap.PCIE_CAP);
+ ASSERT_EFI_ERROR(Status);
+
+ Status=PcieGetCaps(Device);
+ ASSERT_EFI_ERROR(Status);
+
+ //Get PCI Express Slot it is valid only for Ports Switches and Bridges
+ if((Device->Type==tPci2PciBrg) || (Device->Type==tPci2CrdBrg)) PcieSetSlotProperties(Device);
+
+ //Disable Device Control Reg functions we'll not need now
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_DEV_CNT_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+ //Set Default values
+ devc.CorrErrRep=0; //bit 0
+ devc.NfErrRep=0; //bit 1
+ devc.FatalErrRep=0; //bit 2
+ devc.UsupReqRep=0; //bit 3
+ devc.RelaxOrder=1; //bit 4
+ devc.MaxPayload=PCIE_MAXPL_128B;//bit 5..7
+ devc.ExtTagFld=0; //bit 8
+ devc.PhantomFunc=0; //bit 9
+ devc.NoSnoop=1; //bit 11
+ //Don't touch MRR value it might be device dependent and may cause system hung
+ //devc.MaxReadReq=PCIE_MAXPL_512B;//bit 12..14
+
+ Status=PciCfg16(Device->RbIo,addr,TRUE,&devc.DEV_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ //Get common Lnk Properties from LNK_STA reg..
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_STA_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&lnks.LNK_STA);
+ ASSERT_EFI_ERROR(Status);
+
+ //Update data
+ Device->PciExpress->CurrLnkSpeed=(UINT8)lnks.LnkSpeed;
+ Device->PciExpress->CurrLnkWidth=(UINT8)lnks.LnkWidth;
+
+ //Disable ASPM
+ addr.Addr.Register=Device->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ Status=PciCfg16(Device->RbIo,addr,FALSE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ lnkc.AspmControl=PCIE_ASPM_DISABLE;
+ lnkc.ExtSynch=0;
+
+ Status=PciCfg16(Device->RbIo,addr,TRUE,&lnkc.LNK_CNT);
+ ASSERT_EFI_ERROR(Status);
+
+ //Check Pci Express Extended Capability header
+ addr.Addr.ExtendedRegister=0x100;
+ //if something there advance trough EXT capabilities list to find VC Cap
+ while(addr.Addr.ExtendedRegister){
+ Status=PciCfg32(Device->RbIo,addr,FALSE,&extcap.EXT_CAP_HDR);
+ ASSERT_EFI_ERROR(Status);
+ //Check if Extended PciExpress Config Space is assessible.
+ if(extcap.ExtCapId==0xFFFF) break; //(EIP19144+)
+
+ //we've got VC Cap header
+ if(extcap.ExtCapId==PCIE_CAP_ID_VIRTUAL_CH){
+ PCI_TRACE((TRACE_PCI,"PciE2: Found VIRTUAL_CHNL Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+ Status=InitDeviceVc(Device, &addr);
+ ASSERT_EFI_ERROR(Status);
+ }
+#if SRIOV_SUPPORT
+ if (extcap.ExtCapId==PCIE_CAP_ID_SRIOV){
+ PCI_TRACE((TRACE_PCI,"PciE2: Found SRIOV Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+ Status=CollectDeviceExtCap(Device, &Device->PciExpress->SriovData, sizeof(PCIE_SRIOV_DATA),
+ addr.Addr.ExtendedRegister, FALSE, 0); //32 bit cap register
+ ASSERT_EFI_ERROR(Status);
+
+ Status=ProbeSriovDevice(Device, addr.Addr.ExtendedRegister);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Check and collect capability (read only) data from devices
+ //1. Alternative Routing ID capabilities
+ if (extcap.ExtCapId==PCIE_CAP_ID_ARI){
+ PCI_TRACE((TRACE_PCI,"PciE2: Found ARI Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+
+ Status=CollectDeviceExtCap(Device, &Device->PciExpress->AriData, sizeof(PCIE2_ARI_DATA),
+ addr.Addr.ExtendedRegister, TRUE, 0); // 16 bit cap reg
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //2. Access Control Services
+ if (extcap.ExtCapId==PCIE_CAP_ID_ACS){
+ PCI_TRACE((TRACE_PCI," PciE2: Found ACS Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+ Status=CollectDeviceExtCap(Device, &Device->PciExpress->AcsData, sizeof(PCIE2_ACS_DATA),
+ addr.Addr.ExtendedRegister, TRUE, 0); // 16 bit cap reg
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //3. Address Translation services
+ if (extcap.ExtCapId==PCIE_CAP_ID_ATS){
+ PCI_TRACE((TRACE_PCI,"PciE2: Found ATS Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+ Status=CollectDeviceExtCap(Device, &Device->PciExpress->AtsData, sizeof(PCIE2_ATS_DATA),
+ addr.Addr.ExtendedRegister, TRUE, 0); // 16 bit cap reg
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#if PCI_EXPRESS_GEN3_SUPPORT
+ //check for Secondary PCIe Extended Capability header.
+ //must be implemented if device supports GEN 3 speed of 8.0 GT/s
+ if (extcap.ExtCapId==PCIE_CAP_ID_SEC_PCIE_CAP){
+ PCI_TRACE((TRACE_PCI,"PciE3: Found SEC PCIe Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+ Status=CollectDeviceExtCap(Device, &Device->PciExpress->Pcie3, sizeof(PCIE3_DATA),
+ addr.Addr.ExtendedRegister, FALSE, 4); // 32 bit cap reg
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+#endif //gen2 support
+ //4. Internal RC Link
+ if (extcap.ExtCapId==PCIE_CAP_ID_RC_INT_LNK){
+ PCI_TRACE((TRACE_PCI,"PciE2: Found INT_LINK Ext Cap Header @ offset 0x%X\n", addr.Addr.ExtendedRegister));
+ Status=CollectDeviceExtCap(Device, &Device->PciExpress->RcLnkData, sizeof(PCIE_RCLNK_DATA),
+ addr.Addr.ExtendedRegister, FALSE, 0); // 32 bit cap reg
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ addr.Addr.ExtendedRegister=extcap.NextItemPtr;
+ } //while loop serching for ext caps
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //if PciExpress Capability Reg if it supports PCIe 2.1
+ if(Device->PciExpress->PcieCap.CapVersion>=PCIE_CAP_VER2){
+ Device->PciExpress->Pcie2=MallocZ(sizeof(PCIE2_DATA));
+ if(Device->PciExpress->Pcie2==NULL){
+ ASSERT_EFI_ERROR(EFI_OUT_OF_RESOURCES);
+ return EFI_OUT_OF_RESOURCES;
+ } else Status=Pcie2GetGen2Info(Device);//Function Will update GEN 3 Properties as well...
+ }
+#endif
+
+ //If device is Upstream Port type add it to an EndPoint device list.
+ if(!PcieIsDownStreamPort(Device) && (Device->Type!= tPci2PciBrg) &&
+ (Device->PciExpress->PcieCap.PortType!=PCIE_TYPE_RC_INTEGR_EP) &&
+ (Device->PciExpress->PcieCap.PortType!=PCIE_TYPE_RC_EVT_COLLECT) &&
+ (Device->ParentBrg->ParentBrg != NULL))
+ {
+ Status=AppendItemLst(&gPcieEpList, Device);
+ PCI_TRACE((TRACE_PCI,"PciE: Adding Device [B%X|D%X|F%X] to gPcieEpList[%d]\n",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device, Device->Address.Addr.Function, gPcieEpList.ItemCount));
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PcieRecordBootScript()
+//
+// Description: This function will create S3 Resume Boot Script
+// for Device's Virtual Channels feature initialization if device
+// supports Virtual Channels.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PcieRecordBootScript(PCI_DEV_INFO *Brg){
+ PCI_DEV_INFO *dev;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Brg+1);
+ UINTN i,c;
+ PCI_CFG_ADDR addr;
+ EFI_STATUS Status;
+ UINT64 v=0;
+//------------------------------
+ for(i=0; i<ext->ChildCount; i++){
+ dev=ext->ChildList[i];
+ if(!dev->PciExpress) continue;
+ //It could be the case when we have PCI 2 PCI bridges chain and behind
+ //them we will found PCI 2 PCIE bridge. So starting from ROOT we should not
+ //skip bridges without PCIE Capabilities but must go inside and check!
+ //if((dev->PciExpress==NULL) || (dev->Type!=tPci2PciBrg && dev->Type!=tPci2CrdBrg)) continue;
+
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.ExtendedRegister=0;
+ //if device is PciExpress check if it has VC
+ if(dev->Type==tPci2PciBrg || dev->Type==tPci2CrdBrg){
+ //record Base bus Subordinste bus Secondary bus registers programming
+ //to have device visible on the bus
+ addr.Addr.Register=PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET;
+
+ Status=PciCfg32(dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+ //call the same function recoursively
+ PcieRecordBootScript(dev);
+
+ }
+ if(dev->PciExpress->VcData){
+ //if(dev->PciExpress!=NULL && dev->PciExpress->VcData!=NULL){
+ for(c=0; c<dev->PciExpress->VcData->VcCount; c++){
+ VC_RES_DATA *vcrd=dev->PciExpress->VcData->VcResData[c];
+ //---------------------------------------
+ addr.Addr.ExtendedRegister=vcrd->VcResOffset+4;
+ Status=PciCfg32(dev->RbIo,addr,FALSE,(UINT32*)&v);
+
+ BOOT_SCRIPT_S3_MEM_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ PCIE_CFG_ADDR(addr.Addr.Bus,addr.Addr.Device,addr.Addr.Function,addr.Addr.ExtendedRegister),
+ 1,&v); //Data
+ }
+ }
+
+ if (gPciSetupData->S3PciExpressScripts){
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_DEV_CNT_OFFSET;
+ Status=PciCfg16(dev->RbIo,addr,FALSE,(UINT16*)&v);
+
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,
+ 1,&v); //Data
+
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_LNK_CNT_OFFSET;
+ Status=PciCfg16(dev->RbIo,addr,FALSE,(UINT16*)&v);
+
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,
+ 1,&v); //Data
+
+ if(dev->PciExpress->PcieCap.SlotImpl){
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_SLT_CNT_OFFSET;
+ Status=PciCfg16(dev->RbIo,addr,FALSE,(UINT16*)&v);
+
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,
+ 1,&v); //Data
+ }
+ if(dev->PciExpress->Pcie2){
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_DEV_CNT2_OFFSET;
+ Status=PciCfg16(dev->RbIo,addr,FALSE,(UINT16*)&v);
+
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,
+ 1,&v); //Data
+
+ addr.ADDR=dev->Address.ADDR;
+ addr.Addr.Register=dev->PciExpress->PcieOffs+PCIE_LNK_CNT2_OFFSET;
+ Status=PciCfg16(dev->RbIo,addr,FALSE,(UINT16*)&v);
+
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,
+ 1,&v); //Data
+ }
+ } // if (gPciSetupData->S3PciExpressScripts)
+ }//for
+}
+//----------------------------------------------------------------------------
+//Enable PCI Express Handling only if PCI Express Base is Defined and !=0
+#endif //PCI_EXPRESS_SUPPORT
+//----------------------------------------------------------------------------
+
+#if S3_VIDEO_REPOST_SUPPORT == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveBars()
+//
+// Description: This function will create S3 Resume Boot Script
+// for Device's BAR Registers.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+//
+// Output:
+// Nothing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SaveBars(PCI_DEV_INFO *Dev){
+ UINTN i;
+ PCI_BAR *bar;
+ PCI_CFG_ADDR addr;
+ EFI_STATUS Status;
+ UINT64 v=0;
+ PCI_BRG_EXT *ext;
+//----------------------------
+
+ for( i=0; i < PCI_MAX_BAR_NO+1; i++){
+ bar=&Dev->Bar[i];
+ addr.ADDR=Dev->Address.ADDR;
+ addr.Addr.ExtendedRegister=0;
+
+ if( (bar->Type != tBarUnused) && (bar->Length != 0)){
+ addr.Addr.Register=bar->Offset;
+ if( (Dev->Bar[0].DiscoveredType == tBarMmio64) || (Dev->Bar[0].DiscoveredType == tBarMmio64pf)){
+ Status=PciCfg64(Dev->RbIo,addr,FALSE,&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint64, //Width
+ addr.ADDR,1,&v); //Address, Data
+ } else {
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+ }
+ }
+ } //for
+
+ //if device is p2p bridge
+ if( Dev->Type == tPci2PciBrg){
+ //get bridge extension structure pointer
+ ext=(PCI_BRG_EXT*)(Dev+1);
+
+ //For IO 16 Resources Decoded by the bridge
+ addr.Addr.Register = ext->Res[rtIo16].Offset;
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,(UINT16*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,1,&v); //Address, Data
+ //Upper 16bits for IO window
+ addr.Addr.Register = 0x30;
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+
+ //For MMIO Resources Decoded by the bridge
+ addr.Addr.Register = ext->Res[rtMmio32].Offset;
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+ //For MMIO_PF
+ addr.Addr.Register = ext->Res[rtMmio32p].Offset;
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+ //For MMIO_PF Upper 32 bit
+ addr.Addr.Register = 0x28;
+ Status=PciCfg64(Dev->RbIo,addr,FALSE,&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint64, //Width
+ addr.ADDR,1,&v); //Address, Data
+ }
+
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SaveDevice()
+//
+// Description: This function will create S3 Resume Boot Script
+// for Device's other than BAR Registers.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure.
+//
+// Output:
+// Nothing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SaveDevice(PCI_DEV_INFO *Dev){
+ PCI_CFG_ADDR addr;
+ EFI_STATUS Status;
+ UINT64 v=0;
+//----------------------------
+ addr.ADDR=Dev->Address.ADDR;
+ addr.Addr.ExtendedRegister=0;
+
+ //get Cache line size and Latency Timer + ProgInterface
+ addr.Addr.Register=PCI_CLS;
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+ //Save content of BARs
+ SaveBars(Dev);
+
+ //get IntLine; IntPin; MaxLat; MinGnt
+ addr.Addr.Register=PCI_INTLINE;
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+
+
+ //if device is Pci2PciBrg
+ if( Dev->Type == tPci2PciBrg){
+
+ //get Base bus Subordinste bus Secondary bus registers + Secondary Latency Timer
+ addr.Addr.Register=PCI_BRIDGE_PRIMARY_BUS_REGISTER_OFFSET;
+
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+
+ } else {
+ //Get Subsystem VID; DID Just In case...
+ addr.Addr.Register=PCI_SVID;
+ Status=PciCfg32(Dev->RbIo,addr,FALSE,(UINT32*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint32, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+ }
+
+ //Now get Device Control Reg
+ addr.Addr.Register=PCI_COMMAND_REGISTER_OFFSET;
+ Status=PciCfg16(Dev->RbIo,addr,FALSE,(UINT16*)&v);
+ BOOT_SCRIPT_S3_PCI_CONFIG_WRITE_MACRO(
+ gBootScriptSave, //This
+ EfiBootScriptWidthUint16, //Width
+ addr.ADDR,1,&v); //Address, Data
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecordPriVgaBootScript()
+//
+// Description: This function will create S3 Resume Boot Script
+// for Device's on the path of primary VGA Device inclusive.
+//
+// Input:
+// Nothing
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RecordPriVgaBootScript(IN EFI_EVENT Event, IN VOID *Context){
+ PCI_DEV_INFO *vga=NULL;
+ PCI_DEV_INFO *dev;
+ PCI_HOST_INFO *hst=&gPciHost[0];
+ PCI_BRG_EXT *ext;
+ T_ITEM_LIST VgaPath={0,0,NULL};
+ INTN i;
+ UINTN j;
+ EFI_STATUS Status;
+//------------------------------
+ for( i=0; (UINTN)i<gHostCnt; i++){
+ hst=&gPciHost[i];
+ //There might be only one legacy VGA device in the system
+ if( hst->VgaDev!=0){
+ vga=hst->VgaDev;
+ break;//there will be only one Primary VGA
+ }
+ }
+
+ //If we can't find Primery VGA device just exit
+ //Most likely we are dealing here with headless system.
+ if( vga == NULL){
+ return;
+ }
+
+ dev = vga;
+ //Save Device pointers in Current Primary Vga Path
+ while (dev!=NULL){
+ Status=AppendItemLst(&VgaPath,dev);
+ dev=dev->ParentBrg;
+ }
+
+ //Now write the boot script in opposite order for the devices stored @ VgaPath object.
+ //So the script will go from Host Bridge down to the Pri VGA device
+ for(i=VgaPath.ItemCount-1; i>=0;i--){
+ dev=(PCI_DEV_INFO*)VgaPath.Items[i];
+
+ //Save device content into BOOT SCRIPT
+ SaveDevice(dev);
+
+ //Now check if device is a multifunction device
+ //if so it's other functions needs to be saved as well
+ if( ( dev->ParentBrg !=NULL) && ( dev->Type != tPci2PciBrg)){
+
+ ext = (PCI_BRG_EXT*)(dev->ParentBrg+1);
+ //check for devices with the same Dev# but different Function# among device's ParentBridge childs...
+ for(j=0; j<ext->ChildCount; j++){
+ vga=ext->ChildList[j];
+ //Since this is one bridge childs they have to have same bus
+ if(vga->Address.Addr.Device == dev->Address.Addr.Device &&
+ vga->Address.Addr.Function != dev->Address.Addr.Function) {
+ SaveDevice(vga);
+ }
+
+ }//for j
+ }
+ }//for i
+
+ pBS->CloseEvent(Event);
+}
+#endif //S3_VIDEO_REPOST
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetDevicePm()
+//
+// Description: This function will turn off SMI generation on PCI PME
+// and put device in to D0 state, if device has PM capability.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Device Private Data structure.
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ResetDevicePm(PCI_DEV_INFO *Device)
+{
+ EFI_STATUS Status;
+ PCI_CFG_ADDR devaddr;
+ UINT16 pmcsrv=0x8000;//Turn off the PME assertion and set D0 PM State
+//-------------------------------
+
+ if(Device->PmiCapOffs){
+ devaddr.ADDR=Device->Address.ADDR;
+ devaddr.Addr.Register=(UINT8)(Device->PmiCapOffs+4); //
+ Status=PciCfg16(Device->RbIo,devaddr,TRUE,&pmcsrv);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: QueryPciDevice()
+//
+// Description: This function will collect all possible data about PCI Device.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS QueryPciDevice(PCI_DEV_INFO *Device)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINT8 maxbar, i, incr=0;
+ UINT64 buff=0xff, oldv;
+ PCI_CFG_ADDR devaddr;
+ UINT32 *b32=&(UINT32)buff, *o32=&(UINT32)oldv;
+//------------------------------------------
+
+ //for accuracy
+ Device->Address.Addr.Register=0;
+ Device->Address.Addr.ExtendedRegister=0;
+ devaddr.ADDR=Device->Address.ADDR;
+
+ PCI_TRACE((TRACE_PCI,"PciBus: Discovered PCI Device @ [B%X|D%X|F%X]; PCI_DEV_INFO.Type=%d.\n Device Data: -> ",
+ Device->Address.Addr.Bus, Device->Address.Addr.Device,
+ Device->Address.Addr.Function, Device->Type));
+
+ //Clear Interrupt line register
+ devaddr.Addr.Register=PCI_INTLINE;
+ //P2P Bridge Spec. v1.1 requires to set INT Line Register to 0xFF
+ //PCI spec 3.0 require to set it to 0xFF - means not connected for x86 architecture.
+ //Values of 0..0x0F indicating IRQ0..15 values 0x10..0xFE reserved.
+ Status=PciCfg8(Device->RbIo,devaddr,TRUE,(UINT8*)&buff);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //We must call Preprocess Controller
+ Status=DoPrepController(Device);
+
+ Status=GetDeviceCapabilities(Device);
+
+ Status=GetPciCapPtrs(Device);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ ResetDevicePm(Device);
+
+ //Set Pci Latency Timer register according to the Setup settings;
+ devaddr.Addr.Register = 0x0d;
+ Status=PciCfg8(Device->RbIo,devaddr,TRUE,(UINT8*)&gPciSetupData->PciLatency);
+ if((Device->Type == tPci2PciBrg) || (Device->Type == tPci2CrdBrg)){
+ devaddr.Addr.Register = 0x1b;
+ Status=PciCfg8(Device->RbIo,devaddr,TRUE,(UINT8*)&gPciSetupData->PciLatency);
+ }
+
+#if PCI_X_SUPPORT
+ //Set PCI-X Latency Timer register according to the Setup settings;
+ devaddr.Addr.Register = 0x0d;
+ Status=PciCfg8(Device->RbIo,devaddr,TRUE,(UINT8*)&gPciSetupData->PciXLatency);
+ if((Device->Type == tPci2PciBrg) || (Device->Type == tPci2CrdBrg)){
+ devaddr.Addr.Register = 0x1b;
+ Status=PciCfg8(Device->RbIo,devaddr,TRUE,(UINT8*)&gPciSetupData->PciXLatency);
+ }
+#endif
+
+//Enables PCI Express Handling only if PCI Express Base is Defined and !=0
+#if PCI_EXPRESS_SUPPORT
+
+ if(Device->PciExpress) {
+ Status=PcieProbeDevice(Device);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+/*
+ //If it is end point Device or PCIE 2 PCI bridge
+ if(
+ Device->PciExpress->PcieCap.PortType==PCIE_TYPE_LEGACYEP||
+ Device->PciExpress->PcieCap.PortType==PCIE_TYPE_PCIE_PCI||
+ Device->PciExpress->PcieCap.PortType==PCIE_TYPE_RC_INTEGR_EP ||
+ Device->PciExpress->PcieCap.PortType==PCIE_TYPE_RC_EVT_COLLECT)
+ {
+ //Programm Common Clock it will affect ASPM latency of the devices
+ //So it has to be programmed first before collecting all the information about
+ //Device Max PLoad ant reqd request and ep Latency.
+ Status=PcieSetClockConfig(Device);
+ ASSERT_EFI_ERROR(Status);
+
+ //Programm MaxPayLoad, ReadRequest ASPM settings
+ Status=PcieInitDevChain(Device);
+ ASSERT_EFI_ERROR(Status);
+ }
+*/
+ }
+#endif
+
+ if(CheckPciCompatibility(Device,NULL,tBarUnused))Device->Incompatible=TRUE; //(EIP41687)
+ switch (Device->Type){
+ case tPci2PciBrg :
+ maxbar=2;
+ devaddr.Addr.Register=0x10; //first BAR starts here
+ break;
+ case tPciDevice :
+ case tPciHostDev:
+ maxbar=PCI_MAX_BAR_NO;
+ devaddr.Addr.Register=0x10; //first BAR starts here
+ break;
+ case tPci2CrdBrg :
+ maxbar=1;
+ devaddr.Addr.Register=0x10; //first BAR starts here
+ break;
+ default : return EFI_SUCCESS; //other devices not suppose to be examined????
+ }
+
+ for(i=0; i<maxbar; i++){
+ buff=0;
+ oldv=0;
+ devaddr.Addr.Register=devaddr.Addr.Register+incr;
+ Status=PciCfg32(Device->RbIo,devaddr,FALSE,b32);
+ if(EFI_ERROR(Status)) return Status;
+
+ //check if what it is...
+ if((*b32) & 1) {
+ Device->Bar[i].Type=tBarIo;
+ incr=4;
+ } else {
+ switch ((*b32) & 0x0F) {
+ case 0x0 :
+ Device->Bar[i].Type=tBarMmio32;
+ Device->Bar[i].DiscoveredType=tBarMmio32;
+ incr=4;
+ break;
+ case 0x4 :
+ Device->Bar[i].Type=tBarMmio64;
+ Device->Bar[i].DiscoveredType=tBarMmio64;
+ incr=8;
+ maxbar--;
+ break;
+ case 0x8 :
+#if PCI_AMI_COMBINE_MEM_PMEM32 == 1
+ Device->Bar[i].Type=tBarMmio32;
+#else
+ Device->Bar[i].Type=tBarMmio32pf;
+#endif
+ Device->Bar[i].DiscoveredType=tBarMmio32pf;
+ incr=4;
+ break;
+ case 0xc :
+ Device->Bar[i].Type=tBarMmio64pf;
+ Device->Bar[i].DiscoveredType=tBarMmio64pf;
+ incr=8;
+ maxbar--;
+ break;
+ default : return EFI_UNSUPPORTED;
+ } //switch
+ }// else for memory BAR
+ Device->Bar[i].Offset=devaddr.Addr.Register;
+ //Device->Bar[i].Owner=Device;
+
+ buff=(~0ULL);
+
+ switch (Device->Bar[i].Type){
+
+ case tBarMmio64pf :
+ case tBarMmio64 :
+ Status=PciCfg64(Device->RbIo,devaddr,FALSE,&oldv);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg64(Device->RbIo,devaddr,TRUE,&buff);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg64(Device->RbIo,devaddr,FALSE,&buff);
+ if(EFI_ERROR(Status)) return Status;
+ buff&=(~0x0F); //Mask don't care bits
+ if(buff){
+ //This workaround done for PCI Compliance Test...
+ //It could be the BAR that clames - "I'm a 64bit BAR",
+ //but implemented as 32bit register. This BAR will not hold
+ //64bit address and must be converted to 32bit BAR.
+ if(buff<=0xFFFFFFFF) {
+ buff|=0xFFFFFFFF00000000;
+ Device->Bar[i].Type-=2; //reduce tBarType to 32 bit BAR
+ }
+ Device->Bar[i].Gran=(UINTN)(~buff);
+ if(Device->Incompatible) AdjustBarGra(&Device->Bar[i]);
+ if(Device->Bar[i].Type==tBarUnused) {
+ Status=PciCfg64(Device->RbIo,devaddr,TRUE,&oldv);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ Device->Bar[i].Length=Device->Bar[i].Gran+1;
+ } else Device->Bar[i].Type=tBarUnused;
+ break;
+
+ case tBarMmio32pf :
+ case tBarMmio32 :
+ case tBarIo :
+ Status=PciCfg32(Device->RbIo,devaddr,FALSE,o32);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg32(Device->RbIo,devaddr,TRUE,b32);
+ if(EFI_ERROR(Status)) return Status;
+ Status=PciCfg32(Device->RbIo,devaddr,FALSE,b32);
+ if(EFI_ERROR(Status)) return Status;
+ if(Device->Bar[i].Type==tBarIo){
+ (*b32)&=(~0x03);
+ if(*b32){
+ //We got something here try to determine is it 32 bit addressing IO
+ //of 16 bit addressing
+ if(*b32&0xFFFF0000) {
+ Device->Bar[i].Type=tBarIo32;
+ Device->Bar[i].DiscoveredType=tBarIo32;
+ } else {
+ (*b32)|=(0xffff0000);
+ Device->Bar[i].Type=tBarIo16;
+ Device->Bar[i].DiscoveredType=tBarIo16;
+ }
+ }
+ } else (*b32)&=(~0x0F);
+ if(*b32){
+ Device->Bar[i].Gran=(~(*b32));
+ if(Device->Incompatible) AdjustBarGra(&Device->Bar[i]);
+ if(Device->Bar[i].Type==tBarUnused) {
+ Status=PciCfg32(Device->RbIo,devaddr,TRUE,o32);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ Device->Bar[i].Length=Device->Bar[i].Gran+1;
+ //Doing work around for resource requirements for I/O
+ //where request is lesser than 16 bytes. I'll just make it 16
+ //it might be some compatibility issues if I/O resourtce alignment will be
+ // lesser than 8 byte
+ if((Device->Bar[i].Type==tBarIo32 || Device->Bar[i].Type==tBarIo16)&&
+ Device->Bar[i].Length<0x10)
+ {
+ Device->Bar[i].Length=0x10;
+ Device->Bar[i].Gran=0x0F;
+ }
+
+ } else Device->Bar[i].Type=tBarUnused;
+ break;
+
+ default : Device->Bar[i].Type=tBarUnused;
+ }//switch
+
+ //Restore Original Value value
+ if(Device->Bar[i].Type!=tBarUnused){
+ if(Device->Bar[i].Type==tBarMmio64pf || Device->Bar[i].Type==tBarMmio64) Status=PciCfg64(Device->RbIo,devaddr,TRUE,&oldv);
+ else Status=PciCfg32(Device->RbIo,devaddr,TRUE,o32);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+//Check that all MMIO is allocated in 4k aligned chanks IVT-d requirements
+#if( (defined iVTd_SUPPORT && iVTd_SUPPORT == 1) || ( PCI_4K_RESOURCE_ALIGNMENT == 1 ) || (SRIOV_SUPPORT == 1) )
+//---------------------------------------------
+ if((Device->Bar[i].Type==tBarMmio64pf || Device->Bar[i].Type==tBarMmio64 ||
+ Device->Bar[i].Type==tBarMmio32pf || Device->Bar[i].Type==tBarMmio32) &&
+ Device->Bar[i].Length<0x1000 ) {
+ Device->Bar[i].Length=0x1000;
+ Device->Bar[i].Gran=0xFFF;
+ }
+//---------------------------------------------
+#endif
+
+ } // Bar enumeration loop
+
+ if(Device->Type==tPci2CrdBrg){
+ //Clear Brg Control Reg bits 8 & 9 to signify that Mem Window 1&2 is not PF
+ devaddr.Addr.Register=PCI_BRIDGE_CONTROL_REGISTER_OFFSET;
+ Status=PciCfg16(Device->RbIo,devaddr,FALSE,(UINT16*)&buff);
+ ASSERT_EFI_ERROR(Status);
+ buff&=(~(BIT09 | BIT08)); //Memory Window 2 is nonPF
+ Status=PciCfg16(Device->RbIo,devaddr,TRUE,(UINT16*)&buff);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //now we're going to check if any Option ROM present
+ Status=OptionRom(Device);
+#if EFI_DEBUG
+ for(i=0; i<=PCI_MAX_BAR_NO; i++){
+
+ if((Device->Bar[i].Type>0) && (Device->Bar[i].Length>0))
+ {
+ PCI_TRACE((TRACE_PCI,"BAR Index=%d;\tType=%d;\tGRA=0x%lX;\tLEN=0x%lX;\tOffset=0x%X;\n",
+ i, Device->Bar[i].Type, Device->Bar[i].Gran,
+ Device->Bar[i].Length, Device->Bar[i].Offset));
+ }
+ }
+ PCI_TRACE((TRACE_PCI,"\n"));
+#endif
+
+ Device->Discovered=TRUE;
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ApplyCrdPadding()
+//
+// Description: This function applys default Card Bus Bridge Padding.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to PCI Device Private Data structure.
+// MRES_TYPE ResType Type of resource padding is applied.
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ApplyCrdPadding(PCI_DEV_INFO *Device, MRES_TYPE ResType){
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Device+1);
+ PCI_BAR *bbar=&ext->Res[ResType];
+//---------------
+
+ bbar->Type=ResType+1;
+ switch(ResType){
+ case rtIo16:
+ bbar->Length+=0x1000;
+ if(bbar->Gran < 0xFFF) bbar->Gran=0xFFF;
+ break;
+
+ case rtIo32:
+ if(CPU_MAX_IO_SIZE <= 0x10000) {
+ bbar->Type=tBarUnused;
+ bbar=&ext->Res[ResType-1];
+ }
+ bbar->Length+=0x1000;
+ if(bbar->Gran < 0xFFF) bbar->Gran=0xFFF;
+ break;
+
+ case rtMmio32:
+ bbar->Length+=0x1400000;
+ if(bbar->Gran < 0xFFFFF) bbar->Gran=0xFFFFF;
+ break;
+
+ case rtMmio32p:
+ if (gAllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM) {
+ bbar->Type=tBarUnused;
+ bbar=&ext->Res[ResType-1];
+ }
+ bbar->Length+=0x1400000;
+ if(bbar->Gran < 0xFFFFF) bbar->Gran=0xFFFFF;
+ break;
+ case rtMmio64:
+ case rtMmio64p:
+ bbar->Type=tBarUnused;
+ break;
+ }
+
+ ext->Padded=TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Cmp128Int()
+//
+// Description: This function compares 2 128 bit integers.
+//
+// Input:
+// VOID* pDestination *Pointer to the 128bit Integer to compare.
+// VOID* pSource *Pointer to the 128bit Integer to compare.
+//
+// Output: INTN
+// == 0 Destination and are Source equal;
+// > 0 Destination is bigger than Source;
+// < 0 Destination is lesser than Source;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN Cmp128Int(VOID* pDestination, VOID* pSource){
+ INT64 r;
+ UINT64 *d=(UINT64*)pDestination;
+ UINT64 *s=(UINT64*)pSource;
+//----------------------------------
+ r = d[1] - s[1];
+ if( r == 0){
+ r = d[0] - s[0];
+ }
+ return (r>0) ? 1 : (r<0) ? -1 : 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Cmp128IntRR()
+//
+// Description: This function compares 2 128 bit integers with respect to EFI
+// Database Engine Record to Record comparation Routine.
+// When position of record gets determined.
+//
+// Input:
+// VOID* pContext Pointer to the DBE_OFFSET_KEY_CONTEXT structure
+// VOID* pRecord1 Pointer to the 128bit Integer to compare.
+// VOID* pRecord2 Pointer to the 128bit Integer to compare.
+//
+// Output: INTN
+// == 0 pRecord1 and are pRecord2 equal;
+// > 0 pRecord1 is bigger than pRecord2;
+// < 0 pRecord2 is lesser than pRecord2;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN Cmp128IntRR(IN VOID *pContext, VOID *pRecord1, VOID *pRecord2)
+{
+ DBE_OFFSET_KEY_CONTEXT *pOffsetKey = (DBE_OFFSET_KEY_CONTEXT*)pContext;
+//--------------------------
+ return Cmp128Int((VOID*)((INT8*)pRecord1+pOffsetKey->Offset),(VOID*)((INT8*)pRecord2+pOffsetKey->Offset));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Cmp128IntKR()
+//
+// Description: This function compares 2 128 bit integers with respect to EFI
+// Database Engine Key to Record comparation Routine.
+// When search for record is conducted.
+//
+// Input:
+// VOID* pContext Pointer to the DBE_OFFSET_KEY_CONTEXT structure
+// VOID* pRecord1 Pointer to the 128bit Integer to compare.
+// VOID* pRecord2 Pointer to the 128bit Integer to compare.
+//
+// Output: INTN
+// == 0 pRecord1 and are pRecord2 equal;
+// > 0 pRecord1 is bigger than pRecord2;
+// < 0 pRecord2 is lesser than pRecord2;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN Cmp128IntKR(IN DBE_OFFSET_KEY_CONTEXT *pContext, VOID *pKey, VOID *pRecord)
+{
+ DBE_OFFSET_KEY_CONTEXT *pOffsetKey = (DBE_OFFSET_KEY_CONTEXT*)pContext;
+//------------------------------
+ return Cmp128Int((VOID*)pKey,(VOID*)((INT8*)pRecord+pOffsetKey->Offset));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FreeResDb()
+//
+// Description: This function suppore to free memory allocated for index array
+// pool of the EFI Database Engine DATABASE.
+//
+// Input:
+// DBE_DATABASE* Db Pointer to the EFI Database Engine DATABASE.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS if everything OK;
+// an EFI_ERROR if an ERROR
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FreeResDb(DBE_DATABASE *Db){
+ if(Db->IndexArray!=NULL)return pBS->FreePool(Db->IndexArray);
+ else return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitResDb()
+//
+// Description: This function suppore to initialize EFI Database Engine DATABASE
+// with PCI_BAR pointers in decending order.
+//
+// Input:
+// DBE_DATABASE* Db Pointer to the EFI Database Engine DATABASE.
+// PCI_DEV_INFO* Brg, Bridge whose BARs must be stuffed in DATABASE.
+// MRES_TYPE ResType Resource type of the BARs.
+// BOOLEAN Dev We are filling DATABASE with Bridges or Devices.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS if everything OK;
+// an EFI_ERROR if an ERROR
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitResDb(DBE_DATABASE *Db, PCI_DEV_INFO *Brg, MRES_TYPE ResType, BOOLEAN Dev){
+ EFI_STATUS Status=0;
+ PCI_DEV_INFO *dev;
+ PCI_BRG_EXT *Ext=(PCI_BRG_EXT*)(Brg+1);
+ UINTN i,j;
+//------------------------------------
+
+ //Initialize Optimization Database
+ Db->KeyCount=1;
+ Db->KeyField=&gBarKey;
+ Db->MemoryType=EfiBootServicesData;
+ Db->RecordCount=0;
+
+ if(Dev)Db->InitialCount=0x30; //least likely it would be more than 48 BARs of the same type
+ else Db->InitialCount=0x10; //same 16 for the bridges, but anyway it would be realocated...
+
+ Status=pBS->AllocatePool(Db->MemoryType,sizeof(VOID*)*Db->InitialCount,&Db->IndexArray);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Now we will stuff the database with resource requirements sorted in assending order
+ for(i=0; i<Ext->ChildCount; i++){
+ dev=Ext->ChildList[i];
+
+ if(dev->OutOfResRemove) continue;
+
+ if(Dev){
+ for( j=0; j<PCI_MAX_BAR_NO+1; j++){
+ //Use ResType+1 Since CountBars() takes diferent type of parameter -
+ //PCI_BAR_TYPE. It mapps to MRES_TYPE as MRES_TYPE+1
+ if ((dev->Bar[j].Type==ResType+1) && dev->Bar[j].Length){
+ Status=DbeInsert(Db,&dev->Bar[j]);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }//bar loop
+#if SRIOV_SUPPORT
+ if (dev->PciExpress!=NULL && dev->PciExpress->SriovData!=NULL){
+ PCI_BAR *VfBar = &dev->PciExpress->SriovData->Bar[0];
+ for( j=0; j<PCI_MAX_BAR_NO; j++){
+ //Use ResType+1 Since CountBars() takes diferent type of parameter -
+ //PCI_BAR_TYPE. It mapps to MRES_TYPE as MRES_TYPE+1
+ if ((VfBar[j].Type==ResType+1) && VfBar[j].Length){
+ Status=DbeInsert(Db,&VfBar[j]);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }//bar loop
+ }
+#endif
+ } else {
+ //take care of the bridge
+ if(dev->Type==tPci2PciBrg || dev->Type==tPci2CrdBrg){
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(dev+1);
+ //-----------------------
+ //Don't add empry bridge BARs
+ if((ext->Res[ResType].Type==ResType+1) && ext->Res[ResType].Length ){
+ Status=DbeInsert(Db,&ext->Res[ResType]);
+ if(EFI_ERROR(Status)) Status;
+ }
+ }
+ }
+ } //child loop
+
+// if(!Db->RecordCount)Status=EFI_NOT_FOUND;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AppendBarOrder()
+//
+// Description: This function suppore to fill array of BAR ORDER with actual
+// order of PCI_BARs behind the Bridge and remove added BAR structure from
+// the BAR DATABASE.
+//
+// Input:
+// DBE_DATABASE* Db Pointer to the EFI Database Engine DATABASE.
+// BRG_RES_ORDER* BrgResOrder Pointer to the Bridge Resource order structure.
+// PCI_BAR Bar Pointer to the BAR structure to be added.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS if everything OK;
+// an EFI_ERROR if an ERROR
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AppendBarOrder(DBE_DATABASE *Db, BRG_RES_ORDER *BrgResOrder, PCI_BAR *Bar){
+ EFI_STATUS Status;
+//--------------------------
+ Status=AppendItemLst((T_ITEM_LIST*)BrgResOrder, Bar);
+ if(EFI_ERROR(Status))return Status;
+
+ //Remove copied record from Database it not suppose to clear the *bar variable;
+ Status=DbeDelete(Db,Bar,FALSE);
+
+ PCI_TRACE((TRACE_PCI," BAR: Len=0x%lX;\t Gra=0x%lX;\t Ofs=0x%X; Owner->[B%X|D%X|F%X] DEV_TYPE=%d\n",
+ Bar->Length, Bar->Gran, Bar->Offset, Bar->Owner->Address.Addr.Bus,
+ Bar->Owner->Address.Addr.Device, Bar->Owner->Address.Addr.Function, Bar->Owner->Type));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OptimizeBrgResource()
+//
+// Description: This function arrange Bridge resource request in a way it will
+// consume a optimal amount of resources.
+//
+// Input:
+// PCI_DEV_INFO* Brg, Bridge whose BARs must be stuffed in DATABASE.
+// MRES_TYPE ResType Resource type we are doing optimization for.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS if everything OK;
+// an EFI_ERROR if an ERROR
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OptimizeBrgResource(PCI_DEV_INFO *Brg, MRES_TYPE ResType){
+ EFI_STATUS Status=0;
+ PCI_DEV_INFO *dev; //Device Dtata used for iteration,
+ PCI_DEV_INFO *brg; //Bridge Device used to identify Bridge resources with uneven Granularity.
+ PCI_BRG_EXT *Ext=(PCI_BRG_EXT*)(Brg+1),*ext; //This Bridge Bridge Extension Data.
+ UINTN i;
+ PCI_BAR *bar,*bbar,*nbbar,*nextbar; //temp BAR used in iterations, This Bridge child who is the bridge.
+ BRG_ALIGN_INFO *balign;
+ PCI_BAR *ebar;
+ BRG_RES_ORDER *ResOrd=&Ext->BarOrder[ResType]; //This Bridge this bridge Resource Alignment information
+ DBE_DATABASE DevDb={0,0,0,0,NULL,NULL},BrgDb={0,0,0,0,NULL,NULL};
+ INT8 v;
+ UINT64 val;
+ UINT8 bit;
+//------------------------------------
+
+ //No childs behind the bridge, no optimization...
+ if(!Ext->ChildCount)return EFI_SUCCESS;
+ PCI_TRACE((TRACE_PCI,"PciBus: OptimizeBrgRes() Bridge->[B%X|D%X|F%X] PCI_BRG_EXT.Res[%d] :\n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device, Brg->Address.Addr.Function, ResType));
+
+
+ //Start the optimization
+ //1. Create Assending Sorted Database of all PCI Devices BARs behind the Brg of ResType.
+ Status=InitResDb(&DevDb, Brg, ResType, TRUE);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+
+ Status=InitResDb(&BrgDb, Brg, ResType, FALSE);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+
+ PCI_TRACE((TRACE_PCI," BAR(s) Order for %d Device BAR(s); %d Bridge BAR(s) of BAR_TYPE=%d\n",
+ DevDb.RecordCount, BrgDb.RecordCount, ResType+1));
+
+ //2. Start Populating Resource Array Brg->BarOrder[ResType]
+ while(DevDb.RecordCount || BrgDb.RecordCount){
+
+ if(BrgDb.RecordCount){
+ Status=DbeGoToIndex(&BrgDb,0,BrgDb.RecordCount-1,&bbar);
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+ } else bbar=NULL;
+
+ if(DevDb.RecordCount){
+ Status=DbeGoToIndex(&DevDb,0,DevDb.RecordCount-1,&bar);
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+ } else bar=NULL;
+
+ //Check if THIS Bridge has a bridge childs
+ if((bar!=NULL) && (bbar!=NULL)){
+ //This case when we have bridge resourses among regular device resources
+ brg=bbar->Owner;
+ dev=bar->Owner;
+ ext=(PCI_BRG_EXT*)(brg+1);
+ balign=&ext->Align[ResType];
+
+ //1. Check first if Biggest resource in "BrgDb" - "bbar" has the same or lesser
+ //Alignment Requirements as a Biggest one in "DevDb" - "bar". balign->MaxGran
+ if(bar->Gran >= balign->MaxGran){
+ Status=AppendBarOrder(&DevDb,ResOrd, bar);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+ } else {
+ //This is the case when we should use PCI_BRG_EXT.ExtraRes[ResType] information to accomodate
+ //resources with lower granularity to utilize spase used to adjust uneven bridge granularity
+ Status=AppendBarOrder(&BrgDb,ResOrd, bbar);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+
+ //Determine how much Extra resources we will use here
+ ebar=&balign->ExtraRes;
+ if(bbar->Length & bbar->Gran){
+ //Here we have add the biggest bridge resource to the BarOrdedr DB.
+ //We have yet Biggrest Dev Resource. Let's see if there are any Bridge resources left
+ if(BrgDb.RecordCount){
+ Status=DbeGoToIndex(&BrgDb,0,BrgDb.RecordCount-1,&nbbar);
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+ } else nbbar=NULL;
+ //Now see which bar (nbbar-NextBridgeBar) if any, or bar-DeviceBar will be the next
+ //member in BarOrder Database.
+ if(nbbar!=NULL){
+ if(bar->Gran>=nbbar->Gran)nextbar=bar;
+ else nextbar=nbbar;
+ } else nextbar=bar;
+
+ //Determine how much Extra resources we will use here
+ //if we got here - the Bridge resource request, we just added to the BarOrder DB, has uneven alignment
+ //Here we have:
+ //bbar - already added to the BarOrder DB;
+ //nextbar - biggest resource following by the bbar;
+ //bar - biggest Device Bar evenly aligned ;
+ if(nextbar->Gran <= balign->ResGran) {
+ //if next biggest bar has Alignment requirements lesser or equal to the bbar just added
+ //GREAT! We will just add it and forget it;
+ if(nextbar==bar)Status=AppendBarOrder(&DevDb,ResOrd, nextbar);
+ else Status=AppendBarOrder(&BrgDb,ResOrd, nextbar);
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+
+ } else {
+ ebar->Length=(( bbar->Length | nextbar->Gran )+1)-bbar->Length;
+ bit=FindFirstBit(ebar->Length-1,FALSE);
+ ebar->Gran=Shr64((~0ULL),64 - bit);
+ }
+ }
+
+ //bar->Gran here < "bbar" MaxGran, so "bar" holds next biggest Gran after the bridge
+ //we will try to adjust Extra Space requested by the bridge, analizing bar->Gran information
+ if(ebar->Length) {
+ while( ebar->Length >= (ebar->Gran+1) ){
+ VOID* p;
+ //-----------------------
+
+ if(!DevDb.RecordCount)break;
+
+ bar=NULL;
+ val=ebar->Gran+1;
+ Status=DbeLocateKey(&DevDb,0,&val,&p,&v, &i);
+
+
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF) || (Status==EFI_NOT_FOUND))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+
+ Status=DbeGoToIndex(&DevDb,0,i,&bar);
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+
+ //if DevDb (who has even sizes) has resource that smaller or equal
+ //we will try to fill Extra Gap...
+ if((v == -1) && (bar!=NULL)){
+ //Database sorted in ascending order. DbeLocateKey() function, parameter "v" tells how close the result is.
+ //if DBE couldn't find exact match, it will return pointer at first element bigger than Parameter Passed.
+ //There fore, if this is the case, we need to go down one index to get a smaller element than Parameter Passed.
+ if(i>0){
+ bar=NULL;
+ Status=DbeGoToIndex(&DevDb,0,i-1,&bar);
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+ } else break; //this will break "while(DevDb.RecordCount || BrgDb.RecordCount)" loop
+ } //if(v==-1 && bar!=NULL)
+
+ if(bar!=NULL && bar->Gran<=ebar->Gran){
+ Status=AppendBarOrder(&DevDb,ResOrd,bar);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+
+ //Adjust ebar->Length and Gran since we have filled out some extra space...
+ ebar->Length-=bar->Length;
+ if(ebar->Length!=0){
+ bit=FindFirstBit(ebar->Length-1,FALSE);
+ ebar->Gran=Shr64((~0ULL),64-bit);
+ } else break; //this will break "while( ebar->Length >= (ebar->Gran+1) )" loop
+ } else break; //this will break "while( ebar->Length >= (ebar->Gran+1) )" loop
+
+ } //while( ebar->Length >= (ebar->Gran+1)
+
+ //if after all efforts we still have extra resources left
+ //Mark ebar->Offset as 0xFF to notify routine which will programm the BARs
+ //Not to toughch this one, but just add ebar->Length before next valid BAR.
+
+ PCI_TRACE((TRACE_PCI," EBAR: Len=0x%lX;\t Gra=0x%lX;\t Ofs=0x%X; Owner [B%X|D%X|F%X] Type=%d\n",
+ ebar->Length, ebar->Gran, ebar->Offset, ebar->Owner->Address.Addr.Bus,
+ ebar->Owner->Address.Addr.Device, ebar->Owner->Address.Addr.Function, ebar->Owner->Type));
+ if(ebar->Length!=0){
+ ebar->Offset=0xFF;
+ ebar->Type=ResType+1;
+ ebar->DiscoveredType=ebar->Type;
+
+ Status=AppendItemLst((T_ITEM_LIST*)ResOrd, ebar);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+ }
+ }//if(ebar->Length)
+ }//else of "if(bar->Gran >= balign->MaxGran)"
+ } else { //"if((bar!=NULL) && (bbar!=NULL))"
+ //This case when we have only one type of resources most likely it would be regular device resources
+ //But just in case do the check
+ if(bbar==NULL) Status=AppendBarOrder(&DevDb,ResOrd,bar);
+ else {
+ ebar=NULL;
+ //If we got only bridges (more than one) behind parent bridge we might got uneven alignment!
+ //So we have to check if Granuilarity requirements satisfactory for them and padd resources if needed.
+ if(BrgDb.RecordCount>1){
+ UINT64 resgran;
+ //---------------------
+ PCI_TRACE((TRACE_PCI," Bridges ONLY found!!! \n"));
+ brg=bbar->Owner;
+ ext=(PCI_BRG_EXT*)(brg+1);
+ balign=&ext->Align[ResType];
+
+ bit=FindFirstBit(bbar->Length-1,FALSE);
+ resgran=Shr64((~0ULL),64-bit);
+
+ if(bbar->Gran>resgran){
+ //get next record
+ Status=DbeGoToIndex(&BrgDb,0,BrgDb.RecordCount-2,&nextbar);
+ if(EFI_ERROR(Status)){
+ if(!((Status==EFI_DBE_EOF) || (Status==EFI_DBE_BOF))){
+ ASSERT_EFI_ERROR(Status);
+ goto ExitLbl;
+ }
+ }
+ //determine extra resource size...
+ ebar=&ext->Align[ResType].ExtraRes;
+ ebar->Length=(( bbar->Length | nextbar->Gran )+1)-bbar->Length;
+ if(ebar->Length!=0){
+ bit=FindFirstBit(ebar->Length-1,FALSE);
+ ebar->Gran=Shr64((~0ULL),64-bit);
+ }
+ }//if(balign->MaxGran>balign->ResGran)
+ }//if(BrgDb.RecordCount>1)
+ Status=AppendBarOrder(&BrgDb,ResOrd,bbar);
+ if(ebar!=NULL && ebar->Length){
+ ebar->Offset=0xFF;
+ ebar->Type=ResType+1;
+ ebar->DiscoveredType=ebar->Type;
+ PCI_TRACE((TRACE_PCI," EBAR: Len=0x%lX;\t Gra=0x%lX;\t Ofs=0x%X; Owner [B%X|D%X|F%X] Type=%d\n",
+ ebar->Length, ebar->Gran, ebar->Offset, ebar->Owner->Address.Addr.Bus,
+ ebar->Owner->Address.Addr.Device, ebar->Owner->Address.Addr.Function, ebar->Owner->Type));
+
+ Status=AppendItemLst((T_ITEM_LIST*)ResOrd, ebar);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto ExitLbl;
+ }
+
+ ASSERT_EFI_ERROR(Status);
+ }
+ if(EFI_ERROR(Status)) goto ExitLbl;
+ }
+
+ }//while(DevDb.RecordCount || BrgDb.RecordCount)
+
+ExitLbl:
+ //Free Memory allocated...
+ FreeResDb(&DevDb);
+ FreeResDb(&BrgDb);
+
+ //if there was an ERROR clear Bridge Resource Ortder Array.
+ if(EFI_ERROR(Status)){
+ ClearItemLst((T_ITEM_LIST*)ResOrd,FALSE);
+ PCI_TRACE((TRACE_PCI,"PciBus: OptimizeBrgResource() returning ERROR=%r\n", Status));
+ }
+
+ return Status;
+
+}
+
+VOID ClearBrgResources(PCI_DEV_INFO *Brg){
+ EFI_STATUS Status=0;
+ PCI_DEV_INFO *dev;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Brg+1);
+ UINTN i;
+//-------------------------------
+
+ for (i=0; i<ext->ChildCount; i++){
+ dev=ext->ChildList[i];
+
+ if((dev->Type==tPci2PciBrg || dev->Type==tPci2CrdBrg) )
+ ClearBrgResources(dev);
+ } //child loop
+
+ //Once here that means all recourcive calls are done and
+ //all BridgeChilds Bridges - clean....
+ //Clear ThisBridge Res[], Pad[], Align[]...
+ for(i=rtIo16; i<rtMaxRes; i++) {
+ PCI_DEV_INFO *owner;
+ //----------------------
+ owner=ext->Res[i].Owner;
+ pBS->SetMem(&ext->Res[i], sizeof(PCI_BAR),0);
+ ext->Res[i].Owner=owner;
+
+ owner=ext->Align[i].ExtraRes.Owner;
+ pBS->SetMem(&ext->Align[i], sizeof(BRG_ALIGN_INFO),0);
+ ext->Align[i].ExtraRes.Owner=owner;
+#if HOTPLUG_SUPPORT
+ owner=ext->Pad[i].Owner;
+ pBS->SetMem(&ext->Pad[i], sizeof(PCI_BAR),0);
+ ext->Pad[i].Owner=owner;
+#endif
+ if(ext->BarOrder[i].BarCount) ClearItemLst((T_ITEM_LIST*)&ext->BarOrder[i], FALSE);
+ }
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CalculateBrgResources()
+//
+// Description: The objective of this routine is to select the biggest
+// possible Granularity/Alignment for the Bridge by adding all Child's
+// resources of the same type together.
+//
+// Input:
+// PCI_DEV_INFO *Brg Pointer to PCI Device Private Data structure.
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CalculateBrgResources(PCI_DEV_INFO *Brg)
+{
+ EFI_STATUS Status=0;
+ PCI_DEV_INFO *dev;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Brg+1);
+ UINTN i,j,k;
+ PCI_BAR *bar, *bbar;
+ UINT8 bit;
+ BRG_RES_ORDER *resord;
+#if HOTPLUG_SUPPORT
+ PCI_BAR *pbar;
+#endif
+ BRG_ALIGN_INFO *balign;
+ BOOLEAN paddingappl;
+ MRES_TYPE LowResType=rtMaxRes;
+//-----------------------------------------------
+ //Tell what we are doing
+ PCI_TRACE((TRACE_PCI,"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
+ PCI_TRACE((TRACE_PCI,"PciBus: "));
+ if(gPciOutOfRes) PCI_TRACE((TRACE_PCI," RE_"));
+ PCI_TRACE((TRACE_PCI,"CalculateBrgResources() Bridge->[B%X|D%X|F%X] ---> BEGIN \n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device, Brg->Address.Addr.Function));
+ PCI_TRACE((TRACE_PCI,"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n"));
+
+ //Init initial Alignment fields for the special Bridge BARs
+ //every P2P brg has 4k IO and 1M MMMIO alignment
+ //Init Initial Granularity array
+ if(Brg->Type==tPciRootBrg){
+ //in case of Host Bridge Granularity Values should be provided by Root Brg
+ for(i=1; i<rtMaxRes; i++) ext->Align[i].MinGran=1; //just don't care now
+ } else {
+ //in case of P2P Brg use default settings
+ ext->Align[1].MinGran=P2P_BRG_IO_GRA;
+ ext->Align[2].MinGran=P2P_BRG_IO_GRA;
+ ext->Align[3].MinGran=P2P_BRG_MEM_GRA;
+ ext->Align[4].MinGran=P2P_BRG_MEM_GRA;
+ ext->Align[5].MinGran=P2P_BRG_MEM_GRA;
+ ext->Align[6].MinGran=P2P_BRG_MEM_GRA;
+ }
+
+ //Initialize fields in Bridge info Structure
+ ext->Res[rtIo16].Gran=P2P_BRG_IO_GRA;
+ ext->Res[rtIo32].Gran=P2P_BRG_IO_GRA;
+ ext->Res[rtMmio32].Gran=P2P_BRG_MEM_GRA;
+ ext->Res[rtMmio32p].Gran=P2P_BRG_MEM_GRA;
+ ext->Res[rtMmio64].Gran=P2P_BRG_MEM_GRA;
+ ext->Res[rtMmio64p].Gran=P2P_BRG_MEM_GRA;
+
+ //Init Bridge Bar offset fields
+ if(Brg->Type==tPci2PciBrg){
+ //For IO 16 Resources Decoded by the bridge
+ ext->Res[rtIo16].Offset=0x1C;
+ //For IO 32 Resources Decoded by the bridge
+ ext->Res[rtIo32].Offset=0x1C;
+ //For MMIO32
+ ext->Res[rtMmio32].Offset=0x20;
+ //For MMIO32 PF
+ ext->Res[rtMmio32p].Offset=0x24;
+ //For MMIO64
+ ext->Res[rtMmio64].Offset=0x20; //P2PBridge doesnot have any MMIO64
+ //For MMIO64 PF
+ ext->Res[rtMmio64p].Offset=0x24;
+ }
+
+ //Init Card Bus Bridge Bar offset fields
+ if(Brg->Type==tPci2CrdBrg){
+ //For IO 16 Resources Decoded by the bridge
+ ext->Res[rtIo16].Offset=0x2C;
+ //For IO 32 Resources Decoded by the bridge
+ ext->Res[rtIo32].Offset=0x34;
+ //For MMIO32
+ ext->Res[rtMmio32].Offset=0x1C;
+ //For MMIO32 PF
+ ext->Res[rtMmio32p].Offset=0x24;
+ //For MMIO64
+ ext->Res[rtMmio64].Offset=0x1C; //P2Crd Bridge doesnot have any MMIO64
+ //For MMIO64 PF
+ ext->Res[rtMmio64p].Offset=0x24;//P2Crd Bridge doesnot have any MMIO64PF
+ }
+
+ if(gPciOutOfRes){
+//OUT_OF_RES!!
+ //Get AmiOutOfResVar (suppose to be created by ROOT BRG Generic code or Custom HbCspAllocateResources())
+ Status=AmiPciOutOfRes(&gPciOutOfResData, TRUE);
+ ASSERT_EFI_ERROR(Status); //should not fail at that point!
+
+ //gPciOutOfResData.Resource.Type can't be ASLRV_SPC_TYPE_BUS
+ //Update resource type
+ if(gPciOutOfResData.Resource.Type==ASLRV_SPC_TYPE_IO) LowResType=rtIo16;
+
+ if(gPciOutOfResData.Resource.Type==ASLRV_SPC_TYPE_MEM){
+ if(gPciOutOfResData.Resource._GRA==32){
+ LowResType=rtMmio32;
+ if(gPciOutOfResData.Resource.TFlags.MEM_FLAGS._MEM!=ASLRV_MEM_UC)LowResType=rtMmio32p;
+ }
+ if(gPciOutOfResData.Resource._GRA==64){
+ LowResType=rtMmio64;
+ if(gPciOutOfResData.Resource.TFlags.MEM_FLAGS._MEM!=ASLRV_MEM_UC)LowResType=rtMmio64p;
+ }
+ }
+ }
+
+ //Start adding resources for all childs behind that bridge
+ for (i=0; i<ext->ChildCount; i++){
+ dev=ext->ChildList[i];
+
+ //if we got Out Of resources condition call Platforn function to determine
+ //priority list for devices Platform wants to IGNORE.
+ //Pick just ONe device at a time.
+ if(gPciOutOfRes && !gPciOutOfResHit && !dev->OutOfResRemove){
+ Status=PciPortOutOfResourcesRemoveDevice(dev, gPciOutOfResData.Count, LowResType);
+ if(!EFI_ERROR(Status)){
+ gPciOutOfResHit=TRUE;
+ dev->OutOfResRemove=TRUE;
+
+ PCI_TRACE((TRACE_PCI,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"));
+ PCI_TRACE((TRACE_PCI,"\nPciBus: OutOfRes Hit #%d!!! Removing Device [B%X|D%X|F%X]->",
+ gPciOutOfResData.Count, dev->Address.Addr.Bus, dev->Address.Addr.Device, dev->Address.Addr.Function));
+
+ if(dev->PicIrqEntry!=NULL) PCI_TRACE((TRACE_PCI,"Slt #%d\n", dev->PicIrqEntry->SlotNum));
+ else PCI_TRACE((TRACE_PCI,"Slt N/A\n"));
+ PCI_TRACE((TRACE_PCI,"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"));
+
+ //We must remove all it's functions also since f0 defines persence of the rest.
+ if(IsFunc0OfMfDev(dev)&& dev->Type!=tPci2PciBrg) {
+ PCI_TRACE((TRACE_PCI," AND ALL IT's %d FUNCTIONS!!!\n",dev->FuncCount));
+ for(j=0;j<dev->FuncCount;j++){
+ dev->DevFunc[j]->OutOfResRemove=TRUE;
+ DisableDeviceDecoding(dev->DevFunc[j], stDisableAll);
+ }
+ }
+ //if we hit device from remove list - shut it down...
+ DisableDeviceDecoding(dev, stDisableAll);
+ if(dev->Type==tPci2PciBrg) DisableBridgeDecoding((PCI_BRG_INFO*)dev);
+
+ //save OUT_OF_RES_VAR
+ Status=AmiPciOutOfRes(&gPciOutOfResData, FALSE);
+
+ }
+ }
+
+ if(dev->OutOfResRemove) continue;
+ //here we have to check if the Child device is P2P brg -
+ //it requires a special handling
+ if(dev->Type==tPci2PciBrg || dev->Type==tPci2CrdBrg)
+ CalculateBrgResources(dev);
+ } //child loop
+
+ PCI_TRACE((TRACE_PCI,"=>>>Resource Requirements for Bridge->[B%X|D%X|F%X] :<<<=\n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device, Brg->Address.Addr.Function));
+ PCI_TRACE((TRACE_PCI,"ResType: 1=rtIo16; 2=rtIo32; 3=rtMmio32; 4=rtMmio32p; 5=rtMmio64; 6=rtMmio64p\n\n"));
+
+
+ for(j=rtIo16; j<rtMaxRes; j++){
+ //Init variables.
+ paddingappl=FALSE;
+ bbar=&ext->Res[j];
+ balign=&ext->Align[j];
+ resord=&ext->BarOrder[j];
+ balign->MaxGran=bbar->Gran;
+
+ Status=OptimizeBrgResource(Brg, j);
+ ASSERT_EFI_ERROR(Status);
+
+ for(k=0; k<resord->BarCount; k++){
+ bar=resord->BarList[k];
+ //add children's resources to the bridge decoding
+ if(bbar->Gran < bar->Gran)bbar->Gran=bar->Gran;
+ bbar->Length+=bar->Length;
+ bbar->Type=bar->Type;
+ }
+
+#if HOTPLUG_SUPPORT
+ pbar=&ext->Pad[j];
+ //if this is the bridge with hotplug capabilities it might supports Resource Padding
+ //Apply padding and padding alignment if it is bigger than this bridge is currently requesting
+ if(pbar->Length){
+ if(pbar->Length > bbar->Length) bbar->Length = pbar->Length;
+ if(bbar->Gran < pbar->Gran) bbar->Gran=pbar->Gran;
+ bbar->Type=pbar->Type;
+ paddingappl=TRUE;
+ }
+#endif
+ //if we have a card bus brg and hotplug is disabled we will APPLY default padding
+ if(Brg->Type==tPci2CrdBrg && !paddingappl) {
+ PCI_TRACE((TRACE_PCI,"->>>Applying CRD BUS Default Padding for Pci2CrdBrg [B%X|D%X|F%X]\n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device, Brg->Address.Addr.Function));
+ ApplyCrdPadding(Brg, j);
+ }
+
+ //if Brg have resource request
+ balign->MaxGran=bbar->Gran;
+ if(bbar->Length){
+ if( (bbar->Length < (balign->MinGran + 1)) || ((bbar->Length & balign->MinGran)) )
+ bbar->Length=(bbar->Length | balign->MinGran)+1;
+ //Figure out Resource Delivered Granularity
+ bit=FindFirstBit(bbar->Length-1,FALSE);
+ balign->ResGran=Shr64((~0ULL),64-bit);
+ }
+ //Report Bridge Parameters
+ PCI_TRACE((TRACE_PCI,"->ResType=%X; Len=%lX; Gran=%lX; MaxGran=%lX; ResGran=%lX; MinGran=%lX\n\n",
+ j, bbar->Length, bbar->Gran, balign->MaxGran, balign->ResGran, balign->MinGran));
+ PCI_TRACE((TRACE_PCI,"------------------------------------------------------------------------\n"));
+
+ } //for(j=rtIo16; j<rtMaxRes; j++)..
+
+ //Tell what we are doing
+ PCI_TRACE((TRACE_PCI,"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n"));
+ PCI_TRACE((TRACE_PCI,"PciBus: CalculateBrgResources() Bridge->[B%X|D%X|F%X] ---> END \n",
+ Brg->Address.Addr.Bus, Brg->Address.Addr.Device, Brg->Address.Addr.Function));
+ PCI_TRACE((TRACE_PCI,"^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\n\n"));
+
+ //We did it ... EXIT!
+}
+
+//================================================
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NewDevice()
+//
+// Description: Allocats Space nedded for New PCI_Device Instance and inits
+// some of it's Fields
+//
+// Input:
+// BOOLEAN BrgDevice Indicator that New Device is a BRIDGE Device.
+// PCI_CFG_ADDR *DevArrd Device Address on PCI Bus.
+//
+// Output: PCI_DEV_INFO*
+// Pointer to the Created PCI Device Private Data structure.
+// NULL, if there was an ERROR.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+PCI_DEV_INFO* NewDevice(BOOLEAN BrgDevice, PCI_CFG_ADDR *DevAddr)
+{
+ UINTN i;
+ PCI_DEV_INFO *dev;
+ PCI_BRG_EXT *ext;
+//------------------------------------
+ PCI_TRACE((TRACE_PCI,"\n==========================================================================\n"));
+ if(BrgDevice)i=sizeof(PCI_BRG_INFO);
+ else i=sizeof(PCI_DEV_INFO);
+
+ dev=MallocZ(i);
+ if(!dev) return dev;
+
+ //Specify Owner for BusSpecific Override Protocol
+ dev->BusOvrData.Owner=dev;
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ dev->LoadFileData.Owner=dev;
+#endif
+ dev->Signature=AMI_PCI_SIG;
+ dev->MajorVersion = PCI_BUS_MAJOR_VER;
+ dev->MinorVersion = PCI_BUS_MINOR_VER;
+ dev->Revision = PCI_BUS_REVISION;
+
+ //init some fields which must not be ZERO
+ for(i=0; i<PCI_MAX_BAR_NO+1; i++)dev->Bar[i].Owner=dev;
+ if(DevAddr){
+ dev->Address.ADDR=DevAddr->ADDR;
+ dev->Address.Addr.Register=0;
+ } else dev->Address.ADDR=0;
+
+ //Initialize some static fields
+ if(BrgDevice){
+ dev->Type=tPci2PciBrg;
+ ext=(PCI_BRG_EXT*)(dev+1);
+ for(i=0; i<rtMaxRes; i++) {
+ ext->Res[i].Owner=dev;
+ ext->Align[i].ExtraRes.Owner=dev;
+ }
+ } else dev->Type=tPciDevice;
+
+ return dev;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BridgeAddChild()
+//
+// Description: Adds Pointer at the child PCI Device to the "Bridge"
+// T_ITEM_LIST Child List Structure of the BRG_EXT.
+// some of it's Fields
+//
+// Input:
+// PCI_DEV_INFO *Brgidge Pointer to PCI Device Private Data structure
+// of the Parent Bridge.
+// PCI_DEV_INFO *Child Pointer to PCI Device Private Data structure.
+// of the Child Device.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS BridgeAddChild(PCI_DEV_INFO *Bridge,PCI_DEV_INFO *Child)
+{
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(Bridge+1);
+//-------------------------------------------------
+ return AppendItemLst((T_ITEM_LIST*)&ext->InitialCount,Child);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitDeviceData()
+//
+// Description: Initializes missing fields in PCI_DEV_INFO structure.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer to PCI Device Private Data structure
+// to initialize.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitDevData(PCI_DEV_INFO *Dev, PCI_DEV_INFO *Parent, UINT32 VenDevId, UINT32 ClassCodes, PCI_DEV_INFO *Func0){
+ EFI_STATUS Status;
+ PCI_CFG_ADDR addr;
+//-------------------------
+ //Get CMD Register's safe value per UEFI 2.1 spec
+ addr.ADDR=Dev->Address.ADDR;
+
+ Dev->ParentBrg=Parent;
+ Dev->DevVenId.DEV_VEN_ID=VenDevId;
+ Dev->Class.DEV_CLASS=ClassCodes;
+ Dev->HostData=Parent->HostData;
+ Dev->RbIo=Parent->RbIo;
+ Dev->Func0=Func0;
+
+ //If (Func0==NULL && FuncCount==0) function is a single function device, following fields are not used and reserved;
+ //If (Func0!=NULL && FuncCount==0) function is one of the Func1..Func7 of multi-func device, Func0 points on DevFunc0;
+ //If (Func0!=NULL && (FuncCount!=0 || FuncInitCnt!=0)) function is Func0 of multyfunc device DevFunc holds pointers at all other Func1..7 found yet
+
+ //If (Func0==NULL && FuncCount!=0) Illehgal combination - reserved!
+ if(Func0!=NULL){
+ if (Func0!=Dev){
+ //This is func 1..7 of the device... add it to the list.
+ Status=AppendItemLst((T_ITEM_LIST*)&Func0->FuncInitCnt,Dev);
+ ASSERT_EFI_ERROR(Status)
+ if(EFI_ERROR(Status)) return Status;
+ } else {
+ //This is Func 0 if the device.. init Func0->FuncInitCnt with 8
+ Func0->FuncInitCnt=8;
+ }
+ }
+
+ addr.Addr.Register=PCI_CMD;
+ Status=PciCfg16( Dev->RbIo, addr, FALSE, &Dev->CmdReg.CMD_REG);
+ ASSERT_EFI_ERROR(Status)
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=MakePciDevicePath(Dev);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=PciPortSkipThisDevice(Dev);
+ if(!EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"PciBus: Device @ [B%X|D%X|F%X], VID=%X, DID=%X SKIPPED from enumeration.\n\n",
+ Dev->Address.Addr.Bus, Dev->Address.Addr.Device, Dev->Address.Addr.Function,
+ Dev->DevVenId.VenId, Dev->DevVenId.DevId));
+ Dev->SkipDevice=TRUE;
+ }else Status=EFI_SUCCESS;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnumerateBus()
+//
+// Description: Enumerate the PCI BUSes behind the "ParentBrg" and determine
+// how much resources nedded for all its Child devices.
+//
+// Input:
+// PCI_DEV_INFO *ParentBrg Pointer to PCI Device Private Data structure
+// of the Parent Bridge.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnumerateBus(PCI_DEV_INFO *ParentBrg)
+{
+ EFI_STATUS Status, Status1=EFI_NOT_FOUND;
+ PCI_CFG_ADDR pcidev;
+ BOOLEAN mf,ari; //multi-function flag; ARI Flag
+ UINT32 id, cc; //Device ID Vendor ID reg
+ UINT8 ht; //Header type reg
+ PCI_BRG_EXT *ext, *parext;
+ PCI_DEV_INFO *dev, *func0;
+ UINT8 omb=0;
+#if PCI_DEV_REVERSE_SCAN_ORDER
+ UINT8 DevBuff;
+#endif
+//----------------------------------
+ PROGRESS_CODE(DXE_PCI_BUS_ENUM);
+ //Root Bridges Will have Same Number for Primary and Secondary bus
+ pcidev.ADDR=PCI_VID;
+ parext=(PCI_BRG_EXT*)(ParentBrg+1);
+ pcidev.Addr.Bus=(UINT8)parext->Res[rtBus].Base;
+ func0=NULL;
+ ari=FALSE;
+
+ for(pcidev.Addr.Device=0; pcidev.Addr.Device<=PCI_MAX_DEVICE; pcidev.Addr.Device++){
+#if PCI_DEV_REVERSE_SCAN_ORDER
+ DevBuff = pcidev.Addr.Device;
+ pcidev.Addr.Device = PCI_MAX_DEVICE - pcidev.Addr.Device;
+#endif
+ //if ARI Detected and Enabled we should scan all devices and functions
+ //but in ARI Mode Dev0..31 and Func0..7 will be translted for PCIe as Dev0 Func 0...255
+ //So Func0 must be the same as we have detected when started from Actual Function 0
+ //And we should not reset MF flag for ARI device when we reach Func 7 of the device.
+ if(ari == FALSE){
+ mf=FALSE;
+ func0=NULL;
+ }
+
+ for(pcidev.Addr.Function=0; pcidev.Addr.Function<=PCI_MAX_FUNC; pcidev.Addr.Function++){
+ //read devid-vendid register pare,
+ id=0;
+ pcidev.Addr.Register=PCI_VID;
+
+ ///
+ /// A config write is required in order for the device to re-capture the Bus number,
+ /// according to PCI Express Base Specification, 2.2.6.2
+ /// Write to a read-only register VendorID to not cause any side effects.
+ ///
+ Status=PciCfg32(ParentBrg->RbIo,pcidev,TRUE,&id);
+
+ Status=PciCfg32(ParentBrg->RbIo,pcidev,FALSE,&id);
+ if(EFI_ERROR(Status)) return Status; //Error happend - can't continue
+ //Check if all Ones
+#if PCI_EXPRESS_SUPPORT
+ if( (id == 0xFFFFFFFF)&& //oinly if first attemt of CFG read did not find anything
+ (ParentBrg->PciExpress!=NULL) && //and device is PCIe capable
+#if PCI_DEV_REVERSE_SCAN_ORDER
+ (DevBuff==0) && (pcidev.Addr.Function==0) && //for PCIe dev0 func0 is only option
+#else
+ (pcidev.Addr.Device==0) && (pcidev.Addr.Function==0) && //for PCIe dev0 func0 is only option
+#endif
+ (ParentBrg->PciExpress->PcieCap.SlotImpl)) //and we have a slot there...
+ {
+ //Some cards does not reply on configuration transactions
+ //for some time after opening config space behind the bridge.
+ //If slot is implemented behind the bridge -
+ //doiblecheck if card present using PCIe facilities (SLOT_STATUS reg)
+ //we will save time on skipping DEV 1..31 though
+ Status=PcieDoubleCheckCard(ParentBrg,&pcidev,&id);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+ if(id == 0xFFFFFFFF || id==0){
+ if (!mf)break; //devX.fun0.reg=0 returns 0xFFFFFFFF nothing is there
+ else continue; //if device was identified as multifunc keep scanning
+ }
+ //here we got something alive there
+ Status1=EFI_SUCCESS;
+ ht=0;
+ //read the HeaderType Reg
+ pcidev.Addr.Register=EFI_FIELD_OFFSET(PCI_COMMON_REG,HeaderType);
+ Status=PciCfg8(ParentBrg->RbIo,pcidev,FALSE,&ht);
+ if(EFI_ERROR(Status)) return Status; //Error happend cant continue
+
+ if(ari==FALSE){
+ if(pcidev.Addr.Function==0) {
+ if(ht & HDR_TYPE_MULTIFUNC)mf=TRUE; //this is multifunc device
+ }
+ }
+
+ ht&=3;
+
+ //Get the class code and revision Id
+ pcidev.Addr.Register=PCI_RID; //Rev ID and Class Code
+ Status=PciCfg32(ParentBrg->RbIo,pcidev,FALSE,&cc);
+ if(EFI_ERROR(Status)) return Status; //Error happend can't continue
+
+ switch (ht){
+ case HDR_TYPE_DEVICE :
+ //Allocate Space to accomodate found device
+ dev=NewDevice(FALSE,&pcidev);
+ if(!dev) return EFI_OUT_OF_RESOURCES;
+
+ if((ari==FALSE) && (mf) && (pcidev.Addr.Function==0))func0=dev;
+ Status=InitDevData(dev, ParentBrg, id, cc, func0);
+ if(EFI_ERROR(Status)) goto EEXIT;
+ //Test the class code to mark host brg device
+ if( dev->Class.SubClassCode==0 &&
+ dev->Class.BaseClassCode==6 &&
+ dev->Class.ProgInterface==0 )
+ {
+ dev->Type=tPciHostDev;
+ }
+ //Check if we got a debug port here
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+ if(
+ (gDbgPortHob && (
+ (gDbgPortInfo.DebugPortType==USB2_EHCI) ||
+ (gDbgPortInfo.DebugPortType==USB2_UHCI) ||
+ (gDbgPortInfo.DebugPortType==USB2_OHCI) )
+ ) && (
+ (pcidev.Addr.Function==gDbgPortInfo.Address.Addr.Function) &&
+ (pcidev.Addr.Device==gDbgPortInfo.Address.Addr.Device) &&
+ (pcidev.Addr.Bus==gDbgPortInfo.Address.Addr.Bus)
+ )
+ )
+ {
+ dev->Bar[gDbgPortInfo.BarIndex].Length =gDbgPortInfo.Length;
+ dev->Bar[gDbgPortInfo.BarIndex].Gran =gDbgPortInfo.Length-1;
+ dev->Bar[gDbgPortInfo.BarIndex].Offset =gDbgPortInfo.BarOffset;
+ dev->Bar[gDbgPortInfo.BarIndex].Type =gDbgPortInfo.BarType;
+ dev->DebugPort=TRUE;
+ dev->Enumerated=TRUE;
+ dev->Discovered=TRUE;
+ }
+ else
+#endif
+ {
+ if(dev->SkipDevice){
+ //if porting hook tells us to skip this device.
+ //We will just start it
+ dev->Assigned=TRUE;
+ dev->Discovered=TRUE;
+ dev->Enumerated=TRUE;
+ dev->Incompatible=TRUE;
+ } else {
+ //Vars we need here
+ UINTN i;
+ UINT64 tl32, tl64, tlIO;
+ //-------------
+ //make sure - Device is disabled
+ Status=DisableDeviceDecoding(dev, stMemIoSpace);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+ //Try to determine how mutch resources Device consumes
+ Status=QueryPciDevice(dev);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+ //Find IRQ Routing Entry for discovered device
+ Status = FindDevIrqEntry(dev);
+
+ //This workaround done for PCI Compliance Test...
+ //32 bit, 64bit and IO resource request excides certain length.
+ for(i=0,tlIO=0,tl32=0,tl64=0; i<PCI_MAX_BAR_NO+1; i++){
+ if((dev->Bar[i].Type!=tBarUnused) && (dev->Bar[i].Length!=0) ){
+ switch (dev->Bar[i].Type){
+ case tBarIo16:
+ case tBarIo32:
+ tlIO+=dev->Bar[i].Length;
+ break;
+ case tBarMmio32:
+ case tBarMmio32pf:
+ tl32+=dev->Bar[i].Length;
+ break;
+ case tBarMmio64:
+ case tBarMmio64pf:
+ tl64+=dev->Bar[i].Length;
+ }//switch
+ }//if not empty
+ } //for
+
+ //Check if Calculated total resource request falls in acceptable range
+ if( (tlIO>=PCI_DEVICE_IO_RESOURCE_THRESHOLD) ||
+ (tl32>=PCI_DEVICE_32BIT_RESOURCE_THRESHOLD) ||
+ (tl64>=PCI_DEVICE_64BIT_RESOURCE_THRESHOLD)
+ )
+ {
+ //Zero out all BARs and ROM BAR.
+ for(i=PCI_BAR0, id=0; i<PCI_CAPP; i+=4){
+ pcidev.Addr.Register=(UINT8)i;
+ Status=PciCfg32(ParentBrg->RbIo,pcidev,TRUE,&id);
+ if(EFI_ERROR(Status)) goto EEXIT;
+ }
+ //Clear CMD_REG
+ pcidev.Addr.Register=(UINT8)PCI_CMD;
+ Status=PciCfg16(ParentBrg->RbIo,pcidev,TRUE,(UINT16*)(&id));
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+ //Clear All collected resource information for that device
+ //to avoid them to be added to the system's resource request.
+ for(i=0; i<PCI_MAX_BAR_NO+1; i++){
+ dev->Bar[i].Type=tBarUnused;
+ dev->Bar[i].DiscoveredType=tBarUnused;
+ dev->Bar[i].Length=0;
+ dev->Bar[i].Gran=0;
+ }
+ //Setting Flags telling not to install PciIo protocol instance
+ //on this device and don't touch device at all!
+ dev->Started=TRUE;
+ dev->Assigned=TRUE;
+ dev->Discovered=TRUE;
+ dev->Enumerated=TRUE;
+ dev->RomBarError=TRUE;
+ dev->Incompatible=TRUE;
+ } //if .. Device requests too much resources.
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Check if we have to enable ARI here.
+ if(IsFunc0(dev)){
+ Status=Pcie2CheckAri(dev,&mf,&ari);
+ if(EFI_ERROR(Status)) goto EEXIT;
+ }
+#endif
+ dev->Enumerated=TRUE;
+
+ }
+ }
+ break;
+
+ case HDR_TYPE_P2P_BRG :
+ case HDR_TYPE_P2C_BRG :
+ //Allocate space for new bridge struct
+ dev=NewDevice(TRUE,&pcidev);
+ if(!dev) return EFI_OUT_OF_RESOURCES;
+
+ ext=(PCI_BRG_EXT*)(dev+1);
+ if(ht==HDR_TYPE_P2C_BRG)dev->Type=tPci2CrdBrg;
+
+ //Record some properties of the discovered device
+ if(pcidev.Addr.Function==0 && mf)func0=dev;
+ Status=InitDevData(dev, ParentBrg, id, cc, func0);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+ if(dev->SkipDevice){
+ //if porting hook tells us to skip this device.
+ //We will just start it
+ dev->Assigned=TRUE;
+ dev->Discovered=TRUE;
+ dev->Enumerated=TRUE;
+ dev->Incompatible=TRUE;
+ } else {
+ //make sure - Device is disabled
+ if(dev->Type == tPci2PciBrg) DisableBridgeDecoding((PCI_BRG_INFO*)dev);
+ Status=DisableDeviceDecoding(dev, stMemIoSpace);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+ //Try to determine how mutch resources Device consumes
+ Status=QueryPciDevice(dev);
+ //this call must fill Bar[0..1]
+ if(EFI_ERROR(Status)) goto EEXIT;
+ }
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Check if we have to enable Ari in case of
+ if((dev->PciExpress!=0) && (PcieIsDownStreamPort(dev)==FALSE)){
+
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ if(dev->SkipDevice==0){
+#endif
+ Status=Pcie2CheckAri(dev,&mf,&ari);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ }
+#endif
+ }
+#endif
+
+ //Find PCI Bus Xlat entry corresponded to this bridge
+ Status=FindBridgeXlatEntry(dev, ext);
+ //Find IRQ Routing Entry for discovered device
+ Status = FindDevIrqEntry(dev);
+
+ //KeepUpdating NewBrg
+ //Programm Primary and Secondary I/F Bus Numbers
+ //To store Bridge SecondaryBusNo and SubordinateBusNo we will use PCI_BAR structure
+ //Device.Address.Addr.Bus will have PrimaryBusNo
+ //Bar.Base will be used for SecondaryBusNo and
+ //Bar.Base +Bar.Length-1 will give us SubordinateBusNo.
+ //So Record the Secondary Bus we will use for this Bridge..
+
+ //Set Bridge Bus register Proprties
+ ext->Res[rtBus].Type=tBarBus;
+ ext->Res[rtBus].Offset=PCI_BRIDGE_SECONDARY_BUS_REGISTER_OFFSET; //SecondaryBusOffset
+
+ //If fixed bus assignment we should handle situation differenty
+ if( FixedBusAssign && ext->XlatTblEntry != NULL ){
+ //get sceondary bus number from BusXlat Table
+ mMaxBusFound = ext->XlatTblEntry->BusBuild;
+ } else {
+ //Bridge has been found just increase bus counter
+ mMaxBusFound++;
+ }
+
+ ext->Res[rtBus].Base = mMaxBusFound;
+ //Set Sub Bus # for this bridge to max # available
+ ext->Res[rtBus].Length=mMaxBusScan-ext->Res[rtBus].Base;
+ if(ext->XlatTblEntry){
+ ext->XlatTblEntry->BusRun=mMaxBusFound;
+ }
+
+ if(mMaxBusReport < mMaxBusFound) mMaxBusReport=mMaxBusFound;
+
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ if(dev->SkipDevice==0){
+#endif
+ Status=MapBridgeBuses(dev);
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ }
+#endif
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+ omb=mMaxBusFound; //save the old number of buses found only in case of hotplug
+ //this will try to init Root HPC siting behind this bridge if any...
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ if(dev->SkipDevice==0){
+#endif
+ Status=CheckRootHotplug(dev);
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ }
+#endif
+ ASSERT_EFI_ERROR(Status);
+ //if root hpc init fail for any reason we just must keep going
+#endif
+
+ //Enter a Recursive call in both cases
+ //Only in case Device is identifyes itself as Bridge
+ if(dev->Class.BaseClassCode == PCI_CL_BRIDGE){
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ if(dev->SkipDevice==0){
+#endif
+ Status = EnumerateBus(dev);
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ }
+#endif
+
+ if(Status!=EFI_NOT_FOUND){
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto EEXIT;
+ } else Status=EFI_SUCCESS;
+ //After we come back from enumeration update all IRQ Tables entries
+ //From BusBuild to BusRun (actual bus number)
+ if(ext->XlatTblEntry){
+ UpdateIrqTables(ext->XlatTblEntry);
+ PCI_TRACE((TRACE_PCI,"PciBus: Update Bus# for Brg [B%X|D%X|F%X] - Bld %X -> Run %X\n",
+ dev->Address.Addr.Bus,dev->Address.Addr.Device,dev->Address.Addr.Function,
+ ext->XlatTblEntry->BusBuild,ext->XlatTblEntry->BusRun));
+ }
+ }
+
+//-------------------------------------------------------------------------
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+ //here if this is the bridge who has hotplugable slots
+ //we must appy resource padding to it
+ if(dev->HotPlug){
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ if(dev->SkipDevice==0){
+#endif
+ Status=GetHpbResPadding(dev);
+
+ //Here we come with information about resources padding
+ //dev->Hotplug->Padd[rtBus].Length will have Bus numbers needed to pad for this bridge
+ //mMaxBusFound will have number of buses actualy present behind this bridge
+ //take care of buses now the rest of resources will be taken care of when
+ //CalculateBridge resources will be called
+ if(ext->PaddAttr==EfiPaddingPciBus){
+ //EIP 19106 If 1 Bus set to padding in Setup it did not do the padding.
+ if(ext->Pad[rtBus].Length && ext->Pad[rtBus].Length>mMaxBusFound-ext->Res[rtBus].Base){
+ mMaxBusFound=omb+(UINT8)ext->Pad[rtBus].Length;
+ }
+ }
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ }
+#endif
+
+ }
+#endif
+//-------------------------------------------------------------------------
+ //when we come back from EnumerateBus and have applyed padding for Bus Resources
+ // - mMaxBusFound will effectively reflect subordinate bus number for this Bridge so...
+
+ //If fixed bus assignment we should handle situation differenty
+ if( FixedBusAssign &&
+ (ext->XlatTblEntry != NULL) &&
+ (ext->ItemNumber < gPciBusDb.ItemCount-1))
+ {
+ UINT8 busnum;
+ //-------------------------
+ busnum=FindNextSameLevelBrgXlatEntry(ext);
+
+ if( mMaxBusFound <= busnum )mMaxBusFound = busnum;
+ else {
+ //With Fixed Bus allocation this condition signifies an error if we here
+ //that means that we have found more buses than allowed buy fixed bus layout
+ //So scream about it.
+ PCI_TRACE((TRACE_PCI,"PciBus: Can't apply Fixed Buses for the Bridge @ [B%X|D%X|F%X]:\n Actual MAX Bus Discovered =%X; Proposed MAX Bus in BusXlatTbl = %X\n",
+ dev->Address.Addr.Bus, dev->Address.Addr.Device, dev->Address.Addr.Function,
+ mMaxBusFound, busnum));
+ ASSERT(FALSE);
+ }
+
+ }
+ ext->Res[rtBus].Length=mMaxBusFound-ext->Res[rtBus].Base+1;
+
+ if(mMaxBusReport < mMaxBusFound) mMaxBusReport=mMaxBusFound;
+
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ if(dev->SkipDevice==0){
+#endif
+ Status=SetSubBus(dev,mMaxBusFound);
+#if PCI_BUS_SKIP_BRG_RECURSIVELY
+ }
+#endif
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto EEXIT;
+
+//-------------------------------------------------------------------------
+//Enables PCI Express Handling only if PCI Express Base is Defined and !=0
+#if PCI_EXPRESS_SUPPORT
+ //Now when we come back we can power off PCIExpress Empty slot to make it
+ //cpable for Hot Plugging
+ if(dev->PciExpress!=NULL){
+ //Check if we hit a DOWN STREAM type device,
+ //and Initialize PciE link properties if so.
+ if(PcieIsDownStreamPort(dev)){
+ Status=PcieInitLink(dev);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto EEXIT;
+ } else {
+ //Add to the gPcieEpLst Orphan Upstream Ports of Switches and PCIe2PCI bridgers.
+ if((dev->PciExpress->PcieCap.PortType==PCIE_TYPE_UPS_PORT) ||
+ (dev->PciExpress->PcieCap.PortType==PCIE_TYPE_PCIE_PCI)){
+
+ Status=AppendItemLst(&gPcieEpList, dev);
+ PCI_TRACE((TRACE_PCI,"PciE: Adding Device [B%X|D%X|F%X] to gPcieEpList[%d]\n",
+ dev->Address.Addr.Bus,dev->Address.Addr.Device, dev->Address.Addr.Function, gPcieEpList.ItemCount));
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) goto EEXIT;
+ }
+ }
+ }
+#endif
+//-------------------------------------------------------------------------
+ //Finally we got here this bridge is done for now!!! we will use
+ //information collected, when we will programm the resources
+ dev->Enumerated=TRUE;
+ break;
+
+ default :
+ Status=EFI_UNSUPPORTED;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ } //switch;
+ //Now update ParentBridge ChildList and Count
+ Status=BridgeAddChild(ParentBrg,dev);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) goto EEXIT;
+ //and so on
+ if( !mf ) break;
+ } //function loop
+#if PCI_DEV_REVERSE_SCAN_ORDER
+ pcidev.Addr.Device=DevBuff;
+#endif
+ } //device loop
+ return Status1;
+///////////////////////////////////////////
+//Emergency Exit Label
+EEXIT:
+ if(dev){
+ if(dev->PciExpress){
+ if(dev->PciExpress->Pcie2) pBS->FreePool(dev->PciExpress->Pcie2);
+ if(dev->PciExpress->VcData) {
+ if(dev->PciExpress->VcData->VcCount)ClearItemLst((T_ITEM_LIST*)&dev->PciExpress->VcData->InitCnt, TRUE);
+ pBS->FreePool(dev->PciExpress->VcData);
+ }
+ if(dev->PciExpress->SriovData) pBS->FreePool(dev->PciExpress->SriovData);
+ if(dev->PciExpress->AriData) pBS->FreePool(dev->PciExpress->AriData);
+ if(dev->PciExpress->AcsData) pBS->FreePool(dev->PciExpress->AcsData);
+ if(dev->PciExpress->AtsData) pBS->FreePool(dev->PciExpress->AtsData);
+ if(dev->PciExpress->RcLnkData) pBS->FreePool(dev->PciExpress->RcLnkData);
+ if(dev->PciExpress->Pcie3) pBS->FreePool(dev->PciExpress->Pcie3);
+
+ pBS->FreePool(dev->PciExpress);
+ }
+
+ if(dev->PciX) pBS->FreePool(dev->PciX);
+ if(dev->HotPlug)pBS->FreePool(dev->HotPlug);
+ pBS->FreePool(dev);
+ }
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProgramBar()
+//
+// Description: Programm PCI BAR Register with the Resource Address
+// provided by the "bar" parameter.
+//
+// Input:
+// PCI_BAR *bar Pointer at PCI BAR register information
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProgramBar(PCI_BAR *bar)
+{
+ EFI_STATUS Status=0;
+ PCI_CFG_ADDR addr;
+ PCI_DEV_INFO *owner=bar->Owner;
+//------------------------------------
+ addr.ADDR=bar->Owner->Address.ADDR;
+ addr.Addr.Register=bar->Offset;
+ addr.Addr.ExtendedRegister=bar->ExtOffset;
+
+#if EFI_DEBUG || USB_DEBUG_TRANSPORT
+ if(owner->DebugPort){
+ gDbgPortInfo.BaseAddress=bar->Base;
+ Status=gDbgPortHob->SetDebugPortResources(gDbgPortHob, pBS, &gDbgPortInfo);
+ ASSERT_EFI_ERROR(Status);
+ owner->Assigned=TRUE;
+ return Status;
+ }
+#endif
+
+ PCI_TRACE((TRACE_PCI,"PciBus: Device [B%X|D%X|F%X] Type=%X Bar.Offs=%Xh, Bar.Type=%d \n Assigned Base=%lX, Size=%lX \n",
+ owner->Address.Addr.Bus, owner->Address.Addr.Device,
+ owner->Address.Addr.Function, owner->Type,
+ ((bar->ExtOffset==0) ? bar->Offset : bar->ExtOffset),
+ bar->Type, bar->Base, bar->Length));
+ //EIP 26787 +
+ //Forgot to exclude P2P Bridge ROM BAR, it belongs to primary interface!
+ //if(owner->Type==tPci2PciBrg && (bar->Offset > 0x14 ){
+ if(owner->Type==tPci2PciBrg && ( (bar->Offset > PCI_BAR1) && (bar->Offset < PCI_EROM) ) ){
+ //EIP 26787 -
+
+ //we got special P2P bridge BAR
+ switch (bar->Type){
+ case tBarIo16 :
+ case tBarIo32 :
+ Status=EnableBridgeIoDecoding(owner, (UINT64)bar->Base, (UINT64)bar->Length);
+ //if(EFI_ERROR(Status)) return Status;
+ break;
+
+ case tBarMmio32:
+ case tBarMmio64:
+ Status=EnableBridgeMmioDecoding(owner, (UINT64)bar->Base, (UINT64)bar->Length);
+ //if(EFI_ERROR(Status)) return Status;
+ break;
+
+ case tBarMmio32pf:
+ case tBarMmio64pf:
+ Status=EnableBridgePfmmDecoding(owner, (UINT64)bar->Base, (UINT64)bar->Length);
+ //if(EFI_ERROR(Status)) return Status;
+ break;
+ }//switch
+
+ } else {
+ if(owner->Type==tPci2CrdBrg && bar->Offset > PCI_BAR0 ){
+ //here goes special Memory and IO windows of CardBus Bridge
+ UINT32 buffer=(UINT32)bar->Base;
+ //--------------------
+ Status=PciCfg32(owner->RbIo,addr,TRUE,(UINT32*)&buffer); //Base
+
+ addr.Addr.Register+=4; //Limit
+ buffer=(UINT32)(bar->Base+bar->Length-1);
+ Status=PciCfg32(owner->RbIo,addr,TRUE,(UINT32*)&buffer);
+
+ //Program Brg Control Reg to notify that Bridge Mem Window is PF
+ if(bar->Type==tBarMmio32pf || bar->Type==tBarMmio64pf){
+
+ addr.Addr.Register=PCI_BRIDGE_CONTROL_REGISTER_OFFSET;
+ Status=PciCfg16(owner->RbIo,addr,FALSE,(UINT16*)&buffer);
+
+ if(bar->Offset==0x1C) buffer|=BIT08; //Memory Window 1 is PF
+ if(bar->Offset==0x24) buffer|=BIT09; //Memory Window 2 is PF
+
+ Status=PciCfg16(owner->RbIo,addr,TRUE,(UINT16*)&buffer);
+ }
+ } else {
+ //do regular device BAR programming
+ UINT64 buffer=bar->Base;
+ //--------------------
+ if(bar->DiscoveredType == tBarMmio64 || bar->DiscoveredType == tBarMmio64pf)
+ Status=PciCfg64(owner->RbIo,addr,TRUE,&buffer);
+ else Status=PciCfg32(owner->RbIo,addr,TRUE,(UINT32*)&buffer);
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AssignBridgeResources()
+//
+// Description: Sorts, Aligns, and Programms Resources requested by devices
+// residing behind its Parent PCI Bridge - "Brg".
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Device Private Data structure
+// of the Parent Bridge.
+// MRES_TYPE rt Type of PCI Bus resources to work with.
+// See definition of MRES_TYPE for detail.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AssignBridgeResources(PCI_BRG_INFO *Brg, MRES_TYPE rt)
+{
+ EFI_STATUS Status=EFI_NOT_FOUND;
+ UINT64 min=Brg->Bridge.Res[rt].Base;
+ UINT64 max=(min+Brg->Bridge.Res[rt].Length);
+ PCI_BAR *bar=NULL;
+ BRG_RES_ORDER *ord=&Brg->Bridge.BarOrder[rt];
+ UINTN i;//,j;
+//---------------------------------------
+
+ if(ord->BarCount == 0) return EFI_SUCCESS;
+
+ //Assign Io resources to all of Bridge childs
+ for(i=0; i<ord->BarCount; i++){
+ if(min>=max) {
+ Status=EFI_UNSUPPORTED;
+ PCI_TRACE((TRACE_PCI,"PciBus: ERROR Assign Res: MIN_ADDR(0x%lX) >= MAX_ADDR(0x%lX)\n", min, max));
+ break;
+ }
+ bar=ord->BarList[i];
+//(EIP45278)>
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+ if(rt==rtIo16)
+#endif
+ bar->Base=min;
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+ else
+ bar->Base=max-bar->Length;
+#endif
+//<(EIP45278)
+ if(bar->Offset!=0xFF){
+ Status=ProgramBar(bar);
+ if(EFI_ERROR(Status)) break;
+ }
+//(EIP45278)>
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+ if(rt==rtIo16)
+#endif
+ min+=(bar->Length);
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+ else
+ max-=(bar->Length);
+#endif
+//<(EIP45278)
+ }
+
+ if(EFI_ERROR(Status)&& bar!=NULL){
+ PCI_TRACE((TRACE_PCI,"PciBus: ERROR Assign Res for BAR(T=%X O=%X) @ [ B%X|D%X|F%X ]",
+ bar->Type, bar->Offset, bar->Owner->Address.Addr.Bus,
+ bar->Owner->Address.Addr.Device,bar->Owner->Address.Addr.Function));
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ClearBar()
+//
+// Description: Clears/zeros contents of PCI_BAR structure.
+//
+// Input:
+// PCI_BAR *Bar Pointer to PCI_BAR structure to clear.
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ClearBar(PCI_BAR *Bar)
+{
+ Bar->Type=tBarUnused;
+ Bar->Gran=0;
+ Bar->Length=0;
+ Bar->Base=0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindBarByType()
+//
+// Description: Checks if PCI BAR register of a particular "BarType" present
+// behind the PCI Bridge.
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Device Private Data structure
+// of the Parent Bridge.
+// PCI_BAR_TYPE BarType Bar Type to search for.
+//
+// Output: BOOLEAN
+// TRUE if BAR of "BarType" present Behind the "Brg".
+// FALSE if otherwice.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FindBarByType(PCI_BRG_INFO* Brg, PCI_BAR_TYPE BarType)
+{
+ UINTN i,j;
+ BOOLEAN res;
+ PCI_DEV_INFO *dev;
+//---------------------
+ for(i=0; i<Brg->Bridge.ChildCount; i++){
+ dev=Brg->Bridge.ChildList[i];
+ if(dev->Type<tPciHostDev && dev->Type>=tPciRootBrg){
+ //go inside the bridge...
+ res=FindBarByType((PCI_BRG_INFO*)dev,BarType);
+ if(res) return res;
+ }
+
+ for(j=0; j<PCI_MAX_BAR_NO+1; j++) if(dev->Bar[j].Type==BarType) return TRUE;
+#if SRIOV_SUPPORT
+//SRIOV Support adds some more bars ito the picture
+ if( (dev->PciExpress != NULL) && (dev->PciExpress->SriovData != NULL)){
+ for(j=0; j<PCI_MAX_BAR_NO; j++) if(dev->PciExpress->SriovData->Bar[j].Type==BarType) return TRUE;
+ }
+#endif
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertResources()
+//
+// Description: Converts Resources Requested by the Devices behind the
+// PCI Bridge of "ResType" using "ConvType" method of conversion
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Device Private Data structure
+// of the Parent Bridge.
+// PCI_BAR_TYPE ResType Resource Type to convert. Accepted values are
+// tBarIo, tBarMem, tBarMemPf,
+// all other values are invalid.
+// RES_CONV_TYPE ConvType Type of Conversion to be performed.
+//
+// Output: Nothing
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ConvertResources(PCI_BRG_INFO *Brg, PCI_BAR_TYPE ResType, RES_CONV_TYPE ConvType, BOOLEAN CombineMemPmem)
+{
+ PCI_BRG_EXT *ext=&Brg->Bridge;
+ PCI_DEV_INFO *dev;
+ UINTN i,j;
+ BOOLEAN cnv=FALSE;
+ PCI_BAR_TYPE nt, wt;
+ RES_CONV_TYPE p2pct;
+//----------------------------
+
+ //Pick Brg Bars to convert
+ switch (ResType) {
+ case tBarIo:
+ nt=tBarIo16;
+ wt=tBarIo32;
+ p2pct=rcOneOf;
+ if(Brg->Common.Type==tPci2CrdBrg)p2pct=rcBoth;
+ break;
+
+ case tBarMem:
+ nt=tBarMmio32;
+ wt=tBarMmio64;
+ p2pct=rcNarrow;
+ if(Brg->Common.Type==tPci2CrdBrg)p2pct=rcNarrow;
+ break;
+
+ case tBarMemPf:
+ nt=tBarMmio32pf;
+ wt=tBarMmio64pf;
+ p2pct=rcOneOf;
+ if(Brg->Common.Type==tPci2CrdBrg)p2pct=rcNarrow;
+ break;
+
+ default : return; //no other combinations supported
+ }//switch
+
+ switch (ConvType){
+ case rcNone:
+ cnv=TRUE;
+ break;
+ case rcOneOf:
+ cnv=FindBarByType(Brg,nt);
+ break;
+ case rcNarrow:
+ cnv=FindBarByType(Brg,wt);
+ break;
+ case rcBoth: cnv=FALSE;
+ }//switch
+
+ //Take care about Padding behind the bridge if CombineMemPmem Attribute is set
+ if(ext->Pad[rtMmio32p].Length && CombineMemPmem){
+ ext->Pad[rtMmio32].Length+=ext->Pad[rtMmio32p].Length;
+ ext->Pad[rtMmio32p].Length=0;
+ }
+ if(ext->Pad[rtMmio64p].Length && CombineMemPmem){
+ ext->Pad[rtMmio64].Length+=ext->Pad[rtMmio64p].Length;
+ ext->Pad[rtMmio64p].Length=0;
+ }
+
+ for(i=0; i<ext->ChildCount; i++) {
+ dev=ext->ChildList[i];
+ for(j=0; j<PCI_MAX_BAR_NO; j++){
+ if(cnv){
+ switch(ConvType){
+ case rcNone:
+ if(dev->Bar[j].Type==wt) ClearBar(&dev->Bar[j]);
+ break;
+ case rcOneOf:
+ case rcNarrow:
+ if(dev->Bar[j].Type==wt) dev->Bar[j].Type=nt;
+ break;
+ }
+ } //if cnv
+ if(CombineMemPmem){
+ if( dev->Bar[j].Type==tBarMmio32pf ) dev->Bar[j].Type=tBarMmio32;
+ if( dev->Bar[j].Type==tBarMmio64pf ) dev->Bar[j].Type=tBarMmio64;
+ }
+ }//for j
+
+#if SRIOV_SUPPORT
+//SRIOV Support adds some more bars ito the picture
+ if( (dev->PciExpress != NULL) && (dev->PciExpress->SriovData != NULL)){
+ for(j=0; j<PCI_MAX_BAR_NO; j++){
+ if(cnv){
+ switch(ConvType){
+ case rcNone:
+ if(dev->PciExpress->SriovData->Bar[j].Type==wt){
+ ClearBar(&dev->PciExpress->SriovData->Bar[j]);
+ }
+ break;
+ case rcOneOf:
+ case rcNarrow:
+ if(dev->PciExpress->SriovData->Bar[j].Type==wt){
+ dev->PciExpress->SriovData->Bar[j].Type=nt;
+ }
+ break;
+ }//switch
+ } //if cnv
+ if(CombineMemPmem){
+ if( dev->PciExpress->SriovData->Bar[j].Type==tBarMmio32pf )
+ dev->PciExpress->SriovData->Bar[j].Type=tBarMmio32;
+ if( dev->PciExpress->SriovData->Bar[j].Type==tBarMmio64pf )
+ dev->PciExpress->SriovData->Bar[j].Type=tBarMmio64;
+ }
+ }//for j
+ }
+#endif
+
+ //recoursively call to convert child resources behind other brg
+ if(dev->Type==tPci2PciBrg || dev->Type==tPci2CrdBrg){
+ if(cnv){
+ //Unconditionally convert all resources to narrow because parent requested resource conversion
+ if(ConvType)ConvertResources((PCI_BRG_INFO*)dev, ResType, rcNarrow, CombineMemPmem);
+ else ConvertResources((PCI_BRG_INFO*)dev, ResType, ConvType, CombineMemPmem);
+ } else ConvertResources((PCI_BRG_INFO*)dev, ResType, p2pct, CombineMemPmem);
+ }
+ } //Child loop
+ //we did it!!!
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AssignBusResources()
+//
+// Description: Sorts, Aligns, and Programms Resources requested by devices
+// on the PCI Bus created by the PCI Bridge - "Brg".
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer to PCI Device Private Data structure
+// of the Bridge who creates the bus.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Notes:
+// Assigns Resources by filling Device Bar structure
+// and programm all Bridge Childs Bars
+// and Enables Bridge devices to decode their resources
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AssignBusResources(PCI_BRG_INFO *Brg)
+{
+ EFI_STATUS Status=0;
+ UINT8 i;
+ PCI_DEV_INFO *dev;
+//----------------------------------
+ //First Check if Resources Assigned don't do it multiple times
+ if(Brg->Common.Assigned) return EFI_SUCCESS;
+
+ if(Brg->Common.Type == tPci2PciBrg || Brg->Common.Type == tPci2CrdBrg){
+ Status=DisableDeviceDecoding(&Brg->Common,stDisableAll);
+ Brg->Common.Attrib=0;
+ }
+
+ //Start with IO
+ if (Brg->Bridge.Res[rtIo32].Length) Status=AssignBridgeResources(Brg,rtIo32);
+ if(EFI_ERROR(Status)) return Status;
+
+ if (Brg->Bridge.Res[rtIo16].Length) Status=AssignBridgeResources(Brg,rtIo16);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ //Now MMIO 64 PF
+ if(Brg->Bridge.Res[rtMmio64p].Length)Status=AssignBridgeResources(Brg,rtMmio64p);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Now MMIO 64
+ if(Brg->Bridge.Res[rtMmio64].Length)Status=AssignBridgeResources(Brg, rtMmio64);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Now MMIO 32 PF
+ if(Brg->Bridge.Res[rtMmio32p].Length)Status=AssignBridgeResources(Brg,rtMmio32p);
+ if(EFI_ERROR(Status)) return Status;
+
+ //And MMIO 32
+ if(Brg->Bridge.Res[rtMmio32].Length)Status=AssignBridgeResources(Brg, rtMmio32);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ //So far so good - resources has been assigned on this Bridge level
+ //now check if we have any p2p brg among this brg childs...
+ //if so we will call this function recoursively...
+ for(i=0; i<Brg->Bridge.ChildCount; i++ ){
+ PCI_CFG_ADDR a;
+ PCI_CMD_REG cmdreg;
+ //-----------------
+ Status=EFI_SUCCESS;
+
+ dev=Brg->Bridge.ChildList[i];
+ a.ADDR=dev->Address.ADDR;
+
+ //Now take care of CacheLine Size register
+ if(dev->Capab&MY_PCI_IO_ATTRIBUTE_MEM_WR_INVALIDATE){
+ a.Addr.Register=PCI_CLS; // Cache Line Size
+
+ Status=PciCfg8(dev->RbIo,a,TRUE,&gPciCaheLineSize);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+
+ if(dev->Type==tPci2PciBrg ||dev->Type==tPci2CrdBrg) Status=AssignBusResources((PCI_BRG_INFO*)dev);
+
+ //disable decoding fo the PCI devices unles PciPortSkipThisDevice()
+ //says to Skip it. The Device Specific driver should enable it using Attributes() function.
+ if(!dev->SkipDevice){
+ Status=DisableDeviceDecoding(dev,stDisableAll);
+ dev->Attrib=0;
+ }
+
+ if (EFI_ERROR(Status)) return Status;
+ dev->Assigned=TRUE;
+ //UEFI 2.1 - we must leave BRIDGES open (decoding it's ranges)
+ if(dev->Type==tPci2PciBrg ||dev->Type==tPci2CrdBrg){
+ PCI_BRG_CNT_REG bc;
+ //---------------------------
+ Status=DeviceAttributes(dev, dev->Capab & (EFI_PCI_DEVICE_ENABLE), TRUE);
+ ASSERT_EFI_ERROR(Status);
+
+ a.Addr.Register=PCI_BRIDGE_CNTL; //Bridge Control Reg
+
+ Status=PciCfg16(dev->RbIo,a,FALSE,&bc.BRG_CNT_REG);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Set VGA16 enable to avoid forwarding ISA VGA Aliases
+ bc.Vga16Enable=1;
+
+ //Programm device's BRG_CTL_REG to forward #SERR and #PERR to the primary Interface.
+ if(gPciSetupData->SerrEnable) bc.SerrEnable=1;
+ else bc.SerrEnable=0;
+
+ if(gPciSetupData->PerrEnable) bc.PerrEnable=1;
+ else bc.PerrEnable=0;
+
+
+ Status=PciCfg16(dev->RbIo,a,TRUE,&bc.BRG_CNT_REG);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ //Programm device's PCI_CMD_REG to generate #SERR and #PERR according to Setup.
+ a.Addr.Register=PCI_CMD; //PCI Command Reg
+
+ Status=PciCfg16(dev->RbIo,a,FALSE,&cmdreg.CMD_REG);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ if(gPciSetupData->SerrEnable) cmdreg.SerrEnable=1;
+ else cmdreg.SerrEnable=0;
+
+ if(gPciSetupData->PerrEnable) cmdreg.ParityErrorResp=1;
+ else cmdreg.ParityErrorResp=0;
+
+ Status=PciCfg16(dev->RbIo,a,TRUE,&cmdreg.CMD_REG);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ } //for
+ Brg->Common.Assigned=TRUE;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateRootResDsc()
+//
+// Description: Creates an ACPI QWORD Resource Descriptors set to reflect
+// this "RootBrg" resource request
+//
+// Input:
+// PCI_BRG_INFO *RootBrg Pointer to PCI Device Private Data structure
+// of the Bridge who creates the bus.
+// IN OUT VOID* *ResDsc ACPI QWORD Resource Descriptors set.
+// See definition of ASLR_QWORD_ASD for details.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//
+// Notes:
+// Meaning of QWORD Resource Descriptor Fields for this function
+// _LEN => Set to the size of the aperture that is requested.
+// _GRA => Used to differentiate between a 32-bit memory request and a
+// 64-bit memory request. For a 32-bit memory request,
+// this field should be set to 32. For a 64-bit memory request,
+// this field should be set to 64. All other values result in
+// this function returning the error code of EFI_INVALID_PARAMETER.
+// _MAX => Used to specify the alignment requirement.
+// All other fields are ignored.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateRootResDsc(PCI_DEV_INFO *RootBrg, VOID **ResDsc){
+ UINTN i, rc=0;
+ ASLR_QWORD_ASD *rd;
+ PCI_BRG_EXT *ext=(PCI_BRG_EXT*)(RootBrg+1);
+//-----------------------------------------------------
+ //First count how many rd suppose to be
+ for(i=rtIo16; i<rtMaxRes; i++){
+ if(ext->Res[i].Type && ext->Res[i].Length) rc++;
+ }
+
+ //If RB don't have any resource requests fill out END_TAG_DESCRIPTOR and return.
+ if(!rc){
+ rd=MallocZ(sizeof(ASLR_EndTag));
+ rd->Hdr.HDR=ASLV_END_TAG_HDR;
+ *ResDsc=rd;
+ return EFI_SUCCESS;
+ }
+
+ //get some memory
+ rd=MallocZ(sizeof(ASLR_QWORD_ASD)*rc+sizeof(ASLR_EndTag));
+ ASSERT(rd);
+ if(!rd) return EFI_OUT_OF_RESOURCES;
+
+ *ResDsc=rd;
+ for(i=rtIo16; i<rtMaxRes; i++){
+ if(!(ext->Res[i].Type && ext->Res[i].Length)) continue ;
+ switch(ext->Res[i].Type){
+ case tBarIo16:
+ rd->Type=ASLRV_SPC_TYPE_IO;
+ rd->_GRA=16;
+ break;
+ case tBarIo32:
+ rd->Type=ASLRV_SPC_TYPE_IO;
+ rd->_GRA=32;
+ break;
+ case tBarMmio32pf:
+ rd->TFlags.MEM_FLAGS._MEM=ASLRV_MEM_CEPF;
+ //no break intentionally!! DON'T CHANGE
+ case tBarMmio32:
+ rd->Type=ASLRV_SPC_TYPE_MEM;
+ rd->_GRA=32;
+ rd->TFlags.MEM_FLAGS._RW=1;
+ break;
+ case tBarMmio64pf:
+ rd->TFlags.MEM_FLAGS._MEM=ASLRV_MEM_CEPF;
+ //no break intentionally!! DON'T CHANGE
+ case tBarMmio64:
+ rd->Type=ASLRV_SPC_TYPE_MEM;
+ rd->_GRA=64;
+ rd->TFlags.MEM_FLAGS._RW=1;
+ break;
+ default : continue;
+ }
+ rd->Hdr.HDR=0x8A;
+ rd->GFlags.GFLAGS=0x0C; //Means _MIN and _MAX is fixed
+ rd->Hdr.Length=0x2B;
+ rd->_MAX=ext->Res[i].Gran;
+ rd->_LEN=ext->Res[i].Length + ext->Align[i].ExtraRes.Length;
+
+ if(rd->Type==ASLRV_SPC_TYPE_MEM){
+ //Check to Memory Resource Size Align on 4K
+ if(rd->_LEN & (EFI_PAGE_SIZE-1))rd->_LEN=(rd->_LEN | (EFI_PAGE_SIZE-1))+1;
+ }
+
+ PCI_TRACE((TRACE_PCI,"CreateRD QWD: T=%X; GF=%X; TF=%X; _MN=%lX; _MX=%lX; _LN=%lX;_GR=%lX;\n",
+ rd->Type, rd->GFlags.GFLAGS, rd->TFlags.TFLAGS, rd->_MIN, rd->_MAX, rd->_LEN, rd->_GRA));
+
+ rd++;
+ }
+ rd->Hdr.HDR=ASLV_END_TAG_HDR;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertResources()
+//
+// Description: Converts Resource information from QWORD ACPI ResDesc
+// to internal format and store it within PCI_DEV_INFO structure.
+//
+// Input:
+// PCI_BRG_EXT *RbExt Pointer to PCI Device Private Data structure
+// of the Root Bridge. (PCI_BRG_EXT part)
+// ASLR_QWORD_ASD *Resources Pointer to the set
+
+// RES_CONV_TYPE ConvType Type of Conversion to be prformed.
+//
+// Output: Nothing
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ApplyAcpiResources(PCI_BRG_EXT *RbExt, ASLR_QWORD_ASD *Resources){
+ ASLR_QWORD_ASD *res=Resources;
+ PCI_BAR *bar;
+ UINTN i, s, e;
+//------------------------------------
+ while(res->Hdr.HDR!=ASLV_END_TAG_HDR) {
+ bar=NULL;
+ PCI_TRACE((TRACE_PCI,"ApplyRD QWD: T=%X; GF=%X; TF=%X; _MN=%lX; _MX=%lX; _LN=%lX;_GR=%lX;\n",
+ res->Type, res->GFlags.GFLAGS, res->TFlags.TFLAGS, res->_MIN, res->_MAX, res->_LEN, res->_GRA));
+
+ if(res->Type==ASLRV_SPC_TYPE_IO){
+ s=rtIo16;
+ e=rtMmio32;
+ } else {
+ if(res->Type==ASLRV_SPC_TYPE_MEM){
+ s=rtMmio32;
+ e=rtMaxRes;
+ } else {
+ res++;
+ continue;
+ }
+ }
+
+ for(i=s; i<e; i++){
+ UINT64 len;
+ //--------------------
+ bar=&RbExt->Res[i];
+ len=bar->Length+RbExt->Align[i].ExtraRes.Length;
+
+ if( (res->Type==ASLRV_SPC_TYPE_MEM) && (len&(EFI_PAGE_SIZE-1)) )
+ len=(len|(EFI_PAGE_SIZE-1))+1;
+
+ //It might be an empty descriptor (i.e. System has MMIO32, but does not have MMIO32PF)
+ //This might cause to break early. w/o searching through 64bit resources
+ //take care of this condition by adding check (bar->Length != 0)
+ if((bar->Base == 0) && (bar->Length != 0) && (len <= res->_LEN)) break;
+ else bar=NULL;
+ }
+
+ if(bar)bar->Base=res->_MIN;
+ res++;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitPciDb()
+//
+// Description: Creates all anckor structures and Initialize PCI Database.
+//
+// Input:
+// EFI_HANDLE Controller Controller Handle passed to the PCI Bus Driver
+// Start Function.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitPciDb(EFI_HANDLE Controller){
+ EFI_STATUS Status;
+ EFI_HANDLE *hBuff, htmp=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *rbdp;
+ UINTN i, cnt=0;
+ PCI_DEV_INFO *rb;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *rbio;
+
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+ UINTN ghpccnt=0, j;
+ EFI_HPC_LOCATION *ghpclst=NULL;
+#endif
+
+//------------------------
+ Status=PopulateBusDb();
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ Status=pBS->HandleProtocol(Controller,&gPciRootBridgeIoProtocolGuid,&rbio);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_INVALID_PARAMETER;
+ if(gPciHost && gPciHost[0].Updated) return EFI_SUCCESS;
+
+
+ //Try to figure out how many instances of PCI HostBridge Resource Allocation Protocol
+ //exists, this will give us an idea how many PCI_ROOT_INFO instances to create...
+ Status=pBS->LocateHandleBuffer(
+ ByProtocol, // SearchType,
+ &gEfiPciHostBrgResAllocProtocolGuid, //*Protocol OPTIONAL,
+ NULL, //*SearchKey OPTIONAL,
+ &gHostCnt, //*NoHandles,
+ &hBuff); //**Buffer
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Now we know how many Host Bridges the System has
+ gPciHost=MallocZ(sizeof(PCI_HOST_INFO)*gHostCnt);
+
+ //record Host Bridge Properties
+ for(i=0; i<gHostCnt; i++){
+ gPciHost[i].HostHandle=hBuff[i];
+ //Get Resource Alloc Protocol and Record It
+ Status=pBS->HandleProtocol(hBuff[i],&gEfiPciHostBrgResAllocProtocolGuid,&gPciHost[i].ResAllocProt);
+ //it has to be there or plaform is not Framework compliant
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ //now will locate some optional protocols which must be used if present during PCI enumeration
+ //as per spec - only one instance of this protocols should be present
+ if(i==0){
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+ pBS->LocateProtocol(&gEfiPciHotPlugInitProtocolGuid, NULL, &gPciHost[i].HpInitProt);
+#endif
+ pBS->LocateProtocol(&gEfiPciPlatformProtocolGuid, NULL, &gPciHost[i].PlatformProt);
+ pBS->LocateProtocol(&gEfiIncompatiblePciDeviceProtocolGuid, NULL, &gPciHost[i].IncompDevProt);
+ } else {
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+ gPciHost[i].HpInitProt=gPciHost[0].HpInitProt;
+#endif
+ gPciHost[i].PlatformProt=gPciHost[0].PlatformProt;
+ gPciHost[i].IncompDevProt=gPciHost[0].IncompDevProt;
+ }
+ gPciHost[i].Updated=TRUE;
+ }
+
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+
+ //If HpInitProtocol Exists get RootHpcList
+ if(gPciHost[0].HpInitProt ){
+ Status=gPciHost[0].HpInitProt->GetRootHpcList(gPciHost[0].HpInitProt,&ghpccnt,&ghpclst);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ //Now get all RbIo Protocol Handlers and find the right place for it Protocol Instance.
+ Status=pBS->HandleProtocol(Controller,&gPciRootBridgeIoProtocolGuid,&rbio);
+ //RBIoProtocol has to be installed on Controller Handle
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Select Right Host Brg for this RootBrg Io Protocol Handler
+ for(i=0; i<gHostCnt; i++){
+ //if(gPciHost[i].HostHandle==rbio->ParentHandle) gCurHost=i;
+
+ htmp=NULL;
+ //Now we will fill Pci Root infrastructure in the right order
+ while(!Status){
+ //get Root Bridge Handle of this Host
+ Status=gPciHost[i].ResAllocProt->GetNextRootBridge(gPciHost[i].ResAllocProt, &htmp);
+ if(EFI_ERROR(Status)) break;
+
+
+ //Create New PCI_BRG_INFO structure;
+ rb=NewDevice(TRUE,NULL);
+ if(!rb) return EFI_OUT_OF_RESOURCES;
+
+ //Get the Resource Allocation Attributes
+ //Status=gPciHost[i].ResAllocProt->GetAllocAttributes(gPciHost[i].ResAllocProt, htmp, &rb->Attrib);
+ //if(EFI_ERROR(Status)) break;
+
+
+ //Add it to the Root Bridge Item List
+ Status=AppendItemLst((T_ITEM_LIST*)&gPciHost[i].RbInitCnt, rb);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //now I'll get DevicePath and RootBridgeIo protocols Associated with this Handle
+ //Status=pBS->HandleProtocol(htmp,&gPciRootBridgeIoProtocolGuid,&rb->RbIo);
+ //This Protocol will remain opened untill PciBusStop is Called.
+ Status=pBS->OpenProtocol(htmp,
+ &gPciRootBridgeIoProtocolGuid,(VOID **)&rb->RbIo,
+ gPciBusDriverBinding.DriverBindingHandle,htmp,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ ASSERT_EFI_ERROR(Status); //it MUST have this
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=pBS->HandleProtocol(htmp,&gDevicePathProtocolGuid,&rbdp);
+ ASSERT_EFI_ERROR(Status); //it MUST have this
+ if(EFI_ERROR(Status)) return Status;
+
+ //Fill out some missing and incorrectly filled fields
+ rb->DevicePath=DPCopy(rbdp);
+ rb->Type=tPciRootBrg;
+ rb->HostData=&gPciHost[i];
+ rb->Handle=htmp;
+ rb->ParentBrg=NULL;
+
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+
+ //sort out Root Hot Plug Controlers list items to where they belongs
+ PCI_TRACE((TRACE_PCI,"PciBus: Get Location - HpcLocCount=%d; RbDp=[HID(%X)UID(%X)]\n",
+ ghpccnt,((ACPI_HID_DEVICE_PATH*)rbdp)->HID,((ACPI_HID_DEVICE_PATH*)rbdp)->UID));
+ PCI_TRACE((TRACE_PCI,"-------------------------------------------------\n"));
+
+ for (j=0; j<ghpccnt; j++){
+
+ if( !MemCmp(rbdp, ghpclst[j].HpcDevicePath, sizeof(ACPI_HID_DEVICE_PATH)) ){
+ PCI_HPC_INFO *rhpc;
+ //-----------------------------
+ rhpc=MallocZ(sizeof(PCI_HPC_INFO));
+ ASSERT(rhpc);
+ if(!rhpc) return EFI_OUT_OF_RESOURCES;
+ //Init PCI_ROOT_HPC structure
+ rhpc->Root=TRUE;
+ rhpc->HpcLocation=&ghpclst[j];
+
+ PCI_TRACE((TRACE_PCI,"HpcDP=[HID(%X)UID(%X)]; HpbDP[HID(%X)UID(%X)]\n",
+ ((ACPI_HID_DEVICE_PATH*)rhpc->HpcLocation->HpcDevicePath)->HID,((ACPI_HID_DEVICE_PATH*)rhpc->HpcLocation->HpcDevicePath)->UID,
+ ((ACPI_HID_DEVICE_PATH*)rhpc->HpcLocation->HpbDevicePath)->HID,((ACPI_HID_DEVICE_PATH*)rhpc->HpcLocation->HpbDevicePath)->UID));
+
+ Status=AppendItemLst((T_ITEM_LIST*)&rb->HostData->RhpcInitCnt,rhpc);
+ ASSERT_EFI_ERROR(Status); //it MUST have this
+ if(EFI_ERROR(Status)) return Status;
+ }
+ }
+ PCI_TRACE((TRACE_PCI,"-------------------------------------------------\n"));
+#endif
+
+ }
+ if(Status!=EFI_NOT_FOUND) return Status;
+ }
+
+ //Don't forget to free handle Buffer;
+ pBS->FreePool(hBuff);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnumerateAll()
+//
+// Description: This is Main function to start PCI Bus Enumeration Process.
+//
+// Input:
+// EFI_HANDLE Controller Controller Handle passed to the PCI Bus Driver
+// Start Function.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EnumerateAll(EFI_HANDLE Controller){
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN i, j;
+ UINT8 StartBus, EndBus;
+ RES_CONV_TYPE ct;
+ PCI_HOST_INFO *lhst;
+ PCI_DEV_INFO *rb;
+ PCI_BRG_EXT *ext;
+ ASLR_QWORD_ASD *rres;
+//-------------------------------
+ //Init Pci Local Data if it wasn't initialized yet
+ if(gPciHost==NULL){
+ Status=InitPciDb(Controller);
+ ASSERT_EFI_ERROR(Status);
+ }
+ //Check if we have enumerated VERY FIRST ROOT we done.
+ //That means all roots were enumerated alredy, don't spend eny more time here...
+ if(gPciHost[0].Enumerated) return EFI_SUCCESS;
+
+ //We will do enumeration for all PCI infrastructure, as soon as we got very first
+ //Root Bridge Handle. and then will start only devices belonging to the RootBridge
+ //who's handle we have received as a Controller Handle.
+ mMaxBusFound=0;
+ mMaxBusReport=0;
+
+ for(j=0; j<gHostCnt; j++){
+ lhst=&gPciHost[j]; //init local host pointer
+
+ //will circle trough Root bridges system has starting from _UID=0
+ for(i=0; i<lhst->RbCount; i++){
+ rb=lhst->RootBridges[i];
+ ext=(PCI_BRG_EXT*)(rb+1);
+
+#if BoardPciRes_SUPPORT
+ gPciOutOfRes=FALSE;
+#endif
+ //check if we have this Root Bridge Enumerated already
+ if(rb->Enumerated) continue;
+// ClearItemLst(&res, TRUE);
+
+ //6. Notify the host bridge driver that PCI enumeration is about to begin by calling
+ //NotifyPhase (EfiPciHostBridgeBeginEnumeration). This member function
+ //must be the first one that gets called. PCI enumeration has two steps: bus enumeration and
+ //resource enumeration.
+ Status=DoPciNotify(lhst, EfiPciHostBridgeBeginEnumeration);
+ ASSERT_EFI_ERROR(Status);
+
+ //7. Notify the host bridge driver that bus enumeration is about to begin by calling
+ //NotifyPhase (EfiPciHostBridgeBeginBusAllocation).
+ Status=DoPciNotify(lhst, EfiPciHostBridgeBeginBusAllocation);
+ ASSERT_EFI_ERROR(Status);
+
+ //8. Do the following for every PCI root bridge handle:
+ // a. Call StartBusEnumeration (This,RootBridgeHandle).
+ Status=lhst->ResAllocProt->StartBusEnumeration(lhst->ResAllocProt, rb->Handle, &rres);
+ ASSERT_EFI_ERROR(Status);
+
+ //Check if it is NULL descriptor..
+ if(rres->_MIN==0 && rres->_MAX==0 && rres->_LEN==0) {
+ Status=DoPciNotify(lhst, EfiPciHostBridgeEndBusAllocation);
+ Status=DoPciNotify(lhst, EfiPciHostBridgeBeginResourceAllocation);
+ continue;
+ }
+
+ //Check if we've received correct descriptors
+ if(!ValidateDescriptorBlock(rres,tResBus,FALSE)) {
+ ASSERT(0);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //we have reseived BUS configuration information in "rres"
+ //_MIN Bus# has to be Updated with respect of previous pass
+ StartBus=(UINT8)rres->_MIN;
+ mMaxBusFound=StartBus;
+
+ rb->Address.Addr.Bus=StartBus;
+ mMaxBusScan=(UINTN)(StartBus+rres->_LEN-1);
+ //Maximum bus number must not exceed 0xFF buses!
+ if(mMaxBusScan > 0xFF) ASSERT_EFI_ERROR(EFI_DEVICE_ERROR);
+ //Match Busxlat Entry to the current Host Bridge
+ Status=FindBridgeXlatEntry(rb, ext);
+ //It's a seriouse error if it returns NOT_FOUND need to ASSERT here.
+ ASSERT_EFI_ERROR(Status);
+
+ ext->Res[rtBus].Type=tBarBus;
+ ext->Res[rtBus].Base=StartBus;
+ ext->Res[rtBus].Length=rres->_LEN;
+ //Get Attributes to see what this RB could support
+ Status=rb->RbIo->GetAttributes(rb->RbIo,&rb->Capab,&rb->Attrib);
+ ASSERT_EFI_ERROR(Status);
+
+//Exclude Hotplug support
+#if HOTPLUG_SUPPORT
+ //this will try to init Root HPC siting behind this bridge if any...
+ Status=CheckRootHotplug(rb);
+ ASSERT_EFI_ERROR(Status);
+ //if root hpc init fail for any reason we just must keep going
+#endif
+ // b. Make sure each PCI root bridge handle supports the
+ // EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL.
+ // c. Allocate memory to hold resource requirements. These resources can be two resource trees:
+ // one to hold bus requirements and another to hold the I/O and memory requirements.
+ //
+ // e. Scan all the devices in the specified bus range and on the specified segment. If it is a PCIto-
+ // PCI bridge, update the bus numbers and program the bus number registers in the PCI-to-
+ // PCI bridge hardware. If it is an ordinary device, collect the resource request and add up all
+ // of these requests in multiple pools (e.g., I/O, 32-bit prefetchable memory). Combine
+ // different types of memory requests at an appropriate level based on the PCI root bridge
+ // attributes. Update the resource requirement information accordingly. On every PCI root
+ // bridge, reserve space to cover the largest expansion ROMs on that bus, which will allow
+ // the PCI bus driver to retrieve expansion ROMs from the PCI card or device without having
+ // to reprogram the PCI host bridge. Because the memory and I/O resource collection step
+ // does not call any member function of EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL,
+ // it can be performed at a later time.
+ // f. Once the number of PCI buses under this PCI root bridge is known, call
+ // SetBusNumbers() with this information.
+
+ //Go and do the job!
+ mMaxBusReport=StartBus;
+ PCI_TRACE((TRACE_PCI,"PciBus: Root#%d; ScanFullBusRange=%d; Scanning ",i, ScanFullBusRange));
+ if(ScanFullBusRange) {
+ EndBus=(UINT8)(mMaxBusScan);
+ PCI_TRACE((TRACE_PCI,"Bus Range 0x%X...0x%X \n", StartBus, EndBus));
+ } else {
+ EndBus=StartBus;
+ PCI_TRACE((TRACE_PCI,"Buses Starting from 0x%X \n", StartBus));
+ }
+
+ if(ext->XlatTblEntry) ext->XlatTblEntry->BusRun=StartBus;
+
+ do{
+ Status=EnumerateBus((PCI_DEV_INFO*)rb);
+ if(EFI_ERROR(Status)){
+ if(Status != EFI_NOT_FOUND) return Status;
+ } else {
+ if(mMaxBusReport < rb->Address.Addr.Bus) mMaxBusReport = rb->Address.Addr.Bus;
+ rb->Address.Addr.Bus = mMaxBusReport;
+ ext->Res[rtBus].Base = mMaxBusReport;
+ }
+
+ //Bus is UINT8 to avoid deadloop here check
+ //for condition to berak the loop.
+ if(rb->Address.Addr.Bus==0xFF) break;
+ rb->Address.Addr.Bus++;
+ ext->Res[rtBus].Base++;
+ } while (rb->Address.Addr.Bus <= EndBus);
+
+#if PCI_EXPRESS_SUPPORT
+ //We have collected all Upstream Ports information
+ //Now init it from EndPoint up to RootPort
+ while(gPcieEpList.ItemCount!=0){
+ PCI_DEV_INFO *epdev;
+ //---------------------
+ epdev=(PCI_DEV_INFO*)gPcieEpList.Items[0];
+
+ Status=PcieInitDevChain(epdev);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+#endif
+ //Restore old values
+ rb->Address.Addr.Bus = StartBus;
+ ext->Res[rtBus].Base = StartBus;
+ if(ext->XlatTblEntry){
+ UpdateIrqTables(ext->XlatTblEntry);
+ PCI_TRACE((TRACE_PCI,"PciBus: Update Bus# for RootBrg [B%X|D%X|F%X] - Bld %X -> Run %X\n",
+ rb->Address.Addr.Bus,rb->Address.Addr.Device,rb->Address.Addr.Function,
+ ext->XlatTblEntry->BusBuild,ext->XlatTblEntry->BusRun));
+ }
+
+ //we got lucky!!! finally we are here with information about all resources we need
+ //in the Root Bridge device the following fields will reflect ACPI Resource descriptor fields
+ // rb->Address.Bus = Primary Bus Number _MIN
+ // ext->Res[rtBus].Base = Subordinate Bus Number = _MAX
+ // ext->Res[rtBus].Len = _MAX+1
+ ext->Res[rtBus].Base=mMaxBusReport; //that how much this root brg has buses
+ ext->Res[rtBus].Length=mMaxBusReport-StartBus+1;
+
+ //Update discovered Bus Numbers and report Bus Resources to the HOST
+ rres->_LEN=ext->Res[rtBus].Length;
+ rres->_MAX=rres->_MIN+rres->_LEN-1;
+ Status=lhst->ResAllocProt->SetBusNumbers(lhst->ResAllocProt, rb->Handle, rres);
+ ASSERT_EFI_ERROR(Status);
+ //if everything OK free memory given by StartBusEnumeration function
+ pBS->FreePool(rres);
+
+
+
+ //Here we have to convert some resourcers which we have discovered but RB doesn't supports
+ //Get Allocation Attributes for this Root Bridge it will let us know how to convert resources for this Root bridge
+//???????????????????????????????????????????????????????????????????????????????????????????????????
+//Currently resource allocation attributes reflects only capability of RB to decode 64 bit address
+//but still will not give any clue weathere it is single window or RB has a separate BAR to decode it.
+//If the bar is single and it decodes eather 32 or 64 bit resources the "rcOneOf" must be selected
+//???????????????????????????????????????????????????????????????????????????????????????????????????
+ Status=lhst->ResAllocProt->GetAllocAttributes(lhst->ResAllocProt,rb->Handle,&gAllocationAttributes);
+ ASSERT_EFI_ERROR(Status);
+
+ //Notify HB and CSP
+ Status=DoPciNotify(lhst, EfiPciHostBridgeEndBusAllocation);
+ ASSERT_EFI_ERROR(Status);
+
+ PROGRESS_CODE(DXE_PCI_BUS_REQUEST_RESOURCES);
+
+ //First do IO - Any PCI Root Bridge supports only Io16
+ ConvertResources((PCI_BRG_INFO*)rb,tBarIo,rcNarrow,(BOOLEAN)(gAllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM));
+
+ //than do MMIO
+ if(gAllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE)ct=rcBoth;
+ else ct=rcNarrow;
+ ConvertResources((PCI_BRG_INFO*)rb,tBarMem,ct,(BOOLEAN)(gAllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM));
+
+ //than do pfMMIO
+ if(gAllocationAttributes & EFI_PCI_HOST_BRIDGE_MEM64_DECODE)ct=rcBoth;
+ else ct=rcNarrow;
+ ConvertResources((PCI_BRG_INFO*)rb,tBarMemPf,ct,(BOOLEAN)(gAllocationAttributes & EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM));
+
+//???????????????????????????????????????????????????????????????????????????????????????????????????
+// Attempt to boot with reduced number of PCI Cards if resources will be not enough
+//??has to be called consequently
+//??or create RecalculateBrgResources()...
+//////////////////////////////////////////////////////////////////
+//???????????????????????????????????????????????????????????????????????????????????????????????????
+#if BoardPciRes_SUPPORT
+
+ do{
+//OUT_OF_RES!!
+ //Reset Flag to stop calling Platform function to select PCI device selected
+ // to be removed from enumeration for this pass. It will be SET in CalculateBrgResources().
+ gPciOutOfResHit=FALSE;
+ ext=(PCI_BRG_EXT*)(rb+1);
+ if(gPciOutOfRes) ClearBrgResources(rb);
+#endif
+ //Calculate resources Consumed by this Root bridge
+ CalculateBrgResources(rb);
+ rb->Discovered=TRUE;
+
+ //Notify HB and CSP
+ Status=DoPciNotify(lhst, EfiPciHostBridgeBeginResourceAllocation);
+ ASSERT_EFI_ERROR(Status);
+
+ //Status=AllocateRootResources(gPciRoot.RootBrg[i], &mRootRes);
+ //Create Resource information to report to the HOST BRG
+ Status=CreateRootResDsc(rb,&rres);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"PciBus: CreateRootResDsc() returned %r \n ",Status));
+ return Status;
+ }
+
+ //Not Found Condition is Normal for RB it does not have enything behind it.
+ //Skip Calling SubmitResources() since nothing to Submit
+ Status=lhst->ResAllocProt->SubmitResources(lhst->ResAllocProt, rb->Handle, rres);
+ if(EFI_ERROR(Status)) {
+ VOID *Configuration; //This is a dummy parameter.
+#if BoardPciRes_SUPPORT
+#if PCI_OUT_OF_RESOURCE_SETUP_SUPPORT
+ //Declare Boot flow variable GUID...
+ EFI_GUID BootFlowVariableGuid = BOOT_FLOW_VARIABLE_GUID;
+ UINT32 BootFlow = BOOT_FLOW_CONDITION_PCI_OUT_OF_RESOURCE;
+ //------------------------------
+ Status=pRS->SetVariable(L"BootFlow",&BootFlowVariableGuid,EFI_VARIABLE_BOOTSERVICE_ACCESS,sizeof(BootFlow),&BootFlow);
+#endif
+
+ //Give Platform Policy Driver to handle OUT_OF_RESOURCES situation
+ //by itself (it just might want to BEEP and HUNG the system)
+ gPciOutOfRes=TRUE;
+
+#endif
+ lhst->ResAllocProt->GetProposedResources(
+ lhst->ResAllocProt,
+ rb->Handle,
+ &Configuration);
+#if BoardPciRes_SUPPORT
+#else
+ ERROR_CODE(DXE_PCI_BUS_OUT_OF_RESOURCES,EFI_ERROR_MAJOR);
+ ASSERT_EFI_ERROR(Status);
+#endif
+ pBS->FreePool(rres);
+#if BoardPciRes_SUPPORT
+ } else gPciOutOfRes=FALSE;
+ } while(gPciOutOfRes); //while resources found
+#else
+ return Status;
+ }
+#endif
+ } //loop (i) on submiting resources
+#if BoardPciRes_SUPPORT
+ //Check if we suppose to beep and report "OUT OF_RESOURCES" condition
+ Status=AmiPciOutOfRes(NULL, TRUE);
+ if(!EFI_ERROR(Status)) ERROR_CODE(DXE_PCI_BUS_OUT_OF_RESOURCES,EFI_ERROR_MAJOR);
+#endif
+ //Notify HB and CSP
+ Status=DoPciNotify(lhst, EfiPciHostBridgeAllocateResources);
+ PROGRESS_CODE(DXE_PCI_BUS_ASSIGN_RESOURCES);
+
+
+ ASSERT_EFI_ERROR(Status);
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+// if Allocate Resources Notify Phase returns an ERROR
+// Here suppose to be the following logic :
+// a. Make do with the smaller ranges.
+// b. Call GetProposedResources() to retrieve the proposed settings and examine the
+// differences. Prioritize various requests and drop lower-priority requests. Call
+// NotifyPhase (EfiPciHostBridgeFreeResources) to undo the previous
+// allocation. Go back to step 11 with reduced requirements, which includes resubmitting
+// requests for all the root bridges.
+
+
+// It easy to say, but hard to implement!!!!!
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO
+
+ Status=DoPciNotify(lhst, EfiPciHostBridgeSetResources);
+ ASSERT_EFI_ERROR(Status);
+
+ //now enter the loop where we will get resource windows selected by the Root Bridge
+ //and programm it in to PCI subsystem BARs
+ for(i=0; i<lhst->RbCount; i++){
+ rb=lhst->RootBridges[i];
+ ext=(PCI_BRG_EXT*)(rb+1);
+
+ //Get Copy of updated resources to see if our call worked
+ Status=rb->RbIo->Configuration(rb->RbIo,(VOID**)&rres);
+ if (Status==EFI_NOT_AVAILABLE_YET) continue;
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ ApplyAcpiResources(ext, rres);
+
+ //now we have to assign PCI bus resources, and PciRoot will be the special case.
+ //We should not touch the device which adressed as gPciRoot.RootBrg[i].Address
+ //because it is controlled by PciRootBridge Driver and we must not directly access it
+ //So AssignBusResources routine has a checking of such condition
+ Status=AssignBusResources((PCI_BRG_INFO*)rb);
+ if(EFI_ERROR(Status)) return Status;
+
+#if PCI_EXPRESS_SUPPORT
+ //Record PciEcpress Boot Script since not all OSs knows about it
+ PcieRecordBootScript(rb);
+#endif
+
+ //Set Started Flag for RootBridge device in order not to install PCI IO on it later
+ rb->Started=TRUE;
+ }//loop (i) for root bridge
+ Status=DoPciNotify(lhst, EfiPciHostBridgeEndResourceAllocation);
+ ASSERT_EFI_ERROR(Status);
+
+ lhst->Enumerated=TRUE;
+ } //loop (j)
+#if S3_VIDEO_REPOST_SUPPORT == 1
+// if( (gPciSetupData->S3ResumeVideoRepost==1) && S3VideoRepost ){
+ // Register the event handling function to Record Primary VGA BootScript.
+ Status = CreateReadyToBootEvent (
+ TPL_CALLBACK,
+ RecordPriVgaBootScript,
+ NULL,
+ &gVgaS3Event);
+// }
+#endif
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPciDevicePath()
+//
+// Description: Checks if "DevicePath" is a PCI_DEVICE_PATH.
+//
+// Input:
+// EFI_DEVICE_PATH_PROTOCOL *DevicePath Device Path Pointer.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When "DevicePath" is not a PCI_DEVICE_PATH.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckPciDevicePath(EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ // Check if the RemainingDevicePath is valid
+ if (DevicePath->Type != HARDWARE_DEVICE_PATH ||
+ DevicePath->SubType != HW_PCI_DP &&
+ NODE_LENGTH(DevicePath) != sizeof (PCI_DEVICE_PATH))
+ return EFI_UNSUPPORTED;
+ else return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DoubleCheckOpRom()
+//
+// Description: This function called when PciRomHdr->InitializationSize and
+// Pcir->ImageSize has different values and Pcir->Indicator bit 7 is not set.
+// It evaluets whch one is correct by Searching for 0x55AA signature that is
+// must present in the beginning of next OptROM image.
+//
+// Input:
+// LEGACY_OPT_ROM_HEADER *PciRomHdr Pointer to Legacy Option ROM Header(0x55AA).
+// PCI_DATA_STRUCTURE *Pcir Pointer to PCI ROM header ("PCIR")
+//
+// Output: EFI_STATUS
+// UINTN Size of the ROM in bytes;
+// Note: PCIR and OptROM signatures assumed to be valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN DoubleCheckOpRom(VOID *PciRomHdr, PCI_DATA_STRUCTURE *Pcir){
+ UINT8 *p;
+ UINTN sz=0;
+ UINTN hsz=0;
+//---------------------------------
+ //EFI Compatible ROM headers have 16 bit Length field...
+ if( ((PCI_EFI_OPT_ROM_HEADER*)PciRomHdr)->EfiSignature == PCI_OPT_ROM_EFISIG) hsz=((PCI_EFI_OPT_ROM_HEADER*)PciRomHdr)->InitializationSize; //16 bit size
+ else hsz=((LEGACY_OPT_ROM_HEADER*)PciRomHdr)->Size512;
+
+ if(hsz == Pcir->ImageLength ) return (hsz*512);
+
+ p=(UINT8*)PciRomHdr;
+
+ if(hsz < Pcir->ImageLength ) {
+ sz= Pcir->ImageLength*512;
+ if( ((LEGACY_OPT_ROM_HEADER*)(p+sz))->Signature==PCI_OPT_ROM_SIG) return sz;
+ if(Pcir->Indicator&0x80) return sz; //(EIP37774+)
+ }
+
+ sz=hsz*512;
+ if( ((LEGACY_OPT_ROM_HEADER*)(p+sz))->Signature==PCI_OPT_ROM_SIG) return sz;
+ else {
+ if(Pcir->Indicator&0x80) return sz;//(EIP37774+)
+ if ( ((LEGACY_OPT_ROM_HEADER*)PciRomHdr)->Signature==PCI_OPT_ROM_SIG ) return sz;
+ return 512;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetOptRom()
+//
+// Description: Validate and copy PCI Option ROM Image From ADD ON CARD to
+// the System Memory.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer PCI Devicse Private Data.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_DEVICE_ERROR When driver fails access PCI Bus.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetOptRom(PCI_DEV_INFO *Dev)
+{
+ EFI_STATUS Status=EFI_NOT_FOUND, ExitStatus=0;
+ PCI_BAR *rombar=&Dev->Bar[PCI_MAX_BAR_NO];
+ //UINT8 RomBuff[20];
+ UINTN OptRomSize = 0;
+ UINT32 trs=0;
+ PCI_DATA_STRUCTURE Pcir;
+ PCI_STD_OPT_ROM_HEADER PciRomHdr;
+ PCI_EFI_OPT_ROM_HEADER *EfiRomHdr=(PCI_EFI_OPT_ROM_HEADER*)&PciRomHdr;
+#if CSM_SUPPORT
+ VOID *EmbRom;
+#endif
+ BOOLEAN ff=TRUE;
+ UINT64 base=rombar->Base;
+ UINTN sz=0;
+//-------------------------------------
+ //we got Opt ROM to check...
+ if(Dev->Bar[PCI_MAX_BAR_NO].Type!=tBarUnused){
+ //Enable RomBar Decoding
+ //We will use PciIo->SetAttributes here to enable device Memory Space.
+ //If device sits behind some P2P brg Attributes will enable it all the way down
+ //Per UEFI 2.1 spec bridges must be open and decoding it's resources.
+ //Status=DeviceAttributes(Dev, EFI_PCI_IO_ATTRIBUTE_MEMORY, TRUE);
+ //if(EFI_ERROR(Status))return Status;
+
+ Status=EnableDeviceDecoding(Dev,stOptRomSpace);
+ if(EFI_ERROR(Status))return Status;
+
+ for(;;){
+ if(base+trs+512 >= rombar->Base+rombar->Length) break;
+
+ // Get the first 20 bytes of the ROM header
+ Status=Dev->RbIo->Mem.Read(Dev->RbIo, EfiPciWidthUint8, base+trs,
+ sizeof(PCI_STD_OPT_ROM_HEADER), &PciRomHdr);
+ if(EFI_ERROR(Status))goto ExitLbl;
+
+ // Check the validity of the ROM
+ if ((PciRomHdr.Signature != PCI_OPT_ROM_SIG) || (PciRomHdr.PcirOffset == 0) ){
+ if(ff) {
+ Status=EFI_NOT_FOUND;
+ goto ExitLbl;
+ } else {
+ //base+=512;
+ trs+=512;
+ continue;
+ }
+ }
+ ff=FALSE;
+
+ Status=Dev->RbIo->Mem.Read(Dev->RbIo, EfiPciWidthUint8, base+trs+PciRomHdr.PcirOffset,
+ sizeof(PCI_DATA_STRUCTURE), &Pcir);
+ if(EFI_ERROR(Status))goto ExitLbl;
+
+ if(Pcir.Signature!=PCI_PCIR_SIG){
+ //Status=EFI_NOT_FOUND;
+ //goto ExitLbl;
+ continue;
+ }
+
+ OptRomSize=trs;
+
+ sz=DoubleCheckOpRom((VOID*)(base+trs), &Pcir);
+ OptRomSize+=sz;
+
+/*
+ //Figure out the size of image. Some of the cards has PCI_STD_OPT_ROM_HEADER.Size value
+ //bigger then in PCIR PCI_DATA_STRUCTURE.ImageLength field.
+ if(Pcir.CodeType == 0){
+ if(PciRomHdr.Reserved[0] < Pcir.ImageLength) OptRomSize+=(Pcir.ImageLength*512);
+ else OptRomSize+=(PciRomHdr.Reserved[0]*512);
+ }
+ //Open Firmware Standard for PCI
+ if(Pcir.CodeType == 1){
+ OptRomSize+=(Pcir.ImageLength*512);
+ }
+
+ //In case of EFI Option ROM Header
+ if(Pcir.CodeType == 3) {
+ if(EfiRomHdr->InitializationSize < Pcir.ImageLength) OptRomSize+=(Pcir.ImageLength*512);
+ else OptRomSize+=(EfiRomHdr->InitializationSize*512);
+ }
+*/
+ trs=(UINT32)OptRomSize;
+
+ if(Pcir.Indicator & 0x80) break;
+ }//for(;;)
+
+ //Allocate Memory For Opt Rom Image Buffer
+ Dev->PciIo.RomImage=Malloc(OptRomSize);
+ if(Dev->PciIo.RomImage==NULL){
+ Status=EFI_OUT_OF_RESOURCES;
+ goto ExitLbl;
+ }
+
+ //Copy Rom image into memory
+// Status=Dev->RbIo->Mem.Read(Dev->RbIo, EfiPciWidthUint8,rombar->Base,
+// OptRomSize,Dev->PciIo.RomImage);
+// if(EFI_ERROR(Status)) goto ExitLbl;
+
+ MemCpy32(Dev->PciIo.RomImage, (VOID*)(rombar->Base), OptRomSize);
+
+ //We didnot parse OPT ROM buffer yet so RomSize will have temp value
+ Dev->PciIo.RomSize=OptRomSize;
+
+ExitLbl:
+ //Disable decoding option rom again
+ //Per UEFI 2.1 spec bridges must be open and decoding it's resources.
+ //ExitStatus=DeviceAttributes(Dev, EFI_PCI_IO_ATTRIBUTE_MEMORY, FALSE);
+ ExitStatus=DisableDeviceDecoding(Dev,stOptRomSpace);
+ } //if(Dev->Bar[PCI_MAX_BAR_NO].Type!=tBarUnused)
+ //We tryed to Find PCI Off Board Card Option ROM because it's ROM BAR was valid.
+ //But Some On Board Devices Implements ROM BAR but It does not have a valid ROM
+ //So I will check for embeded Option ROM if Status==EFI_NOT_FOUND and ExitStatus==EFI_SUCCES
+#if CSM_SUPPORT
+ if((Status==EFI_NOT_FOUND)&&(ExitStatus==EFI_SUCCESS)){
+ //Here we'll try to locate Embeded rom For Onboard devices.
+ //we'll use CSM Ext Protocol to do so.
+ if(gLegacyBiosExt==NULL) Status=EFI_NOT_FOUND;
+ else {
+ //Got Protocol. Will try to use it.
+ Status=gLegacyBiosExt->GetEmbeddedRom(0x20,Dev->DevVenId.VenId,
+ Dev->DevVenId.DevId,&EmbRom, &OptRomSize);
+ if(EFI_ERROR(Status)) {
+ Dev->PciIo.RomImage=NULL;
+ Dev->PciIo.RomSize=0;
+ } else {
+ //Check if Embeded Op ROM is valid...
+ if(*((UINT16*)EmbRom)!=PCI_OPT_ROM_SIG) Status=EFI_NOT_FOUND;
+ else{
+ //Allocate buffer for ROM Image.
+ Dev->PciIo.RomImage=Malloc(OptRomSize);
+ if(Dev->PciIo.RomImage==NULL) Status=EFI_OUT_OF_RESOURCES;
+ else {
+ MemCpy(Dev->PciIo.RomImage,EmbRom,OptRomSize);
+ Dev->PciIo.RomSize=OptRomSize;
+ Dev->Capab |= (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE + EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM);
+ Dev->Attrib |= (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_DEVICE + EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM);
+ }
+ }
+ }
+ }
+ }
+#endif
+ if(EFI_ERROR(ExitStatus)) return ExitStatus;
+//(EIP42750+)
+ //Calling OEM Hook to override Option Rom content...
+ Status=PciPortOemGetOptRom(Dev, &Dev->PciIo.RomImage, &Dev->PciIo.RomSize);
+ //if porting hook not implemented, adjust Status, otherwice return whatever we got
+ if(Status==EFI_UNSUPPORTED) Status=EFI_SUCCESS;
+//(EIP42750-)
+ return Status;
+}
+
+
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+EFI_STATUS LoadRomFile( IN EFI_LOAD_FILE2_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN BOOLEAN BootPolicy,
+ IN OUT UINTN *BufferSize,
+ IN VOID *Buffer OPTIONAL)
+{
+ PCI_LOAD_FILE_DATA *lfdata=(PCI_LOAD_FILE_DATA*)This;
+ PCI_DEV_INFO *dev=lfdata->Owner;
+ EFI_STATUS Status;
+ UINTN i;
+ MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *dp=(MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH*)FilePath;
+ PCI_ROM_IMAGE_DATA *romdata;
+ BOOLEAN found=FALSE;
+ VOID *imgb=NULL;
+ UINT32 imgsz;
+//---------------------
+
+ //Check input parameters first...
+ if( (dev->Signature != AMI_PCI_SIG) ||
+ (FilePath==NULL) || (BufferSize==NULL) ||
+ (dp->Header.Type!=MEDIA_DEVICE_PATH)||
+ (dp->Header.Type!=MEDIA_RELATIVE_OFFSET_RANGE_DP)||
+ (dev->EfiRomCount==0) ) return EFI_INVALID_PARAMETER;
+
+ if(BootPolicy==TRUE) return EFI_UNSUPPORTED;
+
+ for(i=0;i<dev->EfiRomCount; i++){
+ romdata=dev->EfiRomImages[i];
+ //verify that relative odffset corresponds to the images stored.
+ if(MemCmp(dp,&romdata->RomImageDP,sizeof(MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH))==0){
+ found=TRUE;
+ break;
+ }
+ }
+
+ if(!found) return EFI_NOT_FOUND;
+
+ if((romdata->ActualSize<*BufferSize)||(Buffer==NULL)){
+ *BufferSize=romdata->ActualSize;
+ if(Buffer==NULL)return EFI_SUCCESS;
+ else return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //here we have checked everything Time to read file ...
+ Status=ReadEfiRom(dev, romdata,&imgb,&imgsz);
+ if(EFI_ERROR(Status)) return Status;
+
+ MemCpy(Buffer,imgb,imgsz);
+
+ pBS->FreePool(imgb);
+ return Status;
+
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: OvrGetDriver()
+//
+// Description: PCI Bus Specific Override Protocol Get Override Driver
+// function implementation of the PCI Bus Driver.
+//
+// Input:
+// EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL **This Pointer PCI Devicse's
+// Bus Specific Override
+// Protocol Interface.
+// EFI_HANDLE IN OUT *DriverImageHandle Image Handle of the Option
+// ROM EFI Driver.
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When there are no more handles to override.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OvrGetDriver(IN EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL *This,
+ IN OUT EFI_HANDLE *DriverImageHandle )
+{
+ PCI_BUS_OVERRIDE_DATA *ovr=(PCI_BUS_OVERRIDE_DATA*)This;
+ UINTN i;
+ EFI_HANDLE himg=NULL;
+ PCI_DEV_INFO *dev=ovr->Owner;
+ PCI_ROM_IMAGE_DATA *romdata;
+//------------------------------------------------------------------
+
+ if((DriverImageHandle==NULL)||(dev->EfiRomCount==0))return EFI_INVALID_PARAMETER;
+
+ //Here we know dev->EfiRomCount>0
+ if(*DriverImageHandle==NULL) {
+ romdata=dev->EfiRomImages[0];
+ himg=romdata->RomImgHandle;
+ } else {
+ for(i=0; i<dev->EfiRomCount; i++){
+ romdata=dev->EfiRomImages[i];
+ if(*DriverImageHandle==romdata->RomImgHandle)break;
+ }
+
+ if(i==dev->EfiRomCount) return EFI_INVALID_PARAMETER;
+
+ if(i<dev->EfiRomCount-1)himg=romdata->RomImgHandle;
+ else return EFI_NOT_FOUND;
+ }
+
+ *DriverImageHandle=himg;
+ return EFI_SUCCESS;
+}
+
+/*
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddOvrHandle()
+//
+// Description: Adds EFI_HANDLE of the Addon Card Option ROM image to the
+// PCI Bus Driver Private Data.
+//
+// Input:
+// PCI_BUS_OVERRIDE_DATA *OvrData Pointer to the PCI Devicse's Bus
+// Override data inside PCI_DEV_INFO
+// EFI_HANDLE OvrHandle Handle to add.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AddOvrHandle( PCI_DEV_INFO *Device, EFI_HANDLE OvrHandle, UINTN StartOffset, UINTN EndOffset)
+{
+ PCI_ROM_IMAGE_DATA *romdata;
+//-------------------------------------------------
+ if(Device->BusOvrData.BusOverride.GetDriver==NULL)Device->BusOvrData.BusOverride.GetDriver=OvrGetDriver;
+
+
+ //Get the space needed
+ romdata=MallocZ(sizeof(PCI_ROM_IMAGE_DATA));
+ if (romdata==NULL) return EFI_OUT_OF_RESOURCES;
+
+ romdata->RomImgHandle=OvrHandle;
+ romdata->RelOffsStart=StartOffset;
+ romdata->RelOffsEnd=EndOffset;
+
+ return AppendItemLst((T_ITEM_LIST*)&Device->RomInitCnt, romdata);
+}
+*/
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DecompressOptRom()
+//
+// Description: Decompresses Option ROM Image if it is Compressed.
+//
+// Input:
+// VOID *Image Pointer at the compressed Option ROM Image.
+// UINT32 ImageLength Length of the Compressed Image.
+// OUT VOID **DecompImage Place holder to return pointer to the
+// Decopressed Image.
+// OUT UINT32 ImageLength Length of the Decompressed Image.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DecompressOptRom( VOID *Image, UINT32 ImageLength, VOID** DecompImage, UINT32 *DecompSize)
+{
+ EFI_STATUS Status;
+ EFI_DECOMPRESS_PROTOCOL *dcp;
+ UINT32 scrsz, imgsz;
+ VOID *imgb, *scrb;
+//--------------------------------
+ //Check for parameter first
+ if(!DecompImage) return EFI_INVALID_PARAMETER;
+
+ Status = pBS->LocateProtocol(&gEfiDecompressProtocolGuid, NULL,(VOID**)&dcp);
+ if(EFI_ERROR(Status))return Status;
+
+ Status = dcp->GetInfo(dcp,Image,ImageLength, &imgsz, &scrsz);
+ if (EFI_ERROR (Status)) return Status;
+
+ Status=pBS->AllocatePool(EfiBootServicesData, imgsz,&imgb);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=pBS->AllocatePool(EfiBootServicesData, scrsz,&scrb);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=dcp->Decompress(dcp,Image,ImageLength,imgb,imgsz,scrb,scrsz);
+ pBS->FreePool(scrb);
+
+ if(!EFI_ERROR(Status)){
+ *DecompImage=imgb;
+ *DecompSize=imgsz;
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS ReadEfiRom(PCI_DEV_INFO *Dev, PCI_ROM_IMAGE_DATA *RomData, VOID **ImgBase, UINT32 *ImgSize){
+ EFI_STATUS Status=EFI_SUCCESS;
+ VOID *imgb;
+ UINT32 imgsz;
+//-------------------
+
+ imgb=(VOID*)((UINTN)Dev->PciIo.RomImage+(UINTN)RomData->RomImageDP.StartingOffset);
+ imgsz=(UINT32)(RomData->RomImageDP.EndingOffset-RomData->RomImageDP.StartingOffset+1);
+
+ if (RomData->RomHeader->CompressionType){
+ Status=DecompressOptRom((UINT8*)RomData->RomHeader+RomData->RomHeader->EfiImageOffset,imgsz,&imgb,&imgsz);
+ }
+
+ if(!(EFI_ERROR(Status))){
+ *ImgBase=imgb;
+ *ImgSize=imgsz;
+ }
+ return Status;
+
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InstallEfiOpRom()
+//
+// Description: Loads and Starts Native EFI PCI Option ROM.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer PCI Devicse Private Data.
+// PCI_EFI_OPT_ROM_HEADER *RomHeader Pointer at PCI Option ROM Header
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InstallEfiOpRom( PCI_DEV_INFO *Dev,
+ PCI_EFI_OPT_ROM_HEADER *RomHeader,
+ PCI_DATA_STRUCTURE *Pcir)
+{
+ EFI_STATUS Status=0;
+ VOID *imgb;
+ UINT32 imgsz;
+ PCI_ROM_IMAGE_DATA *romdata;
+ EFI_DEVICE_PATH_PROTOCOL *romdp=NULL;
+
+//-------------------------------------------
+
+ if ((RomHeader->EfiSubsystem != EFI_IMAGE_BS_DRIVER) &&
+ (RomHeader->EfiSubsystem != EFI_IMAGE_RT_DRIVER))
+ return EFI_NOT_FOUND;
+
+ // decompress it if needed
+ if (RomHeader->CompressionType > 1) return EFI_INVALID_PARAMETER;
+
+ //Get the space needed
+ romdata=MallocZ(sizeof(PCI_ROM_IMAGE_DATA));
+ if (romdata==NULL) return EFI_OUT_OF_RESOURCES;
+
+ //Fill RomData Parts
+ romdata->RomHeader=RomHeader;
+ //Init RELATIVE OFFS DP Header...
+ romdata->RomImageDP.Header.Type=MEDIA_DEVICE_PATH;
+ romdata->RomImageDP.Header.SubType=MEDIA_RELATIVE_OFFSET_RANGE_DP;
+ SET_NODE_LENGTH(&romdata->RomImageDP.Header, sizeof(MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH));
+
+ //imgsz=RomHeader->InitializationSize*512-RomHeader->EfiImageOffset;
+ imgsz=(UINT32)DoubleCheckOpRom((VOID*)RomHeader, Pcir);
+ imgsz-=RomHeader->EfiImageOffset;
+
+ //Get Start..End offsets of Rom File...
+ imgb=(VOID*)((UINT8*)RomHeader+RomHeader->EfiImageOffset);
+ romdata->RomImageDP.StartingOffset=(UINT64)((UINTN)imgb-(UINTN)Dev->PciIo.RomImage);
+ romdata->RomImageDP.EndingOffset=romdata->RomImageDP.StartingOffset+imgsz-1;
+
+ Status=ReadEfiRom(Dev, romdata, &imgb, &imgsz);
+ if(EFI_ERROR(Status)) return Status;
+
+ //update Actual File size..
+ romdata->ActualSize=imgsz;
+
+ //Form Rom Image Device Path from Dev->DevicePath + romdata->RomImgDP+DP_END...
+ romdp=DPAddNode((VOID*)Dev->DevicePath, (VOID*)&romdata->RomImageDP);
+ if(romdp==NULL) return EFI_OUT_OF_RESOURCES;
+
+ //load image and start image
+ Status=pBS->LoadImage(FALSE,gPciBusDriverBinding.ImageHandle,romdp,imgb,imgsz,&romdata->RomImgHandle);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status=pBS->StartImage(romdata->RomImgHandle,NULL,NULL);
+ if (EFI_ERROR(Status)) return Status;
+
+ //Add romdata to the EfiRomList...
+ Status=AppendItemLst((T_ITEM_LIST*)&Dev->RomInitCnt, romdata);
+ if(EFI_ERROR(Status)) return Status;
+
+ //update BusOvr Data...
+ if(Dev->BusOvrData.BusOverride.GetDriver==NULL)Dev->BusOvrData.BusOverride.GetDriver=OvrGetDriver;
+
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ //Update LoadFile Data
+ if(Dev->LoadFileData.LoadFile2.LoadFile==NULL)Dev->LoadFileData.LoadFile2.LoadFile=LoadRomFile;
+#endif
+
+ if(romdp!=NULL)pBS->FreePool(romdp);
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPciRomDevId()
+//
+// Description: PCI Firmware Spec 3.0 defines some reserved field in PCIR
+// Structure as Device List Pointer. This function checks additional Device IDs
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer PCI Devicse Private Data.
+// PCI_DATA_STRUCTURE *PciRomStruct Pointer at PCIR ROM Header
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_UNSUPPORTED When ROM is not compatible with device.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckPciRomDevId(PCI_DEV_INFO *Dev, PCI_DATA_STRUCTURE *PciRomStruct){
+ UINT16 *did;
+//--------------------------
+ if(Dev->DevVenId.VenId != PciRomStruct->VendorId) return EFI_NOT_FOUND;
+
+ if(Dev->DevVenId.DevId != PciRomStruct->DeviceId){
+ //Dev->DevVenId.DevId ==0x0000 special case - (Service ROM like PXE, iSCIS boot agent)
+ if(Dev->DevVenId.DevId==0) return EFI_SUCCESS;
+
+ //Check Device List if any...
+ if(PciRomStruct->Reserved0 == 0) return EFI_UNSUPPORTED;
+
+ did=(UINT16*)((UINT8*)PciRomStruct + PciRomStruct->Reserved0);
+
+ while(*did != 0){
+ if(Dev->DevVenId.DevId==*did) return EFI_SUCCESS;
+ did++; // next device list entry
+ }
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ExecuteUefiRom()
+//
+// Description: This function decide to launch or not UEFI compatible
+// Option ROM
+//
+// Input:
+// UINT8 PciClass PCI Class Code Of the Device.
+//
+// Output: BOOLEAN
+// TRUE Launch UEFI Option ROM
+// FALSE NOT Launch UEFI Option ROM
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ExecuteUefiRom(PCI_DEV_INFO *Dev)
+{
+ EFI_STATUS Status;
+ AMI_OPROM_POLICY_PROTOCOL *AmiOpromPolicyProtocol;
+ static EFI_GUID AmiOpromPolicyProtocolGuid = AMI_OPROM_POLICY_PROTOCOL_GUID;
+
+ Status = pBS->LocateProtocol(&AmiOpromPolicyProtocolGuid, NULL, &AmiOpromPolicyProtocol);
+ if(EFI_ERROR(Status)) //if CSM OptOut is disabled we should always launch UEFI OpROM
+ return TRUE;
+
+ Status = AmiOpromPolicyProtocol->CheckUefiOpromPolicy(AmiOpromPolicyProtocol, Dev->Handle);
+ return (EFI_ERROR(Status)) ? FALSE : TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ActivateOptRom()
+//
+// Description: This function parses Option ROM Image to decide which
+// Image to give control to and updates PciIO->OptioRom and
+// PciIO->OptioRomSize with Correct values.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer PCI Devicse Private Data.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_NOT_FOUND When Device does not have any ROMs.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ActivateOptRom(PCI_DEV_INFO *Dev)
+{
+ UINT8 *cp;
+ UINTN roms=0;
+ UINTN romc;
+ PCI_EFI_OPT_ROM_HEADER *rh;
+ PCI_DATA_STRUCTURE *pcir;
+ BOOLEAN ff=TRUE;//, fnd=FALSE;
+ BOOLEAN efior=FALSE;
+ BOOLEAN notarom=FALSE;
+ UINTN sz=0;
+ INT64 rsz=(INT64)Dev->PciIo.RomSize;
+ EFI_STATUS Status=EFI_SUCCESS;
+ BOOLEAN RomMatch=FALSE;
+//------------------------
+ if (!Dev->PciIo.RomImage) return EFI_NOT_FOUND;
+
+ cp=(UINT8*)Dev->PciIo.RomImage;
+ for(romc=0;;romc++){
+ rsz-=sz;
+ if(rsz<=0)return Status;
+ cp=cp+sz;
+
+ rh=(PCI_EFI_OPT_ROM_HEADER*)cp;
+ //Check if a valid signarture here
+ if(ff){//first time here
+ if(rh->Signature!=PCI_OPT_ROM_SIG){
+ notarom=TRUE;
+ break;
+ }
+ roms=(UINTN)rh;
+ } else {
+ //here is the case when we can not find a valid signature for the next image
+ //withing the Option ROM
+ if(rh->Signature!=PCI_OPT_ROM_SIG){
+ sz=512;
+ continue;
+ }
+ }
+ ff=FALSE;
+
+ //Check if it is EFI Opt ROM
+ if(rh->EfiSignature==PCI_OPT_ROM_EFISIG) efior=TRUE;
+ else efior=FALSE;
+
+ //we got what we were looking for...
+ pcir=(PCI_DATA_STRUCTURE*)(cp+rh->PcirOffset);
+ if(pcir->Signature!=PCI_PCIR_SIG) continue;
+
+ //Here is some more conditions to check.
+ //some ROMs has Different Sizes filled in 0x55AA ROM Header and in PCIR structure.
+ //So check which size is right by looking one
+
+ //PCI Firmware Spec 3.0 defines some reserved field in PCIR Structure as Device List Pointer
+ Status=CheckPciRomDevId(Dev, pcir);
+ if(EFI_ERROR(Status)) {
+ if(Status==EFI_NOT_FOUND){
+ PCI_TRACE((TRACE_PCI," ROM Img #%d Dev.VID!=PCIR.VID ", romc));
+ } else PCI_TRACE((TRACE_PCI," ROM Img #%d Dev.DID!=PCIR.DID ", romc));
+ } else RomMatch=TRUE;
+
+ //Check Setup option which Option ROM to post Legacy = 0 \[EFI Compatible = 1]
+ if( ExecuteUefiRom(Dev) ) {
+ //here we go...let's see what it is
+ //check conditions under which we must process EFI OptROM
+ if( efior && pcir->CodeType == PCI_CODE_TYPE_EFI_IMAGE && RomMatch)
+ {
+ PCI_TRACE((TRACE_PCI,"(Install EFI ROM="));
+ Status=InstallEfiOpRom(Dev,rh, pcir);
+ PCI_TRACE((TRACE_PCI,"%r)", Status));
+ }
+ }
+
+ if(pcir->Indicator&0x80) {
+ break;
+ }
+ //else keep circling until we reach the end...
+ sz=DoubleCheckOpRom((VOID*)rh, pcir);
+ }
+
+ if(notarom || !RomMatch){
+ Status=pBS->FreePool(Dev->PciIo.RomImage);
+ Dev->PciIo.RomImage=NULL;
+ Dev->PciIo.RomSize=0;
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InstallPciDevice()
+//
+// Description: This function performs the following operations
+// 1. Register Device with CORE by getting a brand new handle
+// 2. Install PciIo Protocol Interface on This Device
+// 3. Generates EFI_DEVICE_PPATH protocol instance for "Dev"ice
+// 4. Installs DevicePath Protocol on Created Handle
+// 5. If Device has Option ROM copy it to the Memory Buffer
+// 6. If 5 is TRUE and if Opt ROM has EFI compliant Image
+// installs Bus Override protocol.
+//
+// Input:
+// EFI_HANDLE ControllerHandle Device's Controller Handle.
+// PCI_DEV_INFO *Dev Pointer PCI Devicse Private Data.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InstallPciDevice(EFI_HANDLE ControllerHandle, PCI_DEV_INFO *Dev)
+{
+ EFI_STATUS Status=0;
+ EFI_STATUS OpRomStatus = EFI_NOT_FOUND;
+ BOOLEAN ndp=FALSE;//NewDevicePath
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ VOID *buff[8]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+#else
+ VOID *buff[6]={NULL,NULL,NULL,NULL,NULL,NULL};
+#endif
+ UINTN offs=0;
+ BOOLEAN cr=TRUE;
+//-----------------------------------
+
+ PCI_TRACE((TRACE_PCI,"PciBus: Installing PCI IO for B%X|D%X|F%X; ->->->->\n", Dev->Address.Addr.Bus,
+ Dev->Address.Addr.Device,Dev->Address.Addr.Function));
+
+ //Check if Device Has Been already started
+ if(Dev->Started) {
+ Status=EFI_ALREADY_STARTED;
+ PCI_TRACE((TRACE_PCI," -> Dev.Started=1; -> %r\n",Status));
+ return Status;
+ }
+
+ if(Dev->Type==tPciRootBrg) ndp=FALSE;
+ else ndp=TRUE;
+
+ if(Dev->PciIo.PollMem!=gPciIoInstance.PollMem){
+ pBS->CopyMem(&Dev->PciIo, &gPciIoInstance, sizeof(EFI_PCI_IO_PROTOCOL));
+ } else cr=FALSE;
+ buff[offs]=&gPciIoProtocolGuid;
+ buff[offs+1]=&Dev->PciIo;
+ offs+=2;
+
+ //Install Device Path Protocol on newly created Handle
+ if(ndp){
+ buff[offs]=&gDevicePathProtocolGuid;
+ buff[offs+1]=Dev->DevicePath;
+ offs+=2;
+ }
+ //Check if Device has Opton ROM ...
+ if(cr)
+ OpRomStatus=GetOptRom(Dev);
+ else if(Dev->PciIo.RomImage != NULL && Dev->PciIo.RomSize != 0) //OpROM was initialized earlier
+ OpRomStatus = EFI_SUCCESS;
+
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &Dev->Handle,
+ buff[0],buff[1], //PciIO GUID - I/F pare
+ buff[2],buff[3], //DevPath GUID - I/F pare
+ NULL, NULL );
+ PCI_TRACE((TRACE_PCI,"/nPciBus: Installing DP; PCIO Status=%r",Status));
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //update offset it might be ==2 if ndp==FALSE, but we need it as 4 after this point.
+ offs=4;
+
+ PCI_TRACE((TRACE_PCI,":GetRom="));
+
+ if(EFI_ERROR(OpRomStatus)){
+ Dev->RomBarError=TRUE;
+ Dev->PciIo.RomImage=NULL;
+ Dev->PciIo.RomSize=0;
+ PCI_TRACE((TRACE_PCI,"%r\n", OpRomStatus));
+ } else {
+ //Print Status from GetOptRom()
+ PCI_TRACE((TRACE_PCI,"%r :ActivateRom", OpRomStatus));
+ if(cr) Status=ActivateOptRom(Dev);
+ PCI_TRACE((TRACE_PCI,"=%r\n", Status));
+ if(EFI_ERROR(Status)){
+ if(Status==EFI_NOT_FOUND) Status=EFI_SUCCESS; //just there are no any EFI Opt ROMs
+ else return Status;
+ }
+
+ //Check if Override handle count gets changed..
+ //then install Bus Override protocol interface
+ if(Dev->BusOvrData.BusOverride.GetDriver!=NULL){
+ buff[offs]=&gBusSpecificDriverOverrideProtocolGuid;
+ buff[offs+1]=&Dev->BusOvrData.BusOverride;
+ }
+
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ offs+=2;
+ if(Dev->LoadFileData.LoadFile2.LoadFile!=NULL){
+ buff[offs]=&gEfiLoadFile2ProtocolGuid;
+ buff[offs+1]=&Dev->LoadFileData.LoadFile2;
+ }
+#endif
+
+ }
+
+
+ //Now Before installing Protocol Interface for THIS device.
+ //Call Porting Hook to do OEM Custom Programming of the device.
+ //PciIo and all the stuff been updated for this device.
+ //But NO notification yet for PciIO installation dispatchetd
+ Status=PciPortOemProgDevice(Dev);
+
+ PCI_TRACE((TRACE_PCI,":PciBus: Calling PciPortOemProgDevice() >Status=%r\n", Status));
+
+ if(buff[5]!=NULL){
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &Dev->Handle,
+ buff[4],buff[5], //PciIO GUID - I/F pare
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ buff[6],buff[7], //LoadFile2 GUID - I/F pare if present
+#endif
+ NULL, NULL );
+
+ PCI_TRACE((TRACE_PCI," -> Installing BusOvr and LoadFile2 -> %r\n", Status));
+
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ if(Dev->Type>tPciRootBrg){//Don't Open Rb Protocol for itself
+ Status=pBS->OpenProtocol(
+ ControllerHandle, &gPciRootBridgeIoProtocolGuid,
+ (VOID**)&Dev->RbIo, gPciBusDriverBinding.DriverBindingHandle,
+ Dev->Handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER);
+ }
+
+ //Set Started Flag...
+ Dev->Started=TRUE;
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StartPciChildDevice()
+//
+// Description: Starts PCI Devices Behind the Bridge. (Called recoursively)
+// This function performs the following operations
+// 1. Register Device with CORE by getting a brand new handle
+// 2. Install PciIo Protocol Interface on This Device
+// 3. Generates EFI_DEVICE_PPATH protocol instance for "Dev"ice
+// 4. Installs DevicePath Protocol on Created Handle
+// 5. If Device has Option ROM copy it to the Memory Buffer
+// 6. If 5 is TRUE and if Opt ROM has EFI compliant Image
+// installs Bus Override protocol.
+//
+// Input:
+// EFI_HANDLE ControllerHandle Device's Controller Handle.
+// PCI_BRG_INFO *Brg Pointer at PCI Bridge Private Data.
+// EFI_DEVICE_PATH_PROTOCOL *RemainingDp Pointer at PCI Device Path
+// Protocol Instance or NULL.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS StartPciChildDevice(EFI_HANDLE ControllerHandle,PCI_BRG_INFO *Brg, PCI_DEVICE_PATH *RemainingDp)
+{
+ PCI_DEV_INFO *dev;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINTN i;
+ PCI_DEVICE_PATH *pcidp=RemainingDp;
+ BOOLEAN Started=FALSE, Success=FALSE;
+//-------------------------------
+
+ PCI_TRACE((TRACE_PCI, "PciBus: StartPciChildDevice -> Bridge has %d Child Devices \n",Brg->Bridge.ChildCount));
+
+ //Check if Device Path is a valid PCI Device Path
+ if (pcidp!=NULL){
+ //Check if remaining device path is a valid PCI device path
+ if( EFI_ERROR(CheckPciDevicePath(&pcidp->Header)) ) return EFI_INVALID_PARAMETER;
+ //If remaining device path is provided, we must find the device.
+ }
+
+ if(!Brg->Bridge.ChildCount) return Status;
+
+ for(i=0; i<Brg->Bridge.ChildCount; i++){
+ dev=Brg->Bridge.ChildList[i];
+ if(dev->OutOfResRemove) continue;
+ //if Remaining Device Path provided start only specified device
+ if(pcidp)
+ {
+ if(pcidp->Device != dev->Address.Addr.Device ||
+ pcidp->Function != dev->Address.Addr.Function
+ ) continue;
+ // The Device Path of this Device matches provided
+ Status=InstallPciDevice(ControllerHandle, dev);
+ if (EFI_ERROR(Status)){
+ if(Status==EFI_ALREADY_STARTED) Started=TRUE;
+ else return Status;
+ } else Success=TRUE;
+
+ //if Device is P2P bridge than BDS might like to start next DP node
+ //So recousively call this function to find desired Device
+ pcidp++;
+ if(dev->Type==tPci2PciBrg && !isEndNode(&pcidp->Header))
+ Status=StartPciChildDevice(ControllerHandle,(PCI_BRG_INFO*)dev,pcidp);
+
+
+ //if(!EFI_ERROR(Status) && Status == EFI_NOT_FOUND){
+ // if(Started && !Success) Status=EFI_ALREADY_STARTED;
+ //}
+ return Status;
+ }
+ else //if no Remaining Device Path provided start all devices
+ {
+ Status=InstallPciDevice(ControllerHandle, dev);
+ if (EFI_ERROR(Status)){
+ if(Status==EFI_ALREADY_STARTED){
+ Started=TRUE;
+ Status=EFI_SUCCESS;
+ } else return Status;
+ } else Success=TRUE;
+
+ //if Device is P2P bridge recousively call this function
+ if(dev->Type==tPci2PciBrg){
+ Status=StartPciChildDevice(ControllerHandle,(PCI_BRG_INFO*)dev,pcidp);
+ if(EFI_ERROR(Status)){
+ //StartPciChildDevice() could return EFI_ALREADY_STARTED or EFI_NOT_FOUND
+ //this is if we have started this device already, of Bridge don't have any
+ //childs behind it. This is normal and we shouldn't break the loop.
+ //All other ERROR Statuses suppose to break the loop and raise an ERROR.
+ if(Status==EFI_ALREADY_STARTED || Status==EFI_NOT_FOUND){
+ Started=TRUE;
+ Status=EFI_SUCCESS;
+ } else return Status;
+ } else Success=TRUE;
+ }
+ }
+ }//for
+
+ if(!EFI_ERROR(Status)){
+ if(Started && !Success) Status=EFI_ALREADY_STARTED;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StartPciDevices()
+//
+// Description: Installs PCI Io Protocol Instance on all or some PCI Devices
+// in the System
+//
+// Input:
+// EFI_HANDLE ControllerHandle Device's Controller Handle.
+// EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath Pointer at PCI Device Path
+// Protocol Instance or NULL.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS StartPciDevices(IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ UINTN i, j;
+ PCI_DEV_INFO *rbrg;
+ PCI_HOST_INFO *lhst; //local host
+ EFI_DEVICE_PATH_PROTOCOL *rdp=RemainingDevicePath;
+//---------------------------------------------
+ PCI_TRACE((TRACE_PCI, "\n====================================================================\n"));
+ PCI_TRACE((TRACE_PCI, "PciBus: StartPciDevices Called -> hCtrl=0x%X; RemainingDp=0x%X;\n",ControllerHandle,RemainingDevicePath));
+
+ //Check if RemainingDevicePath is valid
+ if(rdp!=NULL){
+
+ if (isEndNode(rdp)) {
+ PCI_TRACE((TRACE_PCI, "PciBus: RemainingDp==EndOfDpNode\n"));
+ return EFI_SUCCESS;
+ } else {
+ Status=CheckPciDevicePath(rdp);
+ PCI_TRACE((TRACE_PCI, "PciBus: START CheckPciDp -> %r\n",Status));
+ if(EFI_ERROR(Status)) goto ExitLbl;
+ }
+ }
+
+ //find Root Bridge first
+ for(j=0; j<gHostCnt; j++){
+ lhst=&gPciHost[j];
+ for(i=0; i<lhst->RbCount; i++){
+ rbrg=lhst->RootBridges[i];
+
+ if(rbrg->Handle==ControllerHandle){
+
+ Status=pBS->OpenProtocol(rbrg->Handle,
+ &gPciRootBridgeIoProtocolGuid,(VOID **)&rbrg->RbIo,
+ gPciBusDriverBinding.DriverBindingHandle,rbrg->Handle,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if(EFI_ERROR(Status)){
+ if( Status!=EFI_ALREADY_STARTED ) return Status;
+ else Status=EFI_SUCCESS;
+ }
+
+ Status=StartPciChildDevice(ControllerHandle,(PCI_BRG_INFO*)rbrg,(PCI_DEVICE_PATH*)rdp);
+ break;
+ }
+ }
+ }
+ExitLbl:
+
+ PCI_TRACE((TRACE_PCI, "PciBus: StartPciChildDevice -> %r\n",Status));
+ PCI_TRACE((TRACE_PCI, "====================================================================\n"));
+
+ return Status;
+}
+
+EFI_STATUS LocateDevHandle(PCI_DEV_INFO *Dev, T_ITEM_LIST *PciHnd){
+ UINTN i;
+ EFI_HANDLE h;
+//------------------------
+ for(i=0; i<PciHnd->ItemCount; i++){
+ h=*(EFI_HANDLE*)(PciHnd->Items[i]);
+ if(Dev->Handle==h){
+ DeleteItemLst(PciHnd, i, FALSE);
+ Dev->Handle=NULL;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StopPciDevice()
+//
+// Description: Stops PCI Device referenced as "Dev". Called From
+// StopPciDeviceBrg() function.
+//
+// Input:
+// PCI_DEV_INFO *Dev Pointer PCI Devicse Private Data.
+// EFI_HANDLE Controller Device's Controller Handle.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS StopPciDevice(PCI_DEV_INFO *Dev,EFI_HANDLE Controller, T_ITEM_LIST *HndDb)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN offs=0;
+ BOOLEAN ndp;
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ VOID *buff[8]={NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL};
+#else
+ VOID *buff[6]={NULL,NULL,NULL,NULL,NULL,NULL};
+#endif
+//--------------------------------------------------------------------
+
+ //Check if Device Has been Stopped already...
+ if(Dev->Started==FALSE) return EFI_SUCCESS;
+
+ if(Dev->Type==tPciRootBrg) {
+ Dev->Started=FALSE;
+ return EFI_SUCCESS;
+ }
+
+ PCI_TRACE((TRACE_PCI,"\nPciBusStop: Hnd=%X [B%X|D%X|F%X]->",Dev->Handle,
+ Dev->Address.Addr.Bus,Dev->Address.Addr.Device, Dev->Address.Addr.Function));
+ //Close Root Brg Protocol we've opened at the beginning.
+ //Avoid Closing Protocol for RootBridge Device - we didn't open it.
+ if(Dev->Handle!=Controller){
+ Status=pBS->CloseProtocol(Controller,&gPciRootBridgeIoProtocolGuid,
+ gPciBusDriverBinding.DriverBindingHandle, Dev->Handle);
+ ndp=TRUE;
+ PCI_TRACE((TRACE_PCI,"Close(RbIo)=%r;\n",Status));
+ } else {
+ ndp=FALSE;
+ }
+
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ buff[offs]=&gPciIoProtocolGuid;
+ buff[offs+1]=&Dev->PciIo;
+ offs+=2;
+
+ //Same for Device Path: we did'not create device path for RootBridge device
+ if(ndp){
+ buff[offs]=&gDevicePathProtocolGuid;
+ buff[offs+1]=Dev->DevicePath;
+ offs+=2;
+ }
+
+ //Now take care of BusSpecific Override Protocol
+ //If it was installed
+ if(Dev->BusOvrData.BusOverride.GetDriver!=NULL){
+ buff[offs]=&gBusSpecificDriverOverrideProtocolGuid;
+ buff[offs+1]=&Dev->BusOvrData.BusOverride;
+ }
+
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ //LoadFile2 Protocol
+ offs+=2;
+ if(Dev->LoadFileData.LoadFile2.LoadFile!=NULL){
+ buff[offs]=&gEfiLoadFile2ProtocolGuid;
+ buff[offs+1]=&Dev->LoadFileData.LoadFile2;
+ }
+#endif
+ Status=pBS->UninstallMultipleProtocolInterfaces(
+ Dev->Handle,
+ buff[0],buff[1], //PciIO GUID - I/F pare
+ buff[2],buff[3], //DevPath GUID - I/F pare
+ buff[4],buff[5], //BusOwerride GUID - I/F pare if present
+#if ((defined EFI_SPECIFICATION_VERSION) && (EFI_SPECIFICATION_VERSION >= 0x2001F))
+ buff[6],buff[7], //LoadFile2 GUID - I/F pare if present
+#endif
+ NULL, NULL );
+
+ PCI_TRACE((TRACE_PCI,"\nPciBusStop: Hnd=%X [B%X|D%X|F%X]->",Dev->Handle,
+ Dev->Address.Addr.Bus,Dev->Address.Addr.Device, Dev->Address.Addr.Function));
+ PCI_TRACE((TRACE_PCI,"Uninst(PciIo,DP,BusOvr)=%r;\n",Status));
+//DEBUG????
+ if(!EFI_ERROR(Status)){
+//DEBUG????
+ Dev->Started=FALSE;
+ if(HndDb!=NULL) Status=LocateDevHandle(Dev, HndDb);
+ Dev->Handle=NULL;
+//DEBUG????
+ }
+//DEBUG????
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StopPciDeviceBrg()
+//
+// Description: Stops - Uninstalls PCI Io Protocol Instance from PCI Devices
+// behind the PCI Bridge referenced as "Brg"
+//
+// Input:
+// PCI_BRG_INFO *Brg Pointer PCI Devicse Private Data.
+// EFI_HANDLE Controller Device's Controller (Parent) Handle.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_OUT_OF_RESOURCES When system runs out of resources.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS StopPciDeviceBrg(PCI_BRG_INFO *Brg, EFI_HANDLE Controller, T_ITEM_LIST *HndDb)
+{
+ PCI_DEV_INFO *dev;
+ UINTN i;
+ EFI_STATUS Status;
+//--------------------------------------------------------------------
+ for(i=0; i<Brg->Bridge.ChildCount; i++){
+ dev=Brg->Bridge.ChildList[i];
+ //recoursive calling ourselfs
+ if(dev->Type==tPci2PciBrg) Status=StopPciDeviceBrg((PCI_BRG_INFO*)dev,Controller, HndDb);
+ else Status=StopPciDevice(dev, Controller, HndDb);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ //After we done with the childs - Stop this Bridge itself
+ Status=StopPciDevice(&Brg->Common, Controller, HndDb);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+//==============================================================================
+//
+// EFI Drver Binding Protocol Functions
+//
+//==============================================================================
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciBusSupported()
+//
+// Description: Supported Function of the EFI_DRIVER_BINDING_PROTOCOL
+// for PCI Bus Driver.
+//
+// Notes:
+// See EFI Specification for detail description
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciBusSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo;
+ EFI_DEVICE_PATH_PROTOCOL *rdp=RemainingDevicePath;
+//-----------------------------------------------
+
+
+ //Check if it is valid Device Path
+ if (rdp != NULL){
+ if (isEndNode(rdp)) rdp=NULL;
+ else {
+ Status=CheckPciDevicePath(rdp);
+ if (EFI_ERROR (Status)) return Status;
+ }
+ }
+
+ //Open the IO Abstraction(s) needed to perform the supported test
+ Status=pBS->OpenProtocol(Controller,
+ &gDevicePathProtocolGuid,
+ (VOID **)&ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (Status == EFI_ALREADY_STARTED)return EFI_SUCCESS;
+ if (EFI_ERROR (Status)) return Status;
+
+ pBS->CloseProtocol(Controller,&gDevicePathProtocolGuid,This->DriverBindingHandle,
+ Controller);
+
+ Status=pBS->OpenProtocol( Controller,
+ &gPciRootBridgeIoProtocolGuid,
+ (VOID **)&PciRootBridgeIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if(Status==EFI_ALREADY_STARTED) return EFI_SUCCESS;
+
+ pBS->CloseProtocol(Controller,&gPciRootBridgeIoProtocolGuid,This->DriverBindingHandle,
+ Controller);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciBusStart()
+//
+// Description: Start Function of the EFI_DRIVER_BINDING_PROTOCOL
+// for PCI Bus Driver
+//
+// Notes:
+// See EFI Specification for detail description
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciBusStart(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_STATUS Status;
+ BOOLEAN ft=FALSE;
+//------------------------------------------------
+ PROGRESS_CODE(DXE_PCI_BUS_BEGIN);
+
+ PCI_TRACE((TRACE_PCI,"\n"));
+
+ //Locate Boot Script protocol we will need it to record Extd PCIExpress Config Space Programing
+ if(gBootScriptSave==NULL){
+ Status = pBS->LocateProtocol(&gEfiBootScriptSaveGuid, NULL, &gBootScriptSave);
+ if(EFI_ERROR(Status)) {
+ PCI_TRACE((TRACE_PCI,"PciBus: Unable to find EfiBootScriptSave Protocol! Status=%r EXITING!\n", Status));
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+#if CSM_SUPPORT
+ //Locate Legacy BIOS Extended protocol, we will need it to record Extd PCIExpress Config Space Programing
+ if(gLegacyBiosExt==NULL){
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosExtProtocolGuid, NULL, &gLegacyBiosExt);
+ if(EFI_ERROR(Status)) {
+ PCI_TRACE((TRACE_PCI,"PciBus: Unable to find Legacy Bios Extension Protocol! Status=%r\n", Status));
+ gLegacyBiosExt=NULL;
+ }
+ }
+#endif
+
+ //Locate Ami Board Info Protocol
+ if(gAmiBoardInfo==NULL){
+ Status = pBS->LocateProtocol(&gAmiBoardInfoProtocolGuid, NULL, &gAmiBoardInfo);
+ if(EFI_ERROR(Status)) {
+ PCI_TRACE((TRACE_PCI,"PciBus: Unable to find AMI Board Info Protocol! Status=%r\n", Status));
+ return Status;
+ }
+ ft=TRUE;
+ }
+
+ //Create Pci Setup Data Buffer;
+ if(gPciSetupData==NULL){
+ gPciSetupData=MallocZ(sizeof(PCI_SETUP_DATA));
+ if (gPciSetupData==NULL) return EFI_OUT_OF_RESOURCES;
+ //Call Board Specific function from PciPort.c to fill PCI Setup data buffer
+ BrdGetPciSetupData(gPciSetupData);
+ }
+
+ // Enumerate the entire host bridge
+ Status = EnumerateAll(Controller);
+ if(ft){
+#if EFI_DEBUG
+ //Print Bus Xlat table
+ UINTN i;
+ PCI_IRQ_PIC_ROUTE *ir;
+ PCI_IRQ_APIC_ROUTE *ar;
+ //-----------
+ PCI_TRACE((TRACE_PCI,"PciBus: Printing PIC $PIR table, %d entries \n", gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE) ));
+ PCI_TRACE((TRACE_PCI,"============================================================\n"));
+ PCI_TRACE((TRACE_PCI," # Bus D|F PIRQ A PIRQ B PIRQ C PIRQ D Slt#\n"));
+ PCI_TRACE((TRACE_PCI,"------------------------------------------------------------\n"));
+ for(i=0; i<(gAmiBoardInfo->PicRoutLength/sizeof(PCI_IRQ_PIC_ROUTE));i++){
+ ir=&gAmiBoardInfo->PicRoutTable[i];
+ PCI_TRACE((TRACE_PCI,"%02d %02X %02X|%X %02X->%04X %02X->%04X %02X->%04X %02X->%04X %02X\n", i,
+ ir->PciBusNumber, ir->DevFun.Dev,ir->DevFun.Fun,
+ ir->PciIrq[0].ChipsetReg, ir->PciIrq[0].IrqMask,
+ ir->PciIrq[1].ChipsetReg, ir->PciIrq[1].IrqMask,
+ ir->PciIrq[2].ChipsetReg, ir->PciIrq[2].IrqMask,
+ ir->PciIrq[3].ChipsetReg, ir->PciIrq[3].IrqMask,
+ ir->SlotNum));
+ }
+ PCI_TRACE((TRACE_PCI,"============================================================\n"));
+ PCI_TRACE((TRACE_PCI,"\nPciBus: Printing APIC table, %d entries \n", gAmiBoardInfo->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE) ));
+ PCI_TRACE((TRACE_PCI,"============================================================\n"));
+ PCI_TRACE((TRACE_PCI," # Bus Dev PIRQ A PIRQ B PIRQ C PIRQ D\n"));
+ PCI_TRACE((TRACE_PCI,"------------------------------------------------------------\n"));
+ for(i=0; i<(gAmiBoardInfo->ApicRoutLength/sizeof(PCI_IRQ_APIC_ROUTE));i++){
+ ar=&gAmiBoardInfo->ApicRoutTable[i];
+ PCI_TRACE((TRACE_PCI,"%02d %02X %02X %02X ID=%02X %02X ID=%02X %02X ID=%02X %02X ID=%02X\n", i,
+ ar->PciBusNumber, ar->DeviceNumber,
+ ar->Intn[0].IoApicItin, ar->Intn[0].IoApicId,
+ ar->Intn[1].IoApicItin, ar->Intn[1].IoApicId,
+ ar->Intn[2].IoApicItin, ar->Intn[2].IoApicId,
+ ar->Intn[3].IoApicItin, ar->Intn[3].IoApicId));
+ }
+ PCI_TRACE((TRACE_PCI,"============================================================\n"));
+
+#endif
+ RemoveUnusedIrqEntries();
+ gAmiBoardInfo->DataValid=TRUE;
+ }
+
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR (Status)) return Status;
+
+ //If Enumeration is OK install Extended PCI BUS Protocol Interface NOW.
+ //Only if we have not done it before. It is only single instance on PciBusExt possible.
+ if(gAmiExtPciBusProtocol.PciExtHanle==NULL){
+ Status=pBS->InstallMultipleProtocolInterfaces( &gAmiExtPciBusProtocol.PciExtHanle,
+ &gAmiExtPciBusProtocolGuid, &gAmiExtPciBusProtocol, NULL);
+ }
+
+ if (EFI_ERROR (Status)){
+ PCI_TRACE((TRACE_PCI,"PciBus: Unable to INSTALL Extended PCI Bus Protocol! Status=%r\n", Status));
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ // Enable PCI device specified by remaining device path. BDS or other driver can call the
+ // start more than once.
+ Status=StartPciDevices (Controller, RemainingDevicePath);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciBusStop()
+//
+// Description: Stop Function of the EFI_DRIVER_BINDING_PROTOCOL
+// for PCI Bus Driver.
+//
+// Notes:
+// See EFI Specification for detail description
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciBusStop(IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer)
+{
+ EFI_STATUS Status=0;
+ PCI_DEV_INFO *dev=NULL;
+ UINTN i;
+ T_ITEM_LIST PciHndDb={0,0,NULL};
+ EFI_HANDLE hnd;
+//------------------------------------------------
+ PCI_TRACE((TRACE_PCI,"\nPciBusStop: NumberOfChildren=0x%X, Controller=0x%X\n",NumberOfChildren, Controller));
+
+ if (NumberOfChildren == 0) {
+ // Close the bus driver
+ //mST->BootServices->CloseProtocol(Controller,&gDevicePathProtocolGuid,
+ // This->DriverBindingHandle, Controller);
+ dev=FindPciDeviceByHandle(Controller);
+ if(dev) Status=StopPciDeviceBrg((PCI_BRG_INFO*)dev, Controller, NULL);
+ else Status=EFI_NOT_FOUND;
+ ASSERT_EFI_ERROR(Status);
+ //Close PCI Rooty Bridge Protocol we opened BY_DRIVER
+ pBS->CloseProtocol(Controller,&gPciRootBridgeIoProtocolGuid,
+ This->DriverBindingHandle,Controller);
+ } else {
+ //Populate PciHandle Database we need to stop. If we will enter recoursive
+ //call we need to rtemove stopped handles from DB inside recoursive call
+ //to avoid getting EFI_INVALID_PARAMETER trying to Stop already stopped devices.
+ for(i=0; i<NumberOfChildren; i++){
+ AppendItemLst(&PciHndDb, &ChildHandleBuffer[i]);
+ PCI_TRACE((TRACE_PCI,"Hnd #%X: %X \n", i, ChildHandleBuffer[i]));
+ }
+
+ //Stopping all the childs
+ while(PciHndDb.ItemCount){
+ hnd=*(EFI_HANDLE*)(PciHndDb.Items[0]);
+ dev=FindPciDeviceByHandle(hnd);
+ if(dev){
+ //If device a bridge stop all its childs first
+ if(dev->Type==tPci2PciBrg)Status=StopPciDeviceBrg((PCI_BRG_INFO*)dev,Controller, &PciHndDb);
+ else Status=StopPciDevice(dev,Controller,&PciHndDb);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status))return Status;
+ } else {
+ Status=EFI_NOT_FOUND;
+ break;
+ }
+ ASSERT_EFI_ERROR(Status);
+ }//while...
+ }
+
+ if(gAmiExtPciBusProtocol.PciExtHanle!=NULL){
+ Status=pBS->UninstallMultipleProtocolInterfaces( gAmiExtPciBusProtocol.PciExtHanle,
+ &gAmiExtPciBusProtocolGuid, &gAmiExtPciBusProtocol, NULL);
+ if (!EFI_ERROR(Status)) {
+ gAmiExtPciBusProtocol.PciExtHanle=NULL;
+ }
+ }
+
+ //Cleanup used memory...
+ ClearItemLst(&PciHndDb, FALSE);
+ return Status;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+//----------------------------------------------------------------------------
+// PCI BUS Extended Protocol Function Implementation
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtGetDevice()
+//
+// Description: Locates PCI_DEV_INFO using passed PCI Device Handle or PciIo
+// Protocol pointer.
+// Input:
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+//
+// Output:
+// PCI_DEV_INFO* When everything is going on fine!
+// NULL If no such device exists.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PCI_DEV_INFO* PciExtGetDevice(EFI_HANDLE PciDeviceHandle, EFI_PCI_IO_PROTOCOL *PciIo){
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ if(PciDeviceHandle == NULL){
+ if(PciIo!=NULL){
+ dev=(PCI_DEV_INFO*)PciIo;
+ if(dev->Signature != AMI_PCI_SIG) return NULL;
+ } else return NULL;
+ } else dev=FindPciDeviceByHandle(PciDeviceHandle);
+
+ return dev;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtIsPciExpresss()
+//
+// Description: Checks if PciDeviceHandle, or PciIO passed belongs to
+// PCI Express device.
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCIE_DATA** PciExpData Double Pointer to the PCIE_DATA Structure (OPTIONAL)
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If Device is not PCI Express device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+// **PciExpData if not needed must be NULL;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtIsPciExpresss(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCIE_DATA **PciExpData OPTIONAL
+)
+{
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev) {
+ if(dev->PciExpress != NULL){
+ //if we have to update pointer
+ if(PciExpData != NULL){
+ *PciExpData = dev->PciExpress;
+ }
+ return EFI_SUCCESS;
+ } else return EFI_NOT_FOUND;
+ } else return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtIsPciX()
+//
+// Description: Checks if PciDeviceHandle, or PciIO passed belongs to
+// PCI Express device.
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCIX_DATA** PciXData Double Pointer to the PCIX_DATA Structure (OPTIONAL)
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If Device is not PCI X device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+// **PciXData if not needed must be NULL;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtIsPciX(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCIX_DATA **PciXData OPTIONAL
+)
+{
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev) {
+ if(dev->PciX != NULL){
+ //if we have to update pointer
+ if(PciXData != NULL){
+ *PciXData = dev->PciX;
+ }
+ return EFI_SUCCESS;
+ } else return EFI_NOT_FOUND;
+ } else return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtIsPciBrg()
+//
+// Description: Checks if PciDeviceHandle, or PciIO passed belongs to
+// PCI 2 PCI Bridge device.
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCI_BRG_EXT** PciBrgExt Double Pointer to the PCI_BRG_EXT Structure (OPTIONAL)
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If Device is not PCI 2 PCI Bridge device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+// **PciBrgExt if not needed must be NULL;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtIsPciBrg(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_BRG_EXT **BrgData OPTIONAL
+)
+{
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev) {
+ if(dev->Type == tPci2PciBrg){
+ //if we have to update pointer
+ if(BrgData != NULL){
+ *BrgData = (PCI_BRG_EXT*)(dev+1);
+ }
+ return EFI_SUCCESS;
+ } else return EFI_NOT_FOUND;
+ } else return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtIsCrdBrg()
+//
+// Description: Checks if PciDeviceHandle, or PciIO passed belongs to
+// PCI 2 Card Bridge device.
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCI_BRG_EXT** PciBrgExt Double Pointer to the PCI_BRG_EXT Structure (OPTIONAL)
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If Device is not PCI 2 Card Bridge device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+// **PciBrgExt if not needed must be NULL;
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtIsCrdBrg(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_BRG_EXT **BrgData OPTIONAL
+)
+{
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev) {
+ if(dev->Type == tPci2CrdBrg){
+ //if we have to update pointer
+ if(BrgData != NULL){
+ *BrgData = (PCI_BRG_EXT*)(dev+1);
+ }
+ return EFI_SUCCESS;
+ } else return EFI_NOT_FOUND;
+ } else return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtIsDevice()
+//
+// Description: Checks if PciDeviceHandle, or PciIO passed belongs to
+// Regular PCI device.
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If Device is not Regular PCI device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtIsDevice(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL
+)
+{
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev){
+ if(dev->Type == tPciDevice) return EFI_SUCCESS;
+ else return EFI_NOT_FOUND;
+ } else return EFI_INVALID_PARAMETER;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtClassCodes()
+//
+// Description: Returns device's Class code; Sub Class code; Programing Interface
+// and Revision Id information.
+//
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCI_DEV_CLASS* CassCodes Pointer to the PCI_DEV_CLASS to fill.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtClassCodes(
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_DEV_CLASS *CassCodes
+)
+{
+ PCI_DEV_INFO *dev=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev){
+ *CassCodes=dev->Class;
+ return EFI_SUCCESS;
+ } else return EFI_INVALID_PARAMETER;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtPicIrqRout()
+//
+// Description: Returns device's corresponded PIC IRQ routing entry from OEMPIR.INC
+// table created by the BUILD process.
+// If function returns EFI_SUCCESS the "PicIrqTblEntry" updated with corresponded PIC
+// IRQ Table entry pointer. "ParentDevices" == NULL and "EntryCount"==0
+// Function will return EFI_NOT_FOUND if there a no entry for the Device HANDLE passed.
+//
+// But it will return update the array of EFI_PCI_CONFIGURATION_ADDRESS structures with
+// PCI Addresses of parenti
+//
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCI_IRQ_PIC_ROUTE** PicIrqTblEntry Double pointer to the corresponded PCI_IRQ_PIC_ROUTE entry
+// EFI_PCI_CONFIGURATION_ADDRESS** ParentDevices Pointer to an array of parent Devices
+// for which was not found a valid PCI_IRQ_PIC_ROUTE entry.
+// UINTN* EntryCount Number of elements in an array above.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If no PIRQ entry was found for this device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtPicIrqRout (
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_IRQ_PIC_ROUTE **PicIrqTblEntry,
+ OUT EFI_PCI_CONFIGURATION_ADDRESS **ParentDevices,
+ OUT UINTN *EntryCount )
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=NULL;
+ PCI_DEV_INFO *parent;
+ T_ITEM_LIST ParentLst={0,0,NULL};
+ INTN i,j;
+ EFI_PCI_CONFIGURATION_ADDRESS *pa=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev != NULL ){
+ if( dev->PicIrqEntry != NULL ){
+ *PicIrqTblEntry = dev->PicIrqEntry;
+ ParentDevices = NULL;
+ EntryCount = 0;
+ return EFI_SUCCESS;
+ } else {
+ parent=dev;
+ do{
+ parent=parent->ParentBrg;
+ Status=AppendItemLst(&ParentLst, parent);
+ }while( (parent->PicIrqEntry == NULL) || (parent->Type != tPciRootBrg));
+
+ if( parent->PicIrqEntry != NULL ){
+ *PicIrqTblEntry=parent->PicIrqEntry;
+ //Create the array of addresses in order from Device which has IRQ endtry down to this Device parent
+ if(ParentLst.ItemCount){
+ pa=Malloc(sizeof(EFI_PCI_CONFIGURATION_ADDRESS)*(ParentLst.ItemCount));
+ for(i=(INTN)ParentLst.ItemCount-1, j=0; i<=0; i--,j++){
+ parent = (PCI_DEV_INFO*)ParentLst.Items[i];
+ pa[j] = parent->Address.Addr;
+ }
+ }
+ *ParentDevices=pa;
+ *EntryCount=ParentLst.ItemCount;
+ } else {
+ *PicIrqTblEntry=NULL;
+ ParentDevices=NULL;
+ EntryCount=0;
+ }
+ return EFI_NOT_FOUND;
+ }
+ }
+ else return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciExtApicIrqRout()
+//
+// Description: Returns device's corresponded APIC IRQ routing entry from MPPCIIRQ.INC
+// table created by the BUILD process.
+// If function returns EFI_SUCCESS the "ApicIrqTblEntry" updated with corresponded PIC
+// IRQ Table entry pointer. "ParentDevices" == NULL and "EntryCount"==0
+// Function will return EFI_NOT_FOUND if there a no entry for the Device HANDLE passed.
+//
+// But it will return update the array of EFI_PCI_CONFIGURATION_ADDRESS structures with
+// PCI Addresses of parenti
+//
+// Input:
+// AMI_PCI_EXT_PROTOCOL* This Pointer to the PciBusExtended protocol.
+// EFI_HANDLE PciDeviceHandle Handle of the PCI Device to check.
+// EFI_PCI_IO_PROTOCOL* PciIo Pointer to the instance of PCI IO Protocol (OPTIONAL)
+// PCI_IRQ_PIC_ROUTE** ApicIrqTblEntry Double pointer to the corresponded PCI_IRQ_PIC_ROUTE entry
+// EFI_PCI_CONFIGURATION_ADDRESS** ParentDevices Pointer to an array of parent Devices
+// for which was not found a valid PCI_IRQ_PIC_ROUTE entry.
+// UINTN* EntryCount Number of elements in an array above.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND If no PIRQ entry was found for this device.
+// EFI_INVALID_PARAMETER When Parameter passed is invalid.
+//
+// Note:
+// If PciDeviceHandle == NULL, PciIo must be valid.
+// If *PciIo == NULL PciDeviceHandle must be valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciExtApicIrqRout (
+ IN AMI_PCI_EXT_PROTOCOL *This,
+ IN EFI_HANDLE PciDeviceHandle,
+ IN EFI_PCI_IO_PROTOCOL *PciIo OPTIONAL,
+ OUT PCI_IRQ_APIC_ROUTE **ApicIrqTblEntry,
+ OUT EFI_PCI_CONFIGURATION_ADDRESS **ParentDevices,
+ OUT UINTN *EntryCount )
+{
+ EFI_STATUS Status;
+ PCI_DEV_INFO *dev=NULL;
+ PCI_DEV_INFO *parent;
+ T_ITEM_LIST ParentLst={0,0,NULL};
+ INTN i,j;
+ EFI_PCI_CONFIGURATION_ADDRESS *pa=NULL;
+//------------------------------------
+ dev=PciExtGetDevice(PciDeviceHandle, PciIo);
+
+ if(dev != NULL ){
+ if( dev->ApicIrqEntry != NULL ){
+ *ApicIrqTblEntry = dev->ApicIrqEntry;
+ ParentDevices = NULL;
+ EntryCount = 0;
+ return EFI_SUCCESS;
+ } else {
+ parent=dev;
+ do{
+ parent=parent->ParentBrg;
+ Status=AppendItemLst(&ParentLst, parent);
+ }while( (parent->ApicIrqEntry == NULL) || (parent->Type != tPciRootBrg));
+
+ if( parent->ApicIrqEntry != NULL ){
+ *ApicIrqTblEntry=parent->ApicIrqEntry;
+ //Create the array of addresses in order from Device which has IRQ endtry down to this Device parent
+ if(ParentLst.ItemCount){
+ pa=Malloc(sizeof(EFI_PCI_CONFIGURATION_ADDRESS)*(ParentLst.ItemCount));
+ for(i=(INTN)ParentLst.ItemCount-1, j=0; i<=0; i--,j++){
+ parent = (PCI_DEV_INFO*)ParentLst.Items[i];
+ pa[j] = parent->Address.Addr;
+ }
+ }
+ *ParentDevices=pa;
+ *EntryCount=ParentLst.ItemCount;
+ } else {
+ *ApicIrqTblEntry=NULL;
+ ParentDevices=NULL;
+ EntryCount=0;
+ }
+ return EFI_NOT_FOUND;
+ }
+ }
+ else return EFI_INVALID_PARAMETER;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PCI/PciBus.chm b/Core/EM/PCI/PciBus.chm
new file mode 100644
index 0000000..2acd504
--- /dev/null
+++ b/Core/EM/PCI/PciBus.chm
Binary files differ
diff --git a/Core/EM/PCI/PciBus.cif b/Core/EM/PCI/PciBus.cif
new file mode 100644
index 0000000..8546bd1
--- /dev/null
+++ b/Core/EM/PCI/PciBus.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "PciBus"
+ category = ModulePart
+ LocalRoot = "Core\EM\PCI\"
+ RefName = "PciBus"
+[files]
+"PciBus.sdl"
+"PciBus.mak"
+"PciBus.sd"
+"PciBus.uni"
+"PciBusSetup.c"
+"PciRootBridge.dxs"
+"PciPort.c"
+"PciSetup.h"
+"PciPort.h"
+"PciBus.chm"
+[parts]
+"PciBusIncludes"
+<endComponent>
diff --git a/Core/EM/PCI/PciBus.mak b/Core/EM/PCI/PciBus.mak
new file mode 100644
index 0000000..945fa2f
--- /dev/null
+++ b/Core/EM/PCI/PciBus.mak
@@ -0,0 +1,152 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/PciBus/PciBus.mak 13 4/05/11 11:08a Yakovlevs $
+#
+# $Revision: 13 $
+#
+# $Date: 4/05/11 11:08a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/PciBus/PciBus.mak $
+#
+# 13 4/05/11 11:08a Yakovlevs
+# [TAG] EIP38174
+# [Category] New Feature
+# [Description] Added generic support to handle
+# [Files] PciBus.c; PciHostBridge.c; PciBus.h; PciHostBridge.c;
+# PciPort.c;
+#
+# 12 1/28/11 2:58p Yakovlevs
+# [TAG] EIP43879
+# [Category] New Feature
+# [Description] Added PciPortOemGetOptRom() OEM Hook to override
+# content of the PCI Device Option ROM.
+# [Files] PciBus.c; PciPort.c; PciPort.h; PciBus.mak; PciBus.sdl
+#
+# 11 8/16/10 1:11p Yakovlevs
+# Added OEM_PCI_DEVICE_SET_ASPM for custom Aspm Programming.
+#
+# 10 9/22/09 6:01p Yakovlevs
+# 1. Added Definitions for OEM_PCI_PROGRAM_DEVICE_CALLBACK_LIST;
+# OEM_PCI_SKIP_DEVICE_CALLBACK_LIST and OEM_PCI_DEVICE_ATTRIBUTES_LIST to
+# support addingh porting hooks trough eLinks
+#
+# 9 4/28/09 3:49p Yakovlevs
+# Changes related to AmiBoardInfo protocol and Multiplatform support.
+#
+# 8 11/14/08 1:31p Yakovlevs
+# Added unconditionaly PciRoot it installs AMI Board Info Protocol
+#
+# 7 10/01/08 7:09p Yakovlevs
+# Updated AMI FUNC HEADER information.
+#
+# 6 9/25/08 11:45a Yakovlevs
+# Changes in build structure to support new features.
+#
+# 5 10/18/07 11:22a Felixp
+# PciPort.c added
+#
+# 4 8/22/07 6:56p Felixp
+# Exlude PciBusSetup.c from the list of files compiled during PciBus and
+# PciRootBridge build (set OBJECTS to blank string).
+#
+# 3 4/18/07 11:11p Felixp
+#
+# 2 4/12/07 3:53p Yakovlevs
+# Removed unused libraryes from module link process.
+#
+# 1 3/12/07 12:07p Yakovlevs
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PciBus.mak
+#
+# Description: Make file to build PciBus Driver
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : PciBus
+
+PciBus : $(BUILD_DIR)\PciBus.mak PciBusBin
+
+!IF "$(AMI_ROOT_BRIDGE_SUPPORT)"=="1"
+PciBus : PciRootBridgeBin
+!ENDIF
+
+$(BUILD_DIR)\PciBus.mak : $(PCIBUS_DIR)\$(@B).cif $(PCIBUS_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PCIBUS_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PciBusBin : $(AMIDXELIB) $(AMICSPLib) $(PCIBUSSRCLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PciBus.mak all\
+ MAKEFILE=$(PCIBUS_DIR)\PciBus.mak \
+ GUID=3C1DE39F-D207-408a-AACC-731CFB7F1DD7\
+ ENTRY_POINT=PciBusEntryPoint\
+ TYPE=BS_DRIVER DEPEX1= LIBRARIES=\
+ "CFLAGS=$(CFLAGS) /D\"OEM_PCI_PROGRAM_DEVICE_CALLBACK_LIST=$(OEM_PROGRAM_PCI_DEVICE)\" \
+ /D\"OEM_PCI_SKIP_DEVICE_CALLBACK_LIST=$(OEM_SKIP_PCI_DEVICE)\" \
+ /D\"OEM_PCI_DEVICE_SET_ASPM_CALLBACK_LIST=$(OEM_PCI_DEVICE_SET_ASPM)\" \
+ /D\"OEM_PCI_DEVICE_SET_LNK_SPEED_CALLBACK_LIST=$(OEM_PCI_DEVICE_SET_LNK_SPEED)\" \
+ /D\"OEM_PCI_DEVICE_GET_OPT_ROM_CALLBACK_LIST=$(OEM_PCI_DEVICE_GET_OPT_ROM)\" \
+ /D\"OEM_PCI_DEVICE_OUT_OF_RESOURCES_CALLBACK_LIST=$(OEM_PCI_DEVICE_OUT_OF_RESOURCES)\" \
+ /D\"OEM_PCI_DEVICE_ATTRIBUTE_CALLBACK_LIST=$(OEM_PCI_ATTRIBUTES)\"" \
+ "OBJECTS=$(BUILD_DIR)\$(PCIBUS_DIR)\PciPort.obj"\
+ COMPRESS=1\
+
+!IF "$(AMI_ROOT_BRIDGE_SUPPORT)"=="1"
+PciRootBridgeBin : $(AMIDXELIB) $(AMICSPLib) $(PCIBUSSRCLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PciBus.mak all\
+ NAME=PciRootBridge\
+ MAKEFILE=$(PCIBUS_DIR)\PciBus.mak \
+ GUID=80E66E0A-CCD1-43fa-A7B1-2D5EE0F13910 \
+ ENTRY_POINT=InitializePCIHostBridge \
+ DEPEX1=$(PCIBUS_DIR)\PciRootBridge.DXS \
+ TYPE=BS_DRIVER LIBRARIES= \
+ "OBJECTS=$(BUILD_DIR)\$(PCIBUS_DIR)\PciPort.obj"\
+ COMPRESS=1\
+!ENDIF
+
+#---------------------------------------------------------------------------
+# Create PCI Bus Setup Screens
+#---------------------------------------------------------------------------
+SetupSdbs : $(BUILD_DIR)\PciBus.mak PCIBUSSDB
+SetupBin : $(BUILD_DIR)\PciBusSetup.obj
+
+PCIBUSSDB :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PciBus.mak all\
+ TYPE=SDB NAME=PciBus MAKEFILE=$(BUILD_DIR)\PciBus.Mak STRING_CONSUMERS=$(PCIBUS_DIR)\PciBus.sd
+$(BUILD_DIR)\PciBusSetup.obj : $(PCIBUS_DIR)\PciBusSetup.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(PCIBUS_DIR)\PciBusSetup.c
+#---------------------------------------------------------------------------
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2007, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/PCI/PciBus.sd b/Core/EM/PCI/PciBus.sd
new file mode 100644
index 0000000..404482b
--- /dev/null
+++ b/Core/EM/PCI/PciBus.sd
@@ -0,0 +1,1067 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PciBus/PciBus.sd 22 9/10/12 12:54p Yakovlevs $
+//
+// $Revision: 22 $
+//
+// $Date: 9/10/12 12:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/PciBus/PciBus.sd $
+//
+// 22 9/10/12 12:54p Yakovlevs
+// [TAG] EIP93341
+// [Category] Improvement
+// [Description] Preserve PCI DEV/LNK/SLT control register in S3 resume
+// path.
+// [Files] PciBus.c PciBus.sd PciBus.uni PciSetup.h PciPort.c
+//
+// 21 2/27/12 6:39p Artems
+// EIP 83608: Added MANUFACTURING flag to setup controls
+//
+// 20 11/09/11 1:54p Yakovlevs
+// [TAG] EIP71380
+// [Category] New Feature
+// [Description] Core support for CSM opt-out feature
+// [Files] PciBus.c; PciPort.c; PciBus.sd; PciBus.uni; PciSetup.h;
+// PciBusSetup.c;
+//
+// 18 4/05/11 11:21a Yakovlevs
+// [TAG] EIP53475
+// [Category] New Feature
+// [Description] PCI Express 3.0 support added. And minor bug fix.
+// [Files] PciBus.c; PciHostBridge.c; PciBus.h; PciHostBridge.c;
+// PciPort.c;
+//
+// 17 1/20/11 3:13p Yakovlevs
+// [TAG] EIP48181
+// [Category] Improvement
+// [Description] Update the PciBus eModule to utilize Setup
+// Customization
+// [Files] PciBus.sd
+//
+// 16 12/08/10 3:18p Yakovlevs
+// Removed Setup Option "Selectable DeEmphasis" since it is HwInit Bit.
+//
+// 15 11/22/10 10:44a Yakovlevs
+// Removed STR_HORIZONTAL_D_LINE string since it creates problems with
+// reduced screen resolution.
+//
+// 14 10/01/10 12:27p Felixp
+// Link Training Defaults changed.
+//
+// 13 4/13/10 12:02p Yakovlevs
+// Changed Default ADPM settings to disable.
+//
+// 12 3/01/10 6:09p Yakovlevs
+// Pci Express V2.1 Support Added.
+//
+// 10 12/04/09 12:00p Felixp
+// UEFI 2.1 support.
+//
+// 9 3/23/09 4:57p Yakovlevs
+// Added generic support for PCI Express Hot-Plug.
+//
+// 8 10/16/08 6:13p Fasihm
+// Also added the MANUFACTURING flag to the setup questions.
+//
+// 7 9/25/08 11:47a Yakovlevs
+// Added Pci Bus Driver version display.
+//
+// 5 3/30/07 5:19p Robert
+// Updated Strings
+//
+// 4 3/30/07 2:57p Robert
+//
+// 3 3/14/07 2:04p Yakovlevs
+// Hode PciOption Rom Option from PCI Setup Screen
+//
+// 2 3/13/07 8:32p Yakovlevs
+//
+// 1 3/12/07 12:07p Yakovlevs
+//
+
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PCIBus.sd
+//
+// Description: PCI/PCIExpress/PCIX settings
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+/***********************************************************/
+/* Put NVRAM data definitions here.
+/* For example: UINT8 Data1;
+/* These definitions will be converted by the build process
+/* to a definitions of SETUP_DATA fields.
+/***********************************************************/
+#if ABOVE_4G_PCI_DECODE
+ UINT8 Above4gDecode; //[Disable]\ Enable
+#endif
+
+ //General PCI Settings: [] - default
+ UINT8 PciLatency; //[32]\ 64 \ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+ UINT8 VgaPallete; //[Disable]\ Enable
+ UINT8 PerrEnable; //[Disable]\ Enable
+ UINT8 SerrEnable; //[Disable]\ Enable
+
+#if PCI_X_SUPPORT
+ UINT8 PciXLatency; // 32 \[64]\ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+#endif
+
+#if PCI_EXPRESS_SUPPORT
+ //PCI Express Device Settings: [] - default
+ UINT8 RelaxedOrdering; //[Disable]\ Enable
+ UINT8 ExtTagField; //[Disable]\ Enable
+ UINT8 NoSnoop; // Disable \[Enable]
+ UINT8 MaxPayload; //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ UINT8 MaxReadRequest; //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ //PCI Express Link settings: [] - default
+ UINT8 AspmMode; //[Disable]\ Auto \ Force L0
+ UINT8 ExtendedSynch; //[Disable]\ Enable
+ UINT8 LnkTrRetry; //[Disable]\ 2 \ 3 \ 5
+ UINT16 LnkTrTimeout; //[1...1000] (Microseconds uS)
+ UINT8 LnkDisable; //[Keep ON == 0] / Disable ==1
+ UINT8 S3PciExpressScripts; //[Disable]\ Enable
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Gen2 Device Settings
+ UINT8 ComplTimeOut; //[Disable]\ Default \ SHORT \ LONG
+ UINT8 AriFwd; //[Disable]\ Enable
+ UINT8 AtomOpReq; //[Disable]\ Enable
+ UINT8 AtomOpEgressBlk; //[Disable]\ Enable
+ UINT8 IDOReq; //[Disable]\ Enable
+ UINT8 IDOCompl; //[Disable]\ Enable
+ UINT8 LtrReport; //[Disable]\ Enable
+ UINT8 E2ETlpPrBlk; //[Disable]\ Enable
+
+ //Gen2 Link Settings
+ UINT8 LnkSpeed; //[Auto]\ Forse to 5.0 GT/s \Force to 2.5 GT/s
+ UINT8 DeEmphasis; //[-3.5 dB]\ -6.0 dB
+ UINT8 ClockPm; //[Disable]\ Enable
+ UINT8 ComplSos; //[Disable]\ Enable
+ UINT8 HwAutoWidth; //[Enable]\ Disable LNK_CNT_REG #1
+ UINT8 HwAutoSpeed; //[Enable]\ Disable
+#endif
+
+#endif
+
+//Hotplug stuff.
+#if AMI_HOTPLUG_INIT_SUPPORT
+ UINT8 HotPlugEnable; // Disable \[Enable]
+ UINT8 BusPadd; // Disable \[1]\ 2 \ 3 \ 4 \ 5
+ //Following field stored in units of KB
+ UINT8 IoPadd; // Disable \[ 4K]\ 8K \ 16K \ 32K
+ //Following fields stored in units of MB
+ UINT8 Mmio32Padd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \128M
+ UINT8 Mmio32PfPadd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \128M
+ //for 512 and 1G 1 byte storege is not enough...
+ UINT16 Mmio64Padd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+ UINT16 Mmio64PfPadd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+#endif
+
+#endif //SETUP_DATA_DEFINITION
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+
+#ifdef CONTROL_DEFINITION
+
+#if ABOVE_4G_PCI_DECODE
+#define PCIBUS_ONEOF_ABOVE4GDECODE\
+ oneof varid = SETUP_DATA.Above4gDecode,\
+ prompt = STRING_TOKEN(STR_PCI_4G_PROMPT),\
+ help = STRING_TOKEN(STR_PCI_4G_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define PCIBUS_ONEOF_ABOVE4GDECODE
+#endif // #if ABOVE_4G_PCI_DECODE
+
+#define PCIBUS_ONEOF_PCILATENCY\
+ oneof varid = SETUP_DATA.PciLatency,\
+ prompt = STRING_TOKEN(STR_PCI_LATENCY_PROMPT),\
+ help = STRING_TOKEN(STR_PCI_LATENCY_HELP),\
+ option text = STRING_TOKEN(STR_PCI_32), value = 32, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_64), value = 64, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_96), value = 96, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_128), value = 128, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_160), value = 160, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_192), value = 192, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_224), value = 224, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_248), value = 248, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_VGAPALLETE\
+ oneof varid = SETUP_DATA.VgaPallete,\
+ prompt = STRING_TOKEN(STR_PCI_VGASNOOP_PROMPT),\
+ help = STRING_TOKEN(STR_PCI_VGASNOOP_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_PERRENABLE\
+ oneof varid = SETUP_DATA.PerrEnable,\
+ prompt = STRING_TOKEN(STR_PCI_PERR_PROMPT),\
+ help = STRING_TOKEN(STR_PCI_PERR_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_SERRENABLE\
+ oneof varid = SETUP_DATA.SerrEnable,\
+ prompt = STRING_TOKEN(STR_PCI_SERR_PROMPT),\
+ help = STRING_TOKEN(STR_PCI_SERR_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#if PCI_X_SUPPORT
+#define PCIBUS_ONEOF_PCIXLATENCY\
+ oneof varid = SETUP_DATA.PciXLatency,\
+ prompt = STRING_TOKEN(STR_PCIX_LATENCY_PROMPT),\
+ help = STRING_TOKEN(STR_PCI_LATENCY_HELP),\
+ option text = STRING_TOKEN(STR_PCI_32), value = 32, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_64), value = 64, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_96), value = 96, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_128), value = 128, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_160), value = 160, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_192), value = 192, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_224), value = 224, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_PCI_248), value = 248, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define PCIBUS_ONEOF_PCIXLATENCY
+#endif // #if PCI_X_SUPPORT
+
+#if PCI_EXPRESS_SUPPORT
+
+#define PCIBUS_ONEOF_RELAXEDORDERING\
+ oneof varid = SETUP_DATA.RelaxedOrdering,\
+ prompt = STRING_TOKEN(STR_PCIE_RELAXEDORDERING_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_RELAXEDORDERING_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_EXTTAGFIELD\
+ oneof varid = SETUP_DATA.ExtTagField,\
+ prompt = STRING_TOKEN(STR_PCIE_EXTTAGFLD_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_EXTTAGFLD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_NOSNOOP\
+ oneof varid = SETUP_DATA.NoSnoop,\
+ prompt = STRING_TOKEN(STR_PCIE_NOSNOOP_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_NOSNOOP_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_MAXPAYLOAD\
+ oneof varid = SETUP_DATA.MaxPayload,\
+ prompt = STRING_TOKEN(STR_PCIE_MAXPAYLOAD_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_MAXPAYLOAD_HELP),\
+ option text = STRING_TOKEN(STR_AUTO), value = 55, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP128), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP256), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP512), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP1024), value = 3, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP2048), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP4096), value = 5, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_MAXREADREQUEST\
+ oneof varid = SETUP_DATA.MaxReadRequest,\
+ prompt = STRING_TOKEN(STR_PCIE_MAXREADREQUEST_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_MAXREADREQUEST_HELP),\
+ option text = STRING_TOKEN(STR_AUTO), value = 55, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP128), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP256), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP512), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP1024), value = 3, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP2048), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_MP4096), value = 5, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_ASPMMODE\
+ oneof varid = SETUP_DATA.AspmMode,\
+ prompt = STRING_TOKEN(STR_PCIE_ASPM_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_ASPM_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_AUTO), value = 55, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_FORCE_L0), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_EXTENDEDSYNCH\
+ oneof varid = SETUP_DATA.ExtendedSynch,\
+ prompt = STRING_TOKEN(STR_PCIE_EXTD_SYNCH_PROMPT),\
+ help = STRING_TOKEN(STR_PCIE_EXTD_SYNCH_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_LNKTRRETRY\
+ oneof varid = SETUP_DATA.LnkTrRetry,\
+ prompt = STRING_TOKEN(STR_LNK_TR_RETRY_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_TR_RETRY_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_3), value = 3, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_5), value = 5, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_NUM_LNKTRTIMEOUT\
+ numeric varid = SETUP_DATA.LnkTrTimeout,\
+ prompt = STRING_TOKEN(STR_LNK_TR_TIMEOUT_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_TR_TIMEOUT_HELP),\
+ flags = RESET_REQUIRED,\
+ minimum = 10,\
+ maximum = 10000,\
+ step = 10,\
+ option text = STRING_TOKEN(STR_EMPTY), value = 100, flags = DEFAULT | MANUFACTURING;\
+ endnumeric;
+
+#define PCIBUS_ONEOF_LNKDISABLE\
+ oneof varid = SETUP_DATA.LnkDisable,\
+ prompt = STRING_TOKEN(STR_LNK_UNPOPULATED_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_UNPOPULATED_HELP),\
+ option text = STRING_TOKEN(STR_KEEP_ON), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLE), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_S3PCIEXPRESSSCRIPTS\
+ oneof varid = SETUP_DATA.S3PciExpressScripts,\
+ prompt = STRING_TOKEN(STR_DEV_S3_PCIE_SCRIPTS_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_S3_PCIE_SCRIPTS_HELP),\
+ option text = STRING_TOKEN(STR_ENABLED), value = 0xFF, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0x00, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+#define PCIBUS_ONEOF_COMPLTIMEOUT\
+ oneof varid = SETUP_DATA.ComplTimeOut,\
+ prompt = STRING_TOKEN(STR_DEV_COMPL_TIMEOUT_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_COMPL_TIMEOUT_HELP),\
+ option text = STRING_TOKEN(STR_DEFAULT), value = 0xFF, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_SHORT), value = 0x55, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_LONG), value = 0xAA, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLED),value = 0x00, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_ARIFWD\
+ oneof varid = SETUP_DATA.AriFwd,\
+ prompt = STRING_TOKEN(STR_DEV_ARI_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_ARI_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_ATOMOPREQ\
+ oneof varid = SETUP_DATA.AtomOpReq,\
+ prompt = STRING_TOKEN(STR_DEV_AOP_REQ_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_AOP_REQ_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_ATOMOPEGRESSBLK\
+ oneof varid = SETUP_DATA.AtomOpEgressBlk,\
+ prompt = STRING_TOKEN(STR_DEV_AOP_EGRESS_BLK_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_AOP_EGRESS_BLK_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_IDOREQ\
+ oneof varid = SETUP_DATA.IDOReq,\
+ prompt = STRING_TOKEN(STR_DEV_IDO_REQ_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_IDO_REQ_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_IDOCOMPL\
+ oneof varid = SETUP_DATA.IDOCompl,\
+ prompt = STRING_TOKEN(STR_DEV_IDO_COMPL_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_IDO_COMPL_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_LTRREPORT\
+ oneof varid = SETUP_DATA.LtrReport,\
+ prompt = STRING_TOKEN(STR_DEV_LTR_REPORT_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_LTR_REPORT_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_E2ETLPPRBLK\
+ oneof varid = SETUP_DATA.E2ETlpPrBlk,\
+ prompt = STRING_TOKEN(STR_DEV_E2E_TLP_BLK_PROMPT),\
+ help = STRING_TOKEN(STR_DEV_E2E_TLP_BLK_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+
+#define PCIBUS_ONEOF_LNKSPEED\
+ oneof varid = SETUP_DATA.LnkSpeed,\
+ prompt = STRING_TOKEN(STR_LNK_SPEED_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_SPEED_HELP),\
+ option text = STRING_TOKEN(STR_AUTO), value = 55, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2_5G), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_5_0G), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_CLOCKPM\
+ oneof varid = SETUP_DATA.ClockPm,\
+ prompt = STRING_TOKEN(STR_LNK_CLOCK_PM_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_CLOCK_PM_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_COMPLSOS\
+ oneof varid = SETUP_DATA.ComplSos,\
+ prompt = STRING_TOKEN(STR_LNK_COMPL_SOS_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_COMPL_SOS_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_HWAUTOWIDTH\
+ oneof varid = SETUP_DATA.HwAutoWidth,\
+ prompt = STRING_TOKEN(STR_LNK_HW_AUTO_WIDTH_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_HW_AUTO_WIDTH_HELP),\
+ option text = STRING_TOKEN(STR_ENABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_HWAUTOSPEED\
+ oneof varid = SETUP_DATA.HwAutoSpeed,\
+ prompt = STRING_TOKEN(STR_LNK_HW_AUTO_SPEED_PROMPT),\
+ help = STRING_TOKEN(STR_LNK_HW_AUTO_SPEED_HELP),\
+ option text = STRING_TOKEN(STR_ENABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_DISABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+
+#define PCIBUS_ONEOF_COMPLTIMEOUT
+#define PCIBUS_ONEOF_ARIFWD
+#define PCIBUS_ONEOF_ATOMOPREQ
+#define PCIBUS_ONEOF_ATOMOPEGRESSBLK
+#define PCIBUS_ONEOF_IDOREQ
+#define PCIBUS_ONEOF_IDOCOMPL
+#define PCIBUS_ONEOF_LTRREPORT
+#define PCIBUS_ONEOF_E2ETLPPRBLK
+#define PCIBUS_ONEOF_LNKSPEED
+#define PCIBUS_ONEOF_CLOCKPM
+#define PCIBUS_ONEOF_COMPLSOS
+#define PCIBUS_ONEOF_HWAUTOWIDTH
+#define PCIBUS_ONEOF_HWAUTOSPEED
+
+#endif//PCI_EXPRESS_GEN2_SUPPORT
+
+#else
+#define PCIBUS_ONEOF_RELAXEDORDERING
+#define PCIBUS_ONEOF_EXTTAGFIELD
+#define PCIBUS_ONEOF_NOSNOOP
+#define PCIBUS_ONEOF_MAXPAYLOAD
+#define PCIBUS_ONEOF_MAXREADREQUEST
+#define PCIBUS_ONEOF_ASPMMODE
+#define PCIBUS_ONEOF_EXTENDEDSYNCH
+#define PCIBUS_ONEOF_LNKTRRETRY
+#define PCIBUS_NUM_LNKTRTIMEOUT
+#define PCIBUS_ONEOF_LNKDISABLE
+#define PCIBUS_ONEOF_S3PCIEXPRESSSCRIPTS
+
+#endif // #if PCI_EXPRESS_SUPPORT
+
+#if AMI_HOTPLUG_INIT_SUPPORT
+#define PCIBUS_ONEOF_HOTPLUGENABLE\
+ oneof varid = SETUP_DATA.HotPlugEnable,\
+ prompt = STRING_TOKEN(STR_HOTPLUG_ENABLE_PROMPT),\
+ help = STRING_TOKEN(STR_HOTPLUG_ENABLE_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_BUSPADD\
+ oneof varid = SETUP_DATA.BusPadd,\
+ prompt = STRING_TOKEN(STR_BUS_PADD_PROMPT),\
+ help = STRING_TOKEN(STR_BUS_PADD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1), value = 1, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_3), value = 3, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_4), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_5), value = 5, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_IOPADD\
+ oneof varid = SETUP_DATA.IoPadd,\
+ prompt = STRING_TOKEN(STR_IO_PADD_PROMPT),\
+ help = STRING_TOKEN(STR_IO_PADD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_4K), value = 4, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_8K), value = 8, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_16K), value = 16, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_32K), value = 32, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_MMIO32PADD\
+ oneof varid = SETUP_DATA.Mmio32Padd,\
+ prompt = STRING_TOKEN(STR_MMIO32_PADD_PROMPT),\
+ help = STRING_TOKEN(STR_MMIO32_PADD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1M), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2M), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_4M), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_8M), value = 8, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_16M), value = 16, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_32M), value = 32, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_64M), value = 64, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_128M),value = 128, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_MMIO32PFPADD\
+ oneof varid = SETUP_DATA.Mmio32PfPadd,\
+ prompt = STRING_TOKEN(STR_MMIO32PF_PADD_PROMPT),\
+ help = STRING_TOKEN(STR_MMIO32PF_PADD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1M), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2M), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_4M), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_8M), value = 8, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_16M), value = 16, flags = DEFAULT | MANUFACTURING |RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_32M), value = 32, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_64M), value = 64, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_128M),value = 128, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_MMIO64PADD\
+ oneof varid = SETUP_DATA.Mmio64Padd,\
+ prompt = STRING_TOKEN(STR_MMIO64_PADD_PROMPT),\
+ help = STRING_TOKEN(STR_MMIO64_PADD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1M), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2M), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_4M), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_8M), value = 8, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_16M), value = 16, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_32M), value = 32, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_64M), value = 64, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_128M),value = 128, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_256M), value = 256, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_512M), value = 512, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1G), value = 1024, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define PCIBUS_ONEOF_MMIO64PFPADD\
+ oneof varid = SETUP_DATA.Mmio64PfPadd,\
+ prompt = STRING_TOKEN(STR_MMIO64PF_PADD_PROMPT),\
+ help = STRING_TOKEN(STR_MMIO64PF_PADD_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1M), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_2M), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_4M), value = 4, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_8M), value = 8, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_16M), value = 16, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_32M), value = 32, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_64M), value = 64, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_128M), value = 128, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_256M), value = 256, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_512M), value = 512, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_1G), value = 1024, flags = RESET_REQUIRED;\
+ endoneof;
+
+#else
+#define PCIBUS_ONEOF_HOTPLUGENABLE
+#define PCIBUS_ONEOF_BUSPADD
+#define PCIBUS_ONEOF_IOPADD
+#define PCIBUS_ONEOF_MMIO32PADD
+#define PCIBUS_ONEOF_MMIO32PFPADD
+#define PCIBUS_ONEOF_MMIO64PADD
+#define PCIBUS_ONEOF_MMIO64PFPADD
+#endif
+
+#endif //#ifdef CONTROL_DEFINITION
+
+#ifdef CONTROLS_WITH_DEFAULTS
+ // PCIBUS_FORM_PCI
+ PCIBUS_ONEOF_ABOVE4GDECODE
+ PCIBUS_ONEOF_PCILATENCY
+ PCIBUS_ONEOF_VGAPALLETE
+ PCIBUS_ONEOF_PERRENABLE
+ PCIBUS_ONEOF_SERRENABLE
+ PCIBUS_ONEOF_PCIXLATENCY
+
+ //PCIBUS_FORM_PCI_EXPRESS
+ PCIBUS_ONEOF_RELAXEDORDERING
+ PCIBUS_ONEOF_EXTTAGFIELD
+ PCIBUS_ONEOF_NOSNOOP
+ PCIBUS_ONEOF_MAXPAYLOAD
+ PCIBUS_ONEOF_MAXREADREQUEST
+ PCIBUS_ONEOF_ASPMMODE
+ PCIBUS_ONEOF_EXTENDEDSYNCH
+ PCIBUS_ONEOF_LNKTRRETRY
+ PCIBUS_NUM_LNKTRTIMEOUT
+ PCIBUS_ONEOF_LNKDISABLE
+ PCIBUS_ONEOF_S3PCIEXPRESSSCRIPTS
+
+ // PCIBUS_FORM_PCI_EXPRESS2
+#if PCI_EXPRESS_GEN2_SUPPORT
+ PCIBUS_ONEOF_COMPLTIMEOUT
+ PCIBUS_ONEOF_ARIFWD
+ PCIBUS_ONEOF_ATOMOPREQ
+ PCIBUS_ONEOF_ATOMOPEGRESSBLK
+ PCIBUS_ONEOF_IDOREQ
+ PCIBUS_ONEOF_IDOCOMPL
+ PCIBUS_ONEOF_LTRREPORT
+ PCIBUS_ONEOF_E2ETLPPRBLK
+ PCIBUS_ONEOF_LNKSPEED
+ PCIBUS_ONEOF_CLOCKPM
+ PCIBUS_ONEOF_COMPLSOS
+ PCIBUS_ONEOF_HWAUTOWIDTH
+ PCIBUS_ONEOF_HWAUTOSPEED
+#endif
+
+ // PCIBUS_FORM_PCIHP
+ PCIBUS_ONEOF_HOTPLUGENABLE
+ PCIBUS_ONEOF_BUSPADD
+ PCIBUS_ONEOF_IOPADD
+ PCIBUS_ONEOF_MMIO32PADD
+ PCIBUS_ONEOF_MMIO32PFPADD
+ PCIBUS_ONEOF_MMIO64PADD
+ PCIBUS_ONEOF_MMIO64PFPADD
+
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+
+#ifdef ADVANCED_FORM_SET
+
+ #ifndef SUPPRESS_GRAYOUT_ENDIF //old Core
+ #define SUPPRESS_GRAYOUT_ENDIF endif;
+ #endif
+
+ #ifdef FORM_SET_ITEM
+ // Define controls to be added to the main page of the formset
+ #endif
+
+ #ifdef FORM_SET_GOTO
+ // Define goto commands for the forms defined in this file
+ goto PCI_FORM_ID,
+ prompt = STRING_TOKEN(STR_PCI_FORM),
+ help = STRING_TOKEN(STR_PCI_FORM_HELP);
+ #endif
+
+
+#ifdef FORM_SET_FORM
+//
+// Define forms
+//
+
+//////////////////////////////////////////////////////////////
+//============================================================
+//Main PCI Form START
+//------------------------------------------------------------
+#ifndef PCIBUS_FORM_PCI
+#define PCIBUS_FORM_PCI
+//------------------------------------------------------------
+
+ form formid = AUTO_ID(PCI_FORM_ID),
+ title = STRING_TOKEN(STR_PCI_FORM);
+
+ //Display PCI Bus Driver Version.
+ text
+ help = STRING_TOKEN(STR_PCI_FORM_HELP),
+ text = STRING_TOKEN(STR_PCI_DRIVER_VER_PROMPT),
+ text = STRING_TOKEN(STR_PCI_DRIVER_VER),
+ flags = 0,
+ key = 0;
+
+ SEPARATOR
+
+#if ABOVE_4G_PCI_DECODE == 1
+ SEPARATOR
+ //Display PCI 64 bit Handling Subtitle
+ SUBTITLE(STRING_TOKEN(STR_PCI_64_SUB))
+// UINT8 Above4gDecode //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_ABOVE4GDECODE
+ endif;
+#endif
+
+
+ SEPARATOR
+
+ SUBTITLE(STRING_TOKEN(STR_PCI_SETTINGS))
+
+// UINT8 PciLatency; //[32]\ 64 \ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_PCILATENCY
+ endif;
+
+// UINT8 VgaPallete; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_VGAPALLETE
+ endif;
+
+// UINT8 PerrEnable //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_PERRENABLE
+ endif;
+
+// UINT8 SerrEnable //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_SERRENABLE
+ endif;
+
+
+#if PCI_X_SUPPORT
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_PCIX))
+// UINT8 PciXLatency; // 32 \[64]\ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_PCIXLATENCY
+ endif;
+#endif
+
+#if PCI_EXPRESS_SUPPORT
+
+ SEPARATOR
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ goto PCI_PCIE1_FORM_ID,
+ prompt = STRING_TOKEN(STR_PCI_PCIE1_FORM),
+ help = STRING_TOKEN(STR_PCI_PCIE1_FORM_HELP);
+ endif;
+
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+ SEPARATOR
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ goto PCI_PCIE2_FORM_ID,
+ prompt = STRING_TOKEN(STR_PCI_PCIE2_FORM),
+ help = STRING_TOKEN(STR_PCI_PCIE2_FORM_HELP);
+ endif;
+#endif
+
+
+#endif
+
+#if AMI_HOTPLUG_INIT_SUPPORT
+
+ SEPARATOR
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ goto PCI_HP_FORM_ID,
+ prompt = STRING_TOKEN(STR_PCI_HP_FORM),
+ help = STRING_TOKEN(STR_PCI_HP_FORM_HELP);
+ endif;
+
+#endif
+
+endform; // PCI_FORM_ID
+//------------------------------------------------------------
+#endif //PCIBUS_FORM_PCI
+//------------------------------------------------------------
+
+//------------------------------------------------------------
+//Main PCI Form END
+//============================================================
+
+//============================================================
+//PCI Express Form START
+//------------------------------------------------------------
+#if PCI_EXPRESS_SUPPORT
+
+#ifndef PCIBUS_FORM_PCI_EXPRESS
+#define PCIBUS_FORM_PCI_EXPRESS
+
+ // Define PCIe Settings Form
+ form formid = AUTO_ID(PCI_PCIE1_FORM_ID),
+ title = STRING_TOKEN(STR_PCI_PCIE1_FORM);
+
+//PCI Express Device Settings: [] - default
+ SUBTITLE(STRING_TOKEN(STR_PCIE_DEVICE))
+
+// UINT8 RelaxedOrdering; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_RELAXEDORDERING
+ endif;
+// UINT8 ExtTagField; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_EXTTAGFIELD
+ endif;
+
+// UINT8 NoSnoop; // Disable \[Enable]
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_NOSNOOP
+ endif;
+
+
+// UINT8 MaxPayload //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_MAXPAYLOAD
+ endif;
+
+
+// UINT8 MaxReadRequest //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_MAXREADREQUEST
+ endif;
+
+//PCI Express Link settings: [] - default
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_PCIE_LINK))
+// UINT8 AspmMode; //[Disabled]\ Auto \ Force L0
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_ASPMMODE
+ endif;
+
+ SUBTITLE(STRING_TOKEN(STR_PCIE_LINK_WARN3))
+ SUBTITLE(STRING_TOKEN(STR_PCIE_LINK_WARN4))
+
+
+// UINT8 ExtendedSynch //[Disable]\ Enable
+
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_EXTENDEDSYNCH
+ endif;
+
+ SEPARATOR
+// UINT8 LnkTrRetry; //[Disable]\ 2 \ 3 \ 5
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_LNKTRRETRY
+ endif;
+
+// UINT8 LnkTrTimeout; //[10...1000] uS
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_NUM_LNKTRTIMEOUT
+ endif;
+
+// UINT8 EmptyLnkDisable //[Enable]\ Disable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_LNKDISABLE
+ endif;
+// UINT8 S3PciExpressScripts; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_S3PCIEXPRESSSCRIPTS
+ endif;
+
+ endform; //PCI_PCIE2_FORM_ID
+#endif //PCIBUS_FORM_PCI_EXPRESS
+//------------------------------------------------------------
+//PCI Express Form END
+//============================================================
+
+
+#if PCI_EXPRESS_GEN2_SUPPORT == 1
+//============================================================
+//PCI Express Gen II Form START
+//------------------------------------------------------------
+
+#ifndef PCIBUS_FORM_PCI_EXPRESS2
+#define PCIBUS_FORM_PCI_EXPRESS2
+
+ form formid = AUTO_ID(PCI_PCIE2_FORM_ID),
+ title = STRING_TOKEN(STR_PCI_PCIE2_FORM);
+
+ SUBTITLE(STRING_TOKEN(STR_PCIE2_DEVICE))
+// UINT8 ComplTimeOut; //[Disable]\ Auto \ Default
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_COMPLTIMEOUT
+ endif;
+
+// UINT8 AriFwd; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_ARIFWD
+ endif;
+
+// UINT8 AtomOpReq; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_ATOMOPREQ
+ endif;
+
+// UINT8 AtomOpEgressBlk; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_ATOMOPEGRESSBLK
+ endif;
+
+// UINT8 IDOReq; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_IDOREQ
+ endif;
+
+// UINT8 IDOCompl; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_IDOCOMPL
+ endif;
+
+// UINT8 LtrReport; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_LTRREPORT
+ endif;
+
+
+// UINT8 E2ETlpPrBlk; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_E2ETLPPRBLK
+ endif;
+//============================================================
+
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_PCIE2_LINK))
+//Gen2 Link Settings
+// UINT8 LnkSpeed; //[Auto]\ Force to 2.5 GHz
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_LNKSPEED
+ endif;
+
+
+// UINT8 ComplSos; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_CLOCKPM
+ endif;
+
+
+// UINT8 ComplSos; //[Disable]\ Enable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_COMPLSOS
+ endif;
+
+// UINT8 HwAutoWidth; //[Enable]\ Disable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_HWAUTOWIDTH
+ endif;
+
+// UINT8 HwAutoSpeed; //[Enable]\ Disable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_HWAUTOSPEED
+ endif;
+ endform; //PCIBUS_FORM_PCI_EXPRESS2
+
+#endif//PCIBUS_FORM_PCI_EXPRESS2
+
+#endif//PCI_EXPRESS_GEN2_SUPPORT
+
+#endif//PCI_EXPRESS_SUPPORT
+//PCI Express Form END
+//-----------------------------------------------------------
+
+//-----------------------------------------------------------
+//Hotplug Form
+#if AMI_HOTPLUG_INIT_SUPPORT == 1
+ // Define HOTPLUG form
+
+#ifndef PCIBUS_FORM_PCIHP
+#define PCIBUS_FORM_PCIHP
+
+ form formid = AUTO_ID(PCI_HP_FORM_ID),
+ title = STRING_TOKEN(STR_PCI_HP_FORM);
+
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_PCI_HP_FORM))
+ SEPARATOR
+
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_HOTPLUGENABLE
+ endif;
+
+ SEPARATOR
+
+#if PCI_FIXED_BUS_ASSIGNMENT == 0
+ suppressif ideqval SETUP_DATA.HotPlugEnable == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_BUSPADD
+ SUPPRESS_GRAYOUT_ENDIF
+#endif
+
+ //UINT8 IoPadd; // Disable \[ 4K]\ 8K \ 16K \ 32K
+ suppressif ideqval SETUP_DATA.HotPlugEnable == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_IOPADD
+ SUPPRESS_GRAYOUT_ENDIF
+
+ //Following fields stored in units of MB
+ //UINT8 Mmio32Padd; // Disable \ 1M \ 2M \4M \ 8M \[16M]\ 32M \ 64M \128M
+ suppressif ideqval SETUP_DATA.HotPlugEnable == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_MMIO32PADD
+ SUPPRESS_GRAYOUT_ENDIF
+
+ //UINT8 Mmio32PfPadd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \128M
+ suppressif ideqval SETUP_DATA.HotPlugEnable == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_MMIO32PFPADD
+ SUPPRESS_GRAYOUT_ENDIF
+
+
+//-----------------------------------------------------------
+#if ABOVE_4G_PCI_DECODE == 1
+
+ //for 512 and 1G 1 byte storege is not enough...
+ //UINT16 Mmio64Padd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+ suppressif ideqval SETUP_DATA.HotPlugEnable == 0 OR
+ ideqval SETUP_DATA.Above4gDecode == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_MMIO64PADD
+ SUPPRESS_GRAYOUT_ENDIF
+
+ //UINT16 Mmio64PfPadd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+ suppressif ideqval SETUP_DATA.HotPlugEnable == 0 OR
+ ideqval SETUP_DATA.Above4gDecode == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ PCIBUS_ONEOF_MMIO64PFPADD
+ SUPPRESS_GRAYOUT_ENDIF
+
+#endif //ABOVE_4G_PCI_DECODE
+
+ endform; //PCI_HP_FORM_ID
+#endif // #ifndef PCIBUS_FORM_PCIHP
+
+#endif //HOTPLUG_SUPPORT
+//-----------------------------------------------------------
+
+//-----------------------------------------------------------
+#endif // FORM_SET_FORM
+
+//-----------------------------------------------------------
+#endif // ADVANCED_FORM_SET
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/PCI/PciBus.sdl b/Core/EM/PCI/PciBus.sdl
new file mode 100644
index 0000000..951bb78
--- /dev/null
+++ b/Core/EM/PCI/PciBus.sdl
@@ -0,0 +1,351 @@
+TOKEN
+ Name = "PciBus_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PciBus support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "AMI_ROOT_BRIDGE_SUPPORT"
+ Value = "1"
+ Help = "The switch to include/exclude AMI Native PCI Root Bridge Implementation.\Set this switch to 'OFF' when using 3rd party PCI Root Bridgr Driver."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AMI_HOTPLUG_INIT_SUPPORT"
+ Value = "0"
+ Help = "The switch to include/exclude AMI Root Hotplug Controller Initialization Protocol automatic creation.\Set this switch to 'OFF' when using 3rd party Root Hotplug Controller Initialization Protocol Driver."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "AMI_ROOT_BRIDGE_SUPPORT" "=" "1"
+ Token = "PCI_EXPRESS_SUPPORT" "=" "1"
+ Token = "HOTPLUG_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PCI_BUS_MAJOR_VER"
+ Value = "02"
+ Help = "PCI BUS Module Major Version Number.\ DO NOT CHANGE THIS VALUE"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "PCI_BUS_MINOR_VER"
+ Value = "05"
+ Help = "PCI BUS Module Minor Version Number.\ DO NOT CHANGE THIS VALUE"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "PCI_BUS_REVISION"
+ Value = "02"
+ Help = "PCI BUS Module Major Version Number.\ DO NOT CHANGE THIS VALUE"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "PCI_BUS_VER_COMBINED"
+ Value = "$(PCI_BUS_MAJOR_VER)*100+ $(PCI_BUS_MINOR_VER)*10+$(PCI_BUS_REVISION)"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "HOTPLUG_SUPPORT"
+ Value = "0"
+ Help = "Enables / Disables Pci Bus Driver Native PCI Hotplug support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_EXPRESS_SUPPORT"
+ Value = "1"
+ Help = "Enables / Disables Pci Bus Driver Native PCI Express support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_EXPRESS_GEN2_SUPPORT"
+ Value = "1"
+ Help = "Enables / Disables Pci Bus Driver Native PCI Express Gen2 support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "PCI_EXPRESS_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PCI_EXPRESS_GEN3_SUPPORT"
+ Value = "1"
+ Help = "Enables / Disables Pci Bus Driver Native PCI Express Gen3 support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "PCI_EXPRESS_SUPPORT" "=" "1"
+ Token = "PCI_EXPRESS_GEN2_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PCI_X_SUPPORT"
+ Value = "0"
+ Help = "Enables / Disables Pci Bus Driver Native PCI-X support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_FIXED_BUS_ASSIGNMENT"
+ Value = "0"
+ Help = "Forces PCI Bus driver try to assign buses \according to the settings in Veb PCI Wizard"
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "On/Off"
+End
+
+TOKEN
+ Name = "PCI_DEV_REVERSE_SCAN_ORDER"
+ Value = "0"
+ Help = "Forces PCI Bus driver to scan PCI devices on the bus in opposite order.\If set to ON scan from Dev 31 down to 0.\If Set to OFF scan from Dev 0 up to 31."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "On/Off"
+End
+
+TOKEN
+ Name = "PCI_SCAN_FULL_BUS_RANGE"
+ Value = "0"
+ Help = "Forces PCI Bus driver Scan ALL PCI Buses in the\Bus Range provided by the Root Bridge driver.\If disabled will scan only consecutive PCI Buses\spawn buy the Root Bridge and save some boot \time on scanning nonexistent buses."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "On/Off"
+End
+
+TOKEN
+ Name = "PCI_4K_RESOURCE_ALIGNMENT"
+ Value = "1"
+ Help = "Forces PCI Bus driver to allocate at least 4K \resource buffer for each resource request lesser \than 4K."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "On/Off"
+End
+
+TOKEN
+ Name = "SRIOV_SUPPORT"
+ Value = "0"
+ Help = "Enables Single Root IO Virtualization (SRIOV) Support."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "On/Off"
+ Token = "PCI_EXPRESS_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PCI_DEVICE_IO_RESOURCE_THRESHOLD"
+ Value = "0xFFFF"
+ Help = "Forces PCI Bus driver to disable Device if it's IO resource request exceeds this value"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "Up to 64K"
+End
+
+TOKEN
+ Name = "PCI_DEVICE_32BIT_RESOURCE_THRESHOLD"
+ Value = "0xFFFFFFFF"
+ Help = "Forces PCI Bus driver to disable Device if it's 32bit resource request exceeds this value"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "Up to 4G"
+End
+
+TOKEN
+ Name = "PCI_DEVICE_64BIT_RESOURCE_THRESHOLD"
+ Value = "0x3FFFFFFFF"
+ Help = "Forces PCI Bus driver to disable Device if it's 64bit resource request exceeds this value"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "Up to 16G"
+End
+
+TOKEN
+ Name = "ABOVE_4G_PCI_DECODE"
+ Value = "0"
+ Help = "Tells if Chipset supports decoding of PCI\resources in Above 4G Address Space.\Sets EFI_PCI_HOST_BRIDGE_MEM64_DECODE in Allocation Attributes."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "ON or OFF"
+End
+
+TOKEN
+ Name = "COMBINE_MEM_PMEM"
+ Value = "0"
+ Help = "Tells if Chipset correctly supports PF MMIO\if set PF MMIO will be decoded through the same resource\window as NONE PF MMIO. PF MEM BASE and PF MEM LIMIT register pare will not be used."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "ON or OFF. Default is OFF!"
+End
+
+TOKEN
+ Name = "PCI_MMIO_RES_TOP_ALLIGN"
+ Value = "0"
+ Help = "Tells what resource allocation rule to use.\ OFF - Biggest resource alligned to the bottom of the window,\ ON - to the TOP."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "ON or OFF. Default is OFF!"
+End
+
+TOKEN
+ Name = "PCI_AMI_COMBINE_MEM_PMEM32"
+ Value = "0"
+ Help = "Tells to map 32 bit sized PF MMIO BARs trough NON PF MMIO Bridge registers."
+ TokenType = Boolean
+ TargetH = Yes
+ Range = "ON or OFF. Default is OFF!"
+End
+
+TOKEN
+ Name = "PCI_T_RST"
+ Value = "1000"
+ Help = "Defines duration of SEC_BUS_RESET signal assertion in nS"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_T_RST_RECOVERY"
+ Value = "100000"
+ Help = "Defines duration of RESET_RECOVERY after SEC_BUS_RESETsignal DE-assertion in nS"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEBS"
+ Value = "$(PCIEX_BASE_ADDRESS)"
+ Help = "Pci Express Base Aliase to use in PCIeAccess.ASL"
+ TokenType = Integer
+ TargetASL = Yes
+ Token = "AMI_ROOT_BRIDGE_SUPPORT" "=" "1"
+ Token = "PCI_EXPRESS_SUPPORT" "=" "1"
+ Token = "HOTPLUG_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PCIBOARDLIB"
+ Value = "$(BUILD_DIR)\PciBoard.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "PCIBUS_DIR"
+End
+
+MODULE
+ Help = "Includes PciBus.mak to Project"
+ File = "PciBus.mak"
+End
+
+ELINK
+ Name = "$(PCIBUS_DIR)\PciBus.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 0
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PciBus.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InitPciBusStrings,"
+ Parent = "SetupStringInit"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PciBus.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PciRootBridge.ffs"
+ Parent = "FV_MAIN"
+ Token = "AMI_ROOT_BRIDGE_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PCIBUSSRCLIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(PCIBUS_DIR)\PciBusSrc$(ARCH).lib"
+ Parent = "PCIBUSSRCLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OEM_SKIP_PCI_DEVICE"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_PROGRAM_PCI_DEVICE"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_PCI_DEVICE_SET_ASPM"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_PCI_DEVICE_SET_LNK_SPEED"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_PCI_DEVICE_GET_OPT_ROM"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_PCI_ATTRIBUTES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OEM_PCI_DEVICE_OUT_OF_RESOURCES"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/EM/PCI/PciBus.uni b/Core/EM/PCI/PciBus.uni
new file mode 100644
index 0000000..a7fa8ee
--- /dev/null
+++ b/Core/EM/PCI/PciBus.uni
Binary files differ
diff --git a/Core/EM/PCI/PciBusSetup.c b/Core/EM/PCI/PciBusSetup.c
new file mode 100644
index 0000000..8f44c20
--- /dev/null
+++ b/Core/EM/PCI/PciBusSetup.c
@@ -0,0 +1,97 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PciBus/PciBusSetup.c 2 9/25/08 11:54a Yakovlevs $
+//
+// $Revision: 2 $
+//
+// $Date: 9/25/08 11:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/PciBus/PciBusSetup.c $
+//
+// 2 9/25/08 11:54a Yakovlevs
+// Added PciBus Driver version display and Screen update routines.
+//
+// 1 3/12/07 12:07p Yakovlevs
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: PciBusSetup.c
+//
+// Description: Pci Bus Setup Routines
+//
+// NOTE: Use this hook to dynamically change PCI BUS Driver Setup screen
+// Strings.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include <Protocol\PciIo.h>
+#include <Token.h>
+
+// Function Definitions
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitBoardStrings
+//
+// Description: This function initializes the board related setup option values
+//
+// Input: HiiHandle Handle to HII database
+// Class Indicates the setup class
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InitPciBusStrings(
+ EFI_HII_HANDLE HiiHandle,
+ UINT16 Class
+)
+{
+ if(Class == ADVANCED_FORM_SET_CLASS){
+ InitString(HiiHandle, STRING_TOKEN(STR_PCI_DRIVER_VER), L"V %d.%02d.%02d",
+ PCI_BUS_MAJOR_VER, PCI_BUS_MINOR_VER, PCI_BUS_REVISION);
+ }
+ return;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PCI/PciBusSrc.chm b/Core/EM/PCI/PciBusSrc.chm
new file mode 100644
index 0000000..3c64f7c
--- /dev/null
+++ b/Core/EM/PCI/PciBusSrc.chm
Binary files differ
diff --git a/Core/EM/PCI/PciBusSrc.cif b/Core/EM/PCI/PciBusSrc.cif
new file mode 100644
index 0000000..53f1371
--- /dev/null
+++ b/Core/EM/PCI/PciBusSrc.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "PciBus Sources"
+ category = ModulePart
+ LocalRoot = "Core\EM\PCI\"
+ RefName = "PciBusSrc"
+[files]
+"PciBusSrc.chm"
+"PciBusSrc.sdl"
+"PciBusSrc.mak"
+"PciBus.c"
+"PciHostBridge.c"
+"DeviceIo.c"
+<endComponent>
diff --git a/Core/EM/PCI/PciBusSrc.mak b/Core/EM/PCI/PciBusSrc.mak
new file mode 100644
index 0000000..0842d12
--- /dev/null
+++ b/Core/EM/PCI/PciBusSrc.mak
@@ -0,0 +1,82 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/PciBus/PciBusSrc.mak 5 1/13/10 3:25p Felixp $
+#
+# $Revision: 5 $
+#
+# $Date: 1/13/10 3:25p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/PciBus/PciBusSrc.mak $
+#
+# 5 1/13/10 3:25p Felixp
+# Dependency from token.h is added
+#
+# 4 4/28/09 5:51p Yakovlevs
+#
+# 3 11/14/08 1:16p Yakovlevs
+# Changed the way PciRootBridge Module gets build.
+#
+# 2 10/01/08 7:12p Yakovlevs
+# Updated AMI FUNC HEADER information
+#
+# 1 3/12/07 12:02p Yakovlevs
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PsiBusSrc.mak
+#
+# Description: Make file to build PciBus Driver Sources.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+PCIBUS_SOURCE_OBJECTS=\
+$(BUILD_DIR)\$(PCIBUS_DIR)\PciBus.obj\
+!IF "$(AMI_ROOT_BRIDGE_SUPPORT)"=="1"
+$(BUILD_DIR)\$(PCIBUS_DIR)\PciHostBridge.obj\
+$(BUILD_DIR)\$(PCIBUS_DIR)\DeviceIo.obj\
+!ENDIF
+
+$(PCIBUSSRCLIB) : PciBusSrc
+
+PciBusSrc : $(BUILD_DIR)\PciBusSrc.mak PciBusSrcBin
+
+$(BUILD_DIR)\PciBusSrc.mak : $(PCIBUS_DIR)\$(@B).cif $(PCIBUS_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PCIBUS_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+PciBusSrcBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PciBusSrc.mak all\
+ MAKEFILE=$(PCIBUS_DIR)\PciBusSrc.mak\
+ "OBJECTS=$(PCIBUS_SOURCE_OBJECTS)"\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=LIBRARY
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/PCI/PciBusSrc.sdl b/Core/EM/PCI/PciBusSrc.sdl
new file mode 100644
index 0000000..8d50c1f
--- /dev/null
+++ b/Core/EM/PCI/PciBusSrc.sdl
@@ -0,0 +1,37 @@
+TOKEN
+ Name = "PciBusSrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable PciBusSrs support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "PCI_BUS_DEBUG_MESSAGES"
+ Value = "0"
+ Help = "A switch to enable PciBus Driver Debug messages over Serial Port."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_CODE" "=" "1"
+End
+
+TOKEN
+ Name = "PCI_BUS_SKIP_BRG_RECURSIVELY"
+ Value = "0"
+ Help = "A switch to Disable enumeration for all Bridge children if bridge set to be skipped from enumeration."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+MODULE
+ Help = "Includes PciBusSrs.mak to Project"
+ File = "PciBusSrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PciBusSrc.lib"
+ Parent = "$(PCIBUS_DIR)\PciBusSrc$(ARCH).lib"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/EM/PCI/PciHostBridge.c b/Core/EM/PCI/PciHostBridge.c
new file mode 100644
index 0000000..873101a
--- /dev/null
+++ b/Core/EM/PCI/PciHostBridge.c
@@ -0,0 +1,3814 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/PciBus/PciHostBridge.c 48 9/10/12 12:49p Yakovlevs $
+//
+// $Revision: 48 $
+//
+// $Date: 9/10/12 12:49p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/PciBus/PciHostBridge.c $
+//
+// 48 9/10/12 12:49p Yakovlevs
+// Minor changes fix for multi host system
+//
+// 47 7/17/12 1:48p Yakovlevs
+//
+// 45 7/16/12 3:10p Yakovlevs
+// [TAG] EIP90378
+// [Category] Improvement
+// [Description] Pci Root bridge driver should be able to access MMIO
+// above 4G
+// [Files] PciHostBridge.c
+//
+// 44 6/26/12 6:24p Yakovlevs
+// [TAG] EIP90378
+// [Category] Improvement
+// [Description] Pci Root bridge driver should be able to access MMIO
+// above 4G
+// [Files] PciHostBridge.c
+//
+// 43 5/22/12 4:50p Yakovlevs
+// Removing wrong comment
+//
+// 42 5/01/12 5:05p Yakovlevs
+// [TAG] EIP84986
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Yellow mark issue in windows device manager on
+// PCIe slots if only 2 CPU for potter city platform.
+// [RootCause] For multy root system where root socets partialy
+// populated SDL data interfered with
+// Actual Hardware configuration.
+// [Solution] Allow control flow keep going when certain
+// ERROR_STATUS received.
+// [Files] PciBus.c; PciHostBridge.c
+//
+// 41 2/27/12 4:47p Yakovlevs
+//
+// 40 11/23/11 11:08a Yakovlevs
+// [TAG] EIP76109
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] VIA VX900 / VX11 CopyMem issue
+// [RootCause] When Src and Dst buffers overlaps
+// size of copy operation was determined incorrectly.
+// [Solution] Added additional cases with negative increments
+// [Files] PciHostBridge.c
+//
+// 39 11/10/11 12:26p Yakovlevs
+// [TAG] EIP72122
+// [Category] Improvement
+// [Description] If system uses UEFI GOP driver, then BIOS does not
+// report legacy VGA resources to ACPI.
+//
+// [Files] PciHostBridge.c
+//
+// 38 8/30/11 2:27p Yakovlevs
+// [TAG] EIP68120
+// [Category] Bug Fix
+// [Symptom] When new PCIe card be plugged, It hangs at 0x94 before
+// adjusting new memory ceiling to nvram with CORE4651.
+// [RootCause] AdjustMmioOverlap() was not called if builtin allocation
+// function returned EFI_ERROR.
+// [Solution] Reorganize code to call this function before returning
+// ERROR Status.
+// [Files] PciHostBridge.c
+//
+// 37 8/02/11 4:13p Yakovlevs
+// [TAG] EIP66216
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Hotplug resource padding not working for ROOT bridges other
+// than 0
+// [RootCause] Hot plug slots was incorrectly associated alvays withthe
+// RootBridge #0
+// [Solution] Changed algorithm to beter distinguish between Root
+// Bridges. Added debug messagers to monitor HPC_LOCATION_DATA.
+// [Files] PciBus.c; PciHostBridge.c.
+//
+// 36 7/08/11 5:00p Yakovlevs
+// [TAG] EIP64414
+// [Category] Improvement
+// [Description] During PCIOUTOF RESOURCE Condition,resource freeing is
+// not done
+// [Files] PciHostBridge.c
+//
+// 35 6/28/11 5:29p Yakovlevs
+// [TAG] EIP 60123
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Resource padding is not functional for PCIe hot-plug.
+// [RootCause] In hot plug function was missed changes in BusXlat
+// Structure.
+// [Solution] Xlat header gets incremented based on AMI_BOARD_INFO
+// driver wersion.
+// [Files] PciHostBridge.c
+//
+// 34 5/04/11 6:15p Yakovlevs
+// Fixed potential issue with EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE
+// attribute some drivers may set.
+//
+// 33 4/05/11 11:40a Yakovlevs
+// [TAG] EIP 38174
+// [Category] New Feature
+// [Description] Generic support to handle PCI OUT OF RESOURDCES added.
+// [Files] PciBus.c; PciHostBridge.c;
+//
+// 32 1/20/11 3:07p Yakovlevs
+// [TAG] EIP45278
+// [Category] Improvement
+// [Description] Added PCI_MMIO_RES_TOP_ALLIGN token to control Resource
+// allocation algorithm selection.
+// [Files] PciBus.c; PciHostBridge.c; PciBus.sdl.
+//
+// 31 1/13/11 1:30p Yakovlevs
+//
+// 30 1/13/11 1:28p Yakovlevs
+// [TAG] EIP45278
+// [Category] Improvement
+// [Description] Changed default resource allocation algorithm to work
+// more efficiently.
+// [Files] PciBus.c; PciHostBridge.c
+//
+// 28 8/23/10 12:29p Yakovlevs
+// Fixed issue with incorrect settings COMPATIBILITY ATTRIBUTES was
+// missing Legacy VGA_ATTRIBUTES.
+//
+// 27 8/16/10 1:07p Yakovlevs
+// Updated ClaimMmioResources to use MMIO resources as-is if AllocType is
+// set to EfiGcdAllocateAddress. For this chipset, each root bridge is
+// programmed with base and limit values for 32bit and 64bit MMIO. The
+// root bridge will only decode addresses within these ranges. For this
+// reason, the Base and Limit values passed to the PCI Bus driver should
+// be used as-is and not modified.
+//
+// 26 3/01/10 6:18p Yakovlevs
+// Generic Multi-ROOT Support Added.
+//
+// 25 9/22/09 6:10p Yakovlevs
+// 3. Generic support for multiple root bridges resources reporting to
+// ACPI DSDT Root Bridge Object (EIP 23548 Support MMIO allocation above
+// 4GB, if devices are capable)
+//
+// 24 8/21/09 4:25p Yakovlevs
+// Added Print out Message in DEBUG_MODE with PCI BUS Driver Version.
+// Added Initialization of ImageHandle field in Host Bridge and Root
+// Bridge Structures. New PciHostBridge.h required.
+//
+// 23 4/28/09 5:50p Yakovlevs
+// Ami Board Info Protocol moved into separate Core\AmiBoardInfo
+// subcomponent.
+//
+// 22 3/27/09 11:48a Yakovlevs
+//
+// 21 3/23/09 2:27p Yakovlevs
+// ADDED support for PCI Root HPC INit Protocol generation based on AMI
+// SDL output.
+//
+// 20 1/30/09 1:01p Yakovlevs
+// Changed gPciHost to gPciRbHost to avoid name collision gPCiHost
+// variable name been differently used in PciBus.c
+//
+// 19 11/21/08 7:01p Yakovlevs
+//
+// 18 11/14/08 3:34p Yakovlevs
+// Removed EFI_DEADLOOP() used for debug
+//
+// 17 11/14/08 1:28p Yakovlevs
+// Implemented AMI Board Info Protocol which has *.inc OUTPUTs generated
+// by AMISDL tool. To keep it in one place and Make PciBus Driver use it.
+//
+// 16 11/03/08 2:35p Yakovlevs
+//
+// 15 11/03/08 2:33p Yakovlevs
+// Fixed EIP 17068: AdjustMmioOverlap() has to be called each boot.
+//
+// 14 10/01/08 7:12p Yakovlevs
+// Updated AMI FUNC HEADER information
+//
+// 13 9/24/08 6:08p Yakovlevs
+// New features added. Multy host support using VeB wizard. No initial
+// porting required.
+//
+// 12 4/29/08 6:56p Yakovlevs
+// Added mechanism to suppress PCI BUs driver debug messages(Latest
+// PciBus.sdl and PciBus.h required).
+//
+// 11 2/19/08 3:38p Felixp
+//
+// 10 2/13/08 1:02p Yakovlevs
+// Fixed issue with incorrect usage of GCD AllocateXX services.
+//
+// 9 10/23/07 5:30p Felixp
+// VC8 warnings fixed
+//
+// 8 8/07/07 2:45p Felixp
+// Additional Status Codes added
+//
+// 7 4/19/07 12:59p Felixp
+// Added Chipset specific call to set RB Attributes
+//
+// 5 4/17/07 11:55a Yakovlevs
+//
+// 4 4/17/07 11:19a Yakovlevs
+//
+// 3 4/17/07 11:18a Yakovlevs
+// Added Chipset specific call to set RB Attributes
+//
+// 2 4/13/07 6:23p Yakovlevs
+// make use of LibGetDxeSvcTbl() instead of manualy getting the DXE Svc
+// Tbl pointer.
+//
+// 1 3/12/07 12:02p Yakovlevs
+//
+// 9 12/28/06 7:20p Yakovlevs
+//
+// 8 12/19/06 12:07p Yakovlevs
+// PciRb->Map; Unmap implementation fixes
+//
+// 7 10/24/06 12:18p Yakovlevs
+// Removed EFI_MEMORY_RUNTIME attribute from PCI BUS resource request.
+//
+// 6 9/20/06 4:47p Felixp
+// x64 warnings fixed
+//
+// 5 6/01/06 12:17p Yakovlevs
+// Handling of memceil logic added.
+//
+// 4 5/23/06 12:59a Felixp
+// Bug fix in HbResAllocStartBusEnumeration - invalid error condition
+// check
+//
+// 3 5/19/06 10:51p Felixp
+// Device Path code updated to use NEXT_NODE/NODE_LENGTH/SET_NODE_LENGTH
+// macros to remove direct access to the Length field
+//
+// 2 4/07/06 2:33p Felixp
+// Bug fix in resource allocation (AllocateResources): Attributes for
+// Prefetchable memory changed from WB to WT
+//
+// 1 4/03/06 5:32p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciHostBridge.c
+//
+// Description: AMI's Native Root Bridge Protocol Implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <PciHostBridge.h>
+#include <Protocol\DevicePath.h>
+#include <AmiCspLib.h>
+#include "PciPort.h"
+#include "PciSetup.h"
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gAmiBoardProtocol
+//
+// Description: Ami Board Info Protocol Instance.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+AMI_BOARD_INFO_PROTOCOL *gAmiBoardInfoProtocol=NULL;
+
+
+
+//**********************************************************************
+//Global Vars and Constants been used
+//**********************************************************************
+
+//GUIDs
+EFI_GUID gHbResAllocProtocolGuid=EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL_GUID;
+EFI_GUID gRbIoProtocolGuid=EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+EFI_GUID gDevPathProtocolGuid=EFI_DEVICE_PATH_PROTOCOL_GUID;
+EFI_GUID gDeviceIoProtocolGuid=DEVICE_IO_PROTOCOL;
+EFI_GUID gAmiBoardInfoGuid=AMI_BOARD_INFO_PROTOCOL_GUID;
+
+#if AMI_HOTPLUG_INIT_SUPPORT == 1
+EFI_GUID gHotPlugInitProtocolGuid=EFI_PCI_HOT_PLUG_INIT_PROTOCOL_GUID;
+#endif
+
+
+
+//**********************************************************************
+//Variables
+
+T_ITEM_LIST gRootBusDb={0,0,NULL};
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: gPciHost
+//
+// Description: Array of PCI Host Bridge Data Sructures.
+// Initial data point for PCI Subsystem.
+//
+// Notes: See PCI_HOST_BRG_DATA. Number of elements in gPciHost[] array
+// defined by NB_NUMBER_OF_HOST_BRG in NB.sdl
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+PCI_HOST_BRG_DATA gPciRbHost[NB_NUMBER_OF_HOST_BRG];
+
+//TODO//TODO //TODO //TODO //TODO
+//Change this to reference VeB output EIP 24469
+//TEMP Hardcoding of ASL RB Device Object NAME
+#if AMI_BOARD_VER_COMBINED < 100
+CHAR8 *RbAslName[]={"PCI0","PCFF"};
+#endif
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: *gPciSetupData; PciSetupDataBuffer
+//
+// Description: Global Setup Variable to get the setup settings pointer.
+//
+// Notes: PCI_SETUP_DATA
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+PCI_SETUP_DATA gRbSetupData;
+
+UINT64 TmpBot[raMaxRes]={0,0,0,0};
+UINT64 TmpTop[raMaxRes]={0,0,0,0};
+
+//**********************************************************************
+//Function Prototypes needed forward declaration
+//**********************************************************************
+EFI_STATUS ConvertMemoryMap(EFI_HANDLE ImgHandle, EFI_HANDLE CntrHandle OPTIONAL);
+EFI_STATUS CreateRootBusData();
+EFI_STATUS HpcInitProtocol(PCI_HOST_BRG_DATA *HostBrg);
+BOOLEAN IsPowerOfTwo(UINT64 Value);
+VOID RbReadyToBoot(IN EFI_EVENT Event, IN VOID *Context);
+
+
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+//PCI Root Bridge Driver Entry Point
+//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializePCIHostBridge()
+//
+// Description: This function is the entry point for PCI Root Bridge Driver.
+// Since PCI Root Bridge Driver follows EFI 1.1 driver model in it's entry
+// point it will initialize some global data and install
+// EFI_DRIVER_BINDING_PROTOCOL.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS When everything is going on fine!
+// EFI_NOT_FOUND When something required is not found!
+// EFI_DEVICE_ERROR When the device is not responding!
+//
+// Notes:
+// Entry Points are used to locate or install protocol interfaces and
+// notification events.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitializePCIHostBridge(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN i,j,n;
+ PCI_HOST_BRG_DATA *hb;
+ PCI_ROOT_BRG_DATA *rb;
+ EFI_EVENT ReadyToBootEvent=NULL;
+//-----------------------------------------
+
+ //Init Lib globals...
+ InitAmiLib(ImageHandle,SystemTable);
+ PROGRESS_CODE(DXE_NB_HB_INIT);
+
+ //Print PCI Bus Driver Version
+ PCI_TRACE((TRACE_PCI,"\nPciRootBrg: Initializing... PCI Driver Version %d.%d.%d\n", PCI_BUS_MAJOR_VER, PCI_BUS_MINOR_VER, PCI_BUS_REVISION));
+
+ Status = pBS->LocateProtocol(&gAmiBoardInfoGuid, NULL,(VOID**)&gAmiBoardInfoProtocol);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Fail to Locate AMI_BOARD_INFO_PROTOCOL Status=%r\n",Status));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ //Zerouot Privete HOST BRG data structure and Setup Data Buffer
+ pBS->SetMem(&gPciRbHost[0], sizeof(gPciRbHost), 0);
+ pBS->SetMem(&gRbSetupData, sizeof(PCI_SETUP_DATA), 0);
+
+ //Get Setup Data it has some Root Brg related features
+ BrdGetPciSetupData(&gRbSetupData);
+
+ //Update GCD resource map with static Chipset Specific Resources decoded.
+ Status=ConvertMemoryMap(ImageHandle,NULL);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Parse BusXlatTable extracting ROOT BRIDGE data from there.
+ Status=CreateRootBusData();
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ //try to map available roots from gRootBusDb.Items to
+ //the corresponded HOST abstraction
+ //each HOST has to have a separate instance of ResourceAllocation Protocol
+ //each ROOT will have a separate instance of RootBridgeIo Protocol.
+ //This "FOR" loop will construcr HOST/ROOT bridge infrastructure and will
+ //try to map each root collected in call CreateRootBusData() to it's correcponded HOST
+ //using HbCspMapRootBrgToHost() CSP hook. For MULTY-HOST systems this hook must be ported
+ for(i=0;i<gRootBusDb.ItemCount; i++){
+ PCI_BUS_XLAT_HDR *roothdr=(PCI_BUS_XLAT_HDR*)gRootBusDb.Items[i];
+ PCI_BUS_XLAT_HDR *nexthdr=NULL;
+ ASLR_QWORD_ASD *busrd;
+ UINT64 aa=0, ra=0;
+ //---------------------------------------
+ //fill Allocation Atributes Property.
+ //Based on Token values of COMBINE_MEM_PMEM and ABOVE_4G_PCI_DECODE
+ if(COMBINE_MEM_PMEM) aa |= EFI_PCI_HOST_BRIDGE_COMBINE_MEM_PMEM;
+ if(ABOVE_4G_PCI_DECODE){
+ aa |= EFI_PCI_HOST_BRIDGE_MEM64_DECODE;
+ ra |= EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+ }
+
+ if(roothdr->BusBuild ==0) ra |= (PCI_ROOT_COMPATIBILITY_ATTRIBUTES | PCI_ROOT_VGA_ATTRIBUTES);
+
+ //Call Chipset Specific function to map this ROOT to HOST.
+ //And override Allocation attributes based on TOKEN VALUES.
+ //Have no clue how to do it automatically though..........
+ j=HbCspMapRootBrgToHost(roothdr, &aa, &ra);
+
+ //If we got NUMBER
+ if(j>=NB_NUMBER_OF_HOST_BRG) {
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Root2Host mapping [HOST=%d >= MAX_HOSTs=%d; ROOT %X|%X \n ",
+ j, NB_NUMBER_OF_HOST_BRG, roothdr->BusBuild, roothdr->BusRun ));
+ ASSERT_EFI_ERROR(EFI_INVALID_PARAMETER);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ hb=&gPciRbHost[j];
+
+ //Check if setup allows us to decode PCI Space above 4G
+ if( gRbSetupData.Above4gDecode == 0 ) aa &= (~(EFI_PCI_HOST_BRIDGE_MEM64_DECODE));
+
+ hb->AllocAttrib=aa;
+
+ //Allocate memory for Root Bridge Data structure;
+ rb=MallocZ(sizeof(PCI_ROOT_BRG_DATA));
+ ASSERT(rb);
+ if(!rb)return EFI_OUT_OF_RESOURCES;
+
+ //Save BusXlatEntry for this Root
+ rb->BusXlatEntry=roothdr;
+
+#if AMI_BOARD_VER_COMBINED >= 100
+ //Change this to reference VeB output EIP 24469
+ rb->RbAslName=(CHAR8*)((UINT8*)(roothdr+1)+2); //Including DEV_FN 1Byte + terminator 1 byte.
+#endif
+
+ //Save returned Attributes
+ rb->Supports=ra;
+
+ //Get Next root header to determine current root Build Bus range
+ if(i<gRootBusDb.ItemCount-1) nexthdr=(PCI_BUS_XLAT_HDR*)gRootBusDb.Items[i+1];
+
+ //Get memory for Bus Resource Descriptor
+ busrd=MallocZ(sizeof(ASLR_QWORD_ASD));
+ //fill Bus Resource descriptor fields
+ busrd->Hdr.HDR=0x8A;
+ busrd->Hdr.Length=0x2B;
+ busrd->Type=ASLRV_SPC_TYPE_BUS;
+ busrd->_GRA=1;
+ busrd->_MIN=roothdr->BusBuild;
+ //if this is last ROOT xlat entry make it MAX Bus Number;
+ if(nexthdr == NULL) busrd->_MAX = 0xFF;
+ else busrd->_MAX=nexthdr->BusBuild-1;
+ busrd->_LEN = busrd->_MAX - busrd->_MIN + 1;
+
+ Status=AppendItemLst((T_ITEM_LIST*)&hb->RbInitCnt,rb);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=AppendItemLst((T_ITEM_LIST*)&rb->ResInitCnt,busrd);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+
+ //Init Number of nitial Host Bridge Structures;
+ for(i=0,n=0; i<NB_NUMBER_OF_HOST_BRG; i++){
+ hb=&gPciRbHost[i];
+ hb->ImageHandle=ImageHandle;
+ //Init Host Bridge Private Data instance
+ //here goes Allocation Arrtibutes
+ //hb->AllocAttrib=gHbAllocAttribTbl[i];
+
+ //Init Prtocol Functions
+ hb->ResAllocProtocol.NotifyPhase=HbResAllocNotifyPhase;
+ hb->ResAllocProtocol.GetNextRootBridge=HbResAllocGetNextRootBridge;
+ hb->ResAllocProtocol.GetAllocAttributes=HbResAllocGetAllocAttributes;
+ hb->ResAllocProtocol.StartBusEnumeration=HbResAllocStartBusEnumeration;
+ hb->ResAllocProtocol.SetBusNumbers=HbResAllocSetBusNumbers;
+ hb->ResAllocProtocol.SubmitResources=HbResAllocSubmitResources;
+ hb->ResAllocProtocol.GetProposedResources=HbResAllocGetProposedResources;
+ hb->ResAllocProtocol.PreprocessController=HbResAllocPreprocessController;
+
+ hb->AllocPhase=-1;
+ //hb->PciSegment=HbCspGetPicSegment();
+
+ //Install HB res Alloc Protocol on this HOST BRG
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &hb->HbHandle, //it was NULL so it going to be a new handle
+ &gHbResAllocProtocolGuid, &hb->ResAllocProtocol,//RbIo Protocol GUID - I/F pare
+ NULL); //terminator
+
+
+ //Init Root Bridge objects of Current Host Bridge
+ //hb->RbInitCnt=gRbCountTbl[i]+1;
+ for(j=0; j<hb->RootBridgeCount; j++,n++){
+ ACPI_HID_DEVICE_PATH *rbdp;
+ //-----------------------------------
+ //Reinit rb pointer for this loop
+ rb=hb->RootBridges[j];
+ rb->ImageHandle=ImageHandle;
+
+#if AMI_BOARD_VER_COMBINED < 100
+ //Change this to reference VeB output EIP 24469
+ rb->RbAslName=RbAslName[j];
+#endif
+
+ //Init Root Bridge Private Data instance
+ rbdp=Malloc(sizeof(ACPI_HID_DEVICE_PATH)+sizeof(EFI_DEVICE_PATH_PROTOCOL));
+ ASSERT(rbdp);
+ if(!rbdp)return EFI_OUT_OF_RESOURCES;
+
+ rb->DevPath=&rbdp->Header;
+ //generate RB device path
+ rbdp->Header.Type=ACPI_DEVICE_PATH;
+ rbdp->Header.SubType=ACPI_DP;
+ SET_NODE_LENGTH(&rbdp->Header,ACPI_DEVICE_PATH_LENGTH);
+ rbdp->HID=EISA_PNP_ID(0x0A03);
+ rbdp->UID=(UINT32)j;
+
+ rbdp++;
+ rbdp->Header.Type=END_DEVICE_PATH;
+ rbdp->Header.SubType=END_ENTIRE_SUBTYPE;
+ SET_NODE_LENGTH(&rbdp->Header,END_DEVICE_PATH_LENGTH);
+
+ //FillOut Capabilities
+ //rb->Supports=gRbSupportsTbl[n];
+ //if Host bridge has capability to decode 64 bit address space we
+ //will add EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE Capability bit
+ //to the RootBridge Supported features Set.
+ if(hb->AllocAttrib & EFI_PCI_HOST_BRIDGE_MEM64_DECODE)
+ rb->Supports |= EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE;
+
+ //Fill out Protocol Interface for RB Protocol Member functions
+ rb->RbIoProtocol.ParentHandle=hb->HbHandle;
+ rb->RbIoProtocol.PollMem=PollMem;
+ rb->RbIoProtocol.PollIo=PollIo;
+ rb->RbIoProtocol.Mem.Read=PciMemRead;
+ rb->RbIoProtocol.Mem.Write=PciMemWrite;
+ rb->RbIoProtocol.Io.Read=PciIoRead;
+ rb->RbIoProtocol.Io.Write=PciIoWrite;
+ rb->RbIoProtocol.Pci.Read=PciRead;
+ rb->RbIoProtocol.Pci.Write=PciWrite;
+ rb->RbIoProtocol.CopyMem=CopyMem;
+ rb->RbIoProtocol.Map=Map;
+ rb->RbIoProtocol.Unmap=Unmap;
+ rb->RbIoProtocol.AllocateBuffer=AllocateBuffer;
+ rb->RbIoProtocol.FreeBuffer=FreeBuffer;
+ rb->RbIoProtocol.Flush=Flush;
+ rb->RbIoProtocol.GetAttributes=GetAttributes;
+ rb->RbIoProtocol.SetAttributes=SetAttributes;
+ rb->RbIoProtocol.Configuration=Configuration;
+ rb->RbIoProtocol.SegmentNumber=(UINT32)HbCspGetPciSegment(i,j);
+ rb->Owner=hb;
+
+ rb->DevIoProtocol=ConstructDeviceIoProtocol(&rb->RbIoProtocol, rb->DevPath);
+ ASSERT(rb->DevIoProtocol);
+ if(!rb->DevIoProtocol) return EFI_OUT_OF_RESOURCES;
+
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &rb->RbHandle, //it was NULL so it going to be a new handle
+ &gRbIoProtocolGuid, &rb->RbIoProtocol, //RbIo Protocol GUID - I/F pare
+ &gDevPathProtocolGuid, rb->DevPath, //DevPath Protocol GUID - I/F pare
+ &gDeviceIoProtocolGuid, rb->DevIoProtocol,
+ NULL); //terminator
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ } //rb loop
+ //Here we must initialize and install PciHotPlugControllerInit Protocol
+ //based on VeB provided OUTPUT, IRQ_ASM_APIC output registy can do that.
+
+#if AMI_HOTPLUG_INIT_SUPPORT
+ if(gRbSetupData.HotPlug == 1){
+ Status = HpcInitProtocol(hb);
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: HpcInitProtocol() call returned %r\n", Status));
+
+ if(!EFI_ERROR(Status)){
+ // Install HB res Alloc Protocol on this HOST BRG
+ Status=pBS->InstallMultipleProtocolInterfaces(
+ &hb->HbHandle, //it is NOT NULL now
+ &gHotPlugInitProtocolGuid, &hb->HpcData->RootHotplugProtocol,
+ NULL); //terminator
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Install PCI RHPC Init Protocol call - returned %r\n", Status));
+ } else {
+ if (Status!=EFI_NOT_FOUND) ASSERT_EFI_ERROR(Status);
+
+ }
+
+ }//if Setup allows (gRbSetupData.HotPlug==1)...
+#endif
+
+ } //hb loop
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK,
+ RbReadyToBoot,
+ NULL,
+ &ReadyToBootEvent);
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Create ReadyToBootEvent - returned %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+
+ //Call Chipset Hook aftert we have initialized Pci Host bridge.
+ Status=HbCspBasicChipsetInit(&gPciRbHost[0]);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+//**********************************************************************
+//HelperFunctions
+//**********************************************************************
+#if AMI_HOTPLUG_INIT_SUPPORT == 1
+
+BOOLEAN HpcCheckHpBus(PCI_HOST_BRG_DATA *HostBrg, UINT8 HpSlotBus,
+ OUT PCI_ROOT_BRG_DATA **RootBrg, OUT PCI_BUS_XLAT_HDR **HlatHdr){
+ UINTN i;
+ PCI_ROOT_BRG_DATA *rb=NULL;
+ PCI_DEV_FUN *rootdf=NULL;
+ UINT8 maxbus;
+//---------------
+ if(RootBrg==NULL || HlatHdr == NULL) return FALSE;
+
+ PCI_TRACE((TRACE_PCI,"PciHp: Locating RB for Slot @ bus 0x%X ... ", HpSlotBus));
+
+ for(i=0; i<HostBrg->RootBridgeCount; i++){
+ PCI_BUS_XLAT_HDR *xhdr=gAmiBoardInfoProtocol->BusXlatTable;
+ PCI_DEV_FUN *devf = (PCI_DEV_FUN*)(xhdr+1);
+ //-----------------------------
+
+ //Init Data...
+ rb=HostBrg->RootBridges[i];
+
+ //See how many buses this root decodes...
+ if(i < HostBrg->RootBridgeCount-1) maxbus=HostBrg->RootBridges[i+1]->BusXlatEntry->BusBuild-1;
+ else maxbus=0xFF;
+
+ //Check if it HpSlotBus falls in this RB bus range.
+ if( (HpSlotBus > maxbus) || (rb->BusXlatEntry->BusBuild > HpSlotBus) )continue;
+
+
+ rootdf=(PCI_DEV_FUN*)(rb->BusXlatEntry+1);
+
+ while((UINTN)devf<=(UINTN)(gAmiBoardInfoProtocol->BusXlatTable)+gAmiBoardInfoProtocol->BusXlatLength){
+ //Terminator found...
+ if(devf->DEV_FUN == 0xFF){
+ //Check if BusBuild # of Xlat entry matches the HpSlotBus
+ if(xhdr->BusBuild == HpSlotBus){
+ PCI_DEV_FUN *rdf=(PCI_DEV_FUN*)(xhdr+1); //Root DevFunc is the first node after header.
+ //-----------------
+ if(rootdf->DEV_FUN == rdf->DEV_FUN ){
+ *RootBrg=rb;
+ *HlatHdr=xhdr;
+ PCI_TRACE((TRACE_PCI,"FOUND! Rb #%d; maxbus=0x%X minbus=0x%X\n ",i, maxbus, rb->BusXlatEntry->BusBuild));
+ return TRUE;
+ }
+ }
+ //Advance to the next record in BusXlatTbl.
+#if AMI_BOARD_VER_COMBINED >= 100
+ //Now we have AslName[5] following devf data
+ xhdr=(PCI_BUS_XLAT_HDR*)(devf+1+5);
+#else
+ xhdr=(PCI_BUS_XLAT_HDR*)(devf+1);
+#endif
+ devf = (PCI_DEV_FUN*)(xhdr+1);
+ continue;
+ } else {
+ devf++;
+ }
+ }
+ //Search through all the ROOTs..
+ } //for
+
+ //we can't find
+ *RootBrg=NULL;
+ *HlatHdr=NULL;
+
+ PCI_TRACE((TRACE_PCI,"NOT FOUND! Rb #%d; maxbus=0x%X minbus=0x%X\n",i, maxbus, rb->BusXlatEntry->BusBuild));
+ return FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HpcFindHpSlots
+//
+// Description:
+// This function find
+// information and initialize an instance of PCI Root Hotplug Controller
+// Initialization Protocol.
+//
+// Input: PCI_HOST_BRG_DATA *HostBrg - Pointer on Private Data
+// structure for which PCI Hot Plug Init Protocol going to
+// be initialized
+//
+// Output: EFI_SUCCESS is OK
+// EFI_NOT_FOUND no Hotplug slots where found.
+//
+// Notes: CHIPSET AND/OR BOARD PORTING NEEDED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HpcFindSlots(PCI_HOST_BRG_DATA *HostBrg){
+ EFI_STATUS Status=EFI_NOT_FOUND;
+ UINTN i;
+ PCI_IRQ_PIC_ROUTE *picr=NULL;
+ PCI_IRQ_APIC_ROUTE *apicr=NULL;
+ PCI_DEVICE_PATH pcidp;
+ UINTN hpscnt=0;
+//-------------------------
+ //Check The conditions and validity of a call...using PIC HP Slots Information...
+ hpscnt=gAmiBoardInfoProtocol->HpSltPicLength/sizeof(PCI_IRQ_PIC_ROUTE);
+
+ PCI_TRACE((TRACE_PCI,"PciHp: Found 0x%X HP Slots; processing...:\n", hpscnt));
+
+ if(hpscnt != (gAmiBoardInfoProtocol->HpSltApicLength/sizeof(PCI_IRQ_APIC_ROUTE)) ){
+ PCI_TRACE((TRACE_PCI,"PciHp: APIC HP Slot count != PIC HPC Slot Count: exiting - EFI_INVALID_PARAMETER\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ //init PCI Device Path variable we will not touch header data there..
+ pcidp.Header.SubType=HW_PCI_DP;
+ pcidp.Header.Type=HARDWARE_DEVICE_PATH;
+ SET_NODE_LENGTH(&pcidp.Header,HW_PCI_DEVICE_PATH_LENGTH);
+
+ //Now look for Hotplug slots we know it must be there...
+ for(i=0,picr=gAmiBoardInfoProtocol->HpSltTablePic; i<hpscnt; i++, picr++){
+ PCI_ROOT_BRG_DATA *hprb=NULL;
+ PCI_BUS_XLAT_HDR *hpsh=NULL;
+ //--------------------------
+
+ //Our helper function identified the Slot and ROOT where it belongs.
+ //We are assuming PCI Express Hotplug. So the Bridge is the HPC and Bus It produces is HPB.
+ if( HpcCheckHpBus(HostBrg, picr->PciBusNumber, &hprb, &hpsh)){
+ HPC_LOCATION_DATA *locdata=NULL;
+ EFI_DEVICE_PATH_PROTOCOL *tmpdp=NULL;
+ PCI_DEV_FUN *df;
+ //----------------
+ PCI_TRACE((TRACE_PCI,"PciHp: Found HP Slot #0x%X (%d dec) at BusBuild #0x%X\n",picr->SlotNum, picr->SlotNum, picr->PciBusNumber));
+
+ //Generate the device path for the HPController\HPBus we have pci device path reserved there.
+ tmpdp=DPCopy(hprb->DevPath);
+ if(tmpdp==NULL) {
+ Status=EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ df=(PCI_DEV_FUN*)(hpsh+1);
+ df+=1; //One node is for ROOT bridge
+
+ while (df->DEV_FUN != 0xFF){
+ VOID *oldp=tmpdp;
+ //---------
+ pcidp.Function=df->Fun;
+ pcidp.Device=df->Dev;
+ tmpdp=DPAddNode(tmpdp, (EFI_DEVICE_PATH_PROTOCOL*)&pcidp);
+
+ if(tmpdp==NULL) {
+ Status=EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+ df+=1;
+ if(oldp!=NULL)pBS->FreePool(oldp);
+ }
+ //Here DevicePath Is Ready.
+
+ //Store data returned by HpcCheckHpBus in private structures.
+ locdata=MallocZ(sizeof(HPC_LOCATION_DATA));
+ if(locdata==NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ } else Status=EFI_SUCCESS;
+
+ locdata->Owner=hprb;
+ locdata->SlotHdr=hpsh;
+
+ //For SHPC and PCIExpress Hotplug HPC==HPB = tmpdp.
+ //make a copy of generated DP into hpclocation buffer
+ locdata->HpcLocation.HpcDevicePath=DPCopy(tmpdp);
+ locdata->HpcLocation.HpbDevicePath=DPCopy(tmpdp);
+
+ pBS->FreePool(tmpdp);
+
+ if(locdata->HpcLocation.HpbDevicePath==NULL || locdata->HpcLocation.HpcDevicePath==NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ //fill out Padding Information for this slot...
+ locdata->Padding[ptBus] = gRbSetupData.BusPadd;
+ locdata->Padding[ptIo ] = gRbSetupData.IoPadd;
+ locdata->Padding[ptMmio32] = gRbSetupData.Mmio32Padd;
+ locdata->Padding[ptMmio32pf]= gRbSetupData.Mmio32PfPadd;
+ locdata->Padding[ptMmio64] = gRbSetupData.Mmio64Padd;
+ locdata->Padding[ptMmio64pf]= gRbSetupData.Mmio64PfPadd;
+
+ Status=AppendItemLst((T_ITEM_LIST*)&HostBrg->HpcData->HpclInitCnt, locdata);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) break;
+ }
+ if((UINTN)picr>((UINTN)gAmiBoardInfoProtocol->HpSltTablePic+gAmiBoardInfoProtocol->HpSltPicLength)) break;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HpcInitGetRootHpcList
+//
+// Description: GetRootHpcList() Function of the PCI Root Hotplug Controller
+// Initialization Protocol. See PI 1.1 Spec or details
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HpcInitGetRootHpcList(IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ OUT UINTN *HpcCount,
+ OUT EFI_HPC_LOCATION **HpcList)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN i;
+ EFI_HPC_LOCATION *hpcl=NULL, *lp=NULL;
+ PCI_HPC_DATA *hpcdata=NULL;
+
+//------------------------
+ hpcdata=(PCI_HPC_DATA*)This;
+
+ PCI_TRACE((TRACE_PCI,"PciHb: Get Location - HpcLocCount=%d\n", hpcdata->HpcLocCount));
+ PCI_TRACE((TRACE_PCI,"-------------------------------------------------\n"));
+
+ //Allocate Buffer for HPC List
+ hpcl=MallocZ(sizeof(EFI_HPC_LOCATION) * hpcdata->HpcLocCount);
+
+ //Check conditions
+ if(hpcl==NULL){
+ Status=EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ //Fill data in RHPC List Data...
+ for(i=0, lp=hpcl; i<hpcdata->HpcLocCount; i++, lp++){
+ HPC_LOCATION_DATA *locdata=hpcdata->HpcLocData[i];
+ //----------------
+ MemCpy(lp, &locdata->HpcLocation, sizeof(EFI_HPC_LOCATION));
+ PCI_TRACE((TRACE_PCI," lp->HpcDP=[HID(%X)UID(%X)]; lp->HpbDP[HID(%X)UID(%X)]\n",
+ ((ACPI_HID_DEVICE_PATH*)lp->HpcDevicePath)->HID,((ACPI_HID_DEVICE_PATH*)lp->HpcDevicePath)->UID,
+ ((ACPI_HID_DEVICE_PATH*)lp->HpbDevicePath)->HID,((ACPI_HID_DEVICE_PATH*)lp->HpbDevicePath)->UID));
+ }
+ PCI_TRACE((TRACE_PCI,"-------------------------------------------------\n"));
+
+ *HpcCount=hpcdata->HpcLocCount;
+ *HpcList=hpcl;
+
+ return Status;
+}
+
+
+EFI_STATUS FindHpcLocData( IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN PCI_HPC_DATA *HpcData,
+ OUT HPC_LOCATION_DATA **HpcLocData )
+{
+ UINTN i;
+ HPC_LOCATION_DATA *locdata;
+//------------------
+
+ for(i=0; i< HpcData->HpcLocCount; i++){
+ locdata=HpcData->HpcLocData[i];
+ if(DPCmp(HpcDevicePath, locdata->HpcLocation.HpcDevicePath) == 0 ){
+ *HpcLocData=locdata;
+ return EFI_SUCCESS;
+ }
+ }
+
+ PCI_TRACE((TRACE_PCI,"PciHp: Can't find matching HPC for DevicePath @ 0x%X \n",HpcDevicePath));
+
+ return EFI_NOT_FOUND;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HpcInitInitializeRootHpc
+//
+// Description: InitializeRootHpc() Function of the PCI Root Hotplug Controller
+// Initialization Protocol. See PI 1.1 Spec or details
+//
+// NOTE:
+// This function call will be used to overwrite default resource Padding settings.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HpcInitInitializeRootHpc(IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN UINT64 HpcPciAddress,
+ IN EFI_EVENT Event, OPTIONAL
+ OUT EFI_HPC_STATE *HpcState)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_HPC_DATA *hpcdata=NULL;
+ HPC_LOCATION_DATA *locdata;
+//------------------------
+ hpcdata=(PCI_HPC_DATA*)This;
+
+ //Find which exactly HPC PCI BUS Driver means..
+ Status=FindHpcLocData(HpcDevicePath, hpcdata,&locdata);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Call Porting function to overwrite HP Padding Settings if needed;
+ PciPortSetOemPadding(hpcdata, locdata, HpcPciAddress);
+
+ *HpcState=(EFI_HPC_STATE_INITIALIZED|EFI_HPC_STATE_ENABLED);
+
+ return EFI_SUCCESS;
+}
+
+VOID HpcFillDescriptor(ASLR_QWORD_ASD *Descriptor, HP_PADD_RES_TYPE PaddType, UINT64 Length){
+
+//---------------------
+
+ Descriptor->Hdr.HDR=0x8A;
+ Descriptor->Hdr.Length=0x2B;
+
+ Descriptor->_LEN=Length;
+ if(PaddType==ptBus)Descriptor->_MAX=1;
+ else{
+ if(IsPowerOfTwo(Length))Descriptor->_MAX=Length-1;
+ else Descriptor->_MAX=1;
+ }
+
+ Descriptor->GFlags._MIF=1;
+ Descriptor->GFlags._MAF=1;
+ Descriptor->TFlags.TFLAGS=0;
+
+ switch(PaddType){
+ case ptBus:
+ Descriptor->Type=ASLRV_SPC_TYPE_BUS;
+ break;
+ case ptIo:
+ Descriptor->Type=ASLRV_SPC_TYPE_IO;
+ break;
+ case ptMmio32:
+ Descriptor->Type=ASLRV_SPC_TYPE_MEM;
+ Descriptor->_GRA=32;
+ break;
+ case ptMmio32pf:
+ Descriptor->Type=ASLRV_SPC_TYPE_MEM;
+ Descriptor->TFlags.TFLAGS=0x06;
+ Descriptor->_GRA=32;
+ break;
+ case ptMmio64: //4
+ Descriptor->Type=ASLRV_SPC_TYPE_MEM;
+ Descriptor->_GRA=64;
+ break;
+ case ptMmio64pf: //5
+ Descriptor->Type=ASLRV_SPC_TYPE_MEM;
+ Descriptor->TFlags.TFLAGS=0x06;
+ Descriptor->_GRA=64;
+ break;
+ }
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HpcInitInitializeRootHpc
+//
+// Description: InitializeRootHpc() Function of the PCI Root Hotplug Controller
+// Initialization Protocol. See PI 1.1 Spec or details
+//
+// NOTE:
+// This function call will be used to overwrite default resource Padding settings.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HpcGetResourcePadding(IN EFI_PCI_HOT_PLUG_INIT_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *HpcDevicePath,
+ IN UINT64 HpcPciAddress,
+ OUT EFI_HPC_STATE *HpcState,
+ OUT VOID **Padding,
+ OUT EFI_HPC_PADDING_ATTRIBUTES *Attributes)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_HPC_DATA *hpcdata=NULL;
+ HPC_LOCATION_DATA *locdata;
+ UINTN i, cnt;
+ ASLR_QWORD_ASD *pd, *qw;
+//----------------------------------------------
+ hpcdata=(PCI_HPC_DATA*)This;
+
+ //Find which exactly HPC PCI BUS Driver means..
+ Status=FindHpcLocData(HpcDevicePath, hpcdata,&locdata);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Calculate how many ACPI_QW_DESC we need for Padding Info.
+ for(i=0, cnt=0; i<ptMaxType; i++){
+ if(locdata->Padding[i]!=0) cnt++;
+ }
+
+ //Get memory for it.
+ pd=MallocZ(sizeof(ASLR_QWORD_ASD)*cnt+sizeof(ASLR_EndTag));
+ if (pd==NULL) {
+ Status=EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ //fill out QW Resopurce Descriptors for resource requirements.
+ for(i=0, qw=pd; i<ptMaxType; i++){
+ if(locdata->Padding[i]!=0){
+ HpcFillDescriptor(qw, (HP_PADD_RES_TYPE)i, locdata->Padding[i]);
+ qw++;
+ }
+ }
+
+ ((ASLR_EndTag*)qw)->Hdr.HDR=ASLV_END_TAG_HDR;
+ ((ASLR_EndTag*)qw)->Chsum=0;
+
+ *Padding=pd;
+ *HpcState=(EFI_HPC_STATE_INITIALIZED|EFI_HPC_STATE_ENABLED);
+ *Attributes=EfiPaddingPciBus;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HpcInitProtocol
+//
+// Description: This function will collect all information HP related
+// information and initialize an instance of PCI Root Hotplug Controller
+// Initialization Protocol.
+//
+// Input: PCI_HOST_BRG_DATA *HostBrg - Pointer on Private Data
+// structure for which PCI Hot Plug Init Protocol going to
+// be initialized
+//
+// Output: EFI_SUCCESS is OK
+// EFI_NOT_FOUND no Hotplug slots where found.
+//
+// Notes: CHIPSET AND/OR BOARD PORTING NEEDED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HpcInitProtocol(PCI_HOST_BRG_DATA *HostBrg){
+ EFI_STATUS Status=EFI_NOT_FOUND;
+// PCI_HPC_DATA *HpcData;
+//---------------------------
+
+ HostBrg->HpcData=MallocZ(sizeof(PCI_HPC_DATA));
+ if(HostBrg->HpcData==NULL){
+ Status=EFI_OUT_OF_RESOURCES;
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+ HostBrg->HpcData->Owner=HostBrg;
+
+ //Get HP Slots information and Device Path.
+ Status=HpcFindSlots(HostBrg);
+ if(EFI_ERROR(Status)) return Status;
+
+ //So far so good... Init Protocol Instance Functions
+ HostBrg->HpcData->RootHotplugProtocol.GetRootHpcList=HpcInitGetRootHpcList;
+ HostBrg->HpcData->RootHotplugProtocol.InitializeRootHpc=HpcInitInitializeRootHpc;
+ HostBrg->HpcData->RootHotplugProtocol.GetResourcePadding=HpcGetResourcePadding;
+
+
+ return Status;
+}
+
+#endif //AMI_HOTPLUG_INIT_SUPPORT == 1
+
+EFI_STATUS FindRbBusData(PCI_ROOT_BRG_DATA *RootBrg, ASLR_QWORD_ASD **ResDsc){
+ UINTN i;
+ ASLR_QWORD_ASD *res;
+//----------------------------
+
+ //Init return walue with NOT_FOUND result
+ *ResDsc=NULL;
+
+ for(i=0;i<RootBrg->ResCount;i++){
+
+ res=RootBrg->RbRes[i];
+ if(res->Type== ASLRV_SPC_TYPE_BUS){
+ *ResDsc=res;
+ return EFI_SUCCESS;
+ }
+ }//for k
+
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_STATUS ClaimMmioResources(PCI_ROOT_BRG_DATA *CurRootBrg, PCI_ROOT_BRG_DATA *NextRootBrg, ACPI_RES_TYPE ResType){
+ EFI_STATUS Status;
+ DXE_SERVICES *dxe=NULL;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR mem;
+ UINT64 top, bot, tmp, ct, cb;
+ ACPI_RES_DATA *car, *nar;
+//--------------------------------
+ // Get GCD's Memory Space and IO Space Maps
+ Status=LibGetDxeSvcTbl(&dxe);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Fail to Get DXE Services Table Pointer - %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+ return EFI_DEVICE_ERROR;
+ }
+
+ if(ResType==raMmio32)car=&CurRootBrg->AcpiRbRes[raMmio32];
+ else car=&CurRootBrg->AcpiRbRes[raMmio64];
+
+ if(car->Len==0) return EFI_NOT_FOUND;
+
+ // Use MMIO resources as-is if AllocType is set to EfiGcdAllocateAddress.
+ if(car->AllocType == EfiGcdAllocateAddress) return EFI_SUCCESS;
+
+ if(NextRootBrg!=NULL) {
+ if(ResType==raMmio32)nar=&NextRootBrg->AcpiRbRes[raMmio32];
+ else nar=&NextRootBrg->AcpiRbRes[raMmio64];
+ }else nar=NULL;
+
+
+ if( nar==NULL ) {
+ if(ResType==raMmio32){
+ top=MAX_PCI_MMIO32;
+ bot=MIN_PCI_MMIO32;
+ } else {
+ top=MAX_PCI_MMIO64;
+ bot=MIN_PCI_MMIO64;
+ }
+ } else {
+ if(car->AllocType<=EfiGcdAllocateAddress){
+ top=nar->Min-1;
+ bot=car->Min;
+ } else {
+ top=car->Max;
+ if(ResType==raMmio32) bot=MIN_PCI_MMIO32;
+ else bot=MIN_PCI_MMIO64;
+ }
+ }
+
+ if( TmpTop[ResType] != 0 ) bot=TmpTop[ResType]+1;
+// if( TmpBot[ResType] != 0 ) bot=TmpBot[ResType];
+
+ cb=car->Min;
+ ct=car->Max;
+
+ PCI_TRACE((TRACE_PCI," Ajusting ACPI MMIO MAP [0x%lX...[0x%lX...0x%lX]...0x%lX]\n",bot,cb,ct,top));
+
+ PCI_TRACE((TRACE_PCI," Searching from "));
+
+ if(car->AllocType<=EfiGcdAllocateAddress) {
+ tmp=ct+1;
+ PCI_TRACE((TRACE_PCI,"0x%lX ==> UP.....to 0x%lX\n", tmp, top));
+ } else {
+ tmp=cb-1;
+ PCI_TRACE((TRACE_PCI,"0x%lX <== DOWN...to 0x%lX\n", tmp, bot));
+ }
+
+ //All IO map's EfiGcdIoTypeNonExistent IO type, must be converted to EfiGcdIoTypeIo
+ while(TRUE){
+ Status=dxe->GetMemorySpaceDescriptor(tmp,&mem);
+
+ //Check if we reach end of GCD Space map...
+ if(EFI_ERROR(Status)) break;
+
+ //Check if we hit another RB
+ if(mem.DeviceHandle!=NULL && mem.DeviceHandle!=CurRootBrg->RbHandle) break;
+
+ //Check if we hit system memory...
+ if(mem.GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) break;
+
+ PCI_TRACE((TRACE_PCI," MemDsc: BAS=0x%lX; LEN=0x%lX; TYP=%d; IH=0x%X; DX=0x%X; %r\n",
+ mem.BaseAddress, mem.Length, mem.GcdMemoryType, mem.ImageHandle, mem.DeviceHandle, Status));
+
+ if(car->AllocType<=EfiGcdAllocateAddress){
+ ct=mem.BaseAddress+mem.Length-1;
+ } else {
+ cb=mem.BaseAddress;
+ }
+
+ if(car->AllocType<=EfiGcdAllocateAddress){
+ //if we are searching bottom to top...
+ if(ct>=top){
+ ct=top;
+ break;
+ }
+ } else {
+ //if we are searching top to bottom...
+ if(cb<=bot){
+ cb=bot;
+ break;
+ }
+ }
+
+ if(car->AllocType<=EfiGcdAllocateAddress) tmp=ct+1;
+ else tmp=cb-1;
+ }
+
+ car->Max=ct;
+ car->Min=cb;
+ car->Len=ct-cb+1;
+
+ TmpTop[ResType]=ct;
+ TmpBot[ResType]=cb;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS ClaimIoResources(PCI_ROOT_BRG_DATA *CurRootBrg, PCI_ROOT_BRG_DATA *NextRootBrg){
+ EFI_STATUS Status;
+ DXE_SERVICES *dxe=NULL;
+ EFI_GCD_IO_SPACE_DESCRIPTOR io;
+ UINT64 top, bot, tmp, ct, cb;
+ ACPI_RES_DATA *car, *nar;
+//--------------------------------
+ // Get GCD's Memory Space and IO Space Maps
+ Status=LibGetDxeSvcTbl(&dxe);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Fail to Get DXE Services Table Pointer - %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+ return EFI_DEVICE_ERROR;
+ }
+
+ car=&CurRootBrg->AcpiRbRes[raIo];
+
+ if(car->Len==0) return EFI_NOT_FOUND;
+
+ if(NextRootBrg!=NULL) nar=&NextRootBrg->AcpiRbRes[raIo];
+ else nar=NULL;
+
+ if( nar==NULL ) {
+ top=MAX_PCI_IO;
+ bot=MIN_PCI_IO;
+ } else {
+ if(car->AllocType<=EfiGcdAllocateAddress){
+ top=nar->Min-1;
+ bot=car->Min;
+ } else {
+ top=car->Max;
+ bot=MIN_PCI_IO;
+ }
+ }
+
+ if( TmpTop[raIo] != 0 ) bot=TmpTop[raIo]+1;
+ //if( TmpBot[raIo] != 0 ) bot=TmpBot[raIo];
+
+ cb=car->Min;
+ ct=car->Max;
+
+ PCI_TRACE((TRACE_PCI," Ajusting ACPI IO MAP [0x%lX...[0x%lX...0x%lX]...0x%lX]\n",bot,cb,ct,top));
+
+ PCI_TRACE((TRACE_PCI," Searching from "));
+
+ if(car->AllocType<=EfiGcdAllocateAddress) {
+ tmp=ct+1;
+ PCI_TRACE((TRACE_PCI,"0x%lX ==> UP.....to 0x%lX\n", tmp, top));
+ } else {
+ tmp=cb-1;
+ PCI_TRACE((TRACE_PCI,"0x%lX <== DOWN...to 0x%lX\n", tmp, bot));
+ }
+
+ //All IO map's EfiGcdIoTypeNonExistent IO type, must be converted to EfiGcdIoTypeIo
+ while(TRUE){
+ Status=dxe->GetIoSpaceDescriptor(tmp,&io);
+
+ //Check if we reach end of GCD Space map...
+ if(EFI_ERROR(Status)) break;
+
+ //Check if we hit another RB
+ if(io.DeviceHandle!=NULL && io.DeviceHandle!=CurRootBrg->RbHandle) break;
+
+ PCI_TRACE((TRACE_PCI," IoDes: BAS=0x%lX; LEN=0x%lX; TYP=%d; IH=0x%X; DX=0x%X; %r\n",
+ io.BaseAddress, io.Length, io.GcdIoType, io.ImageHandle, io.DeviceHandle, Status));
+
+ if(car->AllocType<=EfiGcdAllocateAddress){
+ ct=io.BaseAddress+io.Length-1;
+ } else {
+ cb=io.BaseAddress;
+ }
+ if(car->AllocType<=EfiGcdAllocateAddress){
+ //if we are searching bottom to top...
+ if(ct>=top){
+ ct=top;
+ break;
+ }
+ } else {
+ //if we are searching top to bottom...
+ if(cb<=bot){
+ cb=bot;
+ break;
+ }
+ }
+
+ if(car->AllocType<=EfiGcdAllocateAddress) tmp=ct+1;
+ else tmp=cb-1;
+ }
+
+ car->Max=ct;
+ car->Min=cb;
+ car->Len=ct-cb+1;
+
+ TmpTop[raIo]=ct;
+ TmpBot[raIo]=cb;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS AjustAcpiResource(UINTN HostIndex, UINTN RootIndex, ACPI_RES_TYPE ResType){
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_HOST_BRG_DATA *hb, *nexthb;
+ PCI_ROOT_BRG_DATA *rb, *nextrb;
+ ASLR_QWORD_ASD *res, *nextres;
+//--------------------
+
+ //Get pointers to the main data structures we are going to work with.
+ hb=&gPciRbHost[HostIndex];
+ rb=hb->RootBridges[RootIndex];
+
+ //Check if system has NEXT entity available...
+ if(NB_NUMBER_OF_HOST_BRG>HostIndex+1) nexthb=&gPciRbHost[HostIndex+1];
+ else nexthb=NULL;
+
+ if(hb->RootBridgeCount>RootIndex+1)nextrb=hb->RootBridges[RootIndex+1];
+ else {
+ if(nexthb!=NULL) nextrb=nexthb->RootBridges[0];
+ else nextrb=NULL;
+ }
+
+ //Start parsing resources...
+ switch(ResType){
+ case raBus:
+ //Trying to make bus ranges among the bridges be decoded consistently
+ //even RB0 decodes buses 0..5 and RB1 decodes 0x80..0x82 for ACPI
+ //make it decode 0..0x7F and 80..0xFF correspondently.
+ Status=FindRbBusData(rb, &res);
+ //BUS resources must be there
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+
+ //fill ACPI Resource properties
+ rb->AcpiRbRes[raBus].Min=res->_MIN;
+ rb->AcpiRbRes[raBus].Gra=1;
+ if (nextrb!=NULL) {
+ Status=FindRbBusData(nextrb, &nextres);
+ //BUS resources must be there
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_DEVICE_ERROR;
+ //Check if NULL bus descriptor...
+ if(nextres->_MIN==0 && nextres->_MAX==0 && nextres->_LEN==0)
+ rb->AcpiRbRes[raBus].Max=MAX_PCI_BUSES;
+ else
+ rb->AcpiRbRes[raBus].Max=nextres->_MIN-1;
+ } else {
+ rb->AcpiRbRes[raBus].Max=MAX_PCI_BUSES;
+ }
+ rb->AcpiRbRes[raBus].Len=rb->AcpiRbRes[raBus].Max-rb->AcpiRbRes[raBus].Min+1;
+
+ PCI_TRACE((TRACE_PCI," Ajusting ACPI BUS MAP [0x%lX...[0x%lX...0x%lX]...0x%lX]\n",
+ rb->AcpiRbRes[raBus].Min,res->_MIN,res->_MIN+res->_LEN-1,rb->AcpiRbRes[raBus].Max));
+ PCI_TRACE((TRACE_PCI," ACPI BUS MAP Set to [0x%lX...0x%lX]\n",
+ rb->AcpiRbRes[raBus].Min,rb->AcpiRbRes[raBus].Max));
+ break;
+
+ case raIo:
+ //With IO picture is much worse. we should scan and assume any unallocated IO to the
+ //corresponded RB keeping in mind boundary between RB0..RB1..RBn decoding ranges.
+ //IO resources may not be there ISA res 0...0xFFF is taken care of automatically
+ //If system don't have second root bridge and does not decode any IO, assume all IO
+ //from 0x1000...Fset decoded by
+ Status=ClaimIoResources(rb, nextrb);
+ PCI_TRACE((TRACE_PCI," ACPI IO MAP Set to [0x%lX...0x%lX] %r\n",
+ rb->AcpiRbRes[raIo].Min,rb->AcpiRbRes[raIo].Max,Status));
+ break;
+ case raMmio32:
+ Status=ClaimMmioResources(rb, nextrb, raMmio32);
+ PCI_TRACE((TRACE_PCI," ACPI MEM32 MAP Set to [0x%lX...0x%lX] %r\n",
+ rb->AcpiRbRes[raMmio32].Min,rb->AcpiRbRes[raMmio32].Max, Status));
+
+ break;
+ case raMmio64:
+ Status=ClaimMmioResources(rb, nextrb, raMmio64);
+ PCI_TRACE((TRACE_PCI," ACPI MEM64 MAP Set to [0x%lX...0x%lX] %r\n",
+ rb->AcpiRbRes[raMmio64].Min,rb->AcpiRbRes[raMmio64].Max, Status));
+ break;
+ default: return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RbReadyToBoot
+//
+// Description: This function will create ReadyToBoot Event to update each
+// Root Bridge ASL Object with corresponded resources decoded.
+//
+// Input: Nothing
+//
+// Output: EFI_SUCCESS is OK
+//
+//
+// Notes: CHIPSET AND/OR BOARD PORTING NEEDED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RbReadyToBoot(IN EFI_EVENT Event, IN VOID *Context){
+ EFI_STATUS Status;
+ UINTN i,j,k;
+ PCI_HOST_BRG_DATA *hb;
+ PCI_ROOT_BRG_DATA *rb;
+ ACPI_HDR *dsdt;
+ EFI_PHYSICAL_ADDRESS a;
+ BOOLEAN vga=FALSE;
+//-----------------------------
+
+// EFI_DEADLOOP();
+
+ //Get DSDT.. we have to update it.
+ Status=LibGetDsdt(&a,EFI_ACPI_TABLE_VERSION_ALL);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Fail to Get DSDT - returned %r\n", Status));
+ ASSERT_EFI_ERROR(Status);
+ return;
+ } else dsdt=(ACPI_HDR*)a;
+
+ //Collect currently programed resource requirements, we will need to ajust it
+ //to clame all Unallocated IO/MMIO to report it to OS.
+ for(i=0; i<NB_NUMBER_OF_HOST_BRG; i++){
+ hb=&gPciRbHost[i];
+ for(j=0; j<hb->RootBridgeCount; j++){
+ rb=hb->RootBridges[j];
+
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Host[ %d ].Root[ %d ] \n", i, j));
+
+ for(k=raBus; k<raMaxRes; k++){
+ Status=AjustAcpiResource(i,j,k);
+ }//for k
+ }//for j
+ }//for i
+
+ //after collectinfg and ajusting all Rb decoding info info
+ //Update place holders in each Rb Device Scope in DSDT.
+ for(i=0; i<NB_NUMBER_OF_HOST_BRG; i++){
+ hb=&gPciRbHost[i];
+ for(j=0; j<hb->RootBridgeCount; j++){
+ rb=hb->RootBridges[j];
+
+ //Check if this is a Compatibility Root Bridge.
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Updating ASL Device Object '%s': ...\n", rb->RbAslName));
+
+ if(rb->Supports & (PCI_ROOT_COMPATIBILITY_ATTRIBUTES)){
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "CPRB", 1);
+ PCI_TRACE((TRACE_PCI," =>'CPRB'= 1 -> %r;\n", Status));
+ } else {
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "CPRB", 0);
+ PCI_TRACE((TRACE_PCI," =>'CPRB'= 0 -> %r;\n", Status));
+ }
+
+ if(rb->Attributes & (PCI_ROOT_VGA_ATTRIBUTES)){
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "LVGA", 1);
+ PCI_TRACE((TRACE_PCI," =>'LVGA'= 1 -> %r;\n", Status));
+ vga=TRUE;
+ } else {
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "LVGA", 0);
+ PCI_TRACE((TRACE_PCI," =>'LVGA'= 0 -> %r;\n", Status));
+ }
+
+ //Now Update place holders fit in collected system resource consumption.
+
+ //0. Update device Status
+ if( rb->NotPresent ) Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "STAV", 0x00);
+ PCI_TRACE((TRACE_PCI," =>'SATV'=%d -> %r;\n", !rb->NotPresent, Status));
+
+ //1.Update Bus Object
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "BRB", rb->AcpiRbRes[raBus].Min);
+ PCI_TRACE((TRACE_PCI," =>'BRB_'=0x%lX -> %r; ",rb->AcpiRbRes[raBus].Min, Status));
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "BRL", rb->AcpiRbRes[raBus].Len);
+ PCI_TRACE((TRACE_PCI," 'BRL_'=0x%lX -> %r;\n",rb->AcpiRbRes[raBus].Len, Status));
+
+ //2.Update IO Object
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "IOB", rb->AcpiRbRes[raIo].Min);
+ PCI_TRACE((TRACE_PCI," =>'IOB_'=0x%lX -> %r; ",rb->AcpiRbRes[raIo].Min, Status));
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "IOL", rb->AcpiRbRes[raIo].Len);
+ PCI_TRACE((TRACE_PCI," 'IOL_'=0x%lX -> %r;\n",rb->AcpiRbRes[raIo].Len, Status));
+
+ //3.Update MMIO32 Object
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MBB", rb->AcpiRbRes[raMmio32].Min);
+ PCI_TRACE((TRACE_PCI," =>'MBB_'=0x%lX -> %r; ",rb->AcpiRbRes[raMmio32].Min, Status));
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MBL", rb->AcpiRbRes[raMmio32].Len);
+ PCI_TRACE((TRACE_PCI," 'MBL_'=0x%lX -> %r;\n",rb->AcpiRbRes[raMmio32].Len, Status));
+
+ //3.Update MMIO64 Object
+ //3.1 Update LO part of _MIN
+ a=rb->AcpiRbRes[raMmio64].Min & 0xFFFFFFFF;
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MABL", a);
+ PCI_TRACE((TRACE_PCI," =>'MABL'=0x%lX -> %r; ", a, Status));
+
+ //3.2 Update HI part of _MIN
+ a=Shr64(rb->AcpiRbRes[raMmio64].Min, 32);
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MABH", a);
+ PCI_TRACE((TRACE_PCI,"'MABH'=0x%lX -> %r;\n", a, Status));
+
+ //3.3 Update LO part of MAX
+ a=rb->AcpiRbRes[raMmio64].Max & 0xFFFFFFFF;
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MAML", a);
+ PCI_TRACE((TRACE_PCI," =>'MAML'=0x%lX -> %r; ", a, Status));
+
+ //3.4 Update HI part of _MAX
+ a=Shr64(rb->AcpiRbRes[raMmio64].Max, 32);
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MAMH", a);
+ PCI_TRACE((TRACE_PCI,"'MAMH'=0x%lX -> %r;\n", a, Status));
+
+ //3.3 Update LO part of MAX
+ a=rb->AcpiRbRes[raMmio64].Len & 0xFFFFFFFF;
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MALL", a);
+ PCI_TRACE((TRACE_PCI," =>'MALL'=0x%lX -> %r; ", a, Status));
+
+ //3.4 Update HI part of _MAX
+ a=Shr64(rb->AcpiRbRes[raMmio64].Len, 32);
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "MALH", a);
+ PCI_TRACE((TRACE_PCI,"'MALH'=0x%lX -> %r;\n", a, Status));
+
+ }//j
+ }//i
+
+ //if PCI_ROOT_VGA_ATTRIBUTES were not set by drivers we have to clame Legacy VGS IO and MEM Space.
+ if(!vga){
+ hb=&gPciRbHost[0];
+ rb=hb->RootBridges[0];
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Legacy VGA Attributes were not set!!!\n"));
+ PCI_TRACE((TRACE_PCI," Setting 'LVGA'=1 of Device Object '%s' for Hb[0].Rb[0] -> ", rb->RbAslName));
+ Status=UpdateAslNameOfDevice(dsdt, rb->RbAslName, "LVGA", 1);
+ PCI_TRACE((TRACE_PCI,"%r;\n", Status));
+ }
+
+ //Checksum
+ dsdt->Checksum = 0;
+ dsdt->Checksum = ChsumTbl((UINT8*)dsdt, dsdt->Length);
+
+ // Check for invalid Pci RootBridge Handle.
+ //If Rootbridge handle is invalid, then uninstall PCI Rootbridge IO protocol on this handle.
+ for(i=0; i<NB_NUMBER_OF_HOST_BRG; i++){
+ hb=&gPciRbHost[i];
+ for(j=0; j<hb->RootBridgeCount; j++){
+ rb=hb->RootBridges[j];
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Host[ %d ].Root[ %d ] \n", i, j));
+
+ if(rb->NotPresent) {
+ PCI_TRACE((TRACE_PCI,"Hb.SetBusNumbers - Invalid RB Hndle Passed\n"));
+ Status = pBS->UninstallMultipleProtocolInterfaces (
+ rb->RbHandle,
+ &gRbIoProtocolGuid, &rb->RbIoProtocol,
+ &gDevPathProtocolGuid, rb->DevPath,
+ NULL
+ );
+
+ PCI_TRACE((TRACE_PCI,"Uninstall RbIoProtocol Status %r; \n", Status));
+ rb->RbHandle=NULL;
+ }//if
+ }//for j
+ }//for i
+
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateRootBusData
+//
+// Description: This function will parse NusXlat Table looking for HostBridge
+// entries (one who has Bus IN == Bus OUT) and populate gRootBusDb
+// Structure.
+//
+// Input: Nothing
+//
+// Output: EFI_SUCCESS is OK
+//
+//
+// Notes: CHIPSET AND/OR BOARD PORTING NEEDED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateRootBusData(){
+ PCI_BUS_XLAT_HDR *xhdr=gAmiBoardInfoProtocol->BusXlatTable;
+ PCI_DEV_FUN *devf = (PCI_DEV_FUN*)(xhdr+1);
+ UINTN i=0;
+ EFI_STATUS Status;
+//--------------------------------
+ while((UINTN)devf<=(UINTN)(gAmiBoardInfoProtocol->BusXlatTable)+gAmiBoardInfoProtocol->BusXlatLength){
+ if(devf->DEV_FUN == 0xFF){
+ //if we are looking for host device it shouldn't be any other guys in it's chain.
+ if(i==1) {
+ Status=AddBusDbEntry(xhdr, &gRootBusDb);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ //Advance to the next record in BusXlatTbl.
+#if AMI_BOARD_VER_COMBINED >= 100
+ //Now we have AslName[5] following devf data
+ xhdr=(PCI_BUS_XLAT_HDR*)(devf+1+5);
+#else
+ xhdr=(PCI_BUS_XLAT_HDR*)(devf+1);
+#endif
+ devf = (PCI_DEV_FUN*)(xhdr+1);
+ i=0;
+ } else {
+ devf++;
+ i++;
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertMemoryMap
+//
+// Description: This function will adjust the final GCD resource map and
+// convert all NonrExistant Memory resources into MMIO.
+//
+// Input: ImgHandle Image handle
+// CntrHandle Controller Handle
+//
+// Output: None
+//
+// Notes: CHIPSET AND/OR BOARD PORTING NEEDED
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertMemoryMap(EFI_HANDLE ImgHandle, EFI_HANDLE CntrHandle)
+{
+ EFI_STATUS Status;
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *pMap;
+ EFI_GCD_IO_SPACE_DESCRIPTOR *pIo;
+ UINTN Size, i;
+ DXE_SERVICES *dxe;
+//----------------------------------------------------------------------
+
+ // Convert All Nonexistent Memory space to MMIO
+ // Once GCD and Memory manager gets initialized
+ Status=LibGetDxeSvcTbl(&dxe);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ Status=dxe->GetMemorySpaceMap(&Size, &pMap);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ for(i=0; i<Size; i++)
+ if (pMap[i].GcdMemoryType == EfiGcdMemoryTypeNonExistent ){
+ Status=dxe->AddMemorySpace(EfiGcdMemoryTypeMemoryMappedIo,
+ pMap[i].BaseAddress,pMap[i].Length, GCD_COMMON_MMIO_CAPS);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ pBS->FreePool(pMap);
+
+ //Convert all non-existant IO to existant IO
+ Status=dxe->GetIoSpaceMap(&Size, &pIo);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ for(i=0; i<Size; i++)
+ if (pIo[i].GcdIoType == EfiGcdIoTypeNonExistent){
+ Status=dxe->AddIoSpace(EfiGcdIoTypeIo,pIo[i].BaseAddress,pIo[i].Length);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ }
+ pBS->FreePool(pIo);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsResSubmited()
+//
+// Description:
+// Will check if all root bridges belonging to the "Host" has submitted
+// it's resources
+//
+// Input:
+// PCI_HOST_BRG_DATA *Host Pointer to HOST Bridge private data
+// EFI_HANDLE RootBridgeHandle PCI Root Bridge to be configured
+// VOID **Configuration Pointer to the pointer to the PCI bus resource descriptor
+// EFI_PCI_CONFIGURATION_ADDRESS PciBusAddress Address of the controller on the PCI bus
+// EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase The Phase during resource allocation
+//
+// Output: BOOLEAN
+// TRUE all root bridges belonging to the "Host" has its resources submitted
+// FALSE opposite ...
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsResSubmited(PCI_HOST_BRG_DATA *Host){
+ PCI_ROOT_BRG_DATA *rb;
+ UINTN i;
+//---------------------
+ for(i=0; i<NB_NUMBER_OF_HOST_BRG; i++){
+ rb=Host->RootBridges[i];
+ if(!rb->ResSubmited) return FALSE;
+ }
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetRbByHandle()
+//
+// Description:
+// Lokates
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE RbHandle PCI Root Bridge Handle to get Private data for.
+// UINTN *Index Updated Index of the Found Root Bridge private data
+//
+// Output: PCI_ROOT_BRG_DATA
+// Not NULL if Root was found.
+// NULL if Root was not found.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+PCI_ROOT_BRG_DATA *GetRbByHandle(EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ EFI_HANDLE RbHandle,
+ UINTN *Index OPTIONAL)
+{
+ PCI_HOST_BRG_DATA *hbdata=(PCI_HOST_BRG_DATA*)This;
+ PCI_ROOT_BRG_DATA *rbdata;
+ UINTN i;
+//----------------------------------
+ for(i=0;i<hbdata->RootBridgeCount;i++){
+ rbdata=hbdata->RootBridges[i];
+ if(rbdata->RbHandle==RbHandle){
+ if(Index)(*Index)=i;
+// hbdata->CurrentRb=i;
+ return rbdata;
+ }
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetResources()
+//
+// Description:
+// This function will generate Resource descriptors block based on information
+// stored in RootBridge->RbRes array
+//
+// Input:
+// PCI_HOST_BRG_DATA *Host Pointer to HOST Bridge private data
+// ASLR_QWORD_ASD **Resources Resource List in a form of ACPI QWORD Resource Descriptor.
+// ASLR_TYPE_ENUM ResType Describes what type of resources we are getting.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_OUT_OF_RESOURCES - If SubmitResources ( ) could not allocate resources
+// EFI_NOT_READY - This phase cannot be entered at this time
+// EFI_DEVICE_ERROR - SetResources failed due to HW error.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetResources(PCI_ROOT_BRG_DATA *RootBrg, ASLR_QWORD_ASD **Resources, ASLR_TYPE_ENUM ResType)
+{
+ UINTN i,cnt=0;
+ ASLR_QWORD_ASD *qw;
+ BOOLEAN cpy;
+//---------------------------------1
+ //count descriptors first
+ if(ResType==tResAll) cnt=RootBrg->ResCount;
+ else {
+ for(i=0;i<RootBrg->ResCount;i++){
+ if(ResType==tResBus){
+ if(RootBrg->RbRes[i]->Type == ASLRV_SPC_TYPE_BUS)cnt++;
+ } else {
+ if(RootBrg->RbRes[i]->Type < ASLRV_SPC_TYPE_BUS) cnt++;
+ }
+ }
+ }
+ //if(!cnt) return EFI_NOT_FOUND;
+
+ //Allocate memory for ASL Resource Descriptors
+ qw=Malloc(sizeof(ASLR_QWORD_ASD)*cnt+sizeof(ASLR_EndTag));
+ if(!qw) return EFI_OUT_OF_RESOURCES;
+
+ *Resources=qw;
+
+ //Copy Resource information
+ for(i=0; i<RootBrg->ResCount; i++, cpy=FALSE){
+ if(ResType==tResAll) cpy=TRUE;
+ else {
+ if(ResType==tResBus){
+ if(RootBrg->RbRes[i]->Type == ASLRV_SPC_TYPE_BUS)cpy=TRUE;
+ } else {
+ if(RootBrg->RbRes[i]->Type < ASLRV_SPC_TYPE_BUS) cpy=TRUE;
+ }
+ }
+ if(cpy){
+ MemCpy(qw,RootBrg->RbRes[i],sizeof(ASLR_QWORD_ASD));
+ qw++;
+ }
+ }
+ ((ASLR_EndTag*)qw)->Hdr.HDR=ASLV_END_TAG_HDR;
+ ((ASLR_EndTag*)qw)->Chsum=0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetResources()
+//
+// Description:
+// This function will update RootBridge->RbRes array with Descriptors
+// prowided with *Resources parameter
+//
+// Input:
+// PCI_HOST_BRG_DATA *Host Pointer to HOST Bridge private data
+// ASLR_QWORD_ASD *Resources Resource List in a form of ACPI QWORD Resource Descriptor.
+// ASLR_TYPE_ENUM ResType Describes what type of resources we are getting.
+// BOOLEAN Replace if TRUE function will Remove all descriptors of "ResType" before adding.
+// if FALSE function will just add "Resources"
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_OUT_OF_RESOURCES - If SubmitResources ( ) could not allocate resources
+// EFI_NOT_READY - This phase cannot be entered at this time
+// EFI_DEVICE_ERROR - SetResources failed due to HW error.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetResources(PCI_ROOT_BRG_DATA *RootBrg, ASLR_QWORD_ASD *Resources,
+ ASLR_TYPE_ENUM ResType, BOOLEAN Replace)
+{
+ UINTN i, len, cnt;
+ ASLR_QWORD_ASD *res;
+//---------------------------------
+
+ len=ValidateDescriptorBlock((ASLR_QWORD_ASD*)Resources, ResType, FALSE);
+ if(!len) return EFI_INVALID_PARAMETER;
+
+ cnt=(len-sizeof(ASLR_EndTag))/sizeof(ASLR_QWORD_ASD);
+ //We have received Empty descriptor nothing to do just return.
+ if(!cnt) return EFI_SUCCESS;
+
+ if(Replace){
+ if(ResType==tResAll) ClearItemLst((T_ITEM_LIST*)&RootBrg->ResInitCnt, TRUE);
+ else {
+ i=RootBrg->ResCount;
+ while(i){
+ i--;
+ if(ResType==tResBus){
+ if(RootBrg->RbRes[i]->Type == ASLRV_SPC_TYPE_BUS)
+ DeleteItemLst((T_ITEM_LIST*)&RootBrg->ResInitCnt, i,TRUE);
+ } else {
+ if(RootBrg->RbRes[i]->Type < ASLRV_SPC_TYPE_BUS)
+ DeleteItemLst((T_ITEM_LIST*)&RootBrg->ResInitCnt, i,TRUE);
+ }
+ }
+ }
+ }
+
+ //Update Bus Resources in rbdata
+ for(i=0; i<cnt; i++,Resources++) {
+ res=Malloc(sizeof(ASLR_QWORD_ASD));
+ if(!res) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(res,Resources,sizeof(ASLR_QWORD_ASD));
+
+ if(EFI_ERROR(AppendItemLst((T_ITEM_LIST*)&RootBrg->ResInitCnt,res))) return EFI_OUT_OF_RESOURCES;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsPowerOfTwo()
+//
+// Description:
+// Checks if value passed makes "POWER OF TWO"
+//
+// Input:
+// UINT64 Value Value to check.
+//
+// Output: BOOLEAN
+// TRUE or FALSE based on value passed.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsPowerOfTwo(UINT64 Value){
+ UINTN i;
+ UINT64 t;
+//--------------
+ for(i=0; i<64; i++){
+ t=Shl64(1,(UINT8)i);
+ if(Value&t) {
+ if(Value&(~t))return FALSE;
+ else return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//(EIP45278)>
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AllocateMemoryResource()
+//
+// Description:
+// This function will try to Allocate from GCD set of resources requested by
+// input Length and Alignment.
+//
+// Input:
+// UINTN Alignment Align with 2^Alignment
+// UINT64 Length Length to allocate
+// EFI_PHYSICAL_ADDRESS *BaseAddress Base address to allocate
+// EFI_HANDLE ImageHandle The image handle consume the allocated space.
+// EFI_HANDLE DeviceHandle The device handle consume the allocated space.
+//
+// Output: EFI_STATUS
+// EFI_INVALID_PARAMETER Invalid parameter.
+// EFI_NOT_FOUND No descriptor contains the desired space.
+// EFI_SUCCESS Memory space successfully allocated.
+//
+// EFI_PHYSICAL_ADDRESS *BaseAddress Base address to be allocated
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AllocateMemoryResource (
+ IN UINTN Alignment,
+ IN UINT64 Length,
+ IN OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_HANDLE DeviceHandle
+)
+{
+ EFI_STATUS Status;
+ DXE_SERVICES *dxe;
+ EFI_PHYSICAL_ADDRESS AlignmentMask;
+
+ Status=LibGetDxeSvcTbl(&dxe);
+ if(EFI_ERROR(Status)) return Status;
+
+ AlignmentMask = (1 << Alignment) - 1;
+ // Search an unused for fit the length
+ while (((*BaseAddress + Length) & AlignmentMask)) {
+ Status = dxe->AllocateMemorySpace (
+ EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ 0,
+ Length,
+ BaseAddress,
+ ImageHandle,
+ DeviceHandle);
+ if(EFI_ERROR(Status)) break;
+ // Check if the space is under Alignment
+ if (((*BaseAddress + Length) & AlignmentMask)) {
+ Status = dxe->FreeMemorySpace (*BaseAddress, Length);
+ if(EFI_ERROR(Status)) break;
+ *BaseAddress = ((*BaseAddress + Length) & (~AlignmentMask)) - Length;
+ }
+ }
+ return Status;
+}
+#endif
+//<(EIP45278)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AlignFromGra()
+//
+// Description:
+// Converts C passed into Alignment format
+//
+// Input:
+// UINTN g AlignFromGra Value to convert
+//
+// Output: UINTN
+// Converted Alignment value.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN AlignFromGra(UINTN g){
+ UINTN a=0;
+//------------
+ while(g&1){
+ a++;
+ g=g>>1;
+ }
+ return a;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AllocateResources()
+//
+// Description:
+// This function will try to Allocate from GCD set of resources requested by
+// PCI BUS driver in "*Resources" buffer.
+//
+// Input:
+// PCI_ROOT_BRG_DATA *RootBrg Pointer to ROOT Bridge private data
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_OUT_OF_RESOURCES - If could not allocate resources
+// EFI_DEVICE_ERROR - failed due to HW error.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AllocateResources(PCI_ROOT_BRG_DATA *RootBrg){
+ EFI_STATUS Status=0;
+ EFI_STATUS ReturnStatus = 0;
+ UINTN i;
+ ASLR_QWORD_ASD *res;
+ ACPI_RES_DATA *ar;
+ UINT64 a=0;
+ DXE_SERVICES *dxe;
+//OUT_OF_RES HANDLING++ must be added in Custom Res allocate function.
+#if BoardPciRes_SUPPORT
+ AMI_OUT_OF_RES_VAR OutOfResVar;
+//--------------------------------------
+ //Check if OUT_OF_RES_VAR was already created.
+ Status=AmiPciOutOfRes(&OutOfResVar, TRUE);
+ if(EFI_ERROR(Status)) pBS->SetMem(&OutOfResVar,sizeof(AMI_OUT_OF_RES_VAR),0);
+ else OutOfResVar.Count++;
+#endif
+//OUT_OF_RES HANDLING-- must be added in Custom Res allocate function.
+
+ Status=LibGetDxeSvcTbl(&dxe);
+ if(EFI_ERROR(Status)) return Status;
+
+
+ for(i=0; i<RootBrg->ResCount; i++){
+ res=RootBrg->RbRes[i];
+ if(res->Type==ASLRV_SPC_TYPE_BUS) continue;
+ //Check if Alignment
+ if(!IsPowerOfTwo(res->_MAX+1)) return EFI_INVALID_PARAMETER;
+ switch(res->_GRA){
+ case 16 : a=0xFFFF;//-res->_LEN;
+ break;
+ case 32 : a=0xFFFFFFFF;//-res->_LEN;
+ break;
+ case 64 : a=0xFFFFFFFFFFFFFFFF;//-res->_LEN+1;
+ break;
+ default :ASSERT(0); return EFI_INVALID_PARAMETER;
+ }
+
+ PCI_TRACE((TRACE_PCI,"PciRootBrg:AllocateResources In -> _MIN=0x%lX; _MAX=0x%lX; _LEN=0x%lX; _GRA=0x%lX\n",
+ res->_MIN,res->_MAX,res->_LEN,res->_GRA));
+
+
+ //Allocate IO
+ if(res->Type==ASLRV_SPC_TYPE_IO){
+
+ ar=&RootBrg->AcpiRbRes[raIo];
+ ar->AddrUsed=a;
+ ar->AllocType=EfiGcdAllocateMaxAddressSearchTopDown;
+
+ Status=dxe->AllocateIoSpace(EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdIoTypeIo,
+ AlignFromGra((UINTN)res->_MAX),
+ res->_LEN,
+ &a,
+ RootBrg->ImageHandle, RootBrg->RbHandle);
+
+ if(EFI_ERROR(Status)) {
+ ReturnStatus = Status;
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: IO Allocation Failed: Length: %lX\n",res->_LEN));
+//++OUT_OF_RES!! IO
+#if BoardPciRes_SUPPORT
+ OutOfResVar.Resource=*res;
+ Status=AmiPciOutOfRes(&OutOfResVar, FALSE);
+ return ReturnStatus;
+//--OUT_OF_RES!! IO
+#else
+ continue;
+#endif
+ }
+
+ }
+ //Allocate MMIO
+ else if( res->Type==ASLRV_SPC_TYPE_MEM){
+
+ if(res->_GRA==32)ar=&RootBrg->AcpiRbRes[raMmio32];
+ else ar=&RootBrg->AcpiRbRes[raMmio64];
+ ar->AddrUsed=a;
+ ar->AllocType=EfiGcdAllocateMaxAddressSearchTopDown;
+//(EIP45278)>
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+ Status = AllocateMemoryResource(
+ AlignFromGra((UINTN)res->_MAX),
+ res->_LEN,
+ &a,
+ RootBrg->ImageHandle,
+ RootBrg->RbHandle);
+#else
+ Status=dxe->AllocateMemorySpace(EfiGcdAllocateMaxAddressSearchTopDown,
+ EfiGcdMemoryTypeMemoryMappedIo,
+ AlignFromGra((UINTN)res->_MAX),
+ res->_LEN,
+ &a,
+ RootBrg->ImageHandle, RootBrg->RbHandle);
+#endif
+//<(EIP45278)
+
+ if(EFI_ERROR(Status)) {
+ ReturnStatus = Status;
+ PCI_TRACE((TRACE_PCI,"PciRootBrg: Memory Allocation Failed: Length: %lX\n",res->_LEN));
+//++OUT_OF_RES!! MEM
+#if BoardPciRes_SUPPORT
+ OutOfResVar.Resource=*res;
+ Status=AmiPciOutOfRes(&OutOfResVar, FALSE);
+ return ReturnStatus;
+#else
+//--OUT_OF_RES!! MEM
+ continue;
+#endif
+ }
+
+ //Set this region as WT cache if it is PREFETCHABLE
+ if(res->TFlags.MEM_FLAGS._MEM!=ASLRV_MEM_UC)
+ {
+ //Status=gDxeSvcTbl->SetMemorySpaceAttributes(a,res->_LEN,EFI_MEMORY_WT|EFI_MEMORY_RUNTIME);
+ Status=dxe->SetMemorySpaceAttributes(a,res->_LEN,EFI_MEMORY_WT);
+ //if attempt to set WT attributes has filed, let's try UC
+ if(EFI_ERROR(Status))
+ {
+ PCI_TRACE((TRACE_DXE_CHIPSET,"PciHostBridge: Setting of WT attributes for prefetchable memory has failed(%r). UC is used.\n",Status));
+ //Status=gDxeSvcTbl->SetMemorySpaceAttributes(a,res->_LEN,EFI_MEMORY_UC|EFI_MEMORY_RUNTIME);
+ Status=dxe->SetMemorySpaceAttributes(a,res->_LEN,EFI_MEMORY_UC);
+ }
+ }
+ else Status=dxe->SetMemorySpaceAttributes(a,res->_LEN,EFI_MEMORY_UC);
+ // Status=gDxeSvcTbl->SetMemorySpaceAttributes(a,res->_LEN,EFI_MEMORY_UC|EFI_MEMORY_RUNTIME);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ }
+ res->_MIN=a;
+
+
+ PCI_TRACE((TRACE_PCI,"PciRootBrg:AllocateResources Out-> _MIN=0x%lX; _MAX=0x%lX; _LEN=0x%lX; _GRA=0x%lX\n",
+ res->_MIN,res->_MAX,res->_LEN,res->_GRA));
+
+ //Do some calculation for ACPI _CRS update.
+ if (ar->Min==0) ar->Min=res->_MIN;
+ else {
+ if(ar->Min > res->_MIN)ar->Min=res->_MIN;
+ }
+//(EIP45278+)>
+#if PCI_MMIO_RES_TOP_ALLIGN == 1
+ ar->Gra = 0;
+#else
+ if (ar->Gra==0) ar->Gra=res->_MAX;
+ else {
+ if(ar->Gra<res->_MAX)ar->Gra=res->_MAX;
+ }
+#endif
+//<(EIP45278+)
+ if(ar->Len==0){
+ ar->Len=res->_LEN;
+ if(ar->Len & ar->Gra) ar->Len=(ar->Len |ar->Gra)+1;
+ ar->Max=ar->Min+ar->Len-1;
+ } else {
+ UINT64 max;
+ //--------
+ max=res->_MIN + res->_LEN - 1;
+ if(max>ar->Max)ar->Max=max;
+ ar->Len=ar->Max - ar->Min + 1;
+ if(ar->Len & ar->Gra) ar->Len=(ar->Len |ar->Gra)+1;
+ ar->Max=ar->Min+ar->Len-1;
+ }
+ PCI_TRACE((TRACE_PCI,"PciRootBrg:AcpiResources Min=0x%lX; Max=0x%lX; Len=0x%lX; Gra=0x%lX, AdrUsed=0x%lX\n\n",
+ ar->Min,ar->Max,ar->Len,ar->Gra, ar->AddrUsed));
+
+ //Don't need to set this to actual value it could be calculated using commented formula.
+ //More important to preserve alignment requirements of the resource window.
+ //res->_MAX=res->_MIN+res->_LEN-1;
+ }
+ return ReturnStatus;
+}
+
+
+
+
+//**********************************************************************
+//Pci Host Bridge Resource Allocation Protocol function Implementation
+//**********************************************************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocNotifyPhase()
+//
+//Description: Enter a certain phase of the PCI enumeration process
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase The phase during enumeration
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_OUT_OF_RESOURCES - If SubmitResources ( ) could not allocate resources
+// EFI_NOT_READY - This phase cannot be entered at this time
+// EFI_DEVICE_ERROR - SetResources failed due to HW error.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocNotifyPhase(IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase )
+{
+ PCI_HOST_BRG_DATA *hbdata=(PCI_HOST_BRG_DATA*)This;
+ EFI_STATUS Status=0;
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL **pp;
+ UINTN i;
+//--------------------------------------------------------
+ pp=Malloc(sizeof(VOID*)*hbdata->RootBridgeCount);
+ ASSERT(pp);
+ if(!pp) return EFI_INVALID_PARAMETER;
+
+ for(i=0; i<hbdata->RootBridgeCount; i++) pp[i]=&hbdata->RootBridges[i]->RbIoProtocol;
+
+ switch(Phase){
+ case EfiPciHostBridgeBeginEnumeration:
+ //if(hbdata->AllocPhase!=EfiPciHostBridgeBeginEnumeration) return EFI_INVALID_PARAMETER;
+ Status=HbNotifyCspBeforeEnumeration(&hbdata->ResAllocProtocol, &pp[0], hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return Status;
+ break;
+ case EfiPciHostBridgeBeginBusAllocation:
+ Status=HbNotifyCspBeginBusAllocation(&hbdata->ResAllocProtocol, &pp[0],hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ break;
+ case EfiPciHostBridgeEndBusAllocation:
+ if(hbdata->AllocPhase+1!=Phase) return EFI_INVALID_PARAMETER;
+ Status=HbNotifyCspEndBusAllocation(&hbdata->ResAllocProtocol, &pp[0],hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ break;
+ case EfiPciHostBridgeBeginResourceAllocation:
+ if(hbdata->AllocPhase+1!=Phase) return EFI_INVALID_PARAMETER;
+ Status=HbNotifyCspBeginResourceAllocation(&hbdata->ResAllocProtocol, &pp[0],hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ break;
+ case EfiPciHostBridgeAllocateResources:
+ if(hbdata->AllocPhase+1!=Phase) return EFI_INVALID_PARAMETER;
+ if(!IsResSubmited(hbdata)) return EFI_NOT_READY;
+ Status=HbNotifyCspAllocateResources(&hbdata->ResAllocProtocol, &pp[0],hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ break;
+ case EfiPciHostBridgeSetResources:
+ if(hbdata->AllocPhase+1!=Phase) return EFI_INVALID_PARAMETER;
+ if(!IsResSubmited(hbdata)) return EFI_NOT_READY;
+ Status=HbNotifyCspSetResources(&hbdata->ResAllocProtocol, &pp[0],hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ break;
+ case EfiPciHostBridgeFreeResources:
+ return EFI_UNSUPPORTED;
+ break;
+ case EfiPciHostBridgeEndResourceAllocation:
+ if(hbdata->AllocPhase+2!=Phase) return EFI_INVALID_PARAMETER;
+ Status=HbNotifyCspEndResourceAllocation(&hbdata->ResAllocProtocol, &pp[0],hbdata->RootBridgeCount);
+ ASSERT_EFI_ERROR(Status);
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+
+ if(EFI_ERROR(Status)) return Status;
+ hbdata->AllocPhase=Phase;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocGetNextRootBridge()
+//
+// Description:
+// Return the device handle of the next PCI root bridge that is
+// associated with this Host Bridge.
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE *RootBridgeHandle Returns the device handle
+// of the next PCI Root Bridge. On input, it holds the RootBridgeHandle
+// returned by the most recent call to GetNextRootBridge().
+// The handle for the first PCI Root Bridge is returned if RootBridgeHandle
+// is NULL on input.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocGetNextRootBridge(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN OUT EFI_HANDLE *RootBridgeHandle)
+{
+ PCI_HOST_BRG_DATA *hbdata=(PCI_HOST_BRG_DATA*)This;
+ PCI_ROOT_BRG_DATA *rbdata;
+ UINTN i=0;
+//--------------------------------------------------
+ if(!This) return EFI_INVALID_PARAMETER;
+ if(*RootBridgeHandle==NULL) {
+ rbdata=hbdata->RootBridges[i];
+ *RootBridgeHandle=rbdata->RbHandle;
+ return EFI_SUCCESS;
+ } else {
+ rbdata=GetRbByHandle(This,*RootBridgeHandle,&i);
+ if(!rbdata) return EFI_INVALID_PARAMETER;
+ if(hbdata->RootBridgeCount-1>i){
+ rbdata=hbdata->RootBridges[i+1];
+ *RootBridgeHandle=rbdata->RbHandle;
+ return EFI_SUCCESS;
+ } else return EFI_NOT_FOUND;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocGetAllocAttributes()
+//
+// Description:
+// Returns the attributes of a PCI Root Bridge.
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE RootBridgeHandle The device handle of the PCI Root Bridge
+// that the caller is interested in
+// UINT64 Attribute The pointer to attributes of the PCI Root Bridge
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+// EFI_INVALID_PARAMETER - Attributes is NULL
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocGetAllocAttributes(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT UINT64 *Attributes)
+{
+ PCI_ROOT_BRG_DATA *rbdata;
+//----------------------------------
+ if(!This || !Attributes) return EFI_INVALID_PARAMETER;
+ rbdata=GetRbByHandle(This,RootBridgeHandle,NULL);
+ if(!rbdata)return EFI_INVALID_PARAMETER;
+ else *Attributes=rbdata->Owner->AllocAttrib;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocStartBusEnumeration()
+//
+// Description:
+// This is the request from the PCI enumerator to set up
+// the specified PCI Root Bridge for bus enumeration process.
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This PROTOCOL instance
+// EFI_HANDLE RootBridgeHandle PCI Root Bridge to be configured
+// VOID **Configuration Pointer to the pointer to the PCI bus resource descriptor
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+// EFI_DEVICE_ERROR - Request failed due to hardware error
+// EFI_OUT_OF_RESOURCES - Request failed due to lack of resources
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocStartBusEnumeration(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration)
+{
+ PCI_ROOT_BRG_DATA *rbdata;
+ UINTN i;
+ EFI_STATUS Status;
+ ASLR_QWORD_ASD *qw;
+//-----------------------------
+ if(!Configuration || !This) return EFI_INVALID_PARAMETER;
+
+
+ rbdata=GetRbByHandle(This,RootBridgeHandle,&i);
+ if(!rbdata){
+ PCI_TRACE((TRACE_PCI,"Hb.StartBusEnumeration - Invalid Rb Handle Passed\n"));
+ ASSERT(rbdata);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //ThisCSP Function MIGHT Update rbdata->RbRes[] with bus ranges to scan
+ //and program corresponded RB registers to decode this ranges.
+ //If function overwrites BUS ranges this ROOT decodes IT MUST UPDATE rbdata->RbRes[]!
+ //If NOT it should not touch BUS resource descriptor.
+ Status=HbCspStartBusEnumeration((PCI_HOST_BRG_DATA*)This, rbdata,i);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.StartBusEnumeration - HbCspUpdateBusesBefore returned ERROR!\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ Status=GetResources(rbdata, (ASLR_QWORD_ASD**)Configuration, tResBus);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.StartBusEnum - RB Resources Invalid!\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ qw=(ASLR_QWORD_ASD*)*Configuration;
+
+ PCI_TRACE((TRACE_PCI,"PciRb#%d: Enumerating Buses 0x%lX - 0x%lX \n", i, qw->_MIN, qw->_MIN+qw->_LEN-1));
+ PCI_TRACE((TRACE_PCI,"=====================================================================\n\n"));
+
+
+ ((PCI_HOST_BRG_DATA*)This)->EnumStarted=TRUE;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocSetBusNumbers()
+//
+// Description:
+// This function programs the PCI Root Bridge hardware so that
+// it decodes the specified PCI bus range
+//
+//Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE RootBridgeHandle PCI Root Bridge to be configured
+// VOID **Configuration Pointer to the pointer to the PCI bus resource descriptor
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+// EFI_INVALID_PARAMETER - Configuration is NULL
+// EFI_INVALID_PARAMETER - Configuration does not point to a valid ACPI resource descriptor
+// EFI_INVALID_PARAMETER - Configuration contains one or more memory or IO ACPI resource descriptor
+// EFI_INVALID_PARAMETER - Address Range Minimum or Address Range Length fields in Configuration
+// are invalid for this Root Bridge.
+// EFI_INVALID_PARAMETER - Configuration contains one or more invalid ACPI resource descriptor
+// EFI_DEVICE_ERROR - Request failed due to hardware error
+// EFI_OUT_OF_RESOURCES - Request failed due to lack of resources
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocSetBusNumbers(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration)
+{
+ PCI_ROOT_BRG_DATA *rbdata;
+ UINTN i;
+ EFI_STATUS Status;
+ ASLR_QWORD_ASD *qw=(ASLR_QWORD_ASD*)Configuration;
+//-----------------------------
+ if(!Configuration || !This) return EFI_INVALID_PARAMETER;
+
+ rbdata=GetRbByHandle(This,RootBridgeHandle,&i);
+ if(!rbdata) {
+ PCI_TRACE((TRACE_PCI,"Hb.SetBusNumbers - Invalid RB Hndle Passed\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status=SetResources(rbdata, Configuration, tResBus, TRUE);
+
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.SetBusNumbers - Invalid Resoutce Descriptor(s) Passed\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ //Call CSP function to update RB Buses accordinaly submited information
+ Status=HbCspSetBusNnumbers((PCI_HOST_BRG_DATA*)This, rbdata, i);
+
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.SetBusNumbers - HbCspUpdateBusesAfter returned ERROR!\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+ PCI_TRACE((TRACE_PCI,"PciRb#%d: Assigning Buses 0x%lX - 0x%lX \n", i, qw->_MIN, qw->_MIN+qw->_LEN-1));
+
+
+ rbdata->BusesSet=TRUE;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FreeUsedResources()
+//
+// Description:
+// Cleans internal RB data and free resources allocated trough GCD.
+//
+// Input:
+// PCI_ROOT_BRG_DATA *RootBrg Pointer to RB Private data.
+//
+// Output: NONE
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FreeUsedResources(PCI_ROOT_BRG_DATA *RootBrg){
+ ASLR_QWORD_ASD *res;
+ UINTN i;
+ DXE_SERVICES *dxe;
+ EFI_STATUS Status;
+//------------------------------
+ Status=LibGetDxeSvcTbl(&dxe);
+ ASSERT_EFI_ERROR(Status);
+
+ for(i=0; i<RootBrg->ResCount; i++){
+ res=RootBrg->RbRes[i];
+
+ //Clean only IO and MMIO resources buses was submitted in different call and must stay.
+ if(res->Type < ASLRV_SPC_TYPE_BUS){
+ if(res->_MIN != 0){
+ //Free IO
+ if(res->Type==ASLRV_SPC_TYPE_IO){
+ Status=dxe->FreeIoSpace(res->_MIN, res->_LEN);
+ } else {
+ Status=dxe->FreeMemorySpace(res->_MIN, res->_LEN);
+ }
+ ASSERT_EFI_ERROR(Status);
+ } //res_MIN
+ //Don't free resource list, it will be reupdated with RPLACE option.
+ }
+ } //for
+
+ //Almost done now clean AcpiRbRes[] data
+ pBS->SetMem(&RootBrg->AcpiRbRes[0], sizeof(RootBrg->AcpiRbRes),0);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocSubmitResources()
+//
+// Description:
+// Submits the I/O and memory resource requirements for the specified PCI Root Bridge
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE RootBridgeHandle PCI Root Bridge to be configured
+// VOID **Configuration Pointer to the pointer to the PCI bus resource descriptor
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+// EFI_INVALID_PARAMETER - Configuration is NULL
+// EFI_INVALID_PARAMETER - Configuration does not point to a valid ACPI resource descriptor
+// EFI_INVALID_PARAMETER - Configuration includes a resource descriptor of unsupported type
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocSubmitResources(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN VOID *Configuration)
+{
+ PCI_ROOT_BRG_DATA *rbdata;
+ UINTN i, sz=sizeof(UINT32);
+ EFI_STATUS Status,AllocStatus;
+// UINT32 mc; //MemCeil Variable Available?
+// EFI_GUID gvg = EFI_GLOBAL_VARIABLE;
+ ASLR_EndTag *endtag=(ASLR_EndTag*)Configuration;
+//-----------------------------
+ if(!Configuration || !This) return EFI_INVALID_PARAMETER;
+
+ rbdata=GetRbByHandle(This,RootBridgeHandle,&i);
+ if(!rbdata) {
+ PCI_TRACE((TRACE_PCI,"Hb.SubmitResources - Invalid RB Hndle Passed\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Update Internal data structures with Resource Request
+ Status=SetResources(rbdata, Configuration, tResIoMem, TRUE);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.SubmitResources - Invalid Resoutce Descriptor(s) Passed\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+
+
+ //Call CSP function to update RB Resources Windows
+ Status=HbCspSubmitResources((PCI_HOST_BRG_DATA*)This, rbdata,i);
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.SubmitResources - HbCspSubmitResources return an ERROR!\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+ rbdata->ResSubmited=TRUE; //set the FLAG
+
+ //Check if we are able to accomodate resource request
+ //CSP Routine First...
+ PCI_TRACE((TRACE_PCI,"PciRb: Calling CSP HbCspAllocateResources() - returned "));
+ AllocStatus=HbCspAllocateResources((PCI_HOST_BRG_DATA*)This, rbdata,i);
+ PCI_TRACE((TRACE_PCI,"%r\n", AllocStatus));
+
+ if(EFI_ERROR(AllocStatus)){
+ if( AllocStatus==EFI_UNSUPPORTED ){
+ PCI_TRACE((TRACE_PCI,"PciRb: Calling Generic AllocateResources() routine; returned "));
+ AllocStatus=AllocateResources(rbdata);
+ PCI_TRACE((TRACE_PCI,"%r\n", AllocStatus));
+ }
+ //If custom function Fails or Generic on report it.
+ if(EFI_ERROR(AllocStatus)){
+ PCI_TRACE((TRACE_PCI,"Hb.SubmitResources - Fail to allocate resources AllocStatus=%r\n",AllocStatus));
+ }
+ } else {
+ //Custom function Returned Correct Status:
+ //Check if Above 4G Memory was correctly updated by custom function
+ //and if it match with Above4g setup question?
+ if((gRbSetupData.Above4gDecode==0) && (rbdata->AcpiRbRes[raMmio64].Len!=0)){
+ rbdata->AcpiRbRes[raMmio64].Min=0;
+ rbdata->AcpiRbRes[raMmio64].Max=0;
+ rbdata->AcpiRbRes[raMmio64].Len=0;
+ rbdata->AcpiRbRes[raMmio64].AddrUsed=0;
+ rbdata->AcpiRbRes[raMmio64].AllocType=0;
+ PCI_TRACE((TRACE_PCI,"PciRB: PCI Above 4G Decode Setup Settings and Custom Alloc Function Data Mismatched\n"));
+ }
+ }
+
+ //Check if we can use previoce MRC settings
+ //if(!mc || EFI_ERROR(Status)){
+ Status = HbCspAdjustMemoryMmioOverlap((PCI_HOST_BRG_DATA*)This, rbdata,i );
+
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.SubmitResources - AdjustMmioOverlap() returned %r\n",Status));
+ //AdjustMmioOverlap() must return SUCCESS or Reset the system...
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ //Reflecting What TYPE and HOW MUCH of resouces is not enough...
+ if(EFI_ERROR(AllocStatus)) {
+ ((PCI_HOST_BRG_DATA*)This)->AllocPhase--;
+ FreeUsedResources(rbdata);
+ Status=AllocStatus;
+ }
+
+ if(EFI_ERROR(Status))return Status;
+
+ rbdata->ResAsquired=TRUE; //set the FLAG
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocGetProposedResources()
+//
+// Description:
+// This function returns the proposed resource settings for the specified
+// PCI Root Bridge
+//
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE RootBridgeHandle PCI Root Bridge to be configured
+// VOID **Configuration Pointer to the pointer to the PCI bus resource descriptor
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+// EFI_DEVICE_ERROR - Request failed due to hardware error
+// EFI_OUT_OF_RESOURCES - Request failed due to lack of resources
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocGetProposedResources(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ OUT VOID **Configuration)
+{
+/*
+ PCI_ROOT_BRG_DATA *rbdata;
+ UINTN i;
+ EFI_STATUS Status;
+//-----------------------------
+ if(!Configuration || !This) return EFI_INVALID_PARAMETER;
+
+ rbdata=GetRbByHandle(This,RootBridgeHandle,&i);
+ if(!rbdata) {
+ PCI_TRACE((TRACE_PCI,"Hb.GetProposedResources - Invalid RB Hndle Passed\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //Call CSP function to update RB Resources Windows
+ Status=HbCspGetProposedResources((PCI_HOST_BRG_DATA*)This, rbdata,i);
+
+ if(EFI_ERROR(Status)){
+ PCI_TRACE((TRACE_PCI,"Hb.GetProposedResources - HbCspGetProposedResources return an ERROR!\n"));
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+ }
+*/
+
+
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//
+// implement this function
+//
+//
+//
+//
+//
+//
+//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//TODO//
+
+
+ return EFI_UNSUPPORTED;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HbResAllocPreprocessController()
+//
+// Description:
+// This function is called for all the PCI controllers that the PCI
+// bus driver finds. Can be used to Preprogram the controller.
+//
+//Arguments:
+// Input:
+// EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This Protocol instance
+// EFI_HANDLE RootBridgeHandle PCI Root Bridge to be configured
+// EFI_PCI_CONFIGURATION_ADDRESS PciBusAddress Address of the controller on the PCI bus
+// EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase The Phase during resource allocation
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Success
+// EFI_INVALID_PARAMETER - RootBridgeHandle is invalid
+// EFI_DEVICE_ERROR - Device pre-initialization failed due to hardware error.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HbResAllocPreprocessController(
+ IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PROTOCOL *This,
+ IN EFI_HANDLE RootBridgeHandle,
+ IN EFI_PCI_CONFIGURATION_ADDRESS PciAddress,
+ IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase)
+{
+// EFI_STATUS Status=0;
+ UINTN i;
+ PCI_ROOT_BRG_DATA *rb;
+//-----------------------------------
+ rb=GetRbByHandle(This,RootBridgeHandle,&i);
+ ASSERT(rb)
+ if(!rb) return EFI_INVALID_PARAMETER;
+ //Call CSP function...
+ return HbCspPreprocessController((PCI_HOST_BRG_DATA*)This,rb,i,PciAddress,Phase);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetTmr()
+//
+// Description:
+// Enables timer event to poll PCI IO and MEMORY.
+//
+//Arguments:
+// Input:
+// UINT64 Delay Delay value in us
+//
+// Output: EFI_EVENT if Success
+// NULL if unable to set timer event.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_EVENT SetTmr(UINT64 Delay)
+{
+ EFI_STATUS Status;
+ EFI_EVENT evt;
+//--------------------------------------------
+ Status=pBS->CreateEvent(EVT_TIMER,TPL_NOTIFY,NULL,NULL,&evt);
+ if (EFI_ERROR(Status)) return NULL;
+
+
+ Status = pBS->SetTimer(evt, TimerRelative, Delay);
+ if (EFI_ERROR(Status)){
+ pBS->CloseEvent(evt);
+ evt=NULL;
+ }
+ return evt;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: KillTmr()
+//
+// Description:
+// Disables and Clear timer event to poll PCI IO and MEMORY.
+//
+//Arguments:
+// Input:
+// EFI_EVENT TmrEvt Timer event to close.
+//
+// Output: Nothing
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void KillTmr(EFI_EVENT TmrEvt)
+{
+ pBS->CloseEvent(TmrEvt);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PollMem
+//
+// Description: Poll Memory for a value or until times out.
+//
+// Input: IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * - This
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH - Memory Width
+// IN UINT64 - Memory Address
+// IN UINT64 - Bit Mask
+// IN UINT64 - Value for exit
+// IN UINT64 - Timout
+// OUT UINT64 * - Contents of memory
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Found value
+// EFI_TIMEOUT - Did not find value.
+// EFI_INVALID_PARAMETER
+//
+// Modified: None
+//
+// Referrals: None
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PollMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result)
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ if (Result==NULL ||((UINTN)Width>=(UINTN)EfiPciWidthFifoUint8)) return EFI_INVALID_PARAMETER;
+
+ Status = PciMemRead(This, Width, Address, 1, Result); //Read memory at least once.
+ if (EFI_ERROR(Status)) return Status;
+
+ if ((*Result & Mask)==Value) return EFI_SUCCESS; //If correct value, exit.
+ if (Delay == 0) return EFI_TIMEOUT;
+
+ Event=SetTmr(Delay);
+ if (!Event) return EFI_NOT_AVAILABLE_YET;
+
+ while(pBS->CheckEvent(Event)==EFI_NOT_READY){
+ Status = PciMemRead(This, Width, Address, 1, Result);
+ if (EFI_ERROR(Status)) break;
+ if ((*Result & Mask)==Value){
+ Status = EFI_SUCCESS;
+ break;
+ } else Status=EFI_TIMEOUT; //correct value?
+ }
+ KillTmr(Event); //Correct value not read, in time alloted.
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PollIo
+//
+// Description: Poll IO for a value or until times out.
+//
+// Input: IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * - This
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH - Memory Width
+// IN UINT64 - Memory Address
+// IN UINT64 - Bit Mask
+// IN UINT64 - Value for exit
+// IN UINT64 - Timout
+// OUT UINT64 * - Contents of IO
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Found value
+// EFI_TIMEOUT - Did not find value.
+// EFI_INVALID_PARAMETER
+//
+// Modified: None
+//
+// Referrals: None
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PollIo (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT64 Mask,
+ IN UINT64 Value,
+ IN UINT64 Delay,
+ OUT UINT64 *Result)
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ if (Result==NULL) return EFI_INVALID_PARAMETER;
+ if ((UINTN)Width >= (UINTN)EfiPciWidthFifoUint8) return EFI_INVALID_PARAMETER;
+
+
+ Status = PciIoRead(This, Width, Address, 1, Result); //Read memory at least once.
+ if (EFI_ERROR(Status)) return Status;
+
+ if ((*Result & Mask)==Value) return EFI_SUCCESS; //If correct value, exit.
+ if (Delay == 0) return EFI_TIMEOUT;
+
+ Event=SetTmr(Delay);
+ if (!Event) return EFI_NOT_AVAILABLE_YET;
+
+ while(pBS->CheckEvent(Event)==EFI_NOT_READY){
+ Status = PciIoRead(This, Width, Address, 1, Result);
+ if (EFI_ERROR(Status)) break;
+ if ((*Result & Mask)==Value){
+ Status = EFI_SUCCESS;
+ break;
+ } else Status=EFI_TIMEOUT; //correct value?
+ }
+ KillTmr(Event); //Correct value not read, in time alloted.
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciMemRead
+//
+// Description: Read memory IO into buffer.
+//
+// Input: IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * - This
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH - Memory Width
+// IN UINT64 - Memory Address
+// IN UINTN - Number of width reads.
+// IN OUT VOID * - Buffer where memory is read into.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful read.
+// EFI_INVALID_PARAMETER
+//
+// Modified: None
+//
+// Referrals: None
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciMemRead (
+IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+IN UINT64 Address,
+IN UINTN Count,
+IN OUT VOID *Buffer)
+{
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3); //1st 2 bits currently define width. Other bits define type.
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+
+ if (Buffer==NULL || ((UINTN)Width>=(UINTN)EfiPciWidthMaximum)) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 8) return EFI_INVALID_PARAMETER;
+
+ if(sizeof(UINTN)==8){
+ if (( 0xffffffffffffffff - Count * IncrementValue) <= Address)
+ return EFI_INVALID_PARAMETER;
+ } else {
+ if ((Address + Count * IncrementValue) > 0xffffffff)
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (IncrementType)
+ {
+ case 0: //EfiPciWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiPciWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiPciWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: //byte
+ *(UINT8*) Buffer = *(UINT8*)Address;
+ break;
+ case 2: //word
+ *(UINT16*) Buffer = *(UINT16*)Address;
+ break;
+ case 4: //dword
+ *(UINT32*) Buffer = *(UINT32*)Address;
+ break;
+ case 8: //dword
+ *(UINT64*) Buffer = *(UINT64*)Address;
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciMemWrite
+//
+// Description: Write memory IO from buffer.
+//
+// Input: IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * - This
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH - Memory Width
+// IN UINT64 - Memory Address
+// IN UINTN - Number of width writes.
+// IN OUT VOID * - Buffer where memory is written from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful write.
+// EFI_INVALID_PARAMETER
+//
+// Modified: None
+//
+// Referrals: None
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciMemWrite (
+IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+IN UINT64 Address,
+IN UINTN Count,
+IN OUT VOID *Buffer)
+{
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3); //1st 2 bits currently define width. Other bits define type.
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+
+ if (Buffer==NULL || ((UINTN)Width>=(UINTN)EfiPciWidthMaximum)) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 8) return EFI_INVALID_PARAMETER;
+
+ if ((Address + Count * IncrementValue) > 0xffffffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ switch (IncrementType)
+ {
+ case 0: //EfiPciWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiPciWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiPciWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: //byte
+ *(UINT8*) Address = *(UINT8*)Buffer;
+ break;
+ case 2: //word
+ *(UINT16*) Address = *(UINT16*)Buffer;
+ break;
+ case 4: //dword
+ *(UINT32*) Address = *(UINT32*)Buffer;
+ break;
+ case 8: //dword
+ *(UINT64*) Address = *(UINT64*)Buffer;
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciIoRead
+//
+// Description: Read IO into buffer.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL * - This
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH - Io Width
+// IN UINT64 - Io Address
+// IN UINTN - Number of width reads.
+// IN OUT VOID * - Buffer where Io is read into.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful read.
+// EFI_INVALID_PARAMETER
+//
+// Modified: None
+//
+// Referrals: None
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoRead (
+IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+IN UINT64 Address,
+IN UINTN Count,
+IN OUT VOID *Buffer)
+{
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3); //1st 2 bits currently define width. Other bits define type.
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+
+ if (Buffer==NULL || ((UINTN)Width>=(UINTN)EfiPciWidthMaximum)) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 8) return EFI_INVALID_PARAMETER;
+
+ if ((Address + Count * IncrementValue) > 0xffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ switch (IncrementType)
+ {
+ case 0: //EfiPciWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiPciWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiPciWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: //byte
+ *(UINT8*) Buffer = IoRead8((UINT16)Address);
+ break;
+ case 2: //word
+ *(UINT16*) Buffer = IoRead16((UINT16)Address);
+ break;
+ case 4: //dword
+ *(UINT32*) Buffer = IoRead32((UINT16)Address);
+ break;
+ case 8:
+ *(UINT32*) Buffer = IoRead32((UINT16)Address);
+ *((UINT32*)((UINT32*)Buffer+1)) = IoRead32((UINT16)(Address+4));
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciIoWrite
+//
+// Description: Write IO from buffer.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol instance
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width Pci Width
+// IN UINT64 Address IO Address
+// IN UINTN Count Number of width writes.
+// IN OUT VOID *Buffer where Pci registers are written from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful write.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciIoWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3); //1st 2 bits currently define width. Other bits define type.
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+
+ if (Buffer==NULL || ((UINTN)Width>=(UINTN)EfiPciWidthMaximum)) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 4) return EFI_INVALID_PARAMETER;
+
+ if ((Address + Count * IncrementValue) > 0xffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ switch (IncrementType)
+ {
+ case 0: //EfiPciWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiPciWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiPciWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: //byte
+ IoWrite8((UINT16)Address,*(UINT8*) Buffer);
+ break;
+ case 2: //word
+ IoWrite16((UINT16)Address,*(UINT16*) Buffer);
+ break;
+ default: //dword
+ IoWrite32((UINT16)Address,*(UINT32*) Buffer);
+ break;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CopyMem
+//
+// Description: Copy PCI memory to PCI memory in bridge.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol instance
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width Pci Width
+// IN UINT64 DestAddress Pci Address
+// IN UINT64 SrcAddress Pci Address
+// IN UINTN Count Number of width writes.
+// IN OUT VOID *Buffer where Pci registers are written from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful copy.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CopyMem (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 DestAddress,
+ IN UINT64 SrcAddress,
+ IN UINTN Count)
+{
+ INTN IncrementValue;
+
+ if ((SrcAddress == 0) || (DestAddress==0)) return EFI_INVALID_PARAMETER;
+ if ((UINTN)Width > (UINTN)EfiPciWidthUint64) return EFI_INVALID_PARAMETER;
+
+ IncrementValue = (INTN)1<<(Width&3);
+ if ((SrcAddress + Count * IncrementValue) > 0xffffffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ if ((DestAddress + Count * IncrementValue) > 0xffffffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+
+ if (SrcAddress==DestAddress) return EFI_SUCCESS; //Nothing to do.
+
+
+ if ( (DestAddress > SrcAddress) && (SrcAddress + Count * IncrementValue) ) {
+ SrcAddress += (Count-1) * IncrementValue; //End of source
+ DestAddress += (Count-1) * IncrementValue; //End of destination
+ IncrementValue = -IncrementValue; //Count backwards.
+ } //If Destination addres and after and overlapps Source Address, Copy backwards.
+
+ switch(IncrementValue)
+ {
+ case 1:
+ case -1:
+ while (Count--)
+ {
+ *(UINT8*) DestAddress = *(UINT8*)SrcAddress;
+ SrcAddress += IncrementValue;
+ DestAddress += IncrementValue;
+ }
+ break;
+ case 2:
+ case -2:
+ while (Count--)
+ {
+ *(UINT16*) DestAddress = *(UINT16*)SrcAddress;
+ SrcAddress += IncrementValue;
+ DestAddress += IncrementValue;
+ }
+ break;
+ default:
+ while (Count--)
+ {
+ *(UINT32*) DestAddress = *(UINT32*)SrcAddress;
+ SrcAddress += IncrementValue;
+ DestAddress += IncrementValue;
+ }
+ break;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciRead()
+//
+// Description:
+// Read Pci registers into buffer.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol instance
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width Pci Width
+// IN UINT64 Address Pci Address
+// IN UINTN Count Number of width writes.
+// IN OUT VOID *Buffer where Pci registers are written from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful read.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciRead (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ PCI_ROOT_BRG_DATA *Private = (PCI_ROOT_BRG_DATA*)This;
+
+ if (Buffer == NULL ||((UINTN)Width>=(UINTN)EfiPciWidthMaximum) ) return EFI_INVALID_PARAMETER;
+
+ return RootBridgeIoPciRW (Private, Width, Address, Count, Buffer, FALSE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciWrite()
+//
+// Description:
+// Write Pci registers from buffer.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol instance
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width Pci Width
+// IN UINT64 Address Pci Address
+// IN UINTN Count Number of width writes.
+// IN OUT VOID *Buffer where Pci registers are written from.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful write.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciWrite (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer)
+{
+ PCI_ROOT_BRG_DATA *Private = (PCI_ROOT_BRG_DATA*)This;
+
+ if (Buffer == NULL || ((UINTN)Width>=(UINTN)EfiPciWidthMaximum)) return EFI_INVALID_PARAMETER;
+
+ Private = (PCI_ROOT_BRG_DATA *) This;
+
+ return RootBridgeIoPciRW (Private, Width, Address, Count, Buffer, TRUE);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Map()
+//
+// Description:
+// Provide addresses required to access system memory from a DMA
+// bus master.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation
+// IN VOID *HostAddress Host address
+// IN OUT UINTN **NumberOfBytes Number of bytes
+// OUT EFI_PHYSICAL_ADDRESS *DeviceAddress Device Address
+// OUT VOID **Mapping
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful map
+//
+// Modified: None
+//
+// Referrals: None
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Map (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_OPERATION Operation,
+ IN VOID *HostAddress,
+ IN OUT UINTN *NumberOfBytes,
+ OUT EFI_PHYSICAL_ADDRESS *DeviceAddress,
+ OUT VOID **Mapping)
+{
+ EFI_STATUS Status;
+// PCI_ROOT_BRIDGE_MAPPING *mapping;
+ EFI_PHYSICAL_ADDRESS addr;
+//-------------------------------------------------
+
+ if ( !HostAddress || !NumberOfBytes || !DeviceAddress || !Mapping )
+ return EFI_INVALID_PARAMETER;
+
+ if ((UINT32)Operation >= (UINT32)EfiPciOperationMaximum ) return EFI_INVALID_PARAMETER;
+
+ *Mapping=NULL;
+
+ addr=(EFI_PHYSICAL_ADDRESS) (UINTN) HostAddress;
+
+ if ((addr + *NumberOfBytes) > 0xffffffff)Status=RbCspIoPciMap((PCI_ROOT_BRG_DATA*)This,
+ Operation, addr, NumberOfBytes, DeviceAddress, Mapping);
+ else *DeviceAddress = addr;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Unmap
+//
+// Description: Remove mapping
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+// IN VOID *Mapping Pointer to Mapping formation to Unmap
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful unmapping.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Unmap (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN VOID *Mapping)
+
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ PCI_ROOT_BRIDGE_MAPPING *mapping=(PCI_ROOT_BRIDGE_MAPPING*)Mapping;
+//-------
+
+ if (mapping!=NULL) Status=RbCspIoPciUnmap((PCI_ROOT_BRG_DATA*)This,mapping);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AllocateBuffer
+//
+// Description: Allocate buffer for PCI use.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+// IN EFI_ALLOCATE_TYPE Type Alloocation Type (ignored and uses AllocateMaxAddress)
+// IN EFI_MEMORY_TYPE MemoryType Memory Type (ex. EfiBootServicesData)
+// IN UINTN Pages Number of pages to allocate.
+// OUT VOID **HostAddress Host Address
+// IN UINT64 Attributes Allocation Attributes.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful allocation.
+// EFI_UNSUPPORTED - Attribute not supported.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#define BUFF_ATTR (EFI_PCI_ATTRIBUTE_MEMORY_WRITE_COMBINE |\
+ EFI_PCI_ATTRIBUTE_MEMORY_CACHED |\
+ EFI_PCI_ATTRIBUTE_DUAL_ADDRESS_CYCLE)
+//---------------------------------------------------------------
+EFI_STATUS AllocateBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN Pages,
+ OUT VOID **HostAddress,
+ IN UINT64 Attributes)
+
+{
+ //PCI_ROOT_BRIDGE_STRUCT *Private = (PCI_ROOT_BRIDGE_STRUCT *)This;
+
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS addr;
+
+ if (HostAddress == NULL) return EFI_INVALID_PARAMETER;
+
+ // The only valid memory types are EfiBootServicesData and EfiRuntimeServicesData
+ if (MemoryType != EfiBootServicesData && MemoryType != EfiRuntimeServicesData)
+ return EFI_INVALID_PARAMETER;
+
+ //Check if legal Attributes for this function is passed
+ //Check if any other Attributes set except supported
+ if( Attributes & ~BUFF_ATTR ) return EFI_UNSUPPORTED;
+
+
+ //865 chipset does not support any of Attributes above so as spec. says ignore it
+ //and Allocate buffer
+ // Limit allocations to memory below 4GB
+ addr = 0xffffffff;
+
+ Status = pBS->AllocatePages (AllocateMaxAddress, MemoryType, Pages, &addr);
+ if (EFI_ERROR(Status)) return Status;
+
+ *HostAddress = (VOID *)(UINTN)addr;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FreeBuffer()
+//
+// Description: Frees buffer
+//
+// Input: IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+// IN UINTN Pages Number of pages to free.
+// IN VOID* HostAddress Host Address
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful free.
+// EFI_INVALID_PARAMETER
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FreeBuffer (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINTN Pages,
+ IN VOID *HostAddress)
+
+{
+ return pBS->FreePages((EFI_PHYSICAL_ADDRESS) HostAddress, Pages);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Flush()
+//
+// Description:
+// Flush buffer used by PCI DMA Transfere.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful flushing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Flush (IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This)
+{
+ return EFI_SUCCESS; //Doesn't need buffer to be flushed.
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetAttributes()
+//
+// Description: Get Supported and Current Root Bridge Attributes.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+// OUT UINT64 *Supported Supported Attributes
+// OUT UINT64 *Attributes Current Attributes
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - Successful reading attributes.
+// EFI_INVALID_PARAMETER - If both for attributes are invalid.
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT UINT64 *Supported,
+ OUT UINT64 *Attributes)
+{
+ PCI_ROOT_BRG_DATA *Private = (PCI_ROOT_BRG_DATA*) This;
+
+ if (Attributes == NULL && Supported == NULL) return EFI_INVALID_PARAMETER;
+
+ if (Supported) *Supported = Private->Supports;
+ if (Attributes) *Attributes = Private->Attributes;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetAttributes()
+//
+// Description: Get Supported and Current Root Bridge Attributes.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+// IN UINT64 Attributes
+// IN OUT UINT64 *ResourceBase Resource Base (optional, unused)
+// IN OUT UINT64 *ResourceLength Resource Length (optional, unused)
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS Successful setting attributes.
+// EFI_UNSUPPORTED Unsupported attributes
+//
+// Notes: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetAttributes (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN UINT64 Attributes,
+ IN OUT UINT64 *ResourceBase,
+ IN OUT UINT64 *ResourceLength)
+{
+ EFI_STATUS Status;
+ PCI_ROOT_BRG_DATA *Private = (PCI_ROOT_BRG_DATA *) This;
+//------------------------------------
+
+
+ //First Check if RB supports passed Attributes
+ if((Attributes & Private->Supports)!=Attributes)return EFI_UNSUPPORTED;
+
+ //Note: Only some attributes can be both enabled and disabled.
+
+ Status=RbCspIoPciAttributes(Private, Attributes, ResourceBase, ResourceLength);
+
+ if(EFI_ERROR(Status)) return Status;
+
+ //Update the attributes property
+ //Private->Attributes&=Attributes; //reset all bits that has to be reseted
+ Private->Attributes |= Attributes; //set bits that has to be seted
+
+ return Status;
+}
+//--------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Configuration()
+//
+// Description: Returns, using ACPI 2.0 Descriptors, resources allocated.
+//
+// Input: IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This
+// IN VOID *Resources
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Configuration (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ OUT VOID **Resources)
+{
+ PCI_ROOT_BRG_DATA *rb=(PCI_ROOT_BRG_DATA*)This;
+ EFI_STATUS Status=0;
+//---------------------
+ if(rb->ResAsquired)
+ Status=GetResources((PCI_ROOT_BRG_DATA*)This, (ASLR_QWORD_ASD**)Resources, tResAll);
+ else Status=EFI_NOT_AVAILABLE_YET;
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciRw()
+//
+// Description: Provides Read and Write access to the PCI Configuration Space.
+//
+// Input:
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This Protocol Instance
+// IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width Data Width.
+// IN UINT64 Address PCI Config Address
+// IN UINT32 Mask Mask for the bits to be preserved
+// IN UINT32 Value Data to be written
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - OK
+// EFI_DEVICE_ERROR - HW ERROR
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PciRw (
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
+ IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINT32 Mask,
+ IN UINT32 Value
+ )
+{
+ EFI_STATUS Status;
+ UINT32 Data;
+
+ Status = This->Pci.Read (This,Width,Address,1,&Data);
+ ASSERT_EFI_ERROR (Status);
+
+ Data = (Data & Mask) | Value;
+ Status = This->Pci.Write (This,Width,Address,1,&Data);
+ ASSERT_EFI_ERROR (Status);
+}
+
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PCI/PciPort.c b/Core/EM/PCI/PciPort.c
new file mode 100644
index 0000000..aa6b5c4
--- /dev/null
+++ b/Core/EM/PCI/PciPort.c
@@ -0,0 +1,926 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PciBus/PciPort.c 22 9/10/12 12:54p Yakovlevs $
+//
+// $Revision: 22 $
+//
+// $Date: 9/10/12 12:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/PciBus/PciPort.c $
+//
+// 22 9/10/12 12:54p Yakovlevs
+// [TAG] EIP93341
+// [Category] Improvement
+// [Description] Preserve PCI DEV/LNK/SLT control register in S3 resume
+// path.
+// [Files] PciBus.c PciBus.sd PciBus.uni PciSetup.h PciPort.c
+//
+// 21 11/09/11 1:55p Yakovlevs
+// [TAG] EIP71380
+// [Category] New Feature
+// [Description] Core support for CSM opt-out feature
+// [Files] PciBus.c; PciPort.c; PciBus.sd; PciBus.uni; PciSetup.h;
+// PciBusSetup.c;
+//
+// 20 4/11/11 10:42a Yakovlevs
+// SkipDevice() changed.
+//
+// 19 4/05/11 11:26a Yakovlevs
+// [TAG] EIP 38174; EIP 53475;
+// [Description] 38174 Generic support to handle PCI OUT OF RESOURDCES
+// added.
+// 53475 PCI Express 3.0 support added.
+// [Files] PciBus.c; PciBus.mak; PciHostBridge.c; PciBus.h;
+// PciHostBridge.c; PciPort.c;
+//
+// 17 1/31/11 2:33p Yakovlevs
+// [TAG] EIP43879
+// [Category] New Feature
+// [Description] Added new conditions to have Overwrite Option ROM hook
+// called for every device.
+// [Files] PciPort.c
+//
+// 16 1/28/11 3:01p Yakovlevs
+// [TAG] EIP43879
+// [Category] New Feature
+// [Description] Added PciPortOemGetOptRom() OEM Hook to override
+// content of the PCI Device Option ROM.
+// [Files] PciBus.c; PciPort.c; PciPort.h; PciBus.mak; PciBus.sdl
+//
+// 15 12/08/10 3:22p Yakovlevs
+// Removed Setup Option "Selectable DeEmphasis" since it is HwInit Bit.
+//
+// 14 11/11/10 11:58a Yakovlevs
+//
+// 13 10/18/10 1:23p Yakovlevs
+// Link Training retry and Timeout moved in #if PCI_EXPRESS_SUPPORT scope.
+//
+// 12 8/16/10 1:12p Yakovlevs
+// Added ASPM Programming cipset hook
+//
+// 11 3/01/10 6:12p Yakovlevs
+// Pci Express V2.1 Support Added.
+//
+// 10 9/22/09 6:02p Yakovlevs
+// 1. Added infrastructure to ELINKs as porting Functions delivered from
+// Platform and Chipset files. Now you can port PCI Bus driver without
+// modifying Core files
+//
+// 9 4/28/09 3:49p Yakovlevs
+// Changes related to AmiBoardInfo protocol and Multiplatform support.
+//
+// 8 3/23/09 4:57p Yakovlevs
+// Added generic support for PCI Express Hot-Plug.
+//
+// 7 2/03/09 1:28p Yakovlevs
+//
+// 6 1/30/09 12:47p Yakovlevs
+// Added Porting functoion to skip PCI Device from enumeration.
+//
+// 5 10/01/08 7:10p Yakovlevs
+// Updated AMI FUNC HEADER information.
+//
+// 4 10/01/08 12:34p Yakovlevs
+//
+// 3 9/25/08 12:00p Yakovlevs
+//
+// 1 6/05/08 7:14p Yakovlevs
+//
+// 1 6/05/08 7:06p Yakovlevs
+//
+// 1 6/05/08 6:46p Yakovlevs
+//
+// 2 10/23/07 12:59p Felixp
+//
+// 1 10/18/07 11:22a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciPort.c
+//
+// Description: PCI porting
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <EFI.h>
+#include <Dxe.h>
+#include <Token.h>
+#include <PciBus.h>
+#include <PciHostBridge.h>
+#include <Setup.h>
+#include "PciSetup.h"
+#include "PciPort.h"
+
+//----------------------------------------------------------------------
+//Define Variables == TOKENS to be able to use binary
+// See token help for details
+//----------------------------------------------------------------------
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: NbDmiL0ExitLatency;
+//
+// Description: Variable to replace NB_DMI_L0_EXIT_LATENCY token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 NbDmiL0ExitLatency =
+#ifdef NB_DMI_L0_EXIT_LATENCY
+ NB_DMI_L0_EXIT_LATENCY
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: NbDmiL1ExitLatency;
+//
+// Description: Variable to replace NB_DMI_L1_EXIT_LATENCY token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 NbDmiL1ExitLatency =
+#ifdef NB_DMI_L1_EXIT_LATENCY
+ NB_DMI_L1_EXIT_LATENCY
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SbDmiL0ExitLatency;
+//
+// Description: Variable to replace SB_DMI_L0_EXIT_LATENCY token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 SbDmiL0ExitLatency =
+#ifdef SB_DMI_L0_EXIT_LATENCY
+ SB_DMI_L0_EXIT_LATENCY
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SbDmiL1ExitLatency;
+//
+// Description: Variable to replace SB_DMI_L1_EXIT_LATENCY token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 SbDmiL1ExitLatency =
+#ifdef SB_DMI_L1_EXIT_LATENCY
+ SB_DMI_L1_EXIT_LATENCY
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: NbDmiAspmSupport;
+//
+// Description: Variable to replace NB_DMI_ASPM_SUPPORT token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 NbDmiAspmSupport =
+#ifdef NB_DMI_ASPM_SUPPORT
+ NB_DMI_ASPM_SUPPORT
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SbDmiAspmSupport;
+//
+// Description: Variable to replace SB_DMI_ASPM_SUPPORT token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 SbDmiAspmSupport =
+#ifdef SB_DMI_ASPM_SUPPORT
+ SB_DMI_ASPM_SUPPORT
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SbInternalDelay;
+//
+// Description: Variable to replace SB_INTERNAL_DELAY token.
+//
+// Notes: const UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const UINT16 SbInternalDelay =
+#ifdef SB_INTERNAL_DELAY
+ SB_INTERNAL_DELAY
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: S3VideoRepost;
+//
+// Description: Variable to replace S3_VIDEO_REPOST_SUPPORT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN S3VideoRepost =
+#ifdef S3_VIDEO_REPOST_SUPPORT
+ S3_VIDEO_REPOST_SUPPORT
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FixedBusAssign;
+//
+// Description: Variable to replace PCI_FIXED_BUS_ASSIGNMENT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN FixedBusAssign =
+#ifdef PCI_FIXED_BUS_ASSIGNMENT
+ PCI_FIXED_BUS_ASSIGNMENT
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: ScanFullBusRange;
+//
+// Description: Variable to replace PCI_SCAN_FULL_BUS_RANGE token.
+//
+// Notes: const BOOLEAN
+// This option exists for testing purposes. If System will have additional
+// PCI devices which don't have tree strucuture it might be Pci Device Path
+// conflict
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN ScanFullBusRange =
+#ifdef PCI_SCAN_FULL_BUS_RANGE
+ PCI_SCAN_FULL_BUS_RANGE
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: PciExpressSupport;
+//
+// Description: Variable to replace PCI_EXPRESS_SUPPORT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN PciExpressSupport =
+#ifdef PCI_EXPRESS_SUPPORT
+ PCI_EXPRESS_SUPPORT
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: HotPlugSupport;
+//
+// Description: Variable to replace HOTPLUG_SUPPORT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN HotPlugSupport =
+#ifdef HOTPLUG_SUPPORT
+ HOTPLUG_SUPPORT
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: PciXSupport;
+//
+// Description: Variable to replace PCI_X_SUPPORT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN PciXSupport =
+#ifdef PCI_X_SUPPORT
+ PCI_X_SUPPORT
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SriovSupport;
+//
+// Description: Variable to replace SRIOV_SUPPORT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN SriovSupport =
+#ifdef SRIOV_SUPPORT
+ SRIOV_SUPPORT
+#else
+ 0
+#endif
+;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: Use4KBar;
+//
+// Description: Variable to replace PCI_4K_RESOURCE_ALIGNMENT token.
+//
+// Notes: const BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+const BOOLEAN Use4KBar =
+#ifdef PCI_4K_RESOURCE_ALIGNMENT
+ PCI_4K_RESOURCE_ALIGNMENT
+#else
+ 0
+#endif
+;
+
+
+//----------------------------------------------------------------------
+//Define Bord Porting Functions (Hooks) Herte...
+//----------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BrdGetPciSetupData()
+//
+// Description: Porting function which collects all PCI Bus Driver specific
+// SETUP configuration data and returns it to the PCI Bus Driver.
+//
+// Input:
+// PCI_SETUP_DATA* PciSetupData Pointer to the Pci Bus specific setup data buffer.
+//
+// Output: Nothing
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID BrdGetPciSetupData(PCI_SETUP_DATA *PciSetupData){
+ EFI_GUID SetupGuid = SETUP_GUID;
+ EFI_STATUS Status;
+ UINTN sz=sizeof(SETUP_DATA);
+ SETUP_DATA *SetupData=MallocZ(sizeof(SETUP_DATA));
+//-------------------------------------
+ //Get Setup Data
+ if ( SetupData==NULL) return;
+
+//Initially ALL Setup Data will be initialized with ZEROs
+//So id Defs
+
+ //Zero out PCI_SETUP_DATA buffer
+ pBS->SetMem(PciSetupData, sizeof(PCI_SETUP_DATA), 0);
+
+ //Get global setup variable
+ Status=GetEfiVariable(L"Setup",&SetupGuid, NULL, &sz, &SetupData);
+ if(EFI_ERROR(Status)){
+ //General PCI Settings: [] - default
+ //UINT8 PciLatency; //[32]\ 64 \ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+ PciSetupData->PciLatency=32;
+#if PCI_X_SUPPORT
+ //UINT8 PciXLatency; // 32 \[64]\ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+ PciSetupData->PciXLatency=64;
+#endif
+#if PCI_EXPRESS_SUPPORT
+ //PCI Express Device Settings: [] - default
+ //UINT8 RelaxedOrdering; //[Disable]\ Enable
+ //UINT8 ExtTagField; //[Disable]\ Enable
+ //UINT8 NoSnoop; // Disable \[Enable]
+ PciSetupData->NoSnoop=1;
+
+ //UINT8 MaxPayload; //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ PciSetupData->MaxPayload=55;
+ //UINT8 MaxReadRequest; //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ PciSetupData->MaxReadRequest=55;
+ //PCI Express Link settings: [] - default
+ //UINT8 AspmMode; //[Disable]\ Auto \ Forse L0
+ //UINT8 ExtendedSynch; //[Disable]\ Enable
+
+ //Fill in Default Values... (buffer was initialized with ZEROs)
+ //UINT8 LnkTrRetry; //Disable\ 2 \ 3 \[5]
+ PciSetupData->LnkTrRetry=5;
+ //UINT16 LnkTrTimout; //<1.[2]..100> (Microseconds uS)
+ PciSetupData->LnkTrTimeout=0x10;
+ //UINT8 LnkDisable; //[Keep ON == 0] / Disable ==1
+ PciSetupData->S3PciExpressScripts = 0;
+#endif
+ //UINTN S3ResumeVideoRepost //[Disable]\ Enable
+
+ //UINT8 Above4gDecode; //[Disable]\ Enable
+ //General PCI Settings: [] - default
+ //UINT8 VgaPallete; //[Disable]\ Enable
+ //UINT8 PerrEnable; //[Disable]\ Enable
+ //UINT8 SerrEnable; //[Disable]\ Enable
+#if AMI_HOTPLUG_INIT_SUPPORT
+ //INT8 HotPlug; // Disable \[Enable]
+ PciSetupData->HotPlug=1;
+ //UINT8 BusPadd; // Disable \[1]\ 2 \ 3 \ 4 \ 5
+ PciSetupData->BusPadd=1; // 0 1 2 3 4
+ //UINT8 IoPadd; // Disable \[ 4K]\ 8K \ 16K \ 32K
+ PciSetupData->IoPadd=0x1000; // 0 1 2 3 4 5 6 7
+ //UINT8 Mmio32Padd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \128M
+ PciSetupData->Mmio32Padd=0x1000000;
+ //UINT8 Mmio32PfPadd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \128M
+ PciSetupData->Mmio32PfPadd=0x1000000;
+ //UINT8 Mmio64Padd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+ //UINT8 Mmio64PfPadd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+#endif
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Gen2 Device Settings
+
+ //UINT8 ComplTimeOut; //[Disable]\ Default \ 50 - 100 us \ 1ms - 10ms \ 16...
+
+ //UINT8 AriFwd; //[Disable]\ Enable
+ //UINT8 AtomOpReq; //[Disable]\ Enable
+ //UINT8 AtomOpEgressBlk; //[Disable]\ Enable
+ //UINT8 IDOReq; //[Disable]\ Enable
+ //UINT8 IDOCompl; //[Disable]\ Enable
+ //UINT8 LtrReport; //[Disable]\ Enable
+ //UINT8 E2ETlpPrBlk; //[Disable]\ Enable
+
+ //Gen2 Link Settings
+ //UINT8 LnkSpeed; //[Auto]\ 5.0 GHz \ 2.5 GHz
+ PciSetupData->LnkSpeed=55;
+ //UINT8 DeEmphasis; //[Disable]\ Enable
+ //UINT8 ClockPm; //[Disable]\ Enable
+ //UINT8 ComplSos; //[Disable]\ Enable
+
+ //UINT8 HwAutoWidth; //[Enable]\ Disable
+ //PciSetupData->HwAutoWidth=0;
+ //UINT8 HwAutoSpeed; //[Enable]\ Disable
+ //PciSetupData->HwAutoSpeed=0;
+#endif
+
+ } else {
+ //General PCI Settings: [] - default
+ PciSetupData->PciLatency = SetupData->PciLatency;
+#if PCI_X_SUPPORT
+ PciSetupData->PciXLatency = SetupData->PciXLatency;
+#endif
+#if PCI_EXPRESS_SUPPORT
+ //PCI Express Device Settings: [] - default
+ PciSetupData->RelaxedOrdering = SetupData->RelaxedOrdering;
+ PciSetupData->ExtTagField = SetupData->ExtTagField;
+ PciSetupData->NoSnoop = SetupData->NoSnoop;
+ PciSetupData->MaxPayload = SetupData->MaxPayload;
+ PciSetupData->MaxReadRequest = SetupData->MaxReadRequest;
+ //PCI Express Link settings: [] - default
+ PciSetupData->AspmMode = SetupData->AspmMode;
+ PciSetupData->ExtendedSynch = SetupData->ExtendedSynch;
+
+ //Fill in Default Values... (buffer was initialized with ZEROs)
+ //UINT8 LnkTrRetry; //[Disable]\ 2 \ 3 \ 5
+ PciSetupData->LnkTrRetry=SetupData->LnkTrRetry;
+ PciSetupData->LnkTrTimeout=SetupData->LnkTrTimeout;
+ PciSetupData->LnkDisable=SetupData->LnkDisable; //[Keep ON == 0] / Disable ==1
+ //UINT8 S3PciExpressScripts //[Disable]\ Enable
+ PciSetupData->S3PciExpressScripts = SetupData->S3PciExpressScripts;
+
+#endif
+#if S3_VIDEO_REPOST_SUPPORT
+ PciSetupData->S3ResumeVideoRepost = SetupData->S3ResumeVideoRepost;
+#endif
+ //General2 PCI Settings: [] - default
+ PciSetupData->VgaPallete = SetupData->VgaPallete;
+ PciSetupData->PerrEnable = SetupData->PerrEnable;
+ PciSetupData->SerrEnable = SetupData->SerrEnable;
+#if ABOVE_4G_PCI_DECODE
+ PciSetupData->Above4gDecode = SetupData->Above4gDecode;
+#endif
+
+#if AMI_HOTPLUG_INIT_SUPPORT
+ //INT8 HotPlug; // Disable \[Enable]
+ PciSetupData->HotPlug=SetupData->HotPlugEnable;
+ //if HP Enabled...
+ if(PciSetupData->HotPlug){
+ PciSetupData->BusPadd=SetupData->BusPadd;
+ PciSetupData->IoPadd=SetupData->IoPadd*0x400; //Stored in units of KB
+ PciSetupData->Mmio32Padd=SetupData->Mmio32Padd*0x100000;
+ PciSetupData->Mmio32PfPadd=SetupData->Mmio32PfPadd*0x100000;
+ if(PciSetupData->Above4gDecode == 1){
+ PciSetupData->Mmio64Padd=SetupData->Mmio64Padd*0x100000;
+ PciSetupData->Mmio64PfPadd=SetupData->Mmio64PfPadd*0x100000;
+ } else {
+ PciSetupData->Mmio64Padd=0;
+ PciSetupData->Mmio64PfPadd=0;
+ }
+ }
+#endif
+
+#if PCI_EXPRESS_GEN2_SUPPORT
+ //Gen2 Device Settings
+ //UINT8 ComplTimeOut; //[Disable]\ Default \ 50 - 100 us \ 1ms - 10ms \ 16...
+ PciSetupData->ComplTimeOut=SetupData->ComplTimeOut;
+ //UINT8 AriFwd; //[Disable]\ Enable
+ PciSetupData->AriFwd=SetupData->AriFwd;
+ //UINT8 AtomOpReq; //[Disable]\ Enable
+ PciSetupData->AtomOpReq=SetupData->AtomOpReq;
+ //UINT8 AtomOpEgressBlk; //[Disable]\ Enable
+ PciSetupData->AtomOpEgressBlk=SetupData->AtomOpEgressBlk;
+ //UINT8 IDOReq; //[Disable]\ Enable
+ PciSetupData->IDOReq=SetupData->IDOReq;
+ //UINT8 IDOCompl; //[Disable]\ Enable
+ PciSetupData->IDOCompl=SetupData->IDOCompl;
+ //UINT8 LtrReport; //[Disable]\ Enable
+ PciSetupData->LtrReport=SetupData->LtrReport;
+ //UINT8 E2ETlpPrBlk; //[Disable]\ Enable
+ PciSetupData->E2ETlpPrBlk=SetupData->E2ETlpPrBlk;
+
+ //Gen2 Link Settings
+ //UINT8 LnkSpeed; //[Auto]\ 5.0 GHz \ 2.5 GHz
+ PciSetupData->LnkSpeed=SetupData->LnkSpeed;
+ //UINT8 ComplSos; //[Disable]\ Enable
+ PciSetupData->ComplSos=SetupData->ComplSos;
+ //UINT8 ClockPm; //[Disable]\ Enable
+ PciSetupData->ClockPm=SetupData->ClockPm;
+ //UINT8 HwAutoWidth; //[Enable]\ Disable
+ PciSetupData->HwAutoWidth=SetupData->HwAutoWidth;
+ //UINT8 HwAutoSpeed; //[Enable]\ Disable
+ PciSetupData->HwAutoSpeed=SetupData->HwAutoSpeed;
+#endif
+ }
+ pBS->FreePool(SetupData);
+
+}
+
+//To avoid compilation error define STRUCT delivered trough eLink as extern function.
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) Callback
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_PROGRAM_DEVICE_CALLBACK_LIST EndOfList;
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_SKIP_DEVICE_CALLBACK_LIST EndOfList;
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_DEVICE_SET_ASPM_CALLBACK_LIST EndOfList;
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_DEVICE_SET_LNK_SPEED_CALLBACK_LIST EndOfList;
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_DEVICE_ATTRIBUTE_CALLBACK_LIST EndOfList;
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_DEVICE_OUT_OF_RESOURCES_CALLBACK_LIST EndOfList;
+extern OEM_PCI_PROGRAM_DEVICE_FUNCTION OEM_PCI_DEVICE_GET_OPT_ROM_CALLBACK_LIST EndOfList;
+#undef OEM_PCI_DEVICE_CALLBACK
+
+
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemSkipPciDevice[] =
+ { OEM_PCI_SKIP_DEVICE_CALLBACK_LIST { 0, 0, NULL } };
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PciPortSkipThisDevice()
+//
+// Description: Porting function which collects all Pci Specific configuration
+// data return it to the PCI Bus Driver.
+//
+// Input:
+// PCI_DEV_INFO *Device Pointer to the Pci Bus Driver Private data buffer.
+//
+// Output: EFI_STATUS
+// EFI_SUCCESS - SKIP this device, do not touch PCI Command register.
+// EFI_UNSUPPORTED - DON'T SKIP this device do complete enumeration as usual.
+//
+// NOTE:
+// If device decodes or requires some resources to function properely,
+// allocating and and reporting this reaources to GCD is a total responsibility
+// of this hook. If this FUNCTION RETURNS EFI_SUCCESS PciBus Driver assumes that
+// RESOURCES ARE ALLOCATED AND REPORTED TO THE GCD DXE SERVICES.
+// Reporting resources to GCD Services is important to avoid same resource range
+// been allocated twice.
+// If device you want to skip is PCI2PCI or PCI2CRD bus bridge 1 bus will be allocated
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PciPortSkipThisDevice(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_UNSUPPORTED;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemSkipPciDevice;
+ EFI_STATUS retStatus=EFI_UNSUPPORTED;
+//-------------------
+ while(List->Callback)
+ {
+ OEM_PCI_PROGRAM_DEVICE_FUNCTION *CallBack=(OEM_PCI_PROGRAM_DEVICE_FUNCTION*)List->Callback;
+ //--------------------------------
+ if((List->VendorId == Device->DevVenId.VenId && List->DeviceId == Device->DevVenId.DevId)||
+ (List->VendorId == 0 && List->DeviceId == 0))
+ {
+ PCI_TRACE((TRACE_PCI, "PciBus: OEM Skip Device Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device);
+ PCI_TRACE((TRACE_PCI, " %r,\n", Status));
+ if( EFI_ERROR(Status) && (Status!=EFI_UNSUPPORTED))return Status;
+ else if(Status==EFI_SUCCESS)retStatus=Status;
+ }
+ //if(List->VendorId == 0 && List->DeviceId == 0) break;
+ List++;
+ }
+
+ return retStatus;
+}
+
+
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemProgramPciDevice[] =
+ { OEM_PCI_PROGRAM_DEVICE_CALLBACK_LIST { 0, 0, NULL } };
+
+EFI_STATUS PciPortOemProgDevice(PCI_DEV_INFO *Device){
+ EFI_STATUS Status=EFI_SUCCESS;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemProgramPciDevice;
+//-------------------
+ while(List->Callback)
+ {
+ OEM_PCI_PROGRAM_DEVICE_FUNCTION *CallBack=(OEM_PCI_PROGRAM_DEVICE_FUNCTION*)List->Callback;
+ //--------------------------------
+ if((List->VendorId == Device->DevVenId.VenId && List->DeviceId == Device->DevVenId.DevId)||
+ (List->VendorId == 0 && List->DeviceId == 0))
+ {
+ PCI_TRACE((TRACE_PCI, "PciBus: OEM Programm Device Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device);
+ PCI_TRACE((TRACE_PCI, " %r,\n", Status));
+ if( EFI_ERROR(Status) )
+ return Status;
+ }
+ List++;
+ }
+
+ return Status;
+}
+
+//To avoid compilation error define Srtuct delivered trough eLink as extern function.
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemSetAspmPciDevice[] =
+ { OEM_PCI_DEVICE_SET_ASPM_CALLBACK_LIST { 0, 0, NULL } };
+
+
+//Suppose to be called 2 times for UpStream and DownStream component of a LINK.
+EFI_STATUS PciPortOemSetAspm(PCI_DEV_INFO *Device, VOID *AspmMode){
+ EFI_STATUS Status=EFI_SUCCESS;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemSetAspmPciDevice;
+//-------------------
+ while(List->Callback)
+ {
+ OEM_PCI_DEVICE_SET_ASPM_FUNCTION *CallBack =(OEM_PCI_DEVICE_SET_ASPM_FUNCTION*)List->Callback;
+ //--------------------------------
+
+ if((List->VendorId == Device->DevVenId.VenId && List->DeviceId == Device->DevVenId.DevId)||
+ (List->VendorId == 0 && List->DeviceId == 0))
+ {
+ PCI_TRACE((TRACE_PCI, "PciBus: OEM Device Set ASPM Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device, AspmMode);
+ PCI_TRACE((TRACE_PCI, " %r,\n", Status));
+ if( EFI_ERROR(Status))
+ return Status;
+ }
+ List++;
+ }
+
+ return Status;
+}
+
+//To avoid compilation error define Srtuct delivered trough eLink as extern function.
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemSetLnkSpeedPciDevice[] =
+ { OEM_PCI_DEVICE_SET_LNK_SPEED_CALLBACK_LIST { 0, 0, NULL } };
+
+//Suppose to be called 2 times for UpStream and DownStream component of a LINK.
+EFI_STATUS PciPortOemSetLnkSpeed(PCI_DEV_INFO *Device, UINT8 *LnkSpeed, UINT8 SuppSpeeds){
+ EFI_STATUS Status=EFI_SUCCESS;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemSetLnkSpeedPciDevice;
+//-------------------
+ while(List->Callback)
+ {
+ OEM_PCI_DEVICE_SET_LNK_SPEED_FUNCTION *CallBack =(OEM_PCI_DEVICE_SET_LNK_SPEED_FUNCTION*)List->Callback;
+ //--------------------------------
+
+ if((List->VendorId == Device->DevVenId.VenId && List->DeviceId == Device->DevVenId.DevId)||
+ (List->VendorId == 0 && List->DeviceId == 0))
+ {
+ PCI_TRACE((TRACE_PCI, "PciBus: OEM Device Set LNK SPEED Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device, LnkSpeed, SuppSpeeds);
+ PCI_TRACE((TRACE_PCI, " %r,\n", Status));
+ if( EFI_ERROR(Status))
+ return Status;
+ }
+ List++;
+ }
+
+ return Status;
+}
+
+//To avoid compilation error define Srtuct delivered trough eLink as extern function.
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemGetOptRomPciDevice[] =
+ { OEM_PCI_DEVICE_GET_OPT_ROM_CALLBACK_LIST { 0, 0, NULL } };
+
+
+
+EFI_STATUS PciPortOemGetOptRom(PCI_DEV_INFO *Device, VOID **OptRom, UINT64 *OptRomSize){
+ EFI_STATUS Status=EFI_SUCCESS;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemGetOptRomPciDevice;
+//-------------------
+ while(List->Callback)
+ {
+ OEM_PCI_DEVICE_GET_OPT_ROM_FUNCTION *CallBack =(OEM_PCI_DEVICE_GET_OPT_ROM_FUNCTION*)List->Callback;
+ //--------------------------------
+
+ if((List->VendorId == Device->DevVenId.VenId && List->DeviceId == Device->DevVenId.DevId)||
+ (List->VendorId == 0 && List->DeviceId == 0))
+ {
+ PCI_TRACE((TRACE_PCI, "PciBus: OEM Device Get Opt ROM Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device, OptRom, OptRomSize);
+ PCI_TRACE((TRACE_PCI, " %r,\n", Status));
+ if( EFI_ERROR(Status))
+ return Status;
+ }
+ List++;
+ }
+
+ return Status;
+}
+
+
+
+//To avoid compilation error define Srtuct delivered trough eLink as extern function.
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemPciOutOfResourcesRemoveDevice[] =
+ { OEM_PCI_DEVICE_OUT_OF_RESOURCES_CALLBACK_LIST { 0, 0, NULL } };
+
+EFI_STATUS PciPortOutOfResourcesRemoveDevice(PCI_DEV_INFO *Device, UINTN Count, UINTN LowResType){
+ EFI_STATUS Status=EFI_UNSUPPORTED;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemPciOutOfResourcesRemoveDevice;
+//-----------------------------
+
+ //must be only one + TERMIONATOR.
+ while(List->Callback)
+ {
+ OEM_PCI_DEVICE_OUT_OF_RESOURCES_FUNCTION *CallBack =(OEM_PCI_DEVICE_OUT_OF_RESOURCES_FUNCTION*)List->Callback;
+ //-----------------------------
+
+ PCI_TRACE((TRACE_PCI, "\nPciBus: OEM PCI OUT OF RESOURCES Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device, Count, LowResType);
+ PCI_TRACE((TRACE_PCI, " %r,\n\n", Status));
+
+ List++;
+
+ }
+ return Status;
+}
+
+
+//To avoid compilation error define Srtuct delivered trough eLink as extern function.
+#define OEM_PCI_DEVICE_CALLBACK( VendorId, DeviceId, Callback ) { VendorId, DeviceId, &Callback }
+OEM_PCI_DEVICE_PROGRAM_CALLBACK OemAttributesPciDevice[] =
+ { OEM_PCI_DEVICE_ATTRIBUTE_CALLBACK_LIST { 0, 0, NULL } };
+
+
+
+EFI_STATUS PciPortOemAttributes(PCI_DEV_INFO *Device, UINT64 *Attr, UINT64 Capab, BOOLEAN Set){
+ EFI_STATUS Status=EFI_SUCCESS;
+ OEM_PCI_DEVICE_PROGRAM_CALLBACK *List = OemAttributesPciDevice;
+//-------------------
+ while(List->Callback)
+ {
+ OEM_PCI_DEVICE_ATTRIBUTE_FUNCTION *CallBack =(OEM_PCI_DEVICE_ATTRIBUTE_FUNCTION*)List->Callback;
+ //--------------------------------
+
+ if((List->VendorId == Device->DevVenId.VenId && List->DeviceId == Device->DevVenId.DevId)||
+ (List->VendorId == 0 && List->DeviceId == 0))
+ {
+ PCI_TRACE((TRACE_PCI, "PciBus: OEM Device Attributes Callback @ B%X|D%X|F%X VID=0x%X; DID=0x%X;",
+ Device->Address.Addr.Bus,Device->Address.Addr.Device,Device->Address.Addr.Function,
+ Device->DevVenId.VenId, Device->DevVenId.DevId));
+
+ Status = CallBack(Device, Attr, Capab, Set);
+ PCI_TRACE((TRACE_PCI, " %r,\n", Status));
+ if( EFI_ERROR(Status))
+ return Status;
+ }
+ List++;
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS PciPortSetOemPadding(VOID *HpcData, VOID *HpcLocationData, UINT64 PciAddress){
+ EFI_STATUS Status=EFI_SUCCESS;
+//ADD VARIABLES HERE..
+
+//-----------------
+
+//PORTING START//PORTING START//PORTING START//PORTING START//PORTING START
+//ADD PORTING CODE HERE...
+/*
+ //VOID *HpcData, VOID *HpcLocationData could be typecasted to
+ // (PCI_HPC_DATA*)HpcData and (HPC_LOCATION_DATA*)HpcLocationData.
+ //Update Padding requirements if needed HERE.
+ //PCI_HPC_DATA *HpcData has pointer to the PCI_HOST_BRG_DATA* HpcData->Owner
+ //And number of HPC in subsystem of this HOST - HpcData->HpcLocCount.
+ //HPC_LOCATION_DATA *HpcLocationData has information about Location and Paddin for this
+ //Particular HPC. If system has more than ONE HPC checking needs to be done to
+ //detect correct if PASSED the data from correct HPC.
+
+
+ //Do something like this.
+
+ HpcLocationData->Padding[ptBus]=10;
+
+*/
+//PORTING END//PORTING END//PORTING END//PORTING END//PORTING END//PORTING END
+//DO NOT WRITE BELOW THIS LINE FOR THIS PORTING FUNCTION
+
+ return Status;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PCI/PciPort.h b/Core/EM/PCI/PciPort.h
new file mode 100644
index 0000000..3e7e53c
--- /dev/null
+++ b/Core/EM/PCI/PciPort.h
@@ -0,0 +1,136 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PciBus/PciPort.h 5 4/05/11 11:28a Yakovlevs $
+//
+// $Revision: 5 $
+//
+// $Date: 4/05/11 11:28a $
+//**********************************************************************
+// Revision History
+// ----------------
+//$Log: /Alaska/BIN/Core/Modules/PciBus/PciPort.h $
+//
+// 5 4/05/11 11:28a Yakovlevs
+// [TAG] EIP 38174; EIP 53475;
+// [Description] 38174 Generic support to handle PCI OUT OF RESOURDCES
+// added.
+// 53475 PCI Express 3.0 support added.
+//
+// [Files] PciBus.c; PciBus.mak; PciHostBridge.c; PciBus.h;
+// PciHostBridge.c; PciPort.c;
+//
+// 4 1/28/11 3:02p Yakovlevs
+// [TAG] EIP43879
+// [Category] New Feature
+// [Description] Added PciPortOemGetOptRom() OEM Hook to override
+// content of the PCI Device Option ROM.
+// [Files] PciBus.c; PciPort.c; PciPort.h; PciBus.mak; PciBus.sdl
+//
+// 3 8/16/10 1:12p Yakovlevs
+// ASPM Custom Programming.
+//
+// 2 9/22/09 6:02p Yakovlevs
+// 1. Added infrastructure to ELINKs as porting Functions delivered from
+// Platform and Chipset files. Now you can port PCI Bus driver without
+// modifying Core files
+//
+// 1 4/28/09 3:47p Yakovlevs
+
+#ifndef PCI_PORT_H_
+#define PCI_PORT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <Efi.h>
+
+
+//----------------------------------------------------------------------------------
+//PCI Bus Porting Constants definitions
+const UINT16 NbDmiL0ExitLatency;
+const UINT16 NbDmiL1ExitLatency;
+const UINT16 SbDmiL0ExitLatency;
+const UINT16 SbDmiL1ExitLatency;
+const UINT16 NbDmiAspmSupport;
+const UINT16 SbDmiAspmSupport;
+const UINT16 SbInternalDelay;
+//PCI Bus Configuration Constants definitions
+const BOOLEAN S3VideoRepost;
+const BOOLEAN FixedBusAssign;
+const BOOLEAN ScanFullBusRange;
+const BOOLEAN PciExpressSupport;
+const BOOLEAN HotPlugSupport;
+const BOOLEAN PciXSupport;
+const BOOLEAN SriovSupport;
+const BOOLEAN Use4KBar;
+
+//Define OEM_PCI_DEVICE_PROGRAM_CALLBACK
+typedef EFI_STATUS (OEM_PCI_PROGRAM_DEVICE_FUNCTION)(VOID *PciIoProtocol);
+typedef EFI_STATUS (OEM_PCI_DEVICE_ATTRIBUTE_FUNCTION)(VOID *PciIoProtocol, UINT64 *Attr, UINT64 Capab, BOOLEAN Set);
+typedef EFI_STATUS (OEM_PCI_DEVICE_SET_ASPM_FUNCTION)(VOID *PciIoProtocol, VOID *AspmMode);
+typedef EFI_STATUS (OEM_PCI_DEVICE_SET_LNK_SPEED_FUNCTION)(VOID *PciIoProtocol, UINT8 *LnkSpeed, UINT8 SuppSpeeds);
+typedef EFI_STATUS (OEM_PCI_DEVICE_GET_OPT_ROM_FUNCTION)(VOID *PciIoProtocol, VOID **OptRom, UINT64 *OptRomSize);
+typedef EFI_STATUS (OEM_PCI_DEVICE_OUT_OF_RESOURCES_FUNCTION)(VOID *PciIoProtocol, UINTN Count, UINTN ResType);
+typedef EFI_STATUS (OEM_PCI_PADDING_FUNCTION)(VOID *HpcData, VOID *HpcLocationData, UINT64 PciAddress);
+
+//Data structure of CallBack delivered trough eLink
+typedef struct{
+ UINT16 VendorId;
+ UINT16 DeviceId;
+ VOID *Callback;
+} OEM_PCI_DEVICE_PROGRAM_CALLBACK;
+
+
+
+//PCI Bus Porting Function Prototypes
+EFI_STATUS PciPortSkipThisDevice(VOID *Device);
+
+EFI_STATUS PciPortOemProgDevice(VOID *Device);
+
+EFI_STATUS PciPortOemAttributes(VOID *Device, UINT64 *Attr, UINT64 Capab, BOOLEAN Set);
+
+EFI_STATUS PciPortOemSetAspm(PCI_DEV_INFO *Device, VOID *AspmMode);
+
+EFI_STATUS PciPortOemSetLnkSpeed(PCI_DEV_INFO *Device, UINT8 *LnkSpeed, UINT8 SuppSpeeds);
+
+EFI_STATUS PciPortSetOemPadding(VOID *HpcData, VOID *HpcLocationData, UINT64 PciAddress);
+
+EFI_STATUS PciPortOemGetOptRom(PCI_DEV_INFO *Device, VOID **OptRom, UINT64 *OptRomSize);
+
+EFI_STATUS PciPortOutOfResourcesRemoveDevice(PCI_DEV_INFO *Device, UINTN Count, UINTN LowResType);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif //PCI_BOARD_H_
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/EM/PCI/PciRootBridge.dxs b/Core/EM/PCI/PciRootBridge.dxs
new file mode 100644
index 0000000..7f57b62
--- /dev/null
+++ b/Core/EM/PCI/PciRootBridge.dxs
@@ -0,0 +1,67 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PciBus/PciRootBridge.dxs 3 4/28/09 3:49p Yakovlevs $
+//
+// $Revision: 3 $
+//
+// $Date: 4/28/09 3:49p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/PciBus/PciRootBridge.dxs $
+//
+// 3 4/28/09 3:49p Yakovlevs
+// Changes related to AmiBoardInfo protocol and Multiplatform support.
+//
+// 2 3/13/07 8:32p Yakovlevs
+//
+// 1 3/12/07 12:08p Yakovlevs
+//
+// 2 7/25/05 4:26p Markw
+// Add Variable services.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciRootBridge_dxs
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol\Variable.h>
+#include <Protocol\CPU.h>
+#include <Protocol\AmiBoardInfo.h>
+DEPENDENCY_START
+ EFI_CPU_ARCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+ EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID AND
+ AMI_BOARD_INFO_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PCI/PciSetup.h b/Core/EM/PCI/PciSetup.h
new file mode 100644
index 0000000..90d6cb8
--- /dev/null
+++ b/Core/EM/PCI/PciSetup.h
@@ -0,0 +1,155 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PciBus/PciSetup.h 6 9/10/12 12:54p Yakovlevs $
+//
+// $Revision: 6 $
+//
+// $Date: 9/10/12 12:54p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/PciBus/PciSetup.h $
+//
+// 6 9/10/12 12:54p Yakovlevs
+// [TAG] EIP93341
+// [Category] Improvement
+// [Description] Preserve PCI DEV/LNK/SLT control register in S3 resume
+// path.
+// [Files] PciBus.c PciBus.sd PciBus.uni PciSetup.h PciPort.c
+//
+// 5 11/09/11 1:55p Yakovlevs
+// [TAG] EIP71380
+// [Category] New Feature
+// [Description] Core support for CSM opt-out feature
+// [Files] PciBus.c; PciPort.c; PciBus.sd; PciBus.uni; PciSetup.h;
+// PciBusSetup.c;
+//
+// 4 12/08/10 3:22p Yakovlevs
+// Removed Setup Option "Selectable DeEmphasis" since it is HwInit Bit.
+//
+// 3 3/01/10 6:12p Yakovlevs
+// Pci Express V2.1 Support Added.
+//
+// 2 3/23/09 4:57p Yakovlevs
+// Added generic support for PCI Express Hot-Plug.
+//
+// 1 9/25/08 11:35a Yakovlevs
+//
+// 1 6/05/08 7:14p Yakovlevs
+//
+// 1 6/05/08 7:06p Yakovlevs
+//
+// 1 6/05/08 6:46p Yakovlevs
+//
+// 1 3/18/07 5:23p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PciSetup.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __PCI_SETUP__H__
+#define __PCI_SETUP__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#pragma pack(push)
+//---------------------------------------------------------------------------------
+//Structure Defines PCI Releated data stored in GLOBAL SETUP_DATA NVRAM variable
+typedef struct _PCI_SETUP_DATA {
+ //General PCI Settings: [] - default
+ UINT8 PciLatency; //[32]\ 64 \ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+ UINT8 PciXLatency; // 32 \[64]\ 96 \ 128 \ 160 \ 192 \ 224 \ 248
+ //PCI Express Device Settings: [] - default
+ UINT8 RelaxedOrdering; //[Disable]\ Enable
+ UINT8 ExtTagField; //[Disable]\ Enable
+ UINT8 NoSnoop; // Disable \[Enable]
+ UINT8 MaxPayload; //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ UINT8 MaxReadRequest; //[Auto]\ 128 \ 256 \ 512 \ 1024 \ 2048 \ 4096 (in bytes)
+ //PCI Express Link settings: [] - default
+ UINT8 AspmMode; //[Disable]\ Auto \ Force L0
+ UINT8 ExtendedSynch; //[Disable]\ Enable
+ //Acpi related questions
+ UINT8 S3ResumeVideoRepost;
+//new stuff added in PCI BUS 2.2.0
+ UINT8 Above4gDecode; //[Disable]\ Enable
+ //General PCI Settings: [] - default
+ UINT8 VgaPallete; //[Disable]\ Enable
+ UINT8 PerrEnable; //[Disable]\ Enable
+ UINT8 SerrEnable; //[Disable]\ Enable
+ //Hotlpug Related Settings visible if PCI_HOTPLUG_SUPPORT == 1 && PCI_EXPRESS_SUPPORT == 1
+ UINT8 HotPlug; // Disable \[Enable]
+ UINT8 BusPadd; // Disable \[1]\ 2 \ 3 \ 4 \ 5
+ UINT64 IoPadd; // Disable \[ 4K]\ 8K \ 16K \ 32K
+ UINT64 Mmio32Padd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \ 128M
+ UINT64 Mmio32PfPadd; // Disable \ 1M \ 4M \ 8M \[16M]\ 32M \ 64M \ 128M
+ UINT64 Mmio64Padd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+ UINT64 Mmio64PfPadd; //[Disable]\ 1M \ 4M \ 8M \ 16M \ 32M \ 64M \ 128M \ 256M \ 512M \ 1G
+
+ UINT8 LnkTrRetry; //[Disable]\ 2 \ 3 \ 5
+ UINT16 LnkTrTimeout; //[1...1000] (Microseconds uS)
+ UINT8 LnkDisable; //[Keep ON == 0] / Disable ==1
+
+ UINT8 S3PciExpressScripts; //[Disable]\ Enable
+
+//PCI_EXPRESS_GEN2_SUPPORT
+ //Gen2 Device Settings
+ UINT8 ComplTimeOut; //[Disable]\ Default \ 50 - 100 us \ 1ms - 10ms \ 16...
+ UINT8 AriFwd; //[Disable]\ Enable
+ UINT8 AtomOpReq; //[Disable]\ Enable
+ UINT8 AtomOpEgressBlk; //[Disable]\ Enable
+ UINT8 IDOReq; //[Disable]\ Enable
+ UINT8 IDOCompl; //[Disable]\ Enable
+ UINT8 LtrReport; //[Disable]\ Enable
+ UINT8 E2ETlpPrBlk; //[Disable]\ Enable
+
+ //Gen2 Link Settings
+ UINT8 LnkSpeed; //[Auto]\ 5.0 GHz \ 2.5 GHz
+ UINT8 ClockPm; //[Disable]\ Enable
+ UINT8 ComplSos; //[Disable]\ Enable
+ UINT8 HwAutoWidth; //[Enable]\ Disable //LNK_CNT_REG #1
+ UINT8 HwAutoSpeed; //[Enable]\ Disable
+
+} PCI_SETUP_DATA;
+
+#pragma pack(pop)
+
+//Function Prototypes
+VOID BrdGetPciSetupData(PCI_SETUP_DATA *PciSetupData);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/Names.c b/Core/EM/PS2CTL/Names.c
new file mode 100644
index 0000000..0acdad4
--- /dev/null
+++ b/Core/EM/PS2CTL/Names.c
@@ -0,0 +1,269 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/Names.c 7 8/28/09 10:03a Felixp $
+//
+// $Revision: 7 $
+//
+// $Date: 8/28/09 10:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/Names.c $
+//
+// 7 8/28/09 10:03a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 6 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 5 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 4 4/10/07 10:04a Felixp
+// LookupHID routine renamed to LookupPs2Hid to avoid linking issue when
+// linking with FloppyCtrl module
+//
+// 3 3/13/06 2:38a Felixp
+//
+// 2 3/04/05 1:37p Mandal
+//
+// 1 2/01/05 1:11a Felixp
+//
+// 3 1/28/05 1:21p Felixp
+// bug fix in component name
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 2 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 1 9/21/04 5:42p Olegi
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: Names.c
+//
+// Description: Component name producer for PS/2 Controller DXE driver
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "efi.h"
+#include "ps2ctl.h"
+#include <Protocol\ComponentName.h>
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+#endif
+//----------------------------------------------------------------------
+
+EFI_STATUS PS2GetDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+);
+
+EFI_STATUS
+PS2GetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+);
+
+extern EFI_DRIVER_BINDING_PROTOCOL gPS2CtlDriverBinding;
+extern PS2DEV_TABLE supportedDevices[];
+
+//----------------------------------------------------------------------
+
+CHAR16 *gPS2DriverName = L"AMI PS/2 Driver";
+
+//==================================================================================
+// Driver component name instance for PS2Ctl Driver
+//==================================================================================
+EFI_COMPONENT_NAME_PROTOCOL gPS2CtlDriverName = {
+ PS2GetDriverName,
+ PS2GetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PS2GetDriverName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// Parameters:
+// EFI_COMPONENT_NAME_PROTOCOL
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// CHAR8
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// CHAR16
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// Output:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PS2GetDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+ *DriverName = gPS2DriverName;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PS2GetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Parameters:
+// EFI_COMPONENT_NAME_PROTOCOL
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// EFI_HANDLE
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// EFI_HANDLE
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// CHAR8
+// *Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// CHAR16
+// **ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// Output:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PS2GetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+ ACPI_HID_DEVICE_PATH* acpiDP;
+ PS2DEV_TABLE *ps2dev = 0;
+ if(!Language || !ControllerName) return EFI_INVALID_PARAMETER;
+ if (!LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH))
+ return EFI_UNSUPPORTED;
+
+ //
+ // Find the last device node in the device path and return "Supported"
+ // for mouse and/or keyboard depending on the SDL switches.
+ //
+ if(!EFI_ERROR(GetPS2_DP(&gPS2CtlDriverBinding, Controller, &acpiDP, EFI_OPEN_PROTOCOL_GET_PROTOCOL)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, &ps2dev)){
+ *ControllerName = ps2dev->name;
+ return EFI_SUCCESS;
+ }
+ return EFI_UNSUPPORTED;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/PS2Ctl.cif b/Core/EM/PS2CTL/PS2Ctl.cif
new file mode 100644
index 0000000..df7d5f7
--- /dev/null
+++ b/Core/EM/PS2CTL/PS2Ctl.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "PS2CTL"
+ category = ModulePart
+ LocalRoot = "Core\EM\PS2CTL\"
+ RefName = "PS2CTL"
+[files]
+"PS2Ctl.sdl"
+"ps2kbd.c"
+"ps2main.c"
+"ps2ctl.h"
+"kbc.h"
+"kbc.c"
+"ps2mouse.h"
+"mouse.c"
+"efismplpp.c"
+"Names.c"
+"hotkey.c"
+"Ps2Ctl.chm"
+<endComponent>
diff --git a/Core/EM/PS2CTL/PS2Ctl.sdl b/Core/EM/PS2CTL/PS2Ctl.sdl
new file mode 100644
index 0000000..b70e3f8
--- /dev/null
+++ b/Core/EM/PS2CTL/PS2Ctl.sdl
@@ -0,0 +1,6 @@
+
+PATH
+ Name = "PS2Ctl_DIR"
+ Help = "PS/2 Controller source directory"
+End
+
diff --git a/Core/EM/PS2CTL/Ps2Ctl.chm b/Core/EM/PS2CTL/Ps2Ctl.chm
new file mode 100644
index 0000000..159b643
--- /dev/null
+++ b/Core/EM/PS2CTL/Ps2Ctl.chm
Binary files differ
diff --git a/Core/EM/PS2CTL/efismplpp.c b/Core/EM/PS2CTL/efismplpp.c
new file mode 100644
index 0000000..36bd2d9
--- /dev/null
+++ b/Core/EM/PS2CTL/efismplpp.c
@@ -0,0 +1,256 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/efismplpp.c 7 11/03/11 5:56a Rajeshms $
+//
+// $Revision: 7 $
+//
+// $Date: 11/03/11 5:56a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/efismplpp.c $
+//
+// 7 11/03/11 5:56a Rajeshms
+// [TAG] EIP73263
+// [Category] Improvement
+// [Description] PS2Ctl Driver Follow the UEFI Driver Model as per the
+// UEFI Spec.
+// [Files] ps2main.c, efismplpp.c
+//
+// 6 8/23/10 4:26a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.h
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 5 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 4 12/16/08 2:06a Iminglin
+// The function value of StopMouse for compliance.
+//
+// 3 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 2 3/04/05 1:37p Mandal
+//
+// 1 2/01/05 1:11a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 3 10/04/04 7:42p Olegi
+//
+// 2 9/21/04 2:29p Andriyn
+//
+// 1 9/14/04 2:56p Andriyn
+//
+// 4 9/14/04 2:46p Andriyn
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: efismplpp.c
+//
+// Description: PS/2 mouse implmentation of simple pointer protocol
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "ps2ctl.h"
+#include <AmiLib.h>
+#include "ps2ctl.h"
+#include "kbc.h"
+#include "ps2mouse.h"
+
+//----------------------------------------------------------------------
+
+
+extern MOUSE gMouse;
+extern EFI_GUID gDevicePathProtocolGuid;
+EFI_GUID gSimplePointerGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
+
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StartMouse
+//
+// Description: This routine is called from Driver Binding Start function.
+// It starts the mouse support
+//
+// Parameters:
+// EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this instance of driver
+// binding protocol structure
+// EFI_HANDLE Controller - Handle for this driver
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StartMouse (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *pDummyDevPath;
+ MOUSE* pmouse = 0;
+
+ if (EFI_ERROR(gSysTable->BootServices->OpenProtocol(
+ Controller,
+ &gDevicePathProtocolGuid,
+ &pDummyDevPath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DetectPS2KeyboardAndMouse();
+
+ if ( EFI_ERROR(InitMOUSE( &pmouse ))) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnMouse,
+ pmouse,
+ &pmouse->iSmplPtr.WaitForInput);
+ //
+ // Install protocol interfaces for the pointer device.
+ //
+ Status = gSysTable->BootServices->InstallProtocolInterface (
+ &Controller, &gSimplePointerGuid, EFI_NATIVE_INTERFACE,
+ &pmouse->iSmplPtr);
+
+ if (EFI_ERROR(Status)) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ gSysTable->BootServices->CloseEvent(pmouse->iSmplPtr.WaitForInput);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StopMouse
+//
+// Description: This routine is called from Driver Binding Start function.
+// It stops the mouse support
+//
+// Parameters:
+// EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this instance of driver
+// binding protocol structure
+// EFI_HANDLE Controller - Handle for this driver
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StopMouse (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller )
+{
+ EFI_STATUS Status;
+
+ //
+ // Kill wait event
+ //
+ Status = gSysTable->BootServices->CloseEvent(gMouse.iSmplPtr.WaitForInput);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Uninstall protocol interfaces from the Mouse device.
+ //
+ Status = gSysTable->BootServices->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gSimplePointerGuid, &gMouse.iSmplPtr,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Close protocols that is open during Start
+ //
+ Status = gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->FreePool(gMouse.iSmplPtr.Mode);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/hotkey.c b/Core/EM/PS2CTL/hotkey.c
new file mode 100644
index 0000000..21ef2b9
--- /dev/null
+++ b/Core/EM/PS2CTL/hotkey.c
@@ -0,0 +1,420 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/hotkey.c 9 4/27/11 4:38a Lavanyap $
+//
+// $Revision: 9 $
+//
+// $Date: 4/27/11 4:38a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/hotkey.c $
+//
+// 9 4/27/11 4:38a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 8 12/01/10 6:13a Anandv
+// [TAG] - EIP 45947
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Build Error on disabling INIT_DEFAULT_HOTKEYS SDL Token.
+// [RootCause] - KEY_ASSOCIATION structure variable not declared based on
+// INIT_DEFAULT_HOTKEYS SDL Token.
+// [Solution] - KEY_ASSOCIATION structure variable declared based on
+// INIT_DEFAULT_HOTKEYS SDL Token
+// [Files] - hotkey.c
+//
+// 7 8/23/10 4:31a Rameshr
+// Bug Fix: EIP 40818
+// Symptoms: Pause/Break function key has no function in logo screen
+// FilesModified: HotKey.c
+// Details:Pause key doesn't have valid Ps2 SCAN code. ProcesshotKey
+// function will get 0 as input for Pause key and it tries to execute the
+// invalid function.So getting exception.
+//
+// 6 1/06/10 12:09a Rameshr
+// Sometimes reset fail in BIOS Setup
+// EIP:33327
+// Ctrl+alt+del+Shift key also should reset the system
+//
+// 5 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 4 4/21/08 5:48p Olegi
+// Bugfix in RegisterHotKey routine for multiple hot keys.
+//
+// 3 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 2 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 1 2/01/05 1:11a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 1 9/30/04 8:07a Olegi
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: hotkeys.c
+//
+// Description: PS/2 keyboard hotkeys support routines
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "ps2ctl.h"
+#include "kbc.h"
+#include <Protocol\HotKeys.h>
+
+EFI_GUID gHotKeysGuid = EFI_HOT_KEYS_PROTOCOL_GUID;
+
+HOT_KEYS_PROTOCOL HotKeysProtocol;
+KEY_ASSOCIATION *HotKeys_Table;
+
+extern UINT8 MaxHotKeys;
+extern BOOLEAN InitDefaultHotKeys;
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CopyKey
+//
+// Description: HotKey helper function - Copies key codes from source to
+// target buffers
+//
+// Parameters:
+// KEY_ASSOCIATION *SrcKey - Pointer to source buffer
+// KEY_ASSOCIATION *TrgKey - Pointer to target buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CopyKey (
+ IN KEY_ASSOCIATION *SrcKey,
+ IN KEY_ASSOCIATION *TrgKey
+ )
+{
+ TrgKey->KeyCode = SrcKey->KeyCode;
+ TrgKey->KeyAttrib = SrcKey->KeyAttrib;
+ TrgKey->ReportKey = SrcKey->ReportKey;
+ TrgKey->KeyExtendedFunc = SrcKey->KeyExtendedFunc;
+ TrgKey->FunctionContext = SrcKey->FunctionContext;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RegisterHotKey
+//
+// Description: This is HotKey protocol API implementation function.
+// It registers the "extended" key function.
+//
+// Parameters: KEY_ASSOCIATION *HotKey - Key code to register
+// BOOLEAN ReplaceExisting - a rule that tells whether or
+// not we will replace the existing function; this
+// parameter will not be considered in case the function
+// for a given key is not assigned yet.
+//
+// Output : EFI_SUCCESS if function is successfully registered
+// EFI_OUT_OF_RESOURCES if we already have reached
+// MAX_HOTKEYS registered functions and we are not
+// replacing the existing one
+// EFI_ACCESS_DENIED if requested key has been already
+// assigned, can be returned only when ReplaceExisting
+// is FALSE
+//
+// Modified: HotKeys_Table
+//
+// Referrals: HotKeys_Table
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS RegisterHotKey (
+ IN KEY_ASSOCIATION *HotKey,
+ IN BOOLEAN ReplaceExisting )
+{
+
+ KEY_ASSOCIATION *hk = HotKeys_Table;
+ UINT8 i;
+ UINT8 emptySpot = 0xFF;
+ //
+ // See if the key is already registered, at the same time find the empty
+ // spot in HotKeys_Table
+ //
+ for (i = 0; i < MaxHotKeys; i++, hk++) {
+ if (!hk->KeyCode) { // empty entry found
+ if (emptySpot == 0xff) {
+ emptySpot = i;
+ }
+ continue;
+ }
+ if ((hk->KeyCode == HotKey->KeyCode) && (hk->KeyAttrib == HotKey->KeyAttrib)) {
+ if (ReplaceExisting) {
+ CopyKey(HotKey, hk);
+ return EFI_SUCCESS;
+ }
+ else {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ }
+ //
+ // We are here if the key duplicate is not found
+ //
+ if (emptySpot == 0xFF) {
+ return EFI_OUT_OF_RESOURCES; // no empty space found either
+ }
+
+ CopyKey(HotKey, &HotKeys_Table[emptySpot]); // fill in the new entry
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnregisterHotKeys
+//
+// Description: This is HotKey protocol API implementation function.
+// It unregisters all "extended" key functions.
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS if functions are successfully unregistered
+// EFI_ACCESS_DENIED if functions are not unregistered
+//
+// Modified: HotKeys_Table
+//
+// Referrals: HotKeys_Table
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UnregisterHotKeys()
+{
+ UINT8 i;
+ KEY_ASSOCIATION ZeroedEntry = {0};
+
+ for (i = 0; i < MaxHotKeys; i++) {
+ CopyKey(&ZeroedEntry, &HotKeys_Table[i]);
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ResetSystem
+//
+// Description: This routine performs a warm boot of the system
+//
+// Parameters: VOID *Context - Pointer to context
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ResetSystem (
+ VOID *Context )
+{
+ gSysTable->RuntimeServices->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitHotKeys
+//
+// Description: This routine is called from StartKeyboard function,
+// it initializes the PS/2 keyboard hot keys and produces
+// HotKeys protocol.
+//
+// Parameters: EFI_HANDLE Controller - Handle for this driver
+//
+// Output: EFI_STATUS - Status of the operation
+//
+// Modified: HotKeysProtocol
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitHotKeys (
+ EFI_HANDLE Controller )
+{
+ EFI_STATUS Status;
+ KEY_ASSOCIATION hk;
+ //
+ // Publish the hot key registration interface
+ //
+ HotKeysProtocol.RegisterHotKey = RegisterHotKey;
+ HotKeysProtocol.UnregisterHotKeys = UnregisterHotKeys;
+ Status = gSysTable->BootServices->InstallProtocolInterface (
+ &Controller,
+ &gHotKeysGuid,
+ EFI_NATIVE_INTERFACE,
+ &HotKeysProtocol
+ );
+ //
+ // Initialise the hotkeys table list
+ //
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ MaxHotKeys * sizeof(KEY_ASSOCIATION),
+ &HotKeys_Table );
+ pBS->SetMem( HotKeys_Table, MaxHotKeys * sizeof(KEY_ASSOCIATION), 0);
+
+ if ( InitDefaultHotKeys ) {
+ //
+ // Register Ctl+Alt+Del combination for Soft Reset
+ //
+ hk.KeyCode = 0x53;
+
+ hk.ReportKey = TRUE;
+ hk.KeyExtendedFunc = ResetSystem;
+ hk.FunctionContext = NULL;
+
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | LEFT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | RIGHT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | LEFT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | RIGHT_ALT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | LEFT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | LEFT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | LEFT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | LEFT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = LEFT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | LEFT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+ hk.KeyAttrib = RIGHT_CONTROL_PRESSED | RIGHT_ALT_PRESSED | RIGHT_SHIFT_PRESSED;
+ RegisterHotKey(&hk, TRUE);
+
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessHotKey
+//
+// Description: This routine searches the HotKey table for the matching
+// key and executes the corresponding "key extension"
+// function.
+//
+// Parameters: UINT8 Code - key make code
+// UINT16 KeyShiftState - Shift/Alt/Ctrl modifiers:
+// RIGHT_SHIFT_PRESSED 0x00000001
+// LEFT_SHIFT_PRESSED 0x00000002
+// RIGHT_CONTROL_PRESSED 0x00000004
+// LEFT_CONTROL_PRESSED 0x00000008
+// RIGHT_ALT_PRESSED 0x00000010
+// LEFT_ALT_PRESSED 0x00000020
+// RIGHT_LOGO_PRESSED 0x00000040
+// LEFT_LOGO_PRESSED 0x00000080
+//
+// Output: EFI_SUCCESS if 1)key is not found or 2)key is found,
+// function executed and key has to be reported back
+// to the caller;
+// EFI_NOT_READY if key is found but is not to be reported
+// back to the caller.
+// Referrals: HotKeys_Table
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ProcessHotKey (
+ UINT8 Code,
+ UINT16 KeyShiftState
+)
+{
+ KEY_ASSOCIATION *hk = HotKeys_Table;
+ UINT8 i;
+
+ //
+ // Validate the Input Data
+ //
+ if(Code == 0 && KeyShiftState == 0) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // Find the match in the table
+ //
+ for (i = 0; i < MaxHotKeys; i++) {
+ if ((hk->KeyCode == Code) && (hk->KeyAttrib == (UINT8)KeyShiftState)) {
+ //
+ // Match found - execute the function
+ //
+ hk->KeyExtendedFunc(hk->FunctionContext);
+ return (hk->ReportKey)? EFI_SUCCESS: EFI_NOT_READY;
+ }
+ hk++;
+ }
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/kbc.c b/Core/EM/PS2CTL/kbc.c
new file mode 100644
index 0000000..1712196
--- /dev/null
+++ b/Core/EM/PS2CTL/kbc.c
@@ -0,0 +1,1495 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.c 41 11/07/12 12:24a Srikantakumarp $
+//
+// $Revision: 41 $
+//
+// $Date: 11/07/12 12:24a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.c $
+//
+// 41 11/07/12 12:24a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 40 10/18/12 8:58a Deepthins
+// [TAG] EIP70313
+// [Category] Improvement
+// [Description] Used CheckIssueLEDCmd in function LEDsOnOff instead of
+// OutToKb(Kbd, 0xED)
+// [Files] kbc.c, ps2kbd.c and kbc.h
+//
+// 39 6/05/12 9:30a Lavanyap
+// [TAG] EIP91313
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] Ps2 keyboard does not work with Ps2Ctl label (INT)4.6.5.4
+// [RootCause] Could not process PS2 keyboard data since there were more
+// frequent calls to DISABLE the Keyboard.
+// [Solution] Disabled and enabled the keyboard only before processing
+// the PS2 keyboard data.
+// [Files] kbc.c
+//
+// 38 5/02/12 2:27a Deepthins
+// [TAG] EIP63116
+// [Category] Improvement
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 37 4/30/12 2:21a Rajeshms
+// [TAG] EIP86986
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Can not detect F8 key on PS2 Keyboard while booting to EFI
+// aware OS.
+// [RootCause] Make code of F8 key (0x42) is taken by int09h and EFI
+// aware OS calls only one ReadKeyStroke() for any key catch, Now PS2
+// driver will take Break Code of F8 key(0xC2) and returns EFI_NOT_READY.
+// [Solution] Multiple Read from PS2 keyboard is implemented and read
+// exits if any valid key is detected. Also, the BDA keyboard buffer is
+// checked for any missed key in EFI.
+// [Files] ps2kbd.c, kbc.c, CORE_DXE.sdl
+//
+// 36 2/01/12 1:59a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 35 8/02/11 4:43a Rameshr
+// [TAG] - EIP 58974
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Yellow exclamation mark in Windows when PS2 KB/MS are not
+// present.
+// [RootCause]- ACPI name space variable reports that PS2 device present
+// [Solution] - Updated the SIO device status based on the device present
+// after BDS.
+// [Files] - Kbc.c, Kbc.h , Ps2main.c
+//
+// 34 4/27/11 4:36a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 33 2/05/11 3:57p Artems
+// Fixed bug with ellow exclamation mark in Windows, when PS2 keyboard is
+// absent
+//
+// 32 1/24/11 3:39p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Removed token control of AutodetectKbdMousePortsPtr.
+// [Files] - kbc.c
+//
+// 31 1/05/11 1:02a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 30 12/10/10 5:28a Rameshr
+// [TAG] - EIP 47011
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DTM IO Tests fail due to presence of PS/2 devices that are
+// not ready - no PS/2 devices attached during test.
+// [RootCause]- PS2 device _STA method returns that, device is present .
+// [Solution] - Updated the SIO device status based on the device
+// presence.
+// [Files] - Kbc.c , Kbc.h, Mouse.c
+//
+// 29 8/23/10 4:37a Rameshr
+// Bug Fix: EIP 41862
+// Symptoms: If plug PS/2 KB only, Can`t use hot key enter iSCSI OPROM
+// .The CheckIssueLEDCmd routine cause PS2 keyboard not work.
+// FilesModified: Kbc.c
+// Details: Send Data immediately after sending LED command "ED".
+//
+// 28 8/23/10 4:23a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.c
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 27 7/01/10 9:03a Rameshr
+// Issue:If PS/2 KBD isn't present, KBC returns oxFE when send 0xED
+// command, that makes system to hang for 5 to 10 Sec.
+// Solution:If command output is 0xFE (Resent) , tried for 3 times and
+// gets out.
+// EIP 40515
+//
+// 26 8/04/09 4:32p Rameshr
+// Symptom: Boot to Shell and Press Ps2 keyboard Key, Reduces the EFI
+// available memory.
+// RootCause: Progress_code macro allocate the memory for the Data hub and
+// when ever key pressed , Disable/enable keyboard gets called. That sends
+// the progress code.
+// Solution: Removed the Progress code from Disable/Enable keyboard
+// functions.
+//
+// 25 7/01/09 5:29p Olegi
+// Correction: previous file headers changes were done on the older file.
+// Now changes are applied to the latest file.
+//
+// 24 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 23 4/20/09 1:53p Rameshr
+// CCB byte programmed once Keyboard controller is avilable.
+// EIP 19880-CCB byte not programmed
+//
+// 22 4/22/08 4:31p Felixp
+// Additional progress codes added
+//
+// 21 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 20 10/23/07 4:05p Olegi
+// Removed BDA related data storage.
+//
+// 19 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 18 3/19/07 2:22p Pats
+// Removed test for keyboard active. Issues start keyboard command on
+// logic of SDL tokens only.
+//
+// 17 3/13/07 5:35p Pats
+// Fixed problem of Lakeport not seeing setup key.
+//
+// 16 3/13/07 3:01p Pats
+// If keyboard detection is disabled, tests for keyboard active and issues
+// keyboard enable command only if it is not active. This preserves the
+// input key if there is one.
+//
+// 15 3/13/07 11:11a Pats
+// Added line to enable keyboard if keyboard detection is disabled.
+// Required for some platforms.
+//
+// 14 3/01/07 3:20p Pats
+// Fixed problem of mouse not working if keyboard detection disabled.
+//
+// 13 2/28/07 6:05p Pats
+// Made PS2 Keyboard detection removable with SDL token, to speed up boot,
+// and to keep keep Setup key (F2 or Del) from being absorbed.
+//
+// 12 4/12/06 9:14a Srinin
+// Write to Port 80h removed.
+//
+// 11 1/09/06 11:38a Felixp
+//
+// 9 12/22/05 10:23a Srinin
+// KBD Enable/Disable call optimized. Cleaned up the code.
+//
+// 8 10/27/05 1:04p Srinin
+// When command to KBD is given, check for Timeout error added.
+//
+// 7 10/11/05 4:14p Srinin
+// KBD and Mouse init done together. Re-entry problem fixed.
+//
+// 6 8/31/05 6:21p Srinin
+// Comments added to "AutodetectKbdMousePorts"
+//
+// 5 8/31/05 4:45p Srinin
+// When KBD not connected, DetectPS2Keyboard
+// will returns EFI_SUCCESS in order to support hot plug.
+//
+// 4 8/30/05 5:23p Srinin
+// PortSwap logic changed.
+//
+// 3 5/03/05 8:51a Olegi
+// Delay correction in OutToKb function.
+//
+// 2 2/25/05 10:34a Olegi
+// Removed duplicated code.
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 2 9/17/04 7:02p Olegi
+//
+// 1 8/27/04 3:18p Olegi
+// Initial VSS checkin.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: kbc.c
+//
+// Description: PS/2 Controller I/O support fuctions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "ps2ctl.h"
+#include "kbc.h"
+#include "genericSio.h"
+
+
+//----------------------------------------------------------------------
+
+extern BOOLEAN MouseResetRequired;
+extern BOOLEAN DetectPs2KeyboardValue;
+extern BOOLEAN InstallKeyboardMouseAlways;
+extern UINT32 IbFreeTimeoutValue;
+extern UINT32 IbFreeMaxTimeoutValue;
+BOOLEAN MouseEnableState = FALSE;
+BOOLEAN KBDEnableState = TRUE;
+BOOLEAN Ps2KbdDetected = FALSE;
+BOOLEAN Ps2KbdMouseDetected=FALSE;
+extern BOOLEAN Ps2MouseDetected;
+extern BOOLEAN KbdIrqSupport;
+extern UINT8 gKeyboardIrqInstall;
+extern EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+BOOLEAN InsidePS2DataDispatcher = FALSE;
+//----------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KBCDummyGetData
+//
+// Description: Reads keyboard data port to clear it
+//
+// Parameters: VOID *Context - Pointer to context
+//
+// Output: UINT8 - Keyboard data port data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBCDummyGetData (
+ VOID *Context )
+{
+ UINT8 bData;
+ bData = IoRead8(KBC_DATA_PORT);
+ TRACEKBD((-1,"KD %X ", bData));
+ return bData;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MouseDummyGetData
+//
+// Description: Reads keyboard data port to clear it
+//
+// Parameters: VOID *Context - Pointer to context
+//
+// Output: UINT8 - Keyboard data port data
+//
+// Modified: MouseResetRequired
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+MouseDummyGetData (
+ VOID *Context )
+{
+ UINT8 bData;
+ bData = IoRead8(KBC_DATA_PORT);
+ TRACEKBD((-1,"MD %X ", bData));
+ MouseResetRequired = TRUE; // Since a orphan mouse data is
+ // received, mouse packet will be out
+ // of sync.
+ return bData;
+
+}
+
+
+//----------------------------------------------------------------------
+// The following two fuction pointers are initialized with dummy
+// routines; they will be updated with the real routine pointers
+// in the corresponding device drivers' start functions.
+//----------------------------------------------------------------------
+
+STATEMACHINEPROC DrivePS2KbdMachine = KBCDummyGetData;
+STATEMACHINEPROC DrivePS2MouseMachine = MouseDummyGetData;
+
+extern KEYBOARD gKbd;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KBCBatTest
+//
+// Description: Runs Basic Assurance Test on KBC.
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS KBCBatTest()
+{
+ UINT16 wCounter = 0xFFFF;
+ PROGRESS_CODE(DXE_KEYBOARD_SELF_TEST);
+ //
+ // Empty KBC before BAT
+ //
+ for (; wCounter; wCounter--) {
+ IoRead8(KBC_DATA_PORT);
+ IoDelay();
+ if (!(IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF | KBC_IBF))) {
+ break;
+ }
+ }
+ if (!wCounter) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Perform BAT
+ //
+ if (Read8042(0xAA) != 0x55) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AutodetectKbdMousePorts
+//
+// Description: Auto detection of KB/MS using AMI KB-5. This code will
+// allow the connector swap of Keyboard and PS2 Mouse i.e.
+// keyboard can be connected to PS2 Mouse connector and
+// vice-versa.
+//
+// Parameters: None. AMI KB-5 present in the system, keyboard controller
+// BAT is complete.
+//
+// Output: None
+//
+//
+// Notes: This code should be used only if the motherboard has
+// AMI KB-5 which is also available in IO chipsets having KBC
+// e.g. SMC932, etc.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID AutodetectKbdMousePorts()
+{
+ UINT8 bData, Index;
+
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ WriteKeyboardCommand(0x60); // Lock KBD
+ IoRead8(KBC_DATA_PORT); // Discard any data
+
+ Write8042CommandByte(0x74); // KBD and Aux device disabled
+
+// Check for KBC version
+ IoRead8(KBC_DATA_PORT); // Discard any data
+ WriteKeyboardCommand(0xa1); //
+ if (!ObFullReadTimeout(&bData, 20, TRUE) && bData == 0x35) {
+
+ WriteKeyboardCommand(0x60);
+ WriteKeyboardData(4);
+
+ for (Index = 6; Index; Index--){ // Read max. 6 data
+ if (ObFullReadTimeout(&bData, 10, TRUE)) break;
+ }
+
+ WriteKeyboardCommand(0xa7); // Disable Mouse
+ WriteKeyboardCommand(0xc8); // Select Primary
+
+ WriteKeyboardData(rKeyboardID); // Read KBD ID
+
+ ObFullReadTimeout(&bData, 1000, TRUE); // Read ACK
+
+ if (bData == rKeyboardID) goto PortSwap;
+
+ if (bData == KB_ACK_COM) {
+ ObFullReadTimeout(&bData, 100, TRUE);
+// When Mouse is connected to KBD port, control goes to PortSwap here
+ if (!bData) goto PortSwap;
+ ObFullReadTimeout(&bData, 100, TRUE);
+ }
+ bData = IoRead8(KBC_CMDSTS_PORT);
+// When KBD is connected to the KBD port, control returns here
+ if (!(bData & KBC_TIMEOUT_ERR)) return;
+
+ WriteKeyboardCommand(0xD4); // Secondary Port
+ WriteKeyboardData(rKeyboardID); // Read KBD ID
+ ObFullReadTimeout(&bData, 1000, TRUE);
+ if (bData == rKeyboardID) return;
+ if (bData == KB_ACK_COM) {
+// When Mouse alone is connected to Mouseport, control returns here
+ if (!ObFullRead()) return;
+ bData = ObFullRead();
+ }
+ bData = IoRead8(KBC_CMDSTS_PORT);
+// When KBD alone is connected to Mouse port, no time out error and control
+// goes to portswap.
+ if (bData & KBC_TIMEOUT_ERR) return;
+
+PortSwap:
+ WriteKeyboardCommand(0xC9);
+ return;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AuxDeviceCommand
+//
+// Description: This routine issues AuxDevice command, and returns the
+// from the AUX device
+// the connector swap of Keyboard and PS2 Mouse i.e. keyboard
+// can be connected to PS2 Mouse connector and vice-versa.
+//
+// Parameters: UINT8 bCmd - AUX device command
+//
+// Output: UINT8 Data from AUX device
+//
+// Notes: Only AUX commands that expect the response from AUX device
+// can be executed using this function; otherwise the code will
+// be stuck waiting for OBF
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 AuxDeviceCommand (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return (UINT8)Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xD4);
+
+ return IssueCommand(bCmd);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IssueCommand
+//
+// Description: Helper function to read the data after executing AUX
+// device command.
+//
+// Parameters: UINT8 bCmd - AUX device command
+//
+// Output: UINT8 Data from AUX device
+//
+// Notes: Only AUX commands that expect the response from AUX device
+// can be executed using this function; otherwise the code will
+// be stuck waiting for OBF
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 IssueCommand (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return (UINT8)Status;
+ }
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+ for (;;)
+ {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) {
+ return IoRead8(KBC_DATA_PORT);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Read8042
+//
+// Description: Sends the given command to KBC, reads and returns the
+// acknowledgement byte returned from KBC.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+//
+// Output: UINT8 Acknowledgment byte
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 Read8042 (
+ UINT8 bCmd )
+{
+
+ UINT8 bData = 0xFE;
+ WriteKeyboardCommand(bCmd);
+ ObFullReadTimeout(&bData, 40, FALSE);
+ return bData;
+
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadDevice
+//
+// Description: Sends the given command to KBD, reads and returns the
+// acknowledgement byte returned from KBD.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+// UINT8 *Data - Pointer to data buffer
+// UINT8 Response - Response expected
+//
+// Output: EFI_SUCCESS - Data == Response
+// EFI_DEVICE_ERROR - Data != Response
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadDevice (
+ UINT8 bCmd,
+ UINT8 *Data,
+ UINT8 Response )
+{
+
+ WriteKeyboardData(bCmd);
+ if (ObFullReadTimeout(Data, 40, FALSE)) return EFI_DEVICE_ERROR;
+ if (*Data == Response) return EFI_SUCCESS;
+ return EFI_DEVICE_ERROR;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteKeyboardCommand
+//
+// Description: Writes command to KBC.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteKeyboardCommand (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, bCmd);
+ IbFree();
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WriteKeyboardData
+//
+// Description: Writes data to KBC.
+//
+// Parameters: UINT8 bCmd - Data to send to KBC
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID WriteKeyboardData (
+ UINT8 bCmd )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Write8042CommandByte
+//
+// Description: Writes CCB to KBC
+//
+// Parameters: UINT8 bCCB - Command byte to send to KBC
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID Write8042CommandByte (
+ UINT8 bCCB )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ WriteKeyboardCommand(0x60); // CMD to send command byte
+ IoWrite8(KBC_DATA_PORT, bCCB); // Write command byte into KBC
+ IbFree(); // Wait until input buffer is free
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullRead
+//
+// Description: Waits for Output Buffer Full and then reads the data port
+//
+// Parameters: None
+//
+// Output: UINT8 KBC Data port data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 ObFullRead()
+{
+ for (;;) {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) {
+ return IoRead8(KBC_DATA_PORT);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IbFree
+//
+// Description: Waits for Iutput Buffer to be empty
+//
+// Parameters: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID IbFree()
+{
+ for (;;) {
+ if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) {
+ break;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IbFreeTimeout
+//
+// Description: Waits a specified timeout for Iutput Buffer to be empty
+//
+// Parameters: UINT32 TimeoutValue
+//
+// Return value: EFI_STATUS (EFI_SUCCESS or EFI_TIMEOUT)
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS IbFreeTimeout( UINT32 TimeoutValue)
+{
+ UINTN i;
+
+ for (i = 0; i < TimeoutValue; i++) {
+ if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) {
+ return EFI_SUCCESS;
+ }
+ gSysTable->BootServices->Stall(1000); // 1 ms
+ }
+ return EFI_TIMEOUT;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IoDelay
+//
+// Description: Performs IO delay by executing IO read.
+//
+// Parameters: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID IoDelay()
+{
+ IoRead8(0x61);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullReadTimeout
+//
+// Description: This routine checks for the data availbility in output
+// buffer for a short period of time, if data is available
+// within this time, it reads and returns the data from
+// output buffer.
+//
+// Paremeters: UINT8* data - Pointer to the byte to be updated
+// UINT32 msec - Milliseconds timeout
+// BOOLEAN ONLYOBF - Only waits for OBF if true
+//
+// Output: BOOLEAN - Returns FALSE if data is successfully updated
+// (no timeout), data is updated
+// Returns TRUE if time-out
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+ObFullReadTimeout (
+ UINT8* data,
+ UINT32 msec,
+ BOOLEAN ONLYOBF )
+{
+
+ UINT8 bData;
+ UINT32 loopcount = msec << 1;
+
+
+ for (; loopcount; loopcount--) {
+
+ bData = IoRead8(KBC_CMDSTS_PORT);
+
+ if (ONLYOBF && (bData & KBC_OBF)) {
+ *data = IoRead8(KBC_DATA_PORT);
+ return FALSE;
+ }
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ *data = IoRead8(KBC_DATA_PORT);
+ if (bData & 0x40) {
+ TRACEKBD((-1, "Status Reg K : %x, %x\n", bData, *data));
+ return TRUE;
+ }
+ else return FALSE; // No timeout
+ }
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF | KBC_AUX_OBF)){
+ TRACEKBD((-1, "AUX OBF inside KBD"));
+ return TRUE;
+ }
+
+ gSysTable->BootServices->Stall(500); // 0.5msec
+
+ }
+ TRACEKBD((-1, "KBD data not available"));
+ return TRUE; // Timeout
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OutToKb
+//
+// Description: Send the given command to KDB during runtime.
+//
+// Parameters: KEYBOARD* kbd - Pointer to keyboard buffer
+// UINT8 bCmd - Command to send to keyboard
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+OutToKb (
+ KEYBOARD* kbd,
+ UINT8 bCmd )
+{
+ UINT8 bCounter1, bData;
+ UINT32 Counter;
+ EFI_STATUS Status;
+
+ //
+ // If Keyboard irq is supported, device acknowlegement is prossed by IRQ
+ // Handler. The acknowledgement data is stored in Kbd->CommandResponded
+ //
+ if(KbdIrqSupport && gKeyboardIrqInstall){
+ if(KBDEnableState) {
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+ for (Counter = 1000; Counter > 0; Counter--) {
+ if (kbd->CommandResponded == KB_ACK_COM){
+ kbd->CommandResponded =NULL;
+ return EFI_SUCCESS;
+ }
+ if (kbd->CommandResponded == KB_RSND_COM){
+ kbd->CommandResponded =NULL;
+ break;
+ }
+ gSysTable->BootServices->Stall(1000);
+ }
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+
+ for (bCounter1 = 3; bCounter1 > 0; bCounter1--) {
+ IbFree();
+ IoWrite8(KBC_DATA_PORT, bCmd);
+ IbFree();
+
+ for (Counter = 1000; Counter > 0; Counter--) {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) {
+ bData = IoRead8(KBC_DATA_PORT);
+ if (bData == 0xFA) {
+ return EFI_SUCCESS;
+ } else if (bData == 0xFE) {
+ break;
+ } else {
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_TIMEOUT_ERR) break;
+ //
+ // Insert the key into the buffer
+ //
+ if (kbd) {
+ HandleKBDData(kbd, bData);
+ if (kbd->KeyIsReady) {
+ ProcessHotKey(kbd->KeyData.PS2ScanCode, kbd->KeyData.KeyState.KeyShiftState);
+ InsertKeyToBuffer(kbd, &kbd->KeyData);
+ kbd->KeyIsReady = FALSE;
+ }
+ }
+ }
+ }
+ gSysTable->BootServices->Stall(1000); // 1msec
+ }
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DisableKeyboard
+//
+// Description: Disables KBD interface and reads the data from KBC
+// data port.
+//
+// Modified: KBDEnableState
+//
+// Referral(s): KBDEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DisableKeyboard()
+{
+ EFI_STATUS Status;
+
+ if (!KBDEnableState) return;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xAD);
+ IbFree();
+ KBDEnableState = FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EnableKeyboard
+//
+// Description: Enables KBD interface.
+//
+// Paremeters: None
+//
+// Output: Status
+//
+// Modified: KBDEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnableKeyboard()
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+
+ if (KBDEnableState) {
+ return EFI_SUCCESS;
+ }
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xAE);
+ Status = IbFreeTimeout(IbFreeTimeoutValue);
+ KBDEnableState = TRUE;
+ if (EFI_ERROR(Status)) {
+ KBDEnableState = FALSE;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DisableAuxDevice
+//
+// Description: Disables Aux interface.
+//
+// Paremeters: None
+//
+// Output: None
+//
+// Modified: MouseEnableState
+//
+// Referrals: MouseEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DisableAuxDevice()
+{
+ EFI_STATUS Status;
+ if (!MouseEnableState) return;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xA7);
+ IbFree();
+ MouseEnableState = FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EnableAuxDevice
+//
+// Description: Enables Aux interface.
+//
+// Paremeters: None
+//
+// Output: None
+//
+// Modified: MouseEnableState
+//
+// Referrals: MouseEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EnableAuxDevice()
+{
+ EFI_STATUS Status;
+ if (MouseEnableState) return;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xA8);
+ IbFree();
+ MouseEnableState = TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPS2KeyboardAndMouse
+//
+// Description: Detects the presence of Keyboard and Mouse in KBC port.
+//
+// Parameters: None. Keyboard interface is disabled.
+//
+// Output: Ps2KbdDetected and Ps2MouseDetected variable set accorinding
+// the device presence
+//
+// Modified: Ps2KbdDetected, Ps2MouseDetected
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPS2KeyboardAndMouse()
+{
+ UINT16 wCount;
+ UINT8 bData;
+ BOOLEAN bAck = FALSE;
+
+ if(Ps2KbdMouseDetected) {
+ //
+ // Ps2Keyboard and Mouse Detected already
+ //
+ return EFI_SUCCESS;
+ }
+
+ Ps2KbdMouseDetected=TRUE;
+
+ DetectPs2Mouse();
+
+
+ if ( DetectPs2KeyboardValue ) {
+
+ PROGRESS_CODE(DXE_KEYBOARD_DETECT);
+ Write8042CommandByte (0x6d);
+ KBCGetData(); // Dummy read
+
+ for (wCount = 0; wCount < 3; wCount++) {
+ // Disable Scanning
+ if (!ReadDevice(KBD_DISABLE_SCANNING, &bData, KB_ACK_COM)) break;
+ if (IoRead8(KBC_CMDSTS_PORT) & 0x40) { // Time out error
+ gSysTable->BootServices->Stall(6000); // 6 msec
+ // After power-up some junk data comes from KBD. If not eaten
+ // other command will fail.
+ KBCGetData();
+ }
+ }
+
+ DisableKeyboard();
+ KBCGetData();
+
+ //
+ // 3 times retry on keyboard reset
+ //
+ for (wCount = 0; wCount < 3; wCount++) {
+ if (!ReadDevice(KBD_RESET, &bData, KB_ACK_COM)) { // ACK received
+ TRACEKBD((-1,"KBD Reset Response %X ", bData));
+ bAck = TRUE;
+ break;
+ } else {
+ KBCGetData(); // Dummy read
+ }
+ }
+
+ if (bAck) { //If not not Keyboard
+ if (ObFullRead() == 0xAA) { // Reset successful
+ Ps2KbdDetected=TRUE;
+ } else if (Read8042(0xAB)) { // On Success returns 0
+ //
+ // 0x01 if Clock line stuck low, 0x02 if clock line stuck high,
+ // 0x03 if data line stuck low, and 0x04 if data line stuck high
+ //
+ Ps2KbdDetected=FALSE;
+ }
+ }
+
+ //
+ // Check for lock key
+ //
+ if (!(IoRead8(KBC_CMDSTS_PORT) & 0x10)) {
+ //
+ // Keyboard is locked, we can report it here
+ //
+ Ps2KbdDetected=FALSE;
+ }
+ } else {
+ Ps2KbdDetected = TRUE;
+ KBDEnableState = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UpdateSioVariableForKeyboardMouse
+//
+// Description: Update the SIO variable in the ACPI name space depend on the
+// Ps2keyboard and Mouse Present state.
+//
+// Parameters: None
+//
+// Output: None
+//
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateSioVariableForKeyboardMouse(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ static EFI_GUID SioDevStatusVarGuid = SIO_DEV_STATUS_VAR_GUID;
+ UINTN SioDevStatusVarSize = sizeof(SIO_DEV_STATUS);
+ SIO_DEV_STATUS SioDevStatus;
+ UINT32 SioDevStatusVarAttributes = 0;
+ EFI_STATUS Status;
+
+ //
+ // Get the SIO variable.
+ //
+ Status = pRS->GetVariable( SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ &SioDevStatusVarAttributes,
+ &SioDevStatusVarSize,
+ &SioDevStatus.DEV_STATUS);
+
+ //
+ // If variable not found return without updating it.
+ //
+ if(EFI_ERROR(Status)) {
+ SioDevStatus.DEV_STATUS = 0;
+ SioDevStatusVarAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ SioDevStatus.Res3 = 1; // To indicate that PS2 state vas updated
+ }
+
+ //
+ // Set the flag based on the Ps2 keyboard presence state
+ //
+ if(Ps2KbdDetected) {
+ SioDevStatus.Key60_64 = 1;
+ } else {
+ SioDevStatus.Key60_64 = 0;
+ }
+
+
+ //
+ // Set the Mouse flag based on the Mouse Presence state.
+ //
+ if(Ps2MouseDetected) {
+ SioDevStatus.Ps2Mouse = 1;
+ } else {
+ SioDevStatus.Ps2Mouse = 0;
+ }
+
+ //
+ // Set the SIO variable.
+ //
+ Status = pRS->SetVariable( SIO_DEV_STATUS_VAR_NAME,
+ &SioDevStatusVarGuid,
+ SioDevStatusVarAttributes,
+ SioDevStatusVarSize,
+ &SioDevStatus);
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPS2Keyboard
+//
+// Description: Detects the presence of Keyboard in KBC port.
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS if mouse is detected
+// EFI_NOT_FOUND if mouse is not detected
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPS2Keyboard( )
+{
+ if ( InstallKeyboardMouseAlways ) {
+ return EFI_SUCCESS;
+ } else {
+ return Ps2KbdDetected ? EFI_SUCCESS : EFI_NOT_FOUND;
+ }
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2DataDispatcher
+//
+// Description: This fuction checks whether data is available in the PS2
+// controller output buffer. If so, it gives control to the
+// corresponding state machine executor.
+//
+// Parameters: VOID *Context - Pointer to the context for this function
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PS2DataDispatcher (
+ VOID *Context )
+{
+ UINT8 data;
+ KEYBOARD *kbd = &gKbd;
+ UINT8 bIndicators;
+
+ bIndicators = kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+ if(KbdIrqSupport){
+
+ //
+ // if keyboard irq supported check status of SCRL/NUM/CPSL keys
+ // and send the command to Keyboard to update the LED status
+ //
+ UINT8 bIndicators = kbd->KeyData.KeyState.KeyToggleState & 7;
+ if (bIndicators != kbd->Indicators && kbd->LEDCommandState == 0){
+ LEDsOnOff(kbd);
+ }
+ return;
+ }
+
+ if (InsidePS2DataDispatcher) return;
+ InsidePS2DataDispatcher = TRUE;
+
+ for(data = IoRead8(KBC_CMDSTS_PORT); data & KBC_OBF; data = IoRead8(KBC_CMDSTS_PORT)) {
+ if (data & KBC_AUX_OBF) {
+ DrivePS2MouseMachine(Context);
+ }
+ else {
+ //
+ // Removed the DisableKeyboard() as to read multiple data from port60h,
+ // If any valid key is received we break out of the loop.
+ //
+ DrivePS2KbdMachine(Context);
+ if (CheckKeyinBuffer(kbd) ) {
+ break;
+ }
+ }
+ }
+
+ //
+ // Check LED state before issuing ED command
+ //
+ if (bIndicators != kbd->Indicators && kbd->LEDCommandState == 0) {
+ //
+ // Disable the keyboard before issuing ED command
+ //
+ DisableKeyboard();
+ CheckIssueLEDCmd(kbd);
+ }
+
+ //
+ //Process the led command and data
+ //
+ ProcessLEDCommandData(kbd);
+ EnableKeyboard();
+ InsidePS2DataDispatcher = FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckIssueLEDCmd
+//
+// Description: This function check if KBD LED command ED needs to be
+// issued.
+// If 'yes', sends ED command. No data is read.
+//
+// Parameters: KEYBOARD *kbd - Pointer to keyboard buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CheckIssueLEDCmd (
+ KEYBOARD *Kbd )
+{
+
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+
+ if (bIndicators != Kbd->Indicators && Kbd->LEDCommandState == 0) {
+ //
+ // Don't issue LED command when data is pending
+ //
+ if (IoRead8(KBC_CMDSTS_PORT) & KBC_OBF) return;
+ Kbd->LEDCommandState = ED_COMMAND_ISSUED;
+ WriteKeyboardData(0xED);
+ }
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessKBDResponse
+//
+// Description: If 0xFA is received as data, check for any pending ACK
+// and take necessary action.
+//
+// Parameters: KEYBOARD* kbd - Pointer to keyboard buffer
+// UINT8 bData - Data received from keyboard
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ProcessKBDResponse (
+ KEYBOARD *Kbd,
+ UINT8 Data )
+{
+
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+
+ switch (Data) {
+ case 0xFA:
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ Kbd->LEDCommandState = ED_DATA_ISSUED;
+ Kbd->Indicators = bIndicators;
+ WriteKeyboardData(bIndicators);
+ break;
+ }
+
+ if (Kbd->LEDCommandState == ED_DATA_ISSUED) {
+ Kbd->LEDCommandState = 0;
+ break;
+ }
+
+
+ case 0xFE:
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED || Kbd->LEDCommandState == ED_DATA_ISSUED) {
+// Error occured. Clear out the current indicator bits.
+// Modifiers will have the correct bits that needs to be set.
+// Next Call to CheckIssueLEDCmd will detect the mismatch
+// and start the LED sequence.
+ WriteKeyboardData(0xF4);
+ Kbd->LEDCommandState = 0;
+ bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7;
+ Kbd->KeyData.KeyState.KeyToggleState &=
+ ~(SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE);
+ Kbd->Indicators &= 0xf0;
+ break;
+ }
+
+ case 0xFF:
+ Kbd->LEDCommandState = 0;
+ break;
+ default: break;
+ }
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KBCGetData
+//
+// Description: Reads and returns byte of data from KBC data port. Also
+// used as dummy KBC data process routine.
+//
+// Parameters: VOID *Context - Pointer to the context of this function
+//
+// Output: UINT8 Data read from KBC Data port.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 KBCGetData ()
+{
+ UINT8 Data;
+ Data = IoRead8(KBC_DATA_PORT);
+
+ return Data;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/kbc.h b/Core/EM/PS2CTL/kbc.h
new file mode 100644
index 0000000..44ec5ea
--- /dev/null
+++ b/Core/EM/PS2CTL/kbc.h
@@ -0,0 +1,321 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.h 25 11/07/12 12:25a Srikantakumarp $
+//
+// $Revision: 25 $
+//
+// $Date: 11/07/12 12:25a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/kbc.h $
+//
+// 25 11/07/12 12:25a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 23 10/18/12 9:00a Deepthins
+// [TAG] EIP70313
+// [Category] Improvement
+// [Description] Used CheckIssueLEDCmd in function LEDsOnOff instead of
+// OutToKb(Kbd, 0xED)
+// [Files] kbc.c, ps2kbd.c and kbc.h
+//
+// 22 5/02/12 2:28a Deepthins
+// [TAG] EIP63116
+// [Category] Improvement
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 21 4/24/12 2:18a Deepthins
+// [TAG] EIP85747
+// [Category] Improvement
+// [Description] USB-ReadKeyStrokeEx is returning EFI_SUCCESS with
+// KEY_STATE_EXPOSED for Caps, Num and Scroll Lock Key's.
+// KEY_STATE_EXPOSED only for the ShiftState Key's and not for togglestate
+// key's.
+//
+// [Files] Efiusbkb.c, ps2kbd.c and kbc.h
+//
+// 20 2/01/12 1:59a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 19 9/22/11 6:32a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h
+//
+// 18 8/02/11 4:43a Rameshr
+// [TAG] - EIP 58974
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Yellow exclamation mark in Windows when PS2 KB/MS are not
+// present.
+// [RootCause]- ACPI name space variable reports that PS2 device present
+// [Solution] - Updated the SIO device status based on the device present
+// after BDS.
+// [Files] - Kbc.c, Kbc.h , Ps2main.c
+//
+// 17 1/05/11 1:00a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 16 12/10/10 5:30a Rameshr
+// [TAG] - EIP 47011
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DTM IO Tests fail due to presence of PS/2 devices that are
+// not ready - no PS/2 devices attached during test.
+// [RootCause]- PS2 device _STA method returns that, device is present .
+// [Solution] - Updated the SIO device status based on the device
+// presence.
+// [Files] - Kbc.c , Kbc.h, Mouse.c
+//
+// 15 8/23/10 4:23a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.c
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 14 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 13 4/21/08 5:49p Olegi
+// Removed keyboard modifiers bits definition, they should be taken from
+// SimpleTextInEx.h
+//
+// 12 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 11 9/07/07 4:34p Olegi
+// EFI_KEY code implementation.
+//
+// 10 8/31/07 2:17p Olegi
+// Added SimpleTextInEx definitions.
+//
+// 9 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 8 3/13/06 2:38a Felixp
+//
+// 7 1/09/06 11:38a Felixp
+//
+// 5 12/22/05 10:22a Srinin
+// ProcessKBDData added.
+//
+// 4 10/11/05 4:11p Srinin
+// New function declarations added.
+//
+// 3 8/30/05 1:15p Srinin
+// KEYBOARD struct modified.
+//
+// 2 3/04/05 1:38p Mandal
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 3 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 2 9/17/04 7:02p Olegi
+//
+// 1 8/27/04 3:17p Olegi
+// Initial VSS checkin.
+//
+// 4 8/18/04 6:37p Olegi
+// Header and footer added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: kbc.h
+//
+// Description: Keyboard Controller functions header
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __PS2_KBC_SUPPORT_H__
+#define __PS2_KBC_SUPPORT_H__
+
+#include <Protocol\Cpu.h>
+#include <Protocol\Legacy8259.h>
+//
+// KBC command/status/data IO ports
+//
+#define KBC_CMDSTS_PORT 0x64
+#define KBC_DATA_PORT 0x60
+
+//
+// KBC status bits definition
+//
+#define KBC_OBF 0x01
+#define KBC_IBF 0x02
+#define KBC_SYSFLAG 0x04
+#define KBC_CMD_DATA 0x08
+#define KBC_INHIBIT_SW 0x10
+#define KBC_AUX_OBF 0x20
+#define KBC_TIMEOUT_ERR 0x40
+#define KBC_PARITY_ERR 0x80
+
+//
+// COMMANDS from KEYBOARD to SYSTEM
+//
+#define KB_ACK_COM 0xFA // ACKNOWLEDGE command
+#define KB_RSND_COM 0xFE // RESEND command
+#define KB_OVRN_COM 0xFF // OVERRUN command
+#define KB_DIAG_FAIL_COM 0xFD // DIAGNOSTIC FAILURE command
+
+#define KBD_ENABLE_SCANNING 0xF4
+#define KBD_DISABLE_SCANNING 0xF5
+#define KBD_RESET 0xFF
+
+#define rKeyboardID 0xF2
+#define rMouseID 0xF2
+
+//
+// Keyboard scanner states
+//
+#define KBST_READY 0
+#define KBST_E0 1
+#define KBST_E1 2
+
+#define BUFFER_SIZE 16
+#define SYSTEM_KEYBOARD_IRQ 0x01
+#define SYSTEM_MOUSE_IRQ 0x0C
+#define SLAVE_IRQ 0X02
+// LED inter command state
+#define ED_COMMAND_ISSUED 0x01
+#define ED_DATA_ISSUED 0x02
+
+typedef struct {
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL iSimpleIn;
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL iSimpleInEx;
+ AMI_EFIKEYCODE_PROTOCOL iKeycodeInEx;
+ AMI_EFI_KEY_DATA KeyData;
+ BOOLEAN KeyIsReady;
+ UINT8 ScannerState;
+ AMI_EFI_KEY_DATA* pBufHead;
+ AMI_EFI_KEY_DATA* pBufTail;
+ AMI_EFI_KEY_DATA* pBufStart;
+ AMI_EFI_KEY_DATA* pBufEnd;
+ UINT8 Count;
+// UINT16 Modifiers;
+ UINT8 Indicators;
+ UINT8 LEDCommandState;
+ UINT8 CommandResponded;
+} KEYBOARD;
+
+typedef struct {
+ UINT8 KbdBuffer[BUFFER_SIZE];
+ UINT8 KbdIndex;
+} KEYBOARD_IRQ_STORE;
+
+EFI_STATUS KBCBatTest();
+UINT8 Read8042(UINT8 bCmd);
+UINT8 ObFullRead();
+void WriteKeyboardCommand(UINT8 bCmd);
+void WriteKeyboardData(UINT8 bCmd);
+void Write8042CommandByte(UINT8 bCCB);
+void IbFree();
+EFI_STATUS IbFreeTimeout(UINT32 TimeoutValue);
+void IoDelay();
+void AutodetectKbdMousePorts();
+EFI_STATUS ReadDevice(UINT8 bCmd, UINT8 *Data, UINT8 Response);
+BOOLEAN ObFullReadTimeout(UINT8* data, UINT32 msec, BOOLEAN ONLYOBF);
+UINT8 IssueCommand(UINT8 bCmd);
+UINT8 AuxDeviceCommand(UINT8 bCmd);
+EFI_STATUS OutToKb(KEYBOARD* kbd, UINT8 bCmd);
+EFI_STATUS InsertKeyToBuffer (KEYBOARD* kbd, AMI_EFI_KEY_DATA *key);
+EFI_STATUS GetKeyFromBuffer (KEYBOARD* kbd, VOID* key, UINT8 size);
+BOOLEAN CheckKeyinBuffer (KEYBOARD* kbd);
+void ReadAndProcessKey(void *Context);
+void DisableKeyboard();
+EFI_STATUS EnableKeyboard();
+void DisableAuxDevice();
+void EnableAuxDevice();
+void LEDsOnOff(KEYBOARD* kbd);
+void CheckIssueLEDCmd (KEYBOARD *kbd);
+void ProcessKBDResponse (KEYBOARD *kbd, UINT8 bData);
+EFI_STATUS DetectPS2Keyboard();
+EFI_STATUS DetectPS2KeyboardAndMouse();
+void HandleKBDData(void *Context, UINT8 data);
+void ProcessKBDData (KEYBOARD *kbd, UINT8 data);
+BOOLEAN ObFullReadMTimeout(UINT8* data, UINT32 msec);
+EFI_STATUS ReadDeviceM(UINT8 bCmd, UINT8 *Data, UINT8 Response);
+EFI_STATUS InitHotKeys(EFI_HANDLE Controller);
+EFI_STATUS ProcessHotKey(UINT8 code, UINT16 modifiers);
+EFI_STATUS DetectPs2Mouse();
+EFI_STATUS GetMouseData();
+VOID UpdateSioVariableForKeyboardMouse(
+ EFI_EVENT Event,
+ VOID *Context
+);
+EFI_STATUS
+CheckPartialKey (
+ KEYBOARD *Kbd,
+ EFI_KEY_DATA *Key
+);
+VOID InitKeyboardIrq(VOID);
+void ProcessLEDCommandData(KEYBOARD* kbd);
+EFI_STATUS ProcessMultiLanguage(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+ );
+#endif // __PS2_KBC_SUPPORT_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/mouse.c b/Core/EM/PS2CTL/mouse.c
new file mode 100644
index 0000000..7fdbbfc
--- /dev/null
+++ b/Core/EM/PS2CTL/mouse.c
@@ -0,0 +1,1215 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/mouse.c 24 11/07/12 12:26a Srikantakumarp $
+//
+// $Revision: 24 $
+//
+// $Date: 11/07/12 12:26a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/mouse.c $
+//
+// 24 11/07/12 12:26a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 23 10/18/12 9:49a Deepthins
+// [TAG] EIP95111
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PS2 mouse is not working in setup.
+// [RootCause] In stream mode data reporting is disabled by default. The
+// mouse will not actually issue any movement data packets until it
+// receives the "Enable Data Reporting" (0xF4) command. So even when the
+// DETECT_PS2_KEYBOARD and DETECT_PS2_MOUSE token is disabled we need to
+// send command 0xf4 to Enable Data Reporting.
+// [Solution] In MouseReset function, Set sampleRate ,Resolution and
+// Enable streaming.
+// [Files] mouse.c and ps2kbd.c
+//
+// 22 5/02/12 2:28a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 21 2/01/12 2:00a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 20 9/19/11 9:38a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 19 7/29/11 1:07a Lavanyap
+// [TAG] EIP63310
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MouseGetState() does not differentiate between driver busy
+// and no state change between GetState calls.
+// [RootCause] MouseGetState() return status codes does not follow UEFI
+// specification.
+// [Solution] MouseGetState() return status codes has been updated as
+// per UEFI specification.
+// [Files] mouse.c
+//
+// 18 4/27/11 4:37a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 17 12/10/10 5:31a Rameshr
+// [TAG] - EIP 47011
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - DTM IO Tests fail due to presence of PS/2 devices that are
+// not ready - no PS/2 devices attached during test.
+// [RootCause]- PS2 device _STA method returns that, device is present .
+// [Solution] - Updated the SIO device status based on the device
+// presence.
+// [Files] - Kbc.c , Kbc.h, Mouse.c
+//
+// 16 8/23/10 4:25a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.h
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 15 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 14 10/08/08 4:55p Olegi
+// Change in GetMouseData that will reset the mouse in case the recieved
+// packet is wrong. The failure was observed in TSE.
+//
+// 13 4/22/08 4:31p Felixp
+// Additional progress codes added
+//
+// 12 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 11 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 10 3/01/07 3:43p Pats
+// Modified for faster boot if keyboard detection disabled.
+//
+// 9 5/05/06 5:23p Ambikas
+//
+// 8 1/09/06 11:38a Felixp
+//
+// 6 12/22/05 10:25a Srinin
+// Cleaned up the code. KBD disable inside GetMousedata removed.
+//
+// 5 10/11/05 4:15p Srinin
+// Mouse is initialized for Streaming mode but kept disabled. Re-entry
+// problem fixed.
+//
+// 4 7/18/05 3:37p Felixp
+//
+// 3 3/04/05 1:36p Mandal
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Mouse.c
+//
+// Description: This is the PS/2 mouse EFI driver source file.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: mouse.c
+//
+// Description: PS/2 mouse I/O support fuctions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include <Efi.h>
+#include <AmiLib.h>
+#include "ps2ctl.h"
+#include "kbc.h"
+#include "ps2mouse.h"
+
+STATEMACHINEPROC DrivePS2MouseMachine;
+BOOLEAN Ps2MouseDetected = FALSE;
+UINT8 MouseData[5] = {0,};
+BOOLEAN InsideGetMouseData = FALSE;
+BOOLEAN MouseResetRequired = FALSE;
+UINT8 ByteCount = NON_WHEEL_REPORT_FORMAT;
+extern BOOLEAN InsideKbdReadKey;
+extern BOOLEAN InsideOnWaitingOnKey;
+extern KEYBOARD gKbd;
+typedef struct _STATE;
+MOUSE gMouse = {0,};
+EFI_CPU_ARCH_PROTOCOL *gCpuArch;
+EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+UINT8 gMouseIrqInstall = FALSE;
+extern UINT8 gKeyboardIrqInstall;
+extern BOOLEAN KBDEnableState;
+UINT8 gCurrentMouseIndex = NULL;
+UINT8 gGetMouseStateStart=FALSE;
+VOID GetMouseDataFromIrq(VOID);
+UINT8 gMouseCommandActive=FALSE;
+BOOLEAN InsideMouseReset;
+extern BOOLEAN MsIrqSupport;
+extern BOOLEAN MouseEnableState;
+extern BOOLEAN DetectPs2MouseValue;
+extern BOOLEAN InstallKeyboardMouseAlways;
+extern BOOLEAN KbdIrqSupport;
+extern BOOLEAN InsideKbdReset;
+extern UINT32 IbFreeMaxTimeoutValue;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullRead
+//
+// Description: Waits for Output Buffer Full and then reads the data port
+//
+// Parameters: None
+//
+// Output: UINT8 KBC Data port data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 ObFullReadM()
+{
+ for (;;) {
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+ return IoRead8(KBC_DATA_PORT);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ObFullReadMTimeout
+//
+// Description: This routine checks for the data availbility in output
+// buffer for a short period of time, if data is available
+// within this time, it reads and returns the data from
+// output buffer.
+//
+// Paremeters: UINT8* data - Pointer to the byte to be updated
+// UINT32 msec - Milliseconds timeout
+//
+// Output: BOOLEAN - Returns FALSE if data is successfully updated
+// (no timeout), data is updated
+// Returns TRUE if time-out
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN ObFullReadMTimeout (
+ UINT8* data,
+ UINT32 msec )
+{
+
+ UINT8 bData;
+ UINT32 loopcount = msec << 1;
+
+ for (; loopcount; loopcount--) {
+
+ bData = IoRead8(KBC_CMDSTS_PORT);
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+
+ *data = IoRead8(KBC_DATA_PORT);
+ if (bData & 0x40) {
+ *data = IoRead8(KBC_DATA_PORT);
+ TRACEKBD((-1, "Status Reg M : %x, %x\n", bData, *data));
+ return TRUE;
+ }
+ else return FALSE; // No timeout
+
+ }
+
+ if ((bData & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF)){
+ TRACEKBD((-1, "KB OBF inside Mouse"));
+ return TRUE;
+ }
+
+ gSysTable->BootServices->Stall(500); // 0.5 msec
+
+ }
+
+ return TRUE; // Timeout
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadDeviceM
+//
+// Description: Sends the given command to KBD, reads and returns the
+// acknowledgement byte returned from KBD.
+//
+// Parameters: UINT8 bCmd - Command to send to KBC
+// UINT8 *Data - Pointer to data buffer
+// UINT8 Response - Response expected
+//
+// Output: EFI_SUCCESS - Data == Response
+// EFI_DEVICE_ERROR - Data != Response
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadDeviceM (
+ UINT8 bCmd,
+ UINT8 *Data,
+ UINT8 Response )
+{
+ EFI_STATUS Status;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xD4);
+ IbFree();
+ WriteKeyboardData(bCmd);
+
+ if (ObFullReadMTimeout(Data, 1000)) {
+ return EFI_DEVICE_ERROR;
+ }
+ if (*Data == Response) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MouseInterruptHandler
+//
+// Description: An interrupt handler for PS2 mouse
+//
+//
+// Input: InterruptType Interrupt type
+// SystemContext System context
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MouseInterruptHandler(
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+)
+{
+ EFI_TPL OldTpl=NULL;
+ KEYBOARD *Kbd = &gKbd;
+
+ //
+ // Disable interrupt to prevent interrupt chaining
+ //
+ gCpuArch->DisableInterrupt(gCpuArch);
+
+ //
+ // Post Code verifies the Mouse IRQ generation by sending command 0xD4(Write mouse device)
+ // and data. For the data if the control comes to Mouse IRQ handler, and IRQ method is enabled
+ // and active. Otherwise it will disable the Mouse IRQ
+
+ if (gMouseCommandActive){
+ gMouseIrqInstall = TRUE;
+ //
+ // Throw out the Dummy data that we sent to test the Mouse IRQ generation
+ //
+ IoRead8(KBC_DATA_PORT);
+
+ } else {
+
+ //
+ // Handle the Mouse Data
+ //
+ GetMouseDataFromIrq();
+ }
+
+ EnableAuxDevice();
+
+ //
+ // Send End Of Interrupt command twice as PIC is connected
+ // in cascade mode, once for master and once for corresponding
+ // slave
+ //
+ mLegacy8259->EndOfInterrupt(mLegacy8259, SYSTEM_MOUSE_IRQ);
+ mLegacy8259->EndOfInterrupt(mLegacy8259, SLAVE_IRQ);
+ gCpuArch->EnableInterrupt(gCpuArch);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitMOUSE
+//
+// Description: Initializes mouse driver
+//
+// Parameters: MOUSE** ppMouse - Pointer to mouse structure
+//
+// Output: EFI_SUCCESS - Mouse initialized
+// EFI_DEVICE_ERROR - Mouse not detected
+// EFI_OUT_OF_RESOURCES - Not enough memory for buffers
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS InitMOUSE (
+ MOUSE** ppMouse )
+{
+ MOUSE* pmouse;
+ EFI_STATUS Status;
+ UINT32 MouseVector = NULL;
+ UINT32 loopcount = 1000;
+
+ pmouse = *ppMouse = &gMouse;
+
+ MemSet( &pmouse->state, sizeof(pmouse->state), 0 );
+ pmouse->saved_flags=0;
+
+ if (EFI_ERROR(DetectPS2mouse(pmouse))) {
+ //
+ // Ps2 Mouse not Present.
+ //
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Ps2 Mouse Present. Install Simple Pointer protocol.
+ //
+ (pmouse->iSmplPtr).Mode = MallocZ(sizeof (EFI_SIMPLE_POINTER_MODE));
+
+ if(!((pmouse->iSmplPtr).Mode)) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Check for mouse IRQ support.
+ //
+ if(MsIrqSupport){
+ if (!gMouseIrqInstall){
+ if(mLegacy8259 == NULL){
+ Status = pBS->LocateProtocol(&gEfiLegacy8259ProtocolGuid, NULL, &mLegacy8259);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Find the CPU Arch Protocol
+ //
+ if(gCpuArch == NULL){
+ Status = pBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, &gCpuArch);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ //
+ // Get Mouse vector
+ //
+ Status = mLegacy8259->GetVector(mLegacy8259, SYSTEM_MOUSE_IRQ, (UINT8 *) & MouseVector);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // Register interrupt handler for mouse
+ //
+ Status = gCpuArch->RegisterInterruptHandler(gCpuArch, MouseVector, MouseInterruptHandler);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // To set the interrupt mode operation in legacy mode
+ //
+
+ mLegacy8259->SetMode(mLegacy8259,Efi8259LegacyMode,NULL,NULL);
+ //
+ // Enable Mouse interrupt
+ //
+ Status = mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = mLegacy8259->EnableIrq(mLegacy8259, 0x02, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // To set the interrupt mode operation in protected mode
+ //
+ mLegacy8259->SetMode(mLegacy8259,Efi8259ProtectedMode,NULL,NULL);
+
+ //
+ // Enable PS2 mouse interrupt
+ //
+ Status = mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Enable Master PIC interrupt IRQ2
+ //
+ Status = mLegacy8259->EnableIrq(mLegacy8259, 0x02, FALSE);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // Enable INT2 bit in command register.
+ //
+ Write8042CommandByte(0x67);
+
+ // Is Mouse IRQ active?
+ gMouseCommandActive = TRUE;
+ Status = IbFreeTimeout(IbFreeMaxTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ IoWrite8(KBC_CMDSTS_PORT, 0xD4);
+ IbFree();
+ //
+ // Write mouse data
+ //
+ WriteKeyboardData(0xf4);
+
+ for (; loopcount; loopcount--) {
+ if (gMouseIrqInstall) break;
+ gSysTable->BootServices->Stall(500); // 0.5 msec
+ }
+ gMouseCommandActive = FALSE;
+
+ //
+ // If Mouse irq is not installed then disable interrupt
+ //
+ if (!gMouseIrqInstall){
+ //
+ // a dummy read after writing to mouse
+ //
+ IoRead8(0x60);
+ Write8042CommandByte(0x65);
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ);
+
+ }
+ }
+ }
+
+ (pmouse->iSmplPtr).Mode->ResolutionX = 4;
+ (pmouse->iSmplPtr).Mode->ResolutionY = 4;
+ (pmouse->iSmplPtr).Mode->ResolutionZ = 4;
+ (pmouse->iSmplPtr).Mode->RightButton = TRUE;
+ (pmouse->iSmplPtr).Mode->LeftButton = TRUE;
+
+ //
+ // Initialize pointer interface functions
+ //
+ (pmouse->iSmplPtr).Reset = (EFI_SIMPLE_POINTER_RESET)MouseReset;
+ (pmouse->iSmplPtr).GetState= (EFI_SIMPLE_POINTER_GET_STATE)MouseGetState;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPs2Mouse
+//
+// Description:
+// Implements Reset operation of SimplePointer protocol.
+// As part of initialization process, the firmware/device will make a quick
+// but reasonable attempt to verify that the device is functioning. If the
+// ExtendedVerification flag is TRUE the firmware may take an extended amount
+// of time to verify the device is operating on reset. Otherwise the reset
+// operation is to occur as quickly as possible.
+//
+// Parameters: None
+//
+// Output:
+// Returns EFI_SUCCESS if the device was reset, othewise returns
+// EFI_DEVICE_ERROR - device is not functioning correctly and could
+// not be reset.
+//
+// Modified: MouseEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPs2Mouse()
+{
+
+ UINT8 bData = 0, b1, b2, loop;
+ EFI_STATUS Status;
+
+ if ( DetectPs2MouseValue ) {
+
+
+ PROGRESS_CODE(DXE_MOUSE_RESET);
+
+ for (loop = 3; loop; loop--) {
+
+ if ((IoRead8(KBC_CMDSTS_PORT) & KBC_OBF)) {
+ TRACEKBD((-1,"KBD"));
+ //
+ // Consume Data and discard it
+ //
+ KBCGetData();
+ }
+
+ TRACEKBD((-1,"Reseting mouse...\n"));
+
+ Status = ReadDeviceM(0xFF, &bData, 0xFA);
+ TRACEKBD((-1,"%x, %x ", bData, Status));
+ //
+ // ACK received
+ //
+ if (Status == EFI_SUCCESS) {
+
+ if (ObFullReadMTimeout(&b1, 1000)) {
+ continue;
+ }
+ if (ObFullReadMTimeout(&b2, 1000)) {
+ continue;
+ }
+
+ TRACEKBD((-1,"Data %x; %x\n",b1,b2));
+
+ if ( b1 == 0xAA && b2 == 0x00) {
+ TRACEKBD((-1,"Reset Mouse Ok\n"));
+
+ //
+ // Enable wheel report format
+ //
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0xC8, &bData, 0xFA))) {
+ continue; // 200 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 100 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x50, &bData, 0xFA))) {
+ continue; // 80 samples/sec
+ }
+
+ ReadDeviceM(0xF2, &bData, 0xFA); // Read Mouse ID
+ ObFullReadMTimeout(&bData, 1000);
+
+ // If scroll wheel is supported Mouse Response = 3
+ // else Mouse Response = 0
+ if (bData == 3) {
+ ByteCount = WHEEL_REPORT_FORMAT;
+ }
+
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 20 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xE8, &bData, 0xFA))) {
+ continue; // Set resolution
+ }
+ if (EFI_ERROR(ReadDeviceM(0x2, &bData, 0xFA))) {
+ continue; // 4 Count/mm
+ }
+
+ //
+ // Enable streaming
+ //
+ ReadDeviceM(0xF4, &bData, 0xFA);
+
+ MouseEnableState = TRUE;
+ DisableAuxDevice();
+ Ps2MouseDetected = TRUE;
+
+ return EFI_SUCCESS;
+
+ }
+ }
+ }
+
+ //
+ // Ps2 Mouse Not Present. Return with Error.
+ //
+ return EFI_DEVICE_ERROR;
+ } else {
+ //
+ // By default Ps2 mouse is enabled and Present
+ //
+ MouseEnableState = TRUE;
+ Ps2MouseDetected = TRUE;
+ return EFI_SUCCESS;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MouseReset
+//
+// Description:
+// Implements Reset operation of SimplePointer protocol.
+// As part of initialization process, the firmware/device will make a quick
+// but reasonable attempt to verify that the device is functioning. If the
+// ExtendedVerification flag is TRUE the firmware may take an extended amount
+// of time to verify the device is operating on reset. Otherwise the reset
+// operation is to occur as quickly as possible.
+//
+// Parameters:
+// MOUSE *self - pointer to the mouse structure
+// BOOLEAN extended - Indicates that the driver may perform a more exhaustive
+// verification operation of the device during reset.
+//
+// Output:
+// Returns EFI_SUCCESS if the device was reset, othewise returns
+// EFI_DEVICE_ERROR - device is not functioning correctly and could
+// not be reset.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS MouseReset(
+ MOUSE *self,
+ BOOLEAN extended)
+{
+ UINT8 bData = 0;
+ UINT8 b1;
+ UINT8 b2;
+ UINT8 loop;
+ EFI_STATUS Status;
+
+
+ //
+ // If ExtendedVerification Flag is true then reset the mouse, set
+ // sampleRate and Resolution and Enable streaming.
+ //
+ if(extended) {
+
+ InsideMouseReset = TRUE;
+ Write8042CommandByte(0x74);
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport ) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ);
+ }
+
+ //
+ // Check for mouse IRQ support
+ //
+ if(MsIrqSupport) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->DisableIrq(mLegacy8259, SLAVE_IRQ);
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ);
+ }
+
+ for (loop = 3; loop; loop--) {
+
+ if ((IoRead8(KBC_CMDSTS_PORT) & KBC_OBF)) {
+ TRACEKBD((-1,"KBD"));
+ //
+ // Consume Data and discard it
+ //
+ KBCGetData();
+ }
+
+ TRACEKBD((-1,"Reseting mouse...\n"));
+
+ Status = ReadDeviceM(0xFF, &bData, 0xFA);
+ TRACEKBD((-1,"%x, %x ", bData, Status));
+ //
+ // ACK received
+ //
+ if (Status == EFI_SUCCESS) {
+
+ ByteCount = NON_WHEEL_REPORT_FORMAT;
+
+ if (ObFullReadMTimeout(&b1, 1000)) {
+ continue;
+ }
+ if (ObFullReadMTimeout(&b2, 1000)) {
+ continue;
+ }
+
+ TRACEKBD((-1,"Data %x; %x\n",b1,b2));
+
+ if ( b1 == 0xAA && b2 == 0x00) {
+ TRACEKBD((-1,"Reset Mouse Ok\n"));
+
+ //
+ // Enable wheel report format
+ //
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0xC8, &bData, 0xFA))) {
+ continue; // 200 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 100 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x50, &bData, 0xFA))) {
+ continue; // 80 samples/sec
+ }
+
+ ReadDeviceM(0xF2, &bData, 0xFA); // Read Mouse ID
+ ObFullReadMTimeout(&bData, 1000);
+
+ // If scroll wheel is supported Mouse Response = 3
+ // else Mouse Response = 0
+ if (bData == 3) {
+ ByteCount = WHEEL_REPORT_FORMAT;
+ }
+
+ if (EFI_ERROR(ReadDeviceM(0xF3, &bData, 0xFA))) {
+ continue; // Set Sample Rate
+ }
+ if (EFI_ERROR(ReadDeviceM(0x64, &bData, 0xFA))) {
+ continue; // 20 samples/sec
+ }
+ if (EFI_ERROR(ReadDeviceM(0xE8, &bData, 0xFA))) {
+ continue; // Set resolution
+ }
+ if (EFI_ERROR(ReadDeviceM(0x2, &bData, 0xFA))) {
+ continue; // 4 Count/mm
+ }
+
+
+ //
+ // Enable streaming
+ //
+ ReadDeviceM(0xF4, &bData, 0xFA);
+ break;
+ }
+ }
+ }
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport ) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+ if(MsIrqSupport) {
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_MOUSE_IRQ, FALSE);
+ mLegacy8259->EnableIrq(mLegacy8259, SLAVE_IRQ, FALSE);
+ }
+
+ Write8042CommandByte(0x47);
+ InsideMouseReset = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: MouseGetState
+//
+// Description: Retrieves the current state of a pointer device.
+//
+// Parameters:
+// MOUSE *self - Pointer to the mouse structure
+// EFI_SIMPLE_POINTER_STATE *state - Pointer to state machine buffer
+//
+// Output: EFI_SUCCESS - Mouse data ready
+// EFI_NOT_READY - Mouse data not ready
+//
+// Modified: MouseData
+//
+// Referrals: MouseData
+//
+// Notes:
+// The function retrieves the current state of a pointer device. This includes
+// information on the buttons associated with the pointer device and the
+// distance that each of the axes associated with the pointer device has been
+// moved. If the state of the pointer device has not changed since the last
+// call to MouseGetState(), then EFI_NOT_READY is returned. If the state of
+// the pointer device has changed since the last call to MouseGetState(), then
+// the state information is placed in State, and EFI_SUCCESS is returned. If a
+// device error occurs while attempting to retrieve the state information,
+// then EFI_DEVICE_ERROR is returned.
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS MouseGetState(
+ MOUSE *self,
+ EFI_SIMPLE_POINTER_STATE *state)
+{
+
+ StdMouseDataPacket* packet = (StdMouseDataPacket*)MouseData;
+ EFI_STATUS Status;
+
+ // Check if Mouse Data ready
+ if (!MouseData[ByteCount]) {
+ Status = GetMouseData();
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ if (MouseData[ByteCount]) {
+
+ MouseData[ByteCount] = 0;
+
+ if( packet->flags & (MOUSE_X_OVF|MOUSE_Y_OVF) ){
+ return EFI_DEVICE_ERROR;
+ } else {
+ state->RelativeMovementX = (packet->flags & MOUSE_X_NEG)? (signed char)packet->x:packet->x;
+ state->RelativeMovementY = -(int)((packet->flags & MOUSE_Y_NEG)? (signed char)packet->y:packet->y);
+ state->LeftButton = (packet->flags & BUTTON_LEFT)?TRUE:FALSE;
+ state->RightButton = (packet->flags & BUTTON_RIGHT)?TRUE:FALSE;
+
+ if (ByteCount == WHEEL_REPORT_FORMAT) {
+ state->RelativeMovementZ = ((signed char)packet->z);
+ } else {
+ state->RelativeMovementZ = 0;
+ }
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DetectPS2mouse
+//
+// Description: Detects the presence of mouse in KBC port.
+//
+// Parameters: MOUSE* self - Pointer to the mouse structure
+//
+// Output: EFI_SUCCESS if mouse is detected
+// EFI_NOT_FOUND if mouse is not detected
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DetectPS2mouse (
+ MOUSE* self )
+{
+ if ( InstallKeyboardMouseAlways ) {
+ return EFI_SUCCESS;
+ } else {
+ return Ps2MouseDetected ? EFI_SUCCESS : EFI_NOT_FOUND;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OnWaitingOnMouse
+//
+// Description: Callback for the WaitForInput event;
+// checks whether the mouse state has changed and if so -
+// signals the event.
+//
+// Parameters: EFI_EVENT event - Event to signal
+// MOUSE *self - Pointer to the mouse structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID OnWaitingOnMouse (
+ EFI_EVENT event,
+ MOUSE *self )
+{
+ // Check if Mouse Data ready
+ if (!MouseData[ByteCount]) {
+ GetMouseData();
+ }
+
+ if (MouseData[ByteCount]) gSysTable->BootServices->SignalEvent(event);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetMouseDataFromIrq
+//
+// Description: Enables Mouse and returns data if available
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS - Mouse data returned
+// EFI_NO_RESPONSE - No response from mouse
+//
+// Modified: MouseData, InsideGetMouseData
+//
+// Referrals: MouseData, InsideGetMouseData, MouseResetRequired,
+// InsideKbdReadKey, InsideOnWaitingOnKey, gKbd
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetMouseDataFromIrq(VOID)
+{
+ UINT8 Port64flag = IoRead8(KBC_CMDSTS_PORT);
+
+
+
+ if ((Port64flag & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+ MouseData[gCurrentMouseIndex] = KBCGetData();
+ if (gCurrentMouseIndex ==(ByteCount-1)){
+ DisableAuxDevice();
+ gCurrentMouseIndex = 0;
+ MouseData[ByteCount] = 1;
+ return;
+ }
+ gCurrentMouseIndex++;
+ }
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetMouseData
+//
+// Description: Enables Mouse and returns data if available
+//
+// Parameters: None
+//
+// Output: EFI_SUCCESS - Mouse data returned
+// EFI_NO_RESPONSE - No response from mouse
+//
+// Modified: MouseData, InsideGetMouseData
+//
+// Referrals: MouseData, InsideGetMouseData, MouseResetRequired,
+// InsideKbdReadKey, InsideOnWaitingOnKey, gKbd
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetMouseData()
+{
+
+ UINT8 Index;
+ BOOLEAN MouseDataRead;
+ KEYBOARD *kbd = &gKbd;
+ UINT8 KbdData[20], KbdDataIndex=0, Data8;
+ UINTN Delay, DelayPeriod = 100;
+ BOOLEAN MouseDataValid = FALSE;
+
+ //
+ // If mouse irq is supported and installed then return with success
+ //
+ if(MsIrqSupport){
+ if (gMouseIrqInstall){
+ return EFI_SUCCESS;
+ }
+ }
+
+ // Return if we are in the middle of KBD get key
+ if (InsideGetMouseData || InsideKbdReadKey || InsideOnWaitingOnKey || InsideKbdReset || InsideMouseReset) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (MouseData[ByteCount] == 1) return EFI_SUCCESS;
+
+ // Try to complete the LED sequence
+ for (Index = 0; (Index < 40) && kbd->LEDCommandState; Index++ ) {
+ //
+ // if keyboard irq is supported but not installed yet then call
+ // Ps2DataDispatcher to check whether data is available on port or not
+ //
+ if(KbdIrqSupport)
+ if (!gKeyboardIrqInstall)
+ PS2DataDispatcher(NULL);
+ pBS->Stall(500);
+ }
+
+ // LED sequence is still on, restart it
+ if (kbd->LEDCommandState) {
+ if(KbdIrqSupport)
+ if (!gKeyboardIrqInstall){
+ TRACEKBD((-1,"BLS%x ", kbd->LEDCommandState));
+ ProcessKBDResponse(kbd, 0xfe);
+ }
+ }
+
+ InsideGetMouseData = TRUE;
+
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+
+ EnableAuxDevice();
+ if (MouseResetRequired) {
+ DisableKeyboard();
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+ ReadDeviceM(0xF4, &Index, 0xFA);
+ MouseResetRequired = FALSE;
+ }
+
+ MouseData[ByteCount] = 0;
+
+ DelayPeriod = 200; // Delay for the first byte
+ for (Index = 0; Index < ByteCount; Index++) {
+
+ MouseDataRead = FALSE;
+
+ for (Delay = 0; Delay < DelayPeriod; Delay++) {
+
+ Data8 = IoRead8(KBC_CMDSTS_PORT);
+
+ if ((Data8 & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+
+ if ((Data8 & (KBC_OBF|KBC_AUX_OBF)) == (KBC_OBF|KBC_AUX_OBF)) {
+ MouseData[Index] = KBCGetData();
+ MouseDataValid = TRUE;
+ MouseDataRead = TRUE;
+ if (Index == (ByteCount-1)) DisableAuxDevice();
+ break;
+ }
+
+ pBS->Stall(100);
+
+ }
+
+ DelayPeriod = 100; // Delay for the Second & Third byte
+
+ if (Index == (ByteCount-1) && MouseDataRead) {
+ MouseData[ByteCount] = 1;
+ } else if (Index == (ByteCount-1) && MouseDataValid) {
+ MouseResetRequired=TRUE;
+ }
+
+ if (MouseDataRead) continue;
+ else break;
+
+ }
+
+ // Reset mouse counters if the mouse sequence is not correct
+ if (MouseData[ByteCount] == 1 && !(MouseData[0] & 8)) {
+
+ for (; Index; Index--) {
+ TRACEKBD((-1,"%X ", MouseData[Index]));
+ }
+ TRACEKBD((-1,"\n"));
+
+ DisableKeyboard();
+ if ((IoRead8(KBC_CMDSTS_PORT) & (KBC_OBF|KBC_AUX_OBF)) == KBC_OBF) {
+ KbdData[KbdDataIndex] = KBCGetData();
+ KbdDataIndex++;
+ }
+ ReadDeviceM(0xF4, &Index, 0xFA);
+ }
+
+ EnableKeyboard();
+ DisableAuxDevice();
+
+ for (Index =0 ; KbdDataIndex; KbdDataIndex--, Index++) {
+ ProcessKBDData(kbd, KbdData[Index]);
+ }
+
+ InsideGetMouseData = FALSE;
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2ctl.h b/Core/EM/PS2CTL/ps2ctl.h
new file mode 100644
index 0000000..a117f56
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2ctl.h
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2ctl.h 15 4/27/11 4:35a Lavanyap $
+//
+// $Revision: 15 $
+//
+// $Date: 4/27/11 4:35a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2ctl.h $
+//
+// 15 4/27/11 4:35a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 14 1/24/11 3:41p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Added definition of AutodetectKbdMousePortsPtr.
+// [Files] - ps2ctl.h
+// NOTE: Implementation of this change requires changes to CORE_DXE.sdl
+// and BdsBoard.c.
+//
+// 13 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 12 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 11 9/07/07 4:34p Olegi
+// EFI_KEY code implementation.
+//
+// 10 8/31/07 2:17p Olegi
+// Added SimpleTextInEx definitions.
+//
+// 9 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 8 4/10/07 10:04a Felixp
+// LookupHID routine renamed to LookupPs2Hid to avoid linking issue when
+// linking with FloppyCtrl module
+//
+// 7 3/13/06 2:38a Felixp
+//
+// 6 1/09/06 11:38a Felixp
+//
+// 4 12/22/05 10:22a Srinin
+//
+// 3 10/11/05 4:11p Srinin
+//
+// 2 3/04/05 1:38p Mandal
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 7 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 6 9/21/04 5:51p Olegi
+//
+// 5 8/27/04 3:17p Olegi
+// Header and footer added.
+//
+// 4 8/18/04 6:37p Olegi
+// Header and footer added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2ctl.h
+//
+// Description: PS/2 Controller DXE driver header
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#ifndef __PS2_MAIN_H__
+#define __PS2_MAIN_H__
+
+#include <Efi.h>
+#include <AmiDxeLib.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\AmiKeycode.h>
+#include <Protocol\SimplePointer.h>
+#include <token.h>
+#define TRACEKBD
+
+
+#define PS2_DRIVER_VER 0x10
+#define DEVICETYPE_MOUSE 1
+#define DEVICETYPE_KEYBOARD 2
+extern EFI_SYSTEM_TABLE *gSysTable;
+
+
+EFI_STATUS StartMouse(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+EFI_STATUS StartKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+EFI_STATUS StopMouse(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+EFI_STATUS StopKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+
+typedef EFI_STATUS (*STARTSTOPPROC)(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller);
+
+typedef struct PS2DEV_TABLE_tag {
+ UINT32 hid;
+ UINT32 uid;
+ UINT8 DeviceType;
+ STARTSTOPPROC start;
+ STARTSTOPPROC stop;
+ CHAR16* name;
+} PS2DEV_TABLE;
+
+typedef void (*STATEMACHINEPROC)(void*);
+void PS2DataDispatcher(void*);
+UINT8 KBCGetData();
+
+BOOLEAN LookupPs2Hid(PS2DEV_TABLE*, UINT32, UINT32, PS2DEV_TABLE**);
+EFI_STATUS GetPS2_DP(EFI_DRIVER_BINDING_PROTOCOL*, EFI_HANDLE, ACPI_HID_DEVICE_PATH**, UINT32);
+
+typedef VOID (*AUTODETECT_KBD_MOUSE_PORTS)();
+typedef EFI_STATUS (*DETECT_KBC_DEVICE)();
+extern AUTODETECT_KBD_MOUSE_PORTS AutodetectKbdMousePortsPtr;
+extern DETECT_KBC_DEVICE DetectKeyboardPtr;
+extern DETECT_KBC_DEVICE DetectMousePtr;
+
+#endif // __PS2_MAIN_H__
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2kbd.c b/Core/EM/PS2CTL/ps2kbd.c
new file mode 100644
index 0000000..c74ba48
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2kbd.c
@@ -0,0 +1,2888 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2kbd.c 63 11/01/12 6:42a Deepthins $
+//
+// $Revision: 63 $
+//
+// $Date: 11/01/12 6:42a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2kbd.c $
+//
+// 63 11/01/12 6:42a Deepthins
+// [TAG] EIP101100
+// [Category] Improvement
+// [Description] Multi Language is supported in Ps2ctl driver
+// [Files] CORE_DXE.sdl, kbc.h, ps2kbd.c and Tokens.c
+//
+// 62 10/18/12 9:51a Deepthins
+// [TAG] EIP95111
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PS2 mouse is not working in setup.
+// [RootCause] In stream mode data reporting is disabled by default. The
+// mouse will not actually issue any movement data packets until it
+// receives the "Enable Data Reporting" (0xF4) command. So even when the
+// DETECT_PS2_KEYBOARD and DETECT_PS2_MOUSE token is disabled we need to
+// send command 0xf4 to Enable Data Reporting.
+//
+// [Solution] In MouseReset function, Set sampleRate ,Resolution and
+// Enable streaming.
+// [Files] mouse.c and ps2kbd.c
+//
+// 61 10/18/12 9:03a Deepthins
+// [TAG] EIP70313
+// [Category] Improvement
+// [Description] Used CheckIssueLEDCmd in function LEDsOnOff instead of
+// OutToKb(Kbd, 0xED)
+// [Files] kbc.c, ps2kbd.c and kbc.h
+//
+// 60 7/13/12 7:21a Rajeshms
+// [TAG] EIP57005
+// [Category] Improvement
+// [Description] Need to clear Struck Keys in StartKeyboard() &
+// KbdReset() for some kinds of Notebook KBC. Implemented this feature
+// based on CLEAR_PENDING_KEYS_IN_PS2 token.
+// [Files] Ps2Kbd.c, CORE_DXE.sdl
+//
+// 59 7/09/12 3:13a Rajeshms
+// [TAG] EIP94186
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] side effect after adding the solution of can not catch F8
+// key event on Keyboard - PS2 KB generic implement (EIP6986)
+// [RootCause] BDA is Checked even when CSM is not launched. So even
+// though keys are not pressed Junk Keys are reproted
+// [Solution] Checked whether CSm is launched based of Presence of
+// Legacy BIOS Protocol.
+// [Files] Ps2Kbd.c
+//
+// 58 5/31/12 7:56a Srilathasc
+// [TAG] EIP89947
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ps2Keyboard doesn't work after reconnect -r command from
+// Shell
+// [RootCause] The keyboard driver's stop function does not uninstall
+// AMIEFIKEYCODE Protocol.
+// [Solution] AMIEFIKEYCODE Protocol uninstalled in stop function.
+// [Files] ps2kbd.c
+//
+// 57 5/24/12 6:49a Nimishsv
+// [TAG] EIP90180
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ps2driver doesn't return the proper ShiftState if the valid
+// Unicode char's are pressed.
+// [RootCause] Shift State was not cleared for printable characters
+// [Solution] Shift state is cleared for printable characters
+// [Files] ps2kbd.c
+//
+// 56 5/02/12 2:29a Deepthins
+// [TAG] EIP63116
+// [Category] Improvement
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Ps2kbd.c, Mouse.c, kbc.h, kbc.c
+//
+// 55 4/30/12 2:22a Rajeshms
+// [TAG] EIP86986
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Can not detect F8 key on PS2 Keyboard while booting to EFI
+// aware OS.
+// [RootCause] Make code of F8 key (0x42) is taken by int09h and EFI
+// aware OS calls only one ReadKeyStroke() for any key catch, Now PS2
+// driver will take Break Code of F8 key(0xC2) and returns EFI_NOT_READY.
+// [Solution] Multiple Read from PS2 keyboard is implemented and read
+// exits if any valid key is detected. Also, the BDA keyboard buffer is
+// checked for any missed key in EFI.
+// [Files] ps2kbd.c, kbc.c, CORE_DXE.sdl
+//
+// 54 4/24/12 2:19a Deepthins
+// [TAG] EIP85747
+// [Category] Improvement
+// [Description] USB-ReadKeyStrokeEx is returning EFI_SUCCESS with
+// KEY_STATE_EXPOSED for Caps, Num and Scroll Lock Key's.
+// KEY_STATE_EXPOSED only for the ShiftState Key's and not for togglestate
+// key's.
+// [Files] Efiusbkb.c, ps2kbd.c and kbc.h
+//
+// 53 4/23/12 8:52a Jittenkumarp
+// [TAG] EIP84902
+// [Category] Bug Fix
+// [Symptom] Enter key is not working in PS2 key board
+// [RootCause] Filling wrong EFI KEY value in
+// ScancodeToEfi_table.Therefor Enter key is interpreted wrongly as
+// EfiKeyC12.
+// [Solution] Replaced EfiKeyC12 value with EfiKeyEnter value to
+// Interpreted Enter key properly.
+//
+// [Files] ps2kbd.c
+//
+// 52 4/10/12 2:35a Rameshr
+// [TAG] EIP87058
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Not able to recognise Pause Key Click using ReadKeyStroke
+// [RootCause] Pause Key detection should be done always and only the
+// pause key action should be controlled by PAUSEKEY_SUPPORT SDL token
+// [Solution] SDL token checking removed for the Pause Key detection
+// [Files] Ps2kbd.c
+//
+// 51 2/01/12 2:01a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 50 9/22/11 7:39a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h
+//
+// 49 6/21/11 12:24p Davidd
+// [TAG] EIP55334
+// [Category] New Feature
+// [Description] Add optional code to clear keyboard buffer at
+// ReadyToBoot in PS2KB driver
+// [Files] core_dxe.sdl
+// ps2kbd.c
+//
+// 48 4/27/11 4:34a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 47 1/05/11 12:58a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 46 8/23/10 4:21a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.c
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 45 8/19/10 8:08a Fredericko
+// [TAG] EIP40711
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] Keyboard sometimes does not work in DOS if KBD is being
+// pressed hapazardly during post.
+// [RootCause] After reprogramming of Interrupt Controller base; if
+// keyboard is being pressed hapardzadly, KBD IRQ could be missed and KBD
+// might not work in DOS.
+// [Solution] Follow proper procedures to Reset KBD controller after
+// reprogramming the base of the Interrrupt controller
+// [Files] Thunk.c in CSM
+//
+// 44 7/20/10 4:31a Rameshr
+// Corrected the FreePool call in UnRegisterKeyNotify function
+//
+// 43 5/14/10 11:07a Olegi
+// Added FreePool call in UnRegisterKeyNotify function.
+//
+// 42 5/10/10 1:50a Rameshr
+// Issue:Shift Key issues in RegsiterkeyNotify function
+// Solution: ShiftKeyState and KeyToggleState verified for
+// RegisterKeyNotify callback function.
+// EIP 38211
+//
+// 41 5/10/10 1:41a Rameshr
+// PrintKey/SysRq key, Menu Key, Left Logo and Right Logo Key support
+// added in Ps2 Keyboard driver
+// EIP 38212
+//
+// 40 3/15/10 2:40p Krishnakumarg
+// Pressing DEL key continously intermittently or sticking does not enter
+// setup. EIP: 34615
+//
+// 39 1/29/10 2:11p Krishnakumarg
+// When user press "Ctrl+Break" key, the Scr Lk LED will turn on - #EIP
+// 34317
+//
+// 38 8/13/09 3:02p Rameshr
+// When item "num-lock status" set off, Num-lock will keep open until in
+// DOS.
+// EIP:21757
+//
+// 37 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 36 6/26/09 4:03p Rameshr
+// Symptom: Shift Key Status get set when DELL key pressed more
+// frequently.
+// Reason: DELL key scan code E0 taken by Reset Function and Int9. This
+// has been handled by modifiying Reset function and using BDA.
+// EIP:22611
+//
+// 35 3/30/09 10:28a Pats
+// Issue: EIP 19547 - Pause key support needed in Aptio
+// Solution: Function HandleKBDData modified to pass EFI_KEY vaule of
+// pause key on rather than rejecting it.
+//
+// 34 1/23/09 9:54a Rameshr
+// Symptom:SCT failure in ReadKeystrokeEx function.
+// Solution: Validated the Input parameters Keydata for the
+// ReadKeystrokeEx Function.
+// Eip: 19039
+//
+// 33 11/17/08 10:04a Rameshraju
+// Problem:SCT failure on RegisterKeyNotify, SetState and
+// UnregisterKeyNotify.
+// Fix : Validated the input parameters for RegisterKeyNotify, SetState
+// and UnregisterKeyNotify.
+// EIP:17578
+//
+// 32 10/08/08 4:56p Olegi
+// Implemented the Register/Unregister key notofocation function in
+// SimpletextinEx protocol.
+//
+// 31 8/15/08 10:57a Olegi
+// Correction in KbdReset function.
+//
+// 30 8/13/08 9:54a Olegi
+// Change in KbdReset function, EIP#8330.
+//
+// 29 6/05/08 4:26p Olegi
+// Added support for extended keys (EIP#13630)
+//
+// 28 6/05/08 3:19p Olegi
+// Bugfix in processing the '5' key on a keypad when NumLock is off:
+// nothing should be reported.
+//
+// 27 5/09/08 10:11a Olegi
+// ProcessByte function modified
+//
+// 26 4/22/08 4:31p Felixp
+// Additional progress codes added
+//
+// 25 4/21/08 5:49p Olegi
+//
+// 24 4/09/08 10:19a Olegi
+// Changed the key attributes (modifiers and shift state) reporting.
+//
+// 23 10/25/07 4:48p Olegi
+//
+// 22 10/24/07 6:00p Olegi
+//
+// 21 10/23/07 4:04p Olegi
+// Lock keys maintenance modifications.
+//
+// 20 9/18/07 11:51a Olegi
+//
+// 19 9/18/07 11:47a Olegi
+//
+// 18 9/17/07 3:56p Olegi
+//
+// 17 9/10/07 1:14p Olegi
+//
+// 16 9/07/07 4:34p Olegi
+// EFI_KEY code implementation.
+//
+// 15 8/31/07 2:44p Olegi
+// Added SimpleTextInEx definitions.
+//
+// 14 6/22/07 2:14p Pats
+// Fixed problem of right Ctrl and Alt keys "sticking" and causing reset
+// when Ctrl-Alt-Del pressed sequentially rather than all at once.
+//
+// 13 4/19/07 1:00p Felixp
+// File reformatted to comply with AMI coding standards
+//
+// 11 4/17/07 10:34a Pats
+// Modified to comply with coding standard. No code changes.
+//
+// 10 5/05/06 5:23p Ambikas
+//
+// 9 3/13/06 2:38a Felixp
+//
+// 8 1/09/06 11:38a Felixp
+//
+// 6 12/22/05 10:21a Srinin
+// Optimized KBD Enable/Disable call
+//
+// 5 10/27/05 1:04p Srinin
+// In KbdReset, KBD driver buffer is cleared.
+//
+// 4 10/11/05 4:09p Srinin
+// KBD reset function implemented and other minor changes done.
+//
+// 3 8/30/05 1:08p Srinin
+// KeyBoard buffer and handling of keys which send 4 scan codes modified.
+//
+// 2 3/04/05 3:55p Olegi
+// Shift states corrected for non-letter keys.
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 12/16/04 2:28p Olegi
+// Fix: Caps-Lock made irrelevant to the upper row of keys.
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 10 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2kbd.c
+//
+// Description: PS/2 keyboard support routines
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "ps2ctl.h"
+#include "kbc.h"
+
+
+#define E0_STATUS_IN_BDA BIT1
+#define E1_STATUS_IN_BDA BIT0
+#define LEGACY_8259_CONTROL_REGISTER_MASTER 0x20
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+#include <Protocol/LegacyBios.h>
+UINT16 BdaSeg = 0x400;
+UINT16 *BdaKbdHead = (UINT16 *)0x41A;
+UINT16 *BdaKbdTail = (UINT16 *)0x41C;
+EFI_LEGACY_BIOS_PROTOCOL *gLegacy=NULL;
+BOOLEAN gLegacyBiosProtocolFound = FALSE;
+#endif
+#endif
+
+/*
+Table 2. PS/2 Scan Codes Supported in Windows 2000/Windows XP and Windows Me
+
+HID usage/ key name Set 1Make Set 1Break Set 2Make Set 2Break
+ Scan Next Track E0 19 E0 99 E0 4D E0 F0 4D
+ Scan Previous Track E0 10 E0 90 E0 15 E0 F0 15
+ Stop E0 24 E0 A4 E0 3B E0 F0 3B
+ Play/ Pause E0 22 E0 A2 E0 34 E0 F0 34
+ Mute E0 20 E0 A0 E0 23 E0 F0 23
+ Volume Increment E0 30 E0 B0 E0 32 E0 F0 32
+ Volume Decrement E0 2E E0 AE E0 21 E0 F0 21
+ AL Email Reader E0 6C E0 EC E0 48 E0 F0 48
+ AC Search E0 65 E0 E5 E0 10 E0 F0 10
+ AC Home E0 32 E0 B2 E0 3A E0 F0 3A
+ AC Back E0 6A E0 EA E0 38 E0 F0 38
+ AC Forward E0 69 E0 E9 E0 30 E0 F0 30
+ AC Stop E0 68 E0 E8 E0 28 E0 F0 28
+ AC Refresh E0 67 E0 E7 E0 20 E0 F0 20
+ AC Bookmarks E0 66 E0 E6 E0 18 E0 F0 18
+ AL Calculator* E0 21 E0 A1 E0 2B E0 F0 2B
+ AL Local Browser* E0 6B E0 EB E0 40 E0 F0 40
+ AL Consumer Control Configuration*
+ E0 6D E0 ED E0 50 E0 F0 50
+*/
+static UINT8 E0EnhancedKeys[] = {0x20,0x30,0x2E}; // only mute, volume-up, down
+BOOLEAN IsEnhancedKey( UINT8 data)
+{
+ UINTN i;
+
+ data &= 0x7F; // reset MSB
+ for ( i = 0; i < sizeof(E0EnhancedKeys); i++) {
+ if ( data == E0EnhancedKeys[i]) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//----------------------------------------------------------------------
+
+extern BOOLEAN InsideGetMouseData;
+extern BOOLEAN KBDEnableState;
+extern UINT8 LedsAtStartup;
+extern BOOLEAN InsideMouseReset;
+BOOLEAN InsideKbdReadKey = FALSE;
+BOOLEAN InsideOnWaitingOnKey = FALSE;
+BOOLEAN InsideKbdReset = FALSE;
+extern BOOLEAN InsidePS2DataDispatcher;
+static EFI_GUID gAmiMultiLangSupportGuid = AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID;
+AMI_MULTI_LANG_SUPPORT_PROTOCOL *gPs2MultiLangSupportProtocol=NULL;
+
+EFI_STATUS KbdReset(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ BOOLEAN ExtendedVerification);
+
+EFI_STATUS KbdReadKey(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ EFI_INPUT_KEY *key);
+
+EFI_STATUS KbdResetEx(
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ BOOLEAN ExtendedVerification );
+
+EFI_STATUS KbdReadKeyEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS KbdReadEfiKeyEx (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS SetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+);
+
+EFI_STATUS RegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS UnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+);
+
+void OnWaitingOnKey(EFI_EVENT Event, void *Context);
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+VOID Ps2KbdReset ( VOID );
+VOID ClearOBF ( VOID );
+#endif
+
+
+typedef struct _KEY_WAITING_RECORD{
+ DLINK Link;
+ EFI_KEY_DATA Context;
+ EFI_KEY_NOTIFY_FUNCTION Callback;
+} KEY_WAITING_RECORD;
+
+DLIST mPs2KeyboardData;
+KEY_WAITING_RECORD *mPs2KeyboardRecord;
+EFI_EVENT Ps2KeyEvent;
+#define KEY_POLLING_INTERVAL 500000
+VOID StartPollingKey(EFI_EVENT Event, VOID *Context);
+
+
+extern STATEMACHINEPROC DrivePS2KbdMachine;
+void ReadAndProcessKey(void*);
+void ProcessByte(KEYBOARD *Kbd, UINT8 data, BOOLEAN fourth_byte);
+void ResetStateMachine(KEYBOARD *Kbd);
+void LEDsOnOff(KEYBOARD* Kbd);
+
+static UINT8 E0SeqA[4] = {0x2A, 0xAA, 0x46, 0xB6};
+static UINT8 E0SeqB[11] = {0xD3, 0xD0, 0xCF, 0xC7, 0xD2, 0xCB, 0xD1, 0xC9, 0xCD, 0xC8, 0xB5};
+static UINT8 E1Seq[5] = {0x1D, 0x45, 0xE1, 0x9D, 0xC5};
+
+static UINT8 code_table[59] = { // Lower case keys
+0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 8,
+9, 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13,
+0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'','`',
+0,'\\','z','x','c','v','b','n','m',',','.','/',0,
+'*', 0, ' ', 0};
+static UINT8 Code_Table[59] = { // Upper case keys
+0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 8,
+9, 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 13,
+0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
+0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0,
+'*', 0, ' ',0};
+
+static UINT8 ScancodeToEfi_table[59] = { // EFI keys (UEFI Spec 2.1, Ch.28.4, Pg.1325)
+0, EfiKeyEsc, EfiKeyE1, EfiKeyE2, EfiKeyE3,EfiKeyE4, EfiKeyE5, EfiKeyE6,
+EfiKeyE7, EfiKeyE8, EfiKeyE9, EfiKeyE10, EfiKeyE11, EfiKeyE12, EfiKeyBackSpace,
+EfiKeyTab, EfiKeyD1, EfiKeyD2, EfiKeyD3, EfiKeyD4, EfiKeyD5, EfiKeyD6, EfiKeyD7,
+EfiKeyD8, EfiKeyD9, EfiKeyD10, EfiKeyD11, EfiKeyD12, EfiKeyEnter,
+EfiKeyCapsLock, EfiKeyC1, EfiKeyC2, EfiKeyC3, EfiKeyC4, EfiKeyC5, EfiKeyC6, EfiKeyC7,
+EfiKeyC8, EfiKeyC9, EfiKeyC10, EfiKeyC11, EfiKeyE0,
+EfiKeyLShift, EfiKeyD13, EfiKeyB1, EfiKeyB2, EfiKeyB3, EfiKeyB4, EfiKeyB5, EfiKeyB6,
+EfiKeyB7, EfiKeyB8, EfiKeyB9, EfiKeyB10, EfiKeyRshift,
+0, 0, EfiKeySpaceBar, 0};
+
+typedef struct {
+ UINT8 makecode;
+ UINT8 efi_scancode;
+ UINT8 efi_key;
+}EFI_EXTKEY;
+
+static EFI_EXTKEY ScanCode_Table[] = {
+ 0x3B, EFI_SCAN_F1, EfiKeyF1,
+ 0x3C, EFI_SCAN_F2, EfiKeyF2,
+ 0x3D, EFI_SCAN_F3, EfiKeyF3,
+ 0x3E, EFI_SCAN_F4, EfiKeyF4,
+ 0x3F, EFI_SCAN_F5, EfiKeyF5,
+ 0x40, EFI_SCAN_F6, EfiKeyF6,
+ 0x41, EFI_SCAN_F7, EfiKeyF7,
+ 0x42, EFI_SCAN_F8, EfiKeyF8,
+ 0x43, EFI_SCAN_F9, EfiKeyF9,
+ 0x44, EFI_SCAN_F10, EfiKeyF10,
+ 0x57, EFI_SCAN_F11, EfiKeyF11,
+ 0x58, EFI_SCAN_F12, EfiKeyF12,
+ 0x47, EFI_SCAN_HOME, EfiKeyHome,
+ 0x48, EFI_SCAN_UP, EfiKeyUpArrow,
+ 0x49, EFI_SCAN_PGUP, EfiKeyPgUp,
+ 0x4B, EFI_SCAN_LEFT, EfiKeyLeftArrow,
+ 0x4D, EFI_SCAN_RIGHT, EfiKeyRightArrow,
+ 0x4F, EFI_SCAN_END, EfiKeyEnd,
+ 0x50, EFI_SCAN_DN, EfiKeyDownArrow,
+ 0x51, EFI_SCAN_PGDN, EfiKeyPgDn,
+ 0x52, EFI_SCAN_INS, EfiKeyIns,
+ 0x53, EFI_SCAN_DEL, EfiKeyDel,
+ 0xFF, 0xFF, 0xFF // End of table
+};
+
+static UINT8 KeyPad_Table[] = {
+ '7','8','9','-','4','5','6','+','1','2','3','0','.'
+};
+
+static UINT8 KeyPadEfiCode_Table[] = {
+ EfiKeySeven, EfiKeyEight, EfiKeyNine, EfiKeyMinus,
+ EfiKeyFour, EfiKeyFive, EfiKeySix, EfiKeyPlus,
+ EfiKeyOne, EfiKeyTwo, EfiKeyThree,
+ EfiKeyZero, EfiKeyPeriod
+};
+
+KEYBOARD gKbd;
+KEYBOARD_IRQ_STORE gKeyboardIrqBuffer;
+EFI_CPU_ARCH_PROTOCOL *gCpuArch;
+EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+BOOLEAN gKeyboardIrqInstall=FALSE;
+BOOLEAN gKeyboardDriverStart=FALSE;
+
+extern BOOLEAN Ps2MouseDetected;
+extern BOOLEAN KbdIrqSupport;
+extern BOOLEAN KbRdBeforeInstall;
+extern BOOLEAN InsideGetMouseData;
+extern BOOLEAN KBDEnableState;
+
+#if CLEAR_PS2KB_BUFFER_AT_READYTOBOOT
+EFI_EVENT gClearKbBufferEvent;
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ClearKbBuffer
+//
+// Description:
+// This function clear PS2 KB buffer
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+ClearKbBuffer(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ KEYBOARD *Kbd = &gKbd;
+ UINT8 *BdaKbHead = (UINT8*)((UINTN) 0x41a);
+ UINT8 *BdaKbTail = (UINT8*)((UINTN) 0x41c);
+ UINT8 *BdaKbBuffer = (UINT8*)((UINTN) 0x41e);
+
+ Kbd->pBufHead = Kbd->pBufStart;
+ Kbd->pBufTail = Kbd->pBufStart;
+
+ pBS->SetMem(Kbd->pBufStart, BUFFER_SIZE * sizeof (AMI_EFI_KEY_DATA), 0);
+
+ // Empty KB Buffer in BDA
+ pBS->SetMem(BdaKbBuffer, 32, 0);
+ *BdaKbTail = *BdaKbHead;
+
+ pBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+#endif
+
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateVariabletoCheckBda
+//
+// Description:
+// This function updates variable Legacy BIOS Protocol found,to check BDA
+// for pending keys in EFI.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+VOID UpdateVariabletoCheckBda(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ //
+ // Update Variable to check BDA if Legacy Bios Protocol Found.
+ //
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &gLegacy);
+ if (!EFI_ERROR(Status)) {
+ gLegacyBiosProtocolFound = TRUE;
+ }
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StartKeyboard
+//
+// Description: This routine is called from Driver Binding Start function,
+// it starts the keyboard
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - A pointer to the
+// EFI_DRIVER_BINDING_PROTOCOL instance
+// EFI_HANDLE Controller - Handle for this controller
+//
+// Output: EFI_STATUS - status of the operation
+//
+// Referrals: gEfiSimpleTextInProtocolGuid
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StartKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller)
+{
+
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *pDummyDevPath;
+ KEYBOARD* Kbd = &gKbd;
+ KEYBOARD_IRQ_STORE* KbIrqBuffer = &gKeyboardIrqBuffer;
+ UINT8 Index=0;
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ EFI_EVENT Event;
+ VOID *pRegistration;
+#endif
+#endif
+
+ if (EFI_ERROR(gSysTable->BootServices->OpenProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ &pDummyDevPath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER))) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+ //
+ // Reset the keyboard and Clear Pending Keys as some
+ // NoteBook Kbc needs reset and Clearing the OBF.
+ //
+ Ps2KbdReset();
+ ClearOBF ();
+#endif
+
+ DetectPS2KeyboardAndMouse();
+
+ if (EFI_ERROR(DetectPS2Keyboard())) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Initialize keyboard interface functions
+ //
+ (Kbd->iSimpleIn).Reset = KbdReset;
+ (Kbd->iSimpleIn).ReadKeyStroke = KbdReadKey;
+
+ (Kbd->iSimpleInEx).Reset = KbdResetEx;
+ (Kbd->iSimpleInEx).ReadKeyStrokeEx = KbdReadKeyEx;
+ (Kbd->iSimpleInEx).SetState = SetState;
+ (Kbd->iSimpleInEx).RegisterKeyNotify = RegisterKeyNotify;
+ (Kbd->iSimpleInEx).UnregisterKeyNotify = UnRegisterKeyNotify;
+
+ (Kbd->iKeycodeInEx).Reset = KbdResetEx;
+ (Kbd->iKeycodeInEx).ReadEfikey = KbdReadEfiKeyEx;
+ (Kbd->iKeycodeInEx).SetState = SetState;
+ (Kbd->iKeycodeInEx).RegisterKeyNotify = RegisterKeyNotify;
+ (Kbd->iKeycodeInEx).UnregisterKeyNotify = UnRegisterKeyNotify;
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnKey,
+ Kbd,
+ &Kbd->iSimpleIn.WaitForKey);
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnKey,
+ Kbd,
+ &Kbd->iSimpleInEx.WaitForKeyEx);
+
+ gSysTable->BootServices->CreateEvent(
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ OnWaitingOnKey,
+ Kbd,
+ &Kbd->iKeycodeInEx.WaitForKeyEx);
+
+ //
+ // Install protocol interfaces for the keyboard device.
+ //
+ Status = gSysTable->BootServices->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiSimpleTextInProtocolGuid, &Kbd->iSimpleIn,
+ &gEfiSimpleTextInExProtocolGuid, &Kbd->iSimpleInEx,
+ &gAmiEfiKeycodeProtocolGuid, &Kbd->iKeycodeInEx,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleIn.WaitForKey);
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleInEx.WaitForKeyEx);
+ gSysTable->BootServices->CloseEvent(Kbd->iKeycodeInEx.WaitForKeyEx);
+ }
+
+ if (!(EFI_ERROR(Status))) {
+ //
+ // Initialize keyboard device
+ //
+ Kbd->KeyIsReady = FALSE;
+ Kbd->ScannerState = KBST_READY;
+ Kbd->KeyData.KeyState.KeyToggleState = LedsAtStartup;
+ Kbd->KeyData.KeyState.KeyToggleState |= TOGGLE_STATE_VALID;
+ Kbd->KeyData.KeyState.KeyShiftState = SHIFT_STATE_VALID;
+
+ Kbd->pBufStart = MallocZ(BUFFER_SIZE * sizeof (AMI_EFI_KEY_DATA));
+ if(!Kbd->pBufStart) return EFI_OUT_OF_RESOURCES;
+ Kbd->pBufHead = Kbd->pBufStart;
+ Kbd->pBufTail = Kbd->pBufStart;
+ Kbd->pBufEnd = Kbd->pBufStart + BUFFER_SIZE;
+
+ DrivePS2KbdMachine = ReadAndProcessKey;
+
+ //
+ // Set LED's
+ //
+ LEDsOnOff(Kbd);
+
+ InitHotKeys(Controller); // Produce HotKeys protocol
+
+// for (Count = 3; Count; Count--) {
+// if(IssueCommand(0xF4) == 0xFA) break; // Clear the KBD buffer
+// }
+
+ Kbd->LEDCommandState = 0;
+
+#if CLEAR_PS2KB_BUFFER_AT_READYTOBOOT
+ gSysTable->BootServices->CreateEvent(
+ EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ TPL_NOTIFY,
+ ClearKbBuffer,
+ NULL,
+ &gClearKbBufferEvent);
+#endif
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ RegisterProtocolCallback(
+ &gEfiLegacyBiosProtocolGuid, UpdateVariabletoCheckBda,
+ NULL, &Event,&pRegistration
+ );
+
+ //
+ // Check whether Legacy BIOS Protocol Installed.
+ //
+ UpdateVariabletoCheckBda(NULL,NULL);
+
+#endif
+#endif
+ }
+
+ DListInit(&mPs2KeyboardData);
+
+ Status = pBS->CreateEvent(
+ EVT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ StartPollingKey,
+ Kbd,
+ &Ps2KeyEvent
+ );
+
+ //
+ // if before keyboard driver starts data is available in buffer
+ // it will be collected in local buffer in KeyboardInterrupt?Handler
+ // only if KBD_READ_BEFORE_INSTALL = 1, the avalable data in local
+ // buffer is processed.
+ //
+ if(KbRdBeforeInstall){
+ for (Index=0;Index < KbIrqBuffer->KbdIndex; Index++){
+ ProcessKBDData(Kbd, KbIrqBuffer->KbdBuffer[Index]);
+ }
+ }
+ gKeyboardDriverStart = TRUE;
+ //
+ // Re enable keyboard irq as it was previously disabled.
+ // if KBD_READ_BEFORE_INSTALL = 0 then initialize keyboard irq here
+ //
+ if(KbdIrqSupport){
+ if(KbRdBeforeInstall){
+ gKeyboardIrqInstall = TRUE;
+ //
+ // Now enable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+ else {
+ InitKeyboardIrq();
+ }
+ }
+ //
+ // Enable the Keyboard and Keyboard Interrupt. We must initilize this
+ // one for the Keyboard to work on Legacy mode. And also Legacy mode AMIUSB driver
+ // expects Keyboard and Interrupt should be enabled once Port 60/64 is present.
+ //
+ Write8042CommandByte(0x65);
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: StopKeyboard
+//
+// Description: This routine is called from Driver Binding Stop function.
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - A pointer to the
+// EFI_DRIVER_BINDING_PROTOCOL instance
+// EFI_HANDLE Controller - Handle for this controller
+//
+// Output: EFI_STATUS - status of the operation
+//
+// Referrals: gEfiSimpleTextInProtocolGuid
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StopKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller)
+{
+ KEYBOARD* Kbd = &gKbd;
+ EFI_STATUS Status;
+
+ //
+ // Uninstall protocol interfaces from the keyboard device.
+ //
+ Status = gSysTable->BootServices->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiSimpleTextInProtocolGuid, &Kbd->iSimpleIn,
+ &gEfiSimpleTextInExProtocolGuid, &Kbd->iSimpleInEx,
+ &gAmiEfiKeycodeProtocolGuid, &Kbd->iKeycodeInEx,
+ NULL
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Close protocols that is open during Start
+ //
+ Status = gSysTable->BootServices->CloseProtocol(
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Kill wait event
+ //
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleIn.WaitForKey);
+ gSysTable->BootServices->CloseEvent(Kbd->iSimpleInEx.WaitForKeyEx);
+ gSysTable->BootServices->CloseEvent(Kbd->iKeycodeInEx.WaitForKeyEx);
+ gSysTable->BootServices->CloseEvent(Ps2KeyEvent);
+
+ pBS->FreePool(Kbd->pBufStart);
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KbdReset
+//
+// Description: Resets the input device hardware. This routine is a part
+// of SimpleTextIn protocol implementation.
+//
+// Parameters: EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// *This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// instance.
+// BOOLEAN
+// ExtendedVerification - Indicates that the driver may
+// perform a more exhaustive verification operation of the
+// device during reset.
+//
+// Output: EFI_SUCCESS The device was reset.
+// EFI_DEVICE_ERROR The device is not functioning correctly
+// and could not be reset.
+//
+// Modified: KBDEnableState
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS KbdReset(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ BOOLEAN ExtendedVerification )
+{
+ UINT8 bCount, bData, bBCount;
+ KEYBOARD* Kbd = &gKbd;
+ EFI_STATUS Status;
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport && gKeyboardIrqInstall) {
+ //
+ // Now Disable the interrupt
+ //
+ mLegacy8259->DisableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ);
+ }
+ InsideKbdReset = TRUE;
+ Kbd->KeyIsReady = FALSE;
+ Kbd->ScannerState = KBST_READY;
+
+ Kbd->pBufHead = Kbd->pBufStart;
+ Kbd->pBufTail = Kbd->pBufStart;
+
+ pBS->SetMem(Kbd->pBufStart, BUFFER_SIZE * sizeof (AMI_EFI_KEY_DATA), 0);
+
+ DisableKeyboard();
+ PROGRESS_CODE(DXE_KEYBOARD_RESET);
+
+ for (bBCount = 0; bBCount < 4; bBCount++) {
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_DISABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_ENABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ //
+ // Report the Buffer FULL error code if there is failure.
+ //
+ if (EFI_ERROR(Status)) {
+ ERROR_CODE (DXE_KEYBOARD_BUFFER_FULL_ERROR, EFI_ERROR_MAJOR);
+ }
+
+ KBDEnableState = FALSE;
+ Status = EnableKeyboard();
+
+ if (EFI_ERROR(Status)) {
+ //
+ // Report the KBC Controller error code.
+ //
+ ERROR_CODE (DXE_KEYBOARD_CONTROLLER_ERROR, EFI_ERROR_MAJOR);
+ }
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+ //
+ // Clear OBF as some Notebook KBC has some keys even after
+ // disabling and enabling scanning.
+ //
+ ClearOBF ();
+#endif
+
+ if(!gKeyboardIrqInstall){
+ LEDsOnOff(Kbd);
+ }
+
+ Kbd->LEDCommandState = 0;
+ InsideKbdReset = FALSE;
+
+ if(KbdIrqSupport && gKeyboardIrqInstall) {
+
+
+ //
+ // Now enable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+EFI_STATUS KbdResetEx(
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ BOOLEAN ExtendedVerification )
+{
+ return KbdReset(0, ExtendedVerification);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KbdReadKey
+//
+// Description: Reads the next keystroke from the input device. This
+// routine is a part of SimpleTextIn protocol
+// implementation.
+//
+// Paremeters: EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+// instance.
+// EFI_INPUT_KEY
+// InputKey - A pointer to a buffer that is to be filled in
+// with the keystroke information for the key that was
+// pressed.
+//
+// Output: EFI_SUCCESS - The keystroke information was returned.
+// EFI_NOT_READY - There was no keystroke data available.
+// EFI_DEVICE_ERROR - The keystroke information was not
+// returned due to hardware errors.
+//
+// Modified: InsideKbdReadKey
+//
+// Referral(s): InsideGetMouseData, InsideGetMouseData,
+// InsideOnWaitingOnKey
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS KbdReadKey(
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ EFI_INPUT_KEY *InputKey )
+{
+ KEYBOARD* Kbd = &gKbd;
+
+ if (InsideGetMouseData || InsideKbdReadKey || InsideOnWaitingOnKey || InsideKbdReset || InsideMouseReset) {
+ return GetKeyFromBuffer (Kbd, (VOID*)InputKey, sizeof(EFI_INPUT_KEY));
+ }
+
+ InsideKbdReadKey = TRUE;
+
+ PS2DataDispatcher(This);
+
+ InsideKbdReadKey = FALSE;
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ if (!CheckKeyinBuffer(Kbd)) {
+ if( *BdaKbdHead != *BdaKbdTail ) {
+ ProcessKBDData (Kbd, *((UINT8 *)(*BdaKbdHead + BdaSeg + 1)));
+ *BdaKbdHead += 2;
+ if(*BdaKbdHead == 0x3E) {
+ *BdaKbdHead = 0x1E;
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ return GetKeyFromBuffer (Kbd, (VOID*)InputKey, sizeof(EFI_INPUT_KEY));
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: KbdReadKeyEx
+//
+// Description: Reads the next keystroke from the input device. This
+// routine is a part of SimpleTextInEx protocol
+// implementation.
+//
+// Paremeters: EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
+// *This - A pointer to the EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL
+// instance.
+//
+// Output: EFI_INPUT_KEY
+// *key - A pointer to a buffer that is filled in with the
+// keystroke state data for the key that was pressed.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+KbdReadKeyEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ KEYBOARD *Kbd = &gKbd;
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (!InsideGetMouseData && !InsideKbdReadKey && !InsideOnWaitingOnKey && !InsideKbdReset && !InsideMouseReset) {
+ InsideKbdReadKey = TRUE;
+ PS2DataDispatcher(This);
+ InsideKbdReadKey = FALSE;
+ }
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ if (!CheckKeyinBuffer(Kbd)) {
+ if( *BdaKbdHead != *BdaKbdTail ) {
+ ProcessKBDData (Kbd, *((UINT8 *)(*BdaKbdHead + BdaSeg + 1)));
+ *BdaKbdHead += 2;
+ if(*BdaKbdHead == 0x3E) {
+ *BdaKbdHead = 0x1E;
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ Status = GetKeyFromBuffer (Kbd, (VOID*)KeyData, sizeof(EFI_KEY_DATA));
+ if (EFI_ERROR(Status)) {
+
+ pBS->SetMem(KeyData, sizeof (EFI_KEY_DATA), 0);
+ //
+ // Check the partial Key. If found return Success with NULL data
+ // in EFI_INPUT_KEY.
+ //
+ Status=CheckPartialKey(Kbd, (EFI_KEY_DATA*)KeyData);
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS KbdReadEfiKeyEx (
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+ KEYBOARD *Kbd = &gKbd;
+
+ if (!InsideGetMouseData && !InsideKbdReadKey && !InsideOnWaitingOnKey && !InsideKbdReset && !InsideMouseReset) {
+ InsideKbdReadKey = TRUE;
+ PS2DataDispatcher(This);
+ InsideKbdReadKey = FALSE;
+ }
+
+
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ //
+ // If there is no key, check whether any key is present BDA Keyboard buffer as
+ // we may miss any key in legacy mode.
+ //
+ if (!CheckKeyinBuffer(Kbd)) {
+ if( *BdaKbdHead != *BdaKbdTail ) {
+ //
+ // Get the scan code from BDA keyboard buffer and process it.
+ //
+ ProcessKBDData (Kbd, *((UINT8 *)(*BdaKbdHead + BdaSeg + 1)));
+ *BdaKbdHead += 2;
+ //
+ // Check whether we have reached end of circular buffer, if reached initialize
+ // header to beginning of the buffer.
+ //
+ if(*BdaKbdHead == 0x3E) {
+ *BdaKbdHead = 0x1E;
+ }
+ }
+ }
+ }
+#endif
+#endif
+
+ Status = GetKeyFromBuffer (Kbd, (VOID*)KeyData, sizeof(AMI_EFI_KEY_DATA));
+ if (EFI_ERROR(Status)) {
+ pBS->SetMem(KeyData, sizeof (AMI_EFI_KEY_DATA), 0);
+ //
+ // Check the partial Key. If found return Success with NULL data
+ // in EFI_INPUT_KEY.
+ //
+ Status=CheckPartialKey(Kbd, (EFI_KEY_DATA*)KeyData);
+ return Status;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SetState
+//
+// Description: Set certain state for the input device.
+//
+// Paremeters: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyToggleState - Pointer to the EFI_KEY_TOGGLE_STATE to
+// set the state for the input device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ BOOLEAN ChgSL = FALSE;
+ BOOLEAN ChgCL = FALSE;
+ BOOLEAN ChgNL = FALSE;
+
+ KEYBOARD* Kbd = &gKbd;
+
+ if(KeyToggleState == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(*KeyToggleState & TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED |
+ SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+
+ ChgSL = ((*KeyToggleState & SCROLL_LOCK_ACTIVE)!=0) ^ ((Kbd->KeyData.KeyState.KeyToggleState & SCROLL_LOCK_ACTIVE)!=0);
+ ChgNL = ((*KeyToggleState & NUM_LOCK_ACTIVE)!=0) ^ ((Kbd->KeyData.KeyState.KeyToggleState & NUM_LOCK_ACTIVE)!=0);
+ ChgCL = ((*KeyToggleState & CAPS_LOCK_ACTIVE)!=0) ^ ((Kbd->KeyData.KeyState.KeyToggleState & CAPS_LOCK_ACTIVE)!=0);
+
+ if (ChgSL || ChgCL || ChgNL) {
+ Kbd->KeyData.KeyState.KeyToggleState &= ~(SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE);
+
+ if (*KeyToggleState & SCROLL_LOCK_ACTIVE) Kbd->KeyData.KeyState.KeyToggleState |= SCROLL_LOCK_ACTIVE;
+ if (*KeyToggleState & NUM_LOCK_ACTIVE) Kbd->KeyData.KeyState.KeyToggleState |= NUM_LOCK_ACTIVE;
+ if (*KeyToggleState & CAPS_LOCK_ACTIVE) Kbd->KeyData.KeyState.KeyToggleState |= CAPS_LOCK_ACTIVE;
+
+ LEDsOnOff(Kbd);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: StartPollingKey
+//
+// Description: Get the keys from the keyboard controller
+//
+// Paremeters: IN EFI_EVENT Event event that has been signaled
+// IN VOID *Context
+//
+// Output: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID StartPollingKey(EFI_EVENT Event, VOID *Context)
+{
+ if (!InsideGetMouseData && !InsideKbdReadKey && !InsideOnWaitingOnKey && !InsideKbdReset && !InsideMouseReset) {
+ InsideKbdReadKey = TRUE;
+ PS2DataDispatcher(Context);
+ InsideKbdReadKey = FALSE;
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckKeyNotify
+//
+// Description: Call the notification function based on the key pressed
+//
+// Input: Key - Key pressed
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckKeyNotify(AMI_EFI_KEY_DATA *Key)
+{
+
+ KEY_WAITING_RECORD *Ps2KeyIn = OUTTER(mPs2KeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ BOOLEAN KeyScanCodeMatch=FALSE;
+ BOOLEAN KeyUniCodeMatch=FALSE;
+ BOOLEAN ShiftKeyMatch=FALSE;
+ BOOLEAN CtrlKeyMatch=FALSE;
+ BOOLEAN AltKeyMatch=FALSE;
+ BOOLEAN LogoKeyMatch=FALSE;
+ BOOLEAN MenuKeyMatch=FALSE;
+ BOOLEAN SysRqKeyMatch=FALSE;
+ BOOLEAN KeyShiftCodeMatch=FALSE;
+ BOOLEAN KeyToggleKeyMatch=FALSE;
+
+ // if the list is empty return the status that was passed in
+ if (Ps2KeyIn == NULL)
+ return EFI_SUCCESS;
+
+ // check for a handle that was already identified
+ while ( Ps2KeyIn != NULL)
+ {
+ KeyScanCodeMatch=FALSE;
+ KeyUniCodeMatch=FALSE;
+ ShiftKeyMatch=FALSE;
+ CtrlKeyMatch=FALSE;
+ AltKeyMatch=FALSE;
+ LogoKeyMatch=FALSE;
+ MenuKeyMatch=FALSE;
+ SysRqKeyMatch=FALSE;
+ KeyShiftCodeMatch=FALSE;
+ KeyToggleKeyMatch=FALSE;
+
+ //
+ // Check the Scan Code if the Scan code is not 0
+ //
+ if (Ps2KeyIn->Context.Key.ScanCode != 0) {
+ if( Ps2KeyIn->Context.Key.ScanCode == Key->Key.ScanCode) {
+ KeyScanCodeMatch=TRUE;
+ }
+ } else {
+ KeyScanCodeMatch=TRUE;
+ }
+
+ //
+ // Check the Uncide Code Matching
+ //
+
+ if(Ps2KeyIn->Context.Key.UnicodeChar == Key->Key.UnicodeChar) {
+ KeyUniCodeMatch=TRUE;
+ }
+
+ if(Ps2KeyIn->Context.KeyState.KeyShiftState & SHIFT_STATE_VALID){
+
+ //
+ // Check the ShiftKey Matching. Left Shift Key is matched with
+ // Left or Right Shift Key. Same for Right Shift Key
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) {
+ ShiftKeyMatch=TRUE;
+ }
+ } else {
+ ShiftKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Ctrl Matching. Left Ctrl Key is matched with
+ // Left or Right Ctrl Key. Same for Right Ctrl Key
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_CONTROL_PRESSED | LEFT_CONTROL_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_CONTROL_PRESSED | LEFT_CONTROL_PRESSED)) {
+ CtrlKeyMatch=TRUE;
+ }
+ } else {
+ CtrlKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Alt Matching. Left Alt Key is matched with
+ // Left or Right Alt Key. Same for Right Alt Key
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
+ AltKeyMatch=TRUE;
+ }
+ } else {
+ AltKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Logo Matching. Left Logo Key is matched with
+ // Left or Right Logo Key. Same for Right Logo Key
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & (RIGHT_LOGO_PRESSED | LEFT_LOGO_PRESSED)) {
+ if(Key->KeyState.KeyShiftState & (RIGHT_LOGO_PRESSED | LEFT_LOGO_PRESSED)) {
+ LogoKeyMatch=TRUE;
+ }
+ } else {
+ LogoKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Menu Key Matching
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & MENU_KEY_PRESSED) {
+ if(Key->KeyState.KeyShiftState & MENU_KEY_PRESSED) {
+ MenuKeyMatch=TRUE;
+ }
+ } else {
+ MenuKeyMatch=TRUE;
+ }
+
+ //
+ // Check the SysRq Key Matching
+ //
+ if (Ps2KeyIn->Context.KeyState.KeyShiftState & SYS_REQ_PRESSED) {
+ if(Key->KeyState.KeyShiftState & SYS_REQ_PRESSED) {
+ SysRqKeyMatch=TRUE;
+ }
+ } else {
+ SysRqKeyMatch=TRUE;
+ }
+
+ KeyShiftCodeMatch=ShiftKeyMatch & CtrlKeyMatch & AltKeyMatch
+ & LogoKeyMatch & MenuKeyMatch & SysRqKeyMatch;
+ }else {
+ KeyShiftCodeMatch=TRUE;
+ }
+ //
+ // Check the Key Toggle State
+ //
+ if(Ps2KeyIn->Context.KeyState.KeyToggleState & TOGGLE_STATE_VALID){
+ if(Ps2KeyIn->Context.KeyState.KeyToggleState == Key->KeyState.KeyToggleState) {
+ KeyToggleKeyMatch=TRUE;
+ }
+ } else {
+ KeyToggleKeyMatch=TRUE;
+ }
+
+ //
+ // If everything matched, call the callback function.
+ //
+ if(KeyScanCodeMatch & KeyUniCodeMatch & KeyShiftCodeMatch & KeyToggleKeyMatch) {
+ //Call the notification function
+ //
+ Ps2KeyIn->Callback(&Ps2KeyIn->Context);
+ }
+ // go to the next element in the list
+ Ps2KeyIn = OUTTER(Ps2KeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+
+ // if it is a new handle return the status pass in
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RegisterKeyNotify
+//
+// Description: Register the callback function for the specific Key
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyData - Key value
+// KeyNotificationFunction- Pointer to the Notification Function
+// NotificationHandle - Handle to be unregisterd
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+RegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+)
+{
+ EFI_STATUS Status;
+
+
+ if(KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Create database record and add to database
+ //
+ Status = pBS->AllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (KEY_WAITING_RECORD),
+ &mPs2KeyboardRecord
+ );
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Gather information about the registration request
+ //
+
+ mPs2KeyboardRecord->Context = *KeyData;
+ mPs2KeyboardRecord->Callback = KeyNotificationFunction;
+
+ DListAdd (&mPs2KeyboardData, &(mPs2KeyboardRecord->Link));
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *NotifyHandle = (EFI_HANDLE) (&mPs2KeyboardRecord->Link);
+
+ if(mPs2KeyboardData.Size == 1) {
+ pBS->SetTimer(Ps2KeyEvent,
+ TimerPeriodic,
+ KEY_POLLING_INTERVAL);
+ }
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnRegisterKeyNotify
+//
+// Description: Unregister the callback function
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// NotificationHandle - Handle to be unregisterd
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UnRegisterKeyNotify(
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+
+ DLINK *ListPtr;
+ KEY_WAITING_RECORD *Ps2KeyIn;
+
+ if(NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListPtr = mPs2KeyboardData.pHead;
+ while ( ListPtr != NULL)
+ {
+ Ps2KeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ if ( (&Ps2KeyIn->Link) == NotificationHandle)
+ {
+ DListDelete(&mPs2KeyboardData, ListPtr);
+ pBS->FreePool(Ps2KeyIn);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ if(ListPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(mPs2KeyboardData.Size == 0) {
+ pBS->SetTimer(Ps2KeyEvent,
+ TimerCancel,
+ 0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OnWaitingOnKey
+//
+// Description: Callback for the EFI_SIMPLE_TEXT_INPUT_PROTOCOL.WaitForKey
+// event;
+// checks whether the new key is available and if so -
+// signals the event.
+//
+// Input: EFI_EVENT Event - Event to signal
+// void Context - Event specific context (pointer to Kbd
+// device)
+//
+// Output: None
+//
+// Modified: InsideOnWaitingOnKey
+//
+// Referrals: InsideGetMouseData, InsideKbdReadKey,
+// InsideOnWaitingOnKey
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+OnWaitingOnKey (
+ EFI_EVENT Event,
+ VOID *Context )
+{
+
+ if (InsideGetMouseData || InsideKbdReadKey || InsideOnWaitingOnKey || InsideKbdReset || InsideMouseReset) {
+ if (CheckKeyinBuffer((KEYBOARD*)Context)) gSysTable->BootServices->SignalEvent(Event);
+ return;
+ }
+
+ InsideOnWaitingOnKey = TRUE;
+
+ PS2DataDispatcher(Context); // Process new keys if available
+
+ InsideOnWaitingOnKey = FALSE;
+
+ if (CheckKeyinBuffer((KEYBOARD*)Context))
+ {
+ gSysTable->BootServices->SignalEvent(Event);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadAndProcessKey
+//
+// Description: PS2 keyboard keys processor, called from main PS2
+// dispatcher.
+// It gets the key from KBC output buffer and calls
+// HandleKBDData.
+//
+// Paremeters: void *Context - keyboard device pointer
+//
+// Output: None
+//
+// Notes: PS2 output buffer has data, incoming key is processed,
+// Context->KeyIsReady is updated.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ReadAndProcessKey (
+ VOID *Context )
+{
+
+ KEYBOARD *Kbd = &gKbd;
+ UINT8 data;
+
+ data = KBCGetData();
+ ProcessKBDData (Kbd, data);
+ return;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessKBDData
+//
+// Description: If key is ready, processes any hotkey, and inserts key
+// in buffer
+//
+// Parameters:
+// KEYBOARD *Kbd - Pointer to key buffer
+// UINT8 data - Key data
+//
+// Output: None
+//
+// Notes: Incoming key is processed, Context->KeyIsReady is updated
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessKBDData (
+ KEYBOARD *Kbd,
+ UINT8 data
+)
+{
+ EFI_KEY_DATA DummyKey;
+
+ HandleKBDData(Kbd, data);
+ if (Kbd->KeyIsReady) {
+
+ ProcessHotKey(Kbd->KeyData.PS2ScanCode,
+ (UINT16)Kbd->KeyData.KeyState.KeyShiftState);
+ InsertKeyToBuffer(Kbd, &Kbd->KeyData);
+ Kbd->KeyIsReady = FALSE;
+ } else {
+ if (Kbd->KeyData.Key.ScanCode == 0 && Kbd->KeyData.Key.UnicodeChar == 0 && Kbd->ScannerState == KBST_READY ) {
+ //
+ // If the Key ShiftState has valid key, report as Partial Key
+ //
+ if ((Kbd->KeyData.KeyState.KeyShiftState & ~SHIFT_STATE_VALID) != 0) {
+
+ pBS->CopyMem(&DummyKey, &Kbd->KeyData, sizeof(EFI_KEY_DATA));
+ DummyKey.KeyState.KeyToggleState |= KEY_STATE_EXPOSED;
+ CheckKeyNotify((AMI_EFI_KEY_DATA*)&DummyKey);
+ }
+ }
+ }
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: HandleKBDData
+//
+// Description: Processes the input data. If a callback function is
+// associated with the key, then it is executed.
+//
+// Paremeters:
+// KEYBOARD *Kbd - Pointer to key buffer
+// UINT8 data - Key data
+//
+// Output: None
+//
+//
+// Notes: This routine can be called re-entrantly from LEDsOnOff(OutToKb)
+// e.g. when Numlock and Del is pressed continously.
+// Incoming key is processed, Context->KeyIsReady is updated.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+HandleKBDData (
+ KEYBOARD *Kbd,
+ UINT8 data )
+{
+ //
+ // PS2 keyboard could send one, two, four or six bytes in a row.
+ // Kbd->ScannerState is ST_READY if it is the first byte
+ //
+ if (Kbd->ScannerState == KBST_READY)
+ {
+ switch (data) {
+ case 0xE0:
+ Kbd->ScannerState = KBST_E0;
+ break;
+ case 0xE1:
+ Kbd->ScannerState = KBST_E1;
+ break;
+ default:
+ ProcessByte(Kbd, data, FALSE);
+ }
+ return;
+ }
+ else // Multi-byte sequence is being processed
+ {
+ if (Kbd->ScannerState == KBST_E1) // Processing E1 state
+ {
+ if (data != E1Seq[Kbd->Count]) { // Wrong byte in a sequence
+ ResetStateMachine(Kbd);
+ return;
+ }
+ //
+ // E1 sequence data is correct, proceed
+ //
+ if (Kbd->Count == 2) { // The ONLY 2-key sequence starting with E1 is Pause
+ Kbd->KeyData.EfiKey = EfiKeyPause;
+ Kbd->KeyIsReady = TRUE;
+ ResetStateMachine(Kbd);
+ return;
+ }
+ if (Kbd->Count == 4) { // E1 sequence has finished
+ ProcessByte(Kbd, data, FALSE);
+ ResetStateMachine(Kbd);
+ return;
+ }
+ //
+ // E1 sequence is not complete, update the counter and return
+ //
+ Kbd->Count++;
+ return;
+ }
+ else // Kbd->ScannerState == ST_E0 - processing E0 state
+ {
+
+ //
+ // For E0 state the Count values will be:
+ // 0 for 1st and 2nd byte
+ // 2 for 3rd byte (if available)
+ // 1 for 4th byte (if available)
+ // No validity checking will be done for 2nd,3rd and 4th bytes
+ //
+
+ if (Kbd->ScannerState == KBST_E0) {
+ if ( IsEnhancedKey( data)) {
+ ResetStateMachine(Kbd);
+ return;
+ }
+ // Processing E0 state, if data is 2A or AA or MSB bit is
+ // set (break key) ignore it.
+ if (data == 0x2A || data == 0xAA || data & 0x80 && \
+ // except in special case of alt, ctrl, Print key, Left Logo, Right Logo and Menu Key
+ data != 0xb8 && data != 0x9d && data != 0xB7 && \
+ data != 0xDB && data != 0xDC && data != 0xDD) {
+ ResetStateMachine(Kbd);
+ return;
+ }
+ else {
+ ProcessByte(Kbd, data, TRUE);
+ ResetStateMachine(Kbd);
+ return;
+ }
+ }
+ ProcessByte(Kbd, data, FALSE);
+ ResetStateMachine(Kbd);
+ return;
+
+ }
+ }
+}
+
+
+
+void ResetStateMachine(KEYBOARD *Kbd)
+{
+ Kbd->ScannerState = KBST_READY;
+ Kbd->Count = 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IsLetter
+//
+// Description: Returns TRUE if the given make code belongs to the
+// alphabetical symbol, otherwise returns FALSE.
+//
+// Paremeters: UINT8 data - The character to test
+//
+// Output: BOOLEAN - True if character is letter
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsLetter (
+ UINT8 data )
+{
+ if ((data >= 0x10 && data <= 0x19) || // Q...P
+ (data >= 0x1E && data <= 0x26) || // A...L
+ (data >= 0x2C && data <= 0x32)) { // Z...M
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessByte
+//
+// Description: Checks for valid key, updates key modifiers, keyboard
+// queue head and tail as well as Kbd->KeyIsReady field.
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// UINT8 data - byte to process
+// BOOLEAN long_sequence - the indication of whether it is a
+// 4 byte sequence or not; used to differentiate Shift keys
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessByte (
+ KEYBOARD *Kbd,
+ UINT8 Data,
+ BOOLEAN long_sequence )
+{
+ BOOLEAN bUpperCase, bShifted;
+ EFI_EXTKEY *extkey;
+ static BOOLEAN Make_Capslock = FALSE, Make_SCRLOCK = FALSE, Make_NUMLOCK = FALSE;
+ UINT8 *KeyboardTypeBda = (UINT8*)((UINTN) 0x496);
+
+
+ Kbd->KeyData.Key.ScanCode = 0;
+ Kbd->KeyData.Key.UnicodeChar = 0;
+ Kbd->KeyData.PS2ScanCode = Data;
+
+ //
+ // Process ESC key
+ //
+ if (Data == 1) {
+ Kbd->KeyData.Key.ScanCode = EFI_SCAN_ESC;
+ Kbd->KeyData.EfiKey = EfiKeyEsc;
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+
+ //
+ // Get the E0, E1 Status from BDA (40:96). If those bit get set means Int9 processed the E0
+ // E1 data and before processing other Scan code it came out of Legacy mode.
+ // Now EFI driver sees other scan code that's part of the E0 and E1 scan. So we don't want to Process
+ // those data.
+ //
+#if CHECK_BDA_KEYBOARD_BUFFER
+#if CSM_SUPPORT
+ if( gLegacyBiosProtocolFound ) {
+ if(*KeyboardTypeBda & (E0_STATUS_IN_BDA + E1_STATUS_IN_BDA)) {
+ *KeyboardTypeBda &=~(E0_STATUS_IN_BDA + E1_STATUS_IN_BDA);
+ return;
+ }
+ }
+#endif
+#endif
+
+ //
+ // Process key modifiers: xyzLock (update LEDs) and Ctrl/Alt/Shift
+ //
+ switch (Data) {
+ case 0x38:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_ALT_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_ALT_PRESSED;
+ }
+ return; //break;
+ case 0xB8:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~RIGHT_ALT_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~LEFT_ALT_PRESSED;
+ }
+ return; //break;
+
+ case 0x1D:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_CONTROL_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_CONTROL_PRESSED;
+ }
+ return; //break;
+ case 0x9D:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~RIGHT_CONTROL_PRESSED;
+ } else {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~LEFT_CONTROL_PRESSED;
+ }
+ return; //break;
+
+ case 0x2A: {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_SHIFT_PRESSED; return; //break;
+ }
+ case 0xAA: // could be a part of a long break code
+ if (!long_sequence) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~LEFT_SHIFT_PRESSED;
+ }
+ return; //break;
+
+ case 0x36: Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_SHIFT_PRESSED; return; //break;
+ case 0xB6: Kbd->KeyData.KeyState.KeyShiftState &= ~RIGHT_SHIFT_PRESSED; return; //break;
+
+ case 0x3A:
+ if (!Make_Capslock) {
+ Kbd->KeyData.KeyState.KeyToggleState ^= CAPS_LOCK_ACTIVE;
+ Make_Capslock = TRUE;
+ }
+ Kbd->KeyData.EfiKey = EfiKeyCapsLock;
+ Kbd->KeyIsReady = TRUE;
+ break;
+
+ case 0xBA: Make_Capslock = FALSE; break;
+
+ case 0x46:
+ if (Kbd->ScannerState != KBST_E0){
+ if (!Make_SCRLOCK) {
+ Kbd->KeyData.KeyState.KeyToggleState ^= SCROLL_LOCK_ACTIVE;
+ Make_SCRLOCK = TRUE;
+ }
+ Kbd->KeyData.EfiKey = EfiKeySLck;
+ Kbd->KeyIsReady = TRUE;
+ }
+ break;
+
+ case 0xC6:
+ if (Kbd->ScannerState != KBST_E0){
+ Make_SCRLOCK = FALSE;
+ }
+ break;
+ case 0x45:
+ if (!Make_NUMLOCK) {
+ Kbd->KeyData.KeyState.KeyToggleState ^= NUM_LOCK_ACTIVE;
+ Make_NUMLOCK = TRUE;
+ }
+ Kbd->KeyData.EfiKey = EfiKeyNLck;
+ Kbd->KeyIsReady = TRUE;
+ break;
+
+ case 0xC5: Make_NUMLOCK = FALSE; break;
+ //
+ // Handle the PrintScreen/SysRq make Code
+ //
+ case 0x37:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= SYS_REQ_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the PrintScreen/SysRq breakcode
+ //
+ case 0xB7:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ SYS_REQ_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Left Logo make Code
+ //
+ case 0x5B:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= LEFT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Left Logo breakcode
+ //
+ case 0xDB:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ LEFT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Right Logo make Code
+ //
+ case 0x5C:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= RIGHT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Right Logo breakcode
+ //
+ case 0xDC:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ RIGHT_LOGO_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Menu Key make Code
+ //
+ case 0x5D:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState |= MENU_KEY_PRESSED;
+ return;
+ }
+ break;
+
+ //
+ // Handle the Meny Key breakcode
+ //
+ case 0xDD:
+ if (Kbd->ScannerState == KBST_E0) {
+ Kbd->KeyData.KeyState.KeyShiftState &= ~ MENU_KEY_PRESSED;
+ return;
+ }
+ break;
+
+ case 0xFA: ProcessKBDResponse(Kbd, Data); break;
+ case 0xFE: ProcessKBDResponse(Kbd, Data); break;
+ case 0xFF: ProcessKBDResponse(Kbd, Data); break;
+ }
+
+ //
+ // Process main block of keys
+ //
+ if (Data < 0x3A && !(Kbd->ScannerState == KBST_E0 && Data == 0x37)) {// Exceptional case is Printscreen/sys req
+
+ bShifted = Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+
+ if (Kbd->ScannerState == KBST_E0) bShifted = 0; // Check for '/' in Keypad. Otherwise '?' will be sent
+
+
+ if (IsLetter(Data)) { // for not-a-letter Caps-Lock must not work
+ bUpperCase = (Kbd->KeyData.KeyState.KeyToggleState & CAPS_LOCK_ACTIVE)? !bShifted: bShifted;
+ }
+ else {
+ bUpperCase = bShifted;
+ }
+ if (bUpperCase) {
+ Kbd->KeyData.Key.UnicodeChar = Code_Table[Data]; // UPPER CASE TABLE
+ }
+ else {
+ Kbd->KeyData.Key.UnicodeChar = code_table[Data]; // lower case table
+ }
+ Kbd->KeyData.EfiKey = ScancodeToEfi_table[Data];
+ if (Kbd->KeyData.Key.UnicodeChar != 0) {
+ Kbd->KeyIsReady = TRUE;
+ }
+ return;
+ }
+
+// UK Keyboard "|\" (EfiKeyB0)
+// data = 0x56(ScanCode Set1), EfiKeyB0, "|\"
+ if ( Data == 0x56) {
+ bShifted = Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+ if ( Kbd->ScannerState == KBST_E0) bShifted = 0; // Check for '/' in Keypad. Otherwise '?' will be sent
+ bUpperCase = bShifted; // for not-a-letter Caps-Lock must not work
+ if (bUpperCase) {
+ Kbd->KeyData.Key.UnicodeChar = '|'; // UPPER CASE TABLE
+ }
+ else {
+ Kbd->KeyData.Key.UnicodeChar = '\\'; // lower case
+ }
+ Kbd->KeyData.EfiKey = EfiKeyB0;
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+
+ //
+ // Process keypad keys. Exceptional cases: -, + on keypad
+ // Keypad numbers when NUMLOCK only is ON OR Shift only is pressed.
+ if (Kbd->ScannerState != KBST_E0) {
+ if ((Data > 0x46) && (Data < 0x54) && !long_sequence) {
+ if (((Kbd->KeyData.KeyState.KeyToggleState & NUM_LOCK_ACTIVE) // Only NUMLOCK in ON
+ && ((Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) == 0))
+ || (((Kbd->KeyData.KeyState.KeyToggleState & NUM_LOCK_ACTIVE) == 0) // Only shift key is pressed
+ && (Kbd->KeyData.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)))
+ || Data == 0x4a || Data ==0x4e) // check for -, + keys in keypad
+ {
+ Kbd->KeyData.Key.UnicodeChar = KeyPad_Table[Data-0x47];
+ Kbd->KeyData.EfiKey = KeyPadEfiCode_Table[Data-0x47];
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+ }
+ }
+ //
+ // Process F-keys
+ //
+ for (extkey = ScanCode_Table; extkey->makecode != 0xFF; extkey++) {
+ if (Data == extkey->makecode) {
+ Kbd->KeyData.Key.ScanCode = extkey->efi_scancode;
+ Kbd->KeyData.EfiKey = extkey->efi_key;
+ Kbd->KeyIsReady = TRUE;
+ return;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LEDsOnOff
+//
+// Description: Turns keyboard LEDs on and off.
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void LEDsOnOff (
+ KEYBOARD* Kbd )
+{
+
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+
+ if (InsidePS2DataDispatcher) return;
+ InsidePS2DataDispatcher = TRUE;
+
+ //
+ // Check for keyboard IRQ support
+ //
+ if(KbdIrqSupport){
+ if(gKeyboardIrqInstall && KBDEnableState){
+ if (bIndicators != Kbd->Indicators){
+ //
+ // Turn on/off the lights
+ //
+ Kbd->CommandResponded = NULL;
+ //
+ // Issue Keyboard LED Command 0xED
+ //
+ CheckIssueLEDCmd(Kbd);
+ if(Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ //
+ // LED command "ED" has been issues. Process the Data here itself.
+ //
+ UINT32 Counter;
+ for (Counter = 1000; Counter > 0; Counter--) {
+ //
+ // The Interrupt handler will handle the response
+ // and set the Kbd->LEDCommandState to zero in both
+ // case with or without error. Exit once the response is
+ // handled.
+ //
+ if(Kbd->LEDCommandState == 0) {
+ break;
+ }
+ gSysTable->BootServices->Stall(1000);
+
+ }
+ }
+ }
+ Kbd->LEDCommandState = NULL;
+ InsidePS2DataDispatcher = FALSE;
+ return;
+ }
+ }
+
+
+ if (bIndicators != Kbd->Indicators) {
+ //
+ // Issue Keyboard LED Command 0xED
+ //
+ CheckIssueLEDCmd(Kbd);
+
+ //
+ //Process the led command and data
+ //
+ ProcessLEDCommandData(Kbd);
+ }
+
+ InsidePS2DataDispatcher = FALSE;
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetKeyFromBuffer
+//
+// Description: Gets the next key from the circular buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// EFI_INPUT_KEY *key - Pointer to input key data
+//
+// Output: EFI_SUCCESS - key.ScanCode and key.UnicodeChar updated
+// EFI_NOT_READY - no key in buffer
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetKeyFromBuffer (
+ KEYBOARD *Kbd,
+ VOID *Key,
+ UINT8 KeySize
+)
+{
+ AMI_EFI_KEY_DATA TempKey;
+
+ if (Kbd->pBufHead == Kbd->pBufTail) return EFI_NOT_READY;
+
+ pBS->CopyMem(&TempKey, Kbd->pBufHead, sizeof(AMI_EFI_KEY_DATA));
+
+
+ TempKey.EfiKeyIsValid = 1;
+ TempKey.PS2ScanCodeIsValid = 1;
+
+ ProcessMultiLanguage(&TempKey);
+
+ if (TempKey.Key.UnicodeChar != 0) {
+ TempKey.KeyState.KeyShiftState &= ~(RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+ }
+
+ pBS->CopyMem(Key, &TempKey, KeySize);
+
+ Kbd->pBufHead++;
+ if (Kbd->pBufHead >= Kbd->pBufEnd) Kbd->pBufHead = Kbd->pBufStart; // Point to the beginning
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InsertKeyToBuffer
+//
+// Description: Insert the key into the circular buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// AMI_EFI_INPUT_KEY key - input key data
+//
+// Output: EFI_SUCCESS - Key placed in buffer
+// EFI_WARN_BUFFER_TOO_SMALL - Buffer to small
+//
+// Notes: If buffer is full, the EFI_WARN_BUFFER_TOO_SMALL.
+// Tail points to the new Data.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertKeyToBuffer (
+ KEYBOARD *Kbd,
+ AMI_EFI_KEY_DATA *Key
+)
+{
+ AMI_EFI_KEY_DATA *Temp = Kbd->pBufTail;
+
+ CheckKeyNotify(Key);
+ if (Kbd->pBufTail != Kbd->pBufHead) { // Check if space available
+ Temp++;
+ if (Temp >= Kbd->pBufEnd) Temp = Kbd->pBufStart;
+ if (Kbd->pBufHead == Temp) return EFI_WARN_BUFFER_TOO_SMALL; // No more space
+ }
+
+ *Kbd->pBufTail = *Key;
+ Kbd->pBufTail++;
+
+ if (Kbd->pBufTail >= Kbd->pBufEnd) Kbd->pBufTail = Kbd->pBufStart;
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckKeyinBuffer
+//
+// Description: Checks if any key is present in the buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+//
+// Output: BOOLEAN - TRUE if a key is in the buffer, FALSE otherwise.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+CheckKeyinBuffer (
+ KEYBOARD* Kbd
+)
+{
+ if (Kbd->pBufHead == Kbd->pBufTail) return FALSE;
+ return TRUE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckPartialKey
+//
+// Description: Gets the next key from the circular buffer
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+// EFI_INPUT_KEY *key - Pointer to input key data
+//
+// Output: EFI_SUCCESS - Partial Key Found
+// EFI_NOT_READY - no key in buffer
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CheckPartialKey (
+ KEYBOARD *Kbd,
+ EFI_KEY_DATA *Key
+)
+{
+
+ if (Kbd->KeyData.Key.ScanCode == 0 && Kbd->KeyData.Key.UnicodeChar == 0) {
+ //
+ // If the Key ShiftState has valid key, report as Partial Key
+ //
+ if ((Kbd->KeyData.KeyState.KeyShiftState & ~SHIFT_STATE_VALID) != 0) {
+
+ pBS->CopyMem(Key, &Kbd->KeyData, sizeof(EFI_KEY_DATA));
+ Key->KeyState.KeyToggleState |= KEY_STATE_EXPOSED;
+ CheckKeyNotify((AMI_EFI_KEY_DATA*)Key);
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_NOT_READY;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: KeyboardInterruptHandler
+//
+// Description: An interrupt handler for keyboard IRQ.
+//
+//
+// Input: InterruptType Interrupt type
+// SystemContext System context
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID KeyboardInterruptHandler(
+ IN EFI_EXCEPTION_TYPE InterruptType,
+ IN EFI_SYSTEM_CONTEXT SystemContext
+)
+{
+ KEYBOARD_IRQ_STORE* KbIrqBuffer = &gKeyboardIrqBuffer;
+ KEYBOARD *Kbd = &gKbd;
+ UINT8 bIndicators = Kbd->KeyData.KeyState.KeyToggleState & 7; // SCRL/NUM/CPSL
+ UINT8 Data = IoRead8(KBC_DATA_PORT);
+
+ gCpuArch->DisableInterrupt(gCpuArch);
+
+ //
+ // Stored received acknowledgement
+ //
+ switch (Data) {
+ case 0xFA:
+ Kbd->CommandResponded = KB_ACK_COM;
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ Kbd->LEDCommandState = ED_DATA_ISSUED;
+ Kbd->Indicators = bIndicators;
+ WriteKeyboardData(bIndicators);
+ break;
+ }
+
+ if (Kbd->LEDCommandState == ED_DATA_ISSUED) {
+ Kbd->LEDCommandState = 0;
+ break;
+ }
+
+ break;
+ case 0xFE:
+ Kbd->CommandResponded = KB_RSND_COM;
+ if (Kbd->LEDCommandState == ED_COMMAND_ISSUED || Kbd->LEDCommandState == ED_DATA_ISSUED) {
+// Error occured. Clear out the current indicator bits.
+// Modifiers will have the correct bits that needs to be set.
+// Next Call to CheckIssueLEDCmd will detect the mismatch
+// and start the LED sequence.
+ WriteKeyboardData(0xF4);
+ Kbd->LEDCommandState = 0;
+ Kbd->KeyData.KeyState.KeyToggleState &=
+ ~(SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE);
+ Kbd->Indicators &= 0xf0;
+ }
+ break;
+ case 0xFF:
+ Kbd->CommandResponded = KB_RSND_COM;
+ Kbd->LEDCommandState = 0;
+ break;
+ default:
+ //
+ // If key has been pressed before keyboard start then data will be saved in local buffer
+ // else data will be processed
+ //
+ if(!gKeyboardDriverStart){
+ if (KbIrqBuffer->KbdIndex < BUFFER_SIZE){
+ KbIrqBuffer->KbdBuffer[KbIrqBuffer->KbdIndex]=Data;
+ KbIrqBuffer->KbdIndex++;
+ }
+ }
+ else {
+ ProcessKBDData (Kbd, Data);
+ }
+ break;
+ }
+
+ //
+ // End of interrupt command sent
+ //
+ mLegacy8259->EndOfInterrupt(mLegacy8259, SYSTEM_KEYBOARD_IRQ);
+ gCpuArch->EnableInterrupt(gCpuArch);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitKeyboardIrq
+//
+// Description: To initialize keyboard interrupt, register keyboard
+// handler, and enable the keyboard interrupt
+//
+// Input:
+//
+// Paremeters:
+//
+// Output: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID InitKeyboardIrq(VOID)
+{
+
+ EFI_STATUS Status;
+ KEYBOARD_IRQ_STORE* KbIrqBuffer = &gKeyboardIrqBuffer;
+ EFI_GUID gEfiLegacy8259ProtocolGuid = EFI_LEGACY_8259_PROTOCOL_GUID;
+ EFI_GUID gEfiCpuArchProtocolGuid = EFI_CPU_ARCH_PROTOCOL_GUID;
+ UINT32 KeyboardVector = NULL;
+
+ if (!gKeyboardIrqInstall){
+ Status = pBS->LocateProtocol(&gEfiLegacy8259ProtocolGuid, NULL, &mLegacy8259);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ // Find the CPU Arch Protocol
+ Status = pBS->LocateProtocol(&gEfiCpuArchProtocolGuid, NULL, &gCpuArch);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ //
+ // Get keyboard Interrupt vector
+ //
+ Status = mLegacy8259->GetVector(mLegacy8259, SYSTEM_KEYBOARD_IRQ, (UINT8 *) & KeyboardVector);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ //
+ // Register interrupt handler for keyboard
+ //
+ Status = gCpuArch->RegisterInterruptHandler(gCpuArch, KeyboardVector, KeyboardInterruptHandler);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ KbIrqBuffer->KbdIndex=0;
+ gKeyboardIrqInstall = TRUE;
+
+ //
+ // Now enable the interrupt
+ //
+ mLegacy8259->EnableIrq(mLegacy8259, SYSTEM_KEYBOARD_IRQ, FALSE);
+ }
+ return;
+}
+
+#if CLEAR_PENDING_KEYS_IN_PS2
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ClearOBF
+//
+// Description:
+// Clears any pending keys in Ps2 Output Buffer.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: This OBF clear is done since some PS2 KBC has pending keys even
+// after resetting the Keyboard.
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID
+ClearOBF(
+VOID
+)
+{
+ UINT8 bData;
+ UINT8 Counter=200;
+
+ pBS->Stall(10*1000);
+
+ while( IoRead8(KBC_CMDSTS_PORT) & KBC_OBF )
+ {
+ bData = IoRead8(KBC_DATA_PORT);
+ //
+ // wait 10 ms for KBC OBF output.
+ //
+ pBS->Stall(10*1000);
+ Counter--;
+ //
+ // If still keys are present after 2 sec. exit from the loop.
+ //
+ if(Counter==NULL) {
+ break;
+ }
+ }
+ return;
+}
+
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Ps2KbdReset
+//
+// Description:
+// Reset the Ps2 Keyboard by sending disabling and Enabling scanning.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID
+Ps2KbdReset(
+VOID
+)
+{
+ EFI_STATUS Status;
+ UINT8 bCount, bData, bBCount;
+
+ //
+ // Disable and enable keyboard to reset.
+ //
+ DisableKeyboard();
+
+ for (bBCount = 0; bBCount < 4; bBCount++) {
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_DISABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ for (bCount = 0; bCount < 3; bCount++) {
+ Status = ReadDevice(KBD_ENABLE_SCANNING, &bData, KB_ACK_COM);
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ if (!EFI_ERROR(Status)) {
+ break;
+ }
+ }
+
+ EnableKeyboard();
+ return;
+}
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessLEDCommandData
+//
+// Description: Process the LED command and data.
+//
+// Input: KEYBOARD *Kbd - A pointer to the KEYBOARD device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessLEDCommandData(
+ KEYBOARD* Kbd )
+{
+
+ UINT32 Counter;
+ UINT8 data;
+
+ if(Kbd->LEDCommandState == ED_COMMAND_ISSUED) {
+ //
+ // LED command "ED" has been issued. Disable the keyboard and
+ // Process the Data here itself.
+ //
+
+ DisableKeyboard();
+
+ for (Counter = 1000; Counter > 0; Counter--) {
+ for(data = IoRead8(KBC_CMDSTS_PORT); data & KBC_OBF; data = IoRead8(KBC_CMDSTS_PORT)) {
+ if (!(data & KBC_AUX_OBF)) {
+ //
+ // Handle the Command or Data Status
+ //
+ DrivePS2KbdMachine(NULL);
+ }
+ }
+
+ //
+ // If the command and data is processed with or without error, exit here.
+ //
+ if(Kbd->LEDCommandState == 0) {
+ return;
+ }
+ gSysTable->BootServices->Stall(1000);
+ }
+ EnableKeyboard();
+ }
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessMultiLanguage
+//
+// Description: It maps the current key to a Unicode character from
+// the keyboard layout
+//
+// Paremeters: KeyData - Pointer to the AMI_EFI_KEY_DATA .
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessMultiLanguage(
+ IN OUT AMI_EFI_KEY_DATA *KeyData)
+{
+ EFI_STATUS Status;
+
+ if(gPs2MultiLangSupportProtocol == NULL) {
+ Status= pBS->LocateProtocol (
+ &gAmiMultiLangSupportGuid,
+ NULL,
+ &gPs2MultiLangSupportProtocol
+ );
+ if(EFI_ERROR(Status)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+ Status = gPs2MultiLangSupportProtocol->KeyboardLayoutMap(gPs2MultiLangSupportProtocol,KeyData);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2main.c b/Core/EM/PS2CTL/ps2main.c
new file mode 100644
index 0000000..d760970
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2main.c
@@ -0,0 +1,655 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2main.c 22 11/07/12 12:23a Srikantakumarp $
+//
+// $Revision: 22 $
+//
+// $Date: 11/07/12 12:23a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2main.c $
+//
+// 22 11/07/12 12:23a Srikantakumarp
+// [TAG] EIP99411
+// [Category] Improvement
+// [Description] Add port validation check in the PS2Ctrl module before
+// starting the driver.
+// [Files] kbc.c, kbc.h, mouse.c, ps2main.c, CORE_DXE.sdl, Tokens.c
+//
+// 21 2/01/12 2:02a Deepthins
+// [TAG] EIP63116
+// [Category] New Feature
+// [Description] PS/2 Keyboard/Mouse IRQ mode generic support
+// [Files] Token.c, Ps2main.c, Ps2kbd.c, Mouse.c, kbc.h, kbc.c,
+// CORE_DXE.sdl
+//
+// 20 12/15/11 5:42p Artems
+// Fixed bug in Supported function
+//
+// 19 11/03/11 5:58a Rajeshms
+// [TAG] EIP73263
+// [Category] Improvement
+// [Description] PS2Ctl Driver Follow the UEFI Driver Model as per the
+// UEFI Spec.
+// [Files] ps2main.c, efismplpp.c
+//
+// 18 8/02/11 4:43a Rameshr
+// [TAG] - EIP 58974
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Yellow exclamation mark in Windows when PS2 KB/MS are not
+// present.
+// [RootCause]- ACPI name space variable reports that PS2 device present
+// [Solution] - Updated the SIO device status based on the device present
+// after BDS.
+// [Files] - Kbc.c, Kbc.h , Ps2main.c
+//
+// 17 4/27/11 4:35a Lavanyap
+// [TAG] - EIP49407
+// [Category] - IMPROVEMENT
+// [Description] - Move the Ps2 driver SDL tokens from Core Source to Core
+// Bin,So that we don't need to add Core source for changing the Ps2
+// driver SDL tokens.
+// [Files] - Ps2Ctl.sdl, ps2kbd.c, ps2main.c, ps2ctl.h, kbc.c, mouse.c,
+// hotkey.c, CORE_DXE.sdl, Tokens.c
+//
+// 16 1/24/11 3:45p Pats
+// [TAG] - EIP 18488
+// [Category] - Enhancement
+// [Severity] - Normal
+// [Symptom] - PS2CTL: Need hooks for port swap, Keybaord mouse detect.
+// [RootCause] - Support may be needed for kbc controller or SIO with
+// different support from AMI KB-5.
+// [Solution] - Changes to make AutodetectKbdMousePortsPtr elink
+// controlled instead of token controlled.
+// [Files] - ps2main.c
+// NOTE: Implementation of this change requires changes to CORE_DXE.sdl
+// and BdsBoard.c.
+//
+// 15 1/05/11 12:43a Rameshr
+// [TAG] EIPEIP 35306
+// [Category] Improvement
+// [Description] Report the Ps2 Controller and Device Error Codes.
+// [Files] AmiStatuscodes.h, Kbc.c, Kbc.h,Ps2ctl.sdl, ps2kbd.c,
+// ps2main.c ,Statuscode.h
+//
+// 14 8/28/09 10:03a Felixp
+// Component Name protocol implementation is upadted to support both
+// ComponentName and ComponentName2 protocols
+// (based on value of the EFI_SPECIFICATION_VERSION SDL token).
+//
+// 13 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 12 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 11 4/10/07 10:04a Felixp
+// LookupHID routine renamed to LookupPs2Hid to avoid linking issue when
+// linking with FloppyCtrl module
+//
+// 10 3/19/07 2:28p Pats
+// Removed test for KBC acrive.
+//
+// 9 3/13/07 5:36p Pats
+// Fixed problem in last BAT fix.
+//
+// 8 3/13/07 2:59p Pats
+// Tests for KBC active and skips KBC BAT test if it is. This preserves
+// the input key if there is one.
+//
+// 7 2/28/07 6:05p Pats
+// Made KBC BAT test removable with SDL token, to speed up boot, and to
+// keep keep Setup key (F2 or Del) from being absorbed.
+//
+// 6 3/13/06 2:38a Felixp
+//
+// 5 10/11/05 4:11p Srinin
+// KBD and Mouse Start function is called in TPL_NOTIFY state.
+//
+// 4 6/03/05 5:35p Felixp
+//
+// 2 2/25/05 10:27a Olegi
+//
+// 1 2/01/05 1:10a Felixp
+//
+// 4 1/31/05 3:12p Felixp
+// Driver Binding Installed on a new handle.
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 2 1/07/05 4:57p Felixp
+// Small bug fix in ComponentName Protocol (GetPS2_DP modified)
+//
+// 1 10/28/04 10:19a Olegi
+//
+// 9 9/30/04 8:13a Olegi
+// HotKeys added.
+//
+// 8 9/24/04 4:36p Olegi
+//
+// 7 9/21/04 5:53p Olegi
+//
+// 6 8/27/04 3:17p Olegi
+// Header and footer added.
+//
+// 5 8/18/04 6:44p Olegi
+// Logitech mouse PNPID added.
+//
+// 4 8/18/04 6:37p Olegi
+// Header and footer added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2main.c
+//
+// Description: PS/2 Controller DXE driver
+// This driver supports PS/2 keyboard and/or PS/2 mouse depending on the
+// switches in SDL tokens.
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------
+
+#include "efi.h"
+#include "ps2ctl.h"
+#include "kbc.h"
+#include <Protocol\ComponentName.h>
+
+//----------------------------------------------------------------------
+
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93}
+
+EFI_GUID gBdsAllDriversConnectedProtocolGuid = BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID;
+
+static EFI_GUID gDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#else
+static EFI_GUID gComponentNameProtocolGuid = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
+#endif
+EFI_GUID gDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+UINT8 gDriverStartCounter;
+
+VOID *gAllDriverConnectedNotifyRegistration;
+EFI_EVENT gAllDriverConnectedEvent;
+
+extern BOOLEAN Ps2MouseSupport;
+extern BOOLEAN Ps2KbdSupport;
+extern BOOLEAN KbcBasicAssuranceTest;
+extern EFI_COMPONENT_NAME_PROTOCOL gPS2CtlDriverName;
+extern EFI_LEGACY_8259_PROTOCOL *mLegacy8259;
+extern BOOLEAN KbRdBeforeInstall;
+extern BOOLEAN KbdIrqSupport;
+EFI_SYSTEM_TABLE *gSysTable = NULL;
+extern UINT8 gKeyboardIrqInstall;
+extern UINT32 IbFreeTimeoutValue;
+
+
+
+//==================================================================================
+// Function Prototypes for Driver Binding Protocol Interface
+//==================================================================================
+EFI_STATUS PS2CtlSupported(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS PS2CtlStart(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath);
+
+EFI_STATUS PS2CtlStop(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *ChildHandleBuffer);
+
+//==================================================================================
+// Driver binding protocol instance for PS2Ctl Driver
+//==================================================================================
+EFI_DRIVER_BINDING_PROTOCOL gPS2CtlDriverBinding = {
+ PS2CtlSupported,
+ PS2CtlStart,
+ PS2CtlStop,
+ PS2_DRIVER_VER, // Driver version
+ NULL, // Image Handle
+ NULL // DriverBindingHandle
+};
+
+//==================================================================================
+// Supported PS2 devices table
+//==================================================================================
+CHAR16 *gPS2ControllerName = L"PS/2 Controller";
+
+PS2DEV_TABLE supportedDevices[] = {
+ {EISA_PNP_ID(0xF03), 0, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"Microsoft PS/2 Mouse"},
+ {EISA_PNP_ID(0xF12), 0, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"Logitech PS/2 Mouse"},
+ {EISA_PNP_ID(0xF13), 0, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"Generic PS/2 Mouse"},
+ {EISA_PNP_ID(0x303), 1, DEVICETYPE_MOUSE, StartMouse, StopMouse, L"IBM Keyboard, PS/2 Mouse Support"},
+ {EISA_PNP_ID(0x303), 0, DEVICETYPE_KEYBOARD, StartKeyboard, StopKeyboard, L"Generic PS/2 Keyboard"},
+ {0} // End of table
+};
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlEntryPoint
+//
+// Description: PS/2 Controller Driver Entry Point
+// This function is a part of DriverBinfing protocol
+//
+// Parameters: EFI_HANDLE ImageHandle - Image handle for this driver
+// image
+// EFI_SYSTEM_TABLE *SystemTable - pointer to the EFI
+// system table
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlEntryPoint(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ gSysTable = SystemTable;
+ gPS2CtlDriverBinding.DriverBindingHandle = NULL;
+ gPS2CtlDriverBinding.ImageHandle = ImageHandle;
+
+ Status = gSysTable->BootServices->InstallMultipleProtocolInterfaces(
+ &gPS2CtlDriverBinding.DriverBindingHandle,
+ &gDriverBindingProtocolGuid, &gPS2CtlDriverBinding,
+ &gComponentNameProtocolGuid, &gPS2CtlDriverName,
+ NULL);
+
+ gDriverStartCounter = 0;
+
+ //
+ // Update the SIO variable in the ACPI name space depend on the
+ // Ps2keyboard and Mouse Present state.
+ //
+ Status = RegisterProtocolCallback(
+ &gBdsAllDriversConnectedProtocolGuid,
+ UpdateSioVariableForKeyboardMouse,
+ NULL,
+ &gAllDriverConnectedEvent,
+ &gAllDriverConnectedNotifyRegistration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Initialized Keyboard irq if keys are to be read before starting driver
+ // IRQ handler will save the data in temp buffer and once the Keyboard
+ // Driver started , the temp buffer data is pushed into Keyboard driver.
+ // So that the key's are pressed in post also taken by Ps2 driver
+ //
+ if(KbRdBeforeInstall){
+ if(IoRead8(KBC_CMDSTS_PORT) != 0xFF) {
+ //
+ // Enable the Keyboard and Keyboard Interrupt
+ //
+ Write8042CommandByte(0x65);
+ InitKeyboardIrq();
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlSupported
+//
+// Description: PS/2 Controller Driver Supported function
+// This function is a part of DriverBinfing protocol
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL - *RemainingDevicePath -
+// Pointer to last node in device path
+//
+// Output: EFI_SUCCESS - Ps2 Controller supported
+// EFI_UNSUPPORTED -- Ps2 Controller not supported
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlSupported(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{
+ ACPI_HID_DEVICE_PATH* acpiDP;
+
+ //
+ // Checking if KBC is available at all
+ //
+ if (IoRead8 (KBC_CMDSTS_PORT) == 0xFF){
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Find the last device node in the device path and return "Supported"
+ // for mouse and/or keyboard depending on the SDL switches.
+ //
+ if( !EFI_ERROR(GetPS2_DP(This, Controller, &acpiDP, EFI_OPEN_PROTOCOL_BY_DRIVER)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, 0)){
+ return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlStart
+//
+// Description: PS/2 Controller Driver Start function
+// This function is a part of DriverBinfing protocol
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// EFI_DEVICE_PATH_PROTOCOL - *RemainingDevicePath -
+// Pointer to last node in device path
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlStart(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
+{
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ PS2DEV_TABLE *ps2dev = 0;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ //
+ // The following code performs the basic KBC initialization
+ // It has to be executed only once, we use global variable
+ // gDriverStartCounter to control this. Also, this code is
+ // executed on a higher TPL to prevent re-entrance.
+ //
+ OldTpl = gSysTable->BootServices->RaiseTPL(TPL_NOTIFY);
+ if (OldTpl > TPL_NOTIFY) return EFI_DEVICE_ERROR;
+
+ while (!gDriverStartCounter) {
+ //
+ // Disable the Keyboard IRQ if it's enabled before
+ // Finish all the Keyboard Initilization and Re-enable the IRQ again
+ //
+ if(KbRdBeforeInstall){
+ mLegacy8259->DisableIrq( mLegacy8259, SYSTEM_KEYBOARD_IRQ );
+ gKeyboardIrqInstall=FALSE;
+ }
+ // Initialize KBC hardware
+ //
+ if ( KbcBasicAssuranceTest ) {
+ Status = KBCBatTest(); // Perform KBC Basic Assurance Test
+ if (EFI_ERROR(Status)) {
+ //
+ // Report the Error code if the BAT test failed
+ //
+ ERROR_CODE (DXE_KEYBOARD_STUCK_KEY_ERROR, EFI_ERROR_MAJOR);
+ break;
+ }
+
+ //
+ // Check for stuck keys
+ //
+ Status = IbFreeTimeout(IbFreeTimeoutValue);
+ if (EFI_ERROR(Status)) {
+ //
+ // Report the Error Code.
+ //
+ ERROR_CODE (DXE_KEYBOARD_STUCK_KEY_ERROR, EFI_ERROR_MAJOR);
+ break;
+ }
+ }
+ // Swap ports if needed
+ if (AutodetectKbdMousePortsPtr!=NULL) AutodetectKbdMousePortsPtr();
+
+ gDriverStartCounter++;
+ }
+
+
+ if(!EFI_ERROR(GetPS2_DP(This, Controller, &acpiDP, EFI_OPEN_PROTOCOL_BY_DRIVER)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, &ps2dev) ){
+ Status = ps2dev->start(This, Controller);
+
+ //
+ // End of critical section - restore TPL
+ //
+ gSysTable->BootServices->RestoreTPL(OldTpl);
+
+ if(EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // End of critical section - restore TPL
+ //
+ gSysTable->BootServices->RestoreTPL(OldTpl);
+
+ //
+ // If control is here then something totally wrong happend:
+ // if device is not supported then Start shouldn't be called.
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PS2CtlStop
+//
+// Description: PS/2 Controller Driver Stop function
+// This function is a part of DriverBinfing protocol
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// UINTN NumberOfChildren - Number of children of this
+// controller
+// EFI_HANDLE *ChildHandleBuffer - Pointer to a buffer
+// for child handles
+//
+// Output: EFI_STATUS - Status of the operation
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PS2CtlStop(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *ChildHandleBuffer)
+{
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ PS2DEV_TABLE *ps2dev = 0;
+ EFI_STATUS Status;
+
+ if(!EFI_ERROR(GetPS2_DP(This, Controller, &acpiDP, EFI_OPEN_PROTOCOL_GET_PROTOCOL)) &&
+ LookupPs2Hid(supportedDevices, acpiDP->HID, acpiDP->UID, &ps2dev) ){
+ Status = ps2dev->stop(This, Controller);
+ if(EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If control is here then device path was not found in the lookup table
+ //
+ return EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LookupPs2Hid
+//
+// Description: This fuction searches the PS2 device in table that
+// matches given HID and UID
+//
+// Paremeters:
+// PS2DEV_TABLE * devTable - Lookup table pointer
+// UINT32 hid - HID to look for
+// UINT32 uid - UID to look for
+// PS2DEV_TABLE** dev - address of the matched table entry
+//
+// Output:
+// BOOLEAN - TRUE if match is found, FALSE otherwise
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN LookupPs2Hid(
+ PS2DEV_TABLE * devTable,
+ UINT32 hid,
+ UINT32 uid,
+ PS2DEV_TABLE** dev)
+{
+ for( ;devTable->hid;++devTable){
+ if( devTable->hid == hid && devTable->uid==uid){
+ if ( (devTable->DeviceType == DEVICETYPE_MOUSE && Ps2MouseSupport) ||
+ (devTable->DeviceType == DEVICETYPE_KEYBOARD && Ps2KbdSupport) ) {
+ if(dev) *dev = devTable;
+ return TRUE;
+ }
+ }
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetPS2_DP
+//
+// Description: This fuction returns the last node in the device
+// path for the given controller.
+//
+// Paremeters: EFI_DRIVER_BINDING_PROTOCOL *This - Pointer to this
+// instance of the driver binding protocol
+// EFI_HANDLE Controller - Handle for this controller
+// ACPI_HID_DEVICE_PATH** ps2dp - Pointer to ACPI HID
+// device path
+// UINT32 Attributes - Attributes passed to driver binding
+// protocol
+//
+// Output:
+// EFI_SUCCESS or EFI_UNSUPPORTED
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetPS2_DP(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ ACPI_HID_DEVICE_PATH** ps2dp,
+ UINT32 Attributes)
+{
+ EFI_STATUS Status;
+ ACPI_HID_DEVICE_PATH *acpiDP;
+ EFI_DEVICE_PATH_PROTOCOL * ps2DevPath, *pDP;
+
+ //
+ // Get device path from Controller handle.
+ //
+ Status = gSysTable->BootServices->OpenProtocol (
+ Controller,
+ &gDevicePathProtocolGuid,
+ (VOID**)&pDP,
+ This->DriverBindingHandle,
+ Controller,
+ Attributes
+ );
+
+ if (EFI_ERROR(Status)) {
+ if( Status != (EFI_ALREADY_STARTED || EFI_ACCESS_DENIED) ) {
+ return EFI_UNSUPPORTED;
+ } else {
+ return Status;
+ }
+ }
+
+ //
+ // Process ps2DevPath - get the node which is before the EndNode
+ //
+ ps2DevPath=DPGetLastNode(pDP);
+
+ //
+ // ps2DevPath is now the last node
+ //
+ acpiDP = *ps2dp = (ACPI_HID_DEVICE_PATH*)ps2DevPath;
+
+ Status = (acpiDP->Header.Type == ACPI_DEVICE_PATH &&
+ acpiDP->Header.SubType == ACPI_DP)? EFI_SUCCESS : EFI_UNSUPPORTED;
+
+ if (Attributes!=EFI_OPEN_PROTOCOL_GET_PROTOCOL)
+ gSysTable->BootServices->CloseProtocol (
+ Controller,
+ &gDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PS2CTL/ps2mouse.h b/Core/EM/PS2CTL/ps2mouse.h
new file mode 100644
index 0000000..24fbcce
--- /dev/null
+++ b/Core/EM/PS2CTL/ps2mouse.h
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2mouse.h 6 9/19/11 9:37a Lavanyap $
+//
+// $Revision: 6 $
+//
+// $Date: 9/19/11 9:37a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/CORE_DXE/PS2CTL/ps2mouse.h $
+//
+// 6 9/19/11 9:37a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 5 8/23/10 4:25a Rameshr
+// Bug Fix : EIP 40838
+// Symptoms: KBC.C build failed in DetectPS2Keyboard() if
+// DETECT_PS2_KEYBOARD=0 & PS2MOUSE_SUPPORT=0
+// Files Modified: Efismplpp.c, Kbc.c, Kbc.h, Mouse.c PS2ctl.cif,
+// Ps2ctl.sdl, Ps2Kbd.c, Ps2Mouse.h
+// Details:
+// 1) Added Detect_PS2_Mouse sdl token and modified the code.
+// 2) INSTALL_KEYBOARD_MOUSE_ALWAYS sdl token added.
+// 1 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer Always,
+// 0 - Install the Keyboard- SimpleTextIn, Mouse - AbsPointer only if
+// the device is present at the time of detection.
+// This is for Ps2Keyboard Hot plug support in EFI
+// 3) Code clean up in mouse.c EfiSmplpp.c ,ps2mouse.h
+// 4) Unused file automaton.h removed.
+//
+// 4 7/01/09 12:32p Olegi
+// Source is corrected according to the coding standard: function headers,
+// copyright messages are updated.
+//
+// 3 4/16/07 6:28p Pats
+// Modified to conform with coding standards. No code changes.
+//
+// 2 3/04/05 1:39p Mandal
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: ps2mouse.h
+//
+// Description: Ps2 mouse support header
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include <Protocol\SimplePointer.h>
+
+typedef struct {
+ EFI_SIMPLE_POINTER_PROTOCOL iSmplPtr;
+ EFI_SIMPLE_POINTER_MODE mode;
+ EFI_SIMPLE_POINTER_STATE state;
+ UINT8 saved_flags;
+} MOUSE;
+
+
+EFI_STATUS MouseReset(
+ MOUSE *This,
+ BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS MouseGetState(
+ MOUSE *This,
+ EFI_SIMPLE_POINTER_STATE *State
+);
+
+EFI_STATUS DetectPS2mouse(
+ MOUSE*
+);
+
+VOID OnWaitingOnMouse(
+ EFI_EVENT Event,
+ MOUSE *Context
+);
+
+EFI_STATUS InitMOUSE(
+ MOUSE**
+);
+
+#define KBC_CMD_ENABLE_AUX 0x0A8
+#define KBC_CMD_DISABLE_AUX 0x0A7
+#define KBC_CMD_ENABLE_KBD 0x0AE
+#define KBC_CMD_DISABLE_KBD 0x0AD
+#define KBC_CMD_CHK_AUX 0x0A9
+#define KBC_CMD_WRT_AUX 0x0D4
+
+
+//----------------------------------------------------------------------------
+// MOUSE COMMANDS from SYSTEM SET SAMPLING RATE & SET RESOLUTION
+// Needs one more byte to be sent.
+//----------------------------------------------------------------------------
+
+#define RESET 0x0FF // Reset.
+#define DISABLE 0x0F5 // Disable.
+#define ENABLE 0x0F4 // Enable.
+#define SET_SAMPLING_RATE 0x0F3 // Set sampling rate.
+#define READ_DEVICE_TYPE 0x0F2 // Read device type.
+#define STATUS_REQUEST 0x0E9 // Status request.
+#define SET_RESOLUTION 0x0E8 // Set resolution.
+#define SET_SCALING_2X1 0x0E7 // Set scaling 2:1.
+#define RESET_SCALING 0x0E6 // Set scaling 1:1.
+#define REMOTE_MODE 0x0F0 // Set Remote Mode - mouse transfers
+ // packets by request
+#define READ_DATA 0x0eb // Forces thetransef of a mouse data packet
+#define SET_STANDART 0x0f6 // Iitialize PS/2 and set standart state
+//---------------------------------------
+// MOUSE RESPONSE ON COMMAND COMPLETION
+//---------------------------------------
+
+#define ACK 0x0fa // ACKnowledge
+#define RSND 0x0fe // RESEND
+#define ERROR 0x0fc // two invalid inputs received
+
+//---------------------------------------
+// CCB Flags
+//---------------------------------------
+
+#define CCB_PCCOMPAT 0x40 // PC Compatibility mode
+#define CCB_PS2MS_DISABLE 0x20 // Disable PS/2 mouse interface
+#define CCB_KBD_DISABLE 0x10 // Disable in succession by mouse
+#define CCB_SYSTEM 0x04 //
+#define CCB_MS_INTRPT 0x02 //
+#define CCB_KBD_INTRPT 0x01 //
+
+
+typedef struct {
+ UINT8 flags;
+ UINT8 x,y,z;
+} StdMouseDataPacket;
+
+#define BUTTON_MID 0x04
+#define BUTTON_RIGHT 0x02
+#define BUTTON_LEFT 0x01
+#define MOUSE_X_NEG 0x10
+#define MOUSE_Y_NEG 0x20
+#define MOUSE_X_OVF 0x40
+#define MOUSE_Y_OVF 0x80
+
+#define NON_WHEEL_REPORT_FORMAT 3
+#define WHEEL_REPORT_FORMAT 4
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.c b/Core/EM/PeiRamBoot/PeiRamBoot.c
new file mode 100644
index 0000000..f1c0acd
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.c
@@ -0,0 +1,783 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.c 21 8/28/15 3:55a Tristinchou $
+//
+// $Revision: 21 $
+//
+// $Date: 8/28/15 3:55a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.c $
+//
+// 21 8/28/15 3:55a Tristinchou
+// [TAG] EIP235157
+// [Category] Improvement
+// [Description] Security vulnerability - PeiRamBoot: Should leave cold
+// boot optimization only
+//
+// 20 10/02/14 4:44a Calvinchen
+// [TAG] EIP184075
+// [Category] Improvement
+// [Description] [HWR]FtRecovery support for Intel Top Swap
+// Modified PeiRamBoot module for multiple Boot Block Volumes support.
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 19 7/24/13 6:15a Calvinchen
+// Bug Fixed: System hangs at CP60 if LastFfsFile Guild is installed with
+// DebugMode "ON".
+//
+// 18 5/22/13 7:30a Calvinchen
+// System hangs if OPTIMIZE_BOOT_FV_COPY = 1 with AMI Debug Rx enabled
+// Description : Added Saveing Module Type "EFI_FV_FILETYPE_DRIVER" in
+// Optimize Boot FV.
+//
+// 17 3/15/13 4:39a Calvinchen
+// Bug Fixed: System hangs if OPTIMIZE_BOOT_FV_COPY = 1
+// Description : RAW and FREEFORM FFS must be saved in Optimize Boot FV.
+//
+// 16 2/05/13 12:51a Calvinchen
+//
+// 15 1/16/13 6:31a Calvinchen
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] 1. Added support to minimumize Boot FV copy for
+// improving POST time.
+// 2. Added Last Firmware Volume FFS file Override mechanism.
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 14 11/29/12 10:48p Calvinchen
+// [TAG] EIP106511
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PI 0.9 and 1.0 in Core 4.6.5.4
+// [RootCause] Build failed if PI 1.0.
+// [Files] PeiRamBoot.c
+//
+// 12 8/08/12 4:25a Calvinchen
+// 1. Changed for ReportFv2.c by Artem's suggestion.
+// 2. Fixed System hangs if Memory Mapping Changed with warm boot.
+//
+// 11 7/18/12 3:38a Calvinchen
+// [TAG] EIP94448
+// [Category] Improvement
+// [Description] Can not Save the DXE IPL Boot time,even add the PEI RAM
+// Boot eModule.
+//
+// 10 2/23/12 9:06a Calvinchen
+// Fixed building error.
+//
+// 9 2/23/12 6:35a Calvinchen
+// [TAG] EIP82264
+// [Category] Improvement
+// [Description] Need to do cold boot to get the correct data in rom
+// hole when changing data in rom hole.
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.h
+// PeiRamBoot.c
+// PeiRamBootDxe.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 8 5/27/11 7:19a Calvinchen
+// [TAG] EIP60320
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs at CP 0x72 when SMM_THUNK_IN_CSM is 0 on
+// Huronriver.
+// [RootCause] InSmmFunction is NULL in InitSmmHandlerEx call.
+// [Solution] Added dummy InSmmFunction.
+// [Files] PeiRamBoot.c
+//
+// 7 4/22/11 1:27a Calvinchen
+//
+// 6 3/22/11 7:52a Calvinchen
+// [TAG] EIP56322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs after changing TPM settings in SETUP.
+// [RootCause] System Memory Mappings are changed with warm boot.
+// [Solution] BIOS always go cold boot path if system memory mappings
+// are changed
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.dxs
+// PeiRamBoot.h
+// PeiRamBoot.c
+// PeiRamBootHook.c
+// PeiRamBootDxe.c
+// PeiRamBootOfbd.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 5 2/11/11 3:16a Calvinchen
+// Bug Fixed : System hangs after reflashed BIOS with warm reset if
+// PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot support.
+//
+// 4 12/29/10 5:35a Calvinchen
+// Bug Fixed : DMI structure not update in system memory if
+// PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot support.
+//
+// 3 12/26/10 9:59p Calvinchen
+// Bug Fixed:
+// 1. Recovery not work if PEI_RAM_BOOT_S3_SUPPORT = 2.
+// 2. S4 resume failed if PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot
+// support.
+//
+// 2 12/14/10 2:25a Calvinchen
+// Improvement :
+// 1. Added an eLink "PeiRamBootList" for fast warm boot support
+// (PEI_RAM_BOOT_S3_SUPPORT = 1). If system boots in warm boot state, BIOS
+// directly boot to previous copied ROM image in RAM to save time of
+// copying ROM.
+// 2. Added "PEI_RAM_BOOT_S3_SUPPORT" = "2" for saving runtime memory, it
+// only keep necessary PEIM FFS in runtime memory for S3 resume
+// improvement.
+//
+// 1 10/27/10 2:48a Calvinchen
+// Initial Check-in.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBoot.c
+//
+// Description: PEI RAM BOOT Pei driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <PEI.h>
+#include <AmiPeiLib.h>
+//#include <AmiCspLib.h>
+#include <ppi\ReadOnlyVariable.h>
+#include <ppi\RecoveryModule.h>
+#include <RomLayout.h>
+#include <Token.h>
+#include <PeiRamBoot.h>
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+#include <PeiCore.h>
+#endif
+#if defined (SecureBoot_SUPPORT) && SecureBoot_SUPPORT == 1
+#include <AmiCertificate.h>
+#endif
+//----------------------------------------------------------------------------
+// Function Externs
+extern
+VOID
+SwitchPeiServiceDataToRam (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage
+);
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+extern
+BOOLEAN
+IsPeimDispatched (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINTN Index
+);
+#else
+extern
+UINT64
+GetDispatchedPeimBitMap (
+ IN EFI_PEI_SERVICES **PeiServices
+);
+#endif
+extern ROM_AREA RomLayout[];
+
+typedef BOOLEAN (PEI_RAM_BOOT_ELINK) (EFI_PEI_SERVICES **PeiServices);
+extern PEI_RAM_BOOT_ELINK PEI_RAM_BOOT_LIST EndOfPeiRamBootList;
+PEI_RAM_BOOT_ELINK* IsMrcColdBooteLink[] = {PEI_RAM_BOOT_LIST NULL};
+
+//----------------------------------------------------------------------------
+// Local prototypes
+#define PR_KEY_FFS_FILE_RAW_GUID \
+{ 0x3FEEC852, 0xF14C, 0x4E7F, 0x97, 0xFD, 0x4C, 0x3A, 0x8C, 0x5B, 0xBE, 0xCC }
+#define ROM_LAYOUT_FFS_GUID \
+{ 0x0DCA793A, 0xEA96, 0x42d8, 0xBD, 0x7B, 0xDC, 0x7F, 0x68, 0x4E, 0x38, 0xC1 }
+#define FID_FFS_FILE_NAME_GUID \
+{ 0x3fd1d3a2, 0x99f7, 0x420b, 0xbc, 0x69, 0x8b, 0xb1, 0xd4, 0x92, 0xa3, 0x32 }
+#define PKEY_FILE_GUID \
+{ 0xCC0F8A3F, 0x3DEA, 0x4376, 0x96, 0x79, 0x54, 0x26, 0xba, 0x0a, 0x90, 0x7e }
+#define KEK_FILE_GUID \
+{ 0x9fe7de69, 0xaea, 0x470a, 0xb5, 0xa, 0x13, 0x98, 0x13, 0x64, 0x91, 0x89 }
+#define DB_FILE_GUID \
+{ 0xfbf95065, 0x427f, 0x47b3, 0x80, 0x77, 0xd1, 0x3c, 0x60, 0x71, 0x9, 0x98 }
+#define DBX_FILE_GUID \
+{ 0x9d7a05e9, 0xf740, 0x44c3, 0x85, 0x8b, 0x75, 0x58, 0x6a, 0x8f, 0x9c, 0x8e }
+
+EFI_GUID gHobRomImageGuid = ROM_IMAGE_MEMORY_HOB_GUID;
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+EFI_GUID gCacheInstallGuid = EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI;
+EFI_GUID gEfiPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+EFI_GUID gEfiPeiRecoveryModePpiGuid = EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI;
+EFI_GUID gEfiPeiRecoveryModulePpiGuid = EFI_PEI_RECOVERY_MODULE_PPI_GUID;
+EFI_GUID gSmbiosFlashDataFfsGuid = SMBIOS_FLASH_DATA_FFS_GUID;
+EFI_GUID gRomCacheEnablePpiGuid = ROM_CACHE_ENABLE_PPI_GUID;
+EFI_GUID gPrKeyFfsFileRawGuid = PR_KEY_FFS_FILE_RAW_GUID;
+EFI_GUID gLastFfsFileOverrideGuid = \
+{0x45B9618F, 0xBAA1, 0x421B, { 0x94, 0xF0, 0xB9, 0xEB, 0xDD, 0x2B, 0xA1, 0x77 }};
+
+EFI_STATUS
+PeiRamBootMemoryReady (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+);
+
+EFI_STATUS
+PeiRamBootEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+);
+static EFI_PEI_NOTIFY_DESCRIPTOR PeiRamBootMemoryReadyNotify[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gCacheInstallGuid,
+ PeiRamBootMemoryReady
+ }
+};
+static EFI_PEI_NOTIFY_DESCRIPTOR PeiRamBootEndOfPeiNotify[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ PeiRamBootEndOfPei
+ }
+};
+//----------------------------------------------------------------------------
+// Local Variables
+UINT32 FvBootBlocksList[] = {
+ PEI_RAM_BOOT_FV_BOOTBLOCK_LIST
+ FV_BB_BASE,
+ { -1 }
+};
+
+//----------------------------------------------------------------------------
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsBootFirmwareVolume
+//
+// Description:
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PHYSICAL_ADDRESS - Address
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IsBootBlockFirmwareVolumes (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS Address
+)
+{
+ UINT8 i;
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+ PEI_CORE_INSTANCE *Private = NULL;
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ if (Private->Fv[0].FvHeader == (EFI_FIRMWARE_VOLUME_HEADER*)Address)
+ return TRUE;
+#endif
+ for (i = 0; FvBootBlocksList[i] != -1; i++)
+ if (Address == (EFI_PHYSICAL_ADDRESS)FvBootBlocksList[i]) return TRUE;
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PrepareForCopyRomToRam
+//
+// Description: This procedure allocate memroy buffer for copying rom to ram.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// HOB_ROM_IMAGE - *HobRomImage
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PrepareForCopyRomToRam (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage
+)
+{
+ UINT8 i;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN NumOfPages;
+ EFI_PHYSICAL_ADDRESS Buffer = 0;
+
+ for (i = 0; i < HobRomImage->NumOfFv; i++) {
+ NumOfPages = HobRomImage->FvInfo[i].UsedBytes;
+ if (HobRomImage->FvInfo[i].FvLength !=
+ HobRomImage->FvInfo[i].UsedBytes) {
+#if SAVE_ENTIRE_FV_IN_MEM == 0
+ // 0x1200 = 1)4k aligned, 2)NULL bytes of FV
+ NumOfPages = HobRomImage->FvInfo[i].UsedBytes + 0x1200;
+#else
+ NumOfPages = HobRomImage->FvInfo[i].FvLength;
+#endif
+ }
+ Status = (*PeiServices)->AllocatePages ( PeiServices,
+ EfiBootServicesData,
+ NumOfPages >> 12,
+ &Buffer);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ // If HobValid is "TRUE", it means FV memories aren't destroyed, just
+ // reserve the necessary memory space for FV then exit.
+ if (HobRomImage->HobValid == TRUE) continue;
+ HobRomImage->FvInfo[i].NumOfPages = NumOfPages >> 12;
+ HobRomImage->FvInfo[i].MemAddress = (UINT32)Buffer;
+ HobRomImage->FvInfo[i].FvMemReady = FALSE;
+ }
+ return EFI_SUCCESS;
+}
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A) && (OPTIMIZE_BOOT_FV_COPY == 1)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: MinimumizeBootFv
+//
+// Description: This routine copy only undispatched PEIM and Preserved FFS Guid
+// to memory and FFS Header only if dispatched PEIM.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// HOB_ROM_IMAGE* - HobRomImage,
+// UINT8 - Index
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+MinimumizeBootFv (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage,
+ IN UINT8 Index
+)
+{
+ UINTN k = 0, n = 0, FfsLength;
+ UINT8 *p = (UINT8*)HobRomImage->FvInfo[Index].MemAddress;
+ UINT8 *q = (UINT8*)HobRomImage->FvInfo[Index].FvAddress;
+ EFI_FFS_FILE_HEADER *FfsFile = NULL;
+ EFI_GUID *pGuid = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ // 1. Copy Firmware Volume Header to Memory buffer.
+ (*PeiServices)->CopyMem ( \
+ p, q, ((EFI_FIRMWARE_VOLUME_HEADER*)q)->HeaderLength);
+ p += ((EFI_FIRMWARE_VOLUME_HEADER*)q)->HeaderLength;
+ do {
+ Status = (*PeiServices)->FfsFindNextFile (PeiServices, \
+ EFI_FV_FILETYPE_ALL, (EFI_FIRMWARE_VOLUME_HEADER*)q, &FfsFile );
+ if (EFI_ERROR(Status)) break;
+
+ // calculate file alignment (Align on 8 bytes).
+ FfsLength = *(UINT32*)FfsFile->Size & 0xffffff;
+ FfsLength = (FfsLength + 7) & 0xfffffff8;
+ // Copy undispatched PEIMs and FFS File Header only if dispatched PEIM
+ if ((FfsFile->Type == EFI_FV_FILETYPE_PEI_CORE) || \
+ ((FfsFile->Type == EFI_FV_FILETYPE_PEIM) && \
+ (!IsPeimDispatched(PeiServices, FfsFile, k)))) n = FfsLength;
+ else {
+ n = sizeof(EFI_FFS_FILE_HEADER);
+ // Copy RAW and FREEFORM FFS file..
+ if ((FfsFile->Type == EFI_FV_FILETYPE_FREEFORM) || \
+ (FfsFile->Type == EFI_FV_FILETYPE_DRIVER) || \
+ (FfsFile->Type == EFI_FV_FILETYPE_RAW)) n = FfsLength;
+ }
+ // Increase PEIM index meeting PEI Core Private Data of PI 1.2
+ if (FfsFile->Type == EFI_FV_FILETYPE_PEIM) k++;
+ (*PeiServices)->CopyMem (p, (UINT8*)FfsFile, n);
+ p = p + FfsLength;
+ } while(!EFI_ERROR(Status));
+}
+#endif // #if (PI_SPECIFICATION_VERSION >= 0x0001000A) && (OPTIMIZE_BOOT_FV_COPY == 1)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CopyFirmwareVolumesToRam
+//
+// Description: This procedure copy in used Firmware Volume to memroy.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// HOB_ROM_IMAGE* - HobRomImage,
+// BOOLEAN - IsEndOfPei
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CopyFirmwareVolumesToRam (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage,
+ IN BOOLEAN IsEndOfPei
+)
+{
+ UINT8 i;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ for (i = 0; i < HobRomImage->NumOfFv; i++) {
+ if ((!IsEndOfPei) && (!HobRomImage->FvInfo[i].IsBootFv)) continue;
+ else if (IsEndOfPei && HobRomImage->FvInfo[i].IsBootFv) continue;
+ HobRomImage->FvInfo[i].FvMemReady = TRUE;
+ if (HobRomImage->HobValid) continue;
+
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A) && (OPTIMIZE_BOOT_FV_COPY == 1)
+ if (HobRomImage->FvInfo[i].IsBootFv == TRUE) {
+ MinimumizeBootFv (PeiServices, HobRomImage, i);
+ }
+ else
+#endif // #if (OPTIMIZE_BOOT_FV_COPY == 1)
+ {
+ (*PeiServices)->CopyMem ((UINT8*)HobRomImage->FvInfo[i].MemAddress, \
+ (UINT8*)HobRomImage->FvInfo[i].FvAddress, \
+ HobRomImage->FvInfo[i].UsedBytes);
+ }
+ if (HobRomImage->FvInfo[i].UsedBytes != HobRomImage->FvInfo[i].FvLength)
+ {
+ UINT32 NumofNullBytes;
+#if SAVE_ENTIRE_FV_IN_MEM == 1
+ // Fill Null Bytes after Used Data
+ NumofNullBytes = HobRomImage->FvInfo[i].FvLength - \
+ HobRomImage->FvInfo[i].UsedBytes;
+#else
+ // Fill Max 512 Null Bytes after Used Data
+ NumofNullBytes = (HobRomImage->FvInfo[i].NumOfPages << 12) - \
+ HobRomImage->FvInfo[i].UsedBytes;
+ if (NumofNullBytes > 512) NumofNullBytes = 512;
+#endif // #if SAVE_ENTIRE_FV_IN_MEM == 1
+ (*PeiServices)->SetMem (
+ (UINT8*)(HobRomImage->FvInfo[i].MemAddress + \
+ HobRomImage->FvInfo[i].UsedBytes), \
+ NumofNullBytes, FLASH_EMPTY_BYTE );
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CollectRomImageInfo
+//
+// Description:
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PHYSICAL_ADDRESS - Buffer
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CollectRomImageInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage
+)
+{
+ ROM_AREA *Area;
+ UINT32 FileSize;
+ UINT8 i = 0, j = 0, n = 0;
+ UINTN k = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_FFS_FILE_HEADER *FfsFile = NULL, *LastFfsFile = NULL;
+ BOOLEAN IsDispatched = FALSE;
+ UINT64 DispatchedPeimBitMap = 0;
+ EFI_GUID *pGuid = NULL, *pLastFileOvrdeGuid = NULL;
+
+ if (RomLayout == NULL) return EFI_UNSUPPORTED;
+#if (PI_SPECIFICATION_VERSION < 0x0001000A)
+ DispatchedPeimBitMap = GetDispatchedPeimBitMap(PeiServices);
+#endif
+
+ // Get Last File Override Guid for skiping unnecessary files copied
+ // for reducing POST time.
+ Status = (*PeiServices)->LocatePpi ( PeiServices, \
+ &gLastFfsFileOverrideGuid, \
+ 0, \
+ NULL, \
+ &pLastFileOvrdeGuid);
+ if (EFI_ERROR(Status)) pLastFileOvrdeGuid = NULL;
+
+ // find last ffs file for calculating used rom space for each Firmware Volume.
+ for (Area = RomLayout; Area->Size != 0; Area++, FfsFile = NULL, FileSize = 0) {
+ if (Area->Type != RomAreaTypeFv) continue;
+ if (!(Area->Attributes & (ROM_AREA_FV_PEI_ACCESS + ROM_AREA_FV_DXE)))
+ continue;
+ // find last ffs file for calculating used rom space.
+ do {
+ IsDispatched = TRUE;
+ Status = (*PeiServices)->FfsFindNextFile (
+ PeiServices, \
+ EFI_FV_FILETYPE_ALL, \
+ (EFI_FIRMWARE_VOLUME_HEADER*)(Area->Address), \
+ &FfsFile );
+ if (!EFI_ERROR(Status)) {
+ // Terminate searching Last File if Last File Override Guid
+ // is defined and is identified.
+ if ((pLastFileOvrdeGuid != NULL) && \
+ (!guidcmp(&FfsFile->Name, pLastFileOvrdeGuid))) {
+ FfsFile = LastFfsFile;
+ Status = EFI_NOT_FOUND;
+ } else LastFfsFile = FfsFile;
+ }
+
+ } while(!EFI_ERROR(Status));
+ FileSize = *(UINT32*)FfsFile->Size & 0xffffff;
+ FileSize += ((UINT32)FfsFile - (UINT32)Area->Address);
+ HobRomImage->FvInfo[i].FvAddress = (UINT32)Area->Address;
+ HobRomImage->FvInfo[i].FvLength = Area->Size;
+ HobRomImage->FvInfo[i].UsedBytes = FileSize;
+ HobRomImage->FvInfo[i].MemAddress = 0;
+ if (IsBootBlockFirmwareVolumes(PeiServices, Area->Address))
+ HobRomImage->FvInfo[i].IsBootFv = TRUE;
+ else HobRomImage->FvInfo[i].IsBootFv = FALSE;
+ HobRomImage->NumOfFv = ++i;
+ }
+ if (HobRomImage->NumOfFv == 0) return EFI_UNSUPPORTED;
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FvHobSwitchToRam
+//
+// Description: This procedure redirect the FV Base Address of FV HOB to RAM.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PHYSICAL_ADDRESS - RomImageBuffer
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FvHobSwitchToRam (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage
+)
+{
+ VOID *p;
+ EFI_HOB_FIRMWARE_VOLUME *FvHob;
+ UINT8 i, j = 0;
+ EFI_BOOT_MODE BootMode;
+ EFI_STATUS Status = EFI_SUCCESS;
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+ PEI_CORE_INSTANCE *PrivateData;
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
+#endif
+
+ // Get current Boot Mode.
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ // Update FV HOB (BaseAddress)
+ for ((*PeiServices)->GetHobList(PeiServices,&p);
+ !(FindNextHobByType(EFI_HOB_TYPE_FV,&p)); ) {
+ FvHob = (EFI_HOB_FIRMWARE_VOLUME*)p;
+ for (i = 0; i < HobRomImage->NumOfFv; i++) {
+ if ((FvHob->BaseAddress == HobRomImage->FvInfo[i].FvAddress) && \
+ (FvHob->Length == HobRomImage->FvInfo[i].FvLength) && \
+ (HobRomImage->FvInfo[i].MemAddress != 0) && \
+ (HobRomImage->FvInfo[i].FvMemReady)) {
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+ for(j = 0; j < PrivateData->AllFvCount; ++j){
+ if((UINT32)FvHob->BaseAddress == (UINT32)PrivateData->AllFv[j]) {
+ PrivateData->AllFv[j] = (EFI_PEI_FV_HANDLE)HobRomImage->FvInfo[i].MemAddress;
+ }
+ }
+#endif // #if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+ FvHob->BaseAddress = HobRomImage->FvInfo[i].MemAddress;
+ break;
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootEndOfPei
+//
+// Description: This procedure redirect the FV Base Address of FV HOB to RAM in
+// End of PEI Phase PPI.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PEI_NOTIFY_DESCRIPTOR* - NotifyDescriptor
+// VOID* - NullPpi
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootEndOfPei (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+)
+{
+ VOID *p;
+ INTN Result;
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ // Update BaseAddress of FV HOB again if new FV is reported.
+ for ((*PeiServices)->GetHobList(PeiServices,&p); \
+ !(FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &p)); ) {
+ Result = guidcmp(&((EFI_HOB_GUID_TYPE*)p)->Name, &gHobRomImageGuid);
+ if (!Result) break;
+ }
+ if (Result) return EFI_UNSUPPORTED;
+
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ if (BootMode != BOOT_ON_S3_RESUME) {
+ CopyFirmwareVolumesToRam(PeiServices, (HOB_ROM_IMAGE*)p, TRUE);
+ }
+ FvHobSwitchToRam (PeiServices, (HOB_ROM_IMAGE*)p);
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootMemoryReady
+//
+// Description: This procedure allocate a Memory buffer and redirect the FV from
+// ROM to RAM in PERMANENT MEMORY INSTALLED PPI;
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PEI_NOTIFY_DESCRIPTOR* - NotifyDescriptor
+// VOID* - NullPpi
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootMemoryReady (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+)
+{
+ EFI_STATUS Status;
+ HOB_ROM_IMAGE *HobRomImage = NULL;
+ EFI_BOOT_MODE BootMode;
+
+ // Get current Boot Mode.
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ // Check Boot mode again, do nothing if recovery mode.
+ if ((BootMode == BOOT_IN_RECOVERY_MODE) || \
+ (BootMode == BOOT_ON_FLASH_UPDATE)) return EFI_SUCCESS;
+
+ Status = (*PeiServices)->CreateHob ( PeiServices, \
+ EFI_HOB_TYPE_GUID_EXTENSION, \
+ sizeof(HOB_ROM_IMAGE), \
+ &HobRomImage );
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ HobRomImage->EfiHobGuidType.Name = gHobRomImageGuid;
+
+
+ HobRomImage->HobValid = FALSE;
+
+ HobRomImage->NumOfFv = 0;
+ Status = CollectRomImageInfo (PeiServices, HobRomImage);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ Status = PrepareForCopyRomToRam (PeiServices, HobRomImage);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ Status = CopyFirmwareVolumesToRam (PeiServices, HobRomImage, FALSE);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ SwitchPeiServiceDataToRam (PeiServices, HobRomImage);
+ FvHobSwitchToRam (PeiServices, HobRomImage);
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootEntry
+//
+// Description: PEI Entry Point for PeiRamBoot Driver.
+//
+// Input: EFI_FFS_FILE_HEADER* - FfsHeader
+// EFI_PEI_SERVICES** - PeiServices
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR(Status)) return Status;
+ if ((BootMode == BOOT_IN_RECOVERY_MODE) || \
+ (BootMode == BOOT_ON_FLASH_UPDATE) || \
+ (BootMode == BOOT_ON_S3_RESUME)) return EFI_SUCCESS;
+
+ Status = (*PeiServices)->NotifyPpi ( PeiServices, \
+ PeiRamBootMemoryReadyNotify );
+ Status = (*PeiServices)->NotifyPpi ( PeiServices, \
+ PeiRamBootEndOfPeiNotify );
+
+ return EFI_SUCCESS;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.chm b/Core/EM/PeiRamBoot/PeiRamBoot.chm
new file mode 100644
index 0000000..d8af8be
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.chm
Binary files differ
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.cif b/Core/EM/PeiRamBoot/PeiRamBoot.cif
new file mode 100644
index 0000000..0277b05
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "PEI Ram Boot"
+ category = eModule
+ LocalRoot = "Core\EM\PeiRamBoot"
+ RefName = "PEI_RAM_BOOT"
+[files]
+"PeiRamBoot.sdl"
+"PeiRamBoot.mak"
+"PeiRamBoot.dxs"
+"PeiRamBoot.h"
+"PeiRamBoot.c"
+"PeiRamBootHook.c"
+"PeiRamBootDxe.c"
+"PeiRamBootOfbd.c"
+"PeiRamBootFvHook.c"
+"PeiRamBootCacheRdy.c"
+"PeiRamBootCacheRdy.dxs"
+"PeiRamBoot.chm"
+<endComponent>
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.dxs b/Core/EM/PeiRamBoot/PeiRamBoot.dxs
new file mode 100644
index 0000000..69c45e6
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.dxs
@@ -0,0 +1,66 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.dxs 2 7/18/12 3:39a Calvinchen $
+//
+// $Revision: 2 $
+//
+// $Date: 7/18/12 3:39a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.dxs $
+//
+// 2 7/18/12 3:39a Calvinchen
+// Added changes for AMD AGESA V5.
+//
+// 1 10/27/10 2:48a Calvinchen
+// Initial Check-in.
+//
+//
+//**********************************************************************
+#include <pei.h>
+#include <token.h>
+#include "ppi\CpuIo.h"
+#include "ppi\PciCfg.h"
+#include "ppi\ReadOnlyVariable.h"
+#include "ppi\Stall.h"
+#ifdef AMDV5_SUPPORT
+#define AGESA_MEM_PPI_GUID \
+{ 0x8ba51c1c, 0x4b30, 0x47df, 0xa4, 0x4e, 0x22, 0x53, 0xe1, 0xa5, 0xd4, 0x2 }
+#endif
+
+DEPENDENCY_START
+#ifdef AMDV5_SUPPORT
+ AGESA_MEM_PPI_GUID AND
+#endif
+ EFI_PEI_CPU_IO_PPI_INSTALLED_GUID AND
+ EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID AND
+ EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID AND
+ EFI_PEI_STALL_PPI_GUID
+DEPENDENCY_END
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.h b/Core/EM/PeiRamBoot/PeiRamBoot.h
new file mode 100644
index 0000000..58473e2
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.h
@@ -0,0 +1,162 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.h 7 8/08/12 4:25a Calvinchen $
+//
+// $Revision: 7 $
+//
+// $Date: 8/08/12 4:25a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.h $
+//
+// 7 8/08/12 4:25a Calvinchen
+// 1. Changed for ReportFv2.c by Artem's suggestion.
+// 2. Fixed System hangs if Memory Mapping Changed with warm boot.
+//
+// 6 7/18/12 3:41a Calvinchen
+//
+// 5 2/23/12 6:35a Calvinchen
+// [TAG] EIP82264
+// [Category] Improvement
+// [Description] Need to do cold boot to get the correct data in rom
+// hole when changing data in rom hole.
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.h
+// PeiRamBoot.c
+// PeiRamBootDxe.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 4 4/22/11 1:27a Calvinchen
+//
+// 3 12/29/10 5:35a Calvinchen
+// Bug Fixed : DMI structure not update in system memory if
+// PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot support.
+//
+// 2 12/14/10 2:25a Calvinchen
+// Improvement :
+// 1. Added an eLink "PeiRamBootList" for fast warm boot support
+// (PEI_RAM_BOOT_S3_SUPPORT = 1). If system boots in warm boot state, BIOS
+// directly boot to previous copied ROM image in RAM to save time of
+// copying ROM.
+// 2. Added "PEI_RAM_BOOT_S3_SUPPORT" = "2" for saving runtime memory, it
+// only keep necessary PEIM FFS in runtime memory for S3 resume
+// improvement.
+//
+// 1 10/27/10 2:48a Calvinchen
+// Initial Check-in.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBoot.h
+//
+// Description: Definition file for PEI Ram Boot.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef PI_SPECIFICATION_VERSION
+#define PI_SPECIFICATION_VERSION 91
+#endif
+
+#define FLASH_DEVICE_BASE (0xFFFFFFFF - FLASH_SIZE + 1)
+
+#define ROM_IMAGE_MEMORY_HOB_GUID \
+{ 0xee2f45d2, 0x5ba4, 0x441e, 0x8a, 0x1d, 0xaa, 0x22, 0xdf, 0xa3, 0xb6, 0xc5 }
+
+#define ROM_IMAGE_ADDRESS_GUID \
+{ 0xDDE1BC72, 0xD45E, 0x4209, 0xAB, 0x85, 0x14, 0x46, 0x2D, 0x2F, 0x50, 0x74 }
+
+#define SMBIOS_FLASH_DATA_FFS_GUID \
+{ 0xFD44820B, 0xF1AB, 0x41C0, 0xAE, 0x4E, 0x0C, 0x55, 0x55, 0x6E, 0xB9, 0xBD }
+
+#define ROM_CACHE_ENABLE_PPI_GUID \
+{ 0x36E835BB, 0x661D, 0x4D37, 0x8D, 0xE5, 0x88, 0x53, 0x25, 0xDA, 0xE9, 0x10 }
+
+#define FLASH_EMPTY_BYTE (UINT8)(-FLASH_ERASE_POLARITY)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: HOB_ROM_IMAGE
+//
+// Description: This structure contains information for ROM Image HOB.
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT32 FvAddress;
+ UINT32 FvLength;
+ UINT32 UsedBytes;
+ UINT32 MemAddress;
+ UINT16 NumOfPages;
+ UINT8 FvMemReady;
+ UINT8 IsBootFv;
+} FV_INFO;
+
+typedef struct {
+#if PEI_RAM_BOOT_S3_SUPPORT == 2
+ UINT32 PeimAddress;
+ UINT32 PeimLength;
+#else
+ UINT32 FfsAddress;
+ UINT8 FfsLength[3];
+ UINT8 FvIndex;
+#endif
+} PEIM_FFS_INFO;
+
+typedef struct {
+ UINT32 FvAddress;
+ UINT32 FvLength;
+ UINT32 MemAddress;
+} NESTED_FV_INFO;
+
+typedef struct {
+ EFI_HOB_GUID_TYPE EfiHobGuidType;
+ BOOLEAN HobValid;
+ UINT32 SmbiosFlashData;
+ EFI_PHYSICAL_ADDRESS StolenHobMemory;
+ UINT8 NumOfFv;
+ FV_INFO FvInfo[8];
+ UINT8 NumOfPeim;
+#if PEI_RAM_BOOT_S3_SUPPORT == 2
+ PEIM_FFS_INFO PeimFfsInfo[16];
+#else
+ PEIM_FFS_INFO RsvdFfsInfo[16];
+#endif
+ UINT8 NestedFvValid;
+ UINT8 NumOfNestedFv;
+ NESTED_FV_INFO NestedFvInfo[4];
+} HOB_ROM_IMAGE;
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.mak b/Core/EM/PeiRamBoot/PeiRamBoot.mak
new file mode 100644
index 0000000..a0fee27
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.mak
@@ -0,0 +1,242 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.mak 13 10/02/14 4:44a Calvinchen $
+#
+# $Revision: 13 $
+#
+# $Date: 10/02/14 4:44a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.mak $
+#
+# 13 10/02/14 4:44a Calvinchen
+# [TAG] EIP184075
+# [Category] Improvement
+# [Description] [HWR]FtRecovery support for Intel Top Swap
+# Modified PeiRamBoot module for multiple Boot Block Volumes support.
+# [Files] PeiRamBoot.sdl
+# PeiRamBoot.mak
+# PeiRamBoot.c
+# PeiRamBoot.chm
+# PeiRamBoot.cif
+#
+# 12 3/18/13 6:08a Calvinchen
+# Bug Fixed : Build failed if Core 4.6.5.5.
+#
+# 11 7/18/12 3:41a Calvinchen
+#
+# 10 2/23/12 6:35a Calvinchen
+# [TAG] EIP82264
+# [Category] Improvement
+# [Description] Need to do cold boot to get the correct data in rom
+# hole when changing data in rom hole.
+# [Files] PeiRamBoot.sdl
+# PeiRamBoot.mak
+# PeiRamBoot.h
+# PeiRamBoot.c
+# PeiRamBootDxe.c
+# PeiRamBoot.chm
+# PeiRamBoot.cif
+#
+# 9 6/21/11 2:22a Calvinchen
+# ¡P Bug Fixed:
+# Bug Fixed:
+# 1. Build failed if Core 4.6.4.0.
+# 2. System could hang if SAVE_ENTIRE_FV_TO_MEM = 1with AMD platform.
+#
+# 8 4/22/11 1:27a Calvinchen
+#
+# 7 2/11/11 3:16a Calvinchen
+# Bug Fixed : System hangs after reflashed BIOS with warm reset if
+# PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot support.
+#
+# 6 12/21/10 2:24a Calvinchen
+# Added an eLink "PeiRamBootObjectsList" for oem links their obj files
+# for fast warm boot support.
+#
+# 5 12/14/10 2:25a Calvinchen
+# Improvement :
+# 1. Added an eLink "PeiRamBootList" for fast warm boot support
+# (PEI_RAM_BOOT_S3_SUPPORT = 1). If system boots in warm boot state, BIOS
+# directly boot to previous copied ROM image in RAM to save time of
+# copying ROM.
+# 2. Added "PEI_RAM_BOOT_S3_SUPPORT" = "2" for saving runtime memory, it
+# only keep necessary PEIM FFS in runtime memory for S3 resume
+# improvement.
+#
+# 4 12/02/10 6:18a Calvinchen
+# Bug Fixed : Fixed Update SMBIOS Structures failed with DMI Utility.
+#
+# 3 10/27/10 3:03a Calvinchen
+# Initail check-in.
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PeiRamBoot.mak
+#
+# Description: Make file for PEI Ram Boot.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IFNDEF PI_SPECIFICATION_VERSION
+PI_SPECIFICATION_VERSION = 0
+!ENDIF
+
+all : PeiRamBoot PeiRamBootCacheRdy
+
+#---------------------------------------------------------------------------
+# Create PEI RAM BOOT dependencies
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\PeiRamBoot.mak : $(PeiRamBoot_DIR)\$(@B).cif $(PeiRamBoot_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(PeiRamBoot_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+#---------------------------------------------------------------------------
+# Create PeiRamBoot PEI Component
+#---------------------------------------------------------------------------
+PeiRamBoot: $(BUILD_DIR)\$(PeiRamBoot_DIR)\RomLayout.obj $(BUILD_DIR)\PeiRamBoot.mak PeiRamBootBin
+
+PEI_RAM_BOOT_INCLUDES =\
+/I$(PeiRamBoot_DIR)\
+/I$(CORE_PEI_DIR)\
+!IF $(PI_SPECIFICATION_VERSION) >= 65546
+/I$(CORE_PEI_DIR)\CORE_PEI_PI\
+!ELSE
+/I$(CORE_PEI_DIR)\CORE_PEI_FRAMEWORK\
+!ENDIF
+/I$(CORE_DXE_DIR)\
+/I$(CORE_DIR)
+
+PeiRamBootObjects =\
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\RomLayout.obj\
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBoot.obj\
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootHook.obj\
+$(PeiRamBootObjectsList)
+
+PEI_RAM_BOOT_LISTS = \
+/D\"PEI_RAM_BOOT_LIST=$(PeiRamBootList)\"\
+/D\"PEI_RAM_BOOT_FV_BOOTBLOCK_LIST=$(PeiRamBootFvBootBlockList)\"\
+/D\"PEI_RAM_BOOT_FFS_GUID_LIST=$(PeiRamBootFfsGuidList)\"
+
+PeiRamBootBin : $(AMIPEILIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiRamBoot.mak all\
+ NAME=PeiRamBoot\
+ MAKEFILE=$(BUILD_DIR)\PeiRamBoot.mak \
+ "CFLAGS=$(CFLAGS) $(PEI_RAM_BOOT_LISTS)"\
+ GUID=08efd15d-ec55-4023-b648-7ba40df7d05d \
+ OBJECTS="$(PeiRamBootObjects)" \
+ ENTRY_POINT=PeiRamBootEntry \
+ TYPE=PEIM \
+ "MY_INCLUDES=$(PEI_RAM_BOOT_INCLUDES)" \
+ "MY_DEFINES=$(PEI_CORE_DEFINES)"\
+ DEPEX1=$(PeiRamBoot_DIR)\PeiRamBoot.DXS \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=0
+
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\RomLayout.obj : $(BUILD_DIR)\RomLayout.c
+ $(CC) /Fo$@ $(CFLAGS) $(BUILD_DIR)\RomLayout.c
+#---------------------------------------------------------------------------
+# Create PeiRamBoot DXE Component
+#---------------------------------------------------------------------------
+Runtime_LIBBin : $(BUILD_DIR)\PeiRamBootDxe.lib
+
+$(BUILD_DIR)\PeiRamBootDxe.lib : PeiRamBootDxe
+
+PeiRamBootDxe: $(BUILD_DIR)\PeiRamBoot.mak PeiRamBootDxeBin
+
+PeiRamBootDxeObjs =\
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootDxe.obj
+
+PeiRamBootDxeBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiRamBoot.mak all\
+ NAME=PeiRamBoot\
+ "CFLAGS=$(CFLAGS) /I$(PeiRamBoot_DIR)"\
+ OBJECTS="$(PeiRamBootDxeObjs)" \
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(BUILD_DIR)\PeiRamBootDxe.lib
+
+#---------------------------------------------------------------------------
+# Create PEIRamBoot OFBD Lib Component
+#---------------------------------------------------------------------------
+!IF "$(PEI_RAM_BOOT_S3_SUPPORT)"=="1"
+PeiRamBootOfbd : $(BUILD_DIR)\PeiRamBoot.mak PeiRamBootOfbdBin
+
+PeiRamBootOfbdObjs = $(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootOfbd.obj
+
+PeiRamBootOfbdBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiRamBoot.mak all\
+ "CFLAGS=$(CFLAGS:/W4=/W3) /I$(OFBD_DIR)" \
+ OBJECTS="$(PeiRamBootOfbdObjs)" \
+ NAME=PeiRamBoot \
+ TYPE=LIBRARY LIBRARY_NAME=$(PEIRAMBOOT_OFBD_LIB)
+
+$(PEIRAMBOOT_OFBD_LIB) : PeiRamBootOfbd
+!ENDIF
+#---------------------------------------------------------------------------
+# Create PeiRamBoot PEI Component
+#---------------------------------------------------------------------------
+!IF "$(SAVE_ENTIRE_FV_IN_MEM)"=="1"
+PeiRamBootCacheRdy: $(BUILD_DIR)\PeiRamBoot.mak PeiRamBootCacheRdyBin
+
+PeiRamBootCacheRdyObjects =\
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootCacheRdy.obj
+
+PeiRamBootCacheRdyBin : $(AMIPEILIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\PeiRamBoot.mak all\
+ NAME=PeiRamBootCacheRdy\
+ MAKEFILE=$(BUILD_DIR)\PeiRamBoot.mak \
+ "CFLAGS=$(CFLAGS) /I$(PeiRamBoot_DIR)"\
+ GUID=a6a3a962-c591-4701-9d25-73d0226d89dc\
+ OBJECTS="$(PeiRamBootCacheRdyObjects)" \
+ ENTRY_POINT=PeiRamBootCacheRdyEntry \
+ TYPE=PEIM \
+ DEPEX1=$(PeiRamBoot_DIR)\PeiRamBootCacheRdy.DXS \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ COMPRESS=1
+!ELSE
+PeiRamBootCacheRdy:
+!ENDIF
+#---------------------------------------------------------------------------
+!IF "$(PRESERVE_NESTED_FV_IN_MEM)"=="1"
+$(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootFvHook.obj : $(PeiRamBoot_DIR)\PeiRamBootFvHook.c
+!IF !EXIST($(BUILD_DIR)\$(PeiRamBoot_DIR))
+ mkdir $(BUILD_DIR)\$(PeiRamBoot_DIR)
+!ENDIF
+ $(CC) /Fo$@ $(CFLAGS) /I$(PeiRamBoot_DIR) $(PeiRamBoot_DIR)\PeiRamBootFvHook.c
+
+CORE_PEIBin : $(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootFvHook.obj
+RecoveryBin : $(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootFvHook.obj
+FwCapsuleRecoveryPPIBin : $(BUILD_DIR)\$(PeiRamBoot_DIR)\PeiRamBootFvHook.obj
+!ENDIF
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBoot.sdl b/Core/EM/PeiRamBoot/PeiRamBoot.sdl
new file mode 100644
index 0000000..1854e8f
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBoot.sdl
@@ -0,0 +1,196 @@
+#****************************************************************************
+#****************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30071 **
+#** **
+#** Phone (770)-246-8600 **
+#** **
+#****************************************************************************
+#****************************************************************************
+#****************************************************************************
+# $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.sdl 16 8/28/15 3:54a Tristinchou $
+#
+# $Revision: 16 $
+#
+# $Date: 8/28/15 3:54a $
+#
+#****************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBoot.sdl $
+#
+# 16 8/28/15 3:54a Tristinchou
+# [TAG] EIP235157
+# [Category] Improvement
+# [Description] Security vulnerability - PeiRamBoot: Should leave cold
+# boot optimization only
+#
+# 15 10/02/14 4:44a Calvinchen
+# [TAG] EIP184075
+# [Category] Improvement
+# [Description] [HWR]FtRecovery support for Intel Top Swap
+# Modified PeiRamBoot module for multiple Boot Block Volumes support.
+# [Files] PeiRamBoot.sdl
+# PeiRamBoot.mak
+# PeiRamBoot.c
+# PeiRamBoot.chm
+# PeiRamBoot.cif
+#
+# 14 6/18/14 11:57p Calvinchen
+# Bug Fixed: System hangs with using AFU.
+#
+# 13 1/16/13 6:31a Calvinchen
+# [TAG] EIPNone
+# [Category] Improvement
+# [Description] 1. Added support to minimumize Boot FV copy for
+# improving POST time.
+# 2. Added Last Firmware Volume FFS file Override mechanism.
+# [Files] PeiRamBoot.sdl
+# PeiRamBoot.c
+# PeiRamBoot.chm
+# PeiRamBoot.cif
+#
+# 12 7/18/12 5:25a Calvinchen
+# Missing "PeiRamBootNestedFvPublishing" eLink in sdl file.
+#
+# 11 7/18/12 4:18a Calvinchen
+# PRESERVE_NESTED_FV_IN_MEM = 0 (Default)
+#
+# 10 7/18/12 3:41a Calvinchen
+#
+# 9 2/23/12 6:34a Calvinchen
+# [TAG] EIP82264
+# [Category] Improvement
+# [Description] Need to do cold boot to get the correct data in rom
+# hole when changing data in rom hole.
+# [Files] PeiRamBoot.sdl
+# PeiRamBoot.mak
+# PeiRamBoot.h
+# PeiRamBoot.c
+# PeiRamBootDxe.c
+# PeiRamBoot.chm
+# PeiRamBoot.cif
+#
+# 8 6/21/11 2:22a Calvinchen
+# ¡P Bug Fixed:
+# Bug Fixed:
+# 1. Build failed if Core 4.6.4.0.
+# 2. System could hang if SAVE_ENTIRE_FV_TO_MEM = 1with AMD platform.
+#
+# 7 5/27/11 7:16a Calvinchen
+# Added "WARM_BOOT_VERIFY_CHECKSUM" for verifying FV/FFS checksum if
+# Warmboot support.
+#
+# 6 4/22/11 1:22a Calvinchen
+#
+# 5 2/11/11 3:16a Calvinchen
+# Bug Fixed : System hangs after reflashed BIOS with warm reset if
+# PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot support.
+#
+# 4 12/21/10 2:24a Calvinchen
+# Added an eLink "PeiRamBootObjectsList" for oem links their obj files
+# for fast warm boot support.
+#
+# 3 12/14/10 2:25a Calvinchen
+# Improvement :
+# 1. Added an eLink "PeiRamBootList" for fast warm boot support
+# (PEI_RAM_BOOT_S3_SUPPORT = 1). If system boots in warm boot state, BIOS
+# directly boot to previous copied ROM image in RAM to save time of
+# copying ROM.
+# 2. Added "PEI_RAM_BOOT_S3_SUPPORT" = "2" for saving runtime memory, it
+# only keep necessary PEIM FFS in runtime memory for S3 resume
+# improvement.
+#
+# 2 12/02/10 6:18a Calvinchen
+# Bug Fixed : Fixed Update SMBIOS Structures failed with DMI Utility.
+#
+# 1 10/27/10 2:48a Calvinchen
+# Initial Check-in.
+#
+#
+#****************************************************************************
+TOKEN
+ Name = "PeiRamBootSupport"
+ Value = "1"
+ Help = "Main switch to enable PEI RAM Boot support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+
+TOKEN
+ Name = "SAVE_ENTIRE_FV_IN_MEM"
+ Value = "0"
+ Help = "Switch to enable to copy Entire Firmware Volume to Ram."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OPTIMIZE_BOOT_FV_COPY"
+ Value = "0"
+ Help = "Switch to enable to optimize(Minimumize) Boot FV copy."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+
+PATH
+ Name = "PeiRamBoot_DIR"
+End
+
+MODULE
+ Help = "Includes PeiRamBoot.mak to Project"
+ File = "PeiRamBoot.mak"
+End
+
+ELINK
+ Name = "PeiRamBootDxeEntry,"
+ Parent = "RuntimeSmmInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiRamBoot.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\PeiRamBootCacheRdy.ffs"
+ Parent = "$(BUILD_DIR)\CPUPEI.ffs"
+ Token = "SAVE_ENTIRE_FV_IN_MEM" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+
+
+ELINK
+ Name = "PeiRamBootList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiRamBootFvBootBlockList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiRamBootFfsGuidList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PeiRamBootObjectsList"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/PeiRamBoot/PeiRamBootCacheRdy.c b/Core/EM/PeiRamBoot/PeiRamBootCacheRdy.c
new file mode 100644
index 0000000..1f7c5bf
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBootCacheRdy.c
@@ -0,0 +1,114 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootCacheRdy.c 2 8/28/15 3:53a Tristinchou $
+//
+// $Revision: 2 $
+//
+// $Date: 8/28/15 3:53a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootCacheRdy.c $
+//
+// 2 8/28/15 3:53a Tristinchou
+// [TAG] EIP235157
+// [Category] Improvement
+// [Description] Security vulnerability - PeiRamBoot: Should leave cold
+// boot optimization only
+//
+// 1 4/22/11 1:39a Calvinchen
+// Added Token "SAVE_ENTIRE_FV_TO_MEM" for OEM measure FV if needed.
+//
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBootCacheRdy.c
+//
+// Description: PEI RAM BOOT Pei driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <AmiCspLib.h>
+#include <PeiRamBoot.h>
+//----------------------------------------------------------------------------
+// Function Externs
+//----------------------------------------------------------------------------
+// Local prototypes
+EFI_GUID gRomCacheEnablePpiGuid = ROM_CACHE_ENABLE_PPI_GUID;
+
+// PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR RomCacheEnablePpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gRomCacheEnablePpiGuid, NULL
+ }
+};
+//----------------------------------------------------------------------------
+// Local Variables
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootCacheRdyEntry
+//
+// Description: PEI Entry Point for PeiRamBootCacheRdy Driver.
+//
+// Input: EFI_FFS_FILE_HEADER* - FfsHeader
+// EFI_PEI_SERVICES** - PeiServices
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootCacheRdyEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR(Status)) return Status;
+ if ((BootMode == BOOT_ON_FLASH_UPDATE) || (BootMode == BOOT_ON_S3_RESUME) || \
+ (BootMode == BOOT_IN_RECOVERY_MODE)) return Status;
+ Status = (*PeiServices)->InstallPpi (PeiServices, RomCacheEnablePpiList);
+ return Status;
+
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBootCacheRdy.dxs b/Core/EM/PeiRamBoot/PeiRamBootCacheRdy.dxs
new file mode 100644
index 0000000..812d727
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBootCacheRdy.dxs
@@ -0,0 +1,57 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootCacheRdy.dxs 1 4/22/11 1:39a Calvinchen $
+//
+// $Revision: 1 $
+//
+// $Date: 4/22/11 1:39a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootCacheRdy.dxs $
+//
+// 1 4/22/11 1:39a Calvinchen
+// Added Token "SAVE_ENTIRE_FV_TO_MEM" for OEM measure FV if needed.
+//
+//
+//
+//**********************************************************************
+#include <pei.h>
+#include "ppi\CpuIo.h"
+#include "ppi\PciCfg.h"
+#include "ppi\ReadOnlyVariable.h"
+#include "ppi\Stall.h"
+
+DEPENDENCY_START
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI AND
+ EFI_PEI_CPU_IO_PPI_INSTALLED_GUID AND
+ EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID AND
+ EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID AND
+ EFI_PEI_STALL_PPI_GUID
+DEPENDENCY_END
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/PeiRamBoot/PeiRamBootDxe.c b/Core/EM/PeiRamBoot/PeiRamBootDxe.c
new file mode 100644
index 0000000..57c9ac9
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBootDxe.c
@@ -0,0 +1,368 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootDxe.c 12 8/28/15 3:52a Tristinchou $
+//
+// $Revision: 12 $
+//
+// $Date: 8/28/15 3:52a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootDxe.c $
+//
+// 12 8/28/15 3:52a Tristinchou
+// [TAG] EIP235157
+// [Category] Improvement
+// [Description] Security vulnerability - PeiRamBoot: Should leave cold
+// boot optimization only
+//
+// 11 5/05/14 5:03a Calvinchen
+// [TAG] EIP166551
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Runtime attribute set for the some of the variable used
+// by PEI Ram Boot driver and needs to be reviewed
+// [Files] PeiRamBootDxe.c
+// PeiRamBootOfbd.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 10 1/16/13 4:54a Calvinchen
+// [TAG] EIP108319
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] When we enable PEI RAM BOOT module and set the token
+// ¡§PEI_RAM_S3_SUPPOT¡¨ to 0, smbios will not be writable, system will
+// hang up when writing smbios under DOS using DMI tool.
+// [RootCause] Don't Restore the Base Address of Firmware Volume Block
+// Protocol from RAM to ROM.
+// [Solution] Restore the Base Address of Firmware Volume Block Protocol
+// from RAM to ROM.
+// [Files] PeiRamBootDxe.c
+//
+// 9 8/08/12 4:53a Calvinchen
+// 1. Changed for ReportFv2.c by Artem's suggestion.
+// 2. Fixed System hangs if Memory Mapping Changed with warm boot.
+//
+// 8 5/04/12 5:03a Calvinchen
+// [TAG] EIP88796
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] (JP0005-Q208)When define more than two FV which has the
+// same CUSTOM_SIZE, GetPhysicalAddress() returns invalid value.
+// [RootCause] Coding mistake.
+// [Solution] (JP0005-Q208)When define more than two FV which has the
+// same CUSTOM_SIZE, GetPhysicalAddress() returns invalid value.
+// [Files] PeiRamBootDxe.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 7 2/23/12 6:35a Calvinchen
+// [TAG] EIP82264
+// [Category] Improvement
+// [Description] Need to do cold boot to get the correct data in rom
+// hole when changing data in rom hole.
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.h
+// PeiRamBoot.c
+// PeiRamBootDxe.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 6 5/27/11 7:22a Calvinchen
+// Delete HobRomImage Variable if Recovery mode.
+//
+// 5 4/22/11 1:28a Calvinchen
+//
+// 4 3/22/11 7:52a Calvinchen
+// [TAG] EIP56322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs after changing TPM settings in SETUP.
+// [RootCause] System Memory Mappings are changed with warm boot.
+// [Solution] BIOS always go cold boot path if system memory mappings
+// are changed
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.dxs
+// PeiRamBoot.h
+// PeiRamBoot.c
+// PeiRamBootHook.c
+// PeiRamBootDxe.c
+// PeiRamBootOfbd.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 3 12/14/10 2:25a Calvinchen
+// Improvement :
+// 1. Added an eLink "PeiRamBootList" for fast warm boot support
+// (PEI_RAM_BOOT_S3_SUPPORT = 1). If system boots in warm boot state, BIOS
+// directly boot to previous copied ROM image in RAM to save time of
+// copying ROM.
+// 2. Added "PEI_RAM_BOOT_S3_SUPPORT" = "2" for saving runtime memory, it
+// only keep necessary PEIM FFS in runtime memory for S3 resume
+// improvement.
+//
+// 2 12/02/10 6:18a Calvinchen
+// Bug Fixed : Fixed Update SMBIOS Structures failed with DMI Utility.
+//
+// 1 10/27/10 2:48a Calvinchen
+// Initial Check-in.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBootDxe.c
+//
+// Description: PEI RAM BOOT DXE driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <PeiRamBoot.h>
+#include <Protocol\FirmwareVolumeBlock.h>
+
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+typedef struct {
+ UINTN Base;
+ UINTN Length;
+} LBA_CACHE;
+
+typedef struct {
+ MEMMAP_DEVICE_PATH MemMapDevPath;
+ EFI_DEVICE_PATH_PROTOCOL EndDevPath;
+} FV_DEVICE_PATH;
+
+
+typedef struct {
+ UINTN Signature;
+ EFI_HANDLE Handle;
+ FV_DEVICE_PATH DevicePath;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL FwVolBlockInstance;
+ UINTN NumBlocks;
+ LBA_CACHE *LbaCache;
+ UINT32 FvbAttributes;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+} EFI_FW_VOL_BLOCK_DEVICE;
+
+#define FVB_DEVICE_SIGNATURE EFI_SIGNATURE_32('_','F','V','B')
+
+#ifndef _CR
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+#endif
+#ifndef CR
+#define CR(Record, TYPE, Field, Signature) _CR (Record, TYPE, Field)
+#endif
+#ifndef EFI_FVB_MEMORY_MAPPED
+#define EFI_FVB_MEMORY_MAPPED EFI_FVB2_MEMORY_MAPPED
+#endif
+
+#define FVB_DEVICE_FROM_THIS(a) \
+ CR(a, EFI_FW_VOL_BLOCK_DEVICE, FwVolBlockInstance, FVB_DEVICE_SIGNATURE)
+
+EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = FW_VOLUME_BLOCK_PROTOCOL_GUID;
+
+//----------------------------------------------------------------------------
+// Local Variables
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: DeleteHobRomImageVariable
+//
+// Description: Delete HobRomImage Variable event.
+//
+// Input: None.
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DeleteHobRomImageVariable (
+ IN EFI_EVENT Event,
+ IN VOID *ParentImageHandle
+)
+{
+ EFI_GUID RomImageAddressGuid = ROM_IMAGE_ADDRESS_GUID;
+
+ pRS->SetVariable ( L"HobRomImage",
+ &RomImageAddressGuid, \
+ EFI_VARIABLE_NON_VOLATILE | \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS, \
+ 0, \
+ ParentImageHandle );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootDxeInit
+//
+// Description: DXE Entry Point for PeiRamBoot Driver.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootDxeInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_GUID GuidHob = HOB_LIST_GUID;
+ EFI_STATUS Status;
+ EFI_GUID RomImageHobGuid = ROM_IMAGE_MEMORY_HOB_GUID;
+ EFI_GUID RomImageAddressGuid = ROM_IMAGE_ADDRESS_GUID;
+ UINTN VarSize = 0, NumHandles;
+ UINT8 i, j;
+ EFI_PHYSICAL_ADDRESS HobRomImageAddress = 0;
+ VOID *p = NULL;
+ EFI_HOB_FIRMWARE_VOLUME *FvHob = NULL;
+ HOB_ROM_IMAGE *HobRomImage;
+ EFI_HANDLE *HandleBuffer;
+ EFI_FW_VOL_BLOCK_DEVICE *FvbDevice;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock;
+ EFI_EVENT EvtSetupChange = NULL;
+ VOID *RgnSetupChange = NULL;
+ EFI_GUID AmitseSetupNvramUpdateGuid = \
+ {0xd84beff0, 0x159a, 0x4b60, 0x9a, 0xb9, 0xac, 0x5c, 0x47, 0x4b, 0xd3, 0xb1};
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // Get RamBoot Informatoin from HOB.
+ HobRomImage = (HOB_ROM_IMAGE*)GetEfiConfigurationTable (pST, &GuidHob);
+ Status = FindNextHobByGuid (&RomImageHobGuid, (VOID**)&HobRomImage);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ // Redirect the FV address to RAM and Free memory.
+ for (p = GetEfiConfigurationTable (pST, &GuidHob);
+ !(FindNextHobByType(EFI_HOB_TYPE_FV,&p)); ) {
+ FvHob = (EFI_HOB_FIRMWARE_VOLUME*)p;
+ for (i = 0; i < HobRomImage->NumOfFv; i++) {
+ if ((FvHob->BaseAddress == HobRomImage->FvInfo[i].MemAddress) && \
+ (FvHob->Length == HobRomImage->FvInfo[i].FvLength)) {
+ FvHob->BaseAddress = HobRomImage->FvInfo[i].FvAddress;
+ pBS->FreePages (HobRomImage->FvInfo[i].MemAddress, \
+ HobRomImage->FvInfo[i].NumOfPages);
+ break;
+ }
+ }
+ }
+
+ // Restore the Base Address of Firmware Volume Block Protocol from RAM
+ // to ROM.
+ Status = pBS->LocateHandleBuffer ( ByProtocol, \
+ &gEfiFirmwareVolumeBlockProtocolGuid, \
+ NULL, \
+ &NumHandles, \
+ &HandleBuffer );
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NumHandles; ++i) {
+ Status = pBS->HandleProtocol ( HandleBuffer[i], \
+ &gEfiFirmwareVolumeBlockProtocolGuid, \
+ &FvBlock );
+ if (EFI_ERROR(Status)) continue;
+ FvbDevice = FVB_DEVICE_FROM_THIS (FvBlock);
+ if (!(FvbDevice->FvbAttributes & EFI_FVB_MEMORY_MAPPED)) continue;
+//-TRACE((-1, "FvBaseAddress[%02X] = %08X\n", i, FvbDevice->BaseAddress));
+ for (j = 0; j < HobRomImage->NumOfFv; j++) {
+ if ((FvbDevice->BaseAddress == HobRomImage->FvInfo[j].MemAddress) && \
+ (FvbDevice->NumBlocks == \
+ (HobRomImage->FvInfo[j].FvLength / FLASH_BLOCK_SIZE))) {
+ FvbDevice->BaseAddress = HobRomImage->FvInfo[j].FvAddress;
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootSmmInit
+//
+// Description: PeiRamBoot InSmm Function.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootDxeSmmInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootDxeEntry
+//
+// Description: DXE Entry Point for PeiRamBoot Driver.
+//
+// Input: EFI_HANDLE - ImageHandle
+// EFI_SYSTEM_TABLE* - SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle,SystemTable);
+ return InitSmmHandlerEx(ImageHandle, \
+ SystemTable, PeiRamBootDxeSmmInit, PeiRamBootDxeInit);
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBootFvHook.c b/Core/EM/PeiRamBoot/PeiRamBootFvHook.c
new file mode 100644
index 0000000..bab5415
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBootFvHook.c
@@ -0,0 +1,184 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootFvHook.c 4 1/16/13 6:33a Calvinchen $
+//
+// $Revision: 4 $
+//
+// $Date: 1/16/13 6:33a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootFvHook.c $
+//
+// 4 1/16/13 6:33a Calvinchen
+// Update Header.
+//
+// 3 8/08/12 4:25a Calvinchen
+// 1. Changed for ReportFv2.c by Artem's suggestion.
+// 2. Fixed System hangs if Memory Mapping Changed with warm boot.
+//
+// 2 7/18/12 3:41a Calvinchen
+//
+// 1 7/18/12 3:33a Calvinchen
+// [TAG] EIPNone
+// [Category] New Feature
+// [Description] Added support for Nested Firmware Volume.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBootFvHook.c
+//
+// Description: Hook File for Report Firmware Volume.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <RomLayout.h>
+#include <Token.h>
+#include <AmiPeiLib.h>
+#include <AmiCspLib.h>
+#include <PeiRamBoot.h>
+//----------------------------------------------------------------------------
+// Function Externs
+extern
+EFI_STATUS PublishFv(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN ROM_AREA *Area,
+ IN BOOLEAN Nested
+);
+extern
+EFI_STATUS CreateFvHob2(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN ROM_AREA *Area,
+ IN EFI_GUID *FvName,
+ IN EFI_GUID *FfsName
+);
+extern
+EFI_STATUS CreateFvInfoPpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN ROM_AREA *Area,
+ IN EFI_GUID *FvName OPTIONAL,
+ IN EFI_GUID *FfsName OPTIONAL
+);
+//----------------------------------------------------------------------------
+// Local prototypes
+
+//----------------------------------------------------------------------------
+// Local Variables
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiRamBootNestedFvPublishing
+//
+// Description:
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// ROM_AREA* - Area
+//
+// Output: EFI_STATUS
+// ROM_AREA* - Area
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PeiRamBootNestedFvPublishing (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT ROM_AREA *Area,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **Fv,
+ OUT EFI_FIRMWARE_VOLUME_HEADER **NewFv,
+ OUT EFI_FFS_FILE_HEADER **Nfv
+)
+{
+ VOID *p, *p2;
+ static UINT8 NestedFvIndex = 0;
+ INTN Result;
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+ EFI_GUID HobRomImageGuid = ROM_IMAGE_MEMORY_HOB_GUID;
+ EFI_PHYSICAL_ADDRESS NestedFvBuffer = 0, NestedFvInMem = 0, TopOfMemory = 0;
+ UINT32 NestedFvLength = 0;
+ EFI_FIRMWARE_VOLUME_HEADER *pFv;
+
+ Status = (*PeiServices)->GetBootMode (PeiServices, &BootMode);
+ if (EFI_ERROR(Status) || \
+ (BootMode == BOOT_IN_RECOVERY_MODE) || \
+ (BootMode == BOOT_ON_FLASH_UPDATE)) return EFI_UNSUPPORTED;
+
+ for ((*PeiServices)->GetHobList(PeiServices,&p); \
+ !(FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &p)); ) {
+ Result = guidcmp(&((EFI_HOB_GUID_TYPE*)p)->Name, &HobRomImageGuid);
+ if (!Result) break;
+ }
+ if (Result) return EFI_UNSUPPORTED;
+ if (((HOB_ROM_IMAGE*)p)->HobValid == 0) {
+ // Try to decompress the Nested FV from memory if possible
+ UINT8 i;
+ ((HOB_ROM_IMAGE*)p)->NestedFvValid = 0;
+ for (i = 0; i < ((HOB_ROM_IMAGE*)p)->NumOfFv; i++) {
+ if ((Area->Address == ((HOB_ROM_IMAGE*)p)->FvInfo[i].FvAddress) && \
+ (((HOB_ROM_IMAGE*)p)->FvInfo[i].FvMemReady == TRUE))
+ *Fv = (EFI_FIRMWARE_VOLUME_HEADER*)((HOB_ROM_IMAGE*)p)->FvInfo[i].MemAddress;
+ }
+ return EFI_UNSUPPORTED;
+ }
+ pFv = (EFI_FIRMWARE_VOLUME_HEADER*)Area->Address;
+ NestedFvLength = ((HOB_ROM_IMAGE*)p)->NestedFvInfo[NestedFvIndex].FvLength;
+ NestedFvInMem = (EFI_PHYSICAL_ADDRESS)((HOB_ROM_IMAGE*)p)->NestedFvInfo[NestedFvIndex++].MemAddress;
+ // check whether NestFv memory is valid.
+ for ((*PeiServices)->GetHobList(PeiServices,&p2); \
+ !(FindNextHobByType(EFI_HOB_TYPE_MEMORY_ALLOCATION, &p2)); ) {
+ TopOfMemory = ((EFI_HOB_MEMORY_ALLOCATION*)p2)->AllocDescriptor.MemoryBaseAddress;
+ }
+ if (TopOfMemory != ((NestedFvInMem & (EFI_PHYSICAL_ADDRESS)~0xfff) + NestedFvLength + 0x1000)) {
+ // Memory Mapping changed, decompress Nested FV and re-collect Nested FV information
+ ((HOB_ROM_IMAGE*)p)->NestedFvValid = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = (*PeiServices)->FfsFindNextFile (PeiServices, \
+ EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE, pFv, Nfv);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = (*PeiServices)->AllocatePages(PeiServices, \
+ EfiRuntimeServicesData, (NestedFvLength >> 12) + 1, &NestedFvBuffer);
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+ if ((NestedFvInMem & (EFI_PHYSICAL_ADDRESS)~0xfff) != NestedFvBuffer) {
+ return EFI_UNSUPPORTED;
+ }
+ *NewFv = (EFI_FIRMWARE_VOLUME_HEADER*)(EFI_PHYSICAL_ADDRESS)NestedFvInMem;
+ ((HOB_ROM_IMAGE*)p)->NestedFvValid = 1;
+ return EFI_SUCCESS;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBootHook.c b/Core/EM/PeiRamBoot/PeiRamBootHook.c
new file mode 100644
index 0000000..c01e103
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBootHook.c
@@ -0,0 +1,282 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootHook.c 8 8/28/15 3:51a Tristinchou $
+//
+// $Revision: 8 $
+//
+// $Date: 8/28/15 3:51a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootHook.c $
+//
+// 8 8/28/15 3:51a Tristinchou
+// [TAG] EIP235157
+// [Category] Improvement
+// [Description] Security vulnerability - PeiRamBoot: Should leave cold
+// boot optimization only
+//
+// 7 6/21/11 2:22a Calvinchen
+// ¡P Bug Fixed:
+// Bug Fixed:
+// 1. Build failed if Core 4.6.4.0.
+// 2. System could hang if SAVE_ENTIRE_FV_TO_MEM = 1with AMD platform.
+//
+// 6 5/27/11 7:22a Calvinchen
+// Build failed if Core 4.6.4.1.
+//
+// 5 4/25/11 3:59a Calvinchen
+// Build failed if Core version greater than 4.6.4.1 with PI 0.91.
+//
+// 4 4/22/11 1:27a Calvinchen
+//
+// 3 3/22/11 7:52a Calvinchen
+// [TAG] EIP56322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs after changing TPM settings in SETUP.
+// [RootCause] System Memory Mappings are changed with warm boot.
+// [Solution] BIOS always go cold boot path if system memory mappings
+// are changed
+// [Files] PeiRamBoot.sdl
+// PeiRamBoot.mak
+// PeiRamBoot.dxs
+// PeiRamBoot.h
+// PeiRamBoot.c
+// PeiRamBootHook.c
+// PeiRamBootDxe.c
+// PeiRamBootOfbd.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 2 12/14/10 2:25a Calvinchen
+// Improvement :
+// 1. Added an eLink "PeiRamBootList" for fast warm boot support
+// (PEI_RAM_BOOT_S3_SUPPORT = 1). If system boots in warm boot state, BIOS
+// directly boot to previous copied ROM image in RAM to save time of
+// copying ROM.
+// 2. Added "PEI_RAM_BOOT_S3_SUPPORT" = "2" for saving runtime memory, it
+// only keep necessary PEIM FFS in runtime memory for S3 resume
+// improvement.
+//
+// 1 10/27/10 2:48a Calvinchen
+// Initial Check-in.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBootHook.c
+//
+// Description: Hook file for PEI Ram Boot module.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <Tiano.h>
+#include <PeiCore.h>
+#include <Token.h>
+#include <PeiRamBoot.h>
+
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+
+//----------------------------------------------------------------------------
+// Local Variables
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PeiDebugPrint
+//
+// Description: Worker function for debug print.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// UINTN - ErrorLevel
+// CHAR8* - Format
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#ifdef EFI_DEBUG
+ VOID
+ PeiDebugPrint (
+#if ((PI_SPECIFICATION_VERSION >= 0x0001000A) || (CORE_COMBINED_VERSION > 262785))
+#if (CORE_COMBINED_VERSION > 262785)
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+#else
+ IN EFI_PEI_SERVICES **PeiServices,
+#endif
+#else
+ IN EFI_PEI_SERVICES **PeiServices,
+#endif
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ IN ...
+ )
+ {
+ CHAR8 Buffer[256];
+ va_list ArgList = va_start(ArgList,Format);
+ PrepareStatusCodeString( Buffer, sizeof(Buffer), Format, ArgList );
+ (*PeiServices)->ReportStatusCode (
+ (EFI_PEI_SERVICES**)PeiServices, EFI_DEBUG_CODE,
+ EFI_SOFTWARE_UNSPECIFIED, 0, NULL,
+ (EFI_STATUS_CODE_DATA *)Buffer
+ );
+ va_end(ArgList);
+ }
+#endif
+#if (PI_SPECIFICATION_VERSION >= 0x0001000A)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsPeimDispatched
+//
+// Description:
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PHYSICAL_ADDRESS - Buffer
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IsPeimDispatched (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_FFS_FILE_HEADER *FfsFile,
+ IN UINTN Index
+)
+{
+ PEI_CORE_INSTANCE *Private = NULL;
+ Private = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ return Private->Fv[Private->CurrentPeimFvCount].PeimState[Index];
+}
+#else
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetDispatchedPeimBitMap
+//
+// Description: This procedure gets current PEIM dispatched BitMap from
+// DispatchedData of Privatedata of PeiService.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PHYSICAL_ADDRESS - Buffer
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT64
+GetDispatchedPeimBitMap (
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ PEI_CORE_INSTANCE *PrivateData = NULL;
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+ return PrivateData->DispatchData.DispatchedPeimBitMap;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SwitchPeiServiceDataToRam
+//
+// Description: This procedure redirect the FV Bass Address of Private data of
+// PEI Service from ROM to RAM.
+//
+// Input: EFI_PEI_SERVICES** - PeiServices
+// EFI_PHYSICAL_ADDRESS - Buffer
+//
+// Output: None.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SwitchPeiServiceDataToRam (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN HOB_ROM_IMAGE *HobRomImage
+)
+{
+ PEI_CORE_INSTANCE *PrivateData = NULL;
+ EFI_PHYSICAL_ADDRESS FvAddress = 0, PeimAddress = 0, Buffer = 0;
+ EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList = NULL;
+ UINTN i = 0, j = 0, Index;
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_FFS_FILE_HEADER *FfsFile = NULL;
+
+
+ PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
+#if defined(PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x0001000A)
+ for (i = 0, Index = 0; i < HobRomImage->NumOfFv; i++) {
+ Index = PrivateData->CurrentPeimFvCount;
+ FvAddress = \
+ (EFI_PHYSICAL_ADDRESS)PrivateData->Fv[Index].FvHeader;
+ if ((UINT32)FvAddress != HobRomImage->FvInfo[i].FvAddress) continue;
+ Buffer = HobRomImage->FvInfo[i].MemAddress;
+ PrivateData->Fv[Index].FvHeader = (EFI_FIRMWARE_VOLUME_HEADER*)Buffer;
+ for (j = 0; (j < PEI_CORE_MAX_PEIM_PER_FV) && \
+ (PrivateData->CurrentFvFileHandles[j] != NULL); j++) {
+ PrivateData->CurrentFvFileHandles[j] = \
+ (EFI_PEI_FILE_HANDLE)(((UINTN)PrivateData->CurrentFvFileHandles[j] - \
+ (UINTN)FvAddress) + Buffer);
+ PrivateData->Fv[Index].FvFileHandles[j] = \
+ (EFI_PEI_FILE_HANDLE)(((UINTN)PrivateData->Fv[Index].FvFileHandles[j] - \
+ (UINTN)FvAddress) + Buffer);
+ }
+ }
+#else // // PI 0.9 & 1.0
+ // Update PrivateData.DispatchData of PeiService.
+ FvAddress = (EFI_PHYSICAL_ADDRESS)PrivateData->DispatchData.BootFvAddress;
+ for (i = 0, Index = 0; i < HobRomImage->NumOfFv; i++) {
+ if ((UINT32)FvAddress != HobRomImage->FvInfo[i].FvAddress) continue;
+ Buffer = HobRomImage->FvInfo[i].MemAddress;
+ PrivateData->DispatchData.BootFvAddress = \
+ (EFI_FIRMWARE_VOLUME_HEADER*)(Buffer);
+ PrivateData->DispatchData.CurrentFvAddress = \
+ (EFI_FIRMWARE_VOLUME_HEADER*)(Buffer);
+ // CurrentPeimAddress point to last PEIM, so, dispatcher will start at
+ // the 1st in next time.
+ // find last FFS..
+ PeimAddress = (EFI_PHYSICAL_ADDRESS)PrivateData->DispatchData.CurrentPeimAddress;
+ PrivateData->DispatchData.CurrentPeimAddress = \
+ (EFI_FFS_FILE_HEADER*)(Buffer + (PeimAddress - FvAddress));
+ break;
+ }
+#endif // PI 0.9 & 1.0
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/PeiRamBoot/PeiRamBootOfbd.c b/Core/EM/PeiRamBoot/PeiRamBootOfbd.c
new file mode 100644
index 0000000..8d324d8
--- /dev/null
+++ b/Core/EM/PeiRamBoot/PeiRamBootOfbd.c
@@ -0,0 +1,185 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootOfbd.c 3 6/18/14 11:57p Calvinchen $
+//
+// $Revision: 3 $
+//
+// $Date: 6/18/14 11:57p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/PEI Ram Boot/PeiRamBootOfbd.c $
+//
+// 3 6/18/14 11:57p Calvinchen
+// Bug Fixed: System hangs with using AFU.
+//
+// 2 5/05/14 5:03a Calvinchen
+// [TAG] EIP166551
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Runtime attribute set for the some of the variable used
+// by PEI Ram Boot driver and needs to be reviewed
+// [Files] PeiRamBootDxe.c
+// PeiRamBootOfbd.c
+// PeiRamBoot.chm
+// PeiRamBoot.cif
+//
+// 1 2/11/11 3:15a Calvinchen
+// Bug Fixed : System hangs after reflashed BIOS with warm reset if
+// PEI_RAM_BOOT_S3_SUPPORT = 1 with fast warm boot support.
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PeiRamBootOfbd.c
+//
+// Description: If system updated BIOS with warm reset, PeiRamBoot module
+// will not copy rom to ram in sequence boot, and, it could
+// cause system crashed. For avoiding this situation, BIOS
+// delete the PEI RAM Boot related variables if system executed
+// AFU.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <HOB.h>
+#include "PeiRamBoot.h"
+#include "OFBD.h"
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+typedef struct{
+ SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables;
+} AMI_NVRAM_CONTROL_PROTOCOL;
+static AMI_NVRAM_CONTROL_PROTOCOL *gpNvramControl = NULL;
+
+//----------------------------------------------------------------------------
+// Local Variables
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiRamBootOfbdEntry
+//
+// Description:
+//
+// Input:
+// IN VOID *Buffer
+// IN OUT UINT8 *pOFBDDataHandled
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PeiRamBootOfbdEntry (
+ IN VOID *Buffer,
+ IN OUT UINT8 *pOFBDDataHandled )
+{
+ EFI_GUID RomImageAddressGuid = ROM_IMAGE_ADDRESS_GUID;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS HobRomImageAddress;
+ UINTN VariableSize;
+ static BOOLEAN blIsProcessed = FALSE;
+
+ if (blIsProcessed == FALSE) blIsProcessed = TRUE;
+ else return;
+
+ // Temporarily enable Nvram Variable Boot Time Access permission.
+ if (gpNvramControl) gpNvramControl->ShowBootTimeVariables(TRUE);
+
+ VariableSize = sizeof(EFI_PHYSICAL_ADDRESS);
+ Status = pRS->GetVariable ( L"HobRomImage", \
+ &RomImageAddressGuid, \
+ NULL, \
+ &VariableSize, \
+ &HobRomImageAddress );
+ if (!EFI_ERROR(Status)) {
+ // Delete HobRomImage Variable if system is executing AFU for forcing BIOS
+ // copy rom to image in sequence boot.
+ VariableSize = 0;
+ Status = pRS->SetVariable ( L"HobRomImage", \
+ &RomImageAddressGuid, \
+ EFI_VARIABLE_NON_VOLATILE | \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ VariableSize, \
+ &HobRomImageAddress );
+ }
+ // Disable Nvram Variable Boot Time Access permission.
+ if (gpNvramControl) gpNvramControl->ShowBootTimeVariables(FALSE);
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiRamBootOfbdInSmm
+//
+// Description:
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PeiRamBootOfbdInSmm (VOID)
+{
+ EFI_STATUS Status;
+ EFI_SMM_BASE2_PROTOCOL *pSmmBase2;
+ EFI_SMM_SYSTEM_TABLE2 *mSmst;
+ UINTN i;
+ EFI_CONFIGURATION_TABLE *Table;
+ static EFI_GUID gAmiNvramControlProtocolGuid = \
+ { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } };
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &pSmmBase2);
+ if (EFI_ERROR(Status)) return ;
+
+ Status = pSmmBase2->GetSmstLocation (pSmmBase2, &mSmst);
+ if (EFI_ERROR(Status)) return ;
+
+ Table = mSmst->SmmConfigurationTable;
+ for (i = mSmst->NumberOfTableEntries; i; --i, ++Table) {
+ if (guidcmp(&Table->VendorGuid, &gAmiNvramControlProtocolGuid)) continue;
+ gpNvramControl = (AMI_NVRAM_CONTROL_PROTOCOL*)Table->VendorTable;
+ break;
+ }
+ return;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/PlatformToDriver/PlatformToDriver.c b/Core/EM/PlatformToDriver/PlatformToDriver.c
new file mode 100644
index 0000000..4077656
--- /dev/null
+++ b/Core/EM/PlatformToDriver/PlatformToDriver.c
@@ -0,0 +1,199 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/PlatformToDriverConfiguration/PlatformToDriver.c 1 5/02/11 5:30p Artems $
+//
+// $Revision: 1 $
+//
+// $Date: 5/02/11 5:30p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/PlatformToDriverConfiguration/PlatformToDriver.c $
+//
+// 1 5/02/11 5:30p Artems
+// Platform-to-Driver confuguration protocol supporting infrastructure
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: PlatformToDriver.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Protocol\PlatformToDriverConfiguration.h>
+
+typedef EFI_STATUS (PLATFORM_TO_DRIVER_AGENT_SUPPORTED) (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL
+);
+
+typedef EFI_STATUS (PLATFORM_TO_DRIVER_AGENT_QUERY) (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINTN *Instance,
+ OUT EFI_GUID **ParameterTypeGuid,
+ OUT VOID **ParameterBlock,
+ OUT UINTN *ParameterBlockSize
+);
+
+typedef EFI_STATUS (PLATFORM_TO_DRIVER_AGENT_RESPONSE) (
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINTN *Instance,
+ IN EFI_GUID *ParameterTypeGuid,
+ IN VOID *ParameterBlock,
+ IN UINTN ParameterBlockSize,
+ IN EFI_PLATFORM_CONFIGURATION_ACTION ConfigurationAction
+);
+
+typedef struct{
+ PLATFORM_TO_DRIVER_AGENT_SUPPORTED *Supported;
+ PLATFORM_TO_DRIVER_AGENT_QUERY *Query;
+ PLATFORM_TO_DRIVER_AGENT_RESPONSE *Response;
+} PLATFORM_TO_DRIVER_AGENT;
+
+
+#define OEM_PLATFORM_TO_DRIVER_AGENT(Supported, Query, Response) Supported
+extern PLATFORM_TO_DRIVER_AGENT_SUPPORTED PlatformToDriverAgentList EndOfList1;
+#undef OEM_PLATFORM_TO_DRIVER_AGENT
+
+#define OEM_PLATFORM_TO_DRIVER_AGENT(Supported, Query, Response) Query
+extern PLATFORM_TO_DRIVER_AGENT_QUERY PlatformToDriverAgentList EndOfList2;
+#undef OEM_PLATFORM_TO_DRIVER_AGENT
+
+#define OEM_PLATFORM_TO_DRIVER_AGENT(Supported, Query, Response) Response
+extern PLATFORM_TO_DRIVER_AGENT_RESPONSE PlatformToDriverAgentList EndOfList3;
+#undef OEM_PLATFORM_TO_DRIVER_AGENT
+
+#define OEM_PLATFORM_TO_DRIVER_AGENT(Supported, Query, Response) { Supported, Query, Response }
+PLATFORM_TO_DRIVER_AGENT AgentList[] = {
+ PlatformToDriverAgentList
+ { NULL, NULL, NULL }
+};
+
+EFI_HANDLE CurrentControllerHandle = NULL;
+UINT32 CurrentAgentIndex;
+
+EFI_STATUS PlatformToDriverConfigurationQuery (
+ IN EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINTN *Instance,
+ OUT EFI_GUID **ParameterTypeGuid,
+ OUT VOID **ParameterBlock,
+ OUT UINTN *ParameterBlockSize
+)
+{
+ EFI_STATUS Status;
+
+ if(ControllerHandle == NULL || Instance == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ControllerHandle != CurrentControllerHandle) {
+ CurrentAgentIndex = 0;
+ Status = EFI_UNSUPPORTED;
+ while(AgentList[CurrentAgentIndex].Supported != NULL) {
+ Status = AgentList[CurrentAgentIndex].Supported(ControllerHandle, ChildHandle);
+ if(!EFI_ERROR(Status))
+ break;
+ CurrentAgentIndex++;
+ }
+ if(EFI_ERROR(Status)) {
+ CurrentControllerHandle = NULL;
+ return EFI_NOT_FOUND;
+ }
+
+ CurrentControllerHandle = ControllerHandle;
+ }
+
+ return AgentList[CurrentAgentIndex].Query(ControllerHandle,
+ ChildHandle,
+ Instance,
+ ParameterTypeGuid,
+ ParameterBlock,
+ ParameterBlockSize);
+}
+
+EFI_STATUS PlatformToDriverConfigurationResponse (
+ IN EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN UINTN *Instance,
+ IN EFI_GUID *ParameterTypeGuid,
+ IN VOID *ParameterBlock,
+ IN UINTN ParameterBlockSize,
+ IN EFI_PLATFORM_CONFIGURATION_ACTION ConfigurationAction
+)
+{
+ if(ControllerHandle == NULL || Instance == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ControllerHandle != CurrentControllerHandle)
+ return EFI_NOT_FOUND;
+
+ return AgentList[CurrentAgentIndex].Response(ControllerHandle,
+ ChildHandle,
+ Instance,
+ ParameterTypeGuid,
+ ParameterBlock,
+ ParameterBlockSize,
+ ConfigurationAction);
+}
+
+EFI_PLATFORM_TO_DRIVER_CONFIGURATION_PROTOCOL EfiPlatformToDriverConfigurationProtocol = {
+ PlatformToDriverConfigurationQuery,
+ PlatformToDriverConfigurationResponse
+};
+
+EFI_STATUS PlatformToDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handle = NULL;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiPlatformToDriverConfigurationProtocolGuid,
+ &EfiPlatformToDriverConfigurationProtocol,
+ NULL);
+
+
+ return Status;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/PlatformToDriver/PlatformToDriver.cif b/Core/EM/PlatformToDriver/PlatformToDriver.cif
new file mode 100644
index 0000000..a3d95de
--- /dev/null
+++ b/Core/EM/PlatformToDriver/PlatformToDriver.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "PlatformToDriver"
+ category = ModulePart
+ LocalRoot = "Core\EM\PlatformToDriver"
+ RefName = "PlatformToDriver"
+[files]
+"PlatformToDriver.sdl"
+"PlatformToDriver.mak"
+"PlatformToDriver.c"
+<endComponent>
diff --git a/Core/EM/PlatformToDriver/PlatformToDriver.mak b/Core/EM/PlatformToDriver/PlatformToDriver.mak
new file mode 100644
index 0000000..36f1142
--- /dev/null
+++ b/Core/EM/PlatformToDriver/PlatformToDriver.mak
@@ -0,0 +1,58 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/PlatformToDriverConfiguration/PlatformToDriver.mak 1 5/02/11 5:30p Artems $
+#
+# $Revision: 1 $
+#
+# $Date: 5/02/11 5:30p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/PlatformToDriverConfiguration/PlatformToDriver.mak $
+#
+# 1 5/02/11 5:30p Artems
+# Platform-to-Driver confuguration protocol supporting infrastructure
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: PlatformToDriver.mak
+#
+# Description: Make file to create PlatformToDriver configuration Driver
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\PlatformToDriver.obj
+
+$(BUILD_DIR)\PlatformToDriver.obj : $(PlatformToDriver_DIR)\PlatformToDriver.c
+
+{$(PlatformToDriver_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) /D \"PlatformToDriverAgentList=$(PlatformToDriverAgents)\" /Fo$(BUILD_DIR)\ $<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/PlatformToDriver/PlatformToDriver.sdl b/Core/EM/PlatformToDriver/PlatformToDriver.sdl
new file mode 100644
index 0000000..71ae95f
--- /dev/null
+++ b/Core/EM/PlatformToDriver/PlatformToDriver.sdl
@@ -0,0 +1,31 @@
+TOKEN
+ Name = "PlatformToDriver_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Platform-to-driver configuration support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "PlatformToDriver_DIR"
+ Help = "Path to PlatformToDriver Module in Project"
+End
+
+MODULE
+ Help = "Includes PlatformToDriver.mak to Project"
+ File = "PlatformToDriver.mak"
+End
+
+ELINK
+ Name = "PlatformToDriverEntryPoint,"
+ Parent = "BdsEntryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PlatformToDriverAgents"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/Recovery/CapsuleRecovery.c b/Core/EM/Recovery/CapsuleRecovery.c
new file mode 100644
index 0000000..f38c11e
--- /dev/null
+++ b/Core/EM/Recovery/CapsuleRecovery.c
@@ -0,0 +1,278 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/CapsuleRecovery.c 2 4/16/13 5:51a Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 4/16/13 5:51a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/CapsuleRecovery.c $
+//
+// 2 4/16/13 5:51a Thomaschen
+// Fixed for EIP106722.
+//
+// 4 2/07/13 5:17p Artems
+// [TAG] EIP106722
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] Win8 firmware update doesn't work
+// [RootCause] For Win8 update capsule CapsuleRecovery device didn't
+// skip capsule header
+// [Solution] Added unique GUID to distinguish between AFU and Win8
+// capsule update
+// [Files] Capsule2_0.c CapsuleRecovery.c Capsule.h
+//
+// 3 11/15/12 4:28p Artems
+// [TAG] EIP103898
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] After updating Core 4.6.5.4, the Capsule mode of Secure
+// Flash can't work.
+// [RootCause] Capsule recovery device was stripping capsule header from
+// provided image,
+// but verification code requires header to be present
+// [Solution] Keep header together with recovery image for verification
+// purposes
+// [Files] CapsuleRecovery.c
+//
+// 2 9/17/12 2:50p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Removed unnecessary debug messages
+// [Files] CapsuleRecovery.c
+//
+// 1 8/02/12 12:04p Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Windows 8 firmware update spec
+// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c
+// Esrt.c CapsuleRecovery.c
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: CapsuleRecovery.c
+//
+// Description: Recovery from Capsule support
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiPeiLib.h>
+#include <AmiHobs.h>
+#include <Capsule.h>
+#include <Token.h>
+#include "Recovery.h"
+#include "RecoveryCsp.h"
+
+
+/************************************************************************/
+/* Device Recovery Module PPI */
+/************************************************************************/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetNumberRecoveryCapsules
+//
+// Description:
+// GetNumberRecoveryCapsules function of ppi
+// EFI_PEI_DEVICE_RECOVERY_MODULE_PPI.
+//
+// Input:
+//
+// Output:
+// EFI_SUCCESS - number of recovery capsules returned
+// EFI_INVALID_PARAMETER - the pointer NumberRecoveryCapsules is NULL
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS GetNumberRecoveryCapsules(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ OUT UINTN *NumberRecoveryCapsules
+)
+{
+ if ( !NumberRecoveryCapsules ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *NumberRecoveryCapsules = 1;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetRecoveryCapsuleInfo
+//
+// Description:
+// GetRecoveryCapsuleInfo function of ppi EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
+// for any block devices including floppies, USB keys, CD-ROMs and HDDs.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PeiServices Structure
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This - pointer to the PPI structure
+// IN UINTN CapsuleInstance - value indicating the instance of the PPI
+// OUT UINTN *Size - Size of the recovery capsule
+// OUT EFI_GUID *CapsuleType OPTIONAL - Type of recovery capsule
+//
+// Output:
+// EFI_SUCCESS - Parameters are valid and output parameters are updated
+// EFI_INVALID_PARAMETER - Size pointer is NULL
+// EFI_NOT_FOUND - asking for a 1 or greater instance of the PPI
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS GetRecoveryCapsuleInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT UINTN *Size,
+ OUT EFI_GUID *CapsuleType )
+{
+ EFI_STATUS Status;
+ if ( !Size ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( CapsuleInstance > 0 ) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetRecoveryFileInfo(PeiServices, NULL, Size, NULL);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if ( CapsuleType ) {
+ *CapsuleType = guidOemCapsule;
+ }
+ return EFI_SUCCESS;
+}
+
+#define NUMBER_OF_RETRIES 3
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LoadRecoveryCapsule
+//
+// Description:
+// Locates all EFI_PEI_RECOVERY_BLOCK_IO_PPI PPIs. Calls function
+// GetNumberOfBlockDevices. For each block device, calls the function
+// FsRecoveryRead, to find the recovery image named in var sAmiRomFile.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PeiServices Structure
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This - pointer to the PPI structure
+// IN UINTN CapsuleInstance - value indicating the instance of the PPI
+// OUT VOID *Buffer - contains information read from the block device
+//
+// Output:
+// EFI_SUCCESS - File read from recovery media
+// EFI_INVALID_PARAMETER - Buffer is a NULL pointer
+// EFI_NOT_FOUND - asking for a 1 or greater instance of the PPI
+// Other - return error values from LocatePpi or FsRecoveryRead
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS LoadRecoveryCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ AMI_CAPSULE_HOB *CapsuleHob;
+ static EFI_GUID CapsuleHobGuid = AMI_CAPSULE_HOB_GUID;
+ static EFI_GUID AptioFwCapsuleGuid = APTIO_FW_CAPSULE_GUID;
+ static EFI_GUID W8FwUpdateImageCapsuleGuid = W8_FW_UPDATE_IMAGE_CAPSULE_GUID;
+ EFI_CAPSULE_HEADER *Capsule;
+ VOID *Data;
+ UINTN CapsuleSize;
+
+ Status = (*PeiServices)->GetHobList(PeiServices, &CapsuleHob);
+ if(EFI_ERROR(Status))
+ return EFI_SUCCESS;
+
+ do {
+ Status = FindNextHobByGuid(&CapsuleHobGuid, &CapsuleHob);
+ if(!EFI_ERROR(Status)) {
+ Capsule = (EFI_CAPSULE_HEADER *)(VOID *)(UINTN)(CapsuleHob->CapsuleData);
+ if(!guidcmp(&AptioFwCapsuleGuid, &(CapsuleHob->CapsuleGuid))) { //we found AFU recovery capsule, let's keep capsule header and put into provided buffer
+ MemCpy(Buffer, Capsule, Capsule->CapsuleImageSize);
+ return EFI_SUCCESS;
+ }
+ if(!guidcmp(&W8FwUpdateImageCapsuleGuid, &(CapsuleHob->CapsuleGuid))) { //we found Win8 recovery capsule, let's skip capsule header and put into provided buffer
+ CapsuleSize = Capsule->CapsuleImageSize - Capsule->HeaderSize;
+ Data = (VOID *)((UINT8 *)Capsule + Capsule->HeaderSize);
+ MemCpy(Buffer, Data, CapsuleSize);
+ return EFI_SUCCESS;
+ }
+ }
+ } while(!EFI_ERROR(Status));
+
+ return Status;
+}
+
+/************************************************************************/
+/* Entry Point */
+/************************************************************************/
+EFI_PEI_DEVICE_RECOVERY_MODULE_PPI CapsuleDeviceRecoveryModule = {
+ GetNumberRecoveryCapsules, GetRecoveryCapsuleInfo, LoadRecoveryCapsule
+};
+
+// PPI to be installed
+static EFI_PEI_PPI_DESCRIPTOR CapsuleDeviceRecoveryPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidRecoveryDevice, &CapsuleDeviceRecoveryModule
+ }
+};
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CapsuleDeviceRecoveryEntry
+//
+// Description:
+// Installs EFI_PEI_DEVICE_RECOVERY_MODULE_PPI for loading recovery
+// images from APTIO_FW_CAPSULE_GUID capsule
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CapsuleDeviceRecoveryEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return (*PeiServices)->InstallPpi( PeiServices, CapsuleDeviceRecoveryPpiList );
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/FsRecovery.c b/Core/EM/Recovery/FsRecovery.c
new file mode 100644
index 0000000..b16d7b0
--- /dev/null
+++ b/Core/EM/Recovery/FsRecovery.c
@@ -0,0 +1,3193 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/Recovery/FsRecovery.c 22 8/09/12 11:13a Pats $
+//
+// $Revision: 22 $
+//
+// $Date: 8/09/12 11:13a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/Recovery/FsRecovery.c $
+//
+// 22 8/09/12 11:13a Pats
+// [TAG] - EIP 80780
+// [Category] - Function Request
+// [Description] - Support for recovery from media formatted with the
+// EXT(x) file system.
+// [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+// and FsRecovery.c (source)
+//
+// 21 4/24/12 11:43a Pats
+// [TAG] EIP87223
+// [Category] Bug Fix
+// [Symptom] After update EIP#81131 solution, the MBR recovery function
+// would fail
+// [RootCause] Pointer *Root not being updated correctly in function
+// AmiGetFileListFromNtfsVolume().
+// [Solution] Correct updating of pointer *Root.
+//
+// [Files] FsRecovery.c
+//
+// 20 1/25/12 2:49p Pats
+// [TAG] - EIP 26909
+// [Category] - Function Request
+// [Description] - Support for recovery from media formatted with the NTFS
+// file system. This of necessity includes detection of GPT partitions,
+// which may contain any file system.
+// [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+// and FsRecovery.c (source)
+//
+// 19 5/13/11 5:07p Artems
+// Added secure flash update support
+//
+// 18 2/05/11 3:22p Artems
+// EIP 39463: Added support to override GetFileName function for custom
+// recovery capsule name
+//
+// 17 6/11/10 11:36a Artems
+// Added porting hooks for GetRecoveryCapsuleFileName and
+// IsRecoveryCapsuleValid
+//
+// 16 1/05/10 11:59a Robert
+// Fixed bug in calculation of byte offset of the beginning of a file on a
+// FAT file system. The old code could not handle a file starting address
+// above 4GB. It now uses a UINT64 calculation so it can handle it
+//
+// 15 11/25/09 4:53p Felixp
+// sAmiRomFile renamed to RecoveryFileName
+// FlashSize renamed ro RecoveryImageSize
+//
+// 14 8/11/09 2:27p Robert
+// - EIP 24689: There was a bug in the wildcard search with FAT that
+// caused it not to identify the file properly.
+// - The code was expecting string termination. Switched to filename
+// length instead. Updated both the FAT file search and the ISO9660
+// search with this.
+// - Also added a check for the FAT file system that checks for the 0xE5
+// character that defines an invalid or deleted file.
+//
+// 13 7/09/09 12:54p Artems
+// Removed PeiTrace debugging calls
+//
+// 12 7/07/09 2:05p Robert
+// - Added functionality to search for recovery files that fit one of many
+// comma separated pattern strings.
+// - Function header updates
+//
+// 11 7/01/09 4:18p Rameshr
+// Coding Standard and File header updated.
+//
+// 10 6/16/09 5:21p Artems
+// EIP 21169 Added Eltorito support
+//
+// 7 4/13/07 5:37p Ambikas
+// Coding standards changes: Added AMI_PHDRs for every function; split
+// multiple declarations on a line into single line statements.
+//
+// 6 10/13/06 11:07a Felixp
+// 1. el Torito support added
+// 2. Correct partition handling
+//
+// 5 9/26/06 9:22a Ambikas
+//
+// 4 6/04/06 9:29p Ambikas
+//
+// 3 4/13/06 2:02p Ambikas
+//
+// 1 12/01/05 9:45a Felixp
+//
+// 4 11/18/05 3:55p Felixp
+// bug fix in ReadFileData
+//
+// 3 6/06/05 1:27p Felixp
+// Type parameter removed from AllocatePages to match PEI CIS 0.91
+//
+// 2 3/25/05 5:41p Felixp
+// small bug fix
+//
+// 1 3/24/05 3:37p Felixp
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: FsRecovery.c
+//
+// Description: Recovery Filesytem support
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiPeiLib.h>
+#include <Token.h>
+#include "Recovery.h"
+#include "RecoveryCsp.h"
+
+#define FAT_FILE_NAME_SIZE 11
+
+extern BOOLEAN CdRecoverySupport;
+extern BOOLEAN FatRecoverySupport;
+extern BOOLEAN NtfsRecoverySupport;
+extern BOOLEAN ExtRecoverySupport;
+
+UINT8 *ReadBuffer = NULL;
+UINTN BufferSize = 0;
+
+UINT8 *FatBuffer = NULL;
+UINTN FatBufferSize = 0;
+
+UINT8 *RootBuffer = NULL;
+UINTN RootBufferSize = 0;
+UINT32 RootEntries = 0;
+UINT32 RootSize = 0;
+
+DIR_ENTRY *FatRecoveryFiles[10];
+DIR_RECORD *CdRecoveryFiles[10];
+#if NTFS_RECOVERY_SUPPORT
+INDEX_ENTRY *NtfsRecoveryFiles[10];
+
+//UINT8 MFTRunList[256];
+//UINT8 RootRunList[128];
+//UINT8 ResidentIndex[256];
+BOOLEAN ResidentPresent;
+UINT32 ResidentSize;
+#endif
+#if EXT_RECOVERY_SUPPORT
+DIR_ENTRY_EXT *ExtRecoveryFiles[10];
+UINT32 InodeBlock; // First block of inode table
+UINT8 Indirect;
+UINT32 *BlockList;
+UINT32 *BlockList2;
+#endif
+
+UINTN PartCount;
+BOOLEAN IsMbr;
+UINT32 GpeCount;
+UINT32 PartSector;
+//MASTER_BOOT_RECORD Mbr;
+MEMORY_BLOCK *MemBlk;
+
+EFI_PEI_SERVICES **ThisPeiServices;
+#if SEARCH_FAT_PATH
+RC_VOL_INFO *ThisVolume; // Saved volume info for path search
+#endif
+
+//***************************************************************************
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: toupper
+//
+// Description:
+// Converts lower case characters to upper case
+//
+// Input:
+// IN CHAR8 c - character to convert
+//
+// Output:
+// CHAR8 - converted character value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR8 toupper(
+ IN CHAR8 c )
+{
+ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FileCompare
+//
+// Description:
+// This function takes a filename and a filename pattern and tries to make
+// a match. It can account for Wild characters * and ? in the pattern. Also,
+// the pattern can be multiple comma separated patterns.
+//
+// Input:
+// IN CHAR8 *RecoveryFileName - recover file pattern string comma separated
+// IN CHAR8 *FsFilename - file name to check against the pattern string
+// IN BOOLEAN IgnoreSpacesInFilename - If true, ignore spaces in FsFilename when pattern string is a period
+//
+// Output:
+// TRUE - Pattern matches filename
+// FALSE - Pattern doesn't match filename
+//
+// Notes:
+// RecoveryFileNamePattern is taken from the RECOVERY_ROM token and should look
+// like this: *.rom,ab??rt??.bio,123.bin etc.
+// The Parameter IgnoreSpacesInFilename is for use with file systems that pad
+// spaces into filenames and don't use periods. If TRUE, it matches a period
+// in the pattern to any number of spaces in the filename.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN FileCompare(
+ IN CHAR8 *RecoveryFileNamePattern,
+ IN CHAR8 *FsFilename,
+ IN BOOLEAN IgnoreSpacesInFilename,
+ IN UINT32 FileNameLength)
+{
+ CHAR8 ch1, ch;
+ UINTN len1, len2;
+
+ for (; ;) {
+ // check length of string
+ len1 = Strlen(FsFilename);
+ len2 = Strlen(RecoveryFileNamePattern);
+
+ // if len1 is 0 then at end of filename
+ if(!len1 || !FileNameLength)
+ {
+ // if len2 is 0 then also at end of pattern so file name is
+ // equal to a pattern
+ if(!len2 )
+ return TRUE;
+ else
+ {
+ // if len2 is a comma, then it is the same as len2 == 0 so
+ // file name is equal to a pattern
+ ch1 = *RecoveryFileNamePattern;
+ if (ch1 == ',')
+ {
+ return TRUE;
+ }
+ // if not a comma or 0, then file does not fit the pattern
+ return FALSE;
+ }
+ }
+
+ // get next character of the pattern
+ ch1 = *RecoveryFileNamePattern;
+ RecoveryFileNamePattern ++;
+
+ switch (ch1)
+ {
+ case ',':
+ return TRUE;
+ break;
+
+ case 0: // reached string terminator
+ return TRUE;
+ break;
+
+ // wild character, it must deal with any number of matching characters
+ // in the file name string
+ case '*':
+ while (*FsFilename)
+ {
+ if (FileCompare (RecoveryFileNamePattern, FsFilename, IgnoreSpacesInFilename, FileNameLength))
+ {
+ return TRUE;
+ }
+ FsFilename ++;
+ FileNameLength--;
+ }
+ return FileCompare (RecoveryFileNamePattern, FsFilename, IgnoreSpacesInFilename, FileNameLength);
+ break;
+
+ // wild character, it must deal with a matching character in the file name string
+ case '?':
+ if (!*FsFilename)
+ {
+ return FALSE;
+ }
+
+ FsFilename ++;
+ FileNameLength--;
+ break;
+
+ // in this case statement the case '.' must be directly above the default case.
+ // if IgnoreSpacesInFilename is FALSE, it is supposed to fall through into default.
+ // If IgnoreSpacesInFilenameis TRUE, process the period as a check for spaces character.
+ // then once we skip over all spaces, if there are any, then it moves to the
+ // next character in the pattern
+ case '.':
+ // FAT, spaces added to file name to make 8 3 -- no period in the filename either
+ if (IgnoreSpacesInFilename == TRUE)
+ {
+ ch = *FsFilename;
+
+ while ((ch == ' ') && (ch != 0))
+ {
+ FsFilename ++;
+ FileNameLength--;
+ ch = *FsFilename;
+ }
+ break;
+ }
+ // CDFS, no spaces and there is a period. Let it fall through to the default case
+ default:
+ ch = *FsFilename;
+ if (toupper(ch) != toupper(ch1))
+ {
+ return FALSE;
+ }
+ FsFilename ++;
+ FileNameLength--;
+ break;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FileSearch
+//
+// Description:
+// Wrapper function for parsing through a pattern string with multiple entries
+// Each entry is comma separated and can include wild characters like * and ?
+// The Function can handle CDFS and FAT file systems.
+//
+// Input:
+// IN CHAR8 *RecoveryFileName - recover file pattern string comma separated
+// IN CHAR8 *FsFilename - file name to check against the pattern string
+// IN BOOLEAN IgnoreSpacesInFilename - If true, ignore spaces in FsFilename when pattern string is a period
+//
+// Output:
+// EFI_SUCCESS - File name fits one of the Pattern strings in RecoveryFileName
+// EFI_INVALID_PARAMETER - one of the strings is NULL or file name doesn't fit pattern string
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FileSearch(
+ IN CHAR8 *RecoveryFileName,
+ IN CHAR8 *FsFilename,
+ IN BOOLEAN IgnoreSpacesInFilename,
+ IN UINT32 FileNameLength)
+{
+ CHAR8 *RecStrPtr = RecoveryFileName;
+ CHAR8 *FilenamePtr = FsFilename;
+
+ if (*RecStrPtr == 0)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*FsFilename == 0)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FileNameLength == 0 )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ // loop until all possibilities listed in the RecoveryFileName are exhausted
+ do {
+ // Now compare the current possiblity to the current filename
+ FilenamePtr = FsFilename;
+
+ if (*RecStrPtr == ',')
+ RecStrPtr++;
+
+ if (FileCompare(RecStrPtr, FsFilename, IgnoreSpacesInFilename, FileNameLength) == TRUE)
+ return EFI_SUCCESS;
+
+ while (*RecStrPtr != ',' && *RecStrPtr != 0)
+ RecStrPtr ++;
+
+ } while (*RecStrPtr != 0);
+
+ return EFI_INVALID_PARAMETER;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertToFatFileName
+//
+// Description:
+// Converts file name from "XXXXX.XXX" form to FAT form
+//
+// Input:
+// IN CHAR8 *inFileName - pointer to input file name
+// OUT CHAR8 *outFileName - pointer to output file name
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ConvertToFatFileName(
+ IN CHAR8 *inFileName,
+ OUT CHAR8 *outFileName )
+{
+ UINT32 i = 0;
+ UINT32 j = 0;
+
+ for ( i = 0; inFileName[i] && inFileName[i] != '.'; i++ ) {
+ outFileName[i] = toupper( inFileName[i] );
+ }
+ j = i;
+
+ for (; i < 8; i++ ) {
+ outFileName[i] = ' ';
+ }
+
+ if ( inFileName[j] == '.' ) {
+ for ( j++; inFileName[j]; i++, j++ ) {
+ outFileName[i] = toupper( inFileName[j] );
+ }
+ }
+
+ for (; i < 11; i++ ) {
+ outFileName[i] = ' ';
+ }
+ outFileName[i] = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadDevice
+//
+// Description: Reads data from Block device
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN RC_VOL_INFO *Volume - pointer to volume description structure
+// IN UINT64 Start - starting offset in bytes
+// IN UINTN Size - size of the data to read
+// VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_SUCCESS
+// Errors
+// - returns either the error status from Allocate Pages or Read Blocks
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN RC_VOL_INFO *Volume,
+ IN UINT64 Start,
+ IN UINTN Size,
+ OUT VOID *Buffer )
+{
+ UINT64 StartLba;
+ UINTN ActualSize;
+ UINTN ActualPages;
+ UINT32 StartOffset;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Allocate;
+
+ Start += Volume->PartitionOffset;
+
+ if ( Volume->BlockSize == 4096 ) {
+ StartLba = Shr64( Start, 12 );
+ StartOffset = (UINT32)( Start & 0xfff );
+ } else if ( Volume->BlockSize == 2048 ) {
+ StartLba = Shr64( Start, 11 );
+ StartOffset = (UINT32)( Start & 0x7ff );
+ } else {
+ StartLba = Shr64( Start, 9 );
+ StartOffset = (UINT32)( Start & 0x1ff );
+ }
+
+ ActualSize = ((StartOffset + Size + Volume->BlockSize - 1) / Volume->BlockSize) * Volume->BlockSize;
+ ActualPages = EFI_SIZE_TO_PAGES( ActualSize );
+
+ if ( BufferSize < EFI_PAGES_TO_SIZE( ActualPages )) {
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, ActualPages, &Allocate );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ ReadBuffer = (UINT8*)((UINTN)Allocate);
+ BufferSize = EFI_PAGES_TO_SIZE( ActualPages );
+ }
+
+ Status = Volume->BlkIo->ReadBlocks( PeiServices,
+ Volume->BlkIo,
+ Volume->Device,
+ StartLba,
+ ActualSize,
+ ReadBuffer );
+
+ if ( !EFI_ERROR( Status )) {
+ MemCpy( Buffer, ReadBuffer + StartOffset, Size );
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFat
+//
+// Description:
+// Checks if given data block describes FAT structure
+//
+// Input:
+// BOOT_SECTOR *pBpb - pointer to data block to check
+//
+// Output:
+// TRUE - data block is a FAT structure
+// FALSE - data block is not a FAT structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsFat(
+ IN BOOT_SECTOR *pBpb )
+{
+ return pBpb->BytsPerSec <= 4096
+ && pBpb->SecPerClus && pBpb->SecPerClus <= 128
+ && pBpb->RsvdSecCnt
+ && pBpb->NumFATs
+ && pBpb->Signature == 0xAA55
+ && (pBpb->jmp[0] == 0xEB || pBpb->jmp[0] == 0xE9);
+}
+
+#if NTFS_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsNtfs
+//
+// Description:
+// Checks if given data block describes NTFS structure
+//
+// Input:
+// BOOT_SECTOR *pBpb - pointer to data block to check
+//
+// Output:
+// TRUE - data block is a NTFS structure
+// FALSE - data block is not a NTFS structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsNtfs(
+ IN BOOT_SECTOR *pBpb )
+{
+ return pBpb->NumFATs == 0
+ && pBpb->TotSec16 == 0
+ && pBpb->TotSec32 == 0
+ && pBpb->Fat.Ntfs.TotSec64 != 0
+ && pBpb->OEMName[0] == 0x4E // Name must be "NTFS"
+ && pBpb->OEMName[1] == 0x54
+ && pBpb->OEMName[2] == 0x46
+ && pBpb->OEMName[3] == 0x53
+ && pBpb->Signature == 0xAA55
+ && (pBpb->jmp[0] == 0xEB || pBpb->jmp[0] == 0xE9);
+}
+#endif
+
+#if EXT_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsExt
+//
+// Description:
+// Checks if given data block describes EXT Superblock structure
+//
+// Input:
+// VOLUME_SB *pSb - pointer to data block to check
+//
+// Output:
+// TRUE - data block is a EXT Superblock structure
+// FALSE - data block is not a EXT Superblock structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsExt(
+ IN VOLUME_SB *pSb )
+{
+ return pSb->SB_Magic == 0xEF53
+ && pSb->SB_BlockSize < 4
+ && pSb->SB_FirstBlock < 2
+ && pSb->SB_FreeBlocks < pSb->SB_TotalBlocks
+ && pSb->SB_FreeInodes < pSb->SB_TotalInodes;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetClustersCount
+//
+// Description:
+// Returns number of clusters for given cluster chain
+//
+// Input:
+// IN UINT8 FatType - FAT type (FAT12, FAT16 or FAT32)
+// IN UINT32 CurrentCluster - first cluster of cluster chain
+// UINT32 *NextCluster - first cluster of next cluster chain if there is break
+// IN BOOLEAN Continuous - if TRUE, returns only number of subsequent clusters in chain
+// if FALSE, returns total number of clusters in cluster chain
+//
+// Output:
+// UINT32 - number of clusters
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 GetClustersCount(
+ IN UINT8 FatType,
+ IN UINT32 CurrentCluster,
+ OUT UINT32 *NextCluster,
+ IN BOOLEAN Continuous )
+{
+ UINT32 Count = 0;
+ UINT32 WorkCluster;
+ UINT32 Cluster = CurrentCluster;
+
+ if ( FatType == FAT16 ) {
+ UINT16 *Fat16 = (UINT16*)FatBuffer;
+ while ( TRUE )
+ {
+ Count++;
+ WorkCluster = Fat16[Cluster];
+
+ if ( WorkCluster > 0xfff8 ) {
+ *NextCluster = 0;
+ break;
+ }
+
+ if ( WorkCluster != Cluster + 1 && Continuous ) {
+ *NextCluster = WorkCluster;
+ break;
+ }
+ Cluster = WorkCluster;
+ }
+ } else if ( FatType == FAT32 ) {
+ UINT32 *Fat32 = (UINT32*)FatBuffer;
+ while ( TRUE )
+ {
+ Count++;
+ WorkCluster = Fat32[Cluster] & 0xfffffff;
+
+ if ( WorkCluster > 0xffffff8 ) {
+ *NextCluster = 0;
+ break;
+ }
+
+ if ( WorkCluster != Cluster + 1 && Continuous ) {
+ *NextCluster = WorkCluster;
+ break;
+ }
+ Cluster = WorkCluster;
+ }
+ } else {
+ while ( TRUE ) {
+ Count++;
+ WorkCluster = *(UINT16*)(FatBuffer + Cluster + Cluster / 2);
+ WorkCluster = (Cluster & 1) ? WorkCluster >> 4 : WorkCluster & 0xfff;
+
+ if ( WorkCluster > 0xff8 ) {
+ *NextCluster = 0;
+ break;
+ }
+
+ if ( WorkCluster != Cluster + 1 && Continuous ) {
+ *NextCluster = WorkCluster;
+ break;
+ }
+ Cluster = WorkCluster;
+ }
+ }
+ return Count;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFatData
+//
+// Description:
+// Reads data from FAT device
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN RC_VOL_INFO *Volume - pointer to volume description structure
+// IN UINT32 FirstCluster - starting cluster
+// IN UINTN Size - size of the data to read
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_SUCCESS - correctly read all FAT data
+// EFI_ABORTED - should never get this.
+// Other - any errors reported from ReadDevice function
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFatData(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN RC_VOL_INFO *Volume,
+ IN UINT32 FirstCluster,
+ IN UINTN Size,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINT32 Count;
+ UINT32 NextCluster;
+ UINT32 Cluster = FirstCluster;
+ UINTN SizeToRead;
+
+ while ( TRUE )
+ {
+ SizeToRead = Size;
+ Count = GetClustersCount( Volume->FatType, Cluster, &NextCluster, TRUE );
+ SizeToRead = (SizeToRead > Count * Volume->BytesPerCluster) ? Count * Volume->BytesPerCluster : SizeToRead;
+ Status = ReadDevice( PeiServices,
+ Volume,
+ Volume->DataOffset + Mul64((UINT64)(Cluster - 2), Volume->BytesPerCluster),
+ SizeToRead,
+ Buffer );
+
+ if ( EFI_ERROR( Status ) || NextCluster == 0 ) {
+ return Status;
+ }
+
+ Cluster = NextCluster;
+ (UINT8*)Buffer += SizeToRead;
+ Size -= SizeToRead;
+ }
+ return EFI_ABORTED; //should never get here
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFatType
+//
+// Description:
+// Prepares given volume for read operations. Reads FAT table, root directory,
+// determines FAT type
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN BOOT_SECTOR *Bs - pointer to MBR or diskette FAT data
+//
+// Output:
+// EFI_STATUS - possible return values from ReadDevice, AllocatePages, GetFatData
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFatType(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN BOOT_SECTOR *Bs )
+{
+ EFI_STATUS Status;
+ UINT32 TotalSectors;
+ UINT32 FatSectors;
+ UINT32 RootSectors;
+ UINT32 DataSectors;
+ UINT32 RootSize;
+ UINT32 FatSize;
+ UINT32 DataClusters;
+ UINT32 RootClusters;
+ UINT32 DummyCluster;
+ UINTN FatPages;
+ UINTN RootPages;
+ EFI_PHYSICAL_ADDRESS Allocate;
+
+ FatSectors = (Bs->FATSz16 != 0) ? Bs->FATSz16 : Bs->Fat.Fat32.FATSz32;
+ FatSize = FatSectors * Bs->BytsPerSec;
+ TotalSectors = (Bs->TotSec16 != 0) ? Bs->TotSec16 : Bs->TotSec32;
+ RootSectors = ((Bs->RootEntCnt * 32) + (Bs->BytsPerSec - 1)) / Bs->BytsPerSec;
+ RootSize = RootSectors * Bs->BytsPerSec;
+ DataSectors = TotalSectors - RootSectors - FatSectors * Bs->NumFATs - Bs->RsvdSecCnt;
+ DataClusters = DataSectors / Bs->SecPerClus;
+
+ Volume->FatOffset = Bs->RsvdSecCnt * Bs->BytsPerSec;
+ Volume->RootOffset = Volume->FatOffset + FatSectors * Bs->NumFATs * Bs->BytsPerSec;
+ Volume->DataOffset = Volume->RootOffset + RootSize;
+ Volume->BytesPerCluster = Bs->BytsPerSec * Bs->SecPerClus;
+ Volume->FatType = (DataClusters >= 65525) ? FAT32 : ((DataClusters < 4085) ? FAT12 : FAT16);
+
+ RootEntries = Bs->RootEntCnt;
+
+ //
+ //Read FAT table
+ //
+ FatPages = EFI_SIZE_TO_PAGES( FatSize );
+
+ if ( FatBufferSize < EFI_PAGES_TO_SIZE( FatPages )) {
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, FatPages, &Allocate );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ FatBuffer = (UINT8*)((UINTN)Allocate);
+ FatBufferSize = EFI_PAGES_TO_SIZE( FatPages );
+ }
+ MemSet( FatBuffer, FatBufferSize, 0 );
+ Status = ReadDevice( PeiServices, Volume, Volume->FatOffset, FatSize, FatBuffer );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ //Read Root directory
+ //
+ if ( RootSize == 0 ) {
+ //
+ //in case of FAT32 it will be so at this time
+ //
+ RootClusters = GetClustersCount( FAT32, Bs->Fat.Fat32.RootClus, &DummyCluster, FALSE );
+ RootSize = RootClusters * Volume->BytesPerCluster;
+ RootEntries = RootSize / 32;
+ }
+
+ RootPages = EFI_SIZE_TO_PAGES( RootSize );
+
+ if ( RootBufferSize < EFI_PAGES_TO_SIZE( RootPages )) {
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, RootPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ RootBuffer = (UINT8*)((UINTN)Allocate);
+ RootBufferSize = EFI_PAGES_TO_SIZE( RootPages );
+ }
+ MemSet( RootBuffer, RootBufferSize, 0 );
+
+ if ( Volume->FatType == FAT32 ) {
+ Status = GetFatData( PeiServices, Volume, Bs->Fat.Fat32.RootClus, RootSize, RootBuffer );
+ }
+ else {
+ Status = ReadDevice( PeiServices, Volume, Volume->RootOffset, RootSize, RootBuffer );
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessFatVolume
+//
+// Description:
+// Reads recovery capsule from FAT volume
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessFatVolume(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+// BOOT_SECTOR Bs;
+ UINT32 i;
+ UINT32 FirstFileCluster;
+ UINTN NumberOfFiles;
+
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Bs );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if (!IsFat( &MemBlk->Bs )) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetFatType( PeiServices, Volume, &MemBlk->Bs );
+#if SEARCH_FAT_PATH
+ ThisVolume = Volume; // Save volume info for path search
+#endif
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ GetFileListFromFatVolume((DIR_ENTRY*)RootBuffer, RootEntries, &NumberOfFiles, FatRecoveryFiles);
+ //
+ if ( NumberOfFiles == 0 )
+ return EFI_NOT_FOUND;
+
+ for(i = 0; i < NumberOfFiles; i++) {
+ if ( *FileSize < FatRecoveryFiles[i]->FileSize )
+ continue;
+
+ FirstFileCluster = (FatRecoveryFiles[i]->FirstClusterHi << 16) + FatRecoveryFiles[i]->FirstClusterLo;
+
+ Status = GetFatData( PeiServices, Volume, FirstFileCluster, FatRecoveryFiles[i]->FileSize, Buffer );
+ if(EFI_ERROR(Status))
+ continue;
+
+ if(IsValidFile(Buffer, FatRecoveryFiles[i]->FileSize)) {
+ *FileSize = FatRecoveryFiles[i]->FileSize;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+#if NTFS_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetRunListElementData
+//
+// Description: (NTFS) Retrieves the count and cluster of a run from a run list element
+//
+// Parameters: UINT8 **pRunList - Pointer to the run list, updated if
+// UpdateList is TRUE.
+// UINT64 *ClusterCount - Length of this run in clusters.
+// UINT64 *Cluster - Starting cluster of this run.
+// BOOLEAN UpdateList - Update list pointer to next element if TRUE.
+//
+// Return value: EFI_STATUS Status (EFI_SUCCESS or EFI_END_OF_FILE)
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S): A run list element has 3 parts -- a size byte, a Cluster
+// count, and a Cluster Number.
+// The low nibble of the size byte is the size of the Count
+// in bytes. The high nibble is the size of the Offset in
+// bytes. The element is therefore 1 + (low nibble) + (high
+// nibble) bytes long.
+// The cluster number is a signed number. The new cluster is
+// added to the old one to get the result. So if the new
+// cluster lies before the old one on the disk, it will be
+// a negative number.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetRunListElementData (
+ UINT8 **pRunList,
+ UINT64 *ClusterCount,
+ UINT64 *Cluster,
+ BOOLEAN UpdateList
+ )
+{
+ UINT64 TempCount = 0;
+ UINT64 TempCluster = 0;
+ UINT64 LeftFill = 0;
+ UINT8 LowNibble;
+ UINT8 HighNibble;
+ UINT8 i, HighByte;
+ UINT8 *RunListPtr;
+
+//
+// If the size byte is 0, we have reached the end of the file.
+//
+ RunListPtr = *pRunList;
+ if (RunListPtr[0] == 0)
+ {
+ return EFI_END_OF_FILE;
+ }
+
+ LowNibble = RunListPtr[0] & 0xF;
+ HighNibble = RunListPtr[0] >> 4;
+ RunListPtr++;
+//
+// Get run length.
+//
+ for (i=LowNibble; i>0; i--)
+ {
+ TempCount = Shl64(TempCount, 8);
+ TempCount += RunListPtr[i-1];
+ }
+ RunListPtr += LowNibble;
+//
+// Get the run offset.
+//
+ HighByte = RunListPtr[HighNibble-1];
+ for (i=HighNibble; i>0; i--)
+ {
+ TempCluster = Shl64(TempCluster, 8);
+ TempCluster += RunListPtr[i-1];
+ }
+ RunListPtr += HighNibble;
+//
+// If the offset is negative, left-fill the empty bytes with 0xFF.
+//
+ if ((HighByte & 0x80) && (HighNibble < 8))
+ {
+ for (i=8; i>HighNibble; i--)
+ {
+ LeftFill = Shr64(LeftFill, 8);
+ LeftFill |= 0xFF00000000000000;
+ }
+ TempCluster |= LeftFill;
+ }
+
+ *Cluster += TempCluster;
+ *ClusterCount = TempCount;
+ if (UpdateList) *pRunList = RunListPtr;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFrAttribute
+//
+// Description: (NTFS) Retrieves a File Record Attribute by it's number from a
+// File Record.
+//
+// Parameters: UINT8 *BufferIn - Pointer to a buffer containing a file record
+// UINT8 AttributeNumber - Number of the attribute to retrieve
+// UINTN **BufferOut - Points to the attribute in the buffer
+//
+// Return value: EFI_STATUS Status (EFI_SUCCESS or EFI_NOT_FOUND)
+//
+// Modified:
+//
+// Referral(s):
+//
+// Note(s): Attributes are in sequential order, so, for example,
+// if we're looking for 30, and we find 10 and then 40,
+// we know there is no 30 in the record.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetFrAttribute (
+ UINT8 *BufferIn,
+ UINT8 AttributeNumber,
+ UINT8 **BufferOut
+ )
+{
+ UINT8 *TempBuffer;
+
+ TempBuffer = BufferIn;
+
+//
+// Point to 1st attribute.
+//
+ TempBuffer += ((MFT_FILE_RECORD*)TempBuffer)->FR_AttributeOffset;
+//
+// Search for the attribute.
+//
+ while (TempBuffer[0] != AttributeNumber)
+ {
+ if (TempBuffer[0] > AttributeNumber) return EFI_NOT_FOUND;
+ if (TempBuffer[0] == 0xFF) return EFI_NOT_FOUND;
+ if ( ((FR_ATTR_HEADER_RES*)TempBuffer)->AHR_Length == 0 )
+ return EFI_NOT_FOUND;
+ TempBuffer += ((FR_ATTR_HEADER_RES*)TempBuffer)->AHR_Length;
+ }
+
+ *BufferOut = TempBuffer;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFileRecord
+//
+// Description: (NTFS) Returns the file record specified by MFTRecordNo in a buffer.
+//
+// Parameters: VOLUME_INFO *Vi - Volume Info Structure
+// BOOT_SECTOR *Bs - Boot sector structure
+// UINT64 MFTRecordNo - MFT Record number to get
+// UINT8 *Buffer - Buffer to read record into
+// UINT64 *MFTSector - Sector where record found
+//
+// Return value: EFI_STATUS Status (EFI_SUCCESS or EFI_NOT_FOUND)
+//
+// Modified:
+//
+// Referral(s):
+//
+// NOTE(S): The File Records in the Master File Table are numbered
+// sequentially. We just have to count our way through the
+// MFT's run list until we find it.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetFileRecord (
+ EFI_PEI_SERVICES **PeiServices,
+ RC_VOL_INFO *Volume,
+ BOOT_SECTOR *Bs,
+ UINT64 MFTRecordNo,
+ UINT8 *FrBuffer,
+ UINT64 *MFTSector OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *pRunList;
+ UINT64 Cluster;
+ UINT64 Sector;
+ UINT64 Count;
+ UINT64 ByteCount;
+ UINT32 SecPerRecord = 1;
+ UINT64 RecordCount;
+ UINT32 BytesPerCluster;
+ UINT64 Offset;
+ UINT32 RecordSize;
+
+ Cluster = 0;
+ pRunList = &MemBlk->MFTRunList[0];
+
+ MFTRecordNo &= MAXIMUM_RECORD_NUMBER; // Isolate number part
+
+ Status = GetRunListElementData(&pRunList, &Count, &Cluster, TRUE);
+ BytesPerCluster = Bs->BytsPerSec * Bs->SecPerClus;
+ ByteCount = Mul64(Count, BytesPerCluster);
+ if ( Bs->BytsPerSec <= FILE_RECORD_SIZE ) {
+ SecPerRecord = FILE_RECORD_SIZE / Bs->BytsPerSec;
+ RecordSize = FILE_RECORD_SIZE;
+ } else { // Special case for 4k sectors
+ SecPerRecord = 1;
+ RecordSize = (UINT32)Bs->BytsPerSec;
+ }
+//###DEBUG CHANGE NEEDED LATER ////
+// In NTFS, the cluster size can be 512 bytes to 4096 bytes.
+// File records are 1024 bytes
+// For now, we're going to assume a cluster size of 1024 bytes or more.
+////////////////////////////
+
+ Sector = Mul64(Cluster, Bs->SecPerClus);
+ RecordCount = 0;
+ do {
+ if (ByteCount > 0)
+ {
+ Sector += SecPerRecord;
+ ByteCount -= RecordSize;
+ } else { // We've used up a run, read from the next one.
+ Status = GetRunListElementData(&pRunList, &Count, &Cluster, TRUE);
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+ ByteCount = Mul64(Count, BytesPerCluster);
+ Sector = Mul64(Cluster, Bs->SecPerClus);
+ continue;
+ }
+ RecordCount++;
+ } while (RecordCount < MFTRecordNo); // Record numbers are 0-based.
+//
+// We found the sector of the file record wanted. Now read it.
+//
+ Offset = Mul64( Sector, Bs->BytsPerSec );
+ Status = ReadDevice( PeiServices, Volume, Offset, RecordSize, FrBuffer );
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+//
+// A File recored begins with "FILE". Check it.
+//
+ if ( (FrBuffer[0] != 0x46) || \
+ (FrBuffer[1] != 0x49) || \
+ (FrBuffer[2] != 0x4C) || \
+ (FrBuffer[3] != 0x45) ) return EFI_NOT_FOUND;
+
+ *MFTSector = Sector; // Return sector where the record was found
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadNTFSFile
+//
+// Description:
+// Reads a file from a device formatted in NTFS.
+//
+// Input:
+// Parameters: VOLUME_INFO *Vi - Volume Info Structure
+// BOOT_SECTOR *Bs - Boot sector structure
+// UINT8 *RunList - Run List of file to read
+// VIOD *Buffer - Buffer to read into
+// UINT64 *Size - Size of file to read
+//
+// Output:
+// EFI_STATUS - possible return values
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadNTFSFile(
+ IN EFI_PEI_SERVICES **PeiServices,
+ RC_VOL_INFO *Volume,
+ BOOT_SECTOR *Bs,
+ UINT8 *RunList,
+ VOID *Buffer,
+ UINT64 *Size )
+{
+ UINT64 TotalContiguousBytes;
+ UINT64 TotalBytesRead = 0;
+ UINT64 AbsByte;
+ UINT64 AccessBytes;
+ UINT64 ClusterCount;
+ UINT64 Cluster = 0;
+ EFI_STATUS Status;
+
+ Status = GetRunListElementData(&RunList, &ClusterCount,
+ &Cluster, TRUE);
+ do {
+ TotalContiguousBytes = Mul64(ClusterCount,
+ Bs->SecPerClus);
+ TotalContiguousBytes = Mul64(TotalContiguousBytes,
+ Bs->BytsPerSec);
+ if ( TotalContiguousBytes > *Size) AccessBytes = *Size;
+
+ else AccessBytes = TotalContiguousBytes;
+
+ AbsByte = Mul64( Cluster, Bs->SecPerClus );
+ AbsByte = Mul64( AbsByte, Bs->BytsPerSec );
+
+ if (AccessBytes == 0) {
+ return EFI_VOLUME_CORRUPTED; // Will happen if early EOF.
+ }
+
+ Status = ReadDevice( PeiServices,
+ Volume,
+ AbsByte,
+ (UINTN)AccessBytes,
+ Buffer );
+
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+
+ (UINT8 *)Buffer += AccessBytes;
+ TotalBytesRead +=AccessBytes;
+
+ *Size -= AccessBytes;
+
+ if (AccessBytes == TotalContiguousBytes)
+ {
+ Status = GetRunListElementData (&RunList, &ClusterCount,
+ &Cluster, TRUE);
+ if (EFI_ERROR(Status)) break; // Error here means EOF.
+ }
+
+ } while (*Size);
+
+ *Size = (UINT32)TotalBytesRead;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadNTFSRoot
+//
+// Description:
+// Prepares given volume for read operations. Reads NTFS root directory.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN BOOT_SECTOR *Bs - pointer to MBR
+//
+// Output:
+// EFI_STATUS - possible return values
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadNTFSRoot(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN BOOT_SECTOR *Bs )
+{
+ UINT8 FrBuffer[FILE_RECORD_SIZE]; // This needs to be 4096 for 4k secs.
+ UINT8 *Buffer2;
+ UINT8 *Buffer3;
+ UINT8 *pRunList;
+ EFI_STATUS Status;
+ UINT64 TotalSectors;
+ UINT64 DataSectors;
+ UINT64 Temp64;
+ UINT32 Temp32;
+ UINT16 Temp16;
+ UINT32 IndexSize;
+ UINT64 Cluster = 0;
+ UINT64 ClusterCount;
+ UINT64 TmpRootSize;
+ UINTN RootPages;
+ EFI_PHYSICAL_ADDRESS Allocate;
+
+ TotalSectors = Bs->Fat.Ntfs.TotSec64;
+ DataSectors = TotalSectors - Bs->RsvdSecCnt;
+
+ Temp64 = Mul64( Bs->Fat.Ntfs.MFTClus, Bs->SecPerClus );
+ Volume->FatOffset = Mul64( Temp64, Bs->BytsPerSec ); // For NTFS, FatOffset is MFT Offset
+
+ //
+ // Read the first file record of the MFT, to get the MFT run list.
+ //
+ Status = ReadDevice( PeiServices, Volume, Volume->FatOffset, FILE_RECORD_SIZE, FrBuffer );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Buffer2 = &FrBuffer[0];
+ Status = GetFrAttribute( Buffer2, FR_ATTRIBUTE_DATA, &Buffer2 ); // Get data attribute
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Buffer2 += ((FR_ATTR_HEADER_NONRES*)Buffer2)->AHNR_RunOffset; // Point to run list
+ MemCpy( MemBlk->MFTRunList, Buffer2, 256 ); // Copy MFT run list
+ //
+ // Get the root directory file record, to get its run list.
+ //
+ Buffer2 = &FrBuffer[0];
+ Status = GetFileRecord( PeiServices, Volume, Bs, 5, Buffer2, NULL ); // Root is always record no. 5
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ //
+ // Check for a resident index. It will be in the Index Root Attribute.
+ // If one if found, it will be saved for searching later.
+ //
+ ResidentPresent = FALSE;
+ Buffer3 = Buffer2;
+ Status = GetFrAttribute( Buffer2, FR_ATTRIBUTE_INDEX_ROOT, &Buffer3 );
+ if ( Status == EFI_SUCCESS) { // Root Attribute found
+ Temp16 = ((FR_ATTR_HEADER_RES*)Buffer3)->AHR_InfoOffset;
+ Buffer3 += Temp16;
+ IndexSize = ((FR_INDEX_ROOT_ATTRIBUTE*)Buffer3)->IRA_TotalSize;
+ Temp32 = ((FR_INDEX_ROOT_ATTRIBUTE*)Buffer3)->IRA_Offset;
+ Buffer3 += Temp32 + EFI_FIELD_OFFSET(FR_INDEX_ROOT_ATTRIBUTE, IRA_Offset);
+ if (IndexSize >= MINIMUM_ENTRY_SIZE) { // Resident index is not empty
+ MemCpy ( MemBlk->ResidentIndex, Buffer3, IndexSize );
+ ResidentPresent = TRUE;
+ ResidentSize = IndexSize;
+ }
+ }
+ //
+ // Now, check for a non-resident index.
+ //
+ Status = GetFrAttribute( Buffer2, FR_ATTRIBUTE_INDEX_ALLOC, &Buffer2 );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Buffer2 += ((FR_ATTR_HEADER_NONRES*)Buffer2)->AHNR_RunOffset; // Point to run list
+ MemCpy( MemBlk->RootRunList, Buffer2, 128 ); // Copy Root run list
+ //
+ // Calculate root directory size by running its run list.
+ //
+ pRunList = &MemBlk->RootRunList[0];
+ TmpRootSize = 0;
+ Cluster = 0;
+ do {
+ Status = GetRunListElementData( &pRunList, &ClusterCount, &Cluster, TRUE );
+ if ( Status == EFI_SUCCESS ) TmpRootSize += ClusterCount;
+ } while ( Status == EFI_SUCCESS );
+ TmpRootSize = Mul64 ( TmpRootSize, Bs->SecPerClus );
+ TmpRootSize = Mul64 ( TmpRootSize, Bs->BytsPerSec );
+
+ Buffer2 = &FrBuffer[0];
+ RootPages = EFI_SIZE_TO_PAGES( TmpRootSize );
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, RootPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ RootBuffer = (UINT8*)((UINTN)Allocate);
+ RootBufferSize = EFI_PAGES_TO_SIZE( RootPages );
+ MemSet( RootBuffer, RootBufferSize, 0 );
+
+ pRunList = &MemBlk->RootRunList[0];
+ Status = ReadNTFSFile( PeiServices, Volume, Bs, pRunList, RootBuffer, &TmpRootSize );
+ RootSize = (UINT32)TmpRootSize;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessNTFSVolume
+//
+// Description:
+// Reads recovery capsule from NTFS volume
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessNTFSVolume(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+// BOOT_SECTOR Bs;
+ UINT32 i;
+ UINTN NumberOfFiles;
+ UINT64 MFTRecord;
+ UINT8 *TmpBuffer;
+ UINT8 *pRunList;
+ UINT64 TmpFileSize;
+
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Bs );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if (!IsNtfs( &MemBlk->Bs )) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = ReadNTFSRoot( PeiServices, Volume, &MemBlk->Bs );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ GetFileListFromNtfsVolume((UINT8*)RootBuffer, RootSize, &NumberOfFiles, NtfsRecoveryFiles);
+
+ if ( NumberOfFiles == 0 )
+ return EFI_NOT_FOUND;
+
+ for(i = 0; i < NumberOfFiles; i++) {
+ if ( *FileSize < NtfsRecoveryFiles[i]->INDE_RealSize )
+ continue;
+
+ TmpBuffer = (UINT8*)Buffer;
+ TmpFileSize = NtfsRecoveryFiles[i]->INDE_RealSize;
+ //
+ // Get the file's MFT record number, and from that it's run list
+ //
+ MFTRecord = NtfsRecoveryFiles[i]->INDE_MFTRecord & MAXIMUM_RECORD_NUMBER;
+ Status = GetFileRecord( PeiServices, Volume, &MemBlk->Bs, MFTRecord, TmpBuffer, NULL );
+ Status = GetFrAttribute( TmpBuffer, FR_ATTRIBUTE_DATA, &TmpBuffer );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ TmpBuffer += ((FR_ATTR_HEADER_NONRES*)TmpBuffer)->AHNR_RunOffset; // Point to run list
+ MemCpy( MemBlk->RootRunList, TmpBuffer, 128 ); // Copy the file's run list
+ //
+ // Read the file into the provided buffer
+ //
+ pRunList = &MemBlk->RootRunList[0];
+ Status = ReadNTFSFile( PeiServices, Volume, &MemBlk->Bs, pRunList, Buffer, &TmpFileSize );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if(IsValidFile(Buffer, (UINTN)TmpFileSize)) {
+ *FileSize = (UINTN)TmpFileSize;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+#endif
+
+#if EXT_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetNextBlock
+//
+// Description: (EXT) Retrieves the next block number from an Inode
+// block list.
+//
+// Parameters: VOLUME_INFO *Vi - Volume Info Structure
+// VOLUME_SB *Sb - Superblock structure
+// VOLUME_IT *Inode - Inode table structure
+// UINT32 *BlockNo - Sequential number of the block
+// UINT32 *Block - Next block of the file
+// BOOLEAN UpdateList - Update block no. to next block if TRUE.
+//
+// Return value: EFI_STATUS Status (EFI_SUCCESS or EFI_END_OF_FILE)
+//
+// Modified:
+//
+// Referral(s):
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetNextBlock(
+ EFI_PEI_SERVICES **PeiServices,
+ RC_VOL_INFO *Volume,
+ VOLUME_SB *Sb,
+ VOLUME_IT *Inode,
+ UINT32 *BlockNo,
+ UINT32 *Block,
+ BOOLEAN UpdateList )
+{
+ UINT32 *BlockListPtr;
+ UINT32 TmpBlock;
+ UINT32 TmpBlock2;
+ UINT32 TmpBlkNo;
+ UINT32 IBlkCnt;
+ UINT64 Offset;
+ UINT32 BlockSize;
+ UINT32 NosPerBlock;
+ UINTN BlockPages;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS Allocate;
+
+ BlockSize = 1024 << Sb->SB_BlockSize;
+ NosPerBlock = BlockSize / 4;
+ TmpBlkNo = *BlockNo;
+
+ // Process direct blocks (0-11)
+ if ((TmpBlkNo < 12) && (Indirect == 0))
+ {
+ BlockListPtr = &Inode->Alloc.Ext2.Blocks[0];
+ *Block = BlockListPtr[TmpBlkNo];
+ }
+
+ // Process single indirect blocks (12-(256+11))
+ if ((TmpBlkNo >= 12) && (TmpBlkNo < NosPerBlock+12) && (Indirect != 1))
+ {
+ Indirect = 1;
+ TmpBlock = Inode->Alloc.Ext2.Blocks[12];
+ Offset = Mul64(TmpBlock, BlockSize);
+ ReadDevice (PeiServices, Volume, Offset, BlockSize, &BlockList[0]);
+ }
+
+ if ((TmpBlkNo >= 12) && (TmpBlkNo < NosPerBlock+12) && (Indirect == 1))
+ {
+ BlockPages = EFI_SIZE_TO_PAGES( BlockSize );
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, BlockPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ return EFI_END_OF_FILE;
+ }
+ BlockList = (UINT32*)((UINTN)Allocate);
+
+ BlockListPtr = &BlockList[0];
+ TmpBlock = TmpBlkNo - 12;
+ *Block = BlockListPtr[TmpBlock];
+ }
+
+ // Process double indirect blocks ((256+12)-(65536+256+11))
+ if ((TmpBlkNo >= (NosPerBlock+12)) && (Indirect != 2))
+ {
+ Indirect = 2;
+ BlockPages = EFI_SIZE_TO_PAGES( BlockSize );
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, BlockPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ return EFI_END_OF_FILE;
+ }
+ BlockList2 = (UINT32*)((UINTN)Allocate);
+
+ TmpBlock = Inode->Alloc.Ext2.Blocks[13];
+ Offset = Mul64(TmpBlock, BlockSize);
+ ReadDevice (PeiServices, Volume, Offset, BlockSize, &BlockList[0]);
+ }
+
+ if ((TmpBlkNo >= (NosPerBlock+12)) && (Indirect == 2))
+ {
+ TmpBlock = TmpBlkNo - 12;
+ IBlkCnt = TmpBlock / NosPerBlock;
+ if (TmpBlock % NosPerBlock == 0)
+ {
+ // Read another set of nos. into BlockList2
+ TmpBlock2 = BlockList[IBlkCnt];
+ Offset = Mul64(TmpBlock2, BlockSize);
+ ReadDevice (PeiServices, Volume, Offset, BlockSize, &BlockList2[0]);
+ BlockListPtr = &BlockList2[0];
+ }
+ TmpBlock -= (NosPerBlock * IBlkCnt);
+ *Block = BlockListPtr[TmpBlock];
+ }
+
+ if (UpdateList)
+ {
+ TmpBlkNo++;
+ *BlockNo = TmpBlkNo;
+ }
+ if (*Block == 0)
+ {
+ return EFI_END_OF_FILE;
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadExtFile
+//
+// Description:
+// Reads a file from a device formatted in Ext(n).
+//
+// Input:
+// Parameters: VOLUME_INFO *Vi - Volume Info Structure
+// VOLUME_SB *Sb - Superblock structure
+// VOLUME_IT *Inode - Inode table structure
+// VIOD *Buffer - Buffer to read into
+// UINT64 *Size - Size of file to read
+//
+// Output:
+// EFI_STATUS - possible return values
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadExtFile(
+ IN EFI_PEI_SERVICES **PeiServices,
+ RC_VOL_INFO *Volume,
+ VOLUME_SB *Sb,
+ VOLUME_IT *Inode,
+ VOID *Buffer,
+ UINT64 *Size )
+{
+ EFI_STATUS Status;
+ UINT32 BlockSize;
+ UINT32 Block;
+ UINT32 BlockNo;
+ UINT64 Offset;
+ UINT64 TotalBytesRead = 0;
+ UINT16 ExtentCount;
+ UINT64 BigBlock;
+ UINT32 ReadSize;
+ UINT16 i;
+
+ BlockSize = 1024 << Sb->SB_BlockSize;
+ BlockNo = 0;
+
+ //
+ // Check for which allocation method to use for reading the file
+ //
+ if ((Inode->Alloc.Ext4.Header.EH_Magic == 0xF30A) && \
+ (Inode->Alloc.Ext4.Header.EH_Max == 4))
+ {
+ //
+ // Use the EXT4 allocation method
+ //
+ ExtentCount = Inode->Alloc.Ext4.Header.EH_Extents;
+
+ for (i=0; i<ExtentCount; i++)
+ {
+ BigBlock = Inode->Alloc.Ext4.Extent[i].EE_BlockLo + \
+ Shl64(Inode->Alloc.Ext4.Extent[i].EE_BlockHi, 0x20);
+ Offset = Mul64(BigBlock, BlockSize);
+ ReadSize = BlockSize * Inode->Alloc.Ext4.Extent[i].EE_Length;
+ if (*Size <= ReadSize)
+ {
+ Status = ReadDevice (PeiServices, Volume, Offset, (UINTN)*Size, Buffer);
+ if (EFI_ERROR(Status)) {
+ *Size = TotalBytesRead;
+ return Status;
+ } else {
+ TotalBytesRead += *Size;
+ *Size = TotalBytesRead;
+ return EFI_SUCCESS;
+ }
+ }
+
+ Status = ReadDevice (PeiServices, Volume, Offset, ReadSize, Buffer);
+ if (EFI_ERROR(Status)) return Status;
+ *Size -= ReadSize;
+ TotalBytesRead += ReadSize;
+ } // End of read loop
+
+ return EFI_VOLUME_CORRUPTED; // Shouldn't get here
+
+ } else {
+ //
+ // Use the EXT2, EXT3 allocation method
+ //
+ Status = GetNextBlock ( PeiServices,
+ Volume,
+ Sb,
+ Inode,
+ &BlockNo,
+ &Block,
+ TRUE );
+ if (EFI_ERROR(Status)) // Zero-length file
+ {
+ *Size = 0;
+ return Status;
+ }
+
+ do
+ {
+ Offset = Mul64 (BlockSize, Block);
+
+ if (*Size <= BlockSize)
+ {
+ Status = ReadDevice (PeiServices, Volume, Offset, (UINTN)*Size, Buffer);
+ if (EFI_ERROR(Status)) {
+ *Size = TotalBytesRead;
+ return Status;
+ } else {
+ TotalBytesRead += *Size;
+ *Size = TotalBytesRead;
+ return EFI_SUCCESS;
+ }
+ }
+
+ Status = ReadDevice (PeiServices, Volume, Offset, BlockSize, Buffer);
+ if (EFI_ERROR(Status)) return Status;
+ *Size -= BlockSize;
+ TotalBytesRead += BlockSize;
+
+ Status = GetNextBlock ( PeiServices,
+ Volume,
+ Sb,
+ Inode,
+ &BlockNo,
+ &Block,
+ TRUE );
+ if (EFI_ERROR(Status)) // EOF found
+ {
+ *Size = TotalBytesRead;
+ return EFI_SUCCESS;
+ }
+ }
+ while (*Size);
+
+ return EFI_VOLUME_CORRUPTED; // Shouldn't get here
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadExtRoot
+//
+// Description:
+// Prepares given volume for read operations. Reads Ext(n) root directory.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN VOLUME_SB *Sb - pointer to Superblock
+//
+// Output:
+// EFI_STATUS - possible return values
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadExtRoot(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN VOLUME_SB *Sb )
+{
+ EFI_STATUS Status;
+ UINT32 BlockSize;
+ UINT16 InodeSize;
+ UINT32 BgdtBlock;
+ VOLUME_BGDT Bgdt;
+// VOLUME_IT RootInode;
+ UINT64 Offset;
+ UINT64 TmpRootSize;
+ UINTN RootPages;
+ EFI_PHYSICAL_ADDRESS Allocate;
+
+ BlockSize = 1024 << Sb->SB_BlockSize;
+ if (BlockSize == 1024)
+ {
+ BgdtBlock = 2;
+ } else {
+ BgdtBlock = 1;
+ }
+
+ // Read in the Block Group Descriptor Table
+ Offset = Mul64(BlockSize, BgdtBlock);
+ Status = ReadDevice (PeiServices,
+ Volume,
+ Offset,
+ sizeof(VOLUME_BGDT),
+ &Bgdt);
+ if (EFI_ERROR(Status))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ InodeBlock = Bgdt.BGDT_InodeTableBlk;
+ InodeSize = Sb->SB_InodeStrucSize;
+
+ // The root directory's inode is always the 2nd inode in the
+ // inode table. Read in that inode.
+ Offset = Mul64(BlockSize, InodeBlock) + InodeSize;
+ Status = ReadDevice (PeiServices,
+ Volume,
+ Offset,
+ sizeof(VOLUME_IT),
+ &MemBlk->RootInode);
+ if (EFI_ERROR(Status))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ TmpRootSize = MemBlk->RootInode.IT_SizeLo + Shl64(MemBlk->RootInode.IT_SizeHi, 0x20);
+
+ RootPages = EFI_SIZE_TO_PAGES( TmpRootSize );
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, RootPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ RootBuffer = (UINT8*)((UINTN)Allocate);
+ RootBufferSize = EFI_PAGES_TO_SIZE( RootPages );
+ MemSet( RootBuffer, RootBufferSize, 0 );
+
+ Status = ReadExtFile( PeiServices,
+ Volume,
+ Sb,
+ &MemBlk->RootInode,
+ RootBuffer,
+ &TmpRootSize );
+ RootSize = (UINT32)TmpRootSize;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessExtVolume
+//
+// Description:
+// Reads recovery capsule from Ext(n) volume
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessExtVolume(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+// VOLUME_SB Sb;
+// VOLUME_IT FileInode;
+ UINT32 i;
+ UINT32 Inode;
+ UINT64 TmpFileSize;
+ UINTN NumberOfFiles;
+ UINT64 Offset;
+ UINT32 BlockSize;
+ UINT16 InodeSize;
+ UINT8 *TmpPtr;
+
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Sb );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ // On an EXT(n) volume, the first sector will be all zeros
+ TmpPtr = (UINT8*)&MemBlk->Sb.SB_TotalInodes;
+ for (i=0; i<512; i++)
+ {
+ if ((UINT8)TmpPtr[i] != 0)
+ {
+ return EFI_NOT_FOUND; // Not an EXT(n) volume
+ }
+ }
+
+ // The Superblock is always 1024 bytes in on the volume
+ Status = ReadDevice( PeiServices, Volume, 1024, 512, &MemBlk->Sb );
+
+ if (!IsExt( &MemBlk->Sb )) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = ReadExtRoot( PeiServices, Volume, &MemBlk->Sb );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ GetFileListFromExtVolume((UINT8*)RootBuffer, RootSize, &NumberOfFiles, ExtRecoveryFiles);
+
+ if ( NumberOfFiles == 0 )
+ return EFI_NOT_FOUND;
+
+ BlockSize = 1024 << MemBlk->Sb.SB_BlockSize;
+ InodeSize = MemBlk->Sb.SB_InodeStrucSize;
+ for(i = 0; i < NumberOfFiles; i++) {
+ // An EXT(n) directory entry only contains the name and inode, so we have to
+ // read the inode to get the size.
+ Inode = ExtRecoveryFiles[i]->DIR_Inode;
+ Offset = Mul64(BlockSize, InodeBlock) + \
+ Mul64((Inode-1), InodeSize);
+ Status = ReadDevice (PeiServices,
+ Volume,
+ Offset,
+ sizeof(VOLUME_IT),
+ &MemBlk->FileInode);
+ if (EFI_ERROR(Status)) continue;
+
+ TmpFileSize = MemBlk->FileInode.IT_SizeLo + Shl64(MemBlk->FileInode.IT_SizeHi, 0x20);
+ if ( *FileSize < (UINTN)TmpFileSize )
+ continue;
+ Status = ReadExtFile( PeiServices,
+ Volume,
+ &MemBlk->Sb,
+ &MemBlk->FileInode,
+ Buffer,
+ &TmpFileSize );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if(IsValidFile(Buffer, (UINTN)TmpFileSize)) {
+ *FileSize = (UINTN)TmpFileSize;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindNextPartition
+//
+// Description:
+// Finds the next partition on the volume, and sets the VolumeOffset in
+// the RC_VOL_INFO structure.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+//
+// Output:
+// EFI_STATUS
+//
+// Note:
+// This function uses the following global variables:
+// UINTN PartCount - Counter to keep track of search
+// BOOLEAN IsMbr - True if looking for MBR partitions
+// UINT32 GpeCount - GUID Partition Entry count
+// UINT32 PartSector - Starting sector of partition
+// PartCount and PartSector must be seeded to 0, and IsMbr must be
+// seeded to TRUE before the first call.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindNextPartition(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume )
+{
+ EFI_STATUS Status;
+ UINT64 Offset;
+ GUID_BOOT_RECORD *Gbr;
+ GUID_TABLE_HEADER *Gth;
+ UINT32 GpeSize;
+ UINT32 i;
+ UINT32 TempSector;
+
+ //
+ // Check for MBR partitions
+ //
+ if ( IsMbr ) {
+ while ( PartCount < 4 ) {
+ if ( MemBlk->Mbr.PartRec[PartCount].OSType == 0xEE ) {
+ IsMbr = FALSE; // Mark GUID partition found
+ PartCount = 0; // Reset counter
+ break;
+ }
+
+ if ( MemBlk->Mbr.PartRec[PartCount].OSType == 5
+ || MemBlk->Mbr.PartRec[PartCount].OSType == 15 ) { // Extended partition
+ PartSector += MemBlk->Mbr.PartRec[PartCount].StartingLba;
+ Volume->PartitionOffset = Mul64( 512, PartSector );
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Mbr );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ PartCount = 0;
+ }
+
+ if ( MemBlk->Mbr.PartRec[PartCount].OSType == 0
+ || MemBlk->Mbr.PartRec[PartCount].SizeInLba == 0
+ || MemBlk->Mbr.PartRec[PartCount].StartingLba == 0 ) {
+ PartCount++; // Check next partition
+ continue;
+ }
+
+ TempSector = MemBlk->Mbr.PartRec[PartCount].StartingLba + PartSector;
+ Volume->PartitionOffset = Mul64( 512, TempSector );
+ PartCount++;
+ return EFI_SUCCESS;
+ }
+ }
+ if ( IsMbr ) return EFI_NOT_FOUND; // No MBR partitions were found
+
+ //
+ // Check for GUID partitions
+ //
+ if ( PartCount == 0 ) {
+ Offset = Mul64( 1, Volume->BlockSize );
+ Status = ReadDevice( PeiServices, Volume, Offset, 512, &MemBlk->Mbr );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ Gth = (GUID_TABLE_HEADER*)&MemBlk->Mbr.BootCode[0];
+ if ( (Gth->Signature[0] == 0x45) && // Check for "EFI"
+ (Gth->Signature[1] == 0x46) &&
+ (Gth->Signature[2] == 0x49) )
+ {
+ GpeCount = Gth->EntryCount;
+ GpeSize = Gth->EntrySize;
+ //
+ // We only support entry size of 128 for now.
+ //
+ if ( GpeSize != 128 ) return EFI_NOT_FOUND; //
+ Offset = Mul64( 2, Volume->BlockSize );
+ //
+ // Read in the first entry in the partition table
+ //
+ Status = ReadDevice( PeiServices, Volume, Offset, 512, &MemBlk->Mbr );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ } else return EFI_NOT_FOUND; // Table header not found.
+ }
+
+ while ( PartCount < GpeCount ) {
+ i = PartCount % 4;
+ if ( (i == 0) && (PartCount != 0) ) {
+ Offset = Mul64( 2+(PartCount/4), Volume->BlockSize );
+ Volume->PartitionOffset = 0; // Reset this to zero
+ Status = ReadDevice( PeiServices, Volume, Offset, 512, &MemBlk->Mbr );
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+ }
+ PartCount++;
+ Gbr = (GUID_BOOT_RECORD*)&MemBlk->Mbr.BootCode[0];
+ Volume->PartitionOffset = Mul64( Gbr->GuidPart[i].FirstLba, Volume->BlockSize );
+ //
+ // The partition count is incremented by 4 for each new Guid Boot Record,
+ // even if it does not contain 4 partition records. So we may find an empty
+ // partition. Exit with EFI_NOT_FOUND if there is one.
+ //
+ if ( Volume->PartitionOffset == 0 ) {
+ return EFI_NOT_FOUND;
+ }
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessFatDevice
+//
+// Description:
+// Reads recovery capsule from FAT device. First treat device as
+// non-partitioned device. If failed tries to discover primary partitions and
+// search for capsule there.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessFatDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+
+ //
+ // Assume the volume is floppy-formatted
+ //
+ Status = ProcessFatVolume( PeiServices, Volume, FileSize, Buffer );
+
+ if ( !EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ // Not floppy formatted, look for partitions. Rread sector 0 (MBR).
+ //
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Mbr );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if ( MemBlk->Mbr.Sig != 0xaa55 ) {
+ return EFI_NOT_FOUND;
+ }
+
+ PartCount = 0;
+ PartSector = 0;
+ IsMbr = TRUE;
+
+ //
+ // Locate all partitions. Check each one for the recovery file.
+ // The recovery file will be loaded if it is found, and this
+ // function will return EFI_SUCCESS.
+ //
+ do {
+ Status = FindNextPartition( PeiServices, Volume );
+ if ( !EFI_ERROR(Status) ) {
+ Status2 = ProcessFatVolume( PeiServices, Volume, FileSize, Buffer );
+ if ( !EFI_ERROR(Status2) ) {
+ return Status2;
+ }
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_NOT_FOUND;
+}
+
+#if NTFS_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessNTFSDevice
+//
+// Description:
+// Reads recovery capsule from NTFS device. Tries to discover primary partitions
+// and search for capsule there.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessNTFSDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+
+ //
+ // Assume the volume is floppy-formatted.
+ //
+ Status = ProcessNTFSVolume( PeiServices, Volume, FileSize, Buffer );
+
+ if ( !EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ // Not floppy formatted, look for partitions. Read sector 0 (MBR).
+ //
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Mbr );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if ( MemBlk->Mbr.Sig != 0xaa55 ) {
+ return EFI_NOT_FOUND;
+ }
+
+ PartCount = 0;
+ PartSector = 0;
+ IsMbr = TRUE;
+
+ //
+ // Locate all partitions. Check each one for the recovery file.
+ // The recovery file will be loaded if it is found, and this
+ // function will return EFI_SUCCESS.
+ //
+ do {
+ Status = FindNextPartition( PeiServices, Volume );
+ if ( !EFI_ERROR(Status) ) {
+ Status2 = ProcessNTFSVolume( PeiServices, Volume, FileSize, Buffer );
+ if ( !EFI_ERROR(Status2) ) {
+ return Status2;
+ }
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_NOT_FOUND;
+}
+#endif
+
+#if EXT_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessExtDevice
+//
+// Description:
+// Reads recovery capsule from Ext(n) device. Tries to discover primary partitions
+// and search for capsule there.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessExtDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ EFI_STATUS Status2;
+
+ //
+ // Assume the volume is floppy-formatted.
+ //
+ Status = ProcessExtVolume( PeiServices, Volume, FileSize, Buffer );
+
+ if ( !EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ // Not floppy formatted, look for partitions. Read sector 0 (MBR).
+ //
+ Status = ReadDevice( PeiServices, Volume, 0, 512, &MemBlk->Mbr );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if ( MemBlk->Mbr.Sig != 0xaa55 ) {
+ return EFI_NOT_FOUND;
+ }
+
+ PartCount = 0;
+ PartSector = 0;
+ IsMbr = TRUE;
+
+ //
+ // Locate all partitions. Check each one for the recovery file.
+ // The recovery file will be loaded if it is found, and this
+ // function will return EFI_SUCCESS.
+ //
+ do {
+ Status = FindNextPartition( PeiServices, Volume );
+ if ( !EFI_ERROR(Status) ) {
+ Status2 = ProcessExtVolume( PeiServices, Volume, FileSize, Buffer );
+ if ( !EFI_ERROR(Status2) ) {
+ return Status2;
+ }
+ }
+ } while (Status == EFI_SUCCESS);
+
+ return EFI_NOT_FOUND;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessPrimaryVolume
+//
+// Description:
+// Reads recovery capsule from ISO9660 device
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessPrimaryVolume(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ PRIMARY_VOLUME_DESCRIPTOR PriVol;
+ UINT32 RootSize;
+ UINTN RootPages;
+ EFI_PHYSICAL_ADDRESS Allocate;
+ UINTN NumberOfFiles;
+ UINT32 i;
+
+ Volume->PartitionOffset = 0;
+ Status = ReadDevice( PeiServices, Volume, 16 * Volume->BlockSize, Volume->BlockSize, &PriVol );
+
+ //
+ //check that we read CD
+ //
+ if ( PriVol.Type != 1 || MemCmp( PriVol.StandardId, "CD001", 5 )) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ //read root directory
+ //
+ RootSize = PriVol.RootDir.DataLength;
+ RootPages = EFI_SIZE_TO_PAGES( RootSize );
+
+ if ( RootBufferSize < EFI_PAGES_TO_SIZE( RootPages )) {
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, RootPages, &Allocate );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ RootBuffer = (UINT8*)((UINTN)Allocate);
+ RootBufferSize = EFI_PAGES_TO_SIZE( RootPages );
+ }
+ MemSet( RootBuffer, RootBufferSize, 0 );
+
+ Status = ReadDevice( PeiServices, Volume, PriVol.RootDir.ExtentOffset * Volume->BlockSize, RootSize, RootBuffer );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ GetFileListFromPrimaryVolume((DIR_RECORD*)RootBuffer, RootSize, &NumberOfFiles, CdRecoveryFiles);
+
+ if(NumberOfFiles == 0)
+ return EFI_NOT_FOUND;
+
+ for(i = 0; i < NumberOfFiles; i++) {
+ if ( *FileSize < CdRecoveryFiles[i]->DataLength )
+ continue;
+
+ Status = ReadDevice( PeiServices, Volume, CdRecoveryFiles[i]->ExtentOffset * Volume->BlockSize, CdRecoveryFiles[i]->DataLength, Buffer );
+ if(EFI_ERROR(Status))
+ continue;
+
+ if(IsValidFile(Buffer, CdRecoveryFiles[i]->DataLength)) {
+ *FileSize = CdRecoveryFiles[i]->DataLength;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessCd
+//
+// Description:
+// Reads recovery capsule ATAPI device. First search for recovery capsule in
+// primary volume. If not found tries to process Eltorito images
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN OUT RC_VOL_INFO *Volume - pointer to volume description structure
+// CHAR8 *FileName - recovery capsule file name
+// UINTN *FileSize - pointer to size of provided buffer
+// OUT VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ProcessCd(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT RC_VOL_INFO *Volume,
+ IN OUT UINTN *FileSize,
+ OUT VOID *Buffer )
+{
+ EFI_STATUS Status;
+ UINT8 Data[2048]; //space for 1 block
+ BOOT_RECORD_VOLUME_DESCRIPTOR *BootDesc;
+ INITIAL_DEFAULT_ENTRY *Entry;
+
+ Status = ProcessPrimaryVolume( PeiServices, Volume, FileSize, Buffer );
+
+ if ( !EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ //file not found in primary volume, check Eltorito partitions
+ //
+ Status = ReadDevice( PeiServices, Volume, 17 * Volume->BlockSize, Volume->BlockSize, Data );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ //
+ //check if it is Eltorito
+ //
+ BootDesc = (BOOT_RECORD_VOLUME_DESCRIPTOR*)Data;
+
+ if ( BootDesc->BootRecordIndicator != 0
+ || MemCmp( &(BootDesc->ISO9660Identifier), "CD001", 5 )
+ || BootDesc->DescriptorVersion != 1
+ || MemCmp( &(BootDesc->BootSystemIdentifier), "EL TORITO SPECIFICATION", 23 )) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ //it is Eltorito, read boot catalog
+ //
+ Status = ReadDevice( PeiServices, Volume, BootDesc->BootCatalogFirstSector * Volume->BlockSize, Volume->BlockSize, Data );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ Entry = (INITIAL_DEFAULT_ENTRY*) &Data[32];
+ Volume->PartitionOffset = Entry->LoadRBA * Volume->BlockSize;
+ Status = ProcessFatDevice( PeiServices, Volume, FileSize, Buffer );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FsRecoveryRead
+//
+// Description:
+// Search for recovery capsule file on all file system devices
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN CHAR8 *FileName - recovery capsule file name
+// IN UINTN DeviceIndex - device index for given BlockIo PPI
+// IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *pBlockIo - pointer to BlockIo PPI
+// UINTN *FileSize - pointer to size of provided buffer
+// VOID *Buffer - pointer to buffer to store data
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FsRecoveryRead(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *pBlockIo,
+ IN OUT UINTN *pSize,
+ OUT VOID *pBuffer )
+{
+ EFI_STATUS Status;
+ RC_VOL_INFO Volume;
+ EFI_PEI_BLOCK_IO_MEDIA Media;
+ UINTN BlockPages;
+ EFI_PHYSICAL_ADDRESS Allocate;
+
+ if ( !pBlockIo || !pSize || *pSize && !pBuffer ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MemSet( &Volume, sizeof(RC_VOL_INFO), 0 );
+
+ Status = pBlockIo->GetBlockDeviceMediaInfo( PeiServices, pBlockIo, DeviceIndex, &Media );
+
+ if ( EFI_ERROR( Status )) {
+ return Status;
+ }
+
+ if ( !Media.MediaPresent ) {
+ return EFI_NOT_FOUND;
+ }
+
+ Volume.BlkIo = pBlockIo;
+ Volume.Device = DeviceIndex;
+ Volume.BlockSize = Media.BlockSize;
+
+ //
+ // Allocate memory for MBR, Boot Sector, etc.
+ //
+ BlockPages = EFI_SIZE_TO_PAGES( sizeof(MEMORY_BLOCK) );
+ Status = (*PeiServices)->AllocatePages( PeiServices, EfiBootServicesData, BlockPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ return EFI_NOT_FOUND;
+ }
+ MemBlk = (MEMORY_BLOCK*)((UINTN)Allocate);
+
+ if ( Media.BlockSize == 2048 && CdRecoverySupport ) {
+ Volume.PartitionOffset = 0;
+ Status = ProcessCd( PeiServices, &Volume, pSize, pBuffer );
+ if ( Status == EFI_SUCCESS ) return Status;
+ }
+ if ( FatRecoverySupport ) {
+ Volume.PartitionOffset = 0;
+ Status = ProcessFatDevice( PeiServices, &Volume, pSize, pBuffer );
+ if ( Status == EFI_SUCCESS ) return Status;
+#if NTFS_RECOVERY_SUPPORT
+ }
+ if ( NtfsRecoverySupport ) {
+ Volume.PartitionOffset = 0;
+ Status = ProcessNTFSDevice( PeiServices, &Volume, pSize, pBuffer );
+ if ( Status == EFI_SUCCESS ) return Status;
+#endif
+#if EXT_RECOVERY_SUPPORT
+ }
+ if ( ExtRecoverySupport ) {
+ Volume.PartitionOffset = 0;
+ Status = ProcessExtDevice( PeiServices, &Volume, pSize, pBuffer );
+ if ( Status == EFI_SUCCESS ) return Status;
+#endif
+
+ } else {
+ Status = EFI_NOT_FOUND;
+ }
+ return Status;
+}
+
+
+/************************************************************************/
+/* Device Recovery Module PPI */
+/************************************************************************/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetNumberRecoveryCapsules
+//
+// Description:
+// GetNumberRecoveryCapsules function of ppi
+// EFI_PEI_DEVICE_RECOVERY_MODULE_PPI.
+//
+// Input:
+//
+// Output:
+// EFI_SUCCESS - number of recovery capsules returned
+// EFI_INVALID_PARAMETER - the pointer NumberRecoveryCapsules is NULL
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS GetNumberRecoveryCapsules(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ OUT UINTN *NumberRecoveryCapsules )
+{
+ if ( !NumberRecoveryCapsules ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ *NumberRecoveryCapsules = 1;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetRecoveryCapsuleInfo
+//
+// Description:
+// GetRecoveryCapsuleInfo function of ppi EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
+// for any block devices including floppies, USB keys, CD-ROMs and HDDs.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PeiServices Structure
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This - pointer to the PPI structure
+// IN UINTN CapsuleInstance - value indicating the instance of the PPI
+// OUT UINTN *Size - Size of the recovery capsule
+// OUT EFI_GUID *CapsuleType OPTIONAL - Type of recovery capsule
+//
+// Output:
+// EFI_SUCCESS - Parameters are valid and output parameters are updated
+// EFI_INVALID_PARAMETER - Size pointer is NULL
+// EFI_NOT_FOUND - asking for a 1 or greater instance of the PPI
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetRecoveryCapsuleInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT UINTN *Size,
+ OUT EFI_GUID *CapsuleType )
+{
+ EFI_STATUS Status;
+
+ if ( !Size ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( CapsuleInstance > 0 ) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetRecoveryFileInfo(PeiServices, NULL, Size, NULL);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ if ( CapsuleType ) {
+ *CapsuleType = guidBlockDeviceCapsule;
+ }
+ return EFI_SUCCESS;
+}
+
+#define NUMBER_OF_RETRIES 3
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LoadRecoveryCapsule
+//
+// Description:
+// Locates all EFI_PEI_RECOVERY_BLOCK_IO_PPI PPIs. Calls function
+// GetNumberOfBlockDevices. For each block device, calls the function
+// FsRecoveryRead, to find the recovery image named in var sAmiRomFile.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PeiServices Structure
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This - pointer to the PPI structure
+// IN UINTN CapsuleInstance - value indicating the instance of the PPI
+// OUT VOID *Buffer - contains information read from the block device
+//
+// Output:
+// EFI_SUCCESS - File read from recovery media
+// EFI_INVALID_PARAMETER - Buffer is a NULL pointer
+// EFI_NOT_FOUND - asking for a 1 or greater instance of the PPI
+// Other - return error values from LocatePpi or FsRecoveryRead
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS LoadRecoveryCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT VOID *Buffer )
+{
+ static EFI_GUID guidBlockIo = EFI_PEI_VIRTUAL_BLOCK_IO_PPI;
+ EFI_STATUS Status;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ UINTN i;
+ UINTN RecoveryCapsuleSize;
+ BOOLEAN ExtendedVerification;
+
+ PEI_TRACE((-1, PeiServices, "..BLOCK DEVICE.."));
+
+ if ( !Buffer ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( CapsuleInstance > 0 ) {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetRecoveryFileInfo(PeiServices, NULL, &RecoveryCapsuleSize, &ExtendedVerification);
+ if ( EFI_ERROR( Status ))
+ return Status;
+
+ i = 0;
+
+ do
+ {
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI *pBlockIo;
+ UINTN NumberBlockDevices;
+ UINTN j;
+ UINTN Size;
+ Status = (*PeiServices)->LocatePpi( PeiServices, &guidBlockIo, i++, &pDummy, &pBlockIo );
+
+ if ( EFI_ERROR( Status )) {
+ break;
+ }
+
+ if (EFI_ERROR( Status = pBlockIo->GetNumberOfBlockDevices(
+ PeiServices, pBlockIo, &NumberBlockDevices))) {
+ continue;
+ }
+
+ for ( j = 0; j < NumberBlockDevices; j++ ) {
+ UINTN k;
+ Size = RecoveryCapsuleSize;
+
+ for ( k = 0; k < NUMBER_OF_RETRIES; k++ )
+ {
+ Status = FsRecoveryRead(
+ PeiServices, j, pBlockIo,
+ &Size, Buffer
+ );
+
+ if ( !EFI_ERROR(Status) ){
+ if(ExtendedVerification || Size == RecoveryCapsuleSize )
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ } while ( TRUE );
+ return Status;
+}
+
+/************************************************************************/
+/* Entry Point */
+/************************************************************************/
+EFI_PEI_DEVICE_RECOVERY_MODULE_PPI BlockDeviceRecoveryModule = {
+ GetNumberRecoveryCapsules, GetRecoveryCapsuleInfo, LoadRecoveryCapsule
+};
+
+// PPI to be installed
+static EFI_PEI_PPI_DESCRIPTOR BlockDeviceRecoveryPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidRecoveryDevice, &BlockDeviceRecoveryModule
+ }
+};
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: BlockDeviceRecoveryEntry
+//
+// Description:
+// Installs EFI_PEI_DEVICE_RECOVERY_MODULE_PPI for loading recovery
+// images from block devices such as floppies, USB keys, HDDs or CD-ROMs
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BlockDeviceRecoveryEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ ThisPeiServices = PeiServices;
+ return (*PeiServices)->InstallPpi( PeiServices, BlockDeviceRecoveryPpiList );
+}
+
+//************************** AMI custom eLink implementation *******************
+
+VOID AmiGetFileListFromPrimaryVolume(
+ IN DIR_RECORD *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_RECORD **Buffer
+)
+{
+ UINT32 Count = 0;
+ CHAR8 *DirFileName;
+ UINT32 FileNameSize;
+
+ VOID *FileName;
+ UINTN FileSize;
+ EFI_STATUS Status;
+
+
+ *NumberOfFiles = 0; //no files found yet
+
+ Status = GetRecoveryFileInfo(ThisPeiServices, &FileName, &FileSize, NULL);
+ if(EFI_ERROR(Status))
+ return;
+
+ //
+ //find file in root directory
+ //
+ while ( Count < RootSize ) {
+ DirFileName = (CHAR8*)(Root + 1);
+
+ if(Root->Length == 0)
+ return;
+
+ // Find the length of the file name. The ISO9660 spec has the following structure
+ // up to 8 characters then a '.' then up to 3 more characters then a ';'
+ // then the digits that make up a number between 0 and 32767
+ // The filename search uses all characters up to the ';'
+ FileNameSize = 0;
+ while(DirFileName[FileNameSize] != ';' && (FileNameSize < Root->LengthOfFileId))
+ FileNameSize++;
+
+ if (!EFI_ERROR(FileSearch((CHAR8*)FileName, DirFileName, FALSE, FileNameSize))) {
+ Buffer[*NumberOfFiles] = Root;
+ (*NumberOfFiles)++;
+ break;
+ }
+
+ Count += Root->Length;
+ (UINT8 *)Root += Root->Length;
+ }
+}
+
+#if SEARCH_FAT_PATH
+BOOLEAN IsolateName (
+ IN CHAR8 **FilePath,
+ OUT CHAR8 **NextName
+)
+{
+ UINTN len;
+ BOOLEAN GotName;
+ UINTN i;
+ CHAR8 *TempPath;
+
+ TempPath = *FilePath;
+ len = Strlen(TempPath);
+ GotName = TRUE;
+ for ( i = 0; i < len; i++ ) {
+ if ( TempPath[i] == 0x5C ) { // "\"
+ GotName = FALSE;
+ TempPath[i] = 0;
+ *NextName = TempPath + i + 1;
+ return GotName;
+ }
+ }
+ return GotName;
+}
+
+#endif
+
+VOID AmiGetFileListFromFatVolume(
+ IN DIR_ENTRY *Root,
+ IN UINT32 RootEntries,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY **Buffer
+)
+{
+ UINT32 i;
+
+ VOID *FileName;
+ UINTN FileSize;
+ EFI_STATUS Status;
+ UINT32 DirEntries;
+ DIR_ENTRY *DirPtr;
+ CHAR8 *FilePath;
+#if SEARCH_FAT_PATH
+ UINT32 DirSize;
+ CHAR8 *NextName;
+ UINTN DirPages;
+ EFI_PHYSICAL_ADDRESS Allocate;
+ UINT32 Cluster;
+#endif
+
+ *NumberOfFiles = 0; //no files found yet
+
+ Status = GetRecoveryFileInfo(ThisPeiServices, &FileName, &FileSize, NULL);
+ if(EFI_ERROR(Status))
+ return;
+
+ FilePath = FileName;
+ DirEntries = RootEntries;
+ DirPtr = Root;
+#if SEARCH_FAT_PATH
+ FilePath = (CHAR8*)FileName;
+ NextName = FilePath;
+
+ while ( IsolateName (&FilePath, &NextName) == FALSE ) {
+ //
+ //Find path name in directory
+ //
+ for(i = 0; i < DirEntries; i++) {
+ if((DirPtr[i].FileName[0] == 0xE5) || (DirPtr[i].FileName[0] == 0))
+ continue;
+
+ if(!EFI_ERROR(FileSearch((CHAR8*)FilePath, DirPtr[i].FileName, TRUE, FAT_FILE_NAME_SIZE))) {
+ //
+ // A match was found...
+ // Update FilePath to next name.
+ // Update DirPtr to this directory, and read it in
+ //
+ // *REMOVED* DirSize = DirPtr[i].FileSize;
+ //
+ // The size of a directory is not stored in it's directory entry,
+ // So we will only read in one cluster for now.
+ //
+ DirSize = ThisVolume->BytesPerCluster;
+ DirEntries = DirSize / 32;
+ Cluster = DirPtr[i].FirstClusterLo + (DirPtr[i].FirstClusterHi << 16);
+
+ DirPages = EFI_SIZE_TO_PAGES( DirSize );
+
+ if ( DirSize < EFI_PAGES_TO_SIZE( DirPages )) {
+ Status = (*ThisPeiServices)->AllocatePages( ThisPeiServices,
+ EfiBootServicesData, DirPages, &Allocate );
+ if ( EFI_ERROR( Status )) {
+ *NumberOfFiles = 0;
+ return;
+ }
+
+ DirPtr = (DIR_ENTRY*)((UINTN)Allocate);
+ DirSize = EFI_PAGES_TO_SIZE( DirPages );
+ }
+ MemSet( DirPtr, DirSize, 0 );
+
+ Status = GetFatData( ThisPeiServices, ThisVolume, Cluster, DirSize, DirPtr );
+ if ( EFI_ERROR( Status )) {
+ *NumberOfFiles = 0;
+ return;
+ }
+ FilePath = NextName;
+ break;
+ }
+ }
+ }
+#endif
+ //
+ // Find file in directory
+ //
+ for(i = 0; i < DirEntries; i++) {
+ if((DirPtr[i].FileName[0] == 0xE5) || (DirPtr[i].FileName[0] == 0))
+ continue;
+
+ if(!EFI_ERROR(FileSearch((CHAR8*)FilePath, DirPtr[i].FileName, TRUE, FAT_FILE_NAME_SIZE))) {
+ Buffer[*NumberOfFiles] = &DirPtr[i];
+ *NumberOfFiles = 1;
+ break;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AmiGetFileListFromNtfsVolume
+//
+// Description:
+// Gets a list of valid recovery files from an NTFS volume.
+// As currently written, gets only one file.
+//
+// Input:
+// UINT8 *Root - Pointer to a buffer containing the root directory
+// UINT32 RootSize - Size of the root directory
+// UINTN *NumberOfFiles - Pointer to number of files found
+// INDEX_ENTRY **Buffer - Pointer to buffer containing index entry of
+// the file that was found.
+//
+// Output:
+// None - returned in variables.
+//
+// Notes:
+// This is an e-linked function, which can be replaced.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AmiGetFileListFromNtfsVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT INDEX_ENTRY **Buffer
+)
+{
+#if NTFS_RECOVERY_SUPPORT
+ UINT8 i;
+ UINT32 IndexSize;
+ UINT32 IndexSize2;
+ UINTN Offset;
+ UINT8 *TmpPtr;
+ CHAR16 *NamePtr;
+ CHAR8 TmpFileName[13];
+ UINT8 LfnSize;
+ UINT16 EntrySize;
+ INDEX_ENTRY *IndxPtr;
+ VOID *FileName;
+ UINTN FileSize;
+ EFI_STATUS Status;
+
+ *NumberOfFiles = 0; //no files found yet
+
+ Status = GetRecoveryFileInfo(ThisPeiServices, &FileName, &FileSize, NULL);
+ if(EFI_ERROR(Status))
+ return;
+
+ if (ResidentPresent) { // If resident index found...
+ TmpPtr = &MemBlk->ResidentIndex[0];
+ IndexSize = ResidentSize;
+
+ do { // loop inside the index
+ EntrySize = ((INDEX_ENTRY*)TmpPtr)->INDE_EntrySize;
+ LfnSize = ((INDEX_ENTRY*)TmpPtr)->INDE_NameLength;
+ if (LfnSize > 12) LfnSize = 12; // Limit name to 12 chars
+ NamePtr = &((INDEX_ENTRY*)TmpPtr)->INDE_Name[0];
+ for ( i=0; i<LfnSize; i++ )
+ {
+ TmpFileName[i] = (CHAR8)(CHAR16)NamePtr[i];
+ }
+ TmpFileName[i] = 0; // Zero-terminate name
+
+ if(!EFI_ERROR(FileSearch((CHAR8*)FileName, TmpFileName, FALSE, LfnSize))) {
+ IndxPtr = (INDEX_ENTRY*)&TmpPtr[0];
+ Buffer[*NumberOfFiles] = IndxPtr; // Save pointer to this entry
+ *NumberOfFiles = 1;
+ return;
+ }
+
+ TmpPtr += EntrySize;
+ IndexSize -= EntrySize;
+ if ( IndexSize < MINIMUM_ENTRY_SIZE ) break;
+
+ } while (IndexSize);
+ }
+
+ do { // do loop handling indexes in the root
+ Offset = 0;
+ // Look for "INDX", start of index record
+ if ( (Root[0] == 0x49) && \
+ (Root[1] == 0x4E) && \
+ (Root[2] == 0x44) && \
+ (Root[3] == 0x58) )
+ {
+ IndexSize = ((INDEX_RECORD*)Root)->INDR_IndxEntrySize;
+ IndexSize2 = IndexSize;
+ Offset += ((INDEX_RECORD*)Root)->INDR_IndxEntryOff + \
+ EFI_FIELD_OFFSET(INDEX_RECORD, INDR_IndxEntryOff);
+ TmpPtr = Root;
+ TmpPtr += Offset; // Point to first entry in index
+ if (IndexSize < MINIMUM_ENTRY_SIZE) { // Empty index
+ return;
+ }
+ } else return; // no index found
+
+ do { // loop inside the index
+ EntrySize = ((INDEX_ENTRY*)TmpPtr)->INDE_EntrySize;
+ LfnSize = ((INDEX_ENTRY*)TmpPtr)->INDE_NameLength;
+ if (LfnSize > 12) LfnSize = 12; // Limit name to 12 chars
+ NamePtr = &((INDEX_ENTRY*)TmpPtr)->INDE_Name[0];
+ for ( i=0; i<LfnSize; i++ )
+ {
+ TmpFileName[i] = (CHAR8)(CHAR16)NamePtr[i];
+ }
+ TmpFileName[i] = 0; // Zero-terminate name
+
+ if(!EFI_ERROR(FileSearch((CHAR8*)FileName, TmpFileName, FALSE, LfnSize))) {
+ IndxPtr = (INDEX_ENTRY*)&TmpPtr[0];
+ Buffer[*NumberOfFiles] = IndxPtr; // Save pointer to this entry
+ *NumberOfFiles = 1;
+ return;
+ }
+
+ TmpPtr += EntrySize;
+ IndexSize -= EntrySize;
+ if ( IndexSize < MINIMUM_ENTRY_SIZE ) break;
+
+ } while (IndexSize);
+ if ( IndexSize2 < 0x1000 ) {
+ IndexSize2 = 0x1000;
+ } else {
+ IndexSize2 = (IndexSize2 + 0x100) & 0xffffff00 ; // Round off
+ }
+ Root += IndexSize2;
+ RootSize -= IndexSize2;
+
+ } while (RootSize);
+#else
+ *NumberOfFiles = 0; //no files found
+ return;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AmiGetFileListFromExtVolume
+//
+// Description:
+// Gets a list of valid recovery files from an EXT(n) volume.
+// As currently written, gets only one file.
+//
+// Input:
+// UINT8 *Root - Pointer to a buffer containing the root directory
+// UINT32 RootSize - Size of the root directory
+// UINTN *NumberOfFiles - Pointer to number of files found
+// DIR_ENTRY_EXT **Buffer - Pointer to buffer containing index entry of
+// the file that was found.
+//
+// Output:
+// None - returned in variables.
+//
+// Notes:
+// This is an e-linked function, which can be replaced.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AmiGetFileListFromExtVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY_EXT **Buffer
+)
+{
+#if EXT_RECOVERY_SUPPORT
+ EFI_STATUS Status;
+ DIR_ENTRY_EXT *TmpPtr;
+ UINT16 EntryLength;
+ UINT8 NameLength;
+ VOID *FileName;
+ UINTN FileSize;
+ UINT8 i;
+ CHAR8 TmpFileName[13];
+
+ *NumberOfFiles = 0; //no files found yet
+
+ Status = GetRecoveryFileInfo(ThisPeiServices, &FileName, &FileSize, NULL);
+ if(EFI_ERROR(Status))
+ return;
+
+ do { // do loop handling entries in the root
+
+ TmpPtr = (DIR_ENTRY_EXT*)&Root[0];
+ EntryLength = TmpPtr->DIR_EntryLength;
+ if (EntryLength == 0) break; // End of directory, file not found
+ NameLength = TmpPtr->DIR_NameLength;
+ if (NameLength > 12) NameLength = 12;
+ for ( i=0; i<NameLength; i++ )
+ {
+ TmpFileName[i] = TmpPtr->DIR_Name[i];
+ }
+ TmpFileName[i] = 0; // Zero-terminate name
+
+ if(!EFI_ERROR(FileSearch((CHAR8*)FileName,
+ TmpFileName,
+ FALSE,
+ NameLength))) {
+ Buffer[*NumberOfFiles] = TmpPtr; // Save pointer to this entry
+ *NumberOfFiles = 1;
+ return;
+ }
+
+ Root += EntryLength;
+ RootSize -= EntryLength;
+
+ } while (RootSize);
+#else
+ *NumberOfFiles = 0; //no files found
+ return;
+#endif
+}
+
+BOOLEAN AmiIsValidFile(
+ IN VOID *FileData,
+ IN UINTN FileSize
+)
+{
+ return TRUE;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/IdeRecovery.c b/Core/EM/Recovery/IdeRecovery.c
new file mode 100644
index 0000000..8ece24c
--- /dev/null
+++ b/Core/EM/Recovery/IdeRecovery.c
@@ -0,0 +1,2172 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/Recovery/IdeRecovery.c 15 4/02/12 12:54a Srilathasc $
+//
+// $Revision: 15 $
+//
+// $Date: 4/02/12 12:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/Recovery/IdeRecovery.c $
+//
+// 15 4/02/12 12:54a Srilathasc
+// [TAG] EIP81405
+// [Category] Bug Fix
+// [Symptom] Recovery mode did not work in hard disk
+// [RootCause] Sufficient timeout to wait for DRQ was not given after
+// command was written in AtaPioDataIn()
+// [Solution] Increase the TIMEOUT to 10 seconds after the command is
+// complete
+//
+// [Files] IdeRecovery.c
+//
+// 14 2/21/12 5:04a Rameshr
+// [TAG] EIP75596
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Boot to recovery mode without media in the CD drive.First
+// time it will fail and next time while inserting Media , still recovery
+// not success from CD.
+// [RootCause] Atapi_DetectMedia will get called and irrespective of
+// device status LookedForMedia flag getting updated
+// [Solution] LookedForMedia flag updated only when the success
+// detection of Media in the ODD
+// [Files] IdeRecovery.c
+//
+// 13 7/07/11 3:20a Lavanyap
+// [TAG] EIP59029
+// [Category] Bug Fix
+// [Symptom] Recovery failed in IDE mode in VIA platform.
+// [RootCause] BSY/DRQ status checking was not done on the right port.
+// [Solution] Select the proper device before checking the device
+// status.
+// [Files] IdeRecovery.c
+//
+// 12 5/04/11 12:20p Artems
+// Bug fix: rollback previous check-in changes
+//
+// 11 2/14/11 4:06p Yul
+// [TAG] EIP38288
+// [Category] Enhanced
+// [Description] Klocwork Issues II - Recovery
+//
+// 10 1/07/10 12:01p Robert
+// In Ata_ReadSectors() Change the SectorCount variable to UINT16,
+// removed the typecasting when setting this variable and added a
+// typecasting to UINT8 when call the AtaPioDataIn()
+// Removed previous changes for clearer functionality
+//
+// 9 1/05/10 12:13p Robert
+// in Ata_ReadSectors() if the need arises to call AtaPioDataIn with
+// SectorCount == MaxBlock, no data was ever read. A special case had to
+// be created to handle the case when SectorCount == MaxBlock.
+// Refer to EIP #33174 for more details
+//
+// 8 7/01/09 4:19p Rameshr
+// Coding Standard and File header updated.
+//
+// 7 3/04/09 1:32p Felixp
+// Address in the file header is updated.
+//
+// 6 2/26/09 5:38p Felixp
+// File header is updated (no code changes).
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: IdeRecovery.c
+//
+// Description: IDE Recovery Implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: IdeRecovery.c - PEI driver
+//
+// Description: Implements EFI_PEI_RECOVERY_BLOCK_IO_PPI for ATA and ATAPI devices.
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <AmiLib.h>
+#include <Ppi\DeviceRecoveryBlockIo.h>
+#include <Ppi\Stall.h>
+#include <Protocol\BlockIo.h>
+#include <Ppi\AtaController.h>
+
+
+EFI_GUID gPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+EFI_GUID gPeiAtaControllerPpiGuid = PEI_ATA_CONTROLLER_PPI_GUID;
+EFI_GUID gPeiBlockIoPpiGuid = EFI_PEI_VIRTUAL_BLOCK_IO_PPI;
+EFI_GUID gIdeRecoveryNativeModePpiGuid = PEI_IDE_RECOVERY_NATIVE_MODE_PPI_GUID;
+
+//----------------------------------------------------------------------
+
+//Atapi command definitions
+
+#define EFI_MIN( a, b ) (((a) < (b)) ? (a) : (b))
+
+#define ATAPI_SIGNATURE 0xEB14
+
+#define CD_ROM_DEVICE 0x5
+
+#define SK_NO_SENSE 0
+#define SK_NOT_READY 2
+#define SK_UNIT_ATTENTION 6
+
+#define MAX_SENSE_KEY_COUNT 6
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT16 GeneralConfiguration_0;
+ UINT16 Data_1_58[58];
+ UINT32 TotalUserAddressableSectors_60;
+ UINT16 Data_61_255[195];
+} ATA_IDENTIFY_DATA;
+
+typedef struct
+{
+ UINT8 PeripheralDeviceType_0 : 5;
+ UINT8 Reserved_0 : 3;
+ UINT8 Data_1_95[95];
+} INQUIRY_DATA;
+
+typedef struct
+{
+ UINT8 Data_0_1[2];
+ UINT8 SenseKey_2 : 4;
+ UINT8 Data_2 : 4;
+ UINT8 Data_3_6[4];
+ UINT8 AdditionalSenseLength_7;
+ UINT8 Data_8_11[4];
+ UINT8 AdditionalSenseCode_12;
+ UINT8 AdditionalSenseCodeQualifier_13;
+ UINT8 Data_14_17[4];
+} REQUEST_SENSE_DATA;
+
+typedef struct
+{
+ UINT8 LastLba0;
+ UINT8 LastLba1;
+ UINT8 LastLba2;
+ UINT8 LastLba3;
+ UINT8 BlockSize3;
+ UINT8 BlockSize2;
+ UINT8 BlockSize1;
+ UINT8 BlockSize0;
+} READ_CAPACITY_DATA;
+
+#pragma pack()
+
+#define PACKET_CMD 0xA0
+#define ATA_IDENTIFY_DEVICE_CMD 0xEC
+#define ATA_READ_SECTOR_CMD 0x20
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT8 OperationCode_0;
+ UINT8 Data_1_3[3];
+ UINT8 AllocationLength_4;
+ UINT8 Data_5_11[7];
+} GENERIC_CMD;
+
+typedef struct
+{
+ UINT8 OperationCode_0;
+ UINT8 Data_1;
+ UINT8 Lba0;
+ UINT8 Lba1;
+ UINT8 Lba2;
+ UINT8 Lba3;
+ UINT8 Data_6;
+ UINT8 TransferLengthMSB;
+ UINT8 TransferLengthLSB;
+ UINT8 Data_9_11[3];
+} READ10_CMD;
+
+typedef union
+{
+ UINT16 Data16[6];
+ GENERIC_CMD Cmd;
+ READ10_CMD Read10;
+} ATAPI_PACKET_COMMAND;
+
+#pragma pack()
+
+#define TEST_UNIT_READY 0x00
+#define REQUEST_SENSE 0x03
+#define INQUIRY 0x12
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+
+#define DEFAULT_CTL (0x0a) // default content of device control register, disable INT
+#define DEFAULT_CMD (0xa0)
+
+#define MAX_ATAPI_BYTE_COUNT (0xfffe)
+
+#pragma pack(1)
+
+// IDE registers bit definitions
+
+// Err Reg
+#define ABRT_ERR BIT02 // Aborted Command
+
+
+// Device/Head Reg
+#define LBA_MODE BIT06
+
+// Status Reg
+#define BSY BIT07 // Controller Busy
+#define DRDY BIT06 // Drive Ready
+#define DWF BIT05 // Drive Write Fault
+#define DRQ BIT03 // Data Request
+#define CORR BIT02 // Corrected Data
+#define ERR BIT00 // Error
+
+#pragma pack()
+
+#define STALL_1_MILLI_SECOND 1000 // stall 1 ms
+
+#define TIMEOUT 1000 // 1 second
+#define COMMAND_COMPLETE_TIMEOUT 10000 // 10 seconds
+#define LONGTIMEOUT 5000 // 5 seconds
+
+//----------------------------------------------------------------------
+
+typedef enum {
+ EnumerateAtapi, EnumerateAta
+} ENUMERATE_TYPE;
+typedef enum {
+ IdeLegacy, IdeNative, IdeMaxMode
+} EFI_IDE_MODE;
+typedef enum {
+ IdePrimary, IdeSecondary, IdeMaxChannel
+} EFI_IDE_CHANNEL;
+typedef enum {
+ IdeMaster, IdeSlave, IdeMaxDevice
+} EFI_IDE_DEVICE;
+
+// IDE Registers
+typedef union
+{
+ UINT16 Command; // when write
+ UINT16 Status; // when read
+} IDE_CMD_OR_STATUS;
+
+typedef union
+{
+ UINT16 Error; // when read
+ UINT16 Feature; // when write
+} IDE_ERROR_OR_FEATURE;
+
+typedef union
+{
+ UINT16 AltStatus; // when read
+ UINT16 DeviceControl; // when write
+} IDE_AltStatus_OR_DeviceControl;
+
+
+// IDE registers set
+typedef struct
+{
+ UINT16 Data;
+ IDE_ERROR_OR_FEATURE Reg1;
+ UINT16 SectorCount;
+ UINT16 SectorNumber;
+ UINT16 CylinderLsb;
+ UINT16 CylinderMsb;
+ UINT16 Head;
+ IDE_CMD_OR_STATUS Reg;
+
+ IDE_AltStatus_OR_DeviceControl Alt;
+ UINT16 DriveAddress;
+} IDE_BASE_REGISTERS;
+
+typedef struct
+{
+ UINT8 Device;
+ BOOLEAN LookedForMedia;
+ IDE_BASE_REGISTERS *IdeIoPortRegisters;
+ EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
+} IDE_RECOVERY_DEVICE_INFO;
+
+#define MAX_DEVICE_COUNT 8
+
+typedef struct
+{
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI RecoveryBlkIo;
+
+ BOOLEAN HaveEnumeratedDevices;
+ UINTN DeviceCount;
+ IDE_RECOVERY_DEVICE_INFO *DeviceInfo[MAX_DEVICE_COUNT];
+} IDE_RECOVERY_BLK_IO_DEV;
+
+// IDE registers' fixed address
+IDE_BASE_REGISTERS PrimaryChannelLegacyIdeIoPortRegisters = {
+ 0x1f0, 0x1f1, 0x1f2, 0x1f3, 0x1f4, 0x1f5, 0x1f6, 0x1f7, 0x3f6, 0x3f7
+};
+
+IDE_BASE_REGISTERS SecondaryChannelLegacyIdeIoPortRegisters = {
+ 0x170, 0x171, 0x172, 0x173, 0x174, 0x175, 0x176, 0x177, 0x376, 0x377
+};
+
+//AtaAtapiCommonInit should only be called once
+BOOLEAN gHaveCalledAtaAtapiCommonInit = FALSE;
+
+BOOLEAN gIdeRecoveryNativeModeSupport = FALSE;
+
+IDE_BASE_REGISTERS PrimaryChannelNativeIdeIoPortRegisters = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1
+};
+
+IDE_BASE_REGISTERS SecondaryChannelNativeIdeIoPortRegisters = {
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 1
+};
+
+IDE_BASE_REGISTERS *gNativeModePortRegsiters;
+UINT8 gNativeIdeCount = 0;
+
+
+//----------------------------------------------------------------------
+
+// PEI Recovery Block I/O PPI
+
+EFI_STATUS AtaAtapiCommonInit (
+ IN EFI_PEI_SERVICES **PeiServices );
+
+EFI_STATUS Atapi_GetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices );
+EFI_STATUS Atapi_GetBlockDeviceMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo );
+EFI_STATUS Atapi_ReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+EFI_STATUS Ata_GetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices );
+EFI_STATUS Ata_GetBlockDeviceMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo );
+EFI_STATUS Ata_ReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+// Private functions
+VOID EnumerateDevices (
+ IN OUT IDE_RECOVERY_BLK_IO_DEV *IdeRecoveryBlkIoDev,
+ IN ENUMERATE_TYPE EnumerateType );
+BOOLEAN Atapi_DiscoverDevice (
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo );
+BOOLEAN Ata_DiscoverDevice (
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo );
+
+EFI_STATUS AtapiPacketCommandIn (
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ IN ATAPI_PACKET_COMMAND *Packet,
+ IN UINT16 *Buffer,
+ IN UINT32 ByteCount,
+ IN UINTN TimeoutInMilliSeconds );
+EFI_STATUS Inquiry (
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo );
+EFI_STATUS Atapi_DetectMedia (
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo );
+EFI_STATUS TestUnitReady (
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo );
+EFI_STATUS RequestSense (
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ OUT REQUEST_SENSE_DATA *SenseBuffers,
+ OUT UINT8 *SenseCounts );
+EFI_STATUS ReadCapacity (
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo );
+EFI_STATUS Atapi_ReadSectors (
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ OUT VOID *Buffer,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN NumberOfBlocks,
+ IN UINTN BlockSize );
+
+EFI_STATUS AtaPioDataIn (
+ IN IDE_BASE_REGISTERS *IdeIoPortRegisters,
+ OUT VOID *Buffer,
+ IN UINT32 ByteCount,
+ IN UINT8 SectorCount,
+ IN UINT8 SectorNumber,
+ IN UINT8 CylinderLsb,
+ IN UINT8 CylinderMsb,
+ IN UINT8 Device,
+ IN UINT8 Command );
+EFI_STATUS AtaIdentify (
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ OUT ATA_IDENTIFY_DATA *AtaIdentifyData );
+EFI_STATUS Ata_ReadSectors (
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ OUT VOID *Buffer,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN NumberOfBlocks,
+ IN UINTN BlockSize );
+
+EFI_STATUS WaitForBitsToClear (
+ IN UINT16 Register,
+ IN UINT8 Bits,
+ IN UINTN TimeoutInMilliSeconds );
+EFI_STATUS WaitForBSYClear (
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds );
+EFI_STATUS DRQClear (
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds );
+EFI_STATUS DRQClear2 (
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds );
+
+EFI_STATUS DRQReadyHelper (
+ IN UINT16 StatusRegister,
+ IN UINT16 ErrorRegister,
+ IN UINTN TimeoutInMilliSeconds );
+EFI_STATUS DRQReady (
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds );
+EFI_STATUS DRQReady2 (
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds );
+
+EFI_STATUS CheckErrorStatus (
+ IN UINT16 StatusReg );
+
+VOID ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Size );
+
+//----------------------------------------------------------------------
+
+EFI_PEI_PPI_DESCRIPTOR Atapi_PpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiBlockIoPpiGuid,
+ NULL
+};
+
+EFI_PEI_PPI_DESCRIPTOR Ata_PpiDescriptor = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiBlockIoPpiGuid,
+ NULL
+};
+
+static EFI_PEI_SERVICES **gPeiServices = NULL;
+static EFI_PEI_STALL_PPI *gStallPpi = NULL;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_RecoveryPeimEntry
+//
+// Description: Installs EFI_PEI_RECOVERY_BLOCK_IO_PPI for ATAPI devices.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Atapi_RecoveryPeimEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ IDE_RECOVERY_BLK_IO_DEV *Atapi_BlkIoDev = NULL;
+
+ if ( !gPeiServices ) {
+ gPeiServices = PeiServices;
+ }
+
+ Status = (**PeiServices).AllocatePool( PeiServices, sizeof(IDE_RECOVERY_BLK_IO_DEV), &Atapi_BlkIoDev );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Atapi_BlkIoDev->HaveEnumeratedDevices = FALSE;
+ Atapi_BlkIoDev->DeviceCount = 0;
+
+ Atapi_BlkIoDev->RecoveryBlkIo.GetNumberOfBlockDevices = Atapi_GetNumberOfBlockDevices;
+ Atapi_BlkIoDev->RecoveryBlkIo.GetBlockDeviceMediaInfo = Atapi_GetBlockDeviceMediaInfo;
+ Atapi_BlkIoDev->RecoveryBlkIo.ReadBlocks = Atapi_ReadBlocks;
+ Atapi_PpiDescriptor.Ppi = &Atapi_BlkIoDev->RecoveryBlkIo;
+
+ Status = (**PeiServices).InstallPpi( PeiServices, &Atapi_PpiDescriptor );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Ata_RecoveryPeimEntry
+//
+// Description: Installs EFI_PEI_RECOVERY_BLOCK_IO_PPI for ATA devices.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Ata_RecoveryPeimEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ IDE_RECOVERY_BLK_IO_DEV *Ata_BlkIoDev = NULL;
+
+ if ( !gPeiServices ) {
+ gPeiServices = PeiServices;
+ }
+
+ Status = (**PeiServices).AllocatePool( PeiServices, sizeof(IDE_RECOVERY_BLK_IO_DEV), &Ata_BlkIoDev );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Ata_BlkIoDev->HaveEnumeratedDevices = FALSE;
+ Ata_BlkIoDev->DeviceCount = 0;
+
+ Ata_BlkIoDev->RecoveryBlkIo.GetNumberOfBlockDevices = Ata_GetNumberOfBlockDevices;
+ Ata_BlkIoDev->RecoveryBlkIo.GetBlockDeviceMediaInfo = Ata_GetBlockDeviceMediaInfo;
+ Ata_BlkIoDev->RecoveryBlkIo.ReadBlocks = Ata_ReadBlocks;
+ Ata_PpiDescriptor.Ppi = &Ata_BlkIoDev->RecoveryBlkIo;
+
+ Status = (**PeiServices).InstallPpi( PeiServices, &Ata_PpiDescriptor );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AtaAtapiCommonInit
+//
+// Description: Called by Atapi_RecoveryPeimEntry and Ata_RecoveryPeimEntry
+// functions. Initializes stuff, including
+// gIdeRecoveryNativeModeSupport,
+// PrimaryChannelNativeIdeIoPortRegisters,
+// SecondaryChannelNativeIdeIoPortRegisters.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaAtapiCommonInit(
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_STATUS LegacyStatus = EFI_NOT_FOUND;
+ PEI_ATA_CONTROLLER_PPI *AtaControllerPpi = NULL;
+ PEI_IDE_RECOVERY_NATIVE_MODE_PPI *IdeRecoveryNativeModePpi = NULL;
+ UINT8 i = 0;
+ UINT8 Index = 0;
+
+
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid, 0, NULL, &gStallPpi );
+
+ if ( EFI_ERROR( Status )) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiAtaControllerPpiGuid, 0, NULL, &AtaControllerPpi );
+
+ if ( !(EFI_ERROR( Status ))) {
+ LegacyStatus = AtaControllerPpi->EnableAtaChannel( PeiServices, AtaControllerPpi, PEI_ICH_IDE_PRIMARY | PEI_ICH_IDE_SECONDARY );
+ }
+
+ //
+ //Find Number of Native mode IDE ppi installed
+ //
+ Index = 0;
+
+ do
+ {
+ Status = (**PeiServices).LocatePpi( PeiServices, &gIdeRecoveryNativeModePpiGuid, Index, NULL, &IdeRecoveryNativeModePpi );
+
+ if ( !(EFI_ERROR( Status ))) {
+ Index++;
+ gNativeIdeCount++;
+ }
+ } while ( Status == EFI_SUCCESS );
+
+ //
+ //if Legacy mode init fails and if there is no native PPI return with error.
+ //
+ if ((gNativeIdeCount == 00) && (LegacyStatus != EFI_SUCCESS)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = (**PeiServices).AllocatePool( PeiServices, sizeof(IDE_BASE_REGISTERS) * 2 * gNativeIdeCount, &gNativeModePortRegsiters );
+
+ //
+ //Fill the base address values in gNativeModePortRegsiters
+ //
+ Index = 0;
+
+ do
+ {
+ Status = (**PeiServices).LocatePpi( PeiServices, &gIdeRecoveryNativeModePpiGuid, Index, NULL, &IdeRecoveryNativeModePpi );
+
+ if ( !(EFI_ERROR( Status ))) {
+ gIdeRecoveryNativeModeSupport = TRUE;
+ gNativeModePortRegsiters[i].Data = PrimaryChannelNativeIdeIoPortRegisters.Data + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].Reg1.Error = PrimaryChannelNativeIdeIoPortRegisters.Reg1.Error + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].SectorCount = PrimaryChannelNativeIdeIoPortRegisters.SectorCount + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].SectorNumber = PrimaryChannelNativeIdeIoPortRegisters.SectorNumber + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].CylinderLsb = PrimaryChannelNativeIdeIoPortRegisters.CylinderLsb + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].CylinderMsb = PrimaryChannelNativeIdeIoPortRegisters.CylinderMsb + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].Head = PrimaryChannelNativeIdeIoPortRegisters.Head + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].Reg.Command = PrimaryChannelNativeIdeIoPortRegisters.Reg.Command + IdeRecoveryNativeModePpi->PCMDBarAddress;
+ gNativeModePortRegsiters[i].Alt.AltStatus = PrimaryChannelNativeIdeIoPortRegisters.Alt.AltStatus + IdeRecoveryNativeModePpi->PCNLBarAddress;
+ gNativeModePortRegsiters[i].DriveAddress = PrimaryChannelNativeIdeIoPortRegisters.DriveAddress + IdeRecoveryNativeModePpi->PCNLBarAddress;
+
+ gNativeModePortRegsiters[i + 1].Data = SecondaryChannelNativeIdeIoPortRegisters.Data + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].Reg1.Error = SecondaryChannelNativeIdeIoPortRegisters.Reg1.Error + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].SectorCount = SecondaryChannelNativeIdeIoPortRegisters.SectorCount + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].SectorNumber = SecondaryChannelNativeIdeIoPortRegisters.SectorNumber += IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].CylinderLsb = SecondaryChannelNativeIdeIoPortRegisters.CylinderLsb + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].CylinderMsb = SecondaryChannelNativeIdeIoPortRegisters.CylinderMsb + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].Head = SecondaryChannelNativeIdeIoPortRegisters.Head + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].Reg.Command = SecondaryChannelNativeIdeIoPortRegisters.Reg.Command + IdeRecoveryNativeModePpi->SCMDBarAddress;
+ gNativeModePortRegsiters[i + 1].Alt.AltStatus = SecondaryChannelNativeIdeIoPortRegisters.Alt.AltStatus + IdeRecoveryNativeModePpi->SCNLBarAddress;
+ gNativeModePortRegsiters[i + 1].DriveAddress = SecondaryChannelNativeIdeIoPortRegisters.DriveAddress + IdeRecoveryNativeModePpi->SCNLBarAddress;
+ i = i + 2;
+ Index++;
+ }
+ } while ( Status == EFI_SUCCESS );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_GetNumberOfBlockDevices
+//
+// Description: GetNumberOfBlockDevices function of
+// EFI_PEI_RECOVERY_BLOCK_IO_PPI.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Atapi_GetNumberOfBlockDevices(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices )
+{
+ IDE_RECOVERY_BLK_IO_DEV *Atapi_BlkIoDev = NULL;
+
+ if ( This == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Atapi_BlkIoDev = (IDE_RECOVERY_BLK_IO_DEV*)This;
+
+ if ( !Atapi_BlkIoDev->HaveEnumeratedDevices ) {
+ EnumerateDevices( Atapi_BlkIoDev, EnumerateAtapi );
+ Atapi_BlkIoDev->HaveEnumeratedDevices = TRUE;
+ }
+ *NumberBlockDevices = Atapi_BlkIoDev->DeviceCount;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_GetBlockDeviceMediaInfo
+//
+// Description: GetBlockDeviceMediaInfo function of
+// EFI_PEI_RECOVERY_BLOCK_IO_PPI.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Atapi_GetBlockDeviceMediaInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo )
+{
+ IDE_RECOVERY_BLK_IO_DEV *Atapi_BlkIoDev = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if ((This == NULL) || (MediaInfo == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Atapi_BlkIoDev = (IDE_RECOVERY_BLK_IO_DEV*)This;
+
+ if ( !Atapi_BlkIoDev->HaveEnumeratedDevices ) {
+ EnumerateDevices( Atapi_BlkIoDev, EnumerateAtapi );
+ Atapi_BlkIoDev->HaveEnumeratedDevices = TRUE;
+ }
+
+ if ( DeviceIndex > (Atapi_BlkIoDev->DeviceCount - 1)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !Atapi_BlkIoDev->DeviceInfo[DeviceIndex]->LookedForMedia ) {
+ Status = Atapi_DetectMedia( Atapi_BlkIoDev->DeviceInfo[DeviceIndex] );
+
+ if ( Status != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+ Atapi_BlkIoDev->DeviceInfo[DeviceIndex]->LookedForMedia = TRUE;
+ }
+
+ *MediaInfo = Atapi_BlkIoDev->DeviceInfo[DeviceIndex]->MediaInfo;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_ReadBlocks
+//
+// Description: ReadBlocks function of EFI_PEI_RECOVERY_BLOCK_IO_PPI.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Atapi_ReadBlocks(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN NumberOfBlocks = 0;
+ UINTN BlockSize = 0;
+ IDE_RECOVERY_BLK_IO_DEV *Atapi_BlkIoDev = NULL;
+
+ if ( This == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Atapi_BlkIoDev = (IDE_RECOVERY_BLK_IO_DEV*)This;
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ if ( !Atapi_BlkIoDev->HaveEnumeratedDevices ) {
+ EnumerateDevices( Atapi_BlkIoDev, EnumerateAtapi );
+ Atapi_BlkIoDev->HaveEnumeratedDevices = TRUE;
+ }
+
+ if ( !Atapi_BlkIoDev->DeviceInfo[DeviceIndex]->LookedForMedia ) {
+ Status = Atapi_GetBlockDeviceMediaInfo( PeiServices, This, DeviceIndex, &MediaInfo );
+
+ if ( Status != EFI_SUCCESS ) {
+ return Status;
+ }
+ } else {
+ MediaInfo = Atapi_BlkIoDev->DeviceInfo[DeviceIndex]->MediaInfo;
+ }
+
+ BlockSize = MediaInfo.BlockSize;
+
+ if ((BufferSize % BlockSize) != 0 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !MediaInfo.MediaPresent ) {
+ return EFI_NO_MEDIA;
+ }
+
+ NumberOfBlocks = BufferSize / BlockSize;
+
+ Status = Atapi_ReadSectors(
+ Atapi_BlkIoDev->DeviceInfo[DeviceIndex],
+ Buffer,
+ StartLba,
+ NumberOfBlocks,
+ BlockSize
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Ata_GetNumberOfBlockDevices
+//
+// Description: GetNumberOfBlockDevices function of
+// EFI_PEI_RECOVERY_BLOCK_IO_PPI.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Ata_GetNumberOfBlockDevices(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices )
+{
+ IDE_RECOVERY_BLK_IO_DEV *Ata_BlkIoDev = NULL;
+
+ if ( This == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ata_BlkIoDev = (IDE_RECOVERY_BLK_IO_DEV*)This;
+
+ if ( !Ata_BlkIoDev->HaveEnumeratedDevices ) {
+ EnumerateDevices( Ata_BlkIoDev, EnumerateAta );
+ Ata_BlkIoDev->HaveEnumeratedDevices = TRUE;
+ }
+ *NumberBlockDevices = Ata_BlkIoDev->DeviceCount;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Ata_GetBlockDeviceMediaInfo
+//
+// Description: GetBlockDeviceMediaInfo function of
+// EFI_PEI_RECOVERY_BLOCK_IO_PPI.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Ata_GetBlockDeviceMediaInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo )
+{
+ IDE_RECOVERY_BLK_IO_DEV *Ata_BlkIoDev = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *Buffer = NULL;
+ UINT32 SectorOfFirstPartition = 0;
+ UINT16 LowByte = 0, HighByte = 0, BlockSize = 0;
+
+ if ((This == NULL) || (MediaInfo == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ata_BlkIoDev = (IDE_RECOVERY_BLK_IO_DEV*)This;
+
+ if ( !Ata_BlkIoDev->HaveEnumeratedDevices ) {
+ EnumerateDevices( Ata_BlkIoDev, EnumerateAta );
+ Ata_BlkIoDev->HaveEnumeratedDevices = TRUE;
+ }
+
+ if ( DeviceIndex > (Ata_BlkIoDev->DeviceCount - 1)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !Ata_BlkIoDev->DeviceInfo[DeviceIndex]->LookedForMedia ) {
+ Ata_BlkIoDev->DeviceInfo[DeviceIndex]->LookedForMedia = TRUE;
+
+ }
+
+ *MediaInfo = Ata_BlkIoDev->DeviceInfo[DeviceIndex]->MediaInfo;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Ata_ReadBlocks
+//
+// Description: ReadBlocks function of EFI_PEI_RECOVERY_BLOCK_IO_PPI.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Ata_ReadBlocks(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ EFI_PEI_BLOCK_IO_MEDIA MediaInfo;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN NumberOfBlocks = 0;
+ UINTN BlockSize = 0;
+ IDE_RECOVERY_BLK_IO_DEV *Ata_BlkIoDev = NULL;
+
+ if ( This == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Ata_BlkIoDev = (IDE_RECOVERY_BLK_IO_DEV*)This;
+
+ if ( Buffer == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( BufferSize == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ if ( !Ata_BlkIoDev->HaveEnumeratedDevices ) {
+ EnumerateDevices( Ata_BlkIoDev, EnumerateAta );
+ Ata_BlkIoDev->HaveEnumeratedDevices = TRUE;
+ }
+
+ if ( !Ata_BlkIoDev->DeviceInfo[DeviceIndex]->LookedForMedia ) {
+ Status = Ata_GetBlockDeviceMediaInfo(
+ PeiServices,
+ This,
+ DeviceIndex,
+ &MediaInfo
+ );
+
+ if ( Status != EFI_SUCCESS ) {
+ return Status;
+ }
+ } else {
+ MediaInfo = Ata_BlkIoDev->DeviceInfo[DeviceIndex]->MediaInfo;
+ }
+
+ BlockSize = MediaInfo.BlockSize;
+
+ if ( BufferSize % BlockSize != 0 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( !MediaInfo.MediaPresent ) {
+ return EFI_NO_MEDIA;
+ }
+
+ NumberOfBlocks = BufferSize / BlockSize;
+
+ if ( StartLba > MediaInfo.LastBlock ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((StartLba + NumberOfBlocks) > (MediaInfo.LastBlock + 1)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = Ata_ReadSectors(
+ Ata_BlkIoDev->DeviceInfo[DeviceIndex],
+ Buffer,
+ StartLba,
+ NumberOfBlocks,
+ BlockSize
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EnumerateDevices
+//
+// Description: Enumerates Ata or Atapi devices. Called by
+// Ata_GetNumberOfBlockDevices or
+// Atapi_GetNumberOfBlockDevices.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EnumerateDevices(
+ IN IDE_RECOVERY_BLK_IO_DEV *IdeRecoveryBlkIoDev,
+ ENUMERATE_TYPE EnumerateType )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 MaxModes = IdeMaxMode;
+ EFI_IDE_MODE Mode = 0;
+ UINT8 Channel = 0;
+ UINT8 Device = 0;
+ UINTN DeviceCount = 0;
+ IDE_RECOVERY_DEVICE_INFO DeviceInfo;
+ UINT8 NativeIdeModeCount = 0;
+
+
+ if ( !gHaveCalledAtaAtapiCommonInit ) {
+ AtaAtapiCommonInit( gPeiServices );
+ gHaveCalledAtaAtapiCommonInit = TRUE;
+ }
+
+ if ( gIdeRecoveryNativeModeSupport ) {
+ //
+ //Based on the number of Nativemode PPI maximum mode support is adjusted
+ //
+ MaxModes = IdeMaxMode + gNativeIdeCount - 1;
+ } else {
+ MaxModes = IdeNative;
+ }
+
+ for ( Mode = IdeLegacy; Mode < MaxModes; Mode++ ) {
+ for ( Channel = IdePrimary; Channel < IdeMaxChannel; Channel++ ) {
+ for ( Device = IdeMaster; Device < IdeMaxDevice; Device++ ) {
+
+ DeviceInfo.Device = Device;
+ if ( Mode == IdeLegacy ) {
+ if ( Channel == IdePrimary ) {
+ DeviceInfo.IdeIoPortRegisters = &PrimaryChannelLegacyIdeIoPortRegisters;
+ } else { //IdeSecondary
+ DeviceInfo.IdeIoPortRegisters = &SecondaryChannelLegacyIdeIoPortRegisters;
+ }
+ } else { //IdeNative
+ if ( Channel == IdePrimary ) {
+ DeviceInfo.IdeIoPortRegisters = &gNativeModePortRegsiters[NativeIdeModeCount];
+ } else { //IdeSecondary
+ DeviceInfo.IdeIoPortRegisters = &gNativeModePortRegsiters[NativeIdeModeCount + 1];
+ }
+ }
+
+ if ( EnumerateType == EnumerateAtapi ) {
+ if ( Atapi_DiscoverDevice( &DeviceInfo )) {
+ Status = (**gPeiServices).AllocatePool( gPeiServices, sizeof(IDE_RECOVERY_DEVICE_INFO), &(IdeRecoveryBlkIoDev->DeviceInfo[DeviceCount]));
+
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+ DeviceInfo.MediaInfo.MediaPresent = FALSE;
+ DeviceInfo.MediaInfo.LastBlock = 0;
+ DeviceInfo.LookedForMedia = FALSE;
+ *(IdeRecoveryBlkIoDev->DeviceInfo[DeviceCount]) = DeviceInfo;
+ DeviceCount++;
+ }
+ } else {
+ //
+ //EnumerateAta
+ //
+ if ( Ata_DiscoverDevice( &DeviceInfo )) {
+ Status = (**gPeiServices).AllocatePool( gPeiServices, sizeof(IDE_RECOVERY_DEVICE_INFO), &(IdeRecoveryBlkIoDev->DeviceInfo[DeviceCount]));
+
+ if ( EFI_ERROR( Status )) {
+ return;
+ }
+ DeviceInfo.MediaInfo.MediaPresent = TRUE;
+ DeviceInfo.MediaInfo.BlockSize = 0x200;
+ DeviceInfo.LookedForMedia = FALSE;
+ *(IdeRecoveryBlkIoDev->DeviceInfo[DeviceCount]) = DeviceInfo;
+ DeviceCount++;
+ }
+ }
+ }
+ }
+
+ if ( Mode == IdeNative ) {
+ //
+ //index to the Next native mode PPI base address
+ //
+ NativeIdeModeCount = NativeIdeModeCount + 2;
+ }
+ }
+
+ IdeRecoveryBlkIoDev->DeviceCount = DeviceCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_DiscoverDevice
+//
+// Description: Called by EnumerateDevices. Looks for ATAPI_SIGNATURE.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN Atapi_DiscoverDevice(
+ IDE_RECOVERY_DEVICE_INFO *DeviceInfo )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 Device = DeviceInfo->Device;
+ UINT16 HeadReg = DeviceInfo->IdeIoPortRegisters->Head;
+ UINT16 StatusReg = DeviceInfo->IdeIoPortRegisters->Reg.Status;
+ UINT16 CylinderLsb = DeviceInfo->IdeIoPortRegisters->CylinderLsb;
+ UINT16 CylinderMsb = DeviceInfo->IdeIoPortRegisters->CylinderMsb;
+ UINT8 StatusValue = 0;
+ UINT8 Data8 = 0;
+
+ //
+ // Select Device
+ //
+ IoWrite8( HeadReg, Device << 4 );
+ StatusValue = IoRead8( StatusReg );
+
+ if ((StatusValue == 0x7f) || (StatusValue == 0xff)) {
+ return FALSE;
+ }
+
+ Status = WaitForBSYClear( DeviceInfo->IdeIoPortRegisters, 31000 );
+ StatusValue = IoRead8( StatusReg );
+
+ if ( EFI_ERROR( Status )) {
+ return FALSE;
+ }
+
+ Data8 = IoRead8( CylinderLsb );
+
+ if ( Data8 == (ATAPI_SIGNATURE & 0xff)) {
+ Data8 = IoRead8( CylinderMsb );
+
+ if ( Data8 == (ATAPI_SIGNATURE >> 8)) {
+ Status = Inquiry( DeviceInfo );
+
+ if ( !EFI_ERROR( Status )) {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Ata_DiscoverDevice
+//
+// Description: Called by EnumerateDevices. Looks at IDENTIFY data.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN Ata_DiscoverDevice(
+ IDE_RECOVERY_DEVICE_INFO *DeviceInfo )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 Device = DeviceInfo->Device;
+ UINT16 HeadReg = DeviceInfo->IdeIoPortRegisters->Head;
+ UINT16 StatusReg = DeviceInfo->IdeIoPortRegisters->Reg.Status;
+ UINT16 CylinderLsb = DeviceInfo->IdeIoPortRegisters->CylinderLsb;
+ UINT16 CylinderMsb = DeviceInfo->IdeIoPortRegisters->CylinderMsb;
+ UINT8 StatusValue = 0;
+ UINT8 Data8 = 0;
+
+ ATA_IDENTIFY_DATA AtaIdentifyData;
+
+
+ //
+ //Select Device
+ //
+ IoWrite8( HeadReg, Device << 4 );
+ StatusValue = IoRead8( StatusReg );
+
+ if ((StatusValue == 0x7f) || (StatusValue == 0xff)) {
+ return FALSE;
+ }
+
+ Status = WaitForBSYClear( DeviceInfo->IdeIoPortRegisters, 31000 );
+ StatusValue = IoRead8( StatusReg );
+
+ if ( EFI_ERROR( Status )) {
+ return FALSE;
+ }
+
+ Data8 = IoRead8( CylinderLsb );
+
+ if ( Data8 == (ATAPI_SIGNATURE & 0xff)) {
+ Data8 = IoRead8( CylinderMsb );
+
+ if ( Data8 == (ATAPI_SIGNATURE >> 8)) {
+ return FALSE;
+ }
+ }
+
+ if ( AtaIdentify( DeviceInfo, &AtaIdentifyData ) == EFI_SUCCESS ) {
+ if ((AtaIdentifyData.GeneralConfiguration_0 & 0x8000) == 0 ) {
+ DeviceInfo->MediaInfo.DeviceType = MaxDeviceType;
+ DeviceInfo->MediaInfo.LastBlock = AtaIdentifyData.TotalUserAddressableSectors_60;
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AtapiPacketCommandIn
+//
+// Description: Executes various ATAPI packet commands
+// (TEST_UNIT_READY, INQUIRY, REQUEST_SENSE, READ_CAPACITY, etc).
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtapiPacketCommandIn(
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ IN ATAPI_PACKET_COMMAND *Packet,
+ IN UINT16 *Buffer,
+ IN UINT32 ByteCount,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ IDE_BASE_REGISTERS *IdeIoPortRegisters = DeviceInfo->IdeIoPortRegisters;
+
+ UINT8 Device = DeviceInfo->Device;
+ UINT16 StatusReg = IdeIoPortRegisters->Reg.Status;
+ UINT16 HeadReg = IdeIoPortRegisters->Head;
+ UINT16 CommandReg = IdeIoPortRegisters->Reg.Command;
+ UINT16 FeatureReg = IdeIoPortRegisters->Reg1.Feature;
+ UINT16 CylinderLsbReg = IdeIoPortRegisters->CylinderLsb;
+ UINT16 CylinderMsbReg = IdeIoPortRegisters->CylinderMsb;
+ UINT16 DeviceControlReg = IdeIoPortRegisters->Alt.DeviceControl;
+ UINT16 DataReg = IdeIoPortRegisters->Data;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 Count = 0;
+ UINT16 *CommandIndex = NULL;
+ UINT16 *ptrBuffer = Buffer;
+ UINT32 Index = 0;
+ UINT8 StatusValue = 0;
+ UINT32 WordCount = 0;
+
+ //
+ // required transfer data in word unit.
+ //
+ UINT32 RequiredWordCount = 0;
+
+ //
+ // actual transfer data in word unit.
+ //
+ UINT32 ActualWordCount = 0;
+
+ //
+ // Select device via Device/Head Register.
+ // DEFAULT_CMD: 0xa0 (1010,0000)
+ //
+ IoWrite8( HeadReg, (UINT8) ((Device << 4) | DEFAULT_CMD ));
+
+ //
+ // Set all the command parameters by fill related registers.
+ // Before write to all the following registers, BSY and DRQ must be 0.
+ //
+ if ( DRQClear2(
+ DeviceInfo->IdeIoPortRegisters,
+ TIMEOUT
+ ) != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+
+ //
+ // No OVL; No DMA
+ //
+ IoWrite8( FeatureReg, 0x00 );
+
+ //
+ // set the transfersize to MAX_ATAPI_BYTE_COUNT to let the device
+ // determine how many data should be transfered.
+ //
+ IoWrite8( CylinderLsbReg, (UINT8) ( MAX_ATAPI_BYTE_COUNT & 0x00ff ));
+ IoWrite8( CylinderMsbReg, (UINT8) ( MAX_ATAPI_BYTE_COUNT >> 8 ));
+
+ //
+ // DEFAULT_CTL:0x0a (0000,1010)
+ // Disable interrupt
+ //
+ IoWrite8( DeviceControlReg, DEFAULT_CTL );
+
+ //
+ // Send Packet command to inform device
+ // that the following data bytes are command packet.
+ //
+ IoWrite8( CommandReg, PACKET_CMD );
+
+ Status = DRQReady( IdeIoPortRegisters, TimeoutInMilliSeconds );
+
+ if ( Status != EFI_SUCCESS ) {
+ return Status;
+ }
+ //
+ // Send out command packet
+ //
+ CommandIndex = Packet->Data16;
+
+ for ( Count = 0; Count < 6; Count++, CommandIndex++ ) {
+ IoWrite16( DataReg, *CommandIndex );
+ gStallPpi->Stall( gPeiServices, gStallPpi, 10 );
+ }
+
+ StatusValue = IoRead8( StatusReg );
+ WaitForBSYClear( IdeIoPortRegisters, LONGTIMEOUT );
+ StatusValue = IoRead8( StatusReg );
+
+ if ((StatusValue & ERR) == ERR ) {
+ //
+ // Trouble! Something's wrong here... Wait some time and return. 3 second is
+ // supposed to be long enough for a device reset latency or error recovery
+ //
+ gStallPpi->Stall( gPeiServices, gStallPpi, 100000 );
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( Buffer == NULL || ByteCount == 0 ) {
+ return EFI_SUCCESS;
+ }
+ //
+ // call PioReadWriteData() function to get
+ // requested transfer data form device.
+ //
+ ptrBuffer = Buffer;
+ RequiredWordCount = ByteCount / 2;
+ //
+ // ActuralWordCount means the word count of data really transfered.
+ //
+ ActualWordCount = 0;
+
+ Status = EFI_SUCCESS;
+ while ((Status == EFI_SUCCESS) && (ActualWordCount < RequiredWordCount))
+ {
+ //
+ // before each data transfer stream, the host should poll DRQ bit ready,
+ // which informs device is ready to transfer data.
+ //
+ if ( DRQReady2( IdeIoPortRegisters, TimeoutInMilliSeconds ) != EFI_SUCCESS ) {
+ return CheckErrorStatus( StatusReg );
+ }
+ //
+ // read Status Register will clear interrupt
+ //
+ StatusValue = IoRead8( StatusReg );
+
+ //
+ // get current data transfer size from Cylinder Registers.
+ //
+ WordCount = (( IoRead8( CylinderMsbReg ) << 8) | IoRead8( CylinderLsbReg )) & 0xffff;
+ WordCount /= 2;
+
+ //
+ // perform a series data In/Out.
+ //
+ for ( Index = 0; (Index < WordCount) && (ActualWordCount < RequiredWordCount); Index++, ActualWordCount++ )
+ {
+ *ptrBuffer = IoRead16( DataReg );
+
+ ptrBuffer++;
+ }
+
+ if (((GENERIC_CMD*) Packet)->OperationCode_0 == REQUEST_SENSE && ActualWordCount >= 4 ) {
+ RequiredWordCount = EFI_MIN( RequiredWordCount,
+ (UINT32) ( 4 + (((REQUEST_SENSE_DATA*) Buffer)->AdditionalSenseLength_7 / 2))
+ );
+ }
+ }
+ //
+ // After data transfer is completed, normally, DRQ bit should clear.
+ //
+ Status = DRQClear2( IdeIoPortRegisters, TimeoutInMilliSeconds );
+
+ if ( Status != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // read status register to check whether error happens.
+ //
+ Status = CheckErrorStatus( StatusReg );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Inquiry
+//
+// Description: ATAPI packet command INQUIRY. Uses AtapiPacketCommandIn.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Inquiry(
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo )
+{
+ ATAPI_PACKET_COMMAND Packet;
+ EFI_STATUS Status;
+ INQUIRY_DATA Idata;
+
+ ZeroMem( &Packet, sizeof (ATAPI_PACKET_COMMAND));
+
+ Packet.Cmd.OperationCode_0 = INQUIRY;
+ Packet.Cmd.AllocationLength_4 = sizeof (INQUIRY_DATA);
+
+ Status = AtapiPacketCommandIn(
+ DeviceInfo,
+ &Packet,
+ (UINT16*)(&Idata),
+ sizeof (INQUIRY_DATA),
+ TIMEOUT
+ );
+
+ if ( Status != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( Idata.PeripheralDeviceType_0 == CD_ROM_DEVICE ) {
+ DeviceInfo->MediaInfo.DeviceType = IdeCDROM;
+ DeviceInfo->MediaInfo.MediaPresent = FALSE;
+ DeviceInfo->MediaInfo.LastBlock = 0;
+ DeviceInfo->MediaInfo.BlockSize = 0x800;
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_DetectMedia
+//
+// Description:
+// -Loop: Issues ATAPI packet command TEST_UNIT_READY.
+// If this is not successful, then look at SENSE data.
+// If you get the sense data for (1) becoming ready, (2) media
+// changed, or (3) power on reset, then stall for some time and
+// continue looping with TEST_UNIT_READY and REQUEST_SENSE.
+// -If TEST_UNIT_READY is successful, then issue READ_CAPACITY
+// packet command, which should get device info.
+// -If TEST_UNIT_READY is not succesful or if the SENSE data
+// contains some other error (not one of the three listed above),
+// then return an error.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Atapi_DetectMedia(
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo )
+{
+ UINTN Index = 0;
+ REQUEST_SENSE_DATA SenseBuffers[MAX_SENSE_KEY_COUNT];
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 SenseCounts = 0;
+ BOOLEAN DeviceIsReady = FALSE;
+
+ DeviceInfo->MediaInfo.MediaPresent = FALSE;
+ DeviceInfo->MediaInfo.LastBlock = 0;
+
+ DeviceIsReady = FALSE;
+
+ for ( Index = 0; Index < 50; Index++ ) {
+ Status = TestUnitReady( DeviceInfo );
+
+ if ( Status == EFI_SUCCESS ) {
+ DeviceIsReady = TRUE;
+ break;
+ }
+
+ SenseCounts = MAX_SENSE_KEY_COUNT;
+ Status = RequestSense( DeviceInfo, SenseBuffers, &SenseCounts );
+
+ if ( SenseCounts == 0 ) {
+ gStallPpi->Stall( gPeiServices, gStallPpi, 250000 );
+ continue;
+ }
+
+ if (((SenseBuffers[0].SenseKey_2 == SK_NOT_READY) && (SenseBuffers[0].AdditionalSenseCode_12 == 4) && (SenseBuffers[0].AdditionalSenseCodeQualifier_13 == 1)) // Becoming ready
+ || ((SenseBuffers[0].SenseKey_2 == SK_UNIT_ATTENTION) && (SenseBuffers[0].AdditionalSenseCode_12 == 0x28) && (SenseBuffers[0].AdditionalSenseCodeQualifier_13 == 0)) // Media Changed
+ || ((SenseBuffers[0].SenseKey_2 == SK_UNIT_ATTENTION) && (SenseBuffers[0].AdditionalSenseCode_12 == 0x29) && (SenseBuffers[0].AdditionalSenseCodeQualifier_13 == 0))) { // Power on Reset
+ gStallPpi->Stall( gPeiServices, gStallPpi, 250000 );
+ } else {
+ break;
+ }
+ }
+
+ if ( DeviceIsReady ) {
+ Status = ReadCapacity( DeviceInfo );
+ return Status;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: TestUnitReady
+//
+// Description: ATAPI command TEST_UINT_READY. Uses AtapiPacketCommandIn.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TestUnitReady(
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo )
+{
+ ATAPI_PACKET_COMMAND Packet;
+ EFI_STATUS Status;
+
+ ZeroMem( &Packet, sizeof (ATAPI_PACKET_COMMAND));
+ Packet.Cmd.OperationCode_0 = TEST_UNIT_READY;
+
+ Status = AtapiPacketCommandIn( DeviceInfo, &Packet, NULL, 0, TIMEOUT );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RequestSense
+//
+// Description: Send Request sense command
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RequestSense(
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ IN REQUEST_SENSE_DATA *SenseBuffers,
+ IN OUT UINT8 *SenseCounts )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ REQUEST_SENSE_DATA *Sense = SenseBuffers;
+ ATAPI_PACKET_COMMAND Packet;
+
+ ZeroMem( SenseBuffers, sizeof (REQUEST_SENSE_DATA) * (*SenseCounts));
+
+ ZeroMem( &Packet, sizeof (ATAPI_PACKET_COMMAND));
+ Packet.Cmd.OperationCode_0 = REQUEST_SENSE;
+ Packet.Cmd.AllocationLength_4 = sizeof (REQUEST_SENSE_DATA);
+
+ *SenseCounts = 0;
+
+ while ( TRUE ) {
+ Status = AtapiPacketCommandIn(
+ DeviceInfo,
+ &Packet,
+ (UINT16*) Sense,
+ sizeof (REQUEST_SENSE_DATA),
+ TIMEOUT
+ );
+
+ if ( Status != EFI_SUCCESS ) {
+ if ( *SenseCounts == 0 ) {
+ return EFI_DEVICE_ERROR;
+ } else {
+ return EFI_SUCCESS;
+ }
+ }
+
+ (*SenseCounts)++;
+
+ if ( *SenseCounts == MAX_SENSE_KEY_COUNT ) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // We limit MAX sense data count to 20 in order to avoid dead loop. Some
+ // incompatible ATAPI devices don't retrive NO_SENSE when there is no media.
+ // In this case, dead loop occurs if we don't have a gatekeeper. 20 is
+ // supposed to be large enough for any ATAPI device.
+ // (Actually 6, not 20).
+ if ( Sense->SenseKey_2 != SK_NO_SENSE ) {
+ Sense++;
+ } else {
+ return EFI_SUCCESS;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadCapacity
+//
+// Description: ATAPI packet command READ_CAPACITY.
+// Uses AtapiPacketCommandIn.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadCapacity(
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+ READ_CAPACITY_DATA Data;
+
+ ZeroMem( &Data, sizeof (Data));
+
+ if ( DeviceInfo->MediaInfo.DeviceType == IdeCDROM ) {
+ ZeroMem( &Packet, sizeof (ATAPI_PACKET_COMMAND));
+ Packet.Cmd.OperationCode_0 = READ_CAPACITY;
+ Status = AtapiPacketCommandIn(
+ DeviceInfo,
+ &Packet,
+ (UINT16*)(&Data),
+ sizeof (READ_CAPACITY_DATA),
+ LONGTIMEOUT
+ );
+
+ if ( Status == EFI_SUCCESS ) {
+ if ( DeviceInfo->MediaInfo.DeviceType == IdeCDROM ) {
+ DeviceInfo->MediaInfo.LastBlock = (Data.LastLba0 << 24) | (Data.LastLba1 << 16) | (Data.LastLba2 << 8) | Data.LastLba3;
+ DeviceInfo->MediaInfo.MediaPresent = TRUE;
+ DeviceInfo->MediaInfo.BlockSize = 0x800;
+ }
+ return EFI_SUCCESS;
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Atapi_ReadSectors
+//
+// Description: Helper function called by Atapi_ReadBlocks.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Atapi_ReadSectors(
+ IN OUT IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ IN VOID *Buffer,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN NumberOfBlocks,
+ IN UINTN BlockSize )
+{
+ ATAPI_PACKET_COMMAND Packet;
+ READ10_CMD *Read10Packet = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BlocksRemaining = 0;
+ UINT32 Lba32 = 0;
+ UINT32 ByteCount = 0;
+ UINT16 SectorCount = 0;
+ VOID *ptrBuffer = NULL;
+ UINT16 MaxBlock = 0;
+
+ ZeroMem( &Packet, sizeof (ATAPI_PACKET_COMMAND));
+
+ Read10Packet = &Packet.Read10;
+ Lba32 = (UINT32) StartLba;
+ ptrBuffer = Buffer;
+
+ //
+ // limit the data bytes that can be transfered by one Read(10) Command
+ //
+ MaxBlock = (UINT16) ( 0x10000 / BlockSize );
+ //
+ // (64k bytes)
+ //
+ BlocksRemaining = NumberOfBlocks;
+
+ Status = EFI_SUCCESS;
+ while ( BlocksRemaining > 0 ) {
+ if ( BlocksRemaining <= MaxBlock ) {
+ SectorCount = (UINT16) BlocksRemaining;
+ } else {
+ SectorCount = MaxBlock;
+ }
+
+ Read10Packet->OperationCode_0 = READ_10;
+
+ //
+ // Lba0 ~ Lba3 specify the start logical block address of the data transfer.
+ // Lba0 is MSB, Lba3 is LSB
+ //
+ Read10Packet->Lba3 = (UINT8) ( Lba32 & 0xff );
+ Read10Packet->Lba2 = (UINT8) ( Lba32 >> 8 );
+ Read10Packet->Lba1 = (UINT8) ( Lba32 >> 16 );
+ Read10Packet->Lba0 = (UINT8) ( Lba32 >> 24 );
+
+ //
+ // TransferLengthMSB ~ TransferLengthLSB specify the transfer length in block unit.
+ //
+ Read10Packet->TransferLengthLSB = (UINT8) ( SectorCount & 0xff );
+ Read10Packet->TransferLengthMSB = (UINT8) ( SectorCount >> 8 );
+
+ ByteCount = (UINT32) ( SectorCount * BlockSize );
+
+ Status = AtapiPacketCommandIn(
+ DeviceInfo,
+ &Packet,
+ (UINT16*) ptrBuffer,
+ ByteCount,
+ LONGTIMEOUT
+ );
+
+ if ( Status != EFI_SUCCESS ) {
+ return Status;
+ }
+
+ Lba32 += SectorCount;
+ ptrBuffer = (UINT8*) ptrBuffer + SectorCount * BlockSize;
+ BlocksRemaining -= SectorCount;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AtaPioDataIn
+//
+// Description: Does ATA protocol Pio In with data.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaPioDataIn(
+ IN IDE_BASE_REGISTERS *IdeIoPortRegisters,
+ OUT VOID *Buffer,
+ IN UINT32 ByteCount,
+ IN UINT8 SectorCount,
+ IN UINT8 SectorNumber,
+ IN UINT8 CylinderLsb,
+ IN UINT8 CylinderMsb,
+ IN UINT8 Device,
+ IN UINT8 Command )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ UINT16 HeadReg = IdeIoPortRegisters->Head;
+ UINT16 SectorCountReg = IdeIoPortRegisters->SectorCount;
+ UINT16 SectorNumberReg = IdeIoPortRegisters->SectorNumber;
+ UINT16 CylinderLsbReg = IdeIoPortRegisters->CylinderLsb;
+ UINT16 CylinderMsbReg = IdeIoPortRegisters->CylinderMsb;
+ UINT16 CommandReg = IdeIoPortRegisters->Reg.Command;
+ UINT16 AltStatusRegister = IdeIoPortRegisters->Alt.AltStatus;
+ UINT16 StatusReg = IdeIoPortRegisters->Reg.Status;
+ UINT16 DataReg = IdeIoPortRegisters->Data;
+
+ UINT32 WordCount = 0;
+ UINT32 Increment = 0;
+ UINT32 Index = 0;
+ UINT16 *Buffer16 = (UINT16*)Buffer;
+ ;
+
+ IoWrite8( HeadReg, Device );
+
+ Status = WaitForBSYClear( IdeIoPortRegisters, TIMEOUT );
+
+ if ( Status != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = DRQClear2( IdeIoPortRegisters, TIMEOUT );
+
+ if ( Status != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = DRQClear2( IdeIoPortRegisters, TIMEOUT );
+
+ if ( Status != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ IoWrite8( SectorCountReg, SectorCount );
+ IoWrite8( SectorNumberReg, SectorNumber );
+ IoWrite8( CylinderLsbReg, CylinderLsb );
+ IoWrite8( CylinderMsbReg, CylinderMsb );
+
+ IoWrite8( CommandReg, Command );
+
+ IoRead8( AltStatusRegister );
+
+ Increment = 256;
+ WordCount = 0;
+
+ while ( WordCount < ByteCount / 2 ) {
+ Status = DRQReady2( IdeIoPortRegisters, COMMAND_COMPLETE_TIMEOUT );
+
+ if ( Status != EFI_SUCCESS ) {
+ return Status;
+ }
+
+ if ( CheckErrorStatus( StatusReg ) != EFI_SUCCESS ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ((WordCount + Increment) > ByteCount / 2 ) {
+ Increment = ByteCount / 2 - WordCount;
+ }
+
+ for ( Index = 0; Index < Increment; Index++ )
+ {
+ *Buffer16++ = IoRead16( DataReg );
+ }
+
+ WordCount += Increment;
+ }
+
+ Status = DRQClear( IdeIoPortRegisters, TIMEOUT );
+
+ if ( Status != EFI_SUCCESS ) {
+ return CheckErrorStatus( StatusReg );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AtaIdentify
+//
+// Description: ATA Identify command. Uses AtaPioDataIn
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AtaIdentify(
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ OUT ATA_IDENTIFY_DATA *AtaIdentifyData )
+{
+ return AtaPioDataIn( DeviceInfo->IdeIoPortRegisters,
+ AtaIdentifyData,
+ sizeof (ATA_IDENTIFY_DATA),
+ 0,
+ 0,
+ 0,
+ 0,
+ DeviceInfo->Device << 4,
+ ATA_IDENTIFY_DEVICE_CMD
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: Ata_ReadSectors
+//
+// Description: Helper function called by Ata_ReadBlocks.
+//
+// Input:
+// IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo - pointer to the device info structure
+// IN OUT VOID *Buffer - Pointer to a buffer that will hold the Data that is read
+// IN EFI_PEI_LBA StartLba - the first LBA to read
+// IN UINTN NumberOfBlocks - total number of blocks to read
+// IN UINTN BlockSize - size of the blocks to be read
+//
+// Output:
+// EFI_SUCCESS - Read happened correctly
+// OTHER - any valid error from AtaPioDataIn()
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Ata_ReadSectors(
+ IN IDE_RECOVERY_DEVICE_INFO *DeviceInfo,
+ IN OUT VOID *Buffer,
+ IN EFI_PEI_LBA StartLba,
+ IN UINTN NumberOfBlocks,
+ IN UINTN BlockSize )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BlocksRemaining = 0;
+ UINT32 Lba32 = 0;
+ UINT8 LbaLow = 0;
+ UINT8 LbaMid = 0;
+ UINT8 LbaHigh = 0;
+ UINT32 ByteCount = 0;
+ UINT16 SectorCount = 0;
+ VOID *ptrBuffer = NULL;
+ UINT16 MaxBlock = 0;
+ UINT8 Dev = 0;
+ UINT8 Device = 0;
+
+ Lba32 = (UINT32) StartLba;
+ ptrBuffer = Buffer;
+
+ MaxBlock = (UINT16) ( 0x20000 / BlockSize );
+
+ BlocksRemaining = NumberOfBlocks;
+
+ Status = EFI_SUCCESS;
+ Dev = (DeviceInfo->Device << 4) | LBA_MODE;
+ while ( BlocksRemaining > 0 ) {
+ if ( BlocksRemaining < MaxBlock ) {
+ SectorCount = BlocksRemaining;
+ } else {
+ SectorCount = MaxBlock;
+ }
+ LbaLow = (UINT8) ( Lba32 & 0xff );
+ LbaMid = (UINT8) ( Lba32 >> 8 );
+ LbaHigh = (UINT8) ( Lba32 >> 16 );
+
+ ByteCount = (UINT32) ( SectorCount * BlockSize );
+
+ Dev |= (Lba32 >> 24);
+ Status = AtaPioDataIn( DeviceInfo->IdeIoPortRegisters,
+ ptrBuffer,
+ ByteCount,
+ (UINT8) SectorCount, //sector count
+ LbaLow, //sector number
+ LbaMid, //lsb
+ LbaHigh, //msb
+ Dev,
+ ATA_READ_SECTOR_CMD
+ );
+
+ if ( Status != EFI_SUCCESS ) {
+ return Status;
+ }
+
+ Lba32 += SectorCount;
+ ptrBuffer = (UINT8*) ptrBuffer + SectorCount * BlockSize;
+ BlocksRemaining -= SectorCount;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WaitForBitsToClear
+//
+// Description: Helper functin used by WaitForBSYClear, DRQClear, DRQClear2.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitForBitsToClear(
+ UINT16 Register,
+ UINT8 Bits,
+ UINTN TimeoutInMilliSeconds )
+{
+ UINTN Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
+ UINT8 StatusValue = 0;
+
+ do {
+ StatusValue = IoRead8( Register );
+
+ if ((StatusValue & Bits) == 0x00 ) {
+ break;
+ }
+
+ gStallPpi->Stall( gPeiServices, gStallPpi, 250 );
+
+ Delay--;
+ } while ( Delay );
+
+ if ( Delay == 0 ) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: WaitForBSYClear
+//
+// Description: Wait for busy bit to clear
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WaitForBSYClear(
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ return WaitForBitsToClear( IdeIoRegisters->Reg.Status, BSY, TimeoutInMilliSeconds );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DRQClear
+//
+// Description: Wait for the DRQ bit clear
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DRQClear(
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ return WaitForBitsToClear( IdeIoRegisters->Reg.Status, DRQ | BSY, TimeoutInMilliSeconds );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DRQClear2
+//
+// Description: Wait for the DRQ bit clear in Alternate Status Reg
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DRQClear2(
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ return WaitForBitsToClear( IdeIoRegisters->Alt.AltStatus, DRQ | BSY, TimeoutInMilliSeconds );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DRQReadyHelper
+//
+// Description:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DRQReadyHelper(
+ UINT16 StatusRegister,
+ UINT16 ErrorRegister,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ UINTN Delay = ((TimeoutInMilliSeconds * STALL_1_MILLI_SECOND) / 250) + 1;
+ UINT8 StatusValue = 0;
+ UINT8 ErrValue = 0;
+
+ do
+ {
+ //
+ // read Status Register will clear interrupt
+ //
+ StatusValue = IoRead8( StatusRegister );
+
+ //
+ // BSY==0,DRQ==1
+ //
+ if ((StatusValue & (BSY | DRQ)) == DRQ ) {
+ break;
+ }
+
+ if ((StatusValue & (BSY | ERR)) == ERR ) {
+ ErrValue = IoRead8( ErrorRegister );
+
+ if ((ErrValue & ABRT_ERR) == ABRT_ERR ) {
+ return EFI_ABORTED;
+ }
+ }
+
+ gStallPpi->Stall( gPeiServices, gStallPpi, 250 );
+
+ Delay--;
+ } while ( Delay );
+
+ if ( Delay == 0 ) {
+ return EFI_TIMEOUT;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DRQReady
+//
+// Description: Wait for the DRQ ready
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DRQReady(
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ return DRQReadyHelper( IdeIoRegisters->Reg.Status, IdeIoRegisters->Reg1.Error, TimeoutInMilliSeconds );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: DRQReady2
+//
+// Description: Wait for the DRQ Ready in Alternate Status Reg
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DRQReady2(
+ IN IDE_BASE_REGISTERS *IdeIoRegisters,
+ IN UINTN TimeoutInMilliSeconds )
+{
+ return DRQReadyHelper( IdeIoRegisters->Alt.AltStatus, IdeIoRegisters->Reg1.Error, TimeoutInMilliSeconds );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckErrorStatus
+//
+// Description: Check for the Errros.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckErrorStatus(
+ IN UINT16 StatusReg )
+{
+ UINT8 StatusValue = IoRead8( StatusReg );
+
+ if ((StatusValue & (ERR | DWF | CORR)) == 0 ) {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ZeroMem
+//
+// Description: Clear the Memory
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static
+VOID ZeroMem(
+ IN VOID *Buffer,
+ IN UINTN Size )
+{
+ UINT8 *ptr;
+
+ ptr = Buffer;
+ while ( Size-- )
+ {
+ *(ptr++) = 0;
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/ReFlash/Esrt.c b/Core/EM/Recovery/ReFlash/Esrt.c
new file mode 100644
index 0000000..1823328
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/Esrt.c
@@ -0,0 +1,415 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/Esrt.c 1 3/21/13 7:25a Thomaschen $
+//
+// $Revision: 1 $
+//
+// $Date: 3/21/13 7:25a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/Esrt.c $
+//
+// 1 3/21/13 7:25a Thomaschen
+//
+// 6 2/27/13 3:54p Artems
+// [TAG] EIP106722
+// [Category] Improvement
+// [Description] Used different GUID to differentiate between AMI and
+// Win8 firmware update
+// [Files] Esrt.c
+//
+// 5 2/07/13 5:26p Artems
+// [TAG] EIP106722
+// [Category] Improvement
+// [Description] Add creation of firmware update version from FID table
+// [Files] Esrt.c
+//
+// 4 2/05/13 1:41p Artems
+// [TAG] EIP111562
+// [Category] Improvement
+// [Description] Add Enable/Disable support for Windows8-style firmware
+// update
+// [Files] Esrt.c Reflash.c Reflash.sdl
+//
+// 3 1/02/13 12:18p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Flash update progress report changes:
+// - report progress in non-interactive flash update
+// - do not report progress in Win8-style flash update
+// [Files] ReflashWorker.c Reflash.h Esrt.c
+//
+// 2 8/02/12 11:59a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c
+// Esrt.c
+//
+// 1 7/20/12 10:20a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support for Microsoft ESRT spec
+// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c
+// Protocol.cif AmiReflashProtocol.h Setup.h
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Esrt.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+
+#if SUPPORT_WIN8_STYLE_FW_UPDATE
+
+#include <AmiHobs.h>
+#include <AmiDxeLib.h>
+#include <Capsule.h>
+#include <Setup.h>
+#include <PPI/FwVersion.h>
+#include <Protocol/AmiReflashProtocol.h>
+#include <Protocol/FirmwareVolume2.h>
+#include "Reflash.h"
+
+#define MAX_ESRT_ENTRIES 1
+
+#define FW_TYPE_UNKNOWN 0
+#define FW_TYPE_SYSTEM_FIRMWARE 1
+#define FW_TYPE_DEVICE_FIRMWARE 2
+#define FW_TYPE_FIRMWARE_DRIVER 3
+
+#define FW_UPDATE_STATUS_SUCCESS 0
+#define FW_UPDATE_STATUS_UNKNOWN_ERROR 1
+#define FW_UPDATE_STATUS_OUT_OF_RESOURCES 2
+#define FW_UPDATE_STATUS_INCORRECT_VERSION 3
+#define FW_UPDATE_STATUS_INVALID_FORMAT 4
+#define FW_UPDATE_STATUS_AUTHENTICATION_ERROR 5
+
+#define EFI_SYSTEM_RESOURCE_TABLE_GUID \
+ { 0xb122a263, 0x3661, 0x4f68, 0x99, 0x29, 0x78, 0xf8, 0xb0, 0xd6, 0x21, 0x80 }
+
+#define FID_FFS_FILE_NAME_GUID \
+ { 0x3fd1d3a2, 0x99f7, 0x420b, 0xbc, 0x69, 0x8b, 0xb1, 0xd4, 0x92, 0xa3, 0x32 }
+
+#define FID_FFS_FILE_SECTION_GUID \
+ { 0x2EBE0275, 0x6458, 0x4AF9, 0x91, 0xED, 0xD3, 0xF4, 0xED, 0xB1, 0x00, 0xAA }
+
+#pragma pack(push, 1)
+typedef struct _FIRMWARE_RESOURCE_ENTRY {
+ EFI_GUID FwClass;
+ UINT32 FwType;
+ UINT32 FwVersion;
+ UINT32 LowestSupportedFwVersion;
+ UINT32 CapsuleFlags;
+ UINT32 LastAttemptVersion;
+ UINT32 LastAttemptStatus;
+} FIRMWARE_RESOURCE_ENTRY;
+
+typedef struct _EFI_ESRT_TABLE {
+ UINT32 FwResourceCount;
+ UINT32 FwMaxResources;
+ UINT64 FwResourceVersion;
+ FIRMWARE_RESOURCE_ENTRY Entries[MAX_ESRT_ENTRIES];
+} EFI_ESRT_TABLE;
+
+#pragma pack(pop)
+
+static EFI_GUID SystemFirmwareUpdateClass = W8_FW_UPDATE_IMAGE_CAPSULE_GUID;
+static EFI_GUID SystemResourceTableGuid = EFI_SYSTEM_RESOURCE_TABLE_GUID;
+static EFI_GUID guidHob = HOB_LIST_GUID;
+static W8_IMAGE_CAPSULE *Image;
+
+static const UINT32 FidSignature = 0x44494624; //$FID
+
+EFI_STATUS GetDisplayImage(
+ IN EFI_REFLASH_PROTOCOL *This,
+ OUT UINTN *CoordinateX,
+ OUT UINTN *CoordinateY,
+ OUT VOID **ImageAddress
+);
+
+EFI_STATUS FwUpdate(
+ IN EFI_REFLASH_PROTOCOL *This
+);
+
+EFI_REFLASH_PROTOCOL AmiReflashProtocol = {
+ FwUpdate,
+ GetDisplayImage
+};
+
+EFI_STATUS GetFidFromFv(
+ OUT VOID *Fid
+)
+{
+ static EFI_GUID FidFileName = FID_FFS_FILE_NAME_GUID;
+ EFI_STATUS Status;
+ EFI_HANDLE *FvHandle;
+ UINTN FvCount;
+ UINTN i;
+ UINTN BufferSize;
+ VOID *Buffer;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvCount, &FvHandle);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < FvCount; i++)
+ {
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ UINT32 AuthStatus;
+ Status = pBS->HandleProtocol(FvHandle[i], &gEfiFirmwareVolume2ProtocolGuid, &Fv);
+ if (EFI_ERROR(Status))
+ continue;
+ Buffer = 0;
+ BufferSize = 0;
+ Status = Fv->ReadSection(Fv, &FidFileName, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 0, &Buffer, &BufferSize, &AuthStatus);
+ TRACE((-1, "extracted section with guid %g\n", (EFI_GUID *)Buffer));
+ if (!EFI_ERROR(Status)) {
+ (UINT8 *)Buffer += sizeof(EFI_GUID);
+ MemCpy(Fid, Buffer, sizeof(FW_VERSION));
+ (UINT8 *)Buffer -= sizeof(EFI_GUID);
+ pBS->FreePool(Buffer);
+ return EFI_SUCCESS;
+ }
+ }
+ pBS->FreePool(FvHandle);
+ return EFI_NOT_FOUND;
+}
+
+EFI_STATUS GetFidFromBuffer(
+ IN VOID *Buffer,
+ OUT VOID *Fid
+)
+{
+ static EFI_GUID FidSectionGuid = FID_FFS_FILE_SECTION_GUID;
+ UINT32 Signature;
+ UINT32 *SearchPointer;
+ UINT32 *FidPointer;
+
+ SearchPointer = (UINT32 *)((UINT8 *)Buffer - sizeof(EFI_GUID) + FLASH_SIZE);
+ Signature = FidSectionGuid.Data1;
+
+ do {
+ if(*SearchPointer == Signature) {
+ if(!guidcmp(&FidSectionGuid, (EFI_GUID *)SearchPointer)) {
+ FidPointer = (UINT32 *)((EFI_GUID *)SearchPointer + 1);
+ if(*FidPointer == FidSignature) {
+ MemCpy(Fid, FidPointer, sizeof(FW_VERSION));
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ } while(SearchPointer-- >= (UINT32 *)Buffer);
+
+ return EFI_NOT_FOUND;
+}
+
+UINT32 GetVersionFromFid(
+ VOID *Image OPTIONAL
+)
+{
+ FW_VERSION Fid;
+ UINT32 Version;
+ EFI_STATUS Status;
+
+ if(Image == NULL)
+ Status = GetFidFromFv(&Fid);
+ else
+ Status = GetFidFromBuffer(Image, &Fid);
+
+ if(EFI_ERROR(Status))
+ return 0;
+
+ Version = Atoi(Fid.ProjectMajorVersion);
+ Version <<= 16;
+ Version += Atoi(Fid.ProjectMinorVersion);
+ return Version;
+}
+
+EFI_STATUS InstallEsrtTable(
+ VOID
+)
+{
+ static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHit;
+ EFI_STATUS Status;
+ UINTN Size = sizeof(UINT32);
+ UINT32 Version;
+ EFI_ESRT_TABLE *EsrtTable;
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, sizeof(EFI_ESRT_TABLE), &EsrtTable);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ EsrtTable->FwResourceCount = 1;
+ EsrtTable->FwMaxResources = MAX_ESRT_ENTRIES;
+ EsrtTable->FwResourceVersion = 1;
+
+ EsrtTable->Entries[0].FwClass = SystemFirmwareUpdateClass;
+ EsrtTable->Entries[0].FwType = FW_TYPE_SYSTEM_FIRMWARE;
+ EsrtTable->Entries[0].FwVersion = GetVersionFromFid(NULL);
+ EsrtTable->Entries[0].LowestSupportedFwVersion = EsrtTable->Entries[0].FwVersion; //no rollback allowed
+ EsrtTable->Entries[0].CapsuleFlags = 0;
+
+ Status = pRS->GetVariable(FW_VERSION_VARIABLE, &gAmiGlobalVariableGuid, NULL, &Size, &Version);
+ if(!EFI_ERROR(Status)) {
+ EsrtTable->Entries[0].LastAttemptVersion = Version;
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_UNKNOWN_ERROR;
+ } else {
+ pHit = GetEfiConfigurationTable(pST, &guidHob);
+ if(pHit != NULL && !EFI_ERROR(FindNextHobByGuid(&RecoveryHobGuid, &pHit))) {
+ EsrtTable->Entries[0].LastAttemptVersion = GetVersionFromFid((VOID *)(UINTN)((RECOVERY_IMAGE_HOB*)pHit)->Address);
+ switch(((RECOVERY_IMAGE_HOB*)pHit)->FailedStage) {
+ case 0: //no authentication/verification error
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_UNKNOWN_ERROR;
+ break;
+ case 1:
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_INVALID_FORMAT;
+ break;
+ case 2:
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_AUTHENTICATION_ERROR;
+ break;
+ case 3:
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_AUTHENTICATION_ERROR;
+ break;
+ case 4:
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_INCORRECT_VERSION;
+ break;
+ default:
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_UNKNOWN_ERROR;
+ break;
+ }
+ } else { //recovery hob not found - regular boot
+ EsrtTable->Entries[0].LastAttemptVersion = EsrtTable->Entries[0].FwVersion;
+ EsrtTable->Entries[0].LastAttemptStatus = FW_UPDATE_STATUS_SUCCESS;
+ }
+ }
+
+ Status = pBS->InstallConfigurationTable(&SystemResourceTableGuid, EsrtTable);
+ return Status;
+}
+
+EFI_STATUS IsWin8Update(
+ BOOLEAN RecoveryFailed
+)
+{
+ AMI_CAPSULE_HOB *Hob;
+ static EFI_GUID AmiCapsuleHobGuid = AMI_CAPSULE_HOB_GUID;
+ static EFI_GUID ImageCapsuleGuid = W8_SCREEN_IMAGE_CAPSULE_GUID;
+ static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID;
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+ UINT32 BootFlow = BOOT_FLOW_CONDITION_OS_UPD_CAP;
+
+ Hob = GetEfiConfigurationTable(pST, &guidHob);
+ if(Hob == NULL)
+ return EFI_NOT_FOUND;
+
+ do {
+ Status = FindNextHobByGuid(&AmiCapsuleHobGuid, &Hob);
+ if(!EFI_ERROR(Status) && !guidcmp(&(Hob->CapsuleGuid), &ImageCapsuleGuid))
+ break;
+ } while(!EFI_ERROR(Status));
+
+ if(EFI_ERROR(Status)) //no image hob - we're not on OS FW update path
+ return Status;
+
+ if(RecoveryFailed) { //we're on OS FW update path, but recovery can't be performed
+ InstallEsrtTable();
+ return EFI_UNLOAD_IMAGE;
+ }
+
+//save image capsule pointer
+ Image = (W8_IMAGE_CAPSULE *)(VOID *)(UINTN)(Hob->CapsuleData);
+//install reflash protocol
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gAmiReflashProtocolGuid,
+ &AmiReflashProtocol,
+ NULL);
+ if(EFI_ERROR(Status))
+ return Status;
+
+//set boot flow
+ pRS->SetVariable(L"BootFlow", &guidBootFlow, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(BootFlow), &BootFlow);
+ return Status;
+}
+
+EFI_STATUS GetDisplayImage(
+ IN EFI_REFLASH_PROTOCOL *This,
+ OUT UINTN *CoordinateX,
+ OUT UINTN *CoordinateY,
+ OUT VOID **ImageAddress
+)
+{
+ if(CoordinateX == NULL ||
+ CoordinateY == NULL ||
+ ImageAddress == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ *CoordinateX = Image->ImageOffsetX;
+ *CoordinateY = Image->ImageOffsetY;
+ *ImageAddress = Image->Image;
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS FwUpdate(
+ IN EFI_REFLASH_PROTOCOL *This
+)
+{
+ EFI_STATUS Status;
+ UINT32 Version;
+
+/* set version we're upgrading to */
+ Version = GetVersionFromFid(RecoveryBuffer);
+ Status = pRS->SetVariable(FW_VERSION_VARIABLE, &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32), &Version);
+
+ Status = Prologue(FALSE, TRUE);
+ if(EFI_ERROR(Status))
+ pRS->ResetSystem(EfiResetCold, Status, 0, NULL);
+
+ Status = FlashWalker(FALSE);
+ if(EFI_ERROR(Status))
+ pRS->ResetSystem(EfiResetCold, Status, 0, NULL);
+
+ Status = Epilogue();
+ return Status;
+}
+
+#endif // #if SUPPORT_WIN8_STYLE_FW_UPDATE
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.c b/Core/EM/Recovery/ReFlash/ReFlash.c
new file mode 100644
index 0000000..773d7f9
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.c
@@ -0,0 +1,601 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.c 3 10/01/13 2:03a Thomaschen $
+//
+// $Revision: 3 $
+//
+// $Date: 10/01/13 2:03a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.c $
+//
+// 3 10/01/13 2:03a Thomaschen
+// Update for EIP137328.
+//
+// 2 4/16/13 5:48a Thomaschen
+// Fixed for EIP106722.
+//
+//
+// 40 2/11/13 3:41p Artems
+// [TAG] EIP112180
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] In non-interactive mode system updated flash even when
+// there is no valid image
+// [RootCause] In non-interactive mode system didn't check flash image
+// validity
+// [Solution] Added check of flash image validity. Inform user if image
+// is invalid or not found
+// [Files] Reflash.c ReflashWorker.c Reflash.uni Reflash.vfr
+//
+// 39 2/05/13 1:41p Artems
+// [TAG] EIP111562
+// [Category] Improvement
+// [Description] Add Enable/Disable support for Windows8-style firmware
+// update
+// [Files] Esrt.c Reflash.c Reflash.sdl
+//
+// 38 7/20/12 10:17a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c
+// Protocol.cif AmiReflashProtocol.h Setup.h
+//
+// 37 5/22/12 4:54p Artems
+// [TAG] EIP88314
+// [Category] Improvement
+// [Description] Recovery takes a long time for large flash size
+// Rewrite reflash code to not give control back to TSE until finished
+// reporting progress via DisplayProgress API of AMI Post manager
+// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr
+// Reflash.uni
+//
+// 36 4/09/12 6:03p Artems
+// Undo previous change
+//
+// 35 2/08/12 4:27a Nerofan
+// Update it for capsule function if memory size is over 2G.
+//
+// 34 12/05/11 1:49p Artems
+// EIP 74623: Add capabilities similar to ones in SMIFlash module
+//
+// 33 11/14/11 4:07p Artems
+// Fixed bug with hob size comparison
+// Set default attributes for Reflash Setup variable
+//
+// 32 11/14/11 3:18p Artems
+// Defined Extended errors for security recovery capsule check
+//
+// 31 11/12/11 6:48p Artems
+// Added fault tolerant recovery support
+//
+// 30 11/02/11 4:54p Artems
+// EIP 74446: Fixed bug - reflash is enabled when recovery image is not
+// found
+//
+// 29 5/13/11 4:51p Artems
+// Added secure flash recovery/update support. Extended error reporting
+// Added handling of unsupported FormBrowser actions
+//
+// 28 5/05/11 2:00p Artems
+// Bugfix: callback supports only "CHANGING" browser action
+//
+// 27 5/04/11 5:54p Artems
+// Bugfix: function FlashProgress output parameter ActionRequest was
+// undefined
+//
+// 26 11/17/10 2:52p Felixp
+// Enhencement (EIP 36355):
+// The Reflash component is updated to be extensible with external
+// eModules.
+// The eModules can contribute content for the Recovery setup page,
+// and provide callback function that will be periodically called
+// once BIOS update is completed.The external eModules can be used
+// to implement update of non-standard firmware components.
+// For example, update of the non-shared EC firmware.
+//
+// 25 10/07/10 11:02a Felixp
+// FlashDeviceWriteEnable/FlashDeviceWriteDisable calls added.
+//
+// 24 10/01/10 2:14p Felixp
+// Previous changes related to descrete EC firmware update are rolled back
+// for the Core labeling.
+//
+// 22 12/24/09 12:42p Oleksiyy
+// EIP 30173: Support for the EC Firmware Area Update control added. Main
+// token to enable this support is EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+// should be located in specific EC-related .sdl file.
+//
+// 21 11/25/09 11:38a Felixp
+//
+// 20 11/25/09 11:27a Felixp
+// Action parameter of the Callback function is updated based on UEFI
+// errata
+//
+// 19 10/09/09 6:30p Felixp
+// ReFlash component is updated to support Framework and UEFI 2.1 HII
+//
+// 18 8/25/09 5:29p Felixp
+// Recovery module is updated to pass recovery image location via special
+// GUIDed HOB.
+// Old implementation that was relying on Firmware Volume (FV) handle,
+// required porting for a projects with non standard FV management policy.
+//
+// 17 7/09/09 5:59p Oleksiyy
+// Files clean-up, some headers added
+//
+// 16 5/21/09 4:44p Felixp
+// ReFlash driver is updated to use FlashProtocol instead of Flash library
+// functions.
+//
+// 15 1/02/09 1:14p Felixp
+// Bug fix: initialize size before call to GetVariable
+//
+// 14 10/10/08 5:30p Felixp
+//
+// 13 3/12/08 2:55p Felixp
+// Error code reporting when flash update failed added
+//
+// 12 10/19/07 6:23p Felixp
+// Recovery Flash Update module extended to support Boot Block update.
+// Boot block update can be enabled or disabled using SDL token.
+// In addition to that there is an SDL token that enables/disables
+// checkbox on the
+// recovery setup page that user can use to enable or disable boot block
+// update.
+//
+// 11 4/13/07 6:07p Ambikas
+// Coding standard changes: updated the year in the AMI copyright
+// header/footer.
+//
+// 10 1/26/07 10:31a Anandakrishnanl
+// Added Flash Device Write Enabling and Disabling code to make the device
+// Write wnable before Flash Block writes.
+//
+// 9 12/29/06 2:58p Felixp
+// Updated to use new Flash Interface
+//
+// 8 12/22/06 9:38a Felixp
+// Support for optional NVRAM reset based on user input added
+//
+// 7 12/20/06 1:36p Felixp
+//
+// 6 10/30/06 5:44p Felixp
+// Updated to be complient with HII Spec. 0.92 (used to be 0.91)
+//
+// 5 10/27/06 11:48a Felixp
+// Flash related external variables from Tokens.c are used (instead of
+// global variables declared in Reflash.c)
+//
+// 4 8/24/06 9:19a Felixp
+// x64 Support
+//
+// 3 4/12/06 5:49p Felixp
+//
+// 2 3/13/06 1:47a Felixp
+//
+// 1 12/01/05 9:35a Felixp
+//
+// 1 11/08/05 4:04a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ReFlash.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <HOB.h>
+#include <Flash.h>
+#include <AmiCspLib.h>
+#include <AmiHobs.h>
+#include "ReFlash.h"
+
+
+static EFI_GUID guidRecovery = RECOVERY_FORM_SET_GUID;
+EFI_HANDLE ThisImageHandle;
+FLASH_PROTOCOL *Flash;
+EFI_HII_HANDLE ReflashHiiHandle = NULL;
+UINT8 *RecoveryBuffer = NULL;
+EFI_STATUS RecoveryStatus = EFI_SUCCESS;
+
+
+EFI_HII_CONFIG_ACCESS_PROTOCOL CallBack = { NULL,NULL,FlashProgressEx };
+
+CALLBACK_INFO SetupCallBack[] =
+{
+ // Last field in every structure will be filled by the Setup
+ { &guidRecovery, &CallBack, RECOVERY_FORM_SET_CLASS, 0, 0},
+};
+
+
+//-------------------------------
+//Before flash and After flash eLinks
+
+typedef VOID (OEM_FLASH_UPDATE_CALLBACK) (VOID);
+extern OEM_FLASH_UPDATE_CALLBACK OEM_BEFORE_FLASH_UPDATE_CALLBACK_LIST EndOfList;
+extern OEM_FLASH_UPDATE_CALLBACK OEM_AFTER_FLASH_UPDATE_CALLBACK_LIST EndOfList;
+OEM_FLASH_UPDATE_CALLBACK* OemBeforeFlashCallbackList[] = { OEM_BEFORE_FLASH_UPDATE_CALLBACK_LIST NULL };
+OEM_FLASH_UPDATE_CALLBACK* OemAfterFlashCallbackList[] = { OEM_AFTER_FLASH_UPDATE_CALLBACK_LIST NULL };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OemBeforeFlashCallback
+//
+// Description: This function executes OEM porting hooks before starting flash update
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemBeforeFlashCallback(
+ VOID
+)
+{
+ UINT32 i;
+ for(i = 0; OemBeforeFlashCallbackList[i] != NULL; i++)
+ OemBeforeFlashCallbackList[i]();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OemAfterFlashCallback
+//
+// Description: This function executes OEM porting hooks after finishing flash update
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemAfterFlashCallback(
+ VOID
+)
+{
+ UINT32 i;
+ for(i = 0; OemAfterFlashCallbackList[i] != NULL; i++)
+ OemAfterFlashCallbackList[i]();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHiiString
+//
+// Description: This function reads a string from HII
+//
+// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle
+// IN STRING_REF Token - String Token
+// IN OUT UINTN *pDataSize - Length of the StringBuffer
+// OUT EFI_STRING *ppData - The buffer to receive the characters in the string.
+//
+// Output: EFI_STATUS - Depending on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetHiiString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF Token,
+ IN OUT UINTN *pDataSize,
+ OUT EFI_STRING *ppData
+)
+{
+ EFI_STATUS Status;
+
+ if (!*ppData) *pDataSize=0;
+
+ Status = HiiLibGetString(HiiHandle, Token, pDataSize, *ppData);
+ if (!EFI_ERROR(Status)) return Status;
+ //--- If size was too small free pool and try with right size, which was passed
+ if (Status==EFI_BUFFER_TOO_SMALL)
+ {
+ if (*ppData) pBS->FreePool(*ppData);
+
+ if (!(*ppData=Malloc(*pDataSize))) return EFI_OUT_OF_RESOURCES;
+
+ Status = HiiLibGetString(HiiHandle, Token, pDataSize, *ppData);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ApplyUserSelection
+//
+// Description: This function updates flash parameteres based on user selection
+// or Setup values
+//
+// Input:
+// IN BOOLEAN Interactive - if TRUE get selection from user input, otherwise
+// use Setup values
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ApplyUserSelection(
+ IN BOOLEAN Interactive
+)
+{
+ EFI_STATUS Status;
+ AUTOFLASH FlashUpdateControl;
+ UINTN Size = sizeof(FlashUpdateControl);
+ UINT32 i;
+
+ if(Interactive) {
+ /* get values from Setup Browser */
+ Status = HiiLibGetBrowserData(&Size, &FlashUpdateControl, &guidRecovery, L"Setup");
+ } else {
+ /* get values from NVRAM */
+ Status = pRS->GetVariable(L"Setup", &guidRecovery, NULL, &Size, &FlashUpdateControl);
+ }
+ if(EFI_ERROR(Status)) {
+ /* no user selection, use defaults */
+ FlashUpdateControl.UpdateMain = REFLASH_UPDATE_MAIN_BLOCK;
+ FlashUpdateControl.UpdateBb = REFLASH_UPDATE_BOOT_BLOCK;
+ FlashUpdateControl.UpdateNv = REFLASH_UPDATE_NVRAM;
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ FlashUpdateControl.UpdateEC = REFLASH_UPDATE_EC_FIRMWARE;
+#endif
+ }
+
+ for(i = 0; BlocksToUpdate[i].Type != FvTypeMax; i++) {
+ switch(BlocksToUpdate[i].Type) {
+ case FvTypeMain:
+ BlocksToUpdate[i].Update = FlashUpdateControl.UpdateMain;
+#if FtRecovery_SUPPORT
+ if(FlashUpdateControl.UpdateBb == 1)
+ BlocksToUpdate[i].Update = TRUE; //with fault tolerant recovery FV_MAIN is used for backup - force update
+#endif
+ break;
+ case FvTypeBootBlock:
+ BlocksToUpdate[i].Update = FlashUpdateControl.UpdateBb;
+#if FtRecovery_SUPPORT
+ if(IsTopSwapOn()) //if we're here BB update failed we use backup copy - force BB update again
+ BlocksToUpdate[i].Update = TRUE;
+#endif
+ break;
+ case FvTypeNvRam:
+ BlocksToUpdate[i].Update = FlashUpdateControl.UpdateNv;
+ break;
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ case FvTypeCustom:
+ BlocksToUpdate[i].Update = FlashUpdateControl.UpdateEC;
+ break;
+#endif
+ default:
+ break;
+ }
+ }
+}
+
+//----------------------------------------------------------------------------
+// IsRecovery prototypes
+//----------------------------------------------------------------------------
+// Bit Mask of checks to perform on Aptio FW Image
+// 1- Capsule integrity
+// 2- Verify Signature
+// 3- Verify FW Key
+// 4- Verify FW Version compatibility.
+// To prevent possible re-play attack:
+// update current FW with older version with lower security.
+// 5- Compare MonotonicCounters/date. Replay attack
+//----------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSetupStrings
+//
+// Description: This function updates status strings in setup window, based
+// on execution results
+//
+// Input:
+// IN EFI_HII_HANDLE Handle - handle of Reflash setup formset (page)
+// IN EFI_STATUS Error - execution error if any
+// IN UINT32 FailedStage - in case of authentication error failed stage description
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateSetupStrings(
+ IN EFI_HII_HANDLE Handle,
+ IN EFI_STATUS Error,
+ IN UINT32 FailedStage
+)
+{
+ UINTN Size;
+ EFI_STRING Template = NULL;
+ EFI_STRING Template2 = NULL;
+ CHAR16 ReportString[100];
+
+ if(!EFI_ERROR(Error)) {
+ GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE1_SUCCESS), &Size, &Template);
+ if(FailedStage == 0)
+ GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE2_SUCCESS), &Size, &Template2);
+ else //if we're here we're on manual BIOS rollback to older version
+ GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE2_ROLLBACK_WARNING), &Size, &Template2);
+
+ if(Template != NULL) {
+ HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE1), Template);
+ pBS->FreePool(Template);
+ }
+
+ if(Template2 != NULL) {
+ HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE2), Template2);
+ pBS->FreePool(Template2);
+ }
+
+ return;
+ }
+
+//Get Error string template
+ GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE1_ERROR), &Size, &Template);
+ if(Template != NULL) {
+ HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE1), Template);
+ pBS->FreePool(Template);
+ Template = NULL;
+ }
+
+ GetHiiString(Handle, STRING_TOKEN(STR_SUBTITLE2_ERROR_TEMPLATE), &Size, &Template);
+ switch(FailedStage) {
+ case InvalidHeader:
+ GetHiiString(Handle, STRING_TOKEN(STR_ERR), &Size, &Template2);
+ break;
+ case InvalidSignature:
+ GetHiiString(Handle, STRING_TOKEN(STR_ERR1), &Size, &Template2);
+ break;
+ case IvalidPlatformKey:
+ GetHiiString(Handle, STRING_TOKEN(STR_ERR2), &Size, &Template2);
+ break;
+ case InvalidFwVersion:
+ GetHiiString(Handle, STRING_TOKEN(STR_ERR3), &Size, &Template2);
+ break;
+ default:
+ GetHiiString(Handle, STRING_TOKEN(STR_ERR4), &Size, &Template2);
+ break;
+ }
+
+ if((Template != NULL) && (Template2 != NULL)) {
+ Swprintf(ReportString, Template, Error, Template2);
+ HiiLibSetString(Handle, STRING_TOKEN(STR_SUBTITLE2), ReportString);
+ pBS->FreePool(Template);
+ pBS->FreePool(Template2);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReFlashEntry
+//
+// Description: This is the standard EFI driver entry point called for
+// Recovery flash module initlaization
+// Input: IN EFI_HANDLE ImageHandle - ImageHandle of the loaded driver
+// IN EFI_SYSTEM_TABLE SystemTable - Pointer to the System Table
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EFIAPI ReFlashEntry (IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ static EFI_GUID guidHob = HOB_LIST_GUID;
+ static EFI_GUID guidBootFlow = BOOT_FLOW_VARIABLE_GUID;
+ static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ UINT32 BootFlow = BOOT_FLOW_CONDITION_RECOVERY;
+ EFI_HOB_HANDOFF_INFO_TABLE *pHit;
+ UINTN Size;
+ UINT32 Attributes;
+ UINT32 FailedStage;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ AUTOFLASH AutoFlash = {
+ (UINT8)(EFI_SUCCESS),
+ REFLASH_UPDATE_NVRAM,
+ REFLASH_UPDATE_BOOT_BLOCK,
+ REFLASH_UPDATE_MAIN_BLOCK
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ ,REFLASH_UPDATE_EC_FIRMWARE
+#endif
+ };
+
+ ThisImageHandle = ImageHandle;
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //Get Boot Mode
+ pHit = GetEfiConfigurationTable(pST, &guidHob);
+
+ //unload the module if we are not in recovery mode
+ // TODO:need to distinguish between recovery and Flash Update
+ if (!pHit || (pHit->BootMode != BOOT_IN_RECOVERY_MODE && pHit->BootMode != BOOT_ON_FLASH_UPDATE)) {
+#if SUPPORT_WIN8_STYLE_FW_UPDATE
+ InstallEsrtTable();
+#endif
+ return EFI_UNLOAD_IMAGE;
+ }
+
+ VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashProtocolGuid, NULL, &Flash));
+//Get Recovery Image verification status
+ if(!EFI_ERROR(FindNextHobByGuid(&RecoveryHobGuid, &pHit))) {
+ if(((EFI_HOB_GENERIC_HEADER *)pHit)->HobLength < sizeof(RECOVERY_IMAGE_HOB)) {
+ //we got update from older Core here
+ FailedStage = 0;
+ RecoveryStatus = EFI_SUCCESS;
+ } else {
+ FailedStage = ((RECOVERY_IMAGE_HOB*)pHit)->FailedStage;
+ RecoveryStatus = ((RECOVERY_IMAGE_HOB*)pHit)->Status;
+
+ //Since RECOVERY_IMAGE_HOB Status field is byte long, we should set error bit by ourselves
+ if(RecoveryStatus != NULL)
+ RecoveryStatus |= EFI_ERROR_BIT;
+ }
+ RecoveryBuffer = (UINT8 *)(UINTN)((RECOVERY_IMAGE_HOB*)pHit)->Address;
+ } else { //Recovery Hob not found - should not happen, we always create this hob to report errors
+ FailedStage = 0;
+ RecoveryStatus = EFI_ABORTED;
+ }
+
+ AutoFlash.FailedRecovery = (UINT8)RecoveryStatus;
+
+//Update Reflash parameters
+ Size = sizeof(AUTOFLASH);
+ Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
+ pRS->SetVariable(L"Setup", &guidRecovery, Attributes, Size, &AutoFlash);
+
+#if SUPPORT_WIN8_STYLE_FW_UPDATE
+//Verify if we're on OS firmware update path
+ Status = IsWin8Update((EFI_ERROR(RecoveryStatus)) ? TRUE : FALSE);
+ if(Status == EFI_SUCCESS || Status == EFI_UNLOAD_IMAGE)
+ return Status;
+#endif
+
+//Load setup page and create error message if necessary
+ LoadResources(ImageHandle, sizeof(SetupCallBack) / sizeof(CALLBACK_INFO), SetupCallBack, NULL);
+ ReflashHiiHandle = SetupCallBack[0].HiiHandle;
+ pRS->SetVariable(L"BootFlow", &guidBootFlow, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(BootFlow), &BootFlow);
+
+ UpdateSetupStrings(ReflashHiiHandle, RecoveryStatus, FailedStage);
+
+ return EFI_SUCCESS;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.cif b/Core/EM/Recovery/ReFlash/ReFlash.cif
new file mode 100644
index 0000000..8d76667
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "ReFlash"
+ category = ModulePart
+ LocalRoot = "Core\EM\Recovery\ReFlash\"
+ RefName = "ReFlash"
+[files]
+"ReFlash.sdl"
+"ReFlash.mak"
+"ReFlash.vfr"
+"ReFlash.c"
+"ReFlashWorker.c"
+"ReFlash.dxs"
+"ReFlash.uni"
+"ReFlash.h"
+"Esrt.c"
+<endComponent>
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.dxs b/Core/EM/Recovery/ReFlash/ReFlash.dxs
new file mode 100644
index 0000000..11e6c8d
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.dxs
@@ -0,0 +1,72 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Recovery/ReFlash.dxs 3 10/09/09 6:30p Felixp $
+//
+// $Revision: 3 $
+//
+// $Date: 10/09/09 6:30p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Recovery/ReFlash.dxs $
+//
+// 3 10/09/09 6:30p Felixp
+// ReFlash component is updated to support Framework and UEFI 2.1 HII
+//
+// 2 5/21/09 4:44p Felixp
+// ReFlash driver is updated to use FlashProtocol instead of Flash library
+// functions.
+//
+// 1 12/01/05 9:35a Felixp
+//
+// 1 11/08/05 4:04a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ReFlash.dxs
+//
+// Description: Dependancy expression for the component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#if EFI_SPECIFICATION_VERSION>0x20000
+#include <Protocol/HiiDatabase.h>
+#else
+#include <Protocol/HII.h>
+#endif
+#include <Protocol/FlashProtocol.h>
+DEPENDENCY_START
+#if EFI_SPECIFICATION_VERSION>0x20000
+ EFI_HII_DATABASE_PROTOCOL_GUID
+#else
+ EFI_HII_PROTOCOL_GUID
+#endif
+ AND FLASH_PROTOCOL_GUID
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.h b/Core/EM/Recovery/ReFlash/ReFlash.h
new file mode 100644
index 0000000..26ad479
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.h
@@ -0,0 +1,268 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.h 2 4/16/13 5:50a Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 4/16/13 5:50a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlash.h $
+//
+// 2 4/16/13 5:50a Thomaschen
+// Fixed for EIP106722.
+//
+// 13 1/02/13 12:18p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Flash update progress report changes:
+// - report progress in non-interactive flash update
+// - do not report progress in Win8-style flash update
+// [Files] ReflashWorker.c Reflash.h Esrt.c
+//
+// 12 7/20/12 10:20a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c
+// Protocol.cif AmiReflashProtocol.h Setup.h
+//
+// 11 5/22/12 4:44p Artems
+// [TAG] EIP88314
+// [Description] Recovery takes a long time for large flash size
+// Rewrite reflash code to not give control back to TSE until finished
+// reporting progress via DisplayProgress API of AMI Post manager
+// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr
+// Reflash.uni
+//
+// 10 11/12/11 6:49p Artems
+// Added fault tolerant recovery support
+//
+// 9 5/13/11 4:52p Artems
+// Added extended error reporting for secure flash update/recovery
+//
+// 8 11/17/10 2:52p Felixp
+// Enhencement (EIP 36355):
+// The Reflash component is updated to be extensible with external
+// eModules.
+// The eModules can contribute content for the Recovery setup page,
+// and provide callback function that will be periodically called
+// once BIOS update is completed.The external eModules can be used
+// to implement update of non-standard firmware components.
+// For example, update of the non-shared EC firmware.
+//
+// 7 12/24/09 12:42p Oleksiyy
+// EIP 30173: Support for the EC Firmware Area Update control added. Main
+// token to enable this support is EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+// should be located in specific EC-related .sdl file.
+//
+// 6 10/09/09 6:30p Felixp
+// ReFlash component is updated to support Framework and UEFI 2.1 HII
+//
+// 5 7/09/09 5:59p Oleksiyy
+// Files clean-up, some headers added
+//
+// 4 10/19/07 6:23p Felixp
+// Recovery Flash Update module extended to support Boot Block update.
+// Boot block update can be enabled or disabled using SDL token.
+// In addition to that there is an SDL token that enables/disables
+// checkbox on the
+// recovery setup page that user can use to enable or disable boot block
+// update.
+//
+// 3 4/13/07 6:08p Ambikas
+// Coding standard changes: updated the year in the AMI copyright
+// header/footer.
+//
+// 2 12/22/06 9:38a Felixp
+// Support for optional NVRAM reset based on user input added
+//
+// 1 12/01/05 9:35a Felixp
+//
+// 1 11/08/05 4:04a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ReFlash.h
+//
+// Description: Header file for component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __REFLASH__H__
+#define __REFLASH__H__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+#include <ReFlashStrTokens.h>
+#include <Token.h>
+#ifndef VFRCOMPILE
+#include <AmiDxeLib.h>
+#include <Protocol/FlashProtocol.h>
+#endif
+
+#define RECOVERY_FORM_SET_CLASS 0x40
+// {80E1202E-2697-4264-9CC9-80762C3E5863}
+#define RECOVERY_FORM_SET_GUID { 0x80e1202e, 0x2697, 0x4264, 0x9c, 0xc9, 0x80, 0x76, 0x2c, 0x3e, 0x58, 0x63 }
+
+#if REFLASH_INTERACTIVE
+#define RECOVERY_MAIN 1
+#define RECOVERY_FLASH 2
+#else
+#define RECOVERY_FLASH 1
+#endif
+
+#define FLASH_PROGRESS_KEY 100
+#define FLASH_START_KEY 101
+
+#pragma pack(push, 1)
+typedef struct {
+ UINT8 FailedRecovery; // EFI_STATUS error code
+ UINT8 UpdateNv;
+ UINT8 UpdateBb;
+ UINT8 UpdateMain;
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ UINT8 UpdateEC;
+#endif
+
+#define REFLASH_DATA_DEFINITION
+#include <ReflashDefinitions.h>
+#undef REFLASH_DATA_DEFINITION
+
+} AUTOFLASH;
+#pragma pack(pop)
+
+#include <Setup.h>
+
+#ifndef VFRCOMPILE
+
+#define FW_VERSION_VARIABLE L"AmiFwVersion"
+
+typedef enum {
+ FvTypeMain,
+ FvTypeBootBlock,
+ FvTypeNvRam,
+ FvTypeCustom,
+ FvTypeMax
+} FLASH_FV_TYPE;
+
+typedef struct _FLASH_AREA_EX FLASH_AREA_EX;
+
+typedef EFI_STATUS (REFLASH_FUNCTION_EX)(
+ IN FLASH_AREA_EX *Block,
+ IN UINTN BlockNumber
+);
+
+struct _FLASH_AREA_EX
+{
+ UINT8 *BlockAddress;
+ UINT8 *BackUpAddress;
+ UINTN Size;
+ UINT32 BlockSize;
+ FLASH_FV_TYPE Type;
+ BOOLEAN Update;
+ BOOLEAN TopSwapTrigger;
+ REFLASH_FUNCTION_EX *BackUp;
+ REFLASH_FUNCTION_EX *Program;
+ EFI_STRING_ID BackUpString;
+ EFI_STRING_ID ProgramString;
+};
+
+extern FLASH_AREA_EX BlocksToUpdate[];
+extern FLASH_PROTOCOL *Flash;
+extern EFI_HII_HANDLE ReflashHiiHandle;
+extern UINT8 *RecoveryBuffer;
+
+EFI_STATUS GetHiiString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF Token,
+ IN OUT UINTN *pDataSize,
+ OUT EFI_STRING *ppData
+);
+
+EFI_STATUS AmiFlashBackUp(
+ IN FLASH_AREA_EX *Block,
+ IN UINTN BlockNumber
+);
+EFI_STATUS AmiFlashProgram(
+ IN FLASH_AREA_EX *Block,
+ IN UINTN BlockNumber
+);
+
+VOID ApplyUserSelection(
+ IN BOOLEAN Interactive
+);
+
+VOID OemBeforeFlashCallback(
+ VOID
+);
+
+VOID OemAfterFlashCallback(
+ VOID
+);
+
+EFI_STATUS FlashProgressEx(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID KeyValue,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+);
+
+EFI_STATUS IsWin8Update(
+ BOOLEAN RecoveryFailed
+);
+
+EFI_STATUS FlashWalker(
+ IN BOOLEAN BackUp
+);
+
+EFI_STATUS Epilogue(
+ VOID
+);
+
+EFI_STATUS Prologue(
+ IN BOOLEAN Interactive,
+ IN BOOLEAN Win8StyleUpdate
+);
+
+EFI_STATUS InstallEsrtTable(
+ VOID
+);
+
+#endif
+ /****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.mak b/Core/EM/Recovery/ReFlash/ReFlash.mak
new file mode 100644
index 0000000..6edcd3e
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.mak
@@ -0,0 +1,135 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Modules/Recovery/ReFlash.mak 15 5/22/12 5:10p Artems $
+#
+# $Revision: 15 $
+#
+# $Date: 5/22/12 5:10p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Modules/Recovery/ReFlash.mak $
+#
+# 15 5/22/12 5:10p Artems
+# [TAG] EIP88314
+# [Category] Improvement
+# [Description] Recovery takes a long time for large flash size
+# Rewrite reflash code to not give control back to TSE until finished
+# reporting progress via DisplayProgress API of AMI Post manager
+# [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr
+# Reflash.uni
+#
+# 14 12/05/11 1:48p Artems
+# EIP 74623: Add capabilities similar to ones in SMIFlash module
+#
+# 13 11/29/11 3:33p Artems
+# Fixed build error when FtRecovery module is present but disabled
+#
+# 12 11/12/11 6:47p Artems
+# Added fault tolerant recovery support
+#
+# 11 11/30/10 5:04p Felixp
+# Bug fix: VfrCompile build error when ReflashFunctions eLink list
+# contains more than one function.
+#
+# 10 11/17/10 5:27p Felixp
+# $(BUILD_DIR)\ReFlash.mak dependency is updated.
+#
+# 9 11/17/10 2:52p Felixp
+# Enhencement (EIP 36355):
+# The Reflash component is updated to be extensible with external
+# eModules.
+# The eModules can contribute content for the Recovery setup page,
+# and provide callback function that will be periodically called
+# once BIOS update is completed.The external eModules can be used
+# to implement update of non-standard firmware components.
+# For example, update of the non-shared EC firmware.
+#
+# 8 10/01/10 2:14p Felixp
+# Previous changes related to descrete EC firmware update are rolled back
+# for the Core labeling.
+#
+# 6 2/23/10 9:20p Felixp
+# Support of the ReFlash String Override via REFLASH_SDBS eLink (EIP
+# 32696).
+#
+# 5 7/09/09 5:59p Oleksiyy
+# Files clean-up, some headers added
+#
+# 4 12/29/06 2:58p Felixp
+# RecoveryDxeLib removed. Functionality moved to Flash.lib
+#
+# 3 8/24/06 9:19a Felixp
+# x64 Support
+#
+# 1 11/08/05 4:04a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: ReFlash.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : ReFlash
+
+SetupData : ReFlash
+
+ReFlash : $(BUILD_DIR)\ReFlash.mak ReFlashBin
+
+$(BUILD_DIR)\ReFlash.mak : $(ReFlash_DIR)\$(@B).cif $(ReFlash_DIR)\$(@B).mak $(BUILD_RULES) $(REFLASH_CIFS) $(BUILD_DIR)\token.h
+ $(CIF2MAK) $(ReFlash_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS) $(REFLASH_CIFS)
+
+REFLASH_LISTS = \
+/D\"REFLASH_FUNCTION_LIST=$(ReflashFunctions)\"\
+/D\"OEM_BEFORE_FLASH_UPDATE_CALLBACK_LIST=$(OemBeforeFlashUpdateList)\"\
+/D\"OEM_AFTER_FLASH_UPDATE_CALLBACK_LIST=$(OemAfterFlashUpdateList)\"
+
+ReFlashBin : $(AMIDXELIB) $(FLASHLIB)
+ type << >$(BUILD_DIR)\ReflashDefinitions.h
+!IF "$(REFLASH_DEFINITIONS)"!=""
+#include<$(REFLASH_DEFINITIONS: =>^
+#include<)>
+!ENDIF
+<<
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\ReFlash.mak all\
+ GUID=70e1a818-0be1-4449-bfd4-9ef68c7f02a8\
+ ENTRY_POINT=ReFlashEntry\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=BS_DRIVER \
+ MY_INCLUDES=/I$(ReFlash_DIR)\
+ "CFLAGS=$(CFLAGS) $(REFLASH_LISTS)"\
+ COMPRESS=1 HAS_RESOURCES=1\
+!IF "$(REFLASH_SDBS: =)"!=""
+ "MY_SDBS=-db $(REFLASH_SDBS: = -db )"\
+!ENDIF
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.sdl b/Core/EM/Recovery/ReFlash/ReFlash.sdl
new file mode 100644
index 0000000..db29792
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.sdl
@@ -0,0 +1,135 @@
+TOKEN
+ Name = "ReFlash_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable ReFlash support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "REFLASH_INTERACTIVE"
+ Value = "1"
+ Help = "When this switch is enabled, flash update process is interactive.\User can adjust update parameters before the update.\User can also choose not to update the flash.\Once update is completed user has to press a key to reset the system\When this switch is disabled, flash update process is started automatically.\User can only monitor progress of the operation.\Once update is completed system resets."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_NVRAM_CONTROL"
+ Value = "1"
+ Help = "Eanbles/Disables Setup option that that controls NVRAM update"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "REFLASH_INTERACTIVE" "=" "1"
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_NVRAM"
+ Value = "1"
+ Help = "Enables/Disables update of the NVRAM flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_NVRAM_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_BOOT_BLOCK_CONTROL"
+ Value = "0"
+ Help = "Enables/Disables Setup option that controls boot block update"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "REFLASH_INTERACTIVE" "=" "1"
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_BOOT_BLOCK"
+ Value = "0"
+ Help = "Enables/Disables update of the boot block flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_BOOT_BLOCK_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_MAIN_BLOCK"
+ Value = "1"
+ Help = "Enables/Disables update of the Main block flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_BOOT_BLOCK_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_EC_FIRMWARE_CONTROL"
+ Value = "0"
+ Help = "Eanbles/Disables Setup option that controls EC FIRMWARE update"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "REFLASH_INTERACTIVE" "=" "1"
+ Token = "EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "REFLASH_UPDATE_EC_FIRMWARE"
+ Value = "0"
+ Help = "Enables/Disables update of the EC FIRMWARE flash area.\When REFLASH_INTERACTIVE is on and REFLASH_UPDATE_EC_FIRMWARE_CONTROL is on\this value can be overriden by the user using setup option."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "ReFlash_DIR"
+End
+
+MODULE
+ Help = "Includes ReFlash.mak to Project"
+ File = "ReFlash.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\ReFlash.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\$(ReFlash_DIR)"
+ Parent = "IFR_DIR_LIST"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "REFLASH_SDBS"
+ Help = "List of SDB files with the string overrides for the ReFlash component"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "REFLASH_CIFS"
+ Help = "List of CIF files of the ReFlash plug-ins"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "REFLASH_DEFINITIONS"
+ Help = "List of SD files of the ReFlash plug-ins"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ReflashFunctions"
+ Help = "List of callback functions of the ReFlash plug-ins"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OemBeforeFlashUpdateList"
+ Help = "List of callback functions to be called before flash update"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "OemAfterFlashUpdateList"
+ Help = "List of callback functions to be called after flash update"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.uni b/Core/EM/Recovery/ReFlash/ReFlash.uni
new file mode 100644
index 0000000..13e42f7
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.uni
Binary files differ
diff --git a/Core/EM/Recovery/ReFlash/ReFlash.vfr b/Core/EM/Recovery/ReFlash/ReFlash.vfr
new file mode 100644
index 0000000..5884ea2
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlash.vfr
@@ -0,0 +1,240 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Recovery/ReFlash.vfr 17 5/22/12 5:12p Artems $
+//
+// $Revision: 17 $
+//
+// $Date: 5/22/12 5:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Recovery/ReFlash.vfr $
+//
+// 17 5/22/12 5:12p Artems
+// [TAG] EIP88314
+// [Category] Improvement
+// [Description] Recovery takes a long time for large flash size
+// Rewrite reflash code to not give control back to TSE until finished
+// reporting progress via DisplayProgress API of AMI Post manager
+//
+// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr
+// Reflash.uni
+//
+// 16 11/12/11 6:48p Artems
+// Added fault tolerant recovery support
+//
+// 15 11/02/11 4:53p Artems
+// EIP 74446: Fixed bug - reflash is enabled when recovery image is not
+// found
+//
+// 14 5/13/11 4:49p Artems
+// Added REFLASH_UPDATE_MAIN_BLOCK setup control
+//
+// 13 11/17/10 2:52p Felixp
+// Enhencement (EIP 36355):
+// The Reflash component is updated to be extensible with external
+// eModules.
+// The eModules can contribute content for the Recovery setup page,
+// and provide callback function that will be periodically called
+// once BIOS update is completed.The external eModules can be used
+// to implement update of non-standard firmware components.
+// For example, update of the non-shared EC firmware.
+//
+// 12 10/01/10 2:14p Felixp
+// Previous changes related to descrete EC firmware update are rolled back
+// for the Core labeling.
+//
+// 10 12/24/09 12:41p Oleksiyy
+// EIP 30173: Support for the EC Firmware Area Update control added. Main
+// token to enable this support is EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+// should be located in specific EC-related .sdl file.
+//
+// 9 12/14/09 3:11p Aaronp
+// Updated to support UEFI2.1 interactive text
+//
+// 8 10/09/09 6:30p Felixp
+// ReFlash component is updated to support Framework and UEFI 2.1 HII
+//
+// 7 7/09/09 5:59p Oleksiyy
+// Files clean-up, some headers added
+//
+// 6 10/22/08 9:36a Felixp
+// Bug fix (EIP 15931): NVRAM was never reset during BIOS Recovery. Even
+// when 'Reset NVRAM' setup option was enabled.
+// The bug was caused by the wrong varstore passed into the callback
+// routine.
+// Form layout has been changed to make sure default varstore is active
+// when goto statement is reached.
+//
+// 5 10/09/08 5:30p Felixp
+// Bug fix (EIP 13077): During BIOS Recovery the warning about flash
+// update being disabled due to the user access level was truncated
+//
+// 4 1/17/08 5:30p Felixp
+// Updated to disable flash update option during boot with the USER access
+// level
+//
+// 3 10/19/07 6:23p Felixp
+// Recovery Flash Update module extended to support Boot Block update.
+// Boot block update can be enabled or disabled using SDL token.
+// In addition to that there is an SDL token that enables/disables
+// checkbox on the
+// recovery setup page that user can use to enable or disable boot block
+// update.
+//
+// 2 12/22/06 9:38a Felixp
+// Support for optional NVRAM reset based on user input added
+//
+// 1 12/01/05 9:35a Felixp
+//
+// 1 11/08/05 4:04a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ReFlash.vfr
+//
+// Description: Reflash formset
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "ReFlash.h"
+
+formset guid = RECOVERY_FORM_SET_GUID,
+ title = STRING_TOKEN(STR_RECOVERY),
+ help = STRING_TOKEN(STR_EMPTY),
+ class = RECOVERY_FORM_SET_CLASS, subclass = 0,
+
+ varstore AUTOFLASH,
+ name = Setup,
+ guid = RECOVERY_FORM_SET_GUID;
+
+ AMI_CALLBACK_VARSTORE
+ SYSTEM_ACCESS_VARSTORE
+
+
+#if REFLASH_INTERACTIVE
+
+ form formid = RECOVERY_MAIN,
+ title = STRING_TOKEN(STR_RECOVERY);
+
+ SUBTITLE(STRING_TOKEN(STR_SUBTITLE1))
+ SUBTITLE(STRING_TOKEN(STR_SUBTITLE2))
+
+ suppressif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_ADMIN;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_ACCESS_DENIED),
+ text = STRING_TOKEN(STR_ACCESS_DENIED2),
+ flags = 0, key = 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_ACCESS_DENIED3),
+ text = STRING_TOKEN(STR_ACCESS_DENIED4),
+ flags = 0, key = 0;
+ endif;
+
+ SEPARATOR
+
+ SUBTITLE(STRING_TOKEN(STR_OPTIONS))
+
+ grayoutif NOT ideqval AUTOFLASH.FailedRecovery == 0 OR ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+
+#if REFLASH_UPDATE_NVRAM_CONTROL
+ checkbox varid = AUTOFLASH.UpdateNv,
+ prompt = STRING_TOKEN(STR_UPDATE_NVRAM),
+ help = STRING_TOKEN(STR_UPDATE_NVRAM_HELP),
+ flags = REFLASH_UPDATE_NVRAM, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off
+ endcheckbox;
+#endif
+#if REFLASH_UPDATE_BOOT_BLOCK_CONTROL
+ checkbox varid = AUTOFLASH.UpdateBb,
+ prompt = STRING_TOKEN(STR_UPDATE_BB),
+ help = STRING_TOKEN(STR_UPDATE_BB_HELP),
+ flags = REFLASH_UPDATE_BOOT_BLOCK, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off
+ endcheckbox;
+#endif
+
+ checkbox varid = AUTOFLASH.UpdateMain,
+ prompt = STRING_TOKEN(STR_UPDATE_MAIN),
+ help = STRING_TOKEN(STR_UPDATE_MAIN_HELP),
+ flags = REFLASH_UPDATE_MAIN_BLOCK, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off
+#if FtRecovery_SUPPORT
+ inconsistentif prompt = STRING_TOKEN(STR_FLASH_SELECTION_ERROR_POPUP),
+ ideqval AUTOFLASH.UpdateBb == 1
+ AND
+ ideqval AUTOFLASH.UpdateMain == 0
+ endif
+#endif
+ endcheckbox;
+#if REFLASH_UPDATE_EC_FIRMWARE_CONTROL
+ checkbox varid = AUTOFLASH.UpdateEC,
+ prompt = STRING_TOKEN(STR_UPDATE_EC),
+ help = STRING_TOKEN(STR_UPDATE_EC_HELP),
+ flags = REFLASH_UPDATE_EC_FIRMWARE, // Flags behavior for checkbox is overloaded so that it equals a DEFAULT value. 1 = ON, 0 = off
+ endcheckbox;
+#endif
+
+#define REFLASH_CONTROL
+#include <ReflashDefinitions.h>
+#undef REFLASH_CONTROL
+
+ //Can't use 'SEPARATOR' because it's not allowed in the grayoutif scope
+ INVENTORY(STRING_TOKEN(STR_EMPTY),STRING_TOKEN(STR_EMPTY))
+
+ endif;//grayoutif
+
+ suppressif NOT ideqval AUTOFLASH.FailedRecovery == 0 OR ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ goto RECOVERY_FLASH,
+ prompt = STRING_TOKEN(STR_FLASH),
+ help = STRING_TOKEN(STR_FLASH_HELP),
+ flags = INTERACTIVE, key = FLASH_START_KEY;
+ endif;
+ endform;
+#endif //#if REFLASH_INTERACTIVE
+
+ form formid = RECOVERY_FLASH,
+ title = STRING_TOKEN(STR_RECOVERY_FLASH);
+ SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING1))
+ SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING2))
+ SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING3))
+ SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING_RESET))
+#if REFLASH_INTERACTIVE
+ SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING_RESET_USER))
+#else
+ SUBTITLE(STRING_TOKEN(STR_UPDATE_WARNING_RESET_AUTO))
+#endif
+ SEPARATOR
+
+ INTERACTIVE_TEXT(STRING_TOKEN(STR_FLASH_PROGRESS_HELP), STRING_TOKEN(STR_EMPTY), STRING_TOKEN(STR_EMPTY), FLASH_PROGRESS_KEY)
+#define REFLASH_PROGRESS
+#include <ReflashDefinitions.h>
+#undef REFLASH_PROGRESS
+ endform;
+endformset;
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Recovery/ReFlash/ReFlashWorker.c b/Core/EM/Recovery/ReFlash/ReFlashWorker.c
new file mode 100644
index 0000000..6ab6fa7
--- /dev/null
+++ b/Core/EM/Recovery/ReFlash/ReFlashWorker.c
@@ -0,0 +1,720 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlashWorker.c 3 5/13/13 6:26a Thomaschen $
+//
+// $Revision: 3 $
+//
+// $Date: 5/13/13 6:26a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/ReFlash/ReFlashWorker.c $
+//
+// 3 5/13/13 6:26a Thomaschen
+// Update for EIP122037.
+//
+// 2 4/16/13 5:47a Thomaschen
+// Fixed for EIP106722.
+//
+//
+// 7 2/11/13 3:42p Artems
+// [TAG] EIP112180
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] In non-interactive mode system updated flash even when
+// there is no valid image
+// [RootCause] In non-interactive mode system didn't check flash image
+// validity
+// [Solution] Added check of flash image validity. Inform user if image
+// is invalid or not found
+// [Files] Reflash.c ReflashWorker.c Reflash.uni Reflash.vfr
+//
+// 6 1/02/13 12:20p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Flash update progress report changes:
+// - report progress in non-interactive flash update
+// - do not report progress in Win8-style flash update
+// [Files] ReflashWorker.c Reflash.h Esrt.c
+//
+// 5 8/02/12 12:00p Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c
+// Esrt.c
+//
+// 4 7/24/12 11:56a Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Added dependency on fault-tolerant support module in
+// top-swap triggering code
+// [Files] ReflashWorker.c
+//
+// 3 7/20/12 10:19a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Reflash.c Esrt.c Reflash.h Capsule.h ReflashWorker.c
+// Protocol.cif AmiReflashProtocol.h Setup.h
+//
+// 2 6/08/12 12:35p Artems
+// [TAG] EIP88314
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Incorrect strings in progress message
+// [RootCause] String tokens were twisted up
+// [Solution] Put string tokens in a correct order
+// [Files] ReflashWorker.c
+//
+// 1 5/23/12 1:19p Artems
+// [TAG] EIP 88314
+// [Category] Improvement
+// [Description] Recovery takes a long time for large flash size
+// Rewrite reflash code to not give control back to TSE until finished
+// reporting progress via DisplayProgress API of AMI Post manager
+//
+// [Files] Reflash.c Reflash.h ReflashWorker.c Reflash.mak Reflash.vfr
+// Reflash.uni
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ReFlashWorker.c
+//
+// Description: Implementation of Reflash driver
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+#include <FFS.h>
+#include <AmiCspLib.h>
+#include <Protocol/AmiPostMgr.h>
+#include <Protocol/ConsoleControl.h>
+#include "Reflash.h"
+
+#define FLASH_PART_START_ADDRESS (0xFFFFFFFF - FLASH_SIZE + 1)
+static UINT32 FlashEraser = (FLASH_ERASE_POLARITY) ? 0 : 0xffffffff;
+static UINT8 *FlashPartStart = (UINT8 *)(UINTN)FLASH_PART_START_ADDRESS;
+extern EFI_STATUS RecoveryStatus;
+
+FLASH_AREA_EX BlocksToUpdate[] = {
+#if FtRecovery_SUPPORT
+ {
+ (UINT8 *)FV_RECOVERY_BASE,
+ (UINT8 *)FV_RECOVERY_BACKUP_ADDRESS,
+ FV_RECOVERY_BLOCKS * FLASH_BLOCK_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeBootBlock,
+ REFLASH_UPDATE_BOOT_BLOCK,
+ FALSE,
+ AmiFlashBackUp,
+ AmiFlashProgram,
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_BACKUP_RECOVERY),
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_RECOVERY)
+ },
+ {
+ (UINT8 *)FV_BB_BASE,
+ (UINT8 *)FV_BB_BACKUP_ADDRESS,
+ (FV_BB_BLOCKS - FV_RECOVERY_BLOCKS) * FLASH_BLOCK_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeBootBlock,
+ REFLASH_UPDATE_BOOT_BLOCK,
+ TRUE,
+ AmiFlashBackUp,
+ AmiFlashProgram,
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_BACKUP_BB),
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_BB)
+ },
+#else
+ {
+ (UINT8 *)FV_BB_BASE,
+ NULL,
+ FV_BB_BLOCKS * FLASH_BLOCK_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeBootBlock,
+ REFLASH_UPDATE_BOOT_BLOCK,
+ FALSE,
+ NULL,
+ AmiFlashProgram,
+ 0,
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_BB)
+ },
+#endif
+
+// EIP122037>>
+#if INTEL_FIT_SUPPORT
+ {
+ (UINT8 *)FV_DATA_BASE,
+ NULL,
+ FV_DATA_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeBootBlock,
+ REFLASH_UPDATE_BOOT_BLOCK,
+ FALSE,
+ NULL,
+ AmiFlashProgram,
+ 0,
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_DATA)
+ },
+#endif
+// EIP122037<<
+ {
+ (UINT8 *)FV_MAIN_BASE,
+ NULL,
+ FV_MAIN_BLOCKS * FLASH_BLOCK_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeMain,
+ REFLASH_UPDATE_MAIN_BLOCK,
+ FALSE,
+ NULL,
+ AmiFlashProgram,
+ 0,
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_MAIN)
+ },
+ {
+ (UINT8 *)NVRAM_ADDRESS,
+ NULL,
+ NVRAM_BLOCKS * FLASH_BLOCK_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeNvRam,
+ REFLASH_UPDATE_NVRAM,
+ FALSE,
+ NULL,
+ AmiFlashProgram,
+ 0,
+ STRING_TOKEN(STR_FLASH_PROGRESS_MESSAGE_FLASH_NVRAM)
+ },
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ {
+ (UINT8 *)EC_BASE,
+ NULL,
+ EC_BLOCKS * FLASH_BLOCK_SIZE,
+ FLASH_BLOCK_SIZE,
+ FvTypeCustom,
+ REFLASH_UPDATE_EC_FIRMWARE,
+ FALSE,
+ NULL,
+ AmiFlashProgram,
+ 0,
+ STRING_TOKEN(STR_FLASH_PROGRESS_CAPTION_FLASH)
+ },
+#endif
+
+ {
+ NULL,
+ NULL,
+ 0,
+ 0,
+ FvTypeMax,
+ FALSE,
+ FALSE,
+ NULL,
+ NULL,
+ 0,
+ 0
+ } //terminator
+};
+
+
+
+static EFI_GUID AmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+static AMI_POST_MANAGER_PROTOCOL *AmiPostMgr = NULL;
+static EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+static BOOLEAN UserConfirmation = TRUE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: DrawMessageBox
+//
+// Description: This function draws message box on screen and waits till user presses Enter
+//
+// Input:
+// IN CHAR16 *Caption - message box caption
+// IN CHAR16 *Message - message box message
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DrawMessageBox(
+ IN CHAR16 *Caption,
+ IN CHAR16 *Message
+)
+{
+ EFI_STATUS Status;
+ UINT8 MsgKey;
+
+ if(!UserConfirmation)
+ return;
+
+ if(AmiPostMgr != NULL) {
+ if(ConsoleControl != NULL)
+ ConsoleControl->LockStdIn(ConsoleControl, L"");
+
+ pST->ConIn->Reset(pST->ConIn, FALSE); //discard all keystrokes happend during flash update
+
+ Status = AmiPostMgr->DisplayMsgBox(Caption, Message, MSGBOX_TYPE_OK, &MsgKey);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CountDown
+//
+// Description: This function draws ResetSystem waiting bar
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+//TODO
+VOID CountDown(
+ VOID
+)
+{
+ pBS->Stall(5000000);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Prologue
+//
+// Description: This function is called before actual flashing takes place
+//
+// Input:
+// IN BOOLEAN Interactive - if TRUE reflash is interactive
+// IN BOOLEAN Win8StyleUpdate - if TRUE reflash is Win8Style
+//
+// Output:
+// EFI_SUCCESS - system prepared for flashing
+// EFI_NOT_STARTED - recovery image not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Prologue(
+ IN BOOLEAN Interactive,
+ IN BOOLEAN Win8StyleUpdate
+)
+{
+ static BOOLEAN Executed = FALSE;
+ static EFI_STATUS Status = EFI_SUCCESS;
+
+ if(Executed)
+ return Status;
+
+ Executed = TRUE;
+ ApplyUserSelection(Interactive);
+
+ if(!Win8StyleUpdate) //we do not report progress during Win8-style flash update
+ Status = pBS->LocateProtocol(&AmiPostManagerProtocolGuid, NULL, &AmiPostMgr);
+
+ if(Interactive) {
+ Status = pBS->LocateProtocol(&gEfiConsoleControlProtocolGuid, NULL, &ConsoleControl);
+ if(!EFI_ERROR(Status))
+ ConsoleControl->LockStdIn(ConsoleControl, L"");
+ } else {
+ if(EFI_ERROR(RecoveryStatus)) { //we can't perform flash update, inform user and return error for resetting system
+ CountDown();
+ return EFI_ABORTED;
+ }
+ UserConfirmation = FALSE;
+ }
+
+ OemBeforeFlashCallback();
+ Flash->DeviceWriteEnable();
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: Epilogue
+//
+// Description: This function is called after actual flashing takes place
+//
+// Input:
+// None
+//
+// Output: (this function is not supposed to return control to caller
+// EFI_SUCCESS - flash updated successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Epilogue(VOID)
+{
+ Flash->DeviceWriteDisable();
+ OemAfterFlashCallback();
+
+ DrawMessageBox(L"Flash update", L"Flash update completed. Press Enter key to reset the system");
+ pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FlashWalker
+//
+// Description: This function walks through flash regions and calls respective
+// backup and flash functions
+//
+// Input:
+// IN BOOLEAN BackUp - if TRUE, backup functions should be called on this pass
+// flash programm functions should be called otherwise
+//
+// Output:
+// EFI_SUCCESS - flash updated successfully
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FlashWalker(
+ IN BOOLEAN BackUp
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINTN k;
+ EFI_STRING Title;
+ EFI_STRING Message;
+ UINTN Size;
+ UINTN Step;
+ UINTN Threshold;
+ UINTN Blocks;
+
+ VOID *DisplayHandle;
+ AMI_POST_MGR_KEY OutKey;
+
+ if(AmiPostMgr != NULL) {
+ Title = NULL;
+ if(BackUp)
+ GetHiiString(ReflashHiiHandle, STRING_TOKEN(STR_FLASH_PROGRESS_TITLE_BACKUP), &Size, &Title);
+ else
+ GetHiiString(ReflashHiiHandle, STRING_TOKEN(STR_FLASH_PROGRESS_TITLE_FLASH), &Size, &Title);
+
+ AmiPostMgr->DisplayProgress(AMI_PROGRESS_BOX_INIT,
+ (Title == NULL) ? L"Flash Update Progress" : Title,
+ NULL,
+ NULL,
+ 0,
+ &DisplayHandle,
+ &OutKey);
+ }
+
+ for(i = 0; BlocksToUpdate[i].Type != FvTypeMax; i++) {
+ if(!BlocksToUpdate[i].Update)
+ continue; //block is not updated
+
+ if(BackUp && BlocksToUpdate[i].BackUp == NULL)
+ continue; //no backup function
+
+ if(AmiPostMgr != NULL) {
+ /* prepare display progress window */
+ Message = NULL;
+ if(BackUp)
+ GetHiiString(ReflashHiiHandle, BlocksToUpdate[i].BackUpString, &Size, &Message);
+ else
+ GetHiiString(ReflashHiiHandle, BlocksToUpdate[i].ProgramString, &Size, &Message);
+ }
+
+ /* calculate number of blocks to flash */
+ Blocks = BlocksToUpdate[i].Size / BlocksToUpdate[i].BlockSize;
+
+ /* calculate progress steps */
+ Step = 0;
+ if(Blocks > 100) {
+ Threshold = (Blocks / 100) + 1;
+ } else {
+ Threshold = 1;
+ }
+
+ /* now we're ready to do actual job */
+ for(k = 0; k < Blocks; k++) {
+ if(BackUp)
+ Status = BlocksToUpdate[i].BackUp(&BlocksToUpdate[i], k);
+ else
+ Status = BlocksToUpdate[i].Program(&BlocksToUpdate[i], k);
+
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Step++;
+ if(Step == Threshold && AmiPostMgr != NULL) {
+ /* report progress to user */
+ AmiPostMgr->DisplayProgress(AMI_PROGRESS_BOX_UPDATE,
+ (Title == NULL) ? L"Flash Update Progress" : Title,
+ (Message == NULL) ? L"Flash new data" : Message,
+ NULL,
+ (k * 100) / Blocks,
+ &DisplayHandle,
+ &OutKey);
+ Step = 0;
+ }
+ }
+
+#if FtRecovery_SUPPORT
+ /* check if TopSwap should be triggered */
+ if(BlocksToUpdate[i].TopSwapTrigger) {
+ if(BackUp)
+ SetTopSwap(TRUE);
+ else
+ SetTopSwap(FALSE);
+ }
+#endif
+ }
+
+ if(AmiPostMgr != NULL) {
+ /* close progress window */
+ AmiPostMgr->DisplayProgress(AMI_PROGRESS_BOX_CLOSE,
+ (Title == NULL) ? L"Flash Update Progress" : Title,
+ NULL,
+ NULL,
+ 0,
+ &DisplayHandle,
+ &OutKey);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FlashProgressEx
+//
+// Description: This function is called by Setup browser to perform flash update
+//
+// Input:
+// IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This - pointer to the instance of
+// ConfigAccess protocol
+// IN EFI_BROWSER_ACTION Action - action, that setup browser is performing
+// IN EFI_QUESTION_ID KeyValue - value of currently processed setup control
+// IN UINT8 Type - value type of setup control data
+// IN EFI_IFR_TYPE_VALUE *Value - pointer to setup control data
+// OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest - pointer where to store requested action
+//
+// Output:
+// EFI_SUCCESS - flash updated successfully
+// EFI_UNSUPPORTED - browser action is not supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FlashProgressEx(
+ IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
+ IN EFI_BROWSER_ACTION Action,
+ IN EFI_QUESTION_ID KeyValue,
+ IN UINT8 Type,
+ IN EFI_IFR_TYPE_VALUE *Value,
+ OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
+)
+{
+ EFI_STATUS Status;
+
+ if (ActionRequest)
+ *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
+
+ if(Action != EFI_BROWSER_ACTION_CHANGING)
+ return EFI_UNSUPPORTED;
+
+
+#if REFLASH_INTERACTIVE
+ if(KeyValue == FLASH_START_KEY) {
+ Status = Prologue(TRUE, FALSE);
+ if(EFI_ERROR(Status)) {
+ /* inform user, that flashing can't be performed */
+ DrawMessageBox(L"ERROR!!!!", L"Flash update failed to initialize. Press Enter key to reset system");
+ pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+ /* we have to give control back to setup browser to refresh the screen */
+ return EFI_SUCCESS;
+ }
+/* nothing to do here, wait for user response */
+ if (KeyValue != FLASH_PROGRESS_KEY) {
+ return EFI_SUCCESS;
+ }
+#else
+ Status = Prologue(FALSE, FALSE);
+ if(EFI_ERROR(Status)) {
+ pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+#endif
+
+ Status = EFI_SUCCESS;
+
+#if FtRecovery_SUPPORT
+ if(!IsTopSwapOn()) {
+ Status = FlashWalker(TRUE);
+ }
+#endif
+
+ if(!EFI_ERROR(Status)) {
+ Status = FlashWalker(FALSE);
+ }
+
+ if(EFI_ERROR(Status)) {
+ /* something was wrong - inform user */
+ DrawMessageBox(L"ERROR!!!!", L"Flash update failed. Press Enter key to reset system");
+ pRS->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ }
+
+ Status = Epilogue();
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SetBackUpArea
+//
+// Description: This function prepares FV_MAIN region to be backup region
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetBackUpArea(VOID)
+{
+ static BOOLEAN FirstRun = TRUE;
+ static UINT32 FlashEraser = (FLASH_ERASE_POLARITY) ? 0 : 0xffffffff;
+ EFI_FIRMWARE_VOLUME_HEADER *Fv;
+
+ if(!FirstRun)
+ return;
+
+ FirstRun = FALSE;
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FV_MAIN_BASE;
+ Flash->Write(&(Fv->Signature), sizeof(UINT32), &FlashEraser);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiFlashBackUp
+//
+// Description: This function backs up given block from given region
+//
+// Input:
+// IN FLASH_AREA_EX *Block - flash region to work with
+// IN UINTN BlockNumber - block number within flash region
+//
+// Output:
+// EFI_SUCCESS - block saved successfully
+// EFI_ERROR - there was an error during operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiFlashBackUp(
+ IN FLASH_AREA_EX *Block,
+ IN UINTN BlockNumber
+)
+{
+ UINT8 *Source;
+ UINT8 *Destination;
+ VOID *Tmp;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, Block->BlockSize, &Tmp);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Source = Block->BlockAddress + BlockNumber * Block->BlockSize;
+ Destination = Block->BackUpAddress + BlockNumber * Block->BlockSize;
+
+ if(Block->Type == FvTypeBootBlock)
+ SetBackUpArea();
+
+ Status = Flash->Read(Source, Block->BlockSize, Tmp);
+ if(EFI_ERROR(Status)) {
+ pBS->FreePool(Tmp);
+ return Status;
+ }
+
+//save to backup address
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ Status = Flash->Update(Destination, Block->BlockSize, Tmp);
+ pBS->RestoreTPL(OldTpl);
+
+ pBS->FreePool(Tmp);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiFlashProgram
+//
+// Description: This function programs given block from given region
+//
+// Input:
+// IN FLASH_AREA_EX *Block - flash region to work with
+// IN UINTN BlockNumber - block number within flash region
+//
+// Output:
+// EFI_SUCCESS - block updated successfully
+// EFI_ERROR - there was an error during operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiFlashProgram(
+ IN FLASH_AREA_EX *Block,
+ IN UINTN BlockNumber
+)
+{
+ UINT8 *ImageStart;
+ UINT8 *Source;
+ UINT8 *Destination;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ ImageStart = Block->BlockAddress - FlashPartStart + RecoveryBuffer;
+ Source = ImageStart + BlockNumber * Block->BlockSize;
+ Destination = Block->BlockAddress + BlockNumber * Block->BlockSize;
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ Status = Flash->Update(Destination, Block->BlockSize, Source);
+ pBS->RestoreTPL(OldTpl);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/Recovery.c b/Core/EM/Recovery/Recovery.c
new file mode 100644
index 0000000..8425fb1
--- /dev/null
+++ b/Core/EM/Recovery/Recovery.c
@@ -0,0 +1,720 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Recovery/Recovery.c 34 8/09/12 11:10a Pats $
+//
+// $Revision: 34 $
+//
+// $Date: 8/09/12 11:10a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Recovery/Recovery.c $
+//
+// 34 8/09/12 11:10a Pats
+// [TAG] - EIP 80780
+// [Category] - Function Request
+// [Description] - Support for recovery from media formatted with the
+// EXT(x) file system.
+// [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+// and FsRecovery.c (source)
+//
+// 33 8/02/12 11:56a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c
+// Esrt.c
+//
+// 32 4/20/12 2:53p Artems
+// [TAG] EIP87678
+// [Category] Improvement
+// [Description] Added function headers for CHM builder
+// [Files] Recovery.c
+//
+// 31 4/20/12 2:17p Artems
+// [TAG] EIP87678
+// [Category] New Feature
+// [Description] Selection of image to boot from on flash update boot
+// path - either old image (currently in flash) or new one in recovery
+// capsule
+// [Files] Recovery.c
+// DxeIpl.c
+// Core.sdl
+// Tokens.c
+//
+// 30 1/25/12 2:45p Pats
+// [TAG] - EIP 26909
+// [Category] - Function Request
+// [Description] - Support for recovery from media formatted with the NTFS
+// file system. This of necessity includes detection of GPT partitions,
+// which may contain any file system.
+// [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+// and FsRecovery.c (source)
+//
+// 29 11/02/11 4:52p Artems
+// EIP 74446: Fixed bug - reflash is enabled when recovery image is not
+// found
+//
+// 28 8/11/11 5:57p Artems
+// Minor fix to initialize recovery hob Address field before calling
+// ReportFV
+//
+// 27 5/13/11 4:47p Artems
+// Added secured recovery support
+//
+// 26 2/15/11 6:14p Artems
+// Fixed bug with duplicated Size variable
+//
+// 25 2/05/11 2:45p Artems
+// EIP 39463: Added support for secure update
+// EIP 39461: New ROM layout infrastructure support
+//
+// 24 10/01/10 7:40p Felixp
+// Improvement:
+// The code that detects Firmware Volumes in the recovery image
+// and publishes them is updated to use information from the ROM Layout
+// HOB.
+//
+// 23 6/11/10 11:43a Artems
+// Added porting hooks for recovery file name and validation
+//
+// 22 2/09/10 11:34a Felixp
+// ReadCapsule function update: code that verifies if FV in ROM is updated
+// to ensure that base address is below 4GB.
+//
+// 21 2/05/10 2:32p Felixp
+// Bug fix in UnknownType function.
+// The bug caused occasional hanging, when recovery image was not found.
+//
+// 20 2/05/10 8:40a Felixp
+// More flexible FV detection in the recovery image.
+//
+// 19 11/25/09 4:46p Felixp
+// sAmiRomFile renamed to RecoveryFileName
+// FlashSize renamed ro RecoveryImageSize
+//
+// 18 8/25/09 5:15p Felixp
+// Recovery module is updated to pass recovery image location via special
+// GUIDed HOB.
+// Old implementation that was relying on Firmware Volume (FV) handle,
+// required porting for a projects with non standard FV management policy.
+//
+// 17 7/09/09 12:50p Artems
+// Updated file headers
+//
+// 16 7/08/09 2:14p Robert
+// Changed the definition of the variable FlashSize from FLASH_SIZE to
+// RECOVERY_FLASH_SIZE
+//
+// 15 6/16/09 5:20p Artems
+// EIP 21169 Added Eltorito support
+//
+// 14 3/12/08 2:08p Ambikas
+// Added recovery error code for no capsule found.
+//
+// 13 8/07/07 2:21p Felixp
+// New StatusCodes added
+//
+// 12 4/13/07 6:03p Ambikas
+// Coding standard changes: updated year in AMI copyright header/footer;
+// added AMI_PHDRs for all functions; split the one line function
+// GuidMatch into several lines.
+//
+// 11 12/22/06 11:29a Felixp
+// SDL token added to customize name of the recovery ROM image
+//
+// 10 6/28/06 12:44p Felixp
+// OEM recovery type added
+//
+// 9 6/04/06 9:27p Ambikas
+//
+// 8 5/21/06 11:29p Felixp
+// Support for retries added (If recovery image not found, retry
+// RECOVERY_SCAN_RETRIES times)
+//
+// 7 4/13/06 2:02p Ambikas
+//
+// 6 4/10/06 9:50a Ambikas
+//
+// 5 3/17/06 6:10p Felixp
+// More generic calculation of the FV_MAIN offset within recovery BIOS
+// image
+//
+// 4 1/06/06 9:54a Felixp
+//
+// 1 12/01/05 9:35a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Recovery.c
+//
+// Description: Recovery functionality implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//----------------------------------------------------------------------
+
+#include <PPI/RecoveryModule.h>
+#include <AmiPeiLib.h>
+#include <Token.h>
+#include <AmiHobs.h>
+#include "Recovery.h"
+#include "RecoveryCsp.h"
+
+RECOVERY_IMAGE_HOB *pRecoveryHob;
+
+extern UINTN FlashDeviceBase;
+const CHAR8 *RecoveryFileName = CONVERT_TO_STRING(RECOVERY_ROM);
+const UINTN RecoveryImageSize = RECOVERY_IMAGE_SIZE;
+const BOOLEAN CdRecoverySupport = CD_RECOVERY_SUPPORT;
+const BOOLEAN FatRecoverySupport = FAT_RECOVERY_SUPPORT;
+const BOOLEAN NtfsRecoverySupport = NTFS_RECOVERY_SUPPORT;
+const BOOLEAN ExtRecoverySupport = EXT_RECOVERY_SUPPORT;
+
+EFI_GUID guidBlockDeviceCapsule = BLOCK_DEVICE_RECOVERY_CAPSULE_GUID;
+EFI_GUID guidSerialCapsule = SERIAL_RECOVERY_CAPSULE_GUID;
+EFI_GUID guidOemCapsule = OEM_RECOVERY_CAPSULE_GUID;
+
+#define BLOCK &guidBlockDeviceCapsule
+#define SERIAL &guidSerialCapsule
+#define CAPSULE &guidOemCapsule
+
+EFI_GUID* RecoveryDeviceOrder[] = {RECOVERY_DEVICE_ORDER, NULL};
+
+EFI_GUID guidRecoveryModule = EFI_PEI_RECOVERY_MODULE_PPI_GUID;
+EFI_GUID guidRecoveryDevice = EFI_PEI_DEVICE_RECOVERY_MODULE_PPI_GUID;
+
+EFI_STATUS LoadRecoveryCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN struct _EFI_PEI_RECOVERY_MODULE_PPI *This
+);
+
+EFI_PEI_RECOVERY_MODULE_PPI RecoveryModule = {LoadRecoveryCapsule};
+
+// PPI to be installed
+static EFI_PEI_PPI_DESCRIPTOR RecoveryPpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidRecoveryModule, &RecoveryModule
+ }
+};
+
+EFI_PHYSICAL_ADDRESS RecoveryBuffer = NULL;
+UINTN RecoveryBufferSize = 0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: VerifyFwImage
+//
+// Description: Verifies recovery capsule
+//
+// Note: This is dummy function. Actual implementation is in SecureFlash pkg
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyFwImage (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID **Buffer,
+ IN OUT UINT32 *Size,
+ OUT UINT32 *FailedTask
+)
+#if defined(SecFlashUpd_SUPPORT) && SecFlashUpd_SUPPORT == 1
+;
+#else
+{
+ if(FailedTask)
+ *FailedTask = 0;
+ return EFI_SUCCESS;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadCapsule
+//
+// Description: Called by FindRecoveryDevice. Calls LoadRecoveryCapsule
+// function of the passed in ppi EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
+// to get recovery image. If found, an HOB is created for this
+// recovery image.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ReadCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *pDRM,
+ UINTN CapsuleInstance, UINTN Size
+)
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS RomImageStart = FlashDeviceBase;
+ UINT32 FailedStage;
+
+ if(Size > RecoveryBufferSize){
+ Status = (*PeiServices)->AllocatePages(PeiServices, EfiBootServicesCode, (Size >> 12) + 1, &RecoveryBuffer);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ RecoveryBufferSize = Size;
+ }
+
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Loading Recovery Image..."));
+
+ Status = pDRM->LoadRecoveryCapsule(PeiServices, pDRM, CapsuleInstance, (VOID*)RecoveryBuffer);
+
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "done. Status: %r\n",Status));
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = VerifyFwImage(PeiServices, (VOID**)&RecoveryBuffer, (UINT32*)&Size, (UINT32*)&FailedStage );
+ pRecoveryHob->FailedStage = FailedStage;
+ pRecoveryHob->Status = (UINT8)Status;
+ if (EFI_ERROR(Status )) {
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_INVALID_CAPSULE, EFI_ERROR_MAJOR | Status );
+ return Status;
+ }
+
+ pRecoveryHob->Address = RecoveryBuffer;
+
+ return Status;
+}
+
+typedef BOOLEAN (*PREDICATE)(EFI_GUID *pType, VOID* pContext);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindRecoveryDevice
+//
+// Description: Called by LoadRecoveryCapsule.
+// Loop: Locate all installed EFI_PEI_DEVICE_RECOVERY_MODULE_PPI
+// ppis and call ReadCapsule on them.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindRecoveryDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ PREDICATE Criteria, VOID* pContext
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ BOOLEAN Loaded = FALSE;
+ UINTN i = 0;
+
+ do {
+ EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *pRecoveryDevice;
+ EFI_PEI_PPI_DESCRIPTOR *pDummy;
+ UINTN j, n;
+
+ Status = (*PeiServices)->LocatePpi(PeiServices, &guidRecoveryDevice, i++, &pDummy, &pRecoveryDevice);
+ if (EFI_ERROR(Status))
+ break;
+
+ Status = pRecoveryDevice->GetNumberRecoveryCapsules(PeiServices, pRecoveryDevice, &n);
+ if (EFI_ERROR(Status))
+ continue;
+
+ for(j = 0; j < n; j++) {
+ UINTN Size;
+ EFI_GUID CapsuleType;
+
+ Status = pRecoveryDevice->GetRecoveryCapsuleInfo(PeiServices, pRecoveryDevice, j, &Size, &CapsuleType);
+ if (EFI_ERROR(Status) || !Criteria(&CapsuleType, pContext))
+ continue;
+
+ Status = ReadCapsule(PeiServices, pRecoveryDevice, j, Size);
+ if (!EFI_ERROR(Status)){
+ Loaded = TRUE;
+ PEI_PROGRESS_CODE(PeiServices,PEI_RECOVERY_CAPSULE_LOADED);
+ break;
+ }
+ }
+ } while(!Loaded);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GuidMatch
+//
+// Description: Wrapper for guidcmp function.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GuidMatch(EFI_GUID* Type1, EFI_GUID* Type2)
+{
+ return !guidcmp(Type1,Type2);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UnknownType
+//
+// Description: Returns TRUE if the parameter, guid CapsuleType, in not
+// in parameter, List (a list of guids).
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN UnknownType(EFI_GUID* CapsuleType, EFI_GUID** List)
+{
+ EFI_GUID **pType;
+ for(pType = List; *pType; pType++) if (!guidcmp(*pType,CapsuleType)) return FALSE;
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LoadRecoveryCapsule
+//
+// Description: LoadRecoveryCapsule function of EFI_PEI_RECOVERY_MODULE_PPI
+// ppi. RecoveryDeviceOrder is a list of guids; each guid
+// represents a type of recovery device. We go through
+// this list and call FindRecoveryDevice for each type of
+// device.
+// -This function should not be confused with LoadRecoveryCapsule
+// function of the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI ppi.
+// -Called by DxeIpl.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LoadRecoveryCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN struct _EFI_PEI_RECOVERY_MODULE_PPI *This
+)
+{
+ EFI_GUID **ppType;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+ UINTN i;
+ EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+
+ PEI_PROGRESS_CODE(PeiServices,PEI_RECOVERY_STARTED);
+
+// Create Recovery Hob
+ Status = (*PeiServices)->CreateHob(
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(RECOVERY_IMAGE_HOB), &pRecoveryHob);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ pRecoveryHob->Header.Name = RecoveryHobGuid;
+ pRecoveryHob->Address = NULL;
+ pRecoveryHob->FailedStage = 0;
+
+ for(i = 0; i < RECOVERY_SCAN_RETRIES; i++) {
+ for(ppType = RecoveryDeviceOrder; *ppType; ppType++) {
+ Status = FindRecoveryDevice(PeiServices,GuidMatch,*ppType);
+ if (!EFI_ERROR(Status))
+ return Status;
+ }
+
+ Status = FindRecoveryDevice(PeiServices, UnknownType, RecoveryDeviceOrder);
+ if (!EFI_ERROR(Status)) break;
+ }
+
+ if (EFI_ERROR(Status)) {
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_NO_CAPSULE, EFI_ERROR_MAJOR);
+ pRecoveryHob->Status = (UINT8)Status;
+ }
+
+ return Status;
+}
+
+//this funciton is created from InitList.c template file during build process
+VOID InitParts(IN EFI_FFS_FILE_HEADER *FfsHeader,IN EFI_PEI_SERVICES **PeiServices);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: RecoveryEntry
+//
+// Description: Entry point. Installs EFI_PEI_RECOVERY_MODULE_PPI ppi
+// (which has function LoadRecoveryCapsule).
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RecoveryEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ InitParts(FfsHeader,PeiServices);
+ return (*PeiServices)->InstallPpi(PeiServices,RecoveryPpiList);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OemGetFileListFromPrimaryVolume
+//
+// Description: Porting hook to return recovery capsule file name from CD
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemGetFileListFromPrimaryVolume(
+ IN DIR_RECORD *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_RECORD **Buffer
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OemGetFileListFromFatVolume
+//
+// Description: Porting hook to return recovery capsule file name from FAT
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemGetFileListFromFatVolume(
+ IN DIR_ENTRY *Root,
+ IN UINT32 RootEntries,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY **Buffer
+);
+
+
+#if NTFS_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OemGetFileListFromNtfsVolume
+//
+// Description: Porting hook to return recovery capsule file name from NTFS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemGetFileListFromNtfsVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT INDEX_ENTRY **Buffer
+);
+#endif
+
+#if EXT_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OemGetFileListFromExtVolume
+//
+// Description: Porting hook to return recovery capsule file name from EXT(n)
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID OemGetFileListFromExtVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY_EXT **Buffer
+);
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OemIsValidFile
+//
+// Description: Porting hook to validate recovery capsule file
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN OemIsValidFile(
+ IN VOID *FileData,
+ IN UINTN FileSize
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFileListFromPrimaryVolume
+//
+// Description: Wrapper for porting hook OemGetFileListFromPrimaryVolume
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetFileListFromPrimaryVolume(
+ IN DIR_RECORD *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_RECORD **Buffer
+)
+{
+ OemGetFileListFromPrimaryVolume(Root, RootSize, NumberOfFiles, Buffer);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFileListFromFatVolume
+//
+// Description: Wrapper for porting hook OemGetFileListFromFatVolume
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetFileListFromFatVolume(
+ IN DIR_ENTRY *Root,
+ IN UINT32 RootEntries,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY **Buffer
+)
+{
+ OemGetFileListFromFatVolume(Root, RootEntries, NumberOfFiles, Buffer);
+}
+
+#if NTFS_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFileListFromNtfsVolume
+//
+// Description: Wrapper for porting hook OemGetFileListFromNtfsVolume
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetFileListFromNtfsVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT INDEX_ENTRY **Buffer
+)
+{
+ OemGetFileListFromNtfsVolume(Root, RootSize, NumberOfFiles, Buffer);
+}
+#endif
+
+#if EXT_RECOVERY_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetFileListFromExtVolume
+//
+// Description: Wrapper for porting hook OemGetFileListFromExtVolume
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetFileListFromExtVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY_EXT **Buffer
+)
+{
+ OemGetFileListFromExtVolume(Root, RootSize, NumberOfFiles, Buffer);
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IsValidFile
+//
+// Description: Wrapper for porting hook OemIsValidFile
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsValidFile(
+ IN VOID *FileData,
+ IN UINTN FileSize
+)
+{
+ return OemIsValidFile(FileData, FileSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: OemGetRecoveryFileInfo
+//
+// Description: Porting hook to return recovery capsule filename and size
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS OemGetRecoveryFileInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsuleName,
+ IN OUT UINTN *pCapsuleSize,
+ OUT BOOLEAN *ExtendedVerification
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetRecoveryFileInfo
+//
+// Description: Wrapper for porting hook OemGetRecoveryFileInfo
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetRecoveryFileInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsuleName,
+ IN OUT UINTN *pCapsuleSize,
+ OUT BOOLEAN *ExtendedVerification
+)
+{
+ if(pCapsuleName != NULL)
+ *pCapsuleName = (CHAR8 *)RecoveryFileName;
+
+ if(pCapsuleSize != NULL)
+ *pCapsuleSize = (UINTN)RecoveryImageSize;
+
+ if(ExtendedVerification != NULL)
+ *ExtendedVerification = FALSE;
+
+ return OemGetRecoveryFileInfo(PeiServices, pCapsuleName, pCapsuleSize, ExtendedVerification);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: AmiGetRecoveryFileInfo
+//
+// Description: Default porting hook value for OemGetRecoveryFileInfo
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS AmiGetRecoveryFileInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsuleName,
+ IN OUT UINTN *pCapsuleSize,
+ OUT BOOLEAN *ExtendedVerification
+)
+{
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Recovery/Recovery.cif b/Core/EM/Recovery/Recovery.cif
new file mode 100644
index 0000000..b5b1a7d
--- /dev/null
+++ b/Core/EM/Recovery/Recovery.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Recovery"
+ category = ModulePart
+ LocalRoot = "Core\EM\Recovery\"
+ RefName = "Recovery"
+[files]
+"Recovery.sdl"
+"Recovery.mak"
+"Recovery.c"
+"Recovery.h"
+"Recovery.dxs"
+"RecoveryCsp.h"
+[parts]
+"ReFlash"
+"RecoveryPpi"
+<endComponent>
diff --git a/Core/EM/Recovery/Recovery.dxs b/Core/EM/Recovery/Recovery.dxs
new file mode 100644
index 0000000..6dfec9f
--- /dev/null
+++ b/Core/EM/Recovery/Recovery.dxs
@@ -0,0 +1,57 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Recovery/Recovery.dxs 1 12/01/05 9:35a Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 12/01/05 9:35a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Recovery/Recovery.dxs $
+//
+// 1 12/01/05 9:35a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Recovery.dxs
+//
+// Description: Dependancy expression for the component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <PPI/LoadFile.h>
+DEPENDENCY_START
+EFI_PEI_FV_FILE_LOADER_GUID
+AND
+EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+AND
+EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Recovery/Recovery.h b/Core/EM/Recovery/Recovery.h
new file mode 100644
index 0000000..d6376b6
--- /dev/null
+++ b/Core/EM/Recovery/Recovery.h
@@ -0,0 +1,113 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Recovery/Recovery.h 10 8/02/12 11:54a Artems $
+//
+// $Revision: 10 $
+//
+// $Date: 8/02/12 11:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Recovery/Recovery.h $
+//
+// 10 8/02/12 11:54a Artems
+// [TAG] EIP93520
+// [Category] New Feature
+// [Description] Support of Microsoft ESRT spec
+// [Files] Recovery.h Recovery.sdl Recovery.c Reflash.c ReflashWorker.c
+// Esrt.c
+//
+// 9 5/13/11 4:46p Artems
+// Removed RecoveryCapsuleName and RecoveryCapsuleSize constants
+// All recovery modules should use GetRecoveryFileInfo instead
+//
+// 8 11/25/09 4:46p Felixp
+// sAmiRomFile renamed to RecoveryFileName
+// FlashSize renamed ro RecoveryImageSize
+//
+// 7 7/08/09 6:23p Artems
+// Changed file header, minor code clean-up
+//
+// 6 6/16/09 5:21p Artems
+// EIP 21169 Added Eltorito support
+//
+// 5 4/13/07 6:04p Ambikas
+// Coding standard changes: udpated the year in the AMI copyright
+// header/footer.
+//
+// 4 6/28/06 12:44p Felixp
+// OEM recovery type added
+//
+// 3 4/13/06 2:03p Ambikas
+//
+// 2 4/10/06 9:51a Ambikas
+//
+// 1 12/01/05 9:35a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Recovery.h
+//
+// Description: Recovery devices guid definition
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __RECOVERY__H__
+#define __RECOVERY__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <PPI/DeviceRecoveryModule.h>
+#include <PPI/DeviceRecoveryBlockIo.h>
+
+//Serial port recovery
+#define SERIAL_RECOVERY_CAPSULE_GUID \
+ { 0x699add70, 0x8554, 0x4993, { 0x83, 0xf6, 0xd2, 0xcd, 0xc0, 0x81, 0xdd, 0x85 } }
+
+//Recovery from mass storage device with FAT file system
+#define BLOCK_DEVICE_RECOVERY_CAPSULE_GUID \
+ { 0xba8263c, 0xa8bd, 0x4aad, { 0xb4, 0x2, 0x6a, 0x6a, 0xf2, 0xf7, 0xe7, 0x7d } }
+
+// OEM Recovery
+// {595A6EDC-6D2C-474a-9082-3B992851DFFE}
+#define OEM_RECOVERY_CAPSULE_GUID \
+ { 0x595a6edc, 0x6d2c, 0x474a, { 0x90, 0x82, 0x3b, 0x99, 0x28, 0x51, 0xdf, 0xfe } }
+
+extern EFI_GUID guidRecoveryDevice;
+extern EFI_GUID guidBlockDeviceCapsule;
+extern EFI_GUID guidSerialCapsule;
+extern EFI_GUID guidOemCapsule;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Recovery/Recovery.mak b/Core/EM/Recovery/Recovery.mak
new file mode 100644
index 0000000..0ab43c3
--- /dev/null
+++ b/Core/EM/Recovery/Recovery.mak
@@ -0,0 +1,116 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/Recovery.mak 1 5/17/13 8:01a Thomaschen $
+#
+# $Revision: 1 $
+#
+# $Date: 5/17/13 8:01a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/Recovery/Recovery.mak $
+#
+# 1 5/17/13 8:01a Thomaschen
+# Update for EIP124189.
+#
+# 8 8/09/12 11:11a Pats
+# [TAG] - EIP 80780
+# [Category] - Function Request
+# [Description] - Support for recovery from media formatted with the
+# EXT(x) file system.
+# [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+# and FsRecovery.c (source)
+#
+# 7 1/25/12 2:46p Pats
+# [TAG] - EIP 26909
+# [Category] - Function Request
+# [Description] - Support for recovery from media formatted with the NTFS
+# file system. This of necessity includes detection of GPT partitions,
+# which may contain any file system.
+# [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+# and FsRecovery.c (source)
+#
+# 6 5/13/11 4:44p Artems
+# Replaced GetFileName infrastructure with GetRecoveryFileInfo for
+# clarification
+#
+# 5 2/05/11 2:43p Artems
+# EIP 39463: Integrated Core portion for secure update - eLink support
+# for GetFileName
+#
+# 4 6/11/10 11:42a Artems
+# Added porting hooks for recovery file name and validation
+#
+# 3 7/08/09 6:21p Artems
+# Changed file header
+#
+# 2 12/02/05 11:17a Felixp
+#
+# 1 12/01/05 9:35a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Recovery.mak
+#
+# Description: Makefile for recovery module
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Recovery
+
+AMI_CSP_LIB_INCLUDE_FILES = "$(Recovery_DIR)\RecoveryCsp.h" + \
+$(AMI_CSP_LIB_INCLUDE_FILES)
+
+RECOVERY_DEFINES =\
+/DOemGetFileListFromPrimaryVolume=$(OemGetFileListFromPrimaryVolumeFunction) \
+/DOemGetFileListFromFatVolume=$(OemGetFileListFromFatVolumeFunction) \
+/DOemGetFileListFromNtfsVolume=$(OemGetFileListFromNtfsVolumeFunction) \
+/DOemGetFileListFromExtVolume=$(OemGetFileListFromExtVolumeFunction) \
+/DOemIsValidFile=$(OemIsValidFileFunction) \
+!IF $(PfatServices_SUPPORT) == 1
+/DOemGetRecoveryFileInfo=PfatImageInfo
+!ELSE
+/DOemGetRecoveryFileInfo=$(OemGetRecoveryFileInfoFunction)
+!ENDIF
+
+Recovery : $(BUILD_DIR)\Recovery.mak RecoveryBin
+
+$(BUILD_DIR)\Recovery.mak : $(Recovery_DIR)\$(@B).cif $(Recovery_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(Recovery_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+RecoveryBin : $(AMIPEILIB) $(RECOVERYLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Recovery.mak all\
+ GUID=E008B434-0E73-440c-8612-A143F6A07BCB\
+ "MY_DEFINES=$(RECOVERY_DEFINES)"\
+ ENTRY_POINT=RecoveryEntry\
+ "INIT_LIST=$(RecoveryInitialize)"\
+ TYPE=PEIM COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Recovery/Recovery.sdl b/Core/EM/Recovery/Recovery.sdl
new file mode 100644
index 0000000..c735c00
--- /dev/null
+++ b/Core/EM/Recovery/Recovery.sdl
@@ -0,0 +1,235 @@
+TOKEN
+ Name = "Recovery_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Recovery support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "RECOVERY_DEVICE_ORDER"
+ Value = "CAPSULE, BLOCK, SERIAL"
+ Help = "Defines order in which devices will be searched \for the recovery image."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FAT_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SEARCH_FAT_PATH"
+ Value = "0"
+ Help = "If ON, a path may be specified in the token RECOVERY_ROM. \For FAT file system only."
+ TokenType = BOOLEAN
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NTFS_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EXT_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CD_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ATAPI_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SERIAL_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ATA_RECOVERY_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RECOVERY_SCAN_RETRIES"
+ Value = "3"
+ Help = "Number of times to scan all recovery devices before reporting error"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RECOVERY_ROM"
+ Value = "$(AMI_ROM)"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RECOVERY_IMAGE_SIZE"
+ Value = "$(FLASH_SIZE)"
+ Help = "This is the size of the recovery file used in the build process"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "Recovery_DIR"
+End
+
+MODULE
+ Help = "Includes Recovery.mak to Project"
+ File = "Recovery.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Recovery.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RECOVERYLIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(Recovery_DIR)\Recovery.lib"
+ Parent = "RECOVERYLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RecoveryInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CapsuleDeviceRecoveryEntry,"
+ Parent = "RecoveryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BlockDeviceRecoveryEntry,"
+ Parent = "RecoveryInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SerialRecoveryPeimEntry,"
+ Parent = "RecoveryInitialize"
+ Token = "SERIAL_RECOVERY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "Atapi_RecoveryPeimEntry,"
+ Parent = "RecoveryInitialize"
+ Token = "ATAPI_RECOVERY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "Ata_RecoveryPeimEntry,"
+ Parent = "RecoveryInitialize"
+ Token = "ATA_RECOVERY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemGetFileListFromPrimaryVolumeFunction"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AmiGetFileListFromPrimaryVolume"
+ Parent = "OemGetFileListFromPrimaryVolumeFunction"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemGetFileListFromFatVolumeFunction"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AmiGetFileListFromFatVolume"
+ Parent = "OemGetFileListFromFatVolumeFunction"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemGetFileListFromNtfsVolumeFunction"
+ InvokeOrder = ReplaceParent
+ Token = "NTFS_RECOVERY_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "AmiGetFileListFromNtfsVolume"
+ Parent = "OemGetFileListFromNtfsVolumeFunction"
+ InvokeOrder = AfterParent
+ Token = "NTFS_RECOVERY_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "OemGetFileListFromExtVolumeFunction"
+ InvokeOrder = ReplaceParent
+ Token = "EXT_RECOVERY_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "AmiGetFileListFromExtVolume"
+ Parent = "OemGetFileListFromExtVolumeFunction"
+ InvokeOrder = AfterParent
+ Token = "EXT_RECOVERY_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "OemIsValidFileFunction"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AmiIsValidFile"
+ Parent = "OemIsValidFileFunction"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "OemGetRecoveryFileInfoFunction"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AmiGetRecoveryFileInfo"
+ Parent = "OemGetRecoveryFileInfoFunction"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/Recovery/RecoveryCsp.h b/Core/EM/Recovery/RecoveryCsp.h
new file mode 100644
index 0000000..8460371
--- /dev/null
+++ b/Core/EM/Recovery/RecoveryCsp.h
@@ -0,0 +1,849 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/BIN/Core/Modules/Recovery/RecoveryCsp.h 5 8/09/12 11:12a Pats $
+//
+// $Revision: 5 $
+//
+// $Date: 8/09/12 11:12a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/Modules/Recovery/RecoveryCsp.h $
+//
+// 5 8/09/12 11:12a Pats
+// [TAG] - EIP 80780
+// [Category] - Function Request
+// [Description] - Support for recovery from media formatted with the
+// EXT(x) file system.
+// [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+// and FsRecovery.c (source)
+//
+// 4 1/25/12 2:47p Pats
+// [TAG] - EIP 26909
+// [Category] - Function Request
+// [Description] - Support for recovery from media formatted with the NTFS
+// file system. This of necessity includes detection of GPT partitions,
+// which may contain any file system.
+// [Files] Recovery.c, Recovery.mak, Recovery.sdl, RecoveryCsp.h (bin),
+// and FsRecovery.c (source)
+//
+// 3 5/13/11 4:44p Artems
+// Replaced GetFileName infrastructure with GetRecoveryFileInfo for
+// clarification
+//
+// 2 2/05/11 2:46p Artems
+// EIP 39463: Added support for secure update - GetFileName eLink
+//
+// 1 6/11/10 11:45a Artems
+// Definitions of layout for FAT and ISO9660 structures
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: RecoveryCsp.h
+//
+// Description:
+// File system recovery data types definition
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef __RECOVERY_CSP__H__
+#define __RECOVERY_CSP__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <PPI/DeviceRecoveryBlockIo.h>
+
+#define FAT12 0
+#define FAT16 1
+#define FAT32 2
+#define NTFS 3
+#define EXTx 4
+
+//
+// Some NTFS definitions
+//
+#define FILE_RECORD_SIZE 1024 // Size of an NTFS file record
+#define MAXIMUM_RECORD_NUMBER 0x0000FFFFFFFFFFFF // NTFS max record no.
+#define FR_ATTRIBUTE_NAME 0x00000030
+#define FR_ATTRIBUTE_VOLUME_NAME 0x00000060
+#define FR_ATTRIBUTE_DATA 0x00000080
+#define FR_ATTRIBUTE_INDEX_ROOT 0x00000090
+#define FR_ATTRIBUTE_INDEX_ALLOC 0x000000A0
+#define MINIMUM_ENTRY_SIZE 0x58
+
+#pragma pack(push, 1)
+
+typedef struct
+{
+ CHAR8 FileName[11];
+ UINT8 Unused[3]; //Attr, NTRes, CrtTimeTenth;
+ UINT16 Unused1[3]; //CrtTime, CrtDate, LstAccDate;
+ UINT16 FirstClusterHi;
+ UINT16 Unused2[2]; //WrtTime, WrtDate;
+ UINT16 FirstClusterLo;
+ UINT32 FileSize;
+} DIR_ENTRY;
+
+typedef struct
+{
+ UINT8 jmp[3]; //0
+ CHAR8 OEMName[8]; //3
+ UINT16 BytsPerSec; //11
+ UINT8 SecPerClus; //13
+ UINT16 RsvdSecCnt; //14
+ UINT8 NumFATs; //16
+ UINT16 RootEntCnt; //17
+ UINT16 TotSec16; //19
+ UINT8 Media; //21
+ UINT16 FATSz16; //22
+ UINT16 SecPerTrk; //24
+ UINT16 NumHeads; //26
+ UINT32 HiddSec; //28
+ UINT32 TotSec32; //32
+ union
+ {
+ struct
+ {
+ UINT8 Padding[510 - 36];
+ } Fat16;
+ struct
+ {
+ UINT32 FATSz32; //36
+ UINT8 Padding1[4]; //40
+ UINT32 RootClus; //44
+ UINT8 Padding2[510 - 48];
+ } Fat32;
+ struct
+ {
+ UINT32 FATSz32u; //36
+ UINT64 TotSec64; //40
+ UINT64 MFTClus; //48
+ UINT8 Padding3[510 - 56];
+ } Ntfs;
+ } Fat;
+ UINT16 Signature;
+} BOOT_SECTOR;
+
+typedef struct _RC_VOL_INFO
+{
+ UINT32 BlockSize;
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI *BlkIo;
+ UINTN Device;
+ UINT8 FatType;
+ UINT8 *FatPointer;
+ DIR_ENTRY *RootPointer;
+ UINT64 PartitionOffset;
+ UINT64 FatOffset;
+ UINT64 RootOffset;
+ UINT64 DataOffset;
+ UINT32 BytesPerCluster;
+} RC_VOL_INFO;
+
+typedef struct
+{
+ UINT8 Length, ExtAttrLength; //1,2
+ UINT32 ExtentOffset, Unused1; //3..10
+ UINT32 DataLength, Unused2; //11..18
+ UINT8 DataTime[7]; //19..25
+ UINT8 Flags; //26
+ UINT8 Unused3[32 - 26]; //27..32
+ UINT8 LengthOfFileId; //33
+} DIR_RECORD;
+
+typedef struct
+{
+ UINT8 Type; //1
+ CHAR8 StandardId[5]; //2..6
+ UINT8 Version; //7
+ UINT8 Unused1[156 - 7]; //8..156
+ DIR_RECORD RootDir; //157..190
+ UINT8 Padding;
+ CHAR8 Unused2[2048 - 190]; //191..2048
+} PRIMARY_VOLUME_DESCRIPTOR;
+
+typedef struct
+{
+ UINT8 BootRecordIndicator;
+ CHAR8 ISO9660Identifier[0x5];
+ UINT8 DescriptorVersion;
+ CHAR8 BootSystemIdentifier[0x20];
+ CHAR8 Unused0[0x20];
+ UINT32 BootCatalogFirstSector;
+ UINT8 Unused1[0x7B6];
+} BOOT_RECORD_VOLUME_DESCRIPTOR;
+
+typedef struct
+{
+ UINT8 HeaderID;
+ UINT8 PlatformID;
+ UINT8 Reserved0[0x2];
+ CHAR8 ManufacturerID[0x18];
+ UINT16 Checksum;
+ UINT16 Key;
+} VALIDATION_ENTRY;
+
+typedef struct
+{
+ UINT8 BootIndicator;
+ UINT8 BootMediaType;
+ UINT16 LoadSegment;
+ UINT8 SystemType;
+ UINT8 Unused0;
+ UINT16 SectorCount;
+ UINT32 LoadRBA;
+ UINT8 Unused1[0x14];
+} INITIAL_DEFAULT_ENTRY;
+
+typedef struct _MBR_PARTITION
+{
+ UINT8 BootIndicator;
+ UINT8 StartHead;
+ UINT8 StartSector;
+ UINT8 StartTrack;
+ UINT8 OSType;
+ UINT8 EndHead;
+ UINT8 EndSector;
+ UINT8 EndTrack;
+ UINT32 StartingLba;
+ UINT32 SizeInLba;
+} MBR_PARTITION;
+
+typedef struct _MASTER_BOOT_RECORD
+{
+ UINT8 BootCode[440];
+ UINT32 UniqueMbrSig;
+ UINT16 Unknown;
+ MBR_PARTITION PartRec[4];
+ UINT16 Sig;
+} MASTER_BOOT_RECORD;
+
+//
+// GUID Partition structures
+//
+typedef struct _GUID_PARTITION
+{
+ UINT8 TypeGuid[16];
+ UINT8 UniqueGuid[16];
+ UINT64 FirstLba;
+ UINT64 LastLba;
+ UINT64 Flags;
+ CHAR16 Name[36];
+} GUID_PARTITION;
+
+typedef struct _GUID_BOOT_RECORD
+{
+ GUID_PARTITION GuidPart[4];
+} GUID_BOOT_RECORD;
+
+typedef struct _GUID_TABLE_HEADER
+{
+ UINT8 Signature[8];
+ UINT32 Revision;
+ UINT32 HeaderSize;
+ UINT32 HeaderCRC;
+ UINT32 Reserved;
+ UINT64 CurrentLBA;
+ UINT64 BackupLBA;
+ UINT64 FirstLBA;
+ UINT64 LastLBA;
+ UINT8 DiskGuid[16];
+ UINT64 StartLBA;
+ UINT32 EntryCount;
+ UINT32 EntrySize;
+ UINT32 ArraySize;
+} GUID_TABLE_HEADER;
+
+//
+// NTFS Structures
+//
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: MFT_FILE_RECORD
+//
+// Description: Structure of a Master File Table file record.
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _MFT_FILE_RECORD
+{
+ CHAR8 FR_Name[4]; // 0x00 - Always "FILE"
+ UINT16 FR_UpdateSeqOffset; // 0x04
+ UINT16 FR_UpdateSeqSize; // 0x06
+ UINT64 FR_LogSeqNumber; // 0x08
+ UINT16 FR_SequenceNumber; // 0x10
+ UINT16 FR_HardLinkCount; // 0x12
+ UINT16 FR_AttributeOffset; // 0x14 - Offset to Attributes
+ UINT16 FR_Flags; // 0x16 - File Record Flags
+ // 0x01 - Record is in use
+ // 0x02 - Record is a directory
+ UINT32 FR_RealSize; // 0x18 - Real size of record
+ UINT32 FR_AllocatedSize; // 0x1C - Allocated size of record
+ UINT64 FR_BaseRecordNumber; // 0x20 - Zero if this is a base record
+} MFT_FILE_RECORD;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FR_ATTR_HEADER_RES
+//
+// Description: Structure of a File Record resident attribute header.
+//
+// Referrals:
+//
+// Note(s): The "Name" in this structure is not a file name, but the
+// name of the attribute. Not used in this driver.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _FR_ATTR_HEADER_RES
+{
+ UINT32 AHR_Type; // 0x00 - Attribute Type
+ // 0x30 - File Name
+ // 0x80 - Data
+ UINT32 AHR_Length; // 0x04 - Attribute Length
+ UINT8 AHR_NonResFlag; // 0x08 - Non-Resident Flag
+ UINT8 AHR_NameLength; // 0x09 - Name Length (if named)
+ UINT16 AHR_NameOffset; // 0x0A - Offset to Name (if named)
+ UINT16 AHR_Flags; // 0x0C - Attribute Hdr. Flags
+ // 0x0001 - Compressed
+ // 0x4000 - Encrypted
+ // 0x8000 - Sparse
+ UINT16 AHR_AttributeId; // 0x0E
+ UINT32 AHR_InfoLength; // 0x10 - Attribute Information Length
+ UINT16 AHR_InfoOffset; // 0x14 - Offset to this Attribute's
+ // Information
+ UINT16 AHR_IndexFlag; // 0x16
+} FR_ATTR_HEADER_RES;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FR_ATTR_HEADER_NONRES
+//
+// Description: Structure of a File Record non-resident attribute header.
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _FR_ATTR_HEADER_NONRES
+{
+ UINT32 AHNR_Type; // 0x00 - Attribute Type
+ // 0x30 - File Name
+ // 0x80 - Data
+ UINT32 AHNR_Length; // 0x04 - Attribute Length
+ UINT8 AHNR_NonResFlag; // 0x08 - Non-Resident Flag
+ UINT8 AHNR_NameLength; // 0x09 - Name Length (if named)
+ UINT16 AHNR_NameOffset; // 0x0A - Offset to Name (if named)
+ UINT16 AHNR_Flags; // 0x0C - Flags
+ // 0x0001 - Compressed
+ // 0x4000 - Encrypted
+ // 0x8000 - Sparse
+ UINT16 AHNR_AttributeId; // 0x0E
+ UINT64 AHNR_StartingVCN; // 0x10 - Staeting Virtual Cluster Number
+ UINT64 AHNR_LastVCN; // 0x18 - Last Virtual Cluster Number
+ UINT16 AHNR_RunOffset; // 0x20 - Offset to data runs
+ // (Usually 0x40 for a
+ // Data attribute)
+} FR_ATTR_HEADER_NONRES;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FR_NAME_ATTRIBUTE (0x30)
+//
+// Description: Structure of a Master File Table Name Attribute.
+//
+// Referrals:
+//
+// Notes: Time stamps in NTFS are the number of 100ns units since
+// January 1, 1601.
+// This attribute is preceeded by a resident attribute header.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _FR_NAME_ATTRIBUTE
+{
+ UINT64 NA_PDReference; // 0x00 - Parent Directory Reference
+ UINT64 NA_CreationTime; // 0x08 - File Creation Time
+ UINT64 NA_AlteredTime; // 0x10 - File Altered Time
+ UINT64 NA_MFTChangedTime; // 0x18 - MFT Record Changed Time
+ UINT64 NA_ReadTime; // 0x20 - File Read Time
+ UINT64 NA_AllocatedSize; // 0x28 - Allocated Size of File
+ UINT64 NA_RealSize; // 0x30 - Real size of File
+ UINT32 NA_Flags; // 0x38 - File Flags
+ // Note: These flags correspond to
+ // DOS flags up to 0x20 (Archive).
+ // If other flags are set, reject
+ // the file.
+ UINT32 NA_Reparse; // 0x3C
+ UINT8 NA_NameLength; // 0x40 - Length of file name in Words
+ UINT8 NA_NameType; // 0x41 - File Name type
+ // 0x00 - POSIX
+ // 0x01 - Unicode
+ // 0x02 - DOS
+ // 0x03 - Both
+ CHAR16 NA_Name[1]; // 0x42 - File Name (unicode)
+} FR_NAME_ATTRIBUTE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FR_DATA_ATTRIBUTE (0x80)
+//
+// Description: Structure of a Master File Table Data Attribute.
+//
+// Referrals:
+//
+// Notes: This attribute can be preceeded by a resident or non-resident
+// attribute header. If resident, the data will be the actual
+// file data. If non-resident, the data will be a run list
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _FR_DATA_ATTRIBUTE
+{
+ UINT8 DA_Data[1]; // 0x00 - Run List or data
+} FR_DATA_ATTRIBUTE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FR_INDEX_ROOT_ATTRIBUTE (0x90)
+//
+// Description: Structure of a Master File Table Index Root Attribute.
+//
+// Referrals:
+//
+// Notes: A small index will have it's entries inside this attribute.
+// This attribute is preceeded by a resident attribute header.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct _FR_INDEX_ROOT_ATTRIBUTE
+{
+ UINT32 IRA_Type;
+ UINT32 IRA_Collation;
+ UINT32 IRA_Size;
+ UINT8 IRA_ClustersPerIndexRec;
+ UINT8 Padding1[3];
+ UINT32 IRA_Offset; // 0x10 - Offset to Index entries (if small index)
+ // The above offset is from here,
+ // not from beginning.
+ UINT32 IRA_TotalSize;
+ UINT32 IRA_AllocSize;
+ UINT8 IRA_Flags; // 0x1C - 0 = small index, 1 = large index
+ UINT8 Padding2[3];
+} FR_INDEX_ROOT_ATTRIBUTE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FR_INDEX_ALLOC_ATTRIBUTE (0xA0)
+//
+// Description: Structure of a Master File Table Index Allocation Attribute.
+//
+// Referrals:
+//
+// Notes: A large index will be in a separate index file, and the
+// run list in this attribute will indicate where it is.
+// This attribute is preceeded by a non-resident attribute header
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct _FR_INDEX_ALLOC_ATTRIBUTE
+{
+ UINT8 IAA_RunList[1]; // 0x00 - Run list of index record
+} FR_INDEX_ALLOC_ATTRIBUTE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: INDEX_RECORD
+//
+// Description: Structure of an Index record.
+//
+// Referrals:
+//
+// Notes: In NTFS, the Index is equivalent to a directory in FAT. A large
+// index will be contained in an Index Record, while a small index
+// will be contained within the Master File Table File Record for
+// the index, in the Index Root Attribute. Index Records are
+// files, the way FAT directories are files, but not every
+// "directory" will have a file. See the structure INDEX_ENTRY
+// for the actual "directory entry" format.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct _INDEX_RECORD
+{
+ CHAR8 INDR_Name[4]; // 0x00 - Always "INDX"
+ UINT16 INDR_UpSeqOff; // 0x04 - Offset to update sequence
+ UINT16 INDR_UpSeqSize; // 0x06 - Size of update sequence
+ UINT64 INDR_LogSeqNo; // 0x08 - Log sequence number
+ UINT64 INDR_VCN; // 0x10 - Virtual Cluster Number
+ UINT32 INDR_IndxEntryOff; // 0x18 - Offset to Index Entries
+ // (from here, not from start)
+ UINT32 INDR_IndxEntrySize; // 0x1C - Size of Index Entries
+ UINT32 INDR_IndxEntryAlloc; // 0x20 - Allocated size of Entries
+ UINT8 INDR_LeafNode; // 0x24 - 1 if not leaf node
+ UINT8 INDR_Padding[3]; // 0x25 - Padding
+ UINT16 INDR_UpdateSequence; // 0x28 - Update Sequence
+ UINT16 INDR_SeqenceArray[1]; // 0x2A - Sequence Array
+} INDEX_RECORD;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: INDEX_ENTRY
+//
+// Description: Structure of an Index record entry.
+//
+// Referrals:
+//
+// Notes: In NTFS, the index is the equivalent of a directory in FAT,
+// so the index entry is the equivalent of a directory entry.
+// The lower 4 bytes of the MFT reference is the number of the
+// file's File Record in the MFT. The lower 4 bytes of the MFT
+// parent reference is the number of the File Record for the
+// Index that this entry is in.
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct _INDEX_ENTRY
+{
+ UINT64 INDE_MFTRecord; // 0x00 - MFT reference of this entry's file
+ UINT16 INDE_EntrySize; // 0x08 - Size of this entry
+ UINT16 INDE_NameOffset; // 0x0a - Offset to file name
+ UINT16 INDE_IndexFlags; // 0x0C - Index Flags
+ UINT16 INDE_Padding;
+ UINT64 INDE_MFTParentRec; // 0x10 - MFT refernece of this entry's parent
+ UINT64 INDE_CreationTime; // 0x18 - File Creation Time
+ UINT64 INDE_AlteredTime; // 0x20 - File Altered Time
+ UINT64 INDE_MFTChangedTime; // 0x28 - MFT Record Changed Time
+ UINT64 INDE_ReadTime; // 0x30 - File Read Time
+ UINT64 INDE_AllocSize; // 0x38 - Allocated File Size
+ UINT64 INDE_RealSize; // 0x40 - Real File Size
+ UINT64 INDE_FileFlags; // 0x48 - File Flags (like DOS flags + more)
+ UINT8 INDE_NameLength; // 0x50 - Length of File name
+ UINT8 INDE_NameType; // 0x51 - File Name type
+ // 0x00 - POSIX
+ // 0x01 - Unicode
+ // 0x02 - DOS
+ // 0x03 - Both
+ CHAR16 INDE_Name[1]; // 0x52 - File Name (Unicode, not terminated)
+} INDEX_ENTRY;
+
+//
+// EXTx STRUCTURES
+//
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DIR_ENTRY_EXT
+//
+// Description: Structure of a EXT directory entry
+//
+// Referrals:
+//
+// Notes: The directory entry length must be a multiple of 4 bytes
+// Padding will be added after the name if necessary.
+// Note that the directory does not contain any file info
+// other than the name. That info is in the inode for the file.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct _DIR_ENTRY_EXT {
+ UINT32 DIR_Inode; // 0x00 - Inode no. of file
+ UINT16 DIR_EntryLength; // 0x04 - Length of dir. entry
+ UINT8 DIR_NameLength; // 0x06 - Length of name
+ UINT8 DIR_FileType; // 0x07 - Type of file
+ // 1 = regular file, 2 = directory
+ CHAR8 DIR_Name[1]; // 0x08 - File name starts here
+} DIR_ENTRY_EXT;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: VOLUME_SB
+//
+// Description: Structure of the Volume SuperBlock for EXT volumes.
+//
+// Referrals:
+//
+// Notes: The Superblock is equivalent to the BPB of a FAT or NTFS
+// volume, containing information about the volume. However,
+// it does not contain any boot code.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _VOLUME_SB {
+ UINT32 SB_TotalInodes; // 0x00 - Total Inodes
+ UINT32 SB_TotalBlocks; // 0x04 - Total size in blocks
+ UINT32 SB_ReservedBlocks; // 0x08 - Reserved blocks
+ UINT32 SB_FreeBlocks; // 0x0C - Free blocks
+ UINT32 SB_FreeInodes; // 0x10 - Free inodes
+ UINT32 SB_FirstBlock; // 0x14 - First data block (always 1 or 0)
+ UINT32 SB_BlockSize; // 0x18 - Block size shift value
+ // The actual block size is calculated
+ // as 1024 << SB_BlockSize
+ UINT32 SB_FragSize; // 0x0C - Fragment size
+ UINT32 SB_BlocksPerGroup; // 0x20 - Blocks per group
+ UINT32 SB_FragsPerGroup; // 0x24 - Fragments per group
+ UINT32 SB_InodesPerGroup; // 0x28 - Inodes per group
+ UINT32 SB_LastMountTime; // 0x2C - Time of last mount
+ UINT32 SB_LastWriteTime; // 0x30 - Time of last write
+ UINT16 SB_MountCount; // 0x34 - Count of mounts since verification
+ UINT16 SB_MaxMountCount; // 0x36 - Max mounts allowed before check
+ UINT16 SB_Magic; // 0x38 - Magic number (0xEF53)
+ UINT16 SB_StatusFlag; // 0x3A - 1 = clean, 2 = error
+ UINT16 SB_ErrorDo; // 0x3C - What to do if error
+ UINT16 SB_MinorRev; // 0x3E - Minor revision level
+ UINT32 SB_LastCheckTime; // 0x40
+ UINT32 SB_CheckInterval; // 0x44
+ UINT32 SB_CreatorOS; // 0x48 - OS that created the volume (0=Linux)
+ UINT32 SB_Revision; // 0x4C
+ UINT16 SB_DefaultUID; // 0x50 - Default User ID
+ UINT16 SB_DefaultGID; // 0x52 - Default Group ID
+ UINT32 SB_FirstInode; // 0x54 - First non-reserved inode
+ UINT16 SB_InodeStrucSize; // 0x58 - Inode structure size
+ UINT16 SB_BlockGroupNo; // 0x5A - Block Group Number
+ UINT32 SB_CompFeatMap; // 0x5C - Compatible feature bitmap
+ UINT32 SB_IncompFeatMap; // 0x60 - Incompatible feature bitmap
+ UINT32 SB_ROCompFeatMap; // 0x64 - Read-only comp. feature bitmap
+ EFI_GUID SB_UUID; // 0x68 - Volume Unique ID
+ CHAR8 SB_VolumeName[16]; // 0x78 - Volume name
+ CHAR8 SB_LastPath[64]; // 0x88 - Last mount path (normally not used)
+ UINT32 SB_AlgoBitmap; // 0xC8 - Compression algorithm bitmap
+ UINT8 SB_PreAllocBlocks; // 0xCC - Blocks to pre-allocate for new file
+ UINT8 SB_PreAllocBlocksDir;// 0xCD - Blocks to pre-allocate for new directory
+ UINT8 SB_Padding[512-0xCE];// 0xCE - Padding to 1024 starts here
+ // We're loading this into an MBR buffer,
+ // so we only pad to 512.
+} VOLUME_SB;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: VOLUME_BGDT
+//
+// Description: Structure of the Volume Block Group Descriptor Table.
+//
+// Referrals:
+//
+// Notes: In EXT, volumes are arranged as groups of blocks. The size
+// of each group is defined in SB_BlocksPerGroup in the
+// Superblock. The descriptor table gives info about the group.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _VOLUME_BGDT {
+ UINT32 BGDT_BlockBitmapBlk; // 0x00 - Block bitmap block number
+ UINT32 BGDT_InodeBitmapBlk; // 0x04 - Inode bitmap block number
+ UINT32 BGDT_InodeTableBlk; // 0x08 - Inode table block number
+ UINT16 BGDT_FreeBlocks; // 0x0C - Free blocks in the group
+ UINT16 BGDT_FreeInodes; // 0x0E - Free inodes in the group
+ UINT16 BGDT_UsedDirs; // 0x10 - Inodes used for directories in the group
+ UINT16 BGDT_Padding; // 0x12 - Padding
+ UINT8 BGDT_Reserved[12]; // 0x14 - Reserved
+} VOLUME_BGDT;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: VOLUME_IT
+//
+// Description: Structure of an Inode table
+//
+// Referrals:
+//
+// Notes: The inode table table contains all the information about each
+// file EXCEPT the file's name, which is in the directory.
+// The directory contains the file's name and inode number.
+// The inodes are numbered sequentially in the table, and the
+// table occupies consecutive blocks.
+//
+// EXT2, EXT3 File allocation method:
+// The block map of the file in IT_Blocks works as follows:
+// The first 12 entries are direct block numbers of the file.
+// The 13th entry is the number of a block containing block
+// numbers of the file (single-indirect blocks).
+// The 14th entry is the number of a block containing block
+// numbers of blocks containing file block numbers (double-
+// indirect blocks).
+// Similarly, the 15th entry is triple-indirect blocks.
+// Therefore, the maximum file size with 1024-byte blocks
+// would be 12+256+65536+16777216 1024-byte blocks.
+//
+// EXT4 File allocation method:
+// Instead of a block map, EXT4 has a header followed by up
+// to 4 extents of contiguous blocks. If the entire file is
+// contiguous, there will be only one extent. Each extent
+// consists of a 32-bit logical block no. (relative to the
+// start of the file), a 16-bit block count, and a 48-bit
+// physical block number, expressed as a 16-bit high value
+// and a 32-bit low value. If a file requires more than 4
+// extents, the value of EH_Depth in the header will be
+// non-zero, and the first extent will point to a block of
+// extents indtead of the file.
+//
+// The file dates in VOLUME_IT are the number of seconds since
+// January 1, 1970.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _EXT_HDR {
+ UINT16 EH_Magic; // 0x00 - Magic number (0xF30A)
+ UINT16 EH_Extents; // 0x02 - Number of extents
+ UINT16 EH_Max; // 0x04 - Maximum no. of extents
+ UINT16 EH_Depth; // 0x06 - Depth of tree (0 normally)
+ UINT32 EH_Generation; // 0x08 - Generation ID (currently 0)
+} EXT_HDR;
+typedef struct _EXT_EXT {
+ UINT32 EE_LogBlk; // 0x00 - Logical block no.
+ UINT16 EE_Length; // 0x04 - Length of extent in blocks
+ UINT16 EE_BlockHi; // 0x06 - Uppper 16 bits of block no.
+ UINT32 EE_BlockLo; // 0x08 - Lower 32 bits of block no.
+} EXT_EXT;
+
+typedef struct _VOLUME_IT {
+ UINT16 IT_Type; // 0x00 - File type and access rights
+ // 0x8??? = regular file
+ // 0x4??? = directory
+ UINT16 IT_UID; // 0x02 - User ID
+ UINT32 IT_SizeLo; // 0x04 - File size (low 32 bits)
+ UINT32 IT_ATime; // 0x08 - Last access time
+ UINT32 IT_CTime; // 0x0C - File creation time
+ UINT32 IT_MTime; // 0x10 - File modified time
+ UINT32 IT_DTime; // 0x14 - File deleted time
+ UINT16 IT_GID; // 0x18 - Group ID
+ UINT16 IT_Links; // 0x1A - Links to this file (usually 1)
+ UINT32 IT_ListSize; // 0x1C - Block list size in 512-byte units.
+ UINT32 IT_Flags; // 0x20 - File flags
+ UINT32 IT_OSD1; // 0x24 - OS Dependant value no. 1
+ union
+ {
+ struct
+ {
+ UINT32 Blocks[15]; // 0x28 - Blocks occupied by file (see notes)
+ } Ext2;
+ struct
+ {
+ EXT_HDR Header; // 0x28 - Extent header
+ EXT_EXT Extent[4]; // 0x34 - Extents of file (see notes)
+ } Ext4;
+ } Alloc;
+ UINT32 IT_Version; // 0x64 - File version
+ UINT32 IT_FileACL; // 0x68 - File Access Control List
+ UINT32 IT_SizeHi; // 0x6C - File size (high 32 bits)
+ UINT32 IT_Fragment; // 0x70 - Not used in Linux
+ UINT32 IT_OSD2[3]; // 0x74 - OS Dependant value no. 2
+} VOLUME_IT;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: MEMORY_BLOCK
+//
+// Description: Structure of a memory boock used to hold various basic
+// structures.
+//
+// Referrals:
+//
+// Notes: In order to make a smaller compiled binary, this memory block
+// is allocated, and used to hold structures that were formerly
+// reserved statically.
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _MEMORY_BLOCK {
+ MASTER_BOOT_RECORD Mbr; // Master boot record (all file systems)
+ BOOT_SECTOR Bs; // Boot sector (FAT and NTFS)
+ UINT8 MFTRunList[256];// Master File Table run list (NTFS)
+ UINT8 RootRunList[128];// Root dir run list (NTFS)
+ UINT8 ResidentIndex[256];// Stores resident index (NTFS)
+ VOLUME_SB Sb; // Superblock (EXT(n))
+ VOLUME_IT RootInode; // Root directory inode (EXT(n))
+ VOLUME_IT FileInode; // File inode (EXT(n))
+} MEMORY_BLOCK;
+
+#pragma pack(pop)
+
+//**************** eLink override definitions *******************************
+//This functions may be overriden by eLinks
+
+VOID GetFileListFromPrimaryVolume(
+ IN DIR_RECORD *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_RECORD **Buffer
+);
+
+VOID GetFileListFromFatVolume(
+ IN DIR_ENTRY *Root,
+ IN UINT32 RootEntries,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY **Buffer
+);
+
+VOID GetFileListFromNtfsVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT INDEX_ENTRY **Buffer
+);
+
+VOID GetFileListFromExtVolume(
+ IN UINT8 *Root,
+ IN UINT32 RootSize,
+ OUT UINTN *NumberOfFiles,
+ OUT DIR_ENTRY_EXT **Buffer
+);
+
+BOOLEAN IsValidFile(
+ IN VOID *FileData,
+ IN UINTN FileSize
+);
+
+EFI_STATUS GetRecoveryFileInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsuleName,
+ IN OUT UINTN *pCapsuleSize,
+ OUT BOOLEAN *ExtendedVerification
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/Recovery/RecoverySrc.cif b/Core/EM/Recovery/RecoverySrc.cif
new file mode 100644
index 0000000..76a2a77
--- /dev/null
+++ b/Core/EM/Recovery/RecoverySrc.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "Recovery Sources"
+ category = ModulePart
+ LocalRoot = "Core\EM\Recovery\"
+ RefName = "RecoverySrc"
+[files]
+"RecoverySrc.sdl"
+"FsRecovery.c"
+"RecoverySrc.mak"
+"SerialRecovery.c"
+"IdeRecovery.c"
+"CapsuleRecovery.c"
+<endComponent>
diff --git a/Core/EM/Recovery/RecoverySrc.mak b/Core/EM/Recovery/RecoverySrc.mak
new file mode 100644
index 0000000..411502c
--- /dev/null
+++ b/Core/EM/Recovery/RecoverySrc.mak
@@ -0,0 +1,81 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Modules/Recovery/RecoverySrc.mak 8 6/16/11 9:02a Felixp $
+#
+# $Revision: 8 $
+#
+# $Date: 6/16/11 9:02a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Modules/Recovery/RecoverySrc.mak $
+#
+# 8 6/16/11 9:02a Felixp
+# Enhancement: Replace NAME=RECOVERY with LIBRARY_NAME=$(RECOVERYLIB)
+# to avoid temporary files with identical names in Recovery and
+# RecoverySrc modules.
+#
+# 7 7/01/09 4:19p Rameshr
+# Coding Standard and File header updated.
+#
+# 6 12/29/06 2:59p Felixp
+#
+# 5 10/13/06 4:40p Felixp
+#
+# 4 8/24/06 9:33a Felixp
+# x64 Support: recovery.lib splitted into PEI and DXE parts
+#
+# 3 12/19/05 6:36p Felixp
+#
+# 2 12/02/05 11:22a Felixp
+#
+# 1 12/01/05 9:45a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: RecoverySrc.mak
+#
+# Description: Builds the Recovery source and create the Recovery.lib
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : RecoverySrc
+
+$(RECOVERYLIB) : RecoverySrc
+
+RecoverySrc : $(BUILD_DIR)\RecoverySrc.mak RecoverySrcPeiBin
+
+$(BUILD_DIR)\RecoverySrc.mak : $(Recovery_DIR)\$(@B).cif $(Recovery_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(Recovery_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+RecoverySrcPeiBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\RecoverySrc.mak all\
+ MAKEFILE=$(BUILD_DIR)\RecoverySrc.mak\
+ LIBRARY_NAME=$(RECOVERYLIB) TYPE=PEI_LIBRARY
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Recovery/RecoverySrc.sdl b/Core/EM/Recovery/RecoverySrc.sdl
new file mode 100644
index 0000000..3c5513c
--- /dev/null
+++ b/Core/EM/Recovery/RecoverySrc.sdl
@@ -0,0 +1,21 @@
+TOKEN
+ Name = "RecoverySrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Recovery Sources support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "Recovery_SUPPORT" "=" "1"
+End
+
+MODULE
+ File = "RecoverySrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Recovery.lib"
+ Parent = "$(Recovery_DIR)\Recovery.lib"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/Recovery/SerialRecovery.c b/Core/EM/Recovery/SerialRecovery.c
new file mode 100644
index 0000000..1c59c62
--- /dev/null
+++ b/Core/EM/Recovery/SerialRecovery.c
@@ -0,0 +1,1047 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Modules/Recovery/SerialRecovery.c 8 2/13/12 4:13a Rajeshms $
+//
+// $Revision: 8 $
+//
+// $Date: 2/13/12 4:13a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Modules/Recovery/SerialRecovery.c $
+//
+// 8 2/13/12 4:13a Rajeshms
+// [TAG] EIP80704
+// [Category] New Feature
+// [Description] Serial Recovery support through PCI Serial Port .
+// [Files] PciSerialRecovery.mak, PciSerialRecovery.sdl,
+// PciSerialRecovery.c, PciSerialRecovery.h, PciSerialRecovery.chm,
+// PciSerialRecovery.dxs, SerialRecovery.c, SerialDevice.h
+//
+// 7 5/13/11 5:08p Artems
+// Added secure flash update support
+//
+// 6 11/25/09 4:53p Felixp
+// sAmiRomFile renamed to RecoveryFileName
+// FlashSize renamed ro RecoveryImageSize
+//
+// 5 7/10/09 10:42a Rameshr
+// Recovery from Multiple Serial Device support Added
+// EIP:21100
+//
+// 4 7/01/09 4:19p Rameshr
+// Coding Standard and File header updated.
+//
+// 3 5/20/06 2:58p Felixp
+//
+// 2 12/19/05 5:52p Robert
+// The GetSerialChar function was not returning the character properly in
+// the parameter list. A pointer was being created and it was initialized
+// to a value, but the pointer itself was never initialized. A CHAR8
+// variable was created and the pointer was initialized to that variable.
+// It worked in debug mode because the compiler set aside a data space for
+// the pointer and that the optimized version didn't.
+//
+// 1 12/01/05 9:45a Felixp
+//
+// 1 7/15/05 10:40a Eswark
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: SerialRecovery.c - PEI driver
+//
+// Description: Implements Serial Recovery Functions
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "Recovery.h"
+#include "RecoveryCsp.h"
+
+#include <AmiPeiLib.h>
+#include <Ppi\Stall.h>
+#include <Ppi\DeviceRecoveryModule.h>
+#include <Ppi\SerialDevice.h>
+
+
+#define BAUD_DIVISOR_LSB 0x0001
+#define BAUD_DIVISOR_MSB 0x0000
+#define MAX_USER_DELAY 0x1E84EC //wait for user response in 15 microseconds units
+#define MAX_DATA_DELAY 0x1046A //Wait for data byte in 50 microseconds units
+#define MAX_DATA1_DELAY 0x28B0A
+#define MAX_RESP_DELAY 0x1E //Max Response time in 1 second units
+#define XMODEM_SOH 0x01 // Start Header
+#define XMODEM_EOT 0x04 // End of Transfer
+#define XMODEM_ACK 0x06 // Acknowledge
+#define XMODEM_NAK 0x15 // Negative Acknowledge
+#define XMODEM_CAN 0x18 // Cancel Transfer
+
+#define COM_BASE_ADDRESS 0x3f8
+
+VOID SendSerialChar (
+ CHAR8 c
+);
+BOOLEAN GetSerialData1 (
+ UINT8* ReadData
+);
+BOOLEAN GetSerialData (
+ UINT8* ReadData
+);
+VOID SendSerialData (
+ UINT8 d
+);
+VOID SendSerialString (
+ CHAR8* Str
+);
+BOOLEAN GetSerialChar (
+ CHAR8* ReadChar
+);
+VOID PrintCopyRightMessage ( );
+VOID InitSerialPort ( );
+
+UINT8 ReadSerialDevice (
+ IN PEI_RECOVERY_SERIAL_MODE_PPI *This,
+ IN UINT8 Offset
+);
+
+VOID WriteSerialDevice (
+ IN PEI_RECOVERY_SERIAL_MODE_PPI *This,
+ IN UINT8 Offset,
+ IN UINT8 Data
+);
+
+EFI_PEI_SERVICES **mPeiServices;
+
+PEI_RECOVERY_SERIAL_MODE_PPI *SerialModePpi=NULL;
+
+EFI_STATUS
+EFIAPI GetNumberRecoveryCapsules (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ OUT UINTN *NumberRecoveryCapsules );
+
+EFI_STATUS
+EFIAPI GetRecoveryCapsuleInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT UINTN *Size,
+ OUT EFI_GUID *CapsuleType );
+
+EFI_STATUS
+EFIAPI LoadRecoveryCapsule (
+ IN OUT EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT VOID *Buffer );
+
+BOOLEAN ReadFileFromSerial (
+ CHAR8 * Buffer,
+ UINT32* Size,
+ UINT8 *result );
+
+BOOLEAN ReadSerialBlock (
+ UINT8* Buffer );
+
+BOOLEAN SendNakAck (
+ UINT8 * Data,
+ UINT8 XCommand );
+
+EFI_GUID gEfiPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+static EFI_GUID gPeiDevRecModuleGuid = EFI_PEI_DEVICE_RECOVERY_MODULE_PPI_GUID;
+EFI_PEI_STALL_PPI *mStallPpi;
+
+EFI_PEI_DEVICE_RECOVERY_MODULE_PPI SerialRecoveryModule = {
+ GetNumberRecoveryCapsules, GetRecoveryCapsuleInfo, LoadRecoveryCapsule
+};
+
+// PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR SerialRecoveryPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidRecoveryDevice, &SerialRecoveryModule
+ }
+};
+
+EFI_GUID guidSerialRecoveryDevice=PEI_RECOVERY_SERIAL_MODE_PPI_GUID;
+
+PEI_RECOVERY_SERIAL_MODE_PPI ComSerialDevice =
+{
+ COM_BASE_ADDRESS,
+ ReadSerialDevice,
+ WriteSerialDevice
+};
+
+// PPI to be installed
+EFI_PEI_PPI_DESCRIPTOR SerialDevicePpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidSerialRecoveryDevice, &ComSerialDevice
+ }
+};
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SerialRecoveryPeimEntry
+//
+// Description: Serial Recovery PEI entry Function
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader- FFSHeader
+// IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+EFIAPI SerialRecoveryPeimEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+
+ mPeiServices = PeiServices;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gEfiPeiStallPpiGuid,
+ 0,
+ NULL,
+ &mStallPpi
+ );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = (*PeiServices)->InstallPpi( PeiServices, SerialRecoveryPpiList );
+
+ //
+ //Install the Serial Device for Com port 0x3f8
+ //
+ Status = (*PeiServices)->InstallPpi (PeiServices,SerialDevicePpiList);
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetNumberRecoveryCapsules
+//
+// Description: Get the Number of Recovery Capsules
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This
+// OUT UINTN *NumberRecoveryCapsules- Number of Recovery Capsule
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS
+EFIAPI GetNumberRecoveryCapsules(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ OUT UINTN *NumberRecoveryCapsules )
+{
+ *NumberRecoveryCapsules = 1;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetRecoveryCapsuleInfo
+//
+// Description: Get the Recovery Capsule Information
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This
+// IN UINTN CapsuleInstance,
+// OUT UINTN *Size,
+// OUT EFI_GUID *CapsuleType
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS
+EFIAPI GetRecoveryCapsuleInfo(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT UINTN *Size,
+ OUT EFI_GUID *CapsuleType )
+{
+ EFI_STATUS Status;
+
+ *CapsuleType = guidSerialCapsule;
+
+ Status = GetRecoveryFileInfo(PeiServices, NULL, Size, NULL);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PrintBaseAddress
+//
+// Description: Print the Serial Port base address
+//
+// Input: IN UINT16 BaseAddress
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PrintBaseAddress(
+ IN UINT64 BaseAddress
+)
+{
+
+ CHAR8 TempBuffer[5]={0,0,0,0,0};
+ UINTN ValueCharNum=0;
+ UINTN Remainder;
+ CHAR8 TempPrintBuffer[5]={0,0,0,0,0};
+ UINTN Index=0;
+
+ do {
+ BaseAddress = (UINT64)Div64 ((UINT64)BaseAddress, 0x10, &Remainder);
+
+ if(Remainder < 0xa) {
+ TempBuffer[ValueCharNum] = (CHAR8)(Remainder + '0');
+ } else {
+ TempBuffer[ValueCharNum] = (CHAR8)(Remainder + 'A' - 0xa);
+ }
+ ValueCharNum++;
+ } while (BaseAddress != 0);
+
+ //
+ // Reverse temp string into Buffer.
+ //
+ while (ValueCharNum) {
+ TempPrintBuffer[Index] = TempBuffer[ValueCharNum-1];
+ ValueCharNum--;
+ Index++;
+ }
+ SendSerialString(&TempPrintBuffer[0]);
+ return;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LoadRecoveryCapsule
+//
+// Description: Download the Capsule file from the Serial device and returns the buffer
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices - pointer to PEI services
+// IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This
+// IN UINTN CapsuleInstance,
+// OUT VOID *Buffer- Recovery Capsule Data
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS
+EFIAPI LoadRecoveryCapsule(
+ IN OUT EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_DEVICE_RECOVERY_MODULE_PPI *This,
+ IN UINTN CapsuleInstance,
+ OUT VOID *Buffer )
+{
+ CHAR8 *pBuff;
+ UINT32 FileSize;
+ UINT8 Result = 0xFF;
+ CHAR8 *message;
+ UINTN Number;
+ CHAR8 Char = 0;
+ CHAR8 *ReadChar = &Char;
+ UINT32 waitCount;
+ BOOLEAN Recovery = FALSE;
+ UINT8 Index=0;
+ EFI_STATUS Status;
+ UINTN RecoveryCapsuleSize;
+ BOOLEAN ExtendedVerification;
+
+ Status = GetRecoveryFileInfo(PeiServices, NULL, &RecoveryCapsuleSize, &ExtendedVerification);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ mPeiServices = PeiServices;
+ Index=0;
+
+ do {
+
+ //
+ //Locate the Serial Device PPI
+ //
+ Status = (**PeiServices).LocatePpi (PeiServices, &guidSerialRecoveryDevice, Index, NULL, &SerialModePpi);
+
+ //
+ //If Found Proceed with Reading recovery file. If not break the loop and return the status
+ //
+ if ((EFI_ERROR (Status))) {
+ break;
+ }
+
+ FileSize = (UINT32)RecoveryCapsuleSize;
+
+ GetNumberRecoveryCapsules(PeiServices, This, &Number);
+ if(Number == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ InitSerialPort( );
+
+ *ReadChar = '\n';
+ SendSerialChar( *ReadChar );
+ PrintCopyRightMessage();
+
+ message="Press space to start recovery from Serial Address 0x";
+ //
+ //Display the Serial Port Base address
+ //
+ SendSerialString(message);
+ PrintBaseAddress((UINT64)SerialModePpi->SerialDeviceBaseAddress);
+ message="\n\r or 'N' to try Next Serial Device or 'Q' to quit\n\r";
+ SendSerialString(message);
+ do {
+ waitCount=0xF; // EKCheck
+ while ( waitCount-- ) {
+ if ( GetSerialChar( ReadChar ) == TRUE ) {
+ Recovery = TRUE;
+ break;
+ }
+ }
+
+ if(*ReadChar ==' ') {
+ break;
+ }
+
+ if (*ReadChar=='N' || *ReadChar=='n') {
+ //
+ // Try the Next Serial Device
+ //
+ message="Trying next serial device if avilable.\n\r";
+ SendSerialString(message);
+ Recovery=FALSE;
+ break;
+ }
+ if ( *ReadChar == 'Q' || *ReadChar == 'q' ) {
+ //
+ //Exit from Serial Recovery
+ //
+ message = "Serial Recovery is aborted by user.\n\r";
+ SendSerialString( message );
+ return EFI_ABORTED;
+ }
+ } while(Recovery==TRUE);
+
+ if(Recovery == FALSE) {
+ //
+ // Try Next Device
+ //
+ Index++;
+ continue;
+ }
+ message="Send BIOS image using XMODEM protocol\n\r";
+ SendSerialString( message );
+
+ //
+ //Wait for 3-5 Seconds before User Sends a file
+ //
+ mStallPpi->Stall( mPeiServices, mStallPpi, 20000000 );
+
+ pBuff = Buffer;
+
+ if ( !ReadFileFromSerial( pBuff, &FileSize, &Result )) {
+ PEI_TRACE((-1, PeiServices, "\nRead File Failed Capsule Size= %d, FileRead Result=%d\n", FileSize, Result));
+
+ if ( Result == 1 ) {
+ PEI_TRACE((-1, PeiServices, "\nNo Responce from Terminal\n"));
+ }
+
+ if ( Result == 3 ) {
+ PEI_TRACE((-1, PeiServices, "\nFile Size over Run\n"));
+ }
+
+ //
+ // Error getting Recovery file from current serial device. So try another
+ // Serial Device
+ //
+ Index++;
+ continue;
+ } else {
+ //
+ //File got successfully. So Return
+ //
+ if(ExtendedVerification || FileSize == (UINT32)RecoveryCapsuleSize)
+ return EFI_SUCCESS;
+ }
+ }while(TRUE);
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: InitSerialPort
+//
+// Description: Initilize the Serial port Registers
+//
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitSerialPort( )
+{
+ //
+ // Disable all interrupts
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, InteruptEnableReg, 0x00);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Enable Baud Rate Programming
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, LineControlReg, 0x80);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Program Baud Rate LSB
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, SerialDataReg, BAUD_DIVISOR_LSB);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Program Baud Rate MSB
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, InteruptEnableReg, BAUD_DIVISOR_MSB);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Set to 8 bits, 1 Stop, No Parity
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, LineControlReg, 0x03);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Clear and enable FIFOs
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, FifoControlReg, 0x01);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Disable all interrupts
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, InteruptEnableReg, 0x00);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Clear and enable FIFOs
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, FifoControlReg, 0xC7);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+ //
+ // Activate DTR and RTS
+ //
+ SerialModePpi->WriteSerialDevice(SerialModePpi, ModemControlReg, 0x03);
+ mStallPpi->Stall( mPeiServices, mStallPpi, 1000 );
+
+ //
+ // Discard any garbage that may be in the receive FIFO
+ //
+ while ( (SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg)) & 01 ) {
+ SerialModePpi->ReadSerialDevice(SerialModePpi,SerialDataReg); // else, read data and discard
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadFileFromSerial
+//
+// Description: Read the Recovery file through Serial Device
+//
+// Input: CHAR8 * Buffer- Data buffer
+// UINT32* Size- Size
+// UINT8 * result- Result Status
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ReadFileFromSerial(
+ CHAR8 * Buffer,
+ UINT32* Size,
+ UINT8 * result )
+{
+ // Read recovery file through serial port, check checksum, signature etc.,
+ // and copy it to the buffer ImageStart.
+
+ UINT32 NumBlocks = *Size / 128;
+ UINT32 count = 10;
+ UINT32 BlockID = 1;
+ UINT32 TimeOut = 10; //1 second (in .1 sec units) timeout
+ UINT8 BlockNum = 1;
+ UINT8 Command = XMODEM_NAK;
+ UINT8 Data = 0;
+ CHAR8* InChar = '\0';
+ BOOLEAN Status;
+
+ NumBlocks++;
+ while ( NumBlocks )
+ {
+ if ( !SendNakAck( &Data, Command )) //send NAK
+ {
+ *result = 1;
+ return FALSE;
+ }
+
+ if ( Data == XMODEM_EOT ) //if end of transfer, exit with success
+ {
+ Command = XMODEM_ACK;
+ SendSerialData( Command );
+ BlockID--;
+ *Size = BlockID * 128;
+ *result = 0;
+ return TRUE;
+ }
+
+ if ( Data == XMODEM_SOH ) {
+ //
+ //Start header received, get rest of the packet
+ //
+ Status = GetSerialData( &Data );
+ //
+ //read block#
+ //
+ if ( Status && (Data == BlockNum)) {
+ Status = GetSerialData( &Data );
+
+ if ( Status ) {
+ //if FF-block number doesn't match, retry
+ if ( ReadSerialBlock( Buffer )) {
+ // Read 128 byte packet
+ BlockNum++;
+ BlockID++;
+ NumBlocks--;
+ Command = XMODEM_ACK;
+ continue;
+ }
+ }
+ }
+ while ( GetSerialData( &Data ))
+ {
+ ;
+ }
+ }
+ }
+
+ //
+ //No more block to read, No EOT byte received, terminate xfer and exit with error
+ //
+ *result = 3;
+ while ( GetSerialData( &Data )) {
+ ; //If abort, read and discard
+ }
+ Command = XMODEM_CAN;
+ while ( count-- ) {
+ SendSerialData( Command ); // Send CANCEL Command
+ }
+ return FALSE;
+}
+
+UINT32 CurrentIndex = 0; //global variable to hold current buffer index
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadSerialBlock
+//
+// Description: Read the Serial Block
+//
+// Input: CHAR8 * Buffer- Data buffer
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN ReadSerialBlock(
+ UINT8* Buffer )
+{
+ UINT8 CheckSum = 0;
+ UINT8 DataByte = 0;
+ UINT8 * DataBuffer = Buffer;
+ UINT32 TempIndex = CurrentIndex;
+ UINT8 bytecount;
+
+ //
+ //read 128 byte packet
+ //
+ for ( bytecount = 1; bytecount <= 128; bytecount++ ) {
+ //
+ //if error reading serial port, retry packet
+ //
+ if ( !(GetSerialData( DataBuffer + CurrentIndex ))) {
+ CurrentIndex = TempIndex;
+ return FALSE;
+ }
+ CheckSum += *(DataBuffer + CurrentIndex++);
+ }
+
+ //
+ //Get Checksum byte
+ //
+ if ( !(GetSerialData( &DataByte ))) {
+ CurrentIndex = TempIndex;
+ return FALSE;
+ }
+
+ //
+ //if byte checksum doesn't match, retry
+ //
+ if ( DataByte != CheckSum ) {
+ CurrentIndex = TempIndex;
+ return FALSE;
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SendNakAck
+//
+// Description: Send the Ack
+//
+// Input: UINT8 * Data,
+// UINT8 XCommand
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SendNakAck(
+ UINT8 * Data,
+ UINT8 XCommand )
+{
+ UINT8 AbortCount = 12, count = 24; //Number of NAKs or ACKs to send before abort
+ CHAR8 * SerialMsg;
+
+ while ( count-- ){
+ SendSerialData( XCommand );
+
+ if ( GetSerialData1( Data )) {
+ return TRUE;
+ }
+ }
+ //if timeout, cancel the transfer and
+ // return false, with abort message
+ while ( GetSerialData( Data )) //If abort, read and discard
+ {
+ ;
+ }
+ XCommand = XMODEM_CAN;
+ while ( AbortCount-- ) {
+ SendSerialData( XCommand ); // Send CANCEL Command
+ }
+ SerialMsg = "\n\rAborting Serial Recovery";
+ SendSerialString( SerialMsg );
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SendSerialChar
+//
+// Description: Send a character to Serial Port
+//
+// Input: CHAR8 c- Data to send
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SendSerialChar(
+ CHAR8 c )
+{
+ while ( !(SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x20) ) {
+ ;
+ }
+ SerialModePpi->WriteSerialDevice(SerialModePpi, SerialDataReg, (UINT8)c);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetSerialData1
+//
+// Description: Get the Data from Serial Port
+//
+// Input: UINT8* ReadData - Data Got from Serial Device
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GetSerialData1(
+ UINT8* ReadData )
+{
+ long MaxDelay = MAX_DATA1_DELAY;
+
+ //
+ // wait for upto 1 second for the data byte to be ready
+ //
+ while ( MaxDelay-- )
+ {
+ if ( SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x0A ) {
+ //
+ //exit if overrun/framing error
+ //
+ return FALSE;
+ }
+
+ if ( SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x01 ) {
+ //
+ //exit loop if character ready in Reveive buffer
+ //
+ break;
+ }
+ }
+
+ if ( MaxDelay <= 0 ) {
+ return FALSE;
+ }
+
+ //
+ //read data byte from receive biffer
+ //
+ *ReadData = SerialModePpi->ReadSerialDevice(SerialModePpi,SerialDataReg);
+
+ return TRUE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetSerialData
+//
+// Description: Get the Data from Serial Port
+//
+// Input: UINT8* ReadData - Data Got from Serial Device
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GetSerialData(
+ UINT8* ReadData )
+{
+ long MaxDelay = MAX_DATA_DELAY;
+ volatile infinite = 1;
+ //
+ //wait for upto 1 second for the data byte to be ready
+ //
+ while ( MaxDelay-- )
+ {
+ if ( SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x0A ) {
+ //
+ //exit if overrun/framing error
+ //
+ return FALSE;
+ }
+
+ if ( SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x01 ) {
+ //
+ //exit loop if character ready in Reveive buffer
+ //
+ break;
+ }
+ }
+
+ if ( MaxDelay <= 0 ) {
+ return FALSE;
+ }
+ //
+ //read data byte from receive biffer
+ //
+ *ReadData = SerialModePpi->ReadSerialDevice(SerialModePpi,SerialDataReg);
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SendSerialData
+//
+// Description: Send the Data to serial Device
+//
+// Input: UINT8 d - Data to be send it to Serial Device
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SendSerialData(
+ UINT8 d )
+{
+ while ( !(SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x20) )
+ {
+ ;
+ }
+ SerialModePpi->WriteSerialDevice(SerialModePpi, SerialDataReg, d);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: SendSerialString
+//
+// Description: Send the String to serial Device
+//
+// Input: CHAR8* Str - String to be send it to Serial Device
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SendSerialString(
+ CHAR8* Str )
+{
+ while ( *Str )
+ {
+ SendSerialChar( *Str++ );
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: GetSerialChar
+//
+// Description: Get the Char from the Serial Device
+//
+// Input: CHAR8* ReadChar - Data from Serial Device
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GetSerialChar(
+ CHAR8* ReadChar ) // ReadChar is the output character
+{
+ long MaxDelay = MAX_USER_DELAY;
+
+ //
+ //Wait for upto 30s for the user to enter Response
+ //
+ while ( MaxDelay-- ) {
+ if ( SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x0A ) {
+ //
+ //exit if overrun/framing error
+ //
+ return FALSE;
+ }
+
+ if ( SerialModePpi->ReadSerialDevice(SerialModePpi,LineStatusReg) & 0x01 ) {
+ //
+ //exit loop if character ready in Reveive buffer
+ //
+ break;
+ }
+ }
+
+ if ( MaxDelay <= 0 ) {
+ return FALSE;
+ }
+ //
+ //read character from receive biffer
+ //
+ *ReadChar = (CHAR8) SerialModePpi->ReadSerialDevice(SerialModePpi,SerialDataReg);
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: PrintCopyRightMessage
+//
+// Description: Display the CopyRight Message in Serial Device
+//
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PrintCopyRightMessage( )
+{
+ static CHAR8
+ *Message = "\n\r*********************************************************\n\r"
+ "(C)Copyright 1985-2012, American Megatrends, Inc.\n\r"
+ " All Rights Reserved.\n\r"
+ " AMI Serial Recovery.\n\r"
+ "*********************************************************\n\r";
+
+ SendSerialString( Message );
+}
+
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ReadSerialDevice
+//
+// Description:
+// Reads from address(COM_BASE_ADDRESS+offset) that is mapped toSerial
+// Device.
+//
+// Input:
+// IN PEI_RECOVERY_SERIAL_MODE_PPI *This - Pointer to
+// PEI_RECOVERY_SERIAL_MODE_PPI
+// IN UINT8 Offset - Offset to read the data from the Baseaddress
+//
+// Output:
+// UINT8 - Data Read from the Device
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+UINT8 ReadSerialDevice (
+ IN PEI_RECOVERY_SERIAL_MODE_PPI *This,
+ IN UINT8 Offset
+)
+{
+ return IoRead8( COM_BASE_ADDRESS + Offset );
+}
+
+// <AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: WriteSerialDevice
+//
+// Description:
+// Writes into address(COM_BASE_ADDRESS+offset) that is mapped to Serial
+// Device.
+//
+// Input:
+// IN PEI_RECOVERY_SERIAL_MODE_PPI *This - Pointer to
+// PEI_RECOVERY_SERIAL_MODE_PPI
+// IN UINT8 Offset - Offset to write the data from the Baseaddress
+// IN UINT8 Data - Data to be written
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//---------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID WriteSerialDevice (
+ IN PEI_RECOVERY_SERIAL_MODE_PPI *This,
+ IN UINT8 Offset,
+ IN UINT8 Data
+)
+{
+ IoWrite8( COM_BASE_ADDRESS + Offset , Data );
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.c b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.c
new file mode 100644
index 0000000..c34848d
--- /dev/null
+++ b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.c
@@ -0,0 +1,178 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/RestoreSpecialBootOptions/RestoreSpecialBootOptions.c 3 9/10/13 8:14a Dukeyeh $
+//
+// $Revision: 3 $
+//
+// $Date: 9/10/13 8:14a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/RestoreSpecialBootOptions/RestoreSpecialBootOptions.c $
+//
+// 3 9/10/13 8:14a Dukeyeh
+// [TAG] EIP135544
+// [Category] Bug Fix
+// [RootCause] RestoreSpecialOrphanBootOptions don't compare multi ELINK
+// names
+// [Solution] Change to be able to compare multi ELINKs for target boot
+// options
+// [Files] RestoreSpecialBootOptions.sdl
+// RestoreSpecialBootOptions.chm
+// RestoreSpecialBootOptions.c
+//
+// 2 7/12/13 12:40a Dukeyeh
+// [TAG] EIP127111
+// [Category] New Feature
+// [Description] 1. Initial Release
+// 2. This module restores some special
+// boot options that have been applied orphan boot options policy on.
+// [Files] RestoreSpecialBootOptions.c
+//
+//**********************************************************************
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: RestoreSpecialBootOptions.c
+//
+// Description: Restore some special boot options.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <RestoreSpecialBootOptions.h>
+#include <BootOptions.h>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UnMaskFilePathList
+//
+// Description: Unmask the file path that was masked before.
+//
+// Input: BOOT_OPTION *Option - the boot option's file path to be unmasked
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UnMaskFilePathList(BOOT_OPTION *Option) {
+ VENDOR_DEVICE_PATH *MaskedDp;
+ UINTN MaskedDpLength;
+
+ MaskedDp = (VENDOR_DEVICE_PATH*)Option->FilePathList;
+ MaskedDpLength = DPLength(&MaskedDp->Header);
+ if (Option->FilePathListLength <= MaskedDpLength) return;
+ Option->FilePathListLength -=MaskedDpLength;
+ MemCpy(
+ Option->FilePathList, (UINT8*)Option->FilePathList+MaskedDpLength,
+ Option->FilePathListLength
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreBootOptionByPolicy
+//
+// Description: Restore the orphan boot option by policy.
+//
+// Input: DLIST *BootOptionList - the master boot option list
+// BOOT_OPTION *Option - The orphaned boot option
+// UINTN Policy - the policy to follow, valid values are
+// ORPHAN_BOOT_OPTIONS_POLICY_DELETE
+// ORPHAN_BOOT_OPTIONS_POLICY_DISABLE
+// ORPHAN_BOOT_OPTIONS_POLICY_KEEP
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreBootOptionByPolicy(
+ DLIST *BootOptionList, BOOT_OPTION *Option, const int Policy
+) {
+ /*if (Policy==ORPHAN_BOOT_OPTIONS_POLICY_DELETE){
+ }else*/
+ if (Policy==ORPHAN_BOOT_OPTIONS_POLICY_DISABLE) {
+ Option->Attributes |= LOAD_OPTION_ACTIVE;
+ } else if (Policy==ORPHAN_BOOT_OPTIONS_POLICY_HIDE) {
+ Option->Attributes &= ~LOAD_OPTION_HIDDEN;
+ UnMaskFilePathList(Option);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreSpecialOrphanBootOptions
+//
+// Description: This function restores the target orphan boot options that
+// have been applied policy on.
+//
+// Input: none
+//
+// Output: none
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreSpecialOrphanBootOptions() {
+ DLINK *Link;
+ BOOT_OPTION *Option;
+ CHAR16 *RestoreBootOptionsByName[] = {RESTORED_BOOT_OPTION_NAMES NULL};
+ UINT8 RegisteredBootOptionNames = sizeof(RestoreBootOptionsByName)/sizeof(CHAR16*) - 1; // minus NULL
+ UINT8 NameIndex;
+
+ if (0 == RegisteredBootOptionNames)
+ return;
+
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option) {
+
+ if (RegisteredBootOptionNames) {
+
+ for (NameIndex = 0; NULL != RestoreBootOptionsByName[NameIndex]; NameIndex++) {
+
+ if (!Wcscmp(Option->Description, RestoreBootOptionsByName[NameIndex])) {
+
+ if (Option->FwBootOption) {
+ RestoreBootOptionByPolicy(
+ BootOptionList, Option, FW_ORPHAN_BOOT_OPTIONS_POLICY
+ );
+ }
+ else {
+ RestoreBootOptionByPolicy(
+ BootOptionList, Option, NON_FW_ORPHAN_BOOT_OPTIONS_POLICY
+ );
+ }
+
+ --RegisteredBootOptionNames;
+ if (0 == RegisteredBootOptionNames)
+ return;
+
+ break;
+ }
+ }
+ }
+ }
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.chm b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.chm
new file mode 100644
index 0000000..d040ff5
--- /dev/null
+++ b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.chm
Binary files differ
diff --git a/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.cif b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.cif
new file mode 100644
index 0000000..eeb7736
--- /dev/null
+++ b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "RestoreSpecialBootOptions"
+ category = eModule
+ LocalRoot = "Core\Em\RestoreSpecialBootOptions\"
+ RefName = "RestoreSpecialBootOptions"
+[files]
+"RestoreSpecialBootOptions.sdl"
+"RestoreSpecialBootOptions.mak"
+"RestoreSpecialBootOptions.chm"
+"RestoreSpecialBootOptions.c"
+<endComponent>
diff --git a/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.mak b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.mak
new file mode 100644
index 0000000..c0a560e
--- /dev/null
+++ b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.mak
@@ -0,0 +1,73 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/BootOptionPolicies/RestoreSpecialBootOptions/RestoreSpecialBootOptions.mak 2 7/12/13 12:42a Dukeyeh $
+#
+# $Revision: 2 $
+#
+# $Date: 7/12/13 12:42a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/BootOptionPolicies/RestoreSpecialBootOptions/RestoreSpecialBootOptions.mak $
+#
+# 2 7/12/13 12:42a Dukeyeh
+# [TAG] EIP127111
+# [Category] New Feature
+# [Description] Initial Release.
+# [Files] RestoreSpecialBootOptions.mak
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: RestoerSpecialBootOptions.mak
+#
+# Description: Makefile for the RestoreSpecialBootOptions component.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\RestoreSpecialBootOptions.obj
+
+OBJ_DEPENDENCIES = \
+ $(RestoreSpecialBootOptions_DIR)\RestoreSpecialBootOptions.c\
+ $(BUILD_DIR)\RestoreSpecialBootOptions.h
+
+$(BUILD_DIR)\RestoreSpecialBootOptions.obj : $(OBJ_DEPENDENCIES)
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(RestoreSpecialBootOptions_DIR)\RestoreSpecialBootOptions.c
+
+H_DEPENDENCIES = \
+ $(BUILD_DIR)\Token.h\
+ $(RestoreSpecialBootOptions_DIR)\RestoreSpecialBootOptions.mak
+
+$(BUILD_DIR)\RestoreSpecialBootOptions.h : $(H_DEPENDENCIES)
+ $(SILENT)type << >$(BUILD_DIR)\RestoreSpecialBootOptions.h
+#define RESTORED_BOOT_OPTION_NAMES $(RESTORED_BOOT_OPTION_NAMES)
+<<
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2013, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.sdl b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.sdl
new file mode 100644
index 0000000..cb6a89e
--- /dev/null
+++ b/Core/EM/RestoreSpecialBootOptions/RestoreSpecialBootOptions.sdl
@@ -0,0 +1,39 @@
+TOKEN
+ Name = RestoreSpecialBootOptions_SUPPORT
+ Value = "1"
+ TokenType = Boolean
+ Master = Yes
+ Help = "Main switch to enable RestoreSpecialBootOptions support in Project"
+End
+
+PATH
+ Name = "RestoreSpecialBootOptions_DIR"
+End
+
+MODULE
+ Help = "Includes RestoreSpecialBootOptions.mak to Project"
+ File = "RestoreSpecialBootOptions.mak"
+End
+
+ELINK
+ Name = "RestoreSpecialOrphanBootOptions,"
+ Parent = "PreProcessBootOptions,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RESTORED_BOOT_OPTION_NAMES"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = 'L"USB Entry for Windows To Go",'
+ Parent = "RESTORED_BOOT_OPTION_NAMES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = 'L"USB Entry for Windows To Go Logo Test",'
+ Parent = "RESTORED_BOOT_OPTION_NAMES"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/Runtime/CpuIoDxe.c b/Core/EM/Runtime/CpuIoDxe.c
new file mode 100644
index 0000000..e542418
--- /dev/null
+++ b/Core/EM/Runtime/CpuIoDxe.c
@@ -0,0 +1,547 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Runtime/CpuIoDxe.c 5 5/17/12 4:14p Artems $
+//
+// $Revision: 5 $
+//
+// $Date: 5/17/12 4:14p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Runtime/CpuIoDxe.c $
+//
+// 5 5/17/12 4:14p Artems
+// [TAG] EIP N/A
+// [Category] Improvement
+// [Description] Added support to address MMIO space above 4GB in x64
+// mode
+// [Files] CpuIoDxe.c
+//
+// 4 4/15/11 12:47p Artems
+// EIP 56523: Added support of PI specification v 1.2
+//
+// 3 6/24/09 4:24p Robert
+// updated Comments, copyrights, and some coding standard issues
+//
+// 2 10/21/08 3:41p Felixp
+// Support for usage of the protocol at runtime is added.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CpuIo.c
+//
+// Description:
+// This file contains Protocol functions and definitions for the
+// EFI_CPU_IO_PROTOCOL. This protocol contains functions for memory and I/O
+// access
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//==========================================================================
+// Includes
+#include <Protocol\CpuIo.h>
+#include <AmiDxeLib.h>
+
+
+//==========================================================================
+// GUID definitions
+
+//==========================================================================
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuIoMemRead
+//
+// Description:
+// This function reads from the Memory space at the address defined by Address
+// with the size defined by the lowest 2 bits in the Width parameter. It
+// repeats this Count number of times while incrementing the Buffer,
+// the Address, or both depending on the type of operation defined by the
+// upper 6 bits in the width parameter. Refer to the notes section for
+// further definition of the Width parameter
+//
+// Input:
+// IN EFI_CPU_IO_PROTOCOL *This - Pointer to the EFI_CPU_IO_PROTOCOL
+// IN EFI_CPU_IO_PROTOCOL_WIDTH Width - Contains Type and Width of the Memory operation
+// IN UINT64 Address - Memory address to read from
+// IN UINTN Count - number of times to perform the read operation
+// IN OUT VOID *Buffer - Data buffer to store the data read
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+// The Width Variable contains a width and a type component
+// - The width is defined by the lowest 2 bits
+// - The Type is defined by the other bits as follows:
+// - - Type = 0 - EfiIoWidthUintxx - Increment Buffer and address
+// - - Type = 1 - EfiIoWidthFifoUintxx - Increment only Buffer
+// - - Type > 1 - EfiIoWidthFillUintxx - Increment only Address
+// - The increment happens after each Operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuIoMemRead(
+ IN EFI_CPU_IO_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3); //1st 2 bits currently define width. Other bits define type.
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+ UINT64 Limit;
+
+ if (Buffer==NULL) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 8) return EFI_INVALID_PARAMETER;
+
+ Limit = (sizeof(UINTN) < 8) ? 0xffffffff : 0xffffffffffffffff;
+ if ((Count * IncrementValue) > (Limit - Address))
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ switch (IncrementType)
+ {
+ case 0: //EfiIoWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiIoWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiIoWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: // byte
+ *(UINT8*) Buffer = *(UINT8*)Address;
+ break;
+ case 2: // word
+ *(UINT16*) Buffer = *(UINT16*)Address;
+ break;
+ case 4: // dword
+ *(UINT32*) Buffer = *(UINT32*)Address;
+ break;
+ case 8: // qword
+ *(UINT64*) Buffer = *(UINT64*)Address;
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuIoMemWrite
+//
+// Description:
+// This function writes to the Memory space at the address defined by Address
+// with the size defined by the lowest 2 bits in the Width parameter. It
+// repeats this Count number of times while incrementing the Buffer,
+// the Address, or both depending on the type of operation defined by the
+// upper 6 bits in the width parameter. Refer to the notes section for
+// further definition of the Width parameter
+//
+// Input:
+// IN EFI_CPU_IO_PROTOCOL *This - Pointer to the EFI_CPU_IO_PROTOCOL
+// IN EFI_CPU_IO_PROTOCOL_WIDTH Width - Contains Type and Width of the Memory operation
+// IN UINT64 Address - Memory address to Write to
+// IN UINTN Count - number of times to perform the write operation
+// IN OUT VOID *Buffer - Data buffer of the data to write
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+// The Width Variable contains a width and a type component
+// - The width is defined by the lowest 2 bits
+// - The Type is defined by the other bits as follows:
+// - - Type = 0 - EfiIoWidthUintxx - Increment Buffer and address
+// - - Type = 1 - EfiIoWidthFifoUintxx - Increment only Buffer
+// - - Type > 1 - EfiIoWidthFillUintxx - Increment only Address
+// - The increment happens after each Operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuIoMemWrite(
+ IN EFI_CPU_IO_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ // 1st 2 bits currently define width. Other bits define type.
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3);
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+ UINT64 Limit;
+
+ if (Buffer==NULL) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 8) return EFI_INVALID_PARAMETER;
+
+ // Memory must be within range of the bridge.
+ Limit = (sizeof(UINTN) < 8) ? 0xffffffff : 0xffffffffffffffff;
+ if ((Count * IncrementValue) > (Limit - Address))
+ return EFI_INVALID_PARAMETER;
+
+ switch (IncrementType)
+ {
+ case 0: //EfiIoWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiIoWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiIoWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: //byte
+ *(UINT8*) Address = *(UINT8*)Buffer;
+ break;
+ case 2: //word
+ *(UINT16*) Address = *(UINT16*)Buffer;
+ break;
+ case 4: //dword
+ *(UINT32*) Address = *(UINT32*)Buffer;
+ break;
+ case 8: // qword
+ *(UINT64*) Address = *(UINT64*)Buffer;
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuIoIoRead
+//
+// Description:
+// This function reads the IO space at the address defined by Address
+// with the size defined by the lowest 2 bits in the Width parameter. It
+// repeats this Count number of times while incrementing the Buffer,
+// the Address, or both depending on the type of operation defined by the
+// upper 6 bits in the width parameter. Refer to the notes section for
+// further definition of the Width parameter
+//
+// Input:
+// IN EFI_CPU_IO_PROTOCOL *This - Pointer to the EFI_CPU_IO_PROTOCOL
+// IN EFI_CPU_IO_PROTOCOL_WIDTH Width - Contains Type and Width of the Io operation
+// IN UINT64 Address - IO address to Read from
+// IN UINTN Count - number of times to perform the read operation
+// IN OUT VOID *Buffer - Data buffer to store the data read
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+// The Width Variable contains a width and a type component
+// - The width is defined by the lowest 2 bits
+// - The Type is defined by the other bits as follows:
+// - - Type = 0 - EfiIoWidthUintxx - Increment Buffer and address
+// - - Type = 1 - EfiIoWidthFifoUintxx - Increment only Buffer
+// - - Type > 1 - EfiIoWidthFillUintxx - Increment only Address
+// - The increment happens after each Operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuIoIoRead(
+ IN EFI_CPU_IO_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ //1st 2 bits of the Width parameter currently define width. Other bits define type.
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3);
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+
+ if ((UINT32) Width >= EfiCpuIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ if (Buffer==NULL) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 8) return EFI_INVALID_PARAMETER;
+
+ if ((Address + Count * IncrementValue) > 0xffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ switch (IncrementType)
+ {
+ case 0: //EfiIoWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiIoWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiIoWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: // byte
+ *(UINT8*) Buffer = IoRead8((UINT16)Address);
+ break;
+ case 2: // word
+ *(UINT16*) Buffer = IoRead16((UINT16)Address);
+ break;
+ case 4: // dword
+ *(UINT32*) Buffer = IoRead32((UINT16)Address);
+ break;
+ case 8: // qword
+ *(UINT32*) Buffer = IoRead32((UINT16)Address);
+ *((UINT32*)((UINT32*)Buffer+1)) = IoRead32((UINT16)(Address+4));
+ break;
+ default: return EFI_INVALID_PARAMETER;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuIoIoWrite
+//
+// Description:
+// This function writes to the IO space at the address defined by Address
+// with the size defined by the lowest 2 bits in the Width parameter. It
+// repeats this Count number of times while incrementing the Buffer,
+// the Address, or both depending on the type of operation defined by the
+// upper 6 bits in the width parameter. Refer to the notes section for
+// further definition of the Width parameter
+//
+// Input:
+// IN EFI_CPU_IO_PROTOCOL *This - Pointer to the EFI_CPU_IO_PROTOCOL
+// IN EFI_CPU_IO_PROTOCOL_WIDTH Width - Contains Type and Width of the Io operation
+// IN UINT64 Address - IO address to Write to
+// IN UINTN Count - number of times to perform the write operation
+// IN OUT VOID *Buffer - Data buffer of the data to write
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+// The Width Variable contains a width and a type component
+// - The width is defined by the lowest 2 bits
+// - The Type is defined by the other bits as follows:
+// - - Type = 0 - EfiIoWidthUintxx - Increment Buffer and address
+// - - Type = 1 - EfiIoWidthFifoUintxx - Increment only Buffer
+// - - Type > 1 - EfiIoWidthFillUintxx - Increment only Address
+// - The increment happens after each Operation
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuIoIoWrite(
+ IN EFI_CPU_IO_PROTOCOL *This,
+ IN EFI_CPU_IO_PROTOCOL_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ //1st 2 bits of the Width parameter currently define width. Other bits define type.
+ UINTN IncrementType = Width & ~3;
+ UINT8 IncrementValue = 1 << (Width & 3);
+ UINT8 IncrementBuffer = 0;
+ UINT8 IncrementAddress = 0;
+
+ if ((UINT32) Width >= EfiCpuIoWidthMaximum) return EFI_INVALID_PARAMETER;
+
+ if (Buffer==NULL) return EFI_INVALID_PARAMETER;
+ if (IncrementType > 16 || IncrementValue > 4) return EFI_INVALID_PARAMETER;
+
+ if ((Address + Count * IncrementValue) > 0xffff)
+ return EFI_INVALID_PARAMETER; //Memory must be within range of the bridge.
+
+ switch (IncrementType)
+ {
+ case 0: //EfiIoWidthUintxx
+ IncrementAddress = IncrementBuffer = IncrementValue;
+ break;
+ case 4: //EfiIoWidthFifoUintxx
+ IncrementBuffer = IncrementValue;
+ break;
+ default: //EfiIoWidthFillUintxx
+ IncrementAddress = IncrementValue;
+ }
+
+ while(Count--)
+ {
+ switch(IncrementValue)
+ {
+ case 1: //byte
+ IoWrite8((UINT16)Address,*(UINT8*) Buffer);
+ break;
+ case 2: //word
+ IoWrite16((UINT16)Address,*(UINT16*) Buffer);
+ break;
+ default: //dword
+ IoWrite32((UINT16)Address,*(UINT32*) Buffer);
+ break;
+ }
+ (UINT8*) Buffer += IncrementBuffer;
+ Address += IncrementAddress;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+static EFI_CPU_IO_PROTOCOL gEfiCpuIoProtocol = {
+ { CpuIoMemRead, CpuIoMemWrite },
+ { CpuIoIoRead, CpuIoIoWrite },
+};
+
+//==========================================================================
+// Module specific Global Variable
+static EFI_RUNTIME_SERVICES *MyRS=NULL;
+// End Module specific Global Variable
+//==========================================================================
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuIoVirtAddressChange
+//
+// Description:
+// This function is a callback function that changes the Protocol function
+// pointers from Physical Address Mapping to Virtual Address Mapping
+//
+// Input:
+// IN EFI_EVENT Event - Pointer to the event that was triggered
+// IN VOID *Context - Buffer Pointer defined by the code that calls CreateEvent
+//
+// Output:
+// None
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CpuIoVirtAddressChange (IN EFI_EVENT Event, IN VOID *Context)
+{
+ MyRS->ConvertPointer(0,(VOID**)&gEfiCpuIoProtocol.Mem.Read);
+ MyRS->ConvertPointer(0,(VOID**)&gEfiCpuIoProtocol.Mem.Write);
+ MyRS->ConvertPointer(0,(VOID**)&gEfiCpuIoProtocol.Io.Read);
+ MyRS->ConvertPointer(0,(VOID**)&gEfiCpuIoProtocol.Io.Write);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CpuIoDxeInit
+//
+// Description:
+// This function is the entry point for the EFI_CPU_IO_PROTOCOL.
+//
+// Input:
+// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver
+// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CpuIoDxeInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_STATUS Status;
+
+ // initialize the AMI Library
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // install the CpuIo Protocol
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiCpuIoProtocolGuid, &gEfiCpuIoProtocol,
+#if PI_SPECIFICATION_VERSION >= 0x10014
+ &gEfiCpuIo2ProtocolGuid, &gEfiCpuIoProtocol,
+#endif
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status))
+ return Status;
+
+{
+ EFI_EVENT Event;
+ // defines the local Runtime Services pointer
+ MyRS = pRS;
+
+ // creates event for virtual address change fixup
+ Status = pBS->CreateEvent(
+ EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+ TPL_CALLBACK,
+ &CpuIoVirtAddressChange,
+ NULL,
+ &Event);
+}
+
+ return Status;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Runtime/Flash.c b/Core/EM/Runtime/Flash.c
new file mode 100644
index 0000000..60dc9f2
--- /dev/null
+++ b/Core/EM/Runtime/Flash.c
@@ -0,0 +1,1014 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/em/Runtime/Flash.c 1 7/31/17 4:54a Chienhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 7/31/17 4:54a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/em/Runtime/Flash.c $
+//
+// 1 7/31/17 4:54a Chienhsieh
+// [TAG] EIP344536
+// [Description] SA40037 - BIOS update failure vulnerability
+// [Files] Flash.c
+//
+// 12 5/24/17 12:30p Felixp
+// Bug fixes from Aptio V are back ported to Aptio 4.
+// The following issues are addressed:
+// Bug fix(EIP 201329)
+// Symptom: FlashDriver_04 did not properly mark out/restore the _FVH
+// signature when updating a firmware volume
+// Root Cause: A logic error in the code that was attempting to match
+// the requested flash address update prevented
+// the code from removing/adding the _FVH signature from the memory
+// buffer.
+// Bug fix(EIP 217270)
+// Symptom: _FVH signature was not properly restored during update of
+// multiple sequential firmware volumes.
+// Root Cause: UpdatedArea[i].AreaSize was used before it was
+// initialized if multiple sequential FV were updated
+// by first erasing the entire flash area occupied by all FV and then
+// programming the area.
+// Bug fix
+// Symptom: _FVH signature was not properly restored when more than two
+// areas were simultaneously updated.
+// Root Cause: Logic error in FlashDriverDeviceWriteDisableExt
+// Bug fix in BeforeErase function: the function used wrong value to
+// corrupt the FV signature
+// Improvement: don't corrupt the signature when area block other than the
+// first one is erased.
+// The code that deletes/restores the FV signature is updated to restore
+// the signature only if it has actually
+// been deleted by a flash driver; the signature is not restored
+// otherwise.
+//
+// 11 9/12/13 4:24a Rameshr
+// [TAG] EIP136017
+// [Category] Improvement
+// [Description] Buffer Address updated if the partial block write
+// happens
+// [Files] Flash.c
+//
+// 10 11/11/11 3:06p Artems
+// Security: Copied ROM layout structure to SMM to avoid calls outside SMM
+//
+// 9 1/25/11 12:48p Oleksiyy
+// [TAG] EIP42253
+// [Category] New Feature
+// [Description] Added support for platforms, where flash part is not
+// memory mapped while write enabled, controlled by
+// NO_MMIO_FLASH_ACCESS_DURING_UPDATE sdl token. Flash protocol used to
+// access flash in that case.
+// [Files] NVRAMDXE.c, Flash.c, Tokens.c and Runtime.sdl
+//
+// 8 10/07/10 1:40p Felixp
+// Debug messages are removed.
+//
+// 7 10/07/10 12:07p Felixp
+// Bug fix:
+// Symptoms: The AFU reported verification error during update of
+// the FFS-based ROM hole that is the first FFS file in the firmware
+// volume(FV).
+// Details: The FV signature was not restored.
+// The flash driver logic that destroys and restores the FV signature
+// during the
+// FV update didn't cover the partial update case.
+// The Flash driver is updated to restore the signature during partial FV
+// updates.
+// The signature is now restored:
+// - In case of full FV update,
+// in the AfterWrite function once the last FV block is updated.
+// - In case of partial FV update,
+// in the FlashDriverDeviceWriteDisable function
+// The FlashDriverRead function is updated to return the valid signature
+// when
+// called in the middle of the FV update.
+//
+// 6 10/01/10 7:28p Felixp
+// Previous changes are rolled back. They break the recovery update.
+//
+// 4 9/24/10 8:01a Felixp
+// Definition of CRITICAL_SECTION is updated.
+//
+// 3 8/25/09 11:46p Felixp
+// Bug Fixes:
+// 1. Symptoms: AFUDOS was occasionally hanging in debug mode.
+// Details: Debug message funcation Trace, which uses boot time
+// services was used at runtime.
+// 2. Symptoms: Erase, Write, and Update functions of the Flash Protocol
+// did not work without prior call to DeviceWriteEnable protocol function.
+// Details: Nested call to DeviceWriteEnable was failing due to busy
+// critical section. Code is updated to use non-blocking internal write
+// enable function.
+// 3. Symptoms: DeviceWriteDisable did not work properly.
+// Details: Protocol interface structure was populated with wrong
+// function pointer.
+//
+// 2 7/09/09 5:29p Oleksiyy
+// Files clean-up, headers added
+//
+// 1 5/21/09 5:12p Felixp
+// Flash Driver
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Flash.c
+//
+// Description: Flash Driver Implementation
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Flash.h>
+#include <Ffs.h>
+#include <RomLayout.h>
+#include <AmiHobs.h>
+#include <Protocol/FlashProtocol.h>
+
+typedef struct
+{
+ BOOLEAN Busy;
+ BOOLEAN SmiState;
+ UINT8 IntState[2];
+} CRITICAL_SECTION;
+
+typedef struct
+{
+ ROM_AREA *RomLayout;
+ UINT32 WriteEnableStatus;
+ CRITICAL_SECTION Cs;
+ UINT32 RomLayoutSize;
+} FLASH_DRIVER_MAILBOX;
+
+typedef struct
+{
+ FLASH_PROTOCOL Flash;
+ FLASH_DRIVER_MAILBOX *MailBox;
+} FLASH_PROTOCOL_PRIVATE;
+
+typedef struct
+{
+ ROM_AREA *RomArea;
+ UINT32 AreaSize ;
+ BOOLEAN RestoreSignature;
+} UPDATED_AREA_DESCRIPTOR;
+
+//-----Prototypes------------------------------------
+EFI_STATUS EFIAPI FlashDriverRead(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+EFI_STATUS EFIAPI FlashDriverErase(
+ VOID* FlashAddress, UINTN Size
+);
+EFI_STATUS EFIAPI FlashDriverWrite(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+EFI_STATUS EFIAPI FlashDriverUpdate(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+EFI_STATUS EFIAPI FlashDriverDeviceWriteEnable();
+EFI_STATUS EFIAPI FlashDriverDeviceWriteDisable();
+
+EFI_STATUS EFIAPI FlashDriverReadExt(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+EFI_STATUS EFIAPI FlashDriverEraseExt(
+ VOID* FlashAddress, UINTN Size
+);
+EFI_STATUS EFIAPI FlashDriverWriteExt(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+EFI_STATUS EFIAPI FlashDriverUpdateExt(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+EFI_STATUS EFIAPI FlashDriverDeviceWriteEnableExt();
+EFI_STATUS EFIAPI FlashDriverDeviceWriteDisableExt();
+
+extern const UINTN FlashEmpty;
+extern const BOOLEAN FlashNotMemoryMapped;
+
+#define BEGIN_CRITICAL_SECTION(Cs) \
+ { if ((Cs)->Busy) return EFI_ACCESS_DENIED;\
+ BeginCriticalSection(Cs);\
+ }
+#define END_CRITICAL_SECTION(Cs) EndCriticalSection(Cs)
+
+VOID BeginCriticalSection(CRITICAL_SECTION *Cs);
+VOID EndCriticalSection(CRITICAL_SECTION *Cs);
+
+//---Flash data protocole------------------------------------------
+FLASH_PROTOCOL_PRIVATE FlashData =
+{
+ {
+ FlashDriverReadExt, FlashDriverEraseExt, FlashDriverWriteExt, FlashDriverUpdateExt,
+ FlashDriverDeviceWriteEnableExt, FlashDriverDeviceWriteDisableExt
+ },
+ NULL
+};
+
+ROM_AREA *RomLayout = NULL;
+#define MAX_NUMBER_OF_UPDATED_AREAS 10
+UPDATED_AREA_DESCRIPTOR UpdatedArea[MAX_NUMBER_OF_UPDATED_AREAS];
+INT32 NumberOfUpdatedAreas=0;
+
+/*************** OUTSIDE SMM **********************************/
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDrvVirtAddressChange
+//
+// Description: Function updates the current pointer to FlashData protocol functions and
+// UpdatedArea pointed to by Address to be the proper value for the new address map
+//
+// Input:
+// IN EFI_EVENT Event Signalled event
+// IN VOID *Context Calling context
+//
+// Output: NON
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+VOID FlashDrvVirtAddressChange (
+ IN EFI_EVENT Event, IN VOID *Context
+)
+{
+ VOID **p;
+ INT32 i;
+ FlashVirtualFixup(pRS);
+ //Fixup protocol member functions
+ p=(VOID**)&FlashData.Flash.Write;
+
+ do
+ {
+ pRS->ConvertPointer(0, p++);
+ }
+ while (p!=(VOID**)&FlashData.Flash.DeviceWriteDisable);
+
+ pRS->ConvertPointer(0, &FlashData.MailBox);
+
+// if (RomLayout!=NULL) pRS->ConvertPointer(0, &RomLayout);
+
+ for (i=0; i<NumberOfUpdatedAreas; i++)
+ {
+ pRS->ConvertPointer(0, &UpdatedArea[i].RomArea);
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverInit
+//
+// Description: Creates necessary structures and instatlls Flash services before SMM mode.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle Image Handle
+// IN EFI_SYSTEM_TABLE *SystemTable Pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS FlashDriverInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ static EFI_GUID AmiRomLayoutHobGuid = AMI_ROM_LAYOUT_HOB_GUID;
+ EFI_STATUS Status;
+ EFI_HANDLE Handler = NULL;
+ ROM_LAYOUT_HOB *RomLayoutHob;
+ UINTN MailboxSize = sizeof(FLASH_DRIVER_MAILBOX);
+ UINTN RomLayoutSize;
+
+ InitAmiRuntimeLib(ImageHandle, SystemTable, NULL, FlashDrvVirtAddressChange);
+
+//Create mailbox
+ VERIFY_EFI_ERROR(pBS->AllocatePool(EfiRuntimeServicesData, MailboxSize, (VOID **)&FlashData.MailBox));
+//Get ROM layout
+ RomLayoutHob = GetEfiConfigurationTable(SystemTable, &HobListGuid);
+ if (RomLayoutHob != NULL) {
+ if (!EFI_ERROR(FindNextHobByGuid(&AmiRomLayoutHobGuid, &RomLayoutHob))) {
+ ROM_AREA *Area;
+ RomLayoutSize = RomLayoutHob->Header.Header.HobLength - sizeof(ROM_LAYOUT_HOB);
+ VERIFY_EFI_ERROR(pBS->AllocatePool(EfiBootServicesData, RomLayoutSize, &RomLayout));
+ pBS->CopyMem(RomLayout, RomLayoutHob + 1, RomLayoutSize); //save ROM Layout for future use
+
+ for (Area = RomLayout; Area->Size != 0; Area++) { //update address
+ Area->Address -= FlashDeviceBase;
+ }
+
+ //pass ROM layout to SMM driver
+ FlashData.MailBox->RomLayout = RomLayout;
+ FlashData.MailBox->RomLayoutSize = (UINT32)RomLayoutSize;
+ } else {
+ FlashData.MailBox->RomLayout = NULL;
+ FlashData.MailBox->RomLayoutSize = 0;
+ }
+ }
+
+//Fill MailBox
+ FlashData.MailBox->WriteEnableStatus = 0;
+ FlashData.MailBox->Cs.Busy = FALSE;
+ FlashData.MailBox->Cs.SmiState = FALSE;
+ FlashData.MailBox->Cs.IntState[0] = 0;
+ FlashData.MailBox->Cs.IntState[1] = 0;
+
+ Status = pBS->InstallProtocolInterface(&Handler, &gFlashProtocolGuid, EFI_NATIVE_INTERFACE, &FlashData.Flash);
+
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+/*************** INSIDE SMM **********************************/
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverSmmInit
+//
+// Description: Reinitialize necessary structures and instatlls Flash services in SMM mode.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle Image Handle
+// IN EFI_SYSTEM_TABLE *SystemTable Pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS FlashDriverSmmInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE Handler = NULL;
+ FLASH_PROTOCOL_PRIVATE *NotSmmFlash;
+
+ VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashProtocolGuid, NULL, &NotSmmFlash));
+
+//Reasign MailBox
+ FlashData.MailBox = NotSmmFlash->MailBox;
+
+//Save SMM copy of ROM layout
+ if(FlashData.MailBox->RomLayoutSize != 0) {
+ VERIFY_EFI_ERROR(pSmst->SmmAllocatePool(0, FlashData.MailBox->RomLayoutSize, &RomLayout));
+ pBS->CopyMem(RomLayout, FlashData.MailBox->RomLayout, FlashData.MailBox->RomLayoutSize);
+ }
+
+ Status = pBS->InstallProtocolInterface(&Handler, &gFlashSmmProtocolGuid, EFI_NATIVE_INTERFACE, &FlashData.Flash);
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+/*************** INSIDE and OUSIDE SMM ************************/
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BeforeErase
+//
+// Description: Invalidates FV by destroying the signature before erasing flash.
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash
+//
+// Output: NON
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID BeforeErase(VOID* FlashAddress)
+{
+ ROM_AREA *Area;
+ UINT32 Data;
+
+ if ( RomLayout == NULL
+ || NumberOfUpdatedAreas == MAX_NUMBER_OF_UPDATED_AREAS
+ ) return;
+ //---For Areas in Rom Layout------------------------------------------
+ for (Area=RomLayout; Area->Size!=0; Area++)
+ {
+ //---If this is area we are looking for-------------------------------
+ if (Area->Address+FlashDeviceBase==(EFI_PHYSICAL_ADDRESS)(UINTN)FlashAddress)
+ {
+ if (Area->Type!=RomAreaTypeFv) return;
+
+ UpdatedArea[NumberOfUpdatedAreas].AreaSize = Area->Size;
+ UpdatedArea[NumberOfUpdatedAreas].RomArea = Area;
+ UpdatedArea[NumberOfUpdatedAreas++].RestoreSignature = FALSE;
+ // Invalidate FV by destroying the signature
+ Data = (UINT32)~FlashEmpty;
+ FlashDriverWrite(
+ &((EFI_FIRMWARE_VOLUME_HEADER*)FlashAddress)->Signature,
+ sizeof(UINT32),
+ &Data
+ );
+ return;
+ }
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BeforeWrite
+//
+// Description: Invalidates FV by destroying the signature before writing to flash.
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash
+// UINTN Size Size to write
+// VOID* DataBuffer Poiner to the Data Buffer
+//
+// Output: NON
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID BeforeWrite(VOID* FlashAddress, UINTN Size, VOID* DataBuffer)
+{
+ EFI_FIRMWARE_VOLUME_HEADER* Fv;
+ INT32 i;
+
+ for (i=0; i<NumberOfUpdatedAreas; i++)
+ {
+ //---Invalidate FV by destroying the signature
+ //---(alter data being programmed)
+ if ( UpdatedArea[i].RomArea->Address+FlashDeviceBase
+ ==(EFI_PHYSICAL_ADDRESS)(UINTN)FlashAddress
+ )
+ {
+ Fv = (EFI_FIRMWARE_VOLUME_HEADER*)DataBuffer;
+
+ if ( Size < sizeof(EFI_FIRMWARE_VOLUME_HEADER)
+ || Fv->Signature != FV_SIGNATURE
+ ) //The data being programmed is not FV, don't do anything
+ {
+ UpdatedArea[i] = UpdatedArea[NumberOfUpdatedAreas-1];
+ NumberOfUpdatedAreas--;
+ }
+
+ else
+ {
+ Fv->Signature = (UINT32)FlashEmpty;
+ UpdatedArea[i].AreaSize = (UINT32)Fv->FvLength;
+ UpdatedArea[i].RestoreSignature = TRUE;
+ }
+
+ return;
+ }
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AfterWrite
+//
+// Description: Restores FV signature after writing to flash.
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash
+// UINTN Size Size to write
+// VOID* DataBuffer Poiner to the Data Buffer
+//
+// Output: NON
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID AfterWrite(VOID* FlashAddress, UINTN Size, VOID* DataBuffer)
+{
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_PHYSICAL_ADDRESS AreaAddress;
+ INT32 i;
+
+ Address = (EFI_PHYSICAL_ADDRESS)(UINTN)FlashAddress;
+ for (i=0; i<NumberOfUpdatedAreas; i++)
+ {
+ AreaAddress = UpdatedArea[i].RomArea->Address+FlashDeviceBase;
+
+ if (AreaAddress==Address)
+ {
+ //Restore original data
+ ((EFI_FIRMWARE_VOLUME_HEADER*)DataBuffer)->Signature=FV_SIGNATURE;
+ }
+
+ if (AreaAddress+UpdatedArea[i].AreaSize==Address+Size)
+ {
+ UINT32 FvSignature = FV_SIGNATURE;
+ //Restore FV signature
+ FlashDriverWrite(
+ &((EFI_FIRMWARE_VOLUME_HEADER*)AreaAddress)->Signature,
+ sizeof(UINT32),
+ &FvSignature
+ );
+ UpdatedArea[i] = UpdatedArea[NumberOfUpdatedAreas-1];
+ NumberOfUpdatedAreas--;
+ }
+ }
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AfterRead
+//
+// Description: Hook that is being called after the read operation.
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash
+// UINTN Size Size to read
+//
+// Output: NON
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+VOID AfterRead(VOID* FlashAddress, UINTN Size, VOID* DataBuffer)
+{
+ INT32 i;
+
+ if (FlashData.MailBox->WriteEnableStatus==0) return;
+ // If we are in the middle of flash update
+ // (FlashData.MailBox->WriteEnableStatus is not zero),
+ // it may happen that the FV signature has not been restored yet
+ // (typically happens during partial FV updates).
+ // Let's return the proper value. The signature will be restored later.
+ for (i=0; i<NumberOfUpdatedAreas; i++)
+ {
+ EFI_FIRMWARE_VOLUME_HEADER* Fv
+ = (EFI_FIRMWARE_VOLUME_HEADER*)(
+ UpdatedArea[i].RomArea->Address+FlashDeviceBase
+ );
+ if ( Fv == FlashAddress && Size >= EFI_FIELD_OFFSET(EFI_FIRMWARE_VOLUME_HEADER, Attributes))
+ {
+ ((EFI_FIRMWARE_VOLUME_HEADER*)DataBuffer)->Signature = FV_SIGNATURE;
+ return;
+ }
+ }
+}
+
+// Protocl Functions Implementation
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverRead
+//
+// Description: Implementation of the Read Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash
+// UINTN Size Size to write
+// VOID* DataBuffer Poiner to the Data Buffer to write
+//
+// Output: NON
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS EFIAPI FlashDriverRead(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+)
+{
+ BOOLEAN Status;
+
+ if (FlashData.MailBox->WriteEnableStatus!=0)
+ {
+ Status = FlashRead(FlashAddress, DataBuffer, (UINT32)Size);
+ }
+ else
+ {
+ UINTN i;
+
+ for (i=0; i<Size; i++)
+ ((UINT8*)DataBuffer)[i] = ((UINT8*)FlashAddress)[i];
+
+ Status = TRUE;
+ }
+ return (Status) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+#define INT_SIZE sizeof(INTN)
+#define FLASH_EMPTY_BYTE ((UINT8)FlashEmpty)
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: IsClean
+//
+// Description: Function to loops through the buffer and check if it's empty
+//
+// Input:
+// IN UINT8* Address Pointer to address to check
+// IN UINTN Size Size of data to check
+//
+// Output: TRUE or FALSE
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+BOOLEAN IsClean(IN UINT8 *Address, IN UINTN Size)
+{
+ // loops through the buffer and check if it's empty
+ if (!( (UINTN)Address & (INT_SIZE-1) ))
+ {
+ for ( ; Size >= INT_SIZE; Size -= INT_SIZE, Address += INT_SIZE)
+ {
+ if (FlashNotMemoryMapped)
+ {
+ UINTN nData=0;
+ FlashDriverRead (Address, INT_SIZE, &(UINT8)nData );
+ if (nData != FlashEmpty) return FALSE;
+ }
+ else
+ if (*(UINTN*)Address != FlashEmpty) return FALSE;
+ }
+
+ }
+
+ // the address may not be INT_SIZE aligned
+ // check the remaining part of the buffer
+ for ( ; Size > 0; Size--, Address++)
+ {
+ if (FlashNotMemoryMapped)
+ {
+ UINT8 nData=0;
+ FlashDriverRead (Address, 1, &nData );
+ if (nData != FLASH_EMPTY_BYTE) return FALSE;
+ }
+ else
+ if (*Address != FLASH_EMPTY_BYTE) return FALSE;
+
+ }
+
+ return TRUE;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverErase
+//
+// Description: Implementation of the Erase Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash to erase
+// UINTN Size Size to erase
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR depending on result
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS EFIAPI FlashDriverErase(VOID* FlashAddress, UINTN Size)
+{
+ BOOLEAN Status = TRUE;
+ UINT8 *Address = (UINT8*)FlashAddress;
+
+ //---Enable write---------------------------------------------
+ FlashDriverDeviceWriteEnable();
+
+ for (; Status && Size>0; Address+=FlashBlockSize, Size-=FlashBlockSize)
+ {
+ //--- If block clean already - continue to next-----------
+ if (IsClean(Address, FlashBlockSize)) continue;
+ //---If not - Erase block---------------------------------
+ FlashBlockWriteEnable(Address);
+ Status=FlashEraseBlock(Address);
+ FlashBlockWriteDisable(Address);
+ }
+ //---Disable Write-------------------------------------------
+ FlashDriverDeviceWriteDisable();
+ return (Status) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverWrite
+//
+// Description: Implementation of the Write Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash to write to
+// UINTN Size Size to write
+// VOID* DataBuffer - pointer to data to write to the flash part
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR depending on result
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS EFIAPI FlashDriverWrite(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+)
+{
+ BOOLEAN Status = TRUE;
+ UINT8 *Address = (UINT8*)FlashAddress;
+ UINT8 *Data = (UINT8*)DataBuffer;
+ UINT8 *BlockAddress = (UINT8*)BLOCK(Address); //Align to the block size
+ UINTN PartialSize;
+
+ FlashDriverDeviceWriteEnable();
+ //---If FlashAddress was not the begining of flash----------------
+ if (BlockAddress!=Address)
+ {
+ PartialSize = FlashBlockSize - (Address - BlockAddress);
+
+ if (PartialSize > Size) PartialSize = Size;
+ //---Write data and update address----------------------------
+ FlashBlockWriteEnable(BlockAddress);
+ Status=FlashProgram(Address, Data, (UINT32)PartialSize);
+ FlashBlockWriteDisable(BlockAddress);
+ Address = BlockAddress + FlashBlockSize;
+ Size -= PartialSize;
+ Data += PartialSize;
+ }
+ //---Else Write data and update address----------------------------
+ for (; Status && Size>=FlashBlockSize
+ ; Address+=FlashBlockSize, Size-=FlashBlockSize, Data+=FlashBlockSize
+ )
+ {
+ FlashBlockWriteEnable(Address);
+ Status=FlashProgram(Address, Data, FlashBlockSize);
+ FlashBlockWriteDisable(Address);
+ }
+ //--- If last chunk < FlashBlockSize-------------------------------
+ if (Size!=0 && Status)
+ {
+ FlashBlockWriteEnable(Address);
+ Status=FlashProgram(Address, Data, (UINT32)Size);
+ FlashBlockWriteDisable(Address);
+ }
+
+ FlashDriverDeviceWriteDisable();
+ return (Status) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverUpdate
+//
+// Description: Implementation of the Update Function of the Flash protocol
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash to update (must be aligned to FlashBlockSize)
+// UINTN Size Size to update (must be multiple of FlashBlockSize)
+// VOID* DataBuffer - pointer to data to write to the flash part
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR depending on result
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS EFIAPI FlashDriverUpdate(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+)
+{
+ BOOLEAN Status = TRUE;
+ UINT8 *Address = (UINT8*)FlashAddress;
+ UINT8 *Data = (UINT8*)DataBuffer;
+
+ FlashDriverDeviceWriteEnable();
+
+ for (; Status && Size>=FlashBlockSize
+ ; Address+=FlashBlockSize, Size-=FlashBlockSize, Data+=FlashBlockSize
+ )
+ {
+ //---Writes a block checking is flash block clean or equal-----------
+ Status = FlashWriteBlock(Address, Data);
+ }
+
+ FlashDriverDeviceWriteDisable();
+ return (Status) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverDeviceWriteEnable
+//
+// Description: Enables writes to flash device
+//
+// Input: NON
+//
+//
+// Output: EFI_SUCCESS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS EFIAPI FlashDriverDeviceWriteEnable()
+{
+ FlashData.MailBox->WriteEnableStatus++;
+
+ if (FlashData.MailBox->WriteEnableStatus==1)
+ {
+ FlashDeviceWriteEnable();
+ }
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: FlashDriverDeviceWriteDisable
+//
+// Description: Disables writes to flash device
+//
+// Input: NON
+//
+//
+// Output: EFI_SUCCESS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS EFIAPI FlashDriverDeviceWriteDisable()
+{
+ if (FlashData.MailBox->WriteEnableStatus!=0)
+ {
+ FlashData.MailBox->WriteEnableStatus--;
+
+ if (FlashData.MailBox->WriteEnableStatus==0)
+ {
+ FlashDeviceWriteDisable();
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS EFIAPI FlashDriverReadExt(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+){
+ EFI_STATUS Status;
+ BEGIN_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ Status = FlashDriverRead(FlashAddress,Size,DataBuffer);
+ AfterRead(FlashAddress, Size, DataBuffer);
+ END_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ return Status;
+}
+
+EFI_STATUS EFIAPI FlashDriverEraseExt(
+ VOID* FlashAddress, UINTN Size
+){
+ EFI_STATUS Status;
+
+ if (Size==0) return EFI_SUCCESS;
+ //---If Addres in not alligned properly or Size is not multiple to FlashBlockSize
+ //---Abort----------------------------------
+ if ((UINT8*)BLOCK(FlashAddress)!=FlashAddress || Size%FlashBlockSize!=0)
+ return EFI_UNSUPPORTED;
+
+ BEGIN_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ //---Invalidate FV by destroying the signature----------------
+ BeforeErase(FlashAddress);
+ Status = FlashDriverErase(FlashAddress, Size);
+ END_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ return Status;
+}
+
+EFI_STATUS EFIAPI FlashDriverWriteExt(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+){
+ EFI_STATUS Status;
+ if (Size==0) return EFI_SUCCESS;
+
+ BEGIN_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ //---Invalidate FV by destroying the signature--------------------
+ BeforeWrite(FlashAddress, Size, DataBuffer);
+ Status = FlashDriverWrite(FlashAddress,Size,DataBuffer);
+ //---Restore FV signature-------------------------------------------
+ AfterWrite(FlashAddress, Size, DataBuffer);
+ END_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ return Status;
+}
+
+EFI_STATUS EFIAPI FlashDriverUpdateExt(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+){
+ EFI_STATUS Status;
+
+ if (Size==0) return EFI_SUCCESS;
+
+ if ((UINT8*)BLOCK(FlashAddress)!=FlashAddress || Size%FlashBlockSize!=0)
+ return EFI_UNSUPPORTED;
+
+ BEGIN_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ BeforeErase(FlashAddress);
+ BeforeWrite(FlashAddress, Size, DataBuffer);
+ Status = FlashDriverUpdate(FlashAddress,Size,DataBuffer);
+ AfterWrite(FlashAddress, Size, DataBuffer);
+ END_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ return Status;
+}
+
+EFI_STATUS EFIAPI FlashDriverDeviceWriteEnableExt(){
+ EFI_STATUS Status;
+ BEGIN_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ Status = FlashDriverDeviceWriteEnable();
+ END_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ return Status;
+}
+
+EFI_STATUS EFIAPI FlashDriverDeviceWriteDisableExt(){
+ EFI_STATUS Status;
+ UINT32 OldWriteEnableStatus;
+
+ BEGIN_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ OldWriteEnableStatus = FlashData.MailBox->WriteEnableStatus;
+ Status = FlashDriverDeviceWriteDisable();
+ if (OldWriteEnableStatus!=0 && FlashData.MailBox->WriteEnableStatus==0)
+ {
+ // Before disabling the flash wtrites
+ // restore the destroyed FV signatures (if any).
+ // In case of full FV update, the FV signature is restored
+ // in the AfterWrite function once the last FV block is updated.
+ // In case of partial FV update when last FV block is not updated,
+ // the FV Signature is restored either here or in the BeforeRead function.
+ INT32 i;
+ for (i=0; i<NumberOfUpdatedAreas; i++)
+ {
+ if (UpdatedArea[i].RestoreSignature){
+ EFI_FIRMWARE_VOLUME_HEADER* Fv
+ = (EFI_FIRMWARE_VOLUME_HEADER*)(
+ UpdatedArea[i].RomArea->Address+FlashDeviceBase
+ );
+ UINT32 FvSignature = FV_SIGNATURE;
+ //Restore FV signature
+ FlashDriverWrite(
+ &Fv->Signature, sizeof(UINT32), &FvSignature
+ );
+ }
+ }
+ NumberOfUpdatedAreas = 0;
+ FlashDeviceWriteDisable();
+ }
+
+ END_CRITICAL_SECTION(&FlashData.MailBox->Cs);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FlashDriverEntry
+//
+// Description: This function is the entry point for this module. This function
+// installs Flash protocols before and after SMM.
+//
+// Input: ImageHandle Image handle
+// SystemTable Pointer to the system table
+//
+// Output: Return Status based on errors that occurred while waiting for
+// time to expire.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FlashDriverEntry(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle,SystemTable);
+ return InitSmmHandlerEx(
+ ImageHandle, SystemTable, FlashDriverSmmInit, FlashDriverInit
+ );
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Runtime/Runtime.c b/Core/EM/Runtime/Runtime.c
new file mode 100644
index 0000000..cebe355
--- /dev/null
+++ b/Core/EM/Runtime/Runtime.c
@@ -0,0 +1,579 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Runtime/Runtime.c 23 6/16/11 9:07a Felixp $
+//
+// $Revision: 23 $
+//
+// $Date: 6/16/11 9:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Runtime/Runtime.c $
+//
+// 23 6/16/11 9:07a Felixp
+// Enhancements(EIP 49676):
+// 1. FindDescriptor: upated to ignore boot time memory map descriptors
+// 2. SetVirtualAddressMap: updated to skip virtual address change
+// callbacks that reside in the boot time memory.
+//
+// 22 9/22/10 6:57p Felixp
+// Minor improvements: use InitAmiRuntimeLib instead of InitAmiLib
+//
+// 21 3/12/10 12:00p Felixp
+//
+// 20 3/12/10 10:26a Felixp
+// Bug fix: Potential problems with UEFI OS.
+// pST was used here even after it has been virtualized in the
+// AmiLibGoVirtual.
+// The local copy of the pointer is created.
+//
+// 19 7/08/09 12:00p Felixp
+//
+// 18 6/24/09 4:23p Robert
+// updated comments, copyright and some coding standard items
+//
+// 17 5/14/09 9:34a Felixp
+// New feature: SMM version of Runtime Services
+// Runtime driver is updated to install SMM version of the runtime
+// services table.
+//
+// 15 11/20/08 2:58p Felixp
+// Bug fix in SetVirtualAddressMap( bug fix in the runtime images fixup
+// logic )
+//
+// 14 11/07/07 11:54a Felixp
+// Bug fix in FindDescriptor routine
+//
+// 13 8/07/07 2:23p Felixp
+// New StatusCodes added
+//
+// 7 10/27/06 10:31a Felixp
+// checkpoints on begin/end of SetVirtualAddressMap added
+//
+// 6 10/27/06 10:15a Felixp
+// Bug fixes in SetVirtualAddressMap
+//
+// 5 10/07/06 10:22a Felixp
+// New Runtime protocol defined by DXE CIS 0.91 implemented
+// (Old(DXE CIS 0.90) Runtime protocol and AMI Runtime protocols removed).
+//
+// 3 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 14 12/23/04 9:29a Felixp
+// ArchProtocols moved to Include\Protocols
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Runtime.c
+//
+// Description:
+// This file contains the Runtime Architectural Protocol along with
+// some runtime functions that are included in the Runtime Services Table
+// SetVirtualAddressMap, ConvertPointer, and CalculateCrc32. The entry
+// point for the Runtime Driver also contains a call to InitParts which
+// uses the RuntimeInitialize and RuntimeSmmInitialize eLinks to
+// initialize other pieces of the Runtime Structure
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//=============================================================================
+// Includes
+#include <Protocol/Runtime.h>
+#include <Protocol/LoadedImage.h>
+#include <AmiDxeLib.h>
+
+//=============================================================================
+// Protocol Definition
+EFI_RUNTIME_ARCH_PROTOCOL Runtime =
+{
+ {&Runtime.ImageHead,&Runtime.ImageHead}, //EFI_LIST_ENTRY ImageHead;
+ {&Runtime.EventHead,&Runtime.EventHead}, //EFI_LIST_ENTRY EventHead;
+ 0, //UINTN MemoryDescriptorSize;
+ 0, //UINT32 MemoryDesciptorVersion;
+ 0, //UINTN MemoryMapSize;
+ NULL, //EFI_MEMORY_DESCRIPTOR *MemoryMapPhysical;
+ NULL, //EFI_MEMORY_DESCRIPTOR *MemoryMapVirtual;
+ FALSE, //BOOLEAN VirtualMode;
+ FALSE //BOOLEAN AtRuntime;
+} ;
+
+
+//=============================================================================
+// Module specific Global Variables
+
+static EFI_MEMORY_DESCRIPTOR *pMap = NULL;
+static UINTN MapSize, DescSize;
+static UINT32 CrcTable[256];
+
+//=============================================================================
+// Function Prototypes
+
+//this funciton is created from InitList.c template file during build process
+VOID InitParts(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
+
+
+EFI_STATUS SetVirtualAddressMap(
+ IN UINTN MemoryMapSize, IN UINTN DescriptorSize,
+ IN UINT32 DescriptorVersion, IN EFI_MEMORY_DESCRIPTOR *VirtualMap
+);
+
+EFI_STATUS ConvertPointer(
+ IN UINTN DebugDisposition, IN VOID **Address
+);
+
+EFI_STATUS CalculateCrc32(
+ IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32
+);
+
+VOID InitCrc();
+
+//=============================================================================
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RuntimeInitialize
+//
+// Description:
+// This function is the Initialization function for the runtime driver that is
+// outside of SMM. It sets up all the pieces of the Runtime Architectural
+// Protocol that exist outside of SMM
+//
+// Input:
+// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver
+// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RuntimeInitialize(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle = NULL;
+
+ InitAmiRuntimeLib(ImageHandle, SystemTable, NULL, NULL);
+ InitCrc();
+
+ //this funciton is created from InitList.c template file during build process
+ InitParts(ImageHandle, SystemTable);
+
+ // Initialize pointers in the Runtime Services Table
+ pRS->SetVirtualAddressMap = SetVirtualAddressMap;
+ pRS->ConvertPointer = ConvertPointer;
+ pBS->CalculateCrc32 = CalculateCrc32;
+
+ // install the Runtime Achitectural Protocol
+ pBS->InstallMultipleProtocolInterfaces(
+ &Handle, &gEfiRuntimeArchProtocolGuid, &Runtime, NULL
+ );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindDescriptor
+//
+// Description:
+// This function finds the memory descriptor that contains the pointer that
+// is passed into the function. This is used by the ConvertPointer function
+// to determine how to find the virtual fixup address of the pointer
+//
+// Input:
+// VOID *p - Pointer that needs to be fixed up
+//
+// Output:
+// EFI_MEMORY_DESCRIPTOR * - Memory descriptor that contain the pointer that is passed in
+//
+// Notes:
+// Used only by ConvertPointer function to help it convert the pointer from
+// a physical address to a virtual address
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_MEMORY_DESCRIPTOR* FindDescriptor(VOID *p)
+{
+ EFI_MEMORY_DESCRIPTOR *pD;
+ EFI_PHYSICAL_ADDRESS Address = (EFI_PHYSICAL_ADDRESS)(UINTN)p;
+
+ if(!pMap) return NULL;
+ // Search for the memory descriptor that contains the address of the pointer
+ // that was passed in
+ for(pD = pMap
+ ;pD < (EFI_MEMORY_DESCRIPTOR*)((UINT8*)pMap + MapSize)
+ ;pD = (EFI_MEMORY_DESCRIPTOR*)((UINT8*)pD + DescSize)
+ ) if ( (pD->Attribute & EFI_MEMORY_RUNTIME)
+ && pD->PhysicalStart <= Address
+ && pD->PhysicalStart + Shl64(pD->NumberOfPages, EFI_PAGE_SHIFT)
+ > Address
+ ) return pD;
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetVirtualAddressMap
+//
+// Description:
+// This function is called by a UEFI OS. It changes the pointers for the
+// Runtime Services Table and each of the function pointers and variables
+// that are its elements from physical addresses to virtual addresses.
+//
+// Input:
+// IN UINTN MemoryMapSize - Size of the Current Memory Map
+// IN UINTN DescriptorSize - Size of one descriptor in the Memory Map
+// IN UINT32 DescriptorVersion - Version of the MemoryDescriptor Data Structure
+// IN EFI_MEMORY_DESCRIPTOR *VirtualMap - Address to the first Descriptor in the Virtual Memory Map
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetVirtualAddressMap(
+ IN UINTN MemoryMapSize,
+ IN UINTN DescriptorSize,
+ IN UINT32 DescriptorVersion,
+ IN EFI_MEMORY_DESCRIPTOR *VirtualMap
+)
+{
+ EFI_LIST_ENTRY *pLink;
+ VOID **p;
+ UINTN i;
+ UINT32 crc;
+ EFI_RUNTIME_IMAGE_ENTRY *pThisImageEntry;
+ VOID *VirtualImageBase;
+
+ //Make a local copy of pRS or pST
+ //it case one of the runtime drivers linked with this module
+ //converts pRS or pST to virtual address in the event handler
+ EFI_SYSTEM_TABLE *pSTCopy = pST;
+ EFI_RUNTIME_SERVICES *pRSCopy = pRS;
+
+ //SetVirtualAddressMap can only be called once
+ if(pMap) return EFI_UNSUPPORTED;
+ checkpoint(0xB0);
+
+ //Initialize Global Variables
+ pMap = VirtualMap;
+ MapSize = MemoryMapSize;
+ DescSize = DescriptorSize;
+
+ //Call Event notification funcitons
+ for(pLink = Runtime.EventHead.ForwardLink; pLink != &Runtime.EventHead; pLink = pLink->ForwardLink)
+ {
+ EFI_RUNTIME_EVENT_ENTRY *pEvent = OUTTER(pLink, Link, EFI_RUNTIME_EVENT_ENTRY);
+ if (!pEvent->NotifyFunction) continue;
+ //Let's see if the notification function we about to call is a runtime function
+ if (!FindDescriptor(pEvent->NotifyFunction)){
+ TRACE((TRACE_DXE_CORE,"ERROR: Virtual address change callback at address %X resides in the boot time memory\n",pEvent->NotifyFunction));
+ ASSERT(FALSE);
+ continue;
+ }
+ ASSERT(!pEvent->NotifyContext || FindDescriptor(pEvent->NotifyFunction));
+ pEvent->NotifyFunction(*pEvent->Event, pEvent->NotifyContext);
+ }
+
+ //Fixup runtime images
+ for(pLink = Runtime.ImageHead.ForwardLink; pLink != &Runtime.ImageHead; pLink = pLink->ForwardLink)
+ {
+ EFI_RUNTIME_IMAGE_ENTRY *pImage = OUTTER(pLink, Link, EFI_RUNTIME_IMAGE_ENTRY);
+ //skip this image; it will be fixed up later
+ if (TheImageHandle == pImage->Handle){
+ pThisImageEntry = pImage;
+ continue;
+ }
+ VirtualImageBase = pImage->ImageBase;
+ ConvertPointer(0, &VirtualImageBase);
+ ReallocatePeImage(pImage->ImageBase, VirtualImageBase, pImage->RelocationData);
+ }
+ //Fixup RuntimeServices
+ for(p = (VOID**)((UINT8*)pRSCopy + sizeof(pRSCopy->Hdr)); p < (VOID**)(pRSCopy + 1); p++)
+ ConvertPointer(0, p);
+ //Fixup Configuration Table
+ for(i = 0; i < pSTCopy->NumberOfTableEntries; i++)
+ ConvertPointer(0, &pSTCopy->ConfigurationTable[i].VendorTable);
+ //Fixup SystemTable
+ ConvertPointer(0, &pSTCopy->ConfigurationTable);
+ ConvertPointer(0, &pSTCopy->RuntimeServices);
+ ConvertPointer(0, &pSTCopy->FirmwareVendor);
+ // Update CRC32 of the System Tables
+ pRSCopy->Hdr.CRC32 = 0; crc = 0;
+ CalculateCrc32(pRSCopy, sizeof(*pRSCopy), &crc);
+ pRSCopy->Hdr.CRC32 = crc;
+ pSTCopy->Hdr.CRC32 = 0; crc = 0;
+ CalculateCrc32(pSTCopy, sizeof(*pSTCopy), &crc);
+ pSTCopy->Hdr.CRC32 = crc;
+
+ //finally, fixup ourself
+ VirtualImageBase = pThisImageEntry->ImageBase;
+ ConvertPointer(0, &VirtualImageBase);
+ ReallocatePeImage(pThisImageEntry->ImageBase, VirtualImageBase, pThisImageEntry->RelocationData);
+
+ checkpoint(0xB1);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConvertPointer
+//
+// Description:
+// This function converts pointers from a Physical Memory Map Pointer
+// to a Virtual Memory Map Pointer. Called during the SetVirtualAddressMap
+// function execution.
+//
+// Input:
+// IN UINTN DebugDisposition - If set as EFI_OPTIONAL_POINTER, then Address is allowed to be NULL
+// IN VOID **Address - Pointer to convert to a virtual address
+//
+// Output:
+// EFI_SUCCESS - Pointer converted to Virtual Address
+// EFI_INVALID_PARAMETER - DebugDisposition != EFI_OPTIONAL_POINTER and *Address == NULL
+// EFI_INVALID_PARAMETER - Address == NULL
+// EFI_UNSUPPORTED - Virtual Memory Map address has not be set
+// EFI_NOT_FOUND - Descriptor not found that contains the address of *Address
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConvertPointer(
+ IN UINTN DebugDisposition,
+ IN VOID **Address
+)
+{
+ EFI_MEMORY_DESCRIPTOR *pD;
+
+ // Check for error conditions
+ if(!pMap) return EFI_UNSUPPORTED;
+ if (!Address) return EFI_INVALID_PARAMETER;
+ if (!*Address)
+ return (DebugDisposition == EFI_OPTIONAL_PTR) ? EFI_SUCCESS : EFI_INVALID_PARAMETER;
+
+ // find the descriptor that contains the address passed in If not found, return error
+ if (!(pD = FindDescriptor(*Address))) return EFI_NOT_FOUND;
+
+ // if the descriptor is found, fixup the address to the new virtual address
+ *Address = (VOID*)((EFI_PHYSICAL_ADDRESS)*Address - pD->PhysicalStart + pD->VirtualStart);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitCrc
+//
+// Description:
+// This function Initializes the CrcTable with lookup values for future
+// use durning CRC32 calculations
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+// Notes:
+// At the end of this function the CrcTable will be initialized with lookup
+// values that make calculating CRC32 values much easier
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitCrc( VOID )
+{
+ UINT32 i;
+ UINT32 j;
+
+ for(i = 0; i < 256; i++)
+ {
+ CrcTable[i] = i;
+ for(j = 8; j > 0; j--)
+ CrcTable[i] = (CrcTable[i] & 1)
+ ? (CrcTable[i] >> 1)^0xedb88320
+ : CrcTable[i] >> 1;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CalculateCrc32
+//
+// Description:
+// This function Calculates a CRC32 value using the Data Buffer that is
+// and the DataSize passed in
+//
+// Input:
+// IN VOID *Data - Pointer to the data to have the CRC function run on
+// IN UINTN DataSize - Size in bytes of the Data pointed to by *Data
+//
+// Output:
+// OUT UINT32 *Crc32 - CRC32 value calculated based on Data and Data Size
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CalculateCrc32(
+ IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32
+)
+{
+ UINT32 i, crc = (UINT32)-1;
+ if (!Data || !DataSize || !Crc32) return EFI_INVALID_PARAMETER;
+ for(i = 0; i < DataSize; i++) crc = (crc >> 8)^CrcTable[(UINT8)crc^((UINT8*)Data)[i]];
+ *Crc32 = ~crc;
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+// RT SMM BEGIN
+//**********************************************************************
+//======================================================================
+// SMM externs
+extern EFI_GUID SmmRsTableGuid;
+
+//======================================================================
+// SMM Function Prototypes
+
+//this funciton is created from InitList.c template file during build process
+VOID InitParts2(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
+
+
+//======================================================================
+// SMM Function Definitions
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DummySmmRtFunction
+//
+// Description:
+// This function is a Dummy function that is used as a default function
+// for the SMM instance of the Runtime Services Table
+//
+// Input:
+// None
+//
+// Output:
+// EFI_UNSUPPORTED
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DummySmmRtFunction(){ return EFI_UNSUPPORTED; }
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RuntimeSmmInitialize
+//
+// Description:
+// This function initializes the SMM version of the Runtime Services Table
+//
+// Input:
+// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver
+// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable
+//
+// Output:
+// EFI_STATUS - based on the return values of the SmmInstallConfigurationTable function
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RuntimeSmmInitialize(
+ EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_RUNTIME_SERVICES SmmRs;
+ EFI_STATUS Status;
+ VOID **p;
+
+ //copy header
+ SmmRs.Hdr = pRS->Hdr;
+ //Init Runtime Services function pointers with our dummy function
+ for(p = (VOID**)((UINT8*)&SmmRs + sizeof(SmmRs.Hdr)); p < (VOID**)(&SmmRs + 1); p++)
+ *p = DummySmmRtFunction;
+
+ // install the SMM version of the Runtime Services Table SMM Configuration Table
+ Status = pSmst->SmmInstallConfigurationTable(
+ pSmst, &SmmRsTableGuid, &SmmRs, sizeof(EFI_RUNTIME_SERVICES) );
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RuntimeEntry
+//
+// Description:
+// This function is the entry point for the Runtime Driver. It initializes
+// the AMI Library and then it calls the Initialization functions for both
+// the SMM and NON-SMM versions of the Runtime Driver. It then calls the
+// InitParts2 function which calls the functions in the RuntimeSmmInitialize
+// eLink.
+//
+// Input:
+// EFI_HANDLE ImageHandle - The firmware allocated handle for this driver
+// EFI_SYSTEM_TABLE *SystemTable - Pointer to the UEFI SystemTable
+//
+// Output:
+// EFI_STATUS - based on the return values of the InitSmmHandlerEx function
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RuntimeEntry (
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ // Initialize the AMI Library for this module
+ InitAmiLib(ImageHandle, SystemTable);
+
+ // Initialize both the SMM and Non-SMM verions of the Runtime Services
+ Status = InitSmmHandlerEx(
+ ImageHandle, SystemTable, RuntimeSmmInitialize, RuntimeInitialize
+ );
+ InitParts2(ImageHandle, SystemTable);
+ return Status;
+}
+//**********************************************************************
+// RT SMM END
+//**********************************************************************
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Runtime/Runtime.cif b/Core/EM/Runtime/Runtime.cif
new file mode 100644
index 0000000..d70f08f
--- /dev/null
+++ b/Core/EM/Runtime/Runtime.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "Runtime"
+ category = ModulePart
+ LocalRoot = "Core\EM\Runtime\"
+ RefName = "Runtime"
+[files]
+"Runtime.sdl"
+"Runtime.mak"
+"Runtime.dxs"
+<endComponent>
diff --git a/Core/EM/Runtime/Runtime.dxs b/Core/EM/Runtime/Runtime.dxs
new file mode 100644
index 0000000..7e0cd64
--- /dev/null
+++ b/Core/EM/Runtime/Runtime.dxs
@@ -0,0 +1,49 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2004, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: $
+//
+// $Revision: $
+//
+// $Date: $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: $
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Runtime.dxs
+//
+// Description: Dependancy expression for the Runtime component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2004, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Runtime/Runtime.mak b/Core/EM/Runtime/Runtime.mak
new file mode 100644
index 0000000..6016f77
--- /dev/null
+++ b/Core/EM/Runtime/Runtime.mak
@@ -0,0 +1,102 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Runtime/Runtime.mak 8 6/24/09 4:28p Robert $
+#
+# $Revision: 8 $
+#
+# $Date: 6/24/09 4:28p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Runtime/Runtime.mak $
+#
+# 8 6/24/09 4:28p Robert
+# updated file description
+#
+# 7 5/14/09 9:38a Felixp
+# New feature: SMM version of Runtime Services
+# Runtime driver is updated to install SMM version of the runtime
+# services table.
+# NVRAM driver is updated to populate SMM runtime table
+# with the pointers to SMM version of variable services.
+#
+# 6 5/01/09 6:11p Felixp
+# Bug fix(EIP 19816). $(AMICSPLib) is linked with Runtime module
+# (Used to be linked with NVRAM library that caused problems on systems
+# without Core Sources).
+#
+# 5 8/24/06 9:17a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 4 12/02/05 11:16a Felixp
+# @set INCLUDE=%%INCLUDE%% removed since it's not needed.
+#
+# 3 6/16/05 10:48a Felixp
+# NVRAMTokens.c replaced with Tokens.c
+#
+# 2 2/11/05 5:48p Felixp
+# Binary files organization improved:
+# - extra layer of sub-component removed
+# - macros initialization moved to SDL tokens to eliminate undefined
+# macros situation
+# - debug and release binaries have different names now (workaround for
+# VeB limitation)
+# - binaries reside in the component home directory (eliminates
+# hardcoded paths)
+#
+# 3 1/18/05 3:22p Felixp
+# PrintDebugMessage renamed to Trace
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Runtime.mak
+#
+# Description:
+# This file contains the build commands for the Runtime binary
+# components.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : RUNTIME
+
+RUNTIME : CORE_PEI $(BUILD_DIR)\RUNTIME.mak RUNTIMEBin
+
+$(BUILD_DIR)\RUNTIME.mak : $(RUNTIME_DIR)\$(@B).cif $(RUNTIME_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(RUNTIME_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+RUNTIMEBin : $(AMIDXELIB) $(Runtime_LIB) $(FLASHLIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\RUNTIME.mak all\
+ GUID=CBC59C4A-383A-41eb-A8EE-4498AEA567E4 \
+ ENTRY_POINT=RuntimeEntry \
+ TYPE=RT_DRIVER LIBRARIES= \
+ COMPRESS=1\
+ "INIT_LIST=$(RuntimeInitialize)"\
+ "INIT_LIST2=$(RuntimeSmmInitialize)"
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Runtime/Runtime.sdl b/Core/EM/Runtime/Runtime.sdl
new file mode 100644
index 0000000..93f01d1
--- /dev/null
+++ b/Core/EM/Runtime/Runtime.sdl
@@ -0,0 +1,129 @@
+TOKEN
+ Name = "Runtime_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Runtime support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "RTC_RUNTIME_SERVICES_SUPPORT"
+ Value = "1"
+ Help = "If ON includes in project CORE implementation of RTC \services (from TimeAndReset.c). \Set to OFF to use stand alone RTC driver."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RESET_RUNTIME_SERVICES_SUPPORT"
+ Value = "1"
+ Help = "If ON includes in project CORE implementation of reset \services (from TimeAndReset.c). \Set to OFF to use stand alone reset driver."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NVRAM_MONOTONIC_COUNTER_SUPPORT"
+ Value = "1"
+ Help = "If ON includes in project CORE NVRAM-based implementation of \the monotonic counter services.\Set to OFF to use stand alone monotonic counter driver."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NVRAM_RECORD_CHECKSUM_SUPPORT"
+ Value = "0"
+ Help = "When this token is enabled, every NVRAM record is checksummed."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NVRAM_RT_GARBAGE_COLLECTION_SUPPORT"
+ Value = "1"
+ Help = "This token enables/disables support of the NVRAM garbage collection at runtime."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NO_MMIO_FLASH_ACCESS_DURING_UPDATE"
+ Value = "0"
+ Help = "This token should be set to 1 if flash part is not memory mapped while write enabled."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "RUNTIME_DIR"
+End
+
+MODULE
+ Help = "Includes Runtime.mak to Project"
+ File = "Runtime.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Runtime.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RuntimeInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "Runtime_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(RUNTIME_DIR)\Runtime$(ARCH).lib"
+ Parent = "Runtime_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CpuIoDxeInit,"
+ Parent = "RuntimeInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RuntimeSmmInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "FlashDriverEntry,"
+ Parent = "RuntimeSmmInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TimeServInit,"
+ Parent = "RuntimeSmmInitialize"
+ Token = "RTC_RUNTIME_SERVICES_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ResetServInit,"
+ Parent = "RuntimeSmmInitialize"
+ Token = "RESET_RUNTIME_SERVICES_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "NvRamSmmEntry,"
+ Parent = "FlashDriverEntry,"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/Runtime/RuntimeSrc.cif b/Core/EM/Runtime/RuntimeSrc.cif
new file mode 100644
index 0000000..020e79a
--- /dev/null
+++ b/Core/EM/Runtime/RuntimeSrc.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "Runtime Sources"
+ category = ModulePart
+ LocalRoot = "Core\em\Runtime\"
+ RefName = "RuntimeSrc"
+[files]
+"RuntimeSrc.sdl"
+"RuntimeSrc.mak"
+"Runtime.c"
+"CpuIoDxe.c"
+"Flash.c"
+"TimeAndReset.C"
+<endComponent>
diff --git a/Core/EM/Runtime/RuntimeSrc.mak b/Core/EM/Runtime/RuntimeSrc.mak
new file mode 100644
index 0000000..1ee91a0
--- /dev/null
+++ b/Core/EM/Runtime/RuntimeSrc.mak
@@ -0,0 +1,74 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/Runtime/RuntimeSrc.mak 5 6/24/09 4:22p Robert $
+#
+# $Revision: 5 $
+#
+# $Date: 6/24/09 4:22p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/Runtime/RuntimeSrc.mak $
+#
+# 5 6/24/09 4:22p Robert
+# Updated copyright and file description
+#
+# 4 8/24/06 9:28a Felixp
+# NVRAM removed (separate NVRAM component is created)
+#
+# 3 12/02/05 11:20a Felixp
+#
+# 2 8/23/05 12:02p Felixp
+# dependency from Token.h in debug mode added
+#
+# 1 1/28/05 12:45p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: RuntimeSrc.mak
+#
+# Description:
+# This file contains the build commands to create the Runtime Library
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Runtime_LIB
+
+$(Runtime_LIB) : Runtime_LIB
+
+Runtime_LIB : $(BUILD_DIR)\RuntimeSrc.mak Runtime_LIBBin
+
+$(BUILD_DIR)\RuntimeSrc.mak : $(RUNTIME_DIR)\$(@B).cif $(RUNTIME_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(RUNTIME_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+Runtime_LIBBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\RuntimeSrc.mak all\
+ TYPE=LIBRARY LIBRARY_NAME=$(Runtime_LIB)
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Runtime/RuntimeSrc.sdl b/Core/EM/Runtime/RuntimeSrc.sdl
new file mode 100644
index 0000000..546f756
--- /dev/null
+++ b/Core/EM/Runtime/RuntimeSrc.sdl
@@ -0,0 +1,57 @@
+TOKEN
+ Name = "RuntimeSrc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable RuntimeSrc support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "MINIMUM_YEAR"
+ Value = "1998"
+ Help = "Minimum allowed year.\If RTC year is less than this value, date will be reset to defaults."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "1998"
+End
+
+TOKEN
+ Name = "DEFAULT_YEAR"
+ Value = "2009"
+ Help = "Default year. RTC will be reset to this value if current date is invalid."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "MINIMUM_YEAR - 2099"
+End
+
+TOKEN
+ Name = "DEFAULT_MONTH"
+ Value = "1"
+ Help = "Default month. RTC will be reset to this value if current date is invalid."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "1-12"
+End
+
+TOKEN
+ Name = "DEFAULT_DAY"
+ Value = "1"
+ Help = "Default day. RTC will be reset to this value if current date is invalid."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "1-31"
+End
+
+MODULE
+ Help = "Includes RuntimeSrc.mak to Project"
+ File = "RuntimeSrc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Runtime.lib"
+ Parent = "$(RUNTIME_DIR)\Runtime$(ARCH).lib"
+ InvokeOrder = ReplaceParent
+End
+
diff --git a/Core/EM/Runtime/TimeAndReset.C b/Core/EM/Runtime/TimeAndReset.C
new file mode 100644
index 0000000..5e7ec77
--- /dev/null
+++ b/Core/EM/Runtime/TimeAndReset.C
@@ -0,0 +1,1191 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/Runtime/TimeAndReset.C 10 11/17/10 4:44p Felixp $
+//
+// $Revision: 10 $
+//
+// $Date: 11/17/10 4:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/Runtime/TimeAndReset.C $
+//
+// 10 11/17/10 4:44p Felixp
+// Support for reset type override is added.
+//
+// 9 9/07/10 11:07p Felixp
+//
+// 8 9/02/10 4:49p Felixp
+// Enhancement: RTC driver is updated to use InitAmiRuntimeLib function.
+// The is safer that direct use of pRS->ConvertPointer since by the time
+// driver's
+// virtual address change callback is invoked, pRS may have already been
+// virtualized.
+//
+// 7 2/01/10 11:55a Felixp
+// Bug fix in EfiSetTime function. The timer zone variable was created
+// with the wrong size.
+//
+// 6 7/10/09 8:14a Felixp
+//
+// 4 6/24/09 4:25p Robert
+// updated comments, copyright and some coding standard issues
+//
+// 1 5/22/09 1:29p Felixp
+// RTC and Reset architectural protocols
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TimeAndReset.C
+//
+// Description:
+// This file contains implementation of Time and Reset Runtime Services
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//======================================================================
+// Module specific Includes
+#include <token.h>
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+
+//======================================================================
+// Produced Protocols
+#include <Protocol/Reset.h>
+#include <Protocol/RealTimeClock.h>
+#include <Protocol/Timer.h>
+
+/****************************** RTC Types and Constants *******************/
+//----------------------------------------------------------------------
+//Define Dallas DS12C887 Real Time Clock INDEX and DATA registers
+//----------------------------------------------------------------------
+#define RTC_INDEX_REG 0x70
+#define RTC_DATA_REG 0x71
+
+//----------------------------------------------------------------------
+//Define Internal Registers for Dallas DS12C887 Real Time Clock
+//----------------------------------------------------------------------
+#define RTC_SECONDS_REG 0x00 // R/W Range 0..59
+#define RTC_SECONDS_ALARM_REG 0x01 // R/W Range 0..59
+#define RTC_MINUTES_REG 0x02 // R/W Range 0..59
+#define RTC_MINUTES_ALARM_REG 0x03 // R/W Range 0..59
+#define RTC_HOURS_REG 0x04 // R/W Range 1..12
+ // or 0..23 Bit 7 is AM/PM
+#define RTC_HOURS_ALARM_REG 0x05 // R/W Range 1..12
+ // or 0..23 Bit 7 is AM/PM
+#define RTC_DAY_OF_WEEK_REG 0x06 // R/W Range 1..7
+#define RTC_DAY_OF_MONTH_REG 0x07 // R/W Range 1..31
+#define RTC_MONTH_REG 0x08 // R/W Range 1..12
+#define RTC_YEAR_REG 0x09 // R/W Range 0..99
+#define RTC_REG_A_INDEX 0x0a // R/W[0..6] R0[7]
+#define RTC_REG_B_INDEX 0x0b // R/W
+#define RTC_REG_C_INDEX 0x0c // RO
+#define RTC_REG_D_INDEX 0x0d // RO
+//Defined in ACPI.sdl
+//#define RTC_CENTURY_BYTE 50 // R/W Range 19..20 Bit 8 is R/W
+
+#define RTC_NMI_MASK 0x80
+
+#define AMI_RESET_TYPE_VARIABLE_GUID \
+ {0x308DD02C, 0x092B, 0x4123, 0xA2, 0xAF, 0x3E, 0xF4, 0x44, 0x0A, 0x6B, 0x4A}
+//----------------------------------------------------------------------
+//Registers A..D Bit definitions
+//----------------------------------------------------------------------
+#pragma pack(push,1)
+
+//----------------------------------------------------------------------
+// Register A
+//----------------------------------------------------------------------
+typedef union {
+ UINT8 REG_A;
+ struct {
+ UINT8 RateSel : 4;
+ UINT8 Divisor : 3;
+ UINT8 UpdInProgr : 1;
+ };
+} RTC_REG_A;
+
+//----------------------------------------------------------------------
+// Register B
+//----------------------------------------------------------------------
+typedef union {
+ UINT8 REG_B;
+ struct {
+ UINT8 DaylightSav : 1; // 0 - Daylight saving disabled
+ // 1 - Daylight savings enabled
+ UINT8 Mode : 1; // 0 - 12 hour mode
+ // 1 - 24 hour mode
+ UINT8 Format : 1; // 0 - BCD Format
+ // 1 - Binary Format
+ UINT8 SquareWave : 1; // 0 - Disable SQWE output
+ // 1 - Enable SQWE output
+ UINT8 UpdateInt : 1; // 0 - Update INT disabled
+ // 1 - Update INT enabled
+ UINT8 AlarmInt : 1; // 0 - Alarm INT disabled
+ // 1 - Alarm INT Enabled
+ UINT8 PeriodicInt : 1; // 0 - Periodic INT disabled
+ // 1 - Periodic INT Enabled
+ UINT8 Set : 1; // 0 - Normal operation.
+ // 1 - Updates inhibited
+ };
+} RTC_REG_B;
+
+//----------------------------------------------------------------------
+// Register C
+//----------------------------------------------------------------------
+typedef union {
+ UINT8 REG_C;
+ struct {
+ UINT8 Reserved : 4; // Read as zero. Can not be written.
+ UINT8 UpdEndFlag : 1; // Update End Interrupt Flag
+ UINT8 AlarmFlag : 1; // Alarm Interrupt Flag
+ UINT8 PeriodicFlag : 1; // Periodic Interrupt Flag
+ UINT8 IrqFlag : 1; // Iterrupt Request Flag =
+ // PF & PIE | AF & AIE | UF & UIE
+ };
+} RTC_REG_C;
+
+//----------------------------------------------------------------------
+// Register D
+//----------------------------------------------------------------------
+typedef union {
+ UINT8 REG_D;
+ struct {
+ UINT8 DateAlarm : 6;
+ UINT8 Reserved : 1; // Read as zero. Can not be written.
+ UINT8 DataValid : 1; // Valid RAM and Time
+ };
+} RTC_REG_D;
+
+#pragma pack(pop)
+/*********************** End of RTC Types and Constants *******************/
+
+
+//===========================================================================
+// Time Variable GUID Definition
+#define EFI_TIME_VARIABLE_GUID \
+ {0x9d0da369, 0x540b, 0x46f8, 0x85, 0xa0, 0x2b, 0x5f, 0x2c, 0x30, 0x1e, 0x15}
+
+//===========================================================================
+// Variable Declaration
+static BOOLEAN gTimeOut = FALSE;
+
+// GUID Definitions
+EFI_GUID gEfiTimeVariableGuid = EFI_TIME_VARIABLE_GUID;
+
+//This the number of days in a month - 1. (0 Based)
+UINT8 DaysInMonth[] = {30, 27, 30, 29, 30, 29, 30, 30, 29, 30, 29, 30};
+
+//===========================================================================
+// UEFI Time Variable Type definition
+#pragma pack(1)
+typedef struct {
+ INT16 TimeZone;
+ UINT8 Daylight;
+ } TIME_VARIABLE;
+#pragma pack()
+
+//===========================================================================
+// Function Declarations
+VOID DummyFunction(IN EFI_EVENT Event, IN VOID *Context);
+
+//===========================================================================
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiResetSystem
+//
+// Description:
+// This function is the interface for the reset function.
+//
+// Input:
+// IN EFI_RESET_TYPE ResetType - Type of reset to perform
+// IN EFI_STATUS ResetStatus - System status that caused the reset. if part of normal operation
+// then this should be EFI_SUCCESS, Otherwise it should reflect the
+// state of the system that caused it
+// IN UINTN DataSize - Size in bytes of the data to be logged
+// IN CHAR16 *ResetData - Pointer to the data buffer that is to be logged - OPTIONAL
+//
+// Output:
+// EFI_DEVICE_ERROR - Even though it should never get that far
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+EfiResetSystem (
+ IN EFI_RESET_TYPE ResetType,
+ IN EFI_STATUS ResetStatus,
+ IN UINTN DataSize,
+ IN CHAR16 *ResetData OPTIONAL
+){
+ static EFI_GUID AmiResetTypeVariableGuid = AMI_RESET_TYPE_VARIABLE_GUID;
+ if (!EfiAtRuntime()){
+ EFI_EVENT Event;
+ UINT32 OverrideResetType;
+ UINTN Size = sizeof(UINT32);
+ EFI_STATUS Status;
+
+ pBS->CreateEventEx(
+ 0, TPL_CALLBACK, DummyFunction,
+ NULL, &AmiResetTypeVariableGuid, &Event
+ );
+ pBS->SignalEvent(Event);
+ pBS->CloseEvent(Event);
+ Status = pRS->GetVariable(
+ L"CspResetType", &AmiResetTypeVariableGuid, NULL,
+ &Size, &OverrideResetType
+ );
+ if (!EFI_ERROR(Status)) ResetType = OverrideResetType;
+ }
+ SBLib_ResetSystem (ResetType);
+ ASSERT(FALSE);
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DecToBCD
+//
+// Description:
+// This function converts data from DEC to BCD format
+//
+// Input:
+// UINT8 DEC - value to be converted
+//
+// Output:
+// UINT8 - result of conversion
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 DecToBCD(UINT8 Dec)
+{
+ UINT8 FirstDigit = Dec % 10;
+ UINT8 SecondDigit = Dec / 10;
+
+ return (SecondDigit << 4) + FirstDigit;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BCDToDec
+//
+// Description:
+// This function converts data from BCD to DEC format
+//
+// Input:
+// UINT8 BCD - value to be converted
+//
+// Output:
+// UINT8 - result of conversion
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 BCDToDec(UINT8 BCD)
+{
+ UINT8 FirstDigit = BCD & 0xf;
+ UINT8 SecondDigit = BCD >> 4;;
+
+ return SecondDigit * 10 + FirstDigit;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadRtcIndex
+//
+// Description:
+// Read the RTC value at the given Index.
+//
+// Input:
+// IN UINT8 Index - RTC Register Index to read from
+//
+// Output:
+// RTC Value read from the provided Index
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read port 0x70 (RTC Index Register) to get bit 7.
+// Bit 7 is the NMI bit-it should not be changed.
+// 2. Set Index with the NMI bit setting.
+// 3. Output 0x70 with the Index.
+// 4. Read 0x71 for Data.
+// 5. Return the Data.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 ReadRtcIndex(IN UINT8 Index)
+{
+ UINT8 NMI = IoRead8(RTC_INDEX_REG) & RTC_NMI_MASK; //Read bit 7 (NMI setting).
+ UINT8 volatile Value;
+ BOOLEAN IntState = CPULib_GetInterruptState();
+//----------------------
+ CPULib_DisableInterrupt();
+
+ IoWrite8(RTC_INDEX_REG, Index | NMI);
+ Value = IoRead8(RTC_DATA_REG); //Read register.
+
+ if (IntState) CPULib_EnableInterrupt();
+
+ if (Index <= RTC_YEAR_REG || Index == ACPI_CENTURY_CMOS) Value = BCDToDec(Value);
+
+ return (UINT8)Value;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteRtcIndex
+//
+// Description:
+// Write the RTC value at the given Index.
+//
+// Input:
+// IN UINT8 Index - RTC register Index
+// IN UINT8 Value - Data to write to the Index indicated
+//
+// Output:
+// None
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read port 0x70 (RTC Index Register) to get bit 7.
+// Bit 7 is the NMI bit-it should not be changed.
+// 2. Set Index with the NMI bit setting.
+// 3. Output 0x70 with the Index.
+// 4. Write the data to 0x71.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID WriteRtcIndex(IN UINT8 Index, IN UINT8 Value)
+{
+ UINT8 NMI = IoRead8(RTC_INDEX_REG) & RTC_NMI_MASK; //Read bit 7 (NMI setting).
+ BOOLEAN IntState=CPULib_GetInterruptState();
+//--------------------
+ if (Index <= RTC_YEAR_REG || Index == ACPI_CENTURY_CMOS) Value = DecToBCD(Value);
+
+ CPULib_DisableInterrupt();
+
+ IoWrite8(RTC_INDEX_REG,Index | NMI);
+ IoWrite8(RTC_DATA_REG, Value); //Write Register.
+
+ if (IntState) CPULib_EnableInterrupt();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitRtc
+//
+// Description:
+// This function initializes RTC
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitRtc(VOID)
+{
+ WriteRtcIndex(RTC_REG_B_INDEX, 0x82);
+ WriteRtcIndex(RTC_REG_A_INDEX, 0x26);
+ ReadRtcIndex(RTC_REG_C_INDEX);
+ ReadRtcIndex(RTC_REG_D_INDEX);
+ WriteRtcIndex(RTC_REG_B_INDEX, 0x02);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetUpdate
+//
+// Description: Enables Disables RTC Date and Time update cicles.
+//
+// Input: Enable TRUE or FALSE to Enable\Disabe RTC Update.
+//
+// Output: NOTHING
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SetUpdate(BOOLEAN Enable){
+ RTC_REG_B RegB;
+
+ RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX);
+ if(RegB.Set == Enable) {
+ RegB.Set = !Enable;
+ WriteRtcIndex(RTC_REG_B_INDEX, RegB.REG_B);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckUpdateCmplete
+//
+// Description:
+// Check if RTC Date and Time update in progress and waits till it's over.
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CheckUpdateCmplete(){
+ RTC_REG_A volatile RegA;
+ UINTN timeout=0;
+//-------------------------
+ RegA.REG_A = ReadRtcIndex(RTC_REG_A_INDEX);
+ while ( RegA.UpdInProgr){
+ RegA.REG_A = ReadRtcIndex(RTC_REG_A_INDEX);
+ timeout++;
+ if(timeout >= 0x0fffff){
+ gTimeOut = TRUE;
+ return;
+ }
+ }
+ gTimeOut=FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyTime
+//
+// Description: This routine verifies if time and data if needed, before
+// setting the RTC
+//
+// Input: *Time Time to verify with
+// CheckDate TRUE if check date also
+//
+// Output: TRUE if valid time and date
+//
+// Notes: Here is the control flow of this function:
+// 1. Decrease month and date to change to 0-base
+// 2. Validate Year, Month and Day. If invalid, return FALSE.
+// 3. Validate Hour, Minute, and Second. If invalid, return FALSE.
+// 4. Return True.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN VerifyTime(IN EFI_TIME *Time)
+{
+ //Always check these to satisfy EFI compliancy test even for setting wake-up time.
+ UINT8 Month = Time->Month - 1;
+ UINT8 Day = Time->Day - 1;
+
+ if (Time->Year < MINIMUM_YEAR || Time->Year > 2099) return FALSE;
+ if (Month > 11) return FALSE; //0 based month
+ if (Month != 1 || (Time->Year & 3)) { //not leap year or not February.
+ if (Day > DaysInMonth[Month]) return FALSE; //All values already adjusted for 0 based.
+ } else {
+ if (Day > 28) return FALSE; //February
+ }
+
+ if (Time->Hour > 23) return FALSE;
+ if (Time->Minute > 59) return FALSE;
+ if (Time->Second > 59) return FALSE;
+
+ //Check these to satisfy EFI compliancy test.
+ if (Time->Nanosecond > 999999999) return FALSE; //999,999,999
+ if (Time->TimeZone < -1440) return FALSE;
+ if (Time->TimeZone > 1440 && Time->TimeZone != EFI_UNSPECIFIED_TIMEZONE) return 0;
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckRtc
+//
+// Description:
+// Check if RTC Mode and Format have appropriate values and sets them if
+// necessary
+//
+// Input:
+// BOOLEAN Set - if true, force Rtc to 24 hour mode and binary format
+//
+// Output:
+// EFI_SUCCESS - Rtc mode and format have appropriate values
+// EFI_DEVICE_ERROR - Rtc mode and/or format are invalid
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckRtc(BOOLEAN Set){
+ RTC_REG_B RegB;
+
+ //Check RTC Conditions and stuff
+ RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX);
+ if(RegB.Mode == 0 || RegB.Format == 1) {
+ if(Set){
+ RegB.Mode = 1; // 0 - 12 hour mode 1 - 24 hour mode
+ RegB.Format = 0; // 0 - BCD Format 1 - Binary Format
+ WriteRtcIndex(RTC_REG_B_INDEX, RegB.REG_B);
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiGetTime
+//
+// Description:
+// Return the current date and time
+//
+// Input:
+// OUT EFI_TIME *Time - Current time filled in EFI_TIME structure
+// OUT EFI_TIME_CAPABILITIES *Capabilities - Time capabilities (OPTIONAL)
+//
+// Output:
+// EFI_SUCCESS Always
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read the original time format 12/24 hours and BCD/binary.
+// 2. Set the format to 24 hrs and binary.
+// 3. Read the 2 digit year.
+// 4. Add either 1900 or 2000, so the year is between 1998 - 2097.
+// 5. Read the month, day, hour, minute, second.
+// 6. Set the nanosecond to 0.
+// 7. Set the time to zone to unspecified.
+// 8. Set daylight savings value to 0.
+// 9. Restore the original time format.
+// 10. Set Capabilities with 1 sec Resolution, 0 Accuracy (Unknown), and False SetsToZero.
+// 11. Return EFI_SUCCESS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiGetTime (
+ OUT EFI_TIME *Time,
+ OUT EFI_TIME_CAPABILITIES *Capabilities OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ UINT8 Year;
+ BOOLEAN IntState, SmiState;
+ UINTN TimeVarSize = sizeof(TIME_VARIABLE);
+ TIME_VARIABLE TimeVar;
+
+ if (Time == NULL) return EFI_INVALID_PARAMETER;
+ //Check RTC Conditions (24h Mode and BCD is ON)
+ Status = CheckRtc(FALSE);
+ if(EFI_ERROR(Status)) return Status;
+ //Get SMI State and disable it
+ SmiState = SbLib_GetSmiState();
+ SbLib_SmiDisable();
+ //Get INTERRUPT State and disable it
+ IntState = CPULib_GetInterruptState();
+ CPULib_DisableInterrupt();
+ // Wait till RTC is safe to read,
+ CheckUpdateCmplete();
+ if(gTimeOut){
+ InitRtc();
+ }
+
+ // After control comes back, we will have 488 u's to read data.
+ Year = ReadRtcIndex(RTC_YEAR_REG);
+ Time->Month = ReadRtcIndex(RTC_MONTH_REG);
+ Time->Day = ReadRtcIndex(RTC_DAY_OF_MONTH_REG);
+ Time->Hour = ReadRtcIndex(RTC_HOURS_REG);
+ Time->Minute = ReadRtcIndex(RTC_MINUTES_REG);
+ Time->Second = ReadRtcIndex(RTC_SECONDS_REG);
+ //Restore SMIs and INTERRUPT State
+ if(IntState) CPULib_EnableInterrupt();
+ if(SmiState) SbLib_SmiEnable();
+
+ //This Register is not affected by UIP bit so read it very last.
+ // If RTC Year only 1 digit, EFI spec says years rang is 1998 - 2097
+ Time->Year = ReadRtcIndex(ACPI_CENTURY_CMOS) * 100 + Year;
+ Time->Nanosecond= 0;
+
+ Status = pRS->GetVariable(
+ L"EfiTime",
+ &gEfiTimeVariableGuid,
+ NULL,
+ &TimeVarSize,
+ &TimeVar
+ );
+
+ if (EFI_ERROR(Status))
+ {
+ Time->TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+ Time->Daylight = 0;
+ }
+ else
+ {
+ Time->TimeZone = TimeVar.TimeZone;
+ Time->Daylight = TimeVar.Daylight;
+ }
+
+ if (Capabilities != NULL) {
+ Capabilities->Resolution = 1;
+ Capabilities->Accuracy = 0;
+ Capabilities->SetsToZero = 0;
+ }
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiSetTime
+//
+// Description:
+// Sets the RTC time
+//
+// Input:
+// IN EFI_TIME *Time - Time to set
+//
+// Output:
+// EFI_SUCCESS - Time is Set
+// EFI_INVALID_PARAMETER - Time to Set is not valid.
+//
+// Modified:
+// gTimeZone
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read the original time format 12/24 hours and BCD/binary.
+// 2. Set the format to 24 hrs and binary.
+// 3. Verify the time to set. If it is an invalid time,
+// restore the time format and return EFI_INVALID_PARAMETER.
+// 4. Change the 4 digit year to a 2 digit year.
+// 5. Stop the RTC time.
+// 6. Store time and data on the RTC.
+// 7. Read the month, day, hour, minute, second.
+// 8. Start the RTC time.
+// 9. Restore the original time format.
+// 10. Return EFI_SUCCESS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiSetTime (
+ IN EFI_TIME *Time
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN TimeVarSize = sizeof(TIME_VARIABLE);
+ TIME_VARIABLE TimeVar;
+
+ //Check RTC Conditions and stuff
+ CheckRtc(TRUE);
+ if (Time == NULL) return EFI_INVALID_PARAMETER;
+ if (!VerifyTime(Time)) return EFI_INVALID_PARAMETER;
+ SetUpdate(FALSE);
+ WriteRtcIndex(ACPI_CENTURY_CMOS, Time->Year / 100);
+ WriteRtcIndex(RTC_YEAR_REG, Time->Year % 100);
+ WriteRtcIndex(RTC_MONTH_REG, Time->Month);
+ WriteRtcIndex(RTC_DAY_OF_MONTH_REG, Time->Day);
+ WriteRtcIndex(RTC_HOURS_REG, Time->Hour);
+ WriteRtcIndex(RTC_MINUTES_REG, Time->Minute);
+ WriteRtcIndex(RTC_SECONDS_REG, Time->Second);
+ SetUpdate(TRUE);
+
+ Status = pRS->GetVariable(
+ L"EfiTime",
+ &gEfiTimeVariableGuid,
+ NULL,
+ &TimeVarSize,
+ &TimeVar
+ );
+ if (EFI_ERROR(Status) || (TimeVar.TimeZone != Time->TimeZone) || (TimeVar.Daylight != Time->Daylight))
+ {
+ TimeVar.TimeZone = Time->TimeZone;
+ TimeVar.Daylight = Time->Daylight;
+ Status = pRS->SetVariable(
+ L"EfiTime",
+ &gEfiTimeVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(TIME_VARIABLE),
+ &TimeVar
+ );
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiGetWakeupTime
+//
+// Description:
+// Read the wake time. Read the status if it is enabled or if the system
+// has woken up.
+//
+// Input:
+// OUT BOOLEAN *Enabled - Flag indicating the validity of wakeup time
+// OUT BOOLEAN *Pending - Check if wake up time has expired.
+// OUT EFI_TIME *Time - Current wake up time setting
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS (Always)
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read the original time format 12/24 hours and BCD/binary.
+// 2. Set the format to 24 hrs and binary.
+// 3. Read the status if the wake up time is enabled or if it has expired.
+// 4. Set the wakeup time.
+// 5. Restore the original time format.
+// 6. Return EFI_SUCCESS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiGetWakeupTime (
+ OUT BOOLEAN *Enabled,
+ OUT BOOLEAN *Pending,
+ OUT EFI_TIME *Time
+)
+{
+ RTC_REG_B RegB;
+ RTC_REG_C RegC;
+ RTC_REG_D RegD;
+ BOOLEAN IntState, SmiState;
+ EFI_STATUS Status;
+
+ if (!Enabled || !Pending || !Time) return EFI_INVALID_PARAMETER;
+
+ //Check RTC Conditions (24h Mode and BCD is ON)
+ Status = CheckRtc(FALSE);
+ if(EFI_ERROR(Status)) return Status;
+
+ //Get SMI State and disable it
+ SmiState = SbLib_GetSmiState();
+ SbLib_SmiDisable();
+ //Get INTERRUPT State and disable it
+ IntState = CPULib_GetInterruptState();
+ CPULib_DisableInterrupt();
+
+ // Wait till RTC is safe to read,
+ CheckUpdateCmplete();
+ if(gTimeOut){
+ InitRtc();
+ }
+
+ Time->Hour = ReadRtcIndex(RTC_HOURS_ALARM_REG);
+ Time->Minute = ReadRtcIndex(RTC_MINUTES_ALARM_REG);
+ Time->Second = ReadRtcIndex(RTC_SECONDS_ALARM_REG);
+
+ //Restore SMIs and INTERRUPT State
+ if(IntState) CPULib_EnableInterrupt();
+ if(SmiState) SbLib_SmiEnable();
+
+
+ RegD.REG_D = ReadRtcIndex(RTC_REG_D_INDEX);
+ Time->Day = BCDToDec(RegD.DateAlarm);
+
+ RegB.REG_B=ReadRtcIndex(RTC_REG_B_INDEX);
+ RegC.REG_C=ReadRtcIndex(RTC_REG_C_INDEX);
+
+ *Enabled = RegB.AlarmInt;
+ *Pending = RegC.AlarmFlag;
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiSetWakeupTime
+//
+// Description:
+// Enable/disable and set wakeup time
+//
+// Input:
+// IN BOOLEAN Enable - Flag indicating whether to enable/disble the time
+// IN EFI_TIME *Time - Time to set as the wake up time - OPTIONAL
+//
+// Output:
+// EFI_SUCCESS - Time is Set and/or Enabled/Disabled.
+// EFI_INVALID_PARAMETER - Invalid time or enabling with a NULL Time.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Read the original time format 12/24 hours and BCD/binary.
+// 2. If Time is not NULL,
+// a. Verify the wakeup time to set. If it is an invalid time,
+// restore the time format and return EFI_INVALID_PARAMETER.
+// b. Set the wakeup time.
+// 3. If Time is NULL and Enable is true, restore original time format
+// and return EFI_INVALID_PARAMETER.
+// 4. Enable/Disable wakeup.
+// 5. Restore the original time format.
+// 6. Return EFI_SUCCESS.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiSetWakeupTime (
+ IN BOOLEAN Enable,
+ IN EFI_TIME *Time OPTIONAL
+)
+{
+ RTC_REG_B RegB;
+ RTC_REG_D RegD;
+ UINT8 Day = 0;
+ EFI_STATUS Status;
+
+
+ //Check RTC Conditions (24h Mode and BCD is ON)
+ Status=CheckRtc(FALSE);
+ if(EFI_ERROR(Status)) return Status;
+
+ if (Enable){
+ //According to UEFI specification,
+ // value of 0 is invalid for the alarm day.
+ // However, RTC chip supports value 0.
+ // It interprets it as "every day".
+ //If this functionality is required,
+ //uncomment the following workaround.
+ //The workaround is commented out be default
+ //for compatibility with UEFI specification
+ //(one of the SCT tests fails with the workaround enabled).
+/*
+ if(Time != NULL) {
+ Day = Time->Day;
+ if(Time->Day == 0) Time->Day = 1;
+ }
+*/
+ if (Time == NULL || !VerifyTime(Time)) return EFI_INVALID_PARAMETER;
+ }
+
+ RegB.REG_B = ReadRtcIndex(RTC_REG_B_INDEX);
+ RegD.REG_D = ReadRtcIndex(RTC_REG_D_INDEX);
+ Day = DecToBCD(Day);
+ RegD.DateAlarm = Day;
+
+ SetUpdate(FALSE);
+ if(Time!=NULL){
+ WriteRtcIndex(RTC_HOURS_ALARM_REG, Time->Hour);
+ WriteRtcIndex(RTC_MINUTES_ALARM_REG, Time->Minute);
+ WriteRtcIndex(RTC_SECONDS_ALARM_REG, Time->Second);
+ WriteRtcIndex(RTC_REG_D_INDEX, RegD.REG_D); //Day==0 means don't care
+ }
+ //Set Enable/Disable
+ RegB.AlarmInt = Enable;
+ WriteRtcIndex(RTC_REG_B_INDEX, RegB.REG_B);
+
+ SetUpdate(TRUE);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: NotInSmmTimeServ
+//
+// Description:
+// This function checks the date and time stored in the RTC. If it's wrong
+// it resets the time and and installs Time Runtime services in Non-SMM Mode
+// RTC Arch Protocol would also be installed.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table
+//
+// Output:
+// Returns the EFI_STATUS value returned by the
+// InstallMultipleProtocolInterface function
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS NotInSmmTimeServ(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_TIME Time;
+ EFI_HANDLE Handle = NULL;
+
+ InitAmiRuntimeLib(ImageHandle, SystemTable, NULL, NULL);
+
+ //Make Sure Mode, Format and REG_A is OK
+ CheckRtc(TRUE);
+
+ Status=EfiGetTime(&Time, NULL);
+
+ if( EFI_ERROR(Status) || (!VerifyTime(&Time)))
+ {
+ EFI_TIME nt;
+
+ ERROR_CODE(GENERIC_BAD_DATE_TIME_ERROR, EFI_ERROR_MINOR);
+
+ TRACE((TRACE_ALWAYS, "\n\nTime: %d/%d/%d %d:%d:%d\n",
+ Time.Month,
+ Time.Day,
+ Time.Year,
+ Time.Hour,
+ Time.Minute,
+ Time.Second
+ ));
+
+ TRACE((TRACE_ALWAYS, "Nanosecond: %d TimeZone: %d\n\n\n",
+ Time.Nanosecond,
+ Time.TimeZone
+ ));
+
+ //if Time is invalid the battery probably has been removed
+ //Let's setup RTC_REG_A just in case...
+ WriteRtcIndex(RTC_REG_A_INDEX, 0x26);
+
+ //Check to see what part of EFI_TIME was wrong.
+ //reset unrelated to RTC fields.
+ Time.TimeZone = EFI_UNSPECIFIED_TIMEZONE;
+ Time.Daylight = 0;
+ Time.Nanosecond = 0;
+
+ nt=Time;
+
+ nt.Hour = 0;
+ nt.Minute = 0;
+ nt.Second = 0;
+
+ if(VerifyTime(&nt)){
+ //if we here that means Time was wrong
+ Time.Hour = 0;
+ Time.Minute = 0;
+ Time.Second = 0;
+ } else {
+ //if we here that means Date was wrong
+ Time.Month = DEFAULT_MONTH;
+ Time.Day = DEFAULT_DAY;
+ Time.Year = DEFAULT_YEAR;
+ }
+ //Here is the situation when both Time and Date is Incorrect.
+ if(!VerifyTime(&Time)){
+ Time.Hour = 0;
+ Time.Minute = 0;
+ Time.Second = 0;
+ Time.Month = DEFAULT_MONTH;
+ Time.Day = DEFAULT_DAY;
+ Time.Year = DEFAULT_YEAR;
+ }
+
+ TRACE((TRACE_ALWAYS, "Reseting Invalid Date and Time to: %d/%d/%d %d:%d:%d\n\n",
+ Time.Month,
+ Time.Day,
+ Time.Year,
+ Time.Hour,
+ Time.Minute,
+ Time.Second
+ ));
+ EfiSetTime(&Time);
+ }
+ // Install runtime services
+
+ pRS->GetTime = EfiGetTime;
+ pRS->SetTime = EfiSetTime;
+ pRS->GetWakeupTime = EfiGetWakeupTime;
+ pRS->SetWakeupTime = EfiSetWakeupTime;
+
+ //This protocol is to notify core that the Runtime Table has been updated, so
+ //it can update the runtime table CRC.
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiRealTimeClockArchProtocolGuid,NULL,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: NotInSmmResetServ
+//
+// Description:
+// Installs Reset Runtime Services in Non-SMM Mode
+// Reset Architectural Protocol is installed
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table
+//
+// Output:
+// Returns the EFI_STATUS value returned by the InstallProtocolInterface
+// function
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS NotInSmmResetServ(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_HANDLE ResetProtocolHandle = NULL;
+
+ InitAmiRuntimeLib(ImageHandle, SystemTable, NULL, NULL);
+
+ // Install reset services
+ pRS->ResetSystem = EfiResetSystem;
+
+ Status = pBS->InstallProtocolInterface ( &ResetProtocolHandle,
+ &gEfiResetArchProtocolGuid, EFI_NATIVE_INTERFACE,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InSmmTimeServ
+//
+// Description:
+// Installs Time Runtime Services to SMM mode.
+//
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS InSmmTimeServ(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (pST->RuntimeServices != pRS)
+ {
+
+ pRS->GetTime = EfiGetTime;
+ pRS->SetTime = EfiSetTime;
+ pRS->GetWakeupTime = EfiGetWakeupTime;
+ pRS->SetWakeupTime = EfiSetWakeupTime;
+
+ }
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InSmmResetServ
+//
+// Description:
+// Installs Reset runtime services to SMM mode.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table
+//
+// Output:
+// EFI_SUCCESS
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS InSmmResetServ(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ if (pST->RuntimeServices != pRS)
+ {
+ pRS->ResetSystem = EfiResetSystem;
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TimeServInit
+//
+// Description:
+// This function is the entry point for this DXE. This function installs
+// Time pRS services
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table
+//
+// Output:
+// Return Status based on errors that occurred while waiting for time to expire.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+TimeServInit (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+){
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandlerEx(ImageHandle, SystemTable, InSmmTimeServ, NotInSmmTimeServ);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetServInit
+//
+// Description:
+// This function is the entry point for this DXE Driver. This function
+// installs the Reset pRS service.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the UEFI System Table
+//
+// Output:
+// Return Status based on errors that occurred while waiting for time to expire.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ResetServInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+){
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandlerEx(ImageHandle, SystemTable, InSmmResetServ, NotInSmmResetServ);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/AcpiPeiS3Func.c b/Core/EM/S3/AcpiPeiS3Func.c
new file mode 100644
index 0000000..966ddcb
--- /dev/null
+++ b/Core/EM/S3/AcpiPeiS3Func.c
@@ -0,0 +1,141 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.c 2 7/19/11 11:34a Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 7/19/11 11:34a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.c $
+//
+// 2 7/19/11 11:34a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 7 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 6 4/29/08 4:38p Felixp
+// Bug fix in GetAcpiS3Info: Initialize AcpiVariableSet variable with NULL
+// to make sure there is no junk in the high 4 bytes in x64 mode.
+//
+// 5 4/15/08 9:15p Yakovlevs
+// Functions Headers added
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AcpiPeiS3Func.c
+//
+// Description: ACPI S3 PEI support functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <EFI.h>
+#include <Pei.h>
+#include <Ppi\ReadOnlyVariable2.h>
+#include <AmiPeiLib.h>
+#include "AcpiS3.h"
+
+CHAR16 gAcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+EFI_GUID gEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+
+extern EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAcpiS3Info
+//
+// Description:
+// This function reads ACPI_VARIABLE_SET data from NVRAM and returns pointer to it
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to pointer to PEI services
+//
+// Output:
+// ACPI_VARIABLE_SET* - pointer to ACPI_VARIABLE_SET structure (NULL if error occured)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+ACPI_VARIABLE_SET * GetAcpiS3Info(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable;
+ ACPI_VARIABLE_SET *AcpiVariableSet = NULL;
+
+ UINTN VariableSize = sizeof(ACPI_VARIABLE_SET*);
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ Status = ReadOnlyVariable->GetVariable(
+ ReadOnlyVariable,
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ NULL,
+ &VariableSize,
+ &AcpiVariableSet
+ );
+ if (EFI_ERROR(Status)) return NULL;
+ return AcpiVariableSet;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/EM/S3/AcpiPeiS3Func.h b/Core/EM/S3/AcpiPeiS3Func.h
new file mode 100644
index 0000000..5afbf84
--- /dev/null
+++ b/Core/EM/S3/AcpiPeiS3Func.h
@@ -0,0 +1,83 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.h 1 2/03/11 4:09p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 2/03/11 4:09p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.h $
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 8/22/05 4:06p Markw
+// Removed get cpu info.
+//
+// 1 5/06/05 1:44p Markw
+//
+//**********************************************************************
+
+#ifndef __ACPI_PEI_S3_FUNC_H__
+#define __ACPI_PEI_S3_FUNC_H__
+
+#include <Efi.h>
+#include "AcpiS3.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ACPI_VARIABLE_SET * GetAcpiS3Info(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/AcpiS3Save.c b/Core/EM/S3/AcpiS3Save.c
new file mode 100644
index 0000000..944c6f5
--- /dev/null
+++ b/Core/EM/S3/AcpiS3Save.c
@@ -0,0 +1,468 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.c 8 7/11/14 11:36a Oleksiyy $
+//
+// $Revision: 8 $
+//
+// $Date: 7/11/14 11:36a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.c $
+//
+// 8 7/11/14 11:36a Oleksiyy
+// [TAG] EIP175962
+// [Category] Improvement
+// [Description] Memory allocation logic made more clear.
+// [Files] AcpiS3Save.c
+//
+// 7 7/01/14 4:13p Oleksiyy
+// [TAG] EIP175962
+// [Category] Improvement
+// [Description] Memory type for AcpiGlobalVariable changed to Reserved to
+// prevent OS from restoring it on thertain scenarious.
+// [Files] AcpiS3Save.c
+//
+// 6 6/05/14 3:22p Oleksiyy
+// [TAG] EIP165196
+// [Category] Improvement
+// [Description] Previous check in updated with better logic.
+// [Files] AcpiS3Save.c
+//
+// 5 6/03/14 6:13p Oleksiyy
+// [TAG] EIP165196
+// [Category] Improvement
+// [Description] Taken care of case when BIOS will be updated with
+// preserved NVRAM and AcpiGlobalVariable will still has runtime attribute
+// [Files] AcpiS3Save.c
+//
+// 4 4/22/14 3:35p Oleksiyy
+// [TAG] EIP165196
+// [Category] Improvement
+// [Description] Runtime attribute removed when setting
+// AcpiGlobalVariable.
+// [Files] AcpiS3Save.c
+//
+// 3 7/19/11 11:32a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 2 4/15/11 5:53p Oleksiyy
+// [TAG] EIP58481
+// [Category] Improvement
+// [Description] AllocatePages used instead of AllocatePool to make
+// AcpiMemoryBase aligned on 4KB boundary
+// [Files] AcpiS3Save.c
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 19 4/28/10 2:49p Oleksiyy
+// EIP 35563 Added logic to handle only ACPI 1.1 case in saving FACS.
+//
+// 18 5/18/09 10:41a Yakovlevs
+// Changed token name from S3_BASE_MEMORY to S3_BASE_MEMORY_SIZE for
+// better token meaning.
+//
+// 17 4/28/09 6:02p Markw
+// EIP #16665 - Unable to allocate enough memory in S3. Added allocation
+// of base + memory per cpu.
+//
+// 16 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 15 10/06/08 2:06p Yakovlevs
+// Added NUM_S3_PAGES_RESERVED token support
+//
+// 14 4/15/08 9:14p Yakovlevs
+// Functions Headers added
+//
+// 13 4/09/08 5:13p Yakovlevs
+// Make S3Save code remember all possible locations of FACS.
+//
+// 12 4/23/07 1:31p Felixp
+// Boot Script related code moved from Core to ACPI module.
+// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver.
+//
+// 11 10/13/06 12:29a Felixp
+// UEFI2.0 compliance: use CreateReadyToBootEvent instead of
+// CreateEvent(READY_TO_BOOT)
+//
+// 10 9/18/06 6:51p Markw
+// Fix AcpiGlobalVariable Size below 4GB.
+//
+// 9 8/24/06 3:00p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 7 8/22/05 4:05p Markw
+// Removed IDT saving to CPU.
+//
+// 6 7/20/05 3:35p Girim
+// Fix for S3 Resume.
+//
+// 5 5/31/05 6:05p Markw
+// Number of pages reported to PEI S3 resume and reserved for windows
+// different. Added a #define, so are the same.
+//
+// 4 5/31/05 10:26a Markw
+// Changed reserving ACPI memory from 32k to 128k.
+//
+// 3 5/04/05 12:24p Markw
+// Moved structure definitions to AcpiS3.h.
+//
+// 2 4/29/05 3:26p Markw
+//
+// 1 4/29/05 12:17p Sivagarn
+//
+// 5 4/22/05 2:45p Markw
+// Only save S3 Resume Info once.
+//
+// 4 3/31/05 11:00a Markw
+// Storing the FACS table for S3 resume is working.
+//
+// 3 3/30/05 2:56p Markw
+// Added getting ACPI FACS table.
+//
+// 2 3/24/05 5:40p Markw
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AcpiS3Save.c
+//
+// Description: ACPI S3 support functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#include <Dxe.h>
+#include <Hob.h>
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\MpService.h>
+#include <AmiDxeLib.h>
+#include <Acpi20.h>
+#include "AcpiS3.h"
+#include <token.h>
+
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL *gBootScriptSave;
+EFI_MP_SERVICES_PROTOCOL *gMpServices;
+CHAR16 gAcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+
+EFI_GUID gAcpi20TableGuid = ACPI_20_TABLE_GUID;
+EFI_GUID gAcpi11TAbleGuid = ACPI_10_TABLE_GUID;
+EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+EFI_GUID gEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+EFI_GUID gHobListGuid = HOB_LIST_GUID;
+EFI_GUID gEfiMpServicesGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+
+//Declaration of Boot Script Save module initializarion routine
+EFI_STATUS InitBootScript(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAcpiFacsTable
+//
+// Description:
+// This function returns address of memory where FACS ACPI table resides
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_PHYSICAL_ADDRESS - address of FACS table
+//
+// Notes:
+// The routine may fail if the FACS table is in a different location for
+// ACPI 1.0 and ACPI 2.0 (e.g. 1 above 4G and 1 below 4G). WIN98 will read the
+// RSDT, and WINXP will read the XSDT. If the XSDT and RSDT aren't pointing to
+// the same tables, a S3 resume failure will occur.
+// Currently, the variable from Intel only supports one FACS table.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID GetAcpiFacsTable(EFI_PHYSICAL_ADDRESS *FacsTable)
+{
+ RSDT_PTR_20 *RSDP = NULL;
+ RSDT_20 *RSDT = NULL;
+ XSDT_20 *XSDT = NULL;
+ FACP_20 *FADT = 0;
+ UINT32 i;
+ BOOLEAN Ver1 = FALSE;
+
+ // Initialize each pointer to 0
+ for (i = 0; i < 3; i++) FacsTable[i] = 0;
+
+ RSDP = GetEfiConfigurationTable(pST,&gAcpi20TableGuid);
+ if (!RSDP)
+ {
+ RSDP = GetEfiConfigurationTable(pST,&gAcpi11TAbleGuid);
+ Ver1 = TRUE;
+ }
+ if (!RSDP) return;
+
+ RSDT = (RSDT_20*)RSDP->RsdtAddr; // 32-bit pointer table
+ if (!Ver1) XSDT = (XSDT_20*)RSDP->XsdtAddr; // 64-bit pointer table.
+
+ // Get XSDT FACS Pointers
+ if (XSDT) {
+ UINT32 NumPtrs = (XSDT->Header.Length - sizeof(ACPI_HDR)) / 8;
+ for(i = 0; i < NumPtrs; ++i) {
+ if (((ACPI_HDR*)XSDT->Ptrs[i])->Signature == 'PCAF') {
+ FADT = (FACP_20*)XSDT->Ptrs[i];
+ FacsTable[0] = (EFI_PHYSICAL_ADDRESS)FADT->X_FIRMWARE_CTRL;
+ FacsTable[1] = (EFI_PHYSICAL_ADDRESS)FADT->FIRMWARE_CTRL;
+ break;
+ }
+ }
+ }
+
+ // Get RSDT FACS Pointer
+ if (RSDT) {
+ UINT32 NumPtrs = (RSDT->Header.Length - sizeof(ACPI_HDR)) / 4;
+ for(i = 0; i < NumPtrs; ++i) {
+ if (((ACPI_HDR*)RSDT->Ptrs[i])->Signature == 'PCAF') {
+ FADT = (FACP_20*)RSDT->Ptrs[i];
+ FacsTable[2] = (EFI_PHYSICAL_ADDRESS)FADT->FIRMWARE_CTRL;
+ break;
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CallbackReadyToBoot
+//
+// Description:
+// This function will be called when ReadyToBoot event will be signaled and
+// will update data, needed for S3 resume control flow.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CallbackReadyToBoot(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResDescHob;
+ ACPI_VARIABLE_SET *AcpiVariableSet;
+ EFI_PHYSICAL_ADDRESS AcpiMemoryBase;
+ EFI_PHYSICAL_ADDRESS ScriptAddress;
+ UINT64 SystemMemoryLength;
+ VOID *FirstHob;
+ EFI_STATUS Status;
+ UINTN NumCpus = 1;
+ EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF;
+
+ static BOOLEAN S3ResumeInfo = FALSE;
+ if (S3ResumeInfo) return;
+
+ //Get number of CPUs.
+ Status = pBS->LocateProtocol(
+ &gEfiMpServicesGuid,
+ NULL,
+ &gMpServices
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (!EFI_ERROR(Status)) {
+#if PI_SPECIFICATION_VERSION < 0x0001000A || BACKWARD_COMPATIBLE_MODE && defined(NO_PI_MP_SERVICES_SUPPORT)
+ Status = gMpServices->GetGeneralMPInfo(
+ gMpServices, &NumCpus, NULL, NULL, NULL, NULL
+ );
+#else
+ UINTN NumEnCpus;
+ Status = gMpServices->GetNumberOfProcessors(
+ gMpServices, &NumCpus, &NumEnCpus
+ );
+#endif
+
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ Status = pBS->AllocatePages(
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(sizeof(ACPI_VARIABLE_SET)),
+ &MaxAddress
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ AcpiVariableSet = (VOID*)(UINTN)MaxAddress;
+
+ pBS->SetMem(AcpiVariableSet, sizeof(ACPI_VARIABLE_SET),0);
+
+ Status = pBS->LocateProtocol(
+ &gEfiBootScriptSaveGuid,
+ NULL,
+ &gBootScriptSave
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBootScriptSave->CloseTable(
+ gBootScriptSave,
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ &ScriptAddress);
+ ASSERT_EFI_ERROR(Status);
+
+ // Allocate ACPI reserved memory for S3 resume.
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES(S3_BASE_MEMORY_SIZE + S3_MEMORY_SIZE_PER_CPU * NumCpus),
+ &AcpiMemoryBase
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ // Calculate the system memory length by memory hobs
+ SystemMemoryLength = 0x100000;
+
+ FirstHob = GetEfiConfigurationTable(pST,&gHobListGuid);
+ if (!FirstHob) ASSERT_EFI_ERROR(EFI_NOT_FOUND);
+
+ ResDescHob = (EFI_HOB_RESOURCE_DESCRIPTOR*) FirstHob;
+
+ //Find APIC ID Hob.
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,&ResDescHob)))
+ {
+ if (ResDescHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
+ {
+ if (ResDescHob->PhysicalStart >= 0x100000)
+ SystemMemoryLength += ResDescHob->ResourceLength;
+ }
+ }
+ if (SystemMemoryLength == 0x100000) ASSERT_EFI_ERROR(EFI_NOT_FOUND);
+
+ AcpiVariableSet->AcpiReservedMemoryBase = (EFI_PHYSICAL_ADDRESS)AcpiMemoryBase;
+ AcpiVariableSet->AcpiReservedMemorySize = S3_BASE_MEMORY_SIZE + S3_MEMORY_SIZE_PER_CPU * (UINT32)NumCpus;
+ AcpiVariableSet->AcpiBootScriptTable = (EFI_PHYSICAL_ADDRESS) ScriptAddress;
+ AcpiVariableSet->SystemMemoryLength = SystemMemoryLength;
+ GetAcpiFacsTable(&AcpiVariableSet->AcpiFacsTable[0]);
+
+ Status = pRS->SetVariable(
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32),
+ &AcpiVariableSet
+ );
+ //In case BIOS was updated with preserved NVRAM and AcpiGlobalVariable still has runtime attribute
+ if (Status == EFI_INVALID_PARAMETER)
+ {
+ Status = pRS->SetVariable(
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ 0,
+ 0,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pRS->SetVariable(
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32),
+ &AcpiVariableSet
+ );
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ S3ResumeInfo = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiS3SaveEntryPoint
+//
+// Description:
+// This function is ACPI S3 driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+//
+// Notes:
+// This function also creates ReadyToBoot event to save data
+// needed for S3 resume control flow.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiS3SaveEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //Initialize Boot Script Save module
+ Status = InitBootScript(ImageHandle,SystemTable);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/AcpiS3Save.dxs b/Core/EM/S3/AcpiS3Save.dxs
new file mode 100644
index 0000000..5aa1806
--- /dev/null
+++ b/Core/EM/S3/AcpiS3Save.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.dxs 1 2/03/11 4:08p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 2/03/11 4:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.dxs $
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/24/07 6:27p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiS3Save.dxs
+//
+// Description: Dependency expression for the AcpiS3Save component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/S3/AcpiS3Wake.asm b/Core/EM/S3/AcpiS3Wake.asm
new file mode 100644
index 0000000..642e5d5
--- /dev/null
+++ b/Core/EM/S3/AcpiS3Wake.asm
@@ -0,0 +1,339 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiS3Wake.asm 1 2/03/11 4:09p Oleksiyy $
+;
+; $Revision: 1 $
+;
+; $Date: 2/03/11 4:09p $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiS3Wake.asm $
+;
+; 1 2/03/11 4:09p Oleksiyy
+; [TAG] EIP53402
+; [Category] Improvement
+; [Description] Create new label of ACPI with separate S3 Functionality
+; [Files] S3Restore.cif
+; S3Restore.sdl
+; S3Restore.mak
+; S3Resume.dxs
+; AcpiS3Wake.asm
+; S3Resume.c
+; AcpiPeiS3Func.c
+; AcpiPeiS3Func.h
+; BootScriptExecuter.c
+;
+; 9 3/26/09 4:51p Oleksiyy
+; New ACPI Core implementation - improves logic, execution time and
+; memory usage of ACPI module.
+;
+; 8 4/29/08 5:36p Yakovlevs
+;
+; 7 4/15/08 12:28p Markw
+; Add cs overrides. Option rom may change ds.
+;
+; 6 1/23/07 4:24p Markw
+; Added thunk support for a call for S3 video repost.
+;
+; 5 5/27/05 4:18p Markw
+; Added comment.
+;
+; 4 5/10/05 3:00p Markw
+; Corrected wakeup vector address. Uses 16 bit data selector and adjusts
+; base of data selector to pointer to wake up vector.
+;
+; 3 5/09/05 10:19a Markw
+; Fixed cs and eip backwards. The OS is now given control.
+;
+; 2 5/07/05 11:54p Markw
+; Goes to real mode. But when resuming to windows cs and ip switched.
+; Will fix.
+;
+; 1 5/06/05 1:44p Markw
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: AcpiS3Wake.asm
+;
+; Description: Provide the thunk S3 resume.
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+.586P
+.model small
+include token.equ
+
+ACPI_S3_SEG SEGMENT USE32 'CODE'
+assume DS:ACPI_S3_SEG
+
+public _RealModeThunkStart
+public _RealModeThunkSize
+
+align 16
+;This code may be exexuted
+
+REAL_MODE_BASE equ (MKF_ACPI_THUNK_REAL_MODE_SEGMENT * 16)
+
+;<AMI_PHDR_START>
+;---------------------------------------------------------------------------
+;
+; Procedure: RealModeThunk
+;
+; Description: Switch to 16-bit to jump/call to an address.
+; This may be executed in place for a jump
+; or copied to a location if a call.
+;
+; Input:
+; GdtDesc:DWORD -- pointer descriptors with 16-bit.
+; JmpAddress: DWORD -- Address to jump or call to.
+; IsCall:BYTE -- TRUE - if call. FALSE - if jump.
+;
+;
+; Output: None
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+REAL_MODE_THUNK_START equ $
+RealModeThunk proc C public, GdtDesc:DWORD, JmpAddress: DWORD, IsCall:BYTE
+ pushad
+ call get_base_addr ;push the eip.
+get_base_addr:
+ pop ebx ;ebx = eip.
+ sub ebx, offset get_base_addr - REAL_MODE_THUNK_START ;ebx = Start address
+
+ cmp IsCall, 0
+ je @f
+
+ ;If call, this function will return, so save original state.
+ ;Save 32 bit stack address of this module.
+ ;mov [ebx + offset StackSave - REAL_MODE_THUNK_START], esp
+ db 89h, 0a3h
+ dd offset StackSave - REAL_MODE_THUNK_START
+ ;sgdt fword ptr [ebx + offset GdtSave - REAL_MODE_THUNK_START]
+ db 0fh, 1, 83h
+ dd offset GdtSave - REAL_MODE_THUNK_START
+ ;sidt fword ptr [ebx + offset IdtSave - REAL_MODE_THUNK_START]
+ db 0fh, 1, 8bh
+ dd offset IdtSave - REAL_MODE_THUNK_START
+@@:
+
+;--Switch to real mode--
+ ;lidt fword ptr [ebx + offset LegacyLdtDescriptor - REAL_MODE_THUNK_START]
+ db 0fh, 1, 9bh
+ dd offset LegacyLdtDescriptor - REAL_MODE_THUNK_START
+
+ mov edx, GdtDesc ;Get discriptor table with 16-bit descriptors.
+ mov ecx, [edx + 2] ;ecx = GDT Base
+
+ ;---Set the code selector base address of the memory location
+ ; to jump to 16-bit protected mode above 1MB for execute in place.
+ mov eax, offset Next
+ mov ebx, eax
+ and eax, 00ffffffh ;eax = [23:00] of next
+ shr ebx, 24 ;ebx = [31:24] of next
+
+ or [ecx + 8 + 2], eax ;GDT[1] (Code segment) base [23:00] of next
+ or [ecx + 8 + 7], bl ;GDT[1] base [24:31] of next
+
+ ;---Set the data selector base address of the memory location
+ ; that contains the location to jump to for thunking.
+ ; This is so 16-bit protected mode can read the jump address
+ ; on the caller stack above 1MB. This is needed because the
+ ; jump code will be executed in place.
+ ; For call code, this will not do anything useful.
+ lea edx, JmpAddress
+ mov ebx, edx
+ and edx, 00ffffffh ;edx = [23:00] address of wakeup vector
+ shr ebx, 24 ;ebx = [31:24] address of wakeup vector
+
+ or [ecx + 16 + 2], edx ;GDT[2] (Data segment) base [23:00] of next
+ or [ecx + 16 + 7], bl ;GDT[2] base [24:31] of next
+ ;---
+
+
+ xor esp, esp ;esp will be set to a non-zero if a call.
+ ;This will also to be used to determine
+ ; if call or not call. This is because
+ ; IsCall is not available in 16-bit mode.
+ cmp IsCall, 0
+ je @f
+
+ ;Set real mode stack except the linear stack address.
+ mov esp, REAL_MODE_BASE + MKF_ACPI_THUNK_STACK_TOP
+
+ ;-------------------------------------------------
+ ;Setup the stack to simulate a int xx or call.
+ ;-------------------------------------------------
+
+ mov eax, offset ReturnFromPtr
+ sub eax, REAL_MODE_THUNK_START ;ax = return address.
+
+ ;push the flags and return address to simulate the
+ ; return address on the stack for int xx or call.
+ pushf ;push flags in case intxx
+ push word ptr MKF_ACPI_THUNK_REAL_MODE_SEGMENT
+ push ax ;ax = return ip
+
+ ;push to stack the cs:ip of the address to call to
+ push JmpAddress ;push cs:eip to jump to.
+
+ ;-------------------------------------------------
+ ;Now the stack is setup, so that a retf will jump
+ ;to the address on stack.
+ ;-------------------------------------------------
+
+ ;Adjust the stack address, so it will be relative to ss.
+ sub esp, REAL_MODE_BASE
+@@:
+
+ ;---Switch to 16-bit protected mode---
+ mov edx, GdtDesc
+ lgdt fword ptr [edx]
+
+ ;ITP doesn't display disassembly correctly until jump to 16 bit code.
+ mov ax, 10h ;16 bit data segment
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ ;jmp 08:next
+ db 0eah
+ dd 0 ;offset of next with new selector
+ dw 08 ;16 bit code selector
+next:
+ ;---16 bit mode. Must use 16 bit instructions from here on.---
+ ;-------------------------------------------------------------
+
+ ;---Switch to real mode---
+ mov eax, cr0
+ and al, 0feh
+ mov cr0, eax ;switch to real mode
+ ;---In real mode---
+
+ db 66h
+ or esp, esp ;IsCall?
+ jnz @f
+
+ ;jmp far ptr [0] ;Jump to the address stored in ds:0.
+ db 0ffh, 2eh ;The descriptor's base is in stack.
+ dw 0
+ ;Does not return.
+@@:
+
+ ; jmp REAL_MODE_SEGMENT:real_mode_adr
+ db 0eah
+ dw offset real_mode_adr - REAL_MODE_THUNK_START
+ dw MKF_ACPI_THUNK_REAL_MODE_SEGMENT
+
+real_mode_adr:
+ db 8ch, 0c8h ;mov ax, cs
+ db 8eh, 0d8h ;mov ds, ax
+ db 8eh, 0c0h ;mov es, ax
+ db 8eh, 0d0h ;mov ss, ax
+ db 8eh, 0e0h ;mov fs, ax
+ db 8eh, 0e8h ;mov gs, ax
+
+ retf ;call JmpAddress on stack.
+
+ReturnFromPtr:
+;--------------End Real Mode operations---------
+
+ ;--Switch to protected mode--
+
+ ;mov esp, cs:[offset StackSave - REAL_MODE_THUNK_START] ;Get original stack back.
+ db 2eh, 66h, 8bh, 26h
+ dw offset StackSave - REAL_MODE_THUNK_START
+
+ ;lgdt fword ptr cs:[offset GdtSave - REAL_MODE_THUNK_START]
+ db 2eh, 66h, 0fh, 1, 16h
+ dw offset GdtSave - REAL_MODE_THUNK_START
+
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+ ;jmp 10:P32MODE
+ db 66h, 0eah
+ dd REAL_MODE_BASE + offset P32Mode - REAL_MODE_THUNK_START
+ dw 10h
+P32Mode::
+ mov ax, 08
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ ;lidt fword ptr [REAL_MODE_BASE + offset IdtSave - REAL_MODE_THUNK_START]
+ db 0fh, 1, 1dh
+ dd REAL_MODE_BASE + offset IdtSave - REAL_MODE_THUNK_START
+ popad
+ ret
+RealModeThunk endp
+
+align 8
+ public LegacyLdtDescriptor
+LegacyLdtDescriptor label fword
+ dw 3ffh
+ dd 0
+
+;Note: The following below is only used in a call when this is copied to below 1MB.
+;The data below can not be changed when this is executed from ROM.
+
+ public StackSave
+StackSave label dword
+ dd 0
+
+align 8
+ public GdtSave
+GdtSave label fword
+ dw 0
+ dd 0
+
+align 8
+ public IdtSave
+IdtSave label fword
+ dw 0
+ dd 0
+
+REAL_MODE_THUNK_END EQU $
+
+_RealModeThunkStart label dword
+ dd REAL_MODE_THUNK_START
+
+_RealModeThunkSize label dword
+ dd REAL_MODE_THUNK_END - REAL_MODE_THUNK_START
+
+ACPI_S3_SEG ENDS
+end
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/S3/BootScriptExecuter.c b/Core/EM/S3/BootScriptExecuter.c
new file mode 100644
index 0000000..35ac423
--- /dev/null
+++ b/Core/EM/S3/BootScriptExecuter.c
@@ -0,0 +1,1053 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptExecuter.c 2 9/17/13 10:02p Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/17/13 10:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptExecuter.c $
+//
+// 2 9/17/13 10:02p Thomaschen
+// update for ACPI module labeled 47
+//
+// 8 12/13/12 12:03p Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 7 9/29/11 5:05p Oleksiyy
+// [TAG] EIP71372
+// [Category] Improvement
+// [Description] EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE added.
+// [Files] BootScriptExecuter.c and BootScriptSave.c
+//
+// 6 7/19/11 11:34a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 5 6/01/11 10:27a Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// backward compatibility improved.
+// [Files] BootScriptExecuter.c
+//
+// 4 5/19/11 10:40a Oleksiyy
+// [TAG] EIP60727
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Dispatch opcode invalid
+// [RootCause] Dispatch opcode realization was commented out mistakenly.
+// [Solution] Commented out code restored.
+// [Files] BootScriptExecuter.c
+//
+// 3 5/13/11 3:23p Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// functions added. Support for opcodes introduced in PI 1.2 added.
+// [Files] BootScriptCommon.h, BootScriptExecuter.c,
+// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h
+//
+// 2 3/18/11 3:51p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Improving backward computability and architecture.
+// [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak,
+// S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h,
+// S3smmSaveState.h
+//
+// 2 3/09/11 6:09p Artems
+//
+// 1 3/09/11 6:09p Artems
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 11 3/04/10 2:06p Oleksiyy
+// EIP 35847: Bug Fix
+//
+// 10 11/05/09 4:00p Oleksiyy
+// EIP 27821 Support for 64 bit operations in Bootscript added. To use
+// this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, x64AsmLib.asm
+// files should be updated also.
+//
+// 9 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 8 10/10/08 8:16p Felixp
+// Performance measurement support added
+//
+// 6 6/06/08 11:54a Felixp
+// Performance measurement support added
+//
+// 5 4/16/08 12:10p Yakovlevs
+// fixed compilation issue
+//
+// 4 4/15/08 9:20p Yakovlevs
+// Functions Headers added; Removed definition of EFI_BOOT_SCRIPT WDTH
+//
+// 3 6/07/07 3:09p Felixp
+//
+// 2 6/05/07 12:17a Felixp
+// Added SmmBus support
+//
+// 1 4/23/07 1:31p Felixp
+//
+// 15 12/26/06 2:56p Markw
+// Add BootScript Polling.
+//
+// 14 11/22/06 4:35p Markw
+// Move certain Mem/Io write trace statments before instead of after the
+// write. This is so if the write causes a hang, it can be seen on serial
+// redirection.
+//
+// 13 9/22/06 6:08p Markw
+// 64-bit fix.
+//
+// 12 3/15/06 2:41p Markw
+//
+// 11 3/15/06 2:37p Markw
+// Fixed bug, used value instead of Mask.
+//
+// 10 3/13/06 9:51a Felixp
+//
+// 9 10/09/05 11:25a Felixp
+// Performance measurements added.
+//
+// 8 6/23/05 5:37p Markw
+// Added defintions from Boot Script Save Protocol.
+//
+// 7 6/15/05 4:20p Markw
+// Modified dispatch function to pass in PeiServices.
+//
+// 6 6/06/05 7:49p Felixp
+//
+// 5 6/06/05 1:26p Felixp
+// Usage of CPU I/O and PCI Cfg changed to match PEI CIS 0.91
+//
+// 4 5/27/05 1:36a Felixp
+//
+// 3 5/16/05 3:03p Markw
+// Added more trace messages.
+//
+// 2 4/04/05 2:38p Markw
+// Fix write to pci register bug.
+// Add temporary trace statements.
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BootScriptExecuter.c
+//
+// Description: Boot script execution support functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Ppi\BootScriptExecuter.h>
+#include <Ppi\CpuIo.h>
+#include <Ppi\PciCfg2.h>
+#if PI_SPECIFICATION_VERSION>=0x10000
+#include <Ppi\Smbus2.h>
+#else
+#include <Ppi\Smbus.h>
+#endif
+#include <Ppi\Stall.h>
+#include "BootScriptPrivate.h"
+#include <AmiPeiLib.h>
+
+#if (CORE_REVISION >= 0x5)
+#include <BootScriptCommon.h>
+#else
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+//*******************************************
+// EFI Save State Script Opcode definitions (PI)
+//*******************************************
+
+#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00
+#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01
+#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02
+#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05
+#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06
+#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07
+#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08
+
+#define EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE 0x09
+#define EFI_BOOT_SCRIPT_INFORMATION_OPCODE 0x0A
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE 0x0B
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE 0x0C
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE 0x0D
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE 0x0E
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE 0x0F
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE 0x10
+#define EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM 0x83
+
+#else
+//*******************************************
+// EFI Boot Script Opcode definitions (Framework)
+//*******************************************
+
+#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00
+#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01
+#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02
+#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05
+#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06
+#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07
+#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08
+
+#endif
+//
+// Extensions to boot script definitions
+//
+//OEM
+#ifndef EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM 0x80
+#endif
+
+#ifndef EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM 0x81
+#endif
+
+#ifndef EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM 0x82
+#endif
+
+
+
+#define EFI_BOOT_SCRIPT_TABLE_OPCODE 0xAA
+#define EFI_BOOT_SCRIPT_TERMINATE_OPCODE 0xFF
+
+
+
+//*******************************************
+// EFI_BOOT_SCRIPT_WIDTH
+//*******************************************
+typedef enum {
+ EfiBootScriptWidthUint8,
+ EfiBootScriptWidthUint16,
+ EfiBootScriptWidthUint32,
+ EfiBootScriptWidthUint64,
+ EfiBootScriptWidthFifoUint8,
+ EfiBootScriptWidthFifoUint16,
+ EfiBootScriptWidthFifoUint32,
+ EfiBootScriptWidthFifoUint64,
+ EfiBootScriptWidthFillUint8,
+ EfiBootScriptWidthFillUint16,
+ EfiBootScriptWidthFillUint32,
+ EfiBootScriptWidthFillUint64,
+ EfiBootScriptWidthMaximum
+} EFI_BOOT_SCRIPT_WIDTH;
+
+#endif //#if (CORE_REVISION >= 0x5)
+
+typedef EFI_STATUS (EFIAPI *DISPATCH_ENTRYPOINT_FUNC) (
+ IN EFI_HANDLE ImageHandle,
+ IN VOID* Context
+);
+
+
+EFI_GUID gBootScriptExecuterGuid = EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID;
+#if PI_SPECIFICATION_VERSION>=0x10000
+EFI_GUID gSmBusGuid = EFI_PEI_SMBUS2_PPI_GUID;
+#else
+EFI_GUID gSmBusGuid = EFI_PEI_SMBUS_PPI_GUID;
+#endif
+EFI_GUID gStallGuid = EFI_PEI_STALL_PPI_GUID;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciRegAdd
+//
+// Description: Increase the Pci register number by a value.
+//
+// Input:
+// IN UINT64 Address - Pci Address
+// IN UINT8 ValueSize - Add value to register.
+//
+// Output:
+// UINT64 New Pci Address.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get extended register.
+// 2. If extended register, increment it by ValueSize
+// else increment the non-extended register.
+// 3. Return the Address.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT64 PciRegAdd(UINT64 Address,UINT8 ValueSize)
+{
+ UINT32 ExtReg;
+
+ ExtReg = (UINT32) (*((UINT32*)&Address +1));
+ if (ExtReg)
+ (*((UINT32*)&Address + 1)) += ValueSize;
+
+ else (*(UINT8*)&Address) = (*(UINT8*)&Address) + ValueSize;
+
+ return Address;
+}
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x0001000A)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SwitchPciCfgPpi
+//
+// Description: Serchs for PCI_CFG2_PPI with corresponding Segment
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN UINT16 SegmentSwitchTo
+
+//
+// Output:
+// EFI_PEI_PCI_CFG2_PPI* Pointer to Pci Cfg PPI with Segment wanted
+// NULL if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_PEI_PCI_CFG2_PPI* SwitchPciCfgPpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 SegmentSwitchTo
+ )
+{
+ UINT32 i = 0;
+ EFI_GUID PciCfg2PpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID;
+ EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi;
+ EFI_STATUS Status;
+ while (TRUE) {
+
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &PciCfg2PpiGuid, i, NULL, &PciCfg2Ppi );
+
+ if ( EFI_ERROR( Status ) ) {
+ break;
+ }
+
+ if (PciCfg2Ppi->Segment == SegmentSwitchTo) //We found PPI we need
+ return PciCfg2Ppi; //return pointer
+ i++;
+ }
+ return NULL;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ExecuteScript
+//
+// Description:
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *This
+// IN EFI_PHYSICAL_ADDRESS Address
+// IN EFI_GUID *FvFile OPTIONAL
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Locate Ppis: CpuIo PciCfg SmBus.
+// 2. If any of the Ppis doesn't exist return EFI_UNSUPPORTED.
+// ---Execute table Script---
+// 3. Read Opcode type:
+// a. EFI_BOOT_SCRIPT_IO_WRITE_OPCODE
+// b. EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE
+// etc.
+// If TABLE_END_OP_CODE, return EFI_SUCCESS.
+// If unknown opcode return EFI_UNSUPPORTED.
+//
+// 4. Copy the Opcode type to its structure. Structure will be aligned.
+// 5. If it has a buffer, get Buffer address in table.
+// 6. Get address of in table for next Opcode.
+// 7. Call appropriate Ppi for OpCode with parameters from the structure.
+//
+// Check BootScript spec for better understanding of code.
+// Note for writes there are EfiBootScriptWidthUintxx,
+// EfiBootScriptWidthFifoUintxx, and EfiBootScriptWidthFillUintxx.
+// xx Denotes 8,16,32,or 64(unsupported).
+//
+// 8. Go to step 3.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ExecuteScript(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *This,
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN EFI_GUID *FvFile OPTIONAL
+ )
+{
+ VOID *TableAddr = (VOID *)(UINTN) Address;
+ BOOT_SCRIPT_DATA BootScript;
+ UINT16 Type;
+ UINT32 AddressCount;
+ UINT8 ValueSize;
+ UINT8 Width;
+ UINT64 Count;
+ VOID *Buffer;
+// UINT32 Value32;
+ UINT64 Value64;
+ UINTN i;
+
+ EFI_STATUS Status;
+
+ EFI_PEI_CPU_IO_PPI *CpuIoPpi;
+
+ EFI_PEI_PCI_CFG2_PPI *PciCfgPpi;
+#if PI_SPECIFICATION_VERSION>=0x1000A
+ BOOLEAN Pi12Spec = FALSE;
+ UINT64 PollDelay;
+#endif
+#if PI_SPECIFICATION_VERSION>=0x10000
+ EFI_PEI_SMBUS2_PPI *SmBusPpi;
+#else
+ EFI_PEI_SMBUS_PPI *SmBusPpi;
+#endif
+ EFI_PEI_STALL_PPI *StallPpi;
+
+ if (FvFile) return EFI_UNSUPPORTED;
+ if (!Address) return EFI_INVALID_PARAMETER;
+
+ CpuIoPpi = (*PeiServices)->CpuIo;
+ PciCfgPpi = (*PeiServices)->PciCfg;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gSmBusGuid,
+ 0,
+ NULL,
+ &SmBusPpi
+ );
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gStallGuid,
+ 0,
+ NULL,
+ &StallPpi
+ );
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ for(;;) {
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"UniqueIndex %x\n", ((BOOT_SCRIPT_INFO_STRUCTURE*) TableAddr)->UniqueIndex));
+ TableAddr = (UINT8*) TableAddr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+#endif
+ Type = *(UINT8*) TableAddr + (*((UINT8*) TableAddr + 1) << 8); //In case not aligned if alignment required.
+ switch(Type&0xff) {
+ case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_IO));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_IO);
+
+ Width = (UINT8)(BootScript.WrIo.Type >> 8);
+ ValueSize = 1 << (Width & 3);
+ Count = BootScript.WrIo.Count;
+ Buffer = TableAddr;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1);
+ TableAddr = (UINT8*)TableAddr + AddressCount;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Io Write %x=", BootScript.WrIo.Port));
+#ifdef EFI_DEBUG
+ switch(ValueSize) {
+ case 1:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer));
+ break;
+ case 2:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer));
+ break;
+ case 4:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer));
+ break;
+ case 8:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer));
+ break;
+ default:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n"));
+ }
+#endif
+ CpuIoPpi->Io.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.WrIo.Port,
+ (UINTN)Count,
+ Buffer);
+ break;
+ case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_IO));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_IO);
+
+ Width = (UINT8)((BootScript.WrIo.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ CpuIoPpi->Io.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwIo.Port,
+ 1,
+ &Value64);
+
+ Value64 &= BootScript.RwIo.Mask;
+ Value64 |= BootScript.RwIo.Value;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Io R/Write %x=%x\n", BootScript.WrIo.Port,Value64));
+ CpuIoPpi->Io.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwIo.Port,
+ 1,
+ &Value64);
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_IO_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_IO_POLL);
+ PollDelay = Div64(BootScript.IoPoll.Delay, 10, NULL) + 1; // converting x100 ns units to ms, used in stall
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"IO Poll Delay %lx *100ns\n", BootScript.IoPoll.Delay));
+ Pi12Spec = TRUE;
+#endif
+ case EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_IO));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_IO);
+ }
+ Width = (UINT8)((BootScript.PollIo.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,
+ "Io Poll: Port = %x, Mask = %lx, Result = %lx\n",
+ BootScript.PollIo.Port,
+ BootScript.PollIo.Mask,
+ BootScript.PollIo.Result
+ ));
+
+ do {
+ CpuIoPpi->Io.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.PollIo.Port,
+ 1,
+ &Value64);
+ Value64 &= BootScript.PollIo.Mask;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ StallPpi->Stall(PeiServices, StallPpi, 1);
+ if (--PollDelay == 0) // delay criteria meet
+ Value64 = BootScript.PollIo.Result; //terminate cycle
+ }
+#endif
+ } while (Value64 != BootScript.PollIo.Result);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Pi12Spec = FALSE;
+#endif
+ break;
+
+ case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_MEM));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_MEM);
+ Buffer = TableAddr;
+
+ Width = (UINT8)(BootScript.WrMem.Type >> 8);
+ ValueSize = 1 << (Width & 3);
+ Count = BootScript.WrMem.Count;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1);
+ TableAddr = (UINT8*)TableAddr + AddressCount;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Write %lx=", BootScript.WrMem.Address));
+#ifdef EFI_DEBUG
+ switch(ValueSize) {
+ case 1:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer));
+ break;
+ case 2:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer));
+ break;
+ case 4:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer));
+ break;
+ case 8:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer));
+ break;
+ default:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n"));
+ }
+#endif
+ CpuIoPpi->Mem.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.WrMem.Address,
+ (UINTN)Count,
+ Buffer);
+ break;
+ case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_MEM));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_MEM);
+
+ Width = (UINT8)((BootScript.WrMem.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ CpuIoPpi->Mem.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwMem.Address,
+ 1,
+ &Value64);
+
+ Value64 &= BootScript.RwMem.Mask;
+ Value64 |= BootScript.RwMem.Value;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem R/Write %lx=%x\n", BootScript.WrMem.Address,(UINT32)Value64));
+ CpuIoPpi->Mem.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwMem.Address,
+ 1,
+ &Value64);
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_MEM_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_MEM_POLL);
+ PollDelay = BootScript.MemPoll.LoopTimes + 1;
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Poll Delay %lx \n", BootScript.MemPoll.Delay));
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Poll Loop Times %lx \n", BootScript.MemPoll.LoopTimes));
+ Pi12Spec = TRUE;
+#endif
+ case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_MEM));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_MEM);
+ }
+ Width = (UINT8)((BootScript.PollMem.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,
+ "Mem Poll: Address = %lx, Mask = %lx, Result = %lx\n",
+ BootScript.PollMem.Address,
+ BootScript.PollMem.Mask,
+ BootScript.PollMem.Result
+ ));
+
+ do {
+ CpuIoPpi->Mem.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.PollMem.Address,
+ 1,
+ &Value64);
+
+ Value64 &= BootScript.PollMem.Mask;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ UINTN Delay = (UINTN)BootScript.MemPoll.Delay;
+
+ StallPpi->Stall(PeiServices, StallPpi, Delay);
+ if (--PollDelay == 0) // delay criteria meet
+ {
+ PEI_TRACE((TRACE_ALWAYS, PeiServices,
+ "Mem Poll: Address = %lx, Mask = %lx, Result = %lx\n",
+ BootScript.PollMem.Address, BootScript.PollMem.Mask, Value64));
+ break;
+ }
+ }
+#endif
+
+ } while (Value64 != BootScript.PollMem.Result);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Pi12Spec = FALSE;
+#endif
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE);
+ if (BootScript.WrPci2.Segment != 0)
+ PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.WrPci2.Segment);
+ if (PciCfgPpi == NULL)
+ {
+ PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.WrPci2.Segment));
+ return EFI_UNSUPPORTED;
+ }
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Write to Segment %x\n = ", BootScript.WrPci2.Segment));
+ Pi12Spec = TRUE;
+
+#endif
+ case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_PCI));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_PCI);
+ }
+ Width = (UINT8)(BootScript.WrPci.Type >> 8);
+ ValueSize = 1 << (Width & 3);
+ Count = BootScript.WrPci.Count;
+
+ Buffer = TableAddr;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1);
+ TableAddr = (UINT8*)TableAddr + AddressCount;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Pci Write %lx=", BootScript.WrPci.Address));
+#ifdef EFI_DEBUG
+ switch(ValueSize) {
+ case 1:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer));
+ break;
+ case 2:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer));
+ break;
+ case 4:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer));
+ break;
+ case 8:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer));
+ break;
+ default:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n"));
+ }
+#endif
+ for (i = 0; i < Count; ++i)
+ {
+ Status = PciCfgPpi->Write(PeiServices,
+ PciCfgPpi,
+ Width & 3,
+ BootScript.WrPci.Address,
+ Buffer);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ switch(Width & ~3)
+ {
+ case EfiBootScriptWidthUint8:
+ Buffer = (UINT8*)Buffer + AddressCount;
+ BootScript.WrPci.Address = PciRegAdd(BootScript.WrPci.Address,ValueSize);
+ break;
+ case EfiBootScriptWidthFifoUint8:
+ Buffer = (UINT8*)Buffer + AddressCount;
+ break;
+ case EfiBootScriptWidthFillUint8:
+ BootScript.WrPci.Address = PciRegAdd(BootScript.WrPci.Address,ValueSize);
+ }
+ }
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ Pi12Spec = FALSE;
+ PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer
+ }
+#endif
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE);
+ if (BootScript.RwPci2.Segment != 0)
+ PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.RwPci2.Segment);
+ if (PciCfgPpi == NULL)
+ {
+ PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.RwPci2.Segment));
+ return EFI_UNSUPPORTED;
+ }
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Read/Write to Segment %x\n = ", BootScript.RwPci2.Segment));
+ Pi12Spec = TRUE;
+#endif
+ case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_PCI));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_PCI);
+ }
+ Width = (UINT8)((BootScript.RwPci.Type >> 8) & 3);
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Pci R/Write %x\n", BootScript.RwPci.Address));
+
+ Status = PciCfgPpi->Read(PeiServices,
+ PciCfgPpi,
+ Width,
+ BootScript.RwPci.Address,
+ &Value64
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ Value64 = BootScript.RwPci.Value | (Value64 & BootScript.RwPci.Mask);
+
+ Status = PciCfgPpi->Write(PeiServices,
+ PciCfgPpi,
+ Width,
+ BootScript.RwPci.Address,
+ &Value64
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ Pi12Spec = FALSE;
+ PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer
+ }
+#endif
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_POLL);
+ if (BootScript.PciPoll2.Segment != 0)
+ PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.PciPoll2.Segment);
+ if (PciCfgPpi == NULL)
+ {
+ PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.PciPoll2.Segment));
+ return EFI_UNSUPPORTED;
+ }
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Poll to Segment %x\n = ", BootScript.PciPoll2.Segment));
+ Pi12Spec = TRUE;
+
+ case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:
+ if (!Pi12Spec)
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG_POLL);
+ Pi12Spec = TRUE;
+ }
+ PollDelay = Div64(BootScript.PciPoll.Delay, 10, NULL) + 1; // converting x100 ns units to ms, used in stall
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg Poll Delay %lx *100ns\n", BootScript.PciPoll.Delay));
+#endif
+ case EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_PCI));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_PCI);
+ }
+ Width = (UINT8)((BootScript.PollPci.Type >> 8) & 3);
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,
+ "PCI Poll: Address = %x, Mask = %lx, Result = %lx\n",
+ BootScript.PollPci.Address,
+ BootScript.PollPci.Mask,
+ BootScript.PollPci.Result
+ ));
+
+ do {
+ PciCfgPpi->Read(PeiServices,
+ PciCfgPpi,
+ Width,
+ BootScript.PollPci.Address,
+ &Value64
+ );
+ Value64 &= BootScript.PollPci.Mask;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ StallPpi->Stall(PeiServices, StallPpi, 1);
+ if (--PollDelay == 0) // delay criteria meet
+ Value64 = BootScript.PollPci.Result; //terminate cycle
+ }
+#endif
+ } while (Value64 != BootScript.PollPci.Result);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ Pi12Spec = FALSE;
+ PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer
+ }
+#endif
+ break;
+
+ case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_SMBUS_EXECUTE));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_SMBUS_EXECUTE);
+ Buffer = TableAddr;
+ TableAddr = (UINT8*)TableAddr + BootScript.ExecSmbus.Length;
+
+ PEI_TRACE((-1,PeiServices,
+ "Smbus: Address = %x, Command = %x Operation = %x\n",
+ BootScript.ExecSmbus.SlaveAddress,
+ BootScript.ExecSmbus.Command,
+ BootScript.ExecSmbus.Operation
+ ));
+
+ //Note: In specification, the length pointer is a IN/OUT.
+ //However, I do find that its contents updated.
+ SmBusPpi->Execute(
+#if PI_SPECIFICATION_VERSION<0x10000
+ PeiServices,
+#endif
+ SmBusPpi,
+ BootScript.ExecSmbus.SlaveAddress,
+ BootScript.ExecSmbus.Command,
+ BootScript.ExecSmbus.Operation,
+ BootScript.ExecSmbus.PecCheck,
+ (UINTN*)&BootScript.ExecSmbus.Length,
+ Buffer
+ );
+ break;
+
+ case EFI_BOOT_SCRIPT_STALL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_STALL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_STALL);
+
+ StallPpi->Stall(PeiServices,
+ StallPpi,
+ (UINTN)BootScript.Stall.Duration);
+ break;
+
+ case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
+ PEI_TRACE((-1,PeiServices,"Dispatch Opcode.\n"));
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_DISPATCH));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_DISPATCH);
+ ((DISPATCH_ENTRYPOINT_FUNC)(UINTN)BootScript.Dispatch.EntryPoint)(NULL, PeiServices);
+ break;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+ case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_DISPATCH2));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_DISPATCH2);
+ ((DISPATCH_ENTRYPOINT_FUNC)(UINTN)BootScript.Dispatch.EntryPoint)(NULL, PeiServices);
+ break;
+
+ case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_INFORMATION);
+ PEI_TRACE((-1,PeiServices,"Skipping Information opcode in Boot Script.\n"));
+ break;
+ case EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM:
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_LABEL)
+ + ((BOOT_SCRIPT_LABEL*)TableAddr)->Size;
+ PEI_TRACE((-1,PeiServices,"Skipping Label opcode in Boot Script.\n"));
+ break;
+
+#endif
+ case TABLE_END_OP_CODE:
+ PEI_TRACE((-1,PeiServices,"Table End Found.\n"));
+ return EFI_SUCCESS;
+
+
+ default:
+ PEI_TRACE((-1,PeiServices,"Boot Script Table Invalid. Type = %x\n", Type));
+ return EFI_UNSUPPORTED;
+ }
+ }
+}
+
+
+EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI gBootScriptExecuterPpi =
+{
+ ExecuteScript
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR gPpiList =
+{
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gBootScriptExecuterGuid,
+ &gBootScriptExecuterPpi
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InitBootScriptExecuter
+//
+// Description: Increase the Pci register number by a value.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InstallPpi
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Install Boot Script Executer Ppi.
+// 2. Return status of InstallPpi.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBootScriptExecuter(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ return (**PeiServices).InstallPpi(
+ PeiServices,
+ &gPpiList
+ );
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/BootScriptPrivate.h b/Core/EM/S3/BootScriptPrivate.h
new file mode 100644
index 0000000..b3c8c63
--- /dev/null
+++ b/Core/EM/S3/BootScriptPrivate.h
@@ -0,0 +1,732 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptPrivate.h 2 9/17/13 10:02p Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/17/13 10:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptPrivate.h $
+//
+// 2 9/17/13 10:02p Thomaschen
+// update for ACPI module labeled 47
+//
+// 3 7/01/11 10:03a Oleksiyy
+// [TAG] EIP62200
+// [Category] Improvement
+// [Description] Added #pragma statements to declaration of
+// BOOT_SCRIPT_SMBUS_EXECUTE_32 and BOOT_SCRIPT_SMBUS_EXECUTE structures.
+// [Files] BootScriptPrivate.c
+//
+// 2 5/13/11 3:18p Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// functions added. Support for opcodes introduced in PI 1.2 added.
+// [Files] BootScriptCommon.h, BootScriptExecuter.c,
+// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 5 11/05/09 4:00p Oleksiyy
+// EIP 27821 Support for 64 bit operations in Bootscript added.
+// To use this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c,
+// x64AsmLib.asm files should be updated also.
+//
+// 4 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 3 12/01/08 6:17p Yakovlevs
+// Fixed isue with UINTN SMBUS_ADDRESS in PEI UINTN=32bit; in DXE UINTN
+// for x64 = 64bit.
+//
+// 2 4/15/08 9:16p Yakovlevs
+// Functions Headers added
+//
+// 1 4/23/07 1:31p Felixp
+//
+// 4 12/26/06 2:56p Markw
+// Add BootScript Polling.
+//
+// 3 9/22/06 6:09p Markw
+// 64-bit fix.
+//
+// 2 6/23/05 5:38p Markw
+// Remove include from boot script save protocol.
+//
+// 1 1/21/05 12:01p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 3 3/25/04 11:23a Markw
+// Remove lib include.
+//
+// 2 3/23/04 4:57p Felixp
+//
+// 1 3/04/04 3:52p Markw
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: BootScriptPrivate.h
+//
+// Description: Boot script auxiliary data structures definitions
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __BOOT_SCRIPT_PRIVATE__H__
+#define __BOOT_SCRIPT_PRIVATE__H__
+
+#include <efi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TABLE_TYPE1(OpCode) (OpCode)
+#define TABLE_TYPE2(OpCode, Width) ((OpCode) + ((Width) << 8))
+
+#define TABLE_END_OP_CODE 0xff
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_WRITE_IO
+//
+// Description: Boot script Write IO Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Count;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_WRITE_IO;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_READ_WRITE_IO
+//
+// Description: Boot script Read-Write IO Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Value UINT32
+// Mask UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Value;
+ UINT64 Mask;
+} BOOT_SCRIPT_READ_WRITE_IO;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_POLL_IO
+//
+// Description: Boot script Poll IO Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Mask UINT32
+// Result UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Mask;
+ UINT64 Result;
+} BOOT_SCRIPT_POLL_IO;
+
+
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_WRITE_MEM
+//
+// Description: Boot script Write memory Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT8
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+// UINT8 Value;
+ UINT64 Count;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_WRITE_MEM;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_READ_WRITE_MEM
+//
+// Description: Boot script Read-Write memory Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT64
+// Mask UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Value;
+ UINT64 Mask;
+} BOOT_SCRIPT_READ_WRITE_MEM;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_POLL_MEM
+//
+// Description: Boot script Poll memory Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+} BOOT_SCRIPT_POLL_MEM;
+
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_WRITE_PCI
+//
+// Description: Boot script Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Count;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_WRITE_PCI;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_READ_WRITE_PCI
+//
+// Description: Boot script Read-Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT64
+// Mask UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Value;
+ UINT64 Mask;
+} BOOT_SCRIPT_READ_WRITE_PCI;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_POLL_PCI
+//
+// Description: Boot script Poll PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+} BOOT_SCRIPT_POLL_PCI;
+
+#pragma pack(push,1)
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_SMBUS_EXECUTE
+//
+// Description: Boot script SMBUS command Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// SlaveAddress EFI_SMBUS_DEVICE_ADDRESS
+// Command EFI_SMBUS_DEVICE_COMMAND
+// Operation EFI_SMBUS_OPERATION
+// PecCheck BOOLEAN
+// Length UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_SMBUS_DEVICE_COMMAND Command;
+ EFI_SMBUS_OPERATION Operation;
+ BOOLEAN PecCheck;
+ UINT64 Length;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_SMBUS_EXECUTE;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_SMBUS_EXECUTE_32
+//
+// Description: Boot script SMBUS command Data (32 Bit)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// SlaveAddress UINT32
+// Command UINT32
+// Operation EFI_SMBUS_OPERATION
+// PecCheck BOOLEAN
+// Length UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT32 SlaveAddress;
+ UINT32 Command;
+ EFI_SMBUS_OPERATION Operation;
+ BOOLEAN PecCheck;
+ UINT64 Length;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_SMBUS_EXECUTE_32;
+#pragma pack(pop)
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_STALL
+//
+// Description: Boot script stall Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Duration UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Duration;
+} BOOT_SCRIPT_STALL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_DISPATCH
+//
+// Description: Boot script dispatch Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// EntryPoint EFI_PHYSICAL_ADDRESS
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+} BOOT_SCRIPT_DISPATCH;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_INFORMATION
+//
+// Description: Boot script information Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Size UINT32
+// MessagePtr EFI_PHYSICAL_ADDRESS
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS MessagePtr;
+} BOOT_SCRIPT_INFORMATION;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_DISPATCH2
+//
+// Description: Boot script Dispatch2 Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// EntryPoint EFI_PHYSICAL_ADDRESS
+// Context EFI_PHYSICAL_ADDRESS
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ EFI_PHYSICAL_ADDRESS Context;
+} BOOT_SCRIPT_DISPATCH2;
+
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG2_WRITE
+//
+// Description: Boot script Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Count;
+ UINT16 Segment;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_PCI_CFG2_WRITE;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG2_READ_WRITE
+//
+// Description: Boot script Read-Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT64
+// Mask UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Value;
+ UINT64 Mask;
+ UINT16 Segment;
+} BOOT_SCRIPT_PCI_CFG2_READ_WRITE;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_IO_POLL
+//
+// Description: Boot script Poll IO Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Mask UINT32
+// Result UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+} BOOT_SCRIPT_IO_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_MEM_POLL
+//
+// Description: Boot script Poll memory Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+ UINT64 LoopTimes;
+} BOOT_SCRIPT_MEM_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG_POLL
+//
+// Description: Boot script Poll PCI Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+} BOOT_SCRIPT_PCI_CFG_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG2_POLL
+//
+// Description: Boot script Poll PCI Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+ UINT16 Segment;
+} BOOT_SCRIPT_PCI_CFG2_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_LABEL
+//
+// Description: Boot script information Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Size UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT32 Size;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_LABEL;
+
+typedef struct {
+ UINT32 UniqueIndex;
+ UINT32 Length;
+} BOOT_SCRIPT_INFO_STRUCTURE;
+#endif
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_TABLE_END
+//
+// Description: Boot script end table marker
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+} BOOT_SCRIPT_TABLE_END;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_DATA
+//
+// Description: Boot script data union
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// WrIo BOOT_SCRIPT_WRITE_IO
+// RwIo BOOT_SCRIPT_READ_WRITE_IO
+// PollIo BOOT_SCRIPT_POLL_IO
+// WrMem BOOT_SCRIPT_WRITE_MEM
+// RwMem BOOT_SCRIPT_READ_WRITE_MEM
+// PollMem BOOT_SCRIPT_POLL_MEM
+// WrPci BOOT_SCRIPT_WRITE_PCI
+// RwPci BOOT_SCRIPT_READ_WRITE_PCI
+// PollPci BOOT_SCRIPT_POLL_PCI
+// ExecSmbus BOOT_SCRIPT_SMBUS_EXECUTE
+// Stall BOOT_SCRIPT_STALL
+// Dispatch BOOT_SCRIPT_DISPATCH
+// End BOOT_SCRIPT_TABLE_END
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef union {
+ BOOT_SCRIPT_WRITE_IO WrIo;
+ BOOT_SCRIPT_READ_WRITE_IO RwIo;
+ BOOT_SCRIPT_POLL_IO PollIo;
+ BOOT_SCRIPT_WRITE_MEM WrMem;
+ BOOT_SCRIPT_READ_WRITE_MEM RwMem;
+ BOOT_SCRIPT_POLL_MEM PollMem;
+ BOOT_SCRIPT_WRITE_PCI WrPci;
+ BOOT_SCRIPT_READ_WRITE_PCI RwPci;
+ BOOT_SCRIPT_POLL_PCI PollPci;
+ BOOT_SCRIPT_SMBUS_EXECUTE ExecSmbus;
+ BOOT_SCRIPT_STALL Stall;
+ BOOT_SCRIPT_DISPATCH Dispatch;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ BOOT_SCRIPT_INFORMATION Info;
+ BOOT_SCRIPT_DISPATCH2 Dispatch2;
+ BOOT_SCRIPT_PCI_CFG2_WRITE WrPci2;
+ BOOT_SCRIPT_PCI_CFG2_READ_WRITE RwPci2;
+ BOOT_SCRIPT_IO_POLL IoPoll;
+ BOOT_SCRIPT_MEM_POLL MemPoll;
+ BOOT_SCRIPT_PCI_CFG_POLL PciPoll;
+ BOOT_SCRIPT_PCI_CFG2_POLL PciPoll2;
+#endif
+ BOOT_SCRIPT_TABLE_END End;
+} BOOT_SCRIPT_DATA;
+
+VOID CallbackReadyToBoot(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/BootScriptSave.c b/Core/EM/S3/BootScriptSave.c
new file mode 100644
index 0000000..46e2bc4
--- /dev/null
+++ b/Core/EM/S3/BootScriptSave.c
@@ -0,0 +1,2540 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptSave.c 5 7/15/14 9:51p Chienhsieh $
+//
+// $Revision: 5 $
+//
+// $Date: 7/15/14 9:51p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptSave.c $
+//
+// 5 7/15/14 9:51p Chienhsieh
+// update for ACPI module labeled 49
+//
+// 12 4/14/14 3:10p Oleksiyy
+// [TAG] EIP161916
+// [Category] Improvement
+// [Description] 32 bit typecasting issue fixed.
+// [Files] BootScriptSave.c
+//
+// 4 9/17/13 10:03p Thomaschen
+// update for ACPI module labeled 47
+//
+// 11 8/14/13 12:35p Oleksiyy
+// [TAG] EIP95347
+// [Category] Improvement
+// [Description] Synchronized usage of Allocate/Free memory operations
+// on pool/page basis.
+//
+// [Files] BootScriptSave.c
+//
+// 10 7/05/13 2:32p Oleksiyy
+// [TAG] EIP128054
+// [Category] Improvement
+// [Description] USB ports are disabled after resume from S3 with
+// special steps
+// [Files] BootScriptSave.c
+//
+// 9 12/27/12 4:00p Oleksiyy
+// [TAG] EIP109790
+// [Category] Improvement
+// [Description] Code check result - Possible Null pointer acces.
+// [Files] BootScriptSave.c
+//
+// 8 12/13/12 12:03p Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 7 10/31/12 3:49p Oleksiyy
+// [TAG] EIP104782
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Bug in BootScriptSave.c AllocTableEntry() function
+// [RootCause] Pointer to ACPI_VARIABLE_SET was not initialized.
+// [Solution] Initialize pointer.
+// [Files] BootScriptSave.c
+//
+// 6 12/16/11 4:27p Oleksiyy
+// [TAG] EIP78247
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BootScriptTable problem
+// [RootCause] TablePointer was updated uncorectly during CloseTable
+// call and any opcodes added after closing was ignored.
+// [Solution] Pointer updated correctly now.
+// [Files] BootScriptSave.c
+//
+// 5 9/29/11 5:05p Oleksiyy
+// [TAG] EIP71372
+// [Category] Improvement
+// [Description] EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE added.
+// [Files] BootScriptExecuter.c and BootScriptSave.c
+//
+// 4 6/16/11 9:57a Felixp
+// Bug fix: EFI_BOOT_SCRIPT_PCI_POLL_OPCODE is replaced with
+// EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE
+//
+// 3 5/13/11 4:59p Oleksiyy
+// [TAG] EIP56650
+// [Category] Improvement
+// [Description] Compatibility with older core fixed.
+// [Files] BootScriptSave.c
+//
+// 2 5/13/11 3:20p Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// functions added. Support for opcodes introduced in PI 1.2 added.
+//
+// [Files] BootScriptCommon.h, BootScriptExecuter.c,
+// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 8 1/20/11 12:33p Oleksiyy
+// [TAG] EIP48697
+// [Category] Improvement
+// [Description] Functionality modified and after Close table is called
+// - boot script still added to the end of the table.
+// [Files] BootScriptSave.c
+//
+// 7 11/05/09 4:02p Oleksiyy
+// EIP 27821 Support for 64 bit operations in Bootscript added. To use
+// this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, x64AsmLib.asm
+// files should be updated also.
+//
+// 6 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 5 3/26/09 10:10a Oleksiyy
+// EIP 20471 : MAX_TABLE_ENTRIES value increased to 2048.
+//
+// 4 12/01/08 6:52p Yakovlevs
+// Fixed BootScript code to support IA32 and x64 CPU Architecture EIP #
+// 17317
+//
+// 3 4/15/08 9:21p Yakovlevs
+// Functions Headers added
+//
+// 2 6/05/07 12:19a Felixp
+// Added SmmBus support
+//
+// 1 4/23/07 1:31p Felixp
+//
+// 14 3/21/07 10:53a Markw
+// Previous revision over wrote Felix's changes. I put them back.
+//
+// 13 3/19/07 4:13p Markw
+// Update so that PCI functions saving registers 0xfc - 0xff doesn't fail.
+//
+// 12 2/12/07 11:21a Felixp
+// Revision field removed from EFI_BOOT_SCRIPT_SAVE_PROTOCOL structure
+// to match BootScript spec (it was earlier their for Tiano compliance.
+// Tiano header is fixed now).
+//
+// 11 12/26/06 2:57p Markw
+// Add BootScript Polling.
+//
+// 10 9/29/06 6:02p Markw
+// Fix 64-bit bugs.
+//
+// 9 9/22/06 6:09p Markw
+// 64-bit fix.
+//
+// 8 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 7 3/13/06 5:30p Felixp
+//
+// 6 11/07/05 3:44p Sivagarn
+// Included SMBus.H to resolve SMBus related definition errors
+//
+// 5 6/23/05 5:38p Markw
+// Added include to boot script save protocol. Previously was in
+// bootscriptprivate.h.
+//
+// 4 5/13/05 3:19p Markw
+// UINT32 -> UINT64 sometimes causes sign extend. Clear bits[64:32] for
+// address.
+//
+// 3 3/23/05 2:53p Markw
+// Bug fixes: Pointers, TableLength
+//
+// 2 3/14/05 4:25p Markw
+// Change final memory allocation to Runtime Service Data to ACPI NVS.
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: BootScriptSave.c
+//
+// Description: Save Mem/Io/Pci/Smbus/etc into a table. The script will
+// be executed on a S3 resume.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+#include <Protocol\S3SaveState.h>
+#include <Protocol\S3SmmSaveState.h>
+#include <Protocol\SmmBase2.h>
+#endif
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\smbus.h>
+#include "BootScriptPrivate.h"
+#include <AmiDxeLib.h>
+#include "AcpiS3.h"
+//---For Compatibility Reasons---------------------------------------------------
+#ifndef EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_IO_POLL_OPCODE
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_MEM_POLL_OPCODE
+#define EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE
+#endif
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// Currently reentrant code could fail if reentered when new table
+// is being created.
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+EFI_SMM_SYSTEM_TABLE2 *gSmst2 = NULL;
+EFI_SMM_BASE2_PROTOCOL *mInternalSmmBase2 = NULL;
+EFI_HANDLE mSmmS3SaveHandle = NULL;
+#endif
+
+EFI_EVENT gEvtReadyToBoot;
+
+typedef EFI_STATUS (*GENERIC_OPCODE_FUNC) (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list List
+);
+
+
+#define INIT_TABLE_SIZE 1024
+#define MAX_TABLE_ENTRIES 2048
+#define TBL_VAR_NAME L"S3SS"
+
+
+
+static EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+static EFI_GUID gTableDataVarGuid = { 0x4bafc2b4, 0x2dc, 0x4104, 0xb2, 0x36, 0xd6, 0xf1, 0xb9, 0x8d, 0x9e, 0x84};
+
+
+typedef struct {
+ VOID *TableBottom;
+ VOID *TablePtr;
+ UINTN TableSize;
+ UINTN NumTableEntries;
+ BOOLEAN WasClosed;
+} TABLE_INFO;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+typedef struct {
+ BOOLEAN IsItInsert;
+ BOOLEAN BeforeOrAfter;
+ UINTN Position;
+} BOOT_SCRIPT_INSERT_INFO;
+
+BOOT_SCRIPT_INSERT_INFO gInsertInfo = {FALSE, FALSE, 0};
+#define LABEL_MAX_SIZE 0x200
+#endif
+
+TABLE_INFO *gTableInfo = NULL;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: NewTable
+//
+// Description: Initialize first table.
+//
+// Input:
+// IN UINT16 Table
+//
+// Output:
+// BOOLEAN - TRUE if new table created.
+//
+// Notes:
+// Return True if successful table creation, otherwise return false.
+// Need valid table info even if table fails, because functions may
+// attempt to write to the boot script without a table being created.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NewTable()
+{
+ EFI_STATUS Status;
+//--------------------------------
+
+ Status = pBS->AllocatePool(EfiBootServicesData, INIT_TABLE_SIZE*2, &(gTableInfo->TableBottom));
+ if (EFI_ERROR(Status))
+ {
+ gTableInfo->TableBottom = 0;
+ return FALSE;
+ }
+ gTableInfo->TablePtr = gTableInfo->TableBottom;
+ gTableInfo->TableSize = INIT_TABLE_SIZE*2;
+ gTableInfo->NumTableEntries = 0;
+ gTableInfo->WasClosed = FALSE;
+ return TRUE;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitBootScriptStructure
+//
+// Description: Updates Table pointer Before each Write operation.
+//
+// Input:
+// IN UINT16 Table
+//
+// Output:
+// EFI_SATUS - Status of the operation.
+//
+// Notes:
+// Return True if successful table creation, otherwise return false.
+// Need valid table info even if table fails, because functions may
+// attempt to write to the boot script without a table being created.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBootScriptStructure(BOOLEAN IsItSmm)
+{
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ UINTN sz=sizeof(VOID*);
+#endif
+ EFI_STATUS Status = EFI_SUCCESS;
+
+//--------------------------------
+ if(gTableInfo == NULL)
+ {
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Status = pRS->GetVariable(L"S3SS", &gTableDataVarGuid, NULL, &sz, &gTableInfo);
+ if(EFI_ERROR(Status) && Status!=EFI_NOT_FOUND && IsItSmm) return EFI_OUT_OF_RESOURCES;
+ if(Status==EFI_NOT_FOUND)
+#endif
+ {
+ EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF;
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES(sizeof(TABLE_INFO)),
+ &MaxAddress);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ gTableInfo = (VOID*)(UINTN)MaxAddress;
+ if (!NewTable()) return EFI_OUT_OF_RESOURCES;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Status = pRS->SetVariable(L"S3SS",&gTableDataVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
+ sz, &gTableInfo);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status) && IsItSmm) return EFI_OUT_OF_RESOURCES;
+#endif
+ }
+
+
+ }
+ return Status;
+}
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InsertPositionInBootScript
+//
+// Description: Found position and, based on Size, allocate space for Entry,
+// that has to be incerted, in table based on parameters in
+// gInsertInfo structure.
+//
+// Input:
+// IN UINTN Size - Size of entry to allocate in table.
+//
+// Output:
+// VOID * - Pointer to allocated entry in table.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* InsertPositionInBootScript (UINTN Size)
+{
+ TABLE_INFO *Info = gTableInfo;
+ UINT8 *CopyFrom = Info->TableBottom, *CopyTo;
+ UINTN i = 0, CopySize = (UINT8*)Info->TablePtr - (UINT8*)Info->TableBottom;
+ BOOLEAN Found = FALSE;
+
+ if (gInsertInfo.Position != -1)
+ {
+ for (i=0; i<Info->NumTableEntries; i++)
+ { //Found position with supplied
+ if (((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->UniqueIndex == gInsertInfo.Position)
+ {
+ Found = TRUE;
+ if (gInsertInfo.BeforeOrAfter == FALSE)
+ CopyFrom += ((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->Length;
+ break;
+ }
+ CopyFrom += ((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->Length;
+ }
+ if (!Found) return NULL;
+ }
+ if ((Size != 0) && (i != Info->NumTableEntries))
+ {
+ CopyTo = CopyFrom + Size;
+ CopySize = (UINT8*)Info->TablePtr - CopyFrom;
+ MemCpy(CopyTo, CopyFrom, CopySize);
+ }
+ return CopyFrom;
+
+}
+#endif
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: AllocTableEntry
+//
+// Description: Allocate Entry from table. If not enough space, create
+// larger table and return entry.
+//
+// Input:
+// IN UINTN Size - Size of entry to allocate in table.
+//
+// Output:
+// VOID * - Pointer to allocated entry in table.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Does the BootScript table exist. If no return 0.
+// 2. Does table contain max entries? If so assert.
+// 3. Enough space in the table for the boot script call? If yes, go to step 8.
+// ---Create table---
+// 4. Get Size of table needed for entry. (A multiple of INIT_TABLE_SIZE.)
+// 5. Allocate new table.
+// 6. Copy old table
+// 7. Free old table.
+// 8. Update gTableInfo data.
+// ------------------
+// 9. Adjust allocation pointer to allocate new space.
+// 10. Return newly allocated space.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * AllocTableEntry(IN UINTN Size)
+{
+ TABLE_INFO *Info = gTableInfo;
+ VOID *TempBottom;
+ VOID *TempPtr;
+ UINTN TempSize, NewSize;
+ BOOT_SCRIPT_TABLE_END TableEnd;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ //BOOT_SCRIPT_INFO_STRUCTURE BsHeader;
+ Size += sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+#endif
+ if (Info->TableBottom == NULL) return NULL;
+
+ //Should not fill table. If table becomes full, then an error is causing too many table entries.
+ ASSERT(Info->NumTableEntries < MAX_TABLE_ENTRIES);
+
+ if ((UINTN)Info->TableBottom + Info->TableSize < (UINTN) Info->TablePtr + Size
+ + sizeof(BOOT_SCRIPT_TABLE_END)
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ + sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ )
+ {
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (gSmst2 != NULL) return NULL; // we can't allocate memory in SMM
+#endif
+ TempSize = Info->TableSize + INIT_TABLE_SIZE * (Size / INIT_TABLE_SIZE + 1);
+
+ if (Info->WasClosed == FALSE) // Use AllocatePool if table was not closed - later it will be copyed under 4 Gb.
+ {
+ if (pBS->AllocatePool(EfiBootServicesData, TempSize, &TempBottom) != EFI_SUCCESS)
+ return NULL;
+
+ NewSize = TempSize;
+ }
+ else // Use AllocatePages if table was closed. We need it under 4 Gb.
+ {
+ EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF;
+
+ if (pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(TempSize) + 1, &MaxAddress) != EFI_SUCCESS)
+ return NULL;
+ TempBottom = (VOID*)(UINTN)MaxAddress;
+ NewSize = EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TempSize) + 1); // Calculate the sieze of new structure from pages
+ TempSize = EFI_SIZE_TO_PAGES(Info->TableSize); // Save old size in pages to use in FreePages.
+ }
+
+ MemCpy(TempBottom, Info->TableBottom, Info->TableSize);
+
+ Info->TablePtr = (UINT8*)TempBottom + (UINTN)Info->TablePtr - (UINTN)Info->TableBottom;
+ TempPtr = Info->TableBottom; // Save old TableBottom to freememory
+ Info->TableBottom = TempBottom;
+ Info->TableSize = NewSize;
+ if (Info->WasClosed == TRUE)
+ {
+ EFI_STATUS Status;
+ ACPI_VARIABLE_SET *AcpiVariableSet = NULL;
+ CHAR16 AcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+ EFI_GUID EfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+ UINTN VariableSize = sizeof(ACPI_VARIABLE_SET*);
+ Status = pRS->GetVariable(
+ AcpiGlobalVariable,
+ &EfiAcpiVariableGuid,
+ NULL,
+ &VariableSize,
+ &AcpiVariableSet
+ );
+ ASSERT_EFI_ERROR(Status);
+ AcpiVariableSet->AcpiBootScriptTable = (EFI_PHYSICAL_ADDRESS) (UINTN) TempBottom;
+ pBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) TempPtr, TempSize); // If WasClosed == TRUE use FreePages
+ }
+ else pBS->FreePool(TempPtr); // If WasClosed != TRUE use FreePool
+
+ }
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (gInsertInfo.IsItInsert == TRUE)
+ {
+ TempPtr = InsertPositionInBootScript (Size);
+ if (TempPtr == NULL) return TempPtr;
+ }
+ else
+#endif
+ TempPtr = (UINT8*)Info->TablePtr;
+ Info->TablePtr = (UINT8*)Info->TablePtr + Size;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ ((BOOT_SCRIPT_INFO_STRUCTURE*)TempPtr)->UniqueIndex = (UINT32) Info->NumTableEntries;
+ ((BOOT_SCRIPT_INFO_STRUCTURE*)TempPtr)->Length = (UINT32) Size;
+ TempPtr = (UINT8*) TempPtr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+#endif
+ TableEnd.Type = TABLE_END_OP_CODE;
+ MemCpy((VOID*)((UINTN)Info->TablePtr
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ + sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ ), &TableEnd, sizeof(BOOT_SCRIPT_TABLE_END));
+ ++(Info->NumTableEntries);
+ return TempPtr;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptIoWrite
+//
+// Description: Write to boot script table an IoWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptIoWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ IN va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_WRITE_IO WriteIo;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+ if (Address + AddressCount > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_IO) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WriteIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,Width);
+ WriteIo.Port = (UINT16) Address;
+ WriteIo.Count = Count;
+
+ MemCpy(Ptr, &WriteIo, sizeof(BOOT_SCRIPT_WRITE_IO)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_IO);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptIoReadWrite
+//
+// Description: Write to boot script table a IoReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptIoReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataValue = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_READ_WRITE_IO ReadWriteIo;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Data, Mask;
+
+ Mask = *(UINT64*)DataMask;
+ Data = *(UINT64*)DataValue;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+ if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_IO));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWriteIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE, Width);
+ ReadWriteIo.Port = (UINT16) Address;
+ ReadWriteIo.Value = Data & BitMask;
+ ReadWriteIo.Mask = Mask & BitMask;
+
+ MemCpy(Ptr, &ReadWriteIo, sizeof(ReadWriteIo)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptMemWrite
+//
+// Description: Write to boot script table an MemWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptMemWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_WRITE_MEM WriteMem;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + AddressCount < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + AddressCount > 0xffffffff) return EFI_INVALID_PARAMETER;
+
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_MEM) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WriteMem.Type = (UINT16)TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,Width);
+ WriteMem.Address = (UINT64)Address;
+ WriteMem.Count = Count;
+
+ MemCpy(Ptr, &WriteMem, sizeof(BOOT_SCRIPT_WRITE_MEM)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_MEM);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptMemReadWrite
+//
+// Description: Write to boot script table an MemReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptMemReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataValue = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_READ_WRITE_MEM ReadWriteMem;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Data;
+
+ Mask = *(UINT64*)DataMask;
+ Data = *(UINT64*)DataValue;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_MEM));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWriteMem.Type = (UINT16)TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, Width);
+ ReadWriteMem.Address = (UINT64)Address;
+ ReadWriteMem.Value = Data & BitMask;
+ ReadWriteMem.Mask = Mask & BitMask;
+
+ MemCpy(Ptr, &ReadWriteMem, sizeof(BOOT_SCRIPT_READ_WRITE_MEM)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptPciWrite
+//
+// Description: Write to boot script table an PciWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptPciWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_WRITE_PCI WritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ if (Register + AddressCount > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_PCI) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,Width);
+ WritePci.Address = Address;
+ WritePci.Count = Count;
+
+ MemCpy(Ptr, &WritePci, sizeof(BOOT_SCRIPT_WRITE_PCI)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_PCI);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptPciReadWrite
+//
+// Description: Write to boot script table an PciReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptPciReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *Data = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_READ_WRITE_PCI ReadWritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_PCI));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, Width);
+ ReadWritePci.Address = Address;
+ ReadWritePci.Value = *(UINT64*) Data & BitMask;
+ ReadWritePci.Mask = *(UINT64*) DataMask & BitMask;
+
+ MemCpy(Ptr, &ReadWritePci, sizeof(BOOT_SCRIPT_READ_WRITE_PCI)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptSmbusExecute
+//
+// Description: Write to boot script table an SmbusExecute.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptSmbusExecute (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ VOID *Ptr;
+ VOID *Buffer;
+
+ BOOT_SCRIPT_SMBUS_EXECUTE_32 Smbus;
+
+ Smbus.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE);
+ Smbus.SlaveAddress = (UINT32)va_arg(arglist, UINTN);
+ Smbus.Command = (UINT32)va_arg(arglist, UINTN);
+ Smbus.Operation = va_arg(arglist, EFI_SMBUS_OPERATION);
+ Smbus.PecCheck = va_arg(arglist, BOOLEAN);
+ Smbus.Length = *(va_arg(arglist, UINTN*));
+
+ Buffer = va_arg(arglist, VOID*);
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32) + (UINT32)Smbus.Length);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Ptr, &Smbus, sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32);
+
+ MemCpy(Ptr, Buffer, (UINT32)Smbus.Length);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptStall
+//
+// Description: Write to boot script table an Stall.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptStall (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ VOID *Ptr;
+ BOOT_SCRIPT_STALL Stall;
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_STALL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ Stall.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_STALL_OPCODE);
+ Stall.Duration = va_arg(arglist, UINTN);
+
+ MemCpy(Ptr, &Stall, sizeof(BOOT_SCRIPT_STALL));
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptIoPoll
+//
+// Description: Write to boot script table a IoPoll (OEM specific).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptIoPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_POLL_IO PollIo;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+ if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_IO));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PollIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM, Width);
+ PollIo.Port = (UINT16) Address;
+ PollIo.Mask = Mask & BitMask;
+ PollIo.Result = Result & BitMask;
+
+ MemCpy(Ptr, &PollIo, sizeof(BOOT_SCRIPT_POLL_IO)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptMemPoll
+//
+// Description: Write to boot script table a MemPoll.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptMemPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_POLL_MEM PollMem;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_MEM));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PollMem.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM, Width);
+ PollMem.Address = (UINT64)Address;
+ PollMem.Mask = Mask & BitMask;
+ PollMem.Result = Result & BitMask;
+
+ MemCpy(Ptr, &PollMem, sizeof(BOOT_SCRIPT_POLL_MEM)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptPciPoll
+//
+// Description: Write to boot script table an PciPoll.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptPciPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult= va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_POLL_PCI PollPci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_PCI));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PollPci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM, Width);
+ PollPci.Address = Address;
+ PollPci.Mask = *(UINT64*) DataMask & BitMask;
+ PollPci.Result = *(UINT64*) DataResult & BitMask;
+
+ MemCpy(Ptr, &PollPci, sizeof(BOOT_SCRIPT_POLL_PCI)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptDispatch
+//
+// Description: Write to boot script table an Dispatch.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptDispatch (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+//---------Unsupported by now------------------------
+
+ VOID *Ptr;
+ BOOT_SCRIPT_DISPATCH Dispatch;
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_DISPATCH));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ Dispatch.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_DISPATCH_OPCODE);
+ Dispatch.EntryPoint = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+
+ MemCpy(Ptr, &Dispatch, sizeof(BOOT_SCRIPT_DISPATCH));
+
+ return EFI_SUCCESS;
+
+// return EFI_UNSUPPORTED;
+}
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateDispatch2
+//
+// Description: Write to boot script table an Dispatch2.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateDispatch2 (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ VOID *Ptr;
+ BOOT_SCRIPT_DISPATCH2 Dispatch2;
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_DISPATCH2));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ Dispatch2.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE);
+ Dispatch2.EntryPoint = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+ Dispatch2.Context = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+
+ MemCpy(Ptr, &Dispatch2, sizeof(BOOT_SCRIPT_DISPATCH2));
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateInformation
+//
+// Description: Write to boot script table an Information entry.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateInformation (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ UINT32 InfoSize = va_arg(arglist, UINT32);
+ EFI_PHYSICAL_ADDRESS InfoBuffer = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+ BOOT_SCRIPT_INFORMATION Information;
+ VOID *Ptr;
+
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_INFORMATION));
+ if (Ptr == NULL) return EFI_OUT_OF_RESOURCES;
+
+ Information.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_INFORMATION_OPCODE);
+ Information.Size = InfoSize;
+ Information.MessagePtr = InfoBuffer;
+
+ MemCpy(Ptr, &Information, sizeof(BOOT_SCRIPT_INFORMATION));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfg2Write
+//
+// Description: Write to boot script table an PciWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfg2Write (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT16 Segment = va_arg(arglist, UINT16);
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_PCI_CFG2_WRITE WritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ if (Register + AddressCount > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE,Width);
+ WritePci.Segment = Segment;
+ WritePci.Address = Address;
+ WritePci.Count = Count;
+
+ MemCpy(Ptr, &WritePci, sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfg2ReadWrite
+//
+// Description: Write to boot script table an PciReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfg2ReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT16 Segment = va_arg(arglist, UINT16);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *Data = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_PCI_CFG2_READ_WRITE ReadWritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE, Width);
+ ReadWritePci.Segment = Segment;
+ ReadWritePci.Address = Address;
+ ReadWritePci.Value = *(UINT64*) Data & BitMask;
+ ReadWritePci.Mask = *(UINT64*) DataMask & BitMask;
+
+ MemCpy(Ptr, &ReadWritePci, sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateIoPoll
+//
+// Description: Write to boot script table a PI 1.1 IoPoll.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateIoPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataResult = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_IO_POLL IoPoll;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+ if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_IO_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ IoPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_POLL_OPCODE, Width);
+ IoPoll.Port = (UINT16) Address;
+ IoPoll.Mask = Mask & BitMask;
+ IoPoll.Result = Result & BitMask;
+ IoPoll.Delay = Delay;
+
+ MemCpy(Ptr, &IoPoll, sizeof(BOOT_SCRIPT_IO_POLL)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateMemPoll
+//
+// Description: Write to boot script table a MemPoll (PI 1.1).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateMemPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+ UINT64 LoopTimes = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_MEM_POLL MemPoll;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_MEM_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ MemPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, Width);
+ MemPoll.Address = (UINT64)Address;
+ MemPoll.Mask = Mask & BitMask;
+ MemPoll.Result = Result & BitMask;
+ MemPoll.Delay = Delay;
+ MemPoll.LoopTimes= LoopTimes;
+ MemCpy(Ptr, &MemPoll, sizeof(BOOT_SCRIPT_MEM_POLL)); //Use MemCpy to avoid alignment problems.
+ //TRACE((-1,"SaveState Mem poll Mask %lx\n", MemPoll.Mask));
+ //TRACE((-1,"SaveState Mem poll Result %lx\n", MemPoll.Result));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfgPoll
+//
+// Description: Write to boot script table an PciPoll (PI 1.1).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfgPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataResult= va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_PCI_CFG_POLL PciPoll;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PciPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE, Width);
+ PciPoll.Address = Address;
+ PciPoll.Mask = *(UINT64*) DataMask & BitMask;
+ PciPoll.Result = *(UINT64*) DataResult & BitMask;
+ PciPoll.Delay = Delay;
+
+ MemCpy(Ptr, &PciPoll, sizeof(BOOT_SCRIPT_PCI_CFG_POLL)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfg2Poll
+//
+// Description: Write to boot script table an PciPoll Cfg2 (PI 1.1).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfg2Poll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT16 Segment = va_arg(arglist, UINT16);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataResult= va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_PCI_CFG2_POLL PciPoll2;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG2_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PciPoll2.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE , Width);
+ PciPoll2.Segment = Segment;
+ PciPoll2.Address = Address;
+ PciPoll2.Mask = *(UINT64*) DataMask & BitMask;
+ PciPoll2.Result = *(UINT64*) DataResult & BitMask;
+ PciPoll2.Delay = Delay;
+
+ MemCpy(Ptr, &PciPoll2, sizeof(BOOT_SCRIPT_PCI_CFG2_POLL)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+#endif //#if PI_SPECIFICATION_VERSION>=0x0001000A
+GENERIC_OPCODE_FUNC OpCodeFuncs[] =
+{
+ BootScriptIoWrite, //0
+ BootScriptIoReadWrite, //1
+ BootScriptMemWrite, //2
+ BootScriptMemReadWrite, //3
+ BootScriptPciWrite, //4
+ BootScriptPciReadWrite, //5
+ BootScriptSmbusExecute, //6
+ BootScriptStall, //7
+ BootScriptDispatch, //8
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ SaveStateDispatch2, //9
+ SaveStateInformation, //a ->0xA
+ SaveStatePciCfg2Write, //b ->0xB
+ SaveStatePciCfg2ReadWrite, //c ->0xC
+ SaveStateIoPoll, //d
+ SaveStateMemPoll, //e
+ SaveStatePciCfgPoll, //f
+ SaveStatePciCfg2Poll, //10
+#endif
+//oem
+ BootScriptIoPoll, //0x80 ->
+ BootScriptMemPoll, //0x81 ->
+ BootScriptPciPoll, //0x82 ->
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiBootScriptWrite
+//
+// Description: All boot script functions (except close table) call this function.
+// This function passes argument list to appropriate function.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN UINT16 OpCode
+// ...
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiBootScriptWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ IN UINT16 TableName,
+ IN UINT16 OpCode,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ va_list arglist;
+ va_start(arglist, OpCode);
+
+ if (TableName != EFI_ACPI_S3_RESUME_SCRIPT_TABLE)
+ return EFI_INVALID_PARAMETER;
+
+ if (OpCode > 0x82) {
+ Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;
+ }
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (OpCode > 16 && OpCode < 0x80) {Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;}
+#else
+ if (OpCode > 8 && OpCode < 0x80) {Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;}
+#endif
+
+ if (OpCode >= 0x80)
+ {
+ OpCode -= (0x80 - 9);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ OpCode += 8;
+#endif
+ }
+
+ Status = OpCodeFuncs[OpCode](This, arglist);
+
+EXIT_BOOT_SCRIPT_WRITE:
+ va_end(arglist);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiBootScriptCloseTable
+//
+// Description: Save table in runtime closing table and return pointer to table.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// OUT EFI_PHYSICAL_ADDRESS *Address
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals:
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Allocate table entry for BOOT_SCRIPT_TABLE_END. If no entry, return EFI_OUT_OF_RESOURCES.
+// 2. Fill table.
+// 3. Allocate space for new table in Runtime.
+// 4. Copy table to new table.
+// 5. Set *Address to Runtime Table.
+// 6. Free old table.
+// 7. Create a initial table to start over if more Scripts are added.
+// 8. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiBootScriptCloseTable (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ IN UINT16 TableName,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+{
+ TABLE_INFO *Info = gTableInfo;
+ UINTN TableLength;
+//---------------------------------------
+ if (TableName != EFI_ACPI_S3_RESUME_SCRIPT_TABLE)
+ return EFI_INVALID_PARAMETER;
+ TableLength = (UINTN)Info->TablePtr - (UINTN)Info->TableBottom
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ + sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ + (UINTN) sizeof(BOOT_SCRIPT_TABLE_END);
+
+ //Copy to new table.
+ *Address = 0xFFFFFFFF;
+ if (pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(TableLength + INIT_TABLE_SIZE) + 1, Address) != EFI_SUCCESS)
+ return EFI_OUT_OF_RESOURCES;
+
+ MemCpy((VOID*)(UINTN)*Address,Info->TableBottom, TableLength);
+ pBS->FreePool(Info->TableBottom);
+
+ //Reasign Table Address;
+ Info->TableBottom = (VOID*)(UINTN)*Address;
+ Info->TablePtr = (VOID*)((UINTN) Info->TableBottom + TableLength
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ - sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ - (UINTN) sizeof(BOOT_SCRIPT_TABLE_END));
+ Info->TableSize = EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TableLength + INIT_TABLE_SIZE) + 1);
+ Info->WasClosed = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL gBootScriptSaveProtocol =
+{
+ EfiBootScriptWrite,
+ EfiBootScriptCloseTable
+};
+
+
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+
+VOID ClearInsertInfo()
+{
+ gInsertInfo.IsItInsert = FALSE;
+ gInsertInfo.BeforeOrAfter = FALSE;
+ gInsertInfo.Position = -1;
+ return;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateWrite
+//
+// Description: This function is used to store an OpCode to be replayed as part
+// of the S3 resume boot path.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN UINT16 OpCode
+// ...
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateWrite(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN UINT16 OpCode,
+ ...)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN OpIndex;
+ va_list arglist;
+ va_start(arglist, OpCode);
+//----------------------------------
+
+ //map SaveState opcodes to the op code table.
+ switch(OpCode){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0x0D:
+ case 0x0E:
+ case 0x0F:
+ case 0x10:
+ OpIndex=OpCode;
+ break;
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ OpIndex= OpCode - (0x6F);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ goto EXIT_BOOT_SCRIPT_WRITE;
+ }
+ Status = OpCodeFuncs[OpIndex](&gBootScriptSaveProtocol, arglist);
+ //TRACE((-1,"SaveState UniqueIndex %x\n", gTableInfo->NumTableEntries -1));
+
+EXIT_BOOT_SCRIPT_WRITE:
+ va_end(arglist);
+ return Status;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateInsert
+//
+// Description: This function is used to store an OpCode to be replayed as part
+// of the S3 resume boot path. The opcode is stored before (TRUE)
+// or after (FALSE) the position in the boot script table specified
+// by Position. If Position is NULL or points to NULL then the new
+// opcode is inserted at the beginning of the table (if TRUE) or end
+// of the table (if FALSE).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN BOOLEAN BeforeOrAfter
+// IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL
+// IN UINT16 OpCode
+// ...
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateInsert(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN BOOLEAN BeforeOrAfter,
+ IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL,
+ IN UINT16 OpCode,
+ ...
+){
+
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN OpIndex;
+
+ va_list arglist;
+ va_start(arglist, OpCode);
+//----------------------------------
+
+ //map SaveState opcodes to the op code table.
+ switch(OpCode){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0x0D:
+ case 0x0E:
+ case 0x0F:
+ case 0x10:
+ OpIndex=OpCode;
+ break;
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ OpIndex= OpCode - (0x6F);
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ goto EXIT_BOOT_SCRIPT_WRITE;
+ }
+
+ gInsertInfo.IsItInsert = TRUE;
+ gInsertInfo.BeforeOrAfter = BeforeOrAfter;
+ if (!Position || !*Position)
+ if (BeforeOrAfter) gInsertInfo.Position = -1;
+ else gInsertInfo.IsItInsert = FALSE;
+ else
+ {
+ if ((UINTN) *Position >= gTableInfo->NumTableEntries)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ gInsertInfo.Position = (UINTN)*Position;
+ }
+ Status = OpCodeFuncs[OpIndex](&gBootScriptSaveProtocol, arglist);
+ if (Position) *Position = (VOID*)(gTableInfo->NumTableEntries - 1);
+ ClearInsertInfo();
+EXIT_BOOT_SCRIPT_WRITE:
+ va_end(arglist);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateLabel
+//
+// Description: Find a label within the boot script table and, if not present,
+// optionally create it.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN BOOLEAN BeforeOrAfter
+// IN BOOLEAN CreateIfNotFound
+// IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL
+// IN CONST CHAR8 *Label
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateLabel(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN BOOLEAN BeforeOrAfter,
+ IN BOOLEAN CreateIfNotFound,
+ IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL,
+ IN CONST CHAR8 *Label)
+{
+ UINT32 LabelSize, i;
+ UINT8 *TableHdr = gTableInfo->TableBottom, *TableInfo;
+ UINT16 Type;
+ BOOT_SCRIPT_LABEL LabelStr;
+
+ if ((Label == NULL) || (*Label == 0))
+ {
+ TRACE((-1,"First Exit\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ for(LabelSize=0; LabelSize<= LABEL_MAX_SIZE ; LabelSize++)
+ {
+ if (Label[LabelSize] == 0) break; // We assume label is 0 terminated.
+
+ }
+ if (LabelSize >= LABEL_MAX_SIZE)
+ {
+ TRACE((-1,"2-d Exit\n"));
+ return EFI_INVALID_PARAMETER; // Label is too long or wrong/corrupted pointer
+ }
+ for (i=0; i<=gTableInfo->NumTableEntries; i++)
+ {
+ TableInfo = TableHdr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+ Type = *(UINT8*) TableInfo + (*((UINT8*) TableInfo + 1) << 8); //In case not aligned if alignment required.
+ if (Type == EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM)
+ {
+ if (((BOOT_SCRIPT_LABEL*) TableInfo)->Size == LabelSize &&
+ !MemCmp((VOID*)Label, TableInfo + sizeof(BOOT_SCRIPT_LABEL), LabelSize))
+ {
+ if (Position) *Position = ((VOID*)((BOOT_SCRIPT_INFO_STRUCTURE*) TableHdr)->UniqueIndex);
+ else return EFI_INVALID_PARAMETER; //We found label, but can't return its position
+ return EFI_SUCCESS; // Label found and position returned
+ }
+ }
+ TableHdr += ((BOOT_SCRIPT_INFO_STRUCTURE*) TableHdr)->Length;
+ }
+ //----Label was not found
+
+ if (!CreateIfNotFound) return EFI_NOT_FOUND;
+
+ //----So - lets create it at position
+
+ if (Position && ((UINTN) *Position >= gTableInfo->NumTableEntries))
+ return EFI_INVALID_PARAMETER; // Position is not valid
+
+ //---Filling gInsertInfo based on passed parameters
+
+ gInsertInfo.IsItInsert = TRUE;
+ gInsertInfo.BeforeOrAfter = BeforeOrAfter;
+
+ if (!Position || !*Position)
+ if (BeforeOrAfter) gInsertInfo.Position = -1;
+ else gInsertInfo.IsItInsert = FALSE;
+ else
+ {
+ if ((UINTN) *Position >= gTableInfo->NumTableEntries)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ gInsertInfo.Position = (UINTN)*Position;
+ }
+ TableHdr = AllocTableEntry(sizeof(BOOT_SCRIPT_LABEL) + LabelSize);
+ ClearInsertInfo();
+ if (!TableHdr)
+ return EFI_OUT_OF_RESOURCES;
+ LabelStr.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM);
+ LabelStr.Size = LabelSize;
+ MemCpy(TableHdr, &LabelStr, sizeof(BOOT_SCRIPT_LABEL));
+ TableHdr += sizeof(BOOT_SCRIPT_LABEL);
+ MemCpy(TableHdr, (VOID*)Label, LabelSize);
+ if (Position)
+ *Position = (VOID*)(gTableInfo->NumTableEntries - 1);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateCompare
+//
+// Description: Compare two positions in the boot script table and return their
+// relative position.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN EFI_S3_BOOT_SCRIPT_POSITION Position1
+// IN EFI_S3_BOOT_SCRIPT_POSITION Position2
+// OUT UINTN *RelativePosition
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateCompare(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN EFI_S3_BOOT_SCRIPT_POSITION Position1,
+ IN EFI_S3_BOOT_SCRIPT_POSITION Position2,
+ OUT UINTN *RelativePosition)
+{
+ VOID *First, *Second;
+ if (((UINTN) Position1 > gTableInfo->NumTableEntries)
+ || ((UINTN) Position2 > gTableInfo->NumTableEntries))
+ return EFI_INVALID_PARAMETER;
+ gInsertInfo.BeforeOrAfter = TRUE;
+ gInsertInfo.Position = (UINTN)Position1;
+ First = InsertPositionInBootScript (0);
+ if (!First)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ gInsertInfo.Position = (UINTN)Position2;
+ Second = InsertPositionInBootScript (0);
+ if (!Second)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ if (First == Second) *RelativePosition = 0;
+ else
+ if (First < Second) *RelativePosition = -1;
+ else *RelativePosition = 1;
+ ClearInsertInfo();
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_S3_SAVE_STATE_PROTOCOL gS3SaveStateProtocol={
+ SaveStateWrite,
+ SaveStateInsert,
+ SaveStateLabel,
+ SaveStateCompare
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBootScriptSmm
+//
+// Description: Initialize table, if not done yet, and install protocols in SMM.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBootScriptSmm(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+//-------------------------------
+ Status=InitAmiSmmLib(ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=InitBootScriptStructure(TRUE);
+ if(EFI_ERROR(Status)) return Status;
+
+ // We are in SMM, retrieve the pointer to SMM System Table
+ Status=mInternalSmmBase2->GetSmstLocation (mInternalSmmBase2, &gSmst2);
+ ASSERT (gSmst2 != NULL);
+ if( EFI_ERROR(Status) || (gSmst2 == NULL)) return EFI_UNSUPPORTED;
+
+
+ // Install SMM PCI Root Bridge I/O Protocol
+ Status=gSmst2->SmmInstallProtocolInterface(
+ &mSmmS3SaveHandle,
+ &gEfiS3SmmSaveStateProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (EFI_S3_SMM_SAVE_STATE_PROTOCOL*)&gS3SaveStateProtocol
+ );
+
+
+
+
+ return Status;
+
+
+}
+
+#endif
+//PI 1.1 --
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBootScriptDxe
+//
+// Description: Initialize table and install protocols outside SMM.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitBootScriptDxe(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = InitBootScriptStructure(FALSE);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiBootScriptSaveGuid, &gBootScriptSaveProtocol,
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ &gEfiS3SaveStateProtocolGuid, &gS3SaveStateProtocol,
+#endif
+ NULL
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK,
+ CallbackReadyToBoot,
+ NULL,
+ &gEvtReadyToBoot
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBootScript
+//
+// Description: Initialize table and install protocols.
+// Called twice - in and outside SMM.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitBootScript(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ EFI_STATUS Status;
+ BOOLEAN InSmm=FALSE;
+#endif
+
+//-------
+ InitAmiLib(ImageHandle, SystemTable);
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ // Retrieve SMM Base2 Protocol, Do not use gBS from UefiBootServicesTableLib on purpose
+ // to prevent inclusion of gBS, gST, and gImageHandle from SMM Drivers unless the
+ // SMM driver explicity declares that dependency.
+ Status = SystemTable->BootServices->LocateProtocol (
+ &gEfiSmmBase2ProtocolGuid,
+ NULL,
+ (VOID **)&mInternalSmmBase2
+ );
+ if( EFI_ERROR(Status)){
+ //if we can't find SMM Protocols that's not InSmm initialization
+ if(Status==EFI_NOT_FOUND) InSmm=FALSE;
+ else return EFI_UNSUPPORTED;
+ } else mInternalSmmBase2->InSmm (mInternalSmmBase2, &InSmm);
+
+ // Check to see if we are already in SMM
+ if (!InSmm ) {
+#endif
+ // We are not in SMM, so SMST is not needed
+ return InitBootScriptDxe(ImageHandle,SystemTable);
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ } else {
+ return InitBootScriptSmm(ImageHandle,SystemTable);
+ }
+#endif
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/S3Restore.cif b/Core/EM/S3/S3Restore.cif
new file mode 100644
index 0000000..e4c4c83
--- /dev/null
+++ b/Core/EM/S3/S3Restore.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "S3Restore"
+ category = ModulePart
+ LocalRoot = "Core\EM\S3\"
+ RefName = "S3Restore"
+[files]
+"S3Restore.sdl"
+"S3Restore.mak"
+"S3Resume.dxs"
+"AcpiS3Wake.asm"
+"S3Resume.c"
+"AcpiPeiS3Func.c"
+"AcpiPeiS3Func.h"
+"BootScriptExecuter.c"
+<endComponent>
diff --git a/Core/EM/S3/S3Restore.mak b/Core/EM/S3/S3Restore.mak
new file mode 100644
index 0000000..d229d9c
--- /dev/null
+++ b/Core/EM/S3/S3Restore.mak
@@ -0,0 +1,88 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Restore.mak 2 3/18/11 3:51p Oleksiyy $
+#
+# $Revision: 2 $
+#
+# $Date: 3/18/11 3:51p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Restore.mak $
+#
+# 2 3/18/11 3:51p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Improving backward computability and architecture.
+# [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak,
+# S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h,
+# S3smmSaveState.h
+#
+# 1 2/03/11 4:09p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Create new label of ACPI with separate S3 Functionality
+# [Files] S3Restore.cif
+# S3Restore.sdl
+# S3Restore.mak
+# S3Resume.dxs
+# AcpiS3Wake.asm
+# S3Resume.c
+# AcpiPeiS3Func.c
+# AcpiPeiS3Func.h
+# BootScriptExecuter.c
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <ComponentName>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : S3Restore
+
+S3Restore : $(BUILD_DIR)\S3Restore.mak S3RestoreBin
+
+$(BUILD_DIR)\S3Restore.mak : $(S3Restore_DIR)\$(@B).cif $(S3Restore_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(S3Restore_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+S3RestoreBin : $(AMIPEILIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\S3Restore.mak all\
+ GUID=EFD652CC-0E99-40f0-96C0-E08C089070FC \
+ ENTRY_POINT=S3ResumeEntryPoint\
+ "MY_INCLUDES=/I$(ACPI_CORE_DIR)" \
+ DEPEX1=$(S3Restore_DIR)\S3Resume.DXS \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM \
+ COMPRESS=0
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/S3/S3Restore.sdl b/Core/EM/S3/S3Restore.sdl
new file mode 100644
index 0000000..baa1165
--- /dev/null
+++ b/Core/EM/S3/S3Restore.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "S3Restore_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable S3Restore support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "S3Restore_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\S3Restore.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+MODULE
+ Help = "Includes S3Restore.mak to Project"
+ File = "S3Restore.mak"
+End
+
diff --git a/Core/EM/S3/S3Resume.c b/Core/EM/S3/S3Resume.c
new file mode 100644
index 0000000..1749cf2
--- /dev/null
+++ b/Core/EM/S3/S3Resume.c
@@ -0,0 +1,582 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/S3Resume.c 3 4/16/14 6:18a Chaseliu $
+//
+// $Revision: 3 $
+//
+// $Date: 4/16/14 6:18a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/S3Resume.c $
+//
+// 3 4/16/14 6:18a Chaseliu
+// sync to ACPI module 48
+//
+// 2 9/18/13 1:04a Thomaschen
+// Fix RHEL6.4 S3 resume issue.
+//
+// 9 3/03/14 5:04p Oleksiyy
+// [TAG] EIP154308
+// [Category] Improvement
+// [Description] Aptio 4: Intel Doc #542550 4h) FirmwarePerformance EFI
+// variable contains address of FPDT ACPI table.
+// [Files] AcpiCore.c and S3Resume.c
+//
+// 8 6/12/12 3:20p Oleksiyy
+// TAG] EIP90322
+// [Category] Improvement
+// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to
+// AmiLib.h.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 7 6/12/12 11:18a Oleksiyy
+// [TAG] EIP88889
+// [Category] Improvement
+// [Description] FACP ver 5.0 structure added, FPDT mesurment accuracy
+// improved.
+// [Files] ACPI50.h, ACPI.sdl, AcpiCore.c, S3Resume.c, Image.c,
+// EfiLib.c
+//
+// 6 5/22/12 4:31p Oleksiyy
+// [TAG] EIP90322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail, improper variable FPDT_Variable in
+// ACPI module
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 5 5/08/12 6:05p Oleksiyy
+// [TAG] EIP89643
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] S3Resume2 Ppi newer installs
+// [RootCause] EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST incorrect usage in
+// previous Ppi descriptor entree.
+// [Solution] EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LISTremoved.
+// [Files] S3Resume.c
+//
+// 4 11/11/11 5:13p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added. FirmPerfDataTab.h renamed to ACPI50.h
+// [Files] AcpiCore.c, EfiLib.c, S3Resume.c and ACPI50.h added.
+//
+// 3 11/08/11 4:45p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added.
+// [Files] AcpiCore.c, AmiDxeLib.h, CSM.c, DxeMain.c, EfiLib.c,
+// Image.c, S3Resume.c and FirmPerfDataTab.h
+//
+// 2 7/19/11 11:33a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 25 11/24/09 5:21p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support.
+//
+// 24 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 23 10/03/08 3:20p Felixp
+// Performance measurement support added
+//
+// 19 4/15/08 9:09p Yakovlevs
+// Added support to chech for wake vector in all instances of FACS.
+// EndOfPEIPhase PPI now installed.
+//
+// 18 4/09/08 5:52p Markw
+// Install End of PEI PPI.
+//
+// 17 8/07/07 2:51p Felixp
+// Additional Status Codes added
+//
+// 16 5/18/07 11:11a Markw
+// Reintialize gdt before calling thunk.
+//
+// 15 4/23/07 1:31p Felixp
+// Boot Script related code moved from Core to ACPI module.
+// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver.
+//
+// 14 3/13/07 11:58a Felixp
+// Error reporting updated to use new PEI_ERROR_CODE macro
+//
+// 13 2/07/07 3:08p Markw
+// Add video repost support setup question.
+//
+// 12 1/23/07 4:24p Markw
+// Added thunk support for a call for S3 video repost.
+//
+// 11 4/03/06 4:01p Felixp
+// New Super I/O infrastructure Support
+//
+// 10 12/12/05 9:25p Yakovlevs
+// SIO-specific core surrounded by #ifdefs
+//
+// 9 12/05/05 11:32a Yakovlevs
+// Disabled Generation of SW SMI in order to switch to ACPI mode.
+// System waking up from S3 with SCI_ENABLE bit ON.
+//
+// 8 10/09/05 11:27a Felixp
+// Performance measurements added.
+//
+// 7 5/27/05 4:23p Markw
+// Added Keyboard init.
+//
+// 6 5/10/05 2:50p Markw
+// Use 16bit selectors for data segment.
+//
+// 5 5/07/05 11:53p Markw
+// Store GDT in memory. Give pointer to GDT descripteor base/limit to wake
+// up.
+//
+// 4 5/06/05 5:07p Markw
+// Added 16 bit wakeup support.
+//
+// 3 5/04/05 12:24p Markw
+// Moved structure definitions to AcpiS3.h.
+//
+// 2 4/29/05 3:26p Markw
+//
+// 1 4/29/05 12:17p Sivagarn
+//
+// 5 4/05/05 2:19p Markw
+// Added enable ACPI Mode.
+//
+// 4 3/31/05 11:11a Markw
+// Add wakeup vector support.
+//
+// 3 3/28/05 6:01p Markw
+// Fixed bug. NVRAM variable is address not data.
+//
+// 2 3/27/05 6:36p Markw
+// Execute Boot Script supported added.
+//
+// 1 3/25/05 5:37p Markw
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: S3Resume.c
+//
+// Description: Restore configuration state from S3 resume.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Pei.h>
+#include <Ppi\S3Resume.h>
+#include <Ppi\S3Resume2.h>
+#include <ppi\BootScriptExecuter.h>
+#include <Ppi\ReadOnlyVariable2.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <setup.h>
+#include "AcpiS3.h"
+#include "AcpiPeiS3Func.h"
+#include "AMICSPLIBInc.H"
+#include <ACPI50.h>
+
+#pragma pack(1)
+typedef struct {
+ UINT16 GdtLimit;
+ UINT64 *GdtBase;
+} PTR_GDT_DESCS;
+#pragma pack()
+
+extern UINT32 RealModeThunkStart;
+extern UINT32 RealModeThunkSize;
+
+EFI_GUID gEfiPeiS3ResumePpiGuid = EFI_PEI_S3_RESUME_PPI_GUID;
+EFI_GUID gEfiPeiBootScriptExecuterPpiGuid = EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID;
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+extern EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid;
+EFI_GUID gEfiSetupGuid = SETUP_GUID;
+
+CHAR16 gSetupVariable[] = L"Setup";
+
+VOID RealModeThunk(PTR_GDT_DESCS *GdtDesc, UINT32 Firmware_Waking_Vector, BOOLEAN UseCall);
+typedef VOID(*REAL_MODE_THUNK_FUNCTION)(PTR_GDT_DESCS*, UINT32, BOOLEAN);
+//Boot Script Executer module initialization routine
+EFI_STATUS InitBootScriptExecuter(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+//S3 Resume PPI routine
+//Defined in this file
+EFI_STATUS S3RestoreConfig(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+EFI_STATUS S3RestoreConfig2(
+ IN EFI_PEI_S3_RESUME2_PPI *This
+);
+//To be copied to memory.
+UINT64 gGDT[] = {
+ 0, //NULL_SEL
+ 0x00009a000000ffff, //CODE_SEL 0x08 16-bit code selector, limit of 4K
+ 0x000093000000ffff //DATA_SEL 0x10, 16-bit data selector Data 0-ffffffff
+};
+
+//PPI to be installed
+EFI_PEI_S3_RESUME_PPI S3ResumePpi = {S3RestoreConfig};
+EFI_PEI_S3_RESUME2_PPI S3ResumePpi2 = {S3RestoreConfig2};
+
+static EFI_PEI_PPI_DESCRIPTOR gPpiList[] = {
+ {EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiPeiS3ResumePpiGuid,
+ &S3ResumePpi},
+
+ {(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiS3Resume2PpiGuid,
+ &S3ResumePpi2}
+};
+
+static EFI_PEI_PPI_DESCRIPTOR gEndOfPpiList[] = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ NULL
+};
+
+VOID InitLongModeExt(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2,
+ IN UINT8 NumMemBits
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: S3RestoreConfig
+//
+// Description: Restore configuration state from S3 resume.
+//
+// Input: EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS S3RestoreConfig(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ UINT32 i;
+ PTR_GDT_DESCS *GdtDesc;
+ UINT64 *Gdt;
+
+ ACPI_VARIABLE_SET *AcpiVariableSet;
+ EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *BootScript;
+ EFI_PHYSICAL_ADDRESS BootScriptTable;
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable;
+ SETUP_DATA SetupData;
+ BOOLEAN IsSetupDataValid;
+ UINTN VariableSize=sizeof(SETUP_DATA);
+#endif
+ void(*X_Firmware_Waking_Vector)();
+ UINT32 Firmware_Waking_Vector;
+ UINTN VarSize = sizeof(UINT32);
+ EFI_FPDT_STRUCTURE *FpdtVar;
+
+ PEI_PERF_START(PeiServices,S3RESUME_TOK,NULL,0);
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_STARTED);
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0, NULL,
+ &ReadOnlyVariable
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+#endif
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gEfiPeiBootScriptExecuterPpiGuid,
+ 0,
+ NULL,
+ &BootScript
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ if (EFI_ERROR(Status)){
+ PEI_ERROR_CODE(PeiServices, PEI_S3_BOOT_SCRIPT_ERROR, EFI_ERROR_MAJOR);
+ return Status;
+ }
+
+ AcpiVariableSet = GetAcpiS3Info(PeiServices);
+ if (!AcpiVariableSet){
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No Acpi Global Variable\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_ERROR, EFI_ERROR_MAJOR);
+ return EFI_NOT_FOUND;
+ }
+
+ BootScriptTable = AcpiVariableSet->AcpiBootScriptTable;
+
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ VariableSize = sizeof(SETUP_DATA);
+ Status = ReadOnlyVariable->GetVariable(
+ ReadOnlyVariable,
+ gSetupVariable, &gEfiSetupGuid,
+ NULL,
+ &VariableSize, &SetupData
+ );
+ IsSetupDataValid = !EFI_ERROR(Status);
+#endif
+
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_BOOT_SCRIPT);
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Executing Boot Script Table.\n"));
+ Status = BootScript->Execute(
+ PeiServices,
+ BootScript,
+ BootScriptTable,
+ NULL
+ );
+ if (EFI_ERROR(Status))
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Error executing Boot Script Table.\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_BOOT_SCRIPT_ERROR, EFI_ERROR_MAJOR);
+ }
+
+//for legacy free systems it will be infinite loop
+
+ //keyboard init
+ #define KBC_CMDSTS_PORT 0x64
+ #define KBC_DATA_PORT 0x60
+ #define KBC_IBF 0x02
+ if( IoRead8(KBC_CMDSTS_PORT) != 0xff){
+ IoWrite8(KBC_CMDSTS_PORT, 0xaa);
+ for (;;) {
+ if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) {
+ break;
+ }
+ }
+ }
+
+ _asm cli
+
+ //allocate memory for GDT and copy to Thunk to 16-bit.
+ (*PeiServices)->AllocatePool(PeiServices,sizeof(gGDT), &Gdt);
+
+ //Allocate memory for descriptor.
+ (*PeiServices)->AllocatePool(PeiServices,sizeof(PTR_GDT_DESCS), &GdtDesc);
+ GdtDesc->GdtLimit = sizeof(gGDT)-1;
+ GdtDesc->GdtBase = Gdt;
+
+ (*PeiServices)->InstallPpi(PeiServices, gEndOfPpiList);
+
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ if (IsSetupDataValid && SetupData.S3ResumeVideoRepost) {
+ //The following code executes video option ROM at c000:0003.
+ //For the video option ROM, a thunk is needed to 16-bit.
+ //The Thunk and the area for 16-bit stack are located starting at
+ //ACPI_THUNK_REAL_MODE_SEGMENT * 16 with a length ACPI_THUNK_STACK_TOP.
+
+ VOID *RealModeThunkSave;
+
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_VIDEO_REPOST);
+ //Allocate memory to perserve the the thunk region.
+ Status = (*PeiServices)->AllocatePool(PeiServices, ACPI_THUNK_STACK_TOP, &RealModeThunkSave);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //Save the thunk and stack region.
+ MemCpy(RealModeThunkSave, (VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), ACPI_THUNK_STACK_TOP); //Save Region to copy
+ //Copy the thunk code.
+ MemCpy((VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), (VOID*)RealModeThunkStart, RealModeThunkSize);
+
+ //Open 0xc0000 region--the video option ROM.
+ NBPeiProgramPAMRegisters(
+ PeiServices,
+ 0xc0000,
+ 0x10000,
+ LEGACY_REGION_UNLOCK,
+ NULL
+ );
+
+ //Call video option rom: C000:0003.
+ for(i = 0; i < sizeof(gGDT)/sizeof(UINT64); ++i) Gdt[i] = gGDT[i]; //Set GDT for Thunk to 16-bit
+ ((REAL_MODE_THUNK_FUNCTION)(ACPI_THUNK_REAL_MODE_SEGMENT * 16))(GdtDesc, 0xc0000003, TRUE);
+
+ //Close c000 region
+ NBPeiProgramPAMRegisters(
+ PeiServices,
+ 0xc0000,
+ 0x10000,
+ LEGACY_REGION_LOCK,
+ NULL
+ );
+
+ //Restore region where THUNK and 16-bit stack was copied over.
+ MemCpy((VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), RealModeThunkSave, ACPI_THUNK_STACK_TOP); //Restore region.
+ }
+#endif
+
+ PEI_TRACE((-1, PeiServices, "Smm S3 resume -- ACPI Mode Enable.\n"));
+ if (!AcpiVariableSet->AcpiFacsTable[0] && \
+ !AcpiVariableSet->AcpiFacsTable[1] && \
+ !AcpiVariableSet->AcpiFacsTable[2])
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No ACPI FACS Table\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_ERROR, EFI_ERROR_MAJOR);
+ }
+
+ PEI_PERF_END(PeiServices,S3RESUME_TOK,NULL,0);
+ PEI_PERF_SAVE_S3_DATA(PeiServices);
+
+ Status = PeiGetVariable(
+ PeiServices,
+ L"FPDT_Variable_NV", &gAmiGlobalVariableGuid,
+ NULL, &VarSize, &FpdtVar
+
+ );
+ if (!EFI_ERROR (Status))
+ {
+ if (((PERF_TAB_HEADER*)(UINT8*)(FpdtVar->S3Pointer))->Signature == 0x54503353)
+ {
+ BASIC_S3_RESUME_PERF_REC *S3PerRec;
+ UINT64 NanoTime;
+ S3PerRec = (BASIC_S3_RESUME_PERF_REC*)((UINT8*)(FpdtVar->S3Pointer) + sizeof(PERF_TAB_HEADER));
+ if ((FpdtVar->NanoFreq !=0) && (S3PerRec->Header.PerfRecType == 0))
+ {
+ NanoTime = Div64 (Mul64 (GetCpuTimer (), (UINTN)FpdtVar->NanoFreq), 1000000 , NULL);
+
+ S3PerRec->AverageResume = Div64 ((Mul64 (S3PerRec->AverageResume, (UINTN)(S3PerRec->ResumeCount)) + NanoTime),
+ (UINTN)(S3PerRec->ResumeCount + 1), NULL);
+ S3PerRec->FullResume = NanoTime;
+ S3PerRec->ResumeCount++;
+
+ }
+ }
+ }
+
+ //If given control to X_Firmware_Waking_Vector. It will not return.
+ // Search each FACS table for a valid vector
+ for (i = 0; i < 3; i++ ) {
+ if (!AcpiVariableSet->AcpiFacsTable[i]) continue;
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Trying FACS table #%d.\n", i + 1));
+ X_Firmware_Waking_Vector = (void(*)())*(VOID**)((UINT8*)AcpiVariableSet->AcpiFacsTable[i] + 24);
+ if (X_Firmware_Waking_Vector)
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in protected mode.\n"));
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_OS_WAKE);
+ PEI_TRACE((-1, PeiServices, "Smm S3 Vector %x.\n", X_Firmware_Waking_Vector));
+ if (((UINT32*)AcpiVariableSet->AcpiFacsTable[i] + 36) && 1)
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in protected mode 64 bit enable.\n"));
+ InitLongModeExt (PeiServices, X_Firmware_Waking_Vector, NULL, NULL, 12);
+ }
+ else
+ X_Firmware_Waking_Vector(); // Will not return
+ }
+
+ Firmware_Waking_Vector = *(UINT32*)((UINT8*)AcpiVariableSet->AcpiFacsTable[i] + 12);
+ if (Firmware_Waking_Vector)
+ {
+ UINT32 RealModeSegOff;
+
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in real mode.\n"));
+ PEI_TRACE((-1, PeiServices, "Smm S3 Vector %x.\n", Firmware_Waking_Vector));
+ RealModeSegOff = ((Firmware_Waking_Vector & ~0xf) << 12) + (Firmware_Waking_Vector & 0xf);
+
+ //Execute this thunk from ROM.
+ for(i = 0; i < sizeof(gGDT)/sizeof(UINT64); ++i) Gdt[i] = gGDT[i]; //Set GDT for Thunk to 16-bit
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_OS_WAKE);
+ RealModeThunk(GdtDesc, RealModeSegOff, FALSE); //Will not return.
+ }
+ }
+
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No waking vector.\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_OS_WAKE_ERROR, EFI_ERROR_MAJOR);
+
+ return EFI_UNSUPPORTED;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: S3RestoreConfig2
+//
+// Description: Restore configuration state from S3 resume.
+//
+// Input: EFI_PEI_S3_RESUME2_PPI *This
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS S3RestoreConfig2(
+ IN EFI_PEI_S3_RESUME2_PPI *This
+)
+{
+ EFI_PEI_SERVICES **PeiServices;
+
+ if (This != &S3ResumePpi2) return EFI_INVALID_PARAMETER;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ return S3RestoreConfig(PeiServices);
+
+}
+
+EFI_STATUS S3ResumeEntryPoint(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ //Initialize Boot Script Executer module
+ InitBootScriptExecuter(FfsHeader,PeiServices);
+ return (*PeiServices)->InstallPpi(PeiServices,gPpiList);
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/S3/S3Resume.dxs b/Core/EM/S3/S3Resume.dxs
new file mode 100644
index 0000000..194ac48
--- /dev/null
+++ b/Core/EM/S3/S3Resume.dxs
@@ -0,0 +1,85 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Resume.dxs 2 7/19/11 11:33a Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 7/19/11 11:33a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Resume.dxs $
+//
+// 2 7/19/11 11:33a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/23/07 1:31p Felixp
+// Boot Script related code moved from Core to ACPI module.
+// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: S3Resume.dxs
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Ppi/ReadOnlyVariable2.h>
+
+DEPENDENCY_START
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID AND
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/S3Save.cif b/Core/EM/S3/S3Save.cif
new file mode 100644
index 0000000..423bbc2
--- /dev/null
+++ b/Core/EM/S3/S3Save.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "S3Save"
+ category = ModulePart
+ LocalRoot = "Core\EM\S3\"
+ RefName = "S3Save"
+[files]
+"S3Save.sdl"
+"S3Save.mak"
+"AcpiS3Save.c"
+"BootScriptPrivate.h"
+"BootScriptSave.c"
+"AcpiS3Save.dxs"
+"SmmS3Save.dxs"
+<endComponent>
diff --git a/Core/EM/S3/S3Save.mak b/Core/EM/S3/S3Save.mak
new file mode 100644
index 0000000..9bc43e7
--- /dev/null
+++ b/Core/EM/S3/S3Save.mak
@@ -0,0 +1,99 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/S3Save.mak 2 3/18/11 3:56p Oleksiyy $
+#
+# $Revision: 2 $
+#
+# $Date: 3/18/11 3:56p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/S3Save.mak $
+#
+# 2 3/18/11 3:56p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Improving backward computability and architecture.
+# [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak,
+# S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h,
+# S3smmSaveState.h
+#
+# 1 2/03/11 4:08p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Create new label of ACPI with separate S3 Functionality
+# [Files] S3Save.cif
+# S3Save.sdl
+# S3Save.mak
+# AcpiS3.h
+# AcpiS3Save.c
+# BootScriptPrivate.h
+# BootScriptSave.c
+# AcpiS3Save.dxs
+# SmmS3Save.dxs
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <ComponentName>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : S3Save
+
+!IFNDEF PI_SPECIFICATION_VERSION
+PI_SPECIFICATION_VERSION = 0
+!ENDIF
+
+S3Save : $(BUILD_DIR)\S3Save.mak S3SaveBin
+
+$(BUILD_DIR)\S3Save.mak : $(S3Save_DIR)\$(@B).cif $(S3Save_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(S3Save_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+S3SaveBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\S3Save.mak all\
+ GUID=26A2481E-4424-46a2-9943-CC4039EAD8F8 \
+ ENTRY_POINT=AcpiS3SaveEntryPoint\
+ "MY_INCLUDES=/I$(ACPI_CORE_DIR)" \
+!IF $(PI_SPECIFICATION_VERSION) >= 0x00001000A
+ TYPE=DXESMM_DRIVER \
+ DEPEX1=$(S3Save_DIR)\SmmS3Save.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ DEPEX2=$(S3Save_DIR)\AcpiS3Save.dxs \
+ DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \
+!ELSE
+ DEPEX1=$(S3Save_DIR)\AcpiS3Save.dxs \
+ TYPE=BS_DRIVER \
+!ENDIF
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/S3/S3Save.sdl b/Core/EM/S3/S3Save.sdl
new file mode 100644
index 0000000..fc09ec2
--- /dev/null
+++ b/Core/EM/S3/S3Save.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "S3Save_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable S3Save Support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "S3Save_DIR"
+End
+
+MODULE
+ Help = "Includes S3Save.mak to Project"
+ File = "S3Save.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\S3Save.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/S3/S3Support.cif b/Core/EM/S3/S3Support.cif
new file mode 100644
index 0000000..af97bb6
--- /dev/null
+++ b/Core/EM/S3/S3Support.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "S3Support"
+ category = ModulePart
+ LocalRoot = "Core\EM\S3\"
+ RefName = "S3Support"
+[files]
+"S3Support.sdl"
+[parts]
+"S3Save"
+"S3Restore"
+"S3Common"
+<endComponent>
diff --git a/Core/EM/S3/S3Support.sdl b/Core/EM/S3/S3Support.sdl
new file mode 100644
index 0000000..f5a858b
--- /dev/null
+++ b/Core/EM/S3/S3Support.sdl
@@ -0,0 +1,9 @@
+TOKEN
+ Name = S3Support_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable S3Support support in Project"
+End
diff --git a/Core/EM/S3/SmmS3Save.dxs b/Core/EM/S3/SmmS3Save.dxs
new file mode 100644
index 0000000..abbc621
--- /dev/null
+++ b/Core/EM/S3/SmmS3Save.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/SmmS3Save.dxs 1 2/03/11 4:08p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 2/03/11 4:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/SmmS3Save.dxs $
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/24/07 6:27p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiS3Save.dxs
+//
+// Description: Dependency expression for the AcpiS3Save component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SMBIOSCore.CIF b/Core/EM/SMBIOS/SMBIOSCore.CIF
new file mode 100644
index 0000000..499fb8d
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBIOSCore.CIF
@@ -0,0 +1,17 @@
+<component>
+ name = "SMBIOS - Core Source"
+ category = eModule
+ LocalRoot = "Core\EM\SMBIOS\"
+ RefName = "SMBIOSCore"
+[files]
+"SMBios.c"
+"SMBiosCoreSrc.sdl"
+"SMBios.mak"
+"SMBios.dxs"
+"SMBiosCore.chm"
+[parts]
+"SmbiosDMIEdit"
+"SmbiosGetFlashData"
+"SmbiosFlashData"
+"SmbiosPeim"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SMBios.c b/Core/EM/SMBIOS/SMBios.c
new file mode 100644
index 0000000..de38fe0
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBios.c
@@ -0,0 +1,8091 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SMBios.c 157 4/19/16 4:10p Davidd $
+//
+// $Revision: 157 $
+//
+// $Date: 4/19/16 4:10p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SMBios.c $
+//
+// 157 4/19/16 4:10p Davidd
+// [TAG] EIP231162
+// [Category] New Feature
+// [Description] Merge Aptio V Smbios -09 changes for Aptio 4
+// 4.6.5.5_SMBIOS_40 release
+// [Files] Smbios.c
+//
+// 156 4/07/16 6:01p Davidd
+// [TAG] EIP231162
+// [Category] New Feature
+// [Description] Merge Aptio V Smbios -09 changes for Aptio 4
+// 4.6.5.5_SMBIOS_40 release
+// [Files] Smbios.c
+// SmbiosDmiEdit.c
+// SmbiosDmiEditFunc.c
+//
+// 155 2/22/16 2:41p Davidd
+// [TAG] EIP254247
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Static code analysis issues found in Aptio4 SMBIOS - Core
+// Source module
+// [RootCause] Function CheckForType4AndUpdate is not typed
+// [Solution] Added VOID type to function CheckForType4AndUpdate
+// [Files] Smbios.c
+//
+// 154 8/11/14 10:52a Davidd
+// [TAG] EIP181005
+// [Category] Improvement
+// [Description] Updated version number for Aptio 4 4.6.5.4_SMBIOS_38
+// release
+// [Files] Smbios.c
+//
+// 153 8/11/14 10:42a Davidd
+// [TAG] EIP177887
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error if token "SYS_CHASSIS_INFO" set to "0"
+// [RootCause] Build error caused by non-existence token when
+// SYS_CHASSIS_INFO is disabled
+// [Solution] Added preprocessor checks
+// [Files] Smbios.c
+// SmbiosDmiEditFunc.c
+//
+// 152 8/08/14 1:19p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] SMBIOSCore.cif
+// SMBios.c
+// New SmbiosPeim module part
+//
+// 151 6/13/14 3:22p Davidd
+// [TAG] EIP171151
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Smbios Type 12 - Changes beyond string #8 were not
+// persistent across the reboot
+// [RootCause] Test flag is only 8 bits
+// [Solution] Create and use array of test flags for specified number of
+// Type 12 structure
+// [Files] Smbios.c
+// Smbios.h
+//
+// 150 4/29/14 4:42p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] SMBIOSCore.cif
+// SMBios.c
+// New SmbiosPeim module part
+//
+// 149 2/14/14 12:41p Davidd
+// [TAG] EIPEIP152598
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS UUID can't be updated by DMIEdit tool
+// [RootCause] Update flag not set for changing UUID field
+// [Solution] Set Update flag when changing UUID field
+// [Files] Smbios.c
+//
+// 148 11/18/13 1:00p Davidd
+//
+//
+// [TAG] EIP143631
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Silent code corruption caused by AddProducerHandle
+// routine
+// [RootCause] Variable "i" declare as unsigned eight bit integer,
+// should be sixteen bit because PRODUCER_HANDLE_ELEMENTS is set to value
+// 0x200
+// [Solution] Changed variable "i" to 16-bit
+// [Files] Smbios.c
+//
+// 147 11/15/13 4:32p Davidd
+// [TAG] EIP143321
+// [Category] Improvement
+// [Description] Perform "CppCheck" on Smbios module for
+// '4.6.5.1_SMBIOS_36' release
+// [Files] SmbiosBoard.c
+// Smbios.c
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 146 8/23/13 6:23p Davidd
+// [TAG] EIP132364
+// [Category] Improvement
+// [Description] DMIEdit fails to update in the following cases:
+// 1. When current string is NULL
+// 2. When structure is created by OEM
+// 3. When structure is created with strings not numbered sequentially
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+//
+// 145 6/03/13 6:25p Davidd
+// [TAG] EIP125665
+// [Category] New Feature
+// [Description] Request to Support multiple instances of SMBIOS Type 3
+// structure (merge EIP106206 into Aptio 4)
+// [Files] Smbdata.mac
+// SmbiosStaticData.sdl
+// Smbstruc.def
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbios.h
+//
+// 144 6/03/13 4:18p Davidd
+// [TAG] EIP104836
+// [Category] New Feature
+// [Description] DMIEdit support edit type 4
+// [Files] Smbios.c
+//
+// 143 5/29/13 12:51p Davidd
+// [TAG] EIP124735
+// [Category] Spec Update
+// [Severity] Normal
+// [Description] SMBIOS 2.8.0 specification support for Aptio 4
+// [Files] Smb.equ
+// Smbdata.mac
+// Smbdesc.def
+// Smbstruc.def
+// Smbios.c
+// Smbios.h
+// SmbiosDynamicData.h
+//
+// 142 5/23/13 2:41p Davidd
+// [TAG] EIP104836
+// [Category] New Feature
+// [Description] DMIEdit support edit type 4
+// [Files] SmbiosBoard.c
+// SmbiosDMIEditBoard.sdl
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbios.h
+// SmbiosDynamicData.h
+//
+// 141 5/23/13 10:43a Davidd
+// [TAG] EIP124483
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] After updating to SMBIOS 33, issue found with smbios type 4
+// &7 & 10 & 11 & 13 &14
+// [RootCause] Changes in EIP99697
+// [Solution] Added control token SMBIOS_DYNAMIC_UPDATE_POLICY. Default
+// setting is 0 to do dynamic update at Ready To Boot event for backward
+// compatibility.
+// [Files] Smbios.sdl
+// Smbios.c
+//
+// 140 3/15/13 3:37p Davidd
+// [TAG] EIP118222
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error in Core\EM\SMBIOS\SMBios.c
+// [RootCause] "Status" variable declared outside of all "#if"
+// statements therefore when all "#if" statement evaluated to false,
+// "Status" variable becomes un-used
+// [Solution] Initialize "Status" variable on declaration.
+// [Files] Smbios.c
+//
+// 139 12/27/12 11:05a Davidd
+// [TAG] EIP108986
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS type 13 structure not present
+// [RootCause] This problem is caused by recent change for EIP98861
+// (function AddUpdateType13 was moved to UpdateDynamic)
+// [Solution] Move AddUpdateType13 function back to SmbiosDynamicUpdate
+// [Files] Smbios.c
+//
+// 138 9/19/12 1:32p Davidd
+// [TAG] EIP101114
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System got an assert and hung after updated Smbios -031 to
+// -032 label
+// [RootCause] Bug in "SmbiosPiGetNextStructure" function.
+// [Solution] Revised "SmbiosPiGetNextStructure" function.
+// [Files] Smbios.c
+//
+// 137 9/04/12 4:49p Davidd
+// [TAG] EIP100134
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS type 17 dimm Rank information is not correct.
+// [RootCause] Error in function "DynamicUpdateMemoryData"
+// [Solution] For DDR3, ranking information is at SPD byte 7 bits 5-3.
+// Code has been added to properly shift the value being read before it is
+// used.
+// [Files] Smbios.c
+//
+// 136 9/04/12 2:49p Davidd
+// [TAG] EIP99697
+// [Category] Improvement
+// [Description] To make a generic fix for the SMBIOS type 19 problem
+// (see parent EIP 98861)
+// [Files] Smbios.c
+//
+// 135 8/02/12 12:41p Davidd
+// [TAG] EIP96064
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS: DmiEdit support creates NVRAM variables with names
+// of incorrect length
+// [RootCause] Swprintf_s function creates 15 characters variable name
+// with NULL terminator in last byte.
+// [Solution] Use Swprintf function instead
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 134 6/12/12 5:11p Davidd
+// [TAG] EIP63922
+// [Category] Improvement
+// [Description] After udpate SMBIOS to v30, system hang at CKP 0xA0 if
+// DEBUG_MODE = 1.
+// Note: Changes made for TMP usage of Smbios.
+// [Files] Smbios.c
+//
+// 133 6/12/12 10:34a Davidd
+// [TAG] EIP92170
+// [Category] Improvement
+// [Description] Adding DmiEdit support for multiple instances of Smbios
+// type 39 structure to match with AMI DmiEdit tool
+// [Files] Smbios.c
+//
+// 132 6/11/12 11:30a Davidd
+// [TAG] EIP92170
+// [Category] Improvement
+// [Description] Adding DmiEdit support for multiple instances of Smbios
+// type 39 structure to match with AMI DmiEdit tool
+// [Files] Smbios.h
+// Smbios.c
+// SmbiosStaticData.sdl
+//
+// 131 4/09/12 12:45p Davidd
+// [TAG] EIP86776
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Build error if "OEM_STRING_INFO" token is set to "0"
+// [RootCause] SMBIOS_OEM_STRINGS_INFO definition is used even when
+// OEM_STRING_INFO is disabled.
+// [Solution] Removed reference to "SMBIOS_OEM_STRINGS_INFO" in
+// "GetStructureLength" function (not really needed).
+// [Files] Smbios.c
+//
+// 130 4/09/12 12:32p Davidd
+// [TAG] EIP86487
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] AMIDEDOS update Type 3 Asset Tag failed
+// [RootCause] Incorrectly checking for empty string size
+// [Solution] Corrected code
+// [Files] Smbios.c
+//
+// 129 3/26/12 12:06p Davidd
+// [TAG] EIP84370
+// [Category] New Feature
+// [Description] Flash memory(type 16 and 17) on aptio
+// [Files] Smbdata.mac
+// SmbiosStaticData.asm
+// SmbiosStaticData.sdl
+// Smbios.c
+// Smbios.mak
+// Smbios.h
+//
+// 128 3/16/12 5:36p Davidd
+// [TAG] EIP84942
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Incorrect "next handle" returned by Smbios->GetNext
+// function
+// [RootCause] Next handle incorrectly return with next sequential
+// record handle.
+// [Solution] Modified code to return next record handle having the same
+// input type.
+// [Files] Smbios.c
+//
+// 127 3/09/12 10:59a Davidd
+// [TAG] EIP81469
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS protocl didn't compatible with PI1.1
+// [RootCause] PI1.1 protocol functions incorrectly added after AMI
+// functions of Smbios protocols.
+// [Solution] Moved PI1.1 protocol functions to the top of the protocol.
+// [Files] Smbios.c
+// Smbios.h
+//
+// 126 3/08/12 5:17p Davidd
+// [TAG] EIP81171
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Smbios->GetNext function fail when type is NULL
+// [RootCause] GetNext function does not checked for Type pointer
+// [Solution] Added code to check for Type pointer in GetNext function
+// [Files] Smbios.c
+//
+// 125 2/02/12 12:36p Davidd
+// [TAG] EIP81514
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Wrong handle number assigned to the structure when adding
+// structure with a specific handle number using Smbios "Add" protocol
+// [RootCause] Handle number is not updated when "Add" protocol is
+// called with a specific handle number.
+// [Solution] Change code to update handle number
+// [Files] Smbios.c
+//
+// 124 2/02/12 10:09a Davidd
+// [TAG] EIP81010
+// [Category] Improvement
+// [Description] Smbios type 13 only supports a subset of languages
+// supported by the CORE
+// [Files] Smbios.c
+//
+// 123 1/17/12 4:52p Davidd
+// [TAG] EIP78264
+// [Category] Improvement
+// [Description] SMBOS Type 2 (Spec 2.7.1) - No multiple type 2 support
+// [Files] Smbios.c
+// Smbios.h
+// Smbdata.mac
+// Smbdesc.def
+// SmbiosStaticData.sdl
+//
+// 122 1/06/12 3:26p Davidd
+// [TAG] EIP78790
+// [Category] Improvement
+// [Description] Locating LegacyRegion2 Protocol fails in SMBIOS31 when
+// Bios is Built with PI 1.1 or lesser
+// [Files] Smbios.c
+// Smbios.dxs
+//
+// 121 12/01/11 5:08p Davidd
+// [TAG] EIP76832
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] On 4641 Core after Updating to 4.6.3_SMBIOS_31 and
+// adding 4.6.5.1_ForwCompatibility_01 system asserts in Smbios64.Entry()
+// [RootCause] Problem caused by a redundant FreePool call in
+// UpdateStructuresWithNvramData function
+// [Solution] Removed the redundant FreePool call in
+// UpdateStructuresWithNvramData function
+// [Files] Smbios.c
+//
+// 120 11/17/11 2:37p Davidd
+// [TAG] EIP74579
+// [Category] Improvement
+// [Description] Update SMBIOS moudule to let AMDELNX support SMBIOS
+// spec 2.7
+// (remove the 64 characters string limitation)
+// [Files] Smbios.h
+// SmbiosStaticData.sdl
+// Smbios.c
+// SMBios.dxs
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosNvram.c
+// SmbiosFlashData.sdl
+//
+// 119 10/06/11 5:32p Davidd
+// EIP65648 extended change, and some operator usage error corrections.
+//
+// 118 9/29/11 5:18p Davidd
+// [TAG] EIP71370
+// [Category] Improvement
+// [Description] Customer names in source files
+// [Files] Smbios.c
+//
+// 117 9/29/11 4:38p Davidd
+// [TAG] EIP68202
+// [Category] NEW FEATURE
+// [Description] Allow Smbios Type 2 Location field and Type 3 SKU
+// Number field
+// to be apdated by dmieditwingui tool
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbdata.mac
+//
+// 116 8/30/11 4:11p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 115 8/12/11 10:57a Davidd
+// [TAG] EIP60077
+// [Category] Improvement
+// [Description] BSP waits for all Aps forever when
+// SmbiosAddStrucByHandle () function is called from SMM
+// [Files] Smbios.c
+//
+// 114 8/11/11 12:17p Davidd
+// [TAG] EIP66223
+// [Category] Bug Fix
+// [Severity] Immediate/Critical
+// [Symptom] Status check is missing from Code that tries to call
+// LoadRealModeFileSection()
+// [RootCause] Status check is missing
+// [Solution] Added code to check for status after call to
+// LoadRealModeFileSection()
+// [Files] Smbios.c
+//
+// 113 8/03/11 10:53a Davidd
+// [TAG] EIP64029
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 22 to be modified using DMIEdit
+// [Files] Smbios.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+//
+// 112 8/03/11 10:23a Davidd
+// [TAG] EIP65551
+// [Category] Bug Fix
+// [Severity] Non-Urgent
+// [Symptom] There is an issue in adding a new table to SMBIOS by
+// using PI 1.1 protocol
+// [RootCause] SmbiosHandle parameter is not updated with assigned
+// handle number
+// [Solution] Update SmbiosHandle parameter with assigned handle
+// number
+// [Files] Smbios.c
+//
+// 111 6/16/11 12:25p Davidd
+// [TAG] EIP61776
+// [Category] Improvement
+// [Description] SMBIOS Type 17 "Type Detail" Registered/Unbuffered,
+// needs to be dynamically updated
+// [Files] Smbios.sdl
+// SmbiosDynamicData.h
+// Smbios.c
+//
+// 110 5/25/11 10:20a Davidd
+// [TAG] EIP57961
+// [Category] Bug Fix
+// [Severity] Non-Urgent
+// [Symptom] AMIDEDOS.exe fails to flash UUID & serial number
+// [RootCause] E000-F000 is locked during E000 memory allocation for
+// Smbios table.
+// [Solution] Unlock E000 prior to allocation and lock it afterward.
+// [Files] Smbios.c
+//
+// 109 5/24/11 10:36a Davidd
+// [TAG] EIP60846
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS build error after disable "MEMORY_DEVICE_INFO"
+// [RootCause] Local variable "SmbDmap" is unreferenced when
+// MEMORY_DEVICE_INFO token is turned off.
+// [Solution] Added conditional compilation check around "SmbDmap"
+// variable.
+// [Files] Smbios.c
+//
+// 108 5/13/11 5:21p Davidd
+// [TAG] EIP57758
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] DMIEDIT tool shows error message "Cann't update Smbios
+// Date with PNP function on current system!!" "Error getting DMI
+// data!!(Error code : 12000E)"
+// [RootCause] Because Smbios Structure Table Entry Point header is
+// relocated on ReadyToBoot, it could not be found at runtime.
+// [Solution] Allocate runtime memory for Smbios Structure Table
+// Entry Point header on Smbios driver entry point.
+// [Files] Smbios.c
+// Smbios.dxs
+//
+// 107 5/11/11 12:32p Davidd
+// [TAG] EIP58171
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible for AFU preserve DMI structure feature.
+// [RootCause] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible.
+// [Solution] New TABLE_INFO structure defined for backward
+// compatibility and support added.
+// [Files] Smbios.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+//
+// 106 5/06/11 10:52a Davidd
+// [TAG] EIP58832
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] [Type 11]Oem String can't be updated from nvram if
+// string number >8
+// [RootCause] Size of variable used to test the strings was wrong.
+// [Solution] Corrected the size of the variable.
+// [Files] Smbios.c
+//
+// 105 5/04/11 3:18p Davidd
+// [TAG] EIP57144
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 39 to be modified using DMIEdit
+// [Files] SmbiosBoard.c
+// Smbios.h
+// SmbiosDynamicData.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+// SmbiosNvramFunc.c
+//
+// 104 4/05/11 11:06a Davidd
+// [TAG] EIP57586
+// [Category] Improvement
+// [Description] Build error in SMBios module when CSM_SUPPORT token
+// turned OFF
+// [Files] SmbiosBoard.c - File version: 24
+//
+// 103 1/27/11 10:52a Davidd
+// [TAG] EIP52709
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] After we update SMBIOS Type11 using SMBCFG.exe in debug
+// mode and then reboot, system will hang up
+// [RootCause] FreePool in UpdateSmbiosTable function is called with a
+// pointer pointing to an allocated memory location plus some offset the
+// first time.
+// [Solution] Skip FreePool call in UpdateSmbiosTable function the first
+// time. This memory is freed later in SmbiosDriverEntryPoint function.
+// [Files] Smbios.c
+//
+// 102 12/14/10 3:38p Davidd
+// Updated StringType_3 table to include SKU string field.
+//
+// 101 12/10/10 3:04p Davidd
+// [TAG] EIP49728
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] SMBIOS Type 10 Data incorrect
+// [RootCause] Macro to create Type 10 structure is incorrect.
+// [Solution] Modified macro to create one Type 10 Entry containing
+// the number of ONBOARD_DEVICES.
+// [Files]
+// Smbdata.mac
+// Smbios.c
+//
+// 100 12/08/10 10:56a Davidd
+// [TAG] EIP48952
+// [Category] Improvement
+// [Description] Customer Request for SMBIOS Type 16
+// MemoryErrorCorrection field to be filled out
+// [Files]
+// Smbios.c
+// SmbiosDynamicData.h
+//
+// 99 11/22/10 12:09p Davidd
+// [TAG] EIP44236
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] SMBIOS type 4 Processor Version is incorrect
+// [RootCause] Type 4 Version string is not resized as updated.
+// [Solution] Added code to replace the Version strings as updated.
+// Same
+// also applied to Manufacturer string.
+// [Files] Smbios.c
+//
+// 98 11/19/10 6:20p Davidd
+// [TAG] EIP46175
+// [Category] Improvement
+// [Description] Redesign SMBIOS to avoid redundant SPD reading
+// [Files]
+// Smbios.c
+// SmbiosDynamicData.h
+//
+// 97 11/17/10 10:40a Davidd
+// [TAG] EIP48415
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] Logic Operator Error in Smbios.c
+// [RootCause] Wrong operator used.
+// [Solution] Change "Bitwise AND" operator to "Logical AND".
+// [Files] Smbios.c
+//
+// 96 11/15/10 3:55p Davidd
+// [TAG] EIP46175
+// [Category] Improvement
+// [Description] Redesign SMBIOS to avoid redundant SPD reading
+// [Files]
+// Smbios.c
+// SmbiosDynamicData.h
+//
+// 95 11/15/10 2:46p Davidd
+// [TAG] EIP47697
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] SMBIOS Type 0 BIOS version string update does not
+// retain over Reboot
+// [RootCause] Wrong index used for StringSet array.
+// [Solution] Corrected index.
+// [Files] Smbios.c
+//
+// 94 11/15/10 2:15p Davidd
+// [TAG] EIP46936
+// [Category] Improvement
+// [Description] Generic Smbios module should have the support to
+// disable SMBIOS memory update
+// [Files]
+// Smbios.c
+// Smbios.sdl
+// SmbiosBoard.c
+// SmbiosDynamicData.h
+//
+// 93 11/02/10 4:11p Davidd
+// [TAG] EIP42938
+// [Category] BUG FIX
+// [Severity] Critical
+// [Symptom] The SMBIOS string field cannot be successfully updated
+// if it was programmed to Null by the 3-party SMBIOS tool
+// [RootCause] BIOS did not have support for NULL strings
+// [Solution] Problem has been fixed with code changes
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosDMIEdit.h
+// SmbiosFlashData.sdl
+//
+// 92 11/01/10 12:26p Davidd
+// [TAG] EIP41560
+// [Category] Improvement
+// [Description] DMIEDIT modified values are not preserved in reboot
+// [Files]
+// Smbios.c
+// Smbios.sdl
+// SmbiosBoard.c
+// SmbiosBoard.mak
+//
+// 91 10/27/10 7:05p Davidd
+//
+// 90 10/25/10 5:02p Davidd
+// [TAG] EIP42457
+// [Category] Improvement
+// [Description] SMBIOS data in not legacy boot (when boot to EFI OS)
+// [Files] Smbios.c
+//
+// 89 10/21/10 11:33a Davidd
+// [TAG] EIP46394
+// [Category] BUG FIX
+// [Severity] Important
+// [Symptom] Incorrect variable size for GetVariable() usage in
+// Smbios module
+// [RootCause] GetVariable is called with incorrect "DataSize" type.
+// [Solution] Corrected "DataSize" type in all GetVariable calls.
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 88 10/20/10 6:12p Davidd
+// [TAG] EIP46454
+// [Category] Improvement
+// [Description] SMBIOS hangs after copying memory to below 1MB after
+// installing type 4 structure (This only happened with new changes to let
+// CPU module create Type 4 structure instead of the Smbios module).
+// [Files] Smbios.c
+//
+// 87 10/19/10 5:49p Davidd
+// [TAG] EIP46454
+// [Category] Improvement
+// [Description] SMBIOS hangs after copying memory to below 1MB after
+// installing type 4 structure (This only happened with new changes to let
+// CPU module create Type 4 structure instead of the Smbios module).
+// [Files]
+// Smbios.c
+//
+// 86 10/15/10 3:57p Davidd
+// [TAG] EIPEIP 45855
+// [Category] Improvement
+// [Description] [SMBIOS] Type1 will be removed to the latest if it
+// updated.
+// [Files] Smbios.sdl, Smbios.c
+//
+// 85 10/12/10 11:43a Davidd
+// Added code to insert new structure at location specified by
+// ADD_STRUCTURE_LOCATION token.
+//
+// 84 10/08/10 8:00p Davidd
+// [TAG] EIP43278
+//
+// [Category] Function Request
+//
+// [Severity] Normal
+//
+// [Description] SMBIOS 2.7 requirement
+//
+// [Files] Core\EM\SMBIOS\Smbios.c
+//
+// 82 9/09/10 11:28a Davidd
+// Fixed Type 13 string format to comply with Smbios specification - EIP
+// 43695.
+//
+// 81 8/18/10 5:54p Davidd
+// Changes added to close the Exxxx / F0000 shadow region after being
+// opened for update - EIP 42187.
+//
+// 80 6/30/10 6:42p Davidd
+// Fixed some DMI utility, which uses PnP function calls, not working
+// issue after type0 structure was updated by SmbiosWriteStructure()
+// protocol - EIP 39849.
+//
+// 79 6/29/10 9:20a Olegi
+// EIP40313: removed CSM16_LOCATION token reference.
+//
+// 78 5/18/10 5:08p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 77 5/14/10 11:28a Davidd
+// Added code to update Smbios Table Header after changes to structure
+// done in PI 1.1 Add/Remove/Change String functions.
+//
+// 76 5/06/10 10:39a Davidd
+// Added Smbios PI 1.1 support - EIP 37736.
+//
+// 75 4/27/10 5:24p Davidd
+// Added some memory manufacturer names to the JEDEC table - EIP 37608.
+//
+// 74 4/21/10 12:14p Davidd
+// Added function "FilterCharacter" to filter the SPD data for Type 17
+// Manufacturer and Part Number string into readable form.
+//
+// 73 4/20/10 12:49p Davidd
+// Fixed incorrect memory type 17 Manufacturer field issue - EIP 37608.
+//
+// 72 4/09/10 3:49p Davidd
+// Corrected the issues listed in the Coverity Code and security analysis
+// report - EIP 34502
+//
+// 71 4/06/10 10:59a Davidd
+// Set structure type 13 Reserved field to zero.
+//
+// 70 4/06/10 10:27a Davidd
+// Changes made to dynamically create type 13 structure (BIOS Language
+// Information) based on SUPPORTED_LANGUAGES token if enabled - EIP 34939.
+//
+// 69 2/26/10 5:46p Davidd
+// - Corrected a potential buffer overflow problem in
+// UpdateStructuresWithNvramData function - EIP 34379
+// - Corrected a potential use of uninitialzied pointer in
+// DynamicUpdateCpuData function - EIP 34379
+//
+// 68 12/03/09 4:39p Davidd
+// Corrected a hanging problem when UpdateSmbiosTable function is called
+// to add a structure but it is found to be invalid. In this case, memory
+// has not been allocated, but at the end of the function memory
+// deallocation is called.
+//
+// 67 11/23/09 5:50p Davidd
+// Corrected the DMIEdit data not updated after being updated 5-6 times
+// (when NVRAM is used to store DMIEdit data) - EIP 30837.
+//
+// 66 8/11/09 2:54p Davidd
+// Corrected build error when CSM support is not present.
+//
+// 65 8/06/09 3:30p Davidd
+// Fixed a duplicate handle problem in case a structure with handle =
+// LastHandle was added by SmbiosAddStrucByHandle, and then another
+// structure was added with SmbiosAddStructure.
+//
+// 64 8/05/09 6:17p Davidd
+// Added DMIEDIT support for Type 0 and Type 12 structures - EIP 24878
+//
+// 63 7/16/09 4:59p Davidd
+// Fixed the problem of missing the last character in the Manufacturer and
+// Version strings of SMBIOS CPU Type 4. (EIP 23633)
+//
+// 62 6/02/09 11:12a Davidd
+// Updated function headers. (EIP 22180)
+//
+// 61 6/02/09 10:55a Davidd
+//
+// 60 5/19/09 10:47a Davidd
+// Changes added to improve memory type 17 porting.
+//
+// 59 1/28/09 11:45a Davidd
+// - Removed UpdateStructuresWithNvramType0 and
+// UpdateStructuresWithNvramType12 functions (not supported by DMIEdit
+// utility)
+// - New changes added to support storage locations for DMIEdit data in
+// NVRAM.
+//
+// 58 12/23/08 3:20p Davidd
+// Corrected the random hanging issue when PORTABLE_BATTERY_INFO is
+// enabled.
+//
+// 57 11/18/08 10:21a Davidd
+// - Fixed a bug calculating the number of rank for the attribute field
+// for memory structure type 17.
+// - Added code to fill in the Total Width and Data Width fields from SPD
+// data.
+//
+// 56 11/14/08 4:19p Davidd
+// - Added GetFreeHandle protocol
+// - Added AddStructureByHandle protocol
+// - Added ReadStructureByType protocol
+// - Added a call to the OEM porting hook OemUpdate. OEM can make changes
+// to the SMBIOS table in this hook
+//
+// 55 10/31/08 10:31a Davidd
+// Correct problem of Additional Info structure not updated when
+// PORTABLE_BATTERY_INFO is enabled.
+//
+// 54 10/27/08 2:52p Davidd
+// Code clean up.
+//
+// 53 10/23/08 6:44p Davidd
+// - Added changes to support SMBIOS version 2.5 and 2.6.
+// - Changes added for dynamic table sizing.
+// - Code added to update some memory info obtained from SPD data for type
+// 17
+//
+// 52 10/10/08 5:21p Davidd
+// Corrected a build error in x64 bit mode - EIP 16894
+//
+// 51 10/06/08 1:19p Davidd
+// Renamed SMBIOS_TABLE_E000 token to SMBIOS_TABLE_LOCATION.
+// Added Auto option to SMBIOS_TABLE_LOCATION token.
+// Code added to check for memory allocation error in
+// Install16bitPnPSmbiosFunctions.
+//
+// 50 9/26/08 10:41a Davidd
+// Made changes to either put the SMBIOS table at E000 segment or above
+// 1MB (selectable via SMBIOS_TABLE_E000 token)
+//
+// 49 8/12/08 5:45p Davidd
+// Added conditional compilation switch based on SmbiosDMIEdit_SUPPORT and
+// SmbiosFlashData_SUPPORT SDL tokens to correct build error when either
+// one of those tokens is disabled
+//
+// 48 7/23/08 10:38a Davidd
+// Corrected a bug assigning new handle in AddStructure function.
+//
+// 47 2/13/08 7:24p Davidd
+// Corrected a build issue in 64 bit mode.
+//
+// 46 2/06/08 3:36p Davidd
+// - In DynamicUpdateCpuData, use gSmbiosBoardProtocol->NumberOfCPU
+// instead of NO_OF_PROCESSOR_SOCKETS to represent the number of
+// proccessors in the system in case when project only has SMBIOS binary
+// component.
+// - Moved the "#if PORTABLE_BATTERY_INFO" to only enclose the
+// DynamicUpdateBatteryData function.
+// - In DynamicUpdateBatteryData, use
+// gSmbiosBoardProtocol->NumberOfBatteries instead of
+// NO_OF_PORTABLE_BATTERY to represent the number of batteries in the
+// system in case when project only has SMBIOS binary component.
+//
+// 45 2/05/08 11:21a Davidd
+// Rearranged the code flow in DynamicUpdateMemoryData.
+//
+// 44 2/04/08 1:57p Davidd
+// Fixed a problem updating battery data when BIOS is built with multiple
+// battery structures but some of them are invalid during POST.
+//
+// 43 1/30/08 3:51p Davidd
+// Changes made to SMBIOS type 17 with multiple memory arrays.
+//
+// 42 1/22/08 4:29p Olegi
+//
+// 41 12/26/07 5:07p Olegi
+// Added Install16bitPnPSmbiosFunctions() funciton.
+//
+// 40 12/20/07 11:28a Davidd
+// Added code to skip calling SmbiosCreateBatteryDevData when
+// PORTABLE_BATTERY_INFO is set to OFF. This fixes the hanging issue when
+// BIOS is built with SMBIOS binary only.
+//
+// 39 12/19/07 4:59p Davidd
+// Fixed code to abort updating CPU related data if getting CPU data
+// variable resulted in error.
+//
+// 38 12/14/07 6:53p Davidd
+// Corrected build error when Type 18 is enabled.
+//
+// 37 12/14/07 11:01a Davidd
+// Added conditional IF statement for DynamicUpdateOnboardDevData function
+// to fix the build error in case ONBOARD_DEVICE_INFO is set to OFF.
+//
+// 36 12/14/07 10:44a Davidd
+//
+// 35 12/07/07 12:32p Davidd
+// Restore the UpdateEPSHeader call in the Addstructure and
+// DeleteStructureByHandle functions.
+//
+// 34 11/26/07 5:05p Davidd
+// Changes added to dynamically update Voltage field in Processor
+// Information structure type 4.
+//
+// 33 11/21/07 10:33a Davidd
+// Added code to dynamically update Portable Battery Data structure type
+// 22.
+//
+// 32 9/12/07 2:28p Davidd
+// Added changes to set memory type and speed to unknown for unoccupied
+// memory slot.
+//
+// 31 9/06/07 10:57a Davidd
+// Corrected the UUID reversal problem.
+//
+// 30 30/08/07 2:13p Anandakrishnanl
+// Added token switch in SMBIOS for checking if iAMT_SUPPORT is Defined.
+//
+// 29 7/10/07 3:05p Davidd
+// Fixed bug for DMIEdit Type 12 support.
+//
+// 28 6/29/07 5:31p Davidd
+// AMT3.0: Update: SMBIOS Module modifed to match Compliance Test For AMT
+//
+// 27 6/20/07 10:37a Pats
+// Modified to support editing of SMBIOS structure type 0, offsets 5 and
+// 8.
+//
+// 26 6/05/07 4:15p Michaela
+// Modified DynamicUpdateCpuData() to use
+// SMBIOS_CPU_INFO_PROTOCOL and provide backward
+// compatibility for old method, which used the "CPU_DATA" variable
+//
+// 25 4/13/07 11:35a Davidd
+// Updated to coding standard.
+//
+// 24 3/29/07 5:56p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 23 3/21/07 4:46p Michaela
+// made changes to DynamicUpdateMemoryData to support multiple
+// memory arrays
+//
+// 22 3/14/07 1:18p Pavell
+// Changes for ITK support
+//
+// 21 12/15/06 5:39p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 20 10/27/06 3:10p Davidd
+// Corrected the problem getting the string index in GetType1StringIndex
+//
+// 19 10/13/06 6:34p Felixp
+// UEFI 2.0 compliant handling of ready to boot event
+//
+// 18 10/05/06 4:48p Davidd
+// Changes added for 64 bit support.
+//
+// 17 3/21/06 5:12p Davidd
+// Set L3 Cache Handle to 0xFFFF if L3 cache size is zero.
+//
+// 16 3/02/06 1:53p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+// 15 3/02/06 11:00a Davidd
+// Corrected CPU dynamic updation and removed fields deemed static in
+// memory structures.
+//
+// 14 11/07/05 6:17p Davidd
+// Changes made to support AMIBCP.
+//
+// 13 8/10/05 10:32a Davidd
+// Added #include SmbiosGetFlashDataProtocol.h (EFI_SMBIOS_PROTOCOL_GUID
+// has been moved to this file).
+//
+// 12 8/05/05 11:31a Davidd
+// Made SmbiosVariableSize platform independent to fix the binary issue
+// (ex: if binary built with 2 memory slot, SMBIOS will wrongly report the
+// memory size on a system with 4 memory slot).
+//
+// 11 8/01/05 2:47p Davidd
+// Added back compilation switches to avoid build error. Make sure to
+// enable Memory Error Type 18 support when building the SMBIOS binary.
+//
+// 10 7/27/05 1:05p Davidd
+// Removed all conditional compilation switches. Use the value from the
+// SmbiosBoardProtocol.
+//
+// 9 7/22/05 1:17p Davidd
+// Changed code to dynamically update structures just before boot.
+//
+// 8 7/20/05 12:40p Davidd
+// - Corrected dynamic update on-board device problem.
+//
+// 7 7/20/05 11:38a Davidd
+// - Corrected dynamic update on-board device problem.
+// - Set structure 20 to inactive if memory slot is not filled.
+//
+// 6 7/18/05 4:54p Davidd
+// - Made changes to update the CPU data according to the number of CPU
+// returned from the porting hook.
+// - Added code to make calls to porting hooks (protocol) to create
+// dynamic data.
+//
+// 5 7/15/05 6:13p Davidd
+// Fixed bug updating on-board device status dynamically.
+//
+// 4 7/13/05 5:16p Davidd
+// Code added to dynamically update Processor Manufacturer and Processor
+// Version.
+//
+// 3 6/21/05 11:56a Davidd
+// Corrected hanging problem as BIOS Version was changed starting from
+// label "ALPHA-1.00.12".
+//
+// 2 5/31/05 11:36a Davidd
+// - Corrected intermitten hanging problem after SMBIOS driver is loaded.
+// - Added/corrected dynamic memory structure updation.
+//
+// 1 4/29/05 2:03p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <AmiHobs.h>
+#include <Sb.h>
+#include <SBCspLib.h>
+#include "Protocol\SMBios.h"
+#include "Protocol\SmbiosDynamicData.h"
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+#include <Protocol\FirmwareVolume.h>
+#else
+#include <Protocol\FirmwareVolume2.h>
+#endif
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+#include <Protocol\LegacyBios.h>
+#include <Protocol\LegacyBiosExt.h>
+#if PI_SPECIFICATION_VERSION < 0x10014
+EFI_LEGACY_REGION_PROTOCOL *LegacyRegionProtocol = NULL;
+#else
+#include <Protocol\LegacyRegion2.h>
+EFI_LEGACY_REGION2_PROTOCOL *LegacyRegionProtocol = NULL;
+#endif
+EFI_LEGACY_BIOS_PROTOCOL *LegacyBiosProtocol = NULL;
+LEGACY16_TO_EFI_DATA_TABLE_STRUC *Legacy16Data;
+EFI_STATUS Install16bitPnPSmbiosFunctions();
+#endif // CSM_SUPPORT
+
+#if (defined(SmbiosDMIEdit_SUPPORT) && (SmbiosDMIEdit_SUPPORT !=0))
+#include "SmbiosDMIEditSupport\SmbiosDMIEdit.h"
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#include "Protocol\SmbiosGetFlashDataProtocol.h"
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+#endif // SmbiosDMIEdit_SUPPORT
+
+EFI_GUID gEfiSmbiosNvramGuid = EFI_SMBIOS_NVRAM_DATA_GUID;
+
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+#define AMT_SMBIOS_GROUP \
+ { 0xed27920d, 0x4422, 0x4b4d, { 0xa4, 0xa3, 0x4d, 0xc2, 0xb3, 0xe5, 0x46, 0x3b } }
+#endif // iAMT_SUPPORT
+
+// Added for TPM
+#define SMBIOS_EFI_TABLE_GROUP \
+ { 0xb3dae700, 0x2a77, 0x4ea4, 0xaf, 0x79, 0x32, 0x97, 0xb4, 0x84, 0xbe, 0x61 }
+
+extern EFI_BOOT_SERVICES *pBS;
+extern VOID OemRuntimeShadowRamWrite(IN BOOLEAN Enable);
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+EFI_GUID gEfiFVProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+#else
+EFI_GUID gEfiFVProtocolGuid = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+#endif // PI_SPECIFICATION_VERSION
+EFI_GUID gEfiSmbiosStaticData = EFI_SMBIOS_STATIC_DATA_GUID;
+EFI_GUID gEfiSmbiosDynamicData = EFI_SMBIOS_DYNAMIC_DATA_GUID;
+EFI_GUID gEfiSmbiosBoardProtocolGuid = EFI_SMBIOS_BOARD_PROTOCOL_GUID;
+EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
+
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+VOID AmtNotifyEventFunction(IN EFI_EVENT Event, IN VOID *Context) {}
+#endif // iAMT_SUPPORT
+
+// Added for TPM
+VOID NotifyEventFunction(IN EFI_EVENT Event, IN VOID *Context) {}
+
+UINT8 MemType = 0; // 0 = Not supported
+ // 1 = DDR2
+ // 2 = DDR3
+BOOLEAN SmbiosTableAtE000 = FALSE;
+
+SMBIOS_NVRAM_TYPE4 NvramType4;
+
+#ifdef FLASH_PART_STRING_LENGTH
+VOID GetFlashPartInfomation(UINT8 *pBlockAddress, UINT8 *Buffer);
+#endif // FLASH_PART_STRING_LENGTH
+
+BOOLEAN
+ValidateStringNumber(
+ IN UINT8 *StructurePtr,
+ IN UINT8 StructureType,
+ IN UINTN StringNumber
+);
+
+//
+// String type tables
+//
+STRING_TABLE StringType_0[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x08, 3, 3},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_1[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x19, 5, 5},
+ {0x1a, 6, 6},
+ {0xff, 0, 0},
+ };
+
+#if (TYPE2_STRUCTURE == 1)
+STRING_TABLE StringType_2[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x08, 5, 5},
+ {0x0a, 6, 6},
+ {0xff, 0, 0},
+ };
+#else
+STRING_TABLE StringType_2[] = {{0xff, 0, 0}};
+#endif // TYPE2_STRUCTURE
+
+#if (TYPE3_STRUCTURE == 1)
+STRING_TABLE StringType_3[NUMBER_OF_SYSTEM_CHASSIS][6] =
+ {{{0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_1 * ELEMENT_LEN_1), 5, 5},
+ {0xff, 0, 0},
+ },
+#if NUMBER_OF_SYSTEM_CHASSIS > 1
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_2 * ELEMENT_LEN_2), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+#if NUMBER_OF_SYSTEM_CHASSIS > 2
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_3 * ELEMENT_LEN_3), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+#if NUMBER_OF_SYSTEM_CHASSIS > 3
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_4 * ELEMENT_LEN_4), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+#if NUMBER_OF_SYSTEM_CHASSIS > 4
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_5 * ELEMENT_LEN_5), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif // NUMBER_OF_SYSTEM_CHASSIS
+ }; // StringType_3
+#else
+STRING_TABLE StringType_3[] = {{0xff, 0, 0}};
+#endif // TYPE3_STRUCTURE
+
+STRING_TABLE StringType_4[] = {{0x04, 1, 1},
+ {0x07, 2, 2},
+ {0x10, 3, 3},
+ {0x20, 4, 4},
+ {0x21, 5, 5},
+ {0x22, 6, 6},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_5[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_6[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_7[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_8[] = {{0x04, 1, 1},
+ {0x06, 2, 2},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_9[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_10[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_11[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_12[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_13[] = {{0x15, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_14[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_15[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_16[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_17[] = {{0x10, 1, 1},
+ {0x11, 2, 2},
+ {0x17, 3, 3},
+ {0x18, 4, 4},
+ {0x19, 5, 5},
+ {0x1a, 6, 6},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_18[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_19[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_20[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_21[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_22[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x08, 5, 5},
+ {0x0e, 6, 6},
+ {0x14, 7, 7},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_23[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_24[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_25[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_26[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_27[] = {{0x0e, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_28[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_29[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_30[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_31[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_32[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_33[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_34[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_35[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_36[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_37[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_38[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_39[] = {{0x05, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x09, 5, 5},
+ {0x0a, 6, 6},
+ {0x0b, 7, 7},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_40[] = {{0xff, 0, 0}};
+
+STRING_TABLE StringType_41[] = {{0x04, 1, 1},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_42[] = {{0xff, 0, 0}};
+
+//
+// String table
+//
+VOID* StringTable[] = {&StringType_0, // 0
+ &StringType_1, // 1
+ &StringType_2, // 2
+ &StringType_3, // 3
+ &StringType_4, // 4
+ &StringType_5, // 5
+ &StringType_6, // 6
+ &StringType_7, // 7
+ &StringType_8, // 8
+ &StringType_9, // 9
+ &StringType_10, // 10
+ &StringType_11, // 11
+ &StringType_12, // 12
+ &StringType_13, // 13
+ &StringType_14, // 14
+ &StringType_15, // 15
+ &StringType_16, // 16
+ &StringType_17, // 17
+ &StringType_18, // 18
+ &StringType_19, // 19
+ &StringType_20, // 20
+ &StringType_21, // 21
+ &StringType_22, // 22
+ &StringType_23, // 23
+ &StringType_24, // 24
+ &StringType_25, // 25
+ &StringType_26, // 26
+ &StringType_27, // 27
+ &StringType_28, // 28
+ &StringType_29, // 29
+ &StringType_30, // 30
+ &StringType_31, // 31
+ &StringType_32, // 32
+ &StringType_33, // 33
+ &StringType_34, // 34
+ &StringType_35, // 35
+ &StringType_36, // 36
+ &StringType_37, // 37
+ &StringType_38, // 38
+ &StringType_39, // 39
+ &StringType_40, // 40
+ &StringType_41, // 41
+ &StringType_42, // 42
+ };
+
+JEDEC_MF_ID Bank0Table [] = {{ 0x01, "AMD" },
+ { 0x04, "Fujitsu" },
+ { 0x07, "Hitachi" },
+ { 0x89, "Intel" },
+ { 0x10, "NEC" },
+ { 0x97, "Texas Instrument" },
+ { 0x98, "Toshiba" },
+ { 0x1c, "Mitsubishi" },
+ { 0x1f, "Atmel" },
+ { 0x20, "STMicroelectronics" },
+ { 0xa4, "IBM" },
+ { 0x2c, "Micron Technology" },
+ { 0xad, "SK Hynix" },
+ { 0xb0, "Sharp" },
+ { 0xb3, "IDT" },
+ { 0x3e, "Oracle" },
+ { 0xbf, "SST" },
+ { 0x40, "ProMos/Mosel" },
+ { 0xc1, "Infineon" },
+ { 0xc2, "Macronix" },
+ { 0x45, "SanDisk" },
+ { 0xce, "Samsung" },
+ { 0xda, "Winbond" },
+ { 0xe0, "LG Semi" },
+ { 0x62, "Sanyo" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank1Table [] = {{ 0x98, "Kingston" },
+ { 0xba, "PNY" },
+ { 0x4f, "Transcend" },
+ { 0x7a, "Apacer" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank2Table [] = {{ 0x9e, "Corsair" },
+ { 0xfe, "Elpida" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank3Table [] = {{ 0x0b, "Nanya" },
+ { 0x94, "Mushkin" },
+ { 0x25, "Kingmax" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank4Table [] = {{ 0xb0, "OCZ" },
+ { 0xcb, "A-DATA" },
+ { 0xcd, "G Skill" },
+ { 0xef, "Team" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank5Table [] = {{ 0x02, "Patriot" },
+ { 0x9b, "Crucial" },
+ { 0x51, "Qimonda" },
+ { 0x57, "AENEON" },
+ { 0xf7, "Avant" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank6Table [] = {{ 0x34, "Super Talent" },
+ { 0xd3, "Silicon Power" },
+ { 0xff, "Undefined" }
+};
+JEDEC_MF_ID Bank7Table [] = {{ 0xff, "Undefined" }
+};
+
+
+JEDEC_MF_ID *ManufacturerJedecIdBankTable [] = {
+ Bank0Table,
+ Bank1Table,
+ Bank2Table,
+ Bank3Table,
+ Bank4Table,
+ Bank5Table,
+ Bank6Table,
+ Bank7Table
+};
+
+JEDEC_DATA ManufacturerTable[] = MANUFACTURER_ID_CODE;
+
+SMBIOS_TABLE_ENTRY_POINT SmbiosEntryPointTable = {
+ '_', 'S', 'M', '_',
+ 0, // EPS Checksum
+ 0x1f, // Entry Point Length
+ 0x02, // SMBIOS Major Version
+ 0x08, // SMBIOS Minor Version
+ 0x100, // Maximum Structure Size
+ 0, // Entry Point Revision
+ 0, 0, 0, 0, 0, // Formatted Area
+ '_', 'D', 'M', 'I', '_', // Intermediate Anchor String
+ 0, // Intermediate Checksum
+ 0, // Structure Table Length
+ 0, // Structure Table Address
+ 0x10, // Number of SMBIOS Stuctures
+ 0x28 // SMBIOS BCD Revision};
+ };
+
+SMBIOS_TABLE_ENTRY_POINT *pSmbiosTableEntryPoint = &SmbiosEntryPointTable;
+UINT8 *ScratchBufferPtr = NULL;
+UINT8 *SmbiosDataTable = NULL;
+UINT16 MaximumTableSize;
+UINT16 LastHandle;
+EFI_SMBIOS_BOARD_PROTOCOL *gSmbiosBoardProtocol;
+BOOLEAN UpdateCpuStructure;
+BOOLEAN TableRelocated = FALSE;
+
+EFI_SMBIOS_PROTOCOL SmbiosProtocol = {
+#if ( defined(SMBIOS_PI_1_1) && (SMBIOS_PI_1_1 == 1) )
+ SmbiosPiAddStructure,
+ SmbiosPiUpdateString,
+ SmbiosPiRemoveStructure,
+ SmbiosPiGetNextStructure,
+ SMBIOS_MAJOR_VERSION,
+ SMBIOS_MINOR_VERSION,
+#endif
+ GetSmbiosTableEntryPoint,
+ GetScratchBufferPtr,
+ GetBufferMaxSize,
+ GetFreeHandle,
+ AddStructure,
+ AddStructureByHandle,
+ DeleteStructureByHandle,
+ ReadStructureByHandle,
+ ReadStructureByType,
+ WriteStructureByHandle,
+ UpdateSmbiosTableHeader};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiUpdateString
+//
+// Description: Update the string associated with an existing SMBIOS record
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN EFI_SMBIOS_HANDLE *SmbiosHandle,
+// IN UINTN *StringNumber,
+// IN CHAR8 *String
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiUpdateString (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN EFI_SMBIOS_HANDLE *SmbiosHandle,
+ IN UINTN *StringNumber,
+ IN CHAR8 *String
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *StrucPtr = SmbiosDataTable;
+ UINT8 *BufferPtr;
+ UINT16 BufferSize;
+
+ TRACE((-1, "In SmbiosPiUpdateString\n"));
+
+ if (*StringNumber) {
+ if (FindStructureHandle(&StrucPtr, *SmbiosHandle)) {
+ TRACE((-1, "Found structure with handle = %x\n", *SmbiosHandle));
+ if (ValidateStringNumber(StrucPtr, ((SMBIOS_STRUCTURE_HEADER*)StrucPtr)->Type, *StringNumber)) {
+ BufferSize = GetStructureLength(StrucPtr);
+
+ Status = pBS->AllocatePool(EfiBootServicesData,
+ BufferSize + (UINT16)Strlen(String) + 1,
+ (void**)&BufferPtr);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ MemCpy(BufferPtr, StrucPtr, BufferSize);
+
+ if (ReplaceString(BufferPtr, *(UINT8*)StringNumber, (UINT8*)String)) {
+ TRACE((-1, "Failed to replace string\n"));
+ Status = EFI_UNSUPPORTED;
+ }
+ else {
+ TRACE((-1, "Deleting structure with handle = %x\n", *SmbiosHandle));
+ if (DeleteStructureByHandle(*SmbiosHandle)) {
+ TRACE((-1, "Failed to delete structure\n"));
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ BufferSize = GetStructureLength(BufferPtr);
+
+ TRACE((-1, "Adding structure with handle = %x\n", *SmbiosHandle));
+ if (AddStructureByHandle(*SmbiosHandle, BufferPtr, BufferSize)) {
+ TRACE((-1, "Failed to add structure\n"));
+ Status = EFI_ALREADY_STARTED;
+ }
+ }
+
+ pBS->FreePool(BufferPtr);
+
+ UpdateSmbiosTableHeader();
+
+ Status = EFI_SUCCESS;
+ }
+ else {
+ TRACE((-1, "StringNumber validation failed!\n"));
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ TRACE((-1, "Structure not found!\n"));
+ Status = EFI_INVALID_PARAMETER;
+ }
+ }
+ else {
+ TRACE((-1, "String number missing!\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ TRACE((-1, "Exiting SmbiosPiUpdateString. Status = %r\n", Status));
+ return Status;
+}
+
+#if ( defined(SMBIOS_PI_1_1) && (SMBIOS_PI_1_1 == 1) )
+
+BOOLEAN
+FindStructureType(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT8 **StructureFoundPtr,
+ IN UINT8 SearchType,
+ IN UINT8 Instance // 1-based
+);
+
+EFI_PRODUCER_HANDLE ProducerHandleTable[PRODUCER_HANDLE_ELEMENTS];
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddProducerHandle
+//
+// Description: Add/Register the ProducerHandle associated with SmbiosHandle
+// to the ProducerHandleTable
+//
+// Input: IN EFI_SMBIOS_HANDLE SmbiosHandle
+// IN EFI_HANDLE ProducerHandle
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddProducerHandle (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle,
+ IN EFI_HANDLE ProducerHandle
+)
+{
+ EFI_PRODUCER_HANDLE *ProducerPtr = &ProducerHandleTable[0];
+ UINT16 i = 0;
+
+ while ((ProducerPtr->SmbiosHandle != 0xffff) &&
+ (ProducerPtr->SmbiosHandle != SmbiosHandle) &&
+ (i < PRODUCER_HANDLE_ELEMENTS)) {
+ ProducerPtr++;
+ i++;
+ }
+
+ if (i < PRODUCER_HANDLE_ELEMENTS) {
+ ProducerPtr->SmbiosHandle = SmbiosHandle;
+ ProducerPtr->ProducerHandle = ProducerHandle;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitializeProducerHandleTable
+//
+// Description: Initialize the ProducerHandleTable
+//
+// Input: IN EFI_HANDLE ProducerHandle
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+InitializeProducerHandleTable (
+ IN EFI_HANDLE ProducerHandle
+)
+{
+ EFI_PRODUCER_HANDLE *ProdPtr = &ProducerHandleTable[0];
+ UINT16 i;
+ UINT8 *Ptr = SmbiosDataTable;
+
+ for (i = 0; i < PRODUCER_HANDLE_ELEMENTS; i++) {
+ ProdPtr->SmbiosHandle = 0xffff;
+ ProdPtr->ProducerHandle = 0;
+ ProdPtr++;
+ };
+
+ // Set ProducerHandle for each Smbios record
+ do {
+ AddProducerHandle(((EFI_SMBIOS_TABLE_HEADER*)Ptr)->Handle, ProducerHandle);
+ Ptr += GetStructureLength(Ptr);
+ } while (((EFI_SMBIOS_TABLE_HEADER*)Ptr)->Type != 127);
+
+ AddProducerHandle(((EFI_SMBIOS_TABLE_HEADER*)Ptr)->Handle, ProducerHandle);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RemoveProducerHandle
+//
+// Description: Remove the "SmbiosHandle" entry from the ProducerHandleTable
+//
+// Input: IN EFI_SMBIOS_HANDLE SmbiosHandle
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RemoveProducerHandle (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle
+)
+{
+ UINT16 i = 0;
+ EFI_PRODUCER_HANDLE *ProducerPtr = &ProducerHandleTable[0];
+ UINT16 Size;
+
+ if (SmbiosHandle != 127) {
+ while ((ProducerPtr->SmbiosHandle != 127) && (ProducerPtr->SmbiosHandle != SmbiosHandle)) {
+ i++;
+ ProducerPtr++;
+ }
+
+ if (ProducerPtr->SmbiosHandle == SmbiosHandle) {
+ EFI_PRODUCER_HANDLE *TempPtr;
+
+ TempPtr = ProducerPtr + 1;
+ Size = (PRODUCER_HANDLE_ELEMENTS - i - 1) * sizeof(EFI_PRODUCER_HANDLE);
+ MemCpy((UINT8*)ProducerPtr, (UINT8*)TempPtr, Size);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetProducerHandle
+//
+// Description:
+//
+// Input: IN EFI_SMBIOS_HANDLE SmbiosHandle
+// IN OUT EFI_HANDLE *ProducerHandle
+//
+// Output: ProducerHandle
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetProducerHandle (
+ IN EFI_SMBIOS_HANDLE SmbiosHandle,
+ IN OUT EFI_HANDLE *ProducerHandle
+)
+{
+ EFI_PRODUCER_HANDLE *ProducerPtr = &ProducerHandleTable[0];
+
+ if (SmbiosHandle != 127) {
+ while ((ProducerPtr->SmbiosHandle != 127) && (ProducerPtr->SmbiosHandle != SmbiosHandle)) {
+ ProducerPtr++;
+ }
+
+ *ProducerHandle = ProducerPtr->ProducerHandle;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiAddStructure
+//
+// Description: Add an Smbios record
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN EFI_HANDLE ProducerHandle, OPTIONAL
+// IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
+// IN EFI_SMBIOS_TABLE_HEADER *Record
+//
+// Output: SmbiosHandle
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiAddStructure (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN EFI_HANDLE ProducerHandle, OPTIONAL
+ IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
+ IN EFI_SMBIOS_TABLE_HEADER *Record
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT16 RecordSize;
+
+ RecordSize = GetStructureLength((UINT8*)Record);
+
+ if (*SmbiosHandle) {
+ if (AddStructureByHandle(*SmbiosHandle, (UINT8*)Record, RecordSize)) {
+ Status = EFI_ALREADY_STARTED;
+ }
+ else {
+ AddProducerHandle(*SmbiosHandle, ProducerHandle);
+ }
+ }
+ else {
+ if (AddStructure((UINT8*)Record, RecordSize)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ }
+ else {
+ *SmbiosHandle = Record->Handle;
+ AddProducerHandle(*SmbiosHandle, ProducerHandle);
+ }
+ }
+
+ if (Status == EFI_SUCCESS) {
+ UpdateSmbiosTableHeader();
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiRemoveStructure
+//
+// Description: Remove an SMBIOS record
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN EFI_SMBIOS_HANDLE SmbiosHandle
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiRemoveStructure (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN UINTN SmbiosHandle
+)
+{
+ if (DeleteStructureByHandle((UINT16)SmbiosHandle)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ RemoveProducerHandle((EFI_SMBIOS_HANDLE)SmbiosHandle);
+
+ UpdateSmbiosTableHeader();
+
+ return EFI_SUCCESS;
+};
+
+#if defined PI_SPECIFICATION_VERSION && PI_SPECIFICATION_VERSION >= 0x10014
+#define ANY_HANDLE 0xfffe
+#else
+#define ANY_HANDLE 0
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosPiGetNextStructure
+//
+// Description: Allow the caller to discover all or some of the SMBIOS records
+//
+// Input: IN CONST EFI_SMBIOS_PROTOCOL *This,
+// IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle
+// IN EFI_SMBIOS_TYPE *Type, OPTIONAL
+// OUT EFI_SMBIOS_TABLE_HEADER **Record,
+// OUT EFI_HANDLE *ProducerHandle OPTIONAL
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+// Implementation:
+// SmbiosHandle = 0xfffe, Type = NULL ==> Record = 1st record in table,
+// SmbiosHandle = handle of record being returned
+// SmbiosHandle != 0xfffe, Type = NULL ==> If record of SmbiosHandle is not found, return EFI_NOT_FOUND, SmbiosHandle = 0xfffe
+// else Record = next record after record of SmbiosHandle,
+// SmbiosHandle = handle of record being returned
+// SmbiosHandle = 0xfffe, Type <> 0 ==> If record of input "Type" is not found, return EFI_NOT_FOUND, SmbiosHandle = 0xfffe
+// else Record = 1st record of type "*Type",
+// SmbiosHandle = handle of record being returned
+// SmbiosHandle != 0xfffe, Type <> 0 ==> If record of SmbiosHandle is not found, or found but no record of type "*Type" after
+// record of SmbiosHandle can be found, return EFI_NOT_FOUND, SmbiosHandle = 0xfffe
+// else Record = next record after record of SmbiosHandle,
+// SmbiosHandle = handle of record being returned
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosPiGetNextStructure (
+ IN CONST EFI_SMBIOS_PROTOCOL *This,
+ IN OUT EFI_SMBIOS_HANDLE *SmbiosHandle,
+ IN EFI_SMBIOS_TYPE *Type OPTIONAL,
+ OUT EFI_SMBIOS_TABLE_HEADER **Record,
+ OUT EFI_HANDLE *ProducerHandle OPTIONAL
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *StrucPtr;
+ UINT8 *StructureFoundPtr;
+ UINT16 StrucSize;
+
+ TRACE((-1, "In SmbiosPiGetNextStructure\n"));
+
+ StrucPtr = SmbiosDataTable;
+
+ if (Type == NULL) {
+ if (*SmbiosHandle == 0xfffe) {
+ // Type = NULL, *SmbiosHandle = 0xfffe ==> return 1st record in Smbios table
+ Status = EFI_SUCCESS;
+ goto GetNext_Exit;
+ }
+ else {
+ // Type = NULL, *SmbiosHandle != 0xfffe
+ if (FindStructureHandle(&StrucPtr, *SmbiosHandle)) {
+ if (((EFI_SMBIOS_TABLE_HEADER*)StrucPtr)->Type != 127) {
+ // Record of *SmbiosHandle is found, return next record
+ StrucSize = GetStructureLength(StrucPtr);
+ StrucPtr += StrucSize;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ // End of Smbios table, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ // Record of *SmbiosHandle is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+
+ goto GetNext_Exit;
+ }
+ }
+ else { // Type != NULL
+ if (*SmbiosHandle == 0xfffe) {
+ // Search for 1st record of *Type
+ if (FindStructureType(&StrucPtr, &StructureFoundPtr, *Type, 1)) {
+ // Type != NULL, *SmbiosHandle = 0xfffe
+ // Record of *Type is found ===> return record found
+ StrucPtr = StructureFoundPtr;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ // Type != NULL, *SmbiosHandle = 0xfffe
+ // Record of *Type is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+
+ goto GetNext_Exit;
+ }
+ else { // Type != NULL, *SmbiosHandle != 0xfffe
+ if (FindStructureHandle(&StrucPtr, *SmbiosHandle)) {
+ if (((EFI_SMBIOS_TABLE_HEADER*)StrucPtr)->Type != 127) {
+ // Record of SmbiosHandle is found, skip to next record
+ StrucSize = GetStructureLength(StrucPtr);
+ StrucPtr += StrucSize;
+ if (FindStructureType(&StrucPtr, &StructureFoundPtr, *Type, 1)) {
+ // Type != NULL, *SmbiosHandle != 0xfffe
+ // Record of *Type is found ===> return record found
+ StrucPtr = StructureFoundPtr;
+ Status = EFI_SUCCESS;
+ }
+ else {
+ // Type != NULL, *SmbiosHandle != 0xfffe,
+ // Record of SmbiosHandle is found but record of *Type is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ // End of Smbios table, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ else {
+ // Type != NULL, *SmbiosHandle != 0xfffe,
+ // Record of SmbiosHandle is not found, return error
+ Status = EFI_NOT_FOUND;
+ }
+ }
+ }
+
+GetNext_Exit:
+ if (Status == EFI_SUCCESS) {
+ *SmbiosHandle = ((EFI_SMBIOS_TABLE_HEADER*)StrucPtr)->Handle;
+ *Record = (EFI_SMBIOS_TABLE_HEADER*)StrucPtr;
+
+ if (ProducerHandle != NULL) {
+ GetProducerHandle(*SmbiosHandle, ProducerHandle);
+ }
+ }
+ else {
+ *SmbiosHandle = 0xfffe;
+ }
+
+ TRACE((-1, "Exit SmbiosPiGetNextStructure. Status = %r\n", Status));
+ return Status;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosCheckSum
+//
+// Description: Returns the checksum of "length" bytes starting from the
+// "*ChecksumSrc"
+//
+// Input: IN UINT8 *ChecksumSrc
+// IN UINT8 length
+//
+// Output: UINT8 - Checksum value
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+SmbiosCheckSum(
+ IN UINT8 *ChecksumSrc,
+ IN UINT8 length
+)
+{
+ UINT8 Checksum = 0;
+ UINT8 i;
+
+ for (i = 0; i < length; i++) {
+ Checksum += *ChecksumSrc++;
+ }
+ return (0 - Checksum);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureLength
+//
+// Description: Returns the length of the structure pointed by BufferStart
+// in bytes
+//
+// Input: IN UINT8 *BufferStart
+//
+// Output: UINT16 - Structure Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetStructureLength(
+ IN UINT8 *BufferStart
+)
+{
+ UINT8 *BufferEnd = BufferStart;
+
+ BufferEnd += ((SMBIOS_STRUCTURE_HEADER*)BufferStart)->Length;
+
+ while (*(UINT16*)BufferEnd != 0) {
+ BufferEnd++;
+ }
+
+ return (UINT16)(BufferEnd + 2 - BufferStart); // +2 for double zero terminator
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInstanceByTypeHandle
+//
+// Description: Returns the instance of the input structure type and its handle
+//
+// Input: IN UINT8 Type
+// IN UINT16 Handle
+//
+// Output: Instance number (1-based) if found, or 0 if not found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetInstanceByTypeHandle(
+ IN UINT8 Type,
+ IN UINT16 Handle
+)
+{
+ UINT8 *Table = SmbiosDataTable;
+ UINT8 Instance = 0; // 1-based
+
+ while(((SMBIOS_STRUCTURE_HEADER*)Table)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)Table)->Type == Type) {
+ Instance ++;
+ }
+
+ if (((SMBIOS_STRUCTURE_HEADER*)Table)->Handle == Handle) {
+ return Instance;
+ }
+
+ Table = Table + GetStructureLength(Table);
+ }
+
+ return 0; // Not found
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStructureType
+//
+// Description: Find structure type starting from memory location pointed by
+// Buffer
+//
+// Input: IN OUT UINT8 **Buffer
+// IN OUT UINT8 **StructureFoundPtr
+// IN UINT8 SearchType
+// IN UINT8 Instance
+//
+// Output:
+// BOOLEAN
+// TRUE - Structure found
+// FALSE - Structure not found
+//
+// If SearchType is found:
+// UINT8 **Buffer - Points to the next structure
+// UINT8 **StructureFoundPtr - Points to the structure
+// that was found
+// If SearchType is not found:
+// UINT8 **Buffer - No change
+// UINT8 **StructureFoundPtr = NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindStructureType(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT8 **StructureFoundPtr,
+ IN UINT8 SearchType,
+ IN UINT8 Instance // 1-based
+)
+{
+ UINT8 *BufferPtr = *Buffer;
+ BOOLEAN FindStatus = FALSE;
+
+ *StructureFoundPtr = NULL;
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type == SearchType) {
+ // If this instance, set the find status flag and update the Buffer pointer
+ if (--Instance == 0) {
+ FindStatus = TRUE;
+ *StructureFoundPtr = BufferPtr;
+ *Buffer = BufferPtr + GetStructureLength(BufferPtr);
+ break;
+ }
+ }
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ if ((FindStatus == FALSE) && (SearchType == 127)) {
+ FindStatus = TRUE;
+ *StructureFoundPtr = BufferPtr;
+ *Buffer = BufferPtr + GetStructureLength(BufferPtr);
+ }
+ return FindStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStructureHandle
+//
+// Description: Find structure handle starting from memory location pointed
+// by Buffer
+//
+// Input: IN OUT UINT8 **Buffer
+// IN UINT16 Handle
+//
+// Output:
+// BOOLEAN
+// TRUE - Structure found
+// FALSE - Structure not found
+//
+// If SearchType is found:
+// UINT8 **Buffer - Points to the structure that was found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindStructureHandle(
+ IN OUT UINT8 **Buffer,
+ IN UINT16 Handle
+)
+{
+ while (((SMBIOS_STRUCTURE_HEADER*)*Buffer)->Handle != Handle) {
+ if (((SMBIOS_STRUCTURE_HEADER*)*Buffer)->Type == 127) {
+ return FALSE;
+ }
+ *Buffer += GetStructureLength(*Buffer);
+ }
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateType127Handle
+//
+// Description: Updates Structure Type 127 handle and sets global variable
+// LastHandle to the last structure handle.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: Sets global variable LastHandle
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateType127Handle(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 Handle;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ Handle = ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle;
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle = ++Handle;
+ LastHandle = Handle;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetNumberOfStructures
+//
+// Description: Returns the number of structures starting from Buffer til
+// (and including) type 127 structure.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Number of structures
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetNumberOfStructures(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 SmbiosStrucCount = 1;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ ++SmbiosStrucCount;
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ return SmbiosStrucCount;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLargestStructureSize
+//
+// Description: Returns the largest structure size
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Largest structure size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetLargestStructureSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 LargestStructureSize = 0;
+ UINT16 CurrentStructureSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ UINT8 *LastBufferPtr;
+
+ LastBufferPtr = BufferPtr;
+ BufferPtr += ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length;
+ while(TRUE) {
+ if ((*(UINT16*)BufferPtr) == 0) {
+ BufferPtr += 2;
+ break;
+ }
+ BufferPtr++;
+ }
+ CurrentStructureSize = (UINT16)(BufferPtr - LastBufferPtr);
+ if (CurrentStructureSize > LargestStructureSize) {
+ LargestStructureSize = CurrentStructureSize;
+ }
+ }
+ return LargestStructureSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetTypeTable
+//
+// Description: Return pointer to the input type string table
+//
+// Input: IN UINT8 Structure Type
+//
+// Output: Pointer to the input type string table
+// (or NULL if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetTypeTable(
+ IN UINT8 StructureType
+)
+{
+ if (StructureType < 42) {
+ return StringTable[StructureType];
+ }
+ else {
+ return NULL;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStrIndex
+//
+// Description: Return the string index, assuming all strings exist and they
+// sequentially numbered according to Smbios specification for
+// the input type structure
+//
+// Input: IN UINT8 Structure Type
+// IN UINT8 Offset,
+// IN UINT8 Instance // 1- based
+//
+// Output: String index (0-based)
+// (or 0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStrIndex(
+ IN UINT8 Type,
+ IN UINT8 Offset,
+ IN UINT8 Instance // 1- based
+)
+{
+ UINT8 i = 0;
+ STRING_TABLE *StrTablePtr;
+
+ StrTablePtr = GetTypeTable(Type);
+ if (StrTablePtr != NULL) {
+ StrTablePtr += 6 * (Instance - 1);
+ while (StrTablePtr->Offset != 0xff) {
+ if (StrTablePtr->Offset == Offset) {
+ i = StrTablePtr->SpecStrNum - 1; // 0-based
+ break;
+ }
+
+ StrTablePtr++;
+ }
+
+ if (StrTablePtr->Offset != 0xff) {
+ return i;
+ }
+ }
+
+ return 0xff;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStrNumber
+//
+// Description: Return the string number for a structure "Type" at "Offset"
+//
+// Input: IN UINT8 Pointer to SmbiosTable or Structure
+// IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: String number (1-based)
+// (or 0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStrNumber(
+ IN UINT8 *SmbiosTable,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ UINT8 *NextStructPtr = SmbiosTable;
+ UINT8 *TempPtr;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ return *(TempPtr + Offset);
+ }
+ else {
+ return 0xff;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindLargestStrNumber
+//
+// Description: Return the largest string number in a structure
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 *StrTablePtr
+//
+// Output: String number (1-based)
+// (or 0 if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+FindLargestStrNumber (
+ IN UINT8 *StructPtr,
+ IN STRING_TABLE *StrTablePtr
+)
+{
+ UINT8 Number;
+ UINT8 StrNumber = 0;
+
+ // Find largest string number from structure
+ while (StrTablePtr->Offset != 0xff) {
+ Number = *(StructPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ StrNumber = Number;
+ }
+ StrTablePtr++;
+ }
+
+ return StrNumber; // 1-based, 0 if no string
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringNumber
+//
+// Description: Add new string number for a structure "Type" at "Offset".
+// Return the string index, assuming all strings exist in the
+// structure according to the Smbios specification
+//
+// Input: IN UINT8 Pointer to SmbiosTable or Structure
+// IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: String index (0-based)
+// (0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+AddStringNumber(
+ IN UINT8 *SmbiosTable,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ STRING_TABLE *StrTablePtr;
+ UINT8 *NextStructPtr = SmbiosTable;
+ UINT8 *TempPtr;
+ UINT8 Index = 0xff;
+ UINT8 StrNumber = 0;
+ UINT8 Number;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ StrTablePtr = GetTypeTable(Type);
+ if (StrTablePtr != NULL) {
+ // Find largest string number from structure
+ while (StrTablePtr->Offset != 0xff) {
+ if (StrTablePtr->Offset == Offset) {
+ // String index in Smbios spec
+ Index = StrTablePtr->SpecStrNum - 1; // 0-based
+ }
+
+ Number = *(TempPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ StrNumber = Number;
+ }
+ StrTablePtr++;
+ }
+
+ // Assign next string number to structure at input Offset
+ *(TempPtr + Offset) = ++StrNumber;
+
+ return Index; // 0-based
+ }
+ }
+
+ return 0xff;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStringNumber
+//
+// Description: Zero out the string number in StructPtr
+//
+// Input: IN UINT8 *StructurePtr
+// IN UINT8 StrNumber
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DeleteStringNumber (
+ IN UINT8 *StructPtr,
+ IN UINT8 StrNumber
+)
+{
+ UINT8 Number;
+ STRING_TABLE *StrTablePtr;
+
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+
+ while (StrTablePtr->Offset != 0xff) {
+ Number = *(StructPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ *(StructPtr + StrTablePtr->Offset) = Number - 1;
+ }
+ if (Number == StrNumber) {
+ *(StructPtr + StrTablePtr->Offset) = 0;
+ }
+ StrTablePtr++;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringOffset
+//
+// Description: Returns the string offset for StringNumber from BufferStart
+//
+// Input: IN UINT8 *BufferStart
+// IN UINT8 StringNumber
+//
+// Output: UINT16 - Offset from BufferStart
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetStringOffset(
+ IN UINT8 *BufferStart,
+ IN UINT8 StringNumber // 1-based
+)
+{
+ UINT8 *BufferEnd = BufferStart;
+
+ while (--StringNumber) {
+ while(*BufferEnd != 0) {
+ BufferEnd++;
+ }
+ BufferEnd++;
+ }
+ return (UINT16)(BufferEnd - BufferStart);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindString
+//
+// Description: Returns pointer to the string number in structure BufferPtr
+//
+// Input: IN OUT UINT8 **BufferPtr
+// IN UINT8 StringNumber
+//
+// Output: UINT8 *BufferPtr = Pointer to the #StringNumber string
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindString(
+ IN OUT UINT8 **BufferPtr,
+ IN UINT8 StringNumber // 1-based
+)
+{
+ UINT8 *StructurePtr;
+ UINT8 *StructureEnd;
+
+ StructurePtr = *BufferPtr;
+ StructureEnd = StructurePtr + GetStructureLength(StructurePtr);
+ StructurePtr += ((SMBIOS_STRUCTURE_HEADER*)StructurePtr)->Length;
+ StructurePtr += GetStringOffset(StructurePtr, StringNumber);
+ if (StructurePtr >= StructureEnd) {
+ return FALSE;
+ }
+ else {
+ *BufferPtr = StructurePtr;
+ return TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteString
+//
+// Description: Delete string at Offset
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 Offset
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DeleteString (
+ IN UINT8 *StructPtr,
+ IN UINT8 StrNumber
+)
+{
+ UINT8 *TempPtr;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ // Delete string number
+ DeleteStringNumber(StructPtr, StrNumber);
+
+ FindString(&StructPtr, StrNumber); // StructPtr = StrNumber string
+ TempPtr = StructPtr + Strlen((char*)StructPtr) + 1; // Move pointer to next string
+
+ // Find end of structure
+ StructEndPtr = TempPtr;
+ while(*(UINT16*)StructEndPtr != 0) {
+ StructEndPtr++;
+ }
+
+ // Copy remaining strings
+ RemainingSize = StructEndPtr + 2 - TempPtr; // Including double NULL characters
+ MemCpy(StructPtr, TempPtr, RemainingSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddNullTerminator
+//
+// Description: Add NULL terminator to the end of the structure
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 *StrTablePtr
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddNullTerminator (
+ IN UINT8 *StructPtr,
+ IN STRING_TABLE *StrTablePtr
+)
+{
+ UINT8 StrNumber;
+ UINT8 i;
+
+ // Find largest string number
+ StrNumber = FindLargestStrNumber(StructPtr, StrTablePtr);
+
+ // Skip to string section
+ StructPtr += ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Length;
+
+ // Move pointer to the end of last string
+ for (i = 0; i < StrNumber; i++) {
+ while (*StructPtr != NULL) StructPtr++;
+ StructPtr++;
+ }
+
+ // Add NULL terminator
+ *StructPtr = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStrings
+//
+// Description: Copy strings from NvramData to StructPtr
+//
+// Input: IN SMBIOS_NVRAM_TYPE *NvramData,
+// IN OUT UINT8 *StructPtr
+// IN UINT8 StrTableInstance // 1-based
+//
+// Output: Updated strings in StructPtr
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStrings(
+ IN SMBIOS_NVRAM_TYPE *NvramData,
+ IN OUT UINT8 *StructPtr,
+ IN UINT8 StrTableInstance // 1-based
+)
+{
+ UINT8 TestBit;
+ UINT8 i;
+ UINT8 Type;
+ UINT8 StrNumber;
+ STRING_TABLE *StrTablePtr;
+
+ if (NvramData->Flag != 0) {
+ // Set StringTablePtr pointer to the appropriate string table
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+ if (((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type == 3) {
+ StrTablePtr += 6 * (StrTableInstance - 1);
+ }
+
+ if (StrTablePtr != NULL) {
+ CHAR8 *String;
+
+ // Update String fields
+ for (i = 0; StrTablePtr[i].Offset != 0xff; i++) {
+ TestBit = (1 << i);
+ if (NvramData->Flag & TestBit) {
+ // Structure string has been changed, update it
+ Type = ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type;
+ StrNumber = GetStrNumber(StructPtr, Type, StrTablePtr[i].Offset);
+ String = NvramData->StringSet[i];
+ if (Strlen(String) != 0) {
+ if (StrNumber == 0) {
+ AddStringNumber(StructPtr, Type, StrTablePtr[i].Offset);
+ StrNumber = GetStrNumber(StructPtr, Type, StrTablePtr[i].Offset);
+ }
+ ReplaceString(StructPtr, StrNumber, String); // StrNumber 1-based
+ }
+ else {
+ DeleteString(StructPtr, StrNumber);
+ }
+ }
+ }
+
+ // Add structure terminator Null byte
+ AddNullTerminator(StructPtr, StrTablePtr);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType0
+//
+// Description: Copy Type 0 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE0 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType0(
+ IN SMBIOS_NVRAM_TYPE0 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType1
+//
+// Description: Copy Type 1 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE1 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType1(
+ IN SMBIOS_NVRAM_TYPE1 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+ UINT16 i;
+ SMBIOS_SYSTEM_INFO *Ptr;
+ UINT8 *NvramUuidPtr;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // UUID field - Offset 8 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ UINT8 *UuidPtr;
+
+ Ptr = (SMBIOS_SYSTEM_INFO*)TempBuffer;
+ UuidPtr = (UINT8*)&Ptr->Uuid;
+ NvramUuidPtr = (UINT8*)&NvramData->Uuid;
+ for (i = 0; i < sizeof(EFI_GUID); i++) {
+ UuidPtr[i] = NvramUuidPtr[i];
+ }
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+
+#if BASE_BOARD_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType2
+//
+// Description: Copy Type 2 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE2 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType2(
+ IN SMBIOS_NVRAM_TYPE2 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+#if SYS_CHASSIS_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType3
+//
+// Description: Copy Type 3 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE3 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+// IN UINT8 StringTableInstance
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType3(
+ IN SMBIOS_NVRAM_TYPE3 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer,
+ IN UINT8 StrTableInstance // 1-based
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // Type field - Offset 5 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->Type = NvramData->Type;
+ }
+
+ // OEM-Defined field - Offset 0x0D (Test Bit17)
+ if (NvramData->Flag & 0x00020000) {
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->OemDefined = NvramData->OemDefined;
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, StrTableInstance);
+ }
+}
+#endif
+
+#if PROCESSOR_DMIEDIT_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType4
+//
+// Description: Copy Type 4 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE4 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType4(
+ IN SMBIOS_NVRAM_TYPE4 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+#if OEM_STRING_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType11
+//
+// Description: Copy Type 11 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE11 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType11(
+ IN SMBIOS_NVRAM_TYPE11 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 StringSize;
+ UINT16 NvramStringSize;
+ UINT16 BlockSize;
+ UINT32 TestBit;
+ UINT8 i;
+ UINT8 Count;
+
+ if (NvramData->Flag == 0) {
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+ }
+ else {
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)SrcBuffer)->Length;
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ Count = ((SMBIOS_OEM_STRINGS_INFO*)TempBuffer)->Count;
+
+ // Move pointers
+ SrcBuffer += BlockSize;
+ TempBuffer += BlockSize;
+
+ // "NUMBER_OF_OEM_STRINGS" string fields
+ for (i = 0; (i < Count) && (i < 32); i++) {
+ StringSize = (UINT16)(Strlen(SrcBuffer) + 1); // Size including string NULL terminator
+ TestBit = (1 << i);
+ if (NvramData->Flag & TestBit) {
+ NvramStringSize = (UINT16)(Strlen(NvramData->StringSet[i]) + 1);
+ MemCpy(TempBuffer, NvramData->StringSet[i], NvramStringSize);
+ TempBuffer += NvramStringSize;
+ }
+ else {
+ MemCpy(TempBuffer, SrcBuffer, StringSize);
+ TempBuffer += StringSize;
+ }
+ SrcBuffer += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ }
+}
+#endif
+
+#if SYSTEM_CONFIG_OPTION_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType12
+//
+// Description: Copy Type 12 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE12 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType12(
+ IN SMBIOS_NVRAM_TYPE12 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 StringSize;
+ UINT16 NvramStringSize;
+ UINT16 BlockSize;
+ UINT32 TestBit;
+ UINT8 i;
+ UINT8 Count;
+
+ if (NvramData->Flag == 0) {
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+ }
+ else {
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)SrcBuffer)->Length;
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ Count = ((SMBIOS_SYSTEM_CONFIG_INFO*)TempBuffer)->Count;
+
+ // Move pointers
+ SrcBuffer += BlockSize;
+ TempBuffer += BlockSize;
+
+ // "NUMBER_OF_SYSTEM_CONFIG_STRINGS" string fields
+ for (i = 0; (i < Count) && (i < 32); i++) {
+ StringSize = (UINT16)(Strlen((char*)SrcBuffer) + 1); // Size including string NULL terminator
+ TestBit = (1 << i);
+ if (NvramData->Flag & TestBit) {
+ NvramStringSize = (UINT16)(Strlen(NvramData->StringSet[i]) + 1);
+ MemCpy(TempBuffer, NvramData->StringSet[i], NvramStringSize);
+ TempBuffer += NvramStringSize;
+ }
+ else {
+ MemCpy(TempBuffer, SrcBuffer, StringSize);
+ TempBuffer += StringSize;
+ }
+ SrcBuffer += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ }
+}
+#endif
+
+#if PORTABLE_BATTERY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType22
+//
+// Description: Copy Type 22 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE22 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType22(
+ IN SMBIOS_NVRAM_TYPE22 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // Type field - Offset 9 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DeviceChemistry = NvramData->DeviceChemistry;
+ }
+
+ // OEM-Defined field - Offset 0x0a (Test Bit17)
+ if (NvramData->Flag & 0x00020000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DesignCapacity = NvramData->DesignCapacity;
+ }
+
+ // OEM-Defined field - Offset 0x0c (Test Bit18)
+ if (NvramData->Flag & 0x00040000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DesignVoltage = NvramData->DesignVoltage;
+ }
+
+ // OEM-Defined field - Offset 0x0f (Test Bit19)
+ if (NvramData->Flag & 0x00080000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->MaxErrorInBatteryData = NvramData->MaxErrorInBatteryData;
+ }
+
+ // OEM-Defined field - Offset 0x10 (Test Bit20)
+ if (NvramData->Flag & 0x00100000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->SBDSSerialNumber = NvramData->SbdsSerialNumber;
+ }
+
+ // OEM-Defined field - Offset 0x12 (Test Bit21)
+ if (NvramData->Flag & 0x00200000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->SBDSManufacturerDate = NvramData->SbdsManufacturerDate;
+ }
+
+ // OEM-Defined field - Offset 0x15 (Test Bit22)
+ if (NvramData->Flag & 0x00400000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->DesignCapabilityMult = NvramData->DesignCapacityMultiplier;
+ }
+
+ // OEM-Defined field - Offset 0x16 (Test Bit23)
+ if (NvramData->Flag & 0x00800000) {
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempBuffer)->OEMSpecific = NvramData->OemSpecific;
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+#if SYSTEM_POWER_SUPPLY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramType39
+//
+// Description: Copy Type 39 strings to TempBuffer. Strings will be copied
+// from NVRAM if exist, or else from existing strings in ROM image.
+// SrcBuffer and TempBuffer pointers are updated
+//
+// Input: IN SMBIOS_NVRAM_TYPE39 *NvramData,
+// IN OUT UINT8 *SrcBuffer
+// IN OUT UINT8 *TempBuffer
+//
+// Output: Updated SrcBuffer and TempBuffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateStructuresWithNvramType39(
+ IN SMBIOS_NVRAM_TYPE39 *NvramData,
+ IN OUT UINT8 *SrcBuffer,
+ IN OUT UINT8 *TempBuffer
+)
+{
+ UINT16 BlockSize;
+
+ // Copy structure data from SrcBuffer
+ BlockSize = GetStructureLength(SrcBuffer);
+ MemCpy(TempBuffer, SrcBuffer, BlockSize);
+
+ if (NvramData != NULL) {
+ // Type field - Offset 4 (Test Bit16)
+ if (NvramData->Flag & 0x00010000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->PwrUnitGroup = NvramData->PwrUnitGroup;
+ }
+
+ // OEM-Defined field - Offset 0x0c (Test Bit17)
+ if (NvramData->Flag & 0x00020000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->MaxPwrCapacity = NvramData->MaxPwrCapacity;
+ }
+
+ // OEM-Defined field - Offset 0x0e (Test Bit18)
+ if (NvramData->Flag & 0x00040000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->PwrSupplyChar = NvramData->PwrSupplyChar;
+ }
+
+ // OEM-Defined field - Offset 0x10 (Test Bit19)
+ if (NvramData->Flag & 0x00080000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->InputVoltProbeHandle = NvramData->InputVoltageProbeHandle;
+ }
+
+ // OEM-Defined field - Offset 0x12 (Test Bit20)
+ if (NvramData->Flag & 0x00100000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->CoolingDevHandle = NvramData->CoolingDevHandle;
+ }
+
+ // OEM-Defined field - Offset 0x14 (Test Bit21)
+ if (NvramData->Flag & 0x00200000) {
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)TempBuffer)->InputCurrentProbeHandle = NvramData->InputCurrentProbeHandle;
+ }
+
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)NvramData, TempBuffer, 1);
+ }
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetType22StringIndex
+//
+// Description: Returns the string index for Type 22 structure from a given
+// Offset.
+//
+// Input: IN UINT8 Offset
+//
+// Output: UINT8 - Type 22 Structure String index
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetType22StringIndex(
+ IN UINT8 Offset
+)
+{
+ switch (Offset) {
+ case 0x0e: return 5;
+ case 0x14: return 6;
+ }
+ return (Offset - 4);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetType39StringIndex
+//
+// Description: Returns the string index for Type 39 structure from a given
+// Offset.
+//
+// Input: IN UINT8 Offset
+//
+// Output: UINT8 - Type 39 Structure String index
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetType39StringIndex(
+ IN UINT8 Offset
+)
+{
+ return (Offset - 5);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LoadRealModeFileSection
+//
+// Description: Locates the input specified Guid file in the Firmware Volumn
+// and loads it into the input Buffer
+//
+// Input: IN EFI_GUID *Guid - File GUID to read
+// IN EFI_SECTION_TYPE SectionType
+// IN OUT VOID **Buffer
+// IN OUT UINTN *BufferSize
+//
+// Output: EFI_STATUS
+// VOID **Buffer - Contains the content of the Guid file
+// UINTN *BufferSize - Size of the output buffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+LoadRealModeFileSection(
+ IN EFI_GUID *Guid,
+ IN EFI_SECTION_TYPE SectionType,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *BufferSize
+)
+{
+ EFI_STATUS Status;
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#endif
+ UINT32 Authentication;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN i;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiFVProtocolGuid,NULL,&NumHandles,&HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i< NumHandles; ++i) {
+ Status = pBS->HandleProtocol(HandleBuffer[i],&guidFV,&Fv);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = Fv->ReadSection(Fv,
+ Guid,
+ SectionType,
+ 0, //Instance
+ Buffer,
+ BufferSize,
+ &Authentication);
+
+ if (Status == EFI_SUCCESS) break;
+ }
+
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+#if (defined(SmbiosDMIEdit_SUPPORT) && (SmbiosDMIEdit_SUPPORT != 0))
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStructuresWithNvramData
+//
+// Description: Updates structures in input Buffer with DMI Data in NVRAM
+//
+// Input: IN UINT8 *Buffer
+// IN UINT8 BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateStructuresWithNvramData(
+ IN UINT8 *Buffer,
+ IN UINTN BufferSize
+)
+{
+ EFI_STATUS Status;
+ UINT16 StructureSize;
+ UINT8 *BufferPtr = Buffer;
+ UINT8 *TempBuffer;
+ UINT8 *TempBufferPtr;
+ UINTN Index;
+ UINTN i;
+ BOOLEAN UpdateFlag = FALSE; // Flag indicating if any structure has been updated
+
+#if (TYPE2_STRUCTURE == 1)
+ UINT16 *Type2Handle;
+#endif // TYPE2_STRUCTURE
+#if (TYPE3_STRUCTURE == 1)
+ UINT16 *Type3Handle;
+ UINT8 StrTableInstance;
+#endif // TYPE3_STRUCTURE
+ UINT16 *Type22Handle;
+ UINT16 *Type39Handle;
+
+ UINT8 *DmiData = NULL;
+ UINTN DmiDataSize;
+
+ UINT8 *NvramDataPtrArray[DMI_ARRAY_COUNT];
+
+ SMBIOS_NVRAM_TYPE0 NvramType0;
+ SMBIOS_NVRAM_TYPE1 NvramType1;
+ SMBIOS_NVRAM_TYPE2 *NvramType2 = NULL;
+ SMBIOS_NVRAM_TYPE3 *NvramType3 = NULL;
+ SMBIOS_NVRAM_TYPE11 NvramType11;
+ SMBIOS_NVRAM_TYPE12 NvramType12;
+ SMBIOS_NVRAM_TYPE22 *NvramType22 = NULL;
+ SMBIOS_NVRAM_TYPE39 *NvramType39 = NULL;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ EFI_GUID FlashDataFile = {0xfd44820b, 0xf1ab, 0x41c0, 0xae, 0x4e, 0x0c, 0x55, 0x55, 0x6e, 0xb9, 0xbd};
+ UINT8 *FlashData = NULL;
+ UINTN FlashDataSize = 0;
+ UINT8 *FlashDataPtr;
+ UINT8 *FlashDataEnd;
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ TRACE((-1, "*** SMBIOS - UpdateStructuresWithNvramData ***\n"));
+
+ // Initialize NVRam variables
+ for (i = 0; i < DMI_ARRAY_COUNT; i++) {
+ NvramDataPtrArray[i] = NULL;
+ }
+
+ MemSet(&NvramType0, sizeof(SMBIOS_NVRAM_TYPE0), 0);
+ MemSet(&NvramType1, sizeof(SMBIOS_NVRAM_TYPE1), 0);
+#if (TYPE2_STRUCTURE == 1)
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_BASEBOARDS * sizeof(UINT16), (void**)&Type2Handle);
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_BASEBOARDS * sizeof(SMBIOS_NVRAM_TYPE2), (void**)&NvramType2);
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ Type2Handle[i] = 0;
+ NvramType2[i].Flag = 0;
+ }
+#endif // TYPE2_STRUCTURE
+#if (TYPE3_STRUCTURE == 1)
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_SYSTEM_CHASSIS * sizeof(UINT16), (void**)&Type3Handle);
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_SYSTEM_CHASSIS * sizeof(SMBIOS_NVRAM_TYPE3), (void**)&NvramType3);
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ Type3Handle[i] = 0;
+ NvramType3[i].Flag = 0;
+ }
+#endif // TYPE3_STRUCTURE
+ MemSet(&NvramType4, sizeof(SMBIOS_NVRAM_TYPE4), 0);
+ MemSet(&NvramType11, sizeof(SMBIOS_NVRAM_TYPE11), 0);
+ MemSet(&NvramType12, sizeof(SMBIOS_NVRAM_TYPE12), 0);
+ pBS->AllocatePool(EfiBootServicesData, gSmbiosBoardProtocol->NumberOfBatteries * sizeof(UINT16), (void**)&Type22Handle);
+ pBS->AllocatePool(EfiBootServicesData, gSmbiosBoardProtocol->NumberOfBatteries * sizeof(SMBIOS_NVRAM_TYPE22), (void**)&NvramType22);
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ Type22Handle[i] = 0;
+ NvramType22[i].Flag = 0;
+ }
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_POWER_SUPPLY * sizeof(UINT16), (void**)&Type39Handle);
+ pBS->AllocatePool(EfiBootServicesData, NUMBER_OF_POWER_SUPPLY * sizeof(SMBIOS_NVRAM_TYPE39), (void**)&NvramType39);
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ Type39Handle[i] = 0;
+ NvramType39[i].Flag = 0;
+ }
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ // Get SMBios NVRam Data Structure Image
+ Status = LoadRealModeFileSection(&FlashDataFile, EFI_SECTION_RAW, &FlashData, &FlashDataSize);
+ if (EFI_ERROR(Status)) goto Function_Exit;
+
+ FlashDataPtr = FlashData;
+ FlashDataEnd = FlashData + FLASHDATA_SIZE;
+
+ // Skip _ASB signature and _FlashDataSize
+ FlashDataPtr += 8;
+
+ while ((FlashDataPtr < FlashDataEnd) && (*(UINT32*)FlashDataPtr != 0xffffffff)) {
+ if (((TABLE_INFO*)FlashDataPtr)->Flags & DMIEDIT_DELETE_STRUC) {
+ TRACE((-1, "Delete structure. Handle = %x\n", ((TABLE_INFO*)FlashDataPtr)->Handle));
+ DeleteStructureByHandle(((TABLE_INFO*)FlashDataPtr)->Handle);
+ UpdateFlag = TRUE;
+ }
+ else if (((TABLE_INFO*)FlashDataPtr)->Flags & DMIEDIT_ADD_STRUC) {
+ TRACE((-1, "Add structure by handle. Handle = %x\n", ((TABLE_INFO*)FlashDataPtr)->Handle));
+ TempBufferPtr = FlashDataPtr + sizeof (TABLE_INFO);
+ AddStructureByHandle(((TABLE_INFO*)FlashDataPtr)->Handle, TempBufferPtr, ((TABLE_INFO*)FlashDataPtr)->Size);
+ UpdateFlag = TRUE;
+ }
+ else {
+ TRACE((-1, "Change structure. Type = %x, Handle = %x, Offset = %x\n",\
+ ((TABLE_INFO*)FlashDataPtr)->Type,\
+ ((TABLE_INFO*)FlashDataPtr)->Handle,\
+ ((TABLE_INFO*)FlashDataPtr)->Offset));
+ DmiDataSize = ((TABLE_INFO*)FlashDataPtr)->Size;
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ DmiDataSize,
+ (void**)&DmiData);
+ if (Status == EFI_SUCCESS) {
+ MemCpy(DmiData,
+ FlashDataPtr + sizeof(TABLE_INFO),
+ DmiDataSize);
+
+ switch (((TABLE_INFO*)FlashDataPtr)->Type) {
+ case 0 : {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(0, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType0.StringSet[Index] = (char*)DmiData;
+ NvramType0.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ break;
+ }
+ case 1 : {
+ if (((TABLE_INFO*)FlashDataPtr)->Offset == 8) {
+ MemCpy(&NvramType1.Uuid, FlashDataPtr + sizeof(TABLE_INFO), ((TABLE_INFO*)FlashDataPtr)->Size);
+ NvramType1.Flag |= 0x00010000;
+ UpdateFlag = TRUE;
+ }
+ else {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(1, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType1.StringSet[Index] = (char*)DmiData;
+ NvramType1.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ break;
+ }
+ #if BASE_BOARD_INFO
+ case 2 : {
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ // Save handle number in Type2Handle array for each Type 2 structure
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ if (Type2Handle[i] == 0) {
+ Type2Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type2Handle[i]) break;
+ }
+ if (i < NUMBER_OF_BASEBOARDS) {
+ NvramType2[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(2, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType2[i].StringSet[Index] = (char*)DmiData;
+ NvramType2[i].Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ }
+ break;
+ }
+ #endif // BASE_BOARD_INFO
+ #if SYS_CHASSIS_INFO
+ case 3 : {
+ StrTableInstance = GetInstanceByTypeHandle(3, ((TABLE_INFO*)FlashDataPtr)->Handle);
+
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ // Save handle number in Type3Handle array for each Type 3 structure
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ if (Type3Handle[i] == 0) {
+ Type3Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type3Handle[i]) break;
+ }
+ if (i < NUMBER_OF_SYSTEM_CHASSIS) {
+ NvramType3[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ if (((TABLE_INFO*)FlashDataPtr)->Offset == 5) {
+ MemCpy(&NvramType3[i].Type, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType3[i].Flag |= 0x00010000;
+ UpdateFlag = TRUE;
+ }
+ else if (((TABLE_INFO*)FlashDataPtr)->Offset == 0x0d) {
+ MemCpy(&NvramType3[i].OemDefined, FlashDataPtr + sizeof(TABLE_INFO), sizeof(UINT32));
+ NvramType3[i].Flag |= 0x00020000;
+ UpdateFlag = TRUE;
+ }
+ else {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(3, ((TABLE_INFO*)FlashDataPtr)->Offset, StrTableInstance);
+ if (Index != 0xff) {
+ NvramType3[i].StringSet[Index] = (char*)DmiData;
+ NvramType3[i].Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ }
+ }
+ break;
+ }
+ #endif // SYS_CHASSIS_INFO
+ #if PROCESSOR_DMIEDIT_SUPPORT
+ case 4 : {
+ if (gSmbiosBoardProtocol->ProcessorDmiEditSupport) {
+ // Get string index (Smbios spec) at Offset
+ Index = GetStrIndex(4, ((TABLE_INFO*)FlashDataPtr)->Offset, 1);
+ if (Index != 0xff) {
+ NvramType4.StringSet[Index] = (char*)DmiData;
+ NvramType4.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ }
+ break;
+ }
+ #endif // SYS_CHASSIS_INFO
+ #if OEM_STRING_INFO
+ case 11 : {
+ if (gSmbiosBoardProtocol->OemStringInfoSupport) {
+ Index = ((TABLE_INFO*)FlashDataPtr)->Offset - 1;
+ NvramType11.StringSet[Index] = (char*)DmiData;
+ NvramType11.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ break;
+ }
+ #endif // OEM_STRING_INFO
+ #if SYSTEM_CONFIG_OPTION_INFO
+ case 12 : {
+ if (gSmbiosBoardProtocol->SystemConfigOptionInfoSupport) {
+ Index = ((TABLE_INFO*)FlashDataPtr)->Offset - 1;
+ NvramType12.StringSet[Index] = (char*)DmiData;
+ NvramType12.Flag |= (1 << Index);
+ UpdateFlag = TRUE;
+ }
+ break;
+ }
+ #endif // SYSTEM_CONFIG_OPTION_INFO
+ #if PORTABLE_BATTERY_INFO
+ case 22 : {
+ // Save handle number in Type22Handle array for each Type 22 structure
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ if (Type22Handle[i] == 0) {
+ Type22Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type22Handle[i]) break;
+ }
+ if (i < gSmbiosBoardProtocol->NumberOfBatteries) {
+ NvramType22[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ switch (((TABLE_INFO*)FlashDataPtr)->Offset) {
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x0e:
+ case 0x14: Index = GetType22StringIndex(((TABLE_INFO*)FlashDataPtr)->Offset);
+ NvramType22[i].StringSet[Index] = (char*)DmiData;
+ NvramType22[i].Flag |= (1 << Index);
+ break;
+ case 0x09: MemCpy(&NvramType22[i].DeviceChemistry, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType22[i].Flag |= 0x00010000;
+ break;
+ case 0x0a: MemCpy(&NvramType22[i].DesignCapacity, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00020000;
+ break;
+ case 0x0c: MemCpy(&NvramType22[i].DesignVoltage, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00040000;
+ break;
+ case 0x0f: MemCpy(&NvramType22[i].MaxErrorInBatteryData, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType22[i].Flag |= 0x00080000;
+ break;
+ case 0x10: MemCpy(&NvramType22[i].SbdsSerialNumber, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00100000;
+ break;
+ case 0x12: MemCpy(&NvramType22[i].SbdsManufacturerDate, FlashDataPtr + sizeof(TABLE_INFO), 2);
+ NvramType22[i].Flag |= 0x00200000;
+ break;
+ case 0x15: MemCpy(&NvramType22[i].DesignCapacityMultiplier, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType22[i].Flag |= 0x00400000;
+ break;
+ case 0x16: MemCpy(&NvramType22[i].OemSpecific, FlashDataPtr + sizeof(TABLE_INFO), 4);
+ NvramType22[i].Flag |= 0x00800000;
+ break;
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+ }
+ #endif // PORTABLE_BATTERY_INFO
+ #if SYSTEM_POWER_SUPPLY_INFO
+ case 39 : {
+ // Save handle number in Type39Handle array for each Type 39 structure
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ if (Type39Handle[i] == 0) {
+ Type39Handle[i] = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ break;
+ }
+ if (((TABLE_INFO*)FlashDataPtr)->Handle == Type39Handle[i]) break;
+ }
+ if (i < NUMBER_OF_POWER_SUPPLY) {
+ NvramType39[i].Handle = ((TABLE_INFO*)FlashDataPtr)->Handle;
+ switch (((TABLE_INFO*)FlashDataPtr)->Offset) {
+ case 0x04: MemCpy(&NvramType39[i].PwrUnitGroup, FlashDataPtr + sizeof(TABLE_INFO), 1);
+ NvramType39[i].Flag |= 0x00010000;
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x09:
+ case 0x0a:
+ case 0x0b: Index = GetType39StringIndex(((TABLE_INFO*)FlashDataPtr)->Offset);
+ NvramType39[i].StringSet[Index] = (char*)DmiData;
+ NvramType39[i].Flag |= (1 << Index);
+ break;
+ case 0x0c: NvramType39[i].MaxPwrCapacity = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00020000;
+ break;
+ case 0x0e: NvramType39[i].PwrSupplyChar = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00040000;
+ break;
+ case 0x10: NvramType39[i].InputVoltageProbeHandle = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00080000;
+ break;
+ case 0x12: NvramType39[i].CoolingDevHandle = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00100000;
+ break;
+ case 0x14: NvramType39[i].InputCurrentProbeHandle = *(UINT16*)(FlashDataPtr + sizeof(TABLE_INFO));
+ NvramType39[i].Flag |= 0x00200000;
+ break;
+ }
+ }
+ UpdateFlag = TRUE;
+ }
+ #endif // SYSTEM_POWER_SUPPLY_INFO
+ }
+ }
+ }
+
+ if (((TABLE_INFO*)FlashDataPtr)->Flags & DMIEDIT_DELETE_STRUC) {
+ FlashDataPtr += sizeof(TABLE_INFO);
+ }
+ else {
+ FlashDataPtr += (sizeof(TABLE_INFO) + ((TABLE_INFO*)FlashDataPtr)->Size);
+ }
+ }
+#else // SMBIOS_DMIEDIT_DATA_LOC
+{
+ CHAR16 *DmiArrayVar = L"DmiArray";
+ DMI_VAR *DmiArray;
+ UINTN DmiArraySize = DMI_ARRAY_COUNT * sizeof(DMI_VAR);
+ UINT8 Count = 0;
+ CHAR16 *S1 = L" ";
+ UINT8 Type;
+ UINT16 Handle;
+ UINT8 Offset;
+ UINT8 Flags;
+
+ pBS->AllocatePool(EfiBootServicesData, DmiArraySize, (void**)&DmiArray);
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Count = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+
+ for (Index = 0; Index < Count; Index++) {
+ Type = DmiArray[Index + 1].Type;
+ Handle = DmiArray[Index + 1].Handle;
+ Offset = DmiArray[Index + 1].Offset;
+ Flags = DmiArray[Index + 1].Flags;
+
+ Swprintf(S1, L"DmiVar%02x%04x%02x%02x",
+ Type,
+ Handle,
+ Offset,
+ Flags);
+
+ // Check if variable already exists
+ //
+ // Size of zero is used to detect if the variable exists.
+ // If the variable exists, an error code of EFI_BUFFER_TOO_SMALL
+ // would be returned
+ DmiDataSize = 0;
+ Status = pRS->GetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ &NvramDataPtrArray[Index]);
+
+ if (Status == EFI_NOT_FOUND) {
+ continue;
+ }
+
+ if (Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ DmiDataSize,
+ (void**)&NvramDataPtrArray[Index]);
+
+ DmiData = NvramDataPtrArray[Index];
+
+ Status = pRS->GetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ DmiData);
+ }
+
+ if (Flags & DMIEDIT_DELETE_STRUC) {
+ TRACE((-1, "Delete structure. Handle = %x\n", Handle));
+ DeleteStructureByHandle(Handle);
+ UpdateFlag = TRUE;
+ }
+ else if (Flags & DMIEDIT_ADD_STRUC) {
+ if (Status == EFI_SUCCESS) {
+ TRACE((-1, "Add structure by handle. Handle = %x\n", Handle));
+ AddStructureByHandle(Handle, DmiData, (UINT16)DmiDataSize);
+ UpdateFlag = TRUE;
+ }
+ }
+ else {
+ if (Status == EFI_SUCCESS) {
+ TRACE((-1, "Change structure. Type = %x, Handle = %x, Offset = %x\n",\
+ Type, Handle, Offset));
+ switch (Type) {
+ case 00:
+ if (Offset == 0x04) { // Vendor
+ NvramType0.StringSet[0] = (char*)DmiData;
+ NvramType0.Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Version
+ NvramType0.StringSet[1] = (char*)DmiData;
+ NvramType0.Flag |= 0x00000002;
+ }
+ else if (Offset == 0x08) { // Release Date
+ NvramType0.StringSet[2] = (char*)DmiData;
+ NvramType0.Flag |= 0x00000004;
+ }
+ UpdateFlag = TRUE;
+ break;
+ case 01:
+ if (Offset == 0x04) { // Manufacturer
+ NvramType1.StringSet[0] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Product Name
+ NvramType1.StringSet[1] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000002;
+ }
+ else if (Offset == 0x06) { // Version
+ NvramType1.StringSet[2] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000004;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType1.StringSet[3] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000008;
+ }
+ else if (Offset == 0x08) { // UUID
+ MemCpy(&NvramType1.Uuid,
+ DmiData,
+ 16);
+ NvramType1.Flag |= 0x00010000;
+ }
+ else if (Offset == 0x19) { // SKU Number
+ NvramType1.StringSet[4] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000010;
+ }
+ else if (Offset == 0x1a) { // Family
+ NvramType1.StringSet[5] = (char*)DmiData;
+ NvramType1.Flag |= 0x00000020;
+ }
+ UpdateFlag = TRUE;
+ break;
+#if BASE_BOARD_INFO
+ case 02:
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ // Save handle number in Type2Handle array for each Type 2 structure
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ if (Type2Handle[i] == 0) {
+ Type2Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type2Handle[i]) break;
+ }
+ if (i < NUMBER_OF_BASEBOARDS) {
+ NvramType2[i].Handle = Handle;
+ if (Offset == 0x04) { // Manufacturer
+ NvramType2[i].StringSet[0] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Product
+ NvramType2[i].StringSet[1] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x06) { // Version
+ NvramType2[i].StringSet[2] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType2[i].StringSet[3] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x08) { // Asset Tag
+ NvramType2[i].StringSet[4] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000010;
+ }
+ else if (Offset == 0x0a) { // Location in Chassis
+ NvramType2[i].StringSet[5] = (char*)DmiData;
+ NvramType2[i].Flag |= 0x00000020;
+ }
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // BASE_BOARD_INFO
+#if SYS_CHASSIS_INFO
+ case 03:
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ // Save handle number in Type3Handle array for each Type 3 structure
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ if (Type3Handle[i] == 0) {
+ Type3Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type3Handle[i]) break;
+ }
+ if (i < NUMBER_OF_SYSTEM_CHASSIS) {
+ NvramType3[i].Handle = Handle;
+ TempBuffer = SmbiosDataTable;
+
+ if (Offset == 0x04) { // Manufacturer
+ NvramType3[i].StringSet[0] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Type
+ NvramType3[i].Type = *(UINT8*)DmiData;
+ NvramType3[i].Flag |= 0x00010000;
+ }
+ else if (Offset == 0x06) { // Version
+ NvramType3[i].StringSet[1] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType3[i].StringSet[2] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x08) { // Asset Tag
+ NvramType3[i].StringSet[3] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x0d) { // OEM-defined
+ NvramType3[i].OemDefined = *(UINT32*)DmiData;
+ NvramType3[i].Flag |= 0x00020000;
+ }
+ else if (FindStructureHandle(&TempBuffer, Handle)) {
+ if (Offset == 0x15 + (((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->ElementCount * ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)TempBuffer)->ElementRecordLength)) { // SKU Number
+ NvramType3[i].StringSet[4] = (char*)DmiData;
+ NvramType3[i].Flag |= 0x00000010;
+ }
+ }
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // SYS_CHASSIS_INFO
+#if ( defined(PROCESSOR_DMIEDIT_SUPPORT) && (PROCESSOR_DMIEDIT_SUPPORT == 1) )
+ case 04:
+ if (gSmbiosBoardProtocol->ProcessorDmiEditSupport) {
+ if (Offset == 0x20) { // Serial Number
+ NvramType4.StringSet[3] = (char*)DmiData;
+ NvramType4.Flag |= BIT3;
+ }
+ else if (Offset == 0x21) { // Asset Tag
+ NvramType4.StringSet[4] = (char*)DmiData;
+ NvramType4.Flag |= BIT4;
+ }
+ else if (Offset == 0x22) { // Part Number
+ NvramType4.StringSet[5] = (char*)DmiData;
+ NvramType4.Flag |= BIT5;
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // PROCESSOR_DMIEDIT_SUPPORT
+#if OEM_STRING_INFO
+ case 11:
+ if (gSmbiosBoardProtocol->OemStringInfoSupport) {
+ NvramType11.StringSet[Offset] = (char*)DmiData;
+ NvramType11.Flag |= (1 << Offset);
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // OEM_STRING_INFO
+#if SYSTEM_CONFIG_OPTION_INFO
+ case 12:
+ if (gSmbiosBoardProtocol->SystemConfigOptionInfoSupport) {
+ NvramType12.StringSet[Offset] = (char*)DmiData;
+ NvramType12.Flag |= (1 << Offset);
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // SYSTEM_CONFIG_OPTION_INFO
+#if PORTABLE_BATTERY_INFO
+ case 22:
+ // Save handle number in Type22Handle array for each Type 22 structure
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ if (Type22Handle[i] == 0) {
+ Type22Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type22Handle[i]) break;
+ }
+ if (i < gSmbiosBoardProtocol->NumberOfBatteries) {
+ NvramType22[i].Handle = Handle;
+ if (Offset == 0x04) { // Location
+ NvramType22[i].StringSet[0] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x05) { // Manufacturer
+ NvramType22[i].StringSet[1] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x06) { // Manufacturer Date
+ NvramType22[i].StringSet[2] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x07) { // Serial Number
+ NvramType22[i].StringSet[3] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x08) { // Device Name
+ NvramType22[i].StringSet[4] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000010;
+ }
+ else if (Offset == 0x09) { // Device Chemistry
+ NvramType22[i].DeviceChemistry = *(UINT8*)DmiData;
+ NvramType22[i].Flag |= 0x00010000;
+ }
+ else if (Offset == 0x0a) { // Design Capacity
+ NvramType22[i].DesignCapacity = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00020000;
+ }
+ else if (Offset == 0x0c) { // Design Voltage
+ NvramType22[i].DesignVoltage = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00040000;
+ }
+ else if (Offset == 0x0e) { // SBDS Version Number
+ NvramType22[i].StringSet[5] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000020;
+ }
+ else if (Offset == 0x0f) { // Maximum Error in Battery Data
+ NvramType22[i].MaxErrorInBatteryData = *(UINT8*)DmiData;
+ NvramType22[i].Flag |= 0x00080000;
+ }
+ else if (Offset == 0x10) { // SBDS Serial Number
+ NvramType22[i].SbdsSerialNumber = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00100000;
+ }
+ else if (Offset == 0x12) { // SBDS Manufacturer Date
+ NvramType22[i].SbdsManufacturerDate = *(UINT16*)DmiData;
+ NvramType22[i].Flag |= 0x00200000;
+ }
+ else if (Offset == 0x14) { // SBDS Device Chemistry
+ NvramType22[i].StringSet[6] = (char*)DmiData;
+ NvramType22[i].Flag |= 0x00000040;
+ }
+ else if (Offset == 0x15) { // Design Capacity Multiplier
+ NvramType22[i].DesignCapacityMultiplier = *(UINT8*)DmiData;
+ NvramType22[i].Flag |= 0x00400000;
+ }
+ else if (Offset == 0x16) { // OEM-specific
+ NvramType22[i].OemSpecific = *(UINT32*)DmiData;
+ NvramType22[i].Flag |= 0x00800000;
+ }
+ }
+ UpdateFlag = TRUE;
+ break;
+#endif // PORTABLE_BATTERY_INFO
+#if SYSTEM_POWER_SUPPLY_INFO
+ case 39:
+ // Save handle number in Type39Handle array for each Type 39 structure
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ if (Type39Handle[i] == 0) {
+ Type39Handle[i] = Handle;
+ break;
+ }
+ if (Handle == Type39Handle[i]) break;
+ }
+ if (i < NUMBER_OF_POWER_SUPPLY) {
+ NvramType39[i].Handle = Handle;
+ if (Offset == 0x04) { // Power Unit Group
+ NvramType39[i].PwrUnitGroup = *(UINT8*)DmiData;
+ NvramType39[i].Flag |= 0x00010000;
+ }
+ else if (Offset == 0x05) { // Location
+ NvramType39[i].StringSet[0] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000001;
+ }
+ else if (Offset == 0x06) { // Device Name
+ NvramType39[i].StringSet[1] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000002;
+ }
+ else if (Offset == 0x07) { // Manufacturer
+ NvramType39[i].StringSet[2] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000004;
+ }
+ else if (Offset == 0x08) { // Serial Number
+ NvramType39[i].StringSet[3] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000008;
+ }
+ else if (Offset == 0x09) { // Asset Tag Number
+ NvramType39[i].StringSet[4] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000010;
+ }
+ else if (Offset == 0x0a) { // Model Part Number
+ NvramType39[i].StringSet[5] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000020;
+ }
+ else if (Offset == 0x0b) { // Revision Level
+ NvramType39[i].StringSet[6] = (char*)DmiData;
+ NvramType39[i].Flag |= 0x00000040;
+ }
+ else if (Offset == 0x0c) { // Max Power Capacity
+ NvramType39[i].MaxPwrCapacity = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00020000;
+ }
+ else if (Offset == 0x0e) { // Power Supply Characteristics
+ NvramType39[i].PwrSupplyChar = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00040000;
+ }
+ else if (Offset == 0x10) { // Input Voltage Proble Handle
+ NvramType39[i].InputVoltageProbeHandle = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00080000;
+ }
+ else if (Offset == 0x12) { // Cooling Device Handle
+ NvramType39[i].CoolingDevHandle = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00100000;
+ }
+ else if (Offset == 0x14) { // Input Current Probe Handle
+ NvramType39[i].InputCurrentProbeHandle = *(UINT16*)DmiData;
+ NvramType39[i].Flag |= 0x00200000;
+ }
+ }
+ UpdateFlag = TRUE;
+#endif // SYSTEM_POWER_SUPPLY_INFO
+ }
+ }
+ }
+ }
+ }
+}
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ // Update Smbios table if any structure has been changed
+ if (UpdateFlag) {
+ TRACE((-1, "Updating structures\n"));
+ pBS->AllocatePool(EfiBootServicesData, BufferSize, (void**)&TempBuffer);
+ MemSet(TempBuffer, BufferSize, 0);
+ TempBufferPtr = TempBuffer;
+ BufferPtr = SmbiosDataTable;
+ do {
+ switch (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type) {
+ case 0 : {
+ TRACE((-1, "Updating Type 0 structure\n"));
+ UpdateStructuresWithNvramType0(&NvramType0, BufferPtr, TempBufferPtr);
+ break;
+ }
+ case 1 : {
+ TRACE((-1, "Updating Type 1 structure\n"));
+ UpdateStructuresWithNvramType1(&NvramType1, BufferPtr, TempBufferPtr);
+ break;
+ }
+ #if BASE_BOARD_INFO
+ case 2 : {
+ TRACE((-1, "Updating Type 2 structure\n"));
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ // Find the NvramType2 entry for the structure by matching the handle number
+ for (i = 0; i < NUMBER_OF_BASEBOARDS; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType2[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType2 array if found,
+ // or just copy the original structure if not found
+ if (i < NUMBER_OF_BASEBOARDS) {
+ UpdateStructuresWithNvramType2(&NvramType2[i], BufferPtr, TempBufferPtr);
+ }
+ else {
+ UpdateStructuresWithNvramType2(NULL, BufferPtr, TempBufferPtr);
+ }
+ }
+ break;
+ }
+ #endif // BASE_BOARD_INFO
+ #if SYS_CHASSIS_INFO
+ case 3 : {
+ TRACE((-1, "Updating Type 3 structure\n"));
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ StrTableInstance = GetInstanceByTypeHandle(3, ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle);
+
+ // Find the NvramType3 entry for the structure by matching the handle number
+ for (i = 0; i < NUMBER_OF_SYSTEM_CHASSIS; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType3[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType3 array if found,
+ // or just copy the original structure if not found
+ if (i < NUMBER_OF_SYSTEM_CHASSIS) {
+ UpdateStructuresWithNvramType3(&NvramType3[i], BufferPtr, TempBufferPtr, StrTableInstance);
+ }
+ else {
+ UpdateStructuresWithNvramType3(NULL, BufferPtr, TempBufferPtr, StrTableInstance);
+ }
+ }
+ break;
+ }
+ #endif // SYS_CHASSIS_INFO
+ #if ( defined(PROCESSOR_DMIEDIT_SUPPORT) && (PROCESSOR_DMIEDIT_SUPPORT == 1) )
+ case 4 : {
+ TRACE((-1, "Updating Type 4 structure\n"));
+ if (gSmbiosBoardProtocol->ProcessorDmiEditSupport) {
+ UpdateStructuresWithNvramType4(&NvramType4, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // PROCESSOR_DMIEDIT_SUPPORT
+ #if OEM_STRING_INFO
+ case 11 : {
+ TRACE((-1, "Updating Type 11 structure\n"));
+ if (gSmbiosBoardProtocol->OemStringInfoSupport) {
+ UpdateStructuresWithNvramType11(&NvramType11, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // OEM_STRING_INFO
+ #if SYSTEM_CONFIG_OPTION_INFO
+ case 12 : {
+ TRACE((-1, "Updating Type 12 structure\n"));
+ if (gSmbiosBoardProtocol->SystemConfigOptionInfoSupport) {
+ UpdateStructuresWithNvramType12(&NvramType12, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // SYSTEM_CONFIG_OPTION_INFO
+ #if PORTABLE_BATTERY_INFO
+ case 22: {
+ TRACE((-1, "Updating Type 22 structure\n"));
+ // Find the NvramType22 entry for the structure by matching the handle number
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType22[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType22 array if found,
+ // or just copy the original structure if not found
+ if (i < gSmbiosBoardProtocol->NumberOfBatteries) {
+ UpdateStructuresWithNvramType22(&NvramType22[i], BufferPtr, TempBufferPtr);
+ }
+ else {
+ UpdateStructuresWithNvramType22(NULL, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // PORTABLE_BATTERY_INFO
+ #if SYSTEM_POWER_SUPPLY_INFO
+ case 39: {
+ TRACE((-1, "Updating Type 39 structure\n"));
+ // Find the NvramType39 entry for the structure by matching the handle number
+ for (i = 0; i < NUMBER_OF_POWER_SUPPLY; i++) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle == NvramType39[i].Handle) break;
+ }
+ // Update the structure with the data in NvramType39 array if found,
+ // or just copy the original structure if not found
+ if (i < NUMBER_OF_POWER_SUPPLY) {
+ UpdateStructuresWithNvramType39(&NvramType39[i], BufferPtr, TempBufferPtr);
+ }
+ else {
+ UpdateStructuresWithNvramType39(NULL, BufferPtr, TempBufferPtr);
+ }
+ break;
+ }
+ #endif // SYSTEM_POWER_SUPPLY_INFO
+ default : {
+ StructureSize = GetStructureLength(BufferPtr);
+ MemCpy(TempBufferPtr, BufferPtr, StructureSize);
+ }
+ }
+ BufferPtr += GetStructureLength(BufferPtr);
+ TempBufferPtr += GetStructureLength(TempBufferPtr);
+ } while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127);
+
+ // Copy Type 127
+ StructureSize = GetStructureLength(BufferPtr);
+ MemCpy(TempBufferPtr, BufferPtr, StructureSize);
+
+ TRACE((-1, "Replace all DMI data with TempBuffer\n"));
+ // Replace all DMI data with TempBuffer
+ MemCpy(Buffer, TempBuffer, BufferSize);
+
+ pBS->FreePool(TempBuffer);
+ }
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ pBS->FreePool(FlashData);
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+ Status = EFI_SUCCESS;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+Function_Exit:
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+#if (TYPE2_STRUCTURE == 1)
+ pBS->FreePool(Type2Handle);
+ pBS->FreePool(NvramType2);
+#endif // TYPE2_STRUCTURE
+#if (TYPE3_STRUCTURE == 1)
+ pBS->FreePool(Type3Handle);
+ pBS->FreePool(NvramType3);
+#endif // TYPE3_STRUCTURE
+ pBS->FreePool(Type22Handle);
+ pBS->FreePool(NvramType22);
+ pBS->FreePool(Type39Handle);
+ pBS->FreePool(NvramType39);
+
+ TRACE((-1, "::: SMBIOS - Exit UpdateStructuresWithNvramData. Status = %r :::\n", Status));
+
+ return Status;
+}
+#endif
+
+#if UPDATE_BASEBOARD_TYPE2
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicBaseBoardData
+//
+// Description: Updates base board structure (Type 2) in input Buffer with
+// dynamically detected data.
+//
+// Input: UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateBaseBoardData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT16 StructureHandle;
+ UINT8 *TempStructure2;
+ UINTN TempStructure2Size;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateBaseBoardData ***\n"));
+
+ SmbiosVariableSize = sizeof(BASE_BOARD_DATA);
+
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ SmbiosVariableSize,
+ &SmbiosVariableBuffer);
+
+ Status = pRS->GetVariable(
+ SmbiosBaseBoardVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosBaseBoardVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+
+ //
+ // Search for Type 2 (Base Board) structure pointer
+ //
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 2, 1)) {
+
+ TempStructure2Size = (UINTN)(sizeof(SMBIOS_BASE_BOARD_INFO) + 6*65 + 1);
+ pBS->AllocatePool(EfiBootServicesData,
+ TempStructure2Size,
+ &TempStructure2);
+
+ StructureHandle = ((SMBIOS_STRUCTURE_HEADER*)StructureFoundPtr)->Handle;
+ MemCpy(TempStructure2, StructureFoundPtr, GetStructureLength(StructureFoundPtr));
+
+#if UPDATE_BOARD_MANUFACTURER
+ //
+ // Update Board Manufacturer Name
+ //
+ ReplaceString(TempStructure2, 1, (UINT8*)((BASE_BOARD_DATA*)SmbiosVariableBuffer)->BoardManufacturer);
+#endif // UPDATE_BOARD_MANUFACTURER
+#if UPDATE_BOARD_NAME
+ //
+ // Update Board Name String corresponding to Board ID.
+ //
+ ReplaceString(TempStructure2, 2, (UINT8*)((BASE_BOARD_DATA*)SmbiosVariableBuffer)->BoardName);
+#endif // UPDATE_BOARD_NAME
+ //
+ // Add Structure to the table
+ //
+ WriteStructureByHandle(StructureHandle, TempStructure2, GetStructureLength(TempStructure2));
+
+ pBS->FreePool(TempStructure2);
+ }
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateBaseBoardData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_BASEBOARD_TYPE2
+
+#if UPDATE_SYSTEM_CHASSIS_TYPE3
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateChassisData
+//
+// Description: Updates Chassis structure (Type 3) in input Buffer with
+// dynamically detected data.
+//
+// Input: UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateChassisData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateChassisData ***\n"));
+
+ SmbiosVariableSize = sizeof(CHASSIS_DATA);
+
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ SmbiosVariableSize,
+ &SmbiosVariableBuffer);
+
+ Status = pRS->GetVariable(
+ SmbiosChassisVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosChassisVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 3, 1)) {
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructureFoundPtr)->Type = ((CHASSIS_DATA*)SmbiosVariableBuffer)->Type;
+ }
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateChassisData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_SYSTEM_CHASSIS_TYPE3
+
+#if UPDATE_CPU_TYPE4
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateCpuData
+//
+// Description: Updates CPU structures (Type 4 & 7) in input Buffer with
+// dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: If SMBIOS_CPU_INFO_PROTOCOL is not found, this function tries to
+// use the "CPU_DATA" variable (backward compatibility). Otherwise
+// CPU dynamic information is not available.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateCpuData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT8 UseVariable = FALSE;
+ UINT8 i;
+ UINT8 *SrcBuffer = Buffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINTN Size;
+ EFI_GUID gSmbiosCpuInfoGuid = AMI_SMBIOS_CPU_INFO_PROTOCOL_GUID;
+ SMBIOS_CPU_INFO_PROTOCOL *SmbiosCpuInfo;
+ SMBIOS_PROCESSOR_INFO *CurCpu;
+ SMBIOS_CACHE_INFO *CurCache;
+ SINGLE_CPU_DATA *DynamicData;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateCpuData ***\n"));
+
+ Status = pBS->LocateProtocol(&gSmbiosCpuInfoGuid, NULL, (void**)&SmbiosCpuInfo);
+ if (EFI_ERROR(Status)) {
+ UseVariable = TRUE,
+ Size = sizeof(CPU_DYNAMIC_DATA);
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ Size,
+ (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(
+ SmbiosCpuVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &Size,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosCpuVar\n"));
+ return Status;
+ }
+ }
+
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfCPU; i++) {
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 4, 1)) {
+ Size = GetStructureLength(StructureFoundPtr);
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ Size + 1024, // 1K additional buffer
+ (void**)&CurCpu);
+
+ if (Status == EFI_SUCCESS) {
+ UINT16 *L3HandlePtr;
+
+ MemCpy(CurCpu, StructureFoundPtr, Size);
+ if (UseVariable)
+ DynamicData =
+ &((CPU_DYNAMIC_DATA*)SmbiosVariableBuffer)->CpuData[i];
+ else
+ DynamicData = &SmbiosCpuInfo->CpuData[i];
+
+ CurCpu->Family = DynamicData->CpuData.Family;
+ CurCpu->ProcessorID_1 = DynamicData->CpuData.ProcessorID_1;
+ CurCpu->ProcessorID_2 = DynamicData->CpuData.ProcessorID_2;
+ CurCpu->Voltage = DynamicData->CpuData.Voltage | BIT07;
+ CurCpu->ExtClockFreq = DynamicData->CpuData.ExtClockFreq;
+ CurCpu->MaxSpeed = DynamicData->CpuData.MaxSpeed;
+ CurCpu->CurrentSpeed = DynamicData->CpuData.CurrentSpeed;
+ CurCpu->Status = DynamicData->CpuData.Status;
+ CurCpu->Upgrade = DynamicData->CpuData.Upgrade;
+ CurCpu->CoreCount = DynamicData->CpuData.CoreCount;
+ CurCpu->CoreEnabled = DynamicData->CpuData.CoreEnabled;
+ CurCpu->ThreadCount = DynamicData->CpuData.ThreadCount;
+ CurCpu->Family2 = DynamicData->CpuData.Family2;
+
+ L3HandlePtr = &CurCpu->L3CacheHandle;
+
+ ReplaceString((UINT8*)CurCpu, 2, DynamicData->CpuData.Manufacturer);
+ ReplaceString((UINT8*)CurCpu, 3, DynamicData->CpuData.Version);
+
+ if (DynamicData->CpuData.Status & 0x040) {
+ // L1 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->CacheConfig = DynamicData->L1Cache.CacheConfig;
+ CurCache->MaxCacheSize = DynamicData->L1Cache.MaxCacheSize;
+ CurCache->InstalledSize = DynamicData->L1Cache.InstalledSize;
+ CurCache->SupportSRAM = DynamicData->L1Cache.SupportSRAM;
+ CurCache->CurrentSRAM = DynamicData->L1Cache.CurrentSRAM;
+ CurCache->CacheSpeed = DynamicData->L1Cache.CacheSpeed;
+ CurCache->ErrorCorrectionType =
+ DynamicData->L1Cache.ErrorCorrectionType;
+ CurCache->SystemCacheType = DynamicData->L1Cache.SystemCacheType;
+ CurCache->Associativity = DynamicData->L1Cache.Associativity;
+
+ // L2 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->CacheConfig = DynamicData->L2Cache.CacheConfig;
+ CurCache->MaxCacheSize = DynamicData->L2Cache.MaxCacheSize;
+ CurCache->InstalledSize = DynamicData->L2Cache.InstalledSize;
+ CurCache->SupportSRAM = DynamicData->L2Cache.SupportSRAM;
+ CurCache->CurrentSRAM = DynamicData->L2Cache.CurrentSRAM;
+ CurCache->CacheSpeed = DynamicData->L2Cache.CacheSpeed;
+ CurCache->ErrorCorrectionType =
+ DynamicData->L2Cache.ErrorCorrectionType;
+ CurCache->SystemCacheType = DynamicData->L2Cache.SystemCacheType;
+ CurCache->Associativity = DynamicData->L2Cache.Associativity;
+
+ // L3 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+
+ // Hide structure if L3 cache size is 0
+ if (DynamicData->L3Cache.InstalledSize == 0) {
+ CurCache->StructureType.Type = 126;
+ *L3HandlePtr = 0xffff;
+ }
+ else {
+ CurCache->CacheConfig = DynamicData->L3Cache.CacheConfig;
+ CurCache->MaxCacheSize = DynamicData->L3Cache.MaxCacheSize;
+ CurCache->InstalledSize = DynamicData->L3Cache.InstalledSize;
+ CurCache->SupportSRAM = DynamicData->L3Cache.SupportSRAM;
+ CurCache->CurrentSRAM = DynamicData->L3Cache.CurrentSRAM;
+ CurCache->CacheSpeed = DynamicData->L3Cache.CacheSpeed;
+ CurCache->ErrorCorrectionType =
+ DynamicData->L3Cache.ErrorCorrectionType;
+ CurCache->SystemCacheType =
+ DynamicData->L3Cache.SystemCacheType;
+ CurCache->Associativity = DynamicData->L3Cache.Associativity;
+ }
+ }
+ }
+ }
+ }
+
+ // L1 Cache
+ else if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->StructureType.Type = 126;
+
+ // L2 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->StructureType.Type = 126;
+
+ // L3 Cache
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 7, 1)) {
+ CurCache = (SMBIOS_CACHE_INFO*)StructureFoundPtr;
+ CurCache->StructureType.Type = 126;
+ }
+ }
+ }
+
+ WriteStructureByHandle(((SMBIOS_STRUCTURE_HEADER*)CurCpu)->Handle,
+ (UINT8*)CurCpu,
+ GetStructureLength((UINT8*)CurCpu)
+ );
+
+ pBS->FreePool(CurCpu);
+ }
+ }
+ }
+
+ if (UseVariable)
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateCpuData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_CPU_TYPE4
+
+#if UPDATE_SLOT_TYPE9
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateSlotsData
+//
+// Description: Updates System Slot structure (Type 9) in input Buffer with
+// dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateSlotsData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateSlotsData ***\n"));
+
+ SmbiosVariableSize = sizeof(SYSTEM_SLOT_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData, SmbiosVariableSize, (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(SmbiosSlotsVar, &gEfiSmbiosDynamicData,
+ &Attributes, &SmbiosVariableSize, SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosSlotsVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfSystemSlots; i++) {
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 9, 1)) {
+ ((SMBIOS_SYSTEM_SLOTS_INFO*)StructureFoundPtr)->CurrentUsage = ((SYSTEM_SLOT_DYNAMIC_DATA*)SmbiosVariableBuffer)->CurrentUsage[i];
+ ((SMBIOS_SYSTEM_SLOTS_INFO*)StructureFoundPtr)->BusNumber = ((SYSTEM_SLOT_DYNAMIC_DATA*)SmbiosVariableBuffer)->BusNumber[i];
+ }
+ }
+ }
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateSlotsData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_SLOT_TYPE9
+
+#if UPDATE_ONBOARD_DEV_TYPE10
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateOnboardDevData
+//
+// Description: Updates On Board Devices Information structure (Type 10) in
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateOnboardDevData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateOnboardDevData ***\n"));
+
+ SmbiosVariableSize = sizeof(ONBOARD_DEV_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData, SmbiosVariableSize, (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(SmbiosOnBoardVar, &gEfiSmbiosDynamicData,
+ &Attributes, &SmbiosVariableSize, SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosOnBoardVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 10, 1)) {
+ StructureFoundPtr += 4;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfOnBoardDevices; i++) {
+ ((SINGLE_DEV_INFO*)StructureFoundPtr)->DeviceType &= 0x7f;
+ ((SINGLE_DEV_INFO*)StructureFoundPtr)->DeviceType |= ((ONBOARD_DEV_DYNAMIC_DATA*)SmbiosVariableBuffer)->OnBoardDev[i];
+
+ StructureFoundPtr += 2;
+ }
+ }
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateOnboardDevData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif // UPDATE_ONBOARD_DEV_TYPE10
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSerialNumber
+//
+// Description: Update Type 17 Serial Number field for the input memory slot
+// with data obtained from the SPD.
+//
+// Input: IN UINT8 *StructureBuffer
+// IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: EFI_STATUS
+//
+// Modified: Type 17 Serial Number field
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateSerialNumber (
+ IN UINT8 *StructBuffer,
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr,
+ IN MEM_SPD_DATA *SpdData
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINT8 Data8;
+ UINTN SpdOffset;
+ UINT8 Ascii;
+
+ StructBuffer += ((SMBIOS_STRUCTURE_HEADER*)StructBuffer)->Length;
+ StructBuffer += GetStringOffset(StructBuffer, 4);
+
+ if (MemType == 0) return EFI_UNSUPPORTED; // Not supported
+ if (MemType == 1) SpdOffset = 0x5f;
+ if (MemType == 2) SpdOffset = 122;
+ if (MemType == 3) SpdOffset = 325;
+
+ for (i = 0; i < 4; i++) {
+ if (SpdData) {
+ if (SpdOffset == 95) { // 0x5f
+ Data8 = SpdData->Byte95To98[95 + i - 95];
+ }
+ else if (SpdOffset == 122){
+ Data8 = SpdData->Byte122To125[122 + i - 122];
+ }
+ else {
+ Data8 = SpdData->Byte325To328[325 + i - 325];
+ }
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, SpdOffset + i, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+
+ if (*StructBuffer == 0) return EFI_BUFFER_TOO_SMALL; // Truncate if string is too long
+ Ascii = (Data8 >> 4);
+ if (Ascii > 9) *StructBuffer++ = Ascii - 10 + 0x41;
+ else *StructBuffer++ = Ascii + 0x30;
+ if (*StructBuffer == 0) return EFI_BUFFER_TOO_SMALL; // Truncate if string is too long
+ Ascii = Data8 & 15;
+ if (Ascii > 9) *StructBuffer++ = Ascii - 10 + 0x41;
+ else *StructBuffer++ = Ascii + 0x30;
+ }
+
+ while (*StructBuffer != 0) *StructBuffer++ = 0x20;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FilterCharacter
+//
+// Description: If input character is in the range of 0x20 to 0x7e (readable
+// character), returns the input character value unchanged.
+// Otherwise returns single space character.
+//
+// Input: IN CHAR8 _char
+//
+// Output: CHAR8
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+CHAR8
+FilterCharacter (
+ IN CHAR8 _char
+)
+{
+ if( (_char >= 0x20 && _char <= 0x7E) ){
+ return _char;
+ }
+
+ return ' ';
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdatePartNumber
+//
+// Description: Update Type 17 Part Number field for the input memory slot
+// with data obtained from the SPD.
+//
+// Input: IN UINT8 *StructBuffer
+// IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: EFI_STATUS
+//
+// Modified: Type 17 Part Number field
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdatePartNumber (
+ IN UINT8 *StructBuffer,
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr,
+ IN MEM_SPD_DATA *SpdData
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINT8 Data8;
+ UINTN SpdOffset;
+
+ StructBuffer += ((SMBIOS_STRUCTURE_HEADER*)StructBuffer)->Length;
+ StructBuffer += GetStringOffset(StructBuffer, 6);
+
+ if (MemType == 0) return EFI_UNSUPPORTED; // Not supported
+ if (MemType == 1) SpdOffset = 0x49;
+ if (MemType == 2) SpdOffset = 128;
+ if (MemType == 3) SpdOffset = 329;
+
+ for (i = 0; i < 18; i++) {
+ if (SpdData) {
+ if (SpdOffset == 73) { // 0x49
+ Data8 = SpdData->Byte73To90[73 + i - 73];
+ }
+ else if (SpdOffset == 128){
+ Data8 = SpdData->Byte128To145[128 + i - 128];
+ }
+ else {
+ Data8 = SpdData->Byte329To348[329 + i - 329];
+ }
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, SpdOffset + i, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (*StructBuffer == 0) return EFI_BUFFER_TOO_SMALL;
+ if (Data8 == 0) Data8 = 0x20;
+ *StructBuffer++ = FilterCharacter(Data8);
+ }
+
+ while (*StructBuffer != 0) *StructBuffer++ = 0x20;
+
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+ValidateStringNumber(
+ IN UINT8 *StructurePtr,
+ IN UINT8 StructureType,
+ IN UINTN StringNumber
+)
+{
+ if (StructureType == 11 || StructureType == 12) {
+ return (*(StructurePtr + sizeof(SMBIOS_STRUCTURE_HEADER)) >= StringNumber);
+ }
+ else {
+ STRING_TABLE *StringTablePtr;
+
+ StringTablePtr = (STRING_TABLE*)GetTypeTable(StructureType);
+
+ if (StringTablePtr) {
+ while ((StringTablePtr->Offset != 0xff) && --StringNumber) ++StringTablePtr;
+
+ return (StringTablePtr->Offset != 0xff);
+ }
+ else {
+ return FALSE;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReplaceString
+//
+// Description: Replace the #StringNum in the input buffer *DestStructPtr
+// with StringData
+//
+// Input: IN UINT8 *DestStructPtr Pointer to structure to be updated
+// IN UINT8 StringNum String number (1 based)
+// IN UINT8 *StringData String with NULL terminated character
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReplaceString(
+ IN UINT8 *DestStructPtr,
+ IN UINT8 StringNum,
+ IN UINT8 *StringData
+)
+{
+ UINT8 StringSize = 0;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ if (FindString(&DestStructPtr, StringNum)) {
+ UINT8 *TempPtr;
+ UINT8 *NextStrPtr;
+
+ NextStrPtr = DestStructPtr;
+ StructEndPtr = DestStructPtr;
+
+ while(*NextStrPtr != 0) {
+ NextStrPtr++;
+ }
+
+ // NextStrPtr = Pointer to the next string
+ NextStrPtr++;
+
+ while(*(UINT16*)StructEndPtr != 0) {
+ StructEndPtr++;
+ }
+
+ RemainingSize = StructEndPtr + 2 - NextStrPtr; // Including double NULL characters
+
+ TempPtr = StringData;
+ while (*(TempPtr++) != 0) {
+ StringSize++;
+ }
+ StringSize++; // Including NULL character
+
+ // Copy remaining strings
+ MemCpy(DestStructPtr + StringSize, NextStrPtr, RemainingSize);
+
+ // Copy the string
+ MemCpy(DestStructPtr, StringData, StringSize);
+
+ return EFI_SUCCESS;
+ }
+ else {
+ // String not found
+ return EFI_NOT_FOUND;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateManufacturer
+//
+// Description: Update Type 17 Manufacturer field for the input memory slot
+// with data obtained from the SPD.
+//
+// Input: IN UINT8 *structBuffer
+// IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: EFI_STATUS
+//
+// Modified: Type 17 Manufacturer field
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateManufacturer(
+ IN UINT8 *StructBuffer,
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr,
+ IN MEM_SPD_DATA *SpdData
+)
+{
+ EFI_STATUS Status;
+ UINTN i;
+ UINT8 Data8;
+ UINT8 Index;
+ JEDEC_MF_ID *IdTblPtr = NULL;
+
+ switch (MemType) {
+ case 1: for (i = 0; i < 8; i++) { // DDR2
+ if (SpdData) {
+ Data8 = SpdData->Byte64To71[64 + i - 64];
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 64 + i, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ if (Data8 != 0x7f) break;
+ }
+ break;
+ case 2: if (SpdData) { // DDR3
+ i = SpdData->Byte117To118[117 - 117] & 0x7f; // Remove parity bit
+ Data8 = SpdData->Byte117To118[118 - 117];
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 117, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ i = Data8 & 0x7f; // Remove parity bit
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 118, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ break;
+ case 3: if (SpdData) { // DDR4
+ i = SpdData->Byte320To321[320 - 320] & 0x7f; // Remove parity bit
+ Data8 = SpdData->Byte320To321[321 - 320];
+ }
+ else {
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 320, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ i = Data8 & 0x7f; // Remove parity bit
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 321, &Data8);
+ if (EFI_ERROR(Status)) return Status;
+ }
+ break;
+ default: return EFI_UNSUPPORTED; // Not supported
+ }
+
+ if (i > 7) i = 7;
+ IdTblPtr = ManufacturerJedecIdBankTable[i];
+
+ // Search in Manufacturer table
+ while ((IdTblPtr->VendorId != Data8) && (IdTblPtr->VendorId != 0xff)) {
+ IdTblPtr++;
+ }
+
+ if (IdTblPtr->VendorId != 0xff) {
+ Status = ReplaceString(StructBuffer, 3, IdTblPtr->ManufacturerString);
+ }
+ else {
+ Index = 0;
+ Status = EFI_NOT_FOUND;
+ while (Strcmp(ManufacturerTable[Index].Manufacturer, "Undefined")) {
+ if (i == ManufacturerTable[Index].NumContCode && Data8 == ManufacturerTable[Index].ModuleManufacturer) {
+ Status = ReplaceString(StructBuffer, 3, ManufacturerTable[Index].Manufacturer);
+ break;
+ }
+
+ Index++;
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetMemoryType
+//
+// Description: Detect memory device type from SPD data.
+// Only DDR2 and DDR3 are supported
+//
+// Input: IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+//
+// Output: UINT8
+// 0 -> Memory type not supported
+// 1 -> DDR2
+// 2 -> DDR3
+//
+// Modified: MemType = memory type (Global variable)
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetMemoryType(
+ IN EFI_SMBUS_DEVICE_ADDRESS SpdSmBusAddr
+)
+{
+ EFI_STATUS Status;
+ UINT8 Data8;
+
+ MemType = 0; // Not supported
+
+ Status = gSmbiosBoardProtocol->GetSpdByte(SpdSmBusAddr, 2, &Data8);
+ if (!EFI_ERROR(Status)) {
+ if (Data8 == 8) MemType = 1; // DDR2
+ if (Data8 == 11) MemType = 2; // DDR3
+ if (Data8 == 12) MemType = 3; // DDR4
+ }
+
+ return MemType;
+}
+
+#if UPDATE_MEMORY_TYPE16
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateMemoryData
+//
+// Description: Updates Memory related structures (Type 16-20) in
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateMemoryData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 i;
+ UINT8 j;
+ UINT8 Data8;
+ UINT8 MemErrorCorrection;
+ UINTN SmbiosVariableSize = sizeof(SYSTEM_MEM_ARRAY_DYNAMIC_DATA);
+ SYSTEM_MEM_ARRAY_DYNAMIC_DATA *SmbiosVariableBuffer;
+ SMBIOS_PHYSICAL_MEM_ARRAY_INFO *SmbArray;
+ SMBIOS_MEMORY_DEVICE_INFO *SmbDevice;
+#if MEMORY_ERROR_INFO
+ SMBIOS_MEMORY_ERROR_INFO *SmbError;
+#endif
+ SMBIOS_MEM_ARRAY_MAP_ADDR_INFO *SmbAmap;
+#if MEMORY_DEVICE_INFO
+ SMBIOS_MEM_DEV_MAP_ADDR_INFO *SmbDmap;
+#endif
+ PHYSICAL_MEM_ARRAY *DynArray;
+ MEMORY_DEVICE_GROUP *DynDevice;
+ UINT8 DataWidth[] = {8, 16, 32, 64};
+ EFI_SMBUS_DEVICE_ADDRESS DummyAddr;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_GUID SpdInfoHobGuid = AMI_SMBIOS_MEMORY_INFO_HOB_GUID;
+ VOID *pHobList;
+ MEM_SPD_DATA *SpdDataPtr;
+ UINT8 *TempBuffer;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateMemoryData ***\n"));
+
+ pBS->AllocatePool(EfiBootServicesData,
+ SmbiosVariableSize,
+ (void**)&SmbiosVariableBuffer);
+
+ pBS->AllocatePool(EfiBootServicesData,
+ 0x200,
+ (void**)&TempBuffer);
+
+ MemSet(TempBuffer, 0x200, 0);
+
+ Status = pRS->GetVariable(SmbiosMemVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+ if (EFI_ERROR(Status)) {
+ pBS->FreePool(SmbiosVariableBuffer);
+ if (Status == EFI_NOT_FOUND)
+ return EFI_SUCCESS;
+ return Status;
+ }
+
+ pHobList = GetEfiConfigurationTable(pST, &HobListGuid);
+ if (pHobList != NULL) {
+ Status = FindNextHobByGuid(&SpdInfoHobGuid, &pHobList);
+ if (EFI_ERROR(Status)) {
+ pHobList = NULL; // Smbios Memory Info Hob not found
+ }
+ else {
+ SpdDataPtr = (MEM_SPD_DATA*)((UINTN)pHobList + sizeof(EFI_HOB_GUID_TYPE));
+ }
+ }
+
+ SrcBuffer = Buffer;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfPhysicalMemoryArray; i++)
+ {
+ // Update Type 16
+ if (FindStructureType(&SrcBuffer,
+ &StructureFoundPtr,
+ 16,
+ 1)) {
+ SmbArray = ((SMBIOS_PHYSICAL_MEM_ARRAY_INFO*)StructureFoundPtr);
+ DynArray = &(SmbiosVariableBuffer->PhysicalMemArray[i]);
+ SmbArray->MaxCapacity = DynArray->MaxCapacity;
+ SmbArray->ExtMaxCapacity = DynArray->ExtMaxCapacity;
+ MemErrorCorrection = 0x06; // Assume Multi-bit ECC
+
+ // Update Type 18
+ #if MEMORY_ERROR_INFO
+ if (gSmbiosBoardProtocol->MemoryErrorInfoSupport) {
+ if (DynArray->ArrayMemoryError.ErrorType == 3) {
+ SmbArray->MemErrInfoHandle = 0xffff; // No error
+ }
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 18, 1)) {
+ SmbError = (SMBIOS_MEMORY_ERROR_INFO*)StructureFoundPtr;
+ SmbError->ErrorType = DynArray->ArrayMemoryError.ErrorType;
+ SmbError->ErrorGranularity = DynArray->ArrayMemoryError.ErrorGranularity;
+ SmbError->ErrorOperation = DynArray->ArrayMemoryError.ErrorOperation;
+ SmbError->MemArrayErrorAddress = DynArray->ArrayMemoryError.MemArrayErrorAddress;
+ SmbError->DeviceErrorAddress = DynArray->ArrayMemoryError.DeviceErrorAddress;
+ SmbError->ErrorResolution = DynArray->ArrayMemoryError.ErrorResolution;
+
+ if (DynArray->ArrayMemoryError.ErrorType != 3) {
+ // Update this device's Memory Error Information Handle
+ SmbArray->MemErrInfoHandle = SmbError->StructureType.Handle;
+ }
+ }
+ }
+ #endif
+
+ // Update Type 19
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 19, 1)) {
+ SmbAmap = (SMBIOS_MEM_ARRAY_MAP_ADDR_INFO*)StructureFoundPtr;
+ SmbAmap->StartingAddress = DynArray->MemArrayMapAddr.StartingAddress;
+ SmbAmap->EndingAddress = DynArray->MemArrayMapAddr.EndingAddress;
+ SmbAmap->PartitionWidth = DynArray->MemArrayMapAddr.PartitionWidth;
+ SmbAmap->ExtendedStartAddr = DynArray->MemArrayMapAddr.ExtendedStartAddr;
+ SmbAmap->ExtendedEndAddr = DynArray->MemArrayMapAddr.ExtendedEndAddr;
+ }
+
+ TRACE((-1, "Updating memory slots\n"));
+ for (j = 0; j < gSmbiosBoardProtocol->NumberOfMemorySlots[i]; j++)
+ {
+ // Update Type 17
+ TRACE((-1, "Searching for slot %x structure\n", j+1));
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 17, 1)){
+ TRACE((-1, "Found slot %x structure\n", j+1));
+ SmbDevice = (SMBIOS_MEMORY_DEVICE_INFO*)StructureFoundPtr;
+ DynDevice = &(DynArray->MemoryDeviceData[j]);
+
+ SmbDevice->Size = DynDevice->Type17.Size;
+ SmbDevice->ExtendedSize = DynDevice->Type17.ExtendedSize;
+ SmbDevice->ConfMemClkSpeed = DynDevice->Type17.ConfMemClkSpeed;
+ SmbDevice->TotalWidth = DynDevice->Type17.TotalWidth;
+ SmbDevice->DeviceSet = DynDevice->Type17.DeviceSet;
+ SmbDevice->MinimumVoltage = DynDevice->Type17.MinimumVoltage;
+ SmbDevice->MaximumVoltage = DynDevice->Type17.MaximumVoltage;
+ SmbDevice->ConfiguredVoltage = DynDevice->Type17.ConfiguredVoltage;
+ if (DynDevice->Type17.TypeDetail != 0) {
+ SmbDevice->TypeDetail = DynDevice->Type17.TypeDetail;
+ }
+ if (SmbDevice->Size == 0) {
+ TRACE((-1, "Slot %x is empty\n", j+1));
+ SmbDevice->MemoryType = 2; // Set to Unknown if slot empty
+ SmbDevice->Speed = 0;
+ SmbDevice->Attributes = 0;
+ }
+ else {
+ TRACE((-1, "Slot %x populated\n", j+1));
+ SmbDevice->MemoryType = DynDevice->Type17.MemoryType;
+ SmbDevice->Speed = DynDevice->Type17.Speed;
+
+ if (pHobList) {
+ MemType = 0;
+
+ switch (SpdDataPtr->Byte2) {
+ case 0x08: // DDR2
+ MemType = 1;
+ SmbDevice->TotalWidth = SpdDataPtr->Byte5To8[6 - 5];
+ Data8 = SpdDataPtr->Byte11To14[14 - 11];
+ SmbDevice->DataWidth = SmbDevice->TotalWidth - Data8;
+ Data8 = SpdDataPtr->Byte5To8[5 - 5];
+ SmbDevice->Attributes = (Data8 & 0x07) + 1;
+ if (SpdDataPtr->Byte11To14[11 - 11] != 0x02) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ break;
+
+ case 0x0b: // DDR3
+ MemType = 2;
+ Data8 = SpdDataPtr->Byte5To8[8 - 5];
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ Data8 = SpdDataPtr->Byte5To8[7 - 5];
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ break;
+
+ case 0x0c: // DDR4
+ MemType = 3;
+ Data8 = SpdDataPtr->Byte11To14[13 - 11];
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ Data8 = SpdDataPtr->Byte11To14[12 - 11];
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ }
+
+ DummyAddr.SmbusDeviceAddress = 0;
+ MemCpy(TempBuffer, SmbDevice, GetStructureLength((UINT8*)SmbDevice));
+ UpdateManufacturer(TempBuffer, DummyAddr, SpdDataPtr);
+ UpdateSerialNumber(TempBuffer, DummyAddr, SpdDataPtr);
+ UpdatePartNumber(TempBuffer, DummyAddr, SpdDataPtr);
+ WriteStructureByHandle(SmbDevice->StructureType.Handle, TempBuffer, GetStructureLength(TempBuffer));
+ }
+ else {
+ switch (GetMemoryType(DynArray->SpdSmBusAddr[j])) {
+ case 0: break;
+
+ case 1: gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 6, &Data8); // DDR2
+ SmbDevice->TotalWidth = Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 14, &Data8);
+ SmbDevice->DataWidth = SmbDevice->TotalWidth - Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 5, &Data8);
+ SmbDevice->Attributes = (Data8 & 0x07) + 1;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 11, &Data8);
+ if (Data8 != 0x02) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ break;
+
+ case 2: gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 8, &Data8); // DDR3
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 7, &Data8);
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ break;
+
+ case 3: gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 13, &Data8); // DDR4
+ SmbDevice->DataWidth = DataWidth[Data8 & 0x07];
+ Data8 = (Data8 & 0x18) ? 8: 0;
+ if (Data8 == 0) {
+ MemErrorCorrection = 0x03; // No ECC
+ }
+ SmbDevice->TotalWidth = SmbDevice->DataWidth + Data8;
+ gSmbiosBoardProtocol->GetSpdByte(DynArray->SpdSmBusAddr[j], 12, &Data8);
+ SmbDevice->Attributes = ((Data8 >> 3) & 0x07) + 1;
+ }
+
+ if (GetMemoryType(DynArray->SpdSmBusAddr[j]) != 0) {
+ MemCpy(TempBuffer, SmbDevice, GetStructureLength((UINT8*)SmbDevice));
+ UpdateManufacturer(TempBuffer, DynArray->SpdSmBusAddr[j], 0);
+ UpdateSerialNumber(TempBuffer, DynArray->SpdSmBusAddr[j], 0);
+ UpdatePartNumber(TempBuffer, DynArray->SpdSmBusAddr[j], 0);
+ WriteStructureByHandle(SmbDevice->StructureType.Handle, TempBuffer, GetStructureLength(TempBuffer));
+ }
+ }
+ }
+
+ // Update Type 18
+ #if MEMORY_ERROR_INFO
+ if (gSmbiosBoardProtocol->MemoryErrorInfoSupport) {
+ if (DynDevice->Type18.ErrorType == 3) {
+ SmbDevice->MemErrorInfoHandle = 0xffff; // No error
+ }
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 18, 1)) {
+ SmbError = (SMBIOS_MEMORY_ERROR_INFO*)StructureFoundPtr;
+ SmbError->ErrorType = DynDevice->Type18.ErrorType;
+ SmbError->ErrorGranularity = DynDevice->Type18.ErrorGranularity;
+ SmbError->ErrorOperation = DynDevice->Type18.ErrorOperation;
+ SmbError->MemArrayErrorAddress = DynDevice->Type18.MemArrayErrorAddress;
+ SmbError->DeviceErrorAddress = DynDevice->Type18.DeviceErrorAddress;
+ SmbError->ErrorResolution = DynDevice->Type18.ErrorResolution;
+
+ if (DynDevice->Type18.ErrorType != 3) {
+ // Update this device's Memory Error Information Handle
+ SmbDevice->MemErrorInfoHandle = SmbError->StructureType.Handle;
+ }
+ }
+ }
+ #endif
+
+ // Update Type 20
+ #if MEMORY_DEVICE_INFO
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 20, 1)) {
+ SmbDmap = (SMBIOS_MEM_DEV_MAP_ADDR_INFO*)StructureFoundPtr;
+ if (SmbDevice->Size) {
+ SmbDmap->StartingAddress = DynDevice->Type20.StartingAddress;
+ SmbDmap->EndingAddress = DynDevice->Type20.EndingAddress;
+ SmbDmap->PartitionRowPosition = DynDevice->Type20.PartitionRowPosition;
+ SmbDmap->InterleavePosition = DynDevice->Type20.InterleavePosition;
+ SmbDmap->InterleaveDataDepth = DynDevice->Type20.InterleaveDataDepth;
+ SmbDmap->ExtendedStartAddr = DynDevice->Type20.ExtendedStartAddr;
+ SmbDmap->ExtendedEndAddr = DynDevice->Type20.ExtendedEndAddr;
+ }
+ else {
+ SmbDmap->StructureType.Type = 126;
+ }
+ }
+ #endif
+ }
+
+ SpdDataPtr++;
+ }
+
+ SmbArray->MemErrorCorrection = MemErrorCorrection;
+ }
+ }
+
+ pBS->FreePool(TempBuffer);
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateMemoryData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
+#if FLASH_MEMORY_ARRAY_INFO && defined(FLASH_PART_STRING_LENGTH)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateFlashMemoryData
+//
+// Description: Updates Flash Memory related structures (Type 16-20)
+// with dynamically detected data.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateFlashMemoryData(VOID)
+{
+ UINT32 Flash4GBMapStart;
+ UINT8 FlashInfo[0x100];
+ char *Manufacturer = NULL;
+ char *PartNumber;
+ UINT8 *Buffer;
+ UINT8 *FlashMemoryStructurePtr;
+ EFI_SMBIOS_HANDLE SmbiosHandle;
+ UINTN StringNumber;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateFlashMemoryData ***\n"));
+
+ Flash4GBMapStart = 0xFFFFFFFF - FLASH_BLOCK_SIZE;
+ Flash4GBMapStart ++;
+ GetFlashPartInfomation ( (UINT8*)Flash4GBMapStart, FlashInfo );
+
+ Manufacturer = FlashInfo + 8; // Skip "$FPS" signature and size
+ PartNumber = Strstr(Manufacturer, " ");
+ // Replace " " with string terminator for Manufacturer
+ *PartNumber++ = 0;
+
+ Buffer = SmbiosDataTable;
+
+ // Search for Flash Memory structure
+ while (1) {
+ FindStructureType(&Buffer, &FlashMemoryStructurePtr, 17, 1);
+ if (FlashMemoryStructurePtr == NULL) {
+ break;
+ }
+ else {
+ if (((SMBIOS_MEMORY_DEVICE_INFO*)FlashMemoryStructurePtr)->MemoryType == 9) {
+ break;
+ }
+ }
+ };
+
+ if (FlashMemoryStructurePtr != NULL) {
+ SmbiosHandle = ((SMBIOS_STRUCTURE_HEADER*)FlashMemoryStructurePtr)->Handle;
+ StringNumber = 3;
+ SmbiosPiUpdateString(NULL, &SmbiosHandle, &StringNumber, Manufacturer);
+ StringNumber = 6;
+ SmbiosPiUpdateString(NULL, &SmbiosHandle, &StringNumber, PartNumber);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateFlashMemoryData :::\n"));
+ return EFI_SUCCESS;
+ }
+
+ TRACE((-1, "Flash Memory Structure not found\n"));
+ return EFI_NOT_FOUND;
+}
+#endif
+
+#if UPDATE_BATTERY_TYPE22
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateBatteryData
+//
+// Description: Updates Portable Battery structures (Type 22) in
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateBatteryData(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT16 StructureHandle;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 i;
+ UINT8 *TempStructure22;
+ UINTN TempStructure22Size;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateBatteryData ***\n"));
+
+ SmbiosVariableSize = sizeof(BATTERY_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData,
+ SmbiosVariableSize,
+ &SmbiosVariableBuffer);
+
+ Status = pRS->GetVariable(SmbiosBatteryVar,
+ &gEfiSmbiosDynamicData,
+ &Attributes,
+ &SmbiosVariableSize,
+ SmbiosVariableBuffer);
+
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosBatteryVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ TempStructure22Size = sizeof(SMBIOS_PORTABLE_BATTERY_INFO) + (7 * 65) + 1;
+ pBS->AllocatePool(EfiBootServicesData,
+ TempStructure22Size,
+ &TempStructure22);
+
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfBatteries; i++) {
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 22, i + 1)) {
+ StructureHandle = ((SMBIOS_STRUCTURE_HEADER*)StructureFoundPtr)->Handle;
+ if(((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].Valid){
+ MemCpy(TempStructure22,
+ StructureFoundPtr,
+ GetStructureLength(StructureFoundPtr));
+
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->DesignCapacity =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DesignCapacity;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->DesignVoltage =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DesignVoltage;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->SBDSSerialNumber =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].SbdsSerialNumber;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->SBDSManufacturerDate =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].SbdsManufacturedDate;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)TempStructure22)->DesignCapabilityMult =
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DesignCapacityMult;
+
+ ReplaceString(TempStructure22,
+ 5,
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].DeviceName);
+ ReplaceString(TempStructure22,
+ 6,
+ ((BATTERY_DYNAMIC_DATA*)SmbiosVariableBuffer)->BatteryDynamicData[i].SbdsVersion);
+
+ WriteStructureByHandle(StructureHandle,
+ TempStructure22,
+ GetStructureLength(TempStructure22));
+ }
+ else {
+ DeleteStructureByHandle(StructureHandle);
+ }
+ }
+ }
+ pBS->FreePool(TempStructure22);
+ }
+
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateBatteryData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
+#if UPDATE_ADDITIONAL_INFO_TYPE40
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateAdditionalInfoData
+//
+// Description: Updates Additional Information structures (Type 40) in
+// input Buffer - Referenced Handle field.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateAdditionalInfoData(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *SrcBuffer;
+ UINT8 *AdditionalInfoPtr;
+ UINT8 *StructureFoundPtr;
+ UINT8 NumAdditionalInfoEntries;
+ UINT8 StructureType;
+ UINT8 Instance;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateAdditionalInfoData ***\n"));
+
+ SrcBuffer = Buffer;
+ if (FindStructureType(&SrcBuffer, &AdditionalInfoPtr, 40, 1))
+ {
+ NumAdditionalInfoEntries = ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->NumAdditionalInfoEntries;
+ for (i = 0; i < NumAdditionalInfoEntries; i++)
+ {
+ SrcBuffer = Buffer;
+ StructureType = ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->AdditionalEntries[i].RefHandle / 16;
+ Instance = ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->AdditionalEntries[i].RefHandle % 16;
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, StructureType, Instance))
+ {
+ ((SMBIOS_ADDITIONAL_INFO*)AdditionalInfoPtr)->AdditionalEntries[i].RefHandle =
+ ((SMBIOS_STRUCTURE_HEADER*)StructureFoundPtr)->Handle;
+ }
+ }
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateAdditionalInfoData :::\n"));
+
+ return EFI_SUCCESS;
+}
+#endif
+
+#if UPDATE_DEVICE_EXT_TYPE41
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateOnboardDevExt
+//
+// Description: Updates On Board Devices Extended Information structure (Type 41)
+// in input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateOnboardDevExt(
+ IN UINT8 *Buffer
+)
+{
+ EFI_STATUS Status;
+ UINT32 Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ UINT8 *SrcBuffer;
+ UINT8 *StructureFoundPtr;
+ UINT8 *SmbiosVariableBuffer;
+ UINTN SmbiosVariableSize;
+ UINT8 i;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateOnboardDevExt ***\n"));
+
+ SmbiosVariableSize = sizeof(ONBOARD_DEV_EXT_DYNAMIC_DATA);
+ pBS->AllocatePool(EfiBootServicesData, SmbiosVariableSize, (void**)&SmbiosVariableBuffer);
+ Status = pRS->GetVariable(SmbiosOnBoardExtVar, &gEfiSmbiosDynamicData,
+ &Attributes, &SmbiosVariableSize, SmbiosVariableBuffer);
+ if (EFI_ERROR(Status) && Status != EFI_NOT_FOUND) {
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "Failed to get SmbiosOnBoardExtVar\n"));
+ return Status;
+ }
+
+ if (Status != EFI_NOT_FOUND) {
+ SrcBuffer = Buffer;
+ for (i = 0; i < gSmbiosBoardProtocol->NumberOfOnboardDevExt; i++) {
+ if (FindStructureType(&SrcBuffer, &StructureFoundPtr, 41, 1)) {
+ ((SMBIOS_ONBOARD_DEV_EXT_INFO*)StructureFoundPtr)->DeviceType &= 0x7f;
+ ((SMBIOS_ONBOARD_DEV_EXT_INFO*)StructureFoundPtr)->DeviceType |= ((ONBOARD_DEV_EXT_DYNAMIC_DATA*)SmbiosVariableBuffer)->OnBoardDev[i];
+ ((SMBIOS_ONBOARD_DEV_EXT_INFO*)StructureFoundPtr)->BusNumber = ((ONBOARD_DEV_EXT_DYNAMIC_DATA*)SmbiosVariableBuffer)->BusNumber[i];
+ }
+ }
+ }
+ pBS->FreePool(SmbiosVariableBuffer);
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateOnboardDevExt :::\n"));
+ return EFI_SUCCESS;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateStructures
+//
+// Description: Updates CPU, System Slot, On Board Devices, Memory structures
+// input Buffer with dynamically detected data.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DynamicUpdateStructures(
+ IN UINT8 *Buffer
+)
+{
+ static BOOLEAN FirstRun = TRUE;
+
+ TRACE((-1, "*** SMBIOS - DynamicUpdateStructures ***\n"));
+
+ if (FirstRun && (gSmbiosBoardProtocol != NULL)) {
+ #if (TYPE2_STRUCTURE && UPDATE_BASEBOARD_TYPE2)
+ if (gSmbiosBoardProtocol->BaseBoardInfoSupport) {
+ DynamicUpdateBaseBoardData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE3_STRUCTURE && UPDATE_SYSTEM_CHASSIS_TYPE3)
+ if (gSmbiosBoardProtocol->SysChassisInfoSupport) {
+ DynamicUpdateChassisData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE4_STRUCTURE && UPDATE_CPU_TYPE4)
+ if (UpdateCpuStructure) {
+ DynamicUpdateCpuData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE9_STRUCTURE && UPDATE_SLOT_TYPE9)
+ DynamicUpdateSlotsData(SmbiosDataTable);
+ #endif
+ #if (TYPE10_STRUCTURE && UPDATE_ONBOARD_DEV_TYPE10)
+ if (gSmbiosBoardProtocol->OnboardDeviceInfoSupport) {
+ DynamicUpdateOnboardDevData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE16_STRUCTURE && UPDATE_MEMORY_TYPE16)
+ gSmbiosBoardProtocol->EnableSmbusController();
+ DynamicUpdateMemoryData(SmbiosDataTable);
+ gSmbiosBoardProtocol->RestoreSmbusController();
+ #endif
+ #if FLASH_MEMORY_ARRAY_INFO && defined(FLASH_PART_STRING_LENGTH)
+ DynamicUpdateFlashMemoryData();
+ #endif
+ #if (TYPE22_STRUCTURE && UPDATE_BATTERY_TYPE22)
+ if (gSmbiosBoardProtocol->PortableBatteryInfoSupport) {
+ DynamicUpdateBatteryData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE40_STRUCTURE && UPDATE_ADDITIONAL_INFO_TYPE40)
+ if (gSmbiosBoardProtocol->AdditionalInfoSupport) {
+ DynamicUpdateAdditionalInfoData(SmbiosDataTable);
+ }
+ #endif
+ #if (TYPE41_STRUCTURE && UPDATE_DEVICE_EXT_TYPE41)
+ if (gSmbiosBoardProtocol->OnboardDeviceExtInfoSupport) {
+ DynamicUpdateOnboardDevExt(SmbiosDataTable);
+ }
+ #endif
+
+ FirstRun = FALSE;
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit DynamicUpdateStructures :::\n"));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosTableEntryPoint
+//
+// Description: SMBIOS protocol - Returns the pointer to the SmbiosTableEntryPoint
+//
+// Input: None
+//
+// Output: VOID* - Pointer to the SmbiosTableEntryPoint
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetSmbiosTableEntryPoint(
+)
+{
+ return pSmbiosTableEntryPoint;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetScratchBufferPtr
+//
+// Description: SMBIOS protocol - Returns the pointer to the Scratch buffer
+// equal the SMBIOS data structure in size.
+//
+// Input: None
+//
+// Output: VOID* - Pointer to the Scratch buffer
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetScratchBufferPtr(
+)
+{
+ return ScratchBufferPtr;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetScratchBufferPtr
+//
+// Description: SMBIOS protocol - Returns the maximum size for the SMBIOS
+// data structure table.
+//
+// Input: None
+//
+// Output: UINT16 - Maximum SMBIOS data table size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetBufferMaxSize(VOID)
+{
+ return MaximumTableSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForValidStructure
+//
+// Description: Checks for structure validity
+//
+// Input: IN UINT8 *Buffer
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+CheckForValidStructure(
+ IN UINT8 *Buffer,
+ IN UINT16 Size
+)
+{
+ // Check for valid terminator
+ if (*(UINT16*)(Buffer + Size - 2) != 0) {
+ TRACE((-1, "Invalid structure terminator\n"));
+ return DMI_BAD_PARAMETER;
+ }
+
+ // Check for valid size
+ if (Size < (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Length + 2)) {
+ TRACE((-1, "Invalid structure size\n"));
+ return DMI_BAD_PARAMETER;
+ }
+ return DMI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetTotalStructureSize
+//
+// Description: Returns the total structure size
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Total structure size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetTotalStructureSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT16 Length = 0;
+ UINT16 BlockSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Type != 127) {
+ BlockSize = GetStructureLength(Buffer);
+ Length += BlockSize;
+ Buffer += BlockSize;
+ }
+ Length += GetStructureLength(Buffer);
+ return Length;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetRemainingStructuresSize
+//
+// Description: Return the size from the Pointer Buffer to the last
+// structure 127.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: Size of remaining structure
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetRemainingStructuresSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT16 Length = 0;
+ UINT16 BlockSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Type != 127) {
+ BlockSize = GetStructureLength(Buffer);
+ Length += BlockSize;
+ Buffer += BlockSize;
+ }
+ Length += GetStructureLength(Buffer);
+ return Length;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateEPSHeader
+//
+// Description: Updates the SMBIOS Entry Point Header
+//
+// Input: IN SMBIOS_TABLE_ENTRY_POINT *pSmbiosTableEntryPoint
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateEPSHeader(
+ IN SMBIOS_TABLE_ENTRY_POINT *pSmbiosTableEntryPoint
+)
+{
+#if (defined(SB_WAKEUP_TYPE_FN) && (SB_WAKEUP_TYPE_FN == 1))
+ UINT8 *Buffer;
+ UINT8 *FoundPtr = NULL;
+
+ //
+ // Create "WakeUpType" variable containing pointer to this field
+ // so that it can be updated on S3 resume
+ //
+ Buffer = SmbiosDataTable;
+
+ if (FindStructureType(&Buffer, &FoundPtr, 1, 1)) {
+ FoundPtr += 0x18;
+
+ pRS->SetVariable(
+ L"WakeUpType",
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 4,
+ &FoundPtr);
+ }
+#endif
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && (((UINT32)pSmbiosTableEntryPoint & 0xffff0000) == 0x000f0000)) {
+ LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+ }
+#endif
+ // Updating EPS Header
+ // Update SMBIOS Data Structure Table length in EPS Header
+ pSmbiosTableEntryPoint->TableLength = GetTotalStructureSize(SmbiosDataTable);
+ pSmbiosTableEntryPoint->TableAddress = (UINT32)(UINTN)SmbiosDataTable;
+
+ // Find and update number of SMBios Structures in EPS Header
+ pSmbiosTableEntryPoint->NumberOfSmbiosStructures = GetNumberOfStructures(SmbiosDataTable);
+
+ // Find and update largest SMBios Structure in EPS Header
+ pSmbiosTableEntryPoint->MaxStructureSize = GetLargestStructureSize((UINT8*)(UINTN)pSmbiosTableEntryPoint->TableAddress);
+
+ // Update Checksums in EPS Header
+ pSmbiosTableEntryPoint->IntermediateChecksum = 0;
+ pSmbiosTableEntryPoint->IntermediateChecksum = SmbiosCheckSum((UINT8*)pSmbiosTableEntryPoint + 0x10, 15);
+
+ pSmbiosTableEntryPoint->EntryPointStructureChecksum = 0;
+ pSmbiosTableEntryPoint->EntryPointStructureChecksum = SmbiosCheckSum((UINT8*)pSmbiosTableEntryPoint,
+ pSmbiosTableEntryPoint->EntryPointLength);
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && (((UINT32)pSmbiosTableEntryPoint & 0xffff0000) == 0x000f0000)) {
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+ }
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosTable
+//
+// Description: Update the SMBIOS Table
+//
+// Input: IN SMBIOS_OPERATION Operation
+// IN UINT8 *StructurePtr
+// - Adding operation: N/A
+// - Delete operation: Pointer to
+// structure to be deleted
+// IN UINT8 *Buffer
+// - Adding operation: Pointer to buffer
+// to be added
+// - Delete operation: N/A
+// IN UINT16 Size
+// - Adding operation: Size of buffer
+// to be added
+// - Delete operation: N/A
+// IN UINT16 Handle
+// - Adding operation:
+// = 0xFFFF to assign next handle number
+// = Other value to assign a specific
+// handle number
+// - Delete operation: N/A
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Dynamic table sizing can only be done when SMBIOS table is at
+// high memory. At E000, table can be expanded up to the padding size.
+// This limitation is due to CSM can only allocate memory, but it does
+// not have memory deallocation feature.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateSmbiosTable(
+ IN SMBIOS_OPERATION Operation,
+ IN UINT8 *StructurePtr,
+ IN UINT8 *Buffer,
+ IN UINT16 Size,
+ IN UINT16 Handle
+)
+{
+ EFI_STATUS Status = -1;
+ EFI_STATUS TableCopyStatus = -1;
+ UINT8 *SmbiosTableCopy;
+ UINT8 *AllocatedMemory;
+ UINT8 *MemoryPtr;
+ UINT8 *TempPtr;
+ UINT8 *TempPtr2;
+ UINT8 *Type127;
+ UINT16 TableLength;
+ UINT32 Length;
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ NULL);
+ }
+#endif
+
+ TRACE((-1, "*** SMBIOS - UpdateSmbiosTable ***\n"));
+ TRACE((-1, "Operation = %x, Size = %x, Handle = %x\n", Operation, Size, Handle));
+
+ switch (Operation) {
+ case ADD_STRUCTURE:
+ if (Buffer == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (Handle != 0xffff) {
+ // Check for existing handle
+ TempPtr = SmbiosDataTable;
+ if (FindStructureHandle(&TempPtr, Handle)) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ }
+
+ // Check input buffer for valid structure according to its size
+ Status = CheckForValidStructure(Buffer, Size);
+ if (Status != EFI_SUCCESS) {
+ Status = EFI_PROTOCOL_ERROR;
+ break;
+ }
+
+ // Make copy of the original Smbios Table
+ TableCopyStatus = pBS->AllocatePool(
+ EfiBootServicesData,
+ MaximumTableSize,
+ (void**)&SmbiosTableCopy
+ );
+ if (EFI_ERROR(TableCopyStatus)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ // TempPtr = pointer to the original Smbios table
+ TempPtr = SmbiosTableCopy;
+ MemCpy(TempPtr, SmbiosDataTable, MaximumTableSize);
+
+ if (SmbiosTableAtE000) {
+ // Check for enough space
+ TableLength = GetTotalStructureSize(SmbiosDataTable);
+ if (Size > (MaximumTableSize - TableLength)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ MemoryPtr = SmbiosDataTable;
+ }
+ else {
+ TRACE((-1, "Allocating memory for new table\n"));
+ // Allocate memory to store new Smbios table
+ TableLength = MaximumTableSize + Size;
+ Status = pBS->AllocatePool(
+ EfiRuntimeServicesData,
+ TableLength,
+ &AllocatedMemory
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Failed to allocate memory\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+
+ // Copy current Smbios table to the new location
+ MemCpy(AllocatedMemory, SmbiosDataTable, MaximumTableSize);
+
+ MemoryPtr = AllocatedMemory;
+ TRACE((-1, "Memory allocated = %x\n", MemoryPtr));
+ }
+
+ if (ADD_STRUCTURE_LOCATION == 1) {
+ // Advance the pointers to the first structure whose handle number
+ // is larger than the input handle. In case input handle is FFFF,
+ // move the pointers to the last structure (Type 127).
+ while (((SMBIOS_STRUCTURE_HEADER*)MemoryPtr)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)MemoryPtr)->Handle > Handle) {
+ break;
+ }
+
+ Length = GetStructureLength(MemoryPtr);
+
+ // Move pointer in the new Smbios table
+ MemoryPtr += Length;
+
+ // Move pointer in the original Smbios table
+ TempPtr += Length;
+ }
+ }
+ else {
+ TempPtr2 = TempPtr;
+ FindStructureType(&TempPtr2, &TempPtr, 127, 1);
+ MemoryPtr += TempPtr - SmbiosTableCopy;
+ }
+
+ if (Handle == 0xffff) {
+ // Assign the LastHandle to the newly added structure
+ ((SMBIOS_STRUCTURE_HEADER*)Buffer)->Handle = LastHandle;
+ }
+ else {
+ ((SMBIOS_STRUCTURE_HEADER*)Buffer)->Handle = Handle;
+
+ if (Handle > LastHandle) {
+ LastHandle = Handle;
+ }
+ }
+
+ // Insert input structure
+ MemCpy(MemoryPtr, Buffer, Size);
+ MemoryPtr += Size;
+
+ // Copy remaining structures
+ Length = GetRemainingStructuresSize(TempPtr);
+ MemCpy(MemoryPtr, TempPtr, Length);
+
+ // Update Type 127 handle if needed
+ FindStructureType(&MemoryPtr, &Type127, 127, 1);
+ if (LastHandle >= ((SMBIOS_STRUCTURE_HEADER*)Type127)->Handle) {
+ ((SMBIOS_STRUCTURE_HEADER*)Type127)->Handle = ++LastHandle;
+ }
+
+ TRACE((-1, "Done adding structure\n"));
+ Status = EFI_SUCCESS;
+ break;
+
+ case DELETE_STRUCTURE:
+ TRACE((-1, "Deleting structure\n"));
+ // Clear UpdateCpuStructure flag if CPU (type 4) structure is being deleted
+ if (((SMBIOS_STRUCTURE_HEADER*)StructurePtr)->Type == 4) {
+ UpdateCpuStructure = FALSE;
+ }
+
+ // StructurePtr = Pointer to structure to be deleted
+ if (SmbiosTableAtE000) {
+ Length = GetTotalStructureSize(StructurePtr) - GetStructureLength(StructurePtr);
+ TempPtr = StructurePtr + GetStructureLength(StructurePtr);
+ MemCpy(StructurePtr, TempPtr, Length);
+ Status = EFI_SUCCESS;
+ TRACE((-1, "Done deleting\n"));
+ break;
+ }
+ else {
+ Length = (UINT32)(StructurePtr - SmbiosDataTable); // From start of SmbiosTable to current ptr
+ TableLength = MaximumTableSize - GetStructureLength(StructurePtr);
+ Status = pBS->AllocatePool(
+ EfiRuntimeServicesData,
+ TableLength,
+ &AllocatedMemory
+ );
+ if (EFI_ERROR(Status)) {
+ Status = EFI_OUT_OF_RESOURCES;
+ break;
+ }
+ MemoryPtr = AllocatedMemory;
+ MemCpy(MemoryPtr, SmbiosDataTable, Length);
+ MemoryPtr += Length;
+ TempPtr = StructurePtr + GetStructureLength(StructurePtr);
+ TempPtr2 = SmbiosDataTable + MaximumTableSize;
+ MemCpy(MemoryPtr, TempPtr, TempPtr2 - TempPtr);
+ Status = EFI_SUCCESS;
+ break;
+ }
+
+ default:
+ TableCopyStatus = EFI_PROTOCOL_ERROR;
+ Status = EFI_PROTOCOL_ERROR;
+ }
+
+ if (TableCopyStatus == EFI_SUCCESS) {
+ pBS->FreePool(SmbiosTableCopy);
+ }
+
+ TRACE((-1, "Status = %r\n", Status));
+ if (Status == EFI_SUCCESS) {
+ if (!SmbiosTableAtE000) {
+ if (TableRelocated) {
+ pBS->FreePool(SmbiosDataTable);
+ }
+ SmbiosDataTable = AllocatedMemory;
+ MaximumTableSize = TableLength;
+ TableRelocated = TRUE;
+ }
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+ }
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ NULL);
+ }
+#endif
+
+ TRACE((-1, "::: SMBIOS - Exit UpdateSmbiosTable. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFreeHandle
+//
+// Description: SMBIOS protocol - Searches available handle
+// of Smbios Data Table
+//
+//
+// Input: None
+//
+// Output: UINT16 - Handle or -1(if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetFreeHandle(VOID)
+{
+ EFI_STATUS FoundStatus;
+
+ UINT16 Handle = 0;
+ UINT8 *StructurePtr;
+
+ // Count Handle form 0 to 0xFFFF to find available Handle
+ for (Handle = 0; Handle < 0xffff; Handle++) {
+ StructurePtr = SmbiosDataTable;
+ FoundStatus = FindStructureHandle(&StructurePtr, Handle);
+ if (!FoundStatus) {
+ return Handle;
+ }
+ }
+
+ return -1; // No available Handle to use;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckForType4AndUpdate
+//
+// Description: Check input Buffer for Type 4 (CPU structure) and update it
+// with DMIEdit data if exist
+//
+// Input: IN UINT8 **Buffer
+// IN UINT16 *Size
+//
+// Output: Updated Buffer and Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CheckForType4AndUpdate(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT16 *Size
+)
+{
+ UINT8 *PoolMemory;
+
+ if (((SMBIOS_STRUCTURE_HEADER*)*Buffer)->Type == 4) {
+ // Check if there are DMIEdit data for Serial Number, or Asset Tag, or Part Number fields
+ if (NvramType4.Flag & 0x3f) {
+ // Allocate 1K memory
+ pBS->AllocatePool(
+ EfiBootServicesData,
+ 0x400,
+ (void**)&PoolMemory);
+ MemSet(PoolMemory, 0x400, 0);
+ MemCpy(PoolMemory, *Buffer, *Size);
+
+ // Replace DMIEdit strings if exist
+ UpdateStrings((SMBIOS_NVRAM_TYPE*)&NvramType4, PoolMemory, 1);
+
+ // Change input Buffer to allocated memory with updated data
+ *Buffer = PoolMemory;
+ *Size = GetStructureLength(PoolMemory);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStructure
+//
+// Description: SMBIOS protocol - Add new structure
+//
+// Input: IN UINT8 *Buffer
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+// Buffer->Handle = Assigned handle number
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AddStructure(
+ IN UINT8 *Buffer,
+ IN UINT16 Size
+)
+{
+ EFI_STATUS Status;
+
+ TRACE((-1, "*** SMBIOS - AddStructure ***\n"));
+
+ CheckForType4AndUpdate(&Buffer, &Size);
+
+ Status = UpdateSmbiosTable(
+ ADD_STRUCTURE,
+ NULL,
+ Buffer,
+ Size,
+ 0xFFFF // Assign next handle number
+ );
+
+ TRACE((-1, "::: SMBIOS - Exit AddStructure. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStructureByHandle
+//
+// Description: SMBIOS protocol - Add new structure with a specific handle -
+// structure will not be added if another structure with this
+// handle already existed.
+//
+// Input: IN UINT16 Handle
+// IN UINT8 *Buffer
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+AddStructureByHandle(
+ IN UINT16 Handle,
+ IN UINT8 *Buffer,
+ IN UINT16 Size
+)
+{
+ EFI_STATUS Status;
+
+ TRACE((-1, "*** SMBIOS - AddStructureByHandle ***\n"));
+
+ CheckForType4AndUpdate(&Buffer, &Size);
+
+ return UpdateSmbiosTable(
+ ADD_STRUCTURE,
+ NULL,
+ Buffer,
+ Size,
+ Handle
+ );
+
+ TRACE((-1, "::: SMBIOS - Exit AddStructureByHandle. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStructureByHandle
+//
+// Description: SMBIOS protocol - Searches and deletes structure by handle
+//
+// Input: IN UINT16 Handle
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DeleteStructureByHandle(
+ IN UINT16 Handle
+)
+{
+ EFI_STATUS Status;
+ UINT8 *StructurePtr = SmbiosDataTable;
+
+ TRACE((-1, "*** SMBIOS - DeleteStructureByHandle. Handle = %x ***\n", Handle));
+
+ if (FindStructureHandle(&StructurePtr, Handle)) {
+ TRACE((-1, "Deleting structure type %x\n", ((SMBIOS_STRUCTURE_HEADER*)StructurePtr)->Type));
+ Status = UpdateSmbiosTable(
+ DELETE_STRUCTURE,
+ StructurePtr,
+ 0,
+ 0,
+ 0
+ );
+ }
+ else {
+ TRACE((-1, "Structure not found\n"));
+ Status = EFI_NOT_FOUND;
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit DeleteStructureByHandle. Status = %r :::\n", Status));
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadStructureByHandle
+//
+// Description: SMBIOS protocol - Searches for a structure with input handle,
+// and return a copy of this structure in BufferPtr if found.
+//
+// Input: IN UINT16 Handle
+// IN OUT UINT8 **BufferPtr
+// IN OUT UINT16 *BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Memory will be allocated for the returning structure if
+// structure with input handle is found. Caller is responsible
+// for freeing this memory when done with it.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadStructureByHandle(
+ IN UINT16 Handle,
+ IN OUT UINT8 **BufferPtr,
+ IN OUT UINT16 *BufferSize
+)
+{
+ EFI_STATUS Status;
+ UINT8 *StructurePtr = SmbiosDataTable;
+
+ TRACE((-1, "*** SMBIOS - ReadStructureByHandle ***\n"));
+
+ if (FindStructureHandle(&StructurePtr, Handle)) {
+ *BufferSize = GetStructureLength(StructurePtr);
+ Status = pBS->AllocatePool(EfiBootServicesData, *BufferSize, (void**)BufferPtr);
+ if (Status != EFI_SUCCESS) {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemCpy(*BufferPtr, StructurePtr, *BufferSize);
+
+ TRACE((-1, "Exit ReadStructureByHandle\n"));
+ return EFI_SUCCESS;
+ }
+ else {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Structure not found. Exit\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadStructureByType
+//
+// Description: SMBIOS protocol - Searches for the (n)th structure of input
+// Type and return a copy of this structure in BufferPtr if found.
+//
+// Input: IN UINT8 Type
+// IN UINT8 Instance
+// IN OUT UINT8 **BufferPtr
+// IN OUT UINT16 *BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Memory will be allocated for the returning structure if
+// structure with input handle is found. Caller is responsible
+// for freeing this memory when done with it.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReadStructureByType(
+ IN UINT8 Type,
+ IN UINT8 Instance,
+ IN OUT UINT8 **BufferPtr,
+ IN OUT UINT16 *BufferSize
+)
+{
+ EFI_STATUS Status;
+ UINT8 *StructurePtr = SmbiosDataTable;
+ UINT8 *FoundStructPtr;
+
+ TRACE((-1, "*** SMBIOS - ReadStructureByType ***\n"));
+
+ if (FindStructureType(&StructurePtr, &FoundStructPtr, Type, Instance)) {
+ *BufferSize = GetStructureLength(FoundStructPtr);
+ Status = pBS->AllocatePool(EfiBootServicesData, *BufferSize, (void**)BufferPtr);
+ if (Status != EFI_SUCCESS) {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemCpy(*BufferPtr, FoundStructPtr, *BufferSize);
+
+ TRACE((-1, "::: SMBIOS - Exit ReadStructureByType :::\n"));
+ return EFI_SUCCESS;
+ }
+ else {
+ *BufferPtr = NULL;
+ *BufferSize = 0;
+
+ TRACE((-1, "Structure type %x not found\n", Type));
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteStructureByHandle
+//
+// Description: SMBIOS protocol - Overwrite an existing structure by handle
+//
+// Input: UINT16 Handle
+// UINT8 *BufferPtr
+// UINT16 BufferSize
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WriteStructureByHandle(
+ IN UINT16 Handle,
+ IN UINT8 *BufferPtr,
+ IN UINT16 BufferSize
+)
+{
+ EFI_STATUS Status;
+
+#if WRITE_STRUCTURE_HANDLE_POLICY == 0
+
+ TRACE((-1, "*** SMBIOS - WriteStructureByHandle ***\n"));
+
+ Status = DeleteStructureByHandle(Handle);
+ if (!EFI_ERROR(Status)) {
+ CheckForType4AndUpdate(&BufferPtr, &BufferSize);
+
+ Status = UpdateSmbiosTable(
+ ADD_STRUCTURE,
+ NULL,
+ BufferPtr,
+ BufferSize,
+ Handle
+ );
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit WriteStructureByHandle. Status = %r :::\n", Status));
+ return Status;
+
+#else
+
+ UINT8 *SmbiosTableCopy;
+ UINT8 *TempPtr;
+ UINT8 *MemoryPtr;
+ UINT16 Size;
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ UINT32 Granularity;
+#endif // CSM_SUPPORT
+
+ TRACE((-1, "*** SMBIOS - WriteStructureByHandle ***\n"));
+
+ // Check input buffer for valid structure according to its size
+ Status = CheckForValidStructure(BufferPtr, BufferSize);
+ if (Status != EFI_SUCCESS) {
+ return EFI_PROTOCOL_ERROR;
+ }
+
+ MemoryPtr = SmbiosDataTable;
+ if (FindStructureHandle(&MemoryPtr, Handle)) {
+ // Check for enough space
+ Size = GetTotalStructureSize(SmbiosDataTable) - GetStructureLength(MemoryPtr);
+ if (BufferSize > (MaximumTableSize - Size)) {
+ if (SmbiosTableAtE000) {
+ // Table can not grow when in E000, so exit
+ TRACE((-1, "Not enough space in E000. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ else {
+ Status = DeleteStructureByHandle(Handle);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Cannot delete handle %x. Exit\n", Handle));
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+ }
+ }
+
+ // Make copy of the original Smbios Table
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ MaximumTableSize,
+ (void**)&SmbiosTableCopy
+ );
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // TempPtr = pointer to copy of original Smbios table
+ TempPtr = SmbiosTableCopy;
+ MemCpy(TempPtr, SmbiosDataTable, MaximumTableSize);
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ &Granularity);
+ }
+#endif // CSM_SUPPORT
+
+ MemoryPtr = SmbiosDataTable;
+
+ if (FindStructureHandle(&MemoryPtr, Handle)) {
+ MemCpy(MemoryPtr, BufferPtr, BufferSize);
+ TempPtr += MemoryPtr - SmbiosDataTable;
+ TempPtr += GetStructureLength(TempPtr);
+ MemoryPtr += GetStructureLength(MemoryPtr);
+
+ // Copy remaining structures
+ Size = GetRemainingStructuresSize(TempPtr);
+ MemCpy(MemoryPtr, TempPtr, Size);
+ }
+ else {
+ AddStructureByHandle(Handle, BufferPtr, BufferSize);
+ }
+
+ pBS->FreePool(SmbiosTableCopy);
+
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+ if ((LegacyRegionProtocol != NULL) && SmbiosTableAtE000) {
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ (UINT32)SmbiosDataTable,
+ MaximumTableSize,
+ &Granularity);
+ }
+#endif // CSM_SUPPORT
+
+ TRACE((-1, "::: SMBIOS - Exit WriteStructureByHandle :::\n"));
+ return EFI_SUCCESS;
+
+#endif // WRITE_STRUCTURE_HANDLE_POLICY
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosTableHeader
+//
+// Description: SMBIOS protocol - Updates the SMBIOS Table Header
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UpdateSmbiosTableHeader(VOID)
+{
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindCsm16Table
+//
+// Description: Searches for CSM16 Table in F000 segment
+//
+// Input: IN OUT EFI_COMPATIBILITY16_TABLE **Csm16Table
+//
+// Output: EFI_COMPATIBILITY16_TABLE** Csm16Table
+// EFI_STATUS
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if (defined(ITK_SUPPORT) && (ITK_SUPPORT != 0)) || (SMBIOS_TABLE_LOCATION)
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+EFI_STATUS FindCsm16Table(OUT EFI_COMPATIBILITY16_TABLE** Csm16Table){
+
+ UINT32* PtrCsmTable = (UINT32*)0xe0000;
+
+ for( ; PtrCsmTable < (UINT32*)0x100000; PtrCsmTable+=4) {
+ if(*PtrCsmTable == (UINT32)'$EFI'){
+ *Csm16Table = (EFI_COMPATIBILITY16_TABLE*)PtrCsmTable;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosE000Alloc
+//
+// Description: Allocate memory for SMBIOS table in low memory
+//
+// Input: IN OUT UINT8 **TablePtr
+// IN UINT16 Size
+//
+// Output: EFI_STATUS
+// If success, TablePtr points to allocated memory in
+// E000 segment.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if (defined(ITK_SUPPORT) && (ITK_SUPPORT != 0)) || (SMBIOS_TABLE_LOCATION)
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+EFI_STATUS
+SmbiosE000Alloc(
+ IN OUT UINT8 **TablePtr,
+ IN UINT16 Size
+)
+{
+ EFI_STATUS Status;
+ EFI_IA32_REGISTER_SET Registers;
+ EFI_COMPATIBILITY16_TABLE* Csm16Table;
+
+ TRACE((-1, "*** SMBIOS - SmbiosE000Alloc ***\n"));
+
+ if (LegacyBiosProtocol != NULL) {
+ MemSet(&Registers, sizeof (EFI_IA32_REGISTER_SET), 0);
+
+ Status = FindCsm16Table(&Csm16Table);
+ if (EFI_ERROR (Status)) {
+ TRACE((-1, "Csm16 Table not found. Exit\n"));
+ return Status;
+ }
+
+ Status = LegacyRegionProtocol->UnLock (LegacyRegionProtocol,
+ 0xe0000,
+ 0x20000,
+ NULL);
+
+ // In case E000-F000 fails to unlock then return error without allocating memory
+ if (EFI_ERROR (Status)) {
+ TRACE((-1, "Failed to unlock shadow. Exit\n"));
+ return Status;
+ }
+
+ Registers.X.AX = Compatibility16GetTableAddress;
+ Registers.X.BX = E0000_BIT; // allocate from 0xE0000 64 KB block
+ Registers.X.CX = (UINT16)Size;
+ Registers.X.DX = 1; // alignment
+
+ Status = LegacyBiosProtocol->FarCall86(LegacyBiosProtocol,
+ Csm16Table->Compatibility16CallSegment,
+ Csm16Table->Compatibility16CallOffset,
+ &Registers,
+ 0,
+ 0);
+
+ if (Registers.X.AX) Status = (Registers.X.AX & 0x7fff) | 0x80000000;
+ ASSERT_EFI_ERROR(Status);
+
+ if (!EFI_ERROR(Status)) { // If success
+ *TablePtr = (UINT8*)(((UINTN)Registers.X.DS << 4) + Registers.X.BX);
+ }
+
+ LegacyRegionProtocol->Lock (LegacyRegionProtocol,
+ 0xe0000,
+ 0x20000,
+ NULL);
+ }
+ else {
+ TRACE((-1, "No LegacyBiosProtocol. Exit\n"));
+ Status = EFI_PROTOCOL_ERROR;
+ }
+
+ TRACE((-1, "::: SMBIOS - Exit SmbiosE000Alloc. Status = %r :::\n", Status));
+ return Status;
+}
+#endif // CSM_SUPPORT
+#endif // ITK_SUPPORT || SMBIOS_TABLE_LOCATION
+
+#if BIOS_LANGUAGE_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddUpdateType13
+//
+// Description: Add or update BIOS Language Information structure type 13
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddUpdateType13 (VOID)
+{
+ EFI_STATUS Status;
+ UINT8 i;
+ UINT8 j;
+ UINT8 *SmbiosTablePtr = SmbiosDataTable;
+ UINT8 *TempPtr;
+ UINT8 *BufferPtr;
+ UINT16 BufferSize;
+ UINTN Size = 0;
+ EFI_GUID guidEfiVar = EFI_GLOBAL_VARIABLE;
+
+//----------------------------------------------------------------------------
+// ***** BIOS LANGUAGE TYPE 13 Tables *****
+// (Table entries should cover the languages specified
+// in Languages.mak)
+//----------------------------------------------------------------------------
+#if EFI_SPECIFICATION_VERSION > 0x20000
+ #define LANGUAGESIZE 5
+ CHAR8 SupportLang[][LANGUAGESIZE] = {
+ "en-US",
+ "fr-FR",
+ "es-ES",
+ "de-DE",
+ "ru-RU",
+ "zh-ch", // zh-chs
+ "zh-ch", // zh-cht
+ "ko-KR",
+ "ja-JP",
+ "it-IT",
+ "da-DK",
+ "fi-FI",
+ "nl-NL",
+ "nb-NO",
+ "pt-BR",
+ "sv-FI",
+ };
+#else
+ #define LANGUAGESIZE 3
+ CHAR8 SupportLang[][LANGUAGESIZE] = {
+ "eng",
+ "fra",
+ "spa",
+ "ger",
+ "rus",
+ "zho",
+ "chi",
+ "kor",
+ "jpn",
+ "ita",
+ "dan",
+ "fin",
+ "dut",
+ "nor",
+ "por",
+ "swe",
+ };
+#endif // EFI_SPECIFICATION_VERSION
+#if BIOS_LANGUAGE_FORMAT
+ CHAR8 LangShort[][4] = { "enUS",
+ "frFR",
+ "esES",
+ "deDE",
+ "ruRU",
+ "zhCN",
+ "zhCN",
+ "koKR",
+ "jaJP",
+ "itIT",
+ "daDK",
+ "fiFI",
+ "nlNL",
+ "noNO",
+ "ptPT",
+ "svSE",
+ };
+#else
+ CHAR8 LangLong[][16] = { "en|US|iso8859-1\0",
+ "fr|FR|iso8859-1\0",
+ "es|ES|iso8859-1\0",
+ "de|DE|iso8859-1\0",
+ "ru|RU|iso8859-5\0",
+ "zh|CN|unicode\0",
+ "zh|CN|unicode\0",
+ "ko|KR|unicode\0",
+ "ja|JP|unicode\0",
+ "it|IT|iso8859-1\0",
+ "da|DK|iso8859-1\0",
+ "fi|FI|iso8859-1\0",
+ "nl|NL|iso8859-1\0",
+ "no|NO|iso8859-1\0",
+ "pt|PT|iso8859-1\0",
+ "sv|SE|iso8859-1\0",
+ };
+#endif // BIOS_LANGUAGE_FORMAT
+
+ CHAR8 Language[LANGUAGESIZE]; // Current Language
+ CHAR8 *Lang = &Language[0];
+ CHAR8 LanguageCodes[256]; // Supported Languages - Arbitrary size
+ CHAR8 *LangCodes = &LanguageCodes[0];
+ UINT8 LangCounts;
+//----------------------------------------------------------------------------
+
+ TRACE((-1, "*** SMBIOS - AddUpdateType13 ***\n"));
+
+ Size = sizeof(LanguageCodes);
+
+#if EFI_SPECIFICATION_VERSION > 0x20000 // UEFI 2.1 and later
+ Status = GetEfiVariable(L"PlatformLangCodes",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ (void**)&LangCodes);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Failed to get PlatformLangCodes variable. Exit\n"));
+ return;
+ }
+
+ LangCounts = (UINT8)((UINT16)Size / (LANGUAGESIZE + 1)); // +1 to compensate for ";" and string terminator
+
+ Size = sizeof(Language) + 1;
+ Status = GetEfiVariable(L"PlatformLang",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ (void**)&Lang);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Failed to get PlatformLang variable. Exit\n"));
+ return;
+ }
+
+ BufferSize = 1024;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, BufferSize, (void**)&BufferPtr);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Memory allocation failed. Exit\n"));
+ return;
+ }
+
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type = 13;
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length = sizeof(SMBIOS_BIOS_LANG_INFO);
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->InstallableLang = LangCounts;
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Flags = BIOS_LANGUAGE_FORMAT;
+
+ pBS->SetMem(((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Reserved, 15, 0);
+
+ TempPtr = BufferPtr + sizeof(SMBIOS_BIOS_LANG_INFO);
+
+ for (i = 0; i < LangCounts; i++) {
+ for (j = 0; j < sizeof(SupportLang)/(LANGUAGESIZE); j++) {
+ if (MemCmp(&LangCodes[i * (LANGUAGESIZE + 1)], &SupportLang[j][0], LANGUAGESIZE) == 0) {
+#if BIOS_LANGUAGE_FORMAT
+ Size = 4;
+ MemCpy(TempPtr, &LangShort[j][0], Size);
+#else
+ Size = Strlen(&LangLong[j][0]);
+ MemCpy(TempPtr, &LangLong[j][0], Size);
+#endif // BIOS_LANGUAGE_FORMAT
+
+ *(TempPtr + Size) = 0; // string termination
+ break;
+ }
+ }
+ if (MemCmp(&LangCodes[i * (LANGUAGESIZE + 1)], Lang, LANGUAGESIZE) == 0) {
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->CurrentLang = i + 1;
+ }
+ TempPtr += Size + 1;
+ }
+
+#else // UEFI 2.0 and older
+
+ Status = GetEfiVariable(L"LangCodes",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ &LangCodes);
+ if (EFI_ERROR(Status)) return;
+
+ LangCounts = (UINT8)(Size / 3);
+
+ Size = sizeof(LanguageCodes);
+ Status = GetEfiVariable(L"Lang",
+ &guidEfiVar,
+ NULL,
+ &Size,
+ &Lang);
+ if (EFI_ERROR(Status)) return;
+
+ BufferSize = 1024;
+
+ Status = pBS->AllocatePool(EfiBootServicesData, BufferSize, &BufferPtr);
+ if (EFI_ERROR(Status)) return;
+
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type = 13;
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length = sizeof(SMBIOS_BIOS_LANG_INFO);
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->InstallableLang = LangCounts;
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Flags = BIOS_LANGUAGE_FORMAT;
+
+ pBS->SetMem(((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->Reserved, 15, 0);
+
+ TempPtr = BufferPtr + sizeof(SMBIOS_BIOS_LANG_INFO);
+
+ for (i = 0; i < LangCounts; i++) {
+ for (j = 0; j < sizeof(SupportLang)/3; j++) {
+ if (MemCmp(&LangCodes[3 * i], &SupportLang[j][0], 3) == 0) {
+#if BIOS_LANGUAGE_FORMAT
+ Size = 4;
+ MemCpy(TempPtr, &LangShort[j][0], Size);
+#else
+ Size = Strlen(&LangLong[j][0]);
+ MemCpy(TempPtr, &LangLong[j][0], Size);
+#endif
+ *(TempPtr + Size) = 0; // string termination
+ break;
+ }
+ }
+ if (MemCmp(&LangCodes[3 * i], Lang, 3) == 0) {
+ ((SMBIOS_BIOS_LANG_INFO*)BufferPtr)->CurrentLang = i + 1;
+ }
+ TempPtr += Size + 1;
+ }
+#endif // EFI_SPECIFICATION_VERSION > 0x20000
+
+ *TempPtr = 0; // End of structure
+
+ BufferSize = GetStructureLength(BufferPtr);
+
+ if (FindStructureType(&SmbiosTablePtr, &TempPtr, 13, 1)) {
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle = \
+ ((SMBIOS_STRUCTURE_HEADER*)TempPtr)->Handle;
+
+ // Type 13 exists, overwrite it
+ WriteStructureByHandle(
+ ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Handle,
+ BufferPtr,
+ BufferSize);
+ }
+ else {
+ // Type 13 not found, add a new one
+ AddStructure(BufferPtr, BufferSize);
+ }
+
+ pBS->FreePool(BufferPtr);
+
+ TRACE((-1, "::: SMBIOS - Exit AddUpdateType13 :::\n"));
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosDynamicUpdate
+//
+// Description: Update Processor Information, System Slots, and On-Board
+// Devices Information structures.
+//
+// Input: IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SmbiosDynamicUpdate (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID SmbiosGuid = SMBIOS_TABLE_GUID;
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+ EFI_EVENT SigEvent;
+ EFI_GUID EfiSmbiosAmtDataGuid = AMT_SMBIOS_GROUP;
+#endif
+ EFI_EVENT SmbiosTableEvent;
+ EFI_GUID EfiSmbiosTblPubGuid = SMBIOS_EFI_TABLE_GROUP;
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+ UINTN NumberOfHandles;
+ EFI_HANDLE *HandleBuffer;
+#endif
+
+ pBS->CloseEvent(Event);
+
+TRACE((-1, "*** SmbiosDynamicUpdate Entry ***\n"));
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 0
+#if (TYPE2_STRUCTURE && UPDATE_BASEBOARD_TYPE2)
+ Status = gSmbiosBoardProtocol->SmbiosCreateBaseBoardData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE2_STRUCTURE && UPDATE_BASEBOARD_TYPE2
+#if (TYPE3_STRUCTURE && UPDATE_SYSTEM_CHASSIS_TYPE3)
+ Status = gSmbiosBoardProtocol->SmbiosCreateChassisData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE3_STRUCTURE && UPDATE_SYSTEM_CHASSIS_TYPE3
+#if (TYPE4_STRUCTURE && UPDATE_CPU_TYPE4)
+ if (UpdateCpuStructure) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateCPUData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // TYPE4_STRUCTURE && UPDATE_CPU_TYPE4
+#if (TYPE9_STRUCTURE && UPDATE_SLOT_TYPE9)
+ Status = gSmbiosBoardProtocol->SmbiosCreateSystemSlotData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE9_STRUCTURE && UPDATE_SLOT_TYPE9
+#if (TYPE10_STRUCTURE && UPDATE_ONBOARD_DEV_TYPE10)
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevData();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE10_STRUCTURE && UPDATE_ONBOARD_DEV_TYPE10
+#if (TYPE22_STRUCTURE && UPDATE_BATTERY_TYPE22)
+ if (gSmbiosBoardProtocol->PortableBatteryInfoSupport) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateBatteryDevData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // TYPE22_STRUCTURE && UPDATE_BATTERY_TYPE22
+#if (TYPE41_STRUCTURE && UPDATE_DEVICE_EXT_TYPE41)
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevExtInfo();
+ ASSERT_EFI_ERROR(Status);
+#endif // TYPE41_STRUCTURE && UPDATE_DEVICE_EXT_TYPE41
+#endif // SMBIOS_DYNAMIC_UPDATE_POLICY == 0
+
+#if BIOS_LANGUAGE_INFO
+ AddUpdateType13();
+#endif // BIOS_LANGUAGE_INFO
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 0
+TRACE((-1, "*** Before DynamicUpdateStructures (SMBIOS_DYNAMIC_UPDATE_POLICY = 0) ***\n"));
+ DynamicUpdateStructures(SmbiosDataTable);
+TRACE((-1, "*** After DynamicUpdateStructures (SMBIOS_DYNAMIC_UPDATE_POLICY = 0) ***\n"));
+#endif // SMBIOS_DYNAMIC_UPDATE_POLICY
+
+ // Call OEM porting hook in SmbiosBoard.c - OEM can make changes
+ // to the SMBIOS table in this hook
+ gSmbiosBoardProtocol->OemUpdate();
+
+#if SMBIOS_UPDATE_POLICY == 1
+TRACE((-1, "*** Before UpdateStructuresWithNvramData (SMBIOS_UPDATE_POLICY = 1) ***\n"));
+ UpdateStructuresWithNvramData(SmbiosDataTable, MaximumTableSize);
+TRACE((-1, "*** After UpdateStructuresWithNvramData (SMBIOS_UPDATE_POLICY = 1) ***\n"));
+#endif // SMBIOS_UPDATE_POLICY
+
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT != 0))
+#if PI_SPECIFICATION_VERSION < 0x10014
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiLegacyRegionProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->HandleProtocol(HandleBuffer[0],
+ &gEfiLegacyRegionProtocolGuid,
+ &LegacyRegionProtocol);
+ pBS->FreePool(HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+ }
+#else
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiLegacyRegion2ProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->HandleProtocol(HandleBuffer[0],
+ &gEfiLegacyRegion2ProtocolGuid,
+ &LegacyRegionProtocol);
+ pBS->FreePool(HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // PI_SPECIFICATION_VERSION
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ &NumberOfHandles,
+ &HandleBuffer);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pBS->HandleProtocol(HandleBuffer[0],
+ &gEfiLegacyBiosProtocolGuid,
+ &LegacyBiosProtocol);
+
+ pBS->FreePool(HandleBuffer);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+#if (defined(ITK_SUPPORT) && (ITK_SUPPORT != 0)) || (SMBIOS_TABLE_LOCATION)
+ {
+ UINT8 *SmbiosE000Ptr;
+
+ if (LegacyRegionProtocol != NULL) {
+ Status = SmbiosE000Alloc(&SmbiosE000Ptr, MaximumTableSize);
+
+ // If success, relocate table
+ if (!EFI_ERROR(Status)) {
+ TRACE((-1, "*** SmbiosE000Alloc success ***\n"));
+ Status = LegacyRegionProtocol->UnLock(LegacyRegionProtocol,
+ (UINT32)SmbiosE000Ptr,
+ MaximumTableSize,
+ NULL);
+
+ if (!EFI_ERROR(Status)) {
+ TRACE((-1, "*** E000 unlocked, copying Smbios Table to E000 ***\n"));
+ MemCpy(SmbiosE000Ptr, SmbiosDataTable, MaximumTableSize);
+ pBS->FreePool(SmbiosDataTable);
+ SmbiosDataTable = SmbiosE000Ptr;
+ SmbiosTableAtE000 = TRUE;
+
+ LegacyRegionProtocol->Lock(LegacyRegionProtocol,
+ (UINT32)SmbiosE000Ptr,
+ MaximumTableSize,
+ NULL);
+ TRACE((-1, "*** E000 locked ***\n"));
+ }
+ }
+ }
+ }
+#endif // ITK_SUPPORT || SMBIOS_TABLE_LOCATION
+
+#if (CSM16_VERSION_MINOR >= 64)
+ {
+ if (LegacyRegionProtocol != NULL) {
+ LegacyRegionProtocol->UnLock(LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+
+ TRACE((-1, "*** F000 unlocked ***\n"));
+
+ Legacy16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xf0000 + *(UINT16*)0xfff4c);
+
+ if (*(UINT32*)(0xf0000 + Legacy16Data->Compatibility16TableOfs) == (UINT32)'$EFI') {
+ SMBIOS_TABLE_ENTRY_POINT *TempPtr;
+
+ TempPtr = pSmbiosTableEntryPoint;
+ pSmbiosTableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT*)(0xf0000 + Legacy16Data->SmbiosTableOfs);
+
+ TRACE((-1, "*** Smbios Table Entry Point = %x ***\n", pSmbiosTableEntryPoint));
+
+ MemCpy(pSmbiosTableEntryPoint, TempPtr, sizeof(SMBIOS_TABLE_ENTRY_POINT));
+ }
+
+ LegacyRegionProtocol->Lock(LegacyRegionProtocol,
+ 0xf0000,
+ 0x10000,
+ NULL);
+ }
+ }
+#endif // CSM16_VERSION_MINOR >= 64
+
+ TRACE((-1, "*** Installing 16bit PnP Smbios Functions ***\n"));
+
+ Install16bitPnPSmbiosFunctions();
+#endif // CSM_SUPPORT
+
+ // Updating EPS Header
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+
+ // Update EFI Configuration Table
+ Status = pBS->InstallConfigurationTable(&SmbiosGuid, pSmbiosTableEntryPoint);
+ ASSERT_EFI_ERROR(Status);
+
+#if (defined(SB_WAKEUP_TYPE_FN) && (SB_WAKEUP_TYPE_FN == 1))
+{
+ //
+ // If S4/S5 resume, update System Information structure (Type 1)
+ // Wake-up Type field with detected wake-up source type.
+ //
+
+ UINT8 *Buffer;
+ UINT8 *FoundPtr = NULL;
+ EFI_BOOT_MODE BootMode;
+
+ BootMode = GetBootMode();
+
+ if ((BootMode == BOOT_ON_S4_RESUME) || (BootMode == BOOT_ON_S5_RESUME)) {
+ Buffer = SmbiosDataTable;
+
+ if (FindStructureType(&Buffer, &FoundPtr, 1, 1)) {
+ FoundPtr += 0x18;
+
+ if ((UINT32)FoundPtr < 0xfffff) {
+ OemRuntimeShadowRamWrite(TRUE);
+ }
+
+ *(UINT8*)FoundPtr = getWakeupTypeForSmbios();
+
+ if ((UINT32)FoundPtr < 0xfffff) {
+ OemRuntimeShadowRamWrite(FALSE);\
+ }
+ }
+ }
+}
+#endif // SB_WAKEUP_TYPE_FN
+
+#if defined iAMT_SUPPORT && iAMT_SUPPORT == 1
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ AmtNotifyEventFunction,
+ NULL,
+ &EfiSmbiosAmtDataGuid,
+ &SigEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->SignalEvent(SigEvent);
+ pBS->CloseEvent(SigEvent);
+#endif // iAMT_SUPPORT
+
+// Added for TPM
+ Status = pBS->CreateEventEx(
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ NotifyEventFunction,
+ NULL,
+ &EfiSmbiosTblPubGuid,
+ &SmbiosTableEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ pBS->SignalEvent(SmbiosTableEvent);
+ pBS->CloseEvent(SmbiosTableEvent);
+
+ TRACE((-1, "::: Exitting SmbiosDynamicUpdate :::\n"));
+}
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateDynamicStructures
+//
+// Description: Update structures dynamically
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateDynamicStructures(
+ VOID)
+{
+#if UPDATE_BASEBOARD_TYPE2 || \
+ UPDATE_SYSTEM_CHASSIS_TYPE3 || \
+ UPDATE_CPU_TYPE4 || \
+ UPDATE_SLOT_TYPE9 || \
+ UPDATE_ONBOARD_DEV_TYPE10 || \
+ UPDATE_BATTERY_TYPE22 || \
+ UPDATE_DEVICE_EXT_TYPE41
+ EFI_STATUS Status;
+#endif
+
+ TRACE((-1, "*** SMBIOS - UpdateDynamicStructures ***\n"));
+
+#if UPDATE_BASEBOARD_TYPE2
+ Status = gSmbiosBoardProtocol->SmbiosCreateBaseBoardData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_BASEBOARD_TYPE2
+#if UPDATE_SYSTEM_CHASSIS_TYPE3
+ Status = gSmbiosBoardProtocol->SmbiosCreateChassisData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_SYSTEM_CHASSIS_TYPE3
+#if UPDATE_CPU_TYPE4
+ if (UpdateCpuStructure) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateCPUData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // UPDATE_CPU_TYPE4
+#if UPDATE_SLOT_TYPE9
+ Status = gSmbiosBoardProtocol->SmbiosCreateSystemSlotData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_SLOT_TYPE9
+#if UPDATE_ONBOARD_DEV_TYPE10
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevData();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_ONBOARD_DEV_TYPE10
+#if UPDATE_BATTERY_TYPE22
+ if (gSmbiosBoardProtocol->PortableBatteryInfoSupport) {
+ Status = gSmbiosBoardProtocol->SmbiosCreateBatteryDevData();
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif // UPDATE_BATTERY_TYPE22
+#if UPDATE_DEVICE_EXT_TYPE41
+ Status = gSmbiosBoardProtocol->SmbiosCreateOnBoardDevExtInfo();
+ ASSERT_EFI_ERROR(Status);
+#endif // UPDATE_DEVICE_EXT_TYPE41
+
+ DynamicUpdateStructures(SmbiosDataTable);
+
+ TRACE((-1, "::: SMBIOS - Exit UpdateDynamicStructures :::\n"));
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosDriverEntryPoint
+//
+// Description: SMBIOS driver entry point
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ UINT8 *Buffer = NULL;
+ UINT8 *BufferPtr;
+ UINTN BufferSize;
+ UINT8 *TempPtr = NULL;
+ UINT16 Size;
+ EFI_EVENT ReadyToBootEvent;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ TRACE((-1, "In SmbiosDriverEntryPoint\n"));
+
+ // Allocate runtime buffer for Smbios Table Entry Point
+ pBS->AllocatePool(EfiRuntimeServicesData, sizeof(SMBIOS_TABLE_ENTRY_POINT), &pSmbiosTableEntryPoint);
+ MemCpy(pSmbiosTableEntryPoint, &SmbiosEntryPointTable, sizeof(SMBIOS_TABLE_ENTRY_POINT));
+
+ Status = pBS->LocateProtocol(&gEfiSmbiosBoardProtocolGuid,
+ NULL,
+ &gSmbiosBoardProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ // Get SMBios Data Structure Image
+ Status = LoadRealModeFileSection(&gEfiSmbiosStaticData, \
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID, &Buffer, &BufferSize);
+ if (EFI_ERROR(Status)) return Status;
+ BufferPtr = Buffer;
+
+ // Skip over Section GUID
+ BufferPtr += sizeof (EFI_GUID);
+ BufferSize -= sizeof (EFI_GUID);
+
+ UpdateType127Handle(BufferPtr);
+
+ SmbiosDataTable = BufferPtr;
+ TempPtr = BufferPtr;
+ MaximumTableSize = (UINT16)BufferSize;
+
+ // Set UpdateCpuStructure flag to FALSE if CPU type 4 structure does not exist
+ Status = ReadStructureByType(4, 1, &TempPtr, &Size);
+ if (EFI_ERROR(Status)) {
+ // CPU type 4 structure not found
+ UpdateCpuStructure = FALSE;
+ }
+ else {
+ UpdateCpuStructure = TRUE;
+ pBS->FreePool(TempPtr); // TempPtr from ReadStructureByType
+ }
+
+ // Update structures with NVRAM data
+#if (defined(SmbiosDMIEdit_SUPPORT) && (SmbiosDMIEdit_SUPPORT !=0))
+ #if SMBIOS_UPDATE_POLICY == 0
+TRACE((-1, "Before UpdateStructuresWithNvramData\n"));
+ UpdateStructuresWithNvramData(BufferPtr, BufferSize);
+TRACE((-1, "After UpdateStructuresWithNvramData\n"));
+ #endif
+#endif
+
+ // Allocate Runtime buffer and copy the SMBios Data Structures there
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, MaximumTableSize, &SmbiosDataTable);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ MemCpy(SmbiosDataTable, BufferPtr, MaximumTableSize);
+ pBS->FreePool(Buffer);
+
+#if ( defined(SMBIOS_PI_1_1) && (SMBIOS_PI_1_1 == 1) )
+ // Initialize Producer Handle table and set ProducerHandle
+ // for each Smbios record to Smbios Driver Image Handle
+ InitializeProducerHandleTable(ImageHandle);
+#endif
+
+ // Allocate scratch buffer
+ pBS->AllocatePool(EfiRuntimeServicesData, BufferSize, &ScratchBufferPtr);
+ if (EFI_ERROR(Status)) ScratchBufferPtr = NULL;
+
+ // Updating EPS Header
+ UpdateEPSHeader(pSmbiosTableEntryPoint);
+
+#if SMBIOS_DYNAMIC_UPDATE_POLICY == 1
+ TRACE((-1, "Before UpdateDynamicStructures\n"));
+ // Update dynamic structures
+ UpdateDynamicStructures();
+ TRACE((-1, "After UpdateDynamicStructures\n"));
+#endif
+
+ TRACE((-1, "Registering SmbiosDynamicUpdate callback on ReadyToBoot\n"));
+ //
+ // Register the event handling function to dynamically update
+ // structures.
+ //
+ Status = CreateReadyToBootEvent(TPL_CALLBACK,
+ SmbiosDynamicUpdate,
+ NULL,
+ &ReadyToBootEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->InstallProtocolInterface(&ImageHandle,
+ &gEfiSmbiosProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &SmbiosProtocol);
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((-1, "Exiting SmbiosDriverEntryPoint. Status = %r\n", Status));
+ return Status;
+}
+
+#if ( defined(CSM_SUPPORT) && (CSM_SUPPORT != 0) )
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Install16bitPnPSmbiosFunctions
+//
+// Description: SMBIOS 16-bit PnP runtime functions installation.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+Install16bitPnPSmbiosFunctions()
+{
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *BiosExtensions = NULL;
+ UINTN Dest;
+ UINT32 LockUnlockAddr;
+ UINT32 LockUnlockSize;
+ EFI_STATUS Status;
+ VOID *gImage;
+ UINTN ImageSize;
+ UINT16 *NewPnPFunctionPtr;
+
+ TRACE((-1, "In Install16bitPnPSmbiosFunctions\n"));
+
+ //
+ // Locate 16-bit binary and copy it to F000 segment.
+ //
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosExtProtocolGuid, NULL, &BiosExtensions);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "LegacyBiosExtProtocol not found. Exit\n"));
+ return Status;
+ }
+
+ Status = BiosExtensions->GetEmbeddedRom(
+ CSM16_MODULEID, CSM16_VENDORID, CSM16_PNP_RT_DID, &gImage, &ImageSize);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Embedded Rom not found. Exit\n"));
+ return Status;
+ }
+
+ Dest = BiosExtensions->CopyLegacyTable(gImage, (UINT16)ImageSize, 0, 1);
+ ASSERT(Dest);
+
+ Legacy16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xf0000 + *(UINT16*)0xfff4c);
+ (UINTN)NewPnPFunctionPtr = 0xf0000 + Legacy16Data->AddedPnpFunctionsOfs;
+
+ if (Dest != NULL) {
+ BiosExtensions->UnlockShadow((UINT8*)(UINTN)0xf0000, 0x10000, &LockUnlockAddr, &LockUnlockSize);
+ *NewPnPFunctionPtr = (UINT16)Dest;
+ BiosExtensions->LockShadow(LockUnlockAddr, LockUnlockSize);
+
+ TRACE((-1, "Exit Install16bitPnPSmbiosFunctions\n"));
+ return EFI_SUCCESS;
+ }
+ else {
+ TRACE((-1, "Failed to copy embedded Rom. Exit\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+}
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SMBios.dxs b/Core/EM/SMBIOS/SMBios.dxs
new file mode 100644
index 0000000..c04ddc9
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBios.dxs
@@ -0,0 +1,142 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SMBios.dxs 13 1/06/12 3:25p Davidd $
+//
+// $Revision: 13 $
+//
+// $Date: 1/06/12 3:25p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SMBios.dxs $
+//
+// 13 1/06/12 3:25p Davidd
+// [TAG] EIP78790
+// [Category] Improvement
+// [Description] Locating LegacyRegion2 Protocol fails in SMBIOS31 when
+// Bios is Built with PI 1.1 or lesser
+// [Files] Smbios.c
+// Smbios.dxs
+//
+// 12 11/17/11 2:38p Davidd
+// [TAG] EIP74579
+// [Category] Improvement
+// [Description] Update SMBIOS moudule to let AMDELNX support SMBIOS
+// spec 2.7
+// (remove the 64 characters string limitation)
+// [Files] Smbios.h
+// SmbiosStaticData.sdl
+// Smbios.c
+// SMBios.dxs
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosNvram.c
+// SmbiosFlashData.sdl
+//
+// 11 10/06/11 5:34p Davidd
+// [TAG] EIP70095
+// [Category] Improvement
+// [Description] Microsoft CSM Opt-Out feature implementation
+// [Files] Smbios.dxs
+//
+// 10 8/30/11 4:12p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 9 5/13/11 5:21p Davidd
+// [TAG] EIP57758
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] DMIEDIT tool shows error message "Cann't update Smbios
+// Date with PNP function on current system!!" "Error getting DMI
+// data!!(Error code : 12000E)"
+// [RootCause] Because Smbios Structure Table Entry Point header is
+// relocated on ReadyToBoot, it could not be found at runtime.
+// [Solution] Allocate runtime memory for Smbios Structure Table
+// Entry Point header on Smbios driver entry point.
+// [Files] Smbios.c
+// Smbios.dxs
+//
+// 8 6/02/09 11:15a Davidd
+// Updated AMI header section (EIP 22180).
+//
+// 7 12/26/07 5:06p Olegi
+//
+// 6 3/29/07 5:57p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 5 3/14/07 1:18p Pavell
+// Changes for ITK support
+//
+// 4 3/21/06 8:41p Fasihm
+// Changed the protocol name FV.h to FirmwareVolume.h to be compatable
+// with the new Aptio 4.5 Core and later.
+//
+// 3 7/18/05 4:55p Davidd
+// Added new dependency on SMBIOS Board Protocol.
+//
+//
+//**********************************************************************//
+
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+#include <protocol\FirmwareVolume.h>
+#else
+#include <protocol\FirmwareVolume2.h>
+#endif
+#include <protocol\CPU.h>
+#include <protocol\PciRootBridgeIo.h>
+#include <protocol\SmbiosDynamicData.h>
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT == 1) && defined(AMI_CSM_DRIVER_STARTED_GUID))
+#include <Protocol\CsmPlatform.h>
+#endif
+
+DEPENDENCY_START
+#if (defined(CSM_SUPPORT) && (CSM_SUPPORT == 1) && defined(AMI_CSM_DRIVER_STARTED_GUID))
+ AMI_CSM_DRIVER_STARTED_GUID AND
+#endif
+ EFI_SMBIOS_BOARD_PROTOCOL_GUID AND
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL_GUID AND
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID AND
+#endif
+ EFI_CPU_ARCH_PROTOCOL_GUID AND
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SMBios.mak b/Core/EM/SMBIOS/SMBios.mak
new file mode 100644
index 0000000..3d4a5d4
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBios.mak
@@ -0,0 +1,99 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SMBios.mak 9 3/26/12 12:06p Davidd $
+#
+# $Revision: 9 $
+#
+# $Date: 3/26/12 12:06p $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SMBios.mak $
+#
+# 9 3/26/12 12:06p Davidd
+# [TAG] EIP84370
+# [Category] New Feature
+# [Description] Flash memory(type 16 and 17) on aptio
+# [Files] Smbdata.mac
+# SmbiosStaticData.asm
+# SmbiosStaticData.sdl
+# Smbios.c
+# Smbios.mak
+# Smbios.h
+#
+# 8 8/04/10 2:44p Davidd
+# Remove environment variables "MAKEFILE" and "INCLUDE" - EIP 40634.
+#
+# 7 4/06/10 10:30a Davidd
+#
+# 6 6/02/09 11:14a Davidd
+# Updated AMI header section.
+#
+# 5 12/30/08 3:21p Davidd
+# Changes added for x32 and x64 binary support.
+#
+# 4 1/22/08 4:27p Olegi
+#
+# 3 12/26/07 5:06p Olegi
+#
+# 2 3/29/07 5:56p Davidd
+# Changed the year in the AMI banner.
+#
+# 1 5/02/05 3:16p Davidd
+# Initial Check-in.
+#
+# 1 4/29/05 2:14p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+all : SMBIOS
+
+SMBIOS : $(BUILD_DIR)\SMBios.mak SMBiosBin
+
+SMBIOS_OBJECTS = $(BUILD_DIR)\CORE\EM\SMBIOS\smbios.obj
+
+$(BUILD_DIR)\SMBios.mak : $(SMBIOS_CORE_SRC_DIR)\SMBIOSCore.CIF $(SMBIOS_CORE_SRC_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMBIOS_CORE_SRC_DIR)\SMBIOSCore.CIF $(CIF2MAK_DEFAULTS)
+
+SMBiosBin : $(AMIDXELIB) $(FLASHLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SMBios.mak all\
+!IF "$(x64_BUILD)"=="1"
+ NAME=SMBios64 \
+!ELSE
+ NAME=SMBios32 \
+!ENDIF
+ MAKEFILE=$(BUILD_DIR)\SMBios.mak\
+ OBJECTS="$(SMBIOS_OBJECTS)" \
+ GUID=B13EDD38-684C-41ed-A305-D7B7E32497DF\
+ ENTRY_POINT=SmbiosDriverEntryPoint\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SMBiosCore.chm b/Core/EM/SMBIOS/SMBiosCore.chm
new file mode 100644
index 0000000..75168d4
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBiosCore.chm
Binary files differ
diff --git a/Core/EM/SMBIOS/SMBiosCoreSrc.sdl b/Core/EM/SMBIOS/SMBiosCoreSrc.sdl
new file mode 100644
index 0000000..a666d4c
--- /dev/null
+++ b/Core/EM/SMBIOS/SMBiosCoreSrc.sdl
@@ -0,0 +1,33 @@
+TOKEN
+ Name = "SMBIOS_CORE_SRC_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SMBIOS support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SMBIOS_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "SMBIOS_CORE_SRC_DIR"
+End
+
+MODULE
+ Help = "Includes SMBios.mak to Project"
+ File = "SMBios.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SMBios32.ffs"
+ Parent = "$(SMBIOS_DIR)\SMBios32.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "0"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SMBios64.ffs"
+ Parent = "$(SMBIOS_DIR)\SMBios64.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "1"
+End
+
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c
new file mode 100644
index 0000000..2e1eb93
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c
@@ -0,0 +1,792 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c 27 4/07/16 6:02p Davidd $
+//
+// $Revision: 27 $
+//
+// $Date: 4/07/16 6:02p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.c $
+//
+// 27 4/07/16 6:02p Davidd
+// [TAG] EIP231162
+// [Category] New Feature
+// [Description] Merge Aptio V Smbios -09 changes for Aptio 4
+// 4.6.5.5_SMBIOS_40 release
+// [Files] Smbios.c
+// SmbiosDmiEdit.c
+// SmbiosDmiEditFunc.c
+//
+// 26 4/04/16 11:43a Davidd
+// [TAG] EIP262865
+// [Category] Improvement
+// [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+// protocol is being changed to deny calls with Smm buffer
+// [Files] SmbiosDMIEdit.mak
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 25 2/17/15 1:15p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 24 11/15/13 4:33p Davidd
+// [TAG] EIP143321
+// [Category] Improvement
+// [Description] Perform "CppCheck" on Smbios module for
+// '4.6.5.1_SMBIOS_36' release
+// [Files] SmbiosBoard.c
+// Smbios.c
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 23 6/05/13 2:54p Davidd
+// [TAG] EIP125802
+// [Category] Improvement
+// [Description] Privilege escalation into SMM via SMBIOS SMM driver -
+// BugID 305325
+// [Files] SmbiosDMIEdit.c
+//
+// 22 6/08/12 6:00p Davidd
+// [TAG] EIP88664
+// [Category] New Feature
+// [Description] Need tool to update smbios information
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEditFunc.c
+//
+// 21 6/06/12 3:07p Davidd
+// [TAG] EIP81954
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] WriteOnceTable is not supported when
+// SMBIOS_DMIEDIT_DATA_LOC is 2
+// [RootCause] WriteOnce is not properly checked
+// [Solution] Changes added to check for WriteOnce status
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 20 12/19/11 11:23a Davidd
+// [TAG] EIP78619
+// [Category] Improvement
+// [Description] Customer and project name in SmbiosDMIEdit.c file
+// [Files] SmbiosDMIEdit.c
+//
+// 19 10/06/11 4:48p Davidd
+// EIP65648 extended change.
+//
+// 18 8/30/11 4:14p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 17 8/03/11 10:30a Davidd
+// [TAG] EIP63920
+// [Category] Bug Fix
+// [Severity] Non-Urgent
+// [Symptom] uEFI OS can't support DMI edit tool
+// [RootCause] UEFI OS runs in virtual memory mode. So call to
+// GetVariale will crash.
+// [Solution] Added call to InitSmmHandle so pRS will be properly
+// converted per Runtime Services Table in SMM mode.
+// [Files] SmbiosDMIEdit.c
+//
+// 16 3/16/11 3:35p Davidd
+// [TAG] EIP53939
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS DMIEdit Driver always assumes FLASH_BLOCK_SIZE =
+// 64KB
+// [RootCause] Block size was assumed to be 64K
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 15 5/18/10 5:11p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 14 6/02/09 11:18a Davidd
+// Updated function headers. (EIP 22180)
+//
+// 13 1/28/09 11:52a Davidd
+// New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 12 9/26/08 10:43a Davidd
+// Renamed shadow enable / disable functions.
+//
+// 11 11/27/07 10:26a Davidd
+//
+// 10 11/19/07 11:53a Robert
+//
+// 9 10/22/07 4:27p Davidd
+// Fixed a hanging problem with DMIEdit running on server2003 64bit SP2 -
+// EIP 10754
+//
+// 8 3/29/07 6:06p Davidd
+// Changed the year in the AMI banner.
+//
+// 7 12/15/06 5:42p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 6 3/21/06 8:43p Fasihm
+// Added the directives for DevicePath.h to build and changed the protocol
+// names to be compatable with the new Aptio 4.5 Core and later.
+//
+// 5 3/02/06 1:55p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+// 4 8/10/05 10:40a Davidd
+// Added code to call porting hooks to enable/disable F000 shadow to allow
+// updating the SMBIOS Entry Point header.
+//
+// 3 7/20/05 1:22p Davidd
+// Corrected build error with the last change made to detect which CPU is
+// running.
+//
+// 2 7/12/05 11:20a Markw
+// Add code to detect which CPU is executing.
+//
+// 1 4/29/05 2:06p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <AmiHobs.h>
+#include <Smm.h>
+#include <AmiSmm.h>
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ #include <Protocol\SmmCpu.h>
+ #include <Protocol\SmmBase2.h>
+ EFI_SMM_SYSTEM_TABLE2 *mSmst;
+#else
+ #include <Protocol\SmmBase.h>
+ EFI_SMM_SYSTEM_TABLE *mSmst;
+#endif
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\LoadedImage.h>
+#include "Protocol\Smbios.h"
+#include "SmbiosDMIEdit.h"
+
+#define SMBIOS_SIG (UINT32)'_MS_'
+
+extern SMBIOS_TABLE_ENTRY_POINT *SmbiosTableEntryPoint;
+extern UINT8 *ScratchBufferPtr;
+extern UINT16 MaximumBufferSize;
+extern BOOLEAN SwSmiMethod;
+
+extern VOID EnableShadowWrite();
+extern VOID DisableShadowWrite();
+
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || (SMBIOS_DMIEDIT_DATA_LOC != 2)
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\SmiFlash.h>
+#include <Protocol\FlashProtocol.h>
+
+EFI_GUID gSmbiosFlashDataProtocolGuid = EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID;
+EFI_SMBIOS_FLASH_DATA_PROTOCOL *mSmbiosFlashDataProtocol;
+EFI_SMI_FLASH_PROTOCOL *mSmiFlash;
+FLASH_PROTOCOL *mFlash = NULL;
+
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+EFI_GUID FlashProtocolGuid = FLASH_PROTOCOL_GUID;
+FLASH_PROTOCOL *FlashProtocol;
+#endif // NonSmiDmiEdit_Support
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+#if AmiBufferValidationLib_SUPPORT
+ #include <Include/AmiBufferValidationLib.h>
+
+ extern EFI_STATUS EFIAPI InitAmiBufferValidationLib(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable);
+ extern EFI_STATUS AmiValidateMemoryBuffer(VOID* Buffer, UINTN BufferSize);
+#else
+ EFI_PHYSICAL_ADDRESS TsegStart = 0;
+ EFI_PHYSICAL_ADDRESS TsegEnd = 0;
+#endif
+
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+EFI_GUID gEfiAmiDmieditSmbiosProtocolGuid = AMI_DMIEDIT_SMBIOS_GUID;
+
+EFI_SMBIOS_DMIEDIT_PROTOCOL SmbiosDmieditProtocol = {DmiEditNonSmiHandler};
+#endif // NonSmiDmiEdit_Support
+
+VOID WriteOnceStatusInit(VOID);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosTableF000
+//
+// Description: Searches 0x0F0000 for the SMBIOS signature and fills in the
+// SmbiosTableEntryPoint once it has been found
+//
+// Input: None
+//
+// Output: None
+//
+// Modified: SmbiosTableEntryPoint -is modified if table entry point found
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetSmbiosTableF000 (VOID)
+{
+ UINT32 *ptr32;
+ UINT16 i;
+ static BOOLEAN NotDone = TRUE;
+
+ if (NotDone) {
+ ptr32 = (UINT32*)0xF0000;
+ for (i = 0; i < (0x10000 / 16); i++) {
+ if (*ptr32 == SMBIOS_SIG) {
+ SmbiosTableEntryPoint = (SMBIOS_TABLE_ENTRY_POINT*)ptr32;
+ NotDone = FALSE;
+ break;
+ }
+
+ ptr32 += 4;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckAddress
+//
+// Description: Check address to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Function - DMIEdit function
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// DMI_BAD_PARAMETER - Access denied!
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+CheckAddress (
+ IN UINT8 *Address,
+ IN UINT8 Function
+)
+{
+ UINT16 Status = EFI_SUCCESS;
+
+#if AmiBufferValidationLib_SUPPORT
+{
+ if (AmiValidateMemoryBuffer(Address, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ else {
+ switch(Function) {
+ case 0x50: {
+ if (AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->DmiBiosRevision32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->NumStructures32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->StructureSize32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->DmiStorageBase32BitAddr, 1) |
+ AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_INFO*)Address)->DmiStorageSize32BitAddr, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ break;
+ }
+ case 0x51: {
+ if (AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_STRUCTURE*)Address)->Handle32BitAddr, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if (AmiValidateMemoryBuffer((UINT8*)((GET_SMBIOS_STRUCTURE*)Address)->Buffer32BitAddr, 1)) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+#else
+{
+ if (TsegStart != 0) {
+ //
+ // Check address against TSEG
+ //
+ if ((EFI_PHYSICAL_ADDRESS)Address >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)Address <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ else {
+ switch(Function) {
+ case 0x50: {
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiBiosRevision32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiBiosRevision32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->NumStructures32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->NumStructures32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->StructureSize32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->StructureSize32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageBase32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageBase32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageSize32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_INFO*)Address)->DmiStorageSize32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ break;
+ }
+ case 0x51: {
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Handle32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Handle32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ if ((EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Buffer32BitAddr) >= TsegStart &&
+ (EFI_PHYSICAL_ADDRESS)(((GET_SMBIOS_STRUCTURE*)Address)->Buffer32BitAddr) <= TsegEnd) {
+ Status = DMI_BAD_PARAMETER;
+ }
+ }
+ }
+ }
+ }
+
+ return Status;
+}
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmiHandler
+//
+// Description: Handles the SMI
+//
+// Input: IN EFI_HANDLE DispatchHandle
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+SmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINT8 Data;
+ VOID *pInterface;
+ UINTN i;
+ UINT16 RetStatus;
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ UINTN Cpu = mSmst->CurrentlyExecutingCpu; // For PI 1.1
+ EFI_GUID SmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+ EFI_SMM_CPU_PROTOCOL *SmmCpuProtocol;
+#else
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState;
+ UINTN Cpu = mSmst->CurrentlyExecutingCpu - 1;
+#endif
+
+ GetSmbiosTableF000();
+
+ for (i = 0; i < mSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&mSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ // If found table, check for the CPU that caused the software Smi.
+ if (i != mSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = mSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ mSmst->SmmLocateProtocol(
+ &SmmCpuProtocolGuid,
+ NULL,
+ &SmmCpuProtocol
+ );
+
+ pInterface = 0; // Clear upper 64-bits.
+ SmmCpuProtocol->ReadSaveState(
+ SmmCpuProtocol,
+ 4,
+ EFI_SMM_SAVE_STATE_REGISTER_RBX,
+ Cpu,
+ &pInterface
+ );
+#else
+ pCpuSaveState = mSmst->CpuSaveState;
+ pInterface = (void*)pCpuSaveState[Cpu].Ia32SaveState.EBX;
+#endif
+
+ SwSmiMethod = TRUE;
+
+ Data = (UINT8)DispatchContext->SwSmiInputValue;
+
+ RetStatus = CheckAddress(pInterface, Data);
+
+ if (RetStatus == EFI_SUCCESS) {
+ switch(Data) {
+ case 0x50:
+ RetStatus = GetSmbiosInfo(pInterface);
+ break;
+ case 0x51:
+ RetStatus = GetSmbiosStructure(pInterface);
+ break;
+ case 0x52:
+ EnableShadowWrite();
+ RetStatus = SetSmbiosStructure(pInterface);
+ DisableShadowWrite();
+ }
+ }
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ SmmCpuProtocol->WriteSaveState(
+ SmmCpuProtocol,
+ 2,
+ EFI_SMM_SAVE_STATE_REGISTER_RAX,
+ Cpu,
+ &RetStatus
+ );
+#else
+ (UINT16)pCpuSaveState[Cpu].Ia32SaveState.EAX = RetStatus;
+#endif
+}
+
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DmiEditNonSmiHandler
+//
+// Description: Handles the SMI
+//
+// Input: IN UINT8 Data
+// IN UINT64 pCommBuff
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+DmiEditNonSmiHandler(
+ IN UINT8 Data,
+ IN UINT64 pCommBuff
+)
+{
+ UINT32 eax;
+ VOID *pInterface;
+
+ TRACE((-1, "SMISMBIOSHandler Data: 0x%X \n",Data));
+ pInterface = (void*)pCommBuff;
+
+ GetSmbiosTableF000();
+
+ SwSmiMethod = FALSE;
+
+ switch(Data) {
+ case 0x50:
+ eax = GetSmbiosInfo(pInterface);
+ TRACE((-1, "eax : 0x%X \n",eax));
+ break;
+ case 0x51:
+ eax = GetSmbiosStructure(pInterface);
+ TRACE((-1, "eax : 0x%X \n",eax));
+ break;
+ case 0x52:
+ EnableShadowWrite();
+ eax = SetSmbiosStructure(pInterface);
+ DisableShadowWrite();
+ TRACE((-1, "eax : 0x%X \n",eax));
+ }
+ return eax;
+}
+#endif // NonSmiDmiEdit_Support
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NotInSmmFunction
+//
+// Description: Performs non-smi initialization
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NotInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+ EFI_STATUS Status;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = pBS->LocateProtocol (&FlashProtocolGuid, NULL, &FlashProtocol);
+ ASSERT_EFI_ERROR(Status);
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiAmiDmieditSmbiosProtocolGuid,&SmbiosDmieditProtocol,
+ NULL
+ );
+
+ return Status;
+#endif // NonSmiDmiEdit_Support
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description: Initialize pointers and register SW SMI handlers for
+// DMIEdit support.
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
+#if REGISTER_SW_SMI_FN50 || REGISTER_SW_SMI_FN51 || REGISTER_SW_SMI_FN52
+ EFI_HANDLE SwHandle;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+#endif
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ EFI_SMM_BASE2_PROTOCOL *SmmBase;
+ EFI_GUID gEfiSmmBaseProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
+#else
+ EFI_SMM_BASE_PROTOCOL *SmmBase;
+ EFI_GUID gEfiSmmBaseProtocolGuid = EFI_SMM_BASE_PROTOCOL_GUID;
+#endif
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+ EFI_GUID gFlashSmmProtocolGuid = FLASH_SMM_PROTOCOL_GUID;
+
+ Status = pBS->LocateProtocol (&gEfiSmiFlashProtocolGuid, NULL, &mSmiFlash);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gFlashSmmProtocolGuid, NULL, &mFlash);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+#if AmiBufferValidationLib_SUPPORT
+ Status = InitAmiBufferValidationLib(ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+#endif
+
+ Status = pBS->LocateProtocol (&gEfiSmmBaseProtocolGuid, NULL, &SmmBase);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ SmmBase->GetSmstLocation (SmmBase, &mSmst); // Save the system table pointer
+
+ // Register the SW SMI handler
+ Status = pBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid, NULL, &SwDispatch);
+ ASSERT_EFI_ERROR(Status);
+
+#if REGISTER_SW_SMI_FN50
+ SwContext.SwSmiInputValue = 0x50;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext, &SwHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+
+#if REGISTER_SW_SMI_FN51
+ SwContext.SwSmiInputValue = 0x51;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext, &SwHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+
+#if REGISTER_SW_SMI_FN52
+ SwContext.SwSmiInputValue = 0x52;
+ Status = SwDispatch->Register (SwDispatch, SmiHandler, &SwContext, &SwHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosDmiEditSupportInstall
+//
+// Description: DMIEdit support driver entry point
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosDmiEditSupportInstall(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmbiosProtocolGuid = EFI_SMBIOS_PROTOCOL_GUID;
+ EFI_SMBIOS_PROTOCOL *SmbiosProtocol;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ WriteOnceStatusInit();
+
+ Status = pBS->LocateProtocol (&gEfiSmbiosProtocolGuid, NULL, &SmbiosProtocol);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ SmbiosTableEntryPoint = SmbiosProtocol->SmbiosGetTableEntryPoint();
+ ScratchBufferPtr = SmbiosProtocol->SmbiosGetScratchBufferPtr();
+ MaximumBufferSize = SmbiosProtocol->SmbiosGetBufferMaxSize();
+
+#if !defined(AmiBufferValidationLib_SUPPORT) || (AmiBufferValidationLib_SUPPORT == 0)
+{
+ CPUINFO_HOB *CpuInfoHob = NULL;
+ EFI_GUID CpuInfoHobGuid = AMI_CPUINFO_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+
+ CpuInfoHob = (CPUINFO_HOB*)GetEfiConfigurationTable(pST, &HobListGuid);
+ if (CpuInfoHob != NULL) {
+ Status = FindNextHobByGuid(&CpuInfoHobGuid,(VOID**)&CpuInfoHob);
+ if (Status == EFI_SUCCESS) {
+ TsegStart = CpuInfoHob->TsegAddress;
+ TsegEnd = CpuInfoHob->TsegAddress + CpuInfoHob->TsegSize;
+ }
+ }
+}
+#endif
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = pBS->LocateProtocol (&gSmbiosFlashDataProtocolGuid, NULL, &mSmbiosFlashDataProtocol);
+ ASSERT_EFI_ERROR(Status);
+ mSmbiosFlashDataProtocol->GetFlashTableInfo(mSmbiosFlashDataProtocol, &gFlashData, &gFlashDataSize);
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+ InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NotInSmmFunction);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif
new file mode 100644
index 0000000..1018a94
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "SmbiosDMIEdit"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBios\SmbiosDMIEditSupport"
+ RefName = "SmbiosDMIEdit"
+[files]
+"SmbiosDMIEdit.sdl"
+"SmbiosDMIEdit.mak"
+"SmbiosDMIEdit.dxs"
+"SmbiosDMIEdit.h"
+"SmbiosDMIEdit.c"
+"SmbiosDMIEditFunc.c"
+"SmbiosNvramFunc.c"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs
new file mode 100644
index 0000000..1f2335a
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs
@@ -0,0 +1,78 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs 5 5/18/10 5:10p Davidd $
+//
+// $Revision: 5 $
+//
+// $Date: 5/18/10 5:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.dxs $
+//
+// 5 5/18/10 5:10p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 4 1/28/09 11:51a Davidd
+// - Updated AMI header block
+// - New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 3 3/29/07 6:01p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 2 3/02/06 1:58p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+//
+//**********************************************************************
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\SmiFlash.h>
+#endif
+
+#include <token.h>
+
+#include <Protocol\SmmBase.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\SmmSwDispatch.h>
+
+DEPENDENCY_START
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID AND
+ EFI_SMI_FLASH_GUID AND
+#endif
+ EFI_SMBIOS_PROTOCOL_GUID AND
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h
new file mode 100644
index 0000000..92b5f2a
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h
@@ -0,0 +1,377 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h 15 4/04/16 11:42a Davidd $
+//
+// $Revision: 15 $
+//
+// $Date: 4/04/16 11:42a $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.h $
+//
+// 15 4/04/16 11:42a Davidd
+// [TAG] EIP262865
+// [Category] Improvement
+// [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+// protocol is being changed to deny calls with Smm buffer
+// [Files] SmbiosDMIEdit.mak
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 14 6/12/12 11:28a Davidd
+// [TAG] EIP92073
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] "write once" not updating properly for multiple instances
+// of the same structure type using AMI DmiEdit tool
+// [RootCause] Write-once implementation only supported single instance
+// of a structure.
+// [Solution] Changes made to support more than one instance of a given
+// structure.
+// [Files] SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+//
+// 13 6/08/12 6:02p Davidd
+// [TAG] EIP88664
+// [Category] New Feature
+// [Description] Need tool to update smbios information
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEditFunc.c
+//
+// 12 11/17/11 2:39p Davidd
+// [TAG] EIP74579
+// [Category] Improvement
+// [Description] Update SMBIOS moudule to let AMDELNX support SMBIOS
+// spec 2.7
+// (remove the 64 characters string limitation)
+// [Files] Smbios.h
+// SmbiosStaticData.sdl
+// Smbios.c
+// SMBios.dxs
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosNvram.c
+// SmbiosFlashData.sdl
+//
+// 11 5/11/11 12:33p Davidd
+// [TAG] EIP58171
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible for AFU preserve DMI structure feature.
+// [RootCause] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible.
+// [Solution] New TABLE_INFO structure defined for backward
+// compatibility and support added.
+// [Files] Smbios.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+//
+// 10 11/02/10 4:13p Davidd
+// [TAG] EIP42938
+// [Category] BUG FIX
+// [Severity] Critical
+// [Symptom] The SMBIOS string field cannot be successfully updated
+// if it was programmed to Null by the 3-party SMBIOS tool
+// [RootCause] BIOS did not have support for NULL strings
+// [Solution] Problem has been fixed with code changes
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosDMIEdit.h
+// SmbiosFlashData.sdl
+//
+// 9 5/18/10 5:10p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 8 8/05/09 6:20p Davidd
+// Added DMIEDIT support for Type 0 and Type 12 structures - EIP 24878
+//
+// 7 1/28/09 11:52a Davidd
+// New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 6 1/03/08 12:30p Olegi
+// Fix in GET_SMBIOS_INFO structure for x64 projects.
+//
+// 5 3/29/07 6:02p Davidd
+// Changed the year in the AMI banner and clean up the code.
+//
+// 4 12/15/06 5:42p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 3 11/30/06 3:33p Davidd
+// Changes made for 64 bit support.
+//
+// 2 3/02/06 11:10a Davidd
+// Removed FLASH_START definition. Not needed.
+//
+// 1 4/29/05 2:06p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#ifndef _SmbiosDMIEdit_DRIVER_H
+#define _SmbiosDMIEdit_DRIVER_H
+
+#include <efi.h>
+#include <token.h>
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#include <Protocol/SmiFlash.h>
+#include <Protocol/FlashProtocol.h>
+#endif
+
+extern EFI_BOOT_SERVICES *pBS;
+
+UINT16 GetSmbiosInfo(GET_SMBIOS_INFO);
+UINT16 GetSmbiosStructure(GET_SMBIOS_STRUCTURE);
+UINT16 SetSmbiosStructure(SET_SMBIOS_STRUCTURE);
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SMBIOS_TABLE_ENTRY
+//
+// Description: SMBIOS Entry Point structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT32 AnchorString;
+ UINT8 EntryPointStructChecksum;
+ UINT8 EntryPointLength;
+ UINT8 MajorVersion;
+ UINT8 MinorVersion;
+ UINT16 MaximumStructSize;
+ UINT8 EntryPointRevision;
+ UINT8 FormattedArea[5];
+ UINT8 IntermediateAnchor[5];
+ UINT8 IntermediateChecksum;
+ UINT16 StructTableLength;
+ UINT32 StructTableAddress;
+ UINT16 NumStructs;
+ UINT8 SmbiosBCDRevision;
+} SMBIOS_TABLE_ENTRY;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: DMI_STRUC
+//
+// Description: Structure Header
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 Type;
+ UINT8 Length;
+ UINT16 Handle;
+} DMI_STRUC;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SET_SMBIOS_STRUCTURE_DATA
+//
+// Description: Set SMBIOS Structure Data
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 Command;
+ UINT8 FieldOffset;
+ UINT32 ChangeMask;
+ UINT32 ChangeValue;
+ UINT16 DataLength;
+ DMI_STRUC StructureHeader;
+ UINT8 StructureData[1];
+} SET_SMBIOS_STRUCTURE_DATA;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: GET_SMBIOS_INFO
+//
+// Description: Get SMBIOS Information
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT16 Function;
+ UINT32 DmiBiosRevision32BitAddr;
+ UINT32 NumStructures32BitAddr;
+ UINT32 StructureSize32BitAddr;
+ UINT32 DmiStorageBase32BitAddr;
+ UINT32 DmiStorageSize32BitAddr;
+ UINT16 BiosSelector; //Always 0.
+/////////////////////////////////////
+// The above pointers point below. //
+/////////////////////////////////////
+ UINT32 DmiBiosRevision;
+ UINT32 NumStructures;
+ UINT32 StructureSize;
+ UINT32 pDmiStorageBase;
+ UINT32 DmiStorageSize;
+} GET_SMBIOS_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: GET_SMBIOS_STRUCTURE
+//
+// Description: Get SMBIOS Structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT16 Function;
+ UINT32 Handle32BitAddr;
+ UINT32 Buffer32BitAddr;
+ UINT16 DmiSelector; //Always 0
+ UINT16 BiosSelector; //Always 0
+/////////////////////////////////////
+// The above pointers point below. //
+/////////////////////////////////////
+ UINT16 Handle;
+ UINT8 Buffer[1]; //Variable Length;
+} GET_SMBIOS_STRUCTURE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SET_SMBIOS_STRUCTURE
+//
+// Description: Set SMBIOS Structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT16 Function;
+ UINT32 Buffer32BitAddr;
+ UINT32 DmiWorkBuffer32BitAddr;
+ UINT8 Control; //?
+ UINT16 DmiSelector; //Always 0
+ UINT16 BiosSelector; //Always 0
+/////////////////////////////////////
+// The above pointers point below. //
+/////////////////////////////////////
+ SET_SMBIOS_STRUCTURE_DATA StructureData; //Variable Length;
+} SET_SMBIOS_STRUCTURE;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TABLE_INFO
+//
+// Description: DMI data record
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+#define DMIEDIT_WRITE_ONCE 0x01
+#define DMIEDIT_DELETE_STRUC 0x02
+#define DMIEDIT_ADD_STRUC 0x04
+#define DMIEDIT_EXTENDED_HDR 0x80
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset; // Structure field offset, or string number for Type 11 and 12
+ UINT8 Reserved; // Size of string including \0 or UUID (16)
+ UINT8 Flags; // Bit0 = Write Once
+ // Bit1 = Delete Structure
+ // Bit2 = Add structure
+ // Bit7 = Extended Header
+ UINT8 HdrLength;
+ UINT16 Size;
+ UINT16 Handle;
+} TABLE_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: WRITE_ONCE_TABLE
+//
+// Description: Write Once structure
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset;
+ BOOLEAN WriteOnce;
+} WRITE_ONCE_TABLE;
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset;
+ UINT16 Handle;
+} WRITE_ONCE_STATUS;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2 // FV_BB or FV_MAIN
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: FLASH_DATA_INFO
+//
+// Description: Flash Data Information
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT8 *Location;
+ UINT16 Size;
+ UINT8 *EndOfData;
+} FLASH_DATA_INFO;
+
+extern UINT8 *gBlockSave;
+extern VOID *gFlashData;
+extern UINT32 gFlashDataSize;
+extern EFI_SMI_FLASH_PROTOCOL *mSmiFlash;
+extern FLASH_PROTOCOL *mFlash;
+
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+#if (defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1))
+#define AMI_DMIEDIT_SMBIOS_GUID \
+ { 0x74211cd7, 0x3d8e, 0x496f, { 0xba, 0x2, 0x91, 0x9c, 0x2e, 0x1f, 0x6, 0xcb } }
+
+typedef struct _EFI_SMBIOS_DMIEDIT_PROTOCOL EFI_SMBIOS_DMIEDIT_PROTOCOL;
+
+typedef UINT32 (EFIAPI *DMIEDIT_NONSMI_HANDLER) (
+ IN UINT8 Data,
+ IN UINT64 pCommBuff
+);
+
+typedef struct _EFI_SMBIOS_DMIEDIT_PROTOCOL {
+ DMIEDIT_NONSMI_HANDLER DmiEditNonSmiHandler;
+};
+
+UINT32 DmiEditNonSmiHandler(
+ IN UINT8 Data,
+ IN UINT64 pCommBuff
+);
+#endif // NonSmiDmiEdit_Support
+
+#pragma pack()
+
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak
new file mode 100644
index 0000000..2c5a31f
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak
@@ -0,0 +1,145 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak 11 4/04/16 11:41a Davidd $
+#
+# $Revision: 11 $
+#
+# $Date: 4/04/16 11:41a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.mak $
+#
+# 11 4/04/16 11:41a Davidd
+# [TAG] EIP262865
+# [Category] Improvement
+# [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+# protocol is being changed to deny calls with Smm buffer
+# [Files] SmbiosDMIEdit.mak
+# SmbiosDMIEdit.h
+# SmbiosDMIEdit.c
+# SmbiosDMIEditFunc.c
+#
+# 10 11/14/12 5:01p Davidd
+#
+# 9 9/04/12 11:03a Davidd
+# [TAG] EIP96286
+# [Category] Improvement
+# [Description] Please help to reserve DMI Data for AFUDOS with /r in
+# Capsule Mode
+# [Files] Smbios.sdl
+# SmbiosDMIEdit.mak
+# SmbiosNvramFunc.c
+#
+# 8 8/28/12 11:17a Davidd
+# [TAG] EIP97178
+# [Category] Improvement
+# [Description] SMIFlash fails to build when SMBIOS_DMIEDIT_DATA_LOC =
+# 2
+# [Files] SmbiosDMIEdit.mak
+# SmbiosDMIEdit.sdl
+#
+# 7 4/06/10 3:29p Davidd
+# Added AMICSPLib path - EIP 33862
+#
+# 6 2/02/09 4:32p Davidd
+# - Updated AMI header.
+# - Changes added to build a libray function used to save and restore
+# DMIEdit data (when NVRAM is used for storage) prior to and after
+# flashing using SMIFlash.
+#
+# 5 7/23/08 12:36p Davidd
+# Changes made to build SmbiosDMIEditBoard.obj file.
+#
+# 3 3/29/07 5:58p Davidd
+# Changed the year in the AMI banner.
+#
+# 2 8/10/05 10:44a Davidd
+# Added command to copy the porting file SmbiosDMIEditBoard.c as building
+# the module.
+#
+# 1 4/29/05 2:06p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+all : SMBIOS_DMIEDIT_SUPPORT
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"=="2" && "$(SMBIOS_PRESERVE_NVRAM)"=="1"
+SMBIOS_DMIEDIT_SUPPORT : $(BUILD_DIR)\SmbiosDMIEdit.mak SmbiosDMIEditBin $(BUILD_DIR)\SmbiosNvram.lib
+!ELSE
+SMBIOS_DMIEDIT_SUPPORT : $(BUILD_DIR)\SmbiosDMIEdit.mak SmbiosDMIEditBin
+!ENDIF
+
+$(BUILD_DIR)\SmbiosNvram.lib : $(BUILD_DIR)\SmbiosDMIEdit.mak SmbiosNvramlib
+
+$(BUILD_DIR)\SmbiosDMIEdit.mak : $(SMBIOS_DMIEDIT_DIR)\$(@B).cif $(SMBIOS_DMIEDIT_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.cif
+
+$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditBoard.obj : $(SMBIOS_DMIEDIT_BOARD_DIR)\SmbiosDMIEditBoard.c
+ $(CC) $(CFLAGS:/W4=/W3) /Fo$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\ $(SMBIOS_DMIEDIT_BOARD_DIR)\SmbiosDMIEditBoard.c
+
+!IF "$(AmiBufferValidationLib_SUPPORT)"=="1"
+SMBIOSDMIEDIT_OBJECTS = $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.obj $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditFunc.obj $(BUILD_DIR)\AmiBufferValidationLib.lib
+!ELSE
+SMBIOSDMIEDIT_OBJECTS = $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.obj $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditFunc.obj
+!ENDIF
+
+SmbiosDMIEditBin : $(AMIDXELIB) $(AMICSPLib) $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEditBoard.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosDMIEdit.mak all\
+ "CFLAGS=$(CFLAGS:/W4=/W3)"\
+ NAME=SmbiosDMIEdit\
+ MAKEFILE=$(BUILD_DIR)\SmbiosDMIEdit.mak \
+ OBJECTS="$(SMBIOSDMIEDIT_OBJECTS)" \
+ GUID=E2A74738-8934-48f5-8412-99E948C8DC1B \
+ ENTRY_POINT=SmbiosDmiEditSupportInstall \
+ TYPE=BS_DRIVER \
+ DEPEX1=$(SMBIOS_DMIEDIT_DIR)\SmbiosDMIEdit.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+
+$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj : $(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.c
+ if not exist $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR) mkdir $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)
+ $(CC) $(CFLAGS:/W4=/W3) /Fo$(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\ $(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.c
+
+ReFlashBin : $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"=="2" && "$(SMBIOS_PRESERVE_NVRAM)"=="1"
+PRESERVE_LIB = $(PRESERVE_LIB) \
+ $(BUILD_DIR)\SmbiosNvram.lib
+
+SMBIOS_NVRAM_OBJECTS = $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+
+SmbiosNvramlib : $(BUILD_DIR)\$(SMBIOS_DMIEDIT_DIR)\SmbiosNvramFunc.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosDMIEdit.mak all\
+ "OBJECTS=$(SMBIOS_NVRAM_OBJECTS)"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\SmbiosNvram.lib
+!ENDIF
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl
new file mode 100644
index 0000000..7068b82
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEdit.sdl
@@ -0,0 +1,79 @@
+TOKEN
+ Name = "SmbiosDMIEdit_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AMI DMIEdit for SMBIOS support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "NonSmiDmiEdit_Support"
+ Value = "1"
+ Help = "Switch to disable/enable Non-SMI support"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DMI_ARRAY_COUNT"
+ Value = "256"
+ Help = "The maximum number of entires DMIEdit array can hold"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REGISTER_SW_SMI_FN50"
+ Value = "1"
+ Help = "Enable/Disable SW SMI Function 0x50 registration"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REGISTER_SW_SMI_FN51"
+ Value = "1"
+ Help = "Enable/Disable SW SMI Function 0x51 registration"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REGISTER_SW_SMI_FN52"
+ Value = "1"
+ Help = "Enable/Disable SW SMI Function 0x52 registration"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "SMBIOS_DMIEDIT_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosDMIEdit.mak to Project"
+ File = "SmbiosDMIEdit.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosDMIEdit.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(PRESERVE_LIB)"
+ Parent = "OFBDLISTLIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosNvram.lib"
+ Parent = "PRESERVE_LIB"
+ InvokeOrder = AfterParent
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "=" "2"
+ Token = "SMBIOS_PRESERVE_NVRAM" "=" "1"
+End \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c
new file mode 100644
index 0000000..6c1af45
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c
@@ -0,0 +1,4176 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c 69 4/07/16 6:03p Davidd $
+//
+// $Revision: 69 $
+//
+// $Date: 4/07/16 6:03p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosDMIEditFunc.c $
+//
+// 69 4/07/16 6:03p Davidd
+// [TAG] EIP231162
+// [Category] New Feature
+// [Description] Merge Aptio V Smbios -09 changes for Aptio 4
+// 4.6.5.5_SMBIOS_40 release
+// [Files] Smbios.c
+// SmbiosDmiEdit.c
+// SmbiosDmiEditFunc.c
+//
+// 68 4/04/16 11:43a Davidd
+// [TAG] EIP262865
+// [Category] Improvement
+// [Description] [APTIO4][Smbios]DmiEdit needs changes as smiflash
+// protocol is being changed to deny calls with Smm buffer
+// [Files] SmbiosDMIEdit.mak
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 67 11/25/14 12:50p Davidd
+// [TAG] EIP193846
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Generic changes for EIP187631
+// [RootCause] Function isWriteOnce is called even when the input
+// control is zero case (for validating the parameters)
+// [Solution] Excecute function isWriteOnce only if input control is set
+// [Files] SmbiosDMIEditFunc.c
+//
+// 66 8/11/14 10:46a Davidd
+// [TAG] EIP177887
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error if token "SYS_CHASSIS_INFO" set to "0"
+// [RootCause] Build error caused by non-existence token when
+// SYS_CHASSIS_INFO is disabled
+// [Solution] Added preprocessor checks
+// [Files] Smbios.c - File version: 153
+// SmbiosDmiEditFunc.c
+//
+// 65 8/08/14 3:50p Davidd
+// [TAG] EIP180676
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UUID Updated by 3rd party DMI/SMBIOS tools is not working.
+// [RootCause] UUID is updated 4 bytes at a time instead of 16
+// [Solution] Modified code to handle all update types (1, 2, or 4
+// bytes) as 16 bytes
+// [Files] SmbiosDMIEditFunc.c
+//
+// 64 12/05/13 12:05p Davidd
+//
+// 63 11/15/13 4:34p Davidd
+// [TAG] EIP143321
+// [Category] Improvement
+// [Description] Perform "CppCheck" on Smbios module for
+// '4.6.5.1_SMBIOS_36' release
+// [Files] SmbiosBoard.c
+// Smbios.c
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 62 10/07/13 1:23p Davidd
+// [TAG] EIP129122
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Purchase date is not updated in DMI Data area of NCB
+// [RootCause] Old data is not cleared when new data size is smaller
+// than existing one
+// [Solution] Clear old data when new data size is smaller than existing
+// one
+// [Files] SmbiosDMIEditFunc.c
+//
+// 61 9/25/13 2:51p Davidd
+// [TAG] EIP136093
+// [Category] New Feature
+// [Description] SMBIOS Type0 offest 04 can't update by AMIDEDOS
+// [Files] SmbiosDMIEditFunc.c
+//
+// 60 8/23/13 6:28p Davidd
+// [TAG] EIP132364
+// [Category] Improvement
+// [Description] DMIEdit fails to update in the following cases:
+// 1. When current string is NULL
+// 2. When structure is created by OEM
+// 3. When structure is created with strings not numbered sequentially
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+//
+// 59 6/03/13 6:26p Davidd
+// [TAG] EIP125665
+// [Category] New Feature
+// [Description] Request to Support multiple instances of SMBIOS Type 3
+// structure (merge EIP106206 into Aptio 4)
+// [Files] Smbdata.mac
+// SmbiosStaticData.sdl
+// Smbstruc.def
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbios.h
+//
+// 58 5/23/13 2:41p Davidd
+// [TAG] EIP104836
+// [Category] New Feature
+// [Description] DMIEdit support edit type 4
+// [Files] SmbiosBoard.c
+// SmbiosDMIEditBoard.sdl
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbios.h
+// SmbiosDynamicData.h
+//
+// 57 2/28/13 3:10p Davidd
+// [TAG] EIP115031
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] NVRAM data corruption
+// [RootCause] In UpdateSmbiosTable function, FlashDataOffset is
+// incorrectly calculated for certain case
+// [Solution] Corrected code.
+// [Files] SmbiosDMIEditFunc.c
+//
+// 56 1/16/13 10:49a Davidd
+// [TAG] EIP110905
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] AMI DMIEDIT_DOS tool issue (Type 11 fails to update)
+// [RootCause] Problem is caused by recent change for EIP96221 where a
+// line of code
+// was inadvertently left out when function SetType11 was
+// simplified
+// [Solution] Corrected missing code
+// [Files] SmbiosDMIEditFunc.c
+//
+// 55 8/02/12 12:45p Davidd
+// [TAG] EIP96064
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS: DmiEdit support creates NVRAM variables with names
+// of incorrect length
+// [RootCause] Swprintf_s function creates 15 characters variable name
+// with NULL terminator in last byte.
+// [Solution] Use Swprintf function instead
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 54 7/27/12 2:56p Davidd
+// [TAG] EIP96221
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Smbios DmiEdit: Nvram variables store extraneous data for
+// fixed-length structure change.
+// [RootCause] Input "DataLength" field is used for data size, but this
+// field is not valid for fixed-size data change
+// [Solution] Added code to determine data size based on input command
+// byte
+// [Files] SmbiosDMIEditFunc.c
+//
+// 53 6/12/12 3:54p Davidd
+// [TAG] EIP89994
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] UpdateSmbiosTable function in SmbiosDMIEdit.c seems have
+// problem to handle
+// [RootCause] Data not checked for cross boundary
+// [Solution] Added code to check for cross boundary and update flash
+// block accordingly.
+// [Files] SmbiosDMIEditFunc.c
+//
+// 52 6/12/12 11:30a Davidd
+// [TAG] EIP92073
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] "write once" not updating properly for multiple instances
+// of the same structure type using AMI DmiEdit tool
+// [RootCause] Write-once implementation only supported single instance
+// of a structure.
+// [Solution] Changes made to support more than one instance of a given
+// structure.
+// [Files] SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+//
+// 51 6/08/12 6:03p Davidd
+// [TAG] EIP88664
+// [Category] New Feature
+// [Description] Need tool to update smbios information
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEditFunc.c
+//
+// 50 6/06/12 3:09p Davidd
+// [TAG] EIP81954
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] WriteOnceTable is not supported when
+// SMBIOS_DMIEDIT_DATA_LOC is 2
+// [RootCause] WriteOnce is not properly checked
+// [Solution] Changes added to check for WriteOnce status
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 49 4/17/12 10:39a Davidd
+// [TAG] EIP86776
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Build error if "OEM_STRING_INFO" token is set to "0"
+// [RootCause] SMBIOS_OEM_STRINGS_INFO definition is used even when
+// OEM_STRING_INFO is disabled.
+// [Solution] Removed reference to "SMBIOS_OEM_STRINGS_INFO" in
+// "GetStructureLength" function (not really needed).
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+//
+// 48 11/17/11 2:41p Davidd
+// [TAG] EIP74579
+// [Category] Improvement
+// [Description] Update SMBIOS moudule to let AMDELNX support SMBIOS
+// spec 2.7
+// (remove the 64 characters string limitation)
+// [Files] Smbios.h
+// SmbiosStaticData.sdl
+// Smbios.c
+// SMBios.dxs
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosNvram.c
+// SmbiosFlashData.sdl
+//
+// 45 10/06/11 4:47p Davidd
+// EIP65648 extended change.
+//
+// 44 9/29/11 4:39p Davidd
+// [TAG] EIP68202
+// [Category] NEW FEATURE
+// [Description] Allow Smbios Type 2 Location field and Type 3 SKU
+// Number field
+// to be apdated by dmieditwingui tool
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// Smbdata.mac
+//
+// 43 8/30/11 4:14p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 42 8/03/11 10:53a Davidd
+// [TAG] EIP64029
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 22 to be modified using DMIEdit
+// [Files] Smbios.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+//
+// 41 5/11/11 12:34p Davidd
+// [TAG] EIP58171
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible for AFU preserve DMI structure feature.
+// [RootCause] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible.
+// [Solution] New TABLE_INFO structure defined for backward
+// compatibility and support added.
+// [Files] Smbios.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+//
+// 40 5/04/11 3:19p Davidd
+// [TAG] EIP57144
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 39 to be modified using DMIEdit
+// [Files] SmbiosBoard.c
+// Smbios.h
+// SmbiosDynamicData.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+// SmbiosNvramFunc.c
+//
+// 39 3/16/11 3:37p Davidd
+// [TAG] EIP53939
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMBIOS DMIEdit Driver always assumes FLASH_BLOCK_SIZE =
+// 64KB
+// [RootCause] Block size was assumed to be 64K
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+//
+// 38 3/02/11 11:45a Davidd
+// [TAG] EIP54264
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Data is assumed valid without checking after some
+// GetVariable calls
+// [RootCause] No error checking
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosNvramFunc.c
+// SmbiosDMIEditFunc.c
+//
+// 37 12/14/10 3:40p Davidd
+// Updated StringType_3 table to include SKU string field.
+//
+// 36 11/02/10 4:13p Davidd
+// [TAG] EIP42938
+// [Category] BUG FIX
+// [Severity] Critical
+// [Symptom] The SMBIOS string field cannot be successfully updated
+// if it was programmed to Null by the 3-party SMBIOS tool
+// [RootCause] BIOS did not have support for NULL strings
+// [Solution] Problem has been fixed with code changes
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosDMIEdit.h
+// SmbiosFlashData.sdl
+//
+// 35 10/21/10 11:36a Davidd
+// [TAG] EIP46394
+// [Category] BUG FIX
+// [Severity] Important
+// [Symptom] Incorrect variable size for GetVariable() usage in
+// Smbios module
+// [RootCause] GetVariable is called with incorrect "DataSize" type.
+// [Solution] Corrected "DataSize" type in all GetVariable calls.
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 34 5/18/10 5:13p Davidd
+// Added PnP function 52h commands 3 and 4 support - EIP 38010.
+//
+// 33 3/08/10 3:48p Davidd
+// Corrected Type1 UUID update problem with customer utility (update by
+// dword instead of block command) - EIP 35486
+//
+// 32 2/12/10 3:59p Davidd
+// Added conditional compile switch for Type 12 - EIP 34631
+// Same were added for Type 2, 3, and 11.
+//
+// 31 11/23/09 5:51p Davidd
+// Corrected the DMIEdit data not updated after being updated 5-6 times
+// (when NVRAM is used to store DMIEdit data) - EIP 30837.
+//
+// 30 8/05/09 6:19p Davidd
+// Added DMIEDIT support for Type 0 and Type 12 structures - EIP 24878
+//
+// 29 6/02/09 11:21a Davidd
+// Updated function headers. (EIP 22180)
+//
+// 28 2/13/09 10:43a Davidd
+// Changes made to return the SMBIOS table size in dmiStorageSize for
+// SMBIOS PnP function 50h (EIP 19115)
+//
+// 27 2/02/09 4:36p Davidd
+// Fixed the problem updating the existing DMIEdit data when FV_MAIN is
+// used for storage.
+//
+// 26 1/28/09 11:53a Davidd
+// New changes added to support DMIEdit data storage location in flash
+// selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+//
+// 25 12/16/08 2:24a Iminglin
+// (EIP17767) The function value of GetStructureByHandleThenUpdateHandle
+// for compliance.
+//
+// 24 11/14/08 3:29p Davidd
+// - Changed header blocks
+// - Corrected build error when NUMBER_OF_BLOCKS is a large number.
+//
+// 23 2/13/08 12:57p Davidd
+// Fixed getting SMBIOS structure type 127 problem.
+//
+// 22 1/03/08 12:30p Olegi
+// Fix in GET_SMBIOS_INFO structure for x64 projects.
+//
+// 21 11/26/07 11:39a Davidd
+// Changes added to allow "Asset Tag" in Type 2 structure to be updated
+// per EIP 11283.
+//
+// 20 9/06/07 10:55a Davidd
+// Undo the Rev. 18 check-in. UUID reversal problem is now corrected in
+// Smbios.c.
+//
+// 19 8/30/07 12:23p Davidd
+// Fixed bug writing to NVRAM with 1.5MB BIOS size.
+//
+// 18 8/10/07 12:44p Davidd
+// When updating the system UUID, new UUID is saved in NVRAM correctly but
+// the UUID is copied to memory in reverse order.
+//
+// 17 7/10/07 3:05p Davidd
+// Fixed bug for DMIEdit Type 12 support.
+//
+// 16 6/20/07 10:57a Pats
+// Modified to support editing of SMBIOS structure type 0, offsets 5 and
+// 8.
+//
+// 15 3/29/07 6:06p Davidd
+// Changed the year in the AMI banner and code cleanup.
+//
+// 14 2/21/07 4:30p Davidd
+// Fixed the hanging problem during updating DMI data using DMIEdit
+// (multiple times with long strings).
+//
+// 13 2/05/07 11:59a Davidd
+// Corrected resetting problem during updating DMI data with Dmiedit (seen
+// with Core 4.5.3).
+//
+// 12 12/15/06 5:46p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 11 11/03/06 11:57a Davidd
+// Added code to make Type 1 SKU and Family fields editable by DMIEdit
+// utility.
+//
+// 10 10/27/06 3:12p Davidd
+// Corrected the problem getting the string index in GetType1StringIndex
+//
+// 9 10/05/06 4:52p Davidd
+// Changes added for 64 bit support. Also use generic funtion MemCpy
+// rather than SmbiosMemCpy.
+//
+// 8 3/03/06 2:27p Davidd
+// Fixed the random hanging problem when using GetFlashInfo to get the
+// flash block size.
+//
+// 7 3/03/06 1:20p Davidd
+// In UpdateSmbiosTable, set the flash block size to
+// FLASH_BLOCK_SIZE SDL token.
+//
+// 6 3/02/06 1:57p Davidd
+// Updated include path to SMBios.h. It has been moved to
+// Include\Protocol
+//
+// 5 3/02/06 11:27a Davidd
+// Made some changes in the Update SmbiosTable routine to get the
+// flash information by calling the SMIFlash GetFlashInfo protocol rather
+// than hardcoding.
+//
+// 4 2/24/06 3:47p Davidd
+// Corrected the UUID data updated in reverse order (type 1 structure).
+//
+// 3 8/15/05 1:02p Davidd
+// Fixed the issue of updating DMI data when Debug_Mode is set to 0.
+//
+// 2 8/10/05 10:48a Davidd
+// Code cleanup.
+//
+// 1 4/29/05 2:06p Davidd
+// Initial checkin.
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include "SmbiosDMIEdit.h"
+#include "Protocol\Smbios.h"
+#include <Protocol\FlashProtocol.h>
+#include "AmiLib.h"
+
+#define FLASH_DEVICE_BASE (0xFFFFFFFF - FLASH_SIZE + 1)
+#define WRITE_ONCE_ENTRIES 0x10 // Maximum number of WRITE_ONCE_STATUS entries
+
+#if PI_SPECIFICATION_VERSION >= 0x0001000a && SMM_MINOR_VER >= 43
+ extern EFI_SMM_SYSTEM_TABLE2 *mSmst;
+#else
+ extern EFI_SMM_SYSTEM_TABLE *mSmst;
+#endif
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+extern FLASH_PROTOCOL *FlashProtocol;
+#endif // NonSmiDmiEdit_Support
+
+VOID *gFlashData;
+UINT32 gFlashDataSize;
+#else
+CHAR16 *DmiArrayVar = L"DmiArray";
+DMI_VAR DmiArray[DMI_ARRAY_COUNT] = {0};
+UINTN DmiArraySize = DMI_ARRAY_COUNT * sizeof(DMI_VAR);
+UINT8 *DmiData;
+UINTN DmiDataSize;
+CHAR16 *Var = L" ";
+UINT8 Index;
+#endif // SMBIOS_DMIEDIT_DATA_LOC
+
+EFI_GUID EfiSmbiosNvramGuid = EFI_SMBIOS_NVRAM_DATA_GUID;
+
+SMBIOS_TABLE_ENTRY_POINT *SmbiosTableEntryPoint = NULL;
+UINT8 *ScratchBufferPtr = NULL;
+UINT16 MaximumBufferSize;
+
+BOOLEAN SwSmiMethod;
+
+//
+// String type tables
+//
+STRING_TABLE StringType_0[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x08, 3, 3},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_1[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x19, 5, 5},
+ {0x1a, 6, 6},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_2[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x08, 5, 5},
+ {0x0a, 6, 6},
+ {0xff, 0, 0},
+ };
+
+#if (SYS_CHASSIS_INFO == 1)
+STRING_TABLE StringType_3[NUMBER_OF_SYSTEM_CHASSIS][6] =
+ {{{0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_1 * ELEMENT_LEN_1), 5, 5},
+ {0xff, 0, 0},
+ },
+#if NUMBER_OF_SYSTEM_CHASSIS > 1
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_2 * ELEMENT_LEN_2), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif
+#if NUMBER_OF_SYSTEM_CHASSIS > 2
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_3 * ELEMENT_LEN_3), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif
+#if NUMBER_OF_SYSTEM_CHASSIS > 3
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_4 * ELEMENT_LEN_4), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif
+#if NUMBER_OF_SYSTEM_CHASSIS > 4
+ {
+ {0x04, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x15 + (ELEMENT_COUNT_5 * ELEMENT_LEN_5), 5, 5},
+ {0xff, 0, 0},
+ },
+#endif
+ };
+#endif // #if (SYS_CHASSIS_INFO == 1)
+
+STRING_TABLE StringType_4[] = {{0x04, 1, 1},
+ {0x07, 2, 2},
+ {0x10, 3, 3},
+ {0x20, 4, 4},
+ {0x21, 5, 5},
+ {0x22, 6, 6},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_22[] = {{0x04, 1, 1},
+ {0x05, 2, 2},
+ {0x06, 3, 3},
+ {0x07, 4, 4},
+ {0x08, 5, 5},
+ {0x0e, 6, 6},
+ {0x14, 7, 7},
+ {0xff, 0, 0},
+ };
+
+STRING_TABLE StringType_39[] = {{0x05, 1, 1},
+ {0x06, 2, 2},
+ {0x07, 3, 3},
+ {0x08, 4, 4},
+ {0x09, 5, 5},
+ {0x0a, 6, 6},
+ {0x0b, 7, 7},
+ {0xff, 0, 0},
+ };
+
+//
+// String table
+//
+VOID* StringTable[] = {&StringType_0, // 0
+ &StringType_1, // 1
+ &StringType_2, // 2
+#if (SYS_CHASSIS_INFO == 1)
+ &StringType_3, // 3
+#endif // #if (SYS_CHASSIS_INFO == 1)
+ &StringType_4, // 4
+ &StringType_22, // 5
+ &StringType_39, // 6
+ };
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: WriteOnceTable
+//
+// Description: Table indicating which structure and offset can be written
+// only once or multiple times
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+WRITE_ONCE_TABLE WriteOnceTable[] = {
+ {1, 4, TRUE},
+ {2, 4, TRUE},
+ };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteOnceStatusInit
+//
+// Description: Initialize NVRAM variable holding WriteOnce statuses
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+WriteOnceStatusInit(VOID)
+{
+ EFI_STATUS Status;
+ WRITE_ONCE_STATUS *Buffer;
+ UINTN BufferSize;
+
+ BufferSize = WRITE_ONCE_ENTRIES * sizeof(WRITE_ONCE_STATUS);
+ pBS->AllocatePool(EfiBootServicesData, BufferSize, &Buffer);
+
+ // Create "WriteOnceStatus" variable if it does not exist
+ Status = pRS->GetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &BufferSize,
+ Buffer);
+
+ if (Status == EFI_NOT_FOUND) {
+ // WriteOnceStatus variable does not exist
+ // Create one with default value of Type 127
+ MemSet(Buffer, BufferSize, 127);
+
+ pRS->SetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BufferSize,
+ Buffer);
+ }
+
+ pBS->FreePool(Buffer);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: isWriteOnce
+//
+// Description: Determines if a given structure type and offset can only
+// be written once or multiple times.
+//
+// Input: IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: BOOLEAN - TRUE/FALSE for Write Once/Multiple
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+isWriteOnce(
+ IN UINT8 Type,
+ IN UINT8 Offset,
+ IN UINT16 Handle
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN WriteOnce = FALSE;
+ UINT8 TableEntries = sizeof(WriteOnceTable)/sizeof(WRITE_ONCE_TABLE);
+ WRITE_ONCE_STATUS Buffer[WRITE_ONCE_ENTRIES];
+ UINTN BufferSize;
+ UINT8 i;
+ UINT8 j;
+
+ BufferSize = WRITE_ONCE_ENTRIES * sizeof(WRITE_ONCE_STATUS);
+ Status = pRS->GetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &BufferSize,
+ Buffer);
+
+ for (i = 0; i < TableEntries; ++i) {
+ // Check for WriteOnce condition in WriteOnce table
+ if (WriteOnceTable[i].Type == Type \
+ && WriteOnceTable[i].Offset == Offset \
+ && WriteOnceTable[i].WriteOnce) {
+ // WriteOnce is set for input Type and Offset,
+ // Check if WriteOnce was set already in WriteOnceStatus table
+ // If "WriteOnceStatus" variable was not found then assume
+ // WriteOnce was not set for this data field
+ if (Status == EFI_SUCCESS) {
+ for (j = 0; j < WRITE_ONCE_ENTRIES; ++j) {
+ if (Buffer[j].Type == 127) {
+ break;
+ }
+ if (Buffer[j].Type == Type && Buffer[j].Offset == Offset && Buffer[j].Handle == Handle) {
+ // WriteOnce was already set for input Type and Offset
+ WriteOnce = TRUE;
+ break;
+ }
+ }
+ }
+
+ if (j < WRITE_ONCE_ENTRIES) { // Make sure we are still within the WRITE_ONCE_ENTRIES
+ // Create new WriteOnce entry if it did not exist for input Type and Offset
+ if (WriteOnce == FALSE) {
+ Buffer[j].Type = Type;
+ Buffer[j].Offset = Offset;
+ Buffer[j].Handle = Handle;
+
+ pRS->SetVariable(L"WriteOnceStatus",
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ BufferSize,
+ Buffer);
+ }
+ }
+ }
+ }
+
+ return WriteOnce;
+}
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WriteToFlash
+//
+// Description: Write to the flash part starting at "Address" for a length
+// of "Size".
+//
+// Input: IN VOID *Address,
+// IN VOID *Data,
+// IN UINTN Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+WriteToFlash(
+ IN VOID *Address,
+ IN VOID *Data,
+ IN UINTN Size
+)
+{
+ EFI_STATUS Status;
+
+ Status = mFlash->DeviceWriteEnable();
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = mFlash->Write(Address, Size, Data);
+
+ mFlash->DeviceWriteDisable();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashDataInfo
+//
+// Description: Searches the Flash Data Table for a record of Type and
+// Offset. If found, returns the location found, the data size,
+// and the end of data.
+//
+// Input: IN TABLE_INFO RecordInfo
+//
+// Output: FLASH_DATA_INFO
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+FLASH_DATA_INFO
+GetFlashDataInfo(
+ IN TABLE_INFO *RecordInfo
+)
+{
+ TABLE_INFO *FlashDataPtr = gFlashData;
+ FLASH_DATA_INFO FlashDataInfo = {0, 0, 0};
+
+ while (FlashDataPtr->Handle != 0xffff) {
+ if (FlashDataPtr->Type == RecordInfo->Type &&
+ FlashDataPtr->Handle == RecordInfo->Handle &&
+ FlashDataPtr->Offset == RecordInfo->Offset &&
+ FlashDataPtr->Flags == RecordInfo->Flags) {
+ FlashDataInfo.Location = (UINT8*)FlashDataPtr;
+ FlashDataInfo.Size = FlashDataPtr->Size;
+ }
+
+ FlashDataPtr = (TABLE_INFO*)((UINT8*)(FlashDataPtr + 1) + FlashDataPtr->Size);
+ }
+ FlashDataInfo.EndOfData = (UINT8*)FlashDataPtr;
+ return FlashDataInfo;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosTable
+//
+// Description: Searches the Flash Data Table for a record of Type and
+// Offset. If found, the existing data will be replaced with
+// the new data, else the data will be added as a new record.
+//
+// Input: IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+UpdateSmbiosTable(
+ IN TABLE_INFO *TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT16 i;
+ UINT8 *BufferPtr = NULL;
+ UINT16 BufferSize = 0;
+ UINT16 Count = 0;
+ UINT32 SpaceAvailable;
+ EFI_STATUS Status;
+ FLASH_DATA_INFO FlashDataInfo;
+ UINT8 *FlashDataPtr;
+ FUNC_BLOCK FuncBlock[2];
+ EFI_PHYSICAL_ADDRESS SmmBuffer;
+ EFI_PHYSICAL_ADDRESS Buffer;
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+ EFI_PHYSICAL_ADDRESS FlashDataBlock;
+ UINT8 BlockCount;
+ UINT8 *DataBuffer;
+ UINTN RemainingSize;
+#endif // NonSmiDmiEdit_Support
+
+ FlashDataInfo = GetFlashDataInfo(TableInfo);
+
+ // Check Size
+ SpaceAvailable = (UINT32)((UINT8*)gFlashData + gFlashDataSize - FlashDataInfo.EndOfData);
+ if (FlashDataInfo.Location) SpaceAvailable += FlashDataInfo.Size + sizeof(TABLE_INFO);
+
+ if (sizeof(TABLE_INFO) + TableInfo->Size > SpaceAvailable) {
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+
+ if (SwSmiMethod) {
+ // Initialize FuncBlock
+ for (i = 0; i < 2; i++) {
+ FuncBlock[i].BufAddr = 0;
+ FuncBlock[i].BlockAddr = 0;
+ FuncBlock[i].BlockSize = 0;
+ FuncBlock[i].ErrorCode = 0;
+ }
+
+ // Allocate 4K working buffer in SMM.
+ Status = mSmst->SmmAllocatePages ( AllocateAnyPages, EfiRuntimeServicesData, 1, &Buffer);
+ if (EFI_ERROR(Status)) return DMI_ADD_STRUCTURE_FAILED;
+ BufferPtr = (UINT8*)Buffer;
+
+ // Update String;
+ *(TABLE_INFO *)BufferPtr = *TableInfo;
+ BufferPtr += sizeof(TABLE_INFO);
+
+ for(i = 0; i < TableInfo->Size; ++i) {
+ *BufferPtr++ = Data[i];
+ }
+
+ if (FlashDataInfo.Location) {
+ UINT32 FlashDataOffset;
+
+ // Allocate 64K GetFlashInfo buffer in SMM.
+ Status = mSmst->SmmAllocatePages ( AllocateAnyPages, \
+ EfiRuntimeServicesData, \
+ 16, \
+ &SmmBuffer);
+ if (EFI_ERROR(Status)) {
+ // Free buffer and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+
+ ((INFO_BLOCK*)SmmBuffer)->Length = 0x10000;
+
+ Status = mSmiFlash->GetFlashInfo((INFO_BLOCK*)SmmBuffer);
+
+ if (Status) {
+ // Free buffers and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+ mSmst->SmmFreePages (SmmBuffer, 16);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+
+ // Initialize FUNC_BLOCK structure for SMIFlash used.
+ for (i = 0, Count = 1; i < ((INFO_BLOCK*)SmmBuffer)->TotalBlocks; i++) {
+ if (((UINT32)FlashDataInfo.Location - FLASH_DEVICE_BASE) > \
+ (((INFO_BLOCK*)SmmBuffer)->Blocks[i].StartAddress + \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i].BlockSize)) continue;
+ FuncBlock[0].BlockSize = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i].BlockSize;
+ FuncBlock[0].BlockAddr = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i].StartAddress;
+
+ // Check whether SmbiosFlashData exceeds the block boundary.
+ if (((UINT32)gFlashData + (UINT32)FLASHDATA_SIZE - FLASH_DEVICE_BASE) > \
+ (((INFO_BLOCK*)SmmBuffer)->Blocks[i+1].StartAddress)) {
+ Count = 2;
+ FuncBlock[1].BlockSize = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i+1].BlockSize;
+ FuncBlock[1].BlockAddr = \
+ ((INFO_BLOCK*)SmmBuffer)->Blocks[i+1].StartAddress;
+ }
+ break;
+ }
+
+ // Free the GetFlashInfo buffer.
+ Status = mSmst->SmmFreePages (SmmBuffer, 16);
+ ASSERT_EFI_ERROR(Status);
+
+ // Allocate the blocks buffer.
+ Status = mSmst->SmmAllocatePages ( \
+ AllocateAnyPages, \
+ EfiRuntimeServicesData, \
+ (FuncBlock[0].BlockSize * Count) / 0x1000, \
+ &SmmBuffer);
+ if (EFI_ERROR(Status)) {
+ // Free buffer and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+ FuncBlock[0].BufAddr = SmmBuffer;
+ FuncBlock[1].BufAddr = SmmBuffer + FuncBlock[0].BlockSize;
+
+ // Read the whole SmbiosFlashData Blocks.
+ for (i = 0; i < Count; i++) {
+ Status = mFlash->Read((VOID*)(FuncBlock[i].BlockAddr + FLASH_DEVICE_BASE), \
+ FuncBlock[i].BlockSize, (VOID*)FuncBlock[i].BufAddr);
+ if (Status) {
+ // Free buffer and return error.
+ mSmst->SmmFreePages (Buffer, 1);
+
+ mSmst->SmmFreePages ( \
+ SmmBuffer, \
+ (FuncBlock[0].BlockSize * Count) / 0x1000);
+ return DMI_ADD_STRUCTURE_FAILED;
+ }
+ }
+
+ // Initialize SmbiosFlashData buffer.
+ for (i = 0; i < FLASHDATA_SIZE; i++, *((UINT8*)Buffer + i) = 0xff);
+
+ // Re-collect the Smbios structures to SmbiosFlashData buffer.
+ FlashDataPtr = gFlashData;
+ BufferPtr = (UINT8*)Buffer;
+
+ while((((TABLE_INFO*)FlashDataPtr)->Size != 0xffff) &&
+ (((TABLE_INFO*)FlashDataPtr)->Size != 0)) {
+ if ((((TABLE_INFO*)FlashDataPtr)->Type == TableInfo->Type) && \
+ (((TABLE_INFO*)FlashDataPtr)->Handle == TableInfo->Handle) && \
+ (((TABLE_INFO*)FlashDataPtr)->Offset == TableInfo->Offset)) {
+ // Replace the structure with updated data.
+ MemCpy(BufferPtr, (UINT8*)TableInfo, sizeof(TABLE_INFO));
+ BufferSize = TableInfo->Size;
+ MemCpy (BufferPtr + sizeof(TABLE_INFO), Data, BufferSize);
+ BufferSize += sizeof(TABLE_INFO);
+ } else {
+ // Copy the structure.
+ BufferSize = (((TABLE_INFO*)FlashDataPtr)->Size + sizeof(TABLE_INFO));
+ MemCpy (BufferPtr, FlashDataPtr, BufferSize);
+ }
+
+ BufferPtr += BufferSize;
+ FlashDataPtr += (((TABLE_INFO*)FlashDataPtr)->Size + sizeof(TABLE_INFO));
+ }
+
+ // Copy the new SmbiosFlashData to read buffer.
+ FlashDataOffset = ((UINT32)FlashDataInfo.Location - \
+ FLASH_DEVICE_BASE - FuncBlock[0].BlockAddr);
+ BufferPtr = (UINT8*)Buffer + (UINT32)FlashDataInfo.Location - (UINT32)gFlashData;
+ MemCpy((UINT8*)(FuncBlock[0].BufAddr + FlashDataOffset),
+ (UINT8*)BufferPtr,
+ (UINT32)gFlashData + (UINT32)FLASHDATA_SIZE - (UINT32)FlashDataInfo.Location);
+
+ // Write the block buffer with updated SmbiosFlashData back.
+ if (!EFI_ERROR(Status)) {
+ for (i = 0; i < Count; i++) {
+ Status = mFlash->Update( \
+ (VOID*)(FuncBlock[i].BlockAddr + FLASH_DEVICE_BASE), \
+ FuncBlock[i].BlockSize, (VOID*)FuncBlock[i].BufAddr
+ );
+ if (EFI_ERROR(Status)) break;
+ }
+ }
+
+ // Free the Block Buffer in SMM.
+ mSmst->SmmFreePages ( SmmBuffer, \
+ (FuncBlock[0].BlockSize * Count) / 0x1000);
+ }
+ else {
+ UINT32 EndOfData;
+
+ EndOfData = (UINT32)FlashDataInfo.EndOfData & 0x0ffff;
+
+ if ((EndOfData + (UINT32)(BufferPtr - (UINT8*)Buffer)) > 0x10000) {
+ UINT32 NewOffsetOfData;
+ UINT32 ExtraSize;
+ UINT32 DataLength;
+
+ NewOffsetOfData = (UINT32)(((UINT32)FlashDataInfo.EndOfData & 0xffff0000) + 0x10000);
+ ExtraSize = EndOfData + (UINT32)(BufferPtr - (UINT8*)Buffer) - 0x10000;
+ DataLength = (UINT32)(BufferPtr - (UINT8*)Buffer);
+
+ Status = WriteToFlash(FlashDataInfo.EndOfData,
+ (UINT8*)Buffer,
+ DataLength - ExtraSize);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = WriteToFlash( (VOID *)NewOffsetOfData,
+ (UINT8*)(Buffer + DataLength - ExtraSize),
+ ExtraSize);
+ ASSERT_EFI_ERROR(Status);
+ }
+ else {
+ Status = WriteToFlash(FlashDataInfo.EndOfData,
+ (UINT8*)Buffer,
+ BufferPtr - (UINT8*)Buffer);
+ }
+
+ mSmst->SmmFreePages (Buffer, 1);
+
+ if (Status) return DMI_ADD_STRUCTURE_FAILED;
+ }
+ } // SwSmiMethod
+#if defined(NonSmiDmiEdit_Support) && (NonSmiDmiEdit_Support == 1)
+ else { // Protocol Method
+ // Determine the base block that contains the DmiEdit data
+ FlashDataBlock = (UINTN)gFlashData & (0xFFFFFFFF - FLASH_BLOCK_SIZE + 1);
+
+ // Check to see if it spans more than one block
+ if (((UINTN)gFlashData + FLASHDATA_SIZE) > (FlashDataBlock + FLASH_BLOCK_SIZE)) {
+ BlockCount = 2;
+ }
+ else {
+ BlockCount = 1;
+ }
+
+ // Allocate Flash Data buffer and get the data
+ // Note: additional 4K reserved for data manipulation
+ pBS->AllocatePool(EfiBootServicesData, BlockCount * FLASH_BLOCK_SIZE, &DataBuffer);
+ FlashProtocol->Read((UINT8*)FlashDataBlock, BlockCount * FLASH_BLOCK_SIZE, DataBuffer);
+
+ if (FlashDataInfo.Location) {
+ // Some data is already present for input type
+ // Determine location of existing data
+ BufferPtr = DataBuffer + \
+ (UINTN)gFlashData - FlashDataBlock + \
+ (UINTN)FlashDataInfo.Location - (UINTN)gFlashData; // Existing DmiEdit data location
+
+ // Calculate remaining size from the existing data location
+ // to end of DmiEdit data storage block
+ RemainingSize = (UINTN)FlashDataInfo.EndOfData - \
+ (UINTN)FlashDataInfo.Location - \
+ (sizeof(TABLE_INFO) + ((TABLE_INFO*)BufferPtr)->Size);
+
+ // Copy the remaining data (without the existing data) to location
+ // after input data entry insertion
+ MemCpy(BufferPtr + sizeof(TABLE_INFO) + TableInfo->Size,
+ BufferPtr + sizeof(TABLE_INFO) + ((TABLE_INFO*)BufferPtr)->Size,
+ RemainingSize);
+
+ // In case new data size is smaller than existing one, clear old data
+ // from (EndOfData - size difference) to EndOfData to 0xff
+ if (((TABLE_INFO*)BufferPtr)->Size > TableInfo->Size) {
+ UINT8 *DataEndPtr;
+
+ RemainingSize = ((TABLE_INFO*)BufferPtr)->Size - TableInfo->Size;
+ DataEndPtr = DataBuffer + \
+ ((UINTN)FlashDataInfo.EndOfData - FlashDataBlock) - \
+ RemainingSize;
+
+ for (i = 0; i < RemainingSize; ++i) {
+ *DataEndPtr++ = 0xff;
+ }
+ }
+ }
+ else {
+ // Determine the end location of current DmiEdit data
+ BufferPtr = DataBuffer + \
+ (UINTN)gFlashData - FlashDataBlock + \
+ (UINTN)FlashDataInfo.EndOfData - (UINTN)gFlashData; // End of DmiEdit data
+ }
+
+ // Insert data
+ *(TABLE_INFO *)BufferPtr = *TableInfo;
+ BufferPtr += sizeof(TABLE_INFO);
+
+ for(i = 0; i < TableInfo->Size; ++i) {
+ *BufferPtr++ = Data[i];
+ }
+
+ // Update DmiEdit data block
+ FlashProtocol->Update((UINT8*)FlashDataBlock, BlockCount * FLASH_BLOCK_SIZE, DataBuffer);
+
+ pBS->FreePool(DataBuffer);
+ }
+#endif // NonSmiDmiEdit_Support
+
+ return 0;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosInfo
+//
+// Description: Returns the SMBIOS information
+//
+// Input: IN OUT GET_SMBIOS_INFO *p
+//
+// Output: Returns 0
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetSmbiosInfo(
+ IN OUT GET_SMBIOS_INFO *p
+)
+{
+ if (!SmbiosTableEntryPoint) return DMI_FUNCTION_NOT_SUPPORTED;
+ p->DmiBiosRevision = SmbiosTableEntryPoint->SmbiosBCDRevision;
+ p->NumStructures = SmbiosTableEntryPoint->NumberOfSmbiosStructures;
+ p->StructureSize = SmbiosTableEntryPoint->MaxStructureSize;
+ p->pDmiStorageBase = SmbiosTableEntryPoint->TableAddress;
+ p->DmiStorageSize = MaximumBufferSize;
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureByHandle
+//
+// Description: Searches the structure table for a record with its handle
+// equal to the input Handle.
+// Returns the pointer to the structure if found.
+// Returns NULL if not found
+//
+// Input: IN UINT16 *Handle
+//
+// Output: UINT8* - Pointer to structure found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8*
+GetStructureByHandle(
+ IN UINT16 *Handle
+)
+{
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *SmbiosTableNext;
+
+ while(SmbiosTable < SmbiosTableEnd && ((SMBIOS_STRUCTURE_HEADER*)SmbiosTable)->Type != 127) {
+ SmbiosTableNext = SmbiosTable + GetStructureLength(SmbiosTable);
+ if (((SMBIOS_STRUCTURE_HEADER*)SmbiosTable)->Handle == *Handle) {
+ return SmbiosTable;
+ }
+ SmbiosTable = SmbiosTableNext;
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureByHandleThenUpdateHandle
+//
+// Description: Searches the structure table for a record with its handle
+// equal to the input Handle.
+// Returns the pointer to the structure if found.
+// Returns NULL if not found
+//
+// Input: IN UINT16 *Handle
+//
+// Output: UINT8* - Pointer to structure found
+// Sets Handle to the handle of the next structure
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8*
+GetStructureByHandleThenUpdateHandle(
+ IN UINT16 *Handle
+)
+{
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *SmbiosTableNext;
+
+ if (*Handle == 0) {
+ SmbiosTableNext = SmbiosTable + GetStructureLength(SmbiosTable);
+ if (SmbiosTableNext >= SmbiosTableEnd) *Handle = 0xffff; //Last handle?
+ else *Handle = ((DMI_STRUC*)SmbiosTableNext)->Handle; //Return next handle
+ return SmbiosTable;
+ }
+
+ while(SmbiosTable < SmbiosTableEnd) {
+ SmbiosTableNext = SmbiosTable + GetStructureLength(SmbiosTable);
+ if (((DMI_STRUC*)SmbiosTable)->Handle == *Handle) {
+ if (SmbiosTableNext >= SmbiosTableEnd || ((DMI_STRUC*)SmbiosTable)->Type == 127 ) *Handle = 0xffff; //Last handle?
+ else *Handle = ((DMI_STRUC*)SmbiosTableNext)->Handle; //Return next handle
+ return SmbiosTable;
+ }
+
+ SmbiosTable = SmbiosTableNext;
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetSmbiosStructure
+//
+// Description: Searches the structure table for a record with its handle
+// equal to the input Handle and copies its content into
+// the provided buffer.
+//
+// Input: IN OUT GET_SMBIOS_STRUCTURE *p
+//
+// Output: GET_SMBIOS_STRUCTURE* - Input pointer "p" is loaded with
+// structure data.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetSmbiosStructure(
+ IN OUT GET_SMBIOS_STRUCTURE *p
+)
+{
+ UINT8 *SmbStructurePtr;
+ UINT32 TableSize;
+ UINT8 *src, *dest;
+
+ if (!SmbiosTableEntryPoint) return DMI_FUNCTION_NOT_SUPPORTED;
+
+ SmbStructurePtr = GetStructureByHandleThenUpdateHandle((UINT16*)p->Handle32BitAddr);
+ if (!SmbStructurePtr) return DMI_INVALID_HANDLE;
+
+ TableSize = GetStructureLength(SmbStructurePtr);
+
+ src = SmbStructurePtr;
+ dest = (UINT8*)p->Buffer32BitAddr;
+ while(TableSize--) *dest++ = *src++; //Copy Table
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStructureLength
+//
+// Description: Returns the length of the structure pointed by BufferStart
+// in bytes
+//
+// Input: IN UINT8 *BufferStart
+//
+// Output: UINT16 - Size of the structure
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetStructureLength(
+ IN UINT8 *BufferStart
+)
+{
+ UINT8 *BufferEnd = BufferStart;
+
+ BufferEnd += ((SMBIOS_STRUCTURE_HEADER*)BufferStart)->Length;
+
+ while(*(UINT16*)BufferEnd != 0) {
+ BufferEnd++;
+ }
+
+ return (UINT16)(BufferEnd + 2 - BufferStart); // +2 for double zero terminator
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInstanceByTypeHandle
+//
+// Description: Returns the instance of the input structure type and its handle
+//
+// Input: IN UINT8 Type
+// IN UINT16 Handle
+//
+// Output: Instance number (1-based) if found, or 0 if not found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetInstanceByTypeHandle(
+ IN UINT8 Type,
+ IN UINT16 Handle
+)
+{
+ UINT8 *Table = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *TableEnd = Table + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 Instance = 0; // 1-based
+
+ while ((Table < TableEnd) && ((SMBIOS_STRUCTURE_HEADER*)Table)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)Table)->Type == Type) {
+ Instance ++;
+ }
+
+ if (((SMBIOS_STRUCTURE_HEADER*)Table)->Handle == Handle) {
+ return Instance;
+ }
+
+ Table = Table + GetStructureLength(Table);
+ }
+
+ return 0; // Not found
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindStructureType
+//
+// Description: Find structure type starting from memory location pointed by
+// Buffer
+//
+// Input: IN OUT UINT8 **Buffer
+// IN OUT UINT8 **StructureFoundPtr
+// IN UINT8 SearchType
+// IN UINT8 Instance
+//
+// Output:
+// BOOLEAN
+// TRUE - Structure found
+// FALSE - Structure not found
+//
+// If SearchType is found:
+// UINT8 **Buffer - Points to the next structure
+// UINT8 **StructureFoundPtr - Points to the structure
+// that was found
+// If SearchType is not found:
+// UINT8 **Buffer - No change
+// UINT8 **StructureFoundPtr = NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindStructureType(
+ IN OUT UINT8 **Buffer,
+ IN OUT UINT8 **StructureFoundPtr,
+ IN UINT8 SearchType,
+ IN UINT8 Instance // 1-based
+)
+{
+ UINT8 *BufferPtr = *Buffer;
+ BOOLEAN FindStatus = FALSE;
+
+ *StructureFoundPtr = NULL;
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ if (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type == SearchType) {
+ // If this instance, set the find status flag and update the Buffer pointer
+ if (--Instance == 0) {
+ FindStatus = TRUE;
+ *StructureFoundPtr = BufferPtr;
+ *Buffer = BufferPtr + GetStructureLength(BufferPtr);
+ break;
+ }
+ }
+ BufferPtr += GetStructureLength(BufferPtr);
+ }
+ if ((FindStatus == FALSE) & (SearchType == 127)) {
+ FindStatus = TRUE;
+ *StructureFoundPtr = BufferPtr;
+ *Buffer = BufferPtr + GetStructureLength(BufferPtr);
+ }
+ return FindStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringTableIndex
+//
+// Description: Returns the string array index for a given Offset in
+// structure pointed by input StringTablePtr
+//
+// Input: STRING_TABLE *StringTablePtr
+// IN UINT8 Offset
+//
+// Output: UINT8 - String array index
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStringTableIndex(
+ STRING_TABLE *StringTablePtr,
+ IN UINT8 Offset
+)
+{
+ UINT8 i;
+
+ for (i = 0; StringTablePtr->Offset != 0xff; i++) {
+ if (StringTablePtr->Offset == Offset) break;
+ StringTablePtr++;
+ }
+
+ return i;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrLen
+//
+// Description: Returns the length of an input string
+//
+// Input: IN CHAR8 *Str
+//
+// Output: UINT8 - Length of the string (without zero terminator)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+StrLen(
+ IN CHAR8 *Str
+)
+{
+ UINT16 Length = 0;
+
+ while (*Str++) Length++;
+
+ return Length;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetRemainingStructuresSize
+//
+// Description: Return the size from the Pointer Buffer to the last
+// structure 127.
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: Size of remaining structure
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetRemainingStructuresSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT16 Length = 0;
+ UINT16 BlockSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)Buffer)->Type != 127) {
+ BlockSize = GetStructureLength(Buffer);
+ Length += BlockSize;
+ Buffer += BlockSize;
+ }
+ Length += GetStructureLength(Buffer);
+ return Length;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosCheckSum
+//
+// Description: Returns the checksum of "length" bytes starting from the
+// "*ChecksumSrc"
+//
+// Input: IN UINT8 *ChecksumSrc
+// IN UINT8 length
+//
+// Output: UINT8 - Checksum value
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+SmbiosCheckSum(
+ IN UINT8 *ChecksumSrc,
+ IN UINT8 length
+)
+{
+ UINT8 Checksum = 0;
+ UINT8 i;
+
+ for (i= 0; i < length; i++) {
+ Checksum += *ChecksumSrc++;
+ }
+ return (0 - Checksum);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetLargestStructureSize
+//
+// Description: Returns the largest structure size
+//
+// Input: IN UINT8 *Buffer
+//
+// Output: UINT16 - Largest structure size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetLargestStructureSize(
+ IN UINT8 *Buffer
+)
+{
+ UINT8 *BufferPtr = Buffer;
+ UINT16 LargestStructureSize = 0;
+ UINT16 CurrentStructureSize;
+
+ while (((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Type != 127) {
+ UINT8 *LastBufferPtr;
+
+ LastBufferPtr = BufferPtr;
+ BufferPtr += ((SMBIOS_STRUCTURE_HEADER*)BufferPtr)->Length;
+ while(TRUE) {
+ if ((*(UINT16*)BufferPtr) == 0) {
+ BufferPtr += 2;
+ break;
+ }
+ BufferPtr++;
+ }
+ CurrentStructureSize = (UINT16)(BufferPtr - LastBufferPtr);
+ if (CurrentStructureSize > LargestStructureSize) {
+ LargestStructureSize = CurrentStructureSize;
+ }
+ }
+ return LargestStructureSize;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateHeaderInfo
+//
+// Description: Updates SMBIOS Entry Point Header
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateHeaderInfo(VOID)
+{
+ SmbiosTableEntryPoint->TableLength = GetRemainingStructuresSize((UINT8*)SmbiosTableEntryPoint->TableAddress);
+ SmbiosTableEntryPoint->IntermediateChecksum = 0;
+ SmbiosTableEntryPoint->IntermediateChecksum = SmbiosCheckSum((UINT8*)SmbiosTableEntryPoint + 0x10, 15);
+ SmbiosTableEntryPoint->MaxStructureSize = GetLargestStructureSize((UINT8*)SmbiosTableEntryPoint->TableAddress);
+ SmbiosTableEntryPoint->EntryPointStructureChecksum = 0;
+ SmbiosTableEntryPoint->EntryPointStructureChecksum = SmbiosCheckSum((UINT8*)SmbiosTableEntryPoint,
+ SmbiosTableEntryPoint->EntryPointLength);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetTypeTable
+//
+// Description: Return pointer to the input type string table
+//
+// Input: IN UINT8 Structure Type
+//
+// Output: Pointer to the input type string table
+// (or NULL if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+GetTypeTable(
+ IN UINT8 StructType
+)
+{
+ UINT8 Index;
+
+ switch (StructType) {
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4: Index = StructType;
+ break;
+ case 22: Index = 5;
+ break;
+ case 39: Index = 6;
+ break;
+ default: Index = 0xff;
+ }
+
+ if (Index != 0xff) {
+ return StringTable[Index];
+ }
+ else {
+ return NULL;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStringOffset
+//
+// Description: Returns the string offset for StringNumber from input string
+// buffer BufferStart
+//
+// Input: IN UINT8 *BufferStart
+// IN UINT8 StringNumber (1-based)
+//
+// Output: UINT16 - Offset from BufferStart
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetStringOffset(
+ IN UINT8 *BufferStart,
+ IN UINT8 StringNumber // 1-based
+)
+{
+ UINT8 *BufferEnd = BufferStart;
+
+ while (--StringNumber) {
+ while(*BufferEnd != 0) {
+ BufferEnd++;
+ }
+ BufferEnd++;
+ }
+
+ return (UINT16)(BufferEnd - BufferStart);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindString
+//
+// Description: Returns pointer to the string number in structure BufferPtr
+//
+// Input: IN OUT UINT8 **BufferPtr
+// IN UINT8 StringNumber
+//
+// Output: UINT8 *BufferPtr = Pointer to the #StringNumber string
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+FindString(
+ IN OUT UINT8 **BufferPtr,
+ IN UINT8 StringNumber // 1-based
+)
+{
+ *BufferPtr += ((SMBIOS_STRUCTURE_HEADER*)*BufferPtr)->Length;
+ *BufferPtr += GetStringOffset(*BufferPtr, StringNumber);
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindLargestStrNumber
+//
+// Description: Return the largest string number in a structure
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 *StrTablePtr
+//
+// Output: String number (1-based)
+// (or 0 if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+FindLargestStrNumber (
+ IN UINT8 *StructPtr,
+ IN STRING_TABLE *StrTablePtr
+)
+{
+ UINT8 Number;
+ UINT8 StrNumber = 0;
+
+ // Find largest string number from structure
+ while (StrTablePtr->Offset != 0xff) {
+ Number = *(StructPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ StrNumber = Number;
+ }
+ StrTablePtr++;
+ }
+
+ return StrNumber; // 1-based
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetStrNumber
+//
+// Description: Return the string number for a structure "Type" at "Offset"
+//
+// Input: IN UINT8 Pointer to structure
+// IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: String number (1-based)
+// (or 0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+GetStrNumber(
+ IN UINT8 *StructPtr,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ UINT8 *NextStructPtr = StructPtr;
+ UINT8 *TempPtr;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ return *(TempPtr + Offset);
+ }
+ else {
+ return 0xff;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteStringNumber
+//
+// Description: Zero out the string number in StructPtr
+//
+// Input: IN UINT8 *StructurePtr
+// IN UINT8 StrNumber
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DeleteStringNumber (
+ IN UINT8 *StructPtr,
+ IN UINT8 StrNumber
+)
+{
+ UINT8 Number;
+ STRING_TABLE *StrTablePtr;
+
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+
+ while (StrTablePtr->Offset != 0xff) {
+ Number = *(StructPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ *(StructPtr + StrTablePtr->Offset) = Number - 1;
+ }
+ if (Number == StrNumber) {
+ *(StructPtr + StrTablePtr->Offset) = 0;
+ }
+ StrTablePtr++;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DeleteString
+//
+// Description: Delete string at Offset
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 Offset
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+DeleteString (
+ IN UINT8 *StructPtr,
+ IN UINT8 Offset
+)
+{
+ UINT8 StrNumber;
+ UINT8 *TempPtr;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ StrNumber = GetStrNumber(StructPtr, ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type, Offset);
+
+ // Delete string number
+ DeleteStringNumber(StructPtr, StrNumber);
+
+ FindString(&StructPtr, StrNumber); // StructPtr = StrNumber string
+ TempPtr = StructPtr + StrLen(StructPtr) + 1; // Move pointer to next string
+
+ // Find end of structure
+ StructEndPtr = TempPtr;
+ while(*(UINT16*)StructEndPtr != 0) {
+ StructEndPtr++;
+ }
+
+ // Copy remaining strings
+ RemainingSize = StructEndPtr + 2 - TempPtr; // Including double NULL characters
+ MemCpy(StructPtr, TempPtr, RemainingSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReplaceString
+//
+// Description: Replace the #StringNum in the input buffer *DestStructPtr
+// with StringData
+//
+// Input: IN UINT8 *DestStructPtr Pointer to structure to be updated
+// IN UINT8 StringNum String number (1 based)
+// IN UINT8 *StringData String with NULL terminated character
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ReplaceString(
+ IN UINT8 *DestStructPtr,
+ IN UINT8 StringNum,
+ IN UINT8 *StringData
+)
+{
+ UINT8 StringSize = 0;
+ UINT8 *TempPtr;
+ UINT8 *NextStrPtr;
+ UINT8 *StructEndPtr;
+ UINTN RemainingSize;
+
+ FindString(&DestStructPtr, StringNum);
+ NextStrPtr = DestStructPtr;
+ StructEndPtr = DestStructPtr;
+
+ while(*NextStrPtr != 0) {
+ NextStrPtr++;
+ }
+
+ // NextStrPtr = Pointer to the next string
+ NextStrPtr++;
+
+ while(*(UINT16*)StructEndPtr != 0) {
+ StructEndPtr++;
+ }
+
+ RemainingSize = StructEndPtr + 2 - NextStrPtr; // Including double NULL characters
+
+ TempPtr = StringData;
+ while (*(TempPtr++) != 0) {
+ StringSize++;
+ }
+ StringSize++; // Including NULL character
+
+ // Copy remaining strings
+ MemCpy(DestStructPtr + StringSize, NextStrPtr, RemainingSize);
+
+ // Copy the string
+ MemCpy(DestStructPtr, StringData, StringSize);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddStringNumber
+//
+// Description: Add new string number for a structure "Type" at "Offset".
+// Return the string index, assuming all strings exist in the
+// structure according to the Smbios specification
+//
+// Input: IN UINT8 Pointer to SmbiosTable or Structure
+// IN UINT8 Type
+// IN UINT8 Offset
+//
+// Output: String index (0-based)
+// (0xff if not found)
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+AddStringNumber(
+ IN UINT8 *SmbiosTable,
+ IN UINT8 Type,
+ UINT8 Offset
+)
+{
+ STRING_TABLE *StrTablePtr;
+ UINT8 *NextStructPtr = SmbiosTable;
+ UINT8 *TempPtr;
+ UINT8 Index = 0xff;
+ UINT8 StrNumber = 0;
+ UINT8 Number;
+
+ if (FindStructureType(&NextStructPtr, &TempPtr, Type, 1)) {
+ StrTablePtr = GetTypeTable(Type);
+ if (StrTablePtr != NULL) {
+ // Find largest string number from structure
+ while (StrTablePtr->Offset != 0xff) {
+ if (StrTablePtr->Offset == Offset) {
+ // String index in Smbios spec
+ Index = StrTablePtr->SpecStrNum - 1; // 0-based
+ }
+
+ Number = *(TempPtr + StrTablePtr->Offset);
+ if (Number > StrNumber) {
+ StrNumber = Number;
+ }
+ StrTablePtr++;
+ }
+
+ // Assign next string number to structure at input Offset
+ *(TempPtr + Offset) = ++StrNumber;
+
+ return Index; // 0-based
+ }
+ }
+
+ return 0xff;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AddNullTerminator
+//
+// Description: Add NULL terminator to the end of the structure
+//
+// Input: IN UINT8 *StructPtr
+// IN UINT8 *StrTablePtr
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+AddNullTerminator (
+ IN UINT8 *StructPtr,
+ IN STRING_TABLE *StrTablePtr
+)
+{
+ UINT8 StrNumber;
+ UINT8 i;
+
+ // Find largest string number
+ StrNumber = FindLargestStrNumber(StructPtr, StrTablePtr);
+
+ // Skip to string section
+ StructPtr += ((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Length;
+
+ // Move pointer to end of last string
+ for (i = 0; i < StrNumber; i++) {
+ while (*StructPtr != NULL) StructPtr++;
+ StructPtr++;
+ }
+
+ // Add NULL terminator
+ *StructPtr = 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateStrings
+//
+// Description: Updates strings in SMBIOS Structure with input Handle
+// in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+UpdateStrings(
+ IN UINT16 Handle,
+ IN TABLE_INFO TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT8 *TablePtr;
+ UINT8 *TempBuffer;
+ UINT8 *StructPtr;
+ UINT8 i;
+ UINT16 BlockSize;
+ UINT16 AvailableBlkSize;
+ STRING_TABLE *StrTablePtr;
+ UINT8 StrNumber;
+ UINT8 Instance;
+
+ // Check if enough space
+ AvailableBlkSize = MaximumBufferSize - SmbiosTableEntryPoint->TableLength;
+ if (AvailableBlkSize < (StrLen(Data) + 1)) {
+ return DMI_BAD_PARAMETER; // Not enough space
+ }
+
+ // Get pointer to structure to be updated
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr == NULL) {
+ return DMI_INVALID_HANDLE;
+ }
+
+ // Get pointer to the StringTable
+ StrTablePtr = GetTypeTable(((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type);
+ if (((SMBIOS_STRUCTURE_HEADER*)StructPtr)->Type == 3) {
+ Instance = GetInstanceByTypeHandle(3, Handle);
+ StrTablePtr += 6 * (Instance - 1);
+ }
+
+ if (StrTablePtr == NULL) return DMI_BAD_PARAMETER;
+
+ // Copy structure data
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetStructureLength(StructPtr);
+ MemCpy(TempBuffer, StructPtr, BlockSize);
+
+ // Set TablePtr to next structure
+ TablePtr = StructPtr + BlockSize;
+
+
+ // Update String fields
+ for (i = 0; StrTablePtr[i].Offset != 0xff; i++) {
+ // Update string at input Offset
+ if (StrTablePtr[i].Offset == TableInfo.Offset) {
+ // Update string if input data not empty, else delete it
+ if (StrLen(Data)) {
+ BlockSize = StrLen(Data) + 1;
+ // Add string if does not exist, else replace it
+ StrNumber = GetStrNumber(TempBuffer, TableInfo.Type, TableInfo.Offset);
+ if (StrNumber == 0) {
+ AddStringNumber(TempBuffer, TableInfo.Type, TableInfo.Offset);
+ StrNumber = GetStrNumber(TempBuffer, TableInfo.Type, TableInfo.Offset);
+ }
+ ReplaceString(TempBuffer, StrNumber, Data);
+ }
+ else {
+ DeleteString(TempBuffer, TableInfo.Offset);
+ }
+ }
+ }
+
+ // Add structure terminator Null byte
+ AddNullTerminator(TempBuffer, StrTablePtr);
+
+ BlockSize = GetRemainingStructuresSize(TablePtr);
+ MemCpy(TempBuffer + GetStructureLength(TempBuffer), TablePtr, BlockSize);
+
+ // Replace all DMI data with TempBuffer
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetRemainingStructuresSize(TempBuffer);
+ MemCpy(StructPtr, TempBuffer, BlockSize);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+
+ return DMI_SUCCESS;
+}
+
+#if OEM_STRING_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateType11
+//
+// Description: Updates SMBIOS Type 11 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+DynamicUpdateType11(
+ IN UINT16 Handle,
+ IN TABLE_INFO TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT8 *TablePtr;
+ UINT8 *TempBuffer;
+ UINT8 *StructPtr;
+ UINT16 BlockSize;
+ UINT16 StringSize;
+ UINT8 i;
+ UINT16 AvailableBlkSize;
+ UINT8 Count;
+
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr == NULL) {
+ return DMI_INVALID_HANDLE;
+ }
+
+ TablePtr = StructPtr;
+ TempBuffer = ScratchBufferPtr;
+
+ AvailableBlkSize = MaximumBufferSize - SmbiosTableEntryPoint->TableLength;
+ if (AvailableBlkSize < (StrLen(Data) + 1)) {
+ return DMI_BAD_PARAMETER; // Not enough space
+ }
+
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)TablePtr)->Length;
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+ Count = ((SMBIOS_OEM_STRINGS_INFO*)TempBuffer)->Count;
+
+ TablePtr += BlockSize;
+ TempBuffer += BlockSize;
+
+ // string fields
+ for (i = 1; i < (Count + 1); i++) {
+ StringSize = StrLen(TablePtr) + 1; // Size including string NULL terminator
+ if (TableInfo.Offset == i) {
+ BlockSize = StrLen(Data) + 1;
+ MemCpy(TempBuffer, Data, BlockSize);
+ TempBuffer += BlockSize;
+ }
+ else {
+ MemCpy(TempBuffer, TablePtr, StringSize);
+ TempBuffer += StringSize;
+ }
+ TablePtr += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ TempBuffer++;
+ TablePtr++;
+
+ BlockSize = GetRemainingStructuresSize(TablePtr);
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+
+ // Replace all DMI data with TempBuffer
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetRemainingStructuresSize(TempBuffer);
+ MemCpy(StructPtr, TempBuffer, BlockSize);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+
+ return DMI_SUCCESS;
+}
+#endif
+
+#if SYSTEM_CONFIG_OPTION_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DynamicUpdateType12
+//
+// Description: Updates SMBIOS Type 12 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN TABLE_INFO TableInfo,
+// IN UINT8 *Data
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+DynamicUpdateType12(
+ IN UINT16 Handle,
+ IN TABLE_INFO TableInfo,
+ IN UINT8 *Data
+)
+{
+ UINT8 *TablePtr;
+ UINT8 *TempBuffer;
+ UINT8 *StructPtr;
+ UINT16 BlockSize;
+ UINT16 StringSize;
+ UINT8 i;
+ UINT16 AvailableBlkSize;
+ UINT8 Count;
+
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr == NULL) {
+ return DMI_INVALID_HANDLE;
+ }
+
+ TablePtr = StructPtr;
+ TempBuffer = ScratchBufferPtr;
+
+ AvailableBlkSize = MaximumBufferSize - SmbiosTableEntryPoint->TableLength;
+ if (AvailableBlkSize < (StrLen(Data) + 1)) {
+ return DMI_BAD_PARAMETER; // Not enough space
+ }
+
+ // Copy structure data (without string data)
+ BlockSize = ((SMBIOS_STRUCTURE_HEADER*)TablePtr)->Length;
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+ Count = ((SMBIOS_SYSTEM_CONFIG_INFO*)TempBuffer)->Count;
+
+ TablePtr += BlockSize;
+ TempBuffer += BlockSize;
+
+ // string fields
+ for (i = 1; i < (Count + 1); i++) {
+ StringSize = StrLen(TablePtr) + 1; // Size including string NULL terminator
+ if (TableInfo.Offset == i) {
+ BlockSize = StrLen(Data) + 1;
+ MemCpy(TempBuffer, Data, BlockSize);
+ TempBuffer += BlockSize;
+ }
+ else {
+ MemCpy(TempBuffer, TablePtr, StringSize);
+ TempBuffer += StringSize;
+ }
+ TablePtr += StringSize;
+ }
+
+ // Add NULL byte for end of string-set
+ *TempBuffer = 0;
+ TempBuffer++;
+ TablePtr++;
+
+ BlockSize = GetRemainingStructuresSize(TablePtr);
+ MemCpy(TempBuffer, TablePtr, BlockSize);
+
+ // Replace all DMI data with TempBuffer
+ TempBuffer = ScratchBufferPtr;
+ BlockSize = GetRemainingStructuresSize(TempBuffer);
+ MemCpy(StructPtr, TempBuffer, BlockSize);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+
+ return DMI_SUCCESS;
+}
+#endif
+
+/////////////////////////////////////////////
+// Worker function for setting structures. //
+/////////////////////////////////////////////
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC == 2
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StoreNvramData
+//
+// Description: Store DMIEdit data into input variable
+//
+// Input: IN CHAR16 *Var
+// IN VOID *Data
+// IN UINTN DataSize
+//
+// Global variable "DmiArray", "DmiArraySize",
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+StoreNvramData(
+ IN CHAR16 *Var,
+ IN VOID *Data,
+ IN UINTN DataSize
+)
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT8 *Buffer;
+
+ // Check if variable already exists
+ //
+ // Size of zero is used to detect if the variable exists.
+ // If the variable exists, an error code of EFI_BUFFER_TOO_SMALL
+ // would be returned
+ Size = 0;
+ Status = pRS->GetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &Size,
+ &Buffer);
+
+ if (Status == EFI_NOT_FOUND) {
+ // Record not present, increment record count
+ DmiArray[0].Type += 1;
+
+ Status = pRS->SetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ // Update DMI data record if already exists,
+ // or store new record if total record count in DmiArray was successfully
+ // updated
+ if (Status == EFI_BUFFER_TOO_SMALL || Status == EFI_SUCCESS) {
+ Status = pRS->SetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DataSize,
+ Data);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ return Status;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDmiDataSize
+//
+// Description: Returns the data size for DMI Function 0x52
+//
+// Input: IN SET_SMBIOS_STRUCTURE_DATA *Data,
+//
+// Output: UINT16 - Data Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+GetDmiDataSize(
+ IN SET_SMBIOS_STRUCTURE_DATA *Data
+)
+{
+ switch(Data->Command) {
+ case 0:
+ return 1;
+ case 1:
+ return 2;
+ case 2:
+ return 4;
+ case 4:
+ return 0; // Delete command, size does not matter
+ default:
+ return Data->DataLength; // Add, String, or Block change command
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetInputDataInfo
+//
+// Description: Fills "TableInfo" with data from DMI Function 0x52
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN OUT TABLE_INFO *TableInfo
+//
+// Output: UINT16 - Data Size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetInputDataInfo(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN OUT TABLE_INFO *TableInfo
+)
+{
+ TableInfo->Type = Data->StructureHeader.Type;
+ TableInfo->Offset = Data->FieldOffset;
+ TableInfo->Reserved = 0;
+ TableInfo->Flags = DMIEDIT_EXTENDED_HDR;
+ TableInfo->HdrLength = sizeof(TABLE_INFO);
+ TableInfo->Size = GetDmiDataSize(Data);
+ TableInfo->Handle = Handle;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType0
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 0 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes: Type 0 Offset 8 (Release Date) is a fixed form string. This
+// function only checks for proper length. It is up to the DMI
+// editing utility to check for the proper format.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType0(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+
+ if ( Data->FieldOffset != 4
+ && Data->FieldOffset != 5
+ && Data->FieldOffset != 8
+ ) return DMI_BAD_PARAMETER;
+
+ if ((Data->FieldOffset == 8) && (Data->DataLength != 11)) {
+ return DMI_BAD_PARAMETER; // Date string is fixed size
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(0, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 0;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update strings in Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType1
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 1 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType1(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *UuidPtr;
+ UINT8 i;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ switch (Data->FieldOffset) {
+ case 0x04 :
+ case 0x05 :
+ case 0x06 :
+ case 0x07 :
+ case 0x19 :
+ case 0x1a : if (Data->Command != 5) return DMI_BAD_PARAMETER;
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(1, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+ break;
+
+ default: if ((Data->FieldOffset > 0x07) && (Data->FieldOffset < 0x18)) {
+ UINT8 *Ptr;
+
+ Ptr = GetStructureByHandle(&Handle);
+ UuidPtr = (UINT8*)&((SMBIOS_SYSTEM_INFO*)Ptr)->Uuid;
+ Ptr = UuidPtr + Data->FieldOffset - 8;
+
+ if (Data->Command < 3) {
+ if (Data->Command == 0) {
+ *Ptr &= (UINT8)Data->ChangeMask;
+ *Ptr |= (UINT8)Data->ChangeValue;
+ }
+ if (Data->Command == 1) {
+ *(UINT16*)Ptr &= (UINT16)Data->ChangeMask;
+ *(UINT16*)Ptr |= (UINT16)Data->ChangeValue;
+ }
+ if (Data->Command == 2) {
+ *(UINT32*)Ptr &= Data->ChangeMask;
+ *(UINT32*)Ptr |= Data->ChangeValue;
+ }
+ }
+ else if (Data->Command == 6) {
+ for (i = 0; i < (UINT8)TableInfo.Size; i++) {
+ Ptr[i] = Data->StructureData[i];
+ }
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(1, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ TableInfo.Offset = 8;
+ TableInfo.Size = sizeof(EFI_GUID);
+
+ Status = UpdateSmbiosTable(&TableInfo, UuidPtr);
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+#else
+{
+ VOID *NvramData;
+
+ NvramData = &Data->StructureData;
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 1;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ switch (Data->FieldOffset) {
+ case 0x04 :
+ case 0x05 :
+ case 0x06 :
+ case 0x07 :
+ case 0x19 :
+ case 0x1a : if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+
+ default: if ((Data->FieldOffset > 0x07) && (Data->FieldOffset < 0x18)) {
+ UINT8 *Ptr;
+
+ Ptr = GetStructureByHandle(&Handle);
+ UuidPtr = (UINT8*)&((SMBIOS_SYSTEM_INFO*)Ptr)->Uuid;
+ Ptr = UuidPtr + Data->FieldOffset - 8;
+
+ if (Data->Command < 3) {
+ if (Data->Command == 0) {
+ *Ptr &= (UINT8)Data->ChangeMask;
+ *Ptr |= (UINT8)Data->ChangeValue;
+ }
+ if (Data->Command == 1) {
+ *(UINT16*)Ptr &= (UINT16)Data->ChangeMask;
+ *(UINT16*)Ptr |= (UINT16)Data->ChangeValue;
+ }
+ if (Data->Command == 2) {
+ *(UINT32*)Ptr &= Data->ChangeMask;
+ *(UINT32*)Ptr |= Data->ChangeValue;
+ }
+ }
+ else if (Data->Command == 6) {
+ for (i = 0; i < (UINT8)TableInfo.Size; i++) {
+ Ptr[i] = Data->StructureData[i];
+ }
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+
+ DmiArray[Index].Offset = 0x08;
+ NvramData = UuidPtr;
+ TableInfo.Offset = 8;
+ TableInfo.Size = sizeof(EFI_GUID);
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(1, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, NvramData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ TRACE((-1, "Change structure. Type = %x, Handle = %x, Offset = %x\n",\
+ TableInfo.Type,\
+ TableInfo.Handle,\
+ TableInfo.Offset));
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ if ((Data->FieldOffset > 0x07) && (Data->FieldOffset < 0x18)) {
+ return DMI_SUCCESS;
+ }
+ else {
+ // Dynamically update strings in Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+ }
+}
+
+#if BASE_BOARD_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType2
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 2 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType2(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ if ( Data->FieldOffset != 4
+ && Data->FieldOffset != 5
+ && Data->FieldOffset != 6
+ && Data->FieldOffset != 7
+ && Data->FieldOffset != 8
+ && Data->FieldOffset != 0x0a
+ ) return DMI_BAD_PARAMETER;
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(2, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 2;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update strings in Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if SYS_CHASSIS_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType3
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 3 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType3(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *StructPtr;
+ UINT8 Instance;
+ STRING_TABLE *StringTablePtr;
+
+ switch (Data->FieldOffset) {
+ case 4:
+ case 6:
+ case 7:
+ case 8: if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+ case 5: if (Data->Command != 0) return DMI_BAD_PARAMETER;
+ break;
+ case 0x0d: if (Data->Command != 2) return DMI_BAD_PARAMETER;
+ break;
+ default: {
+ // Get instance number
+ Instance = GetInstanceByTypeHandle(3, Handle);
+ StringTablePtr = &StringType_3[0][0];
+ StringTablePtr += 6 * (Instance - 1);
+
+ while (StringTablePtr->Offset != 0xff) {
+ if (StringTablePtr->Offset == Data->FieldOffset) {
+ break;
+ }
+
+ StringTablePtr++;
+ };
+
+ if (StringTablePtr->Offset != 0xff) {
+ if (Data->Command != 0x5) {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+ else {
+ return DMI_BAD_PARAMETER;
+ }
+ }
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(3, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ if (Data->Command == 0 || Data->Command == 0x2)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 3;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ if (Data->Command == 0 || Data->Command == 0x2)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr != NULL) {
+ switch (Data->FieldOffset) {
+ case 0x05: ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->Type &= (UINT8)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->Type |= (UINT8)Data->ChangeValue;
+ break;
+ case 0x0d: ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->OemDefined &= (UINT32)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_ENCLOSURE_INFO*)StructPtr)->OemDefined |= (UINT32)Data->ChangeValue;
+ }
+ }
+
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if PROCESSOR_DMIEDIT_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType4
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 4 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType4(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+
+ switch (Data->FieldOffset) {
+ case 0x20:
+ case 0x21:
+ case 0x22: if (Data->Command != 0x5) return DMI_BAD_PARAMETER;
+ break;
+ default: return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 4;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if OEM_STRING_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType11
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 11 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType11(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ static UINT8 StringNumber = 0;
+
+ if (isWriteOnce(11, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ if (Data->Command == 0) {
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ StringNumber = (UINT8) Data->ChangeValue;
+ return DMI_SUCCESS;
+ }
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (!StringNumber) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ TableInfo.Offset = StringNumber;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 11;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = StringNumber - 1;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+ return DynamicUpdateType11(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if SYSTEM_CONFIG_OPTION_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType12
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 12 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType12(
+ UINT16 Handle,
+ SET_SMBIOS_STRUCTURE_DATA *Data,
+ BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ static UINT8 StringNumber = 0;
+
+ if (Data->Command == 0) {
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ StringNumber = (UINT8) Data->ChangeValue;
+ return DMI_SUCCESS;
+ }
+
+ if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ if (Data->FieldOffset != 4) return DMI_BAD_PARAMETER;
+ if (!StringNumber) return DMI_BAD_PARAMETER;
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(12, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ TableInfo.Offset = StringNumber;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 12;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = StringNumber - 1;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+ return DynamicUpdateType12(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if PORTABLE_BATTERY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType22
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 22 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType22(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *StructPtr;
+
+ switch (Data->FieldOffset) {
+ case 0x09:
+ case 0x0f:
+ case 0x15: if (Data->Command != 0) return DMI_BAD_PARAMETER;
+ break;
+ case 0x0a:
+ case 0x0c:
+ case 0x10:
+ case 0x12: if (Data->Command != 1) return DMI_BAD_PARAMETER;
+ break;
+ case 0x16: if (Data->Command != 2) return DMI_BAD_PARAMETER;
+ break;
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x0e:
+ case 0x14: if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+ default: return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(22, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ if (Data->Command == 0 || Data->Command == 0x1 || Data->Command == 0x2)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 22;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr != NULL) {
+ switch (Data->FieldOffset) {
+ case 0x09: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DeviceChemistry &= (UINT8)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DeviceChemistry |= (UINT8)Data->ChangeValue;
+ break;
+ case 0x0a: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapacity &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapacity |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x0c: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignVoltage &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignVoltage |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x0f: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->MaxErrorInBatteryData &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->MaxErrorInBatteryData |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x10: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSSerialNumber &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSSerialNumber |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x12: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSManufacturerDate &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->SBDSManufacturerDate |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x15: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapabilityMult &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->DesignCapabilityMult |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x16: ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->OEMSpecific &= (UINT32)Data->ChangeMask;
+ ((SMBIOS_PORTABLE_BATTERY_INFO*)StructPtr)->OEMSpecific |= (UINT32)Data->ChangeValue;
+ break;
+ }
+ }
+
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+#if SYSTEM_POWER_SUPPLY_INFO
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetType39
+//
+// Description: Updates Flash Data record with input DMI data
+// Updates SMBIOS Type 39 Structure in Runtime with DMI data
+//
+// Input: IN UINT16 Handle,
+// IN SET_SMBIOS_STRUCTURE_DATA *Data,
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetType39(
+ IN UINT16 Handle,
+ IN SET_SMBIOS_STRUCTURE_DATA *Data,
+ IN BOOLEAN Set
+)
+{
+ EFI_STATUS Status;
+ TABLE_INFO TableInfo;
+ UINT8 *StructPtr;
+
+ switch (Data->FieldOffset) {
+ case 0x04: if (Data->Command != 0) return DMI_BAD_PARAMETER;
+ break;
+ case 0x05:
+ case 0x06:
+ case 0x07:
+ case 0x08:
+ case 0x09:
+ case 0x0a:
+ case 0x0b: if (Data->Command != 5) return DMI_BAD_PARAMETER;
+ break;
+ case 0x0c:
+ case 0x0e:
+ case 0x10:
+ case 0x12:
+ case 0x14: if (Data->Command != 1) return DMI_BAD_PARAMETER;
+ break;
+ default: return DMI_BAD_PARAMETER;
+ }
+
+ if (Set == FALSE) return DMI_SUCCESS;
+
+ if (isWriteOnce(39, Data->FieldOffset, Handle)) return DMI_READ_ONLY;
+
+ // Fill TableInfo with input data
+ GetInputDataInfo(Handle, Data, &TableInfo);
+
+ if (Data->Command == 0 || Data->Command == 0x1)
+ *(UINT32*)Data->StructureData = Data->ChangeValue;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+
+ Status = UpdateSmbiosTable(&TableInfo, Data->StructureData);
+
+#else
+{
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ DmiArray[Index].Type = 39;
+ DmiArray[Index].Handle = Handle;
+ DmiArray[Index].Offset = Data->FieldOffset;
+ DmiArray[Index].Flags = 0;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index].Type,
+ DmiArray[Index].Handle,
+ DmiArray[Index].Offset,
+ DmiArray[Index].Flags);
+
+ Status = StoreNvramData(Var, &Data->StructureData, (UINTN)TableInfo.Size);
+}
+#endif
+
+ if (Status) {
+ return (UINT16)Status;
+ }
+
+ // Dynamically update the structure in the Smbios table
+ StructPtr = GetStructureByHandle(&Handle);
+ if (StructPtr != NULL) {
+ switch (Data->FieldOffset) {
+ case 0x04: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrUnitGroup &= (UINT8)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrUnitGroup |= (UINT8)Data->ChangeValue;
+ break;
+ case 0x0c: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->MaxPwrCapacity &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->MaxPwrCapacity |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x0e: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrSupplyChar &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->PwrSupplyChar |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x10: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputVoltProbeHandle &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputVoltProbeHandle |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x12: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->CoolingDevHandle &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->CoolingDevHandle |= (UINT16)Data->ChangeValue;
+ break;
+ case 0x14: ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputCurrentProbeHandle &= (UINT16)Data->ChangeMask;
+ ((SMBIOS_SYSTEM_PWR_SUPPY_INFO*)StructPtr)->InputCurrentProbeHandle |= (UINT16)Data->ChangeValue;
+ break;
+ }
+ }
+
+ return UpdateStrings(Handle, TableInfo, Data->StructureData);
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PnPFn52AddStructure
+//
+// Description: PnP function 52 Command 03: Add structure
+//
+// Input: IN SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+PnPFn52AddStructure (
+ IN SET_SMBIOS_STRUCTURE *p
+)
+{
+ UINT16 Status;
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *SrcPtr;
+ UINT8 *DestPtr;
+ UINT8 Type127Buffer[4];
+ SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer;
+ TABLE_INFO TableInfo;
+
+ dmiDataBuffer = (SET_SMBIOS_STRUCTURE_DATA*)p->Buffer32BitAddr;
+ DestPtr = GetStructureByHandle(&dmiDataBuffer->StructureHeader.Handle);
+
+ if (DestPtr) {
+ Status = DMI_INVALID_HANDLE;
+ }
+ else {
+ SrcPtr = SmbiosTable;
+ if (FindStructureType(&SrcPtr, &DestPtr, 127, 1)) {
+ if ((MaximumBufferSize - ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength) >= dmiDataBuffer->DataLength) {
+ if (p->Control & 1) {
+ TableInfo.Type = dmiDataBuffer->StructureHeader.Type;
+ TableInfo.Offset = dmiDataBuffer->FieldOffset;
+ TableInfo.Reserved = 0;
+ TableInfo.Flags = DMIEDIT_ADD_STRUC | DMIEDIT_EXTENDED_HDR;
+ TableInfo.HdrLength = sizeof(TABLE_INFO);
+ TableInfo.Size = dmiDataBuffer->DataLength;
+ TableInfo.Handle = dmiDataBuffer->StructureHeader.Handle;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, (UINT8*)&dmiDataBuffer->StructureHeader);
+ if (Status != 0) {
+ return Status;
+ }
+#else
+{
+ EFI_STATUS Status;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ TableInfo.Type,
+ TableInfo.Handle,
+ TableInfo.Offset,
+ TableInfo.Flags);
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ // Check if record already exists
+ //
+ // DmiDataSize can be anything since the purpose of this GetVariable
+ // call is to detect if the variable already exists or not. Its
+ // content is not used.
+ DmiDataSize = 0; // Dummy value
+ Status = pRS->GetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ &DmiData);
+
+ if (Status == EFI_NOT_FOUND) {
+ // Record not present, increment record count
+ DmiArray[Index].Type = TableInfo.Type;
+ DmiArray[Index].Handle = TableInfo.Handle;
+ DmiArray[Index].Offset = TableInfo.Offset;
+ DmiArray[Index].Flags = TableInfo.Flags;
+
+ DmiArray[0].Type += 1; // Increment # variable counter
+
+ Status = pRS->SetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray);
+ ASSERT_EFI_ERROR(Status);
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+ }
+
+ // Update DMI data record if already exists,
+ // or store new record if total record count in DmiArray was successfully
+ // updated
+ if (Status == EFI_BUFFER_TOO_SMALL || Status == EFI_SUCCESS) {
+ DmiDataSize = (UINTN)dmiDataBuffer->DataLength;
+ Status = pRS->SetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiDataSize,
+ (UINT8*)&dmiDataBuffer->StructureHeader);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+}
+#endif
+
+ // Copy Type 127
+ MemCpy(&Type127Buffer, DestPtr, 4);
+ MemCpy(DestPtr, (UINT8*)&dmiDataBuffer->StructureHeader, dmiDataBuffer->DataLength);
+ DestPtr = DestPtr + GetStructureLength(DestPtr);
+ MemCpy(DestPtr, &Type127Buffer, 4);
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+ }
+
+ Status = DMI_SUCCESS;
+ }
+ else {
+ Status = DMI_ADD_STRUCTURE_FAILED;
+ }
+ }
+ else {
+ Status = DMI_ADD_STRUCTURE_FAILED;
+ }
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PnPFn52DeleteStructure
+//
+// Description: PnP function 52 Command 04: Delete structure
+//
+// Input: IN SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer
+// IN BOOLEAN Set
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+PnPFn52DeleteStructure (
+ IN SET_SMBIOS_STRUCTURE *p
+)
+{
+ UINT16 Status;
+ UINT8 *SmbiosTable = (UINT8*)((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableAddress;
+ UINT8 *SmbiosTableEnd = SmbiosTable + ((SMBIOS_TABLE_ENTRY_POINT*)SmbiosTableEntryPoint)->TableLength;
+ UINT8 *DestPtr;
+ UINT16 i;
+ UINT16 RemainingSize;
+ SET_SMBIOS_STRUCTURE_DATA *dmiDataBuffer;
+ TABLE_INFO TableInfo;
+
+ dmiDataBuffer = (SET_SMBIOS_STRUCTURE_DATA*)p->Buffer32BitAddr;
+ DestPtr = GetStructureByHandle(&((SET_SMBIOS_STRUCTURE_DATA*)dmiDataBuffer)->StructureHeader.Handle);
+ if (DestPtr) {
+ if (p->Control & 1) {
+ UINT8 *SrcPtr;
+
+ TableInfo.Type = dmiDataBuffer->StructureHeader.Type;
+ TableInfo.Offset = 0xff;
+ TableInfo.Reserved = 0;
+ TableInfo.Flags = DMIEDIT_DELETE_STRUC | DMIEDIT_EXTENDED_HDR;
+ TableInfo.HdrLength = sizeof(TABLE_INFO);
+ TableInfo.Size = 0;
+ TableInfo.Handle = dmiDataBuffer->StructureHeader.Handle;
+
+#if !defined(SMBIOS_DMIEDIT_DATA_LOC) || SMBIOS_DMIEDIT_DATA_LOC != 2
+ Status = UpdateSmbiosTable(&TableInfo, (UINT8*)&dmiDataBuffer->StructureHeader);
+ if (Status != 0) {
+ return Status;
+ }
+#else
+{
+ EFI_STATUS Status;
+
+ Swprintf(Var, L"DmiVar%02x%04x%02x%02x",
+ TableInfo.Type,
+ TableInfo.Handle,
+ TableInfo.Offset,
+ TableInfo.Flags);
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray);
+
+ if (Status == EFI_SUCCESS) {
+ Index = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+ ++Index;
+ }
+ else {
+ Index = 1;
+ }
+
+ // Check if record already exists
+ //
+ // DmiDataSize can be anything since the purpose of this GetVariable
+ // call is to detect if the variable already exists or not. Its
+ // content is not used.
+ DmiDataSize = 0; // Dummy value
+ Status = pRS->GetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DmiDataSize,
+ &DmiData);
+
+ if (Status == EFI_NOT_FOUND) {
+ // Record not present, increment record count
+ DmiArray[Index].Type = TableInfo.Type;
+ DmiArray[Index].Handle = TableInfo.Handle;
+ DmiArray[Index].Offset = TableInfo.Offset;
+ DmiArray[Index].Flags = TableInfo.Flags;
+
+ DmiArray[0].Type += 1; // Increment # variable counter
+
+ Status = pRS->SetVariable(
+ DmiArrayVar,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray);
+ ASSERT_EFI_ERROR(Status);
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+ }
+
+ // Update DMI data record if already exists,
+ // or store new record if total record count in DmiArray was successfully
+ // updated
+ if (Status == EFI_BUFFER_TOO_SMALL || Status == EFI_SUCCESS) {
+ DmiDataSize = (UINTN)sizeof(TABLE_INFO);
+ Status = pRS->SetVariable(
+ Var,
+ &EfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiDataSize,
+ &TableInfo);
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ if (Status != 0) {
+ return (UINT16)Status;
+ }
+}
+#endif
+
+ // Copy / update the remaining structures in the Smbios Table
+ SrcPtr = DestPtr + GetStructureLength(DestPtr);
+ RemainingSize = (UINT16)(SmbiosTableEnd - SrcPtr);
+
+ for (i = 0; i < RemainingSize; i++) {
+ *DestPtr = *SrcPtr;
+ SrcPtr++;
+ DestPtr++;
+ }
+
+ // Update SMBIOS Structure Table Entry Point - Structure Table Length, Intermediate checksum
+ UpdateHeaderInfo();
+ }
+
+ Status = DMI_SUCCESS;
+ }
+ else {
+ Status = DMI_INVALID_HANDLE;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetSmbiosStructure
+//
+// Description: DMIEdit function to update the structures and saves the
+// DMI data in the Flash Part for subsequent boot.
+//
+// Input: IN SET_SMBIOS_STRUCTURE *p
+//
+// Output: UINT8 - Status
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT16
+SetSmbiosStructure(
+ IN SET_SMBIOS_STRUCTURE *p
+)
+{
+ SET_SMBIOS_STRUCTURE_DATA *Data = (SET_SMBIOS_STRUCTURE_DATA *)p->Buffer32BitAddr;
+ UINT8 *SmbTable;
+ UINT16 Handle = Data->StructureHeader.Handle;
+
+ if (!SmbiosTableEntryPoint) return DMI_FUNCTION_NOT_SUPPORTED;
+
+ if (Data->Command == 3) { // Add structure
+ return PnPFn52AddStructure(p);
+ }
+
+ if (Data->Command == 4) { // Delete structure
+ return PnPFn52DeleteStructure(p);
+ }
+
+ SmbTable = GetStructureByHandle(&Handle);
+ if (!SmbTable) return DMI_INVALID_HANDLE;
+
+ // Verify header
+ if (*(UINT16*)&Data->StructureHeader != *(UINT16*)SmbTable) return DMI_BAD_PARAMETER;
+
+ // Currently only accept certain table types;
+ switch (Data->StructureHeader.Type) {
+ case 0:
+ return SetType0(Handle, Data, p->Control&1);
+ case 1:
+ return SetType1(Handle, Data, p->Control&1);
+#if BASE_BOARD_INFO
+ case 2:
+ return SetType2(Handle, Data, p->Control&1);
+#endif
+#if SYS_CHASSIS_INFO
+ case 3:
+ return SetType3(Handle, Data, p->Control&1);
+#endif
+#if PROCESSOR_DMIEDIT_SUPPORT
+ case 4:
+ return SetType4(Handle, Data, p->Control&1);
+#endif
+#if OEM_STRING_INFO
+ case 11:
+ return SetType11(Handle, Data, p->Control&1);
+#endif
+#if SYSTEM_CONFIG_OPTION_INFO
+ case 12:
+ return SetType12(Handle, Data, p->Control&1);
+#endif
+#if PORTABLE_BATTERY_INFO
+ case 22:
+ return SetType22(Handle, Data, p->Control&1);
+#endif
+#if SYSTEM_POWER_SUPPLY_INFO
+ case 39:
+ return SetType39(Handle, Data, p->Control&1);
+#endif
+ }
+ return DMI_BAD_PARAMETER;
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c
new file mode 100644
index 0000000..4bf72a1
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c
@@ -0,0 +1,386 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c 11 2/17/15 1:16p Davidd $
+//
+// $Revision: 11 $
+//
+// $Date: 2/17/15 1:16p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosDMIEditSupport/SmbiosNvramFunc.c $
+//
+// 11 2/17/15 1:16p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 10 11/15/13 4:34p Davidd
+// [TAG] EIP143321
+// [Category] Improvement
+// [Description] Perform "CppCheck" on Smbios module for
+// '4.6.5.1_SMBIOS_36' release
+// [Files] SmbiosBoard.c
+// Smbios.c
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 9 9/04/12 11:05a Davidd
+// [TAG] EIP96286
+// [Category] Improvement
+// [Description] Please help to reserve DMI Data for AFUDOS with /r in
+// Capsule Mode
+// [Files] Smbios.sdl
+// SmbiosDMIEdit.mak
+// SmbiosNvramFunc.c
+//
+// 8 8/02/12 12:48p Davidd
+// [TAG] EIP96064
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMBIOS: DmiEdit support creates NVRAM variables with names
+// of incorrect length
+// [RootCause] Swprintf_s function creates 15 characters variable name
+// with NULL terminator in last byte.
+// [Solution] Use Swprintf function instead
+// [Files] Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 7 11/17/11 2:41p Davidd
+// [TAG] EIP74579
+// [Category] Improvement
+// [Description] Update SMBIOS moudule to let AMDELNX support SMBIOS
+// spec 2.7
+// (remove the 64 characters string limitation)
+// [Files] Smbios.h
+// SmbiosStaticData.sdl
+// Smbios.c
+// SMBios.dxs
+// SmbiosDMIEdit.sdl
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosNvram.c
+// SmbiosFlashData.sdl
+//
+// 6 5/04/11 3:20p Davidd
+// [TAG] EIP57144
+// [Category] NEW FEATURE
+// [Description] Allow SMBIOS Type 39 to be modified using DMIEdit
+// [Files] SmbiosBoard.c
+// Smbios.h
+// SmbiosDynamicData.h
+// Smbios.c
+// SmbiosDmieditFunc.c
+// SmbiosNvramFunc.c
+//
+// 5 3/02/11 11:47a Davidd
+// [TAG] EIP54264
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Data is assumed valid without checking after some
+// GetVariable calls
+// [RootCause] No error checking
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosNvramFunc.c
+// SmbiosDMIEditFunc.c
+//
+// 4 1/14/11 3:57p Davidd
+// [TAG] EIP50564
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BIOS can't keep DMI data after flash BIOS with /p /b /n /r
+// parameters
+// [RootCause] Side effect of previous changes (NVRAM variable name
+// format
+// has been changed)
+// [Solution] Problem has been fixed with code changes
+// [Files] SmbiosNvramFunc.c
+//
+// 3 10/21/10 11:36a Davidd
+// [TAG] EIP46394
+// [Category] BUG FIX
+// [Severity] Important
+// [Symptom] Incorrect variable size for GetVariable() usage in
+// Smbios module
+// [RootCause] GetVariable is called with incorrect "DataSize" type.
+// [Solution] Corrected "DataSize" type in all GetVariable calls.
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosNvramFunc.c
+//
+// 2 12/04/09 3:28p Davidd
+// Corrected the DMIEdit data not updated after being updated 5-6 times
+// (when NVRAM is used to store DMIEdit data) - EIP 30837.
+//
+// 1 2/02/09 4:21p Davidd
+// Initial checkin
+//
+//**********************************************************************//
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include "Protocol\Smbios.h"
+#include "SmbiosDMIEdit.h"
+
+#if SMBIOS_DMIEDIT_DATA_LOC == 2
+static BOOLEAN DmiEditVarPresent = FALSE;
+EFI_GUID gEfiSmbiosNvramGuid = EFI_SMBIOS_NVRAM_DATA_GUID;
+CHAR16 *DmiArrayVar = L"DmiArray";
+DMI_VAR DmiArray[DMI_ARRAY_COUNT] = {0};
+UINTN DmiArraySize = DMI_ARRAY_COUNT * sizeof(DMI_VAR);
+CHAR16 *S1 = L" ";
+UINT8 DmiData[0x1000];
+UINT8 *DmiDataPtr;
+UINT8 Buffer[0x400];
+UINTN BufferSize;
+UINTN DmiDataLength[DMI_ARRAY_COUNT];
+UINT8 gRecoveryKeepDMIFlag = FALSE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PreserveDmiEditData
+//
+// Description: Preserve the DMIEdit data by loading its data into memory
+// prior to flashing
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PreserveDmiEditData (VOID)
+{
+ EFI_STATUS Status;
+ UINT8 Count;
+ UINT8 Index;
+
+ //
+ // Get number of DMI data records in NVRAM
+ //
+ // Note: DMI data record actually starts with record #1,
+ // first record #0 holds total number of DMI data records
+ // instead of TABLE_INFO
+ // ===> DmiArray[0].Type = count
+ //
+ Status = pRS->GetVariable(
+ DmiArrayVar,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &DmiArraySize,
+ &DmiArray[0]);
+
+ if (Status == EFI_SUCCESS) {
+ DmiDataPtr = DmiData;
+
+ Count = DmiArray[0].Type; // Note: DmiArray[0] has count #
+
+ // Get DMI data into memory. The data will be saved back into
+ // NVRAM later in RestoreDmiEditData
+ for (Index = 0; Index < Count; Index++) {
+ Swprintf(S1, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index + 1].Type,
+ DmiArray[Index + 1].Handle,
+ DmiArray[Index + 1].Offset,
+ DmiArray[Index + 1].Flags);
+
+ BufferSize = sizeof(Buffer);
+ Status = pRS->GetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &BufferSize,
+ &Buffer);
+
+ if (Status == EFI_SUCCESS) {
+ MemCpy(DmiDataPtr, Buffer, BufferSize);
+ DmiDataLength[Index] = BufferSize;
+ DmiDataPtr += BufferSize;
+ }
+ else {
+ DmiDataLength[Index] = 0;
+ }
+ }
+
+ DmiEditVarPresent = TRUE;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RestoreDmiEditData
+//
+// Description: Restore the DMIEdit data in NVRAM with data previously loaded
+// in memory by PreserveDmiEditData.
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RestoreDmiEditData (VOID)
+{
+ UINT8 Count;
+ UINT8 Index;
+
+ // DMI data were read and saved in memory in PreserveDmiEditData.
+ // Now save DMI data back into NVRAM if present
+ if (DmiEditVarPresent) {
+ pRS->SetVariable(
+ DmiArrayVar,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiArraySize,
+ &DmiArray[0]);
+
+ DmiDataPtr = DmiData;
+
+ Count = DmiArray[0].Type; // Note: DmiArray[0] has count # instead of Type/Offset
+
+ for (Index = 0; Index < Count; Index++) {
+ Swprintf(S1, L"DmiVar%02x%04x%02x%02x",
+ DmiArray[Index + 1].Type,
+ DmiArray[Index + 1].Handle,
+ DmiArray[Index + 1].Offset,
+ DmiArray[Index + 1].Flags);
+
+ pRS->SetVariable(
+ S1,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ DmiDataLength[Index],
+ DmiDataPtr);
+
+ DmiDataPtr += DmiDataLength[Index];
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecoveryPreserveDmiEditData
+//
+// Description: Preserve the DMIEdit data by loading its data into memory
+// prior to flashing (for capsule mode)
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RecoveryPreserveDmiEditData (VOID)
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiSmbiosNvramGuid = {0x4b3082a3, 0x80c6, 0x4d7e, { 0x9c, 0xd0, 0x58, 0x39, 0x17, 0x26, 0x5d, 0xf1 }};
+ CHAR16 *PreserveSmbiosNvramVar = L"PreserveSmbiosNvramVar";
+ UINTN Size = sizeof (UINT8);
+ UINT32 PreserveSmbiosNvram;
+
+ gRecoveryKeepDMIFlag = FALSE;
+
+ Status = pRS->GetVariable (
+ PreserveSmbiosNvramVar,
+ &gEfiSmbiosNvramGuid,
+ NULL,
+ &Size,
+ &PreserveSmbiosNvram
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gRecoveryKeepDMIFlag = TRUE;
+ PreserveDmiEditData ();
+ }
+
+ Status = pRS->SetVariable (
+ PreserveSmbiosNvramVar,
+ &gEfiSmbiosNvramGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
+ 0,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecoveryRestoreDmiEditData
+//
+// Description: Restore the DMIEdit data in NVRAM with data previously loaded
+// in memory by PreserveDmiEditData (for capsule mode)
+//
+// Input: None
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+RecoveryRestoreDmiEditData (VOID)
+{
+ if (gRecoveryKeepDMIFlag) {
+ RestoreDmiEditData ();
+ }
+
+ gRecoveryKeepDMIFlag = FALSE;
+}
+#endif
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm
new file mode 100644
index 0000000..69e5839
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm
@@ -0,0 +1,67 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm 4 6/02/09 11:28a Davidd $
+;
+; $Revision: 4 $
+;
+; $Date: 6/02/09 11:28a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.asm $
+;
+; 4 6/02/09 11:28a Davidd
+; Updated AMI headers (EIP 22180)
+;
+; 3 3/29/07 6:13p Davidd
+; Changed the year in the AMI banner.
+;
+; 2 12/15/06 5:48p Davidd
+; Code cleanup and reformatted to coding standard.
+;
+; 1 4/29/05 2:06p Davidd
+; Initial checkin.
+;
+;**********************************************************************
+
+ INCLUDE token.equ
+
+.686p
+.model flat
+.data
+ dd '_ASB'
+_FlashDataSize label dword
+ dd offset FlashDataEnd - offset FlashDataStart
+;align 4
+FlashDataStart EQU $
+ db MKF_FLASHDATA_SIZE dup (0FFh)
+FlashDataEnd label byte
+ db 4 dup (0FFh) ;Mark end of table. Same size as each flash data entry.
+end
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif
new file mode 100644
index 0000000..4c4cd85
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmbiosFlashData"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBios\SmbiosFlashData\"
+ RefName = "SmbiosFlashData"
+[files]
+"\SmbiosFlashData.sdl"
+"\SmbiosFlashData.mak"
+"\SmbiosFlashData.asm"
+"\pad.txt"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak
new file mode 100644
index 0000000..e02b4ab
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak
@@ -0,0 +1,86 @@
+#************************************************************************
+#************************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#************************************************************************
+#************************************************************************
+#************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak 8 3/15/10 12:10p Davidd $
+#
+# $Revision: 8 $
+#
+# $Date: 3/15/10 12:10p $
+#************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosFlashData/SmbiosFlashData.mak $
+#
+# 8 3/15/10 12:10p Davidd
+# Making sure the checksum is not calculated, else, the system hangs on
+# reset after flash. FFS_CHECKSUM=0.
+#
+# 7 5/15/09 3:26p Davidd
+# Changes made to the build process to support Nested Firmware Volume
+#
+# 6 1/28/09 11:55a Davidd
+# New changes added to support DMIEdit data storage location in flash
+# selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+#
+# 5 12/30/08 3:27p Davidd
+# Removed switches to ganerate List and Map files.
+#
+# 4 3/29/07 6:12p Davidd
+# Changed the year in the AMI banner.
+#
+# 3 1/27/06 5:40p Davidd
+# Set compression to off.
+#
+# 2 8/22/05 5:08p Davidd
+# Set file compression to ON.
+#
+# 1 4/29/05 2:06p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"!="2"
+all : SMBIOS_FLASHDATA
+
+SMBIOS_FLASHDATA : $(BUILD_DIR)\SMBiosFlashData.ffs
+
+$(BUILD_DIR)\SMBiosFlashData.ffs : $(BUILD_DIR)\SMBiosFD.bin
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=FD44820B-F1AB-41C0-AE4E-0C55556EB9BD\
+ TYPE=EFI_FV_FILETYPE_FREEFORM \
+ BINFILE=$** FFSFILE=$@ COMPRESS=0 NAME=SmbiosFlashData FFS_CHECKSUM=0
+
+$(BUILD_DIR)\SMBiosFD.bin : $(BUILD_DIR)\SMBiosFD.exe
+ exe2bin $(BUILD_DIR)\SMBiosFD.exe $(BUILD_DIR)\SMBiosFD.tmp
+ copy /b $(BUILD_DIR)\SMBiosFD.tmp + /b $(SOURCE_DIR)\pad.txt /b $(BUILD_DIR)\SMBiosFD.bin
+
+$(BUILD_DIR)\SMBiosFD.exe : $(SMBIOS_FLASHDATA_DIR)\SMBiosFlashData.asm $(SMBIOS_FLASHDATA_DIR)\SMBiosFlashData.mak
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\SMBiosFD.obj $(SMBIOS_FLASHDATA_DIR)\SMBiosFlashData.asm
+ $(ASMLINK) $(BUILD_DIR)\SMBiosFD.obj, $(BUILD_DIR)\SMBiosFD.exe , NUL,,,
+!ENDIF
+
+#************************************************************************
+#************************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#************************************************************************
+#************************************************************************
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl
new file mode 100644
index 0000000..4e2625c
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/SmbiosFlashData.sdl
@@ -0,0 +1,37 @@
+TOKEN
+ Name = "SmbiosFlashData_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmbiosFlashData support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "SmbiosDMIEdit_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "FLASHDATA_SIZE"
+ Value = "2048"
+ Help = "SMBIOS Flash Data size."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "SMBIOS_FLASHDATA_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosFlashData.mak to Project"
+ File = "SmbiosFlashData.Mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosFlashData.ffs"
+ Parent = "$(SMBIOS_DIR)\SmbiosFlashData.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "!=" "2"
+End
+
diff --git a/Core/EM/SMBIOS/SmbiosFlashData/pad.txt b/Core/EM/SMBIOS/SmbiosFlashData/pad.txt
new file mode 100644
index 0000000..6715cef
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosFlashData/pad.txt
@@ -0,0 +1 @@
+_v_z \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
new file mode 100644
index 0000000..49a35da
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c
@@ -0,0 +1,497 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c 11 2/17/15 1:17p Davidd $
+//
+// $Revision: 11 $
+//
+// $Date: 2/17/15 1:17p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.c $
+//
+// 11 2/17/15 1:17p Davidd
+// [TAG] EIP205509
+// [Category] Improvement
+// [Description] Merge Aptio V Smbios EIP193807, 193858, 196901 changes
+// into Aptio 4 Smbios
+// [Files] SmbiosDmiEdit.sdl
+// SmbiosDmiEdit.c
+// SmbiosNvramFunc.c
+// SmbiosGetFlashData.c
+//
+// 10 5/23/13 6:10p Davidd
+// [TAG] EIP124635
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When DMIEdit data area in BootBlock is erased with 0x00
+// value, the system hangs at CP 0x62
+// [RootCause] In function FindRawSection, a pointer is used to
+// traverse sections in the FFS to locate the DMIEdit raw data section. In
+// case the "size" of the header become corrupted (cleared to zero), this
+// zero value is added to the pointer causes it not to move making the
+// system hang.
+// [Solution] Check if the size is zero then break out of the while
+// loop
+// [Files] SmbiosGetFlashData.c
+//
+// 9 8/30/11 4:15p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 8 5/11/11 12:35p Davidd
+// [TAG] EIP58171
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible for AFU preserve DMI structure feature.
+// [RootCause] TABLE_INFO structure of SmbiosDMIEdit is not backward
+// compatible.
+// [Solution] New TABLE_INFO structure defined for backward
+// compatibility and support added.
+// [Files] Smbios.c
+// SmbiosDMIEdit.h
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+//
+// 7 11/02/10 4:14p Davidd
+// [TAG] EIP42938
+// [Category] BUG FIX
+// [Severity] Critical
+// [Symptom] The SMBIOS string field cannot be successfully updated
+// if it was programmed to Null by the 3-party SMBIOS tool
+// [RootCause] BIOS did not have support for NULL strings
+// [Solution] Problem has been fixed with code changes
+// [Files]
+// Smbios.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosDMIEdit.h
+// SmbiosFlashData.sdl
+//
+// 6 6/02/09 11:25a Davidd
+// Updated AMI and function headers. (EIP 22180)
+//
+// 5 12/16/08 2:28a Iminglin
+// (EIP17767) The function value of FindFile for compliance.
+//
+// 4 3/29/07 6:11p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 3 12/15/06 5:47p Davidd
+// Code cleanup and reformatted to coding standard.
+//
+// 2 3/21/06 8:44p Fasihm
+// Changed the protocol name FvBlock.h to FirmwareVolumeBlock.h to be
+// compatable with the new Aptio 4.5 Core and later.
+//
+// 1 4/29/05 2:07p Davidd
+// Initial checkin.
+//
+// 2 6/12/04 11:54p Markw
+//
+// 1 5/20/04 3:41p Markw
+//
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\SmbiosGetFlashDataProtocol.h>
+#include <Protocol\FirmwareVolumeBlock.h>
+
+#define Align4(Value) (((Value)+3) & ~3)
+#define Align8(Value) (((Value)+7) & ~7)
+#define SECTION_SIZE(SectionHeaderPtr) \
+ ( (UINT32) ( *((UINT32 *) ((EFI_COMMON_SECTION_HEADER *)SectionHeaderPtr)->Size) & 0x00ffffff) )
+
+#pragma pack(1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TABLE_INFO
+//
+// Description: DMI data record
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+#define DMIEDIT_WRITE_ONCE 0x01
+#define DMIEDIT_DELETE_STRUC 0x02
+#define DMIEDIT_ADD_STRUC 0x04
+#define DMIEDIT_EXTENDED_HDR 0x80
+
+typedef struct {
+ UINT8 Type;
+ UINT8 Offset; // Structure field offset, or string number for Type 11 and 12
+ UINT8 Reserved; // Size of string including \0 or UUID (16)
+ UINT8 Flags; // Bit0 = Write Once
+ // Bit1 = Delete Structure
+ // Bit2 = Add structure
+ // Bit7 = Extended Header
+ UINT8 HdrLength;
+ UINT16 Size;
+ UINT16 Handle;
+} TABLE_INFO;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: ROM_INFO
+//
+// Description: DMI Data Table Header
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+typedef struct {
+ UINT32 Signature;
+ UINT32 Size;
+} ROM_INFO;
+
+#pragma pack()
+
+
+EFI_GUID FlashDataFile = {0xFD44820B,0xF1AB,0x41c0,0xAE,0x4E,0x0C,0x55,0x55,0x6E,0xB9,0xBD};
+EFI_GUID ZeroGuid = {0,0,0,0,0,0,0,0,0,0,0};
+EFI_GUID FFGuid = {0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff};
+
+ROM_INFO gRomInfo;
+void *gRomData;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CompareGuid
+//
+// Description: Compares two input GUIDs
+//
+// Input: IN EFI_GUID *G1
+// IN EFI_GUID *G2
+//
+// Output: INT8 - 0/-1 for Equal/Not Equal
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INT8
+CompareGuid (
+ IN EFI_GUID *G1,
+ IN EFI_GUID *G2
+)
+{
+ UINT32 *p1 = (UINT32*)G1, *p2 = (UINT32*)G2;
+ UINTN i;
+ for(i=0; i<4; ++i) {
+ if(p1[i] != p2[i]) return -1;
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashTableInfo
+//
+// Description: Get Flash Data location and size.
+//
+// Input: IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This
+// IN OUT VOID **Location
+// IN OUT UINT32 *Size
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetFlashTableInfo (
+ IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This,
+ IN OUT VOID **Location,
+ IN OUT UINT32 *Size
+)
+{
+ *Location = gRomData;
+ *Size = gRomInfo.Size;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetField
+//
+// Description: Get Flash Data Field
+//
+// Input: IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This
+// IN UINT8 Table
+// IN UINT8 Offset
+// IN VOID **Field
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetField (
+ IN EFI_SMBIOS_FLASH_DATA_PROTOCOL *This,
+ IN UINT8 Table,
+ IN UINT8 Offset,
+ IN VOID **Field
+)
+{
+ TABLE_INFO *p = gRomData;
+
+ while ( p->Offset != 0xff && (p->Type != Table || p->Offset != Offset)) {
+ p = (TABLE_INFO*) ((UINT8*)(p+1) + p->Size);
+ }
+
+ if (p->Offset != 0xff) {
+ *Field = p + 1;
+ return EFI_SUCCESS;
+ }
+
+ *Field = 0;
+ return EFI_NOT_FOUND;
+}
+
+
+EFI_SMBIOS_FLASH_DATA_PROTOCOL gSmbiosFlashDataProtocol = {
+ GetFlashTableInfo,
+ GetField
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindRawSection
+//
+// Description: Find the RAW section
+//
+// Input: IN VOID *Section
+// IN VOID *End
+//
+// Output: VOID* - Pointer to Raw Section if found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+FindRawSection (
+ IN VOID *Section,
+ IN VOID *End
+)
+{
+ EFI_COMMON_SECTION_HEADER *p = Section;
+ while((INT32)p < (INT32)End) //Use signed because 0 = 0x100000000
+ {
+ if (p->Type == EFI_SECTION_RAW) return (p+1);
+
+ if (Align4(SECTION_SIZE(p)) == 0x00) {
+ return 0; // Section size = 0 indicates data is corrupted
+ }
+
+ p = (EFI_COMMON_SECTION_HEADER*)((UINT8*)p+Align4(SECTION_SIZE(p)));
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindFile
+//
+// Description: Find file in the FV with the input GUID
+//
+// Input: IN EFI_GUID *Guid
+// IN VOID *File
+// IN VOID *EndOfFiles
+//
+// Output: VOID* - Pointer to File if found
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID*
+FindFile (
+ IN EFI_GUID *Guid,
+ IN VOID *File,
+ IN VOID *EndOfFiles
+)
+{
+ EFI_FFS_FILE_HEADER *p = File;
+
+ while(((INT32)p < (INT32)EndOfFiles) &&
+ ((INT32)(p+sizeof(EFI_FFS_FILE_HEADER)) < (INT32)EndOfFiles)) // Use signed because 0 = 0x100000000
+ {
+ if (0==CompareGuid(Guid,&p->Name)) {
+ //Found File.
+ return FindRawSection(
+ p+1,
+ (UINT8*)p + (*(UINT32*)p->Size & 0xffffff) - sizeof(*p)
+ );
+ }
+ //Check for last of File in firmware volume.
+ if (0==CompareGuid(&p->Name,&FFGuid) || 0==CompareGuid(&p->Name,&ZeroGuid))
+ return NULL;
+
+ p = (EFI_FFS_FILE_HEADER*)((UINT8*)p + Align8((*(UINT32*)p->Size & 0xffffff)));
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetDataLocation
+//
+// Description: Find the Flash Data file in the FV.
+//
+// Input: None
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetDataLocation (VOID)
+{
+ EFI_GUID gEfiFirmwareVolumeBlockProtocolGuid = EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID;
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL *FvBlock;
+ EFI_PHYSICAL_ADDRESS Address;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS Status;
+ UINTN i;
+ UINTN NumHandles;
+ void *FirstFile;
+ void *EndOfFiles;
+ void *File;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ NULL,
+ &NumHandles,
+ &HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i < NumHandles; ++i) {
+ Status = pBS->HandleProtocol(HandleBuffer[i],
+ &gEfiFirmwareVolumeBlockProtocolGuid,
+ &FvBlock);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = FvBlock->GetPhysicalAddress(FvBlock, &Address);
+
+ if (Status == EFI_SUCCESS) {
+ FirstFile = (UINT8*)Address
+ + ((EFI_FIRMWARE_VOLUME_HEADER*)Address)->HeaderLength;
+
+ EndOfFiles = (UINT8*)Address
+ + ((EFI_FIRMWARE_VOLUME_HEADER*)Address)->FvLength;
+
+ File = FindFile(&FlashDataFile, FirstFile, EndOfFiles);
+ if (!File) {
+ Status = EFI_NOT_FOUND;
+ continue;
+ }
+
+ gRomInfo = *(ROM_INFO*)File;
+ gRomData = (ROM_INFO*)File + 1;
+ break;
+ }
+ }
+
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosGetFlashDataInstall
+//
+// Description: Driver entry point for SmbiosGetFlashData
+//
+// Input: IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosGetFlashDataInstall (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_GUID gSmbiosFlashDataProtocolGuid = EFI_SMBIOS_FLASH_DATA_PROTOCOL_GUID;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = GetDataLocation();
+ if (EFI_ERROR(Status)) return Status;
+
+ return pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gSmbiosFlashDataProtocolGuid,&gSmbiosFlashDataProtocol,
+ NULL);
+}
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif
new file mode 100644
index 0000000..880fa15
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmbiosGetFlashData"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBios\SmbiosGetFlashData\"
+ RefName = "SmbiosGetFlashData"
+[files]
+"\SmbiosGetFlashData.sdl"
+"\SmbiosGetFlashData.mak"
+"\SmbiosGetFlashData.c"
+"\SmbiosGetFlashData.dxs"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs
new file mode 100644
index 0000000..4e37f65
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs 5 8/30/11 4:15p Davidd $
+//
+// $Revision: 5 $
+//
+// $Date: 8/30/11 4:15p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.dxs $
+//
+// 5 8/30/11 4:15p Davidd
+// [TAG] EIP65648
+// [Category] Improvement
+// [Description] Update SMBIOS eModules for uEFI 2.3.1 / PI 1.2
+// compliance
+// [Files] Smbios.c
+// Smbios.dxs
+// SmbiosDMIEdit.c
+// SmbiosDMIEditFunc.c
+// SmbiosGetFlashData.c
+// SmbiosGetFlashData.dxs
+//
+// 4 6/02/09 11:27a Davidd
+// Updated AMI header section (EIP 22180)
+//
+// 3 3/29/07 6:11p Davidd
+// Changed the year in the AMI banner and adjust indentation to coding
+// standard.
+//
+// 2 3/21/06 8:45p Fasihm
+// Changed the protocol name FvBlock.h to FirmwareVolumeBlock.h to be
+// compatable with the new Aptio 4.5 Core and later.
+//
+//
+//**********************************************************************
+
+#include <Protocol\FirmwareVolumeBlock.h>
+
+DEPENDENCY_START
+ EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak
new file mode 100644
index 0000000..f174415
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak
@@ -0,0 +1,82 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak 6 8/04/10 2:45p Davidd $
+#
+# $Revision: 6 $
+#
+# $Date: 8/04/10 2:45p $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.mak $
+#
+# 6 8/04/10 2:45p Davidd
+# Remove environment variables "MAKEFILE" and "INCLUDE" - EIP 40634.
+#
+# 5 6/02/09 11:23a Davidd
+# Updated AMI header section (EIP 22180)
+#
+# 4 1/28/09 11:54a Davidd
+# New changes added to support DMIEdit data storage location in flash
+# selectable via SMBIOS_DMIEDIT_DATA_LOC SDL token
+#
+# 3 12/30/08 3:24p Davidd
+# Changes added for x32 and x64 binary support.
+#
+# 2 3/29/07 6:08p Davidd
+# Changed the year in the AMI banner.
+#
+# 1 4/29/05 2:07p Davidd
+# Initial checkin.
+#
+#************************************************************************//
+
+!IF "$(SMBIOS_DMIEDIT_DATA_LOC)"!="2"
+all : SMBIOS_GETFLASHDATA_SUPPORT
+
+SMBIOS_GETFLASHDATA_SUPPORT : $(BUILD_DIR)\SmbiosGetFlashData.mak SmbiosGetFlashDataBin
+
+$(BUILD_DIR)\SmbiosGetFlashData.mak : $(SMBIOS_GETFLASHDATA_DIR)\$(@B).cif $(SMBIOS_GETFLASHDATA_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMBIOS_GETFLASHDATA_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SmbiosGetFlashDataBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosGetFlashData.mak all\
+!IF "$(x64_BUILD)"=="1"
+ NAME=SmbiosGetFlashData64 \
+!ELSE
+ NAME=SmbiosGetFlashData32 \
+!ENDIF
+ MAKEFILE=$(BUILD_DIR)\SmbiosGetFlashData.mak\
+ GUID=DED7956D-7E20-4f20-91A1-190439B04D5B \
+ ENTRY_POINT=SmbiosGetFlashDataInstall \
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+!ENDIF
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2009, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl
new file mode 100644
index 0000000..2ed3cf2
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosGetFlashData/SmbiosGetFlashData.sdl
@@ -0,0 +1,36 @@
+TOKEN
+ Name = "SmbiosGetFlashData_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmbiosGetFlashData support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SmbiosDMIEdit_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "SMBIOS_GETFLASHDATA_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosGetFlashData.mak to Project"
+ File = "SmbiosGetFlashData.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosGetFlashData32.ffs"
+ Parent = "$(SMBIOS_DIR)\SmbiosGetFlashData32.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "0"
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "!=" "2"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosGetFlashData64.ffs"
+ Parent = "$(SMBIOS_DIR)\SmbiosGetFlashData64.ffs"
+ InvokeOrder = ReplaceParent
+ Token = "x64_BUILD" "=" "1"
+ Token = "SMBIOS_DMIEDIT_DATA_LOC" "!=" "2"
+End
+
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c
new file mode 100644
index 0000000..e5869b0
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPei.c
@@ -0,0 +1,201 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPei.c 1 5/27/14 1:44p Davidd $
+//
+// $Revision: 1 $
+//
+// $Date: 5/27/14 1:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPei.c $
+//
+// 1 5/27/14 1:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Files] SmbiosPeim.cif
+// SmbiosPeim.sdl
+// SmbiosPeim.mak
+// SmbiosPeim.dxs
+// SmbiosPei.c
+//
+// 1 4/29/14 4:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] Core\EM\SMBios\SmbiosPeim\SmbiosPeim.cif
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.sdl
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.mak
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.dxs
+// Core\EM\SMBios\SmbiosPeim\SmbiosPei.c
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SmbiosPei.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiPeiLib.h>
+#include <Ppi\ReadOnlyVariable2.h>
+#include "Core\Ppi\MemoryDiscovered.h"
+
+extern VOID OemRuntimeShadowRamWrite(IN BOOLEAN Enable);
+extern UINT8 getWakeupTypeForSmbios(VOID);
+
+EFI_STATUS
+SmbiosAfterInitMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+);
+
+static EFI_GUID gPeiPermanentMemInstalledPpiGuid = PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID;
+
+static EFI_PEI_NOTIFY_DESCRIPTOR SmbiosPeiNotify[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiPermanentMemInstalledPpiGuid,
+ SmbiosAfterInitMemory
+ }
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSmbiosWakeupType
+//
+// Description: Detect and update SMBIOS Type 1 structure "Wake-up Type"
+// data field
+//
+// Input:IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: Updated SMBIOS Type 1 "Wake-up Type"
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateSmbiosWakeupType(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable;
+ EFI_GUID EfiPeiReadOnlyVariablePpiGuid = \
+ {0x2ab86ef5, 0xecb5, 0x4134, {0xb5, 0x56, 0x38, 0x54, 0xca, 0x1f, 0xe1, 0xb4}};
+ EFI_GUID EfiSmbiosNvramGuid = \
+ {0x4b3082a3, 0x80c6, 0x4d7e, {0x9c, 0xd0, 0x58, 0x39, 0x17, 0x26, 0x5d, 0xf1}};
+ UINTN DataSize = 4;
+ UINT32 WakeupTypePtr;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &EfiPeiReadOnlyVariablePpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ if (Status == EFI_SUCCESS){
+ Status = ReadOnlyVariable->GetVariable(
+ ReadOnlyVariable,
+ L"WakeUpType",
+ &EfiSmbiosNvramGuid,
+ NULL,
+ &DataSize,
+ &WakeupTypePtr);
+ if (Status == EFI_SUCCESS) {
+ if (WakeupTypePtr > 0xf0000) {
+ *(UINT8*)WakeupTypePtr = getWakeupTypeForSmbios();
+ }
+ else {
+ OemRuntimeShadowRamWrite(TRUE);
+ *(UINT8*)WakeupTypePtr = getWakeupTypeForSmbios();
+ OemRuntimeShadowRamWrite(FALSE);
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmbiosAfterInitMemory
+//
+// Description:
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+// IN VOID *NullPpi
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmbiosAfterInitMemory(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *NullPpi
+)
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ // Determine boot mode
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ if (BootMode == BOOT_ON_S3_RESUME) {
+ UpdateSmbiosWakeupType(PeiServices);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+SmbiosPeiEntryPoint(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+
+ // Set the Smbios Notify PPI
+ Status = (*PeiServices)->NotifyPpi(PeiServices, SmbiosPeiNotify);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif
new file mode 100644
index 0000000..d13b0a1
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "SmbiosPeim"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMBIOS\SmbiosPeim"
+ RefName = "SmbiosPeim"
+[files]
+"SmbiosPeim.sdl"
+"SmbiosPeim.mak"
+"SmbiosPeim.dxs"
+"SmbiosPei.c"
+<endComponent>
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs
new file mode 100644
index 0000000..c769128
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.dxs
@@ -0,0 +1,66 @@
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
+
+//**********************************************************************//
+// $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.dxs 1 5/27/14 1:44p Davidd $
+//
+// $Revision: 1 $
+//
+// $Date: 5/27/14 1:44p $
+//**********************************************************************//
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.dxs $
+//
+// 1 5/27/14 1:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Files] SmbiosPeim.cif
+// SmbiosPeim.sdl
+// SmbiosPeim.mak
+// SmbiosPeim.dxs
+// SmbiosPei.c
+//
+// 1 4/29/14 4:44p Davidd
+// [TAG] EIP103526
+// [Category] Improvement
+// [Description] We should update Wake-up Type in SMBIOS type 1
+// dynamically
+// [Files] Core\EM\SMBios\SmbiosPeim\SmbiosPeim.cif
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.sdl
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.mak
+// Core\EM\SMBios\SmbiosPeim\SmbiosPeim.dxs
+// Core\EM\SMBios\SmbiosPeim\SmbiosPei.c
+//
+//**********************************************************************//
+
+#include "ppi\ReadOnlyVariable2.h"
+
+DEPENDENCY_START
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID
+DEPENDENCY_END
+
+//**********************************************************************//
+//**********************************************************************//
+//** **//
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **//
+//** **//
+//** All Rights Reserved. **//
+//** **//
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **//
+//** **//
+//** Phone: (770)-246-8600 **//
+//** **//
+//**********************************************************************//
+//**********************************************************************//
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak
new file mode 100644
index 0000000..e73289c
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.mak
@@ -0,0 +1,89 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.mak 1 5/27/14 1:44p Davidd $
+#
+# $Revision: 1 $
+#
+# $Date: 5/27/14 1:44p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMBIOS/SmbiosPeim/SmbiosPeim.mak $
+#
+# 1 5/27/14 1:44p Davidd
+# [TAG] EIP103526
+# [Category] Improvement
+# [Files] SmbiosPeim.cif
+# SmbiosPeim.sdl
+# SmbiosPeim.mak
+# SmbiosPeim.dxs
+# SmbiosPei.c
+#
+# 1 4/29/14 4:44p Davidd
+# [TAG] EIP103526
+# [Category] Improvement
+# [Description] We should update Wake-up Type in SMBIOS type 1
+# dynamically
+# [Files] Core\EM\SMBios\SmbiosPeim\SmbiosPeim.cif
+# Core\EM\SMBios\SmbiosPeim\SmbiosPeim.sdl
+# Core\EM\SMBios\SmbiosPeim\SmbiosPeim.mak
+# Core\EM\SMBios\SmbiosPeim\SmbiosPeim.dxs
+# Core\EM\SMBios\SmbiosPeim\SmbiosPei.c
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <SmbiosPeim>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : SmbiosPeim
+
+SmbiosPeim : $(BUILD_DIR)\SmbiosPeim.mak SmbiosPeimBin
+
+$(BUILD_DIR)\SmbiosPeim.mak : $(SMBIOS_PEIM_DIR)\$(@B).cif $(SMBIOS_PEIM_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMBIOS_PEIM_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+SMBIOS_PEIM_OBJECTS = $$(BUILD_DIR)\$(SMBIOS_PEIM_DIR)\SmbiosPei.obj
+
+SmbiosPeimBin : $(AMIPEILIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmbiosPeim.mak all\
+ NAME=SmbiosPeim\
+ OBJECTS="$(SMBIOS_PEIM_OBJECTS)" \
+ GUID=AC836A8E-B69A-470b-BECF-912A01B794F4\
+ ENTRY_POINT=SmbiosPeiEntryPoint\
+ DEPEX1=$(SMBIOS_PEIM_DIR)\SmbiosPeim.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM \
+ COMPRESS=0
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl
new file mode 100644
index 0000000..d8ba7cc
--- /dev/null
+++ b/Core/EM/SMBIOS/SmbiosPeim/SmbiosPeim.sdl
@@ -0,0 +1,32 @@
+TOKEN
+ Name = "SmbiosPeim_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmbiosPeim support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "SB_WAKEUP_TYPE_FN" "=" "1"
+End
+
+PATH
+ Name = "SMBIOS_PEIM_DIR"
+End
+
+MODULE
+ Help = "Includes SmbiosPeim.mak to Project"
+ File = "SmbiosPeim.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosPeim.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmbiosPeim.ffs"
+ Parent = "FT_FV_BB"
+ InvokeOrder = AfterParent
+ Token = "FtRecovery_SUPPORT" "=" "1"
+End \ No newline at end of file
diff --git a/Core/EM/SMIFlash/SMIFlash.c b/Core/EM/SMIFlash/SMIFlash.c
new file mode 100644
index 0000000..6566102
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlash.c
@@ -0,0 +1,990 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.c 52 3/23/16 3:58a Calvinchen $
+//
+// $Revision: 52 $
+//
+// $Date: 3/23/16 3:58a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.c $
+//
+// 52 3/23/16 3:58a Calvinchen
+// [TAG] EIP262060
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Buffer Overflow Vulnerability
+// [RootCause] SmiFlash interface security vulnerability if the buffer
+// address is starting before/less SMM Base and the buffer length is
+// larger than SMM size.
+// [Solution] Adapted the CheckAddressRange function as the
+// "AmiValidateMemoryBuffer" function of the AptioV.
+// [Files] SMIFlash.c
+//
+// 51 1/08/16 3:59a Calvinchen
+// [TAG] EIP249791
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] SMM Buffer Validation - additional vulnerability
+// [RootCause] BufAddr is an embedded input pointer which has not been
+// validated to be outside of SMRAM and is being used as a destination
+// buffer for read/write operation from flash.
+//
+// [Solution] Validate BufAddr to must be outside of SMRAM.
+// [Files] SMIFlash.c
+// SMIFlash.chm
+// SMIFlash.cif
+//
+// 50 6/21/13 4:32a Tristinchou
+// [TAG] EIP125801
+// [Category] Improvement
+// [Description] SMI Flash handler could be used to set value in SMRAM.
+// Check the adrress before use the function.
+// [Files] SMIFlash.c
+//
+// 49 11/02/12 7:13a Calvinchen
+// [TAG] EIP64328
+// [Category] Improvement
+// [Description] Improvement:
+// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI
+// 2.3.1 specifications.
+// BugFix:
+// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed
+// after restored.
+// 2. (EIP98199) The #### in Boot#### should be upper case.
+// [Files] SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlashDxe.dxs
+// SMIFlash.cif
+//
+// 48 3/06/12 2:40a Klzhan
+// NVRAM backup address will not updated.
+//
+// 47 1/16/12 2:29a Calvinchen
+// [TAG] EIPNone
+// [Category] Improvement
+// [Description] Updated for Secure Update.
+//
+// 46 5/17/11 3:16a Klzhan
+// Report BIOS project tag length to AFU.
+//
+// 45 3/23/11 4:44a Calvinchen
+// [TAG] EIP53067
+// [Category] Improvement
+// [Description] Modified for OEM Secure BIOS Update Requirements.
+// [Files] SMIFlash.sdl
+// SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlash.cif
+//
+// 44 1/21/11 4:48a Klzhan
+// Improvement : Check CPU number in SMIHandler
+//
+// 43 12/14/10 4:16a Klzhan
+// Move Locate USB Protocol to SMIFlashLinks.c.
+//
+// 42 12/14/10 1:13a Klzhan
+// Improvement : Move ELinks to SMIFlashLinks.c.
+//
+// 41 10/20/10 2:21a Klzhan
+// Remove ASFU related codes, ASFU will implement with OFBD module.
+//
+// 40 10/19/10 6:58a Klzhan
+// Improvement : Support Secure Flash Update.
+// EIP : 46069
+//
+// 39 8/10/10 2:40a Klzhan
+// Improvement : Replace Memory Read by SPIRead when checking flash data.
+//
+// 38 6/15/10 3:12a Klzhan
+// Improvement: Add Elink to modify GetFlashInfo.
+//
+// 37 4/14/10 5:43a Klzhan
+// BugFix : Fix compile error when FAULT_TOLERANT_NVRAM_UPDATE is off.
+//
+// 36 4/13/10 4:26a Klzhan
+// Improvement : Report NVRam backup as NVRam block.
+//
+// 35 4/12/10 7:45a Klzhan
+// Improvement : When FAULT_TOLERANT_NVRAM_UPDATE is on and System working
+// at NVRam backup address, system works fine on next boot.
+//
+// 34 4/12/10 3:37a Klzhan
+// Improvement : Add E-Link to Enable/Disable USB KBD.
+// BugFix : Correct USB driver verion control.
+//
+// 33 4/08/10 2:22a Rameshr
+// Usb changes added based on AMIUSB release version.
+//
+// 32 4/07/10 1:53a Rameshr
+// USB K/B and USB M/S should be stopped during flashing BIOS.
+// EIP 37130
+//
+// 31 3/26/10 5:25a Rameshr
+// After flashupdate, Silent boot setup option is not restored to default
+// value
+// EIP 36617
+//
+// 30 3/02/10 2:59a Klzhan
+// Improvement : If Setup PassWord Length is changed, Password will not be
+// restore when update NVRam region.
+//
+// 29 3/02/10 12:43a Klzhan
+// Improvement : Disable Power Button when flash ROM image.(EIP35662)
+//
+// 28 2/26/10 2:31a Klzhan
+// 1. Improvement : Restore "Windows Boot Manager" for EFI OS(EIP 32339)
+//
+// 27 12/21/09 4:39a Klzhan
+// Improvement : Updated for Aptio Source Enhancement.
+//
+// 26 11/26/09 6:03a Klzhan
+// Improvement : Add Flash Chip info.EIP 30081
+//
+// 25 8/25/09 8:22a Klzhan
+// Improvement: Support Flash ME FW.
+//
+// 24 5/22/09 8:19p Felixp
+// SmiFlash module is updated to replace Flash library calls with the
+// calls to new Core 4.6.3.6 Flash Protocol .
+//
+// 23 4/03/09 11:28a Fredericko
+// Reverting changes for EIP 18818. causing Afu flash error.
+//
+// 22 3/05/09 1:17p Felixp
+// - Bug fix. EIP 17632.
+// Flash Blocks that do not belong to FV_BB, FV_MAIN, and FV_NVRAM
+// have been reported as boot block.
+// The SmiFlash.c is updated to report these blocks as non critical
+// blocks.
+// The SmiFlash.h header is updated to define non critical block type
+// (NC_BLOCK ).
+// - Headers updated.
+//
+// 21 2/02/09 6:46p Fredericko
+// Changes for EIP 18819: Using FlashRead to read from flash part. Changed
+// SMIFLASH_RRE_UPDATE_LIST to SMIFLASH_PRE_UPDATE_LIST
+//
+// 19 1/29/09 7:33p Fredericko
+// Added code to account for functions (ELinked) that need to run before
+// we program flash and after we program flash. EIP 18819
+//
+// 18 1/13/09 4:36p Fredericko
+// EIP18723: Increase the size of Index (to UINT16) variable for case
+// where number of blocks is more than 255.
+//
+// 17 3/07/08 11:41a Rameshraju
+// Readflash failed for 1.5Mb flash size
+//
+// 16 8/21/07 3:39p Pats
+// Removed calculations for sizeof(AMITSESETUP)
+//
+// 15 8/17/07 4:37p Pats
+// Fixed sizeof problem.
+//
+// 14 8/16/07 6:12p Pats
+// Sizeof was returning wrong size for AMITSESETUP.
+//
+// 13 8/16/07 10:54a Pats
+// Fixed problem with setvariable call in password preservation path.
+//
+// 12 8/15/07 7:06p Pats
+// Modified to support preservation of passwords through flashing.
+//
+// 11 1/24/07 1:42p Felixp
+// Erase/Programming code changed to use low level flash routines because
+// AFU sends write requests, for a chunks of data smaller then the flash
+// block.
+//
+// 10 12/29/06 3:04p Felixp
+// 1. Updated to use new Flash Interface.
+// 2. Embedded Controller support added.
+//
+// 9 3/24/06 7:57p Felixp
+//
+// 7 11/11/05 11:46a Markw
+// Renamed IntallSmmHandler to InitSmmHandler because of build errors
+// because another driver used InstallSmmHandler.
+//
+// 6 11/09/05 3:09p Yakovlevs
+// InSmmFunction() "not all controls return a value" compiler warning
+// fixed
+//
+// 5 11/08/05 6:05p Markw
+// Using libary function InstallSmiHandler.
+//
+// 4 7/12/05 11:19a Markw
+// Add code to detect which CPU is executing.
+//
+// 3 5/02/05 6:42p Markw
+// Added Eswar's updates.
+//
+// 2 5/02/05 6:25p Markw
+//
+// 1 4/05/05 3:47p Sivagarn
+// Initial Checkin
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SMIFlash.c
+//
+// Description: SMIFlash Driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\SmiFlash.h>
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+#include <Protocol\SmmCpu.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#define RETURN(status) {return status;}
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#define RETURN(status) {return ;}
+#endif
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\FlashProtocol.h>
+#include <Flash.h>
+#include <AmiSmm.h>
+#include <Setup.h>
+#include <AmiHobs.h>
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+#include <Protocol\AmiUsbController.h>
+#endif
+#endif
+
+//----------------------------------------------------------------------
+// component MACROs
+#define FLASH_EMPTY_BYTE (UINT8)(-FLASH_ERASE_POLARITY)
+#define STR(a) CONVERT_TO_STRING(a)
+//----------------------------------------------------------------------
+// Module defined global variables
+
+//----------------------------------------------------------------------
+// Module specific global variable
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID;
+EFI_GUID gEfiSmmBase2ProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
+EFI_GUID gEfiSmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
+EFI_SMM_CPU_PROTOCOL *gSmmCpu;
+#else
+EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+#endif
+EFI_GUID gEfiSmiFlashProtocolGuid = EFI_SMI_FLASH_GUID;
+
+
+// oem flash write enable/disable list creation code must be in this order
+typedef VOID (SMIFLASH_UPDATE) (VOID);
+extern SMIFLASH_UPDATE SMIFLASH_PRE_UPDATE_LIST EndOfSMIFlashList;
+extern SMIFLASH_UPDATE SMIFLASH_END_UPDATE_LIST EndOfSMIFlashList;
+SMIFLASH_UPDATE* SMIFlashPreUpdate[] = {SMIFLASH_PRE_UPDATE_LIST NULL};
+SMIFLASH_UPDATE* SMIFlashEndUpdate[] = {SMIFLASH_END_UPDATE_LIST NULL};
+typedef VOID (SMIFLASH_PRE_HANDLER) (UINT8 Date, UINT64 pInfoBlock);
+typedef VOID (SMIFLASH_END_HANDLER) (UINT8 Date, UINT64 pInfoBlock);
+extern SMIFLASH_PRE_HANDLER SMIFLASH_PRE_HANDLER_LIST EndOfPreHandlerList;
+extern SMIFLASH_END_HANDLER SMIFLASH_END_HANDLER_LIST EndOfEndHandlerList;
+SMIFLASH_PRE_HANDLER* SMIFlashPreHandler[] = {SMIFLASH_PRE_HANDLER_LIST NULL};
+SMIFLASH_END_HANDLER* SMIFlashEndHandler[] = {SMIFLASH_END_HANDLER_LIST NULL};
+
+typedef VOID (SMIFLASH_FUNCTION) (VOID);
+extern SMIFLASH_FUNCTION SMIFLASH_IN_SMM_LIST EndOfInSmmList;
+SMIFLASH_FUNCTION* SMIFlashInSmm[] = {SMIFLASH_IN_SMM_LIST NULL};
+extern SMIFLASH_FUNCTION SMIFLASH_NOT_IN_SMM_LIST EndOfNotInSmmList;
+SMIFLASH_FUNCTION* SMIFlashNotInSmm[] = {SMIFLASH_NOT_IN_SMM_LIST NULL};
+
+FLASH_PROTOCOL *Flash = NULL;
+SMM_HOB gSmmHob;
+#ifdef FLASH_PART_STRING_LENGTH
+VOID GetFlashPartInfomation(UINT8 *pBlockAddress, UINT8 *Buffer);
+#endif
+//----------------------------------------------------------------------
+// externally defined variables
+
+//----------------------------------------------------------------------
+// Function definitions
+EFI_STATUS
+GetFlashInfo(
+ IN OUT INFO_BLOCK *pInfoBlock
+);
+EFI_STATUS EnableFlashWrite(
+ IN OUT FUNC_BLOCK *pFuncBlock
+);
+EFI_STATUS DisableFlashWrite(
+ IN OUT FUNC_BLOCK *pFuncBlock
+);
+EFI_STATUS ReadFlash(
+ IN OUT FUNC_BLOCK *pFuncBlock
+);
+EFI_STATUS WriteFlash(
+ IN OUT FUNC_BLOCK *pFuncBlock
+);
+EFI_STATUS EraseFlash(
+ IN OUT FUNC_BLOCK *pFuncBlock
+);
+EFI_SMI_FLASH_PROTOCOL SmiFlash = {
+ GetFlashInfo,
+ EnableFlashWrite,
+ DisableFlashWrite,
+ ReadFlash,
+ WriteFlash,
+ EraseFlash,
+ FLASH_SIZE
+};
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CheckAddressRange
+//
+// Description: Check address range to avoid TSEG area.
+//
+// Input:
+// Address - starting address
+// Range - length of the area
+//
+// Output:
+// EFI_SUCCESS - Access granted
+// EFI_ACCESS_DENIED - Access denied!
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CheckAddressRange( IN UINT8 *Address, IN UINTN Range )
+{
+ // Check the size and range
+ if (((EFI_PHYSICAL_ADDRESS)Address + Range) < (EFI_PHYSICAL_ADDRESS)Address)
+ return EFI_INVALID_PARAMETER; // overflow
+
+ if (((EFI_PHYSICAL_ADDRESS)Address >= gSmmHob.Tseg) && \
+ ((EFI_PHYSICAL_ADDRESS)Address < (gSmmHob.Tseg + gSmmHob.TsegLength)))
+ return EFI_ACCESS_DENIED; // Buffer starts in SMRAM
+
+ if (((EFI_PHYSICAL_ADDRESS)Address < gSmmHob.Tseg) && \
+ (((EFI_PHYSICAL_ADDRESS)Address + Range) > gSmmHob.Tseg))
+ return EFI_ACCESS_DENIED; // Buffer overlaps with SMRAM
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetFlashInfo
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetFlashInfo(
+ IN OUT INFO_BLOCK *pInfoBlock
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 BuffLen = 0;
+ UINT64 BlkOff;
+ BLOCK_DESC *pBlock;
+ UINT16 Index;
+ UINT32 Add;
+ UINT32 Flash4GBMapStart;
+ UINT16 NumBlocks, MainStart, MainEnd,
+ NVStart, NVEnd, BBStart, BBEnd;
+ UINT16 LastNcb = 0xFFFF;
+ UINT8 NcbType = NC_BLOCK;
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT && SMI_FLASH_INTERFACE_VERSION > 10
+ UINT16 ECStart, ECEnd;
+#endif
+#ifdef FAULT_TOLERANT_NVRAM_UPDATE
+#if FAULT_TOLERANT_NVRAM_UPDATE
+ UINT16 NVBackupStart, NVBackupEnd;
+#endif
+#endif
+
+ BuffLen = pInfoBlock->Length; // Total buffer length
+ pInfoBlock->Version = SMI_FLASH_INTERFACE_VERSION;
+ pInfoBlock->Implemented = 0;
+#if SMI_FLASH_INTERFACE_VERSION > 10
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ pInfoBlock->ECVersionOffset = EC_VERSION_OFFSET;
+ pInfoBlock->ECVersionMask = EC_VERSION_MASK;
+#else
+ pInfoBlock->ECVersionOffset = 0;
+ pInfoBlock->ECVersionMask = 0;
+#endif
+#endif
+
+ // Reduce number of bytes used for header information
+ BuffLen -= EFI_FIELD_OFFSET( INFO_BLOCK, Blocks);
+
+ // Get the total block count
+ pInfoBlock->TotalBlocks = NumBlocks = NUMBER_OF_BLOCKS;
+
+ // Calculate the flash mapping start address. This is calculated
+ // as follows:
+ // 1. Find the total size of the flash (FLASH_BLOCK_SIZE *
+ // pInfoBlock->TotalBlocks)
+ // 2. Subtract the total flash size from 4GB
+ Flash4GBMapStart = 0xFFFFFFFF - (FLASH_BLOCK_SIZE * NumBlocks);
+ Flash4GBMapStart ++;
+
+ // Fill the flash region start & end values
+ BBStart = (FV_BB_BASE - Flash4GBMapStart) / FLASH_BLOCK_SIZE;
+ BBEnd = BBStart + FV_BB_BLOCKS - 1;
+
+ MainStart = (FV_MAIN_BASE - Flash4GBMapStart) / FLASH_BLOCK_SIZE;
+ MainEnd = MainStart + FV_MAIN_BLOCKS - 1;
+
+ NVStart = (NVRAM_ADDRESS - Flash4GBMapStart) / FLASH_BLOCK_SIZE;
+ NVEnd = NVStart + NVRAM_BLOCKS - 1;
+
+#ifdef FAULT_TOLERANT_NVRAM_UPDATE
+#if FAULT_TOLERANT_NVRAM_UPDATE
+ NVBackupStart = (NVRAM_BACKUP_ADDRESS - Flash4GBMapStart) / FLASH_BLOCK_SIZE;
+ NVBackupEnd = NVBackupStart + NVRAM_BLOCKS - 1;
+#endif
+#endif
+
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT && SMI_FLASH_INTERFACE_VERSION > 10
+ ECStart = (EC_BASE - Flash4GBMapStart) / FLASH_BLOCK_SIZE;
+ ECEnd = ECStart + EC_BLOCKS - 1;
+#endif
+
+ BlkOff = (UINT64)&pInfoBlock->Blocks;
+
+ // Chek whether we have enough buffer space
+ if (BuffLen < (sizeof (BLOCK_DESC) * NumBlocks)) {
+ pInfoBlock->Implemented = 1;
+ return Status;
+ }
+
+ for (Index = 0; Index < NumBlocks; Index++) {
+
+ pBlock = (BLOCK_DESC *)BlkOff;
+ Add = Index * FLASH_BLOCK_SIZE;
+
+ pBlock->StartAddress = Add;
+ Add |= Flash4GBMapStart;
+ pBlock->BlockSize = FLASH_BLOCK_SIZE;
+
+ if ((Index >= MainStart) && (Index <= MainEnd))
+ pBlock->Type = MAIN_BLOCK;
+ else if ((Index >= NVStart) && (Index <= NVEnd))
+ pBlock->Type = NV_BLOCK;
+ else if ((Index >= BBStart) && (Index <= BBEnd))
+ pBlock->Type = BOOT_BLOCK;
+#ifdef FAULT_TOLERANT_NVRAM_UPDATE
+#if FAULT_TOLERANT_NVRAM_UPDATE
+ else if ((Index >= NVBackupStart) && (Index <= NVBackupEnd))
+ {
+ pBlock->Type = NVB_BLOCK;
+ }
+#endif
+#endif
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT && SMI_FLASH_INTERFACE_VERSION > 10
+ else if ((Index >= ECStart) && (Index <= ECEnd))
+ pBlock->Type = EC_BLOCK;
+#endif
+ else {
+ if (LastNcb+1 != Index) NcbType++;
+
+ pBlock->Type = NcbType;
+ LastNcb=Index;
+ }
+ BlkOff += sizeof (BLOCK_DESC);
+ }
+
+ // Info AFU Project Tag length.
+ if (((UINT64)pInfoBlock + pInfoBlock->Length) > (BlkOff + 5))
+ {
+ CHAR8* ProjectTag = STR(PROJECT_TAG);
+ UINTN TagLength;
+ UINT8 ProjectTagSign[4] = {'$','B','P','T'};
+
+ TagLength = Strlen(ProjectTag);
+
+ MemCpy ( (UINT8*)BlkOff, ProjectTagSign, 4 );
+ BlkOff += sizeof (UINT32);
+ *(UINT8*)BlkOff = (UINT8)TagLength;
+ BlkOff += 1;
+ }
+
+#ifdef FLASH_PART_STRING_LENGTH
+ if (((UINT64)pInfoBlock + pInfoBlock->Length) > \
+ (BlkOff + FLASH_PART_STRING_LENGTH + 8))
+ GetFlashPartInfomation ( (UINT8*)Flash4GBMapStart, (UINT8*)BlkOff );
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: EnableFlashWrite
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EnableFlashWrite(
+ IN OUT FUNC_BLOCK *pFuncBlock
+)
+{
+ return Flash->DeviceWriteEnable();
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: DisableFlashWrite
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DisableFlashWrite(
+ IN OUT FUNC_BLOCK *pFuncBlock
+)
+{
+ return Flash->DeviceWriteDisable();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: EraseFlash
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EraseFlash(
+ IN OUT FUNC_BLOCK *pFuncBlock
+)
+{
+ EFI_STATUS Status;
+ UINT8 *BlockAddress;
+ BlockAddress = (UINT8*)(UINTN)(pFuncBlock->BlockAddr + \
+ (0xFFFFFFFF - SmiFlash.FlashCapacity + 1));
+ (UINT32)BlockAddress &= (0xFFFFFFFF - FLASH_BLOCK_SIZE + 1);
+ if (EFI_ERROR(CheckAddressRange (BlockAddress, \
+ FlashBlockSize))) return EFI_ACCESS_DENIED;
+ Status = Flash->Erase(BlockAddress, FlashBlockSize);
+ pFuncBlock->ErrorCode = EFI_ERROR(Status) != 0;
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: ReadFlash
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadFlash(
+ IN OUT FUNC_BLOCK *pFuncBlock
+)
+{
+ UINT32 Flash4GBMapStart;
+ EFI_STATUS Status;
+
+ Flash4GBMapStart = 0xFFFFFFFF - (FLASH_BLOCK_SIZE * NUMBER_OF_BLOCKS);
+ Flash4GBMapStart += (pFuncBlock->BlockAddr + 1);
+ if (EFI_ERROR(CheckAddressRange ((UINT8*)Flash4GBMapStart, \
+ pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED;
+ if (EFI_ERROR(CheckAddressRange ((UINT8*)pFuncBlock->BufAddr, \
+ pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED;
+ Status = Flash->Read((UINT8*)Flash4GBMapStart, \
+ pFuncBlock->BlockSize, (UINT8*)pFuncBlock->BufAddr);
+ pFuncBlock->ErrorCode = EFI_ERROR(Status) != 0;
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: WriteFlash
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteFlash(
+ IN OUT FUNC_BLOCK *pFuncBlock
+)
+{
+ EFI_STATUS Status;
+ UINT8 *FlashAddress;
+
+ FlashAddress = (UINT8*)(UINTN)(pFuncBlock->BlockAddr + \
+ (0xFFFFFFFF - SmiFlash.FlashCapacity + 1));
+ if (EFI_ERROR(CheckAddressRange (FlashAddress, \
+ pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED;
+ if (EFI_ERROR(CheckAddressRange ((UINT8*)pFuncBlock->BufAddr, \
+ pFuncBlock->BlockSize))) return EFI_ACCESS_DENIED;
+ Status = Flash->Write(FlashAddress, \
+ pFuncBlock->BlockSize, (UINT8*)pFuncBlock->BufAddr);
+ pFuncBlock->ErrorCode = EFI_ERROR(Status) != 0;
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SMIFlashSMIHandler
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+EFI_STATUS
+SMIFlashSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+#else
+VOID SMIFlashSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+#endif
+{
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState = NULL;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 Data;
+ UINT64 pCommBuff;
+ UINT32 HighBufferAddress = 0;
+ UINT32 LowBufferAddress = 0;
+ UINTN Cpu = (UINTN)-1, i = 0;
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ if (CommBuffer != NULL && CommBufferSize != NULL) {
+ Cpu = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->SwSmiCpuIndex;
+ Data = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->CommandPort;
+ }
+
+ //
+ // Found Invalid CPU number, return
+ //
+ if(Cpu == (UINTN)-1) RETURN(Status);
+
+ Status = gSmmCpu->ReadSaveState ( gSmmCpu, \
+ 4, \
+ EFI_SMM_SAVE_STATE_REGISTER_RBX, \
+ Cpu, \
+ &LowBufferAddress );
+ Status = gSmmCpu->ReadSaveState ( gSmmCpu, \
+ 4, \
+ EFI_SMM_SAVE_STATE_REGISTER_RCX, \
+ Cpu, \
+ &HighBufferAddress );
+#else // PI_SPECIFICATION_VERSION < 0x1000A
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,
+ &gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+ //
+ // Found Invalid CPU number, return
+ //
+ if(Cpu == (UINTN) -1) RETURN(Status);
+
+ Data = (UINT8)DispatchContext->SwSmiInputValue;
+
+ pCpuSaveState = pSmst->CpuSaveState;
+ HighBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.ECX;
+ LowBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.EBX;
+
+#endif
+
+ pCommBuff = HighBufferAddress;
+ pCommBuff = Shl64(pCommBuff, 32);
+ pCommBuff += LowBufferAddress;
+
+ if(Data == SMIFLASH_GET_FLASH_INFO)
+ Status = CheckAddressRange( (UINT8*)pCommBuff, sizeof(INFO_BLOCK) );
+ else
+ Status = CheckAddressRange( (UINT8*)pCommBuff, sizeof(FUNC_BLOCK) );
+ if(EFI_ERROR(Status)) RETURN(Status);
+
+ if (Data != SMIFLASH_GET_FLASH_INFO)
+ ((FUNC_BLOCK*)pCommBuff)->ErrorCode = 0;
+ for (i = 0; SMIFlashPreHandler[i] != NULL; i++)
+ SMIFlashPreHandler[i](Data, pCommBuff);
+ if ((Data == SMIFLASH_GET_FLASH_INFO) || \
+ (((FUNC_BLOCK*)pCommBuff)->ErrorCode == 0)) {
+ switch (Data) {
+ case 0x20: // Enable Flash
+ for (i = 0; SMIFlashPreUpdate[i] != NULL; i++)
+ SMIFlashPreUpdate[i]();
+ EnableFlashWrite((FUNC_BLOCK *)pCommBuff);
+ break;
+
+ case 0x24: // Disable Flash
+ for (i = 0; SMIFlashEndUpdate[i] != NULL; i++)
+ SMIFlashEndUpdate[i]();
+
+ DisableFlashWrite((FUNC_BLOCK *)pCommBuff);
+ break;
+
+ case 0x22: // Erase Flash
+
+ EraseFlash((FUNC_BLOCK *)pCommBuff);
+
+ break;
+
+ case 0x21: // Read Flash
+ ReadFlash((FUNC_BLOCK *)pCommBuff);
+ break;
+
+ case 0x23: // Write Flash
+
+ WriteFlash((FUNC_BLOCK *)pCommBuff);
+ break;
+
+ case 0x25: // Get Flash Info
+ GetFlashInfo((INFO_BLOCK *)pCommBuff);
+ }
+
+ }
+ for (i = 0; SMIFlashEndHandler[i] != NULL; i++)
+ SMIFlashEndHandler[i](Data, pCommBuff);
+ RETURN(Status);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle;
+ UINTN Index;
+ EFI_HANDLE DummyHandle = NULL;
+ EFI_STATUS Status;
+ SMM_HOB *SmmHob;
+ EFI_GUID SmmHobGuid = SMM_HOB_GUID;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+#else
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+#endif
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ Status = InitAmiSmmLib( ImageHandle, SystemTable );
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pSmmBase->GetSmstLocation (gSmmBase2, &pSmst);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pSmst->SmmLocateProtocol( \
+ &gEfiSmmSwDispatch2ProtocolGuid, NULL, &pSwDispatch);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ Status = pSmst->SmmLocateProtocol(&gEfiSmmCpuProtocolGuid, NULL, &gSmmCpu);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+#else
+ VERIFY_EFI_ERROR(pBS->LocateProtocol(
+ &gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch));
+#endif
+ VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashSmmProtocolGuid,
+ NULL, &Flash));
+ TRACE((TRACE_ALWAYS,"SmiFlash: Flash Protocol %X\n",Flash));
+
+ SmmHob = (SMM_HOB*)GetEfiConfigurationTable(pST, &HobListGuid);
+ if (SmmHob == NULL) return EFI_NOT_FOUND;
+ Status = FindNextHobByGuid(&SmmHobGuid,(VOID**)&SmmHob);
+ if (EFI_ERROR(Status)) return Status;
+ gSmmHob = *SmmHob;
+
+ for (Index = 0x20; Index < 0x26; Index++) {
+ SwContext.SwSmiInputValue = Index;
+ Status = pSwDispatch->Register(pSwDispatch, SMIFlashSMIHandler,
+ &SwContext, &Handle);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ //TODO: If any errors, unregister any registered SwSMI by this driver.
+ //If error, and driver is unloaded, then a serious problem would exist.
+ }
+
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ Status = pSmst->SmmInstallProtocolInterface(
+ &DummyHandle,
+ &gEfiSmiFlashProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &SmiFlash
+ );
+#endif
+ // If PI 1.2, install this protocol for backward compatible.
+ DummyHandle = NULL;
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &DummyHandle,
+ &gEfiSmiFlashProtocolGuid,&SmiFlash,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ for (Index = 0; SMIFlashInSmm[Index] != NULL; Index++) {
+ SMIFlashInSmm[Index]();
+ }
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: NonSmmElinkFunctions
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+NonSmmElinkFunctions(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ UINT8 i;
+
+ for (i = 0; SMIFlashNotInSmm[i] != NULL; i++)
+ SMIFlashNotInSmm[i]();
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SMIFlashDriverEntryPoint
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SMIFlashDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler (ImageHandle, \
+ SystemTable, InSmmFunction, NonSmmElinkFunctions);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SMIFlash/SMIFlash.chm b/Core/EM/SMIFlash/SMIFlash.chm
new file mode 100644
index 0000000..7235dae
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlash.chm
Binary files differ
diff --git a/Core/EM/SMIFlash/SMIFlash.cif b/Core/EM/SMIFlash/SMIFlash.cif
new file mode 100644
index 0000000..ebed2dc
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlash.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "SMIFlash"
+ category = eModule
+ LocalRoot = "CORE\EM\SMIFlash\"
+ RefName = "SMIFlash"
+[files]
+"SMIFlash.sdl"
+"SMIFlash.mak"
+"SMIFlash.dxs"
+"SMIFlash.c"
+"SMIFlash.chm"
+"SMIFlashLinks.c"
+"SMIFlashDxe.dxs"
+[parts]
+"SMIFlashProtocols"
+<endComponent>
diff --git a/Core/EM/SMIFlash/SMIFlash.dxs b/Core/EM/SMIFlash/SMIFlash.dxs
new file mode 100644
index 0000000..0fbc5ec
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlash.dxs
@@ -0,0 +1,103 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.dxs 7 11/02/12 7:13a Calvinchen $
+//
+// $Revision: 7 $
+//
+// $Date: 11/02/12 7:13a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.dxs $
+//
+// 7 11/02/12 7:13a Calvinchen
+// [TAG] EIP64328
+// [Category] Improvement
+// [Description] Improvement:
+// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI
+// 2.3.1 specifications.
+// BugFix:
+// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed
+// after restored.
+// 2. (EIP98199) The #### in Boot#### should be upper case.
+// [Files] SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlashDxe.dxs
+// SMIFlash.cif
+//
+// 6 12/14/10 3:51a Klzhan
+// Remove dependency of USB protocol.
+// USB might be remove in some Mobile when FAST_BOOT is on.
+//
+// 5 4/07/10 1:56a Rameshr
+// USB K/B and USB M/S should be stopped during flashing BIOS.
+// EIP 37130
+//
+// 4 12/21/09 4:41a Klzhan
+//
+// 3 5/22/09 8:19p Felixp
+// SmiFlash module is updated to replace Flash library calls with the
+// calls to new Core 4.6.3.6 Flash Protocol .
+//
+// 2 5/11/07 1:47p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SMIFlash_dxs
+//
+// Description: This file is the dependency file for the SMIFlash driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmSwDispatch2.h>
+#else
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#endif
+#include <Protocol/FlashProtocol.h>
+
+DEPENDENCY_START
+#if PI_SPECIFICATION_VERSION >= 0x1000A
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID AND
+#else
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+#endif
+ FLASH_SMM_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMIFlash/SMIFlash.mak b/Core/EM/SMIFlash/SMIFlash.mak
new file mode 100644
index 0000000..cb840d3
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlash.mak
@@ -0,0 +1,183 @@
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2005, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.mak 13 11/02/12 7:13a Calvinchen $
+#
+# $Revision: 13 $
+#
+# $Date: 11/02/12 7:13a $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlash.mak $
+#
+# 13 11/02/12 7:13a Calvinchen
+# [TAG] EIP64328
+# [Category] Improvement
+# [Description] Improvement:
+# 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI
+# 2.3.1 specifications.
+# BugFix:
+# 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed
+# after restored.
+# 2. (EIP98199) The #### in Boot#### should be upper case.
+# [Files] SMIFlash.mak
+# SMIFlash.dxs
+# SMIFlash.c
+# SMIFlash.chm
+# SMIFlashLinks.c
+# SMIFlashDxe.dxs
+# SMIFlash.cif
+#
+# 12 5/29/12 5:45a Klzhan
+# [TAG] EIP86878
+# [Category] Improvement
+# [Description] Restore SMBIOS data when recovery.
+# [Files] SMIFlash.sdl
+# SMIFlash.mak
+# SMIFlash.dxs
+# SMIFlash.c
+# SMIFlash.chm
+# SMIFlashLinks.c
+# SMIFlash.cif
+#
+# 11 5/23/12 3:01a Klzhan
+# [TAG] EIP81706
+# [Category] Improvement
+# [Description] Restore variables when recovery.
+#
+# 10 3/06/12 2:41a Klzhan
+# Improvement :
+# 1. Add non SMM Elinks
+# 2. Search Variables on in-active NVRam.
+#
+# 9 11/23/11 3:39a Calvinchen
+# [TAG] EIP54533
+# [Category] Improvement
+# [Description] 1. Removed BiosLockEnablePatchHook hook. Moved to
+# Chipset file.
+# 2. Also enable/disable PS2 keyboard in Enable/DisableUSBKBD hook.
+# 3. (EIP54533) Request for afu capable updating OEM firmware volumes
+# [Files] SMIFlash.sdl
+# SMIFlash.mak
+# SMIFlash.chm
+# SMIFlashLinks.c
+#
+# 8 3/23/11 4:44a Calvinchen
+# [TAG] EIP53067
+# [Category] Improvement
+# [Description] Modified for OEM Secure BIOS Update Requirements.
+# [Files] SMIFlash.sdl
+# SMIFlash.mak
+# SMIFlash.dxs
+# SMIFlash.c
+# SMIFlash.chm
+# SMIFlashLinks.c
+# SMIFlash.cif
+#
+# 7 6/15/10 3:11a Klzhan
+# Improvement: Add Elink to modify GetFlashInfo.
+#
+# 6 2/02/09 6:42p Fredericko
+#
+# 5 1/29/09 5:36p Fredericko
+# modified build for SMIFLASH_PRE_UPDATE_LIST and
+# SMIFLASH_END_UPDATE_LIST. See EIP 18819
+#
+# 4 8/15/07 7:07p Pats
+# Modified to support preservation of passwords through flashing.
+#
+# 3 12/29/06 3:04p Felixp
+# 1. Updated to use new Flash Interface.
+# 2. Embedded Controller support added.
+#
+# 2 12/02/05 11:48a Felixp
+#
+# 1 4/05/05 3:47p Sivagarn
+# Initial Checkin
+#
+#************************************************************************//
+
+all : SMIFlash
+
+SMIFLASH_BUILD_DIR = $(BUILD_DIR)\$(SMI_FLASH_DIR)
+
+SMIFlash : $(SMIFLASH_BUILD_DIR)\RomLayout.obj $(BUILD_DIR)\SMIFlash.mak SMIFlashBin
+
+SMIFlashObjects =\
+$(SMIFLASH_BUILD_DIR)\SMIFlash.obj\
+$(SMIFLASH_BUILD_DIR)\SMIFlashLinks.obj\
+$(SMIFLASH_BUILD_DIR)\RomLayout.obj\
+$(BUILD_DIR)\$(NVRAM_DIR)\NVRAMRead.obj\
+
+SMIFLASH_LISTS = \
+/D\"PRESERVE_FFS_GUID=$(SMIFlashPreserveRomHoleGuid)\"\
+/D\"SMIFLASH_IN_SMM_LIST=$(SMIFlashInSmmList)\"\
+/D\"SMIFLASH_NOT_IN_SMM_LIST=$(SMIFlashNotSmmList)\"\
+/D\"SMIFLASH_END_UPDATE_LIST=$(SMIFlashEndUpdateList)\"\
+/D\"SMIFLASH_PRE_UPDATE_LIST=$(SMIFlashPreUpdateList)\"\
+/D\"SMIFLASH_PRE_HANDLER_LIST=$(SMIFlashPreHandlerList)\"\
+/D\"SMIFLASH_END_HANDLER_LIST=$(SMIFlashEndHandlerList)\"
+
+$(BUILD_DIR)\SMIFlash.mak : $(SMI_FLASH_DIR)\SMIFlash.cif $(SMI_FLASH_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMI_FLASH_DIR)\SMIFlash.cif $(CIF2MAK_DEFAULTS)
+
+SMIFlashBin : $(AMIDXELIB) $(FLASHLIB) $(PRESERVE_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SMIFlash.mak all\
+ GUID=BC327DBD-B982-4f55-9F79-056AD7E987C5\
+ OBJECTS="$(SMIFlashObjects)" \
+ ENTRY_POINT=SMIFlashDriverEntryPoint\
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ "CFLAGS=$(CFLAGS) /DVFRCOMPILE $(SMIFLASH_LISTS)"\
+!IF $(PI_SPECIFICATION_VERSION) >= 0x1000A
+ TYPE=DXESMM_DRIVER\
+ DEPEX1=$(SMI_FLASH_DIR)\SMIFlash.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ DEPEX2=$(SMI_FLASH_DIR)\SMIFlashDxe.dxs \
+ DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \
+!ELSE
+ TYPE=BS_DRIVER\
+ DEPEX1=$(SMI_FLASH_DIR)\SMIFlash.dxs \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+!ENDIF
+ COMPRESS=1
+
+$(SMIFLASH_BUILD_DIR)\RomLayout.obj : $(BUILD_DIR)\RomLayout.c
+ $(CC) /Fo$@ $(CFLAGS) $(BUILD_DIR)\RomLayout.c
+
+#---------------------------------------------------------------------------
+# Reflash link file
+#---------------------------------------------------------------------------
+!IF "$(RECOVERY_PRESERVE_VARS_IN_SMM)"=="1"
+ReFlashBin : $(BUILD_DIR)\ReflashHooks.obj
+
+$(BUILD_DIR)\ReflashHooks.obj : $(SMI_FLASH_DIR)\SMIFlashLinks.c
+ $(CC) /Fo$(BUILD_DIR)\ReflashHooks.obj $(CFLAGS) /D_OUTSIDE_SMM_ $(SMI_FLASH_DIR)\SMIFlashLinks.c
+!ENDIF
+
+#//**********************************************************************//
+#//**********************************************************************//
+#//** **//
+#//** (C)Copyright 1985-2005, American Megatrends, Inc. **//
+#//** **//
+#//** All Rights Reserved. **//
+#//** **//
+#//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **//
+#//** **//
+#//** Phone: (770)-246-8600 **//
+#//** **//
+#//**********************************************************************//
+#//**********************************************************************//
diff --git a/Core/EM/SMIFlash/SMIFlash.sdl b/Core/EM/SMIFlash/SMIFlash.sdl
new file mode 100644
index 0000000..7cdc8e2
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlash.sdl
@@ -0,0 +1,349 @@
+TOKEN
+ Name = "SMIFlash_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SMIFlash support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SMI_FLASH_INTERFACE_VERSION"
+ Value = "11"
+ Help = "Version of the SMI Flash Interface"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REPORT_NCB_BY_ROM_LAYOUT"
+ Value = "0"
+ Help = "Report NCBs by ROM Layout Definitions."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PRESERVE_PASSWORDS"
+ Value = "0"
+ Help = "1 - Preserve passwords through flashing. 0 - Do not preserve passwords."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PRESERVE_EFIBOOTORDER"
+ Value = "1"
+ Help = "1 - Preserve EFI BootOrder through flashing. 0 - Do not preserve EFI BootOrder."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AFU_BUFFER_IN_SHADOW"
+ Value = "0"
+ Help = "1 - AFU will store the buffer pointer in F-segment If Afu support."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DISABLE_PWR_BUTTON"
+ Value = "0"
+ Help = "1 - Disable PWR Button when flashing BIOS in DOS."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "SMI_FLASH_DIR"
+End
+
+MODULE
+ Help = "Includes SMIFlash.mak to Project"
+ File = "SMIFlash.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SMIFlash.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreserveSetupPassword,"
+ Parent = "SMIFlashPreUpdateList"
+ Token = "PRESERVE_PASSWORDS" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RestoreSetupPassword,"
+ Parent = "SMIFlashEndUpdateList"
+ Token = "PRESERVE_PASSWORDS" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreserveEfiBootOrders,"
+ Parent = "SMIFlashPreUpdateList"
+ Token = "PRESERVE_EFIBOOTORDER" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RestoreEfiBootOrders,"
+ Parent = "SMIFlashEndUpdateList"
+ Token = "PRESERVE_EFIBOOTORDER" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DisablePowerButton,"
+ Parent = "SMIFlashPreUpdateList"
+ Token = "DISABLE_PWR_BUTTON" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "EnablePowerButton,"
+ Parent = "SMIFlashEndUpdateList"
+ Token = "DISABLE_PWR_BUTTON" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DisableUSBKBD,"
+ Parent = "SMIFlashPreUpdateList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "EnableUSBKBD,"
+ Parent = "SMIFlashEndUpdateList"
+ InvokeOrder = AfterParent
+End
+
+
+ELINK
+ Name = "UpdateShadowBuffer,"
+ Parent = "SMIFlashPreHandlerList"
+ Token = "AFU_BUFFER_IN_SHADOW" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ClearShadowBuffer,"
+ Parent = "SMIFlashEndHandlerList"
+ Token = "AFU_BUFFER_IN_SHADOW" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\AMICSPLib.Lib"
+ Parent = "PRESERVE_LIB"
+ Token = "AFU_BUFFER_IN_SHADOW" "=" "1"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ReassignNcbByRomLayout,"
+ Parent = "SMIFlashEndHandlerList"
+ Token = "REPORT_NCB_BY_ROM_LAYOUT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PostRestoreVariables,"
+ Parent = "SMIFlashNotSmmList"
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+ Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "USBNonSmmFunction,"
+ Parent = "SMIFlashNotSmmList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "USBInSmmFunction,"
+ Parent = "SMIFlashInSmmList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SMIFlashInSmmList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SMIFlashPreserveRomHoleGuid"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SMIFlashNotSmmList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SMIFlashPreUpdateList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SMIFlashEndUpdateList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SMIFlashPreHandlerList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "SMIFlashEndHandlerList"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "PRESERVE_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "RestoreSecureVariablesPreHandler,"
+ Parent = "SMIFlashPreHandlerList"
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+ Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RestoreSecureVariablesEndHandler,"
+ Parent = "SMIFlashEndHandlerList"
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+ Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ClearFFSState,"
+ Parent = "SecureUpdBeforeSmiflashWrite,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreserveWin8Variables,"
+ Parent = "SMIFlashPreUpdateList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RestoreWin8Variables,"
+ Parent = "SMIFlashEndUpdateList"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "NON_SECURE_NCB_UPDATE"
+ Value = "0"
+ Help = "1 - Allow NCB Update w/o Secure check."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "NCBUpdate,"
+ Parent = "SecureUpdBeforeSmiflashWrite,"
+ Token = "NON_SECURE_NCB_UPDATE" "=" "1"
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "NCBUpdate,"
+ Parent = "SecureUpdBeforeSmiflashWrite,"
+ Token = "NON_SECURE_NCB_UPDATE" "=" "1"
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "RECOVERY_PRESERVE_VARS_IN_SMM"
+ Value = "1"
+ Help = "1 - Preserved variables thru SMIFlash Func 0x20/0x24 if Capsule/Recovery mode of Secure Flash."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "RECOVERY_PRESERVE_ROMHOLE"
+ Value = "1"
+ Help = "1 - Preserved Romholes if Capsule/Recovery mode of Secure Flash."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+End
+
+ELINK
+ Name = "RecoveryPreserveRomHoles,"
+ Parent = "SMIFlashNotSmmList"
+ Token = "RECOVERY_PRESERVE_ROMHOLE" "=" "1"
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RecoveryHookBeforeFlash,"
+ Parent = "OemBeforeFlashUpdateList"
+ Token = "RECOVERY_PRESERVE_VARS_IN_SMM" "=" "1"
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RecoveryHookAfterFlash,"
+ Parent = "OemAfterFlashUpdateList"
+ Token = "RECOVERY_PRESERVE_VARS_IN_SMM" "=" "1"
+ Token = "SecSMIFlash_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "{0xFD44820B,0xF1AB,0x41c0,0xAE,0x4E,0x0C,0x55,0x55,0x6E,0xB9,0xBD},"
+ Parent = "SMIFlashPreserveRomHoleGuid"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "BACKUP_NVRAM_WHEN_FLASH"
+ Value = "0"
+ Help = "1 - Keep Current NVRAM, update new NVRAM to another NVRAM Region."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+End
+
+ELINK
+ Name = "CheckNVRAMArea,"
+ Parent = "SMIFlashPreUpdateList"
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+ Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "0"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "UpdateNVRAMArea,"
+ Parent = "SMIFlashEndUpdateList"
+ Token = "FAULT_TOLERANT_NVRAM_UPDATE" "=" "1"
+ Token = "BACKUP_NVRAM_WHEN_FLASH" "=" "0"
+ InvokeOrder = BeforeParent
+End
diff --git a/Core/EM/SMIFlash/SMIFlashDxe.dxs b/Core/EM/SMIFlash/SMIFlashDxe.dxs
new file mode 100644
index 0000000..09c5a47
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlashDxe.dxs
@@ -0,0 +1,72 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashDxe.dxs 2 11/02/12 7:14a Calvinchen $
+//
+// $Revision: 2 $
+//
+// $Date: 11/02/12 7:14a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashDxe.dxs $
+//
+// 2 11/02/12 7:14a Calvinchen
+// [TAG] EIP64328
+// [Category] Improvement
+// [Description] Improvement:
+// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI
+// 2.3.1 specifications.
+// BugFix:
+// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed
+// after restored.
+// 2. (EIP98199) The #### in Boot#### should be upper case.
+// [Files] SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlashDxe.dxs
+// SMIFlash.cif
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SMIFlashDxe.dxs
+//
+// Description: This file is the dependency file for the SMIFlash driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Protocol/FlashProtocol.h>
+
+DEPENDENCY_START
+ FLASH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SMIFlash/SMIFlashLinks.c b/Core/EM/SMIFlash/SMIFlashLinks.c
new file mode 100644
index 0000000..88e3155
--- /dev/null
+++ b/Core/EM/SMIFlash/SMIFlashLinks.c
@@ -0,0 +1,2227 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashLinks.c 52 4/11/16 9:22p Tristinchou $
+//
+// $Revision: 52 $
+//
+// $Date: 4/11/16 9:22p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMIFlash/SMIFlashLinks.c $
+//
+// 52 4/11/16 9:22p Tristinchou
+// [TAG] EIP261702
+// [Category] Improvement
+// [Description] Register event to get UsbRtKbcAccessControl() function
+// to disable keyboard
+//
+// 51 4/07/15 2:52a Tristinchou
+// [TAG] EIP211721
+// [Category] Improvement
+// [Description] Modify codes to call UsbRtKbcAccessControl() instead of
+// using outside smm pointer.
+//
+// 50 5/06/14 5:01a Calvinchen
+// [TAG] EIP166597
+// [Category] New Feature
+// [Description] Removing RT from variables could cause problems
+// accessing variables if PRESERVE_EFIBOOTORDER=1
+// [Files] SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlash.cif
+//
+// 49 3/10/14 2:44a Calvinchen
+// [TAG] EIP156780
+// [Category] Improvement
+// [Description] Boot related variables preserving in Aptio 4 SmiFlash
+//
+// 48 12/06/13 4:20a Calvinchen
+// [TAG] EIP145305
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Variable Restored failed after re-flashing when Nvram is in
+// Backup Area.
+// [RootCause] NVRAM State is not restored after re-flashing.
+// [Solution] Restore Nvram State.
+// [Files] SMIFlash.sdl
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlash.cif
+//
+// 47 12/20/12 8:52a Calvinchen
+// [TAG] EIP103562
+// [Category] Improvement
+// [Description] Need a way to preserve debug policy NV+BS variable(
+// WIN8 Logo requirement) in Nvram driver
+// [Files] SMIFlashLinks.c
+//
+// 46 12/06/12 4:56a Calvinchen
+// [TAG] EIP106623
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SmiFlash breaks build when NVRAM_BACKUP_ADDRESS is not
+// defined.
+// [RootCause] Smiflash don't remove the related procedures if
+// FAULT_TOLERANT_NVRAM_UPDATE is disabled.
+// [Solution] Remove the related procedures if
+// FAULT_TOLERANT_NVRAM_UPDATE is disabled.
+// [Files] SMIFlashLinks.c
+//
+// 45 11/20/12 5:39a Calvinchen
+// [TAG] EIP106623
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SmiFlash breaks build when FAULT_TOLERANT_NVRAM_UPDATE is
+// disabled
+// [RootCause] Smiflash don't remove the related procedures if
+// FAULT_TOLERANT_NVRAM_UPDATE is disabled.
+// [Solution] Remove the related procedures if
+// FAULT_TOLERANT_NVRAM_UPDATE is disabled.
+// [Files] SMIFlashLinks.c
+//
+// 44 11/19/12 3:48a Calvinchen
+// SmiFlash does not compile when CryptoPkg/Secure Boot Pkg/Secure Flash
+// Pkg are not in the project.
+//
+// 43 11/02/12 7:13a Calvinchen
+// [TAG] EIP64328
+// [Category] Improvement
+// [Description] Improvement:
+// 1. (EIP64328) Update modules to be compliant with PI 1.2 and UEFI
+// 2.3.1 specifications.
+// BugFix:
+// 1. (EIP100950) Fix the attribute of Win8 Debug Variable been changed
+// after restored.
+// 2. (EIP98199) The #### in Boot#### should be upper case.
+// [Files] SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlashDxe.dxs
+// SMIFlash.cif
+//
+// 41 7/13/12 2:14a Klzhan
+// Fix : Backup Flag not clear property.
+//
+// 4 7/02/12 3:45a Nerofan
+// Update to version 36
+//
+// 36 6/13/12 5:17a Klzhan
+// [TAG] EIP92023
+// [Category] Improvement
+// [Description] Emulation SMI should be disabled before Read/Write
+// 60/64 ports in smiflash.
+//
+// 35 6/01/12 5:13a Klzhan
+// Fix sometimes Deadloop when GetNextVariableName
+//
+// 34 5/31/12 2:22a Klzhan
+// Correct pointers.
+//
+// 33 5/30/12 4:19a Klzhan
+// Remove un-used GUID.
+//
+// 32 5/29/12 5:45a Klzhan
+// [TAG] EIP86878
+// [Category] Improvement
+// [Description] Restore SMBIOS data when recovery.
+// [Files] SMIFlash.sdl
+// SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlash.cif
+//
+// 31 5/25/12 6:26a Klzhan
+// [TAG] EIP90325
+// [Category] Improvement
+// [Description] UEFI Compliant - Global Defined Variables test
+//
+// 30 5/24/12 11:57p Klzhan
+// Fix exception error after flash NVRAM.
+//
+// 29 5/23/12 2:58a Klzhan
+// [TAG] EIP81706
+// [Category] Improvement
+// [Description] Restore variables when recovery.
+//
+// 28 5/22/12 4:43a Klzhan
+// [TAG] EIP90325
+// [Category] Improvement
+// [Description] Fix : UEFI Compliant - Globally Defined Variables test
+// fail
+//
+// 27 5/22/12 3:09a Klzhan
+// [TAG] EIP87892
+// [Category] Improvement
+// [Description] As Windows Logo requirment, need support to preserve
+// all UEFI variables with VendorGuid {77fa9abd-0359-4d32-bd60-
+// 28f4e78f784b} between flash updates
+//
+// 26 5/22/12 3:00a Klzhan
+// Set secure variables with authenticated Attributes.
+//
+// 25 5/21/12 4:48a Klzhan
+// Improvement : POST resetore only been called after AFU update.
+//
+// 24 4/05/12 4:40a Klzhan
+// BugFix : AFU will stop when SecureFlash is enabled.
+//
+// 23 3/27/12 11:19p Klzhan
+// [TAG] EIP86161
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build Error when X64_BUILD = 0
+//
+// 22 3/14/12 6:59a Klzhan
+// Remove un-use code
+//
+// 21 3/09/12 1:02a Klzhan
+// Fix variables not been restored property.
+//
+// 20 3/06/12 3:01a Klzhan
+// Improvement :
+// Support restore secure variables in POST.
+//
+// 19 2/10/12 7:14a Klzhan
+// Support NCB blocks updated with secure flash updated.
+//
+// 18 2/07/12 3:05a Klzhan
+// BugFIx : Fix erase size not correct.
+//
+// 17 2/06/12 3:27a Klzhan
+// [TAG] EIP80781
+// [Category] Improvement
+// [Description] Support OA key in NCB updated when Scure Flash Enabled
+//
+// 15 11/23/11 3:39a Calvinchen
+// [TAG] EIP54533
+// [Category] Improvement
+// [Description] 1. Removed BiosLockEnablePatchHook hook. Moved to
+// Chipset file.
+// 2. Also enable/disable PS2 keyboard in Enable/DisableUSBKBD hook.
+// 3. (EIP54533) Request for afu capable updating OEM firmware volumes
+// [Files] SMIFlash.sdl
+// SMIFlash.mak
+// SMIFlash.chm
+// SMIFlashLinks.c
+//
+// 14 11/03/11 7:09a Klzhan
+// [TAG] EIP73027
+// [Category] Improvement
+// [Description] Avoid un-inital variable used.
+//
+// 13 10/31/11 11:07p Klzhan
+// [TAG] EIP73017
+// [Category] Improvement
+// [Description] SavedBootXXX, conditionally not set.
+//
+// 12 5/18/11 6:03a Klzhan
+// BugFix : Memory will be crashed, free memory property.
+//
+// 11 5/17/11 3:23a Klzhan
+// Add Elinks to read buffer form shadow.
+//
+// 10 5/16/11 4:03a Klzhan
+// [TAG] EIP35562
+// [Category] Improvement
+// [Description] Boot#### variable,the #### should be upper case of A-F.
+// [Files] SMIFlahElinks.c
+//
+// 9 5/05/11 3:05a Klzhan
+//
+// 8 4/26/11 6:07a Calvinchen
+// [TAG] EIP58402
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AFUxxx flash utility hangs when Bootxxxx variable size is
+// greater than 0x200
+// [RootCause] The size of Boot0003 variable in the customer's project
+// is 0x242 bytes, which causes the memory corruption.
+// [Solution] Used allocate smm buffer instead of static structure.
+// [Files] SMIFlashLinks.c
+//
+// 6 3/23/11 4:44a Calvinchen
+// [TAG] EIP53067
+// [Category] Improvement
+// [Description] Modified for OEM Secure BIOS Update Requirements.
+// [Files] SMIFlash.sdl
+// SMIFlash.mak
+// SMIFlash.dxs
+// SMIFlash.c
+// SMIFlash.chm
+// SMIFlashLinks.c
+// SMIFlash.cif
+//
+// 5 12/14/10 4:38a Klzhan
+// [TAG] EIP49217
+// [Category] Improvement
+// [Description] Preserve BOOTxxxx for all EFI OS.
+// [Files] SMIFlashLinks.c
+//
+// 4 12/14/10 4:18a Klzhan
+// Move Locate USB Protocol to SMIFlashLinks.c.
+//
+// 3 12/14/10 3:49a Klzhan
+// Improvement : check is ROM layout changed before update NVRAM.
+//
+// 2 12/14/10 1:18a Klzhan
+// Remove debug codes.
+//
+// 1 12/14/10 1:15a Klzhan
+// Improvement : Move ELinks to SMIFlashLinks.c.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SMIFlashLinks.c
+//
+// Description: Elinks to SMIFlash.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <Token.h>
+#include <Protocol\SmiFlash.h>
+#include <Setup.h>
+#include <Protocol\FlashProtocol.h>
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+#include <Protocol\AmiUsbController.h>
+#endif
+#endif
+
+#include <RomLayout.h>
+#include <Flash.h>
+#include <AmiHobs.h>
+#include <Core\EM\NVRAM\NVRam.h>
+#include <ImageAuthentication.h>
+#include <Protocol\FlashProtocol.h>
+#include "timestamp.h"
+//----------------------------------------------------------------------
+// component MACROs
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_GUID gEfiCertTypePkcs7Guid = EFI_CERT_TYPE_PKCS7_GUID;
+
+//----------------------------------------------------------------------
+// Module defined global variables
+extern FLASH_PROTOCOL *Flash;
+//*********** INSIDE SMM ***********************************************
+#if !defined _OUTSIDE_SMM_
+
+extern ROM_AREA RomLayout[];
+extern VOID ChipsetFlashDeviceWriteEnable();
+
+EFI_GUID RecoveryPreserveGUID[] =
+{
+ { 0x05ca01fc, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca01fd, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca01fe, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca01ff, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0200, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0201, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0202, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0203, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0204, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0205, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0206, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0207, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0208, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca0209, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca020a, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ { 0x05ca020b, 0x0fc1, 0x11dc, 0x90, 0x11, 0x00, 0x17, 0x31, 0x53, 0xeb, 0xa8 },
+ PRESERVE_FFS_GUID
+ {NULL}
+};
+
+//----------------------------------------------------------------------
+// Module specific global variable
+#define ROM_LAYOUT_FFS_GUID \
+ { 0x0DCA793A, 0xEA96, 0x42d8, 0xBD, 0x7B, 0xDC, 0x7F, 0x68, 0x4E, 0x38, 0xC1 }
+#define AMITSESETUP_GUID \
+ { 0xc811fa38, 0x42c8, 0x4579, 0xa9, 0xbb, 0x60, 0xe9, 0x4e, 0xdd, 0xfb, 0x34 }
+#define WIN8_GUID \
+ { 0x77FA9ABD, 0x0359, 0x4D32, 0xBD, 0x60, 0x28, 0xF4, 0xE7, 0x8F, 0x78, 0x4B }
+EFI_GUID gWin8Guid = WIN8_GUID;
+#define DefaultVariableSize 100
+
+EFI_GUID gAmiTseSetupGuid = AMITSESETUP_GUID;
+AMITSESETUP gAmiTseData;
+UINT32 gAmiTseDataAttr = 0;
+
+#pragma pack(1)
+typedef struct {
+ CHAR16 BootVarName[0x20];
+ UINT16 BootOrderNO;
+ UINTN BootXXXXSize;
+//- UINT8 *BootXXXX;
+} RESTORE_BOOTORDER;
+EFI_PHYSICAL_ADDRESS gSmmBootOrder = NULL;
+UINT8 gNumBootDevice = 0;
+#define RESTORE_BOOT_ORDER_BUFFER 0x4000
+#define BOOT_ORDER_OFFSET (RESTORE_BOOT_ORDER_BUFFER - 0x100)
+#define LEGACY_BOOT_ORDER_OFFSET (RESTORE_BOOT_ORDER_BUFFER - 0x200)
+
+typedef struct {
+ CHAR16 *BootVarName;
+ EFI_GUID *Guid;
+} RESTORE_VARIABLES;
+
+typedef struct {
+ UINT32 Attrib;
+ UINTN Size;
+ UINT8* Data;
+} RESTORE_ATTR;
+
+typedef struct {
+ RESTORE_VARIABLES rVar;
+ RESTORE_ATTR rATTR;
+ UINTN NextData;
+} RESTORE_VAR;
+#pragma pack()
+RESTORE_VAR *RestoreVarList;
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+EFI_KBC_ACCESS_CONTROL gUsbRtKbcAccessControl = NULL;
+#endif
+#endif
+
+#define EFI_IMAGE_SECURITY_DATABASE L"db"
+#define EFI_IMAGE_SECURITY_DATABASE1 L"dbx"
+#define EFI_PLATFORM_KEY_NAME L"PK"
+#define EFI_KEY_EXCHANGE_KEY_NAME L"KEK"
+
+EFI_GUID PKeyFileGuid = EFI_GLOBAL_VARIABLE;
+EFI_GUID KekFileGuid = EFI_GLOBAL_VARIABLE;
+EFI_GUID DbFileGuid = EFI_IMAGE_SECURITY_DATABASE_GUID;
+EFI_GUID DbxFileGuid = EFI_IMAGE_SECURITY_DATABASE_GUID;
+
+//-VOID CheckNVRAMArea(VOID);
+EFI_FFS_FILE_STATE NvramFFSState;
+EFI_FFS_FILE_STATE *NvramFFSStatePtr;
+
+RESTORE_VARIABLES RestoreVariables[] = {
+{EFI_IMAGE_SECURITY_DATABASE1, &DbxFileGuid},
+{EFI_IMAGE_SECURITY_DATABASE, &DbFileGuid},
+{EFI_KEY_EXCHANGE_KEY_NAME, &KekFileGuid},
+{EFI_PLATFORM_KEY_NAME, &PKeyFileGuid},
+{NULL,NULL}
+};
+
+#define NUM_OF_RESTORE_VARS (sizeof(RestoreVariables)/sizeof(RESTORE_VARIABLES))
+
+#ifndef EFI_VARIABLE_AUTHENTICATION_2
+typedef struct {
+ EFI_TIME TimeStamp;
+ WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION_2;
+#endif
+
+static EFI_TIME EfiTimeStamp = {
+ FOUR_DIGIT_YEAR_INT,
+ TWO_DIGIT_MONTH_INT,
+ TWO_DIGIT_DAY_INT,
+ TWO_DIGIT_HOUR_INT,
+ TWO_DIGIT_MINUTE_INT,
+ TWO_DIGIT_SECOND_INT,0,0,0,0,0};
+
+RESTORE_ATTR RestoreAttr[NUM_OF_RESTORE_VARS - 1];
+
+// SMM Nvram Control Protocol Definitions
+typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+typedef struct{
+ SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables;
+} AMI_NVRAM_CONTROL_PROTOCOL;
+
+AMI_NVRAM_CONTROL_PROTOCOL *LocateNvramControlSmmProtocol(){
+ static EFI_GUID gAmiNvramControlProtocolGuid = { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } };
+ return GetSmstConfigurationTable(&gAmiNvramControlProtocolGuid);
+}
+AMI_NVRAM_CONTROL_PROTOCOL *gNvramControl = NULL;
+//----------------------------------------------------------------------
+// externally defined variables
+//----------------------------------------------------------------------
+// Function definitions
+// BIT00 = 1 --> Update NVRAM
+// BIT01 = 1 --> Update NVRAM Backup Address
+UINT8 UpdateNVram = 0;
+UINT64 BufAddr;
+UINT8 FFSState;
+#if FAULT_TOLERANT_NVRAM_UPDATE
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: MoveNVRamToAnotherRegion
+//
+// Description: Copy current NVRAM to another NBRAM region
+//
+//
+// Input: Data - SW SMI value number
+// pInfoBlock - AFU Data Buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+MoveNVRamToAnotherRegion
+(
+ VOID
+)
+{
+ // Move NVRam to another Region
+ // We can keep secure variables
+ EFI_STATUS Status;
+ UINT32 UpdateAddress, SourceAddress, i, Buffer32;
+ UINTN NumberOfPages;
+ EFI_PHYSICAL_ADDRESS Phy_Address;
+ UINT8* Buffer;
+
+ if(UpdateNVram & BIT00)
+ {
+ UpdateAddress = NVRAM_BACKUP_ADDRESS;
+ SourceAddress = NVRAM_ADDRESS;
+ }
+ else
+ {
+ UpdateAddress = NVRAM_ADDRESS;
+ SourceAddress = NVRAM_BACKUP_ADDRESS;
+ }
+ NumberOfPages = ((NVRAM_SIZE) >> 12);
+ Status = pSmst->SmmAllocatePages(AllocateAnyPages,
+ EfiRuntimeServicesData, NumberOfPages, &Phy_Address);
+
+ Flash->Erase((UINT8*)UpdateAddress, NVRAM_SIZE);
+ if(!EFI_ERROR(Status))
+ {
+ Buffer = (UINT8*)Phy_Address;
+ Flash->Read(
+ (UINT8*)(SourceAddress), NVRAM_SIZE, Buffer);
+
+ Flash->Write(
+ (UINT8*)(UpdateAddress), NVRAM_SIZE, Buffer);
+
+ pSmst->SmmFreePages(Phy_Address, NumberOfPages);
+ }else
+ {
+ // If no memory , just do it 4 bytes one time.
+ for(i = 0; i < NVRAM_SIZE ; i += sizeof(UINT32))
+ {
+ Flash->Read(
+ (UINT8*)(SourceAddress + i), sizeof(UINT32), &Buffer32);
+ if(Buffer32 == 0xFFFFFFFF)
+ continue;
+ Flash->Write(
+ (UINT8*)(UpdateAddress + i), sizeof(UINT32), &Buffer32);
+ }
+ }
+
+}
+#endif // #if FAULT_TOLERANT_NVRAM_UPDATE
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: ClearFFSState
+//
+// Description: Clear FFS State of Buffer
+//
+//
+// Input: Data - SW SMI value number
+// pInfoBlock - AFU Data Buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ClearFFSState(
+ UINT8 Data,
+ UINT64 pInfoBlock
+)
+{
+ FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock;
+ UINT32 FlashAddress;
+
+ FlashAddress = (pFuncBuff->BlockAddr + (0xFFFFFFFF - FLASH_SIZE + 1));
+ // Runs in Main Address, clear FFSState
+ // if power-off while update, system runs in Backup address
+ if((Data == SMIFLASH_WRITE_FLASH) && (FlashAddress == NVRAM_ADDRESS))
+ {
+ BufAddr = pFuncBuff->BufAddr;
+ FFSState = *(UINT8*)(pFuncBuff->BufAddr + 0x5F);
+ *(UINT8*)(pFuncBuff->BufAddr + 0x5F) = 0xFF;
+ }
+}
+#if FAULT_TOLERANT_NVRAM_UPDATE
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: RestoreSecureVariablesPreHandler
+//
+// Description: Clear and Set FFS state when NVRAM region updated
+//
+//
+// Input: Data - SW SMI value number
+// pInfoBlock - AFU Data Buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreSecureVariablesPreHandler(
+ UINT8 Data,
+ UINT64 pInfoBlock
+)
+{
+ FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock;
+ UINT32 FlashAddress;
+ static BOOLEAN InitDone = FALSE, RunInMain = FALSE;
+
+ if((Data != SMIFLASH_ERASE_FLASH) &&
+ (Data != SMIFLASH_WRITE_FLASH) &&
+ (Data != SMIFLASH_READ_FLASH))
+ return;
+
+ FlashAddress = (pFuncBuff->BlockAddr + (0xFFFFFFFF - FLASH_SIZE + 1));
+ if((FlashAddress < NVRAM_ADDRESS) ||
+ (FlashAddress >= NVRAM_ADDRESS + NVRAM_SIZE))
+ return;
+
+ if(!InitDone)
+ {
+ NVRAM_STORE_INFO MainNvram;
+ BOOLEAN BackupStoreValid;
+ VOID *BackupNvramAddress = (VOID*)NVRAM_BACKUP_ADDRESS;
+
+
+ MainNvram.NvramAddress = (UINT8*)NVRAM_ADDRESS;
+ MainNvram.NvramSize = NVRAM_SIZE;
+ if (!IsMainNvramStoreValid(&MainNvram, BackupNvramAddress,&BackupStoreValid)){
+ if (BackupStoreValid)
+ RunInMain = FALSE;
+ }else
+ RunInMain = TRUE;
+
+ InitDone = TRUE;
+ }
+
+ // NVRam runs in NVRAM address
+ if(RunInMain)
+ {
+ UpdateNVram |= BIT00;
+ }else
+ {
+ if(NVRAM_ADDRESS > NVRAM_BACKUP_ADDRESS)
+ pFuncBuff->BlockAddr -= (NVRAM_ADDRESS - NVRAM_BACKUP_ADDRESS);
+ else
+ pFuncBuff->BlockAddr += (NVRAM_BACKUP_ADDRESS - NVRAM_ADDRESS);
+
+ UpdateNVram |= BIT01;
+ }
+
+ // Frist in, move current NVRam to another
+ if((Data == SMIFLASH_ERASE_FLASH) && (FlashAddress == NVRAM_ADDRESS))
+ MoveNVRamToAnotherRegion();
+
+ // Runs in Main Address, clear FFSState
+ // if power-off while update, system runs in Backup address
+ if((Data == SMIFLASH_WRITE_FLASH) && (FlashAddress == NVRAM_ADDRESS))
+ *(UINT8*)(pFuncBuff->BufAddr + 0x5F) = 0xFF;
+
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: RestoreSecureVariablesEndHandler
+//
+// Description: Clear and Set FFS state when NVRAM region updated
+//
+//
+// Input: Data - SW SMI value number
+// pInfoBlock - AFU Data Buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreSecureVariablesEndHandler(
+ UINT8 Data,
+ UINT64 pInfoBlock
+)
+{
+ FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock;
+ UINT32 FlashAddress, EndNVRamAddress, TempNVRamAddress;
+ UINT8 Buffer8 = 0x08;
+
+ if(Data != SMIFLASH_WRITE_FLASH)
+ return;
+
+ switch(UpdateNVram)
+ {
+ case 1:
+ EndNVRamAddress = NVRAM_ADDRESS + NVRAM_SIZE;
+ TempNVRamAddress = NVRAM_BACKUP_ADDRESS;
+ break;
+ case 2:
+ EndNVRamAddress = NVRAM_BACKUP_ADDRESS + NVRAM_SIZE;
+ TempNVRamAddress = NVRAM_ADDRESS;
+ break;
+ default:
+ return;
+ }
+
+ FlashAddress = (pFuncBuff->BlockAddr + (0xFFFFFFFF - FLASH_SIZE + 1));
+ if(FlashAddress == NVRAM_ADDRESS)
+ *(UINT8*)(BufAddr + 0x5F) = FFSState;
+
+ if((FlashAddress + pFuncBuff->BlockSize) != EndNVRamAddress)
+ return;
+
+ // Clear State
+ Flash->Write((UINT8*)(TempNVRamAddress + 0x5F),
+ sizeof(UINT8), &Buffer8);
+
+ Buffer8 = 0xF8;
+ // Set State
+ Flash->Write((UINT8*)(EndNVRamAddress - NVRAM_SIZE + 0x5F),
+ sizeof(UINT8), &Buffer8);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PostRestoreVariables
+//
+// Description: Find Variables want to restore and restore then
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PostRestoreVariables(
+ VOID
+)
+{
+ NVRAM_STORE_INFO pInfo;
+ UINTN HeaderSize = 0x60, i;
+ UINT8 Flags = NVRAM_STORE_FLAG_NON_VALATILE;
+ EFI_STATUS Status;
+ NVRAM_STORE_INFO MainNvram;
+ BOOLEAN BackupStoreValid, RunInMain, ClearFlag = FALSE;
+ VOID *BackupNvramAddress = (VOID*)NVRAM_BACKUP_ADDRESS;
+ UINT8 Buffer8 = 0x08;
+ EFI_VARIABLE_AUTHENTICATION_2 *AuthHdr2;
+ UINTN VarSize;
+
+ for(i = 0 ; i < (NUM_OF_RESTORE_VARS - 1) ; i ++)
+ {
+ RestoreAttr[i].Size = 0;
+ Status = pRS->GetVariable(RestoreVariables[i].BootVarName,
+ RestoreVariables[i].Guid,
+ &RestoreAttr[i].Attrib,
+ &RestoreAttr[i].Size,
+ NULL);
+ // EFI_BUFFER_TOO_SMALL means variable exists
+ if(Status != EFI_BUFFER_TOO_SMALL)
+ break;
+ }
+
+ // All secure variable exist, return
+ if(i == (NUM_OF_RESTORE_VARS - 1))
+ ClearFlag = TRUE;
+
+
+ VERIFY_EFI_ERROR(pBS->LocateProtocol(&gFlashProtocolGuid,
+ NULL, &Flash));
+ // Check current running region
+ MainNvram.NvramAddress = (UINT8*)NVRAM_ADDRESS;
+ MainNvram.NvramSize = NVRAM_SIZE;
+ if (!IsMainNvramStoreValid(&MainNvram, BackupNvramAddress,&BackupStoreValid)){
+ if (BackupStoreValid)
+ RunInMain = FALSE;
+ }else
+ RunInMain = TRUE;
+
+ if(RunInMain)
+ {
+
+ pInfo.NvramAddress = (UINT8*)NVRAM_BACKUP_ADDRESS;
+ // NVRAM update successful, but variables not restored yet.
+ if(*(pInfo.NvramAddress + 0x5F) == 0xF8)
+ {
+ Flash->DeviceWriteEnable();
+ Flash->Write((UINT8*)(pInfo.NvramAddress + 0x5F),
+ sizeof(UINT8), &Buffer8);
+ Flash->DeviceWriteDisable();
+ }
+ }
+ else
+ pInfo.NvramAddress = (UINT8*)NVRAM_ADDRESS;
+
+ // FFS State is 8 mneas AFU update NVRAM but variables not been restored
+ if(*(pInfo.NvramAddress + 0x5F) != 0x08)
+ return;
+
+ pInfo.NvramSize = NVRAM_SIZE;
+ NvInitInfoBuffer(&pInfo, HeaderSize, Flags);
+
+ for( ; i < (NUM_OF_RESTORE_VARS - 1) && !ClearFlag ; i ++)
+ {
+
+ RestoreAttr[i].Size = 0;
+ Status = NvGetVariable2(RestoreVariables[i].BootVarName,
+ RestoreVariables[i].Guid,
+ &RestoreAttr[i].Attrib,
+ &RestoreAttr[i].Size,
+ NULL,
+ 1,
+ &pInfo);
+
+ // It should be happened on frist few boots
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ UINT8* DataBuffer = NULL;
+
+ VarSize = RestoreAttr[i].Size + sizeof(EFI_VARIABLE_AUTHENTICATION_2);
+
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ VarSize,
+ (VOID**)&DataBuffer);
+
+ Status = NvGetVariable2(RestoreVariables[i].BootVarName,
+ RestoreVariables[i].Guid,
+ &RestoreAttr[i].Attrib,
+ &RestoreAttr[i].Size,
+ DataBuffer + sizeof(EFI_VARIABLE_AUTHENTICATION_2),
+ 1,
+ &pInfo);
+
+ AuthHdr2 = (EFI_VARIABLE_AUTHENTICATION_2*)DataBuffer;
+ MemCpy (&AuthHdr2->TimeStamp, &EfiTimeStamp, sizeof (EFI_TIME));
+ AuthHdr2->AuthInfo.Hdr.dwLength = sizeof(WIN_CERTIFICATE_UEFI_GUID);
+ AuthHdr2->AuthInfo.Hdr.wRevision = 0x200;
+ AuthHdr2->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
+ AuthHdr2->AuthInfo.CertType = gEfiCertTypePkcs7Guid;
+
+ if (!EFI_ERROR(Status)) {
+ Status = pRS->SetVariable ( RestoreVariables[i].BootVarName,
+ RestoreVariables[i].Guid,
+ RestoreAttr[i].Attrib | \
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS,
+ VarSize,
+ DataBuffer);
+ pBS->FreePool (DataBuffer);
+ }
+
+ }
+ }
+ Buffer8 = 0;
+ Flash->DeviceWriteEnable();
+ Flash->Write((UINT8*)(pInfo.NvramAddress + 0x5F),
+ sizeof(UINT8), &Buffer8);
+ Flash->DeviceWriteDisable();
+}
+#endif // #if FAULT_TOLERANT_NVRAM_UPDATE
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: NCBUpdate
+//
+// Description: Support All NCBs updated when enable secure Flash Support
+//
+//
+// Input: SwSmiNum - SW SMI value number
+// Buffer - Flash descriptor address
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID NCBUpdate(
+ UINT8 Data,
+ UINT64 pInfoBlock
+)
+{
+ FUNC_BLOCK *pFuncBuff = (FUNC_BLOCK*)pInfoBlock;
+ EFI_STATUS Status;
+ UINT8 *FlashAddress;
+ static BOOLEAN BeforeSecure = FALSE;
+ ROM_AREA *Area;
+
+ if(BeforeSecure)
+ {
+ BeforeSecure = FALSE;
+ pFuncBuff->ErrorCode = 0;
+ return;
+ }
+
+ if((Data != SMIFLASH_ERASE_FLASH) && (Data != SMIFLASH_WRITE_FLASH))
+ return;
+
+ FlashAddress = (UINT8*)(UINTN)(pFuncBuff->BlockAddr +
+ (0xFFFFFFFF - FLASH_SIZE + 1));
+ for (Area = RomLayout; Area->Size != 0; Area++) {
+
+ if(Area->Type != RomAreaTypeRaw)
+ continue;
+
+ if(((UINT32)FlashAddress >= Area->Address) &&
+ ((UINT32)FlashAddress < (Area->Address + Area->Size)))
+ {
+ if(Data == 0x22)
+ {
+ Status = Flash->Erase(FlashAddress, FLASH_BLOCK_SIZE);
+ pFuncBuff->ErrorCode = EFI_ERROR(Status) != 0;
+ BeforeSecure = TRUE;
+ }
+ if(Data == 0x23)
+ {
+ Status = Flash->Write(FlashAddress, pFuncBuff->BlockSize,
+ (UINT8*)pFuncBuff->BufAddr);
+ pFuncBuff->ErrorCode = EFI_ERROR(Status) != 0;
+ BeforeSecure = TRUE;
+ }
+ }
+ }
+}
+#if REPORT_NCB_BY_ROM_LAYOUT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: ReassignNcbByRomLayout
+//
+// Description: Re-assign NCBs Type Id by ROM Layout definition for
+// separating NCBs.
+//
+// Input: SwSmiNum - SW SMI value number
+// Buffer - Flash descriptor address
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ReassignNcbByRomLayout (
+ IN UINT8 SwSmiNum,
+ IN UINT64 Buffer
+)
+{
+ BLOCK_DESC *BlockDesc;
+ ROM_AREA *Area;
+ UINT16 i, j, LastNcb;
+ UINT8 NCBTypeId = NC_BLOCK;
+
+ // return if SW SMI value is not "Get Flash Info"
+ if (SwSmiNum != SMIFLASH_GET_FLASH_INFO) return;
+
+ BlockDesc = (BLOCK_DESC*)&((INFO_BLOCK*)Buffer)->Blocks;
+ for (i = 0, LastNcb = 0xffff; i < ((INFO_BLOCK*)Buffer)->TotalBlocks; i++) {
+ if (BlockDesc[i].Type < NC_BLOCK) continue;
+ // check whether NCB is described in RomLayout.
+ for (Area = RomLayout; Area->Size != 0; Area++) {
+ if (BlockDesc[i].StartAddress != \
+ (UINT32)(Area->Address - FlashDeviceBase)) continue;
+ for (j = 0, NCBTypeId++; j < (Area->Size / FlashBlockSize); j++) {
+ BlockDesc[i + j].Type = NCBTypeId;
+ }
+ i += ((Area->Size / FLASH_BLOCK_SIZE) - 1);
+ break;
+ }
+ // if this NCB isn't describe in RomLayout
+ if (Area->Size == 0) {
+ if (i != (LastNcb + 1)) NCBTypeId++;
+ BlockDesc[i].Type = NCBTypeId;
+ }
+ LastNcb = i;
+ }
+}
+#endif // #if REPORT_NCB_BY_ROM_LAYOUT
+
+#ifdef FAULT_TOLERANT_NVRAM_UPDATE
+#if FAULT_TOLERANT_NVRAM_UPDATE == 1 && BACKUP_NVRAM_WHEN_FLASH == 0
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetNvramMainFFSStats
+//
+// Description: Get NVRAM Main FFS state.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_FFS_FILE_STATE*
+GetNvramMainFFSStats(
+ VOID
+)
+{
+ EFI_FFS_FILE_HEADER *FfsFileHeader;
+ EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader;
+
+ FwVolHeader = (EFI_FIRMWARE_VOLUME_HEADER *)NVRAM_ADDRESS;
+
+ if (FwVolHeader->FvLength == NVRAM_SIZE)
+ {
+ FfsFileHeader = (EFI_FFS_FILE_HEADER *)(
+ NVRAM_ADDRESS + FwVolHeader->HeaderLength
+ );
+ return &FfsFileHeader->State;
+ }else
+ return NULL;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CheckNVRAMArea
+//
+// Description: Check NVRam FFS state.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CheckNVRAMArea(
+ VOID
+)
+{
+ NvramFFSState = *GetNvramMainFFSStats();
+ NvramFFSStatePtr = GetNvramMainFFSStats();
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: NVRAMChanged
+//
+// Description: Check Location of NVRAM region.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: TRUE - Location of NVRAM been changed.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+NVRAMChanged(
+ VOID
+)
+{
+ UINTN FVSignOffset = 0x28, NVRAMRegion = NVRAM_ADDRESS;
+ UINT32 FVSig;
+
+ // Check NVRAM_ADDRESS still NVRAM region
+ // Can we find signature ??
+ Flash->Read((UINT8*)(NVRAMRegion + FVSignOffset),sizeof(FVSig), &FVSig);
+ if (FVSig != FV_SIGNATURE) return TRUE;
+
+ // The first Data is NVAR ??
+ // Simple verify.
+ Flash->Read((UINT8*)(NVRAMRegion + NVRAM_HEADER_SIZE),sizeof(FVSig), &FVSig);
+ if ((FVSig != 'RAVN') && (FVSig != 'NVAR')) return TRUE;
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: UpdateNVRAMArea
+//
+// Description: If NVRam updated and current NVRam runs at Backup address.
+// also update NVRAM Backup address.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateNVRAMArea(
+ VOID
+)
+{
+ UINT32 i = 0, Buffer32 = 0;
+ UINT8* Buffer;
+ EFI_FFS_FILE_STATE NewNVRamFFSState;
+ EFI_STATUS Status;
+ UINTN NumberOfPages;
+ EFI_PHYSICAL_ADDRESS Phy_Address;
+
+ // Check NVRAM_ADDRESS FFS State
+ // If Status changed.
+ // Then, we got an NVRAM area update
+ // and current NVRam working at NVRAM_BACKUP_ADDRESS!!
+ // So move the NVRAM_MAIN to NVRAM_BACKUP and Restore NVRAM_MAIN State.
+ Flash->Read((UINT8*)NvramFFSStatePtr,
+ sizeof(EFI_FFS_FILE_STATE), &NewNVRamFFSState);
+ // Before update FFSState to new NVRAM, check ROMLAYOUT changed or not.
+ if(NVRAMChanged())
+ return;
+ if((NvramFFSState == NewNVRamFFSState) || (NvramFFSState == 0))
+ return;
+ NumberOfPages = ((NVRAM_SIZE) >> 12);
+ Status = pSmst->SmmAllocatePages(AllocateAnyPages, EfiRuntimeServicesData, NumberOfPages, &Phy_Address);
+
+ // NVRAM updated !!
+ // Move NVRAM Main to NVRAM Backup
+ Flash->Erase((UINT8*)NVRAM_BACKUP_ADDRESS, NVRAM_SIZE);
+ // For AMD chipset workaround !!
+ // AMD SPI can't read SPI ROM as buffer.
+ if(!EFI_ERROR(Status))
+ {
+ Buffer = (UINT8*)Phy_Address;
+ Flash->Read(
+ (UINT8*)(NVRAM_ADDRESS), NVRAM_SIZE, Buffer);
+
+ Flash->Write(
+ (UINT8*)(NVRAM_BACKUP_ADDRESS), NVRAM_SIZE, Buffer);
+
+ pSmst->SmmFreePages(Phy_Address, NumberOfPages);
+
+ }else
+ {
+ // If no memory , just do it 4 bytes one time.
+ for(; i < NVRAM_SIZE ; i += sizeof(UINT32))
+ {
+ Flash->Read(
+ (UINT8*)(NVRAM_ADDRESS + i), sizeof(UINT32), &Buffer32);
+ if(Buffer32 == 0xFFFFFFFF)
+ continue;
+ Flash->Write(
+ (UINT8*)(NVRAM_BACKUP_ADDRESS + i), sizeof(UINT32), &Buffer32);
+ }
+ }
+ // Restore NVRAM Main FFS state!!
+ Flash->Write((UINT8*)NvramFFSStatePtr,
+ sizeof(EFI_FFS_FILE_STATE),&NvramFFSState);
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PreserveEfiBootOrders
+//
+// Description: Save the BootXXXX contains "Windows Boot Manager"
+// For EFI OS.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PreserveEfiBootOrders(VOID)
+{
+
+ UINTN BootOrderSize, LegacyOrderSize;
+ EFI_STATUS Status;
+ EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_GUID LegacyDevOrderGuid = LEGACY_DEV_ORDER_GUID;
+ RESTORE_BOOTORDER *SavedBootXXX;
+ UINT8 i;
+ UINT16 *BootOrder, *LegacyOrder;
+
+ // Get BootOrder for restore
+ if (gSmmBootOrder == NULL) {
+ Status = pSmst->SmmAllocatePages ( AllocateAnyPages, \
+ 0, \
+ RESTORE_BOOT_ORDER_BUFFER >> 12, \
+ &gSmmBootOrder);
+ if (EFI_ERROR(Status)) return ;
+ SavedBootXXX = (RESTORE_BOOTORDER*)gSmmBootOrder;
+ BootOrder = (UINT16*)(gSmmBootOrder + BOOT_ORDER_OFFSET);
+ } else return;
+
+ // Get BootOrder variable size
+ BootOrderSize = 0;
+ Status = pRS->GetVariable(L"BootOrder",&EfiVariableGuid, \
+ NULL,&BootOrderSize, NULL);
+ if(Status != EFI_NOT_FOUND)
+ {
+ Status = pRS->GetVariable(L"BootOrder", &EfiVariableGuid, \
+ NULL, &BootOrderSize, BootOrder);
+ if(EFI_ERROR(Status)) return;
+
+ } else return; // If BootOrder is not found, just return
+
+ // Due to the "RT" attribute could be removed from LegacyDevOreder variable,
+ // here to enable Nvram Full Access control for getting variable if "NV+BS" only.
+ if (gNvramControl == NULL) gNvramControl = LocateNvramControlSmmProtocol();
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE);
+ // Get LegacyBootOrder variable size
+ LegacyOrder = (UINT16*)(gSmmBootOrder + LEGACY_BOOT_ORDER_OFFSET);
+ LegacyOrderSize = 0;
+ Status = pRS->GetVariable(L"LegacyDevOrder", \
+ &LegacyDevOrderGuid, NULL, &LegacyOrderSize, NULL);
+ if(Status != EFI_NOT_FOUND) {
+ Status = pRS->GetVariable(L"LegacyDevOrder",
+ &LegacyDevOrderGuid, \
+ (UINT32*)((UINT8*)LegacyOrder + sizeof(UINT32)), \
+ &LegacyOrderSize, \
+ (UINT8*)LegacyOrder + (sizeof(UINT32) * 2));
+ *(UINT32*)LegacyOrder = (UINT32)LegacyOrderSize;
+ } else *(UINT32*)LegacyOrder = 0; // Clear Buffer to indicate no LegacyDevOrder
+ // Disable the Nvram Full Access control after processing the "LegacyDevOrder".
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE);
+
+ // Get BootXXXX for restore
+ for(i = 0, gNumBootDevice = 0; i < (BootOrderSize / sizeof(UINT16)); i++)
+ {
+ Swprintf(SavedBootXXX->BootVarName, L"Boot%04X", *(BootOrder + i));
+ // Get Bootxxx variable size
+ SavedBootXXX->BootXXXXSize = 0;
+ Status = pRS->GetVariable( SavedBootXXX->BootVarName, \
+ &EfiVariableGuid, \
+ NULL, \
+ &SavedBootXXX->BootXXXXSize, \
+ NULL);
+ // if not found, try upper case.
+ if(Status == EFI_NOT_FOUND)
+ {
+ Swprintf(SavedBootXXX->BootVarName, L"Boot%04X", *(BootOrder + i));
+ // Get Variable size.
+ SavedBootXXX->BootXXXXSize = 0;
+ Status = pRS->GetVariable(
+ SavedBootXXX->BootVarName, \
+ &EfiVariableGuid, \
+ NULL, \
+ &SavedBootXXX->BootXXXXSize, \
+ NULL);
+ }
+ // Get this from BootOrder, there must be a variable
+ pRS->GetVariable( SavedBootXXX->BootVarName, \
+ &EfiVariableGuid, \
+ NULL, \
+ &SavedBootXXX->BootXXXXSize, \
+ (UINT8*)SavedBootXXX + sizeof(RESTORE_BOOTORDER));
+ SavedBootXXX->BootOrderNO = *(BootOrder + i);
+ // Ptr to next "BootXXXX" buffer.
+ (UINT8*)SavedBootXXX += (SavedBootXXX->BootXXXXSize + \
+ sizeof(RESTORE_BOOTORDER));
+ gNumBootDevice++;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: RestoreEfiBootOrders
+//
+// Description: Restore the BootXXXX contains "Windows Boot Manager"
+// For EFI OS.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID RestoreEfiBootOrders (VOID)
+{
+ EFI_GUID EfiVariableGuid = EFI_GLOBAL_VARIABLE;
+ EFI_GUID LegacyDevOrderGuid = LEGACY_DEV_ORDER_GUID;
+ UINTN BootOrderSize;
+ UINT16 *BootOrder;
+ RESTORE_BOOTORDER *SavedBootXXX;
+ UINT8 i;
+ EFI_STATUS Status;
+
+ if (gSmmBootOrder == NULL) return;
+ BootOrder = (UINT16*)(gSmmBootOrder + BOOT_ORDER_OFFSET);
+ SavedBootXXX = (RESTORE_BOOTORDER*)gSmmBootOrder;
+ BootOrderSize = 0;
+ // Get BootOrderSize Variable size if exist.
+ Status = pRS->GetVariable(L"BootOrder",&EfiVariableGuid,NULL,&BootOrderSize, NULL);
+ if(Status != EFI_NOT_FOUND)
+ {
+ Status = pRS->GetVariable( L"BootOrder", &EfiVariableGuid, \
+ NULL, &BootOrderSize, BootOrder);
+ // if BootOreder found, update nothing.
+ if(!EFI_ERROR(Status))
+ {
+ // Free BootOrder buffer in SMM.
+ pSmst->SmmFreePages (gSmmBootOrder, RESTORE_BOOT_ORDER_BUFFER >> 12);
+ // Re-initial global variable.
+ gSmmBootOrder = NULL;
+ gNumBootDevice = 0;
+ return;
+ }
+ }
+
+ for(i = 0 ; i < gNumBootDevice; i++)
+ {
+ // Restore BootXXXX
+ Status = pRS->SetVariable ( \
+ SavedBootXXX->BootVarName, \
+ &EfiVariableGuid, \
+ EFI_VARIABLE_NON_VOLATILE | \
+ EFI_VARIABLE_RUNTIME_ACCESS | \
+ EFI_VARIABLE_BOOTSERVICE_ACCESS, \
+ SavedBootXXX->BootXXXXSize, \
+ (UINT8*)SavedBootXXX + sizeof(RESTORE_BOOTORDER));
+ BootOrder[i] = SavedBootXXX->BootOrderNO;
+ // Ptr to next "BootXXXX" buffer.
+ (UINT8*)SavedBootXXX += (SavedBootXXX->BootXXXXSize + sizeof(RESTORE_BOOTORDER));
+ }
+ // Restore "BootOrder"
+ pRS->SetVariable ( L"BootOrder",
+ &EfiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ (sizeof(UINT16) * i),
+ BootOrder );
+
+ // Enable the Nvram Full Access control for processing the "LegacyDevOrder".
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE);
+ // Restore "LegacyDevOrder"
+ BootOrder = (UINT16*)(gSmmBootOrder + LEGACY_BOOT_ORDER_OFFSET);
+ BootOrderSize = *(UINT32*)BootOrder;
+ if (BootOrderSize != 0) pRS->SetVariable (L"LegacyDevOrder", \
+ &LegacyDevOrderGuid, \
+ *(UINT32*)((UINT8*)BootOrder + sizeof(UINT32)), \
+ BootOrderSize, \
+ (UINT8*)BootOrder + (sizeof(UINT32) * 2));
+ // Disable the Nvram Full Access control after processing the "LegacyDevOrder".
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE);
+
+ // Free BootOrder buffer in SMM.
+ pSmst->SmmFreePages (gSmmBootOrder, RESTORE_BOOT_ORDER_BUFFER >> 12);
+ // Re-initial global variable.
+ gSmmBootOrder = NULL;
+ gNumBootDevice = 0;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PreserveSetupPassword
+//
+// Description: Save the Setup Password
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PreserveSetupPassword(VOID)
+{
+ UINTN VariableSize;
+ EFI_STATUS Status;
+
+ // Due to the "RT" attribute could be removed from "AMITSESetup" variable,
+ // here to enable Nvram Full Access control for getting variable with "NV+BS" only.
+ if (gNvramControl == NULL) gNvramControl = LocateNvramControlSmmProtocol();
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE);
+
+ VariableSize = sizeof(AMITSESETUP);
+ Status = pRS->GetVariable ( L"AMITSESetup", \
+ &gAmiTseSetupGuid, \
+ &gAmiTseDataAttr, \
+ &VariableSize, \
+ &gAmiTseData );
+
+ if (EFI_ERROR(Status)) gAmiTseDataAttr = 0;
+
+ // Disable the Nvram Full Access control after processing the "AMITSESetup".
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: RestoreSetupPassword
+//
+// Description: Restore previous Password
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreSetupPassword (VOID)
+{
+ UINTN VariableSize = 0;
+ EFI_STATUS Status;
+ AMITSESETUP TempAmiTseData;
+
+ pRS->GetVariable ( L"AMITSESetup", \
+ &gAmiTseSetupGuid, \
+ NULL, \
+ &VariableSize, \
+ &gAmiTseData );
+
+ //
+ // Check the length of new AMITSESETUP stucture and old AMITSESETUP
+ //
+ if(VariableSize != sizeof(AMITSESETUP)) {
+ //
+ // Sturcture changed, Don't Restore !!
+ //
+ return;
+ }
+
+ if (gAmiTseDataAttr == 0) return;
+ //
+ // Check Nvram is updated or not. If updated, restore only the password.
+ // SilentBoot value will be restored to default value.
+ //
+ VariableSize = sizeof(AMITSESETUP);
+ Status = pRS->GetVariable ( L"AMITSESetup", \
+ &gAmiTseSetupGuid, \
+ NULL, \
+ &VariableSize, \
+ &TempAmiTseData );
+
+ if(Status == EFI_SUCCESS) {
+ //
+ // If the nvram is not modified exit without restoring the AMITSESETUP nvram variable.
+ //
+ if (!MemCmp(&TempAmiTseData, &gAmiTseData, sizeof(AMITSESETUP))){
+ return;
+ }
+ }
+ // Enable the Nvram Full Access control for processing the "AMITSESetup".
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE);
+ gAmiTseData.AMISilentBoot= DEFAULT_QUIET_BOOT;
+ VariableSize = sizeof(AMITSESETUP);
+ pRS->SetVariable ( L"AMITSESetup", \
+ &gAmiTseSetupGuid, \
+ gAmiTseDataAttr, \
+ VariableSize, \
+ &gAmiTseData );
+ // Disable the Nvram Full Access control after processing the "AMITSESetup".
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: DisablePowerButton
+//
+// Description: Disable Power Button when AFU.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DisablePowerButton(VOID)
+{
+ // Disable PWR Button SMI
+ IoWrite16(PM_BASE_ADDRESS + 0x02, IoRead16(PM_BASE_ADDRESS + 0x02) & 0xFEDF);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: EnablePowerButton
+//
+// Description: Re-Enable PowerButton after flash BIOS
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EnablePowerButton (VOID)
+{
+ //Clear All PM Statuses
+ IoWrite16(PM_BASE_ADDRESS,IoRead16(PM_BASE_ADDRESS));
+ // Re-ensable PWR Button SMI
+ IoWrite16(PM_BASE_ADDRESS + 0x02, BIT05 + BIT08);
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: DisableUSBKBD
+//
+// Description: Disable USB Keyboard when flashing BIOS.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DisableUSBKBD(VOID)
+{
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+ EFI_GUID EfiVariableGuid = AMITSESETUP_GUID;
+ UINTN VariableSize = sizeof(VOID*);
+ EFI_STATUS Status;
+
+ Status = pRS->GetVariable ( L"USB_POINT",
+ &EfiVariableGuid,
+ NULL,
+ &VariableSize,
+ &gUsbRtKbcAccessControl);
+ if(!EFI_ERROR(Status) && (gUsbRtKbcAccessControl != NULL))
+ gUsbRtKbcAccessControl(1);
+#endif
+#endif
+
+ // Disable KBC.
+ if (0xff != IoRead8(0x60)) {
+ IoWrite8(0x64, 0xad);
+ IoWrite8(0x21, IoRead8(0x21) | 0x2);
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: EnableUSBKBD
+//
+// Description: Re-Enable USB KeyBoard after flashing BIOS
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID EnableUSBKBD (VOID)
+{
+ // Enable KBC.
+ if (0xff != IoRead8(0x60)) {
+ IoWrite8(0x64, 0xae);
+ IoWrite8(0x21, IoRead8(0x21) & 0xfd);
+ }
+
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+ if (gUsbRtKbcAccessControl != NULL)
+ gUsbRtKbcAccessControl(0);
+#endif
+#endif
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetUsbProtocol
+//
+// Description: This hook gets USB Protocol for disabling USB while flashing.
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+GetUsbProtocolPoint(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+ EFI_GUID EfiVariableGuid = AMITSESETUP_GUID;
+ EFI_USB_PROTOCOL *AmiUsb = NULL;
+
+ pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &AmiUsb);
+ pRS->SetVariable ( L"USB_POINT",
+ &EfiVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(VOID*),
+ (VOID*)&AmiUsb->UsbRtKbcAccessControl );
+#endif
+#endif
+ return;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetUsbControl
+//
+// Description: This hook gets USB Protocol's function
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetUsbControl(
+ CONST EFI_GUID *Protocol,
+ VOID *Interface,
+ EFI_HANDLE Handle
+)
+{
+ GetUsbProtocolPoint( NULL, NULL );
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: USBInSmmFunction
+//
+// Description: Notify for USB smm Protocol
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBInSmmFunction(
+ VOID
+)
+{
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *AmiUsb = NULL;
+ EFI_GUID EfiVariableGuid = AMITSESETUP_GUID;
+ EFI_GUID AmiUsbSmmProtocolGuid = AMI_USB_SMM_PROTOCOL_GUID;
+
+ Status = pSmst->SmmLocateProtocol(
+ &AmiUsbSmmProtocolGuid,
+ NULL,
+ &AmiUsb );
+ if( EFI_ERROR(Status) )
+ {
+ VOID *NotifyReg;
+
+ Status = pSmst->SmmRegisterProtocolNotify(
+ &AmiUsbSmmProtocolGuid,
+ GetUsbControl,
+ &NotifyReg );
+ }
+ else
+ {
+ GetUsbProtocolPoint( NULL, NULL );
+ }
+
+ return;
+#else
+ return;
+#endif
+#else
+ return;
+#endif
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: USBNonSmmFunction
+//
+// Description: Find USB Protocol pointer
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBNonSmmFunction(
+ VOID
+)
+{
+#if AMIUSB_SUPPORT == 1
+#if (((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *AmiUsb = NULL;
+ EFI_GUID EfiVariableGuid = AMITSESETUP_GUID;
+
+ Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &AmiUsb);
+ if(EFI_ERROR(Status))
+ {
+ EFI_EVENT SmiFlashEvt;
+ VOID *NotifyReg;
+
+ Status = pBS->CreateEvent (
+ EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ GetUsbProtocolPoint,
+ NULL,
+ &SmiFlashEvt
+ );
+
+ if (!EFI_ERROR (Status)) {
+ Status = pBS->RegisterProtocolNotify (
+ &gEfiUsbProtocolGuid,
+ SmiFlashEvt,
+ &NotifyReg);
+ }
+ }else
+ pRS->SetVariable ( L"USB_POINT",
+ &EfiVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(VOID*),
+ (VOID*)&AmiUsb->UsbRtKbcAccessControl );
+
+ return;
+#else
+ return;
+#endif //(((USB_DRIVER_MAJOR_VER*100 ) + (USB_DRIVER_MINOR_VER*10) + (USB_DRIVER_BUILD_VER)) >= 891)
+#else
+ return;
+#endif //AMIUSB_SUPPORT
+}
+#if AFU_BUFFER_IN_SHADOW
+#include <AmiCspLib.h>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: UpdateShadowBuffer
+//
+// Description: This hook enables shadow write for updating buffer pointer
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateShadowBuffer(
+ IN UINT8 Data,
+ IN OUT UINT64 pCommBuff
+)
+{
+ UINT8 FixLen;
+ static UINT8* Buffer = 0;
+ UINT32 LowBufferAddress, HighBufferAddress;
+
+ if(Data == SMIFLASH_ENABLE_FLASH)
+ OemRuntimeShadowRamWrite(TRUE);
+ else
+ {
+ if((UINTN)Buffer == 0)
+ {
+ Buffer = (UINT8*)0xF0000;
+ for(;*(UINT32*)Buffer != 0x46534124 &&
+ ((UINTN)Buffer < 0x100000);(UINTN)Buffer++);
+ }
+
+ if((UINTN)Buffer == 0xFFFFF)
+ return;
+ // Skip Sig
+ FixLen = *(Buffer + 4);
+
+ if(*(UINT32*)(Buffer + FixLen) == 0 ||
+ *(UINT32*)(Buffer + FixLen) == 0xFFFFFFFF)
+ return;
+
+ LowBufferAddress = *(UINT32*)(Buffer + FixLen);
+ HighBufferAddress = 0;
+ pCommBuff = HighBufferAddress;
+ pCommBuff = Shl64(pCommBuff, 32);
+ pCommBuff += LowBufferAddress;
+ }
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: ClearShadowBuffer
+//
+// Description: Elink for Disable shadow and clear buffer pointer
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ClearShadowBuffer (
+ IN UINT8 Data,
+ IN OUT UINT64 pCommBuff
+)
+{
+ UINT8 FixLen;
+ static UINT8* Buffer = 0;
+
+ if(Data == SMIFLASH_DISABLE_FLASH)
+ OemRuntimeShadowRamWrite(FALSE);
+ else
+ {
+ if((UINTN)Buffer == 0)
+ {
+ Buffer = (UINT8*)0xF0000;
+ for(;*(UINT32*)Buffer != 0x46534124 &&
+ ((UINTN)Buffer < 0x100000);(UINTN)Buffer++);
+
+ }
+ if((UINTN)Buffer == 0xFFFFF)
+ return;
+
+ // Skip Sig
+ FixLen = *(Buffer + 4);
+ // Clear Buffer address
+ *(UINT32*)(Buffer + FixLen) = 0;
+ }
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: FindFfsFileByGuid
+//
+// Description: This hooks finds FFS file by GUID.
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+FindFfsFileByGuid (
+ IN UINT8 *pFV,
+ IN UINT32 FvLength,
+ IN EFI_GUID *pGuid
+)
+{
+ EFI_FFS_FILE_HEADER *pFfsFile;
+ UINT32 Length, FileSize;
+
+ if ((((EFI_FIRMWARE_VOLUME_HEADER*)pFV)->Signature != FV_SIGNATURE) || \
+ (((EFI_FIRMWARE_VOLUME_HEADER*)pFV)->FvLength != (UINT64)FvLength))
+ return FALSE;
+ Length = ((EFI_FIRMWARE_VOLUME_HEADER*)pFV)->HeaderLength;
+ pFfsFile = (EFI_FFS_FILE_HEADER*)((UINT32)pFV + Length);
+ FileSize = *(UINT32 *)pFfsFile->Size & 0x00FFFFFF;
+ do {
+ if (!MemCmp ((UINT8*)pFfsFile, pGuid ,sizeof(EFI_GUID)))
+ return (UINT32)pFfsFile;
+ FileSize = *(UINT32 *)pFfsFile->Size & 0x00FFFFFF;
+ pFfsFile = (EFI_FFS_FILE_HEADER*)((UINT32)pFfsFile + FileSize);
+ pFfsFile = (EFI_FFS_FILE_HEADER*)(((UINT32)pFfsFile + 7) & 0xfffffff8);
+ if ((UINT32)((UINT8*)pFfsFile - pFV) >= FvLength) break;
+ } while(((*(UINT32 *)pFfsFile->Size & 0x00FFFFFF) != 0xFFFFFF) && \
+ ((*(UINT32 *)pFfsFile->Size & 0x00FFFFFF) != 0));
+ return FALSE;
+}
+#if defined SecSMIFlash_SUPPORT && SecSMIFlash_SUPPORT == 1
+#include <FlashUpd.h>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PreserveRomHole
+//
+// Description: This hook preserves ROM Holes while flashing.
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RecoveryPreserveRomHoles(VOID) {
+ EFI_GUID RomLayoutGuid = ROM_LAYOUT_FFS_GUID;
+ ROM_AREA *RomArea;
+ UINT32 FfsFile = 0, RomHoleFfs1, RomHoleFfs2, RomHoleSize;
+ EFI_GUID HobListGuid = HOB_LIST_GUID;
+ EFI_STATUS Status;
+ RECOVERY_IMAGE_HOB *RecoveryHob;
+ EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID;
+ AMI_FLASH_UPDATE_BLOCK FlashUpdDesc;
+ UINTN Size, Attributes;
+ UINT8 *Fv;
+ EFI_GUID *pGuid = NULL;
+
+ RecoveryHob = GetEfiConfigurationTable(pST, &HobListGuid);
+ if ((RecoveryHob == NULL) || \
+ (((EFI_HOB_HANDOFF_INFO_TABLE*)RecoveryHob)->BootMode != \
+ BOOT_ON_FLASH_UPDATE)) return;
+ // Due to AFU 3.03 have support to preserve Romholes if capsule mode,
+ // SMIFlash only preserve Romholes if Recovery mode of Secure Update.
+ Status = pRS->GetVariable(FLASH_UPDATE_VAR, \
+ &FlashUpdGuid, (UINT32*)&Attributes, &Size, &FlashUpdDesc);
+ if (EFI_ERROR(Status) || (FlashUpdDesc.FlashOpType != FlRecovery)) return;
+
+ Status = FindNextHobByGuid(&RecoveryHobGuid, &RecoveryHob);
+ if (EFI_ERROR(Status)) return;
+ // Search Romlayout in ROM
+ for(Fv = (UINT8*)(0xffffffff - FLASH_SIZE + 1);
+ ((Fv < (UINT8*)0xffffffff) && (FfsFile == 0));
+ FfsFile = FindFfsFileByGuid (Fv,
+ (UINT32)(((EFI_FIRMWARE_VOLUME_HEADER*)Fv)->FvLength), &RomLayoutGuid),
+ Fv = Fv+16 );
+
+ if(FfsFile == 0) return;
+ for(pGuid = RecoveryPreserveGUID; pGuid->Data1 != 0; pGuid++) {
+ // Search in ROM File
+ RomHoleFfs1 = 0;
+ for (RomArea = (ROM_AREA*)(FfsFile + 0x2c); RomArea->Size != 0; RomArea++)
+ {
+ if (RomArea->Type != RomAreaTypeFv) continue;
+ RomHoleFfs1 = FindFfsFileByGuid ((UINT8*)RomArea->Address, \
+ RomArea->Size, \
+ pGuid);
+ if(RomHoleFfs1 != 0)
+ break;
+ }
+ // if not found, search next.
+ if (RomHoleFfs1 == 0) continue;
+
+ // Search in Recovery File
+ RomHoleFfs2 = 0;
+ for (RomArea = RomLayout; RomArea->Size != 0; RomArea++)
+ {
+
+ if (RomArea->Type != RomAreaTypeFv) continue;
+ RomHoleFfs2 = FindFfsFileByGuid ( \
+ (UINT8*)(RecoveryHob->Address + RomArea->Offset), \
+ RomArea->Size, \
+ pGuid);
+ if(RomHoleFfs2 != 0)
+ break;
+ }
+ // FFS found in ROM and Recovery File
+ if (RomHoleFfs2 != 0)
+ {
+ RomHoleSize = *(UINT32*)(RomHoleFfs1 + 0x14) & 0xFFFFFF;
+ if ((RomHoleSize == (*(UINT32*)(RomHoleFfs2 + 0x14) & 0xFFFFFF)) && \
+ MemCmp((UINT8*)(RomHoleFfs1 + sizeof(EFI_FFS_FILE_HEADER)), \
+ (UINT8*)(RomHoleFfs2 + sizeof(EFI_FFS_FILE_HEADER)), \
+ RomHoleSize - sizeof(EFI_FFS_FILE_HEADER))) {
+ pBS->CopyMem((UINT8*)(RomHoleFfs2 + sizeof(EFI_FFS_FILE_HEADER)), \
+ (UINT8*)(RomHoleFfs1 + sizeof(EFI_FFS_FILE_HEADER)), \
+ RomHoleSize - sizeof(EFI_FFS_FILE_HEADER));
+ }
+ }
+ }
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PreserveWin8Variables
+//
+// Description: Preserve all variables that GUID is {77fa9abd-0359-4d32-bd60-28f4e78f784b}.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PreserveWin8Variables(VOID)
+{
+ UINTN VarNameSize = 2;
+ CHAR16 *VarName = NULL;
+ CHAR16 *OldVarName = NULL;
+ EFI_GUID VarGuid;
+ UINTN VariableSize;
+ UINT8 *VariableData;
+ EFI_STATUS Status;
+ RESTORE_VAR *pRestoreVarList;
+ UINT8 *pData;
+ UINT32 VariableAttr;
+
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ VarNameSize, &VarName
+ );
+
+ if(EFI_ERROR(Status))
+ return;
+
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof(RESTORE_VAR), &RestoreVarList);
+
+ if(EFI_ERROR(Status))
+ {
+ RestoreVarList = NULL;
+ return;
+ }
+ gNvramControl = LocateNvramControlSmmProtocol();
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE);
+ pRestoreVarList = RestoreVarList;
+
+ // Init Variable List
+ pRestoreVarList->NextData = 0;
+
+ // Get frist variable
+ VarName[0] = NULL;
+ do{
+ if(VarNameSize != 0)
+ Status = pRS->GetNextVariableName (&VarNameSize,
+ VarName, &VarGuid);
+ else
+ Status = EFI_BUFFER_TOO_SMALL;
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ // If VarNameSize is 0, VarName is not existed.
+ if(VarNameSize != 0)
+ {
+ // Keep the old variable name for next search
+ OldVarName = VarName;
+ }
+
+ // Avoid dead loop
+ VarNameSize = DefaultVariableSize;
+
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ VarNameSize, &VarName);
+
+ if(EFI_ERROR(Status))
+ return;
+
+ MemCpy(VarName, OldVarName, VarNameSize);
+
+ continue;
+ }
+
+
+ if(!EFI_ERROR(Status))
+ {
+ if(guidcmp(&VarGuid, &gWin8Guid))
+ {
+ // Make sure every time, it gets a buffer too small,
+ // don't waste this buffer
+ VarNameSize = DefaultVariableSize;
+ continue;
+ }
+
+ VariableSize = 0;
+ Status = pRS->GetVariable(VarName, &gWin8Guid,
+ NULL, &VariableSize, NULL);
+
+ if(Status != EFI_BUFFER_TOO_SMALL)
+ continue;
+
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ VariableSize, &VariableData);
+
+ if(EFI_ERROR(Status))
+ continue;
+
+ Status = pRS->GetVariable(VarName, &gWin8Guid,
+ &VariableAttr, &VariableSize, VariableData);
+
+ if(EFI_ERROR(Status))
+ {
+ pSmst->SmmFreePool(VariableData);
+ continue;
+ }
+ // Store variable in Link list
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof(RESTORE_VAR), &pData);
+
+ if(EFI_ERROR(Status))
+ continue;
+ Status = pSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ VarNameSize, &OldVarName);
+
+ if(EFI_ERROR(Status))
+ continue;
+
+ MemCpy(OldVarName, VarName, VarNameSize);
+ // Free the bigger Varname
+ pSmst->SmmFreePool(VarName);
+
+
+ pRestoreVarList->rVar.BootVarName = OldVarName;
+ pRestoreVarList->rVar.Guid = &gWin8Guid;
+ pRestoreVarList->rATTR.Attrib = VariableAttr;
+ pRestoreVarList->rATTR.Size = VariableSize;
+ pRestoreVarList->rATTR.Data = VariableData;
+ pRestoreVarList->NextData = (UINTN)pData;
+
+ (UINT8*)pRestoreVarList = pData;
+ pRestoreVarList->NextData = 0;
+ // Make sure every time, it gets a buffer too small,
+ // make it allocate new buffer for name
+ VarNameSize = 0;
+ }
+
+ }while(Status != EFI_NOT_FOUND);
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE);
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------
+// Procedure: RestoreWin8Variables
+//
+// Description: Restore all variables that GUID is {77fa9abd-0359-4d32-bd60-28f4e78f784b}.
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreWin8Variables (VOID)
+{
+ RESTORE_VAR *pRestoreVarList = RestoreVarList, *TempPoint;
+ EFI_STATUS Status;
+
+ if(RestoreVarList == NULL)
+ return;
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(TRUE);
+ for( ; pRestoreVarList->NextData != 0 ; )
+ {
+ Status = pRS->SetVariable ( pRestoreVarList->rVar.BootVarName,
+ pRestoreVarList->rVar.Guid,
+ pRestoreVarList->rATTR.Attrib,
+ pRestoreVarList->rATTR.Size,
+ pRestoreVarList->rATTR.Data );
+
+ (UINTN)TempPoint = pRestoreVarList->NextData;
+
+ pSmst->SmmFreePool(pRestoreVarList->rVar.BootVarName);
+ pSmst->SmmFreePool(pRestoreVarList->rATTR.Data);
+ pSmst->SmmFreePool(pRestoreVarList);
+ pRestoreVarList = TempPoint;
+ }
+ if (gNvramControl) gNvramControl->ShowBootTimeVariables(FALSE);
+ RestoreVarList = NULL;
+}
+#else // #if defined _OUTSIDE_SMM_
+//*********** OUTSIDE SMM ***********************************************
+#if defined RECOVERY_PRESERVE_VARS_IN_SMM && RECOVERY_PRESERVE_VARS_IN_SMM == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: mSMIFlashSmi
+//
+// Description: mSMIFlashSmi structure for generating SW SMI call.
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static UINT8 mSMIFlashSmi[] = {
+ 0x50, // push eax
+ 0x53, // push ebx
+ 0x51, // push ecx
+ 0x52, // push edx
+ 0xBA, SW_SMI_IO_ADDRESS, 0, 0, 0, // mov edx, SW_SMI_IO_ADDRESS
+ 0xB8, 0x00, 0x00, 0x00, 0x00, // mov eax, 0 //SW SMI value
+ 0xBB, 0x00, 0x00, 0x00, 0x00, // mov ebx, 0 //LowBufferAddress
+ 0xB9, 0x00, 0x00, 0x00, 0x00, // mov ecx, 0 //HighBufferAddress
+ 0xEE, // out dx, al
+ 0x5A, // pop edx
+ 0x59, // pop ecx
+ 0x5B, // pop ebx
+ 0x58, // pop eax
+ 0xC3, // ret
+};//mSMIFlashSmi[]
+
+FUNC_BLOCK FuncBlock = {0,0,0,0};
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: RecoveryHookBeforeFlash
+//
+// Description: This hook preserves variables in SMM while reflash update.
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RecoveryHookBeforeFlash (VOID)
+{
+ void (*IssueSWSMI)(void);
+ *(UINT8*)&mSMIFlashSmi[10] = SMIFLASH_ENABLE_FLASH; //EAX
+ *(UINT32*)&mSMIFlashSmi[15] = (UINT32)&FuncBlock; //EBX
+ IssueSWSMI = (void*)mSMIFlashSmi;
+ IssueSWSMI();
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ // For following DeviceWriteEnable call of reflash.c.
+ Flash->DeviceWriteDisable();
+#endif
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: RecoveryHookAfterFlash
+//
+// Description: This hook restores variables from SMM after reflash update.
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RecoveryHookAfterFlash (VOID)
+{
+ void (*IssueSWSMI)(void);
+
+#if EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT
+ // For following DeviceWriteDisable call of smiflash func#24.
+ Flash->DeviceWriteEnable();
+#endif
+ *(UINT8*)&mSMIFlashSmi[10] = SMIFLASH_DISABLE_FLASH;//EAX
+ *(UINT32*)&mSMIFlashSmi[15] = (UINT32)&FuncBlock; //EBX
+ IssueSWSMI = (void*)mSMIFlashSmi;
+ IssueSWSMI();
+}
+#endif // if defined RECOVERY_PRESERVE_IN_SMM && RECOVERY_PRESERVE_IN_SMM == 1
+#endif // if defined _OUTSIDE_SMM_
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SMM/SMM.cif b/Core/EM/SMM/SMM.cif
new file mode 100644
index 0000000..2a6a922
--- /dev/null
+++ b/Core/EM/SMM/SMM.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "SMM"
+ category = eModule
+ LocalRoot = "Core\EM\SMM"
+ RefName = "SMM"
+[files]
+"SMM.sdl"
+"SmmPrivateShared.h"
+"SmmHdr.equ"
+"Smm.chm"
+[parts]
+"SmmDispatcher"
+"SmmBase"
+"SmmCommunicate"
+"SmmProtocols"
+"SmmPiIncludes"
+"SmmPiProtocols"
+"PowerButton"
+<endComponent>
diff --git a/Core/EM/SMM/SMM.sdl b/Core/EM/SMM/SMM.sdl
new file mode 100644
index 0000000..2923eaa
--- /dev/null
+++ b/Core/EM/SMM/SMM.sdl
@@ -0,0 +1,101 @@
+TOKEN
+ Name = "SMM_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SMM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SMM_MAJOR_VER"
+ Value = "00"
+ Help = "SMM Major Version Number. Do not change"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "SMM_MINOR_VER"
+ Value = "0x46"
+ Help = "SMM Minor Version Number. Do not change"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "SMM_PAGING_MAX_ADDRESS_LINES"
+ Value = "32"
+ Help = "For x64, maximum number of address lines to page.\Each additional line doubles the page table size."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SMM_CACHE_SUPPORT"
+ Value = "1"
+ Help = "Enable/disable SMM Cache Support"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SMM_THUNK_NO_AB_SEG"
+ Value = "1"
+ Help = "Enable/disable using A & B segment for SMM Thunk.\Some CPUs don't provide support for SMM THUNK in A&B segment."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SMM_THUNK_IN_CSM"
+ Value = "0"
+ Help = "Enable/disable SMM Thunk in CSM"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SMM_TIME_OUT_US"
+ Value = "1000"
+ Help = "uS Timeout waiting for BSP and APs to sync."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BSP_SMM_STACK_SIZE"
+ Value = "16384"
+ Help = "Must be 4k byte alligned."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AP_SMM_STACK_SIZE"
+ Value = "16384"
+ Help = "Must be 4k byte alligned."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INTEL_MP_SW_SMI_PATCH"
+ Value = "0"
+ Help = "INTEL drivers always read Save State Copy 0.\When this is enabled, an AP generated sw smi will\appear as CPU 0.\Further, Save State Copies of other CPUs may be invalid."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
diff --git a/Core/EM/SMM/Smm.chm b/Core/EM/SMM/Smm.chm
new file mode 100644
index 0000000..dd76d80
--- /dev/null
+++ b/Core/EM/SMM/Smm.chm
Binary files differ
diff --git a/Core/EM/SMM/SmmBase.c b/Core/EM/SMM/SmmBase.c
new file mode 100644
index 0000000..219e405
--- /dev/null
+++ b/Core/EM/SMM/SmmBase.c
@@ -0,0 +1,911 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase.c 73 2/13/12 4:41p Markw $
+//
+// $Revision: 73 $
+//
+// $Date: 2/13/12 4:41p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase.c $
+//
+// 73 2/13/12 4:41p Markw
+// [TAG] EIP83005
+// [Category] Improvement
+// [Description] Some framework based SMM libraries expect a DXE image
+// handle on input. However, PI 1.1 SMM drivers expect a SMM handle on
+// input.
+// Update code to provide proper EFI_HANDLE when calling SMM functions.
+// [Files] SmmBase.c, SmmDriverDispatcher.c
+//
+// 72 8/25/11 10:29a Markw
+// [TAG] EIP64115
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PI 1.1 - unable to install protocol on image handle.
+// [RootCause] Image handle is created by AMI code, but protocol handles
+// are created by Intel code.
+// [Solution] Create a new dummy handle from Intel's code and use that a
+// the image handle in the entry point.
+// [Files] SmmBase.c
+//
+// 71 2/07/11 3:35p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+// 70 12/28/09 11:07a Markw
+// EIP #32378 - Use SDL token to determine how much memory to page to be
+// able to page above 4GB.
+//
+// 69 11/23/09 11:04a Markw
+// Add back SMM Communicate function. Smm runtime module needed this.
+//
+// 68 11/05/09 4:31p Markw
+// SMM Base functions pre-initalize Status to EFI_DEVICE_ERROR in case sw
+// smi doesn't happen.
+//
+// 67 10/13/09 3:42p Markw
+// EIP #27823 - Fix allocating SMM driver below 1MB if out of SMM memory.
+//
+// 66 8/11/09 11:47a Markw
+// Removed Legacy registration. This is removed from latest PI and not
+// used by projects.
+//
+// 65 8/05/09 2:59p Markw
+// When functions aren't available in BDS for SMM security, return proper
+// error of EFI_UNSUPPORTED.
+//
+// 64 7/17/09 4:19p Markw
+// Added back changes 60 and 61.
+//
+// 63 7/16/09 8:12p Markw
+// EIP #24284 - Correct order SmmCpuInfo structure. It's was ordered
+// incorrectly the same as CpuInfo. Thus, the wrong APIC ID could be used
+// when starting unstarted APs if the BSP was changed.
+//
+// 62 7/08/09 8:03p Markw
+// Update headers.
+//
+// 61 6/25/09 4:15p Markw
+// Move setting gDispatcherPrivate->SmrrEnable outside condition.
+//
+// 60 6/10/09 3:17p Markw
+// Remove extra freepool.
+//
+// 59 1/26/09 5:29p Markw
+// EIP 14800: Aptio 4.x SMI Code vulnerablity. Disable call back inside
+// SMM before BDS can launch option roms.
+//
+// 58 1/22/09 1:07p Markw
+// EIP #18671 (OPEN) Clear SW SMI status and set EOS inside SMM. Move
+// Clear from Base function.
+//
+// 57 12/24/08 10:55a Markw
+// EIP #18423: Adjust EBDA location as more EBDA data is allocated.
+//
+// 56 12/23/08 2:19p Markw
+// EIP #17900 Set up TSS. Borland C in DOS hangs otherwise.
+//
+// 55 11/21/08 5:02p Markw
+// Use 32-bit CPU Count.
+//
+// 54 10/06/08 6:27p Markw
+// Add generic Smm Memory libary hook.
+//
+// 53 9/26/08 4:51p Markw
+// InSmm is now a runtime function.
+//
+// 52 9/15/08 4:00p Markw
+// Initialize HandlerListHead and FloatingPointSave in Dispatcher Private
+// structure.
+//
+// 51 9/09/08 3:06p Markw
+// Align Dispatcher to 4k.
+//
+// 50 9/07/08 12:47a Markw
+// Separate SMM Private structure into inside SMM and outside SMM
+// structure.
+//
+// 49 8/27/08 9:07p Markw
+// Nehalem SMRR is not WB. Fix VIA not supporting cpuid 0x80000008.
+//
+// 47 6/10/08 6:46p Markw
+// Disable SMM Thunk if no A & B seg, and no CSM.
+//
+// 46 6/10/08 1:30p Markw
+// Update gdt for Smm Thunk for APs.
+//
+// 45 6/09/08 5:42p Markw
+// Provide support for any CPU to be BSP by providing APIC for each CPU
+// and allowing CPU 0 to have a structure for controlling as an Ap.
+//
+// 44 5/23/08 5:28p Markw
+// Undo change from previous revision to lock smm before os with AMI
+// debugger.
+//
+// 43 5/23/08 12:25p Markw
+// Disallow registering now disallows all callbacks.
+//
+// 42 4/04/08 6:23p Markw
+// Change SMM base here instead of CPU module.
+//
+// 41 3/18/08 4:59p Markw
+// Change 64-bit pages to have the first 2MB as 4k pages. This is so
+// different MTRR types will not overlap a page.
+//
+// 40 3/11/08 12:46p Markw
+//
+// 39 3/04/08 9:01a Markw
+// Updated EBDA allocation for SMM THUNK to use the changed protocol from
+// 4.5.3_CSM.6.43_56.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmBase.c
+//
+// Description: Provide functions to register drivers with SMM,
+// determine if driver is in SMM Mode, register call backs,
+// provide callback buffer, return SMST table pointer,
+// and allocate memory.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//This include should be first.
+#include "SmmPrivateShared.h"
+
+#include <Protocol\LoadPe32Image.h>
+#include <Protocol\LoadedImage.h>
+#include <token.h>
+#include <Ffs.h>
+#include <AmiDxeLib.h>
+
+#if SMM_USE_FRAMEWORK
+#include <Smm.h>
+#include <Protocol\SmmBase.h>
+#endif
+
+#if SMM_USE_PI
+#include <SmmPi.h>
+#include <Protocol\SmmReadyToLock.h>
+#endif
+
+UINT8 gDisallowCallbacks = FALSE;
+BOOLEAN gRegisterForPi = FALSE;
+
+VOID SmmRegisterHandler();
+
+#if SMM_USE_FRAMEWORK
+VOID SmmUnregisterHandler();
+VOID SmmCommunicate();
+VOID SmmAllocatePool();
+VOID SmmFreePool();
+
+extern EFI_SMM_SYSTEM_TABLE *gSmstTable;
+#endif
+
+#if SMM_USE_PI
+extern EFI_SMM_SYSTEM_TABLE2 *gSmstTable2;
+#endif
+
+extern EFI_HANDLE gThisImageHandle;
+extern SMM_BASE_PRIVATE_STRUCT *gBasePrivate;
+extern EFI_PE32_IMAGE_PROTOCOL *gPe32Image;
+extern SMM_DISPATCHER_PRIVATE_STRUCT *gDispatcherPrivate;
+
+EFI_GUID gEfiLoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+
+
+#if SMM_USE_PI
+//EFI_GUID gEfiSmmReadyToLockProtocolGuid = EFI_SMM_READY_TO_LOCK_PROTOCOL_GUID;
+EFI_GUID gSmmImageHandleDummyGuid = {0x33aa4ba3, 0x5439, 0x4658, 0x89, 0x51, 0xe2, 0xe7, 0xea, 0xf8, 0x1c, 0x49};
+#endif
+
+VOID CallFuncInSmm(IN VOID func());
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SetDisallowRegistering
+//
+// Description: Don't allow registering handlers from SMM.
+//
+// Input: VOID
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SetDisallowRegistering()
+{
+#if SMM_USE_PI
+ EFI_HANDLE Handle = NULL;
+#endif
+
+ //Dispatcher has a private variable, is set after this.
+ //Thus, once DisallowCallbacks is set, it can not be unset.
+ gBasePrivate->DisallowCallbacks = TRUE;
+ gDisallowCallbacks = TRUE;
+
+#if SMM_USE_PI
+ gSmstTable2->SmmInstallProtocolInterface(
+ &Handle,
+ &gEfiSmmReadyToLockProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmRegister
+//
+// Description: Register a driver with the SMM Handler.
+// * Loads SMM PE32 Driver into SMM memory and give control to the entry point.
+// * Or, loads SMM 16-bit driver into SMM memory. It is given control during SMM mode.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+// IN VOID *SourceBuffer OPTIONAL
+// IN UINTN SourceSize
+// OUT EFI_HANDLE *ImageHandle
+// IN BOOLEAN LegacyIA32Binary OPTIONAL
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Driver was registered.
+// * EFI_OUT_OF_RESOURCES - No additional resources to load handler.
+// * EFI_INVALID_PARAMETER - Invalid inputs.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmRegister(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle,
+ IN BOOLEAN LegacyIA32Binary OPTIONAL
+ )
+{
+
+ if (gDisallowCallbacks) return EFI_UNSUPPORTED;
+ if (LegacyIA32Binary) return EFI_UNSUPPORTED;
+
+ gBasePrivate->CallbackParameters.RegisterHandler.FilePath = FilePath;
+ gBasePrivate->CallbackParameters.RegisterHandler.SourceBuffer = SourceBuffer;
+ gBasePrivate->CallbackParameters.RegisterHandler.SourceSize = SourceSize;
+ gBasePrivate->CallbackParameters.RegisterHandler.ImageHandle = ImageHandle;
+ gBasePrivate->CallbackParameters.RegisterHandler.LegacyIA32Binary = FALSE;
+ gBasePrivate->CallbackStatus = EFI_DEVICE_ERROR; //Pre-init - SW SMI didn't happen.
+
+ CallFuncInSmm(SmmRegisterHandler);
+
+ return gBasePrivate->CallbackStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmRegisterHandler
+//
+// Description: Does the actual work for EfiSmmRegisterHandler.
+//
+// Input: VOID
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//Can Legacy and PE32 handle overlap?
+VOID SmmRegisterHandler()
+{
+ EFI_PHYSICAL_ADDRESS EntryPoint, DstBuffer;
+ UINTN NumberOfPages,RealNumberOfPages;
+ EFI_STATUS Status;
+ EFI_HANDLE NewImageHandle;
+ EFI_HANDLE SmmImageHandle;
+
+ //Pre-allocate plenty of pages for the SMM driver, so LoadPeImage will only decompress the driver once.
+ //If memory is not enough, the number of pages will returned and enough memory allocated,
+ // then LoadPeImage will decompress the driver again.
+ //Any extra pages will be freed and not wasted.
+#define DEFAULT_SMM_DRIVER_PAGES 16
+ NumberOfPages = DEFAULT_SMM_DRIVER_PAGES;
+#if SMM_USE_FRAMEWORK
+ Status = gSmstTable->SmmAllocatePages(
+#else
+ Status = gSmstTable2->SmmAllocatePages(
+#endif
+ AllocateAnyPages, 0, NumberOfPages, &DstBuffer
+ );
+ if (EFI_ERROR(Status)) {
+ //If allocation failed, so try the minimum of 1 page.
+ NumberOfPages = 1;
+#if SMM_USE_FRAMEWORK
+ Status = gSmstTable->SmmAllocatePages(
+#else
+ Status = gSmstTable2->SmmAllocatePages(
+#endif
+ AllocateAnyPages, 0, NumberOfPages, &DstBuffer
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ gBasePrivate->CallbackStatus = Status;
+ return;
+ }
+ }
+
+ //DstBuffer can't be 0, or LoadPeImage will allocate non-SMM memory.
+ RealNumberOfPages = NumberOfPages;
+ Status=gPe32Image->LoadPeImage(
+ gPe32Image, gThisImageHandle,
+ gBasePrivate->CallbackParameters.RegisterHandler.FilePath, //Either DevicePath or
+ gBasePrivate->CallbackParameters.RegisterHandler.SourceBuffer, //Buffer. This will be zero if DevicePath.
+ gBasePrivate->CallbackParameters.RegisterHandler.SourceSize,
+ DstBuffer, &RealNumberOfPages,
+ &NewImageHandle,
+ &EntryPoint, EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE
+ );
+ //If Image has been loaded, let's free extra memory
+ if (!EFI_ERROR(Status) && RealNumberOfPages<NumberOfPages) {
+#if SMM_USE_FRAMEWORK
+ gSmstTable->SmmFreePages(
+#else
+ gSmstTable2->SmmFreePages(
+#endif
+ DstBuffer+EFI_PAGES_TO_SIZE(RealNumberOfPages),
+ NumberOfPages-RealNumberOfPages
+ );
+ //If it's not enough memory, let's allocate new chunk and try again.
+ } else if (Status==EFI_BUFFER_TOO_SMALL) {
+ //Free Old Buffer
+#if SMM_USE_FRAMEWORK
+ gSmstTable->SmmFreePages(
+#else
+ gSmstTable2->SmmFreePages(
+#endif
+ DstBuffer, NumberOfPages);
+ //Allocate New Buffer
+#if SMM_USE_FRAMEWORK
+ Status = gSmstTable->SmmAllocatePages(
+#else
+ Status = gSmstTable2->SmmAllocatePages(
+#endif
+ AllocateAnyPages, 0, RealNumberOfPages, &DstBuffer
+ );
+ if (!EFI_ERROR(Status))
+ Status=gPe32Image->LoadPeImage(
+ gPe32Image, gThisImageHandle,
+ gBasePrivate->CallbackParameters.RegisterHandler.FilePath, //Either DevicePath or
+ gBasePrivate->CallbackParameters.RegisterHandler.SourceBuffer, //Buffer. This will be zero if DevicePath.
+ gBasePrivate->CallbackParameters.RegisterHandler.SourceSize,
+ DstBuffer, &RealNumberOfPages,
+ &NewImageHandle,
+ &EntryPoint, EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE
+ );
+ }
+ if (!EFI_ERROR(Status)) {
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ //EFI_IMAGE_ENTRY_POINT EntryPoint;
+
+ Status = pBS->HandleProtocol(NewImageHandle, &gEfiLoadedImageProtocolGuid, &LoadedImage);
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((TRACE_ALWAYS,"SMM."));
+#ifdef EFI_DEBUG
+{
+//Debug message: name/entry point of the module being started
+BOOLEAN GetImageName(EFI_HANDLE, CHAR8 *);
+VOID Trace(UINTN Level, CHAR8 *sFormat,...);
+CHAR8 sName[0x100];
+
+ GetImageName(NewImageHandle, sName);
+ TRACE((TRACE_ALWAYS, "%s.Entry(%X)\n", sName, EntryPoint));
+}
+#endif
+
+ SmmImageHandle = NewImageHandle;
+#if SMM_USE_PI
+ if (gRegisterForPi) {
+ //Create an Image Handle for SMM driver, so the handle can be used to install new handles on.
+ SmmImageHandle = NULL;
+ Status = gSmstTable2->SmmInstallProtocolInterface(
+ &SmmImageHandle,
+ &gSmmImageHandleDummyGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL //Dummy
+ );
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ gBasePrivate->CallbackParameters.RegisterHandler.ImageHandle = SmmImageHandle;
+
+ Status = ((EFI_IMAGE_ENTRY_POINT)EntryPoint)(SmmImageHandle, pST);
+ if (EFI_ERROR(Status))
+#if SMM_USE_FRAMEWORK
+ gSmstTable->SmmFreePages(
+#else
+ gSmstTable2->SmmFreePages(
+#endif
+ DstBuffer, RealNumberOfPages
+ );
+ }
+ gBasePrivate->CallbackStatus = Status;
+}
+
+#if SMM_USE_FRAMEWORK
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmUnregister
+//
+// Description: Removes handler from being called in SMM.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_HANDLE ImageHandle
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Driver was unregistered.
+// * EFI_INVALID_PARAMETER - Image Handle doesn't exist.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmUnregister(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ if (gDisallowCallbacks) return EFI_UNSUPPORTED;
+
+ gBasePrivate->CallbackParameters.UnregisterHandler.ImageHandle = ImageHandle;
+ gBasePrivate->CallbackStatus = EFI_DEVICE_ERROR; //Pre-init - SW SMI didn't happen.
+
+ CallFuncInSmm(SmmUnregisterHandler);
+
+ return gBasePrivate->CallbackStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmUnregisterHandler
+//
+// Description: Does the actual work for EfiSmmUnregisterHandler.
+//
+// Input: VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmUnregisterHandler()
+{
+ gBasePrivate->CallbackStatus = EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmCommunicate
+//
+// Description: Buffer location for EFI Call Back function.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_HANDLE ImageHandle
+// IN OUT VOID *CommunicationBuffer
+// IN OUT UINTN *SourceSize
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Buffer is set.
+// * EFI_INVALID_PARAMETER - Buffer is NULL
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmCommunicate(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle,
+ IN OUT VOID *CommunicationBuffer,
+ IN OUT UINTN *SourceSize
+ )
+{
+ if (gDisallowCallbacks) return EFI_UNSUPPORTED;
+
+ if (!CommunicationBuffer) return EFI_INVALID_PARAMETER;
+
+ gBasePrivate->CallbackParameters.Communicate.ImageHandle = ImageHandle;
+ gBasePrivate->CallbackParameters.Communicate.CommunicationBuffer = CommunicationBuffer;
+ gBasePrivate->CallbackParameters.Communicate.SourceSize = SourceSize;
+ gBasePrivate->CallbackStatus = EFI_DEVICE_ERROR; //Pre-init - SW SMI didn't happen.
+
+ CallFuncInSmm(SmmCommunicate);
+
+ return gBasePrivate->CallbackStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmCommunicate
+//
+// Description: Does the actual work for EfiSmmCommunicate.
+//
+// Input: VOID
+//
+// Output:
+// VOID
+//
+// Notes:
+// A runtime driver will have to call this function again for a virtual address.
+// Currently, virtual address are not automatically fixed up.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmCommunicate()
+{
+// A runtime driver will have to call this function again for a virtual address.
+// Currently, virtual address are not automaically fixed up. Also, no runtime drivers are
+// using this.
+
+ HANDLER_LIST *Link;
+ for (Link = gDispatcherPrivate->HandlerListHead;Link; Link = Link->Link) {
+ if (Link->SmmImageHandle == gBasePrivate->CallbackParameters.Communicate.ImageHandle) {
+ Link->CommunicationBuffer = gBasePrivate->CallbackParameters.Communicate.CommunicationBuffer;
+ Link->SourceSize = gBasePrivate->CallbackParameters.Communicate.SourceSize;
+ gBasePrivate->CallbackStatus = EFI_SUCCESS;
+ return;
+ }
+ }
+ gBasePrivate->CallbackStatus = EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmCallBackService
+//
+// Description: Function for the SMM to call back.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_HANDLE SmmImageHandle
+// IN EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress
+// IN BOOLEAN MakeLast OPTIONAL
+// IN BOOLEAN FloatingPointSave OPTIONAL
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Call back function set for Handle.
+// * EFI_OUT_OF_RESOURCES - Not enough memory to add callback.
+// * EFI_UNSUPPORTED - Caller not in SMM.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmCallBackService(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE SmmImageHandle,
+ IN EFI_SMM_CALLBACK_ENTRY_POINT CallbackAddress,
+ IN BOOLEAN MakeLast OPTIONAL,
+ IN BOOLEAN FloatingPointSave OPTIONAL
+ )
+{
+ HANDLER_LIST *Handler,*Link;
+
+ if (!*gBasePrivate->InSmm) return EFI_UNSUPPORTED;
+
+ if (gSmstTable->SmmAllocatePool(0,sizeof(HANDLER_LIST),&Handler) != EFI_SUCCESS)
+ return EFI_OUT_OF_RESOURCES;
+
+ Handler->EntryPoint = CallbackAddress;
+ Handler->SmmImageHandle = SmmImageHandle;
+ Handler->CommunicationBuffer = 0;
+ Handler->SourceSize = 0;
+ Handler->IsRoot = TRUE;
+ Handler->IsPi = FALSE;
+ Handler->Link = 0;
+
+ if (FloatingPointSave) gDispatcherPrivate->FloatingPointSave = TRUE;
+
+ //If very first add.
+ if (!gDispatcherPrivate->HandlerListHead) {
+ gDispatcherPrivate->HandlerListHead = Handler;
+ return EFI_SUCCESS;
+ }
+
+ //If not MakeLast, add to beginning of list.
+ if (!MakeLast) {
+ Handler->Link = gDispatcherPrivate->HandlerListHead;
+ gDispatcherPrivate->HandlerListHead = Handler;
+ return EFI_SUCCESS;
+ }
+
+ //Add to end of list.
+ for (Link = gDispatcherPrivate->HandlerListHead; Link->Link; Link = Link->Link); //Find end of list
+ Link->Link = Handler;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmAllocatePool
+//
+// Description: Allocate buffer from SMM Memory.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_MEMORY_TYPE PoolType
+// IN UINTN Size
+// OUT VOID **Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Allocation successful.
+// * EFI_OUT_OF_RESOURCES - Not enough space.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmAllocatePool(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+{
+ if (gDisallowCallbacks) return EFI_UNSUPPORTED;
+
+ gBasePrivate->CallbackParameters.AllocatePool.Size = Size;
+ gBasePrivate->CallbackParameters.AllocatePool.Buffer = Buffer;
+ gBasePrivate->CallbackStatus = EFI_DEVICE_ERROR; //Pre-init - SW SMI didn't happen.
+
+ CallFuncInSmm(SmmAllocatePool);
+
+ return gBasePrivate->CallbackStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmAllocatePool
+//
+// Description: Does the actual work for EfiSmmAllocatePool.
+//
+// Input: VOID
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmAllocatePool()
+{
+ gBasePrivate->CallbackStatus = gSmstTable->SmmAllocatePool(
+ 0,
+ gBasePrivate->CallbackParameters.AllocatePool.Size,
+ gBasePrivate->CallbackParameters.AllocatePool.Buffer
+ );
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmFreePool
+//
+// Description: Free pool of memory.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Buffer freed
+// * EFI_INVALID_PARAMETER - Buffer invalid.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmFreePool(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN VOID *Buffer
+ )
+{
+ if (gDisallowCallbacks) return EFI_UNSUPPORTED;
+
+ gBasePrivate->CallbackParameters.FreePool.Buffer = Buffer;
+ gBasePrivate->CallbackStatus = EFI_DEVICE_ERROR; //Pre-init - SW SMI didn't happen.
+
+ CallFuncInSmm(SmmFreePool);
+
+ return gBasePrivate->CallbackStatus;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmFreePool
+//
+// Description: Does the actual work for EfiSmmFreePool.
+//
+// Input: VOID
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmFreePool()
+{
+ gBasePrivate->CallbackStatus = gSmstTable->SmmFreePool(
+ gBasePrivate->CallbackParameters.FreePool.Buffer);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmGetSmstLocation
+//
+// Description: Returns a pointer to the Smst.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN OUT EFI_SMM_SYSTEM_TABLE **Smst
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - SMST address saved in *Smst.
+// * EFI_INVALID_PARAMETER - Smst = NULL.
+// * EFI_UNSUPPORTED - Not in SMM.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmGetSmstLocation(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN OUT EFI_SMM_SYSTEM_TABLE **Smst
+ )
+{
+ if (!*gBasePrivate->InSmm) return EFI_UNSUPPORTED;
+ if (Smst == NULL) return EFI_INVALID_PARAMETER;
+
+ *Smst = gSmstTable;
+ return EFI_SUCCESS;
+}
+
+EFI_SMM_BASE_PROTOCOL gEfiSmmBase = {
+ EfiSmmRegister,
+ EfiSmmUnregister,
+ EfiSmmCommunicate,
+ EfiSmmCallBackService,
+ NULL, //EfiSmmInSmm is runtime function. This will be updated.
+ EfiSmmAllocatePool,
+ EfiSmmFreePool,
+ EfiSmmGetSmstLocation,
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmRegisterUnsupported
+//
+// Description:
+// The SMM Base Protocol function Register return unsupported after
+// BIOS is done executing.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+// IN VOID *SourceBuffer OPTIONAL,
+// IN UINTN SourceSize
+// OUT EFI_HANDLE *ImageHandle
+// IN BOOLEAN LegacyIA32Binary OPTIONAL
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmRegisterUnsupported(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle,
+ IN BOOLEAN LegacyIA32Binary OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmUnregisterUnsupported
+//
+// Description:
+// The SMM Base Protocol function UnRegister return unsupported after
+// BIOS is done executing.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN EFI_HANDLE ImageHandle
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EfiSmmUnregisterUnsupported(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmBase.cif b/Core/EM/SMM/SmmBase.cif
new file mode 100644
index 0000000..79d6ba1
--- /dev/null
+++ b/Core/EM/SMM/SmmBase.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "SmmBase"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMM"
+ RefName = "SmmBase"
+[files]
+"SmmBase.sdl"
+"SmmBase.mak"
+"SmmInit.c"
+"SmmBase.c"
+"SmmBase2.c"
+"SmmDriverDispatcher.c"
+"SmmBase.dxs"
+"SmmBaseAsm.asm"
+<endComponent>
diff --git a/Core/EM/SMM/SmmBase.dxs b/Core/EM/SMM/SmmBase.dxs
new file mode 100644
index 0000000..b6bc561
--- /dev/null
+++ b/Core/EM/SMM/SmmBase.dxs
@@ -0,0 +1,107 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase.dxs 8 4/01/11 10:36a Markw $
+//
+// $Revision: 8 $
+//
+// $Date: 4/01/11 10:36a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase.dxs $
+//
+// 8 4/01/11 10:36a Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Update for PI 1.1
+// [Files] SmmBase.dxs
+//
+// 7 7/08/09 8:03p Markw
+// Update headers.
+//
+// 6 8/28/08 2:04p Markw
+//
+// 5 10/29/07 3:38p Markw
+//
+// 4 10/29/07 11:21a Markw
+// Smm Thunk:
+// * Code and data different segments.
+// * Code position independent.
+// * Switch for CSM for code and EBDA for data.
+//
+// 3 3/14/06 10:02a Felixp
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmBase.dxs
+//
+// Description: Dependency file for the SMM base driver
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Token.h>
+#if PI_SPECIFICATION_VERSION >= 0x0001000a
+#include <Protocol\SmmAccess2.h>
+#include <Protocol\smmcontrol2.h>
+#else
+#include <Protocol\SmmAccess.h>
+#include <Protocol\smmcontrol.h>
+#endif
+#include <Protocol\FirmwareVolume.h >
+#include <Protocol\Variable.h>
+
+#if SMM_THUNK_IN_CSM == 1
+#include <Protocol\LegacyBiosExt.h>
+#include <Protocol\LegacyBios.h>
+#endif
+
+DEPENDENCY_START
+#if PI_SPECIFICATION_VERSION >= 0x0001000a
+ EFI_SMM_ACCESS2_PROTOCOL_GUID AND
+ EFI_SMM_CONTROL2_PROTOCOL_GUID AND
+#else
+ EFI_SMM_ACCESS_PROTOCOL_GUID AND
+ EFI_SMM_CONTROL_PROTOCOL_GUID AND
+#endif
+ EFI_FIRMWARE_VOLUME_PROTOCOL_GUID AND
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+#if SMM_THUNK_IN_CSM == 0
+ EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID
+#else
+ EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID AND
+ EFI_LEGACY_BIOS_EXT_PROTOCOL_GUID AND
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmBase.mak b/Core/EM/SMM/SmmBase.mak
new file mode 100644
index 0000000..1d57955
--- /dev/null
+++ b/Core/EM/SMM/SmmBase.mak
@@ -0,0 +1,84 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase.mak 4 2/07/11 3:35p Markw $
+#
+# $Revision: 4 $
+#
+# $Date: 2/07/11 3:35p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase.mak $
+#
+# 4 2/07/11 3:35p Markw
+# [TAG] EIP53481
+# [Category] New Feature
+# [Description] Add PIWG 1.1 SMM support
+# [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+# SmmDispatcher.h, SmmDispatcher.c,
+# Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+# SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+# Smm Pi Protocol files, SmmPciRbio files
+#
+# 3 7/08/09 8:26p Markw
+# Updated headers.
+#
+# 2 12/02/05 11:48a Felixp
+#
+# 1 1/28/05 4:31p Sivagarn
+# SMM Base Component - Initial check in
+#
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#---------------------------------------------------------------------------
+#
+# Name: SmmBase.MAK
+#
+# Description: Make file for the SMM base code
+#
+#---------------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+all : SmmBase
+
+SmmBase : $(BUILD_DIR)\SmmBase.mak SmmBaseBin
+
+$(BUILD_DIR)\SmmBase.mak : $(SMM_BASE_DIR)\SmmBase.cif $(SMM_BASE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMM_BASE_DIR)\SmmBase.cif $(CIF2MAK_DEFAULTS)
+
+SmmBaseBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmmBase.mak all\
+ GUID=D0632C90-AFD7-4492-B186-257C63143C61\
+ ENTRY_POINT=SmmInitEntry\
+ TYPE=BS_DRIVER \
+ COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SMM/SmmBase.sdl b/Core/EM/SMM/SmmBase.sdl
new file mode 100644
index 0000000..449d117
--- /dev/null
+++ b/Core/EM/SMM/SmmBase.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "SmmBase_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmmBase support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "SMM_BASE_DIR"
+End
+
+MODULE
+ Help = "Includes SmmBase.mak to Project"
+ File = "SmmBase.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmmBase.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/SMM/SmmBase2.c b/Core/EM/SMM/SmmBase2.c
new file mode 100644
index 0000000..679b880
--- /dev/null
+++ b/Core/EM/SMM/SmmBase2.c
@@ -0,0 +1,102 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-20011 American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase2.c 1 2/07/11 3:35p Markw $
+//
+// $Revision: 1 $
+//
+// $Date: 2/07/11 3:35p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBase2.c $
+//
+// 1 2/07/11 3:35p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmBase2.c
+//
+// Description: SmmBase2 Protocol
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "SmmPrivateShared.h"
+#if SMM_USE_PI
+#include <SmmPi.h>
+#include <Protocol\SmmBase2.h>
+#include <AmiDxeLib.h>
+
+EFI_SMM_SYSTEM_TABLE2 *gSmstTable2;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiSmmGetSmstLocation2
+//
+// Description: Retruns a pointer to the Smst.
+//
+// Input:
+// IN EFI_SMM_BASE_PROTOCOL *This
+// IN OUT EFI_SMM_SYSTEM_TABLE **Smst
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - SMST address saved in *Smst.
+// * EFI_INVALID_PARAMETER - Smst = NULL.
+// * EFI_UNSUPPORTED - Not in SMM.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiSmmGetSmstLocation2(
+ IN CONST EFI_SMM_BASE2_PROTOCOL *This,
+ IN OUT EFI_SMM_SYSTEM_TABLE2 **Smst
+ )
+{
+ *Smst = gSmstTable2;
+ return EFI_SUCCESS;
+}
+
+EFI_SMM_BASE2_PROTOCOL gEfiSmmBase2 = {
+ NULL, //This will be updated dynamically.
+ EfiSmmGetSmstLocation2
+};
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmBaseAsm.asm b/Core/EM/SMM/SmmBaseAsm.asm
new file mode 100644
index 0000000..cdaa37b
--- /dev/null
+++ b/Core/EM/SMM/SmmBaseAsm.asm
@@ -0,0 +1,139 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2008, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBaseAsm.asm 2 7/14/09 12:16p Markw $
+;
+; $Revision: 2 $
+;
+; $Date: 7/14/09 12:16p $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmBaseAsm.asm $
+;
+; 2 7/14/09 12:16p Markw
+; Update headers.
+;
+; 1 9/26/08 4:48p Markw
+;
+; 1 6/09/08 5:56p Markw
+; Assembly functions for Dispatcher.
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: SmmDispatcher.asm
+;
+; Description: File that contains assembly for Smm Dispatcher.
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+IFDEF EFIx64
+.code
+include token.equ
+
+public EfiSmmInSmm
+
+public InSmmFuncOffset
+public InSmmFuncLength
+
+InSmmFuncOffset dd InSmmFixup - InSmmStart
+InSmmFuncLength dd InSmmEnd - InSmmStart
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: InSmm
+;
+; Description: Updates if *InSmm if in SMM.
+;
+; Input:
+; IN EFI_SMM_BASE_PROTOCOL *This,
+; OUT BOOLEAN *InSmm
+;
+; Output: EFI_STATUS
+;
+; Modified: Nothing
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+EfiSmmInSmm proc
+InSmmStart EQU $
+ or rdx, rdx
+ jnz @f
+ mov rax, 8000000000000002h
+ ret
+@@:
+ ;mov al, 0
+ db 0b0h
+InSmmFixup EQU $
+ db 0
+ mov [rdx], al
+ mov rax, 0
+ ret
+InSmmEnd EQU $
+EfiSmmInSmm endp
+
+ELSE ;32-bits
+.586p
+.model small
+.code
+
+public _InSmmFuncOffset
+public _InSmmFuncLength
+
+_InSmmFuncOffset dd InSmmFixup - InSmmStart
+_InSmmFuncLength dd InSmmEnd - InSmmStart
+
+_EfiSmmInSmm proc public
+InSmmStart EQU $
+ or dword ptr [esp + 8], 0
+ jnz @f
+ mov eax, 80000002h
+ ret
+@@:
+ ;mov al, 0
+ db 0b0h
+InSmmFixup EQU $
+ db 0
+ push ebx
+ mov ebx, [esp + 12]
+ mov [ebx], al
+ pop ebx
+ xor eax, eax
+ ret
+InSmmEnd EQU $
+_EfiSmmInSmm endp
+ENDIF
+
+end
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2008, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/EM/SMM/SmmCommunicate.c b/Core/EM/SMM/SmmCommunicate.c
new file mode 100644
index 0000000..929118e
--- /dev/null
+++ b/Core/EM/SMM/SmmCommunicate.c
@@ -0,0 +1,462 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011 American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmCommunicate.c 5 3/22/12 11:38a Markw $
+//
+// $Revision: 5 $
+//
+// $Date: 3/22/12 11:38a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmCommunicate.c $
+//
+// 5 3/22/12 11:38a Markw
+// [TAG] EIP84198
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Using SMM Communication can cause OS to hang
+// [RootCause] SMM Communication Protocol’s Communicate API does not
+// function in UEFI OS after Exit boot services event because
+// ConvertPointer() did not convert SMM_COMMUNICATE_DATA *gCommunicateData
+// pointer from a Physical Memory Map Pointer to a Virtual Memory Map
+// Pointer. gCommunicateData is allocated in EfiACPIMemoryNVS.
+// [Solution] Allocate memory gCommunicateData as Runtime Services Data.
+// [Files] SmmCommunicate.c
+//
+// 4 10/03/11 3:56p Markw
+// Use tokens for SW SMI. Comment publishing ACPI table until ready.
+// Files: SmmCommunicate.sdl, SmmCommunicate.c
+//
+// 3 9/14/11 11:30a Markw
+// Add comment for pRS->GetVariable in CommunicateCallback, and in SMM
+// Communcate generating SW SMI.
+//
+// 2 9/12/11 9:58a Markw
+// [TAG] EIP64115
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SmmCommuncate hangs in OS.
+// [RootCause] SMM Communciate not available in OS.
+// [Solution] Update SMM Communicate to work under OS by making it a
+// runtime driver and converting pointers to virtual points on
+// EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+//
+// [Files] SmmCommunicate.c, SmmCommunicate.mak
+//
+// 1 4/18/11 12:03p Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Add SMM PI 1.1 Communicate Support.
+// [Files] SmmCommunicate.cif
+// SmmCommunicate.sdl
+// SmmCommunicate.c
+// SmmCommunicate.dxs
+// SmmDxeCommunicate.dxs
+// SmmCommunicate.mak
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmCommunicate.c
+//
+// Description: Provide SMM Communicate Protocol
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#include <Acpi.h>
+#include <AmiDxeLib.h>
+#include <SmmPi.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmCommunication.h>
+#include <Protocol\SmmSwDispatch2.h>
+#include <Protocol\AcpiSupport.h>
+#include <Protocol\AmiInternalSmmComm.h>
+#include <Token.h>
+
+typedef struct {
+ VOID *CommBuffer;
+ UINTN *CommSize;
+ EFI_STATUS Status;
+} SMM_COMMUNICATE_DATA;
+
+#define SMM_COMMUNICATE_DATA_VARIABLE L"SMM_COMMUNICATE_DATA"
+
+// {08F10CB6-3131-4919-9D70-5C8A17366EE8}
+#define SMM_COMMUNICATE_DATA_GUID \
+ {0x8f10cb6, 0x3131, 0x4919, 0x9d, 0x70, 0x5c, 0x8a, 0x17, 0x36, 0x6e, 0xe8}
+
+EFI_HANDLE gImageHandle;
+
+EFI_GUID gEfiSmmBase2ProtocolGuid = EFI_SMM_BASE2_PROTOCOL_GUID;
+EFI_GUID gEfiSmmCommunicationProtocolGuid = EFI_SMM_COMMUNICATION_PROTOCOL_GUID;
+EFI_GUID gAmiIntSmmCommProtocolGuid = AMI_INT_SMM_COMM_PROTOCOL_GUID;
+EFI_GUID gSmmCommunicateDataGuid = SMM_COMMUNICATE_DATA_GUID;
+EFI_GUID gEfiAcpiSupportGuid = EFI_ACPI_SUPPORT_GUID;
+
+
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
+
+
+SMM_COMMUNICATE_DATA *gCommunicateData = NULL;
+
+/////////////////////SMM//////////////////
+EFI_GUID gEfiSmmSwDispatch2ProtocolGuid = EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID;
+
+EFI_SMM_SW_DISPATCH2_PROTOCOL *gSmmSw2;
+EFI_SMM_SYSTEM_TABLE2 *Smst2;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CommunicateCallBack
+//
+// Description: Sw SMI callback to call communicate functions.
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle - Unused
+// IN CONST VOID *Context OPTIONAL - Unused
+// IN OUT VOID *CommBuffer OPTIONAL - Unused
+// IN OUT UINTN *CommBufferSize OPTIONAL - Unused
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CommunicateCallBack(
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+{
+ EFI_SMM_COMMUNICATE_HEADER *Header;
+ EFI_STATUS Status;
+
+ if (gCommunicateData == NULL) {
+ UINTN VariableSize = sizeof(EFI_SMM_COMMUNICATE_HEADER*);
+
+ //SMM_COMMUNICATE_DATA_VARIABLE variable is not available during
+ // SMM entry. When this variable is set in DXE before BDS,
+ // a SW SMI is executed, and gCommunicateData is initialized
+ // before SMM Communciate protocol is published.
+ Status = pRS->GetVariable(
+ SMM_COMMUNICATE_DATA_VARIABLE,
+ &gSmmCommunicateDataGuid,
+ NULL,
+ &VariableSize,
+ &gCommunicateData
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (!EFI_ERROR(Status)) gCommunicateData->Status = Status;
+ return EFI_SUCCESS;
+ }
+
+ if (gCommunicateData->CommBuffer == NULL) {
+ gCommunicateData->Status = EFI_INVALID_PARAMETER;
+ return EFI_SUCCESS;
+ }
+
+ gCommunicateData->Status = EFI_NOT_FOUND; //Default no handler found.
+
+ Header = (EFI_SMM_COMMUNICATE_HEADER*)(gCommunicateData->CommBuffer);
+ Status = Smst2->SmiManage(&Header->HeaderGuid, NULL, Header->Data, &Header->MessageLength);
+
+ //Default Status of SmiManage is EFI_INTERRUPT_PENDING. Thus, no handler found.
+ if (Status != EFI_INTERRUPT_PENDING) gCommunicateData->Status = EFI_SUCCESS;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitSmm
+//
+// Description: Initialize SMM part of SMM Communicate.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitSmm()
+{
+ EFI_STATUS Status;
+ EFI_SMM_SW_REGISTER_CONTEXT RegisterContext = {SMM_COMM_SW_SMI};
+ EFI_HANDLE ImageHandle = NULL;
+ EFI_HANDLE DispatchHandle;
+
+ Status = gSmmBase2->GetSmstLocation(gSmmBase2, &Smst2);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = Smst2->SmmLocateProtocol(&gEfiSmmSwDispatch2ProtocolGuid, NULL, &gSmmSw2);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gSmmSw2->Register(
+ gSmmSw2,
+ CommunicateCallBack,
+ &RegisterContext,
+ &DispatchHandle
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+
+//Signal that Handler is ready
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gAmiIntSmmCommProtocolGuid, NULL,
+ NULL
+ );
+
+ return Status;
+}
+
+
+/////////////////////ACPI//////////////////
+
+#pragma pack(push, 1)
+typedef struct {
+ ACPI_HDR Hdr;
+ EFI_GUID Identifier;
+ UINT16 DataOffset;
+ UINT32 SwSmi;
+ UINT64 BufferPtr;
+} ACPI_SMM_COMM_TABLE;
+#pragma pack(pop)
+
+ACPI_SMM_COMM_TABLE gAcpiSmmCommTable =
+{
+ 'UEFI',
+ sizeof(ACPI_SMM_COMM_TABLE),
+ 1, //Revision
+ 0, //Checksum
+ CONVERT_TO_STRING(T_ACPI_OEM_ID),
+ CONVERT_TO_STRING(T_ACPI_OEM_TBL_ID),
+ ACPI_OEM_REV,
+ 0, //Creator ID
+ 0, //Creator Revision,
+ EFI_SMM_COMMUNICATION_PROTOCOL_GUID,
+ EFI_FIELD_OFFSET(ACPI_SMM_COMM_TABLE, SwSmi),
+ SMM_COMM_SW_SMI,
+ 0
+};
+
+EFI_ACPI_SUPPORT_PROTOCOL *gAcpiSupport;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitAcpi
+//
+// Description: Initialize Acpi SMM Communicate part.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitAcpi()
+{
+//TODO: Proper support for ACPI SMM communicate will be in SMM label 45.
+#if 0
+ EFI_STATUS Status;
+ UINTN AcpiHandle = 0;
+
+ Status = pBS->LocateProtocol(&gEfiAcpiSupportGuid, NULL, &gAcpiSupport);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = gAcpiSupport->SetAcpiTable(
+ gAcpiSupport,
+ &gAcpiSmmCommTable,
+ TRUE,
+ EFI_ACPI_TABLE_VERSION_ALL,
+ &AcpiHandle
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+#endif
+
+ return EFI_SUCCESS;
+}
+
+/////////////////////DXE//////////////////
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmCommunicate
+//
+// Description: SmmCommunicate Protocol function. This will generate SW SMI.
+//
+// Input:
+// IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This,
+// IN OUT VOID *CommBuffer,
+// IN OUT UINTN *CommSize
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmCommunicate(
+ IN CONST EFI_SMM_COMMUNICATION_PROTOCOL *This,
+ IN OUT VOID *CommBuffer,
+ IN OUT UINTN *CommSize
+)
+{
+ gCommunicateData->CommBuffer = CommBuffer;
+ gCommunicateData->CommSize = CommSize;
+ gCommunicateData->Status = EFI_DEVICE_ERROR; //Pre-initialize status in case SMI doesn't happen.
+
+ //Execute SW SMI to initialize
+ IoWrite8(SW_SMI_IO_ADDRESS, SMM_COMM_SW_SMI);
+
+ return gCommunicateData->Status;
+}
+
+EFI_SMM_COMMUNICATION_PROTOCOL gEfiSmmCommunicationProtocol = {
+ SmmCommunicate
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: VirtAddrChg
+//
+// Description: Change pointer of gCommunicateData to virtual address.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID VirtAddrChg(IN EFI_EVENT Event, IN VOID *Context)
+{
+ pRS->ConvertPointer(0, (VOID**)&gCommunicateData);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitDxe
+//
+// Description: Initialize DXE SMM Communicate part.
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitDxe()
+{
+ EFI_STATUS Status;
+ EFI_EVENT VirtAddrChgEvt;
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, sizeof(SMM_COMMUNICATE_DATA), &gCommunicateData);
+ ASSERT_EFI_ERROR(Status);
+
+ //Pass gCommunicateData to SMM Dispatcher.
+ gCommunicateData->Status = EFI_DEVICE_ERROR; //Pre-initialize status in case SMI doesn't happen.
+
+ //Set Value
+ Status = pRS->SetVariable(
+ SMM_COMMUNICATE_DATA_VARIABLE,
+ &gSmmCommunicateDataGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(SMM_COMMUNICATE_DATA*),
+ &gCommunicateData
+ );
+
+ IoWrite8(SW_SMI_IO_ADDRESS, SMM_COMM_SW_SMI);
+
+ if (gCommunicateData->Status == EFI_DEVICE_ERROR) return EFI_DEVICE_ERROR;
+
+ InitAcpi();
+
+ Status = pBS->CreateEvent(
+ EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE,
+ TPL_CALLBACK,
+ &VirtAddrChg,
+ NULL,
+ &VirtAddrChgEvt
+ );
+ ASSERT_EFI_ERROR(Status);
+
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &gImageHandle,
+ &gEfiSmmCommunicationProtocolGuid, &gEfiSmmCommunicationProtocol,
+ NULL
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmCommunicateEntry
+//
+// Description: Smm Communciation entry point to initialize provide SMM Communicate Protocol.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmCommunicateEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ BOOLEAN InSmram;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ gImageHandle = ImageHandle;
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gSmmBase2->InSmm(gSmmBase2, &InSmram);
+ ASSERT_EFI_ERROR(Status);
+
+ if (InSmram) return InitSmm();
+ return InitDxe();
+}
diff --git a/Core/EM/SMM/SmmCommunicate.cif b/Core/EM/SMM/SmmCommunicate.cif
new file mode 100644
index 0000000..3d086cd
--- /dev/null
+++ b/Core/EM/SMM/SmmCommunicate.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "SmmCommunicate"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMM\"
+ RefName = "SmmCommunicate"
+[files]
+"SmmCommunicate.sdl"
+"SmmCommunicate.c"
+"SmmCommunicate.dxs"
+"SmmDxeCommunicate.dxs"
+"SmmCommunicate.mak"
+<endComponent>
diff --git a/Core/EM/SMM/SmmCommunicate.dxs b/Core/EM/SMM/SmmCommunicate.dxs
new file mode 100644
index 0000000..4eb6b47
--- /dev/null
+++ b/Core/EM/SMM/SmmCommunicate.dxs
@@ -0,0 +1,67 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmCommunicate.dxs 1 4/18/11 12:03p Markw $
+//
+// $Revision: 1 $
+//
+// $Date: 4/18/11 12:03p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmCommunicate.dxs $
+//
+// 1 4/18/11 12:03p Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Add SMM PI 1.1 Communicate Support.
+// [Files] SmmCommunicate.cif
+// SmmCommunicate.sdl
+// SmmCommunicate.c
+// SmmCommunicate.dxs
+// SmmDxeCommunicate.dxs
+// SmmCommunicate.mak
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmCommunicate.dxs
+//
+// Description: Dependency file for the SMM Communicate driver
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Protocol\SmmSwDispatch2.h>
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmCommunicate.mak b/Core/EM/SMM/SmmCommunicate.mak
new file mode 100644
index 0000000..b0b4918
--- /dev/null
+++ b/Core/EM/SMM/SmmCommunicate.mak
@@ -0,0 +1,91 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmCommunicate.mak 2 9/12/11 9:59a Markw $
+#
+# $Revision: 2 $
+#
+# $Date: 9/12/11 9:59a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmCommunicate.mak $
+#
+# 2 9/12/11 9:59a Markw
+# [TAG] EIP64115
+# [Category] Bug Fix
+# [Severity] Normal
+# [Symptom] SmmCommuncate hangs in OS.
+# [RootCause] SmmCommunicate not supported in OS.
+# [Solution] Update SMM Communicate to work under OS by making it a
+# runtime driver and converting pointers to virtual points on
+# EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.
+#
+# [Files] SmmCommunicate.c, SmmCommunicate.mak
+#
+# 1 4/18/11 12:03p Markw
+# [TAG] EIP57440
+# [Category] New Feature
+# [Description] Add SMM PI 1.1 Communicate Support.
+# [Files] SmmCommunicate.cif
+# SmmCommunicate.sdl
+# SmmCommunicate.c
+# SmmCommunicate.dxs
+# SmmDxeCommunicate.dxs
+# SmmCommunicate.mak
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#---------------------------------------------------------------------------
+#
+# Name: SmmCommunicate.mak
+#
+# Description: Make file for the SMM Communicate code
+#
+#---------------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+all : SmmCommunicate
+SmmCommunicate : $(BUILD_DIR)\SmmCommunicate.mak SmmCommunicateBin
+
+$(BUILD_DIR)\SmmCommunicate.mak : $(SMM_COMMUNICATE_DIR)\SmmCommunicate.cif $(SMM_COMMUNICATE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMM_COMMUNICATE_DIR)\SmmCommunicate.cif $(CIF2MAK_DEFAULTS)
+
+SmmCommunicateBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmmCommunicate.mak all\
+ GUID=7E2D983F-F703-4a29-9761-77B51F5354ED\
+ ENTRY_POINT=SmmCommunicateEntry\
+ TYPE=DXESMM_DRIVER PE_TYPE=RT_DRIVER\
+ DEPEX1=$(SMM_COMMUNICATE_DIR)\SmmCommunicate.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ DEPEX2=$(SMM_COMMUNICATE_DIR)\SmmDxeCommunicate.dxs \
+ DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SMM/SmmCommunicate.sdl b/Core/EM/SMM/SmmCommunicate.sdl
new file mode 100644
index 0000000..7ac66cc
--- /dev/null
+++ b/Core/EM/SMM/SmmCommunicate.sdl
@@ -0,0 +1,44 @@
+TOKEN
+ Name = "SMM_COMMUNICATE_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmmBase support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "PI_SPECIFICATION_VERSION" ">=" "0x1000A"
+End
+
+TOKEN
+ Name = "SMM_COMM_SW_SMI"
+ Value = "0xdd"
+ Help = "SMM Communicate function SW SMI. Do not change"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "SMM_COMM_ACPI_SW_SMI"
+ Value = "0xde"
+ Help = "SMM Communicate ACPI SW SMI. Do not change"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+PATH
+ Name = "SMM_COMMUNICATE_DIR"
+End
+
+MODULE
+ Help = "Includes SmmCommunicate.mak to Project"
+ File = "SmmCommunicate.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmmCommunicate.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/SMM/SmmDispatcher.c b/Core/EM/SMM/SmmDispatcher.c
new file mode 100644
index 0000000..c510cc7
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcher.c
@@ -0,0 +1,1533 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/SmmDispatcher.c 5 6/17/16 4:14a Chienhsieh $
+//
+// $Revision: 5 $
+//
+// $Date: 6/17/16 4:14a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/SmmDispatcher.c $
+//
+// 5 6/17/16 4:14a Chienhsieh
+// Roll back #if condition: "ENABLE_SEND_SMI_IPI_IN_SMM" as Rev.3
+//
+// 4 7/08/15 4:26a Chienhsieh
+//
+// 3 12/19/12 6:25a Wesleychen
+// Set a #if condition: "ENABLE_SEND_SMI_IPI_IN_SMM" to isolate send SMI
+// IPI in SMM for avoid system stay in an unstable state when numerous
+// SMI# are generated.
+//
+// 2 10/31/12 6:30a Wesleychen
+// Modify SMM InterruptManage function to execute Non-PI handler after PI
+// handler.
+//
+// 75 10/03/11 2:53p Markw
+// Add SMM Machine Check handler.
+// Files: SmmDispatcher.c, SmmDispatcherAsm.asm
+//
+// 74 9/28/11 4:52p Markw
+// [TAG] EIP71122
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] System may hang randomly in PI 1.1 mode.
+// [RootCause] PI 1.1 SMST was initialized using uninitialized gSmmBase.
+// [Solution] Initialize gSmmBase before initializing PI 1.1 SMST.
+// [Files] SmmDispatcher.c
+//
+// 73 6/01/11 3:09p Markw
+// [TAG] EIP61586
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] None
+// [RootCause] SMM security issue. Need ITP, specific board, and memory
+// to exploit.
+// SMM Dispatcher reads a pointer out of SMM. It uses this pointer to
+// access outside of SMM.
+// To exploit, the pointer would have to modified to write inside of SMM
+// to update code to allow SMM code to access the function call outside of
+// SMM.
+// Then, the exploit would have update a callback structure with an
+// address outside of SMM.
+// [Solution] Copy the pointer inside of SMM. Thus, a direct write
+// outside of SMM without reading a pointer outside of SMM first.
+// [Files] SmmDispatcher.c
+//
+// 72 4/15/11 4:39p Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] PI 1.1 update of Manage function from previous
+// check-in.
+// [Files] SmmDispatcher.c
+//
+// 71 3/31/11 6:44p Markw
+// [TAG] EIP57440
+// [Category] Improvement
+// [Description] Separate Framework and PI 1.1 registered SMI source
+// handlers function return status checking.
+// [Files] SmmDispatcher.c
+//
+// 69 2/07/11 3:29p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+// 67 10/13/10 1:15p Markw
+// Fix compiler warning form Timeout->EndValue = ((UINT32)EndValue) & ((1
+// << NUM_BITS_IN_ACPI_TIMER) - 1);
+//
+// 66 9/10/10 5:05p Markw
+// Typecase to UINT8 when comparing savestate eax with SW SMI number.
+//
+// 65 4/29/10 11:23a Markw
+// Added some additional asserts on allocating SMM memory during SMM
+// initialization.
+//
+// 64 4/27/10 7:28p Markw
+// EIP 37921 - Update timeout functions to fix boundary condition in
+// timeout.
+//
+// 63 3/02/10 1:49p Markw
+// Added functions/structures for Save/Restore CPU state in SMM.
+//
+// 62 2/25/10 5:24p Markw
+// Install AmiSmmInfo Protocol.
+//
+// 61 2/18/10 4:31p Markw
+// EIP 34991 - Update CPU detection of CPU that generated SW SMI. It is
+// possible that multiple SW SMI may be generated simutaneously.
+// The CPU reported as generated the SW SMI by SwSMiCpuTrigger will the
+// first CPU that matches SW_SMI_IO_ADDRESS not just the first CPU found
+// that generated a SW SMI.
+//
+// 60 11/23/09 11:27a Markw
+// Remove ASSERT when SBSP not in SMM.
+//
+// 59 11/23/09 10:59a Markw
+// Renamed TIMEOUT to SMM_TIMEOUT.
+//
+// 58 9/09/09 5:17p Markw
+// EIP #25506 - Use token for x2apic support.
+//
+// 57 8/05/09 3:03p Markw
+// EIP #24914 - Add early local x2APIC support.
+//
+// 56 7/08/09 8:04p Markw
+// Update headers.
+//
+// 55 5/12/09 7:22p Markw
+// Fix mismatch #if/#endif when updating AMI_DEBUGGER_SUPPORT.
+//
+// 54 5/12/09 7:04p Markw
+// EIP #22087 - When AMI Debugger enabled, save IDT for IDT
+// re-initialization in SmmEntry.asm.
+//
+// 53 1/22/09 1:03p Markw
+// EIP #18671 (OPEN) Clear SW SMI status and set EOS inside SMM. Also
+// check for private SW SMI as well as private function. Call Clear
+// function inside SMM.
+//
+// 52 12/24/08 10:54a Markw
+// EIP #18423: Adjust EBDA location as more EBDA data is allocated.
+//
+// 51 12/01/08 1:55p Markw
+//
+// 50 11/25/08 4:09p Markw
+// Remove TRACE. Hangs during runtime OS.
+//
+// 49 11/25/08 11:25a Markw
+// Reinitialize the InSmm variable.
+//
+// 48 11/24/08 7:13p Markw
+// Save/restore upper byte of Interrupt command register. Check if no IPI
+// pending before issuing interrupt.
+//
+// 47 11/21/08 4:59p Markw
+// SBSP if available dispatches. S3 reinitialization. User ACPI timer for
+// time.out.
+//
+// 46 11/12/08 4:57p Markw
+// Dynamically update the CurrentlyExecutingCpu in SMM SYSTEM TABLE.
+//
+// 45 10/03/08 9:45a Markw
+// Fix race condindition when sync APs with BSP. Under some conditions
+// some APs skip the SmmStartupAp control loop.
+//
+// 44 9/26/08 4:52p Markw
+// The Private InSmm is now a pointer.
+//
+// 43 9/09/08 3:06p Markw
+// Align Dispatcher to 4k.
+//
+// 42 9/07/08 12:44a Markw
+// Separate SMM Private structure into inside SMM and outside SMM
+// structure.
+//
+// 41 9/04/08 12:26a Markw
+// Always have timeout on AP. Check SMM IPI pending status.
+//
+// 40 8/28/08 3:54p Markw
+//
+// 39 8/28/08 3:52p Markw
+//
+// 38 8/12/08 5:58p Markw
+// Use SMM instance BSP, not not runtime BSP. Call dispatcher even for SMM
+// software SMIs.
+//
+// 37 6/10/08 6:45p Markw
+// Disable SMM Thunk, if SMM is in TSEG and no CSM.
+//
+// 36 6/09/08 5:51p Markw
+// Any CPU can be BSP now. Created a Common Entry. Start APs that have not
+// started yet.
+//
+// 35 5/23/08 11:19a Markw
+// Don't allow callbacks once the flag is set.
+//
+// 34 3/03/08 6:58p Markw
+// Add 32-bit registers to SMM 16-bit thunk.
+//
+// 33 11/21/07 1:06p Markw
+// Header updates.
+//
+// 32 11/21/07 12:56p Markw
+// Always install thunk protocol.
+//
+// 31 11/14/07 2:02p Markw
+// Added SMRR support and updated SMM Cache for non-SMRR.
+// Updated SMM interrupt handeling because of complier optimization bug.
+//
+// 30 10/29/07 3:38p Markw
+//
+// 29 10/29/07 10:58a Markw
+// Smm Thunk:
+// * Code and data different segments.
+// * Code position independent.
+// * Switch for CSM for code and EBDA for data.
+//
+// 28 10/24/07 12:02p Markw
+// SMM Thunk code position independent. Data in a separate segment than
+// code in Smm Thunk.
+// Combined BSP and AP SmmEntry.
+//
+// 27 9/10/07 1:39p Markw
+// Add Interrupt Handling in SMM.
+//
+// 26 7/25/07 2:11p Markw
+// Limit number of CPUs in SMM to maximum in case system shutsdown in SMM.
+//
+// 25 6/14/07 11:01a Markw
+// Comment change.
+//
+// 24 4/13/07 11:03a Markw
+// Update header.
+//
+// 23 3/27/07 11:42a Markw
+// Fix get SmmBases in dispatcher for APs if BSP is in TSEG.
+//
+// 22 3/14/07 5:58p Markw
+// Allow the BSP to service the SMI if APs time-out.
+//
+// 21 2/07/07 11:06a Markw
+// Add Smm Cpu State protocol.
+//
+// 20 1/30/07 11:58a Markw
+// Added code to exit if not all CPUs enter SMM.
+//
+// 19 1/11/07 12:29p Markw
+// Use switch to enable/disable legacy code during build.
+//
+// 18 1/10/07 5:29p Markw
+// Only install SMM Thunk if BSP entry below 1MB.
+//
+// 17 1/09/07 6:45p Markw
+// Remove dependencies on SMM_BSP_BASE. Use SMM Hob.
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmDispatcher.c
+//
+// Description: Contains the SMM dispatcher code for BSP & APs
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//This include should be first.
+#include "SmmPrivateShared.h"
+#include <Protocol\SmmThunk.h>
+#include <AmiSmm.h>
+#include <Protocol\SmmCpuState.h>
+#include <Protocol\AmiSmmInfo.h>
+#if SMM_USE_PI
+#include "SmmPi.h"
+#include <Protocol\SmmCpu.h>
+#include <Protocol\SmmControl2.h>
+#else
+#include <smm.h>
+#include <Protocol\SmmControl.h>
+#endif
+#include "AmiCspLib.h"
+
+//CPU APIC includes
+#define APIC_ALL_EXCLUDING_SELF (3 << 18)
+#define APIC_SIPI (6 << 8)
+#define APIC_INIT (5 << 8)
+#define APIC_SMI (2 << 8)
+#define APIC_DELIVERY_STATUS (1 << 12)
+#define APIC_LEVEL_ASSERT (1 << 14)
+#define APIC_LEVEL_DEASSERT (0 << 14)
+#define APIC_NO_SHORT_HAND (0 << 18)
+
+#define MSR_EXT_XAPIC_ICR 0x830
+
+EFI_GUID gEfiSmmThunkProtocolGuid = EFI_SMM_THUNK_PROTOCOL_GUID;
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+EFI_GUID gEfiSmmCpuSaveStateProtocolGuid = EFI_SMM_CPU_SAVE_STATE_PROTOCOL_GUID;
+EFI_GUID gAmiSmmInfoProtcolGuid = AMI_SMM_INFO_PROTOCOL_GUID;
+#if SMM_USE_PI
+EFI_GUID gEfiCpuIo2ProtocolGuid = EFI_SMM_CPU_IO2_PROTOCOL_GUID;
+#endif
+
+UINT8 **gSmmBase;
+
+SMM_ENTRY_INIT_STRUCT *gSmmEntryData;
+SW_SMI_CPU_TRIGGER *gSwSmiCpuTrigger;
+EFI_SMM_CPU_SAVE_STATE_PROTOCOL gEfiSmmCpuSaveState;
+SMM_BASE_PRIVATE_STRUCT *gBasePrivate;
+SMM_DISPATCHER_PRIVATE_STRUCT *gDispatcherPrivate;
+volatile BOOLEAN gEntrySemaphore = FALSE;
+volatile BOOLEAN gUseSbsp;
+UINT32 gSbsp;
+volatile BOOLEAN gReleaseStartedCpus = FALSE;
+volatile UINT32 gNumCpusReady = 0;
+volatile BOOLEAN gAllCpusInSync = FALSE;
+volatile BOOLEAN gReadyForApsToExecute;
+volatile UINT8 gInitSemaphore = 0;
+BOOLEAN *gInSmm;
+
+
+#if SMM_USE_FRAMEWORK
+extern EFI_SMM_SYSTEM_TABLE gSmmSystemTable;
+#endif
+#if SMM_USE_PI
+extern EFI_SMM_SYSTEM_TABLE2 gSmmSystemTable2;
+extern EFI_SMM_CPU_PROTOCOL gEfiSmmCpuProtocol;
+#endif
+
+EFI_SMM_SAVE_RESTORE_FUNCTION SmmSaveRestoreFunctionTable[] = {
+ SmmSaveRestoreEnvironment
+ NULL
+};
+
+#if SMM_USE_PI
+EFI_SMM_ENTRY_CONTEXT gEfiSmmEntryContext; //For now, hardcode.
+UINTN gEfiSmmEntryContextSize = sizeof(EFI_SMM_ENTRY_CONTEXT);
+#endif
+
+void * Allocate(
+ IN VOID *Address OPTIONAL,
+ IN UINTN Size,
+ UINTN Alignment OPTIONAL
+);
+
+VOID InitializeMemoryManager(SMM_BASE_PRIVATE_STRUCT *Private);
+VOID InitializeSmmSystemTable();
+VOID InitializeSmmPiSystemTable();
+BOOLEAN IsSwSmiTrigger(UINT8 *SmmBase, UINT16 SwSmiPort);
+VOID StartAllCpus(SMM_ENTRY_INIT_STRUCT *SmmEntryInit);
+VOID HoldStartedCpus(SMM_ENTRY_INIT_STRUCT *SmmEntryInit);
+VOID SmmBspEntry(SMM_ENTRY_INIT_STRUCT *SmmEntryInit);
+VOID SmmApEntry(SMM_ENTRY_INIT_STRUCT *SmmEntryInit);
+UINT32 LockInc32(UINT32 *);
+VOID LockDec32(UINT32 *);
+VOID MachineCheckHandler();
+VOID InitCrc();
+
+EFI_STATUS InterruptManage(
+ IN CONST EFI_GUID *HandlerType,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+);
+
+typedef struct {
+ UINT32 OverFlow;
+ UINT32 EndValue;
+ UINT32 OldTimerValue;
+} SMM_TIMEOUT;
+
+EFI_STATUS StartTimeout(SMM_TIMEOUT *Timeout, UINT32 Time);
+EFI_STATUS HasItTimedOut(SMM_TIMEOUT *Timeout);
+
+BOOLEAN EfiSmmFarCall86Ex(
+ IN EFI_SMM_THUNK_PROTOCOL *This,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN SMM_THUNK_IA32_REGISTER_SET_EX *Regs,
+ IN VOID *Stack,
+ IN UINTN StackSize
+);
+
+//TODOx64: move it to a library header
+VOID CPULib_Pause();
+
+BOOLEAN Xchg8(IN OUT volatile UINT8 *, IN UINT8);
+
+//This typedef is the same as EFI_SMM_HANDLER_ENTRY_POINT2 in SmmPi.h.
+typedef EFI_STATUS (EFIAPI *SMM_HANDLER_ENTRY) (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+);
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CommonEntry
+//
+// Description: BSP and APs start here from SmmEntry.asm.
+//
+// Input:
+// IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CommonEntry(IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit)
+{
+ //Two groups of CPUs where come through this function.
+ //1. The initial group all at once. They race for the semaphore.
+ // The winning CPU will try to start any other that has not been started.
+ //2. The CPUs that got started or stragglers after the time-out.
+ //
+ //The SMM Dispatcher will be run by the SBSP if it has been started.
+ //Otherwise, the winning CPU in #1 will run the Dispatcher.
+ //
+ //If SMM generates S3, flags will not be reset.
+
+ UINT32 CpuNo = SmmEntryInit->CpuNo;
+ volatile UINT8 IsNotFirstCpu = TRUE;
+ CPU_LIB_SMM_SAVE_RESTORE_DATA CpuSaveRestoreData;
+
+ CpuLib_SmmSaveCpuState(&CpuSaveRestoreData); //This not save state area.
+
+ //Use gSmmEntryData, so all CPUs use the same SmmInit.
+ //Re-initialize the variables on first entry and S3 resume.
+ if (gSmmEntryData->SmmInit) {
+ volatile UINT8 HoldCpus = 1;
+ HoldCpus = Xchg8(&gInitSemaphore, HoldCpus);
+ if (!HoldCpus) {
+ UINT8 i;
+ gDispatcherPrivate->NumCpusInSmm = 0;
+ gNumCpusReady = 0;
+ gAllCpusInSync = FALSE;
+ gEntrySemaphore = FALSE; //This be reset once, or all CPUs go into hold loop.
+
+ for(i = 0; i < gDispatcherPrivate->NumCpus; ++i) {
+ gDispatcherPrivate->SmmCpuInfo[i].InSmm = FALSE;
+ }
+
+ gSmmEntryData->SmmInit = 0; //This must be last; it releases the other CPUs.
+ } else {
+ while (gSmmEntryData->SmmInit) CPULib_Pause();
+ }
+ }
+
+ //InSmm must be before LockIn32, otherwise StartAllCpus fucntion could
+ //exit time-out loop, and InSmm would be false, so BSP would not execute
+ //dispatcher.
+ gDispatcherPrivate->SmmCpuInfo[CpuNo].InSmm = TRUE;
+
+ LockInc32(&gDispatcherPrivate->NumCpusInSmm);
+
+ if (gEntrySemaphore == 0) { //This if causes fewer memory exchanges.
+ IsNotFirstCpu = Xchg8(&gEntrySemaphore, IsNotFirstCpu);
+ }
+
+ if (!IsNotFirstCpu) { //This is the first CPU.
+ StartAllCpus(SmmEntryInit);
+ } else {
+ HoldStartedCpus(SmmEntryInit);
+ }
+
+ gDispatcherPrivate->SmmCpuInfo[CpuNo].InSmm = FALSE;
+
+ CpuLib_SmmRestoreCpuState(&CpuSaveRestoreData); //This not save state area.
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StartAllCpus
+//
+// Description:
+// One random CPU enters here. Waits for CPUs to sync. If no sync, tries to
+// start CPUs that didn't enter SMM.
+//
+// Input:
+// IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID StartAllCpus(IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit)
+{
+ SMM_TIMEOUT Timeout;
+ UINT32 i;
+
+ //Wait until all APs and BSP are synced.
+ StartTimeout(&Timeout, SMM_TIME_OUT_US);
+
+ while(gDispatcherPrivate->NumCpusInSmm < gDispatcherPrivate->NumCpus
+ && !EFI_ERROR(HasItTimedOut(&Timeout))) CPULib_Pause();
+
+ //If not all CPUs get control in SMM, try to start other CPUs.
+ if (gDispatcherPrivate->NumCpusInSmm < gDispatcherPrivate->NumCpus) {
+ for (i = 0; i < gDispatcherPrivate->NumCpus; ++i) {
+ if (!gDispatcherPrivate->SmmCpuInfo[i].InSmm) {
+ UINT32 ApicId = gDispatcherPrivate->SmmCpuInfo[i].ApicId;
+#if LOCAL_X2APIC_SUPPORT
+ if (CPULib_IsLocalX2ApicEnabled()) {
+ while(ReadMsr(MSR_EXT_XAPIC_ICR) & APIC_DELIVERY_STATUS); //Wait until idle.
+ ReadWriteMsr(MSR_EXT_XAPIC_ICR,
+ Shl64(ApicId, 32) + APIC_NO_SHORT_HAND + APIC_LEVEL_ASSERT + APIC_SMI,
+ 0xfff32000);
+ } else {
+#endif
+#if ENABLE_SEND_SMI_IPI_IN_SMM
+ UINT32 SaveHighByte = *(UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER);
+ //Wait until IPI is Idle
+ while(
+ MemRead32((UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER)) & APIC_DELIVERY_STATUS
+ );
+
+ //Send IPI to APIC ID.
+ MemReadWrite32(
+ (UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER),
+ ApicId << 24,
+ 0x00ffffff
+ );
+ MemReadWrite32(
+ (UINT32*)(LOCAL_APIC_BASE + APIC_ICR_LOW_REGISTER),
+ (0 << 18) + (1 << 14) + (2 << 8),
+ 0
+ );
+ //Restore high byte. Before SMI, BIOS, OS, etc may have
+ *(UINT32*)(LOCAL_APIC_BASE + APIC_ICR_HIGH_REGISTER) = SaveHighByte;
+#endif
+#if LOCAL_X2APIC_SUPPORT
+ }
+#endif
+ }
+ }
+
+ //If not all CPUs get control in SMM.
+ StartTimeout(&Timeout, SMM_TIME_OUT_US); //uS
+ while(gDispatcherPrivate->NumCpusInSmm < gDispatcherPrivate->NumCpus
+ && !EFI_ERROR(HasItTimedOut(&Timeout))) CPULib_Pause();
+ }
+
+ //Has SBSP been started.
+ gUseSbsp = gDispatcherPrivate->SmmCpuInfo[gSbsp].InSmm;
+
+ //The ASSERT below is to signal SBSP not in SMM when testing SMM.
+ //It is generally not an error when the ASSERT below is triggered. It is triggered when debugging, non-SMM errors, etc.
+ //The SMM Dispatcher is designed to process correctly if SBSP is not in SMM.
+ //DEBUG ASSERT(gUseSbsp);
+
+ gReleaseStartedCpus = TRUE;
+
+ if (gUseSbsp) {
+ if (SmmEntryInit->CpuNo == gSbsp) SmmBspEntry(SmmEntryInit);
+ else SmmApEntry(SmmEntryInit);
+ } else {
+ SmmBspEntry(SmmEntryInit); //BSP has not started, so use this as the BSP.
+ }
+
+ //reset flags before exiting.
+ gEntrySemaphore = FALSE;
+ gReleaseStartedCpus = FALSE; //This must be reset last because this releases APs to resume.
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: HoldStartedCpus
+//
+// Description:
+// Hold loop for CPU to sync. All but one CPU will enter here.
+//
+// Input:
+// IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID HoldStartedCpus(IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit)
+{
+ //Wait until trying to start all CPUs.
+ while(!gReleaseStartedCpus) CPULib_Pause();
+
+ //All CPUs have been started.
+ if (gUseSbsp) {
+ if (SmmEntryInit->CpuNo == gSbsp) SmmBspEntry(SmmEntryInit);
+ else SmmApEntry(SmmEntryInit);
+ } else {
+ SmmApEntry(SmmEntryInit);
+ }
+
+ //Wait until flags are reset by First CPU.
+ while (gReleaseStartedCpus) CPULib_Pause();
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmBspEntry
+//
+// Description: Call Smm call back or dispatch handlers.
+//
+// Input:
+// IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmBspEntry(IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit)
+{
+ static BOOLEAN DisallowCallbacks = FALSE;
+ UINT32 i;
+#if INTEL_MP_SW_SMI_PATCH == 1
+ EFI_SMM_CPU_SAVE_STATE *OrigCpuSaveState = 0;
+#endif
+ UINT32 CpuNo = SmmEntryInit->CpuNo;
+ BOOLEAN IsCallBackFunction = FALSE;
+
+#if SMM_USE_FRAMEWORK
+ gSmmSystemTable.CurrentlyExecutingCpu = CpuNo + 1;
+#endif
+ gDispatcherPrivate->SmmBspNumber = CpuNo;
+#if SMM_USE_PI
+ gEfiSmmEntryContext.CurrentlyExecutingCpu = CpuNo;
+ gSmmSystemTable2.CurrentlyExecutingCpu = CpuNo; //This 0-based, Framework is 1-based.
+#endif
+
+ //Copy save state area.
+#if SMM_USE_FRAMEWORK
+ CPU_GetSaveState(gSmmBase[CpuNo], &gSmmSystemTable.CpuSaveState[CpuNo].Ia32SaveState);
+#endif
+
+ //Indicates APs can execute function for a driver when released.
+ gReadyForApsToExecute = TRUE;
+
+ LockInc32((UINT32*)&gNumCpusReady);
+ while (gNumCpusReady < gDispatcherPrivate->NumCpusInSmm) CPULib_Pause();
+ gAllCpusInSync = TRUE;
+
+ //Make OEM Call to save state.
+ for (i = 0; SmmSaveRestoreFunctionTable[i] != NULL; ++i) SmmSaveRestoreFunctionTable[i](TRUE);
+
+ //Check if software smi, and the CPU that caused it.
+ gSwSmiCpuTrigger->Cpu = (UINTN)-1;
+
+ for(i = 0; i < gDispatcherPrivate->NumCpus; ++i) {
+ if (IsSwSmiTrigger(gSmmBase[i], SW_SMI_IO_ADDRESS)) {
+ UINT8 SwSmi = IoRead8(SW_SMI_IO_ADDRESS);
+#if SMM_USE_FRAMEWORK
+ if ( SwSmi == (UINT8)gSmmSystemTable.CpuSaveState[i].Ia32SaveState.EAX) {
+#else
+ UINT8 RegAl;
+ EFI_STATUS Status;
+ Status = gEfiSmmCpuProtocol.ReadSaveState(
+ &gEfiSmmCpuProtocol,
+ 1,
+ EFI_SMM_SAVE_STATE_REGISTER_RAX,
+ i,
+ &RegAl
+ );
+ if (EFI_ERROR(Status) || SwSmi == RegAl) { //Assume if error, then this is the correct CPU.
+#endif
+ gSwSmiCpuTrigger->Cpu = i;
+ break;
+ }
+ }
+ }
+
+//Intel only uses save state CpuSaveState[0] for software SMIs, event though it may
+//be generated by a AP. If INTEL_MP_SW_SMI_PATCH is enabled, it will temporarily,
+//set CpuSaveState[0] to the AP that generated SMI. However, this means CpuSaveState[x]
+//may be invalid.
+//
+//The PIWG should come up with a permanent solution.
+//
+#if INTEL_MP_SW_SMI_PATCH == 1
+ if ((INTN)gSwSmiCpuTrigger->Cpu > 0) {
+ OrigCpuSaveState = gSmmSystemTable.CpuSaveState;
+ gSmmSystemTable.CpuSaveState = &OrigCpuSaveState[gSwSmiCpuTrigger->Cpu];
+ gSwSmiCpuTrigger->Cpu = 0;
+ }
+#endif
+
+ if (gDispatcherPrivate->FloatingPointSave) {
+//The XMM is already before executing C because of possible optimizations.
+// _asm FXSAVE gSmmSystemTable.CpuOptionalFloatingPointState //Save Floating Point Context;
+ }
+
+ *gInSmm = TRUE; //SMM BASE protocol InSmm function returns this variable.
+ //This CallBackFunc is only called during boot services before shell.
+ if (!DisallowCallbacks) {
+ //Check both CallBackFunc and software smi.
+ //This is done in case asynchronous SMI occurs between setting up CallBackFunc and SW SMI.
+ IsCallBackFunction = gBasePrivate->CallBackFunc && IoRead8(SW_SMI_IO_ADDRESS) == SMMBASE_CALLBACK;
+
+ if (IsCallBackFunction) {
+ gBasePrivate->CallBackFunc();
+ gBasePrivate->CallBackFunc = 0;
+ if (gBasePrivate->DisallowCallbacks) DisallowCallbacks = TRUE;
+ }
+ }
+
+ gInitSemaphore = 0; //Clear this away from loop to be sure 2 CPUs don't do xchg.
+
+#if SMM_USE_PI
+ InterruptManage(NULL, NULL, &gEfiSmmEntryContext, &gEfiSmmEntryContextSize); //Execute root handlers
+#else
+ InterruptManage(NULL, NULL, NULL, NULL); //Execute root handlers
+#endif
+
+ *gInSmm = FALSE; //SMM BASE protocol InSmm function returns this variable.
+
+ if (gDispatcherPrivate->FloatingPointSave) {
+//The XMM is already before executing C because of possible optimizations.
+// _asm FXRSTOR gSmmSystemTable.CpuOptionalFloatingPointState //Restore Floating Point Context;
+ }
+
+ if (IsCallBackFunction) {
+ //This will clear the SW SMI Status. This is done last in case an incorrect
+ // implementation Clear, clears all statuses.
+ //
+ //This will not be called during runtime.
+#if SMM_USE_PI
+ ((EFI_SMM_CONTROL2_PROTOCOL*)gDispatcherPrivate->SmmControl)->Clear((EFI_SMM_CONTROL2_PROTOCOL*)gDispatcherPrivate->SmmControl, FALSE);
+#else
+ ((EFI_SMM_CONTROL_PROTOCOL*)gDispatcherPrivate->SmmControl)->Clear((EFI_SMM_CONTROL_PROTOCOL*)gDispatcherPrivate->SmmControl, FALSE);
+#endif
+ }
+
+//Restore CpuSaveState.
+#if INTEL_MP_SW_SMI_PATCH == 1
+ if(OrigCpuSaveState) gSmmSystemTable.CpuSaveState = OrigCpuSaveState;
+#endif
+
+ //Make OEM Call to restore state.
+ for (i = 0; SmmSaveRestoreFunctionTable[i] != NULL; ++i) SmmSaveRestoreFunctionTable[i](FALSE);
+
+#if SMM_USE_FRAMEWORK
+ //Copy save state area.
+ CPU_RestoreSaveState(gSmmBase[CpuNo], &gSmmSystemTable.CpuSaveState[CpuNo].Ia32SaveState);
+#endif
+
+ gReadyForApsToExecute = FALSE; //Used to indicate that BSP is exiting SMM mode.
+
+ LockDec32(&gDispatcherPrivate->NumCpusInSmm);
+ while(gDispatcherPrivate->NumCpusInSmm > 0) CPULib_Pause();
+
+ gNumCpusReady = 0; //Initialize count.
+ gAllCpusInSync = FALSE; //This must be set last. Releases CPUs from SmmApEntry.
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmApEntry
+//
+// Description: APs after switching to protected mode will jump here.
+//
+// Input:
+// IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmApEntry(IN SMM_ENTRY_INIT_STRUCT *SmmEntryInit)
+{
+ volatile SMM_AP_CPU_CONTROL *SmmApCpuControl = &gDispatcherPrivate->SmmApCpuControl[SmmEntryInit->CpuNo];
+ UINT32 CpuNo = SmmEntryInit->CpuNo;
+
+ //Copy save state area.
+#if SMM_USE_FRAMEWORK
+ CPU_GetSaveState(gSmmBase[CpuNo], &gSmmSystemTable.CpuSaveState[CpuNo].Ia32SaveState);
+#endif
+
+ LockInc32((UINT32*)&gNumCpusReady);
+ while(!gAllCpusInSync) CPULib_Pause();
+
+ while(gReadyForApsToExecute) {
+ if (SmmApCpuControl->Procedure) {
+ SmmApCpuControl->Procedure(SmmApCpuControl->ProcArguments);
+ SmmApCpuControl->Procedure = 0;
+ }
+ CPULib_Pause();
+ }
+
+#if SMM_USE_FRAMEWORK
+ CPU_RestoreSaveState(
+ (UINT8*)SmmEntryInit->SmmEntryStart - 0x8000,
+ &gSmmSystemTable.CpuSaveState[SmmEntryInit->CpuNo].Ia32SaveState
+ );
+#endif
+
+ LockDec32(&gDispatcherPrivate->NumCpusInSmm);
+
+ while(gAllCpusInSync) CPULib_Pause(); //Wait until BSP is ready.
+}
+
+
+//*******************************************************
+//EFI SMM Handler Return Code
+//*******************************************************
+#define EFI_HANDLER_SUCCESS 0x0000
+#define EFI_HANDLER_CRITICAL_EXIT 0x0001
+#define EFI_HANDLER_SOURCE_QUIESCED 0x0002
+#define EFI_HANDLER_SOURCE_PENDING 0x0003
+
+EFI_STATUS InterruptManage(
+ IN CONST EFI_GUID *HandlerType,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+)
+{
+ HANDLER_LIST *Link;
+#if SMM_USE_PI
+ EFI_STATUS Status = EFI_INTERRUPT_PENDING; //Default: Interrupt not handled.
+#else
+ EFI_STATUS Status = EFI_HANDLER_SUCCESS;
+#endif
+ EFI_STATUS HdlrStatus;
+
+ for (Link = gDispatcherPrivate->HandlerListHead; Link; Link = Link->Link) {
+ if (HandlerType == NULL) {
+ if (!Link->IsRoot) continue;
+ } else {
+ if (Link->IsRoot || (guidcmp((EFI_GUID*)HandlerType, &Link->HandlerType) != 0)) continue;
+ }
+
+#if SMM_USE_PI
+ if(Link->IsPi) {
+ HdlrStatus = ((SMM_HANDLER_ENTRY)Link->EntryPoint)(
+ Link->SmmImageHandle, Context, CommBuffer, CommBufferSize
+ );
+
+ //TODO: PI 1.1 spec SmiManage function EFI_SUCCESS description questionable.
+ //Review with PI work group.
+
+ switch(HdlrStatus) {
+ case EFI_WARN_INTERRUPT_SOURCE_PENDING:
+ break;
+ //TODO: Comment out for now because of build error related to core header files.
+ //case EFI_INTERRUPT_PENDING:
+ // return EFI_INTERRUPT_PENDING;
+ case EFI_WARN_INTERRUPT_SOURCE_QUIESCED:
+ Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; //Change status to interrupt handled.
+ break;
+ case EFI_SUCCESS:
+ if (Link->IsRoot) {
+ Status = EFI_WARN_INTERRUPT_SOURCE_QUIESCED; //Change status to interrupt handled.
+ break; //Continue checking other root handlers.
+ }
+ return EFI_WARN_INTERRUPT_SOURCE_QUIESCED;
+ default:
+ break;
+ }
+ }
+#endif
+#if 0//SMM_USE_FRAMEWORK
+ if (!Link->IsPi) {
+ HdlrStatus = ((EFI_SMM_CALLBACK_ENTRY_POINT)Link->EntryPoint)(
+ Link->SmmImageHandle, Link->CommunicationBuffer, Link->SourceSize
+ );
+ switch(HdlrStatus) {
+ case EFI_HANDLER_CRITICAL_EXIT:
+ case EFI_HANDLER_SOURCE_QUIESCED:
+ return EFI_HANDLER_CRITICAL_EXIT;
+ case EFI_HANDLER_SUCCESS:
+ case EFI_HANDLER_SOURCE_PENDING:
+ default:
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ #endif
+ }
+#if SMM_USE_FRAMEWORK
+ if (HandlerType == NULL)
+ {
+ for (Link = gDispatcherPrivate->HandlerListHead; Link; Link = Link->Link)
+ {
+ if (!Link->IsRoot)
+ continue;
+
+ if (!Link->IsPi)
+ {
+ HdlrStatus = ((EFI_SMM_CALLBACK_ENTRY_POINT)Link->EntryPoint)(Link->SmmImageHandle, Link->CommunicationBuffer, Link->SourceSize);
+ switch(HdlrStatus)
+ {
+ case EFI_HANDLER_CRITICAL_EXIT:
+ case EFI_HANDLER_SOURCE_QUIESCED:
+ return EFI_HANDLER_CRITICAL_EXIT;
+ case EFI_HANDLER_SUCCESS:
+ case EFI_HANDLER_SOURCE_PENDING:
+ default:
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+ }
+ }
+#endif
+ return Status;
+}
+
+
+//SMM thunk either requires AB Segment of CSM.
+#if SMM_THUNK_NO_AB_SEG == 0 || SMM_THUNK_IN_CSM == 1
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiSmmFarCall86Ex
+//
+// Description:
+// Smm Thunk call. If no stack, this will push flags to simulate int call.
+//
+// Input:
+// IN EFI_SMM_THUNK_PROTOCOL *This,
+// IN UINT16 Segment -16-bit segment to call
+// IN UINT16 Offset -16-bit offset to call
+// IN SMM_THUNK_IA32_REGISTER_SET_EX *Regs -Preload registers before call
+// IN VOID *Stack -Stack before call optional
+// IN UINTN StackSize - if no stack, this should be zero.
+//
+// Output: BOOLEAN
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN EfiSmmFarCall86Ex(
+ IN EFI_SMM_THUNK_PROTOCOL *This,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN SMM_THUNK_IA32_REGISTER_SET_EX *Regs,
+ IN VOID *Stack,
+ IN UINTN StackSize
+)
+{
+ SMM_THUNK_DATA *SmmThunkData = gDispatcherPrivate->SmmThunkData;
+
+#if SMM_THUNK_IN_CSM == 1
+ if (gDispatcherPrivate->EbdaStartOffset) {
+ UINT32 CurrentEbda = (UINT32)(UINTN)(*(UINT16*)0x40e << 4);
+ SmmThunkData =(SMM_THUNK_DATA *) (CurrentEbda + gDispatcherPrivate->EbdaStartOffset);
+ }
+#endif
+
+ SmmThunkData->FarCall.Segment = Segment;
+ SmmThunkData->FarCall.Offset = Offset;
+
+ //Copy address for stack
+ if (Stack) {
+ SmmThunkData->Stack.Stack = (UINT32)Stack;
+ SmmThunkData->Stack.StackSize = (UINT32)StackSize;
+ } else SmmThunkData->Stack.StackSize = 0;
+
+ //Copy thunk registers.
+ SmmThunkData->Regs = *Regs;
+
+ gDispatcherPrivate->SmmThunkProc(); //Do Far call.
+
+ //Restore thunk registers.
+ *Regs = SmmThunkData->Regs;
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiSmmFarCall86
+//
+// Description:
+// Smm Thunk call. If no stack, this will push flags to simulate int call.
+//
+// Input:
+// IN EFI_SMM_THUNK_PROTOCOL *This,
+// IN UINT16 Segment -16-bit segment to call
+// IN UINT16 Offset -16-bit offset to call
+// IN SMM_THUNK_IA32_REGISTER_SET *Regs -Preload registers before call
+// IN VOID *Stack -Stack before call optional
+// IN UINTN StackSize - if no stack, this should be zero.
+//
+// Output: BOOLEAN
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN EfiSmmFarCall86(
+ IN EFI_SMM_THUNK_PROTOCOL *This,
+ IN UINT16 Segment,
+ IN UINT16 Offset,
+ IN SMM_THUNK_IA32_REGISTER_SET *Regs,
+ IN VOID *Stack,
+ IN UINTN StackSize
+)
+{
+ SMM_THUNK_IA32_REGISTER_SET_EX RegsEx;
+ BOOLEAN RetValue;
+
+ RegsEx.X.AX = Regs->X.AX;
+ RegsEx.X.BX = Regs->X.BX;
+ RegsEx.X.CX = Regs->X.CX;
+ RegsEx.X.DX = Regs->X.DX;
+ RegsEx.X.SI = Regs->X.SI;
+ RegsEx.X.DI = Regs->X.DI;
+ RegsEx.X.Flags = Regs->X.Flags;
+ RegsEx.X.ES = Regs->X.ES;
+ RegsEx.X.CS = Regs->X.CS;
+ RegsEx.X.SS = Regs->X.SS;
+ RegsEx.X.DS = Regs->X.DS;
+ RegsEx.X.BP = Regs->X.BP;
+
+ RetValue = EfiSmmFarCall86Ex(
+ This,
+ Segment,
+ Offset,
+ &RegsEx,
+ Stack,
+ StackSize
+ );
+
+ Regs->X.AX = RegsEx.X.AX;
+ Regs->X.BX = RegsEx.X.BX;
+ Regs->X.CX = RegsEx.X.CX;
+ Regs->X.DX = RegsEx.X.DX;
+ Regs->X.SI = RegsEx.X.SI;
+ Regs->X.DI = RegsEx.X.DI;
+ Regs->X.Flags = RegsEx.X.Flags;
+ Regs->X.ES = RegsEx.X.ES;
+ Regs->X.CS = RegsEx.X.CS;
+ Regs->X.SS = RegsEx.X.SS;
+ Regs->X.DS = RegsEx.X.DS;
+ Regs->X.BP = RegsEx.X.BP;
+
+ return RetValue;
+}
+
+EFI_SMM_THUNK_PROTOCOL EfiSmmThunkProtocol = {EfiSmmFarCall86, EfiSmmFarCall86Ex};
+
+#endif
+
+#pragma pack (1)
+typedef struct {
+ UINT16 LoOffset;
+ UINT16 Segment;
+ UINT16 DescBits; //Will be set to 0x0f00 Present=1, DPL = 0, D = 1 (32bit)
+ UINT16 HiOffset;
+#ifdef EFIx64
+ UINT32 Hi32Offset;
+ UINT32 Rsv;
+#endif
+} INTR_GATE_DESC;
+
+typedef struct {
+ UINT8 MovAlOp;
+ UINT8 InterruptNum;
+ UINT8 JmpOp;
+ UINT8 RelOffset;
+} INT_ENTRY_POINT;
+
+INT_ENTRY_POINT gIntEntryTemplate = { //No global memory
+ 0xb0, //mov al, Int
+ 0, //Int
+ 0xeb, //jmp
+ 0xfe // to itself
+};
+
+typedef struct {
+ UINT8 PushEaxOp;
+ UINT8 MovAlOp;
+ UINT8 MovAlValue;
+ UINT8 OutAlOp;
+ UINT8 OutAlValue;
+ UINT8 PopEaxOp;
+#ifdef EFIx64
+ UINT8 Ext64Op;
+#endif
+ UINT8 IretValue;
+} EOI_TEMPLATE;
+
+EOI_TEMPLATE EoiTemplate = {
+ 0x50, //push eax/rax
+ 0xb0, 0x20, //mov al, 20h ;EOI
+ 0xe6, 0x20, //out 20h, al ;Sent Master EOI to interrupt controller.
+ 0x58, //pop eax/rax
+#ifdef EFIx64
+ 0x48, //Ext 64-bit Opcode.
+#endif
+ 0xcf //iret
+};
+
+#pragma pack()
+
+#define NUM_EXCEPTIONS 19
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitInterrupts
+//
+// Description:
+// Install Interrupt Handlers. Initialize the interrupt descriptors.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitInterrupts()
+{
+#if AMI_DEBUGGER_SUPPORT
+ CPULib_SaveIdt(&gDispatcherPrivate->Idt);
+ return;
+#else
+
+ UINT32 i;
+ UINT16 Segment;
+ INT_ENTRY_POINT *IntEntryPoint;
+ INTR_GATE_DESC *IntGateDescs;
+#ifdef EFIx64
+ UINT16 *DummyIrqHandler;
+#else
+ UINT8 *DummyIrqHandler;
+#endif
+
+ //Allocate memory for addresses of interrupt Handlers.
+ DummyIrqHandler = Allocate(0, sizeof(*DummyIrqHandler), 0);
+ ASSERT(DummyIrqHandler != NULL);
+
+#ifdef EFIx64
+ *DummyIrqHandler = 0xcf48; //IRET
+#else
+ *DummyIrqHandler = 0xcf;
+#endif
+
+ IntEntryPoint = Allocate(0, sizeof(INT_ENTRY_POINT) * NUM_EXCEPTIONS, 0);
+ ASSERT(IntEntryPoint != NULL);
+
+ //Initialize interrupt entry points using template.
+ for(i = 0; i < NUM_EXCEPTIONS; ++i) {
+ gIntEntryTemplate.InterruptNum = i;
+ IntEntryPoint[i] = gIntEntryTemplate;
+ }
+
+ //Alocate space for Interrupt Descriptor Table. 256 entries/8 bytes.
+ IntGateDescs = Allocate(0, 256 * sizeof(*IntGateDescs),0);
+ ASSERT(IntGateDescs != NULL);
+
+ Segment = GetCsSegment();
+
+ //Setup halts for exceptions.
+ for (i = 0 ; i < NUM_EXCEPTIONS; ++i) {
+ UINTN IntHndlrAddr = (UINTN)&IntEntryPoint[i];
+ if (i == 18) IntHndlrAddr = (UINTN)MachineCheckHandler;
+
+ IntGateDescs[i].LoOffset=(UINT16)IntHndlrAddr;
+ IntGateDescs[i].HiOffset=(UINT16)((UINT32)IntHndlrAddr >> 16);
+ IntGateDescs[i].Segment=Segment;
+ IntGateDescs[i].DescBits=0x8e00; //Present=1, DPL = 0, D = 1 (32bit)
+#ifdef EFIx64
+ IntGateDescs[i].Hi32Offset = 0;
+ IntGateDescs[i].Rsv = 0;
+#endif
+ }
+
+ //Initialize the rest for dummy irets except timer to be overwritten below.
+ for (; i < 256 ; ++i) {
+ IntGateDescs[i].LoOffset=(UINT16)DummyIrqHandler;
+ IntGateDescs[i].HiOffset=(UINT16)((UINT32)DummyIrqHandler >> 16);
+ IntGateDescs[i].Segment=Segment;
+ IntGateDescs[i].DescBits=0x8e00; //Present=1, DPL = 0, D = 1 (32bit)
+#ifdef EFIx64
+ IntGateDescs[i].Hi32Offset = 0;
+ IntGateDescs[i].Rsv = 0;
+#endif
+ }
+
+//Setup EOI for timer interrupt.
+ {
+ VOID *TimerEoi = Allocate(0, sizeof(EOI_TEMPLATE), 0);
+ ASSERT(TimerEoi != NULL);
+ MemCpy(TimerEoi, &EoiTemplate, sizeof(EOI_TEMPLATE));
+
+ IntGateDescs[MASTER_INTERRUPT_BASE].LoOffset=*(UINT16*)&TimerEoi;
+ IntGateDescs[MASTER_INTERRUPT_BASE].HiOffset=*(((UINT16*)&TimerEoi)+1);
+ }
+
+ gDispatcherPrivate->Idt.Base=(UINT32)(UINTN)IntGateDescs;
+#ifdef EFIx64
+ gDispatcherPrivate->Idt.Limit=16*256-1;
+#else
+ gDispatcherPrivate->Idt.Limit=8*256-1;
+#endif
+#endif
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: StartTimeout
+//
+// Description:
+// Initialize timeout for a specified about of time in uS.
+//
+// Input:
+// OUT SMM_TIMEOUT *Timeout
+// IN UINT32 Time
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS StartTimeout(OUT SMM_TIMEOUT *Timeout, IN UINT32 Time) //uS
+{
+ UINT64 TicksNeeded;
+ UINT64 EndValue;
+
+ //
+ // There are 3.58 ticks per us.
+ //
+ // TicksNeeded = Time * 358 / 100
+ //
+ TicksNeeded = Div64 (Mul64 (Time, 358), 100, NULL);
+
+ // Read ACPI Timer
+ Timeout->OldTimerValue = IoRead32(PM_TMR_BLK_ADDRESS);
+ EndValue = TicksNeeded + Timeout->OldTimerValue;
+
+ //
+ // Calculate Overflow and EndValue from FullEndValue,
+ // based on number of bits in ACPI Timer
+ //
+ Timeout->OverFlow = (UINT32)Shr64 (EndValue, NUM_BITS_IN_ACPI_TIMER);
+ Timeout->EndValue = ((UINT32)EndValue) & (UINT32)(((UINT64)1 << NUM_BITS_IN_ACPI_TIMER) - 1);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: HasItTimedOut
+//
+// Description:
+// Return EFI_TIMEOUT if timer has expired.
+//
+// Input:
+// IN OUT SMM_TIMEOUT *Timeout
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS HasItTimedOut(IN OUT SMM_TIMEOUT *Timeout)
+{
+ UINT32 TimerValue;
+
+ //Read ACPI Timer
+ TimerValue = IoRead32(PM_TMR_BLK_ADDRESS);
+
+ if (Timeout->OverFlow > 0) {
+ //
+ // See if the current timer value is less than the previous value.
+ // If it is, then the timer had wrapped around.
+ //
+ if (TimerValue < Timeout->OldTimerValue) {
+ --Timeout->OverFlow;
+ }
+
+ // Update OldTimerValue
+ Timeout->OldTimerValue = TimerValue;
+ return EFI_SUCCESS;
+ }
+
+ //
+ // See if the current timer value is less than the previous value.
+ // If it is, then we are done.
+ //
+ if (TimerValue < Timeout->OldTimerValue) return EFI_TIMEOUT;
+
+ // If we passed the EndValue, we are done.
+ if (TimerValue >= Timeout->EndValue) return EFI_TIMEOUT;
+
+ // Update OldTimerValue
+ Timeout->OldTimerValue = TimerValue;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GetNumOfCpusInsideSmm(
+ IN AMI_SMM_INFO_PROTOCOL *This,
+ OUT UINT32 *Cpus
+)
+{
+ if (Cpus == NULL) return EFI_INVALID_PARAMETER;
+ *Cpus = gDispatcherPrivate->NumCpusInSmm;
+ return EFI_SUCCESS;
+}
+
+AMI_SMM_INFO_PROTOCOL gAmiSmmInfo = {
+ 0, //Protocol Ver
+ GetNumOfCpusInsideSmm
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeDispatcher
+//
+// Description: Initialize Dispatcher.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitializeDispatcher(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN SMM_BASE_PRIVATE_STRUCT *BasePrivate,
+ IN SMM_DISPATCHER_PRIVATE_STRUCT *DispatcherPrivate,
+ OUT VOID **SmstTable,
+ OUT VOID **SmstTable2
+)
+{
+ //SwSmiCpuTrigger is temporary. When installed in the configuration table
+ // a copy will be made. The copy will be used.
+ SW_SMI_CPU_TRIGGER SwSmiCpuTrigger = {(UINTN)-1};
+ VOID *Address;
+ UINT8 *SmmAllocMemoryStart = BasePrivate->SmmAllocMemoryStart;
+ SMM_HOB *SmmHob = BasePrivate->SmmHob;
+ EFI_HANDLE Handle=NULL;
+ EFI_STATUS Status;
+ UINT32 i;
+//-------------------------------
+ InitAmiLib(ImageHandle, SystemTable);
+
+ gBasePrivate = BasePrivate;
+ gDispatcherPrivate = DispatcherPrivate;
+
+ gInSmm = gBasePrivate->InSmm; //Initialize pointer SMM BASE function InSmm to notify if inside of SMM.
+
+ InitializeMemoryManager(BasePrivate);
+
+ //Allocate Image
+ Address = Allocate(gBasePrivate->Pe32DispatcherImage, BasePrivate->Pe32DispatcherImageSize, 0);
+ ASSERT(Address != NULL);
+
+ InitInterrupts();
+
+ gSmmBase = (UINT8**)Allocate(0, sizeof(UINT8**) * SmmHob->NumCpus, 0);
+ ASSERT(gSmmBase != NULL);
+
+ gEfiSmmCpuSaveState.CpuSaveState = (EFI_SMM_CPU_STATE**)Allocate(0, sizeof(EFI_SMM_CPU_STATE*) * SmmHob->NumCpus, 0);
+ ASSERT(gEfiSmmCpuSaveState.CpuSaveState != NULL);
+
+/*
+ //Any Cpu number can be BSP.
+ for(i = 0; i < SmmHob->NumCpus; ++i) {
+ gSmmBase[i] = (UINT8*)(SmmHob->SmmBase[i]);
+ gEfiSmmCpuSaveState.CpuSaveState[i] = (EFI_SMM_CPU_STATE*)(SmmHob->SmmBase[i] + 0x10000-0x400);
+ }
+*/
+
+ //CPU Number 0 must be BSP.
+ gSmmBase[0] = (UINT8*)(SmmHob->SmmBase[SmmHob->Bsp]);
+ gEfiSmmCpuSaveState.CpuSaveState[0] = (EFI_SMM_CPU_STATE*)(SmmHob->SmmBase[SmmHob->Bsp] + 0x10000-0x400);
+
+
+ for(i = 0; i < SmmHob->NumCpus; ++i) {
+ static UINT32 ApNum = 0; //BSP is given CPU #0, and APs 1,2...
+ if (i == SmmHob->Bsp) continue;
+ ++ApNum;
+
+ gSmmBase[ApNum] = (UINT8*)(SmmHob->SmmBase[i]);
+ gEfiSmmCpuSaveState.CpuSaveState[ApNum] = (EFI_SMM_CPU_STATE*)(SmmHob->SmmBase[i] + 0x10000-0x400);
+ }
+
+ gSmmEntryData = (SMM_ENTRY_INIT_STRUCT *) (gSmmBase[0] + 0x8004);
+ gSmmEntryData->DispatcherEntry = CommonEntry;
+ gSmmEntryData->DispatcherPrivate = DispatcherPrivate;
+
+ gSbsp = 0;//SmmHob->Bsp;
+
+ InitCrc();
+#if SMM_USE_PI
+ InitializeSmmPiSystemTable();
+#endif
+#if SMM_USE_FRAMEWORK
+ InitializeSmmSystemTable();
+#endif
+
+
+//If installed, it will install on both SMST tables.
+#if SMM_USE_PI
+ Status = gSmmSystemTable2.SmmInstallConfigurationTable(
+ &gSmmSystemTable2,
+ &gSwSmiCpuTriggerGuid,
+ &SwSmiCpuTrigger,
+ sizeof(SW_SMI_CPU_TRIGGER)
+ );
+ ASSERT_EFI_ERROR(Status);
+#else
+ Status = gSmmSystemTable.SmmInstallConfigurationTable(
+ &gSmmSystemTable,
+ &gSwSmiCpuTriggerGuid,
+ &SwSmiCpuTrigger,
+ sizeof(SW_SMI_CPU_TRIGGER)
+ );
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+#if SMM_USE_PI
+ gSwSmiCpuTrigger = gSmmSystemTable2.SmmConfigurationTable[0].VendorTable;
+#else
+ gSwSmiCpuTrigger = gSmmSystemTable.SmmConfigurationTable[0].VendorTable;
+#endif
+
+#if SMM_USE_FRAMEWORK
+ *SmstTable = &gSmmSystemTable;
+#endif
+#if SMM_USE_PI
+ *SmstTable2 = &gSmmSystemTable2;
+#endif
+
+#if SMM_USE_FRAMEWORK
+ pBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gAmiSmmInfoProtcolGuid, &gAmiSmmInfo,
+ &gEfiSmmCpuSaveStateProtocolGuid, &gEfiSmmCpuSaveState,
+//SMM thunk either requires AB Segment or CSM.
+#if SMM_THUNK_NO_AB_SEG == 0 || SMM_THUNK_IN_CSM == 1
+ &gEfiSmmThunkProtocolGuid, &EfiSmmThunkProtocol,
+#endif
+ NULL
+ );
+#endif
+
+#if SMM_USE_PI
+ Handle = NULL;
+ gSmmSystemTable2.SmmInstallProtocolInterface(
+ &Handle,
+ &gAmiSmmInfoProtcolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gAmiSmmInfo
+ );
+
+ Handle = NULL;
+ gSmmSystemTable2.SmmInstallProtocolInterface(
+ &Handle,
+ &gEfiSmmCpuSaveStateProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gEfiSmmCpuSaveState
+ );
+
+#if SMM_THUNK_NO_AB_SEG == 0 || SMM_THUNK_IN_CSM == 1
+ Handle = NULL;
+ gSmmSystemTable2.SmmInstallProtocolInterface(
+ &Handle,
+ &gEfiSmmThunkProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &EfiSmmThunkProtocol
+ );
+#endif
+
+ Handle = NULL;
+ gSmmSystemTable2.SmmInstallProtocolInterface(
+ &Handle,
+ &gEfiCpuIo2ProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gSmmSystemTable2.SmmIo
+ );
+
+ Handle = NULL;
+ gSmmSystemTable2.SmmInstallProtocolInterface(
+ &Handle,
+ &gEfiCpuProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gEfiSmmCpuProtocol
+ );
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmDispatcher.cif b/Core/EM/SMM/SmmDispatcher.cif
new file mode 100644
index 0000000..cada3c7
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcher.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "SmmDispatcher"
+ category = ModulePart
+ LocalRoot = "Core\EM\SMM"
+ RefName = "SmmDispatcher"
+[files]
+"SmmDispatcher.sdl"
+"SmmDispatcher.mak"
+"SmmEntry.asm"
+"SmmDispatcher.h"
+"SmmDispatcher.c"
+"Smst.c"
+"SmmPiSmst.c"
+"SmmMemoryManager.c"
+"SmmDispatcherAsm.asm"
+"SmmDispatcher.dxs"
+<endComponent>
diff --git a/Core/EM/SMM/SmmDispatcher.dxs b/Core/EM/SMM/SmmDispatcher.dxs
new file mode 100644
index 0000000..fd931d5
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcher.dxs
@@ -0,0 +1,59 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcher.dxs 2 8/05/09 3:04p Markw $
+//
+// $Revision: 2 $
+//
+// $Date: 8/05/09 3:04p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcher.dxs $
+//
+// 2 8/05/09 3:04p Markw
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmDispatcher.dxs
+//
+// Description: Dependency file for the SMM dispatcher
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+DEPENDENCY_START
+ FALSE
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmDispatcher.h b/Core/EM/SMM/SmmDispatcher.h
new file mode 100644
index 0000000..2b0f07c
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcher.h
@@ -0,0 +1,253 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcher.h 2 2/07/11 3:29p Markw $
+//
+// $Revision: 2 $
+//
+// $Date: 2/07/11 3:29p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcher.h $
+//
+// 2 2/07/11 3:29p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmDispatcher.h
+//
+// Description: SmmDispatcher header file
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __SMM_DISPATCHER__H__
+#define __SMM_DISPATCHER__H__
+
+#include <SmmPi.h>
+#include <AmiLib.h>
+
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#ifndef _CR
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+#endif
+
+#ifndef CR
+#define CR(record, TYPE, field, signature) _CR(record, TYPE, field)
+#endif
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
+#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+//---- Added from Core\Tiano.h
+
+
+//
+// SMM_HANDLER - used for each SMM handler
+//
+
+#define SMI_ENTRY_SIGNATURE SIGNATURE_32('s','m','i','e')
+
+ typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY AllEntries; // All entries
+
+ EFI_GUID HandlerType; // Type of interrupt
+ EFI_LIST_ENTRY SmiHandlers; // All handlers
+} SMM_SMI_ENTRY;
+
+#define SMI_HANDLER_SIGNATURE SIGNATURE_32('s','m','i','h')
+
+typedef struct {
+ UINTN Signature;
+ EFI_LIST_ENTRY Link; // Link on SMI_ENTRY.SmiHandlers
+ EFI_SMM_HANDLER_ENTRY_POINT2 Handler; // The smm handler's entry point
+ SMM_SMI_ENTRY *SmiEntry;
+} SMM_SMI_HANDLER;
+
+
+
+
+#define SMM_EFI_HANDLE_SIGNATURE SIGNATURE_32('S','h','n','d')
+//#define ASSERT_IS_HANDLE(a) ASSERT((a)->Signature == EFI_HANDLE_SIGNATURE)
+
+#define SMM_PROTOCOL_ENTRY_SIGNATURE SIGNATURE_32('S','p','r','E')
+
+#define SMM_SMST_SIGNATURE2 SIGNATURE_32('S','M','T','2')
+
+
+#ifndef EFI_LIST_ENTRY_DEFINED
+#define EFI_LIST_ENTRY_DEFINED
+typedef struct _EFI_LIST_ENTRY {
+ struct _EFI_LIST_ENTRY *ForwardLink;
+ struct _EFI_LIST_ENTRY *BackLink;
+} EFI_LIST_ENTRY;
+#endif
+
+
+typedef struct {
+ UINTN Signature;
+ /// All handles list of IHANDLE
+ EFI_LIST_ENTRY AllHandles;
+ /// List of PROTOCOL_INTERFACE's for this handle
+ EFI_LIST_ENTRY Protocols;
+ UINTN LocateRequest;
+} SMM_IHANDLE;
+
+
+
+typedef struct {
+ UINTN Signature;
+ /// Link Entry inserted to mProtocolDatabase
+ EFI_LIST_ENTRY AllEntries;
+ /// ID of the protocol
+ EFI_GUID ProtocolID;
+ /// All protocol interfaces
+ EFI_LIST_ENTRY Protocols;
+ /// Registerd notification handlers
+ EFI_LIST_ENTRY Notify;
+} SMM_PROTOCOL_ENTRY;
+
+
+#define SMM_PROTOCOL_INTERFACE_SIGNATURE SIGNATURE_32('S','p','i','f')
+
+typedef struct {
+ UINTN Signature;
+ /// Link on IHANDLE.Protocols
+ EFI_LIST_ENTRY Link;
+ /// Back pointer
+ SMM_IHANDLE *Handle;
+ /// Link on PROTOCOL_ENTRY.Protocols
+ EFI_LIST_ENTRY ByProtocol;
+ /// The protocol ID
+ SMM_PROTOCOL_ENTRY *Protocol;
+ /// The interface value
+ VOID *Interface;
+} SMM_PROTOCOL_INTERFACE;
+
+#define SMM_PROTOCOL_NOTIFY_SIGNATURE ('S','p','r','n')
+
+typedef struct {
+ UINTN Signature;
+ SMM_PROTOCOL_ENTRY *Protocol;
+ /// All notifications for this protocol
+ EFI_LIST_ENTRY Link;
+ /// Notification function
+ EFI_SMM_NOTIFY_FN Function;
+ /// Last position notified
+ EFI_LIST_ENTRY *Position;
+} SMM_PROTOCOL_NOTIFY;
+
+typedef struct {
+ EFI_GUID *Protocol;
+ VOID *SearchKey;
+ EFI_LIST_ENTRY *Position;
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+} SMM_LOCATE_POSITION;
+
+typedef
+SMM_IHANDLE *
+(* SMM_CORE_GET_NEXT) (
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+ );
+
+VOID
+SmmNotifyProtocol (
+ IN SMM_PROTOCOL_INTERFACE *Prot
+ );
+
+EFI_STATUS
+SmmSmstInstallProtocolInterfaceNotify (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface,
+ IN BOOLEAN Notify
+ );
+
+EFI_STATUS
+EFIAPI
+SmmSmstHandleProtocol (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+ );
+
+
+EFI_STATUS
+EFIAPI
+SmmSmstLocateProtocol (
+ IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface
+ );
+
+EFI_STATUS
+EFIAPI
+SmmUninstallProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ );
+
+SMM_PROTOCOL_INTERFACE *
+SmmRemoveInterfaceFromProtocol (
+ IN SMM_IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ );
+
+
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmDispatcher.mak b/Core/EM/SMM/SmmDispatcher.mak
new file mode 100644
index 0000000..241d939
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcher.mak
@@ -0,0 +1,127 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcher.mak 9 2/07/11 3:29p Markw $
+#
+# $Revision: 9 $
+#
+# $Date: 2/07/11 3:29p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcher.mak $
+#
+# 9 2/07/11 3:29p Markw
+# [TAG] EIP53481
+# [Category] New Feature
+# [Description] Add PIWG 1.1 SMM support
+# [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+# SmmDispatcher.h, SmmDispatcher.c,
+# Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+# SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+# Smm Pi Protocol files, SmmPciRbio files
+#
+# 8 7/08/09 9:28p Markw
+# Update headers.
+#
+# 7 3/05/09 5:20p Fasihm
+# Rolled back accidental check-in.
+#
+# 5 8/28/08 3:52p Markw
+#
+# 4 6/09/08 5:48p Markw
+# Add SmmDispatcherBoard.obj and SmmDispatcherAsm.obj to be linked.
+#
+# 3 10/24/07 12:01p Markw
+# Combined BSP and AP SmmEntry.
+#
+# 2 8/24/06 3:28p Felixp
+# Preliminary x64 support (work in progress)
+#
+# 1 1/28/05 4:32p Sivagarn
+# SMM Dispatcher Component - Initial check in
+#
+#
+#**********************************************************************
+
+#<AMI_FHDR_START>
+#---------------------------------------------------------------------------
+#
+# Name: SmmDispatcher.mak
+#
+# Description: Make file for the SMM Dispatcher
+#
+#---------------------------------------------------------------------------
+#<AMI_FHDR_END>
+SMM_DISPATCHER_BUILD_DIR = $(BUILD_DIR)\$(SMM_DISPATCHER_DIR)
+
+all : SmmDispatcher SmmEntry
+
+SMM_DISPATCHER_OBJECTS = \
+ $(SMM_DISPATCHER_BUILD_DIR)\SmmDispatcher.obj \
+ $(SMM_DISPATCHER_BUILD_DIR)\Smst.obj \
+ $(SMM_DISPATCHER_BUILD_DIR)\SmmPiSmst.obj \
+ $(SMM_DISPATCHER_BUILD_DIR)\SmmMemoryManager.obj \
+ $(SMM_DISPATCHER_BUILD_DIR)\SmmDispatcherAsm.obj
+
+SmmDispatcher : $(BUILD_DIR)\SmmDispatcher.mak SmmDispatcherBin
+SmmEntry : $(BUILD_DIR)\SmmDispatcher.mak SmmEntryBin
+
+$(BUILD_DIR)\SmmDispatcher.mak : $(SMM_DISPATCHER_DIR)\$(@B).cif $(SMM_DISPATCHER_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SMM_DISPATCHER_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+!IFNDEF PI_SPECIFICATION_VERSION
+PI_SPECIFICATION_VERSION = 0
+!ENDIF
+
+SmmDispatcherBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmmDispatcher.mak all\
+# Don't change the GUID. SmmBase driver expects this GUID.
+ GUID=4A37320B-3FB3-4365-9730-9E89C600395D\
+ ENTRY_POINT=InitializeDispatcher \
+!IF $(PI_SPECIFICATION_VERSION) >= 0x00001000A
+ TYPE=SMM_CORE \
+!ELSE
+ TYPE=BS_DRIVER \
+!ENDIF
+ "OBJECTS=$(SMM_DISPATCHER_OBJECTS)"\
+ "EXT_HEADERS=$(SMM_DISPATCHER_DIR)\SmmPrivateShared.h"\
+ "CFLAGS=$(CFLAGS) /D\"SmmSaveRestoreEnvironment=$(SmmSaveRestoreEnvironment)\""\
+ COMPRESS=1\
+
+SmmEntryBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SmmDispatcher.mak all\
+# Don't change the GUID. SmmBase driver expects this GUID.
+ GUID=D2596F82-F0E1-49fa-95BC-62012C795728\
+ MAKEFILE=$(SMM_DISPATCHER_DIR)\SmmDispatcher.mak \
+ TYPE=LEGACY16 NAME=SmmEntry DEPEX1= \
+ "OBJECTS=$(SMM_DISPATCHER_BUILD_DIR)\SmmEntry.obj"\
+ COMPRESS=1\
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SMM/SmmDispatcher.sdl b/Core/EM/SMM/SmmDispatcher.sdl
new file mode 100644
index 0000000..5ec4c24
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcher.sdl
@@ -0,0 +1,35 @@
+TOKEN
+ Name = "SmmDispatcher_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SmmDispatcher support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "SMM_DISPATCHER_DIR"
+End
+
+MODULE
+ Help = "Includes SmmDispatcher.mak to Project"
+ File = "SmmDispatcher.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmmDispatcher.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SmmEntry.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SmmSaveRestoreEnvironment"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/EM/SMM/SmmDispatcherAsm.asm b/Core/EM/SMM/SmmDispatcherAsm.asm
new file mode 100644
index 0000000..1abc682
--- /dev/null
+++ b/Core/EM/SMM/SmmDispatcherAsm.asm
@@ -0,0 +1,196 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcherAsm.asm 4 10/03/11 2:53p Markw $
+;
+; $Revision: 4 $
+;
+; $Date: 10/03/11 2:53p $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmDispatcherAsm.asm $
+;
+; 4 10/03/11 2:53p Markw
+; Add SMM Machine Check handler.
+; Files: SmmDispatcher.c, SmmDispatcherAsm.asm
+;
+; 3 7/08/09 8:18p Markw
+; Update headers.
+;
+; 2 11/21/08 5:00p Markw
+; Add LockInc32 and LockDec32.
+;
+; 1 6/09/08 5:56p Markw
+; Assembly functions for Dispatcher.
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: SmmDispatcher.asm
+;
+; Description: File that contains assembly for Smm Dispatcher.
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+IFDEF EFIx64
+.code
+include token.equ
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: Xchg8
+;
+; Description: Exchange a value with a pointer and return the exchanged value.
+;
+; Input:
+; IN OUT volatile UINT8 * Pointer to value to exchange.
+; IN UINT8 Value to exchange.
+;
+; Output: UINT8 Exchanged Value
+;
+; Modified: Nothing
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+Xchg8 proc public
+ xchg dl, [rcx]
+ mov al, dl
+ ret
+Xchg8 endp
+
+;<AMI_PHDR_START>
+;---------------------------------------------------------------------------
+;
+; Procedure: LockInc32
+;
+; Description: Increment value at pointer locking address.
+;
+; Input: IN OUT UINT32 *ptr
+;
+; Output: None
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+LockInc32 proc public
+ lock inc dword ptr [rcx]
+ ret
+LockInc32 endp
+
+;<AMI_PHDR_START>
+;---------------------------------------------------------------------------
+;
+; Procedure: LockDec32
+;
+; Description: Decrement value at pointer locking address.
+;
+; Input: IN OUT UINT32 *ptr
+;
+; Output: None
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+LockDec32 proc public
+ lock dec dword ptr [rcx]
+ ret
+LockDec32 endp
+
+;<AMI_PHDR_START>
+;---------------------------------------------------------------------------
+;
+; Procedure: MachineCheckHandler
+;
+; Description: SMM Machine Check Handler
+;
+; Input: VOID
+;
+; Output: VOID
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+MachineCheckHandler proc public
+ push rax
+ push rcx
+ push rdx
+ mov ecx, 17ah ;IA32_MCG_STATUS
+ rdmsr
+ btr eax, 2 ;MCIP
+ wrmsr
+ pop rdx
+ pop rcx
+ pop rax
+ iretq
+MachineCheckHandler endp
+
+ELSE ;32-bits
+.586p
+.model small
+.code
+
+_Xchg8 proc public
+ mov al, [esp + 8]
+ mov edx, [esp + 4]
+ xchg al, [edx]
+ ret
+_Xchg8 endp
+
+_LockInc32 proc public
+ mov eax, [esp + 4]
+ lock inc dword ptr [eax]
+ ret
+_LockInc32 endp
+
+
+_LockDec32 proc public
+ mov eax, [esp + 4]
+ lock dec dword ptr [eax]
+ ret
+_LockDec32 endp
+
+_MachineCheckHandler proc public
+ push eax
+ push ecx
+ push edx
+ mov ecx, 17ah ;IA32_MCG_STATUS
+ rdmsr
+ btr eax, 2 ;MCIP
+ wrmsr
+ pop edx
+ pop ecx
+ pop eax
+ iretd
+_MachineCheckHandler endp
+
+ENDIF
+
+end
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2008, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/EM/SMM/SmmDriverDispatcher.c b/Core/EM/SMM/SmmDriverDispatcher.c
new file mode 100644
index 0000000..c5b4431
--- /dev/null
+++ b/Core/EM/SMM/SmmDriverDispatcher.c
@@ -0,0 +1,1694 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+/** SmmDriverDispatcher.c - Modified from Intel's SMM source.
+
+ Copyright (c) 2009, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmDriverDispatcher.c 6 2/13/12 4:42p Markw $
+//
+// $Revision: 6 $
+//
+// $Date: 2/13/12 4:42p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMBase/SmmDriverDispatcher.c $
+//
+// 6 2/13/12 4:42p Markw
+// [TAG] EIP83005
+// [Category] Improvement
+// [Description] Some framework based SMM libraries expect a DXE image
+// handle on input. However, PI 1.1 SMM drivers expect a SMM handle on
+// input.
+// Update code to provide proper EFI_HANDLE when calling SMM functions.
+//
+// [Files] SmmBase.c, SmmDriverDispatcher.c
+//
+// 5 1/10/12 12:58p Markw
+// [TAG] EIP78978
+// [Category] Improvement
+// [Description] Cleanup of SmmLoadImage function - removing unused and
+// removing unneeded variable initialization.
+// [Files] SmmDriverDispatcher.c
+//
+// 4 1/09/12 3:06p Markw
+// [TAG] EIP78978
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] SMM driver will authentication failed.
+// [RootCause] Incorrect device path as input parameter when checking
+// authentication.
+//
+// [Solution] Authentication is done twice. Remove redundant code.
+// Second authentication check is using the correct original device path.
+//
+// [Files] SmmDriverDispatcher.c
+//
+// 3 3/15/11 2:37p Markw
+// Copyright header update.
+//
+// 2 3/08/11 4:57p Markw
+// Header and spacing updates.
+//
+// 1 2/07/11 3:34p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmDriverDispatcher.c
+//
+// Description: Dispatch SMM Drivers
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//This include should come first.
+#include "SmmPrivateShared.h"
+#if SMM_USE_PI
+#include <SmmPi.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\Security.h>
+#include <Dxe.h>
+#include <Protocol\FirmwareVolume2.h>
+#include <Protocol\LoadedImage.h>
+#include <AmiDxeLib.h>
+#include <AmiLib.h>
+
+extern EFI_SMM_SYSTEM_TABLE2 *gSmstTable2;
+extern SMM_BASE_PRIVATE_STRUCT *gBasePrivate;
+extern BOOLEAN gRegisterForPi;
+
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#ifndef _CR
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+#endif
+
+#ifndef CR
+#define CR(record, TYPE, field, signature) _CR(record, TYPE, field)
+#endif
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define SIGNATURE_16(A, B) ((A) | (B << 8))
+#define SIGNATURE_32(A, B, C, D) (SIGNATURE_16 (A, B) | (SIGNATURE_16 (C, D) << 16))
+#define SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (SIGNATURE_32 (A, B, C, D) | ((UINT64) (SIGNATURE_32 (E, F, G, H)) << 32))
+//---- Added from Core\Tiano.h
+
+
+// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependency expression
+// to save time. A EFI_DEP_PUSH is evaluated one an
+// replaced with EFI_DEP_REPLACE_TRUE. If PI spec's Vol 2
+// Driver Execution Environment Core Interface use 0xff
+// as new DEPEX opcode. EFI_DEP_REPLACE_TRUE should be
+// defined to a new value that is not conflicting with PI spec.
+//
+#define EFI_DEP_REPLACE_TRUE 0xff
+
+/// Define the initial size of the dependency expression evaluation stack
+#define DEPEX_STACK_SIZE_INCREMENT 0x1000
+
+//
+//
+// EFI_DEP_BEFORE - If present, it must be the first and only opcode
+// EFI_DEP_AFTER - If present, it must be the first and only opcode
+// EFI_DEP_SOR - If present, it must be the first opcode
+// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependency expression
+// to save time. A EFI_DEP_PUSH is evaluated one an
+// replaced with EFI_DEP_REPLACE_TRUE
+//
+#define EFI_DEP_BEFORE 0x00
+#define EFI_DEP_AFTER 0x01
+#define EFI_DEP_PUSH 0x02
+#define EFI_DEP_AND 0x03
+#define EFI_DEP_OR 0x04
+#define EFI_DEP_NOT 0x05
+#define EFI_DEP_TRUE 0x06
+#define EFI_DEP_FALSE 0x07
+#define EFI_DEP_END 0x08
+#define EFI_DEP_SOR 0x09
+#define EFI_DEP_REPLACE_TRUE 0xff
+
+
+// Global stack used to evaluate dependency expressions
+BOOLEAN *mDepexEvaluationStack = NULL;
+BOOLEAN *mDepexEvaluationStackEnd = NULL;
+BOOLEAN *mDepexEvaluationStackPointer = NULL;
+
+#define LIST_ENTRY EFI_LIST_ENTRY
+
+//
+// The Driver List contains one copy of every driver that has been discovered.
+// Items are never removed from the driver list. List of EFI_SMM_DRIVER_ENTRY
+//
+LIST_ENTRY mDiscoveredList = INITIALIZE_LIST_HEAD_VARIABLE (mDiscoveredList);
+
+//
+// Queue of drivers that are ready to dispatch. This queue is a subset of the
+// mDiscoveredList.list of EFI_SMM_DRIVER_ENTRY.
+//
+LIST_ENTRY mScheduledQueue = INITIALIZE_LIST_HEAD_VARIABLE (mScheduledQueue);
+
+//
+// List of handles who's Fv's have been parsed and added to the mFwDriverList.
+//
+LIST_ENTRY mFvHandleList = INITIALIZE_LIST_HEAD_VARIABLE (mFvHandleList);
+
+//
+// Flag for the SMM Dispacher. TRUE if dispatcher is executing.
+//
+BOOLEAN gDispatcherRunning = FALSE;
+
+//
+// Flag for the SMM Dispacher. TRUE if there is one or more SMM drivers ready to be dispatched
+//
+BOOLEAN gRequestDispatch = FALSE;
+
+//
+// List of file types supported by dispatcher
+//
+EFI_FV_FILETYPE mSmmFileTypes[] = {
+ EFI_FV_FILETYPE_SMM,
+ EFI_FV_FILETYPE_COMBINED_SMM_DXE
+ //
+ // Note: DXE core will process the FV image file, so skip it in SMM core
+ // EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
+ //
+};
+
+typedef struct {
+ MEDIA_FW_VOL_FILEPATH_DEVICE_PATH File;
+ EFI_DEVICE_PATH_PROTOCOL End;
+} FV_FILEPATH_DEVICE_PATH;
+
+FV_FILEPATH_DEVICE_PATH mFvDevicePath;
+
+//
+// DXE Architecture Protocols
+//
+EFI_SECURITY_ARCH_PROTOCOL *mSecurity = NULL;
+
+//
+// SMM Dispatcher Data structures
+//
+#define KNOWN_HANDLE_SIGNATURE SIGNATURE_32('k','n','o','w')
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link; // mFvHandleList
+ EFI_HANDLE Handle;
+} KNOWN_HANDLE;
+
+//
+// Structure for recording the state of an SMM Driver
+//
+#define EFI_SMM_DRIVER_ENTRY_SIGNATURE SIGNATURE_32('s', 'd','r','v')
+
+#define LIST_ENTRY EFI_LIST_ENTRY
+
+typedef struct {
+ UINTN Signature;
+ LIST_ENTRY Link; // mDriverList
+
+ LIST_ENTRY ScheduledLink; // mScheduledQueue
+
+ EFI_HANDLE FvHandle;
+ EFI_GUID FileName;
+ EFI_DEVICE_PATH_PROTOCOL *FvFileDevicePath;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+
+ VOID *Depex;
+ UINTN DepexSize;
+
+ BOOLEAN Before;
+ BOOLEAN After;
+ EFI_GUID BeforeAfterGuid;
+
+ BOOLEAN Dependent;
+ BOOLEAN Unrequested;
+ BOOLEAN Scheduled;
+ BOOLEAN Untrusted;
+ BOOLEAN Initialized;
+ BOOLEAN DepexProtocolError;
+
+ EFI_HANDLE ImageHandle;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ //
+ // Image EntryPoint in SMRAM
+ //
+ EFI_PHYSICAL_ADDRESS ImageEntryPoint;
+ //
+ // Image Buffer in SMRAM
+ //
+ EFI_PHYSICAL_ADDRESS ImageBuffer;
+ //
+ // Image Page Number
+ //
+ UINTN NumberOfPage;
+} EFI_SMM_DRIVER_ENTRY;
+
+EFI_GUID gAprioriGuid=EFI_APRIORI_GUID;
+
+EFI_STATUS SmmDispatcher();
+
+EFI_HANDLE gThisImageHandle;
+
+EFI_STATUS EfiSmmRegister(
+ IN VOID *This,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath,
+ IN VOID *SourceBuffer OPTIONAL,
+ IN UINTN SourceSize,
+ OUT EFI_HANDLE *ImageHandle,
+ IN BOOLEAN LegacyIA32Binary OPTIONAL
+);
+
+//////////////////////////////////////////////////////////////////////
+// ----- PI 1.1 --------------------------------------------- START //
+//////////////////////////////////////////////////////////////////////
+
+#define SetDevicePathNodeLength(a,l) { \
+ (a)->Length[0] = (UINT8) (l); \
+ (a)->Length[1] = (UINT8) ((l) >> 8); \
+ }
+
+#define SetDevicePathEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH; \
+ (a)->SubType = END_ENTIRE_SUBTYPE; \
+ (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \
+ (a)->Length[1] = 0; \
+ }
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AllocatePool
+//
+// Description: Allocate memory.
+//
+// Input:
+// IN UINTN Size
+//
+// Output: VOID * - Address
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *AllocatePool(UINTN Size){
+ return Malloc(Size);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GrowDepexStack
+//
+// Description: Increase Depex Stack..
+//
+// Input: VOID
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GrowDepexStack(VOID)
+{
+ BOOLEAN *NewStack;
+ UINTN Size;
+
+ Size = DEPEX_STACK_SIZE_INCREMENT;
+ if (mDepexEvaluationStack != NULL) {
+ Size = Size + (mDepexEvaluationStackEnd - mDepexEvaluationStack);
+ }
+
+ NewStack = AllocatePool (Size * sizeof(BOOLEAN));
+ if (NewStack == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if (mDepexEvaluationStack != NULL) {
+ //
+ // Copy to Old Stack to the New Stack
+ //
+
+ MemCpy(
+ NewStack,
+ mDepexEvaluationStack,
+ (mDepexEvaluationStackEnd - mDepexEvaluationStack) * sizeof (BOOLEAN)
+ );
+
+ //
+ // Free The Old Stack
+ //
+ pBS->FreePool (mDepexEvaluationStack);
+ }
+
+ //
+ // Make the Stack pointer point to the old data in the new stack
+ //
+ mDepexEvaluationStackPointer = NewStack + (mDepexEvaluationStackPointer - mDepexEvaluationStack);
+ mDepexEvaluationStack = NewStack;
+ mDepexEvaluationStackEnd = NewStack + Size;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PushBool
+//
+// Description: Push boolean value to stack.
+//
+// Input: IN BOOLEAN Value
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PushBool(IN BOOLEAN Value)
+{
+ EFI_STATUS Status;
+
+ //
+ // Check for a stack overflow condition
+ //
+ if (mDepexEvaluationStackPointer == mDepexEvaluationStackEnd) {
+ //
+ // Grow the stack
+ //
+ Status = GrowDepexStack ();
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // Push the item onto the stack
+ //
+ *mDepexEvaluationStackPointer = Value;
+ mDepexEvaluationStackPointer++;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PopBool
+//
+// Description: Pop boolean value to stack.
+//
+// Input: OUT BOOLEAN *Value
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PopBool(OUT BOOLEAN *Value)
+{
+ //
+ // Check for a stack underflow condition
+ //
+ if (mDepexEvaluationStackPointer == mDepexEvaluationStack) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ //
+ // Pop the item off the stack
+ //
+ mDepexEvaluationStackPointer--;
+ *Value = *mDepexEvaluationStackPointer;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmIsSchedulable
+//
+// Description: Check if driver meets dependencies.
+//
+// Input: IN EFI_SMM_DRIVER_ENTRY *DriverEntry
+//
+// Output: BOOLEAN
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN SmmIsSchedulable (IN EFI_SMM_DRIVER_ENTRY *DriverEntry)
+{
+ EFI_STATUS Status;
+ UINT8 *Iterator;
+ BOOLEAN Operator;
+ BOOLEAN Operator2;
+ EFI_GUID DriverGuid;
+ VOID *Interface;
+
+ Operator = FALSE;
+ Operator2 = FALSE;
+
+ if (DriverEntry->After || DriverEntry->Before) {
+ //
+ // If Before or After Depex skip as SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter ()
+ // processes them.
+ //
+ return FALSE;
+ }
+
+ if (DriverEntry->Depex == NULL) {
+ //
+ // A NULL Depex means that the SMM driver is schedulable.
+ //
+ //ASSERT (FALSE);
+ return TRUE;
+ }
+
+ //
+ // Clean out memory leaks in Depex Boolean stack. Leaks are only caused by
+ // incorrectly formed DEPEX expressions
+ //
+ mDepexEvaluationStackPointer = mDepexEvaluationStack;
+
+ Iterator = DriverEntry->Depex;
+
+ while (TRUE) {
+ //
+ // Check to see if we are attempting to fetch dependency expression instructions
+ // past the end of the dependency expression.
+ //
+ if (((UINTN)Iterator - (UINTN)DriverEntry->Depex) >= DriverEntry->DepexSize) {
+ return FALSE;
+ }
+
+ //
+ // Look at the opcode of the dependency expression instruction.
+ //
+ switch (*Iterator) {
+ case EFI_DEP_BEFORE:
+ case EFI_DEP_AFTER:
+ //
+ // For a well-formed Dependency Expression, the code should never get here.
+ // The BEFORE and AFTER are processed prior to this routine's invocation.
+ // If the code flow arrives at this point, there was a BEFORE or AFTER
+ // that were not the first opcodes.
+ //
+ ASSERT (FALSE);
+ case EFI_DEP_SOR:
+ //
+ // These opcodes can only appear once as the first opcode. If it is found
+ // at any other location, then the dependency expression evaluates to FALSE
+ //
+ if (Iterator != DriverEntry->Depex) {
+ return FALSE;
+ }
+ //
+ // Otherwise, it is the first opcode and should be treated as a NOP.
+ //
+ break;
+ case EFI_DEP_PUSH:
+ //
+ // Push operator is followed by a GUID. Test to see if the GUID protocol
+ // is installed and push the boolean result on the stack.
+ //
+
+ MemCpy (&DriverGuid, Iterator + 1, sizeof (EFI_GUID));
+
+ Status = gSmstTable2->SmmLocateProtocol (&DriverGuid, NULL, &Interface);
+ if (EFI_ERROR (Status)) {
+ //
+ // For SMM Driver, it may depend on uefi protocols
+ //
+ Status = pBS->LocateProtocol (&DriverGuid, NULL, &Interface);
+ }
+
+ if (EFI_ERROR (Status)) {
+ Status = PushBool (FALSE);
+ } else {
+ *Iterator = EFI_DEP_REPLACE_TRUE;
+ Status = PushBool (TRUE);
+ }
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Iterator += sizeof (EFI_GUID);
+ break;
+ case EFI_DEP_AND:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PopBool (&Operator2);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PushBool ((BOOLEAN)(Operator && Operator2));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+ case EFI_DEP_OR:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PopBool (&Operator2);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PushBool ((BOOLEAN)(Operator || Operator2));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+ case EFI_DEP_NOT:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Status = PushBool ((BOOLEAN)(!Operator));
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+ case EFI_DEP_TRUE:
+ Status = PushBool (TRUE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+ case EFI_DEP_FALSE:
+ Status = PushBool (FALSE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ break;
+ case EFI_DEP_END:
+ Status = PopBool (&Operator);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+ return Operator;
+ case EFI_DEP_REPLACE_TRUE:
+ Status = PushBool (TRUE);
+ if (EFI_ERROR (Status)) {
+ return FALSE;
+ }
+
+ Iterator += sizeof (EFI_GUID);
+ break;
+ default:
+ goto Done;
+ }
+
+ //
+ // Skip over the Dependency Op Code we just processed in the switch.
+ // The math is done out of order, but it should not matter. That is
+ // we may add in the sizeof (EFI_GUID) before we account for the OP Code.
+ // This is not an issue, since we just need the correct end result. You
+ // need to be careful using Iterator in the loop as it's intermediate value
+ // may be strange.
+ //
+ Iterator++;
+ }
+
+ Done:
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiInitializeFwVolDevicepathNode
+//
+// Description: Create Firmware volume device path.
+//
+// Input:
+// IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode,
+// IN EFI_GUID *NameGuid
+
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EFIAPI EfiInitializeFwVolDevicepathNode (
+ IN OUT MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvDevicePathNode,
+ IN EFI_GUID *NameGuid
+)
+{
+ //
+ // EFI Specification extension on Media Device Path. MEDIA_FW_VOL_FILEPATH_DEVICE_PATH is adopted by UEFI later and added in UEFI2.10.
+ // In EdkCompatibility Package, we only support MEDIA_FW_VOL_FILEPATH_DEVICE_PATH that complies with
+ // EFI 1.10 and UEFI 2.10.
+ //
+
+ FvDevicePathNode->Header.Type = MEDIA_DEVICE_PATH;
+ FvDevicePathNode->Header.SubType = MEDIA_FV_FILEPATH_DP;
+ SetDevicePathNodeLength (&FvDevicePathNode->Header, sizeof (MEDIA_FW_VOL_FILEPATH_DEVICE_PATH));
+
+ MemCpy (&FvDevicePathNode->NameGuid, NameGuid, sizeof(EFI_GUID));
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmDisplayDiscoveredNotDispatched
+//
+// Description: Display to debug output drivers discovered, but not loaded.
+//
+// Input: VOID
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmDisplayDiscoveredNotDispatched(VOID)
+{
+ LIST_ENTRY *Link;
+ EFI_SMM_DRIVER_ENTRY *DriverEntry;
+
+ for (Link = mDiscoveredList.ForwardLink;Link !=&mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->Dependent) {
+ TRACE ((-1, "SMM Driver %g was discovered but not loaded!!\n", &DriverEntry->FileName));
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FvHasBeenProcessed
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN FvHasBeenProcessed (IN EFI_HANDLE FvHandle)
+{
+ LIST_ENTRY *Link;
+ KNOWN_HANDLE *KnownHandle;
+
+ for (Link = mFvHandleList.ForwardLink; Link != &mFvHandleList; Link = Link->ForwardLink) {
+ KnownHandle = CR(Link, KNOWN_HANDLE, Link, KNOWN_HANDLE_SIGNATURE);
+ if (KnownHandle->Handle == FvHandle) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FvIsBeingProcesssed
+//
+// Description: This firmware volume is marked as being processed.
+//
+// Input: IN EFI_HANDLE FvHandle
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FvIsBeingProcesssed(IN EFI_HANDLE FvHandle)
+{
+ KNOWN_HANDLE *KnownHandle;
+
+ KnownHandle = AllocatePool (sizeof (KNOWN_HANDLE));
+ ASSERT (KnownHandle != NULL);
+
+ KnownHandle->Signature = KNOWN_HANDLE_SIGNATURE;
+ KnownHandle->Handle = FvHandle;
+ InsertTailList (&mFvHandleList, &KnownHandle->Link);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmFvToDevicePath
+//
+// Description: Create device path for Driver.
+//
+// Input:
+// IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv
+// IN EFI_HANDLE FvHandle
+// IN EFI_GUID *DriverName
+//
+// Output: EFI_DEVICE_PATH_PROTOCOL *
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_DEVICE_PATH_PROTOCOL * SmmFvToDevicePath (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FileNameDevicePath;
+
+ //
+ // Remember the device path of the FV
+ //
+ Status = pBS->HandleProtocol(FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+ if (EFI_ERROR (Status)) {
+ FileNameDevicePath = NULL;
+ } else {
+ //
+ // Build a device path to the file in the FV to pass into gBS->LoadImage
+ //
+ EfiInitializeFwVolDevicepathNode (&mFvDevicePath.File, DriverName);
+ SetDevicePathEndNode (&mFvDevicePath.End);
+
+ //
+ // Note: FileNameDevicePath is in DXE memory
+ //
+ FileNameDevicePath = DPAdd (
+ FvDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *)&mFvDevicePath
+ );
+ }
+ return FileNameDevicePath;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmPreProcessDepex
+//
+// Description: Check driver dependencies for SOR, BEFORE, or AFTER, and update DriverEntry.
+//
+// Input: IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmPreProcessDepex (
+ IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
+)
+{
+ UINT8 *Iterator;
+
+ Iterator = DriverEntry->Depex;
+ if (*Iterator == EFI_DEP_SOR) {
+ DriverEntry->Unrequested = TRUE;
+ } else {
+ DriverEntry->Dependent = TRUE;
+ }
+
+ if (*Iterator == EFI_DEP_BEFORE) {
+ DriverEntry->Before = TRUE;
+ } else if (*Iterator == EFI_DEP_AFTER) {
+ DriverEntry->After = TRUE;
+ }
+
+ if (DriverEntry->Before || DriverEntry->After) {
+ MemCpy (&DriverEntry->BeforeAfterGuid, Iterator + 1, sizeof (EFI_GUID));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmGetDepexSectionAndPreProccess
+//
+// Description: Get driver depex section.
+//
+// Input: IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmGetDepexSectionAndPreProccess (
+ IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
+)
+{
+ EFI_STATUS Status;
+ EFI_SECTION_TYPE SectionType;
+ UINT32 AuthenticationStatus;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+
+ Fv = DriverEntry->Fv;
+
+ //
+ // Grab Depex info, it will never be free'ed.
+ // (Note: DriverEntry->Depex is in DXE memory)
+ //
+ SectionType = EFI_SECTION_SMM_DEPEX;
+ Status = Fv->ReadSection (
+ DriverEntry->Fv,
+ &DriverEntry->FileName,
+ SectionType,
+ 0,
+ &DriverEntry->Depex,
+ (UINTN *)&DriverEntry->DepexSize,
+ &AuthenticationStatus
+ );
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_PROTOCOL_ERROR) {
+ //
+ // The section extraction protocol failed so set protocol error flag
+ //
+ DriverEntry->DepexProtocolError = TRUE;
+ } else {
+ //
+ // If no Depex assume depend on all architectural protocols
+ //
+ DriverEntry->Depex = NULL;
+ DriverEntry->Dependent = TRUE;
+ DriverEntry->DepexProtocolError = FALSE;
+ }
+ } else {
+ //
+ // Set Before, After, and Unrequested state information based on Depex
+ // Driver will be put in Dependent or Unrequested state
+ //
+ SmmPreProcessDepex (DriverEntry);
+ DriverEntry->DepexProtocolError = FALSE;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmAddToDriverList
+//
+// Description: Add Driver to database for processing.
+//
+// Input:
+// IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv
+// IN EFI_HANDLE FvHandle
+// IN EFI_GUID *DriverName
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmAddToDriverList (
+ IN EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv,
+ IN EFI_HANDLE FvHandle,
+ IN EFI_GUID *DriverName
+)
+{
+ EFI_SMM_DRIVER_ENTRY *DriverEntry;
+
+ //
+ // Create the Driver Entry for the list. ZeroPool initializes lots of variables to
+ // NULL or FALSE.
+ //
+ DriverEntry = MallocZ(sizeof (EFI_SMM_DRIVER_ENTRY));
+ ASSERT (DriverEntry != NULL);
+
+ DriverEntry->Signature = EFI_SMM_DRIVER_ENTRY_SIGNATURE;
+ MemCpy(&DriverEntry->FileName, DriverName, sizeof(EFI_GUID));
+ DriverEntry->FvHandle = FvHandle;
+ DriverEntry->Fv = Fv;
+ DriverEntry->FvFileDevicePath = SmmFvToDevicePath (Fv, FvHandle, DriverName);
+
+ SmmGetDepexSectionAndPreProccess (DriverEntry);
+
+ InsertTailList (&mDiscoveredList, &DriverEntry->Link);
+ gRequestDispatch = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmLoadImage
+//
+// Description: Load driver into memory and give control.
+//
+// Input: IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI SmmLoadImage (
+ IN OUT EFI_SMM_DRIVER_ENTRY *DriverEntry
+)
+{
+ UINT32 AuthenticationStatus;
+ VOID *Buffer;
+ UINTN Size;
+ //UINTN PageCount;
+ EFI_GUID *NameGuid;
+ EFI_STATUS Status;
+ //EFI_HANDLE DeviceHandle;
+ //EFI_PHYSICAL_ADDRESS DstBuffer;
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ //PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+
+ Buffer = NULL;
+ Size = 0;
+ Fv = DriverEntry->Fv;
+ NameGuid = &DriverEntry->FileName;
+ FilePath = DriverEntry->FvFileDevicePath;
+
+ AuthenticationStatus = 0;
+
+ //
+ // Try reading PE32 section firstly
+ //
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_PE32,
+ 0,
+ &Buffer,
+ &Size,
+ &AuthenticationStatus
+ );
+
+/*
+ if (EFI_ERROR (Status)) {
+ //
+ // Try reading TE section secondly
+ //
+ Buffer = NULL;
+ Size = 0;
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_TE,
+ 0,
+ &Buffer,
+ &Size,
+ &AuthenticationStatus
+ );
+ }
+*/
+
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = pBS->FreePool (Buffer);
+ }
+ return Status;
+ }
+
+ gRegisterForPi = TRUE;
+ Status=EfiSmmRegister(NULL, FilePath, Buffer, Size,
+ &DriverEntry->ImageHandle, FALSE);
+ gRegisterForPi = FALSE;
+/*
+ //
+ // Initialize ImageContext
+ //
+ ImageContext.Handle = Buffer;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ //
+ // Get information about the image being loaded
+ //
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ return Status;
+ }
+ //
+ // if Loading module at Fixed Address feature is enabled, then cut out a memory range started from TESG BASE
+ // to hold the Smm driver code
+ //
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
+ //
+ // Get the fixed loading address assigned by Build tool
+ //
+ Status = GetPeCoffImageFixLoadingAssignedAddress (&ImageContext);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Since the memory range to load Smm core alreay been cut out, so no need to allocate and free this range
+ // following statements is to bypass SmmFreePages
+ //
+ PageCount = 0;
+ DstBuffer = (UINTN)gLoadModuleAtFixAddressSmramBase;
+ } else {
+ DEBUG ((EFI_D_INFO|EFI_D_LOAD, "LOADING MODULE FIXED ERROR: Failed to load module at fixed address. \n"));
+ //
+ // allocate the memory to load the SMM driver
+ //
+ PageCount = (UINTN)EFI_SIZE_TO_PAGES(ImageContext.ImageSize + ImageContext.SectionAlignment);
+ DstBuffer = (UINTN)(-1);
+
+ Status = SmmAllocatePages (
+ AllocateMaxAddress,
+ EfiRuntimeServicesCode,
+ PageCount,
+ &DstBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ return Status;
+ }
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
+ }
+ } else {
+ PageCount = (UINTN)EFI_SIZE_TO_PAGES(ImageContext.ImageSize + ImageContext.SectionAlignment);
+ DstBuffer = (UINTN)(-1);
+
+ Status = SmmAllocatePages (
+ AllocateMaxAddress,
+ EfiRuntimeServicesCode,
+ PageCount,
+ &DstBuffer
+ );
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ return Status;
+ }
+
+ ImageContext.ImageAddress = (EFI_PHYSICAL_ADDRESS)DstBuffer;
+ }
+ //
+ // Align buffer on section boundary
+ //
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~(ImageContext.SectionAlignment - 1);
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ SmmFreePages (DstBuffer, PageCount);
+ return Status;
+ }
+
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ SmmFreePages (DstBuffer, PageCount);
+ return Status;
+ }
+
+ //
+ // Flush the instruction cache so the image data are written before we execute it
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN) ImageContext.ImageAddress, (UINTN) ImageContext.ImageSize);
+
+ //
+ // Save Image EntryPoint in DriverEntry
+ //
+ DriverEntry->ImageEntryPoint = ImageContext.EntryPoint;
+ DriverEntry->ImageBuffer = DstBuffer;
+ DriverEntry->NumberOfPage = PageCount;
+
+ //
+ // Allocate a Loaded Image Protocol in EfiBootServicesData
+ //
+ Status = gBS->AllocatePool (EfiBootServicesData, sizeof (EFI_LOADED_IMAGE_PROTOCOL), (VOID **)&DriverEntry->LoadedImage);
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ SmmFreePages (DstBuffer, PageCount);
+ return Status;
+ }
+
+ //
+ // Fill in the remaining fields of the Loaded Image Protocol instance.
+ // Note: ImageBase is an SMRAM address that can not be accessed outside of SMRAM if SMRAM window is closed.
+ //
+ DriverEntry->LoadedImage->Revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
+ DriverEntry->LoadedImage->ParentHandle = gThisImageHandle;
+ DriverEntry->LoadedImage->SystemTable = pST;
+ DriverEntry->LoadedImage->DeviceHandle = DeviceHandle;
+
+ //
+ // Make an EfiBootServicesData buffer copy of FilePath
+ //
+ Status = gBS->AllocatePool (EfiBootServicesData, GetDevicePathSize (FilePath), (VOID **)&DriverEntry->LoadedImage->FilePath);
+ if (EFI_ERROR (Status)) {
+ if (Buffer != NULL) {
+ Status = gBS->FreePool (Buffer);
+ }
+ SmmFreePages (DstBuffer, PageCount);
+ return Status;
+ }
+ CopyMem (DriverEntry->LoadedImage->FilePath, FilePath, GetDevicePathSize (FilePath));
+
+ DriverEntry->LoadedImage->ImageBase = (VOID *)(UINTN)DriverEntry->ImageBuffer;
+ DriverEntry->LoadedImage->ImageSize = ImageContext.ImageSize;
+ DriverEntry->LoadedImage->ImageCodeType = EfiRuntimeServicesCode;
+ DriverEntry->LoadedImage->ImageDataType = EfiRuntimeServicesData;
+
+ //
+ // Create a new image handle in the UEFI handle database for the SMM Driver
+ //
+ DriverEntry->ImageHandle = NULL;
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &DriverEntry->ImageHandle,
+ &gEfiLoadedImageProtocolGuid, DriverEntry->LoadedImage,
+ NULL
+ );
+
+ //
+ // Print the load address and the PDB file name if it is available
+ //
+
+ // DEBUG_CODE_BEGIN ();
+#if EFI_DEBUG
+ {
+ UINTN Index;
+ UINTN StartIndex;
+ CHAR8 EfiFileName[256];
+
+
+ TRACE ((-1,
+ "Loading driver at 0x%11p EntryPoint=0x%11p ",
+ (VOID *)(UINTN) ImageContext.ImageAddress,
+ FUNCTION_ENTRY_POINT (ImageContext.EntryPoint)));
+
+
+ //
+ // Print Module Name by Pdb file path.
+ // Windows and Unix style file path are all trimmed correctly.
+ //
+ if (ImageContext.PdbPointer != NULL) {
+ StartIndex = 0;
+ for (Index = 0; ImageContext.PdbPointer[Index] != 0; Index++) {
+ if ((ImageContext.PdbPointer[Index] == '\\') || (ImageContext.PdbPointer[Index] == '/')) {
+ StartIndex = Index + 1;
+ }
+ }
+ //
+ // Copy the PDB file name to our temporary string, and replace .pdb with .efi
+ // The PDB file name is limited in the range of 0~255.
+ // If the length is bigger than 255, trim the redudant characters to avoid overflow in array boundary.
+ //
+ for (Index = 0; Index < sizeof (EfiFileName) - 4; Index++) {
+ EfiFileName[Index] = ImageContext.PdbPointer[Index + StartIndex];
+ if (EfiFileName[Index] == 0) {
+ EfiFileName[Index] = '.';
+ }
+ if (EfiFileName[Index] == '.') {
+ EfiFileName[Index + 1] = 'e';
+ EfiFileName[Index + 2] = 'f';
+ EfiFileName[Index + 3] = 'i';
+ EfiFileName[Index + 4] = 0;
+ break;
+ }
+ }
+
+ if (Index == sizeof (EfiFileName) - 4) {
+ EfiFileName[Index] = 0;
+ }
+ TRACE ((-1, "%a", EfiFileName)); // &Image->ImageContext.PdbPointer[StartIndex]));
+ }
+ TRACE ((-1, "\n"));
+ }
+// DEBUG_CODE_END ();
+#endif
+
+ //
+ // Free buffer allocated by Fv->ReadSection.
+ //
+ // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
+ // used the UEFI Boot Services AllocatePool() function
+ //
+*/
+ Status = pBS->FreePool(Buffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter
+//
+// Description: Add drivers on queue with before or after dependencies.
+//
+// Input: IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (
+ IN EFI_SMM_DRIVER_ENTRY *InsertedDriverEntry
+)
+{
+ LIST_ENTRY *Link;
+ EFI_SMM_DRIVER_ENTRY *DriverEntry;
+
+ //
+ // Process Before Dependency
+ //
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->Before && DriverEntry->Dependent) {
+ if (! guidcmp (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
+ //
+ // Recursively process BEFORE
+ //
+ SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ }
+ }
+ }
+
+ //
+ // Convert driver from Dependent to Scheduled state
+ //
+
+ InsertedDriverEntry->Dependent = FALSE;
+ InsertedDriverEntry->Scheduled = TRUE;
+ InsertTailList (&mScheduledQueue, &InsertedDriverEntry->ScheduledLink);
+
+ //
+ // Process After Dependency
+ //
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
+ if (DriverEntry->After && DriverEntry->Dependent) {
+ if (!guidcmp (&InsertedDriverEntry->FileName, &DriverEntry->BeforeAfterGuid)) {
+ //
+ // Recursively process AFTER
+ //
+ SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmDispatcher
+//
+// Description: Dispatch drivers that dependencies are met.
+//
+// Input: VOID
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmDispatcher(VOID)
+{
+ EFI_STATUS Status;
+ EFI_STATUS ReturnStatus;
+ LIST_ENTRY *Link;
+ EFI_SMM_DRIVER_ENTRY *DriverEntry;
+ BOOLEAN ReadyToRun;
+
+ if (!gRequestDispatch) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (gDispatcherRunning) {
+ //
+ // If the dispatcher is running don't let it be restarted.
+ //
+ return EFI_ALREADY_STARTED;
+ }
+
+ gDispatcherRunning = TRUE;
+ ReturnStatus = EFI_NOT_FOUND;
+
+ do {
+ //
+ // Drain the Scheduled Queue
+ //
+ while (!IsListEmpty (&mScheduledQueue)) {
+ DriverEntry = CR (
+ mScheduledQueue.ForwardLink,
+ EFI_SMM_DRIVER_ENTRY,
+ ScheduledLink,
+ EFI_SMM_DRIVER_ENTRY_SIGNATURE
+ );
+
+ //
+ // Load the SMM Driver image into memory. If the Driver was transitioned from
+ // Untrusted to Scheduled it would have already been loaded so we may need to
+ // skip the LoadImage
+ //
+ if (DriverEntry->ImageHandle == NULL) {
+ Status = SmmLoadImage (DriverEntry);
+
+ //
+ // Update the driver state to reflect that it's been loaded
+ //
+ if (EFI_ERROR (Status)) {
+ if (Status == EFI_SECURITY_VIOLATION) {
+ //
+ // Take driver from Scheduled to Untrusted state
+ //
+ DriverEntry->Untrusted = TRUE;
+ } else {
+ //
+ // The SMM Driver could not be loaded, and do not attempt to load or start it again.
+ // Take driver from Scheduled to Initialized.
+ //
+ // This case include the Never Trusted state if EFI_ACCESS_DENIED is returned
+ //
+ DriverEntry->Initialized = TRUE;
+ }
+
+ DriverEntry->Scheduled = FALSE;
+ RemoveEntryList (&DriverEntry->ScheduledLink);
+
+ //
+ // If it's an error don't try the StartImage
+ //
+ continue;
+ }
+ }
+
+ DriverEntry->Scheduled = FALSE;
+ DriverEntry->Initialized = TRUE;
+ RemoveEntryList (&DriverEntry->ScheduledLink);
+/*
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_BEGIN,
+ &DriverEntry->ImageHandle,
+ sizeof(DriverEntry->ImageHandle)
+ );
+
+ //
+ // For each SMM driver, pass NULL as ImageHandle
+ //
+ Status = ((EFI_IMAGE_ENTRY_POINT)(UINTN)DriverEntry->ImageEntryPoint)(DriverEntry->ImageHandle, pST);
+ if (EFI_ERROR(Status)){
+ SmmFreePages(DriverEntry->ImageBuffer, DriverEntry->NumberOfPage);
+ }
+
+ REPORT_STATUS_CODE_WITH_EXTENDED_DATA (
+ EFI_PROGRESS_CODE,
+ EFI_SOFTWARE_SMM_DRIVER | EFI_SW_PC_INIT_END,
+ &DriverEntry->ImageHandle,
+ sizeof(DriverEntry->ImageHandle)
+ );
+*/
+ ReturnStatus = EFI_SUCCESS;
+ }
+
+ //
+ // Search DriverList for items to place on Scheduled Queue
+ //
+ ReadyToRun = FALSE;
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
+
+ if (DriverEntry->DepexProtocolError){
+ //
+ // If Section Extraction Protocol did not let the Depex be read before retry the read
+ //
+ Status = SmmGetDepexSectionAndPreProccess (DriverEntry);
+ }
+
+ if (DriverEntry->Dependent) {
+ if (SmmIsSchedulable (DriverEntry)) {
+ SmmInsertOnScheduledQueueWhileProcessingBeforeAndAfter (DriverEntry);
+ ReadyToRun = TRUE;
+ }
+ }
+ }
+ } while (ReadyToRun);
+
+ //
+ // If there is no more SMM driver to dispatch, stop the dispatch request
+ //
+ gRequestDispatch = FALSE;
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR (Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
+
+ if (!DriverEntry->Initialized){
+ //
+ // We have SMM driver pending to dispatch
+ //
+ gRequestDispatch = TRUE;
+ break;
+ }
+ }
+
+ gDispatcherRunning = FALSE;
+
+ return ReturnStatus;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmDriverDispatchHandler
+//
+// Description: Dispatch SMM drivers
+//
+// Input: VOID
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmDriverDispatchHandler ()
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ EFI_HANDLE *HandleBuffer;
+ EFI_STATUS GetNextFileStatus;
+ EFI_STATUS SecurityStatus;
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+ EFI_DEVICE_PATH_PROTOCOL *FvDevicePath;
+ EFI_HANDLE FvHandle;
+ EFI_GUID NameGuid;
+ UINTN Key;
+ EFI_FV_FILETYPE Type;
+ EFI_FV_FILE_ATTRIBUTES Attributes;
+ UINTN Size;
+ EFI_SMM_DRIVER_ENTRY *DriverEntry;
+ EFI_GUID *AprioriFile;
+ UINTN AprioriEntryCount;
+ UINTN Index;
+ LIST_ENTRY *Link;
+ UINT32 AuthenticationStatus;
+ UINTN SizeOfBuffer;
+
+ HandleBuffer = NULL;
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiFirmwareVolume2ProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+ if (EFI_ERROR (Status)) return; //return EFI_NOT_FOUND;
+
+ for (Index = 0; Index < HandleCount; Index++) {
+ FvHandle = HandleBuffer[Index];
+
+ if (FvHasBeenProcessed (FvHandle)) {
+ //
+ // This Fv has already been processed so lets skip it!
+ //
+ continue;
+ }
+
+ //
+ // Since we are about to process this Fv mark it as processed.
+ //
+ FvIsBeingProcesssed (FvHandle);
+
+ Status = pBS->HandleProtocol (FvHandle, &gEfiFirmwareVolume2ProtocolGuid, (VOID **)&Fv);
+ if (EFI_ERROR (Status)) {
+ //
+ // FvHandle must have a Firmware Volume2 Protocol thus we should never get here.
+ //
+ ASSERT (FALSE);
+ continue;
+ }
+
+ Status = pBS->HandleProtocol (FvHandle, &gEfiDevicePathProtocolGuid, (VOID **)&FvDevicePath);
+ if (EFI_ERROR (Status)) {
+ //
+ // The Firmware volume doesn't have device path, can't be dispatched.
+ //
+ continue;
+ }
+
+ //
+ // If the Security Architectural Protocol has not been located yet, then attempt to locate it
+ //
+ if (mSecurity == NULL) {
+ pBS->LocateProtocol (&gEfiSecurityArchProtocolGuid, NULL, (VOID**)&mSecurity);
+ }
+
+ //
+ // Evaluate the authentication status of the Firmware Volume through
+ // Security Architectural Protocol
+ //
+ if (mSecurity != NULL) {
+ SecurityStatus = mSecurity->FileAuthenticationState (
+ mSecurity,
+ 0,
+ FvDevicePath
+ );
+ if (SecurityStatus != EFI_SUCCESS) {
+ //
+ // Security check failed. The firmware volume should not be used for any purpose.
+ //
+ continue;
+ }
+ }
+
+ //
+ // Discover Drivers in FV and add them to the Discovered Driver List.
+ // Process EFI_FV_FILETYPE_SMM type and then EFI_FV_FILETYPE_COMBINED_SMM_DXE
+ //
+ for (Index = 0; Index < sizeof (mSmmFileTypes)/sizeof (EFI_FV_FILETYPE); Index++) {
+ //
+ // Initialize the search key
+ //
+ Key = 0;
+ do {
+ Type = mSmmFileTypes[Index];
+ GetNextFileStatus = Fv->GetNextFile (
+ Fv,
+ &Key,
+ &Type,
+ &NameGuid,
+ &Attributes,
+ &Size
+ );
+ if (!EFI_ERROR (GetNextFileStatus)) {
+ SmmAddToDriverList (Fv, FvHandle, &NameGuid);
+ }
+ } while (!EFI_ERROR (GetNextFileStatus));
+ }
+
+ //
+ // Read the array of GUIDs from the Apriori file if it is present in the firmware volume
+ // (Note: AprioriFile is in DXE memory)
+ //
+ AprioriFile = NULL;
+ Status = Fv->ReadSection (
+ Fv,
+ &gAprioriGuid,
+ EFI_SECTION_RAW,
+ 0,
+ (VOID **)&AprioriFile,
+ &SizeOfBuffer,
+ &AuthenticationStatus
+ );
+ if (!EFI_ERROR (Status)) {
+ AprioriEntryCount = SizeOfBuffer / sizeof (EFI_GUID);
+ } else {
+ AprioriEntryCount = 0;
+ }
+
+ //
+ // Put drivers on Apriori List on the Scheduled queue. The Discovered List includes
+ // drivers not in the current FV and these must be skipped since the a priori list
+ // is only valid for the FV that it resided in.
+ //
+
+ for (Index = 0; Index < AprioriEntryCount; Index++) {
+ for (Link = mDiscoveredList.ForwardLink; Link != &mDiscoveredList; Link = Link->ForwardLink) {
+ DriverEntry = CR(Link, EFI_SMM_DRIVER_ENTRY, Link, EFI_SMM_DRIVER_ENTRY_SIGNATURE);
+ if (!guidcmp (&DriverEntry->FileName, &AprioriFile[Index]) &&
+ (FvHandle == DriverEntry->FvHandle)
+ ){
+ DriverEntry->Dependent = FALSE;
+ DriverEntry->Scheduled = TRUE;
+ InsertTailList (&mScheduledQueue, &DriverEntry->ScheduledLink);
+ break;
+ }
+ }
+ }
+
+ //
+ // Free data allocated by Fv->ReadSection ()
+ //
+ // The UEFI Boot Services FreePool() function must be used because Fv->ReadSection
+ // used the UEFI Boot Services AllocatePool() function
+ //
+ pBS->FreePool (AprioriFile);
+ }
+
+ //
+ // Execute the SMM Dispatcher on any newly discovered FVs and previously
+ // discovered SMM drivers that have been discovered but not dispatched.
+ //
+ SmmDispatcher();
+}
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmDxeCommunicate.dxs b/Core/EM/SMM/SmmDxeCommunicate.dxs
new file mode 100644
index 0000000..24f46a0
--- /dev/null
+++ b/Core/EM/SMM/SmmDxeCommunicate.dxs
@@ -0,0 +1,69 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmDxeCommunicate.dxs 1 4/18/11 12:03p Markw $
+//
+// $Revision: 1 $
+//
+// $Date: 4/18/11 12:03p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SmmCommunicate/SmmDxeCommunicate.dxs $
+//
+// 1 4/18/11 12:03p Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Add SMM PI 1.1 Communicate Support.
+// [Files] SmmCommunicate.cif
+// SmmCommunicate.sdl
+// SmmCommunicate.c
+// SmmCommunicate.dxs
+// SmmDxeCommunicate.dxs
+// SmmCommunicate.mak
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmCommunicate.dxs
+//
+// Description: Dependency file for the SMM Communicate driver
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Protocol\SmmBase2.h>
+#include <Protocol\AmiInternalSmmComm.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ AMI_INT_SMM_COMM_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmEntry.asm b/Core/EM/SMM/SmmEntry.asm
new file mode 100644
index 0000000..883d1c6
--- /dev/null
+++ b/Core/EM/SMM/SmmEntry.asm
@@ -0,0 +1,1041 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2008, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/SmmEntry.asm 2 10/31/12 10:26a Wesleychen $
+;
+; $Revision: 2 $
+;
+; $Date: 10/31/12 10:26a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/SmmEntry.asm $
+;
+; 2 10/31/12 10:26a Wesleychen
+; Update SMM to 4.6.3_SMM_46.
+;
+; 1 10/22/12 7:08a Wesleychen
+; Support Intel PFAT.
+;
+; 58 4/01/11 10:33a Markw
+; [TAG] EIP57440
+; [Category] New Feature
+; [Description] Add PI 1.1 SMM support for reading/writing floating
+; point/smm save state.
+;
+; [Files] CpuCspLib.h, CpuCspLib.c, SmmPiSmst.c, SmmPrivateShared.h,
+; SmmHdr.equ, SmmInit.c, SmmEntry.asm
+;
+; 57 11/23/09 11:20a Markw
+; Update fxsave and fxrstor for 64-bit.
+;
+; 56 8/11/09 11:49a Markw
+; Removed Legacy registration. This is removed from latest PI and not
+; used by projects. Also, update clearing upper 32-bits of 64-bit
+; registers.
+;
+; 55 7/08/09 8:13p Markw
+; Update headers.
+;
+; 54 5/12/09 7:02p Markw
+; EIP #22087 - Always reinialize IDT in SMM even with AMI Debugger. Some
+; processors place junk value in IDT.
+;
+; 53 12/23/08 2:18p Markw
+; EIP #17900 Set up TSS. Borland C in DOS hangs otherwise.
+;
+; 52 11/21/08 4:57p Markw
+; Add SmmInit into SMM_ENTRY_STRUCT.
+;
+; 51 9/07/08 12:51a Markw
+;
+; 50 9/07/08 12:43a Markw
+; Separate SMM Private structure into inside SMM and outside SMM
+; structure.
+;
+; 49 8/27/08 9:05p Markw
+; Nehalem SMRR is now WB. Fix SMM Thunk Stack bug.
+;
+; 48 5/23/08 11:14a Markw
+; Don't load idt if AMI Debugger. Debugger won't work in SMM if idt is
+; reloaded.
+;
+; 47 4/04/08 6:22p Markw
+; User Smm Msr from SMM_BASE_PRIVATE_STRUCT instead of token.
+;
+; 46 3/03/08 6:36p Markw
+; Added 32-bit register for smm thunk.
+;
+; 45 1/07/08 1:58p Markw
+; For SMM thunk, read cs in 16-bit real mode instead of undefined CPU
+; execution between real and protected mode.
+; cs was invalid when read.
+;
+; 44 11/26/07 6:00p Markw
+; Fix bug in previous bug fix.
+;
+; 43 11/26/07 5:51p Markw
+; Fix smm thunk bug - store return address.
+;
+; 42 11/21/07 3:38p Markw
+; Update checking MKF_SMM_THUNK_IN_CSM condition from 1 to -1.
+;
+; 41 11/14/07 2:02p Markw
+; Added SMRR support and updated SMM Cache for non-SMRR.
+;
+; 40 10/29/07 3:24p Markw
+;
+; 39 10/29/07 10:58a Markw
+; Smm Thunk:
+; * Code and data different segments.
+; * Code position independent.
+; * Switch for CSM for code and EBDA for data.
+;
+; 38 10/24/07 12:02p Markw
+; SMM Thunk code position independent. Data in a separate segment than
+; code in Smm Thunk.
+; Combined BSP and AP SmmEntry.
+;
+; 37 9/10/07 1:39p Markw
+; Add Interrupt Handling in SMM.
+;
+; 36 6/14/07 10:54a Markw
+; In SmmThunk, jump condition is incorrect. pushf wasn't occurring before
+; iret call.
+;
+; 35 6/08/07 6:51p Markw
+; Save/Restore XMM.
+;
+; 34 4/13/07 11:04a Markw
+; Update header.
+;
+; 33 3/22/07 5:37p Markw
+; Set stack before calling legacy_handler.
+;
+; 32 3/12/07 11:24a Markw
+; Enable XMM for 32-bit. Guarantee 16-byte stack alignment.
+;
+; 31 3/06/07 10:40a Markw
+; Fix legacy handler calling entry point.
+;
+; 30 2/08/07 10:49a Markw
+; Preserve stack on legacy_handler.
+;
+; 29 1/11/07 12:31p Markw
+; Use switch to enable/disable legacy code during build.
+;
+; 28 1/10/07 2:12p Markw
+; Move legacy only code to end. Otherwise, if 64-bit BSP entry in TSEG,
+; APs will overlap part of smm bsp entry code.
+;
+; 27 1/09/07 6:47p Markw
+; Store fixup addresses in SmmEntry for locations that have to fixed-up
+; during BIOS.
+;
+; 26 1/09/07 11:47a Markw
+; Removed using MKF_SMM_BSP_BASE in memory access and segment changes.
+; Uses indexing or retf.
+;
+; 25 12/29/06 4:46p Markw
+; Update CPU syncronization.
+;
+; 24 12/11/06 5:53p Markw
+; Commented out initializing the flags because of potentional errors, and
+; using flags as input would be unusual.
+;
+; 23 11/13/06 7:15p Markw
+; Combine more common code between 32 and 64 bit.
+;
+; 22 11/10/06 3:18p Markw
+; Combined x32 and x64 where it is the same.
+;
+; 21 10/17/06 11:23a Davidd
+; Change made to not setting the Page Global Enable bit in CR4 to correct
+; the system reset problem when installing / booting Vista 32.
+;
+; 20 9/22/06 6:07p Markw
+; In 32-bit fix stack after calling dispatcher.
+;
+; 19 9/18/06 3:21p Markw
+; Updated 32 bit part for BSP an AP sync.
+;
+; 18 9/18/06 11:44a Markw
+; Add a check to guarentee that BSP and Ap can't get out of sync. Also
+; clear WT bit in cr0 in 64-bit.
+;
+; 17 8/25/06 10:49a Markw
+; Enable XMM for 64-bit.
+;
+; 16 8/24/06 3:28p Felixp
+; Preliminary x64 support (work in progress)
+;
+; 15 4/20/06 1:50p Markw
+; Fixed SmmThunk to use token for BSP SMM Base.
+; For SmmThunk calls that don't pass arguments on stack, added 3f to
+; emulate INT calls.
+;
+; 14 2/03/06 10:27a Markw
+; Moved Smm Base change to PEI CPU.
+; Added a token for SMM BSP Base Address.
+; Added IED support.
+;
+; 13 1/13/06 11:28a Markw
+; Added SMM Thunk support.
+;
+; 12 1/10/06 2:57p Markw
+; Add support for multi-threadding and sync all CPUs during entry/exit of
+; SMM.
+;
+; 11 11/03/05 5:35p Markw
+; Added entries to GDT for addional descriptors that Intel uses.
+;
+; 10 7/21/05 11:28a Srinin
+; Fixed Legacy SMI handler support.
+;
+; 8 7/19/05 8:00p Markw
+; Add support for calling real mode handlers.
+;
+; 7 7/12/05 3:14p Markw
+; Moved BSP entry from 0xa8000 to 0xa0000.
+;
+; 6 7/11/05 12:04p Markw
+; Removed setting isCallback. This simplified the dispatcher.
+;
+; 5 7/06/05 2:15p Markw
+; Commented out unused code.
+;
+; 4 4/07/05 4:05p Sivagarn
+; Corrected the make token issue
+;
+; 3 4/04/05 5:18p Sivagarn
+; Converted hard coded S/W SMI port to generic SDL token
+;
+; 1 1/28/05 4:32p Sivagarn
+; SMM Dispatcher Component - Initial check in
+;
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: SmmEntry.ASM
+;
+; Description: File that contains the code for BSP SMM entry point
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+.586p
+.model small
+.xmm
+
+include token.equ
+include SmmHdr.equ
+
+IFNDEF MKF_SMM_THUNK_IN_CSM
+MKF_SMM_THUNK_IN_CSM EQU 0
+ENDIF
+
+IFNDEF MKF_AMI_DEBUGGER_SUPPORT
+MKF_AMI_DEBUGGER_SUPPORT EQU 0
+ENDIF
+
+IA32_HANDLER_LIST STRUCT
+ Entry dd ?
+ Link dd ?
+IA32_HANDLER_LIST ENDS
+
+;org 8000h
+SMM SEGMENT USE16
+
+;<AMI_PHDR_START>
+;----------------------------------------------------------------------------
+;
+; Procedure: SmmEntry
+;
+; Description: Call any Legacy Handlers and call 32 bit protected Mode Dispatcher.
+;
+; Input: None
+;
+; Output: None
+;
+;----------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+;To make assembler happy.
+; SmmThunkData will have an address of 0, but a different segment.
+SmmThunkData equ $
+SmmEntry:
+ jmp SmmStart
+align 4
+SmmEntryData label dword
+ SmmEntryInit SMM_ENTRY_INIT_STRUCT < \
+ 1, \
+ SmmEntryEnd - SmmEntry, \
+ GDT_DESC_FIXUP - SmmEntry, \
+ L_CODE_SEL_FIXUP - SmmEntry, \
+ TSS_SEL_FIXUP - SmmEntry, \
+ THUNK - SmmEntry, \
+ SmmThunkEnd - THUNK, \
+ -1 \
+ >
+SmmStart:
+;Note use cs override on data access. This code may be executed above 1MB.
+ mov ax, cs
+ mov ds, ax
+ mov ss, ax
+ cld
+
+IF MKF_SMM_CACHE_SUPPORT
+IFNDEF MKF_NEHALEM_CPU_MODULE
+ ; *************** CACHE ENABLE **************
+;-----------
+;HT support
+;-----------
+ ;TODO: Move HT detection to SMM Base and out of SMM entry.
+
+ mov eax, -1
+ cmp cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).Ht0, eax
+ jne ht0_flag_is_init
+
+ mov eax, 1 ;default true
+ mov cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).Ht0, eax
+
+ mov eax, 1
+ cpuid
+ test edx, 1 SHL 28 ;Set if hyper-threading support.
+ jz ht0_flag_is_init
+ shr ebx, 16 ;After shift, bl = number of logical processors
+ movzx esi, bl ;Store # local processors.
+
+ mov eax, 4
+ xor ecx, ecx
+ cpuid
+ shr eax, 26
+ inc eax ;Number of Cores.
+
+ xor edx, edx ;clear for div.
+ xchg esi, eax ;esi = NumCores, eax = num #logical CPUS
+ div esi ;#logical CPUs / NumCores
+ cmp eax, 1
+ jle ht0_flag_is_init
+
+ mov ebx, MKF_LOCAL_APIC_BASE + MKF_APIC_ID_REGISTER
+ mov eax, es:[ebx]
+ bt eax, 24
+ jnc ht0_flag_is_init
+ xor eax, eax ;This not Ht0 flag, so clear.
+ mov cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).Ht0, eax
+ht0_flag_is_init:
+
+ mov esi, dword ptr cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).SmmDispatcherPrivateStruct
+
+ mov eax, cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).Ht0
+ or eax, eax
+ jz cache_enable_end ;skip if HT
+
+ mov al, 1
+ cmp es:(SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).SmrrEnable, al
+ jne non_smrr_cache
+ ;Disable SMRR.
+ mov ecx, es:(SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).SmrrMsr
+ inc ecx
+ rdmsr
+ btr ax, 11 ;Disable UC SMRR. This makes the region WT by overlapping MTRR.
+ wrmsr
+ jmp cache_enable_end
+
+non_smrr_cache:
+ mov ecx, es:(SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).TsegMsr
+ or ecx, ecx
+ jz cache_enable_end ;Not enough/or moved MTRR to support cache.
+
+ rdmsr
+ cmp eax, dword ptr es:(SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).TsegMsrBase
+ je @f
+ ;---Disable future cache. Validation failed.
+ xor ecx, ecx
+ mov es:(SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).TsegMsr, ecx
+ jmp cache_enable_end
+@@:
+ mov al, 4
+ wrmsr ;Make MTRR WT.
+;-----------------
+cache_enable_end:
+; ************** END CACHE ENABLE *************
+ENDIF
+ENDIF
+
+IFDEF MKF_PfatServices_SUPPORT
+IF MKF_PfatServices_SUPPORT
+ mov eax, cr0
+ or al, 20h ;Set NE bit
+ mov cr0, eax
+ENDIF
+ENDIF
+
+ mov esi, dword ptr cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).SmmDispatcherPrivateStruct
+ mov edi, dword ptr cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).SmmEntryStart
+ mov ebx, dword ptr cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).SmmDispatcherAddr
+ mov edx, dword ptr cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).CpuNo
+
+ mov byte ptr cs:TSS_SEL_FIXUP + 8000h + 3, 89h
+
+ ;Switch to protected mode
+ db 66h
+ lgdt fword ptr cs:GdtDescriptor + 8000h
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+ ;In 16 bit protected mode
+ jmp $+2 ;Clear prefetch queue
+
+ mov ax, DATA_SEL
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ xor ax, ax
+ lldt ax
+
+ str ax
+ or ax, ax
+ jz @f
+ mov ax,TSS_SEL
+ ltr ax
+@@:
+
+ ;Stack starts near bottom of Smm TSEG after BSP/AP entries
+ mov esp, dword ptr cs:(SMM_ENTRY_INIT_STRUCT ptr [SmmEntryInit + 8000h]).SmmStack
+ and esp, 0fffffff0h ;guarentee 16-byte stack.
+
+ ;set cs segment
+ lea eax, [edi + offset P32Mode]
+ pushd CODE32_SEL
+ push eax
+ db 66h
+ retf
+P32Mode::
+ mov eax, cr4
+ ;or eax, 0620h ;Enable XMM.
+ db 0dh
+ dd 0600h
+ mov cr4, eax
+
+ ;mov eax, dword ptr (SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).SmmXmmSave
+ db 8bh, 46h, SMM_DISPATCHER_PRIVATE_STRUCT.SmmXmmSave
+IFNDEF EFIx64
+ ;mov edx, [eax + 4 * edx]
+ db 8bh, 14h, 90h
+ELSE
+ ;mov edx, [eax + 8 * edx]
+ db 8bh, 14h, 0d0h
+ENDIF
+
+IFNDEF EFIx64
+ ;lidt fword ptr (SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).Idt
+ db 0fh, 1, 5eh
+ db SMM_DISPATCHER_PRIVATE_STRUCT.IDT
+
+ ;fxsave [edx]
+ db 0fh, 0aeh, 2
+ push dx ;push edx
+ sub sp, 12 ;sub esp, 12 -- make stack 16 byte aligned
+ ;Call Dispatcher
+
+ add di, 4 ;edi = SmmEntryInit
+ push di ;push edi ;Optimization will modify this stack location.
+ call bx ;call ebx ;SmmDispatcherAddr
+ add sp, 12 + 4 ;add esp, 12 + 4
+ pop dx ;pop edx
+ ;fxrstor [edx]
+ db 0fh, 0aeh, 0ah
+ELSE
+ push dx ;push edx This is read later directly from [esp]
+
+ ;mov eax, dword ptr (SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).PageDirectories
+ db 8bh, 86h
+ dd SMM_DISPATCHER_PRIVATE_STRUCT.PageDirectories
+ mov cr3, eax ;Set CR3 to first page directory pointer table
+
+ mov eax, cr4
+ or al, 20h ;Enable PAE.
+ mov cr4, eax
+
+ ;Enable long mode in msr register. Doesn't actually enter long mode yet.
+
+ ;mov ecx, 0c0000080h
+ db 0b9h
+ dd 0C0000080h
+ rdmsr
+ ;bts eax, 8
+ db 0Fh, 0BAh, 0E8h, 08h
+ wrmsr
+
+ ;Enable paging
+ mov eax, cr0
+ ;bts eax, 31
+ db 0Fh, 0BAh, 0E8h, 1fh
+ ;btr eax, 16 ;Clear WT bit. This affects paging.
+ db 0fh, 0bah, 0f0h, 10h
+ mov cr0, eax ;Now in long mode compatiblity.
+ jmp @f
+@@:
+
+ ;set cs segment
+ ;lea eax, [edi + offset long_mode_64]
+ db 8dh, 87h
+ dd offset long_mode_64
+ ;push CODE64_SEL
+ db 68h
+ dd CODE64_SEL
+ push ax ;push eax
+ retf
+
+long_mode_64:
+ ;in 64-bit long mode
+
+ ;mov rax, 0ffffffffh
+ db 48h, 0b8h
+ dq 0ffffffffh
+
+ db 48h
+ and bx, ax ;and rbx, rax
+ db 48h
+ and dx, ax ;and rdx, rax
+ db 48h
+ and si, ax ;and rsi, rax
+ db 48h
+ and di, ax ;and rdi, rax
+ db 48h
+ and sp, ax ;and esp, rax
+
+ ;mov edx, [rsp]
+ db 8bh, 14h, 24h
+ ;fxsave [rdx]
+ db 48h, 0fh, 0aeh, 2
+
+ ;align stack by 16-bytes, sub 0ch and reserve stack for caller.
+ sub sp, 0ch + 20h ;sub esp, 12 + 20
+
+ ;Call Dispatcher
+
+ ;lidt fword ptr (SMM_DISPATCHER_PRIVATE_STRUCT ptr [rsi]).Idt
+ db 0fh, 1, 5eh
+ db SMM_DISPATCHER_PRIVATE_STRUCT.IDT
+
+ add di, 4 ;di = SmmEntryInit
+
+ db 48h
+ mov cx, di ;mov rcx, rdi
+
+ call bx ;call rbx
+
+ ;restore stack
+ add sp, 0ch + 20h
+
+ ;mov edx, [rsp]
+ db 8bh, 14h, 24h
+
+ ;fxrstor [rdx]
+ db 48h, 0fh, 0aeh, 0ah
+
+ ;lea rax, [@f];
+ db 48h, 8Dh, 05
+ dd offset @f - $ - 4
+ ;push CODE32_SEL
+ db 68h
+ dd CODE32_SEL
+ db 48h
+ push ax ;push rax
+ db 48h
+ retf ;retq ;switch to compatibility mode.
+@@:
+ pop dx ;pop edx
+endif
+;---We are in 32-bit protected or 32-bit compatibility mode.---
+;C calls preserve ESI, EDI, EBX, and EBP.
+;esi = SMM_DISPATCHER_PRIVATE_STRUCT
+;edi = SMM_ENTRY_INIT_STRUCT
+
+IFDEF MKF_PfatServices_SUPPORT
+IF MKF_PfatServices_SUPPORT
+ mov eax, cr0
+ and al, 0DFh ;Clear NE bit
+ mov cr0, eax
+ENDIF
+ENDIF
+
+IF MKF_SMM_CACHE_SUPPORT
+IFNDEF MKF_NEHALEM_CPU_MODULE
+; **************** CACHE DISABLE ****************
+ ;mov al, byte ptr (SMM_ENTRY_INIT_STRUCT ptr [edi]).Ht0
+ db 8Ah, 47h
+ db SMM_ENTRY_INIT_STRUCT.Ht0
+ or al, al ;or al, al
+ jz cache_disable_end ;skip if HT
+
+ mov al, 1
+ ;cmp (SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).SmrrEnable, al
+ db 38h, 46h
+ db SMM_DISPATCHER_PRIVATE_STRUCT.SmrrEnable
+ jne non_smrr_cache2
+ ;Disable SMRR.
+
+ ;mov ecx, (SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).SmrrMsr
+ db 08bh, 4eh
+ db SMM_DISPATCHER_PRIVATE_STRUCT.SmrrMsr
+ inc cx ;inc ecx
+
+ rdmsr
+ bts eax, 11 ;Disable UC SMRR. This makes the region WT by overlapping MTRR.
+ wrmsr
+ jmp cache_disable_end
+
+non_smrr_cache2:
+ ;mov ecx, (SMM_DISPATCHER_PRIVATE_STRUCT ptr [esi]).TsegMsr
+ db 8bh, 4eh
+ db SMM_DISPATCHER_PRIVATE_STRUCT.TsegMsr
+ or cx, cx ;or ecx, ecx
+ jz cache_disable_end ;Not enough/or moved MTRR to support cache.
+
+ rdmsr
+ xor al, al
+ wrmsr ;Make MTRR UC
+;-----------------
+cache_disable_end:
+; ************** END OF CACHE DISABLE ************
+ENDIF
+ENDIF
+ rsm
+
+align 16
+GDT_BASE:
+NULL_SEL equ $-GDT_BASE ;NULL Selector 0
+ dd 0, 0
+
+DATA_SEL equ $-GDT_BASE ; Selector 8, Data 0-ffffffff 32 bit
+ dd 0000ffffh
+ dd 00cf9300h
+
+CODE32_SEL equ $-GDT_BASE ; Selector 10h, CODE 0-ffffffff 32 bit
+ dd 0000ffffh
+ dd 00cf9b00h
+
+; We only need this because Intel DebugSupport driver
+; (RegisterPeriodicCallback function) assumes that selector 0x20 is valid
+; The funciton sets 0x20 as a code selector in IDT
+;
+; System data segment descriptor
+;
+SYS_DATA_SEL equ $ - GDT_BASE ; Selector [0x18]
+ dd 0000FFFFh ;0 - f_ffff
+ dd 00cf9300h ;data, expand-up, notwritable, 32-bit
+
+; System code segment descriptor
+SYS_CODE_SEL equ $ - GDT_BASE ; Selector [0x20]
+ dd 0000FFFFh ;0 - f_ffff
+ dd 00cf9b00h ;data, expand-up, writable, 32-bit
+SPARE3_SEL equ $-GDT_BASE ; Selector [0x28]
+ dd 0, 0
+SYS_DATA64_SEL equ $-GDT_BASE ; Selector [0x30]
+ dd 0000FFFFh
+ dd 00cf9300h
+CODE64_SEL equ $-GDT_BASE ; Selector [0x38]
+ dd 0000FFFFh
+ dd 00af9b00h
+TSS_SEL equ $-GDT_BASE ; Selector [0x40]
+ dw 0067h
+TSS_SEL_FIXUP:
+ dw 0000h
+ dd 00008900h
+L_DATA_SEL equ $-GDT_BASE
+ dd 0000ffffh
+ dd 008f9300h
+L_CODE_SEL equ $-GDT_BASE
+ dw 0ffffh
+L_CODE_SEL_FIXUP:
+ dd 09a000000h ;Fix up by adding SMM BASE + 8000h
+ dw 0
+GDT_SIZE equ $-GDT_BASE ;Size of Descriptor Table
+
+GdtDescriptor:
+ dw GDT_SIZE - 1 ;GDT limit
+GDT_DESC_FIXUP:
+ dd offset GDT_BASE ;Fix up by adding SMM BASE + 8000h
+SmmEntryEnd:
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+;<AMI_PHDR_START>
+;---------------------------------------------------------------------------
+;
+; Procedure: Thunk
+;
+; Description: The thunk code is copied to below 1MB and used in SMM to thunk to
+; 16-bit mode.
+;
+; Input: None
+;
+; Output: None
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+
+THUNK:
+ jmp short skip_thunk_fixup_data
+ dw offset thunk_data_fixup - offset THUNK
+ dw offset thunk_data_fixup2 - offset THUNK
+skip_thunk_fixup_data:
+IFDEF EFIx64
+;Starts in 64-bit mode. Need to turn this into machine code.
+ push dx ;rdx
+;---Jump from long mode to compatiblity mode---
+ push 10h
+ ;push eip (call next instruction)
+ db 0e8h
+ dd 0
+ ;add dword ptr [rsp], 6 ;rip = ComMode.
+ db 83h, 04h, 24h
+ db 6
+ db 48h
+ retf
+ComMode:
+;---Go to protected mode---
+ mov eax, cr0
+ btr ax, 31 ;btr eax, 31
+ mov cr0, eax ;Now in protected mode.
+ jmp $+2
+
+ ;mov ecx, 0c0000080h
+ db 0b9h
+ dd 0c0000080h
+ rdmsr
+ btr ax, 8 ;btr eax, 8
+ wrmsr
+ENDIF
+;Starts in protected mode. Need to turn this into machine code.
+ db 60h ;pushad
+ db 9ch ;pushfd
+
+ ;mov ebx, ThunkData
+ db 0bbh
+thunk_data_fixup:
+ dd 0
+
+if MKF_SMM_THUNK_IN_CSM EQ -1
+ ;movzx eax, word ptr [40eh] ;Get segment of ebda.
+ db 0Fh, 0B7h, 05
+ dd 40eh
+ shl ax, 4 ;shl eax, 4 ;Get address ebda
+ add bx, ax ;add ebx, eax
+endif
+
+;--Save Data--
+ ;mov ds:(SMM_THUNK_DATA ptr [ebx]).StackSave, esp ;Save 32 bit stack address of this module.
+ db 89h, 63h
+ db SMM_THUNK_DATA.StackSave
+ ;sgdt ds:(SMM_THUNK_DATA ptr [ebx]).GdtSave
+ db 0Fh, 01h, 43h
+ db SMM_THUNK_DATA.GdtSave
+ ;sidt ds:(SMM_THUNK_DATA ptr [ebx]).IdtSave
+ db 0Fh, 01h, 4Bh
+ db SMM_THUNK_DATA.IdtSave
+;---Copy Stack parameters of LegacyBiosFarCall---
+ ;mov ecx, ds:(SMM_THUNK_DATA ptr [ebx]).StackParm.StackSize
+ db 8Bh, 4Bh
+ db SMM_THUNK_DATA.StackParm.StackSize
+
+ or cx, cx ;32-bit or ecx, ecx
+ jz no_stack_to_copy
+
+ ;movzx edi, ds:(SMM_THUNK_DATA ptr [ebx]).Below1MStack
+ db 0Fh, 0B7h, 7Bh
+ db SMM_THUNK_DATA.Below1MStack
+ add di, bx ;32-bit add edi, ebx
+ sub di, cx ;32-bit sub edi, ecx
+
+ ;mov esi, ds:(SMM_THUNK_DATA ptr [ebx]).StackParm.StackPtr
+ db 8Bh, 73h
+ db SMM_THUNK_DATA.StackParm.StackPtr
+
+
+ rep movsb
+no_stack_to_copy:
+
+;--Get Real mode address to switch to--
+ ;call get_eip ;push eip
+ db 0E8h
+ dd 0h
+get_eip:pop dx ;pop edx
+ ;add edx, offset RealMode - offset get_eip
+ db 83h, 0C2h
+ db offset RealMode - offset get_eip
+
+;--Switch to real mode--
+ ;lidt fword ptr ds:(SMM_THUNK_DATA ptr [ebx]).LegacyIdtDesc
+ db 0Fh, 01h, 5Bh
+ db SMM_THUNK_DATA.LegacyIdtDesc
+ ;Jump to L_CODE_SEL:next
+ ;push L_CODE_SEL
+ db 6ah
+ db L_CODE_SEL
+ ;push offset next - offset THUNK
+ db 68h
+ dd offset next - offset THUNK
+ retf
+next:
+ mov ax, L_DATA_SEL
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ mov eax, cr0
+ and al, 0feh
+ mov cr0, eax
+ shr ebx, 4
+ mov ds, bx
+ mov ss, bx
+;---------------Real mode operations-----------
+ movzx esp, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).Below1MStack
+ sub sp, word ptr ds:(SMM_THUNK_DATA ptr [SmmThunkData]).StackParm.StackSize
+
+ ;--jump to real mode--
+ mov eax, edx
+ shr edx, 4 ;edx = segment
+ and eax, 0fh ;eax = ip
+ push dx
+ push ax
+ retf
+RealMode:
+ mov ax, cs
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ ;---copy registers for FarCall---
+ mov eax, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_eax
+ mov ebx, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ebx
+ mov ecx, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ecx
+ mov edx, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_edx
+ mov esi, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_esi
+ mov edi, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_edi
+ mov ebp, ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ebp
+
+ push ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_es
+ pop es
+ push ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_fs
+ pop fs
+ push ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_gs
+ pop gs
+
+ ;Generally, flags are not used to pass information as a parameter only to return information.
+ ;Uninialized flags in the parameters may cause an exception if they are set.
+
+ cmp word ptr ds:(SMM_THUNK_DATA ptr [SmmThunkData]).StackParm.StackSize, 0
+ jne @f
+ ;If no stack, push flags to imitate INT xx, in case of using call to emulate interrupt.
+ pushf
+@@:
+ ;---Push return cs:ip---
+ push cs
+ call store_ret_ptr ;push ip
+store_ret_ptr:
+ push bp ;save bp for temp use.
+ mov bp, sp
+
+ add word ptr [bp + 2], ret_from_16bit - store_ret_ptr ;Change return address in stack.
+ pop bp ;restore bp
+
+ ;----------------------
+ ;---Call 16-bit code---
+ ;----------------------
+
+ ;push the function to stack.
+ push ds:(SMM_THUNK_DATA ptr [SmmThunkData]).FarCallPtr16.seg_offset
+ push ds:(SMM_THUNK_DATA ptr [SmmThunkData]).FarCallPtr16.ptr_offset
+
+ ;This is done last because of ds is used.
+ push ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ds
+ pop ds
+
+ ;---Execute 16-bit call---
+ retf ;Execute far call
+ret_from_16bit:
+ push ds ;Save orginal ds
+if MKF_SMM_THUNK_IN_CSM EQ -1
+ push ax
+ xor ax, ax
+ mov fs, ax
+ movzx eax, word ptr fs:[40eh]
+
+ ;add ax, thunk_data_fixup2
+ db 5
+thunk_data_fixup2:
+ dw 0
+ mov ds, ax
+ pop ax
+else
+ ;push ThunkData2 ;ds = thunk data >> 4
+ db 68h
+thunk_data_fixup2:
+ dw 0
+ pop ds
+endif
+
+ pop ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ds
+
+
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_eax, eax
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ebx, ebx
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ecx, ecx
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_edx, edx
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_esi, esi
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_edi, edi
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_ebp, ebp
+
+ pushfd
+ pop ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_flags
+
+ mov ax, es
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_es, ax
+
+ mov ax, fs
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_fs, ax
+
+ mov ax, gs
+ mov ds:(SMM_THUNK_DATA ptr [SmmThunkData]).regs.reg_gs, ax
+
+;--------------End Real Mode operations---------
+
+ xor ebx, ebx
+ mov bx, ds
+ shl ebx, 4
+
+ xor edx,edx
+ mov dx, cs
+ shl edx, 4 ;edx+ already 0
+
+ ;--Switch to protected mode--
+ db 66h
+ lgdt fword ptr ds:(SMM_THUNK_DATA ptr [SmmThunkData]).GdtSave
+
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+;---Switch into protected mode---
+ ;jmp 10:TP32MODE to set cs segment
+
+ mov eax, edx
+ call get_eip2 ;push ip
+get_eip2:
+ xor edx, edx
+ pop dx
+ add edx, offset TP32Mode - offset get_eip2
+ add edx, eax ;eip = cs * 10h + offset
+ pushd 10h
+ push edx
+ db 66h
+ retf
+TP32Mode::
+;---In protected mode.---
+ ;mov ax, DATA_SEL
+ db 66h, 0b8h
+ dw DATA_SEL
+ db 66h, 8eh, 0d8h ;mov ds, ax
+ db 66h, 8eh, 0c0h ;mov es, ax
+ db 66h, 8eh, 0d0h ;mov ss, ax
+ db 66h, 8eh, 0e0h ;mov fs, ax
+ db 66h, 8eh, 0e8h ;mov gs, ax
+
+ ;lidt fword ptr ds:(SMM_THUNK_DATA ptr [ebx]).IdtSave
+ db 0Fh, 01h, 5Bh
+ db SMM_THUNK_DATA.IdtSave
+
+ ;mov esp, ds:(SMM_THUNK_DATA ptr [ebx]).StackSave ;Get original stack back.
+ db 8Bh, 63h
+ db SMM_THUNK_DATA.StackSave
+
+ xor ax, ax ;xor eax, eax short/quick way to set EAX = 0
+ lldt ax ;(source operand == 0) => LDTR is invalid
+ db 9dh ;popfd
+ db 61h ;popad
+
+IFDEF EFIx64
+;---Switch to long mode---
+ ;mov ecx, 0c0000080h
+ db 0b9h
+ dd 0c0000080h
+ rdmsr
+ bts ax, 8 ;bts eax, 8
+ wrmsr
+
+ mov eax, cr0
+ bts ax, 31 ;bts eax, 31
+ mov cr0, eax ;Now in compatibility mode.
+ jmp $+2
+
+ ;jmp 38:LongModeThk to set cs segment
+ ;call get_eip3 ;push eip
+ db 0E8h
+ dd 0h
+get_eip3:
+ pop dx ;pop edx (edx = eip)
+ ;add edx, offset LongModeThk - offset get_eip3
+ db 83h, 0C2h
+ db offset LongModeThk - offset get_eip3
+ push 38h
+ push dx ;push edx
+ retf
+LongModeThk:
+ ;mov ax, DATA_SEL
+ db 66h, 0b8h
+ dw DATA_SEL
+ db 66h, 8eh, 0d8h ;mov ds, ax
+ db 66h, 8eh, 0c0h ;mov es, ax
+ db 66h, 8eh, 0d0h ;mov ss, ax
+ db 66h, 8eh, 0e0h ;mov fs, ax
+ db 66h, 8eh, 0e8h ;mov gs, ax
+
+ pop dx ;pop rdx
+ENDIF
+ ret
+SmmThunkEnd:
+SMM ENDS
+
+end
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2008, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/EM/SMM/SmmHdr.equ b/Core/EM/SMM/SmmHdr.equ
new file mode 100644
index 0000000..5209fe0
--- /dev/null
+++ b/Core/EM/SMM/SmmHdr.equ
@@ -0,0 +1,286 @@
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2011, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/SMM/SmmHdr.equ 26 4/01/11 10:09a Markw $
+;
+; $Revision: 26 $
+;
+; $Date: 4/01/11 10:09a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/SMM/SmmHdr.equ $
+;
+; 26 4/01/11 10:09a Markw
+; [TAG] EIP57440
+; [Category] New Feature
+; [Description] Add PI 1.1 SMM support for reading/writing floating
+; point/smm save state.
+;
+; [Files] CpuCspLib.h, CpuCspLib.c, SmmPiSmst.c, SmmPrivateShared.h,
+; SmmHdr.equ, SmmInit.c
+;
+; 25 8/11/09 11:46a Markw
+; Removed Legacy registration. This is removed from latest PI and not
+; used by projects.
+;
+; 24 7/08/09 8:09p Markw
+; Update headers.
+;
+; 23 12/23/08 2:15p Markw
+; EIP #17900 Set up TSS. Borland C in DOS hangs otherwise.
+;
+; 22 11/21/08 4:57p Markw
+; Add SmmInit to SMM_ENTRY_STRUCT for SMM init for first normal/S3 boot.
+; 32-bit CPU count.
+;
+; 21 9/07/08 12:42a Markw
+; Separate SMM Private structure into inside SMM and outside SMM
+; structure.
+;
+; 20 4/04/08 6:21p Markw
+; Add Smrr MSR to SMM_BASE_PRIVATE_STRUCT.
+;
+; 19 3/03/08 6:35p Markw
+; Added 32-bit register for smm thunk.
+;
+; 18 11/14/07 2:03p Markw
+; Added SMRR support and updated SMM Cache for non-SMRR.
+;
+; 17 10/29/07 10:58a Markw
+; Smm Thunk:
+; * Code and data different segments.
+; * Code position independent.
+; * Switch for CSM for code and EBDA for data.
+;
+; 16 10/24/07 12:00p Markw
+; SMM Thunk code position independent. Data in a separate segment than
+; code in Smm Thunk.
+;
+; 15 9/10/07 1:39p Markw
+; Add Interrupt Handling in SMM.
+;
+; 14 6/08/07 6:51p Markw
+; Save/Restore XMM.
+;
+; 13 1/11/07 12:28p Markw
+; Adjusted location of fields in structure for removal of legacy.
+;
+; 12 1/09/07 6:40p Markw
+; Update BSP Entry Structure to remove dependencies on SMM_BSP_BASE.
+;
+; 11 12/29/06 4:45p Markw
+; Add Smm Cache Support and update CPU syncronization.
+;
+; 10 12/21/06 5:19p Markw
+; Remove old unused SmmStackSize from Private structure.
+;
+; 9 11/13/06 11:23a Markw
+; Added structure for AP entry.
+;
+; 8 9/18/06 3:20p Markw
+; Updated 32 bit part for BSP an AP sync.
+;
+; 7 9/18/06 11:47a Markw
+;
+; 6 8/24/06 3:27p Felixp
+; Preliminary x64 support (work in progress)
+;
+; 5 1/13/06 11:27a Markw
+; Added SMM Thunk support.
+;
+; 4 1/10/06 2:56p Markw
+; Add support for multi-threadding and sync all CPUs during entry/exit of
+; SMM.
+;
+; 3 7/19/05 7:59p Markw
+; Fixed smm base private header.
+;
+; 2 7/11/05 1:06p Markw
+; Removed isCallback from structure.
+;
+; 1 1/28/05 4:29p Sivagarn
+; Generic SMM module - Intial Check in
+;
+;
+;**********************************************************************
+
+;<AMI_FHDR_START>
+;----------------------------------------------------------------------------
+;
+; Name: SmmHdr.EQU
+;
+; Description: Header file for the SMM x86 assembly source
+;
+;----------------------------------------------------------------------------
+;<AMI_FHDR_END>
+
+
+FAR_CALL_PTR_16 struct
+ ptr_offset dw ?
+ seg_offset dw ?
+FAR_CALL_PTR_16 ends
+
+REGISTERS struct
+ reg_eax dd ?
+ reg_ebx dd ?
+ reg_ecx dd ?
+ reg_edx dd ?
+ reg_esi dd ?
+ reg_edi dd ?
+ reg_flags dd ?
+ reg_es dw ?
+ reg_cs dw ?
+ reg_ss dw ?
+ reg_ds dw ?
+ reg_fs dw ?
+ reg_gs dw ?
+ reg_ebp dd ?
+REGISTERS ends
+
+IFNDEF EFIx64
+
+SMM_DESC STRUCT 1
+ Limit dw ?
+ Base dd ?
+ Rsv dw ? ;For alignment
+SMM_DESC ENDS
+
+STACK_PARAM STRUCT
+ StackPtr dd ?
+ StackSize dd ?
+STACK_PARAM ENDS
+
+SMM_ENTRY_INIT_STRUCT STRUCT
+ SmmInit dd ? ;This must be first.
+ SmmEntryLength dd ?
+ GdtDescBaseOffset dd ?
+ LCodeSelBaseOffset dd ?
+ TssSelBaseOffset dd ?
+ SmmThunkProcOffset dd ?
+ SmmThunkLength dd ?
+ Ht0 dd ?
+ SmmEntryStart dd ?
+ SmmDispatcherAddr dd ?
+ SmmDispatcherPrivateStruct dd ?
+ SmmStack dd ?
+ CpuNo dd ?
+SMM_ENTRY_INIT_STRUCT ENDS
+
+SMM_THUNK_DATA STRUCT 8
+ ;Real mode thunk
+ FarCallPtr16 FAR_CALL_PTR_16 <>
+ Regs REGISTERS <>
+ StackParm STACK_PARAM <>
+ StackSave dd ?
+ GdtSave SMM_DESC <>
+ IdtSave SMM_DESC <>
+ LegacyIdtDesc SMM_DESC <>
+
+ Below1MStack dw ? ;ss = ds
+SMM_THUNK_DATA ENDS
+
+DESCRIPTOR_TABLE STRUCT 1
+ Limit dw ?
+ Base dd ?
+DESCRIPTOR_TABLE ends
+
+SMM_DISPATCHER_PRIVATE_STRUCT STRUCT 8
+ PageDirectories dd ?
+ SmmXmmSave dd ?
+ SmrrEnable db ?
+ SmrrMsr dd ?
+ TsegMsr dd ?
+ TsegMsrBase dq ?
+ TsegMsrMask dq ?
+ Idt DESCRIPTOR_TABLE <>
+
+ ;Addional members not specified here.
+SMM_DISPATCHER_PRIVATE_STRUCT ENDS
+
+ELSE
+
+STACK_PARAM struct
+ StackPtr dd ?
+ StackSize dd ?
+STACK_PARAM ends
+
+SMM_DESC STRUCT 1
+ Limit dw ?
+ Base dd ?
+ Rsv dw ? ;For alignment
+SMM_DESC ENDS
+
+DESCRIPTOR_TABLE STRUCT 1
+ Limit dw ?
+ Base dq ?
+DESCRIPTOR_TABLE ends
+
+SMM_DISPATCHER_PRIVATE_STRUCT STRUCT 8
+ PageDirectories dq ?
+ SmmXmmSave dq ?
+ SmrrEnable db ?
+ SmrrMsr dd ?
+ TsegMsr dd ?
+ TsegMsrBase dq ?
+ TsegMsrMask dq ?
+ Idt DESCRIPTOR_TABLE <>
+ ;Addional members not specified here.
+SMM_DISPATCHER_PRIVATE_STRUCT ENDS
+
+SMM_ENTRY_INIT_STRUCT STRUCT 8
+ SmmInit dd ? ;This must be first.
+ SmmEntryLength dd ?
+ GdtDescBaseOffset dd ?
+ LCodeSelBaseOffset dd ?
+ TssSelBaseOffset dd ?
+ SmmThunkProcOffset dd ?
+ SmmThunkLength dd ?
+ Ht0 dd ?
+ SmmEntryStart dq ?
+ SmmDispatcherAddr dq ?
+ SmmDispatcherPrivateStruct dq ?
+ SmmStack dq ?
+ CpuNo dd ?
+ Ia32HandlerListHead dq ?
+SMM_ENTRY_INIT_STRUCT ENDS
+
+SMM_THUNK_DATA STRUCT 8
+ ;Real mode thunk
+ FarCallPtr16 FAR_CALL_PTR_16 <>
+ Regs REGISTERS <>
+ StackParm STACK_PARAM <>
+ StackSave dd ?
+ GdtSave SMM_DESC <>
+ IdtSave SMM_DESC <>
+ LegacyIdtDesc SMM_DESC <>
+ Below1MStack dw ? ;ss = ds
+SMM_THUNK_DATA ENDS
+
+ENDIF
+
+;*************************************************************************
+;*************************************************************************
+;** **
+;** (C)Copyright 1985-2011, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;*************************************************************************
+;*************************************************************************
diff --git a/Core/EM/SMM/SmmInit.c b/Core/EM/SMM/SmmInit.c
new file mode 100644
index 0000000..fa0f699
--- /dev/null
+++ b/Core/EM/SMM/SmmInit.c
@@ -0,0 +1,1319 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/SmmInit.c 3 10/31/12 6:32a Wesleychen $
+//
+// $Revision: 3 $
+//
+// $Date: 10/31/12 6:32a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/SmmInit.c $
+//
+// 3 10/31/12 6:32a Wesleychen
+// Move 'DisableSmmCallbacks' event from BDS_CONNECT_DRIVERS_PROTOCOL_GUID
+// to BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID.
+//
+// 8 1/05/12 1:54p Markw
+// [TAG] EIP78457
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] If BSP is switch, SMM may not bring all CPUs into SMM if
+// not all CPUs are inside of SMM.
+// [RootCause] During CPU initialization, the sytem uses the actual BSP
+// instead of BSP from the SMM HOB.
+// This creates a inconsistentancy with the rest of the SMM numbering.
+// [Solution] Use SMM HOB BSP value.
+// [Files] SmmInit.c
+//
+// 7 10/03/11 2:51p Markw
+// Update StartupThisAP for PI 1.1.
+// File: SmmInit.c
+//
+// 6 6/22/11 11:55a Markw
+// Separate DxeSmmReadyToLock from Protocol\SmmReadyToLock.h.
+//
+//
+// 5 5/10/11 12:06p Markw
+// [TAG] EIP60051
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] With PI 1.1, BIOS may hang in DisableSmmCallbacks .
+// [RootCause] DisableSmmCallbacks calls SmmDispatcher. This must be
+// executed inside SMM.
+// [Solution] Call SmmDispatcher inside SMM.
+// [Files] SmmInit.c
+//
+// 4 4/12/11 3:00p Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] PI Update allocated SMM BASE Protocol with boot
+// services data. Change it to runtime services data.
+// [Files] SmmInit.c
+//
+// 3 4/01/11 10:07a Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Add PI 1.1 SMM support for reading/writing floating
+// point/smm save state.
+//
+// [Files] CpuCspLib.h, CpuCspLib.c, SmmPiSmst.c, SmmPrivateShared.h,
+// SmmHdr.equ, SmmInit.c
+//
+// 2 3/04/11 3:32p Markw
+// Update headers.
+//
+// 1 2/07/11 3:34p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support.
+// Moved common initialization from SmmBase.c to SmmInit.c.
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmInit.c
+//
+// Description: Dispatch SMM Drivers
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//This include should be first.
+#include "SmmPrivateShared.h"
+#include <AmiDxeLib.h>
+#include "AmiCspLib.h"
+#include <AmiSmm.h>
+#include <AmiHobs.h>
+#if USE_FV2
+#include <Protocol\FirmwareVolume2.h>
+#else
+#include <Protocol\FirmwareVolume.h>
+#endif
+#include <Protocol\LoadPe32Image.h>
+#include <Protocol\MpService.h>
+#if SMM_THUNK_IN_CSM == 1
+#include <Protocol\LegacyBiosExt.h>
+#include <Protocol\LegacyBios.h>
+#endif
+
+#if SMM_USE_FRAMEWORK
+#include <Protocol\SmmBase.h>
+#endif
+
+#if SMM_USE_PI
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmReadyToLock.h>
+#include <Protocol\DxeSmmReadyToLock.h>
+#endif
+
+
+#if SMM_USE_PI
+#include <Protocol\SmmAccess2.h>
+#include <Protocol\SmmControl2.h>
+#else
+#include <Protocol\SmmAccess.h>
+#include <Protocol\SmmControl.h>
+#endif
+
+#include <Token.h>
+
+// {3AA83745-9454-4f7a-A7C0-90DBD02FAB8E}
+#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \
+ { 0x3aa83745, 0x9454, 0x4f7a, { 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e } }
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93}
+
+CPUINFO_HOB *gCpuinfoHob;
+SMM_HOB *gSmmHob;
+EFI_HOB_CPU *gCpuHob;
+UINT32 gBspSmmBase;
+SMM_ENTRY_INIT_STRUCT *gSmmEntryData;
+SMM_BASE_PRIVATE_STRUCT *gBasePrivate;
+SMM_DISPATCHER_PRIVATE_STRUCT *gDispatcherPrivate;
+EFI_PE32_IMAGE_PROTOCOL *gPe32Image;
+EFI_MP_SERVICES_PROTOCOL *gMpServices;
+
+
+#if SMM_USE_FRAMEWORK
+EFI_SMM_SYSTEM_TABLE *gSmstTable;
+#endif
+
+#if SMM_USE_PI
+EFI_SMM_SYSTEM_TABLE2 *gSmstTable2;
+#endif
+
+#if SMM_USE_PI
+EFI_SMM_CONTROL2_PROTOCOL *gSmmControl;
+EFI_SMM_ACCESS2_PROTOCOL *gSmmAccess;
+#else
+EFI_SMM_CONTROL_PROTOCOL *gSmmControl;
+EFI_SMM_ACCESS_PROTOCOL *gSmmAccess;
+#endif
+
+
+#if SMM_THUNK_IN_CSM == 1
+EFI_LEGACY_BIOS_PROTOCOL *gLegacyBios;
+EFI_LEGACY_BIOS_EXT_PROTOCOL *gLegacyBiosExt;
+#endif
+
+EFI_HANDLE gThisImageHandle;
+
+EFI_GUID gHobListGuid = HOB_LIST_GUID;
+EFI_GUID gSmmHobGuid = SMM_HOB_GUID;
+EFI_GUID gCpuinfoHobGuid = AMI_CPUINFO_HOB_GUID;
+EFI_GUID gEfiPe32ImageProtocolGuid = PE32_IMAGE_PROTOCOL_GUID;
+EFI_GUID gEfiMpServicesProtocolGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+EFI_GUID gBdsConnectDriversProtocolGuid = BDS_CONNECT_DRIVERS_PROTOCOL_GUID;
+EFI_GUID gBdsAllDriversConnectedProtocolGuid = BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID;
+#if SMM_USE_PI
+EFI_GUID gEfiEventDxeDispatchGuid = EFI_EVENT_GROUP_DXE_DISPATCH;
+//EFI_GUID gEfiDxeSmmReadyToLockProtocolGuid = EFI_DXE_SMM_READY_TO_LOCK_PROTOCOL_GUID;
+#endif
+
+#if USE_FV2
+EFI_GUID gEfiFVProtocolGuid = EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID;
+#else
+EFI_GUID gEfiFVProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+#endif
+
+#if SMM_THUNK_IN_CSM == 1
+EFI_GUID gEfiLegacyBiosProtocolGuid = EFI_LEGACY_BIOS_PROTOCOL_GUID;
+EFI_GUID gEfiLegacyBiosExtProtocolGuid = EFI_LEGACY_BIOS_EXT_PROTOCOL_GUID;
+#endif
+
+#if SMM_USE_FRAMEWORK
+extern EFI_SMM_BASE_PROTOCOL gEfiSmmBase;
+#endif
+
+#if SMM_USE_PI
+extern EFI_SMM_BASE2_PROTOCOL gEfiSmmBase2;
+#endif
+
+UINT32 gBspSmmBase;
+SMM_ENTRY_INIT_STRUCT *gSmmEntryData;
+UINTN gBsp;
+
+EFI_GUID SmmEntryGuid =
+ {0xD2596F82,0xF0E1,0x49fa,0x95,0xBC,0x62,0x01,0x2C,0x79,0x57,0x28};
+ //D2596F82-F0E1-49fa-95BC-62012C795728
+EFI_GUID gEfiSmmCoreDispatcherGuid =
+ {0x4A37320B,0x3FB3,0x4365,0x97,0x30,0x9e,0x89,0xC6,0x00,0x39,0x5D};
+ //4A37320B-3FB3-4365-9730-9E89C600395D
+
+VOID SmmDispatcher();
+VOID SetDisallowRegistering();
+VOID SmmDriverDispatchHandler();
+
+extern UINT32 InSmmFuncLength;
+extern UINT32 InSmmFuncOffset;
+
+EFI_STATUS EfiSmmInSmm(
+ IN EFI_SMM_BASE_PROTOCOL *This,
+ OUT BOOLEAN *InSmm
+);
+
+//
+// This is the structure contains default values in Boot Services memory.
+// This table will be updated and copied into Runtime memory.
+//
+SMM_BASE_PRIVATE_STRUCT gSmmBasePrivateStruct =
+{
+ 0, //*CallBackFunc
+ FALSE, //InSmm
+ FALSE //DisallowCallbacks
+ //Additional members not specified.
+};
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CallFuncInSmm
+//
+// Description: Call function in SMM. If not in SMM, generate SW SMI, otherwise
+// call the function.
+//
+// Input: IN func -- Pointer to function
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CallFuncInSmm(IN VOID func())
+{
+ if (!*gBasePrivate->InSmm) {
+#if SMM_USE_PI
+ UINT8 CommandPort = SMMBASE_CALLBACK;
+#else
+ UINT8 ArgBuffer = SMMBASE_CALLBACK;
+ UINTN ArgBufferSize = 1;
+#endif
+ gBasePrivate->CallBackFunc = func;
+
+ //Generate SW SMI
+#if SMM_USE_PI
+ gSmmControl->Trigger(gSmmControl, &CommandPort, NULL, FALSE, 0);
+#else
+ gSmmControl->Trigger(gSmmControl, &ArgBuffer, &ArgBufferSize, FALSE, 0);
+#endif
+ //This is cleared inside of SMM.
+ } else {
+ func();
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindMatchingMtrr
+//
+// Description: Search MTRRs for a matching MTRR.
+//
+// Input:
+// IN UINT64 BASE
+// IN UINT64 Mask
+//
+// Output:
+// UINT32 -- MSR for matching MTTR.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+#if SMM_CACHE_SUPPORT == 1
+#ifndef NEHALEM_CPU_MODULE
+VOID InitSmmCacheData()
+{
+ UINT32 Msr;
+ UINT32 i;
+ UINT8 NumMtrrs = (UINT8)ReadMsr(0xfe); //MSR_IA32_MTRR_CAP
+ UINT32 RegEAX, RegEBX, RegECX, RegEDX;
+ UINT8 NumOfMemoryBits = 36;
+ UINT64 MemoryMask;
+
+ CPULib_CpuID(0x80000008, &RegEAX, &RegEBX, &RegECX, &RegEDX);
+ //Check if CPU supports this CPUID.
+ if (RegEAX != 0 && RegEAX != 0xffffffff)
+ NumOfMemoryBits = (UINT8)RegEAX & 0xff;
+
+ MemoryMask = Shl64(1, NumOfMemoryBits)- 1;
+
+ gDispatcherPrivate->SmrrEnable = FALSE;
+ gDispatcherPrivate->SmrrMsr = GetSmrrBaseMsr();
+ gDispatcherPrivate->TsegMsr = 0;
+ gDispatcherPrivate->TsegMsrBase = (UINT64)(UINTN)gSmmHob->Tseg;
+ gDispatcherPrivate->TsegMsrMask = (MemoryMask & (~(TSEG_SIZE - 1))) | (1 << 11);
+
+ //MSRs will not be found if there is not enough MSRs for caching SMM.
+
+ for(i = 0, Msr = 0x200; i < NumMtrrs; ++i, Msr+=2) { //MTRR_PHYS_BASE_0
+ if ((ReadMsr(Msr) & ~(UINT64)0xff) == gDispatcherPrivate->TsegMsrBase
+ && ReadMsr(Msr+1) == gDispatcherPrivate->TsegMsrMask
+ ) {
+ gDispatcherPrivate->TsegMsr = Msr;
+ }
+ }
+
+ if (CPULib_IsSmrrEnabled()) gDispatcherPrivate->SmrrEnable = TRUE;
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: LoadRealModeFile
+//
+// Description: Load a real mode file into a buffer.
+//
+// Input:
+// IN EFI_GUID *Guid
+// OUT VOID **Buffer
+// OUT UINTN *BufferSize
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS LoadRealModeFile(EFI_GUID *Guid, VOID **Buffer, UINTN *BufferSize)
+{
+#if USE_FV2
+ EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;
+#else
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+#endif
+ UINT32 Authentication;
+ EFI_STATUS Status;
+ UINTN NumHandles;
+ EFI_HANDLE *HandleBuffer;
+ UINTN i;
+
+ *Buffer=0;
+ *BufferSize=0;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiFVProtocolGuid,NULL,&NumHandles,&HandleBuffer);
+ if (EFI_ERROR(Status)) return Status;
+
+ for (i = 0; i< NumHandles; ++i) {
+ Status = pBS->HandleProtocol(HandleBuffer[i],&guidFV,&Fv);
+ if (EFI_ERROR(Status)) continue;
+
+ Status = Fv->ReadSection(Fv,
+ Guid,
+ EFI_SECTION_RAW,
+ 0, //Instance
+ Buffer,
+ BufferSize,
+ &Authentication);
+
+ if (Status == EFI_SUCCESS) break;
+ }
+
+ pBS->FreePool(HandleBuffer);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EarlyAllocSmmMemory
+//
+// Description: Allocate SMM memory before SMM memory manager available.
+//
+// Input:
+// IN UINT32 Size -- Memory size
+//
+// Output: VOID * -- ptr to allocated memory.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * EarlyAllocSmmMemory(IN UINT32 Size)
+{
+ UINT8 *AllocatedAddress;
+ UINT32 AdjSize;
+
+ AdjSize = (Size + 7) & ~7; //Minimum 8 bytes.
+ if (AdjSize > gBasePrivate->SmmAllocMemoryLength) return 0;
+
+ AllocatedAddress = (UINT8*)gBasePrivate->SmmAllocMemoryStart;
+ gBasePrivate->SmmAllocMemoryStart = AllocatedAddress + AdjSize;
+ gBasePrivate->SmmAllocMemoryLength -= AdjSize;
+
+ return AllocatedAddress;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EarlyAllocSmmMemoryAlign
+//
+// Description:
+// Allocate SMM memory before SMM memory manager available with specified alignment.
+// Memory address returned will be the next aligned address available and the free memory
+// before the aligned address can not be allocated.
+//
+// Input:
+// IN UINT32 Size -- Memory size.
+// IN UINT32 Align -- Alignment. Must be 2^n.
+//
+// Output: VOID * -- ptr to allocated memory.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * EarlyAllocSmmMemoryAlign(IN UINT32 Size, IN UINT32 Align)
+{
+ UINT8* AllocatedAddress;
+ UINT8 *OrigAddress;
+ UINT32 AdjSize;
+
+ AdjSize = (Size + 7) & ~7; //Minimum 8 bytes.
+ if (AdjSize > gBasePrivate->SmmAllocMemoryLength) return 0;
+
+ OrigAddress = (UINT8*)gBasePrivate->SmmAllocMemoryStart;
+ AllocatedAddress = (UINT8*)(((UINT32)OrigAddress + (Align - 1)) & ~(Align - 1));
+
+ gBasePrivate->SmmAllocMemoryStart = AllocatedAddress + AdjSize;
+ gBasePrivate->SmmAllocMemoryLength -= (UINT32)(AllocatedAddress + AdjSize - OrigAddress);
+
+ return AllocatedAddress;
+}
+
+//SMM thunk either requires AB Segment of CSM.
+#if SMM_THUNK_NO_AB_SEG == 0 || SMM_THUNK_IN_CSM == 1
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CopySmmThunkAfterBspEntry
+//
+// Description:
+// Copy SMM Thunk to immediately after SMM BSP entry.
+//
+// Input:
+// IN VOID *SmmEntryBuffer -- pointer to SMM Entry file
+// IN UINTN SmmEntryBufferSize -- Size of SMM Entry file
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CopySmmThunkAfterBspEntry (
+ IN VOID *SmmEntryBuffer,
+ IN UINTN SmmEntryBufferSize
+)
+{
+ UINT8 *SmmThunkStart = (UINT8*)gBspSmmBase + 0x8000 + gSmmEntryData->SmmThunkProcOffset;
+ UINT16 AdrFixup;
+ UINT16 SegFixup;
+
+ *(UINT32*)(gBspSmmBase + 0x8000 + gSmmEntryData->LCodeSelBaseOffset) += (UINT32)SmmThunkStart;
+ *(UINT32*)((UINT8*)SmmEntryBuffer + gSmmEntryData->LCodeSelBaseOffset) += (UINT32)SmmThunkStart;
+
+ MemCpy(SmmThunkStart,
+ (UINT8*)SmmEntryBuffer + gSmmEntryData->SmmThunkProcOffset,
+ gSmmEntryData->SmmThunkLength
+ );
+
+ gDispatcherPrivate->SmmThunkProc = (VOID(*)())SmmThunkStart;
+
+ gDispatcherPrivate->SmmThunkData = (SMM_THUNK_DATA*)
+ (((UINTN)SmmThunkStart + gSmmEntryData->SmmThunkLength + 16) & ~0xf);
+
+ ASSERT(((UINTN)gDispatcherPrivate->SmmThunkData & 0xf) == 0);
+
+ //Update Thunk to set Smm Thunk Data.
+ AdrFixup = *(UINT16*)(SmmThunkStart + 2);
+ SegFixup = *(UINT16*)(SmmThunkStart + 4);
+
+ *(UINT32*)(SmmThunkStart + AdrFixup) = (UINT32)gDispatcherPrivate->SmmThunkData;
+ *(UINT16*)(SmmThunkStart + SegFixup) = (UINT16)((UINT32)gDispatcherPrivate->SmmThunkData >> 4);
+
+ //Max 4k of stack.
+ //In this case, code, data, and stack in this 4k block.
+ //The ss=ds, and points to the end of the code,
+ // so code will have to be subtracted from the 4k top,
+ // so ss:sp = cs:1000h
+ gDispatcherPrivate->SmmThunkData->Below1MStack =
+ 0x1000
+ - gSmmEntryData->SmmEntrySize
+ - gSmmEntryData->SmmThunkLength
+ - 0xf; //Could be up to 15 bytes skipped for alignment purposes;
+ gDispatcherPrivate->SmmThunkData->Below1MStack &= ~1; //Align on word bounary;
+
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Limit = 0x3ff;
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Base = 0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CopySmmThunkAtStartABSegment
+//
+// Description:
+// Copy SMM Thunk to start of AB Segment
+//
+// Input:
+// IN VOID *SmmEntryBuffer -- pointer to SMM Entry file
+// IN UINTN SmmEntryBufferSize -- Size of SMM Entry file
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CopySmmThunkAtStartABSegment(
+ IN VOID *SmmEntryBuffer,
+ IN UINTN SmmEntryBufferSize
+)
+{
+ UINT8 *SmmThunkStart;
+ UINT16 AdrFixup;
+ UINT16 SegFixup;
+
+#if SMM_EXCLUDE_A000 != 1
+ SmmThunkStart = (UINT8*)0xa0000;
+#else
+ SmmThunkStart = (UINT8*)0xb0000;
+#endif
+
+ *(UINT32*)(gBspSmmBase + 0x8000 + gSmmEntryData->LCodeSelBaseOffset) += (UINT32)SmmThunkStart;
+
+//TODO: remove and share GDT between all CPUs. CPU0 is already copied. CPUx will copy this buffer later.
+ *(UINT32*)((UINT8*)SmmEntryBuffer + gSmmEntryData->LCodeSelBaseOffset) += (UINT32)SmmThunkStart;
+
+
+ MemCpy(SmmThunkStart,
+ (UINT8*)SmmEntryBuffer + gSmmEntryData->SmmThunkProcOffset,
+ gSmmEntryData->SmmThunkLength
+ );
+
+ gDispatcherPrivate->SmmThunkProc = (VOID(*)())SmmThunkStart;
+
+ //SmmThunkData must be aligned on 16 byte boundary.
+ gDispatcherPrivate->SmmThunkData = (SMM_THUNK_DATA*)
+ (((UINTN)SmmThunkStart + gSmmEntryData->SmmThunkLength + 16) & ~0xf);
+ ASSERT(((UINTN)gDispatcherPrivate->SmmThunkData & 0xf) == 0);
+
+ //Update Thunk to set Smm Thunk Data.
+ AdrFixup = *(UINT16*)(SmmThunkStart + 2);
+ SegFixup = *(UINT16*)(SmmThunkStart + 4);
+
+ *(UINT32*)(SmmThunkStart + AdrFixup) = (UINT32)gDispatcherPrivate->SmmThunkData;
+ *(UINT16*)(SmmThunkStart + SegFixup) = (UINT16)((UINT32)gDispatcherPrivate->SmmThunkData >> 4);
+
+ //Max 4k of stack.
+ //If in SMM, 1 block is reserved for stack and data.
+ gDispatcherPrivate->SmmThunkData->Below1MStack =
+ 0x1000
+ - gSmmEntryData->SmmThunkLength
+ - 0xf; //Could be up to 15 bytes skipped for alignment purposes;
+ gDispatcherPrivate->SmmThunkData->Below1MStack &= ~1; //Align on word boundary;
+
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Limit = 0x3ff;
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Base = 0;
+ return EFI_SUCCESS;
+}
+
+#if SMM_THUNK_IN_CSM == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CopySmmThunkInCsmEBDA
+//
+// Description:
+// Copy SMM Thunk to CSM. Data will be in EBDA.
+//
+// Input:
+// IN VOID *SmmEntryBuffer -- pointer to SMM Entry file
+// IN UINTN SmmEntryBufferSize -- Size of SMM Entry file
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CopySmmThunkInCsmEBDA (
+ VOID *SmmEntryBuffer,
+ UINTN SmmEntryBufferSize
+)
+{
+ UINT8 *SmmThunkStart;
+ UINT16 AdrFixup;
+ UINT16 SegFixup;
+ UINT32 EbdaStart;
+ EFI_STATUS Status;
+
+ //Initialize this with the pointer to the Buffer in memory.
+ //This will be update later to the newly allocated region.
+ SmmThunkStart = (UINT8*)SmmEntryBuffer + gSmmEntryData->SmmThunkProcOffset;
+
+ //In case this is 64-bits, initialize upper 32-bits to 0.
+ //Allocate Ebda, updates only the lower 32-bits.
+ gDispatcherPrivate->SmmThunkData = 0;
+
+ Status = gLegacyBiosExt->AllocateEbda(
+ gLegacyBiosExt,
+ 4,
+ (UINT32*)&gDispatcherPrivate->SmmThunkData,
+ &gDispatcherPrivate->EbdaStartOffset
+ );
+ if (EFI_ERROR(Status)) return Status;
+
+ EbdaStart = (*(UINT16*)(0x40e)) << 4;
+
+ //Max 4k of stack.
+ //If in SMM, 1 block is reserved for stack and data.
+ gDispatcherPrivate->SmmThunkData->Below1MStack = 0x1000;
+
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Limit = 0x3ff;
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Base = 0;
+
+ AdrFixup = *(UINT16*)(SmmThunkStart + 2);
+ SegFixup = *(UINT16*)(SmmThunkStart + 4);
+
+ *(UINT32*)(SmmThunkStart + AdrFixup) = (UINT32)gDispatcherPrivate->SmmThunkData - EbdaStart;
+ *(UINT16*)(SmmThunkStart + SegFixup) = (UINT16)(((UINT32)gDispatcherPrivate->SmmThunkData - EbdaStart) >> 4);
+
+ //Allocate CSM memory.
+ Status = gLegacyBios->GetLegacyRegion(
+ gLegacyBios,
+ gSmmEntryData->SmmThunkLength,
+ 0, //In e_0000 - f_ffff.
+ 1, //Byte alignment
+ &SmmThunkStart
+ );
+ if (EFI_ERROR(Status)) return Status;
+
+ *(UINT32*)(gBspSmmBase + 0x8000 + gSmmEntryData->LCodeSelBaseOffset) += (UINT32)SmmThunkStart;
+ *(UINT32*)((UINT8*)SmmEntryBuffer + gSmmEntryData->LCodeSelBaseOffset) += (UINT32)SmmThunkStart;
+
+ //Copy to CSM memory.
+ Status = gLegacyBios->CopyLegacyRegion(
+ gLegacyBios,
+ gSmmEntryData->SmmThunkLength,
+ SmmThunkStart,
+ (UINT8*)SmmEntryBuffer + gSmmEntryData->SmmThunkProcOffset
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ gDispatcherPrivate->SmmThunkProc = (VOID(*)())SmmThunkStart;
+
+ ASSERT(((UINTN)gDispatcherPrivate->SmmThunkData & 0xf) == 0);
+
+ //Max 4k of stack.
+ gDispatcherPrivate->SmmThunkData->Below1MStack = 0x1000;
+
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Limit = 0x3ff;
+ gDispatcherPrivate->SmmThunkData->LegacyIdtDesc.Base = 0;
+
+ return EFI_SUCCESS;
+}
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: LoadAndInitDispatcherImages
+//
+// Description: Load and initialize dispatcher images.
+//
+// Input:
+// IN EFI_SYSTEM_TABLE SystemTable
+// IN UINT32 NumCpus
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LoadAndInitDispatcherImages(
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN UINT32 NumCpus
+)
+{
+ EFI_STATUS Status;
+ VOID *SmmEntryBuffer;
+ UINTN SmmEntryBufferSize;
+ VOID *SmmBaseSaveBuffer;
+ VOID *Buffer;
+ UINTN BufferSize;
+ UINT32 AuthenticationStatus;
+ UINT8 *SmmBase;
+ UINT8 *ApStackTop;
+ UINT16 Bsp = gSmmHob->Bsp;
+ UINT32 i;
+ UINT32 TssBaseAddress;
+
+ SMM_ENTRY_INIT_STRUCT *SmmApEntryInit;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ EFI_HANDLE ImageHandle;
+
+ CPU_SmmMemoryInit(gSmmHob);
+
+ //
+ // Load BSP SMM real mode.
+ // This must be done before loading protected mode dispatcher
+ // because the entry point of the protected mode dispatcher
+ // initializes some of SMM real mode variables.
+ //
+
+ Status = LoadRealModeFile(&SmmEntryGuid, &SmmEntryBuffer, &SmmEntryBufferSize);
+ ASSERT_EFI_ERROR(Status);
+
+ SmmBase = (UINT8*)gBspSmmBase;
+ MemCpy(SmmBase+0x8000, SmmEntryBuffer, ((SMM_ENTRY_INIT_STRUCT*)((UINT8*)SmmEntryBuffer+4))->SmmEntrySize);
+
+ gSmmEntryData->CpuNo = 0;
+ gSmmEntryData->SmmEntryStart = (VOID*)(SmmBase + 0x8000);
+ gSmmEntryData->DispatcherPrivate = gDispatcherPrivate;
+
+ *(UINT32*)(SmmBase + 0x8000 + gSmmEntryData->GdtDescBaseOffset) += gBspSmmBase + 0x8000;
+
+ TssBaseAddress=*(UINT16*)(SmmBase + 0x8000 + gSmmEntryData->TssSelBaseOffset) + gBspSmmBase + 0x8000;
+ *(UINT16*)(SmmBase + 0x8000 + gSmmEntryData->TssSelBaseOffset) = TssBaseAddress;
+ *(UINT8*)(SmmBase + 0x8000 + gSmmEntryData->TssSelBaseOffset+2) = TssBaseAddress>>16;
+ *(UINT8*)(SmmBase + 0x8000 + gSmmEntryData->TssSelBaseOffset+5) = TssBaseAddress>>24;
+
+
+ gDispatcherPrivate->EbdaStartOffset = 0; //CopySmmThunkInCsmEBDA will update this.
+//SMM thunk either requires AB Segment of CSM.
+#if SMM_THUNK_NO_AB_SEG == 0 || SMM_THUNK_IN_CSM == 1
+#if SMM_THUNK_IN_CSM == 0
+ if (gBspSmmBase < 0x100000)
+ CopySmmThunkAfterBspEntry(SmmEntryBuffer, SmmEntryBufferSize);
+ else
+ CopySmmThunkAtStartABSegment(SmmEntryBuffer, SmmEntryBufferSize);
+#else
+ CopySmmThunkInCsmEBDA(SmmEntryBuffer, SmmEntryBufferSize);
+#endif
+#endif
+
+#ifdef EFIx64
+ //Setup pages for virtual memory after Stack.
+
+ //align page directories to 4k.
+ {
+ UINT8 *PageTable;
+ UINT32 NumAddrLines = gCpuHob->SizeOfMemorySpace;
+
+ if (NumAddrLines > SMM_PAGING_MAX_ADDRESS_LINES) NumAddrLines = SMM_PAGING_MAX_ADDRESS_LINES;
+
+ PageTable = EarlyAllocSmmMemoryAlign(GetPageTableNumPages(NumAddrLines) * 4096, 4096);
+ ASSERT(PageTable);
+ FillPageTable(NumAddrLines, PageTable);
+ gDispatcherPrivate->PageDirectories = PageTable;
+ }
+#endif
+
+ //
+ // Load and call entry of protected mode dispatcher.
+ // This must be done before AP real mode entry point because
+ // the protected mode init provides a pointer for the AP real mode
+ // to call after switching to protected mode.
+
+ Buffer = 0;
+ Status = FvReadPe32Image(
+ &gEfiSmmCoreDispatcherGuid,&Buffer,&BufferSize,
+ &AuthenticationStatus);
+ ASSERT_EFI_ERROR(Status);
+
+ gBasePrivate->Pe32DispatcherImage =
+ (VOID*)(((UINTN)gBasePrivate->SmmAllocMemoryStart + 4095) & ~4095);
+ gBasePrivate->Pe32DispatcherImageSize=EFI_SIZE_TO_PAGES(gSmmHob->ManagedMemSize);
+
+ Status=gPe32Image->LoadPeImage(
+ gPe32Image, gThisImageHandle,
+ NULL, //Either DevicePath or
+ Buffer, BufferSize, //Buffer. This will be zero if DevicePath.
+ (EFI_PHYSICAL_ADDRESS)gBasePrivate->Pe32DispatcherImage,
+ &gBasePrivate->Pe32DispatcherImageSize, &ImageHandle,
+ &EntryPoint, EFI_LOAD_PE_IMAGE_ATTRIBUTE_NONE
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ gBasePrivate->Pe32DispatcherImageSize=EFI_PAGES_TO_SIZE(gBasePrivate->Pe32DispatcherImageSize);
+
+ pBS->FreePool(Buffer);
+//
+// Give control to protected mode dispatcher. The dispatcher is in SMM memory,
+// however, the CPU is NOT in SMM mode. Currently SMM space is open.
+//
+ if (!EFI_ERROR(Status)) {
+ TRACE((TRACE_ALWAYS,"SMM.SmmDispatcher.Entry(%lX)\n",EntryPoint));
+ Status = ((DISPATCHER_ENTRY_POINT)EntryPoint)(
+ ImageHandle,
+ SystemTable,
+ gBasePrivate,
+ gDispatcherPrivate,
+#if SMM_USE_FRAMEWORK
+ &gSmstTable,
+#else
+ NULL,
+#endif
+#if SMM_USE_PI
+ &gSmstTable2
+#else
+ NULL
+#endif
+ );
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ gSmmEntryData->SmmStackTop = (VOID*)(gSmmHob->ManagedMemStart + BSP_SMM_STACK_SIZE);
+
+ //Copy ApCode to SMM region.
+
+ ApStackTop = gSmmEntryData->SmmStackTop + AP_SMM_STACK_SIZE;
+
+ for (i = 0; i < NumCpus; ++i) {
+ static UINT32 ApNum = 0; //BSP is given CPU #0, and APs 1,2...
+
+ if (i == Bsp) continue;
+ ++ApNum;
+ SmmBase = (VOID*)gSmmHob->SmmBase[i];
+ MemCpy(SmmBase + 0x8000, SmmEntryBuffer, SmmEntryBufferSize);
+ SmmApEntryInit = (SMM_ENTRY_INIT_STRUCT*) (SmmBase + 0x8004);
+ SmmApEntryInit->SmmEntryStart = SmmBase + 0x8000;
+ SmmApEntryInit->DispatcherEntry = gSmmEntryData->DispatcherEntry;
+ SmmApEntryInit->DispatcherPrivate = gDispatcherPrivate;
+ SmmApEntryInit->SmmStackTop = ApStackTop;
+ SmmApEntryInit->CpuNo = ApNum;
+
+ *(UINT32*)(SmmApEntryInit->GdtDescBaseOffset + SmmBase + 0x8000)
+ += (UINT32)SmmBase + 0x8000;
+
+ TssBaseAddress=(UINT32)((*(UINT16*)(SmmBase + 0x8000 + SmmApEntryInit->TssSelBaseOffset)) + (SmmBase + 0x8000));
+ *(UINT16*)(SmmBase + 0x8000 + SmmApEntryInit->TssSelBaseOffset) = TssBaseAddress;
+ *(UINT8*)(SmmBase + 0x8000 + SmmApEntryInit->TssSelBaseOffset+2) = (TssBaseAddress>>16);
+ *(UINT8*)(SmmBase + 0x8000 + SmmApEntryInit->TssSelBaseOffset+5) = (TssBaseAddress>>24);
+
+ ApStackTop += AP_SMM_STACK_SIZE;
+ }
+
+ pBS->FreePool(SmmEntryBuffer);
+
+ SmmBaseSaveBuffer = Malloc(SmmGetBaseSaveBufferSize());
+ ASSERT(SmmBaseSaveBuffer);
+
+ SmmSetupDefaultHandler(SmmBaseSaveBuffer, gSmmHob);
+
+ for (i = 0; i < gSmmHob->NumCpus; ++i) {
+ if (i == gBsp) {
+ SmmBaseChangeOnCpu((VOID*)gSmmHob->SmmBase[i]);
+ continue;
+ }
+
+ gMpServices->StartupThisAP(
+ gMpServices,
+ SmmBaseChangeOnCpu,
+ i, //Cpu
+ NULL,
+ 0,
+ (VOID*)gSmmHob->SmmBase[i]
+#if !(PI_SPECIFICATION_VERSION < 0x0001000A || BACKWARD_COMPATIBLE_MODE && defined(NO_PI_MP_SERVICES_SUPPORT))
+ , NULL
+#endif
+ );
+ }
+
+ SmmRemoveDefaultHandler(SmmBaseSaveBuffer);
+ pBS->FreePool(SmmBaseSaveBuffer);
+}
+
+VOID InitgBasePrivate()
+{
+ UINT32 NumCpus = gSmmHob->NumCpus;
+ gBasePrivate->SmmHob = gSmmHob;
+ gBasePrivate->CallBackFunc = 0;
+ gBasePrivate->SmmAllocMemoryStart =
+ (VOID*) (gSmmHob->ManagedMemStart + BSP_SMM_STACK_SIZE + AP_SMM_STACK_SIZE * (NumCpus - 1));
+ gBasePrivate->SmmAllocMemoryLength =
+ gSmmHob->ManagedMemSize - BSP_SMM_STACK_SIZE - AP_SMM_STACK_SIZE * (NumCpus - 1);
+}
+
+VOID InitgDispatcherPrivate()
+{
+ UINT8 i;
+ UINT32 SmmNum;
+ UINT32 NumCpus = gSmmHob->NumCpus;
+ UINT8 *XmmSaveBase;
+
+ gDispatcherPrivate = EarlyAllocSmmMemory(sizeof(*gDispatcherPrivate));
+ ASSERT(gDispatcherPrivate);
+
+ gDispatcherPrivate->NumCpus = NumCpus;
+ gDispatcherPrivate->NumCpusInSmm = 0;
+ gDispatcherPrivate->HandlerListHead = NULL;
+ gDispatcherPrivate->FloatingPointSave = FALSE;
+
+ //Allocate a XMM Save Restore on a 16-byte boundary
+ XmmSaveBase = EarlyAllocSmmMemoryAlign(NumCpus * 512, 16);
+ gDispatcherPrivate->SmmXmmSave = EarlyAllocSmmMemory(NumCpus * sizeof(VOID*));
+ for (i = 0; i < NumCpus; ++i) {
+ gDispatcherPrivate->SmmXmmSave[i] = XmmSaveBase;
+ XmmSaveBase += 512;
+ }
+
+ //Initialize SmmCpuInfo
+ gDispatcherPrivate->SmmCpuInfo = EarlyAllocSmmMemory(sizeof(SMM_CPU_INFO) * NumCpus);
+ ASSERT(gDispatcherPrivate->SmmCpuInfo);
+ MemSet(gDispatcherPrivate->SmmCpuInfo, sizeof(SMM_CPU_INFO) * NumCpus, 0);
+
+ gDispatcherPrivate->SmmCpuInfo[0].ApicId = gCpuinfoHob->Cpuinfo[gSmmHob->Bsp].ApicId;
+
+ SmmNum = 1;
+ for (i = 0; i < NumCpus; ++i) {
+ if (i == gSmmHob->Bsp) continue;
+ gDispatcherPrivate->SmmCpuInfo[SmmNum].ApicId = gCpuinfoHob->Cpuinfo[i].ApicId;
+ ++SmmNum;
+ }
+
+ //Initialize AP control for multi-threaded SMM.
+ gDispatcherPrivate->SmmApCpuControl = EarlyAllocSmmMemory(sizeof(SMM_AP_CPU_CONTROL) * NumCpus);
+ ASSERT(gDispatcherPrivate->SmmApCpuControl);
+ MemSet((VOID*)gDispatcherPrivate->SmmApCpuControl, sizeof(SMM_AP_CPU_CONTROL) * NumCpus, 0);
+
+ gDispatcherPrivate->SmmControl = gSmmControl;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CreateRuntimeInSmmFunction
+//
+// Description:
+// Create InSmm function in runtime.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *CreateRuntimeInSmmFunction()
+{
+ UINT8 *RuntimeInSmmFunc;
+ EFI_STATUS Status;
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesCode, InSmmFuncLength, &RuntimeInSmmFunc);
+ ASSERT_EFI_ERROR(Status);
+
+ MemCpy(RuntimeInSmmFunc, EfiSmmInSmm, InSmmFuncLength);
+
+ return RuntimeInSmmFunc;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: DisableSmmCallbacks
+//
+// Description:
+// This is signaled before booting or shell.
+// This makes the SMM Base protocol register/unregister unsupported.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//
+//
+// NOTE: This routine could be called multiple times right before booting.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID DisableSmmCallbacks(IN EFI_EVENT Event, IN VOID *Context)
+{
+#if SMM_USE_PI
+ EFI_HANDLE Handle = NULL;
+#endif
+ //This should only run once, even if called by different events.
+ static BOOLEAN HasRun = FALSE;
+ if (HasRun) return;
+
+ pBS->CloseEvent(Event);
+
+ //If we are following PI1.1 model we should dispatch rest of SMM drivers whose DEPEX
+ //was not TRUE at the time of the first pass.
+#if SMM_USE_PI
+ CallFuncInSmm(SmmDispatcher);
+
+ pBS->InstallMultipleProtocolInterfaces (
+ &Handle,
+ &gEfiDxeSmmReadyToLockProtocolGuid, NULL,
+ NULL
+ );
+#endif
+
+ CallFuncInSmm(SetDisallowRegistering);
+ HasRun = TRUE;
+}
+
+#if SMM_USE_PI
+VOID SmmIplGuidedEventNotify (
+ IN EFI_EVENT Event,
+ IN VOID *Context)
+{
+ CallFuncInSmm(SmmDriverDispatchHandler);
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: LocateProtocols
+//
+// Description:
+// Locate protocols needed for SMM Base.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID LocateProtocols()
+{
+ EFI_STATUS Status;
+#if SMM_USE_PI
+ Status = pBS->LocateProtocol(&gEfiSmmAccess2ProtocolGuid, NULL, &gSmmAccess);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&gEfiSmmControl2ProtocolGuid, NULL, &gSmmControl);
+ ASSERT_EFI_ERROR(Status);
+#else
+ Status = pBS->LocateProtocol(&gEfiSmmAccessProtocolGuid, NULL, &gSmmAccess);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&gEfiSmmControlProtocolGuid, NULL, &gSmmControl);
+ ASSERT_EFI_ERROR(Status);
+#endif
+
+ Status = pBS->LocateProtocol(&gEfiPe32ImageProtocolGuid, NULL, &gPe32Image);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&gEfiMpServicesProtocolGuid, NULL, &gMpServices);
+ ASSERT_EFI_ERROR(Status);
+
+#if SMM_THUNK_IN_CSM == 1
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &gLegacyBios);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosExtProtocolGuid, NULL, &gLegacyBiosExt);
+ ASSERT_EFI_ERROR(Status);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: FindHobs
+//
+// Description: Locate the HOBs needed.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FindHobs()
+{
+ VOID *FirstHob;
+ EFI_STATUS Status;
+
+ //Parse hobs to get CPU Hob.
+ //Find first Hob
+ FirstHob = GetEfiConfigurationTable(pST,&gHobListGuid);
+ if (!FirstHob) {
+ TRACE((TRACE_ALWAYS, "SmmBase.Entry()Error:Unable to find CPUInfo HOB\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ //Find SMM Hob.
+ gSmmHob = (SMM_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &gSmmHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)gSmmHob)->Name, &gSmmHobGuid) == 0) {
+ break;
+ }
+ }
+ if (EFI_ERROR(Status)) return Status;
+
+ //Find Cpu Info Hob.
+ gCpuinfoHob = (CPUINFO_HOB*) FirstHob;
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &gCpuinfoHob))) {
+ if (guidcmp(&((EFI_HOB_GUID_TYPE*)gCpuinfoHob)->Name, &gCpuinfoHobGuid) == 0) {
+ break;
+ }
+ }
+ if (EFI_ERROR(Status)) return Status;
+
+ gCpuHob = (EFI_HOB_CPU*)FirstHob;
+ Status = FindNextHobByType(EFI_HOB_TYPE_CPU, &gCpuHob);
+ if (EFI_ERROR(Status)) return Status;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SmmInitEntry
+//
+// Description: SMM Installer Entry Point.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmInitEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_EVENT BootEvent;
+ EFI_EVENT Event;
+ VOID *Registration;
+ VOID *RuntimeInSmmFunc;
+#if SMM_USE_FRAMEWORK
+ EFI_SMM_BASE_PROTOCOL *RuntimeSmmBase;
+#endif
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ gThisImageHandle = ImageHandle;
+
+ LocateProtocols();
+
+ Status = FindHobs();
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+
+ Status = gMpServices->WhoAmI(gMpServices, &gBsp);
+ ASSERT_EFI_ERROR(Status);
+
+ gBspSmmBase = gSmmHob->SmmBase[gSmmHob->Bsp];
+ gSmmEntryData = (SMM_ENTRY_INIT_STRUCT *) (gBspSmmBase + 0x8004);
+
+
+ // Allocate space in runtime services for gPrivate.
+ // This is needed because this pointer will be used by SMM during runtime.
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, sizeof(SMM_BASE_PRIVATE_STRUCT), &gBasePrivate);
+ ASSERT_EFI_ERROR(Status);
+
+ // Copy the private structure. This does not copy the pointer. It copies the entire structure.
+ *gBasePrivate = gSmmBasePrivateStruct; //Make available during runtime.
+
+ InitgBasePrivate();
+ RuntimeInSmmFunc = CreateRuntimeInSmmFunction();
+
+#if SMM_USE_FRAMEWORK
+ gEfiSmmBase.InSmm = (EFI_SMM_INSIDE_OUT)RuntimeInSmmFunc;
+#endif
+#if SMM_USE_PI
+ gEfiSmmBase2.InSmm = (EFI_SMM_INSIDE_OUT2)RuntimeInSmmFunc;
+#endif
+ gBasePrivate->InSmm = (UINT8*)RuntimeInSmmFunc + InSmmFuncOffset;
+
+ Status = gSmmAccess->Open(gSmmAccess
+#if SMM_USE_PI == 0
+ ,0
+#endif
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ InitgDispatcherPrivate();
+
+#if SMM_CACHE_SUPPORT == 1
+#ifndef NEHALEM_CPU_MODULE
+ InitSmmCacheData();
+#endif
+#endif
+
+ LoadAndInitDispatcherImages(pST, gSmmHob->NumCpus);
+
+ gSmmAccess->Close(gSmmAccess
+#if SMM_USE_PI == 0
+ , 0
+#endif
+ );
+
+ // locks SMM area so no one else can change it
+ gSmmAccess->Lock(gSmmAccess
+#if SMM_USE_PI == 0
+ , 0
+#endif
+ );
+
+ //For security reasons SMM should call from inside SMM to outside SMM before option ROMs are loaded.
+ //The following callback is registered to disable this. When this is disabled, no new SMM drivers
+ //can be registered.
+
+ //This call back is only available since core 4.6.3.5.
+ Status = RegisterProtocolCallback(
+ &gBdsAllDriversConnectedProtocolGuid,
+ DisableSmmCallbacks,
+ NULL,
+ &Event,
+ &Registration
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ //In cases where core does not support a call back before option roms are executed.
+ //The calling outside of SMM will be disabled before shell or a OS is loaded.
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK,
+ DisableSmmCallbacks,
+ NULL,
+ &BootEvent
+ );
+ ASSERT_EFI_ERROR(Status);
+
+#if SMM_USE_PI
+ //Setup Notification when BDS has finished 1st pass on loading drivers...
+ Status = pBS->CreateEventEx (
+ EVT_NOTIFY_SIGNAL,
+ TPL_CALLBACK,
+ SmmIplGuidedEventNotify,
+ NULL,
+ &gEfiEventDxeDispatchGuid,
+ &Event
+ );
+ ASSERT_EFI_ERROR(Status);
+
+#endif
+
+#if SMM_USE_FRAMEWORK
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, sizeof(EFI_SMM_BASE_PROTOCOL), &RuntimeSmmBase);
+ ASSERT_EFI_ERROR(Status);
+ *RuntimeSmmBase = gEfiSmmBase;
+#endif
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+#if SMM_USE_FRAMEWORK
+ &gEfiSmmBaseProtocolGuid, RuntimeSmmBase,
+#endif
+#if SMM_USE_PI
+ &gEfiSmmBase2ProtocolGuid, &gEfiSmmBase2,
+#endif
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmMemoryManager.c b/Core/EM/SMM/SmmMemoryManager.c
new file mode 100644
index 0000000..0e6addb
--- /dev/null
+++ b/Core/EM/SMM/SmmMemoryManager.c
@@ -0,0 +1,962 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmMemoryManager.c 12 4/22/10 4:39p Markw $
+//
+// $Revision: 12 $
+//
+// $Date: 4/22/10 4:39p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmMemoryManager.c $
+//
+// 12 4/22/10 4:39p Markw
+// Update to build with /w4 flag.
+//
+// 11 5/08/09 10:56a Markw
+// Header updates.
+//
+// 10 12/16/08 2:34a Iminglin
+// (EIP17767) The function value of FindFreeSpace, FindFreeAddress,
+// Allocate for compliance.
+//
+// 9 10/29/07 10:58a Markw
+// Smm Thunk:
+// * Code and data different segments.
+// * Code position independent.
+// * Switch for CSM for code and EBDA for data.
+//
+// 8 10/24/07 12:02p Markw
+// SMM Thunk code position independent. Data in a separate segment than
+// code in Smm Thunk.
+//
+// 7 7/25/07 2:11p Markw
+// Exclude A000 region if needed.
+//
+// 6 8/24/06 7:13p Felixp
+//
+// 5 8/24/06 7:00p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 4 4/25/06 6:25p Markw
+//
+// 3 4/21/06 5:14p Markw
+//
+// 2 7/19/05 6:09p Markw
+// Add support for managing A&B SMM segments.
+//
+// 1 1/28/05 4:32p Sivagarn
+// SMM Dispatcher Component - Initial check in
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmMemoryManager.c
+//
+// Description: Provides functions to manage SMM memory. Allocate and Free memory.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <efi.h>
+#include <AmiDxeLib.h>
+#include "SmmPrivateShared.h"
+
+#define NUM_MEM_DESCRIPTORS 30 //<--Number of descriptors before in a table. If more descriptors needed, a new table is created.
+
+typedef struct _MEMORY_DESCRIPTOR MEMORY_DESCRIPTOR;
+typedef struct _MEMORY_RESERVED_TABLE MEMORY_RESERVED_TABLE;
+
+
+//<AMI_SHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: MEMORY_DESCRIPTOR
+//
+// Description:
+// Each descriptor contains the Base and end + 1 of each
+// memory allocation. The list is sorted from lowest to highest.
+// Last linked descriptor has a Link = 0.
+// Unused descriptors have links = 0xffffffff.
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// MemBase UINT8* Base address of allocated memory.
+// MemEnd UINT8* End address + 1 of allocated memory.
+// Link MEMORY_DESCRIPTOR* Link to next Descriptor.
+//
+//---------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+struct _MEMORY_DESCRIPTOR
+{
+ UINT8 *MemBase;
+ UINT8 *MemEnd;
+ MEMORY_DESCRIPTOR *Link;
+};
+
+//<AMI_SHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: MEMORY_RESERVED_TABLE
+//
+// Description:
+// Table stores memory descriptors. If runs out of descriptors,
+// additional tables will be linked. New tables can not be removed.
+// Unused descriptors Link will be 0xffffffff.
+// Last table Link = 0.
+//
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// MemDesc MEMORY_DESCRIPTOR[] Array of memory descriptors.
+// MemNextTable MEMORY_DESCRIPTOR A descriptor used if a new table is created.
+// NumMemDescUsed UINTN Number of descriptors used.
+// Link MEMORY_RESERVED_TABLE* Link to next table.
+//
+//---------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+struct _MEMORY_RESERVED_TABLE
+{
+ MEMORY_DESCRIPTOR MemDesc[NUM_MEM_DESCRIPTORS];
+ MEMORY_DESCRIPTOR MemNextTable;
+ UINTN NumMemDescUsed;
+ MEMORY_RESERVED_TABLE *Link;
+};
+
+//Default descriptor for unused descriptor.
+MEMORY_DESCRIPTOR gDefaultMemoryDescriptor = {0,0,(MEMORY_DESCRIPTOR*)(UINTN)0xffffffff};
+
+//Default descriptor for next table.
+MEMORY_DESCRIPTOR gDefaultMemoryDescriptor2 = {0,0,0};
+
+UINT8 *gSmmMemBase;
+UINT8 *gSmmMemEnd; //Top of SMM memory + 1.
+
+MEMORY_RESERVED_TABLE gTableHead; //First memory table.
+MEMORY_DESCRIPTOR *gDescHead; //Pointer to first descriptor. (Lowest memory address.)
+
+BOOLEAN ABSegPageAlloc[32] = {
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //ASEG.
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //BSEG.
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Align8
+//
+// Description: Align the address to nearest 8 byte alignment.
+//
+// Input:
+// UINTN Value - Value to Align.
+//
+// Output:
+// UINTN - Aligned Value.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN Align8(UINTN Value)
+{
+ return (Value + 7) & ~7;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Align2n
+//
+// Description: Align the address to nearest specified 2n alignment.
+// If the alignment isn't 2^n-1, then result will be invalid.
+//
+// Input:
+// UINT8 *Value - Pointer to value to Align.
+// UINTN Alignment (This the 2n Alignment - 1. Example Alignment = 31, for 32 byte alignment.
+//
+// Output:
+// UINT8* - Aligned Value.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8* Align2n(UINT8 *Value,UINTN Alignment)
+{
+ return (UINT8*)(((UINTN)Value+Alignment) & ~Alignment);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ConstructMemoryReservedTable
+//
+// Description: Intitialize the MEMORY_RESERVED_TABLE.
+//
+// Input:
+// MEMORY_RESERVED_TABLE *Table
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ConstructMemoryReservedTable(MEMORY_RESERVED_TABLE *Table)
+{
+ UINTN i;
+ for(i=0;i<NUM_MEM_DESCRIPTORS;++i) Table->MemDesc[i] = gDefaultMemoryDescriptor;
+ Table->MemNextTable = gDefaultMemoryDescriptor2;
+ Table->Link = 0;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindFreeSpace
+//
+// Description: Find a gap of free memory of a size and possibly of an alignment. This returns
+// the preceding memory descriptor. If no gaps are found, the last memory descriptor
+// is returned.
+//
+// Input:
+// UINTN Size - Size of free space.
+// UINTN Alignment OPTIONAL - This the 2n Alignment - 1. Example Alignment = 31, for 32 byte alignment.
+//
+// Output:
+// MEMORY_DESCRIPTOR *
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Start with the first descriptor.
+// 2. Evaluate the difference (empty space) between the
+// (a) the base of address of the next descriptor and (b) the
+// aligned End address of the current descriptor.
+// 3. If the difference is greater or equal to the requested size,
+// return the link.
+// 4. Repeat 2-4, until out of descriptors.
+// 5. Return the last descriptor.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MEMORY_DESCRIPTOR *FindFreeSpace(
+ IN UINTN Size,
+ IN UINTN Alignment OPTIONAL)
+{
+ MEMORY_DESCRIPTOR *Link;
+ UINT8 *FreeStart;
+ UINT8 *UsedNext;
+
+ if (!Size) return NULL;
+
+ //Find the preceding descriptor of a memory gap of the specified size (and alignment).
+ for (Link = gDescHead; Link->Link; Link = Link->Link)
+ {
+ UINTN EmptySpace;
+ FreeStart = Link->MemEnd; //Beginning of possible gap.
+ if (Alignment) FreeStart = Align2n(FreeStart,Alignment); //Align possible gap to requested alignment.
+ UsedNext = Link->Link->MemBase; //Find end of possible gap.
+ EmptySpace = (UINTN)UsedNext - (UINTN)FreeStart; //Gap size (may be negative because of alligned start)
+ if ((INTN)EmptySpace >= (INTN) Size) return Link; //If gap size is larger or equal requested size,
+ // return link of descriptor preceding link.
+ }
+ return Link; //Out of descriptors, return last Link.
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindAddress
+//
+// Description: Find a gap of free memory of an specific Address and a size.
+// If part of the space is taken, return 0.
+// If the space is found, return the preceding memory descriptor,
+// or the last memory descriptor.
+//
+// Input:
+// UINTN Size - Size of memory.
+// UINTN Alignment - This the 2n Alignment - 1. Example Alignment = 31, for 32 byte alignment.
+//
+// Output:
+// MEMORY_DESCRIPTOR * - 0 if the address range is taken.
+// - not zero, if gap is found, or last link.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Start with the first descriptor.
+// 2. If the specifed address is in the descriptor, it is taken return 0.
+// 3. If the specified address is in the gap after the descriptor,
+// if the gap is big enough, return the preceding link, otherwise return 0.
+// 4. Repeat steps 2-4 until iterated all the descriptors.
+// 5. Return the last descriptor.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MEMORY_DESCRIPTOR *FindFreeAddress(UINT8 *Address, UINTN Size)
+{
+ MEMORY_DESCRIPTOR *Link;
+ UINT8 *FreeStart;
+ UINT8 *UsedNext;
+
+ if (!Size) return NULL;
+
+ for(Link = gDescHead; Link->Link; Link = Link->Link)
+ {
+ UINTN EmptySpace;
+ FreeStart = Link->MemEnd;
+ UsedNext = Link->Link->MemBase;
+
+ if (Address >= Link->MemBase && Address < FreeStart) return NULL; //Space taken, if address is in the descriptor.
+
+ if (Address >= FreeStart && Address <= UsedNext ) { //Is address in the, gap after the descriptor.
+ //UINTN typecasts used instead of UINT32, so complier won't give warning.
+ EmptySpace = (UINTN)UsedNext - (UINTN)Address;
+ if ((INTN)EmptySpace >= (INTN) Size) return Link; //If enough space in gap, return Link
+ return NULL; //Space not available.
+ }
+ }
+ return Link; //Out of descriptors, return last Link.
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetEmptyDescriptor
+//
+// Description: Find an unused memory descriptor in the tables.
+//
+// Input: VOID
+//
+// Output:
+// MEMORY_DESCRIPTOR * - 0 if can not allocate a new descriptor.
+// - Empty descriptor.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Find a table with empty descriptors.
+// 2. If a table is not found with an empty descriptor, go to step 5.
+// ---Found table with an empty descriptor---
+// 3. Search descriptor array for an unused descriptors (Link = 0xffffffff)
+// 4. Return the descriptor.
+// ---Did not find table with an empty descriptor---
+// 5. Search memory descriptors for free space for a new table.
+// 6. Check if last descriptor and enough free space at end, if not return 0.
+// 7. Add a new memory table descriptor at the end of the returned descriptor.
+// 8. Add new table link.
+// 9. Construct a new table.
+// 10. Return the first descriptor.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MEMORY_DESCRIPTOR * GetEmptyDescriptor()
+{
+ MEMORY_RESERVED_TABLE *Table = &gTableHead;
+ MEMORY_RESERVED_TABLE *PrevTable = NULL;
+ MEMORY_DESCRIPTOR *MemDesc;
+ UINTN i;
+
+ //Find a table with an unused descriptor.
+ while (Table && (Table->NumMemDescUsed == NUM_MEM_DESCRIPTORS)) //If table full, find next descriptor.
+ {
+ PrevTable = Table; //Keep track of last table, in case we need to create a new one.
+ Table = Table->Link;
+ }
+
+ if (Table) //Found table.
+ {
+ for(i=0;i<NUM_MEM_DESCRIPTORS;++i)
+ {
+ if (Table->MemDesc[i].Link == (MEMORY_DESCRIPTOR*)(UINTN)0xffffffff) //Search for empty descriptor
+ {
+ ++Table->NumMemDescUsed;
+ return &Table->MemDesc[i]; //Return empty descriptor.
+ }
+ } //Will not exit from this loop. An empty descriptor is guaranteed since NumMemDescUsed isn't the max.
+ }
+
+ //No more empty descriptors. Create a new table
+ MemDesc = FindFreeSpace(sizeof(MEMORY_RESERVED_TABLE),0); //Find free memory.
+
+ //This is the address of the new table if there is space available for the table. The table doesn't exist yet.
+ Table = (MEMORY_RESERVED_TABLE*) MemDesc->MemEnd;
+
+ if (!MemDesc->Link) { //If end of descriptors, check if enough space for table.
+ if ((UINT8*) Table + Align8(sizeof(MEMORY_RESERVED_TABLE)) > gSmmMemEnd) return 0; //If out of space
+ }
+
+ PrevTable->MemNextTable.Link = MemDesc->Link; //Add new table descriptor.
+ MemDesc->Link = &PrevTable->MemNextTable;
+
+ PrevTable->MemNextTable.MemBase = (UINT8*) Table; //Fill in table descriptor
+ PrevTable->MemNextTable.MemEnd = (UINT8*) Table + Align8(sizeof(MEMORY_RESERVED_TABLE));
+ PrevTable->Link = Table; //Add table end of previous table link.
+
+ ConstructMemoryReservedTable(Table); //Fill in table with default values.
+ Table->NumMemDescUsed = 1; //1 descriptor is being allocated.
+
+ return &Table->MemDesc[0]; //Return first descriptor.
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RemoveDescriptor
+//
+// Description: Find an unused memory descriptor in the tables.
+//
+// Input: MEMORY_DESCRIPTOR * Descriptor - Descriptor to free.
+//
+// Output: VOID
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Start with first table.
+// 2. Check each table's descriptor array for the descriptor to be removed.
+// 3. If descriptor not found go to step 7.
+// ---Descriptor found---
+// 4. Replace the Link with 0xffffffff.
+// 5. Reduce number of descripors being used.
+// 6. return.
+// ---Descriptor not found---
+// 7. Repeat for next table steps 2-7 until last table.
+// 8. Return
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID RemoveDescriptor(MEMORY_DESCRIPTOR * Descriptor)
+{
+ MEMORY_RESERVED_TABLE *Table;
+ UINTN i;
+
+ for (Table = &gTableHead; Table; Table = Table->Link)
+ {
+ if (Table->NumMemDescUsed==0) continue;
+ for(i=0; i < NUM_MEM_DESCRIPTORS; ++i)
+ {
+ if (&Table->MemDesc[i] == Descriptor)
+ {
+ Table->MemDesc[i].Link = (MEMORY_DESCRIPTOR*)(UINTN)0xffffffff;
+ --Table->NumMemDescUsed;
+ return;
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Allocate
+//
+// Description:
+// Allocate a memory. Caller may specify either a specific address
+// or alignment, or neither. Alignment is a minimum of 8 bytes.
+//
+// Input:
+// IN VOID *Address OPTIONAL - If caller wants to specify a specific address (Alignment is ignored).
+// IN UINTN Size - Size of allocation.
+// UINTN Alignment OPTIONAL - Specific alignment, if required. An address must not be given.
+// If alignment is set to 0, then alignment is 8 bytes. (Required by SMM spec.)
+//
+// Output:
+// VOID * - Memory allocated start address.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If no size requested return 0.
+// 2. Align Size up to the nearest 8 bytes.
+// 3. Get an empty descriptor. If none, return 0.
+// 4. If Address is given, set BaseStart to address.
+// If not aligned on 8 byte boundary, remove descriptor and return 0.
+// 5. Otherwise, set BaseStart to gSmmMemBase and
+// align if and to the given alignment. (Bottom of SMM.)
+// 6. If Size requested is greater than the Smm memory region,
+// remove descriptor and return 0.
+// 7. If no memory is previously allocated, setup descriptor, and point to it from gDescHead.
+// (Baseaddress is either the Address requested or beggining of Smm RAM.) Return address.
+// 8. Otherwise if requested memory base is lower than the base pointed by gDescHead or
+// gap between start of smm ram and memory base pointed to by gDescHead is larger than
+// the size requested is available,
+// fill in memory descriptor, and add it in front of gDescHead, replacing gDescHead. Return Address.
+// 9. Otherwise, if address address, find descriptor preceding the Address requested.
+// 10. If size requested, find the descriptor preceding the gap >= Size requested.
+// 11. If last descriptor, if not enough space left, remove descriptor, and return 0.
+// 12. Fill in descriptor. Return Address.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void * Allocate(
+ IN VOID *Address OPTIONAL,
+ IN UINTN Size,
+ UINTN Alignment OPTIONAL
+ )
+{
+ MEMORY_DESCRIPTOR *EmptyDesc = NULL;
+ MEMORY_DESCRIPTOR *FreeSpaceDesc;
+ UINT8 *BaseStart;
+
+ if (!Size) return NULL;
+
+ Size = Align8(Size); //Minimum size requested is 8 bytes.
+
+ EmptyDesc = GetEmptyDescriptor();
+ if (!EmptyDesc){
+ return NULL; //Return if out of descriptors.
+ }
+
+ if (Address)
+ {
+ if ((UINTN)Address != Align8((UINTN)Address)) {RemoveDescriptor(EmptyDesc);return 0;} //Address must be 8 byte aligned.
+ BaseStart = Address;
+ } else {
+ BaseStart = gSmmMemBase;
+ if (Alignment) BaseStart = Align2n(BaseStart,Alignment);
+ }
+
+ if (Size > (UINTN)(gSmmMemEnd - BaseStart)) { //If Smm Memory is smaller than requested, return error.
+ RemoveDescriptor(EmptyDesc);
+ return NULL;
+ }
+
+ if (!gDescHead) //True if no previous allocated memory.
+ {
+ EmptyDesc->MemBase = BaseStart;
+ EmptyDesc->Link = 0;
+
+ gDescHead = EmptyDesc;
+ //else if is true if requested memory base or gap larger than the size requested is available.
+ } else if (((INTN) gDescHead->MemBase - (INTN)BaseStart) >= (INTN) Size) {//Insert before gDescHead;
+ EmptyDesc->MemBase=BaseStart;
+ EmptyDesc->Link = gDescHead;
+ gDescHead = EmptyDesc;
+ //else is true if memory base is more than
+ } else {
+ if (Address)
+ {
+ FreeSpaceDesc = FindFreeAddress(Address,Size);
+ if (!FreeSpaceDesc)
+ {
+ RemoveDescriptor(EmptyDesc);
+ return NULL;
+ }
+ BaseStart = Address;
+ } else {
+ FreeSpaceDesc = FindFreeSpace(Size,Alignment);
+ BaseStart = FreeSpaceDesc->MemEnd;
+ if (Alignment) BaseStart = Align2n(BaseStart,Alignment);
+ }
+
+ if(!FreeSpaceDesc->Link && (UINTN)(gSmmMemEnd - BaseStart) < Size)
+ { //Last Link and not enough room.
+ RemoveDescriptor(EmptyDesc);
+ return NULL;
+ }
+
+ EmptyDesc->MemBase = BaseStart;
+ EmptyDesc->Link = FreeSpaceDesc->Link;
+ FreeSpaceDesc->Link = EmptyDesc;
+ }
+
+ EmptyDesc->MemEnd = EmptyDesc->MemBase + Size;
+
+ return EmptyDesc->MemBase;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Free
+//
+// Description: Free an allocated buffer.
+//
+// Input:
+// IN VOID *Buffer - Allocation to free.
+//
+// Output:
+// BOOLEAN - TRUE if buffer freed.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If no allocations, return FALSE.
+// 2. If Buffer to free is gDescHead, set gDescHead to next Link, remove decriptor, and return TRUE.
+// 3. Search link list for buffer.
+// 4. If not found, return FALSE.
+// 5. Set previous link of buffer to link after buffer.
+// 6. Remove Descriptor.
+// 7. Return TRUE.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN Free(VOID *Buffer)
+{
+ MEMORY_DESCRIPTOR *Link;
+ MEMORY_DESCRIPTOR *Prev;
+
+ if (!gDescHead) return FALSE;
+ if (gDescHead->MemBase == (UINT8*)Buffer)
+ {
+ Link = gDescHead;
+ gDescHead = gDescHead->Link;
+ RemoveDescriptor(Link);
+ return TRUE;
+ }
+
+ Prev = gDescHead; Link = gDescHead->Link;
+
+ while(Link)
+ {
+ if (Link->MemBase == Buffer)
+ {
+ Prev->Link = Link->Link;
+ RemoveDescriptor(Link);
+ return TRUE;
+ }
+ Prev = Link;
+ Link = Link->Link;
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Free4kPages
+//
+// Description: Free pages from buffer.
+//
+// Input:
+// IN VOID *StartAddress - Pages to free.
+// IN UINTN Pages - # of 4k pages.
+//
+// Output:
+// BOOLEAN - TRUE if buffer freed.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. If End Address is not greater than 4G, return FALSE.
+// 2. If StartAddress is not aligned 4k, return FALSE.
+// 3. If no allocations, return FALSE.
+// 4. Search for a descriptor with the StartAddress is allocated.
+// 5. If descriptor not found, return FALSE.
+// 6. Search for a descriptor with the EndAddress is allocated. These criteria must be met which searching.
+// * Allocation size of each descriptor must be 4k pages, otherwise return FALSE.
+// * End address of descriptor must match base address of next descriptor (no free space), otherwise return FALSE.
+// 7. If descriptor not found, return FALSE.
+// 8. If Start and End descriptors are not the same go to step 13.
+// -----Start and End Descriptor match exactly.----
+// 9. If Base and End descriptor match exactly, remove the descriptor from the list.
+// 10. If only Start Address matches exactly, free that space by setting the start address to the End Address.
+// 11. If only the End Address matches exactly, move the end address to Start Address.
+// Note: the end address of the descriptor is not allocated.
+// 12. return TRUE.
+// ----Start and End Descriptors are different descriptors.----
+// 13. If Base address of the Start Descriptor, adjust its end address to the space, and
+// move the Start Descriptor to the next descriptor.
+// 14. Free the descriptors up till the end descriptor.
+// 15. If the End Descriptor's End address doesn match the end address to free,
+// set the base address to the end address, to free the space.
+// 16. Otherwise, remove the end descriptor.
+// 17. Return True.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN Free4kPages(VOID *StartAddress,UINTN Pages)
+{
+ MEMORY_DESCRIPTOR *StartDesc,*EndDesc,*PrevStart = NULL,*Link,*Link2;
+ UINT8* EndAddress = (UINT8*) StartAddress + 4096 * Pages;
+ if (EndAddress < (UINT8*)StartAddress) return FALSE; //If Endaddress > 4G.
+
+ if (StartAddress != Align2n(StartAddress,4095)) return FALSE; //Must be align 4k.
+
+ //--------Find Beginning and End of Descriptors to adjust--------
+
+ if (!gDescHead) return FALSE;
+ for (StartDesc = gDescHead; StartDesc; StartDesc = StartDesc->Link)
+ {
+ if ((UINT8*)StartAddress >= StartDesc->MemBase && (UINT8*)StartAddress < StartDesc->MemEnd) break;
+ PrevStart = StartDesc;
+ }
+
+ if (!StartDesc) return FALSE;
+
+ EndDesc = StartDesc;
+ for (;;)
+ {
+ if ((UINT8*)(EndDesc->MemEnd - EndDesc->MemBase) != Align2n((UINT8*)(EndDesc->MemEnd - EndDesc->MemBase),4095))
+ return FALSE; //Size must be multiple of 4k.
+
+ if (EndAddress >= EndDesc->MemBase && EndAddress <= EndDesc->MemEnd) break;
+ if (!EndDesc->Link) return FALSE;
+ if (EndDesc->MemEnd != EndDesc->Link->MemBase) return FALSE; //Gap of unallocated space in region to free.
+ EndDesc=EndDesc->Link;
+ }
+
+ //--------Adjust Descriptors, Removing unused ones--------
+
+ if (StartDesc == EndDesc) //If true, range only affects 1 descriptor.
+ {
+ if (StartAddress == StartDesc->MemBase)
+ {
+ if (EndAddress == StartDesc->MemEnd) //If descriptor matches address exactly, free descriptor.
+ {
+ if (StartDesc == gDescHead) gDescHead = StartDesc->Link;
+ else PrevStart->Link = StartDesc->Link;
+ RemoveDescriptor(StartDesc);
+ return TRUE;
+ }
+ StartDesc->MemBase = EndAddress; //Start address matches, change start address.
+ return TRUE;
+ }
+ StartDesc->MemEnd = StartAddress; //If End address matches, change End address.
+ return TRUE;
+ }
+
+
+ //Range affects multiple descriptors.
+ if (StartAddress != StartDesc->MemBase)
+ {
+ StartDesc->MemEnd = StartAddress;
+
+ PrevStart = StartDesc;
+ StartDesc = StartDesc->Link; //Don't delete this descriptor, since it has been adjusted.
+ }
+
+
+ //Remove descriptors in the middle before End.
+ if (StartDesc == gDescHead) gDescHead = EndDesc;
+ else PrevStart->Link = EndDesc;
+
+ for (Link = StartDesc; Link != EndDesc; Link = Link2)
+ {
+ Link2 = Link->Link;
+ RemoveDescriptor(Link); //Remove Descriptors in between.
+ }
+
+
+ //If end address matches, free descriptor, otherwise adjust end address.
+ if (EndAddress != EndDesc->MemEnd)
+ {
+ EndDesc->MemBase = EndAddress;
+ } else {
+ if (EndDesc==gDescHead) gDescHead = EndDesc->Link;
+ else PrevStart->Link = EndDesc->Link;
+ RemoveDescriptor(EndDesc);
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AllocateABSegPages
+//
+// Description: Allocate SMM 4k pages of memory in A or B segment.
+//
+// Input:
+// IN EFI_ALLOCATE_TYPE Type
+// IN UINTN NumberOfPages
+// IN OUT EFI_PHYSICAL_ADDRESS *Memory
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AllocateABSegPages(
+ IN EFI_ALLOCATE_TYPE Type,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+)
+{
+ UINTN i;
+ UINT8 FreePageCount;
+ UINTN StartPage, EndPage;
+ UINT32 MaxAddress;
+
+ VOID **pMemory32 = (VOID**) Memory;
+ UINT32 Memory32 = (UINT32)(UINTN)*pMemory32;
+
+ //Only supported types.
+ if (Type != AllocateMaxAddress && Type != AllocateAddress)
+ return EFI_INVALID_PARAMETER;
+
+ if (Memory32 < 0xa0000) return EFI_NOT_FOUND;
+
+ if (Type == AllocateAddress) {
+ //Check memory alignment.
+ if ((Memory32 & (EFI_PAGE_SIZE - 1)) != 0) return EFI_INVALID_PARAMETER;
+
+ StartPage = (Memory32 - 0xa0000) >> 12;
+
+ //Check for allocation range.
+ if ((StartPage + NumberOfPages) > 32) return EFI_OUT_OF_RESOURCES;
+
+ //Check if pages are free.
+ for (i = StartPage; i < (StartPage + NumberOfPages); ++i)
+ {
+ if (ABSegPageAlloc[i] == TRUE) return EFI_OUT_OF_RESOURCES;
+ }
+ for(i = StartPage; i < (StartPage + NumberOfPages); ++i)
+ ABSegPageAlloc[i] = TRUE;
+
+ return EFI_SUCCESS;
+ }
+
+ if (Memory32 < 0xa0ffe) return EFI_OUT_OF_RESOURCES; //Max address must be whole page.
+
+ MaxAddress = Memory32 & ~(EFI_PAGE_SIZE - 1); //Round down to 4k alignment
+
+ EndPage = (Memory32 - 0xa0000) >> 12;
+ if (EndPage > 31) EndPage = 31; //Max page is 31.
+
+ //Find free pages.
+ FreePageCount = (UINT8) NumberOfPages;
+ for (i = 0; i < EndPage; ++i)
+ {
+ UINTN j;
+ if (ABSegPageAlloc[i] == TRUE)
+ {
+ FreePageCount = (UINT8) NumberOfPages;
+ continue; //Page allocated. Find next
+ }
+ if (--FreePageCount) continue;
+
+ //Found page
+ StartPage = i + 1 - NumberOfPages;
+ *pMemory32 = (VOID *)((StartPage << 12) + 0xa0000);
+
+ for (j = StartPage; j <= i; ++j) ABSegPageAlloc[j] = TRUE;
+
+ return EFI_SUCCESS;
+ }
+ return EFI_OUT_OF_RESOURCES;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: AllocateABSegPages
+//
+// Description: Allocate SMM 4k pages of memory in A or B segment.
+//
+// Input:
+// IN EFI_PHYSICAL_ADDRESS Memory - Memory address.
+// IN UINTN NumberOfPages
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FreeABSegPages(
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+)
+{
+ UINTN i, StartPage, EndPage;
+ VOID *Memory32 = (VOID*)(UINTN)Memory;
+
+ if (((UINT32)(UINTN)Memory32 & (EFI_PAGE_SIZE - 1)) != 0) return EFI_INVALID_PARAMETER;
+
+ if ((UINT32)(UINTN)Memory32 < 0xa0000) return EFI_NOT_FOUND;
+
+ StartPage = ((UINT32)(UINTN)Memory32 - 0xa0000) >> 12;
+
+ //Check for allocation range.
+ if ((StartPage + NumberOfPages) > 32) return EFI_NOT_FOUND;
+
+ EndPage = StartPage + NumberOfPages;
+
+ for (i = StartPage; i < EndPage; ++i) if (ABSegPageAlloc[i] == FALSE) return EFI_NOT_FOUND;
+ for (i = StartPage; i < EndPage; ++i) ABSegPageAlloc[i] = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeMemoryManager
+//
+// Description: Initialize the memory manager, so the functions can be used.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitializeMemoryManager(SMM_BASE_PRIVATE_STRUCT *Private) {
+ UINT32 *pSmmBase = &Private->SmmHob->SmmBase[0];
+ UINT32 NumCpus = Private->SmmHob->NumCpus;
+ UINT8 i;
+
+#if SMM_EXCLUDE_A000 == 1
+ for (i = 0; i < 16; ++i) ABSegPageAlloc[i] = TRUE;
+#endif
+
+ //Initalize Legacy memory management.
+ for (i = 0; i < NumCpus; ++i) {
+ if (pSmmBase[i] < 0x100000) {
+ UINT8 Page = (UINT8)((pSmmBase[i] - 0x98000) / 4096);
+ ASSERT(Page < 32);
+ ASSERT((Page + 7) < 32);
+ ABSegPageAlloc[Page] = TRUE;
+ ABSegPageAlloc[Page + 7] = TRUE;
+ }
+ }
+
+//If Bsp = TSEG, reserve 1 page for SMM thunk and its stack.
+ if (pSmmBase[0] > 0x100000) {
+#if SMM_EXCLUDE_A000 != 1
+ ABSegPageAlloc[0] = TRUE;
+#else
+ ABSegPageAlloc[16] = TRUE;
+#endif
+ }
+
+ //Initialize TSEG memory management.
+ gSmmMemBase = Private->SmmAllocMemoryStart;
+ gSmmMemEnd = gSmmMemBase + Private->SmmAllocMemoryLength;
+ ConstructMemoryReservedTable(&gTableHead);
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmPiSmst.c b/Core/EM/SMM/SmmPiSmst.c
new file mode 100644
index 0000000..f6a676b
--- /dev/null
+++ b/Core/EM/SMM/SmmPiSmst.c
@@ -0,0 +1,1827 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+/** SmmPiSmst.c - Protocol functions are modified verision from Intel's SMM source.
+
+ Copyright (c) 2009, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmPiSmst.c 6 3/31/11 6:52p Markw $
+//
+// $Revision: 6 $
+//
+// $Date: 3/31/11 6:52p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SMMDispatcher/SmmPiSmst.c $
+//
+// 6 3/31/11 6:52p Markw
+// Add back revisions 2 to 4.
+//
+// 5 3/31/11 6:45p Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Add PI 1.1 SMM support for reading/writing floating
+// point/smm save state.
+//
+// [Files] CpuCspLib.h, CpuCspLib.c, SmmPiSmst.c
+//
+// 4 3/15/11 2:35p Markw
+// Copyright header update.
+//
+// 3 3/14/11 3:19p Markw
+// Update for EIP 53481.
+// Rename gSmmFirmwareVender to gSmmFirmwareVendor.
+// For gSmmFirmwareVendor use CONVERT_TO_WSTRING(CORE_VENDOR); instead of
+// AMI.
+//
+// 2 3/08/11 2:00p Markw
+// Update headers and spacing.
+//
+// 1 2/07/11 3:28p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SmmPiSmst.c
+//
+// Description: PI Smst functions.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//This include should come first.
+//#include "SmmPi.h"
+#include "SmmPrivateShared.h"
+#include <AmiDxeLib.h>
+#include <Protocol\SmmCpu.h>
+#if SMM_USE_PI
+#include "SmmDispatcher.h"
+#include <AmiLib.h>
+#include <AmiCspLib.h>
+#endif
+
+CHAR16 gSmmFirmwareVendor[] = CONVERT_TO_WSTRING(CORE_VENDOR);
+
+extern UINT8 **gSmmBase;
+
+//TODOx64: move it to a library header
+VOID CPULib_Pause();
+
+VOID *Allocate(VOID *Base, UINTN Size,UINTN Alignment);
+
+EFI_STATUS AllocateABSegPages(
+ IN EFI_ALLOCATE_TYPE Type,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+);
+EFI_STATUS FreeABSegPages(
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+);
+
+BOOLEAN Free(VOID *Buffer);
+BOOLEAN Free4kPages(VOID *StartAddress,UINTN Pages);
+
+EFI_STATUS InterruptManage(
+ IN CONST EFI_GUID *HandlerType,
+ IN CONST VOID *Context OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+);
+
+VOID UpdateFrameworkSmmConfigTable(IN EFI_CONFIGURATION_TABLE *SmmConfigurationTable, IN UINTN NumberOfTableEntries);
+
+UINT8* Align2n(UINT8 *Value,UINTN Alignment);
+
+#if SMM_USE_FRAMEWORK
+extern EFI_SMM_SYSTEM_TABLE gSmmSystemTable;
+#endif
+#if SMM_USE_PI
+extern EFI_SMM_SYSTEM_TABLE2 gSmmSystemTable2;
+extern EFI_SMM_ENTRY_CONTEXT gEfiSmmEntryContext; //For now, hardcode.
+#endif
+extern SMM_DISPATCHER_PRIVATE_STRUCT *gDispatcherPrivate;
+
+#if SMM_USE_PI
+EFI_STATUS SmmMemRead(
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS SmmMemWrite(
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS SmmIoRead(
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS SmmIoWrite(
+ IN CONST EFI_SMM_CPU_IO2_PROTOCOL *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+);
+
+EFI_STATUS SmmSmstAllocatePages(
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+);
+
+EFI_STATUS SmmSmstFreePages(
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+);
+
+EFI_STATUS SmmStartupThisAp(
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN CpuNumber,
+ IN OUT VOID *ProcArguments OPTIONAL
+);
+
+#endif
+
+EFI_STATUS SmmSmstAllocatePool(
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+);
+
+EFI_STATUS SmmSmstFreePool(
+ IN VOID *Buffer
+);
+
+EFI_STATUS CalculateCrc32(
+ IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32
+);
+
+#if SMM_USE_PI
+
+EFI_STATUS SmmInstallConfigurationTable(
+ IN EFI_SMM_SYSTEM_TABLE2 *SystemTable,
+ IN EFI_GUID *Guid,
+ IN VOID *Table,
+ IN UINTN TableSize
+ );
+
+EFI_STATUS ReadSaveState(
+ IN CONST EFI_SMM_CPU_PROTOCOL *This,
+ IN UINTN Width,
+ IN EFI_SMM_SAVE_STATE_REGISTER Register,
+ IN UINTN CpuIndex,
+ OUT VOID *Buffer
+)
+{
+ UINT8 *SmmBase;
+#if SMM_USE_FRAMEWORK
+ UINT8 *SstSaveState;
+#endif
+
+ if (CpuIndex >= gDispatcherPrivate->NumCpus) return EFI_INVALID_PARAMETER;
+
+ SmmBase = gSmmBase[CpuIndex];
+#if SMM_USE_FRAMEWORK
+ SstSaveState = (UINT8*)&gSmmSystemTable.CpuSaveState[CpuIndex];
+#endif
+
+ if (Register >= EFI_SMM_SAVE_STATE_REGISTER_FCW && Register <= EFI_SMM_SAVE_STATE_REGISTER_XMM15) {
+ return CpuLib_SmmReadSaveStateFxSave(
+ gDispatcherPrivate->SmmXmmSave[CpuIndex],
+ (UINT8)Width,
+ Register,
+ (VOID*)Buffer
+ );
+ }
+
+ return CPULib_SmmReadSaveState(
+ SmmBase,
+#if SMM_USE_FRAMEWORK
+ SstSaveState,
+ TRUE,
+#else
+ NULL,
+ FALSE,
+#endif
+ (UINT8)Width,
+ Register,
+ Buffer
+ );
+}
+
+EFI_STATUS WriteSaveState(
+ IN CONST EFI_SMM_CPU_PROTOCOL *This,
+ IN UINTN Width,
+ IN EFI_SMM_SAVE_STATE_REGISTER Register,
+ IN UINTN CpuIndex,
+ IN CONST VOID *Buffer
+)
+{
+ UINT8 *SmmBase;
+#if SMM_USE_FRAMEWORK
+ UINT8 *SstSaveState;
+#endif
+
+ if (CpuIndex >= gDispatcherPrivate->NumCpus) return EFI_INVALID_PARAMETER;
+
+ SmmBase = gSmmBase[CpuIndex];
+#if SMM_USE_FRAMEWORK
+ SstSaveState = (UINT8*)&gSmmSystemTable.CpuSaveState[CpuIndex];
+#endif
+
+ if (Register >= EFI_SMM_SAVE_STATE_REGISTER_FCW && Register <= EFI_SMM_SAVE_STATE_REGISTER_XMM15) {
+ return CpuLib_SmmWriteSaveStateFxSave(
+ gDispatcherPrivate->SmmXmmSave[CpuIndex],
+ (UINT8)Width,
+ Register,
+ (VOID*)Buffer
+ );
+ }
+
+ return CPULib_SmmWriteSaveState(
+ SmmBase,
+#if SMM_USE_FRAMEWORK
+ SstSaveState,
+ TRUE,
+#else
+ NULL,
+ FALSE,
+#endif
+ (UINT8)Width,
+ Register,
+ Buffer
+ );
+}
+
+EFI_SMM_CPU_PROTOCOL gEfiSmmCpuProtocol = {
+ ReadSaveState,
+ WriteSaveState
+};
+
+
+static EFI_LIST_ENTRY SmmProtocolDatabase = INITIALIZE_LIST_HEAD_VARIABLE (SmmProtocolDatabase);
+EFI_LIST_ENTRY SmmHandleList = INITIALIZE_LIST_HEAD_VARIABLE (SmmHandleList);
+UINTN mEfiLocateHandleRequest = 0; // Added for SmmSmstLocateProtocol
+
+EFI_LIST_ENTRY mRootSmiHandlerList = INITIALIZE_LIST_HEAD_VARIABLE (mRootSmiHandlerList);
+EFI_LIST_ENTRY mSmiEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mSmiEntryList);
+
+SMM_IHANDLE *SmmGetNextLocateByRegisterNotify(
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+);
+
+
+SMM_IHANDLE *SmmGetNextLocateByProtocol (
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+);
+
+SMM_IHANDLE *SmmGetNextLocateAllHandles (
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+);
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmValidateHandle
+//
+// Description: Check whether a handle is a valid EFI_HANDLE.
+//
+// Input:
+// IN EFI_HANDLE UserHandle
+
+// Output:
+// EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SmmValidateHandle (
+ IN EFI_HANDLE UserHandle
+)
+{
+ SMM_IHANDLE *Handle;
+ Handle = (SMM_IHANDLE *)UserHandle;
+ if (Handle == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (Handle->Signature != SMM_EFI_HANDLE_SIGNATURE) {
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmFindProtocolEntry
+//
+// Description: Finds the protocol entry for the requested protocol.
+//
+// Input:
+// IN EFI_GUID *Protocol
+// IN BOOLEAN Create
+//
+// Output:
+// Protocol entry
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+SMM_PROTOCOL_ENTRY *
+SmmFindProtocolEntry (
+ IN EFI_GUID *Protocol,
+ IN BOOLEAN Create
+ )
+{
+ EFI_LIST_ENTRY *Link;
+ SMM_PROTOCOL_ENTRY *Item;
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+ EFI_STATUS Status;
+ //
+ // Search the database for the matching GUID
+ //
+
+ ProtEntry = NULL;
+ for (Link = SmmProtocolDatabase.ForwardLink;
+ Link != &SmmProtocolDatabase;
+ Link = Link->ForwardLink
+ ) {
+ Item = CR(Link, SMM_PROTOCOL_ENTRY, AllEntries, SMM_PROTOCOL_ENTRY_SIGNATURE);
+ if ( !guidcmp (&Item->ProtocolID, Protocol)) {
+ //
+ // This is the protocol entry
+ //
+ ProtEntry = Item;
+ break;
+ }
+ }
+
+ //
+ // If the protocol entry was not found and Create is TRUE, then
+ // allocate a new entry
+ //
+ if ((ProtEntry == NULL) && Create) {
+ Status = SmmSmstAllocatePool(0,sizeof(SMM_PROTOCOL_ENTRY),&ProtEntry); // ********** Probe whether it works? Typecast to VOID** to make it go thro SmmPiAllocatePool.
+ if (ProtEntry != NULL) {
+ //
+ // Initialize new protocol entry structure
+ //
+ ProtEntry->Signature = SMM_PROTOCOL_ENTRY_SIGNATURE;
+ ProtEntry->ProtocolID = *Protocol; // This done as Core Handle.C function implementation.
+ InitializeListHead (&ProtEntry->Protocols);
+ InitializeListHead (&ProtEntry->Notify);
+
+ //
+ // Add it to protocol database
+ //
+ InsertTailList (&SmmProtocolDatabase, &ProtEntry->AllEntries);
+ }
+ }
+ return ProtEntry;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmFindProtocolInterface
+//
+// Description:
+// Finds the protocol instance for the requested handle and protocol.
+// Note: This function doesn't do parameters checking, it's caller's responsibility
+// to pass in valid parameters.
+//
+// Input:
+// IN SMM_IHANDLE *Handle,
+// IN EFI_GUID *Protocol
+// IN VOID *Interface
+//
+// Output:
+// Protocol instance (NULL: Not found)
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_PROTOCOL_INTERFACE * SmmFindProtocolInterface (
+ IN SMM_IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+ )
+{
+ SMM_PROTOCOL_INTERFACE *Prot;
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+ EFI_LIST_ENTRY *Link;
+
+ Prot = NULL;
+
+ //
+ // Lookup the protocol entry for this protocol ID
+ //
+ ProtEntry = SmmFindProtocolEntry (Protocol, FALSE);
+ if (ProtEntry != NULL) {
+ //
+ // Look at each protocol interface for any matches
+ //
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link=Link->ForwardLink) {
+ //
+ // If this protocol interface matches, remove it
+ //
+ Prot = CR(Link, SMM_PROTOCOL_INTERFACE, Link, SMM_PROTOCOL_INTERFACE_SIGNATURE);
+ if (Prot->Interface == Interface && Prot->Protocol == ProtEntry) {
+ break;
+ }
+ Prot = NULL;
+ }
+ }
+ return Prot;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmNotifyProtocol
+//
+// Description: Signal event for every protocol in protocol entry.
+//
+// Input:
+// IN SMM_PROTOCOL_INTERFACE *Prot
+
+// Output:
+// VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SmmNotifyProtocol (
+ IN SMM_PROTOCOL_INTERFACE *Prot
+ )
+{
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+ SMM_PROTOCOL_NOTIFY *ProtNotify;
+ EFI_LIST_ENTRY *Link;
+
+ ProtEntry = Prot->Protocol;
+ for (Link=ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
+ ProtNotify = CR(Link, SMM_PROTOCOL_NOTIFY, Link, SMM_PROTOCOL_NOTIFY_SIGNATURE);
+ ProtNotify->Function (&ProtEntry->ProtocolID, Prot->Interface, Prot->Handle);
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstInstallProtocolInterface
+//
+// Description:
+// Wrapper function to SmmInstallProtocolInterfaceNotify. This is the public API which
+// Calls the private one which contains a BOOLEAN parameter for notifications
+//
+// Input:
+// IN OUT EFI_HANDLE *Handle
+// IN EFI_GUID *Protocol
+// IN EFI_INTERFACE_TYPE InterfaceType
+// IN VOID Interface
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstInstallProtocolInterface (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface
+)
+{
+ return SmmSmstInstallProtocolInterfaceNotify (
+ UserHandle,
+ Protocol,
+ InterfaceType,
+ Interface,
+ TRUE
+ );
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstInstallProtocolInterfaceNotify
+//
+// Description: Installs a protocol interface into the boot services environment.
+
+// Input:
+// IN OUT EFI_HANDLE *UserHandle,
+// IN EFI_GUID *Protocol,
+// IN EFI_INTERFACE_TYPE InterfaceType,
+// IN VOID *Interface,
+// IN BOOLEAN Notify
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SmmSmstInstallProtocolInterfaceNotify (
+ IN OUT EFI_HANDLE *UserHandle,
+ IN EFI_GUID *Protocol,
+ IN EFI_INTERFACE_TYPE InterfaceType,
+ IN VOID *Interface,
+ IN BOOLEAN Notify
+)
+{
+ SMM_PROTOCOL_INTERFACE *Prot;
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+ SMM_IHANDLE *Handle;
+ EFI_STATUS Status;
+ VOID *ExistingInterface;
+
+ //
+ // returns EFI_INVALID_PARAMETER if InterfaceType is invalid.
+ // Also added check for invalid UserHandle and Protocol pointers.
+ //
+
+ if (UserHandle == NULL || Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (InterfaceType != EFI_NATIVE_INTERFACE) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Print debug message
+ //
+ //DEBUG((DEBUG_LOAD | DEBUG_INFO, "SmmInstallProtocolInterface: %g %p\n", Protocol, Interface));
+
+ Status = EFI_OUT_OF_RESOURCES;
+
+ Prot = NULL;
+ Handle = NULL;
+
+ if (*UserHandle != NULL) {
+ Status = SmmSmstHandleProtocol(*UserHandle, Protocol, (VOID **)&ExistingInterface);
+
+ if (!EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
+ //
+ // Lookup the Protocol Entry for the requested protocol
+ //
+ ProtEntry = SmmFindProtocolEntry (Protocol, TRUE);
+
+ if (ProtEntry == NULL) {
+ goto Done;
+ }
+
+ //
+ // Allocate a new protocol interface structure
+ //
+ Status = SmmSmstAllocatePool(0,sizeof(SMM_PROTOCOL_INTERFACE),&Prot);
+ MemSet(Prot,(Prot == NULL) ? 0 : sizeof(SMM_PROTOCOL_INTERFACE), 0);
+
+ if (Prot == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // If caller didn't supply a handle, allocate a new one
+ //
+ Handle = (SMM_IHANDLE *)*UserHandle;
+ if (Handle == NULL) {
+ Status = SmmSmstAllocatePool(0,sizeof(SMM_IHANDLE),&Handle);
+ MemSet(Handle,(Handle == NULL) ? 0 : sizeof(SMM_IHANDLE), 0);
+ if (Handle == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ //
+ // Initialize new handler structure
+ //
+ Handle->Signature = SMM_EFI_HANDLE_SIGNATURE;
+ InitializeListHead (&Handle->Protocols);
+
+ //
+ // Add this handle to the list global list of all handles
+ // in the system
+ //
+ InsertTailList (&SmmHandleList, &Handle->AllHandles);
+ }
+
+ Status = SmmValidateHandle (Handle);
+
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ //
+ // Each interface that is added must be unique
+ //
+ ASSERT (SmmFindProtocolInterface (Handle, Protocol, Interface) == NULL);
+
+ //
+ // Initialize the protocol interface structure
+ //
+ Prot->Signature = SMM_PROTOCOL_INTERFACE_SIGNATURE;
+ Prot->Handle = Handle;
+ Prot->Protocol = ProtEntry;
+ Prot->Interface = Interface;
+
+ //
+ // Add this protocol interface to the head of the supported
+ // protocol list for this handle
+ //
+ InsertHeadList (&Handle->Protocols, &Prot->Link);
+
+ //
+ // Add this protocol interface to the tail of the
+ // protocol entry
+ //
+ InsertTailList (&ProtEntry->Protocols, &Prot->ByProtocol);
+
+ //
+ // Notify the notification list for this protocol
+ //
+ if (Notify) {
+ SmmNotifyProtocol (Prot);
+ }
+ Status = EFI_SUCCESS;
+
+Done:
+ if (!EFI_ERROR (Status)) {
+ //
+ // Return the new handle back to the caller
+ //
+ *UserHandle = Handle;
+ } else {
+ //
+ // There was an error, clean up
+ //
+ if (Prot != NULL) {
+ SmmSmstFreePool (Prot);
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstUninstallProtocolInterface
+//
+// Description:
+// Uninstalls all instances of a protocol:interfacer from a handle.
+// If the last protocol interface is remove from the handle, the
+// handle is freed.
+//
+// Input:
+// IN OUT EFI_HANDLE UserHandle
+// IN EFI_GUID *Protocol
+// IN VOID *Interface
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstUninstallProtocolInterface (
+ IN OUT EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+)
+{
+ EFI_STATUS Status;
+ SMM_IHANDLE *Handle;
+ SMM_PROTOCOL_INTERFACE *Prot;
+
+ //
+ // Check that Protocol is valid
+ //
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check that UserHandle is a valid handle
+ //
+ Status = SmmValidateHandle (UserHandle);
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Check that Protocol exists on UserHandle, and Interface matches the interface in the database
+ //
+ Prot = SmmFindProtocolInterface (UserHandle, Protocol, Interface);
+
+ if (Prot == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Remove the protocol interface from the protocol
+ //
+ Status = EFI_NOT_FOUND;
+ Handle = (SMM_IHANDLE *)UserHandle;
+
+ Prot = SmmRemoveInterfaceFromProtocol (Handle, Protocol, Interface);
+
+ if (Prot != NULL) {
+ //
+ // Remove the protocol interface from the handle
+ //
+ RemoveEntryList (&Prot->Link);
+
+ //
+ // Free the memory
+ //
+ Prot->Signature = 0;
+ SmmSmstFreePool(Prot);
+ Status = EFI_SUCCESS;
+ }
+
+ //
+ // If there are no more handlers for the handle, free the handle
+ //
+ if (IsListEmpty (&Handle->Protocols)) {
+ Handle->Signature = 0;
+ RemoveEntryList (&Handle->AllHandles);
+ SmmSmstFreePool (Handle);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmRemoveInterfaceFromProtocol
+//
+// Description: Removes Protocol from the protocol list (but not the handle list).
+//
+// Input:
+// IN SMM_IHANDLE *Handle,
+// IN EFI_GUID *Protocol
+// IN VOID *Interface
+//
+// Output: Protocol Entry
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_PROTOCOL_INTERFACE * SmmRemoveInterfaceFromProtocol (
+ IN SMM_IHANDLE *Handle,
+ IN EFI_GUID *Protocol,
+ IN VOID *Interface
+)
+{
+ SMM_PROTOCOL_INTERFACE *Prot;
+ SMM_PROTOCOL_NOTIFY *ProtNotify;
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+ EFI_LIST_ENTRY *Link;
+
+ Prot = SmmFindProtocolInterface (Handle, Protocol, Interface);
+ if (Prot != NULL) {
+ ProtEntry = Prot->Protocol;
+
+ //
+ // If there's a protocol notify location pointing to this entry, back it up one
+ //
+ for(Link = ProtEntry->Notify.ForwardLink; Link != &ProtEntry->Notify; Link=Link->ForwardLink) {
+ ProtNotify = CR(Link, SMM_PROTOCOL_NOTIFY, Link, SMM_PROTOCOL_NOTIFY_SIGNATURE);
+
+ if (ProtNotify->Position == &Prot->ByProtocol) {
+ ProtNotify->Position = Prot->ByProtocol.BackLink;
+ }
+ }
+
+ //
+ // Remove the protocol interface entry
+ //
+ RemoveEntryList (&Prot->ByProtocol);
+ }
+
+ return Prot;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmGetProtocolInterface
+//
+// Description: Locate a certain GUID protocol interface in a Handle's protocols.
+//
+// Input:
+// IN EFI_HANDLE UserHandle,
+// IN EFI_GUID *Protocol
+//
+// Output:
+// The requested protocol interface for the handle.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_PROTOCOL_INTERFACE * SmmGetProtocolInterface (
+ IN EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol
+)
+{
+ EFI_STATUS Status;
+ SMM_PROTOCOL_ENTRY *ProtEntry;
+ SMM_PROTOCOL_INTERFACE *Prot;
+ SMM_IHANDLE *Handle;
+ EFI_LIST_ENTRY *Link;
+
+ Status = SmmValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+
+ Handle = (SMM_IHANDLE *)UserHandle;
+
+ //
+ // Look at each protocol interface for a match
+ //
+ for (Link = Handle->Protocols.ForwardLink; Link != &Handle->Protocols; Link = Link->ForwardLink) {
+ Prot = CR(Link, SMM_PROTOCOL_INTERFACE, Link, SMM_PROTOCOL_INTERFACE_SIGNATURE);
+ ProtEntry = Prot->Protocol;
+ if (!guidcmp(&ProtEntry->ProtocolID, Protocol)) {
+ return Prot;
+ }
+ }
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstHandleProtocol
+//
+// Description: Queries a handle to determine if it supports a specified protocol.
+//
+// Input:
+// IN OUT EFI_HANDLE UserHandle
+// IN EFI_GUID *Protocol
+// OUT VOID **Interface
+//
+// Output:
+// EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstHandleProtocol (
+ IN OUT EFI_HANDLE UserHandle,
+ IN EFI_GUID *Protocol,
+ OUT VOID **Interface
+)
+{
+ EFI_STATUS Status;
+ SMM_PROTOCOL_INTERFACE *Prot;
+
+ //
+ // Check for invalid Protocol
+ //
+ if (Protocol == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for invalid Interface
+ //
+ if (Interface == NULL) {
+ return EFI_INVALID_PARAMETER;
+ } else {
+ *Interface = NULL;
+ }
+
+ //
+ // Check for invalid UserHandle
+ //
+ Status = SmmValidateHandle (UserHandle);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Look at each protocol interface for a match
+ //
+ Prot = SmmGetProtocolInterface (UserHandle, Protocol);
+ if (Prot == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // This is the protocol interface entry for this protocol
+ //
+ *Interface = Prot->Interface;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstRegisterProtocolNotify
+//
+// Description: Add a new protocol notification record for the request protocol.
+//
+// Input:
+// IN EFI_GUID *Protocol
+// IN EFI_SMM_NOTIFY_FN Function
+// OUT VOID **Registration
+//
+// Output:
+// EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstRegisterProtocolNotify (
+ IN CONST EFI_GUID *Protocol,
+ IN EFI_SMM_NOTIFY_FN Function,
+ OUT VOID **Registration)
+{
+ SMM_PROTOCOL_ENTRY *ProtEntry=NULL;
+ SMM_PROTOCOL_NOTIFY *ProtNotify=NULL;
+ EFI_LIST_ENTRY *Link;
+// EFI_GUID *protocol=(EFI_GUID*)Protocol;
+ EFI_STATUS Status;
+
+ if ((Protocol == NULL) || (Function == NULL) || (Registration == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ProtNotify = NULL;
+
+ //
+ // Get the protocol entry to add the notification too
+ //
+ ProtEntry = SmmFindProtocolEntry ((EFI_GUID *) Protocol, TRUE);
+ if (ProtEntry != NULL) {
+ //
+ // Find whether notification already exist
+ //
+ for (Link = ProtEntry->Notify.ForwardLink;
+ Link != &ProtEntry->Notify;
+ Link = Link->ForwardLink) {
+
+ ProtNotify = CR(Link, SMM_PROTOCOL_NOTIFY, Link, SMM_PROTOCOL_NOTIFY_SIGNATURE);
+ if ((!guidcmp(&ProtNotify->Protocol->ProtocolID, (EFI_GUID*)Protocol)) &&
+ (ProtNotify->Function == Function)
+ ) {
+
+ //
+ // Notification already exist
+ //
+ *Registration = ProtNotify;
+
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Allocate a new notification record
+ //
+ Status = SmmSmstAllocatePool(0,sizeof(SMM_PROTOCOL_NOTIFY),&ProtNotify);
+ ASSERT_EFI_ERROR(Status);
+ if (ProtNotify != NULL) {
+ ProtNotify->Signature = SMM_PROTOCOL_NOTIFY_SIGNATURE;
+ ProtNotify->Protocol = ProtEntry;
+ ProtNotify->Function = Function;
+ //
+ // Start at the ending
+ //
+ ProtNotify->Position = ProtEntry->Protocols.BackLink;
+
+ InsertTailList (&ProtEntry->Notify, &ProtNotify->Link);
+ }
+ }
+
+ //
+ // Done. If we have a protocol notify entry, then return it.
+ // Otherwise, we must have run out of resources trying to add one
+ //
+ Status = EFI_OUT_OF_RESOURCES;
+ if (ProtNotify != NULL) {
+ *Registration = ProtNotify;
+ Status = EFI_SUCCESS;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstLocateHandle
+//
+// Description: Locates the requested handle(s) and returns them in Buffer.
+//
+// Input:
+// IN EFI_LOCATE_SEARCH_TYPE SearchType
+// IN EFI_GUID *Protocol OPTIONAL
+// IN VOID *SearchKey OPTIONAL
+// IN OUT UINTN *BufferSize
+// OUT EFI_HANDLE *Buffer
+//
+// Output:
+// EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SmmSmstLocateHandle (
+ IN EFI_LOCATE_SEARCH_TYPE SearchType,
+ IN EFI_GUID *Protocol OPTIONAL,
+ IN VOID *SearchKey OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT EFI_HANDLE *Buffer
+)
+
+{
+ EFI_STATUS Status;
+ SMM_LOCATE_POSITION Position;
+ SMM_PROTOCOL_NOTIFY *ProtNotify;
+ SMM_CORE_GET_NEXT GetNext;
+ UINTN ResultSize;
+ SMM_IHANDLE *Handle;
+ SMM_IHANDLE **ResultBuffer;
+ VOID *Interface;
+
+ if (BufferSize == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((*BufferSize > 0) && (Buffer == NULL)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ GetNext = NULL;
+
+ //
+ // Set initial position
+ //
+ Position.Protocol = Protocol;
+ Position.SearchKey = SearchKey;
+ Position.Position = &SmmHandleList;
+
+ ResultSize = 0;
+ ResultBuffer = (SMM_IHANDLE **) Buffer;
+ Status = EFI_SUCCESS;
+
+ //
+ // Get the search function based on type
+ //
+ switch (SearchType) {
+ case AllHandles:
+ GetNext = SmmGetNextLocateAllHandles;
+ break;
+
+ case ByRegisterNotify:
+ GetNext = SmmGetNextLocateByRegisterNotify;
+ //
+ // Must have SearchKey for locate ByRegisterNotify
+ //
+ if (SearchKey == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ }
+ break;
+ case ByProtocol:
+ GetNext = SmmGetNextLocateByProtocol;
+ if (Protocol == NULL) {
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+ //
+ // Look up the protocol entry and set the head pointer
+ //
+ Position.ProtEntry = SmmFindProtocolEntry (Protocol, FALSE);
+ if (Position.ProtEntry == NULL) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+ Position.Position = &Position.ProtEntry->Protocols;
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Enumerate out the matching handles
+ //
+ mEfiLocateHandleRequest += 1;
+ for (; ;) {
+ //
+ // Get the next handle. If no more handles, stop
+ //
+ Handle = GetNext (&Position, &Interface);
+ if (NULL == Handle) {
+ break;
+ }
+
+ //
+ // Increase the resulting buffer size, and if this handle
+ // fits return it
+ //
+ ResultSize += sizeof(Handle);
+ if (ResultSize <= *BufferSize) {
+ *ResultBuffer = Handle;
+ ResultBuffer += 1;
+ }
+ }
+
+ //
+ // If the result is a zero length buffer, then there were no
+ // matching handles
+ //
+ if (ResultSize == 0) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ //
+ // Return the resulting buffer size. If it's larger than what
+ // was passed, then set the error code
+ //
+ if (ResultSize > *BufferSize) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ *BufferSize = ResultSize;
+
+ if (SearchType == ByRegisterNotify && !EFI_ERROR(Status)) {
+ ASSERT (SearchKey != NULL);
+ //
+ // If this is a search by register notify and a handle was
+ // returned, update the register notification position
+ //
+ ProtNotify = SearchKey;
+ ProtNotify->Position = ProtNotify->Position->ForwardLink;
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstLocateProtocol
+//
+// Description:
+// Return the first Protocol Interface that matches the Protocol GUID. If
+// Registration is passed in, return a Protocol Instance that was just add
+// to the system. If Registration is NULL return the first Protocol Interface
+// you find.
+//
+// Input:
+// IN EFI_GUID *Protocol,
+// IN VOID *Registration OPTIONAL
+// OUT VOID **Interface
+//
+// Output:
+// EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstLocateProtocol (
+ IN EFI_GUID *Protocol,
+ IN VOID *Registration OPTIONAL,
+ OUT VOID **Interface
+)
+{
+ EFI_STATUS Status;
+ SMM_LOCATE_POSITION Position;
+ SMM_PROTOCOL_NOTIFY *ProtNotify;
+ SMM_IHANDLE *Handle;
+
+ if (Interface == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Protocol == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ *Interface = NULL;
+ Status = EFI_SUCCESS;
+ //
+ // Set initial position
+ //
+ Position.Protocol = Protocol;
+ Position.SearchKey = Registration;
+ Position.Position = &SmmHandleList;
+
+ mEfiLocateHandleRequest += 1;
+
+ if (Registration == NULL) {
+ //
+ // Look up the protocol entry and set the head pointer
+ //
+ Position.ProtEntry = SmmFindProtocolEntry (Protocol, FALSE);
+ if (Position.ProtEntry == NULL) {
+ return EFI_NOT_FOUND;
+ }
+ Position.Position = &Position.ProtEntry->Protocols;
+
+ Handle = SmmGetNextLocateByProtocol (&Position, Interface);
+ } else {
+ Handle = SmmGetNextLocateByRegisterNotify (&Position, Interface);
+ }
+
+ if (Handle == NULL) {
+ Status = EFI_NOT_FOUND;
+ } else if (Registration != NULL) {
+ //
+ // If this is a search by register notify and a handle was
+ // returned, update the register notification position
+ //
+ ProtNotify = Registration;
+ ProtNotify->Position = ProtNotify->Position->ForwardLink;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmGetNextLocateAllHandles
+//
+// Description:
+// Find next handle.
+//
+// Input:
+// IN OUT SMM_LOCATE_POSITION *Position,
+// OUT VOID **Interface
+//
+// Output:
+// SMM_IHANDLE
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_IHANDLE *SmmGetNextLocateAllHandles (
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+)
+{
+ SMM_IHANDLE *Handle;
+
+ //
+ // Next handle
+ //
+ Position->Position = Position->Position->ForwardLink;
+
+ //
+ // If not at the end of the list, get the handle
+ //
+ Handle = NULL;
+ *Interface = NULL;
+ if (Position->Position != &SmmHandleList) {
+ Handle = CR (Position->Position, SMM_IHANDLE, AllHandles, SMM_EFI_HANDLE_SIGNATURE);
+ }
+ return Handle;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmGetNextLocateByRegisterNotify
+//
+// Description: Routine to get the next Handle, when you are searching for register protocol
+// notifies.
+//
+// Input:
+// IN OUT SMM_LOCATE_POSITION *Position
+// OUT VOID **Interface
+//
+// Output:
+// An pointer to SMM_IHANDLE if the next Position is not the end of the list.
+// Otherwise,NULL is returned.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_IHANDLE *SmmGetNextLocateByRegisterNotify (
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+)
+{
+ SMM_IHANDLE *Handle;
+ SMM_PROTOCOL_NOTIFY *ProtNotify;
+ SMM_PROTOCOL_INTERFACE *Prot;
+ EFI_LIST_ENTRY *Link;
+
+ Handle = NULL;
+ *Interface = NULL;
+ ProtNotify = Position->SearchKey;
+
+ //
+ // If this is the first request, get the next handle
+ //
+ if (ProtNotify != NULL) {
+ ASSERT(ProtNotify->Signature == SMM_PROTOCOL_NOTIFY_SIGNATURE);
+ Position->SearchKey = NULL;
+
+ //
+ // If not at the end of the list, get the next handle
+ //
+ Link = ProtNotify->Position->ForwardLink;
+ if (Link != &ProtNotify->Protocol->Protocols) {
+ Prot = CR (Link, SMM_PROTOCOL_INTERFACE, ByProtocol, SMM_PROTOCOL_INTERFACE_SIGNATURE);
+ Handle = Prot->Handle;
+ *Interface = Prot->Interface;
+ }
+ }
+ return Handle;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmGetNextLocateByProtocol
+//
+// Description: Routine to get the next Handle, when you are searching for a given protocol.
+//
+// Input:
+// IN OUT SMM_LOCATE_POSITION *Position
+// OUT VOID **Interface
+//
+// Output:
+// An pointer to SMM_IHANDLE if the next Position is not the end of the list.
+// Otherwise,NULL is returned.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_IHANDLE *SmmGetNextLocateByProtocol (
+ IN OUT SMM_LOCATE_POSITION *Position,
+ OUT VOID **Interface
+)
+{
+ SMM_IHANDLE *Handle;
+ EFI_LIST_ENTRY *Link;
+ SMM_PROTOCOL_INTERFACE *Prot;
+
+ Handle = NULL;
+ *Interface = NULL;
+
+ for (; ;) {
+ //
+ // Next entry
+ //
+ Link = Position->Position->ForwardLink;
+ Position->Position = Link;
+
+ //
+ // If not at the end, return the handle
+ //
+ if (Link == &Position->ProtEntry->Protocols) {
+ Handle = NULL;
+ break;
+ }
+
+ //
+ // Get the handle
+ //
+ Prot = CR(Link, SMM_PROTOCOL_INTERFACE, ByProtocol, SMM_PROTOCOL_INTERFACE_SIGNATURE);
+ Handle = Prot->Handle;
+ *Interface = Prot->Interface;
+
+ //
+ // If this handle has not been returned this request, then
+ // return it now
+ //
+ if (Handle->LocateRequest != mEfiLocateHandleRequest) {
+ Handle->LocateRequest = mEfiLocateHandleRequest;
+ break;
+ }
+ }
+ return Handle;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmCoreFindSmiEntry
+//
+// Description: Find Smi Entry
+//
+// Input:
+// IN EFI_GUID *HandlerType
+// IN BOOLEAN Create
+//
+// Output: SMM_SMI_ENTRY
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+SMM_SMI_ENTRY* SmmCoreFindSmiEntry (
+ IN EFI_GUID *HandlerType,
+ IN BOOLEAN Create
+)
+{
+ EFI_LIST_ENTRY *Link;
+ SMM_SMI_ENTRY *Item;
+ SMM_SMI_ENTRY *SmiEntry;
+ EFI_STATUS Status;
+
+ //
+ // Search the SMI entry list for the matching GUID
+ //
+ SmiEntry = NULL;
+ for (Link = mSmiEntryList.ForwardLink;
+ Link != &mSmiEntryList;
+ Link = Link->ForwardLink) {
+
+ Item = CR (Link, SMM_SMI_ENTRY, AllEntries, SMI_ENTRY_SIGNATURE);
+ if (!guidcmp(&Item->HandlerType, HandlerType)) {
+ //
+ // This is the SMI entry
+ //
+ SmiEntry = Item;
+ break;
+ }
+ }
+
+ //
+ // If the protocol entry was not found and Create is TRUE, then
+ // allocate a new entry
+ //
+ if ((SmiEntry == NULL) && Create) {
+ Status = SmmSmstAllocatePool (0,sizeof(SMM_SMI_ENTRY),&SmiEntry);
+ if (EFI_ERROR(Status) || (SmiEntry != NULL)) {
+ //
+ // Initialize new SMI entry structure
+ //
+ SmiEntry->Signature = SMI_ENTRY_SIGNATURE;
+ MemCpy((VOID *)&SmiEntry->HandlerType, HandlerType, sizeof(EFI_GUID));
+ InitializeListHead (&SmiEntry->SmiHandlers);
+
+ // Add it to SMI entry list
+ InsertTailList (&mSmiEntryList, &SmiEntry->AllEntries);
+ }
+ }
+ return SmiEntry;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmiHandlerRegister
+//
+// Description: Register SMI Handle
+//
+// Input:
+// IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler,
+// IN CONST EFI_GUID *HandlerType OPTIONAL,
+// OUT EFI_HANDLE *DispatchHandle
+//
+// Output: EFI_STATUS
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmiHandlerRegister(
+ IN EFI_SMM_HANDLER_ENTRY_POINT2 Handler,
+ IN CONST EFI_GUID *HandlerType OPTIONAL,
+ OUT EFI_HANDLE *DispatchHandle
+)
+{
+ HANDLER_LIST *HandlerInfo, *Link;
+
+ if (gSmmSystemTable2.SmmAllocatePool(0, sizeof(HANDLER_LIST), &HandlerInfo) != EFI_SUCCESS)
+ return EFI_OUT_OF_RESOURCES;
+
+ HandlerInfo->IsPi = TRUE;
+ HandlerInfo->EntryPoint = Handler;
+ HandlerInfo->SmmImageHandle = HandlerInfo;
+ if (HandlerType) {
+ MemCpy(&HandlerInfo->HandlerType, (EFI_GUID*)HandlerType, sizeof(EFI_GUID));
+ HandlerInfo->IsRoot = FALSE;
+ } else HandlerInfo->IsRoot = TRUE;
+
+ HandlerInfo->Link = 0;
+
+ //If very first add.
+ if (!gDispatcherPrivate->HandlerListHead) {
+ gDispatcherPrivate->HandlerListHead = HandlerInfo;
+ return EFI_SUCCESS;
+ }
+
+ //Add to end of list.
+ for (Link = gDispatcherPrivate->HandlerListHead; Link->Link; Link = Link->Link); //Find end of list
+ Link->Link = HandlerInfo;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS SmiHandlerUnRegister(IN EFI_HANDLE DispatchHandle)
+{
+ HANDLER_LIST *Link = gDispatcherPrivate->HandlerListHead;
+ HANDLER_LIST *PrevLink;
+
+ while (Link != 0) {
+ if (Link->SmmImageHandle == DispatchHandle) {
+ if (Link == gDispatcherPrivate->HandlerListHead) {
+ gDispatcherPrivate->HandlerListHead = Link->Link;
+ } else {
+ PrevLink->Link = Link->Link;
+ }
+ SmmSmstFreePool(Link);
+ return EFI_SUCCESS;
+ }
+ PrevLink = Link;
+ Link = Link->Link;
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+EFI_SMM_SYSTEM_TABLE2 gSmmSystemTable2 =
+{
+ { //Header
+ SMM_SMST_SIGNATURE2, //Signature
+ EFI_SMM_SYSTEM_TABLE_REVISION2, //Revison will show 1.1
+ sizeof(EFI_SMM_SYSTEM_TABLE2), //Header size
+ 0, //CRC32
+ 0 //Reserved
+ },
+ gSmmFirmwareVendor, //Vendor
+ 0, //Vendor version
+
+ SmmInstallConfigurationTable,
+ {
+ {
+ SmmMemRead,
+ SmmMemWrite
+ },
+ {
+ SmmIoRead,
+ SmmIoWrite
+ }
+ },
+ SmmSmstAllocatePool,
+ SmmSmstFreePool,
+ SmmSmstAllocatePages,
+ SmmSmstFreePages,
+ SmmStartupThisAp,
+ 1, //Executing CPU
+ 1, //Number of CPUs
+ 0, //CpuSaveStateSize...PI 1.1
+ 0, //Cpu Save State
+ 0, //Number of Table Entries
+ 0, //Table pointer
+ SmmSmstInstallProtocolInterface,
+ SmmSmstUninstallProtocolInterface,
+ SmmSmstHandleProtocol,
+ SmmSmstRegisterProtocolNotify,
+ SmmSmstLocateHandle,
+ SmmSmstLocateProtocol,
+ InterruptManage,
+ SmiHandlerRegister,
+ SmiHandlerUnRegister
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InsertTailList
+//
+// Description:
+// Insert a Node into the end of a doubly linked list. The list must have
+// been initialized with InitializeListHead () before using this function.
+//
+//
+// Input:
+// IN EFI_LIST_ENTRY *ListHead
+// IN EFI_LIST_ENTRY *Entry
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InsertTailList (
+ IN EFI_LIST_ENTRY *ListHead,
+ IN EFI_LIST_ENTRY *Entry
+)
+{
+ EFI_LIST_ENTRY *_ListHead;
+ EFI_LIST_ENTRY *_BackLink;
+
+ _ListHead = ListHead;
+ _BackLink = _ListHead->BackLink;
+ Entry->ForwardLink = _ListHead;
+ Entry->BackLink = _BackLink;
+ _BackLink->ForwardLink = Entry;
+ _ListHead->BackLink = Entry;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InsertHeadList
+//
+// Description:
+// Insert a Node into the start of a doubly linked list. The list must have
+// been initialized with InitializeListHead () before using this function.
+//
+// Input:
+// IN EFI_LIST_ENTRY *ListHead
+// IN EFI_LIST_ENTRY *Entry
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InsertHeadList (
+ IN EFI_LIST_ENTRY *ListHead,
+ IN EFI_LIST_ENTRY *Entry
+)
+{
+ EFI_LIST_ENTRY *_ListHead;
+ EFI_LIST_ENTRY *_ForwardLink;
+
+ _ListHead = ListHead;
+ _ForwardLink = _ListHead->ForwardLink;
+ Entry->ForwardLink = _ForwardLink;
+ Entry->BackLink = _ListHead;
+ _ForwardLink->BackLink = Entry;
+ _ListHead->ForwardLink = Entry;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeListHead
+//
+// Description:
+// Initialize the head of the List. The caller must allocate the memory
+// for the EFI_LIST. This function must be called before the other linked
+// list macros can be used.
+//
+// Input:
+// IN EFI_LIST_ENTRY *List
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitializeListHead (
+ IN EFI_LIST_ENTRY *List
+)
+{
+ List->ForwardLink = List;
+ List->BackLink = List;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsListEmpty
+//
+// Description:
+// Return TRUE is the list contains zero nodes. Otherwise return FALSE.
+// The list must have been initialized with InitializeListHead () before using
+// this function.
+//
+// Input:
+// IN EFI_LIST_ENTRY *List
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsListEmpty (
+ IN EFI_LIST_ENTRY *List
+)
+{
+ return (BOOLEAN)(List->ForwardLink == List);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RemoveEntryList
+//
+// Description:
+// Remove Node from the doubly linked list. It is the caller's responsibility
+// to free any memory used by the entry if needed. The list must have been
+// initialized with InitializeListHead () before using this function.
+//
+// Input:
+// IN EFI_LIST_ENTRY *Entry
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID RemoveEntryList (
+ EFI_LIST_ENTRY *Entry
+)
+{
+ EFI_LIST_ENTRY *_ForwardLink;
+ EFI_LIST_ENTRY *_BackLink;
+
+ _ForwardLink = Entry->ForwardLink;
+ _BackLink = Entry->BackLink;
+ _BackLink->ForwardLink = _ForwardLink;
+ _ForwardLink->BackLink = _BackLink;
+
+#if EFI_DEBUG
+ Entry->ForwardLink = (EFI_LIST_ENTRY *) 0xAFAFAFAF;
+ Entry->BackLink = (EFI_LIST_ENTRY *) 0xAFAFAFAF;
+#endif
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeSmmPiSystemTable
+//
+// Description:
+// Initialize SMM PI System Table.
+//
+// Input: VOID
+//
+// Output: VOID
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitializeSmmPiSystemTable()
+{
+ UINT32 CRC32;
+ UINT32 NumCpus = gDispatcherPrivate->NumCpus;
+ UINT32 i;
+
+ gSmmSystemTable2.NumberOfCpus = NumCpus;
+
+ gSmmSystemTable2.CpuSaveStateSize = Allocate(0,sizeof(UINTN) * NumCpus,0);
+ for (i = 0; i < NumCpus; ++i) gSmmSystemTable2.CpuSaveStateSize[i] = MAX_SMM_SAVE_STATE_SIZE;
+
+ gSmmSystemTable2.CpuSaveState = Allocate(0,sizeof(VOID*) * NumCpus,0);
+ for (i = 0; i < NumCpus; ++i) {
+ gSmmSystemTable2.CpuSaveState[i] = (VOID*)(gSmmBase[i] + 0x10000 - MAX_SMM_SAVE_STATE_SIZE);
+ }
+
+ CalculateCrc32(&gSmmSystemTable2, sizeof(EFI_SMM_SYSTEM_TABLE2), &CRC32);
+ gSmmSystemTable2.Hdr.CRC32 = CRC32;
+
+ gEfiSmmEntryContext.SmmStartupThisAp = gSmmSystemTable2.SmmStartupThisAp;
+ gEfiSmmEntryContext.NumberOfCpus = gSmmSystemTable2.NumberOfCpus;
+ gEfiSmmEntryContext.CpuSaveStateSize = gSmmSystemTable2.CpuSaveStateSize;
+ gEfiSmmEntryContext.CpuSaveState = gSmmSystemTable2.CpuSaveState;
+}
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/SmmPrivateShared.h b/Core/EM/SMM/SmmPrivateShared.h
new file mode 100644
index 0000000..46f94e9
--- /dev/null
+++ b/Core/EM/SMM/SmmPrivateShared.h
@@ -0,0 +1,392 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SMM/SmmPrivateShared.h 36 4/01/11 10:08a Markw $
+//
+// $Revision: 36 $
+//
+// $Date: 4/01/11 10:08a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SMM/SmmPrivateShared.h $
+//
+// 36 4/01/11 10:08a Markw
+// [TAG] EIP57440
+// [Category] New Feature
+// [Description] Add PI 1.1 SMM support for reading/writing floating
+// point/smm save state.
+//
+// [Files] CpuCspLib.h, CpuCspLib.c, SmmPiSmst.c, SmmPrivateShared.h,
+// SmmHdr.equ, SmmInit.c
+//
+//
+// 35 2/07/11 4:07p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+// 34 8/11/09 11:46a Markw
+// Removed Legacy registration. This is removed from latest PI and not
+// used by projects.
+//
+// 33 7/08/09 8:04p Markw
+// Update headers.
+//
+// 32 1/22/09 12:59p Markw
+// EIP #18671 (OPEN) Clear SW SMI status and set EOS inside SMM. Add
+// SmmControl to private structure.
+//
+// 31 12/24/08 10:53a Markw
+// EIP #18423: Adjust EBDA location as more EBDA data is allocated.
+//
+// 30 12/23/08 2:15p Markw
+// EIP #17900 Set up TSS. Borland C in DOS hangs otherwise.
+//
+// 29 11/21/08 4:56p Markw
+// Add SmmInit to SMM_ENTRY_STRUCT for SMM init for first normal/S3 boot.
+// 32-bit CPU count.
+//
+// 28 9/26/08 4:52p Markw
+// The Private InSmm is now a pointer.
+//
+// 27 9/09/08 3:05p Markw
+// Add in SMM_BASE_PRIVATE_STRUCT, Dispatcher pe32 Image Start.
+//
+// 26 9/07/08 12:41a Markw
+// Separate SMM Private structure into inside SMM and outside SMM
+// structure.
+//
+// 25 8/28/08 3:51p Markw
+// Added support for saving/restoring chipset context.
+//
+// 24 6/09/08 5:57p Markw
+// Add SMM_CPU_INFO for Cpu specific information in the Private structure.
+//
+// 23 5/23/08 11:18a Markw
+// Add member for disallowing callbacks.
+//
+// 22 4/04/08 6:21p Markw
+// Add Smrr MSR to SMM_BASE_PRIVATE_STRUCT.
+//
+// 21 3/03/08 6:35p Markw
+// Added 32-bit register for smm thunk.
+//
+// 20 11/14/07 2:03p Markw
+// Added SMRR support and updated SMM Cache for non-SMRR.
+//
+// 19 10/29/07 10:58a Markw
+// Smm Thunk:
+// * Code and data different segments.
+// * Code position independent.
+// * Switch for CSM for code and EBDA for data.
+//
+// 18 10/24/07 12:00p Markw
+// SMM Thunk code position independent. Data in a separate segment than
+// code in Smm Thunk.
+//
+// 17 9/10/07 1:38p Markw
+// Add IDT entry.
+//
+// 16 6/08/07 6:51p Markw
+// Save/Restore XMM.
+//
+// 15 1/11/07 12:28p Markw
+// Adjusted location of fields in structure for removal of legacy.
+//
+// 14 1/09/07 6:40p Markw
+// Update BSP Entry Structure to remove dependencies on SMM_BSP_BASE.
+//
+// 13 12/29/06 4:44p Markw
+// Add Smm Cache Support and update CPU syncronization.
+//
+// 12 12/21/06 5:19p Markw
+// Remove old unused SmmStackSize from Private structure.
+//
+// 11 11/13/06 11:24a Markw
+// Updated structure for Ap Entry.
+//
+// 10 9/18/06 11:47a Markw
+// Add a check to guarentee that BSP and Ap can't get out of sync.
+//
+// 9 8/24/06 3:27p Felixp
+// Preliminary x64 support (work in progress)
+//
+// 8 5/08/06 6:47p Markw
+// Use Hob for initalizing SMM.
+//
+// 7 2/03/06 10:26a Markw
+// Moved Smm Base change to PEI CPU.
+//
+// 6 1/13/06 11:27a Markw
+// Added SMM Thunk support.
+//
+// 5 1/10/06 2:56p Markw
+// Add support for multi-threadding and sync all CPUs during entry/exit of
+// SMM.
+//
+// 4 8/10/05 5:01p Markw
+// Added ChangeBaseInfo Structure for changing bases and passing
+// information to a runtime function.
+//
+// 3 7/12/05 11:08a Markw
+// Added TSEG start to private structure.
+//
+// 2 7/11/05 1:05p Markw
+// Removed isCallback from structure. Chaged Io Port from UINT8 to UINT16.
+//
+// 1 1/28/05 4:29p Sivagarn
+// Generic SMM module - Intial Check in
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SMMPrivateShared.h
+//
+// Description: Header file for the SMM shared equates and structures
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __SMM_PRIVATE_SHARED__H__
+#define __SMM_PRIVATE_SHARED__H__
+
+#include <efi.h>
+#include <Protocol\SmmThunk.h>
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010000)
+#define USE_FV2 1
+#else
+#define USE_FV2 0
+#endif
+
+#define SMM_USE_FRAMEWORK 1
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#define SMM_USE_PI 1
+#else
+#define SMM_USE_PI 0
+#endif
+
+#include <AmiHobs.h>
+#include <Token.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SMMBASE_CALLBACK 0xf0
+typedef struct _SMM_ENTRY_INIT_STRUCT SMM_ENTRY_INIT_STRUCT;
+typedef struct _SMM_THUNK_DATA SMM_THUNK_DATA;
+
+typedef VOID (*SMM_AP_PROCEDURE) (
+ IN VOID *Buffer
+);
+
+typedef struct {
+ SMM_AP_PROCEDURE Procedure;
+ VOID *ProcArguments;
+} SMM_AP_CPU_CONTROL;
+
+
+typedef struct _HANDLER_LIST HANDLER_LIST;
+struct _HANDLER_LIST
+{
+ EFI_GUID HandlerType; //Only filled if non-root.
+ VOID *EntryPoint;
+ EFI_HANDLE SmmImageHandle;
+ VOID *Context;
+ VOID *CommunicationBuffer; //Framework only
+ UINTN *SourceSize; //Framework only
+
+ BOOLEAN IsRoot;
+ BOOLEAN IsPi;
+ HANDLER_LIST *Link;
+};
+
+typedef struct {
+ EFI_DEVICE_PATH_PROTOCOL *FilePath;
+ VOID *SourceBuffer;
+ UINTN SourceSize;
+ EFI_HANDLE *ImageHandle;
+ BOOLEAN LegacyIA32Binary;
+} REGISTER_HANDLER_CALLBACK;
+
+typedef struct {
+ EFI_HANDLE ImageHandle;
+} UNREGISTER_HANDLER_CALLBACK;
+
+typedef struct {
+ EFI_HANDLE ImageHandle;
+ VOID *CommunicationBuffer;
+ UINTN *SourceSize;
+} COMMUNICATE_CALLBACK;
+
+typedef struct {
+ UINTN Size;
+ VOID **Buffer;
+} ALLOCATE_POOL_CALLBACK;
+
+typedef struct {
+ VOID *Buffer;
+} FREE_POOL_CALLBACK;
+
+
+typedef union {
+ REGISTER_HANDLER_CALLBACK RegisterHandler;
+ UNREGISTER_HANDLER_CALLBACK UnregisterHandler;
+ COMMUNICATE_CALLBACK Communicate;
+ ALLOCATE_POOL_CALLBACK AllocatePool;
+ FREE_POOL_CALLBACK FreePool;
+} CALLBACKS;
+
+#pragma pack (1)
+typedef struct {
+ UINT16 Limit;
+ UINTN Base; //This shared between 32 bit and 64 bit.
+} DESCRIPTOR_TABLE;
+#pragma pack()
+
+typedef struct {
+ BOOLEAN InSmm;
+ UINT32 ApicId;
+} SMM_CPU_INFO;
+
+typedef struct {
+ VOID (*CallBackFunc)();
+ BOOLEAN *InSmm;
+ BOOLEAN DisallowCallbacks;
+ EFI_STATUS CallbackStatus;
+ VOID *Pe32DispatcherImage;
+ UINTN Pe32DispatcherImageSize;
+
+ CALLBACKS CallbackParameters;
+ SMM_HOB *SmmHob;
+ VOID *SmmAllocMemoryStart; //Area to allocate memory
+ UINT32 SmmAllocMemoryLength;
+} SMM_BASE_PRIVATE_STRUCT;
+
+typedef struct {
+ VOID *PageDirectories;
+ VOID **SmmXmmSave;
+ BOOLEAN SmrrEnable;
+ UINT32 SmrrMsr;
+ UINT32 TsegMsr;
+ UINT64 TsegMsrBase;
+ UINT64 TsegMsrMask;
+ DESCRIPTOR_TABLE Idt;
+ SMM_CPU_INFO *SmmCpuInfo;
+
+ VOID (*SmmThunkProc)();
+ SMM_THUNK_DATA *SmmThunkData;
+ UINT32 EbdaStartOffset;
+ UINT32 NumCpus;
+ UINT32 NumCpusInSmm;
+
+ HANDLER_LIST *HandlerListHead;
+ BOOLEAN FloatingPointSave;
+
+ volatile SMM_AP_CPU_CONTROL *SmmApCpuControl;
+ UINT32 SmmBspNumber; //This can change each SMM entry.
+ VOID *SmmControl;
+} SMM_DISPATCHER_PRIVATE_STRUCT;
+
+
+#pragma pack(1)
+typedef struct {
+ UINT16 Offset;
+ UINT16 Segment;
+} FAR_CALL_PTR_16;
+
+typedef struct {
+ UINT32 Stack;
+ UINT32 StackSize;
+} STACK;
+
+typedef struct {
+ UINT16 Limit;
+ UINT32 Base;
+ UINT16 Rsv; //For alignment
+} SMM_DESC;
+
+#pragma pack()
+
+struct _SMM_ENTRY_INIT_STRUCT {
+ UINT32 SmmInit; //This must be first.
+ UINT32 SmmEntrySize;
+ UINT32 GdtDescBaseOffset;
+ UINT32 LCodeSelBaseOffset;
+ UINT32 TssSelBaseOffset;
+ UINT32 SmmThunkProcOffset;
+ UINT32 SmmThunkLength;
+ UINT32 HtCpu;
+ VOID *SmmEntryStart;
+ VOID (*DispatcherEntry)(SMM_ENTRY_INIT_STRUCT *);
+ SMM_DISPATCHER_PRIVATE_STRUCT *DispatcherPrivate;
+ UINT8 *SmmStackTop;
+ UINT32 CpuNo;
+};
+
+struct _SMM_THUNK_DATA {
+ FAR_CALL_PTR_16 FarCall;
+ SMM_THUNK_IA32_REGISTER_SET_EX Regs;
+ STACK Stack;
+ UINT32 StackSave;
+ SMM_DESC GdtSave;
+ SMM_DESC IdtSave;
+ SMM_DESC LegacyIdtDesc;
+ UINT16 Below1MStack;
+};
+
+typedef EFI_STATUS (*DISPATCHER_ENTRY_POINT)(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ IN SMM_BASE_PRIVATE_STRUCT *BasePrivate,
+ IN SMM_DISPATCHER_PRIVATE_STRUCT *DispatcherPrivate,
+ OUT VOID **SmstTable,
+ OUT VOID **SmstTable2
+);
+
+
+typedef VOID (*EFI_SMM_SAVE_RESTORE_FUNCTION)(BOOLEAN Save);
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SMM/Smst.c b/Core/EM/SMM/Smst.c
new file mode 100644
index 0000000..8ac8add
--- /dev/null
+++ b/Core/EM/SMM/Smst.c
@@ -0,0 +1,917 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/Smst.c 2 11/21/12 4:07a Wesleychen $
+//
+// $Revision: 2 $
+//
+// $Date: 11/21/12 4:07a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/SMM/Smst.c $
+//
+// 2 11/21/12 4:07a Wesleychen
+// Support Intel PFAT.
+//
+// 25 3/14/11 3:18p Markw
+// Rename gSmmFirmwareVender to gSmmFirmwareVendor.
+//
+// 24 2/07/11 3:29p Markw
+// [TAG] EIP53481
+// [Category] New Feature
+// [Description] Add PIWG 1.1 SMM support
+// [Files] Smm.sdl, SmmPrivateShared.h, SmmDispatcher.mak,
+// SmmDispatcher.h, SmmDispatcher.c,
+// Smst.c, SmmPiSmst.c, SmmInit.c, SmmBase.c, SmmBase2.c,
+// SmmDriverDispatcher.c, Smm Framewwork Protocol files, SmmPi.h,
+// Smm Pi Protocol files, SmmPciRbio files
+//
+// 23 6/18/10 12:29p Markw
+// Fix history log.
+//
+// 22 4/22/10 6:22p Markw
+// Support /w4 compilier option.
+//
+// 21 2/25/10 5:16p Markw
+// Add support for all APs to execute non-blocking.
+// Fixed issue with memory allocation
+//
+// 20 2/12/10 3:54p Markw
+// Update SmmSmstAllocatePages for AllocateAddress to return correct
+// Status.
+//
+// 19 5/08/09 10:55a Markw
+// Header updates.
+//
+// 18 11/05/08 5:25p Markw
+// Fix SMM Allocate Pool of type AllocateMaxAddress.
+//
+// 17 9/09/08 4:30p Markw
+// Add headers.
+//
+// 16 9/07/08 12:45a Markw
+// Separate SMM Private structure into inside SMM and outside SMM
+// structure. Remove access to BS function for CRC.
+//
+// 15 6/09/08 5:47p Markw
+// CPU0 has its own AP control structure. CPU0 can now be the AP.
+//
+// 14 3/14/07 5:57p Markw
+// Only allow SmmStartupThisAp if all CPUs are in SMM.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Smst.c
+//
+// Description: Smst functions.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//This include should come first.
+#include "SmmPrivateShared.h"
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+
+#if SMM_USE_FRAMEWORK
+#include <Smm.h>
+#endif
+
+#if SMM_USE_PI
+#include <SmmPi.h>
+#endif
+
+#include "ReferenceCode\Haswell\Include\CpuRegs.h"
+#ifndef BIT35
+#define BIT35 0x0000000800000000ULL
+#endif
+
+//TODOx64: move it to a library header
+VOID CPULib_Pause();
+
+VOID *Allocate(VOID *Base, UINTN Size,UINTN Alignment);
+
+EFI_STATUS AllocateABSegPages(
+ IN EFI_ALLOCATE_TYPE Type,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+);
+EFI_STATUS FreeABSegPages(
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+);
+
+BOOLEAN Free(VOID *Buffer);
+BOOLEAN Free4kPages(VOID *StartAddress,UINTN Pages);
+
+UINT8* Align2n(UINT8 *Value,UINTN Alignment);
+
+#if SMM_USE_FRAMEWORK
+
+EFI_STATUS CalculateCrc32(
+ IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32
+);
+
+extern EFI_SMM_SYSTEM_TABLE gSmmSystemTable;
+extern UINT8 **gSmmBase;
+#endif
+
+#if SMM_USE_PI
+extern EFI_SMM_SYSTEM_TABLE2 gSmmSystemTable2;
+#endif
+
+
+extern SMM_DISPATCHER_PRIVATE_STRUCT *gDispatcherPrivate;
+
+static UINT32 CrcTable[256];
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitCrc
+//
+// Description: InitCrc
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitCrc()
+{
+ UINT32 i, j;
+ for(i = 0; i < 256; i++) {
+ CrcTable[i] = i;
+ for(j = 8; j > 0; j--)
+ CrcTable[i] =
+ (CrcTable[i] & 1) ? (CrcTable[i] >> 1) ^ 0xedb88320 : CrcTable[i] >> 1;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateCrc32
+//
+// Description: Calculate Crc 32
+//
+// Input:
+// IN VOID *Data
+// IN UINTN DataSize
+// OUT UINT32 *Crc32
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS CalculateCrc32(
+ IN VOID *Data, IN UINTN DataSize, OUT UINT32 *Crc32
+)
+{
+ UINT32 i, crc = (UINT32)-1;
+ if (!Data || !DataSize || !Crc32) return EFI_INVALID_PARAMETER;
+ for(i = 0; i < DataSize; i++) crc = (crc >> 8) ^ CrcTable[(UINT8)crc ^ ((UINT8*)Data)[i]];
+ *Crc32 = ~crc;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmMemRead
+//
+// Description: Read memory buffer.
+//
+// Input:
+// IN EFI_SMM_CPU_IO_INTERFACE *This
+// IN EFI_SMM_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Buffer written Successfully.
+// * EFI_INVALID_PARAMETER - 0 Count, Unsupported Width, or memory region out of range.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmMemRead(
+ IN EFI_SMM_CPU_IO_INTERFACE *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+)
+{
+ UINT8 ByteWidth;
+ if (Width >= (UINTN)SMM_IO_UINT64) return EFI_INVALID_PARAMETER;
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ ByteWidth = (UINT8)(1 << Width);
+
+
+ //Alignment must be done by the caller.
+ switch(ByteWidth) {
+ case 1:
+ while(Count--) {
+ *(UINT8*)Buffer = *(UINT8*)(UINTN)Address;
+ ++((UINT8*)(UINTN)Buffer);
+ ++((UINT8*)(UINTN)Address);
+ }
+ break;
+ case 2:
+ while(Count--) {
+ *(UINT16*)Buffer = *(UINT16*)(UINTN)Address;
+ ++((UINT16*)(UINTN)Buffer);
+ ++((UINT16*)(UINTN)Address);
+ }
+ break;
+ default: //case 4:
+ while(Count--) {
+ *(UINT32*)Buffer = *(UINT32*)(UINTN)Address;
+ ++((UINT32*)(UINTN)Buffer);
+ ++((UINT32*)(UINTN)Address);
+ }
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmMemWrite
+//
+// Description: Write to memory from buffer.
+//
+// Input:
+// IN EFI_SMM_CPU_IO_INTERFACE *This
+// IN EFI_SMM_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Buffer written Successfully.
+// * EFI_INVALID_PARAMETER - 0 Count, Unsupported Width, or memory region out of range.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmMemWrite(
+ IN EFI_SMM_CPU_IO_INTERFACE *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ UINT8 ByteWidth;
+ if (Width >= (UINTN)SMM_IO_UINT64) return EFI_INVALID_PARAMETER;
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ //Alignment must be done by the caller.
+ ByteWidth = (UINT8)(1 << Width);
+
+ switch(ByteWidth) {
+ case 1:
+ while(Count--) {
+ *(UINT8*)(UINTN)Address = *(UINT8*)(UINTN)Buffer;
+ ++((UINT8*)(UINTN)Buffer);
+ ++((UINT8*)(UINTN)Address);
+ }
+ break;
+ case 2:
+ while(Count--) {
+ *(UINT16*)(UINTN)Address = *(UINT16*)(UINTN)Buffer;
+ ++((UINT16*)(UINTN)Buffer);
+ ++((UINT16*)(UINTN)Address);
+ }
+ break;
+ default: //case 4:
+ while(Count--) {
+ *(UINT32*)(UINTN)Address = *(UINT32*)(UINTN)Buffer;
+ ++((UINT32*)(UINTN)Buffer);
+ ++((UINT32*)(UINTN)Address);
+ }
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmIoRead
+//
+// Description: Read io buffer.
+//
+// Input:
+// IN EFI_SMM_CPU_IO_INTERFACE *This
+// IN EFI_SMM_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Buffer written Successfully.
+// * EFI_INVALID_PARAMETER - 0 Count, Unsupported Width, or memory region out of range.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmIoRead(
+ IN EFI_SMM_CPU_IO_INTERFACE *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ UINT8 ByteWidth;
+ if (Width >= (UINTN)SMM_IO_UINT64) return EFI_INVALID_PARAMETER;
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ ByteWidth = (UINT8)(1 << Width);
+
+ if (Address + ByteWidth * Count > 0x10000) return EFI_INVALID_PARAMETER; //Beyond IO space.
+ if ((UINT64)(UINTN)Buffer + ByteWidth * Count > (UINT64)0x100000000) return EFI_INVALID_PARAMETER; //Beyond address space.
+
+ //Alignment must be done by the caller.
+ switch(ByteWidth) {
+ case 1:
+ while(Count--) {
+ *(UINT8*)Buffer = IoRead8((UINT16)Address);
+ ++((UINT8*)(UINTN)Buffer);
+ ++((UINT8*)(UINTN)Address);
+ }
+ break;
+ case 2:
+ while(Count--) {
+ *(UINT16*)(UINTN)Buffer = IoRead16((UINT16)Address);
+ ++((UINT16*)(UINTN)Buffer);
+ ++((UINT16*)(UINTN)Address);
+ }
+ break;
+ default: //case 4:
+ while(Count--) {
+ *(UINT32*)Buffer = IoRead32((UINT16)Address);
+ ++((UINT32*)(UINTN)Buffer);
+ ++((UINT32*)(UINTN)Address);
+ }
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmIoWrite
+//
+// Description: Write to Io from buffer.
+//
+// Input:
+// IN EFI_SMM_CPU_IO_INTERFACE *This
+// IN EFI_SMM_IO_WIDTH Width
+// IN UINT64 Address
+// IN UINTN Count
+// IN OUT VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Buffer written Successfully.
+// * EFI_INVALID_PARAMETER - 0 Count, Unsupported Width, or memory region out of range.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmIoWrite(
+ IN EFI_SMM_CPU_IO_INTERFACE *This,
+ IN EFI_SMM_IO_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+{
+ UINT8 ByteWidth;
+ if (Width >= (UINTN)SMM_IO_UINT64) return EFI_INVALID_PARAMETER;
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ ByteWidth = (UINT8)(1 << Width);
+
+ if (Address + ByteWidth * Count > 0x10000) return EFI_INVALID_PARAMETER; //Beyond IO space.
+ if ((UINT64)(UINTN)Buffer + ByteWidth * Count > (UINT64)0x100000000) return EFI_INVALID_PARAMETER; //Beyond address space.
+
+ //Alignment must be done by the caller.
+ switch(ByteWidth) {
+ case 1:
+ while(Count--) {
+ IoWrite8((UINT16)Address,*(UINT8*)(UINTN)Buffer);
+ ++((UINT8*)(UINTN)Buffer);
+ ++((UINT8*)(UINTN)Address);
+ }
+ break;
+ case 2:
+ while(Count--) {
+ IoWrite16((UINT16)Address,*(UINT16*)(UINTN)Buffer);
+ ++((UINT16*)(UINTN)Buffer);
+ ++((UINT16*)(UINTN)Address);
+ }
+ break;
+ default: //case 4:
+ while(Count--) {
+ IoWrite32((UINT16)Address,*(UINT32*)(UINTN)Buffer);
+ ++((UINT32*)(UINTN)Buffer);
+ ++((UINT32*)(UINTN)Address);
+ }
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstAllocatePool
+//
+// Description: Allocate a pool of memory.
+//
+// Input:
+// IN EFI_MEMORY_TYPE PoolType
+// IN UINTN Size
+// OUT VOID **Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Pool of memory allocated.
+// * EFI_INVALID_PARAMETER - Allocate 0 size.
+// * EFI_OUT_OF_RESOURCES - Memory unavailable.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstAllocatePool(
+ IN EFI_MEMORY_TYPE PoolType,
+ IN UINTN Size,
+ OUT VOID **Buffer
+ )
+{
+ if (!Size) return EFI_INVALID_PARAMETER;
+ *Buffer = Allocate(0,Size,0);
+ if (!(*Buffer)) return EFI_OUT_OF_RESOURCES;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstFreePool
+//
+// Description: Free Allocated memory.
+//
+// Input:
+// IN VOID *Buffer
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Memory is freed.
+// * EFI_INVALID_PARAMETER - Memory starting at Buffer was not allocated.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstFreePool(
+ IN VOID *Buffer
+ )
+{
+ if (!Free(Buffer)) return EFI_INVALID_PARAMETER;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstAllocatePages
+//
+// Description: Allocate # pages at any address, a max address, or a specified address.
+//
+// Input:
+// IN EFI_ALLOCATE_TYPE Type
+// IN EFI_MEMORY_TYPE MemoryType
+// IN UINTN NumberOfPages
+// OUT EFI_PHYSICAL_ADDRESS *Memory
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Memory allocated.
+// * EFI_OUT_OF_RESOURCES - Memory already allocated or unavailable.
+// * EFI_INVALID_PARAMETER - Incorrect Type or specified address not 4k aligned.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstAllocatePages(
+ IN EFI_ALLOCATE_TYPE Type,
+ IN EFI_MEMORY_TYPE MemoryType,
+ IN UINTN NumberOfPages,
+ IN OUT EFI_PHYSICAL_ADDRESS *Memory
+ )
+{
+ VOID *AllocatedMemory;
+
+ if (!NumberOfPages) return EFI_INVALID_PARAMETER;
+ if (Type != AllocateAnyPages && *Memory <= 0x100000) return AllocateABSegPages(Type, NumberOfPages, Memory);
+
+ switch(Type) {
+ case AllocateAnyPages:
+ *Memory = (EFI_PHYSICAL_ADDRESS)(UINTN)Allocate(0, NumberOfPages * 4096, 4095);
+ if (!(*Memory)) return EFI_OUT_OF_RESOURCES;
+ return EFI_SUCCESS;
+
+ case AllocateMaxAddress:
+ AllocatedMemory = Allocate(0, NumberOfPages * 4096, 4095);
+ if (!AllocatedMemory) return EFI_OUT_OF_RESOURCES;
+ if ((UINTN)AllocatedMemory > *(UINTN*)(UINTN)Memory) {
+ Free(AllocatedMemory);
+ return EFI_OUT_OF_RESOURCES;
+ }
+ *Memory = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatedMemory;
+ return EFI_SUCCESS;
+ case AllocateAddress:
+ if ((UINT8*)(UINTN)*Memory != Align2n((UINT8*)(UINTN)*Memory,4095)) return EFI_INVALID_PARAMETER;
+ AllocatedMemory = Allocate((UINT8*)(UINTN)*Memory,NumberOfPages * 4096,0);
+ if (!AllocatedMemory) return EFI_OUT_OF_RESOURCES;
+ return EFI_SUCCESS;
+ }
+ return EFI_INVALID_PARAMETER;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmSmstFreePages
+//
+// Description:
+// Free pages. The address must be on a page boundary, but it doesn't have to
+// start on address from AllocatePages. It only frees the requested pages.
+//
+// Input:
+// IN EFI_PHYSICAL_ADDRESS Memory
+// IN UINTN NumberOfPages
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmSmstFreePages(
+ IN EFI_PHYSICAL_ADDRESS Memory,
+ IN UINTN NumberOfPages
+ )
+{
+ if (Memory <= 0x100000) return FreeABSegPages(Memory, NumberOfPages);
+
+ if (!Free4kPages((VOID*)(UINTN)Memory,NumberOfPages)) return EFI_INVALID_PARAMETER;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmStartupThisAp
+//
+// Description: Execute a procedure on an AP.
+//
+// Input:
+// IN EFI_AP_PROCEDURE Procedure
+// IN UINTN CpuNumber
+// IN OUT VOID *ProcArguments OPTIONAL
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmStartupThisAp(
+ IN EFI_AP_PROCEDURE Procedure,
+ IN UINTN CpuNumber,
+ IN OUT VOID *ProcArguments OPTIONAL
+)
+{
+ volatile SMM_AP_CPU_CONTROL *SmmApCpuControl;
+ BOOLEAN IsBlocking = (BOOLEAN)(CpuNumber != (UINTN)-1);
+ UINT32 i;
+
+ if (Procedure == NULL) return EFI_INVALID_PARAMETER;
+ if (CpuNumber == gDispatcherPrivate->SmmBspNumber) return EFI_INVALID_PARAMETER;
+ if (CpuNumber >= gDispatcherPrivate->NumCpus && IsBlocking) return EFI_INVALID_PARAMETER;
+
+ if (IsBlocking) {
+ if (!gDispatcherPrivate->SmmCpuInfo[CpuNumber].InSmm) return EFI_NOT_READY;
+ SmmApCpuControl = &gDispatcherPrivate->SmmApCpuControl[CpuNumber];
+
+ SmmApCpuControl->ProcArguments = ProcArguments;
+ SmmApCpuControl->Procedure = Procedure;
+
+ if ( !((ReadMsr (MSR_PLATFORM_INFO) & B_MSR_PLATFORM_INFO_PFAT_AVAIL) &&
+ (ReadMsr (MSR_PLAT_FRMW_PROT_CTRL) & B_MSR_PLAT_FRMW_PROT_CTRL_EN)) ) {
+ while(SmmApCpuControl->Procedure) CPULib_Pause();
+ }
+ return EFI_SUCCESS;
+ }
+
+ for (i = 0; i < gDispatcherPrivate->NumCpus; ++i) {
+ if (i == gDispatcherPrivate->SmmBspNumber) continue;
+ if (!gDispatcherPrivate->SmmCpuInfo[i].InSmm) continue;
+ SmmApCpuControl = &gDispatcherPrivate->SmmApCpuControl[i];
+ ASSERT(SmmApCpuControl->Procedure == NULL);
+ if (SmmApCpuControl->Procedure != NULL) continue;
+
+ SmmApCpuControl->ProcArguments = ProcArguments;
+ SmmApCpuControl->Procedure = Procedure;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: MoveToNewConfigurationTable
+//
+// Description: Create a new bigger or smaller table and copy the old table to the new table.
+//
+// Input:
+// IN EFI_CONFIGURATION_TABLE *OldTable
+// IN UINTN NumOldDescriptors
+// IN UINTN NumDescriptors
+//
+// Output:
+// EFI_CONFIGURATION_TABLE * - New table address.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_CONFIGURATION_TABLE * MoveToNewConfigurationTable(
+ EFI_CONFIGURATION_TABLE *OldTable,
+ UINTN NumOldDescriptors,
+ UINTN NumDescriptors
+ )
+{
+ EFI_CONFIGURATION_TABLE *NewTable,*Descriptor,*OldDescriptor;
+ UINTN i;
+ //Create new table
+ if (SmmSmstAllocatePool(0,NumDescriptors * sizeof(EFI_CONFIGURATION_TABLE),&NewTable)!=EFI_SUCCESS) return 0;
+
+ //If new table is larger, only copy valid descriptors.
+ //If new table is smaller, only copy descriptors for allocated table.
+ NumDescriptors = NumDescriptors > NumOldDescriptors ? NumOldDescriptors : NumDescriptors;
+ Descriptor = NewTable;
+ OldDescriptor = OldTable;
+ for (i=0;i<NumDescriptors;++i) *Descriptor++ = *OldDescriptor++;
+
+ //Free old table
+ SmmSmstFreePool(OldTable);
+
+ return NewTable;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SmmInstallConfigurationTable
+//
+// Description:
+// This procedure add/updates/deletes configuration table entries.
+//
+// Configuration Table Entry definition:
+// EFI_GUID VendorGuid
+// VOID *VenderTable
+//
+// 1. If Vendor Guid is not in table and Input table isn't NULL, add Guid/Table pair.
+// 2. If Vendor Guid is in table and Input table isn't NULL, update Guid/Table pair.
+// 3. If Vendor Guid is in table and Input table is NULL, remove Guid/Tablble pair.
+// 4. If Vendor Guid is not in table, Input table is NULL, return EFI_NOT_FOUND. Nothing to delete.
+//
+// Input:
+// IN EFI_SMM_SYSTEM_TABLE *SystemTable
+// IN EFI_GUID *Guid
+// IN VOID *Table
+// IN UINTN TableSize
+//
+// Output:
+// EFI_STATUS
+// * EFI_SUCCESS - Add/update/remove operation successful.
+// * EFI_INVALID_PARAMETER - Guid = 0.
+// * EFI_NOT_FOUND - Can not delete a nonexistent entry.
+// * EFI_OUT_OF_RESOURCES - Not enough memory to complete operation.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS SmmInstallConfigurationTable(
+#if SMM_USE_FRAMEWORK
+ IN EFI_SMM_SYSTEM_TABLE *SystemTable,
+#else
+ IN EFI_SMM_SYSTEM_TABLE2 *SystemTable,
+#endif
+ IN EFI_GUID *Guid,
+ IN VOID *Table,
+ IN UINTN TableSize
+ )
+{
+ UINTN i;
+ UINT32 CRC32;
+
+#if SMM_USE_PI
+ EFI_CONFIGURATION_TABLE **FirstEntryPtr = &gSmmSystemTable2.SmmConfigurationTable;
+ EFI_CONFIGURATION_TABLE *Entry = *FirstEntryPtr;
+ UINTN *NumberOfTableEntries = &gSmmSystemTable2.NumberOfTableEntries;
+ UINT32 SystemTableSize = sizeof(gSmmSystemTable2);
+ #else
+ EFI_CONFIGURATION_TABLE **FirstEntryPtr = &gSmmSystemTable.SmmConfigurationTable;
+ EFI_CONFIGURATION_TABLE *Entry = *FirstEntryPtr;
+ UINTN *NumberOfTableEntries = &gSmmSystemTable.NumberOfTableEntries;
+ UINT32 SystemTableSize = sizeof(gSmmSystemTable);
+#endif
+
+ EFI_CONFIGURATION_TABLE *NewConfigTable;
+ VOID *NewVendorTable;
+
+ if (!Guid) return EFI_INVALID_PARAMETER;
+
+ for (i=0;i < *NumberOfTableEntries;++i) {
+ if (guidcmp(&Entry->VendorGuid,Guid)==0) break;
+ ++Entry;
+ }
+ if (i == *NumberOfTableEntries) Entry=0;
+
+ if (!Entry) {
+ if (!Table) return EFI_NOT_FOUND;
+ //Add Guid
+ NewConfigTable = MoveToNewConfigurationTable(
+ *FirstEntryPtr,
+ *NumberOfTableEntries,
+ *NumberOfTableEntries+1);
+ if (!NewConfigTable) return EFI_OUT_OF_RESOURCES;
+
+ if (SmmSmstAllocatePool(0,TableSize,&NewVendorTable)!=EFI_SUCCESS) return EFI_OUT_OF_RESOURCES;
+ MemCpy(NewVendorTable,Table,TableSize);
+ *FirstEntryPtr = NewConfigTable;
+ ++(*NumberOfTableEntries);
+ NewConfigTable[*NumberOfTableEntries - 1].VendorGuid = *Guid;
+ NewConfigTable[*NumberOfTableEntries - 1].VendorTable = NewVendorTable;
+ } else {
+ if (!Table) {
+ //Remove Guid
+ EFI_CONFIGURATION_TABLE *LastEntry = *FirstEntryPtr + *NumberOfTableEntries;
+
+ SmmSmstFreePool(Entry->VendorTable);
+
+ while (Entry != LastEntry) {
+ *Entry = *(Entry + 1);
+ ++Entry;
+ }
+
+ --(*NumberOfTableEntries);
+ } else {
+ //Update Guid
+ if (SmmSmstAllocatePool(0,TableSize,&NewVendorTable)!=EFI_SUCCESS) return EFI_OUT_OF_RESOURCES;
+ MemCpy(NewVendorTable,Table,TableSize);
+
+ SmmSmstFreePool(Entry->VendorTable);
+ Entry->VendorTable = NewVendorTable;
+ }
+ }
+
+#if SMM_USE_PI && SMM_USE_FRAMEWORK
+ gSmmSystemTable.SmmConfigurationTable = gSmmSystemTable2.SmmConfigurationTable;
+ gSmmSystemTable.NumberOfTableEntries = gSmmSystemTable2.NumberOfTableEntries;
+#endif
+
+#if SMM_USE_PI
+ gSmmSystemTable2.Hdr.CRC32 = 0;
+ CalculateCrc32(&gSmmSystemTable2, SystemTableSize, &CRC32);
+ gSmmSystemTable2.Hdr.CRC32 = CRC32;
+#endif
+
+#if SMM_USE_FRAMEWORK
+ gSmmSystemTable.Hdr.CRC32 = 0;
+ CalculateCrc32(&gSmmSystemTable, sizeof(EFI_SMM_SYSTEM_TABLE), &CRC32);
+ gSmmSystemTable.Hdr.CRC32 = CRC32;
+#endif
+
+ return EFI_SUCCESS;
+}
+
+
+#if SMM_USE_FRAMEWORK
+
+//////////////////////////////////////////
+extern CHAR16 gSmmFirmwareVendor[];
+EFI_SMM_SYSTEM_TABLE gSmmSystemTable =
+{
+ { //Header
+ SMM_SMST_SIGNATURE, //Signature
+ EFI_SMM_SYSTEM_TABLE_REVISION, //Revision
+ sizeof(EFI_SMM_SYSTEM_TABLE), //Header size
+ 0, //CRC32
+ 0 //Reserved
+ },
+ gSmmFirmwareVendor, //Vendor
+ 0, //Vendor version
+ SmmInstallConfigurationTable,
+ EFI_SMM_CPU_IO_GUID,
+ {
+ {
+ SmmMemRead,
+ SmmMemWrite
+ },
+ { SmmIoRead,
+ SmmIoWrite
+ }
+ },
+ SmmSmstAllocatePool,
+ SmmSmstFreePool,
+ SmmSmstAllocatePages,
+ SmmSmstFreePages,
+ SmmStartupThisAp,
+ 1, //Executing CPU
+ 1, //Number of CPUs
+ 0, //Cpu Save State
+ 0, //Cpu Floating Point Save
+ 0, //Number of Table Entries
+ 0 //Table pointer
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitializeSmmSystemTable
+//
+// Description: Initialize the System Table.
+//
+// Input: SMM_BASE_PRIVATE_STRUCT *Private
+//
+// Output: VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID InitializeSmmSystemTable()
+{
+ UINT32 CRC32;
+
+ gSmmSystemTable.NumberOfCpus = gDispatcherPrivate->NumCpus;
+
+ gSmmSystemTable.CpuSaveState = Allocate(0,sizeof(EFI_SMM_CPU_SAVE_STATE) * gSmmSystemTable.NumberOfCpus,0);
+ gSmmSystemTable.CpuOptionalFloatingPointState = Allocate(0, 512 * gSmmSystemTable.NumberOfCpus, 15); //16 byte alignment, Save floating point context.
+
+ CalculateCrc32(&gSmmSystemTable, sizeof(EFI_SMM_SYSTEM_TABLE), &CRC32);
+ gSmmSystemTable.Hdr.CRC32 = CRC32;
+}
+
+#endif
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SecurityPkg/AuthenticatedVariable/Auth2Variable.c b/Core/EM/SecurityPkg/AuthenticatedVariable/Auth2Variable.c
new file mode 100644
index 0000000..e979531
--- /dev/null
+++ b/Core/EM/SecurityPkg/AuthenticatedVariable/Auth2Variable.c
@@ -0,0 +1,869 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/Auth2Variable.c 30 3/09/15 4:31p Alexp $
+//
+// $Revision: 30 $
+//
+// $Date: 3/09/15 4:31p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/Auth2Variable.c $
+//
+// 30 3/09/15 4:31p Alexp
+// Compliancy with UEFI spec:
+// EFI_VARIABLE_AUTHENTICATION_2.TimeStamp -
+// during Append operations the TimeStamp value may be set to '0'
+//
+// 29 10/08/14 3:16p Alexp
+// Introduced global mCustomMode flag passing the status from
+// PhysicalUserPresent()
+//
+// 28 8/15/13 11:27a Alexp
+// Link AmyCryptoLib. Replaced locally defined mkLongTime() with generic
+// AmiCryptoLib defined os_mktime()
+//
+// 27 2/08/13 5:15p Alexp
+// Optimized the code flow fro Auth2 Variables.
+//
+// 26 12/07/12 3:48p Alexp
+// - Replaced TRACE macro with AVAR_TRACE. Stop debug traces in Virtual
+// address mode
+// - VerifyVariable2() Fix final check for IsPk and run
+// ValidateSignatureList()
+//
+// 25 12/04/12 6:56p Alexp
+// VerifyVariable2()
+// IsPk -> skip ValidateSignatureList if *DataSize =0
+//
+// 24 11/29/12 3:08p Alexp
+// ValidateSelfSigned(): keep *x509_SignCert ptr to non-0 for
+// Pkcs7CertValidateGetSignerKeyHash operation
+// Will trigger an error in old CryptoDxe.c Pkcs7Verify()
+//
+// 22 11/16/12 7:11p Alexp
+// Fixed ValidateSignatureList() return status for Zero Data or Size
+//
+// 21 11/16/12 5:09p Alexp
+// EIP:104961 UEFI 2.3.1 SCTc test failed in Generic\EfiCompliant case.
+// Fix for SelfSigned variables.
+//
+// 19 9/17/12 4:50p Alexp
+// add Time Stamp traces
+//
+// 18 9/06/12 5:14p Alexp
+// ConstructDataParameter() Fix debug messages.
+//
+// 17 9/04/12 3:35p Alexp
+// EIP#99648: SCT will fail when enable Secure Boot in setup menu.
+// Fix: Use globally defined buffer to pass calculated Key Hash for
+// SelfSigned Variables
+//
+// 15 8/22/12 6:19p Alexp
+// ProcessVarWithPk2()
+// Properly implemented the case for PK variable carrying RSA2048 Key.
+// Requires CryptoPkg Label 009 or later.
+//
+// 12 4/26/12 7:29p Alexp
+// fix debug trace messages
+//
+// 11 4/16/12 5:28p Alexp
+// Add debug traces in ConstructDataParameter to display serialization
+// data
+//
+// 10 11/30/11 7:58p Alexp
+// According to UEFI 2.3.1 Sec 7.2.1 : "db" vars can be validated either
+// by KEK key or by PK key.
+// The fix adds the check for PK if none of KEKs can validate new "db"
+//
+// 9 8/19/11 5:06p Alexp
+//
+// 8 8/18/11 4:54p Alexp
+// restored use of global variable mPlatformMode instead of a field in
+// AuthVarMaibox
+//
+// 7 8/16/11 7:18p Alexp
+// added Mailbox variable AuthVarMAilbox to syncronize local state between
+// DXE and SMM AuthVariable services
+//
+// 6 7/18/11 10:17a Alexp
+// made gEfiGlobalVariableGuid static to prevent linker issues
+//
+// 5 6/27/11 6:16p Alexp
+// code optimization: moved ValidateSignatureList () call in the main
+// VerifyVariable1(2) function.
+//
+// 4 6/24/11 7:04p Alexp
+// fixed ValidateSignatureList () logic. Added Certificate RSA2048 to
+// supported Signatures
+//
+// 3 6/24/11 3:23p Alexp
+// test PK, KEK, db(x) for valid Signatuer List header with
+// ValidateSignatureList()
+// run test only if other tests passed
+//
+// 2 6/23/11 6:19p Alexp
+// Added ValidateSigList() function
+//
+// 1 6/13/11 5:25p Alexp
+//
+// 13 6/13/11 4:29p Alexp
+//
+// 12 6/10/11 6:24p Alexp
+// Update SelfSigned variable: Pkcs7CertValidateGetSignerKeyHash
+//
+// 11 6/09/11 5:51p Alexp
+// add new parameter to ValidateSelfSigned - Operation.
+// test for self-signed variables: hash CA certificate instead of Signer
+// certificate.
+//
+// 10 6/03/11 10:36a Alexp
+// Add alternative cert verify logic in ProcessVarWithPk2 (). Keep it
+// commented for now
+//
+// 9 6/02/11 5:53p Alexp
+// add new function to ValidateSelfSigned certificates
+// add processing for Time BAsed self signed variables
+// succesfully Verified Msft Win8 PK-KEK test keys
+//
+// 8 5/31/11 3:11p Alexp
+// Use UpdatePlatformMode() to update SetupMode variable
+//
+// 7 5/25/11 8:34p Alexp
+// draft fix for TimeBased auth variables. More work w Msft needed
+//
+// 6 5/19/11 4:59p Alexp
+// Major code revamp to be able to handle of handling Secure vars in Setup
+// Mode
+// TBD: TimeBased certificates from Msft fail to process. Not compiled as
+// Authenticode format
+//
+// 5 5/17/11 12:48p Alexp
+// fix WDK level4 compiler warnings
+//
+// 4 5/13/11 3:43p Alexp
+// add dependency on Core rev.
+//
+// 3 5/11/11 7:20p Alexp
+// VarData init for FindVariable
+//
+// 2 5/10/11 5:07p Alexp
+// removed local Hash Guid defines
+// intermediate check in befor implementing Auth2 var verify logic
+//
+//**********************************************************************
+
+#include "NVRAM.h"
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <Protocol/AmiDigitalSignature.h>
+
+#include "AuthVariable.h"
+#include <cryptlib.h>
+
+///
+/// Global database array for scratch
+///
+extern BOOLEAN AVarRuntime;
+extern UINT8 mCustomMode;
+extern UINT8 mPlatformMode;
+extern UINT8 PublicKeyHashArray[HASH_SHA256_LEN];
+
+extern AMI_DIGITAL_SIGNATURE_PROTOCOL *mDigitalSigProtocol;
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessVarWithPk2
+//
+// Description: Process variable with platform key for verification.
+// Called for PK or KEK Variables
+//
+//
+// Input:
+// Pkcs7Cert Pointer to Pkcs#7 cert.
+// Pkcs7Cert_len Size of Pkcs7 cert
+// pDigest Digest of serialized data block
+// Digest_len size of the digest (20 or 32 bytes)
+// Output:
+// Status
+// EFI_SUCCESS Variable passed validation successfully.
+// EFI_INVALID_PARAMETER Invalid parameter.
+// EFI_SECURITY_VIOLATION The variable does NOT pass the validation.
+// check carried out by the firmware.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ProcessVarWithPk2 (
+ IN UINT8 *Pkcs7Cert,
+ IN UINTN Pkcs7Cert_len,
+ IN UINT8 *pDigest,
+ IN UINTN Digest_len
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *OldPkList;
+ EFI_SIGNATURE_DATA *OldPkData;
+ UINT32 VarAttr;
+ UINT8 *VarData;
+ UINTN VarDataSize=0;
+ UINT8 *x509_TrustCert, *TrustCert;
+ UINTN x509_TrustCert_len, TrustCert_len;
+ UINT8 Pkcs7Operation;
+
+ //
+ // Get platform key from variable.
+ //
+ Status = FindVariable (
+ EFI_PLATFORM_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ &VarAttr,
+ &VarDataSize,
+ &VarData
+ );
+// PK should have been set when we were in SETUP_MODE. This condition is INVALID.
+// ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status) || VarData==NULL || !VarDataSize)
+ return EFI_SECURITY_VIOLATION;
+
+ OldPkList = (EFI_SIGNATURE_LIST *) VarData;
+ OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize);
+
+// Verify the PK SignatureType GUID
+
+ if (!guidcmp ((EFI_GUID*) &(OldPkList->SignatureType), &gEfiCertRsa2048Guid))
+ {
+ //Process x509 cert and load Raw Key for Root cert comparison
+ Pkcs7Operation = Pkcs7CertValidateGetSignerKey;
+ x509_TrustCert = NULL;
+ x509_TrustCert_len = 0;
+ }
+ else if(!guidcmp ((EFI_GUID*) &(OldPkList->SignatureType), &gEfiCertX509Guid))
+ {
+ Pkcs7Operation = Pkcs7CertValidateGetSignerCert;
+ x509_TrustCert = (UINT8*)OldPkData->SignatureData;
+ x509_TrustCert_len = (UINTN)OldPkList->SignatureSize-sizeof(EFI_GUID);
+ } else
+ //
+ // Unsupported Sig Type, return EFI_SECURITY_VIOLATION.
+ //
+ return EFI_SECURITY_VIOLATION;
+
+ TrustCert = (UINT8*)OldPkData->SignatureData;
+ TrustCert_len = (UINTN)OldPkList->SignatureSize-sizeof(EFI_GUID);
+
+/*
+// Validate Self-Signed
+//
+ x509_TrustCert = &pDigest; // Init with addr to global var
+ //&PublicKeyHashArray[0];
+ x509_TrustCert_len = Digest_len;
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ NULL, 0, // use Internal Cert
+ &x509_TrustCert, &x509_TrustCert_len, // Input->Digest, Output->DER Ptr to Signing Cert
+ Pkcs7Operation,
+ RESET
+ );
+ if (!EFI_ERROR (Status)) {
+ Status = ( TrustCert_len == x509_TrustCert_len &&
+ !(MemCmp(TrustCert, x509_TrustCert, x509_TrustCert_len))) ?
+ EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+ }
+*/
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ x509_TrustCert, x509_TrustCert_len, // TrustCert
+ &pDigest, &Digest_len, // In/OutData
+ Pkcs7Operation,
+ RELEASE // Flags, mutex
+ );
+ if (!EFI_ERROR (Status)) {
+
+ Status = ( TrustCert_len == Digest_len &&
+ !(MemCmp(TrustCert, pDigest, Digest_len))) ?
+ EFI_SUCCESS:EFI_SECURITY_VIOLATION;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessVarWithKek2
+//
+// Description: Process variable with key exchange key for verification.
+// Called for DB or DBx variables
+//
+//
+// Input:
+// Pkcs7Cert Pointer to Pkcs#7 cert.
+// Pkcs7Cert_len Size of Pkcs7 cert
+// pDigest Digest of serialized data block
+// Digest_len size of the digest (20 or 32 bytes)
+//
+// Output:
+// Status
+// EFI_SUCCESS Variable passed validation successfully.
+// EFI_INVALID_PARAMETER Invalid parameter.
+// EFI_SECURITY_VIOLATION The variable does NOT pass the validation.
+// check carried out by the firmware.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ProcessVarWithKek2 (
+ IN UINT8 *Pkcs7Cert,
+ IN UINTN Pkcs7Cert_len,
+ IN UINT8 *pDigest,
+ IN UINTN Digest_len
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *KekList;
+ EFI_SIGNATURE_DATA *KekItem;
+ UINT32 KekCount;
+ BOOLEAN IsFound;
+ UINT32 Index;
+ UINT32 VarAttr;
+ UINT8 *VarData;
+ UINTN VarDataSize=0;
+
+ //
+ // Get KEK database from variable.
+ //
+ Status = FindVariable (
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ &VarAttr,
+ &VarDataSize,
+ &VarData
+ );
+ if (EFI_ERROR (Status) || VarData==NULL || !VarDataSize)
+ return EFI_SECURITY_VIOLATION;
+
+ KekList = (EFI_SIGNATURE_LIST *) VarData;
+
+ //
+ // Enumerate all Kek items in this list to verify the variable certificate data.
+ // If anyone is authenticated successfully, it means the variable is correct!
+ //
+ IsFound = FALSE;
+ //
+ // scan thru multiple Sig Lists if exist. Add 1 more loop....
+ //
+ while (!IsFound && (VarDataSize > 0) && (VarDataSize >= KekList->SignatureListSize)) {
+ if (!guidcmp ((EFI_GUID*) &(KekList->SignatureType), &gEfiCertX509Guid))
+ {
+ KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;
+ KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);
+ for (Index = 0; Index < KekCount; Index++) {
+ // find x509 cert and compare against one from Kek
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ KekItem->SignatureData, // TrustCert Cert
+ KekList->SignatureSize,
+ &pDigest, &Digest_len, // In/OutData
+ Pkcs7CertValidate,
+ RELEASE
+ );
+ if (!EFI_ERROR(Status)) {
+ IsFound = TRUE;
+ break;
+ }
+ KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);
+ }
+ }// else
+ // Auth2 Vars must be signed with x509 Certs
+// if (!guidcmp ((EFI_GUID*) &(KekList->SignatureType), &gEfiCertRsa2048Guid))
+// return EFI_SECURITY_VIOLATION;
+ VarDataSize -= KekList->SignatureListSize;
+ KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);
+ }
+
+ if (!IsFound)
+ return EFI_SECURITY_VIOLATION;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ValidateSelfSigned
+//
+// Description: Extract Signer certificate and verify Pkcs#7 SignedData signature.
+// Called for Private Authenticated variables
+//
+//
+// Input:
+// Pkcs7Cert Pointer to Pkcs#7 cert.
+// Pkcs7Cert_len Size of Pkcs7 cert
+// pDigest Digest of serialized data block
+// Digest_len size of the digest (20 or 32 bytes)
+// Operation type of Pkcs operation:Pkcs7CertValidateGetSignerCert...
+//
+// Output: EFI_SUCCESS SignedData passed validation successfully.
+// EFI_INVALID_PARAMETER Invalid parameter.
+// EFI_SECURITY_VIOLATION The data does NOT pass the validation.
+// check carried out by the firmware.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ValidateSelfSigned (
+ IN UINT8 *Pkcs7Cert,
+ IN UINTN Pkcs7Cert_len,
+ IN OUT UINT8 **pDigest,
+ IN OUT UINTN *Digest_len,
+ IN UINT8 Operation
+ )
+{
+ EFI_STATUS Status;
+ UINT8 *x509_SignCert;
+ UINTN x509_SignCert_len=0;
+
+ //
+ // Extract x509 Signing Cert and validate self-signed data
+ //
+ x509_SignCert=(UINT8*)&x509_SignCert_len; // non-zero ptr
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ Pkcs7Cert, Pkcs7Cert_len,
+ NULL, 0, // RootCert
+ &x509_SignCert, &x509_SignCert_len,
+ Pkcs7GetSignerCert,
+ KEEP
+ );
+ //
+ // Authenticate using internal Signer Cert, Extract Cert or Key Hash
+ //
+ if (!EFI_ERROR (Status))
+ {
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ x509_SignCert, x509_SignCert_len, // RootCert
+ pDigest, Digest_len, // Input->Digest, Output->DER Ptr to Signing Cert
+ Operation,
+ RELEASE
+ );
+
+// Status = mDigitalSigProtocol->Hash(mDigitalSigProtocol, &gEfiHashAlgorithmSha256Guid, 1 &x509_SignCert, (const UINTN*)&x509_SignCert_len, pDigest);
+// *Digest_len = HASH_SHA256_LEN;
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConstructDataParameter
+//
+// Description:
+// Generates the Hash (SHA256) out of serialized data block
+// Hash(VariableName, VendorGuid, Attributes, TimeStamp, Data)
+//
+// Input:
+// CHAR16 *VariableName Name of Variable to be found.
+// EFI_GUID *VendorGuid Variable vendor GUID.
+// IN UINT32 Attributes - Attributes of the Var
+// VOID *Data - pointer to data block within AutVar Data
+// UINTN DataSize - size of data block
+//
+// Output: EFI_STATUS
+// UINT8 Digest - Hash of the serialized data block
+// UINTN Digest_len - size of data block
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConstructDataParameter (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *pDigest,
+ OUT UINTN *Digest_len,
+ IN UINT8 Mutex
+)
+{
+ EFI_STATUS Status;
+
+ EFI_GUID *HashAlgorithm;
+ UINT8 *Addr[5];
+ UINTN Len[5];
+ EFI_VARIABLE_AUTHENTICATION_2 *CertData;
+ UINTN CertHdrSize, Pkcs7Cert_len;
+ UINT8 *Pkcs7Cert;
+ UINT8 HashType=SHA1;
+ UINT8 *pHash=&HashType;
+
+#ifdef EFI_DEBUG
+ UINTN j, i;
+#endif
+
+ CertData = (EFI_VARIABLE_AUTHENTICATION_2 *)Data;
+ CertHdrSize = AUTHINFO_2_SIZE(Data);
+
+// !!!sha256 is the only digest algorithm supported.
+// temp w/a: determine the digest algorithm from contentInfo hdr
+//
+ // quick cheat. CertBlock->CerData is a begining of Pkcs7 Cert
+ Pkcs7Cert = (UINT8*)&(CertData->AuthInfo.CertData);
+ Pkcs7Cert_len = CertHdrSize - ((UINTN)Pkcs7Cert - (UINTN)Data);
+
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ Pkcs7Cert,
+ Pkcs7Cert_len,
+ NULL,
+ 0,
+ &pHash, // returns DER Ptr to Sign Cert
+ &Len[0],
+ Pkcs7GetDigestAlgorithm,
+ Mutex
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ switch(*pHash) {
+ case SHA1:
+ *Digest_len = HASH_SHA1_LEN;
+ HashAlgorithm = &gEfiHashAlgorithmSha1Guid;
+ break;
+ case SHA256:
+ *Digest_len = HASH_SHA256_LEN;
+ HashAlgorithm = &gEfiHashAlgorithmSha256Guid;
+ break;
+ default:
+ return EFI_UNSUPPORTED;
+ break;
+ }
+ //
+ // Hash data payload with SHA.
+ //
+ Addr[0] = (UINT8*)VariableName;
+ Len[0] = StrSize16(VariableName);
+ Addr[1] = (UINT8*)VendorGuid;
+ Len[1] = sizeof(EFI_GUID);
+ Addr[2] = (UINT8*)&Attributes;
+ Len[2] = sizeof(UINT32);
+ Addr[3] = (UINT8*)&(CertData->TimeStamp);
+ Len[3] = sizeof(EFI_TIME);
+ Addr[4] = (UINT8*) Data + (CertHdrSize) ;
+ Len[4] = DataSize - (CertHdrSize);
+// zero out unused Time fields:
+/* CertData->TimeStamp.Pad1 = 0;
+ CertData->TimeStamp.Pad2 = 0;
+ CertData->TimeStamp.Nanosecond = 0;
+ CertData->TimeStamp.TimeZone = 0;
+ CertData->TimeStamp.Daylight = 0;*/
+#ifdef EFI_DEBUG
+AVAR_TRACE((TRACE_ALWAYS,"Hash Serialization"));
+ for (j=0; j<5; j++) {
+ AVAR_TRACE((TRACE_ALWAYS,"\nArg%d, Len=0x%x\n0000: ", j, Len[j]));
+ for (i=0; i<Len[j]; i++)
+ {
+ AVAR_TRACE((TRACE_ALWAYS,"%02X ", *(UINT8*)(Addr[j]+i) ));
+ if(Len[j]>16 && i>=15){
+ AVAR_TRACE((TRACE_ALWAYS,"\n....\n%04X: ",Len[j]-16));
+ for (i=Len[j]-16; i<Len[j]; i++)
+ AVAR_TRACE((TRACE_ALWAYS,"%02X ", *(UINT8*)(Addr[j]+i) ));
+ }
+ }
+ }
+#endif
+ Status = mDigitalSigProtocol->Hash(mDigitalSigProtocol, HashAlgorithm, 5, Addr, Len, pDigest);
+#ifdef EFI_DEBUG
+AVAR_TRACE((TRACE_ALWAYS,"\nOutput Digest\n"));
+ for (i=0; i<16; i++)
+ AVAR_TRACE((TRACE_ALWAYS,"%02X ", (pDigest[i]) ));
+AVAR_TRACE((TRACE_ALWAYS,"...\n"));
+#endif
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyVariable2
+//
+// Description:
+// Verify data payload with AuthInfo in EFI_VARIABLE_AUTHENTICATION_2 type.
+// Follow the steps in UEFI2.3.1. This function is called every time variable with
+// EFI_VARIABLE_AUTHENTICATED_TIME_BASED_ACCESS attribute is
+// created, updated or deleted. This function does all necessary
+// authetication checks and based on the results returns Status.
+// Also it updates the ExtFlags.KeyHash with the hash the Signer's
+// certificate from Variable's AuthInfo Hdr
+//
+// Input:
+// CHAR16 *VariableName Name of Variable to be found.
+// EFI_GUID *VendorGuid Variable vendor GUID.
+// IN UINT32 Attributes - Attributes of the Var
+// VOID **Data - pointer to data block within AutVar Data
+// UINTN *DataSize - size of data block
+// VOID *OldData - pointer to Existing in NVRAM data block
+// UINTN OldDataSize - size of data block
+// UINT64 ExtFlags.MonotonicCount - value of MC or TIME stamp
+// UINT8 ExtFlags.KeyHash[32] - pointer to memory, allocated by caller,
+// where Hash of Signer's certificate will be returned.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyVariable2 (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+){
+ EFI_STATUS Status;
+ VOID *RealData;
+ EFI_VARIABLE_AUTHENTICATION_2 *CertData;
+ UINTN CertHdrSize, Pkcs7Cert_len, i;
+ UINT8 *Pkcs7Cert;
+ INT32 TimeStamp, NonZeroTime;
+ UINT8 *PubKeyHash;
+ UINTN PubKeyHashLen;
+ UINT8 AuthVarType;
+
+/*
+ common algo for all Auth2 Vars
+
+1. Verify that the correct AuthInfo.CertType (EFI_CERT_TYPE_PKCS7_GUID) has been
+used and that the AuthInfo.CertData value parses correctly as a PKCS #7 SignedData
+value
+
+2. Verify the signature by:
+-extracting the EFI_VARIABLE_AUTHENTICATION_2 descriptor from the Data buffer;
+-using the descriptor contents and other parameters to
+- construct the input to the digest algorithm;
+-computing the digest;
+ digest = hash (VariableName, VendorGuid, Attributes, TimeStamp, DataNew_variable_content).
+ and
+-comparing the digest with the result of applying the signer's public key to the signature
+!!!!Signer must have at least one Cert!!!!
+
+3. Verify that the signer's certificate chains to a certificate in the Key Exchange Key database (or
+the Platform Key)
+!!!!
+!!!! branch off to handle special Vars for PK or KEK-> Use PK Cert to verify Signer's key
+!!!! all other vars including DB and DBx should be looking for Cert chains in KEK db!!!!
+!!!!
+
+4. Unless the EFI_VARIABLE_APPEND_WRITE attribute is set, verify that the TimeStamp value
+is later than the current timestamp value associated with the variable.
+
+5. For variables with GUID EFI_IMAGE_SECURITY_DATABASE_GUID (i.e. where the data buffer is formatted
+ as EFI_SIGNATURE_LIST), the driver shall not perform an append of EFI_SIGNATURE_DATA values that
+ are already part of the existing variable value
+*/
+// must have Auth attribute to go deeper
+ if ((Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)==0)
+ return EFI_INVALID_PARAMETER;
+
+ RealData = *Data;
+
+ CertData = (EFI_VARIABLE_AUTHENTICATION_2 *) *Data;
+ CertHdrSize = AUTHINFO_2_SIZE(CertData);//(CertData->AuthInfo.Hdr.Hdr.dwLength + sizeof(EFI_TIME));
+
+ if(*DataSize < CertHdrSize)
+ return EFI_SECURITY_VIOLATION;
+
+ // CertBlock->CerData is a begining of Pkcs7 Cert
+ Pkcs7Cert = (UINT8*)&(CertData->AuthInfo.CertData);
+ Pkcs7Cert_len = CertHdrSize - ((UINTN)Pkcs7Cert - (UINTN)*Data);
+
+ //
+ // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
+ // Cert type should be EFI_CERT_TYPE_PKCS7_GUID.
+ //
+ if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
+ guidcmp ((EFI_GUID*) &(CertData->AuthInfo.CertType), &gEfiCertTypePkcs7Guid)
+ ) {
+ //
+ // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
+ //
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ //
+ // Time check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
+ //
+ TimeStamp = 0;
+ if(os_mktime( CertData->TimeStamp.Year, CertData->TimeStamp.Month,
+ CertData->TimeStamp.Day, CertData->TimeStamp.Hour,
+ CertData->TimeStamp.Minute, CertData->TimeStamp.Second, &TimeStamp ))
+ {
+ NonZeroTime = 0;
+ for(i=0;i < sizeof(EFI_TIME); i++)
+ NonZeroTime+=(INT32)((UINT8*)CertData)[i];
+
+ if(NonZeroTime || ((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0)) {
+ AVAR_TRACE((TRACE_ALWAYS,"Invalid Time Stamp\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+ }
+ AVAR_TRACE((TRACE_ALWAYS,"Update Time Stamp\nOld=%x\nNew=%x\n", ExtFlags->Mc, TimeStamp));
+ if( (Attributes & EFI_VARIABLE_APPEND_WRITE) == EFI_VARIABLE_APPEND_WRITE) {
+ // AppendWrite: Only update Timestamp if New one is greater then current
+ if(OldData && (INT32)ExtFlags->Mc > TimeStamp)
+ TimeStamp = (INT32)ExtFlags->Mc;
+ } else {
+ //Unless the EFI_VARIABLE_APPEND_WRITE attribute is set, verify that the TimeStamp value
+ //is later than the current timestamp value associated with the variable.
+ // and reserved TimeStamp fields must be set to 0
+ if( CertData->TimeStamp.Pad1 ||
+ CertData->TimeStamp.Pad2 ||
+ CertData->TimeStamp.Nanosecond ||
+ CertData->TimeStamp.TimeZone ||
+ CertData->TimeStamp.Daylight ||
+ (OldData && (INT32)ExtFlags->Mc >= TimeStamp)
+ ) {
+ AVAR_TRACE((TRACE_ALWAYS,"Failed\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+ }
+ ExtFlags->Mc = TimeStamp;
+ AVAR_TRACE((TRACE_ALWAYS,"Upd=%x\n", ExtFlags->Mc));
+ //
+ // Process PK, KEK, seperately.
+ //
+ if (IsDbVar(VendorGuid))
+ AuthVarType = IsDbVarType;
+ else
+ if (IsPkVar(VariableName, VendorGuid))
+ AuthVarType = IsPkVarType;
+ else
+ if (IsKekVar(VariableName, VendorGuid))
+ AuthVarType = IsKekVarType;
+ else
+ AuthVarType = IsPrivateVarType;
+
+ if(AuthVarType != IsPrivateVarType) {
+
+ //
+ // PK, KEK and db/dbx should set EFI_VARIABLE_NON_VOLATILE attribute
+ // authenticated variable.
+ //
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if (mPlatformMode == SETUP_MODE || mCustomMode == 1 ) {
+ Status = EFI_SUCCESS;
+ goto Exit_SetupMode;
+ }
+ }
+
+ PubKeyHash = &PublicKeyHashArray[0];
+ Status = ConstructDataParameter (
+ VariableName, VendorGuid, Attributes,
+ *Data, *DataSize,
+ PublicKeyHashArray, &PubKeyHashLen,
+ LOCK // first time Pkcs7 cert process.
+ );
+ if (EFI_ERROR(Status))
+ return EFI_SECURITY_VIOLATION;
+
+//
+// Process UEFI Private TimeBased Authenticated Variables
+//
+ if (AuthVarType == IsPrivateVarType){
+ /*
+ Extract x509 Signing Cert(hash) and validate self signed data
+ Updating Cert hash Existing Variable
+ */
+ Status = ValidateSelfSigned (
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ &PubKeyHash, &PubKeyHashLen, // Input->Digest, Output->DER Ptr to Signing Cert
+ Pkcs7CertValidateGetSignerKeyHash
+ );
+ if (!EFI_ERROR(Status)) {
+ // Updating Existing Variable
+ if (OldData && MemCmp(&ExtFlags->KeyHash[0], PubKeyHash, PubKeyHashLen)){
+ AVAR_TRACE((TRACE_ALWAYS,"Private Var Key Compare FAILED!\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+ // Setting Hash for self signed variables
+ MemCpy(&ExtFlags->KeyHash[0], PubKeyHash, PubKeyHashLen);
+
+ *DataSize = *DataSize - CertHdrSize;
+ *Data = (UINT8*)RealData + CertHdrSize;
+ }
+ } else {
+//
+// Process UEFI TimeBased PK, KEK and db(x) variables
+//
+ if (AuthVarType == IsDbVarType) {
+ Status = ProcessVarWithKek2 (Pkcs7Cert, Pkcs7Cert_len, PubKeyHash, PubKeyHashLen);
+ // verify process db(x) with one of KEK keys or if not found within KEK - with PK
+ AVAR_TRACE((TRACE_ALWAYS,"kek for db check %r\n", Status));
+ if (Status == EFI_SECURITY_VIOLATION) {
+ Status = ProcessVarWithPk2 (Pkcs7Cert, Pkcs7Cert_len, PubKeyHash, PubKeyHashLen);
+ AVAR_TRACE((TRACE_ALWAYS,"PK for db check %r\n", Status));
+ }
+ //
+ // Process PK, KEK separately.
+ //
+ } else
+ if (AuthVarType == IsPkVarType || AuthVarType == IsKekVarType)
+ Status = ProcessVarWithPk2 (Pkcs7Cert, Pkcs7Cert_len, PubKeyHash, PubKeyHashLen);
+
+ if (EFI_ERROR(Status))
+ return EFI_SECURITY_VIOLATION;
+
+Exit_SetupMode:
+
+ *DataSize = *DataSize - CertHdrSize;
+ *Data = (UINT8*)RealData + CertHdrSize;
+
+ // Validate Signature List integrity
+ if(*DataSize && EFI_ERROR(ValidateSignatureList (*Data, *DataSize)))
+ return EFI_SECURITY_VIOLATION;
+ //
+ // If delete PK in user mode -> change to setup mode.
+ // If enroll PK in setup mode -> change to user mode.
+ //
+ if(AuthVarType == IsPkVarType) {
+ if (*DataSize == 0)
+ UpdatePlatformMode (SETUP_MODE);
+ else
+ UpdatePlatformMode (USER_MODE);
+ }
+ }
+
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.c b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.c
new file mode 100644
index 0000000..a8489f9
--- /dev/null
+++ b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.c
@@ -0,0 +1,1729 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/AuthVariable.c 90 3/09/15 4:28p Alexp $
+//
+// $Revision: 90 $
+//
+// $Date: 3/09/15 4:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/AuthVariable.c $
+//
+// 90 3/09/15 4:28p Alexp
+// Update year 2015 in the file header
+//
+// 88 10/08/14 3:16p Alexp
+// Introduced global mCustomMode flag passing the status from
+// PhysicalUserPresent()
+//
+// 87 10/17/13 12:58p Alexp
+//
+// 85 6/25/13 1:52p Alexp
+// GetmSecureBootSupport() Init SecureBootVar structure with SDL defaults.
+//
+// 84 5/17/13 4:37p Alexp
+// EIP:122063 CSM related: failure to boot UEFI if DefaultKeyProvision is
+// set without system reset
+// change: SecureBoot variable is set once during AuthVar Init()
+//
+// 83 4/15/13 11:07a Alexp
+// Restore the code to install "SignatureSupport" variable.
+// It was mistakenly removed due to a discussin at USWG that
+// the Var should have been deprectated.
+//
+// 82 3/06/13 6:52p Alexp
+// AuthVariableServiceInitSMM()
+// verify if gAmiSmmDigitalSignatureProtocol already installed before
+// installing a callback on protocol
+//
+// 79 2/20/13 6:31p Alexp
+// EIP[115120]:Secureboot Firmware does not verify duplication before
+// Appending to the variable.
+// Fix: Update FindInSignatureDb() to process combination of SigData and
+// SigLists
+//
+// 77 2/08/13 5:14p Alexp
+// removed unused arguments from ProcessVarWithPk & ProcessVarWithKek
+//
+// 76 12/18/12 10:58a Alexp
+// code fixes according to "cppcheck" style & performance suggestions
+//
+// 73 12/11/12 6:31p Alexp
+// - Replaced TRACE macro with AVAR_TRACE. Stop debug traces in Virtual
+// address mode
+// - VerifyVariable() Fix final check for IsPk and run
+// ValidateSignatureList()
+//
+// 71 12/06/12 7:36p Alexp
+// EIP#98995, EIP#102807 : WHCK tests fail
+// -removed AuthVarLock logic,
+// -use PhysicalUserPresent() hook
+// to unlock Secure Variables for write/erase
+//
+// 70 12/04/12 6:54p Alexp
+// EIP#98995, EIP#102807 : Secure Boot WHCK tests fail
+// temp fix in PhysicalUserPresent()->return NOT_DETECTED if var not found
+//
+// 69 11/26/12 10:46a Alexp
+// replaced hardwired Var name L"SecureBootSetup" to generic Var define
+//
+// 68 11/21/12 3:33p Alexp
+// Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+// across flash updates.
+// Move all secure boot Setup settings to a separate varstore variable
+// in order to preserve settings across re-flash
+//
+// 66 11/16/12 7:11p Alexp
+// Fixed ValidateSignatureList() return status for Zero Data or Size
+//
+// 65 11/09/12 4:30p Alexp
+// EIP:104961 UEFI 2.3.1 SCTc test failed in Generic\EfiCompliant case.
+// Fix for SelfSigned variables.
+//
+// 64 11/01/12 5:45p Alexp
+// bug fix: ValidateSignatureList () returned Success
+// even if no sig detected if file size = 0( line 1015)
+//
+// 63 10/22/12 10:32a Alexp
+// fixed SetupMode overwrite while updating RO vars:SetupMode and
+// SecureBoot.
+//
+// 62 10/19/12 5:07p Alexp
+// Implemented R/O Variables support via fixed and OEM defined (eLink)
+// lists. Secure Boot RO Variable logic includes Vendor GUID check
+// Reserved Secure Boot RO variables are gEfiGlobalVariableGuid.
+//
+// 58 9/25/12 11:20a Alexp
+// Add New feature:
+// include facility to link external Physical User Presence
+// detect hooks via eLink:PhysicalUserPresenceDetect
+//
+// 55 9/14/12 3:40p Alexp
+// 1. removed unused code for setting Pk/Kek/db vars
+// 2. optimized mAuthVarLock logic
+//
+// 54 9/12/12 12:16p Alexp
+// removed dependency on mSecureBootMode. AuthVar is locked always at
+// ReadyTo boot
+//
+// 53 8/29/12 5:02p Alexp
+// SetVariable(): return status matched to UEFI Spec: if both
+// Authenticated Attributes are set returns INVALID_PARAMETER (old
+// UNSUPPORTED)
+//
+// 52 8/27/12 6:55p Alexp
+// GetmSecureBootSupport():
+// Add input parameter SetupMode to disable
+// Setup Flag:SecureBootSupport when platform in Setup Mode
+// Logic enabled by DEFAULT_SECURE_BOOT_ENABLE = 0
+//
+// 50 8/23/12 5:36p Alexp
+// UEFI ECR change.
+// Don't install SignatureSupport Variable. It's obsolete in UEFI 2.3.1+
+//
+// 49 8/22/12 9:23a Alexp
+// difined CUSTOM_BOOT_MODE = 2 to match value in Setup Variable
+//
+// 47 7/27/12 4:36p Alexp
+// Changed Auth Var rules override policy: no need for Admin var checking
+// Further enhancement will introduce physical user presence detection
+//
+// 45 7/25/12 6:37p Alexp
+// enhance ValidateSignatureList() checking. SigList.Size field must be of
+// valid size.
+//
+// 44 5/17/12 4:21p Alexp
+// Fix for SCT 5/12 test for Auth Variables. SCT ignores rules for
+// reserved Secure Boot variables always be formatted as Authenticated
+// Variable with proper attributes.
+//
+// 42 4/30/12 10:53a Alexp
+// EIP88439: irrespective of SetupMode, only properly formatted
+// Authenticated Variable can be erased
+//
+// 40 4/10/12 6:53p Alexp
+// comment clean up
+//
+// 36 3/14/12 1:02p Alexp
+// AuthServiceVirtualFixup: fixup addresses within AmiSigAPI
+//
+// 35 3/13/12 2:36p Alexp
+// Add check for System in Admin mode while allowing Var Security override
+//
+// 33 3/09/12 3:37p Alexp
+// -add logic to process new Secure Boot mode-Custom
+// -just a temp change - will be reviewed in later releases
+//
+// 13 3/09/12 3:35p Alexp
+// -add logic to process new Secure Boot mode-Custom
+// -just a temp change - will be reviewed in later releases
+//
+// 32 2/27/12 6:48p Alexp
+//
+// 31 2/15/12 11:00a Alexp
+// added traces for Signature List validation.
+//
+// 30 2/03/12 9:56a Alexp
+// EIP#82122. WHCK "Secure Boot Manual Logo Test" fails
+// Fixed Append logic to process multiple sig data instances in a single
+// Signature List block
+// New logic will remove dupplicated certs and update new SigList header.
+//
+// 29 12/29/11 6:52p Alexp
+// Updated logic for handling cases with mAuthVarLock = FALSE.
+//
+// 28 12/16/11 4:44p Alexp
+// Add build time switch USER_MODE_POLICY_OVERRIDE
+// AuthVariable logic will allow override/erase Secure Variables without
+// enforcing Authentication rules until receiving EFI ReadyToBoot event.
+//
+// 26 11/30/11 7:58p Alexp
+// According to UEFI 2.3.1 Sec 7.2.1 : "db" vars can be validated either
+// by KEK key or by PK key.
+// The fix adds the check for PK if none of KEKs can validate new "db"
+//
+// 25 11/08/11 3:03p Alexp
+// 1. ValidateSignatureList: add check for invalid parameter Data== NULL
+// 2. VerifyVariable: ignore check for AuthAttribute match if in Setup
+// Mode
+// 3. VerifyVariable: Always set TimeBased Attributes for reserved Sec
+// variables
+//
+// 24 11/02/11 10:53a Alexp
+// 1. EIP#71452. Due to a bug in FindVariable() in NVRAMDXE.C SecureBootSetup
+// Variable cannot be located at first boot.
+// Changed GetmSecureBootSupport() to use
+// DxeGetVariable instead of FindVariable
+// 2. Made temp fixes to pass SCT 2.3.1 TW UEFI Plugfest build.
+// a. MC Based Variable. Length of the CertHdr reported wrongly
+// 22b vs 230 bytes
+// b. MC based Variable. CertType GUID is reported wrongly
+// c. Allow to set reserved Sec Variables KEK, db(x) without Auth
+// attributes in Setup Mode
+//
+// 22 8/24/11 8:45a Alexp
+// added Mailbox variable AuthVarMailbox to inform SMM AuthVariable code
+// of ReadyToBoot event. Needed to prevent erase of Signed Variables in
+// runtime
+//
+//
+// 19 8/22/11 11:11a Alexp
+// UpdatePlatformMode() - moved mPlatformMode=Mode at the end
+// VerifyVar - move back door code inside AuthAttribute branch
+//
+// 17 8/18/11 5:59p Alexp
+// renamed SecureBootMode to more appropriate SecureBootSupport
+// renamed BeforeBoot to AuthVarLock.
+// Keep unlocked in DXE phase and locked while in SMM
+//
+// 16 8/18/11 4:57p Alexp
+// 1. Removed use of Mailbox varaible to communicate state to SMM copy of
+// AuthVar service
+// 2. Removed Callback event to erase Secure Variables.
+// 3. Optimized logic to exchange local data between DXE and SMM copies of
+// AuthVar
+// 4. Add provision to erase of Auth Variables before
+// BdsConnect(ReadyToBoot) lock event
+//
+// 15 8/16/11 7:18p Alexp
+// added Mailbox variable AuthVarMAilbox to syncronize local state between
+// DXE and SMM AuthVariable services
+//
+// 14 8/12/11 1:49p Alexp
+// comment out getplatfmode() in VerifyVariable call. Not needed as we do
+// not want to change the SetupMode in runtime
+//
+// 13 8/05/11 3:13p Alexp
+// VerifyVariable->Set current time as TimeStamp for Signed Variables (PK,
+// KEK..) if they are set in User mode
+//
+// 12 8/04/11 7:15p Alexp
+// 1. UpdatePlatformMode. Moved Get SecureBootSetup to Init function.
+// 2. Fix detection of IsPk() in VerifyVariable for SetupMode control flow
+//
+// 11 7/18/11 10:09a Alexp
+// 1. Made gEfiGlobalVariableGuid static. Fixes link issues in older Aptio
+// cores
+// 2. Update Append verify with added check for the new data to be in
+// SignatureList format
+//
+// 10 6/30/11 4:02p Alexp
+// added Callback event on Setup Mode change request form Security Setup
+// Page.
+//
+// 9 6/27/11 6:16p Alexp
+// code optimization: moved ValidateSignatureList () call in the main
+// VerifyVariable1(2) function.
+//
+// 8 6/24/11 7:03p Alexp
+// fixed ValidateSignatureList () logic. Added Certificate RSA2048 to
+// supported Signatures
+//
+// 7 6/24/11 3:22p Alexp
+// test PK, KEK, db(x) for valid Signatuer List header with
+// ValidateSignatureList()
+//
+// 6 6/24/11 2:24p Alexp
+// 1. Call Auth Variable init in smm callback. need to initialize global
+// variables for SetupMode and SecureBoot
+// 2. Enable SignatureList header validation for PK-KEK-db payload
+//
+// 5 6/23/11 6:19p Alexp
+// Added ValidateSigList() function
+//
+// 4 6/23/11 10:05a Alexp
+// add dependency on ImageAuthentication token for SecureBoot Variable
+// installation
+//
+// 3 6/22/11 5:42p Alexp
+// ignore Authenticated Variable rules while in non SecureBoot mode
+//
+// 2 6/15/11 3:01p Alexp
+// Add checks for variables with zero parameters: Attributes, Data, Size
+//
+// 1 6/13/11 5:25p Alexp
+//
+// 18 6/13/11 4:28p Alexp
+// rearranged calls to VerifyVariable1 & 2 from main VerifyVariable()
+//
+// 17 6/09/11 5:49p Alexp
+// add AuthServiceVirtualFixup
+//
+// 16 6/06/11 6:01p Alexp
+// UpdatePlatformMode: update both SetupMode and SecureBoot at once
+//
+// 15 6/03/11 4:12p Alexp
+// bug fix: when changing SetupMode check for PK file attribute to have
+// Auth flag
+// set TimeBased attrib for non-signed generic Secured variables (Win8
+// w/a)
+//
+//
+// 13 6/02/11 5:50p Alexp
+// fix a bug with self signed key hash compare
+//
+// 12 6/02/11 1:06p Alexp
+// fix failed case with Append db logic if certificate already existed
+//
+// 11 6/01/11 1:06p Alexp
+// removed GetSecureVars hook. Use UpdatePlatformMode() instead
+// cleaned Append logic
+//
+// 9 5/25/11 8:34p Alexp
+// draft fix for TimeBased auth variables. More work w Msft needed
+//
+// 8 5/19/11 4:59p Alexp
+// Major code revamp to be able to handle of handling Secure vars in Setup
+// Mode
+// TBD: TimeBased certificates from Msft fail to process. Not compiled as
+// Authenticode format
+//
+// 7 5/17/11 12:48p Alexp
+// fix WDK level4 compiler warnings
+//
+// 6 5/13/11 3:43p Alexp
+// add dependency on Core rev.
+//
+// 5 5/12/11 5:53p Alexp
+// fix tobuld for Aptio core 4.6.4. and older.
+//
+// 4 5/11/11 7:20p Alexp
+// VarData init for FindVariable
+//
+// 3 5/10/11 5:07p Alexp
+// removed local Hash Guid defines
+//
+// 2 5/10/11 3:56p Alexp
+// move FindVariable to NVRAMDXE.c
+//
+// 1 5/09/11 10:00a Alexp
+//
+// 9 5/05/11 12:10p Alexp
+// make it as eModule, replace TRACE call to TRACE macro. Only dump TRACEs
+// in Debug mode
+//
+// 8 3/31/11 6:27p Alexp
+// removed asserts on missing DB, KEK
+//
+//**********************************************************************
+
+#include "NVRAM.h"
+#include <AmiDxeLib.h>
+#include <AmiCspLib.h>
+#include <Setup.h>
+#include <SecureBootMod.h>
+
+#include <Protocol/AmiDigitalSignature.h>
+
+#include "AuthVariable.h"
+
+//
+// Global defines and variables
+//
+
+BOOLEAN AVarRuntime = FALSE;
+
+#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \
+{0x3aa83745, 0x9454, 0x4f7a, 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e}
+static EFI_GUID gBdsConnectDriversProtocolGuid = BDS_CONNECT_DRIVERS_PROTOCOL_GUID;
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+static EFI_GUID mSignatureSupport[SIGSUPPORT_NUM] = {SIGSUPPORT_LIST};
+static EFI_GUID gSecureSetupGuid = SECURITY_FORM_SET_GUID;
+static EFI_GUID gSystemAccessGuid = SYSTEM_ACCESS_GUID;
+static SECURE_BOOT_SETUP_VAR mSecureBootSetup;
+
+UINT8 PublicKeyHashArray[HASH_SHA256_LEN];
+UINT8 mPlatformMode = SETUP_MODE;
+UINT8 mSetupMode = USER_MODE;
+UINT8 mCustomMode = 0;
+static UINT8 mSecureBootSupport = NONSECURE_BOOT;
+
+AMI_DIGITAL_SIGNATURE_PROTOCOL *mDigitalSigProtocol = NULL;
+
+static CHAR16* ReservedReadOnlyVarNameList[] = {
+ EFI_SETUP_MODE_NAME,
+ EFI_SECURE_BOOT_NAME,
+ EFI_SIGNATURE_SUPPORT_NAME,
+ EFI_IMAGE_SECURITY_DATABASE_DEFAULT,
+ EFI_IMAGE_SECURITY_DATABASE1_DEFAULT,
+ EFI_PLATFORM_KEY_NAME_DEFAULT,
+ EFI_KEY_EXCHANGE_KEY_NAME_DEFAULT,
+ NULL
+};
+static CHAR16* OemReadOnlyVariableList[] = {OEM_READONLY_VAR_LIST NULL};
+
+#if USER_MODE_POLICY_OVERRIDE == 1
+
+typedef BOOLEAN (HOOK_PHYSICAL_USER_PRESENCE_DETECT)(
+ VOID
+);
+
+extern HOOK_PHYSICAL_USER_PRESENCE_DETECT PHYSICAL_USER_PRESENCE_DETECT_LIST EndOfPhysicalUserPresentHook;
+
+HOOK_PHYSICAL_USER_PRESENCE_DETECT* PhysicalUserPresentHookList[]=
+ {PHYSICAL_USER_PRESENCE_DETECT_LIST NULL};
+
+BOOLEAN PhysicalUserPresent( VOID )
+{
+ UINTN i;
+ BOOLEAN Result = FALSE;
+ for(i=0; PhysicalUserPresentHookList[i] && (Result == FALSE); i++)
+ Result = PhysicalUserPresentHookList[i]();
+ return Result;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AuthVarAdminUserPresent
+//
+// Description: Default implementation for Physical User Presense detection.
+// Detects if Admin User signed in by checking "SystemAccess" Variable
+//
+// Input: NONE
+//
+// Output: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN AuthVarAdminUserPresent ( VOID )
+{
+ SYSTEM_ACCESS SystemAccess = {SYSTEM_PASSWORD_USER};
+ UINTN Size = sizeof(SYSTEM_ACCESS);
+ UINT32 Attributes = 0;
+ EFI_STATUS Status;
+ // TBD. Replace Admin User mode with true Physical user presence detection
+ Status = DxeGetVariable(L"SystemAccess", &gSystemAccessGuid, &Attributes, &Size, &SystemAccess);
+ if (!EFI_ERROR(Status)
+ && !(Attributes & EFI_VARIABLE_NON_VOLATILE)
+ && SystemAccess.Access==SYSTEM_PASSWORD_ADMIN)
+ {
+ return TRUE;
+ }
+
+ return FALSE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AuthServiceVirtualFixup
+//
+// Description: This function will be invoked to convert
+// runtime pointers to virtual address
+//
+// Input: none
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AuthServiceVirtualFixup()
+{
+
+ static BOOLEAN bSigProtoVirtual = FALSE;
+ VOID **p;
+ UINT8 i;
+
+ //if mDigitalSigProtocol is NULL, nothing to fix up
+ if (!mDigitalSigProtocol) return;
+
+ // This function gets called from Nvramdxe.c, do nothing when
+ // the function is called second time.
+ if (bSigProtoVirtual == TRUE) return;
+ else bSigProtoVirtual = TRUE;
+//AVAR_TRACE((-1,"AuthVarService mDigitalSig Virtual addr Fixup\n"));
+ //Fixup mDigitalSigProtocol member functions
+ for(i=0,p = (VOID**)mDigitalSigProtocol; p < (VOID**)(mDigitalSigProtocol + 1); i++,p++)
+// {
+//AVAR_TRACE((-1,"mSigAPI[%d] before Virtual MemFixup = %lx (%lx), ", i, p));
+ pRS->ConvertPointer(0, p);
+//AVAR_TRACE((-1,"After = %lx\n", p));
+// }
+ pRS->ConvertPointer(0,&mDigitalSigProtocol);
+ AVarRuntime = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitSmmAuthServiceCallback
+//
+// Description: This function initialize mDigitalSigProtocol in SMM
+//
+//
+// Input: IN EFI_EVENT Event - Event that was triggered
+// IN VOID *Context - data pointer to information that is defined
+// when the event is registered
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS InitSmmAuthServiceCallback (IN EFI_EVENT Event, IN VOID *Context)
+{
+ return pBS->LocateProtocol(
+ &gAmiSmmDigitalSignatureProtocolGuid, NULL, &mDigitalSigProtocol
+ );
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitSmmAuthService
+//
+// Description: This function calls InitSmmAuthServiceCallback to initialaze
+// DigitalSigProtocol in SMM by trying to Locate
+// DigitalSigProtocol. If Protocol is not installed yet
+// RegisterProtocolCallback will be called.
+//
+//
+// Input: None
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AuthVariableServiceInitSMM ()
+{
+ EFI_STATUS Status;
+ EFI_EVENT SmmHashEvent;
+ VOID *pSmm;
+
+ // temp w/a: don't print debug traces from SMM
+ AVarRuntime = TRUE;
+ //
+ // Authenticated variable initialize.
+ //
+ // Check PK database's existence to determine the value.
+ // Then create "SetupMode" with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
+ //
+ // Update mPlatformMode
+ GetPlatformMode();
+
+ // Update mSecureBootSupport global variable
+ GetmSecureBootSupport(mPlatformMode);
+
+ Status = InitSmmAuthServiceCallback (NULL, NULL);
+ if (EFI_ERROR(Status))
+ RegisterProtocolCallback(
+ &gAmiSmmDigitalSignatureProtocolGuid,
+ InitSmmAuthServiceCallback,
+ NULL,
+ &SmmHashEvent,
+ &pSmm
+ );
+}
+
+//------------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitAuthServiceCallback
+//
+// Description: This function initialize mDigitalSigProtocol not in SMM
+//
+//
+// Input: IN EFI_EVENT Event - Event that was triggered
+// IN VOID *Context - data pointer to information that is defined
+// when the event is registered
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS InitAuthServiceCallback (IN EFI_EVENT Event, IN VOID *Context)
+{
+ return pBS->LocateProtocol(
+ &gAmiDigitalSignatureProtocolGuid, NULL, &mDigitalSigProtocol
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AuthVariableServiceInit
+//
+// Description: This function calls InitAuthServiceCallback to initialaze
+// DigitalSigProtocol not in SMM by trying to Locate
+// DigitalSigProtocol. If Protocol is not installed yet
+// RegisterProtocolCallback will be called.
+//
+//
+// Input: None
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID AuthVariableServiceInit ()
+{
+ EFI_EVENT Event;
+ VOID *p;
+ UINT8 Data;
+
+ //
+ // Create "SignatureSupport" with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
+ //
+ DxeSetVariable(EFI_SIGNATURE_SUPPORT_NAME,&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SIGSUPPORT_NUM * sizeof(EFI_GUID), &mSignatureSupport
+ );
+ //
+ // Check presence of PK database to determine the value.
+ // Then create "SetupMode" with EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS set.
+ // Update mPlatformMode
+ GetPlatformMode();
+
+ // Update mSecureBootSupport global variable
+ GetmSecureBootSupport(mPlatformMode);
+
+ // Set SecureBoot, both conditions must be met
+ Data = (mPlatformMode==USER_MODE && mSecureBootSupport==SECURE_BOOT)?1:0;
+ DxeSetVariable(EFI_SECURE_BOOT_NAME,&gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT8), &Data);
+
+ // Create "SetupMode" variable with RO access
+ UpdatePlatformMode(mPlatformMode);
+
+ if (EFI_ERROR(InitAuthServiceCallback (NULL, NULL)))
+ RegisterProtocolCallback(
+ &gAmiDigitalSignatureProtocolGuid,
+ InitAuthServiceCallback,
+ NULL,
+ &Event,
+ &p
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrSize16
+//
+// Description:
+// This function returns UNICODE string size in bytes
+//
+// Input:
+// CHAR16 *String - Pointer to string
+//
+// Output:
+// UINT32 - Size of string in bytes excluding the nul-terminator
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32 StrSize16(CHAR16 *String)
+{
+ UINT32 Size = 0;//2;
+ while(*String++)
+ Size += 2;
+ return Size;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StrCmp16
+//
+// Description:
+// This function compares two UNICODE strings
+//
+// Input:
+// IN CHAR16 *Dest - Pointer to destination string
+// IN CHAR16 *Src - Pointer to source string
+//
+// Output:
+// INTN - Zero if strings are equal, non-zero otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+INTN StrCmp16(CHAR16 *Dest, CHAR16 *Src)
+{
+ return MemCmp(Dest, Src, StrSize16(Src));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsPkVar
+//
+// Description:
+// This function compares two UNICODE strings
+//
+// Input:
+// CHAR16 - Pointer to UNICODE Variable Name
+// EFI_GUID - Pointer to Variable GUID
+//
+// Output:
+// BOOLEAN - TRUE if strings are equal
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsPkVar(
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+)
+{
+ return ((guidcmp(VendorGuid, &gEfiGlobalVariableGuid) == 0) &&
+ (StrCmp16 ((CHAR16 *)VariableName, (CHAR16 *)EFI_PLATFORM_KEY_NAME) == 0));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsKekVar
+//
+// Description:
+// This function compares two UNICODE strings
+//
+// Input:
+// CHAR16 - Pointer to UNICODE Variable Name
+// EFI_GUID - Pointer to Variable GUID
+//
+// Output:
+// BOOLEAN - TRUE if strings are equal
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsKekVar(
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+)
+{
+ return ((guidcmp(VendorGuid, &gEfiGlobalVariableGuid) == 0) &&
+ (StrCmp16 ((CHAR16 *)VariableName, (CHAR16 *)EFI_KEY_EXCHANGE_KEY_NAME) == 0));
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsReservedVariableName
+//
+// Description:
+// Check if Variable name matches one from Predefined Read-Only Variable Name list
+//
+// Input:
+// CHAR16 - Pointer to UNICODE Variable Name
+// EFI_GUID *VendorGuid - Variable GUID
+//
+// Output:
+// BOOLEAN
+// TRUE if Variable name found in the Predefined Read-Only Variable Name lists
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+IsReservedVariableName(
+ CHAR16 *VariableName,
+ EFI_GUID *VendorGuid
+)
+{
+ UINT8 Index;
+ Index = 0;
+
+ while(ReservedReadOnlyVarNameList[Index] != NULL)
+ {
+ if(StrCmp16 (VariableName, ReservedReadOnlyVarNameList[Index]) == 0)
+ {
+// Reserved Secure Boot RO variables are gEfiGlobalVariableGuid.
+ return (guidcmp(VendorGuid, &gEfiGlobalVariableGuid) == 0);
+ }
+ Index++;
+ }
+ Index = 0;
+ while(OemReadOnlyVariableList[Index] != NULL)
+ {
+ if(StrCmp16 (VariableName, OemReadOnlyVariableList[Index]) == 0)
+ return TRUE;
+ Index++;
+ }
+
+ return FALSE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsDbVar
+//
+// Description:
+// This function compares two UNICODE strings
+//
+// Input:
+// IN CHAR16 *Dest - Pointer to destination string
+// IN CHAR16 *Src - Pointer to source string
+//
+// Output:
+// INTN - Zero if strings are equal, non-zero otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsDbVar(
+ IN EFI_GUID *VendorGuid
+)
+{
+ return (!guidcmp (VendorGuid, &gEfiImageSecurityDatabaseGuid));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetPlatformMode
+//
+// Description:
+// Initializes for authenticated varibale service.
+//
+// Input:
+// UINT8 *PlatformMode
+//
+// Output: EFI_STATUS Function successfully executed.
+// UINT8 *PlatformMode
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetPlatformMode (
+ VOID
+)
+{
+ EFI_STATUS Status;
+ UINT32 VarAttr;
+ UINTN VarDataSize;
+ VOID *Data;
+
+ mPlatformMode = USER_MODE;
+
+ //
+ // Check PK database's existence to determine the value.
+ //
+ VarDataSize = 0;
+ Status = FindVariable (
+ EFI_PLATFORM_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ &VarAttr,
+ &VarDataSize,
+ &Data
+ );
+ if (Status != EFI_SUCCESS || Data == NULL || VarDataSize == 0 ||
+ !(VarAttr & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES)
+ ) {
+ mPlatformMode = SETUP_MODE;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetmSecureBootSupport
+//
+// Description:
+// Initializes for authenticated varibale service.
+//
+// Input:
+// SetupMode Disable SecureBoot control if Platform runs in SetupMode (no PK)
+//
+// Output: EFI_STATUS Function successfully executed.
+// EFI_OUT_OF_RESOURCES Fail to allocate enough memory resources.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+GetmSecureBootSupport (
+ UINT8 SetupMode
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+//#if defined(ImageVerification_SUPPORT) && ImageVerification_SUPPORT==1
+ UINTN DataSize=0;
+ //
+ // Get Setup variable, check SecureBoot and set the EFI Var
+ //
+ Status = DxeGetVariable(
+ AMI_SECURE_BOOT_SETUP_VAR,
+ &gSecureSetupGuid,
+ NULL,
+ &DataSize,
+ &mSecureBootSetup
+ );
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ Status = DxeGetVariable(
+ AMI_SECURE_BOOT_SETUP_VAR,
+ &gSecureSetupGuid,
+ NULL,
+ &DataSize,
+ &mSecureBootSetup
+ );
+ ASSERT_EFI_ERROR (Status);
+ mSecureBootSupport = (mSecureBootSetup.SecureBootSupport);
+// Disable SecureBoot Setup Option if system is in Setup mode
+#if DEFAULT_SECURE_BOOT_ENABLE == 0
+ if(mSecureBootSupport == 1 &&
+ (SetupMode == SETUP_MODE && mSecureBootSetup.DefaultKeyProvision == 0)
+ )
+ {
+ mSecureBootSupport = NONSECURE_BOOT;
+ }
+#endif
+//#else
+// mSecureBootSupport = NONSECURE_BOOT;
+//#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdatePlatformMode
+//
+// Description: Update mPlatformMode & "SetupMode" Efi var
+//
+// Input: Mode SETUP_MODE or USER_MODE.
+//
+// Output: none
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdatePlatformMode(
+ IN UINT8 Mode
+)
+{
+AVAR_TRACE((TRACE_ALWAYS,"Update Setup Mode\nCurrent=%x, New=%x\n", mPlatformMode, Mode));
+ //
+ // update global mPlatformMode var
+ //
+ mPlatformMode = Mode;
+ //
+ // Set "SetupMode" variable.
+ //
+ // Setting of mSetupMode=SETUP_MODE will un-lock access to runtime R/O vars
+ mSetupMode = SETUP_MODE;
+
+ DxeSetVariable(EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid,
+ EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT8), &mPlatformMode);
+
+// Re-lock access to runtime protected vars
+ mSetupMode = USER_MODE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ValidateSignatureList
+//
+// Description:
+// Validate the data payload begins with valid Signature List header
+// and based on the results returns Status.
+//
+// Input:
+// IN VOID *Data - pointer to the Var data
+// IN UINTN DataSize - size of Var data
+//
+// Output: EFI_STATUS
+// UINTN RealDataSize - only the size of the combined length of Signature Lists
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ValidateSignatureList (
+ IN VOID *Data,
+ IN UINTN DataSize
+)
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *SigList;
+ UINTN Index;
+
+ Status = EFI_SECURITY_VIOLATION;
+
+ if(Data == NULL || DataSize == 0)
+ return Status; // Sig not found
+
+ SigList = (EFI_SIGNATURE_LIST *)Data;
+
+// loop till end of DataSize for all available SigLists
+
+// Verify signature is one from SigDatabase list mSignatureSupport / sizeof(EFI_GUID)
+// SigData begins with SigOwner GUID
+// SignatureHdrSize = 0 for known Sig Types
+
+ while ((DataSize > 0) && (DataSize >= SigList->SignatureListSize)) {
+
+ for (Index = 0; Index < SIGSUPPORT_NUM; Index++) {
+ if (!guidcmp ((EFI_GUID*) &(SigList->SignatureType), &mSignatureSupport[Index]))
+ break;
+ }
+AVAR_TRACE((TRACE_ALWAYS,"SigList.Type-"));
+ if(Index >= SIGSUPPORT_NUM)
+ return EFI_SECURITY_VIOLATION; // Sig not found
+
+AVAR_TRACE((TRACE_ALWAYS,"OK\nSigList.Size-"));
+ if(SigList->SignatureListSize < 0x4c || // Min size for SHA2 Hash Certificate sig list
+ SigList->SignatureListSize > NVRAM_SIZE)
+ return EFI_SECURITY_VIOLATION;
+
+AVAR_TRACE((TRACE_ALWAYS,"OK\nSigList.HdrSize-"));
+ if(SigList->SignatureHeaderSize != 0)
+ return EFI_SECURITY_VIOLATION; // Sig not found
+AVAR_TRACE((TRACE_ALWAYS,"OK\n"));
+ DataSize -= SigList->SignatureListSize;
+ SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);
+
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessVarWithPk
+//
+// Description: Process variable with platform key for verification.
+//
+//
+// Input:
+// VariableName Name of Variable to be found.
+// VendorGuid Variable vendor GUID.
+// Data Data pointer.
+// DataSize Size of Data found. If size is less than the
+// data, this value contains the required size.
+// Variable The variable information which is used to
+// keep track of variable usage.
+// Attributes Attribute value of the variable
+// IsPk Indicate whether it is to process pk.
+//
+// Output: EFI_SUCCESS Variable passed validation successfully.
+// EFI_INVALID_PARAMETER Invalid parameter.
+// EFI_SECURITY_VIOLATION The variable does NOT pass the validation.
+// check carried out by the firmware.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ProcessVarWithPk (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN UINT32 Attributes,
+ IN BOOLEAN IsPk
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_SIGNATURE_LIST *OldPkList;
+ EFI_SIGNATURE_DATA *OldPkData;
+ UINT32 VarAttr;
+ UINT8 *VarData;
+ UINTN VarDataSize=0;
+
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
+ //
+ // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute.
+ //
+//AVAR_TRACE((TRACE_ALWAYS,"PK NOT_VOLITILE\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mPlatformMode == SETUP_MODE || mCustomMode == 1)
+ return Status;
+ //
+ // Get platform key from variable.
+ //
+ Status = FindVariable (
+ EFI_PLATFORM_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ &VarAttr,
+ &VarDataSize,
+ &VarData
+ );
+// PK should have been set when we were in SETUP_MODE. This condition is INVALID.
+ if (EFI_ERROR (Status) || VarData==NULL || !VarDataSize)
+ return EFI_SECURITY_VIOLATION;
+
+ OldPkList = (EFI_SIGNATURE_LIST *) VarData;
+ OldPkData = (EFI_SIGNATURE_DATA *) ((UINT8 *) OldPkList + sizeof (EFI_SIGNATURE_LIST) + OldPkList->SignatureHeaderSize);
+
+// Authenticate
+ Status = VerifyDataPayload (Data, DataSize, OldPkData->SignatureData);
+//AVAR_TRACE((TRACE_ALWAYS,"PK VerifyPayload %r\n",Status));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ProcessVarWithKek
+//
+// Description: Process variable with key exchange key for verification.
+//
+//
+// Input:
+// Data Data pointer.
+// DataSize Size of Data found. If size is less than the
+// data, this value contains the required size.
+// Variable The variable information which is used to
+// keep track of variable usage.
+// Attributes Attribute value of the variable
+//
+// Output: EFI_SUCCESS Variable passed validation successfully.
+// EFI_INVALID_PARAMETER Invalid parameter.
+// EFI_SECURITY_VIOLATION The variable does NOT pass the validation.
+// check carried out by the firmware.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ProcessVarWithKek (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN UINT32 Attributes
+ )
+{
+// so far can be DB or DBx variables
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_SIGNATURE_LIST *KekList;
+ EFI_SIGNATURE_DATA *KekItem;
+ UINT32 KekCount;
+ EFI_VARIABLE_AUTHENTICATION *CertData;
+ EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
+// BOOLEAN IsFound;
+ UINT32 Index;
+ UINT32 VarAttr;
+ UINT8 *VarData;
+ UINTN VarDataSize = 0;
+
+ if ((Attributes & EFI_VARIABLE_NON_VOLATILE) == 0) {
+ //
+ // PK and KEK should set EFI_VARIABLE_NON_VOLATILE attribute.
+ //
+ return EFI_INVALID_PARAMETER;
+ }
+
+//
+// If in setup mode, no authentication needed.
+//
+ if (mPlatformMode == SETUP_MODE || mCustomMode == 1)
+ return Status;
+
+ CertData = (EFI_VARIABLE_AUTHENTICATION *) Data;
+ CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256 *)&(CertData->AuthInfo.CertData);
+ //
+ // Get Key database from KEK variable.
+ //
+ Status = FindVariable (
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ &gEfiGlobalVariableGuid,
+ &VarAttr,
+ &VarDataSize,
+ &VarData
+ );
+
+ KekList = (EFI_SIGNATURE_LIST *) VarData;
+ if (EFI_ERROR(Status) || guidcmp ((EFI_GUID*) &(KekList->SignatureType), &gEfiCertRsa2048Guid))
+ return EFI_SECURITY_VIOLATION;
+ //
+ // Enumerate all Kek items in this list to verify the variable certificate data.
+ // If anyone is authenticated successfully, it means the variable is correct!
+ //
+// IsFound = FALSE;
+//
+// scan thru multiple Sig Lists if exist. Add 1 more loop....
+// actually, KEK would have one list since KEK owner may club all Kek keys together before signing with PK
+// do {
+ KekCount = (KekList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - KekList->SignatureHeaderSize) / KekList->SignatureSize;
+ KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekList + sizeof (EFI_SIGNATURE_LIST) + KekList->SignatureHeaderSize);
+ for (Index = 0; Index < KekCount; Index++) {
+ if (MemCmp (KekItem->SignatureData, CertBlock->PublicKey, EFI_CERT_TYPE_RSA2048_SIZE) == 0) {
+// IsFound = TRUE;
+ break;
+ }
+ KekItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) KekItem + KekList->SignatureSize);
+ }
+// KekList = (EFI_SIGNATURE_LIST *) ((UINT8 *) KekList + KekList->SignatureListSize);
+// } while (!IsFound || (UINT8*)KekList < (VarData+VarDataSize));
+// if (!IsFound) {
+ if (Index >= KekCount) {
+ return EFI_SECURITY_VIOLATION;
+ }
+// Authenticate
+ Status = VerifyDataPayload (Data, DataSize, CertBlock->PublicKey);
+//AVAR_TRACE((TRACE_ALWAYS,"KEK VerifyPayload %r\n",Status));
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyDataPayload
+//
+// Description:
+// Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type.
+// Follow the steps in UEFI2.2. This function does signature
+// authetication and based on the results returns Status.
+//
+// Input:
+// IN VOID *Data - pointer to the Var data
+// IN UINTN DataSize - size of Var data
+// UINT8 *PubKey - PublicKey used for Sig verification.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyDataPayload (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN UINT8 *PubKey
+)
+{
+ EFI_STATUS Status;
+ EFI_VARIABLE_AUTHENTICATION *CertData;
+ EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
+ UINT8 Digest[HASH_SHA256_LEN];
+ UINT8 *Addr[2];
+ UINTN Len[2];
+ UINTN CertHdrSize;
+
+ CRYPT_HANDLE PublicKey;
+ CRYPT_HANDLE HashToVerify;
+
+ CertData = (EFI_VARIABLE_AUTHENTICATION *)Data;
+// CertHdrSize = AUTHINFO_SIZE(Data);
+// SCT 2.3.1. TW UEFI Plugfest BUG with listing of a Cert Size in Cert->AuthInfo.Hdr.dwLength
+ CertHdrSize = 0x230;
+
+ CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256*)&(CertData->AuthInfo.CertData);
+
+ //
+ // Hash data payload with SHA256.
+ //
+ Addr[0] = (UINT8*) Data + (CertHdrSize) ;
+ Len[0] = DataSize - (CertHdrSize);
+ Addr[1] = (UINT8*)&(CertData->MonotonicCount);
+ Len[1] = sizeof(UINT64);
+ Status = mDigitalSigProtocol->Hash(mDigitalSigProtocol,
+ &gEfiHashAlgorithmSha256Guid,
+ 2, Addr, Len, (UINT8*)&Digest[0]);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ PublicKey.AlgGuid = gEfiCertRsa2048Guid;
+ PublicKey.BlobSize = EFI_CERT_TYPE_RSA2048_SIZE;
+ PublicKey.Blob = PubKey;//(UINT8*)&(CertData->AuthInfo.CertData.PublicKey);
+
+ HashToVerify.AlgGuid = gEfiHashAlgorithmSha256Guid;
+ HashToVerify.BlobSize = SHA256_DIGEST_SIZE;
+ HashToVerify.Blob = &Digest[0];
+
+ Status = mDigitalSigProtocol->Pkcs1Verify(
+ mDigitalSigProtocol,
+ &PublicKey,
+ &HashToVerify,
+ (UINT8*)&(CertBlock->Signature),
+ EFI_CERT_TYPE_RSA2048_SHA256_SIZE, EFI_CRYPT_RSASSA_PKCS1V15/*EFI_CRYPT_RSASSA_PSS*/);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindInSignatureDb
+//
+// Description:
+// For variables with GUID EFI_IMAGE_SECURITY_DATABASE_GUID
+// (i.e. where the data buffer is formatted as EFI_SIGNATURE_LIST),
+// the driver shall not perform an append of EFI_SIGNATURE_DATA values
+// that are already part of the existing variable value (Note: This situation
+// is not considered an error, and shall in itself not cause a status code other
+// than EFI_SUCCESS to be returned or the timestamp associated with the variable not
+// to be updated).
+//
+// Input:
+// EFI_GUID *VendorGuid Variable vendor GUID.
+// IN UINT32 Attributes - Attributes of the Var
+// VOID *Data - pointer to data block within AutVar Data
+// UINTN *DataSize - ptr to size of data block
+// VOID *SigDb - current SigDb
+// UINTN SigDbSize
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindInSignatureDb (
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID *Data,
+ IN OUT UINTN *DataSize,
+ IN VOID *SigDb,
+ IN UINTN SigDbSize
+){
+ EFI_SIGNATURE_LIST *SigList;
+ EFI_SIGNATURE_LIST *SigListNew;
+ EFI_SIGNATURE_DATA *SigItem;
+ EFI_SIGNATURE_DATA *SigItemNew;
+ UINT32 SigCount;
+ UINT32 Index;
+ UINT32 SigCountNew;
+ UINT32 IndexNew;
+
+ UINTN SigNewSize;
+ BOOLEAN bSigMatch;
+ // Is Append & SigDB
+ if ( (SigDb && SigDbSize) &&
+ ((Data != SigDb) && (Attributes & EFI_VARIABLE_APPEND_WRITE)) &&
+ // Validate Signature List integrity
+ !EFI_ERROR(ValidateSignatureList (Data, *DataSize))
+ ) {
+ SigList = (EFI_SIGNATURE_LIST *)SigDb;
+ SigListNew = (EFI_SIGNATURE_LIST *)Data;
+AVAR_TRACE((TRACE_ALWAYS,"FindInDB(x)\nDataSize In %d (0x%X)\n",*DataSize,*DataSize));
+ //
+ // Enumerate all Sig items in this list to verify the variable certificate data.
+ //
+ //
+ // scan through multiple Sig Lists in DB exist.
+ while ((SigDbSize > 0) && (SigDbSize >= SigList->SignatureListSize)) {
+ SigCount = (SigList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigList->SignatureHeaderSize) / SigList->SignatureSize;
+ SigItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigList + sizeof (EFI_SIGNATURE_LIST) + SigList->SignatureHeaderSize);
+//AVAR_TRACE((TRACE_ALWAYS,"Org SigList Count: %d, SigSize %X\n", SigCount, SigList->SignatureSize));
+ // scan through multiple Sig Lists in NewSigList.
+ for (Index = 1; Index <= SigCount; Index++) {
+////AVAR_TRACE((TRACE_ALWAYS,"OrgCert %d, Data %X\n",Index, *(UINT32*)SigItem->SignatureData));
+ SigListNew = (EFI_SIGNATURE_LIST *)Data;
+ SigNewSize = *DataSize;
+ while ((SigNewSize > 0) && (SigNewSize >= SigListNew->SignatureListSize)) {
+ bSigMatch = FALSE;
+ SigItemNew = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigListNew + sizeof (EFI_SIGNATURE_LIST) + SigListNew->SignatureHeaderSize);
+ SigCountNew = (SigListNew->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigListNew->SignatureHeaderSize) / SigListNew->SignatureSize;
+ if (!guidcmp ((EFI_GUID*) &(SigList->SignatureType), (EFI_GUID*)&(SigListNew->SignatureType)) &&
+ SigList->SignatureSize == SigListNew->SignatureSize) {
+//AVAR_TRACE((TRACE_ALWAYS,"New SigDb Size %X\nNew SigList Count: %d, SigSize %X\n", SigNewSize, SigNewCount, SigNewList->SignatureSize));
+ // loop through all instances of NewSigList->SigData.
+ for (IndexNew = 1; IndexNew <= SigCountNew; IndexNew++) {
+////AVAR_TRACE((TRACE_ALWAYS,"NewCert %d, Data %X\n",IndexNew, *(UINT32*)SigNewItem->SignatureData));
+ if (MemCmp (SigItem->SignatureData, SigItemNew->SignatureData, SigList->SignatureSize-sizeof(EFI_GUID)) == 0) {
+//AVAR_TRACE((TRACE_ALWAYS,"---> match found!!!\n"));
+//AVAR_TRACE((TRACE_ALWAYS,"OrgCert %4d, Data %X\n",Index, *(UINT32*)SigItem->SignatureData));
+//AVAR_TRACE((TRACE_ALWAYS,"NewCert %4d, Data %X\n",IndexNew, *(UINT32*)SigNewItem->SignatureData));
+ if(SigCountNew == 1) {
+ // only 1 SigData per SigList - discard this SigList
+ bSigMatch = TRUE;
+//AVAR_TRACE((TRACE_ALWAYS,"Before: DataSize=%x\nAfter : DataSize=%x\n", *DataSize, *DataSize-SigNewList->SignatureListSize));
+ // 1. Decrease *Datasize by SigNewList->SignatureSize
+ SigNewSize -= SigListNew->SignatureListSize;
+ *DataSize -= SigListNew->SignatureListSize;
+ // 2. replace this SigData block with data following it
+ MemCpy (SigListNew, (void*)((UINTN)SigListNew+SigListNew->SignatureListSize), SigNewSize);
+ // 3. Skip to next SigListNew
+ break;
+ } else {
+ // more then 1 - discard this SigData
+ // 1. replace this SigData block with data following it
+ MemCpy (SigItemNew, (void*)((UINTN)SigItemNew+SigListNew->SignatureSize), ((UINTN)Data+*DataSize)-((UINTN)SigItemNew+SigListNew->SignatureSize));
+ // 2. Decrease SigNewList->SignatureListSize by SigNewList->SignatureSize
+ SigListNew->SignatureListSize-=SigListNew->SignatureSize;
+ *DataSize-=SigListNew->SignatureSize;
+//AVAR_TRACE((TRACE_ALWAYS,"Upd SignatureListSize=%x, DataSize=%x\n",SigNewList->SignatureListSize, *DataSize));
+ // 3. If this is last SigData element
+ if((SigListNew->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - SigListNew->SignatureHeaderSize)==0)
+ {
+//AVAR_TRACE((TRACE_ALWAYS,"SigList is Empty!\n"));
+ break;
+ }
+ // 4. Skip incrementing of SigNewItem
+ continue;
+ }
+ } // if cmp
+ SigItemNew = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigItemNew + SigListNew->SignatureSize);
+ } // for SigNewItem
+ } // if guid
+ // Skip incrementing of SigNewList if bSigListMatch is found - we already on next siglist
+ if(!bSigMatch) {
+ SigNewSize -= SigListNew->SignatureListSize;
+ SigListNew = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigListNew + SigListNew->SignatureListSize);
+ }
+ } // while SigNewList
+ SigItem = (EFI_SIGNATURE_DATA *) ((UINT8 *) SigItem + SigList->SignatureSize);
+ } // for SigItem
+ SigDbSize -= SigList->SignatureListSize;
+ SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);
+ } // while SigList
+
+AVAR_TRACE((TRACE_ALWAYS,"DataSize Out: %d (0x%X)\n",*DataSize, *DataSize));
+ if(*DataSize==0)
+ return EFI_ALREADY_STARTED;
+
+AVAR_TRACE((TRACE_ALWAYS,"APPEND OK!\n"));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyVariable1
+//
+// Description:
+// Verify data payload with AuthInfo in EFI_CERT_TYPE_RSA2048_SHA256 type.
+// Follow the steps in UEFI2.2.
+// This function is called every time variable with
+// EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS attribute is
+// created, updated or deleted. This function does all necessary
+// authetication checks and based on the results returns Status.
+// Also it returns the Mc Hash of PublicKey from Variable's AuthInfo Hdr
+//
+// Input:
+// CHAR16 *VariableName Name of Variable to be found.
+// EFI_GUID *VendorGuid Variable vendor GUID.
+// IN UINT32 Attributes - Attributes of the Var
+// VOID **Data - pointer to data block within AutVar Data
+// UINTN *DataSize - size of data block
+// VOID *OldData - pointer to Existing in NVRAM data block
+// UINTN OldDataSize - size of data block
+// UINT64 ExtFlags.MonotonicCount - value of MC or TIME stamp
+// UINT8 ExtFlags.KeyHash[32] - pointer to memory, allocated by caller,
+// where Hash of Public Key will be returned.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyVariable1 (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+){
+ EFI_STATUS Status;
+
+ VOID *RealData;
+ EFI_VARIABLE_AUTHENTICATION *CertData;
+ EFI_CERT_BLOCK_RSA_2048_SHA256 *CertBlock;
+ UINT8 *PubKey, *PubKeyHash;
+ UINTN CertHdrSize;
+ UINTN Size;
+ BOOLEAN IsSigListVar;
+ BOOLEAN IsPk;
+
+ RealData = *Data;
+ Status = EFI_SUCCESS;
+ IsSigListVar = TRUE;
+ IsPk = FALSE;
+
+// must have Auth attribute to go deeper
+ if ((Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) == 0)
+ return EFI_INVALID_PARAMETER;
+
+ if(*DataSize < sizeof(EFI_VARIABLE_AUTHENTICATION))
+ return EFI_SECURITY_VIOLATION;
+
+// specific for EFI_VARIABLE_AUTHENTICATION mode variables
+//--->>>
+ CertData = (EFI_VARIABLE_AUTHENTICATION *) *Data;
+ CertBlock = (EFI_CERT_BLOCK_RSA_2048_SHA256*)&(CertData->AuthInfo.CertData);
+// SCT 2.3.1 TW Plugfest BUG with listing of a Cert Size in Cert->AuthInfo.Hdr.dwLength
+// 0x22b vs 0x230
+// CertHdrSize = AUTHINFO_SIZE(CertData);//(CertData->AuthInfo.Hdr.Hdr.dwLength + sizeof(CertData->MonotonicCount));
+ AVAR_TRACE((TRACE_ALWAYS,"VerifyVariable CertHdr Size 0x%x (expected(0x230)\n",AUTHINFO_SIZE(CertData)));
+
+ CertHdrSize = 0x230;
+
+ //
+ // wCertificateType should be WIN_CERT_TYPE_EFI_GUID.
+ // Cert type should be EFI_CERT_TYPE_RSA2048_SHA256.
+ //
+ if ((CertData->AuthInfo.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID) ||
+ guidcmp ((EFI_GUID*) &(CertData->AuthInfo.CertType), &gEfiCertTypeRsa2048Sha256Guid)
+ ) {
+ //
+ // Invalid AuthInfo type, return EFI_SECURITY_VIOLATION.
+ //
+ AVAR_TRACE((TRACE_ALWAYS,"VerifyVariable AuthHdr GUID test Fails\nWinCert_Type\nExpected %x\nReceived %x\nGUID\nExpected %g\nReceived %g\n",WIN_CERT_TYPE_EFI_GUID, CertData->AuthInfo.Hdr.wCertificateType, gEfiCertTypeRsa2048Sha256Guid, &(CertData->AuthInfo.CertType)));
+// SCT 2.3.1 TW Plugfest uses wrong GUID
+ return EFI_SECURITY_VIOLATION;
+ }
+
+ if(*DataSize < CertHdrSize)
+ {
+AVAR_TRACE((TRACE_ALWAYS,"VerifyVariable DataSize test fails: DataSize(%x) < AuthHdrSize (%x)\n", *DataSize, CertHdrSize));
+ return EFI_SECURITY_VIOLATION;
+ }
+ //
+ // Monotonic count check fail, suspicious replay attack, return EFI_SECURITY_VIOLATION.
+ //
+AVAR_TRACE((TRACE_ALWAYS,"Check MC:\nOld=%x\nNew=%x\n",ExtFlags->Mc, CertData->MonotonicCount));
+ if (((Attributes & EFI_VARIABLE_APPEND_WRITE) == 0) &&
+ (OldData && ExtFlags->Mc >= CertData->MonotonicCount)
+ ) {
+ AVAR_TRACE((TRACE_ALWAYS,"Failed\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+AVAR_TRACE((TRACE_ALWAYS,"Pass\n"));
+
+// AppendWrite: Only update Timestamp if New one is greater then current
+ if( (Attributes & EFI_VARIABLE_APPEND_WRITE) &&
+ (OldData && ExtFlags->Mc > CertData->MonotonicCount)
+ );
+ else
+ ExtFlags->Mc = CertData->MonotonicCount;
+ //
+ // Process PK, KEK, Sig db separately.
+ //
+ if (IsPkVar(VariableName, VendorGuid)){
+ IsPk = TRUE;
+ Status = ProcessVarWithPk (*Data, *DataSize, Attributes, TRUE);
+ } else if (IsKekVar(VariableName, VendorGuid)) {
+ Status = ProcessVarWithPk (*Data, *DataSize, Attributes, FALSE);
+ } else if (IsDbVar(VendorGuid)) {
+ Status = ProcessVarWithKek (*Data, *DataSize, Attributes);
+ // verify process db(x) with one of KEK keys or if not found within KEK - with PK
+ if (Status == EFI_SECURITY_VIOLATION)
+ Status = ProcessVarWithPk (*Data, *DataSize, Attributes, FALSE);
+ } else {
+ IsSigListVar = FALSE;
+ PubKey = &(CertBlock->PublicKey[0]);
+ PubKeyHash = &PublicKeyHashArray[0];
+ // Verify SelfSigned variable is signed with a valid Key
+ Status = VerifyDataPayload (*Data, *DataSize, PubKey);
+ if (!EFI_ERROR(Status)) {
+
+ Size = RSA2048_PUB_KEY_LEN;
+ Status = mDigitalSigProtocol->Hash(mDigitalSigProtocol,
+ &gEfiHashAlgorithmSha256Guid,
+ 1, &PubKey, (const UINTN*)&Size, PubKeyHash);
+
+ if (OldData && MemCmp(&ExtFlags->KeyHash[0], PubKeyHash, HASH_SHA256_LEN)){
+//AVAR_TRACE((TRACE_ALWAYS,"Self Signed MC Var Key Compare FAILED!\n"));
+ return EFI_SECURITY_VIOLATION;
+ }
+ // Setting key Hash for self signed variables
+ MemCpy(&ExtFlags->KeyHash[0], PubKeyHash, HASH_SHA256_LEN);
+ }
+ }
+ if (EFI_ERROR(Status))
+ return EFI_SECURITY_VIOLATION;
+
+ *DataSize = *DataSize - CertHdrSize;
+ *Data = (UINT8*)RealData + CertHdrSize;
+
+ if(IsSigListVar == TRUE) {
+
+ // Validate Signature List integrity
+ if(*DataSize && EFI_ERROR(ValidateSignatureList (*Data, *DataSize)))
+ return EFI_SECURITY_VIOLATION;
+ //
+ // If delete PK in user mode -> change to setup mode.
+ // If enroll PK in setup mode -> change to user mode.
+ //
+ if(IsPk) {
+ if (*DataSize == 0)
+ UpdatePlatformMode (SETUP_MODE);
+ else
+ UpdatePlatformMode (USER_MODE);
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyVariable
+//
+// Description:
+// This function is called every time variable with
+// EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS and
+// EFI_VARIABLE_AUTHENTICATED_TIME_BASED_ACCESS attributes
+// created, updated or deleted. This function does all necessary
+// authetication checks and based on the results returns Status.
+// Also it returns the Mc Hash of PublicKey from Variable's AuthInfo Hdr
+//
+// Input:
+// CHAR16 *VariableName Name of Variable to be found.
+// EFI_GUID *VendorGuid Variable vendor GUID.
+// IN UINT32 Attributes - Attributes of the Var
+// VOID **Data - pointer to data block within AutVar Data
+// UINTN *DataSize - size of data block
+// VOID *OldData - pointer to Existing in NVRAM data block
+// UINTN OldDataSize - size of data block
+// UINT64 ExtFlags.MonotonicCount - value of MC or TIME stamp
+// UINT8 ExtFlags.KeyHash[32] - pointer to memory, allocated by caller,
+// where Hash of Public Key will be returned.
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 *Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtSecFlags
+){
+ EFI_STATUS Status;
+ UINT32 AuthAttributes;
+ UINT64 OldMC;
+
+ Status = EFI_SUCCESS;
+ mCustomMode = 0;
+
+//AVAR_TRACE((TRACE_ALWAYS,"Var Name: %S, Attr=%X, Data=%X, Size=%d\n", VariableName, *Attributes, *Data, *DataSize));
+
+ // bypass Var R/O check when updating
+ // SetupMode and SecureBoot variables after changing of a PK
+ if(mSetupMode == SETUP_MODE) {
+// Faking presense of NV attribute for SetupMode in order to meet UEFI requirement
+// to display SetupMode state even in runtime (after exit boot services)
+// AuthAttributes = *Attributes & (~EFI_VARIABLE_NON_VOLATILE);
+// *Attributes = AuthAttributes;
+// *Attributes &= (UINT32)(~EFI_VARIABLE_NON_VOLATILE);
+ // Re-lock access to runtime protected vars
+ mSetupMode = USER_MODE;
+ return Status;//EFI_SUCCESS;
+ }
+
+ // existing reserved variables are RO!!!
+ if(OldData && OldDataSize && IsReservedVariableName(VariableName, VendorGuid))
+ return EFI_WRITE_PROTECTED;
+
+ AuthAttributes = ExtSecFlags->AuthFlags & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES;
+
+ while ((*Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES)
+ // Old Variable with no attributes can be erased after proper AuthHeader validation
+ // EIP88439: irrespective of SetupMode, only properly formatted Auth Variable can be erased
+ || (AuthAttributes)
+ ){
+ // get mPlatformMode
+ GetPlatformMode ();
+
+ // check if both attributes are set
+ if ((*Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES) ==
+ UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES
+ )
+ { Status = EFI_INVALID_PARAMETER; break;}
+
+#if USER_MODE_POLICY_OVERRIDE == 1
+ // ignore Variable Authentication rules while in Physical User Presence
+ mCustomMode = PhysicalUserPresent();
+ AVAR_TRACE((TRACE_ALWAYS,"Physical User %s\n",
+ (mCustomMode?"detected - suppress Variable Authentication":"not detected")));
+ if (mCustomMode) {
+ if(*DataSize==0 || *Data==NULL) {
+ if(IsPkVar(VariableName, VendorGuid))
+ UpdatePlatformMode(SETUP_MODE);
+
+ Status = EFI_SUCCESS;
+ break;
+ }
+ }
+#endif
+// Old - nonAuth, New - nonAuth - exit with EFI_SUCCESS
+// Old - nonAuth, New - Auth - Continue with new Auth attr
+// Old - Auth, New - nonAuth - if *Attribs=0 - Erase in progress if in SetupMode
+// else EFI_SECURITY_VIOLATION
+// Old - Auth, New - Auth - Continue if AuthAttr matching
+// else EFI_SECURITY_VIOLATION
+// OldVar AuthAttributes mismatch
+ if( AuthAttributes && *Attributes &&
+ !(AuthAttributes & (*Attributes & UEFI23_1_AUTHENTICATED_VARIABLE_ATTRIBUTES))
+ )
+ // Attribute mismatch
+ { Status = EFI_SECURITY_VIOLATION; break;}
+
+ // else in process of erasing or Setting AuthVar
+
+ AuthAttributes |= *Attributes;
+ OldMC = ExtSecFlags->Mc;
+
+ if(*DataSize==0 || *Data==NULL)
+ { Status = EFI_SECURITY_VIOLATION; break;}
+
+ if(!mDigitalSigProtocol)
+ { Status = EFI_UNSUPPORTED; break;}
+
+//AVAR_TRACE((TRACE_ALWAYS,"Verify AuthVar: %S, Attr=%X, Data=%X, Size=%d\n", VariableName, *Attributes, *Data, *DataSize));
+ if (AuthAttributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS)
+ Status = VerifyVariable2(VariableName, VendorGuid, AuthAttributes, Data, DataSize, OldData, OldDataSize, ExtSecFlags);
+ else
+ Status = VerifyVariable1(VariableName, VendorGuid, AuthAttributes, Data, DataSize, OldData, OldDataSize, ExtSecFlags);
+//AVAR_TRACE((TRACE_ALWAYS, "Exit - %r, Data - %X, Size %d, Attributes %x\n",Status, *Data, *DataSize, *Attributes));
+ if (EFI_ERROR(Status))
+ break;
+
+ // Find out if New Var is a Signature Db and the Sig already present in current Sig DB Variable
+ // bail out SetVar if present - nothing to change
+ Status = FindInSignatureDb(VendorGuid, *Attributes, *Data, DataSize, OldData, OldDataSize);
+ if (EFI_ERROR(Status)) {
+ // Only update the Timestamp if new Sig found in OldSig list
+ if(OldMC != ExtSecFlags->Mc)
+ {
+ *DataSize = 0;
+ Status = EFI_SUCCESS;
+
+ }
+ // else Variable not changed, abort the SetVar
+ }
+
+ break;
+ } // end while loop
+
+ return Status; // variable not changed
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.cif b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.cif
new file mode 100644
index 0000000..4bc04f6
--- /dev/null
+++ b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "NVRAM. Authenticated Variables"
+ category = ModulePart
+ LocalRoot = "Core\EM\SecurityPkg\AuthenticatedVariable\"
+ RefName = "AuthVariable"
+[files]
+"AuthVariable.sdl"
+"AuthVariable.mak"
+"AuthVariable.c"
+"Auth2Variable.c"
+"AuthVariable.h"
+<endComponent>
diff --git a/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.h b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.h
new file mode 100644
index 0000000..38a4cfa
--- /dev/null
+++ b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.h
@@ -0,0 +1,351 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/AuthVariable.h 17 3/09/15 4:27p Alexp $
+//
+// $Revision: 17 $
+//
+// $Date: 3/09/15 4:27p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/AuthVariable.h $
+//
+// 17 3/09/15 4:27p Alexp
+// Update year 2015 in the file header
+//
+// 16 2/08/13 5:15p Alexp
+// Optimized the code flow fro Auth2 Variables.
+//
+// 15 12/07/12 3:45p Alexp
+// define AVAR_TRACE macro
+//
+// 14 11/19/12 4:41p Alexp
+// Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+// across flash updates.
+// Move all secure boot Setup settings to a separate varstore variable.
+// Preserve var across re-flash
+//
+// 13 10/16/12 3:45p Alexp
+// Implemented R/O Variables support via fixed and OEM defined (eLink)
+// lists
+//
+// 12 8/27/12 10:42a Alexp
+// GetmSecureBootSupport():
+// Add input parameter SetupMode to control state of
+// Setup Flag:SecureBootSupport
+//
+// 11 2/27/12 6:52p Alexp
+// removed AuthenticatedVariableServiceInitialize()
+//
+// 10 2/03/12 9:56a Alexp
+// EIP#82122. WHCK "Secure Boot Manual Logo Test" fails
+// Fixed Append logic to process multiple sig data instances in a single
+// Signature List block
+// New logic will remove dupplicated certs and update new SigList header.
+//
+// 9 8/18/11 5:59p Alexp
+// renamed func SecureBootSupport()
+//
+// 8 8/18/11 4:53p Alexp
+// removed AuthVar mailbox
+//
+// 7 8/16/11 7:18p Alexp
+// added Mailbox variable AuthVarMAilbox to syncronize local state between
+// DXE and SMM AuthVariable services
+//
+// 6 8/05/11 3:12p Alexp
+// add mkime prototyte define
+//
+// 5 8/04/11 7:12p Alexp
+//
+// 4 6/30/11 4:02p Alexp
+// added Callback event on Setup Mode change request form Security Setup
+// Page.
+//
+// 3 6/24/11 7:04p Alexp
+// fixed ValidateSignatureList () logic. Added Certificate RSA2048 to
+// supported Signatures
+//
+// 2 6/23/11 6:19p Alexp
+// Added ValidateSigList() function
+//
+// 5 6/09/11 5:49p Alexp
+// add new parameter to ValidateSelfSigned - Operation.
+//
+// 4 6/02/11 5:52p Alexp
+// add ValidateSelfSigned certificates func definition
+//
+// 2 5/19/11 4:59p Alexp
+// Major code revamp to be able to handle of handling Secure vars in Setup
+// Mode
+// TBD: TimeBased certificates from Msft fail to process. Not compiled as
+// Authenticode format
+//
+// 4 3/31/11 6:28p Alexp
+// Add SHA256 to supported SignatureList
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AuthVariable.h Implement authentication services for the authenticated variable
+// service in UEFI2.2+
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _AUTHVARIABLE_H_
+#define _AUTHVARIABLE_H_
+
+#include <Efi.h>
+// All are EDKII defined headers
+#include "WinCertificate.h"
+#include "ImageAuthentication.h"
+#include <Protocol/Hash.h>
+
+#define HASH_SHA256_LEN sizeof(EFI_SHA256_HASH) // 32
+#define HASH_SHA1_LEN sizeof(EFI_SHA1_HASH)
+#define RSA2048_PUB_KEY_LEN DEFAULT_RSA_KEY_MODULUS_LEN // 256
+#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE RSA2048_PUB_KEY_LEN
+#define EFI_CERT_TYPE_RSA2048_SIZE RSA2048_PUB_KEY_LEN
+
+//
+// EFI_VARIABLE_AUTHENTICATION descriptor
+//
+// A authentication authentication method descriptor template
+// AuthInfo is a WIN_CERTIFICATE using the wCertificateType
+// WIN_CERTIFICATE_UEFI_GUID and the CertType
+// EFI_CERT_TYPE_RSA2048_SHA256.
+//
+#ifndef EFI_VARIABLE_AUTHENTICATION
+typedef struct {
+ UINT64 MonotonicCount;
+ WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION;
+#endif
+
+//
+// EFI_VARIABLE_AUTHENTICATION_2 descriptor
+//
+// A time-based authentication method descriptor template
+//
+#ifndef EFI_VARIABLE_AUTHENTICATION_2
+typedef struct {
+ EFI_TIME TimeStamp;
+ WIN_CERTIFICATE_UEFI_GUID AuthInfo;
+} EFI_VARIABLE_AUTHENTICATION_2;
+#endif
+
+///
+/// Size of AuthInfo prior to the data payload
+///
+#define AUTHINFO_SIZE(Cert) (((UINTN)(((EFI_VARIABLE_AUTHENTICATION *) Cert)->AuthInfo.Hdr.dwLength)) + sizeof(UINT64))
+#define AUTHINFO_2_SIZE(Cert) (((UINTN)(((EFI_VARIABLE_AUTHENTICATION_2 *) Cert)->AuthInfo.Hdr.dwLength)) + sizeof(EFI_TIME))
+
+#ifdef EFI_DEBUG
+#define AVAR_TRACE(Arguments) { if (!AVarRuntime) TRACE(Arguments); }
+#else
+#define AVAR_TRACE(Arguments)
+#endif
+
+
+typedef enum {
+ IsPkVarType = 0,
+ IsKekVarType,
+ IsDbVarType,
+ IsPrivateVarType
+} AUTHVAR_TYPE;
+
+VOID AuthVariableServiceInitSMM (VOID );
+VOID AuthVariableServiceInit ( VOID );
+
+EFI_STATUS VerifyVariable (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 *Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+ );
+
+EFI_STATUS FindInSignatureDb (
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID *Data,
+ IN UINTN *DataSize,
+ IN VOID *SigDB,
+ IN UINTN SigDBSize
+ );
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Variable Auth Hdr EFI_VARIABLE_AUTHENTICATION
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EFI_STATUS VerifyVariable1 (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+ );
+
+EFI_STATUS VerifyDataPayload (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN UINT8 *PubKey
+ );
+
+EFI_STATUS ProcessVarWithPk (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN UINT32 Attributes,
+ IN BOOLEAN IsPk
+ );
+
+EFI_STATUS ProcessVarWithKek (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ IN UINT32 Attributes
+ );
+
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Variable Auth Hdr EFI_VARIABLE_AUTHENTICATION_2
+//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+EFI_STATUS VerifyVariable2 (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID **Data,
+ IN UINTN *DataSize,
+ IN VOID *OldData,
+ IN UINTN OldDataSize,
+ IN OUT EXT_SEC_FLAGS *ExtFlags
+ );
+
+EFI_STATUS ValidateSelfSigned (
+ IN UINT8 *Pkcs7Cert,
+ IN UINTN Pkcs7Cert_len,
+ IN OUT UINT8 **pDigest,
+ IN OUT UINTN *Digest_len,
+ IN UINT8 Operation
+ );
+
+EFI_STATUS ConstructDataParameter (
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes,
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT8 *pDigest,
+ OUT UINTN *Digest_len,
+ IN UINT8 Mutex
+ );
+
+EFI_STATUS ProcessVarWithPk2 (
+ IN UINT8 *Pkcs7Cert,
+ IN UINTN Pkcs7Cert_len,
+ IN UINT8 *pDigest,
+ IN UINTN Digest_len
+ );
+
+EFI_STATUS ProcessVarWithKek2 (
+ IN UINT8 *Pkcs7Cert,
+ IN UINTN Pkcs7Cert_len,
+ IN UINT8 *pDigest,
+ IN UINTN Digest_len
+ );
+
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// Misc auxilary functions
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+INTN StrCmp16(CHAR16 *Dest, CHAR16 *Src);
+UINT32 StrSize16(CHAR16 *String);
+
+BOOLEAN IsPkVar(
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ );
+
+BOOLEAN IsKekVar(
+ IN CHAR16 *VariableName,
+ IN EFI_GUID *VendorGuid
+ );
+
+BOOLEAN IsDbVar(
+ IN EFI_GUID *VendorGuid
+ );
+
+EFI_STATUS GetPlatformMode (
+ VOID
+ );
+
+EFI_STATUS GetmSecureBootSupport (
+ UINT8
+ );
+
+VOID UpdatePlatformMode (
+ IN UINT8 Mode
+ );
+
+EFI_STATUS ValidateSignatureList (
+ IN VOID *Data,
+ IN UINTN DataSize
+);
+
+UINT64 mkLongTime (
+ EFI_TIME *TimeStamp
+);
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+// NVRAM module defined auxilary functions
+//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+EFI_STATUS FindVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID **Data
+ );
+
+EFI_STATUS DxeSetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ IN UINT32 Attributes, IN UINTN DataSize, IN VOID *Data
+);
+EFI_STATUS DxeGetVariable(
+ IN CHAR16 *VariableName, IN EFI_GUID *VendorGuid,
+ OUT UINT32 *Attributes OPTIONAL,
+ IN OUT UINTN *DataSize, OUT VOID *Data
+);
+
+#endif // _AUTHVARIABLE_H_
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.mak b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.mak
new file mode 100644
index 0000000..5633611
--- /dev/null
+++ b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.mak
@@ -0,0 +1,89 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/AuthVariable.mak 6 8/15/13 11:26a Alexp $
+#
+# $Revision: 6 $
+#
+# $Date: 8/15/13 11:26a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/AuthenticatedVariable_efi/AuthVariable.mak $
+#
+# 6 8/15/13 11:26a Alexp
+# Link AmyCryptoLib
+#
+# 5 11/19/12 4:41p Alexp
+# Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+# across flash updates.
+# Move all secure boot Setup settings to a separate varstore variable.
+# Preserve var across re-flash
+#
+# 4 10/16/12 3:45p Alexp
+# Implemented R/O Variables support via fixed and OEM defined (eLink)
+# lists
+#
+# 3 9/19/12 4:29p Alexp
+# New feature: add facility to link external Physical User Presence
+# detect hooks via eLink:PhysicalUserPresenceDetect
+#
+# 2 6/30/11 4:02p Alexp
+# added Callback event on Setup Mode change request form Security Setup
+# Page.
+#
+# 1 6/13/11 5:25p Alexp
+#
+# 2 5/11/11 1:03p Alexp
+# filled in file header text
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AuthVariable.mak
+#
+# Description:
+# Link Authenticated Variable extension to NVRAM driver
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+NvramDxeBin : $(BUILD_DIR)\$(NVRAM_DIR)\AUTHVARIABLE.obj $(BUILD_DIR)\$(NVRAM_DIR)\AUTH2VARIABLE.obj $(CRYPTOLIB)
+
+AuthVariable_INCLUDES= \
+ /I $(AuthVariable_DIR) \
+ /I $(SecureBoot_DIR) \
+ /I $(NVRAM_DIR)
+
+AuthVariable_LISTS= \
+ /D PHYSICAL_USER_PRESENCE_DETECT_LIST=$(PhysicalUserPresenceDetect) \
+ /D OEM_READONLY_VAR_LIST=$(OemReadOnlyVariableList)
+
+$(BUILD_DIR)\$(NVRAM_DIR)\AUTHVARIABLE.obj $(BUILD_DIR)\$(NVRAM_DIR)\AUTH2VARIABLE.obj: \
+ $(AuthVariable_DIR)\AUTHVARIABLE.c $(AuthVariable_DIR)\AUTH2VARIABLE.c
+ if not exist $(*D) mkdir $(*D)
+ $(CC) $(CFLAGS) $(AuthVariable_LISTS) $(AuthVariable_INCLUDES) /Fo$@ $(AuthVariable_DIR)\$(*B).c
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.sdl b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.sdl
new file mode 100644
index 0000000..e90eddc
--- /dev/null
+++ b/Core/EM/SecurityPkg/AuthenticatedVariable/AuthVariable.sdl
@@ -0,0 +1,44 @@
+TOKEN
+ Name = "AuthVariable_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AuthVariable support in Project"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "USER_MODE_POLICY_OVERRIDE"
+ Value = "1"
+ Help = "Ignore Variable Authentication rules until AuthVarLock(ready to boot) event\A back door for Administrative Users to modify Secure Variables from Key Management Setup Page"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "AuthVariable_DIR"
+ Help = "Path to AuthVariable Module in Project"
+End
+
+MODULE
+ Help = "Includes AuthVariable.mak to Project"
+ File = "AuthVariable.mak"
+End
+
+
+ELINK
+ Name = "PhysicalUserPresenceDetect"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "AuthVarAdminUserPresent,"
+ InvokeOrder = AfterParent
+ Parent = PhysicalUserPresenceDetect
+End
+
+ELINK
+ Name = "OemReadOnlyVariableList"
+ InvokeOrder = ReplaceParent
+End
diff --git a/Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.c b/Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.c
new file mode 100644
index 0000000..7593b20
--- /dev/null
+++ b/Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.c
@@ -0,0 +1,2431 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/ImageVerification_efi/DxeImageVerificationLib.c 79 6/22/15 6:26p Alexp $
+//
+// $Revision: 79 $
+//
+// $Date: 6/22/15 6:26p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/ImageVerification_efi/DxeImageVerificationLib.c $
+//
+// 79 6/22/15 6:26p Alexp
+// EIP219415
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UEFI PXE can launch unsigned images when
+// SecureBoot is enabled.
+// [RootCause] Image from PXE server gets cloned device path
+// from its parent network controller with PciIo protocol
+// and embedded PCI ROM attributes
+// [Solution] Add checking for unique path for embedded
+// Pci OpROMs to prevent non-OpROM images
+//
+// 77 5/14/15 9:49a Alexp
+// DxeImageVerificationHandler()
+// Modify certificate offset calculation to match EDKII version
+//
+// 76 3/09/15 4:24p Alexp
+// EIP192504: Prevent Built In EFI Shell boot option from being created in
+// BDS when Secure Boot is enabled
+// [Resolution]: Leave old logic to allow launching embedded shell
+// based on the token:LOAD_UNSIGNED_EMBEDDED_SHELL
+// enabled by default only in Debug mode
+// EIP197749: Need to authenticate images loaded from external FV
+// [Resolution] Add logic inside GetImageType() to detect images loaded
+// from external FV
+//
+// 75 5/29/14 8:52a Alexp
+// minor debug trace message change;
+//
+// 74 8/15/13 11:29a Alexp
+// EIP#118850: Implement support for Certificate Revocation Storage
+// reduction and Timestamp Support.
+// Link AmyCryptoLib to make use of os_mktime()
+//
+// 73 7/26/13 3:40p Alexp
+// 1. EIP118850: Integrate ECR1009 chnages for TimeStamp dbt processing
+// 2. Image policy settings are checked against the build time defaults.
+// Prevents un-authorized change to NVRAM policy settings
+// to lower security policy.
+//
+// 72 6/26/13 10:48a Alexp
+// EIP[125931]: Security review. Fix after follow up review.
+// UINT32 integer wrapping still occurs due to incorrect placement
+// of delimiting parentheses
+//
+// 70 6/25/13 7:21p Alexp
+// EIP:127292 Item#2. Add dependency on ENABLE_IMAGE_EXEC_POLICY_OVERRIDE
+// EIP:127292 Item#3 Only For deprecated Security protocol:
+// DxeImageVerificationHandler Returns Error if FileRead() is
+// unsuccessful
+//
+// 67 6/21/13 10:41a Alexp
+// EIP[125931]: Security review: HashPeImage does not validate certificate
+// table offset and size
+//
+// 66 5/21/13 4:05p Alexp
+// EIP:124444 Secure boot improvement for LoadImage call with NULL
+// DevicePath
+// EIP:122339 GetImageType() detect if PciOpROM image is loaded from
+// internal FV by
+// checking the corresponding PCI I/O instance for the embedded
+// attribute.
+//
+// 63 3/25/13 3:41p Alexp
+// 1. EIP:118243 add support for multi-signed PE Images
+// 2. Removed append image certificates to db from User Query dialog.
+//
+// 56 3/11/13 5:07p Alexp
+// IsSignatureFoundInDatabase(): fix method to calculate CertCount.
+// AddImageExeInfo(): code cleanup for cases when *Name is NULL
+// DxeImageVerificationHandler(): Optimized code to determine if PE image
+// is signed
+//
+// 55 3/09/13 4:31p Alexp
+// EIP114998: wrong cert size passed in PCR[7] calculation
+//
+// 54 12/19/12 10:28a Alexp
+// EIP[104046]: Hardened code per #2,3,4,5,6,7 of security review findings
+//
+//
+// 53 12/17/12 3:10p Alexp
+// code fixes according to "cppcheck" style & performance suggestions
+//
+// 52 12/06/12 7:31p Alexp
+// Update ImageAuthorization()
+//
+// 51 11/26/12 10:46a Alexp
+// replaced hardwired Var name L"SecureBootSetup" to generic Var define
+//
+// 50 11/19/12 4:42p Alexp
+// Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+// across flash updates.
+// Move all secure boot Setup settings to a separate varsore variable.
+// Preserve var across re-flash
+//
+// 49 11/09/12 4:32p Alexp
+// IsPkcsSignedDataVerifiedBySignatureList()
+// Fix CertData size - excude EFI_GUID size
+//
+// 48 10/17/12 3:03p Alexp
+// EIP[104046]: Findings from Security review on Aptio4 Image verification
+// Includes the fix for item #4:
+// HashPeImage returns TRUE even in error case
+//
+// 47 10/16/12 3:53p Alexp
+// EIP[104046]: Findings from Security review on Aptio4 Image verification
+// Includes the fix for item #7 from the list attached to the EIP
+//
+// 46 9/25/12 11:22a Alexp
+// removed ImageVerify simulation when system in SetupMode.
+//
+// 45 9/24/12 12:26p Alexp
+// fix code branch for WIN_CERT_TYPE_EFI_GUID certificates
+//
+// 44 9/19/12 4:07p Alexp
+// fix code branch to set action EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED
+//
+// 43 9/14/12 3:42p Alexp
+// Hardwire LoadFromFv to AlwaysEnable irrespective of SetupData
+//
+// 42 9/13/12 11:38a Alexp
+// Fix Bug in HashPeiImage.
+// Last step 16 in hashing of optional data structures after the
+// Certificate entry was missing
+//
+// 41 9/07/12 9:37a Alexp
+// 1. Set all global variables Static
+// 2. IsPkcsSignedDataVerifiedBySignatureList(). Compiler optimization for
+// "IsVerified = VerifyWinCertificateForPkcsSignedData(
+// &(PkcsCertData->Hdr));"
+// may not link the main code.
+// 3. Run Verify code when platform is in SetupMode and SecureBoot set to
+// Custom
+//
+// 39 9/05/12 5:42p Alexp
+// GetImageType() :
+// Change Device Path search criteria to match EDKII example:
+// check FV path first and then Block I/O
+//
+// 38 8/29/12 11:16a Alexp
+// Add definition for EFI_MAX_ADDRESS if it's not defined elsewhere in
+// included header files
+//
+// 37 8/28/12 4:21p Alexp
+// Restore dependencies on SecureBootMode->Custom Setup option
+//
+// 35 8/15/12 4:16p Alexp
+// IsPkcsSignedDataVerifiedBySignatureList()
+// Fix bug prev version in processing multiple Certs from PE Hdr.
+//
+// 34 7/26/12 3:54p Alexp
+// Query User -> Append Certificate only available in Setup Mode.
+//
+// 33 7/25/12 6:45p Alexp
+// 1. Update ImageVerification logic to the latest EDK2 patch (13469)
+// Add support for multiple Signatures within PE/COFF table
+// Additional Header validation checks
+// 2. Add code flow when SecureBoot set to Custom mode.
+// Image Verification is performed but failing images are allowed to
+// run
+// Use this mode to append image certificates to DB in User Query mode.
+//
+// 32 6/11/12 3:15p Alexp
+// use modified WIN_CERTIFICATE_UEFI_GUID_1 struc in
+// AppendEfiImageSecurityDatabaseVariableEx()
+// moded struc is shorter by 4 bytes
+//
+// 30 5/18/12 9:21a Alexp
+// Fine tune User Query messages. Only display the messages if Admin user
+// has signed in
+//
+// 29 5/01/12 4:43p Alexp
+// PCR[7] - mTrustSigDbOffs contains offset to SigData struct within SigDb
+//
+// 28 4/27/12 3:57p Alexp
+// Fix Certificate type in AppendEfiImageSecurityDatabaseVariableEx()
+//
+// 27 4/23/12 5:19p Alexp
+// EIP:80874 Made changes to support PCR[7] measurments for Secure Boot
+// state in TCG
+// Install "Efi Boot Image Certificate" info strusture on Efi System
+// Table.
+//
+// 26 4/20/12 5:14p Alexp
+// Add new function to install the handle on Efi System Table with the
+// location
+// within DB variable of the Trusted Certificate that was used to verify
+// signature of Efi OS BootLoader image.
+//
+// 25 4/10/12 6:52p Alexp
+// Update VerifyCertPkcsSignedData() to support extended search in
+// Forbidded db for any leaf certificate, not only Root CA
+//
+// 23 4/03/12 7:35p Alexp
+// Move ReadImage() under legacy SecureFileAuthentication()
+//
+// 22 4/02/12 4:24p Alexp
+// Installs EFI_SECURITY2_ARCH_PROTOCOL.
+// Input arguments include File Path and pointer to a File buffer in
+// memory.
+//
+// 20 3/20/12 10:51a Alexp
+// 1. fix in AppendEfiImageSecurityDatabaseVariableEx()
+// 2. removed unused global vars
+//
+// 18 3/16/12 10:29a Alexp
+// [EIP85500] Build problem with (INT)4.6.5.1_SECUREBOOT_WIN8_11
+// move "extern EFI_GUID BdsConnectDriversProtocolGuid " outside of #ifdef
+// scope
+//
+// 17 3/13/12 2:41p Alexp
+// Add check for Admin signed credentials while allowing User Querry
+// policy
+//
+// 16 3/12/12 3:01p Alexp
+// 1. Deffer image verification till BdsConnectDriversProtocol event.
+// Speeds up the boot time.
+// 2. Enforce default (hardwired by SDL token) image veriication policy
+// for image device path if SecureBootMode is set to Standard.
+//
+// 15 3/09/12 3:39p Alexp
+// 1. Fixed Image authentication by Hash certificate in "db"
+// 2. Add User interructive controls to append image certificate to Sig
+// "db" (test implementation, will change in later releases)
+//
+// 14 2/27/12 6:47p Alexp
+// Reduce time spent in the DxeImageVerificationHandler function during
+// non-Secure Boot mode. Original code caused additional 0.5 sec to boot
+// time.
+// Note: internal SecureBoot mode flag once registered during
+// initializaton - will not change until restart.
+//
+// 13 1/04/12 3:27p Alexp
+// Fixed possible security risk:
+// GetImageType(). Block I/O Device Path check made higher priority then
+// of FV device path.
+//
+// 12 12/29/11 6:49p Alexp
+// GetImageType() - Fix for Image Device Path resolution
+// Added SubType = MEDIA_FV_FILEPATH_DP to search options for
+// MEDIA_DEVICE_PATH.
+// It appears SmmDriverDispatcher sets this device path for files loaded
+// by SmmDispatcher.
+//
+// 11 12/23/11 8:59a Alexp
+// Bug fix:
+// EIP:78978:Secure boot will hang at CP 0x72
+// ConOut & ConIn are not available until later in BDS phase, earlier
+// calls to display User Prompt may hang the system
+//
+// 10 12/07/11 7:23p Alexp
+// Bug fix:
+// EIP:77088 SecureBoot: Image can be loaded if click "No" when query
+// user after image verification failed
+// ImageAuthorization() -> Return EFI_ACCESS_DENIED of User Override
+// option
+//
+// 9 8/22/11 11:14a Alexp
+// optimizations to GetImageType()
+//
+// 6 7/18/11 4:12p Alexp
+// EIP:65085. LoadImage Error status is different When Secure Boot is ON
+// EIP:65194: No way to control the Secure Boot module to not interact
+// with the USER without changing the code
+//
+// 4 6/23/11 9:27a Alexp
+// moved mDigitalSig Protocol check up before API may be called
+//
+// 3 6/22/11 5:45p Alexp
+// draft change: add Sha256 as valid cert for "db" databases
+//
+// 2 6/13/11 7:21p Alexp
+// fix Hash calculation for Sha256 Certs in Forbidden database dbx
+//
+// 10 5/17/11 5:36p Alexp
+// update conOut messages
+//
+// 9 5/17/11 12:50p Alexp
+// replace AmiPostManager with pST->ConOut
+// use pBS instead of gBS
+//
+// 6 5/13/11 4:02p Alexp
+// 1. add dependency on Core rev. 4.6.5+ to buld for older Aptio cores
+// 2. Ignore Querry User policy for internal FV files
+//
+//**********************************************************************
+/*++
+ This file contains an 'Intel Peripheral Driver' and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+--*/
+/** @file
+
+ Implement image verification services for secure boot
+ service in UEFI2.2.
+
+ Caution: This file requires additional review when modified.
+ This library will have external input - PE/COFF image.
+ This external input must be validated carefully to avoid security issue like
+ buffer overflow, integer overflow.
+
+ DxeImageVerificationLibImageRead() function will make sure the PE/COFF image content
+ read is within the image buffer.
+
+ DxeImageVerificationHandler(), HashPeImageByType(), HashPeImage() function will accept
+ untrusted PE/COFF image and validate its data structure within this image buffer before use.
+
+Copyright (c) 2009 - 2012, Intel Corporation. All rights reserved.<BR>
+
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+**/
+
+#pragma warning (disable : 4090)
+
+#include <Token.h>
+#include <Protocol/Security.h>
+#include "DxeImageVerificationLib.h"
+#include "EfiImage.h"
+#include <AmiDxeLib.h>
+#include<Guid/PeiPeCoffLoader.h>
+#include <Protocol/AmiDigitalSignature.h>
+#include <AmiCertificate.h>
+#include <Setup.h>
+#include <SecureBootMod.h>
+#include <Protocol/PciIo.h> //EIP 122339
+#include <cryptlib.h>
+
+extern EFI_GUID BdsConnectDriversProtocolGuid;
+
+// 4.6.5.4
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028e
+#include <Protocol/Security2.h>
+#endif
+
+// 4.6.5.1
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+#include <EdkIICommon.h>
+#else
+#include <Tiano.h>
+
+//********tmp declaration from EdkIICommon.h
+#define MEDIA_RELATIVE_OFFSET_RANGE_DP 0x08
+
+extern VOID ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Size
+);
+VOID* CopyMem (
+ OUT VOID *DestinationBuffer,
+ IN VOID *SourceBuffer,
+ IN UINTN Length
+);
+#endif
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetImageInfo (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+#include <Protocol/SimpleTextIn.h>
+#include <Protocol/SimpleTextOut.h>
+
+#define AMI_MEDIA_DEVICE_PATH_GUID \
+ { 0x5023b95c, 0xdb26, 0x429b, 0xa6, 0x48, 0xbd, 0x47, 0x66, 0x4c, 0x80, 0x12 }
+
+#define STANDARD_SECURE_BOOT 0
+#define CUSTOM_SECURE_BOOT 1
+
+static EFI_GUID AmiMediaDevicePathGuid = AMI_MEDIA_DEVICE_PATH_GUID;
+static EFI_GUID gSecureSetupGuid = SECURITY_FORM_SET_GUID;
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+static AMI_DIGITAL_SIGNATURE_PROTOCOL *mDigitalSigProtocol = NULL;
+//
+// Caution: This is used by a function which may receive untrusted input.
+// These global variables hold PE/COFF image data, and they should be validated before use.
+//
+EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION mNtHeader;
+static UINT8 *mImageBase = NULL;
+static UINTN mImageSize;
+static EFI_GUID *mCertType;
+static UINT32 mPeCoffHeaderOffset;
+static UINT8 mImageDigest[MAX_DIGEST_SIZE];
+static UINTN mImageDigestSize;
+static SECURE_BOOT_SETUP_VAR mSecureBootSetup;
+static UINT8 mSecureBootEnable = 0;
+static UINTN mFvHandlesCount = 0;
+static EFI_HANDLE *mFvHandles = NULL;
+static BOOLEAN gImageLoadingAfterBDS = FALSE;
+
+//
+// Notify string for authorization UI.
+//
+CHAR16 mNotifyString1[MAX_NOTIFY_STRING_LEN] = L"\r\nImage verification failed!\r\n";
+CHAR16 mNotifyString2[MAX_NOTIFY_STRING_LEN] = L"\r\nLaunch this image anyway? (Y/N)";
+CHAR16 mNotifyString3[MAX_NOTIFY_STRING_LEN] = L"Image Certificate not found in Authorized database(db)!";
+CHAR16 mNotifyString4[MAX_NOTIFY_STRING_LEN] = L"Image Certificate is found in Forbidden database(dbx)!";
+CHAR16 mNotifyString5[MAX_NOTIFY_STRING_LEN] = L"Image is unsigned or Certificate is invalid!";
+
+//6683D10C-CF6E-4914-B5B4-AB8ED7370ED7
+EFI_GUID gBootImageCertTblGuid = AMI_VALID_BOOT_IMAGE_CERT_TBL_GUID;
+static UINT32 mTrustSigDbOffs = 0;
+static UINT32 mTrustSigDbSize = 0;
+
+//---------------------------------------
+// NEW TIME STAMP definitions ECR#1009
+//---------------------------------------
+extern EFI_GUID gEfiCertX509Sha256Guid;
+extern EFI_GUID gEfiCertX509Sha384Guid;
+extern EFI_GUID gEfiCertX509Sha512Guid;
+static INT32 mTimeOfSigningLong;
+typedef enum {
+ CertUndefined,
+ CertSha256,
+ CertX509,
+ CertX509Sha256,
+ CertX509Sha384,
+ CertX509Sha512,
+} nCertType;
+//---------------------------------------
+// NEW TIME STAMP definitions ECR#1009
+//---------------------------------------
+
+//************TEMP UTILITY FUNCTIONS. Use EDKII common wrapper lib instead****************
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+#else
+UINTN StrSize (
+ IN CHAR16 *String)
+{
+ UINTN Size;
+
+ for (Size = 2; *String != L'\0'; String++, Size += 2);
+
+ return Size;
+}
+#endif
+
+VOID* GetEfiGlobalVariableEx (
+ IN CHAR16 *Name,
+ IN OUT UINTN *VarSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *Var=NULL;
+
+ Status = GetEfiVariable(Name, &gEfiGlobalVariableGuid, NULL, VarSize, &Var);
+ return (EFI_ERROR(Status)) ? NULL : Var;
+}
+
+VOID* GetEfiImageSecurityDatabaseVariableEx (
+ IN CHAR16 *Name,
+ IN OUT UINTN *VarSize
+ )
+{
+ EFI_STATUS Status;
+ VOID *Var = NULL;
+
+ Status = GetEfiVariable(Name, &gEfiImageSecurityDatabaseGuid, NULL, VarSize, &Var);
+ return (EFI_ERROR(Status)) ? NULL : Var;
+}
+
+/**
+ Reads contents of a PE/COFF image in memory buffer.
+
+ Caution: This function may receive untrusted input.
+ PE/COFF image is external input, so this function will make sure the PE/COFF image content
+ read is within the image buffer.
+
+ @param FileHandle Pointer to the file handle to read the PE/COFF image.
+ @param FileOffset Offset into the PE/COFF image to begin the read operation.
+ @param ReadSize On input, the size in bytes of the requested read operation.
+ On output, the number of bytes actually read.
+ @param Buffer Output buffer that contains the data read from the PE/COFF image.
+
+ @retval EFI_SUCCESS The specified portion of the PE/COFF image was read and the size
+**/
+EFI_STATUS
+EFIAPI
+DxeImageVerificationLibImageRead (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ )
+{
+
+ if (FileHandle == NULL || ReadSize == NULL || Buffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((EFI_MAX_ADDRESS - FileOffset) < *ReadSize) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (((UINT64)FileOffset + *ReadSize) > mImageSize) {
+// *ReadSize = (UINT32)(mImageSize - FileOffset);
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (FileOffset >= mImageSize) {
+// *ReadSize = 0;
+ return EFI_INVALID_PARAMETER;
+ }
+
+ CopyMem (Buffer, (UINT8 *)((UINTN) FileHandle + FileOffset), *ReadSize);
+
+ return EFI_SUCCESS;
+}
+
+
+/**
+ Get the image type.
+
+ @param[in] File This is a pointer to the device path of the file that is
+ being dispatched.
+
+ @return UINT32 Image Type
+
+**/
+UINT32
+GetImageType (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *File
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE DeviceHandle;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ UINT8 nDevicePathSubType;
+ //EIP 122339 Start
+ EFI_PCI_IO_PROTOCOL *PciIoInterface = NULL;
+ UINT64 AttributesResult;
+ //EIP 122339 Stop
+ UINTN Index;
+ BOOLEAN IsFv = FALSE;
+
+ // Unknown device path: image security policy is applied to the image with the least trusted origin.
+ if (File == NULL) {
+ return IMAGE_UNKNOWN;
+ }
+
+ //
+ // Check if File is just a Firmware Volume.
+ //
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
+ while (!IsDevicePathEndType(TempDevicePath)){
+ nDevicePathSubType = DevicePathSubType (TempDevicePath);
+ TRACE((TRACE_ALWAYS,"Device PathType %x, SubType %x\n", DevicePathType(TempDevicePath), nDevicePathSubType ));
+ //
+ // EFI Specification extension on Media Device Path. MEDIA_FW_VOL_FILEPATH_DEVICE_PATH is adopted by UEFI later and added in UEFI2.10.
+ // In EdkCompatibility Package, we only support MEDIA_FW_VOL_FILEPATH_DEVICE_PATH that complies with EFI 1.10 and UEFI 2.10.
+ //
+ if( (DevicePathType(TempDevicePath) == MEDIA_DEVICE_PATH && nDevicePathSubType == MEDIA_FV_FILEPATH_DP) ||
+ (DevicePathType(TempDevicePath) == HARDWARE_DEVICE_PATH && nDevicePathSubType == HW_MEMMAP_DP)
+ ){
+ IsFv = TRUE;
+ } else {
+ IsFv = FALSE;
+ break;
+ }
+ TempDevicePath = NextDevicePathNode(TempDevicePath);
+ }
+
+ //
+ // Check to see if a File or a FV is from internal Firmware Volume.
+ //
+ if(IsFv) {
+
+ DeviceHandle = NULL;
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
+ Status = pBS->LocateDevicePath (
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ &TempDevicePath,
+ &DeviceHandle
+ );
+
+ if (!EFI_ERROR (Status)) {
+ if(!gImageLoadingAfterBDS)
+ return IMAGE_FROM_FV;
+
+ Status = pBS->OpenProtocol (
+ DeviceHandle,
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+#else
+ &gEfiFirmwareVolume2ProtocolGuid,
+#endif
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ for(Index=0;Index < mFvHandlesCount;Index++){
+ TRACE((TRACE_ALWAYS,"FV%02d. DeviceHandle %X=%X\n", Index, DeviceHandle, mFvHandles[Index] ));
+ if(DeviceHandle == mFvHandles[Index] )
+ return IMAGE_FROM_FV;
+ }
+ }
+ }
+ return IMAGE_UNKNOWN;
+ }
+ //
+ // Next check to see if File is from a Block I/O device
+ // Must be a Block I/O device since we reached here after Int FV path check
+ //
+ DeviceHandle = NULL;
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
+ Status = pBS->LocateDevicePath (
+ &gEfiBlockIoProtocolGuid,
+ &TempDevicePath,
+ &DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ BlockIo = NULL;
+ Status = pBS->OpenProtocol (
+ DeviceHandle,
+ &gEfiBlockIoProtocolGuid,
+ (VOID **) &BlockIo,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status) && BlockIo != NULL) {
+ if (BlockIo->Media != NULL) {
+ if (BlockIo->Media->RemovableMedia) {
+ //
+ // Block I/O is present and specifies the media is removable
+ //
+ return IMAGE_FROM_REMOVABLE_MEDIA;
+ } else {
+ //
+ // Block I/O is present and specifies the media is not removable
+ //
+ return IMAGE_FROM_FIXED_MEDIA;
+ }
+ }
+ }
+ }
+ //
+ // File is not in a Firmware Volume or on a Block I/O device, so check to see if
+ // the device path supports the Simple File System Protocol.
+ //
+ DeviceHandle = NULL;
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
+ Status = pBS->LocateDevicePath (
+ &gEfiSimpleFileSystemProtocolGuid,
+ &TempDevicePath,
+ &DeviceHandle
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Simple File System is present without Block I/O, so assume media is fixed.
+ //
+ return IMAGE_FROM_FIXED_MEDIA;
+ }
+
+ //
+ // File is not from an FV, Block I/O or Simple File System, so the only options
+ // left are a PCI Option ROM and a Load File Protocol such as a PXE Boot from a NIC.
+ //
+ TempDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)File;
+ while (!IsDevicePathEndType (TempDevicePath)) {
+ nDevicePathSubType = DevicePathSubType (TempDevicePath);
+ switch (DevicePathType (TempDevicePath)) {
+ //EIP 219415 Start
+ //Embedded OpROM
+ case HARDWARE_DEVICE_PATH:
+
+ if(nDevicePathSubType == HW_MEMMAP_DP) {
+ //EIP 122339 Start: Return IMAGE_FROM_FV if the EFI_PCI_IO_PROTOCOL installed
+ //on the same handle as the Device Path has the attribute EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM
+ DeviceHandle = NULL;
+ //
+ // Check if an instance of the EFI_PCI_IO_PROTOCOL is installed on the same handle
+ // as the Device Path. If an instance is found WorkAroundDevHandle contains the
+ // handle for the Device Path and EFI_PCI_IO_PROTOCOL instance.
+ //
+ Status = pBS->LocateDevicePath(
+ &gEfiPciIoProtocolGuid,
+ &File,
+ &DeviceHandle
+ );
+ if(EFI_ERROR(Status)) break;
+
+ Status = pBS->HandleProtocol(
+ DeviceHandle,
+ &gEfiPciIoProtocolGuid,
+ &PciIoInterface
+ );
+
+ if(EFI_ERROR(Status)) break;
+
+ //
+ // Using the EFI_PCI_IO_PROTOCOL get the value of the PCI controller's
+ // Embedded Rom attribute (EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM)
+ //
+ Status = PciIoInterface->Attributes(
+ PciIoInterface,
+ EfiPciIoAttributeOperationGet,
+ 0, //this parameter is ignored during Get operation
+ &AttributesResult
+ );
+ if(EFI_ERROR(Status)) break;
+ //
+ // Check if the PCI controller's EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM is set
+ //
+ if(AttributesResult & EFI_PCI_IO_ATTRIBUTE_EMBEDDED_ROM)
+ return IMAGE_FROM_FV;
+ //EIP 122339 Stop
+ }
+ break;
+ //EIP 219415 end
+ case MEDIA_DEVICE_PATH:
+
+ if (nDevicePathSubType == MEDIA_RELATIVE_OFFSET_RANGE_DP) {
+ return IMAGE_FROM_OPTION_ROM;
+ }
+#if LOAD_UNSIGNED_EMBEDDED_SHELL == 1
+ // Case for embedded FV application such as Shell(check GUID. BootOptions.h)
+ if (nDevicePathSubType == MEDIA_VENDOR_DP &&
+ !guidcmp(&((VENDOR_DEVICE_PATH*)TempDevicePath)->Guid, &AmiMediaDevicePathGuid)) {
+ return IMAGE_FROM_FV;
+ }
+#endif
+ break;
+
+ case MESSAGING_DEVICE_PATH:
+
+ if (nDevicePathSubType == MSG_MAC_ADDR_DP) {
+ return IMAGE_FROM_REMOVABLE_MEDIA;
+ }
+ break;
+ }
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ return IMAGE_UNKNOWN;
+}
+
+/**
+ Caculate hash of Pe/Coff image based on the authenticode image hashing in
+ PE/COFF Specification 8.0 Appendix A
+
+ Caution: This function may receive untrusted input.
+ PE/COFF image is external input, so this function will validate its data structure
+ within this image buffer before use.
+
+ @param[in] HashAlg Hash algorithm type.
+
+ @retval TRUE Successfully hash image.
+ @retval FALSE Fail in hash image.
+
+**/
+BOOLEAN
+HashPeImage (
+ IN UINT32 HashAlg
+ )
+{
+ EFI_STATUS EfiStatus;
+ BOOLEAN Status;
+ UINT16 Magic;
+ EFI_IMAGE_SECTION_HEADER *Section;
+ UINT8 *HashBase;
+ UINTN HashSize;
+ UINTN SumOfBytesHashed;
+ EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ UINTN Index;
+ UINTN Pos;
+
+ const UINT8 *addr[MAX_ELEM_NUM]; // tbd. test if 20 elements is enough
+ UINTN num_elem, len[MAX_ELEM_NUM];
+ EFI_GUID *EfiHashAlgorithmGuid;
+
+ UINT32 CertSize;
+ UINT32 NumberOfRvaAndSizes;
+
+ SectionHeader = NULL;
+ Status = FALSE;
+ EfiStatus = EFI_SECURITY_VIOLATION;
+ num_elem = 0;
+ //
+ // Initialize context of hash.
+ //
+ ZeroMem (mImageDigest, MAX_DIGEST_SIZE);
+ if (HashAlg == HASHALG_SHA1) {
+ mImageDigestSize = SHA1_DIGEST_SIZE;
+ EfiHashAlgorithmGuid = &gEfiHashAlgorithmSha1Guid;
+ mCertType = &gEfiCertSha1Guid;
+ } else if (HashAlg == HASHALG_SHA256) {
+ mImageDigestSize = SHA256_DIGEST_SIZE;
+ EfiHashAlgorithmGuid = &gEfiHashAlgorithmSha256Guid;
+ mCertType = &gEfiCertSha256Guid;
+ } else {
+ return FALSE;
+ }
+
+ // 1. Load the image header into memory.
+
+ //
+ // Measuring PE/COFF Image Header;
+ // But CheckSum field and SECURITY data directory (certificate) are excluded
+ //
+ if (mNtHeader.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64 && mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
+ // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
+ // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
+ // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ //
+ // Get the magic value from the PE/COFF Optional Header
+ //
+ Magic = mNtHeader.Pe32->OptionalHeader.Magic;
+ }
+
+ //
+ // 3. Calculate the distance from the base of the image header to the image checksum address.
+ // 4. Hash the image header from its base to beginning of the image checksum.
+ //
+ HashBase = mImageBase;
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset.
+ //
+ HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.CheckSum) - HashBase);
+ NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ } else if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ //
+ // Use PE32+ offset.
+ //
+ HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.CheckSum) - HashBase);
+ NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ } else {
+ //
+ // Invalid header magic number.
+ //
+ TRACE((TRACE_ALWAYS,"Invalid header magic number.\n"));
+ goto Done;
+ }
+
+ if (HashSize != 0)
+ {
+ addr[num_elem] = HashBase;
+ len[num_elem++] = HashSize;
+ } else {
+//TRACE((TRACE_ALWAYS,"Hash1.%x\n", HashSize));
+ goto Done;}
+ //
+ // 5. Skip over the image checksum (it occupies a single ULONG).
+ //
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
+ //
+ // 6. Since there is no Cert Directory in optional header, hash everything
+ // from the end of the checksum to the end of image header.
+ //
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset.
+ //
+ HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
+ HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - mImageBase);
+ } else {
+ //
+ // Use PE32+ offset.
+ //
+ HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
+ HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - mImageBase);
+ }
+
+ if (HashSize != 0)
+ {
+ addr[num_elem] = HashBase;
+ len[num_elem++] = HashSize;
+ } else {
+//TRACE((TRACE_ALWAYS,"Hash2.%x\n", HashSize));
+ goto Done;}
+ } else {
+ //
+ // 7. Hash everything from the end of the checksum to the start of the Cert Directory.
+ //
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset.
+ //
+ HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.CheckSum + sizeof (UINT32);
+ HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
+ } else {
+ //
+ // Use PE32+ offset.
+ //
+ HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.CheckSum + sizeof (UINT32);
+ HashSize = (UINTN) ((UINT8 *) (&mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
+ }
+ if (HashSize != 0)
+ {
+ addr[num_elem] = HashBase;
+ len[num_elem++] = HashSize;
+ } else {
+//TRACE((TRACE_ALWAYS,"Hash3.%x\n", HashSize));
+ goto Done;}
+
+ //
+ // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
+ // 9. Hash everything from the end of the Cert Directory to the end of image header.
+ //
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset
+ //
+ HashBase = (UINT8 *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
+ HashSize = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - mImageBase);
+ } else {
+ //
+ // Use PE32+ offset.
+ //
+ HashBase = (UINT8 *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
+ HashSize = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders - (UINTN) (HashBase - mImageBase);
+ }
+ if (HashSize != 0)
+ {
+ addr[num_elem] = HashBase;
+ len[num_elem++] = HashSize;
+ } else {
+//TRACE((TRACE_ALWAYS,"Hash4.%x\n", HashSize));
+ goto Done;}
+ }
+
+ //
+ // 10. Set the SUM_OF_BYTES_HASHED to the size of the header.
+ //
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset.
+ //
+ SumOfBytesHashed = mNtHeader.Pe32->OptionalHeader.SizeOfHeaders;
+ } else {
+ //
+ // Use PE32+ offset
+ //
+ SumOfBytesHashed = mNtHeader.Pe32Plus->OptionalHeader.SizeOfHeaders;
+ }
+
+
+ Section = (EFI_IMAGE_SECTION_HEADER *) (
+ mImageBase +
+ mPeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ mNtHeader.Pe32->FileHeader.SizeOfOptionalHeader
+ );
+ //
+ // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
+ // structures in the image. The 'NumberOfSections' field of the image
+ // header indicates how big the table should be. Do not include any
+ // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
+ //
+// TRACE((TRACE_ALWAYS,"Num Sections = %x\n", mNtHeader.Pe32->FileHeader.NumberOfSections));
+
+// Security review [305408]: HashPeImage does not validate NumberOfSections field
+ Pos = sizeof (EFI_IMAGE_SECTION_HEADER) * mNtHeader.Pe32->FileHeader.NumberOfSections;
+ if(Pos > mImageSize)
+ goto Done;
+
+ EfiStatus = pBS->AllocatePool(EfiBootServicesData, Pos, &SectionHeader);
+ if (SectionHeader == NULL || EFI_ERROR(EfiStatus)) {
+//TRACE((TRACE_ALWAYS,"Hash4.\n"));
+ goto Done;
+
+ }
+ MemSet(SectionHeader, Pos, 0);
+ //
+ // 12. Using the 'PointerToRawData' in the referenced section headers as
+ // a key, arrange the elements in the table in ascending order. In other
+ // words, sort the section headers according to the disk-file offset of
+ // the section.
+ //
+ for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {
+ Pos = Index;
+
+ // Security review EIP[104046]:6. HashPeImage does not validate NumberOfSections field
+ if(((UINT64)Section + sizeof (EFI_IMAGE_SECTION_HEADER))> ((UINT64)mImageBase+mImageSize) )
+ goto Done;
+
+ while ((Pos > 0) && (Section->PointerToRawData < SectionHeader[Pos - 1].PointerToRawData)) {
+ CopyMem (&SectionHeader[Pos], &SectionHeader[Pos - 1], sizeof (EFI_IMAGE_SECTION_HEADER));
+ Pos--;
+ }
+ CopyMem (&SectionHeader[Pos], Section, sizeof (EFI_IMAGE_SECTION_HEADER));
+ Section += 1;
+ }
+
+ //
+ // 13. Walk through the sorted table, bring the corresponding section
+ // into memory, and hash the entire section (using the 'SizeOfRawData'
+ // field in the section header to determine the amount of data to hash).
+ // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
+ // 15. Repeat steps 13 and 14 for all the sections in the sorted table.
+ //
+ for (Index = 0; Index < mNtHeader.Pe32->FileHeader.NumberOfSections; Index++) {
+ Section = &SectionHeader[Index];
+ if (Section->SizeOfRawData == 0) {
+ continue;
+ }
+
+//TRACE((TRACE_ALWAYS,"Section->PointerToRawData = %x\nSection->SizeOfRawData = %x\nSumOfBytesHashed = %x\n",Section->PointerToRawData, Section->SizeOfRawData, SumOfBytesHashed+Section->SizeOfRawData));
+ // Security review EIP[104046]: 5.HashPeImage does not validate PointerToRawData and SizeOfRawData fields
+ if( ((UINT64)Section->PointerToRawData + Section->SizeOfRawData) > mImageSize )
+ goto Done;
+
+ HashBase = mImageBase + Section->PointerToRawData;
+ HashSize = (UINTN) Section->SizeOfRawData;
+
+ addr[num_elem] = HashBase;
+ len[num_elem++] = HashSize;
+ if(num_elem >= MAX_ELEM_NUM)
+// goto Done;
+ {
+TRACE((TRACE_ALWAYS,"MAX_ELEM_NUM.1 = %d\n", num_elem));
+ goto Done;}
+ // Security review EIP[125931]: HashPeImage does not validate certificate table offset and size
+ if (((UINT64)SumOfBytesHashed+HashSize) > mImageSize)
+ goto Done;
+
+ SumOfBytesHashed += HashSize;
+ }
+
+ //
+ // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
+ // data in the file that needs to be added to the hash. This data begins
+ // at file offset SUM_OF_BYTES_HASHED and its length is:
+ // FileSize - (CertDirectory->Size)
+ //
+//dbg
+//TRACE((TRACE_ALWAYS,"mImageSize > SumOfBytesHashed.\n%x > %x\n", mImageSize, SumOfBytesHashed));
+//dbg
+ if (mImageSize > SumOfBytesHashed) {
+
+ HashBase = mImageBase + SumOfBytesHashed;
+
+ if (NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
+ CertSize = 0;
+ } else {
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset.
+ //
+ CertSize = mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
+ } else {
+ //
+ // Use PE32+ offset.
+ //
+ CertSize = mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size;
+ }
+ }
+
+ if (mImageSize > ((UINT64)CertSize + SumOfBytesHashed)) {
+ HashSize = (UINTN) (mImageSize - CertSize - SumOfBytesHashed);
+
+//TRACE((TRACE_ALWAYS,"\nData beyond nSumOfBytesHashed\nBase = %x, Size = %x\n",SumOfBytesHashed, HashSize));
+
+ addr[num_elem] = HashBase;
+ len[num_elem++] = HashSize;
+ if(num_elem >= MAX_ELEM_NUM)
+// goto Done;
+ {
+TRACE((TRACE_ALWAYS,"MAX_ELEM_NUM.2=%d\n", num_elem));
+ goto Done;}
+
+ } else if (mImageSize < ((UINT64)CertSize + SumOfBytesHashed)) {
+TRACE((TRACE_ALWAYS,"mImageSize < CertSize + SumOfBytesHashed.\n%d < %d\n", mImageSize, CertSize + SumOfBytesHashed));
+ goto Done;
+ }
+ else
+ HashSize = 0;
+ // ??? HashBase += CertSize;
+//TRACE((TRACE_ALWAYS,"\nData beyond CertDir\nBase = %x, Size = %x\n",SumOfBytesHashed+HashSize+CertSize, mImageSize-(SumOfBytesHashed+HashSize+CertSize)));
+ }
+ EfiStatus = mDigitalSigProtocol->Hash(
+ mDigitalSigProtocol,
+ EfiHashAlgorithmGuid, num_elem, addr, len, (UINT8*)&mImageDigest);
+
+TRACE((TRACE_ALWAYS,"Found HashElements %d\nImageHash: [%2X],[%2X],..\n", num_elem, mImageDigest[0], mImageDigest[1]));
+
+ if(!EFI_ERROR(EfiStatus))
+ Status = TRUE;
+
+Done:
+
+ if (SectionHeader != NULL) {
+ pBS->FreePool (SectionHeader);
+ }
+ // Security review EIP[104046]: 4.HashPeImage returns TRUE even in error case
+ // Status = FALSE unless updated to TRUE in the final Hash step before "Done" label
+ return Status;
+}
+
+/**
+ Recognize the Hash algorithm in PE/COFF Authenticode and caculate hash of
+ Pe/Coff image based on the authenticode image hashing in PE/COFF Specification
+ 8.0 Appendix A
+
+ Caution: This function may receive untrusted input.
+ PE/COFF image is external input, so this function will validate its data structure
+ within this image buffer before use.
+
+ @param[in] AuthData Pointer to the Authenticode Signature retrieved from signed image.
+ @param[in] AuthDataSize Size of the Authenticode Signature in bytes.
+
+ @retval EFI_UNSUPPORTED Hash algorithm is not supported.
+ @retval EFI_SUCCESS Hash successfully.
+
+**/
+EFI_STATUS
+HashPeImageByType (
+ IN UINT8 *AuthData,
+ IN UINTN AuthDataSize
+ )
+{
+ EFI_STATUS Status;
+ UINT8 DigestAlgo;
+ UINT8 *pDigestAlgo;
+ UINTN Size;
+
+// get Digest Algorithm
+ Size = 0;
+ pDigestAlgo = (UINT8*)&DigestAlgo;
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ AuthData,
+ AuthDataSize,
+ NULL,
+ 0,
+ &pDigestAlgo, // returns DER Ptr to Sign Cert
+ &Size,
+ Pkcs7GetDigestAlgorithm,
+ LOCK
+ );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ switch(DigestAlgo) {
+ case SHA1:
+ if (!HashPeImage (HASHALG_SHA1)) {
+ Status = EFI_SECURITY_VIOLATION;
+ }
+ break;
+ case SHA256:
+ if (!HashPeImage (HASHALG_SHA256)) {
+ Status = EFI_SECURITY_VIOLATION;
+ }
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+
+ return Status;
+}
+
+/**
+ Returns the size of a given image execution info table in bytes.
+
+ This function returns the size, in bytes, of the image execution info table specified by
+ ImageExeInfoTable. If ImageExeInfoTable is NULL, then 0 is returned.
+
+ @param ImageExeInfoTable A pointer to a image execution info table structure.
+
+ @retval 0 If ImageExeInfoTable is NULL.
+ @retval Others The size of a image execution info table in bytes.
+
+**/
+UINTN
+GetImageExeInfoTableSize (
+ EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable
+ )
+{
+ UINTN Index;
+ EFI_IMAGE_EXECUTION_INFO *ImageExeInfoItem;
+ UINTN TotalSize;
+
+ if (ImageExeInfoTable == NULL) {
+ return 0;
+ }
+
+ ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) ImageExeInfoTable + sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE));
+ TotalSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);
+ for (Index = 0; Index < ImageExeInfoTable->NumberOfImages; Index++) {
+ TotalSize += ImageExeInfoItem->InfoSize;
+ ImageExeInfoItem = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) ImageExeInfoItem + ImageExeInfoItem->InfoSize);
+ }
+
+ return TotalSize;
+}
+
+/**
+ Create an Image Execution Information Table entry and add it to system configuration table.
+
+ @param[in] Action Describes the action taken by the firmware regarding this image.
+ @param[in] Name Input a null-terminated, user-friendly name.
+ @param[in] DevicePath Input device path pointer.
+ @param[in] Signature Input signature info in EFI_SIGNATURE_LIST data structure.
+ @param[in] SignatureSize Size of signature.
+
+**/
+VOID
+AddImageExeInfo (
+ IN EFI_IMAGE_EXECUTION_ACTION Action,
+ IN CHAR16 *Name OPTIONAL,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN EFI_SIGNATURE_LIST *Signature OPTIONAL,
+ IN UINTN SignatureSize
+ )
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_EXECUTION_INFO_TABLE *ImageExeInfoTable;
+ EFI_IMAGE_EXECUTION_INFO_TABLE *NewImageExeInfoTable;
+ EFI_IMAGE_EXECUTION_INFO *ImageExeInfoEntry;
+ UINTN ImageExeInfoTableSize;
+ UINTN NewImageExeInfoEntrySize;
+ UINTN NameStringLen;
+ UINTN DevicePathSize;
+
+ NewImageExeInfoTable = NULL;
+ ImageExeInfoEntry = NULL;
+ NameStringLen = sizeof (CHAR16);
+
+ if (DevicePath == NULL) {
+ return ;
+ }
+
+ if (Name != NULL) {
+ NameStringLen = StrSize (Name);
+ }
+
+ ImageExeInfoTable = GetEfiConfigurationTable(pST, &gEfiImageSecurityDatabaseGuid);
+ if (ImageExeInfoTable != NULL) {
+ //
+ // The table has been found!
+ // We must enlarge the table to accmodate the new exe info entry.
+ //
+ ImageExeInfoTableSize = GetImageExeInfoTableSize (ImageExeInfoTable);
+ } else {
+ //
+ // Not Found!
+ // We should create a new table to append to the configuration table.
+ //
+ ImageExeInfoTableSize = sizeof (EFI_IMAGE_EXECUTION_INFO_TABLE);
+ }
+
+ DevicePathSize = DPLength(DevicePath);
+ NewImageExeInfoEntrySize = sizeof (EFI_IMAGE_EXECUTION_INFO) + NameStringLen + DevicePathSize + SignatureSize;
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, ImageExeInfoTableSize + NewImageExeInfoEntrySize, &NewImageExeInfoTable);
+ if(EFI_ERROR(Status)) return;
+
+ if (ImageExeInfoTable != NULL) {
+ CopyMem (NewImageExeInfoTable, ImageExeInfoTable, ImageExeInfoTableSize);
+ } else {
+ NewImageExeInfoTable->NumberOfImages = 0;
+ }
+ NewImageExeInfoTable->NumberOfImages++;
+ ImageExeInfoEntry = (EFI_IMAGE_EXECUTION_INFO *) ((UINT8 *) NewImageExeInfoTable + ImageExeInfoTableSize);
+ //
+ // Update new item's infomation.
+ //
+ ImageExeInfoEntry->Action = Action;
+ ImageExeInfoEntry->InfoSize = (UINT32) NewImageExeInfoEntrySize;
+
+ if (Name != NULL) {
+ CopyMem ((UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32), Name, NameStringLen);
+ } else {
+ ZeroMem ((UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32), NameStringLen);
+ }
+ CopyMem (
+ (UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32) + NameStringLen,
+ DevicePath,
+ DevicePathSize
+ );
+ if (Signature != NULL) {
+ CopyMem (
+ (UINT8 *) &ImageExeInfoEntry->InfoSize + sizeof (UINT32) + NameStringLen + DevicePathSize,
+ Signature,
+ SignatureSize
+ );
+ }
+ //
+ // Update/replace the image execution table.
+ //
+ Status = pBS->InstallConfigurationTable (&gEfiImageSecurityDatabaseGuid, (VOID *) NewImageExeInfoTable);
+ ASSERT_EFI_ERROR (Status);
+ //
+ // Free Old table data!
+ //
+ if (ImageExeInfoTable != NULL) {
+ pBS->FreePool (ImageExeInfoTable);
+ }
+}
+
+/**
+ Create a Boot Image Certificate table entry and add it to system configuration table.
+
+ @param[in] Name Input a null-terminated, user-friendly name.
+ @param[in] DevicePath Input device path pointer.
+ @param[in] Signature Input signature info in EFI_SIGNATURE_LIST data structure.
+ @param[in] SignatureSize Size of signature.
+
+**/
+VOID
+AddBootImageCertInfo (
+ IN CHAR16 *Name OPTIONAL,
+ IN UINT32 SignatureOffs,
+ IN UINT32 SignatureSize
+ )
+{
+ EFI_STATUS Status;
+ AMI_VALID_CERT_IN_SIG_DB *BootImageCertInfoTable;
+ UINTN BootImageCertInfoTableSize;
+
+ if(SignatureOffs == 0 || SignatureSize == 0)
+ return;
+
+ BootImageCertInfoTable = GetEfiConfigurationTable(pST, &gBootImageCertTblGuid);
+ if (BootImageCertInfoTable == NULL) {
+ //
+ // Not Found!
+ // We should create a new table.
+ //
+ BootImageCertInfoTableSize = sizeof (AMI_VALID_CERT_IN_SIG_DB);
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, BootImageCertInfoTableSize, &BootImageCertInfoTable);
+ if(EFI_ERROR(Status)) return;
+ //
+ // Update/replace the image execution table.
+ //
+ Status = pBS->InstallConfigurationTable (&gBootImageCertTblGuid, (VOID *) BootImageCertInfoTable);
+ ASSERT_EFI_ERROR (Status);
+ TRACE((TRACE_ALWAYS,"Install BootImageCert Table ...%r\n", Status));
+ if (EFI_ERROR (Status)) return;
+ }
+ //
+ // Update Table's infomation.
+ //
+ BootImageCertInfoTable->SigOffset = SignatureOffs;
+ BootImageCertInfoTable->SigLength = SignatureSize;
+
+TRACE((TRACE_ALWAYS,"BootImage Cert in db\nOffset=%X\nLength=%X\n", BootImageCertInfoTable->SigOffset, BootImageCertInfoTable->SigLength));
+}
+
+/**
+ Discover if the UEFI image is authorized by user's policy setting.
+
+ @param[in] Policy Specify platform's policy setting.
+ @param[in] Action Image Validation status.
+
+ @retval EFI_ACCESS_DENIED Image is not allowed to run.
+ @retval EFI_SECURITY_VIOLATION Image is deferred.
+ @retval EFI_SUCCESS Image is authorized to run.
+
+**/
+EFI_STATUS
+ImageAuthorization (
+ IN UINT32 Policy,
+ IN UINT32 Action
+ )
+{
+ EFI_STATUS Status;
+ EFI_INPUT_KEY Key = {0,0};
+ UINTN Index;
+ BOOLEAN bQuery;
+
+ Status = EFI_ACCESS_DENIED;
+
+ switch (Policy) {
+
+ case QUERY_USER_ON_SECURITY_VIOLATION:
+ // Conditions to allow overwrite of Execution Policy:
+ // 1. Output Console available
+ if((pST->ConIn != NULL && pST->ConOut != NULL))
+ {
+ pST->ConOut->OutputString(pST->ConOut, mNotifyString1);
+ bQuery = TRUE;
+ switch(Action) {
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND: // not found in db
+ pST->ConOut->OutputString(pST->ConOut, mNotifyString3);
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND: // found in dbx
+ pST->ConOut->OutputString(pST->ConOut, mNotifyString4);
+ break;
+ case EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED:
+ case EFI_IMAGE_EXECUTION_AUTH_UNTESTED:
+ pST->ConOut->OutputString(pST->ConOut, mNotifyString5);
+ break;
+ default:
+ bQuery = FALSE;
+ break;
+ }
+ if(!bQuery) break;
+ //Wait for key
+ pST->ConOut->OutputString(pST->ConOut, mNotifyString2);
+Repeat:
+ pBS->WaitForEvent( 1, &pST->ConIn->WaitForKey, &Index );
+ Status = pST->ConIn->ReadKeyStroke( pST->ConIn, &Key );
+ if (!EFI_ERROR (Status)) {
+ if ((Key.UnicodeChar == L'y') || (Key.UnicodeChar == L'Y')) { //yes
+ Status = EFI_SUCCESS;
+ } else if ((Key.UnicodeChar == L'n') || (Key.UnicodeChar == L'N')) { //no
+ Status = EFI_ACCESS_DENIED;
+ } else {
+ goto Repeat;
+ }
+ }
+ pST->ConOut->OutputString(pST->ConOut, L"\r\n");
+ }
+ break;
+
+ case DEFER_EXECUTE_ON_SECURITY_VIOLATION:
+ Status = EFI_SECURITY_VIOLATION;
+ break;
+
+ // case DENY_EXECUTE_ON_SECURITY_VIOLATION:
+ default:
+ Status = EFI_ACCESS_DENIED;
+ break;
+ }
+
+TRACE((TRACE_ALWAYS,"Image Authorization policy...%r\n", Status));
+
+ return Status;
+}
+
+/**
+ Advanced check in Signature Database
+ Check whether signature is located in target database
+
+ @param[in] Signature Pointer to signature that is searched for.
+ @param[in] SignatureSize Size of Signature.
+ @param[in] SignatureType Type of the Certificate, Guid
+
+ @return TRUE - found in IsSigForbidden
+ @return FALSE
+
+**/
+BOOLEAN
+IsSignatureFoundInDatabase (
+ IN CHAR16 *Name,
+ EFI_GUID *SignatureType,
+ IN UINT8 *Signature,
+ IN UINTN SignatureSize
+ )
+{
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINT8 *Data;
+ UINTN DataSize;
+ UINTN Index;
+ UINTN CertCount;
+ BOOLEAN IsSigFound;
+
+ //
+ // Read signature database variable.
+ //
+ IsSigFound = FALSE;
+
+ //
+ // Get Signature Database variable.
+ //
+
+ Data = GetEfiImageSecurityDatabaseVariableEx (Name, &DataSize);
+
+ if (Data != NULL) {
+// not an error if no "dbx" defined
+ //
+ // Enumerate all signature data in SigDB to check if executable's signature exists.
+ //
+ CertList = (EFI_SIGNATURE_LIST *) Data;
+ while (!IsSigFound && (DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {
+ if (!guidcmp(&CertList->SignatureType, SignatureType)) { // Cert types do match
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ if (CertList->SignatureSize == (sizeof(EFI_SIGNATURE_DATA) - 1 + SignatureSize)) {
+ for (Index = 0; Index < CertCount; Index++) {
+ if (MemCmp(Cert->SignatureData, Signature, SignatureSize) == 0) {
+ //
+ // Find the signature in database.
+ //
+ IsSigFound = TRUE;
+ break;
+ }
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ }
+ }
+ } // next CertList
+ DataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ }
+ pBS->FreePool (Data);
+ }
+
+ return IsSigFound;
+}
+
+
+/**
+ Verify PKCS#7 SignedData using certificate found in Variable which formatted
+ as EFI_SIGNATURE_LIST. The Variable may be PK, KEK, DB or DBX.
+
+ @param VariableName Name of Variable to search for Certificate.
+
+ @retval TRUE Image pass verification.
+ @retval FALSE Image fail verification.
+
+**/
+BOOLEAN
+IsPkcsSignedDataVerifiedBySignatureList (
+ IN UINT8 *AuthData,
+ IN UINTN AuthDataSize,
+ IN CHAR16 *VariableName,
+ IN UINT8 Operation
+ )
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *CertList;
+ EFI_SIGNATURE_DATA *Cert;
+ UINT32 CertCount;
+ UINT32 Index;
+ UINT8 *Data;
+ UINTN DataSize;
+ UINT8 *RootCert;
+ UINTN RootCertSize;
+ UINT8 *SigCert;
+ UINTN SigCertSize;
+ BOOLEAN IsVerified;
+ EFI_TIME *TimeStamp;
+ INT32 TimeOfRevocationLong;
+ UINT8 ValidCertType;
+ BOOLEAN bVerifyTimeStampStatus;
+ BOOLEAN bProcessVerifyTimeStampStatus;
+
+ CertList = NULL;
+ Cert = NULL;
+ RootCert = NULL;
+ RootCertSize = 0;
+ IsVerified = FALSE;
+ ValidCertType = CertUndefined;
+ bVerifyTimeStampStatus= FALSE;
+ bProcessVerifyTimeStampStatus = FALSE;
+
+ mTimeOfSigningLong = 0;
+ TimeOfRevocationLong = 0;
+ // Verify the certificate's header
+ //
+ // Find certificate in store and verify authenticode struct.
+ //
+ Data = GetEfiImageSecurityDatabaseVariableEx (VariableName, &DataSize);
+
+ if (!Data)
+ return IsVerified;
+
+TRACE((TRACE_ALWAYS,"\nLook for a match in '%S'===>\n\n", VariableName));
+
+ CertList = (EFI_SIGNATURE_LIST *)Data;
+
+ //
+ // TO DO Optimization.
+ // 1. Find Root CA Cert Ptr or Signer Cert if Root is not found
+ // 2. loop thru Trust Cert list and compare each one against Root CA cert(verify SignCert signature with Trust Cert)
+ // 3. If found, break the 'while' loop and Pkcs7Verify with Trust Cert
+ //
+ //
+ // Find Cert Enrolled in database to verify the signature in pkcs7 signed data.
+ //
+ // here should be a loop thru Cert list till CertCount
+ while ((DataSize > 0) && (DataSize >= CertList->SignatureListSize)) {
+
+ if(!guidcmp(&CertList->SignatureType, &gEfiCertX509Guid))
+ ValidCertType = CertX509;
+ else
+ if(!guidcmp(&CertList->SignatureType, mCertType))
+ ValidCertType = CertSha256;
+ else
+ if(!guidcmp(&CertList->SignatureType, &gEfiCertX509Sha256Guid))
+ ValidCertType = CertX509Sha256;
+ else
+ if(!guidcmp(&CertList->SignatureType, &gEfiCertX509Sha384Guid))
+ ValidCertType = CertX509Sha384;
+ else
+ if(!guidcmp(&CertList->SignatureType, &gEfiCertX509Sha512Guid))
+ ValidCertType = CertX509Sha512;
+
+ if (ValidCertType)
+ {
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) CertList + sizeof (EFI_SIGNATURE_LIST) + CertList->SignatureHeaderSize);
+ CertCount = (CertList->SignatureListSize - sizeof (EFI_SIGNATURE_LIST) - CertList->SignatureHeaderSize) / CertList->SignatureSize;
+ RootCertSize = CertList->SignatureSize-sizeof(EFI_GUID); // sig data structure starts with SigOwner Guid
+TRACE((TRACE_ALWAYS,"Signature Type %g\nRootCertSize = %X\n",CertList->SignatureType, RootCertSize));
+
+ for (Index = 0; Index < CertCount; Index++) {
+ //
+ // Iterate each Signature Data Node within this CertList for verify.
+ //
+ RootCert = Cert->SignatureData;
+ switch(ValidCertType) {
+// is Sha256/Sha1
+ case CertSha256:
+ if(RootCertSize == mImageDigestSize &&
+ MemCmp(RootCert, mImageDigest, mImageDigestSize) == 0) {
+TRACE((TRACE_ALWAYS,"Hash Cert match found...\n"));
+ //
+ // Found the signature in database.
+ //
+ IsVerified = TRUE;
+ }
+ break;
+// x509, x509_ShaXXX
+/*
+Revocation is true:
+- return success && Time = 0
+- return success && Time != 0 && VerifyTimeStampStatus
+- success
+if success but mVerifyTimeStampStatus = ACCESS_DENIED = return FAIL
+timestamp non-0 Year > 0
+*/
+ case CertX509Sha256:
+ case CertX509Sha384:
+ case CertX509Sha512:
+ switch(ValidCertType) {
+ case CertX509Sha256:
+ TimeStamp = &((EFI_CERT_X509_SHA256*)RootCert)->TimeOfRevocation;
+ break;
+ case CertX509Sha384:
+ TimeStamp = &((EFI_CERT_X509_SHA384*)RootCert)->TimeOfRevocation;
+ break;
+ case CertX509Sha512:
+ TimeStamp = &((EFI_CERT_X509_SHA512*)RootCert)->TimeOfRevocation;
+ break;
+ }
+ // Check the timestamp cert validity the valid certificate in allowed database (dbt).
+ if(!bProcessVerifyTimeStampStatus) {
+ bVerifyTimeStampStatus = IsPkcsSignedDataVerifiedBySignatureList (AuthData, AuthDataSize, EFI_IMAGE_SECURITY_DATABASE2, Pkcs7TimeStampCertValidateGet);
+ bProcessVerifyTimeStampStatus = TRUE;
+ }
+ if(os_mktime(TimeStamp->Year, TimeStamp->Month, TimeStamp->Day, TimeStamp->Hour, TimeStamp->Minute, TimeStamp->Second,&TimeOfRevocationLong))
+ TimeOfRevocationLong = 0;
+TRACE((TRACE_ALWAYS,"\nTimeStamp cert validate %s\nTimeOfSigning %X\nTimeOfRevocation %X\n", (!bVerifyTimeStampStatus?"FAIL":"PASS"), mTimeOfSigningLong, TimeOfRevocationLong));
+ if(TimeOfRevocationLong) {
+ if(!bVerifyTimeStampStatus) {
+ IsVerified = TRUE; // found in dbx -> image is revoked!
+ break;
+ }
+ // keep looking for cert with sign time passed revocation
+ if(mTimeOfSigningLong < TimeOfRevocationLong)
+ break;
+ }
+ case CertX509:
+TRACE((TRACE_ALWAYS,"proceed with Pkcs7Verify...\n"));
+ //
+ //
+ // Verify Authenticode struct for image's current certificate.
+ //
+ // using protocol
+ SigCert = mImageDigest;
+ SigCertSize = mImageDigestSize;
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ AuthData,
+ AuthDataSize,
+ RootCert,
+ RootCertSize,
+ // mDigest, DigestLen
+ &SigCert,
+ &SigCertSize,
+ Operation, // Operation; Pkcs7CertValidate OR Pkcs7CertGetMatchInCertChain
+ KEEP // Flags
+ );
+TRACE((TRACE_ALWAYS,"====> %r\n", Status));
+ if (!EFI_ERROR(Status)) {
+ IsVerified = TRUE; // found matching certificate in the image
+ switch(Operation) {
+ case Pkcs7TimeStampCertValidateGet:
+ mTimeOfSigningLong = (INT32)SigCertSize;
+ break;
+ case Pkcs7CertValidate:
+ // only x509 certs frm db are measured in PCR[7]
+ mTrustSigDbOffs = (UINT32)(UINT8*)(((UINT8*)Cert-Data));
+ mTrustSigDbSize = CertList->SignatureSize;
+ break;
+ }
+ }
+ break;
+ default :
+ goto Exit;
+ } // switch
+ if (IsVerified)
+ {
+ goto Exit;
+ }
+ Cert = (EFI_SIGNATURE_DATA *) ((UINT8 *) Cert + CertList->SignatureSize);
+ } // end for
+ } // end If
+
+ DataSize -= CertList->SignatureListSize;
+ CertList = (EFI_SIGNATURE_LIST *) ((UINT8 *) CertList + CertList->SignatureListSize);
+ } // end while
+Exit:
+ pBS->FreePool (Data);
+TRACE((TRACE_ALWAYS,"\n<===%s cert match in '%S'\n",(IsVerified?"Got":"No"), VariableName));
+ return IsVerified;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeImageVerificationHandler
+//
+// Description: Handle for Security Architectural Protocol
+// Provide verification service for signed images, which include both signature validation
+// and platform policy control. For signature types, both UEFI WIN_CERTIFICATE_UEFI_GUID and
+// MSFT Authenticode type signatures are supported.
+//
+// In this implementation, only verify external executables when in USER MODE.
+// Executables from FV is bypass, so pass in AuthenticationStatus is ignored.
+//
+// The image verification policy is:
+// If the image is signed,
+// At least one valid signature or at least one hash value of the image must match a record
+// in the security database "db", and no valid signature nor any hash value of the image may
+// be reflected in the security database "dbx".
+// Otherwise, the image is not signed,
+// The SHA256 hash value of the image must match a record in the security database "db", and
+// not be reflected in the security data base "dbx".
+//
+// Caution: This function may receive untrusted input.
+// PE/COFF image is external input, so this function will validate its data structure
+// within this image buffer before use.
+//
+// Input:
+// File This is a pointer to the device path of the file that is
+// being dispatched. This will optionally be used for logging.
+// FileBuffer File buffer matches the input file device path.
+// FileSize Size of File buffer matches the input file device path.
+//
+// Output: EFI_STATUS
+//
+// EFI_SUCCESS The file specified by File did authenticate, and the
+// platform policy dictates that the DXE Core may use File.
+// EFI_INVALID_PARAMETER File is NULL.
+// EFI_SECURITY_VIOLATION The file specified by File did not authenticate, and
+// the platform policy dictates that File should be placed
+// in the untrusted state. A file may be promoted from
+// the untrusted to the trusted state at a future time
+// with a call to the Trust() DXE Service.
+// EFI_ACCESS_DENIED The file specified by File did not authenticate, and
+// the platform policy dictates that File should not be
+// used for any purpose.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DxeImageVerificationHandler (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *File,
+ IN VOID *FileBuffer,
+ IN UINTN FileSize,
+ IN BOOLEAN BootPolicy
+ )
+
+{
+ EFI_STATUS Status;
+ UINT16 Magic;
+ EFI_IMAGE_DOS_HEADER *DosHdr;
+ EFI_STATUS VerifyStatus;
+ EFI_SIGNATURE_LIST *SignatureList;
+ UINTN SignatureListSize;
+ EFI_SIGNATURE_DATA *Signature;
+ EFI_IMAGE_EXECUTION_ACTION Action;
+ WIN_CERTIFICATE *WinCertificate;
+ UINT32 Policy;
+ BOOLEAN bFileRead;
+
+ EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINT32 NumberOfRvaAndSizes;
+
+ WIN_CERTIFICATE_EFI_PKCS *PkcsCertData;
+ WIN_CERTIFICATE_UEFI_GUID *WinCertUefiGuid;
+ UINT8 *AuthData;
+ UINTN AuthDataSize;
+ EFI_IMAGE_DATA_DIRECTORY *SecDataDir;
+ UINT32 OffSet;
+
+
+ SignatureList = NULL;
+ SignatureListSize = 0;
+ WinCertificate = NULL;
+ SecDataDir = NULL;
+ PkcsCertData = NULL;
+ Action = EFI_IMAGE_EXECUTION_AUTH_UNTESTED;
+ VerifyStatus = EFI_ACCESS_DENIED;
+ Status = EFI_ACCESS_DENIED;
+ bFileRead = FALSE;
+
+ mImageDigestSize = 0;
+ mCertType = NULL;
+ //
+ // Check the image type and get policy setting.
+ //
+ switch (GetImageType (File)) {
+
+ case IMAGE_FROM_FV:
+ Policy = ALWAYS_EXECUTE;
+ break;
+
+ case IMAGE_FROM_OPTION_ROM:
+ Policy = mSecureBootSetup.Load_from_OROM;
+ break;
+
+ case IMAGE_FROM_REMOVABLE_MEDIA:
+ Policy = mSecureBootSetup.Load_from_REMOVABLE_MEDIA;
+ break;
+
+ case IMAGE_FROM_FIXED_MEDIA:
+ Policy = mSecureBootSetup.Load_from_FIXED_MEDIA;
+ break;
+
+ default:
+TRACE((TRACE_ALWAYS,"Unknown Image Path\n"));
+ Policy = DENY_EXECUTE_ON_SECURITY_VIOLATION;
+ break;
+ }
+
+ //
+ // If policy is always/never execute, return directly.
+ //
+ if (Policy == ALWAYS_EXECUTE) {
+ return EFI_SUCCESS;
+ } else
+ if (Policy == NEVER_EXECUTE) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (FileBuffer == NULL) {
+ //
+ // Read the PE/COFF file.
+ //
+ TRACE((TRACE_ALWAYS,"FileAuthentication\nFileType = %x, SubType = %x\n", File->Type, File->SubType));
+ Status = ReadImage(FALSE, File, &FileBuffer, &FileSize, NULL, NULL, NULL);
+ TRACE((TRACE_ALWAYS,"File read(1)...%r\n", Status));
+ if(EFI_ERROR(Status)) {
+ Status = ReadImage(TRUE, File, &FileBuffer, &FileSize, NULL, NULL, NULL);
+ TRACE((TRACE_ALWAYS,"File read(2)...%r\n", Status));
+ if(EFI_ERROR(Status))
+ return EFI_ACCESS_DENIED;
+ }
+
+ bFileRead = TRUE;
+ }
+ //
+ // Read the Dos header.
+ //
+ ASSERT (FileBuffer != NULL);
+ if (FileBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ mImageBase = (UINT8 *) FileBuffer;
+ mImageSize = FileSize;
+
+ ZeroMem (&ImageContext, sizeof (ImageContext));
+ ImageContext.Handle = (VOID *) FileBuffer;
+ ImageContext.ImageRead = (EFI_PEI_PE_COFF_LOADER_READ_FILE) DxeImageVerificationLibImageRead;
+
+ //
+ // Get information about the image being loaded
+ //
+ if (EFI_ERROR (PeCoffLoaderGetImageInfo (NULL, &ImageContext)) ||
+ ( mImageSize< sizeof(EFI_IMAGE_DOS_HEADER)) ) {
+ //
+ // The information can't be gotten from the invalid PeImage
+ //
+ TRACE((TRACE_ALWAYS,"PeCoffLoaderGetImageInfo Error\n"));
+ goto Done;
+ }
+
+ DosHdr = (EFI_IMAGE_DOS_HEADER *) mImageBase;
+ if (DosHdr->e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present,
+ // so read the PE header after the DOS image header.
+ //
+ mPeCoffHeaderOffset = DosHdr->e_lfanew;
+ } else {
+ mPeCoffHeaderOffset = 0;
+ }
+ // Security review EIP[104046]: 3.HashPeImage does not validate minimum image size
+ // Validate mPeCoffHeaderOffset is within the Image size range
+ if(((UINT64)mPeCoffHeaderOffset+sizeof(EFI_IMAGE_NT_HEADERS32)) > mImageSize) {
+ TRACE((TRACE_ALWAYS,"EFI_IMAGE_NT_SIGNATURE Error\n"));
+ goto Done;
+ }
+
+ //
+ // Check PE/COFF image.
+ //
+ mNtHeader.Pe32 = (EFI_IMAGE_NT_HEADERS32 *) (mImageBase + mPeCoffHeaderOffset);
+ if (mNtHeader.Pe32->Signature != EFI_IMAGE_NT_SIGNATURE) {
+ //
+ // It is not a valid Pe/Coff file.
+ //
+ TRACE((TRACE_ALWAYS,"EFI_IMAGE_NT_SIGNATURE Error\n"));
+ goto Done;
+ }
+
+ if (mNtHeader.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64 && mNtHeader.Pe32->OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // NOTE: Some versions of Linux ELILO for Itanium have an incorrect magic value
+ // in the PE/COFF Header. If the MachineType is Itanium(IA64) and the
+ // Magic value in the OptionalHeader is EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
+ // then override the magic value to EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
+ //
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ //
+ // Get the magic value from the PE/COFF Optional Header
+ //
+ Magic = mNtHeader.Pe32->OptionalHeader.Magic;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset.
+ //
+ NumberOfRvaAndSizes = mNtHeader.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
+ SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
+ }
+ } else {
+ //
+ // Use PE32+ offset.
+ //
+ NumberOfRvaAndSizes = mNtHeader.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_SECURITY) {
+ SecDataDir = (EFI_IMAGE_DATA_DIRECTORY *) &mNtHeader.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_SECURITY];
+ }
+ }
+
+ TRACE((TRACE_ALWAYS,"mImageSize %x\n", mImageSize));
+
+ //
+ // Start Image Validation.
+ //
+ if (SecDataDir && SecDataDir->Size) {
+ //
+ // Image is possibly signed
+ //
+ TRACE((TRACE_ALWAYS,"SecDataDir->VirtualAddress %x\nSecDataDir->Size = %x\nIMAGE is Signed\n",
+ SecDataDir->VirtualAddress, SecDataDir->Size));
+ // Security review EIP[104046]: 2.Multiple integer underflows calculating size of certificate data in PE file
+ if(((UINT64)SecDataDir->VirtualAddress+SecDataDir->Size) > mImageSize)
+ goto Done;
+
+ //
+ // Verify the signature of the image, multiple signatures are allowed as per PE/COFF Section 4.7
+ // "Attribute Certificate Table".
+ // The first certificate starts at offset (SecDataDir->VirtualAddress) from the start of the file.
+ //
+ Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FAILED;
+ for (OffSet = SecDataDir->VirtualAddress;
+ OffSet < (SecDataDir->VirtualAddress + SecDataDir->Size);
+// OffSet += WinCertificate->dwLength, OffSet += ALIGN_SIZE (OffSet)) {
+ OffSet +=(WinCertificate->dwLength + ALIGN_SIZE (WinCertificate->dwLength))) {
+
+ WinCertificate = (WIN_CERTIFICATE *) (mImageBase + OffSet);
+ TRACE((TRACE_ALWAYS,"\nOffSet = %x, WinCertificate->dwLength %x\n\n", OffSet, WinCertificate->dwLength));
+ if ((SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) <= sizeof (WIN_CERTIFICATE) ||
+ (SecDataDir->VirtualAddress + SecDataDir->Size - OffSet) < WinCertificate->dwLength) {
+ break;
+ }
+ //
+ // Verify the image's Authenticode signature, only DER-encoded PKCS#7 signed data is supported.
+ //
+ //
+ // Verify signature of executables.
+ //
+
+ if (WinCertificate->wCertificateType == WIN_CERT_TYPE_PKCS_SIGNED_DATA) {
+ //
+ // The certificate is formatted as WIN_CERTIFICATE_EFI_PKCS which is described in the
+ // Authenticode specification.
+ //
+ PkcsCertData = (WIN_CERTIFICATE_EFI_PKCS *) WinCertificate;
+ if (PkcsCertData->Hdr.dwLength <= sizeof (PkcsCertData->Hdr)) {
+ break;
+ }
+ AuthData = PkcsCertData->CertData;
+ AuthDataSize = PkcsCertData->Hdr.dwLength - sizeof(PkcsCertData->Hdr);
+
+ } else if (WinCertificate->wCertificateType == WIN_CERT_TYPE_EFI_GUID) {
+ //
+ // The certificate is formatted as WIN_CERTIFICATE_UEFI_GUID which is described in UEFI Spec.
+ //
+ WinCertUefiGuid = (WIN_CERTIFICATE_UEFI_GUID *) WinCertificate;
+ if (WinCertUefiGuid->Hdr.dwLength <= OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData)) {
+ break;
+ }
+ if (guidcmp (&WinCertUefiGuid->CertType, &gEfiCertTypePkcs7Guid)) {
+ continue;
+ }
+ AuthData = WinCertUefiGuid->CertData;
+ AuthDataSize = WinCertUefiGuid->Hdr.dwLength - OFFSET_OF(WIN_CERTIFICATE_UEFI_GUID, CertData);
+
+ } else {
+ if (WinCertificate->dwLength < sizeof (WIN_CERTIFICATE)) {
+ break;
+ }
+ continue;
+ }
+ //
+ // Verify Pkcs signed data type.
+ //
+ // At least 1 Cert from Pe Image should be in DB
+ // None of Certs should be found in DBX
+ //
+ // get Digest Algorithm, set mCertType
+ // lock mutex, preserve Pkcs7 context
+ Status = HashPeImageByType (AuthData, AuthDataSize);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Check the digital signature against the revoked certificate in forbidden database (dbx).
+ //
+ if (IsPkcsSignedDataVerifiedBySignatureList (AuthData, AuthDataSize, EFI_IMAGE_SECURITY_DATABASE1, Pkcs7CertGetMatchInCertChain)) {
+
+ Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;
+ VerifyStatus = EFI_ACCESS_DENIED;
+ break;
+ }
+ //
+ // Check the digital signature against the valid certificate in allowed database (db).
+ //
+ if (EFI_ERROR (VerifyStatus)) {
+ if(IsPkcsSignedDataVerifiedBySignatureList (AuthData, AuthDataSize, EFI_IMAGE_SECURITY_DATABASE, Pkcs7CertValidate)) {
+
+ VerifyStatus = EFI_SUCCESS;
+ }
+ }
+ // clear context
+ Status = mDigitalSigProtocol->Pkcs7Verify (
+ mDigitalSigProtocol,
+ AuthData, AuthDataSize,
+ NULL, 0,
+ NULL, NULL,
+ Pkcs7Arg0, // Dummy op
+ RESET // Flags
+ );
+
+ } // end multi-sig for
+
+// if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size + ALIGN_SIZE(SecDataDir->Size))) {
+ if(Action != EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {
+ if (OffSet != (SecDataDir->VirtualAddress + SecDataDir->Size)) {
+ TRACE((TRACE_ALWAYS,"Offset outside of CertDir boundary %X != %x\n", OffSet, SecDataDir->VirtualAddress + SecDataDir->Size));
+ //
+ // The Size in Certificate Table or the attribute certificate table is corrupted.
+ //
+ VerifyStatus = EFI_ACCESS_DENIED;
+ } else
+ Action = EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND;
+ }
+
+ } // end Signed cert branch
+
+ // Image not Signed or
+ // Image is Signed, its Cert verified in db but not found in DBX
+ if(mCertType != &gEfiCertSha256Guid &&
+ Action != EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {
+
+ //
+ // This image is not signed or signed but found only in db or failed previous checks.
+ // Expected:
+ // The SHA256 hash value of the image must match a record in the security database "db",
+ // and not be reflected in the security data base "dbx".
+ //
+ TRACE((TRACE_ALWAYS,"IMAGE not Signed\n\tor signed with non-Sha256, Try Sha256 Hash Cert...\n"));
+
+ if(!HashPeImage (HASHALG_SHA256)) // init Hash type and calculate PE hash if not done already
+ goto Done;
+
+ if(IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE1, &gEfiCertSha256Guid, mImageDigest, mImageDigestSize)) {
+ //
+ // Image Hash in forbidden database (DBX)
+ //
+ VerifyStatus = EFI_ACCESS_DENIED;
+ Action = EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND;
+ } else
+ // no - try in allowed db if not there already
+ if(EFI_ERROR (VerifyStatus) &&
+ IsSignatureFoundInDatabase (EFI_IMAGE_SECURITY_DATABASE, &gEfiCertSha256Guid, mImageDigest, mImageDigestSize)) {
+ //
+ // Image Hash is in allowed database (DB).
+ //
+ VerifyStatus = EFI_SUCCESS;
+ }
+ }
+ //
+ // Signature database check after verification.
+ //
+ if(!EFI_ERROR (VerifyStatus) ) {
+ //
+ // Executable signature is found in authorized signature database.
+ //
+ Status = EFI_SUCCESS;
+ } else {
+ Status = EFI_ACCESS_DENIED;
+
+ if(Action == EFI_IMAGE_EXECUTION_AUTH_SIG_FOUND) {
+ //
+ // Executable signature is found in forbidden signature database.
+ //
+ TRACE((TRACE_ALWAYS,"Certificate IS FOUND in Forbidden database!\n"));
+ } else
+ //
+ // Verification failure.
+ //
+ if(Action == EFI_IMAGE_EXECUTION_AUTH_SIG_NOT_FOUND) {
+ //
+ // Executable signature cannot be found in authorized signature database.
+ // Use platform policy to determine the action.
+ //
+ TRACE((TRACE_ALWAYS,"Certificate NOT FOUND in authorized database!\n"));
+ }
+ else
+ TRACE((TRACE_ALWAYS,"Image Certificate is Invalid!\n"));
+
+ TRACE((TRACE_ALWAYS,"%r Record added to Image Execution Table\n", Status));
+
+ if(!mCertType || !mImageDigestSize ) {
+ goto Done;
+ }
+ SignatureListSize = sizeof (EFI_SIGNATURE_LIST) + sizeof (EFI_SIGNATURE_DATA) - 1 + mImageDigestSize;
+
+ // Security review EIP[104046]:7. Unchecked AllocatePool may result in NULL pointer dereference
+ if (!EFI_ERROR(pBS->AllocatePool(EfiBootServicesData, SignatureListSize, &SignatureList)))
+ {
+ MemSet(SignatureList, SignatureListSize, 0);
+ SignatureList->SignatureHeaderSize = 0;
+ SignatureList->SignatureListSize = (UINT32) SignatureListSize;
+ SignatureList->SignatureSize = (UINT32) mImageDigestSize;
+ CopyMem (&SignatureList->SignatureType, mCertType, sizeof (EFI_GUID));
+ Signature = (EFI_SIGNATURE_DATA *) ((UINT8 *) SignatureList + sizeof (EFI_SIGNATURE_LIST));
+ CopyMem (Signature->SignatureData, mImageDigest, mImageDigestSize);
+ }
+ if (SignatureList != NULL) {
+ pBS->FreePool (SignatureList);
+ }
+ }
+Done:
+ if (Status != EFI_SUCCESS) {
+ //
+ // Policy decides to defer or reject the image; add its information in image executable information table.
+ //
+ AddImageExeInfo (Action, NULL, File, SignatureList, SignatureListSize);
+ // Treat unsecured images according to Image Authorization policy
+ Status = ImageAuthorization (Policy, Action);
+ }
+ if(bFileRead)
+ pBS->FreePool (FileBuffer);
+
+TRACE((TRACE_ALWAYS,"Image Verification ...%r\n", Status));
+ return Status;
+}
+
+//===================== Security Architectural Protocol ======================
+#ifndef EFI_SECURITY2_ARCH_PROTOCOL_GUID
+#define EFI_SECURITY2_ARCH_PROTOCOL_GUID \
+ { 0x94ab2f58, 0x1438, 0x4ef1, 0x91, 0x52, 0x18, 0x94, 0x1a, 0x3a, 0xe, 0x68 }
+
+typedef struct _EFI_SECURITY2_ARCH_PROTOCOL EFI_SECURITY2_ARCH_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_SECURITY2_FILE_AUTHENTICATION) (
+ IN CONST EFI_SECURITY2_ARCH_PROTOCOL *This,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *File,
+ IN VOID *FileBuffer,
+ IN UINTN FileSize,
+ IN BOOLEAN BootPolicy
+);
+
+struct _EFI_SECURITY2_ARCH_PROTOCOL {
+ EFI_SECURITY2_FILE_AUTHENTICATION FileAuthentication;
+};
+
+static EFI_GUID gEfiSecurity2ArchProtocolGuid = EFI_SECURITY2_ARCH_PROTOCOL_GUID;
+#endif
+
+EFI_STATUS SecureFileAuthentication2(
+ IN CONST EFI_SECURITY2_ARCH_PROTOCOL *This,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *File,
+ IN VOID *FileBuffer,
+ IN UINTN FileSize,
+ IN BOOLEAN BootPolicy
+ )
+{
+ EFI_STATUS Status;
+
+ TRACE((TRACE_ALWAYS,"...............Call Security2 Arch proto.. File=%x, FileBuffer=%x, FileSize=%d\n",File,FileBuffer,FileSize ));
+
+ //
+ // skip verification if platform is NOT in SECURE BOOT MODE
+ //
+ if(mSecureBootEnable == 0)
+ return EFI_SUCCESS;
+
+ //
+ // Protocol should have been installed by AmiDigitalSig Driver once it's dispatched
+ //
+ if( mDigitalSigProtocol == NULL )
+ return EFI_ACCESS_DENIED;
+
+ Status = DxeImageVerificationHandler(File, FileBuffer, FileSize, BootPolicy);
+ // Install Tbl only on the Boot Loader launch
+ if (!EFI_ERROR (Status)/* && BootPolicy*/) {
+ AddBootImageCertInfo(NULL, mTrustSigDbOffs, mTrustSigDbSize);
+ mTrustSigDbOffs = 0;
+ mTrustSigDbSize = 0;
+ }
+ TRACE((TRACE_ALWAYS,"...............return status %r\n",Status));
+ return Status;
+}
+
+EFI_STATUS SecureFileAuthentication(
+ IN EFI_SECURITY_ARCH_PROTOCOL *This,
+ IN UINT32 AuthenticationStatus,
+ IN EFI_DEVICE_PATH_PROTOCOL *File
+ )
+{
+ BOOLEAN BootPolicy;
+ VOID *FileBuffer;
+ UINTN FileSize;
+
+ BootPolicy = TRUE;
+ FileBuffer = NULL;
+ FileSize = 0;
+
+ TRACE((TRACE_ALWAYS,".........Call Security Arch proto.. File=%x\n",File));
+
+ if (File == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ //Security Protocol w/a: BootPolicy == 1 if File->Type == 4 Media Dev Path
+// if(File->Type == 4) // Media Dev Path
+// BootPolicy=TRUE;
+
+ return SecureFileAuthentication2(NULL, File, FileBuffer, FileSize, BootPolicy);
+}
+
+EFI_SECURITY2_ARCH_PROTOCOL mSecurity2 = {SecureFileAuthentication2};
+EFI_SECURITY_ARCH_PROTOCOL mSecurity = {SecureFileAuthentication};
+
+//----------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitDigitalProtocolCallback
+//
+// Description: This function initialize mDigitalSigProtocol ptr
+//
+//
+// Input: IN EFI_EVENT Event - Event that was triggered
+// IN VOID *Context - data pointer to information that is defined
+// when the event is registered
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS InitDigitalProtocolCallback(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 *pSecureBootEnable=NULL;
+ //
+ // Look up for image authorization policy in "SetupData" variable
+ //
+#if (defined(ENABLE_IMAGE_EXEC_POLICY_OVERRIDE) && ENABLE_IMAGE_EXEC_POLICY_OVERRIDE == 1)
+ DataSize = sizeof(mSecureBootSetup);
+ Status = pRS->GetVariable (AMI_SECURE_BOOT_SETUP_VAR,&gSecureSetupGuid,NULL,&DataSize,&mSecureBootSetup);
+ if(EFI_ERROR(Status) ||
+ // Standard boot mode policy->apply defaults
+ mSecureBootSetup.SecureBootMode == STANDARD_SECURE_BOOT ||
+ // Policy check against fixed settings
+ mSecureBootSetup.Load_from_OROM < LOAD_FROM_OROM ||
+ mSecureBootSetup.Load_from_REMOVABLE_MEDIA < LOAD_FROM_REMOVABLE_MEDIA ||
+ mSecureBootSetup.Load_from_FIXED_MEDIA < LOAD_FROM_FIXED_MEDIA
+ )
+#endif
+ {
+ mSecureBootSetup.Load_from_OROM = LOAD_FROM_OROM;
+ mSecureBootSetup.Load_from_REMOVABLE_MEDIA = LOAD_FROM_REMOVABLE_MEDIA;
+ mSecureBootSetup.Load_from_FIXED_MEDIA = LOAD_FROM_FIXED_MEDIA;
+ }
+ //
+ // SecureBoot variable to be installed along with NVRAM driver
+ //
+ pSecureBootEnable = GetEfiGlobalVariableEx (EFI_SECURE_BOOT_NAME, &DataSize);
+ if(pSecureBootEnable && DataSize==1)
+ mSecureBootEnable = *pSecureBootEnable;
+ //
+ // will skip verification if platform is NOT in SECURE BOOT MODE
+ //
+ if(mSecureBootEnable == 0)
+ return EFI_SUCCESS;
+
+ Status = pBS->LocateHandleBuffer (
+ ByProtocol,
+ #if (PI_SPECIFICATION_VERSION < 0x00010000)
+ &gEfiFirmwareVolumeProtocolGuid,
+ #else
+ &gEfiFirmwareVolume2ProtocolGuid,
+ #endif
+ NULL,
+ &mFvHandlesCount,
+ &mFvHandles
+ );
+ if(!EFI_ERROR(Status)){
+ gImageLoadingAfterBDS = TRUE;
+ }
+
+ return pBS->LocateProtocol( &gAmiDigitalSignatureProtocolGuid, NULL, &mDigitalSigProtocol );
+}
+
+extern BOOLEAN const InstallDummySecurityProtocol;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InstallSecurityArchProtocol
+//
+// Description: This function installs the EFI_SECURITY_ARCH_PROTOCOL.
+// It is called at DxeCoreInitialize.
+//
+// Input:
+// EFI_HANDLE ImageHandle Image handle.
+// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table.
+//
+// Output:
+// EFI_SUCCESS : Security Architecture protocols are successfully installed.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InstallSecurityArchProtocol(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE Handle = NULL;
+ EFI_EVENT Event;
+ VOID *p;
+
+ if (InstallDummySecurityProtocol)
+ return;
+
+ // Enable Security verification at beginning of BDS connect controller phase,
+ // We assume all drivers before the event were launched from internal FV
+ // !!! This bds event is only available since core 4.6.3.5.
+ RegisterProtocolCallback(
+ &BdsConnectDriversProtocolGuid,
+ InitDigitalProtocolCallback,
+ NULL,
+ &Event,
+ &p
+ );
+ // Security2 Arch protocol must be installed before Security Arch protocol
+ pBS->InstallMultipleProtocolInterfaces(
+ &Handle,
+ &gEfiSecurity2ArchProtocolGuid, &mSecurity2,
+ &gEfiSecurityArchProtocolGuid, &mSecurity,
+ NULL
+ );
+}
+
+#pragma warning (default : 4090)
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.h b/Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.h
new file mode 100644
index 0000000..1a3ddd5
--- /dev/null
+++ b/Core/EM/SecurityPkg/ImageVerificationLib/DxeImageVerificationLib.h
@@ -0,0 +1,175 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/ImageVerification_efi/DxeImageVerificationLib.h 3 3/15/13 4:59p Alexp $
+//
+// $Revision: 3 $
+//
+// $Date: 3/15/13 4:59p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/ImageVerification_efi/DxeImageVerificationLib.h $
+//
+// 3 3/15/13 4:59p Alexp
+// EIP:118243 add support for multi-signed PE Images
+//
+// 2 4/20/12 5:14p Alexp
+// Add new function to install the handle on Efi System Table with the
+// location
+// within DB variable of the Trusted Certificate that was used to verify
+// signature of Efi OS BootLoader image.
+//
+// 1 6/13/11 5:25p Alexp
+//
+// 2 5/10/11 5:05p Alexp
+// add header & footer
+//
+//
+//
+//**********************************************************************
+//
+// This file contains an 'Intel Peripheral Driver' and is
+// licensed for Intel CPUs and chipsets under the terms of your
+// license agreement with Intel or your vendor. This file may
+// be modified by the user, subject to additional terms of the
+// license agreement
+//
+/** @file
+
+ The internal header file includes the common header files, defines
+ internal structure and functions used by ImageVerificationLib.
+
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved. <BR>
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+**/
+
+#ifndef __IMAGEVERIFICATIONLIB_H__
+#define __IMAGEVERIFICATIONLIB_H__
+
+
+#include <Protocol/FirmwareVolume.h>
+#include <Protocol/DevicePath.h>
+#include <Protocol/BlockIo.h>
+#include <Protocol/SimpleFileSystem.h>
+
+#include "WinCertificate.h"
+#include <ImageAuthentication.h>
+#include <Protocol/Hash.h>
+
+#define EFI_CERT_TYPE_RSA2048_SHA256_SIZE 256
+#define EFI_CERT_TYPE_RSA2048_SIZE 256
+#define EFI_CERT_TYPE_SHA256_SIZE 32
+#define MAX_NOTIFY_STRING_LEN 64
+
+//
+// Image type definitions
+//
+#define IMAGE_UNKNOWN 0x00000000
+#define IMAGE_FROM_FV 0x00000001
+#define IMAGE_FROM_OPTION_ROM 0x00000002
+#define IMAGE_FROM_REMOVABLE_MEDIA 0x00000003
+#define IMAGE_FROM_FIXED_MEDIA 0x00000004
+
+//
+// Authorization policy bit definition
+//
+#define ALWAYS_EXECUTE 0x00000000
+#define NEVER_EXECUTE 0x00000001
+#define ALLOW_EXECUTE_ON_SECURITY_VIOLATION 0x00000002
+#define DEFER_EXECUTE_ON_SECURITY_VIOLATION 0x00000003
+#define DENY_EXECUTE_ON_SECURITY_VIOLATION 0x00000004
+#define QUERY_USER_ON_SECURITY_VIOLATION 0x00000005
+
+//
+// Support hash types
+//
+#define HASHALG_SHA1 0x00000001
+#define HASHALG_SHA256 0x00000002
+
+#define MAX_ELEM_NUM 28 // TBD. ~20 max number of PE hdr elements to be hashed in one pass
+///
+/// SHA-1 digest size in bytes.
+///
+#define SHA1_DIGEST_SIZE 20
+///
+/// SHA-256 digest size in bytes
+///
+#define SHA256_DIGEST_SIZE 32
+
+//
+// Set max digest size as SHA256 Output (32 bytes) by far
+//
+#define MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
+
+#define ALIGNMENT_SIZE 8
+#define ALIGN_SIZE(a) (((a) % ALIGNMENT_SIZE) ? ALIGNMENT_SIZE - ((a) % ALIGNMENT_SIZE) : 0)
+
+#ifndef OFFSET_OF
+#define OFFSET_OF(TYPE, Field) ((UINTN) &(((TYPE *)0)->Field))
+#endif
+
+//defined for every CPU architecture
+// Maximum legal IA-32 address
+#ifndef EFI_MAX_ADDRESS
+#define EFI_MAX_ADDRESS 0xFFFFFFFF
+#endif
+
+//
+//
+// PKCS7 Certificate definition
+//
+typedef struct _WIN_CERTIFICATE_EFI_PKCS {
+ WIN_CERTIFICATE Hdr;
+ UINT8 CertData[1];
+} WIN_CERTIFICATE_EFI_PKCS;
+
+//
+// Definitions for Efi System table entry to store the location within DB variable
+// of the Trusted Certificate that was used to verify Efi OS BootLoader image
+//
+//6683D10C-CF6E-4914-B5B4-AB8ED7370ED7
+#define AMI_VALID_BOOT_IMAGE_CERT_TBL_GUID \
+ { 0x6683D10C, 0xCF6E, 0x4914, 0xB5, 0xB4, 0xAB, 0x8E, 0xD7, 0x37, 0x0E, 0xD7 }
+//
+//
+// Data Table definition
+//
+typedef struct _AMI_VALID_CERT_IN_SIG_DB {
+ UINT32 SigOffset;
+ UINT32 SigLength;
+} AMI_VALID_CERT_IN_SIG_DB;
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/ImageVerificationLib/EfiImage.h b/Core/EM/SecurityPkg/ImageVerificationLib/EfiImage.h
new file mode 100644
index 0000000..f50b0e5
--- /dev/null
+++ b/Core/EM/SecurityPkg/ImageVerificationLib/EfiImage.h
@@ -0,0 +1,702 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiImage.h
+
+Abstract:
+
+ EFI image format for PE32+. Please note some data structures are different
+ for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64
+
+ BugBug: Fix text - doc as defined in MSFT EFI specification
+
+--*/
+
+#ifndef _EFI_IMAGE_H_
+#define _EFI_IMAGE_H_
+
+//
+// PE32+ Subsystem type for EFI images
+//
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+
+//
+// BugBug: Need to get a real answer for this problem. This is not in the
+// PE specification.
+//
+// A SAL runtime driver does not get fixed up when a transition to
+// virtual mode is made. In all other cases it should be treated
+// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image
+//
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13
+
+//
+// PE32+ Machine type for EFI images
+//
+#define EFI_IMAGE_MACHINE_IA32 0x014c
+#define EFI_IMAGE_MACHINE_IA64 0x0200
+#define EFI_IMAGE_MACHINE_X64 0x8664
+#define EFI_IMAGE_MACHINE_ARMTHUMB_MIXED 0x01c2
+
+//
+// #define EFI_IMAGE_MACHINE_FCODE 0xfc0d
+//
+#define EFI_IMAGE_MACHINE_EBC 0x0EBC
+
+#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE
+#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE
+#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
+//
+// PE images can start with an optional DOS header, so if an image is run
+// under DOS it can print an error message.
+//
+typedef struct {
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+} EFI_IMAGE_DOS_HEADER;
+
+//
+// File header format.
+//
+typedef struct {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} EFI_IMAGE_FILE_HEADER;
+
+#define EFI_IMAGE_SIZEOF_FILE_HEADER 20
+
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
+#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File.
+#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0
+#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
+#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian
+#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian
+#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP*
+#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian
+#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
+//
+// * Other names and brands may be claimed as the property of others.
+//
+//
+// Directory format.
+//
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} EFI_IMAGE_DATA_DIRECTORY;
+
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
+
+typedef struct {
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ UINT32 BaseOfBss;
+ UINT32 GprMask;
+ UINT32 CprMask[4];
+ UINT32 GpValue;
+} EFI_IMAGE_ROM_OPTIONAL_HEADER;
+
+#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)
+
+typedef struct {
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} EFI_IMAGE_ROM_HEADERS;
+
+//
+// ATTENTION!!! EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+// are for use ONLY by tools. All proper EFI code MUST use
+// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+//
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ //
+ // NT additional fields.
+ //
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER32;
+
+//
+// ATTENTION!!! EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+// are for use ONLY by tools. All proper EFI code MUST use
+// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+//
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ //
+ // NT additional fields.
+ //
+ UINT64 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT64 SizeOfStackReserve;
+ UINT64 SizeOfStackCommit;
+ UINT64 SizeOfHeapReserve;
+ UINT64 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER64;
+
+//
+// ATTENTION!!! EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY
+// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!
+//
+typedef struct {
+ UINT32 Signature;
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS32;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)
+
+typedef struct {
+ UINT32 Signature;
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS64;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)
+
+//
+// Include processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the
+// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for
+// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code.
+//
+#if !defined(EFI64) && !defined(EFIx64)
+//IA32
+#define EFI_IMAGE_MACHINE_TYPE (EFI_IMAGE_MACHINE_IA32)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64)
+
+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
+typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER;
+typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS;
+#elif defined(EFI64)
+//IPF
+#define EFI_IMAGE_MACHINE_TYPE (EFI_IMAGE_MACHINE_IA64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ (((Machine) == EFI_IMAGE_MACHINE_IA64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
+typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;
+typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;
+#elif defined(EFIx64)
+//x64
+#define EFI_IMAGE_MACHINE_TYPE (EFI_IMAGE_MACHINE_X64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32)
+
+//
+// Assume we can use IPF values
+//
+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
+typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;
+typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;
+#endif
+
+#define EFI_IMAGE_FIRST_SECTION(ntheader) \
+ ( \
+ (EFI_IMAGE_SECTION_HEADER *) \
+ ( \
+ (UINT32) ntheader + \
+ FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \
+ ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \
+ ) \
+ )
+
+//
+// Subsystem Values
+//
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0
+#define EFI_IMAGE_SUBSYSTEM_NATIVE 1
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7
+
+//
+// Directory Entries
+//
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+
+//
+// Section header format.
+//
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct {
+ UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} EFI_IMAGE_SECTION_HEADER;
+
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
+#define EFI_IMAGE_SCN_CNT_CODE 0x00000020
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+
+#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
+#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
+#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
+#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000
+
+#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000
+
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000
+#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define EFI_IMAGE_SCN_MEM_READ 0x40000000
+#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000
+
+//
+// Symbol format.
+//
+#define EFI_IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common.
+#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value.
+#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item.
+//
+// Type (fundamental) values.
+//
+#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type.
+#define EFI_IMAGE_SYM_TYPE_VOID 1 //
+#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character.
+#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer.
+#define EFI_IMAGE_SYM_TYPE_INT 4
+#define EFI_IMAGE_SYM_TYPE_LONG 5
+#define EFI_IMAGE_SYM_TYPE_FLOAT 6
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8
+#define EFI_IMAGE_SYM_TYPE_UNION 9
+#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration.
+#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
+#define EFI_IMAGE_SYM_TYPE_BYTE 12
+#define EFI_IMAGE_SYM_TYPE_WORD 13
+#define EFI_IMAGE_SYM_TYPE_UINT 14
+#define EFI_IMAGE_SYM_TYPE_DWORD 15
+
+//
+// Type (derived) values.
+//
+#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type.
+#define EFI_IMAGE_SYM_DTYPE_POINTER 1
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2
+#define EFI_IMAGE_SYM_DTYPE_ARRAY 3
+
+//
+// Storage classes.
+//
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1
+#define EFI_IMAGE_SYM_CLASS_NULL 0
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2
+#define EFI_IMAGE_SYM_CLASS_STATIC 3
+#define EFI_IMAGE_SYM_CLASS_REGISTER 4
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define EFI_IMAGE_SYM_CLASS_LABEL 6
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18
+#define EFI_IMAGE_SYM_CLASS_BLOCK 100
+#define EFI_IMAGE_SYM_CLASS_FUNCTION 101
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define EFI_IMAGE_SYM_CLASS_FILE 103
+#define EFI_IMAGE_SYM_CLASS_SECTION 104
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+
+//
+// type packing constants
+//
+#define EFI_IMAGE_N_BTMASK 017
+#define EFI_IMAGE_N_TMASK 060
+#define EFI_IMAGE_N_TMASK1 0300
+#define EFI_IMAGE_N_TMASK2 0360
+#define EFI_IMAGE_N_BTSHFT 4
+#define EFI_IMAGE_N_TSHIFT 2
+
+//
+// Communal selection types.
+//
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define EFI_IMAGE_COMDAT_SELECT_ANY 2
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+//
+// Relocation format.
+//
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 SymbolTableIndex;
+ UINT16 Type;
+} EFI_IMAGE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
+#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define EFI_IMAGE_REL_I386_SECTION 012
+#define EFI_IMAGE_REL_I386_SECREL 013
+#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
+//
+// Based relocation format.
+//
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 SizeOfBlock;
+} EFI_IMAGE_BASE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8
+
+//
+// Based relocation types.
+//
+#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
+#define EFI_IMAGE_REL_BASED_HIGH 1
+#define EFI_IMAGE_REL_BASED_LOW 2
+#define EFI_IMAGE_REL_BASED_HIGHLOW 3
+#define EFI_IMAGE_REL_BASED_HIGHADJ 4
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
+#define EFI_IMAGE_REL_BASED_DIR64 10
+
+//
+// Line number format.
+//
+typedef struct {
+ union {
+ UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+ UINT32 VirtualAddress; // Virtual address of line number.
+ } Type;
+ UINT16 Linenumber; // Line number.
+} EFI_IMAGE_LINENUMBER;
+
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+#define EFI_IMAGE_ARCHIVE_START_SIZE 8
+#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"
+#define EFI_IMAGE_ARCHIVE_END "`\n"
+#define EFI_IMAGE_ARCHIVE_PAD "\n"
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct {
+ UINT8 Name[16]; // File member name - `/' terminated.
+ UINT8 Date[12]; // File member date - decimal.
+ UINT8 UserID[6]; // File member user id - decimal.
+ UINT8 GroupID[6]; // File member group id - decimal.
+ UINT8 Mode[8]; // File member mode - octal.
+ UINT8 Size[10]; // File member size - decimal.
+ UINT8 EndHeader[2]; // String to end header.
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+//
+// Export Format
+//
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Name;
+ UINT32 Base;
+ UINT32 NumberOfFunctions;
+ UINT32 NumberOfNames;
+ UINT32 AddressOfFunctions;
+ UINT32 AddressOfNames;
+ UINT32 AddressOfNameOrdinals;
+} EFI_IMAGE_EXPORT_DIRECTORY;
+
+//
+// Import Format
+//
+typedef struct {
+ UINT16 Hint;
+ UINT8 Name[1];
+} EFI_IMAGE_IMPORT_BY_NAME;
+
+typedef struct {
+ union {
+ UINT32 Function;
+ UINT32 Ordinal;
+ EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;
+ } u1;
+} EFI_IMAGE_THUNK_DATA;
+
+#define EFI_IMAGE_ORDINAL_FLAG 0x80000000
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
+#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT32 ForwarderChain;
+ UINT32 Name;
+ EFI_IMAGE_THUNK_DATA *FirstThunk;
+} EFI_IMAGE_IMPORT_DESCRIPTOR;
+
+//
+// Debug Format
+//
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Type;
+ UINT32 SizeOfData;
+ UINT32 RVA;
+ UINT32 FileOffset;
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
+
+#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"
+typedef struct {
+ UINT32 Signature; // "NB10"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
+
+#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS"
+typedef struct {
+ UINT32 Signature; // "RSDS"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ UINT32 Unknown4;
+ UINT32 Unknown5;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
+
+//
+// Header format for TE images
+//
+typedef struct {
+ UINT16 Signature; // signature for TE format = "VZ"
+ UINT16 Machine; // from the original file header
+ UINT8 NumberOfSections; // from the original file header
+ UINT8 Subsystem; // from original optional header
+ UINT16 StrippedSize; // how many bytes we removed from the header
+ UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header
+ UINT32 BaseOfCode; // from original image -- required for ITP debug
+ UINT64 ImageBase; // from original file header
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory
+} EFI_TE_IMAGE_HEADER;
+
+#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ"
+//
+// Data directory indexes in our TE image header
+//
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1
+
+//
+// Union of PE32, PE32+, and TE headers
+//
+typedef union {
+ EFI_IMAGE_NT_HEADERS32 Pe32;
+ EFI_IMAGE_NT_HEADERS64 Pe32Plus;
+ EFI_TE_IMAGE_HEADER Te;
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;
+
+typedef union {
+ EFI_IMAGE_NT_HEADERS32 *Pe32;
+ EFI_IMAGE_NT_HEADERS64 *Pe32Plus;
+ EFI_TE_IMAGE_HEADER *Te;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *Union;
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;
+
+#endif
diff --git a/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.cif b/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.cif
new file mode 100644
index 0000000..ff5909a
--- /dev/null
+++ b/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "Image Verification Library"
+ category = ModulePart
+ LocalRoot = "Core\EM\SecurityPkg\ImageVerificationLib"
+ RefName = "ImageVerificationLib"
+[files]
+"ImageVerificationLib.sdl"
+"ImageVerificationLib.mak"
+"DxeImageVerificationLib.c"
+"DxeImageVerificationLib.h"
+"EfiImage.h"
+<endComponent>
diff --git a/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.mak b/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.mak
new file mode 100644
index 0000000..bb6b02b
--- /dev/null
+++ b/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.mak
@@ -0,0 +1,92 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/ImageVerification_efi/ImageVerificationLib.mak 5 8/15/13 11:28a Alexp $
+#
+# $Revision: 5 $
+#
+# $Date: 8/15/13 11:28a $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/ImageVerification_efi/ImageVerificationLib.mak $
+#
+# 5 8/15/13 11:28a Alexp
+#
+# 4 11/19/12 4:42p Alexp
+# Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+# across flash updates.
+# Move all secure boot Setup settings to a separate varsore variable.
+# Preserve var across re-flash
+#
+# 3 6/30/11 4:01p Alexp
+# moved Setup Page defines to parent SecureBoot module
+#
+# 2 6/15/11 3:06p Alexp
+# removed commented instructions
+#
+# 1 6/13/11 5:25p Alexp
+#
+# 5 5/17/11 5:35p Alexp
+#
+#
+# 3 5/11/11 1:03p Alexp
+# update file hdr
+#
+# 2 5/10/11 12:35p Alexp
+#
+# 1 5/09/11 10:04a Alexp
+#
+# 3 5/04/11 7:15p Alexp
+# add Setup controls on Secure page
+#
+# 2 4/11/11 12:58p Alexp
+# remove Crypto lib linkage
+#
+# 1 3/12/11 11:31a Alexp
+#
+# 1 3/10/11 5:00p Alexp
+#
+# 1 3/03/11 6:35p Alexp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: ImageVerificationLib.mak
+#
+# Description: installs Security Architecture Protocol
+#
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+CORE_DXE_LIBBin : $(IMAGEVERIFY_LIB)
+
+$(IMAGEVERIFY_LIB) : $(BUILD_DIR)\ImageVerificationLib.mak ImageVerificationLibBin
+
+$(BUILD_DIR)\ImageVerificationLib.mak : $(ImageVerificationLib_DIR)\ImageVerificationLib.cif $(BUILD_RULES)
+ $(CIF2MAK) $(ImageVerificationLib_DIR)\ImageVerificationLib.cif $(CIF2MAK_DEFAULTS)
+
+ImageVerificationLib_INCLUDES= \
+ /I $(ImageVerificationLib_DIR) \
+ /I $(SecureBoot_DIR) \
+ /I $(CORE_DIR)
+
+ImageVerificationLibBin : $(CRYPTOLIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\ImageVerificationLib.mak all\
+ NAME=ImageVerificationLib\
+ MAKEFILE=$(BUILD_DIR)\ImageVerificationLib.mak\
+ "MY_INCLUDES= $(ImageVerificationLib_INCLUDES)" \
+ TYPE=LIBRARY
diff --git a/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.sdl b/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.sdl
new file mode 100644
index 0000000..73e98c0
--- /dev/null
+++ b/Core/EM/SecurityPkg/ImageVerificationLib/ImageVerificationLib.sdl
@@ -0,0 +1,109 @@
+TOKEN
+ Name = "ImageVerification_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Crypto library support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "ENABLE_IMAGE_EXEC_POLICY_OVERRIDE"
+ Value = "0"
+ Help = "Enable user override of Image Execution policy"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ENABLE_IMAGE_EXEC_POLICY_OVERRIDE"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "LOAD_FROM_FV"
+ Value = "0"
+ Help = "Load image from Internal FV. Possible options:\0-ALWAYS_EXECUTE; 1-NEVER_EXECUTE; 2-ALLOW_EXECUTE_ON_SECURITY_VIOLATION;\3-DEFER_EXECUTE_ON_SECURITY_VIOLATION; 4-DENY_EXECUTE_ON_SECURITY_VIOLATION; 5-QUERY_USER_ON_SECURITY_VIOLATION"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+ Range = "Supported options: 0"
+End
+
+TOKEN
+ Name = "LOAD_FROM_OROM"
+ Value = "4"
+ Help = "Load image from Option ROM"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "Supported options: 3,4,5"
+End
+
+TOKEN
+ Name = "LOAD_FROM_REMOVABLE_MEDIA"
+ Value = "4"
+ Help = "Load image from Removable Media"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "Supported options: 3,4,5"
+End
+
+TOKEN
+ Name = "LOAD_FROM_FIXED_MEDIA"
+ Value = "4"
+ Help = "Load image from Fixed Media"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "Supported options: 3,4,5"
+End
+
+TOKEN
+ Name = "INSTALL_DUMMY_SECURITY_PROTOCOL"
+ Value = "0"
+ Help = "When this token is 'on', the Core publishes dummy instance of the security protocol.\The security protocol is one of the architectural protocols and as such must be available.\The default value is 'on'. \Set to 'off' if project includes driver that publishes the security protocol.\"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "LOAD_UNSIGNED_EMBEDDED_SHELL"
+ Value = "0"
+ Help = "Load Shell from Internal FV"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "LOAD_UNSIGNED_EMBEDDED_SHELL"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_MODE" "=" "1"
+End
+
+TOKEN
+ Name = "IMAGEVERIFY_LIB"
+ Value = "$$(LIB_BUILD_DIR)\ImageVerificationLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "ImageVerificationLib_DIR"
+ Help = "Path to Crypto library Module in Project"
+End
+
+MODULE
+ Help = "Includes ImageVerificationLib.mak to Project"
+ File = "ImageVerificationLib.mak"
+End
+
+ELINK
+ Name = "InstallSecurityArchProtocol,"
+ Parent = "DxeCoreInitialize"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c
new file mode 100644
index 0000000..a82e2c7
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.c
@@ -0,0 +1,325 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014 American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.c 13 3/18/14 3:02p Alexp $
+//
+// $Revision: 13 $
+//
+// $Date: 3/18/14 3:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.c $
+//
+// 13 3/18/14 3:02p Alexp
+// year '2014' in file hdr & ftr
+//
+// 12 2/27/13 6:31p Alexp
+// don't assume the Capsule hob starts with FWCapsule header.
+// helps to hadle Windows Update Capsule with Ami.rom as payload
+//
+// 11 12/17/12 2:40p Alexp
+// optimized LoadRecoveryCapsule()
+//
+// 10 8/28/12 4:19p Alexp
+// change return NULL to return 0 for EFI_PHYSICAL_ADDRESS types
+//
+// 8 4/19/12 2:43p Alexp
+// EIP:87678: Woking image during Recovery and Capsule Secure Flash Update
+// Deffer Publishing of FV DXE to DxeIpl. Launch DXE from original FV on
+// Flash updates while in Recovery use DXE form new image
+//
+// 7 2/14/12 3:24p Alexp
+// Replace VOID (32bit) with EFI_PHYSICAL_ADDRESS(64bit) pointer for an
+// address of a Recovery Hob data.
+//
+// 6 12/08/11 12:22p Alexp
+// Re-define EFI_HOB_TYPE_CV type as EFI_HOB_TYPE_UEFI_CAPSULE
+// for forward compatibility with PI 1.2 Hob.h definitions
+//
+// 5 11/17/11 10:01a Alexp
+// 1. Replace local Capsule pointer with global one.
+// 2. Locate FW CApsule includes search in 2 potential Capsule Hob types
+// - EFI_HOB_TYPE_GUID_EXTENSION
+// - EFI_HOB_TYPE_CV
+//
+// 4 10/11/11 12:23p Alexp
+// re-arrange Function defines and global defines
+//
+// 3 9/20/11 2:26p Alexp
+// do not change BootMode from FlUpdate to Recovery if FwCapsule update is
+// pending
+//
+// 2 7/20/11 7:16p Alexp
+// remove dependency on Capsule module
+//
+// 1 7/01/11 4:39p Alexp
+//
+// 3 4/29/11 10:28a Alexp
+// Capsule Recovery to be invoked sepparately from generic Recovery PPI
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: EFICapsuleRecovery.c - PEI driver
+//
+// Description: Implements EFI_PEI_RECOVERY_BLOCK_IO_PPI for Capsule HOB.
+// Capsule Recovery to be invoked separately from generic Recovery PPI
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include <Token.h>
+#include <PPI/RecoveryModule.h>
+
+#include <AmiPeiLib.h>
+#include <AmiHobs.h>
+#include <Hob.h>
+#include "AmiCertificate.h"
+#include <FlashUpd.h>
+
+// Definitions
+
+EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID;
+EFI_GUID guidRecoveryModule = EFI_PEI_RECOVERY_MODULE_PPI_GUID;
+
+#ifndef EFI_HOB_TYPE_CV
+#define EFI_HOB_TYPE_CV EFI_HOB_TYPE_UEFI_CAPSULE
+typedef EFI_HOB_UEFI_CAPSULE EFI_HOB_CAPSULE_VOLUME;
+#endif // PI BACKWARD_COMPATIBLE_MODE
+
+EFI_PHYSICAL_ADDRESS gCapsuleAddress = 0;
+UINT64 gCapsuleLength = 0;
+//----------------------------------------------------------------------------
+// Function Prototypes
+//----------------------------------------------------------------------------
+EFI_STATUS ReportFV2Dxe(
+ IN VOID* RecoveryCapsule OPTIONAL,
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+EFI_STATUS VerifyFwImage(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsule,
+ IN OUT UINT32 *pCapsuleSize,
+ IN OUT UINT32 *FailedVTask
+);
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//----------------------------------------------------------------------------
+EFI_STATUS LoadRecoveryCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN struct _EFI_PEI_RECOVERY_MODULE_PPI *This
+);
+
+BOOLEAN IsFlashUpdateS3Capsule (
+ EFI_PEI_SERVICES **PeiServices,
+ EFI_BOOT_MODE *BootMode
+);
+//----------------------------------------------------------------------------
+// PPI to be installed
+//----------------------------------------------------------------------------
+static EFI_PEI_RECOVERY_MODULE_PPI RecoveryModule =
+{
+ LoadRecoveryCapsule
+};
+
+//----------------------------------------------------------------------------
+// Notify list that are installed
+//----------------------------------------------------------------------------
+static EFI_PEI_PPI_DESCRIPTOR RecoveryPpiList[] =
+{
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidRecoveryModule, &RecoveryModule
+ }
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FindFWCapsuleHOB
+//
+// Description: Locates Aptio FW Capsule in Capsule Hob
+//
+// Input: EFI_PEI_SERVICES **PeiServices
+// Output: EFI_PHYSICAL_ADDRESS pointer to FW CApsule
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FindFWCapsuleHOB
+(
+ IN EFI_PEI_SERVICES **PeiServices
+){
+ EFI_HOB_GUID_TYPE *pHob;
+ EFI_HOB_CAPSULE_VOLUME *pHob1;
+ EFI_PHYSICAL_ADDRESS CapsuleAddress;
+ UINT64 CapsuleLength;
+ EFI_CAPSULE_HEADER *FWCapsuleVolume;
+
+ (*PeiServices)->GetHobList(PeiServices, &pHob);
+ pHob1 = (EFI_HOB_CAPSULE_VOLUME*)pHob;
+// 1. attempt to locate Capsule by GUID guidAmiCapsuleHob
+ while (!EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_GUID_EXTENSION, &pHob)))
+ {
+ if((pHob->Header.HobType == EFI_HOB_TYPE_GUID_EXTENSION)&&
+ !(guidcmp(&((AMI_CAPSULE_HOB*)pHob)->CapsuleGuid, &gFWCapsuleGuid)))
+ {
+ PEI_TRACE((-1, PeiServices, "FW Capsule found in GUIDed Capsule Hob\n"));
+ gCapsuleLength = ((AMI_CAPSULE_HOB*)pHob)->CapsuleLength;
+ gCapsuleAddress = (EFI_PHYSICAL_ADDRESS)(((AMI_CAPSULE_HOB*)pHob)->CapsuleData);
+ return EFI_SUCCESS;
+ }
+ }
+// 2. attempt to locate capsule volume hob
+ while (!EFI_ERROR(FindNextHobByType(EFI_HOB_TYPE_CV, &pHob1)))
+ {
+ // if capsule volume hob is found, determine the capsule's location
+ CapsuleAddress = pHob1->BaseAddress;
+ CapsuleLength = pHob1->Length;
+ FWCapsuleVolume = (EFI_CAPSULE_HEADER*) CapsuleAddress;
+ if(CapsuleLength != 0 && FWCapsuleVolume->CapsuleImageSize <= CapsuleLength &&
+ !(guidcmp(&(FWCapsuleVolume->CapsuleGuid), &gFWCapsuleGuid)))
+ {
+ PEI_TRACE((-1, PeiServices, "FW Capsule found in Capsule Volume Hob\n"));
+ gCapsuleLength = CapsuleLength;
+ gCapsuleAddress = CapsuleAddress;
+ return EFI_SUCCESS;
+ }
+ }
+
+ PEI_TRACE((-1,PeiServices, "FW capsule HOB not found\n"));
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: LoadRecoveryCapsule
+//
+// Description: LoadRecoveryCapsule function of EFI_PEI_RECOVERY_MODULE_PPI
+// ppi. RecoveryDeviceOrder is a list of guids; each guid
+// represents a type of recovery device. We go through
+// this list and call FindRecoveryDevice for each type of
+// device.
+// -This function should not be confused with LoadRecoveryCapsule
+// function of the EFI_PEI_DEVICE_RECOVERY_MODULE_PPI ppi.
+// -Called by DxeIpl.
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LoadRecoveryCapsule(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN struct _EFI_PEI_RECOVERY_MODULE_PPI *This
+)
+{
+ EFI_STATUS Status;
+ static EFI_GUID RecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ RECOVERY_IMAGE_HOB *pRecoveryHob;
+ UINTN Size;
+ EFI_PHYSICAL_ADDRESS CapsuleAddress;
+
+ PEI_PROGRESS_CODE(PeiServices,PEI_RECOVERY_STARTED);
+
+ PEI_TRACE((TRACE_DXEIPL, PeiServices, "Loading Recovery Image..."));
+
+// Locate Capsule Hob
+ if(!gCapsuleAddress || !gCapsuleLength) return EFI_NOT_FOUND;
+
+ //create HOB that describes location of the Recovery image
+ Status = (*PeiServices)->CreateHob(
+ PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ sizeof(RECOVERY_IMAGE_HOB), &pRecoveryHob
+ );
+ pRecoveryHob->Header.Name = RecoveryHobGuid;
+ pRecoveryHob->Address = 0;
+
+// Size = (UINTN)((APTIO_FW_CAPSULE_HEADER*)gFwCapsule)->CapHdr.CapsuleImageSize;
+ Size = (UINTN)gCapsuleLength;
+ CapsuleAddress = (EFI_PHYSICAL_ADDRESS)gCapsuleAddress;
+ Status = VerifyFwImage(PeiServices, (VOID**)&CapsuleAddress, (UINT32*)&Size,(UINT32*)&pRecoveryHob->FailedStage );
+ pRecoveryHob->Status = (UINT8)Status;
+ pRecoveryHob->Address = CapsuleAddress;
+ if (EFI_ERROR(Status)) {
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_INVALID_CAPSULE, EFI_ERROR_MAJOR | Status);
+ }
+// < 4.6.5.4
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION < 0x4028e
+ else{
+ // DxeIpl from 4.6.5.4. will publish Dxe FV
+ Status = ReportFV2Dxe((VOID *)CapsuleAddress, PeiServices);
+ }
+#endif
+
+ if (EFI_ERROR(Status)) {
+ PEI_ERROR_CODE(PeiServices, PEI_RECOVERY_NO_CAPSULE, EFI_ERROR_MAJOR);
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: EFICapsuleRecoveryPeimEntry
+//
+// Description: Entry point. Installs EFI_PEI_RECOVERY_MODULE_PPI ppi
+// (which has function LoadRecoveryCapsule).
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+EFICapsuleRecoveryPeimEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+// Change the Boot Mode to Recovery from S3_RESUME/BOOT_ON_FLASH_UPDATE
+ Status = (*PeiServices)->GetBootMode(PeiServices, &BootMode);
+ PEI_TRACE((-1, PeiServices, "FW Capsule Recovery Module, BootMode 0x%x\n", BootMode));
+ if(BootMode == BOOT_ON_S3_RESUME || BootMode == BOOT_ON_FLASH_UPDATE)
+ {
+// Locate Capsule Hob
+ Status = FindFWCapsuleHOB(PeiServices);
+ if (EFI_ERROR(Status) || !gCapsuleAddress || !gCapsuleLength) {
+// Capsule not found:
+// Change the Boot Mode to BOOT_WITH_FULL_CONFIGURATION from BOOT_ON_FLASH_UPDATE
+ BootMode = BOOT_WITH_FULL_CONFIGURATION;
+ Status = (*PeiServices)->SetBootMode(PeiServices, BootMode);
+ } else {
+ Status = (*PeiServices)->InstallPpi(PeiServices,RecoveryPpiList);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ }
+ PEI_TRACE((-1, PeiServices, "\tchange mode to 0x%x\n",BootMode));
+ }
+
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014 American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs
new file mode 100644
index 0000000..85dc91e
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/EfiCapsuleRecovery.dxs
@@ -0,0 +1,89 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.dxs 6 3/18/14 3:01p Alexp $
+//
+// $Revision: 6 $
+//
+// $Date: 3/18/14 3:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/EfiCapsuleRecovery.dxs $
+//
+// 6 3/18/14 3:01p Alexp
+// set 2014 in file hdr & ftr
+//
+// 5 5/31/12 1:18p Alexp
+// EIP74625:New Capsule PPI required by latest Intel's MRC code
+// New PPI GUID;
+// Capsule_2_0 Mailbox does not need extra Cap Hdr
+// EIP90678: MonotonicCounter variable guid changed
+// Use gAmiGlobalVariableGuid
+//
+// 4 11/21/11 5:49p Alexp
+// include optional GUID dependenccy on Intel Misc Framework
+// PEI_CAPSULE_PPI_GUID
+//
+// 3 11/17/11 10:02a Alexp
+// include dependency on AMI_DIGITAL_SIG PPI
+//
+// 2 7/20/11 7:16p Alexp
+// remove dependency on Capsule module
+//
+// 1 7/01/11 4:39p Alexp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Recovery.dxs
+//
+// Description: Dependancy expression for the component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <PPI/LoadFile.h>
+#include <PPI/CryptoPPI.h>
+#include <FlashUpd.h>
+// AMI Capsule PPI (deprecated)
+#define EFI_PEI_CAPSULE_PPI_GUID \
+ { 0x066785b1, 0xedb8, 0x46dc, 0x84, 0x2f, 0x57, 0x44, 0x04, 0xb8, 0x69, 0x2f }
+// Intel Misc Framework PEI_CAPSULE_PPI_GUID
+#define PEI_CAPSULE_PPI_GUID \
+ { 0x3acf33ee, 0xd892, 0x40f4, 0xa2, 0xfc, 0x38, 0x54, 0xd2, 0xe1, 0x32, 0x3d }
+DEPENDENCY_START
+EFI_PEI_FV_FILE_LOADER_GUID
+AND
+EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+AND
+EFI_PEI_BOOT_IN_FLASH_UPDATE_MODE_PEIM_PPI
+AND
+(EFI_PEI_CAPSULE_PPI_GUID OR PEI_CAPSULE_PPI_GUID)
+AND
+AMI_DIGITAL_SIGNATURE_PPI_GUID
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c b/Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c
new file mode 100644
index 0000000..112f655
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/IsSecRecovery.c
@@ -0,0 +1,390 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/IsSecRecovery.c 18 10/29/14 5:11p Alexp $
+//
+// $Revision: 18 $
+//
+// $Date: 10/29/14 5:11p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/IsSecRecovery.c $
+//
+// 18 10/29/14 5:11p Alexp
+// GetFlashUpdateVar() - set default value of CounterHi= -1
+// for cases when MC variable is available only in pre-boot.
+//
+// 15 3/18/14 3:02p Alexp
+// year '2014' in file hdr & ftr
+//
+// 14 8/12/13 4:36p Alexp
+// fix ChangeBootModeAfterEndofMrc() to change BootMode and install PPI if
+// CApsule Upd is pending
+//
+// 13 4/01/13 9:37a Alexp
+// exclude capsule recovery code if FWCAPSULE_RECOVERY_SUPPORT is 0
+//
+// 12 2/27/13 6:43p Alexp
+// GetFlashUpdateVar() to check for AMI Capsule Variable
+// if Ami FwCapsule is pending and update boot mode to
+// BOOT_ON_FLASH_UPDATE
+//
+// 11 7/09/12 5:30p Alexp
+// IsFlashUpdateS3Capsule
+// Install Capsule Recovery Event whether by checking FlashUpd variable
+// or if BOOT_ON_FLASH_UPDATE. It may've already been set by Capsule PEI
+//
+//
+// 9 6/01/12 10:44a Alexp
+// EIP74625:New Capsule PPI required by latest Intel's MRC code
+// New PPI GUID;
+// Capsule_2_0 Mailbox does not need extra Cap Hdr
+// EIP90678: MonotonicCounter variable guid changed
+// Use AMI_GLOBAL_VARIABLE_GUID
+//
+// 7 12/08/11 4:51p Alexp
+// Change method of calling IsSecRecovery init routine.
+// Replaced IsSecRecovery PEI with function call IsFlashUpdateRecovery
+// from PeiCoreInitialize
+//
+// 6 11/10/11 7:10p Alexp
+// minor optimizations
+//
+// 5 11/03/11 6:41p Alexp
+// Add provision to build file as .FFS with new function to install
+// callback on gAmiPeiAfterMrcGuid event
+// Update BootMode to BOOT_ON_FLASH_UPDATE if Capsule update is detected
+//
+// 4 10/17/11 11:33a Alexp
+// Replace old method to detect FlashUpd with single IsFlashUpdate() hook
+// to be called from SbPei.c ->GetBootMode
+//
+// 3 10/11/11 12:23p Alexp
+// removed comments
+//
+// 2 7/20/11 7:16p Alexp
+// remove dependency on Capsule module
+//
+// 1 7/01/11 4:39p Alexp
+//
+//
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: IsSecRecovery.c - PEI recovery services
+//
+// Description: File contains hook to determine if BootMode needs to follow
+// recovery path due to pending Flash Update
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+// Module specific Includes
+#include "Efi.h"
+#include "Pei.h"
+#include "token.h"
+#include <AmiPeiLib.h>
+#include <Hob.h>
+#include <Ppi\ReadOnlyVariable.h>
+#include <FlashUpd.h>
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+#include "AmiCertificate.h"
+#include <Capsule.h>
+
+// Definitions
+static EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID;
+static EFI_GUID gEfiCapsuleVendorGuid = EFI_CAPSULE_AMI_GUID;
+#endif
+static EFI_GUID gFlashUpdBootModeGuid = EFI_PEI_BOOT_IN_FLASH_UPDATE_MODE_PEIM_PPI;
+// PPI that are installed
+static EFI_PEI_PPI_DESCRIPTOR mFlashUpdateModePpi[] =
+ {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gFlashUpdBootModeGuid,
+ NULL
+};
+
+static EFI_GUID gPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+static EFI_GUID gFlashUpdGuid = FLASH_UPDATE_GUID;
+// must be defined in AmiLib.h (Core 4.6.5.4 +)
+#if defined(AMI_GLOBAL_VARIABLE_GUID)
+static EFI_GUID guidVar = AMI_GLOBAL_VARIABLE_GUID;
+#else
+static EFI_GUID guidVar = EFI_GLOBAL_VARIABLE;
+#endif
+
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+///////////////////////////////////////////////////////
+// {64C96700-6B4C-480C-A3E1-B8BDE8F602B2}
+#define AMI_PEI_AFTER_MRC_GUID \
+ {0x64c96700, 0x6b4c, 0x480c, 0xa3, 0xe1, 0xb8, 0xbd, 0xe8, 0xf6, 0x2, 0xb2}
+
+static EFI_GUID gAmiPeiAfterMrcGuid = AMI_PEI_AFTER_MRC_GUID;
+
+EFI_STATUS ChangeBootModeAfterEndofMrc (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *InvokePpi
+);
+
+static EFI_PEI_NOTIFY_DESCRIPTOR EndOfMrcNotifyList[] = {
+ { EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | \
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, \
+ &gAmiPeiAfterMrcGuid, ChangeBootModeAfterEndofMrc },
+};
+#endif
+//--------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFlashUpdateVar
+//
+// Description:
+// This function checks if recovery flow is needed due to pending Flash Update
+//
+// Input:
+// PeiServices Pointer to the PEI services table
+//
+// Output:
+// TRUE - recovery is requested
+// FALSE - recovery is not requested
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+GetFlashUpdateVar (
+ EFI_PEI_SERVICES **PeiServices,
+ AMI_FLASH_UPDATE_BLOCK *FlashUpdDesc,
+ UINT32 *CounterHi
+){
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable;
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+ EFI_PHYSICAL_ADDRESS IoData;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *pCapsuleMailboxPtr;
+#endif
+// Check FlashOp variable for Recovery Flash operation
+// Detect if we are in Flash Update mode and set some recovery global variables
+// Read "FlashOp" Variable to update global RecoveryFileName, Size
+ Status = (*PeiServices)->LocatePpi( PeiServices,
+ &gPeiReadOnlyVariablePpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable );
+ if(EFI_ERROR(Status))
+ return FALSE;
+
+ Size = sizeof(AMI_FLASH_UPDATE_BLOCK);
+ Status = ReadOnlyVariable->GetVariable( PeiServices,
+ FLASH_UPDATE_VAR,
+ &gFlashUpdGuid,
+ NULL,
+ &Size,
+ FlashUpdDesc );
+ if (!EFI_ERROR(Status))
+ {
+ Size = sizeof(UINT32);
+ Status = ReadOnlyVariable->GetVariable(PeiServices,
+ L"MonotonicCounter",
+ &guidVar,
+ NULL,
+ &Size,
+ CounterHi);
+ if (EFI_ERROR(Status) || FlashUpdDesc->MonotonicCounter == 0xffffffff)
+ *CounterHi = 0xffffffff;
+
+ return TRUE;
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+ } else {
+ Size=sizeof(EFI_PHYSICAL_ADDRESS);
+ Status = ReadOnlyVariable->GetVariable( PeiServices,
+ CAPSULE_UPDATE_VAR, &gEfiCapsuleVendorGuid,
+ NULL,
+ &Size,
+ &IoData );
+ if (!EFI_ERROR(Status))
+ {
+ // verify the FW capsule is in memory. May first check if pCapsuleMailboxPtr == IoData
+ pCapsuleMailboxPtr = (EFI_CAPSULE_BLOCK_DESCRIPTOR*)IoData;
+ CapsuleHeader = (EFI_CAPSULE_HEADER*)pCapsuleMailboxPtr[0].DataBlock;
+ //
+ // Compare GUID with APTIO_FW_CAPSULE_GUID
+ //
+ if (guidcmp (&CapsuleHeader->CapsuleGuid, &gFWCapsuleGuid)==0) {
+ FlashUpdDesc->FlashOpType = FlCapsule;
+ return TRUE;
+ }
+ }
+#endif
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFlashUpdate
+//
+// Description:
+// This function returns proper BootMode if Flash Update mode is pending
+//
+// Input:
+// **PeiServices - Pointer to the PEI services table
+// *BootMode - Pointer to a BootMode variable
+//
+// Output:
+// BOOLEAN
+// TRUE - recovery is requested
+// FALSE - recovery is not requested
+// BootMode - updated BootMode value if TRUE
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IsFlashUpdate(
+ EFI_PEI_SERVICES **PeiServices,
+ EFI_BOOT_MODE *BootMode
+){
+ UINT32 CounterHi = 0;
+ AMI_FLASH_UPDATE_BLOCK FlashUpdDesc;
+
+ FlashUpdDesc.MonotonicCounter = 0;
+ FlashUpdDesc.FlashOpType = FlDisabled;
+
+//SetMode should have set FlashUpd var even if no MC var detected.
+// MC check should fail Recovery
+ if(/**BootMode != BOOT_IN_RECOVERY_MODE && */
+ GetFlashUpdateVar(PeiServices, &FlashUpdDesc, &CounterHi) &&
+ CounterHi==(UINT32)FlashUpdDesc.MonotonicCounter)
+ {
+ if(FlashUpdDesc.FlashOpType == FlRecovery)
+ {
+ *BootMode = BOOT_IN_RECOVERY_MODE;
+ return TRUE;
+ }
+ if(FlashUpdDesc.FlashOpType == FlCapsule/* && *BootMode == BOOT_ON_S3_RESUME*/)
+ {
+ *BootMode = BOOT_ON_FLASH_UPDATE;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsFlashUpdateRecovery
+//
+// Description:
+// This function checks if recovery flow is needed due to pending Flash Update
+//
+// Input:
+// PeiServices Pointer to the PEI services table
+//
+// Output:
+// TRUE - recovery is requested
+// FALSE - recovery is not requested
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IsFlashUpdateRecovery (
+ EFI_PEI_SERVICES **PeiServices
+){
+ EFI_BOOT_MODE BootMode;
+ if(IsFlashUpdate(PeiServices, &BootMode) && BootMode == BOOT_IN_RECOVERY_MODE)
+ return TRUE;
+ return FALSE;
+}
+
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ChangeBootModeAfterEndofMrc
+//
+// Description: Change BootMode to BOOT_ON_FLASH_UPDATE if Capsule update is pending
+//
+// Input: PeiServices - Pointer to the PEI services table
+// NotifyDescriptor - Pointer to the descriptor for the
+// notification event.
+// InvokePpi - Pointer to the PPI that was installed
+//
+// Output: EFI_STATUS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ChangeBootModeAfterEndofMrc (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor,
+ IN VOID *InvokePpi )
+{
+ EFI_STATUS Status;
+ EFI_BOOT_MODE BootMode;
+
+ Status = (*PeiServices)->GetBootMode( PeiServices, &BootMode );
+// if (!EFI_ERROR(Status) && (BootMode != BOOT_IN_RECOVERY_MODE))
+// BOOT_ON_FLASH_UPDATE may already be set by Capsule PEI
+ if(!EFI_ERROR(Status) && (BootMode == BOOT_ON_S3_RESUME || BootMode == BOOT_ON_FLASH_UPDATE))
+ {
+ // Change the Boot Mode to Recovery from S3_RESUME/BOOT_ON_FLASH_UPDATE
+ if (IsFlashUpdate(PeiServices, &BootMode) && BootMode == BOOT_ON_FLASH_UPDATE)
+ (*PeiServices)->SetBootMode(PeiServices, BootMode);
+ }
+ //install Flash Update Boot Mode PPI
+ if(BootMode == BOOT_ON_FLASH_UPDATE)
+ (*PeiServices)->InstallPpi( PeiServices, mFlashUpdateModePpi);
+
+ return EFI_SUCCESS;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: IsFlashUpdateCapsuleInit
+//
+// Description: Installs callback to ChangeBootModeAfterEndofMrc
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+IsFlashUpdateCapsuleInit (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+ return (*PeiServices)->NotifyPpi( PeiServices, EndOfMrcNotifyList);
+#else
+ return EFI_SUCCESS;
+#endif
+
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif
new file mode 100644
index 0000000..aecb88d
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "Secure Flash Update"
+ category = ModulePart
+ LocalRoot = "Core\EM\SecurityPkg\SecFlashUpd\"
+ RefName = "SecFlashUpd"
+[files]
+"SecFlashUpd.sdl"
+"SecFlashUpd.mak"
+"VerifyFwCapsule.c"
+"IsSecRecovery.c"
+"EfiCapsuleRecovery.c"
+"EfiCapsuleRecovery.dxs"
+"SecFlashUpdDxe.c"
+"SecFlashUpdDxe.dxs"
+[parts]
+"FlashUpdInc"
+<endComponent>
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak
new file mode 100644
index 0000000..f44a380
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.mak
@@ -0,0 +1,176 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpd.mak 17 9/30/14 3:34p Alexp $
+#
+# $Revision: 17 $
+#
+# $Date: 9/30/14 3:34p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpd.mak $
+#
+# 17 9/30/14 3:34p Alexp
+# EIP185686:Build error with Recovery_SUPPORT = 0
+#
+# 16 3/18/14 3:02p Alexp
+# year '2014' in file hdr & ftr
+#
+# 15 4/19/13 4:48p Alexp
+# add external define
+#
+# 14 11/21/12 10:36a Alexp
+# don not link cryptolib
+#
+# 13 10/31/12 10:09a Alexp
+# EIP#100418: Make SecureFlashPkg build independent
+# from Core's ReFlash driver Support
+#
+# 12 9/06/12 6:15p Alexp
+# EIP#100418: Make SecureFlashPkg build independant from ReFlash-Support
+#
+# 11 7/13/12 12:11p Alexp
+# Replace custom _EFI_CAPSULE_BLOCK_DESCRIPTOR_ with
+# generic EFI_CAPSULE_BLOCK_DESCRIPTOR
+#
+# 10 5/18/12 4:22p Alexp
+# 1. Link Crypto Library with VerifyFwCap in Recovery boot flow.Use Hash
+# functions only
+# 2. Pass SEC_FLASH_GUID_DEFINES containing unique FwCap Ffs Guid and
+# Section guids
+#
+# 9 12/08/11 4:51p Alexp
+# Change method of calling IsSecRecovery init routine ->
+# ->Replaced IsSecRecovery PEI with function call IsFlashUpdateRecovery
+# from PeiCoreInitialize
+#
+# 8 11/10/11 4:36p Alexp
+# Add build rules to generate SecFlashDxe driver
+#
+# 7 11/03/11 6:38p Alexp
+# create build rules for IsSecRecovery.ffs PEI module
+#
+# 6 10/17/11 11:33a Alexp
+# Replace old method to detect FlashUpd with single IsFlashUpdate() hook
+# to be called from SbPei.c ->GetBootMode
+#
+# 5 8/22/11 5:22p Alexp
+# removed build rules for SecFlash Setup pages
+#
+# 4 8/18/11 4:45p Alexp
+# removed unused build target:SecFlashUpdDxeBin
+#
+# 3 8/05/11 3:18p Alexp
+# removed Flash Policy driver, files, Protocol; Flash Policy is hardwired
+# via SDL
+#
+# 2 7/20/11 7:16p Alexp
+# remove dependency on Capsule module
+#
+# 1 7/01/11 4:39p Alexp
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: SecFlashUpd.mak
+#
+# Description:
+#
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+SecureModule: SecureFlashUpdate
+
+SecureFlashUpdate : $(BUILD_DIR)\SecFlashUpd.mak SecFlashUpdDxeBin \
+!IF $(Recovery_SUPPORT) == 1
+FwCapsuleRecoveryPPIBin
+!ENDIF
+
+$(BUILD_DIR)\SecFlashUpd.mak : $(SecFlashUpd_DIR)\SecFlashUpd.cif $(SecFlashUpd_DIR)\SecFlashUpd.mak $(BUILD_RULES)
+ $(CIF2MAK) $(SecFlashUpd_DIR)\SecFlashUpd.cif $(CIF2MAK_DEFAULTS)
+
+BUILD_SecFlashUpd_DIR = $(BUILD_DIR)\$(SecFlashUpd_DIR)
+
+!IFDEF ReFlash_SUPPORT
+SecFlashUpd_DEFINES= \
+ /D ReFlash_SUPPORT=$(ReFlash_SUPPORT)
+!ENDIF
+
+SecFlashUpd_INCLUDES= \
+ /I $(SecFlashUpd_DIR)\
+ $(SEC_FLASH_GUID_DEFINES)\
+!IFDEF ReFlash_DIR
+ /I $(ReFlash_DIR)\
+!ENDIF
+ /I$(CORE_DIR)
+
+AMI_CSP_LIB_INCLUDE_FILES = "Include\FlashUpd.h" + \
+$(AMI_CSP_LIB_INCLUDE_FILES)
+
+AMI_CSP_LIB_OBJS = $(AMI_CSP_LIB_OBJS) \
+$(BUILD_DIR)\IsSecRecovery.obj
+#-----------------------------------------------------------------------
+# Auxilary library files compilation
+#-----------------------------------------------------------------------
+RecoveryBin FwCapsuleRecoveryPPIBin : $(BUILD_DIR)\VerifyFwCapsule.obj $(CRYPTOLIBPEI)
+
+{$(SecFlashUpd_DIR)}.c{$(BUILD_DIR)}.obj::
+ $(CC) $(CFLAGS) $(SEC_FLASH_GUID_DEFINES) /I $(SecFlashUpd_DIR) /Fo$(BUILD_DIR)\ $<
+
+SecFlashUpdDxeBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecFlashUpd.mak all\
+ NAME=SecFlashUpdDxe\
+ MAKEFILE=$(BUILD_DIR)\SecFlashUpd.mak \
+ GUID=A0EF80E3-F9AB-4CBA-98FD-704620F4048D \
+ ENTRY_POINT=SecFlashUpdDxe_Init\
+ DEPEX1=$(SecFlashUpd_DIR)\SecFlashUpdDxe.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX\
+ "MY_INCLUDES=$(SecFlashUpd_INCLUDES) "\
+ "CFLAGS=$(CFLAGS) $(SecFlashUpd_DEFINES)" \
+ OBJECTS="$(BUILD_SecFlashUpd_DIR)\SecFlashUpdDxe.obj" \
+ TYPE=RT_DRIVER COMPRESS=1
+
+!IF $(CORE_COMBINED_VERSION) < 0x4028e
+FwCapsuleRecoveryPPIBin : $(AMIPEILIB) $(BUILD_DIR)\$(BOARD_DIR)\ReportFV2.obj
+!ELSE
+FwCapsuleRecoveryPPIBin : $(AMIPEILIB)
+!ENDIF
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecFlashUpd.mak all\
+ NAME=FwCapsuleRecoveryPPI\
+ MAKEFILE=$(BUILD_DIR)\SecFlashUpd.mak \
+ GUID=83FA5AED-5171-4949-BDC9-0CBC9E123663 \
+ ENTRY_POINT=EFICapsuleRecoveryPeimEntry \
+# "MY_INCLUDES=$(SecFlashUpd_INCLUDES) /I $(Recovery_DIR)"\
+ "MY_INCLUDES=$(SecFlashUpd_INCLUDES)"\
+ OBJECTS="$(BUILD_SecFlashUpd_DIR)\EfiCapsuleRecovery.obj" \
+ DEPEX1=$(SecFlashUpd_DIR)\EfiCapsuleRecovery.DXS DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl
new file mode 100644
index 0000000..a21f769
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpd.sdl
@@ -0,0 +1,152 @@
+TOKEN
+ Name = "SecFlashUpd_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Secured FlashUpdate support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "FlashUpdatePolicy"
+ Value = "7"
+ Help = "Flash update policy bitmap\0-Disabled, \bit0-Cold Reboot(recovery),bit1-Warm Reboot(capsule),bit2-Runtime,\bits 3..31-Reserved"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BBUpdatePolicy"
+ Value = "7"
+ Help = "Select Boot Block (CRTM) Flash update policy."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IGNORE_IMAGE_ROLLBACK"
+ Value = "0"
+ Help = "1-FW Capsule Validate logic will skip image Revision check"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK"
+ Value = "0"
+ Help = "When set, FW Capsule Validate logic will skip image Revision check during Runtime updates"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK"
+ Value = "1"
+ Help = "Force Ignore_runtime. if master Ignore_image_rollback is set"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "IGNORE_IMAGE_ROLLBACK" "=" "1"
+End
+
+TOKEN
+ Name = "RUNTIME_SECURE_UPDATE_FLOW"
+ Value = "1"
+ Help = "Force security checks during runtime SMM flash update process"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWCAPSULE_RECOVERY_SUPPORT"
+ Value = "0"
+ Help = "Enable APTIO FW Capsule recovery PPI"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWCAPSULE_RECOVERY_SUPPORT"
+ Value = "1"
+ Help = "Don't modify this value!"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "Recovery_SUPPORT" "=" "1"
+ Token = "CAPSULE_SUPPORT" "=" "1"
+ Token = "WARM_BOOT_SUPPORT" "=" "1"
+ Token = "UEFI_2_0_CAPSULE" "=" "1"
+End
+
+TOKEN
+ Name = "FWCAPSULE_RECOVERY_SUPPORT"
+ Value = "1"
+ Help = "Don't modify this value!"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "Recovery_SUPPORT" "=" "1"
+ Token = "CAPSULE2_0_SUPPORT" "=" "1"
+ Token = "SUPPORT_UPDATE_CAPSULE_RESET" "=" "1"
+End
+
+TOKEN
+ Name = "FWCAPSULE_2_0_SUPPORT"
+ Value = "1"
+ Help = "Older Aptio Capsule formats expected extra Cap Hdr in Mailbox"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "CAPSULE2_0_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "FLASH_LOCK_EVENT_NOTIFY"
+ Value = "1"
+ Help = "1:Issue Flash Ready to Lock Event"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "SecFlashUpd_DIR"
+ Help = "Path to FlashUpdate Module in Project"
+End
+
+MODULE
+ File = "SecFlashUpd.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FwCapsuleRecoveryPPI.ffs"
+ Parent = "FV_BB"
+ Token = "FWCAPSULE_RECOVERY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IsFlashUpdateRecovery,"
+ Parent = "IsRecovery"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "IsFlashUpdateCapsuleInit,"
+ Parent = "PeiCoreInitialize"
+ Token = "FWCAPSULE_RECOVERY_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "FwCapsuleInfo"
+ Parent = "AmiGetRecoveryFileInfo"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SecFlashUpdDxe.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c
new file mode 100644
index 0000000..8ce7d3f
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.c
@@ -0,0 +1,276 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.c 10 3/18/14 3:01p Alexp $
+//
+// $Revision: 10 $
+//
+// $Date: 3/18/14 3:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.c $
+//
+// 10 3/18/14 3:01p Alexp
+// set 2014 in file hdr & ftr
+//
+// 9 5/09/13 10:37a Alexp
+// EIP#123379 : Disabling FLASH_LOCK_EVENT_NOTIFY causes build error
+//
+// 8 10/31/12 1:36p Alexp
+// removed #ifdef for CAPSULE_SUPPORTbefore checks for capsule variable.
+//
+// 7 9/06/12 6:15p Alexp
+// EIP#100418: Make SecureFlashPkg build independant from ReFlash-Support
+//
+// 6 1/06/12 10:37a Alexp
+// Streamlined the code for Setup.AutoFlash variable update if FlashUpdate
+// is pending
+//
+// 4 11/17/11 10:02a Alexp
+// Use Core 4.6.5.2 provided name AMI_EVENT_FLASH_WRITE_LOCK as GUID
+// define for Flash Lock event
+//
+// 3 11/10/11 4:38p Alexp
+// 1. UpdateAutoFlash() updates the AutoFlash Variable installed by
+// ReFlash driver in Recovery/Flash Update flows
+// 2. Issue FlashReadyToLock Event notification based on the Flash Update
+// policy.
+//
+// 2 7/20/11 7:16p Alexp
+// remove dependency on Capsule module
+//
+// 1 7/01/11 4:39p Alexp
+//
+//
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <AmiHobs.h>
+#include <FlashUpd.h>
+
+#include <Flash.h>
+#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1)
+#include "ReFlash.h"
+#endif
+#include "Capsule.h"
+
+//
+// Global variables
+//
+extern EFI_BOOT_SERVICES *pBS;
+
+#if FLASH_LOCK_EVENT_NOTIFY == 1
+
+VOID *gSbHobList = NULL;
+static EFI_GUID gHobListGuid = HOB_LIST_GUID;
+
+// Core 4.6.5.2 sources GUID
+#ifndef AMI_EVENT_FLASH_WRITE_LOCK
+// {49D34AE7-1348-4551-8F71-467D8C0E4EF5}
+#define AMI_EVENT_FLASH_WRITE_LOCK \
+ { 0x49D34AE7, 0x9454, 0x4551, 0x8F, 0x71, 0x46, 0x7D, 0x8C, 0x0E, 0x4E, 0xF5 }
+#endif
+
+#define BDS_CONNECT_DRIVERS_PROTOCOL_GUID \
+ { 0x3aa83745, 0x9454, 0x4f7a, 0xa7, 0xc0, 0x90, 0xdb, 0xd0, 0x2f, 0xab, 0x8e }
+
+EFI_GUID gBiosLockEnableEventGuid = AMI_EVENT_FLASH_WRITE_LOCK;
+EFI_GUID gBdsConnectDriversProtocolGuid = BDS_CONNECT_DRIVERS_PROTOCOL_GUID;
+
+EFI_EVENT mSecureModEvent;
+VOID *mSecureModReg;
+#endif //#if FLASH_LOCK_EVENT_NOTIFY == 1
+
+//----------------------------------------------------------------------------
+// Function definitions
+//----------------------------------------------------------------------------
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadyToLockCallback
+//
+// Description: ready to Lock Flash part
+// Signal a event for ready to lock.
+//
+// Input: Event - The event that triggered this notification function
+// ParentImageHandle - Pointer to the notification functions context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if FLASH_LOCK_EVENT_NOTIFY == 1
+VOID
+ReadyToLockCallback (
+ EFI_EVENT Event,
+ VOID *ParentImageHandle
+ )
+{
+ EFI_HANDLE Handle = NULL;
+ TRACE((-1,"\nSecure Fl Upd: FlashReadyToLock callback\n"));
+
+// Signal Event.....
+ pBS->InstallProtocolInterface (
+ &Handle, &gBiosLockEnableEventGuid, EFI_NATIVE_INTERFACE,NULL
+ );
+ pBS->UninstallProtocolInterface (
+ Handle,&gBiosLockEnableEventGuid, NULL
+ );
+ //
+ //Kill the Event
+ //
+ pBS->CloseEvent(Event);
+}
+
+#endif //#if FLASH_LOCK_EVENT_NOTIFY == 1
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateAutoFlash
+//
+// Description: This is the standard EFI driver entry point called for
+// Recovery flash module initlaization
+// Input: IN EFI_HANDLE ImageHandle - ImageHandle of the loaded driver
+// IN EFI_SYSTEM_TABLE SystemTable - Pointer to the System Table
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateAutoFlash ()
+{
+ EFI_STATUS Status;
+ UINT32 Attributes;
+ UINTN Size;
+#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1)
+ AUTOFLASH AutoFlash;
+ static EFI_GUID guidReFlash = RECOVERY_FORM_SET_GUID;
+#endif //#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1)
+ static EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID;
+ static EFI_GUID CapsuleBootModeGuid = EFI_CAPSULE_AMI_GUID;
+ AMI_FLASH_UPDATE_BLOCK FlashUpdDesc;
+
+// Prep the FlashOp variable
+ Attributes = 0;
+ Size = sizeof(AMI_FLASH_UPDATE_BLOCK);
+ Status = pRS->GetVariable( FLASH_UPDATE_VAR,&FlashUpdGuid,&Attributes,&Size, &FlashUpdDesc);
+ if(!EFI_ERROR(Status))
+ {
+ // Erase Flash Var
+ pRS->SetVariable (FLASH_UPDATE_VAR,&FlashUpdGuid,Attributes,0,NULL);
+ // Clear pending Capsule Update Var
+ // only if FlashOp is pending. We don't want to interfere with other types of Capsule Upd
+ Size = 0;
+ if(pRS->GetVariable(CAPSULE_UPDATE_VAR,&CapsuleBootModeGuid, &Attributes, &Size, NULL)==EFI_BUFFER_TOO_SMALL)
+ pRS->SetVariable(CAPSULE_UPDATE_VAR,&CapsuleBootModeGuid, Attributes, 0, NULL);
+#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1)
+ // Update ReFlash parameters
+ Size = sizeof(AUTOFLASH);
+ Status = pRS->GetVariable(L"Setup",&guidReFlash, &Attributes, &Size, &AutoFlash);
+ if(!EFI_ERROR(Status))
+ {
+
+ AutoFlash.UpdateNv = (FlashUpdDesc.ROMSection & (1<<FV_NV)) ? 1 : 0;
+ AutoFlash.UpdateBb = (FlashUpdDesc.ROMSection & (1<<FV_BB)) ? 1 : 0;
+ AutoFlash.UpdateMain=(FlashUpdDesc.ROMSection & (1<<FV_MAIN)) ? 1 : 0;
+ // EC block
+#if (defined EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT) && (EC_FIRMWARE_UPDATE_INTERFACE_SUPPORT == 1)
+ AutoFlash.UpdateEC =(FlashUpdDesc.ROMSection & (1<<ROM_EC)) ? 1 : 0;
+#endif
+ pRS->SetVariable(L"Setup",&guidReFlash, Attributes, sizeof(AUTOFLASH), &AutoFlash);
+ }
+#endif //#if (defined ReFlash_SUPPORT) && (ReFlash_SUPPORT == 1)
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SecFlashUpdDxe_Init
+//
+// Description: Entry point of Flash Update Policy driver
+//
+// Input: EFI_HANDLE ImageHandle,
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SecFlashUpdDxe_Init (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = UpdateAutoFlash();
+///////////////////////////////////////////////////////////////////////////////
+//
+// Create Flash Lock event.
+//
+///////////////////////////////////////////////////////////////////////////////
+#if FLASH_LOCK_EVENT_NOTIFY == 1
+ // Get Hob List
+ gSbHobList = GetEfiConfigurationTable(SystemTable, &gHobListGuid);
+ if (!gSbHobList)
+ return EFI_INVALID_PARAMETER;
+
+// Locking SPI before BDS Connect on normal boot
+ if (((EFI_HOB_HANDOFF_INFO_TABLE*)gSbHobList)->BootMode!=BOOT_IN_RECOVERY_MODE &&
+ ((EFI_HOB_HANDOFF_INFO_TABLE*)gSbHobList)->BootMode!=BOOT_ON_FLASH_UPDATE
+ )
+ Status = RegisterProtocolCallback ( &gBdsConnectDriversProtocolGuid, \
+ ReadyToLockCallback, \
+ NULL, \
+ &mSecureModEvent, \
+ &mSecureModReg );
+// Locking SPI after ReFlash(BDS) if in Recoovery/Flash Upd mode
+ else
+ Status = CreateReadyToBootEvent ( TPL_CALLBACK,
+ ReadyToLockCallback,
+ NULL,
+ &mSecureModEvent);
+
+ ASSERT_EFI_ERROR (Status);
+#endif
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs
new file mode 100644
index 0000000..f55eee7
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/SecFlashUpdDxe.dxs
@@ -0,0 +1,58 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.dxs 4 3/18/14 3:01p Alexp $
+//
+// $Revision: 4 $
+//
+// $Date: 3/18/14 3:01p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/SecFlashUpdDxe.dxs $
+//
+// 4 3/18/14 3:01p Alexp
+// set 2014 in file hdr & ftr
+//
+// 3 11/10/11 4:38p Alexp
+// 1. UpdateAutoFlash() updates the AutoFlash Variable installed by
+// ReFlash driver in Recovery/Flash Update flows
+// 2. Issue FlashReadyToLock Event notification based on the Flash Update
+// policy.
+//
+// 2 7/20/11 7:16p Alexp
+// remove dependency on Capsule module
+//
+// 1 7/01/11 4:39p Alexp
+//
+//**********************************************************************
+#include <Protocol/AmiDigitalSignature.h>
+
+DEPENDENCY_START
+ AMI_DIGITAL_SIGNATURE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c b/Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c
new file mode 100644
index 0000000..9bc9693
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecFlashUpd/VerifyFwCapsule.c
@@ -0,0 +1,974 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/VerifyFwCapsule.c 41 9/30/14 3:34p Alexp $
+//
+// $Revision: 41 $
+//
+// $Date: 9/30/14 3:34p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/FlashUpdate/VerifyFwCapsule.c $
+//
+// 41 9/30/14 3:34p Alexp
+// EIP185686:Build error with Recovery_SUPPORT = 0
+//
+// 40 7/03/14 10:15a Alexp
+// EIP176297: Fix bug in condition expresison inside For loops.
+//
+// [Files] VerifyFwCapsule.c
+//
+// 39 6/13/14 10:08a Alexp
+// VerifyFwCapsule(): With dummy FwKey function returns no error but with
+// set Key flag.
+// The Recovery page must display the warning and user prompt.
+//
+// 38 4/24/14 3:17p Alexp
+// Fix build error when REFLASH_INTERACTIVE is 0
+//
+// 37 3/20/14 11:34a Alexp
+// 1. EIP149817: don't override a default Recovery file name defined by
+// RECOVERY_ROM
+// 2. Add logic to ignore Capsule Verify error if dummy FwKey is detected.
+// The feature is activated only when REFLASH_INTERACTIVE mode is ON
+// 3. VerifyFwCapsule: FwCap RomImageOffset checked against max size
+// (FWCAPSULE_IMAGE_SIZE-FLASH_SIZE)
+//
+// 36 12/12/13 10:11a Alexp
+//
+// 34 8/22/13 11:36a Alexp
+// VerifyFwCertRsa2048Sha256() - Break a loop after RootCert Verify
+// if key match is found. Old code would cycle through all root certs.
+//
+// 33 8/12/13 4:35p Alexp
+// 1. Add check for an end of Certificate block
+// 2. Chnage Ignore_rollback behavior. Won't skip Project Tag check
+//
+// 32 7/11/13 3:39p Alexp
+// Removed check for FWCAPSULE_MAX_HDR_SIZE. Replaced it with fixed 0x8000
+// value
+//
+// 31 6/28/13 12:01p Alexp
+// restore logic to return FwCapsule file name as expected Recovery file
+// name
+//
+// 30 6/21/13 11:02a Alexp
+// HashFwRomMapImage() - add check for 32bit address overflow
+//
+// 29 6/12/13 3:48p Alexp
+// VerifyFwCertRsa2048Sha256() - parse multiple chained RootKey
+// certificate structures in FwCert header
+//
+// 28 5/01/13 6:16p Alexp
+// VerifyFwImage() - ignore verification if no FwKey file is detected in
+// FV_BB
+//
+// 26 2/21/13 4:00p Alexp
+// update IGNORE_IMAGE_ROLLBACK logic.
+//
+// 25 1/24/13 4:05p Alexp
+// Made IGNORE_IMAGE_ROLLBACK depend on REFLASH_INTERACTIVE
+// Disable revision rollback check if interactive flag is set
+//
+// 24 12/17/12 2:45p Alexp
+// fix cppcheck style check finds
+//
+// 23 11/21/12 10:38a Alexp
+// EIP#105015: Add support for Pkcs7# Certificates in Aptio Fw Capsule
+// update packages
+//
+// 22 11/20/12 3:32p Alexp
+// EIP[104046]: Findings from Security review on Aptio4 Image verification
+// Includes the fix for item #10: hardening of RomMap parsing oin
+// FwCapsule update
+//
+// 21 11/13/12 3:29p Alexp
+// 1. Calculate offset to RomLayout table within FwCapsHdr instead of
+// using hardwired location. Pkcs#7 cert may overlap fixed RomMap field
+// 2. Remove dependency on FWSIG_SIGNHDR flag. Use Capsule flags instead.
+//
+// 20 10/18/12 10:43a Alexp
+// VerifyFwImage:
+// sanity check for buffer overruns.
+// Applied for FwCapsules with Hdr on top of the Payload
+//
+// 19 9/18/12 6:59p Alexp
+// Bug: Recovery update was broken for FwCapsule with embedded signature
+// and FwSig_hdr token 0.
+// Fix: FindCapHdrFFS() change Ffs Hdr size testing
+//
+// 18 7/26/12 3:26p Alexp
+// replaced #if FWSIG_PADDING == 0 with #if FWSIG_SIGNHDR == 1.
+// Flag in the FwCap Hdr to switch between PKCS1_5 and PSS padding is
+// available only if #if FWSIG_SIGNHDR == 1
+//
+// 17 5/18/12 4:35p Alexp
+// 1. Add support for Embedded FwSignature file
+// 2. EIP:89687 Replace Hash PPI calls with calls to Crypto lib functions.
+// Allows to support RomMap tables in FwCaps Hdr with unlimited number of
+// entries
+// 3. VerifyFwVersion. a)Moved the call after Rom image signature is
+// verified.; b) search FID struct only in signed FVs with PEI or DXE
+// attributes
+//
+// 16 4/25/12 2:12p Alexp
+// New logic extends search for matching Platform FW Key inside Signing
+// and then RootKey
+// certificates in the Cap Hdr
+//
+// 14 3/09/12 11:16a Alexp
+// VerifyFwImage-> fixed logic to process RomMap entries.
+// Number of signed elements in RomMap may not exceed max_num_elem
+// constant.
+// Overall number of elements in th RomMap may not exceed max_num_elem x 2
+//
+// 13 2/29/12 4:11p Alexp
+// Update format of Capsule signiing:
+// 1. Entire Cap Hdr and FW_Cert Hdr are included in SigCert Signature
+// calculation. Improves Cap image security
+// 2. RootKey signs only SignKey buffer and not entire Sign Certificate.
+// No nee dfor resigning of RootCert each time SignCert is being created
+//
+// 12 2/13/12 2:07p Alexp
+// GetFidData: Use 1 byte alligned pointer in searching "Section Guid".
+// Fixes the issue with RomMap entries that are not 4 byte alligned
+//
+// 11 12/29/11 3:59p Alexp
+// VerifyProjectId().
+// Calculate size of ProjectId string based on SDL Token PROJECT_TAG
+//
+// 10 11/30/11 8:02p Alexp
+// FW Revision searched inside FID structure.
+// Simplified the search throughout FW block by 4byte aligned $FID
+// signature only
+//
+// 9 11/08/11 3:08p Alexp
+// match the name "FW"CAPSULE_FILE_NAME to one defined in SDL token
+//
+// 8 11/03/11 6:39p Alexp
+// restored FwCapsuleInfo()
+//
+// 7 10/17/11 11:33a Alexp
+// Replace old method to detect FlashUpd with single IsFlashUpdate() hook
+// to be called from SbPei.c ->GetBootMode
+//
+// 6 10/11/11 12:24p Alexp
+// VerifyFwRevision(): removed unused input parameter: **PeiServices
+//
+// 5 9/29/11 3:25p Alexp
+// Bug fix. EIP#71244: No Rollback support
+//
+// 4 9/20/11 2:25p Alexp
+// change BootMode from Recovery to BOOT_ON_FLASH_UPDATE if FlUpdate is
+// pending.
+//
+// 3 8/05/11 3:19p Alexp
+// add condition to skip Revision check. Ignore rollback protection
+//
+// 2 7/20/11 7:16p Alexp
+// remove dependency on Capsule module
+//
+// 1 7/01/11 4:39p Alexp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------
+//
+// Name: VerifyFwCapsule.c - PEI secured recovery services
+//
+// Description: File contains VerifyFwCapsule hook to evaluate Fw Capsule
+//
+//----------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//----------------------------------------------------------------------------
+// Includes
+// Statements that include other files
+#include "Efi.h"
+#include "Pei.h"
+#include "token.h"
+#include <AmiPeiLib.h>
+#include <Hob.h>
+#include <RomLayout.h>
+#include <Ffs.h>
+#include <Ppi\ReadOnlyVariable.h>
+#include <FlashUpd.h>
+#include <PPI\CryptoPPI.h>
+#include <PPI\FwVersion.h>
+#include <Protocol\Hash.h>
+#include "AmiCertificate.h"
+#include <BaseCryptLib.h>
+
+//----------------------------------------------------------------------------
+// Function Externs
+
+//----------------------------------------------------------------------------
+// Local prototypes
+EFI_STATUS
+FwCapsuleInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsuleName,
+ IN OUT UINTN *pCapsuleSize,
+ OUT BOOLEAN *ExtendedVerification
+);
+
+//----------------------------------------------------------------------------
+typedef struct {
+ EFI_FFS_FILE_HEADER FfsHdr;
+ EFI_COMMON_SECTION_HEADER SecHdr;
+ EFI_GUID SectionGuid;
+ UINT8 FwCapHdr[0];
+} AMI_FFS_COMMON_SECTION_HEADER;
+
+typedef struct _FID_SECTION {
+ EFI_GUID Guid;
+ FW_VERSION FwVersion;
+} FID_SECTION;
+
+//----------------------------------------------------------------------------
+// Local Variables
+static EFI_GUID FwCapFfsGuid = AMI_FW_CAPSULE_FFS_GUID;
+static EFI_GUID FwCapSectionGuid = AMI_FW_CAPSULE_SECTION_GUID;
+static EFI_GUID FidSectionGuid = \
+ { 0x2EBE0275, 0x6458, 0x4AF9, 0x91, 0xed, 0xD3, 0xF4, 0xED, 0xB1, 0x00, 0xAA };
+
+const UINT8 *FidSignature = "$FID";
+
+EFI_PEI_SERVICES **gPeiServices;
+static AMI_CRYPT_DIGITAL_SIGNATURE_PPI *gpAmiSigPPI=NULL;
+
+//static EFI_GUID gAmiDigitalSignaturePPIGuid = AMI_DIGITAL_SIGNATURE_PPI_GUID;
+static EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID;
+static EFI_GUID gEfiCertRsa2048Guid = EFI_CERT_RSA2048_GUID;
+static EFI_GUID gFWkeyGuid = PR_KEY_GUID;
+static EFI_GUID gEfiHashAlgorithmSha256Guid = EFI_HASH_ALGORITHM_SHA256_GUID;
+static EFI_GUID gEfiCertX509Guid = EFI_CERT_X509;
+static EFI_GUID gEfiCertTypePkcs7Guid = EFI_CERT_TYPE_PKCS7_GUID;
+
+static EFI_GUID gPeiReadOnlyVariablePpiGuid = EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+static AMI_FLASH_UPDATE_BLOCK gFlashUpdDesc;
+
+//const char *RecoveryCapFileName = CONVERT_TO_STRING(FWCAPSULE_FILE_NAME);
+const UINTN RecoveryCapImageSize = FWCAPSULE_IMAGE_SIZE;
+
+static UINT8 gHashDB[SHA256_DIGEST_SIZE];
+// Allocate Hash Descr table
+static UINTN *gAddrList=NULL;
+static UINTN *gLenList=NULL;
+static UINTN gHashNumElem=0;
+
+//----------------------------------------------------------------------------
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: VerifyProjectId
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+VerifyProjectId (
+ IN FW_VERSION *FwVersionData,
+ IN OUT UINT32 *FailedVTask
+)
+{
+ char *strProjectId = CONVERT_TO_STRING(PROJECT_TAG);
+ UINTN Size = sizeof(CONVERT_TO_STRING(PROJECT_TAG));
+/*
+CHAR8 BiosTag[9]; //BIOS Tag
+EFI_GUID FirmwareGuid; //Firmware GUID
+CHAR8 CoreMajorVersion[3];
+CHAR8 CoreMinorVersion[3];
+CHAR8 ProjectMajorVersion[3];
+CHAR8 ProjectMinorVersion[3];
+*/
+ *FailedVTask = Ver;
+// Project ID, Major, Minor rev
+PEI_TRACE((-1, gPeiServices, "\nOrgBiosTag=%s,NewBiosTag=%s\nPrjMajVer=%02d, NewMajVer=%s\nPrjMinorVer=%02d, NewMinorVer=%s\n",
+FwVersionData->BiosTag, strProjectId,
+PROJECT_MAJOR_VERSION, FwVersionData->ProjectMajorVersion,
+PROJECT_MINOR_VERSION, FwVersionData->ProjectMinorVersion
+));
+ if (Size==0 || MemCmp (FwVersionData->BiosTag, strProjectId, Size-1)) return FALSE;
+#if IGNORE_IMAGE_ROLLBACK == 0
+// Physically present user may override roll back protection from Setup screen
+ if(Atoi(FwVersionData->ProjectMajorVersion) < PROJECT_MAJOR_VERSION ||
+ Atoi(FwVersionData->ProjectMinorVersion) < PROJECT_MINOR_VERSION)
+#if (defined(REFLASH_INTERACTIVE) && REFLASH_INTERACTIVE==1)
+ return TRUE;
+#else
+ return FALSE;
+#endif
+#endif
+
+ *FailedVTask = 0;
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFidData
+//
+// Description: Function to read FFS FID data structure from the given data buffer
+//
+// Input: OUT FW_VERSION **Fid - pointer to output buffer
+// IN VOID *pFV - pointer to data buffer to read from
+//
+// Output: EFI_SUCCESS if FID data is retrieved
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GetFidData(
+ IN VOID *pFV,
+ IN UINT32 Size,
+ OUT FW_VERSION **FwVersionData
+)
+{
+// UINT32 Signature;
+ UINT8* SearchPointer;
+ FID_SECTION *Section;
+
+// Simplified search by $FID signature only.
+// SearchPointer = (UINT32 *)((UINT8 *)pFV + sizeof(EFI_GUID));
+// Signature = FidSectionGuid.Data1;
+ SearchPointer = (UINT8 *)pFV;
+
+ do {
+// if(*SearchPointer == Signature) {
+ Section = (FID_SECTION *)SearchPointer;
+ if(!guidcmp(&FidSectionGuid, &(Section->Guid)) &&
+ (*((UINT32*)(&Section->FwVersion.FirmwareID[0])) == *(UINT32*)FidSignature)){
+ *FwVersionData = &Section->FwVersion;
+ return TRUE;
+ }
+// }
+ } while( SearchPointer++ < (UINT8*)((UINT32)pFV+Size));
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyFwRevision
+//
+// Description: Verify Fw revision compatibility
+// NewVer > OldVer, newProjectTAGid = oldProjectTAGid
+//
+// Input:
+// IN OUT UINT8 *pCapsule
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+VerifyFwRevision (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *RomData,
+ IN OUT UINT32 *FailedVTask
+)
+{
+ ROM_AREA *Area;
+ EFI_PHYSICAL_ADDRESS FvAddress;
+ FW_VERSION *FwVersionData;
+
+ *FailedVTask = Ver;
+
+ Area = (ROM_AREA *)(UINTN)((UINT32)FWCapsuleHdr+FWCapsuleHdr->RomLayoutOffset);
+ for (Area; Area->Size != 0; Area++) {
+ if (!(Area->Attributes & ROM_AREA_FV_SIGNED))
+ continue;
+ // $FID can be in FV with either PEI or DXE
+ if (!(Area->Attributes & (ROM_AREA_FV_PEI+ROM_AREA_FV_DXE)))
+ continue;
+
+ FvAddress = (EFI_PHYSICAL_ADDRESS)RomData + (Area->Offset);
+ if (GetFidData((UINT8*)FvAddress, Area->Size, &FwVersionData)){
+ if(VerifyProjectId(FwVersionData, FailedVTask))
+ return EFI_SUCCESS;
+ break;
+ }
+ }
+// At least one FW block must be signed OR no $FID structure found in the new FW image
+ return EFI_SECURITY_VIOLATION;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindCapHdrFFS
+//
+// Description: Function to read FW Cap Sig data from Ffs
+//
+// Input: OUT UINT8 **pFwCapHdr - pointer to output buffer
+// IN VOID *pCapsule - pointer to data buffer to read from
+//
+// Output: EFI_SUCCESS if Capsule Hdr with Signature is retrieved
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindCapHdrFFS(
+ IN VOID *pCapsule,
+ OUT UINT8 **pFfsData
+)
+{
+ UINT32 Signature;
+ UINT32 *SearchPointer;
+ AMI_FFS_COMMON_SECTION_HEADER *FileSection;
+ APTIO_FW_CAPSULE_HEADER *pFwCapHdr;
+
+ SearchPointer = (UINT32 *)((UINT8 *)pCapsule - sizeof(AMI_FFS_COMMON_SECTION_HEADER) + FLASH_SIZE);
+ Signature = FwCapFfsGuid.Data1;
+
+ do {
+ if(*SearchPointer == Signature) {
+ FileSection = (AMI_FFS_COMMON_SECTION_HEADER *)SearchPointer;
+ if(!guidcmp(&FwCapFfsGuid, &(FileSection->FfsHdr.Name)) &&
+ !guidcmp(&FwCapSectionGuid, &(FileSection->SectionGuid))
+ ){
+ pFwCapHdr = (APTIO_FW_CAPSULE_HEADER*)(FileSection->FwCapHdr);
+ // just a sanity check - Cap Size must match the Section size
+ if(((*(UINT32 *)FileSection->FfsHdr.Size) & 0xffffff) >=
+ pFwCapHdr->CapHdr.HeaderSize + sizeof(AMI_FFS_COMMON_SECTION_HEADER) &&
+ !guidcmp((EFI_GUID*)&pFwCapHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid)
+ ){
+ *pFfsData = (UINT8*)pFwCapHdr;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ } while(SearchPointer-- != pCapsule);
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HashFwRomMapImage
+//
+// Description: The Rom image hash is calculated based on info from the Rom Area map
+//
+// Input:
+// Payload - pointer to a FW Image
+// FwCapsuleHdr - pointer to a FW Capsule Hdr
+// RomSize - Size of Rom Image
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HashFwRomMapImage (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *Payload,
+ IN UINTN RomSize,
+ OUT UINT8 *gHashDB
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ ROM_AREA *RomAreaTbl;
+
+ UINTN i, RomMap_size, max_num_elem, num_elem;
+
+ RomAreaTbl = (ROM_AREA *)(UINTN)((UINT32)FWCapsuleHdr+FWCapsuleHdr->RomLayoutOffset);
+
+ RomMap_size = FWCapsuleHdr->RomImageOffset-FWCapsuleHdr->RomLayoutOffset;
+ max_num_elem = RomMap_size/sizeof(ROM_AREA);
+
+// assume max size of RomMap array = RomMap_size/sizeof(ROM_AREA);
+// or better yet ...calculate exact number
+ num_elem = 0;
+ for (i=0; i < max_num_elem && RomAreaTbl[i].Size != 0; i++ )
+ {
+ if (RomAreaTbl[i].Attributes & ROM_AREA_FV_SIGNED)
+ num_elem++;
+ }
+ max_num_elem=i;
+ num_elem+=2; // add 2 extra entries
+
+ if(!gAddrList || !gHashNumElem || gHashNumElem<num_elem) {
+ gHashNumElem = num_elem;
+ i = num_elem*sizeof(UINTN);
+ Status = (*gPeiServices)->AllocatePool(gPeiServices, i*2, &gAddrList);
+ ASSERT_PEI_ERROR (gPeiServices, Status);
+ if(EFI_ERROR(Status)) return Status;
+ gLenList = (UINTN*)((UINT8*)gAddrList + i);
+ }
+ num_elem = 0;
+ for(i=0; i < max_num_elem && num_elem < gHashNumElem && RomAreaTbl[i].Size != 0; i++)
+ {
+ if (!(RomAreaTbl[i].Attributes & ROM_AREA_FV_SIGNED))
+ continue;
+ // sanity check for buffer overruns
+ if(RomAreaTbl[i].Offset > RomSize ||
+ (UINT64)RomAreaTbl[i].Offset + RomAreaTbl[i].Size > RomSize)
+ return EFI_SECURITY_VIOLATION;
+ // RomArea only holds offsets within a payload
+ gAddrList[num_elem] = (UINTN)((UINTN)Payload + RomAreaTbl[i].Offset);
+ gLenList[num_elem] = RomAreaTbl[i].Size;
+
+ num_elem++;
+
+ }
+ if(num_elem >= gHashNumElem) return EFI_SECURITY_VIOLATION;
+//
+// Hash of Capsule Hdr + FW Certificate Hdr
+//
+ if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_CAPHDR_IN_SIGNCERT) {
+ gAddrList[num_elem] = (UINTN) FWCapsuleHdr;
+ gLenList[num_elem] = (UINTN)&FWCapsuleHdr->FWCert.SignCert.CertData - (UINTN)FWCapsuleHdr;
+ num_elem++;
+ if(num_elem >= gHashNumElem) return EFI_SECURITY_VIOLATION;
+ }
+//
+// Hash of the ROM_MAP table
+//
+ gAddrList[num_elem] = (UINTN)RomAreaTbl;
+ gLenList[num_elem] = (i+1)*sizeof(ROM_AREA);
+ num_elem++;
+
+ Status = gpAmiSigPPI->Hash(gpAmiSigPPI, &gEfiHashAlgorithmSha256Guid,
+ num_elem, (const UINT8**)gAddrList, (const UINTN*)gLenList, gHashDB );
+
+// PEI_TRACE((-1, gPeiServices, "Hash the FW Image %r\n", Status));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyFwCertPkcs7
+//
+// Description: This code verifies FW Capsule is genuine,
+// and performs following checks on the image:
+// 1. Signing certificate is signed with trusted Root Platform key
+// 2. Integrity check. Image Signature verification
+//
+// Input:
+// Payload - pointer to a FW Image
+// FwCapsuleHdr - pointer to a FW Capsule Hdr
+// RomSize - Size of Rom Image
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyFwCertPkcs7 (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *Payload,
+ IN UINTN RomSize,
+ IN PEI_CRYPT_HANDLE *PubKeyHndl,
+ IN OUT UINT32 *FailedVTask
+){
+ EFI_STATUS Status;
+ UINT8 *Pkcs7Cert, *pDigest;
+ UINTN Pkcs7Cert_len, DigestLen;
+
+//
+// 1. Validate Root Key
+//
+ *FailedVTask = Key;
+
+ if( PubKeyHndl->Blob==NULL)
+ return EFI_SECURITY_VIOLATION;
+
+ if(guidcmp(&PubKeyHndl->AlgGuid, &gEfiCertX509Guid))
+ return EFI_UNSUPPORTED;
+
+// 2. Verify Signing Cert Signature
+//
+// 2.1 The Rom image hash is calculated based on info from the Rom Area map
+//
+ *FailedVTask = Sig;
+
+ Status = HashFwRomMapImage(FWCapsuleHdr, Payload, RomSize, gHashDB);
+ if (EFI_ERROR(Status)) return Status;
+
+// 2.2 Verify Fw Certificate
+ pDigest = &gHashDB[0];
+ DigestLen = SHA256_DIGEST_SIZE;
+ Pkcs7Cert = (UINT8*)&FWCapsuleHdr->FWCert.SignCert.CertData;
+ Pkcs7Cert_len = FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength-sizeof(WIN_CERTIFICATE_UEFI_GUID_1);
+
+ return gpAmiSigPPI->VerifyPkcs7Sig( gpAmiSigPPI,
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ PubKeyHndl->Blob, PubKeyHndl->BlobSize, // TrustCert
+ &pDigest, &DigestLen // In/OutData
+ );
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyFwCertRsa2048Sha256
+//
+// Description: This code verifies FW Capsule is genuine,
+// and performs following checks on the image:
+// 1. Signing certificate is signed with trusted Root Platform key
+// 2. Integrity check. Image Signature verification
+//
+// Input:
+// Payload - pointer to a FW Image
+// FwCapsuleHdr - pointer to a FW Capsule Hdr
+// RomSize - Size of Rom Image
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyFwCertRsa2048Sha256 (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *Payload,
+ IN UINTN RomSize,
+ IN OUT UINT32 *FailedVTask
+){
+ EFI_STATUS Status;
+ PEI_CRYPT_HANDLE HashHndl;
+ PEI_CRYPT_HANDLE PubKeyHndl;
+ UINT8 *pSig;
+ UINT32 Flags=0;
+ UINT8 *Addr;
+ UINTN Size;
+ EFI_CERT_BLOCK_RSA_2048_SHA256* pRootCert;
+
+// Versions 010 and later support extended flags
+// if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_CAPHDR_IN_SIGNCERT)
+ if(FWCapsuleHdr->CapHdr.HeaderSize == FWCapsuleHdr->RomImageOffset)
+ {
+ if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_RSA_PSS_PADDING_SCHEME)
+ Flags = EFI_CRYPT_RSASSA_PSS;
+ else
+ Flags = EFI_CRYPT_RSASSA_PKCS1V15;
+ }
+ else
+ Flags = EFI_CRYPT_RSASSA_PSS;
+
+ HashHndl.AlgGuid = gEfiHashAlgorithmSha256Guid;
+ HashHndl.BlobSize = SHA256_DIGEST_SIZE;
+ HashHndl.Blob = (UINT8*)&gHashDB;
+//
+// 1. Compare Capsule's Sign Cert key with Platform Root Key
+//
+ *FailedVTask = Key;
+
+ PubKeyHndl.BlobSize = DEFAULT_RSA_KEY_MODULUS_LEN;
+ PubKeyHndl.AlgGuid = gEfiCertRsa2048Guid;
+ PubKeyHndl.Blob = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey;
+ Status = gpAmiSigPPI->VerifyKey(gpAmiSigPPI, &gFWkeyGuid, &PubKeyHndl);
+ PEI_TRACE((-1, gPeiServices, "Compare Platform and SignCert Keys : %r\n", Status));
+// Skip the RootCert key checking if SignCert Key and PR Key are matching
+ if(EFI_ERROR(Status)) {
+//
+// 1.1 Compare Platform Root with Capsule's Key from a Root Key store
+//
+ for (pRootCert = &FWCapsuleHdr->FWCert.RootCert;
+ (UINT8*)pRootCert <
+ (UINT8*)&FWCapsuleHdr->FWCert+FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength &&
+ pRootCert->PublicKey[0]!=0;
+ pRootCert++)
+ {
+ PubKeyHndl.Blob = (UINT8*)pRootCert->PublicKey;
+ Status = gpAmiSigPPI->VerifyKey(gpAmiSigPPI, &gFWkeyGuid, &PubKeyHndl);
+ PEI_TRACE((-1, gPeiServices, "Compare Platform and RootCert Keys : %r\n", Status));
+ if (EFI_ERROR(Status)) continue;
+
+ // 2. Verify RootCert.Signature
+ //
+ // 2.1 Compute FWCert.SignCert.PublicKey Hash
+ //
+ if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_SIGNKEY_IN_ROOTCERT)
+ {
+ Addr = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey;
+ Size = DEFAULT_RSA_KEY_MODULUS_LEN;
+ } else
+ // 2.2 Compute FWCert.SignCert Hash
+ {
+ Addr = (UINT8*)&FWCapsuleHdr->FWCert.SignCert;
+ Size = sizeof(AMI_CERTIFICATE_RSA2048_SHA256);
+ }
+
+ Status = gpAmiSigPPI->Hash(gpAmiSigPPI,&gEfiHashAlgorithmSha256Guid, 1,&Addr,(const UINTN*)&Size, gHashDB);
+ if (EFI_ERROR(Status)) break;
+
+ pSig = (void*)pRootCert->Signature;
+ Status = gpAmiSigPPI->VerifySig(gpAmiSigPPI, &PubKeyHndl, &HashHndl, pSig, DEFAULT_RSA_SIG_LEN, Flags );
+ PEI_TRACE((-1, gPeiServices, "Verify Root Cert : %r\n", Status));
+ break;
+ }
+ }
+ if (EFI_ERROR(Status)) return EFI_SECURITY_VIOLATION;
+//
+// 3. Verify Signing Cert
+//
+ *FailedVTask = Sig;
+//
+// 3.1 The Rom image hash is calculated based on info from the Rom Area map
+//
+ Status = HashFwRomMapImage(FWCapsuleHdr, Payload, RomSize, gHashDB);
+ if (EFI_ERROR(Status)) return Status;
+
+ pSig = (void*)FWCapsuleHdr->FWCert.SignCert.CertData.Signature;
+ PubKeyHndl.Blob = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey;
+
+ return gpAmiSigPPI->VerifySig(gpAmiSigPPI, &PubKeyHndl, &HashHndl, pSig, DEFAULT_RSA_SIG_LEN, Flags);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: VerifyFwImage
+//
+// Description: Function verifies various sections of the FW Capsule
+//
+// 0. Locate protocol AMI_CRYPT_DIGITAL_SIGNATURE_PPI
+// 1. Check if FV GUID matches Aptio FW Capsule.
+// - Yes -
+// update Payload ptr to beginning of BIOS ROM data
+// continue with Image Varify
+// - Not found at offs 0 - assume Cap Hdr is in FFS
+// locate FFS by Hole GUID, Sec GUID
+// update FWCapsuleHdr ptr,
+// continue with Image Varify
+// 2. Validate Root Certificate
+// -Compare PubKey in Root Certificate Hdr with local FW Platform Key
+// -Hash SignCert.PubKey
+// -VerifySig for RootCert.Signature and compare with SignCert.Key hash
+// 3. Validate Sign Certificate
+// -Hash the ROM image inside the FW Capsule
+// -VerifySig for SignCert.Signature and compare with ROM hash
+// 4. Update pCapsuleSize = FwPayload and set pCapsule to point to FW Payload
+//
+// Input:
+// PeiServices Pointer to PeiServices instance.
+// pCapsule Points to the start of the Aptio FW Capsule.
+// pCapsuleSize The size of buffer, in bytes.
+// FailedVTask Specifies additional flags to further customize the signing/verifying behavior.
+//
+// Output:
+// pCapsule ptr is set to start of Capsule's Payload - ROM image
+// pCapsuleSize return ROM image size
+// EFI_SUCCESS The signature is successfully verified.
+// EFI_SECURITY_VIOLATION The signature does not match the given message.
+// EFI_ACCESS_DENIED The key could not be used in signature operation.
+// EFI_INVALID_PARAMETER The size of input message or signature does not meet the criteria
+// of the underlying signature algorithm.
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+VerifyFwImage(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsule,
+ IN OUT UINT32 *pCapsuleSize,
+ IN OUT UINT32 *FailedVTask
+){
+ EFI_STATUS Status;
+ APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr;
+ UINT8 *Payload;
+ UINTN RomSize;
+ PEI_CRYPT_HANDLE PubKeyHndl;
+ UINT8 Byte;
+ UINTN Size;
+
+ gPeiServices = PeiServices;
+
+ PEI_TRACE((-1, PeiServices, "\nValidate FW Capsule ...\n"));
+
+// Predefined bit mask of checks to perform on Aptio FW Capsule
+ *FailedVTask = Cap;
+
+ Status = (*PeiServices)->LocatePpi(PeiServices, &gAmiDigitalSignaturePPIGuid, 0, NULL, &gpAmiSigPPI);
+ if(EFI_ERROR(Status)) return Status;
+
+ // ignore Verification if FwKey is not detected in the FW.
+ // Works with unsigned Aptio.ROM image or Signed ROM with embedded sig.
+ PubKeyHndl.BlobSize = 0;
+ PubKeyHndl.Blob = NULL;
+ Status = gpAmiSigPPI->GetKey(gpAmiSigPPI, &gFWkeyGuid, &PubKeyHndl);
+ PEI_TRACE((-1, PeiServices, "Get Root Cert Key (%r),0x%8X (%d bytes)\n", Status, (*(UINT32*)PubKeyHndl.Blob), PubKeyHndl.BlobSize));
+ if(EFI_ERROR(Status))
+ {
+#if (defined(REFLASH_INTERACTIVE) && REFLASH_INTERACTIVE==1)
+ if(Status == EFI_NOT_FOUND)
+ return EFI_SUCCESS;
+#endif
+ *FailedVTask = Key;
+ return Status;
+ }
+
+ FWCapsuleHdr = *pCapsule;
+ Payload = (UINT8*)*pCapsule;
+ RomSize = (UINTN)*pCapsuleSize;
+
+// verify Capsule Mailbox points to FW_CAPSULE hdr
+ if(guidcmp((EFI_GUID*)&FWCapsuleHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid))
+ {
+// looking FwCap hdr inside BIOS.ROM
+ if(EFI_ERROR(FindCapHdrFFS(Payload, (UINT8**)&FWCapsuleHdr)))
+ return EFI_SECURITY_VIOLATION;
+ }
+ PEI_TRACE((-1, PeiServices, "FW Capsule Hdr Detected...\n"));
+
+// Aptio FW Capsule only supporting WIN_CERT_TYPE_EFI_GUID
+ if(FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
+ return EFI_SECURITY_VIOLATION;
+
+// Applied for FwCapsules with Hdr on top of the Payload
+ if( (UINT8*)*pCapsule ==(UINT8*) FWCapsuleHdr) {
+ if(FWCapsuleHdr->CapHdr.CapsuleImageSize > *pCapsuleSize)
+ return EFI_SECURITY_VIOLATION;
+ // Update pFwCapsule to point to beginning of Bios ROM
+ Payload = (UINT8*)((UINT32)FWCapsuleHdr + FWCapsuleHdr->RomImageOffset);
+ RomSize = (FWCapsuleHdr->CapHdr.CapsuleImageSize - FWCapsuleHdr->RomImageOffset);
+ }
+
+// Capsule Hdr sanity checks
+ if((RomSize > *pCapsuleSize) ||
+ (FWCapsuleHdr->RomImageOffset > (FWCAPSULE_IMAGE_SIZE-FLASH_SIZE)) || // 16k is a MAX possible FwCap Hdr size
+ (FWCapsuleHdr->CapHdr.HeaderSize > FWCapsuleHdr->RomImageOffset) ||
+ (FWCapsuleHdr->RomLayoutOffset > FWCapsuleHdr->RomImageOffset) ||
+ (FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength + offsetof(APTIO_FW_CAPSULE_HEADER, FWCert) >
+ FWCapsuleHdr->RomLayoutOffset )
+ )
+ return EFI_SECURITY_VIOLATION;
+
+ // If dummy FWkey - skip integrity check - only test the Capsule's structure
+ Byte = PubKeyHndl.Blob[0];
+ for(Size = 1; Size < PubKeyHndl.BlobSize && (Byte == PubKeyHndl.Blob[Size]); Size++);
+ if(Size == PubKeyHndl.BlobSize) {
+ *FailedVTask = Key;
+ PEI_TRACE((-1, PeiServices, "Dummy FW Key detected. Skip image verification...\n"));
+ } else
+ {
+// Begin Authentication
+ if(!guidcmp((EFI_GUID*)&FWCapsuleHdr->FWCert.SignCert.Hdr.CertType, &gEfiCertTypePkcs7Guid))
+ Status = VerifyFwCertPkcs7(FWCapsuleHdr, Payload, RomSize, &PubKeyHndl, FailedVTask);
+ else
+ Status = VerifyFwCertRsa2048Sha256(FWCapsuleHdr, Payload, RomSize, FailedVTask);
+
+ PEI_TRACE((-1, gPeiServices, "Verify Sign Certificate Sig : %r\n", Status));
+ if (EFI_ERROR(Status)) return Status;
+
+ *FailedVTask = 0;
+
+// Local PEI $FID is linked with CspLib. extern FW_VERSION FwVersionData;
+// Find $FID in new Fw FVs. Any instance found should do for us. Use RomMap from Capsule's Hdr
+// compare local BB and Main $Fid BIOS Major/Minor revs with New one.
+ Status = VerifyFwRevision(FWCapsuleHdr, Payload, FailedVTask);
+ PEI_TRACE((-1, PeiServices, "FW Revision test %r (FailedVTask = %x)\n", Status, *FailedVTask));
+ }
+
+ *pCapsule = (UINT32*)Payload;
+ *pCapsuleSize = RomSize;
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: FwCapsuleInfo
+//
+// Description: Updates the Recovery File name and size if defaults are
+// overriden in FlashUpd EFI Var.
+// Called from Recovery LoadRecoveryCapsule.
+//
+// pCapsuleName Pointer to the variable containing a Recovery File name
+// pCapsuleSize Pointer to the size of recovery image capsule, in bytes.
+// ExtendedVerification Indicates to Recovery module whether Fw Capsule
+// Recovery path will perform image size check.
+//
+// Output:
+// EFI_SUCCESS
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+FwCapsuleInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT VOID **pCapsuleName,
+ IN OUT UINTN *pCapsuleSize,
+ OUT BOOLEAN *ExtendedVerification
+){
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable = NULL;
+ EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID;
+
+ if(!pCapsuleName && !pCapsuleSize && !ExtendedVerification )
+ return EFI_UNSUPPORTED;
+
+ if(ExtendedVerification != NULL)
+ *ExtendedVerification = TRUE;
+
+ if(pCapsuleSize != NULL)
+ {
+ *pCapsuleSize = RecoveryCapImageSize;
+
+ if(pCapsuleName != NULL)
+ {
+// EIP149817: don't override a default recovery file name
+// *pCapsuleName = (VOID*)RecoveryCapFileName;
+
+ // Detect if we are in Flash Update mode and set some recovery global variables
+ // Read "FlashOp" Variable to update global RecoveryFileName, Size
+ Status = (*PeiServices)->LocatePpi( PeiServices,
+ &gPeiReadOnlyVariablePpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable );
+ // ASSERT_PEI_ERROR (PeiServices, Status);
+ if(EFI_ERROR(Status))
+ return Status;
+
+ Size = sizeof(AMI_FLASH_UPDATE_BLOCK);
+ Status = ReadOnlyVariable->GetVariable( PeiServices,
+ FLASH_UPDATE_VAR,
+ &FlashUpdGuid,
+ NULL,
+ &Size,
+ &gFlashUpdDesc );
+ if(!EFI_ERROR(Status))
+ {
+ if(gFlashUpdDesc.FlashOpType == FlRecovery && gFlashUpdDesc.FwImage.AmiRomFileName[0] != 0)
+ *pCapsuleName = (VOID*)gFlashUpdDesc.FwImage.AmiRomFileName;
+
+ *pCapsuleSize = gFlashUpdDesc.ImageSize;
+ Status = (*PeiServices)->SetBootMode(PeiServices, BOOT_ON_FLASH_UPDATE);
+ }
+ PEI_TRACE((-1, PeiServices, "FW Capsule update %r\nImage Name %s, Size %x\n", Status, *pCapsuleName, *pCapsuleSize));
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.c b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.c
new file mode 100644
index 0000000..170461a
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.c
@@ -0,0 +1,1810 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/SecSMIFlash.c 61 9/10/14 5:03p Alexp $
+//
+// $Revision: 61 $
+//
+// $Date: 9/10/14 5:03p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/SecSMIFlash.c $
+//
+// 61 9/10/14 5:03p Alexp
+// EIP176297: Harden external parameter checks in SW SMI API
+// Fixes are made to address:
+// #7. Arbitrary SMRAM overwrite in SetFlUpdMethod()
+// #8. Integer overflow leading to buffer overflow in
+// LoadFwImage in SecSMIFlash SMI handler
+//
+// 60 8/04/14 11:59a Alexp
+// 1. Use internal RomLayout map to process Flash Erase/Write requests.
+// Issue- new RomMap may be different - exposing rom holes in wrong
+// places
+// 2. SetFlUpdMethod() - SecSmiFlash.RomLayout is updated to a map from a
+// new image but not used.
+// Later may compare the maps to find inconsistencies.
+// 3. BeforeSecureUpdate() - bug in calculating the flash range within
+// RomArea
+//
+// 59 7/29/14 12:07p Alexp
+// Add a code to erase existing CapsuleUpdate and FlashUdate vars
+// Fixes the case when vars exist with different attributes which prevent
+// SecSmiFlash to set new valid var.
+//
+// 57 7/03/14 10:16a Alexp
+// EIP176297: Harden external parameter checks in SW SMI API
+//
+// 56 6/11/14 10:16a Alexp
+// EIP#168391:The power button does not work with failed NVRAM
+// - harden SmiS5CapsuleCallback()
+// - memory allocation for gpEfiCapsuleHdr changed from runtime memory to
+// SMRAM.
+//
+// 55 3/20/14 3:20p Alexp
+// 1. EIP#159507 : S3 resume time improvement: Use EfiReservedMemoryType
+// instead of EfiACPIMemoryNVS for large buffer allocations.
+// FwCapsule buffer to be allocated below 4GB.
+// 2. Allow gpPubKeyHndl to be accessed from externally linked code
+//
+// 54 1/24/14 4:02p Alexp
+// SetFlUpdMethod()
+// 1. Set SecSmiFlash.RomLayout only for Runtime and Capsule update
+// 2. removed dummy code " SecSmiFlash.pFwCapsule =
+// SecSmiFlash.pFwCapsule"
+//
+// 53 10/11/13 2:50p Alexp
+//
+// 52 6/21/13 10:56a Alexp
+// EIP#125800: add more error checking in release mode inside
+// InSmmFunction()
+//
+// 51 6/12/13 3:52p Alexp
+// CapsuleValidate() made external function in SecSmiFlash API
+//
+// 50 6/06/13 4:03p Alexp
+// EIP#125800 : Privilege escalation into SMM via Secure SMI Flash SMM
+// driver via GetFlUpdPolicy and SetFlUpdMethod - BugID 305294
+// add IsAddressInSmram() checks inside exposed API functions
+//
+// 49 4/23/13 2:49p Alexp
+// GetFlUpdPolicy() to return FwKey up to 256 bytes.
+//
+//
+// 47 2/26/13 6:14p Alexp
+// Set data size for Capsule Upd variable as
+// size of (EFI_PHYSICAL_ADDRESS)
+//
+//
+// 45 12/28/12 2:19p Alexp
+// fix "cppcheck: code style issues
+//
+// 42 11/21/12 10:42a Alexp
+// Replace direct calls to Hash() in CryptoLib with API calls
+//
+// 41 11/13/12 3:26p Alexp
+// 1. Calculate offset to RomLayout table within FwCapsHdr instead of
+// using hardwired location. Pkcs#7
+// cert will differ in size and offset may change
+// 2. Remove assert after GetKey function.
+//
+// 40 11/09/12 5:44p Alexp
+// fixed branch for FWCAPSULE_2_0_SUPPORT
+//
+// 39 10/18/12 10:17a Alexp
+// Bug fix: make allocation of HashCtx buffer not to be dependent on
+// CAPSULE_RECOVERY support.
+//
+// 38 8/28/12 4:12p Alexp
+// fix spelling
+//
+// 37 8/22/12 9:40a Alexp
+// Allow to insrtall SecSmi Flash handler if RomLayout map not detected
+// during module Init
+//
+// 36 8/16/12 11:31a Alexp
+// use global pSmmBase ptr in InSmmFunction()
+//
+// 35 7/25/12 6:21p Alexp
+// replaced custom Capsule module defined _EFI_CAPSULE_BLOCK_DESCRIPTOR_
+// with generic UEFI EFI_CAPSULE_BLOCK_DESCRIPTOR structure
+//
+// 34 6/26/12 9:49a Alexp
+// include GetRomLayout under
+// #if RUNTIME_SECURE_UPDATE_FLOW == 1
+//
+// 33 6/12/12 5:33p Alexp
+// EIP74625:New Capsule PPI required by latest Intel's MRC code
+// -Fw Capsule upload supports new Capsule_2_0 format without extra
+// CapHdr in the Mailbox
+// EIP90678: MonotonicCounter variable guid changed
+// -Use AMI_GLOBAL_VARIABLE_GUID
+//
+// 30 5/21/12 4:55p Alexp
+// keep a pointer to FwCaps Hdr withing Capsule image. Streamlines
+// creation of Capsule Mailbox.
+//
+// 29 5/18/12 5:27p Alexp
+// 1. Replace Hash PPI calls with calls to Crypto lib functions.
+// 2. Enforce flash update security by replacing SMM Flash protocol
+// Write/Erase functions with local functions
+// 3. Include RomLayout map pointer to SecSmiFlash protocol table. Local
+// RomMap table is replaced with new one from valid FwCapsule image
+//
+// 28 2/29/12 4:15p Alexp
+// Removed "gAmiSig->GetKey" from driver entry point. Will use VerifyKey
+// instead. FW Key may be stored as a Hash in FW Key file storage.
+//
+// 27 2/16/12 9:38a Alexp
+// SetFlUpdMethod() - removed condition #if NEW_BIOS_MEM_ALLOC != 0 left
+// out from older logic
+//
+// 26 2/03/12 2:42p Alexp
+// Use SHA256 Hash for Hash table
+//
+// 25 1/27/12 12:14p Alexp
+// move defines for HASH_TBL_... to SecSmiFlash header file
+//
+// 23 1/13/12 4:18p Alexp
+// Replace "AFU_FLASH_PAGE_SIZE" with "FLASH_BLOCK_SIZE"
+//
+// 22 1/10/12 6:22p Alexp
+// 1. Always perform Hash match for new bios data block with one
+// calculated during Capsule verification
+// 2. Flash block available for hashing is determined by SDL token
+// FLASH_BLOCK_SIZE and not by AFU interface
+//
+// 21 12/16/11 1:19p Alexp
+// Bug fix: UpdateCapsule()
+// While preparing MailBox discriptor, the pointer gpCapsuleMailboxPtr
+// went outside of allocated memory pEfiCapsuleHdr
+//
+// 19 12/01/11 3:34p Alexp
+// 1.SmiS5CapsuleCallback-> Introduce a call to Chipset defined
+// SBLib_ResetSystem(WarmReset)
+// Call is included based on the SDL switch CSLIB_WARM_RESET_SUPPORTED
+// It replaces sample oimplementation of WarmReset via S3 & RTC wake up
+// 2. SetFlUpdMethod-> Add temp w/a for AFU rev 3.0. Wrong image size(0)
+// is reported by AFU in pSessionBlock->FlUpdBlock.ImageSize
+// 3. Updated conditional statements to match newly defined SDL tokens:
+// INSTALL_SECURE_FLASH_SW_SMI_HNDL and CSLIB_WARM_RESET_SUPPORTED
+//
+// 17 11/30/11 8:11p Alexp
+// 1. Replaced dependencies from WARM_REBOOT flag to generic
+// FWCAPSULE_RECOVERY_SUPPORT
+// 2. SetFlUpdMethod() corercted behavior of some AFU implementations for
+// CApsule Set mode. Size should have been provided
+// 3. Memory for Capsule Mailbox allocation moved form "EfiRuntime" to
+// more appropriate "AcpiNvs"
+//
+// 16 11/11/11 12:50p Alexp
+// fixed InSmmFunction() when building without FWCAPSULE_RECOVERY_SUPPORT
+//
+// 15 11/03/11 6:45p Alexp
+// skip SecSMIFlashSMIHandler() if OFBD Secure Flash module is active
+//
+// 14 10/17/11 11:25a Alexp
+// update Hdr & Footer. Clear BIOS buffer
+//
+// 13 10/11/11 12:28p Alexp
+// add OFBD dependency
+//
+// 12 9/30/11 4:39p Alexp
+// add porting notes
+//
+// 11 8/24/11 6:51p Alexp
+// replaced CAPSULE_SUPPORT check to FWCAPSULE_RECOVERY_SUPPORT
+//
+// 10 8/24/11 11:30a Alexp
+// Clear Capsule update capability in gFlUpdatePolicy.FlashUpdate if no
+// Capsule Driver or WarmReboot tokens are defined
+//
+// 9 8/09/11 7:45p Alexp
+//
+// 8 8/09/11 9:54a Alexp
+// bug fix: NEW #if NEW_BIOS_MEM_ALLOC != 0, OLD: #if NEW_BIOS_MEM_ALLOC
+//
+// 7 8/08/11 7:23p Alexp
+// SetFlashUpdateVar - assign Attributes to SetVar via CounterHi variable.
+// old init method "A | B | C" had wrong Attributes passed to the SetVar
+//
+// 6 8/06/11 11:35a Alexp
+// LoadImage-> clear out FSHndl. Need to be set to valid value only if
+// image Verification complete inside SetFlMethod
+//
+// 5 8/05/11 3:43p Alexp
+// hardwire Flash Upd policy (staticly provided from SDL tokens)
+//
+// 4 7/21/11 3:13p Alexp
+// removed mistakenly put while(1){} statement at the end of
+// SmiS5CapsuleCallback()
+//
+// 3 7/20/11 7:20p Alexp
+// removed dependency on Capsule module.
+//
+// 2 7/20/11 6:22p Alexp
+// include sample implementation to enter S3 on AMD chipsets
+//
+// 1 7/01/11 4:41p Alexp
+//
+// 1 7/01/11 4:37p Alexp
+//
+// 10 6/24/11 4:32p Alexp
+// move around debug comments
+//
+// 9 6/24/11 2:09p Alexp
+// SetFlUpd: abort if capsule size passed by AFU is greater then allocated
+// buffer in gRomFileSize
+//
+// 8 6/23/11 7:08p Alexp
+// SetFlashUpd: update local buffer with Ptr to AFU allocated buffer with
+// rom image
+//
+// 14 6/20/11 2:10p Alexp
+// // AFU updates the address in CapsuleMailboxPtr if
+// SetFlashMethod: update for the case if AFU provided address in memory
+// for new BIOS image
+//
+// 7 6/17/11 5:47p Alexp
+// bug fix: GetKey expects valid buffer size on input
+//
+// 6 6/01/11 12:35p Alexp
+// fix FSHandle init value
+//
+// 5 5/25/11 8:31p Alexp
+// forse Implemented flag to "1" if SecSMIFlash supported. ASFU would
+// check for combination, Version>-12 and this flag to determine if SecSMI
+// Flash API is supported
+//
+// 4 5/17/11 12:58p Alexp
+// add build switch for location of temp BIOS image
+//
+// 3 5/12/11 7:58p Alexp
+//
+// 2 5/10/11 5:10p Alexp
+// Hash guids are defined globally
+//
+// 1 5/10/11 10:01a Alexp
+//
+// 13 5/06/11 11:59a Alexp
+//
+// 12 5/02/11 3:22p Alexp
+// merged capsule hdr and mailbox into one mem allocation unit
+//
+// 11 4/28/11 6:21p Alexp
+// tbd: in release mode get FW pub key may fail
+//
+// 10 4/28/11 10:45a Alexp
+// update Capsule mailbox format. Add extra Efi Capsule Hdr that will be
+// discarded by CApsul PEI service while coalescing the Capsule into a Hob
+//
+// 8 4/22/11 4:36p Alexp
+// temp debug: init MC field in FlashUpd var with 0 if MC Var is missing.
+//
+// 7 4/19/11 6:42p Alexp
+// tested Reboot and Online flash. Recovery flow fails.
+//
+// 6 4/18/11 7:22p Alexp
+// working version. Need to review HashTable as it may not be practical if
+// block sizes do not mach BLOCK_SIZE
+//
+// 5 4/13/11 7:14p Alexp
+// locate RomMap for easy location of Fid.ffs for VersionControl
+// Create HashTable for uplaoded Fw Image. Used for runtime updates only
+// generate FSHandle for future use
+//
+// 4 4/11/11 2:10p Alexp
+// -Revision 12 and upper to support "Installed" field in Flash Info as
+// bit mask
+// -Add support for new CApsule SigningCert header
+// - Replace PKpub with new FW Sign key as a root Platform key to verify
+// Capsule Sig with
+//
+// 3 4/05/11 6:38p Alexp
+// use GetVariable to get PK Pub key
+//
+// 2 3/11/11 6:51p Alexp
+//
+// 1 3/10/11 4:59p Alexp
+//
+// 1 3/03/11 6:34p Alexp
+//
+//**********************************************************************
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Protocol\SmiFlash.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\SmmSxDispatch.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include <AmiSmm.h>
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol\SmmAccess2.h>
+#else
+#include <Protocol\SmmAccess.h>
+#endif
+
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+#include <Capsule.h>
+#endif
+
+#include <AmiHobs.h>
+
+#include <Protocol\SecSmiFlash.h>
+#include <Protocol\FlashProtocol.h>
+
+//----------------------------------------------------------------------
+// Module defined global variables
+static EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+static EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+static EFI_GUID gEfiSmmSxDispatchProtocolGuid = EFI_SMM_SX_DISPATCH_PROTOCOL_GUID;
+//extern EFI_GUID gEfiSmmSxDispatchProtocolGuid = EFI_SMM_SX_DISPATCH_PROTOCOL_GUID;
+
+// AMI_GLOBAL_VARIABLE_GUID must be defined in AmiLib.h (Core 4.6.5.4 +)
+#if defined(AMI_GLOBAL_VARIABLE_GUID)
+static EFI_GUID gAmiGlobalVariableGuid = AMI_GLOBAL_VARIABLE_GUID;
+#else
+static EFI_GUID gAmiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+#endif
+
+static EFI_GUID FlashUpdGuid = FLASH_UPDATE_GUID;
+
+EFI_GUID gFWCapsuleGuid = APTIO_FW_CAPSULE_GUID;
+EFI_GUID gPRKeyGuid = PR_KEY_GUID;
+EFI_GUID gFwCapFfsGuid = AMI_FW_CAPSULE_FFS_GUID;
+
+static FLASH_UPD_POLICY FlUpdatePolicy = {FlashUpdatePolicy, BBUpdatePolicy};
+
+EFI_SHA256_HASH *gHashTbl = NULL;
+UINT8 gHashDB[SHA256_DIGEST_SIZE];
+CRYPT_HANDLE gpPubKeyHndl;
+
+AMI_DIGITAL_SIGNATURE_PROTOCOL *gAmiSig;
+
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+static EFI_GUID CapsuleVendorGuid = EFI_CAPSULE_AMI_GUID;
+EFI_CAPSULE_BLOCK_DESCRIPTOR *gpEfiCapsuleHdr = NULL;
+#endif
+
+// BIOS allocates the space in AcpiNVS for new BIOS image to be uploaded by Flash tool
+// Alternatively the buffer may be reserved within the SMM TSEG. Check NEW_BIOS_MEM_ALLOC Token
+// AFU would have to execute a sequence of SW SMI calls to load new BIOS image to mem
+UINTN gFwCapMaxSize = FWCAPSULE_IMAGE_SIZE;
+UINT32 *pFwCapsuleLowMem = NULL;
+
+static EFI_SMRAM_DESCRIPTOR *mSmramRanges;
+static UINTN mSmramRangeCount;
+//----------------------------------------------------------------------
+// Flash Upd Protocol defines
+//----------------------------------------------------------------------
+typedef EFI_STATUS (EFIAPI *FLASH_READ_WRITE)(
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+);
+typedef EFI_STATUS (EFIAPI *FLASH_ERASE)(
+ VOID* FlashAddress, UINTN Size
+);
+
+FLASH_PROTOCOL *Flash;
+
+FLASH_READ_WRITE pFlashWrite; // Original Ptr inside FlashAPI
+FLASH_ERASE pFlashErase;
+
+static UINT32 Flash4GBMapStart;
+ROM_AREA *RomLayout = NULL;
+//----------------------------------------------------------------------
+
+//----------------------------------------------------------------------
+// UpFront Function definitions
+BOOLEAN SupportUpdateCapsuleReset (
+ VOID
+);
+EFI_STATUS CapsuleValidate (
+ IN OUT UINT8 **pFwCapsule,
+ IN OUT APTIO_FW_CAPSULE_HEADER **pFwCapsuleHdr
+);
+EFI_STATUS LoadFwImage(
+ IN OUT FUNC_BLOCK *pFuncBlock
+);
+EFI_STATUS GetFlUpdPolicy(
+ IN OUT FLASH_POLICY_INFO_BLOCK *InfoBlock
+);
+EFI_STATUS SetFlUpdMethod(
+ IN OUT FUNC_FLASH_SESSION_BLOCK *pSessionBlock
+);
+EFI_STATUS FindCapHdrFFS(
+ IN VOID *pCapsule,
+ OUT UINT8 **pFfsData
+);
+BOOLEAN IsAddressInSmram (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+);
+
+//----------------------------------------------------------------------
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SecSmiFlash
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_SEC_SMI_FLASH_PROTOCOL SecSmiFlash = {
+ LoadFwImage,
+ GetFlUpdPolicy,
+ SetFlUpdMethod,
+ CapsuleValidate,
+ 0,// pFwImageLowMem
+ 0,// RomLayout,
+ 0,// gSha256HashTbl,
+ 0,// FSHandle
+};
+
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+
+#if CSLIB_WARM_RESET_SUPPORTED == 0
+
+//#if (defined x64_BUILD && x64_BUILD == 1)
+//VOID flushcaches();
+void DisableCacheInCR0();
+//#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: ReadRtcIndexedRegister
+//
+// DESCRIPTION: Used to read RTC register indexed by the argument
+//
+// Input:
+// IN UINT8 Index Index of the register to read
+//
+//
+// Output:
+// UINT8 Current value of the register
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 ReadRtcIndexedRegister(IN UINT8 Index){
+
+ UINT8 Byte = IoRead8(0x70) & 0x80; // preserve bit 7
+ IoWrite8(0x70, Index | Byte);
+ Byte = IoRead8(0x71);
+ return Byte;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: ReadRtcIndexedRegister
+//
+// DESCRIPTION: Used to write to RTC register indexed by the argument
+//
+// Input:
+// IN UINT8 Index Index of the register to write to
+//
+// IN UINT8 Value Value to write to the RTC register
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID WriteRtcIndexedRegister(IN UINT8 Index, IN UINT8 Value){
+
+ IoWrite8(0x70,Index | (IoRead8(0x70) & 0x80));
+ IoWrite8(0x71,Value);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: S3RTCresume
+//
+// Description: This function puts system into ACPI S3 State.
+// if token ENABLE_RTC_ONE_SECOND_WAKEUP = 1, then it setups RTC
+// 1 second alarm as well.
+//
+// Input: None
+//
+// Output: None, system will enter ACPI S3 State.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID S3RTCresume (VOID)
+{
+ UINT32 IoData;
+ UINT8 Hour, Minute, Second;
+ BOOLEAN inBCD = TRUE;
+
+ //flush caches befor going to S3
+//#if (defined x64_BUILD && x64_BUILD == 1)
+// flushcaches();
+ DisableCacheInCR0();
+//#else
+// _asm wbinvd
+//#endif
+
+ // determine if RTC is in BCD mode
+ if( ReadRtcIndexedRegister(0xB) & 0x4 ) // bit 2
+ inBCD = FALSE;
+ // wait for time update to complete before reading the values
+ while( ReadRtcIndexedRegister(0xA) & 0x80 ); // while bit 7 is set the
+ // time update is in progress
+ //read current hour, minute, second
+ Hour = ReadRtcIndexedRegister(0x4);
+ Minute = ReadRtcIndexedRegister(0x2);
+ Second = ReadRtcIndexedRegister(0x0);
+
+ //convert second to decimal from BCD and increment by 1
+ if(inBCD)
+ Second = (Second >> 4) * 10 + (Second & 0x0F);
+ Second += 2;
+
+ if(Second > 59){
+ Second -= 60;
+ if(inBCD)
+ Minute = (Minute >> 4) * 10 + (Minute & 0x0F);
+ Minute++;
+ if(Minute > 59){
+ Minute = 0;
+ if(inBCD)
+ Hour = (Hour >> 4) * 10 + (Hour & 0x0F);
+ Hour++;
+ // check 24 hour mode/12 hour mode
+ if( ReadRtcIndexedRegister(0xB) & 0x2 ) {// bit 1 1=24hour else 12 hour
+ if(Hour > 23)
+ Hour = 0;
+ } else {
+ if(Hour > 11)
+ Hour = 0;
+ }
+
+ if(inBCD)
+ Hour = Hour % 10 + ( (Hour / 10) << 4 ) ;
+ }
+ if(inBCD)
+ Minute = Minute % 10 + ( (Minute / 10) << 4 ) ;
+ }
+
+ //convert from decimal to BCD
+ if(inBCD)
+ Second = Second % 10 + ( (Second / 10) << 4 ) ;
+
+ //set the alarm
+
+ WriteRtcIndexedRegister(0x5, Hour);
+ WriteRtcIndexedRegister(0x3, Minute);
+ WriteRtcIndexedRegister(0x1, Second);
+ //enable the alarm
+ WriteRtcIndexedRegister(0xB, ( ReadRtcIndexedRegister(0xB) | ((UINT8)( 1 << 5 )) ));
+
+// ========== PORTING REQUIRED ===========================================================
+// Current implementation to simulate the Warm Reboot may not be sufficient on some platforms.
+// S3 transition may require additional Chipset/Platform coding.
+// If needed add any necessary OEM hooks to be able to put the system into S3 at the end of this handler
+//========================================================================================
+
+ //set RTC_EN bit in PM1_EN to wake up from the alarm
+ IoWrite16(PM_BASE_ADDRESS + 0x02, ( IoRead16(PM_BASE_ADDRESS + 0x02) | (1 << 10) ));
+
+ //Disable Sleep SMI to avoid SMI re-entrance.
+// IoWrite16(PM_BASE_ADDRESS + 0x30, ( IoRead16(PM_BASE_ADDRESS + 0x30) & (~BIT4) ));
+
+ //modify power management control register to reflect S3
+ IoData = IoRead32(PM_BASE_ADDRESS + 0x04);
+ //following code is applicable to Intel PCH only.
+ IoData &= ~(0x1C00);
+ IoData |= 0x1400; //Suspend to RAM
+/*
+ // AMD w/a to enter S3 state
+ IoData |= 0x2C00; //Suspend to RAM
+ {
+ UINT8 Temp8;
+ IoWrite8(0xCD6, 0x004);
+ Temp8 = IoRead8(0xCD7);
+ Temp8 &= ~(BIT7);
+ IoWrite8(0xCD6, 0x004);
+ IoWrite8(0xCD7, Temp8);
+ IoWrite8(0xCD6, 0x007);
+ IoWrite8(0xCD7, BIT7);
+ }
+}
+*/
+ IoWrite32(PM_BASE_ADDRESS + 0x04, IoData );
+}
+//#else
+//extern SBLib_ResetSystem( IN EFI_RESET_TYPE ResetType );
+#endif
+extern SBLib_ResetSystem( IN EFI_RESET_TYPE ResetType );
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: SmiS5CapsuleCallback
+//
+// DESCRIPTION: SMI handler to perform capsule reset (bounce from S5 to S3)
+// ========== PORTING REQUIRED ===========================================================
+// Current implementation to simulate the Warm Reboot may not be sufficient on some platforms.
+// S3 transition may require additional Chipset/Platform coding.
+// If needed add any necessary OEM hooks to be able to put the system into S3 at the end of this handler
+//========================================================================================
+//
+// Input:
+// IN EFI_HANDLE DispatchHandle Handle of SMI dispatch
+// protocol
+// IN EFI_SMM_SX_DISPATCH_CONTEXT* DispatchContext Pointer to SMI dispatch
+// context structure
+//
+// Output:
+// VOID
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SmiS5CapsuleCallback ( IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
+){
+ EFI_PHYSICAL_ADDRESS IoData;
+ UINTN Size;
+ EFI_CAPSULE_HEADER *CapsuleHeader;
+ AMI_FLASH_UPDATE_BLOCK FlUpdateBlock;
+
+ TRACE((TRACE_ALWAYS,"SecSMI. S5 Trap\n"));
+
+ //
+ //Check if the Capsule update is supported by platform policy
+ //
+ if (!SupportUpdateCapsuleReset())
+ return;
+
+ Size=sizeof(AMI_FLASH_UPDATE_BLOCK);
+ if(EFI_ERROR(pRS->GetVariable(FLASH_UPDATE_VAR,&FlashUpdGuid, NULL, &Size, &FlUpdateBlock)) ||
+ FlUpdateBlock.FlashOpType != FlCapsule)
+ return;
+
+ // verify the FW capsule is in memory.
+ Size = sizeof(EFI_PHYSICAL_ADDRESS);
+ if(EFI_ERROR(pRS->GetVariable(CAPSULE_UPDATE_VAR,&CapsuleVendorGuid, NULL, &Size, &IoData)))
+ return;
+
+ if(IoData != (EFI_PHYSICAL_ADDRESS)gpEfiCapsuleHdr ||
+ !IsAddressInSmram((EFI_PHYSICAL_ADDRESS)IoData, sizeof(EFI_PHYSICAL_ADDRESS)))
+ return;
+
+ CapsuleHeader = (EFI_CAPSULE_HEADER*)gpEfiCapsuleHdr[0].DataBlock;
+ //
+ // Compare GUID with APTIO_FW_CAPSULE_GUID
+ //
+ if (guidcmp (&CapsuleHeader->CapsuleGuid, &gFWCapsuleGuid))
+ return;
+
+#if CSLIB_WARM_RESET_SUPPORTED == 1
+ SBLib_ResetSystem(EfiResetWarm);
+#else
+ S3RTCresume();
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SupportUpdateCapsuleReset
+//
+// Description: This function returns platform policy capability for capsule update via a system reset.
+//
+// Input: None
+//
+// Output: TRUE - memory can be preserved across reset
+// FALSE - memory integrity across reset is not guaranteed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SupportUpdateCapsuleReset (
+ VOID
+)
+{
+ //
+ //If the platform has a way to guarantee the memory integrity across a system reset, return
+ //TRUE, else FALSE.
+ //
+ if( (FlUpdatePolicy.FlashUpdate & FlCapsule) ||
+ (FlUpdatePolicy.BBUpdate & FlCapsule))
+ return TRUE;
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateCapsule
+//
+// Description: This code prepares Capsule Update EFI Variable
+//
+// Input:
+// IN EFI_CAPSULE_HEADER **CapsuleHeaderArray - array of pointers to capsule headers passed in
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_INVALID_PARAMETER - CapsuleCount is less than 1,CapsuleGuid is not supported
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS UpdateCapsule (
+ IN FUNC_FLASH_SESSION_BLOCK *pSessionBlock,
+ IN APTIO_FW_CAPSULE_HEADER *pFwCapsuleHdr
+){
+ EFI_STATUS Status;
+ EFI_CAPSULE_HEADER *pEfiCapsuleHdr = NULL;
+ EFI_CAPSULE_BLOCK_DESCRIPTOR *pCapsuleMailboxPtr;
+ UINT32 Attributes, Index;
+
+ //
+ //Compare GUID with APTIO_FW_CAPSULE_GUID
+ //
+ if (!pFwCapsuleHdr ||
+ guidcmp (&pFwCapsuleHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid)
+ )
+ return EFI_DEVICE_ERROR;
+
+ pCapsuleMailboxPtr = gpEfiCapsuleHdr;
+ Index = 0;
+#if !defined(FWCAPSULE_2_0_SUPPORT) || FWCAPSULE_2_0_SUPPORT == 0
+ pEfiCapsuleHdr = (EFI_CAPSULE_HEADER*)&pCapsuleMailboxPtr[4];
+// New Capsule PPI supports single CapHdr.
+// construct dummy EfiCapHdr struct within pEfiCapsuleHdr as 1st element to be linked from Mailbox
+ MemCpy((VOID*)pEfiCapsuleHdr, &gFWCapsuleGuid, sizeof(EFI_GUID));
+ pEfiCapsuleHdr->Flags = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
+ pEfiCapsuleHdr->HeaderSize = sizeof(EFI_CAPSULE_HEADER);
+ pEfiCapsuleHdr->CapsuleImageSize = pFwCapsuleHdr->CapHdr.CapsuleImageSize + sizeof(EFI_CAPSULE_HEADER);
+ // create ScatterGather list: use pre-allocated runtime memory
+ pCapsuleMailboxPtr[Index].Length = pEfiCapsuleHdr->HeaderSize;
+ pCapsuleMailboxPtr[Index].DataBlock = (EFI_PHYSICAL_ADDRESS)pEfiCapsuleHdr;
+ Index++;
+#endif
+ pCapsuleMailboxPtr[Index].Length = pFwCapsuleHdr->CapHdr.HeaderSize;
+ pCapsuleMailboxPtr[Index].DataBlock = (EFI_PHYSICAL_ADDRESS)pFwCapsuleHdr;
+ pCapsuleMailboxPtr[Index+1].Length = pFwCapsuleHdr->CapHdr.CapsuleImageSize-pFwCapsuleHdr->CapHdr.HeaderSize;
+ if((UINT32*)pFwCapsuleLowMem == (UINT32*)pFwCapsuleHdr) {
+ // Fw Cap Hdr is on top of Payload
+
+ pCapsuleMailboxPtr[Index+1].DataBlock = pCapsuleMailboxPtr[Index].DataBlock+pCapsuleMailboxPtr[Index].Length;
+ } else {
+ // Fw Cap Hdr is embedded inside Payload
+ pCapsuleMailboxPtr[Index+1].DataBlock = (EFI_PHYSICAL_ADDRESS)pFwCapsuleLowMem;
+ }
+ pCapsuleMailboxPtr[Index+2].Length = 0;
+ pCapsuleMailboxPtr[Index+2].DataBlock = 0;
+ //
+ //Check if the platform supports update capsule across a system reset
+ //
+ if (!SupportUpdateCapsuleReset()) {
+ return EFI_UNSUPPORTED;
+ }
+ // Erase prev copy
+ Status = pRS->SetVariable ( CAPSULE_UPDATE_VAR, &CapsuleVendorGuid,0,0,NULL);
+ Attributes = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ Status = pRS->SetVariable ( CAPSULE_UPDATE_VAR, &CapsuleVendorGuid,
+ Attributes, sizeof(EFI_PHYSICAL_ADDRESS),(VOID*)&pCapsuleMailboxPtr);
+
+ if(!EFI_ERROR(Status))
+ return Status;
+
+ return EFI_DEVICE_ERROR;
+}
+
+#endif //#if FWCAPSULE_RECOVERY_SUPPORT == 1
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetFlashUpdateVar
+//
+// Description: This code finds if the capsule needs reset to update, if no, update immediately.
+//
+// Input:
+// IN EFI_CAPSULE_HEADER **CapsuleHeaderArray - array of pointers to capsule headers passed in
+// IN UINTN CapsuleCount - number of capsule
+// IN EFI_PHYSICAL_ADDRESS ScatterGatherList - physical address of datablock list points to capsule
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_INVALID_PARAMETER - CapsuleCount is less than 1,CapsuleGuid is not supported
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetFlashUpdateVar (
+ IN FUNC_FLASH_SESSION_BLOCK *pSessionBlock
+){
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT32 CounterHi;
+
+ if(pSessionBlock->FlUpdBlock.FlashOpType == FlRecovery &&
+ pSessionBlock->FlUpdBlock.FwImage.AmiRomFileName[0] == 0
+ )
+ return EFI_DEVICE_ERROR;
+
+ CounterHi = 0;
+ Size = sizeof(UINT32);
+// MonotonicCounter is a boot time service, hence the variable may have restricted access in runtime
+ if(EFI_ERROR(pRS->GetVariable(L"MonotonicCounter", &gAmiGlobalVariableGuid,
+ NULL, &Size, &CounterHi))
+ )
+// return Status;//EFI_DEVICE_ERROR;
+//SetMode should set FlashUpd even if no MC var detected.
+ CounterHi=0xffffffff;
+
+ pSessionBlock->FlUpdBlock.MonotonicCounter = CounterHi;
+ CounterHi = (EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS);
+ // Erase prev copy
+ Status = pRS->SetVariable ( FLASH_UPDATE_VAR, &FlashUpdGuid,0,0,NULL);
+ Status = pRS->SetVariable ( FLASH_UPDATE_VAR, &FlashUpdGuid, CounterHi,
+ sizeof(AMI_FLASH_UPDATE_BLOCK), (VOID*) &pSessionBlock->FlUpdBlock
+ );
+
+ if(!EFI_ERROR(Status))
+ return Status;
+
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: GetFlUpdPolicy
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS GetFlUpdPolicy(
+ IN OUT FLASH_POLICY_INFO_BLOCK *InfoBlock
+)
+{
+ UINT32 KeySize = DEFAULT_RSA_KEY_MODULUS_LEN;
+
+//TRACE((TRACE_ALWAYS,"SecSMI. GetPolicy. %X_%X\n",FlUpdatePolicy.FlashUpdate, FlUpdatePolicy.BBUpdate));
+
+ if(IsAddressInSmram((EFI_PHYSICAL_ADDRESS)InfoBlock, sizeof(FLASH_POLICY_INFO_BLOCK)))
+ return EFI_DEVICE_ERROR;
+
+ MemCpy(&InfoBlock->FlUpdPolicy, &FlUpdatePolicy, sizeof(FLASH_UPD_POLICY));
+ MemSet(&InfoBlock->PKpub, KeySize, 0xFF);
+ if(gpPubKeyHndl.BlobSize < KeySize)
+ KeySize = gpPubKeyHndl.BlobSize;
+ MemCpy(&InfoBlock->PKpub, gpPubKeyHndl.Blob, KeySize);
+
+ InfoBlock->ErrorCode = 0;
+
+ return EFI_SUCCESS;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SetFlUpdMethod
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SetFlUpdMethod(
+ IN OUT FUNC_FLASH_SESSION_BLOCK *pSessionBlock
+)
+{
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+#if RUNTIME_SECURE_UPDATE_FLOW == 1
+ UINT32 HashBlock;
+ UINT32 BlockSize;
+ UINT8 *BlockAddr;
+#endif
+ UINT32 *FSHandl;
+ APTIO_FW_CAPSULE_HEADER *pFwCapsuleHdr;
+
+//TRACE((TRACE_ALWAYS,"SecSMI. SetFlash\nSize : %X\n",pSessionBlock->FlUpdBlock.ImageSize));
+
+ if(IsAddressInSmram((EFI_PHYSICAL_ADDRESS)pSessionBlock, sizeof(FUNC_FLASH_SESSION_BLOCK)))
+ return EFI_DEVICE_ERROR;
+
+//if(pSessionBlock->FlUpdBlock.FlashOpType == FlRecovery)
+//TRACE((TRACE_ALWAYS,"File Name: %s\n",pSessionBlock->FlUpdBlock.FwImage.AmiRomFileName));
+//else
+//TRACE((TRACE_ALWAYS,"Image Adr: %X\n",pSessionBlock->FlUpdBlock.FwImage.CapsuleMailboxPtr[0]));
+
+//TRACE((TRACE_ALWAYS,"ROMmap : %X\n",pSessionBlock->FlUpdBlock.ROMSection));
+//TRACE((TRACE_ALWAYS,"FlOpType : %X\n",pSessionBlock->FlUpdBlock.FlashOpType));
+// Verify if chosen Flash method is compatible with FlUpd Policy
+ if(((pSessionBlock->FlUpdBlock.ROMSection & (1<<BOOT_BLOCK)) && (pSessionBlock->FlUpdBlock.FlashOpType & FlUpdatePolicy.BBUpdate)) ||
+ (!(pSessionBlock->FlUpdBlock.ROMSection & (1<<BOOT_BLOCK))&& (pSessionBlock->FlUpdBlock.FlashOpType & FlUpdatePolicy.FlashUpdate))
+ ){
+
+//TRACE((TRACE_ALWAYS,"Buff Adr : %X\nBuff Size: %X\n",pFwCapsuleLowMem, gRomFileSize));
+//!!! make sure Flash blocks BOOT_BLOCK, MAIN_, NV_ and EC_ are matching enum types in FlashUpd.h
+ // Get Flash Update mode
+ switch(pSessionBlock->FlUpdBlock.FlashOpType)
+ {
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+ case FlCapsule:
+#endif
+ case FlRuntime:
+ // common for FlRuntime or Capsule
+ if(pSessionBlock->FlUpdBlock.ImageSize > gFwCapMaxSize)
+ break; // suspecting buffer overrun.
+
+ SecSmiFlash.pFwCapsule = pFwCapsuleLowMem;
+ // AFU updates the address in CapsuleMailboxPtr if
+ // it's capable of allocating large buffer to load entire FW Capsule image
+ if(pSessionBlock->FlUpdBlock.FwImage.CapsuleMailboxPtr[0] != 0 )
+ {
+ if(IsAddressInSmram((EFI_PHYSICAL_ADDRESS)pSessionBlock->FlUpdBlock.FwImage.CapsuleMailboxPtr[0],
+ pSessionBlock->FlUpdBlock.ImageSize))
+ return EFI_DEVICE_ERROR;
+#if NEW_BIOS_MEM_ALLOC != 2
+ if(SecSmiFlash.pFwCapsule != NULL) {
+ // prevent leaking of the SMM code to the external buffer
+ if(!IsAddressInSmram((EFI_PHYSICAL_ADDRESS)SecSmiFlash.pFwCapsule, sizeof(UINTN)))
+ return EFI_DEVICE_ERROR;
+
+ MemCpy((UINT8*)SecSmiFlash.pFwCapsule,
+ (UINT8*)pSessionBlock->FlUpdBlock.FwImage.CapsuleMailboxPtr[0],
+ pSessionBlock->FlUpdBlock.ImageSize);
+ }
+ else
+#endif
+ SecSmiFlash.pFwCapsule = (UINT32*)pSessionBlock->FlUpdBlock.FwImage.CapsuleMailboxPtr[0];
+ }
+ // else AFU must've uploaded the image to designated SMM space using LoadFw command
+
+ // verify we got a capsule at pFwCapsuleLowMem, update a ptr to FwCapHdr within Payload image
+ Status = CapsuleValidate((UINT8**)&(SecSmiFlash.pFwCapsule), &pFwCapsuleHdr);
+ if(!pFwCapsuleHdr ||
+ EFI_ERROR(Status)) break;
+ // capture RomLayout from new Secure Image if it's loaded in memory and validated
+ SecSmiFlash.RomLayout = (ROM_AREA *)(UINTN)((UINT32)pFwCapsuleHdr+pFwCapsuleHdr->RomLayoutOffset);
+ if(pSessionBlock->FlUpdBlock.FlashOpType == FlRuntime)
+ {
+#if RUNTIME_SECURE_UPDATE_FLOW == 1
+ // Fill in gShaHashTbl Hash Table
+ BlockSize = FLASH_BLOCK_SIZE;
+ BlockAddr = (UINT8*)SecSmiFlash.pFwCapsule;
+ for(HashBlock = 0; HashBlock < SEC_FLASH_HASH_TBL_BLOCK_COUNT; HashBlock++)
+ {
+
+ Status = gAmiSig->Hash(gAmiSig, &gEfiHashAlgorithmSha256Guid,
+ 1, &BlockAddr, (const UINTN*)&BlockSize, gHashTbl[HashBlock]);
+ if (EFI_ERROR(Status)) break;
+ BlockAddr+= (UINTN)(BlockSize);
+ }
+#endif
+ // done for Runtime Upd
+ break;
+ }
+ // Set Capsule EFI Var if Capsule(Verify Capsule Mailbox points to FW_CAPSULE)
+ pSessionBlock->FlUpdBlock.ImageSize = pFwCapsuleHdr->CapHdr.CapsuleImageSize;
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+ Status = UpdateCapsule (pSessionBlock, pFwCapsuleHdr);
+ if(EFI_ERROR(Status)) break;
+#endif
+ // common for Recovery or Capsule
+ case FlRecovery:
+ // Set FlUpd EFI Var (Get MC, verify RecFileName)
+ Status = SetFlashUpdateVar (pSessionBlock);
+ break;
+
+ default:
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ // Set Error Status
+ if (Status != EFI_SUCCESS) {
+ SecSmiFlash.FSHandle = 0;
+ SecSmiFlash.pFwCapsule = NULL;
+ SecSmiFlash.RomLayout = RomLayout; // back to default RomLayout
+ pSessionBlock->FSHandle = 0;
+ pSessionBlock->ErrorCode = 1;
+
+ return EFI_DEVICE_ERROR;
+ }
+ // FSHandle is updated if Capsule validation passed.
+ // Create FSHandle as 1st 4 bytes of gHashTbl. It must be different each time
+ // SetMethod is called with new Image
+ FSHandl = (UINT32*)gHashTbl;
+ SecSmiFlash.FSHandle = *FSHandl; // should be unique per Capsule;
+ pSessionBlock->FSHandle = SecSmiFlash.FSHandle;
+ pSessionBlock->ErrorCode = 0;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: LoadFwImage
+//
+// Description: Routine is called in a loop by the Flash tool.
+// Depending on the OS environment, Flash tool passes either an entire
+// Flash Image into SMM buffer or block by block.
+// E.g AFUDOS could allocate a contiguous buffer for the entire ROM buffer,
+// while certain OSes (Linux) may only allocate limited buffer sizes
+//
+// Input: FUNC_BLOCK -> Address, size
+//
+// Output: FUNC_BLOCK -> Status
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS LoadFwImage(
+ IN OUT FUNC_BLOCK *pFuncBlock
+)
+{
+ if(IsAddressInSmram((EFI_PHYSICAL_ADDRESS)pFuncBlock, sizeof(FUNC_BLOCK)))
+ return EFI_DEVICE_ERROR;
+
+ // prevent leaking of the SMM code to the external buffer
+ if(IsAddressInSmram((EFI_PHYSICAL_ADDRESS)pFuncBlock->BufAddr, pFuncBlock->BlockSize))
+ return EFI_DEVICE_ERROR;
+
+ pFuncBlock->ErrorCode = 1;
+
+ SecSmiFlash.FSHandle = 0; // clear out Hndl. Will be set to valid number in SetFlashMethod
+ SecSmiFlash.pFwCapsule = NULL;
+ SecSmiFlash.RomLayout = RomLayout; // back to default RomLayout
+
+//TRACE((TRACE_ALWAYS,"SecSMI. LoadImage at %X, size %X\n",(UINT32)pFwCapsuleLowMem + pFuncBlock->BlockAddr, pFuncBlock->BlockSize));
+
+ if(pFwCapsuleLowMem == NULL)
+ return EFI_DEVICE_ERROR;
+
+// assuming the address in 0 based offset in new ROM image
+ if((UINT64)((UINT32)pFwCapsuleLowMem + pFuncBlock->BlockAddr + pFuncBlock->BlockSize) >
+ (UINT64)((UINT32)pFwCapsuleLowMem + gFwCapMaxSize)
+ )
+ return EFI_DEVICE_ERROR;
+
+ MemCpy((VOID*)((UINT32)pFwCapsuleLowMem+pFuncBlock->BlockAddr),
+ (UINT8*)pFuncBlock->BufAddr, pFuncBlock->BlockSize);
+
+ pFuncBlock->ErrorCode = (UINT8)MemCmp(
+ (VOID*)((UINT32)pFwCapsuleLowMem+pFuncBlock->BlockAddr),
+ (VOID*)pFuncBlock->BufAddr, pFuncBlock->BlockSize);
+
+ pFuncBlock->ErrorCode = 0;
+
+ return EFI_SUCCESS;
+}
+// End Secured Flash Update API
+
+#if RUNTIME_SECURE_UPDATE_FLOW == 1
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BeforeSecureUpdate
+//
+// Description: Verifies if the Update range is protected by Signature
+// 1. return Success if flash region is inside unSigned RomArea
+// 2. if region is signed - compare its hash with pre-calculated Hash in smm
+// and return pointer to internal DataBuffer
+//
+// Input:
+// VOID* FlashAddress Pointer to address of a flash
+//
+// Output: Status
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS BeforeSecureUpdate (
+ VOID* FlashAddress, UINTN Size, UINT8 **DataBuffer
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ ROM_AREA *Area;
+ UINT8 *BuffAddr;
+ UINT8 *PageAddr;
+ UINT8 HashCounter;
+ UINTN PageSize;
+ UINTN PageCount;
+ UINT32 *FSHandl;
+
+ // enforce write protection if RomArea undefined
+ if ( RomLayout == NULL )
+ Status = EFI_WRITE_PROTECTED;
+
+ for (Area = RomLayout; Area && Area->Size!=0; Area++)
+ {
+ if(Area->Address == 0) // construct an Address field if not initialized
+ Area->Address = (UINT64)((0xFFFFFFFF - FLASH_SIZE) + 1)+Area->Offset;
+//TRACE((-1, "RomArea %8X(%8X) + Size %8X = %8X, Attr %X\n",Area->Address,Area->Offset, Area->Size, (UINT64)((UINTN)Area->Address+Area->Size), Area->Attributes));
+ if(
+ (((UINT64)FlashAddress >= (UINT64)(Area->Address)) &&
+ ((UINT64)FlashAddress < (UINT64)(Area->Address+Area->Size)))
+ ||
+ (((UINT64)(Area->Address) >= (UINT64)FlashAddress) &&
+ ((UINT64)(Area->Address) < (UINT64)((UINT64)FlashAddress + Size))) )
+ {
+ if (Area->Attributes & ROM_AREA_FV_SIGNED)
+ {
+ Status = EFI_WRITE_PROTECTED;
+ break;
+ }
+//TRACE((-1, "\nSignAttr %x(%x)\nRomArea %8X, Size %8X, (%8X)\nFlsAddr %8X, Size %8X, (%8X)\n", Area->Attributes, (Area->Attributes & ROM_AREA_FV_SIGNED),
+// Area->Address, Area->Size, (UINT64)((UINTN)Area->Address+Area->Size),
+// (UINTN)FlashAddress, Size, (UINT64)((UINTN)FlashAddress+Size)));
+ }
+ }
+//if(Status != EFI_WRITE_PROTECTED) {
+// TRACE((-1, "SpiOffs %8X, Size %8X, (%8X)\n", (0-(UINTN)FlashAddress), Size, (0-(EFI_PHYSICAL_ADDRESS)((UINTN)FlashAddress+Size))));
+//}
+ if(Status == EFI_WRITE_PROTECTED &&
+ (FlUpdatePolicy.FlashUpdate & FlRuntime)
+ ){
+ // check Verify status by comparing FSHandl with gHashTbl[0]
+ // should be unique per Capsule;
+ FSHandl = (UINT32*)gHashTbl;
+ if(SecSmiFlash.FSHandle == 0 ||
+ SecSmiFlash.FSHandle != *FSHandl)
+ return Status; // EFI_WRITE_PROTECTED
+
+ PageSize = FLASH_BLOCK_SIZE;
+ PageCount=( (UINTN)FlashAddress - Flash4GBMapStart) / PageSize;
+
+ if(SecSmiFlash.pFwCapsule != NULL)
+ {
+ // Flash Write -> Update ptr to internal Acpi NVS or SMM Buffer
+ BuffAddr = (UINT8*)SecSmiFlash.pFwCapsule;
+ PageAddr = (UINT8*)((UINTN)BuffAddr + (PageSize * PageCount));
+ BuffAddr = (UINT8*)((UINTN)BuffAddr + ((UINTN)FlashAddress - Flash4GBMapStart));
+
+ Status = EFI_SUCCESS;
+ HashCounter = 2; // addr may rollover to next flash page
+ while(HashCounter-- && PageCount < SEC_FLASH_HASH_TBL_BLOCK_COUNT)
+ {
+ // compare calculated block hash with corresponding hash from the Hw Hash Table
+ // if no match -> make Size=0 to skip Flash Write Op
+ Status = gAmiSig->Hash(gAmiSig, &gEfiHashAlgorithmSha256Guid,
+ 1, (const UINT8**)&PageAddr, (const UINTN*)&PageSize, gHashDB);
+ if(EFI_ERROR(Status) ||
+ MemCmp(gHashDB, SecSmiFlash.HashTbl[PageCount], SHA256_DIGEST_SIZE)
+ ){
+//TRACE((-1, "Hash Err! FlashBuff = %8X, Data = %8X, BlockAddr=%x, BlockSize=%x\n", BuffAddr, *((UINT32*)BuffAddr), PageAddr, Size));
+ return EFI_WRITE_PROTECTED;
+ }
+ // repeat Hash check on next Flash Block if Write Block overlaps the Flash Block boundary
+ PageCount++;
+ PageAddr = (UINT8*)((UINTN)PageAddr + PageSize);
+ if((BuffAddr+Size) <= PageAddr)
+ break;
+ }
+ // Erase
+ if(DataBuffer != NULL)
+ *DataBuffer = BuffAddr;
+ }
+ }
+
+ return Status;
+}
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SecureFlashWrite
+//
+// Description: Allows to write to flash device is Secure Capsule is loaded into memory
+// Function replacing Flash->Write API call
+//
+// Input: VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+//
+//
+// Output: EFI_SUCCESS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS SecureFlashWrite (
+ VOID* FlashAddress, UINTN Size, VOID* DataBuffer
+)
+{
+ EFI_STATUS Status;
+ UINT8 *CurrBuff;
+
+ CurrBuff = (UINT8*)DataBuffer;
+ Status = BeforeSecureUpdate(FlashAddress, Size, &CurrBuff);
+//TRACE((-1, "SecSMIFlash Write %X, BuffAddr=%X(%X) Lock Status=%r\n", FlashAddress, DataBuffer, CurrBuff, Status));
+ if(!EFI_ERROR(Status))
+ return pFlashWrite(FlashAddress, Size, CurrBuff);
+
+ return Status;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SecureFlashErase
+//
+// Description: Allows erase of flash device is Secure Capsule is loaded into memory
+// Function replacing Flash->Erase API call
+//
+// Input: NON
+//
+//
+// Output: EFI_SUCCESS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS SecureFlashErase (
+ VOID* FlashAddress, UINTN Size
+)
+{
+ EFI_STATUS Status;
+
+ Status = BeforeSecureUpdate(FlashAddress, Size, NULL);
+//TRACE((-1, "SecSMIFlash Erase %X - %X Lock Status=%r\n", FlashAddress, Size, Status));
+ if(!EFI_ERROR(Status))
+ return pFlashErase(FlashAddress, Size);
+
+ return Status;//EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetFwCapFfs
+//
+// Description: Loads binary from RAW section of X firwmare volume
+//
+// Input:
+// NameGuid - The guid of binary file
+// Buffer - Returns a pointer to allocated memory. Caller must free it when done.
+// Size - Returns the size of the binary loaded into the buffer.
+//
+// Output: Buffer - returns a pointer to allocated memory. Caller
+// must free it when done.
+// Size - returns the size of the binary loaded into the
+// buffer.
+// EFI_NOT_FOUND - Can't find the binary.
+// EFI_LOAD_ERROR - Load fail.
+// EFI_SUCCESS - Load success.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+GetFwCapFfs (
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ EFI_HANDLE *HandleBuff;
+ UINT32 AuthenticationStatus;
+
+ *Buffer=0;
+ *Size=0;
+ Status = pBS->LocateHandleBuffer (ByProtocol,&gEfiFirmwareVolumeProtocolGuid,NULL,&HandleCount,&HandleBuff);
+ if (EFI_ERROR (Status) || HandleCount == 0) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Find desired image in all Fvs
+ //
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = pBS->HandleProtocol (HandleBuff[Index],&gEfiFirmwareVolumeProtocolGuid,&Fv);
+
+ if (EFI_ERROR (Status)) {
+ continue;//return EFI_LOAD_ERROR;
+ }
+ //
+ // Try a raw file
+ //
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid, //&gFwCapFfsGuid,
+ EFI_SECTION_FREEFORM_SUBTYPE_GUID,//EFI_SECTION_RAW
+ 0, //Instance
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+
+ if (Status == EFI_SUCCESS) break;
+ }
+
+ pBS->FreePool(HandleBuff);
+
+ if (Index >= HandleCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetRomLayout
+//
+// Description:
+//
+// Input:
+// IN EFI_HANDLE ImageHandle Image Handle
+// IN EFI_SYSTEM_TABLE *SystemTable Pointer to System Table
+//
+// Output: EFI_STATUS
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+EFI_STATUS GetRomLayout(
+ IN EFI_SYSTEM_TABLE *SystemTable,
+ EFI_SMM_BASE_PROTOCOL *SmmBase,
+ OUT ROM_AREA **RomLayout
+)
+{
+ EFI_STATUS Status;
+ static EFI_GUID HobListGuid = HOB_LIST_GUID;
+ static EFI_GUID AmiRomLayoutHobGuid = AMI_ROM_LAYOUT_HOB_GUID;
+ ROM_LAYOUT_HOB *RomLayoutHob;
+ UINTN RomLayoutSize=0, Size;
+ ROM_AREA *Area;
+ APTIO_FW_CAPSULE_HEADER *FwCapHdr;
+ UINT8* pFwCapHdr=NULL;
+
+// 1. Try to locate RomLayout from embedded CapHdr Ffs
+ Status = GetFwCapFfs(&gFwCapFfsGuid, &pFwCapHdr, &Size);
+ if(!EFI_ERROR(Status))
+ {
+ // Skip over Section GUID
+ FwCapHdr = (APTIO_FW_CAPSULE_HEADER*)pFwCapHdr;
+ (UINT8*)FwCapHdr += sizeof (EFI_GUID);
+ Size -= sizeof (EFI_GUID);
+ *RomLayout = (ROM_AREA *)(UINTN)((UINT32)FwCapHdr+FwCapHdr->RomLayoutOffset);
+ RomLayoutSize = sizeof(ROM_AREA);
+ for (Area=*RomLayout; Area->Size!=0 && RomLayoutSize<=(Size - FwCapHdr->RomLayoutOffset); Area++)
+ {
+ RomLayoutSize+=sizeof(ROM_AREA);
+ }
+// TRACE((-1, "Get Rom Map from the FwCap FFS at %X(size 0x%X)\nRomLayout offs %X(size 0x%X)\n", FwCapHdr, Size, FwCapHdr->RomLayoutOffset, RomLayoutSize));
+ Area=*RomLayout;
+ }
+ else
+ {
+// 2. Backup: Use primary RomLayout from Rom Layout HOB.
+// This one does not yet report the Rom Hole regions
+ //----- Get HobList -------------------------------------
+ RomLayoutHob = GetEfiConfigurationTable(SystemTable, &HobListGuid);
+ if (RomLayoutHob!=NULL)
+ {
+ // -------- Get RomLayoutHob ----------------------
+ if (!EFI_ERROR(
+ FindNextHobByGuid(&AmiRomLayoutHobGuid, &RomLayoutHob)
+ ))
+ {
+ RomLayoutSize = RomLayoutHob->Header.Header.HobLength
+ - sizeof(ROM_LAYOUT_HOB);
+
+ Area=(ROM_AREA*)((UINT8*)RomLayoutHob+1);
+ //TRACE((-1, "Get Default Rom Map from the Hob at %X\n", Area));
+ }
+ }
+ }
+ if(RomLayoutSize)
+ {
+ //---Allocate memory in SMRAM for RomLayout---
+ *RomLayout = NULL;
+ Status = pSmst->SmmAllocatePool(EfiRuntimeServicesData, RomLayoutSize,(void **)RomLayout);
+ if (EFI_ERROR(Status) || *RomLayout == NULL)
+ return EFI_NOT_FOUND;
+
+ pBS->CopyMem( *RomLayout, Area, RomLayoutSize);
+
+ if(pFwCapHdr)
+ pBS->FreePool(pFwCapHdr);
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+#endif //#if RUNTIME_SECURE_UPDATE_FLOW == 1
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsAddressInSmram
+//
+// Description: CThis function check if the address is in SMRAM
+//
+// Input:
+// Address - the buffer address to be checked.
+// Range - the buffer length to be checked
+//
+// Output:
+// TRUE this address is in SMRAM.
+// FALSE this address is NOT in SMRAM.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN IsAddressInSmram (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+)
+{
+ UINTN Index;
+//TRACE((TRACE_ALWAYS,"Addr in SMRAM %X_%X\n",Buffer, Length));
+ for (Index = 0; Index < mSmramRangeCount; Index ++) {
+ if (((Buffer >= mSmramRanges[Index].CpuStart) && (Buffer < mSmramRanges[Index].CpuStart + mSmramRanges[Index].PhysicalSize)) ||
+ ((mSmramRanges[Index].CpuStart >= Buffer) && (mSmramRanges[Index].CpuStart < Buffer + Length))) {
+//TRACE((TRACE_ALWAYS,"TRUE\n"));
+ return TRUE;
+ }
+ }
+//TRACE((TRACE_ALWAYS,"FALSE\n"));
+ return FALSE;
+}
+
+// !!! do not install if OFBD SecFlash is installed
+#if INSTALL_SECURE_FLASH_SW_SMI_HNDL == 1
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SecSMIFlashSMIHandler
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SecSMIFlashSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINT8 Data;
+ UINT64 pCommBuff;
+ UINT32 HighBufferAddress = 0;
+ UINT32 LowBufferAddress = 0;
+ UINTN i;
+ UINTN Cpu = pSmst->CurrentlyExecutingCpu - 1;
+
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+ //
+ // Found Invalid CPU number, return
+ //
+ if(Cpu == (UINTN) -1) {
+ return;
+ }
+
+ Data = (UINT8)DispatchContext->SwSmiInputValue;
+
+ pCpuSaveState = pSmst->CpuSaveState;
+ HighBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.ECX;
+ LowBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.EBX;
+ pCommBuff = HighBufferAddress;
+ pCommBuff = Shl64(pCommBuff, 32);
+ pCommBuff += LowBufferAddress;
+
+//TRACE((-1, "Sec SW SMI Flash Hook == 0x%x\n", Data));
+
+ switch(Data)
+ {
+ case SecSMIflash_Load: // 0x1d Send Flash Block to memory
+ LoadFwImage((FUNC_BLOCK *)pCommBuff);
+ break;
+
+ case SecSMIflash_GetPolicy: // 0x1e Get Fl Upd Policy
+ GetFlUpdPolicy((FLASH_POLICY_INFO_BLOCK *)pCommBuff);
+ break;
+
+ case SecSMIflash_SetFlash: // 0x1f Set Flash method
+ SetFlUpdMethod((FUNC_FLASH_SESSION_BLOCK *)pCommBuff);
+ break;
+ }
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: InSmmFunction
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InSmmFunction(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
+{
+#if INSTALL_SECURE_FLASH_SW_SMI_HNDL == 1
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch = NULL;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ UINTN Index;
+#endif
+#if FWCAPSULE_RECOVERY_SUPPORT == 1
+ EFI_SMM_SX_DISPATCH_CONTEXT SxDispatchContext;
+ EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatchProtocol;
+#endif
+
+ EFI_HANDLE Handle = NULL;
+ EFI_HANDLE DummyHandle = NULL;
+ EFI_STATUS Status;
+
+ UINTN Size = 0;
+ UINT8 MinSMIPort = SecSMIflash_Load; //0x1d
+ //UINT8 MinSMIPort = SecSMIflash_GetPolicy; //0x1e;
+ UINT8 MaxSMIPort = SecSMIflash_SetFlash; //0x1f;
+
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ EFI_SMM_ACCESS2_PROTOCOL *SmmAccess;
+#else
+ EFI_SMM_ACCESS_PROTOCOL *SmmAccess;
+#endif
+
+ InitAmiSmmLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol(&gAmiSmmDigitalSignatureProtocolGuid, NULL, &gAmiSig);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+
+// Test if Root Platform Key is available,else - don't install Flash Upd security measures.
+ gpPubKeyHndl.Blob = NULL;
+ gpPubKeyHndl.BlobSize = 0;
+ Status = gAmiSig->GetKey(gAmiSig, &gpPubKeyHndl, &gPRKeyGuid, gpPubKeyHndl.BlobSize, 0);
+//TRACE((TRACE_ALWAYS,"GetKey %r (%x, %d bytes)\n",Status, gpPubKeyHndl.Blob,gpPubKeyHndl.BlobSize));
+ if (EFI_ERROR(Status) || gpPubKeyHndl.Blob == NULL) {
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ return EFI_SUCCESS;
+ return Status;
+ }
+ //
+ // Get SMRAM information
+ //
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ Status = pBS->LocateProtocol (&gEfiSmmAccess2ProtocolGuid, NULL, (VOID **)&SmmAccess);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+#else
+ Status = pBS->LocateProtocol(&gEfiSmmAccessProtocolGuid, NULL, &SmmAccess);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+#endif
+ Size = 0;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ if (Size==0) return EFI_NOT_FOUND;
+ Status = pSmst->SmmAllocatePool (EfiRuntimeServicesData,Size,(VOID **)&mSmramRanges);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ Status = SmmAccess->GetCapabilities (SmmAccess, &Size, mSmramRanges);
+ if (EFI_ERROR(Status)) return Status;
+ mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+ //
+ // Allocate scratch buffer to hold entire Signed BIOS image for Secure Capsule and Runtime Flash Updates
+ // AFU would have to execute a sequence of SW SMI calls to push entire BIOS image to SMM
+ //
+ //NEW_BIOS_MEM_ALLOC == 2 AFU will allocate a buffer and provide pointer via SET_FLASH_METHOD API call.
+ //
+#if NEW_BIOS_MEM_ALLOC == 0
+ //
+ // Alternatively the buffer may be reserved within the SMM TSEG memory
+ //
+ Status = pSmmBase->SmmAllocatePool(pSmmBase, EfiRuntimeServicesData, gFwCapMaxSize, (void**)&pFwCapsuleLowMem);
+
+//TRACE((TRACE_ALWAYS,"SecSmiFlash: Alloc 0x%X bytes in SMM, %r\n",gRomFileSize, Status));
+#else
+#if NEW_BIOS_MEM_ALLOC == 1
+ //
+ // The buffer allocated in OS reserved memory below 4GB
+ //
+// Status = pST->BootServices->AllocatePool(EfiReservedMemoryType, gRomFileSize, &pFwCapsuleLowMem);
+ pFwCapsuleLowMem = (UINT32*)0xFFFFFFFF;
+ Status = pST->BootServices->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(gFwCapMaxSize), (EFI_PHYSICAL_ADDRESS*)&pFwCapsuleLowMem);
+//TRACE((TRACE_ALWAYS,"SecSmiFlash: AllocatePages=%X,(0x%x) %r\n",pFwCapsuleLowMem,gRomFileSize, Status));
+#endif
+#endif
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+#if NEW_BIOS_MEM_ALLOC < 2
+ MemSet((void*)pFwCapsuleLowMem, gFwCapMaxSize, 0 );
+#endif
+ //
+ // Allocate space to hold a Hash table for all Flash blocks
+ //
+ Size = SEC_FLASH_HASH_TBL_SIZE;
+ Status = pSmmBase->SmmAllocatePool(pSmmBase, EfiRuntimeServicesData, Size, (void**)&gHashTbl);
+ if (EFI_ERROR(Status)) return Status;
+ MemSet((void*)gHashTbl, Size, 0xdb );
+
+#if FWCAPSULE_RECOVERY_SUPPORT == 0
+ FlUpdatePolicy.FlashUpdate &=~FlCapsule;
+ FlUpdatePolicy.BBUpdate &=~FlCapsule;
+#else
+ //
+ // Reserve pool in smm runtime memory for capsule's mailbox list
+ //
+ Size = 4*sizeof(EFI_CAPSULE_BLOCK_DESCRIPTOR) + sizeof(EFI_CAPSULE_HEADER); // (4*16)+28
+ Status = pSmmBase->SmmAllocatePool(pSmmBase, EfiRuntimeServicesData, Size, (void**)&gpEfiCapsuleHdr);
+//TRACE((TRACE_ALWAYS,"Mailbox: AllocatePages=%X,(0x%x) %r\n",gpEfiCapsuleHdr,Size, Status));
+ if (EFI_ERROR(Status)) return Status;
+ MemSet((void*)gpEfiCapsuleHdr, Size, 0 );
+
+ //
+ // Install callback on S5 Sleep Type SMI. Needed to transition to S3 if Capsule's mailbox ie pending
+ // Locate the Sx Dispatch Protocol
+ //
+ // gEfiSmmSxDispatch2ProtocolGuid
+ Status = pBS->LocateProtocol (&gEfiSmmSxDispatchProtocolGuid,NULL,&SxDispatchProtocol);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR(Status)) return Status;
+ //
+ // Register the callback for S5 entry
+ //
+ if (SxDispatchProtocol && SupportUpdateCapsuleReset()) {
+ SxDispatchContext.Type = SxS5;
+ SxDispatchContext.Phase = SxEntry;
+ Status = SxDispatchProtocol->Register (SxDispatchProtocol,SmiS5CapsuleCallback,&SxDispatchContext,&Handle);
+ ASSERT_EFI_ERROR (Status);
+ }
+ if (EFI_ERROR(Status)) goto Done;
+#endif
+#if RUNTIME_SECURE_UPDATE_FLOW == 1
+/*
+AFU For Rom Holes in Runtime/Capsule upd
+ 1. Read full ROM image to ROM buffer
+ 2. Merge Rom Hole from input file to ROM buffer
+ 3. call "LoadImage" for full BIOS
+ 3. call "SetFlash" with Runtime update (NVRAM block should be unsigned!!!)
+ 4. calls to upd Rom hole -erase,write should pass
+*/
+ Status = GetRomLayout(SystemTable, pSmmBase, &RomLayout);
+//TRACE((TRACE_ALWAYS,"SecSmiFlash: Get Rom Layout ptr=%X, %r\n",RomLayout, Status));
+ // Rom Layout HOB may not be found in Recovery mode and if FW does not include built in FwCapsule Hdr file
+// if (EFI_ERROR(Status)) goto Done;
+ //
+ // Trap the original Flash Driver API calls to enforce
+ // Flash Write protection in SMM at the driver API level
+ //
+ Status = pBS->LocateProtocol(&gFlashSmmProtocolGuid, NULL, &Flash);
+//TRACE((TRACE_ALWAYS,"SecSmiFlash: Flash Protocol Fixup %X->%X\n",Flash->Write,SecureFlashWrite));
+ if (EFI_ERROR(Status)) goto Done;
+
+ // preserve org Flash API
+ pFlashWrite = Flash->Write;
+ pFlashErase = Flash->Erase;
+ // replace with local functions
+ Flash->Erase = SecureFlashErase;
+ Flash->Write = SecureFlashWrite;
+ // Calculate the flash mapping start address. This is calculated
+ // as follows:
+ // 1. Find the total size of the flash (FLASH_BLOCK_SIZE * NUMBER_OF_BLOCKS)
+ // 2. Subtract the total flash size from 4GB
+ Flash4GBMapStart = 0xFFFFFFFF - (FLASH_BLOCK_SIZE * NUMBER_OF_BLOCKS);
+ Flash4GBMapStart ++;
+#endif
+ //
+ // Install Secure SMI Flash Protocol
+ //
+ SecSmiFlash.pFwCapsule = pFwCapsuleLowMem;
+ SecSmiFlash.HashTbl = gHashTbl;
+ SecSmiFlash.RomLayout = RomLayout;
+// SecSmiFlash.FSHandle = 0;
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &DummyHandle,
+ &gSecureSMIFlashProtocolGuid,&SecSmiFlash,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Install SW SMI callbacks for 3 SecSMI Flash functions
+ // !!! do not install if OFBD SecFlash is installed
+ //
+#if INSTALL_SECURE_FLASH_SW_SMI_HNDL == 1
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return EFI_SUCCESS;
+
+ for(Index=MinSMIPort;Index<=MaxSMIPort;Index++)
+ {
+ SwContext.SwSmiInputValue = Index;
+ Status = pSwDispatch->Register(pSwDispatch, SecSMIFlashSMIHandler, &SwContext, &Handle);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) break;
+ //If any errors,unregister any registered SwSMI by this driver.
+ //If error, and driver is unloaded, then a serious problem would exist.
+ }
+#endif
+Done:
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: SecSMIFlashDriverEntryPoint
+//
+// Description: Secure SMI Flash driver init
+//
+// Input:
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SecSMIFlashDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.cif b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.cif
new file mode 100644
index 0000000..5a62525
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Secure SMIFlash"
+ category = ModulePart
+ LocalRoot = "CORE\EM\SecurityPkg\SecSMIFlash\"
+ RefName = "SecSMIFlash"
+[files]
+"SecSMIFlash.sdl"
+"SecSMIFlash.mak"
+"SecSMIFlash.dxs"
+"SecSMIFlash.c"
+"VerifyFwCapsule.c"
+[parts]
+"SecSMIFlashProtocols"
+[dependOn]
+"SMIFlash"
+<endComponent>
diff --git a/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.dxs b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.dxs
new file mode 100644
index 0000000..f28ae6d
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.dxs
@@ -0,0 +1,67 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/SecSMIFlash.dxs 4 3/18/14 3:12p Alexp $
+//
+// $Revision: 4 $
+//
+// $Date: 3/18/14 3:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/SecSMIFlash.dxs $
+//
+// 4 3/18/14 3:12p Alexp
+// update year to 2014 in ftr & hdr
+//
+// 3 8/10/12 11:42a Alexp
+// Removed dependency on Flash Update protocol
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SMIFlash_dxs
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Protocol/SmiFlash.h>
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#include <Protocol/AmiDigitalSignature.h>
+
+DEPENDENCY_START
+ EFI_SMI_FLASH_GUID AND
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+ AMI_SMM_DIGITAL_SIGNATURE_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.mak b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.mak
new file mode 100644
index 0000000..25aae09
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.mak
@@ -0,0 +1,108 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#************************************************************************//
+# $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/SecSMIFlash.mak 14 3/18/14 3:12p Alexp $
+#
+# $Revision: 14 $
+#
+# $Date: 3/18/14 3:12p $
+#************************************************************************//
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/SecSMIFlash.mak $
+#
+# 14 3/18/14 3:12p Alexp
+# update year to 2014 in ftr & hdr
+#
+# 13 11/21/12 10:40a Alexp
+# do not link CryptoLib with SecSmiFlash.
+#
+# 12 8/10/12 11:48a Alexp
+# Removed build rules of now obsolete SecSmiFlashHooks
+#
+# 11 5/18/12 5:03p Alexp
+# 1. Link Crypto Library with VerifyFwCap in Recovery boot flow.Use Hash
+# functions only
+# 2. Pass SEC_FLASH_GUID_DEFINES containing unique FwCap Ffs Guid and
+# Section guids
+#
+# 10 12/01/11 5:30p Alexp
+# restore build rules. When needed, PRESERVE_LIB eLink can be reused
+#
+# 9 12/01/11 3:37p Alexp
+# Add Build target for SecSmiFlashHooks library. New lib is linked to
+# SmiFlash and (or) OFBD SecFlash via PRESERVE_LIB eLink list
+#
+# 7 11/30/11 8:13p Alexp
+# left optional link rules for future usage with Ofbd module
+#
+# 5 9/20/11 2:20p Alexp
+# removed linkage of SecFlashHooks with ReFlash.
+#
+# 4 8/18/11 4:47p Alexp
+# 1. Add Depex rule to launch SecSmiFlash after AimDigitalSig protocol is
+# available
+# 2. Link SecSMIFlashHooks to ReFlash driver. Needed to preserve
+# SecureVars on Recovery style reFlash
+#
+# 3 8/11/11 5:32p Alexp
+# updated header
+#
+# 2 8/05/11 3:28p Alexp
+# add SMM_COMPILE flag to SecSMIFlashHook compile rules
+#
+#************************************************************************//
+
+all : SecSMIFlash
+
+SecSMIFlash : $(BUILD_DIR)\SecSMIFlash.mak SecSMIFlashBin
+
+$(BUILD_DIR)\SecSMIFlash.mak : $(SEC_SMI_FLASH_DIR)\SecSMIFlash.cif $(SEC_SMI_FLASH_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(SEC_SMI_FLASH_DIR)\SecSMIFlash.cif $(CIF2MAK_DEFAULTS)
+
+BUILD_SecSMIFlash_DIR = $(BUILD_DIR)\$(SEC_SMI_FLASH_DIR)
+
+SecSMIFlash_INCLUDES= \
+ /I $(SEC_SMI_FLASH_DIR)\
+ /I$(CORE_DIR)
+
+SecSMIFlash_OBJECTS = \
+ $(BUILD_SecSMIFlash_DIR)\SecSMIFlash.obj \
+ $(BUILD_SecSMIFlash_DIR)\VerifyFwCapsule.obj
+
+SecSMIFlashBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecSMIFlash.mak all\
+ GUID=3BF4AF16-AB7C-4b43-898D-AB26AC5DDC6C\
+ ENTRY_POINT=SecSMIFlashDriverEntryPoint\
+ OBJECTS="$(SecSMIFlash_OBJECTS)" \
+ "CFLAGS=$(CFLAGS) $(SEC_FLASH_GUID_DEFINES)" \
+ TYPE=RT_DRIVER "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ DEPEX1=$(SEC_SMI_FLASH_DIR)\SecSMIFlash.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.sdl b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.sdl
new file mode 100644
index 0000000..f0ad04a
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecSMIFlash/SecSMIFlash.sdl
@@ -0,0 +1,74 @@
+TOKEN
+ Name = "SecSMIFlash_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Secured SMIFlash support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "INSTALL_SECURE_FLASH_SW_SMI_HNDL"
+ Value = "0"
+ Help = "Install SecFlash SW SMI callbacks. Not needed if OFBD Secure Flash is present"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NEW_BIOS_MEM_ALLOC"
+ Value = "1"
+ Help = "Memory buffer location for new BIOS image.\0-SMM TSEG, 1-ACPI NVS, 2-allocated by AFU"
+ Range = "0-1-2"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CSLIB_WARM_RESET_SUPPORTED"
+ Value = "0"
+ Help = "1 - Chipset provides SBLib_ResetSystem(EfiResetWarm).\0 - Simulate Warm Reset via S3 & RTC resume."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SwSmi_LoadFwImage"
+ Value = "0x1d"
+ Help = "SW SMI value for Load FW image to SMM RAM"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SwSmi_GetFlashPolicy"
+ Value = "0x1e"
+ Help = "SW SMI value for Get Fl Upd Policy"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SwSmi_SetFlashMethod"
+ Value = "0x1f"
+ Help = "SW SMI value for Set Fl Upd Method"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "SEC_SMI_FLASH_DIR"
+End
+
+MODULE
+ Help = "Includes SecSMIFlash.mak to Project"
+ File = "SecSMIFlash.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SecSMIFlash.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/SecurityPkg/SecSMIFlash/VerifyFwCapsule.c b/Core/EM/SecurityPkg/SecSMIFlash/VerifyFwCapsule.c
new file mode 100644
index 0000000..b078df2
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecSMIFlash/VerifyFwCapsule.c
@@ -0,0 +1,790 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/VerifyFwCapsule.c 30 7/03/14 10:15a Alexp $
+//
+// $Revision: 30 $
+//
+// $Date: 7/03/14 10:15a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureSmiFlash/VerifyFwCapsule.c $
+//
+// 30 7/03/14 10:15a Alexp
+// EIP176297: Fix bug in condition expresison inside For loops.
+//
+// 29 5/20/14 5:22p Alexp
+// Replace a var name gRomFileSize to a more appropriate gFwCapMaxSize
+//
+// 27 3/20/14 12:31p Alexp
+// 1. Don't re-read FwKey. Use gpPubKeyHndl
+// 2. CapsuleValidate: sanity check: FwCapHdr RomImageOffset checked
+// against max size
+// (FWCAPSULE_IMAGE_SIZE-FLASH_SIZE)
+// 3. CapsuleValidate: add parameter check pFWCapsuleHdr != NULL
+//
+// 26 8/22/13 11:34a Alexp
+// VerifyFwCertRsa2048Sha256() - Break a loop after RootCert Verify if key
+// match is found. Old code would cycle through all certs.
+//
+// 25 8/12/13 4:31p Alexp
+// add check for end of Certificate block marker
+//
+// 24 7/11/13 3:41p Alexp
+// Removed check for FWCAPSULE_MAX_HDR_SIZE. Replaced it with fixed 0x8000
+// value
+//
+// 23 6/27/13 9:43a Alexp
+// fixed range check in ROM_MAP table processing.
+//
+// 22 6/21/13 11:00a Alexp
+// HashFwRomMapImage(): add check for address overflow in UIN32 build mode
+//
+// 21 6/12/13 3:51p Alexp
+// 1. CapsuleValidate() made external function in SecSmiFlash API
+// EIP#125800 : Privilege escalation into SMM via Secure SMI Flash SMM
+// driver via GetFlUpdPolicy and SetFlUpdMethod - BugID 305294
+// add IsAddressInSmram() checks inside exposed API functions
+// 2. VerifyFwCertRsa2048Sha256() - parse multiple chained RootKey
+// certificate structures in FwCert header
+//
+// 20 12/17/12 2:51p Alexp
+// fix cppcheck style check finds
+//
+// 19 11/21/12 10:44a Alexp
+// EIP#105015: Implemented handling of Pkcs7# Certificate in Aptio Fw
+// Capsule update packages
+// Replace direct calls to Hash() infrom CryptoLib with calls to Crypto
+// API. Saves ROM space
+//
+//
+// 18 11/20/12 3:30p Alexp
+// EIP[104046]: Findings from Security review on Aptio4 Image verification
+// Includes the fix for item #10: hardening of RomMap parsing oin
+// FwCapsule update
+//
+// 17 11/13/12 3:23p Alexp
+// 1. EIP#106359 : Secure Flash Cross function fail.
+// Move FwCapSectionGuid define outside of #if branch
+// 2. Calculate offset to RomLayout table within FwCapsHdr instead of
+// using hardwired location. Pkcs#7
+// cert will differ in size and offset may change
+// 3. Remove dependency on FWSIG_SIGNHDR flag. Use Capsule flags instead.
+//
+// 16 9/18/12 6:59p Alexp
+// Bug: Recovery update was broken for FwCapsule with embedded signature
+// and FwSig_hdr token 0.
+// Fix: FindCapHdrFFS() change Ffs Hdr size testing
+//
+// 15 9/06/12 7:28p Alexp
+// Add new IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK flag
+// When set, FW Capsule Validate logic will skip image Revision check only
+// for Runtime updates
+//
+// 14 7/26/12 3:26p Alexp
+// replaced #if FWSIG_PADDING == 0 with #if FWSIG_SIGNHDR == 1.
+// Flag in the FwCap Hdr to switch between PKCS1_5 and PSS padding is
+// available only if #if FWSIG_SIGNHDR == 1
+//
+// 13 5/21/12 4:55p Alexp
+// keep a pointer to FwCaps Hdr withing Capsule image. Streamlines
+// creation of Capsule Mailbox.
+//
+// 12 5/18/12 5:14p Alexp
+// 1. Add support for Embedded FwSignature file
+// 2. EIP:89687 Replace Hash PPI calls with calls to Crypto lib
+// functions.
+// Allows to support RomMap tables in FwCaps Hdr with unlimited
+// number of
+// entries
+// 3. VerifyFwVersion.
+// a) Moved the call after Rom image signature is verified.;
+// b) search $FID struct only in signed FVs with PEI or DXE
+// attributes
+//
+// 11 4/25/12 2:11p Alexp
+// Platform FW Key is compared with either Signing or if no match - with
+// RootKey certificates
+//
+// 9 3/09/12 11:16a Alexp
+// VerifyFwImage-> fixed logic to process RomMap entries.
+// Number of signed elements in RomMap may not exceed max_num_elem
+// constant.
+// Overall number of elements in th RomMap may not exceed max_num_elem x 2
+//
+// 8 2/29/12 4:13p Alexp
+// Update format of Capsule signing:
+// 1. Entire Cap Hdr and FW_Cert Hdr are included in SigCert Signature
+// calculation. Improves Cap image security
+// 2. RootKey signs only SignKey buffer and not entire Sign Certificate.
+// No need for resigning of RootCert each time SignCert is being created
+//
+// 7 2/13/12 1:57p Alexp
+// GetFidData: Use 1 byte alligned pointer in searching "Section Guid".
+// Fixes the issue with RomMap entries that are not 4 byte alligned
+//
+// 6 12/29/11 4:00p Alexp
+// VerifyProjectId().
+// Calculate size of ProjectId string based on SDL Token PROJECT_TAG
+//
+// 5 11/30/11 8:04p Alexp
+// FW Revision searched inside FID structure. Simplified the search
+// throughout FW block by 4byte aligned $FID signature only
+//
+// 4 10/17/11 11:26a Alexp
+// Fix misspelled FidSignature name
+//
+// 3 9/29/11 3:27p Alexp
+// Bug fix. EIP#71244: No Rollback support
+//
+// 2 8/05/11 3:29p Alexp
+// add SDL condition to IGNORE_IMAGE_ROLLBACK. Disabled by default
+//
+// 4 5/16/11 5:54p Alexp
+// Use 5 characters for Project Tag comparison (old was 4)
+//
+// 3 5/10/11 5:09p Alexp
+// Hash guids are defined globally
+//
+// 2 4/13/11 7:15p Alexp
+// included first draft of VersionControl code
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: VerifyFwCapsule.c
+//
+// Description: Verify Aptio FW capsule integrity and performs other security checks
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiDxeLib.h>
+#include <Protocol\SmiFlash.h>
+#include <Protocol\SecSmiFlash.h>
+#include <Ppi\FwVersion.h>
+#include <RomLayout.h>
+#include <Ffs.h>
+#include "AmiCertificate.h"
+
+//----------------------------------------------------------------------------
+// Function Externs
+extern AMI_DIGITAL_SIGNATURE_PROTOCOL *gAmiSig;
+extern UINTN gFwCapMaxSize; // add 4k for capsule's header
+extern EFI_GUID gFWCapsuleGuid;
+extern EFI_GUID gPRKeyGuid;
+extern EFI_GUID gFwCapFfsGuid;
+extern EFI_SHA256_HASH *gHashTbl;
+extern CRYPT_HANDLE gpPubKeyHndl;
+extern UINT8 gHashDB[SHA256_DIGEST_SIZE];
+
+BOOLEAN IsAddressInSmram (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+);
+//----------------------------------------------------------------------------
+// Local prototypes
+EFI_STATUS CapsuleValidate (
+ IN OUT UINT8 **pFwCapsule,
+ IN OUT APTIO_FW_CAPSULE_HEADER **pFWCapsuleHdr
+);
+
+typedef struct {
+ EFI_FFS_FILE_HEADER FfsHdr;
+ EFI_COMMON_SECTION_HEADER SecHdr;
+ EFI_GUID SectionGuid;
+ UINT8 FwCapHdr[0];
+} AMI_FFS_COMMON_SECTION_HEADER;
+
+//----------------------------------------------------------------------------
+// Local Variables
+
+static EFI_GUID FwCapSectionGuid = AMI_FW_CAPSULE_SECTION_GUID;
+
+//----------------------------------------------------------------------------
+#if IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK == 0
+//----------------------------------------------------------------------------
+typedef struct _FID_SECTION {
+ EFI_GUID Guid;
+ FW_VERSION FwVersion;
+} FID_SECTION;
+
+static EFI_GUID FidSectionGuid = \
+ { 0x2EBE0275, 0x6458, 0x4AF9, 0x91, 0xed, 0xD3, 0xF4, 0xED, 0xB1, 0x00, 0xAA };
+
+const UINT8 *FidSignature = "$FID";
+//----------------------------------------------------------------------------
+// Function Definitions
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: VerifyProjectId
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+VerifyProjectId (
+ IN FW_VERSION *FwVersionData
+)
+{
+ char *strProjectId = CONVERT_TO_STRING(PROJECT_TAG);
+ UINTN Size = sizeof(CONVERT_TO_STRING(PROJECT_TAG));
+/*
+CHAR8 BiosTag[9]; //BIOS Tag
+EFI_GUID FirmwareGuid; //Firmware GUID
+CHAR8 CoreMajorVersion[3];
+CHAR8 CoreMinorVersion[3];
+CHAR8 ProjectMajorVersion[3];
+CHAR8 ProjectMinorVersion[3];
+*/
+// Project ID, Major, Minor rev
+ TRACE((-1, "OrgBiosTag=%s,NewBiosTag=%s\nPrjMajVer=%02X, NewMajVer=%s\nPrjMinorVer=%02X, NewMinorVer=%s\n",
+ FwVersionData->BiosTag, strProjectId,
+ PROJECT_MAJOR_VERSION, FwVersionData->ProjectMajorVersion,
+ PROJECT_MINOR_VERSION, FwVersionData->ProjectMinorVersion
+ ));
+
+ if (Size==0 || MemCmp (FwVersionData->BiosTag, strProjectId, Size-1)) return FALSE;
+#if IGNORE_IMAGE_ROLLBACK == 0
+ if(Atoi(FwVersionData->ProjectMajorVersion) < PROJECT_MAJOR_VERSION) return FALSE;
+ if(Atoi(FwVersionData->ProjectMinorVersion) < PROJECT_MINOR_VERSION) return FALSE;
+#endif
+
+ return TRUE;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFidData
+//
+// Description: Function to read FFS FID data structure from the given data buffer
+//
+// Input: OUT FW_VERSION **Fid - pointer to output buffer
+// IN VOID *pFV - pointer to data buffer to read from
+
+//
+// Output: EFI_SUCCESS if FID data is retrieved
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN GetFidData(
+ IN VOID *pFV,
+ IN UINT32 Size,
+ OUT FW_VERSION **FwVersionData
+)
+{
+// UINT32 Signature;
+ UINT8 *SearchPointer;
+ FID_SECTION *Section;
+
+// Simplified search by $FID signature only.
+// SearchPointer = (UINT32 *)((UINT8 *)pFV + sizeof(EFI_GUID));
+// Signature = FidSectionGuid.Data1;
+ SearchPointer = (UINT8 *)pFV;
+
+ do {
+// if(*SearchPointer == Signature) {
+ Section = (FID_SECTION *)SearchPointer;
+ if(!guidcmp(&FidSectionGuid, &(Section->Guid)) &&
+ (*((UINT32*)(&Section->FwVersion.FirmwareID[0])) == *(UINT32*)FidSignature)){
+ *FwVersionData = &Section->FwVersion;
+ return TRUE;
+ }
+// }
+ } while( SearchPointer++ < (UINT8*)((UINT32)pFV+Size));
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyFwRevision
+//
+// Description: Verify Fw revision compatibility
+// NewVer > OldVer, newProjectTAGid = oldProjectTAGid
+//
+// Input:
+// IN OUT UINT8 *pCapsule
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+VerifyFwRevision (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *RomData
+)
+{
+ ROM_AREA *Area;
+ EFI_PHYSICAL_ADDRESS FvAddress;
+ FW_VERSION *FwVersionData;
+
+ Area = (ROM_AREA *)(UINTN)((UINT32)FWCapsuleHdr+FWCapsuleHdr->RomLayoutOffset);
+
+ for (Area; Area->Size != 0; Area++) {
+ if (!(Area->Attributes & ROM_AREA_FV_SIGNED))
+ continue;
+ // $FID can be in FV with either PEI or DXE
+ if (!(Area->Attributes & (ROM_AREA_FV_PEI+ROM_AREA_FV_DXE)))
+ continue;
+
+ FvAddress = (EFI_PHYSICAL_ADDRESS)RomData + (Area->Offset);
+ if (GetFidData((UINT8*)FvAddress, Area->Size, &FwVersionData)) {
+ if(VerifyProjectId(FwVersionData))
+ return EFI_SUCCESS;
+ break;
+ }
+ }
+// At least one FW block must be signed OR no $FID structure found in the new FW image
+ return EFI_SECURITY_VIOLATION;
+}
+
+#endif // #if IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK == 0
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindCapHdrFFS
+//
+// Description: Function to read FW Cap Sig data from Ffs
+//
+// Input: OUT UINT8 **pFwCapHdr - pointer to output buffer
+// IN VOID *pCapsule - pointer to data buffer to read from
+//
+// Output: EFI_SUCCESS if Capsule Hdr with Signature is retrieved
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FindCapHdrFFS(
+ IN VOID *pCapsule,
+ OUT UINT8 **pFfsData
+)
+{
+ UINT32 Signature;
+ UINT32 *SearchPointer;
+ AMI_FFS_COMMON_SECTION_HEADER *FileSection;
+ APTIO_FW_CAPSULE_HEADER *pFwCapHdr;
+
+ SearchPointer = (UINT32 *)((UINT8 *)pCapsule - sizeof(AMI_FFS_COMMON_SECTION_HEADER) + FLASH_SIZE);
+ Signature = gFwCapFfsGuid.Data1;
+ do {
+ if(*SearchPointer == Signature) {
+ FileSection = (AMI_FFS_COMMON_SECTION_HEADER *)SearchPointer;
+ if(!guidcmp(&gFwCapFfsGuid, &(FileSection->FfsHdr.Name))
+ && !guidcmp(&FwCapSectionGuid, &(FileSection->SectionGuid))
+ ){
+ pFwCapHdr = (APTIO_FW_CAPSULE_HEADER*)(FileSection->FwCapHdr);
+ // just a sanity check - Cap Size must match the Section size
+ if(((*(UINT32 *)FileSection->FfsHdr.Size) & 0xffffff) >=
+ pFwCapHdr->CapHdr.HeaderSize + sizeof(AMI_FFS_COMMON_SECTION_HEADER) &&
+ !guidcmp((EFI_GUID*)&pFwCapHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid)
+ ){
+ *pFfsData = (UINT8*)pFwCapHdr;
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ } while(SearchPointer-- != pCapsule);
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: HashFwRomMapImage
+//
+// Description: The Rom image hash is calculated based on info from the Rom Area map
+//
+// Input:
+// Payload - pointer to a FW Image
+// FwCapsuleHdr - pointer to a FW Capsule Hdr
+// RomSize - Size of Rom Image
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS HashFwRomMapImage (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *Payload,
+ IN UINTN RomSize,
+ OUT UINT8 *gHashDB
+){
+ EFI_STATUS Status = EFI_SUCCESS;
+ ROM_AREA *RomAreaTbl;
+ UINTN *Addr;
+ UINTN *Len;
+ UINTN i, RomMap_size, max_num_elem, num_elem, max_hash_elem;
+
+ RomAreaTbl = (ROM_AREA *)(UINTN)((UINT32)FWCapsuleHdr+FWCapsuleHdr->RomLayoutOffset);
+
+ RomMap_size = FWCapsuleHdr->RomImageOffset-FWCapsuleHdr->RomLayoutOffset;
+ max_num_elem = RomMap_size/sizeof(ROM_AREA);
+// assume max size of RomMap array = RomMap_size/sizeof(ROM_AREA);
+// or better yet ...calculate exact number
+ num_elem = 0;
+ for (i=0; i < max_num_elem && RomAreaTbl[i].Size != 0; i++ )
+ {
+ if (RomAreaTbl[i].Attributes & ROM_AREA_FV_SIGNED)
+ num_elem++;
+ }
+ max_num_elem = i;
+ max_hash_elem = num_elem+2; // add 2 extra entries
+ Addr = (UINTN*)gHashTbl;
+ Len = (UINTN*)((UINT8*)gHashTbl + max_hash_elem*sizeof(UINTN));
+
+ num_elem = 0;
+ for (i=0; i < max_num_elem && num_elem < max_hash_elem && RomAreaTbl[i].Size != 0; i++)
+ {
+ if (!(RomAreaTbl[i].Attributes & ROM_AREA_FV_SIGNED))
+ continue;
+ // sanity check for buffer overruns
+ if(RomAreaTbl[i].Offset > RomSize ||
+ (UINT64)RomAreaTbl[i].Offset + RomAreaTbl[i].Size > RomSize)
+ return EFI_SECURITY_VIOLATION;
+ // RomArea only holds offsets within a payload
+ Addr[num_elem] = (UINTN)((UINTN)Payload + RomAreaTbl[i].Offset);
+ Len[num_elem] = RomAreaTbl[i].Size;
+//TRACE((-1, "\n Num %d: Offs = %X (%X), len %X\n", num_elem, /*Addr[num_elem]*/RomAreaTbl[i].Offset, (UINT32)*(UINT32*)Addr[num_elem], Len[num_elem]));
+
+ num_elem++;
+
+ }
+ if(num_elem >= max_hash_elem) return EFI_SECURITY_VIOLATION;
+//
+// Hash of Capsule Hdr + FW Certificate Hdr
+//
+ if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_CAPHDR_IN_SIGNCERT) {
+ Addr[num_elem] = (UINTN) FWCapsuleHdr;
+ Len[num_elem] = (UINTN)&FWCapsuleHdr->FWCert.SignCert.CertData - (UINTN)FWCapsuleHdr;
+//TRACE((-1, "\n Num %d: Offs = %X (%X), len %X\n", num_elem, Addr[num_elem], (UINT32)*(UINT32*)Addr[num_elem], Len[num_elem]));
+ num_elem++;
+ if(num_elem >= max_hash_elem) return EFI_SECURITY_VIOLATION;
+ }
+//
+// Hash of the ROM_MAP table
+//
+ Addr[num_elem] = (UINTN)RomAreaTbl;
+ Len[num_elem] = (i+1)*sizeof(ROM_AREA);
+//TRACE((-1, "\n Num %d: Offs = %X (%X), len %X\n", num_elem, Addr[num_elem], (UINT32)*(UINT32*)Addr[num_elem], Len[num_elem]));
+ num_elem++;
+
+ Status = gAmiSig->Hash(gAmiSig, &gEfiHashAlgorithmSha256Guid,
+ num_elem, (const UINT8**)Addr, (const UINTN*)Len, gHashDB );
+
+//TRACE((-1, "\nHash the FW Image %r\nNumElems = %d\n", Status, num_elem));
+
+//for (i=0; i<16; i++)
+// TRACE((-1,"%02X ", (gHashDB[i]) ));
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyFwCertPkcs7
+//
+// Description: This code verifies FW Capsule is genuine,
+// and performs following checks on the image:
+// 1. Signing certificate is signed with trusted Root Platform key
+// 2. Integrity check. Image Signature verification
+//
+// Input:
+// Payload - pointer to a FW Image
+// FwCapsuleHdr - pointer to a FW Capsule Hdr
+// RomSize - Size of Rom Image
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyFwCertPkcs7 (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *Payload,
+ IN UINTN RomSize
+){
+ EFI_STATUS Status;
+ UINT8 *Pkcs7Cert, *pDigest;
+ UINTN Pkcs7Cert_len, DigestLen;
+ UINT32 Flags=0;
+
+// TRACE((-1, "Verify Fw Pkcs7 Cert\n"));
+//
+// 1. Verify Platform Key algo matches x509 cert
+//
+ if(guidcmp(&gpPubKeyHndl.AlgGuid, &gEfiCertX509Guid))
+ return EFI_UNSUPPORTED;
+
+// 2. Verify Signing Cert Signature
+//
+// 2.1 The Rom image hash is calculated based on info from the Rom Area map
+//
+ Status = HashFwRomMapImage(FWCapsuleHdr, Payload, RomSize, gHashDB);
+ if (EFI_ERROR(Status)) return Status;
+
+// 2.2 Verify Fw Certificate
+ pDigest = &gHashDB[0];
+ DigestLen = SHA256_DIGEST_SIZE;
+ Pkcs7Cert = (UINT8*)&FWCapsuleHdr->FWCert.SignCert.CertData;
+ Pkcs7Cert_len = FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength-sizeof(WIN_CERTIFICATE_UEFI_GUID_1);
+ Status = gAmiSig->Pkcs7Verify( gAmiSig,
+ Pkcs7Cert, Pkcs7Cert_len, // Pkcs7Cert
+ gpPubKeyHndl.Blob, gpPubKeyHndl.BlobSize, // TrustCert
+ &pDigest, &DigestLen, // In/OutData
+ Pkcs7CertValidate,
+ RELEASE // Flags, mutex
+ );
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VerifyFwCertRsa2048Sha256
+//
+// Description: This code verifies FW Capsule is genuine,
+// and performs following checks on the image:
+// 1. Signing certificate is signed with trusted Root Platform key
+// 2. Integrity check. Image Signature verification
+//
+// Input:
+// Payload - pointer to a FW Image
+// FwCapsuleHdr - pointer to a FW Capsule Hdr
+// RomSize - Size of Rom Image
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_DEVICE_ERROR - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS VerifyFwCertRsa2048Sha256 (
+ IN APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr,
+ IN UINT8 *Payload,
+ IN UINTN RomSize
+){
+ EFI_STATUS Status;
+ CRYPT_HANDLE HashHndl;
+ CRYPT_HANDLE PubKeyHndl;
+ UINT8 *pSig;
+ UINT32 Flags;
+ UINT8 *Addr;
+ UINTN Size;
+ EFI_CERT_BLOCK_RSA_2048_SHA256* pRootCert;
+
+// Version 010 and later supporting extended flags
+// if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_CAPHDR_IN_SIGNCERT)
+ if(FWCapsuleHdr->CapHdr.HeaderSize == FWCapsuleHdr->RomImageOffset)
+ {
+ if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_RSA_PSS_PADDING_SCHEME)
+ Flags = EFI_CRYPT_RSASSA_PSS;
+ else
+ Flags = EFI_CRYPT_RSASSA_PKCS1V15;
+ }
+ else
+ Flags = EFI_CRYPT_RSASSA_PSS;
+
+ HashHndl.AlgGuid = gEfiHashAlgorithmSha256Guid;
+ HashHndl.BlobSize = SHA256_DIGEST_SIZE;
+ HashHndl.Blob = gHashDB;
+
+ PubKeyHndl.AlgGuid = gEfiCertRsa2048Guid;
+ PubKeyHndl.BlobSize = DEFAULT_RSA_KEY_MODULUS_LEN;
+//
+// 1. Compare Capsule's Sign Cert key with Platform Root Key
+//
+ PubKeyHndl.Blob = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey;
+ Status = gAmiSig->VerifyKey(gAmiSig, &gPRKeyGuid, &PubKeyHndl);
+ // Skip the RootCert key checking if SignCert Key and PR Key are matching
+//TRACE((-1, "Compare SignCert Key == FW Key(%X) : %r\n", (UINT32)*PubKeyHndl.Blob, Status));
+ if(EFI_ERROR(Status)) {
+//
+// 1.1 Compare Platform Root with Capsule's Key from a Root Key store
+//
+ for (pRootCert = &FWCapsuleHdr->FWCert.RootCert;
+ (UINT8*)pRootCert <
+ (UINT8*)&FWCapsuleHdr->FWCert+FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength &&
+ pRootCert->PublicKey[0]!=0;
+ pRootCert++)
+ {
+ PubKeyHndl.Blob = pRootCert->PublicKey;
+ Status = gAmiSig->VerifyKey(gAmiSig, &gPRKeyGuid, &PubKeyHndl);
+//TRACE((-1, "Compare RootCert Key == FW Key(%X) : %r\n", (UINT32)*PubKeyHndl.Blob, Status));
+ if (EFI_ERROR(Status)) continue;
+//
+// 2. Verify RootCert.Signature
+//
+// 2.1 Compute FWCert.SignCert.PublicKey Hash
+ if(FWCapsuleHdr->CapHdr.Flags & CAPSULE_FLAGS_SIGNKEY_IN_ROOTCERT)
+ {
+ Addr = (UINT8*)&FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey;
+ Size = DEFAULT_RSA_KEY_MODULUS_LEN;
+ } else
+// 2.2 Compute FWCert.SignCert Hash
+ {
+ Addr = (UINT8*)&FWCapsuleHdr->FWCert.SignCert;
+ Size = sizeof(AMI_CERTIFICATE_RSA2048_SHA256);
+ }
+
+ Status = gAmiSig->Hash(gAmiSig, &gEfiHashAlgorithmSha256Guid, 1,&Addr,(const UINTN*)&Size, gHashDB);
+ if (EFI_ERROR(Status)) break;
+
+ pSig = (void*)pRootCert->Signature;
+ Status = gAmiSig->Pkcs1Verify(gAmiSig, &PubKeyHndl, &HashHndl, pSig, DEFAULT_RSA_SIG_LEN, Flags);
+//TRACE((-1, "Verify Root Cert : %r\n", Status));
+ break;
+ }
+ }
+ if (EFI_ERROR(Status)) return EFI_SECURITY_VIOLATION;
+// 3. Verify Signing Cert Signature
+//
+// 3.1 The Rom image hash is calculated based on info from the Rom Area map
+//
+ Status = HashFwRomMapImage(FWCapsuleHdr, Payload, RomSize, gHashDB);
+ if (EFI_ERROR(Status)) return Status;
+
+ pSig = (void*)FWCapsuleHdr->FWCert.SignCert.CertData.Signature;
+ PubKeyHndl.Blob = (UINT8*)FWCapsuleHdr->FWCert.SignCert.CertData.PublicKey;
+ Status = gAmiSig->Pkcs1Verify(gAmiSig, &PubKeyHndl, &HashHndl, pSig, DEFAULT_RSA_SIG_LEN, Flags);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CapsuleValidate
+//
+// Description: This code verifies FW Capsule is genuine,
+// and performs following checks on the image:
+// 1. Re-Play protection. Verifies that new FW image version is newer then the current one
+// 2. Signing certificate is signed with trusted Root Platform key
+// 3. Integrity check. Image Signature verification
+//
+// Input:
+// IN VOID *pFwCapsule - pointer to a FW Image
+// OUT UINT8 *pFwCapsuleHdr - return a pointer to a FW Capsule Hdr(optional if parameter is not NULL)
+//
+// Output: EFI_SUCCESS - capsule processed successfully
+// EFI_SECURITY_VIOLATION - capsule processing failed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CapsuleValidate (
+ IN OUT UINT8 **pFwCapsule,
+ IN OUT APTIO_FW_CAPSULE_HEADER **pFWCapsuleHdr
+){
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ APTIO_FW_CAPSULE_HEADER *FWCapsuleHdr;
+ UINTN RomSize;
+ UINT8 *Payload;
+
+ FWCapsuleHdr = (APTIO_FW_CAPSULE_HEADER*)*pFwCapsule;
+ Payload = (UINT8*)*pFwCapsule;
+ RomSize = FLASH_SIZE;
+
+/*
+ - CapsuleValidate
+ - Look up Capsule GUID
+ - Found -
+ update pFwCapsule ptr to beginning of BIOS ROM data
+ continue with Image Verify
+ - Not found at offs 0 - assume Cap Hdr in FFS
+ Call GetSigFFS
+ locate FFS by Hole GUID, Sec GUID
+ if found, update FWCapsuleHdr,
+ continue with Image Verify
+*/
+// proper FW Capsule presence check
+
+// verify Capsule Mailbox points to FW_CAPSULE hdr
+ if(!guidcmp((EFI_GUID*)&FWCapsuleHdr->CapHdr.CapsuleGuid, &gFWCapsuleGuid))
+ {
+// Update pFwCapsule to point to beginning of Bios ROM
+ Payload = (UINT8*)((UINT32)FWCapsuleHdr + FWCapsuleHdr->RomImageOffset);
+ RomSize = (FWCapsuleHdr->CapHdr.CapsuleImageSize - FWCapsuleHdr->RomImageOffset);
+ *pFwCapsule = Payload;
+ }
+ else
+ {
+//TRACE((-1, "Looking for embedded Signature...\n"));
+ if(EFI_ERROR(FindCapHdrFFS(Payload, (UINT8**)&FWCapsuleHdr)))
+ return EFI_SECURITY_VIOLATION;
+ }
+TRACE((-1, "Found Fw Capsule GUID %g\n\r", &(FWCapsuleHdr->CapHdr.CapsuleGuid)));
+
+// update return argument with a ptr to FwCapHdr
+ if(pFWCapsuleHdr)
+ *pFWCapsuleHdr = FWCapsuleHdr;
+
+// Aptio FW Capsule only supporting WIN_CERT_TYPE_EFI_GUID
+ if(FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.wCertificateType != WIN_CERT_TYPE_EFI_GUID)
+ return EFI_SECURITY_VIOLATION;
+
+// sanity check for buffer overruns
+ if((FWCapsuleHdr->CapHdr.CapsuleImageSize > gFwCapMaxSize) ||
+ (FWCapsuleHdr->RomImageOffset > (FWCAPSULE_IMAGE_SIZE-FLASH_SIZE)) || // 16k is a MAX possible FwCap Hdr size
+ (FWCapsuleHdr->CapHdr.HeaderSize > FWCapsuleHdr->RomImageOffset) ||
+ (FWCapsuleHdr->RomLayoutOffset > FWCapsuleHdr->RomImageOffset) ||
+ (FWCapsuleHdr->FWCert.SignCert.Hdr.Hdr.dwLength + offsetof(APTIO_FW_CAPSULE_HEADER, FWCert) >
+ FWCapsuleHdr->RomLayoutOffset )
+ )
+ return EFI_SECURITY_VIOLATION;
+
+ if(!IsAddressInSmram((EFI_PHYSICAL_ADDRESS)gpPubKeyHndl.Blob, gpPubKeyHndl.BlobSize) )
+ return EFI_SECURITY_VIOLATION;
+ TRACE((TRACE_ALWAYS,"gpKey (%x, %x bytes)\n",gpPubKeyHndl.Blob,gpPubKeyHndl.BlobSize));
+// Begin Authentication
+ if(!guidcmp((EFI_GUID*)&FWCapsuleHdr->FWCert.SignCert.Hdr.CertType, &gEfiCertTypePkcs7Guid))
+ Status = VerifyFwCertPkcs7(FWCapsuleHdr, Payload, RomSize);
+ else
+ Status = VerifyFwCertRsa2048Sha256(FWCapsuleHdr, Payload, RomSize);
+ TRACE((-1, "Signature validate %r\n", Status));
+ if (EFI_ERROR(Status)) return Status;
+//
+// Local PEI $FID is linked with CspLib. extern FW_VERSION FwVersionData;
+// Find $FID in new Fw FVs. Any found should do for us. Use RomMap from Capsule's Hdr
+// compare local BB and Main $Fid BIOS Major/Minor revs with New one.
+#if IGNORE_RUNTIME_UPDATE_IMAGE_REVISION_CHECK == 0
+ Status = VerifyFwRevision(FWCapsuleHdr, Payload);
+//TRACE((-1, "FW Revision test %r\n", Status));
+#endif
+
+//TRACE((-1, "Capsule Verify %r\n", Status));
+
+ return Status;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/SecurityPkg/SecureBootMod.c b/Core/EM/SecurityPkg/SecureBootMod.c
new file mode 100644
index 0000000..d8469fd
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.c
@@ -0,0 +1,2503 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.c 80 5/14/15 9:45a Alexp $
+//`
+// $Revision: 80 $
+//
+// $Date: 5/14/15 9:45a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.c $
+//
+// 80 5/14/15 9:45a Alexp
+// InstallSecureVariables() Update Default Provision logic to handle no
+// key defaults mode.
+// SecureBootMod_Init() Do not issue system reset if BootMode = FlUpdate
+// or Recovery
+//
+// 79 3/09/15 5:05p Alexp
+// 1. Implement User prompt to install Secure Boot key defaults
+// while switching of Secure Boot mode from Custom to Standard
+// (per Windows8+ Hardware Certification requirements).
+// Add callback on SECURE_BOOT_MODE_CHANGE_KEY
+// 2. EIP#200639: When the token DEFAULT_PROVISION_SECURE_VARS enable,
+// the secure boot status is Not Active when first enter setup.
+// [Resolution] Issue SystemReset after initial Secure Boot provisioning
+// 3. EIP#201422: set SecVariables_SUPPORT = 0, code will build fail
+//
+// 78 10/08/14 3:11p Alexp
+// FillAuthhdr(): Default times for Append and Set Variables are
+// different.
+// -Append uses time "2010.1.1.1" in order not to change var time during
+// updates.
+// -Set uses time of BIOS creation(original implementation)
+//
+// 77 4/11/14 10:20a Alexp
+// EIP#163153: [APTIO4] update 4.6.5.5_TCG_43 is build error.
+// Bug: Global var name NvramControl was shared with
+// TpmClearOnRollbackOfbd..
+// Fix: define variable as static
+//
+// 76 4/07/14 2:47p Alexp
+// Add Hii event SECURE_BOOT_MENU_REFRESH on entering of Secure Boot menu
+// The callback to this event refreshes the state of internal Secure Boot
+// setup flags.
+// UpdateSecureVariableBrowserInfo()
+//
+// 75 11/15/13 11:38a Alexp
+// TSE Callbacks return EFI_UNSUPPORTED for unsupported browser actions
+// Always clear RT attribute for SecureBootSetup var.
+//
+// 73 11/04/13 1:13p Alexp
+// ForceSetupModeCallback() . Load defaults fail with new TSE.
+// Return UNSUPPORTED for new TSE 2.16.1240 TSE callback event
+// EFI_BROWSER_ACTION_DEFAULT_STANDARD
+//
+// 72 10/04/13 12:49p Alexp
+// Define EXPOSE_SECURE_BOOT_SETUP_VAR_IF_NOT_SECURE_BOOT_MODE
+// switch to allow OS tools to gain access to Secure Boot setup control
+// only while system is not in Secure Boot mode
+//
+// 71 10/03/13 5:27p Alexp
+// SecureBootMod_Init()
+// Change the logic for clearing of RT attrib for SecureBoot Setup var:
+// only clear it if SecureBoot is active, else let OEM OS tools to see the
+// var
+//
+// 70 10/01/13 10:26a Alexp
+// 1. EIP#134931 :The value of "Secure Boot Option" items on
+// setup menu cannot be kept after flashed BIOS by AFU tool
+// 2. Prevent Preserve-, RestoreSecureVariables to be called out of order.
+//
+// 69 9/30/13 11:49a Alexp
+// EIP#137818 :SecureBootSetup variables are not preserved after flash
+// update even though PRESERVE_SECURE_VARIABLES enabled.
+// Fix: temporary toggle internal SMM NVRAM flag to gain access to non-RT
+// variables
+//
+// 68 8/15/13 10:09a Alexp
+// add handling of x509_SHAxx cert types while adding new certs to dbx
+// variable
+//
+// 67 7/26/13 3:32p Alexp
+// 1. EIP#118850: ECR1009: enable dbt dialogs.
+// 2. Allow selective Key var provisioning. e.g dbx or dbt are optional
+//
+// 66 6/24/13 5:29p Alexp
+// EIP127292: Erase SecureBootSetupVar before setting it with no RT
+// attribute
+//
+// 65 6/22/13 12:24p Alexp
+// EIP:127292: Remove RT attribute from SecureBootSetupVar.
+//
+// 64 5/17/13 6:06p Alexp
+// 1. Add action on KEY_PROVISION_CHANGE_KEY Enable. Prompt user to
+// install keys immediately
+// 2. Always install default Secure Keys as volatile vars based on SDL
+// Token
+// 3. EIP#118850: ECR1009: Add placeholder defines for "dbt"
+//
+// 62 5/01/13 1:54p Alexp
+// InstallSecureVariables() fix build errors if Secure Boot Vars module
+// not detected
+//
+// 61 3/22/13 4:59p Alexp
+// Optimized order in menu selecting option: Key Certificate before Efi
+// Variable
+//
+// 60 12/24/12 12:33p Alexp
+// EIP#108982 : "Secure Boot" Multilanguage Support missing
+// Move all local string defines under .uni
+// Retrieve strings using updated GetHiiString() function
+//
+// 59 12/17/12 3:08p Alexp
+// code fixes according to "cppcheck" style & performance suggestions
+//
+// 58 12/07/12 4:20p Alexp
+// Update Key Management page layout
+//
+// 56 11/26/12 10:45a Alexp
+// EIP#104961: UEFI 2.3.1 SCT test failed in Generic\EfiCompliant case.
+// Fix build warning with PRESERVE_SECURE_VARIABLES flag enabled.
+//
+// 54 11/19/12 4:40p Alexp
+// Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+// across flash updates.
+// Move all secure boot Setup settings to a separate varstore variable.
+// Preserve var across re-flash
+//
+// 53 11/16/12 7:16p Alexp
+// Fixed ValidateSignatureList() return status for Zero Data or Size
+//
+// 52 11/01/12 5:44p Alexp
+// bug fix: ValidateSignatureList () returned Success even if no sig
+// detected if file size = 0
+//
+// 51 10/22/12 3:53p Alexp
+// Fix interactive menus for Set/Append Key operations
+//
+// 50 10/22/12 10:49a Alexp
+// SetMode callback: fix dependency on SetupMode for SecureBoot Enable
+// switch.
+//
+// 49 10/19/12 5:15p Alexp
+// Serve both Set and Append Hii callbacks with common routine SetAppendDb
+//
+// 48 10/16/12 3:16p Alexp
+// 1. replaced wrong return types for Hi iCallback routines from
+// EFI_SUCCESS to EFI_STATUS
+// 2. Removed Authenticated attribute from generic R/O UEFI Variables
+// PKDefault, etc.
+//
+// 47 9/24/12 12:29p Alexp
+// 1. Update all callback functions to return EFI_STATUS according to
+// newer 4.6.5.4.1 Setup module
+// 2. Block Secure Boot switch from being enabled if CSM is enabled or
+// platform is in Setup Mode: ForceSetupModeCallback()
+// 41 9/07/12 5:13p Alexp
+// Remove dependency on newer Cores 4.6.5.0+:
+// CORE_COMBINED_VERSION >= 0x4028a
+// Win8 compliant BIOS must have upgraded
+// Core components, TSE
+//
+// 40 8/23/12 5:42p Alexp
+// Add user selection for supported file formats in Append SecureBoot
+// operations
+//
+// 39 8/15/12 4:48p Alexp
+// 1. Modify Secure Boot page controls. Hide all controls under new
+// sub-page
+// 2. Refrash Secure Boot Setup screens upon user load Defaults/Previous
+// values
+// 3.
+//
+// 38 8/01/12 3:55p Alexp
+// Link KEY_PROVISION_CHANGE_KEY event with common
+// ForceSetupModeCallback()
+//
+// 37 7/30/12 10:59a Alexp
+// Added code to address UEFI ECR874: Install Factory defaults as
+// Read-only volatile variables for key distribution.
+// Update Secure Boot page layout
+// 1. Security Page
+// 1.3 Replaced standalone SecureBootMode Option to an added value
+// in
+// Secure Boot list (on/off/custom)
+// 1.4 Display SecureBootMode Standard/Custom Status
+// 2. Key Management Page
+// 2.1 Add Append Certificate Options along with Append from File
+// New functions append new Certificates from different types
+// of
+// input Certs (x509, RSA2048 & SHA256) and Signature List
+// blobs
+// 2.2 Use single Save to files option for all Sec Variables
+// 2.3 Set Variable Option gets a Key from a File Browser or a
+// Factory Default storage.
+//
+//
+// 34 7/09/12 2:40p Alexp
+// HiiAddString
+// Fix build error if warning level=3
+//
+// 33 6/13/12 10:01a Alexp
+// Fix build warning for uninitialized VarSize in
+// PreserveSecureVariables()
+//
+// 32 6/11/12 3:21p Alexp
+// EIP:90468 UEFI Secure Boot implementation inquiry. When I export the
+// PK, KEK, DB, and DBX files from the Setup menu, I can't reload them.
+// FIX: Added logic to append dummy AuthHdr on top of exportable Variable
+// data in order to make file importable by Key Management page.
+//
+// 31 6/05/12 4:26p Alexp
+// EIP:91587 Function HiiLibSetBrowserData always return error under new
+// tse
+// Fix in UpdateSecureVariableBrowserInfo() -> call
+// HiiLibSetBrowserData() only when called form HiiCallback
+//
+// 30 5/15/12 9:46a Alexp
+// Preserve/Restore SecureVariables(). Use properly formatted Auth
+// Variable data block.
+//
+// 29 4/20/12 5:03p Alexp
+// EIP:88261: Default Secure Variables are being reinstalled on each
+// system reboot when "DEFAULT_PROVISION_SECURE_VARS" is enabled
+// Fix: Replaced usage of FORCE_SETUP_KEY and FORCE_DEFAULT_KEY with
+// dynamicaly generated values to fixed enum types RESET_NV_KEYS=1,
+// SET_NV_DEFAULT_KEYS
+//
+// 27 3/16/12 12:04p Alexp
+// made "PKeyFileGuid" names "static" to avoid double names across linked
+// modules
+//
+// 26 3/09/12 3:29p Alexp
+// Implementation to PRESERVE_SECURE_VARIABLES on Flash Update is moved
+// here from SecSmiFlash component
+//
+// 25 2/14/12 7:35p Alexp
+// SecureBootMod_Init: Update browser info after DefaultKeys are
+// provisioned.
+//
+// 24 2/02/12 12:59p Alexp
+// 1. AppendSecureBootDBCallback. Removed DEL attribute when do Append
+// 2. SetSecureVariable. optimized the logic
+//
+// 23 12/12/11 6:37p Alexp
+// Add check if "DEFAULT_PROVISION_SECURE_VARS" is defined.
+// Fix build error for condition SET_SECURE_VARS = 0
+//
+// 22 11/18/11 11:13a Alexp
+// ForceSetupModeCallback: Initialize Status as not all execution path
+// update this variable
+//
+// 21 11/10/11 4:02p Alexp
+// conditionallly compile all callback related code if
+// CORE_COMBINED_VERSION
+// >=0x4028a (4.6.5.0+)
+//
+// 19 11/08/11 3:05p Alexp
+// fix spelling errors in displayed messages
+//
+// 18 11/07/11 6:26p Alexp
+// Add Key Management controls to add/get/append and delete Secure
+// Variables from the Setup page
+//
+// 17 11/03/11 6:30p Alexp
+// SecureBootMod.c(sdl, .sd, .uni) Change the appearance of Secure Boot
+// items on Setup Security page. Added information on currently installed
+// Secure Variables.
+//
+// 16 10/17/11 6:55p Alexp
+// Add warning message if User Mode can't be reset due to the lock set on
+// Secure Variable update
+//
+// 13 8/25/11 8:30a Alexp
+// -ForceSetupModeCallback: proceed inside the function after check for
+// action-EFI_BROWSER_ACTION_CHANGING
+// -force manufacturing defaults during first boot if
+// DEFAULT_PROVISION_SECURE_VARS set to 1
+//
+// 11 8/23/11 4:50p Alexp
+//
+// 9 8/22/11 5:19p Alexp
+// restored CallBack notification method to set Manufacturing defaults
+// from TSE SetupPage
+//
+// 8 8/19/11 5:25p Alexp
+// removed callback events on Security Page updates
+// Use static Setup Flags to Update Secure Variables at boot time
+//
+// 5 8/05/11 3:15p Alexp
+// use globally defined names for PK, KEK,.. variable
+//
+// 4 7/18/11 9:57a Alexp
+// Added new protocol SECURITY_VARIABLE_INSTALL_PROTOCOL
+//
+// 3 7/01/11 1:30p Alexp
+// ForceSetupModeCallback: fix for EFI_REVISION < 2.1builds
+//
+//
+// 1 6/30/11 3:49p Alexp
+// Add provisioning of factory default Secure variables. Used Setup page
+// to add/remove sec variables
+//
+// 3 5/16/11 1:07p Alexp
+// include SDL switch to control provisioning of Platform Key EFI
+// variable.
+//
+// 2 5/10/11 5:12p Alexp
+// removed include statement
+//
+// 1 5/10/11 10:01a Alexp
+//
+// 6 4/18/11 7:23p Alexp
+// draft. may not need this file at all
+//
+//
+//**********************************************************************
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <ImageAuthentication.h>
+#include <AmiCertificate.h>
+#include <Protocol\AmiDigitalSignature.h>
+#include <Setup.h>
+#include <SecureBootMod.h>
+
+#include "timestamp.h"
+
+#include <AutoId.h>
+#include <SetupStrTokens.h>
+
+#include <Protocol\AmiPostMgr.h>
+#include <Protocol\simplefilesystem.h>
+#ifdef SETUP_COMPILE
+#include <Protocol\HiiString.h>
+#include <Protocol\devicepath.h>
+#endif
+
+extern EFI_RUNTIME_SERVICES *pRS;
+
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+#define RETURN(status) {return status;}
+#else
+#define RETURN(status) {return ;}
+#endif
+//
+// Global variables
+//
+static EFI_GUID gAmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+static EFI_GUID gSimpleFileSystemGuid = EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID;
+static EFI_GUID gEfiGlobalVariableGuid = EFI_GLOBAL_VARIABLE;
+
+//static EFI_GUID gEfiCertX509Sha256Guid = EFI_CERT_X509_SHA256_GUID;
+//static EFI_GUID gEfiCertX509Sha384Guid = EFI_CERT_X509_SHA384_GUID;
+//static EFI_GUID gEfiCertX509Sha512Guid = EFI_CERT_X509_SHA512_GUID;
+
+static EFI_GUID PKeyFileGuid = //CC0F8A3F-3DEA-4376-9679-5426BA0A907E
+{ 0xCC0F8A3F, 0x3DEA, 0x4376, 0x96, 0x79, 0x54, 0x26, 0xba, 0x0a, 0x90, 0x7e };
+static EFI_GUID KekFileGuid = // {9FE7DE69-0AEA-470a-B50A-139813649189}
+{ 0x9fe7de69, 0xaea, 0x470a, 0xb5, 0xa, 0x13, 0x98, 0x13, 0x64, 0x91, 0x89 };
+static EFI_GUID DbFileGuid = // {FBF95065-427F-47b3-8077-D13C60710998}
+{ 0xfbf95065, 0x427f, 0x47b3, 0x80, 0x77, 0xd1, 0x3c, 0x60, 0x71, 0x9, 0x98 };
+static EFI_GUID DbxFileGuid = // {9D7A05E9-F740-44c3-858B-75586A8F9C8E}
+{ 0x9d7a05e9, 0xf740, 0x44c3, 0x85, 0x8b, 0x75, 0x58, 0x6a, 0x8f, 0x9c, 0x8e };
+static EFI_GUID DbtFileGuid = // {C246FBBF-F75C-43F7-88A6-B5FD0CF1DB7F}
+{ 0xC246FBBF, 0xF75C, 0x43F7, 0x88, 0xa6, 0xb5, 0xfd, 0x0c, 0xf1, 0xdb, 0x7f };
+
+static AMI_POST_MANAGER_PROTOCOL *mPostMgr = NULL;
+
+static EFI_GUID *SecureVariableFileGuid [] = {
+ &DbxFileGuid,
+ &DbtFileGuid,
+ &DbFileGuid,
+ &KekFileGuid,
+ &PKeyFileGuid,
+ NULL
+};
+
+static CHAR16* SecureVariableFileName[] = {
+ EFI_IMAGE_SECURITY_DATABASE1,
+ EFI_IMAGE_SECURITY_DATABASE2,
+ EFI_IMAGE_SECURITY_DATABASE,
+ EFI_KEY_EXCHANGE_KEY_NAME,
+ EFI_PLATFORM_KEY_NAME,
+ NULL
+};
+
+static CHAR16* SecureVariableFileNameDefault[] = {
+ EFI_IMAGE_SECURITY_DATABASE1_DEFAULT,
+ EFI_IMAGE_SECURITY_DATABASE2_DEFAULT,
+ EFI_IMAGE_SECURITY_DATABASE_DEFAULT,
+ EFI_KEY_EXCHANGE_KEY_NAME_DEFAULT,
+ EFI_PLATFORM_KEY_NAME_DEFAULT,
+ NULL
+};
+
+static SECURE_BOOT_SETUP_VAR SecureBootSetup = {
+ DEFAULT_SECURE_BOOT_ENABLE,
+ DEFAULT_SECURE_BOOT_MODE,
+#ifdef DEFAULT_PROVISION_SECURE_VARS
+ DEFAULT_PROVISION_SECURE_VARS,
+#else
+ 0,
+#endif
+ LOAD_FROM_FV,
+ LOAD_FROM_OROM,
+ LOAD_FROM_REMOVABLE_MEDIA,
+ LOAD_FROM_FIXED_MEDIA};
+
+static EFI_GUID guidSecurity = SECURITY_FORM_SET_GUID;
+static UINT8 bKey[5] = {0, 0, 0, 0, 0};
+typedef enum { RESET_NV_KEYS=1, SET_NV_DEFAULT_KEYS=2, SET_RT_DEFAULT_KEYS=4};
+
+EFI_STATUS InstallSecureVariables (UINT16);
+VOID UpdateSecureVariableBrowserInfo (VOID);
+VOID UpdateSecureBootBrowserInfo (VOID);
+
+//
+//
+// AMI_EFI_VARIABLE_AUTHENTICATION_2 descriptor
+//
+// A time-based authentication method descriptor template
+//
+#pragma pack(1)
+#ifndef AMI_EFI_VARIABLE_AUTHENTICATION_2
+typedef struct {
+ EFI_TIME TimeStamp;
+ WIN_CERTIFICATE_UEFI_GUID_1 AuthInfo;
+} AMI_EFI_VARIABLE_AUTHENTICATION_2;
+#endif
+typedef struct {
+ AMI_EFI_VARIABLE_AUTHENTICATION_2 AuthHdr;
+ EFI_SIGNATURE_LIST SigList;
+ EFI_SIGNATURE_DATA SigData;
+} EFI_VARIABLE_SIG_HDR_2;
+#pragma pack()
+
+#define EFI_CERT_TYPE_RSA2048_SIZE 256
+#define EFI_CERT_TYPE_SHA256_SIZE 32
+#define EFI_CERT_TYPE_CERT_X509_SHA256_GUID_SIZE 48
+#define EFI_CERT_TYPE_CERT_X509_SHA384_GUID_SIZE 64
+#define EFI_CERT_TYPE_CERT_X509_SHA512_GUID_SIZE 80
+
+static EFI_GUID mSignatureSupport[SIGSUPPORT_NUM] = {SIGSUPPORT_LIST};
+
+#ifdef TSEBIN_COMPILE
+extern BOOLEAN gBrowserCallbackEnabled;
+#else
+BOOLEAN gBrowserCallbackEnabled = FALSE;
+#endif
+
+// InstallVars
+#define SET_SECURE_VARIABLE_DEL 1
+#define SET_SECURE_VARIABLE_SET 2
+#define SET_SECURE_VARIABLE_APPEND 4
+
+//#############################################################################################################################
+#ifdef SETUP_COMPILE
+//#############################################################################################################################
+typedef struct
+{
+ UINT64 Type;
+ UINTN Size;
+ CHAR16 *Name;
+ STRING_REF Token;
+} FILE_TYPE;
+
+static BOOLEAN gValidOption = FALSE;
+static EFI_HII_STRING_PROTOCOL *HiiString = NULL;
+static EFI_HII_HANDLE gHiiHandle;
+
+#define StrMaxSize 200
+static CHAR16 StrTitle[StrMaxSize], StrMessage[StrMaxSize];
+static CHAR16 StrTemp[StrMaxSize];
+
+EFI_STATUS DevicePathToStr(EFI_DEVICE_PATH_PROTOCOL *Path,CHAR8 **Str);
+EFI_STATUS FileBrowserLaunchFileSystem(BOOLEAN bSelectFile, OUT EFI_HANDLE **outFsHandle, OUT CHAR16 **outFilePath, OUT UINT8 **outFileBuf,OUT UINTN *size );
+VOID GetHiiString(IN EFI_HII_HANDLE HiiHandle, IN STRING_REF Token, UINTN DataSize, CHAR16 * pData);
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSecureBootBrowserInfo
+//
+// Description: Update Secure Boot flags status
+//
+// Input: none
+//
+// Output: none
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateSecureBootBrowserInfo ()
+{
+#if (defined(SETUP_COMPILE) || defined (TSEBIN_COMPILE)) && EFI_SPECIFICATION_VERSION >= 0x2000A
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT8 Byte=0;
+ UINT32 Attributes=0;
+ BOOLEAN tmpBrowserCallbackEnabled = gBrowserCallbackEnabled;
+
+ gBrowserCallbackEnabled = TRUE;
+ Status = HiiLibSetBrowserData( sizeof(bKey), &bKey, &guidSecurity, AMI_SECURE_VAR_PRESENT_VAR);
+ Size = 1;
+ Status=pRS->GetVariable(EFI_SECURE_BOOT_NAME, &gEfiGlobalVariableGuid, (UINT32*)&Attributes, &Size, &Byte);
+ TRACE((-1,"SecureBoot=%x, status=%r\n", Byte, Status));
+ Status = HiiLibSetBrowserData(Size, &Byte, &gEfiGlobalVariableGuid, EFI_SECURE_BOOT_NAME);
+ Size = 1;
+ Status=pRS->GetVariable(EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (UINT32*)&Attributes, &Size, &Byte);
+ TRACE((-1,"SetupMode=%x, Status %r\n", Byte, Status));
+ Status = HiiLibSetBrowserData( Size, &Byte, &gEfiGlobalVariableGuid, EFI_SETUP_MODE_NAME);
+ gBrowserCallbackEnabled = tmpBrowserCallbackEnabled;
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateSecureVariableBrowserInfo
+//
+// Description: Detect 5 EFI Variables: PK, KEK, db, dbx, dbt(TBD)
+//
+// Input: none
+//
+// Output: none
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateSecureVariableBrowserInfo ()
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINT8 Index;
+ EFI_GUID *EfiVarGuid;
+
+ Index = 0;
+ while(SecureVariableFileName[Index] != NULL)
+ {
+ if(Index < 3)
+ EfiVarGuid = &gEfiImageSecurityDatabaseGuid;
+ else
+ EfiVarGuid = &gEfiGlobalVariableGuid;
+
+ Size = 0;
+ bKey[Index] = 0;
+ Status = pRS->GetVariable( SecureVariableFileName[Index], EfiVarGuid, NULL, &Size, NULL);
+ TRACE((-1,"NV Var %S, status=%r\n", SecureVariableFileName[Index], Status));
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ bKey[Index] = 1;
+
+ Index++;
+ }
+ pRS->SetVariable(AMI_SECURE_VAR_PRESENT_VAR,&guidSecurity, EFI_VARIABLE_BOOTSERVICE_ACCESS, sizeof(bKey), &bKey);
+
+ UpdateSecureBootBrowserInfo();
+}
+
+#if SET_SECURE_VARS == 1
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CryptoGetRawImage
+//
+// Description: Loads binary from RAW section of X firmware volume
+//
+// Input:
+// NameGuid - The guid of binary file
+// Buffer - Returns a pointer to allocated memory. Caller must free it when done.
+// Size - Returns the size of the binary loaded into the buffer.
+//
+// Output: Buffer - returns a pointer to allocated memory. Caller
+// must free it when done.
+// Size - returns the size of the binary loaded into the
+// buffer.
+// EFI_NOT_FOUND - Can't find the binary.
+// EFI_LOAD_ERROR - Load fail.
+// EFI_SUCCESS - Load success.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+CryptoGetRawImage (
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *Size
+ )
+{
+ EFI_STATUS Status;
+ UINTN HandleCount;
+ UINTN Index;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ EFI_HANDLE *HandleBuff;
+ UINT32 AuthenticationStatus;
+
+ *Buffer=0;
+ *Size=0;
+ Status = pBS->LocateHandleBuffer (ByProtocol,&gEfiFirmwareVolumeProtocolGuid,NULL,&HandleCount,&HandleBuff);
+ if (EFI_ERROR (Status) || HandleCount == 0) {
+ return EFI_NOT_FOUND;
+ }
+ //
+ // Find desired image in all Fvs
+ //
+ for (Index = 0; Index < HandleCount; Index++) {
+ Status = pBS->HandleProtocol (HandleBuff[Index],&gEfiFirmwareVolumeProtocolGuid,&Fv);
+
+ if (EFI_ERROR (Status)) {
+ continue;//return EFI_LOAD_ERROR;
+ }
+ //
+ // Try a raw file
+ //
+ Status = Fv->ReadSection (
+ Fv,
+ NameGuid,
+ EFI_SECTION_RAW,
+ 0, //Instance
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+
+ if (Status == EFI_SUCCESS) break;
+ }
+
+ pBS->FreePool(HandleBuff);
+
+ if (Index >= HandleCount) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InstallSecureVariables
+//
+// Description: Install 4 EFI Variables: PK, KEK, db, dbx & dbt(TBD)
+//
+// Input: BOOLEAN InstallVars
+// TRUE - attempt to install 4 secure variables
+// FALSE - erase 4 secure variables
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+InstallSecureVariables (
+ UINT16 InstallVars
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *pVarBuffer = NULL;
+ UINT8 Index;
+ EFI_GUID *EfiVarGuid;
+ UINT32 Attributes;
+ UINTN FileSize = 0;
+#if SET_SECURE_VARS == 1
+ UINTN Size, Offset;
+ AMI_EFI_VARIABLE_AUTHENTICATION_2 *AuthHdr2;
+#endif
+///////////////////////////////////////////////////////////////////////////////
+// Initial provisioning of Authenticated non-volitile EFI Variables
+////////////////////////////////////////////////////////////////////////////////
+ Attributes = EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ Index = 0;
+ while(/*!EFI_ERROR(Status) &&*/ SecureVariableFileName[Index] != NULL)
+ {
+ if(Index < 3)
+ EfiVarGuid = &gEfiImageSecurityDatabaseGuid;
+ else
+ EfiVarGuid = &gEfiGlobalVariableGuid;
+// if SET_NV_DEFAULT_KEYS set
+/*
+1. check if File is present CryptoGetRawImage
+2. if not - skip to next var
+3. if present -> move to Erase... .
+*/
+#if SET_SECURE_VARS == 1
+ if(InstallVars & (SET_NV_DEFAULT_KEYS | SET_RT_DEFAULT_KEYS)) {
+ pVarBuffer = NULL;
+ FileSize = 0 ;
+ Status = CryptoGetRawImage( SecureVariableFileGuid[Index], &pVarBuffer, (UINTN*)&FileSize);
+ if(EFI_ERROR(Status)) {
+ Index++;
+ continue;
+ }
+ }
+#endif
+ if((InstallVars & RESET_NV_KEYS)== RESET_NV_KEYS) {
+ // try to erase. should succeed if system in pre-boot and Admin mode
+ Status = pRS->SetVariable(SecureVariableFileName[Index],EfiVarGuid,0,0,NULL);
+ TRACE((-1,"Clear NV Var %S, Status %r\n",SecureVariableFileName[Index], Status));
+ if(EFI_ERROR(Status) && Status == EFI_NOT_FOUND)
+ Status = EFI_SUCCESS;
+ }
+#if SET_SECURE_VARS == 1
+ if((InstallVars & (SET_NV_DEFAULT_KEYS | SET_RT_DEFAULT_KEYS)) &&
+ pVarBuffer && FileSize
+ ){
+ if(InstallVars & (SET_RT_DEFAULT_KEYS)) {
+ AuthHdr2 = (AMI_EFI_VARIABLE_AUTHENTICATION_2*)pVarBuffer;
+ Offset = sizeof(EFI_TIME) + AuthHdr2->AuthInfo.Hdr.dwLength;
+ Status = pRS->SetVariable(SecureVariableFileNameDefault[Index],
+ &gEfiGlobalVariableGuid,
+ Attributes,
+ FileSize - Offset,
+ (UINT8*)pVarBuffer + Offset
+ );
+ TRACE((-1,"Set RT Var %S, Status %r\n",SecureVariableFileNameDefault[Index], Status));
+ }
+ if(InstallVars & (SET_NV_DEFAULT_KEYS)) {
+ Size = 0;
+ Status = pRS->GetVariable( SecureVariableFileName[Index], EfiVarGuid, NULL, &Size, NULL);
+ if(EFI_ERROR(Status) && Status == EFI_NOT_FOUND ) {
+ Status = pRS->SetVariable(SecureVariableFileName[Index],
+ EfiVarGuid,
+ (UINT32)(Attributes | EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS),
+ FileSize,
+ pVarBuffer
+ );
+ TRACE((-1,"Set NV Var %S, Status %r\n",SecureVariableFileName[Index], Status));
+ }
+ }
+ pBS->FreePool(pVarBuffer);
+ }
+#endif
+ Index++;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: FillAuthHdr
+//
+// Description:
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static VOID FillAuthHdr(
+ UINT8* pVar,
+ UINT8 VarSetMode
+)
+{
+ AMI_EFI_VARIABLE_AUTHENTICATION_2 *AuthHdr2;
+ static EFI_TIME EfiTime = {
+ FOUR_DIGIT_YEAR_INT,
+ TWO_DIGIT_MONTH_INT,
+ TWO_DIGIT_DAY_INT,
+ TWO_DIGIT_HOUR_INT,
+ TWO_DIGIT_MINUTE_INT,
+ TWO_DIGIT_SECOND_INT,0,0,0,0,0};
+
+ AuthHdr2 = (AMI_EFI_VARIABLE_AUTHENTICATION_2*)pVar;
+ MemCpy (&AuthHdr2->TimeStamp, &EfiTime, sizeof (EFI_TIME));
+ if((VarSetMode & SET_SECURE_VARIABLE_APPEND)== SET_SECURE_VARIABLE_APPEND)
+ AuthHdr2->TimeStamp.Year = 2000; // append should not change the original date the var was created
+ AuthHdr2->AuthInfo.Hdr.dwLength = sizeof(WIN_CERTIFICATE_UEFI_GUID_1);
+ AuthHdr2->AuthInfo.Hdr.wRevision = 0x200;
+ AuthHdr2->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
+ AuthHdr2->AuthInfo.CertType = gEfiCertTypePkcs7Guid;
+
+ return;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: FillAuthVarHdr
+//
+// Description:
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID FillAuthVarHdr(
+ UINT8 *pVar,
+ UINT8 *pCert,
+ UINTN CertSize,
+ UINT8 VarSetMode
+)
+{
+ EFI_VARIABLE_SIG_HDR_2 *AuthHdr2;
+ static EFI_GUID AmiSigOwner = AMI_APTIO_SIG_OWNER_GUID;
+
+ AuthHdr2 = (EFI_VARIABLE_SIG_HDR_2*)pVar;
+
+ // Append AuthHdr to Var data.
+ FillAuthHdr(pVar, VarSetMode); // Append AuthHdr to Var data.
+
+ // CopyMem (&AuthHdr2->SigList.SignatureType, gEfiCertSha256Guid, sizeof (EFI_GUID));
+ if(CertSize == EFI_CERT_TYPE_SHA256_SIZE)
+ AuthHdr2->SigList.SignatureType = gEfiCertSha256Guid;
+ if(CertSize == EFI_CERT_TYPE_CERT_X509_SHA256_GUID_SIZE)
+ AuthHdr2->SigList.SignatureType = gEfiCertX509Sha256Guid;
+ if(CertSize == EFI_CERT_TYPE_CERT_X509_SHA384_GUID_SIZE)
+ AuthHdr2->SigList.SignatureType = gEfiCertX509Sha384Guid;
+ if(CertSize == EFI_CERT_TYPE_CERT_X509_SHA512_GUID_SIZE)
+ AuthHdr2->SigList.SignatureType = gEfiCertX509Sha512Guid;
+ if(CertSize == EFI_CERT_TYPE_RSA2048_SIZE)
+ AuthHdr2->SigList.SignatureType = gEfiCertRsa2048Guid;
+ if(CertSize > EFI_CERT_TYPE_RSA2048_SIZE)
+ AuthHdr2->SigList.SignatureType = gEfiCertX509Guid;
+
+ AuthHdr2->SigList.SignatureSize = (UINT32)(sizeof(EFI_GUID)+CertSize);
+ AuthHdr2->SigList.SignatureListSize = AuthHdr2->SigList.SignatureSize+sizeof(EFI_SIGNATURE_LIST);
+ AuthHdr2->SigList.SignatureHeaderSize = 0;
+ AuthHdr2->SigData.SignatureOwner = AmiSigOwner;
+
+TRACE((TRACE_ALWAYS,"SigList GUID: %g\nSigSize=%x\nListSize=%x", AuthHdr2->SigList.SignatureType, AuthHdr2->SigList.SignatureSize, AuthHdr2->SigList.SignatureListSize));
+
+// MemCpy(AuthHdr2->SigData.SignatureData, pCert, CertSize);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ValidateSignatureList
+//
+// Description:
+// Validate the data payload begins with valid Signature List header
+// and based on the results returns Status.
+//
+// Input:
+// IN VOID *Data - pointer to the Var data
+// IN UINTN DataSize - size of Var data
+//
+// Output: EFI_STATUS
+// UINTN RealDataSize - only the size of the combined length of Signature Lists
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ValidateSignatureList (
+ IN VOID *Data,
+ IN UINTN DataSize
+)
+{
+ EFI_STATUS Status;
+ EFI_SIGNATURE_LIST *SigList;
+ UINTN Index;
+
+ Status = EFI_SECURITY_VIOLATION;
+
+ if(DataSize == 0 || Data == NULL)
+ return Status; // Sig not found
+
+ SigList = (EFI_SIGNATURE_LIST *)Data;
+
+// loop till end of DataSize for all available SigLists
+
+// Verify signature is one from SigDatabase list mSignatureSupport / sizeof(EFI_GUID)
+// SigData begins with SigOwner GUID
+// SignatureHdrSize = 0 for known Sig Types
+
+ while ((DataSize > 0) && (DataSize >= SigList->SignatureListSize)) {
+
+ for (Index = 0; Index < SIGSUPPORT_NUM; Index++) {
+ if (!guidcmp ((EFI_GUID*) &(SigList->SignatureType), &mSignatureSupport[Index]))
+ break;
+ }
+TRACE((TRACE_ALWAYS,"SigList.Type-"));
+ if(Index >= SIGSUPPORT_NUM)
+ return EFI_SECURITY_VIOLATION; // Sig not found
+
+TRACE((TRACE_ALWAYS,"OK\nSigList.Size-"));
+ if(SigList->SignatureListSize < 0x4C || // Min size for SHA2 Hash Certificate sig list
+ SigList->SignatureListSize > NVRAM_SIZE)
+ return EFI_SECURITY_VIOLATION;
+
+TRACE((TRACE_ALWAYS,"OK\nSigList.HdrSize-"));
+ if(SigList->SignatureHeaderSize != 0)
+ return EFI_SECURITY_VIOLATION; // Sig not found
+
+TRACE((TRACE_ALWAYS,"OK\n"));
+ DataSize -= SigList->SignatureListSize;
+ SigList = (EFI_SIGNATURE_LIST *) ((UINT8 *) SigList + SigList->SignatureListSize);
+
+ Status = EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+#ifdef SMIFLASH_COMPILE
+
+#if defined(PRESERVE_SECURE_VARIABLES) && PRESERVE_SECURE_VARIABLES==1
+
+static EFI_GUID AmiNvramControlProtocolGuid = { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } };
+typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+
+typedef struct{
+ SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables;
+} AMI_NVRAM_CONTROL_PROTOCOL;
+
+static AMI_NVRAM_CONTROL_PROTOCOL *NvramControl = NULL;
+
+// Array of pointers to Secure Variables in TSEG.
+static UINT8* SecureFlashVar[6];
+static UINTN SecureFlashVarSize[6];
+static UINT32 SecureFlashVarAttr[6];
+static UINT32 SecBootVar_Attr=0;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: PreserveSecureVariables
+//
+// Description: Save the PK-KEK-db-dbx
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PreserveSecureVariables(VOID)
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+ EFI_GUID *EfiVarGuid;
+ UINTN VarSize;
+
+TRACE((TRACE_ALWAYS,"PreserveVar:\n"));
+// 1. Preserve Secure Boot variables.
+ Index = 0;
+ while(SecureVariableFileName[Index] != NULL)
+ {
+ if(Index < 3)
+ EfiVarGuid = &gEfiImageSecurityDatabaseGuid;
+ else
+ EfiVarGuid = &gEfiGlobalVariableGuid;
+
+ SecureFlashVar[Index] = NULL;
+ SecureFlashVarSize[Index] = 0;
+ SecureFlashVarAttr[Index] = 0;
+ Status = pRS->GetVariable( SecureVariableFileName[Index], EfiVarGuid, &SecureFlashVarAttr[Index], &SecureFlashVarSize[Index], SecureFlashVar[Index]);
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ VarSize = SecureFlashVarSize[Index]+sizeof(AMI_EFI_VARIABLE_AUTHENTICATION_2);
+ Status = pSmst->SmmAllocatePool(0, VarSize, (void**)&SecureFlashVar[Index]);
+ if(!EFI_ERROR(Status))
+ Status = pRS->GetVariable(
+ SecureVariableFileName[Index],
+ EfiVarGuid,
+ &SecureFlashVarAttr[Index],
+ &SecureFlashVarSize[Index],
+ SecureFlashVar[Index]+sizeof(AMI_EFI_VARIABLE_AUTHENTICATION_2));
+
+ SecureFlashVarSize[Index] = VarSize;
+ FillAuthHdr(SecureFlashVar[Index], SET_SECURE_VARIABLE_SET);
+
+TRACE((TRACE_ALWAYS,"%S (%r) Size=%x\n", SecureVariableFileName[Index], Status, SecureFlashVarSize[Index]));
+ }
+ Index++;
+ }
+// 2. Preserve Secure Boot Setup variables
+ // Set "Show BootTime Variables" flag
+ if (NvramControl == NULL) // first time?
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+ if (NvramControl == NULL)
+ return;
+ // Set "Show BootTime Variables" flag
+ NvramControl->ShowBootTimeVariables(TRUE);
+
+ VarSize = sizeof(SECURE_BOOT_SETUP_VAR);
+ Status = pRS->GetVariable (AMI_SECURE_BOOT_SETUP_VAR,&guidSecurity,&SecBootVar_Attr,&VarSize,&SecureBootSetup);
+TRACE((TRACE_ALWAYS,"SecureBootSetup (%r) Size=%x, SecBoot-%d, SecMode-%d,DefaultProvision-%d\n", Status, VarSize, SecureBootSetup.SecureBootSupport, SecureBootSetup.SecureBootMode,SecureBootSetup.DefaultKeyProvision));
+
+ // Clear "Show Boot Time Variables"
+ NvramControl->ShowBootTimeVariables(FALSE);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: RestoreSecureVariables
+//
+// Description: Restore previous PK-KEK-db-dbx
+//
+// Input: NONE
+//
+// Output: NONE
+//
+// Returns: NONE
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RestoreSecureVariables (VOID)
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+ EFI_GUID *EfiVarGuid;
+
+TRACE((TRACE_ALWAYS,"RestoreVar:\n"));
+// 1. Restore Secure Boot variables.
+ Index = 0;
+ while(SecureVariableFileName[Index] != NULL)
+ {
+ if(SecureFlashVar[Index] && SecureFlashVarSize[Index])
+ {
+ if(Index < 3)
+ EfiVarGuid = &gEfiImageSecurityDatabaseGuid;
+ else
+ EfiVarGuid = &gEfiGlobalVariableGuid;
+
+ Status = pRS->SetVariable(SecureVariableFileName[Index],
+ EfiVarGuid,
+ SecureFlashVarAttr[Index],
+ SecureFlashVarSize[Index],
+ SecureFlashVar[Index]
+ );
+TRACE((TRACE_ALWAYS,"%S (%r) Size=%x Attr=%x\n", SecureVariableFileName[Index], Status, SecureFlashVarSize[Index], SecureFlashVarAttr[Index]));
+ pSmst->SmmFreePool(SecureFlashVar[Index]);
+ SecureFlashVar[Index] = NULL;
+ }
+ Index++;
+ }
+// 2. Restore Secure Boot Setup variables
+ // Set "Show BootTime Variables" flag
+ if (NvramControl == NULL)
+ return;
+ // Set "Show BootTime Variables" flag
+ NvramControl->ShowBootTimeVariables(TRUE);
+
+ Status = pRS->SetVariable (AMI_SECURE_BOOT_SETUP_VAR, &guidSecurity,SecBootVar_Attr, sizeof(SECURE_BOOT_SETUP_VAR),&SecureBootSetup);
+TRACE((TRACE_ALWAYS,"SecureBootSetup (%r)\n", Status));
+
+ // Clear "Show Boot Time Variables"
+ NvramControl->ShowBootTimeVariables(FALSE);
+
+}
+#endif //#if defined(PRESERVE_SECURE_VARIABLES) && PRESERVE_SECURE_VARIABLES==1
+#endif // #ifdef SMIFLASH_COMPILE
+
+//#############################################################################################################################
+#ifdef SETUP_COMPILE
+//#############################################################################################################################
+#ifndef EFI_LEGACY_BIOS_PROTOCOL_GUID
+// ## Include/Protocol/LegacyBios.h
+#define EFI_LEGACY_BIOS_PROTOCOL_GUID \
+{ 0xdb9a1e3d, 0x45cb, 0x4abb, { 0x85, 0x3b, 0xe5, 0x38, 0x7f, 0xdb, 0x2e, 0x2d }}
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: IsCsmEnabled
+//
+// Description: This function checks if CSM is enabled
+//
+// Input:
+// None
+//
+// Output:
+// 0 - CSM is disabled
+// 1 - CSM is enabled
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+IsCsmEnabled(VOID)
+{
+ EFI_STATUS Status;
+ UINTN Size = sizeof(EFI_HANDLE);
+ EFI_HANDLE Handle;
+ static EFI_GUID EfiLegacyBiosProtocolGuid = EFI_LEGACY_BIOS_PROTOCOL_GUID;
+
+ Status = pBS->LocateHandle(ByProtocol, &EfiLegacyBiosProtocolGuid, NULL, &Size, &Handle);
+ return (EFI_ERROR(Status)) ? 0 : 1;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ForceSetupModeCallback
+//
+// Description:
+//
+// Input: none
+//
+// Output: VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+// 4.6.5.1
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+EFI_STATUS
+#else
+VOID
+#endif
+ForceSetupModeCallback(EFI_HII_HANDLE HiiHandle, UINT16 Class, UINT16 SubClass, UINT16 Key)
+{
+ EFI_STATUS Status;
+ UINT8 Sel = 0;
+ UINTN Size;
+ UINT32 Attributes=0;
+
+#if EFI_SPECIFICATION_VERSION>0x20000
+ CALLBACK_PARAMETERS *Callback;
+ EFI_BROWSER_ACTION_REQUEST *rq;
+
+ Callback = GetCallbackParameters();
+ TRACE((-1,"\n====ForceSetupModeCallback==== Key = %d, Callback %x, Value %d\n", Key, Callback, Callback->Value->u8));
+ if(!Callback || Callback->Action != EFI_BROWSER_ACTION_CHANGING)
+ RETURN(EFI_UNSUPPORTED)
+#endif
+ if(mPostMgr == NULL)
+ {
+ Status = pBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL, &mPostMgr);
+ if(EFI_ERROR(Status) || !mPostMgr) {
+ RETURN(EFI_UNSUPPORTED)
+ }
+ }
+ Status = EFI_SUCCESS;
+ switch(Key) {
+ case SECURE_BOOT_MENU_REFRESH:
+ UpdateSecureBootBrowserInfo();
+ break;
+ case KEY_MANAGEMENT_MENU_REFRESH:
+ UpdateSecureVariableBrowserInfo();
+ break;
+#if EFI_SPECIFICATION_VERSION>0x20000
+ case SECURE_BOOT_SUPPORT_CHANGE_KEY:
+ if( Callback->Value->u8 == 1) // trying to switch Secure Boot from Disable to Enable
+ {
+ rq = Callback->ActionRequest;
+ *rq = EFI_BROWSER_ACTION_REQUEST_NONE;
+ Size = 1;
+ Status=pRS->GetVariable(EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, (UINT32*)&Attributes, &Size, &Sel);
+ if(Sel) {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_ENABLE_ERROR_MODE_TITLE), sizeof(StrTitle), StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_ENABLE_ERROR_MODE), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, MSGBOX_TYPE_OK,NULL);
+ #if DEFAULT_SECURE_BOOT_ENABLE == 0
+ Status = EFI_UNSUPPORTED;
+ #endif
+ } else
+ if (IsCsmEnabled()) {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_CSM_LOAD_TITLE), sizeof(StrTitle),StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_CSM_LOAD), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, MSGBOX_TYPE_OK,NULL);
+/* this should be enough, but TSE has a bug that doesn't support FORM_DISCARD action try a workaround instead
+ {
+ SETUP_DATA Setup;
+ UINTN Size = sizeof(Setup);
+ static EFI_GUID SetupGuid = SETUP_GUID;
+ Status = HiiLibGetBrowserData(&Size, &Setup, &SetupGuid, L"Setup");
+ TRACE((-1, "Setup.CsmSupport=: %x, Size = %x\n", Setup.CsmSupport, Size));
+ if(!EFI_ERROR(Status) && Setup.CsmSupport == 1) {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_CSM_LOAD_TITLE), sizeof(StrTitle),StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_CSM_LOAD), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, (UINT8)MSGBOX_TYPE_YESNO, &Sel);
+ if (Sel == 1) {
+ Setup.CsmSupport = 0;
+ Status = HiiLibSetBrowserData(Size, &Setup, &SetupGuid, L"Setup");
+// pRS->SetVariable ( L"Setup", &SetupGuid, Attributes, Size, &Setup);
+ }
+ }
+ }
+end of workaround */
+
+ #if DEFAULT_SECURE_BOOT_ENABLE == 0
+ Status = EFI_UNSUPPORTED;
+ #endif
+ }
+ }
+ break;
+#endif
+ case SECURE_BOOT_MODE_CHANGE_KEY:
+ if( Callback->Value->u8 == 1) // trying to switch from Custom to Standard
+ break;
+ case KEY_PROVISION_CHANGE_KEY:
+ if(Key == KEY_PROVISION_CHANGE_KEY &&
+ Callback->Value->u8 == 0) // trying to switch from Disable to Enable
+ break;
+ case FORCE_SETUP_KEY:
+ case FORCE_DEFAULT_KEY:
+ if (Key == FORCE_SETUP_KEY)
+ {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_FORCE_SETUP_MODE), sizeof(StrTitle),StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_RESET_TO_SETUP), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, (UINT8)MSGBOX_TYPE_YESNO, &Sel);
+ if (Sel == 0)
+ Status = InstallSecureVariables(RESET_NV_KEYS); // erase
+ }
+#if SET_SECURE_VARS == 1
+ if (Key == FORCE_DEFAULT_KEY || Key == KEY_PROVISION_CHANGE_KEY || Key == SECURE_BOOT_MODE_CHANGE_KEY)
+ {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_LOAD_DEFAULT_VARS_TITLE), sizeof(StrTitle),StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_LOAD_DEFAULT_VARS), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, (UINT8)MSGBOX_TYPE_YESNO, &Sel);
+ if (Sel == 0)
+ Status = InstallSecureVariables(RESET_NV_KEYS | SET_NV_DEFAULT_KEYS); // erase+set
+ }
+#endif
+ UpdateSecureVariableBrowserInfo();
+ if (EFI_ERROR(Status))
+ {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_VAR_UPDATE_LOCKED_TITLE), sizeof(StrTitle),StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_VAR_UPDATE_LOCKED), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, MSGBOX_TYPE_OK,NULL);
+ Status = EFI_SUCCESS;
+ }
+ break;
+
+ default:
+ break;
+ }
+ RETURN(Status)
+}
+// ==========================================
+// (4.6.5.0+)
+// #if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028a
+// ==========================================
+
+EFI_STATUS SetSecureVariable(UINT8 Index, UINT16 InstallVars, UINT8 *pVarBuffer, UINTN VarSize )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_GUID *EfiVarGuid;
+ UINT32 Attributes;
+
+///////////////////////////////////////////////////////////////////////////////
+// Initial provisioning of Authenticated non-volitile EFI Variables
+///////////////////////////////////////////////////////////////////////////////
+ if(SecureVariableFileName[Index] != NULL)
+ {
+ if(Index < 3)
+ EfiVarGuid = &gEfiImageSecurityDatabaseGuid;
+ else
+ EfiVarGuid = &gEfiGlobalVariableGuid;
+
+ if((InstallVars & SET_SECURE_VARIABLE_DEL) == SET_SECURE_VARIABLE_DEL) {
+ // try to erase. should succeed if system in pre-boot and Admin mode
+ Status = pRS->SetVariable(SecureVariableFileName[Index],EfiVarGuid,0,0,NULL);
+ TRACE((-1,"Set(0) Var %S, Status %r\n",SecureVariableFileName[Index], Status));
+ }
+ if((InstallVars & SET_SECURE_VARIABLE_SET)==SET_SECURE_VARIABLE_SET &&
+ pVarBuffer && VarSize) {
+
+ Attributes = EFI_VARIABLE_RUNTIME_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE |
+ EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS;
+
+ if((InstallVars & SET_SECURE_VARIABLE_APPEND)== SET_SECURE_VARIABLE_APPEND)
+ Attributes |= EFI_VARIABLE_APPEND_WRITE;
+
+ Status = pRS->SetVariable(SecureVariableFileName[Index], EfiVarGuid, Attributes, VarSize, pVarBuffer);
+ TRACE((-1,"Set Var %S, Status %r\n",SecureVariableFileName[Index], Status));
+ }
+ }
+
+ UpdateSecureVariableBrowserInfo();
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetHiiString
+//
+// Description: This function Reads a String from HII
+//
+// Input: IN EFI_HII_HANDLE HiiHandle - Efi Hii Handle
+// IN STRING_REF Token - String Token
+// IN OUT UINTN *pDataSize - Length of the StringBuffer
+// OUT EFI_STRING *ppData - The buffer to receive the characters in the string.
+//
+// Output: EFI_STATUS - Depending on result
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID GetHiiString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF Token,
+ IN UINTN DataSize,
+ IN OUT CHAR16 *ppData
+ )
+{
+ EFI_STATUS Status;
+
+ if (!ppData) return;
+
+ Status = HiiLibGetString(HiiHandle, Token, &DataSize, (EFI_STRING)ppData);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) ppData=L"??? ";
+
+TRACE((-1,"%r, StrRef '%S', Size %d, Token=%d\n",Status, ppData, DataSize, Token));
+}
+
+// 4.6.5.1
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+EFI_STATUS
+#else
+VOID
+#endif
+SetAppendSecureBootDBCallback(EFI_HII_HANDLE HiiHandle, UINT16 Class, UINT16 SubClass, UINT16 Key)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *FsHandle;
+ UINT8 *FileBuf=NULL;
+ UINT8 *Data=NULL;
+ UINTN size, VarSize;
+ CHAR16 *FilePath=NULL;
+ UINT8 index;
+ UINT8 Sel = 1;
+ UINT16 CertSel = 0, AddSize;
+ POSTMENU_TEMPLATE MenuList[2];
+ UINT8 VarSetMode = SET_SECURE_VARIABLE_SET;
+
+#if EFI_SPECIFICATION_VERSION>0x20000
+ CALLBACK_PARAMETERS *Callback;
+
+ Callback = GetCallbackParameters();
+ if(!Callback || Callback->Action != EFI_BROWSER_ACTION_CHANGING)
+ RETURN(EFI_UNSUPPORTED)
+#endif
+
+ switch(Key)
+ {
+ case APPEND_KEK_KEY:
+ index = 3;
+ VarSetMode |= SET_SECURE_VARIABLE_APPEND;
+ break;
+ case APPEND_DB_KEY:
+ index = 2;
+ VarSetMode |= SET_SECURE_VARIABLE_APPEND;
+ break;
+ case APPEND_DBT_KEY:
+ index =1;
+ VarSetMode |= SET_SECURE_VARIABLE_APPEND;
+ break;
+ case APPEND_DBX_KEY:
+ index = 0;
+ VarSetMode |= SET_SECURE_VARIABLE_APPEND;
+ break;
+ case SET_PK_KEY:
+ index = 4;
+ VarSetMode |= SET_SECURE_VARIABLE_DEL;
+ break;
+ case SET_KEK_KEY:
+ index = 3;
+ VarSetMode |= SET_SECURE_VARIABLE_DEL;
+ break;
+ case SET_DB_KEY:
+ index = 2;
+ VarSetMode |= SET_SECURE_VARIABLE_DEL;
+ break;
+ case SET_DBT_KEY:
+ index = 1;
+ VarSetMode |= SET_SECURE_VARIABLE_DEL;
+ break;
+ case SET_DBX_KEY:
+ index = 0;
+ VarSetMode |= SET_SECURE_VARIABLE_DEL;
+ break;
+ default:
+ RETURN(EFI_SUCCESS)
+ }
+
+ if(mPostMgr == NULL)
+ {
+ RETURN(EFI_SUCCESS)
+ }
+
+ gHiiHandle = HiiHandle;
+
+ MemSet(StrTemp, sizeof(StrTemp), 0);
+
+#if SET_SECURE_VARS == 1
+ Sel = 1; // No
+// DataSize = sizeof(StrTitle);
+ if(VarSetMode & SET_SECURE_VARIABLE_APPEND)
+// HiiLibGetString(HiiHandle, STRING_TOKEN(STR_SECURE_APPEND), &DataSize, (EFI_STRING)StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_SECURE_APPEND), sizeof(StrTitle), StrTitle);
+ else
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_SECURE_SET), sizeof(StrTitle), StrTitle);
+
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_UPDATE_FROM_DEFAULTS),sizeof(StrMessage), StrMessage);
+ Swprintf_s(StrTemp, sizeof(StrTemp), StrMessage , SecureVariableFileName[index]);
+ mPostMgr->DisplayMsgBox( StrTitle, StrTemp, (UINT8)MSGBOX_TYPE_YESNO, &Sel);
+
+ if(Sel == 0)
+ {
+ size = 0 ;
+ Status = CryptoGetRawImage( SecureVariableFileGuid[index], &FileBuf, (UINTN*)&size);
+ } else
+#endif
+ {
+ size = 0;
+ AddSize = 0;
+ Status = FileBrowserLaunchFileSystem(TRUE, &FsHandle, &FilePath, &FileBuf, &size);
+ if(!EFI_ERROR(Status) && FileBuf)
+ {
+ // Clear the memory allocated
+ MemSet(MenuList, sizeof(MenuList), 0);
+ MenuList[0].ItemToken = STRING_TOKEN(STR_SECURE_CER);
+ MenuList[1].ItemToken = STRING_TOKEN(STR_SECURE_VAR);
+
+ // Call post manager to display the menu
+ Status = mPostMgr->DisplayPostMenu(gHiiHandle,
+ STRING_TOKEN(STR_SECURE_TITLE), // Change this
+ 0,
+ MenuList,
+ 2,
+ &CertSel);
+
+ if(!EFI_ERROR(Status))
+ {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_UPDATE_FROM_FILE), sizeof(StrMessage), StrMessage);
+ Swprintf_s(StrTemp, sizeof(StrTemp),StrMessage, SecureVariableFileName[index],FilePath);
+
+ if(CertSel==0) {
+ AddSize = sizeof(EFI_VARIABLE_SIG_HDR_2)-1; // decrement by 1 byte as SIG_DATA adds 1 dummy byte
+ }
+
+ // Validate Signature List integrity
+ if(!EFI_ERROR(ValidateSignatureList (FileBuf, size))) {
+ CertSel=2;
+ AddSize = sizeof(AMI_EFI_VARIABLE_AUTHENTICATION_2);
+ }
+ //
+ // form an AuthVar Hdr on top of Var
+ //
+ //Allocate new Size
+ VarSize = size+AddSize;
+ Status = pBS->AllocatePool(EfiBootServicesData, VarSize, &Data);
+ ASSERT_EFI_ERROR (Status);
+ // Append AuthHdr to Var data.
+ if(CertSel==0)
+ FillAuthVarHdr(Data,FileBuf,size, VarSetMode);
+ else
+ if(CertSel==2) // unsupported - append from SigList
+ FillAuthHdr(Data, VarSetMode);
+
+ MemCpy ((VOID*)((UINTN)Data+AddSize), FileBuf, size);
+ if(FileBuf)
+ pBS->FreePool(FileBuf);
+ FileBuf = Data;
+ size = VarSize;
+ }
+ }
+ }
+
+ if(!EFI_ERROR(Status) && FileBuf){
+ if(Sel == 1)
+ mPostMgr->DisplayMsgBox( StrTitle, StrTemp, (UINT8)MSGBOX_TYPE_YESNO, &Sel);
+
+ if(Sel == 0)
+ {
+ Status = SetSecureVariable(index, VarSetMode, FileBuf, size);
+ if(!EFI_ERROR(Status)){
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_SUCCESS), sizeof(StrMessage),StrMessage);
+ }
+ else
+ {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_FAILED), sizeof(StrMessage),StrMessage);
+ }
+ mPostMgr->DisplayMsgBox( StrTitle,StrMessage , MSGBOX_TYPE_OK, NULL );
+ }
+ }
+ if(FileBuf)
+ pBS->FreePool(FileBuf);
+
+ if(FilePath)
+ pBS->FreePool(FilePath);
+
+ RETURN(EFI_SUCCESS)
+}
+// 4.6.5.1
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+EFI_STATUS
+#else
+VOID
+#endif
+GetSecureBootDBCallback(EFI_HII_HANDLE HiiHandle, UINT16 Class, UINT16 SubClass, UINT16 Key)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *FsHandle;
+ UINT8 *FileBuf=NULL;
+ UINTN size;
+ CHAR16 *FilePath=NULL;
+ UINT8 Index, nVars;
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *pSFP;
+ EFI_FILE_PROTOCOL *pRoot,*FileHandle;
+ EFI_GUID *EfiVarGuid;
+ UINT8 *Data=NULL;
+ BOOLEAN bFound = TRUE;
+
+#if EFI_SPECIFICATION_VERSION>0x20000
+ CALLBACK_PARAMETERS *Callback;
+
+ Callback = GetCallbackParameters();
+ if(!Callback || Callback->Action != EFI_BROWSER_ACTION_CHANGING)
+ RETURN(EFI_UNSUPPORTED)
+#endif
+
+ gHiiHandle = HiiHandle;
+ size = 0;
+ Status = FileBrowserLaunchFileSystem(FALSE, &FsHandle, &FilePath, &FileBuf, &size);
+ if(EFI_ERROR(Status))
+ goto Done;
+
+ Index = 0;
+ nVars = 0;
+ MemSet(StrTemp, sizeof(StrTemp), 0);
+ while(bFound && SecureVariableFileName[Index] != NULL)
+ {
+ if(Index < 3)
+ EfiVarGuid = &gEfiImageSecurityDatabaseGuid;
+ else
+ EfiVarGuid = &gEfiGlobalVariableGuid;
+
+ size = 0;
+ Status = pRS->GetVariable( SecureVariableFileName[Index], EfiVarGuid, NULL, &size, NULL);
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ // Append AuthHdr to Var data.
+ //Allocate Size
+ Status = pBS->AllocatePool(EfiBootServicesData, size, &Data);
+ ASSERT_EFI_ERROR (Status);
+
+ // Read the Variable
+ Status = pRS->GetVariable( SecureVariableFileName[Index], EfiVarGuid, NULL, &size, Data);
+ if (!EFI_ERROR(Status))
+ {
+ Status = pBS->HandleProtocol( FsHandle, &gSimpleFileSystemGuid, &pSFP );
+ if (!EFI_ERROR(Status))
+ {
+ Status = pSFP->OpenVolume(pSFP,&pRoot);
+ if (!EFI_ERROR(Status))
+ {
+ Status = pRoot->Open(pRoot,&FileHandle,SecureVariableFileName[Index],
+ EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,0);
+ if(!EFI_ERROR(Status))
+ {
+ // Write
+ FileHandle->Write(FileHandle,&size, Data);
+ FileHandle->Close(FileHandle);
+ nVars++;
+ }
+ }
+ }
+
+ if (EFI_ERROR(Status)) {
+ bFound = FALSE;
+ Swprintf_s(StrTemp, sizeof(StrTemp), L" %s ", SecureVariableFileName[Index]);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_WRITE_ERROR_TITLE), sizeof(StrTitle),StrTitle);
+ mPostMgr->DisplayMsgBox( StrTitle, StrTemp, MSGBOX_TYPE_OK, NULL );
+ }
+ }
+ if(Data!=NULL)
+ pBS->FreePool(Data);
+ }
+
+ Index++;
+ }
+ if (Index==5 && bFound) {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_SAVE_SEC_KEY),sizeof(StrMessage), StrMessage);
+ Swprintf_s(StrTemp, sizeof(StrTemp), StrMessage, nVars);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_SAVE_SEC_KEY_TITLE),sizeof(StrTitle), StrTitle);
+ mPostMgr->DisplayMsgBox(StrTitle , StrTemp, MSGBOX_TYPE_OK, NULL );
+ }
+
+Done:
+
+ if(FileBuf)
+ pBS->FreePool(FileBuf);
+
+ if(FilePath)
+ pBS->FreePool(FilePath);
+
+ RETURN(EFI_SUCCESS)
+}
+
+// 4.6.5.1
+#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028b
+EFI_STATUS
+#else
+VOID
+#endif
+DeleteSecureBootDBCallback(EFI_HII_HANDLE HiiHandle, UINT16 Class, UINT16 SubClass, UINT16 Key)
+{
+ EFI_STATUS Status;
+ UINT8 index;
+ UINT8 Sel = 0;
+
+#if EFI_SPECIFICATION_VERSION>0x20000
+ CALLBACK_PARAMETERS *Callback;
+
+ Callback = GetCallbackParameters();
+ if(!Callback || Callback->Action != EFI_BROWSER_ACTION_CHANGING)
+ RETURN(EFI_UNSUPPORTED)
+#endif
+
+ switch(Key)
+ {
+ case DELETE_PK_KEY:
+ index = 4;
+ break;
+ case DELETE_KEK_KEY:
+ index = 3;
+ break;
+ case DELETE_DB_KEY:
+ index = 2;
+ break;
+ case DELETE_DBT_KEY:
+ index = 1;
+ break;
+ case DELETE_DBX_KEY:
+ index = 0;
+ break;
+ default:
+ RETURN(EFI_SUCCESS)
+ }
+
+ if(mPostMgr == NULL)
+ {
+ RETURN(EFI_SUCCESS)
+ }
+
+ gHiiHandle = HiiHandle;
+
+ MemSet(StrTemp, sizeof(StrTemp), 0);
+
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_DELETE_SEC_KEY_TITLE), sizeof(StrTitle),StrTitle);
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_DELETE_SEC_KEY), sizeof(StrMessage),StrMessage);
+ Swprintf_s(StrTemp, sizeof(StrTemp), StrMessage, SecureVariableFileName[index]);
+ mPostMgr->DisplayMsgBox( StrTitle, StrTemp, (UINT8)MSGBOX_TYPE_YESNO, &Sel);
+
+ if(Sel == 0)
+ {
+ Status = SetSecureVariable(index,SET_SECURE_VARIABLE_DEL, NULL, 0);
+
+ if(!EFI_ERROR(Status)){
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_SUCCESS), sizeof(StrMessage),StrMessage);
+ }
+ else
+ {
+ GetHiiString(HiiHandle, STRING_TOKEN(STR_FAILED), sizeof(StrMessage),StrMessage);
+ }
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, MSGBOX_TYPE_OK, NULL );
+ }
+
+ RETURN(EFI_SUCCESS)
+}
+//############################################################################################################
+static VOID EfiStrCat (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ )
+{
+ Wcscpy (Destination + Wcslen (Destination), Source);
+}
+
+static CHAR16 *StrDup8to16( CHAR8 *string )
+{
+ CHAR16 *text;
+ UINTN i;
+
+ if ( string == NULL )
+ return NULL;
+
+ pBS->AllocatePool(EfiBootServicesData, (1 + Strlen( string )) * sizeof(CHAR16), &text);
+
+ if ( text != NULL )
+ {
+ i=0;
+ while(text[i] = (CHAR16)string[i])
+ i++;
+ }
+
+ return text;
+}
+
+
+EFI_STRING_ID HiiAddString(IN EFI_HII_HANDLE HiiHandle,IN CHAR16 *String)
+{
+ EFI_STATUS Status;
+ CHAR8* Languages = NULL;
+ UINTN LangSize = 0;
+ CHAR8* CurrentLanguage;
+ BOOLEAN LastLanguage = FALSE;
+ EFI_STRING_ID StringId = 0;
+ CHAR8 *SupportedLanguages=NULL;
+
+ if(HiiString == NULL) {
+ Status = pBS->LocateProtocol(&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString);
+ if(EFI_ERROR(Status))
+ return 0;
+ }
+
+ if(SupportedLanguages == NULL) {
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, Languages, &LangSize);
+ if(Status == EFI_BUFFER_TOO_SMALL) {
+ Status = pBS->AllocatePool(EfiBootServicesData, LangSize, &Languages);
+ if(EFI_ERROR(Status))
+ return 0; //not enough resources to allocate string
+ Status = HiiString->GetLanguages(HiiString, HiiHandle, Languages, &LangSize);
+ }
+ if(EFI_ERROR(Status))
+ return 0;
+ } else {
+ Languages = SupportedLanguages;
+ }
+
+ while(!LastLanguage) {
+ CurrentLanguage = Languages; //point CurrentLanguage to start of new language
+ while(*Languages != ';' && *Languages != 0)
+ Languages++;
+
+ if(*Languages == 0) { //last language in language list
+ LastLanguage = TRUE;
+ if(StringId == 0)
+ Status = HiiString->NewString(HiiString, HiiHandle, &StringId, CurrentLanguage, NULL, String, NULL);
+ else
+ Status = HiiString->SetString(HiiString, HiiHandle, StringId, CurrentLanguage, String, NULL);
+ if(EFI_ERROR(Status))
+ return 0;
+ } else {
+ *Languages = 0; //put null-terminator
+ if(StringId == 0)
+ Status = HiiString->NewString(HiiString, HiiHandle, &StringId, CurrentLanguage, NULL, String, NULL);
+ else
+ Status = HiiString->SetString(HiiString, HiiHandle, StringId, CurrentLanguage, String, NULL);
+ *Languages = ';'; //restore original character
+ Languages++;
+ if(EFI_ERROR(Status))
+ return 0;
+ }
+ }
+ return StringId;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EfiLibAllocateCopyPool
+//
+// Description: Allocate BootServicesData pool and use a buffer provided by
+// caller to fill it.
+//
+// Input: AllocationSize - The size to allocate
+// Buffer - Buffer that will be filled into the buffer allocated
+//
+// Output: Pointer of the buffer allocated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *
+EfiLibAllocateCopyPool (
+ IN UINTN AllocationSize,
+ IN VOID *Buffer
+ )
+{
+ VOID *Memory;
+
+ Memory = NULL;
+ pBS->AllocatePool (EfiBootServicesData, AllocationSize, &Memory);
+ if (Memory != NULL) {
+ pBS->CopyMem (Memory, Buffer, AllocationSize);
+ }
+
+ return Memory;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CleanFileTypes
+//
+// Description: Frees all allocated memory associated with the FILE_TYPE structure
+// and resets the InternalString current strings next available string token
+// to be the first dynamically added string
+//
+// Input: FILE_TYPE **FileList - The array of FILE_TYPE structures found in
+// a directory
+// UINTN *FileCount - pointer to the number of entries in the FileList
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CleanFileTypes(FILE_TYPE **FileList, UINTN *FileCount)
+{
+ UINTN i;
+ for(i = 0; i<*FileCount; i++) pBS->FreePool((*FileList)[i].Name);
+ if(FileList!=NULL && (*FileList!=NULL) && (*FileCount>0)) pBS->FreePool(*FileList);
+ if(FileList!=NULL) *FileList = NULL;
+ *FileCount = 0;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CheckDirectoryType
+//
+// Description: Checks if the EFI_FILE_INFO is a directory (and not the current directory)
+//
+// Input: EFI_FILE_INFO *File
+//
+// Output:
+//
+// Returns: BOOLEAN - TRUE - item is a directory, and not the current directory
+// FALSE - item is not a directory, or is the current directory
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckDirectoryType(EFI_FILE_INFO *File)
+{
+ BOOLEAN Status = FALSE;
+
+ if((File->Attribute & EFI_FILE_DIRECTORY) && (Wcscmp(File->FileName, L".") != 0)) {
+
+ Status = TRUE;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CheckExtension
+//
+// Description: Check is the EFI_FILE_INFO has the same extension as the
+// extension passed in the second parameter
+//
+// Input: EFI_FILE_INFO *File - The file entry whose extension should be checked
+// CHAR16 *ExtensionEfi - the extension
+//
+// Output:
+//
+// Returns: BOOLEAN - TRUE - The extension matches
+// FALSE - the extension does not match
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN CheckExtension(EFI_FILE_INFO *File, CHAR16 *ExtensionEfi)
+{
+ BOOLEAN Status = FALSE;
+ UINTN Length = Wcslen(File->FileName);
+
+ if((File->Attribute & EFI_FILE_DIRECTORY) != EFI_FILE_DIRECTORY && Length > 3)
+ if((((File->FileName[Length-1])&0xdf) == ((ExtensionEfi[2])&0xdf)) &&
+ (((File->FileName[Length-2])&0xdf) == ((ExtensionEfi[1])&0xdf)) &&
+ (((File->FileName[Length-3])&0xdf) == ((ExtensionEfi[0])&0xdf)))
+ Status = TRUE;
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: FindInsertionIndex
+//
+// Description: Finds the inded where directories items turn into file items
+//
+// Input: FILE_TYPE *List - the current array of File Type structures
+// UINTN FileCount - the count of File Type structures in the array
+//
+// Output:
+//
+// Returns: the index to insert a new item
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINTN FindInsertionIndex(FILE_TYPE *List, UINTN FileCount)
+{
+ UINTN i = 0;
+
+ if(FileCount <= 1) return 0;
+
+ for(i = 1; i < (FileCount-1); i++)
+ {
+ if(List[i-1].Type != List[i].Type)
+ break;
+ }
+
+ return i;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: AddFileTypeEntry
+//
+// Description: Creates a new entry in the FILE_TYPE array and adds the current File into
+// the array.
+//
+// Input: FILE_TYPE **List - Array of FILE_TYPE structures alread found
+// UINTN *FileCount - number of entries in the FILE_TYPE array
+// EFI_FILE_INFO *FileInfo - file info of the file that should be added
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static VOID AddFileTypeEntry(FILE_TYPE **List, UINTN *FileCount, EFI_FILE_INFO *FileInfo)
+{
+ FILE_TYPE *NewList=NULL;
+ UINTN Length;
+ UINTN Index = 0;
+
+ Length = (Wcslen(FileInfo->FileName)+3)*sizeof(CHAR16);
+
+ // Allocate space for a new list entry plus all the previous list items
+ NewList = EfiLibAllocateCopyPool(sizeof(FILE_TYPE)*(++(*FileCount)), NewList);
+ if (NewList != NULL)
+ {
+ // Clear the memory of the entire list
+ MemSet(NewList, sizeof(FILE_TYPE)*(*FileCount), 0);
+
+ // Copy the old entries (if there are any old entries to copy)
+ if(*List != NULL)
+ {
+ Index = FindInsertionIndex(*List, *FileCount);
+
+ pBS->CopyMem(NewList, *List, sizeof(FILE_TYPE)*(Index));
+ pBS->CopyMem(&(NewList[Index+1]), &((*List)[Index]), sizeof(FILE_TYPE)*((*FileCount)-Index-1));
+
+ pBS->FreePool(*List);
+ }
+
+ // Store the type of this FILE_TYPE entry (non-zero is directory)
+ NewList[Index].Type = ((FileInfo->Attribute) & EFI_FILE_DIRECTORY);
+
+ // Store the size of the file
+ NewList[Index].Size = (UINTN)FileInfo->FileSize;
+
+ // Allocate space for the string
+ NewList[Index].Name = EfiLibAllocateCopyPool(Length, NewList[Index].Name);
+ if((NewList[Index].Name) != NULL )
+ {
+ // Clear the allocated memory
+ MemSet(NewList[Index].Name, Length, 0);
+
+ // Create either a Dir string or a File string for addition to the HiiDataBase
+ if(NewList[Index].Type == EFI_FILE_DIRECTORY)
+ Swprintf_s(NewList[Index].Name, Length, L"<%s>", FileInfo->FileName);
+ else
+ Swprintf_s(NewList[Index].Name, Length, L"%s", FileInfo->FileName);
+
+ // Add the string to the HiiDataBase
+ ///NewList[Index].Token = AddStringToHii(FileInfo->FileName, &gInternalStrings); ///Just by trying using the following line
+ NewList[Index].Token = HiiAddString(gHiiHandle, NewList[Index].Name );
+
+ // Clear the memory and create the string for the File Structure
+ MemSet(NewList[Index].Name, Length, 0);
+ Swprintf_s(NewList[Index].Name, Length, L"%s", FileInfo->FileName);
+ }
+ *List = NewList;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: CreateFileList
+//
+// Description: Parse all the files in the current directory and add valid files to the
+// FILE_TYPE list and update the filecount
+//
+// Input: EFI_FILE_PROTOCOL *FileProtocol - the current direcotry to parse
+//
+// Output: FILE_TYPE **FileList - pointer in which to return the array of FileType items
+// UINTN *FileCount - the count of filetype items discovered
+//
+// Returns: EFI_STATUS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS CreateFileList(EFI_FILE_PROTOCOL *FileProtocol, FILE_TYPE **FileList, UINTN *FileCount)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ UINTN BufferSize = 1;
+ EFI_FILE_INFO *File = NULL;
+
+// CHAR16 ExtensionEfi[] = L"EFI";
+
+ // Continue parsing the directory until we no longer read valid files
+ while(BufferSize != 0 && !EFI_ERROR(Status))
+ {
+ BufferSize = 0;
+ Status = FileProtocol->Read(FileProtocol, &BufferSize, NULL);
+
+ if(!EFI_ERROR(Status)) break;
+
+ if(Status == EFI_BUFFER_TOO_SMALL)
+ {
+ File = EfiLibAllocateCopyPool(BufferSize, File);
+ if(File != NULL) {
+ MemSet(File, BufferSize, 0);
+ }
+ }
+
+ Status = FileProtocol->Read(FileProtocol, &BufferSize, File);
+
+ // Check if a valid file was read
+ if(!EFI_ERROR(Status) && BufferSize != 0)
+ {
+ // check if the file read was a directory or a ".efi" extension
+// if(CheckDirectoryType(File) || CheckExtension(File, ExtensionEfi))
+// {
+ // the file was valid, add it to the file list
+ AddFileTypeEntry(FileList, FileCount, File);
+// }
+ }
+
+ // free the space allocated for readin the file info structure
+ pBS->FreePool(File);
+
+ // set the pointer to null to prevent the chance of memory corruption
+ File = NULL;
+ }
+
+ if(*FileCount == 0) Status = EFI_NOT_FOUND;
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: DisplayFileListMenu
+//
+// Description: Display a menu of the FILE_TYPE items and return the selected item
+// in the Selection
+//
+// Input: FILE_TYPE *FileList - List of FILE_TYPE items to display in the menu
+// UINTN FileCount - the number of FILE_TYPE items in the list
+//
+// Output: UINT16 *Selection - The index of the selected FILE_TYPE item
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+static EFI_STATUS DisplayFileListMenu(FILE_TYPE *FileList, UINTN FileCount, UINT16 *Selection)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ UINT16 i = 0;
+
+ POSTMENU_TEMPLATE *List = NULL;
+
+ // Check there are any files to display
+ if(FileCount != 0 && FileList != NULL)
+ {
+ // allocate space for the POSTMENU_TEMPLATE items
+ List = EfiLibAllocateCopyPool(sizeof(POSTMENU_TEMPLATE)*FileCount, List);
+ if(List != NULL)
+ {
+ // Clear the memory allocated
+ MemSet(List, sizeof(POSTMENU_TEMPLATE)*FileCount, 0);
+
+ // Add the STRING_REF tokens to the POSTMENU_TEMPLATE structures
+ for(i = 0; i < FileCount; i++)
+ List[i].ItemToken = FileList[i].Token;
+ }
+
+ // Call post manager to display the menu
+ Status = mPostMgr->DisplayPostMenu(gHiiHandle,
+ STRING_TOKEN(STR_FILE_SELECT), // Change this
+ 0,
+ List,
+ (UINT16)FileCount,
+ Selection);
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: UpdateFilePathString
+//
+// Description: To create the File Path string based on the file selected.
+//
+// Input: CHAR16 *FilePath - Buffer to fill with the file path
+// CHAR16 * CurFile - current file selected
+// UINT16 idx - Index of the file in the current directory
+//
+// Output: CHAR16 *FilePath - Updated File Path
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID UpdateFilePathString(CHAR16 *FilePath, CHAR16 * CurFile, UINT16 idx)
+{
+ UINTN Length=0;
+
+ if(Wcslen(FilePath))
+ {
+ if( idx==0 ) {
+ if(Wcscmp(CurFile,L"..")) {
+ EfiStrCat(FilePath,L"\\");
+ EfiStrCat(FilePath,CurFile);
+ }
+ else {
+
+ for ( Length = Wcslen(FilePath); ( Length!= 0 ) && (FilePath[Length-1] != L'\\') ; Length -- );
+ if ( Length )
+ FilePath[Length-1] = L'\0';
+ else
+ FilePath[Length] = L'\0';
+ }
+ }
+ else {
+ EfiStrCat(FilePath,L"\\");
+ EfiStrCat(FilePath,CurFile);
+ }
+ }
+ else {
+ Wcscpy(FilePath,CurFile);
+ }
+}
+
+EFI_STATUS FileBrowserLaunchFilePath(IN EFI_HANDLE *FileHandle, OUT CHAR16 **outFilePath, OUT UINT8 **outFileBuf,OUT UINTN *size );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: FileBrowserLaunchFileSystem
+//
+// Description: To select the File System for the new boot option with the help of file browser.
+//
+// Input: BOOLEAN bSelectFile - TRUE - Select FSHandle and File path
+// FALSE - Select only FSHandle
+//
+// Output: Selected File System Index
+//
+// Returns: EFI_STATUS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FileBrowserLaunchFileSystem(BOOLEAN bSelectFile, OUT EFI_HANDLE **outFsHandle,OUT CHAR16 **outFilePath, OUT UINT8 **outFileBuf,OUT UINTN *size )
+{
+ EFI_STATUS Status;
+ UINTN Count = 0;
+ UINT16 i = 0;
+ EFI_HANDLE *gSmplFileSysHndlBuf = NULL;
+ UINT16 gSelIdx=0;
+
+ EFI_DEVICE_PATH_PROTOCOL *Dp = NULL;
+
+ POSTMENU_TEMPLATE *PossibleFileSystems = NULL;
+
+ if(mPostMgr == NULL)
+ return EFI_UNSUPPORTED;
+
+ // To launch the files from the selected file system
+ if(!size)
+ return EFI_INVALID_PARAMETER;
+
+ // Locate all the simple file system devices in the system
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gSimpleFileSystemGuid, NULL, &Count, &gSmplFileSysHndlBuf);
+ if(!EFI_ERROR(Status))
+ {
+ // allocate space to display all the simple file system devices
+ PossibleFileSystems = EfiLibAllocateCopyPool(sizeof(POSTMENU_TEMPLATE)*Count,PossibleFileSystems);
+ if(PossibleFileSystems != NULL)
+ {
+ // clear the allocated space
+ MemSet(PossibleFileSystems, sizeof(POSTMENU_TEMPLATE)*Count, 0);
+ for(i = 0; i < Count; i++)
+ {
+ // get the device path for each handle with a simple file system
+ Status = pBS->HandleProtocol(gSmplFileSysHndlBuf[i], &gEfiDevicePathProtocolGuid, &Dp);
+ if(!EFI_ERROR(Status))
+ {
+ CHAR16 *Name;
+ CHAR8 *Name8;
+ // Get the name of the driver installed on the handle
+ // GetControllerName(gHandleBuffer[i],&Name);
+
+ Name8 = NULL;
+ Status = DevicePathToStr(Dp, &Name8 );
+ Name = StrDup8to16(Name8);
+
+ // Add the name to the Hii Database
+ ///PossibleFileSystems[i].ItemToken = AddStringToHii(Name);
+ PossibleFileSystems[i].ItemToken = HiiAddString(gHiiHandle, Name );
+
+ PossibleFileSystems[i].Attribute = AMI_POSTMENU_ATTRIB_FOCUS;
+ pBS->FreePool(Name);
+ pBS->FreePool(Name8);
+ }
+ else
+ {
+ PossibleFileSystems[i].ItemToken = 0;
+ PossibleFileSystems[i].Attribute = AMI_POSTMENU_ATTRIB_HIDDEN;
+ }
+ }
+ // Reset the item selected to be the first item
+ gSelIdx = 0;
+
+ // Display the post menu and wait for user input
+ Status = mPostMgr->DisplayPostMenu(gHiiHandle,
+ STRING_TOKEN(STR_FILE_SYSTEM),
+ 0,
+ PossibleFileSystems,
+ (UINT16)Count,
+ &gSelIdx);
+
+
+ // A valid item was selected by the user
+ if(!EFI_ERROR(Status))
+ {
+ gValidOption = TRUE;
+ }
+ }
+ }
+
+ else {
+ GetHiiString(gHiiHandle, STRING_TOKEN(STR_NO_VALID_FS_TITLE), sizeof(StrTitle) ,StrTitle);
+ GetHiiString(gHiiHandle, STRING_TOKEN(STR_NO_VALID_FS), sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, MSGBOX_TYPE_OK, NULL );//EIP:41615 To display Warning message when there is no file system connected.
+ }
+
+ // Free the allocated menu list space
+ if(PossibleFileSystems != NULL)
+ pBS->FreePool(PossibleFileSystems);
+
+ *outFsHandle = gSmplFileSysHndlBuf[gSelIdx];
+
+ *size = 0;
+ if(bSelectFile)
+ Status = FileBrowserLaunchFilePath(*outFsHandle,outFilePath, outFileBuf,size );//EIP:41615 Returning the status of Filebrowselaunchfilepath
+
+ if(gSmplFileSysHndlBuf != NULL)
+ pBS->FreePool(gSmplFileSysHndlBuf);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: FileBrowserLaunchFilePath
+//
+// Description: To select the Boot file for the new boot option with the help of file browser.
+//
+// Input: VOID
+//
+// Output: File Path string
+//
+// Returns: EFI_STATUS
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS FileBrowserLaunchFilePath(IN EFI_HANDLE *FileHandle,OUT CHAR16 **outFilePath, OUT UINT8 **outFileBuf,OUT UINTN *size )
+{
+ EFI_STATUS Status;
+
+ EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFs = NULL;
+ EFI_FILE_PROTOCOL *NewFs = NULL;
+ FILE_TYPE *FileList = NULL;
+ UINTN FileCount = 0;
+ UINT16 i = 0;
+ CHAR16 FilePath[120];
+ EFI_FILE_PROTOCOL *gFs = NULL;
+
+ // Attempt to locate the post manager protocol
+ if(mPostMgr == NULL)
+ return EFI_UNSUPPORTED;
+
+ if( gValidOption == TRUE )
+ {
+ gValidOption = FALSE;
+
+ // Get the simple file system protocol
+ Status = pBS->HandleProtocol(FileHandle, &gSimpleFileSystemGuid, &SimpleFs);
+ if(!EFI_ERROR(Status))
+ {
+ // And open it and return the efi file protocol
+ Status = SimpleFs->OpenVolume(SimpleFs, &gFs);
+ }
+ }
+ else {
+ return EFI_UNSUPPORTED;
+ }
+
+ // clean up the file list and strings used in getting the file system
+ CleanFileTypes(&FileList, &FileCount);
+
+ while(!EFI_ERROR(Status) && gFs != NULL)
+ {
+ i = 0;
+ MemSet(FilePath, sizeof(FilePath), 0);
+
+ // Create a list of the files in the current directory
+ Status = CreateFileList(gFs, &FileList, &FileCount);
+ if(!EFI_ERROR(Status))
+ {
+ // Display the list in a menu and allow the user to select
+ Status = DisplayFileListMenu(FileList, FileCount, &i);
+ if(!EFI_ERROR(Status))
+ {
+ // The user selected something, attempt to open it
+ Status = gFs->Open( gFs,
+ &NewFs,
+ FileList[i].Name,
+ EFI_FILE_MODE_READ,
+ 0);
+
+ // close the old file system protocol and set it to null
+ gFs->Close(gFs);
+ gFs = NULL;
+
+ // Create the File Path based on the file selected
+ UpdateFilePathString(FilePath, FileList[i].Name, i);
+
+ // the newly selected item was opened correctly
+ if(!EFI_ERROR(Status))
+ {
+ // check what type was opened
+ if(FileList[i].Type != EFI_FILE_DIRECTORY)
+ {
+
+
+ Status = pBS->AllocatePool(EfiBootServicesData,FileList[i].Size, (VOID**)outFileBuf);
+ if(!EFI_ERROR(Status))
+ {
+ *size = FileList[i].Size;
+ // The user selected something, attempt to open it
+ Status = NewFs->Read( NewFs, size, *outFileBuf); }
+
+ // the file was read, close the file system protocol and set it to null
+ NewFs->Close(NewFs);
+ NewFs = NULL;
+ //Swprintf_s (FileName, 50, L"%s", FileList[i].Name);
+ //ShowPostMsgBox( L"Selected Boot File Name", FileName, MSGBOX_TYPE_OK, &SelOpt );
+ }
+ gFs = NewFs;
+ }
+ }
+ }
+
+ if(FileCount <= 0) {
+ GetHiiString(gHiiHandle, STRING_TOKEN(STR_NO_VALID_FILE_TITLE),sizeof(StrTitle), StrTitle);
+ GetHiiString(gHiiHandle, STRING_TOKEN(STR_NO_VALID_FILE),sizeof(StrMessage),StrMessage);
+ mPostMgr->DisplayMsgBox( StrTitle, StrMessage, MSGBOX_TYPE_OK, NULL );//EIP:41615 Warning message to show unavailability of the selected file
+ }
+
+ // clean the strings that were used and free allocated space
+ CleanFileTypes(&FileList, &FileCount);
+
+ if(Status == EFI_ABORTED) {
+ return Status;//EIP:41615 Returning the status if its aborted.
+ }
+ }
+ // Set the File path for the new boot option added.
+ Status = pBS->AllocatePool(EfiBootServicesData, ((Wcslen(FilePath)+1)*sizeof(CHAR16)), outFilePath);
+ Wcscpy (*outFilePath, FilePath);
+
+ return Status;
+}
+//#endif //#if defined(CORE_COMBINED_VERSION) && CORE_COMBINED_VERSION >=0x4028a (4.6.5.0)
+#endif // #ifdef SETUP_COMPILE
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SecureMod_Init
+//
+// Description: Entry point of Secure Module DXE driver
+//
+// Input: EFI_HANDLE ImageHandle,
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SecureBootMod_Init (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ UINTN DataSize;
+ UINT8 Byte;
+ UINT32 Attributes;
+ VOID *pHobList;
+ static EFI_GUID gHobListGuid = HOB_LIST_GUID;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Byte = 0;
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE;
+ //
+ // Look up for Secure Boot policy in "SecureBootSetup" variable. If not defined - create one with SDL defaults
+ //
+ DataSize = sizeof(SECURE_BOOT_SETUP_VAR);
+ Status = pRS->GetVariable (AMI_SECURE_BOOT_SETUP_VAR, &guidSecurity,&Attributes,&DataSize,&SecureBootSetup);
+//TRACE((TRACE_ALWAYS,"SecureBootSetup (%r) Attrib=%x, SecBoot-%d, SecMode-%d,DefaultProvision-%d\n", Status, Attributes, SecureBootSetup.SecureBootSupport, SecureBootSetup.SecureBootMode,SecureBootSetup.DefaultKeyProvision));
+ // Default variable is created with RT attribute which violates
+ // Intel's Secure Boot technical advisory #527669 and MS Windows Secure Boot requirements
+ if((!EFI_ERROR(Status) &&
+ (Attributes & EFI_VARIABLE_RUNTIME_ACCESS)==EFI_VARIABLE_RUNTIME_ACCESS)
+ || Status == EFI_NOT_FOUND) // Var is not yet initialized
+ {
+ // Clear RT attributes if set for "SecureBootSetup"
+ pRS->SetVariable (AMI_SECURE_BOOT_SETUP_VAR, &guidSecurity, 0, 0, NULL);
+ pRS->SetVariable (AMI_SECURE_BOOT_SETUP_VAR, &guidSecurity,(Attributes & ~EFI_VARIABLE_RUNTIME_ACCESS), DataSize, &SecureBootSetup);
+ }
+
+ DataSize = 1;
+ Byte = USER_MODE;
+ // Provision of defaults only if in Setup mode
+ Status = pRS->GetVariable(EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, NULL, &DataSize, &Byte);
+ if(SecureBootSetup.DefaultKeyProvision == 1 &&
+ !EFI_ERROR(Status) && Byte == SETUP_MODE)
+ {
+ Status = InstallSecureVariables(SET_NV_DEFAULT_KEYS);
+ // Status of last key to be installed - PK
+ TRACE((TRACE_ALWAYS,"Provision Sec Vars(%r)\n", Status));
+ // Issue reset after key provision only during normal boot with system is in User Mode and SecureBootSupport flag is enabled
+ if(!EFI_ERROR(Status) && SecureBootSetup.SecureBootSupport)
+ {
+ Status = pRS->GetVariable(EFI_SETUP_MODE_NAME, &gEfiGlobalVariableGuid, NULL, &DataSize, &Byte);
+ if(!EFI_ERROR(Status) && Byte == USER_MODE)
+ //Get Boot Mode
+ pHobList = GetEfiConfigurationTable(SystemTable, &gHobListGuid);
+ if (pHobList)
+ {
+ if (((EFI_HOB_HANDOFF_INFO_TABLE*)pHobList)->BootMode!=BOOT_IN_RECOVERY_MODE &&
+ ((EFI_HOB_HANDOFF_INFO_TABLE*)pHobList)->BootMode!=BOOT_ON_FLASH_UPDATE
+ )
+ pRS->ResetSystem(EfiResetCold, Status, 0, NULL);
+ }
+ }
+ }
+#if ALWAYS_INSTALL_DEFAULT_RT_KEYS == 0
+ if(Byte == SETUP_MODE)
+#endif
+ InstallSecureVariables(SET_RT_DEFAULT_KEYS);
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecureBootMod.chm b/Core/EM/SecurityPkg/SecureBootMod.chm
new file mode 100644
index 0000000..e17830d
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.chm
Binary files differ
diff --git a/Core/EM/SecurityPkg/SecureBootMod.cif b/Core/EM/SecurityPkg/SecureBootMod.cif
new file mode 100644
index 0000000..f51d310
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "Secure Boot Pkg"
+ category = eModule
+ LocalRoot = "Core\EM\SecurityPkg\"
+ RefName = "SecureBootMod"
+[files]
+"SecureBootMod.chm"
+"SecureBootMod.sdl"
+"SecureBootMod.uni"
+"SecureBootMod.mak"
+"SecureBootMod.dxs"
+"SecureBootMod.sd"
+"SecureBootMod.c"
+"SecureBootMod.h"
+[parts]
+"AuthVariable"
+"ImageVerificationLib"
+"SecVariables"
+[dependon]
+"CryptoPkg"
+<endComponent>
diff --git a/Core/EM/SecurityPkg/SecureBootMod.dxs b/Core/EM/SecurityPkg/SecureBootMod.dxs
new file mode 100644
index 0000000..a846460
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.dxs
@@ -0,0 +1,51 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.dxs 1 8/18/11 4:48p Alexp $
+//
+// $Revision: 1 $
+//
+// $Date: 8/18/11 4:48p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.dxs $
+//
+// 1 8/18/11 4:48p Alexp
+//
+// 1 5/10/11 10:01a Alexp
+//
+// 1 3/10/11 4:58p Alexp
+//
+// 1 2/24/11 6:57p Alexp
+//
+//**********************************************************************
+#include <Protocol/AmiDigitalSignature.h>
+
+DEPENDENCY_START
+ AMI_DIGITAL_SIGNATURE_PROTOCOL_GUID
+DEPENDENCY_END
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/SecurityPkg/SecureBootMod.h b/Core/EM/SecurityPkg/SecureBootMod.h
new file mode 100644
index 0000000..0ec0642
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.h
@@ -0,0 +1,116 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.h 6 8/15/13 10:10a Alexp $
+//
+// $Revision: 6 $
+//
+// $Date: 8/15/13 10:10a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.h $
+//
+// 6 8/15/13 10:10a Alexp
+// supported Signatures include 3 more: EFI_CERT_X509_SHAXXX_GUID
+//
+// 5 7/26/13 3:30p Alexp
+// add dbt related defines
+//
+// 4 5/17/13 6:02p Alexp
+// add placeholder defines for "dbt"
+//
+// 3 12/06/12 7:32p Alexp
+// define AMI_SECURE_VAR_PRESENT_VAR
+//
+// 2 11/26/12 10:43a Alexp
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SecureBootMod.h
+//
+// Description: Common Secure Boot definitions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _SECURE_BOOT_MODE_H_
+#define _SECURE_BOOT_MODE_H_
+
+#define AMI_SECURE_BOOT_SETUP_VAR L"SecureBootSetup"
+#define AMI_SECURE_VAR_PRESENT_VAR L"SecureVarPresent"
+
+#pragma pack(1)
+typedef struct{
+ UINT8 SecureBootSupport;
+ UINT8 SecureBootMode;
+ UINT8 DefaultKeyProvision;
+ UINT8 Load_from_FV;
+ UINT8 Load_from_OROM;
+ UINT8 Load_from_REMOVABLE_MEDIA;
+ UINT8 Load_from_FIXED_MEDIA;
+} SECURE_BOOT_SETUP_VAR;
+
+typedef struct{
+ UINT8 Value;
+} SETUP_MODE_VAR;
+
+typedef struct{
+ UINT8 Value;
+} SECURE_BOOT_VAR;
+
+typedef struct{
+ UINT8 DBX;
+ UINT8 DBT;
+ UINT8 DB;
+ UINT8 KEK;
+ UINT8 PK;
+} SECURE_VAR_INSTALL_VAR;
+
+#pragma pack()
+
+// EFI_IMAGE_SECURITY_DATABASE_DEFAULT must be defined in ImageAuthentication.h (Core 4.6.5.4 +)
+// UEFI ECR874: Install Factory defaults as Read-only volatile variables for key distribution.
+#ifndef EFI_IMAGE_SECURITY_DATABASE_DEFAULT
+#define EFI_IMAGE_SECURITY_DATABASE_DEFAULT L"dbDefault"
+#define EFI_IMAGE_SECURITY_DATABASE1_DEFAULT L"dbxDefault"
+#define EFI_PLATFORM_KEY_NAME_DEFAULT L"PKDefault"
+#define EFI_KEY_EXCHANGE_KEY_NAME_DEFAULT L"KEKDefault"
+#define EFI_IMAGE_SECURITY_DATABASE2_DEFAULT L"dbtDefault"
+#endif
+#ifndef EFI_IMAGE_SECURITY_DATABASE2
+#define EFI_IMAGE_SECURITY_DATABASE2 L"dbt"
+#define EFI_IMAGE_SECURITY_DATABASE2_DEFAULT L"dbtDefault"
+#endif
+
+#define SIGSUPPORT_NUM 8
+#define SIGSUPPORT_LIST EFI_CERT_X509_SHA256_GUID, EFI_CERT_X509_SHA384_GUID, EFI_CERT_X509_SHA512_GUID, EFI_CERT_SHA256_GUID, EFI_CERT_X509, EFI_CERT_RSA2048_GUID, EFI_CERT_RSA2048_SHA256_GUID, EFI_CERT_RSA2048_SHA1_GUID
+
+#endif //_SECURE_BOOT_MODE_H_
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecureBootMod.mak b/Core/EM/SecurityPkg/SecureBootMod.mak
new file mode 100644
index 0000000..2d30872
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.mak
@@ -0,0 +1,153 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.mak 14 11/19/12 4:40p Alexp $
+#
+# $Revision: 14 $
+#
+# $Date: 11/19/12 4:40p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.mak $
+#
+# 14 11/19/12 4:40p Alexp
+# Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+# across flash updates.
+# Move all secure boot Setup settings to a separate varsore variable.
+# Preserve var across re-flash
+#
+# 13 8/23/12 5:40p Alexp
+# Added SecureBootMod.c file to the list of String Consumers
+#
+# 12 8/15/12 4:48p Alexp
+# 1. Modify Secure Boot page controls. Hide all controls under new
+# sub-page
+# 2. Refrash Secure Boot Setup screens upon user load Defaults/Previous
+# values
+# 3.
+#
+# 11 6/05/12 10:30a Alexp
+# moved build rules for default SecureVariables to SecureVariable eModule
+#
+# 10 6/01/12 4:13p Alexp
+# cleaned up Include list
+#
+# 8 3/09/12 3:29p Alexp
+# Implementation to PRESERVE_SECURE_VARIABLES on Flash Update is moved
+# here from SecSmiFlash component
+#
+# 7 8/25/11 8:33a Alexp
+# add back .dxs dependency on AmiDigitalSig protocol. Needed if Secure
+# Variable provisioning is enabled at Driver's entry point
+#
+# 6 8/24/11 6:23p Alexp
+# link SecureBootMod.obj to SetupBin.
+#
+# 5 8/22/11 5:19p Alexp
+# restored CallBack notification method to set Manufacturing defaults
+# from TSE SetupPage
+#
+# 4 8/18/11 4:50p Alexp
+# 1. removed callback events on Security Page updates
+# 2. Add DEPEX on AmiDigitalSig protocol
+#
+# 3 7/18/11 9:58a Alexp
+# make Variable ffs files compressed
+#
+# 2 6/30/11 4:25p Alexp
+# add dependency on SecureVariable module with OEM defined default
+# variables for PK-KEK-db-dbx
+# if present will add setup control to provision default Secure Variables
+#
+# 1 6/30/11 3:47p Alexp
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: SecureBootMod.mak
+#
+# Description:
+#
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all: SecureBootModule
+
+SecureBootModule : $(BUILD_DIR)\SecureBootMod.mak SecureBootModDxe
+
+$(BUILD_DIR)\SecureBootMod.mak : $(SecureBoot_DIR)\SecureBootMod.cif $(BUILD_RULES)
+ $(CIF2MAK) $(SecureBoot_DIR)\SecureBootMod.cif $(CIF2MAK_DEFAULTS)
+
+SecureBootModDxe : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecureBootMod.mak all\
+ NAME=SecureBootMod\
+ "MY_INCLUDES=/I$(SecureBoot_DIR)"\
+ MAKEFILE=$(BUILD_DIR)\SecureBootMod.mak \
+ GUID=A95C1D60-CB9F-4BD8-A030-3F1C4A185156 \
+ ENTRY_POINT=SecureBootMod_Init\
+ "EXT_HEADERS=$(BUILD_DIR)\SetupStrTokens.h $(BUILD_DIR)\AUTOID.h"\
+ DEPEX1=$(SecureBoot_DIR)\SecureBootMod.DXS DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ TYPE=BS_DRIVER COMPRESS=1
+
+#---------------------------------------------------------------------------
+# Create Setup Screen(s)
+#---------------------------------------------------------------------------
+SetupSdbs : SecureBootModSDB
+
+SecureBootModSDB : $(BUILD_DIR)\SecureBootMod.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecureBootMod.mak all\
+ TYPE=SDB NAME=SecureBootMod\
+ "MY_INCLUDES=/I$(SecureBoot_DIR)"\
+ "STRING_CONSUMERS=$(SecureBoot_DIR)\SecureBootMod.sd $(SecureBoot_DIR)\SecureBootMod.c"
+
+#---------------------------------------------------------------------------
+# Link Callback Lib to Setup
+#---------------------------------------------------------------------------
+SetupBin : $(BUILD_DIR)\$(Setup_DIR)\SecureBootMod.obj
+
+$(BUILD_DIR)\$(Setup_DIR)\SecureBootMod.obj : $(SecureBoot_DIR)\SecureBootMod.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /I$(SecureBoot_DIR) /DSETUP_COMPILE=1 $(SecureBoot_DIR)\SecureBootMod.c /Fo$@
+
+AMITSEBin : $(BUILD_DIR)\$(TSEBIN_DIR)\SecureBootMod.obj
+$(BUILD_DIR)\$(TSEBIN_DIR)\SecureBootMod.obj : $(SecureBoot_DIR)\SecureBootMod.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /DTSEBIN_COMPILE=1 /I$(SecureBoot_DIR) /I $(TSEBIN_DIR)\Inc /I $(TSEBIN_DIR) /I$(CORE_DIR) $(SecureBoot_DIR)\SecureBootMod.c /Fo$@
+
+#---------------------------------------------------------------------------
+# Link SMIFlash hooks to SmiFlash module
+#---------------------------------------------------------------------------
+!IF "$(PRESERVE_SECURE_VARIABLES)" == "1"
+SMIFlashBin : $(BUILD_DIR)\$(SMI_FLASH_DIR)\SecureBootMod.obj
+
+$(BUILD_DIR)\$(SMI_FLASH_DIR)\SecureBootMod.obj: $(SecureBoot_DIR)\SecureBootMod.c
+ $(CC) $(CFLAGS) /I$(SecureBoot_DIR) /I$(CORE_DIR) /DSMIFLASH_COMPILE=1 /DSMM_COMPILE=1 /Fo$@ $**
+!ENDIF
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2012, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SecurityPkg/SecureBootMod.sd b/Core/EM/SecurityPkg/SecureBootMod.sd
new file mode 100644
index 0000000..0584d69
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.sd
@@ -0,0 +1,685 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.sd 51 3/09/15 5:05p Alexp $
+//
+// $Revision: 51 $
+//
+// $Date: 3/09/15 5:05p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/SecureBoot_WIN8/SecureBootMod.sd $
+//
+// 51 3/09/15 5:05p Alexp
+// 1. Implement User prompt to install Secure Boot key defaults
+// while switching of Secure Boot mode from Custom to Standard
+// (per Windows8+ Hardware Certification requirements).
+// Add callback on SECURE_BOOT_MODE_CHANGE_KEY
+// 2. EIP#200639: When the token DEFAULT_PROVISION_SECURE_VARS enable,
+// the secure boot status is Not Active when first enter setup.
+// [Resolution] Issue SystemReset after initial Secure Boot provisioning
+// 3. EIP#201422: set SecVariables_SUPPORT = 0, code will build fail
+//
+// 50 4/07/14 2:47p Alexp
+// Add Hii event SECURE_BOOT_MENU_REFRESH on entering of Secure Boot menu
+// The callback to this event refreshes the state of internal Secure Boot
+// setup flags.
+// UpdateSecureVariableBrowserInfo()
+//
+// 49 12/05/13 9:05a Alexp
+// don't hide Secure Boot menu if in User mode. Instead - keep all
+// controls greyed out
+//
+// 48 8/15/13 10:08a Alexp
+// add DBT controls
+//
+// 47 7/26/13 3:34p Alexp
+// 1. Add dbt dialogs on Key Management page
+// 2. Image Execution policies options are enabled according to defaults
+// in SDL
+//
+
+// 46 6/22/13 12:22p Alexp
+// Made Image Execution page depend on ENABLE_IMAGE_EXEC_POLICY_OVERRIDE
+//
+// 45 5/17/13 5:50p Alexp
+// add separator
+//
+// 44 3/22/13 5:00p Alexp
+// Put Key Management sub-menu in front of Image Executin Policy.
+//
+// 43 3/21/13 1:16p Alexp
+// Update help strings
+//
+// 42 2/08/13 4:52p Alexp
+// EIP#114350:Need the Token for SecureBootMode default value
+//
+// 41 12/06/12 7:32p Alexp
+// Update Key Management page layout
+//
+// 40 12/04/12 11:23a Alexp
+// Revert the change in #39- do not introduce SETUP_DATA.SecureBootSupport
+// Mudules that had reference to this field must change to use generic
+// UEFI SecureBoot variable
+//
+// 39 11/29/12 11:10a Alexp
+// Include dummy variable to the SetupData structure in case it's
+// referenced by external modules (e.g. old labels of TCG)
+// SETUP_DATA.SecureBootSupport;
+//
+// 38 11/19/12 4:40p Alexp
+// Fix for Win8 SecureBoot logo requirement: restore Secure Boot state
+// across flash updates.
+// Move all secure boot Setup settings to a separate varsore variable.
+// Preserve var across re-flash
+//
+// 37 10/22/12 3:53p Alexp
+// Fix interactive menus for Set/Append Key operations
+//
+// 36 9/18/12 3:51p Alexp
+//
+// 35 9/10/12 2:06p Alexp
+// Link SDL defined defaults for Image Exec Policy settings
+//
+// 34 9/07/12 5:12p Alexp
+// Remove dependency on newer Cores:CORE_COMBINED_VERSION >= 0x4028a
+// Win8 compliant BIOS must have upgraded Core components and Tse
+//
+// 33 9/04/12 12:40p Alexp
+// Change dependency on from Efi Generic Variable: SetupMode to custom
+// Variable: SECURE_VAR_INSTALL
+// Needed to display proper Goto Control symbol in TSE
+//
+// 32 8/30/12 2:05p Alexp
+// Add warning label and steps to overcome Vfr coompatibility issues on
+// older Cores with EfiSpec version less then 2.1
+//
+// 31 8/29/12 5:24p Alexp
+// Fix Display issues with Core 4.6.5.4+
+// Changed oneof parameters in SecureBootSupport.
+//
+// 30 8/28/12 3:46p Alexp
+//
+// 29 8/27/12 6:51p Alexp
+// DEFAULT_SECURE_BOOT_ENABLE changes behavior of SecureBoot Option.
+// If set to 0 - Secure Boot will be kept disabled if in Setup Mode
+//
+// 28 8/27/12 10:46a Alexp
+// SecureBoot Supprt value made dependent on System State = User Mode and
+// Default Provisioning.
+// User should not be able to Enable Secure Boot if Keys are not
+// provisioned.
+//
+// 27 8/23/12 5:43p Alexp
+// Add user selection for supported file formats in Append SecureBoot
+// operations
+//
+// 26 8/15/12 4:48p Alexp
+// 1. Modify Secure Boot page controls. Hide all controls under new
+// sub-page
+// 2. Refrash Secure Boot Setup screens upon user load Defaults/Previous
+// values
+// 3.
+//
+// 25 7/30/12 10:59a Alexp
+//
+// 24 7/27/12 2:00p Alexp
+// Execution Policy page. Made "User Query" visible only if System is in
+// Setup mode
+//
+//
+// 22 7/25/12 6:34p Alexp
+// Update Secure Boot page layout
+// 1. Security Page
+// 1.3 Replaced standalone SecureBootMode Option to an added value in
+// Secure Boot list (on/off/custom)
+// 1.4 Display SecureBootMode Standard/Custom Status
+// 2. Key Management Page
+// 2.1 Add Append Certificate Options along with Append from File
+// New functions append new Certificates from different types of
+// input Certs (x509, RSA2048 & SHA256) and Signature List blobs
+// 2.2 Use single Save to files option for all Sec Variables
+// 2.3 Set Variable Option gets a Key from a File Browser or a Factory
+// Default storage.
+//
+// 21 5/15/12 9:43a Alexp
+// EIP:89280. When secure boot enable with secure flash disable, in
+// Security page of setup menu same items will exist twice
+// FIX: modify rules to suppress lines for installed Variables
+//
+// 20 4/27/12 3:52p Alexp
+//
+// 19 4/23/12 5:25p Alexp
+// Update Key Management Setup page.
+// -Added "Default Key Provisioning" switch
+// -reuse help strings for custom Secure Boot key options
+//
+// 18 4/10/12 6:52p Alexp
+// change control order
+//
+// 17 3/22/12 10:51a Alexp
+// change Secure Boot default to Enabled
+//
+// 16 3/09/12 3:57p Alexp
+// [EIP#82334]-TSE Text Verification test failed
+// -fixed misspelled messages
+// - Win8 Logo requirement: add new Setup switch- Secure Boot mode to
+// toggle between Standard and Custom
+// -changed Security page layout
+//
+// 14 2/15/12 1:57p Alexp
+// Disable "Key Delete" controls if DEFAULT_PROVISION_SECURE_VARS is set
+//
+// 13 2/14/12 7:34p Alexp
+// disable unused controlls when DEFAULT_PROVISION_SECURE_VARS is set
+//
+// 12 11/10/11 2:16p Alexp
+// exclude all HII callback forms based on "EFI_SPECIFICATION_VERSION"
+// ">=" "0x2000A
+//
+// 11 11/08/11 5:58p Alexp
+//
+// 10 11/07/11 6:26p Alexp
+// Add Key Management controls to add/get/append and delete Secure
+// Variables from the Setup page
+//
+// 9 11/03/11 6:30p Alexp
+// SecureBootMod.c(sdl, .sd, .uni) Change the appearance of Secure Boot
+// items on Setup Security page. Added information on currently installed
+// Secure Variables.
+//
+// 8 8/22/11 5:19p Alexp
+// restored CallBack notification method to set Manufacturing defaults
+// from TSE SetupPage
+//
+// 7 8/18/11 4:51p Alexp
+// replaced dynamic removed callback events to static Setup Option
+//
+// 6 8/05/11 3:15p Alexp
+// re-arranged setup page
+//
+// 5 7/18/11 9:57a Alexp
+// rearranged Security Setup page
+//
+// 4 7/01/11 3:35p Alexp
+// Made changes to comply with older VfrCompilers (pre 4.6.5.)
+//
+// 3 6/30/11 4:25p Alexp
+// add dependency on SecureVariable module with OEM defined default
+// variables for PK-KEK-db-dbx
+// if present will add setup control to provision default Secure Variables
+//
+// 2 6/30/11 3:56p Alexp
+// removed comments
+//
+// 1 6/30/11 3:47p Alexp
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: SecureBootMod.sd
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifdef SETUP_DATA_DEFINITION
+/***********************************************************/
+/* Put NVRAM data definitions here.
+/* For example: UINT8 Data1;
+/* These definitions will be converted by the build process
+/* to a definitions of SETUP_DATA fields.
+/***********************************************************/
+#endif
+
+#ifdef SECURITY_FORM_SET
+
+#ifdef FORM_SET_TYPEDEF
+ #include "SecureBootMod.h"
+#endif
+ #ifdef FORM_SET_VARSTORE
+ varstore SECURE_BOOT_SETUP_VAR,
+ key = AUTO_ID(SECURE_BOOT_SETUP_ID),
+ name = SecureBootSetup,
+ guid = SECURITY_FORM_SET_GUID;
+ varstore SECURE_VAR_INSTALL_VAR,
+ key = AUTO_ID(SECURE_VAR_INSTALL_ID),
+ name = SecureVarPresent,
+ guid = SECURITY_FORM_SET_GUID;
+ varstore SETUP_MODE_VAR,
+ key = AUTO_ID(SETUP_MODE_ID),
+ name = SetupMode,
+ guid = {0x8BE4DF61,0x93CA,0x11d2,0xAA,0xD,0x0,0xE0,0x98,0x03,0x2B,0x8C};
+ varstore SECURE_BOOT_VAR,
+ key = AUTO_ID(SECURE_BOOT_ID),
+ name = SecureBoot,
+ guid = {0x8BE4DF61,0x93CA,0x11d2,0xAA,0xD,0x0,0xE0,0x98,0x03,0x2B,0x8C};
+ #endif
+
+ #ifdef FORM_SET_ITEM
+ #endif
+
+ #ifdef FORM_SET_GOTO
+
+ SEPARATOR
+ //
+ // Define goto commands for the forms defined in this file
+ //
+ //
+ // Define goto commands for the forms defined in this file
+ //
+ goto SECURE_BOOT_SUBMENU_FORM_ID,
+ prompt = STRING_TOKEN(SECURE_BOOT_MENU_FORM_TITLE),
+ help = STRING_TOKEN(SECURE_BOOT_MENU_FORM_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(SECURE_BOOT_MENU_REFRESH);
+
+ #endif
+
+ #ifdef FORM_SET_FORM
+ //
+ // Define forms
+ //
+ form formid = AUTO_ID(SECURE_BOOT_SUBMENU_FORM_ID),
+ title = STRING_TOKEN(SECURE_BOOT_MENU_FORM_TITLE);
+
+ SEPARATOR
+ suppressif ideqval SETUP_MODE_VAR.Value == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_PLATFORM_MODE),
+ text = STRING_TOKEN(STR_USER),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif ideqval SETUP_MODE_VAR.Value == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_PLATFORM_MODE),
+ text = STRING_TOKEN(STR_SETUP),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif ideqval SECURE_BOOT_VAR.Value == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_PLATFORM_SECURE_MODE),
+ text = STRING_TOKEN(STR_INACTIVE),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif ideqval SECURE_BOOT_VAR.Value == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_PLATFORM_SECURE_MODE),
+ text = STRING_TOKEN(STR_ACTIVE),
+ flags = 0,
+ key = 0;
+ endif;
+ //
+ // Define controls to be added to the main page of the formset
+ //
+//!!!!!!!!!!!
+// WARNING: On older Aptio Core versions (< 4.6.5.0) VfrCompiler may generate errors in SecureBootMod.sd due to incompatible syntax of `questionid' and
+// `INTERRACTIVE' constructions. User may need to upgrade Aptio Core support for EFI_SPECIFICATION version to 2.1 (SDL:0x2000A) or edit this SecureBootMod.sd to
+// remove unsupported keywords e.g. remove `INTERACTIVE' in `one of' structures and add `, key=0' instead. Also remove `questioned' from `oneof' constructions .
+// Note that above mentioned fixes will disable some of the Secure Boot page functionality
+//!!!!!!!!!!!
+ SEPARATOR
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ oneof varid = SECURE_BOOT_SETUP_VAR.SecureBootSupport,
+ questionid = AUTO_ID(SECURE_BOOT_SUPPORT_CHANGE_KEY),
+ prompt = STRING_TOKEN(STR_SECURE_BOOT_ENABLE),
+ help = STRING_TOKEN(STR_SECURE_BOOT_HELP),
+ default = DEFAULT_SECURE_BOOT_ENABLE,
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED | INTERACTIVE;
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = MANUFACTURING | RESET_REQUIRED | INTERACTIVE;
+ endoneof;
+ oneof varid = SECURE_BOOT_SETUP_VAR.SecureBootMode,
+ questionid = AUTO_ID(SECURE_BOOT_MODE_CHANGE_KEY),
+ prompt = STRING_TOKEN(STR_SECURE_BOOT_MODE),
+ help = STRING_TOKEN(STR_SECURE_BOOT_MODE_HELP),
+ default = DEFAULT_SECURE_BOOT_MODE,
+ option text = STRING_TOKEN(SECURE_BOOT_STANDARD), value = 0, flags = MANUFACTURING | RESET_REQUIRED | INTERACTIVE;//, key = 0;
+ option text = STRING_TOKEN(SECURE_BOOT_CUSTOM), value = 1, flags = RESET_REQUIRED | INTERACTIVE;//, key = 0;
+ endoneof;
+ endif;
+ //
+ // Define goto commands for the forms defined in this file
+ //
+ suppressif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval SECURE_BOOT_SETUP_VAR.SecureBootMode == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_KEY_MANAGEMENT_TITLE),
+ help = STRING_TOKEN(STR_KEY_MANAGEMENT_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(KEY_MANAGEMENT_MENU_REFRESH);
+ #if (defined(ENABLE_IMAGE_EXEC_POLICY_OVERRIDE) && ENABLE_IMAGE_EXEC_POLICY_OVERRIDE == 1)
+ goto IMAGE_EXEC_POLICY_FORM_ID,
+ prompt = STRING_TOKEN(IMAGE_EXEC_POLICY_FORM_TITLE),
+ help = STRING_TOKEN(IMAGE_EXEC_POLICY_FORM_HELP);
+ #endif
+ endif;
+ endform;
+
+ form formid = AUTO_ID(SECURE_KEY_MANAGEMENT_FORM_ID),
+ title = STRING_TOKEN(STR_KEY_MANAGEMENT_TITLE);
+
+ oneof varid = SECURE_BOOT_SETUP_VAR.DefaultKeyProvision,
+ questionid = AUTO_ID(KEY_PROVISION_CHANGE_KEY),
+ prompt = STRING_TOKEN(STR_DEFAULT_KEY_PROVISION_MODE),
+ help = STRING_TOKEN(STR_KEY_PROVISION_MODE_HELP),
+ #if (defined(DEFAULT_PROVISION_SECURE_VARS) && DEFAULT_PROVISION_SECURE_VARS == 1)
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = RESET_REQUIRED | INTERACTIVE;
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED | INTERACTIVE;
+ #else
+ #if defined(SET_SECURE_VARS) && SET_SECURE_VARS
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED | INTERACTIVE;
+ option text = STRING_TOKEN(STR_ENABLED), value = 1, flags = RESET_REQUIRED | INTERACTIVE;
+ #else
+ option text = STRING_TOKEN(STR_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED | INTERACTIVE;
+ #endif
+ #endif
+
+ endoneof;
+ //
+ // Define goto commands for the forms defined in this file
+ //
+ SEPARATOR
+ suppressif ideqval SECURE_VAR_INSTALL_VAR.PK == 0 OR ideqval SECURE_BOOT_SETUP_VAR.DefaultKeyProvision == 1;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_FORCE_SETUP_MODE),
+ help = STRING_TOKEN(STR_FORCE_SETUP_MODE_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(FORCE_SETUP_KEY);
+ endif;
+ #if defined(SET_SECURE_VARS) && SET_SECURE_VARS
+ suppressif ideqval SECURE_VAR_INSTALL_VAR.PK == 1 AND ideqval SECURE_BOOT_SETUP_VAR.DefaultKeyProvision == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_FORCE_DEFAULT_MODE),
+ help = STRING_TOKEN(STR_FORCE_DEFAULT_MODE_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(FORCE_DEFAULT_KEY);
+ endif;
+ #endif // SET_SECURE_VARS
+ grayoutif ideqval SECURE_VAR_INSTALL_VAR.PK == 0 AND ideqval SECURE_VAR_INSTALL_VAR.KEK == 0 AND ideqval SECURE_VAR_INSTALL_VAR.DB == 0 AND ideqval SECURE_VAR_INSTALL_VAR.DBX == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_GET_ALL_VARS),
+ help = STRING_TOKEN(STR_GET_PK_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(GET_PK_KEY);
+ endif;
+ SEPARATOR
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.PK == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_PK),
+ text = STRING_TOKEN(STR_NOT_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.PK == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_PK),
+ text = STRING_TOKEN(STR_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SECURE_VAR_INSTALL_VAR.PK == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_DELETE_PK),
+ help = STRING_TOKEN(STR_DELETE_PK_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(DELETE_PK_KEY);
+ endif;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_SET_PK),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(SET_PK_KEY);
+
+ SEPARATOR
+
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.KEK == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_KEK),
+ text = STRING_TOKEN(STR_NOT_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.KEK == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_KEK),
+ text = STRING_TOKEN(STR_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SECURE_VAR_INSTALL_VAR.KEK == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_DELETE_KEK),
+ help = STRING_TOKEN(STR_DELETE_PK_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(DELETE_KEK_KEY);
+ endif;
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_SET_KEK),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(SET_KEK_KEY);
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_APPEND_KEK_ENTRY),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(APPEND_KEK_KEY);
+
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.DB == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_DB),
+ text = STRING_TOKEN(STR_NOT_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.DB == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_DB),
+ text = STRING_TOKEN(STR_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SECURE_VAR_INSTALL_VAR.DB == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_DELETE_DB),
+ help = STRING_TOKEN(STR_DELETE_PK_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(DELETE_DB_KEY);
+ endif;
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_SET_DB),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(SET_DB_KEY);
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_APPEND_DB_ENTRY),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(APPEND_DB_KEY);
+
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.DBX == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_DBX),
+ text = STRING_TOKEN(STR_NOT_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.DBX == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_DBX),
+ text = STRING_TOKEN(STR_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SECURE_VAR_INSTALL_VAR.DBX == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_DELETE_DBX),
+ help = STRING_TOKEN(STR_DELETE_PK_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(DELETE_DBX_KEY);
+ endif;
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_SET_DBX),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(SET_DBX_KEY);
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_APPEND_DBX_ENTRY),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(APPEND_DBX_KEY);
+
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.DBT == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_DBT),
+ text = STRING_TOKEN(STR_NOT_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+ suppressif NOT ideqval SECURE_VAR_INSTALL_VAR.DBT == 1;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_MANAGE_DBT),
+ text = STRING_TOKEN(STR_INSTALLED),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SECURE_VAR_INSTALL_VAR.DBT == 0;
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_DELETE_DBT),
+ help = STRING_TOKEN(STR_DELETE_PK_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(DELETE_DBT_KEY);
+ endif;
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_SET_DBT),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(SET_DBT_KEY);
+
+ goto SECURE_KEY_MANAGEMENT_FORM_ID,
+ prompt = STRING_TOKEN(STR_APPEND_DBT_ENTRY),
+ help = STRING_TOKEN(STR_APPEND_KEK_ENTRY_HELP),
+ flags = INTERACTIVE, key = AUTO_ID(APPEND_DBT_KEY);
+
+ endform;
+
+#if (defined(ENABLE_IMAGE_EXEC_POLICY_OVERRIDE) && ENABLE_IMAGE_EXEC_POLICY_OVERRIDE == 1)
+ form formid = AUTO_ID(IMAGE_EXEC_POLICY_FORM_ID),
+ title = STRING_TOKEN(IMAGE_EXEC_POLICY_FORM_TITLE);
+
+ oneof varid = SECURE_BOOT_SETUP_VAR.Load_from_FV,
+ prompt = STRING_TOKEN(STR_LOAD_FROM_FV),
+ help = STRING_TOKEN(STR_LOAD_FROM_HELP),
+ option text = STRING_TOKEN(ALWAYS_ENABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED, key = 0;
+ endoneof;
+
+ oneof varid = SECURE_BOOT_SETUP_VAR.Load_from_OROM,
+ prompt = STRING_TOKEN(STR_LOAD_FROM_OROM),
+ help = STRING_TOKEN(STR_LOAD_FROM_HELP),
+ default = LOAD_FROM_OROM,
+#if (LOAD_FROM_OROM == 0 )
+ option text = STRING_TOKEN(ALWAYS_ENABLED), value = 0, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_OROM < 2 )
+ option text = STRING_TOKEN(ALWAYS_DISABLED), value = 1, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_OROM < 3 )
+ option text = STRING_TOKEN(ALLOW_EXECUTE_ON_SECURITY_VIOLATION), value = 2, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_OROM < 4 )
+ option text = STRING_TOKEN(DEFER_EXECUTE_ON_SECURITY_VIOLATION), value = 3, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_OROM < 5 )
+ option text = STRING_TOKEN(DENY_EXECUTE_ON_SECURITY_VIOLATION), value = 4, flags = MANUFACTURING | RESET_REQUIRED, key = 0;
+#endif
+ option text = STRING_TOKEN(QUERY_USER_ON_SECURITY_VIOLATION), value = 5, flags = RESET_REQUIRED, key = 0;
+ endoneof;
+
+ oneof varid = SECURE_BOOT_SETUP_VAR.Load_from_REMOVABLE_MEDIA,
+ prompt = STRING_TOKEN(STR_LOAD_FROM_REMOVABLE_MEDIA),
+ help = STRING_TOKEN(STR_LOAD_FROM_HELP),
+ default = LOAD_FROM_REMOVABLE_MEDIA,
+#if (LOAD_FROM_REMOVABLE_MEDIA == 0 )
+ option text = STRING_TOKEN(ALWAYS_ENABLED), value = 0, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_REMOVABLE_MEDIA < 2 )
+ option text = STRING_TOKEN(ALWAYS_DISABLED), value = 1, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_REMOVABLE_MEDIA < 3 )
+ option text = STRING_TOKEN(ALLOW_EXECUTE_ON_SECURITY_VIOLATION), value = 2, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_REMOVABLE_MEDIA < 4 )
+ option text = STRING_TOKEN(DEFER_EXECUTE_ON_SECURITY_VIOLATION), value = 3, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_REMOVABLE_MEDIA < 5 )
+ option text = STRING_TOKEN(DENY_EXECUTE_ON_SECURITY_VIOLATION), value = 4, flags = MANUFACTURING | RESET_REQUIRED, key = 0;
+#endif
+ option text = STRING_TOKEN(QUERY_USER_ON_SECURITY_VIOLATION), value = 5, flags = RESET_REQUIRED, key = 0;
+ endoneof;
+
+ oneof varid = SECURE_BOOT_SETUP_VAR.Load_from_FIXED_MEDIA,
+ prompt = STRING_TOKEN(STR_LOAD_FROM_FIXED_MEDIA),
+ help = STRING_TOKEN(STR_LOAD_FROM_HELP),
+ default = LOAD_FROM_FIXED_MEDIA,
+#if (LOAD_FROM_FIXED_MEDIA == 0 )
+ option text = STRING_TOKEN(ALWAYS_ENABLED), value = 0, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_FIXED_MEDIA < 2 )
+ option text = STRING_TOKEN(ALWAYS_DISABLED), value = 1, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_FIXED_MEDIA < 3 )
+ option text = STRING_TOKEN(ALLOW_EXECUTE_ON_SECURITY_VIOLATION), value = 2, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_FIXED_MEDIA < 4 )
+ option text = STRING_TOKEN(DEFER_EXECUTE_ON_SECURITY_VIOLATION), value = 3, flags = RESET_REQUIRED, key = 0;
+#endif
+#if (LOAD_FROM_FIXED_MEDIA < 5 )
+ option text = STRING_TOKEN(DENY_EXECUTE_ON_SECURITY_VIOLATION), value = 4, flags = MANUFACTURING | RESET_REQUIRED, key = 0;
+#endif
+ option text = STRING_TOKEN(QUERY_USER_ON_SECURITY_VIOLATION), value = 5, flags = RESET_REQUIRED, key = 0;
+ endoneof;
+
+ endform;
+#endif
+ #endif
+
+#endif // SECURITY_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/SecurityPkg/SecureBootMod.sdl b/Core/EM/SecurityPkg/SecureBootMod.sdl
new file mode 100644
index 0000000..0b75e1b
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.sdl
@@ -0,0 +1,277 @@
+TOKEN
+ Name = "SecureBoot_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable SecureBoot Module support in Project"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CryptoAPI_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SECURE_BOOT_MODULE_REVISION"
+ Value = "25"
+ Help = "Version of Secure Boot module interfaces"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SECURE_BOOT_ENABLE"
+ Value = "1"
+ Help = "Default value of Secure Boot Enable Control.\0-Secure Boot control option will be locked Disabled unless platform in User mode with CSM disabled"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SECURE_BOOT_MODE"
+ Value = "0"
+ Help = "Default Secure Boot Mode selector.\0-Standard, 1-Custom Mode allows physically present users more flexibility changing Image Execution policy and Secure Boot Key management."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_SECURE_BOOT_MODE"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEFAULT_SECURE_BOOT_ENABLE" "=" "0"
+End
+
+TOKEN
+ Name = "DEFAULT_PROVISION_SECURE_VARS"
+ Value = "0"
+ Help = "Install factory default Secure Boot variables: PK, KEK, db, dbx and dbt.\Note: this function will not override existing Secure Boot variables in NVRAM."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "SecVariables_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SET_SECURE_VARS"
+ Value = "0"
+ Help = "Placeholder token"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SET_SECURE_VARS"
+ Value = "1"
+ Help = "Includes the code to provision Platform Keys EFI variable from Setup Page and at 1st boot after reFlash"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "SecVariables_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PRESERVE_SECURE_VARIABLES"
+ Value = "1"
+ Help = "1 - Preserve Secure Boot State across flash updates.\0 - Do not preserve Secure Boot State across flash updates.\Note. Same functionality may already exist in SmiFlash eModule"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ALWAYS_INSTALL_DEFAULT_RT_KEYS"
+ Value = "0"
+ Help = "UEFI 2.3.1c. Install vendor default Secure Boot keys as volatile variables: PKdefault, KEKdefault etc. are set irrespective of Setup mode"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "SecureBoot_DIR"
+ Help = "Path to SecureBoot Module Module in Project"
+End
+
+MODULE
+ File = "SecureBootMod.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SecureBootMod.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SecureBootMod.sdb"
+ Parent = "SETUP_SDBS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(SecureBoot_DIR)\SecureBootMod.sd"
+ Parent = "SETUP_DEFINITIONS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "UpdateSecureVariableBrowserInfo,"
+ Parent = "LoadedPreviousValuesHook,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "UpdateSecureVariableBrowserInfo,"
+ Parent = "LoadedConfigDefaults,"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SECURE_BOOT_MENU_REFRESH,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SECURE_BOOT_SUPPORT_CHANGE_KEY,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SECURE_BOOT_MODE_CHANGE_KEY,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,KEY_MANAGEMENT_MENU_REFRESH,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,FORCE_DEFAULT_KEY,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,FORCE_SETUP_KEY,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,KEY_PROVISION_CHANGE_KEY,ForceSetupModeCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SET_KEK_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,DELETE_KEK_KEY,DeleteSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,APPEND_KEK_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SET_DB_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,DELETE_DB_KEY,DeleteSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,APPEND_DB_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SET_DBT_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,DELETE_DBT_KEY,DeleteSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,APPEND_DBT_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SET_DBX_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,DELETE_DBX_KEY,DeleteSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,APPEND_DBX_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,SET_PK_KEY,SetAppendSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,GET_PK_KEY,GetSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ITEM_CALLBACK(SECURITY_FORM_SET_CLASS,0,DELETE_PK_KEY,DeleteSecureBootDBCallback),"
+ Parent = "SetupItemCallbacks"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PreserveSecureVariables,"
+ Parent = "SMIFlashPreUpdateList"
+ Token = "SMIFlash_SUPPORT" "=" "1"
+ Token = "PRESERVE_SECURE_VARIABLES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RestoreSecureVariables,"
+ Parent = "SMIFlashEndUpdateList"
+ Token = "SMIFlash_SUPPORT" "=" "1"
+ Token = "PRESERVE_SECURE_VARIABLES" "=" "1"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/SecurityPkg/SecureBootMod.uni b/Core/EM/SecurityPkg/SecureBootMod.uni
new file mode 100644
index 0000000..f712aa3
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureBootMod.uni
Binary files differ
diff --git a/Core/EM/SecurityPkg/SecureMod.chm b/Core/EM/SecurityPkg/SecureMod.chm
new file mode 100644
index 0000000..85b98e0
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureMod.chm
Binary files differ
diff --git a/Core/EM/SecurityPkg/SecureMod.cif b/Core/EM/SecurityPkg/SecureMod.cif
new file mode 100644
index 0000000..64a79a1
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureMod.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "Secure Flash Pkg"
+ category = eModule
+ LocalRoot = "Core\EM\SecurityPkg\"
+ RefName = "SecureFlashMod"
+[files]
+"SecureMod.chm"
+"SecureMod.sdl"
+"SecureMod.mak"
+[parts]
+"SecFlashUpd"
+"SecSMIFlash"
+"FWKey"
+"CryptoUtils"
+[dependOn]
+"CryptoPkg"
+<endComponent>
diff --git a/Core/EM/SecurityPkg/SecureMod.mak b/Core/EM/SecurityPkg/SecureMod.mak
new file mode 100644
index 0000000..be3e8c5
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureMod.mak
@@ -0,0 +1,458 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureMod.mak 35 9/10/14 5:13p Alexp $
+#
+# $Revision: 35 $
+#
+# $Date: 9/10/14 5:13p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/SecureFlashPkg/SecureMod.mak $
+#
+# 35 9/10/14 5:13p Alexp
+# restore generation of make_sign_capsule.bat file
+#
+# 34 5/28/14 12:34p Alexp
+# update format of make_sign_capsule_readme.txt
+#
+# 32 3/21/14 12:30p Alexp
+# 1. Eliminate generation of a .bat file. Instead provide capsule build
+# instructions inside make_sign_capsule_readme file
+# 2. Split the cryptocon command line to 2 sets:
+# 1. for preparing BIOS ROM image with mapping of capsule
+# signing instructions and an extended ROM map layout
+# 2. Actual capsule signing command line.
+#
+#
+# 30 11/11/13 9:43a Alexp
+# file is inlcuded only when create_capsule switch is non-0
+# updated displayed warning messages and content of generated readme
+# file.
+#
+# 29 10/17/13 4:50p Alexp
+# moved FwKey build rules and Guuid defines to a separare FwKey module
+#
+# 28 10/14/13 4:11p Alexp
+# [TAG] EIP139208
+# [Description] Build FwCapsule with Pkcs7 sig fails.
+# 1. Fix Cryptocon.exe to provide proper input line for generation of
+# detached signatures
+# Cryptocon.exe ver 4.10.10
+# 2. Fix mak scripts to invoke msft signtool along with cryptocon if .pfx
+# password is to be provided
+#
+# 27 8/21/13 3:24p Alexp
+#
+# 22 7/12/13 12:41p Alexp
+# Redesigned make file to accommodate more SDL defined build options and
+# generate user friendly messages to deal with different build warnings
+#
+# 21 4/19/13 4:52p Alexp
+# -removed rules to generate igned image. will use external signing
+# ToolKit (e.g. VEB project)
+# -add build rules to generate emptu placeholder for FwKey and FwSig
+# header.
+# -Insert RomLayoutEX into FwSig hdr after AMI.ROM is generated
+#
+# 20 4/10/13 7:04p Alexp
+# Removed all FwCapsule signing build instructions
+#
+# 19 11/13/12 3:11p Alexp
+# add x509 Key format to list of supported FwKey file formats
+#
+# 18 11/12/12 6:09p Alexp
+# Add CREATE_FWCAPSULE token to be able to control Fw Capsule make rules
+# Add FWCAPSULE_CERT_FORMAT to choose format for the digital certificate:
+# PKCS1_v1.5 or PKCS7
+#
+# 17 8/22/12 5:03p Alexp
+# Added FWSIG_KEY_ROOT flag to select which Key is used to sign
+# FwCapsule's FwSig signature.
+#
+# 15 7/26/12 3:03p Alexp
+# Make token:FWSIG_PADDING relevant only if FWSIG_SIGNHDR = 1.
+#
+# 14 6/06/12 9:31a Alexp
+# -New FWSIG_SIGNHDR and FWSIG_PADDING Tokens control input arguments -q
+# and -p in CryptoCon.exe.
+# -New flags control format of signing FwCapHdr and Signature padding
+# scheme
+# -Fix for the issue of backward compatibility when flashing BIOS with
+# SecFlash 008 to new one with label 009 and onwards.
+#
+# 12 5/21/12 4:51p Alexp
+# keep name of signed BIOS image as .CAP. Should match to the default
+# recovery file name.
+#
+# 11 5/18/12 4:13p Alexp
+# 1. Add rebuild dependency on .mak file
+# 2. pass SIGPAD flag to indicate current padding scheme
+# 3. Create rules to translete SDL defined GUID strings to .MAK and .H
+# acceprtable formats
+#
+# 10 4/17/12 4:46p Alexp
+# EIP87889: Signed Aptio Flash Update binary image
+# Supporting new output file format of the BIOS.ROM with
+# embeded FwCapsule Hdr inside the FFS File Section with the special GUID
+#
+# 9 2/29/12 4:06p Alexp
+# Use FWKEY_FORMAT to switch between RSA2048 and SH256 FW Key formats
+#
+# 8 1/05/12 4:19p Alexp
+# Add switch to generate FW Capsule output files based on SDL tokens :
+# FWCAPSULE_FILE_FORMAT and FWCAPSULE_HDR_FILE
+#
+# 6 1/03/12 4:21p Alexp
+# Rearrange build rules, clarify build steps, allow for FW Key to change
+# location from default.
+# Display error if FW Key file is not present
+#
+# 4 12/20/11 5:09p Alexp
+# Use ROM_LAYOUT_EX macro as a name for RomLayout table. New SDL Token is
+# defined by Core.sdl starting from Label:4.6.5.3
+#
+# 3 11/08/11 3:07p Alexp
+# Change names and fix FWCAPSULE_IMAGE_SIZE vallue to depend on
+# FWCAPSULE_IMAGE_ALLIGN
+#
+# 2 11/03/11 6:36p Alexp
+# added FWCAPSULE_ROM_ALLIGN token to control alignment size of generated
+# FW Capsule
+# use new CryptoCon.exe with support for -l key for alignment
+#
+# 1 7/01/11 4:37p Alexp
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: SecureMod.mak
+#
+# Description: Includes main build module for Secure sub-components
+#
+# Create signed BIOS image (Aptio FW Capsule)
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all: SecureModule
+!INCLUDE $(BUILD_DIR)\timestamp.mak
+
+SecureModule : $(BUILD_DIR)\SecureMod.mak
+
+#---------------------------------------------------------------------------
+# Generic MAK dependencies
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\SecureMod.mak : $(SecureMod_DIR)\SecureMod.mak $(SecureMod_DIR)\SecureMod.cif $(SecureMod_DIR)\SecureMod.sdl $(BUILD_RULES)
+ $(CIF2MAK) $(SecureMod_DIR)\SecureMod.cif $(CIF2MAK_DEFAULTS)
+
+#---------------------------------------------------------------------------
+# Generic GUID defines. Aptio Tools must support these GUIDs
+#---------------------------------------------------------------------------
+#GUID used to identify FW Capsule Hdr FFS file within the Firmware Volume.
+FWCAPSULE_FFS_GUID = 414D94AD-998D-47D2-BFCD-4E882241DE32
+#Section GUID used to identify FW Capsule Hdr section within FwCap FFS file.
+FWCAPSULE_FFS_SECTION_GUID = 5A88641B-BBB9-4AA6-80F7-498AE407C31F
+
+#---------------------------------------------------------------------------
+# Creating a placeholder FFS for embedded FwCapsule Hdr
+#---------------------------------------------------------------------------
+SecureModule: $(BUILD_DIR)\FwCapsuleHdr.ffs
+
+$(BUILD_DIR)\FwCapsuleHdr.obj: $(BUILD_DIR)\SecureMod.mak
+ $(SILENT)copy << $(BUILD_DIR)\FwCapsuleHdr.c > NUL
+#include <AmiCertificate.h>
+#pragma pack(1)
+APTIO_FW_CAPSULE_HEADER dummyHdr =
+ { { APTIO_FW_CAPSULE_GUID,
+ $(FWCAPSULE_MAX_HDR_SIZE),
+ CAPSULE_FLAGS_PERSIST_ACROSS_RESET |
+ CAPSULE_FLAGS_FWCERTBLOCK_VALID, // 1 - sig is invalid
+ $(FWCAPSULE_MAX_HDR_SIZE)},
+ $(FWCAPSULE_MAX_HDR_SIZE), // Rom Offs
+ sizeof(APTIO_FW_CAPSULE_HEADER) // RomLayout Offs
+ };
+char pad[$(FWCAPSULE_MAX_HDR_SIZE)-sizeof(APTIO_FW_CAPSULE_HEADER)] = {0x55, 0xAA};
+<<KEEP
+ $(CC) /Fo$@ $(CFLAGS) $(BUILD_DIR)\FwCapsuleHdr.c
+
+#The FFS section with Fw Capsule Signature block should be left unsigned and uncompressed.
+#Ignore FFS checksum as the file data will be updated by external utility
+$(BUILD_DIR)\FwCapsuleHdr.ffs : $(BUILD_DIR)\FwCapsuleHdr.obj $(BUILD_DIR)\SecureMod.mak
+ $(MAKE) /$(MAKEFLAGS) EXT_OBJS= $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\SecureMod.mak bin\
+ NAME=FwCapsuleHdr OBJECTS=$(BUILD_DIR)\FwCapsuleHdr.obj\
+ MAKEFILE=$(BUILD_DIR)\SecureMod.mak \
+ TYPE=BINARY
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=$(FWCAPSULE_FFS_GUID) \
+ TYPE=EFI_FV_FILETYPE_FREEFORM FFS_CHECKSUM=0\
+ SECTION_GUID=$(FWCAPSULE_FFS_SECTION_GUID) \
+ RESOURCE=$(BUILD_DIR)\FwCapsuleHdr.bin \
+ FFSFILE=$@ COMPRESS=0 NAME=$(@B)
+
+#---------------------------------------------------------------------------
+# Only for PKCS1v2.1 Key files: re-assign FWpub = FWpriv only if
+# following codition is true: FWpub file not defined but full RSA key FWpriv file is defined
+#---------------------------------------------------------------------------
+!IF "$(FWCAPSULE_CERT_FORMAT)"=="0"
+!IF !EXIST($(FWpub))
+!IF EXIST($(FWpriv))
+FWpub = $(FWpriv)
+!ENDIF
+!ENDIF
+!ENDIF
+
+#---------------------------------------------------------------------------
+# Conditions when error log needs to be created
+#---------------------------------------------------------------------------
+!IF !EXIST($(FWpriv))
+FWCAP_BUILD_ERROR_TXT = $(FWCAP_BUILD_ERROR_TXT)&\
+WARNING!!! Missing RSA private key FWpriv="$(FWpriv)" to sign BIOS image.
+!ENDIF
+
+!IF "$(FWCAPSULE_CERT_FORMAT)" == "0" && !EXIST($(FWrootKey))
+FWCAP_BUILD_ERROR_TXT = $(FWCAP_BUILD_ERROR_TXT)&\
+WARNING!!! Missing RSA private key FWrootKey="$(FWrootKey)"
+!ENDIF
+
+!IF !EXIST($(FWpub))
+FWCAP_BUILD_ERROR_TXT = $(FWCAP_BUILD_ERROR_TXT)&\
+WARNING!!! Missing RSA public key FWpub="$(FWpub)" to verify Signed BIOS updates.&\
+$(FWKEY_FILE_SIZE) byte dummy Key is inserted into BIOS RTU (FV_BB).&\
+Flash Updates or Recovery will fail on "$(UNSIGNED_BIOS_ROM)" BIOS&\
+unless the dummy Key is replaced with a valid Platform key during BIOS signing.
+!ENDIF
+
+!IFDEF CONFIG_PEI_PKCS7
+!IF "$(FWCAPSULE_CERT_FORMAT)" == "1" && "$(CONFIG_PEI_PKCS7)" == "0"
+FWCAP_BUILD_ERROR_TXT = $(FWCAP_BUILD_ERROR_TXT)&\
+WARNING!!! Capsule or Recovery Flash updates are disabled for PKCS7 Signed Fw Capsules.&\
+Enable support via SDL Token "CONFIG_PEI_PKCS7" in CryptoAPI.sdl
+!ENDIF
+!ENDIF
+
+!IF "$(FWCAPSULE_FILE_FORMAT)" == "1"
+FWCAP_SIG_HDR_TXT = Attached FW signature (Capsule)
+!ELSE
+FWCAP_SIG_HDR_TXT = Embedded FW signature
+!ENDIF
+!IF "$(FWKEY_FILE_FORMAT)"=="0"
+FWCAP_KEY_STORE_TXT = RSA2048 modulus N
+!ENDIF
+!IF "$(FWKEY_FILE_FORMAT)"=="1"
+FWCAP_KEY_STORE_TXT = SHA-256 digest of a public Key certificate
+!ENDIF
+!IF "$(FWKEY_FILE_FORMAT)"=="2"
+FWCAP_KEY_STORE_TXT = DER-encoded X.509 public key certificate
+!ENDIF
+
+!IF "$(FWCAPSULE_CERT_FORMAT)" == "1"
+FWCAP_SIGN_CERT_TYPE_TXT = PKCS7 Signed data
+FWCAP_SIGN_KEY_TYPE_TXT = RSA, PKCS12 PFX(private) and X.509 DER(public)
+!ELSE
+FWCAP_SIGN_CERT_TYPE_TXT = RSASSA-PKCS1-v1.5 (-PSS)
+FWCAP_SIGN_KEY_TYPE_TXT = RSA-2048, PKCS1-v2.1(DER or PEM)&\
+"$(FWrootKey)" - Root Key Certificate key (full RSA key)
+!ENDIF
+
+#---------------------------------------------------------------------------
+# Prepare Signed Capsule : FWCAPSULE_FILE_NAME
+#---------------------------------------------------------------------------
+SecureModule: CLEAR_FWCAPSULE_FILES MAKE_FWCAPSULE_HELP_FILES
+
+CLEAR_FWCAPSULE_FILES:
+ $(SILENT)if exist $(FWCAPSULE_FILE_NAME) $(SILENT)del $(FWCAPSULE_FILE_NAME)
+ $(SILENT)if exist make_sign_capsule*.* $(SILENT)del make_sign_capsule*.*
+
+#---------------------------------------------------------------------------
+# 1. Create error log and batch files with instructions to sign Fw Capsule
+# using CryptoCon.exe
+#---------------------------------------------------------------------------
+#Create make_sign_capsule.bat - command line to sign BIOS image
+#Create make_sign_capsule_error.log - error log
+#Create make_sign_capsule_readme.txt - simple instructions to create signed FwCapsule
+#---------------------------------------------------------------------------
+MAKE_FWCAPSULE_HELP_FILES:
+#------------------------------------------------------------------------
+#Create make_sign_capsule.bat - command line to sign BIOS image
+#------------------------------------------------------------------------
+ $(SILENT)copy << make_sign_capsule.bat > NUL
+@echo ----update the rom map file $(ROM_LAYOUT_EX)
+@echo ----if the BIOS ROM image was edited
+@echo FWBUILD $(UNSIGNED_BIOS_ROM) /s /m $(ROM_LAYOUT_EX)
+@echo ----sign BIOS image using external rom map
+CRYPTCON -r $(ROM_LAYOUT_EX) $(CRYPTOCON_CMDLINE_SIG)
+<< KEEP
+ $(SILENT)copy << make_sign_capsule_readme.txt > NUL
+#---------------------------------------------------------------------------
+#Create make_sign_capsule_error.log - error log
+#---------------------------------------------------------------------------
+!IFDEF FWCAP_BUILD_ERROR_TXT
+ $(SILENT)copy << make_sign_capsule_error.log > NUL
+$(FWCAP_BUILD_ERROR_TXT:& =^
+ )
+
+<<KEEP
+!ENDIF
+#---------------------------------------------------------------------------
+#Create make_sign_capsule_readme.txt - simple instructions to create signed FwCapsule
+#---------------------------------------------------------------------------
+ $(SILENT)copy << make_sign_capsule_readme.txt > NUL
+===============================================================
+=== Un-signed Aptio FW Image
+===============================================================
+BIOS File name : $(UNSIGNED_BIOS_ROM)
+Project TAG : $(PROJECT_TAG)
+Build Time : $(TODAY), $(NOW)
+BIOS Flash size : $(FLASH_SIZE)
+FW update Key store(FwKey ffs): $(FWCAP_KEY_STORE_TXT)
+Embedded FwCapsule parameters : $(CRYPTOCON_CMDLINE_MAP)
+
+===============================================================
+=== Pre-defined Signed FwCapsule parameters
+===============================================================
+FwCapsule file name : $(FWCAPSULE_FILE_NAME)
+FwCapsule file package : $(FWCAP_SIG_HDR_TXT)
+FwCapsule Signature type : $(FWCAP_SIGN_CERT_TYPE_TXT)
+FwCapsule Sign Key format : $(FWCAP_SIGN_KEY_TYPE_TXT:& =^
+ )
+ "$(FWpriv)" - Signing Certificate key (full RSA key)
+ "$(FWpub)" - Signing Certificate key (public key part)
+
+===============================================================
+=== Cryptocon.exe script to generate signed FwCapsule
+===============================================================
+Cryptocon.exe $(CRYPTOCON_CMDLINE_SIG)
+
+===============================================================
+=== Common Cryptocon FwCapsule build instructions
+===============================================================
+ -c'FWrootPriv' -k'FWsignPriv' Create PKCS#1v1.5 signed FwCapsule (Note1)
+ -c2 -x 'FWpriv'[,'pswd'] Create PKCS#7 signed FwCapsule (Note2, Note3)
+ -f'file' input, un-signed BIOS image
+ -o'file' output, signed FwCapsule image
+ -y update an embedded FwCapsule Header, default-Hdr attached on top of BIOS
+ -l'value' max size of a FwCapsule Header (file alignment)
+ -n -k'key' insert Signer public 'key' into a signed image
+ -r'rom.map' use a rom map from the external file
+ -m embed the FwCapsule sign parameters without creating a signed image
+
+Note1. -c'key1'-k'key2' :take PKCS#1v2.1 DER(PEM) encoded RSA2048 keys
+Note2. -c2 -x'key1'-k'key2':key1-PKCS#12(PFX) with optional PFX password;
+ key2-X.509(DER) with public 'key1'
+Note3. -c2 -x command invokes external Msft signtool.exe
+
+===============================================================
+=== Extended Cryptocon FwCapsule build instructions
+===============================================================
+ -c2 -s Create serialized data block based on the rom map info
+ -c2 -s -x'p7.sig' import PKCS#7 signed data from file into a FwCapsule
+ -r2 use embedded rom map data
+<< KEEP
+
+#---------------------------------------------------------------------------
+# Should be the last step after creating of the ROM image. All fixups to the .ROM must be made prior to this step.
+# check END target in the CORE.MAK and all .MAK files to make sure this step is not overriden
+# Use AFTER_ROM as alternative target.
+#---------------------------------------------------------------------------
+End: $(FWCAPSULE_FILE_NAME)
+
+#------------------------------------------------------------------------
+# 1. Creating Signing descriptor table (RomLayout map) file
+#------------------------------------------------------------------------
+
+#--------------------
+# Older Cores 4.6.3.x didn't generate RomLayout map file
+# 1. Add rules to generate RomLayout.c file. Rules to generate RomLayout.c file are defined in newer versions of Core.mak (4.6.5.x)
+# 2. Create binary file. Build rule is also defined in newer versions of Board.mak (4.6.5.0_Board_27)
+#$(AMI_ROM_TABLE): $(BUILD_DIR)\RomLayout.c $(BUILD_DIR)\RomLayout.obj
+# @CL /Fo$(BUILD_DIR)\ $(CFLAGS) /TC $(BUILD_DIR)\RomLayout.c
+# @LINK /OUT:$(BUILD_DIR)\RomLayout.dll /DLL /SUBSYSTEM:NATIVE /NODEFAULTLIB /NOENTRY $(BUILD_DIR)\RomLayout.obj
+# pe2bin $(BUILD_DIR)\RomLayout.dll $@
+#--------------------
+!IFNDEF ROM_LAYOUT_EX
+ROM_LAYOUT_EX = $(BUILD_DIR)\RomLayoutEx.bin
+!ENDIF
+
+$(ROM_LAYOUT_EX): $(UNSIGNED_BIOS_ROM) $(BUILD_DIR)\RomLayout.bin
+ @if not exist $@ $(FWBUILD) $(UNSIGNED_BIOS_ROM) /s /m $@
+
+#---------------------------------------------------------------------------
+# 3. Embed Signing descriptor table "$(ROM_LAYOUT_EX)" inside "$(UNSIGNED_BIOS_ROM)"
+#--------------------------------------------------------------------------
+MOD_FWCAPSULE_HDR_FFS: $(ROM_LAYOUT_EX) $(UNSIGNED_BIOS_ROM)
+ @echo ----Update "$(UNSIGNED_BIOS_ROM)" with Extended BIOS Rom Map "$(ROM_LAYOUT_EX)" and FwCapsule signing parameters
+ $(CRYPTCON) $(CRYPTOCON_CMDLINE_MAP)
+
+#---------------------------------------------------------------------------
+# 4. Invoke cryptocon.exe to create Signed FwCapsule if CREATE_FWCAPSULE == 1
+#---------------------------------------------------------------------------
+$(FWCAPSULE_FILE_NAME): MOD_FWCAPSULE_HDR_FFS $(UNSIGNED_BIOS_ROM) $(ROM_LAYOUT_EX)
+!IF "$(CREATE_FWCAPSULE)" == "1"
+ @echo ----Create signed BIOS image "$(FWCAPSULE_FILE_NAME)"
+ -$(CRYPTCON) $(CRYPTOCON_CMDLINE_SIG)
+ @if not exist $@ @echo ERROR!!! Failed to create signed BIOS Image.
+!IF "$(FWCAPSULE_FILE_FORMAT)" == "0"
+# Target FWCAPSULE_FILE_NAME file is an original unsigned UNSIGNED_BIOS_ROM with Fw Signature block embedded as Ffs file
+# Replace original UNSIGNED_BIOS_ROM with the signed one if this file will be used as input to Intel fitc or other Flash image packaging tool
+ @if exist $@ @COPY $@ $(UNSIGNED_BIOS_ROM)
+!ENDIF
+!ENDIF #$(CREATE_FWCAPSULE) == 1
+#---------------------------------------------------------------------------
+# Display error log
+#---------------------------------------------------------------------------
+ @if exist make_sign_capsule_error.log @type make_sign_capsule_error.log
+#---------------------------------------------------------------------------
+# Display warning
+#---------------------------------------------------------------------------
+ @if not exist $@ @echo WARNING!!! Do not use un-signed "$(UNSIGNED_BIOS_ROM)" file as a BIOS update image.
+#---------------------------------------------------------------------------
+#
+#####
+#Example of an alternative way to build PKCS#7 signed Fw Capsule using Cryptocon.exe as a packaging tool and signing done by a msft signtool.exe
+#Make sure to use the version of Microsoft SignTool.exe that supports /p7 switch
+#Latest tool version can be downloaded as part of Win8 SDK from http://msdn.microsoft.com/en-us/windows/hardware/hh852363.aspx.
+#
+#1. Optional step if new BIOS verification key $(FWpub) needs to be embedded into $(UNSIGNED_BIOS_ROM)
+#$(CRYPTCON) -c2 -n -k $(FWpub) -f $(UNSIGNED_BIOS_ROM) -o $(UNSIGNED_BIOS_ROM)
+#
+#2. Create serialized data stream "fwcap_serialized" to be signed in step 3.
+#$(CRYPTCON) -c2 -s -f $(UNSIGNED_BIOS_ROM) -o $(BUILD_DIR)\fwcap_serialized
+#
+#3. Create .p7 detached certificate file by signing of "fwcap_serialized":
+# 3.1 sign using a certificate whose private key information is protected by a hardware cryptography module (e.g. HSM).
+# A computer store is specified for the certification authority (CA) store; Certificate is identified by a Subject Name "My High Value Certificate" .
+#Signtool sign /fd sha256 /p7 $(BUILD_DIR) /p7co 1.2.840.113549.1.7.1 /p7ce DetachedSignedData /sm /n "My High Value Certificate" $(BUILD_DIR)\fwcap_serialized
+# 3.2 sign using a certificate stored in a password-protected PFX file "$(FWpriv)"
+#Signtool sign /fd sha256 /p7 $(BUILD_DIR) /p7co 1.2.840.113549.1.7.1 /p7ce DetachedSignedData /f $(FWpriv) /p$(FW_PFX_Password) $(BUILD_DIR)\fwcap_serialized
+#
+#4. Creating Fw Capsule image $(FWCAPSULE_FILE_NAME) with .p7 signature embedded into a FwCap header
+#$(CRYPTCON) -c2 -s -x $(BUILD_DIR)\fwcap_serialized.p7 -f $(UNSIGNED_BIOS_ROM) -o $(FWCAPSULE_FILE_NAME)
+#####
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2014, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/SecurityPkg/SecureMod.sdl b/Core/EM/SecurityPkg/SecureMod.sdl
new file mode 100644
index 0000000..c4a3338
--- /dev/null
+++ b/Core/EM/SecurityPkg/SecureMod.sdl
@@ -0,0 +1,315 @@
+TOKEN
+ Name = "SecureMod_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CryptoAPI_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "SECURE_FLASH_MODULE_REVISION"
+ Value = "17"
+ Help = "Version of Secure Flash module interfaces"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CREATE_FWCAPSULE"
+ Value = "1"
+ Help = "Mode selector for creating of digitally signed Aptio FW Capsule, to be used for Protected Flash Updates including Recovery.\0 - Enable Secure Flash interfaces, but skip FW Capsule signing;\1 - Create Aptio FW Capsule;\2 - Skip final FW Capsule signing process, e.g to hand off this task to signing server."
+ TokenType = Integer
+ TargetMAK = Yes
+ Range = "0-1-2"
+End
+
+TOKEN
+ Name = "====FWCAPSULE FORMAT TUNE-UP===="
+ Value = "=============================="
+ TokenType = Expression
+End
+
+TOKEN
+ Name = "FWCAPSULE_FILE_FORMAT"
+ Value = "1"
+ Help = "0 - Include Aptio FW Signature Block inside the BIOS ROM as a ROM Hole Ffs.\1 - FW Signature Block is attached on top of BIOS Image."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWCAPSULE_CERT_FORMAT"
+ Value = "0"
+ Help = "0 - FwCapsule Hdr includes UEFI RSA2048_SHA256 certificates\1 - PKCS#7 Certificate. Signing keys delivered in PKCS#12 .pfx and X.509.cer"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UNSIGNED_BIOS_ROM"
+ Value = "$(AMI_ROM)"
+ Help = "File name of the BIOS image to be signed."
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "FWCAPSULE_FILE_NAME"
+ Value = "$(PROJECT_TAG).ROM"
+ Help = "Signed BIOS file name. FwCapsule Hdr with Signature embedded inside the BIOS.ROM.\Note!!!Default Recovery image name is provided by RECOVERY_ROM"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "FWCAPSULE_FILE_FORMAT" "=" "0"
+End
+
+TOKEN
+ Name = "FWCAPSULE_FILE_NAME"
+ Value = "$(PROJECT_TAG).CAP"
+ Help = "Signed BIOS file name. Aptio FwCapsule Hdr is attached on top of BIOS.ROM.\Note!!!Default Recovery image name is provided by RECOVERY_ROM"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "FWCAPSULE_FILE_FORMAT" "=" "1"
+End
+
+TOKEN
+ Name = "FWCAPSULE_IMAGE_ALLIGN"
+ Value = "4096"
+ Help = "FW Capsule file size alignment"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "Min FW Capsule file size allignment is 512"
+End
+
+TOKEN
+ Name = "FWCAPSULE_MAX_HDR_SIZE"
+ Value = "4096"
+ Help = "Maximum Size of the embedded FW Capsule Header"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "Min FW Capsule Header size is 2048"
+End
+
+TOKEN
+ Name = "FWCAPSULE_IMAGE_SIZE"
+ Value = "$(FLASH_SIZE)+0x4000"
+ Help = "This is the max size of the signed Recovery image with attached 16kb FwCapsule Hdr"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWSIG_SIGNHDR"
+ Value = "0"
+ Help = "FwCapsule Hdr Signature Calculation scheme\0-FwSig Cert signs hash of Rom Image and RomMap, FwRoot signs full FwSig Certificate. Fixed in Labels 0-008\1-Add FwCap hdr into a FwSig signature calculation, FwRoot signs FwSig certificate. Supported from Label 009"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWSIG_PADDING"
+ Value = "1"
+ Help = "RSA Signature padding scheme.\0-PKCS1v1.5, 1-PSS (default for Secure Flash Module labels 0 to 009), 2-xx reserved"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWKEY_FILE_FORMAT"
+ Value = "1"
+ Help = "Data format of Root FW Key FFS inside BIOS RTU (FV_BB).\0-n-modulus of RSA2048 key, 1-SHA256 Hash of RSA2048 n-modulus, 2-x.509 DER Certificate key, 3-xx reserved"
+ TokenType = Integer
+ TargetMAK = Yes
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "0"
+End
+
+TOKEN
+ Name = "FWKEY_FILE_FORMAT"
+ Value = "2"
+ Lock = Yes
+ Help = "Don't change the value."
+ TokenType = Integer
+ TargetMAK = Yes
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "1"
+End
+
+TOKEN
+ Name = "FWKEY_FILE_REPLACE"
+ Value = "1"
+ Help = "Directive to Cryptocon.exe to replace existing Root Platform Key inside BIOS.ROM with the Key used to sign FwCapsule"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "ROM_LAYOUT_EX"
+ Value = "$(BUILD_DIR)\RomLayoutEx.bin"
+ Help = "Name of the extended rom map file used to sign ROM image"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CRYPTCON"
+ Value = "$(SILENT)CryptoCon.exe"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "CRYPTCON"
+ Value = "$(SILENT)CryptoCon.exe -@"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "BRIEF" "=" "1"
+End
+
+TOKEN
+ Name = "CRYPTKEYGEN"
+ Value = "$(SILENT)keygen.exe"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "SecureMod_DIR"
+End
+
+MODULE
+ File = "SecureMod.mak"
+ Token = "CREATE_FWCAPSULE" "!=" "0"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FwCapsuleHdr.ffs"
+ Parent = "FV_MAIN"
+ Token = "CREATE_FWCAPSULE" "!=" "0"
+ Token = "LZMA_SUPPORT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\FwCapsuleHdr.ffs"
+ Parent = "FV_MAIN_OUTSIDE_NESTED"
+ Token = "CREATE_FWCAPSULE" "!=" "0"
+ Token = "LZMA_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CRYPTOCON_CMDLINE"
+ InvokeOrder = ReplaceParent
+ Help = "Cryptocon.exe command line to create signed FwCapsule"
+End
+
+ELINK
+ Name = "CRYPTOCON_CMDLINE_SIG"
+ InvokeOrder = ReplaceParent
+ Help = "Cryptocon.exe command line to create signed FwCapsule"
+End
+
+ELINK
+ Name = "CRYPTOCON_CMDLINE_MAP"
+ InvokeOrder = ReplaceParent
+ Help = "Cryptocon.exe command line to prepare embedded signature block FwCapsule"
+End
+
+ELINK
+ Name = "-c $(FWrootKey) -k $(FWpriv)"
+ Parent = "CRYPTOCON_CMDLINE"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-c2 -x $(FWpriv),$(FW_PFX_Password)"
+ Parent = "CRYPTOCON_CMDLINE"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-n"
+ Parent = "CRYPTOCON_CMDLINE"
+ Help = "-n ia a directive to replace Platform Root Key embedded inside BIOS.ROM with the Key used to sign new FwCapsule"
+ Token = "FWKEY_FILE_REPLACE" "=" "1"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-n -k $(FWpub)"
+ Parent = "CRYPTOCON_CMDLINE"
+ Token = "FWKEY_FILE_REPLACE" "=" "1"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-m -r $(ROM_LAYOUT_EX)"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-y"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ Token = "FWCAPSULE_FILE_FORMAT" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-l $(FWCAPSULE_IMAGE_ALLIGN)"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ Token = "FWCAPSULE_FILE_FORMAT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-q"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ Help = "Extended FwCapsule Hdr Signature Calculation scheme"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "0"
+ Token = "FWSIG_SIGNHDR" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-p"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ Help = "RSA-PSS Signature padding scheme. (Default - PKCS#1v1.5)"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "0"
+ Token = "FWSIG_PADDING" "=" "1"
+ Token = "FWSIG_SIGNHDR" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-p"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ Token = "FWCAPSULE_CERT_FORMAT" "=" "0"
+ Token = "FWSIG_SIGNHDR" "=" "0"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(CRYPTOCON_CMDLINE) -f $(UNSIGNED_BIOS_ROM) -o $(FWCAPSULE_FILE_NAME)"
+ Parent = "CRYPTOCON_CMDLINE_SIG"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(CRYPTOCON_CMDLINE) -f $(UNSIGNED_BIOS_ROM) -o $(UNSIGNED_BIOS_ROM)"
+ Parent = "CRYPTOCON_CMDLINE_MAP"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/Sredir/LegacySmmSredir.c b/Core/EM/Sredir/LegacySmmSredir.c
new file mode 100644
index 0000000..bd167e5
--- /dev/null
+++ b/Core/EM/Sredir/LegacySmmSredir.c
@@ -0,0 +1,474 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySmmSredir.c 6 12/08/14 3:36a Anbuprakashp $
+//
+// $Revision: 6 $
+//
+// $Date: 12/08/14 3:36a $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySmmSredir.c $
+//
+// 6 12/08/14 3:36a Anbuprakashp
+// [TAG] EIP192305
+// [Category] Improvement
+// [Description] Replacing SmmGetMemoryType usage in LegacySredir module
+// with AmiBufferValidationLib
+// [Files] LegacySredir.mak, LegacySmmSredir.c, LegacySredir_Setup.C
+//
+// 5 6/25/13 4:40a Rameshr
+// [TAG] EIP125655
+// [Category] Improvement
+// [Description] MMIO Address validated before reading or writing to the
+// MMIO region in the SW SMI handler
+// [Files] LegacySmmSredir.c, LegacySredir.dxs
+//
+// 4 4/10/12 12:49a Rameshr
+// [TAG] EIP84345
+// [Category] Improvement
+// [Description] Error checking and SMM dependency added
+// [Files] LegacySmmSredir.c, LegacySredir.dxs
+//
+// 3 6/17/11 4:41a Rameshr
+// [TAG] - EIP 47188
+// [Category]- IMPROVEMENT
+// [Description]- MMIO COM device access width SDL token support added
+// [Files] - legacysredir.c, LegacySredirSmm.c, LegacySredir_setup.c
+//
+// 2 9/24/10 1:37a Rameshr
+// [TAG] - EIP 44133
+// [Category]- BUG FIX & IMPROVEMENT
+// [Severity]- Major
+// [Symptom] - Flowcontrol and Terminal type is not working in Legacy
+// console redirection
+// [RootCause] - Baud rate value overwrites the Flowcontrol and Terminal
+// Type fields.
+// [Solution] - BaudRate programming done in EFI driver. So removed the
+// baud rate value passing into Sredir.bin
+// MMIO com device width added based on SDL token.
+// [Files] - LegacySmmSredir.c , Legacysredir.c, Legacysredir.sdl
+//
+// 1 3/05/10 4:17a Rameshr
+// Initial Check-in
+//
+// MMIO COM device support added.
+// EIP 33847
+//
+//
+//****************************************************************************
+//****************************************************************************
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: LegacySmmSredir.C
+//
+// Description: Legacy console redirection SMM support
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "token.h"
+#include "Protocol/LegacySredir.h"
+#include "AmiDxeLib.h"
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+#include <Protocol\SmmCpu.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol\SmmBase.h>
+#include <Protocol\SmmSwDispatch.h>
+#endif
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include <AmiSmm.h>
+#include <AmiBufferValidationLib.h>
+
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION>=0x4028B)
+EFI_SMM_BASE2_PROTOCOL *gSmmBase2;
+EFI_SMM_SYSTEM_TABLE2 *pSmst2;
+EFI_GUID gEfiSmmCpuProtocolGuid = EFI_SMM_CPU_PROTOCOL_GUID;
+EFI_SMM_CPU_PROTOCOL *gSmmCpu=NULL;
+#define RETURN(status) {return status;}
+#else
+EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+EFI_GUID gSwSmiCpuTriggerGuid = SW_SMI_CPU_TRIGGER_GUID;
+#define RETURN(status) {return ;}
+#endif
+
+#pragma pack(1)
+typedef struct {
+ UINT32 MMIOAddress;
+ UINT8 FuncNo;
+ UINT8 ReadWrite;
+ UINT8 Offset;
+ UINT8 Value;
+ UINT8 Count;
+ UINT32 BufferAddress;
+} SREDIR_INPUT_PARAMETER;
+#pragma pack()
+
+EFI_STATUS
+LegacySreDirInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS LegacySredirSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID LegacySredirSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: ReadSerialPort
+//
+// Description: Read the Data from Serial Port
+//
+// Input: SREDIR_INPUT_PARAMETER SredirParam
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadSerialPort(
+ IN OUT SREDIR_INPUT_PARAMETER *SredirParam
+)
+{
+
+ UINT32 TempValue;
+#if COM_MMIO_WIDTH == 4
+ TempValue=*(UINT32*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH));
+#else
+ #if COM_MMIO_WIDTH == 2
+ TempValue=*(UINT16*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH));
+ #else
+ TempValue=*(UINT8*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH));
+ #endif
+#endif
+
+ SredirParam->Value=(UINT8)TempValue;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: WriteSerialPort
+//
+// Description: Write the Data to Serial Port
+//
+// Input: SREDIR_INPUT_PARAMETER SredirParam
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteSerialPort(
+ IN OUT SREDIR_INPUT_PARAMETER *SredirParam
+)
+{
+ UINT32 TempValue=(UINT32)SredirParam->Value;
+
+#if COM_MMIO_WIDTH == 4
+ *(UINT32*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH))=TempValue;
+#else
+ #if COM_MMIO_WIDTH == 2
+ *(UINT16*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH))=(UINT16)TempValue;
+ #else
+ *(UINT8*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH))=(UINT8)TempValue;
+ #endif
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+// Procedure: WriteBufferSerialPort
+//
+// Description: Write the buffer of data to Serial port
+//
+// Input: SREDIR_INPUT_PARAMETER SredirParam
+//
+// Output:
+//
+// Returns:
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS WriteBufferSerialPort(
+ IN OUT SREDIR_INPUT_PARAMETER *SredirParam
+)
+{
+ UINT8 i;
+ UINT32 TempValue=0;
+ UINT8 *DataBuffer=(UINT8*)SredirParam->BufferAddress;
+ EFI_STATUS Status;
+
+ if(SredirParam->Count == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if( !DataBuffer ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Validate Input buffer is valid and not resides in SMRAM region
+ Status = AmiValidateMemoryBuffer ( (VOID*)DataBuffer, SredirParam->Count );
+ if( Status != EFI_SUCCESS ) {
+ RETURN(Status);
+ }
+
+ for(i=0;i<SredirParam->Count;i++) {
+ TempValue=*DataBuffer;
+
+#if COM_MMIO_WIDTH == 4
+ *(UINT32*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH))=TempValue;
+#else
+ #if COM_MMIO_WIDTH == 2
+ *(UINT16*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH))=(UINT16)TempValue;
+ #else
+ *(UINT8*)(SredirParam->MMIOAddress+(SredirParam->Offset*COM_MMIO_WIDTH))=(UINT8)TempValue;
+ #endif
+#endif
+ DataBuffer++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: LegacySredirSMIHandler
+//
+// Description: Legacy Serial Redirection Smm handler function
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+EFI_STATUS LegacySredirSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN CONST VOID *DispatchContext OPTIONAL,
+ IN OUT VOID *CommBuffer OPTIONAL,
+ IN OUT UINTN *CommBufferSize OPTIONAL
+#else
+VOID LegacySredirSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+#endif
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 Data;
+ UINT64 pCommBuff;
+ UINT32 HighBufferAddress = 0;
+ UINT32 LowBufferAddress = 0;
+ UINTN Cpu=(UINTN)-1;
+ SREDIR_INPUT_PARAMETER *SredirParam;
+#if PI_SPECIFICATION_VERSION < 0x1000A
+ EFI_SMM_CPU_SAVE_STATE *pCpuSaveState;
+ SW_SMI_CPU_TRIGGER *SwSmiCpuTrigger;
+ UINTN i;
+#endif
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+
+ Cpu = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->SwSmiCpuIndex;
+ //
+ // Found Invalid CPU number, return
+ //
+ if(Cpu == (UINTN)-1) RETURN(Status);
+
+ Status = gSmmCpu->ReadSaveState ( gSmmCpu, \
+ 4, \
+ EFI_SMM_SAVE_STATE_REGISTER_RBX, \
+ Cpu, \
+ &LowBufferAddress );
+
+ Status = gSmmCpu->ReadSaveState ( gSmmCpu, \
+ 4, \
+ EFI_SMM_SAVE_STATE_REGISTER_RCX, \
+ Cpu, \
+ &HighBufferAddress );
+
+ Data = ((EFI_SMM_SW_CONTEXT*)CommBuffer)->CommandPort;
+#else
+ for (i = 0; i < pSmst->NumberOfTableEntries; ++i) {
+ if (guidcmp(&pSmst->SmmConfigurationTable[i].VendorGuid,&gSwSmiCpuTriggerGuid) == 0) {
+ break;
+ }
+ }
+
+ //If found table, check for the CPU that caused the software Smi.
+ if (i != pSmst->NumberOfTableEntries) {
+ SwSmiCpuTrigger = pSmst->SmmConfigurationTable[i].VendorTable;
+ Cpu = SwSmiCpuTrigger->Cpu;
+ }
+
+ //
+ // Found Invalid CPU number, return
+ //
+ if(Cpu == (UINTN) -1) {
+ RETURN(Status);
+ }
+
+ Data = (UINT8)DispatchContext->SwSmiInputValue;
+
+ pCpuSaveState = pSmst->CpuSaveState;
+ HighBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.ECX;
+ LowBufferAddress = pCpuSaveState[Cpu].Ia32SaveState.EBX;
+
+#endif
+
+ pCommBuff = HighBufferAddress;
+ pCommBuff = Shl64(pCommBuff, 32);
+ pCommBuff += LowBufferAddress;
+ SredirParam =(SREDIR_INPUT_PARAMETER *)pCommBuff;
+
+ // Validate COM port register's MMIO address space are valid and not reside in SMRAM region
+ Status = AmiValidateMmioBuffer( (VOID*)SredirParam->MMIOAddress, 8*COM_MMIO_WIDTH );
+ if( Status != EFI_SUCCESS ) {
+ SredirParam->Value=0;
+ RETURN(Status);
+ }
+
+ switch(SredirParam->FuncNo) {
+
+ case 0x1:
+ ReadSerialPort(SredirParam);
+ break;
+
+ case 0x2:
+ WriteSerialPort(SredirParam);
+ break;
+
+ case 0x3:
+ Status = WriteBufferSerialPort(SredirParam);
+ break;
+
+ }
+
+ RETURN(Status);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: LegacySreDirInSmmFunction
+//
+// Description: Legacy Serial Redirection Smm entry point
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+// EFI System Table - Pointer to System Table
+//
+// Output: EFI_STATUS OR EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacySreDirInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ EFI_SMM_SW_DISPATCH2_PROTOCOL *pSwDispatch = NULL;
+ EFI_SMM_SW_REGISTER_CONTEXT SwContext;
+#else
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+#endif
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ Status = InitAmiSmmLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &gSmmBase2);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // We are in SMM, retrieve the pointer to SMM System Table
+ //
+ Status = gSmmBase2->GetSmstLocation( gSmmBase2, &pSmst2);
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pSmst2->SmmLocateProtocol( &gEfiSmmSwDispatch2ProtocolGuid, \
+ NULL, \
+ &pSwDispatch );
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = pSmst2->SmmLocateProtocol(&gEfiSmmCpuProtocolGuid, NULL, &gSmmCpu);
+
+#else
+ Status = pBS->LocateProtocol(&gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch);
+#endif
+
+ ASSERT_EFI_ERROR(Status);
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ InitAmiBufferValidationLib( ImageHandle, SystemTable );
+
+ SwContext.SwSmiInputValue = LEGACY_SREDIR_SWSMI;
+ Status = pSwDispatch->Register(pSwDispatch, LegacySredirSMIHandler, &SwContext, &Handle);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Sredir/LegacySredir.c b/Core/EM/Sredir/LegacySredir.c
new file mode 100644
index 0000000..78b3293
--- /dev/null
+++ b/Core/EM/Sredir/LegacySredir.c
@@ -0,0 +1,1422 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySredir.c 51 11/27/14 12:38a Srilathasc $
+//
+// $Revision: 51 $
+//
+// $Date: 11/27/14 12:38a $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySredir.c $
+//
+// 51 11/27/14 12:38a Srilathasc
+// [TAG] EIP193345
+// [Category] Improvement
+// [Description] Sredir bin module needs to be modified to make use ACPI
+// timer instead of 8254 timer
+// [Files] Sredir.asm, LegacySredir.c, csm.sdl, Sredir,bin
+//
+// 50 11/18/14 5:22a Anandakrishnanl
+// [TAG] EIP192802
+// [Category] Improvement
+// [Description] Support for legacy redirection by UART polling is added
+// for platforms in which serial port does not support IRQ on PIC Mode.
+// [Files] LegacySredir.c LegacySredir.h,LegacySredir.sdl
+//
+// 49 12/20/13 6:53a Divyac
+// [TAG] EIP147701
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] DOS redirection is not working in Shark Bay platform.
+// [RootCause] Wrong Value assigned to CTRLH_MAPPING Macro in
+// LegacySredir.c
+// [Solution] Assigned Value to CTRLH_MAPPING Macro, according to the
+// value defined for CTRLH_MAPPING Equate in Sredir.asm
+// [Files] LegacySredir.c
+//
+// 48 12/09/13 5:23a Divyac
+// [TAG] EIP129549
+// [Category] Improvement
+// [Description] Serial Redirection has dependency on Amilegacy16.bin
+// [Files] LegacySredir.c, LegacySredir.h, OR_MOD.EQU, SREDIR.ASM
+//
+// 47 12/09/13 4:45a Divyac
+// [TAG] EIP146051
+// [Category] Improvement
+// [Description] Refresh Key needs to be configured via SDL token for
+// Legacy Serial Redirection.
+// [Files] LegacySredir.c, LegacySredir_Setup.C, LegacySredir.h,
+// Sredir.bin
+//
+// 46 9/17/13 5:31a Rameshr
+// [TAG] EIP134807
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Redirection doesn't work with MMIO PCI device
+// [RootCause] CTRLH_MAPPING and MMIO_WORD_WIDTH both the equate uses
+// the same values.
+// [Solution] Modified CTRLH_MAPPING equate value
+// [Files] LegacySredir.c, Sredir.bin
+//
+// 45 5/30/13 2:46a Rameshr
+// [TAG] EIP123584
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] when active PCI console redirectioin support, keyboard not
+// response at POST stage
+// [RootCause] CSM16 region status changed by Legacy Serial Redirection
+// driver
+// [Solution] CSM16 region unlocked and locked again only when the
+// Legacy OS booting happens
+// [Files] Legacysredir.c
+//
+// 44 5/29/13 8:51a Srikantakumarp
+// [TAG] EIP122394
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] 0xE0000~0xEFFFF was overwrite by Legacy Serial Redirection
+// module.
+// [RootCause] LegacySerialRedirection driver assumed that
+// SerialBootcall.asm will be the first entry in CsmOem16Functions which
+// was wrong.
+// [Solution] Added a Signature check code for SerialBootCall.asm and
+// SredirBootFail.asm before it writes to the memory location
+// 0xE0000~0xEFFFF.
+// [Files] LegacySredir.c, SerialBootCall.asm, SredirBootFail.asm
+//
+// 43 9/17/12 7:27a Srikantakumarp
+// [TAG] EIP101094
+// [Category] Improvement
+// [Description] Generic change for sdl token to control the ctrl+H key
+// [Files] LegacySredir.c, LegacySredir.sdl, Sredir.asm
+//
+// 42 7/27/12 5:00a Rajeshms
+// [TAG] EIP95246
+// [Category] Improvement
+// [Description] RTS is used to control redirection flow when
+// FlowControl is enabled. When RTS is disabled (host not ready to accept
+// data) Redirection is disabled and when RTS is enabled (i.e CTS is set)
+// Redirection is enabled again.
+// [Files] Terminal.sdl, SerialIo.c, LegacySredir.c, SREDIR.ASM,
+// INT10REDIR.ASM, GRAPHREDIR.ASM
+//
+// 41 3/29/12 11:51p Rajeshms
+// [TAG] EIP84341
+// [Category] Improvement
+// [Description] Added Separate PCI_UART_INPUT_CLOCK token for setting
+// the Clock for PCI Serial UART.
+// [Files] Terminal.sdl, TerminalSetup.c, SerialIo.c, LegacySredir.c,
+// LegacySredir_Setup.c
+//
+// 40 2/29/12 11:37p Rameshr
+// [TAG] EIP82480
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System does not boot to Legacy Devices when Launch Video
+// OpRom DISABLED
+// [RootCause] Temp buffer address is not correct
+// [Solution] Redirection uses the 0x9F000 are temp buffer to save the
+// Video data. It should have been calculated in runtime based on the Base
+// memory allocated for sredir.bin
+// [Files] Legacysredir.c, LegacySredir.h
+//
+// 39 2/27/12 5:48a Jittenkumarp
+// [TAG] EIP81401
+// [Category] New Feature
+// [Description] Select Redirection After BIOS POST as BootLoader in
+// serial redirection, the behaviour is not same as Core8.
+// [Files] LegacySredir.c, LegacySredir.mak, LegacySredir.sdl,
+// LegacySredir_Setup.c, LegacySredir.h ,SerialBootCall.asm,
+// SredirBootFail.asm,GRAPHREDIR.ASM, INT10REDIR.ASM, OR_MOD.EQU,
+// SREDIR.ASM
+//
+// 38 12/28/11 10:52p Rajeshms
+// [TAG] EIP65051
+// [Category] Improvement
+// [Description] Data passing between EFI to Legacy has been changed in
+// Legacy console redirection as we are running out of registers to pass
+// parameters from EFI to Legacy.
+// [Files] LegacySredir.c, LegacySredir.h, LegacySredir_Setup.C,
+// SREDIR.ASM, OR_MOD.ASM, OR_MOD.EQU
+//
+// 37 12/12/11 2:06a Jittenkumarp
+// [TAG] EIP75982
+// [Category] New Feature
+// [Description] Redirection After BIOS POST item on the setup menu
+// [Files] Terminal.sd, Terminal.uni, LegacySredir.c,
+// LegacySredir_Setup.c
+//
+// 36 12/12/11 12:12a Jittenkumarp
+// [TAG] EIP75169
+// [Category] Improvement
+// [Description] Added ESC sequence support for Legacy Serial
+// Redirection.
+// [Files] LegacySredir.c, SREDIR.ASM, KEYREDIR.ASM
+//
+// 35 11/10/11 3:44a Rameshr
+// [TAG] EIP64383
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System will hang when dash redirection disconnect in legacy
+// environment
+// [RootCause] Waiting for the Transmitter Holding Register Empty bit to
+// set to send the next data.
+// [Solution] After retry count is reached, redirection disabled.
+// [Files] Graphredir.asm , Or_mod.asm , Sredir.asm , Legacysredir.c
+//
+// 34 11/09/11 11:52p Rajeshms
+// [TAG]- EIP 63665
+// [Category]-IMPROVEMENT
+// [Description]- Install Linux(Legacy OS) through remote. Some Linux
+// versions are forced to text mode to redirect and some are redirected in
+// graphics mode itself. It might not work for all the Linux versions as
+// the Linux kernel's behave differently.
+// [Files]- Terminal.sdl, Terminal.uni, Terminal.sd, LegacySredir.c,
+// LegacySredir.h, LegacySredir_Setup.c, GRAPHREDIR.ASM, INT10REDIR.ASM,
+// OR_MOD.ASM, OR_MOD.EQU, SREDIR.ASM
+//
+// 33 8/16/11 4:45p Davidd
+// [TAG] EIP55337
+// [Category] New Feature
+// [Description] Add optional code to clear keyboard buffer at
+// ReadyToBoot in Legacy Serial Redirection driver
+// [Files] LegacySredir.c
+// LegacySredir.h
+// LegacySredir.sdl
+// Sredir.asm
+//
+// 32 8/05/11 4:19a Rameshr
+// [TAG] - EIP 66389
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - System hangs at 0xAE when legacy serial redirection is
+// enable
+// [RootCause]- Before Legacy console redirection allocates the base
+// memory, some other driver allocates the base memory. So legacy console
+// redirection memory location moved down. But Sredir.bin thinks that seg
+// address of the sredir.bin is 0x9cc00. So system is hanging when we call
+// 0x9cc00:offset, as this region is not used to copy the sredir.bin
+// [Solution] - insteed of using the segment address from bin( hardcoded
+// value), Used the segment address we get it in runtime
+// [Files] - Legacysredir.c
+//
+// 31 7/13/11 2:38a Rajeshms
+// [TAG]- EIP 36444
+// [Category]- New Feature
+// [Description]- Add Setup option for Various Putty keyPad support in
+// Legacy console redirection driver
+// [Files]- LegacySredir.c, LegacySredir.h, LegacySredir_Setup.C,
+// SREDIR.ASM, KEYREDIR.ASM, OR_MOD.EQU, SREDIR.MAK
+//
+// 30 6/17/11 4:42a Rameshr
+// [TAG] - EIP 47188
+// [Category]- IMPROVEMENT
+// [Description]- MMIO COM device access width SDL token support added
+// [Files] - legacysredir.c, LegacySredirSmm.c, LegacySredir_setup.c
+//
+// 29 6/14/11 5:37a Rameshr
+// [TAG]- EIP 58140
+// [Category]- New Feature
+// [Description]- Add Setup option for Vt-UTF8 combo key support in Legacy
+// console redirection driver
+// [Files]- Sredir.asm, Legacysredir.c, Legacysredir.h,
+// Legacysredir_setup.c
+//
+// 28 2/11/11 4:58a Rameshr
+// [TAG]- EIP 53465
+// [Category]-IMPROVEMENT
+// [Description]- gLegacySredir variable name used as global and local
+// variable. Changed the Local Variable name
+// [Files]- LegacySredir.c
+//
+// 27 1/10/11 5:06a Rameshr
+// [TAG] - EIP 47188
+// [Category]- IMPROVEMENT
+// [Description]- MMIO COM device access width SDL token support added
+// [Files] - legacysredir.c, Sredir.asm
+//
+// 26 1/04/11 11:40p Rameshr
+// [TAG] - EIP 48120
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - Function key Ctrl + i do not work via serial redirection.
+// [RootCause]- Crtl+I is mapped to tab key in the redirection module
+// [Solution] - Provided the SDL token for Ctrl+I key mapping. Tab and
+// Ctrl+I can be selected through this sdl token
+// [Files] - Legacysredir.c, Legacysredir.sdl, Sredir.asm(Sredir.bin)
+//
+// 25 9/24/10 1:37a Rameshr
+// [TAG] - EIP 44133
+// [Category]- BUG FIX & IMPROVEMENT
+// [Severity]- Major
+// [Symptom] - Flowcontrol and Terminal type is not working in Legacy
+// console redirection
+// [RootCause] - Baud rate value overwrites the Flowcontrol and Terminal
+// Type fields.
+// [Solution] - BaudRate programming done in EFI driver. So removed the
+// baud rate value passing into Sredir.bin
+// MMIO com device width added based on SDL token.
+// [Files] - LegacySmmSredir.c , Legacysredir.c, Legacysredir.sdl
+//
+// 24 6/04/10 2:01a Rameshr
+// Sredir.bin Size increased.
+//
+// 23 6/01/10 1:05a Rameshr
+// Issue: Sredir.bin always allocated memory in basememory
+// Solution: If the redirection is enabled, allocaed the base memory and
+// copied the Sredir.bin
+// EIP 37831
+//
+// 22 5/03/10 1:55a Rameshr
+// Callback function added for read and write function of the Serial Port.
+// EIP 37850
+//
+// 21 5/03/10 1:21a Rameshr
+// Issue:Need to handle different Base Hz values for SerialStatusCode,
+// Terminal, and Legacy Serial Redirection.
+// Solution: Moved Uart input clock into Core.sdl token and used in all
+// the above modules.
+// EIP: 37332
+//
+// 20 4/13/10 4:13a Rameshr
+// Recorder Mode support added
+// EIP 36514
+// Some of the MMIO COM port has non standard bits implemented. These bits
+// are reset to 0 in Sredir.bin
+// EIP 37123
+//
+// 19 3/05/10 4:20a Rameshr
+// MMIO COM device support added.
+// EIP 33847
+//
+// 18 2/03/10 12:58a Rameshr
+// Int10 Workaround added based on SDL token.
+// EIP 33300
+//
+// 17 11/26/09 5:16a Rameshr
+// Legacy console redirection module size increased. So changing the base
+// address.
+// EIP:26405
+//
+// 16 10/23/09 10:46a Yul
+// EIP 24167 and EIP 26405
+// Serial redirection selection of 80X24 or 80X25 implemented based on
+// setup question instead of BUILD token
+//
+// 15 9/21/09 3:36p Rameshr
+// compile Error in legacy sredir when using VS 2008
+// EIP 27263
+//
+// 14 6/29/09 12:11p Rameshr
+// Coding Standard and File header updated.
+//
+// 13 4/21/09 12:17p Rameshr
+// Updated the Legacy console redirection to get the Databits,Parity and
+// Stop bits from the Terminal Driver Setup option
+// EIP20874-Legacy serial redirection is using hra coded values for
+// Databits as 8, Parity as None and Stop bit as 1
+//
+// 12 4/20/09 12:58p Rameshr
+// EIP 20251 -Ebda value inside Legacy Serial Redirection need to be
+// Dynamic
+//
+// Removed Unwanted code and updated with proper comments on Sredir.bin
+// Memory allocation.
+//
+// 11 3/09/09 3:09p Rameshr
+// Symptom: PXE boot messages are not displayed on local console.
+// Solution: Without Disabling the Legacy console redirection, Enable
+// redirection is not processed.
+// EIP:19089
+//
+// 10 12/24/08 3:51p Rameshraju
+//
+// 9 12/16/08 2:49a Iminglin
+// (EIP17767) The function value of FindLegacySreDirTable for compliance.
+//
+// 8 11/20/08 12:50p Rameshraju
+// SDL parameters passed from EFI to 16bit code
+// Added code to display whole screen before disalbing the redirection.
+// This is done based on the SDL token. default set to disabled.
+//
+// 7 29/10/08 4:27p Anandakrishnanl
+// Added Status Check For GetSetupValuesForLegacySredir so that Legacy
+// Serial Redirection Can be Enabled Based on Setup Options.
+//
+// 6 10/24/08 11:21a Rameshraju
+// Disable redirection is called only when the enabled redirection call is
+// done.
+//
+// 5 9/10/08 12:44p Pats
+// Reverted method for reserving memory for Sredir.bin to previous method
+// (AllocateEbda not used).
+//
+// 4 8/26/08 10:01a Pats
+// Removed call to GetInterruptAddress function since it is not used.
+//
+// 3 8/20/08 6:52p Pats
+// Fixed bug of setup values being loaded into uninitialized null pointer.
+// Changed EBDA allocation to use AllocateEbda function.
+//
+// 2 4/17/07 4:41a Rameshraju
+// PCIserial support added
+//
+//****************************************************************************
+//****************************************************************************
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: LegacySredir.C
+//
+// Description: Serial Redirection Compatibility Support Module entry point and interface functions
+//****************************************************************************
+//<AMI_FHDR_END>
+
+//
+// Disabling the warnings.
+//
+#pragma warning (disable : 4100 )
+
+#pragma warning (disable : 4306 )
+#include "Token.h"
+#include "Protocol/LoadedImage.h"
+#include "Protocol/LegacySredir.h"
+#include "Protocol/LegacyBios.h"
+#include "Protocol/LegacyBiosExt.h"
+#include "AmiDxeLib.h"
+
+
+#ifndef SERIAL_WRITE_ERROR_CHECK
+#define SERIAL_WRITE_ERROR_CHECK 1
+#ifndef MAXIMUM_SERIAL_WRITE_ERROR_COUNT
+#define MAXIMUM_SERIAL_WRITE_ERROR_COUNT 10
+#endif
+#endif
+
+#ifndef MAX_FAILURES_ALLOWED
+#define MAX_FAILURES_ALLOWED 5
+#endif
+
+
+#define CONVENTIONAL_MEMORY_TOP 0xA0000
+#define SREDIR_BIN_SIZE 0x3C00
+
+//
+//Parameter passed to sredir.bin
+//
+#define DISPLAY_SCREEN 0x0001
+#define INT10_WORKAROUND 0x0002
+#define MMIO_DEVICE 0x0004
+#define SERIAL_READWRITE_CALLBACK 0x0008
+#define CTRLI_MAPPING 0x0010
+#define MMIO_BYTE_WIDTH 0x0000
+#define MMIO_WORD_WIDTH 0x0020
+#define MMIO_DWORD_WIDTH 0x0040
+#define SERIAL_ERROR_CHECK 0x0080
+#define ESC_SEQUENCES 0x0100
+#define CTRLH_MAPPING 0x0200
+
+EFI_GUID gEfiLoadedImageGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+EFI_GUID gEfiFirmwareVolumeProtocol = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+
+UINT32 Int10hAddress;
+UINT32 Int0chAddress;
+UINT32 Int14hAddress;
+VOID *EmbeddedRom;
+UINTN EmbeddedRomSize;
+
+AMI_LEGACYSREDIR_TABLE *mLegacySreDirHeader;
+EFI_EVENT SreDir;
+BOOLEAN RedirectionStatus=FALSE;
+UINTN gSreDirImageStart=0;
+EFI_LEGACY_BIOS_PROTOCOL *pLegacy=NULL;
+BOOLEAN IsCopied = FALSE;
+BOOLEAN IsDataCopied = FALSE;
+extern BOOLEAN IsPciDevice;
+BOOLEAN LegacyOSBooting=FALSE;
+
+//
+// The GetSetupValuesForLegacySredir procedure to get the setup values
+//
+extern EFI_STATUS GetSetupValuesForLegacySredir(
+ OUT AMI_COM_PARAMETERS *AmiComParameters
+);
+
+EFI_STATUS
+InitilizeNonCommonSerialRegsiters(
+ IN AMI_COM_PARAMETERS *AmiComParameters
+);
+
+
+EFI_STATUS
+EnableLegacySredir (
+ IN AMI_LEGACY_SREDIR_PROTOCOL * This
+);
+
+EFI_STATUS
+DisableLegacySredir (
+ IN AMI_LEGACY_SREDIR_PROTOCOL * This
+);
+
+EFI_STATUS
+LegacySreDirInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+EFI_STATUS FindLegacySredirRom(
+ UINT16 ModuleId, UINT16 VendorId, UINT16 DeviceId,
+ VOID **ImageStart, UINT32 *ImageSize
+);
+
+EFI_STATUS DataCopiedToCsm16Function(
+ UINTN StructStartAddress,
+ AMI_COM_PARAMETERS *AmiComParameters
+);
+
+//
+// AMI_LEGACY_SREDIR_PROTOCOL
+//
+AMI_LEGACY_SREDIR_PROTOCOL gLegacySredir = {
+ EnableLegacySredir,
+ DisableLegacySredir
+};
+#define DLAB_BIT 1
+#define LSR_OFFSET 0x05
+#define LCR_OFFSET 0x03
+#define DIV_MSB 0x01
+#define DIV_LSB 0
+
+//
+// ACPI PM timer signature,for 'TM' the ASCII code is 0x544D
+// the MSB bit of the signature denotes 24bit/32bit timer
+//
+#if ACPI_SUPPORT
+#if FACP_FLAG_TMR_VAL_EXT
+#define TIMER_SIGNATURE_32BIT 0xD44D0000
+#else
+#define TIMER_SIGNATURE_24BIT 0x544D0000
+#endif
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: DataCopiedToCsm16Function
+//
+// Description: This function copies the segment and offset address of sredir.bin
+//
+// Input: UINTN StructStartAddress
+// AMI_COM_PARAMETERS *AmiComParameters
+//
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS DataCopiedToCsm16Function(
+ IN UINTN StructStartAddress,
+ IN AMI_COM_PARAMETERS *AmiComParameters
+)
+{
+ EFI_STATUS Status;
+ UINTN ImageSize = 0x10;
+ UINT32 LockUnlockAddr, LockUnlockSize;
+ UINT16 *Addr;
+ UINT32 Addr16;
+ EFI_LEGACY_BIOS_EXT_PROTOCOL *BiosExtensions = NULL;
+ UINT8 *RpSBCSig = "$SBC";
+ UINT8 *RpSBFSig = "$SBF";
+ //
+ // Check Data already copied into CSM16 call backfunction
+ //
+ if(IsDataCopied) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ //Data copied into CSM16 callback function
+ //
+ IsDataCopied=TRUE;
+
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosExtProtocolGuid,\
+ NULL,\
+ &BiosExtensions);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = BiosExtensions->Get16BitFuncAddress(
+ CSM16_OEM_BEFORE_CALL_BOOT_VECTOR, \
+ &Addr16);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = BiosExtensions->UnlockShadow(
+ (UINT8*)Addr16, \
+ ImageSize, \
+ &LockUnlockAddr, \
+ &LockUnlockSize);
+
+ ASSERT_EFI_ERROR(Status);
+
+
+ while(Addr16 < 0xf0000)
+ {
+ if (!MemCmp((UINT8*)Addr16, RpSBCSig, 4))
+ {
+ Addr16 = Addr16+4; // Skip the Signature "$SBC"
+ Addr = (UINT16*) Addr16;
+ *Addr =((StructStartAddress>>4) & 0xF000);
+ Addr++;
+ *Addr =(UINT16)StructStartAddress;
+ Addr++;
+ *Addr = (UINT16)(((UINT8 *)&(AmiComParameters->Flag)) - ((UINT8*)(AmiComParameters)));
+ break;
+ }
+ Addr16++;
+ }
+
+ Status = BiosExtensions->Get16BitFuncAddress(
+ CSM16_OEM_ON_BOOT_FAIL, \
+ &Addr16);
+
+ if (EFI_ERROR(Status))
+ return Status;
+
+
+
+ while(Addr16 < 0xf0000)
+ {
+ if (!MemCmp((UINT8*)Addr16, RpSBFSig, 4))
+ {
+ Addr16 = Addr16+4; // Skip the Signature "$SBF"
+ Addr = (UINT16*) Addr16;
+ *Addr =((StructStartAddress>>4) & 0xF000);
+ Addr++;
+ *Addr =(UINT16)StructStartAddress;
+ Addr++;
+ *Addr = (UINT16)(((UINT8 *)&(AmiComParameters->Flag)) - ((UINT8*)(AmiComParameters))) ;
+ break;
+ }
+ Addr16++;
+ }
+ BiosExtensions->LockShadow(LockUnlockAddr, LockUnlockSize);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: CopySredirBinIntoBaseMemory
+//
+// Description: This function copies the Sredir.bin into Base Memory
+//
+// Input: This
+// Indicates the AMI_LEGACY_SREDIR_PROTOCOL instance.
+//
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CopySredirBinIntoBaseMemory (
+ IN AMI_LEGACY_SREDIR_PROTOCOL * This
+)
+{
+
+ VOID *SreDirImageStart = NULL;
+ UINT32 SreDirImageSize = 0;
+ UINT16 EbdaSeg = (UINT16)(*(UINT16*)0x40E);
+ UINT8 *EbdaAddress = (UINT8*)((UINTN)EbdaSeg<<4);
+ UINT32 EbdaSize = (*EbdaAddress)<<10;
+ UINT32 NewEbdaAdd;
+ UINT32 NewEbdaSeg;
+ EFI_STATUS Status;
+
+
+ //
+ // Check Sredir.bin already copied into Memory
+ //
+ if(IsCopied) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ //Sredir.bin copied into Base Memory
+ //
+ IsCopied=TRUE;
+
+ //
+ // Sredir.bin is placed in below A0000. It will not be reported as EBDA memory.
+ // So sredir place will not be changed when there is allocateEbda.
+ //
+ if(EbdaSeg== 0) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ //New EBDA Address will be EbdaAddress - Sredir.bin
+ //
+ NewEbdaAdd = (EbdaSeg<<4)-SREDIR_BIN_SIZE; //To allocate memory for sredir.bin
+ NewEbdaSeg = NewEbdaAdd>>4;
+
+ //
+ //We are taking memory for the Sredir.bin from the base memory. So adjust the Base Memory
+ //
+ *(UINT16*)0x413 = ((*(UINT16*)0x413) - (SREDIR_BIN_SIZE >> 10));
+
+ //
+ //Update the New EBDA address
+ //
+ *(UINT16*)0x40e = (UINT16)NewEbdaSeg;
+
+ //
+ //Move the OLD ebda data to new EBDA area. We have not changed the EBDA Size here. This makes
+ //Sredir.bin area will not be moved any where.it means Sredir.bin is not placed under EBDA area.
+ //
+ pBS->CopyMem((VOID*)NewEbdaAdd,(VOID*)(EbdaSeg<<4),EbdaSize);
+
+ Status = FindLegacySredirRom(SREDIR_MODULEID, SREDIR_VENDORID, SREDIR_DEVICEID,&SreDirImageStart, &SreDirImageSize);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Copy the Sredir.bin Base Memory.
+ //
+ pBS->CopyMem((VOID*)(NewEbdaAdd+EbdaSize), SreDirImageStart, SreDirImageSize);
+ gSreDirImageStart = (UINTN)(NewEbdaAdd+EbdaSize);
+
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitilizeBuadRate
+//
+// Description: This Function is used to Initilize the Baud Rate of the COM port
+//
+// Input: AMI_COM_PARAMETERS AmiComParameters
+//
+//
+// Output: Com port Baud Rate Initilized.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitilizeBuadRate(
+ OUT AMI_COM_PARAMETERS *AmiComParameters
+)
+{
+
+ UINT8 Data8;
+ UINT16 Divisor;
+ UINTN Remainder;
+ UINTN UartInputClock;
+
+ if( IsPciDevice ) {
+#ifdef PCI_UART_INPUT_CLOCK
+ UartInputClock = PCI_UART_INPUT_CLOCK;
+#else
+ //
+ // Set the default value((24000000/13)MHz input clock)
+ // if the PCI_UART_INPUT_CLOCK SDL token is not present.
+ //
+ UartInputClock=1843200;
+#endif
+ } else {
+#ifdef UART_INPUT_CLOCK
+ UartInputClock=UART_INPUT_CLOCK;
+#else
+ //
+ // Set the default value((24000000/13)MHz input clock)
+ // if the UART_INPUT_CLOCK SDL token is not present.
+ //
+ UartInputClock=1843200;
+#endif
+ }
+
+ //
+ // Compute the baud rate divisor.
+ //
+ Divisor = (UINT32) Div64 (UartInputClock,
+ ((UINT32)AmiComParameters->Baudrate * 16),
+ &Remainder);
+ if ( Remainder ) {
+ Divisor += 1;
+ }
+
+ if ((Divisor == 0) || (Divisor & 0xffff0000)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for the MMIO device. If it's MMIO device do MMIO access to
+ // Read and Write to the COM port Regsiters. Otherwise use IO access
+ // to Read and Write to Com port Registers.
+ //
+ if(AmiComParameters->MMIOBaseAddress != 0) {
+ //
+ // Programm Serial port.
+ // Set Line Control Register (LCR)
+ //
+ Data8 = DLAB_BIT << 7;
+
+#if COM_MMIO_WIDTH == 4
+ *(UINT32*)(AmiComParameters->MMIOBaseAddress+(LCR_OFFSET*COM_MMIO_WIDTH))=(UINT32)Data8;
+#else
+ #if COM_MMIO_WIDTH == 2
+ *(UINT16*)(AmiComParameters->MMIOBaseAddress+(LCR_OFFSET*COM_MMIO_WIDTH))=(UINT16)Data8;
+ #else
+ *(UINT8*)(AmiComParameters->MMIOBaseAddress+(LCR_OFFSET*COM_MMIO_WIDTH))=(UINT8)Data8;
+ #endif
+#endif
+
+ //
+ //Program the Baud Rate
+ //
+
+#if COM_MMIO_WIDTH == 4
+ *(UINT32*)(AmiComParameters->MMIOBaseAddress+(DIV_LSB*COM_MMIO_WIDTH))=(UINT32)Divisor & 0xFF;
+ *(UINT32*)(AmiComParameters->MMIOBaseAddress+(DIV_MSB*COM_MMIO_WIDTH))=(UINT32)Divisor >> 8;
+#else
+ #if COM_MMIO_WIDTH == 2
+ *(UINT16*)(AmiComParameters->MMIOBaseAddress+(DIV_LSB*COM_MMIO_WIDTH))=(UINT16)Divisor & 0xFF;
+ *(UINT16*)(AmiComParameters->MMIOBaseAddress+(DIV_MSB*COM_MMIO_WIDTH))=(UINT16)Divisor >> 8;
+
+ #else
+ *(UINT8*)(AmiComParameters->MMIOBaseAddress+(DIV_LSB*COM_MMIO_WIDTH))=(UINT8)Divisor & 0xFF;
+ *(UINT8*)(AmiComParameters->MMIOBaseAddress+(DIV_MSB*COM_MMIO_WIDTH))=(UINT8)(Divisor >> 8);
+ #endif
+#endif
+
+ //
+ // Clear DLAB bit in LCR
+ //
+ Data8 &= ~((UINT8)DLAB_BIT << 7);
+
+#if COM_MMIO_WIDTH == 4
+ *(UINT32*)(AmiComParameters->MMIOBaseAddress+(LCR_OFFSET*COM_MMIO_WIDTH))=(UINT32)Data8;
+#else
+ #if COM_MMIO_WIDTH == 2
+ *(UINT16*)(AmiComParameters->MMIOBaseAddress+(LCR_OFFSET*COM_MMIO_WIDTH))=(UINT16)Data8;
+ #else
+ *(UINT8*)(AmiComParameters->MMIOBaseAddress+(LCR_OFFSET*COM_MMIO_WIDTH))=(UINT8)Data8;
+ #endif
+#endif
+
+ } else {
+ //
+ // Programm Serial port.
+ // Set Line Control Register (LCR)
+ //
+ Data8 = DLAB_BIT << 7;
+ IoWrite8(AmiComParameters->BaseAddress + LCR_OFFSET, Data8 );
+
+ //
+ //Program the Baud Rate
+ //
+ IoWrite8(AmiComParameters->BaseAddress + DIV_LSB, Divisor & 0xFF);
+ IoWrite8(AmiComParameters->BaseAddress + DIV_MSB, Divisor >> 8);
+
+ //
+ // Clear DLAB bit in LCR
+ //
+ Data8 &= ~((UINT8)DLAB_BIT << 7);
+ IoWrite8(AmiComParameters->BaseAddress + LCR_OFFSET, Data8 );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: EnableLegacySredir
+//
+// Description: This function is used for enabling the legacy Serial Redirection
+// This function contains calls for Intialising Serial ports and
+// hooking the interrupts which are required for purpose of Redirection
+//
+// Input: This
+// Indicates the AMI_LEGACY_SREDIR_PROTOCOL instance.
+//
+//
+// Output: EFI_SUCCESS
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EnableLegacySredir (
+ IN AMI_LEGACY_SREDIR_PROTOCOL * This
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_IA32_REGISTER_SET RegSet;
+ AMI_COM_PARAMETERS AmiComParameters;
+ UINT32 SdlParameters=0;
+ AMI_COM_PARAMETERS *SredirSetupComParameters;
+ UINTN StructStartAddress = NULL;
+
+ if(RedirectionStatus) {
+ return EFI_NOT_FOUND;
+ }
+
+ if(pLegacy==NULL) {
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &pLegacy);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ //
+ //Getting Setup values from terminal module
+ //
+ Status = GetSetupValuesForLegacySredir(&AmiComParameters);
+
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+ //
+ //Copy the Sredir.bin into Base Memory
+ //
+ Status=CopySredirBinIntoBaseMemory(This);
+
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+
+ //
+ //Serial Redirection starting Address
+ //
+ mLegacySreDirHeader = (AMI_LEGACYSREDIR_TABLE*)gSreDirImageStart;
+
+ if (mLegacySreDirHeader == NULL) return EFI_NOT_FOUND;
+
+#if DISPLAY_WHOLE_SCREEN
+ SdlParameters |= DISPLAY_SCREEN;
+#endif
+#if TRAP_INT10_WORKAROUND
+ SdlParameters |= INT10_WORKAROUND;
+#endif
+#if SERIAL_READ_WRITE_CALLBACK
+ SdlParameters |= SERIAL_READWRITE_CALLBACK;
+#endif
+#if CTRLI_KEY_MAPPING
+ SdlParameters |= CTRLI_MAPPING;
+#endif
+#if CTRLH_KEY_MAPPING
+ SdlParameters |= CTRLH_MAPPING;
+#endif
+#if SERIAL_WRITE_ERROR_CHECK
+ SdlParameters |= SERIAL_ERROR_CHECK;
+#endif
+#if OEM_ESC_SEQUENCES
+ SdlParameters |= ESC_SEQUENCES;
+#endif
+#if COM_MMIO_WIDTH == 1
+ SdlParameters |= MMIO_BYTE_WIDTH;
+#endif
+#if COM_MMIO_WIDTH == 2
+ SdlParameters |= MMIO_WORD_WIDTH;
+#endif
+#if COM_MMIO_WIDTH == 4
+ SdlParameters |= MMIO_DWORD_WIDTH;
+#endif
+
+
+ Status=InitilizeBuadRate(&AmiComParameters);
+
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+
+ //
+ //Initilize the Non Standard Serial Port Regsiters.
+ //
+ Status = InitilizeNonCommonSerialRegsiters(&AmiComParameters);
+
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+
+ if(AmiComParameters.MMIOBaseAddress != 0) {
+ SdlParameters |= MMIO_DEVICE;
+ AmiComParameters.BaseAddress = 0;
+ AmiComParameters.SwSMIValue = LEGACY_SREDIR_SWSMI;
+#if defined(SW_SMI_IO_ADDRESS)
+ AmiComParameters.SwSMIPort = SW_SMI_IO_ADDRESS;
+#endif
+ }
+
+
+ AmiComParameters.SdlParameters = SdlParameters;
+
+ AmiComParameters.SredirBinSize=SREDIR_BIN_SIZE;
+ AmiComParameters.RefreshScreenKey = REFRESH_SCREEN_KEY;
+ AmiComParameters.UartPollingRedirection = UART_POLLING_REDIRECTION;
+
+ //
+ // Transfer the Setup Values and Com Parameters from EFI to Legacy.
+ //
+
+ SredirSetupComParameters = (AMI_COM_PARAMETERS *)(gSreDirImageStart + (mLegacySreDirHeader->SreDirEfiToLegacyOffset));
+
+ pBS->CopyMem((VOID*)SredirSetupComParameters, (VOID*)&AmiComParameters, sizeof(AMI_COM_PARAMETERS));
+
+ StructStartAddress = (UINTN )SredirSetupComParameters;
+
+ if(LegacyOSBooting) {
+ Status=DataCopiedToCsm16Function(StructStartAddress, &AmiComParameters);
+
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+ }
+
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = LEGACY_SreDirInitializeSerialPort;
+
+ RegSet.X.BX = MAXIMUM_SERIAL_WRITE_ERROR_COUNT;
+ RegSet.X.CX = MAX_FAILURES_ALLOWED;
+#if ACPI_SUPPORT
+ #if FACP_FLAG_TMR_VAL_EXT
+ RegSet.E.EDX = TIMER_SIGNATURE_32BIT;
+ #else
+ RegSet.E.EDX = TIMER_SIGNATURE_24BIT;
+ #endif
+#if ACPI_TIMER_IN_LEGACY_SUPPORT
+ RegSet.X.DX = PM_TMR_BLK_ADDRESS;
+#else
+ RegSet.X.DX = 0;
+#endif
+#endif
+
+ Status = pLegacy->FarCall86(pLegacy,
+ (UINT16)(gSreDirImageStart>>4),
+ mLegacySreDirHeader->SreDirOffset,
+ &RegSet,
+ NULL,
+ 0);
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = LEGACY_SerialRedirection;
+
+
+ Status = pLegacy->FarCall86(pLegacy,
+ (UINT16)(gSreDirImageStart>>4),
+ mLegacySreDirHeader->SreDirOffset,
+ &RegSet,
+ NULL,
+ 0);
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+/*
+ //
+ // Intel wants to have interface to get the Original Int10, Int0c and Int14
+ // Address. By default this code is disabled.
+ //
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+
+ RegSet.X.AX = LEGACY_GetInterruptAddress; //returns Int10,Int0c,Int14 original
+ //vector address in EAX,EBX and ECX
+
+ Status = pLegacy->FarCall86(pLegacy,
+ (UINT16)(gSreDirImageStart>>4),
+ mLegacySreDirHeader->SreDirOffset,
+ &RegSet,
+ NULL,
+ 0);
+
+ Int10hAddress = RegSet.E.EAX;
+ Int0chAddress = RegSet.E.EBX;
+ Int14hAddress = RegSet.E.ECX;
+*/
+ RedirectionStatus=TRUE;
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: DisableLegacySredir
+//
+// Description: This function is used to disable the Legacy Serial redirection
+// This function contains calls for functions which are used to
+// release the interrupts which are used for Serial Redirection
+//
+// Input: This
+// Indicates the AMI_LEGACY_SREDIR_PROTOCOL instance.
+//
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DisableLegacySredir (
+ IN AMI_LEGACY_SREDIR_PROTOCOL * This
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_IA32_REGISTER_SET RegSet;
+
+ if(!RedirectionStatus) {
+ return EFI_NOT_FOUND;
+ }
+
+ if(pLegacy==NULL) {
+ Status = pBS->LocateProtocol(&gEfiLegacyBiosProtocolGuid, NULL, &pLegacy);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ //
+ //Serial Redirection starting Address
+ //
+ mLegacySreDirHeader = (AMI_LEGACYSREDIR_TABLE*)gSreDirImageStart;
+
+ if (mLegacySreDirHeader == NULL) {
+ return EFI_NOT_FOUND;
+ }
+
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = LEGACY_ReleaseSerialRedirection;
+
+ Status = pLegacy->FarCall86(pLegacy,
+ (UINT16)(gSreDirImageStart>>4),
+ mLegacySreDirHeader->SreDirOffset,
+ &RegSet,
+ NULL,
+ 0);
+
+ RedirectionStatus=FALSE;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FindLegacySredirRom
+//
+// Description: This function searches for ROM within the data previously loaded
+// from the main FV image and returns its pointer and size.
+//
+// Input: Module Id
+// Vendor Id
+// Device Id
+// Image Start Address
+// Image Size
+//
+// Output: EFI_SUCCESS or EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS FindLegacySredirRom(
+ UINT16 ModuleId, UINT16 VendorId, UINT16 DeviceId,
+ VOID **ImageStart, UINT32 *ImageSize
+)
+{
+#pragma pack(push,1)
+ typedef struct{
+ UINT16 ModuleId, VendorId, DeviceId;
+ UINT32 Size;
+ } OPROM_HEADER;
+#pragma pack(pop)
+
+ OPROM_HEADER *Header;
+ for( Header = (OPROM_HEADER*)EmbeddedRom
+ ; (UINT8*)Header<(UINT8*)EmbeddedRom+EmbeddedRomSize
+ ; Header = (OPROM_HEADER*)((UINT8*)(Header+1)+Header->Size)
+ )
+ {
+ if ( Header->ModuleId==ModuleId
+ && Header->VendorId==VendorId
+ && Header->DeviceId==DeviceId
+ )
+ {
+ *ImageStart = Header+1;
+ *ImageSize=Header->Size;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Legacy_OS_SerialRedirection
+//
+// Description: This function is used for Legacy Serial Redirection
+//
+// Input: EFI_Hanlde - Image Handle
+// EFI_System_Table - Pointer to System Table
+//
+// Output: EFI_SUCCESS or EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS Legacy_OS_SerialRedirection (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+
+ EFI_STATUS Status;
+ AMI_LEGACY_SREDIR_PROTOCOL *LegacySredir=NULL;
+
+ Status=pBS->LocateProtocol(&gAmiLegacySredirProtocolGuid, NULL, &LegacySredir);
+
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ LegacyOSBooting=TRUE;
+ Status = LegacySredir->EnableLegacySredir(LegacySredir);
+
+ return Status;
+
+}
+
+#if CLEAR_LEGACYSREDIR_KB_BUFFER_AT_READYTOBOOT
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ClearKbCharBuffer
+//
+// Description: Function to clear the Keyboard character buffer
+// (in the 16-bit Serial Redirection module)
+//
+// Input: IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ClearKbCharBuffer (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_IA32_REGISTER_SET RegSet;
+
+ //
+ // Serial Redirection starting Address
+ //
+ mLegacySreDirHeader = (AMI_LEGACYSREDIR_TABLE*)gSreDirImageStart;
+
+ if (mLegacySreDirHeader != NULL) {
+ pBS->SetMem(&RegSet, sizeof (EFI_IA32_REGISTER_SET), 0);
+ RegSet.X.AX = LEGACY_ClearKbCharBuffer;
+
+ pLegacy->FarCall86(pLegacy,
+ mLegacySreDirHeader->SreDirSegment,
+ mLegacySreDirHeader->SreDirOffset,
+ &RegSet,
+ NULL,
+ 0);
+ }
+
+ pBS->CloseEvent(Event);
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Name: LegacySreDirNotInSmmFunction
+//
+// Description: Legacy Serial Redirection Non Smm entry point
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+// EFI System Table - Pointer to System Table
+//
+// Output: EFI_STATUS OR EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacySreDirNotInSmmFunction(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImage;
+ EFI_GUID gFile;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *pFV;
+ UINT32 Authentication;
+ EFI_HANDLE NewHandle;
+#if CLEAR_LEGACYSREDIR_KB_BUFFER_AT_READYTOBOOT
+ EFI_EVENT ReadyToBootEvent;
+#endif
+
+
+ Status = pBS->HandleProtocol(ImageHandle, &gEfiLoadedImageGuid, &LoadedImage);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Now we have EFI_DEVICE_PATH *LoadedImage->FilePath
+ //
+ gFile = ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(LoadedImage->FilePath))->NameGuid;
+
+ //
+ // Get the Firmware Volume Protocol
+ //
+ Status = pBS->HandleProtocol (
+ LoadedImage->DeviceHandle,
+ &gEfiFirmwareVolumeProtocol,
+ &pFV
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Read section with Legacy ROMs
+ //
+ EmbeddedRom = NULL; // make ReadSection allocate memory
+ EmbeddedRomSize = 0;
+ Status = pFV->ReadSection (
+ pFV,
+ &gFile,
+ EFI_SECTION_RAW,
+ 0,
+ &EmbeddedRom,
+ &EmbeddedRomSize,
+ &Authentication);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ NewHandle = NULL;
+ Status = pBS->InstallProtocolInterface (
+ &NewHandle,
+ &gAmiLegacySredirProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gLegacySredir
+ );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+#if CLEAR_LEGACYSREDIR_KB_BUFFER_AT_READYTOBOOT
+ //
+ // Register the ReadyToBoot event function to clear the Keyboard
+ // character buffer (in the 16-bit Serial Redirection module)
+ //
+#if defined(EFI_EVENT_SIGNAL_READY_TO_BOOT) && (EFI_SPECIFICATION_VERSION < 0x20000)
+ pBS->CreateEvent(
+ EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ TPL_NOTIFY,
+ ClearKbCharBuffer,
+ NULL,
+ &ReadyToBootEvent
+ );
+#else
+ CreateReadyToBootEvent(TPL_CALLBACK,
+ ClearKbCharBuffer,
+ NULL,
+ &ReadyToBootEvent
+ );
+#endif
+#endif
+
+#if defined(EFI_EVENT_SIGNAL_READY_TO_BOOT) && (EFI_SPECIFICATION_VERSION < 0x20000)
+ Status = pBS->CreateEvent(
+ EFI_EVENT_SIGNAL_LEGACY_BOOT,
+ TPL_CALLBACK,
+ Legacy_OS_SerialRedirection,
+ NULL,
+ &SreDir
+ );
+#else
+ Status = CreateLegacyBootEvent(
+ TPL_CALLBACK,
+ Legacy_OS_SerialRedirection,
+ NULL,
+ &SreDir
+ );
+#endif
+ ASSERT_EFI_ERROR(Status);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: LegacySredirEntryPoint
+//
+// Description: Legacy Serial Redirection driver entry point
+//
+// Input: Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT
+// EFI System Table - Pointer to System Table
+//
+// Output: EFI_STATUS OR EFI_NOT_FOUND
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LegacySredirEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ InitAmiLib(ImageHandle, SystemTable);
+ return InitSmmHandler(ImageHandle, SystemTable, LegacySreDirInSmmFunction, LegacySreDirNotInSmmFunction);
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Sredir/LegacySredir.chm b/Core/EM/Sredir/LegacySredir.chm
new file mode 100644
index 0000000..42fa76d
--- /dev/null
+++ b/Core/EM/Sredir/LegacySredir.chm
Binary files differ
diff --git a/Core/EM/Sredir/LegacySredir.cif b/Core/EM/Sredir/LegacySredir.cif
new file mode 100644
index 0000000..ca866ba
--- /dev/null
+++ b/Core/EM/Sredir/LegacySredir.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "Legacy Serial Redirection"
+ category = eModule
+ LocalRoot = "Core\EM\Sredir\"
+ RefName = "LEGACYSREDIR"
+[files]
+"LegacySredir.mak"
+"LegacySredir.sdl"
+"LegacySredir.dxs"
+"LegacySredir.c"
+"LegacySmmSredir.c"
+"LegacySredir.chm"
+"SerialBootCall.asm"
+"SredirBootFail.asm"
+[parts]
+"LSREDIR_BOARD"
+"LSREDIR_BIN"
+"LEGACY_SREDIR_PROTOCOL"
+<endComponent>
diff --git a/Core/EM/Sredir/LegacySredir.dxs b/Core/EM/Sredir/LegacySredir.dxs
new file mode 100644
index 0000000..5532cd0
--- /dev/null
+++ b/Core/EM/Sredir/LegacySredir.dxs
@@ -0,0 +1,104 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySredir.dxs 7 6/25/13 4:41a Rameshr $
+//
+// $Revision: 7 $
+//
+// $Date: 6/25/13 4:41a $
+//**********************************************************************
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySredir.dxs $
+//
+// 7 6/25/13 4:41a Rameshr
+// [TAG] EIP125655
+// [Category] Improvement
+// [Description] MMIO Address validated before reading or writing to the
+// MMIO region in the SW SMI handler
+// [Files] LegacySmmSredir.c, LegacySredir.dxs
+//
+// 6 4/10/12 12:50a Rameshr
+// [TAG] EIP84345
+// [Category] Improvement
+// [Description] Error checking and SMM dependency added
+// [Files] LegacySmmSredir.c, LegacySredir.dxs
+//
+// 5 3/05/10 4:19a Rameshr
+// MMIO COM device support added.
+// EIP 33847
+//
+// 4 6/29/09 12:11p Rameshr
+// Coding Standard and File header updated.
+//
+// 3 12/24/08 3:51p Rameshraju
+// Added the dependency for LegacyBios
+//
+// 2 4/17/07 4:41a Rameshraju
+// PCIserial support added
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//**********************************************************************
+// Name: LegacySredir.dxs
+//
+// Description: Dependancy Expression file for Legacy Serial Redirection
+//
+//**********************************************************************
+//<AMI_FHDR_END>
+
+#include <Protocol/LegacyRegion.h>
+#include <Protocol/LegacyInterrupt.h>
+#include <Protocol/Legacy8259.h>
+#include <Protocol/FirmwareVolume.h>
+#include <Protocol/Cpu.h>
+#include <Protocol/LegacyBios.h>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+#include <Protocol\SmmBase2.h>
+#include <Protocol\SmmSwDispatch2.h>
+#else
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#endif
+
+DEPENDENCY_START
+ EFI_LEGACY_INTERRUPT_PROTOCOL_GUID AND
+ EFI_LEGACY_REGION_PROTOCOL_GUID AND
+ EFI_LEGACY_8259_PROTOCOL_GUID AND
+ EFI_FIRMWARE_VOLUME_PROTOCOL_GUID AND
+ EFI_LEGACY_BIOS_PROTOCOL_GUID AND
+ EFI_CPU_ARCH_PROTOCOL_GUID AND
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ EFI_SMM_BASE2_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH2_PROTOCOL_GUID
+#else
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/Sredir/LegacySredir.mak b/Core/EM/Sredir/LegacySredir.mak
new file mode 100644
index 0000000..814d9a6
--- /dev/null
+++ b/Core/EM/Sredir/LegacySredir.mak
@@ -0,0 +1,135 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySredir.mak 8 12/08/14 3:36a Anbuprakashp $
+#
+# $Revision: 8 $
+#
+# $Date: 12/08/14 3:36a $
+#**********************************************************************
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/Legacy Serial Redirection/LegacySredir.mak $
+#
+# 8 12/08/14 3:36a Anbuprakashp
+# [TAG] EIP192305
+# [Category] Improvement
+# [Description] Replacing SmmGetMemoryType usage in LegacySredir module
+# with AmiBufferValidationLib
+# [Files] LegacySredir.mak, LegacySmmSredir.c, LegacySredir_Setup.C
+#
+# 7 2/27/12 5:49a Jittenkumarp
+# [TAG] EIP81401
+# [Category] New Feature
+# [Description] Select Redirection After BIOS POST as BootLoader in
+# serial redirection, the behaviour is not same as Core8.
+# [Files] LegacySredir.c, LegacySredir.mak, LegacySredir.sdl,
+# LegacySredir_Setup.c, LegacySredir.h ,SerialBootCall.asm,
+# SredirBootFail.asm,GRAPHREDIR.ASM, INT10REDIR.ASM, OR_MOD.EQU,
+# SREDIR.ASM
+#
+# 6 9/20/10 4:09a Rameshr
+# [TAG]- EIP 44007
+# [Category]-IMPROVEMENT
+# [Description]- Invalid PCI COM device list added as Elink. These
+# devices will not be used for Redirection.
+# [Files]- LegacySredir.mak, LegacySredir.sdl, LegacySredir_Setup.c
+#
+# 5 5/03/10 1:55a Rameshr
+# Callback function added for read and write function of the Serial Port.
+# EIP 37850
+#
+# 4 6/29/09 12:11p Rameshr
+# Coding Standard and File header updated.
+#
+# 3 11/06/08 9:54a Rameshraju
+# Guid's updated.
+#
+# 2 4/17/07 4:41a Rameshraju
+# PCIserial support added
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#**********************************************************************
+#
+# Name: LegacySredir.MAK
+#
+# Description: Make file for the Legacy Serial Redirection Module part
+#
+#**********************************************************************
+#<AMI_FHDR_END>
+
+all : LEGACYSREDIR
+
+LEGACYSREDIR : $(BUILD_DIR)\LEGACYSREDIR.mak SerialCallBack LEGACYR_ROM LEGACYSREDIRBin
+
+$(BUILD_DIR)\LEGACYSREDIR.mak : $(LEGACYSREDIR_DIR)\LEGACYSREDIR.cif $(LEGACYSREDIR_BOARD_DIR)\LegacySredir-Board.cif $(LEGACYSREDIR_DIR)\LEGACYSREDIR.mak $(BUILD_RULES)
+ $(CIF2MAK) $(LEGACYSREDIR_DIR)\LEGACYSREDIR.cif $(LEGACYSREDIR_BOARD_DIR)\LegacySredir-Board.cif $(CIF2MAK_DEFAULTS)
+
+LEGACYSREDIR_INCLUDES = $(AMIDXELIB) \
+ $(AMICSPLib) \
+ $(BUILD_DIR)\AmiBufferValidationLib.lib
+
+LegacySreDir_OBJECTS = \
+$(BUILD_DIR)\$(LEGACYSREDIR_DIR)\LegacySredir.obj \
+$(BUILD_DIR)\$(LEGACYSREDIR_DIR)\LegacySmmSredir.obj \
+$(BUILD_DIR)\$(LEGACYSREDIR_BOARD_DIR)\LegacySredir_Setup.obj
+
+LEGACYSREDIRBin : $(LEGACYSREDIR_INCLUDES)
+ @set INCLUDE=%%INCLUDE%%
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\LEGACYSREDIR.mak all\
+ GUID=4A3602BC-1A05-4c82-99B4-588CD2A32CD5 \
+ ENTRY_POINT=LegacySredirEntryPoint \
+ "CFLAGS=$(CFLAGS) /I$(LEGACYSREDIR_DIR) /D\"INVALID_PCICOM_DEVICELIST=$(InvalidPciComDeviceList)\"" \
+ "OBJECTS=$(LegacySreDir_OBJECTS)"\
+ TYPE=BS_DRIVER \
+ EXT_HEADERS=$(BUILD_DIR)\token.h\
+ BINFILE=$(BUILD_DIR)\ROMss.bin \
+ SECTION_GUID=9BA21891-7E7D-4e94-B8DF-F4D2D320801C \
+ COMPRESS=1\
+
+SerialCallBack: $(BUILD_DIR)\SerialCallback.obj
+
+$(BUILD_DIR)\SerialCallback.obj: $(LEGACYSREDIR_BOARD_DIR)\SerialCallback.asm
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\ /Fl$(BUILD_DIR)\ $(LEGACYSREDIR_BOARD_DIR)\SerialCallback.asm
+
+$(BUILD_DIR)\SerialBootCall.obj: $(LEGACYSREDIR_DIR)\SerialBootCall.asm
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\ /Fl$(BUILD_DIR)\ $(LEGACYSREDIR_DIR)\SerialBootCall.asm
+
+$(BUILD_DIR)\SredirBootFail.obj: $(LEGACYSREDIR_DIR)\SredirBootFail.asm
+ $(ASM) /c /nologo /Fo$(BUILD_DIR)\ /Fl$(BUILD_DIR)\ $(LEGACYSREDIR_DIR)\SredirBootFail.asm
+
+LEGACYR_ROM :
+ $(PACKOPROM) /o$(BUILD_DIR)\ROMss.bin <<$(BUILD_DIR)\ROMss.inf
+[MODULE]
+ModuleID = 3
+VendorID = 7
+DeviceID = 9
+File = addon\SREDIR.bin
+<<KEEP
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/Sredir/LegacySredir.sdl b/Core/EM/Sredir/LegacySredir.sdl
new file mode 100644
index 0000000..7941dd7
--- /dev/null
+++ b/Core/EM/Sredir/LegacySredir.sdl
@@ -0,0 +1,164 @@
+TOKEN
+ Name = "LEGACYSREDIR_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AMI Legacy Serial Redirection support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+ Token = "Terminal_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "LEGACYSREDIR_DIR"
+ Path = "core\em\sredir"
+End
+
+TOKEN
+ Name = "DISPLAY_WHOLE_SCREEN"
+ Value = "0"
+ Help = "Display the whole screen before disabling the Legacy console redirection"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TRAP_INT10_WORKAROUND"
+ Value = "0"
+ Help = "Trap Int10 to avoid the b8000 region accessed by Video option rom and Legacy console redirection."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SERIAL_READ_WRITE_CALLBACK"
+ Value = "0"
+ Help = "1- Call back will come from Sredir.bin for SerialRead and SerialWrite(SerialCallback.asm).0-Disabled."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "LEGACY_SREDIR_SWSMI"
+ Value = "0x41"
+ Help = "SW SMI value to be used in Legacy console redirection"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0...0FFh"
+End
+
+TOKEN
+ Name = "COM_MMIO_WIDTH"
+ Value = "4"
+ Help = "MMIO Com device width size. 1- Byte, 2- Word, 4-Dword. Default Set to Dword"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "1...4h"
+End
+
+TOKEN
+ Name = "CTRLI_KEY_MAPPING"
+ Value = "1"
+ Help = "0- Mapped to TAB key, 1- Mapped to CtrlI Key"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CTRLH_KEY_MAPPING"
+ Value = "1"
+ Help = "0- Mapped to BackSpace Key, 1- Mapped to CtrlH Key"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CHECK_FOR_LOOPBACK_DEVICE"
+ Value = "0"
+ Help = "0- hardware Loop back checking disabled 1- Hardware loopback checking enabled and if present redirection skipped for the port"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CLEAR_LEGACYSREDIR_KB_BUFFER_AT_READYTOBOOT"
+ Value = "0"
+ Help = "ON -> Legacy Serial Redirection KB Buffer will be cleared at ReadyToBoot.\OFF -> Legacy Serial Redirection KB Buffer will not be cleared at ReadyToBoot."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_POLLING_REDIRECTION"
+ Value = "0"
+ Help = "Use polling method redirection to send and receive data from COM Port"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "LEGACYSREDIR_BOARD_DIR"
+ Path = "Board\em\sredir"
+End
+
+MODULE
+ Help = "Includes LegacySredir.cif to Project"
+ Path = "$(LEGACYSREDIR_DIR)"
+ File = "LEGACYSREDIR.mak"
+End
+
+ELINK
+ Name = "InvalidPciComDeviceList"
+ InvokeOrder = ReplaceParent
+ Help = "Invalid PCI Device List to skip the redirection from that device. Format of the InvalidPciComDeviceList is {VendorId, DeviceId), "
+End
+
+ELINK
+ Name = "SerialCallBackApiModuleStart"
+ Parent = "CsmOem16Functions"
+ ProcID = 0Bh
+ SrcFile = "$(LEGACYSREDIR_BOARD_DIR)\SerialCallback.asm"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SerialCallback.obj"
+ Parent = "CSM_OEM16_OBJS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "LegcaySredirModuleStart"
+ Parent = "CsmOem16Functions"
+ ProcID = 08h
+ SrcFile = "Core\em\Sredir\SerialBootCall.asm"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SerialBootCall.obj"
+ Parent = "CSM_OEM16_OBJS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "EnableLegcaySredirModuleStart"
+ Parent = "CsmOem16Functions"
+ ProcID = 06h
+ SrcFile = "Core\em\Sredir\SredirBootFail.asm"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\SredirBootFail.obj"
+ Parent = "CSM_OEM16_OBJS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\LEGACYSREDIR.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/Sredir/SerialBootCall.asm b/Core/EM/Sredir/SerialBootCall.asm
new file mode 100644
index 0000000..ebd9c1b
--- /dev/null
+++ b/Core/EM/Sredir/SerialBootCall.asm
@@ -0,0 +1,180 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2014, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/Legacy Serial Redirection/SerialBootCall.asm 3 6/16/14 7:39a Divyac $
+;
+; $Revision: 3 $
+;
+; $Date: 6/16/14 7:39a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/Legacy Serial Redirection/SerialBootCall.asm $
+;
+; 3 6/16/14 7:39a Divyac
+; [TAG] EIP172120
+; [Category] Bug Fix
+; [Severity] Important
+; [Symptom] Redirection After BIOS POST feature is not working.
+; [RootCause] The flag Indicating whether redirection can happen or not
+; is not updated.
+; 1)The way of Defining signatures and Comparing Signatures are
+; different.
+; 2)The variables defined in CSM16 files( SreDirBin_Base_Segadd,
+; SreDirBin_Base_Offadd, Flag ) are accessed wrongly.
+;
+; [Solution] a) The pointer used to check for signatures must be
+; UINT32* or we should define signatures byte by byte (db
+; '$','S','B','F', db '$','S','B','C'). so changed the way of defining
+; Signatures in CSM16 files from dd '$SBF' to db '$','S','B','F'.
+; b) Variables should be accessed using OFFSET Keyword.
+; [Files] SerialBootCall.asm, SerialBootFail.asm
+;
+; 2 5/29/13 8:53a Srikantakumarp
+; [TAG] EIP122394
+; [Category] Bug Fix
+; [Severity] Normal
+; [Symptom] 0xE0000~0xEFFFF was overwrite by Legacy Serial Redirection
+; module.
+; [RootCause] LegacySerialRedirection driver assumed that
+; SerialBootcall.asm will be the first entry in CsmOem16Functions which
+; was wrong.
+; [Solution] Added a Signature check code for SerialBootCall.asm and
+; SredirBootFail.asm before it writes to the memory location
+; 0xE0000~0xEFFFF.
+; [Files] LegacySredir.c, SerialBootCall.asm, SredirBootFail.asm
+;
+; 1 2/27/12 5:57a Jittenkumarp
+; [TAG] EIP81401
+; [Category] New Feature
+; [Description] Select Redirection After BIOS POST as BootLoader in
+; serial redirection, the behaviour is made same as Core8.
+; [Files] LegacySredir.c, LegacySredir.mak, LegacySredir.sdl,
+; LegacySredir_Setup.c, LegacySredir.h ,SerialBootCall.asm,
+; SredirBootFail.asm,GRAPHREDIR.ASM, INT10REDIR.ASM, OR_MOD.EQU,
+; SREDIR.ASM
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: SerialBootCall.asm
+;
+; Description: Call Back function registered for
+; CSM16_OEM_BEFORE_CALL_BOOT_VECTOR
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+
+;----------------------------------------------------------------------------
+; INCLUDE FILES
+;----------------------------------------------------------------------------
+
+ include token.equ
+
+;----------------------------------------------------------------------------
+; EXTERNS USED
+;----------------------------------------------------------------------------
+
+.586p
+OEM16_CSEG SEGMENT PARA PUBLIC 'CODE' USE16
+ ASSUME cs:OEM16_CSEG, ds:OEM16_CSEG
+;-------------------------------------------------------------------------
+ PUBLIC LegcaySredirModuleStart
+LegcaySredirModuleStart LABEL BYTE
+ jmp SHORT LegcaySredirCsm16Api
+ db '$','S','B','C'
+SreDirBin_Base_Segadd dw 0000h ;SreDirBin Segement Address
+SreDirBin_Base_Offadd dw 0000h ;SreDirbin offset Address
+Flag dw 0000h
+
+;----------------------------------------------------------------------------
+; IMPORTANT: Do not put any OEM/CHIPSET code above this, the above code and
+; and data are at fixed locations.
+;----------------------------------------------------------------------------
+
+;-------------------------------------------------------------------------
+; LEGACYSREDIR_CSM16_API_Start
+;----------------------------------------------------------------------------
+; This routine is implementation of the CSM16 API #8.
+;
+; Input: BX - SreDirBin Segment add
+; BX - SreDirBin Offset add
+; AX - Flag offset value
+;
+; Output: None
+;
+; Register Usage: Do not destroy any register
+;
+;----------------------------------------------------------------------------
+
+LegcaySredirCsm16Api PROC FAR PUBLIC
+; Adjust current IP so that the data offsets are valid
+
+ call $+3 ; Push curent IP
+ pop bx ; Get current IP in BX
+ shr bx, 4
+ mov ax, cs ; Always x000h
+ add ax, bx ; New CS
+ push ax
+ push newOffset-LegcaySredirModuleStart
+ retf ; Execute from new CS:IP
+
+newOffset:
+
+ push bx
+ push si
+ push ax
+ push es
+ push 0
+ pop es
+ mov si, offset SreDirBin_Base_Segadd
+ mov bx, word ptr cs:[si]
+ mov es, bx
+ mov si, offset SreDirBin_Base_Offadd
+ mov bx, word ptr cs:[si]
+ mov si, offset Flag
+ mov ax, word ptr cs:[si]
+ mov si, ax
+ add si, bx
+ mov al, 01h
+ mov byte ptr es:[si], al
+
+ pop es
+ pop ax
+ pop si
+ pop bx
+
+ retf
+
+LegcaySredirCsm16Api ENDP
+
+OEM16_CSEG ENDS
+
+END
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2012, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;********************************************************************** \ No newline at end of file
diff --git a/Core/EM/Sredir/SredirBootFail.asm b/Core/EM/Sredir/SredirBootFail.asm
new file mode 100644
index 0000000..b8433b9
--- /dev/null
+++ b/Core/EM/Sredir/SredirBootFail.asm
@@ -0,0 +1,179 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2014, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/Legacy Serial Redirection/SredirBootFail.asm 3 6/16/14 7:40a Divyac $
+;
+; $Revision: 3 $
+;
+; $Date: 6/16/14 7:40a $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/Legacy Serial Redirection/SredirBootFail.asm $
+;
+; 3 6/16/14 7:40a Divyac
+; [TAG] EIP172120
+; [Category] Bug Fix
+; [Severity] Important
+; [Symptom] Redirection After BIOS POST feature is not working.
+; [RootCause] The flag Indicating whether redirection can happen or not
+; is not updated.
+; 1)The way of Defining signatures and Comparing Signatures are
+; different.
+; 2)The variables defined in CSM16 files( SreDirBin_Base_Segadd,
+; SreDirBin_Base_Offadd, Flag ) are accessed wrongly.
+;
+; [Solution] a) The pointer used to check for signatures must be
+; UINT32* or we should define signatures byte by byte (db
+; '$','S','B','F', db '$','S','B','C'). so changed the way of defining
+; Signatures in CSM16 files from dd '$SBF' to db '$','S','B','F'.
+; b) Variables should be accessed using OFFSET Keyword.
+; [Files] SerialBootCall.asm, SerialBootFail.asm
+;
+; 2 5/29/13 8:54a Srikantakumarp
+; [TAG] EIP122394
+; [Category] Bug Fix
+; [Severity] Normal
+; [Symptom] 0xE0000~0xEFFFF was overwrite by Legacy Serial Redirection
+; module.
+; [RootCause] LegacySerialRedirection driver assumed that
+; SerialBootcall.asm will be the first entry in CsmOem16Functions which
+; was wrong.
+; [Solution] Added a Signature check code for SerialBootCall.asm and
+; SredirBootFail.asm before it writes to the memory location
+; 0xE0000~0xEFFFF.
+; [Files] LegacySredir.c, SerialBootCall.asm, SredirBootFail.asm
+;
+; 1 2/27/12 5:58a Jittenkumarp
+; [TAG] EIP81401
+; [Category] New Feature
+; [Description] Select Redirection After BIOS POST as BootLoader in
+; serial redirection, the behaviour is made same as Core8.
+; [Files] LegacySredir.c, LegacySredir.mak, LegacySredir.sdl,
+; LegacySredir_Setup.c, LegacySredir.h ,SerialBootCall.asm,
+; SredirBootFail.asm,GRAPHREDIR.ASM, INT10REDIR.ASM, OR_MOD.EQU,
+; SREDIR.ASM
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: SredirBootFail.asm
+;
+; Description: Call Back function registered for CSM16_OEM_ON_BOOT_FAIL
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+
+;----------------------------------------------------------------------------
+; INCLUDE FILES
+;----------------------------------------------------------------------------
+
+ include token.equ
+
+;----------------------------------------------------------------------------
+; EXTERNS USED
+;----------------------------------------------------------------------------
+
+.586p
+OEM16_CSEG SEGMENT PARA PUBLIC 'CODE' USE16
+ ASSUME cs:OEM16_CSEG, ds:OEM16_CSEG
+;-------------------------------------------------------------------------
+ PUBLIC EnableLegcaySredirModuleStart
+EnableLegcaySredirModuleStart LABEL BYTE
+ jmp SHORT EnableLegcaySredirCsm16Api
+ db '$','S','B','F'
+SreDirBin_Base_Segadd dw 0000h ;SreDirBin Segement Address
+SreDirBin_Base_Offadd dw 0000h ;SreDirbin offset Address
+Flag dw 0000h
+
+
+;----------------------------------------------------------------------------
+; IMPORTANT: Do not put any OEM/CHIPSET code above this, the above code and
+; and data are at fixed locations.
+;----------------------------------------------------------------------------
+
+;-------------------------------------------------------------------------
+; LEGACYSREDIR_CSM16_API_Start
+;----------------------------------------------------------------------------
+; This routine is implementation of the CSM16 API #6.
+; Input: BX - SreDirBin Segment add
+; BX - SreDirBin Offset add
+; AX - Flag offset value
+;
+; Output: None
+;
+; Register Usage: Do not destroy any register
+;
+;----------------------------------------------------------------------------
+
+EnableLegcaySredirCsm16Api PROC FAR PUBLIC
+; Adjust current IP so that the data offsets are valid
+
+ call $+3 ; Push curent IP
+ pop bx ; Get current IP in BX
+ shr bx, 4
+ mov ax, cs ; Always x000h
+ add ax, bx ; New CS
+ push ax
+ push newOffset-EnableLegcaySredirModuleStart
+ retf ; Execute from new CS:IP
+
+newOffset:
+
+ push bx
+ push si
+ push ax
+ push es
+ push 0
+ pop es
+ mov si, offset SreDirBin_Base_Segadd
+ mov bx, word ptr cs:[si]
+ mov es, bx
+ mov si, offset SreDirBin_Base_Offadd
+ mov bx, word ptr cs:[si]
+ mov si, offset Flag
+ mov ax, word ptr cs:[si]
+ mov si, ax
+ add si, bx
+ mov al, 00h
+ mov byte ptr es:[si], al
+
+ pop es
+ pop ax
+ pop si
+ pop bx
+
+ retf
+
+EnableLegcaySredirCsm16Api ENDP
+
+OEM16_CSEG ENDS
+
+END
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2014, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;********************************************************************** \ No newline at end of file
diff --git a/Core/EM/StatusCode/SerialStatusCode.c b/Core/EM/StatusCode/SerialStatusCode.c
new file mode 100644
index 0000000..1aefcde
--- /dev/null
+++ b/Core/EM/StatusCode/SerialStatusCode.c
@@ -0,0 +1,358 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/SerialStatusCode.c 13 1/22/13 4:56p Oleksiyy $
+//
+// $Revision: 13 $
+//
+// $Date: 1/22/13 4:56p $
+//*****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/SerialStatusCode.c $
+//
+// 13 1/22/13 4:56p Oleksiyy
+// [TAG] EIP112774
+// [Category] Bug Fix
+// [Severity:] Normal
+// [Symptom:] CPU Exception occurs when TRACE is used in SMM Handler
+// [Root Cause] pBS, used in Delay function, do not exist during runtime.
+// [Solution] Delay replaced with dummy "for" cycle in SerialOutput
+// function.
+// [Files] StatusCodeCommon.c
+//
+//
+// 12 3/18/11 12:33p Oleksiyy
+// [TAG] EIP54959
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] No debug output in projects with no SIO.
+// [RootCause] Dependency from SIO added to sdl.
+// [Solution] Dependency from SIO removed from SerialOutput eLink and
+// moved directly to SerialOutput function body.
+//
+// [Files] SeriaStatusCode.c and StatusCode.sdl
+//
+// 11 10/01/10 6:08p Oleksiyy
+// Issue Number: 43888
+//
+// Category: Bug Fix
+//
+// Symptom: System hang endlesly if com port not working and Debug is ON
+//
+// Severity: Normal
+//
+// Root Cause: Infinite loop in SerialOutput.
+//
+// Solution: SEND_BYTE_DELEY and SEND_BYTE_ATEMPTS values is added. In
+// SendByte SEND_BYTE_DELEY atempts will be made in loop until the serial
+// port is ready for the next byte.
+//
+// Files: SeriaStatusCode.c, StausCode.sdl
+//
+// 10 5/03/10 1:17a Rameshr
+// Issue:Need to handle different Base Hz values for SerialStatusCode,
+// Terminal, and Legacy Serial Redirection.
+// Solution: Moved Uart input clock into Core.sdl token and used in all
+// the above modules.
+// EIP: 37332
+//
+// 9 11/13/09 4:30p Felixp
+// Buffer overflow protection is added (calls to Sprintf replaced with
+// Sprintf_s).
+//
+// 8 7/09/09 5:18p Oleksiyy
+// Files clean-up some headers added
+//
+// 7 3/05/09 1:41p Felixp
+// Major update of the StatusCode module.
+// See Label Comments and Release Notes in StatusCode.chm for more
+// details.
+//
+// 5 8/24/06 3:33p Felixp
+// Preliminary x64 support (work in progress)
+//
+// 4 5/04/06 12:01p Robert
+// Updated to support core release 4.4.10
+//
+// 15 6/07/05 7:23p Felixp
+// Moving toward generic Status Code module
+//
+// 13 1/20/05 11:31a Felixp
+// StatusCodes.h renamed to AmiStatusCode.h
+//
+// 12 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 11 11/15/04 10:35 Dougm
+// Change the initialization of SIO
+//
+// 9 11/10/04 5:21p Felixp
+// Serial output implementation changed to send '\r' before every '\n'
+//
+//*****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: SerialStatusCode.c
+//
+// Description: Implementation of the serial port status code handler.
+//
+//<AMI_FHDR_END>
+//*****************************************************************************
+#include <PEI.h>
+#include <StatusCodes.h>
+#include <AMILIB.h>
+#include <token.h>
+
+//----------------------------------------------------------------------------
+// Local constant definitions
+#define CONFIG_PORT0 0x2E
+#define INDEX_PORT0 0x2E
+#define DATA_PORT0 0x2F
+#define SEND_BYTE_DELEY 0x200
+#define SEND_BYTE_ATEMPTS 0x10
+
+#ifdef DEBUG_COM_PORT_ADDR
+#define COM_BASE_ADDR DEBUG_COM_PORT_ADDR
+#else
+#define COM_BASE_ADDR 0x03f8
+#endif
+#define LSR_OFFSET 0x05
+#define LCR_OFFSET 0x03
+#define DIV_MSB 0x01
+#define DIV_LSB 0
+
+#define TRANSMIT_READY_BIT 0x020
+#ifdef UART_INPUT_CLOCK
+UINTN UartInputClock=UART_INPUT_CLOCK;
+#else
+//
+// Set the default value((24000000/13)MHz input clock) if the UART_INPUT_CLOCK SDL token is not present.
+//
+UINTN UartInputClock=1843200;
+#endif
+
+#define BAUD_RATE_DIVISOR 115200
+
+#define DATA_BITS 3 // 0 - 5 bits / 1 - 6 bits
+// 2 - 7 bits / 3 - 8 bits
+// RSP BUGBUG #define STOP_BIT 0 // 0 - 1 stop bit
+#define STOP_BIT 1 // 0 - 1 stop bit
+// 1 - mutiple bits depending on the databits
+#define PARITY_BITS 0 // 0 - None / 1 enables parity
+#define BREAK_BIT 0 // 0 - No break
+#define DLAB_BIT 1 // 0 - Divisor Latch Disabled
+// 1 - Divisor Latch Enabled
+
+//----------------------------------------------------------------------------
+// Module specific type definitions
+
+
+//----------------------------------------------------------------------------
+// Function Prototypes
+EFI_STATUS SerialData(
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_STATUS_CODE_DATA *Data,
+ OUT UINT8 *String
+);
+VOID Delay(EFI_PEI_SERVICES **PeiServices, UINT32 Microseconds);
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SendByte
+//
+// Description: Writes the given byte to the serial port
+//
+// Input:
+// UINT8 Byte - a byte to write to the serial port
+//
+// Output: TRUE - Byte was sent, FALSE - serial port was not ready
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN SendByte(UINT8 Byte)
+{
+ UINT8 Buffer8;
+ UINT32 Cntr = 0;
+
+ do
+ {
+ // Read the ready signal to see if the serial port is
+ // ready for the next byte.
+ Buffer8 = IoRead8(COM_BASE_ADDR + LSR_OFFSET);
+ // Increment timeout counter.
+ Cntr++;
+ // Loop until the serial port is ready for the next byte.
+ }
+ while ( (Cntr < SEND_BYTE_DELEY) &&
+ ((Buffer8 & TRANSMIT_READY_BIT) == FALSE) );
+ if (Cntr < SEND_BYTE_DELEY){
+
+ IoWrite8(COM_BASE_ADDR, Byte);
+ return TRUE;
+ } else return FALSE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SerialOutput
+//
+// Description: Writes the given string to the serial port byte by byte
+// using the function SendByte.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to the PEI Boot Services table
+// CHAR8 *String - String to be sent over the serial port
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SerialOutput(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN CHAR8 *String
+)
+{
+#if SERIAL_STATUS_SUPPORT
+ UINT8 *Buffer, i;
+ UINT32 Delay;
+ BOOLEAN ByteSent;
+
+ if (String == NULL) return EFI_SUCCESS;
+ // first make data useable
+ Buffer = String;
+
+ // now send data one byte at a time until the string hits the end of string
+ // or we hit the max number of characters
+ while (*Buffer)
+ {
+ // replace "\n" with "\r\n"
+ for (i = 0; i <= SEND_BYTE_ATEMPTS; i++){
+ ByteSent = TRUE;
+
+ if (*Buffer=='\n') ByteSent = SendByte('\r');
+
+ if (ByteSent) ByteSent = SendByte(*Buffer);
+
+ if (ByteSent) break;
+ else
+ for (Delay = 0; Delay <= 100000; Delay++);
+ }
+
+ // move Data pointer to the next byte if previous was sent
+ if (ByteSent) Buffer++;
+ else return EFI_SUCCESS;
+ }
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SerialStatusInit
+//
+// Description:
+// The function programs the stop bits, data bits, and baud rate
+// of the com port and outputs the debug message "Status Code Available."
+// NOTE: This function does not assumes Super I/O has already been initialized.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices - pointer to the PEI Boot Services table
+// Output:
+// EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SerialStatusInit(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ UINT8 Data8;
+ UINT16 Divisor;
+ UINTN Remainder;
+
+ //
+ // Compute the baud rate divisor.
+ //
+ Divisor = (UINT32) Div64 (UartInputClock,
+ ((UINT32)BAUD_RATE_DIVISOR * 16),
+ &Remainder);
+ if ( Remainder ) {
+ Divisor += 1;
+ }
+
+ if ((Divisor == 0) || (Divisor & 0xffff0000)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Programm Serial port
+ // Set Line Control Register (LCR)
+ Data8 = DLAB_BIT << 7 | STOP_BIT << 2 | DATA_BITS;
+ IoWrite8(COM_BASE_ADDR + LCR_OFFSET, Data8 );
+
+ IoWrite8(COM_BASE_ADDR + DIV_LSB, Divisor & 0xFF);
+ IoWrite8(COM_BASE_ADDR + DIV_MSB, Divisor >> 8);
+
+ // Clear DLAB bit in LCR
+ Data8 &= ~((UINT8)DLAB_BIT << 7);
+ IoWrite8(COM_BASE_ADDR + LCR_OFFSET, Data8 );
+#ifdef EFI_DEBUG
+#ifndef PEI_STATUS_CODE
+ SerialOutput(PeiServices, "DXE Status Code Available\n");
+#else
+ SerialOutput(PeiServices, "Status Code Available\n");
+#endif
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SerialStatusInit
+//
+// Description:
+// The function sends "Checkpoint #" string to serial port
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to the PEI Boot Services table
+// UINT8 Checkpoint - Checkpoint to send
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SerialCheckpoint(EFI_PEI_SERVICES **PeiServices, UINT8 Checkpoint)
+{
+ char s[20];
+ Sprintf_s(s, sizeof(s), "Checkpoint %X\n",Checkpoint);
+ SerialOutput(PeiServices, s);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/StatusCode/StatusCode.chm b/Core/EM/StatusCode/StatusCode.chm
new file mode 100644
index 0000000..5acc724
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCode.chm
Binary files differ
diff --git a/Core/EM/StatusCode/StatusCode.cif b/Core/EM/StatusCode/StatusCode.cif
new file mode 100644
index 0000000..d13f4bb
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCode.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "StatusCode"
+ category = eModule
+ LocalRoot = "Core\EM\StatusCode\"
+ RefName = "StatusCode"
+[files]
+"StatusCode.mak"
+"StatusCode.sdl"
+"StatusCodePei.c"
+"StatusCodeDxe.c"
+"StatusCodeCommon.c"
+"StatusCodeInt.h"
+"SerialStatusCode.c"
+"StatusCodeMap.c"
+"StatusCode.chm"
+"StatusCodeRuntime.c"
+<endComponent>
diff --git a/Core/EM/StatusCode/StatusCode.mak b/Core/EM/StatusCode/StatusCode.mak
new file mode 100644
index 0000000..05522b3
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCode.mak
@@ -0,0 +1,200 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/StatusCode/StatusCode.mak 17 10/07/10 4:39p Oleksiyy $
+#
+# $Revision: 17 $
+#
+# $Date: 10/07/10 4:39p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/StatusCode/StatusCode.mak $
+#
+# 17 10/07/10 4:39p Oleksiyy
+# Minor fix of StatusCodeRuntime support.
+#
+# 16 10/06/10 4:31p Oleksiyy
+# Issue Number: 39752
+#
+# Category: Improvement
+#
+# Description: Runtime Staus Code support is added.
+#
+# Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c,
+# CsmLib.c, AmiDxeLib.h and StatusCode eModule.
+#
+# 15 3/05/09 1:41p Felixp
+# Major update of the StatusCode module.
+# See Label Comments and Release Notes in StatusCode.chm for more
+# details.
+#
+# 14 4/22/08 5:56p Felixp
+# Bug fix (project did not compile in IA32 mode).
+#
+# 8 3/06/08 4:12p Felixp
+# Differences in IA32 and x64 build rules has been removed.
+#
+# 6 4/20/07 5:10p Felixp
+# Updated to use new Status Code infrastructure
+#
+# 2 6/16/05 11:10a Felixp
+# module reallocated to RAM once it is available
+#
+# 22 6/08/05 5:59p Felixp
+# Beep Codes added
+# SerialStatusCode.c moved to StatusCode component
+#
+# 21 6/07/05 7:23p Felixp
+# Moving toward generic Status Code module
+#
+# 20 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 19 11/01/04 8:44a Felixp
+#
+# 18 10/22/04 10:24a Felixp
+# Status Code updated to use PEIM_HOB to pass status code pointer to DXE
+#
+# 17 9/21/04 10:50a Robert
+# added standard library support in the build process
+#
+# 16 7/13/04 10:42a Felixp
+#
+# 15 4/10/04 2:17p Felixp
+#
+# 14 4/09/04 11:49a Robert
+# Adding string support for displaying, Type, Severity, Class, and
+# SubClass for unknown error types
+#
+# 13 4/07/04 5:21p Robert
+# fixed up DXE part of status Code Protocol, the mak file should now make
+# the available to both DXE and PEI. In addition, it should add a
+# dependency expression
+#
+# 12 3/29/04 12:41p Markw
+# Moved EfiStatusCode.h into include component. Deleted this reference in
+# makefile.
+#
+# 4 2/06/04 2:46a Felixp
+# - Support for VC6 tools
+# - bug fixes
+# - component AddOn added
+#
+# 2 1/18/04 8:32a Felixp
+# From now on, OBJ files are created in a component specific subdirectory
+# of $(BUILD_DIR)
+#
+# 1 1/15/04 5:18p Robert
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: StatusCode.mak
+#
+# Description:
+# Builds PEI and DXE StatusCode modules.
+# Two libraries StatusCodePei.lib and StatusCodeDxe.lib
+# are built and these are linked with CORE_PEI and CORE_DXE
+# respectively.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : StatusCode
+
+STATUS_CODE_COMMON_OBJECTS=\
+$$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeCommon.obj\
+$$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeMap.obj\
+$$(BUILD_DIR)\$(STATUS_CODE_DIR)\SerialStatusCode.obj\
+
+STATUS_CODE_PEI_OBJECTS=\
+$(STATUS_CODE_COMMON_OBJECTS)\
+$$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodePei.obj
+
+STATUS_CODE_DXE_OBJECTS=\
+$(STATUS_CODE_COMMON_OBJECTS)\
+$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeDxe.obj
+
+STATUS_CODE_RUNTIME_OBJECTS=\
+$(BUILD_DIR)\$(STATUS_CODE_DIR)\StatusCodeRuntime.obj
+
+STATUS_CODE_EXT_HEADERS=\
+$(BUILD_DIR)\token.h\
+$(BUILD_DIR)\StatusCodeELinks.h
+
+StatusCode : StatusCodePei StatusCodeDxe StatusCodeRuntime
+
+StatusCodePei : $(BUILD_DIR)\StatusCodeELinks.h StatusCodePeiBin
+StatusCodeDxe : $(BUILD_DIR)\StatusCodeELinks.h StatusCodeDxeBin
+StatusCodeRuntime : $(BUILD_DIR)\StatusCodeELinks.h StatusCodeRuntimeBin
+
+$(BUILD_DIR)\StatusCode.mak : $(STATUS_CODE_DIR)\$(@B).cif $(STATUS_CODE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(STATUS_CODE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+CORE_PEIBin : $(BUILD_DIR)\StatusCodePei.lib
+CORE_DXEBin : $(BUILD_DIR)\StatusCodeDxe.lib
+RUNTIMEBin : $(BUILD_DIR)\StatusCodeRuntime.lib
+
+$(BUILD_DIR)\StatusCodePei.lib : StatusCodePei
+$(BUILD_DIR)\StatusCodeDxe.lib : StatusCodeDxe
+$(BUILD_DIR)\StatusCodeRuntime.lib : StatusCodeRuntime
+
+$(BUILD_DIR)\StatusCodeELinks.h : $(BUILD_DIR)\token.h $(BUILD_DIR)\StatusCode.mak
+ $(ECHO) #define INIT_LIST $(StatusCodeInitialize) > $@
+ $(ECHO) #define STRING_LIST $(ReportStringStatus) >> $@
+ $(ECHO) #define SIMPLE_LIST $(ReportSimpleStatus) >> $@
+ $(ECHO) #define MISC_LIST $(ReportMiscStatus) >> $@
+ $(ECHO) #define CHECKPOINT_LIST $(ReportCheckpoint) >> $@
+ $(ECHO) #define PEI_ERROR_CODE_ACTIONS $(PeiErrorCodeActions) >> $@
+ $(ECHO) #define DXE_ERROR_CODE_ACTIONS $(DxeErrorCodeActions) >> $@
+
+StatusCodePeiBin : $(AMIPEILIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\StatusCode.mak all\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ "OBJECTS=$(STATUS_CODE_PEI_OBJECTS)"\
+ "EXT_HEADERS=$(STATUS_CODE_EXT_HEADERS)"\
+ "MY_DEFINES=/DPEI_STATUS_CODE"\
+ TYPE=PEI_LIBRARY LIBRARY_NAME=$(BUILD_DIR)\StatusCodePei.lib
+
+StatusCodeDxeBin: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\StatusCode.mak all\
+ "OBJECTS=$(STATUS_CODE_DXE_OBJECTS)"\
+ "EXT_HEADERS=$(STATUS_CODE_EXT_HEADERS)"\
+ "MY_DEFINES=/DDXE_STATUS_CODE"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\StatusCodeDxe.lib
+
+StatusCodeRuntimeBin: $(BUILD_DIR)\StatusCodeDxe.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\StatusCode.mak all\
+ "OBJECTS=$(STATUS_CODE_RUNTIME_OBJECTS)"\
+ "EXT_HEADERS=$(STATUS_CODE_EXT_HEADERS)"\
+ "MY_DEFINES=/DRUNTIME_STATUS_CODE"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\StatusCodeRuntime.lib
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/StatusCode/StatusCode.sdl b/Core/EM/StatusCode/StatusCode.sdl
new file mode 100644
index 0000000..5ced211
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCode.sdl
@@ -0,0 +1,280 @@
+TOKEN
+ Name = "StatusCode_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Status Code support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "STRING_STATUS_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables all string-based status code routines \defined by the ReportStringStatus eLink"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SERIAL_STATUS_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables serail port status code routine"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "STRING_STATUS_SUPPORT" "=" "1"
+ Token = "SIO_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "RUNTIME_TRACE_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables support of trace messages in Runtime"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_MODE" "!=" "0"
+End
+
+TOKEN
+ Name = "DATAHUB_STATUS_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables logging of the status codes into a data hub"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CONOUT_CHECKPOINTS_SUPPORT"
+ Value = "1"
+ Help = "Enables/Disables checkpoint display on the ConOut devices\(right bottom corner)"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CON_OUT_CHECKPOINTS_IN_QUIET_MODE"
+ Value = "1"
+ Help = "Enables/Disables checkpoints display on the ConOut devices\in quiet mode (only in effect when CONOUT_CHECKPOINTS_SUPPORT is enabled)"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CHECKPOINT_PROGRESS_CODES_MAP"
+ Value = "ProgressCheckpointMap"
+ Help = "Name of the table that establishes mapping between progress codes and checkpoints.\Clone this token to support custom checkpoint lists."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CHECKPOINT_ERROR_CODES_MAP"
+ Value = "ErrorCheckpointMap"
+ Help = "Name of the table that establishes mapping between error codes and checkpoints.\Clone this token to support custom checkpoint lists."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BEEP_PROGRESS_CODES_MAP"
+ Value = "ProgressBeepMap"
+ Help = "Name of the table that establishes mapping between progress codes and number of beeps.\Clone this token to support custom beep codes."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BEEP_ERROR_CODES_MAP"
+ Value = "ErrorBeepMap"
+ Help = "Name of the table that establishes mapping between error codes and number of beeps.\Clone this token to support custom beep codes."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "STATUS_CODE_VERSION"
+ Value = "16"
+ Help = "Version of the status code module."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+End
+
+PATH
+ Name = "STATUS_CODE_DIR"
+End
+
+MODULE
+ Help = "Includes StatusCode.mak to Project"
+ File = "StatusCode.mak"
+End
+
+ELINK
+ Name = "StatusCodeInitialize"
+ Help = "This is a list of initialization routines for status code subcomponents. The routines are called during initialization of the StatusCode module\The child eLink can be in one of the following formats:\'InitFunctionName,' - The function will be called in PEI as well as in DXE\'PEI(InitFunctionName),' - The function will only be called in PEI\'DXE(InitFunctionName),' - The function will only be called in DXE\"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ReportSimpleStatus"
+ Help = "This is a list of status code routines that consume only status code type and value. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ReportMiscStatus"
+ Help = "This is a list of status code routines that consume all available status code data. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "CheckPointStatus,"
+ Parent = "ReportSimpleStatus"
+ Help = "This is a list of checkpoint routines. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RUNTIME(CheckPointStatus),"
+ Parent = "ReportSimpleStatus"
+ Help = "This is a list of checkpoint routines. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiInitStatusCode,"
+ Parent = "PeiCoreInitialize"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BeepService,"
+ Parent = "ReportMiscStatus"
+ Token = "BEEP_ENABLE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "BeepStatus,"
+ Parent = "ReportSimpleStatus"
+ Token = "BEEP_ENABLE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "ReportStringStatus"
+ Help = "This is a list of status code routines that consume strings. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\"
+ Token = "STRING_STATUS_SUPPORT" "=" "1"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "ReportCheckpoint"
+ Help = "This is a list of checkpoint display routines. \The child eLink can be in one of the following formats:\'FunctionName,' - The function will be called in PEI as well as in DXE\'PEI(FunctionName),' - The function will only be called in PEI\'DXE(FunctionName),' - The function will only be called in DXE\"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "Port80Checkpoint,"
+ Parent = "ReportCheckpoint"
+ Help = "Port 0x80 checkpoints"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RUNTIME(Port80Checkpoint),"
+ Parent = "ReportCheckpoint"
+ Help = "Port 0x80 checkpoints"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DXE(DataHubStatusCode),"
+ Parent = "ReportMiscStatus"
+ Help = "DataHub status code routine (DXE only).\Logs prorgess and error status codes into data hub"
+ Token = "DATAHUB_STATUS_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SerialOutput,"
+ Parent = "ReportStringStatus"
+ Help = "Serial port string status code"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "RUNTIME(SerialOutput),"
+ Parent = "ReportStringStatus"
+ Help = "Serial port string status code"
+ Token = "SERIAL_STATUS_SUPPORT" "=" "1"
+ Token = "RUNTIME_TRACE_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DXE(ConOutCheckpoint),"
+ Parent = "ReportCheckpoint"
+ Help = "ConOut Checkpoints (DXE only)"
+ Token = "CONOUT_CHECKPOINTS_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SerialCheckpoint,"
+ Parent = "ReportCheckpoint"
+ Help = "Checkpoints over Serial Port"
+ Token = "SERIAL_STATUS_SUPPORT" "=" "1"
+ Disable = Yes
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SerialStatusInit,"
+ Parent = "StatusCodeInitialize"
+ Help = "Serial port status code initialization routine"
+ Token = "SERIAL_STATUS_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DXE(ConOutCpInit),"
+ Parent = "StatusCodeInitialize"
+ Help = "ConOut checkpoints initialization routine (DXE only)"
+ Token = "CONOUT_CHECKPOINTS_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "DXE(DataHubInit),"
+ Parent = "StatusCodeInitialize"
+ Help = "DataHub status code initialization routine (DXE only).\Logs prorgess and error status codes into data hub"
+ Token = "DATAHUB_STATUS_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "PeiErrorCodeActions"
+ Help = "List of actions to perform when error of a particular type is detected in PEI.\The child eLink has the following format: \ERROR_ACTION(Value,Action)\where\Value - error code value (error values are defined in AmiStatusCodes.h)\Action - error action. Function with the following interface:\VOID (ERROR_CODE_ACTION)(\ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value\);\Custom or standard action can be used.\The following standard actions are defined:\Halt, ResetOrHalt, ResetOrResume\"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "DxeErrorCodeActions"
+ Help = "List of actions to perform when error of a particular type is detected in DXE.\The child eLink has the following format: \ERROR_ACTION(Value,Action)\where\Value - error code value (error values are defined in AmiStatusCodes.h)\Action - error action. Function with the following interface:\VOID (ERROR_CODE_ACTION)(\ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value\);\Custom or standard action can be used.\The following standard actions are defined:\Halt, ResetOrHalt, ResetOrResume\"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "StatusCodeSmmEntry,"
+ Parent = "RuntimeSmmInitialize"
+ InvokeOrder = BeforeParent
+End
+
+ELINK
+ Name = "DxeInitStatusCode,"
+ Parent = "DxeCoreInitialize"
+ InvokeOrder = BeforeParent
+End
+
diff --git a/Core/EM/StatusCode/StatusCodeCommon.c b/Core/EM/StatusCode/StatusCodeCommon.c
new file mode 100644
index 0000000..e694c8c
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCodeCommon.c
@@ -0,0 +1,1142 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeCommon.c 7 6/23/11 6:10p Oleksiyy $
+//
+// $Revision: 7 $
+//
+// $Date: 6/23/11 6:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeCommon.c $
+//
+// 7 6/23/11 6:10p Oleksiyy
+// [TAG] EIP56644
+// [Category] New Feature
+// [Description] Implemented PPI and Protocols, described in a PI 1.2
+// Report Status Code Router specification.
+// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h,
+// StatusCodeCommon.c and StatusCodeRuntime.c
+//
+// 6 10/06/10 4:34p Oleksiyy
+// Issue Number: 39752
+//
+// Category: Improvement
+//
+// Description: Runtime Staus Code support is added.
+//
+// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c,
+// CsmLib.c, AmiDxeLib.h and StatusCode eModule.
+//
+// 5 8/12/09 2:09p Felixp
+// 1. Replace Sprintf calls with Sprint_s (to protect from buffer
+// overflow).
+// 2. Fix format string in ReportData function.
+//
+// 4 7/30/09 10:51a Felixp
+// Minor Bug fix: EIP 24740. ReportData updated to extract status code
+// type from the 'Type' parameter.
+//
+// 3 7/28/09 5:11p Vyacheslava
+// Bug fix. EIP#24453: Synopsis: CPU exception when printing long
+// debug messages.
+//
+// 2 7/09/09 5:18p Oleksiyy
+// Files clean-up some headers added
+//
+// 1 3/05/09 1:40p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeCommon.c
+//
+// Description:
+// This file contains routines used in PEI and DXE status code modules.
+// It contains two main function groups:
+// - Status Code Library (functions utilized throughout the component).
+// - Status Code initialization code. The initialization code enables
+// support of the multiple eLinks exposed by the status code module.
+// The eLinks are described in the AMI Aptio 4.x StatusCode Porting Guide.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiLib.h>
+#include <Token.h>
+#include <StatusCodeELinks.h>
+#include "StatusCodeInt.h"
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+
+BOOLEAN RouterRecurciveStatus = FALSE;
+#ifndef PEI_STATUS_CODE
+extern BOOLEAN InRscHandlerNotification;
+#include <Protocol/ReportStatusCodeHandler.h>
+
+extern EFI_BOOT_SERVICES *pBS;
+ROUTER_STRUCT_HEADER *RouterCallbackStr = NULL;
+
+BOOLEAN SmmRouter = FALSE;
+#endif
+#endif
+//------------------------------RouterEnd
+BOOLEAN StatusRuntime = FALSE;
+#ifdef PEI_STATUS_CODE
+#define PEI(x) x
+#define DXE(x) DUMMY_HANDLER
+#define RUNTIME(x) DUMMY_HANDLER
+#elif defined(DXE_STATUS_CODE)
+#define PEI(x) DUMMY_HANDLER
+#define DXE(x) x
+#define RUNTIME(x) DUMMY_HANDLER
+#endif
+
+#pragma pack(1)
+typedef struct
+{
+ UINT32 ErrorLevel;
+ // 12 * sizeof (UINT64) Var Arg stack
+ // ascii EFI_DEBUG () Format string
+} EFI_DEBUG_INFO;
+#pragma pack()
+#ifdef PEI_STATUS_CODE
+#define EFI_MAX_STRING_LENGTH 256
+#else
+#define EFI_MAX_STRING_LENGTH 2048
+#endif
+
+//----------------------------------------------------------------------------
+// GUID Definitions
+#define EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID \
+ {0x9A4E9246, 0xD553, 0x11D5, 0x87, 0xE2, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xb9}
+#define EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID \
+ {0xDA571595, 0x4D99, 0x487C, 0x82, 0x7C, 0x26, 0x22, 0x67, 0x7D, 0x33, 0x07}
+static EFI_GUID gEfiStatusCodeDataTypeDebugGuid = EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID;
+static EFI_GUID gEfiStatusCodeDataTypeAssertGuid = EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID;
+EFI_GUID gDataTypeStringGuid = EFI_STATUS_CODE_DATA_TYPE_STRING_GUID;
+EFI_GUID gSpecificDataGuid = EFI_STATUS_CODE_SPECIFIC_DATA_GUID;
+
+
+//**********************************************************************
+// Status Code Library (functions used throughout the module)
+//**********************************************************************
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindByteCode
+//
+// Description: Match "Value" to Map->Value and return Map->Byte.
+//
+// Input:
+// STATUS_CODE_TO_BYTE_MAP *Map - Pointer to a table (array of structures) that maps status code value (EFI_STATUS_CODE_VALUE) to a byte (UINT8) domain specific value.
+// EFI_STATUS_CODE_VALUE Value - status code to map
+//
+// Output:
+// UINT8 - domain specific mapping of the Value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8 FindByteCode(STATUS_CODE_TO_BYTE_MAP *Map, EFI_STATUS_CODE_VALUE Value)
+{
+ while (Map->Value!=0)
+ {
+ if (Map->Value==Value)
+ {
+ return Map->Byte;
+ }
+
+ Map++;
+ }
+
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportAssertString
+//
+// Description: This function creates a string from the ASSERT data
+//
+// Input:
+// IN EFI_STATUS_CODE_DATA *Data - Pointer to the beginning of the ASSERT data
+// OUT UINT8 *String - Pointer to the beginning of a byte String array
+//
+// Output: *String - Contains information from the ASSERT data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportAssertString(IN EFI_STATUS_CODE_DATA *Data, OUT UINT8 *String)
+{
+ EFI_DEBUG_ASSERT_DATA *AssertData;
+ CHAR8 *FileName;
+ UINT32 LineNum;
+ CHAR8 *Desc;
+
+ // gather the data for the different parts of the Assert Info
+ AssertData = (EFI_DEBUG_ASSERT_DATA *)Data;
+
+// TODO: Change this to use the FileName member of the data structure
+// be aware that the FileName member is another data structure
+ // get filename
+// FileName = AssertData->FileName.String;
+ FileName = (CHAR8 *) (AssertData + 1);
+
+ // get line number
+ LineNum = AssertData->LineNumber;
+
+// TODO: Change this to use the FileNameSize in the Data Structure.
+// Intel does not fill this in their worker function, so it is a junk value
+
+ // get description
+// Desc = Filename + AssertData->FileNameSize;
+ Desc = FileName + Strlen(FileName) + 1;
+
+ Sprintf_s(String, EFI_MAX_STRING_LENGTH, "ASSERT: %s, (%d) - %s", FileName, LineNum, Desc);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportData
+//
+// Description: This function creates a string for error types that have not
+// been predefined by the spec. This string contains the information in
+// the Type and Value parameters.
+//
+// Input:
+// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error
+// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused
+// the error
+// IN EFI_STATUS_CODE_DATA *Data - Data field that contains strings and values to be reported
+// OUT UINT8 *String - Pointer to the beginning of a byte String array
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportData(
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_STATUS_CODE_DATA *Data, OUT UINT8 *String
+)
+{
+ if (STATUS_CODE_TYPE(Type)!=EFI_ERROR_CODE) return EFI_UNSUPPORTED;
+
+ Sprintf_s(
+ String, EFI_MAX_STRING_LENGTH,
+ "ERROR: Type:%X; Severity:%X; Class:%X; Subclass:%X; Operation: %X\n",
+ Type&0xFF, Type>>24, Value >> 24, (Value >> 16)& 0xFF, Value & 0xFFFF
+ );
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportDebugInfo
+//
+// Description: This function creates a string from the debug informatoin packaged into
+// Intel-specific(not defined in the standard spec) EFI_DEBUG_INFO structure.
+//
+// Input: IN EFI_STATUS_CODE_DATA *Data - Pointer to the beginning of the ASSERT data
+//
+// Output: OUT UINT8 *String - Contains information in the ASSERT data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportDebugInfo(IN EFI_STATUS_CODE_DATA *Data, OUT UINT8 *String)
+{
+ va_list Marker;
+ CHAR8 *Format;
+ EFI_DEBUG_INFO *DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
+
+ // The first 12 * UINTN bytes of the string are really an
+ // argument stack to support varargs on the Format string.
+ Marker = (va_list) (DebugInfo + 1);
+ Format = (CHAR8 *)(((UINT64 *)Marker) + 12);
+
+ Sprintf_s_va_list(String, EFI_MAX_STRING_LENGTH, Format, Marker);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CreateString
+//
+// Description: This function converts the Type, Value, and Data into a string
+// that can be easily output to any console: serial, screen, data storage, etc.
+//
+// Input:
+// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error
+// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused
+// the error
+// IN EFI_STATUS_CODE_DATA *Data - Data field that contains strings and values to be reported
+// OUT UINT8 *String - Pointer to the beginning of a byte String array
+//
+// Output: EFI_STATUS
+// *String - points to the string that was created
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CreateString(
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_STATUS_CODE_DATA *Data,
+ OUT UINT8 *String
+)
+{
+ EFI_STATUS_CODE_STRING_DATA *StrData;
+ CHAR8 *StrAscii;
+ CHAR16 *StrUnicode;
+ UINT16 Count = 0;
+
+ if (Data != NULL)
+ {
+ // Check to see if the optional Data parameter is a standard string or
+ // if it is a more complex data structure
+ if (!guidcmp(&(Data->Type), &gDataTypeStringGuid))
+ {
+ // set pointers to different parts of the data structure for
+ // easier access to the data it contains
+ StrData = ( EFI_STATUS_CODE_STRING_DATA *)Data;
+
+ // Set up pointer to the beginning of both parts of the union
+ StrAscii = StrData->String.Ascii;
+ StrUnicode = StrData->String.Unicode;
+
+ // check for end of string or max length of output string
+ while ( ( ((StrData->StringType == EfiStringAscii)
+ && (*StrAscii != '\0'))
+ || ((StrData->StringType == EfiStringUnicode)
+ && (*StrUnicode != '\0')) )
+ && (Count < (EFI_MAX_STRING_LENGTH -1))
+ )
+ {
+ if (StrData->StringType == EfiStringAscii)
+ {
+ String[Count++] = *(StrAscii++);
+ }
+
+ else if (StrData->StringType == EfiStringUnicode)
+ {
+ String[Count] = (UINT8)(*(StrUnicode++));
+ // advance to the next character in the string
+ Count+=2;
+ }
+
+ else
+ {
+ return EFI_UNSUPPORTED;
+ }
+ }
+
+ String[Count] = '\0';
+ return EFI_SUCCESS;
+ }
+
+ else if ( !guidcmp (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid) )
+ {
+ ReportDebugInfo(Data, String);
+ }
+
+ else if (!guidcmp(&(Data->Type), &gSpecificDataGuid))
+ {
+ // This checks for an assert statement. Make a string of the data
+ // field
+ if ( ((Type & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)
+ && ((Type & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)
+ && ((Value & EFI_STATUS_CODE_OPERATION_MASK)== EFI_SW_EC_ILLEGAL_SOFTWARE_STATE)
+ && (Data != NULL)
+ )
+ {
+ ReportAssertString(Data, String);
+ }
+
+ else
+ {
+ ReportData(Type, Value, Data, String);
+ }
+ }
+
+ else if ( !guidcmp (&Data->Type, &gEfiStatusCodeDataTypeAssertGuid) )
+ {
+ //this is Intel specific GUID
+ //we have to use Data+1 because of Intel specific bug
+ ReportAssertString(Data+1, String);
+ }
+
+ else
+ {
+ ReportData(Type, Value, Data, String);
+ }
+ }
+
+ else // if (Data != NULL)
+ {
+ // If Data is NULL just report required data
+ ReportData(Type, Value, NULL, String);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Halt
+//
+// Description: Error Code Action.
+// Halts the execution.
+//
+// Input:
+// VOID *PeiServices - not used
+// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action.
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Halt(
+ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ EFI_DEADLOOP();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetOrHalt
+//
+// Description: Error Code Action.
+// Attempts to perform a system reset. If reset fails, halts the execution (calls Halt function).
+//
+// Input:
+// VOID *PeiServices - not used
+// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action.
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ResetOrHalt(
+ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ ResetOrResume(PeiServices,Value);
+ Halt(PeiServices, Value);
+}
+
+//**********************************************************************
+// Status Code Initialization
+//**********************************************************************
+typedef EFI_STATUS (INIT_FUNCTION)(IN VOID *ImageHandler, IN VOID *ServicesTable);
+typedef EFI_STATUS (STRING_FUNCTION)(IN VOID *PeiServices, IN CHAR8 *String);
+typedef EFI_STATUS (SIMPLE_FUNCTION)(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+);
+typedef EFI_STATUS (MISC_FUNCTION)(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+);
+typedef VOID (CHECKPOINT_FUNCTION)(IN VOID *PeiServices, IN UINT8 Checkpoint);
+
+EFI_STATUS DummyInitHandler(IN VOID *ImageHandler, IN VOID *ServicesTable) {return EFI_SUCCESS;}
+EFI_STATUS DummyStringHandler(IN VOID *PeiServices, IN CHAR8 *String) {return EFI_SUCCESS;}
+EFI_STATUS DummySimpleHandler(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+) {return EFI_SUCCESS;}
+EFI_STATUS DummyMiscHandler(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+) {return EFI_SUCCESS;}
+VOID DummyCheckpointHandler(IN VOID *PeiServices, IN UINT8 Checkpoint) {}
+
+#define DUMMY_HANDLER DummyInitHandler
+extern INIT_FUNCTION INIT_LIST EndOfInitList;
+INIT_FUNCTION* InitPartsList[] = {INIT_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummyStringHandler
+extern STRING_FUNCTION STRING_LIST EndOfStringList;
+STRING_FUNCTION* StringList[] = {STRING_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummySimpleHandler
+extern SIMPLE_FUNCTION SIMPLE_LIST EndOfSimpleList;
+SIMPLE_FUNCTION* SimpleList[] = {SIMPLE_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummyMiscHandler
+extern MISC_FUNCTION MISC_LIST EndOfMiscList;
+MISC_FUNCTION* MiscList[] = {MISC_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummyCheckpointHandler
+extern CHECKPOINT_FUNCTION CHECKPOINT_LIST EndOfCheckpointList;
+CHECKPOINT_FUNCTION* CheckpointList[] = {CHECKPOINT_LIST NULL};
+#undef DUMMY_HANDLER
+
+typedef STATUS_CODE_TO_BYTE_MAP STATUS_CODE_TO_BYTE_MAP_ARRAY[];
+
+extern STATUS_CODE_TO_BYTE_MAP_ARRAY
+CHECKPOINT_PROGRESS_CODES_MAP, CHECKPOINT_ERROR_CODES_MAP,
+BEEP_PROGRESS_CODES_MAP, BEEP_ERROR_CODES_MAP
+;
+
+STATUS_CODE_TO_BYTE_MAP* CheckPointStatusCodes[] =
+{
+ //#define EFI_PROGRESS_CODE 0x00000001
+ CHECKPOINT_PROGRESS_CODES_MAP,
+ //#define EFI_ERROR_CODE 0x00000002
+ CHECKPOINT_ERROR_CODES_MAP
+ //#define EFI_DEBUG_CODE 0x00000003
+};
+
+STATUS_CODE_TO_BYTE_MAP* BeepStatusCodes[] =
+{
+ //#define EFI_PROGRESS_CODE 0x00000001
+ BEEP_PROGRESS_CODES_MAP,
+ //#define EFI_ERROR_CODE 0x00000002
+ BEEP_ERROR_CODES_MAP
+ //#define EFI_DEBUG_CODE 0x00000003
+};
+
+#define ERROR_ACTION(Value,Action) Action
+#ifdef PEI_STATUS_CODE
+extern ERROR_CODE_ACTION PEI_ERROR_CODE_ACTIONS EndOfActionList;
+#else
+extern ERROR_CODE_ACTION DXE_ERROR_CODE_ACTIONS EndOfActionList;
+#endif
+#undef ERROR_ACTION
+#define ERROR_ACTION(Value,Action) {Value,&Action}
+
+ERROR_CODE_ACTION_MAP ErrorCodeActions[] =
+{
+#ifdef PEI_STATUS_CODE
+ PEI_ERROR_CODE_ACTIONS
+#endif
+#ifdef DXE_STATUS_CODE
+ DXE_ERROR_CODE_ACTIONS
+#endif
+ {0,0}
+};
+
+
+#undef PEI
+#undef DXE
+#undef RUNTIME
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitStatusCodeParts
+//
+// Description: calls initialization routines of status code subcomponents
+// registered under StatusCodeInitialize eLink.
+//
+// Input:
+// IN VOID *ImageHandler
+// IN VOID *ServicesTable
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitStatusCodeParts(IN VOID *ImageHandler, IN VOID *ServicesTable)
+{
+ UINTN i;
+
+ for (i=0; InitPartsList[i]; i++) InitPartsList[i](ImageHandler,ServicesTable);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StringStatusReport
+//
+// Description: Calls the string satus code handlers registered under ReportStringStatus eLink.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN CHAR8 *String
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StringStatusReport(IN VOID *PeiServices, IN CHAR8 *String)
+{
+ UINTN i;
+
+ for (i=0; StringList[i]; i++) StringList[i](PeiServices,String);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SimpleStatusReport
+//
+// Description: Calls simple status code handlers registered under ReportSimpleStatus eLink
+//
+// Input:
+// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services
+// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error
+// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused
+// the error
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID SimpleStatusReport(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ UINTN i;
+
+ for (i=0; SimpleList[i]; i++) SimpleList[i](PeiServices,Type,Value);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MiscStatusReport
+//
+// Description: Calls Misc. status code handlers
+// (handlers that consume all available status code data)
+// registered under ReportMiscStatus eLink
+//
+// Input:
+// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services
+// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error
+// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused
+// the error
+// IN UINT32 Instance - Instance
+// IN EFI_GUID *CallerId OPTIONAL - The GUID of the caller function
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID MiscStatusReport(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+ UINTN i;
+
+ for (i=0; MiscList[i]; i++) MiscList[i](PeiServices,Type,Value,Instance,CallerId,Data);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckpointStatusReport
+//
+// Description: Calls checkpoint status code handlers registered under ReportCheckpoint eLink.
+//
+// Input:
+// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services
+// IN UINT8 Checkpoint - checkpoint
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID CheckpointStatusReport(IN VOID *PeiServices, IN UINT8 Checkpoint)
+{
+ UINTN i;
+
+ for (i=0; CheckpointList[i]; i++) CheckpointList[i](PeiServices,Checkpoint);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PerformErrorCodeAction
+//
+// Description:
+// Scans list of error actions defined by the PeiErrorCodeActions/DxeErrorCodeActions lists.
+// If action corresponding to the passed in Value is found, performs the action.
+//
+// Input:
+// IN EFI_PEI_SERVICES *PeiServices - pointer to Pei Services
+// IN EFI_STATUS_CODE_TYPE Type - Contains the type and severity of the error
+// IN EFI_STATUS_CODE_VALUE Value - Contains the Class, SubClass, and Operation that caused
+// the error
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PerformErrorCodeAction(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ ERROR_CODE_ACTION_MAP *Map = ErrorCodeActions;
+
+ while (Map->Value!=0)
+ {
+ if (Map->Value==Value)
+ {
+ if (Map->Action!=NULL)
+ {
+ Map->Action(PeiServices,Value);
+ return;
+ }
+ }
+
+ Map++;
+ }
+}
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+
+BOOLEAN IsItRecursiveCall (
+ IN OUT BOOLEAN *Value,
+ IN BOOLEAN CompareWith,
+ IN BOOLEAN SvitchTo
+ )
+{
+ if (*Value == CompareWith)
+ {
+ *Value = SvitchTo;
+ return CompareWith;
+ }
+ else return *Value;
+
+}
+
+#ifndef PEI_STATUS_CODE
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportDxeAndRtRouter
+//
+// Description:
+// Top level status code reporting routine exposed by the status code protocol/PPI.
+// Calls the various types of status code handlers
+// (SimpleStatusReport, StringStatusReport, MiscStatusReport, PerformErrorCodeAction)
+// Generates string from the status code data to pass to StringStatusReport function.
+//
+// Input:
+// IN VOID *PeiServices - pointer to the PEI Boot Services table
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance -
+// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportDxeAndRtRouter (
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+{
+
+ RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
+ RSC_DATA_ENTRY *RscData;
+ EFI_STATUS Status;
+ VOID *NewBuffer = NULL, *Ptr;
+ EFI_TPL CurrentTpl = TPL_HIGH_LEVEL;
+ UINT32 i;
+
+ if ((RouterCallbackStr == NULL) || (IsItRecursiveCall (&RouterRecurciveStatus, FALSE, TRUE) == TRUE))
+ return EFI_ACCESS_DENIED;
+ for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++)
+ {
+
+ if (i == 0)
+ Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER);
+ else
+ Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY);
+ CallbackEntry = Ptr;
+
+ if (CallbackEntry->RscHandlerCallback == NULL) continue;//Unregistered function
+
+ if (!StatusRuntime)
+ {
+ CurrentTpl = pBS->RaiseTPL (TPL_HIGH_LEVEL);
+ pBS->RestoreTPL (CurrentTpl);
+ }
+
+ if ((CallbackEntry->Tpl >= CurrentTpl) || StatusRuntime)
+ {
+ CallbackEntry->RscHandlerCallback (Type, Value, Instance, CallerId, Data);
+ continue;
+ }
+
+
+ // If callback is registered with TPL lower than TPL_HIGH_LEVEL, event must be signaled at boot time to possibly wait for
+ // allowed TPL to report status code. Related data should also be stored in data buffer.
+
+ RscData = (RSC_DATA_ENTRY *) (UINTN) CallbackEntry->EndPointer;
+ CallbackEntry->EndPointer += sizeof (RSC_DATA_ENTRY);
+ if (Data != NULL)
+ CallbackEntry->EndPointer += Data->Size;
+
+
+ // If data buffer is about to be used up (7/8 here), try to reallocate a buffer with double size, if not at TPL_HIGH_LEVEL.
+
+ if (CallbackEntry->EndPointer > (CallbackEntry->StatusCodeDataBuffer + (CallbackEntry->BufferSize / 8) * 7))
+ {
+ if ((CurrentTpl < TPL_HIGH_LEVEL) && !InRscHandlerNotification)
+ {
+ Status = pBS->AllocatePool (EfiRuntimeServicesData, CallbackEntry->BufferSize * 2, &NewBuffer);
+ //ASSERT_EFI_ERROR (Status);
+ if (NewBuffer != NULL && CallbackEntry->StatusCodeDataBuffer != NULL)
+ {
+ pBS->SetMem(NewBuffer, CallbackEntry->BufferSize * 2, 0);
+ MemCpy (NewBuffer, (VOID*)CallbackEntry->StatusCodeDataBuffer, CallbackEntry->BufferSize);
+ pBS->FreePool ((VOID *) (UINTN) CallbackEntry->StatusCodeDataBuffer);
+ }
+
+ if (NewBuffer != NULL)
+ {
+ CallbackEntry->EndPointer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer + (CallbackEntry->EndPointer - CallbackEntry->StatusCodeDataBuffer);
+ CallbackEntry->StatusCodeDataBuffer = (EFI_PHYSICAL_ADDRESS) (UINTN) NewBuffer;
+ CallbackEntry->BufferSize *= 2;
+ }
+ }
+ }
+
+
+ // If data buffer is used up, do not report for this time.
+
+ if (CallbackEntry->EndPointer > (CallbackEntry->StatusCodeDataBuffer + CallbackEntry->BufferSize))
+ continue;
+
+ RscData->Type = Type;
+ RscData->Value = Value;
+ RscData->Instance = Instance;
+ if (CallerId != NULL)
+ MemCpy (&RscData->CallerId, CallerId, sizeof (EFI_GUID));
+
+ if (Data != NULL)
+ MemCpy (&RscData->Data, Data, Data->HeaderSize + Data->Size);
+
+ Status = pBS->SignalEvent (CallbackEntry->Event);
+
+ }
+ // Restore the Recursive status of report
+
+ IsItRecursiveCall (&RouterRecurciveStatus, TRUE, FALSE);
+ return EFI_SUCCESS;
+}
+#endif
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportStatusCode
+//
+// Description:
+// Top level status code reporting routine exposed by the status code protocol/PPI.
+// Calls the various types of status code handlers
+// (SimpleStatusReport, StringStatusReport, MiscStatusReport, PerformErrorCodeAction)
+// Generates string from the status code data to pass to StringStatusReport function.
+//
+// Input:
+// IN VOID *PeiServices - pointer to the PEI Boot Services table
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance -
+// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportStatusCode (
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+#if STRING_STATUS_SUPPORT
+ UINT8 String[EFI_MAX_STRING_LENGTH];
+#endif
+ SimpleStatusReport(PeiServices,Type,Value);
+#if STRING_STATUS_SUPPORT
+ String[0] = '\0';
+ CreateString(Type, Value, Data, String);
+
+ // step through the useable data and display information as needed
+ // Serial data
+ if (String[0] != '\0') StringStatusReport(PeiServices,String);
+
+#endif
+ MiscStatusReport(PeiServices,Type,Value,Instance,CallerId,Data);
+
+ if (STATUS_CODE_TYPE(Type)==EFI_ERROR_CODE)
+ PerformErrorCodeAction(PeiServices,Type,Value);
+#ifndef PEI_STATUS_CODE
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ if ((PeiServices == NULL) && !SmmRouter)
+ ReportDxeAndRtRouter(Type, Value, Instance, CallerId, Data);
+#endif
+#endif
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+// Status Code Transports
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Port80Checkpoint
+//
+// Description: Outputs checkpoint value to port 0x80
+// To support different checkpoint displaying hardware do not port this function.
+// Use ReportCheckpoint eLink based interface instead.
+//
+// Input:
+// VOID *PeiServices - pointer to the PEI Boot Services table,
+// IN UINTN Checkpoint - checkpoint to display
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Port80Checkpoint(IN VOID *PeiServices, IN UINT8 Checkpoint)
+{
+ checkpoint(Checkpoint);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CheckPointStatus
+//
+// Description:
+// Looks up the checkpoint for the given status code Type
+// and Value and calls CheckpointStatusReport function to invoke all checkpoint handlers.
+//
+// Input:
+// IN VOID *PeiServices - pointer to the PEI Boot Services table
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS CheckPointStatus(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ UINT8 n;
+ UINT32 CodeTypeIndex = STATUS_CODE_TYPE(Type) - 1;
+
+ if (CodeTypeIndex >= sizeof(CheckPointStatusCodes)/sizeof(STATUS_CODE_TO_BYTE_MAP*) )
+ return EFI_SUCCESS;
+
+ n=FindByteCode(CheckPointStatusCodes[CodeTypeIndex],Value);
+
+ if (n>0) CheckpointStatusReport(PeiServices,n);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeepOn
+//
+// Description: Initiates generation of the sound corresponding
+// to the passed in musical note/octave pair using legacy PC/AT speaker.
+//
+// Input:
+// UINT8 note - a note to play
+// UINT8 octave - an octave for the note
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BeepOn(UINT8 note, UINT8 octave)
+{
+ // beep tones
+#define note(x) ((119318200+(x)/2)/(x))
+ UINT16 tones[8]={note(26163),note(29366),note(32963),note(34923),note(39200),note(44000),note(49388),note(26163*2)};
+ UINT16 Frequency=tones[(note%8)];
+
+ if (octave-1>=0) Frequency>>=octave-1;
+ else Frequency<<=1-octave;
+
+ //set up channel 1 (used for delays)
+ IoWrite8(0x43,0x54);
+ IoWrite8(0x41,0x12);
+ //set up channel 2 (used by speaker)
+ IoWrite8(0x43,0xb6);
+ IoWrite8(0x42,(UINT8)Frequency);
+ IoWrite8(0x42,(UINT8)(Frequency>>8));
+ //turn the speaker on
+ IoWrite8(0x61,IoRead8(0x61)|3);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeepOff
+//
+// Description: Stops generation of the legacy PC/AT speaker sound started by the BeepOn routine.
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID BeepOff()
+{
+ IoWrite8(0x61,IoRead8(0x61)&0xfc);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Beep
+//
+// Description: Generates sound of the specified duration corresponding
+// to the passed in musical note/octave pair using legacy PC/AT speaker.
+// Control flow:
+// BeepOn
+// Delay
+// BeepOff
+//
+// Input:
+// VOID *PeiServices - pointer to the PEI Boot Services table
+// UINT8 note - a note to play
+// UINT8 octave - an octave for the note
+// UINT32 duration - sound duration in microseconds.
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Beep(VOID *PeiServices, UINT8 note, UINT8 octave, UINT32 duration)
+{
+ BeepOn(note,octave);
+ Delay(PeiServices, duration);
+ BeepOff();
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeepStatus
+//
+// Description: Simple Status Code handler that generates beep codes for a certain types of
+// progress and error codes defined by the BEEP_PROGRESS_CODES_MAP and BEEP_ERROR_CODES_MAP mapping tables.
+//
+// Input:
+// EFI_PEI_SERVICES *PeiServices, - pointer to the PEI Boot Services table
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+//
+// Output:
+// EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BeepStatus(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ UINT32 CodeTypeIndex = STATUS_CODE_TYPE(Type) - 1;
+ UINT8 i,n;
+
+ if (CodeTypeIndex >= sizeof(BeepStatusCodes)/sizeof(STATUS_CODE_TO_BYTE_MAP*) ) return EFI_SUCCESS;
+
+ n = FindByteCode(BeepStatusCodes[CodeTypeIndex],Value);
+
+ if (n>0)
+ {
+ for (i=0; i<n; i++)
+ {
+ Beep(PeiServices,1,2,400000);
+ Delay(PeiServices,100000);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BeepService
+//
+// Description:
+// This function plays Value quantity of beeps
+//
+// Input:
+// IN VOID *PeiServices - pointer to the PEI Boot Services table
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance -
+// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BeepService(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+ UINT8 n;
+
+ if ((Value&0xFF00)!=AMI_STATUS_CODE_BEEP_CLASS) return EFI_SUCCESS;
+
+ n = (UINT8)Value;
+
+ if (n)
+ {
+ UINT8 i;
+
+ for (i=0; i<n; i++) { Beep(PeiServices,0,4,40000); Delay(PeiServices,100000);}
+ }
+
+ return EFI_SUCCESS;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/StatusCode/StatusCodeDxe.c b/Core/EM/StatusCode/StatusCodeDxe.c
new file mode 100644
index 0000000..2917f32
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCodeDxe.c
@@ -0,0 +1,883 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeDxe.c 8 11/13/12 6:21p Oleksiyy $
+//
+// $Revision: 8 $
+//
+// $Date: 11/13/12 6:21p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeDxe.c $
+//
+// 8 11/13/12 6:21p Oleksiyy
+// [TAG] EIP106198
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Memory leak in DataHubStatusCode function of
+// StatusCodeDxe.c
+// [RootCause] Memory allocated for the Record was newer released.
+// [Solution] FreePool operation added.
+// [Files] StatusCodeDxe.c
+//
+// 7 6/12/12 3:50p Oleksiyy
+// [TAG] EIP90338
+// [Category] Improvement
+// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to
+// AmiLib.h.
+// [Files] AmiLib.h, StatusCodeDxe.c and StatusCoderuntime.c
+//
+// 6 5/22/12 5:31p Oleksiyy
+// [TAG] EIP90338
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail on item Generic Test\EFI Compliant Test
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c, StatusCodeDxe.c and StatusCoderuntime.c
+//
+// 5 6/23/11 6:09p Oleksiyy
+// [TAG] EIP56644
+// [Category] New Feature
+// [Description] Implemented PPI and Protocols, described in a PI 1.2
+// Report Status Code Router specification.
+// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h,
+// StatusCodeCommon.c and StatusCodeRuntime.c
+//
+// 4 2/25/11 11:12a Oleksiyy
+// [TAG] EIP54703
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Disabling "CON_OUT_CHECKPOINTS_IN_QUIET_MODE" token, ends
+// with build error
+// [RootCause] Wrong dependency from CON_OUT_CHECKPOINTS_IN_QUIET_MODE
+// [Solution] Declaration of Foreground and Background variables now
+// also depend from CON_OUT_CHECKPOINTS_IN_QUIET_MODE value.
+// [Files] StatusCodeDxe.c
+//
+// 3 11/17/10 6:02p Oleksiyy
+// [TAG] EIP39752
+// [Category] Improvement
+// [Description] Bug fix. Status code moved to EfiRuntimeServicesData
+// memory.
+// [Files] StatusCodeDxe.c
+//
+// 2 7/09/09 5:18p Oleksiyy
+// Files clean-up some headers added
+//
+// 1 3/05/09 1:40p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeDxe.c
+//
+// Description:
+// File contains DXE specific status code routines such as:
+// - Entry point of the StatusCode DXE driver
+// DXE implementation of some of the functions from the status code library.
+// Implementation of the data hub logger (status code subcomponent that logs status codes into the data hub)
+// Implementation of the ConOut checkpoints (status code subcomponent that displays checkpoints on all ConOut devices).
+// (Status code library is a set of generic routines utilized throughout the component).
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiDxeLib.h>
+#include <StatusCodes.h>
+#include <Token.h>
+#include <Protocol/StatusCode.h>
+#include <Protocol/DataHub.h>
+#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE
+#include <Protocol/AmiPostMgr.h>
+#endif
+#include <Protocol/ConsoleControl.h>
+#include <Protocol/SimpleTextOut.h>
+#include "StatusCodeInt.h"
+
+EFI_DATA_HUB_PROTOCOL *DataHub = NULL;
+EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
+#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE
+AMI_POST_MANAGER_PROTOCOL *PostManager = NULL;
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL Foreground = {0xFF,0xFF,0xFF,0};
+EFI_GRAPHICS_OUTPUT_BLT_PIXEL Background = {0,0,0,0};
+static EFI_GUID gAmiPostManagerProtocolGuid = AMI_POST_MANAGER_PROTOCOL_GUID;
+#endif
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+//----Router------------------------------------
+#include <Protocol/Variable.h>
+#include <Protocol/ReportStatusCodeHandler.h>
+
+extern ROUTER_STRUCT_HEADER *RouterCallbackStr;
+#define SC_ROUTER_ENTRIES 0xF
+
+//----Router End---------------------------------
+#endif
+extern BOOLEAN StatusRuntime;
+
+#define EFI_STANDARD_CALLER_ID_GUID \
+ {0xC9DCF469, 0xA7C4, 0x11D5, 0x87, 0xDA, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9}
+
+#define EFI_STATUS_CODE_GUID \
+ {0xd083e94c, 0x6560, 0x42e4, 0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a}
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+BOOLEAN InRscHandlerNotification = FALSE;
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RscHandlerNotification
+//
+// Description:
+// Executes delayed calls (when current TPL is higher that one router was
+// registered with) to registered status code routers.
+//
+// Input:
+// N EFI_EVENT Event - signaled event.
+// IN VOID *Context - pointer to structure with parameters.
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RscHandlerNotification (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
+ EFI_PHYSICAL_ADDRESS Address;
+ RSC_DATA_ENTRY *RscData;
+
+ CallbackEntry = (RSC_HANDLER_CALLBACK_ENTRY *) Context;
+
+
+ // Traverse the status code data buffer to parse all data to report.
+
+ Address = CallbackEntry->StatusCodeDataBuffer;
+ InRscHandlerNotification = TRUE;
+ while (Address < CallbackEntry->EndPointer)
+ {
+ RscData = (RSC_DATA_ENTRY *) (UINTN) Address;
+ CallbackEntry->RscHandlerCallback (
+ RscData->Type,
+ RscData->Value,
+ RscData->Instance,
+ &RscData->CallerId,
+ &RscData->Data
+ );
+
+ Address += (sizeof (RSC_DATA_ENTRY) + RscData->Data.Size);
+ }
+
+ CallbackEntry->EndPointer = CallbackEntry->StatusCodeDataBuffer;
+ InRscHandlerNotification = FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RouterRegister
+//
+// Description: Register the callback function for ReportStatusCode() notification
+// in DXE and Runtime.
+//
+// Input:
+// IN EFI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type
+// EFI_RSC_HANDLER_CALLBACK that is to be registered.
+// IN EFI_TPL Tpl - TPL at which callback can be safely invoked.
+//
+// Output:
+// EFI_SUCCESS The function was successfully registered.
+// EFI_INVALID_PARAMETER The callback function was NULL.
+// EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions can be
+// registered.
+// EFI_ALREADY_STARTED The function was already registered. It can't be registered again.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RouterRegister (
+ IN EFI_RSC_HANDLER_CALLBACK Callback,
+ IN EFI_TPL Tpl
+ )
+{
+ EFI_STATUS Status;
+ RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
+ UINT32 i;
+ VOID *Ptr, *UnregisteredPtr=NULL;
+
+ if (Callback == NULL)
+ return EFI_INVALID_PARAMETER;
+ if (RouterCallbackStr == NULL)
+ return EFI_OUT_OF_RESOURCES;
+
+ Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER);
+
+ for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++)
+ {
+ CallbackEntry = Ptr;
+
+ if (CallbackEntry->RscHandlerCallback == NULL)
+ {
+ UnregisteredPtr = Ptr;
+ }
+ else
+ {
+ if (CallbackEntry->RscHandlerCallback == Callback)
+ // If the function was already registered. It can't be registered again.
+ return EFI_ALREADY_STARTED;
+ }
+ Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY);
+ }
+ if (UnregisteredPtr == NULL) //No Unregistered entries
+ {
+ if (RouterCallbackStr->RegisteredEntries == RouterCallbackStr->TotalEntries)
+ return EFI_OUT_OF_RESOURCES; // And all entries are taken already - exit
+ CallbackEntry = Ptr;
+ RouterCallbackStr->RegisteredEntries++;
+ }
+ else
+ CallbackEntry = UnregisteredPtr; // Will fill uregistered entry
+
+ CallbackEntry->RscHandlerCallback = Callback;
+ CallbackEntry->Tpl = Tpl;
+
+ // If TPL of registered callback funtion is not TPL_HIGH_LEVEL, then event should be created
+ // for it, and related buffer for status code data should be prepared.
+ // Here the data buffer must be prepared in advance, because Report Status Code Protocol might
+ // be invoked under TPL_HIGH_LEVEL and no memory allocation is allowed then.
+ // If TPL is TPL_HIGH_LEVEL, then all status code will be reported immediately, without data
+ // buffer and event trigger.
+ if ((Tpl != TPL_HIGH_LEVEL) && !StatusRuntime)
+ {
+ VOID *StatusCodeDataBuff;
+ Status = pBS->AllocatePool (EfiRuntimeServicesData, EFI_PAGE_SIZE, &StatusCodeDataBuff);
+ CallbackEntry->StatusCodeDataBuffer = (EFI_PHYSICAL_ADDRESS) (UINTN) StatusCodeDataBuff;
+ CallbackEntry->BufferSize = EFI_PAGE_SIZE;
+ CallbackEntry->EndPointer = CallbackEntry->StatusCodeDataBuffer;
+ Status = pBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ Tpl,
+ RscHandlerNotification,
+ CallbackEntry,
+ &CallbackEntry->Event
+ );
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RouterUnregister
+//
+// Description: Remove a previously registered callback function from the notification list.
+//
+// Input:
+// IN EFI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type
+// EFI_RSC_HANDLER_CALLBACK that is to be unregistered.
+//
+// Output:
+// EFI_SUCCESS The function was successfully unregistered.
+// EFI_INVALID_PARAMETER The callback function was NULL.
+// EFI_NOT_FOUND The callback function was not found to be unregistered.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RouterUnregister (IN EFI_RSC_HANDLER_CALLBACK Callback)
+{
+ RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
+ UINT32 i;
+ VOID *Ptr;
+
+ if (Callback == NULL)
+ return EFI_INVALID_PARAMETER;
+ if (RouterCallbackStr == NULL)
+ return EFI_NOT_FOUND;
+
+ Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER);
+
+ for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++)
+ {
+ CallbackEntry = Ptr;
+
+ if (CallbackEntry->RscHandlerCallback == Callback)
+ {
+
+ // If the function is found in list, delete it and return.
+
+ if ((CallbackEntry->Tpl != TPL_HIGH_LEVEL) && (CallbackEntry->StatusCodeDataBuffer != 0))
+ {
+ pBS->FreePool ((VOID *) (UINTN) CallbackEntry->StatusCodeDataBuffer);
+ pBS->CloseEvent (CallbackEntry->Event);
+ }
+ pBS->SetMem(Ptr, sizeof(RSC_HANDLER_CALLBACK_ENTRY), 0);//Clear all data in entry
+ return EFI_SUCCESS;
+ }
+ Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY);
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+EFI_RSC_HANDLER_PROTOCOL RscHandlerProtocol = {
+ RouterRegister,
+ RouterUnregister
+ };
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PassRouterAdress
+//
+// Description: Sets variable with the address of RSC Info structure.
+//
+// Input:
+// IN EFI_EVENT Event
+// IN VOID *Context
+//
+// Output:
+// VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID PassRouterAdress(IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_PHYSICAL_ADDRESS RSCInfoAddresss = (EFI_PHYSICAL_ADDRESS) (UINTN) RouterCallbackStr;
+
+
+ if (RouterCallbackStr == NULL)
+ return;
+ pRS->SetVariable(
+ L"RSCInfoAddresss",
+ &gAmiGlobalVariableGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS,
+ sizeof(EFI_PHYSICAL_ADDRESS),
+ &RSCInfoAddresss
+ );
+
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Delay
+//
+// Description: Stalls execution for a passed in number of microseconds
+//
+// Input:
+// VOID *PeiServices - not used
+// UINT32 Microseconds - the number of microseconds to stall execution
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Delay(VOID **PeiServices, UINT32 Microseconds)
+{
+ pBS->Stall(Microseconds);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeReportStatusCode
+//
+// Description: DXE Status Code Reporting function.
+// A wrapper around phase independent ReportStatucCode
+// function defined in StatusCodeCommon.c.
+//
+// Input:
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance Instance - Instance
+// *CallerId OPTIONAL - The GUID of the caller function
+// *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+ //If we are in runtime don't do anything.
+ //Port this code if runtime status code is required.
+ if (StatusRuntime) return EFI_SUCCESS;
+
+ return ( ReportStatusCode( NULL, Type, Value, Instance, CallerId, Data));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StatusCodeExitBS
+//
+// Description: Exit Boot Services event handler.
+// Terminates boot time status code processing
+//
+// Input:
+// IN EFI_EVENT Event - not used
+// IN VOID *Context - not used
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StatusCodeExitBS (IN EFI_EVENT Event, IN VOID *Context)
+{
+ StatusRuntime = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DxeInitStatusCode
+//
+// Description:
+// Entry point of the StatusCode Driver.
+// Calls InitStatusCodeParts function, installs the Status Code Protocol,
+// and registers event handlers for the legacy boot and exit boot services events.
+// DxeInitStatusCode installs different protocol based on value of the
+// EFI_SPECIFICATION_VERSION SDL token (defined in Core.sdl).
+// If value of the EFI_SPECIFICATION_VERSION constant is less than 0x20000,
+// framework EFI_STATUS_CODE_ARCH_PROTOCOL_GUID protocol is installed;
+// otherwise, PI EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID protocol is installed.
+// PI Status Code Protocol is initialized with the address of DxeReportStatusCode function.
+//
+// Input:
+// *ImageHandle - The firmware allocate handle for the EFI image
+// *SystemTable - pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+// Modified: StatusCode Arch Protocol- now published
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DxeInitStatusCode(
+ IN EFI_HANDLE *ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE StatusCodeHandle = NULL;
+ EFI_EVENT Event;
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ EFI_EVENT VarEvent = NULL;
+ VOID *VarReg;
+#endif
+#if EFI_SPECIFICATION_VERSION >= 0x20000
+ static EFI_STATUS_CODE_PROTOCOL *StatusCode;
+#endif
+ InitStatusCodeParts(ImageHandle,SystemTable);
+
+#if EFI_SPECIFICATION_VERSION >= 0x20000
+ Status = pBS->AllocatePool (
+ EfiRuntimeServicesData, sizeof(EFI_STATUS_CODE_PROTOCOL), &StatusCode
+ );
+ if (EFI_ERROR(Status)) return Status;
+ StatusCode->ReportStatusCode = DxeReportStatusCode;
+#endif
+#if EFI_SPECIFICATION_VERSION < 0x20000
+ SystemTable->RuntimeServices->ReportStatusCode = DxeReportStatusCode;
+#endif
+ Status = SystemTable->BootServices->InstallProtocolInterface(
+ &StatusCodeHandle,
+#if EFI_SPECIFICATION_VERSION < 0x20000
+ &gEfiStatusCodeArchProtocolGuid,
+#else
+ &gEfiStatusCodeRuntimeProtocolGuid,
+#endif
+ EFI_NATIVE_INTERFACE,
+#if EFI_SPECIFICATION_VERSION < 0x20000
+ NULL
+#else
+ StatusCode
+#endif
+ );
+ //Register Exit Boot Services Callback
+ pBS->CreateEvent(
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,TPL_CALLBACK,
+ &StatusCodeExitBS, NULL, &Event
+ );
+ CreateLegacyBootEvent(TPL_CALLBACK, &StatusCodeExitBS, NULL, &Event);
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ //Allocate memory for Status Code Router inforstructure
+ Status = pBS->AllocatePool (EfiRuntimeServicesData,
+ sizeof(ROUTER_STRUCT_HEADER) + (sizeof(RSC_HANDLER_CALLBACK_ENTRY) * SC_ROUTER_ENTRIES),
+ &RouterCallbackStr);
+ if (EFI_ERROR(Status)) return Status;
+ pBS->SetMem(RouterCallbackStr, sizeof(ROUTER_STRUCT_HEADER) +
+ (sizeof(RSC_HANDLER_CALLBACK_ENTRY) * SC_ROUTER_ENTRIES), 0);
+ RouterCallbackStr->TotalEntries = SC_ROUTER_ENTRIES;
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &StatusCodeHandle,
+ &gEfiRscHandlerProtocolGuid,
+ &RscHandlerProtocol,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ Status = RegisterProtocolCallback(&gEfiVariableArchProtocolGuid,PassRouterAdress,NULL,&VarEvent,&VarReg);
+
+ ASSERT_EFI_ERROR(Status);
+#endif
+ return Status;
+}
+
+//<AMI_GHDR_START>
+//----------------------------------------------------------------------------
+// Name: Data_Hub_Logging
+//
+// Description:
+// DataHub Logging Functions:
+// - DataHubInint
+// - DataHubInstalled
+// - DataHubStatusCode
+//----------------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DataHubStatusCode
+//
+// Description: Logs status code data into the data hub
+//
+// Input:
+// IN EFI_STATUS_CODE_TYPE Type
+// IN EFI_STATUS_CODE_VALUE Value
+// IN UINT32 Instance
+// IN EFI_GUID *CallerId OPTIONAL
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DataHubStatusCode (
+ IN VOID **Dummy, //dummy parameter for compatibility with PEI callback interface
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+ EFI_STATUS Status;
+ DATA_HUB_STATUS_CODE_DATA_RECORD *Record;
+ UINT32 Size;
+ UINT8 CodeType = STATUS_CODE_TYPE(Type);
+
+ static EFI_GUID gEfiCallerIdGuid = EFI_STANDARD_CALLER_ID_GUID;
+ static EFI_GUID gEfiStatusCodeGuid = EFI_STATUS_CODE_GUID;
+ static EFI_GUID gEfiStatusCodeRuntimeProtocolGuid = EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID;
+ static UINT8 DataHubClasses[] = {EFI_DATA_CLASS_PROGRESS_CODE,EFI_DATA_CLASS_ERROR,EFI_DATA_CLASS_DEBUG};
+
+ if (DataHub == NULL) return EFI_NOT_AVAILABLE_YET;
+
+ //Do not log debug codes
+ if (CodeType==EFI_DEBUG_CODE) return EFI_SUCCESS;
+
+ if (CodeType > sizeof(DataHubClasses)) return EFI_INVALID_PARAMETER;
+
+ if (Data!=NULL)
+ Size = EFI_FIELD_OFFSET(DATA_HUB_STATUS_CODE_DATA_RECORD,Data)
+ +Data->HeaderSize+Data->Size;
+ else
+ Size = sizeof(DATA_HUB_STATUS_CODE_DATA_RECORD);
+
+ pBS->AllocatePool(EfiBootServicesData,Size,&Record);
+ //---Fill Record structure--------
+ Record->CodeType = Type;
+ Record->Value = Value;
+ Record->Instance = Instance;
+
+ if (CallerId==NULL) Record->CallerId = gEfiCallerIdGuid;
+ else Record->CallerId = *CallerId;
+
+ if (Data==NULL)
+ pBS->SetMem(&Record->Data,sizeof(EFI_STATUS_CODE_DATA),0);
+ else
+ pBS->CopyMem(&Record->Data,Data,Data->HeaderSize+Data->Size);
+
+ Status = DataHub->LogData(
+ DataHub,
+ &gEfiStatusCodeGuid,
+ &gEfiStatusCodeRuntimeProtocolGuid,
+ DataHubClasses[CodeType-1],
+ Record,
+ Size
+ );
+ pBS->FreePool(Record);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DataHubInstalled
+//
+// Description: Callback routine. Activates data hub status code logging once DataHub protocol is installed.
+//
+// Input:
+// IN EFI_EVENT Event - Signalled Event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID DataHubInstalled (IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+
+ if (DataHub!=NULL) return;
+
+ Status = pBS->LocateProtocol(&gEfiDataHubProtocolGuid,NULL,&DataHub);
+
+ if (EFI_ERROR(Status)) DataHub=NULL;
+ else pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DataHubInit
+//
+// Description: Initializes data hub error logging infrastructure.
+// This function is called from InitStatusCodeParts function (in DXE only).
+//
+// Input:
+// IN EFI_HANDLE *ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS DataHubInit(
+ IN EFI_HANDLE *ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_EVENT Event;
+ VOID *Registration;
+ //Register Data Hub Callback
+ EFI_STATUS Status = RegisterProtocolCallback(
+ &gEfiDataHubProtocolGuid, DataHubInstalled, NULL,
+ &Event, &Registration
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SignalEvent(Event);
+ return Status;
+}
+
+//<AMI_GHDR_START>
+//----------------------------------------------------------------------------
+// Name: Con_Out_Checkpoints
+//
+// Description:
+// ConOut checkpoints functions:
+// - ConOutCpInit
+// - ConOutInstalled
+// - StopConOutCheckpoints
+// - ConOutCheckpoint
+//----------------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConOutCheckpoint
+//
+// Description: Displays checkpoints at the right bottom corner or the ConOut devices.
+//
+// Input:
+// IN VOID *Dummy - not used. Dummy parameter for compatibility with PEI callback interface.
+// IN UINT8 Checkpoint - checkpoint to display
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConOutCheckpoint (
+ IN VOID *Dummy,
+ IN UINT8 Checkpoint
+)
+{
+ EFI_STATUS Status;
+ EFI_CONSOLE_CONTROL_SCREEN_MODE Mode;
+ CHAR16 s[10];
+
+ if (ConsoleControl==NULL || pST->ConOut==NULL
+#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE
+ || PostManager == NULL
+#endif
+ ) return EFI_NOT_AVAILABLE_YET;
+
+ Status = ConsoleControl->GetMode(ConsoleControl,&Mode,NULL,NULL);
+
+ if (EFI_ERROR(Status)) return Status;
+
+ //TODO: try Sprintf and convert
+ Swprintf(s, L"%X",Checkpoint);
+
+ if (Mode==EfiConsoleControlScreenText)
+ {
+ UINTN X,Y, MaxX, MaxY;
+ pST->ConOut->QueryMode(pST->ConOut,pST->ConOut->Mode->Mode, &MaxX, &MaxY);
+ //Get cursor position
+ X = pST->ConOut->Mode->CursorColumn;
+ Y = pST->ConOut->Mode->CursorRow;
+ //Set cursor and print string
+ pST->ConOut->SetCursorPosition(pST->ConOut, MaxX-3, MaxY-1);
+ pST->ConOut->OutputString(pST->ConOut, s);
+ //Restore cursor position
+ pST->ConOut->SetCursorPosition(pST->ConOut, X, Y);
+ }
+
+#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE
+ else // EfiConsoleControlScreenGraphics
+ {
+ PostManager->DisplayQuietBootMessage(
+ s, 0, 0, CA_AttributeRightBottom,
+ Foreground, Background
+ );
+ }
+
+#endif
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StopConOutCheckpoints
+//
+// Description: Read To Boot Callback routine. Terminates ConOut checkpoint display.
+//
+// Input:
+// IN EFI_EVENT Event - Signalled Event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID StopConOutCheckpoints (IN EFI_EVENT Event, IN VOID *Context)
+{
+ ConsoleControl=NULL;
+ pBS->CloseEvent(Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConOutInstalled
+//
+// Description: Callback routine. Activates ConOut checkpoint display once
+// ConOut field in the UEFI ststem table is populated.
+//
+// Input:
+// IN EFI_EVENT Event - Signalled Event
+// IN VOID *Context - calling context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ConOutInstalled (IN EFI_EVENT Event, IN VOID *Context)
+{
+ EFI_STATUS Status;
+
+ if (ConsoleControl!=NULL) return;
+
+#if CON_OUT_CHECKPOINTS_IN_QUIET_MODE
+ Status = pBS->LocateProtocol(&gAmiPostManagerProtocolGuid,NULL,&PostManager);
+
+ if (EFI_ERROR(Status)) PostManager=NULL;
+
+#endif
+ Status = pBS->LocateProtocol(&gEfiConsoleControlProtocolGuid,NULL,&ConsoleControl);
+
+ if (EFI_ERROR(Status)) ConsoleControl=NULL;
+ else pBS->CloseEvent(Event);
+
+ CreateReadyToBootEvent(TPL_CALLBACK, &StopConOutCheckpoints, NULL, &Event);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ConOutCpInit
+//
+// Description: Initializes ConOut checkpoint display code.
+// This function is called from InitStatusCodeParts function (in DXE only).
+//
+// Input:
+// IN EFI_HANDLE *ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ConOutCpInit (
+ IN EFI_HANDLE *ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_EVENT Event;
+ VOID *Registration;
+ //Register Data Hub Callback
+ EFI_STATUS Status = RegisterProtocolCallback(
+ &gEfiConsoleControlProtocolGuid, ConOutInstalled, NULL,
+ &Event, &Registration
+ );
+
+ if (EFI_ERROR(Status)) return Status;
+
+ pBS->SignalEvent(Event);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetOrResume
+//
+// Description: Error Code Action.
+// Attempts to perform a system reset. If reset fails, returns.
+//
+// Input:
+// VOID *PeiServices - not used
+// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action.
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ResetOrResume(
+ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ pRS->ResetSystem(EfiResetCold,0,0,NULL);
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/StatusCode/StatusCodeInt.h b/Core/EM/StatusCode/StatusCodeInt.h
new file mode 100644
index 0000000..c60e6ec
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCodeInt.h
@@ -0,0 +1,125 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeInt.h 3 6/23/11 6:10p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 6/23/11 6:10p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeInt.h $
+//
+// 3 6/23/11 6:10p Oleksiyy
+// [TAG] EIP56644
+// [Category] New Feature
+// [Description] Implemented PPI and Protocols, described in a PI 1.2
+// Report Status Code Router specification.
+// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h,
+// StatusCodeCommon.c and StatusCodeRuntime.c
+//
+// 2 7/09/09 5:18p Oleksiyy
+// Files clean-up some headers added
+//
+// 1 3/05/09 1:40p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeInt.c
+//
+// Description: Header file containing declarations of functions, macros, and types shared across status code module files.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __STATUS_CODE_INT__H__
+#define __STATUS_CODE_INT__H__
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+ typedef struct
+ {
+ EFI_STATUS_CODE_VALUE Value;
+ UINT8 Byte;
+ } STATUS_CODE_TO_BYTE_MAP;
+
+ typedef VOID (ERROR_CODE_ACTION)(
+ IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value
+ );
+
+ typedef struct
+ {
+ EFI_STATUS_CODE_VALUE Value;
+ ERROR_CODE_ACTION *Action;
+ } ERROR_CODE_ACTION_MAP;
+
+#define STATUS_CODE_TYPE(Type) ((Type)&EFI_STATUS_CODE_TYPE_MASK)
+
+ UINT8 FindByteCode(STATUS_CODE_TO_BYTE_MAP *Map, EFI_STATUS_CODE_VALUE Value);
+ VOID Delay(VOID **PeiServices, UINT32 Microseconds);
+ EFI_STATUS ReportStatusCode (
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ );
+ VOID InitStatusCodeParts(IN VOID *ImageHandler, IN VOID *ServicesTable);
+ VOID ResetOrResume(IN VOID *PeiServices, IN EFI_STATUS_CODE_VALUE Value);
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+#include <Protocol/ReportStatusCodeHandler.h>
+typedef struct {
+ EFI_STATUS_CODE_TYPE Type;
+ EFI_STATUS_CODE_VALUE Value;
+ UINT32 Instance;
+ UINT32 Reserved;
+ EFI_GUID CallerId;
+ EFI_STATUS_CODE_DATA Data;
+} RSC_DATA_ENTRY;
+
+typedef struct {
+ EFI_RSC_HANDLER_CALLBACK RscHandlerCallback;
+ EFI_TPL Tpl;
+ EFI_EVENT Event;
+ EFI_PHYSICAL_ADDRESS StatusCodeDataBuffer;
+ UINTN BufferSize;
+ EFI_PHYSICAL_ADDRESS EndPointer;
+} RSC_HANDLER_CALLBACK_ENTRY;
+
+typedef struct {
+ UINT32 RegisteredEntries;
+ UINT32 TotalEntries;
+} ROUTER_STRUCT_HEADER;
+#endif
+ /****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/StatusCode/StatusCodeMap.c b/Core/EM/StatusCode/StatusCodeMap.c
new file mode 100644
index 0000000..b8f416c
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCodeMap.c
@@ -0,0 +1,278 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeMap.c 2 7/09/09 5:18p Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 7/09/09 5:18p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeMap.c $
+//
+// 2 7/09/09 5:18p Oleksiyy
+// Files clean-up some headers added
+//
+// 1 3/05/09 1:40p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeMap.c
+//
+// Description:
+// This file contains several tables that map generic namespace
+// of status code values into domain specific namespaces.
+// In the current implementation the following tables are included:
+// ProgressCheckpointMap - establishes mapping between progress code values and checkpoint values.
+// ErrorCheckpointMap - establishes mapping between error code values and checkpoint values.
+// ProgressBeepMap - establishes mapping between progress code values and number of beeps.
+// ErrorBeepMap - establishes mapping between error code values and number of beeps.
+// The mapping tables can be overriden using SDL tokens.
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiStatusCodes.h>
+#include "StatusCodeInt.h"
+
+//**********************************************************************
+// Checkpoints map
+//**********************************************************************
+//1 - 0xF : SEC execution
+//0x10 - 0x2F: PEI CAR execution
+//0x30 - 0x4F: PEI execution after memory detection
+//0x50 - 0x5F: PEI errors
+//0x60 - 0xCF: DXE execution
+//0xD0 - 0xDF: DXE errors
+//0xE0 - 0xE8: S3 Resume
+//0xE9 - 0xEF: S3 Resume errors
+//0xF0 - 0xF8: Recovery
+//0xF9 - 0xFF: Recovery errors
+
+STATUS_CODE_TO_BYTE_MAP ProgressCheckpointMap[] =
+{
+#ifdef PEI_STATUS_CODE
+//Regular boot
+ { PEI_CORE_STARTED, 0x10 },
+ { PEI_CAR_CPU_INIT, 0x11 },
+ // reserved for CPU 0x12 - 0x14
+ { PEI_CAR_NB_INIT, 0x15 },
+ // reserved for NB 0x16 - 0x18
+ { PEI_CAR_SB_INIT, 0x19 },
+ // reserved for SB 0x1A - 0x1C
+ // reserved for OEM use: 0x1D - 0x2A
+ { PEI_MEMORY_SPD_READ, 0x2B },
+ { PEI_MEMORY_PRESENCE_DETECT, 0x2C },
+ { PEI_MEMORY_TIMING, 0x2D},
+ { PEI_MEMORY_CONFIGURING, 0x2E },
+ { PEI_MEMORY_INIT, 0x2F },
+ // reserved for AML use: 0x30
+ { PEI_MEMORY_INSTALLED, 0x31 },
+ { PEI_CPU_INIT, 0x32 },
+ { PEI_CPU_CACHE_INIT, 0x33 },
+ { PEI_CPU_AP_INIT, 0x34 },
+ { PEI_CPU_BSP_SELECT, 0x35 },
+ { PEI_CPU_SMM_INIT, 0x36 },
+ { PEI_MEM_NB_INIT, 0x37 },
+ // reserved for NB 0x38 - 0x3A
+ { PEI_MEM_SB_INIT, 0x3B },
+ // reserved for SB 0x3C - 0x3E
+ // reserved for OEM use: 0x3F - 0x4E
+ { PEI_DXE_IPL_STARTED, 0x4F },
+ { DXE_CORE_STARTED, 0x60 },
+//Recovery
+ { PEI_RECOVERY_AUTO, 0xF0 },
+ { PEI_RECOVERY_USER, 0xF1 },
+ { PEI_RECOVERY_STARTED, 0xF2 },
+ { PEI_RECOVERY_CAPSULE_FOUND, 0xF3 },
+ { PEI_RECOVERY_CAPSULE_LOADED, 0xF4 },
+//S3
+ { PEI_S3_STARTED, 0xE0 },
+ { PEI_S3_BOOT_SCRIPT, 0xE1 },
+ { PEI_S3_VIDEO_REPOST, 0xE2 },
+ { PEI_S3_OS_WAKE, 0xE3 },
+#endif
+#ifdef DXE_STATUS_CODE
+ { DXE_CORE_STARTED, 0x60 },
+ { DXE_NVRAM_INIT, 0x61 },
+ { DXE_SBRUN_INIT, 0x62 },
+ { DXE_CPU_INIT, 0x63 },
+ //reserved for CPU 0x64 - 0x67
+ { DXE_NB_HB_INIT, 0x68 },
+ { DXE_NB_INIT, 0x69 },
+ { DXE_NB_SMM_INIT, 0x6A },
+ //reserved for NB 0x6B - 0x6F
+ { DXE_SB_INIT, 0x70 },
+ { DXE_SB_SMM_INIT, 0x71 },
+ { DXE_SB_DEVICES_INIT, 0x72 },
+ //reserved for SB 0x73 - 0x77
+ { DXE_ACPI_INIT, 0x78 },
+ { DXE_CSM_INIT, 0x79 },
+ //reserved for AMI use: 0x7A - 0x7F
+ //reserved for OEM use: 0x80 - 0x8F
+ { DXE_BDS_STARTED, 0x90 },
+ { DXE_BDS_CONNECT_DRIVERS, 0x91 },
+ { DXE_PCI_BUS_BEGIN, 0x92 },
+ { DXE_PCI_BUS_HPC_INIT, 0x93 },
+ { DXE_PCI_BUS_ENUM, 0x94 },
+ { DXE_PCI_BUS_REQUEST_RESOURCES, 0x95 },
+ { DXE_PCI_BUS_ASSIGN_RESOURCES, 0x96 },
+ { DXE_CON_OUT_CONNECT, 0x97 },
+ { DXE_CON_IN_CONNECT, 0x98 },
+ { DXE_SIO_INIT, 0x99 },
+ { DXE_USB_BEGIN, 0x9A },
+ { DXE_USB_RESET, 0x9B },
+ { DXE_USB_DETECT, 0x9C },
+ { DXE_USB_ENABLE, 0x9D },
+ //reserved for AMI use: 0x9E - 0x9F
+ { DXE_IDE_BEGIN, 0xA0 },
+ { DXE_IDE_RESET, 0xA1 },
+ { DXE_IDE_DETECT, 0xA2 },
+ { DXE_IDE_ENABLE, 0xA3 },
+ { DXE_SCSI_BEGIN, 0xA4 },
+ { DXE_SCSI_RESET, 0xA5 },
+ { DXE_SCSI_DETECT, 0xA6 },
+ { DXE_SCSI_ENABLE, 0xA7 },
+ { DXE_SETUP_VERIFYING_PASSWORD, 0xA8 },
+ { DXE_SETUP_START, 0xA9 },
+ //reserved for AML use: 0xAA
+ { DXE_SETUP_INPUT_WAIT, 0xAB },
+ //reserved for AML use: 0xAC
+ { DXE_READY_TO_BOOT, 0xAD },
+ { DXE_LEGACY_BOOT, 0xAE },
+ { DXE_EXIT_BOOT_SERVICES, 0xAF },
+ { RT_SET_VIRTUAL_ADDRESS_MAP_BEGIN, 0xB0 },
+ { RT_SET_VIRTUAL_ADDRESS_MAP_END, 0xB1 },
+ { DXE_LEGACY_OPROM_INIT, 0xB2 },
+ { DXE_RESET_SYSTEM, 0xB3 },
+ { DXE_USB_HOTPLUG, 0xB4 },
+ { DXE_PCI_BUS_HOTPLUG, 0xB5 },
+ { DXE_NVRAM_CLEANUP, 0xB6 },
+ { DXE_CONFIGURATION_RESET, 0xB7 },
+ //reserved for AMI use: 0xB8 - 0xBF
+ //reserved for OEM use: 0xC0 - 0xCF
+#endif
+ {0,0}
+};
+
+STATUS_CODE_TO_BYTE_MAP ErrorCheckpointMap[] =
+{
+#ifdef PEI_STATUS_CODE
+//Errors
+//Regular boot
+ { PEI_MEMORY_INVALID_TYPE, 0x50 },
+ { PEI_MEMORY_INVALID_SPEED, 0x50 },
+ { PEI_MEMORY_SPD_FAIL, 0x51 },
+ { PEI_MEMORY_INVALID_SIZE, 0x52 },
+ { PEI_MEMORY_MISMATCH, 0x52 },
+ { PEI_MEMORY_NOT_DETECTED, 0x53 },
+ { PEI_MEMORY_NONE_USEFUL, 0x53 },
+ { PEI_MEMORY_ERROR, 0x54 },
+ { PEI_MEMORY_NOT_INSTALLED, 0x55 },
+ { PEI_CPU_INVALID_TYPE, 0x56 },
+ { PEI_CPU_INVALID_SPEED, 0x56 },
+ { PEI_CPU_MISMATCH, 0x57 },
+ { PEI_CPU_SELF_TEST_FAILED, 0x58 },
+ { PEI_CPU_CACHE_ERROR, 0x58 },
+ { PEI_CPU_MICROCODE_UPDATE_FAILED, 0x59 },
+ { PEI_CPU_NO_MICROCODE, 0x59 },
+ { PEI_CPU_INTERNAL_ERROR, 0x5A },
+ { PEI_CPU_ERROR, 0x5A },
+ { PEI_RESET_NOT_AVAILABLE,0x5B },
+ //reserved for AMI use: 0x5C - 0x5F
+//Recovery
+ { PEI_RECOVERY_PPI_NOT_FOUND, 0xF8 },
+ { PEI_RECOVERY_NO_CAPSULE, 0xF9 },
+ { PEI_RECOVERY_INVALID_CAPSULE, 0xFA },
+ //reserved for AMI use: 0xFB - 0xFF
+//S3 Resume
+ { PEI_MEMORY_S3_RESUME_FAILED, 0xE8 },
+ { PEI_S3_RESUME_PPI_NOT_FOUND, 0xE9 },
+ { PEI_S3_BOOT_SCRIPT_ERROR, 0xEA },
+ { PEI_S3_OS_WAKE_ERROR, 0xEB },
+ //reserved for AMI use: 0xEC - 0xEF
+#endif
+#ifdef DXE_STATUS_CODE
+ { DXE_CPU_ERROR, 0xD0 },
+ { DXE_NB_ERROR, 0xD1 },
+ { DXE_SB_ERROR, 0xD2 },
+ { DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 0xD3 },
+ { DXE_PCI_BUS_OUT_OF_RESOURCES, 0xD4 },
+ { DXE_LEGACY_OPROM_NO_SPACE, 0xD5 },
+ { DXE_NO_CON_OUT, 0xD6 },
+ { DXE_NO_CON_IN, 0xD7 },
+ { DXE_INVALID_PASSWORD, 0xD8 },
+ { DXE_BOOT_OPTION_LOAD_ERROR, 0xD9 },
+ { DXE_BOOT_OPTION_FAILED, 0xDA },
+ { DXE_FLASH_UPDATE_FAILED, 0xDB },
+ { DXE_RESET_NOT_AVAILABLE, 0xDC },
+ //reserved for AMI use: 0xDE - 0xDF
+#endif
+ {0,0}
+};
+
+//**********************************************************************
+// Beep codes map
+//**********************************************************************
+STATUS_CODE_TO_BYTE_MAP ProgressBeepMap[] =
+{
+#ifdef PEI_STATUS_CODE
+//Recovery
+ { PEI_RECOVERY_STARTED, 2 },
+#endif
+#ifdef DXE_STATUS_CODE
+#endif
+ {0,0}
+};
+
+STATUS_CODE_TO_BYTE_MAP ErrorBeepMap[] =
+{
+#ifdef PEI_STATUS_CODE
+//Errors
+//Regular boot
+ { PEI_MEMORY_NOT_INSTALLED, 1 },
+ { PEI_MEMORY_INSTALLED_TWICE, 1 },
+ { PEI_DXEIPL_NOT_FOUND, 3 },
+ { PEI_DXE_CORE_NOT_FOUND, 3 },
+ { PEI_RESET_NOT_AVAILABLE, 7 },
+//Recovery
+ { PEI_RECOVERY_FAILED, 4 },
+//S3 Resume
+ { PEI_S3_RESUME_FAILED, 4 },
+#endif
+#ifdef DXE_STATUS_CODE
+ { DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 4 },
+ { DXE_NO_CON_OUT, 5 },
+ { DXE_NO_CON_IN, 5 },
+ { DXE_INVALID_PASSWORD, 1 },
+ { DXE_FLASH_UPDATE_FAILED, 6 },
+ { DXE_RESET_NOT_AVAILABLE, 7 },
+ { DXE_PCI_BUS_OUT_OF_RESOURCES, 8},
+#endif
+ {0,0}
+};
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/StatusCode/StatusCodePei.c b/Core/EM/StatusCode/StatusCodePei.c
new file mode 100644
index 0000000..1e452d1
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCodePei.c
@@ -0,0 +1,492 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodePei.c 3 6/23/11 6:09p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 6/23/11 6:09p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodePei.c $
+//
+// 3 6/23/11 6:09p Oleksiyy
+// [TAG] EIP56644
+// [Category] New Feature
+// [Description] Implemented PPI and Protocols, described in a PI 1.2
+// Report Status Code Router specification.
+// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h,
+// StatusCodeCommon.c and StatusCodeRuntime.c
+//
+// 2 7/09/09 5:18p Oleksiyy
+// Files clean-up some headers added
+//
+// 1 3/05/09 1:40p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodePei.c
+//
+// Description:
+// File contains PEI specific status code routines such as
+// entry point of the StatusCode PEIM (PeiInitStatusCode) and
+// PEI implementation of some of the functions from the status code library.
+// (Status code library is a set of generic routines utilized throughout the component).
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiPeiLib.h>
+#include <PPI/ProgressCode.h>
+#include <PPI/Stall.h>
+#include "StatusCodeInt.h"
+#include <Token.h>
+
+//--------------------To HEADER-----------------------------------------------
+/** @file
+ GUID used to identify HOB for pointers to callback functios registered on
+ PEI report status code router.
+
+Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+
+#include <PPI/ReportStatusCodeHandler.h>
+#define INITIAL_RSC_PEI_ENTRIES 8
+#define STATUS_CODE_CALLBACK_GUID \
+ { \
+ 0xe701458c, 0x4900, 0x4ca5, {0xb7, 0x72, 0x3d, 0x37, 0x94, 0x9f, 0x79, 0x27} \
+ }
+
+EFI_GUID gStatusCodeCallbackGuid = STATUS_CODE_CALLBACK_GUID;
+
+
+BOOLEAN IsItRecursiveCall (
+ IN OUT BOOLEAN *Value,
+ IN BOOLEAN CompareWith,
+ IN BOOLEAN SvitchTo
+ );
+
+
+EFI_GUID gEfiPeiRscHandlerPpiGuid = EFI_PEI_RSC_HANDLER_PPI_GUID;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Delay
+//
+// Description: Worker function to create one memory status code GUID'ed HOB
+//
+// Input: None
+//
+// Output:
+// UINTN* - Pointer to the NumberOfEntries field in Hob
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINTN*
+CreateRscHandlerCallbackPacket (
+ )
+{
+ UINTN *NumberOfEntries;
+ EFI_HOB_GUID_TYPE *Hob;
+ EFI_STATUS Status;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ //
+ // Build GUID'ed HOB with PCD defined size.
+ //
+
+ Status = (*PeiServices)->CreateHob (PeiServices, EFI_HOB_TYPE_GUID_EXTENSION,
+ (UINT16)(sizeof (EFI_PEI_RSC_HANDLER_CALLBACK) * INITIAL_RSC_PEI_ENTRIES
+ + sizeof (UINTN)+ sizeof (EFI_HOB_GUID_TYPE)), &Hob);
+ //ASSERT_PEI_ERROR(PeiServices,Status);
+ if (EFI_ERROR(Status)) return NULL;
+ MemCpy (&Hob->Name, &gStatusCodeCallbackGuid, sizeof (EFI_GUID));
+
+ NumberOfEntries = (UINTN*)(Hob + 1);
+
+ *NumberOfEntries = 0;
+
+ return NumberOfEntries;
+}
+
+
+#define GET_GUID_HOB_DATA(HobStart) \
+ (VOID*)((UINT8*)(HobStart) + sizeof (EFI_HOB_GUID_TYPE))
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetFirstGuidHob
+//
+// Description: Returns the first instance of the matched GUID HOB among the
+// whole HOB list.
+//
+// Input:
+// IN EFI_GUID *Guid - The GUID to match with in the HOB list.
+//
+// Output:
+// VOID* Pointer po first matched Hob (NULL - if not found)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *
+GetFirstGuidHob (
+ IN EFI_GUID *Guid
+ )
+{
+
+ VOID *HobList = NULL;
+ EFI_STATUS Status;
+ EFI_PEI_SERVICES **PeiServices;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ Status = (*PeiServices)->GetHobList (PeiServices, &HobList);
+ if (EFI_ERROR(Status)) return NULL;
+ Status = FindNextHobByGuid (Guid, &HobList);
+ if (EFI_ERROR(Status)) return NULL;
+ else return HobList;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PpiUnregister
+//
+// Description: Remove a previously registered callback function from the notification list.
+//
+// Input:
+// IN EFI_PEI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type
+// EFI_PEI_RSC_HANDLER_CALLBACK that is to be unregistered.
+//
+// Output:
+// EFI_SUCCESS The function was successfully unregistered.
+// EFI_INVALID_PARAMETER The callback function was NULL.
+// EFI_NOT_FOUND The callback function was not found to be unregistered.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PpiUnregister (
+ IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
+ UINTN *NumberOfEntries;
+ UINTN Index;
+ EFI_STATUS Status;
+
+
+ if (Callback == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+ while (Hob.Raw != NULL) {
+ NumberOfEntries = GET_GUID_HOB_DATA (Hob.Raw);
+ CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+ for (Index = 0; Index < *NumberOfEntries; Index++) {
+ if (CallbackEntry[Index] == Callback) {
+ CallbackEntry[Index] = CallbackEntry[*NumberOfEntries - 1];
+ *NumberOfEntries -= 1;
+ return EFI_SUCCESS;
+ }
+ }
+ Status = FindNextHobByGuid (&gStatusCodeCallbackGuid, &Hob.Raw);
+ if (EFI_ERROR(Status)) Hob.Raw = NULL;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PpiRegister
+//
+// Description: Register the callback function for ReportStatusCode() notification.
+//
+// Input:
+// IN EFI_PEI_RSC_HANDLER_CALLBACK Callback - A pointer to a function of type
+// EFI_PEI_RSC_HANDLER_CALLBACK that is to be registered.
+//
+// Output:
+// EFI_SUCCESS The function was successfully registered.
+// EFI_INVALID_PARAMETER The callback function was NULL.
+// EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions can be
+// registered.
+// EFI_ALREADY_STARTED The function was already registered. It can't be registered again.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PpiRegister (
+ IN EFI_PEI_RSC_HANDLER_CALLBACK Callback
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
+ UINTN *NumberOfEntries;
+ UINTN Index;
+ UINTN *FreePacket;
+ EFI_STATUS Status;
+
+ if (Callback == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+ FreePacket = NULL;
+ while (Hob.Raw != NULL) {
+ NumberOfEntries = GET_GUID_HOB_DATA (Hob.Raw);
+ CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+ if (*NumberOfEntries < INITIAL_RSC_PEI_ENTRIES) {
+ FreePacket = NumberOfEntries;
+ }
+ for (Index = 0; Index < *NumberOfEntries; Index++) {
+ if (CallbackEntry[Index] == Callback) {
+ //
+ // If the function was already registered. It can't be registered again.
+ //
+ return EFI_ALREADY_STARTED;
+ }
+ }
+
+ Status = FindNextHobByGuid (&gStatusCodeCallbackGuid, &Hob.Raw);
+ if (EFI_ERROR(Status)) Hob.Raw = NULL;
+ }
+
+ if (FreePacket == NULL) {
+ FreePacket = CreateRscHandlerCallbackPacket();
+ }
+ if (FreePacket == NULL) return EFI_OUT_OF_RESOURCES;
+ CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (FreePacket + 1);
+ CallbackEntry[*FreePacket] = Callback;
+ *FreePacket += 1;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_PEI_RSC_HANDLER_PPI RscHandlerPpi = {
+ PpiRegister,
+ PpiUnregister
+ };
+
+EFI_PEI_PPI_DESCRIPTOR RscHandlerPpiDescriptor[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiRscHandlerPpiGuid,
+ &RscHandlerPpi
+ }
+};
+
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportStatusCodePei
+//
+// Description:
+// Top level status code reporting routine exposed by the status code protocol/PPI.
+// Calls the various types of status code handlers
+// (SimpleStatusReport, StringStatusReport, MiscStatusReport, PerformErrorCodeAction)
+// Generates string from the status code data to pass to StringStatusReport function.
+// Also pass all parameters to Registered Statuse Code Routers.
+//
+// Input:
+// IN VOID *PeiServices - pointer to the PEI Boot Services table
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance -
+// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportStatusCodePei (
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ EFI_PEI_HOB_POINTERS Hob;
+ EFI_PEI_RSC_HANDLER_CALLBACK *CallbackEntry;
+ UINTN *NumberOfEntries;
+ UINTN Index;
+ EFI_STATUS Status;
+
+ //if (IsItRecursiveCall(&PeiRouterRecurciveStatus, FALSE, TRUE) != TRUE)
+ //{ //return EFI_ACCESS_DENIED;
+ Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
+ while (Hob.Raw != NULL)
+ {
+ NumberOfEntries = GET_GUID_HOB_DATA (Hob.Raw);
+ CallbackEntry = (EFI_PEI_RSC_HANDLER_CALLBACK *) (NumberOfEntries + 1);
+ for (Index = 0; Index < *NumberOfEntries; Index++)
+ {
+ CallbackEntry[Index](
+ PeiServices,
+ Type,
+ Value,
+ Instance,
+ CallerId,
+ Data
+ );
+ }
+
+ Status = FindNextHobByGuid (&gStatusCodeCallbackGuid, &Hob.Raw);
+ if (EFI_ERROR(Status)) Hob.Raw = NULL;
+
+ }
+// }
+// IsItRecursiveCall (&PeiRouterRecurciveStatus, TRUE, FALSE);
+#endif
+
+ return ReportStatusCode (PeiServices,Type,Value,Instance,CallerId,Data);
+}
+
+// Status Code PPI
+EFI_PEI_PROGRESS_CODE_PPI StatusCodePpi = {ReportStatusCodePei};
+// Status Code PPI Descriptor
+EFI_PEI_PPI_DESCRIPTOR StatusCodePpiDescriptor[] =
+{
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiStatusCodePpiGuid, &StatusCodePpi
+};
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiInitStatusCode
+//
+// Description: Pei "entry point" for this module, called by the Pei Core.
+// Conotol flow:
+// 1. Creates a RSC Hob and installs RSC PPI.
+// 2. Calls InitStatusCodeParts function.
+// 3. Installs the Status Code PPI.
+// InitStatusCodeParts function calls initialization routines of status code subcomponents
+// registered under StatusCodeInitialize eLink.
+// Status Code PPI is initialized with the address of ReportStatusCode function.
+//
+// Input:
+// *FfsHeader - pointer to the header of the current firmware file system file
+// **PeiServices - pointer to the Pei Services table
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS PeiInitStatusCode(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ InitStatusCodeParts(FfsHeader,PeiServices);
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ CreateRscHandlerCallbackPacket ();
+ // First install Report Status Code Handler PPI
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices, &RscHandlerPpiDescriptor[0]
+ );
+
+#endif
+ // And then install the Status Code PPI
+ Status = (*PeiServices)->InstallPpi(
+ PeiServices, &StatusCodePpiDescriptor[0]
+ );
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: Delay
+//
+// Description: Stalls execution for a passed in number of microseconds
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// UINT32 Microseconds - the number of microseconds to stall execution
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID Delay(EFI_PEI_SERVICES **PeiServices, UINT32 Microseconds)
+{
+ EFI_PEI_STALL_PPI *Stall;
+ EFI_STATUS Status = (*PeiServices)->LocatePpi(PeiServices,&gPeiStallPpiGuid,0,NULL,&Stall);
+
+ if (EFI_ERROR(Status)) return;
+
+ Stall->Stall(PeiServices, Stall, Microseconds);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ResetOrResume
+//
+// Description: Error Code Action.
+// Attempts to perform a system reset. If reset fails, returns.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// EFI_STATUS_CODE_VALUE Value - Value of the error code that triggered the action.
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ResetOrResume(
+ IN EFI_PEI_SERVICES **PeiServices, IN EFI_STATUS_CODE_VALUE Value
+)
+{
+ (*PeiServices)->ResetSystem(PeiServices);
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/StatusCode/StatusCodeRuntime.c b/Core/EM/StatusCode/StatusCodeRuntime.c
new file mode 100644
index 0000000..76d8f23
--- /dev/null
+++ b/Core/EM/StatusCode/StatusCodeRuntime.c
@@ -0,0 +1,768 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/StatusCode/StatusCodeRuntime.c 9 12/13/12 3:59p Oleksiyy $
+//
+// $Revision: 9 $
+//
+// $Date: 12/13/12 3:59p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/StatusCode/StatusCodeRuntime.c $
+//
+// 9 12/13/12 3:59p Oleksiyy
+// [TAG] EIP109426
+// [Category] Improvement
+// [Description] Issues found by CppCheck in StatusCode eModule.
+// [Files] StatuseCodeRuntime.c
+//
+// 8 8/09/12 5:27p Oleksiyy
+// [TAG] EIP97932
+// [Category] Improvement
+// [Description] StatusCode Router RT init fix
+// [Files] StatusCodeRuntime.c
+//
+// 7 6/12/12 3:50p Oleksiyy
+// [TAG] EIP90338
+// [Category] Improvement
+// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to
+// AmiLib.h.
+// [Files] AmiLib.h, StatusCodeDxe.c and StatusCoderuntime.c
+//
+// 6 5/22/12 5:31p Oleksiyy
+// [TAG] EIP90338
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail on item Generic Test\EFI Compliant Test
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c, StatusCodeDxe.c and StatusCoderuntime.c
+//
+// 5 10/20/11 5:22p Oleksiyy
+// [TAG] EIP72806
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Runtime status code hangs
+// [RootCause] Not converting actual status code functions addresses on
+// Virtual Address Change event.
+// [Solution] Status code functions converted.
+// [Files] EfiLib.c, StatusCode.sdl and StatusCodeRuntime.c
+//
+// 4 6/23/11 6:10p Oleksiyy
+// [TAG] EIP56644
+// [Category] New Feature
+// [Description] Implemented PPI and Protocols, described in a PI 1.2
+// Report Status Code Router specification.
+// [Files] StatusCodePei.c, StatusCodeDxe.c, StatusCodeInt.h,
+// StatusCodeCommon.c and StatusCodeRuntime.c
+//
+// 3 11/18/10 4:00p Oleksiyy
+// [TAG] EIP46589
+// [Category] Improvement
+// [Description] All StatusCode listeners not marked as RUNTIME removed
+// from runtime instance.
+// [Files] StatusCodeRuntime.c
+//
+// 2 10/06/10 4:50p Oleksiyy
+// Issue Number: 39752
+//
+// Category: New Feature
+//
+// Description: Runtime Staus Code support is added.
+//
+// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c,
+// CsmLib.c, AmiDxeLib.h and StatusCode eModule.
+//
+// 1 10/04/10 5:49p Oleksiyy
+// Issue Number: 39752 and 29307
+//
+// Category: New Feature
+//
+// Description: Support of Status Code in Runtime is added. Trace API
+// keeps working after handing off control to OS. New instances of
+// StatusCode services in runtime and SMM are now available.
+//
+// Files: Uart1.asl, Tokens.c, Runtime.c, GenericSio.c, EfiLib.c,
+// CsmLib.c, AmiDxeLib.h and StatusCode eModule.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeRuntime.c
+//
+// Description:
+// File contains Runtime specific status code routines such as:
+// - Entry point of the StatusCode Runtime driver
+// Runtime implementation of some of the functions from the status code library.
+// (Status code library is a set of generic routines utilized throughout the component).
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <StatusCodes.h>
+#include <Protocol/StatusCode.h>
+#include <Protocol/SmmStatusCode.h>
+#include <StatusCodeELinks.h>
+#include "StatusCodeInt.h"
+
+#define BDS_ALL_DRIVERS_CONNECTED_PROTOCOL_GUID \
+ {0xdbc9fd21, 0xfad8, 0x45b0, 0x9e, 0x78, 0x27, 0x15, 0x88, 0x67, 0xcc, 0x93}
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+#include <Protocol/SmmBase2.h>
+#include <Protocol/SmmReportStatusCodeHandler.h>
+#include <Protocol/ReportStatusCodeHandler.h>
+//----Router-----------------------------------
+
+#define SMM_CALLBACK_NUMBER 10
+
+typedef struct {
+ UINT32 RegisteredSmmEntries;
+ EFI_SMM_RSC_HANDLER_CALLBACK RscSmmHandlerCallback[SMM_CALLBACK_NUMBER];
+} SMM_ROUTER_STRUCT;
+extern BOOLEAN SmmRouter;
+extern ROUTER_STRUCT_HEADER *RouterCallbackStr;
+SMM_ROUTER_STRUCT SmmRouterCallbackStr;
+//----Router End---------------------------------
+#endif
+extern BOOLEAN StatusRuntime;
+EFI_STATUS_CODE_PROTOCOL *gStatusCode = NULL;
+EFI_REPORT_STATUS_CODE gOldStatusCode = NULL;
+
+
+typedef EFI_STATUS (STRING_FUNCTION)(IN VOID *PeiServices, IN CHAR8 *String);
+typedef EFI_STATUS (MY_STRING_FUNCTION)(IN VOID *PeiServices, IN CHAR8 *String);
+typedef EFI_STATUS (SIMPLE_FUNCTION)(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+);
+typedef EFI_STATUS (MISC_FUNCTION)(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+);
+typedef VOID (CHECKPOINT_FUNCTION)(IN VOID *PeiServices, IN UINT8 Checkpoint);
+
+
+extern EFI_STATUS DummyStringHandler(IN VOID *PeiServices, IN CHAR8 *String);
+extern EFI_STATUS DummySimpleHandler(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value
+);
+extern EFI_STATUS DummyMiscHandler(
+ IN VOID *PeiServices,
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+);
+
+
+extern VOID DummyCheckpointHandler(IN VOID *PeiServices, IN UINT8 Checkpoint);
+
+extern SIMPLE_FUNCTION* SimpleList[];
+extern STRING_FUNCTION* StringList[];
+extern MISC_FUNCTION* MiscList[];
+extern CHECKPOINT_FUNCTION* CheckpointList[];
+
+#define PEI(x) DUMMY_HANDLER
+#define DXE(x) DUMMY_HANDLER
+#define RUNTIME(x) x
+
+#define DUMMY_HANDLER DummyStringHandler
+extern STRING_FUNCTION STRING_LIST EndOfStringList;
+STRING_FUNCTION* MyStringList[] = {STRING_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummySimpleHandler
+extern SIMPLE_FUNCTION SIMPLE_LIST EndOfSimpleList;
+SIMPLE_FUNCTION* MySimpleList[] = {SIMPLE_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummyMiscHandler
+extern MISC_FUNCTION MISC_LIST EndOfMiscList;
+MISC_FUNCTION* MyMiscList[] = {MISC_LIST NULL};
+#undef DUMMY_HANDLER
+
+#define DUMMY_HANDLER DummyCheckpointHandler
+extern CHECKPOINT_FUNCTION CHECKPOINT_LIST EndOfCheckpointList;
+CHECKPOINT_FUNCTION* MyCheckpointList[] = {CHECKPOINT_LIST NULL};
+#undef DUMMY_HANDLER
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitElinks
+//
+// Description: This function inits all Statuse code E-links that dose not have RUNTIME mark
+// as dummy. While leaving only RUNTIME marked E-links .
+//
+// Input: None
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitElinks ()
+{
+ UINTN i;
+
+ for (i=0; SimpleList[i]; i++){
+ if (MySimpleList[i]== SimpleList[i])
+ SimpleList[i]= DummySimpleHandler;
+ else
+ SimpleList[i]= MySimpleList[i];
+ }
+ for (i=0; StringList[i]; i++){
+ if (MyStringList[i]== StringList[i])
+ StringList[i]= DummyStringHandler;
+ else
+ StringList[i]= MyStringList[i];
+ }
+ for (i=0; MiscList[i]; i++){
+ if (MyMiscList[i]== MiscList[i])
+ MiscList[i]= DummyMiscHandler;
+ else
+ MiscList[i]= MyMiscList[i];
+ }
+ for (i=0; CheckpointList[i]; i++){
+ if (MyCheckpointList[i]== CheckpointList[i])
+ CheckpointList[i]= DummyCheckpointHandler;
+ else
+ CheckpointList[i]= MyCheckpointList[i];
+ }
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RuntimeReportStatusCode
+//
+// Description: Runtime Status Code Reporting function.
+// A wrapper around phase independent ReportStatucCode
+// function defined in StatusCodeCommon.c.
+//
+// Input:
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance Instance - Instance
+// *CallerId OPTIONAL - The GUID of the caller function
+// *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RuntimeReportStatusCode (
+ IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+ //If we are not in runtime call old function.
+
+ if (!StatusRuntime) return ( gOldStatusCode( Type, Value, Instance, CallerId, Data));
+
+ return ( ReportStatusCode( NULL, Type, Value, Instance, CallerId, Data));
+}
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+extern BOOLEAN RouterRecurciveStatus;
+BOOLEAN IsItRecursiveCall (
+ IN OUT BOOLEAN *Value,
+ IN BOOLEAN CompareWith,
+ IN BOOLEAN SvitchTo
+ );
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReportStatusCodePei
+//
+// Description:
+// Pass all parameters to Registered Statuse Code Routers.
+//
+// Input:
+// IN EFI_STATUS_CODE_TYPE Type - the type and severity of the error that occurred
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance -
+// IN EFI_GUI *CallerId OPTIONAL - The GUID of the caller function
+// IN EFI_STATUS_CODE_DATA *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReportSmmRouter (
+ IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance,
+ IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+ )
+{
+
+ UINT32 i;
+
+ if ((SmmRouterCallbackStr.RegisteredSmmEntries == 0) || (IsItRecursiveCall (&RouterRecurciveStatus, FALSE, TRUE) == TRUE))
+ return EFI_ACCESS_DENIED;
+ for (i = 0; i != SmmRouterCallbackStr.RegisteredSmmEntries; i++)
+ {
+ if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == NULL)
+ continue;//Unregistered function
+ else
+ SmmRouterCallbackStr.RscSmmHandlerCallback[i] (Type, Value, Instance, CallerId, Data);
+ }
+ // Restore the Recursive status of report
+
+ IsItRecursiveCall (&RouterRecurciveStatus, TRUE, FALSE);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmRegister
+//
+// Description: Remove a previously registered callback function from the notification list.
+//
+// Input:
+// IN EFI_SMM_RSC_HANDLER_CALLBACK Callback - A pointer to a function that
+// that is to be unregistered.
+//
+// Output:
+// EFI_SUCCESS Function was successfully unregistered.
+// EFI_INVALID_PARAMETER The callback function was NULL.
+// EFI_NOT_FOUND The callback function was not found to be unregistered.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+SmmUnregister (
+ IN EFI_SMM_RSC_HANDLER_CALLBACK Callback
+ )
+{
+ UINT32 i;
+
+ if (Callback == NULL) return EFI_INVALID_PARAMETER;
+
+ for (i = 0; i != SmmRouterCallbackStr.RegisteredSmmEntries; i++)
+ {
+ if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == Callback)
+ {
+ SmmRouterCallbackStr.RscSmmHandlerCallback[i] = NULL;
+ return EFI_SUCCESS; //Function Unregistered
+ }
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmRegister
+//
+// Description: When this function is called the function pointer is added to an
+// internal list and any future calls to ReportStatusCode() will be
+// forwarded to the Callback function.
+//
+// Input:
+// IN EFI_SMM_RSC_HANDLER_CALLBACK Callback - A pointer to a function that
+// is called when a call to ReportStatusCode() occurs.
+//
+// Output:
+// EFI_SUCCESS Function was successfully registered.
+// EFI_INVALID_PARAMETER The callback function was NULL.
+// EFI_OUT_OF_RESOURCES The internal buffer ran out of space. No more functions
+// can be registered.
+// EFI_ALREADY_STARTED The function was already registered. It can't be
+// registered again.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+
+SmmRegister (
+ IN EFI_SMM_RSC_HANDLER_CALLBACK Callback
+ )
+{
+ UINT32 i=0, FreeEntry = -1;
+
+ if (Callback == NULL)
+ return EFI_INVALID_PARAMETER;
+ if (SmmRouterCallbackStr.RegisteredSmmEntries != 0)
+ {
+ for (i = 0; i != SmmRouterCallbackStr.RegisteredSmmEntries; i++)
+ {
+ if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == Callback)
+ return EFI_ALREADY_STARTED; //Function already registered
+ if (SmmRouterCallbackStr.RscSmmHandlerCallback[i] == NULL)
+ FreeEntry = i;
+ }
+ if (FreeEntry = -1) //No Unregistered entries
+ {
+ if (SmmRouterCallbackStr.RegisteredSmmEntries == SMM_CALLBACK_NUMBER - 1)
+ return EFI_OUT_OF_RESOURCES; // And all entries are taken already - exit
+ FreeEntry = i;
+ SmmRouterCallbackStr.RegisteredSmmEntries++;
+ }
+ }
+ else
+ {
+ SmmRouterCallbackStr.RegisteredSmmEntries++;
+ FreeEntry = 0;
+ }
+ SmmRouterCallbackStr.RscSmmHandlerCallback[FreeEntry] = Callback;
+
+ return EFI_SUCCESS;
+}
+
+EFI_SMM_RSC_HANDLER_PROTOCOL mSmmRscHandlerProtocol = {
+ SmmRegister,
+ SmmUnregister
+ };
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitRouterAdress
+//
+// Description: Reads variable with the address of RSC Info structure and
+// initialize global variable with it.
+//
+// Input: None
+//
+// Output:
+// VOID
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID InitRouterAdress()
+{
+ EFI_PHYSICAL_ADDRESS RSCInfoAddresss;
+ UINTN SizeOfRCInfo = sizeof(EFI_PHYSICAL_ADDRESS);
+ EFI_STATUS Status;
+
+ if (RouterCallbackStr == NULL)
+ {
+ Status = pRS->GetVariable(
+ L"RSCInfoAddresss",
+ &gAmiGlobalVariableGuid,
+ NULL,
+ &SizeOfRCInfo,
+ &RSCInfoAddresss
+ );
+ if (!EFI_ERROR(Status))
+ RouterCallbackStr = (ROUTER_STRUCT_HEADER*) RSCInfoAddresss;
+ }
+
+}
+//----Router End--------------------------------
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ScRuntimeVirtualAddressChange
+//
+// Description:
+// Updates pointers to RSC structure and to callback functions inside structure.
+//
+// Input:
+// N EFI_EVENT Event - signaled event.
+// IN VOID *Context - Context
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ScRuntimeVirtualAddressChange (IN EFI_EVENT Event, IN VOID *Context)
+{
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ RSC_HANDLER_CALLBACK_ENTRY *CallbackEntry;
+ VOID *Ptr;
+#endif
+ UINTN i;
+
+ for (i=0; SimpleList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(SimpleList[i]));
+ }
+
+ for (i=0; StringList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(StringList[i]));
+ }
+
+ for (i=0; MiscList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(MiscList[i]));
+ }
+
+ for (i=0; CheckpointList[i]; i++){
+ pRS->ConvertPointer(0,(VOID**)&(CheckpointList[i]));
+ }
+ pRS->ConvertPointer(0,(VOID**)&(gStatusCode->ReportStatusCode));
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ if (RouterCallbackStr == NULL)
+ InitRouterAdress();
+ if (RouterCallbackStr == NULL)
+ return;
+ for (i = 0; i != RouterCallbackStr->RegisteredEntries; i++)
+ {
+
+ if (i == 0)
+ Ptr = (UINT8*) RouterCallbackStr + sizeof (ROUTER_STRUCT_HEADER);
+ else
+ Ptr = (UINT8*) Ptr + sizeof (RSC_HANDLER_CALLBACK_ENTRY);
+ CallbackEntry = Ptr;
+
+ if (CallbackEntry->RscHandlerCallback == NULL) continue;//Unregistered function
+ else pRS->ConvertPointer(0,(VOID**)&(CallbackEntry->RscHandlerCallback));
+
+ }
+
+ pRS->ConvertPointer(0,(VOID**)&RouterCallbackStr);
+#endif
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmReportStatusCode
+//
+// Description: SMM Status Code Reporting function.
+// A wrapper around phase independent ReportStatucCode
+// function defined in StatusCodeCommon.c.
+//
+// Input:
+// IN CONST EFI_SMM_STATUS_CODE_PROTOCOL *This -
+// Points to this instance of the EFI_SMM_STATUS_CODE_PROTOCOL.
+// IN EFI_STATUS_CODE_VALUE Value - the Class, subclass and Operation that caused the error
+// IN UINT32 Instance Instance - Instance
+// *CallerId OPTIONAL - The GUID of the caller function
+// *Data OPTIONAL - the extended data field that contains additional info
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SmmReportStatusCode (
+ IN CONST EFI_SMM_STATUS_CODE_PROTOCOL *This, IN EFI_STATUS_CODE_TYPE Type,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN UINT32 Instance, IN EFI_GUID *CallerId OPTIONAL,
+ IN EFI_STATUS_CODE_DATA *Data OPTIONAL
+)
+{
+ EFI_STATUS Status;
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ SmmRouter = TRUE;
+ ReportSmmRouter (Type, Value, Instance, CallerId, Data);
+#endif
+ Status = ReportStatusCode( NULL, Type, Value, Instance, CallerId, Data);
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ SmmRouter = FALSE;
+#endif
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RuntimeStatusCodeExitBS
+//
+// Description: Exit Boot Services event handler.
+// Terminates boot time status code processing
+//
+// Input:
+// IN EFI_EVENT Event - not used
+// IN VOID *Context - not used
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RuntimeStatusCodeExitBS (IN EFI_EVENT Event, IN VOID *Context)
+{
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ InitRouterAdress();
+#endif
+ StatusRuntime = TRUE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RuntimeInitStatusCode
+//
+// Description:
+// Entry point of the StatusCode Runtime Driver.
+// Calls InitStatusCodeParts function, installs the Status Code Protocol,
+// and registers event handlers for the legacy boot and exit boot services events.
+// RuntimeInitStatusCode installs different protocol based on value of the
+// EFI_SPECIFICATION_VERSION SDL token (defined in Core.sdl).
+// If value of the EFI_SPECIFICATION_VERSION constant is less than 0x20000,
+// framework EFI_STATUS_CODE_ARCH_PROTOCOL_GUID protocol is installed;
+// otherwise, PI EFI_STATUS_CODE_RUNTIME_PROTOCOL_GUID protocol is installed.
+// PI Status Code Protocol is initialized with the address of RuntimeReportStatusCode function.
+//
+// Input:
+// *ImageHandle - The firmware allocate handle for the EFI image
+// *SystemTable - pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+// Modified: StatusCode Arch Protocol- now published
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS RuntimeInitStatusCode(
+ IN EFI_HANDLE *ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+
+ InitAmiRuntimeLib(
+ ImageHandle, SystemTable, RuntimeStatusCodeExitBS, ScRuntimeVirtualAddressChange
+ );
+
+ InitElinks();
+ Status = SystemTable->BootServices->LocateProtocol(
+#if EFI_SPECIFICATION_VERSION < 0x20000
+ &gEfiStatusCodeArchProtocolGuid,
+#else
+ &gEfiStatusCodeRuntimeProtocolGuid,
+#endif
+ NULL, &gStatusCode
+ );
+ gOldStatusCode = gStatusCode->ReportStatusCode;
+ gStatusCode->ReportStatusCode = RuntimeReportStatusCode;
+#if EFI_SPECIFICATION_VERSION < 0x20000
+ SystemTable->RuntimeServices->ReportStatusCode = RuntimeReportStatusCode;
+#endif
+
+ //Register Exit Boot Services Callback
+
+ CreateLegacyBootEvent(TPL_CALLBACK, &RuntimeStatusCodeExitBS, NULL, &Event);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SmmInitStatusCode
+//
+// Description:
+// Entry point of the StatusCode SMM Driver.
+//
+// Input:
+// IN EFI_HANDLE *ImageHandle - The firmware allocate handle for the EFI image
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to the EFI System Table
+//
+// Output: EFI_STATUS
+//
+// Modified: StatusCode Arch Protocol- now published
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+EFI_STATUS SmmInitStatusCode(
+ IN EFI_HANDLE *ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE StatusCodeHandle = NULL;
+ static EFI_SMM_STATUS_CODE_PROTOCOL StatusCode = {SmmReportStatusCode};
+
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ EFI_HANDLE SmmRscHandle = NULL;
+ EFI_GUID gEfiSmmRscHandlerProtocolGuid = EFI_SMM_RSC_HANDLER_PROTOCOL_GUID;
+ EFI_SMM_SYSTEM_TABLE2 *pSmst2 = NULL;
+ EFI_SMM_BASE2_PROTOCOL *mInternalSmmBase2 = NULL;
+
+ SmmRouterCallbackStr.RegisteredSmmEntries = 0;
+
+ Status = SystemTable->BootServices->LocateProtocol (
+ &gEfiSmmBase2ProtocolGuid,
+ NULL,
+ (VOID **)&mInternalSmmBase2
+ );
+
+ Status=mInternalSmmBase2->GetSmstLocation (mInternalSmmBase2, &pSmst2);
+ ASSERT (pSmst2 != NULL);
+ Status = pSmst2->SmmInstallProtocolInterface(
+ &SmmRscHandle,
+ &gEfiSmmRscHandlerProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mSmmRscHandlerProtocol
+ );
+ ASSERT_EFI_ERROR (Status);
+#endif
+
+ InitElinks ();
+ Status = SystemTable->BootServices->InstallProtocolInterface(
+ &StatusCodeHandle,
+ &gEfiSmmStatusCodeProtocolGuid,
+ EFI_NATIVE_INTERFACE, &StatusCode
+ );
+#if PI_SPECIFICATION_VERSION >= 0x00010014
+ Status = pSmst2->SmmInstallProtocolInterface(
+ &StatusCodeHandle,
+ &gEfiSmmStatusCodeProtocolGuid,
+ EFI_NATIVE_INTERFACE, &StatusCode
+ );
+
+#endif
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: StatusCodeSmmEntry
+//
+// Description: This function is the entry point for this file. This function
+// installs services in and outside SMM.
+//
+// Input: IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - Pointer to the system table
+//
+// Output: EFI_STATUS - Status based on errors that occurred while waiting for
+// time to expire.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS StatusCodeSmmEntry(
+ IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ InitAmiLib(ImageHandle,SystemTable);
+ return InitSmmHandlerEx(
+ ImageHandle, SystemTable, SmmInitStatusCode, RuntimeInitStatusCode
+ );
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c
new file mode 100644
index 0000000..81a086d
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.c
@@ -0,0 +1,171 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 3 3/14/14 3:19p Fredericko
+//
+// 2 3/11/14 6:02p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:48p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name:
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Efi.h>
+#include "Tpm20CRBLib.h"
+#include "AmiLib.h"
+#include <token.h>
+#include <Tpm20Includes\Tpm20.h>
+
+
+//Forward declare functions
+#if FTpmPlatformProfile == 1
+
+EFI_STATUS
+iTpmGetResponse (
+ IN OUT VOID *ResponseBuffer,
+ IN OUT UINT32 *ResponseSize
+ );
+
+EFI_STATUS
+iTpmSendCommand (
+ IN VOID *CommandBuffer,
+ IN UINT32 CommandSize
+ );
+
+EFI_STATUS
+CheckPspDevicePresent (
+ VOID
+ );
+
+#else
+
+EFI_STATUS
+EFIAPI
+PttHciReceive(
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ );
+
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ );
+
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck();
+
+
+#endif
+
+BOOLEAN isTpm20CrbPresent()
+{
+ #if FTpmPlatformProfile == 1
+ if(!EFI_ERROR(CheckPspDevicePresent()))return TRUE;
+ return FALSE;
+ #else
+ return (PttHciPresenceCheck());
+ #endif
+}
+
+
+EFI_STATUS
+EFIAPI
+CrbSend(
+ IN UINT8 *InputBuffer,
+ IN UINT32 DataLength
+)
+{
+ #if FTpmPlatformProfile == 1
+ return(iTpmSendCommand(InputBuffer, DataLength));
+ #else
+ return (PttHciSend(InputBuffer, DataLength));
+ #endif
+}
+
+
+EFI_STATUS
+EFIAPI
+CrbReceive(
+ OUT UINT8 *OutBuffer,
+ OUT UINT32 *RespSize
+)
+{
+ #if FTpmPlatformProfile == 1
+ return(iTpmGetResponse(OutBuffer, RespSize));
+ #else
+ return (PttHciReceive(OutBuffer, RespSize));
+ #endif
+}
+
+EFI_STATUS
+EFIAPI
+CrbSubmitCmd(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *OutputBuffer,
+ OUT UINT32 *OutputBufferSize
+ )
+{
+ EFI_STATUS Status;
+
+ if(InputBuffer == NULL || OutputBuffer == NULL || InputBufferSize == 0){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = CrbSend(InputBuffer, InputBufferSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ///
+ /// Receive the response data from TPM
+ ///
+ Status = CrbReceive(OutputBuffer, OutputBufferSize);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return Status;
+}
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif
new file mode 100644
index 0000000..5476df6
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "Tpm20CRBLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\CRB_lib"
+ RefName = "Tpm20CRBLib"
+[files]
+"Tpm20CRBLib.mak"
+"Tpm20CRBLib.c"
+"Tpm20CRBLib.h"
+"Tpm20CRBLib.sdl"
+[parts]
+"Tpm2PttLibrary"
+<endComponent>
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h
new file mode 100644
index 0000000..1182ab2
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.h
@@ -0,0 +1,140 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.h 2 6/14/14 12:24a Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/14/14 12:24a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.h $
+//
+// 2 6/14/14 12:24a Fredericko
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 9/16/13 1:51p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name:
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <Efi.h>
+#include <token.h>
+
+
+//Defines ACPI Interface for Control Resource Buffer Access
+#define TPM20H2NS(x) ((((x) << 8) | ((x) >> 8)) & 0xffff)
+#define TPM20H2NL(x) (TPM20H2NS ((x) >> 16) | (TPM20H2NS ((x) & 0xffff) << 16))
+
+#define CONTROL_AREA_RSVD 0x00
+#define CONTROL_AREA_ERROR 0x04
+#define CONTROL_AREA_CANCEL 0x08
+#define CONTROL_AREA_START 0x0C
+#define CONTROL_AREA_INT 0x10
+#define CONTROL_AREA_CMD_SZ 0x18
+#define CONTROL_AREA_CMD_BASE 0x1C
+#define CONTROL_AREA_RSP_SZ 0x24
+#define CONTROL_AREA_RSP_BASE 0x28
+
+//Timeouts
+#define TIMEOUT_A 500 ///< 500 microseconds
+#define TIMEOUT_B 500 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms)
+#define TIMEOUT_C 1000 * 1000 ///< 1s
+#define TIMEOUT_D 500 * 1000 ///< 500 ms
+#define POLLING_PERIOD 140 ///< Poll register every 140 microsecondss
+
+#define CRB_DEVICE_CMD 0x40
+#define CRB_DEVICE_STS 0x44
+
+#define TPM20_CRB_IDLE 0x02
+
+#define TPM20_MAX_COMMAND_SIZE 0x0F80
+#define StartStatusFieldSet 0x00000001
+
+#define TPM20_CRB_CMD_BASE 0x80
+#define TPM20_CRB_RSP_BASE 0x80
+
+#define TPM20_CRBSTATUS_START 0x00000001
+#define TPM20_CRB_ALL_CLEAR 0xFFFFFFFF
+
+#define RESPONSE_HEADER_SIZE 0x0a
+
+
+#pragma pack(1)
+
+typedef struct _STATUS_FIELD_
+{
+ UINT32 Rsvd;
+ UINT32 Error;
+ UINT32 Cancel;
+ UINT32 Start;
+}STATUS_FIELD;
+
+typedef struct _CONTROL_AREA_LAYOUT_
+{
+ STATUS_FIELD StatusFieled;
+ UINT64 IntCntrl;
+ UINT32 Cmd_Sz;
+ UINT64 Cmd_Addrs;
+ UINT32 Rsp_Sz;
+ UINT64 Rsp_Addrs;
+}CONTROL_AREA_LAYOUT;
+
+typedef struct _GENERIC_RESP_HDR_
+{
+ UINT16 Tag;
+ UINT32 RespSize;
+ UINT32 RespCode;
+}GENERIC_RESP_HDR;
+
+#pragma pack()
+
+
+EFI_STATUS
+EFIAPI
+CrbSubmitCmd(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *OutputBuffer,
+ OUT UINT32 *OutputBufferSize);
+
+BOOLEAN isTpm20CrbPresent();
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak
new file mode 100644
index 0000000..3fa1f66
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.mak
@@ -0,0 +1,87 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.mak 1 4/21/14 2:15p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:15p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/Tpm20CRBLib/Tpm20CRBLib.mak $
+#
+# 1 4/21/14 2:15p Fredericko
+#
+# 3 3/14/14 3:20p Fredericko
+#
+# 2 3/11/14 6:01p Fredericko
+# [TAG] EIP151925
+# [Category] New Feature
+# [Description] Changes for TcgGeneric Regression Testing
+#
+# 1 10/08/13 11:59a Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 1:48p Fredericko
+#
+# 1 7/10/13 5:50p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Tpm20CrbLib.mak
+#
+# Description: Make file for the Tpm20CrbLib component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+Tpm20Crb_lib : $(BUILD_DIR)\Tpm20CRBLib.mak make_crb_lib make_crb_Peilib
+$(BUILD_DIR)\Tpm20CRBLib.lib: Tpm20Crb_lib
+$(BUILD_DIR)\IA32\Tpm20CRBLib.lib: Tpm20Crb_lib
+
+$(BUILD_DIR)\Tpm20CRBLib.mak : $(TPM20_CRBLIB)\Tpm20CrbLib.cif $(TPM20_CRBLIB)\Tpm20CrbLib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(TPM20_CRBLIB)\Tpm20CrbLib.cif $(CIF2MAK_DEFAULTS)
+
+LIB_CFLAGS=$(CFLAGS)\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\Common\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\
+
+TCG_LIB_LITE_OBJS = \
+$(BUILD_DIR)\$(TPM20_CRBLIB)\Tpm20CrbLib.obj
+
+
+make_crb_lib: $(SHALIB) $(FWTPM20LIBx64)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Tpm20CrbLib.mak all\
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=LIBRARY
+
+make_crb_Peilib: $(SHALIBPEI) $(FWTPM20LIBx32)
+!IF "$(PROCESSOR)"=="x64"
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\Tpm20CrbLib.mak all\
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TisLib.mak all\
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+!ENDIF \ No newline at end of file
diff --git a/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl
new file mode 100644
index 0000000..27c38ed
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm20CRBLib.sdl
@@ -0,0 +1,61 @@
+TOKEN
+ Name = "TPM20CRB_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TCG support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "TPM20_CRBLIB"
+ Help = "Tcg Directory"
+End
+
+MODULE
+ Help = "Includes TCG.mak to Project"
+ File = "Tpm20CRBLib.mak"
+End
+
+TOKEN
+ Name = "FTpmPlatformProfile"
+ Value = "0"
+ Help = "Set to 0 for Intel PTT and 1 for AMD PSP device"
+ TokenType = BOOLEAN
+ TargetMAK = Yes
+ TargetH = Yes
+END
+
+TOKEN
+ Name = "TPM20_CRBBASE"
+ Value = "0x0FED70000"
+ Help = "Start of Mem I/O region dedicated for TPM access"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FWTPM20LIBx32"
+ Value = " $(BUILD_DIR)\IA32\Tpm2PttLibrary.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "x64_BUILD" "=" "1"
+End
+
+TOKEN
+ Name = "FWTPM20LIBx32"
+ Value = " $(BUILD_DIR)\Tpm2PttLibrary.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "x64_BUILD" "=" "0"
+End
+
+TOKEN
+ Name = "FWTPM20LIBx64"
+ Value = "$(BUILD_DIR)\Tpm2PttLibrary.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c
new file mode 100644
index 0000000..edf31ac
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.c
@@ -0,0 +1,707 @@
+/** @file
+ Implements Platform Trust Technology (FTPM) HCI Device Library.
+
+@copyright
+ Copyright (c) 2012 - 2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+
+**/
+#include <efi.h>
+#include <AmiLib.h>
+#include "Tpm2PttHciRegs.h"
+#include "Tpm2PttHciDeviceLib.h"
+#include <Tpm20Includes\Tpm20.h>
+//#include <EfiCommonLib.h>
+
+
+#ifndef ASSERT
+#define ASSERT(Condition) if(!(Condition)) { \
+ EFI_DEADLOOP() \
+ }
+#endif
+
+#define MmioAddress(BaseAddr, Register) \
+ ( (UINTN)BaseAddr + (UINTN)(Register) )
+
+#define Mmio32Ptr(BaseAddr, Register) \
+ ( (volatile UINT32 *)MmioAddress(BaseAddr, Register) )
+
+#define Mmio32(BaseAddr, Register) \
+ *Mmio32Ptr(BaseAddr, Register)
+
+#define MmioRead32(Addr) \
+ Mmio32(Addr, 0)
+
+#define MmioWrite32(Addr, Value) \
+ (Mmio32(Addr, 0) = (UINT32)Value)
+
+#define TPM_H2NS( x ) \
+ (((UINT16)(x) << 8) | ((UINT16)(x) >> 8))
+#define TPM_H2NL( x ) \
+ (UINT32)((((UINT32)(x)) >> 24) \
+ | (((x) >> 8) & 0xff00) \
+ | ((x) << 24) \
+ | (((x) & 0xff00) << 8))
+
+#define TPM_N2HS( x ) TPM_H2NS( x )
+#define TPM_N2HL( x ) TPM_H2NL( x )
+
+#pragma pack (push, 1)
+typedef struct {
+ TPM_ST tag;
+ UINT32 paramSize;
+ TPM_RC responseCode;
+} TPM2_RESPONSE_HEADER;
+#pragma pack (pop)
+
+#define EFI_MAX_ADDRESS 0xFFFFFFFFFFFFFFFF
+
+
+#ifdef INT_EFI_DEBUG
+/**
+ Prints command or response buffer for debugging purposes.
+
+ @param[in] Buffer Buffer to print.
+ @param[in] BufferSize Buffer data length.
+**/
+VOID
+EFIAPI
+PttHciPrintBuffer(IN UINT8 *Buffer, IN UINT32 BufferSize)
+{
+ UINT32 Index;
+
+ DEBUG ((EFI_D_INFO, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n", Buffer, BufferSize));
+ for(Index = 0; Index < BufferSize; Index++){
+ DEBUG ((EFI_D_INFO, "%02x ", *(Buffer + Index)));
+ if((Index+1) % 16 == 0) DEBUG ((EFI_D_INFO, "\n"));
+ }
+ DEBUG ((EFI_D_INFO, "\n"));
+}
+#endif // EFI_DEBUG
+
+
+VOID MicroSecDelay (
+ UINTN Delay
+)
+{
+ UINTN Counter, i;
+ UINT32 Data32, PrevData;
+ UINTN Remainder;
+
+ Counter = (UINTN)Div64 ((UINT64)(Delay * 10), 3, &Remainder);
+ if (Remainder != 0) {
+ Counter++;
+ }
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i = 0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+ return;
+}
+
+
+/**
+ Copy data from the MMIO region to system memory by using 32-bit access.
+
+ Copy data from the MMIO region specified by starting address StartAddress
+ to system memory specified by Buffer by using 32-bit access. The total
+ number of byte to be copied is specified by Length. Buffer is returned.
+
+ If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
+
+ If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().
+
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param StartAddress The starting address for the MMIO region to be copied from.
+ @param Length The size, in bytes, of Buffer.
+ @param Buffer The pointer to a system memory buffer receiving the data read.
+
+ @return Buffer
+**/
+UINT32 *
+EFIAPI
+MmioReadBuffer32 (
+ IN UINTN StartAddress,
+ IN UINTN Length,
+ OUT UINT32 *Buffer
+ )
+{
+ UINT32 *ReturnBuffer;
+
+ ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
+
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - StartAddress));
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - (UINTN) Buffer));
+
+ ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
+ ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
+
+ ReturnBuffer = Buffer;
+
+ while (Length != 0) {
+ *(Buffer++) = MmioRead32 (StartAddress);
+ StartAddress += sizeof (UINT32);
+ Length -= sizeof (UINT32);
+ }
+
+ return ReturnBuffer;
+}
+
+/**
+ Copy data from system memory to the MMIO region by using 32-bit access.
+
+ Copy data from system memory specified by Buffer to the MMIO region specified
+ by starting address StartAddress by using 32-bit access. The total number
+ of byte to be copied is specified by Length. Buffer is returned.
+
+ If StartAddress is not aligned on a 32-bit boundary, then ASSERT().
+
+ If Length is greater than (MAX_ADDRESS - StartAddress + 1), then ASSERT().
+ If Length is greater than (MAX_ADDRESS -Buffer + 1), then ASSERT().
+
+ If Length is not aligned on a 32-bit boundary, then ASSERT().
+
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+
+ @param StartAddress The starting address for the MMIO region to be copied to.
+ @param Length The size, in bytes, of Buffer.
+ @param Buffer The pointer to a system memory buffer containing the data to write.
+
+ @return Buffer
+**/
+UINT32 *
+EFIAPI
+MmioWriteBuffer32 (
+ IN UINTN StartAddress,
+ IN UINTN Length,
+ IN CONST UINT32 *Buffer
+ )
+{
+ UINT32 *ReturnBuffer;
+
+ ASSERT ((StartAddress & (sizeof (UINT32) - 1)) == 0);
+
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - StartAddress));
+ ASSERT ((Length - 1) <= (EFI_MAX_ADDRESS - (UINTN) Buffer));
+
+ ASSERT ((Length & (sizeof (UINT32) - 1)) == 0);
+ ASSERT (((UINTN) Buffer & (sizeof (UINT32) - 1)) == 0);
+
+ ReturnBuffer = (UINT32 *) Buffer;
+
+ while (Length != 0) {
+ MmioWrite32 (StartAddress, *(Buffer++));
+
+ StartAddress += sizeof (UINT32);
+ Length -= sizeof (UINT32);
+ }
+
+ return ReturnBuffer;
+}
+
+/**
+ Checks whether FTPM is enabled (FTPM_STS::FTPM_EN).
+
+ @retval TRUE FTPM is enabled.
+ @retval FALSE FTPM is disabled. All LT writes will be dropped.
+ All LT reads will be returned with read data value of all 0’s.
+ The bit can only be written once per ME power cycle.
+
+**/
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciPresenceCheck start\n"));
+
+ DEBUG ((EFI_D_INFO, "Check FTPM_STS - ENABLED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS)));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS),
+ B_PTT_HCI_STS_ENABLED,
+ V_PTT_HCI_IGNORE_BITS,
+ PTT_HCI_TIMEOUT_A
+ );
+ if(Status == EFI_SUCCESS){
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Checks whether PTT is Ready
+
+ @retval TRUE PTT is ready.
+ @retval FALSE PTT is not ready
+
+**/
+BOOLEAN
+EFIAPI
+PttHciReadyCheck (
+ VOID
+ )
+{
+ UINT32 RegRead;
+
+ RegRead = MmioRead32 ((UINTN) ( R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS ));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Check PTT_STS - READY bit (@ 0x%08x)\n", RegRead));
+#endif
+
+ if(( B_PTT_HCI_STS_READY & RegRead) != 0){
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC).
+ If command was executed, it should not be redundantly issued again.
+
+ @retval TRUE Startup command executed already.
+ @retval FALSE Startup command not executed yet.
+
+**/
+BOOLEAN
+EFIAPI
+PttHciStartupExecuted (
+ VOID
+ )
+{
+ EFI_STATUS Status;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciStartupExecuted start\n"));
+ DEBUG ((EFI_D_INFO, "Check FTPM_STS - STARTUP_EXECECUTED bit (@ 0x%08x)\n", (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS)));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_STS),
+ B_PTT_HCI_STS_STARTUP_EXEC,
+ V_PTT_HCI_IGNORE_BITS,
+ PTT_HCI_TIMEOUT_A
+ );
+ if(Status == EFI_SUCCESS){
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is
+ available for processing.
+ Any host write to this register shall result in an interrupt to the ME firmware.
+
+ @retval EFI_SUCCESS Register successfully written.
+ @retval TBD
+
+**/
+EFI_STATUS
+EFIAPI
+PttHciRequestCommandExec (
+ VOID
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciRequestCommandExec start\n"));
+
+ DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CA_START register (@ 0x%08x)\n",
+ V_PTT_HCI_COMMAND_AVAILABLE_START,
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START)));
+#endif
+ MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START, V_PTT_HCI_COMMAND_AVAILABLE_START);
+
+ ///
+ /// Write 0x1 to HCI CMD register to indicate that a command is available for processing
+ ///
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Command ready for processing - write 0x%08x to FTPM_CMD register (@ 0x%08x)\n",
+ V_PTT_HCI_COMMAND_AVAILABLE_CMD,
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD)));
+#endif
+ MmioWrite32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CMD, V_PTT_HCI_COMMAND_AVAILABLE_CMD);
+
+ return Status;
+}
+
+/**
+ Checks whether the value of a FTPM register satisfies the input BIT setting.
+
+ @param[in] Register Address port of register to be checked.
+ @param[in] BitSet Check these data bits are set.
+ @param[in] BitClear Check these data bits are clear.
+ @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
+
+ @retval EFI_SUCCESS The register satisfies the check bit.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciWaitRegisterBits(
+ IN EFI_PHYSICAL_ADDRESS RegAddress,
+ IN UINT32 BitSet,
+ IN UINT32 BitClear,
+ IN UINT32 TimeOut
+ )
+{
+ UINT32 RegRead;
+ UINT32 WaitTime;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciWaitRegisterBits start\n"));
+#endif
+
+ for (WaitTime = 0; WaitTime < TimeOut; WaitTime += PTT_HCI_POLLING_PERIOD){
+ RegRead = MmioRead32 ((UINTN)RegAddress);
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "RegRead: 0x%08x, BitSetMask: 0x%08x, BitClearMask: 0x%08x, WaitTime: %d (microsec)\n", RegRead, BitSet, BitClear, WaitTime));
+#endif
+
+ if (RegRead == 0xFFFFFFFF)
+ continue;
+
+ if ((RegRead & BitSet) == BitSet && (RegRead & BitClear) == 0) {
+ return EFI_SUCCESS;
+ }
+// MicroSecondDelay (PTT_HCI_POLLING_PERIOD); Override
+ MicroSecDelay(PTT_HCI_POLLING_PERIOD);
+ }
+ return EFI_TIMEOUT;
+}
+
+/**
+ Sends command to FTPM for execution.
+
+ @param[in] FtpmBuffer Buffer for TPM command data.
+ @param[in] DataLength TPM command data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ )
+{
+ EFI_STATUS Status;
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciSend start\n"));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START),
+ V_PTT_HCI_IGNORE_BITS,
+ V_PTT_HCI_START_CLEAR,
+ PTT_HCI_TIMEOUT_A
+ );
+
+ if(EFI_ERROR (Status)){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 command cannot be sent! EFI_ERROR = %r\n", Status));
+#endif
+ return EFI_NOT_READY;
+ }
+ ///
+ /// Align command size to dword before writing to FTPM_CRB
+ ///
+ if(DataLength % 4 != 0){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Alignment: DataLength change from %d ", DataLength));
+#endif
+ DataLength += (4 - (DataLength % 4));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "to %d\n", DataLength));
+#endif
+ }
+
+ MmioWriteBuffer32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB), (UINTN)DataLength, (UINT32*)FtpmBuffer);
+
+ ///
+ /// FTPM_CA_CMD - the physical address to which the TPM 2.0 driver will write the command to execute
+ ///
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB);
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), S_PTT_HCI_CRB_LENGTH);
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "FTPM_CA_CMD (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD),
+ R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB));
+ DEBUG ((EFI_D_INFO, "FTPM_CA_CMD_SZ (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_CMD_SZ), DataLength));
+#endif
+
+ ///
+ /// Set FTPM_CMD and FTPM_CA_START registers to indicate TPM command ready for execution
+ ///
+ Status = PttHciRequestCommandExec();
+#ifdef INT_EFI_DEBUG
+ if(Status == EFI_SUCCESS){
+ DEBUG ((EFI_D_INFO, "FTPM_CMD register written - TPM2 command available for processing\n"));
+ }
+#endif
+
+ return Status;
+}
+
+/**
+ Receives response data of last command from FTPM.
+
+ @param[out] FtpmBuffer Buffer for response data.
+ @param[out] RespSize Response data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_DEVICE_ERROR Unexpected device status.
+ @retval EFI_BUFFER_TOO_SMALL Response data is too long.
+**/
+EFI_STATUS
+EFIAPI
+PttHciReceive(
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ )
+{
+ EFI_STATUS Status;
+ UINT16 Data16;
+ UINT32 Data32;
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciReceive start\n"));
+#endif
+
+ ///
+ /// Wait for the command completion - poll FTPM_CA_START clear
+ ///
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Check Start status (FTPM_CA_START)\n"));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_START),
+ V_PTT_HCI_IGNORE_BITS,
+ V_PTT_HCI_START_CLEAR,
+ PTT_HCI_TIMEOUT_D
+ );
+ if(EFI_ERROR (Status)){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTPM_CA_START register not clear - TPM2 response cannot be read! EFI_ERROR = %r\n", Status));
+#endif
+ goto Exit;
+ }
+
+ ///
+ /// Check for error condition - FTPM_CA_ERROR
+ ///
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Check Error status (FTPM_CA_ERROR)\n"));
+#endif
+ Status = PttHciWaitRegisterBits(
+ (EFI_PHYSICAL_ADDRESS)(UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_ERROR),
+ V_PTT_HCI_IGNORE_BITS,
+ V_PTT_HCI_ALL_BITS_CLEAR,
+ PTT_HCI_TIMEOUT_A
+ );
+ if(EFI_ERROR (Status)){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTPM_CA_ERROR register set - TPM2 response cannot be provided! EFI_ERROR = %r\n", Status));
+#endif
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "FTPM_CA_START register clear - TPM2 command processing completed - ready to read\n"));
+#endif
+
+ ///
+ /// Read the response data header
+ ///
+ MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, PTT_HCI_RESPONSE_HEADER_SIZE, (UINT32*)FtpmBuffer);
+
+ ///
+ /// Check the reponse data header (tag, parasize and returncode)
+ ///
+ MemCpy (&Data16, FtpmBuffer, sizeof (UINT16));
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.tag = 0x%04x\n", TPM_H2NS(Data16)));
+#endif
+
+ ///
+ /// TPM Rev 2.0 Part 2 - 6.9 TPM_ST (Structure Tags)
+ /// TPM_ST_RSP_COMMAND - Used in a response that has an error in the tag.
+ ///
+ if (TPM_H2NS(Data16) == TPM_ST_RSP_COMMAND) {
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "TPM2_RESPONSE_HEADER.tag = TPM_ST_RSP_COMMAND - Error in response!\n"));
+#endif
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+
+ MemCpy(&Data32, (FtpmBuffer + 2), sizeof(UINT32));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "TPM2_RESPONSE_HEADER.paramSize = 0x%08x\n", TPM_H2NL(Data32)));
+#endif
+
+ *RespSize = TPM_H2NL(Data32);
+
+ if(*RespSize == sizeof(TPM2_RESPONSE_HEADER)) {
+ Status = EFI_SUCCESS;
+ goto Exit;
+ }
+ if(*RespSize < sizeof(TPM2_RESPONSE_HEADER)) {
+ Status = EFI_DEVICE_ERROR;
+ goto Exit;
+ }
+ if(*RespSize > S_PTT_HCI_CRB_LENGTH) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ goto Exit;
+ }
+
+ ///
+ /// Align command size to dword before writing to FTPM_CRB
+ ///
+ if(*RespSize % 4 != 0){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "Alignment: RespSize change from %d ", *RespSize));
+#endif
+ *RespSize += (4 - (*RespSize % 4));
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "to %d\n", *RespSize));
+#endif
+ }
+
+ ///
+ /// Reading the entire response data
+ ///
+ MmioReadBuffer32((UINTN)R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB, *RespSize, (UINT32*)FtpmBuffer);
+
+ Exit:
+ if(!EFI_ERROR(Status)){
+ ///
+ /// FTPM_CA_CMD - the physical address from which the TPM 2.0 driver will read command responses
+ ///
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP), R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB);
+ MmioWrite32((UINTN)(R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ),S_PTT_HCI_CRB_LENGTH);
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "FTPM_CA_RSP (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP),
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CRB)));
+ DEBUG ((EFI_D_INFO, "FTPM_CA_RSP_SZ (@ 0x%08x) written, value = 0x%08x\n",
+ (R_PTT_HCI_BASE_ADDRESS + R_PTT_HCI_CA_RSP_SZ), *RespSize));
+#endif
+ }
+
+ return Status;
+}
+
+/**
+ Sends formatted command to FTPM for execution and returns formatted response data.
+
+ @param[in] InputBuffer Buffer for the input data.
+ @param[in] InputBufferSize Size of the input buffer.
+ @param[out] ReturnBuffer Buffer for the output data.
+ @param[out] ReturnBufferSize Size of the output buffer.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSubmitCommand(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *ReturnBuffer,
+ OUT UINT32 *ReturnBufferSize
+ )
+{
+ EFI_STATUS Status;
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: PttHciSubmitCommand start\n"));
+#endif
+
+ if(!PttHciReadyCheck()){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "PTT device not ready. \n"));
+#endif
+ return EFI_NOT_READY;
+ }
+
+ if(InputBuffer == NULL || ReturnBuffer == NULL || InputBufferSize == 0){
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "Buffer == NULL or InputBufferSize == 0\n"));
+#endif
+ return EFI_INVALID_PARAMETER;
+ }
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Command Buffer dump\n"));
+#endif
+
+ ///
+ /// Send the command to TPM
+ ///
+ Status = PttHciSend(InputBuffer, InputBufferSize);
+ if (EFI_ERROR (Status)) {
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTpmHciSend EFI_ERROR = %r\n", Status));
+#endif
+ return Status;
+ }
+
+ ///
+ /// Receive the response data from TPM
+ ///
+ Status = PttHciReceive(ReturnBuffer, ReturnBufferSize);
+ if (EFI_ERROR (Status)) {
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_ERROR, "FTpmHciReceive EFI_ERROR = %r\n", Status));
+#endif
+ return Status;
+ }
+
+#ifdef INT_EFI_DEBUG
+ DEBUG ((EFI_D_INFO, "PTT: Response Buffer dump\n"));
+#endif
+
+ return Status;
+}
+
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h
new file mode 100644
index 0000000..bcb204f
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttHciDeviceLib.h
@@ -0,0 +1,170 @@
+/** @file
+ Platform Trust Technology (FTPM) HCI Device Library
+
+@copyright
+ Copyright (c) 2012 -2013 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _TPM2_PTT_HCI_DEVICE_LIB_H_
+#define _TPM2_PTT_HCI_DEVICE_LIB_H_
+
+#include <Efi.h>
+
+///
+/// Default Timeout values
+///
+#define PTT_HCI_TIMEOUT_A 500 ///< 500 microseconds
+// AMI-Core Override for PTT +
+//#define PTT_HCI_TIMEOUT_B 10 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms)
+#define PTT_HCI_TIMEOUT_B 500 * 1000 ///< 10ms (max command processing time in PK-TPM ca. 3ms)
+// AMI-Core Override for PTT -
+#define PTT_HCI_TIMEOUT_C 1000 * 1000 ///< 1s
+#define PTT_HCI_TIMEOUT_D 500 * 1000 ///< 500 ms
+#define PTT_HCI_POLLING_PERIOD 140 ///< Poll register every 140 microsecondss
+
+/// TPM2_RESPONSE_HEADER size (10B) aligned to dword
+#define PTT_HCI_RESPONSE_HEADER_SIZE 12 ///< 12B
+
+/**
+ Checks whether FTPM is enabled (FTPM_STS::FTPM_EN).
+
+ @retval TRUE FTPM is enabled.
+ @retval FALSE FTPM is disabled. All LT writes will be dropped.
+ All LT reads will be returned with read data value of all 0’s.
+ The bit can only be written once per ME power cycle.
+**/
+BOOLEAN
+EFIAPI
+PttHciPresenceCheck (
+ VOID
+ );
+
+/**
+ Checks whether TPM2_Startup command has been executed (FTPM_STS::STARTUP_EXEC).
+ If command was executed, it should not be redundantly issued again.
+
+ @retval TRUE Startup command executed already.
+ @retval FALSE Startup command not executed yet.
+**/
+BOOLEAN
+EFIAPI
+PttHciStartupExecuted (
+ VOID
+ );
+
+/**
+ Sets FTPM_CMD and CA_START register to a defined value to indicate that a command is
+ available for processing.
+ Any host write to this register shall result in an interrupt to the ME firmware.
+
+ @retval EFI_SUCCESS Register successfully written.
+ @retval TBD
+**/
+EFI_STATUS
+EFIAPI
+PttHciRequestCommandExec (
+ VOID
+ );
+
+/**
+ Checks whether the value of a FTPM register satisfies the input BIT setting.
+
+ @param[in] Register Address port of register to be checked.
+ @param[in] BitSet Check these data bits are set.
+ @param[in] BitClear Check these data bits are clear.
+ @param[in] TimeOut The max wait time (unit MicroSecond) when checking register.
+
+ @retval EFI_SUCCESS The register satisfies the check bit.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciWaitRegisterBits(
+ IN EFI_PHYSICAL_ADDRESS RegAddress,
+ IN UINT32 BitSet,
+ IN UINT32 BitClear,
+ IN UINT32 TimeOut
+ );
+
+/**
+ Sends command to FTPM for execution.
+
+ @param[in] FtpmBuffer Buffer for TPM command data.
+ @param[in] DataLength TPM command data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSend(
+ IN UINT8 *FtpmBuffer,
+ IN UINT32 DataLength
+ );
+
+/**
+ Receives response data of last command from FTPM.
+
+ @param[out] FtpmBuffer Buffer for response data.
+ @param[out] RespSize Response data length.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+ @retval EFI_DEVICE_ERROR Unexpected device status.
+ @retval EFI_BUFFER_TOO_SMALL Response data is too long.
+**/
+EFI_STATUS
+EFIAPI
+PttHciReceive(
+ OUT UINT8 *FtpmBuffer,
+ OUT UINT32 *RespSize
+ );
+
+/**
+ Sends formatted command to FTPM for execution and returns formatted response data.
+
+ @param[in] InputBuffer Buffer for the input data.
+ @param[in] InputBufferSize Size of the input buffer.
+ @param[out] ReturnBuffer Buffer for the output data.
+ @param[out] ReturnBufferSize Size of the output buffer.
+
+ @retval EFI_SUCCESS Operation completed successfully.
+ @retval EFI_TIMEOUT The register can't run into the expected status in time.
+**/
+EFI_STATUS
+EFIAPI
+PttHciSubmitCommand(
+ IN UINT8 *InputBuffer,
+ IN UINT32 InputBufferSize,
+ OUT UINT8 *ReturnBuffer,
+ OUT UINT32 *ReturnBufferSize
+ );
+
+/**
+ Checks whether PTT is Ready
+
+ @retval TRUE PTT is ready.
+ @retval FALSE PTT is not ready
+
+**/
+BOOLEAN
+EFIAPI
+PttHciReadyCheck (
+ VOID
+ );
+
+
+#endif
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h b/Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h
new file mode 100644
index 0000000..1d1a484
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttHciRegs.h
@@ -0,0 +1,99 @@
+/** @file
+ Register definitions for PTT HCI (Platform Trust Technology - Host Controller Interface).
+
+ Conventions:
+
+ - Prefixes:
+ Definitions beginning with "R_" are registers
+ Definitions beginning with "B_" are bits within registers
+ Definitions beginning with "V_" are meaningful values of bits within the registers
+ Definitions beginning with "S_" are register sizes
+ Definitions beginning with "N_" are the bit position
+
+@copyright
+ Copyright (c) 2012 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Reference Module" and is
+ licensed for Intel CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+**/
+#ifndef _TPM2_PTT_HCI_REGS_H_
+#define _TPM2_PTT_HCI_REGS_H_
+
+
+///
+/// FTPM HCI register base address
+///
+#define R_PTT_HCI_BASE_ADDRESS 0xFED70000
+
+//
+// FTPM HCI Control Area
+//
+#define R_PTT_HCI_CA_RSVD 0x00
+#define R_PTT_HCI_CA_ERROR 0x04
+#define R_PTT_HCI_CA_CANCEL 0x08
+#define R_PTT_HCI_CA_START 0x0C
+#define R_PTT_HCI_CA_INT_RSVD 0x10
+#define R_PTT_HCI_CA_CMD_SZ 0x18
+#define R_PTT_HCI_CA_CMD 0x1C
+#define R_PTT_HCI_CA_RSP_SZ 0x24
+#define R_PTT_HCI_CA_RSP 0x28
+
+//
+// FTPM HCI Private Area
+//
+#define R_PTT_HCI_CMD 0x40
+#define R_PTT_HCI_STS 0x44
+
+///
+/// FTPM HCI Command and Response Buffer
+///
+#define R_PTT_HCI_CRB 0x80
+
+//
+// R_PTT_HCI_STS Flags
+//
+#define B_PTT_HCI_STS_ENABLED 0x00000001 ///< BIT0
+#define B_PTT_HCI_STS_READY 0x00000002 ///< BIT1
+#define B_PTT_HCI_STS_ACM_AS_CRTM 0x00000004 ///< BIT2
+#define B_PTT_HCI_STS_STARTUP_EXEC 0x00000008 ///< BIT3
+
+//
+// Value written to R_PTT_HCI_CMD and CA_START
+// to indicate that a command is available for processing
+//
+#define V_PTT_HCI_COMMAND_AVAILABLE_START 0x00000001
+#define V_PTT_HCI_COMMAND_AVAILABLE_CMD 0x00000000
+#define V_PTT_HCI_BUFFER_ADDRESS_RDY 0x00000003
+
+///
+/// Ignore bit setting mask for WaitRegisterBits
+///
+#define V_PTT_HCI_IGNORE_BITS 0x00000000
+
+///
+/// All bits clear mask for WaitRegisterBits
+///
+#define V_PTT_HCI_ALL_BITS_CLEAR 0xFFFFFFFF
+#define V_PTT_HCI_START_CLEAR 0x00000001
+
+///
+/// Max FTPM command/reponse buffer length
+///
+#define S_PTT_HCI_CRB_LENGTH 3968 ///< 0xFED70080:0xFED70FFF = 3968 Bytes
+// AMI-Core Override for PTT +
+#define PM_BASE_ADDRESS 0x1800
+// AMI-Core Override for PTT -
+
+
+#endif
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif
new file mode 100644
index 0000000..c2c3718
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "Tpm2PttLibrary"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\CRB_lib"
+ RefName = "Tpm2PttLibrary"
+[files]
+"Tpm2PttLibrary.sdl"
+"Tpm2PttLibrary.mak"
+"Tpm2PttHciDeviceLib.h"
+"Tpm2PttHciDeviceLib.c"
+"Tpm2PttHciRegs.h"
+<endComponent>
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak
new file mode 100644
index 0000000..1c2be5c
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.mak
@@ -0,0 +1,52 @@
+# /*++
+# Copyright (c) 2009 Intel Corporation. All rights reserved.
+# This software and associated documentation (if any) is furnished
+# under a license and may only be used or copied in accordance
+# with the terms of the license. Except as permitted by such
+# license, no part of this software or documentation may be
+# reproduced, stored in a retrieval system, or transmitted in any
+# form or by any means without the express written consent of
+# Intel Corporation.
+# --*/
+# MAK file for the ModulePart:AtDxeLib
+Tpm2PttLibrary_Lib : $(BUILD_DIR)\Tpm2PttLibrary.mak Tpm2PttDxeLibBin Tpm2PttPeiLibBin
+$(BUILD_DIR)\Tpm2PttLibrary.lib: Tpm2PttLibrary_Lib
+$(BUILD_DIR)\IA32\Tpm2PttLibrary.lib: Tpm2PttLibrary_Lib
+
+$(BUILD_DIR)\Tpm2PttLibrary.mak : $(Tpm2PttLibrary_DIR)\Tpm2PttLibrary.cif $(Tpm2PttLibrary_DIR)\Tpm2PttLibrary.mak $(BUILD_RULES)
+ $(CIF2MAK) $(Tpm2PttLibrary_DIR)\Tpm2PttLibrary.cif $(CIF2MAK_DEFAULTS)
+
+LIB_CFLAGS=$(CFLAGS)\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\Common\
+ /I$(Tpm2PttLibrary_DIR)\
+ /I$(TCG_DIR)\
+
+Tpm2PttDxeLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Tpm2PttLibrary.mak all \
+ "CFLAGS=$(LIB_CFLAGS) "\
+ LIBRARY_NAME=$(BUILD_DIR)\Tpm2PttLibrary.lib\
+ TYPE=LIBRARY
+
+
+Tpm2PttPeiLibBin :
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\Tpm2PttLibrary.mak all \
+ "CFLAGS=$(LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl
new file mode 100644
index 0000000..1432273
--- /dev/null
+++ b/Core/EM/TCG2/CRB_lib/Tpm2PttLibrary.sdl
@@ -0,0 +1,20 @@
+TOKEN
+ Name = "Tpm2PttLibrary_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "This driver will work for Intel FTPM only"
+End
+
+PATH
+ Name = "Tpm2PttLibrary_DIR"
+ Help = "Path"
+End
+
+
+MODULE
+ Help = "Includes Tpm2PttLibrary.mak to Project"
+ File = "Tpm2PttLibrary.mak"
+End
diff --git a/Core/EM/TCG2/Common/AmiTcgNvflagSample.c b/Core/EM/TCG2/Common/AmiTcgNvflagSample.c
new file mode 100644
index 0000000..5fffccd
--- /dev/null
+++ b/Core/EM/TCG2/Common/AmiTcgNvflagSample.c
@@ -0,0 +1,580 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/AmiTcgNvflagSample/AmiTcgNvflagSample.c 1 4/21/14 2:17p Fredericko $Revision:
+//
+// $Date:
+//*************************************************************************
+// Revision History
+// ----------------
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiTcgNvflagSample
+//
+// Description: This is a sample file for support TCG Ppi. It creates and installed
+// a protocal to access the persistent bios tpm flags in Tpm NV 0x50010000.
+// See Ppi Spec 1.2
+//
+//<AMI_FHDR_END>
+//************************************************************************
+#include "AmiTcgNvflagSample.h"
+#include <EFI.h>
+#include "TcgEFI12.h"
+#include "TcgPc.h"
+#include <TcgCommon.h>
+
+
+
+EFI_GUID gEfiTpmDxeDeviceProtocolGuid = EFI_TPM_DEVICE_PROTOCOL_GUID;
+EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+UINT8 Internal_flag = 0;
+
+UINT32
+NvSendTpmCommand (
+ IN EFI_TCG_PROTOCOL *tcg,
+ IN UINT32 ord,
+ IN int dataSize,
+ IN VOID *data
+);
+
+
+TPM_RESULT SendSelfTest()
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ TPM_RESULT tpmResult = 0;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+
+ Status = pBS->LocateProtocol( &gEfiTpmDxeDeviceProtocolGuid,NULL, &TpmDevice);
+ if ( EFI_ERROR( Status ))
+ {
+ return 0;
+ }
+
+ Status = pBS->LocateProtocol( &gEfiTcgProtocolGuid, NULL, &tcgSvc );
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Error: failed to locate TCG protocol: %r\n"));
+ return 0;
+ }
+
+#if defined DONT_SEND_SELFTEST_TILL_READY_TO_BOOT && DONT_SEND_SELFTEST_TILL_READY_TO_BOOT == 1
+ TpmDevice->Init( TpmDevice );
+
+ if(*(UINT16 *)(UINTN)(PORT_TPM_IOMEMBASE + 0xF00) == SELF_TEST_VID)
+ {
+ tpmResult = NvSendTpmCommand( tcgSvc, TPM_ORD_ContinueSelfTest,0, 0);
+ }
+
+ TpmDevice->Close( TpmDevice );
+#endif
+ return tpmResult;
+}
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Set_Persistent_Bios_TPM_Flags
+//
+// Description: Sets persistent bios flags in TPM NV
+//
+//
+// Input: IN PERSISTENT_BIOS_TPM_FLAGS *
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS Set_Persistent_Bios_TPM_Flags(PERSISTENT_BIOS_TPM_FLAGS *NvBIOSflags)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TPM_NV_WRITE_CMD WriteCmd;
+ TPM_NV_WRITE_RET WriteRet;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ TPM_RESULT RetCode;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+ UINTN Count = 10;
+
+ if(NvBIOSflags == NULL)return EFI_INVALID_PARAMETER;
+
+ Status = pBS->LocateProtocol( &gEfiTpmDxeDeviceProtocolGuid,NULL, &TpmDevice);
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = pBS->LocateProtocol( &gEfiTcgProtocolGuid, NULL, &tcgSvc );
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Error: failed to locate TCG protocol: %r\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ SendSelfTest();
+
+ TpmDevice->Init( TpmDevice );
+
+ //physical presence is required so tcgpei should have already taken care of
+ //physical presence requirement
+ WriteCmd.writeHeader.dataSize = TPM_H2NL( NV_DATA_SIZE );
+ WriteCmd.writeHeader.tag = TPM_H2NS(TPM_TAG_RQU_COMMAND);
+ WriteCmd.writeHeader.paramSize = TPM_H2NL( sizeof(TPM_NV_WRITE_CMD_HDR) + NV_DATA_SIZE);
+ WriteCmd.writeHeader.ordinal = TPM_H2NL(TPM_ORD_NV_WriteValue);
+ WriteCmd.writeHeader.nvIndex = TPM_H2NL(0x50010000);
+ WriteCmd.writeHeader.offset = TPM_H2NL(0x00000000);
+
+ pBS->SetMem(WriteCmd.data, NV_DATA_SIZE, 0);
+ pBS->CopyMem(WriteCmd.data, NvBIOSflags, sizeof(PERSISTENT_BIOS_TPM_FLAGS));
+
+ Status = tcgSvc->PassThroughToTpm ( tcgSvc, \
+ sizeof(TPM_NV_WRITE_CMD_HDR) + NV_DATA_SIZE, \
+ (UINT8*)&WriteCmd, \
+ sizeof(TPM_NV_WRITE_RET), \
+ (UINT8*)&WriteRet );
+
+ RetCode = WriteRet.returnCode;
+
+ if ( EFI_ERROR(Status) || (WriteRet.returnCode != 0)){
+
+ TRACE((TRACE_ALWAYS, "(TPM Error) Status: %r; RetCode: %x.\n", \
+ Status, \
+ TPM_H2NL(WriteRet.returnCode)));
+//wait for proper return codes
+ while(TPM_H2NL(RetCode)==INTERNAL_TPM_DOING_SELFTEST){
+
+ pBS->Stall (500000); //stall 500ms for Selftest to complete
+
+ Status = tcgSvc->PassThroughToTpm ( tcgSvc, \
+ sizeof(TPM_NV_WRITE_CMD_HDR) + NV_DATA_SIZE, \
+ (UINT8*)&WriteCmd, \
+ sizeof(TPM_NV_WRITE_RET), \
+ (UINT8*)&WriteRet );
+
+ RetCode = WriteRet.returnCode;
+ if(Count == 0)break;
+ Count-=1; //total timeout is 5minutes for define the space
+ }
+
+ }
+
+
+ TpmDevice->Close( TpmDevice );
+
+
+ if(RetCode != 0)
+ {
+ return EFI_ACCESS_DENIED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmSet_Persistent_Bios_TPM_Flags
+//
+// Description: Sets persistent bios flags in TPM NV
+//
+//
+// Input: IN PERSISTENT_BIOS_TPM_FLAGS *
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS TcmSet_Persistent_Bios_TPM_Flags(PERSISTENT_BIOS_TPM_FLAGS *NvBIOSflags)
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmRead_Persistent_Bios_TPM_Flags
+//
+// Description: Sets persistent bios flags in TPM NV
+//
+//
+// Input: IN PERSISTENT_BIOS_TPM_FLAGS *
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS TcmRead_Persistent_Bios_TPM_Flags(PERSISTENT_BIOS_TPM_FLAGS *NvBIOSflags)
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Read_Persistent_Bios_TPM_Flags
+//
+// Description: Read persistent bios flags in TPM NV
+//
+//
+// Input: IN PERSISTENT_BIOS_TPM_FLAGS *
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS Read_Persistent_Bios_TPM_Flags( PERSISTENT_BIOS_TPM_FLAGS *NvBIOSflags)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TPM_NV_READ_CMD ReadCmd;
+ TPM_NV_READ_RET ReadRet;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+ EFI_GUID FlagsStatusguid = AMI_TCG_CONFIRMATION_FLAGS_GUID;
+ PERSISTENT_BIOS_TPM_FLAGS TpmNvflags;
+ UINTN Size = sizeof(PERSISTENT_BIOS_TPM_FLAGS);
+
+ if(NvBIOSflags == NULL)return EFI_INVALID_PARAMETER;
+
+ Status = pBS->LocateProtocol( &gEfiTpmDxeDeviceProtocolGuid,NULL, &TpmDevice);
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = pBS->LocateProtocol( &gEfiTcgProtocolGuid, NULL, &tcgSvc );
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Error: failed to locate TCG protocol: %r\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ TpmDevice->Init( TpmDevice );
+
+ //read space
+ ReadCmd.dataSize = TPM_H2NL( NV_DATA_SIZE );
+ ReadCmd.tag = TPM_H2NS(TPM_TAG_RQU_COMMAND);
+ ReadCmd.paramSize = TPM_H2NL( sizeof(TPM_NV_READ_CMD));
+ ReadCmd.ordinal = TPM_H2NL(TPM_ORD_NV_ReadValue);
+ ReadCmd.nvIndex = TPM_H2NL(0x50010000);
+ ReadCmd.offset = TPM_H2NL(0x00000000);
+
+ Status = tcgSvc->PassThroughToTpm ( tcgSvc, \
+ sizeof(TPM_NV_READ_CMD) , \
+ (UINT8*)&ReadCmd, \
+ (sizeof(TPM_NV_READ_CMD) - 4 + NV_DATA_SIZE), \
+ (UINT8*)&ReadRet );
+
+ if ( EFI_ERROR(Status) || (ReadRet.returnCode != 0))
+ TRACE((TRACE_ALWAYS, "(TPM Error) Status: %r; RetCode: %x.\n", \
+ Status, \
+ TPM_H2NL(ReadRet.returnCode)));
+
+
+
+ TpmDevice->Close( TpmDevice );
+
+ if( TPM_H2NL(ReadRet.returnCode) == INTERNAL_TPM_BADINDEX ){
+
+ Status = pRS->GetVariable( L"TPMPERBIOSFLAGS", \
+ &FlagsStatusguid, \
+ NULL, \
+ &Size, \
+ &TpmNvflags );
+
+ if(!EFI_ERROR(Status)){
+ NvBIOSflags->NoPpiProvision = TRUE;
+ NvBIOSflags->NoPpiClear = FALSE;
+ NvBIOSflags->NoPpiMaintenance = FALSE;
+ return EFI_SUCCESS;
+ }else{
+ if(Internal_flag == 1)
+ {
+ return EFI_NOT_AVAILABLE_YET;
+ }
+ }
+ }
+
+ if( ReadRet.returnCode != 0)
+ {
+ //all ways require confirmation
+ NvBIOSflags->NoPpiProvision = TRUE;
+ NvBIOSflags->NoPpiClear = FALSE;
+ NvBIOSflags->NoPpiMaintenance = FALSE;
+ return EFI_SUCCESS;
+ }
+
+ pBS->CopyMem (NvBIOSflags, ReadRet.data, sizeof(PERSISTENT_BIOS_TPM_FLAGS));
+ return EFI_SUCCESS;
+}
+
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: NvSendTpmCommand
+//
+// Description: Sends a command to the TPM
+//
+// Input: *EFI_TCG_PROTOCOL - Tcg Protocol type.
+// UINT32 - Tcg Command ordinal.
+// int - cmd datasize.
+// VOID* - cmd data.
+//
+// Output: UINT32 - TPM_RESULT
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+NvSendTpmCommand (
+ IN EFI_TCG_PROTOCOL *tcg,
+ IN UINT32 ord,
+ IN int dataSize,
+ IN VOID *data
+)
+{
+ EFI_STATUS Status;
+ static UINT8 result[0x400];
+ TPM_1_2_RET_HEADER* tpmResult;
+ struct {
+ TPM_1_2_CMD_HEADER hdr;
+ UINT8 data[0x100];
+ } cmd;
+
+ cmd.hdr.Tag = TPM_H2NS (TPM_TAG_RQU_COMMAND);
+ cmd.hdr.ParamSize = TPM_H2NL (sizeof(TPM_1_2_RET_HEADER) + dataSize);
+ cmd.hdr.Ordinal = TPM_H2NL (ord);
+ pBS->CopyMem(cmd.data, data, dataSize);
+ Status = tcg->PassThroughToTpm ( tcg, \
+ sizeof(TPM_1_2_CMD_HEADER) + dataSize, \
+ (UINT8*)&cmd, \
+ sizeof (result), \
+ (UINT8*)&result );
+ tpmResult = (TPM_1_2_RET_HEADER*)result;
+ if ( EFI_ERROR(Status) || (tpmResult->RetCode != 0))
+ TRACE((TRACE_ALWAYS, "TXT (TPM Error) Status: %r; RetCode: %x.\n", \
+ Status, \
+ TPM_H2NL(tpmResult->RetCode) ));
+ return tpmResult->RetCode;
+}
+
+
+
+PERSISTENT_BIOS_TPM_MANAGEMENT_FLAGS_PROTOCOL PersistentBiosflagsManagementProtocol = {
+ Read_Persistent_Bios_TPM_Flags,
+ Set_Persistent_Bios_TPM_Flags
+};
+
+PERSISTENT_BIOS_TPM_MANAGEMENT_FLAGS_PROTOCOL TcmPersistentBiosflagsManagementProtocol = {
+ TcmRead_Persistent_Bios_TPM_Flags,
+ TcmSet_Persistent_Bios_TPM_Flags
+};
+
+EFI_GUID Overrideguid = AMI_BIOSPPI_FLAGS_MANAGEMENT_GUID;
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AmiTcgPpiNvflagEntry
+//
+// Description: Entry point
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI AmiTcgPpiNvflagEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+ PERSISTENT_BIOS_TPM_FLAGS NvBIOSflags;
+ TPM_RESULT RetCode;
+ UINTN Count = 10;
+ EFI_GUID FlagsStatusguid = AMI_TCG_CONFIRMATION_FLAGS_GUID;
+ UINTN Size = sizeof(PERSISTENT_BIOS_TPM_FLAGS);
+ TPM_DEF_NV_DATA CmdDefineNvram [] = { \
+ // TPM_NV_DATA_PUBLIC1 & TPM_NV_DATA_PUBLIC1.TPM_PCR_INFO_SHORT
+ TPM_H2NS(0x18), TPM_H2NL(0x50010000), TPM_H2NS(0x03), 0, 0, 0 , 0x1f, \
+ // TPM_NV_DATA_PUBLIC1.TPM_PCR_INFO_SHORT.TCPA_DIGEST
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ // TPM_NV_DATA_PUBLIC2.TPM_PCR_INFO_SHORT
+ TPM_H2NS(0x3), 0, 0, 0 , 0x1f, \
+ // TPM_NV_DATA_PUBLIC2.TPM_PCR_INFO_SHORT.TCPA_DIGEST
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, \
+ // TPM_NV_DATA_PUBLIC2
+ TPM_H2NS(0x17), TPM_H2NL(0x00000001), 0, 0, 0, TPM_H2NL(NV_DATA_SIZE), \
+ // TCPA_DIGEST
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol( &gEfiTpmDxeDeviceProtocolGuid,NULL, &TpmDevice);
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = pBS->LocateProtocol( &gEfiTcgProtocolGuid, NULL, &tcgSvc );
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Error: failed to locate TCG protocol: %r\n"));
+ return EFI_NOT_FOUND;
+ }
+
+ if(AutoSupportType()){
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &Overrideguid,
+ EFI_NATIVE_INTERFACE,
+ &TcmPersistentBiosflagsManagementProtocol);
+
+ return Status;
+ }
+
+ Internal_flag = 1;
+
+ Status = Read_Persistent_Bios_TPM_Flags(&NvBIOSflags);
+
+ TpmDevice->Init( TpmDevice );
+
+
+ //analyze return code
+ if(Status == EFI_NOT_AVAILABLE_YET){
+ //it might not be defined so define it
+
+ SendSelfTest(); //make sure we send selftest before defining space
+
+ RetCode = NvSendTpmCommand ( tcgSvc, \
+ TPM_ORD_NV_DefineSpace, \
+ sizeof(TPM_DEF_NV_DATA), \
+ &CmdDefineNvram );
+
+ if(RetCode != 0){
+ while(TPM_H2NL(RetCode) == INTERNAL_TPM_DOING_SELFTEST){
+
+ pBS->Stall (500000); //stall 500ms for Selftest to complete
+
+ RetCode = NvSendTpmCommand ( tcgSvc, \
+ TPM_ORD_NV_DefineSpace, \
+ sizeof(TPM_DEF_NV_DATA), \
+ &CmdDefineNvram );
+
+ if(Count == 0)break;
+ Count-=1;
+ }
+ }
+
+ Internal_flag = 0;
+
+ //read again to make sure we can read TPM Indices
+ Status = Read_Persistent_Bios_TPM_Flags(&NvBIOSflags);
+ if(Status)return EFI_ABORTED;
+
+ //if read is successful set the default values only once
+ //we only do this here because of the protections on TPM Nvram
+ //writes without owner. Do this only after defining the index
+ NvBIOSflags.NoPpiProvision = NO_PPI_PROVISION_DEFAULT;
+ NvBIOSflags.NoPpiClear = NO_PPI_CLEAR_DEFAULT;
+ NvBIOSflags.NoPpiMaintenance = NO_PPI_MAINTENANCE_DEFAULT;
+
+ Set_Persistent_Bios_TPM_Flags(&NvBIOSflags);
+ }
+ else if(Status){
+ return EFI_ABORTED;
+ }else{
+ //already allocated but check for first boot.
+ Status = pRS->GetVariable( L"TPMPERBIOSFLAGS", \
+ &FlagsStatusguid, \
+ NULL, \
+ &Size, \
+ &NvBIOSflags );
+
+ if(Status == EFI_NOT_FOUND){
+ NvBIOSflags.NoPpiProvision = NO_PPI_PROVISION_DEFAULT;
+ NvBIOSflags.NoPpiClear = NO_PPI_CLEAR_DEFAULT;
+ NvBIOSflags.NoPpiMaintenance = NO_PPI_MAINTENANCE_DEFAULT;
+ Set_Persistent_Bios_TPM_Flags(&NvBIOSflags);
+ }
+ }
+
+ TpmDevice->Close( TpmDevice );
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &Overrideguid,
+ EFI_NATIVE_INTERFACE,
+ &PersistentBiosflagsManagementProtocol);
+
+ return Status;
+}
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/AmiTcgNvflagSample.cif b/Core/EM/TCG2/Common/AmiTcgNvflagSample.cif
new file mode 100644
index 0000000..ce3e997
--- /dev/null
+++ b/Core/EM/TCG2/Common/AmiTcgNvflagSample.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "AmiTcgNvflagSample"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "AmiTcgNvflagSample"
+[files]
+"AmiTcgNvflagSample.sdl"
+"AmiTcgNvflagSample.mak"
+"AmiTcgNvflagSample.c"
+"AmiTcgNvflagSample.dxs"
+"AmiTcgNvflagSample.h"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/AmiTcgNvflagSample.dxs b/Core/EM/TCG2/Common/AmiTcgNvflagSample.dxs
new file mode 100644
index 0000000..3e867b7
--- /dev/null
+++ b/Core/EM/TCG2/Common/AmiTcgNvflagSample.dxs
@@ -0,0 +1,44 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/AmiTcgNvflagSample/AmiTcgNvflagSample.dxs 1 4/21/14 2:17p Fredericko $Revision:
+//
+// $Date: 4/21/14 2:17p $Log:
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiTcgNvflagSample.dxs
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "Include\Protocol\TcgService.h"
+
+DEPENDENCY_START
+ EFI_TCG_PROTOCOL_GUID
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/AmiTcgNvflagSample.h b/Core/EM/TCG2/Common/AmiTcgNvflagSample.h
new file mode 100644
index 0000000..3ba4ab1
--- /dev/null
+++ b/Core/EM/TCG2/Common/AmiTcgNvflagSample.h
@@ -0,0 +1,199 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/AmiTcgNvflagSample/AmiTcgNvflagSample.h 1 4/21/14 2:17p Fredericko $Revision:
+//
+// $Date:
+//*************************************************************************
+// Revision History
+// ----------------
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiTcgNvflagSample
+//
+// Description: This is a sample file for support TCG Ppi. It creates and installed
+// a protocal to access the persistent bios tpm flags in Tpm NV 0x50010000.
+// See Ppi Spec 1.2
+//
+//<AMI_FHDR_END>
+//************************************************************************
+#include <AmiDxeLib.h>
+#include "token.h"
+#include "protocol\TcgService\TcgService.h"
+#include <Protocol\TpmDevice\TpmDevice.h>
+#include "TCGMisc.h"
+
+
+#pragma pack(1)
+
+typedef struct TPM_NV_READ_CMD
+{
+ TPM_TAG tag;
+ UINT32 paramSize;
+ TPM_COMMAND_CODE ordinal;
+ TPM_NV_INDEX nvIndex;
+ UINT32 offset;
+ UINT32 dataSize;
+} TPM_NV_READ_CMD;
+
+typedef struct TPM_NV_READ_RET
+{
+ TPM_TAG tag;
+ UINT32 paramSize;
+ TPM_RESULT returnCode;
+ UINT32 dataSize;
+ UINT8 data[NV_DATA_SIZE];
+ UINT8 nonceEven[20];
+ UINT8 nonceOdd[20];
+ BOOLEAN ContinueAuthSession;
+ UINT8 ownerAuth[20];
+} TPM_NV_READ_RET;
+
+typedef struct TPM_NV_WRITE_CMD_HDR
+{
+ TPM_TAG tag;
+ UINT32 paramSize;
+ TPM_COMMAND_CODE ordinal;
+ TPM_NV_INDEX nvIndex;
+ UINT32 offset;
+ UINT32 dataSize;
+} TPM_NV_WRITE_CMD_HDR;
+
+typedef struct TPM_NV_WRITE_CMD
+{
+ TPM_NV_WRITE_CMD_HDR writeHeader;
+ UINT8 data[NV_DATA_SIZE];
+} TPM_NV_WRITE_CMD;
+
+
+typedef struct TPM_NV_WRITE_RET
+{
+ TPM_TAG tag;
+ UINT32 paramSize;
+ TPM_RESULT returnCode;
+ UINT8 nonceEven[20];
+ UINT8 nonceOdd[20];
+ BOOLEAN ContinueAuthSession;
+ UINT8 ownerAuth[20];
+} TPM_NV_WRITE_RET;
+
+
+typedef struct _TCPA_DIGEST {
+ UINT8 digest[20];
+} TCPA_DIGEST;
+
+typedef struct _TPM_PCR_SELECTION {
+ UINT16 sizeOfSelect;
+ UINT8 pcrSelect[3];
+} NV_PCR_SELECTION;
+
+typedef struct _TPM_PCR_INFO_SHORT {
+ UINT16 sizeOfSelect;
+ UINT8 pcrSelect[3];
+ UINT8 localityAtRelease;
+ TCPA_DIGEST digestAtRelease;
+} NV_PCR_INFO_SHORT;
+
+typedef struct _TPM_NV_ATTRIBUTES {
+ UINT16 tag;
+ UINT32 attributes;
+} NV_ATTRIBUTES;
+
+typedef struct _TPM_NV_DATA_PUBLIC1 {
+ UINT16 Tag_;
+ UINT32 NvIndex;
+ NV_PCR_INFO_SHORT PcrInfoRead;
+} NV_DATA_PUBLIC1;
+
+typedef struct _TPM_NV_DATA_PUBLIC2 {
+ NV_PCR_INFO_SHORT PcrInfoWrite;
+ NV_ATTRIBUTES PerMission;
+ UINT8 bReadSTClear;
+ UINT8 bWriteSTClear;
+ UINT8 bWriteDefine;
+ UINT32 DataSize;
+} NV_DATA_PUBLIC2;
+
+typedef struct _TPM_DEF_NV_DATA {
+ NV_DATA_PUBLIC1 TpmDefineSpaceIn_pubinfo1;
+ NV_DATA_PUBLIC2 TpmDefineSpaceIn_pubinfo2;
+ TCPA_DIGEST TpmDefineSpaceIn_encAuth;
+} TPM_DEF_NV_DATA;
+
+
+typedef struct TPM_NV_PUBLIC_DATA
+{
+ UINT16 tag;
+ UINT32 Index;
+ UINT16 InfoReadsizeOfSelect;
+ UINT16 InfoReadpcrSelect;
+ UINT8 InfoReadlocalityAtRelease;
+ UINT8 InfoReaddigestAtRelease[20];
+ UINT16 InfoWritesizeOfSelect;
+ UINT16 InfoWritepcrSelect;
+ UINT8 InfoWritelocalityAtRelease;
+ UINT8 InfoWritedigestAtRelease[20];
+ UINT16 AttribTag;
+ UINT32 Attributes;
+ BOOLEAN bReadSTClear;
+ BOOLEAN bWriteSTClear;
+ BOOLEAN bWriteDefine;
+ UINT32 dataSize;
+}TPM_NV_PUBLIC_DATA;
+
+
+typedef struct TPM_NV_DEFINESPCE_CMD
+{
+ TPM_TAG tag;
+ UINT32 paramSize;
+ TPM_COMMAND_CODE ordinal;
+ TPM_NV_PUBLIC_DATA pubInfo;
+ UINT8 encAuth[20];
+} TPM_NV_DEFINESPCE_CMD;
+
+
+typedef struct TPM_NV_DEFINESPCE_RET
+{
+ TPM_TAG tag;
+ UINT32 paramSize;
+ TPM_RESULT returnCode;
+ UINT8 nonceEven[20];
+ UINT8 nonceOdd[20];
+ BOOLEAN ContinueAuthSession;
+ UINT8 ownerAuth[20];
+} TPM_NV_DEFINESPCE_RET;
+
+
+#define INTERNAL_TPM_BADINDEX 0x00000002
+#define INTERNAL_TPM_DOING_SELFTEST 0x00000802
+
+#pragma pack()
+
+#define EFI_MAX_BIT 0x80000000
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/AmiTcgNvflagSample.mak b/Core/EM/TCG2/Common/AmiTcgNvflagSample.mak
new file mode 100644
index 0000000..5141bcf
--- /dev/null
+++ b/Core/EM/TCG2/Common/AmiTcgNvflagSample.mak
@@ -0,0 +1,75 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/AmiTcgNvflagSample/AmiTcgNvflagSample.mak 1 4/21/14 2:17p Fredericko $Revision:
+#
+# $Date: 4/21/14 2:17p $Log:
+#
+#*************************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiTcgNvflagSample.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : AmiTcgNvflagSample
+
+#---------------------------------------------------------------------------
+# Making AmiTcgNvflagSample
+#---------------------------------------------------------------------------
+AmiTcgNvflagSample : $(BUILD_DIR)\AmiTcgNvflagSample.mak AmiTcgNvflagSamplebin
+
+$(BUILD_DIR)\AmiTcgNvflagSample.mak : $(AMI_TCG_NVFLAG_SAMPLE_DIR)\$(@B).cif $(AMI_TCG_NVFLAG_SAMPLE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AMI_TCG_NVFLAG_SAMPLE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+MODULE_CFLAGS=$(CFLAGS)\
+ /I$(TCG_DIR)\
+ /I$(TPM12_DIR)\
+ /I$(TCG_DIR)\Common\
+ /I$(AMI_TCG_PLATFORM_DXE_DIR)\
+ /I$(TCG_DIR)\protocol\TcgService\
+ /I$(TCG_DIR)\protocol\TpmDevice\
+ /I$(PROJECT_DIR)\Include\Protocol\
+
+AmiTcgNvflagSample_OBJECTS = \
+$(BUILD_DIR)\$(AMI_TCG_NVFLAG_SAMPLE_DIR)\AmiTcgNvflagSample.obj \
+
+AmiTcgNvflagSamplebin: $(AMIDXELIB) $(BUILD_DIR)\AmiTcmlib.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiTcgNvflagSample.mak all\
+ "CFLAGS=$(MODULE_CFLAGS)"\
+ GUID=50F6096D-7C98-4c78-9A1D-C5A1833B6A88 \
+ ENTRY_POINT=AmiTcgPpiNvflagEntry \
+ TYPE=BS_DRIVER \
+ "OBJECTS=$(AmiTcgNvflagSample_OBJECTS)"\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1
+#---------------------------------------------------------------------------
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/TCG2/Common/AmiTcgNvflagSample.sdl b/Core/EM/TCG2/Common/AmiTcgNvflagSample.sdl
new file mode 100644
index 0000000..13923e6
--- /dev/null
+++ b/Core/EM/TCG2/Common/AmiTcgNvflagSample.sdl
@@ -0,0 +1,66 @@
+TOKEN
+ Name = "AMI_TCG_NVFLAG_SAMPLE_SUPPORT"
+ Value = "1"
+ Help = "Sample module to provide interface to manipulate TPM NV BIOS FLAGS"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "USE_AMI_PERSISTENT_BIOS_MANAGEMENT_FLAGS_SUPPORT" "=" "1"
+ Token = "TCGPPISPEC_1_2_SUPPORT" "=" "1"
+ Token = "TPM12Enabled" "!=" "0"
+End
+
+
+TOKEN
+ Name = "NV_DATA_SIZE"
+ Value = "10"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NO_PPI_PROVISION_DEFAULT"
+ Value = "001h"
+ Help = "default for TPM NoPpiProvision flag"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NO_PPI_CLEAR_DEFAULT"
+ Value = "000h"
+ Help = "default for TPM NoPpiclear flag"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NO_PPI_MAINTENANCE_DEFAULT"
+ Value = "000h"
+ Help = "default for TPM NoPpiclear flag"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "AMI_TCG_NVFLAG_SAMPLE_DIR"
+End
+
+MODULE
+ Help = "AmiTcgNvflagSample.mak"
+ File = "AmiTcgNvflagSample.mak"
+End
+
+
+ELINK
+ Name = "$(BUILD_DIR)\AmiTcgNvflagSample.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/Common.cif b/Core/EM/TCG2/Common/Common.cif
new file mode 100644
index 0000000..d79a439
--- /dev/null
+++ b/Core/EM/TCG2/Common/Common.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "Common"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "Common"
+[parts]
+"TcgPei"
+"TcgDxe"
+"AmiTcgBinaries"
+"AmiTcgNvflagSample"
+"AmiTcgPlatform"
+"TcgDxeplatform"
+"TcgLegacy"
+"TcgPeiplatform"
+"TcgPlatformSetupPeiPolicy"
+"TcgPlatformSetupPolicy"
+"TcgSetup"
+"TCGSmm"
+"TpmClearOnRollback"
+"Tpm20PlatformDxe"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/CommonHeaders.cif b/Core/EM/TCG2/Common/CommonHeaders.cif
new file mode 100644
index 0000000..324c25a
--- /dev/null
+++ b/Core/EM/TCG2/Common/CommonHeaders.cif
@@ -0,0 +1,19 @@
+<component>
+ name = "CommonHeaders"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "CommonHeaders"
+[files]
+"TCGMisc.h"
+"TcgPrivate.h"
+"TcgPrivate.c"
+[parts]
+"TcgService_PPI"
+"TcgService_Protocol"
+"TpmDevice_PPI"
+"TpmDevice_Protocol"
+"AmiTcgPlatformProtocol"
+"AmiTpmClearOnRollbackProtocol"
+"Tpm20Includes"
+"AmiTcgPlatformPpi"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/EMpCallBin.asm b/Core/EM/TCG2/Common/EMpCallBin.asm
new file mode 100644
index 0000000..f63c3d7
--- /dev/null
+++ b/Core/EM/TCG2/Common/EMpCallBin.asm
@@ -0,0 +1,337 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2005, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;*************************************************************************
+; $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/EMpCallBin.asm 1 4/21/14 2:16p Fredericko $
+;
+; $Revision: 1 $
+;
+; $Date: 4/21/14 2:16p $
+;*************************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/EMpCallBin.asm $
+;
+; 1 4/21/14 2:16p Fredericko
+;
+; 1 10/08/13 12:03p Fredericko
+; Initial Check-In for Tpm-Next module
+;
+; 1 7/10/13 5:51p Fredericko
+; [TAG] EIP120969
+; [Category] New Feature
+; [Description] TCG (TPM20)
+;
+; 13 5/09/12 6:38p Fredericko
+; Fix for possible Tcm hang issues during reboot cycles.
+;
+; 12 1/20/12 9:13p Fredericko
+; Added code to work around RTC issue when using legacy IO support.
+;
+; 11 4/22/11 8:53p Fredericko
+; Token to enable stack workaround for binaries that don't return
+; properly.
+;
+; 10 3/29/11 1:13p Fredericko
+;
+; [TAG] EIP 54642
+; [Category] Improvement
+; [Description] 1. Checkin Files related to TCG function override
+; 2. Include TCM and TPM auto detection
+; [Files] Affects all TCG files
+;
+; 9 3/28/11 2:22p Fredericko
+; [TAG] EIP 54642
+; [Category] Improvement
+; [Description] 1. Checkin Files related to TCG function override
+; 2. Include TCM and TPM auto detection
+; [Files] Affects all TCG files
+;
+; 8 5/19/10 5:38p Fredericko
+; Included File Header
+; Included File Revision History
+; Updated AMI Function Headers
+; Code Beautification
+; EIP 37653
+;
+; 7 4/16/10 10:36a Fredericko
+; Function Headers updated
+;
+; 6 3/23/10 9:21p Fredericko
+;
+; 5 3/23/10 6:56p Fredericko
+;
+; 4 3/19/10 4:27p Fredericko
+; Modified the way Driver calls into legacy TCG Binary.
+;
+; 3 6/02/09 1:12p Fredericko
+;
+; 2 5/18/09 6:04p Fredericko
+;
+; 1 5/18/09 6:03p Fredericko
+; Initial check-in for EMpCallBin.asm for CTPM support infrastructure
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: EMpCallBin.asm
+;
+; Description:
+; Contains functions for legacy TCG calls in 32 bit Binaries
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+.code
+ INCLUDE token.equ
+
+;Global variable for MpLoc
+ public MpLoc
+ MpLoc label dword
+ FWORD ?
+
+public TPMRTCSave
+ TPMRTCSave label dword
+ WORD ?
+
+TPMTransmitEntryStruct STRUC
+ pbInBuf DD ? ;[IN] Pointer to input data for the data transfers to TPM
+ dwInLen DD ? ; [IN] Length of the input data record
+ pbOutBuf DD 0 ; [OUT] Pointer to output buffer for the data from the TPM
+ dwOutLen DD 0 ; [IN/OUT] DWORD to store the length info of the
+ ; output data record.
+TPMTransmitEntryStruct ENDS
+
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: Prepare2Thunkproc
+;
+; Description:
+; Function to setup location of Mp Driver as a local variable
+;
+; Input:
+; ecx - Location of MP Driver
+; dx - Segment for MP Driver
+;
+; Output:
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+Prepare2Thunkproc proc
+ push rax
+ push rcx
+ push rdx
+ mov dword ptr [MpLoc],ecx
+ mov word ptr [MpLoc + 4],dx
+ pop rdx
+ pop rcx
+ pop rax
+ ret
+Prepare2Thunkproc ENDP
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgDxeCallMPDriver (TCM_support eq 0)
+;
+; Description:
+; Makes a function call into MP Driver
+;
+; Input:
+; rcx - Call type: 4-Buffer Transmission call
+; rsi - Buffer to be tansmitted
+;
+; Output:
+; rax - TCG return code
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+TpmDxeCallMPDriver proc
+ push rbp
+ push rax
+ push rcx
+ push rdx
+ mov rbp,rsp
+ cmp rcx, 04h
+ jnz Empty_Buff
+ MOV rsi, rdx
+Empty_Buff:
+ mov rax, rcx
+ push rcx
+ mov rcx, offset next
+IF MKF_Stack_Work_Around
+ mov dword ptr [IP_Offset], ecx
+ENDIF
+IF MKF_PMBASE_RTC_WKAround
+ push rax
+ push rdx
+ mov dx, MKF_PM_BASE_ADDRESS
+ in ax, dx
+ mov word ptr [TPMRTCSave],ax
+ pop rdx
+ pop rax
+ENDIF
+ pop rcx
+ call fword ptr [MpLoc]
+IF MKF_Stack_Work_Around
+ db 0eah
+IP_Offset:
+ dd 0
+ dw 038h
+ENDIF
+next:
+IF MKF_PMBASE_RTC_WKAround
+ push rax
+ push rdx
+ mov dx,MKF_PM_BASE_ADDRESS
+ in ax, dx
+ test ax, dx
+ jz RtcNotSet
+ mov ax, word ptr [TPMRTCSave]
+ and ax,0FBFEh
+ or ax,0400h
+ out dx, ax
+RtcNotSet:
+ pop rdx
+ pop rax
+ENDIF
+ mov rsp,rbp
+ pop rdx
+ pop rcx
+ pop rax
+ pop rbp
+ ret
+TpmDxeCallMPDriver ENDP
+
+
+
+TcmIoDelay proc
+ push rax
+ mov al, 80h
+ out 080h, al
+ in al, 080h
+ pop rax
+ ret
+TcmIoDelay ENDP
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgDxeCallMPDriver (TCM_support eq 1)
+;
+; Description:
+; Makes a function call into MP Driver
+;
+; Input:
+; rcx - Call type: 4-Buffer Transmission call
+; rsi - Buffer to be tansmitted
+;
+; Output:
+; rax - TCG return code
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+TcmDxeCallMPDriver proc
+ push rax
+ push rcx
+ push rdx
+ push rsi
+ cmp rcx, 04h
+ jnz Empty_Buff
+ MOV rsi, rdx
+Empty_Buff:
+ mov rax, rcx
+ call TcmIoDelay
+ call fword ptr [MpLoc]
+ call TcmIoDelay
+ pop rsi
+ pop rdx
+ pop rcx
+ pop rax
+ ret
+TcmDxeCallMPDriver ENDP
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgThunk32
+;
+; Description:
+; Go to compatibility mode for MP driver
+;
+; Input:
+;
+; Output:
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+TcgThunk32 proc
+TcgThunk32 ENDP
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgThunkSwitchback
+;
+; Description:
+; Switch back to 64bit mode
+;
+; Input:
+;
+; Output:
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+TcgThunkSwitchback proc
+TcgThunkSwitchback ENDP
+
+END
diff --git a/Core/EM/TCG2/Common/EMpCallBin32.asm b/Core/EM/TCG2/Common/EMpCallBin32.asm
new file mode 100644
index 0000000..bc030eb
--- /dev/null
+++ b/Core/EM/TCG2/Common/EMpCallBin32.asm
@@ -0,0 +1,251 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2005, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+; $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/EMpCallBin32.asm 1 4/21/14 2:16p Fredericko $
+;
+; $Revision: 1 $
+;
+; $Date: 4/21/14 2:16p $
+;*************************************************************************
+;Revision History
+; ----------------
+; $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/EMpCallBin32.asm $
+;
+; 1 4/21/14 2:16p Fredericko
+;
+; 1 10/08/13 12:03p Fredericko
+; Initial Check-In for Tpm-Next module
+;
+; 1 7/10/13 5:51p Fredericko
+; [TAG] EIP120969
+; [Category] New Feature
+; [Description] TCG (TPM20)
+;
+; 4 4/27/11 3:03p Fredericko
+; Changes for working around stack problems when calling into binaries
+; that don't return properly.
+;
+; 3 3/29/11 1:15p Fredericko
+;
+; [TAG] EIP 54642
+; [Category] Improvement
+; [Description] 1. Checkin Files related to TCG function override
+; 2. Include TCM and TPM auto detection
+; [Files] Affects all TCG files
+;
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: EMpCallBin32.asm
+;
+; Description:
+;
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+.686
+.model flat
+.code
+ INCLUDE token.equ
+
+;Global variable for MpLoc
+ public MpLoc
+ MpLoc label dword
+ FWORD ?
+
+TPMTransmitEntryStruct STRUC
+ pbInBuf DD ? ;[IN] Pointer to input data for the data transfers to TPM
+ dwInLen DD ? ; [IN] Length of the input data record
+ pbOutBuf DD 0 ; [OUT] Pointer to output buffer for the data from the TPM
+ dwOutLen DD 0 ; [IN/OUT] DWORD to store the length info of the
+ ; output data record.
+TPMTransmitEntryStruct ENDS
+
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: Prepare2Thunkproc
+;
+; Description:
+; Function to setup location of Mp Driver as a local variable
+;
+; Input:
+; ecx - Location of MP Driver
+; dx - Segment for MP Driver
+;
+; Output:
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+_Prepare2Thunkproc proc
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ecx, dword ptr [ebp + 08h]
+ mov edx, dword ptr [ebp + 0ch]
+ mov dword ptr [MpLoc],ecx
+ mov word ptr [MpLoc + 4], dx
+ popa
+ pop ebp
+ ret
+_Prepare2Thunkproc ENDP
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgDxeCallMPDriver (TCM_support eq 0)
+;
+; Description:
+; Makes a function call into MP Driver
+;
+; Input:
+; rcx - Call type: 4-Buffer Transmission call
+; rsi - Buffer to be tansmitted
+;
+; Output:
+; rax - TCG return code
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+_TpmDxeCallMPDriver proc
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ecx, dword ptr [ebp + 08h]
+ cmp ecx, 04h
+ jnz Empty_Buff
+ mov esi, dword ptr [ebp + 0ch]
+Empty_Buff:
+ mov eax, ecx
+ call fword ptr [MpLoc]
+IF MKF_Stack_Work_Around
+ pop ebp ;balance the stack after call
+ENDIF
+ popa
+ pop ebp
+ ret
+_TpmDxeCallMPDriver ENDP
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgDxeCallMPDriver (TCM_support eq 1)
+;
+; Description:
+; Makes a function call into MP Driver
+;
+; Input:
+; rcx - Call type: 4-Buffer Transmission call
+; rsi - Buffer to be tansmitted
+;
+; Output:
+; rax - TCG return code
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+_TcmDxeCallMPDriver proc
+ push ebp
+ mov ebp, esp
+ pusha
+ mov ecx, dword ptr [ebp + 08h]
+ cmp ecx, 04h
+ jnz Empty_Buff
+ mov esi, dword ptr [ebp + 0ch]
+Empty_Buff:
+ mov eax, ecx
+ call fword ptr [MpLoc]
+ popa
+ pop ebp
+ ret
+_TcmDxeCallMPDriver ENDP
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgThunk32
+;
+; Description:
+; Go to compatibility mode for MP driver
+;
+; Input:
+;
+; Output:
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+_TcgThunk32 proc
+_TcgThunk32 ENDP
+
+
+
+
+
+;<AMI_PHDR_START>
+;-----------------------------------------------------------------------------
+;
+; Procedure: TcgThunkSwitchback
+;
+; Description:
+; Switch back to 64bit mode
+;
+; Input:
+;
+; Output:
+;
+; Modified:
+;
+; Referrals:
+;
+; Notes:
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+_TcgThunkSwitchback proc
+_TcgThunkSwitchback ENDP
+END
diff --git a/Core/EM/TCG2/Common/EMpTcmDxe.c b/Core/EM/TCG2/Common/EMpTcmDxe.c
new file mode 100644
index 0000000..c06b7d2
--- /dev/null
+++ b/Core/EM/TCG2/Common/EMpTcmDxe.c
@@ -0,0 +1,482 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/EMpTcmDxe.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/EMpTcmDxe.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 2 3/11/14 6:39p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 4 5/09/12 6:40p Fredericko
+// Changes to streamline Tcm driver. Also fixes possible Tcm hang issues
+// during reboot cycles.
+//
+// 3 4/01/11 11:14a Fredericko
+//
+// 2 3/29/11 1:16p Fredericko
+//
+// 1 3/28/11 2:23p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 11 5/20/10 12:02p Fredericko
+// variable name change
+//
+// 7 3/25/10 7:18p Fredericko
+// changes for clearing of PPI variables on legacy or TCM support.
+//
+// 6 3/23/10 9:21p Fredericko
+//
+// 5 3/23/10 6:59p Fredericko
+// Changes for optimization issues with compiler.
+//
+// 4 3/19/10 4:29p Fredericko
+// Modified for legacy IO interface support
+//
+// 3 6/02/09 2:38p Fredericko
+//
+// 2 6/02/09 1:12p Fredericko
+//
+// 1 5/18/09 6:06p Fredericko
+// Initial check-in for EMpTpmDxe.c for CTPM support infrastructure.
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EMpTpmDxe.c
+//
+// Description:
+// Contains function that help with making legacy TCG calls
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TcgTpm12.h"
+#include <TpmLib.h>
+#include "Protocol\TpmDevice\TpmDevice.h"
+#include <AmiDxeLib.h>
+#include "TcgMisc.h"
+#include "token.h"
+#include "Efi.h"
+
+#define _CR( Record, TYPE,\
+ Field )((TYPE*) ((CHAR8*) (Record)- (CHAR8*) &(((TYPE*) 0)->Field)))
+
+#define TPM_DXE_PRIVATE_DATA_FROM_THIS( this )\
+ _CR( this, TPM_DXE_PRIVATE_DATA, TpmInterface )
+
+typedef struct _TPM_DXE_PRIVATE_DATA
+{
+ EFI_TPM_DEVICE_PROTOCOL TpmInterface;
+} TPM_DXE_PRIVATE_DATA;
+
+static UINTN FuncID;
+static TPMTransmitEntryStruct EmptyBuf;
+static UINT32 Ret;
+UINT8 *SHA_ARRAY;
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: EMpTcmDxeInit
+//
+// Description: Call to OEM driver to initialize TPM.
+//
+// Input: IN EFI_TPM_DEVICE_PROTOCOL *This
+//
+// Returns: EFI_STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmDxeInit(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ TPM_DXE_PRIVATE_DATA *Private;
+ EFI_PHYSICAL_ADDRESS TPM_Base = (EFI_PHYSICAL_ADDRESS)PORT_TPM_IOMEMBASE;
+
+ FuncID = MA_FUNCTION_INIT;
+ Private = TPM_DXE_PRIVATE_DATA_FROM_THIS( This );
+ TcmDxeCallMPDriver( FuncID, &EmptyBuf, &Ret );
+
+ if ( !Ret )
+ {
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: EMpTcmDxeClose
+//
+// Description: Close TPM connection for locality 0
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+///
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmDxeClose(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ TPM_DXE_PRIVATE_DATA *Private;
+
+ FuncID = MP_FUNCTION_CLOSE;
+ Private = TPM_DXE_PRIVATE_DATA_FROM_THIS( This );
+ TcmDxeCallMPDriver( FuncID, &EmptyBuf, &Ret );
+
+ if ( !Ret )
+ {
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+//
+// Name: EMpTcmDxeGetStatusInfo
+//
+// Description: GetStatus Info from MP driver
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmDxeGetStatusInfo(
+ IN EFI_TPM_DEVICE_PROTOCOL * This
+ )
+{
+ TPM_DXE_PRIVATE_DATA *Private;
+
+ FuncID = MP_FUNCTION_GET_STATUS;
+ Private = TPM_DXE_PRIVATE_DATA_FROM_THIS( This );
+ TcmDxeCallMPDriver( FuncID, &EmptyBuf, &Ret );
+
+ if ( !Ret )
+ {
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+//
+// Name: EMpTcmDxeGetStatusInfo
+//
+// Description: GetStatus Info from MP driver
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN
+EFIAPI EMpTcmDxeSHA1Setup (
+IN EFI_TPM_DEVICE_PROTOCOL *This,
+IN UINTN NoInBuffers,
+IN TPM_TRANSMIT_BUFFER *InBuffers,
+IN OUT void **Buffer
+)
+{
+
+ TPM_1_2_CMD_HEADER *SHA1HeaderCheck;
+
+ SHA1HeaderCheck = (TPM_1_2_CMD_HEADER*)InBuffers->Buffer;
+
+ if ( SHA1HeaderCheck->Ordinal !=TPM_H2NL(TCM_ORD_SHA1CompleteExtend ) &&
+ SHA1HeaderCheck->Ordinal !=TPM_H2NL( TCM_ORD_SHA1Update ))
+ {
+ //no need to modify buffers just pass it through
+ return FALSE;
+ }
+
+ //if we get here it means the buffer needs to be modified!
+ pBS->AllocatePool( EfiBootservicesData,
+ InBuffers[0].Size + InBuffers[1].Size,
+ &SHA_ARRAY );
+
+ pBS->CopyMem( &SHA_ARRAY[0],
+ InBuffers[0].Buffer,
+ InBuffers[0].Size );
+
+ pBS->CopyMem( &SHA_ARRAY[InBuffers[0].Size],
+ InBuffers[1].Buffer,
+ InBuffers[1].Size );
+ *Buffer = SHA_ARRAY;
+ return TRUE;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+//
+// Name: EMpTcmDxeTransmit
+//
+// Description: Dxe Transmit Tcg Data
+//
+// Input: IN EFI_TPM_DEVICE_PROTOCOL *This,
+// IN UINTN NoInBuffers,
+// IN TPM_TRANSMIT_BUFFER *InBuffers,
+// IN UINTN NoOutBuffers,
+// IN OUT TPM_TRANSMIT_BUFFER *OutBuffers
+//
+// Output: EFI STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+EFIAPI EMpTcmDxeTransmit(
+ IN EFI_TPM_DEVICE_PROTOCOL *This,
+ IN UINTN NoInBuffers,
+ IN TPM_TRANSMIT_BUFFER *InBuffers,
+ IN UINTN NoOutBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutBuffers )
+{
+ TPM_DXE_PRIVATE_DATA *Private;
+ TPMTransmitEntryStruct FillESI;
+ UINTN FuncID = (UINTN)MP_FUNCTION_TRANSMIT;
+ UINT32 Ret;
+ UINT8 *SHA_ARRAY_OUT = NULL;
+ BOOLEAN FillBuff = FALSE;
+ BOOLEAN Other = FALSE;
+ UINTN i = 0, loc = 0;
+ UINT8 *Tpm_SHA_ARRAY= NULL;
+ EFI_STATUS Status;
+
+
+ if(NoInBuffers == 0 || InBuffers == NULL || NoOutBuffers == 0 || OutBuffers == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ FillESI.dwInLen = 0;
+ FillESI.dwOutLen = 0;
+
+ for (; i < NoInBuffers; i++ )
+ {
+ FillESI.dwInLen += (UINT32)InBuffers[i].Size;
+ }
+
+ Status = pBS-> AllocatePool( EfiBootservicesData, FillESI.dwInLen, &Tpm_SHA_ARRAY);
+ if(EFI_ERROR(Status))return Status;
+
+ for (i = 0; i < NoOutBuffers; i++ )
+ {
+ FillESI.dwOutLen += (UINT32)OutBuffers[i].Size;
+ }
+
+ Status = pBS-> AllocatePool( EfiBootservicesData, FillESI.dwOutLen, &SHA_ARRAY_OUT );
+ if(EFI_ERROR(Status))return Status;
+
+
+ for (i = 0; i < NoInBuffers; i++ )
+ {
+ pBS->CopyMem(Tpm_SHA_ARRAY + loc,
+ InBuffers[i].Buffer,
+ InBuffers[i].Size );
+
+ loc += InBuffers[i].Size;
+ }
+
+ FillESI.pbInBuf = (UINT32)(EFI_PHYSICAL_ADDRESS) Tpm_SHA_ARRAY;
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS) SHA_ARRAY_OUT;
+
+ Private = TPM_DXE_PRIVATE_DATA_FROM_THIS( This );
+ TcmDxeCallMPDriver( FuncID, &FillESI, &Ret );
+
+ if ( Tpm_SHA_ARRAY != NULL )
+ {
+ pBS->FreePool( Tpm_SHA_ARRAY );
+ }
+
+ loc = 0;
+
+ for (i=0; i < NoOutBuffers; i++ )
+ {
+ pBS->CopyMem( OutBuffers[i].Buffer,
+ &SHA_ARRAY_OUT[loc],
+ OutBuffers[i].Size );
+ loc += (UINTN)OutBuffers[i].Size;
+ }
+
+ if ( SHA_ARRAY_OUT != NULL )
+ {
+ pBS->FreePool( SHA_ARRAY_OUT );
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+static TPM_DXE_PRIVATE_DATA mTpmPrivate = {
+ {
+ EMpTcmDxeInit,
+ EMpTcmDxeClose,
+ EMpTcmDxeGetStatusInfo,
+ EMpTcmDxeTransmit
+ }
+};
+
+
+EFI_GUID legTcgGuid = AMI_TCG_RESETVAR_HOB_GUID;
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+//
+// Name: TcmDxeEntry
+//
+// Description: TpmDxeEntry, Init TpmDxeDriver and install protocol
+//
+// Input: EFI_HANDLE ImageHandle
+// EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+EFIAPI TcmDxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TPM_Base = (EFI_PHYSICAL_ADDRESS)PORT_TPM_IOMEMBASE;
+ FAR32LOCALS *TempLoc = NULL;
+ EFI_GUID gMpDriverHobGuid = EFI_TCG_MPDriver_HOB_GUID;
+
+ TempLoc = (FAR32LOCALS*)LocateATcgHob( pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gMpDriverHobGuid );
+
+
+ if(TempLoc->Offset == 0) return EFI_NOT_FOUND;
+
+ Prepare2Thunkproc( TempLoc->Offset, TempLoc->Selector );
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiTpmDeviceProtocolGuid,
+ &mTpmPrivate.TpmInterface,
+ NULL
+ );
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/EMpTcmPei.c b/Core/EM/TCG2/Common/EMpTcmPei.c
new file mode 100644
index 0000000..480aa61
--- /dev/null
+++ b/Core/EM/TCG2/Common/EMpTcmPei.c
@@ -0,0 +1,691 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/EMpTcmPei.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/EMpTcmPei.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 8 5/09/12 6:13p Fredericko
+// Changes to streamline Tcm driver. Also fixes possible Tcm hang issues
+// during reboot cycles.
+//
+// 7 12/12/11 3:19p Fredericko
+// [TAG] EIP76865
+// [Category] Improvement
+// [Description] Dual Support for TCM and TPM. System could hang in TXT
+// if txt is enabled in setup
+// [Files] AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif,
+// AmiTcgPlatformPpi.h, AmiTcgPlatformProtocol.cif,
+// AmiTcgPlatformProtocol.h,
+// EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+// TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+// xTcgPeiAfterMem.c
+//
+// 6 4/18/11 2:26p Fredericko
+//
+// 5 4/14/11 6:17p Fredericko
+// Disable optimization for asm related changes.
+//
+// 4 4/06/11 12:23p Fredericko
+//
+// 3 4/01/11 9:33a Fredericko
+// Updated function Header
+//
+// 2 3/29/11 12:58p Fredericko
+//
+// 1 3/28/11 2:14p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 8 5/19/10 5:54p Fredericko
+// Updated AMI copyright header
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+// 7 4/08/10 6:45p Fredericko
+// removed Verify_TCG_VARIABLES, now called in xtcgpei.c
+//
+// 6 3/26/10 12:51a Fredericko
+//
+// 5 3/19/10 5:14p Fredericko
+// modified for legacy IO interface support
+//
+// 4 6/02/09 1:16p Fredericko
+//
+// 3 6/01/09 4:29p Fredericko
+//
+// 2 5/18/09 5:50p Fredericko
+//
+// 1. Initial check-in for EMpTpmPei.c for CTPM support infrastructure.
+//**********************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EMpTpmPei.c
+//
+// Description:
+// Handles legacy calls into 32bit Binaries
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include <Pei.h>
+#include <TcgTpm12.h>
+#include <TpmLib.h>
+#include <AmiPeiLib.h>
+#include "TcgMisc.h"
+#include "token.h"
+#include "TcgCommon.h"
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+
+
+#define _CR( Record, TYPE,\
+ Field )((TYPE*) ((CHAR8*) (Record)- (CHAR8*) &(((TYPE*) 0)->Field)))
+
+#define TPM_PEI_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TPM_PEI_PRIVATE_DATA, TpmPpi )
+
+typedef struct _TPM_PEI_PRIVATE_DATA
+{
+ PEI_TPM_PPI TpmPpi;
+} TPM_PEI_PRIVATE_DATA;
+
+EFI_GUID gTcmCallbackguid = AMI_TCM_CALLBACK_GUID;
+EFI_GUID guid = EFI_TCG_MPDriver_HOB_GUID;
+
+typedef struct _TCM_PEI_CALLBACK
+{
+ EFI_PEI_NOTIFY_DESCRIPTOR NotifyDesc;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+
+} TCM_PEI_CALLBACK;
+
+
+VOID TcmPeiCallMPDriver (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CFuncID,
+ TPMTransmitEntryStruct *CData,
+ UINT32* OUT CRetVal );
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTcmPeiInit
+//
+// Description: Call to OEM driver to initialize TCM
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmPeiInit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI EMpTcmPeiInit2(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTcmPeiClose
+//
+// Description: Call to OEM driver to Close TCM
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmPeiClose(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI EMpTcmPeiClose2(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTcmPeiGetStatusInfo
+//
+// Description: Function call to get status infomation
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI_UNSUPPORTED
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmPeiGetStatusInfo(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTcmPeiSHA1Setup
+//
+// Description: Helper function to help with Command transmission to TCM
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+// IN UINTN NoInputBuffers
+// IN TPM_TRANSMIT_BUFFER *InputBuffers
+// IN OUT void **Buffer
+// IN UINT8 *SHA_ARRAY
+//
+// Output: BOOLEAN
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN
+EFIAPI EMpTcmPeiSHA1Setup(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN OUT void **Buffer,
+ IN UINT8 *SHA_ARRAY )
+{
+ TPM_1_2_CMD_HEADER *SHA1HeaderCheck;
+ void *Context = NULL;
+
+
+ //check if this an SHA1 update or Complete call and set the buffer
+ //else no need to update the buffer is the same
+ SHA1HeaderCheck = (TPM_1_2_CMD_HEADER*)InputBuffers->Buffer;
+
+ if ( SHA1HeaderCheck->Ordinal !=
+ TPM_H2NL(
+ TCM_ORD_SHA1CompleteExtend ) && SHA1HeaderCheck->Ordinal !=
+ TPM_H2NL( TCM_ORD_SHA1Update ))
+ {
+ //no need to modify buffers just pass it through
+ return FALSE;
+ }
+
+
+ TcgCommonCopyMem( Context,
+ SHA_ARRAY,
+ InputBuffers[0].Buffer,
+ InputBuffers[0].Size );
+
+ TcgCommonCopyMem( Context,
+ &SHA_ARRAY[InputBuffers[0].Size],
+ InputBuffers[1].Buffer,
+
+ InputBuffers[1].Size );
+
+ *Buffer = SHA_ARRAY;
+ return TRUE;
+}
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTcmPeiTransmit
+//
+// Description: TCM Transmit function
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices,
+// IN UINTN NoInputBuffers,
+// IN TPM_TRANSMIT_BUFFER *InputBuffers,
+// IN UINTN NoOutputBuffers,
+// IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EMpTcmPeiTransmit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ TPM_PEI_PRIVATE_DATA *Private;
+ TPMTransmitEntryStruct FillESI;
+ UINT8 FuncID = MP_FUNCTION_TRANSMIT;
+ UINT32 Ret;
+ void *buffer;
+ UINT8 SHA_ARRAY[INTERNAL_SHA_ARRAY_LENGTH];
+ UINT8 SHA_ARRAY_OUT[INTERNAL_SHA_ARRAY_LENGTH];
+ BOOLEAN FillBuff = FALSE;
+ TPM_1_2_CMD_HEADER *SHA1HeaderCheck;
+ void *Context = NULL;
+ UINT8 i = 0;
+ UINT8 loc = 0;
+
+ if ( !EMpTcmPeiSHA1Setup( This, PeiServices, NoInputBuffers, InputBuffers,
+ &buffer, SHA_ARRAY ))
+ {
+ FillESI.pbInBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)InputBuffers->Buffer;
+ FillESI.dwInLen = (UINT32)InputBuffers->Size;
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)OutputBuffers->Buffer;
+ FillESI.dwOutLen = (UINT32)OutputBuffers->Size;
+ }
+ else {
+ FillESI.pbInBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)SHA_ARRAY;
+ FillESI.dwInLen = 0;
+
+ for (; i < NoInputBuffers; i++ )
+ {
+ FillESI.dwInLen += (UINT32)InputBuffers[i].Size;
+ }
+
+ SHA1HeaderCheck = (TPM_1_2_CMD_HEADER*)InputBuffers->Buffer;
+
+ if ( SHA1HeaderCheck->Ordinal == TPM_H2NL( TCM_ORD_SHA1CompleteExtend ))
+ {
+ FillBuff = TRUE;
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)SHA_ARRAY_OUT;
+ FillESI.dwOutLen = (OutputBuffers[0].Size + OutputBuffers[1].Size
+ + OutputBuffers[2].Size);
+ }
+
+ if ( !FillBuff )
+ {
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)OutputBuffers->Buffer;
+ FillESI.dwOutLen = (UINT32)OutputBuffers->Size;
+ }
+ }
+
+ Private = TPM_PEI_PRIVATE_DATA_FROM_THIS( This );
+ TcmPeiCallMPDriver( PeiServices, FuncID, &FillESI, &Ret );
+
+ if ( FillBuff ) //setup output buffer for the interface
+ {
+ i = 0;
+ for (; i < NoOutputBuffers; i++ )
+ {
+ TcgCommonCopyMem( Context,
+ OutputBuffers[i].Buffer,
+ &SHA_ARRAY_OUT[loc],
+ OutputBuffers[i].Size );
+
+ loc += OutputBuffers[i].Size;
+ }
+
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI EMpTcmPeiTransmit2(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ return EFI_NOT_AVAILABLE_YET;
+}
+
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmPeiCallMPDriver
+//
+// Description: Interface to performing MP driver function calls in PEI
+// Uses _ASM directives. Return Value in EAX return as status
+//
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// IN UINT8 CFuncID,
+// IN TPMTransmitEntryStruct * CData,
+// OUT UINT32* CRetVal
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID TcmPeiCallMPDriver(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CFuncID,
+ TPMTransmitEntryStruct * CData,
+ UINT32* OUT CRetVal )
+{
+ UINT32 ReturnVal;
+ FAR32LOCALS CommonLegX;
+ EFI_GUID guidMA = EFI_TCG_MADriver_HOB_GUID;
+ EFI_GUID guidMP = EFI_TCG_MPDriver_HOB_GUID;
+ TPMTransmitEntryStruct IntCData = *CData;
+ UINT32 Address = (UINT32)&IntCData;
+ FAR32LOCALS InternalMPLoc;
+
+
+ FillDriverLoc( &InternalMPLoc.Offset, PeiServices, &guid );
+
+ CommonLegX.Offset = 0;
+ CommonLegX.Selector = 0;
+ CommonLegX.Offset = InternalMPLoc.Offset;
+ CommonLegX.Selector = SEL_flatCS;
+
+ _asm {
+ xor eax, eax
+ mov al, [CFuncID]
+ cmp eax, MP_FUNCTION_TRANSMIT
+ jnz Empty_Buff
+ mov ESI, Address
+Empty_Buff:
+ call fword ptr [CommonLegX];
+ mov ReturnVal, eax
+ }
+ *CRetVal = ReturnVal;
+}
+
+
+static TPM_PEI_PRIVATE_DATA mTcmPrivate = {
+ {
+ EMpTcmPeiInit,
+ EMpTcmPeiClose,
+ EMpTcmPeiGetStatusInfo,
+ EMpTcmPeiTransmit
+ }
+};
+
+static TPM_PEI_PRIVATE_DATA mTcmPrivate2 = {
+ {
+ EMpTcmPeiInit2,
+ EMpTcmPeiClose2,
+ EMpTcmPeiGetStatusInfo,
+ EMpTcmPeiTransmit2
+ }
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmPpiGuid,
+ &mTcmPrivate.TpmPpi
+ }
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList2[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmPpiGuid,
+ &mTcmPrivate2.TpmPpi
+ }
+};
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitTcmEntry
+//
+// Description: Entry point for TCM ppi initialization after memory is installed
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI InitTcmEntry(
+IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi)
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TPM_Base = (EFI_PHYSICAL_ADDRESS)PORT_TPM_IOMEMBASE;
+ FAR32LOCALS InternalMPLoc;
+ EFI_PEI_PPI_DESCRIPTOR *PpiDesc;
+ PEI_TCG_PPI *TcmPpi;
+
+ Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_Base );
+ if(EFI_ERROR(Status))
+ {
+ return Status;
+ }
+
+ FillDriverLoc( &InternalMPLoc.Offset, PeiServices, &guid );
+ if ( InternalMPLoc.Offset == 0 )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiTpmPpiGuid,
+ 0,
+ &PpiDesc,
+ &TcmPpi);
+ if(EFI_ERROR(Status))
+ {
+ return Status;
+ }
+
+
+ Status = (*PeiServices)->ReInstallPpi( PeiServices, PpiDesc, &mPpiList[0] );
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_UNLOAD_IMAGE;
+ }
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiTpmPpiGuid,
+ 0,
+ &PpiDesc,
+ &TcmPpi );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_UNLOAD_IMAGE;
+ }
+
+ return Status;
+}
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmPeiEntry
+//
+// Description: Entry for TcmPei Device when TCM_Support is enabled
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcmPeiEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ TCM_PEI_CALLBACK *TcmCallback;
+
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof (TCM_PEI_CALLBACK),
+ &TcmCallback);
+
+ if ( !EFI_ERROR( Status ))
+ {
+ TcmCallback->NotifyDesc.Flags
+ = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ TcmCallback->NotifyDesc.Guid = &gTcmCallbackguid;
+ TcmCallback->NotifyDesc.Notify = InitTcmEntry;
+ TcmCallback->FfsHeader = FfsHeader;
+
+ Status = (*PeiServices)->NotifyPpi( PeiServices,
+ &TcmCallback->NotifyDesc );
+ }
+
+ Status = (*PeiServices)->InstallPpi( PeiServices, &mPpiList2[0] );
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_UNLOAD_IMAGE;
+ }
+
+ return Status;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/PPI/TcgService/TcgService.c b/Core/EM/TCG2/Common/PPI/TcgService/TcgService.c
new file mode 100644
index 0000000..906d671
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TcgService/TcgService.c
@@ -0,0 +1,64 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ GUID definition for PEI_TCG_PPI
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgService.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgService.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 5/19/10 6:48p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.c
+//
+// Description:
+// Defines TcgPpiguid
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <Efi.h>
+#include <Pei.h>
+#include <Tpm12.h>
+
+#include EFI_PPI_DEFINITION( TcgService )
+
+EFI_GUID gPeiTcgPpiGuid = PEI_TCG_PPI_GUID;
+
+EFI_GUID_STRING( &gPeiTcgPpiGuid, "TcgService", "TCG Services PPI" );
diff --git a/Core/EM/TCG2/Common/PPI/TcgService/TcgService.h b/Core/EM/TCG2/Common/PPI/TcgService/TcgService.h
new file mode 100644
index 0000000..c621600
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TcgService/TcgService.h
@@ -0,0 +1,122 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ TCG Service PPI
+
+ Only minimum subset of features is contained in this PPI definition
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgService.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgService.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 6 3/29/11 2:59p Fredericko
+//
+// 5 3/28/11 3:14p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 4 5/19/10 6:49p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.h
+//
+// Description:
+// Header file for TcgService.c
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#ifndef _TCG_SERVICE_H_
+#define _TCG_SERVICE_H_
+
+#include <TcgEfiTpm.h>
+#include <TCGMisc.h>
+#include <token.h>
+
+struct _PEI_TCG_PPI;
+
+typedef struct _PEI_TCG_PPI PEI_TCG_PPI;
+
+
+#define PEI_TCG_PPI_GUID \
+ {0x177d39d2, 0x43b8, 0x40c8, 0x9a, 0xe1, 0x3c, 0x51, 0x98, 0xd6, 0x94, 0x1e}
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TCG_LOG_EVENT)(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCG_PCR_EVENT *Event,
+ OUT UINT32 *EventNum
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TCG_HASH_LOG_EXTEND_EVENT)(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN TCG_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TCG_PASS_THROUGH_TO_TPM)(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiSerivces,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock
+ );
+
+typedef struct _PEI_TCG_PPI
+{
+ PEI_TCG_HASH_LOG_EXTEND_EVENT TCGHashLogExtendEvent;
+ PEI_TCG_LOG_EVENT TCGLogEvent;
+ PEI_TCG_PASS_THROUGH_TO_TPM TCGPassThroughToTpm;
+} PEI_TCG_PPI;
+
+extern EFI_GUID gPeiTcgPpiGuid;
+
+#endif
diff --git a/Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.c b/Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.c
new file mode 100644
index 0000000..51c6f4a
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.c
@@ -0,0 +1,73 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ GUID definition for PEI_TCG_PPI
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgTcmService.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgTcmService.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 3/29/11 3:00p Fredericko
+//
+// 1 3/28/11 3:16p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 2 5/19/10 6:48p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.c
+//
+// Description:
+// Defines TcgPpiguid
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <Efi.h>
+#include <Pei.h>
+#include <Tpm12.h>
+
+#include EFI_PPI_DEFINITION( TcgTcmService )
+
+EFI_GUID gPeiTcmPpiGuid = PEI_TCG_PPI_GUID;
+
+EFI_GUID_STRING( &gPeiTcgPpiGuid, "TcgTcmService", "TCM Services PPI" );
diff --git a/Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.h b/Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.h
new file mode 100644
index 0000000..3f6c973
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TcgService/TcgTcmService.h
@@ -0,0 +1,181 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ TCG Service PPI
+
+ Only minimum subset of features is contained in this PPI definition
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgTcmService.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgTcmService.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 9/29/11 6:08p Davidd
+// [TAG] EIP71378
+// [Category] Improvement
+// [Description] Customer names in source files
+// [Files] TcgTcmService.h
+//
+// 2 3/29/11 3:00p Fredericko
+//
+// 1 3/28/11 3:15p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 4 5/19/10 6:49p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+/*
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ TCM Service PPI
+
+ Only minimum subset of features is contained in this PPI definition
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgTcmService.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_PPI/TcgService/TcgTcmService.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 9/29/11 6:08p Davidd
+// [TAG] EIP71378
+// [Category] Improvement
+// [Description] Customer names in source files
+// [Files] TcgTcmService.h
+//
+// 2 3/29/11 3:00p Fredericko
+//
+// 1 3/28/11 3:15p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG file override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 4 5/19/10 6:49p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TCMService.h
+//
+// Description:
+// Header file for TCMService.c
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCG_TCM_SERVICE_H_
+#define _TCG_TCM_SERVICE_H_
+
+#include <TcgEfiTpm.h>
+#include <TcgMisc.h>
+#include <token.h>
+
+struct _PEI_TCM_PPI;
+typedef struct _PEI_TCM_PPI PEI_TCM_PPI;
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TCM_LOG_EVENT)(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCM_PCR_EVENT *Event,
+ OUT UINT32 *EventNum );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TCM_HASH_LOG_EXTEND_EVENT)(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN TCM_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TCM_PASS_THROUGH_TO_TCM)(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiSerivces,
+ IN UINT32 TcmInputParameterBlockSize,
+ IN UINT8 *TcmInputParameterBlock,
+ IN UINT32 TcmOutputParameterBlockSize,
+ IN UINT8 *TcmOutputParameterBlock
+ );
+
+typedef struct _PEI_TCM_PPI
+{
+ PEI_TCM_HASH_LOG_EXTEND_EVENT TCMHashLogExtendEvent;
+ PEI_TCM_LOG_EVENT TCMLogEvent;
+ PEI_TCM_PASS_THROUGH_TO_TCM TCMPassThroughToTcm;
+} PEI_TCM_PPI;
+
+extern EFI_GUID gPeiTCMPpiGuid;
+
+#endif \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/PPI/TcgService_PPI.cif b/Core/EM/TCG2/Common/PPI/TcgService_PPI.cif
new file mode 100644
index 0000000..4138030
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TcgService_PPI.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "TcgService_PPI"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common\PPI\"
+ RefName = "TcgService_PPI"
+[files]
+"TcgService\TcgService.c"
+"TcgService\TcgService.h"
+"TcgService\TcgTcmService.h"
+"TcgService\TcgTcmService.c"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.c b/Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.c
new file mode 100644
index 0000000..f370d4c
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.c
@@ -0,0 +1,97 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ TPM Service PPI GUID as defined in EFI 2.0
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_PPI/TpmDevice/TpmDevice.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_PPI/TpmDevice/TpmDevice.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:59p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 3/31/13 6:42p Fredericko
+// [TAG] EIP113715
+// [Category] Improvement
+// [Description] Please update the copyright header according to AMI
+// copyright rule
+// [Files] Multiple Files
+//
+// 2 5/20/10 8:45a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmDevice.c
+//
+// Description:
+// Defines Tpm Device Ppis' GUID
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "Efi.h"
+#include "Pei.h"
+
+#include EFI_PPI_DEFINITION( TpmDevice )
+
+EFI_GUID gPeiTpmPpiGuid = PEI_TPM_PPI_GUID;
+
+EFI_GUID_STRING( &gPeiTpmPpiGuid, "Tpm PPI", "Tpm 1.2 Device PPI" );
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.h b/Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.h
new file mode 100644
index 0000000..08b4b43
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TpmDevice/TpmDevice.h
@@ -0,0 +1,179 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+ Abstract:
+
+ TPM PPI as defined in EFI 2.0
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_PPI/TpmDevice/TpmDevice.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_PPI/TpmDevice/TpmDevice.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:01p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:59p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 8 3/31/13 6:42p Fredericko
+// [TAG] EIP113715
+// [Category] Improvement
+// [Description] Please update the copyright header according to AMI
+// copyright rule
+// [Files] Multiple Files
+//
+// 7 3/29/11 3:09p Fredericko
+//
+// 6 3/28/11 3:25p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 5 5/20/10 8:45a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmDevice.h
+//
+// Description:
+// Header file for TpmDevice.c[Ppi]
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _PEI_TPMDEVICE_H_
+#define _PEI_TPMDEVICE_H_
+
+#include <TcgEfiTpm.h>
+#include <TcgEfi12.h>
+
+#define PEI_TPM_PPI_GUID \
+ {0xca4853f4, 0xe94b, 0x42b4, 0x86, 0x42, 0xcd, 0xe2, 0x8a, 0x7f, 0xac, 0x2d}
+
+#define TPM_DEACTIVATED_VARIABLE_NAME \
+ L"IsTpmDeactivated"
+
+struct _PEI_TPM_PPI;
+typedef struct _PEI_TPM_PPI PEI_TPM_PPI;
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TPM_INIT)(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TPM_CLOSE)(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TPM_GET_STATUS_INFO)(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+
+VOID FillDriverLoc (
+ UINT32 * Offset,
+ EFI_PEI_SERVICES **ps,
+ EFI_GUID *Driveguid );
+
+VOID MAFillDriverLoc (
+ MASTRUCT *Data,
+ EFI_PEI_SERVICES **ps,
+ EFI_GUID *Driveguid );
+
+EFI_STATUS FillDriverLocByFile (
+ UINT32 * Offset,
+ EFI_PEI_SERVICES **ps,
+ EFI_GUID *Driveguid,
+ void **MAStart,
+ UINTN *MASize );
+
+
+EFI_STATUS
+EFIAPI TpmPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+
+typedef
+EFI_STATUS
+(EFIAPI * PEI_TPM_TRANSMIT)(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers
+ );
+
+typedef struct _PEI_TPM_PPI
+{
+ PEI_TPM_INIT Init;
+ PEI_TPM_CLOSE Close;
+ PEI_TPM_GET_STATUS_INFO GetStatusInfo;
+ PEI_TPM_TRANSMIT Transmit;
+} PEI_TPM_PPI;
+
+extern EFI_GUID gPeiTpmPpiGuid;
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/PPI/TpmDevice_PPI.cif b/Core/EM/TCG2/Common/PPI/TpmDevice_PPI.cif
new file mode 100644
index 0000000..57a9c16
--- /dev/null
+++ b/Core/EM/TCG2/Common/PPI/TpmDevice_PPI.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "TpmDevice_PPI"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common\PPI\"
+ RefName = "TpmDevice_PPI"
+[files]
+"TpmDevice\TpmDevice.c"
+"TpmDevice\TpmDevice.h"
+<endComponent> \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/Protocol/TcgService/TcgService.c b/Core/EM/TCG2/Common/Protocol/TcgService/TcgService.c
new file mode 100644
index 0000000..afa983b
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TcgService/TcgService.c
@@ -0,0 +1,66 @@
+/*++
+
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+ Abstract:
+
+ TcgService Protocol GUID as defined in TCG_EFI_Protocol_1_20_Final
+
+ See http://trustedcomputinggroup.org for the latest specification
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgService.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgService.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 5/20/10 8:44a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.c
+//
+// Description:
+// Defines Tcg Protocol guid
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <Tiano.h>
+
+#include EFI_PROTOCOL_DEFINITION( TcgService )
+
+EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+
+EFI_GUID_STRING( &gEfiTcgServiceProtocolGuid,
+ "TcgService",
+ "TCG Services Protocol" );
diff --git a/Core/EM/TCG2/Common/Protocol/TcgService/TcgService.h b/Core/EM/TCG2/Common/Protocol/TcgService/TcgService.h
new file mode 100644
index 0000000..f6f3960
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TcgService/TcgService.h
@@ -0,0 +1,171 @@
+/*++
+
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Abstract:
+
+ TCG Service Protocol as defined in TCG_EFI_Protocol_1_20_Final
+
+ See http://trustedcomputinggroup.org for the latest specification
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgService.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgService.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 6 3/29/11 3:01p Fredericko
+//
+// 5 3/28/11 3:22p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 4 5/20/10 8:44a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.h
+//
+// Description:
+// Header file for TcgService.c [Protocol]
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCG_SERVICE_PROTOCOL_H_
+#define _TCG_SERVICE_PROTOCOL_H_
+
+#include "TcgEfiTpm.h"
+
+#define EFI_TCG_PROTOCOL_GUID \
+ {0xf541796d, 0xa62e, 0x4954, 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd}
+
+#define TSS_EVENT_DATA_MAX_SIZE 256
+
+EFI_FORWARD_DECLARATION( EFI_TCG_PROTOCOL );
+
+//
+// Set structure alignment to 1-byte
+//
+#pragma pack (push, 1)
+
+typedef struct
+{
+ UINT8 Major;
+ UINT8 Minor;
+ UINT8 RevMajor;
+ UINT8 RevMinor;
+} TCG_VERSION;
+
+typedef struct _TCG_EFI_BOOT_SERVICE_CAPABILITY
+{
+ UINT8 Size; // Size of this structure
+ TCG_VERSION StructureVersion;
+ TCG_VERSION ProtocolSpecVersion;
+ UINT8 HashAlgorithmBitmap; // Hash algorithms
+ // this protocol is capable of : 01=SHA-1
+ BOOLEAN TPMPresentFlag; // 00h = TPM not present
+ BOOLEAN TPMDeactivatedFlag; // 01h = TPM currently deactivated
+} TCG_EFI_BOOT_SERVICE_CAPABILITY;
+
+typedef UINT32 TCG_ALGORITHM_ID;
+//
+// Restore original structure alignment
+//
+#pragma pack (pop)
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCG_STATUS_CHECK)(
+ IN EFI_TCG_PROTOCOL *This,
+ OUT TCG_EFI_BOOT_SERVICE_CAPABILITY
+ *ProtocolCapability,
+ OUT UINT32 *TCGFeatureFlags,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCG_HASH_ALL)(
+ IN EFI_TCG_PROTOCOL *This,
+ IN UINT8 *HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT UINT64 *HashedDataLen,
+ IN OUT UINT8 **HashedDataResult
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCG_LOG_EVENT)(
+ IN EFI_TCG_PROTOCOL *This,
+ IN TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ IN UINT32 Flags
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCG_PASS_THROUGH_TO_TPM)(
+ IN EFI_TCG_PROTOCOL *This,
+ IN UINT32 TpmInputParamterBlockSize,
+ IN UINT8 *TpmInputParamterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCG_HASH_LOG_EXTEND_EVENT)(
+ IN EFI_TCG_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry
+ );
+
+typedef struct _EFI_TCG_PROTOCOL
+{
+ EFI_TCG_STATUS_CHECK StatusCheck;
+ EFI_TCG_HASH_ALL HashAll;
+ EFI_TCG_LOG_EVENT LogEvent;
+ EFI_TCG_PASS_THROUGH_TO_TPM PassThroughToTpm;
+ EFI_TCG_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
+} EFI_TCG_PROTOCOL;
+
+extern EFI_GUID gEfiTcgProtocolGuid;
+
+#endif
diff --git a/Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.c b/Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.c
new file mode 100644
index 0000000..fcf3611
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.c
@@ -0,0 +1,75 @@
+/*++
+
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+
+ Abstract:
+
+ TcgService Protocol GUID as defined in TCG_EFI_Protocol_1_20_Final
+
+ See http://trustedcomputinggroup.org for the latest specification
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgTcmService.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgTcmService.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 3/29/11 3:03p Fredericko
+//
+// 1 3/28/11 3:20p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 2 5/20/10 8:44a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.c
+//
+// Description:
+// Defines Tcg Protocol guid
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include <Tiano.h>
+
+#include EFI_PROTOCOL_DEFINITION( TcgTcmService )
+
+EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+
+EFI_GUID_STRING( &gEfiTcgServiceProtocolGuid,
+ "TcgTcmService",
+ "TCM Services Protocol" );
diff --git a/Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.h b/Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.h
new file mode 100644
index 0000000..829b40b
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TcgService/TcgTcmService.h
@@ -0,0 +1,167 @@
+/*++
+
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Abstract:
+
+ TCG Service Protocol as defined in TCG_EFI_Protocol_1_20_Final
+
+ See http://trustedcomputinggroup.org for the latest specification
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgTcmService.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgService_Protocol/TcgService/TcgTcmService.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 3/29/11 3:02p Fredericko
+//
+// 1 3/28/11 3:20p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 4 5/20/10 8:44a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgService.h
+//
+// Description:
+// Header file for TcgService.c [Protocol]
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCG_TCM_SERVICE_PROTOCOL_H_
+#define _TCG_TCM_SERVICE_PROTOCOL_H_
+
+#include "TcgEfiTpm.h"
+
+#define EFI_TCG_PROTOCOL_GUID \
+ {0xf541796d, 0xa62e, 0x4954, 0xa7, 0x75, 0x95, 0x84, 0xf6, 0x1b, 0x9c, 0xdd}
+
+#define TSS_EVENT_DATA_MAX_SIZE 256
+
+EFI_FORWARD_DECLARATION( EFI_TCM_PROTOCOL );
+// Set structure alignment to 1-byte
+//
+#pragma pack (push, 1)
+
+typedef struct
+{
+ UINT8 Major;
+ UINT8 Minor;
+ UINT8 RevMajor;
+ UINT8 RevMinor;
+} TCM_VERSION;
+
+typedef struct _TCM_EFI_BOOT_SERVICE_CAPABILITY
+{
+ UINT8 Size; // Size of this structure
+ TCM_VERSION StructureVersion;
+ TCM_VERSION ProtocolSpecVersion;
+ UINT8 HashAlgorithmBitmap; // Hash algorithms
+ // this protocol is capable of : 01=SHA-1
+ BOOLEAN TPMPresentFlag; // 00h = TPM not present
+ BOOLEAN TPMDeactivatedFlag; // 01h = TPM currently deactivated
+} TCM_EFI_BOOT_SERVICE_CAPABILITY;
+
+typedef UINT32 TCG_ALGORITHM_ID;
+
+#pragma pack (pop)
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCM_STATUS_CHECK)(
+ IN EFI_TCM_PROTOCOL *This,
+ OUT TCM_EFI_BOOT_SERVICE_CAPABILITY
+ *ProtocolCapability,
+ OUT UINT32 *TCGFeatureFlags,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCM_HASH_ALL)(
+ IN EFI_TCM_PROTOCOL *This,
+ IN UINT8 *HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT UINT64 *HashedDataLen,
+ IN OUT UINT8 **HashedDataResult
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCM_LOG_EVENT)(
+ IN EFI_TCM_PROTOCOL *This,
+ IN TCM_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ IN UINT32 Flags
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCM_PASS_THROUGH_TO_TPM)(
+ IN EFI_TCM_PROTOCOL *This,
+ IN UINT32 TpmInputParamterBlockSize,
+ IN UINT8 *TpmInputParamterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TCM_HASH_LOG_EXTEND_EVENT)(
+ IN EFI_TCM_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCM_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry
+ );
+
+typedef struct _EFI_TCM_PROTOCOL
+{
+ EFI_TCM_STATUS_CHECK StatusCheck;
+ EFI_TCM_HASH_ALL HashAll;
+ EFI_TCM_LOG_EVENT LogEvent;
+ EFI_TCM_PASS_THROUGH_TO_TPM PassThroughToTpm;
+ EFI_TCM_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
+} EFI_TCM_PROTOCOL;
+
+extern EFI_GUID gEfiTcgProtocolGuid;
+
+#endif
diff --git a/Core/EM/TCG2/Common/Protocol/TcgService_Protocol.cif b/Core/EM/TCG2/Common/Protocol/TcgService_Protocol.cif
new file mode 100644
index 0000000..a4e469a
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TcgService_Protocol.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "TcgService_Protocol"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common\Protocol\"
+ RefName = "TcgService_Protocol"
+[files]
+"TcgService\TcgService.c"
+"TcgService\TcgService.h"
+"TcgService\TcgTcmService.h"
+"TcgService\TcgTcmService.c"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.c b/Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.c
new file mode 100644
index 0000000..4251fb2
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.c
@@ -0,0 +1,60 @@
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_Protocol/TpmDevice/TpmDevice.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_Protocol/TpmDevice/TpmDevice.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:01p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:59p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 5/20/10 8:46a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmDevice.c
+//
+// Description:
+// Defines Tpm Device Protocol GUID
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "Efi.h"
+#include EFI_PROTOCOL_DEFINITION( TpmDevice )
+
+EFI_GUID gEfiTpmDeviceProtocolGuid = EFI_TPM_DEVICE_PROTOCOL_GUID;
+
+EFI_GUID_STRING( &gEfiTpmDeviceProtocolGuid,
+ "TPM DXE Driver Protocol",
+ "TPM DXE Driver Protocol" );
diff --git a/Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.h b/Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.h
new file mode 100644
index 0000000..9b9108f
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TpmDevice/TpmDevice.h
@@ -0,0 +1,197 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Abstract:
+
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_Protocol/TpmDevice/TpmDevice.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TpmDevice_Protocol/TpmDevice/TpmDevice.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:01p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:59p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 7 3/29/11 3:10p Fredericko
+//
+// 6 3/28/11 3:27p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 5 5/20/10 8:47a Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmDevice.h
+//
+// Description:
+// Header file for TpmDevice.c[Protocol]
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _EFI_TPM_DEVICE_H_
+#define _EFI_TPM_DEVICE_H_
+
+#include "TcgEfiTpm.h"
+#include "TcgEFI12.h"
+#include "TCGMisc.h"
+#include "TcgCommon.h"
+
+#define EFI_TPM_DEVICE_PROTOCOL_GUID \
+ { 0xde161cfe, 0x1e60, 0x42a1, 0x8c, 0xc3, 0xee, 0x7e, 0xf0, 0x73, 0x52,\
+ 0x12 }
+
+
+EFI_FORWARD_DECLARATION( EFI_TPM_DEVICE_PROTOCOL );
+
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TPM_MP_INIT)(
+ IN EFI_TPM_DEVICE_PROTOCOL *This
+ );
+
+/*++
+
+ Routine Description:
+ This service Open the TPM interface
+
+ Arguments:
+ This - A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+
+ Returns:
+ EFI_SUCCESS - Operation completed successfully
+ EFI_DEVICE_ERROR - The command was unsuccessful
+ EFI_NOT_FOUND - The component was not running
+
+ --*/
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TPM_MP_CLOSE)(
+ IN EFI_TPM_DEVICE_PROTOCOL *This
+ );
+/*++
+
+ Routine Description:
+ This service close the TPM interface and deactivate TPM
+
+ Arguments:
+ This - A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+
+ Returns:
+ EFI_SUCCESS - Operation completed successfully
+ EFI_DEVICE_ERROR - The command was unsuccessful
+ EFI_NOT_FOUND - The component was not running
+
+ --*/
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TPM_MP_GET_STATUS_INFO)(
+ IN EFI_TPM_DEVICE_PROTOCOL *This
+ );
+/*++
+
+ Routine Description:
+ This service get the current status infomation of TPM
+
+ Arguments:
+ This - A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+ ReqStatusType - Requested type of status information, driver or device.
+ Status - Pointer to the returned status.
+
+ Returns:
+ EFI_SUCCESS - Operation completed successfully
+ EFI_DEVICE_ERROR - The command was unsuccessful
+ EFI_INVALID_PARAMETER - One or more of the parameters are incorrect
+ EFI_BUFFER_TOO_SMALL - The receive buffer is too small
+ EFI_NOT_FOUND - The component was not running
+
+ --*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TPM_MP_TRANSMIT)(
+ IN EFI_TPM_DEVICE_PROTOCOL *This,
+ IN UINTN NoInBuffers,
+ IN TPM_TRANSMIT_BUFFER *InBuffers,
+ IN UINTN NoOutBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutBuffers
+ );
+/*++
+
+ Routine Description:
+ This service transmit data to the TPM and get response from TPM
+
+ Arguments:
+ This - A pointer to the EFI_TPM_MP_DRIVER_PROTOCOL.
+
+ Returns:
+ EFI_SUCCESS - Operation completed successfully
+ EFI_DEVICE_ERROR - The command was unsuccessful
+ EFI_INVALID_PARAMETER - One or more of the parameters are incorrect
+ EFI_BUFFER_TOO_SMALL - The receive buffer is too small
+ EFI_NOT_FOUND - The component was not running
+
+ --*/
+
+
+void Prepare2Thunkproc (
+ UINT32 TcgOffset,
+ UINT16 TcgSelector );
+
+void TcmDxeCallMPDriver (
+ IN UINTN CFuncID,
+ TPMTransmitEntryStruct *CData,
+ UINT32* OUT CRetVal );
+
+void TpmDxeCallMPDriver (
+ IN UINTN CFuncID,
+ TPMTransmitEntryStruct *CData,
+ UINT32* OUT CRetVal );
+
+
+typedef struct _EFI_TPM_DEVICE_PROTOCOL
+{
+ EFI_TPM_MP_INIT Init;
+ EFI_TPM_MP_CLOSE Close;
+ EFI_TPM_MP_GET_STATUS_INFO GetStatusInfo;
+ EFI_TPM_MP_TRANSMIT Transmit;
+} EFI_TPM_DEVICE_PROTOCOL;
+
+extern EFI_GUID gEfiTpmDeviceProtocolGuid;
+
+#endif
diff --git a/Core/EM/TCG2/Common/Protocol/TpmDevice_Protocol.cif b/Core/EM/TCG2/Common/Protocol/TpmDevice_Protocol.cif
new file mode 100644
index 0000000..f24c11c
--- /dev/null
+++ b/Core/EM/TCG2/Common/Protocol/TpmDevice_Protocol.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "TpmDevice_Protocol"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common\Protocol\"
+ RefName = "TpmDevice_Protocol"
+[files]
+"TpmDevice\TpmDevice.c"
+"TpmDevice\TpmDevice.h"
+<endComponent> \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/TCGMisc.h b/Core/EM/TCG2/Common/TCGMisc.h
new file mode 100644
index 0000000..4b1b7a4
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGMisc.h
@@ -0,0 +1,822 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TCGMisc.h 2 6/11/14 4:13p Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/11/14 4:13p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TCGMisc.h $
+//
+// 2 6/11/14 4:13p Fredericko
+// [TAG] EIP173073
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] PPI operations will fail
+// [RootCause] EFI spec changes requires that only industry variables
+// should use EfiGlobalVariableGuid
+// [Solution] REF-28609.V2: Clear The TPM via OS test fail /1AQPM037
+// (TPM1.2)
+// [Files] TcgMisc.h
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 8/30/13 11:06p Fredericko
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 34 3/29/13 9:45p Fredericko
+// [TAG] EIP113715
+// [Category] Improvement
+// [Description] Please update the copyright header according to AMI
+// copyright rule
+// [Files] Multiple Files
+//
+// [TAG] EIP109597
+// [Category] Improvement
+// [Description] Add a switch for TPM PPI flag access via BIOS NVRAM
+// [Files] TCGMisc.h, AmiTcgNvflagSample.c,
+//
+// [TAG] EIP118211
+// [Category] Improvement
+// [Description] Implement ability to skip Physical presence lock in
+// manufacturing mode
+// [Files] TcgPei.c, AmiTcgPlatformDxe.c, AmiTcgNvflagSample.c
+//
+// 33 11/30/12 7:20p Fredericko
+// [TAG] EIP104949
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UEFI 2.3.1 SCT test failed in Generic\EfiCompliant case.
+// TpmOldvar is not defined in the Spec.
+//
+// 32 5/20/12 2:08p Fredericko
+//
+// 31 4/19/12 8:04p Fredericko
+// Add Fastboot GUID definition for Internal use
+//
+// 30 3/19/12 6:19p Fredericko
+// Changes for TcgPerformance Metrics Improvement.
+// Files Changed: Tcg.sdl, TcgMisc.h, TcgDxe.c, TcgCommon.c, TcgCommon.h,
+// AmiTcgPlatformPeiLib.c, AmiTcgPlatformDxe.c, TcgDxe.dxs
+//
+// 29 2/03/12 5:11p Fredericko
+// [TAG] EIP81665
+// [Category] Improvement
+// [Description] Support for MOR feature improvement
+// [Files] Tcg.sdl, AmiTcgPlatformDxe.c, Tcgdxe.c, Tcglegacy.c
+//
+// 28 1/17/12 11:22a Fredericko
+// Install Tpm_Initialized Ppi in PEI
+//
+// 27 11/01/11 4:15a Fredericko
+// Fixed spelling changes request for physicalPresenceLock and
+// bGlobalLock.
+//
+// 26 8/26/11 12:53p Fredericko
+// [TAG] EIP65710
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Wrong structure for TPM and TCM permanent flags
+// [RootCause] Lower part of structure was not defined properly since we
+// don't use them in BIOS
+// [Solution] Update structure in TcgMisc.h
+// [Files] TcgMisc.h
+//
+// 25 8/09/11 6:13p Fredericko
+// [TAG] EIP65605
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] None
+// [RootCause] Tpm Permanent flags Structure needs to be updated
+// [Solution] Updated the Tpm Permanent Flags structure
+// [Files] TcgMisc.h
+//
+// 24 7/24/11 10:05p Fredericko
+// [TAG] EIP65177
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] Included sample protocoldefinition to read and set
+// persistent BIOS flags.
+// 2. Also include defines for new smi transactions for Ppi.
+//
+// 23 4/06/11 6:46p Fredericko
+// PPI confirmation Override changes
+//
+// 22 4/01/11 10:50a Fredericko
+// Added TCG legacy GUID for initializing the TPM in legacy mode
+//
+// 21 3/29/11 12:25p Fredericko
+//
+// 20 3/28/11 12:22p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 17 8/04/10 5:21p Fredericko
+// Added #defines for TCG SMI transactions
+//
+// 16 7/09/10 3:26p Fredericko
+// EFI_NULL GUID defined
+//
+// 15 5/19/10 5:18p Fredericko
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+// 14 3/25/10 7:13p Fredericko
+// Function definition for ResetPPI variables added
+//
+// 13 3/23/10 8:40p Fredericko
+//
+// 12 3/19/10 4:13p Fredericko
+// Generic guid defined for legacy MA Driver, Legacy MP driver and TCG
+// driver hobs
+// Also modified structures Far32Locals, MAStruct, ESPFuncStruc
+//
+// 11 1/14/10 11:43a Fredericko
+// Added TCG NVRAM structure and guid definitions.
+//
+// 10 12/03/09 6:23p Fredericko
+// added UEFI guid definition for MOR
+//
+// 9 6/08/09 4:35p Fredericko
+// typedefs for STANY_FLAGS
+//
+// 8 6/01/09 3:54p Fredericko
+// changes for TCM support.
+//
+// 7 4/30/09 6:13p Fredericko
+// Updated Header Date
+//
+// 6 4/30/09 5:30p Fredericko
+// AMI company Header Address changes
+//
+// 5 3/05/09 2:02p Fredericko
+// Changes for CoreSources dependency
+//
+// 4 2/05/09 4:54p Fredericko
+// Generic TCG structures added and GUIDs added in favor of building
+// without EDK.
+//
+// 3 26/08/08 10:44a Anandakrishnanl
+// Added Sdl Token for the define Equates and Changed the Corresponding
+// Codes
+//
+// 2 2/27/08 5:50p Fredericko
+// TCG structures included
+//
+// 1 7/23/07 10:24a Fredericko
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgMisc.h
+//
+// Description:
+// Miscellaneous Tcg Header file
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+//------------------------------------------------------------------------------
+// OEM INFO for TCG structures(Port OEM info)
+//------------------------------------------------------------------------------
+#ifndef _TCGMISC_H //To Avoid this header get compiled twice
+#define _TCGMISC_H
+#include <EFI.h>
+
+#define EV_SPECIFICATION_IDENTIFIER (UINT32)0x000000012
+//--------------------AMI_PORTING----------------------------------------------
+#define TCG_BIOS_VENDOR "AMI"
+#define TCG_OEM_ID "ALASKA"
+//-----------------------------------------------------------------------------
+#define EFI_TCG_WAKE_EVENT_DATA_HOB_GUID \
+ {0xBBB810BB, 0x5EF0, 0x4E8F, 0xB2, 0x98, 0xAD, 0x74, 0xAA, 0x50, 0xEF, 0x0A}
+
+#define TCG_EFI_HOB_LIST_GUID \
+ { 0x7739f24c, 0x93d7, 0x11d4, 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}
+
+#define EFI_TCG_LOG_HOB_GUID \
+ {0x5f7d4e0e, 0x3d6d, 0x42bc, 0xa9, 0x42, 0xe, 0x91, 0xe8, 0x3e, 0x3c, 0x31}
+
+#define AMI_TCG_EFI_OS_VARIABLE_GUID \
+ {0xa8a2093b, 0xfefa, 0x43c1, 0x8e, 0x62, 0xce, 0x52, 0x68, 0x47, 0x26, 0x5e}
+
+#define AMI_TCG_RESETVAR_HOB_GUID \
+ {0xa8a2093b, 0xfefa, 0x43c1, 0x8e, 0x62, 0xce, 0x52, 0x68, 0x47, 0x26, 0x5e}
+
+#define AMI_TCG_MANUFACTURING_MODE_HOB_GUID \
+ {0x5d7f83ee, 0x88e5, 0x4ea8, 0xbe, 0xe8, 0x23, 0x79, 0xa6, 0x3c, 0xff, 0x8}
+
+#define AMI_TCG_CONFIRMATION_FLAGS_GUID \
+ {0x7d3dceee, 0xcbce, 0x4ea7, 0x87, 0x09, 0x6e, 0x55, 0x2f, 0x1e, 0xdb, 0xde}
+
+#define AMI_TCG_PERM_FLAGS_GUID \
+ {0x2325f2fc, 0x5683, 0x4648, 0x97, 0xc4, 0x9a, 0x52, 0x0d, 0xfb, 0xe3, 0x25}
+
+#define EFI_NULL_GUID \
+ {0x00000000, 0x0000, 0x0000, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
+
+#define TCG_EFI_GLOBAL_VARIABLE_GUID \
+ { \
+ 0x135902e7, 0x9709, 0x4b41, 0x8f, 0xd2, 0x40, 0x69, 0xda, 0xf0, 0x54,\
+ 0x6a \
+ }
+
+#define TCG_VARIABLE_GUID \
+ {0x9868b77b, 0x607e, 0x4cb7, 0xa6, 0xce, 0xe1, 0xd5, 0x29, 0xd4, 0x41, 0x64}
+
+#define EFI_TCM_MPDriver_GUID \
+ { 0x3EB9F0D3, 0x40D0, 0x435b, 0xB6, 0x92, 0x80, 0x91, 0x51, 0x80, 0x7F,\
+ 0xF4}
+
+#define EFI_TCM_MADriver_GUID \
+ { 0xca0d6ff6, 0x62a7, 0x4b1f, 0xbb, 0x90, 0x52, 0xee, 0xca, 0x1, 0xa9,\
+ 0x9f}
+
+#define AMI_TCM_CALLBACK_GUID \
+ { 0x91c74e50, 0x361d, 0x4cda, 0xa1, 0x6b, 0xc9, 0x2b, 0xe4, 0xbf, 0x16,\
+ 0xee}
+
+#define AMI_TPM_LEGACY_GUID \
+ { 0xa1c85085, 0x3053, 0x4c4b, 0xa9, 0xf6, 0x72, 0x4d, 0x22, 0xa7, 0x6e,\
+ 0xf9}
+
+#define PEI_TPM_INITIALIZED_PPI_GUID \
+ { \
+ 0xe9db0d58, 0xd48d, 0x47f6, 0x9c, 0x6e, 0x6f, 0x40, 0xe8, 0x6c, 0x7b, 0x41 \
+ }
+
+#define TPM20_HOB_GUID \
+ { \
+ 0x7cea4f7e, 0x2052, 0x46ed, 0xbe, 0xfd, 0xe2, 0x2a, 0x44, 0xdc, 0x65, 0xe7 \
+ }
+
+#define FAST_BOOT_VARIABLE_GUID \
+ { 0xb540a530, 0x6978, 0x4da7, 0x91, 0xcb, 0x72, 0x7, 0xd7, 0x64, 0xd2, 0x62 }
+
+
+typedef struct
+{
+ UINT8 RQST;
+ UINT8 RCNT;
+ UINT8 ERROR;
+ UINT8 Flag;
+ UINT8 AmiMisc;
+} AMI_PPI_NV_VAR;
+
+typedef struct _mem_in
+{
+ UINTN datat; //0=use_32;1=use_64;2=use_both; 3=dont_use
+ UINT64 address; //Start Memory address
+ UINTN size; //Memory block Size
+} mem_in;
+
+#pragma pack (1)
+typedef struct tdVendorInfoStruct
+{
+ UINT8 *TCGBIOSVENDOR[6];
+ UINT8 *TCGOEMID[8];
+} TCG_VendorInfoStruct;
+
+typedef struct tdPCClientSpecIdEventStruct
+{
+ UINT8 PlatformClass;
+ UINT8 BIOSTypeInterface;
+ UINT8 BIOSTypeMapping;
+ UINT8 SpecVersionMajor;
+ UINT8 SpecVersionMinor;
+ UINT8 SpecErrata;
+ UINTN Reserved;
+ UINTN VendorInfoSize;
+ TCG_VendorInfoStruct *VendorInfo;
+} TCG_PCClientSpecIDEventStruct;
+#pragma pack()
+
+
+#pragma pack (1)
+typedef struct
+{
+ UINT16 Signature; // 0xaa55
+ UINT32 CodeP; // Pointer to beginning of code ( offset to entry point for driver)
+ UINT16 Size; //Total size of the driver in bytes including header
+ UINT32 BaseAddress; //base address of the TPM(as set by BIOS)
+ UINT32 BaseAddress2; //optional second base address of the TPM(as set by BIOS)
+ UINT8 TcgIrqL; //IRQ level
+ UINT8 DMACH; //DMA channel
+ UINT8 checksum; //XOR checksum
+ UINT8 Reserved;
+ UINT32 PCIPFA; //IRQ level
+ UINT32 Other; //Cardbus, USB etc
+ UINT32 TpmPort; //location of TPM configuration port
+ UINT16 VID; //vendor ID
+ UINT16 DID; //device ID
+} MPDRIVER_LEGHEADER;
+#pragma pack ()
+
+
+
+#define EfiBootservicesData 0x04
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINTN NumberOfTables;
+ EFI_CONFIGURATION_TABLE TableEntry[1];
+} TCG_EFI_HANDOFF_TABLE_POINTERS;
+
+//
+// EFI_VARIABLE_DATA
+//
+// This structure serves as the header for measuring variables. The name of the
+// variable (in Unicode format) should immediately follow, then the variable
+// data.
+//
+typedef struct
+{
+ EFI_GUID VariableName;
+ UINTN UnicodeNameLength;
+ UINTN VariableDataLength;
+ CHAR16 UnicodeName[1];
+ INT8 VariableData[1]; // Driver or platform-specific data
+} TCG_EFI_VARIABLE_DATA;
+#pragma pack()
+
+#define INTERNAL_SHA_ARRAY_LENGTH 0x500 //500 bytes per SHA update or extend
+
+//-----------------------------------------------------------------------------
+
+#define EFI_TCG_CAP_HOB_GUID \
+ { 0xd05f8ff9, 0x8498, 0x4673, 0x84, 0x17, 0x7b, 0x9c, 0xce, 0x3d, 0xdb,\
+ 0x9b}
+
+#define EFI_TCG_MPDriver_HOB_GUID \
+ { 0xbaaead09, 0x2a0, 0x4131, 0x9e, 0xd, 0xbc, 0x52, 0x9e, 0xf0, 0xff,\
+ 0x2a}
+
+#define EFI_TCG_MADriver_HOB_GUID \
+ { 0xb58a69fe, 0x163e, 0x4cc0, 0xa4, 0x87, 0x30, 0x4d, 0x34, 0xd5, 0x48,\
+ 0x9f}
+
+#define EFI_TCG_MPDriver_GUID \
+ { 0x0515BC05, 0x2959, 0x4e91, 0x89, 0xC6, 0x6B, 0x3A, 0x3F, 0x1F, 0xCB,\
+ 0x65}
+
+#define EFI_TCG_MADriver_GUID \
+ { 0x92ba9255, 0x2819, 0x4479, 0x86, 0x7a, 0x1c, 0x58, 0xf0, 0x72, 0xc5,\
+ 0xb2}
+
+#define EFI_TCM_MPDriver_GUID \
+ { 0x3EB9F0D3, 0x40D0, 0x435b, 0xB6, 0x92, 0x80, 0x91, 0x51, 0x80, 0x7F,\
+ 0xF4}
+
+#define EFI_TCM_MADriver_GUID \
+ { 0xca0d6ff6, 0x62a7, 0x4b1f, 0xbb, 0x90, 0x52, 0xee, 0xca, 0x1, 0xa9,\
+ 0x9f}
+
+#define EFI_TCG_PEI_READ_ONLY_VARIABLE_PPI_GUID\
+ {0x3cdc90c6, 0x13fb, 0x4a75, 0x9e, 0x79, 0x59, 0xe9, 0xdd, 0x78, 0xb9, 0xfa}
+
+#define AMI_TCG_FV_HOB_GUID \
+ { 0x69275410, 0x9be7, 0x4df2, 0xb7, 0xbb, 0x54, 0x50, 0x65, 0xb6, 0x70,\
+ 0xa4}
+
+#define AMI_TCG_INTERFACE_VAR_GUID \
+ { 0x6e6ebc2d, 0x77ab, 0x46cf, 0xb2, 0xa7, 0xcc, 0x96, 0x8b, 0xe, 0x8a,\
+ 0xf3}
+
+#define AMI_PPI_INTERNAL_VAR_GUID \
+ { 0x78097bb6, 0x48cf, 0x449b, 0x9b, 0xdb, 0xf6, 0x38, 0x49, 0x85, 0x64,\
+ 0x60}
+
+#define AMI_PROTOCOL_INTERNAL_HLXE_GUID \
+ { 0x78092548, 0x48cf, 0x449b, 0x9b, 0xdb, 0xf6, 0x38, 0x49, 0x85, 0x64,\
+ 0x60}
+
+
+#define CMOS_BANK1_INDEXREG 0x70
+#define CMOS_BANK2_INDEXREG 0x72
+#define CMOS_BANK1_SIZE 0x80
+
+// *****************************************************************************************************************************/
+// PHYSICAL PRESENCE INTERFACE
+// *****************************************************************************************************************************/
+#define TCPA_PPI_USERABORT 0xFFF0
+#define TCPA_PPI_BIOSFAIL 0xFFF1
+
+#define TCPA_PPIOP_ENABLE 1
+#define TCPA_PPIOP_DISABLE 2
+#define TCPA_PPIOP_ACTIVATE 3
+#define TCPA_PPIOP_DEACTIVATE 4
+#define TCPA_PPIOP_CLEAR 5
+#define TCPA_PPIOP_ENABLE_ACTV 6
+#define TCPA_PPIOP_DEACT_DSBL 7
+#define TCPA_PPIOP_OWNER_ON 8
+#define TCPA_PPIOP_OWNER_OFF 9
+#define TCPA_PPIOP_ENACTVOWNER 10
+#define TCPA_PPIOP_DADISBLOWNER 11
+#define TCPA_PPIOP_UNOWNEDFIELDUPGRADE 12
+#define TCPA_PPIOP_SETOPAUTH 13
+#define TCPA_PPIOP_CLEAR_ENACT 14
+#define TCPA_PPIOP_SETNOPPIPROVISION_FALSE 15
+#define TCPA_PPIOP_SETNOPPIPROVISION_TRUE 16
+#define TCPA_PPIOP_SETNOPPICLEAR_FALSE 17
+#define TCPA_PPIOP_SETNOPPICLEAR_TRUE 18
+#define TCPA_PPIOP_SETNOPPIMAINTENANCE_FALSE 19
+#define TCPA_PPIOP_SETNOPPIMAINTENANCE_TRUE 20
+#define TCPA_PPIOP_ENABLE_ACTV_CLEAR 21
+#define TCPA_PPIOP_ENABLE_ACTV_CLEAR_ENABLE_ACTV 22
+
+#define PPIXOP_ENABLE 0x01
+#define PPIXOP_DISABLE 0x02
+#define PPIXOP_ACTIVATE 0x04
+#define PPIXOP_DEACTIVATE 0x08
+#define PPIXOP_OWNER_ON 0x10
+#define PPIXOP_OWNER_OFF 0x20
+#define PPIXOP_CLEAR 0x40
+
+#define PPIXOP_EN_FLAG (PPIXOP_ENABLE | PPIXOP_DISABLE)
+#define PPIXOP_A_FLAG (PPIXOP_ACTIVATE | PPIXOP_DEACTIVATE)
+#define PPIXOP_O_FLAG (PPIXOP_OWNER_ON | PPIXOP_OWNER_OFF)
+
+#define PPI_MAX_BASIC_OP 5
+#define PPI_FEATURE_ON 1
+#define PPI_FEATURE_OFF 2
+#define PPI_FEATURE_CHANGE (PPI_FEATURE_ON | PPI_FEATURE_OFF)
+
+
+//
+// TSS event strings
+//
+#define TSS_ACTION_CALLING_INT19 "Calling INT 19h"
+#define TSS_ACTION_RETURNED_INT19 "Returned INT 19h"
+#define TSS_ACTION_RETURNED_INT18 "Return via INT 18h"
+#define TSS_ACTION_BOOTING_BCV_DEVICE "Booting BCV Device "
+#define TSS_ACTION_BOOTING_BEV_DEVICE "Booting BEV Device "
+#define TSS_ACTION_ROM_BASED_SETUP "Entering ROM Based Setup"
+#define TSS_ACTION_BOOTING_PARTIES "Booting to Parties "
+#define TSS_ACTION_USER_PASSWORD "User Password Entered"
+#define TSS_ACTION_ADMINISTRATOR_PASSWORD "Administrator Password Entered"
+#define TSS_ACTION_PASSWORD_FAILURE "Password Failure"
+#define TSS_ACTION_WAKE_EVENT "Wake Event n"
+#define TSS_ACTION_BOOT_SEQ_INTERVENTION "Boot Sequence User Intervention"
+#define TSS_ACTION_CHASSIS_INTRUSION "Chassis Intrusion"
+#define TSS_ACTION_NON_FATAL_ERROR "Non Fatal Error"
+#define TSS_ACTION_OPROM_SCAN "Start Option ROM Scan"
+#define TSS_ACTION_UNHIDEING_OPROM "Unhiding Option ROM Code"
+
+#define TSS_ACTION_IPL_PARTITION "Booting from "
+#define TSS_ACTION_IPL_LEGACY_PARTITION "Booting from Legacy "
+
+
+//-----------------------------------------------------------------------------
+// Internal Tcg Capabilities Headers and Struct
+//-----------------------------------------------------------------------------
+VOID* LocateATcgHob (
+ UINTN NoTableEntries,
+ EFI_CONFIGURATION_TABLE *ConfigTable,
+ EFI_GUID *HOB_guid );
+
+#pragma pack (1)
+typedef struct
+{
+ UINT16 Tag;
+ UINT32 ParamSize;
+ UINT32 CommandCode;
+ UINT32 caparea;
+ UINT32 subCapSize;
+ UINT32 subCap;
+} TPM_GetCapabilities_Input;
+
+typedef struct
+{
+ UINT16 Tag;
+ UINT32 ParamSize;
+ UINT32 RetCode;
+ UINT32 respSize;
+ UINT16 tag;
+ UINT8 disabled;
+ UINT8 ownership;
+ UINT8 deactivated;
+ UINT8 readPubek;
+ UINT8 disableOwnerClear;
+ UINT8 allowMaintenance;
+ UINT8 physicalPresenceLifetimeLock;
+ UINT8 physicalPresenceHWEnable;
+ UINT8 physicalPresenceCMDEnable;
+ UINT8 CEKPUsed;
+ UINT8 TPMpost;
+ UINT8 TPMpostLock;
+ UINT8 FIPS;
+ UINT8 Operator;
+ UINT8 enableRevokeEK;
+ UINT8 nvLocked;
+ UINT8 readSRKPub;
+ UINT8 tpmEstablished;
+ UINT8 maintenanceDone;
+ UINT8 disableFullDALogicInfo;
+} TPM_Capabilities_PermanentFlag;
+
+#define NTC_ORD_GET_TPM_STATUS ((UINT32) 0x20000021)
+typedef struct
+{
+ UINT16 Tag;
+ UINT32 ParamSize;
+ UINT32 RetCode;
+ UINT8 isdisabled;
+ UINT8 isdeactivated;
+ UINT8 isEkSet;
+ UINT8 isOwnerSet;
+ UINT8 preConfigSet;
+ //ami specific we
+ //don't need rest of structure
+} NUVOTON_SPECIFIC_FLAGS;
+
+
+typedef struct
+{
+ UINT16 Tag;
+ UINT32 ParamSize;
+ UINT32 RetCode;
+ UINT32 respSize;
+ UINT16 tag;
+ UINT8 deactivated;
+ UINT8 disableForceClear;
+ UINT8 physicalPresence;
+ UINT8 physicalPresenceLock;
+ UINT8 bGlobalLock;
+} TPM_VOLATILE_FLAGS;
+
+
+
+typedef struct
+{
+ UINT16 Tag;
+ UINT32 ParamSize;
+ UINT32 RetCode;
+ UINT32 respSize;
+ UINT16 tag;
+ UINT8 disabled;
+ UINT8 ownership;
+ UINT8 deactivated;
+ UINT8 readPubek;
+ UINT8 disableOwnerClear;
+ UINT8 physicalPresenceLifetimeLock;
+ UINT8 physicalPresenceHWEnable;
+ UINT8 physicalPresenceCMDEnable;
+ UINT8 CEKPUsed;
+ UINT8 TPMpost;
+ UINT8 TPMpostLock;
+ UINT8 Operator;
+ UINT8 enableRevokeEK;
+ UINT8 nvLocked;
+ UINT8 tpmEstablished;
+ UINT8 writeEkCertLock;
+} TCM_Capabilities_PermanentFlag;
+
+
+typedef struct _TPMTransmitEntryStruct
+{
+ UINT32 pbInBuf;
+ UINT32 dwInLen;
+ UINT32 pbOutBuf;
+ UINT32 dwOutLen;
+} TPMTransmitEntryStruct;
+
+
+#define PCI_EXPANSION_ROM_HEADER_SIGNATURE 0xaa55
+
+#define READTRANSACTION 0x01
+#define WRITETRANSACTION 0x02
+#define GETCONFTRANSACTION 0x03
+#define RQSTVAR 0x10
+#define RCNTVAR 0x20
+#define ERRORVAR 0x30
+#define CONFIRMATION 0x40
+#define ERRORVAR2 0x50
+#define WRITEMOR 0x20
+#define WRITERQST 0x10
+#define WRITEENDRQSTFLAG 0x01
+#define WRITEENDMORFLAG 0x02
+#define READENDCONFLAG 0x03
+#define TRANSACTION_MASK 0x0F
+#define TYPE_MASK 0xF0
+
+typedef struct
+{
+ UINT16 Signature; // 0xaa55
+ UINT16 InitializationSize;
+ UINT32 EfiSignature; // 0x0EF1
+ UINT16 EfiSubsystem;
+ UINT16 EfiMachineType;
+ UINT16 CompressionType;
+ UINT8 Reserved[8];
+ UINT16 EfiImageHeaderOffset;
+ UINT16 PcirOffset;
+} EFI_PCI_EXPANSION_ROM_HEADER;
+
+#define SCAN_F1 EFI_SCAN_F1
+#define SCAN_F2 EFI_SCAN_F2
+#define SCAN_F3 EFI_SCAN_F3
+#define SCAN_F4 EFI_SCAN_F4
+#define SCAN_F5 EFI_SCAN_F5
+#define SCAN_F6 EFI_SCAN_F6
+#define SCAN_F7 EFI_SCAN_F7
+#define SCAN_F8 EFI_SCAN_F8
+#define SCAN_F9 EFI_SCAN_F9
+#define SCAN_F10 EFI_SCAN_F10
+#define SCAN_F11 EFI_SCAN_F11
+#define SCAN_F12 EFI_SCAN_F12
+#define SCAN_ESC EFI_SCAN_ESC
+
+typedef struct _TCG_LOG_HOB_
+{
+ UINT32 TableMaxSize;
+ UINT32 TableSize;
+ UINT32 EventNum;
+ UINT32 Reserved;
+} TCG_LOG_HOB;
+
+#pragma pack()
+//--------------------------------------------------------------------------
+// END_OF Internal Tcg Capabilities Headers and Struct
+//--------------------------------------------------------------------------
+
+//--------------------------------------------------------------------------
+//USED PE/COFF image headers
+//--------------------------------------------------------------------------
+typedef struct
+{
+ UINTN Signature;
+ BOOLEAN FreeBuffer;
+ VOID *Source;
+ UINTN SourceSize;
+} IMAGE_FILE_HANDLE;
+
+
+#define EFI_IMAGE_ERROR_SUCCESS 0
+#define EFI_IMAGE_ERROR_IMAGE_READ 1
+#define EFI_IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+//
+//
+//----------------------------------------------------------------------------
+// Description: TCG ACPI table. Requires PORTING: OEM data
+// Input: None
+// Output: None
+//----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+//PORTING STARTS
+//-----------------------------------------------------------------------------
+#define TCG_TBL_REV 0x02
+#define TCG_OEMID "APTIO4" //; 6 charachters that identify the OEM
+#define TCG_TBL_OEM_ID 0x4653414150414E //"NAPAASF" //; 8 charachters as OEM manufacturer model ID
+#define TCG_TBL_OEM_REV 01 //; DWORD - Revision Number of this table,
+#define TCG_CREATOR_ID 0x5446534D // "MSFT"
+#define TCG_CREATOR_REVISION 0x01000013 // TBD
+#define TCG_PLATFORM_CLASS 0x0
+
+//-----------------------------------------------------------------------------
+//Assuming we are in 32bit mode in PEI and the selectors are set up in real mode
+//-----------------------------------------------------------------------------
+#define SEL_flatDS 0x8
+#define SEL_flatCS 0x10
+
+typedef struct
+{
+ UINT32 Offset;
+ UINT16 Selector;
+ UINT32 Codep;
+ UINT32 Size;
+} FAR32LOCALS;
+
+typedef struct
+{
+ UINT32 Offset;
+ UINT16 Selector;
+ UINT32 Codep;
+} MASTRUCT;
+
+typedef struct
+{
+ UINT16 Tag;
+ UINT32 ParamSize;
+ UINT32 RetCode;
+ UINT32 respSize;
+ UINT16 tag;
+ BOOLEAN postInitialise;
+ UINT32 localityModifier;
+ BOOLEAN transportExclusive;
+ BOOLEAN TOSPresent;
+} IntTPM_STANY_FLAGS;
+
+
+typedef struct
+{
+ UINT32 ReturnAddress;
+ UINT32 Header;
+ UINT8 FuncNum;
+} ESPFUNCSTRUCT;
+
+
+typedef struct
+{
+ UINT8 NoPpiProvision;
+ UINT8 NoPpiClear;
+ UINT8 NoPpiMaintenance;
+} PERSISTENT_BIOS_TPM_FLAGS;
+
+typedef struct
+{
+ UINT8 Interface : 1; //0=TpmNv, 1= BIOSNv
+ UINT8 Reserved1 : 1;
+ UINT8 Reserved2 : 1;
+ UINT8 Reserved3 : 1;
+ UINT8 Reserved4 : 1;
+ UINT8 Reserved5 : 1;
+ UINT8 Reserved6 : 1;
+ UINT8 Reserved7 : 1;
+} INTERNAL_BIOS_TPM_PPI_INTERFACE;
+
+
+typedef
+UINT8
+(EFIAPI * CONFIRM_USER)(
+);
+
+typedef struct _AMI_CONFIRMATION_OVERRIDE_PROTOCOL
+{
+ CONFIRM_USER ConfirmUser;
+} AMI_CONFIRMATION_OVERRIDE_PROTOCOL;
+
+
+typedef
+EFI_STATUS
+(EFIAPI * READ_PERSISTENT_BIOS_TPM_FLAGS)(
+ PERSISTENT_BIOS_TPM_FLAGS *
+);
+
+typedef
+EFI_STATUS
+(EFIAPI * SET_PERSISTENT_BIOS_TPM_FLAGS)(
+ PERSISTENT_BIOS_TPM_FLAGS *
+);
+
+
+typedef struct _TPM_PERM_FLAGS
+{
+ TPM_Capabilities_PermanentFlag Capabilities;
+} TPM_PERM_FLAGS;
+
+typedef struct _PERSISTENT_BIOS_TPM_MANAGEMENT_FLAGS_PROTOCOL
+{
+ READ_PERSISTENT_BIOS_TPM_FLAGS ReadBiosTpmflags;
+ SET_PERSISTENT_BIOS_TPM_FLAGS SetBiosTpmflags;
+} PERSISTENT_BIOS_TPM_MANAGEMENT_FLAGS_PROTOCOL;
+
+
+#define MA_FUNCTION_INIT 0x01
+#define MP_FUNCTION_CLOSE 0x02
+#define MP_FUNCTION_GET_STATUS 0x03
+#define MP_FUNCTION_TRANSMIT 0x04
+//-----------------------------------------------------------------------------
+//PORTING ENDS
+//-----------------------------------------------------------------------------
+
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/TCGSmm/TCGSmm.DXS b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.DXS
new file mode 100644
index 0000000..fe7043b
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.DXS
@@ -0,0 +1,84 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.DXS 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.DXS $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 2 12/10/13 12:59p Fredericko
+// Modify dependency's
+//
+// 1 10/08/13 12:05p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 7/11/13 6:14p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20).
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 7/25/11 3:21a Fredericko
+// [TAG] EIP65177
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] TCG Ppi Sec ver 1.2 update
+//
+// 2 5/20/10 8:54a Fredericko
+//
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TCGSmm.dxs
+//
+// Description:
+// Dependency for TcgSmm
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "TCGSmm.h"
+
+DEPENDENCY_START
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID
+DEPENDENCY_END
+
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/TCGSmm/TCGSmm.c b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.c
new file mode 100644
index 0000000..5740605
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.c
@@ -0,0 +1,956 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.c 2 6/09/14 5:01p Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/09/14 5:01p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.c $
+//
+// 2 6/09/14 5:01p Fredericko
+// Changes for SetVariable vulnerability during Runtime
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 4 3/17/14 3:23p Fredericko
+//
+// 3 3/14/14 3:53p Fredericko
+//
+// 2 12/10/13 12:58p Fredericko
+// Locate Tree Protocol as well
+//
+// 1 10/08/13 12:05p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 8/30/13 11:02p Fredericko
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 17 7/31/12 6:27p Fredericko
+// [TAG] EIP94589
+// [Category] Improvement
+// [Description] Use better variable names in TcgSmm.c
+// [Files] TcgSmm.c
+//
+// 16 5/20/12 2:12p Fredericko
+//
+// 15 5/09/12 5:31p Fredericko
+// Change Port address to support 16bit port addresses. Some Chipsets
+// require this.
+//
+// 14 3/19/12 6:37p Fredericko
+// [TAG] EIP82866
+// [Description] AMIUEFI: Implement the NoPPIClear flag and provide
+// operations to set/clear the value or a BIOS config option - Windows
+// Partner Bug Management Bug #679996
+// [Files] AmiTcgNvFlagSample.c, AmiTcgNvFlagSample.sdl,
+// AmiTcgPlatformDxe.c
+//
+// 13 12/12/11 1:08p Fredericko
+// [TAG] EIP59683
+// [Category] Improvement
+// [Description] Allow selection between writing to SMI port as a word
+// or as a Byte.
+// Some platforms might require word writes to the SMI Status port.
+// [Files] Tcg.cif, Tcg.sdl, Tcg_ppi1_2_Ex.asl, TcgSmm.mak, TcgSmm.c
+//
+// 12 12/07/11 4:27p Fredericko
+//
+// 11 12/07/11 4:26p Fredericko
+// [TAG] EIP59683
+// [Category] Improvement
+// [Description] Allow selection between writing to SMI port as a word
+// or as a Byte.
+// Some platforms might require word writes to the SMI Status port.
+// [Files] Tcg.cif, Tcg.sdl, Tcg_ppi1_2_Ex.asl, TcgSmm.mak, TcgSmm.c
+//
+// 10 8/10/11 4:30p Fredericko
+// [TAG] EIPEIP66468
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] 1. Added some more boundary checking for unsupported
+// functions and for handling of Ppi 0
+// [Files] 1. TcgSmm.c
+//
+// 9 8/09/11 6:29p Fredericko
+// [TAG] EIP66468
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] 1. Changes for Tcg Ppi 1.2 support.
+// [Files] 1 TcgSmm.h
+// 2.TcgSmm.c
+// 3.Tcg_ppi1_2.asl
+// 4. AmiTcgNvflagsSample.c
+// 5. AmiTcgPlatformPeiLib.c
+// 6. AmiTcgPlatformDxe.sdl
+// 7. AmiTcgPlatformDxe.c
+//
+// 8 7/25/11 3:20a Fredericko
+// [TAG] EIP65177
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] TCG Ppi Sec ver 1.2 update
+//
+// 7 2/16/11 10:37a Fredericko
+// [TAG] EIP54014
+// [Category] BUG FIX
+// [Severity] HIGH
+// [Symptom] TPM initialize failed using win7 tool tpm.msc after drive
+// bitlocker test.
+// [RootCause] wrong size used for getvariable
+// [Solution] Use correct size
+// [Files] TCGSmm.c
+//
+// 6 8/23/10 4:21p Fredericko
+// Code Clean up. Removed port 80 checkpoint writes from code.
+//
+// 5 8/09/10 2:34p Fredericko
+// Added NVRAM writes functions for TCG PPI support. Moved from TcgBoard
+// component
+//
+// 4 8/04/10 5:07p Fredericko
+// Changed AMI interface to use only one SMI value instead of 3
+//
+// 3 5/20/10 8:54a Fredericko
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TCGSmm.c
+//
+// Description:
+// Function definition file for TCGSMM subcomponent
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#include "TCGSmm.h"
+#include <Tpm20Includes\TrEEProtocol.h>
+#include <Setup.h>
+
+#if WORD_ACCESS_SMI_PORT == 0x01
+void DisablePlatformSMI();
+#endif
+
+VOID NVOSWrite_PPI_request (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext );
+
+VOID NVOSWrite_MOR_request (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext );
+
+VOID NVOSRead_PPI_request (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext );
+
+EFI_STATUS GetNextGuidHob(
+ IN OUT VOID **HobStart,
+ IN EFI_GUID * Guid,
+ OUT VOID **Buffer,
+ OUT UINTN*BufferSize OPTIONAL )
+{
+ return EFI_SUCCESS;
+}
+
+typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+
+static EFI_GUID AmiNvramControlProtocolGuid = { 0xf7ca7568, 0x5a09, 0x4d2c, { 0x8a, 0x9b, 0x75, 0x84, 0x68, 0x59, 0x2a, 0xe2 } };
+typedef EFI_STATUS (*SHOW_BOOT_TIME_VARIABLES)(BOOLEAN Show);
+
+typedef struct{
+ SHOW_BOOT_TIME_VARIABLES ShowBootTimeVariables;
+} AMI_NVRAM_CONTROL_PROTOCOL;
+
+
+AMI_NVRAM_CONTROL_PROTOCOL *NvramControl = NULL;
+
+
+UINT8 ReadSmiPort(UINT16 Port)
+{
+ #if WORD_ACCESS_SMI_PORT == 0x00
+ return (IoRead8(Port ));
+ #else
+ if(Port == (TCGSMIDATAPORT)){
+ Port = TCGSMIPORT;
+ return ((UINT8)(((IoRead16( Port ) & 0xFF00))>> 8));
+ }
+ else{
+ return ((UINT8)(IoRead16( Port ) & 0x00FF));
+ }
+ #endif
+}
+
+
+VOID WritebyteSmiPort(UINT16 Port, UINT8 data)
+{
+ UINT16 SmiPortVal = 0;
+
+ #if WORD_ACCESS_SMI_PORT == 0x00
+ IoWrite8(Port, data );
+ #else
+ SmiPortVal = ReadSmiPort (TCGSMIPORT);
+ if(Port == TCGSMIDATAPORT)
+ {
+ SmiPortVal |= (data << 8);
+ }else{
+ return; //don't change current SMI value
+ }
+ Port = TCGSMIPORT;
+ DisablePlatformSMI(); //put this function under board so that it is added to the CSP lib
+ IoWrite16(Port, SmiPortVal );
+ EnablePlatformSMI();
+ #endif
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NVOSread_PPI_request
+//
+// Description: Returns TCG PPI variable values to the Operating system
+//
+//
+// Input: IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID NVOSRead_PPI_request(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+ UINTN Size = sizeof(AMI_PPI_NV_VAR);
+ AMI_PPI_NV_VAR Temp;
+ UINT8 Read_value = 0;
+ EFI_STATUS Status;
+
+ Read_value = ReadSmiPort( TCGSMIDATAPORT );
+
+ if (NvramControl == NULL)
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(TRUE);
+
+ Status = pRS->GetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ NULL, \
+ &Size, \
+ &Temp );
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+
+ if(Status){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ return;
+ }
+
+ switch (Read_value & TYPE_MASK ){
+ case RQSTVAR:
+ WritebyteSmiPort( TCGSMIDATAPORT, Temp.RQST );
+ break;
+ case RCNTVAR:
+ WritebyteSmiPort( TCGSMIDATAPORT, Temp.RCNT );
+ break;
+ case ERRORVAR:
+ WritebyteSmiPort( TCGSMIDATAPORT, Temp.ERROR );
+ case ERRORVAR2:
+ WritebyteSmiPort( TCGSMIDATAPORT, Temp.AmiMisc );
+ break;
+ default:
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ break;
+ }
+}
+
+//****************************************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NVWrite_PPI_request
+//
+// Description: Writes TCG PPI variable values to NVRAM on SMI request the Operating system
+//
+//
+// Input: IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//****************************************************************************************
+VOID NVOSWrite_PPI_request(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+ UINTN Size = sizeof(AMI_PPI_NV_VAR);
+ AMI_PPI_NV_VAR Temp;
+ EFI_STATUS Status;
+ UINT8 Read_value = 0;
+ UINT32 attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ Read_value = ReadSmiPort( TCGSMIDATAPORT );
+
+ if( Read_value == TCPA_PPIOP_UNOWNEDFIELDUPGRADE
+ || Read_value == TCPA_PPIOP_SETOPAUTH
+ || Read_value == TCPA_PPIOP_SETNOPPIMAINTENANCE_FALSE
+ || Read_value == TCPA_PPIOP_SETNOPPIMAINTENANCE_TRUE
+ || Read_value > TCPA_PPIOP_ENABLE_ACTV_CLEAR_ENABLE_ACTV)
+ {
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xF1 );
+ return;
+ }
+
+ if(Read_value >= 0 && Read_value < 23)
+ {
+ Temp.RQST = Read_value;
+ Temp.RCNT = Read_value;
+ Temp.ERROR = 0;
+ Temp.Flag = 0;
+ Temp.AmiMisc = 0;
+
+ if (NvramControl == NULL)
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(TRUE);
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ Size, \
+ &Temp );
+
+ if(Status == EFI_INVALID_PARAMETER)
+ {
+ Status = pRS->SetVariable(L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ 0, \
+ 0, \
+ NULL);
+
+ if(EFI_ERROR(Status)){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ return;
+ }
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ Size, \
+ &Temp );
+ }
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+
+ if(Status){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ return;
+ }
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xF1 );
+ return;
+ }
+}
+
+
+
+#if defined TCGPPISPEC_1_2_SUPPORT && TCGPPISPEC_1_2_SUPPORT == 1
+//****************************************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Read_User_Confirmation_Status
+//
+// Description: Reads the user confirmation satus for PPI requests
+//
+//
+// Input: IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//****************************************************************************************
+VOID Read_User_Confirmation_Status(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+ UINTN Size = sizeof(PERSISTENT_BIOS_TPM_FLAGS);
+ UINTN BiosSize = sizeof(AMI_PPI_NV_VAR);
+ AMI_PPI_NV_VAR Temp;
+ PERSISTENT_BIOS_TPM_FLAGS TpmNvFlags;
+ UINT8 Read_value = 0;
+ EFI_STATUS Status;
+ SETUP_DATA SetupDataBuffer;
+ UINTN SetupVariableSize = sizeof(SETUP_DATA);
+ UINT32 SetupVariableAttributes=0;
+ EFI_GUID gSetupGuid = SETUP_GUID;
+ UINT32 attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ if (NvramControl == NULL)
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(TRUE);
+
+
+ Read_value = ReadSmiPort( TCGSMIDATAPORT );
+
+ Status = pRS->GetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ NULL, \
+ &BiosSize, \
+ &Temp );
+
+ //reset ppi transaction flag
+ Temp.Flag = 0;
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ BiosSize, \
+ &Temp );
+
+ if(Status == EFI_INVALID_PARAMETER)
+ {
+ Status = pRS->SetVariable(L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ 0, \
+ 0, \
+ NULL);
+
+ if(EFI_ERROR(Status)){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ return;
+ }
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ BiosSize, \
+ &Temp );
+ }
+
+
+ Status = pRS->GetVariable( L"TPMPERBIOSFLAGS", \
+ &SmmFlagsStatusguid, \
+ NULL, \
+ &Size, \
+ &TpmNvFlags );
+
+ Status = pRS->GetVariable (
+ L"Setup",
+ &gSetupGuid,
+ &SetupVariableAttributes,
+ &SetupVariableSize,
+ &SetupDataBuffer);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+
+ if(Read_value >= 0 && Read_value < 23)
+ {
+ if(Read_value == 0 )
+ {
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ return;
+ }
+
+ if( Read_value == TCPA_PPIOP_UNOWNEDFIELDUPGRADE
+ || Read_value == TCPA_PPIOP_SETOPAUTH
+ || Read_value == TCPA_PPIOP_SETNOPPIMAINTENANCE_FALSE
+ || Read_value == TCPA_PPIOP_SETNOPPIMAINTENANCE_TRUE
+ || Read_value > TCPA_PPIOP_ENABLE_ACTV_CLEAR_ENABLE_ACTV)
+ {
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x0 );
+ return;
+ }else if(Read_value == TCPA_PPIOP_CLEAR || Read_value == TCPA_PPIOP_ENABLE_ACTV_CLEAR )
+ {
+ if(TpmNvFlags.NoPpiClear == TRUE){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x3 );
+ }
+ return;
+ }else if(Read_value == TCPA_PPIOP_CLEAR_ENACT || Read_value == TCPA_PPIOP_ENABLE_ACTV_CLEAR_ENABLE_ACTV)
+ {
+ if(TpmNvFlags.NoPpiClear == TRUE && TpmNvFlags.NoPpiProvision == TRUE ){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x3 );
+ }
+ return;
+ }else if(Read_value == TCPA_PPIOP_SETNOPPIPROVISION_FALSE || Read_value == TCPA_PPIOP_SETNOPPIPROVISION_TRUE)
+ {
+ if(Read_value == TCPA_PPIOP_SETNOPPIPROVISION_TRUE ){
+ if(SetupDataBuffer.Tpm20Device == 1){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x3 );
+ }
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ }
+ return;
+ }else if(Read_value == TCPA_PPIOP_SETNOPPICLEAR_FALSE || Read_value == TCPA_PPIOP_SETNOPPICLEAR_TRUE)
+ {
+ if(Read_value == TCPA_PPIOP_SETNOPPICLEAR_TRUE ){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x3 );
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ }
+ return;
+ }
+ else if(TpmNvFlags.NoPpiProvision == TRUE)
+ {
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x4 );
+ }else
+ {
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x3 );
+ }
+ }else{
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x0 );
+ }
+}
+#endif
+
+
+
+//****************************************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: NVOSWrite_MOR_request
+//
+// Description: Writes TCG PPI MOR variable to NVRAM on SMI request the Operating system
+//
+//
+// Input: IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//****************************************************************************************
+VOID NVOSWrite_MOR_request(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+ UINT8 mor = 0;
+ UINTN MorSize = sizeof(mor);
+ EFI_STATUS Status;
+ CHAR16 UefiMor[] = L"MemoryOverwriteRequestControl";
+ EFI_GUID MorUefiGuid = MEMORY_ONLY_RESET_CONTROL_GUID;
+ UINT8 Read_value = 0;
+ UINTN PpiVarSize = sizeof(AMI_PPI_NV_VAR);
+ AMI_PPI_NV_VAR Temp;
+ UINT32 attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+ Read_value = ReadSmiPort( TCGSMIDATAPORT );
+
+ if (NvramControl == NULL)
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(TRUE);
+
+
+ Status = pRS->SetVariable( UefiMor, \
+ &MorUefiGuid, \
+ EFI_VARIABLE_NON_VOLATILE \
+ | EFI_VARIABLE_RUNTIME_ACCESS \
+ | EFI_VARIABLE_BOOTSERVICE_ACCESS, \
+ MorSize, \
+ &Read_value );
+
+ if(Status){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ return;
+ }
+
+ Status = pRS->GetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ NULL, \
+ &PpiVarSize, \
+ &Temp );
+
+ if(Status){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ return;
+ }
+
+ Temp.Flag = 0;
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ PpiVarSize, \
+ &Temp );
+
+ if(Status == EFI_INVALID_PARAMETER)
+ {
+ Status = pRS->SetVariable(L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ 0, \
+ 0, \
+ NULL);
+
+ if(EFI_ERROR(Status)){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ return;
+ }
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ PpiVarSize, \
+ &Temp);
+ }
+
+ if(Status){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ return;
+ }
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgCommonSetFlag
+//
+// Description: Common function to set flag for PPI write transactions
+//
+//
+// Input: UINT8 Data
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS TcgCommonSetFlag(
+ UINT8 Data
+)
+{
+ EFI_STATUS Status;
+ UINTN Size = sizeof(AMI_PPI_NV_VAR);
+ AMI_PPI_NV_VAR Temp;
+ UINT32 attrib = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS;
+
+
+ if (NvramControl == NULL)
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(TRUE);
+
+ Status = pRS->GetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ NULL, \
+ &Size, \
+ &Temp );
+
+ if(Status){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ return Status;
+ }
+
+ if((Data & TYPE_MASK) == WRITERQST){
+
+ Temp.Flag = WRITEENDRQSTFLAG;
+
+ }
+ else if((Data & TYPE_MASK) == WRITEMOR){
+
+ Temp.Flag = WRITEENDMORFLAG;
+ }
+#if defined TCGPPISPEC_1_2_SUPPORT && TCGPPISPEC_1_2_SUPPORT == 1
+ else if((Data & TYPE_MASK) == CONFIRMATION){
+
+ Temp.Flag = READENDCONFLAG;
+ }
+#endif
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ Size, \
+ &Temp );
+
+ if(Status == EFI_INVALID_PARAMETER)
+ {
+ Status = pRS->SetVariable(L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ 0, \
+ 0, \
+ NULL);
+
+ if(EFI_ERROR(Status)){
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ return Status;
+ }
+
+ Status = pRS->SetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ attrib, \
+ Size, \
+ &Temp);
+ }
+
+
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+ return Status;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgSmiCommonHandler
+//
+// Description: Common function to handle TCG SMI's
+//
+//
+// Input: IN EFI_HANDLE DispatchHandle,
+// IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+//
+// Output: VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID TcgSmiCommonHandler(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext )
+{
+ EFI_STATUS Status;
+ UINTN Size = sizeof(AMI_PPI_NV_VAR);
+ AMI_PPI_NV_VAR Temp;
+ UINT8 Data;
+
+
+ Data = ReadSmiPort( TCGSMIDATAPORT );
+
+ if (NvramControl == NULL)
+ NvramControl = GetSmstConfigurationTable(&AmiNvramControlProtocolGuid);
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(TRUE);
+
+ Status = pRS->GetVariable( L"AMITCGPPIVAR", \
+ &SmmtcgefiOsVariableGuid, \
+ NULL, \
+ &Size, \
+ &Temp );
+
+ if (NvramControl) NvramControl->ShowBootTimeVariables(FALSE);
+
+ if(Status){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ return;
+ }
+
+#if defined TCGPPISPEC_1_2_SUPPORT && TCGPPISPEC_1_2_SUPPORT == 1
+ if(Temp.Flag == READENDCONFLAG){
+ Read_User_Confirmation_Status ( DispatchHandle, DispatchContext );
+ return;
+ }
+#endif
+
+ if(Temp.Flag == WRITEENDRQSTFLAG){
+
+ NVOSWrite_PPI_request( DispatchHandle, DispatchContext );
+ return;
+
+ }else if(Temp.Flag == WRITEENDMORFLAG){
+
+ NVOSWrite_MOR_request( DispatchHandle, DispatchContext );
+ return;
+ }
+
+ switch(Data & TRANSACTION_MASK)
+ {
+ case READTRANSACTION:
+ NVOSRead_PPI_request( DispatchHandle, DispatchContext);
+ break;
+ case WRITETRANSACTION:
+ Status = TcgCommonSetFlag(Data);
+ if(Status){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0xFF );
+ }
+ break;
+#if defined TCGPPISPEC_1_2_SUPPORT && TCGPPISPEC_1_2_SUPPORT == 1
+ case GETCONFTRANSACTION:
+ Status = TcgCommonSetFlag(Data);
+ if(Status){
+ WritebyteSmiPort( TCGSMIDATAPORT, 0x00 );
+ }
+ break;
+#endif
+ default:
+ break;
+ }
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: HelpRegisterPPISMI
+//
+// Description: Common function to handle TCG SMI's
+//
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS HelpRegisterPPISMI(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_SMM_SW_DISPATCH_PROTOCOL *pSwDispatch;
+ EFI_SMM_SW_DISPATCH_CONTEXT SwContext;
+ EFI_HANDLE Handle;
+ EFI_HANDLE DummyHandle = NULL;
+ EFI_STATUS Status;
+
+ VERIFY_EFI_ERROR( pBS->LocateProtocol(
+ &gEfiSmmSwDispatchProtocolGuid, NULL, &pSwDispatch
+ ));
+
+ TRACE((TRACE_ALWAYS, "SMIFlash: Registering TCG SMI functions at offset\n"));
+
+ SwContext.SwSmiInputValue = PPI_OFFSET;
+ Status = pSwDispatch->Register( pSwDispatch,
+ TcgSmiCommonHandler,
+ &SwContext,
+ &Handle );
+
+ ASSERT_EFI_ERROR( Status );
+
+ if ( EFI_ERROR( Status )){
+ return EFI_SUCCESS;
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TCGSmmInit
+//
+// Description: Entry point for subcomponent
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS TCGSmmInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwDispatch;
+ EFI_GUID gTreeprotocol = EFI_TREE_PROTOCOL_GUID;
+ EFI_GUID gAmiTcgPltformProtocol = AMI_TCG_PLATFORM_PROTOCOL_GUID;
+ EFI_TREE_PROTOCOL *TreeProtocol = NULL;
+
+ InitAmiLib( ImageHandle, SystemTable );
+ Status = pBS->LocateProtocol( &SwDispatchProtocolGuid, NULL, &SwDispatch );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol(&gTreeprotocol, NULL, &TreeProtocol);
+ if(EFI_ERROR(Status)){
+ Status = pBS->LocateProtocol(&gAmiTcgPltformProtocol, NULL, &TreeProtocol);
+ if(EFI_ERROR(Status))return Status;
+ }
+
+ return InitSmmHandler( ImageHandle, SystemTable, HelpRegisterPPISMI, NULL );
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/Common/TCGSmm/TCGSmm.cif b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.cif
new file mode 100644
index 0000000..1410191
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "TCGSmm"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common\TCGSmm\"
+ RefName = "TCGSmm"
+[files]
+"TCGSmm.sdl"
+"TCGSmm.mak"
+"TCGSmm.h"
+"TCGSmm.c"
+"TCGSmm.DXS"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/TCGSmm/TCGSmm.h b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.h
new file mode 100644
index 0000000..45e1d3e
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.h
@@ -0,0 +1,104 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.h 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.h $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:05p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 5 8/09/11 6:28p Fredericko
+// [TAG] EIP66468
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] 1. Changes for Tcg Ppi 1.2 support.
+// [Files] 1 TcgSmm.h
+// 2.TcgSmm.c
+// 3.Tcg_ppi1_2.asl
+// 4. AmiTcgNvflagsSample.c
+// 5. AmiTcgPlatformPeiLib.c
+// 6. AmiTcgPlatformDxe.sdl
+// 7. AmiTcgPlatformDxe.c
+//
+// 4 7/25/11 3:18a Fredericko
+// [TAG] EIP65177
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] TCG Ppi Sec ver 1.2 update
+//
+// 3 8/04/10 5:08p Fredericko
+//
+// 2 5/20/10 8:52a Fredericko
+// Added Header defined switches
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TCGSmm.h
+//
+// Description:
+// Header file for TCGSMM subcomponent
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCGSMM_H_
+#define _TCGSMM_H_
+
+#include <AmiDxeLib.h>
+#include <Protocol\SmmThunk.h>
+#include <Protocol\SmmBase.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\SmmSwDispatch.h>
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <HOB.h>
+#include "..\TCGMisc.h"
+
+
+#define AMI_TCG_PLATFORM_PROTOCOL_GUID\
+ {0x8c939604, 0x700, 0x4415, 0x9d, 0x62, 0x11, 0x61, 0xdb, 0x81, 0x64, 0xa6}
+
+EFI_GUID SwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+EFI_GUID SmmtcgefiOsVariableGuid = AMI_TCG_EFI_OS_VARIABLE_GUID;
+EFI_GUID SmmFlagsStatusguid = AMI_TCG_CONFIRMATION_FLAGS_GUID;
+extern EFI_GUID gEfiSmmBaseProtocolGuid;
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/TCGSmm/TCGSmm.mak b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.mak
new file mode 100644
index 0000000..37c7464
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.mak
@@ -0,0 +1,101 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.mak 1 4/21/14 2:18p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:18p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Common/TCGSmm/TCGSmm.mak $
+#
+# 1 4/21/14 2:18p Fredericko
+#
+# 2 12/10/13 12:57p Fredericko
+#
+# 1 10/08/13 12:05p Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 7/11/13 6:12p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20).
+#
+# 1 7/10/13 5:57p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+# 4 12/07/11 4:30p Fredericko
+# [TAG] EIP59683
+# [Category] Improvement
+# [Description] Allow selection between writing to SMI port as a word
+# or as a Byte.
+# Some platforms might require word writes to the SMI Status port.
+# [Files] Tcg.cif, Tcg.sdl, Tcg_ppi1_2_Ex.asl, TcgSmm.mak, TcgSmm.c
+#
+# 3 8/09/10 2:32p Fredericko
+#
+# 2 5/20/10 8:50a Fredericko
+# Included File Header
+# Included File Revision History
+# EIP 37653
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: TCGSmm.mak
+#
+# Description:
+# Make file for TCG SMM module
+#
+#<AMI_FHDR_END>
+#*************************************************************************
+all : TCGSmm
+
+TCGSmm : $(BUILD_DIR)\TCGSmm.mak TCGSmmBin
+
+$(BUILD_DIR)\TCGSmm.mak : $(TCGSmm_DIR)\TCGSmm.cif $(TCGSmm_DIR)\TCGSmm.mak $(BUILD_RULES)
+ $(CIF2MAK) $(TCGSmm_DIR)\TCGSmm.cif $(CIF2MAK_DEFAULTS)
+
+TcgSmmFlags=$(CFLAGS) \
+ /I$(TCG_DIR)\
+ /I$(TPM12_DIR)\
+ /I$(TCG_DIR)\Common\
+ /I$(PROJECT_DIR)\Include\Protocol\
+
+TCGSmmBin : $(AMIDXELIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TCGSmm.mak all\
+ "CFLAGS=$(TcgSmmFlags) "\
+ "CPFLAGS=$(TcgSmmFlags) "\
+ GUID=FD93F9E1-3C73-46e0-B7B8-2BBA3F718F6C\
+ ENTRY_POINT=TCGSmmInit\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#************************************************************************* \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/TCGSmm/TCGSmm.sdl b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.sdl
new file mode 100644
index 0000000..200ec4f
--- /dev/null
+++ b/Core/EM/TCG2/Common/TCGSmm/TCGSmm.sdl
@@ -0,0 +1,24 @@
+TOKEN
+ Name = "TCGSMM_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TCGSMM support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "TCGSmm_DIR"
+End
+
+MODULE
+ Help = "Includes TCGSMM.mak to Project"
+ File = "TCGSmm.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\TCGSmm.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/TcgCRBPei.c b/Core/EM/TCG2/Common/TcgCRBPei.c
new file mode 100644
index 0000000..02dff94
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgCRBPei.c
@@ -0,0 +1,537 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgCRBPei.c 3 4/21/14 3:45p Fredericko $
+//
+// $Revision: 3 $
+//
+// $Date: 4/21/14 3:45p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgCRBPei.c $
+//
+// 3 4/21/14 3:45p Fredericko
+//
+// 2 4/21/14 3:16p Fredericko
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 2 3/17/14 3:17p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:55p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name:
+//
+// Description:
+//
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TcgCommon.h"
+#include <AmiPeiLib.h>
+#include <Sha.h>
+#include <TcgMisc.h>
+#include <token.h>
+#include <TpmLib.h>
+#include <TcgPc.h>
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "Tpm20CRBLib.h"
+#include "PPI\CpuIo.h"
+#include "PPI\LoadFile.h"
+#include <FFS.h>
+#include "TcgPlatformSetupPeiPolicy.h"
+
+
+//*********************************************************************
+// GLOBAL DEFINITIONS
+//*********************************************************************
+EFI_GUID gEfiCrbPeiAmiTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+EFI_GUID gPeiCrbTcgPpiGuid = PEI_TCG_PPI_GUID;
+
+
+UINT8 GetHashPolicy(IN EFI_PEI_SERVICES **PeiServices);
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InternalPeiBuildHobGuid
+//
+// Description: Internal abstracted function to create a Hob
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_GUID *Guid,
+// IN UINTN DataLength,
+// OUT VOID **Hob
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS InternalPeiBuildHobGuid(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN DataLength,
+ OUT VOID **Hob )
+{
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->CreateHob(
+ PeiServices,
+ EFI_HOB_TYPE_GUID_EXTENSION,
+ (UINT16) ( sizeof (EFI_HOB_GUID_TYPE) + DataLength ),
+ Hob
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ PEI_TRACE((-1, PeiServices, "Hob created \n"));
+ ((EFI_HOB_GUID_TYPE*)(*Hob))->Name = *Guid;
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+EFIAPI CrbGetEventLog(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT TCG_LOG_HOB **EventLog )
+{
+ EFI_STATUS Status;
+ VOID *HobStart;
+
+ Status = (*PeiServices)->GetHobList( PeiServices, &HobStart );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ return GetNextGuidHob( &HobStart, &gEfiCrbPeiAmiTcgLogHobGuid, EventLog, NULL );
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcgPeiLogEvent
+//
+// Description: TCGPEI common function to Hash, Log and Extend data
+// using software SHA-1
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *Event,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI CrbTcgPeiLogEvent(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCG_PCR_EVENT *Event,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_LOG_HOB *TcgLog;
+
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(Event->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ Status = CrbGetEventLog( PeiServices, &TcgLog );
+ if ( EFI_ERROR( Status ))goto Exit;
+
+ Status = TcgCommonLogEvent(NULL,
+ (TCG_PCR_EVENT*)(TcgLog + 1),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ Event, 0);
+
+ if ( EFI_ERROR( Status ))goto Exit;
+
+ *EventNum = TcgLog->EventNum;
+ TcgLog->EventNum++;
+
+Exit:
+ return Status;
+}
+
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcgPeiHashLogExtendEventTpm
+//
+// Description: TCGPEI common function to Hash, Log and Extend data using TPM
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *HashData
+// IN HashDataLen
+// IN *NewEvent,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI CrbTcgPeiHashLogExtendEventTpm(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCG_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+CrbTpm20PeiExtend(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM2_PCRExtend_cmd_t Cmd;
+ TPM2_PCRExtend_res_t Res;
+ TPM2_PCRExtend_res_t Tmpres;
+ UINT32 CmdSize;
+ UINT8 *Buffer;
+ UINT8 *AuthSizeOffset;
+ UINT8 *ResultBuf = NULL;
+ UINT32 ResultBufSize = 0;
+ UINT32 DigestSize;
+ EFI_STATUS Status;
+
+ Cmd.Tag = (TPMI_ST_COMMAND_TAG)TPM_H2NS(TPM_ST_SESSIONS);
+ Cmd.CommandSize = TPM_H2NL(sizeof(Cmd));
+ Cmd.CommandCode = TPM_H2NL(TPM_CC_PCR_Extend);
+
+ Buffer = (UINT8 *)&Cmd.inputParameters;
+ *(UINT32 *)Buffer = TPM_H2NL(PcrIndex);
+ Buffer += sizeof(UINT32);
+
+ AuthSizeOffset = Buffer;
+ *(UINT32 *)Buffer = 0;
+ Buffer += sizeof(UINT32);
+
+ // pcr authHandle
+ *(UINT32 *)Buffer = TPM_H2NL(TPM_RS_PW);
+ Buffer += sizeof(UINT32);
+
+ // nonce = nullNonce
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // sessionAttributes = 0
+ *(UINT8 *)Buffer = 0;
+ Buffer += sizeof(UINT8);
+
+ // auth = nullAuth
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // authorizationSize
+ *(UINT32 *)AuthSizeOffset = TPM_H2NL((UINT32)(Buffer - AuthSizeOffset - sizeof(UINT32)));
+
+ //Digest count
+ *(UINT32 *)Buffer = TPM_H2NL(1);
+ Buffer += sizeof(UINT32);
+
+ //Hash alg
+ // Get the digest size based on Hash Alg
+ if(GetHashPolicy(PeiServices)==0){
+ //Hash alg
+ *(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA1);
+ Buffer += sizeof(UINT16);
+ DigestSize = 0x14;
+ TcgCommonCopyMem(NULL, Buffer, &Digest->digest, DigestSize);
+ }else{
+ //Hash alg
+ /**(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA256);
+ Buffer += sizeof(UINT16);
+ DigestSize = 0x20;
+ TcgCommonCopyMem(NULL, Buffer, &Digest->digestSha2, DigestSize);*/
+ return EFI_UNSUPPORTED;
+ }
+
+ Buffer += DigestSize;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.CommandSize = TPM_H2NL(CmdSize);
+
+ ResultBuf = (UINT8 *) &Tmpres;
+ ResultBufSize = sizeof(Res);
+
+
+ PEI_TRACE((-1, PeiServices, "OutputSizeBefore = %x \n", ResultBufSize));
+
+ Status = CrbSubmitCmd((UINT8 *)&Cmd, CmdSize, ResultBuf, &ResultBufSize);
+
+ PEI_TRACE((-1, PeiServices, "Status = %r \n", Status));
+ PEI_TRACE((-1, PeiServices, "OutputSizeAfter = %x \n", ResultBufSize));
+
+ return Status;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiHashLogExtendEventSW
+// Description: TCGPEI Software function to Hash, Log and Extend data
+// using software SHA-1
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *HashData
+// IN HashDataLen
+// IN OUT *NewEvent,
+// OUT *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS CrbTcgPeiHashLogExtendEventSW(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCG_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status;
+ TCG_DIGEST NewPCRValue;
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(NewEvent->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ if(GetHashPolicy(PeiServices)==0)
+ {
+ Status = SHA1HashAll( NULL, HashData, HashDataLen, &NewEvent->Digest );
+ if ( EFI_ERROR( Status )){
+ PEI_TRACE((-1, PeiServices, "SHA1HashAll fail %r \n", Status));
+ return Status;
+ }
+ }else if(GetHashPolicy(PeiServices)==1){
+ /* Status = SHA2HashAll( NULL, HashData, HashDataLen, &NewEvent->Digest);
+ if ( EFI_ERROR( Status )){
+ PEI_TRACE((-1, PeiServices, "SHA1HashAll fail %r \n", Status));
+ return Status;
+ }*/
+ }
+
+ Status = CrbTpm20PeiExtend(
+ PeiServices,
+ NewEvent->PCRIndex,
+ &NewEvent->Digest,
+ &NewPCRValue );
+
+ if ( EFI_ERROR( Status )){
+ PEI_TRACE((-1, PeiServices, "CrbTpm20PeiExtend fail %r \n", Status));
+ goto Exit;
+ }
+
+ Status = CrbTcgPeiLogEvent( This, PeiServices, NewEvent, EventNum );
+ PEI_TRACE((-1, PeiServices, "CrbTcgPeiLogEvent fail %r \n", Status));
+
+Exit:
+ return Status;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiPassThroughToTpm
+//
+// Description: TCGPEI common function to abstract passing commands to the TPM
+// FIFO
+//
+// Input: IN *This
+// IN **PeiServices
+// IN TpmInputParameterBlockSize
+// IN *TpmInputParameterBlock
+// IN TpmOutputParameterBlockSize
+// IN *TpmOutputParameterBlock
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI CrbTcgPeiPassThroughToTpm(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock )
+{
+ UINT32 Size = 0;
+ EFI_STATUS Status;
+ Size = TpmOutputParameterBlockSize;
+
+ PEI_TRACE((-1, PeiServices, "CrbTcgPeiPassThroughToTpm Execution \n"));
+
+ PEI_TRACE((-1, PeiServices, "OutputSizeBefore = %x \n", Size));
+
+ Status = CrbSubmitCmd(TpmInputParameterBlock,
+ TpmInputParameterBlockSize,
+ TpmOutputParameterBlock,
+ &Size);
+
+ PEI_TRACE((-1, PeiServices, "Status = %r \n", Status));
+ PEI_TRACE((-1, PeiServices, "OutputSizeAfter = %x \n", Size));
+ return Status;
+}
+
+
+static PEI_TCG_PPI mTcgPpi = {
+ CrbTcgPeiHashLogExtendEventSW,
+ CrbTcgPeiLogEvent,
+ CrbTcgPeiPassThroughToTpm
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mTcgPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiCrbTcgPpiGuid,
+ &mTcgPpi
+ }
+};
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: Tpm20CrbEntry
+//
+// Description:
+//
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI Tpm20CrbEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ TCG_LOG_HOB *TcgLog;
+ EFI_HOB_GUID_TYPE *Hob;
+
+ if(!isTpm20CrbPresent())return EFI_NOT_FOUND;
+ Status = InternalPeiBuildHobGuid(PeiServices, &gEfiCrbPeiAmiTcgLogHobGuid,
+ (sizeof (*TcgLog) + 0x200), & Hob);
+
+ PEI_TRACE((-1, PeiServices, "CrbBuild Hob Status = %r \n", Status));
+
+ TcgLog = (TCG_LOG_HOB*)(Hob + 1);
+ (*PeiServices)->SetMem( TcgLog, sizeof (*TcgLog), 0 );
+ TcgLog->TableMaxSize = 0x200;
+ Status = (*PeiServices)->InstallPpi( PeiServices, mTcgPpiList );
+ return Status;
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/TcgDxe.c b/Core/EM/TCG2/Common/TcgDxe.c
new file mode 100644
index 0000000..84a1e4d
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgDxe.c
@@ -0,0 +1,2187 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgDxe.c
+
+ Abstract:
+
+ DXE Driver that provides TCG services
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe.c 3 6/14/14 12:28a Fredericko $
+//
+// $Revision: 3 $
+//
+// $Date: 6/14/14 12:28a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe.c $
+//
+// 3 6/14/14 12:28a Fredericko
+//
+// 2 6/09/14 4:50p Fredericko
+// Changes for SetVariable vulnerability during Runtime
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 4 3/17/14 3:19p Fredericko
+//
+// 3 3/14/14 3:22p Fredericko
+//
+// 2 3/11/14 6:37p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 2:00p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 37 10/30/12 11:18a Fredericko
+//
+// 36 10/08/12 10:02a Fredericko
+// [TAG] EIP90986
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System Hang
+// [RootCause] We tried to measure an unexpected FV if FV_MAIN was not
+// found.
+// [Solution] Verify we found FV_MAIN before trying to measure.
+// [Files] TcgDxe.c
+//
+// 35 5/21/12 11:44a Fredericko
+// Changes for x32 bit build for TCG
+//
+// 34 5/18/12 6:06p Fredericko
+// Type cast size to UINTN for x64 and x32 bit builds
+//
+// 33 5/09/12 6:37p Fredericko
+// Tcm changes. For Win Server 8 and reboot test failure.
+//
+// 32 4/28/12 3:26p Fredericko
+// If PPI request comes in and VGA and USB enumeration is disabled Ppi
+// request cannot be dispalyed or executed. So Abort Fastboot when Ppi
+// request comes in.
+//
+// 31 4/27/12 6:06p Fredericko
+// Measurement of FWVol Changed.
+//
+// 30 3/19/12 6:30p Fredericko
+// [TAG] EIP82769
+// [Category] Improvement
+// [Description] Firmware updates disable the TPM when Firmware update
+// is done
+// Changes for Tcg Performance Metrics Improvement.
+// [Files] EIP82769: xTcgPei.c, TcgDxe.c, xTcgDxe,c
+// Performance: Files Changed: Tcg.sdl, TcgMisc.h, TcgDxe.c, TcgCommon.c,
+// TcgCommon.h,
+// AmiTcgPlatformPeiLib.c, AmiTcgPlatformDxe.c, TcgDxe.dxs
+//
+// 29 2/03/12 5:17p Fredericko
+// [TAG] EIP81665
+// [Category] Improvement
+// [Description] Support for MOR feature improvement
+// [Files] Tcg.sdl, AmiTcgPlatformDxe.c, Tcgdxe.c, Tcglegacy.c
+//
+// 28 11/14/11 1:31p Fredericko
+// Changes for Tcgprotocol interface. Function is currently not used.
+//
+// 27 8/26/11 1:07p Fredericko
+// Fastboot Changes.
+//
+// 26 8/09/11 6:16p Fredericko
+// [TAG] EIP66465
+// [Category] Improvement
+// [Description] 1. Added support to remove EFI_EV_ACTION from the TCG
+// logs if customer wants.
+// [Files] 1. Tcgdxe.c
+// 2. Tcgpei.c
+// 3. Tcg.sdl
+//
+// 25 4/22/11 8:51p Fredericko
+// Changes for build in x32 bit mode.
+//
+// 24 4/04/11 1:58p Fredericko
+// Removed #pragma optimization directives
+//
+// 23 4/01/11 9:37a Fredericko
+// Updated function Header
+//
+// 22 3/29/11 1:12p Fredericko
+//
+// 21 3/28/11 2:19p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 20 5/19/10 5:36p Fredericko
+// Included File Header
+// Included File Revision History
+// Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgDxe.c
+//
+// Description:
+// Abstracted functions for Tcg protocol are defined here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "TcgCommon.h"
+#include <sha.h>
+#include <TcgMisc.h>
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Runtime.h>
+#include <AmiPeiLib.h>
+#include "protocol\TcgService\TcgTcmService.h"
+#include "TcgPlatformSetupPolicy.h"
+#include <AcpiSupport.h>
+#include "TcgPc.h"
+#include "protocol\TcgService\TcgService.h"
+#include "protocol\TpmDevice\TpmDevice.h"
+
+#if PI_SPECIFICATION_VERSION<0x00010000
+#include <Protocol\FirmwareVolume.h>
+#else
+#include <Protocol\FirmwareVolume2.h>
+#endif
+
+
+EFI_GUID gEfiAmiDTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+
+UINT8 GetHashPolicy();
+
+#pragma pack (1)
+typedef struct
+{
+ EFI_PHYSICAL_ADDRESS PostCodeAddress;
+ #if x64_BUILD
+ UINT64 PostCodeLength;
+ #else
+ UINTN PostCodeLength;
+ #endif
+} EFI_TCG_EV_POST_CODE;
+
+typedef struct
+{
+ EFI_TCG_PCR_EVENT_HEADER Header;
+ EFI_TCG_EV_POST_CODE Event;
+} PEI_EFI_POST_CODE;
+
+#pragma pack()
+
+
+typedef struct _TCG_DXE_PRIVATE_DATA
+{
+ EFI_TCG_PROTOCOL TcgServiceProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+} TCG_DXE_PRIVATE_DATA;
+
+
+typedef struct _TCM_DXE_PRIVATE_DATA
+{
+ EFI_TCM_PROTOCOL TcgServiceProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+} TCM_DXE_PRIVATE_DATA;
+
+
+
+EFI_STATUS EFIAPI TcgDxeLogEvent (
+ IN EFI_TCG_PROTOCOL *This,
+ IN TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ IN UINT32 Flags );
+
+EFI_STATUS EFIAPI TcmDxeLogEvent(
+ IN EFI_TCM_PROTOCOL *This,
+ IN TCM_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ IN UINT32 Flags );
+
+EFI_STATUS
+__stdcall Tcg20CommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue,
+ IN UINT8 DigestSize );
+
+BOOLEAN IsTpm20Device();
+UINTN FindNextLogLocation(TCG_PCR_EVENT_HDR *TcgLog, UINTN EventNum);
+
+EFI_GUID gEfiTcgCapHobGuid = EFI_TCG_CAP_HOB_GUID;
+static UINTN TcmBootVar = 0;
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmBootDone
+//
+// Description: SetEfiOSTransitions
+//
+// Input: IN EFI_EVENT efiev
+// IN VOID *ctx
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+void TcmBootDone(
+ IN EFI_EVENT efiev,
+ IN VOID *ctx )
+{
+ TcmBootVar = 1;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EfiOSReadyToBoot
+//
+// Description: Sets ready to boot callback on ready to boot
+//
+// Input: NONE
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcmOSTransition()
+{
+ EFI_EVENT ReadToBootEvent;
+ EFI_STATUS Status;
+
+ #if defined(EFI_EVENT_SIGNAL_READY_TO_BOOT)\
+ && EFI_SPECIFICATION_VERSION < 0x20000
+
+ Status = pBS->CreateEvent( EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ EFI_TPL_CALLBACK,
+ TcmBootDone, NULL, &ReadToBootEvent );
+
+ #else
+ Status = CreateReadyToBootEvent( EFI_TPL_CALLBACK,
+ TcmBootDone,
+ NULL,
+ &ReadToBootEvent );
+ #endif
+
+ return Status;
+}
+
+
+#define _CR( Record, TYPE,\
+ Field )((TYPE*) ((CHAR8*) (Record) - (CHAR8*) &(((TYPE*) 0)->Field)))
+
+#define TCG_DXE_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TCG_DXE_PRIVATE_DATA, TcgServiceProtocol )
+
+#define TCM_DXE_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TCM_DXE_PRIVATE_DATA, TcgServiceProtocol )
+
+
+TCG_ACPI_TABLE mTcgAcpiTableTemplate = {
+ {
+ EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE,
+ sizeof (TCG_ACPI_TABLE)
+ //
+ // Compiler initializes the remaining bytes to 0
+ // These fields should be filled in in production
+ //
+ },
+ 0,
+ TPM_LOG_AREA_MAX_LEN,
+ (EFI_PHYSICAL_ADDRESS)( -1 )
+};
+
+static TPM_Capabilities_PermanentFlag TcgDxe_Cap;
+
+EFI_STATUS
+__stdcall TcgCommonPassThrough(
+ IN VOID *Context,
+ IN UINT32 NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINT32 NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ TCG_DXE_PRIVATE_DATA *Private;
+ EFI_STATUS Status;
+
+ Private = TCG_DXE_PRIVATE_DATA_FROM_THIS( Context );
+
+ Status = Private->TpmDevice->Init( Private->TpmDevice );
+
+ TRACE(( TRACE_ALWAYS,"TcgDxePassThroughToTpm Init Status = %r \n", Status));
+
+ Status= Private->TpmDevice->Transmit(
+ Private->TpmDevice,
+ NoInputBuffers,
+ InputBuffers,
+ NoOutputBuffers,
+ OutputBuffers
+ );
+
+ TRACE(( TRACE_ALWAYS,"TcgDxePassThroughToTpm Transmit Status = %r \n", Status));
+
+ Private->TpmDevice->Close( Private->TpmDevice );
+
+ return Status;
+
+}
+
+
+EFI_STATUS EFIAPI TcgDxePassThroughToTpm(
+ IN EFI_TCG_PROTOCOL *This,
+ IN UINT32 TpmInputParamterBlockSize,
+ IN UINT8 *TpmInputParamterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock )
+{
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+ EFI_STATUS Status;
+ TCG_DXE_PRIVATE_DATA *Private;
+
+ //some applications might not set init command before making this call.
+ //Just set init commands[locality zero for them]
+ Private = TCG_DXE_PRIVATE_DATA_FROM_THIS( This );
+ Status = Private->TpmDevice->Init( Private->TpmDevice );
+
+ TRACE(( TRACE_ALWAYS,"TcgDxePassThroughToTpm Init Status = %r \n", Status));
+
+ InBuffer[0].Buffer = TpmInputParamterBlock;
+ InBuffer[0].Size = TpmInputParamterBlockSize;
+ OutBuffer[0].Buffer = TpmOutputParameterBlock;
+ OutBuffer[0].Size = TpmOutputParameterBlockSize;
+
+ Status= Private->TpmDevice->Transmit(
+ Private->TpmDevice,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer);
+
+ TRACE(( TRACE_ALWAYS,"TcgDxePassThroughToTpm Transmit Status = %r \n", Status));
+
+ Private->TpmDevice->Close( Private->TpmDevice );
+
+ TRACE(( TRACE_ALWAYS,"TcgDxePassThroughToTpm Close Status = %r \n", Status));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+__stdcall TcgDxeCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_HEADER cmdHeader;
+ TPM_1_2_RET_HEADER retHeader;
+ TPM_TRANSMIT_BUFFER InBuffer[3], OutBuffer[2];
+ BOOLEAN Sha2 = TRUE;
+
+ if(IsTpm20Device()){
+ TRACE(( TRACE_ALWAYS,"Tpm20 Extend Status \n"));
+
+ if(GetHashPolicy()==0){
+ return(Tcg20CommonExtend(NULL, PCRIndex, Digest, NewPCRValue, 20));
+ }else{
+ return(Tcg20CommonExtend((VOID *)&Sha2, PCRIndex, Digest, NewPCRValue,32));
+ }
+ }
+
+ TRACE(( TRACE_ALWAYS,"Tpm1_2 Extend Status \n"));
+ InBuffer[0].Buffer = &cmdHeader;
+ InBuffer[0].Size = sizeof (cmdHeader);
+ InBuffer[1].Buffer = &PCRIndex;
+ InBuffer[1].Size = sizeof (PCRIndex);
+ InBuffer[2].Buffer = Digest->digest;
+ InBuffer[2].Size = sizeof (Digest->digest);
+
+ OutBuffer[0].Buffer = &retHeader;
+ OutBuffer[0].Size = sizeof (retHeader);
+ OutBuffer[1].Buffer = NewPCRValue->digest;
+ OutBuffer[1].Size = sizeof (NewPCRValue->digest);
+
+ cmdHeader.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdHeader.ParamSize = TPM_H2NL(sizeof (cmdHeader)
+ + sizeof (PCRIndex) + sizeof (Digest->digest));
+
+ cmdHeader.Ordinal = TPM_H2NL( TPM_ORD_Extend );
+ PCRIndex = TcgCommonH2NL( PCRIndex );
+
+ return TcgCommonPassThrough( CallbackContext,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer);
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmCommonPassThrough
+//
+// Description: Helper function for TCM transmit command
+//
+// Input: VOID *Context
+// UINT32 NoInputBuffers
+// TPM_TRANSMIT_BUFFER InputBuffers
+// UINT32 NoOutputBuffers
+// TPM_TRANSMIT_BUFFER OutputBuffers
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+__stdcall TcmCommonPassThrough(
+ IN VOID *Context,
+ IN UINT32 NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINT32 NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ TCM_DXE_PRIVATE_DATA *Private;
+
+ Private = TCM_DXE_PRIVATE_DATA_FROM_THIS( Context );
+ return Private->TpmDevice->Transmit(
+ Private->TpmDevice,
+ NoInputBuffers,
+ InputBuffers,
+ NoOutputBuffers,
+ OutputBuffers
+ );
+}
+
+
+EFI_STATUS EFIAPI TcgDxeStatusCheck(
+ IN EFI_TCG_PROTOCOL *This,
+ OUT TCG_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability,
+ OUT UINT32 *TCGFeatureFlags,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *LastEvent )
+{
+ TCG_LOG_HOB *TcgLog;
+ TCG_PCR_EVENT *EventStart;
+ UINTN Index;
+
+ if ( ProtocolCapability != NULL )
+ {
+ pBS->SetMem( ProtocolCapability, sizeof (*ProtocolCapability), 0 );
+ ProtocolCapability->Size = sizeof (TCG_EFI_BOOT_SERVICE_CAPABILITY);
+ ProtocolCapability->StructureVersion.Major = TCG_SPEC_VERSION_MAJOR;
+ ProtocolCapability->StructureVersion.Minor = TCG_SPEC_VERSION_MINOR;
+ ProtocolCapability->StructureVersion.RevMajor = 0;
+ ProtocolCapability->StructureVersion.RevMinor = 0;
+ ProtocolCapability->ProtocolSpecVersion.Major = TCG_SPEC_VERSION_MAJOR;
+ ProtocolCapability->ProtocolSpecVersion.Minor = TCG_SPEC_VERSION_MINOR;
+ ProtocolCapability->ProtocolSpecVersion.RevMajor = 0;
+ ProtocolCapability->ProtocolSpecVersion.RevMinor = 0;
+ ProtocolCapability->HashAlgorithmBitmap = 1; // SHA-1
+ ProtocolCapability->TPMPresentFlag = 1; // TPM is present.
+ ProtocolCapability->TPMDeactivatedFlag = TcgDxe_Cap.deactivated;
+ }
+
+ if ( TCGFeatureFlags != NULL )
+ {
+ *TCGFeatureFlags = 0;
+ }
+
+ EventStart = (TCG_PCR_EVENT*)(UINTN)mTcgAcpiTableTemplate.LogStart;
+ TcgLog = (TCG_LOG_HOB*)EventStart;
+ TcgLog--;
+
+
+ if ( EventLogLocation != NULL )
+ {
+ *EventLogLocation
+ = (EFI_PHYSICAL_ADDRESS)( UINTN ) mTcgAcpiTableTemplate.LogStart;
+ }
+
+ if ( LastEvent != NULL )
+ {
+ if ( TcgLog->EventNum == 0 )
+ {
+ *LastEvent = 0;
+ }
+ else {
+ Index = TcgLog->EventNum;
+ *LastEvent = (EFI_PHYSICAL_ADDRESS)( UINTN )FindNextLogLocation((TCG_PCR_EVENT_HDR *)mTcgAcpiTableTemplate.LogStart,
+ (TcgLog->EventNum - 1));
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgTcmDxeStatusCheck
+//
+// Description: Tcm Dxe status check function
+//
+// Input: IN EFI_TCM_PROTOCOL *This,
+// OUT TCM_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability,
+// OUT UINT32 *TCGFeatureFlags,
+// OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+// OUT EFI_PHYSICAL_ADDRESS *LastEvent
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS EFIAPI TcgTcmDxeStatusCheck(
+ IN EFI_TCM_PROTOCOL *This,
+ OUT TCM_EFI_BOOT_SERVICE_CAPABILITY *ProtocolCapability,
+ OUT UINT32 *TCGFeatureFlags,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *LastEvent )
+{
+ TCG_LOG_HOB *TcgLog;
+ TCM_PCR_EVENT *EventStart;
+ UINTN Index;
+
+ if((AutoSupportType()) && (TcmBootVar == 1)){
+ pBS->SetMem( ProtocolCapability, sizeof (TCM_EFI_BOOT_SERVICE_CAPABILITY), 0 );
+ if ( TCGFeatureFlags != NULL )*TCGFeatureFlags = 0;
+ if ( LastEvent != NULL )*LastEvent = 0;
+ return EFI_UNSUPPORTED;
+ }
+
+ if ( ProtocolCapability != NULL )
+ {
+ pBS->SetMem( ProtocolCapability, sizeof (*ProtocolCapability), 0 );
+ ProtocolCapability->Size = sizeof (TCG_EFI_BOOT_SERVICE_CAPABILITY);
+ ProtocolCapability->StructureVersion.Major = TCG_SPEC_VERSION_MAJOR;
+ ProtocolCapability->StructureVersion.Minor = TCG_SPEC_VERSION_MINOR;
+ ProtocolCapability->StructureVersion.RevMajor = 0;
+ ProtocolCapability->StructureVersion.RevMinor = 0;
+ ProtocolCapability->ProtocolSpecVersion.Major = TCG_SPEC_VERSION_MAJOR;
+ ProtocolCapability->ProtocolSpecVersion.Minor = TCG_SPEC_VERSION_MINOR;
+ ProtocolCapability->ProtocolSpecVersion.RevMajor = 0;
+ ProtocolCapability->ProtocolSpecVersion.RevMinor = 0;
+ ProtocolCapability->HashAlgorithmBitmap = 1; // SHA-1
+ ProtocolCapability->TPMPresentFlag = 1; // TPM is present.
+ ProtocolCapability->TPMDeactivatedFlag = TcgDxe_Cap.deactivated;
+ }
+
+ if ( TCGFeatureFlags != NULL )
+ {
+ *TCGFeatureFlags = 0;
+ }
+
+ EventStart = (TCM_PCR_EVENT*)(UINTN)mTcgAcpiTableTemplate.LogStart;
+ TcgLog = (TCG_LOG_HOB*)EventStart;
+ TcgLog--;
+
+ if ( EventLogLocation != NULL )
+ {
+ *EventLogLocation
+ = (EFI_PHYSICAL_ADDRESS)( UINTN ) mTcgAcpiTableTemplate.LogStart;
+ }
+
+ if ( LastEvent != NULL )
+ {
+ if ( TcgLog->EventNum == 0 )
+ {
+ *LastEvent = 0;
+ }
+ else {
+ Index = TcgLog->EventNum;
+
+ do
+ {
+ *LastEvent = (EFI_PHYSICAL_ADDRESS)( UINTN ) EventStart;
+ EventStart = (TCM_PCR_EVENT*)(UINTN)(
+ *LastEvent
+ + _TPM_STRUCT_PARTIAL_SIZE( TCM_PCR_EVENT, Event[ 0] )
+ + EventStart->EventSize
+ );
+ } while ( --Index > 0 );
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+
+
+EFI_STATUS EFIAPI TcgDxeHashAll(
+ IN EFI_TCG_PROTOCOL *This,
+ IN UINT8 *HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT UINT64 *HashedDataLen,
+ IN OUT UINT8 **HashedDataResult )
+{
+ if ( AlgorithmId != TCG_ALG_SHA )
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ( *HashedDataResult == NULL || *HashedDataLen == 0 )
+ {
+ *HashedDataLen = sizeof (TCG_DIGEST);
+ pBS->AllocatePool( EfiBootServicesData,
+ (UINTN)*HashedDataLen,
+ HashedDataResult );
+
+ if ( *HashedDataResult == NULL )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ return SHA1HashAll(
+ This,
+ (VOID*)(UINTN)HashData,
+ (UINTN)HashDataLen,
+ (TCG_DIGEST*)*HashedDataResult);
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmDxeHashAll
+//
+// Description: TcmDxeHashAll function [SHA1]
+//
+// Input: IN EFI_TCG_PROTOCOL *This,
+// IN UINT8 *HashData,
+// IN UINT64 HashDataLen,
+// IN TCG_ALGORITHM_ID AlgorithmId,
+// IN OUT UINT64 *HashedDataLen,
+// IN OUT UINT8 **HashedDataResult
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS EFIAPI TcmDxeHashAll(
+ IN EFI_TCM_PROTOCOL *This,
+ IN UINT8 *HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT UINT64 *HashedDataLen,
+ IN OUT UINT8 **HashedDataResult )
+{
+
+ if((AutoSupportType()) && (TcmBootVar == 1)){
+ return EFI_UNSUPPORTED;
+ }
+
+ if ( AlgorithmId != TCG_ALG_SHA )
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ( *HashedDataResult == NULL || *HashedDataLen == 0 )
+ {
+ *HashedDataLen = sizeof (TCG_DIGEST);
+ pBS->AllocatePool( EfiBootServicesData,
+ (UINTN)*HashedDataLen,
+ HashedDataResult );
+
+ if ( *HashedDataResult == NULL )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ return SHA1HashAll(
+ This,
+ (VOID*)(UINTN)HashData,
+ (UINTN)HashDataLen,
+ (TCG_DIGEST*)*HashedDataResult);
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgDxeHashLogExtendEventTpm
+//
+// Description: TcgDxe common function to Hash, Log and Extend data using TPM
+//
+// Input: *This
+// *HashData
+// HashDataLen
+// AlgorithmId,
+// *TCGLogData,
+// *EventNum,
+// *EventLogLastEntry
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals: TcgCommonSha1Start, TcgCommonSha1Start, TcgCommonSha1CompleteExtend
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgDxeHashLogExtendEventTpm(
+ IN EFI_TCG_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNum,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry )
+{
+ EFI_STATUS Status;
+ UINT32 Sha1MaxBytes;
+ TCG_DIGEST NewPCRValue;
+ TCG_DXE_PRIVATE_DATA *Private;
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(TCGLogData->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ Private = TCG_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+ Status = Private->TpmDevice->Init( Private->TpmDevice );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE(( TRACE_ALWAYS,"Private->TpmDevice Status = %r \n", Status));
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Start( This, TCG_ALG_SHA, &Sha1MaxBytes );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE(( TRACE_ALWAYS,"TcgCommonSha1Start Status = %r \n", Status));
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Update(
+ This,
+ (UINT8 *)HashData,
+ (UINT32)HashDataLen,
+ Sha1MaxBytes
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE(( TRACE_ALWAYS,"TcgCommonSha1Update Status = %r \n", Status));
+ goto Exit;
+ }
+
+#if defined(TCG_DEBUG_MODE) && (TCG_DEBUG_MODE == 1)
+ HashData += (UINTN)(HashDataLen & ~63);
+ HashDataLen &= 63;
+#else
+ HashData += (HashDataLen & ~63);
+ HashDataLen &= 63;
+#endif
+
+ Status = TcgCommonSha1CompleteExtend(
+ This,
+ (UINT8 *)HashData,
+ (UINT32)HashDataLen,
+ TCGLogData->PCRIndex,
+ &TCGLogData->Digest,
+ &NewPCRValue
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE(( TRACE_ALWAYS,"TcgCommonSha1CompleteExtend Status = %r \n", Status));
+ goto Exit;
+ }
+
+ Status = TcgDxeLogEvent( This, TCGLogData, EventNum, 1 );
+ TRACE(( TRACE_ALWAYS,"TcgDxeLogEvent Status = %r \n", Status));
+
+Exit:
+ Private->TpmDevice->Close( Private->TpmDevice );
+ return Status;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgDxeHashLogExtendEventTcm
+//
+// Description: TcgDxe common function to Hash, Log and Extend data using TPM
+//
+// Input: *This
+// *HashData
+// HashDataLen
+// AlgorithmId,
+// *TCGLogData,
+// *EventNum,
+// *EventLogLastEntry
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals: TcgCommonSha1Start, TcgCommonSha1Start, TcgCommonSha1CompleteExtend
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgDxeHashLogExtendEventTcm(
+ IN EFI_TCM_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCM_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNum,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry )
+{
+ EFI_STATUS Status;
+ UINT32 Sha1MaxBytes;
+ TCM_DIGEST NewPCRValue;
+ TCM_DXE_PRIVATE_DATA *Private;
+
+ Private = TCM_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+ if((AutoSupportType()) && (TcmBootVar == 1)){
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = TcgCommonSha1Start( This, TCG_ALG_SHA, &Sha1MaxBytes );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Update(
+ This,
+ (UINT8 *)HashData,
+ (UINT32)HashDataLen,
+ Sha1MaxBytes
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ HashData += (HashDataLen & ~63);
+ HashDataLen &= 63;
+
+ Status = TcmCommonSha1CompleteExtend(
+ This,
+ (UINT8 *)HashData,
+ (UINT32)HashDataLen,
+ TCGLogData->PCRIndex,
+ &TCGLogData->Digest,
+ &NewPCRValue
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcmDxeLogEvent( This, TCGLogData, EventNum, 1 );
+
+Exit:
+ return Status;
+}
+
+#pragma optimize("",off)
+
+VOID
+EFIAPI
+PrintBuffer(IN UINT8 *Buffer, IN UINT32 BufferSize)
+{
+ UINT32 Index;
+
+ TRACE(( TRACE_ALWAYS, "Buffer Address: 0x%08x, Size: 0x%08x, Value:\n", Buffer, BufferSize));
+ for(Index = 0; Index < BufferSize; Index++){
+ TRACE(( TRACE_ALWAYS, "%02x ", *(Buffer + Index)));
+ if((Index+1) % 16 == 0) TRACE(( TRACE_ALWAYS, "\n"));
+ }
+ TRACE(( TRACE_ALWAYS, "\n"));
+}
+
+
+EFI_STATUS
+__stdcall TcgDxeCommonLogEvent(
+ IN VOID *CallbackContext,
+ IN TCG_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCG_PCR_EVENT *NewEntry,
+ IN UINT8 HashAlgorithm )
+{
+ UINT32 TempSize;
+
+ //protect Tcglog from possible overflow log operation
+ if(NewEntry->EventSize > ((UINT32)(~0) - sizeof(EFI_TCG_PCR_EVENT_HEADER))){
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ TempSize = sizeof(TCG_PCR_EVENT)-sizeof(NewEntry->Digest) - sizeof(UINT32)-1;
+
+ TcgCommonCopyMem( CallbackContext, EvtLog, NewEntry, TempSize );
+
+ PrintBuffer((UINT8 *)NewEntry, 0x50);
+
+ TRACE(( TRACE_ALWAYS,"CopyMem 1 \n"));
+
+ if(HashAlgorithm == 0){
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->Digest.digest, sizeof(NewEntry->Digest.digest) );
+ TempSize+=sizeof(NewEntry->Digest.digest);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->EventSize, sizeof(UINT32));
+ TempSize+=sizeof(UINT32);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), NewEntry->Event, NewEntry->EventSize);
+ }else{
+ /*TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->Digest.digestSha2, sizeof(NewEntry->Digest.digestSha2) );
+ TempSize+=sizeof(NewEntry->Digest.digestSha2);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->EventSize, sizeof(UINT32));
+ TempSize+=sizeof(UINT32);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), NewEntry->Event, NewEntry->EventSize);
+ */
+ }
+
+ *TableSize += (TempSize + NewEntry->EventSize);
+ return EFI_SUCCESS;
+}
+#pragma optimize("",on)
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgDxeLogEvent
+//
+// Description: Logs TCG events in DXE
+//
+// Input: IN EFI_TCG_PROTOCOL *This,
+// IN TCG_PCR_EVENT *TCGLogData,
+// IN OUT UINT32 *EventNumber,
+// IN UINT32 Flags
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+#pragma optimize("",off)
+EFI_STATUS EFIAPI TcgDxeLogEvent(
+ IN EFI_TCG_PROTOCOL *This,
+ IN TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ IN UINT32 Flags )
+{
+ EFI_STATUS Status;
+ TCG_LOG_HOB *TcgLog;
+ TCG_DXE_PRIVATE_DATA *Private;
+ TCG_DIGEST NewPCR;
+ UINTN NextLocation;
+ UINT8 HashAlgo = GetHashPolicy();
+
+
+ Private = TCG_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(TCGLogData->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ Status = EFI_SUCCESS;
+
+ if ( !(Flags & (UINT32)(0x1)))
+ {
+ TRACE((TRACE_ALWAYS, "Flags = %x \n", Flags));
+ Status = Private->TpmDevice->Init( Private->TpmDevice );
+
+ TRACE((TRACE_ALWAYS, "Private->TpmDevice->Init = %r \n", Status));
+
+ if ( !EFI_ERROR( Status ))
+ {
+ Status = TcgDxeCommonExtend(
+ This,
+ TCGLogData->PCRIndex,
+ &TCGLogData->Digest,
+ &NewPCR
+ );
+
+ TRACE((TRACE_ALWAYS, "TcgDxeCommonExtend Status = %r \n", Status));
+ }
+ Private->TpmDevice->Close( Private->TpmDevice );
+ }
+
+ if ( !TcgDxe_Cap.deactivated )
+ {
+ TcgLog = (TCG_LOG_HOB*)(UINTN)mTcgAcpiTableTemplate.LogStart;
+ TcgLog--;
+
+ if ( !EFI_ERROR( Status ))
+ {
+ NextLocation = FindNextLogLocation((TCG_PCR_EVENT_HDR*)(TcgLog + 1), TcgLog->EventNum);
+
+ Status = TcgDxeCommonLogEvent(
+ This,
+ (TCG_PCR_EVENT*)(NextLocation),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ TCGLogData, HashAlgo);
+
+
+ if ( !EFI_ERROR( Status ))
+ {
+ TcgLog->EventNum++;
+ *EventNumber = TcgLog->EventNum;
+ }
+ }
+ }
+ return Status;
+}
+#pragma optimize("",on)
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmDxeLogEvent
+//
+// Description: Logs TCM events in DXE
+//
+// Input: IN EFI_TCG_PROTOCOL *This,
+// IN TCG_PCR_EVENT *TCGLogData,
+// IN OUT UINT32 *EventNumber,
+// IN UINT32 Flags
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS EFIAPI TcmDxeLogEvent(
+ IN EFI_TCM_PROTOCOL *This,
+ IN TCM_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ IN UINT32 Flags )
+{
+ EFI_STATUS Status;
+ TCG_LOG_HOB *TcgLog;
+ TCM_DXE_PRIVATE_DATA *Private;
+ TCM_DIGEST NewPCR;
+
+ Private = TCM_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+ if((AutoSupportType()) && (TcmBootVar == 1)){
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = EFI_SUCCESS;
+
+ if ( !(Flags & 1))
+ {
+ if ( !EFI_ERROR( Status ))
+ {
+ Status = TcmCommonExtend(
+ This,
+ TCGLogData->PCRIndex,
+ &TCGLogData->Digest,
+ &NewPCR);
+ }
+ }
+
+ if ( !TcgDxe_Cap.deactivated )
+ {
+ TcgLog = (TCG_LOG_HOB*)(UINTN)mTcgAcpiTableTemplate.LogStart;
+ TcgLog--;
+
+ if ( !EFI_ERROR( Status ))
+ {
+ Status = TcmCommonLogEvent(
+ This,
+ (TCM_PCR_EVENT*)(TcgLog + 1),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ TCGLogData
+ );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ TcgLog->EventNum++;
+ *EventNumber = TcgLog->EventNum;
+ }
+ }
+ }
+ return Status;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgDxePassThroughToTcm
+//
+// Description: Helper function for TCM transmit function
+//
+// Input: IN EFI_TCM_PROTOCOL *This,
+// IN UINT32 TpmInputParamterBlockSize,
+// IN UINT8 *TpmInputParamterBlock,
+// IN UINT32 TpmOutputParameterBlockSize,
+// IN UINT8 *TpmOutputParameterBlock
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS EFIAPI TcgDxePassThroughToTcm(
+ IN EFI_TCM_PROTOCOL *This,
+ IN UINT32 TpmInputParamterBlockSize,
+ IN UINT8 *TpmInputParamterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock )
+{
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+ EFI_STATUS Status;
+ TCM_DXE_PRIVATE_DATA *Private;
+
+ //some applications might not set init command before making this call.
+ //Just set init commands[locality zero for them]
+ Private = TCM_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+ if((AutoSupportType()) && (TcmBootVar == 1)){
+ return EFI_UNSUPPORTED;
+ }
+
+ InBuffer[0].Buffer = TpmInputParamterBlock;
+ InBuffer[0].Size = TpmInputParamterBlockSize;
+ OutBuffer[0].Buffer = TpmOutputParameterBlock;
+ OutBuffer[0].Size = TpmOutputParameterBlockSize;
+
+ Status = TcmCommonPassThrough(
+ This,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer
+ );
+
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS EFIAPI TcgDxeHashLogExtendEvent(
+ IN EFI_TCG_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *EventNumber,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry )
+{
+ EFI_STATUS Status;
+ UINT64 DigestSize;
+ UINT8 *HashResult;
+ TCG_DXE_PRIVATE_DATA *Private;
+
+ Private = TCG_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(TCGLogData->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ DigestSize = sizeof (TCGLogData->Digest);
+ HashResult = TCGLogData->Digest.digest;
+ Status = TcgDxeHashAll(
+ This,
+ (UINT8 *)HashData,
+ HashDataLen,
+ AlgorithmId,
+ &DigestSize,
+ &HashResult
+ );
+
+ TRACE((TRACE_ALWAYS, "TcgDxeHashAll Status = %r \n", Status));
+
+
+ if ( !EFI_ERROR( Status ))
+ {
+ Status = TcgDxeLogEvent(
+ This,
+ TCGLogData,
+ EventNumber,
+ 0
+ );
+
+ TRACE((TRACE_ALWAYS, "TcgDxeLogEvent Status = %r \n", Status));
+ }
+
+ return Status;
+}
+
+
+static TCG_DXE_PRIVATE_DATA mTcgDxeData = {
+ {
+ TcgDxeStatusCheck,
+ TcgDxeHashAll,
+ TcgDxeLogEvent,
+ TcgDxePassThroughToTpm,
+ TcgDxeHashLogExtendEvent
+ },
+ NULL
+};
+
+
+static TCM_DXE_PRIVATE_DATA mTcmDxeData = {
+ {
+ TcgTcmDxeStatusCheck,
+ TcmDxeHashAll,
+ TcmDxeLogEvent,
+ TcgDxePassThroughToTcm,
+ TcgDxeHashLogExtendEventTcm
+ },
+ NULL
+};
+
+//***********************************************************************
+// MOR RELATED FUNCTIONS
+//***********************************************************************
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: OverwriteSystemMemory
+//
+// Description: Overwrites system memory
+//
+// Input:
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS OverwriteSystemMemory(
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 TmpMemoryMap[1];
+ UINTN MapKey;
+ UINTN DescriptorSize;
+ UINT32 DescriptorVersion;
+ UINTN MemoryMapSize;
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;
+ EFI_MEMORY_DESCRIPTOR *MemoryMapPtr;
+ BOOLEAN IsRuntime;
+ UINTN Index;
+ UINT64 Size;
+ IsRuntime = FALSE;
+
+ //
+ // Get System MemoryMapSize
+ //
+ MemoryMapSize = 1;
+ Status = pBS->GetMemoryMap (
+ &MemoryMapSize,
+ (EFI_MEMORY_DESCRIPTOR *)TmpMemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+ //
+ // Enlarge space here, because we will allocate pool now.
+ //
+ MemoryMapSize += EFI_PAGE_SIZE;
+ Status = pBS->AllocatePool (
+ EfiBootServicesData,
+ MemoryMapSize,
+ (VOID**)&MemoryMap
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get System MemoryMap
+ //
+ Status = pBS->GetMemoryMap (
+ &MemoryMapSize,
+ MemoryMap,
+ &MapKey,
+ &DescriptorSize,
+ &DescriptorVersion
+ );
+ ASSERT_EFI_ERROR (Status);
+
+ MemoryMapPtr = MemoryMap;
+ //
+ // Search the request Address
+ //
+ for (Index = 0; Index < (MemoryMapSize / DescriptorSize); Index++) {
+ switch (MemoryMap->Type){
+ case EfiMemoryMappedIO:
+ case EfiReservedMemoryType:
+ case EfiRuntimeServicesCode:
+ case EfiRuntimeServicesData:
+ case EfiUnusableMemory:
+ case EfiMemoryMappedIOPortSpace:
+ case EfiPalCode:
+ case EfiACPIReclaimMemory:
+ case EfiACPIMemoryNVS:
+ case EfiBootServicesCode:
+ case EfiBootServicesData:
+ case EfiLoaderCode:
+ case EfiLoaderData:
+ case EfiMaxMemoryType:
+ break;
+ default:
+ Size = Shl64(MemoryMap->NumberOfPages, EFI_PAGE_SHIFT);
+ MemSet((VOID*)MemoryMap->PhysicalStart, (UINTN)Size, 0);
+ }
+ MemoryMap = (EFI_MEMORY_DESCRIPTOR *)((UINTN)MemoryMap + DescriptorSize);
+ }
+
+ //
+ // Done
+ //
+ pBS->FreePool (MemoryMapPtr);
+
+ return IsRuntime;
+
+
+
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ReadMORValue
+//
+// Description: Reads TCG MOR variable
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID ReadMORValue( )
+{
+ CHAR16 UefiMor[] = L"MemoryOverwriteRequestControl";
+ EFI_GUID MorUefiGuid = MEMORY_ONLY_RESET_CONTROL_GUID;
+ UINT8 mor = 0;
+ UINTN size = sizeof(mor);
+ EFI_STATUS Status;
+
+
+ Status = pRS->GetVariable( UefiMor, &MorUefiGuid,
+ NULL, &size, &mor );
+
+ if(EFI_ERROR(Status))return;
+
+ if ( mor & 1 )
+ {
+
+ //clear memory
+ TRACE((-1,"MOR: before Clear memory"));
+ Status = OverwriteSystemMemory();
+ TRACE((-1,"MOR: After Clear memory"));
+ }
+}
+
+
+
+
+//**********************************************************************
+// MOR FUNCTIONS END
+//**********************************************************************
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: OnAcpiInstalled
+//
+// Description: Adds Tcg Table to Acpi Tables
+//
+// Input: IN EFI_EVENT ev
+// IN Callback Context *ctx
+//
+// Output: Device path size
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS OnAcpiInstalled(
+ IN EFI_EVENT ev,
+ IN VOID *ctx )
+{
+ EFI_STATUS Status;
+ EFI_ACPI_SUPPORT_PROTOCOL *acpi;
+ UINTN handle = 0;
+
+ TRACE((TRACE_ALWAYS, "Adding TCG ACPI table...\n"));
+ Status = pBS->LocateProtocol( &gEfiAcpiSupportGuid, NULL, &acpi );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_ABORTED;
+ }
+
+ mTcgAcpiTableTemplate.Header.Revision = TCG_TBL_REV;
+ MemCpy( mTcgAcpiTableTemplate.Header.OemId,
+ TCG_OEMID,
+ sizeof(mTcgAcpiTableTemplate.Header.OemId));
+
+ mTcgAcpiTableTemplate.Header.OemTableId = TCG_TBL_OEM_ID;
+ mTcgAcpiTableTemplate.Header.OemRevision = TCG_TBL_OEM_REV;
+ mTcgAcpiTableTemplate.Header.CreatorId = TCG_CREATOR_ID;
+ mTcgAcpiTableTemplate.Header.CreatorRevision = TCG_CREATOR_REVISION;
+ mTcgAcpiTableTemplate.Reserved = TCG_PLATFORM_CLASS;
+
+ Status = acpi->SetAcpiTable( acpi, &mTcgAcpiTableTemplate, TRUE,
+ EFI_ACPI_TABLE_VERSION_ALL,
+ &handle );
+ return Status;
+}
+
+
+
+
+
+EFI_STATUS
+EFIAPI SetTcgAcpiTable()
+{
+ EFI_STATUS Status;
+ EFI_ACPI_SUPPORT_PROTOCOL *acpi;
+ EFI_EVENT ev;
+ UINTN handle = 0;
+ static VOID *reg = NULL;
+
+ TRACE((TRACE_ALWAYS, "SetTcgAcpiTable....\n"));
+ Status = pBS->LocateProtocol( &gEfiAcpiSupportGuid, NULL, &acpi );
+
+ if(EFI_ERROR(Status)){
+
+ Status = pBS->CreateEvent( EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_DRIVER,
+ OnAcpiInstalled,
+ NULL,
+ &ev );
+
+ ASSERT( !EFI_ERROR( Status ));
+ Status = pBS->RegisterProtocolNotify( &gEfiAcpiSupportGuid, ev, &reg );
+ return Status;
+ }
+
+ mTcgAcpiTableTemplate.Header.Revision = TCG_TBL_REV;
+ MemCpy( mTcgAcpiTableTemplate.Header.OemId,TCG_OEMID,
+ sizeof(mTcgAcpiTableTemplate.Header.OemId));
+
+ mTcgAcpiTableTemplate.Header.OemTableId = TCG_TBL_OEM_ID;
+ mTcgAcpiTableTemplate.Header.OemRevision = TCG_TBL_OEM_REV;
+ mTcgAcpiTableTemplate.Header.CreatorId = TCG_CREATOR_ID;
+ mTcgAcpiTableTemplate.Header.CreatorRevision = TCG_CREATOR_REVISION;
+ mTcgAcpiTableTemplate.Reserved = TCG_PLATFORM_CLASS;
+
+ Status = acpi->SetAcpiTable( acpi, &mTcgAcpiTableTemplate, TRUE,
+ EFI_ACPI_TABLE_VERSION_ALL,
+ &handle );
+
+ return Status;
+}
+
+
+static EFI_STATUS CopyLogToAcpiNVS(
+ void )
+{
+ EFI_STATUS Status;
+ TCG_LOG_HOB *TcgLog = NULL;
+ void** DummyPtr;
+
+ TcgLog = (TCG_LOG_HOB*) LocateATcgHob(
+ pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gEfiAmiDTcgLogHobGuid );
+
+ DummyPtr = &TcgLog;
+
+ if ( *DummyPtr == NULL )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ Status = pBS->AllocatePages(
+ AllocateMaxAddress,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES( mTcgAcpiTableTemplate.LogMaxLength + sizeof (*TcgLog)),
+ (UINT64*)(UINTN)&mTcgAcpiTableTemplate.LogStart
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ pBS->SetMem(
+ (VOID*)((UINTN)mTcgAcpiTableTemplate.LogStart),
+ (UINTN)mTcgAcpiTableTemplate.LogMaxLength,
+ 0x00 // Clean up this region with this value.
+ );
+
+ TcgLog->TableMaxSize = mTcgAcpiTableTemplate.LogMaxLength;
+
+ if(TcgDxe_Cap.deactivated){
+ TcgLog->EventNum = 0;
+ TcgLog->TableSize = 0;
+
+ pBS->CopyMem(
+ (VOID*)(UINTN)mTcgAcpiTableTemplate.LogStart,
+ TcgLog,
+ sizeof (TCG_LOG_HOB));
+
+ mTcgAcpiTableTemplate.LogStart += sizeof (*TcgLog);
+ }else{
+ pBS->CopyMem(
+ (VOID*)(UINTN)mTcgAcpiTableTemplate.LogStart,
+ TcgLog,
+ TcgLog->TableSize + sizeof (*TcgLog)
+ );
+ mTcgAcpiTableTemplate.LogStart += sizeof (*TcgLog);
+ }
+
+ Status = SetTcgAcpiTable();
+
+ return Status;
+}
+
+VOID InsertTailList(
+ EFI_LIST_ENTRY *ListHead,
+ EFI_LIST_ENTRY *Entry )
+{
+ EFI_LIST_ENTRY *_ListHead;
+ EFI_LIST_ENTRY *_BackLink;
+
+ _ListHead = ListHead;
+ _BackLink = _ListHead->BackLink;
+ Entry->ForwardLink = _ListHead;
+ Entry->BackLink = _BackLink;
+ _BackLink->ForwardLink = Entry;
+ _ListHead->BackLink = Entry;
+}
+
+typedef struct _TCG_DXE_FWVOL_LIST
+{
+ EFI_LIST_ENTRY Link;
+ EFI_HANDLE FvHandle;
+} TCG_DXE_FWVOL_LIST;
+
+static EFI_LIST_ENTRY mMeasuredFvs = {
+ &mMeasuredFvs,
+ &mMeasuredFvs
+};
+
+static EFI_STATUS AddFvToMeasuredFvList(
+ EFI_HANDLE FvHandle )
+{
+ TCG_DXE_FWVOL_LIST *NewEntry;
+
+ pBS->AllocatePool( EfiBootServicesData, sizeof (*NewEntry), &NewEntry );
+
+ if ( NewEntry == NULL )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewEntry->FvHandle = FvHandle;
+ InsertTailList( &mMeasuredFvs, &NewEntry->Link );
+ return EFI_SUCCESS;
+}
+
+static EFI_STATUS HashAllFilesInFv(
+ IN SHA1_CTX *Sha1Ctx,
+ IN EFI_FIRMWARE_VOLUME_PROTOCOL
+ *FwVol,
+ IN EFI_FV_FILETYPE FileType )
+{
+ EFI_STATUS Status;
+ VOID *KeyBuffer = NULL;
+ EFI_GUID FileName;
+ EFI_FV_FILE_ATTRIBUTES FileAttr;
+ UINTN FileSize;
+ VOID *FileBuffer;
+ UINT32 AuthStat;
+
+
+ Status = pBS->AllocatePool( EfiBootServicesData, FwVol->KeySize, KeyBuffer );
+
+ if ( KeyBuffer != NULL )
+ {
+ pBS->SetMem( KeyBuffer, FwVol->KeySize, 0 );
+ }
+
+ if ( KeyBuffer == NULL )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ do
+ {
+ Status = FwVol->GetNextFile(
+ FwVol,
+ KeyBuffer,
+ &FileType,
+ &FileName,
+ &FileAttr,
+ &FileSize
+ );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ FileBuffer = NULL;
+ Status = FwVol->ReadFile(
+ FwVol,
+ &FileName,
+ &FileBuffer,
+ &FileSize,
+ &FileType,
+ &FileAttr,
+ &AuthStat
+ );
+ ASSERT( !EFI_ERROR( Status ));
+
+ SHA1Update(Sha1Ctx, FileBuffer, (u32)FileSize );
+ pBS->FreePool( FileBuffer );
+ }
+ } while ( !EFI_ERROR( Status ));
+
+ pBS->FreePool( KeyBuffer );
+ return EFI_SUCCESS;
+}
+
+
+
+static EFI_STATUS MeasureFv(
+ IN EFI_TCG_PROTOCOL *This,
+ IN EFI_HANDLE FvHandle )
+{
+ EFI_STATUS Status;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *FwVol;
+ EFI_LIST_ENTRY *Link;
+ TCG_DXE_FWVOL_LIST *FwVolList;
+ SHA1_CTX Sha1Ctx;
+ TCG_DIGEST *FvDigest;
+ EFI_TCG_PCR_EVENT TcgEvent;
+ UINT32 EventNum;
+
+ for ( Link = mMeasuredFvs.ForwardLink;
+ Link != &mMeasuredFvs;
+ Link = Link->ForwardLink )
+ {
+ FwVolList = _CR( Link, TCG_DXE_FWVOL_LIST, Link );
+
+ if ( FvHandle == FwVolList->FvHandle )
+ {
+ return EFI_SUCCESS;
+ }
+ }
+
+ Status = AddFvToMeasuredFvList( FvHandle );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ Status = pBS->HandleProtocol(
+ FvHandle,
+ &gEfiFirmwareVolumeProtocolGuid,
+ &FwVol
+ );
+ ASSERT( !EFI_ERROR( Status ));
+
+ SHA1Init(&Sha1Ctx );
+ Status = HashAllFilesInFv( &Sha1Ctx, FwVol, EFI_FV_FILETYPE_DRIVER );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+ Status = HashAllFilesInFv( &Sha1Ctx, FwVol, EFI_FV_FILETYPE_APPLICATION );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+ SHA1Final((unsigned char *)&FvDigest->digest, &Sha1Ctx);
+
+ TcgEvent.Header.PCRIndex = PCRi_OPROM_CODE;
+ TcgEvent.Header.EventType = EV_EVENT_TAG;
+ TcgEvent.Event.Tagged.EventID = EV_ID_OPROM_EXECUTE;
+ TcgEvent.Event.Tagged.EventSize
+ = sizeof (TcgEvent.Event.Tagged.EventData.OptionRomExecute);
+ TcgEvent.Header.EventDataSize
+ = _TPM_STRUCT_PARTIAL_SIZE( struct _EFI_TCG_EV_TAG, EventData )
+ + TcgEvent.Event.Tagged.EventSize;
+
+ TcgEvent.Event.Tagged.EventData.OptionRomExecute.PFA = 0;
+ TcgEvent.Event.Tagged.EventData.OptionRomExecute.Reserved = 0;
+ TcgEvent.Event.Tagged.EventData.OptionRomExecute.Hash = *FvDigest;
+
+ Status = TcgDxeHashLogExtendEvent(
+ This,
+ (UINTN)&TcgEvent.Event,
+ TcgEvent.Header.EventDataSize,
+ TCG_ALG_SHA,
+ (TCG_PCR_EVENT*)&TcgEvent,
+ &EventNum,
+ 0
+ );
+
+Exit:
+ return Status;
+}
+
+
+
+
+static
+VOID
+EFIAPI OnFwVolInstalled(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handles;
+ UINTN NumHandles;
+
+ Handles = NULL;
+ NumHandles = 0;
+ Status = pBS->LocateHandleBuffer(
+ ByRegisterNotify,
+ NULL,
+ *(VOID**)Context,
+ &NumHandles,
+ &Handles
+ );
+
+ ASSERT(!EFI_ERROR( Status ));
+
+ while (!EFI_ERROR( Status ) && NumHandles > 0 )
+ {
+ NumHandles--;
+ Status = MeasureFv( &mTcgDxeData.TcgServiceProtocol,
+ Handles[NumHandles] );
+ }
+
+ if ( Handles != NULL )
+ {
+ pBS->FreePool( Handles );
+ }
+}
+
+static EFI_STATUS MonitorFvs(
+ void )
+{
+ EFI_STATUS Status;
+ EFI_EVENT Event;
+ static VOID *RegFwVol;
+
+ Status = pBS->CreateEvent(
+ EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_DRIVER,
+ OnFwVolInstalled,
+ (VOID*)&RegFwVol,
+ &Event
+ );
+ ASSERT( !EFI_ERROR( Status ));
+
+ Status = pBS->RegisterProtocolNotify(
+ &gEfiFirmwareVolumeProtocolGuid,
+ Event,
+ &RegFwVol
+ );
+ ASSERT( !EFI_ERROR( Status ));
+
+ return Status;
+}
+
+
+#define FAST_BOOT_VARIABLE_GUID \
+ { 0xb540a530, 0x6978, 0x4da7, 0x91, 0xcb, 0x72, 0x7, 0xd7, 0x64, 0xd2, 0x62 }
+EFI_GUID FastBootVariableGuid = FAST_BOOT_VARIABLE_GUID;
+EFI_GUID AmitcgefiOsVariableGuid = AMI_TCG_EFI_OS_VARIABLE_GUID;
+
+
+
+
+
+
+//*******************************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FindAndMeasureDxeFWVol
+//
+// Description:
+//
+// Input:
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//******************************************************************************
+EFI_STATUS FindAndMeasureDxeFWVol()
+{
+ PEI_EFI_POST_CODE ev;
+ UINT32 n;
+ UINTN last;
+ EFI_STATUS Status;
+ EFI_GUID NameGuid =\
+ {0x7739f24c, 0x93d7, 0x11d4,\
+ 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d};
+ UINTN Size;
+ void *Buffer = NULL;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ VOID *HobStart;
+ UINTN TableEntries;
+ EFI_PEI_HOB_POINTERS FirmwareVolumeHob;
+ BOOLEAN Found=FALSE;
+
+ TableEntries = pST->NumberOfTableEntries;
+
+ while ( TableEntries > 0 )
+ {
+ TableEntries--;
+
+ if ((!MemCmp(
+ &pST->ConfigurationTable[TableEntries].VendorGuid,
+ &NameGuid, sizeof(EFI_GUID))))
+ {
+ HobStart = pST->ConfigurationTable[TableEntries].VendorTable;
+ FirmwareVolumeHob.Raw = GetHob (EFI_HOB_TYPE_FV, HobStart);
+ if (FirmwareVolumeHob.Header->HobType != EFI_HOB_TYPE_FV) {
+ continue;
+ }
+ break;
+ }
+ }
+
+ for (Status = EFI_NOT_FOUND; EFI_ERROR (Status);) {
+ if (END_OF_HOB_LIST (FirmwareVolumeHob)) {
+ return EFI_NOT_FOUND;
+ }
+
+ if (GET_HOB_TYPE (FirmwareVolumeHob) == EFI_HOB_TYPE_FV) {
+ if ((((UINT64)FirmwareVolumeHob.FirmwareVolume->BaseAddress)\
+ < (UINT64)NVRAM_ADDRESS ) ||
+ ((UINT64)FirmwareVolumeHob.FirmwareVolume->BaseAddress) == FV_MAIN_BASE)
+ {
+ Found = TRUE;
+ break;
+ }
+ }
+
+ FirmwareVolumeHob.Raw = GET_NEXT_HOB (FirmwareVolumeHob);
+ }
+
+ if(Found== FALSE)return EFI_NOT_FOUND;
+
+ TRACE((-1,"TcgDxe:: Found Volume: Base = %x Length = %x",\
+ FirmwareVolumeHob.FirmwareVolume->BaseAddress,\
+ FirmwareVolumeHob.FirmwareVolume->Length));
+
+ Status = pBS->AllocatePool(
+ EfiBootServicesData,
+ (UINTN)FirmwareVolumeHob.FirmwareVolume->Length,
+ &Buffer);
+
+ if(EFI_ERROR(Status) || Buffer == NULL) return EFI_OUT_OF_RESOURCES;
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid,\
+ NULL, &TcgProtocol);
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+
+ if(FirmwareVolumeHob.FirmwareVolume->BaseAddress == FV_MAIN_BASE)
+ {
+ if(FirmwareVolumeHob.FirmwareVolume->Length > TCG_SIZE){
+ Size = TCG_SIZE;
+ }else{
+ Size = (UINTN)FirmwareVolumeHob.FirmwareVolume->Length;
+ }
+
+ pBS->CopyMem(Buffer, (UINT8 *)(EFI_PHYSICAL_ADDRESS)FirmwareVolumeHob.FirmwareVolume->BaseAddress,\
+ Size);
+
+ }else{
+
+ Buffer = (UINT8 *)(EFI_PHYSICAL_ADDRESS)FirmwareVolumeHob.FirmwareVolume->BaseAddress;
+ Size = (UINTN)FirmwareVolumeHob.FirmwareVolume->Length;
+ }
+
+ ev.Header.PCRIndex = PCRi_CRTM_AND_POST_BIOS;
+ ev.Header.EventType = EV_POST_CODE;
+ ev.Header.EventDataSize = sizeof (EFI_TCG_EV_POST_CODE);
+ ev.Event.PostCodeAddress = \
+ (EFI_PHYSICAL_ADDRESS)FirmwareVolumeHob.FirmwareVolume->BaseAddress;
+
+ #if defined x64_BUILD && x64_BUILD == 1
+ ev.Event.PostCodeLength = Size;
+ #else
+ ev.Event.PostCodeLength = Size;
+ #endif
+
+ Status = TcgProtocol->HashLogExtendEvent (TcgProtocol,
+ (EFI_PHYSICAL_ADDRESS)Buffer,
+ Size,
+ TCG_ALG_SHA,
+ (TCG_PCR_EVENT*)&ev,
+ #if defined x64_BUILD && x64_BUILD == 1
+ &n,
+ &last);
+ #else
+ &n,
+ (EFI_PHYSICAL_ADDRESS *)&last);
+ #endif
+
+ return Status;
+}
+
+
+
+EFI_STATUS
+EFIAPI TcgDxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ BOOLEAN Support = FALSE;
+ TPM_GetCapabilities_Input cmdGetCap;
+ TPM_RQU_COMMAND_HDR NuvotoncmdGetTpmStatus;
+ UINT8 result[0x100];
+
+ Status = pBS->LocateProtocol(
+ &gEfiTpmDeviceProtocolGuid,
+ NULL,
+ &mTcgDxeData.TpmDevice);
+
+ Status = pBS->LocateProtocol(
+ &gEfiTpmDeviceProtocolGuid,
+ NULL,
+ &mTcmDxeData.TpmDevice);
+
+ if ( EFI_ERROR( Status )){
+ return Status;
+ }
+
+ Status = CopyLogToAcpiNVS( );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ if(*(UINT16 *)(UINTN)(PORT_TPM_IOMEMBASE + 0xF00) != 0x1050)
+ {
+ cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap));
+
+ if(AutoSupportType()){
+ cmdGetCap.CommandCode = TPM_H2NL( TCM_ORD_GetCapability );
+ cmdGetCap.CommandCode = TPM_H2NL( TCM_ORD_GetCapability );
+ cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG );
+ }else{
+ cmdGetCap.CommandCode = TPM_H2NL( TPM_ORD_GetCapability );
+ cmdGetCap.CommandCode = TPM_H2NL( TPM_ORD_GetCapability );
+ cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG );
+ }
+
+ cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long
+ cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_PERMANENT );
+
+ if(AutoSupportType()){
+ Status = TcgDxePassThroughToTcm( &mTcmDxeData.TcgServiceProtocol,
+ sizeof (cmdGetCap),
+ (UINT8*)&cmdGetCap,
+ sizeof (TPM_Capabilities_PermanentFlag),
+ (UINT8*)&TcgDxe_Cap );
+ }else{
+ Status = TcgDxePassThroughToTpm( &mTcgDxeData.TcgServiceProtocol,
+ sizeof (cmdGetCap),
+ (UINT8*)&cmdGetCap,
+ sizeof (TPM_Capabilities_PermanentFlag),
+ (UINT8*)&TcgDxe_Cap );
+ }
+ }else{
+ MemSet(&TcgDxe_Cap,sizeof(TPM_Capabilities_PermanentFlag), 0);
+ NuvotoncmdGetTpmStatus.tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ NuvotoncmdGetTpmStatus.paramSize = TPM_H2NL( sizeof (TPM_RQU_COMMAND_HDR));
+ NuvotoncmdGetTpmStatus.ordinal = TPM_H2NL( NTC_ORD_GET_TPM_STATUS );
+
+ Status = TcgDxePassThroughToTpm( &mTcgDxeData.TcgServiceProtocol,
+ sizeof (NuvotoncmdGetTpmStatus),
+ (UINT8*)&NuvotoncmdGetTpmStatus,
+ 0x100,
+ result );
+
+ if(((NUVOTON_SPECIFIC_FLAGS *) result)->RetCode == 0)
+ {
+ if(((NUVOTON_SPECIFIC_FLAGS *)result)->isdisabled){
+ TcgDxe_Cap.disabled = 1;
+ }
+
+ if(((NUVOTON_SPECIFIC_FLAGS *)result)->isdeactivated){
+ TcgDxe_Cap.deactivated = 1;
+ }
+
+ if(((NUVOTON_SPECIFIC_FLAGS *)result)->isOwnerSet){
+ TcgDxe_Cap.ownership = 1;
+ }
+ }else{
+
+ TcgDxe_Cap.RetCode = ((NUVOTON_SPECIFIC_FLAGS *)result)->RetCode;
+ }
+ }
+
+ if ( TPM_H2NL(TcgDxe_Cap.RetCode)!=0)
+ {
+ return EFI_SUCCESS;
+ }
+
+ Support = AutoSupportType();
+
+ ReadMORValue();
+
+ if(!Support){
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiTcgProtocolGuid,
+ &mTcgDxeData.TcgServiceProtocol,
+ NULL);
+#if defined (USE_BIOS_IMAGE_AS_CRTM) && (USE_BIOS_IMAGE_AS_CRTM == 0)
+ FindAndMeasureDxeFWVol();
+#endif
+ return Status;
+ }else{
+
+ TcmOSTransition();
+ return pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiTcgProtocolGuid,
+ &mTcmDxeData.TcgServiceProtocol,
+ NULL);
+ }
+
+}
diff --git a/Core/EM/TCG2/Common/TcgDxe.cif b/Core/EM/TCG2/Common/TcgDxe.cif
new file mode 100644
index 0000000..20e2b7f
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgDxe.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "TcgDxe"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "TcgDxe"
+[files]
+"TcgDxe.mak"
+"TpmDxe.c"
+"TcgDxe.c"
+"TcgDxe.dxs"
+"xTcgDxe.c"
+"EMpCallBin.asm"
+"EMpCallBin32.asm"
+"EMpTcmDxe.c"
+"TcgDxe20.c"
+"TcgDxe.sdl"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/TcgDxe.dxs b/Core/EM/TCG2/Common/TcgDxe.dxs
new file mode 100644
index 0000000..05479e0
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgDxe.dxs
@@ -0,0 +1,110 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe.dxs 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe.dxs $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 7 3/19/12 6:31p Fredericko
+// Changes for Tcg Performance Metrics Improvement.
+// Files Changed: Tcg.sdl, TcgMisc.h, TcgDxe.c, TcgCommon.c, TcgCommon.h,
+// AmiTcgPlatformPeiLib.c, AmiTcgPlatformDxe.c, TcgDxe.dxs
+//
+// 6 5/20/10 8:59a Fredericko
+// Included File Header
+// Updated AMI copyright header
+//
+// 5 4/30/09 6:17p Fredericko
+// Updated Header Date
+//
+// 4 4/30/09 5:34p Fredericko
+// AMI company Header Address changes
+//
+// 3 2/05/09 5:25p Fredericko
+// To build without EDK changed includes in Tcgdxe.dxs file
+//
+// 2 3/06/07 12:59p Fasihm
+// Added dependencies.
+//
+// 1 6/20/06 5:58p Andriyn
+//
+//**********************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgDxe.dxs
+//
+// Description:
+// TcgDxe dependency file
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: TCGDXE.dxs
+//
+// Description: Dependency expression for TCGPEI component.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include <Token.h>
+#include <Protocol\Variable.h>
+#include <Protocol\CpuIo.h>
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+#include <Protocol\FirmwareVolume.h>
+#else
+#include <Protocol\FirmwareVolume2.h>
+#endif
+
+
+DEPENDENCY_START
+ EFI_VARIABLE_ARCH_PROTOCOL_GUID AND
+ EFI_CPU_IO_PROTOCOL_GUID AND
+#if (PI_SPECIFICATION_VERSION < 0x00010000)
+ EFI_FIRMWARE_VOLUME_PROTOCOL_GUID
+#else
+ EFI_FIRMWARE_VOLUME2_PROTOCOL_GUID
+#endif
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/TcgDxe.mak b/Core/EM/TCG2/Common/TcgDxe.mak
new file mode 100644
index 0000000..5a13732
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgDxe.mak
@@ -0,0 +1,196 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe.mak 1 4/21/14 2:16p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:16p $
+#**********************************************************************
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe.mak $
+#
+# 1 4/21/14 2:16p Fredericko
+#
+# 1 10/08/13 12:03p Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 1:59p Fredericko
+#
+# 1 7/10/13 5:51p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+# 29 9/27/11 10:25p Fredericko
+# [TAG] EIP67286
+# [Category] Improvement
+# [Description] changes for Tcg Setup policy
+# [Files] Tcg.sdl
+# TcgPei.cif
+# TcgPei.mak
+# xtcgPei.c
+# xTcgPeiAfterMem.c
+# TcgPeiAfterMem.mak
+# TcgDxe.cif
+# TcgDxe.mak
+# xTcgDxe.c
+# AmiTcgPlatformPeilib.c
+# AmiTcgPlatformDxelib.c
+#
+# 28 3/29/11 1:12p Fredericko
+#
+# 27 3/28/11 2:17p Fredericko
+# [TAG] EIP 54642
+# [Category] Improvement
+# [Description] 1. Checkin Files related to TCG function override
+# 2. Include TCM and TPM auto detection
+# [Files] Affects all TCG files
+#
+# 26 6/30/10 3:05p Fredericko
+# Modified for building EMpCallBin32.asm
+#
+# 25 5/19/10 5:26p Fredericko
+# Updated AMI copy right header
+# EIP 37653
+#
+# 24 4/21/10 11:49a Fredericko
+# Changes on the way Post strings are created for PPI display for
+# multi-language support
+#
+# 23 4/20/10 12:35p Fredericko
+# Included dependency on SetupStrTokens.h.
+#
+# 22 3/23/10 6:53p Fredericko
+# Tcglegacy support is currently it's own subcomponent
+#
+# 21 3/19/10 4:15p Fredericko
+# modified for legacy IO interface support
+#
+# 20 6/01/09 4:08p Fredericko
+# Changes for building Tcgdxe ffs when TCM_SUPPORT is enabled or
+# Disabled.
+#
+# 19 4/30/09 6:15p Fredericko
+# Updated Header Date
+#
+# 18 4/30/09 5:31p Fredericko
+# Removed unneccesary directories paths and AMI company Header Address
+# changes
+#
+# 17 2/05/09 5:10p Fredericko
+# USE BUILD_DEFAULTS instead of EDK_DEFAULTS and removal of all EDK paths
+#
+# 16 4/10/08 5:29p Fredericko
+# Print Library added
+#
+# 15 11/02/07 4:26p Fredericko
+# Changes to support Montevina Build process
+#
+# 1 10/26/07 9:41a Fasihm
+# Changed the Link order of the Libraries.
+# Need to remove after TCG is labeled again.
+#
+# 14 9/26/07 4:52p Fredericko
+#
+# 13 9/04/07 6:10p Fredericko
+# Cflags defined to make compiler use \W4 switch instead of \W3 switch
+#
+# 12 9/04/07 10:16a Fredericko
+# Use of AMIDXELIB.
+#
+# 11 7/13/07 2:53p Rameshraju
+# Added the TPM post meesage based on the UNI string.
+#
+#**********************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: TcgDxe.MAK
+#
+# Description: Make file for the tcgdxe component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : TCGDXE
+
+TCGDXE : $(BUILD_DIR)\tcgdxe.mak tcgdxeBin #$(BUILD_DIR)\LEGX16.ffs $(BUILD_DIR)\MPTPM.ffs $(BUILD_DIR)\TPM32BIN.ffs
+!IF "$(AMI_ZTEIC_SUPPORT)" == "1"
+TCGDXE : $(BUILD_DIR)\tcgdxe.mak tcgdxeBin
+!ENDIF
+
+$(BUILD_DIR)\tcgdxe.mak : $(TCGDXE_DIR)\$(@B).cif $(TCGDXE_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TCGDXE_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TCGDXE_CFLAGS=$(CFLAGS) \
+ /I$(TCG_DIR)\
+ /I$(TPM12_DIR)\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\Common\
+ /I$(PROJECT_DIR)\Include\Protocol\
+ /I$(TCG_DIR)\Protocol\
+ /I$(TcgPlatformSetupPolicy_DIR)\
+
+
+!IF "$(x64_BUILD)" != "0"
+$(BUILD_DIR)\$(TCGDXE_DIR)\EMpCallBin.obj : $(TCGDXE_DIR)\EMpCallBin.asm
+ $(ASM) /c /nologo /Fo$$(BUILD_DIR)\$(TCG_DIR)\EMpCallBin.obj $(TCG_DIR)\EMpCallBin.asm
+!ELSE
+$(BUILD_DIR)\$(TCGDXE_DIR)\EMpCallBin32.obj : $(TCGDXE_DIR)\EMpCallBin32.asm
+ $(ASM) /c /nologo /Fo$$(BUILD_DIR)\$(TCGDXE_DIR)\EMpCallBin32.obj $(TCGDXE_DIR)\EMpCallBin32.asm
+!ENDIF
+
+
+TCGDXE_OBJECTS = \
+$(BUILD_DIR)\$(TCGDXE_DIR)\TpmDxe.obj \
+$(BUILD_DIR)\$(TCGDXE_DIR)\TcgDxe.obj \
+$(BUILD_DIR)\$(TCGDXE_DIR)\TcgDxe20.obj \
+$(BUILD_DIR)\$(TCGDXE_DIR)\xTcgDxe.obj \
+$(BUILD_DIR)\$(TCGDXE_DIR)\EMpTcmDxe.obj\
+!IF "$(x64_BUILD)" == "0"
+$(BUILD_DIR)\$(TCGDXE_DIR)\EMpCallBin32.obj\
+!ENDIF
+!IF "$(x64_BUILD)" == "1"
+$(BUILD_DIR)\$(TCGDXE_DIR)\EMpCallBin.obj\
+!ENDIF
+
+
+tcgdxeBin : $(AMIDXELIB) $(BUILD_DIR)\TisLib.lib $(BUILD_DIR)\Tpm20CRBLib.lib
+ @echo CFLAGS=$(CFLAGS)
+ @echo TCGDXE_CFLAGS=$(TCGDXE_CFLAGS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\tcgdxe.mak all\
+ "CFLAGS=$(TCGDXE_CFLAGS)"\
+ GUID=5E9CABA3-F2B1-497a-ADAC-24F575E9CDE9 \
+ ENTRY_POINT=CommonTcgDxEntryPoint \
+ TYPE=BS_DRIVER \
+ "OBJECTS=$(TCGDXE_OBJECTS)"\
+ DEPEX1=$(TCGDXE_DIR)\tcgdxe.dxs \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ COMPRESS=1 HAS_RESOURCES=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/TCG2/Common/TcgDxe.sdl b/Core/EM/TCG2/Common/TcgDxe.sdl
new file mode 100644
index 0000000..c57b3a2
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgDxe.sdl
@@ -0,0 +1,27 @@
+TOKEN
+ Name = "TcgDxeSupport"
+ Value = "1"
+ Help = "Enable or Diasble TcgPeiSupport"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "TCG2Support" "=" "1"
+End
+
+PATH
+ Name = "TCGDXE_DIR"
+End
+
+MODULE
+ Help = "Includes tcgdxe.mak into project"
+ Path = "$(TCGDXE_DIR)"
+ File = "tcgdxe.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\tcgdxe.ffs"
+ Parent = "$(BUILD_DIR)\TcgPlatformSetupPolicy.ffs"
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/TCG2/Common/TcgDxe20.c b/Core/EM/TCG2/Common/TcgDxe20.c
new file mode 100644
index 0000000..981a88a
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgDxe20.c
@@ -0,0 +1,853 @@
+/*++
+ Module Name:
+
+ TcgDxe.c
+
+ Abstract:
+
+ DXE Driver that provides TCG services
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TcgDxe20.c 3 6/14/14 12:29a Fredericko $
+//
+// $Revision: 3 $
+//
+// $Date: 6/14/14 12:29a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log:
+#include "TcgCommon.h"
+#include <TcgMisc.h>
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <Runtime.h>
+#include <Tpm20Includes\Tpm20.h>
+#include <Tpm20Includes\TrEEProtocol.h>
+#include "protocol\TpmDevice\TpmDevice.h"
+#include <Protocol\ComponentName.h>
+#include <Protocol\ComponentName2.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\AcpiSupport.h>
+#include "TcgPlatformSetupPolicy.h"
+#include <Acpi.h>
+#include <AcpiRes.h>
+#include "Tpm20CRBLib.h"
+
+/*
+ locates the TPM20 hob from Pei. If found we are processing TPM 20 devic
+ need to install the TreeProtocol and do TPM20 binding measurements
+*/
+#define MAX_LOG_AREA_SIZE (32 * 1024) // 32KB
+
+static EFI_PHYSICAL_ADDRESS TreeEventLogLocation;
+static EFI_PHYSICAL_ADDRESS LastEntry = NULL;
+static EFI_PHYSICAL_ADDRESS LastEventPtr = 0;
+static EFI_TPM_DEVICE_PROTOCOL *TpmDevice=NULL;
+
+BOOLEAN IsTpm20Device();
+
+typedef struct _AMI_INTERNAL_HLXE_PROTOCOL AMI_INTERNAL_HLXE_PROTOCOL;
+
+typedef
+EFI_STATUS
+(EFIAPI * INTERNAL_HASH_LOG_EXTEND_EVENT) (
+ IN UINT8 *DataToHash,
+ IN UINT64 Flags,
+ IN UINTN DataSize,
+ IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
+ IN UINT8 *NewEventData
+);
+
+
+struct _AMI_INTERNAL_HLXE_PROTOCOL {
+ INTERNAL_HASH_LOG_EXTEND_EVENT InternalHashLogExtend;
+};
+
+
+static UINT16 *gDriverName=L"TPM Driver";
+static BOOLEAN Tpm20FwDevice = FALSE;
+
+
+UINT8 GetHashPolicy()
+{
+ TCG_PLATFORM_SETUP_PROTOCOL *ProtocolInstance;
+ EFI_STATUS Status;
+ EFI_GUID Policyguid = TCG_PLATFORM_SETUP_POLICY_GUID;
+
+ Status = pBS->LocateProtocol (&Policyguid, NULL, &ProtocolInstance);
+ if (EFI_ERROR (Status)) {
+ return 0;
+ }
+
+ return(ProtocolInstance->ConfigFlags.Reserved1);
+}
+
+
+EFI_STATUS
+EFIAPI
+Tpm20ComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ //Supports only English
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+
+ if (!LanguageCodesEqual( Language, "en-US") &&
+ !LanguageCodesEqual( Language, "eng"))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+Tpm20ComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI
+Tpm20ComponentNameGetDriverName2 (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ //Supports only English
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+//LANGUAGE_CODE_ENGLISH
+ if (!LanguageCodesEqual( Language, "en-US") &&
+ !LanguageCodesEqual( Language, "eng"))
+ return EFI_UNSUPPORTED;
+ else
+ *DriverName=gDriverName;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+Tpm20ComponentNameGetControllerName2 (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+static EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
+ Tpm20ComponentNameGetDriverName,
+ Tpm20ComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+
+
+static EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
+ Tpm20ComponentNameGetDriverName2,
+ Tpm20ComponentNameGetControllerName2,
+ LANGUAGE_CODE_ENGLISH
+};
+
+
+EFI_STATUS
+EFIAPI
+Tpm20DriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ static BOOLEAN Initialized = FALSE;
+
+ if(Initialized == FALSE){
+ Initialized = TRUE;
+ if(IsTpm20Device()){
+ return EFI_SUCCESS;
+ }else if(Tpm20FwDevice)return EFI_SUCCESS;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+EFI_STATUS
+EFIAPI
+Tpm20DriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+Tpm20DriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_DRIVER_BINDING_PROTOCOL Tpm20DriverBinding = {
+ Tpm20DriverBindingSupported,
+ Tpm20DriverBindingStart,
+ Tpm20DriverBindingStop,
+ 0xa,
+ NULL,
+ NULL
+};
+
+
+
+EFI_STATUS
+__stdcall Tcg20CommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue );
+
+
+
+BOOLEAN IsTpm20Device()
+{
+ EFI_GUID gTpm20Supporthobguid = TPM20_HOB_GUID;
+ UINT8 *TpmSupport = NULL;
+
+ TpmSupport = LocateATcgHob( pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gTpm20Supporthobguid);
+
+ if(TpmSupport != NULL){
+ if((*(volatile UINT8 *)((UINTN)(0xfed40000))!=0xff)){
+ if(*TpmSupport == 1)
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+EFI_STATUS
+TreeGetCapability (
+ IN EFI_TREE_PROTOCOL *This,
+ IN OUT TREE_BOOT_SERVICE_CAPABILITY *ProtocolCapability
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 HashAlg = GetHashPolicy();
+
+ if((ProtocolCapability == NULL) || (This == NULL)){
+ Status = EFI_INVALID_PARAMETER;
+ }
+ else {
+ if(ProtocolCapability->Size < (sizeof(UINT8) + sizeof(TREE_VERSION) + sizeof(TREE_VERSION))){
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ else {
+ ProtocolCapability->StructureVersion.Major = 1;
+ ProtocolCapability->StructureVersion.Minor = 0;
+ ProtocolCapability->ProtocolVersion.Major = 1;
+ ProtocolCapability->ProtocolVersion.Minor = 0;
+
+ if (ProtocolCapability->Size < sizeof(TREE_BOOT_SERVICE_CAPABILITY)){
+ ProtocolCapability->Size = sizeof(TREE_BOOT_SERVICE_CAPABILITY);
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+ else {
+
+ if( HashAlg == 0){
+ ProtocolCapability->HashAlgorithmBitmap = TREE_BOOT_HASH_ALG_SHA1;
+ }else if(HashAlg == 1){
+ ProtocolCapability->HashAlgorithmBitmap = TREE_BOOT_HASH_ALG_SHA256;
+ }
+
+ ProtocolCapability->SupportedEventLogs = TREE_EVENT_LOG_FORMAT_TCG_1_2;
+ ProtocolCapability->TrEEPresentFlag = TRUE;
+ ProtocolCapability->MaxCommandSize = 0x0F80;
+ ProtocolCapability->MaxResponseSize = 0x0F80;
+ ProtocolCapability->ManufacturerID = *(UINT16 *)(UINTN)(PORT_TPM_IOMEMBASE + 0xF00);
+ }
+ }
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS
+TreeGetEventLog (
+ IN EFI_TREE_PROTOCOL *This,
+ IN TREE_EVENTLOGTYPE EventLogFormat,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
+ OUT BOOLEAN *EventLogTruncated
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(EventLogFormat != TREE_EVENT_LOG_FORMAT_TCG_1_2)
+ {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ *EventLogLocation = TreeEventLogLocation;
+ *EventLogLastEntry = LastEventPtr;
+ *EventLogTruncated = FALSE;
+
+ return Status;
+}
+
+
+EFI_STATUS
+InternalTcg20CommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM2_PCRExtend_cmd_t Cmd;
+ TPM2_PCRExtend_res_t Res;
+ TPM2_PCRExtend_res_t Tmpres;
+ UINT32 CmdSize;
+ UINT8 *Buffer;
+ UINT8 *AuthSizeOffset;
+ UINT8 *ResultBuf = NULL;
+ UINT32 ResultBufSize = 0;
+ UINT32 DigestSize;
+ EFI_STATUS Status;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ Cmd.Tag = (TPMI_ST_COMMAND_TAG)TPM_H2NS(TPM_ST_SESSIONS);
+ Cmd.CommandSize = TPM_H2NL(sizeof(Cmd));
+ Cmd.CommandCode = TPM_H2NL(TPM_CC_PCR_Extend);
+
+ Buffer = (UINT8 *)&Cmd.inputParameters;
+ *(UINT32 *)Buffer = TPM_H2NL(PcrIndex);
+ Buffer += sizeof(UINT32);
+
+ AuthSizeOffset = Buffer;
+ *(UINT32 *)Buffer = 0;
+ Buffer += sizeof(UINT32);
+
+ // pcr authHandle
+ *(UINT32 *)Buffer = TPM_H2NL(TPM_RS_PW);
+ Buffer += sizeof(UINT32);
+
+ // nonce = nullNonce
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // sessionAttributes = 0
+ *(UINT8 *)Buffer = 0;
+ Buffer += sizeof(UINT8);
+
+ // auth = nullAuth
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // authorizationSize
+ *(UINT32 *)AuthSizeOffset = TPM_H2NL((UINT32)(Buffer - AuthSizeOffset - sizeof(UINT32)));
+
+ //Digest count
+ *(UINT32 *)Buffer = TPM_H2NL(1);
+ Buffer += sizeof(UINT32);
+
+
+ // Get the digest size based on Hash Alg
+ if(GetHashPolicy()==0){
+ //Hash alg
+ *(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA1);
+ Buffer += sizeof(UINT16);
+ DigestSize = 0x14;
+ TcgCommonCopyMem(CallbackContext, Buffer, &Digest->digest, DigestSize);
+ }else{
+ //Hash alg
+ /**(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA256);
+ Buffer += sizeof(UINT16);
+ DigestSize = 0x20;
+ TcgCommonCopyMem(CallbackContext, Buffer, &Digest->digestSha2, DigestSize);*/
+ return EFI_UNSUPPORTED;
+ }
+
+ Buffer += DigestSize;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.CommandSize = TPM_H2NL(CmdSize);
+
+ ResultBuf = (UINT8 *) &Tmpres;
+ ResultBufSize = sizeof(Res);
+
+ if(Tpm20FwDevice ==FALSE)
+ {
+ TRACE(( TRACE_ALWAYS," Tpm20FwDevice = FALSE \n"));
+ if(TpmDevice==NULL)return EFI_NOT_FOUND;
+
+ InBuffer[0].Buffer = &Cmd;
+ InBuffer[0].Size = CmdSize;
+ OutBuffer[0].Buffer = ResultBuf;
+ OutBuffer[0].Size = ResultBufSize;
+
+ TpmDevice->Init(TpmDevice );
+
+ Status = TpmDevice->Transmit(TpmDevice,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer);
+
+ TpmDevice->Close(TpmDevice );
+ }else{
+ Status = CrbSubmitCmd((UINT8 *)&Cmd, CmdSize, ResultBuf, &ResultBufSize);
+ }
+
+ return Status;
+}
+
+
+#pragma optimize("",off)
+EFI_STATUS
+TpmHashLogExtendEventI(
+ IN UINT8 *DataToHash,
+ IN UINT64 Flags,
+ IN UINTN DataSize,
+ IN OUT TCG_PCR_EVENT_HDR *NewEventHdr,
+ IN UINT8 *NewEventData
+)
+{
+ EFI_STATUS Status;
+ TCG_DIGEST Out_Digest;
+ BOOLEAN isSha1 = GetHashPolicy();
+ UINT32 TempSize;
+ UINTN RequiredSpace=0;
+
+
+ TRACE(( TRACE_ALWAYS," TpmHashLogExtendEvent Entry \n"));
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(NewEventHdr->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ if(DataToHash!=NULL)
+ {
+ if(isSha1==0){
+ RequiredSpace = sizeof(TCG_PCR_EVENT_HDR) - sizeof(NewEventHdr->Digest)\
+ + sizeof(NewEventHdr->Digest.digest) + NewEventHdr->EventSize;
+ Status = SHA1HashAll( NULL, DataToHash, DataSize, &NewEventHdr->Digest );
+ TRACE(( TRACE_ALWAYS," SHA1HashAll Status = %r \n", Status));
+ if(EFI_ERROR(Status))return Status;
+ }else{
+ /* RequiredSpace = sizeof(TCG_PCR_EVENT_HDR) - sizeof(NewEventHdr->Digest)\
+ + sizeof(NewEventHdr->Digest.digestSha2) + NewEventHdr->EventSize;
+ Status = SHA2HashAll( NULL, DataToHash, DataSize, &NewEventHdr->Digest );
+ TRACE(( TRACE_ALWAYS," SHA2HashAll Status = %r \n", Status));
+ if(EFI_ERROR(Status))return Status;*/
+ }
+ }
+
+
+
+ if((RequiredSpace + LastEventPtr) > \
+ (TreeEventLogLocation + MAX_LOG_AREA_SIZE))return EFI_OUT_OF_RESOURCES;
+
+ Status = InternalTcg20CommonExtend(NULL,
+ NewEventHdr->PCRIndex,
+ &NewEventHdr->Digest,
+ &Out_Digest);
+
+ TRACE(( TRACE_ALWAYS," InternalTcg20CommonExtend Status = %r \n", Status));
+ if(EFI_ERROR(Status))return Status;
+
+ TRACE(( TRACE_ALWAYS," LastEntry = %x \n", LastEntry));
+ if(LastEntry == NULL) return EFI_ABORTED;
+
+ LastEventPtr = LastEntry;
+
+ if(isSha1 == 0){ //log event record
+ pBS->CopyMem(
+ (VOID*)(UINTN)LastEntry,
+ NewEventHdr,
+ sizeof(TCG_PCR_EVENT_HDR) -sizeof(NewEventHdr->Digest) - sizeof(UINT32));
+
+ TempSize = sizeof(TCG_PCR_EVENT_HDR) -sizeof(NewEventHdr->Digest) - sizeof(UINT32);
+
+ pBS->CopyMem(
+ (VOID*)(UINTN)(LastEntry + TempSize) ,
+ (UINT8 *)&NewEventHdr->Digest.digest,
+ sizeof(NewEventHdr->Digest.digest));
+
+ TempSize+=sizeof(NewEventHdr->Digest.digest);
+
+ }else{
+
+ /* pBS->CopyMem(
+ (VOID*)(UINTN)LastEntry,
+ NewEventHdr,
+ sizeof(TCG_PCR_EVENT_HDR) -sizeof(NewEventHdr->Digest) - sizeof(UINT32));
+
+ TempSize = sizeof(TCG_PCR_EVENT_HDR) -sizeof(NewEventHdr->Digest) - sizeof(UINT32);
+
+ pBS->CopyMem(
+ (VOID*)(UINTN)(LastEntry + TempSize) ,
+ (UINT8 *)&NewEventHdr->Digest.digestSha2,
+ sizeof(NewEventHdr->Digest.digestSha2));
+
+ TempSize+=sizeof(NewEventHdr->Digest.digestSha2);*/
+ return EFI_UNSUPPORTED;
+ }
+
+
+ pBS->CopyMem(
+ (VOID*)(UINTN)(LastEntry + TempSize) ,
+ (UINT8 *)&NewEventHdr->EventSize,
+ sizeof(UINT32));
+
+ pBS->CopyMem(
+ (VOID*)(UINTN)(LastEntry + TempSize + sizeof(UINT32)) ,
+ NewEventData,
+ NewEventHdr->EventSize);
+
+ TempSize+=sizeof(UINT32);
+ LastEntry = LastEventPtr + ((EFI_PHYSICAL_ADDRESS)(UINTN)(NewEventHdr->EventSize \
+ + TempSize));
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+TreeHashLogExtentEvent (
+ IN EFI_TREE_PROTOCOL *This,
+ IN UINT64 Flags,
+ IN EFI_PHYSICAL_ADDRESS DataToHash,
+ IN UINT64 DataToHashLen,
+ IN TrEE_EVENT *TreeEvent
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_PCR_EVENT_HDR TcgEvent;
+
+ if((This == NULL ) || (DataToHash == 0) || (TreeEvent == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+ else if(TreeEvent->Size < (TreeEvent->Header.HeaderSize + sizeof(UINT32))\
+ || (TreeEvent->Header.PCRIndex > 23)){
+ Status = EFI_INVALID_PARAMETER;
+ goto Exit;
+ }
+
+ TcgEvent.PCRIndex = TreeEvent->Header.PCRIndex;
+ TcgEvent.EventType = TreeEvent->Header.EventType;
+ TcgEvent.EventSize = TreeEvent->Size - sizeof(TrEE_EVENT_HEADER) \
+ -sizeof(UINT32);
+
+ Status = TpmHashLogExtendEventI(
+ (UINT8 *)(UINTN)DataToHash,
+ Flags,
+ (UINTN) DataToHashLen,
+ &TcgEvent,
+ (UINT8 *)&TreeEvent->Event
+ );
+
+Exit:
+
+ return Status;
+}
+
+
+EFI_STATUS
+TreeSubmitCommand (
+IN EFI_TREE_PROTOCOL *This,
+IN UINT32 InputParameterBlockSize,
+IN UINT8 *InputParameterBlock,
+IN UINT32 OutputParameterBlockSize,
+IN UINT8 *OutputParameterBlock
+ )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 ReturnSize = 0;
+ UINT32 Size = 0;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ if (This == NULL || InputParameterBlock == NULL || OutputParameterBlock == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if(Tpm20FwDevice ==FALSE)
+ {
+ ReturnSize = OutputParameterBlockSize;
+
+ Status = TpmDevice->Init( TpmDevice );
+
+ InBuffer[0].Buffer = InputParameterBlock;
+ InBuffer[0].Size = InputParameterBlockSize;
+ OutBuffer[0].Buffer = OutputParameterBlock;
+ OutBuffer[0].Size = OutputParameterBlockSize;
+
+
+ TpmDevice->Transmit(TpmDevice,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer);
+
+ TpmDevice->Close(TpmDevice );
+ }else{
+
+ Size = OutputParameterBlockSize;
+ Status = CrbSubmitCmd(InputParameterBlock,
+ InputParameterBlockSize,
+ OutputParameterBlock,
+ &Size);
+ }
+
+ return Status;
+}
+
+
+
+static EFI_STATUS CopyTcgLog(
+ void )
+{
+ TCG_LOG_HOB *TcgLog = NULL;
+ void** DummyPtr;
+ EFI_GUID gEfiPeiLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+
+ TcgLog = (TCG_LOG_HOB*) LocateATcgHob(
+ pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gEfiPeiLogHobGuid );
+
+ DummyPtr = &TcgLog;
+
+ if ( *DummyPtr == NULL )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ TcgLog->TableMaxSize = MAX_LOG_AREA_SIZE;
+
+ pBS->CopyMem(
+ (UINT8 *)(UINTN)TreeEventLogLocation,
+ (((UINT8 *)TcgLog) + sizeof(TCG_LOG_HOB)),
+ TcgLog->TableSize
+ );
+
+ LastEntry = TreeEventLogLocation + TcgLog->TableSize;
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_TREE_PROTOCOL mTreeProtocol = {
+ TreeGetCapability,
+ TreeGetEventLog,
+ TreeHashLogExtentEvent,
+ TreeSubmitCommand
+};
+
+AMI_INTERNAL_HLXE_PROTOCOL InternalLogProtocol = {
+ TpmHashLogExtendEventI
+};
+
+
+
+EFI_STATUS
+InstallTrEEProtocol(
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ EFI_GUID gEfiTrEEProtocolGuid = EFI_TREE_PROTOCOL_GUID;
+ EFI_GUID gEfiAmiHLXEGuid = AMI_PROTOCOL_INTERNAL_HLXE_GUID;
+
+ TRACE(( TRACE_ALWAYS," InstallTrEEProtocol \n"));
+ Status = pBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiTrEEProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mTreeProtocol
+ );
+
+ Status = pBS->InstallProtocolInterface (
+ &Handle,
+ &gEfiAmiHLXEGuid,
+ EFI_NATIVE_INTERFACE,
+ &InternalLogProtocol
+ );
+
+ Status = pBS->AllocatePages(AllocateAnyPages,
+ EfiRuntimeServicesData,
+ EFI_SIZE_TO_PAGES(MAX_LOG_AREA_SIZE),
+ (UINT64*)(UINTN)&TreeEventLogLocation);
+
+ pBS->SetMem(
+ (VOID*)((UINTN)TreeEventLogLocation),
+ (UINTN)MAX_LOG_AREA_SIZE,
+ 0x00);
+
+ //locate PEI hob and copy to the TreeLogArea
+ Status = CopyTcgLog();
+
+ TRACE(( TRACE_ALWAYS," InstallTrEEProtocol Exit Status = %r \n", Status));
+ return Status;
+}
+
+
+
+
+VOID UpdateTpmDeviceASL(
+ IN EFI_EVENT ev,
+ IN VOID *ctx)
+{
+ ACPI_HDR *dsdt;
+ EFI_PHYSICAL_ADDRESS dsdtAddress=0;
+ static VOID *reg;
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+ UINT64 Value;
+
+
+ //locate AcpiProtocol
+
+ Status = LibGetDsdt(&dsdtAddress, EFI_ACPI_TABLE_VERSION_ALL);
+ if (EFI_ERROR(Status)){
+ TRACE((TRACE_ALWAYS, "UpdateTpmDeviceASL::DSDT not found\n"));
+ if(Status == EFI_NOT_AVAILABLE_YET){
+ //set callback
+ Status = pBS->CreateEvent( EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_DRIVER, UpdateTpmDeviceASL, &reg, &Event );
+
+ if(EFI_ERROR(Status)){
+ TRACE((TRACE_ALWAYS, "Unable to create Event..Exit(1)\n"));
+ return;
+ }
+ Status = pBS->RegisterProtocolNotify( &gEfiAcpiSupportGuid, Event, &reg );
+ }
+ return;
+ }
+
+ TRACE((TRACE_ALWAYS, "UpdateTpmDeviceASL::dsdtAddress %x \n", dsdtAddress));
+ dsdt = (ACPI_HDR*)dsdtAddress;
+
+ TRACE((TRACE_ALWAYS, "dsdt->Signature = %x \n", dsdt->Signature));
+
+ Value = 1;
+ Status=UpdateAslNameObject(dsdt, "TTDP", (UINT64)Value);
+ if (EFI_ERROR(Status)){
+ TRACE((TRACE_ALWAYS, "UpdateTpmDeviceASL::Failure setting ASL TTDP %r \n", Status));
+ return;
+ }
+
+ if(isTpm20CrbPresent()){
+ Value = 0;
+ }else{
+ Value = 1;
+ }
+
+ Status=UpdateAslNameObject(dsdt, "TTPF", (UINT64)Value);
+ if (EFI_ERROR(Status)){
+ TRACE((TRACE_ALWAYS, "UpdateTpmDeviceASL::Failure setting ASL value %r \n", Status));
+ }
+ return;
+}
+
+VOID ReadMORValue( );
+
+
+EFI_STATUS
+EFIAPI Tcg20DxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ TCG_PLATFORM_SETUP_PROTOCOL *PolicyInstance;
+ EFI_GUID gPolicyguid = TCG_PLATFORM_SETUP_POLICY_GUID;
+ TCG_CONFIGURATION Config;
+
+ TRACE(( TRACE_ALWAYS," Tcg20DxeEntry \n"));
+ if(!IsTpm20Device()){
+ if(!isTpm20CrbPresent()){
+ TRACE(( TRACE_ALWAYS," isTpm20CrbPresent returned false \n"));
+ return EFI_UNSUPPORTED;
+ }
+ TRACE(( TRACE_ALWAYS," Tpm20FwDevice = TRUE \n"));
+ Tpm20FwDevice = TRUE;
+ }
+
+ if(Tpm20FwDevice == FALSE)
+ {
+ Status = pBS->LocateProtocol(
+ &gEfiTpmDeviceProtocolGuid,
+ NULL,
+ &TpmDevice);
+ }
+
+ Status = pBS->LocateProtocol (&gPolicyguid, NULL, &PolicyInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ ReadMORValue();
+
+ MemCpy(&Config, &PolicyInstance->ConfigFlags, sizeof(TCG_CONFIGURATION));
+
+ if(Config.TpmSupport != 0){
+ Config.Tpm20Device = 1;
+ }else{
+ Config.Tpm20Device = 0;
+ PolicyInstance->UpdateStatusFlags(&Config, TRUE);
+ return EFI_SUCCESS;
+ }
+
+ PolicyInstance->UpdateStatusFlags(&Config, TRUE);
+
+ Status = InstallTrEEProtocol(ImageHandle);
+ if(EFI_ERROR(Status))return EFI_ABORTED;
+
+ //install binding protocol TrEE binding protocol
+ Tpm20DriverBinding.DriverBindingHandle = ImageHandle;
+ Tpm20DriverBinding.ImageHandle = ImageHandle;
+
+ Status = pBS->InstallMultipleProtocolInterfaces (
+ &Tpm20DriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &Tpm20DriverBinding,
+ &gEfiComponentNameProtocolGuid, &gComponentName,
+ &gEfiComponentName2ProtocolGuid, &gComponentName2,
+ NULL);
+
+ UpdateTpmDeviceASL(NULL, NULL);
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/EM/TCG2/Common/TcgLegacy.c b/Core/EM/TCG2/Common/TcgLegacy.c
new file mode 100644
index 0000000..5453141
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgLegacy.c
@@ -0,0 +1,977 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.c 2 6/14/14 12:35a Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/14/14 12:35a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.c $
+//
+// 2 6/14/14 12:35a Fredericko
+//
+// 1 4/21/14 2:17p Fredericko
+//
+// 1 10/08/13 12:04p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 3:07p Fredericko
+//
+// 1 7/10/13 5:56p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 7 4/05/11 8:06p Fredericko
+// TCG Legacy IO support changes
+//
+// 6 3/31/11 4:58p Fredericko
+// Changes for TCG_LEGACY support
+//
+// 5 3/29/11 1:28p Fredericko
+//
+// 4 3/28/11 3:38p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 3 7/14/10 2:56p Fredericko
+// Included logic to update the CSM16 Table checksum.
+//
+// 2 5/20/10 8:56a Fredericko
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+// 1 3/23/10 7:57p Fredericko
+//
+// 21 3/19/10 4:20p Fredericko
+// modified for legacy IO interface support
+//
+// 20 12/31/09 2:36p Fredericko
+// Update Location of BevBcv function after legacy init call
+//
+// 19 11/19/09 4:13p Fredericko
+// Update last event for legacy efi aspect of boot
+//
+// 18 11/09/09 5:26p Fredericko
+// Changes for Memory Leak EIP 28575
+//
+// 17 6/02/09 2:38p Fredericko
+//
+// 16 6/01/09 4:15p Fredericko
+// Changes added for TCM_SUPPORT
+//
+// 15 4/30/09 6:15p Fredericko
+// Updated Header Date
+//
+// 14 4/30/09 5:32p Fredericko
+// AMI company Header Address changes
+//
+// 13 4/03/09 6:13p Fredericko
+// Coding standard changes
+//
+// 12 3/05/09 2:59p Fredericko
+//
+// 11 2/05/09 5:23p Fredericko
+// Use Trace instead of Debug for debug messages, Removed EDK headers
+// included and "gbs" changed to "pBS"
+//
+// 10 2/27/08 5:52p Fredericko
+// Tcg Specification Compliance changes
+//
+// 9 9/26/07 2:45p Fredericko
+// Build in TRACE mode fixes
+//
+// 8 9/04/07 6:07p Fredericko
+// Changes made for new compiler swtich "\W4" to work
+//
+// 7 9/04/07 10:19a Fredericko
+// Measuring Embedded PciROM pointer fixes.
+//
+// 6 6/13/07 5:17p Fredericko
+// Function to read embedded option ROMS
+//
+// 5 11/03/06 6:34p Andriyn
+//
+// 4 8/15/06 9:28a Andriyn
+//
+// 3 6/22/06 3:03p Andriyn
+//
+// 2 6/20/06 7:13p Andriyn
+// Changes due to protocols moved to MiscFramework
+//
+// 1 6/20/06 5:58p Andriyn
+//**********************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgLegacy.c
+//
+// Description:
+// Contains functions that handle setting up the handoff between EFI and Legacy
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <EFI.h>
+#include "TcgLegacy.h"
+#include "token.h"
+#include "TCGMisc.h"
+#include <Protocol\LegacyRegion.h>
+#include "TcgCommon.h"
+#include "protocol\TcgService\TcgTcmService.h"
+#include "protocol\TcgService\TcgService.h"
+#include "protocol\TpmDevice\TpmDevice.h"
+#include <Protocol\FirmwareVolume.h>
+#include <Protocol\LegacyBios.h>
+#include <AmiDxeLib.h>
+#include <Tpm20Includes\TrEEProtocol.h>
+
+
+EFI_GUID gEfiAmiTcgWakeEventDataHobGuid = EFI_TCG_WAKE_EVENT_DATA_HOB_GUID;
+EFI_GUID gEfiAmiHobListGuid = TCG_EFI_HOB_LIST_GUID;
+EFI_GUID gEfiAmiTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+EFI_GUID gEfiIntTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+
+
+
+#define GUID_VARIABLE_DECLARATION( Variable, Guid ) extern EFI_GUID Variable
+EFI_GUID gEfiAmiTHobListGuid = TCG_EFI_HOB_LIST_GUID;
+
+#include "TcgPc.h"
+
+void* AllocateRTMemory (
+ UINTN size );
+
+EFI_GUID TCGLEGX16_FILE_GUID
+ = {0x142204e2, 0xc7b1, 0x4af9, 0xa7, 0x29, 0x92, 0x37, 0x58, 0xd9, 0x6d, 0x3};
+
+EFI_GUID TPM32_FILE_GUID =
+ {0xaa31bc6, 0x3379, 0x41e8, 0x82, 0x5a, 0x53, 0xf8, 0x2c, 0xc0, 0xf2, 0x54};
+
+EFI_GUID MPTPM_FILE_GUID
+ ={0x7d113aa9, 0x6280, 0x48c6, 0xba, 0xce, 0xdf, 0xe7, 0x66, 0x8e, 0x83, 0x7};
+
+EFI_GUID TCMLEGX16_FILE_GUID
+ = {0x1E753E16, 0xDCEF, 0x47d0, 0x9A, 0x38, 0x7A, 0xDE, 0xCD, 0xB9, 0x83, 0xED};
+
+EFI_GUID TCM32_FILE_GUID =
+ {0xB74E676E,0x3B2E, 0x483f, 0x94, 0x58, 0xC3, 0x78, 0xFE, 0x0A, 0xC6, 0x9F};
+
+
+EFI_GUID gEfiLegacyRegionProtocol = EFI_LEGACY_REGION_PROTOCOL_GUID;
+
+#define GET_HOB_TYPE( Hob ) ((Hob).Header->HobType)
+#define GET_HOB_LENGTH( Hob ) ((Hob).Header->HobLength)
+#define GET_NEXT_HOB( Hob ) ((Hob).Raw + GET_HOB_LENGTH( Hob ))
+#define END_OF_HOB_LIST( Hob ) (GET_HOB_TYPE( Hob ) == \
+ EFI_HOB_TYPE_END_OF_HOB_LIST)
+
+static TPM32HEADER * installedTpm32 = 0;
+static EFI_TCG_PROTOCOL * gTcgProtocol = 0;
+extern TCG_ACPI_TABLE mTcgAcpiTableTemplate;
+UINT8 Tpm20Support = 0;
+
+
+#define _CR( Record, TYPE,\
+ Field )((TYPE*) ((CHAR8*) (Record) - (CHAR8*) &(((TYPE*) 0)->Field)))
+
+#define TCG_DXE_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TCG_DXE_PRIVATE_DATA, TcgServiceProtocol )
+
+#define TCM_DXE_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TCM_DXE_PRIVATE_DATA, TcgServiceProtocol )
+
+typedef struct _TCG_DXE_PRIVATE_DATA
+{
+ EFI_TCG_PROTOCOL TcgServiceProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+} TCG_DXE_PRIVATE_DATA;
+
+typedef struct _TCM_DXE_PRIVATE_DATA
+{
+ EFI_TCM_PROTOCOL TcgServiceProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+} TCM_DXE_PRIVATE_DATA;
+
+#pragma pack (1)
+typedef struct _TCG_PCR_EVENT_HDR2 {
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+} TCG_PCR_EVENT_HDR2;
+#pragma pack()
+
+EFI_TREE_PROTOCOL *TrEEProtocolInstance = NULL;
+#define MAX_LOG_AREA_SIZE (32 * 1024)
+
+
+#define SEG_ALIGNMENT 0x10
+
+
+void TcgLogEventProxy(
+ TCG_PCR_EVENT* data )
+{
+ UINT32 n;
+
+ gTcgProtocol->LogEvent( gTcgProtocol, data, &n, 0x01 );
+}
+
+void TreeLogEventProxy(
+ TCG_PCR_EVENT* data )
+{
+ return; //unsupported
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: linkTPMDriver
+//
+// Description: Establishes link used to synchronize change to the
+// LOG when done through the INT1A interface while DXE is still in
+// control.
+//
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+void linkTPMDriver(
+ IN OUT TPM32HEADER * tpm32,
+ IN EFI_TCG_PROTOCOL *tcgProtocol )
+{
+ TCG_LOG_HOB *TcgLog;
+ TCG_EFI_BOOT_SERVICE_CAPABILITY Cap;
+ EFI_PHYSICAL_ADDRESS EventLogLoc;
+ EFI_PHYSICAL_ADDRESS LastEv;
+ BOOLEAN IsTrancated;
+ EFI_STATUS Status;
+
+ gTcgProtocol = tcgProtocol;
+
+ tpm32->lastEventShadow = 0;
+ tpm32->ptrOnTPMFailue = 0;
+
+ if(Tpm20Support == 0)
+ {
+ tpm32->efi_log_event_ptr = (UINTN) (void*)(UINTN)TcgLogEventProxy;
+
+ gTcgProtocol->StatusCheck( gTcgProtocol, &Cap, NULL, &EventLogLoc, &LastEv );
+ TcgLog = (TCG_LOG_HOB*)(UINTN)EventLogLoc;
+ TcgLog--;
+
+ TRACE((TRACE_ALWAYS, "\n\n linkTPMDriver: TCGLOG( %x )\n", TcgLog));
+
+
+ tpm32->log.memptr = (UINT32)( UINTN ) EventLogLoc;
+ tpm32->log.dwSize = TcgLog->TableMaxSize;
+ tpm32->lastEventShadow = 0;
+ }else{
+ if(TrEEProtocolInstance ==NULL) return;
+
+ tpm32->efi_log_event_ptr = (UINTN) (void*)(UINTN)TreeLogEventProxy;
+
+ Status = TrEEProtocolInstance->GetEventLog(TrEEProtocolInstance, TREE_BOOT_HASH_ALG_SHA1,\
+ &EventLogLoc, &LastEv, &IsTrancated);
+ tpm32->lastEventShadow = 0;
+ tpm32->ptrOnTPMFailue = 0;
+
+ tpm32->log.memptr = (UINT32)( UINTN ) EventLogLoc;
+ tpm32->log.dwSize = MAX_LOG_AREA_SIZE;
+ tpm32->lastEventShadow = 0;
+
+ }
+}
+
+
+UINT32 CountEvents(EFI_PHYSICAL_ADDRESS TcgLog, UINTN Eventlast, UINT8 HashPolicy)
+{
+ TCG_PCR_EVENT_HDR2 *TcgLogNext = (TCG_PCR_EVENT_HDR2 *)TcgLog;
+ UINTN NextLoc =0;
+ UINT32 EventSize=0;
+ UINTN *ValidCheck;
+ UINTN *ValidCheckNext;
+ UINT32 EventCount=0;
+ UINTN i=0;
+
+ ValidCheck = (UINTN *)TcgLog;
+ ValidCheckNext = ValidCheck + 1;
+
+ if(TcgLogNext == NULL) return EventCount;
+ if((UINTN)ValidCheck > Eventlast) return EventCount;
+ if(*ValidCheck == 0 && *ValidCheckNext == 0)return EventCount;
+
+ if(HashPolicy == 0)
+ {
+ //return the location of the next log
+ while((UINTN)ValidCheck <= Eventlast)
+ {
+
+ ValidCheckNext = ValidCheck + 1;
+ if(*ValidCheck == 0 && *ValidCheckNext == 0)break;
+
+ if(TcgLogNext->PCRIndex < 0)break;
+ EventSize = *(UINT32 *)(((UINTN)TcgLogNext) + TPM_SHA1_160_HASH_LEN + sizeof(TCG_PCR_EVENT_HDR2));
+ NextLoc = (UINTN)(((UINTN)TcgLogNext)+ EventSize + sizeof(EventSize)+\
+ + TPM_SHA1_160_HASH_LEN + sizeof(TCG_PCR_EVENT_HDR2));
+
+ TcgLogNext = (TCG_PCR_EVENT_HDR2 *)NextLoc;
+ ValidCheck = (UINTN *)NextLoc;
+ EventCount+=1;
+
+ }
+ }else{
+ //unsupported SHA1 only for now
+ }
+
+ return (EventCount);
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: UnlinkTPM32fromEFI
+//
+// Description: Breaks the link that exist between TPM32 code and DXE TCG
+// driver. The established link was used to synchronize change to the
+// LOG when done through the INT1A interface while DXE is still in
+// control. Need to break this link one DXE driver is stoped or EFI
+// boots OS ( including calling INT19)
+//
+//
+// Input: IN EFI_EVENT Event,
+// IN VOID *Context
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS EFIAPI UnlinkTPM32fromEFI(
+ IN EFI_EVENT Event,
+ IN VOID *Context )
+{
+ TCG_LOG_HOB *TcgLog;
+ TPM32HEADER * tpm32 = (TPM32HEADER*)Context;
+ EFI_PHYSICAL_ADDRESS logStart, logLast;
+ TCG_EFI_BOOT_SERVICE_CAPABILITY TcgCapability;
+ BOOLEAN IsTrancated;
+ EFI_STATUS Status;
+ UINT32 FreeLogSize;
+ SHA1_PCR_EVENT *PtrtoLastEvent;
+
+ if ( installedTpm32 == 0 )
+ {
+ return EFI_SUCCESS;
+ }
+
+ if(Tpm20Support == 0)
+ {
+ ASSERT( installedTpm32 == tpm32 );
+ TRACE((TRACE_ALWAYS, "UnlinkTPM32fromEFI: TPM32( %x )\n", tpm32));
+ installedTpm32 = 0;
+
+ tpm32->lastEventShadow = 0;
+ tpm32->efi_log_event_ptr = 0;
+ Status = gTcgProtocol->StatusCheck( gTcgProtocol,
+ &TcgCapability,
+ NULL,
+ &logStart,
+ &logLast );
+
+ if ( EFI_ERROR( Status ))
+ {
+ tpm32->last = 0;
+ tpm32->freelog = 0;
+ return Status;
+ }
+ TcgLog = (TCG_LOG_HOB*)(UINTN)logStart;
+ TcgLog--;
+
+ tpm32->last = (UINT32)( UINTN ) ( logLast - logStart );
+ tpm32->TPMAcDeact = TcgCapability.TPMDeactivatedFlag;
+ tpm32->freelog = TcgLog->TableSize;
+ tpm32->nextevent = TcgLog->EventNum + 1;
+
+ tpm32->Tpm20Enabled = 0;
+ }else{
+
+ ASSERT( installedTpm32 == tpm32 );
+ TRACE((TRACE_ALWAYS, "UnlinkTPM32fromEFI: TPM32( %x )\n", tpm32));
+ installedTpm32 = 0;
+
+ if(TrEEProtocolInstance ==NULL) return EFI_SUCCESS;
+
+ Status = TrEEProtocolInstance->GetEventLog(TrEEProtocolInstance, TREE_BOOT_HASH_ALG_SHA1,\
+ &logStart, &logLast, &IsTrancated);
+ tpm32->lastEventShadow = 0;
+ tpm32->ptrOnTPMFailue = 0;
+
+ tpm32->lastEventShadow = 0;
+ tpm32->efi_log_event_ptr = 0;
+
+ tpm32->last = (UINT32)( UINTN ) ( logLast );
+ tpm32->TPMAcDeact = 0;
+ FreeLogSize = (UINT32)(logLast - logStart);
+ FreeLogSize += (sizeof(SHA1_PCR_EVENT)- 1);
+ PtrtoLastEvent = (SHA1_PCR_EVENT *)(logLast);
+ FreeLogSize += PtrtoLastEvent->EventSize;
+ tpm32->freelog = FreeLogSize;
+ tpm32->nextevent = CountEvents(logStart,logLast,0);
+ tpm32->Tpm20Enabled = 1;
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetRawImage
+//
+// Description: Loads binary from RAW section of main firwmare volume
+//
+//
+// Input: IN EFI_GUID *NameGuid,
+// IN OUT VOID **Buffer,
+// IN OUT UINTN *Size
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS GetRawImage(
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *Size )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *HandleBuffer = 0;
+ UINTN HandleCount = 0;
+ UINTN i;
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ UINT32 AuthenticationStatus;
+
+ Status = pBS->LocateHandleBuffer(
+ ByProtocol,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ &HandleCount,
+ &HandleBuffer
+ );
+
+ if ( EFI_ERROR( Status ) || HandleCount == 0 )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Find desired image in all Fvs
+ //
+ for ( i = 0; i < HandleCount; i++ )
+ {
+ Status = pBS->HandleProtocol(
+ HandleBuffer[i],
+ &gEfiFirmwareVolumeProtocolGuid,
+ &Fv
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ pBS->FreePool( HandleBuffer );
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Try a raw file
+ //
+ *Buffer = NULL;
+ *Size = 0;
+ Status = Fv->ReadSection(
+ Fv,
+ NameGuid,
+ EFI_SECTION_RAW,
+ 0,
+ Buffer,
+ Size,
+ &AuthenticationStatus
+ );
+
+ if ( !EFI_ERROR( Status ))
+ {
+ break;
+ }
+ }
+ pBS->FreePool( HandleBuffer );
+
+ if ( i >= HandleCount )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AllocateRTMemory
+//
+// Description: Allocates memory used by TCG Legacy code during run-time
+//
+//
+// Input: IN UINTN size
+//
+// Output: VOID*
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+void* AllocateRTMemory(
+ IN UINTN size )
+{
+ EFI_STATUS Status;
+ void * addr = 0;
+
+ Status = pBS->AllocatePool( EfiRuntimeServicesCode, size, &addr );
+ return addr;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FindCompatibility16Table
+//
+// Description: This function identifies the validity of CSM16 binary by
+// searching "$EFI" and verifying table checksum and returs the
+// location of $EFI table
+//
+// Input:
+//
+// Output: EFI_COMPATIBILITY16_TABLE*
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_COMPATIBILITY16_TABLE* FindCompatibility16Table( )
+{
+ UINT8 *p = NULL, *p1 = NULL;
+ UINT32 *data32;
+ UINT32 count32;
+ UINT8 chksum, count8, tablelength;
+
+ //
+ // Find CSM16 entry point; "$EFI" is in E0000..FFFFF, 16 bytes aligned.
+ //
+ data32 = (UINT32*)(UINTN)0xE0000;
+
+ for ( count32 = 0; count32 < 0x8000; count32 += 4 )
+ {
+ if ( data32[count32] != 0x24454649 )
+ {
+ continue;
+ }
+ p = (UINT8*)((UINTN)data32 + (count32 << 2)); // Pointer to "$EFI"
+
+ //
+ // Verify the checksum
+ //
+ tablelength = ((EFI_COMPATIBILITY16_TABLE*)p)->TableLength;
+
+ for ( chksum = 0, count8 = 0, p1 = p; count8 < tablelength; count8++ )
+ {
+ chksum = chksum + *p1++;
+ }
+
+ if ( chksum == 0 )
+ {
+ break;
+ }
+ }
+
+ if ( count32 == 0x8000 )
+ {
+ return 0;
+ }
+
+ return ((EFI_COMPATIBILITY16_TABLE*)p);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetTCGLegacyInterface
+//
+// Description: Loads legacy BIOS binary extensions (TcgLegX16,
+// TPM32 and MPTPM ) and initializes the TCG Legacy support.
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS InitTCGLegacyInterface(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ TCG_LEGX16_HEADER *legX16header;
+ void * legX16dest;
+ UINTN legX16size;
+ EFI_LEGACY_BIOS_PROTOCOL *legBios;
+ void * rawPtr;
+ static TpmBinaryStruct tpmBinary;
+ UINT16 segLegX16;
+ TPM32HEADER * tpm32hdr;
+ UINTN tpm32size;
+ TPMBIOSDriverHeader * mptpmHdr;
+#if TCG_LEGACY == 0
+ UINTN mpTpmSize;
+#endif
+ EFI_TCG_PROTOCOL *tcgProtocol;
+ EFI_EVENT event;
+ EFI_LEGACY_REGION_PROTOCOL * iRegion;
+ EFI_GUID gMpDriverHobGuid = EFI_TCG_MPDriver_HOB_GUID;
+ FAR32LOCALS *LegFill = NULL;
+ void *Table = NULL;
+ UINTN TableSize = 0;
+ UINTN Location = 0;
+ UINTN Alignment = 0;
+ EFI_GUID gEfiTrEEProtocolGuid = EFI_TREE_PROTOCOL_GUID;
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ if ( installedTpm32 != 0 )
+ {
+ ASSERT( installedTpm32 == 0 );
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Access EFI TPM driver
+ //
+ Status = pBS->LocateProtocol( &gEfiIntTcgProtocolGuid, NULL,
+ &tcgProtocol );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "TCG Service is not found: error=%x\n", Status));
+ tcgProtocol = 0;
+ Status = pBS->LocateProtocol( &gEfiTrEEProtocolGuid, NULL, &TrEEProtocolInstance );
+ if(EFI_ERROR(Status))return Status;
+ Tpm20Support = 1;
+ }
+
+
+ //
+ // Access legacyBios internals
+ //
+ EFI_VERIFY(
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosProtocolGuid,
+ NULL,
+ &legBios
+ ));
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+#if TCG_LEGACY == 0
+ if(AutoSupportType()){
+ TCGLEGX16_FILE_GUID = TCMLEGX16_FILE_GUID;
+ TPM32_FILE_GUID = TCM32_FILE_GUID;
+ }
+#else
+ TCGLEGX16_FILE_GUID = TCMLEGX16_FILE_GUID;
+ TPM32_FILE_GUID = TCM32_FILE_GUID;
+#endif
+
+
+ //
+ // Load LEGX16 into legacy region
+ //
+ rawPtr = 0;
+ Status = GetRawImage( &TCGLEGX16_FILE_GUID, &rawPtr, &legX16size );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Failed to load LEGX16: error=%x\n", Status));
+ return Status;
+ }
+ legX16header = (TCG_LEGX16_HEADER* )rawPtr;
+ EFI_VERIFY(
+ legBios->GetLegacyRegion( legBios, legX16size + SEG_ALIGNMENT, 0,
+ SEG_ALIGNMENT, &legX16dest ));
+ segLegX16 = (UINT16)((UINTN)legX16dest >> 4 );
+
+ //
+ // Load TPM32 into runtime-code memory
+ //
+ Status = GetRawImage( &TPM32_FILE_GUID, &rawPtr, &tpm32size );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Failed to load TPM32: error=%x\n", Status));
+ return Status;
+ }
+ tpm32hdr = AllocateRTMemory( tpm32size );
+ MemCpy( tpm32hdr, rawPtr, tpm32size );
+
+ //
+ // Load MPTPM into runtime-code memory
+ //
+#if TCG_LEGACY == 0
+ if(!(AutoSupportType())){
+ Status = GetRawImage( &MPTPM_FILE_GUID, &rawPtr, &mpTpmSize );
+
+ if ( EFI_ERROR( Status )){
+ TRACE((TRACE_ALWAYS, "Failed to load MPTPM: error=%x\n", Status));
+ return Status;
+ }
+ mptpmHdr = AllocateRTMemory( mpTpmSize );
+ MemCpy( mptpmHdr, rawPtr, mpTpmSize );
+ }else{
+ LegFill = (FAR32LOCALS*)LocateATcgHob( pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gMpDriverHobGuid );
+ mptpmHdr = (TPMBIOSDriverHeader*)(UINTN)( LegFill->Offset - LegFill->Codep );
+ }
+#else
+ LegFill = (FAR32LOCALS*)LocateATcgHob( pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gMpDriverHobGuid );
+ mptpmHdr = (TPMBIOSDriverHeader*)(UINTN)( LegFill->Offset - LegFill->Codep );
+#endif
+
+
+
+ //
+ // Link pointers from TPM32 to MPTPM
+ //
+ tpm32hdr->MP_HDR = (UINT32)( UINTN ) mptpmHdr;
+ tpm32hdr->scratch.memptr = (UINT32)( UINTN ) AllocateRTMemory(
+ TPM32_SCRATCHMEM_SIZE );
+ tpm32hdr->scratch.dwSize = TPM32_SCRATCHMEM_SIZE;
+ {
+ UINT32 * p
+ = (UINT32*)((UINT8*)legX16header + legX16header->wTpm32entryPtr);
+ *p = (UINT32)( UINTN ) tpm32hdr + tpm32hdr->entryPoint;
+ }
+ legX16header->wTpm32hdr = (UINT32)( UINTN ) tpm32hdr;
+ linkTPMDriver( tpm32hdr, tcgProtocol );
+ legX16header->regMOR = ((TCG_MOR_REG) << 8);
+
+ //
+ // Copy final LegX16 to dest (F000-E000 area)
+ //
+ legBios->CopyLegacyRegion( legBios, legX16size, legX16dest, legX16header );
+ legX16header = (TCG_LEGX16_HEADER* )legX16dest;
+
+
+ //
+ // Unlock E000-F000: Init will update variable inside LEGX16
+ //
+ Status = pBS->LocateProtocol( &gEfiLegacyRegionProtocol, NULL, &iRegion );
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS,
+ "Failed to locate Legacy Region Protocol to unlock E000: %r\n",
+ Status));
+ return Status;
+ }
+ Status = iRegion->UnLock( iRegion, 0xE0000, 0x20000, NULL );
+
+ //
+ // Init LEGX16
+ //
+ {
+ EFI_IA32_REGISTER_SET Regs;
+
+ if ( EFI_ERROR( Status ))
+ {
+ TRACE((TRACE_ALWAYS, "Failed to unlock Legacy region E000: %r\n",
+ Status));
+ return Status;
+ }
+
+ MemSet( &Regs, sizeof (EFI_IA32_REGISTER_SET), 0 );
+ legBios->FarCall86(
+ legBios,
+ segLegX16,
+ legX16header->InitCode,
+ &Regs,
+ NULL,
+ 0
+ );
+ }
+
+ //
+ // Lock E000-F000
+ //
+ iRegion->Lock( iRegion, 0xE0000, 0x20000, NULL );
+
+ //
+ // Fills TpmBinaryStruct : Setup int1Ahook, int19Hook, and osloaderHook
+ //
+ tpmBinary.wLegX16Seg = segLegX16;
+ tpmBinary.int1a_dispatch = legX16header->int1a_dispatch;
+ tpmBinary.int19Ev = legX16header->int19Ev;
+ tpmBinary.intLoaderEv = legX16header->intLoaderEv;
+ tpmBinary.BevBcvEv = legX16header->BevBcvEv;
+
+ //
+ // Hookup for BootimeServices shutdown: need to strip *installedTpm32 off the
+ // pointers to BootTime data
+ //
+ installedTpm32 = tpm32hdr;
+
+ #if defined(EFI_EVENT_SIGNAL_READY_TO_BOOT) && EFI_SPECIFICATION_VERSION <\
+ 0x20000
+ EFI_VERIFY(
+ Status = gBS->CreateEvent( EFI_EVENT_SIGNAL_LEGACY_BOOT,
+ EFI_TPL_CALLBACK, UnlinkTPM32fromEFI,
+ tpm32hdr, &event ));
+ #else
+ EFI_VERIFY(
+ Status = CreateLegacyBootEvent(
+ EFI_TPL_CALLBACK,
+ UnlinkTPM32fromEFI,
+ tpm32hdr,
+ &event
+ ));
+ #endif
+ TRACE((TRACE_ALWAYS, "\tLEGX16: %x:%x, %x, %x\n",
+ tpmBinary.wLegX16Seg, tpmBinary.int1a_dispatch, tpmBinary.int19Ev,
+ tpmBinary.intLoaderEv));
+ TRACE((TRACE_ALWAYS, "\tTPM32: header:%x entry:%x log:%x logsize:%x\n",
+ (UINT32)( UINTN ) tpm32hdr, (UINT32)( UINTN ) tpm32hdr
+ + tpm32hdr->entryPoint));
+ TRACE((TRACE_ALWAYS, "\tMPTPM: %x\n", (UINT32)( UINTN ) mptpmHdr));
+
+ //
+ // Returns table pointing to TpmBinaryStruct
+ //
+ if ( Table != NULL && TableSize != NULL )
+ {
+ Table = &tpmBinary;
+ TableSize = (UINTN)sizeof(tpmBinary);
+
+ if ( Location )
+ {
+ Location = 0;
+ }
+
+ if ( Alignment )
+ {
+ Alignment = SEG_ALIGNMENT;
+ }
+ }
+ else {
+ //
+ // Put them int Leg Segment on our own
+ //
+ void * legPtr = 0;
+ EFI_COMPATIBILITY16_TABLE * bfi16 = 0;
+ UINT8 * p;
+ UINT8 chksum;
+ UINT8 i=0;
+
+ EFI_VERIFY(
+ legBios->GetLegacyRegion( legBios, sizeof(tpmBinary)
+ + SEG_ALIGNMENT, 0,
+ SEG_ALIGNMENT, &legPtr ));
+ Status = iRegion->UnLock( iRegion, 0xE0000, 0x20000, NULL );
+ MemCpy( legPtr, &tpmBinary, sizeof(tpmBinary));
+ bfi16 = FindCompatibility16Table( );
+
+ if ( bfi16 != 0 )
+ {
+ TRACE((TRACE_ALWAYS, "\tFound BFI at 0x%x\n", bfi16));
+ bfi16->TpmSegment = (UINT16)((UINTN)legPtr >> 4 );
+ bfi16->TpmOffset = 0;
+
+ bfi16->TableChecksum = 0;
+ p = (UINT8*)bfi16;
+ for (chksum=0, i=0; i<bfi16->TableLength; i++) {
+ chksum+=*p++;
+ }
+ bfi16->TableChecksum = ~(--chksum);
+ }
+
+
+ else {
+ TRACE((TRACE_ALWAYS, "\t!!!Not Found BFI\n"));
+ }
+ iRegion->Lock( iRegion, 0xE0000, 0x20000, NULL );
+ }
+
+
+ return EFI_SUCCESS;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/Common/TcgLegacy.cif b/Core/EM/TCG2/Common/TcgLegacy.cif
new file mode 100644
index 0000000..b2a318f
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgLegacy.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "TcgLegacy"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "TcgLegacy"
+[files]
+"TcgLegacy.sdl"
+"TcgLegacy.mak"
+"TcgLegacy.c"
+"TcgLegacy.h"
+"TcgLegacy.dxs"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/TcgLegacy.dxs b/Core/EM/TCG2/Common/TcgLegacy.dxs
new file mode 100644
index 0000000..d238b69
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgLegacy.dxs
@@ -0,0 +1,71 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.dxs 1 4/21/14 2:17p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:17p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.dxs $
+//
+// 1 4/21/14 2:17p Fredericko
+//
+// 1 10/08/13 12:04p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 3:09p Fredericko
+//
+// 1 7/10/13 5:56p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 5/20/10 8:58a Fredericko
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgLEgacy.dxs
+//
+// Description:
+// dependecy file
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Protocol/TcgService/TcgService.h>
+#include <Protocol/LegacyBios.h>
+
+DEPENDENCY_START
+ EFI_LEGACY_BIOS_PROTOCOL_GUID
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/TcgLegacy.h b/Core/EM/TCG2/Common/TcgLegacy.h
new file mode 100644
index 0000000..51e3fad
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgLegacy.h
@@ -0,0 +1,213 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.h 1 4/21/14 2:17p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:17p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.h $
+//
+// 1 4/21/14 2:17p Fredericko
+//
+// 1 10/08/13 12:04p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 3:08p Fredericko
+//
+// 1 7/10/13 5:56p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 5/20/10 8:57a Fredericko
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+// 1 3/23/10 7:57p Fredericko
+//
+// 11 12/31/09 2:42p Fredericko
+// modfied the legacy16 and tpm32 structure.
+//
+// 10 4/30/09 6:16p Fredericko
+// Updated Header Date
+//
+// 9 4/30/09 5:33p Fredericko
+// AMI company Header Address changed
+//
+// 8 3/05/09 3:17p Fredericko
+// Changes for CoreSources dependency
+//
+// 7 2/27/08 5:53p Fredericko
+// Change in tpm32Header
+//
+// 6 6/13/07 5:24p Fredericko
+// Function header for GetPCIOptionROM added
+//
+// 5 11/30/06 5:00p Fasihm
+// More organized and formatted.
+//
+// 4 8/25/06 4:10p Andriyn
+// Changed LEGX16HEADER with fields to track version information
+//
+// 3 8/22/06 1:30p Andriyn
+// MOR related changes
+//
+// 2 8/15/06 9:28a Andriyn
+//
+// 1 6/20/06 5:58p Andriyn
+//**********************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgLegacy.h
+//
+// Description:
+// Header file for TCG Legacy subcomponent
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <EFI.h>
+
+#pragma pack (push, 1)
+
+EFI_FORWARD_DECLARATION( EFI_LEGACY_TCG_PROTOCOL );
+
+typedef struct _TCG_LEGX16_HEADER TCG_LEGX16_HEADER;
+struct _TCG_LEGX16_HEADER
+{
+ UINT16 wHeaderSize;
+ UINT16 wLeg16Ver;
+ UINT32 wTpm32hdr;
+ UINT16 wTpm32entryPtr;
+ UINT16 int1a_dispatch;
+ UINT16 int19Ev;
+ UINT16 intLoaderEv;
+ UINT16 BevBcvEv;
+ UINT16 InitCode;
+ UINT16 Reserved;
+ UINT16 regMOR; //8-15: byte offset; 0-7: bit position
+};
+
+typedef struct _TpmBinaryStruct TpmBinaryStruct;
+struct _TpmBinaryStruct
+{
+ UINT16 wLegX16Seg;
+ UINT16 int1a_dispatch;
+ UINT16 int19Ev;
+ UINT16 intLoaderEv;
+ UINT16 BevBcvEv;
+};
+
+typedef struct _TPMBIOSDriverHeader TPMBIOSDriverHeader;
+struct _TPMBIOSDriverHeader
+{
+ UINT16 TPMSignature; // 55AAh
+ UINT32 TPMCodeOffset; // Offset to Entry Point
+ UINT16 TPMCodeSize;
+ UINT32 TPMBaseAddr; // Base Adress of CMD register
+ UINT32 TPMBaseAddrOpt;
+ UINT8 TPMIRQ;
+ UINT8 TPMDMA;
+ UINT8 TPMCheckSum;
+ UINT8 TPMReserve1; // 00h
+ UINT32 TPMPCIPFA;
+ UINT32 TPMUSB;
+ UINT32 TPMReserve2; // 00000000h
+ UINT16 TPMOEM0;
+ UINT16 TPMOEM1;
+};
+
+typedef struct _MEM_OBJECT MEM_OBJECT;
+struct _MEM_OBJECT
+{
+ UINT32 memptr; //void* memptr;
+ UINT32 dwSize;
+ UINT32 reserved1;
+};
+
+typedef struct _TPM32HEADER TPM32HEADER;
+struct _TPM32HEADER
+{
+ UINT32 Signature; //Signature of TPM32 module
+ UINT32 entryPoint; //offset to the dispatch code relative to the
+ //start of the TPM32 module
+ UINT32 MP_HDR; //TPMBIOSDriverHeader* MP_HDR;//offset to the start of the MP driver in MP_xSEG
+ MEM_OBJECT scratch;
+
+ //errType is one of { TCPA_ERRGRP_TPM,TCPA_ERRGRP_TCPA,or TCPA_ERRGRP_OTHER}
+ //see tcpatpm.inc
+ UINT32 errType;
+ UINT8 TPMAcDeact;
+ //meaning of errCode depends on errType: TPM err code, TCPA err code
+ //or own error code
+ UINT32 errCode;
+
+ UINT32 ptrOnTPMFailue;
+
+ MEM_OBJECT log;
+ UINT32 freelog;
+ UINT32 last;
+ UINT32 nextevent;
+ UINT32 lastEventShadow; // UINT8**
+ UINT8 Tpm20Enabled;
+ UINT64 efi_log_event_ptr;
+};
+
+typedef struct _SHA1_TCG_PCR_EVENT {
+ UINT32 PCRIndex; // PCRIndex event extended to
+ UINT32 EventType; // TCG EFI event type
+ UINT8 Digest[20]; // Value extended into PCRIndex
+ UINT32 EventSize; // Size of the event data
+ UINT8 Event[1]; // The event data
+} SHA1_PCR_EVENT;
+
+#pragma pack (pop)
+//
+// TcgLegacy imports
+//
+EFI_STATUS GetRawImage (
+ IN EFI_GUID *NameGuid,
+ IN OUT VOID **Buffer,
+ IN OUT UINTN *Size );
+
+EFI_STATUS GetPCIOPROMImage (
+ IN EFI_HANDLE PciHandle,
+ OUT VOID *RomImage,
+ OUT UINTN *Romsize,
+ OUT UINTN *Flags );
+#ifdef EFI_DEBUG
+ #define EFI_VERIFY( x ) ASSERT( !EFI_ERROR( x ))
+#else
+ #define EFI_VERIFY( x ) x
+#endif
+#define TPM32_SCRATCHMEM_SIZE 0x400
+#define TPM32_LOG_SIZE 0x1000
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/Common/TcgLegacy.mak b/Core/EM/TCG2/Common/TcgLegacy.mak
new file mode 100644
index 0000000..ce91db5
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgLegacy.mak
@@ -0,0 +1,104 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.mak 1 4/21/14 2:17p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:17p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgLegacy/TcgLegacy.mak $
+#
+# 1 4/21/14 2:17p Fredericko
+#
+# 1 10/08/13 12:04p Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 1 7/10/13 5:56p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+# 5 4/22/11 8:54p Fredericko
+# Changes for x32bit mode build
+#
+# 4 3/29/11 1:28p Fredericko
+#
+# 3 3/28/11 3:38p Fredericko
+# [TAG] EIP 54642
+# [Category] Improvement
+# [Description] 1. Checkin Files related to TCG function override
+# 2. Include TCM and TPM auto detection
+# [Files] Affects all TCG files
+#
+# 2 5/20/10 8:55a Fredericko
+# Included File Header
+# Included File Revision History
+# EIP 37653
+#
+#*************************************************************************
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: tcgLegacy.MAK
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all: TcgLegacy
+
+TcgLegacy : $(BUILD_DIR)\TcgLegacy.mak TcgLegacyBIN
+
+$(BUILD_DIR)\TcgLegacy.mak : $(TCGLEG_DIR)\TcgLegacy.cif $(TCGLEG_DIR)\TcgLegacy.mak $(BUILD_RULES)
+ $(CIF2MAK) $(TCGLEG_DIR)\TcgLegacy.cif $(CIF2MAK_DEFAULTS)
+
+TcgLegacyCflags=$(CFLAGS)\
+ /I$(TCG_DIR)\
+ /I$(TPM12_DIR)\
+ /I$(TCG_DIR)\Common\
+
+!IFNDEF LIB_BUILD_DIR
+!IF "$(PROCESSOR)"=="x64"
+AMITCMLIB = $(BUILD_DIR)\IA32\AmiTcmlib.lib
+!ELSE
+AMITCMLIB = $(BUILD_DIR)\AmiTcmlib.lib
+!ENDIF
+!ENDIF #LIB_BUILD_DIR
+
+
+TcgLegacyBIN: $(AMIDXELIB) $(AMITCMLIB) $(BUILD_DIR)\AmiTcgLibDxe.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TcgLegacy.mak all\
+ "CFLAGS=$(TcgLegacyCflags)"\
+ "CPFLAGS=$(TcgLegacyCflags)"\
+ GUID=858EBE6F-360F-415b-B7DC-463AAEB03412 \
+ ENTRY_POINT=InitTCGLegacyInterface\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/TCG2/Common/TcgLegacy.sdl b/Core/EM/TCG2/Common/TcgLegacy.sdl
new file mode 100644
index 0000000..c6de6fe
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgLegacy.sdl
@@ -0,0 +1,36 @@
+TOKEN
+ Name = "TcgLegacy_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TcgLegacy support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "TCGLEG_DIR"
+End
+
+MODULE
+ Help = "Includes TcgLegacy.mak to Project"
+ File = "TcgLegacy.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\TcgLegacy.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+TOKEN
+ Name = "TCG_MOR_REG"
+ Value = "0xE3"
+ Help = "Address of the MOR bit in CMOS (byte location in the bank of CMOS registers)"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/TcgPei.cif b/Core/EM/TCG2/Common/TcgPei.cif
new file mode 100644
index 0000000..013895b
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPei.cif
@@ -0,0 +1,18 @@
+<component>
+ name = "TcgPei"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "TcgPei"
+[files]
+"TcgPei.mak"
+"TisPei.c"
+"TcgPei.dxs"
+"TcgTisPei.c"
+"xTcgPei.c"
+"TcgTcmPei.c"
+"EMpTcmPei.c"
+"TcgCRBPei.c"
+"TcgPei.sdl"
+[parts]
+"TcgPeiAfterMem"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/TcgPei.dxs b/Core/EM/TCG2/Common/TcgPei.dxs
new file mode 100644
index 0000000..d4726c4
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPei.dxs
@@ -0,0 +1,114 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPei.dxs 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPei.dxs $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 11 3/29/11 12:57p Fredericko
+//
+// 10 3/28/11 2:10p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 9 5/19/10 5:45p Fredericko
+// Included File Header
+// Updated AMI copyright header
+// EIP 37653
+//
+// 8 6/01/09 4:23p Fredericko
+//
+// 7 4/30/09 6:21p Fredericko
+// Updated Header Date
+//
+// 6 4/30/09 5:41p Fredericko
+// AMI company Header Address changed
+//
+// 5 2/05/09 5:43p Fredericko
+// No more using EDK style includes
+//
+// 4 6/25/08 6:17p Fredericko
+// Txt related changes
+//
+// 3 6/02/08 8:37p Fredericko
+//
+// 2 6/22/06 3:03p Andriyn
+//
+// 1 6/20/06 5:58p Andriyn
+//
+// 4 3/03/06 5:18p Markw
+// Added checking boot mode.
+//
+// 3 2/03/06 10:30a Markw
+// This is loaded after memory.
+//
+// 2 10/05/05 4:38p Mirk
+// All changes based on P4 CPU label "1.00.18_INTEL_P4_05"
+//
+// 3 9/07/05 11:55a Markw
+// Added dependency on read only variable for setup.
+//
+//**********************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPei.dxs
+//
+// Description:
+// Dependency file for TcgPei subcomponent
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <pei.h>
+#include "ppi\LoadFile.h"
+#include <Ppi\ReadOnlyVariable.h>
+#include <token.h>
+
+
+DEPENDENCY_START
+ EFI_PEI_MASTER_BOOT_MODE_PEIM_PPI AND
+ EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/TcgPei.mak b/Core/EM/TCG2/Common/TcgPei.mak
new file mode 100644
index 0000000..99e7323
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPei.mak
@@ -0,0 +1,123 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPei.mak 1 4/21/14 2:16p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:16p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPei.mak $
+#
+# 1 4/21/14 2:16p Fredericko
+#
+# 1 10/08/13 12:02p Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 1:51p Fredericko
+#
+# 1 7/10/13 5:51p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+# 27 10/24/11 12:39p Fredericko
+# WAIT_FOR_MEM token is deprecated. Use the StartupCmd_Selftest_State to
+# control when TPM is first used.
+#
+# 26 9/27/11 10:20p Fredericko
+# [TAG] EIP67286
+# [Category] Improvement
+# [Description] changes for Tcg Setup policy
+# [Files] Tcg.sdl
+# TcgPei.cif
+# TcgPei.mak
+# xtcgPei.c
+# xTcgPeiAfterMem.c
+# TcgPeiAfterMem.mak
+# TcgDxe.cif
+# TcgDxe.mak
+# xTcgDxe.c
+# AmiTcgPlatformPeilib.c
+# AmiTcgPlatformDxelib.c
+#
+# 25 4/22/11 8:49p Fredericko
+# Changes for building in x32 bit mode.
+#
+# 24 3/29/11 12:56p Fredericko
+#
+# [TAG] EIP 54642
+# [Category] Improvement
+# [Description] 1. Checkin Files related to TCG function override
+# 2. Include TCM and TPM auto detection
+# [Files] Affects all TCG files
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: TCGPEI.MAK
+#
+# Description: Make file for the TcgPei component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : tcgPei
+
+tcgPei : $(BUILD_DIR)\TcgPei.mak TcgPeiBin
+
+$(BUILD_DIR)\TcgPei.mak : $(TCGPEI_DIR)\$(@B).cif $(TCGPEI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TCGPEI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TCGPEI_CFLAGS=$(CFLAGS)\
+ /I$(TcgPlatformSetupPeiPolicy_DIR)\
+ /I$(TCG_DIR)\
+ /I$(TPM12_DIR)\
+ /I$(TPM20_CRBLIB)\
+ /I$(TCG_DIR)\Common\
+ /I$(TCG_BOARD_OEM__DIR)\
+
+!IFNDEF LIB_BUILD_DIR
+!IF "$(PROCESSOR)"=="x64"
+TCGLIB=$(BUILD_DIR)\IA32\TisLib.lib
+!ELSE
+TCGLIB=$(BUILD_DIR)\TisLib.lib
+!ENDIF
+!ENDIF #LIB_BUILD_DIR
+
+TcgPeiBin : $(AMIPEILIB) $(BUILD_DIR)\AmiTcgLibPei.lib $(BUILD_DIR)\IA32\Tpm20CRBLib.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TcgPei.mak all\
+ "CFLAGS=$(TCGPEI_CFLAGS) "\
+ GUID=34989D8E-930A-4a95-AB04-2E6CFDFF6631\
+ ENTRY_POINT=CommonTcgPeiEntryPoint \
+ TYPE=PEIM \
+ DEPEX1=$(TCGPEI_DIR)\TcgPei.dxs \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ EXT_HEADERS=$(BUILD_DIR)\token.h \
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/TCG2/Common/TcgPei.sdl b/Core/EM/TCG2/Common/TcgPei.sdl
new file mode 100644
index 0000000..445a5a2
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPei.sdl
@@ -0,0 +1,34 @@
+TOKEN
+ Name = "TcgPeiSupport"
+ Value = "1"
+ Help = "Enable or Diasble TcgPeiSupport"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetH = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "TCG2Support" "=" "1"
+End
+
+PATH
+ Name = "TCGPEI_DIR"
+End
+
+MODULE
+ Help = "Includes tcgpei.mak into project"
+ Path = "$(TCGPEI_DIR)"
+ File = "tcgpei.mak"
+End
+
+MODULE
+ Help = "Includes tcgpei.mak into project"
+ Path = "$(TCGPEI_DIR)"
+ File = "TcgPeiAftermem.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\tcgPei.ffs"
+ Parent = "$(BUILD_DIR)\TcgPlatformSetupPeiPolicy.ffs"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/TCG2/Common/TcgPeiAfterMem.c b/Core/EM/TCG2/Common/TcgPeiAfterMem.c
new file mode 100644
index 0000000..cc659e6
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPeiAfterMem.c
@@ -0,0 +1,492 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgPei.c
+
+ Abstract:
+
+ PEIM that provides TCG services
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/TcgPeiAfterMem.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/TcgPeiAfterMem.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:57p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 1/12/12 12:11p Fredericko
+// Remove unused function.
+//
+// 2 8/29/11 6:49p Fredericko
+// [TAG] EIP0000
+// [Category] Improvement
+// [Description] Include Open and Close of locality 0 for TPM Ppi
+// functions
+// [Files] TcgPeiAfterMem.c
+//
+// 1 8/22/11 1:45p Fredericko
+// [TAG] EIP61168
+// [Category] Improvement
+// [Description] Reload TCG PPI from memory when Memory is Installed
+// [Files] TcgPeiAfterMem.cif
+// TcgPeiAfterMem.c
+// xTcgPeiAfterMem.c
+// TcgPeiAfterMem.mak
+//
+// 54 3/31/11 4:49p Fredericko
+// Changes for TCG_LEGACY support
+//
+// 53 3/29/11 12:57p Fredericko
+//
+// 52 3/28/11 2:12p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 50 8/04/10 5:16p Fredericko
+// Changes to flow of Lock Physical Presence for support Smi PPI changes
+//
+// 49 5/21/10 4:31p Fredericko
+// Changes for some build errors that happened with MOR support
+//
+// 48 5/19/10 5:51p Fredericko
+// Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPei.c
+//
+// Description:
+// Functions for early initialization of TPM are executed here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TcgCommon.h"
+#include <AmiPeiLib.h>
+#include <Sha.h>
+#include <TcgMisc.h>
+#include <token.h>
+#include <TpmLib.h>
+#include <TcgPc.h>
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "PPI\CpuIo.h"
+#include "PPI\LoadFile.h"
+#include <FFS.h>
+
+
+//*********************************************************************
+// GLOBAL DEFINITIONS
+//*********************************************************************
+
+
+#pragma pack(1)
+typedef struct _TCG_PEI_CALLBACK_CONTEXT
+{
+ PEI_TPM_PPI *TpmDevice;
+ EFI_PEI_SERVICES **PeiServices;
+} TCG_PEI_CALLBACK_CONTEXT;
+#pragma pack()
+
+
+EFI_GUID gEfiPeiAmiTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+EFI_GUID gPeiTpmPpiGuid = PEI_TPM_PPI_GUID;
+EFI_GUID gPeiTcgPpiGuid = PEI_TCG_PPI_GUID;
+
+static
+EFI_STATUS
+__stdcall FillCallbackContext(
+ IN EFI_PEI_SERVICES **PeiService,
+ OUT TCG_PEI_CALLBACK_CONTEXT *CallbackContext )
+{
+ CallbackContext->PeiServices = PeiService;
+ return (*PeiService)->LocatePpi(
+ PeiService,
+ &gPeiTpmPpiGuid,
+ 0,
+ NULL,
+ &CallbackContext->TpmDevice
+ );
+}
+
+EFI_STATUS
+EFIAPI TcgPeiGetEventLog(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT TCG_LOG_HOB **EventLog )
+{
+ EFI_STATUS Status;
+ VOID *HobStart;
+
+ Status = (*PeiServices)->GetHobList( PeiServices, &HobStart );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ return GetNextGuidHob( &HobStart, &gEfiPeiAmiTcgLogHobGuid, EventLog, NULL );
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcgPeiLogEvent
+//
+// Description: TCGPEI common function to Hash, Log and Extend data
+// using software SHA-1
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *Event,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiLogEvent(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCG_PCR_EVENT *Event,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_LOG_HOB *TcgLog;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+ UINT8 HashAlgo = 0;
+
+
+ //only log events if TPM is not deactivated
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(Event->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = TcgPeiGetEventLog( PeiServices, &TcgLog );
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgCommonLogEvent(
+ &Context,
+ (TCG_PCR_EVENT*)(TcgLog + 1),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ Event, HashAlgo);
+
+ if ( EFI_ERROR( Status )){
+ goto Exit;
+ }
+
+ *EventNum = TcgLog->EventNum;
+ TcgLog->EventNum++;
+
+Exit:
+ return Status;
+}
+
+
+
+
+
+EFI_STATUS
+__stdcall TcgPeiCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_HEADER cmdHeader;
+ TPM_1_2_RET_HEADER retHeader;
+ TPM_TRANSMIT_BUFFER InBuffer[3], OutBuffer[2];
+ static BOOLEAN SupportType = 0xff;
+
+ InBuffer[0].Buffer = &cmdHeader;
+ InBuffer[0].Size = sizeof (cmdHeader);
+ InBuffer[1].Buffer = &PCRIndex;
+ InBuffer[1].Size = sizeof (PCRIndex);
+ InBuffer[2].Buffer = Digest->digest;
+ InBuffer[2].Size = sizeof (Digest->digest);
+
+ OutBuffer[0].Buffer = &retHeader;
+ OutBuffer[0].Size = sizeof (retHeader);
+ OutBuffer[1].Buffer = NewPCRValue->digest;
+ OutBuffer[1].Size = sizeof (NewPCRValue->digest);
+
+ cmdHeader.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdHeader.ParamSize = TPM_H2NL(sizeof (cmdHeader)
+ + sizeof (PCRIndex) + sizeof (Digest->digest));
+
+ cmdHeader.Ordinal = TPM_H2NL( TPM_ORD_Extend );
+ PCRIndex = TcgCommonH2NL( PCRIndex );
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiHashLogExtendEventSW
+// Description: TCGPEI Software function to Hash, Log and Extend data
+// using software SHA-1
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *HashData
+// IN HashDataLen
+// IN OUT *NewEvent,
+// OUT *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS TcgPeiHashLogExtendEventSW(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCG_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status;
+ TCG_DIGEST NewPCRValue;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(NewEvent->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ Status = SHA1HashAll( &Context, HashData, HashDataLen, &NewEvent->Digest );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ Status = Context.TpmDevice->Init( Context.TpmDevice, PeiServices );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgPeiCommonExtend(
+ &Context,
+ NewEvent->PCRIndex,
+ &NewEvent->Digest,
+ &NewPCRValue
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgPeiLogEvent( This, PeiServices, NewEvent, EventNum );
+
+Exit:
+ Context.TpmDevice->Close( Context.TpmDevice, PeiServices );
+ return Status;
+}
+
+
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiPassThroughToTpm
+//
+// Description: TCGPEI common function to abstract passing commands to the TPM
+// FIFO
+//
+// Input: IN *This
+// IN **PeiServices
+// IN TpmInputParameterBlockSize
+// IN *TpmInputParameterBlock
+// IN TpmOutputParameterBlockSize
+// IN *TpmOutputParameterBlock
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiPassThroughToTpm(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock )
+{
+ EFI_STATUS Status;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ InBuffer[0].Buffer = TpmInputParameterBlock;
+ InBuffer[0].Size = TpmInputParameterBlockSize;
+ OutBuffer[0].Buffer = TpmOutputParameterBlock;
+ OutBuffer[0].Size = TpmOutputParameterBlockSize;
+
+ return TcgCommonPassThrough(
+ &Context,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer
+ );
+}
+
+
+static PEI_TCG_PPI mTcgPpi = {
+ TcgPeiHashLogExtendEventSW,
+ TcgPeiLogEvent,
+ TcgPeiPassThroughToTpm
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mTcgPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTcgPpiGuid,
+ &mTcgPpi
+ }
+};
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgPeiEntry
+//
+// Description: Entry point to Memory Absent and Memory Present Initialization
+// for TPM
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiMemoryCallbackEntry(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_PPI_DESCRIPTOR *PpiDesc;
+ PEI_TCG_PPI *TcgPpi;
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiTcgPpiGuid,
+ 0,
+ &PpiDesc,
+ &TcgPpi);
+
+
+ Status = (*PeiServices)->ReInstallPpi(
+ PeiServices,
+ PpiDesc,
+ &mTcgPpiList[0] );
+
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiTcgPpiGuid,
+ 0,
+ &PpiDesc,
+ &TcgPpi );
+
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ return Status;
+}
+
+
diff --git a/Core/EM/TCG2/Common/TcgPeiAfterMem.cif b/Core/EM/TCG2/Common/TcgPeiAfterMem.cif
new file mode 100644
index 0000000..bb6807e
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPeiAfterMem.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "TcgPeiAfterMem"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common"
+ RefName = "TcgPeiAfterMem"
+[files]
+"TcgPeiAfterMem.c"
+"xTcgPeiAfterMem.c"
+"TcgPeiAfterMem.mak"
+"TcgTcmPeiAfterMem.c"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/TcgPeiAfterMem.mak b/Core/EM/TCG2/Common/TcgPeiAfterMem.mak
new file mode 100644
index 0000000..b48fb94
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPeiAfterMem.mak
@@ -0,0 +1,149 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/TcgPeiAfterMem.mak 1 4/21/14 2:16p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:16p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/TcgPeiAfterMem.mak $
+#
+# 1 4/21/14 2:16p Fredericko
+#
+# 1 10/08/13 12:03p Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 1:57p Fredericko
+#
+# 1 7/10/13 5:51p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+# 3 12/12/11 3:32p Fredericko
+# [TAG] EIP76865
+# [Category] Improvement
+# [Description] Dual Support for TCM and TPM. System could hang in TXT
+# if txt is enabled in setup
+# [Files] AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif,
+# AmiTcgPlatformPpi.h, AmiTcgPlatformProtocol.cif,
+# AmiTcgPlatformProtocol.h,
+# EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+# TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+# xTcgPeiAfterMem.c
+#
+# 2 9/27/11 10:23p Fredericko
+# [TAG] EIP67286
+# [Category] Improvement
+# [Description] changes for Tcg Setup policy
+# [Files] Tcg.sdl
+# TcgPei.cif
+# TcgPei.mak
+# xtcgPei.c
+# xTcgPeiAfterMem.c
+# TcgPeiAfterMem.mak
+# TcgDxe.cif
+# TcgDxe.mak
+# xTcgDxe.c
+# AmiTcgPlatformPeilib.c
+# AmiTcgPlatformDxelib.c
+#
+# 1 8/22/11 1:45p Fredericko
+# [TAG] EIP61168
+# [Category] Improvement
+# [Description] Reload TCG PPI from memory when Memory is Installed
+# [Files] TcgPeiAfterMem.cif
+# TcgPeiAfterMem.c
+# xTcgPeiAfterMem.c
+# TcgPeiAfterMem.mak
+#
+# 25 4/22/11 8:49p Fredericko
+# Changes for building in x32 bit mode.
+#
+# 24 3/29/11 12:56p Fredericko
+#
+# [TAG] EIP 54642
+# [Category] Improvement
+# [Description] 1. Checkin Files related to TCG function override
+# 2. Include TCM and TPM auto detection
+# [Files] Affects all TCG files
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: TCGPEI.MAK
+#
+# Description: Make file for the TcgPei component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : tcgPeiAftermem
+
+tcgPeiAftermem : $(BUILD_DIR)\TcgPeiAftermem.mak TcgPeiBinMem
+
+$(BUILD_DIR)\TcgPeiAftermem.mak : $(TCGPEI_DIR)\$(@B).cif $(TCGPEI_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TCGPEI_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TCGPEIMEM_CFLAGS=$(CFLAGS)\
+ /I$(TcgPlatformSetupPeiPolicy_DIR)\
+ /I$(TCG_DIR)\
+ /I$(TPM12_DIR)\
+ /I$(TCG_DIR)\Common\
+ /I$(TCG_BOARD_OEM__DIR)\
+
+TCG_CORE_POSTMEM_OBJECTS = \
+$(BUILD_DIR)\$(TCGPEI_DIR)\TcgPeiAfterMem.obj \
+$(BUILD_DIR)\$(TCGPEI_DIR)\TcgTcmPeiAfterMem.obj \
+$(BUILD_DIR)\$(TCGPEI_DIR)\xTcgPeiAfterMem.obj
+
+!IFNDEF LIB_BUILD_DIR
+!IF "$(PROCESSOR)"=="x64"
+TCGLIB=$(BUILD_DIR)\IA32\TisLib.lib.
+AMITCMLIB = $(BUILD_DIR)\IA32\AmiTcmlib.lib
+Tpm20Crb_lib = $(BUILD_DIR)\IA32\Tpm20CRBLib.lib
+!ELSE
+TCGLIB=$(BUILD_DIR)\TisLib.lib
+AMITCMLIB = $(BUILD_DIR)\AmiTcmlib.lib
+!ENDIF
+!ENDIF #LIB_BUILD_DIR
+
+
+TcgPeiBinMem : $(AMIPEILIB) $(BUILD_DIR)\AmiTcgLibPei.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TcgPeiAftermem.mak all\
+ "CFLAGS=$(TCGPEIMEM_CFLAGS) "\
+ GUID=12345678-930A-4a95-AB04-2E6CFDFF6631\
+ "OBJECTS=$(TCG_CORE_POSTMEM_OBJECTS)" \
+ ENTRY_POINT=ReInstallTcgServiceAfterMem \
+ TYPE=PEIM \
+ DEPEX1=$(TCGPEI_DIR)\TcgPei.dxs \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ EXT_HEADERS=$(BUILD_DIR)\token.h \
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/TCG2/Common/TcgPrivate.c b/Core/EM/TCG2/Common/TcgPrivate.c
new file mode 100644
index 0000000..2ee8179
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPrivate.c
@@ -0,0 +1,70 @@
+/*++
+
+ Copyright (c) 1999 - 2007 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgPrivate.c
+
+ Abstract:
+
+ TCG private interface GUID used internally by TCG modules
+
+ --*/
+/*++
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Mobile Silicon Support Module" and is
+ licensed for Intel Mobile CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgPrivate.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgPrivate.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 12:00p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 5/19/10 5:20p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPrivate.c
+//
+// Description:
+// Contains guid definition for Tcg Private protocol
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <EFI.h>
+#include "TcgPrivate.h"
+
+EFI_GUID gEfiTcgPrivateInterfaceGuid = EFI_TCG_PRIVATE_INTERFACE_GUID;
diff --git a/Core/EM/TCG2/Common/TcgPrivate.h b/Core/EM/TCG2/Common/TcgPrivate.h
new file mode 100644
index 0000000..2b55058
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgPrivate.h
@@ -0,0 +1,400 @@
+/*++
+
+ Copyright (c) 1999 - 2007 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgPrivate.h
+
+ Abstract:
+
+ Private interface used internally by TCG modules
+
+ --*/
+/*++
+ This file contains an 'Intel Peripheral Driver' and uniquely
+ identified as "Intel Mobile Silicon Support Module" and is
+ licensed for Intel Mobile CPUs and chipsets under the terms of your
+ license agreement with Intel or your vendor. This file may
+ be modified by the user, subject to additional terms of the
+ license agreement
+ --*/
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgPrivate.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/TcgPrivate.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:58p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 8 3/29/11 12:25p Fredericko
+//
+// 7 3/28/11 12:23p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 6 7/09/10 3:32p Fredericko
+// Updated TCG structures for image measurement.
+//
+// 5 5/19/10 5:20p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPrivate.h
+//
+// Description:
+// Header file for Tcg private protocol definitions
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCG_PRIVATE_H_
+#define _TCG_PRIVATE_H_
+
+#define EFI_TCG_PRIVATE_INTERFACE_GUID \
+ { 0x8c4c9a41, 0xbf56, 0x4627, 0x9e, 0xa, 0xc8, 0x38, 0x6d, 0x66, 0x11, 0x5c }
+
+
+#define TCG_EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define TCG_EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // TE
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
+#define TCG_EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+#define TCG_MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+#define TCG_EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
+#define END_DEVICE_PATH_TYPE 0x7F
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF
+#define EFI_DP_TYPE_MASK 0x7F
+#define EFI_DP_TYPE_UNPACKED 0x80
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+// Type definitions for the Hard drive device path
+#define TCG_MBR_TYPE_MASTER_BOOT_RECORD 0x01
+#define TCG_MBR_TYPE_EFI_PARTITION_TABLE_HEADER 0x02
+
+// Needed Partition Type definitions for MBR
+#define TCG_NO_PARTITION 0x0
+#define TCG_EXTENDED_PARTITION 0x05
+#define TCG_WIN95_EXTENDED_PARTITION 0x0f
+
+
+
+
+#define DP_IS_END_TYPE(a)
+#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK )
+#define DevicePathSubType(a) ( (a)->SubType )
+#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
+
+#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE )
+#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
+#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
+
+#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
+
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} TCG_EFI_IMAGE_DATA_DIRECTORY;
+
+typedef struct {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} TCG_EFI_IMAGE_FILE_HEADER;
+
+
+#if EFIx64
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ //
+ // NT additional fields.
+ //
+ UINT64 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT64 SizeOfStackReserve;
+ UINT64 SizeOfStackCommit;
+ UINT64 SizeOfHeapReserve;
+ UINT64 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ TCG_EFI_IMAGE_DATA_DIRECTORY DataDirectory[TCG_EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} TCG_EFI_IMAGE_OPTIONAL_HEADER64;
+
+typedef struct {
+ UINT32 Signature;
+ TCG_EFI_IMAGE_FILE_HEADER FileHeader;
+ TCG_EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} TCG_EFI_IMAGE_NT_HEADERS64;
+
+
+typedef TCG_EFI_IMAGE_OPTIONAL_HEADER64 TCG_EFI_IMAGE_OPTIONAL_HEADER;
+typedef TCG_EFI_IMAGE_NT_HEADERS64 TCG_EFI_IMAGE_NT_HEADERS;
+
+#else
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ //
+ // NT additional fields.
+ //
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ TCG_EFI_IMAGE_DATA_DIRECTORY DataDirectory[TCG_EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} TCG_EFI_IMAGE_OPTIONAL_HEADER32;
+
+typedef struct {
+ UINT32 Signature;
+ TCG_EFI_IMAGE_FILE_HEADER FileHeader;
+ TCG_EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} TCG_EFI_IMAGE_NT_HEADERS32;
+
+
+typedef TCG_EFI_IMAGE_OPTIONAL_HEADER32 TCG_EFI_IMAGE_OPTIONAL_HEADER;
+typedef TCG_EFI_IMAGE_NT_HEADERS32 TCG_EFI_IMAGE_NT_HEADERS;
+#endif
+
+#define TCG_EFI_IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct {
+ UINT8 Name[TCG_EFI_IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} TCG_EFI_IMAGE_SECTION_HEADER;
+
+typedef struct {
+ UINT16 Signature; // signature for TE format = "VZ"
+ UINT16 Machine; // from the original file header
+ UINT8 NumberOfSections; // from the original file header
+ UINT8 Subsystem; // from original optional header
+ UINT16 StrippedSize; // how many bytes we removed from the header
+ UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header
+ UINT32 BaseOfCode; // from original image -- required for ITP debug
+ UINT64 ImageBase; // from original file header
+ TCG_EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory
+} TCG_EFI_TE_IMAGE_HEADER;
+
+typedef struct {
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+} TCG_EFI_IMAGE_DOS_HEADER;
+
+
+// GPT Partition Entry
+//<AMI_STHDR_START>
+//============================================================================
+// Structure: PARTITION_ENTRY
+//
+// Description: Data Structure definition of a partion entry in the GPT table
+//
+// Fields:
+// PartitionTypeGuid - EFI_GUID - contains GUID that defines that type
+// of GUID
+// UniquePartitionGuid - EFI_GUID - contains unique GUID for each
+// partition
+// StartingLba - EFI_LBA - first LBA of the partition
+// EndingLba - EFI_LBA - last logical block address
+// Attributes - UINT64 - UEFI defined attributes
+// Bit 0 - Partition is required for platform to function
+// Bits 1 - 47 - undefined
+// Bits 48 - 64 - reserved for GUID specific use
+// PartitionName[36] - CHAR16 - unicode string containing the name of
+// the partition
+//
+// Referral:
+// EFI_LBA
+//============================================================================
+//<AMI_STHDR_END>
+typedef struct
+{
+ EFI_GUID PartitionTypeGuid;
+ EFI_GUID UniquePartitionGuid;
+ EFI_LBA StartingLba;
+ EFI_LBA EndingLba;
+ UINT64 Attributes;
+ CHAR16 PartitionName[36];
+} TCG_EFI_PARTITION_ENTRY;
+
+
+typedef struct
+{
+ EFI_TABLE_HEADER Header;
+ EFI_LBA MyLba;
+ EFI_LBA AlternateLba;
+ EFI_LBA FirstUsableLba;
+ EFI_LBA LastUsableLba;
+ EFI_GUID DiskGuid;
+ EFI_LBA PartitionEntryLba;
+ UINT32 NumberOfPartitionEntries;
+ UINT32 SizeOfPartitionEntry;
+ UINT32 Crc32;
+} TCG_EFI_PARTITION_TABLE_HEADER;
+
+
+typedef struct {
+ TCG_EFI_PARTITION_TABLE_HEADER EfiPartitionHeader;
+ UINTN NumberOfPartitions;
+ TCG_EFI_PARTITION_ENTRY Partitions[1];
+} TCG_EFI_GPT_DATA;
+
+
+//
+// EFI TCG Platform Protocol
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG_MEASURE_PE_IMAGE) (
+ IN BOOLEAN BootPolicy,
+ IN EFI_PHYSICAL_ADDRESS ImageAddress,
+ IN UINTN ImageSize,
+ IN UINTN LinkTimeBase,
+ IN UINT16 ImageType,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG_MEASURE_ACTION) (
+ IN CHAR8 *ActionString
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TCG_MEASURE_GPT_TABLE) (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+typedef struct _EFI_TCG_PLATFORM_PROTOCOL {
+ EFI_TCG_MEASURE_PE_IMAGE MeasurePeImage;
+ EFI_TCG_MEASURE_ACTION MeasureAction;
+ EFI_TCG_MEASURE_GPT_TABLE MeasureGptTable;
+} EFI_TCG_PLATFORM_PROTOCOL;
+
+extern EFI_GUID gEfiTcgPrivateInterfaceGuid;
+#endif // _TCG_PRIVATE_H_
diff --git a/Core/EM/TCG2/Common/TcgTcmPei.c b/Core/EM/TCG2/Common/TcgTcmPei.c
new file mode 100644
index 0000000..ec48285
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgTcmPei.c
@@ -0,0 +1,476 @@
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgTcmPei.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgTcmPei.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:54p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 4 4/27/12 6:04p Fredericko
+// remove unused functions
+//
+// 3 4/01/11 9:33a Fredericko
+// Updated function Header
+//
+// 2 3/29/11 12:58p Fredericko
+//
+// 1 3/28/11 2:14p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 51 11/30/10 11:31p Fredericko
+// [TAG} EIP45885
+// [Category] NEW FEATURE
+// [Description] Provide hook to override Ppi request confirmation
+// [Files] TCGMisc.h, xTcgDxe.c, TcgPei.c
+//
+// 50 8/04/10 5:16p Fredericko
+// Changes to flow of Lock Physical Presence for support Smi PPI changes
+//
+// 49 5/21/10 4:31p Fredericko
+// Changes for some build errors that happened with MOR support
+//
+// 48 5/19/10 5:51p Fredericko
+// Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPei.c
+//
+// Description:
+// Functions for early initialization of TPM are executed here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TcgCommon.h"
+#include <AmiPeiLib.h>
+#include <Sha.h>
+#include <TcgMisc.h>
+#include <token.h>
+#include <TcgPc.h>
+#include "PPI\TcgService\TcgTcmService.h"
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "PPI\CpuIo.h"
+#include "PPI\LoadFile.h"
+#include <FFS.h>
+
+
+//*********************************************************************
+// GLOBAL DEFINITIONS
+//*********************************************************************
+
+EFI_GUID gPeiTcmPpiGuid = PEI_TPM_PPI_GUID;
+EFI_GUID gPeiTcgTcmPpiGuid = PEI_TCG_PPI_GUID;
+
+#pragma pack(1)
+typedef struct _TCG_PEI_CALLBACK_CONTEXT
+{
+ PEI_TPM_PPI *TpmDevice;
+ EFI_PEI_SERVICES **PeiServices;
+} TCG_PEI_CALLBACK_CONTEXT;
+#pragma pack()
+
+EFI_GUID gEfiPeiAmiTcmTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+
+EFI_STATUS
+EFIAPI TcmPeiLogEvent(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCM_PCR_EVENT *Event,
+ OUT UINT32 *EventNum );
+
+EFI_STATUS
+EFIAPI TcgPeiHashLogExtendEventTcm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCM_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum );
+
+
+static
+EFI_STATUS
+__stdcall FillCallbackContext(
+ IN EFI_PEI_SERVICES **PeiService,
+ OUT TCG_PEI_CALLBACK_CONTEXT *CallbackContext )
+{
+ CallbackContext->PeiServices = PeiService;
+ return (*PeiService)->LocatePpi(
+ PeiService,
+ &gPeiTcmPpiGuid,
+ 0,
+ NULL,
+ &CallbackContext->TpmDevice
+ );
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmPeiGetEventLog
+//
+// Description: Helper function for logging TCM events
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// OUT TCG_LOG_HOB **EventLog
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcmPeiGetEventLog(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT TCG_LOG_HOB **EventLog )
+{
+ EFI_STATUS Status;
+ VOID *HobStart;
+ EFI_GUID gEfiPeiAmiTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+
+ Status = (*PeiServices)->GetHobList( PeiServices, &HobStart );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ return GetNextGuidHob( &HobStart, &gEfiPeiAmiTcgLogHobGuid, EventLog, NULL );
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiPassThroughToTpm
+//
+// Description: TCGPEI common function to abstract passing commands to the TPM
+// FIFO
+//
+// Input: IN *This
+// IN **PeiServices
+// IN TpmInputParameterBlockSize
+// IN *TpmInputParameterBlock
+// IN TpmOutputParameterBlockSize
+// IN *TpmOutputParameterBlock
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiPassThroughToTpm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock );
+
+
+
+static PEI_TCM_PPI mTcmPpi = {
+ TcgPeiHashLogExtendEventTcm,
+ TcmPeiLogEvent,
+ TcgPeiPassThroughToTpm
+};
+
+
+static EFI_PEI_PPI_DESCRIPTOR mTcgPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTcgTcmPpiGuid,
+ &mTcmPpi
+ }
+};
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: IntTcmTcgPeiGetCapabilities
+//
+// Description: Executes TCM operation to read capabilities
+//
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: TCM_Capabilities_PermanentFlag
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+TCM_Capabilities_PermanentFlag IntTcmTcgPeiGetCapabilities(
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ TCM_Capabilities_PermanentFlag * cap = NULL;
+ EFI_STATUS Status;
+ TPM_GetCapabilities_Input cmdGetCap;
+ UINT8 result[0x100];
+
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap));
+ cmdGetCap.CommandCode = TPM_H2NL( TCM_ORD_GetCapability );
+ cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG );
+ cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long
+ cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_PERMANENT );
+
+ Status = FillCallbackContext( PeiServices, &Context );
+
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = Context.TpmDevice->Init( Context.TpmDevice, PeiServices );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = TcgPeiPassThroughToTpm(
+ &mTcmPpi,
+ PeiServices,
+ sizeof(cmdGetCap),
+ (UINT8*)&cmdGetCap,
+ 0x100,
+ result );
+
+ cap = (TCM_Capabilities_PermanentFlag*)result;
+
+ PEI_TRACE((-1, PeiServices,
+ "GetCapability: %r; size: %x; retCode:%x; tag:%x; bytes %08x\n",
+ Status,TPM_H2NL( cap->ParamSize ), TPM_H2NL(cap->RetCode ),
+ (UINT32)TPM_H2NS(cap->tag ), TPM_H2NL( *(UINT32*)&cap->disabled )));
+
+ Status = Context.TpmDevice->Close( Context.TpmDevice, PeiServices );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ return *cap;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcmPeiLogEvent
+//
+// Description: TCM common function to log PEI events
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *Event,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI TcmPeiLogEvent(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCM_PCR_EVENT *Event,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_LOG_HOB *TcgLog;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+ TCM_Capabilities_PermanentFlag Cap;
+
+ //only log events if TPM is not deactivated
+ Cap = IntTcmTcgPeiGetCapabilities( PeiServices );
+
+ if ( !Cap.deactivated )
+ {
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = TcmPeiGetEventLog(PeiServices, &TcgLog );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcmCommonLogEvent(
+ &Context,
+ (TCM_PCR_EVENT*)(TcgLog + 1),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ (TCM_PCR_EVENT *)Event
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ *EventNum = TcgLog->EventNum;
+ TcgLog->EventNum++;
+ }
+Exit:
+ return Status;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcgPeiHashLogExtendEventTcm
+//
+// Description: Tcm common function to Hash, Log and Extend data
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *HashData
+// IN HashDataLen
+// IN *NewEvent,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiHashLogExtendEventTcm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCM_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status;
+ UINT32 Sha1MaxBytes;
+ TCM_DIGEST NewPCRValue;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Start( &Context, TCG_ALG_SHA, &Sha1MaxBytes );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Update(
+ &Context,
+ HashData,
+ HashDataLen,
+ Sha1MaxBytes
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ HashData += (HashDataLen & ~63);
+ HashDataLen &= 63;
+
+ Status = TcmCommonSha1CompleteExtend(
+ &Context,
+ HashData,
+ HashDataLen,
+ NewEvent->PCRIndex,
+ &NewEvent->Digest,
+ &NewPCRValue
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcmPeiLogEvent( This, PeiServices, NewEvent, EventNum );
+
+Exit:
+ return Status;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgTcmPeiEntry
+//
+// Description: Entry point for TCM device initialization
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgTcmPeiEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->InstallPpi( PeiServices, mTcgPpiList );
+ return Status;
+}
diff --git a/Core/EM/TCG2/Common/TcgTcmPeiAfterMem.c b/Core/EM/TCG2/Common/TcgTcmPeiAfterMem.c
new file mode 100644
index 0000000..531da8f
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgTcmPeiAfterMem.c
@@ -0,0 +1,538 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgPei.c
+
+ Abstract:
+
+ PEIM that provides TCG services
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/TcgTcmPeiAfterMem.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/TcgTcmPeiAfterMem.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:57p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 2 1/12/12 12:12p Fredericko
+// Remove unused function declaration.
+//
+// 1 12/12/11 12:40p Fredericko
+// [TAG] EIP76865
+// [Category] Improvement
+// [Description] Dual Support for TCM and TPM. System could hang in TXT
+// if txt is enabled in setup
+// [Files] AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif,
+// AmiTcgPlatformPpi.h, AmiTcgPlatformProtocol.cif,
+// AmiTcgPlatformProtocol.h,
+// EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+// TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+// xTcgPeiAfterMem.c
+//
+//*************************************************************************
+#include <Efi.h>
+#include "TcgCommon.h"
+#include <AmiPeiLib.h>
+#include <Sha.h>
+#include <TcgMisc.h>
+#include <token.h>
+#include <TcgPc.h>
+#include "PPI\TcgService\TcgTcmService.h"
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "PPI\CpuIo.h"
+#include "PPI\LoadFile.h"
+#include <FFS.h>
+
+
+//*********************************************************************
+// GLOBAL DEFINITIONS
+//*********************************************************************
+
+
+#pragma pack(1)
+typedef struct _TCG_PEI_CALLBACK_CONTEXT
+{
+ PEI_TPM_PPI *TpmDevice;
+ EFI_PEI_SERVICES **PeiServices;
+} TCG_PEI_CALLBACK_CONTEXT;
+#pragma pack()
+
+
+EFI_GUID gPeiTcmPpiGuid = PEI_TPM_PPI_GUID;
+EFI_GUID gPeiTcgTcmPpiGuid = PEI_TCG_PPI_GUID;
+
+static
+EFI_STATUS
+__stdcall FillCallbackContext(
+ IN EFI_PEI_SERVICES **PeiService,
+ OUT TCG_PEI_CALLBACK_CONTEXT *CallbackContext )
+{
+ CallbackContext->PeiServices = PeiService;
+ return (*PeiService)->LocatePpi(
+ PeiService,
+ &gPeiTpmPpiGuid,
+ 0,
+ NULL,
+ &CallbackContext->TpmDevice
+ );
+}
+
+EFI_STATUS
+EFIAPI TcmPeiLogEvent(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCM_PCR_EVENT *Event,
+ OUT UINT32 *EventNum );
+
+EFI_STATUS
+EFIAPI TcgPeiHashLogExtendEventTcm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCM_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum );
+
+
+EFI_STATUS
+EFIAPI TcgPeiPassThroughToTcm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock );
+
+
+
+static PEI_TCM_PPI mTcmPpi = {
+ TcgPeiHashLogExtendEventTcm,
+ TcmPeiLogEvent,
+ TcgPeiPassThroughToTcm
+};
+
+
+static EFI_PEI_PPI_DESCRIPTOR mTcgTcgPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTcgTcmPpiGuid,
+ &mTcmPpi
+ }
+};
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcmPeiGetEventLog
+//
+// Description: Helper function for logging TCM events
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// OUT TCG_LOG_HOB **EventLog
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcmPeiGetEventLog(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT TCG_LOG_HOB **EventLog )
+{
+ EFI_STATUS Status;
+ VOID *HobStart;
+ EFI_GUID gEfiPeiAmiTcgTcmLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+
+ Status = (*PeiServices)->GetHobList( PeiServices, &HobStart );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ return GetNextGuidHob( &HobStart, &gEfiPeiAmiTcgTcmLogHobGuid, EventLog, NULL );
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: IntTcmTcgPeiGetCapabilities
+//
+// Description: Executes TCM operation to read capabilities
+//
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: TCM_Capabilities_PermanentFlag
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+TCM_Capabilities_PermanentFlag IntTcmTcgPeiGetCapabilities(
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ TCM_Capabilities_PermanentFlag * cap = NULL;
+ EFI_STATUS Status;
+ TPM_GetCapabilities_Input cmdGetCap;
+ UINT8 result[0x100];
+
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap));
+ cmdGetCap.CommandCode = TPM_H2NL( TCM_ORD_GetCapability );
+ cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG );
+ cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long
+ cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_PERMANENT );
+
+ Status = FillCallbackContext( PeiServices, &Context );
+
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = Context.TpmDevice->Init( Context.TpmDevice, PeiServices );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = TcgPeiPassThroughToTcm(
+ &mTcmPpi,
+ PeiServices,
+ sizeof(cmdGetCap),
+ (UINT8*)&cmdGetCap,
+ 0x100,
+ result );
+
+ cap = (TCM_Capabilities_PermanentFlag*)result;
+
+ PEI_TRACE((-1, PeiServices,
+ "GetCapability: %r; size: %x; retCode:%x; tag:%x; bytes %08x\n",
+ Status,TPM_H2NL( cap->ParamSize ), TPM_H2NL(cap->RetCode ),
+ (UINT32)TPM_H2NS(cap->tag ), TPM_H2NL( *(UINT32*)&cap->disabled )));
+
+ Status = Context.TpmDevice->Close( Context.TpmDevice, PeiServices );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ return *cap;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcmPeiLogEvent
+//
+// Description: TCM common function to log PEI events
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *Event,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI TcmPeiLogEvent(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCM_PCR_EVENT *Event,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_LOG_HOB *TcgLog;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+ TCM_Capabilities_PermanentFlag Cap;
+
+ //only log events if TPM is not deactivated
+ Cap = IntTcmTcgPeiGetCapabilities( PeiServices );
+
+ if ( !Cap.deactivated )
+ {
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = TcmPeiGetEventLog(PeiServices, &TcgLog );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcmCommonLogEvent(
+ &Context,
+ (TCM_PCR_EVENT*)(TcgLog + 1),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ (TCM_PCR_EVENT *)Event
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ *EventNum = TcgLog->EventNum;
+ TcgLog->EventNum++;
+ }
+Exit:
+ return Status;
+}
+
+
+
+
+
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcgPeiHashLogExtendEventTcm
+//
+// Description: Tcm common function to Hash, Log and Extend data
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *HashData
+// IN HashDataLen
+// IN *NewEvent,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiHashLogExtendEventTcm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCM_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status;
+ UINT32 Sha1MaxBytes;
+ TCM_DIGEST NewPCRValue;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Start( &Context, TCG_ALG_SHA, &Sha1MaxBytes );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgCommonSha1Update(
+ &Context,
+ HashData,
+ HashDataLen,
+ Sha1MaxBytes
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ HashData += (HashDataLen & ~63);
+ HashDataLen &= 63;
+
+ Status = TcmCommonSha1CompleteExtend(
+ &Context,
+ HashData,
+ HashDataLen,
+ NewEvent->PCRIndex,
+ &NewEvent->Digest,
+ &NewPCRValue
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcmPeiLogEvent( This, PeiServices, NewEvent, EventNum );
+
+Exit:
+ return Status;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiPassThroughToTcm
+//
+// Description: TCGPEI common function to abstract passing commands to the TPM
+// FIFO
+//
+// Input: IN *This
+// IN **PeiServices
+// IN TpmInputParameterBlockSize
+// IN *TpmInputParameterBlock
+// IN TpmOutputParameterBlockSize
+// IN *TpmOutputParameterBlock
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiPassThroughToTcm(
+ IN PEI_TCM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock )
+{
+ EFI_STATUS Status;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ InBuffer[0].Buffer = TpmInputParameterBlock;
+ InBuffer[0].Size = TpmInputParameterBlockSize;
+ OutBuffer[0].Buffer = TpmOutputParameterBlock;
+ OutBuffer[0].Size = TpmOutputParameterBlockSize;
+
+ return TcgCommonPassThrough(
+ &Context,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer
+ );
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgPeiEntry
+//
+// Description: Entry point to Memory Absent and Memory Present Initialization
+// for TPM
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgTcmPeiMemoryCallbackEntry(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_PPI_DESCRIPTOR *PpiDesc;
+ PEI_TCG_PPI *TcgPpi;
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiTcgTcmPpiGuid,
+ 0,
+ &PpiDesc,
+ &TcgPpi);
+
+
+ Status = (*PeiServices)->ReInstallPpi(
+ PeiServices,
+ PpiDesc,
+ &mTcgTcgPpiList[0] );
+
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gPeiTcgTcmPpiGuid,
+ 0,
+ &PpiDesc,
+ &TcgPpi );
+
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ return Status;
+}
+
+
diff --git a/Core/EM/TCG2/Common/TcgTisPei.c b/Core/EM/TCG2/Common/TcgTisPei.c
new file mode 100644
index 0000000..d075938
--- /dev/null
+++ b/Core/EM/TCG2/Common/TcgTisPei.c
@@ -0,0 +1,538 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgPei.c
+
+ Abstract:
+
+ PEIM that provides TCG services
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgTisPei.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgTisPei.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 3 3/17/14 3:05p Fredericko
+//
+// 2 3/11/14 6:32p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:52p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 57 1/12/12 12:10p Fredericko
+// Remove unused functions.
+//
+// 56 8/26/11 1:01p Fredericko
+//
+// 55 8/09/11 6:15p Fredericko
+// [TAG] EIP66465
+// [Category] New Feature
+// [Description] 1. Added support to remove EFI_EV_ACTION from the TCG
+// logs if customer wants.
+// [Files] 1. Tcgdxe.c
+// 2. Tcgpei.c
+// 3. Tcg.sdl
+//
+// 54 3/31/11 4:49p Fredericko
+// Changes for TCG_LEGACY support
+//
+// 53 3/29/11 12:57p Fredericko
+//
+// 52 3/28/11 2:12p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 50 8/04/10 5:16p Fredericko
+// Changes to flow of Lock Physical Presence for support Smi PPI changes
+//
+// 49 5/21/10 4:31p Fredericko
+// Changes for some build errors that happened with MOR support
+//
+// 48 5/19/10 5:51p Fredericko
+// Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPei.c
+//
+// Description:
+// Functions for early initialization of TPM are executed here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TcgCommon.h"
+#include <AmiPeiLib.h>
+#include <Sha.h>
+#include <TcgMisc.h>
+#include <token.h>
+#include <TpmLib.h>
+#include <TcgPc.h>
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "PPI\CpuIo.h"
+#include "PPI\LoadFile.h"
+#include <FFS.h>
+#include <ppi\AmiTcgPlatformPpi.h>
+#include "TcgPlatformSetupPeiPolicy.h"
+
+
+//*********************************************************************
+// GLOBAL DEFINITIONS
+//*********************************************************************
+
+#pragma pack(1)
+typedef struct _TCG_PEI_CALLBACK_CONTEXT
+{
+ PEI_TPM_PPI *TpmDevice;
+ EFI_PEI_SERVICES **PeiServices;
+} TCG_PEI_CALLBACK_CONTEXT;
+#pragma pack()
+
+EFI_GUID gEfiPeiAmiTcgLogHobGuid = EFI_TCG_LOG_HOB_GUID;
+EFI_GUID gPeiTpmPpiGuid = PEI_TPM_PPI_GUID;
+EFI_GUID gPeiTcgPpiGuid = PEI_TCG_PPI_GUID;
+
+static BOOLEAN SupportType = 0xff;
+
+
+EFI_STATUS
+__stdcall Tcg20CommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue,
+ IN UINT8 DigestSize);
+
+UINTN FindNextLogLocation(TCG_PCR_EVENT_HDR *TcgLog, UINTN EventNum);
+
+
+
+static
+EFI_STATUS
+__stdcall FillCallbackContext(
+ IN EFI_PEI_SERVICES **PeiService,
+ OUT TCG_PEI_CALLBACK_CONTEXT *CallbackContext )
+{
+ CallbackContext->PeiServices = PeiService;
+ return (*PeiService)->LocatePpi(
+ PeiService,
+ &gPeiTpmPpiGuid,
+ 0,
+ NULL,
+ &CallbackContext->TpmDevice
+ );
+}
+
+
+UINT8 GetHashPolicy(IN EFI_PEI_SERVICES **PeiServices)
+{
+ TCG_PLATFORM_SETUP_INTERFACE *TcgPeiPolicy = NULL;
+ EFI_STATUS Status;
+ EFI_GUID gTcgPeiPolicyGuid = TCG_PLATFORM_SETUP_PEI_POLICY_GUID;
+ TCG_CONFIGURATION Configuration;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gTcgPeiPolicyGuid,
+ 0, NULL,
+ &TcgPeiPolicy);
+
+ if(EFI_ERROR(Status) || TcgPeiPolicy == NULL )return 0;
+
+ TcgPeiPolicy->getTcgPeiPolicy(PeiServices, &Configuration);
+ return(Configuration.Reserved1);
+}
+
+
+
+EFI_STATUS
+EFIAPI TcgPeiGetEventLog(
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT TCG_LOG_HOB **EventLog )
+{
+ EFI_STATUS Status;
+ VOID *HobStart;
+
+ Status = (*PeiServices)->GetHobList( PeiServices, &HobStart );
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ return GetNextGuidHob( &HobStart, &gEfiPeiAmiTcgLogHobGuid, EventLog, NULL );
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Name: TcgPeiLogEvent
+//
+// Description: TCGPEI common function to Hash, Log and Extend data
+// using software SHA-1
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *Event,
+// IN *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiLogEvent(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN TCG_PCR_EVENT *Event,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TCG_LOG_HOB *TcgLog;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+ UINT8 HashAlgo = GetHashPolicy(PeiServices);
+ UINTN NextLocation;
+
+
+ //only log events if TPM is not deactivated
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(Event->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ Status = TcgPeiGetEventLog( PeiServices, &TcgLog );
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ //prepare next location
+ NextLocation = FindNextLogLocation((TCG_PCR_EVENT_HDR*)(TcgLog + 1), TcgLog->EventNum);
+
+ Status = TcgCommonLogEvent(
+ &Context,
+ (TCG_PCR_EVENT*)(NextLocation),
+ &TcgLog->TableSize,
+ TcgLog->TableMaxSize,
+ Event, HashAlgo);
+
+ if ( EFI_ERROR( Status )){
+ goto Exit;
+ }
+
+ *EventNum = TcgLog->EventNum;
+ TcgLog->EventNum++;
+
+Exit:
+ return Status;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgPeiCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_HEADER cmdHeader;
+ TPM_1_2_RET_HEADER retHeader;
+ TPM_TRANSMIT_BUFFER InBuffer[3], OutBuffer[2];
+
+ if(SupportType==1){
+ if(GetHashPolicy(((TCG_PEI_CALLBACK_CONTEXT *)CallbackContext)->PeiServices) ==0 ){
+ return(Tcg20CommonExtend(CallbackContext, PCRIndex, Digest, NewPCRValue, 20));
+ }else{
+ return(Tcg20CommonExtend(CallbackContext, PCRIndex, Digest, NewPCRValue, 32));
+ }
+ }
+
+ InBuffer[0].Buffer = &cmdHeader;
+ InBuffer[0].Size = sizeof (cmdHeader);
+ InBuffer[1].Buffer = &PCRIndex;
+ InBuffer[1].Size = sizeof (PCRIndex);
+ InBuffer[2].Buffer = Digest->digest;
+ InBuffer[2].Size = sizeof (Digest->digest);
+
+ OutBuffer[0].Buffer = &retHeader;
+ OutBuffer[0].Size = sizeof (retHeader);
+ OutBuffer[1].Buffer = NewPCRValue->digest;
+ OutBuffer[1].Size = sizeof (NewPCRValue->digest);
+
+ cmdHeader.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdHeader.ParamSize = TPM_H2NL(sizeof (cmdHeader)
+ + sizeof (PCRIndex) + sizeof (Digest->digest));
+
+ cmdHeader.Ordinal = TPM_H2NL( TPM_ORD_Extend );
+ PCRIndex = TcgCommonH2NL( PCRIndex );
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiHashLogExtendEventSW
+// Description: TCGPEI Software function to Hash, Log and Extend data
+// using software SHA-1
+//
+// Input: IN *This
+// IN **PeiServices
+// IN *HashData
+// IN HashDataLen
+// IN OUT *NewEvent,
+// OUT *EventNum
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//*********************************************************************
+EFI_STATUS TcgPeiHashLogExtendEventSW(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *HashData,
+ IN UINT32 HashDataLen,
+ IN OUT TCG_PCR_EVENT *NewEvent,
+ OUT UINT32 *EventNum )
+{
+ EFI_STATUS Status;
+ TCG_DIGEST NewPCRValue;
+ TCG_PEI_CALLBACK_CONTEXT Context;
+ EFI_GUID Tpm20Hobguid = TPM20_HOB_GUID;
+ AMI_TPM20SUPPORTTYPE_PPI *Tpm20PeiSupportPpi = NULL;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+#if defined LOG_EV_EFI_ACTION && LOG_EV_EFI_ACTION == 0
+ if(NewEvent->EventType == EV_EFI_ACTION)
+ {
+ return EFI_SUCCESS;
+ }
+#endif
+
+ if(GetHashPolicy( PeiServices)==0)
+ {
+ Status = SHA1HashAll( &Context, HashData, HashDataLen, &NewEvent->Digest );
+ }else{
+ //Status = SHA2HashAll(&Context, HashData, HashDataLen, &NewEvent->Digest);
+ }
+
+ if ( EFI_ERROR( Status ))
+ {
+ return Status;
+ }
+
+ Status = Context.TpmDevice->Init( Context.TpmDevice, PeiServices );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ if(SupportType == 0xff)
+ {
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &Tpm20Hobguid,
+ 0, NULL,
+ &Tpm20PeiSupportPpi);
+
+ if(!EFI_ERROR(Status) && Tpm20PeiSupportPpi!= NULL){
+ SupportType = 1;
+ }else{
+ SupportType = 0;
+ }
+ }
+
+ Status = TcgPeiCommonExtend(
+ &Context,
+ NewEvent->PCRIndex,
+ &NewEvent->Digest,
+ &NewPCRValue
+ );
+
+ if ( EFI_ERROR( Status ))
+ {
+ goto Exit;
+ }
+
+ Status = TcgPeiLogEvent( This, PeiServices, NewEvent, EventNum );
+
+Exit:
+ Context.TpmDevice->Close( Context.TpmDevice, PeiServices );
+ return Status;
+}
+
+
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TcgPeiPassThroughToTpm
+//
+// Description: TCGPEI common function to abstract passing commands to the TPM
+// FIFO
+//
+// Input: IN *This
+// IN **PeiServices
+// IN TpmInputParameterBlockSize
+// IN *TpmInputParameterBlock
+// IN TpmOutputParameterBlockSize
+// IN *TpmOutputParameterBlock
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiPassThroughToTpm(
+ IN PEI_TCG_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT32 TpmInputParameterBlockSize,
+ IN UINT8 *TpmInputParameterBlock,
+ IN UINT32 TpmOutputParameterBlockSize,
+ IN UINT8 *TpmOutputParameterBlock )
+{
+ EFI_STATUS Status;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+ TCG_PEI_CALLBACK_CONTEXT Context;
+
+ Status = FillCallbackContext( PeiServices, &Context );
+ ASSERT_PEI_ERROR( PeiServices, Status );
+
+ InBuffer[0].Buffer = TpmInputParameterBlock;
+ InBuffer[0].Size = TpmInputParameterBlockSize;
+ OutBuffer[0].Buffer = TpmOutputParameterBlock;
+ OutBuffer[0].Size = TpmOutputParameterBlockSize;
+
+ return TcgCommonPassThrough(
+ &Context,
+ sizeof (InBuffer) / sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer
+ );
+}
+
+
+static PEI_TCG_PPI mTcgPpi = {
+ TcgPeiHashLogExtendEventSW,
+ TcgPeiLogEvent,
+ TcgPeiPassThroughToTpm
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mTcgPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTcgPpiGuid,
+ &mTcgPpi
+ }
+};
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TcgPeiEntry
+//
+// Description: Entry point to Memory Absent and Memory Present Initialization
+// for TPM
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TPM_Base = (EFI_PHYSICAL_ADDRESS)PORT_TPM_IOMEMBASE;
+#if TCG_LEGACY == 0
+ Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_Base );
+ if(EFI_ERROR(Status))return Status;
+#endif
+ Status = (*PeiServices)->InstallPpi( PeiServices, mTcgPpiList );
+ return Status;
+}
diff --git a/Core/EM/TCG2/Common/TisPei.c b/Core/EM/TCG2/Common/TisPei.c
new file mode 100644
index 0000000..ded01a7
--- /dev/null
+++ b/Core/EM/TCG2/Common/TisPei.c
@@ -0,0 +1,691 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TpmPei.h
+
+ Abstract:
+
+ PEI driver for TPM devices
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TisPei.c 2 4/21/14 3:16p Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 4/21/14 3:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TisPei.c $
+//
+// 2 4/21/14 3:16p Fredericko
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 17 4/01/11 11:13a Fredericko
+//
+// 16 4/01/11 10:52a Fredericko
+// Changes for TPM support in Legacy IO mode. Some TPMs do not allow init
+// function to be called more than once during legacy mode.
+//
+// 15 3/31/11 4:49p Fredericko
+// Changes for TCG_LEGACY support
+//
+// 14 3/29/11 12:57p Fredericko
+//
+// 13 3/28/11 2:06p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 12 5/19/10 5:44p Fredericko
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmPei.c
+//
+// Description:
+// Abstracted functions for Tpm ppis' are defined here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include <Pei.h>
+#include <TcgTpm12.h>
+#include <TpmLib.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include "TcgCommon.h"
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "Tpm20CRBLib.h"
+
+
+#define _CR( Record, TYPE,\
+ Field )((TYPE*) ((CHAR8*) (Record) - (CHAR8*) &(((TYPE*) 0)->Field)))
+
+#define INTEL_VID 0x8086
+#define TCG_VID_OFFSET 0x0F00
+
+BOOLEAN iTPMVerifyMeStatus( );
+
+#define TPM_PEI_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TPM_PEI_PRIVATE_DATA, TpmPpi )
+
+typedef struct _TPM_PEI_PRIVATE_DATA
+{
+ PEI_TPM_PPI TpmPpi;
+ EFI_PHYSICAL_ADDRESS BaseAddr;
+} TPM_PEI_PRIVATE_DATA;
+
+#if TCG_LEGACY == 1
+
+typedef struct _TPM_PEI_CALLBACK
+{
+ EFI_PEI_NOTIFY_DESCRIPTOR NotifyDesc;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+
+} TPM_PEI_CALLBACK;
+
+
+VOID TpmPeiCallMPDriver(IN EFI_PEI_SERVICES **PeiServices, IN UINT8 CFuncID,
+ TPMTransmitEntryStruct *CData, UINT32* OUT CRetVal);
+
+EFI_GUID gTpmCallbackguid = AMI_TPM_LEGACY_GUID;
+#endif
+
+
+#if TCG_LEGACY == 0
+EFI_STATUS
+EFIAPI TpmPeiInit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ TPM_PEI_PRIVATE_DATA *Private;
+
+ Private = TPM_PEI_PRIVATE_DATA_FROM_THIS( This );
+ return TisRequestLocality(
+ (TPM_1_2_REGISTERS_PTR)( UINTN ) Private->BaseAddr);
+}
+
+EFI_STATUS
+EFIAPI TpmPeiClose(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ TPM_PEI_PRIVATE_DATA *Private;
+
+ Private = TPM_PEI_PRIVATE_DATA_FROM_THIS( This );
+ return TisReleaseLocality(
+ (TPM_1_2_REGISTERS_PTR)( UINTN ) Private->BaseAddr);
+}
+
+EFI_STATUS
+EFIAPI TpmPeiGetStatusInfo(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI TpmPeiTransmit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ TPM_PEI_PRIVATE_DATA *Private;
+ TPM_1_2_REGISTERS_PTR TpmReg;
+
+ Private = TPM_PEI_PRIVATE_DATA_FROM_THIS( This );
+ TpmReg = (TPM_1_2_REGISTERS_PTR)( UINTN ) Private->BaseAddr;
+ return TpmLibPassThrough(
+ TpmReg,
+ NoInputBuffers,
+ InputBuffers,
+ NoOutputBuffers,
+ OutputBuffers
+ );
+}
+
+
+EFI_STATUS
+EFIAPI CrbTpmPeiInit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI CrbTpmPeiClose(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI CrbTpmPeiGetStatusInfo(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI CrbTpmPeiTransmit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ return EFI_UNSUPPORTED;
+}
+#else
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTpmPeiInit
+//
+// Description: Call to OEM driver to initialize TPM
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TpmPeiInit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_SUCCESS;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTpmPeiClose
+//
+// Description: Call to OEM driver to Close TPM
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TpmPeiClose(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+EFIAPI TpmPeiGetStatusInfo(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTpmPeiSHA1Setup
+//
+// Description: Helper function to help with Command transmission to TPM
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+// IN UINTN NoInputBuffers
+// IN TPM_TRANSMIT_BUFFER *InputBuffers
+// IN OUT void **Buffer
+// IN UINT8 *SHA_ARRAY
+//
+// Output: BOOLEAN
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN
+EFIAPI TpmPeiSHA1Setup(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN OUT void **Buffer,
+ IN UINT8 *SHA_ARRAY )
+{
+ TPM_1_2_CMD_HEADER *SHA1HeaderCheck;
+ void *Context = NULL;
+ UINT8 i = 0, loc = 0;
+
+ //check if this an SHA1 update or Complete call and set the buffer
+ //else no need to update the buffer is the same
+ SHA1HeaderCheck = (TPM_1_2_CMD_HEADER*)InputBuffers->Buffer;
+
+ if ( SHA1HeaderCheck->Ordinal !=
+ TPM_H2NL(TPM_ORD_SHA1CompleteExtend ) && SHA1HeaderCheck->Ordinal !=
+ TPM_H2NL( TPM_ORD_SHA1Update ) && SHA1HeaderCheck->Ordinal != TPM_H2NL(TPM_ORD_Extend))
+ {
+ //no need to modify buffers just pass it through
+ return FALSE;
+ }
+
+ if ( NoInputBuffers > 1 )
+ {
+ //if we get here it means the buffer needs to be modified!
+ for (; i < NoInputBuffers; i++ )
+ {
+ TcgCommonCopyMem( Context,
+ &SHA_ARRAY[loc],
+ InputBuffers[i].Buffer,
+ InputBuffers[i].Size );
+
+ loc += InputBuffers[i].Size;
+ }
+ }
+ else {
+ return FALSE;
+ }
+
+ *Buffer = SHA_ARRAY;
+ return TRUE;
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EMpTpmPeiTransmit
+//
+// Description: TPM Transmit function
+//
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices,
+// IN UINTN NoInputBuffers,
+// IN TPM_TRANSMIT_BUFFER *InputBuffers,
+// IN UINTN NoOutputBuffers,
+// IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TpmPeiTransmit(
+ IN PEI_TPM_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers )
+{
+ TPM_PEI_PRIVATE_DATA *Private;
+ TPMTransmitEntryStruct FillESI;
+ UINT8 FuncID = MP_FUNCTION_TRANSMIT;
+ UINT32 Ret;
+ void *buffer;
+ UINT8 SHA_ARRAY[INTERNAL_SHA_ARRAY_LENGTH];
+ UINT8 SHA_ARRAY_OUT[INTERNAL_SHA_ARRAY_LENGTH];
+ BOOLEAN FillBuff = FALSE;
+ void *Context = NULL;
+ UINT8 i = 0;
+ UINT8 loc = 0;
+
+
+ if ( !TpmPeiSHA1Setup( This, PeiServices, NoInputBuffers, InputBuffers,
+ &buffer, SHA_ARRAY ))
+ {
+ FillESI.pbInBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)InputBuffers->Buffer;
+ FillESI.dwInLen = (UINT32)InputBuffers->Size;
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)OutputBuffers->Buffer;
+ FillESI.dwOutLen = (UINT32)OutputBuffers->Size;
+ }
+ else {
+ FillESI.pbInBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)SHA_ARRAY;
+ FillESI.dwInLen = 0;
+
+ for (; i < NoInputBuffers; i++ )
+ {
+ FillESI.dwInLen += (UINT32)InputBuffers[i].Size;
+ }
+ i = 0;
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS)SHA_ARRAY_OUT;
+ FillBuff = TRUE;
+ FillESI.dwOutLen = 0;
+
+ for (; i < NoOutputBuffers; i++ )
+ {
+ FillESI.dwOutLen += OutputBuffers[i].Size;
+ }
+ }
+
+ Private = TPM_PEI_PRIVATE_DATA_FROM_THIS( This );
+ TpmPeiCallMPDriver( PeiServices, FuncID, &FillESI, &Ret );
+
+ if ( FillBuff ) //setup output buffer for the interface
+ {
+ i = 0;
+ for (; i < NoOutputBuffers; i++ )
+ {
+ TcgCommonCopyMem( Context,
+ OutputBuffers[i].Buffer,
+ &SHA_ARRAY_OUT[loc],
+ OutputBuffers[i].Size );
+
+ loc += OutputBuffers[i].Size;
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: TpmPeiCallMPDriver
+//
+// Description: Interface to performing MP driver function calls in PEI
+// Uses _ASM directives. Return Value in EAX return as status
+//
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// IN UINT8 CFuncID,
+// IN TPMTransmitEntryStruct * CData,
+// OUT UINT32* CRetVal
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID TpmPeiCallMPDriver(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 CFuncID,
+ TPMTransmitEntryStruct * CData,
+ UINT32* OUT CRetVal )
+{
+ UINT32 ReturnVal;
+ FAR32LOCALS CommonLegX;
+ EFI_GUID guidMA = EFI_TCG_MADriver_HOB_GUID;
+ EFI_GUID guidMP = EFI_TCG_MPDriver_HOB_GUID;
+ ESPFUNCSTRUCT EspStruct;
+ VOID *Temp = &ReturnVal;
+ MASTRUCT MA;
+ UINT32 MAStart;
+ UINT32 EspVal;
+
+
+ TPMTransmitEntryStruct IntCData = *CData;
+ UINT32 Address = (UINT32)&IntCData;
+
+ CommonLegX.Offset = 0;
+ CommonLegX.Selector = 0;
+
+ if (((UINT32)Temp & (UINT32)0xff000000) == (UINT32)0xff000000 )
+ {
+ FillDriverLoc( &MA.Offset, PeiServices, &guidMA );
+ MAStart = MA.Offset - MA.Codep;
+ CommonLegX.Offset = MA.Offset;
+ CommonLegX.Selector = SEL_flatCS;
+ Temp = &EspStruct;
+
+ if ( CommonLegX.Offset == NULL )
+ {
+ return;
+ }
+
+ _asm {
+ //fill esp
+ push esi
+ mov esi, [ReturnAdd]
+ mov [EspStruct.ReturnAddress], esi
+ mov esi, [MAStart]
+ mov [EspStruct.Header], esi
+ pop esi
+ mov EspVal, esp // Save ESP
+ mov al, [CFuncID]
+ mov [EspStruct.FuncNum], al
+ mov esp, Temp
+ call fword ptr [CommonLegX]
+ mov esp, EspVal // Restore ESP
+ReturnAdd:
+ mov ReturnVal, eax
+ }
+
+ *CRetVal = ReturnVal;
+ return;
+ }
+ else {
+ FillDriverLoc( &CommonLegX.Offset, PeiServices, &guidMP );
+ CommonLegX.Selector = SEL_flatCS;
+
+ _asm {
+ xor eax, eax
+ mov al, [CFuncID]
+ cmp eax, MP_FUNCTION_TRANSMIT
+ jnz Empty_Buff
+ mov ESI, Address
+Empty_Buff:
+ mov EspVal, esp // Save ESP
+ call fword ptr [CommonLegX];
+ mov ReturnVal, eax
+ mov esp, EspVal // Restore ESP
+
+ }
+ *CRetVal = ReturnVal;
+ }
+}
+
+#endif
+
+static TPM_PEI_PRIVATE_DATA mTpmPrivate = {
+ {
+ TpmPeiInit,
+ TpmPeiClose,
+ TpmPeiGetStatusInfo,
+ TpmPeiTransmit
+ },
+ TPM_BASE_ADDRESS
+};
+
+static TPM_PEI_PRIVATE_DATA CrbmTpmPrivate = {
+ {
+ CrbTpmPeiInit,
+ CrbTpmPeiClose,
+ CrbTpmPeiGetStatusInfo,
+ CrbTpmPeiTransmit
+ },
+ TPM_BASE_ADDRESS
+};
+
+
+
+#if TCG_LEGACY == 1
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitLegacyTpmEntry
+//
+// Description: Entry point for TPM initialization after memory is installed
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI InitLegacyTpmEntry(
+IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi)
+{
+ UINT8 FuncID;
+ TPMTransmitEntryStruct EmptyBuf;
+ UINT32 Ret;
+
+ FuncID = MA_FUNCTION_INIT;
+ TpmPeiCallMPDriver( PeiServices, FuncID, &EmptyBuf, &Ret );
+ if ( !Ret )
+ {
+ return EFI_SUCCESS;
+ }
+ return EFI_DEVICE_ERROR;
+}
+#endif
+
+
+static EFI_PEI_PPI_DESCRIPTOR mPpiList[] = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmPpiGuid,
+ &mTpmPrivate.TpmPpi
+};
+
+static EFI_PEI_PPI_DESCRIPTOR mCrbPpiList[] = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiTpmPpiGuid,
+ &CrbmTpmPrivate.TpmPpi
+};
+
+
+
+
+EFI_STATUS
+EFIAPI TpmPeiEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status=EFI_NOT_FOUND;
+ BOOLEAN Temp = TRUE;
+#if TCG_LEGACY == 1
+ TPM_PEI_CALLBACK *Callback;
+#endif
+
+ if(!isTpm20CrbPresent()) (*PeiServices)->InstallPpi( PeiServices, mPpiList );
+
+#if TCG_LEGACY == 1
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof (TPM_PEI_CALLBACK),
+ &Callback);
+
+ if ( !EFI_ERROR( Status ))
+ {
+ Callback->NotifyDesc.Flags
+ = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ Callback->NotifyDesc.Guid = &gTpmCallbackguid;
+ Callback->NotifyDesc.Notify = InitLegacyTpmEntry;
+ Callback->FfsHeader = FfsHeader;
+
+ Status = (*PeiServices)->NotifyPpi( PeiServices,
+ &Callback->NotifyDesc );
+ }
+ return EFI_SUCCESS;
+#endif
+
+ if ( Temp )
+ {
+ Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)(
+ UINTN ) mTpmPrivate.BaseAddr );
+
+ if ( EFI_ERROR( Status ))
+ {
+ if(!isTpm20CrbPresent())return Status;
+ else{
+ Status = (*PeiServices)->InstallPpi( PeiServices, mCrbPpiList );
+ return Status;
+ }
+ }
+ }
+
+ return Status;
+} \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/Tpm20Includes/Tpm20.h b/Core/EM/TCG2/Common/Tpm20Includes/Tpm20.h
new file mode 100644
index 0000000..9ba9d3e
--- /dev/null
+++ b/Core/EM/TCG2/Common/Tpm20Includes/Tpm20.h
@@ -0,0 +1,1917 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/CommonHeaders/Tpm20Includes/Tpm20.h 2 6/14/14 12:25a Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/14/14 12:25a $
+//*************************************************************************
+// Revision History
+// ----------------
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Tpm20.h.h
+//
+// Description:
+// Contains Industry Standard #defines and Structures for TPM20
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TPM20_H_
+#define _TPM20_H_
+
+#include <efi.h>
+
+#pragma pack (push)
+#pragma pack (1)
+
+
+#ifdef TRUE
+#undef TRUE
+#endif
+
+#ifdef FALSE
+#undef FALSE
+#endif
+
+// Table 189 -- Hash Algorithm Digest and Block Size Values
+#define SHA1_DIGEST_SIZE 20 // 20
+#define SHA1_BLOCK_SIZE 64 // 64
+#define SHA256_DIGEST_SIZE 32 // 32
+#define SHA256_BLOCK_SIZE 64 // 64
+#define SM3_256_DIGEST_SIZE 32 // 32
+#define SM3_256_BLOCK_SIZE 64 // 64
+#define SHA384_DIGEST_SIZE 48 // 48
+#define SHA384_BLOCK_SIZE 128 // 128
+#define SHA512_DIGEST_SIZE 64 // 64
+#define SHA512_BLOCK_SIZE 128 // 128
+#define WHIRLPOOL512_DIGEST_SIZE 64 // 64
+#define WHIRLPOOL512_BLOCK_SIZE 64 // 64
+
+
+// Table 190 -- Logic Values
+#define YES 1 // 1
+#define NO 0 // 0
+#define TRUE 1 // 1
+#define FALSE 0 // 0
+#define SET 1 // 1
+#define CLEAR 0 // 0
+
+
+// Table 191 -- Processor Values
+#define BIG_ENDIAN 0 // NO
+#define LITTLE_ENDIAN 1 // YES
+
+
+// Table 192 -- Implemented Algorithms
+#define RSA 1 // YES
+#define DES 0 // NO
+#define _3DES 0 // NO
+#define SHA1 1 // YES
+#define SHA 1 // SHA1
+#define HMAC 1 // YES
+#define AES 1 // YES
+#define CFB 1 // YES
+#define MGF1 1 // YES
+#define XOR 1 // YES
+#define KEYEDHASH 1 // YES
+#define SHA256 1 // YES
+#define SHA384 1 // YES
+#define SHA512 0 // NO
+#define WHIRLPOOL512 0 // NO
+#define SM3_256 0 // NO
+#define SMS4 0 // NO
+#define RSASSA_PKCS1v1_5 1 // RSA
+#define RSAES_PKCS1v1_5 1 // RSA
+#define PSS 1 // RSA
+#define OAEP 1 // RSA
+#define ECC 1 // YES
+#define ECDSA 1 // ECC
+#define KDF1_SP800_56a 1 // ECC
+#define KDF2 0 // NO
+#define KDF1_SP800_108 1 // YES
+#define CTR 1 // YES
+#define OFB 1 // YES
+#define CBC 1 // YES
+#define ECB 1 // YES
+
+
+// Table 193 -- Implemented Algorithm Constants
+#define MAX_RSA_KEY_BYTES 256 // 2048/8
+#define MAX_ECC_KEY 48 // 384/8
+#define MAX_CONTEXT_SIZE 4096 // 4096
+#define AES_KEY_SIZE_256 256 // 256
+#define MAX_AES_KEY 32 // 256/8
+#define RSA_KEY_SIZE_2048 2048 // 2048
+#define MAX_CC_LIST_SIZE 8 // 8
+#define MAX_HASH_BLOCK 128 // 128
+
+
+// Table 194 -- Implementation Values
+#define IMPLEMENTATION_PCR 24 // 24
+#define PLATFORM_PCR 24 // 24
+#define DRTM_PCR (TPM_RH_PCR0+17) // (TPM_RH_PCR0+17)
+#define NUM_LOCALITIES 5 // 5
+#define MAX_ACTIVE_SESSIONS 64 // 64
+#define CONTEXT_SLOT UINT16 // UINT16
+#define CONTEXT_COUNTER UINT64 // UINT64
+#define MAX_LOADED_SESSIONS 3 // 3
+#define MAX_LOADED_OBJECTS 3 // 3
+#define MAX_EVICT_OBJECTS 16 // 16
+#define HASH_COUNT 3 // (SHA1+SHA256+SHA384+SHA512+SM3_256)
+#define SYM_COUNT 2 // (XOR+AES+SMS4)
+#define ASYM_COUNT 2 // (RSA+ECC)
+#define PCR_SELECT_MIN 3 // ((PLATFORM_PCR+7)/8)
+#define PCR_SELECT_MAX 3 // ((IMPLEMENTATION_PCR+7)/8)
+#define MAX_DIGEST_BUFFER 1024 // 1024
+#define MAX_NV_INDEX_SIZE 1024 // 1024
+#define MAX_CAP_BUFFER 1024 // 1024
+#define MAX_CAP_DATA (MAX_CAP_BUFFER-sizeof(TPM_CAP)-sizeof(UINT32)) // (MAX_CAP_BUFFER-sizeof(TPM_CAP)-sizeof(UINT32))
+#define MAX_CAP_ALGS (MAX_CAP_DATA/sizeof(TPMS_ALG_PROPERTY)) // (MAX_CAP_DATA/sizeof(TPMS_ALG_PROPERTY))
+#define MAX_CAP_HANDLES (MAX_CAP_DATA/sizeof(TPM_HANDLE)) // (MAX_CAP_DATA/sizeof(TPM_HANDLE))
+#define MAX_CAP_CC (MAX_CAP_DATA/sizeof(TPM_CC)) // (MAX_CAP_DATA/sizeof(TPM_CC))
+#define MAX_TPM_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY)) // (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PROPERTY))
+#define MAX_PCR_PROPERTIES (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PCR_SELECT)) // (MAX_CAP_DATA/sizeof(TPMS_TAGGED_PCR_SELECT))
+#define MAX_ECC_CURVES (MAX_CAP_DATA/sizeof(TPM_ECC_CURVE_ID)) // (MAX_CAP_DATA/sizeof(TPM_ECC_CURVE_ID))
+#define NV_MEMORY_SIZE 8192 // 8192
+#define NUM_STATIC_PCR 16 // 16
+#define MAX_ALG_LIST_SIZE 128 // 128
+#define NV_CLOCK_UPDATE_RATE 12 // 12
+#define TIMER_PRESCALE 100000 // 100000
+#define PP_COMMANDS_NUM 16 // 16
+#define PROOF_SIZE 32 // 32
+#define PRIMARY_SEED_SIZE 64 // 64
+#define CONTEXT_ENCRYPT_ALG TPM_ALG_AES // TPM_ALG_AES
+#define CONTEXT_ENCRYPT_KEYSIZE 128 // 128
+#define CONTEXT_INTEGRITY_HASH_ALG TPM_ALG_SHA256 // TPM_ALG_SHA256
+#define CONTEXT_INTEGRITY_HASH_SIZE 32 // 32
+#define NV_CLOCK_UPDATE_INTERVAL 12 // 12
+#define GENERATION_CTR UINT8 // UINT8
+#define NUM_POLICY_PCR 1 // 1
+#define MAX_COMMAND_SIZE 4096 // 4096
+#define MAX_RESPONSE_SIZE 4096 // 4096
+#define MAX_ORDERLY_COUNT 256 // 256
+#define ALG_ID_FIRST TPM_ALG_RSA // TPM_ALG_RSA
+#define ALG_ID_LAST TPM_ALG_ECB // TPM_ALG_ECB
+#define MAX_SYM_DATA 128 // 128
+#define MAX_HASH_STATE_SIZE 400 // 400
+#define MAX_HMAC_STATE_SIZE 800 // 800
+
+
+// Table 2 -- BaseTypes from BaseTypes <I/O>
+typedef unsigned char BYTE;
+
+// Table 3 -- DocumentationClarity from outputTypeDef <I/O>
+typedef UINT32 TPM_ALGORITHM_ID;
+typedef UINT32 TPM_MODIFIER_INDICATOR;
+typedef UINT32 TPM_SESSION_OFFSET;
+typedef UINT16 TPM_KEY_SIZE;
+typedef UINT16 TPM_KEY_BITS;
+typedef UINT64 TPM_SYSTEM_ADDRESS;
+
+typedef UINT32 TPM2_PCRINDEX;
+
+// Table 4 -- TPM_GENERATED from outputConstDef <O,S>
+typedef UINT32 TPM_GENERATED;
+
+#define TPM_GENERATED_VALUE (TPM_GENERATED)(0xff544347)
+
+
+
+
+// Table 5 -- TPM2_ALG_ID from outputConstDef <I/O,S>
+typedef UINT16 TPM2_ALG_ID;
+
+
+#define TPM2_ALG_ERROR (TPM2_ALG_ID)(0x0000)
+#define TPM2_ALG_RSA (TPM2_ALG_ID)(0x0001)
+#define TPM2_ALG_DES (TPM2_ALG_ID)(0x0002)
+#define TPM2_ALG__3DES (TPM2_ALG_ID)(0x0003)
+#define TPM2_ALG_SHA (TPM2_ALG_ID)(0x0004)
+#define TPM2_ALG_SHA1 (TPM2_ALG_ID)(0x0004)
+#define TPM2_ALG_HMAC (TPM2_ALG_ID)(0x0005)
+#define TPM2_ALG_AES (TPM2_ALG_ID)(0x0006)
+#define TPM2_ALG_MGF1 (TPM2_ALG_ID)(0x0007)
+#define TPM2_ALG_XOR (TPM2_ALG_ID)(0x000A)
+#define TPM2_ALG_KEYEDHASH (TPM2_ALG_ID)(0x0008)
+#define TPM2_ALG_SHA256 (TPM2_ALG_ID)(0x000B)
+#define TPM2_ALG_SHA384 (TPM2_ALG_ID)(0x000C)
+#define TPM2_ALG_SHA512 (TPM2_ALG_ID)(0x000D)
+#define TPM2_ALG_WHIRLPOOL512 (TPM2_ALG_ID)(0x000E)
+#define TPM2_ALG_NULL (TPM2_ALG_ID)(0x0010)
+#define TPM2_ALG_SM3_256 (TPM2_ALG_ID)(0x0012)
+#define TPM2_ALG_SMS4 (TPM2_ALG_ID)(0x0013)
+#define TPM2_ALG_RSASSA_PKCS1v1_5 (TPM2_ALG_ID)(0x0014)
+#define TPM2_ALG_RSAES_PKCS1v1_5 (TPM2_ALG_ID)(0x0015)
+#define TPM2_ALG_PSS (TPM2_ALG_ID)(0x0016)
+#define TPM2_ALG_OAEP (TPM2_ALG_ID)(0x0017)
+#define TPM2_ALG_ECDSA (TPM2_ALG_ID)(0x0018)
+#define TPM2_ALG_SP800_56a_C1_1 (TPM2_ALG_ID)(0x0019)
+#define TPM2_ALG_KDF1_SP800_56a (TPM2_ALG_ID)(0x0020)
+#define TPM2_ALG_KDF2 (TPM2_ALG_ID)(0x0021)
+#define TPM2_ALG_KDF1_SP800_108 (TPM2_ALG_ID)(0x0022)
+#define TPM2_ALG_ECC (TPM2_ALG_ID)(0x0023)
+#define TPM2_ALG_ECDAA (TPM2_ALG_ID)(0x0024)
+#define TPM2_ALG_CTR (TPM2_ALG_ID)(0x0040)
+#define TPM2_ALG_OFB (TPM2_ALG_ID)(0x0041)
+#define TPM2_ALG_CBC (TPM2_ALG_ID)(0x0042)
+#define TPM2_ALG_CFB (TPM2_ALG_ID)(0x0043)
+#define TPM2_ALG_ECB (TPM2_ALG_ID)(0x0044)
+
+
+// Table 7 -- TPM_CC from outputConstDef <I/O,S>
+typedef UINT32 TPM_CC;
+
+#define TPM_CC_FIRST (TPM_CC)(0x00000120)
+#define TPM_CC_PP_FIRST (TPM_CC)(0x00000120)
+#define TPM_CC_EvictControl (TPM_CC)(0x00000120)
+#define TPM_CC_HierarchyControl (TPM_CC)(0x00000121)
+#define TPM_CC_NV_UndefineSpace (TPM_CC)(0x00000122)
+#define TPM_CC_ChangeEPS (TPM_CC)(0x00000124)
+#define TPM_CC_ChangePPS (TPM_CC)(0x00000125)
+#define TPM_CC_Clear (TPM_CC)(0x00000126)
+#define TPM_CC_ClearControl (TPM_CC)(0x00000127)
+#define TPM_CC_ClockSet (TPM_CC)(0x00000128)
+#define TPM_CC_HierarchyChangeAuth (TPM_CC)(0x00000129)
+#define TPM_CC_NV_DefineSpace (TPM_CC)(0x0000012A)
+#define TPM_CC_PCR_Allocate (TPM_CC)(0x0000012B)
+#define TPM_CC_PCR_SetAuthPolicy (TPM_CC)(0x0000012C)
+#define TPM_CC_PP_Commands (TPM_CC)(0x0000012D)
+#define TPM_CC_SetPrimaryPolicy (TPM_CC)(0x0000012E)
+#define TPM_CC_FieldUpgradeStart (TPM_CC)(0x0000012F)
+#define TPM_CC_ClockRateAdjust (TPM_CC)(0x00000130)
+#define TPM_CC_CreatePrimary (TPM_CC)(0x00000131)
+#define TPM_CC_NV_GlobalWriteLock (TPM_CC)(0x00000132)
+#define TPM_CC_PP_LAST (TPM_CC)(0x00000132)
+#define TPM_CC_GetCommandAuditDigest (TPM_CC)(0x00000133)
+#define TPM_CC_NV_Increment (TPM_CC)(0x00000134)
+#define TPM_CC_NV_SetBits (TPM_CC)(0x00000135)
+#define TPM_CC_NV_Extend (TPM_CC)(0x00000136)
+#define TPM_CC_NV_Write (TPM_CC)(0x00000137)
+#define TPM_CC_NV_WriteLock (TPM_CC)(0x00000138)
+#define TPM_CC_DictionaryAttackLockReset (TPM_CC)(0x00000139)
+#define TPM_CC_DictionaryAttackParameters (TPM_CC)(0x0000013A)
+#define TPM_CC_NV_ChangeAuth (TPM_CC)(0x0000013B)
+#define TPM_CC_PCR_Event (TPM_CC)(0x0000013C)
+#define TPM_CC_PCR_Reset (TPM_CC)(0x0000013D)
+#define TPM_CC_SequenceComplete (TPM_CC)(0x0000013E)
+#define TPM_CC_SetRegion (TPM_CC)(0x0000013F)
+#define TPM_CC_SetCommandCodeAuditStatus (TPM_CC)(0x00000140)
+#define TPM_CC_FieldUpgradeData (TPM_CC)(0x00000141)
+#define TPM_CC_IncrementalSelfTest (TPM_CC)(0x00000142)
+#define TPM_CC_SelfTest (TPM_CC)(0x00000143)
+#define TPM_CC_Startup (TPM_CC)(0x00000144)
+#define TPM_CC_Shutdown (TPM_CC)(0x00000145)
+#define TPM_CC_StirRandom (TPM_CC)(0x00000146)
+#define TPM_CC_ActivateCredential (TPM_CC)(0x00000147)
+#define TPM_CC_Certify (TPM_CC)(0x00000148)
+#define TPM_CC_PolicyNV (TPM_CC)(0x00000149)
+#define TPM_CC_CertifyCreation (TPM_CC)(0x0000014A)
+#define TPM_CC_Duplicate (TPM_CC)(0x0000014B)
+#define TPM_CC_GetTime (TPM_CC)(0x0000014C)
+#define TPM_CC_GetSessionAuditDigest (TPM_CC)(0x0000014D)
+#define TPM_CC_NV_Read (TPM_CC)(0x0000014E)
+#define TPM_CC_NV_ReadLock (TPM_CC)(0x0000014F)
+#define TPM_CC_ObjectChangeAuth (TPM_CC)(0x00000150)
+#define TPM_CC_PolicySecret (TPM_CC)(0x00000151)
+#define TPM_CC_Rewrap (TPM_CC)(0x00000152)
+#define TPM_CC_Create (TPM_CC)(0x00000153)
+#define TPM_CC_ECDH_ZGen (TPM_CC)(0x00000154)
+#define TPM_CC_HMAC (TPM_CC)(0x00000155)
+#define TPM_CC_Import (TPM_CC)(0x00000156)
+#define TPM_CC_Load (TPM_CC)(0x00000157)
+#define TPM_CC_Quote (TPM_CC)(0x00000158)
+#define TPM_CC_RSADP (TPM_CC)(0x00000159)
+#define TPM_CC_RSAES_OAEP_Decrypt (TPM_CC)(0x0000015A)
+#define TPM_CC_HMAC_Start (TPM_CC)(0x0000015B)
+#define TPM_CC_SequenceUpdate (TPM_CC)(0x0000015C)
+#define TPM_CC_Sign (TPM_CC)(0x0000015D)
+#define TPM_CC_Unseal (TPM_CC)(0x0000015E)
+#define TPM_CC_PolicySigned (TPM_CC)(0x00000160)
+#define TPM_CC_ContextLoad (TPM_CC)(0x00000161)
+#define TPM_CC_ContextSave (TPM_CC)(0x00000162)
+#define TPM_CC_ECDH_KeyGen (TPM_CC)(0x00000163)
+#define TPM_CC_EncryptDecrypt (TPM_CC)(0x00000164)
+#define TPM_CC_FlushContext (TPM_CC)(0x00000165)
+#define TPM_CC_LoadPrimary (TPM_CC)(0x00000166)
+#define TPM_CC_LoadExternal (TPM_CC)(0x00000167)
+#define TPM_CC_MakeCredential (TPM_CC)(0x00000168)
+#define TPM_CC_NV_ReadPublic (TPM_CC)(0x00000169)
+#define TPM_CC_PolicyAuthorize (TPM_CC)(0x0000016A)
+#define TPM_CC_PolicyAuthValue (TPM_CC)(0x0000016B)
+#define TPM_CC_PolicyCommandCode (TPM_CC)(0x0000016C)
+#define TPM_CC_PolicyCounterTimer (TPM_CC)(0x0000016D)
+#define TPM_CC_PolicyCpHash (TPM_CC)(0x0000016E)
+#define TPM_CC_PolicyLocality (TPM_CC)(0x0000016F)
+#define TPM_CC_PolicyNameHash (TPM_CC)(0x00000170)
+#define TPM_CC_PolicyOR (TPM_CC)(0x00000171)
+#define TPM_CC_PolicyTicket (TPM_CC)(0x00000172)
+#define TPM_CC_ReadPublic (TPM_CC)(0x00000173)
+#define TPM_CC_RSAEP (TPM_CC)(0x00000174)
+#define TPM_CC_RSAES_OAEP_Encrypt (TPM_CC)(0x00000175)
+#define TPM_CC_StartAuthSession (TPM_CC)(0x00000176)
+#define TPM_CC_VerifySignature (TPM_CC)(0x00000177)
+#define TPM_CC_ECC_Parameters (TPM_CC)(0x00000178)
+#define TPM_CC_FirmwareRead (TPM_CC)(0x00000179)
+#define TPM_CC_GetCapability (TPM_CC)(0x0000017A)
+#define TPM_CC_GetRandom (TPM_CC)(0x0000017B)
+#define TPM_CC_GetTestResult (TPM_CC)(0x0000017C)
+#define TPM_CC_Hash (TPM_CC)(0x0000017D)
+#define TPM_CC_PCR_Read (TPM_CC)(0x0000017E)
+#define TPM_CC_PolicyPCR (TPM_CC)(0x0000017F)
+#define TPM_CC_PolicyRestart (TPM_CC)(0x00000180)
+#define TPM_CC_ReadClock (TPM_CC)(0x00000181)
+#define TPM_CC_PCR_Extend (TPM_CC)(0x00000182)
+#define TPM_CC_PCR_SetAuthValue (TPM_CC)(0x00000183)
+#define TPM_CC_NV_Certify (TPM_CC)(0x00000184)
+#define TPM_CC_EventSequenceComplete (TPM_CC)(0x00000185)
+#define TPM_CC_HashSequenceStart (TPM_CC)(0x00000186)
+#define TPM_CC_PolicyPhysicalPresence (TPM_CC)(0x00000187)
+#define TPM_CC_PolicyDuplicationSelect (TPM_CC)(0x00000188)
+#define TPM_CC_PolicyGetDigest (TPM_CC)(0x00000189)
+#define TPM_CC_TestParms (TPM_CC)(0x0000018A)
+#define TPM_CC_ECDAA_Certify (TPM_CC)(0x0000018B)
+#define TPM_CC_PolicyPassword (TPM_CC)(0x0000018C)
+#define TPM_CC_LAST (TPM_CC)(0x0000018C)
+
+
+
+
+// Table 11 -- TPM_RC from outputConstDef <O,S>
+typedef UINT32 TPM_RC;
+
+#define TPM_RC_SUCCESS (TPM_RC)(0x000)
+#define TPM_RC_BAD_TAG (TPM_RC)(0x030)
+#define RC_VER1 (TPM_RC)(0x100)
+#define TPM_RC_PRIVATE (TPM_RC)(RC_VER1 + 0x00B)
+#define TPM_RC_INITIALIZE (TPM_RC)(RC_VER1 + 0x000)
+#define TPM_RC_FAILURE (TPM_RC)(RC_VER1 + 0x001)
+#define TPM_RC_SEQUENCE (TPM_RC)(RC_VER1 + 0x003)
+#define TPM_RC_HMAC (TPM_RC)(RC_VER1 + 0x019)
+#define TPM_RC_DISABLED (TPM_RC)(RC_VER1 + 0x020)
+#define TPM_RC_EXCLUSIVE (TPM_RC)(RC_VER1 + 0x021)
+#define TPM_RC_ECC_CURVE (TPM_RC)(RC_VER1 + 0x023)
+#define TPM_RC_AUTH_TYPE (TPM_RC)(RC_VER1 + 0x024)
+#define TPM_RC_AUTH_MISSING (TPM_RC)(RC_VER1 + 0x025)
+#define TPM_RC_POLICY (TPM_RC)(RC_VER1 + 0x026)
+#define TPM_RC_PCR (TPM_RC)(RC_VER1 + 0x027)
+#define TPM_RC_PCR_CHANGED (TPM_RC)(RC_VER1 + 0x028)
+#define TPM_RC_ECC_POINT (TPM_RC)(RC_VER1 + 0x02C)
+#define TPM_RC_UPGRADE (TPM_RC)(RC_VER1 + 0x02D)
+#define TPM_RC_TOO_MANY_CONTEXTS (TPM_RC)(RC_VER1 + 0x02E)
+#define TPM_RC_AUTH_UNAVAILABLE (TPM_RC)(RC_VER1 + 0x02F)
+#define TPM_RC_REBOOT (TPM_RC)(RC_VER1 + 0x030)
+#define TPM_RC_COMMAND_SIZE (TPM_RC)(RC_VER1 + 0x042)
+#define TPM_RC_COMMAND_CODE (TPM_RC)(RC_VER1 + 0x043)
+#define TPM_RC_AUTHSIZE (TPM_RC)(RC_VER1 + 0x044)
+#define TPM_RC_AUTH_CONTEXT (TPM_RC)(RC_VER1 + 0x045)
+#define TPM_RC_NV_RANGE (TPM_RC)(RC_VER1 + 0x046)
+#define TPM_RC_NV_SIZE (TPM_RC)(RC_VER1 + 0x047)
+#define TPM_RC_NV_LOCKED (TPM_RC)(RC_VER1 + 0x048)
+#define TPM_RC_NV_AUTHORIZATION (TPM_RC)(RC_VER1 + 0x049)
+#define TPM_RC_NV_UNINITIALIZED (TPM_RC)(RC_VER1 + 0x04A)
+#define TPM_RC_NV_SPACE (TPM_RC)(RC_VER1 + 0x04B)
+#define TPM_RC_NV_DEFINED (TPM_RC)(RC_VER1 + 0x04C)
+#define TPM_RC_BAD_CONTEXT (TPM_RC)(RC_VER1 + 0x050)
+#define TPM_RC_CPHASH (TPM_RC)(RC_VER1 + 0x051)
+#define TPM_RC_PARENT (TPM_RC)(RC_VER1 + 0x052)
+#define RC_MAX_FM0 (TPM_RC)(RC_VER1 + 0x07F)
+#define RC_FMT1 (TPM_RC)(0x080)
+#define TPM_RC_ASYMMETRIC (TPM_RC)(RC_FMT1 + 0x001)
+#define TPM_RC_ATTRIBUTES (TPM_RC)(RC_FMT1 + 0x002)
+#define TPM_RC_HASH (TPM_RC)(RC_FMT1 + 0x003)
+#define TPM_RC_VALUE (TPM_RC)(RC_FMT1 + 0x004)
+#define TPM_RC_HIERARCHY (TPM_RC)(RC_FMT1 + 0x005)
+#define TPM_RC_KEY_SIZE (TPM_RC)(RC_FMT1 + 0x007)
+#define TPM_RC_MGF (TPM_RC)(RC_FMT1 + 0x008)
+#define TPM_RC_MODE (TPM_RC)(RC_FMT1 + 0x009)
+#define TPM_RC_TYPE (TPM_RC)(RC_FMT1 + 0x00A)
+#define TPM_RC_HANDLE (TPM_RC)(RC_FMT1 + 0x00B)
+#define TPM_RC_KDF (TPM_RC)(RC_FMT1 + 0x00C)
+#define TPM_RC_RANGE (TPM_RC)(RC_FMT1 + 0x00D)
+#define TPM_RC_AUTH_FAIL (TPM_RC)(RC_FMT1 + 0x00E)
+#define TPM_RC_NONCE (TPM_RC)(RC_FMT1 + 0x00F)
+#define TPM_RC_PP (TPM_RC)(RC_FMT1 + 0x010)
+#define TPM_RC_SCHEME (TPM_RC)(RC_FMT1 + 0x012)
+#define TPM_RC_SIZE (TPM_RC)(RC_FMT1 + 0x015)
+#define TPM_RC_SYMMETRIC (TPM_RC)(RC_FMT1 + 0x016)
+#define TPM_RC_TAG (TPM_RC)(RC_FMT1 + 0x017)
+#define TPM_RC_SELECTOR (TPM_RC)(RC_FMT1 + 0x018)
+#define TPM_RC_INSUFFICIENT (TPM_RC)(RC_FMT1 + 0x01A)
+#define TPM_RC_SIGNATURE (TPM_RC)(RC_FMT1 + 0x01B)
+#define TPM_RC_KEY (TPM_RC)(RC_FMT1 + 0x01C)
+#define TPM_RC_POLICY_FAIL (TPM_RC)(RC_FMT1 + 0x01D)
+#define TPM_RC_INTEGRITY (TPM_RC)(RC_FMT1 + 0x01F)
+#define TPM_RC_TICKET (TPM_RC)(RC_FMT1 + 0x020)
+#define TPM_RC_RESERVED_BITS (TPM_RC)(RC_FMT1 + 0x021)
+#define RC_WARN (TPM_RC)(0x900)
+#define TPM_RC_CONTEXT_GAP (TPM_RC)(RC_WARN + 0x001)
+#define TPM_RC_OBJECT_MEMORY (TPM_RC)(RC_WARN + 0x002)
+#define TPM_RC_SESSION_MEMORY (TPM_RC)(RC_WARN + 0x003)
+#define TPM_RC_MEMORY (TPM_RC)(RC_WARN + 0x004)
+#define TPM_RC_SESSION_HANDLES (TPM_RC)(RC_WARN + 0x005)
+#define TPM_RC_OBJECT_HANDLES (TPM_RC)(RC_WARN + 0x006)
+#define TPM_RC_LOCALITY (TPM_RC)(RC_WARN + 0x007)
+#define TPM_RC_YIELDED (TPM_RC)(RC_WARN + 0x008)
+#define TPM_RC_CANCELLED (TPM_RC)(RC_WARN + 0x009)
+#define TPM_RC_TESTING (TPM_RC)(RC_WARN + 0x00A)
+#define TPM_RC_REFERENCE_H0 (TPM_RC)(RC_WARN + 0x010)
+#define TPM_RC_REFERENCE_H1 (TPM_RC)(RC_WARN + 0x011)
+#define TPM_RC_REFERENCE_H2 (TPM_RC)(RC_WARN + 0x012)
+#define TPM_RC_REFERENCE_H3 (TPM_RC)(RC_WARN + 0x013)
+#define TPM_RC_REFERENCE_H4 (TPM_RC)(RC_WARN + 0x014)
+#define TPM_RC_REFERENCE_H5 (TPM_RC)(RC_WARN + 0x015)
+#define TPM_RC_REFERENCE_H6 (TPM_RC)(RC_WARN + 0x016)
+#define TPM_RC_REFERENCE_S0 (TPM_RC)(RC_WARN + 0x018)
+#define TPM_RC_REFERENCE_S1 (TPM_RC)(RC_WARN + 0x019)
+#define TPM_RC_REFERENCE_S2 (TPM_RC)(RC_WARN + 0x01A)
+#define TPM_RC_REFERENCE_S3 (TPM_RC)(RC_WARN + 0x01B)
+#define TPM_RC_REFERENCE_S4 (TPM_RC)(RC_WARN + 0x01C)
+#define TPM_RC_REFERENCE_S5 (TPM_RC)(RC_WARN + 0x01D)
+#define TPM_RC_REFERENCE_S6 (TPM_RC)(RC_WARN + 0x01E)
+#define TPM_RC_REFERENCE_S7 (TPM_RC)(RC_WARN + 0x01F)
+#define TPM_RC_NV_RATE (TPM_RC)(RC_WARN + 0x020)
+#define TPM_RC_LOCKOUT (TPM_RC)(RC_WARN + 0x021)
+#define TPM_RC_H (TPM_RC)(0x000)
+#define TPM_RC_P (TPM_RC)(0x040)
+#define TPM_RC_S (TPM_RC)(0x800)
+#define TPM_RC_1 (TPM_RC)(0x100)
+#define TPM_RC_2 (TPM_RC)(0x200)
+#define TPM_RC_3 (TPM_RC)(0x300)
+#define TPM_RC_4 (TPM_RC)(0x400)
+#define TPM_RC_5 (TPM_RC)(0x500)
+#define TPM_RC_6 (TPM_RC)(0x600)
+#define TPM_RC_7 (TPM_RC)(0x700)
+#define TPM_RC_8 (TPM_RC)(0x800)
+#define TPM_RC_9 (TPM_RC)(0x900)
+#define TPM_RC_A (TPM_RC)(0xA00)
+#define TPM_RC_B (TPM_RC)(0xB00)
+#define TPM_RC_C (TPM_RC)(0xC00)
+#define TPM_RC_D (TPM_RC)(0xD00)
+#define TPM_RC_E (TPM_RC)(0xE00)
+#define TPM_RC_F (TPM_RC)(0xF00)
+#define TPM_RC_N_MASK (TPM_RC)(0xF00)
+
+
+
+
+// Table 12 -- TPM_CLOCK_ADJUST from outputConstDef <I,S>
+typedef INT8 TPM_CLOCK_ADJUST;
+
+#define TPM_CLOCK_COARSE_SLOWER (TPM_CLOCK_ADJUST)(-3)
+#define TPM_CLOCK_MEDIUM_SLOWER (TPM_CLOCK_ADJUST)(-2)
+#define TPM_CLOCK_FINE_SLOWER (TPM_CLOCK_ADJUST)(-1)
+#define TPM_CLOCK_NO_CHANGE (TPM_CLOCK_ADJUST)(0)
+#define TPM_CLOCK_FINE_FASTER (TPM_CLOCK_ADJUST)(1)
+#define TPM_CLOCK_MEDIUM_FASTER (TPM_CLOCK_ADJUST)(2)
+#define TPM_CLOCK_COARSE_FASTER (TPM_CLOCK_ADJUST)(3)
+
+
+
+
+// Table 13 -- TPM_EO from outputConstDef <I/O,S>
+typedef UINT16 TPM_EO;
+
+#define TPM_EO_EQ (TPM_EO)(0x0000)
+#define TPM_EO_NEQ (TPM_EO)(0x0001)
+#define TPM_EO_SIGNED_GT (TPM_EO)(0x0002)
+#define TPM_EO_UNSIGNED_GT (TPM_EO)(0x0003)
+#define TPM_EO_SIGNED_LT (TPM_EO)(0x0004)
+#define TPM_EO_UNSIGNED_LT (TPM_EO)(0x0005)
+#define TPM_EO_SIGNED_GE (TPM_EO)(0x0006)
+#define TPM_EO_UNSIGNED_GE (TPM_EO)(0x0007)
+#define TPM_EO_SIGNED_LE (TPM_EO)(0x0008)
+#define TPM_EO_UNSIGNED_LE (TPM_EO)(0x0009)
+#define TPM_EO_BITSET (TPM_EO)(0x000A)
+#define TPM_EO_BITCLEAR (TPM_EO)(0x000B)
+
+
+
+
+// Table 14 -- TPM_ST from outputConstDef <I/O,S>
+typedef UINT16 TPM_ST;
+
+#define TPM_ST_RSP_COMMAND (TPM_ST)(0x00C4)
+#define TPM_ST_NULL (TPM_ST)(0X8000)
+#define TPM_ST_NO_SESSIONS (TPM_ST)(0x8001)
+#define TPM_ST_SESSIONS (TPM_ST)(0x8002)
+#define TPM_ST_ATTEST_COMMAND_AUDIT (TPM_ST)(0x8015)
+#define TPM_ST_ATTEST_SESSION_AUDIT (TPM_ST)(0x8016)
+#define TPM_ST_ATTEST_CERTIFY (TPM_ST)(0x8017)
+#define TPM_ST_ATTEST_QUOTE (TPM_ST)(0x8018)
+#define TPM_ST_ATTEST_TIME (TPM_ST)(0x8019)
+#define TPM_ST_ATTEST_CREATION (TPM_ST)(0x801A)
+#define TPM_ST_ATTEST_NV (TPM_ST)(0x801B)
+#define TPM_ST_CREATION (TPM_ST)(0x8021)
+#define TPM_ST_VERIFIED (TPM_ST)(0x8022)
+#define TPM_ST_AUTH (TPM_ST)(0x8023)
+#define TPM_ST_HASHCHECK (TPM_ST)(0x8024)
+#define TPM_ST_FU_MANIFEST (TPM_ST)(0x8029)
+
+
+// Table 15 -- TPM_SU from outputConstDef <I>
+typedef UINT16 TPM_SU;
+
+#define TPM_SU_CLEAR (TPM_SU)(0x0000)
+#define TPM_SU_STATE (TPM_SU)(0x0001)
+
+
+
+
+// Table 16 -- TPM_SE from outputConstDef <I>
+typedef UINT8 TPM_SE;
+
+#define TPM_SE_HMAC (TPM_SE)(0x00)
+#define TPM_SE_POLICY (TPM_SE)(0x01)
+#define TPM_SE_TRIAL (TPM_SE)(0x03)
+
+
+
+
+// Table 17 -- TPM_CAP from outputConstDef <I/O,S>
+typedef UINT32 TPM_CAP;
+
+#define TPM_CAP_FIRST (TPM_CAP)(0x00000000)
+#define TPM_CAP_ALGS (TPM_CAP)(0x00000000)
+#define TPM_CAP_HANDLES (TPM_CAP)(0x00000001)
+#define TPM_CAP_COMMANDS (TPM_CAP)(0x00000002)
+#define TPM_CAP_PP_COMMANDS (TPM_CAP)(0x00000003)
+#define TPM_CAP_AUDIT_COMMANDS (TPM_CAP)(0x00000004)
+#define TPM_CAP_PCRS (TPM_CAP)(0x00000005)
+#define TPM_CAP_TPM_PROPERTIES (TPM_CAP)(0x00000006)
+#define TPM_CAP_PCR_PROPERTIES (TPM_CAP)(0x00000007)
+#define TPM_CAP_ECC_CURVES (TPM_CAP)(0x00000008)
+#define TPM_CAP_LAST (TPM_CAP)(0x00000008)
+#define TPM_CAP_VENDOR_PROPERTY (TPM_CAP)(0x00000100)
+
+
+
+
+// Table 18 -- TPM_PT from outputConstDef <I/O,S>
+typedef UINT32 TPM_PT;
+
+#define TPM_PT_NONE (TPM_PT)(0x00000000)
+#define PT_GROUP (TPM_PT)(0x00000100)
+#define PT_FIXED (TPM_PT)(PT_GROUP * 1)
+#define TPM_PT_FAMILY_INDICATOR (TPM_PT)(PT_FIXED + 0)
+#define TPM_PT_LEVEL (TPM_PT)(PT_FIXED + 1)
+#define TPM_PT_REVISION (TPM_PT)(PT_FIXED + 2)
+#define TPM_PT_DAY_OF_YEAR (TPM_PT)(PT_FIXED + 3)
+#define TPM_PT_YEAR (TPM_PT)(PT_FIXED + 4)
+#define TPM_PT_MANUFACTURER (TPM_PT)(PT_FIXED + 5)
+#define TPM_PT_VENDOR_TPM_TYPE (TPM_PT)(PT_FIXED + 6)
+#define TPM_PT_FIRMWARE_VERSION_1 (TPM_PT)(PT_FIXED + 7)
+#define TPM_PT_FIRMWARE_VERSION_2 (TPM_PT)(PT_FIXED + 8)
+#define TPM_PT_INPUT_BUFFER (TPM_PT)(PT_FIXED + 9)
+#define TPM_PT_HR_TRANSIENT_MIN (TPM_PT)(PT_FIXED + 10)
+#define TPM_PT_HR_PERSISTENT_MIN (TPM_PT)(PT_FIXED + 11)
+#define TPM_PT_HR_LOADED_MIN (TPM_PT)(PT_FIXED + 12)
+#define TPM_PT_ACTIVE_SESSIONS_MAX (TPM_PT)(PT_FIXED + 13)
+#define TPM_PT_PCR_COUNT (TPM_PT)(PT_FIXED + 14)
+#define TPM_PT_PCR_SELECT_MIN (TPM_PT)(PT_FIXED + 15)
+#define TPM_PT_CONTEXT_GAP_MAX (TPM_PT)(PT_FIXED + 16)
+#define TPM_PT_NV_COUNTERS_MAX (TPM_PT)(PT_FIXED + 17)
+#define TPM_PT_NV_INDEX_MAX (TPM_PT)(PT_FIXED + 18)
+#define TPM_PT_MEMORY (TPM_PT)(PT_FIXED + 19)
+#define TPM_PT_CLOCK_UPDATE (TPM_PT)(PT_FIXED + 20)
+#define TPM_PT_CONTEXT_HASH (TPM_PT)(PT_FIXED + 22)
+#define TPM_PT_CONTEXT_SYM (TPM_PT)(PT_FIXED + 23)
+#define TPM_PT_CONTEXT_SYM_SIZE (TPM_PT)(PT_FIXED + 24)
+#define TPM_PT_ORDERLY_COUNT (TPM_PT)(PT_FIXED + 25)
+#define TPM_PT_MAX_COMMAND_SIZE (TPM_PT)(PT_FIXED + 26)
+#define TPM_PT_MAX_RESPONSE_SIZE (TPM_PT)(PT_FIXED + 27)
+#define TPM_PT_MAX_DIGEST (TPM_PT)(PT_FIXED + 28)
+#define TPM_PT_MAX_OBJECT_CONTEXT (TPM_PT)(PT_FIXED + 29)
+#define TPM_PT_MAX_SESSION_CONTEXT (TPM_PT)(PT_FIXED+ 30)
+#define PT_VAR (TPM_PT)(PT_GROUP * 2)
+#define TPM_PT_PERMANENT (TPM_PT)(PT_VAR + 0)
+#define TPM_PT_STARTUP_CLEAR (TPM_PT)(PT_VAR + 1)
+#define TPM_PT_HR_NV_INDEX (TPM_PT)(PT_VAR + 2)
+#define TPM_PT_HR_LOADED (TPM_PT)(PT_VAR + 3)
+#define TPM_PT_HR_LOADED_AVAIL (TPM_PT)(PT_VAR + 4)
+#define TPM_PT_HR_ACTIVE (TPM_PT)(PT_VAR + 5)
+#define TPM_PT_HR_ACTIVE_AVAIL (TPM_PT)(PT_VAR + 6)
+#define TPM_PT_HR_TRANSIENT_AVAIL (TPM_PT)(PT_VAR + 7)
+#define TPM_PT_HR_PERSISTENT (TPM_PT)(PT_VAR + 8)
+#define TPM_PT_HR_PERSISTENT_AVAIL (TPM_PT)(PT_VAR + 9)
+#define TPM_PT_NV_COUNTERS (TPM_PT)(PT_VAR + 10)
+#define TPM_PT_NV_COUNTERS_AVAIL (TPM_PT)(PT_VAR + 11)
+#define TPM_PT_REGION (TPM_PT)(PT_VAR + 12)
+#define TPM_PT_LOADED_CURVES (TPM_PT)(PT_VAR + 13)
+#define TPM_PT_AUDIT_COUNTER (TPM_PT)(PT_VAR + 14)
+#define TPM_PT_LOCKOUT_COUNTER (TPM_PT)(PT_VAR + 15)
+#define TPM_PT_MAX_AUTH_FAIL (TPM_PT)(PT_VAR + 16)
+#define TPM_PT_LOCKOUT_INTERVAL (TPM_PT)(PT_VAR + 17)
+#define TPM_PT_LOCKOUT_RECOVERY (TPM_PT)(PT_VAR + 18)
+#define TPM_PT_NV_WRITE_RECOVERY (TPM_PT)(PT_VAR + 19)
+
+
+// Table 19 -- TPM_PT_PCR from outputConstDef <I/O,S>
+typedef UINT32 TPM_PT_PCR;
+
+#define TPM_PT_PCR_FIRST (TPM_PT_PCR)(0x00000000)
+#define TPM_PT_PCR_SAVE (TPM_PT_PCR)(0x00000000)
+#define TPM_PT_PCR_EXTEND_L0 (TPM_PT_PCR)(0x00000001)
+#define TPM_PT_PCR_RESET_L0 (TPM_PT_PCR)(0x00000002)
+#define TPM_PT_PCR_EXTEND_L1 (TPM_PT_PCR)(0x00000003)
+#define TPM_PT_PCR_RESET_L1 (TPM_PT_PCR)(0x00000004)
+#define TPM_PT_PCR_EXTEND_L2 (TPM_PT_PCR)(0x00000005)
+#define TPM_PT_PCR_RESET_L2 (TPM_PT_PCR)(0x00000006)
+#define TPM_PT_PCR_EXTEND_L3 (TPM_PT_PCR)(0x00000007)
+#define TPM_PT_PCR_RESET_L3 (TPM_PT_PCR)(0x00000008)
+#define TPM_PT_PCR_EXTEND_L4 (TPM_PT_PCR)(0x00000009)
+#define TPM_PT_PCR_RESET_L4 (TPM_PT_PCR)(0x0000000A)
+#define TPM_PT_PCR_DRTM_RESET (TPM_PT_PCR)(0x0000000B)
+#define TPM_PT_PCR_POLICY (TPM_PT_PCR)(0x0000000C)
+#define TPM_PT_PCR_AUTH (TPM_PT_PCR)(0x0000000D)
+#define TPM_PT_PCR_LAST (TPM_PT_PCR)(0x0000000D)
+
+
+// Table 20 -- Handles from outputTypeDef <I/O>
+typedef UINT32 TPM_HANDLE;
+
+// Table 21 -- TPM_HT from outputConstDef <S>
+typedef UINT8 TPM_HT;
+
+#define TPM_HT_PCR (TPM_HT)(0x00)
+#define TPM_HT_NV_INDEX (TPM_HT)(0x01)
+#define TPM_HT_HMAC_SESSION (TPM_HT)(0x02)
+#define TPM_HT_LOADED_SESSION (TPM_HT)(0x02)
+#define TPM_HT_POLICY_SESSION (TPM_HT)(0x03)
+#define TPM_HT_ACTIVE_SESSION (TPM_HT)(0x03)
+#define TPM_HT_PERMANENT (TPM_HT)(0x40)
+#define TPM_HT_TRANSIENT (TPM_HT)(0x80)
+#define TPM_HT_PERSISTENT (TPM_HT)(0x81)
+
+
+
+
+// Table 22 -- TPM_RH from outputConstDef <I,S>
+typedef UINT32 TPM_RH;
+
+#define TPM_RH_FIRST (TPM_RH)(0x40000000)
+#define TPM_RH_SRK (TPM_RH)(0x40000000)
+#define TPM_RH_OWNER (TPM_RH)(0x40000001)
+#define TPM_RH_REVOKE (TPM_RH)(0x40000002)
+#define TPM_RH_TRANSPORT (TPM_RH)(0x40000003)
+#define TPM_RH_OPERATOR (TPM_RH)(0x40000004)
+#define TPM_RH_ADMIN (TPM_RH)(0x40000005)
+#define TPM_RH_EK (TPM_RH)(0x40000006)
+#define TPM_RH_NULL (TPM_RH)(0x40000007)
+#define TPM_RH_UNASSIGNED (TPM_RH)(0x40000008)
+#define TPM_RH_PW (TPM_RH)(0x40000009)
+#define TPM_RS_PW (TPM_RH)(0x40000009)
+#define TPM_RH_LOCKOUT (TPM_RH)(0x4000000A)
+#define TPM_RH_ENDORSEMENT (TPM_RH)(0x4000000B)
+#define TPM_RH_PLATFORM (TPM_RH)(0x4000000C)
+#define TPM_RH_LAST (TPM_RH)(0x4000000C)
+#define TPM_RH_PCR0 (TPM_RH)(0x00000000)
+
+
+// Table 23 -- TPM_HC from outputConstDef <I,S>
+typedef TPM_HANDLE TPM_HC;
+
+#define HR_HANDLE_MASK (TPM_HC)(0x00FFFFFF)
+#define HR_RANGE_MASK (TPM_HC)(0xFF000000)
+#define HR_SHIFT (TPM_HC)(24)
+#define HR_PCR (TPM_HC)(TPM_HT_PCR << HR_SHIFT)
+#define HR_HMAC_SESSION (TPM_HC)(TPM_HT_HMAC_SESSION << HR_SHIFT)
+#define HR_POLICY_SESSION (TPM_HC)(TPM_HT_POLICY_SESSION << HR_SHIFT)
+#define HR_TRANSIENT (TPM_HC)(TPM_HT_TRANSIENT << HR_SHIFT)
+#define HR_PERSISTENT (TPM_HC)(TPM_HT_PERSISTENT << HR_SHIFT)
+#define HR_NV_INDEX (TPM_HC)(TPM_HT_NV_INDEX << HR_SHIFT)
+#define HR_PERMANENT (TPM_HC)(TPM_HT_PERMANENT << HR_SHIFT)
+#define PCR_FIRST (TPM_HC)(TPM_RH_PCR0)
+#define PCR_LAST (TPM_HC)(PCR_FIRST + IMPLEMENTATION_PCR-1)
+#define HMAC_SESSION_FIRST (TPM_HC)(HR_HMAC_SESSION + 0)
+#define HMAC_SESSION_LAST (TPM_HC)(HMAC_SESSION_FIRST+MAX_ACTIVE_SESSIONS-1)
+#define POLICY_SESSION_FIRST (TPM_HC)(HR_POLICY_SESSION + 0)
+#define POLICY_SESSION_LAST (TPM_HC)(POLICY_SESSION_FIRST + MAX_ACTIVE_SESSIONS-1)
+#define TRANSIENT_FIRST (TPM_HC)(HR_TRANSIENT + 0)
+#define TRANSIENT_LAST (TPM_HC)(TRANSIENT_FIRST+MAX_LOADED_OBJECTS-1)
+#define PERSISTENT_FIRST (TPM_HC)(HR_PERSISTENT + 0)
+#define PERSISTENT_LAST (TPM_HC)(PERSISTENT_FIRST + 0x00FFFFFF)
+#define PLATFORM_PERSISTENT (TPM_HC)(PERSISTENT_FIRST + 0x00800000)
+#define NV_INDEX_FIRST (TPM_HC)(HR_NV_INDEX + 0)
+#define NV_INDEX_LAST (TPM_HC)(NV_INDEX_FIRST + 0x00FFFFFF)
+#define PERMANENT_FIRST (TPM_HC)(TPM_RH_FIRST)
+#define PERMANENT_LAST (TPM_HC)(TPM_RH_LAST)
+
+
+// Table 24 -- TPMA_ALGORITHM from outputBitDef <I/O>
+typedef struct {
+ unsigned int asymmetric : 1;
+ unsigned int symmetric : 1;
+ unsigned int hash : 1;
+ unsigned int reserved4 : 5;
+ unsigned int signing : 1;
+ unsigned int encrypting : 1;
+ unsigned int method : 1;
+ unsigned int reserved8 : 21;
+} TPMA_ALGORITHM ;
+
+// Table 25 -- TPMA_OBJECT from outputBitDef <I/O>
+typedef struct {
+ unsigned int reserved1 : 1;
+ unsigned int fixedTPM : 1;
+ unsigned int stClear : 1;
+ unsigned int reserved4 : 1;
+ unsigned int fixedParent : 1;
+ unsigned int newKey : 1;
+ unsigned int withAuth : 1;
+ unsigned int withPolicy : 1;
+ unsigned int Pad9 : 1; //Inserted extra pad
+ unsigned int fixedEmptyAuth : 1;
+ unsigned int noDA : 1;
+ unsigned int reserved11 : 5;
+ unsigned int restricted : 1;
+ unsigned int decrypt : 1;
+ unsigned int sign : 1;
+ unsigned int Pad15 : 13;
+} TPMA_OBJECT ;
+
+// Table 26 -- TPMA_SESSION from outputBitDef <I/O>
+typedef struct {
+ unsigned int continueSession : 1;
+ unsigned int auditExclusive : 1;
+ unsigned int auditReset : 1;
+ unsigned int reserved4 : 2;
+ unsigned int encrypted : 1;
+ unsigned int encrypt : 1;
+ unsigned int audit : 1;
+} TPMA_SESSION ;
+
+// Table 27 -- TPMA_LOCALITY from outputBitDef <I/O>
+typedef struct {
+ unsigned int TPM2_LOC_ZERO : 1;
+ unsigned int TPM2_LOC_ONE : 1;
+ unsigned int TPM2_LOC_TWO : 1;
+ unsigned int TPM2_LOC_THREE : 1;
+ unsigned int TPM2_LOC_FOUR : 1;
+ unsigned int reserved6 : 3;
+} TPMA_LOCALITY ;
+
+// Table 28 -- TPMA_PERMANENT from outputBitDef <O,S>
+typedef struct {
+ unsigned int ownerAuthSet : 1;
+ unsigned int endorsementAuthSet : 1;
+ unsigned int lockoutAuthSet : 1;
+ unsigned int reserved4 : 5;
+ unsigned int disableClear : 1;
+ unsigned int inLockout : 1;
+ unsigned int tpmGeneratedEPS : 1;
+ unsigned int reserved8 : 21;
+} TPMA_PERMANENT ;
+
+// Table 29 -- TPMA_STARTUP_CLEAR from outputBitDef <O,S>
+typedef struct {
+ unsigned int phEnable : 1;
+ unsigned int shEnable : 1;
+ unsigned int ehEnable : 1;
+ unsigned int reserved4 : 28;
+ unsigned int orderly : 1;
+} TPMA_STARTUP_CLEAR ;
+
+// Table 30 -- TPMA_MEMORY from outputBitDef <O,S>
+typedef struct {
+ unsigned int sharedRAM : 1;
+ unsigned int sharedNV : 1;
+ unsigned int objectCopiedToRam : 1;
+ unsigned int reserved4 : 29;
+} TPMA_MEMORY ;
+
+// Table 31 -- TPMI_YES_NO from outputType <I/O>
+typedef BYTE TPMI_YES_NO;
+
+
+// Table 32 -- TPMI_DH_OBJECT from outputType <I/O>
+typedef TPM_HANDLE TPMI_DH_OBJECT;
+
+
+// Table 33 -- TPMI_DH_PERSISTENT from outputType <I/O>
+typedef TPM_HANDLE TPMI_DH_PERSISTENT;
+
+
+// Table 34 -- TPMI_DH_ENTITY from outputType <I>
+typedef TPM_HANDLE TPMI_DH_ENTITY;
+
+
+// Table 35 -- TPMI_DH_PARENT from outputType <I>
+typedef TPM_HANDLE TPMI_DH_PARENT;
+
+
+// Table 36 -- TPMI_DH_PCR from outputType <I>
+typedef TPM_HANDLE TPMI_DH_PCR;
+
+
+// Table 37 -- TPMI_SH_AUTH_SESSION from outputType <I/O>
+typedef TPM_HANDLE TPMI_SH_AUTH_SESSION;
+
+
+// Table 38 -- TPMI_SH_HMAC from outputType <I/O>
+typedef TPM_HANDLE TPMI_SH_HMAC;
+
+
+// Table 39 -- TPMI_SH_POLICY from outputType <I/O>
+typedef TPM_HANDLE TPMI_SH_POLICY;
+
+
+// Table 40 -- TPMI_DH_CONTEXT from outputType <I/O>
+typedef TPM_HANDLE TPMI_DH_CONTEXT;
+
+
+// Table 41 -- TPMI_RH_HIERARCHY from outputType <I/O>
+typedef TPM_HANDLE TPMI_RH_HIERARCHY;
+
+
+// Table 42 -- TPMI_RH_HIERARCHY_AUTH from outputType <I>
+typedef TPM_HANDLE TPMI_RH_HIERARCHY_AUTH;
+
+
+// Table 43 -- TPMI_RH_PLATFORM from outputType <I>
+typedef TPM_HANDLE TPMI_RH_PLATFORM;
+
+
+// Table 44 -- TPMI_RH_OWNER from outputType <I>
+typedef TPM_HANDLE TPMI_RH_OWNER;
+
+
+// Table 45 -- TPMI_RH_ENDORSEMENT from outputType <I>
+typedef TPM_HANDLE TPMI_RH_ENDORSEMENT;
+
+
+// Table 46 -- TPMI_RH_PROVISION from outputType <I>
+typedef TPM_HANDLE TPMI_RH_PROVISION;
+
+
+// Table 47 -- TPMI_RH_CLEAR from outputType <I>
+typedef TPM_HANDLE TPMI_RH_CLEAR;
+
+
+// Table 48 -- TPMI_RH_NV_AUTH from outputType <I>
+typedef TPM_HANDLE TPMI_RH_NV_AUTH;
+
+
+// Table 49 -- TPMI_RH_LOCKOUT from outputType <I>
+typedef TPM_HANDLE TPMI_RH_LOCKOUT;
+
+
+// Table 50 -- TPMI_RH_NV_INDEX from outputType <I/O>
+typedef TPM_HANDLE TPMI_RH_NV_INDEX;
+
+
+// Table 51 -- TPMI_ALG_HASH from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_HASH;
+
+
+// Table 52 -- TPMI_ALG_ASYM from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_ASYM;
+
+
+// Table 53 -- TPMI_ALG_SYM from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_SYM;
+
+
+// Table 54 -- TPMI_ALG_SYM_OBJECT from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_SYM_OBJECT;
+
+
+// Table 55 -- TPMI_ALG_SYM_MODE from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_SYM_MODE;
+
+
+// Table 56 -- TPMI_ALG_KDF from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_KDF;
+
+
+// Table 57 -- TPMI_ALG_SIG_SCHEME from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_SIG_SCHEME;
+
+
+// Table 58 -- TPMI_ST_COMMAND_TAG from outputType <I/O>
+typedef TPM_ST TPMI_ST_COMMAND_TAG;
+
+
+// Table 59 -- TPMS_ALGORITHM_DESCRIPTION from outputStructDef <O,S>
+typedef struct {
+ TPM2_ALG_ID alg;
+ TPMA_ALGORITHM attributes;
+} TPMS_ALGORITHM_DESCRIPTION;
+
+// Table 60 -- TPMU_HA from outputUnionDef <I/O,S>
+typedef union {
+#if SHA1 == YES
+ BYTE sha1[SHA1_DIGEST_SIZE];
+#endif
+#if SHA256 == YES
+ BYTE sha256[SHA256_DIGEST_SIZE];
+#endif
+#if SM3_256 == YES
+ BYTE sm3_256[SM3_256_DIGEST_SIZE];
+#endif
+#if SHA384 == YES
+ BYTE sha384[SHA384_DIGEST_SIZE];
+#endif
+#if SHA512 == YES
+ BYTE sha512[SHA512_DIGEST_SIZE];
+#endif
+#if WHIRLPOOL512 == YES
+ BYTE whirlpool[WHIRLPOOL512_DIGEST_SIZE];
+#endif
+
+} TPMU_HA ;
+
+
+// Table 61 -- TPMT_HA from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ TPMU_HA digest;
+} TPMT_HA;
+
+// Table 62 -- TPMS_HASH_DEF from outputStructDef <O,S>
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ UINT32 digestSize;
+ UINT32 blockSize;
+} TPMS_HASH_DEF;
+
+// Table 63 -- TPM2B_DIGEST from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMU_HA)];
+} TPM2B_DIGEST;
+
+// Table 64 -- TPM2B_DATA from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPMT_HA)];
+} TPM2B_DATA;
+
+// Table 65 -- TPM2B_NONCE from outputTypeDef <I/O>
+typedef TPM2B_DIGEST TPM2B_NONCE;
+
+// Table 66 -- TPM2B_AUTH from outputTypeDef <I/O>
+typedef TPM2B_DIGEST TPM2B_AUTH;
+
+// Table 67 -- TPM2B_OPERAND from outputTypeDef <I/O>
+typedef TPM2B_DIGEST TPM2B_OPERAND;
+
+// Table 68 -- TPM2B_EVENT from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[1024];
+} TPM2B_EVENT;
+
+// Table 69 -- TPM2B_MAX_BUFFER from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_DIGEST_BUFFER];
+} TPM2B_MAX_BUFFER;
+
+// Table 70 -- TPM2B_TIMEOUT from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof(UINT64)];
+} TPM2B_TIMEOUT;
+
+// Table 71 -- TPMU_NAME from outputUnionDef <S>
+typedef union {
+ TPMU_HA digest;
+ TPM_HANDLE handle;
+
+} TPMU_NAME ;
+
+
+// Table 72 -- TPM2B_NAME from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE name[sizeof(TPMU_NAME)];
+} TPM2B_NAME;
+
+// Table 73 -- TPMS_PCR_SELECT from outputStructDef <I/O>
+typedef struct {
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_PCR_SELECT;
+
+// Table 74 -- TPMS_PCR_SELECTION from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH hash;
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_PCR_SELECTION;
+
+// Table 78 -- TPMT_TK_CREATION from outputStructDef <I/O>
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_CREATION;
+
+// Table 79 -- TPMT_TK_VERIFIED from outputStructDef <I/O>
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_VERIFIED;
+
+// Table 80 -- TPMT_TK_AUTH from outputStructDef <I/O>
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_AUTH;
+
+// Table 81 -- TPMT_TK_HASHCHECK from outputStructDef <I/O>
+typedef struct {
+ TPM_ST tag;
+ TPMI_RH_HIERARCHY hierarchy;
+ TPM2B_DIGEST digest;
+} TPMT_TK_HASHCHECK;
+
+// Table 82 -- TPMS_ALG_PROPERTY from outputStructDef <O,S>
+typedef struct {
+ TPM2_ALG_ID alg;
+ TPMA_ALGORITHM algProperties;
+} TPMS_ALG_PROPERTY;
+
+// Table 83 -- TPMS_TAGGED_PROPERTY from outputStructDef <O,S>
+typedef struct {
+ TPM_PT property;
+ UINT32 value;
+} TPMS_TAGGED_PROPERTY;
+
+// Table 84 -- TPMS_TAGGED_PCR_SELECT from outputStructDef <O,S>
+typedef struct {
+ TPM_PT tag;
+ UINT8 sizeofSelect;
+ BYTE pcrSelect[PCR_SELECT_MAX];
+} TPMS_TAGGED_PCR_SELECT;
+
+// Table 85 -- TPML_CC from outputStructDef <I/O>
+typedef struct {
+ UINT32 count;
+ TPM_CC commandCodes[MAX_CAP_CC];
+} TPML_CC;
+
+// Table 86 -- TPML_ALG from outputStructDef <I/O>
+typedef struct {
+ UINT32 count;
+ TPM2_ALG_ID alorithms[MAX_ALG_LIST_SIZE];
+} TPML_ALG;
+
+// Table 87 -- TPML_HANDLE from outputStructDef <O,S>
+typedef struct {
+ UINT32 count;
+ TPM_HANDLE handle[MAX_CAP_HANDLES];
+} TPML_HANDLE;
+
+// Table 88 -- TPML_DIGEST from outputStructDef <I/O>
+typedef struct {
+ UINT32 count;
+ TPM2B_DIGEST digests[8];
+} TPML_DIGEST;
+
+// Table 89 -- TPML_DIGEST_VALUES from outputStructDef <I/O>
+typedef struct {
+ UINT32 count;
+ TPMT_HA digests[HASH_COUNT];
+} TPML_DIGEST_VALUES;
+
+// Table 90 -- TPM2B_DIGEST_VALUES from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE buffer[sizeof(TPML_DIGEST_VALUES)];
+} TPM2B_DIGEST_VALUES;
+
+// Table 91 -- TPML_PCR_SELECTION from outputStructDef <I/O>
+typedef struct {
+ UINT32 count;
+ TPMS_PCR_SELECTION pcrSelections[HASH_COUNT];
+} TPML_PCR_SELECTION;
+
+// Table 92 -- TPML_ALG_PROPERTY from outputStructDef <O,S>
+typedef struct {
+ UINT32 count;
+ TPMS_ALG_PROPERTY algProperties[MAX_CAP_ALGS];
+} TPML_ALG_PROPERTY;
+
+// Table 93 -- TPML_TAGGED_TPM_PROPERTY from outputStructDef <O,S>
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_PROPERTY pcrProperty[MAX_TPM_PROPERTIES];
+} TPML_TAGGED_TPM_PROPERTY;
+
+// Table 94 -- TPML_TAGGED_PCR_PROPERTY from outputStructDef <O,S>
+typedef struct {
+ UINT32 count;
+ TPMS_TAGGED_PCR_SELECT pcrProperty[MAX_PCR_PROPERTIES];
+} TPML_TAGGED_PCR_PROPERTY;
+
+// Table 95 -- ECCCurve from outputTypeDef <I/O>
+#if ECC == YES
+typedef UINT16 TPM_ECC_CURVE_ID;
+#endif
+
+// Table 96 -- TPML_ECC_CURVE from outputStructDef <O,S>
+#if ECC == YES
+typedef struct {
+ UINT32 count;
+ TPM_ECC_CURVE_ID eccCurves[MAX_ECC_CURVES];
+} TPML_ECC_CURVE;
+#endif
+
+// Table 97 -- TPMU_CAPABILITIES from outputUnionDef <O,S>
+typedef union {
+ TPML_ALG_PROPERTY algorithms;
+ TPML_HANDLE handles;
+ TPML_CC command;
+ TPML_CC ppCommands;
+ TPML_CC auditCommands;
+ TPML_PCR_SELECTION assignedPCR;
+ TPML_TAGGED_TPM_PROPERTY tpmProperties;
+ TPML_TAGGED_PCR_PROPERTY pcrProperties;
+ TPML_ECC_CURVE eccCurves;
+
+} TPMU_CAPABILITIES ;
+
+
+// Table 98 -- TPMS_CAPABILITY_DATA from outputStructDef <O,S>
+typedef struct {
+ TPM_CAP capability;
+ TPMU_CAPABILITIES data;
+} TPMS_CAPABILITY_DATA;
+
+// Table 99 -- TPMS_CLOCK_INFO from outputStructDef <I/O>
+typedef struct {
+ UINT64 clock;
+ TPMI_YES_NO safe;
+ UINT32 resetCount;
+ UINT32 restartCount;
+} TPMS_CLOCK_INFO;
+
+// Table 100 -- TPMS_TIME_INFO from outputStructDef <I/O>
+typedef struct {
+ UINT64 time;
+ TPMS_CLOCK_INFO clockInfo;
+} TPMS_TIME_INFO;
+
+// Table 101 -- TPMS_TIME_ATTEST_INFO from outputStructDef <O,S>
+typedef struct {
+ TPMS_TIME_INFO time;
+ UINT64 firmwareVersion;
+} TPMS_TIME_ATTEST_INFO;
+
+// Table 102 -- TPMS_CERTIFY_INFO from outputStructDef <O,S>
+typedef struct {
+ TPM2B_NAME name;
+ TPM2B_NAME qualifiedName;
+} TPMS_CERTIFY_INFO;
+
+// Table 103 -- TPMS_QUOTE_INFO from outputStructDef <O,S>
+typedef struct {
+ TPML_PCR_SELECTION pcrSelect;
+ TPM2B_DIGEST pcrDigest;
+} TPMS_QUOTE_INFO;
+
+// Table 104 -- TPMS_COMMAND_AUDIT_INFO from outputStructDef <O,S>
+typedef struct {
+ UINT32 auditCounter;
+ TPM2_ALG_ID digestAlg;
+ TPM2B_DIGEST auditDigest;
+ TPM2B_DIGEST commandDigest;
+} TPMS_COMMAND_AUDIT_INFO;
+
+// Table 105 -- TPMS_SESSION_AUDIT_INFO from outputStructDef <O,S>
+typedef struct {
+ UINT8 exclusiveSesstion;
+ TPM2B_DIGEST sessionDigest;
+} TPMS_SESSION_AUDIT_INFO;
+
+// Table 106 -- TPMS_CREATION_INFO from outputStructDef <O,S>
+typedef struct {
+ TPM2B_NAME objectName;
+} TPMS_CREATION_INFO;
+
+// Table 107 -- TPMS_NV_CERTIFY_INFO from outputStructDef <O,S>
+typedef struct {
+ TPM2B_MAX_BUFFER nvContents;
+} TPMS_NV_CERTIFY_INFO;
+
+// Table 108 -- TPMI_ST_ATTEST from outputType <O,S>
+typedef TPM_ST TPMI_ST_ATTEST;
+
+
+// Table 109 -- TPMU_ATTEST from outputUnionDef <O,S>
+typedef union {
+ TPMS_CERTIFY_INFO certify;
+ TPMS_CREATION_INFO creation;
+ TPMS_QUOTE_INFO quote;
+ TPMS_COMMAND_AUDIT_INFO commandAudit;
+ TPMS_SESSION_AUDIT_INFO sessionAudit;
+ TPMS_TIME_ATTEST_INFO time;
+ TPMS_NV_CERTIFY_INFO nv;
+
+} TPMU_ATTEST ;
+
+
+// Table 110 -- TPMS_ATTEST from outputStructDef <O,S>
+typedef struct {
+ TPM_GENERATED magic;
+ TPMI_ST_ATTEST type;
+ TPM2B_NAME qualifiedSigner;
+ TPM2B_DATA extraData;
+ TPMS_CLOCK_INFO clockInfo;
+ UINT64 firmwareVersion;
+ TPMU_ATTEST attested;
+} TPMS_ATTEST;
+
+// Table 111 -- TPM2B_ATTEST from outputStructDef <O,S>
+typedef struct {
+ UINT16 size;
+ TPMS_ATTEST attestationData;
+} TPM2B_ATTEST;
+
+// Table 112 -- TPMS_AUTH_SESSION_COMMAND from outputStructDef <I>
+typedef struct {
+ TPMI_SH_AUTH_SESSION sessionHandle;
+ TPM2B_NONCE nonce;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_AUTH auth;
+} TPMS_AUTH_SESSION_COMMAND;
+
+// Table 113 -- TPMS_AUTH_SESSION_RESPONSE from outputStructDef <I/O>
+typedef struct {
+ TPM2B_NONCE nonce;
+ TPMA_SESSION sessionAttributes;
+ TPM2B_AUTH auth;
+} TPMS_AUTH_SESSION_RESPONSE;
+
+// Table 114 -- TPMS_AUTH_COMPUTE_NOT_BOUND from outputStructDef <S>
+typedef struct {
+ TPM2B_AUTH sessionKey;
+ TPM2B_AUTH authValue;
+ TPM2B_DIGEST pHash;
+ TPM2B_NONCE nonceNewer;
+ TPM2B_NONCE nonceOlder;
+ TPMA_SESSION sessionFlags;
+} TPMS_AUTH_COMPUTE_NOT_BOUND;
+
+// Table 115 -- TPMS_AUTH_COMPUTE_BOUND from outputStructDef <S>
+typedef struct {
+ TPM2B_DIGEST sessionKey;
+ TPM2B_DIGEST pHash;
+ TPM2B_NONCE nonceNewer;
+ TPM2B_NONCE nonceOlder;
+ TPMA_SESSION sessionFlags;
+} TPMS_AUTH_COMPUTE_BOUND;
+
+// Table 116 -- TPMS_XOR_PARMS from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH hash;
+} TPMS_XOR_PARMS;
+
+// Table 117 -- TPMS_AES_PARMS from outputStructDef <I/O>
+#if AES == YES
+typedef struct {
+ TPM_KEY_BITS keyBits;
+ TPMI_ALG_SYM_MODE mode;
+} TPMS_AES_PARMS;
+#endif
+
+// Table 118 -- TPMS_SMS4_PARMS from outputStructDef <I/O>
+#if SMS4 == YES
+typedef struct {
+ TPM_KEY_BITS keyBits;
+ TPMI_ALG_SYM_MODE mode;
+} TPMS_SMS4_PARMS;
+#endif
+
+// Table 119 -- TPMS_KEYEDHASH_PARMS from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH sign;
+ TPMI_ALG_KDF encrypt;
+} TPMS_KEYEDHASH_PARMS;
+
+// Table 120 -- TPMU_SYM_DEF from outputUnionDef <I/O>
+typedef union {
+#if AES == YES
+ TPMS_AES_PARMS aes;
+#endif
+#if SMS4 == YES
+ TPMS_SMS4_PARMS sms4;
+#endif
+#if XOR == YES
+ TPMS_XOR_PARMS xor;
+#endif
+
+} TPMU_SYM_DEF ;
+
+
+// Table 121 -- TPMT_SYM_DEF from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_SYM algorithm;
+ TPMU_SYM_DEF details;
+} TPMT_SYM_DEF;
+
+// Table 122 -- TPMT_SYM_DEF_OBJECT from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_SYM_OBJECT algorithm;
+ TPMU_SYM_DEF details;
+} TPMT_SYM_DEF_OBJECT;
+
+// Table 123 -- TPM2B_SYM_KEY from outputStructDef <I/O>
+typedef struct {
+ UINT16 keySize;
+ BYTE key[MAX_SYM_DATA];
+} TPM2B_SYM_KEY;
+
+// Table 124 -- TPMS_SENSITIVE_CREATE from outputStructDef <I>
+typedef struct {
+ TPM2B_AUTH userAuth;
+ TPM2B_SYM_KEY data;
+} TPMS_SENSITIVE_CREATE;
+
+// Table 125 -- TPM2B_SENSITIVE_CREATE from outputStructDef <I,S>
+typedef struct {
+ UINT16 size;
+ TPMS_SENSITIVE_CREATE sensitive;
+} TPM2B_SENSITIVE_CREATE;
+
+// Table 126 -- TPMS_SCHEME_PKCS1v1_5 from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_PKCS1v1_5;
+#endif
+
+// Table 127 -- TPMS_SCHEME_PSS from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+ UINT16 saltSize;
+} TPMS_SCHEME_PSS;
+#endif
+
+// Table 128 -- TPMS_SCHEME_ECDSA from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_ECDSA;
+#endif
+
+// Table 129 -- TPMS_SCHEME_ECDAA from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_ECDAA;
+#endif
+
+// Table 130 -- TPMS_SCHEME_HMAC from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_HMAC;
+#endif
+
+// Table 131 -- TPMU_SIG_SCHEME from outputUnionDef <I/O,S>
+typedef union {
+#if RSASSA_PKCS1v1_5 == YES
+ TPMS_SCHEME_PKCS1v1_5 pkcs1v1_5;
+#endif
+#if PSS == YES
+ TPMS_SCHEME_PSS pkcspss;
+#endif
+#if ECDSA == YES
+ TPMS_SCHEME_ECDSA ecdsa;
+#endif
+#if ECDAA == YES
+ TPMS_SCHEME_ECDAA ecdaa;
+#endif
+#if HMAC == YES
+ TPMS_SCHEME_HMAC hmac;
+#endif
+
+} TPMU_SIG_SCHEME ;
+
+
+// Table 132 -- TPMT_SIG_SCHEME from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_SIG_SCHEME scheme;
+ TPMU_SIG_SCHEME details;
+} TPMT_SIG_SCHEME;
+
+// Table 133 -- TPMS_SCHEME_MGF1 from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_MGF1;
+
+// Table 134 -- TPMS_SCHEME_KDF1_SP800_56a from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_KDF1_SP800_56a;
+#endif
+
+// Table 135 -- TPMS_SCHEME_KDF2 from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_KDF2;
+
+// Table 136 -- TPMS_SCHEME_KDF1_SP800_108 from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_HASH hashAlg;
+} TPMS_SCHEME_KDF1_SP800_108;
+
+// Table 137 -- TPMU_KDF_SCHEME from outputUnionDef <I/O,S>
+typedef union {
+#if MGF1 == YES
+ TPMS_SCHEME_MGF1 mgf1;
+#endif
+#if KDF1_SP800_56a == YES
+ TPMS_SCHEME_KDF1_SP800_56a kdf1_SP800_56a;
+#endif
+#if KDF2 == YES
+ TPMS_SCHEME_KDF2 kdf2;
+#endif
+#if KDF1_SP800_108 == YES
+ TPMS_SCHEME_KDF1_SP800_108 kdf1_sp800_108;
+#endif
+
+} TPMU_KDF_SCHEME ;
+
+
+// Table 138 -- TPMT_KDF_SCHEME from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_KDF scheme;
+ TPMU_KDF_SCHEME details;
+} TPMT_KDF_SCHEME;
+
+// Table 139 -- TPMI_ALG_RSA_SIG_SCHEME from outputType <I/O>
+#if RSA == YES
+typedef TPM2_ALG_ID TPMI_ALG_RSA_SIG_SCHEME;
+
+#endif
+
+// Table 140 -- TPMT_RSA_SIG_SCHEME from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ TPMI_ALG_RSA_SIG_SCHEME scheme;
+ TPMU_SIG_SCHEME details;
+} TPMT_RSA_SIG_SCHEME;
+#endif
+
+// Table 141 -- TPMS_RSA_PARMS from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ TPM_KEY_BITS keyBits;
+ UINT32 exponent;
+ TPMT_RSA_SIG_SCHEME sign;
+ TPMT_SYM_DEF_OBJECT symmetric;
+} TPMS_RSA_PARMS;
+#endif
+
+// Table 142 -- TPM2B_RSA_PUBLIC_KEY from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_RSA_KEY_BYTES];
+} TPM2B_RSA_PUBLIC_KEY;
+#endif
+
+// Table 143 -- TPM2B_RSA_PRIVATE_KEY from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ UINT16 size;
+ BYTE buffer[MAX_RSA_KEY_BYTES/2];
+} TPM2B_RSA_PRIVATE_KEY;
+#endif
+
+// Table 144 -- TPM_ECC_CURVE from outputConstDef <I/O>
+#if ECC == YES
+typedef TPM_ECC_CURVE_ID TPM_ECC_CURVE;
+
+#define TPM_ECC_NIST_P256 (TPM_ECC_CURVE)(0x0000)
+#define TPM_ECC_NIST_P384 (TPM_ECC_CURVE)(0x0001)
+#define TPM_ECC_NIST_P521 (TPM_ECC_CURVE)(0x0002)
+
+
+
+#endif
+
+// Table 145 -- TPM2B_ECC_PARAMETER from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ UINT16 size;
+ BYTE value[MAX_ECC_KEY];
+} TPM2B_ECC_PARAMETER;
+#endif
+
+// Table 146 -- TPMS_ECC_POINT from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPM2B_ECC_PARAMETER pointX;
+ TPM2B_ECC_PARAMETER pointY;
+} TPMS_ECC_POINT;
+#endif
+
+// Table 147 -- TPM2B_ECC_POINT from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ UINT16 size;
+ TPMS_ECC_POINT point;
+} TPM2B_ECC_POINT;
+#endif
+
+// Table 148 -- TPMI_ALG_ECC_SIG_SCHEME from outputType <I/O>
+#if ECC == YES
+typedef TPM2_ALG_ID TPMI_ALG_ECC_SIG_SCHEME;
+
+#endif
+
+// Table 149 -- TPMT_ECC_SIG_SCHEME from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPMI_ALG_ECC_SIG_SCHEME scheme;
+ TPMU_SIG_SCHEME details;
+} TPMT_ECC_SIG_SCHEME;
+#endif
+
+// Table 150 -- TPMS_ECC_PARMS from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPM_ECC_CURVE curveID;
+ TPMT_ECC_SIG_SCHEME sign;
+ TPMT_SYM_DEF_OBJECT symmetric;
+ TPMT_KDF_SCHEME kdf;
+} TPMS_ECC_PARMS;
+#endif
+
+// Table 151 -- TPMS_ALGORITHM_DETAIL_ECC from outputStructDef <O,S>
+typedef struct {
+ TPM_ECC_CURVE_ID curveID;
+ UINT16 keySize;
+ TPMT_KDF_SCHEME kdf;
+ TPMT_ECC_SIG_SCHEME sign;
+ TPM2B_ECC_PARAMETER p;
+ TPM2B_ECC_PARAMETER a;
+ TPM2B_ECC_PARAMETER b;
+ TPM2B_ECC_PARAMETER gX;
+ TPM2B_ECC_PARAMETER gY;
+ TPM2B_ECC_PARAMETER n;
+ TPM2B_ECC_PARAMETER h;
+} TPMS_ALGORITHM_DETAIL_ECC;
+
+// Table 152 -- TPMS_SIGNATURE_PKCS1v1_5 from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_RSA_PUBLIC_KEY sig;
+} TPMS_SIGNATURE_PKCS1v1_5;
+#endif
+
+// Table 153 -- TPMS_SIGNATURE_PSS from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_RSA_PUBLIC_KEY sig;
+ UINT16 saltSize;
+} TPMS_SIGNATURE_PSS;
+#endif
+
+// Table 154 -- TPMS_SIGNATURE_ECDSA from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPMI_ALG_HASH hash;
+ TPM2B_ECC_PARAMETER signatureR;
+ TPM2B_ECC_PARAMETER signatureS;
+} TPMS_SIGNATURE_ECDSA;
+#endif
+
+// Table 155 -- TPMU_SIGNATURE from outputUnionDef <I/O,S>
+typedef union {
+#if RSASSA_PKCS1v1_5 == YES
+ TPMS_SIGNATURE_PKCS1v1_5 pkcs1v1_5;
+#endif
+#if PSS == YES
+ TPMS_SIGNATURE_PSS pkcspss;
+#endif
+#if ECDSA == YES
+ TPMS_SIGNATURE_ECDSA ecdsa;
+#endif
+#if HMAC == YES
+ TPMT_HA hmac;
+#endif
+
+} TPMU_SIGNATURE ;
+
+
+// Table 156 -- TPMT_SIGNATURE from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_SIG_SCHEME sigAlg;
+ TPMU_SIGNATURE digest;
+} TPMT_SIGNATURE;
+
+// Table 157 -- TPMU_ENCRYPTED_SECRET from outputUnionDef <S>
+typedef union {
+#if ECC == YES
+ BYTE ecc[sizeof(TPMS_ECC_POINT)];
+#endif
+#if RSA == YES
+ BYTE rsa[MAX_RSA_KEY_BYTES];
+#endif
+#if AES == YES
+ BYTE aes[sizeof(TPM2B_DIGEST)];
+#endif
+#if SMS4 == YES
+ BYTE sms4[sizeof(TPM2B_DIGEST)];
+#endif
+#if KEYEDHASH == YES
+ BYTE keyedHash[sizeof(TPM2B_DIGEST)];
+#endif
+
+} TPMU_ENCRYPTED_SECRET ;
+
+
+// Table 158 -- TPM2B_ENCRYPTED_SECRET from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE secret[sizeof(TPMU_ENCRYPTED_SECRET)];
+} TPM2B_ENCRYPTED_SECRET;
+
+// Table 159 -- TPMI_ALG_PUBLIC from outputType <I/O>
+typedef TPM2_ALG_ID TPMI_ALG_PUBLIC;
+
+
+// Table 160 -- TPMS_PUBLIC_ID_SYM from outputStructDef <I/O>
+typedef struct {
+ TPM2B_DIGEST unique;
+} TPMS_PUBLIC_ID_SYM;
+
+// Table 161 -- PublicIDStructures from outputTypeDef <I/O>
+typedef TPMS_PUBLIC_ID_SYM TPMS_PUBLIC_ID_AES;
+typedef TPMS_PUBLIC_ID_SYM TPMS_PUBLIC_ID_SMS4;
+typedef TPMS_PUBLIC_ID_SYM TPMS_PUBLIC_ID_KEYEDHASH;
+
+// Table 162 -- TPM2B_PUBLIC_ID_RSA from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ UINT16 keySize;
+ BYTE key[MAX_RSA_KEY_BYTES];
+} TPM2B_PUBLIC_ID_RSA;
+#endif
+
+// Table 163 -- TPMS_PUBLIC_ID_ECC from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPM2B_ECC_PARAMETER qX;
+ TPM2B_ECC_PARAMETER qY;
+} TPMS_PUBLIC_ID_ECC;
+#endif
+
+// Table 164 -- TPMU_PUBLIC_PARMS from outputUnionDef <I/O,S>
+typedef union {
+#if RSA == YES
+ TPMS_RSA_PARMS rsaDetail;
+#endif
+#if ECC == YES
+ TPMS_ECC_PARMS eccDetail;
+#endif
+#if KEYEDHASH == YES
+ TPMS_KEYEDHASH_PARMS keyedHash;
+#endif
+#if AES == YES
+ TPMS_AES_PARMS aesDetail;
+#endif
+#if SMS4 == YES
+ TPMS_SMS4_PARMS sms4Detail;
+#endif
+
+} TPMU_PUBLIC_PARMS ;
+
+
+// Table 165 -- TPMU_PUBLIC_ID from outputUnionDef <I/O,S>
+typedef union {
+#if AES == YES
+ TPMS_PUBLIC_ID_AES aes;
+#endif
+#if SMS4 == YES
+ TPMS_PUBLIC_ID_SMS4 sms4;
+#endif
+#if KEYEDHASH == YES
+ TPMS_PUBLIC_ID_KEYEDHASH keyedHash;
+#endif
+#if RSA == YES
+ TPM2B_PUBLIC_ID_RSA rsa;
+#endif
+#if ECC == YES
+ TPMS_PUBLIC_ID_ECC ecc;
+#endif
+
+} TPMU_PUBLIC_ID ;
+
+
+// Table 166 -- TPMT_PUBLIC_PARMS from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMU_PUBLIC_PARMS parameters;
+} TPMT_PUBLIC_PARMS;
+
+// Table 167 -- TPMT_PUBLIC from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_PUBLIC type;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_OBJECT objectAttributes;
+ TPM2B_DIGEST authPolicy;
+ TPMU_PUBLIC_PARMS parameters;
+ TPMU_PUBLIC_ID unique;
+} TPMT_PUBLIC;
+
+// Table 168 -- TPM2B_PUBLIC from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ TPMT_PUBLIC publicArea;
+} TPM2B_PUBLIC;
+
+// Table 169 -- TPMS_SENSITIVE_SYM from outputStructDef <I/O>
+typedef struct {
+ TPM2B_DIGEST obfuscate;
+ TPM2B_SYM_KEY symKey;
+} TPMS_SENSITIVE_SYM;
+
+// Table 170 -- PrivateSymmetricStructures from outputTypeDef <I/O>
+typedef TPMS_SENSITIVE_SYM TPMS_SENSITIVE_AES;
+typedef TPMS_SENSITIVE_SYM TPMS_SENSITIVE_SMS4;
+typedef TPMS_SENSITIVE_SYM TPMS_SENSITIVE_KEYEDHASH;
+
+// Table 171 -- TPMS_SENSITIVE_RSA from outputStructDef <I/O>
+#if RSA == YES
+typedef struct {
+ UINT16 keySize;
+ BYTE key[(MAX_RSA_KEY_BYTES+1)/2];
+ TPM2B_SYM_KEY symKey;
+} TPMS_SENSITIVE_RSA;
+#endif
+
+// Table 172 -- TPMS_SENSITIVE_ECC from outputStructDef <I/O>
+#if ECC == YES
+typedef struct {
+ TPM2B_ECC_PARAMETER key;
+ TPM2B_SYM_KEY symKey;
+} TPMS_SENSITIVE_ECC;
+#endif
+
+// Table 173 -- TPMU_SENSITIVE_COMPOSITE from outputUnionDef <I/O,S>
+typedef union {
+#if RSA == YES
+ TPMS_SENSITIVE_RSA rsaDetail;
+#endif
+#if ECC == YES
+ TPMS_SENSITIVE_ECC eccDetail;
+#endif
+#if KEYEDHASH == YES
+ TPMS_SENSITIVE_SYM bitsDetail;
+#endif
+#if AES == YES
+ TPMS_SENSITIVE_SYM aesDetail;
+#endif
+#if SMS4 == YES
+ TPMS_SENSITIVE_SYM sms4Detail;
+#endif
+
+} TPMU_SENSITIVE_COMPOSITE ;
+
+
+// Table 174 -- TPMT_SENSITIVE from outputStructDef <I/O>
+typedef struct {
+ TPMI_ALG_PUBLIC sensitiveType;
+ TPM2B_AUTH authValue;
+ TPMU_SENSITIVE_COMPOSITE sensitive;
+} TPMT_SENSITIVE;
+
+// Table 175 -- TPM2B_SENSITIVE from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ TPMT_SENSITIVE sensitiveArea;
+} TPM2B_SENSITIVE;
+
+// Table 176 -- TPMS_ENCRYPT from outputStructDef <I/O,S>
+typedef struct {
+ TPM2B_DIGEST integrity;
+ TPMT_SENSITIVE sensitive;
+} TPMS_ENCRYPT;
+
+// Table 177 -- TPM2B_PRIVATE from outputStructDef <I/O,S>
+typedef struct {
+ UINT16 size;
+ BYTE data[sizeof(TPMS_ENCRYPT)];
+} TPM2B_PRIVATE;
+
+// Table 178 -- TPMS_ID_OBJECT from outputStructDef <I/O,S>
+typedef struct {
+ TPM2B_DIGEST integrity;
+ TPM2B_DIGEST protector;
+} TPMS_ID_OBJECT;
+
+// Table 179 -- TPM2B_ID_OBJECT from outputStructDef <I/O,S>
+typedef struct {
+ UINT16 size;
+ BYTE credential[sizeof(TPMS_ID_OBJECT)];
+} TPM2B_ID_OBJECT;
+
+// Table 180 -- TPM_NV_INDEX from outputBitDef <S>
+typedef struct {
+ unsigned int index : 21;
+ unsigned int space : 3;
+ unsigned int RH_NV : 8;
+} TPM2_NV_INDEX ;
+
+// Table 182 -- TPMA_NV from outputBitDef <I/O>
+typedef struct {
+ unsigned int TPMA_NV_PPWRITE : 1;
+ unsigned int TPMA_NV_OWNERWRITE : 1;
+ unsigned int TPMA_NV_AUTHWRITE : 1;
+ unsigned int TPMA_NV_POLICYWRITE : 1;
+ unsigned int TPMA_NV_COUNTER : 1;
+ unsigned int TPMA_NV_BITS : 1;
+ unsigned int TPMA_NV_EXTEND : 1;
+ unsigned int reserved8 : 4;
+ unsigned int TPMA_NV_WRITELOCKED : 1;
+ unsigned int TPMA_NV_WRITEALL : 1;
+ unsigned int TPMA_NV_WRITEDEFINE : 1;
+ unsigned int TPMA_NV_WRITE_STCLEAR : 1;
+ unsigned int TPMA_NV_GLOBALLOCK : 1;
+ unsigned int TPMA_NV_PPREAD : 1;
+ unsigned int TPMA_NV_OWNERREAD : 1;
+ unsigned int TPMA_NV_AUTHREAD : 1;
+ unsigned int TPMA_NV_POLICYREAD : 1;
+ unsigned int reserved18 : 5;
+ unsigned int TPMA_NV_NO_DA : 1;
+ unsigned int TPMA_NV_ORDERLY : 1;
+ unsigned int TPMA_NV_CLEAR_STCLEAR : 1;
+ unsigned int TPMA_NV_READLOCKED : 1;
+ unsigned int TPMA_NV_WRITTEN : 1;
+ unsigned int TPMA_NV_PLATFORMCREATE : 1;
+ unsigned int TPMA_NV_READ_STCLEAR : 1;
+} TPMA_NV ;
+
+// Table 183 -- TPMS_NV_PUBLIC from outputStructDef <I/O>
+typedef struct {
+ TPMI_RH_NV_INDEX nvIndex;
+ TPMI_ALG_HASH nameAlg;
+ TPMA_NV attributes;
+ TPM2B_DIGEST authPolicy;
+ UINT16 dataSize;
+} TPMS_NV_PUBLIC;
+
+// Table 184 -- TPM2B_NV_PUBLIC from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ TPMS_NV_PUBLIC nvPublic;
+} TPM2B_NV_PUBLIC;
+
+// Table 185 -- TPM2B_CONTEXT from outputStructDef <I/O>
+typedef struct {
+ UINT16 size;
+ BYTE contextData[MAX_CONTEXT_SIZE];
+} TPM2B_CONTEXT;
+
+// Table 186 -- TPMS_CONTEXT from outputStructDef <I/O>
+typedef struct {
+ UINT32 sequence;
+ TPMI_DH_CONTEXT savedHandle;
+ TPM2B_CONTEXT contextBlob;
+} TPMS_CONTEXT;
+
+// Table 187 -- TPMS_CREATION_DATA from outputStructDef <O,S>
+typedef struct {
+ TPML_PCR_SELECTION pcrSelect;
+ TPM2B_DIGEST pcrDigest;
+ TPMA_LOCALITY locality;
+ TPM2_ALG_ID parentNameAlg;
+ TPM2B_NAME parentName;
+ TPM2B_NAME parentQualifiedName;
+ TPM2B_DATA outsideInfo;
+} TPMS_CREATION_DATA;
+
+// Table 188 -- TPM2B_CREATION_DATA from outputStructDef <O,S>
+typedef struct {
+ UINT16 size;
+ TPMS_CREATION_DATA creationData;
+} TPM2B_CREATION_DATA;
+
+#pragma pack (pop)
+#endif
diff --git a/Core/EM/TCG2/Common/Tpm20Includes/Tpm20Includes.cif b/Core/EM/TCG2/Common/Tpm20Includes/Tpm20Includes.cif
new file mode 100644
index 0000000..55d6848
--- /dev/null
+++ b/Core/EM/TCG2/Common/Tpm20Includes/Tpm20Includes.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "Tpm20Includes"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Common\Tpm20Includes"
+ RefName = "Tpm20Includes"
+[files]
+"Tpm20.h"
+"Tpm20Pei.h"
+"TrEEProtocol.h"
+<endComponent>
diff --git a/Core/EM/TCG2/Common/Tpm20Includes/Tpm20Pei.h b/Core/EM/TCG2/Common/Tpm20Includes/Tpm20Pei.h
new file mode 100644
index 0000000..f372b45
--- /dev/null
+++ b/Core/EM/TCG2/Common/Tpm20Includes/Tpm20Pei.h
@@ -0,0 +1,32 @@
+#ifndef TPM_2_0_PEI_H
+#define TPM_2_0_PEI_H
+
+#include <Tpm20Includes\Tpm20.h>
+
+#pragma pack(push, 1)
+
+typedef struct _TPM2_Startup{
+ TPMI_ST_COMMAND_TAG tag;
+ UINT32 CommandSize;
+ TPM_CC CommandCode;
+ TPM_SU StartupType;
+}TPM2_Startup_Cmd;
+
+typedef struct _TPM2_SelfTest{
+ TPMI_ST_COMMAND_TAG tag;
+ UINT32 CommandSize;
+ TPM_CC CommandCode;
+ TPMI_YES_NO SelfTestType;
+}TPM2_SelfTest;
+
+typedef struct _TPM2_Startup_Resp{
+ TPM_ST tag;
+ UINT32 ResponsSize;
+ TPM_RC ResponseCode;
+}TPM2_Common_RespHdr;
+
+#pragma pack(pop)
+
+EFI_STATUS Tpm20PeiSendStartup(IN EFI_PEI_SERVICES **PeiServices);
+EFI_STATUS Tpm20PeiSelfTest();
+#endif \ No newline at end of file
diff --git a/Core/EM/TCG2/Common/Tpm20Includes/TrEEProtocol.h b/Core/EM/TCG2/Common/Tpm20Includes/TrEEProtocol.h
new file mode 100644
index 0000000..c94df74
--- /dev/null
+++ b/Core/EM/TCG2/Common/Tpm20Includes/TrEEProtocol.h
@@ -0,0 +1,152 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+#ifndef TREE_PROTOCOL_H
+
+#define TREE_PROTOCOL_H
+
+#define EFI_TREE_SERVICE_BINDING_PROTOCOL_GUID \
+{0x4cf01d0a, 0xc48c, 0x4271, 0xa2, 0x2a, 0xad, 0x8e, 0x55, 0x97,\
+ 0x81, 0x88}
+
+#define EFI_TREE_PROTOCOL_GUID \
+{0x607f766c, 0x7455, 0x42be, 0x93, 0x0b, 0xe4, 0xd7, 0x6d, 0xb2,\
+ 0x72, 0x0f}
+
+typedef struct _EFI_TREE_PROTOCOL EFI_TREE_PROTOCOL;
+
+//#pragma pack(push,1) // Byte align structures
+
+typedef struct _TREE_VERSION {
+ UINT8 Major;
+ UINT8 Minor;
+} TREE_VERSION;
+
+typedef UINT32 TREE_EVENT_LOG_BITMAP;
+typedef UINT32 TREE_EVENT_LOG_FORMAT;
+#define TREE_EVENT_LOG_FORMAT_TCG_1_2 0x00000001
+
+#define TREE_STRUCTURE_VERSION_MAJOR (1)
+#define TREE_STRUCTURE_VERSION_MINOR (0)
+
+#define TREE_PROTOCOL_VERSION_MAJOR (1)
+#define TREE_PROTOCOL_VERSION_MINOR (0)
+
+typedef struct _TREE_BOOT_SERVICE_CAPABILITY {
+ UINT8 Size;
+ TREE_VERSION StructureVersion;
+ TREE_VERSION ProtocolVersion;
+ UINT32 HashAlgorithmBitmap;
+ TREE_EVENT_LOG_BITMAP SupportedEventLogs;
+ BOOLEAN TrEEPresentFlag;
+ UINT16 MaxCommandSize;
+ UINT16 MaxResponseSize;
+ UINT32 ManufacturerID;
+} TREE_BOOT_SERVICE_CAPABILITY;
+
+#define TREE_BOOT_HASH_ALG_SHA1 0x00000001
+#define TREE_BOOT_HASH_ALG_SHA256 0x00000002
+#define TREE_BOOT_HASH_ALG_SHA384 0x00000004
+#define TREE_BOOT_HASH_ALG_SHA512 0x00000008
+
+#define TREE_EXTEND_ONLY 0x0000000000000001
+#define PE_COFF_IMAGE 0x0000000000000010
+
+//#define EV_EFI_VARIABLE_DRIVER_CONFIG 0x80000001
+//#define EV_EFI_VARIABLE_AUTHORITY 0x800000E0
+typedef UINT32 TCG_EVENTTYPE;
+typedef UINT32 TCG_PCRINDEX;
+
+#pragma pack(push, 1) // Byte align structures
+
+typedef UINT32 TrEE_PCRINDEX;
+typedef UINT32 TrEE_EVENTTYPE;
+typedef UINT32 TREE_EVENTLOGTYPE;
+
+typedef struct _TrEE_EVENT_HEADER {
+ UINT32 HeaderSize;
+ UINT16 HeaderVersion;
+ TrEE_PCRINDEX PCRIndex;
+ TrEE_EVENTTYPE EventType;
+} TrEE_EVENT_HEADER;
+
+typedef struct _TrEE_EVENT {
+ UINT32 Size;
+ TrEE_EVENT_HEADER Header;
+ UINT8 Event[1];
+} TrEE_EVENT;
+
+#pragma pack(pop) // Byte align structures
+
+#define SIZE_OF_TrEE_EVENT OFFSET_OF (TrEE_EVENT, Event)
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TREE_GET_CAPABILITY) (
+ IN EFI_TREE_PROTOCOL *This,
+ IN OUT TREE_BOOT_SERVICE_CAPABILITY *ProtocolCapability
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TREE_GET_EVENT_LOG) (
+ IN EFI_TREE_PROTOCOL *This,
+ IN TREE_EVENTLOGTYPE EventLogFormat,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLocation,
+ OUT EFI_PHYSICAL_ADDRESS *EventLogLastEntry,
+ OUT BOOLEAN *EventLogTruncated
+);
+
+typedef
+EFI_STATUS
+(EFIAPI * EFI_TREE_HASH_LOG_EXTEND_EVENT) (
+ IN EFI_TREE_PROTOCOL *This,
+ IN UINT64 Flags,
+ IN EFI_PHYSICAL_ADDRESS DataToHash,
+ IN UINT64 DataToHashLen,
+ IN TrEE_EVENT *Event
+);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TREE_SUBMIT_COMMAND) (
+ IN EFI_TREE_PROTOCOL *This,
+ IN UINT32 InputParameterBlockSize,
+ IN UINT8 *InputParameterBlock,
+ IN UINT32 OutputParameterBlockSize,
+ IN UINT8 *OutputParameterBlock
+);
+
+struct _EFI_TREE_PROTOCOL {
+ EFI_TREE_GET_CAPABILITY GetCapability;
+ EFI_TREE_GET_EVENT_LOG GetEventLog;
+ EFI_TREE_HASH_LOG_EXTEND_EVENT HashLogExtendEvent;
+ EFI_TREE_SUBMIT_COMMAND SubmitCommand;
+};
+
+#endif //TREE_PROTOCOL_H
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/Common/TpmDxe.c b/Core/EM/TCG2/Common/TpmDxe.c
new file mode 100644
index 0000000..662e91a
--- /dev/null
+++ b/Core/EM/TCG2/Common/TpmDxe.c
@@ -0,0 +1,545 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TpmDxe.h
+
+ Abstract:
+
+ DXE driver for TPM devices
+
+ --*/
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TpmDxe.c 2 4/21/14 3:17p Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 4/21/14 3:17p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/TpmDxe.c $
+//
+// 2 4/21/14 3:17p Fredericko
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 2 3/11/14 6:35p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 2:00p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 13 11/14/11 1:27p Fredericko
+// Changes for Tcgprotocol interface. Function is currently not used.
+//
+// 12 3/31/11 4:57p Fredericko
+// Changes for TCG_LEGACY support
+//
+// 11 3/29/11 1:12p Fredericko
+//
+// 10 3/28/11 2:19p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 9 5/19/10 5:31p Fredericko
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmDxe.c
+//
+// Description:
+// Abstracted functions for Tpm protocol are defined here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TcgTpm12.h"
+#include <TpmLib.h>
+#include <Protocol\TpmDevice\TpmDevice.h>
+#include <AmiDxeLib.h>
+#include <token.h>
+#include "Tpm20CRBLib.h"
+
+
+#define _CR( Record, TYPE,\
+ Field )((TYPE*) ((CHAR8*) (Record) - (CHAR8*) &(((TYPE*) 0)->Field)))
+
+EFI_GUID TcgGuid = AMI_TCG_RESETVAR_HOB_GUID;
+
+VOID* LocateATcgHob (
+ UINTN NoTableEntries,
+ EFI_CONFIGURATION_TABLE *ConfigTable,
+ EFI_GUID *HOB_guid );
+
+#define TPM_DXE_PRIVATE_DATA_FROM_THIS( this ) \
+ _CR( this, TPM_DXE_PRIVATE_DATA, TpmInterface )
+
+typedef struct _TPM_DXE_PRIVATE_DATA
+{
+ EFI_TPM_DEVICE_PROTOCOL TpmInterface;
+ EFI_PHYSICAL_ADDRESS BaseAddr;
+} TPM_DXE_PRIVATE_DATA;
+
+FixedDelay(UINT32 dCount);
+
+static UINTN TpmFuncID;
+static TPMTransmitEntryStruct TpmEmptyBuf;
+static UINT32 TpmRet;
+static UINTN ReadytoBootVar = 0;
+
+
+#if TCG_LEGACY == 0
+EFI_STATUS
+EFIAPI TpmDxeInit(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ EFI_STATUS Status;
+ volatile TPM_1_2_REGISTERS_PTR TpmReg;
+ TpmReg = (TPM_1_2_REGISTERS_PTR)(( UINTN ) (PORT_TPM_IOMEMBASE));
+ Status = TisRequestLocality(TpmReg);
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI TpmDxeClose(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ EFI_STATUS Status;
+ volatile TPM_1_2_REGISTERS_PTR TpmReg;
+ TpmReg = (TPM_1_2_REGISTERS_PTR)(( UINTN ) (PORT_TPM_IOMEMBASE));
+ Status = TisReleaseLocality(TpmReg);
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI TpmDxeGetStatusInfo(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS
+EFIAPI TpmDxeTransmit(
+ IN EFI_TPM_DEVICE_PROTOCOL *This,
+ IN UINTN NoInBuffers,
+ IN TPM_TRANSMIT_BUFFER *InBuffers,
+ IN UINTN NoOutBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutBuffers )
+{
+ volatile TPM_1_2_REGISTERS_PTR TpmReg;
+ TpmReg = (TPM_1_2_REGISTERS_PTR)(( UINTN ) (PORT_TPM_IOMEMBASE));
+
+ TRACE(( TRACE_ALWAYS,"TpmReg.Access = %x \n", TpmReg->Access));
+ return TpmLibPassThrough(
+ TpmReg,
+ NoInBuffers,
+ InBuffers,
+ NoOutBuffers,
+ OutBuffers
+ );
+}
+
+#else
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TpmDxeInit
+//
+// Description: Call to OEM driver to initialize TPM.
+//
+// Input: IN EFI_TPM_DEVICE_PROTOCOL *This
+//
+// Returns: EFI_STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TpmDxeInit(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ return EFI_SUCCESS; //init command is only sent once and done in PEI
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Name: TpmDxeClose
+//
+// Description: Close TPM connection for locality 0
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+///
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TpmDxeClose(
+ IN EFI_TPM_DEVICE_PROTOCOL *This )
+{
+ return EFI_SUCCESS;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+//
+// Name: TpmDxeGetStatusInfo
+//
+// Description: GetStatus Info from MP driver
+//
+// Input: IN PEI_TPM_PPI *This,
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TpmDxeGetStatusInfo(
+ IN EFI_TPM_DEVICE_PROTOCOL * This
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SetEfiOSTransitions
+//
+// Description: SetEfiOSTransitions
+//
+// Input: IN EFI_EVENT efiev
+// IN VOID *ctx
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+void SetEfiOSTransitions(
+ IN EFI_EVENT efiev,
+ IN VOID *ctx )
+{
+ ReadytoBootVar = 1;
+}
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: EfiOSReadyToBoot
+//
+// Description: Sets ready to boot callback on ready to boot
+//
+// Input: NONE
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI EfiOSReadyToBoot()
+{
+ EFI_EVENT ReadToBootEvent;
+ EFI_STATUS Status;
+
+ #if defined(EFI_EVENT_SIGNAL_READY_TO_BOOT)\
+ && EFI_SPECIFICATION_VERSION < 0x20000
+
+ Status = pBS->CreateEvent( EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ EFI_TPL_CALLBACK,
+ SetEfiOSTransitions, NULL, &ReadToBootEvent );
+
+ #else
+ Status = CreateReadyToBootEvent( EFI_TPL_CALLBACK-1,
+ SetEfiOSTransitions,
+ NULL,
+ &ReadToBootEvent );
+ #endif
+
+ return Status;
+}
+
+
+
+EFI_STATUS
+EFIAPI EfiPreOSTransition(
+ IN EFI_TPM_DEVICE_PROTOCOL *This,
+ IN UINTN NoInBuffers,
+ IN TPM_TRANSMIT_BUFFER *InBuffers,
+ IN UINTN NoOutBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutBuffers )
+{
+ TPM_DXE_PRIVATE_DATA *Private;
+ TPM_1_2_REGISTERS_PTR TpmReg;
+ EFI_STATUS Status;
+
+ Private = TPM_DXE_PRIVATE_DATA_FROM_THIS( This );
+
+ TisRequestLocality(
+ (TPM_1_2_REGISTERS_PTR)( UINTN ) Private->BaseAddr);
+
+ TpmReg = (TPM_1_2_REGISTERS_PTR)( UINTN ) Private->BaseAddr;
+
+ Status = TpmLibPassThrough(
+ TpmReg,
+ NoInBuffers,
+ InBuffers,
+ NoOutBuffers,
+ OutBuffers
+ );
+
+ TisReleaseLocality(
+ (TPM_1_2_REGISTERS_PTR)( UINTN ) Private->BaseAddr);
+
+ return Status;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+//
+// Name: TpmDxeTransmit
+//
+// Description: Dxe Transmit Tcg Data
+//
+// Input: IN EFI_TPM_DEVICE_PROTOCOL *This,
+// IN UINTN NoInBuffers,
+// IN TPM_TRANSMIT_BUFFER *InBuffers,
+// IN UINTN NoOutBuffers,
+// IN OUT TPM_TRANSMIT_BUFFER *OutBuffers
+//
+// Output: EFI STATUS
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+
+EFI_STATUS
+EFIAPI TpmDxeTransmit(
+ IN EFI_TPM_DEVICE_PROTOCOL *This,
+ IN UINTN NoInBuffers,
+ IN TPM_TRANSMIT_BUFFER *InBuffers,
+ IN UINTN NoOutBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutBuffers )
+{
+ TPM_DXE_PRIVATE_DATA *Private;
+ TPMTransmitEntryStruct FillESI;
+ UINTN FuncID = (UINTN)MP_FUNCTION_TRANSMIT;
+ UINT32 Ret;
+ UINT8 *SHA_ARRAY_OUT = NULL;
+ BOOLEAN FillBuff = FALSE;
+ BOOLEAN Other = FALSE;
+ UINTN i = 0, loc = 0;
+ UINT8 *Tpm_SHA_ARRAY= NULL;
+ EFI_STATUS Status;
+
+
+ if(NoInBuffers == 0 || InBuffers == NULL || NoOutBuffers == 0 || OutBuffers == NULL)
+ return EFI_INVALID_PARAMETER;
+
+ if(ReadytoBootVar == 1)
+ {
+ return EfiPreOSTransition(This, NoInBuffers, InBuffers, NoOutBuffers, OutBuffers);
+ }
+
+
+ FillESI.dwInLen = 0;
+ FillESI.dwOutLen = 0;
+
+ for (; i < NoInBuffers; i++ )
+ {
+ FillESI.dwInLen += (UINT32)InBuffers[i].Size;
+ }
+
+ Status = pBS-> AllocatePool( EfiBootservicesData, FillESI.dwInLen, &Tpm_SHA_ARRAY);
+ if(EFI_ERROR(Status))return Status;
+
+
+ for (i = 0; i < NoOutBuffers; i++ )
+ {
+ FillESI.dwOutLen += (UINT32)OutBuffers[i].Size;
+ }
+
+ Status = pBS-> AllocatePool( EfiBootservicesData, FillESI.dwOutLen, &SHA_ARRAY_OUT );
+ if(EFI_ERROR(Status))return Status;
+
+
+ for (i = 0; i < NoInBuffers; i++ )
+ {
+ pBS->CopyMem(Tpm_SHA_ARRAY + loc,
+ InBuffers[i].Buffer,
+ InBuffers[i].Size );
+
+ loc += InBuffers[i].Size;
+ }
+
+ FillESI.pbInBuf = (UINT32)(EFI_PHYSICAL_ADDRESS) Tpm_SHA_ARRAY;
+ FillESI.pbOutBuf = (UINT32)(EFI_PHYSICAL_ADDRESS) SHA_ARRAY_OUT;
+
+ Private = TPM_DXE_PRIVATE_DATA_FROM_THIS( This );
+ TpmDxeCallMPDriver( FuncID, &FillESI, &Ret );
+
+ if ( Tpm_SHA_ARRAY != NULL )
+ {
+ pBS->FreePool( Tpm_SHA_ARRAY );
+ }
+
+ loc = 0;
+
+ for (i=0; i < NoOutBuffers; i++ )
+ {
+ pBS->CopyMem( OutBuffers[i].Buffer,
+ &SHA_ARRAY_OUT[loc],
+ OutBuffers[i].Size );
+ loc += (UINTN)OutBuffers[i].Size;
+ }
+
+ if ( SHA_ARRAY_OUT != NULL )
+ {
+ pBS->FreePool( SHA_ARRAY_OUT );
+ }
+
+ return EFI_SUCCESS;
+}
+
+#endif
+
+static TPM_DXE_PRIVATE_DATA mTpmPrivate = {
+ {
+ TpmDxeInit,
+ TpmDxeClose,
+ TpmDxeGetStatusInfo,
+ TpmDxeTransmit
+ },
+ TPM_BASE_ADDRESS
+};
+
+
+
+
+EFI_STATUS
+EFIAPI TpmDxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+#if TCG_LEGACY == 1
+ EFI_GUID gMpDriverHobGuid = EFI_TCG_MPDriver_HOB_GUID;
+ FAR32LOCALS *TempLoc = NULL;
+#endif
+
+#if TCG_LEGACY == 0
+ Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)( UINTN ) mTpmPrivate.BaseAddr );
+
+ if ( EFI_ERROR( Status ))
+ {
+ if(isTpm20CrbPresent())return EFI_SUCCESS;
+ return EFI_UNLOAD_IMAGE;
+ }
+#else
+ TempLoc = (FAR32LOCALS*)LocateATcgHob( pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &gMpDriverHobGuid );
+
+
+ if(TempLoc == NULL || TempLoc->Offset == NULL ) return EFI_NOT_FOUND;
+ Prepare2Thunkproc( TempLoc->Offset, TempLoc->Selector );
+ Status = EfiOSReadyToBoot();
+#endif
+
+ Status = pBS->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiTpmDeviceProtocolGuid,
+ &mTpmPrivate.TpmInterface,
+ NULL
+ );
+
+ return Status;
+}
+
+
+
+EFI_GUID gEfiTpmDeviceProtocolGuid = EFI_TPM_DEVICE_PROTOCOL_GUID;
diff --git a/Core/EM/TCG2/Common/xTcgDxe.c b/Core/EM/TCG2/Common/xTcgDxe.c
new file mode 100644
index 0000000..4e2d21f
--- /dev/null
+++ b/Core/EM/TCG2/Common/xTcgDxe.c
@@ -0,0 +1,1835 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/xTcgDxe.c 2 6/14/14 12:28a Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 6/14/14 12:28a $
+//**********************************************************************
+// Revision History
+// ----------------\
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgDxe/xTcgDxe.c $
+//
+// 2 6/14/14 12:28a Fredericko
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 2 10/31/13 11:20a Fredericko
+//
+// 1 10/08/13 12:03p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 2:01p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 105 12/10/12 6:24p Fredericko
+//
+// 104 12/03/12 11:01p Fredericko
+// [TAG] EIP104961
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] UEFI 2.3.1 SCT test failed in Generic\EfiCompliant case.
+// The VariableAttribute of SecureBoot is not correct.
+// [RootCause] Changes to Secureboot module
+// [Solution] Remove secureboot variable check in Tcg
+// [Files] AmiTcgPlatformDxe.c
+// xTcgdxe.c
+//
+// 103 10/30/12 11:31a Fredericko
+//
+// 102 9/13/12 5:09p Fredericko
+// [TAG] EIP96217
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] AMIUEFI: Only one EV_EFI_VARIABLE_AUTHORITY event instead
+// of two when an EFI application or driver is not executed because of a
+// Secure Boot violation and then booted into Windows ( Winqual Bug ID :
+// 958465 )
+// [RootCause] Not measuring Subsequent Certificate Authority that can
+// be loaded after boot before ExitBootServices is called
+// [Solution] Measuring all Subsequent Certificate Authority that can be
+// loaded after boot before ExitBootServices is called
+// Also EIP [96218]: Measure Zero Events for when SecureBootSupport is
+// enabled but Keys are not installed
+// [Files] xTcgDxe.c
+// AmiTcgPlatformDxe.c
+//
+// 101 5/09/12 3:52p Fredericko
+// Changes for the measurement for Certificate Authority for secureboot.
+//
+// 100 4/28/12 3:28p Fredericko
+// Changed When gpt is measured as well as put Perf macro for DP
+// information.
+//
+// 99 4/19/12 5:57p Fredericko
+// EIP: 85771. Fixes for measurement of gpt partitions on EFI platform.
+// First boot scenario after flashing was failing sometimes.
+//
+// 97 3/19/12 6:32p Fredericko
+// [TAG] EIP82769
+// [Category] Improvement
+// [Description] Firmware updates disable the TPM when Firmware update
+// is done
+// [Files] xTcgPei.c, xTcgDxe.c, TcgDxe.c
+//
+// 96 12/15/11 3:25p Fredericko
+//
+// 95 12/12/11 3:37p Fredericko
+// [TAG] EIP76865
+// [Category] Improvement
+// [Description] Dual Support for TCM and TPM. System could hang in TXT
+// if txt is enabled in setup
+// [Files] AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif,
+// AmiTcgPlatformPpi.h, AmiTcgPlatformProtocol.cif,
+// AmiTcgPlatformProtocol.h,
+// EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+// TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+// xTcgPeiAfterMem.c
+//
+// 94 11/17/11 2:31p Fredericko
+// Changes for AmiTcgSetup for cases when TPM is plug into board after
+// first boot.
+//
+// 93 10/26/11 3:15p Fredericko
+// Changes for First boot scenerio and when Tcg Support is enabled and
+// Disabled
+//
+// 92 10/10/11 12:06a Fredericko
+// [TAG] EIP70220
+// [Category] Improvement
+// [Description] Remove dependency on CSM
+// [Files] TcgLegacy.sdl
+// AmiTcgPlatformDxe.c
+// AmiTcgPlatformDxe.h
+// xTcgDxe.c
+//
+// 91 9/27/11 10:26p Fredericko
+// [TAG] EIP67286
+// [Category] Improvement
+// [Description] changes for Tcg Setup policy
+// [Files] Tcg.sdl
+// TcgPei.cif
+// TcgPei.mak
+// xtcgPei.c
+// xTcgPeiAfterMem.c
+// TcgPeiAfterMem.mak
+// TcgDxe.cif
+// TcgDxe.mak
+// xTcgDxe.c
+// AmiTcgPlatformPeilib.c
+// AmiTcgPlatformDxelib.c
+//
+// 90 9/03/11 8:05p Fredericko
+//
+// 89 8/29/11 6:50p Fredericko
+// [TAG] EIP0000
+// [Category] Improvement
+// [Description] Tcg Setup improvement. Logic for when Tcgsupport is
+// enabled.
+// [Files] xtcgdxe.c
+//
+// 88 4/18/11 5:00p Fredericko
+//
+// 87 3/29/11 9:17p Fredericko
+// Don't install platform protocol if there is a TPM device error from
+// startup command or selftest
+//
+// 86 3/29/11 1:13p Fredericko
+//
+// 85 3/28/11 2:20p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 82 10/07/10 10:37a Fredericko
+// [TAG] EIP45667
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] Fail to get AMITSEVar
+// [RootCause] Uninitialized variable
+// [Solution] Initialize Size variable in prompt_operation function
+// [Files] xtcgdxe.c
+//
+// 81 9/23/10 6:12p Fredericko
+// [TAG] EIP42580
+// [Category] BUG FIX
+// [Severity] Normal
+// [Symptom] TPM prompt message override on LOGO mode
+// [RootCause] Proper SDL token comparism
+// [Solution] Use proper SDL token comparism
+// [Files] xtcgdxe.c
+//
+// 80 8/31/10 2:18p Fredericko
+// Workaround TSE problem with using AMIpost Manager for string display.
+//
+// 79 8/19/10 5:28p Fredericko
+// Edit display string positions on screen.
+//
+// 78 8/13/10 11:06a Fredericko
+// [TAG] N\A
+// [Category] IMPROVEMENT
+// [Description] Support for core 4.6.4.x and UEFI 2.1 Specifications
+// [FILES] xTcgDxe.c, TPMPwd.c
+//
+// 77 8/10/10 6:11p Fredericko
+// String display operations changes.
+//
+// 76 8/09/10 3:49p Fredericko
+// UEFI 2.1 changes
+//
+// 75 8/09/10 2:23p Fredericko
+// UEFI 2.1 changes
+//
+// 74 8/04/10 5:18p Fredericko
+// Reset system after executing owner commands. Special case.
+//
+// 73 7/13/10 5:37p Fredericko
+//
+// 72 7/09/10 3:39p Fredericko
+// modified platform protocol
+//
+// 71 6/02/10 5:06p Fredericko
+// Do nothing on some TPM error scenerios. We were shutting down the
+// system before.
+//
+// 70 5/21/10 4:03p Fredericko
+// Hii String package changes
+//
+// 68 5/21/10 11:37a Rizwank
+// Changes to include proper strings token header when AMI_TCG_MESSAGE is
+// enabled
+// Use correct imagehandle name
+//
+// 67 5/20/10 5:37p Fredericko
+//
+//
+// 65 5/20/10 9:02a Fredericko
+// Included File Header
+// Code Beautification
+// EIP 37653
+//
+// 64 4/30/10 5:01p Fredericko
+// EIP 36943: Was not writing TPM results and clearing TPM request on a
+// special case.
+//
+// 63 4/21/10 11:50a Fredericko
+// Removal of functions that are no needed anymore for multi language
+// support.
+//
+// 62 3/23/10 8:42p Fredericko
+// TcgLegacy event moved to subcomponent
+//
+// 61 3/19/10 4:20p Fredericko
+// modified for legacy IO interface support
+//
+// 60 1/14/10 11:57a Fredericko
+// Physical presence lifetime lock support added.
+//
+// 59 12/31/09 2:52p Fredericko
+// modified to allow the setting of lifetime lock on physical presence
+//
+// 58 11/17/09 5:53p Fredericko
+// Check-in changes for PPI request that was lost in label 32...
+//
+// 57 10/10/09 5:11p Fredericko
+//
+// 56 9/15/09 6:22p Fredericko
+// Changed to not use CMOS for the case when a deactivated for Enable,
+// Activate and allow owner command.
+//
+// 55 8/19/09 1:58p Fredericko
+//
+// 54 8/19/09 10:54a Fredericko
+// Support to measure CPU microcode in Nested firmware volume.
+//
+// 53 8/14/09 4:22p Fredericko
+// Changed flow with Authentication and Setup Confirmation to rid of extra
+// reset in the flow.
+//
+// 52 7/29/09 11:17a Fredericko
+// 1. Create ACPI table for all ACPI NVS. including ACPI3.0
+// 2. If Setup request fails full reset the platform and re-execute the
+// command on next boot.
+// 3. Minor Compiler problem with error checking fixed.
+//
+// 1 6/10/09 4:56p Fasihm
+// Added fix for TCG support. Remove after TCG label is updated with
+// changes generically incorporated.
+//
+// 51 6/02/09 4:49p Fredericko
+//
+// 50 6/02/09 1:12p Fredericko
+//
+// 49 6/01/09 4:18p Fredericko
+// Changes added for TCM_SUPPORT
+//
+// 48 4/30/09 6:18p Fredericko
+// Updated Header Date
+//
+// 47 4/30/09 5:36p Fredericko
+// AMI company Header Address changes, Fixes when AMI_TCG_MESSAGE is
+// enabled. Build and display Fixes.
+//
+// 46 4/13/09 4:39p Fredericko
+//
+// 45 4/03/09 6:14p Fredericko
+// #define changes and coding standard changes
+//
+// 43 3/05/09 3:15p Fredericko
+// Changes for CoreSources dependency
+//
+// 42 2/05/09 5:37p Fredericko
+// Lots of changes done in relation to removing dependencies on EDK
+//
+// 41 1/02/09 5:36p Fredericko
+// Moving Measurement of event Separators to EFI phase from legacy phase.
+//
+// 39 6/02/08 8:34p Fredericko
+// update Setup with no hardware if TPM does not respond properly to
+// commands.
+//
+// 38 4/10/08 6:02p Fredericko
+// Mor implemenation changes. Currently supports upto 4GB.
+//
+// 37 4/10/08 5:31p Fredericko
+// Generic Measurement changes and bug fixes
+//
+// 36 2/27/08 8:50p Fredericko
+//
+// 35 2/27/08 5:57p Fredericko
+// TCG specification changes and code clean up
+//
+// 34 2/06/08 9:01p Fredericko
+// Changes for DTM WLK 1.1 and Physical Presence Lock before booting.
+//
+// 33 1/18/08 8:23p Fredericko
+// Generic changes for Tcg EFI measurements specification requirements
+//
+// 32 11/09/07 6:44p Fasihm
+// Removed CONFIRM_SETUP_CHANGE around update_cmos() as it is not needed
+// now.
+//
+// 31 10/23/07 12:36p Fredericko
+// Setup PPI bug fixes
+//
+// 30 10/08/07 9:16a Fredericko
+//
+// 29 9/26/07 2:46p Fredericko
+// Build in TRACE "TRACE" bugs
+//
+// 28 9/04/07 6:09p Fredericko
+// Changes made for new compiler swtich "\W4" to work
+//
+// 27 9/04/07 10:22a Fredericko
+// Measuring Embedded PciROM fix
+//
+// 26 8/09/07 2:20p Pats
+// Removed unnecessary extern reference.
+//
+// 25 8/09/07 11:34a Pats
+// Modified to support password authentication and state change
+// confirmation.
+//
+// 24 7/13/07 2:54p Rameshraju
+// Added the TPM post message and SDL tokens for the TPM key's
+//
+// 23 6/13/07 5:26p Fredericko
+// Measuring PCI option ROM fixes
+//
+// 22 6/08/07 6:36p Fredericko
+// New TPM feature to allow disabling and enabling TPM support.
+//
+// 21 5/22/07 7:24p Fredericko
+//
+// 20 5/22/07 3:51p Fredericko
+// Added TPM feature to report TPM status and ownership in setup
+//
+// 19 3/23/07 3:34p Fredericko
+// Display Correction for PPI request
+//
+// 18 3/19/07 9:07a Fredericko
+// Build issue fix
+//
+// 17 3/14/07 5:14p Fredericko
+// PPI print change and PPI bug fixes
+//
+// 16 3/12/07 11:45a Fredericko
+// Allow execution of TCG command if Tcg_Setup_enable and
+// TCG_setup_operation is requested
+//
+// 15 3/07/07 3:10p Fredericko
+// TCG_PPI bug fixes
+//
+// 14 3/06/07 1:02p Fasihm
+// Added the support for the TCG PPI support to the TCG module.
+//
+// 13 3/01/07 8:00p Fasihm
+// Changes made for the new Edk in both structures and APIs.
+//
+// 12 12/11/06 1:56p Fasihm
+// Added code for controlling with the Setup question TCG_SETUP.
+//
+// 11 11/15/06 11:16a Radhikav
+//
+// 10 11/13/06 3:47p Radhikav
+//
+// 9 11/03/06 6:34p Andriyn
+//
+// 8 11/02/06 9:59a Andriyn
+// Change: new features (PPI and Setup questions) are conditional under
+// SDL flag
+//
+// 7 10/06/06 5:16p Andriyn
+//
+// 6 8/22/06 1:30p Andriyn
+// MOR related changes
+//
+// 5 8/18/06 9:02a Andriyn
+// Refactor code
+//
+// 4 8/15/06 9:28a Andriyn
+//
+// 3 6/22/06 3:03p Andriyn
+//
+// 2 6/20/06 7:13p Andriyn
+// Changes due to protocols moved to MiscFramework
+//--------------------------------------------------------------------------
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: xTcgDxe.c
+//
+// Description:
+// Most Tcg DXE initialization and measurements are done here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <EFI.h>
+#include <TcgCommon.h>
+#include <AmiLib.h>
+#include <token.h>
+
+#if SMBIOS_SUPPORT == 1
+ #include <SmBios.h>
+#endif
+
+#include <TcgMisc.h>
+#include "TcgPrivate.h"
+#include <AmiDxeLib.h>
+#include <TcgPrivate.h>
+#include <DiskIo.h>
+#include <BlockIo.h>
+#include "protocol\TcgService\TcgService.h"
+#include "protocol\TpmDevice\TpmDevice.h"
+#include "Protocol/CpuIo.h"
+#include "Protocol/FirmwareVolume.h"
+#include "Protocol/DevicePath.h"
+#include "Protocol/PciIo.h"
+#include "TcgPlatformSetupPolicy.h"
+#include <AmiTcgPlatformProtocol.h>
+#if (defined(TCGMeasureSecureBootVariables) && (TCGMeasureSecureBootVariables != 0))
+#include <ImageAuthentication.h>
+#endif
+
+
+//------------------------------------------------------------------------
+//Internal Structures
+//------------------------------------------------------------------------
+typedef struct _TCG_DXE_PRIVATE_DATA
+{
+ EFI_TCG_PROTOCOL TcgServiceProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmDevice;
+} TCG_DXE_PRIVATE_DATA;
+
+EFI_STATUS
+__stdcall TcgDxeCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue );
+
+
+#define TCG_DXE_PRIVATE_DATA_FROM_THIS( This ) \
+ _CR( This, TCG_DXE_PRIVATE_DATA, TcgServiceProtocol )
+//--------------------------------------------------------------------------
+//--------------------------------------------------------------------------
+
+#define GUID_VARIABLE_DECLARATION( Variable, Guid ) extern EFI_GUID Variable
+
+EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+EFI_GUID gDsdtGuidDxe = DSDT_GUID;
+EFI_GUID TcgEfiGlobalVariableGuid = TCG_EFI_GLOBAL_VARIABLE_GUID;
+EFI_GUID AmiTcgPlatformProtocolGuid = AMI_TCG_PLATFORM_PROTOCOL_GUID;
+EFI_GUID gEfiTcgPrivateInterfaceGuid = EFI_TCG_PRIVATE_INTERFACE_GUID;
+static BOOLEAN BootLaunchDone = FALSE;
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+
+#include <AcpiSupport.h>
+
+//---------------------------------------------------------------------------
+//---------------------------------------------------------------------------
+EFI_STATUS EFIAPI TcgDxeHashLogExtendEvent (
+ IN EFI_TCG_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS HashData,
+ IN UINT64 HashDataLen,
+ IN TCG_ALGORITHM_ID AlgorithmId,
+ IN OUT TCG_PCR_EVENT *TCGLogData,
+ IN OUT UINT32 *evNum );
+
+EFI_STATUS
+EFIAPI
+TcgMeasureGptTable (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ );
+
+
+/////////////////////////////////////////////////
+#define AMI_VALID_BOOT_IMAGE_CERT_TBL_GUID \
+ { 0x6683D10C, 0xCF6E, 0x4914, 0xB5, 0xB4, 0xAB, 0x8E, 0xD7, 0x37, 0x0E, 0xD7 }
+//
+//
+// Data Table definition
+//
+typedef struct _AMI_VALID_CERT_IN_SIG_DB {
+ UINT32 SigOffset;
+ UINT32 SigLength;
+} AMI_VALID_CERT_IN_SIG_DB;
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AppendDevicePath
+//
+// Description: Appends Two given Device Path
+//
+// Input: IN EFI_DEVICE_PATH_PROTOCOL *Path1
+// IN EFI_DEVICE_PATH_PROTOCOL *Path2
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+static
+EFI_DEVICE_PATH_PROTOCOL* TcgAppendDevicePath(
+ IN EFI_DEVICE_PATH_PROTOCOL *Path1,
+ IN EFI_DEVICE_PATH_PROTOCOL *Path2 )
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewPath;
+ UINTN PathSize1, PathSize2;
+
+ if ( !Path1 && !Path2 )
+ {
+ return NULL;
+ }
+
+ PathSize1 = DPLength( Path1 );
+ PathSize2 = DPLength( Path2 );
+
+ if ( PathSize1 && PathSize2 )
+ {
+ PathSize1 -= sizeof (EFI_DEVICE_PATH_PROTOCOL);
+ }
+
+ pBS->AllocatePool( EfiBootServicesData,
+ PathSize1 + PathSize2,
+ (void**)&NewPath );
+
+ pBS->CopyMem( NewPath, Path1, PathSize1 );
+ pBS->CopyMem( (UINT8*)NewPath + PathSize1, Path2, PathSize2 );
+
+ return NewPath;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EfiLibAllocatePool
+//
+// Description: Allocate BootServicesData pool.
+//
+// Input: AllocationSize - The size to allocate
+//
+// Output: Pointer of the buffer allocated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *
+EfiLibAllocatePool (
+ IN UINTN AllocationSize
+)
+{
+ VOID *Memory;
+
+ Memory = NULL;
+ pBS->AllocatePool (EfiBootServicesData, AllocationSize, &Memory);
+ return Memory;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: TcgEfiLibAllocateZeroPool
+//
+// Description: Allocate BootServicesData pool and zero the pool.
+//
+// Input: AllocationSize - The size to allocate
+//
+// Output: Pointer of the buffer allocated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID *
+TcgEfiLibAllocateZeroPool (
+ IN UINTN AllocationSize
+ )
+{
+ VOID *Memory;
+
+ Memory = EfiLibAllocatePool (AllocationSize);
+ if (Memory != NULL) {
+ pBS->SetMem (Memory, AllocationSize, 0);
+ }
+
+ return Memory;
+}
+
+
+#if (defined(TCGMeasureSecureBootVariables) && (TCGMeasureSecureBootVariables != 0))
+EFI_STATUS
+MeasureCertificate(UINTN sizeOfCertificate,
+ UINT8 *pterCertificate)
+{
+ EFI_STATUS Status;
+ TCG_PCR_EVENT *TcgEvent = NULL;
+ EFI_GUID gEfiTcgProtocolGuid = EFI_TCG_PROTOCOL_GUID;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ TCG_EFI_VARIABLE_DATA *VarLog;
+ EFI_PHYSICAL_ADDRESS Last;
+ UINT32 evNum;
+ BOOLEAN AlreadyMeasuredCert = FALSE;
+ UINTN i=0;
+ UINTN VarNameLength;
+ static BOOLEAN initialized = 0;
+ static TPM_DIGEST digestTrackingArray[10];
+ static TPM_DIGEST zeroDigest;
+ UINT8 *tempDigest = NULL;
+ UINT64 HashedDataLen = 20;
+
+ if(!initialized)
+ {
+ for(i=0;i<5; i++)
+ {
+ MemSet(digestTrackingArray[i].digest,20,0);
+ }
+ MemSet(zeroDigest.digest,20,0);
+ initialized = TRUE;
+ }
+
+ Status = pBS->LocateProtocol(&gEfiTcgProtocolGuid,
+ NULL, &tcgSvc );
+
+ if(EFI_ERROR(Status))return Status;
+
+ VarNameLength = Wcslen(L"db");
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ _TPM_STRUCT_PARTIAL_SIZE( TCG_PCR_EVENT,Event )
+ + (UINT32)(sizeof(TCG_EFI_VARIABLE_DATA) + (VarNameLength
+ * sizeof(CHAR16)) + sizeOfCertificate - 3),
+ &TcgEvent);
+
+ if(EFI_ERROR(Status))return Status;
+
+ TcgEvent->PCRIndex = 7;
+ TcgEvent->EventType = 0x800000E0;
+
+ TcgEvent->EventSize = (UINT32)( sizeof (*VarLog) + VarNameLength
+ * sizeof (CHAR16) + sizeOfCertificate) - 3;
+
+ pBS->AllocatePool( EfiBootServicesData, TcgEvent->EventSize, &VarLog );
+
+ if ( VarLog == NULL ){
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ VarLog->VariableName = gEfiImageSecurityDatabaseGuid;
+ VarLog->UnicodeNameLength = VarNameLength;
+ VarLog->VariableDataLength = sizeOfCertificate;
+
+ pBS->CopyMem((CHAR16*)(VarLog->UnicodeName),
+ L"db",
+ VarNameLength * sizeof (CHAR16));
+
+ pBS->CopyMem((CHAR16*)(VarLog->UnicodeName) + VarNameLength,
+ pterCertificate,
+ sizeOfCertificate);
+
+ pBS->CopyMem( TcgEvent->Event,
+ VarLog,
+ TcgEvent->EventSize );
+
+ //before extending verify if we have already measured it.
+ tcgSvc->HashAll(tcgSvc,
+ (UINT8 *)VarLog,
+ TcgEvent->EventSize,
+ 4,
+ &HashedDataLen,
+ &tempDigest);
+
+ for(i=0; i<10; i++)
+ {
+ //tempDigest
+ if(!MemCmp(digestTrackingArray[i].digest, tempDigest, 20))
+ return EFI_SUCCESS; //already measured
+
+ if(!MemCmp(digestTrackingArray[i].digest, zeroDigest.digest, 20))
+ break; //we need to measure
+ }
+
+ pBS->CopyMem(digestTrackingArray[i].digest, tempDigest, 20);
+
+ Status = tcgSvc->HashLogExtendEvent(tcgSvc,
+ (EFI_PHYSICAL_ADDRESS)VarLog,
+ TcgEvent->EventSize,
+ 4,
+ TcgEvent,
+ &evNum,
+ &Last );
+
+ pBS->FreePool(TcgEvent);
+
+ return Status;
+}
+
+
+EFI_STATUS FindandMeasureSecureBootCertificate(BOOLEAN BootPolicy)
+{
+ EFI_STATUS Status;
+ UINTN VarSize = 0;
+ UINTN i=0;
+ UINT8 *SecureDBBuffer = NULL;
+ UINT8 *CertificateBuffer = NULL;
+ UINTN SizeofCertificate = 0;
+ EFI_GUID Certificateguid = AMI_VALID_BOOT_IMAGE_CERT_TBL_GUID;
+ AMI_VALID_CERT_IN_SIG_DB *CertInfo;
+ UINT8 *CertOffsetPtr = NULL;
+ static BOOLEAN NullKeysMeasured = FALSE;
+
+
+ if(BootPolicy == FALSE && BootLaunchDone == FALSE) return EFI_SUCCESS;
+ if(NullKeysMeasured == TRUE)return EFI_SUCCESS;
+
+ if(BootPolicy == TRUE && BootLaunchDone == FALSE)
+ {
+ Status = pRS->GetVariable(L"db",
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &VarSize,
+ NULL);
+
+ if ( Status == EFI_BUFFER_TOO_SMALL )
+ {
+ pBS->AllocatePool( EfiBootServicesData, VarSize, &SecureDBBuffer );
+
+ if ( SecureDBBuffer != NULL )
+ {
+ Status = pRS->GetVariable(L"db",
+ &gEfiImageSecurityDatabaseGuid,
+ NULL,
+ &VarSize,
+ SecureDBBuffer);
+
+ if ( EFI_ERROR( Status ))
+ {
+ pBS->FreePool( SecureDBBuffer );
+ SecureDBBuffer = NULL;
+#if (defined(UnconfiguredSecureBootVariables) && (UnconfiguredSecureBootVariables == 0))
+ return EFI_NOT_FOUND;
+#endif
+ }
+ }
+
+ }else{
+#if (defined(UnconfiguredSecureBootVariables) && (UnconfiguredSecureBootVariables == 0))
+ return EFI_NOT_FOUND;
+#else
+ SecureDBBuffer = NULL;
+#endif
+ }
+ }
+
+ //we need to find the pointer in the EFI system table and work from
+ //there
+ CertInfo = NULL;
+ CertInfo = GetEfiConfigurationTable(pST, &Certificateguid);
+ if(CertInfo == NULL){
+ TRACE(( TRACE_ALWAYS,"db variable found SecCertificate Information not found in EFI System Table \n"));
+ }
+ if(CertInfo->SigLength == 0){
+ TRACE(( TRACE_ALWAYS,"SecCertificate Information found in EST but Information might be invalid \n"));
+ }
+
+ CertOffsetPtr = NULL;
+
+ if(CertInfo!=0)
+ {
+ CertOffsetPtr = (SecureDBBuffer + CertInfo->SigOffset);
+ SizeofCertificate = (UINTN)CertInfo->SigLength;
+ }else{
+ SizeofCertificate = 0;
+ }
+
+ if(SizeofCertificate == 0){
+ NullKeysMeasured = TRUE;
+ }
+
+ MeasureCertificate(SizeofCertificate,CertOffsetPtr);
+
+ if(SecureDBBuffer!=NULL){
+ pBS->FreePool( SecureDBBuffer );
+ }
+
+ return Status;
+}
+#endif
+
+
+
+
+//--------------------------------------------------------------------------------------------
+//Description: Measure a PE/COFF image into PCR 2 or 4 depending on Boot policy of 0 or 1
+//Arguments:
+// BootPolicy - Boolean value of 0 or 1 for PCR index 2 or 4.
+// ImageContext - Contains details about the image.
+// LinkTimeBase - Linking time Image Address
+// ImageType - EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION, BOOT_SERVICE_DRIVER, EFI_RUNTIME_DRIVER
+// DeviceHandle - Device identification handle
+// FilePath - Device File path
+//Output: EFI_SUCCESS - Image Measured successfully.
+//---------------------------------------------------------------------------------------------
+
+EFI_STATUS
+EFIAPI
+TcgMeasurePeImage (
+ IN BOOLEAN BootPolicy,
+ IN EFI_PHYSICAL_ADDRESS ImageAddress,
+ IN UINTN ImageSize,
+ IN UINTN LinkTimeBase,
+ IN UINT16 ImageType,
+ IN EFI_HANDLE DeviceHandle,
+ IN EFI_DEVICE_PATH_PROTOCOL *FilePath
+ )
+{
+
+ EFI_STATUS Status;
+ TCG_PCR_EVENT_HDR TcgEvent;
+ TCG_PCR_EVENT *TcgEventlog = NULL;
+ EFI_IMAGE_LOAD_EVENT *ImageLoad;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FullPath;
+ UINT32 FullPathSize;
+ SHA1_CTX Sha1Ctx;
+ TCG_EFI_IMAGE_DOS_HEADER *DosHdr;
+ UINT32 PeCoffHeaderOffset;
+ TCG_EFI_IMAGE_NT_HEADERS *Hdr;
+ TCG_EFI_IMAGE_SECTION_HEADER *Section;
+ UINT8 *HashBase;
+ UINTN HashSize;
+ UINTN SumOfBytesHashed;
+ TCG_EFI_IMAGE_SECTION_HEADER *SectionHeader;
+ UINTN Index, iPos;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmProtocol;
+ UINT32 EventNumber;
+ TCG_DIGEST *Sha1Digest = NULL;
+
+ ImageLoad = NULL;
+ FullPath = NULL;
+ SectionHeader = NULL;
+ FullPathSize = 0;
+
+ if(AutoSupportType()){
+ return EFI_SUCCESS;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, &TcgProtocol);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiTpmDeviceProtocolGuid, NULL, &TpmProtocol );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+
+ if (DeviceHandle != NULL) {
+ //
+ // Skip images loaded from FVs
+ //
+ Status = pBS->OpenProtocol (
+ DeviceHandle,
+ &gEfiFirmwareVolumeProtocolGuid,
+ NULL,
+ NULL,
+ NULL,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ goto Done;
+ }
+ ASSERT (Status == EFI_UNSUPPORTED);
+
+ //
+ // Get device path for the device handle
+ //
+ Status = pBS->HandleProtocol (
+ DeviceHandle,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+
+ FullPath = TcgAppendDevicePath (DevicePath, FilePath);
+ FullPathSize = (UINT32)DPLength (FullPath);
+ }
+
+ //Allocate Event log memory
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ _TPM_STRUCT_PARTIAL_SIZE( TCG_PCR_EVENT, Event )
+ + ((sizeof (*ImageLoad)
+ - sizeof (ImageLoad->DevicePath)) + FullPathSize),
+ &TcgEventlog );
+ //
+ // Determine destination PCR by BootPolicy
+ //
+ TcgEvent.PCRIndex = BootPolicy ? 4 : 2;
+ TcgEvent.EventSize = sizeof (*ImageLoad) - sizeof (ImageLoad->DevicePath);
+ TcgEvent.EventSize += FullPathSize;
+
+ switch (ImageType) {
+ case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ TcgEvent.EventType = EV_EFI_BOOT_SERVICES_APPLICATION;
+ break;
+ case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ TcgEvent.EventType = EV_EFI_BOOT_SERVICES_DRIVER;
+ break;
+ case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ TcgEvent.EventType = EV_EFI_RUNTIME_SERVICES_DRIVER;
+ break;
+ default:
+ TRACE(( TRACE_ALWAYS,
+ __FUNCTION__ ": Unknown subsystem type %d",
+ ImageType));
+
+ ASSERT (FALSE);
+ TcgEvent.EventType = ImageType;
+ Status = EFI_UNSUPPORTED;
+ goto Done;
+ }
+
+ //do measure images from ROM that call LoadImage themselves
+ // without the correct Devicepath
+ if(ImageType == EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER
+ && BootLaunchDone == FALSE){
+ return EFI_SUCCESS;
+ }
+
+
+ PERF_START(0,L"MeasurePeImg",NULL,0);
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ TcgEvent.EventSize,
+ &ImageLoad );
+
+ if (ImageLoad == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Done;
+ }
+
+ ImageLoad->ImageLocationInMemory = ImageAddress;
+ ImageLoad->ImageLengthInMemory = ImageSize;
+ ImageLoad->ImageLinkTimeAddress = LinkTimeBase;
+ ImageLoad->LengthOfDevicePath = FullPathSize;
+ pBS->CopyMem( ImageLoad->DevicePath, FullPath, FullPathSize );
+
+ //
+ // Check PE/COFF image
+ //
+ DosHdr = (TCG_EFI_IMAGE_DOS_HEADER *)(UINTN)ImageAddress;
+ PeCoffHeaderOffset = 0;
+ if (DosHdr->e_magic == TCG_EFI_IMAGE_DOS_SIGNATURE) {
+ PeCoffHeaderOffset = DosHdr->e_lfanew;
+ }
+ if (((TCG_EFI_TE_IMAGE_HEADER *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset))->Signature
+ == TCG_EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ goto Done;
+ }
+
+ //
+ // PE/COFF Image Measurement
+ //
+ // NOTE: The following codes/steps are based upon the authenticode image hashing in
+ // PE/COFF Specification 8.0 Appendix A.
+ //
+ //
+
+ // 1. Load the image header into memory.
+
+ // 2. Initialize a SHA hash context.
+// Status = SHA1_init(TcgProtocol, &Sha1Ctx);
+ SHA1Init(&Sha1Ctx );
+
+ //
+ // Measuring PE/COFF Image Header;
+ // But CheckSum field and SECURITY data directory (certificate) are excluded
+ //
+ Hdr = (TCG_EFI_IMAGE_NT_HEADERS *)((UINT8 *)(UINTN)ImageAddress + PeCoffHeaderOffset);
+
+ //
+ // 3. Calculate the distance from the base of the image header to the image checksum address.
+ // 4. Hash the image header from its base to beginning of the image checksum.
+ //
+ HashBase = (UINT8 *)(UINTN)ImageAddress;
+ HashSize = (UINTN) ((UINT8 *)(&Hdr->OptionalHeader.CheckSum) - HashBase);
+
+/*Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ //
+ // 5. Skip over the image checksum (it occupies a single ULONG).
+ // 6. Get the address of the beginning of the Cert Directory.
+ // 7. Hash everything from the end of the checksum to the start of the Cert Directory.
+ //
+ HashBase = (UINT8 *) &Hdr->OptionalHeader.CheckSum + sizeof (UINT32);
+ HashSize = (UINTN) ((UINT8 *)(&Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY]) - HashBase);
+
+/* Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ //
+ // 8. Skip over the Cert Directory. (It is sizeof(IMAGE_DATA_DIRECTORY) bytes.)
+ // 9. Hash everything from the end of the Cert Directory to the end of image header.
+ //
+ HashBase = (UINT8 *) &Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1];
+ HashSize = Hdr->OptionalHeader.SizeOfHeaders -
+ (UINTN) ((UINT8 *)(&Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY + 1]) - (UINT8 *)(UINTN)ImageAddress);
+
+/* Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ //
+ // 10. Set the SUM_OF_BYTES_HASHED to the size of the header
+ //
+ SumOfBytesHashed = Hdr->OptionalHeader.SizeOfHeaders;
+
+ //
+ // 11. Build a temporary table of pointers to all the IMAGE_SECTION_HEADER
+ // structures in the image. The 'NumberOfSections' field of the image
+ // header indicates how big the table should be. Do not include any
+ // IMAGE_SECTION_HEADERs in the table whose 'SizeOfRawData' field is zero.
+ //
+
+ Status = pBS->AllocatePool (EfiBootServicesData, sizeof (TCG_EFI_IMAGE_SECTION_HEADER) * Hdr->FileHeader.NumberOfSections, &SectionHeader);
+ if(SectionHeader==NULL)return EFI_OUT_OF_RESOURCES;
+ pBS->SetMem (SectionHeader, sizeof (TCG_EFI_IMAGE_SECTION_HEADER) * Hdr->FileHeader.NumberOfSections , 0);
+
+ //
+ // 12. Using the 'PointerToRawData' in the referenced section headers as
+ // a key, arrange the elements in the table in ascending order. In other
+ // words, sort the section headers according to the disk-file offset of
+ // the section.
+ //
+ Section = (TCG_EFI_IMAGE_SECTION_HEADER *) (
+ (UINT8 *)(UINTN)ImageAddress +
+ PeCoffHeaderOffset +
+ sizeof(UINT32) +
+ sizeof(TCG_EFI_IMAGE_FILE_HEADER) +
+ Hdr->FileHeader.SizeOfOptionalHeader
+ );
+ for (Index = 0; Index < Hdr->FileHeader.NumberOfSections; Index++) {
+ iPos = Index;
+ while ((iPos > 0) && (Section->PointerToRawData < SectionHeader[iPos - 1].PointerToRawData)) {
+ MemCpy (&SectionHeader[iPos], &SectionHeader[iPos - 1], sizeof(TCG_EFI_IMAGE_SECTION_HEADER));
+ iPos--;
+ }
+ MemCpy( &SectionHeader[iPos], Section,
+ sizeof(TCG_EFI_IMAGE_SECTION_HEADER));
+ Section += 1;
+ }
+
+ //
+ // 13. Walk through the sorted table, bring the corresponding section
+ // into memory, and hash the entire section (using the 'SizeOfRawData'
+ // field in the section header to determine the amount of data to hash).
+ // 14. Add the section's 'SizeOfRawData' to SUM_OF_BYTES_HASHED .
+ // 15. Repeat steps 13 and 14 for all the sections in the sorted table.
+ //
+ for (Index = 0; Index < Hdr->FileHeader.NumberOfSections; Index++) {
+ Section = (TCG_EFI_IMAGE_SECTION_HEADER *) &SectionHeader[Index];
+ if (Section->SizeOfRawData == 0) {
+ continue;
+ }
+ HashBase = (UINT8 *)(UINTN)ImageAddress + Section->PointerToRawData;
+ HashSize = (UINTN) Section->SizeOfRawData;
+/*
+ Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+
+ SumOfBytesHashed += HashSize;
+ }
+
+ //
+ // 16. If the file size is greater than SUM_OF_BYTES_HASHED, there is extra
+ // data in the file that needs to be added to the hash. This data begins
+ // at file offset SUM_OF_BYTES_HASHED and its length is:
+ // FileSize - (CertDirectory->Size)
+ //
+ if (ImageSize > SumOfBytesHashed) {
+ HashBase = (UINT8 *)(UINTN)ImageAddress + SumOfBytesHashed;
+ HashSize = (UINTN)(ImageSize -
+ Hdr->OptionalHeader.DataDirectory[TCG_EFI_IMAGE_DIRECTORY_ENTRY_SECURITY].Size -
+ SumOfBytesHashed);
+/*
+ Status = SHA1_update(TcgProtocol,
+ &Sha1Ctx,
+ HashBase,
+ HashSize
+ );
+*/
+ SHA1Update(&Sha1Ctx, HashBase, (u32)HashSize );
+ }
+
+ //
+ // 17. Finalize the SHA hash.
+ //
+// Status = SHA1_final(TcgProtocol, &Sha1Ctx, &Sha1Digest);
+ SHA1Final((unsigned char *)&Sha1Digest->digest, &Sha1Ctx);
+
+ pBS->CopyMem (&TcgEvent.Digest.digest,Sha1Digest->digest, sizeof (TcgEvent.Digest.digest));
+
+ //
+ // HashLogExtendEvent
+ //
+
+ //hash has been generated so extend it
+ TpmProtocol->Init(TpmProtocol);
+
+ Status = TcgDxeCommonExtend (
+ (void *)TcgProtocol,
+ TcgEvent.PCRIndex,
+ &TcgEvent.Digest,
+ Sha1Digest
+ );
+
+ TpmProtocol->Close(TpmProtocol);
+
+ if (!EFI_ERROR (Status)) {
+
+ //Now log the event
+ TcgEventlog->PCRIndex = TcgEvent.PCRIndex;
+ TcgEventlog->EventType = TcgEvent.EventType;
+ TcgEventlog->EventSize = TcgEvent.EventSize;
+ MemCpy(&TcgEventlog->Digest, &TcgEvent.Digest, sizeof(TCG_DIGEST));
+ MemCpy(&TcgEventlog->Event, ImageLoad, TcgEvent.EventSize);
+ Status = TcgProtocol->LogEvent(TcgProtocol, TcgEventlog, &EventNumber,0x01);
+ }
+
+ PERF_END(0,L"MeasurePeImg",NULL,0);
+
+ if(BootPolicy == TRUE && BootLaunchDone == FALSE){
+ PERF_START(0,L"MeasureGpt",NULL,0);
+ TcgMeasureGptTable(FullPath);
+ PERF_END(0,L"MeasureGpt",NULL,0);
+ }
+
+#if (defined(TCGMeasureSecureBootVariables) && (TCGMeasureSecureBootVariables != 0))
+ FindandMeasureSecureBootCertificate(BootPolicy);
+#endif
+
+ if(BootPolicy == TRUE && BootLaunchDone == FALSE){
+ BootLaunchDone = TRUE;
+ }
+
+ TpmProtocol->Close(TpmProtocol);
+
+Done:
+ if (ImageLoad != NULL) {
+ pBS->FreePool (ImageLoad);
+ }
+
+ if (TcgEventlog != NULL )
+ {
+ pBS->FreePool( TcgEventlog );
+ }
+ if (FullPathSize > 0) {
+ pBS->FreePool (FullPath);
+ }
+ if (SectionHeader != NULL) {
+ pBS->FreePool (SectionHeader);
+ }
+ return Status;
+}
+
+
+
+
+
+
+EFI_STATUS
+EFIAPI
+GptDevicePathToHandle (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ OUT EFI_HANDLE *GptHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePathNode;
+ EFI_DEVICE_PATH_PROTOCOL *PreDevicePathNode;
+ HARDDRIVE_DEVICE_PATH *HdDevicePath;
+ EFI_HANDLE Handle;
+ BOOLEAN GptDiskFound;
+
+ NewDevicePathNode = TcgEfiLibAllocateZeroPool (DPLength (DevicePath));
+ MemCpy (NewDevicePathNode, DevicePath, DPLength (DevicePath));
+ DevicePathNode = NewDevicePathNode;
+
+ //
+ // The device should support blockIO protocol. Check it.
+ //
+ Status = pBS->LocateDevicePath (&gEfiBlockIoProtocolGuid, &DevicePathNode, &Handle);
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (NewDevicePathNode);
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Find the gpt partion on the given devicepath, if not, return.
+ //
+ GptDiskFound = FALSE;
+ PreDevicePathNode = NULL;
+ HdDevicePath = NULL;
+ DevicePathNode = NewDevicePathNode;
+ while (!IsDevicePathEnd (DevicePathNode)) {
+ //
+ // Find the Gpt partition
+ //
+ if (DevicePathType (DevicePathNode) == MEDIA_DEVICE_PATH &&
+ DevicePathSubType (DevicePathNode) == MEDIA_HARDDRIVE_DP) {
+ HdDevicePath = (HARDDRIVE_DEVICE_PATH *) DevicePathNode;
+ //
+ // Check whether it is a gpt partition or not
+ //
+ if (PreDevicePathNode != NULL &&
+ HdDevicePath->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER &&
+ HdDevicePath->SignatureType == SIGNATURE_TYPE_GUID) {
+ GptDiskFound = TRUE;
+ break;
+ }
+ }
+ PreDevicePathNode = DevicePathNode;
+ DevicePathNode = NextDevicePathNode (DevicePathNode);
+ }
+ if (!GptDiskFound) {
+ pBS->FreePool (NewDevicePathNode);
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Change the device path to the parent device path and get the handle.
+ //
+ DevicePathNode->Type = 0xFF;
+ DevicePathNode->SubType = 0xFF;
+ DevicePathNode = NewDevicePathNode;
+ Status = pBS->LocateDevicePath (
+ &gEfiDiskIoProtocolGuid,
+ &DevicePathNode,
+ &Handle
+ );
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (NewDevicePathNode);
+ return Status;
+ }
+ *GptHandle = Handle;
+ pBS->FreePool (NewDevicePathNode);
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+HandleBootDevicePath(
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *Handle;
+ UINTN Count, i;
+ EFI_DEVICE_PATH_PROTOCOL *FullDevicePath=NULL;
+ HARDDRIVE_DEVICE_PATH *BootParitionDevicePath = (HARDDRIVE_DEVICE_PATH*)DevicePath;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol,&gEfiBlockIoProtocolGuid,NULL,&Count,&Handle);
+ if (EFI_ERROR(Status)) return NULL;
+
+ for( i=0; i<Count; i++ )
+ {
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DEVICE_PATH_PROTOCOL *PartitionDevicePath, *TmpDevicePath;
+ HARDDRIVE_DEVICE_PATH* PartitionNode;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiBlockIoProtocolGuid,&BlockIo);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // if this is not partition, continue
+ if (!BlockIo->Media->LogicalPartition)
+ continue;
+
+ Status = pBS->HandleProtocol(Handle[i],&gEfiDevicePathProtocolGuid,&PartitionDevicePath);
+ if (EFI_ERROR(Status))
+ continue;
+
+ // Get last node of the device path. It should be partition node
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)PartitionDevicePath;
+
+ for( TmpDevicePath = PartitionDevicePath;
+ !IsDevicePathEndType(TmpDevicePath);
+ TmpDevicePath=NextDevicePathNode(TmpDevicePath) )
+ {
+ PartitionNode = (HARDDRIVE_DEVICE_PATH*)TmpDevicePath;
+ }
+
+ //Check if our partition matches Boot partition
+ if (PartitionNode->Header.Type!=MEDIA_DEVICE_PATH || PartitionNode->Header.SubType!=MEDIA_HARDDRIVE_DP)
+ continue;
+
+ if ( PartitionNode->PartitionNumber==BootParitionDevicePath->PartitionNumber &&
+ PartitionNode->SignatureType==BootParitionDevicePath->SignatureType &&
+ !MemCmp(PartitionNode->Signature,BootParitionDevicePath->Signature,16) )
+ {
+ //Match found
+ FullDevicePath = TcgAppendDevicePath(PartitionDevicePath,NextDevicePathNode(DevicePath));
+ break;
+ }
+ }
+
+ pBS->FreePool(Handle);
+ return FullDevicePath;
+}
+
+
+EFI_STATUS
+EFIAPI
+TcgMeasureGptTable (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+ EFI_DISK_IO_PROTOCOL *DiskIo;
+ TCG_EFI_PARTITION_TABLE_HEADER *PrimaryHeader;
+ TCG_EFI_PARTITION_ENTRY *PartitionEntry;
+ UINT8 *EntryPtr;
+ UINTN NumberOfPartition;
+ UINT32 Index;
+ TCG_PCR_EVENT *TcgEvent;
+ TCG_EFI_GPT_DATA *GptData;
+ EFI_GUID NullGuid = EFI_NULL_GUID;
+ EFI_HANDLE Handle;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ EFI_TPM_DEVICE_PROTOCOL *TpmProtocol;
+ UINT32 evNum;
+ EFI_PHYSICAL_ADDRESS Last;
+ UINTN GptIndex;
+
+ if(AutoSupportType()){
+ return EFI_SUCCESS;
+ }
+
+ Status = GptDevicePathToHandle (DevicePath, &Handle);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, &BlockIo);
+ if (EFI_ERROR (Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = pBS->HandleProtocol (Handle, &gEfiDiskIoProtocolGuid, &DiskIo);
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, &TcgProtocol);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = pBS->LocateProtocol (&gEfiTpmDeviceProtocolGuid, NULL, &TpmProtocol );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+
+ //
+ // Read the EFI Partition Table Header
+ //
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ BlockIo->Media->BlockSize,
+ &PrimaryHeader );
+
+ if (PrimaryHeader == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = DiskIo->ReadDisk (
+ DiskIo,
+ BlockIo->Media->MediaId,
+ 1 * BlockIo->Media->BlockSize,
+ BlockIo->Media->BlockSize,
+ (UINT8 *)PrimaryHeader
+ );
+
+ if (EFI_ERROR (Status)) {
+ TRACE ((TRACE_ALWAYS, "Failed to Read Partition Table Header!\n"));
+ pBS->FreePool (PrimaryHeader);
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Read the partition entry.
+ //
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,
+ &EntryPtr );
+
+ if (EntryPtr == NULL) {
+ pBS->FreePool (PrimaryHeader);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Status = DiskIo->ReadDisk (
+ DiskIo,
+ BlockIo->Media->MediaId,
+ Mul64(PrimaryHeader->PartitionEntryLba, BlockIo->Media->BlockSize),
+ PrimaryHeader->NumberOfPartitionEntries * PrimaryHeader->SizeOfPartitionEntry,
+ EntryPtr);
+
+ if (EFI_ERROR (Status)) {
+ pBS->FreePool (PrimaryHeader);
+ pBS->FreePool (EntryPtr);
+ return EFI_DEVICE_ERROR;
+ }
+
+
+ //
+ // Count the valid partition
+ //
+ PartitionEntry = (TCG_EFI_PARTITION_ENTRY *)EntryPtr;
+ NumberOfPartition = 0;
+ for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
+ if (MemCmp(&PartitionEntry->PartitionTypeGuid, &NullGuid, sizeof(EFI_GUID))) {
+ NumberOfPartition++;
+ }
+ PartitionEntry++;
+ }
+ //
+ // Parepare Data for Measurement
+ //
+
+ //allocate memory for TCG event
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ sizeof(TCG_PCR_EVENT_HDR) + \
+ (UINT32)(sizeof (TCG_EFI_PARTITION_TABLE_HEADER) + sizeof(UINTN)\
+ + (NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry)),
+ &TcgEvent );
+
+ TcgEvent->PCRIndex = 5;
+ TcgEvent->EventType = EV_EFI_GPT_EVENT;
+ TcgEvent->EventSize = (UINT32)(sizeof (TCG_EFI_PARTITION_TABLE_HEADER) + sizeof(UINTN)\
+ + (NumberOfPartition * PrimaryHeader->SizeOfPartitionEntry));
+
+
+ Status = pBS->AllocatePool( EfiBootServicesData,
+ TcgEvent->EventSize,
+ &GptData );
+ if (GptData == NULL) {
+ pBS->FreePool (PrimaryHeader);
+ pBS->FreePool (EntryPtr);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ MemSet(GptData, TcgEvent->EventSize, 0);
+ //
+ // Copy the EFI_PARTITION_TABLE_HEADER and NumberOfPartition
+ //
+ MemCpy ((UINT8 *)GptData, (UINT8*)PrimaryHeader, sizeof (TCG_EFI_PARTITION_TABLE_HEADER));
+ GptData->NumberOfPartitions = NumberOfPartition;
+ //
+ // Copy the valid partition entry
+ //
+
+ PartitionEntry = (TCG_EFI_PARTITION_ENTRY*)EntryPtr;
+ GptIndex = 0;
+ for (Index = 0; Index < PrimaryHeader->NumberOfPartitionEntries; Index++) {
+ if (MemCmp (&PartitionEntry->PartitionTypeGuid, &NullGuid, sizeof(EFI_GUID))) {
+ MemCpy (
+ (UINT8 *)&GptData->Partitions + (GptIndex * sizeof (TCG_EFI_PARTITION_ENTRY)),
+ (UINT8 *)PartitionEntry,
+ sizeof (TCG_EFI_PARTITION_ENTRY)
+ );
+ GptIndex+=1;
+ }
+ PartitionEntry++;
+ }
+ //
+ // Measure the GPT data
+ //
+
+ pBS->CopyMem (TcgEvent->Event,
+ GptData,
+ TcgEvent->EventSize);
+
+ TpmProtocol ->Init( TpmProtocol );
+
+ Status = TcgProtocol->HashLogExtendEvent(
+ TcgProtocol,
+ (EFI_PHYSICAL_ADDRESS)GptData,
+ TcgEvent->EventSize,
+ TCG_ALG_SHA,
+ TcgEvent,
+ &evNum,
+ &Last);
+
+
+ TpmProtocol ->Close( TpmProtocol );
+
+ pBS->FreePool (PrimaryHeader);
+ pBS->FreePool (EntryPtr);
+ pBS->FreePool (TcgEvent);
+ pBS->FreePool (GptData);
+
+ TRACE(( TRACE_ALWAYS,"GPT_EXIT"));
+ return Status;
+}
+
+
+
+EFI_STATUS
+TcgMeasureAction(
+ IN CHAR8 *String
+ )
+{
+
+ TCG_PCR_EVENT *TcgEvent = NULL;
+ EFI_PHYSICAL_ADDRESS Last;
+ EFI_TCG_PROTOCOL *tcgSvc;
+ UINT32 evNum;
+ UINT32 Len;
+ EFI_STATUS Status;
+
+
+ Status = pBS->LocateProtocol (
+ &gEfiTcgProtocolGuid,
+ NULL,
+ &tcgSvc);
+
+ ASSERT(!EFI_ERROR(Status));
+
+ Len = (UINT32)Strlen(String);
+ Status = pBS->AllocatePool (EfiBootServicesData,
+ _TPM_STRUCT_PARTIAL_SIZE (TCG_PCR_EVENT, Event) +
+ Len,
+ &TcgEvent);
+
+ ASSERT(!EFI_ERROR(Status));
+
+ TcgEvent->PCRIndex = 5;
+ TcgEvent->EventType = EV_EFI_ACTION;
+ TcgEvent->EventSize = Len;
+
+ pBS->CopyMem (TcgEvent->Event,
+ String,
+ Len);
+
+ Status = tcgSvc->HashLogExtendEvent (
+ tcgSvc,
+ (EFI_PHYSICAL_ADDRESS)String,
+ TcgEvent->EventSize,
+ TCG_ALG_SHA,
+ TcgEvent,
+ &evNum,
+ &Last);
+
+ if(TcgEvent!=NULL)
+ {
+ pBS->FreePool (TcgEvent);
+ }
+
+ return Status;
+}
+
+UINT8 GetPlatformSupportType()
+{
+ return (AutoSupportType());
+}
+
+
+static EFI_TCG_PLATFORM_PROTOCOL mTcgPlatformProtocol = {
+ TcgMeasurePeImage,
+ TcgMeasureAction,
+ TcgMeasureGptTable
+};
+
+
+static AMI_TCG_PLATFORM_PROTOCOL mAmiTcgPlatformProtocol = {
+ GetPlatformSupportType
+};
+
+
+EFI_STATUS EFIAPI TcmDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable);
+
+TpmDxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE * SystemTable);
+
+
+
+EFI_STATUS
+EFIAPI TcgDxeEntry (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable );
+
+EFI_STATUS
+EFIAPI Tcg20DxeEntry(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable );
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+// Procedure: CommonTcgDxEntryPoint
+//
+// Description: Common entry point for Tcgdxe
+//
+// Input: IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI CommonTcgDxEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_STATUS Status;
+ TCG_PLATFORM_SETUP_PROTOCOL *ProtocolInstance;
+ EFI_GUID Policyguid = TCG_PLATFORM_SETUP_POLICY_GUID;
+ BOOLEAN TpmInitError = FALSE;
+#if TCG_LEGACY == 1
+ BOOLEAN TpmLegBin = TRUE;
+#else
+ BOOLEAN TpmLegBin = FALSE;
+#endif
+ TCG_CONFIGURATION Config;
+ EFI_TCG_PROTOCOL *TcgProtocol;
+ EFI_GUID TcgFirstbootGuid = AMI_TCG_RESETVAR_HOB_GUID;
+ void ** DummyPtr;
+ BOOLEAN *ResetAllTcgVar = NULL;
+
+
+ InitAmiLib( ImageHandle, SystemTable );
+
+ Status = pBS->LocateProtocol (&Policyguid, NULL, &ProtocolInstance);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ MemCpy(&Config, &ProtocolInstance->ConfigFlags, sizeof(TCG_CONFIGURATION));
+
+ Config.TcgSupportEnabled = 0;
+
+ if((AutoSupportType()== TRUE) || (TpmLegBin == TRUE))
+ {
+ if( Config.TpmSupport != 0x00)
+ {
+#if TCG_LEGACY == 0
+ Config.TcmSupport = TRUE;
+ Status = TcmDxeEntry( ImageHandle, SystemTable );
+#else
+ Config.TcmSupport = FALSE;
+ Status = TpmDxeEntry( ImageHandle, SystemTable);
+#endif
+ if(Status){
+ Config.TpmHardware = TRUE;
+ TpmInitError = TRUE;
+ }
+ }
+ }else{
+ Config.TcmSupport = FALSE;
+ Status = TpmDxeEntry( ImageHandle, SystemTable );
+ if(Status){
+ Config.TpmHardware = TRUE;
+ TpmInitError = TRUE;
+ }else{
+ Config.TpmHardware = FALSE; //negative logic False means present
+ }
+ }
+
+ if(TpmInitError){
+ Config.Tpm20Device = 0;
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ return Status;
+ }
+
+ Status = Tcg20DxeEntry( ImageHandle, SystemTable );
+ if(Status != EFI_UNSUPPORTED){
+ //all dependent components will depend on
+ //the TrEEProtocol installed above
+ return EFI_SUCCESS;
+ }
+
+ Status = TcgDxeEntry( ImageHandle, SystemTable );
+
+ if(EFI_ERROR(Status)){
+
+ //if Support was enabled don't change TPM state
+ if((ProtocolInstance->ConfigFlags.TcgSupportEnabled!=0 &&
+ ProtocolInstance->ConfigFlags.TpmSupport == 0) ||
+ (ProtocolInstance->ConfigFlags.TcgSupportEnabled!=0 &&
+ ProtocolInstance->ConfigFlags.TcmSupport == 0))
+ {
+ Config.TcgSupportEnabled = FALSE;
+ }
+ else{
+ Config.TpmEnable = 0;
+ Config.TpmOperation = 0;
+ Config.TpmEnaDisable = TRUE;
+ Config.TpmActDeact = TRUE;
+ Config.TpmOwnedUnowned = FALSE;
+ }
+
+ Config.PpiSetupSyncFlag = TRUE;
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ return Status;
+ }else{
+
+ Status = pBS->LocateProtocol (&gEfiTcgProtocolGuid, NULL, &TcgProtocol);
+ if (EFI_ERROR (Status)) {
+ Config.TcgSupportEnabled = FALSE;
+ ResetAllTcgVar = (UINT8*)LocateATcgHob(
+ pST->NumberOfTableEntries,
+ pST->ConfigurationTable,
+ &TcgFirstbootGuid);
+
+ DummyPtr = &ResetAllTcgVar;
+ if ( *DummyPtr != NULL )
+ {
+ if ( *ResetAllTcgVar == TRUE )
+ {
+ Config.PpiSetupSyncFlag = TRUE;
+ }
+ }
+
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ return Status;
+ }
+
+ Config.Tpm20Device = 0;
+ Config.TcgSupportEnabled = TRUE;
+ ProtocolInstance->UpdateStatusFlags(&Config, TRUE);
+ }
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &gEfiTcgPrivateInterfaceGuid,
+ EFI_NATIVE_INTERFACE,
+ &mTcgPlatformProtocol);
+
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &AmiTcgPlatformProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &mAmiTcgPlatformProtocol);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/xTcgPei.c b/Core/EM/TCG2/Common/xTcgPei.c
new file mode 100644
index 0000000..506f9be
--- /dev/null
+++ b/Core/EM/TCG2/Common/xTcgPei.c
@@ -0,0 +1,317 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/xTcgPei.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/xTcgPei.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 1:54p Fredericko
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 36 9/19/12 10:34a Fredericko
+// [TAG] EIP90807
+// [Category] Improvement
+// [Description] MonotonicCounter variable guid changed.
+// [Files] xTcgPei.c, AmiTcgPlatformPeiAfterMem.c
+//
+// 35 3/19/12 6:27p Fredericko
+// [TAG] EIP82769
+// [Description] Firmware updates disable the TPM when Firmware update
+// is done
+// [Files] TcgDxe.c, xTcgDxe.c, xTcgPei.c
+//
+// 34 12/12/11 3:17p Fredericko
+// [TAG] EIP76865
+// [Category] Improvement
+// [Description] Dual Support for TCM and TPM. System could hang in TXT
+// if txt is enabled in setup
+// [Files]
+// AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif, AmiTcgPlatformPpi.h,
+// AmiTcgPlatformProtocol.cif, AmiTcgPlatformProtocol.h,
+// EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+// TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+// xTcgPeiAfterMem.c
+//
+// 33 9/27/11 10:21p Fredericko
+// [TAG] EIP67286
+// [Category] Improvement
+// [Description] changes for Tcg Setup policy
+// [Files] Tcg.sdl
+// TcgPei.cif
+// TcgPei.mak
+// xtcgPei.c
+// xTcgPeiAfterMem.c
+// TcgPeiAfterMem.mak
+// TcgDxe.cif
+// TcgDxe.mak
+// xTcgDxe.c
+// AmiTcgPlatformPeilib.c
+// AmiTcgPlatformDxelib.c
+//
+// 32 4/27/11 3:01p Fredericko
+// removed VFR compile directive
+//
+// 31 3/29/11 12:57p Fredericko
+//
+// 30 3/28/11 2:14p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 29 5/19/10 5:53p Fredericko
+// Included File Header
+// Included File Revision History
+// Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: xTcgPei.c
+//
+// Description:
+// Contians entry point function for TcgPei Subcomponent
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include <Pei.h>
+#include <TcgCommon.h>
+#include <AmiPeiLib.h>
+#include <TcgMisc.h>
+#include <ppi\AmiTcgPlatformPpi.h>
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "PPI\CpuIo.h"
+#include "PPI\LoadFile.h"
+#include "TcgPlatformSetupPeiPolicy.h"
+#include "Tpm20Includes\Tpm20.h"
+#include "Tpm20CRBLib.h"
+
+
+
+EFI_GUID gTcgPpiGuid = PEI_TCG_PPI_GUID;
+EFI_GUID gPlatformGuid = AMI_TCG_PLATFORM_PPI_GUID;
+
+EFI_STATUS
+EFIAPI TpmPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+EFI_STATUS
+EFIAPI TcmPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+
+EFI_STATUS
+EFIAPI TcgPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+EFI_STATUS
+EFIAPI TcgTcmPeiEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+EFI_STATUS TcgPeiBuildHobGuid(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN DataLength,
+ OUT VOID **Hob );
+
+EFI_STATUS
+EFIAPI Tpm20CrbEntry(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+UINT8 GetPlatformSupportType()
+{
+ return (AutoSupportType());
+}
+
+static AMI_TCG_PLATFORM_PPI PlatformTypePpi = {
+ GetPlatformSupportType
+};
+
+
+static EFI_PEI_PPI_DESCRIPTOR mPlatformPpiList[] = {
+ {
+ EFI_PEI_PPI_DESCRIPTOR_PPI
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPlatformGuid,
+ &PlatformTypePpi
+ }
+};
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CommonTcgPeiEntryPoint
+//
+// Description: Entry point for Tcg PEI component
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI CommonTcgPeiEntryPoint(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ VOID *Context = NULL;
+ BOOLEAN DeviceType = FALSE;
+ TCG_PLATFORM_SETUP_INTERFACE *TcgPeiPolicy = NULL;
+ EFI_GUID gTcgPeiPolicyGuid =\
+ TCG_PLATFORM_SETUP_PEI_POLICY_GUID;
+ TCG_CONFIGURATION ConfigFlags;
+ CHAR16 Monotonic[] = L"MonotonicCounter";
+#if defined(CORE_COMBINED_VERSION) && (CORE_COMBINED_VERSION > 262797)
+ EFI_GUID Guid = AMI_GLOBAL_VARIABLE_GUID;
+#else
+ EFI_GUID Guid = EFI_GLOBAL_VARIABLE;
+#endif
+ EFI_GUID TcgGuid = AMI_TCG_RESETVAR_HOB_GUID;
+ UINTN Size = sizeof(UINT32);
+ UINT32 Counter;
+ EFI_PEI_READ_ONLY_VARIABLE_PPI *ReadOnlyVariable;
+ EFI_HOB_GUID_TYPE *Hob;
+ BOOLEAN ResetAllTcgVar = FALSE;
+ EFI_GUID gTcgReadOnlyVariablePpiGuid
+ = EFI_TCG_PEI_READ_ONLY_VARIABLE_PPI_GUID;
+
+
+ Status = (*PeiServices)->InstallPpi( PeiServices, &mPlatformPpiList[0] );
+ if ( EFI_ERROR( Status ))
+ {
+ return EFI_UNLOAD_IMAGE;
+ }
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gTcgPeiPolicyGuid,
+ 0, NULL,
+ &TcgPeiPolicy);
+
+ if(EFI_ERROR(Status) || TcgPeiPolicy == NULL )return Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gTcgReadOnlyVariablePpiGuid,
+ 0, NULL,
+ &ReadOnlyVariable
+ );
+
+ if(EFI_ERROR(Status) || ReadOnlyVariable == NULL )return Status;
+
+ Status = ReadOnlyVariable->GetVariable( PeiServices, Monotonic, &Guid,
+ NULL, &Size, &Counter );
+
+ if ( EFI_ERROR( Status ))
+ {
+
+ ResetAllTcgVar = TRUE;
+ Status = TcgPeiBuildHobGuid(
+ PeiServices,
+ &TcgGuid,
+ sizeof (BOOLEAN),
+ &Hob );
+
+ Hob++;
+ (*PeiServices)->CopyMem( Hob, &ResetAllTcgVar, sizeof (ResetAllTcgVar));
+ }
+
+ if(!AutoSupportType()){
+ Status = TpmPeiEntry( FfsHeader, PeiServices );
+ PEI_TRACE((-1, PeiServices, "TpmPeiEntry results = %r \n", Status));
+ if ( EFI_ERROR( Status )){
+ return Status;
+ }
+ }else{
+ Status = TcmPeiEntry( FfsHeader, PeiServices );
+ if ( EFI_ERROR( Status )){
+ return Status;}
+ }
+
+ PEI_TRACE((-1, PeiServices, "before getTcgPeiPolicy\n"));
+ Status = TcgPeiPolicy->getTcgPeiPolicy(PeiServices, &ConfigFlags);
+
+ PEI_TRACE((-1, PeiServices, "getTcgPeiPolicy results = %r \n", Status));
+
+ if ( ConfigFlags.TpmSupport == 0x00 || EFI_ERROR( Status ))
+ {
+ PEI_TRACE((-1, PeiServices, "ConfigFlags.TpmSupport == 0x00 || EFI_ERROR( Status )\n"));
+ return EFI_SUCCESS;
+ }
+
+
+ PEI_TRACE((-1, PeiServices, "TcgPeiEntry processing\n"));
+ if(!AutoSupportType()){
+ Status = TcgPeiEntry( FfsHeader, PeiServices );
+ PEI_TRACE((-1, PeiServices, "TcgPeiEntry result = %r\n", Status));
+ if(EFI_ERROR(Status)){
+ PEI_TRACE((-1, PeiServices, "Tpm20CrbEntry Execution\n", Status));
+ Tpm20CrbEntry(FfsHeader, PeiServices );
+ }
+ }else{
+ Status = TcgTcmPeiEntry( FfsHeader, PeiServices );
+ }
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Common/xTcgPeiAfterMem.c b/Core/EM/TCG2/Common/xTcgPeiAfterMem.c
new file mode 100644
index 0000000..772571c
--- /dev/null
+++ b/Core/EM/TCG2/Common/xTcgPeiAfterMem.c
@@ -0,0 +1,284 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/xTcgPeiAfterMem.c 1 4/21/14 2:16p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:16p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TcgPei/TcgPeiAfterMem/xTcgPeiAfterMem.c $
+//
+// 1 4/21/14 2:16p Fredericko
+//
+// 1 10/08/13 12:02p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:51p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 4 12/12/11 3:31p Fredericko
+// [TAG] EIP76865
+// [Category] Improvement
+// [Description] Dual Support for TCM and TPM. System could hang in TXT
+// if txt is enabled in setup
+// [Files] AmiTcgPlatfompeilib.c, AmiTcgPlatformPpi.cif,
+// AmiTcgPlatformPpi.h, AmiTcgPlatformProtocol.cif,
+// AmiTcgPlatformProtocol.h,
+// EMpTcmPei.c, TcgDxe.cif, TcgPei.cif, TcgPeiAfterMem.cif,
+// TcgPeiAfterMem.mak, TcgTcmPeiAfterMem.c, xTcgDxe.c, xTcgPei.c,
+// xTcgPeiAfterMem.c
+//
+// 3 9/27/11 10:22p Fredericko
+// [TAG] EIP67286
+// [Category] Improvement
+// [Description] changes for Tcg Setup policy
+//
+// [Files] Tcg.sdl
+// TcgPei.cif
+// TcgPei.mak
+// xtcgPei.c
+// xTcgPeiAfterMem.c
+// TcgPeiAfterMem.mak
+// TcgDxe.cif
+// TcgDxe.mak
+// xTcgDxe.c
+// AmiTcgPlatformPeilib.c
+// AmiTcgPlatformDxelib.c
+//
+// 2 9/03/11 8:04p Fredericko
+//
+// 1 8/22/11 1:45p Fredericko
+// [TAG] EIP61168
+// [Category] Improvement
+// [Description] Reload TCG PPI from memory when Memory is Installed
+// [Files] TcgPeiAfterMem.cif
+// TcgPeiAfterMem.c
+// xTcgPeiAfterMem.c
+// TcgPeiAfterMem.mak
+//
+// 32 4/27/11 3:01p Fredericko
+// removed VFR compile directive
+//
+// 31 3/29/11 12:57p Fredericko
+//
+// 30 3/28/11 2:14p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 29 5/19/10 5:53p Fredericko
+// Included File Header
+// Included File Revision History
+// Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: xTcgPei.c
+//
+// Description:
+// Contians entry point function for TcgPei Subcomponent
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include <Pei.h>
+#include <TcgCommon.h>
+#include <AmiPeiLib.h>
+#include <TcgMisc.h>
+#include "PPI\TcgService\TcgService.h"
+#include "PPI\TpmDevice\TpmDevice.h"
+#include "PPI\CpuIo.h"
+#include <TpmLib.h>
+#include "PPI\LoadFile.h"
+#include "TcgPlatformSetupPeiPolicy.h"
+
+
+EFI_GUID gTcgPpiGuid = PEI_TCG_PPI_GUID;
+EFI_GUID gCacheInstallGuid = EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI;
+
+
+EFI_STATUS
+EFIAPI TcgPeiMemoryCallbackEntry(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+EFI_STATUS
+EFIAPI TcgTcmPeiMemoryCallbackEntry(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+
+typedef struct _TCG_PEI_MEMORY_CALLBACK
+{
+ EFI_PEI_NOTIFY_DESCRIPTOR NotifyDesc;
+ EFI_FFS_FILE_HEADER *FfsHeader;
+} TCG_PEI_MEMORY_CALLBACK;
+
+
+EFI_STATUS
+EFIAPI TcgPeiMemoryEntry(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi );
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: OnMemoryDiscovered
+//
+// Description: Call Memory Present initialization on memory Installation
+//
+//
+// Input: IN EFI_PEI_SERVICES **PeiServices,
+// IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+// IN VOID *Ppi
+//
+// Output: EFI STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI TcgPeiMemoryEntry(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *Ppi )
+{
+ EFI_STATUS Status;
+ PEI_TCG_PPI *TcgPpi = NULL;
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gTcgPpiGuid ,
+ 0,
+ NULL,
+ &TcgPpi);
+
+ if ( EFI_ERROR( Status )){
+ return Status;
+ }
+
+ if(AutoSupportType())
+ {
+ TcgTcmPeiMemoryCallbackEntry(PeiServices);
+ }else{
+ TcgPeiMemoryCallbackEntry(PeiServices);
+ }
+
+ return (Status);
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CommonTcgPeiEntryPoint
+//
+// Description: Entry point for Tcg PEI component
+//
+//
+// Input: IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices,
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS
+EFIAPI ReInstallTcgServiceAfterMem(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ TCG_PLATFORM_SETUP_INTERFACE *TcgPeiPolicy = NULL;
+ EFI_GUID gTcgPeiPolicyGuid =\
+ TCG_PLATFORM_SETUP_PEI_POLICY_GUID;
+ TCG_PEI_MEMORY_CALLBACK *MemCallback;
+ TCG_CONFIGURATION ConfigFlags;
+
+ Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)(UINTN )PORT_TPM_IOMEMBASE);
+ if(EFI_ERROR(Status))return Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gTcgPeiPolicyGuid,
+ 0, NULL,
+ &TcgPeiPolicy);
+
+ if(EFI_ERROR(Status))return Status;
+
+ Status = TcgPeiPolicy->getTcgPeiPolicy(PeiServices, &ConfigFlags);
+
+ if (ConfigFlags.TpmSupport == 0x00 || EFI_ERROR( Status ))
+ {
+ return EFI_SUCCESS;
+ }
+
+
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof (TCG_PEI_MEMORY_CALLBACK),
+ &MemCallback);
+
+ if ( !EFI_ERROR( Status ))
+ {
+ MemCallback->NotifyDesc.Flags
+ = (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK
+ | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ MemCallback->NotifyDesc.Guid = &gCacheInstallGuid;
+ MemCallback->NotifyDesc.Notify = TcgPeiMemoryEntry;
+ MemCallback->FfsHeader = FfsHeader;
+
+ Status = (*PeiServices)->NotifyPpi( PeiServices,
+ &MemCallback->NotifyDesc );
+ }
+
+ return Status;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.cif b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.cif
new file mode 100644
index 0000000..697a7b6
--- /dev/null
+++ b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "ShaLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\CommonLibraries\ShaLib"
+ RefName = "ShaLib"
+[files]
+"ShaLib.sdl"
+"ShaLibPei.lib"
+"ShaLib.lib"
+<endComponent>
diff --git a/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.lib b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.lib
new file mode 100644
index 0000000..651216b
--- /dev/null
+++ b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.lib
Binary files differ
diff --git a/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.sdl b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.sdl
new file mode 100644
index 0000000..6a6785f
--- /dev/null
+++ b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLib.sdl
@@ -0,0 +1,27 @@
+TOKEN
+ Name = "ShaLib_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "TCG2Support" "=" "1"
+End
+
+TOKEN
+ Name = "SHALIB"
+ Value = "$(SHALIB_DIR)\SHALIB.lib"
+ TokenType = "Expression"
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SHALIBPEI"
+ Value = "$(SHALIB_DIR)\SHALIBPEI.lib"
+ TokenType = "Expression"
+ TargetMAK = Yes
+End
+
+PATH
+ Name = "SHALIB_DIR"
+End \ No newline at end of file
diff --git a/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLibPei.lib b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLibPei.lib
new file mode 100644
index 0000000..780b06b
--- /dev/null
+++ b/Core/EM/TCG2/CommonLibraries/ShaLib/ShaLibPei.lib
Binary files differ
diff --git a/Core/EM/TCG2/Libraries.cif b/Core/EM/TCG2/Libraries.cif
new file mode 100644
index 0000000..644e389
--- /dev/null
+++ b/Core/EM/TCG2/Libraries.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "Libraries"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\"
+ RefName = "Libraries"
+[parts]
+"ShaLib"
+"TisLib"
+"Tpm20CRBLib"
+<endComponent>
diff --git a/Core/EM/TCG2/TCG2.chm b/Core/EM/TCG2/TCG2.chm
new file mode 100644
index 0000000..92c239a
--- /dev/null
+++ b/Core/EM/TCG2/TCG2.chm
Binary files differ
diff --git a/Core/EM/TCG2/Tcg.cif b/Core/EM/TCG2/Tcg.cif
new file mode 100644
index 0000000..f7a185d
--- /dev/null
+++ b/Core/EM/TCG2/Tcg.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "TCG2"
+ category = eModule
+ LocalRoot = "Core\EM\TCG2\"
+ RefName = "TcgGeneric"
+[files]
+"TCG2.chm"
+"Tcg.sdl"
+[parts]
+"Libraries"
+"CommonHeaders"
+"Common"
+<endComponent>
diff --git a/Core/EM/TCG2/Tcg.sdl b/Core/EM/TCG2/Tcg.sdl
new file mode 100644
index 0000000..d925bfc
--- /dev/null
+++ b/Core/EM/TCG2/Tcg.sdl
@@ -0,0 +1,646 @@
+TOKEN
+ Name = "TCG2Support"
+ Value = "1"
+ Help = "Enable or Disable TCG_generic support"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SecurityChipMode"
+ Value = "7"
+ Help = "4-bit Bit 0 Sets Discreet TPM 2.0, Bit 1 sets Ftpm, Bit 2 sets TPM 1.2, BIT3 reserved"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM12Enabled"
+ Value = "($(SecurityChipMode) & 0x4)"
+ Help = "TPM 1.2 Support Enabled"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM20Enabled"
+ Value = "($(SecurityChipMode) & 0x1)"
+ Help = "TPM 20 enabled"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FTPM20Enabled"
+ Value = "($(SecurityChipMode) & 0x2)"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_SIZE"
+ Value = "010000h"
+ Help = "Size of Dxecore to measure"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_LEGACY"
+ Value = "0"
+ Help = "Main switch to enable Tcg Legacy support in Project."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCGPPISPEC_1_2_SUPPORT"
+ Value = "1"
+ Help = "This will enable TCG Ppi spec 1.2 support. The default is 1.0 support since most O.S. will support released version 1.0."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USE_BIOS_IMAGE_AS_CRTM"
+ Value = "0"
+ Help = "Requires controlled access to BIOS region on the Flash PART. Easily achieved with secureboot."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "WORD_ACCESS_SMI_PORT"
+ Value = "0"
+ Help = "This will cause 16 bit read and write to the TPM SMI port required for some AMD platforms"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "StartupCmd_SelfTest_State"
+ Value = "1"
+ Help = " 1 - Send TPM startup and Selftest before Mem. 0 Send selftest and Startup After Mem Init"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "TCG_LEGACY" "=" "0"
+End
+
+TOKEN
+ Name = "StartupCmd_SelfTest_State"
+ Value = "0"
+ Help = "Always send selftest and Startup Command after Mem if TCG_LEGACY is enabled"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Lock = Yes
+ Token = "TCG_LEGACY" "=" "1"
+End
+
+TOKEN
+ Name = "TPM_DRIVER_WAIT"
+ Value = "005h"
+ Help = "Delay count for TPM wait loop. Default is 50us. Please dont change to less than 2 (4us)."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DELAY_AMOUNT"
+ Value = "010"
+ Help = "Delay amount for TPM wait loop. Default is 5us. Please dont change to less than 2 (2us)."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OVERRIDE_TCG_ASL"
+ Value = "0"
+ Help = "Allow override of TCG ASL files"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "Stack_Work_Around"
+ Value = "0"
+ Help = "Allows for working around binaries that don't return correctly when called into"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PMBASE_RTC_WKAround"
+ Value = "1"
+ Help = "Calling into some TPM binaries via legacy IO might cause RTC status to be set."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_DEBUG_MODE"
+ Value = "1"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+ Lock = Yes
+ Token = "DEBUG_MODE" "=" "1"
+ Token = "x64_BUILD" "=" "0"
+End
+
+TOKEN
+ Name = "SET_LIFETIME_PPLOCK"
+ Value = "0"
+ Help = "Main switch to set lifetime lock to TCG physical presence. Once set this is not revertible"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USE_ZERO_SEPARATOR"
+ Value = "0"
+ Help = "Enable this bit to use a separator value of zeros"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPMID"
+ Value = "PNP0C31"
+ Help = "Device ID of the TPM device. This ID will show up in ACPI structure"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "TCG_LEGACY" "=" "0"
+End
+
+TOKEN
+ Name = "CTPMID"
+ Value = "PNP0C31"
+ Help = "Compatible Device ID of the TPM device. This ID will show up in _CID object"
+ TokenType = Expression
+ TargetMAK = Yes
+ Token = "TCG_LEGACY" "=" "0"
+End
+
+TOKEN
+ Name = "CID_SUPPORT"
+ Value = "0"
+ Help = "Enable optional ACPI compatiblity support in TPM ASL"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_IOMEMBASE"
+ Value = "0FED40000h"
+ Help = "Start of Mem I/O region dedicated for TPM access"
+ TokenType = Expression
+ TargetEQU = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "PORT_TPM_IOMEMBASE"
+ Value = "0xFED40000h"
+ Help = "Start of Mem I/O region dedicated for TPM access"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_PCCLIENT_SPEC"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_IOMEMSZ"
+ Value = "5000h"
+ Help = "Size of Mem I/O region dedicated for TPM access"
+ TokenType = Expression
+ TargetEQU = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "TPM_IOBASE"
+ Value = "600h"
+ Help = "Define IOBase for Legacy support. Should not be zero if TCG_Legacy is enabled"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_IOBASE_MAX"
+ Value = "6FFh"
+ Help = "Define IOBase for Legacy support. Should not be zero if TCG_Legacy is enabled"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_IOBASE2"
+ Value = "7Eh"
+ Help = "I/O registers used to configure the TPM and programm to use\TPM_IOBASE I/O range"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_IOBASE2_DATA"
+ Value = "7Fh"
+ Help = "I/O registers used to configure the TPM and programm to use\TPM_IOBASE I/O range"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_IOSZ"
+ Value = "0FFh"
+ Help = "Size of the IO range with base TPM_IOBASE"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCGSMIPORT"
+ Value = "$(SW_SMI_IO_ADDRESS)"
+ Help = "IO port used to generate software SMI."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCGSMIDATAPORT"
+ Value = "$(SW_SMI_IO_ADDRESS)+1"
+ Help = "IO port used to generate software SMI."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PPI_OFFSET"
+ Value = "035h"
+ Help = "Ppi SMI Value"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SMIA"
+ Value = "$(TCGSMIPORT)"
+ Help = "Add a name of smiport for asl using"
+ TokenType = Integer
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "SMIB"
+ Value = "$(TCGSMIDATAPORT)"
+ Help = "Add a name of smiport for asl using"
+ TokenType = Integer
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "OFST"
+ Value = "$(PPI_OFFSET)"
+ Help = "Add a name of smiport for asl using"
+ TokenType = Integer
+ TargetASL = Yes
+End
+
+TOKEN
+ Name = "PARTIALLY_MEASURE_FVMAIN"
+ Value = "0"
+ Help = "Enable this token to make the TPM measure part of FVMAIN. This is useful to reduce the amount of time used for hashing FVMAIN."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_FV_MAIN_SIZE"
+ Value = "0x180000"
+ Help = "Size of FV_MAIN to Measure."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "PARTIALLY_MEASURE_FVMAIN" "=" "1"
+End
+
+TOKEN
+ Name = "TCG_CONVENTIONAL_BIOS_6_1"
+ Value = "1"
+ Help = "Enable this token to send the TcgStartup_DISABLE commmand if Bootmode is recovery"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_MOR"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TPM_PASSWORD_AUTHENTICATION"
+ Value = "0"
+ Help = "1 - If a pasword is set, it will be required for TPM state change. 0 - No password reqired."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CONFIRM_SETUP_CHANGE"
+ Value = "0"
+ Help = "1 - A Setup change to TPM State requires confirmation (same as OS change). 0 - Setup change not confirmed."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "LOG_EV_EFI_ACTION"
+ Value = "0"
+ Help = "Switch to LOG TPM events of type EV_ACTION"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_CLEAR_REQUEST_KEY"
+ Value = "SCAN_F12"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol. When you change the Key, Change the message string in the tcgstring.uni"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_CONFIGURATION_ACCEPT_KEY"
+ Value = "SCAN_F10"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol. When you change the Key, Change the message string in the tcgstring.uni"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_CONFIGURATION_IGNORE_KEY"
+ Value = "SCAN_ESC"
+ Help = "Set to one of the defined constants from EFI_SIMPLE_TEXT_INPUT protocol. When you change the Key, Change the message string in the tcgstring.uni"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DSDT_GUID"
+ Value = "{0x11D8AC35,0xFB8A,0x44d1,0x8D,0x09,0x0B,0x56,0x06,0xD3,0x21,0xB9}"
+ Help = "GUID for DSDT..PORTING...VERIFY VALUE MATCHES WITH ACTUAL DSDT_GUID"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+End
+
+TOKEN
+ Name = "MEMORY_ONLY_RESET_CONTROL_GUID"
+ Value = "{0xe20939be, 0x32d4, 0x41be, 0xa1, 0x50, 0x89, 0x7f, 0x85, 0xd4, 0x98, 0x29}"
+ Help = "Industry standard guid for MOR"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+End
+
+TOKEN
+ Name = "CRTM_GUID"
+ Value = "{0x546BFB1E,0x1D0C,0x4055,0xA4,0xAD,0x4E,0xF4,0xBF,0x17,0xB8,0x3A}"
+ Help = "GUID for CRTM..PORTING..."
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+End
+
+TOKEN
+ Name = "AMI_OS_PPI_CONFIRMATION_OVERRIDE_GUID"
+ Value = "{0x5f171f5f, 0x8385, 0x4086, 0xa6, 0x9b, 0x1f, 0xcf, 0x6, 0xae, 0x4a, 0x3d}"
+ Help = "GUID for Overriding TCG Physical Presence Locking"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+End
+
+TOKEN
+ Name = "AMI_BIOSPPI_FLAGS_MANAGEMENT_GUID"
+ Value = "{0xe9008d70, 0x2a4e, 0x47ea, 0x8e, 0xc4, 0x72, 0xe2, 0x57, 0x67, 0xe5, 0xef}"
+ Help = "GUID for OEM protocol to reading persistent BIOS TPM Management flags. See Ppi section 2 table 1"
+ TokenType = Expression
+ TargetH = Yes
+ Range = "GUID"
+End
+
+TOKEN
+ Name = "TRST"
+ Value = "2"
+ Help = "Platform transition for PPI request under O.S. 0: None 1: Shutdown 2: Reboot 3: OS Vendor Specific"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+ Range = "0 - 4"
+End
+
+TOKEN
+ Name = "TCG_PLATFORM_CLASS"
+ Value = "0"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_BIOS_TYPE_INTERFACE"
+ Value = "3"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_BIOS_TYPE_MAPPING"
+ Value = "2"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_SPEC_VERSION_MAJOR"
+ Value = "1"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_SPEC_VERSION_MINOR"
+ Value = "2"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TCG_SPEC_ERRATA"
+ Value = "1"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "AUTO_ACCEPT_PPI"
+ Value = "1"
+ Help = "Use this token for PreProduction WHCK TESTING. If Enabled PPi Requests will be automatically executed without use interaction"
+ TokenType = Boolean
+ TargetH = Yes
+END
+
+TOKEN
+ Name = "TCMF"
+ Value = "0"
+ Help = "TPM ASL update Variable"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TMF1"
+ Value = "0"
+ Help = "TPM ASL update Variable"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TMF2"
+ Value = "0"
+ Help = "TPM ASL update Variable"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TMF3"
+ Value = "0"
+ Help = "TPM ASL update Variable"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "tcgLibLite"
+ Value = "$(BUILD_DIR)\tcgLibLite.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "TTPF"
+ Value = "1"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TTDP"
+ Value = "0"
+ TokenType = Integer
+ TargetASL = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PTTHciSmm_SUPPORT"
+ Value = "0"
+ Help = " 1 - Send TPM startup and Selftest before Mem. 0 Send selftest and Startup After Mem Init"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "TCG_DIR"
+ Help = "Tcg Directory"
+End
+
+ELINK
+ Name = "PasswordAuthentication,"
+ Parent = "MinisetupDriverEntryHook,"
+ Token = "TPM_PASSWORD_AUTHENTICATION" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "/D PTT_FLAG"
+ Parent = "GLOBAL_DEFINES"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/TCG2/TisLib/INTTcgAcpi.h b/Core/EM/TCG2/TisLib/INTTcgAcpi.h
new file mode 100644
index 0000000..6ebcdc2
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/INTTcgAcpi.h
@@ -0,0 +1,114 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/INTTcgAcpi.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/INTTcgAcpi.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 2 5/19/10 5:24p Fredericko
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: INTTcgAcpi.h
+//
+// Description: Acpi definitions for TCG module
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCG_ACPI_3_0_H_
+#define _TCG_ACPI_3_0_H_
+
+
+#define EFI_ACPI_30_TABLE_GUID EFI_ACPI_20_TABLE_GUID
+
+extern EFI_GUID gEfiAcpiTableGuid;
+extern EFI_GUID gEfiAcpi20TableGuid;
+extern EFI_GUID gEfiAcpi30TableGuid;
+
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT32 Signature;
+ UINT32 Length;
+ UINT8 Revision;
+ UINT8 Checksum;
+ UINT8 OemId[6];
+ UINT64 OemTableId;
+ UINT32 OemRevision;
+ UINT32 CreatorId;
+ UINT32 CreatorRevision;
+} EFI_ACPI_DESCRIPTION_HEADER;
+
+
+//
+// "TCPA" Trusted Computing Platform Alliance Capabilities Table
+//
+#define\
+ EFI_ACPI_3_0_TRUSTED_COMPUTING_PLATFORM_ALLIANCE_CAPABILITIES_TABLE_SIGNATURE \
+ 0x41504354
+
+
+#pragma pack()
+
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
diff --git a/Core/EM/TCG2/TisLib/TcgCommon.c b/Core/EM/TCG2/TisLib/TcgCommon.c
new file mode 100644
index 0000000..922514a
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgCommon.c
@@ -0,0 +1,808 @@
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgCommon.c 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgCommon.c $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 3 3/17/14 3:04p Fredericko
+//
+// 2 3/11/14 6:00p Fredericko
+// [TAG] EIP151925
+// [Category] New Feature
+// [Description] Changes for TcgGeneric Regression Testing
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 12:34p Fredericko
+// Sha256 support policy update
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 9 3/19/12 6:13p Fredericko
+//
+// 8 3/29/11 12:24p Fredericko
+//
+// 7 3/28/11 12:12p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 6 5/19/10 5:07p Fredericko
+// Included File Header
+// Included File Revision History
+// Include \Updated AMI Function Headers
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgCommon.c
+
+ Abstract:
+
+ TCG Commands implemented for both PEI and DXE
+
+ --*/
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgCommon.c
+//
+// Description:
+// common TCG functions can be found here
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include "TcgCommon.h"
+#include <AmiDxeLib.h>
+#include "token.h"
+#include "Sha.h"
+
+#define TCG_EFI_HOB_LIST_GUID \
+ { 0x7739f24c, 0x93d7, 0x11d4, 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d}
+
+#pragma pack (1)
+typedef struct _TCG_PCR_EVENT_HDR2 {
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+} TCG_PCR_EVENT_HDR2;
+#pragma pack()
+
+UINT16
+__stdcall TcgCommonH2NS(
+ IN UINT16 Val )
+{
+ return TPM_H2NS( Val );
+}
+
+UINT32
+__stdcall TcgCommonH2NL(
+ IN UINT32 Val )
+{
+ return TPM_H2NL( Val );
+}
+
+
+
+VOID
+__stdcall TcgCommonCopyMem(
+ IN VOID *CallbackContext,
+ OUT VOID *Dest,
+ IN VOID *Src,
+ IN UINTN Size )
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+
+ if ( Src < Dest )
+ {
+ Destination8 = (CHAR8*) Dest + Size - 1;
+ Source8 = (CHAR8*) Src + Size - 1;
+ while ( Size-- )
+ {
+ *(Destination8--) = *(Source8--);
+ }
+ }
+ else {
+ Destination8 = (CHAR8*) Dest;
+ Source8 = (CHAR8*) Src;
+ while ( Size-- )
+ {
+ *(Destination8++) = *(Source8++);
+ }
+ }
+}
+
+
+#pragma optimize("",off)
+UINTN FindNextLogLocation(TCG_PCR_EVENT_HDR *TcgLog, UINTN EventNum)
+{
+ TCG_PCR_EVENT_HDR2 *TcgLogNext = (TCG_PCR_EVENT_HDR2 *)TcgLog;
+ UINTN NextLoc =0;
+ UINT32 EventSize=0;
+ UINTN i=0;
+
+ if(EventNum == 0) return ((UINTN) TcgLogNext);
+ //return the location of the next log
+ for(i=0;i<EventNum;i++){
+ if(TcgLogNext == NULL)break;
+ if(TcgLogNext->PCRIndex > 24 || TcgLogNext->PCRIndex < 0)
+ break;
+
+ EventSize = *(UINT32 *)(((UINTN)TcgLogNext) + TPM_SHA1_160_HASH_LEN + sizeof(TCG_PCR_EVENT_HDR2));
+ NextLoc = (UINTN)(((UINTN)TcgLogNext)+ EventSize + sizeof(EventSize)+\
+ + TPM_SHA1_160_HASH_LEN + sizeof(TCG_PCR_EVENT_HDR2));
+
+ TcgLogNext = (TCG_PCR_EVENT_HDR2 *)NextLoc;
+ }
+ return ((UINTN) TcgLogNext);
+}
+#pragma optimize("",on)
+
+
+EFI_STATUS
+__stdcall TcgCommonLogEvent(
+ IN VOID *CallbackContext,
+ IN TCG_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCG_PCR_EVENT *NewEntry,
+ IN UINT8 HashAlgorithm )
+{
+ UINT32 TempSize;
+
+ TempSize = sizeof(TCG_PCR_EVENT)-sizeof(NewEntry->Digest) - sizeof(UINT32)-1;
+ TcgCommonCopyMem( CallbackContext, EvtLog, NewEntry, TempSize );
+
+ if(HashAlgorithm == 0){
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->Digest.digest, sizeof(NewEntry->Digest.digest) );
+ TempSize+=sizeof(NewEntry->Digest.digest);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), (UINT8 *)&NewEntry->EventSize, sizeof(UINT32));
+ TempSize+=sizeof(UINT32);
+ TcgCommonCopyMem( CallbackContext, (((UINT8 *)EvtLog) + TempSize), NewEntry->Event, NewEntry->EventSize);
+ }
+ *TableSize += (TempSize + NewEntry->EventSize);
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+__stdcall TcmCommonLogEvent(
+ IN VOID *CallbackContext,
+ IN TCM_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCM_PCR_EVENT *NewEntry )
+{
+ UINT32 EvtSize;
+
+ EvtSize = NewEntry->EventSize + sizeof (*NewEntry) - 1;
+
+ if ( *TableSize + EvtSize > MaxSize )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ EvtLog = (TCM_PCR_EVENT*)((UINT8*)EvtLog + *TableSize);
+ TcgCommonCopyMem( CallbackContext, EvtLog, NewEntry, EvtSize );
+
+ *TableSize += EvtSize;
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgCommonSha1Start(
+ IN VOID *CallbackContext,
+ IN TCG_ALGORITHM_ID AlgId,
+ OUT UINT32 *MaxBytes )
+{
+ EFI_STATUS Status;
+ TPM_1_2_CMD_HEADER cmdSHA1Start = {
+ TPM_H2NS( TPM_TAG_RQU_COMMAND ),
+ TPM_H2NL( sizeof (TPM_1_2_CMD_HEADER)),
+ TPM_H2NL( TPM_ORD_SHA1Start )
+ };
+ TPM_1_2_RET_SHA1START retSHA1Start;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ if ( AlgId != TCG_ALG_SHA )
+ {
+ return EFI_UNSUPPORTED;
+ }
+
+ if(AutoSupportType()){
+ cmdSHA1Start.Ordinal = TPM_H2NL(TCM_ORD_SHA1Start);
+ }
+
+
+ InBuffer[0].Buffer = &cmdSHA1Start;
+ InBuffer[0].Size = sizeof (cmdSHA1Start);
+ OutBuffer[0].Buffer = &retSHA1Start;
+ OutBuffer[0].Size = sizeof (retSHA1Start);
+ Status = TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+
+ if ( EFI_ERROR( Status ) || retSHA1Start.Header.RetCode != 0 )
+ {
+ return Status;
+ }
+
+ if ( MaxBytes != NULL )
+ {
+ *MaxBytes = TcgCommonN2HL( retSHA1Start.MaxBytes );
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgCommonSha1Update(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN UINT32 MaxBytes )
+{
+ EFI_STATUS Status;
+ TPM_1_2_CMD_SHA1UPDATE cmdSHA1Update;
+ TPM_1_2_RET_HEADER retSHA1Update;
+ TPM_TRANSMIT_BUFFER InBuffer[2], OutBuffer[1];
+ UINT8 *DataPtr;
+
+ if ( DataLen < 64 )
+ {
+ return EFI_SUCCESS;
+ }
+
+ cmdSHA1Update.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdSHA1Update.Header.Ordinal = TPM_H2NL( TPM_ORD_SHA1Update );
+
+ if(AutoSupportType()){
+ cmdSHA1Update.Header.Ordinal = TPM_H2NL(TCM_ORD_SHA1Update);
+ }
+
+ InBuffer[0].Buffer = &cmdSHA1Update;
+ InBuffer[0].Size = sizeof (cmdSHA1Update);
+ OutBuffer[0].Buffer = &retSHA1Update;
+ OutBuffer[0].Size = sizeof (retSHA1Update);
+
+ DataPtr = (UINT8*)Data;
+
+ do
+ {
+ InBuffer[1].Buffer = DataPtr;
+ InBuffer[1].Size = DataLen < MaxBytes ? DataLen : MaxBytes;
+
+ cmdSHA1Update.NumBytes = TcgCommonH2NL((UINT32)InBuffer[1].Size );
+ cmdSHA1Update.Header.ParamSize = TcgCommonH2NL(
+ (UINT32)InBuffer[1].Size + sizeof (cmdSHA1Update)
+ );
+
+ DataPtr += InBuffer[1].Size;
+ DataLen -= (UINT32)InBuffer[1].Size;
+
+ Status = TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+ } while ( !EFI_ERROR( Status ) && DataLen >= 64 );
+
+ return Status;
+}
+
+
+
+EFI_STATUS
+__stdcall TcgCommonSha1CompleteExtend(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN TPM_PCRINDEX PCRIndex,
+ OUT TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_SHA1COMPLETEEXTEND cmdSHA1Complete;
+ TPM_1_2_RET_HEADER retSHA1Complete;
+ TPM_TRANSMIT_BUFFER InBuffer[2], OutBuffer[3];
+
+ if ( DataLen >= 64 )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ cmdSHA1Complete.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdSHA1Complete.Header.ParamSize = TcgCommonH2NL(sizeof(cmdSHA1Complete)
+ + DataLen);
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL( TPM_ORD_SHA1CompleteExtend );
+
+ if(AutoSupportType()){
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL(TCM_ORD_SHA1CompleteExtend);
+ }
+
+ cmdSHA1Complete.PCRIndex = TcgCommonH2NL( PCRIndex );
+ cmdSHA1Complete.NumBytes = TcgCommonH2NL( DataLen );
+
+ InBuffer[0].Buffer = &cmdSHA1Complete;
+ InBuffer[0].Size = sizeof (cmdSHA1Complete);
+ InBuffer[1].Buffer = Data;
+ InBuffer[1].Size = DataLen;
+
+ OutBuffer[0].Buffer = &retSHA1Complete;
+ OutBuffer[0].Size = sizeof (retSHA1Complete);
+ OutBuffer[1].Buffer = Digest;
+ OutBuffer[1].Size = sizeof (*Digest);
+ OutBuffer[2].Buffer = NewPCRValue;
+ OutBuffer[2].Size = sizeof (*NewPCRValue);
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+EFI_STATUS
+__stdcall TcmCommonSha1CompleteExtend(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN TPM_PCRINDEX PCRIndex,
+ OUT TCM_DIGEST *Digest,
+ OUT TCM_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_SHA1COMPLETEEXTEND cmdSHA1Complete;
+ TPM_1_2_RET_HEADER retSHA1Complete;
+ TPM_TRANSMIT_BUFFER InBuffer[2], OutBuffer[3];
+
+ if ( DataLen >= 64 )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ cmdSHA1Complete.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdSHA1Complete.Header.ParamSize = TcgCommonH2NL(sizeof(cmdSHA1Complete)
+ + DataLen);
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL( TPM_ORD_SHA1CompleteExtend );
+
+ if(AutoSupportType()){
+ cmdSHA1Complete.Header.Ordinal = TPM_H2NL(TCM_ORD_SHA1CompleteExtend);
+ }
+
+ cmdSHA1Complete.PCRIndex = TcgCommonH2NL( PCRIndex );
+ cmdSHA1Complete.NumBytes = TcgCommonH2NL( DataLen );
+
+ InBuffer[0].Buffer = &cmdSHA1Complete;
+ InBuffer[0].Size = sizeof (cmdSHA1Complete);
+ InBuffer[1].Buffer = Data;
+ InBuffer[1].Size = DataLen;
+
+ OutBuffer[0].Buffer = &retSHA1Complete;
+ OutBuffer[0].Size = sizeof (retSHA1Complete);
+ OutBuffer[1].Buffer = Digest;
+ OutBuffer[1].Size = sizeof (*Digest);
+ OutBuffer[2].Buffer = NewPCRValue;
+ OutBuffer[2].Size = sizeof (*NewPCRValue);
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+
+EFI_STATUS
+__stdcall TcmCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCM_DIGEST *Digest,
+ OUT TCM_DIGEST *NewPCRValue )
+{
+ TPM_1_2_CMD_HEADER cmdHeader;
+ TPM_1_2_RET_HEADER retHeader;
+ TPM_TRANSMIT_BUFFER InBuffer[3], OutBuffer[2];
+
+ InBuffer[0].Buffer = &cmdHeader;
+ InBuffer[0].Size = sizeof (cmdHeader);
+ InBuffer[1].Buffer = &PCRIndex;
+ InBuffer[1].Size = sizeof (PCRIndex);
+ InBuffer[2].Buffer = Digest->digest;
+ InBuffer[2].Size = sizeof (Digest->digest);
+
+ OutBuffer[0].Buffer = &retHeader;
+ OutBuffer[0].Size = sizeof (retHeader);
+ OutBuffer[1].Buffer = NewPCRValue->digest;
+ OutBuffer[1].Size = sizeof (NewPCRValue->digest);
+
+ cmdHeader.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdHeader.ParamSize = TPM_H2NL(sizeof (cmdHeader)
+ + sizeof (PCRIndex) + sizeof (Digest->digest));
+
+ cmdHeader.Ordinal = TPM_H2NL( TCM_ORD_Extend );
+ PCRIndex = TcgCommonH2NL( PCRIndex );
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+}
+
+
+EFI_STATUS
+__stdcall Tcg20CommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PcrIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue,
+ IN UINT8 DigestSize )
+{
+ TPM2_PCRExtend_cmd_t Cmd;
+ TPM2_PCRExtend_res_t Res;
+ TPM2_PCRExtend_res_t Tmpres;
+ UINT32 CmdSize;
+ UINT8 *Buffer;
+ UINT8 *AuthSizeOffset;
+ UINT8 *ResultBuf = NULL;
+ UINT32 ResultBufSize = 0;
+
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ Cmd.Tag = (TPMI_ST_COMMAND_TAG)TPM_H2NS(TPM_ST_SESSIONS);
+ Cmd.CommandSize = TPM_H2NL(sizeof(Cmd));
+ Cmd.CommandCode = TPM_H2NL(TPM_CC_PCR_Extend);
+
+ Buffer = (UINT8 *)&Cmd.inputParameters;
+ *(UINT32 *)Buffer = TPM_H2NL(PcrIndex);
+ Buffer += sizeof(UINT32);
+
+ AuthSizeOffset = Buffer;
+ *(UINT32 *)Buffer = 0;
+ Buffer += sizeof(UINT32);
+
+ // pcr authHandle
+ *(UINT32 *)Buffer = TPM_H2NL(TPM_RS_PW);
+ Buffer += sizeof(UINT32);
+
+ // nonce = nullNonce
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // sessionAttributes = 0
+ *(UINT8 *)Buffer = 0;
+ Buffer += sizeof(UINT8);
+
+ // auth = nullAuth
+ *(UINT16 *)Buffer = 0;
+ Buffer += sizeof(UINT16);
+
+ // authorizationSize
+ *(UINT32 *)AuthSizeOffset = TPM_H2NL((UINT32)(Buffer - AuthSizeOffset - sizeof(UINT32)));
+
+ //Digest count
+ *(UINT32 *)Buffer = TPM_H2NL(1);
+ Buffer += sizeof(UINT32);
+
+ //Hash alg
+ *(UINT16 *)Buffer = TPM_H2NS(TPM2_ALG_SHA1);
+ Buffer += sizeof(UINT16);
+
+ // Get the digest size based on Hash Alg
+ TcgCommonCopyMem(CallbackContext, Buffer, &Digest->digest, DigestSize);
+
+ Buffer += DigestSize;
+
+ CmdSize = (UINT32)(Buffer - (UINT8 *)&Cmd);
+ Cmd.CommandSize = TPM_H2NL(CmdSize);
+
+ ResultBuf = (UINT8 *) &Tmpres;
+ ResultBufSize = sizeof(Res);
+
+ InBuffer[0].Buffer = &Cmd;
+ InBuffer[0].Size = CmdSize;
+ OutBuffer[0].Buffer = ResultBuf;
+ OutBuffer[0].Size = ResultBufSize;
+
+ return TCGPASSTHROUGH( CallbackContext, InBuffer, OutBuffer );
+
+}
+
+
+
+
+EFI_STATUS
+__stdcall SHA1HashAll(
+ IN VOID *CallbackContext,
+ IN VOID *HashData,
+ IN UINTN HashDataLen,
+ OUT TCG_DIGEST *Digest
+)
+{
+ SHA1_CTX Sha1Ctx;
+ unsigned char DigestArray[20];
+
+ SHA1Init( &Sha1Ctx );
+
+ SHA1Update( &Sha1Ctx, HashData, (u32)HashDataLen );
+
+ SHA1Final( DigestArray, &Sha1Ctx );
+
+ TcgCommonCopyMem(
+ CallbackContext,
+ Digest->digest,
+ DigestArray,
+ sizeof (Digest->digest));
+
+ return EFI_SUCCESS;
+}
+
+
+/*
+EFI_STATUS
+__stdcall SHA2HashAll(
+ IN VOID *CallbackContext,
+ IN VOID *HashData,
+ IN UINTN HashDataLen,
+ OUT TCG_DIGEST *Digest
+)
+{
+ SHA2_CTX Sha2Ctx;
+ unsigned char DigestArray[32];
+
+ sha256_init( &Sha2Ctx );
+
+ sha256_process( &Sha2Ctx, HashData, (u32)HashDataLen );
+
+ sha256_done( &Sha2Ctx, DigestArray );
+
+ TcgCommonCopyMem(
+ CallbackContext,
+ Digest->digestSha2,
+ DigestArray,
+ sizeof (Digest->digestSha2));
+
+ return EFI_SUCCESS;
+}*/
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetHob
+//
+// Description: Find instance of a HOB type in a HOB list
+//
+// Input:
+// Type The HOB type to return.
+// HobStart The first HOB in the HOB list.
+//
+// Output:
+// Pointer to the Hob matching the type or NULL
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID* GetHob(
+ IN UINT16 Type,
+ IN VOID *HobStart )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+
+ Hob.Raw = HobStart;
+
+ //
+ // Return input if not found
+ //
+ if ( HobStart == NULL )
+ {
+ return HobStart;
+ }
+
+ //
+ // Parse the HOB list, stop if end of list or matching type found.
+ //
+ while ( !END_OF_HOB_LIST( Hob ))
+ {
+ if ( Hob.Header->HobType == Type )
+ {
+ break;
+ }
+
+ Hob.Raw = GET_NEXT_HOB( Hob );
+ }
+
+ //
+ // Return input if not found
+ //
+ if ( END_OF_HOB_LIST( Hob ))
+ {
+ return HobStart;
+ }
+
+ return (VOID*)(Hob.Raw);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: CompareGuid
+//
+// Description: Compares two input GUIDs
+//
+// Input: Comparision status
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+BOOLEAN CompareGuid(
+ EFI_GUID *G1,
+ EFI_GUID *G2 )
+{
+ UINT32 *p1 = (UINT32*)G1, *p2 = (UINT32*)G2;
+ UINTN i;
+
+ for ( i = 0; i < 4; ++i )
+ {
+ if ( p1[i] != p2[i] )
+ {
+ return FALSE;
+ }
+ }
+ return TRUE;
+ ;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: LocateATcgHob
+//
+// Description:
+//
+// Input:
+//
+// Output: None
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_GUID gEfiAmiTHobListGuid = TCG_EFI_HOB_LIST_GUID;
+VOID* LocateATcgHob(
+ UINTN NoTableEntries,
+ EFI_CONFIGURATION_TABLE *ConfigTable,
+ EFI_GUID *HOB_guid )
+{
+ VOID *HobStart;
+ VOID *PtrHob;
+
+ while ( NoTableEntries > 0 )
+ {
+ NoTableEntries--;
+
+ if ((!MemCmp(
+ &ConfigTable[NoTableEntries].VendorGuid,
+ &gEfiAmiTHobListGuid, sizeof(EFI_GUID)
+ )))
+ {
+ HobStart = ConfigTable[NoTableEntries].VendorTable;
+
+ if ( !EFI_ERROR(
+ GetNextGuidHob( &HobStart, HOB_guid, &PtrHob, NULL )
+ ))
+ {
+ return PtrHob;
+ }
+ }
+ }
+ return NULL;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetNextGuidHob
+//
+// Description: Find GUID HOB
+//
+// Input: HobStart A pointer to the start hob.
+// Guid A pointer to a guid.
+// Output:
+// Buffer A pointer to the buffer.
+// BufferSize Buffer size.
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS GetNextGuidHob(
+ IN OUT VOID **HobStart,
+ IN EFI_GUID * Guid,
+ OUT VOID **Buffer,
+ OUT UINTN *BufferSize OPTIONAL )
+{
+ EFI_STATUS Status;
+ EFI_PEI_HOB_POINTERS GuidHob;
+
+ if ( Buffer == NULL )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ for ( Status = EFI_NOT_FOUND; EFI_ERROR( Status );)
+ {
+ GuidHob.Raw = *HobStart;
+
+ if ( END_OF_HOB_LIST( GuidHob ))
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ GuidHob.Raw = GetHob( EFI_HOB_TYPE_GUID_EXTENSION, *HobStart );
+
+ if ( GuidHob.Header->HobType == EFI_HOB_TYPE_GUID_EXTENSION )
+ {
+ if ( CompareGuid( Guid, &GuidHob.Guid->Name ))
+ {
+ Status = EFI_SUCCESS;
+ *Buffer = (VOID*)((UINT8*)(&GuidHob.Guid->Name)
+ + sizeof (EFI_GUID));
+
+ if ( BufferSize != NULL )
+ {
+ *BufferSize = GuidHob.Header->HobLength
+ - sizeof (EFI_HOB_GUID_TYPE);
+ }
+ }
+ }
+
+ *HobStart = GET_NEXT_HOB( GuidHob );
+ }
+
+ return Status;
+}
diff --git a/Core/EM/TCG2/TisLib/TcgCommon.h b/Core/EM/TCG2/TisLib/TcgCommon.h
new file mode 100644
index 0000000..4565f79
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgCommon.h
@@ -0,0 +1,305 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TcgCommon.h
+
+ Abstract:
+
+ Header file for TcgCommon.c
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgCommon.h 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgCommon.h $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 12:32p Fredericko
+// Sha256 support policy update
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 13 3/19/12 6:14p Fredericko
+//
+// 12 3/29/11 12:24p Fredericko
+//
+// 11 3/28/11 12:18p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 10 5/19/10 5:10p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgCommon.h
+//
+// Description:
+// Header file for TcgCommon.c
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCG_COMMON_H_
+#define _TCG_COMMON_H_
+
+#include <Efi.h>
+#include "TcgPc.h"
+#include "TcgEfiTpm.h"
+#include "Sha.h"
+#include <HOB.h>
+#include "..\Common\Tpm20Includes\Tpm20.h"
+//#include "TcgMisc.h"
+
+#define TcgCommonN2HS( v16 ) TcgCommonH2NS( v16 )
+#define TcgCommonN2HL( v32 ) TcgCommonH2NL( v32 )
+#define EFI_TPL_DRIVER 6
+#define EFI_TPL_APPLICATION 4
+#define EFI_TPL_CALLBACK 8
+#define EFI_TPL_NOTIFY 16
+#define EFI_TPL_HIGH_LEVEL 31
+#define STRING_TOKEN( x ) x
+
+
+#define GET_HOB_TYPE( Hob ) ((Hob).Header->HobType)
+#define GET_HOB_LENGTH( Hob ) ((Hob).Header->HobLength)
+#define GET_NEXT_HOB( Hob ) ((Hob).Raw + GET_HOB_LENGTH( Hob ))
+#define END_OF_HOB_LIST( Hob ) (GET_HOB_TYPE( Hob ) ==\
+ EFI_HOB_TYPE_END_OF_HOB_LIST)
+
+#define TCGPASSTHROUGH( cb, in, out ) \
+ TcgCommonPassThrough( \
+ cb, \
+ sizeof (in) / sizeof (*(in)), \
+ (in), \
+ sizeof (out) / sizeof (*(out)), \
+ (out) \
+ )
+
+
+extern
+UINT16
+__stdcall TcgCommonH2NS (
+ IN UINT16 Val );
+
+extern
+UINT32
+__stdcall TcgCommonH2NL (
+ IN UINT32 Val );
+
+VOID* GetHob (
+ IN UINT16 Type,
+ IN VOID *HobStart );
+
+BOOLEAN CompareGuid (
+ EFI_GUID *G1,
+ EFI_GUID *G2 );
+
+EFI_STATUS GetNextGuidHob (
+ IN OUT VOID **HobStart,
+ IN EFI_GUID * Guid,
+ OUT VOID **Buffer,
+ OUT UINTN*BufferSize OPTIONAL );
+
+extern
+EFI_STATUS
+__stdcall TcgCommonPassThrough (
+ IN VOID *CallbackContext,
+ IN UINT32 NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINT32 NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers );
+
+extern
+VOID
+__stdcall TcgCommonCopyMem (
+ IN VOID *CallbackContext,
+ OUT VOID *Dest,
+ IN VOID *Src,
+ IN UINTN Len );
+
+extern
+EFI_STATUS
+__stdcall TcgCommonLogEvent(
+ IN VOID *CallbackContext,
+ IN TCG_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCG_PCR_EVENT *NewEntry,
+ IN UINT8 HashAlgorithm );
+
+extern
+EFI_STATUS
+__stdcall TcmCommonLogEvent (
+ IN VOID *CallbackContext,
+ IN TCM_PCR_EVENT *EvtLog,
+ IN OUT UINT32 *TableSize,
+ IN UINT32 MaxSize,
+ IN TCM_PCR_EVENT *NewEntry );
+
+extern
+EFI_STATUS
+__stdcall TcgCommonSha1Start (
+ IN VOID *CallbackContext,
+ IN TCG_ALGORITHM_ID AlgId,
+ OUT UINT32 *MaxBytes );
+
+extern
+EFI_STATUS
+__stdcall TcgCommonSha1Update (
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN UINT32 MaxBytes );
+
+extern
+EFI_STATUS
+__stdcall TcgCommonSha1CompleteExtend (
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN TPM_PCRINDEX PCRIndex,
+ OUT TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue );
+
+
+EFI_STATUS
+__stdcall TcmCommonSha1CompleteExtend(
+ IN VOID *CallbackContext,
+ IN VOID *Data,
+ IN UINT32 DataLen,
+ IN TPM_PCRINDEX PCRIndex,
+ OUT TCM_DIGEST *Digest,
+ OUT TCM_DIGEST *NewPCRValue );
+
+extern
+EFI_STATUS
+__stdcall TcgCommonExtend (
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCG_DIGEST *Digest,
+ OUT TCG_DIGEST *NewPCRValue );
+
+EFI_STATUS
+__stdcall TcmCommonExtend(
+ IN VOID *CallbackContext,
+ IN TPM_PCRINDEX PCRIndex,
+ IN TCM_DIGEST *Digest,
+ OUT TCM_DIGEST *NewPCRValue );
+
+extern
+EFI_STATUS
+__stdcall SHA1HashAll (
+ IN VOID *CallbackContext,
+ IN VOID *HashData,
+ IN UINTN HashDataLen,
+ OUT TCG_DIGEST *Digest
+ );
+
+EFI_STATUS
+__stdcall SHA2HashAll(
+ IN VOID *CallbackContext,
+ IN VOID *HashData,
+ IN UINTN HashDataLen,
+ OUT TCG_DIGEST *Digest
+ );
+
+EFI_STATUS EfiLibGetSystemConfigurationTable(
+ IN EFI_GUID *TableGuid,
+ IN OUT VOID **Table );
+
+#pragma pack(push,1)
+
+typedef union {
+ UINT8 sha1[SHA1_DIGEST_SIZE];
+ UINT8 sha256[SHA256_DIGEST_SIZE];
+} TPM_COMM_DIGEST_UNION;
+
+typedef struct{
+ UINT16 HashAlgId;
+ TPM_COMM_DIGEST_UNION Digest;
+}TPM_COMM_DIGEST;
+
+#define HASH_ALG_COUNT 2
+
+typedef struct {
+ UINT32 Count;
+ TPM_COMM_DIGEST Digests[HASH_ALG_COUNT];
+}TPM_COMM_DIGEST_LIST;
+
+typedef struct {
+ TPMI_DH_PCR pcrHandle;
+ TPM_COMM_DIGEST_LIST DigestValue;
+} PCR_Extend_In;
+
+typedef struct {
+ TPMI_ST_COMMAND_TAG Tag;
+ UINT32 CommandSize;
+ TPM_CC CommandCode;
+ PCR_Extend_In inputParameters;
+ UINT32 authorizationSize;
+ TPMS_AUTH_SESSION_COMMAND pwapAuth;
+} TPM2_PCRExtend_cmd_t;
+
+typedef struct {
+ TPMI_ST_COMMAND_TAG Tag;
+ UINT32 RespondSize;
+ TPM_RC ResponseCode;
+ UINT32 parameterSize;
+ TPMS_AUTH_SESSION_RESPONSE pwapAuth;
+} TPM2_PCRExtend_res_t;
+
+
+#pragma pack(pop)
+
+extern
+BOOLEAN
+__stdcall AutoSupportType (
+ );
+
+#endif
diff --git a/Core/EM/TCG2/TisLib/TcgEFI12.h b/Core/EM/TCG2/TisLib/TcgEFI12.h
new file mode 100644
index 0000000..9ecfa92
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgEFI12.h
@@ -0,0 +1,186 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TpmEfi.h
+
+ Abstract:
+
+ This file contains definitions of structures for TPM and TCG
+ protocols/ppis.
+
+ --*/
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgEFI12.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgEFI12.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 2 5/19/10 5:22p Fredericko
+//
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgEFI12.h
+//
+// Description:
+// Contains Industry Standard structures for TCG
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCGEFI_H_
+#define _TCGEFI_H_
+
+#include "TcgTpm12.h"
+#include "TcgPc.h"
+
+#define _TPM_NTH_BIT( x ) (1 << (x))
+#define _TPM_STRUCT_PARTIAL_SIZE( type, field ) \
+ ((UINTN)&(((type*)0)->field))
+
+#pragma pack (push)
+#pragma pack (1)
+
+//
+// TCG_PCClientEventStructure
+//
+#pragma pack (pop)
+
+//
+// Per the EFI Implementation
+//
+typedef TPM_DIGEST TCG_DIGEST;
+
+//
+// TPM_TRANSMIT_BUFFER used by TCG services
+//
+typedef struct _TPM_TRANSMIT_BUFFER
+{
+ VOID *Buffer;
+ UINTN Size;
+} TPM_TRANSMIT_BUFFER;
+
+//
+// Definitons of TPM commands
+//
+
+#pragma pack (push)
+#pragma pack (1)
+
+typedef struct _TPM_1_2_CMD_HEADER
+{
+ TPM_TAG Tag;
+ UINT32 ParamSize;
+ TPM_COMMAND_CODE Ordinal;
+} TPM_1_2_CMD_HEADER;
+
+typedef struct _TPM_1_2_RET_HEADER
+{
+ TPM_TAG Tag;
+ UINT32 ParamSize;
+ TPM_RESULT RetCode;
+} TPM_1_2_RET_HEADER;
+
+//
+// TPM_Startup
+//
+
+typedef struct _TPM_1_2_CMD_STARTUP
+{
+ TPM_1_2_CMD_HEADER Header;
+ TPM_STARTUP_TYPE StartupType;
+} TPM_1_2_CMD_STARTUP;
+
+//
+// TPM_SHA1Start
+//
+
+typedef struct _TPM_1_2_RET_SHA1START
+{
+ TPM_1_2_RET_HEADER Header;
+ UINT32 MaxBytes;
+} TPM_1_2_RET_SHA1START;
+
+//
+// TPM_SHA1Update
+//
+
+typedef struct _TPM_1_2_CMD_SHA1UPDATE
+{
+ TPM_1_2_CMD_HEADER Header;
+ UINT32 NumBytes;
+} TPM_1_2_CMD_SHA1UPDATE;
+
+//
+// TPM_SHA1Complete
+//
+
+typedef TPM_1_2_CMD_SHA1UPDATE TPM_1_2_CMD_SHA1COMPLETE;
+
+typedef struct _TPM_1_2_RET_SHA1COMPLETE
+{
+ TPM_1_2_CMD_HEADER Header;
+ TCG_DIGEST Digest;
+} TPM_1_2_RET_SHA1COMPLETE;
+
+//
+// TPM_SHA1CompleteExtend
+//
+
+typedef struct _TPM_1_2_CMD_SHA1COMPLETEEXTEND
+{
+ TPM_1_2_CMD_HEADER Header;
+ TPM_PCRINDEX PCRIndex;
+ UINT32 NumBytes;
+} TPM_1_2_CMD_SHA1COMPLETEEXTEND;
+
+#pragma pack (pop)
+
+#endif // _TCGEFI_H_
diff --git a/Core/EM/TCG2/TisLib/TcgEfiTpm.h b/Core/EM/TCG2/TisLib/TcgEfiTpm.h
new file mode 100644
index 0000000..3639048
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgEfiTpm.h
@@ -0,0 +1,220 @@
+/*++
+
+ Copyright (c) 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Module Name:
+
+ EfiTpm.h
+
+ Abstract:
+
+ EFI definition according to TCG_EFI_Platform_1_20_Final
+
+ See http://trustedcomputinggroup.org for latest specification updates
+
+ --*/
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgEfiTpm.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgEfiTpm.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 5 11/17/11 2:28p Fredericko
+// [TAG] EIP75882
+// [Category] New Feature
+// [Description] Measurement of Secureboot variables PK, KEK, DB, DBX
+// and the EFI_Image_Execution_tables
+// [Files] TcgEfiTpm.h
+// AmitcgPlatform.sdl
+// AmiTcgPlatformDxe.c
+// AmiTcgPlatformDxe.h
+//
+// 4 5/19/10 5:24p Fredericko
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgTpm12.h
+//
+// Description:
+// Contains Industry Standard #defines and structures for TCG
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _EFI_TPM_H_
+#define _EFI_TPM_H_
+
+#include <EFI.h>
+
+//
+// The start of TPM return codes
+//
+#define TPM_BASE (EFI_MAX_BIT + (EFI_MAX_BIT >> 1))
+#include "TcgTpm12.h"
+
+//
+// Standard event types
+//
+#define EV_POST_CODE ((TCG_EVENTTYPE) 0x00000001)
+#define EV_SEPARATOR ((TCG_EVENTTYPE) 0x00000004)
+#define EV_S_CRTM_CONTENTS ((TCG_EVENTTYPE) 0x00000007)
+#define EV_S_CRTM_VERSION ((TCG_EVENTTYPE) 0x00000008)
+
+//
+// EFI specific event types
+//
+#define EV_EFI_EVENT_BASE ((TCG_EVENTTYPE) 0x80000000)
+#define EV_EFI_VARIABLE_DRIVER_CONFIG (EV_EFI_EVENT_BASE + 1)
+#define EV_EFI_VARIABLE_BOOT (EV_EFI_EVENT_BASE + 2)
+#define EV_EFI_BOOT_SERVICES_APPLICATION (EV_EFI_EVENT_BASE + 3)
+#define EV_EFI_BOOT_SERVICES_DRIVER (EV_EFI_EVENT_BASE + 4)
+#define EV_EFI_RUNTIME_SERVICES_DRIVER (EV_EFI_EVENT_BASE + 5)
+#define EV_EFI_GPT_EVENT (EV_EFI_EVENT_BASE + 6)
+#define EV_EFI_ACTION (EV_EFI_EVENT_BASE + 7)
+#define EV_EFI_PLATFORM_FIRMWARE_BLOB (EV_EFI_EVENT_BASE + 8)
+#define EV_EFI_HANDOFF_TABLES (EV_EFI_EVENT_BASE + 9)
+#define EV_EFI_SETUP_MODE (EV_EFI_EVENT_BASE + 0x0a)
+#define EV_EFI_PLATFORM_KEY (EV_EFI_EVENT_BASE + 0x0b)
+#define EV_EFI_KEY_EXCHANGE_KEY (EV_EFI_EVENT_BASE + 0x0c)
+#define EV_EFI_AUTHORIZED_DB (EV_EFI_EVENT_BASE + 0x0d)
+#define EV_EFI_FORBIDDEN_DBX (EV_EFI_EVENT_BASE + 0x0e)
+#define EV_EFI_EXECUTION_INFO_TABLE (EV_EFI_EVENT_BASE + 0x0f)
+
+
+//
+// Set structure alignment to 1-byte
+//
+#pragma pack (push, 1)
+
+typedef UINT32 TCG_EVENTTYPE;
+
+#define TCG_DIGEST TPM_DIGEST
+#define TCG_PCRINDEX TPM_PCRINDEX
+
+//
+// TCG_PCR_EVENT
+//
+typedef struct tdTCG_PCR_EVENT
+{
+ TCG_PCRINDEX PCRIndex; // PCRIndex event extended to
+ TCG_EVENTTYPE EventType; // TCG EFI event type
+ TCG_DIGEST Digest; // Value extended into PCRIndex
+ UINT32 EventSize; // Size of the event data
+ UINT8 Event[1]; // The event data
+} TCG_PCR_EVENT;
+
+//
+// TCG_PCR_EVENT_HDR
+//
+typedef struct tdTCG_PCR_EVENT_HDR
+{
+ TCG_PCRINDEX PCRIndex;
+ TCG_EVENTTYPE EventType;
+ TCG_DIGEST Digest;
+ UINT32 EventSize;
+} TCG_PCR_EVENT_HDR;
+
+//
+// EFI_PLATFORM_FIRMWARE_BLOB
+//
+// BlobLength should be of type UINTN but we use UINT64 here
+// because PEI is 32-bit while DXE is 64-bit on x64 platforms
+//
+typedef struct tdEFI_PLATFORM_FIRMWARE_BLOB
+{
+ EFI_PHYSICAL_ADDRESS BlobBase;
+ UINT64 BlobLength;
+} EFI_PLATFORM_FIRMWARE_BLOB;
+
+//
+// EFI_IMAGE_LOAD_EVENT
+//
+// This structure is used in EV_EFI_BOOT_SERVICES_APPLICATION,
+// EV_EFI_BOOT_SERVICES_DRIVER and EV_EFI_RUNTIME_SERVICES_DRIVER
+//
+typedef struct tdEFI_IMAGE_LOAD_EVENT
+{
+ EFI_PHYSICAL_ADDRESS ImageLocationInMemory;
+ UINTN ImageLengthInMemory;
+ UINTN ImageLinkTimeAddress;
+ UINTN LengthOfDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL DevicePath[1];
+} EFI_IMAGE_LOAD_EVENT;
+
+//
+// EFI_HANDOFF_TABLE_POINTERS
+//
+// This structure is used in EV_EFI_HANDOFF_TABLES event to facilitate
+// the measurement of given configuration tables.
+//
+typedef struct tdEFI_HANDOFF_TABLE_POINTERS
+{
+ UINTN NumberOfTables;
+ EFI_CONFIGURATION_TABLE TableEntry[1];
+} EFI_HANDOFF_TABLE_POINTERS;
+
+//
+// EFI_VARIABLE_DATA
+//
+// This structure serves as the header for measuring variables. The name of the
+// variable (in Unicode format) should immediately follow, then the variable
+// data.
+//
+typedef struct tdEFI_VARIABLE_DATA
+{
+ EFI_GUID VariableName;
+ UINTN UnicodeNameLength;
+ UINTN VariableDataLength;
+ CHAR16 UnicodeName[1];
+ INT8 VariableData[1]; // Driver or platform-specific data
+} EFI_VARIABLE_DATA;
+
+//
+// Restore original structure alignment
+//
+#pragma pack (pop)
+
+#endif // _EFI_TPM_H_
diff --git a/Core/EM/TCG2/TisLib/TcgPc.h b/Core/EM/TCG2/TisLib/TcgPc.h
new file mode 100644
index 0000000..18b1a43
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgPc.h
@@ -0,0 +1,311 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TpmDev.h
+
+ Abstract:
+
+ Header file for tpm device drivers
+
+ --*/
+
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgPc.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgPc.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 4 3/29/11 12:26p Fredericko
+//
+// 3 3/28/11 12:27p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 2 5/19/10 5:23p Fredericko
+//
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgPc.h
+//
+// Description:
+// Contains Industry Standard #defines and Structures for TCG
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TPMPC_H_
+#define _TPMPC_H_
+
+#include "TcgEfi12.h"
+#include "INTTcgAcpi.h"
+#include "TcmPc.h"
+
+#pragma pack (push)
+#pragma pack (1)
+
+typedef struct _TPM_1_2_REGISTERS
+{
+ UINT8 Access; // 0
+ UINT8 Reserved1[7]; // 1
+ UINT32 IntEnable; // 8
+ UINT8 IntVector; // 0ch
+ UINT8 Reserved2[3]; // 0dh
+ UINT32 IntSts; // 10h
+ UINT32 IntfCapability; // 14h
+ UINT8 Sts; // 18h
+ UINT16 BurstCount; // 19h
+ UINT8 Reserved3[9];
+ UINT32 DataFifo; // 24h
+ UINT8 Reserved4[0xed8]; // 28h
+ UINT16 Vid; // 0f00h
+ UINT16 Did; // 0f02h
+ UINT8 Rid; // 0f04h
+ UINT8 TcgDefined[0x7b]; // 0f05h
+ UINT32 LegacyAddress1; // 0f80h
+ UINT32 LegacyAddress1Ex; // 0f84h
+ UINT32 LegacyAddress2; // 0f88h
+ UINT32 LegacyAddress2Ex; // 0f8ch
+ UINT8 VendorDefined[0x70]; // 0f90h
+} TPM_1_2_REGISTERS;
+
+typedef struct _TCG_ACPI_TABLE
+{
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT16 Reserved;
+ UINT32 LogMaxLength;
+ EFI_PHYSICAL_ADDRESS LogStart;
+} TCG_ACPI_TABLE;
+
+//
+// Trusted Computing Platform Alliance Capabilities Table (TCPA)
+//
+typedef struct
+{
+ EFI_ACPI_DESCRIPTION_HEADER Header;
+ UINT16 Reserved;
+ UINT32 LogAreaMaxLength;
+ UINT64 LogAreaStartAddress;
+} EFI_ACPI_TCPA_CAPABILITIES_TABLE;
+
+#pragma pack (pop)
+
+typedef volatile TPM_1_2_REGISTERS *TPM_1_2_REGISTERS_PTR;
+
+#define TPM_ACC_VALID _TPM_NTH_BIT( 7 )
+#define TPM_ACC_ACTIVE_LOCALITY _TPM_NTH_BIT( 5 )
+#define TPM_ACC_BEEN_SEIZED _TPM_NTH_BIT( 4 )
+#define TPM_ACC_SEIZE _TPM_NTH_BIT( 3 )
+#define TPM_ACC_PENDING_REQUEST _TPM_NTH_BIT( 2 )
+#define TPM_ACC_REQUEST_USE _TPM_NTH_BIT( 1 )
+#define TPM_ACC_ESTABLISHMENT _TPM_NTH_BIT( 0 )
+
+#define TPM_STS_VALID _TPM_NTH_BIT( 7 )
+#define TPM_STS_READY _TPM_NTH_BIT( 6 )
+#define TPM_STS_GO _TPM_NTH_BIT( 5 )
+#define TPM_STS_DATA_AVAILABLE _TPM_NTH_BIT( 4 )
+#define TPM_STS_EXPECT _TPM_NTH_BIT( 3 )
+#define TPM_STS_RESPONSE_RETRY _TPM_NTH_BIT( 1 )
+
+#define TPM_BASE_ADDRESS 0xFED40000
+
+#define TPM_H2NS( x ) \
+ (((UINT16)(x) << 8) | ((UINT16)(x) >> 8))
+#define TPM_H2NL( x ) \
+ (UINT32)((((UINT32)(x)) >> 24) \
+ | (((x) >> 8) & 0xff00) \
+ | ((x) << 24) \
+ | (((x) & 0xff00) << 8))
+
+#define TPM_N2HS( x ) TPM_H2NS( x )
+#define TPM_N2HL( x ) TPM_H2NL( x )
+
+//
+// PCR Usage
+//
+#define PCRi_CRTM_AND_POST_BIOS 0
+#define PCRi_HOST_PLATFORM_CONFIG 1
+#define PCRi_OPROM_CODE 2
+#define PCRi_OPROM_CONFIG_AND_DATA 3
+#define PCRi_IPL_CODE 4
+#define PCRi_IPL_CONFIG_AND_DATA 5
+#define PCRi_STATE_TRANSITION 6
+#define PCRi_HOST_PLATFORM_MANUFACTURER_CONTROL 7
+
+//
+// TCG Event Logs
+//
+#define TPM_LOG_AREA_MAX_LEN 0x10000
+
+//
+// TCG Event Types
+//
+#define EV_PREBOOT_CERT 0
+#define EV_UNUSED 2
+#define EV_NO_ACTION 3
+#define EV_ACTION 5
+#define EV_EVENT_TAG 6
+#define EV_CPU_MICROCODE 9
+#define EV_PLATFORM_CONFIG_FLAGS 10
+#define EV_TABLE_OF_DEVICES 11
+#define EV_COMPACT_HASH 12
+#define EV_IPL 13
+#define EV_IPL_PARTITION_DATA 14
+#define EV_NONHOST_CODE 15
+#define EV_NONHOST_CONFIG 16
+
+//
+// TCG Event IDs
+//
+#define EV_ID_NULL 0
+#define EV_ID_SMBIOS_RECORD 1
+#define EV_ID_BIS_CERTIFICATE 2
+#define EV_ID_POST_BIOS_STRING 3
+#define EV_ID_ESCD 4
+#define EV_ID_RAW_CMOS 5
+#define EV_ID_RAW_NVRAM 6
+#define EV_ID_OPROM_EXECUTE 7
+#define EV_ID_OPROM_CONFIG 8
+#define EV_ID_OPROM_MICROCODE_UPDATE 9
+
+#pragma pack (push)
+#pragma pack (1)
+
+//
+// _EFI_TCG_EV_S_CRTM_VERSION
+//
+struct _EFI_TCG_EV_S_CRTM_VERSION
+{
+ EFI_GUID VersionGuid;
+};
+
+//
+// _EFI_TCG_EV_POST_CODE
+//
+struct _EFI_TCG_EV_POST_CODE
+{
+ EFI_PHYSICAL_ADDRESS PostCodeAddress;
+ UINT64 PostCodeLength;
+};
+
+//
+// _EFI_TCG_EV_TAG_OPTION_ROM_EXECUTE
+//
+struct _EFI_TCG_EV_TAG_OPTION_ROM_EXECUTE
+{
+ UINT16 Reserved;
+ UINT16 PFA;
+ TCG_DIGEST Hash;
+};
+
+//
+// _EFI_TCG_EV_CPU_MICROCODE
+//
+struct _EFI_TCG_EV_CPU_MICROCODE
+{
+ EFI_PHYSICAL_ADDRESS MicrocodeEntrypoint;
+};
+
+//
+// _EFI_TCG_EV_TAG_EVENT_DATA
+//
+union _EFI_TCG_EV_TAG_EVENT_DATA
+{
+ struct _EFI_TCG_EV_TAG_OPTION_ROM_EXECUTE
+ OptionRomExecute;
+};
+
+//
+// _EFI_TCG_EV_TAG
+//
+struct _EFI_TCG_EV_TAG
+{
+ UINT32 EventID;
+ UINT32 EventSize;
+ union _EFI_TCG_EV_TAG_EVENT_DATA EventData;
+};
+
+//
+// EFI_TCG_PCR_EVENT_HEADER
+//
+typedef struct _EFI_TCG_PCR_EVENT_HEADER
+{
+ TPM_PCRINDEX PCRIndex;
+ UINT32 EventType;
+ TCG_DIGEST Digest;
+ UINT32 EventDataSize;
+} EFI_TCG_PCR_EVENT_HEADER;
+
+//
+// EFI_TCG_PCR_EVENT_DATA
+//
+typedef union _EFI_TCG_PCR_EVENT_DATA
+{
+ struct _EFI_TCG_EV_S_CRTM_VERSION SCrtmVersion;
+ struct _EFI_TCG_EV_POST_CODE PostCode;
+ struct _EFI_TCG_EV_TAG Tagged;
+ struct _EFI_TCG_EV_CPU_MICROCODE Mcu;
+} EFI_TCG_PCR_EVENT_DATA;
+
+//
+// EFI_TCG_PCR_EVENT
+// equivalent to TCG_PCR_EVENT in the TCG PC Client Spec
+//
+typedef struct _EFI_TCG_PCR_EVENT
+{
+ EFI_TCG_PCR_EVENT_HEADER Header;
+ EFI_TCG_PCR_EVENT_DATA Event;
+} EFI_TCG_PCR_EVENT;
+
+#pragma pack (pop)
+
+#endif // _TPMPC_H_
diff --git a/Core/EM/TCG2/TisLib/TcgTpm12.h b/Core/EM/TCG2/TisLib/TcgTpm12.h
new file mode 100644
index 0000000..c20668c
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcgTpm12.h
@@ -0,0 +1,1973 @@
+/*++
+
+ Copyright (c) 2005 - 2006, Intel Corporation
+ All rights reserved. This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ Module Name:
+
+ Tpm12.h
+
+ Abstract:
+
+ TPM Specification data structures (TCG TPM Specification Version 1.2 Revision 94)
+
+ See http://trustedcomputinggroup.org for latest specification updates
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgTpm12.h 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcgTpm12.h $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 2 3/17/14 3:03p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 12:32p Fredericko
+// Sha256 support policy update
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 6 3/29/11 12:25p Fredericko
+//
+// 5 3/28/11 12:25p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 4 5/19/10 5:21p Fredericko
+// Included File Header
+// Included File Revision History
+// Code Beautification
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcgTpm12.h
+//
+// Description:
+// Contains Industry Standard #defines for TCG
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TPM12_H_
+#define _TPM12_H_
+
+#include "token.h"
+#include "ZTEICTcmOrdinals.h"
+
+//
+// Structures are all packed on 1-byte alignment
+//
+
+#pragma pack (push)
+#pragma pack (1)
+
+//
+// Part 2, section 2.2: Basic types & Helper redefinitions
+//
+typedef UINT8 TPM_AUTH_DATA_USAGE;
+typedef UINT8 TPM_PAYLOAD_TYPE;
+typedef UINT8 TPM_VERSION_BYTE;
+typedef UINT16 TPM_TAG;
+typedef UINT16 TPM_PROTOCOL_ID;
+typedef UINT16 TPM_STARTUP_TYPE;
+typedef UINT16 TPM_ENC_SCHEME;
+typedef UINT16 TPM_SIG_SCHEME;
+typedef UINT16 TPM_MIGRATE_SCHEME;
+typedef UINT16 TPM_PHYSICAL_PRESENCE;
+typedef UINT16 TPM_ENTITY_TYPE;
+typedef UINT16 TPM_KEY_USAGE;
+typedef UINT16 TPM_EK_TYPE;
+typedef UINT16 TPM_STRUCTURE_TAG;
+typedef UINT16 TPM_PLATFORM_SPECIFIC;
+typedef UINT32 TPM_COMMAND_CODE;
+typedef UINT32 TPM_CAPABILITY_AREA;
+typedef UINT32 TPM_KEY_FLAGS;
+typedef UINT32 TPM_ALGORITHM_ID;
+typedef UINT32 TPM_MODIFIER_INDICATOR;
+typedef UINT32 TPM_ACTUAL_COUNT;
+typedef UINT32 TPM_TRANSPORT_ATTRIBUTES;
+typedef UINT32 TPM_AUTHHANDLE;
+typedef UINT32 TPM_DIRINDEX;
+typedef UINT32 TPM_KEY_HANDLE;
+typedef UINT32 TPM_PCRINDEX;
+typedef UINT32 TPM_RESULT;
+typedef UINT32 TPM_RESOURCE_TYPE;
+typedef UINT32 TPM_KEY_CONTROL;
+typedef UINT32 TPM_NV_INDEX;
+typedef UINT32 TPM_FAMILY_ID;
+typedef UINT32 TPM_FAMILY_VERIFICATION;
+typedef UINT32 TPM_STARTUP_EFFECTS;
+typedef UINT32 TPM_SYM_MODE;
+typedef UINT32 TPM_FAMILY_FLAGS;
+typedef UINT32 TPM_DELEGATE_INDEX;
+typedef UINT32 TPM_CMK_DELEGATE;
+typedef UINT32 TPM_COUNT_ID;
+typedef UINT32 TPM_REDIT_COMMAND;
+typedef UINT32 TPM_TRANSHANDLE;
+typedef UINT32 TPM_HANDLE;
+typedef UINT32 TPM_FAMILY_OPERATION;
+
+//
+// Part 2, section 2.2.4: Vendor specific
+// The following defines allow for the quick specification of a
+// vendor specific item.
+//
+#define TPM_Vendor_Specific32 ((UINT32) 0x00000400)
+#define TPM_Vendor_Specific8 ((UINT8) 0x80)
+
+//
+// Part 2, section 3.1: Structure TAGs
+//
+#define TPM_TAG_CONTEXTBLOB ((TPM_STRUCTURE_TAG) 0x0001)
+#define TPM_TAG_CONTEXT_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0002)
+#define TPM_TAG_CONTEXTPOINTER ((TPM_STRUCTURE_TAG) 0x0003)
+#define TPM_TAG_CONTEXTLIST ((TPM_STRUCTURE_TAG) 0x0004)
+#define TPM_TAG_SIGNINFO ((TPM_STRUCTURE_TAG) 0x0005)
+#define TPM_TAG_PCR_INFO_LONG ((TPM_STRUCTURE_TAG) 0x0006)
+#define TPM_TAG_PERSISTENT_FLAGS ((TPM_STRUCTURE_TAG) 0x0007)
+#define TPM_TAG_VOLATILE_FLAGS ((TPM_STRUCTURE_TAG) 0x0008)
+#define TPM_TAG_PERSISTENT_DATA ((TPM_STRUCTURE_TAG) 0x0009)
+#define TPM_TAG_VOLATILE_DATA ((TPM_STRUCTURE_TAG) 0x000A)
+#define TPM_TAG_SV_DATA ((TPM_STRUCTURE_TAG) 0x000B)
+#define TPM_TAG_EK_BLOB ((TPM_STRUCTURE_TAG) 0x000C)
+#define TPM_TAG_EK_BLOB_AUTH ((TPM_STRUCTURE_TAG) 0x000D)
+#define TPM_TAG_COUNTER_VALUE ((TPM_STRUCTURE_TAG) 0x000E)
+#define TPM_TAG_TRANSPORT_INTERNAL ((TPM_STRUCTURE_TAG) 0x000F)
+#define TPM_TAG_TRANSPORT_LOG_IN ((TPM_STRUCTURE_TAG) 0x0010)
+#define TPM_TAG_TRANSPORT_LOG_OUT ((TPM_STRUCTURE_TAG) 0x0011)
+#define TPM_TAG_AUDIT_EVENT_IN ((TPM_STRUCTURE_TAG) 0x0012)
+#define TPM_TAG_AUDIT_EVENT_OUT ((TPM_STRUCTURE_TAG) 0x0013)
+#define TPM_TAG_CURRENT_TICKS ((TPM_STRUCTURE_TAG) 0x0014)
+#define TPM_TAG_KEY ((TPM_STRUCTURE_TAG) 0x0015)
+#define TPM_TAG_STORED_DATA12 ((TPM_STRUCTURE_TAG) 0x0016)
+#define TPM_TAG_NV_ATTRIBUTES ((TPM_STRUCTURE_TAG) 0x0017)
+#define TPM_TAG_NV_DATA_PUBLIC ((TPM_STRUCTURE_TAG) 0x0018)
+#define TPM_TAG_NV_DATA_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0019)
+#define TPM_TAG_DELEGATIONS ((TPM_STRUCTURE_TAG) 0x001A)
+#define TPM_TAG_DELEGATE_PUBLIC ((TPM_STRUCTURE_TAG) 0x001B)
+#define TPM_TAG_DELEGATE_TABLE_ROW ((TPM_STRUCTURE_TAG) 0x001C)
+#define TPM_TAG_TRANSPORT_AUTH ((TPM_STRUCTURE_TAG) 0x001D)
+#define TPM_TAG_TRANSPORT_PUBLIC ((TPM_STRUCTURE_TAG) 0x001E)
+#define TPM_TAG_PERMANENT_FLAGS ((TPM_STRUCTURE_TAG) 0x001F)
+#define TPM_TAG_STCLEAR_FLAGS ((TPM_STRUCTURE_TAG) 0x0020)
+#define TPM_TAG_STANY_FLAGS ((TPM_STRUCTURE_TAG) 0x0021)
+#define TPM_TAG_PERMANENT_DATA ((TPM_STRUCTURE_TAG) 0x0022)
+#define TPM_TAG_STCLEAR_DATA ((TPM_STRUCTURE_TAG) 0x0023)
+#define TPM_TAG_STANY_DATA ((TPM_STRUCTURE_TAG) 0x0024)
+#define TPM_TAG_FAMILY_TABLE_ENTRY ((TPM_STRUCTURE_TAG) 0x0025)
+#define TPM_TAG_DELEGATE_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0026)
+#define TPM_TAG_DELG_KEY_BLOB ((TPM_STRUCTURE_TAG) 0x0027)
+#define TPM_TAG_KEY12 ((TPM_STRUCTURE_TAG) 0x0028)
+#define TPM_TAG_CERTIFY_INFO2 ((TPM_STRUCTURE_TAG) 0x0029)
+#define TPM_TAG_DELEGATE_OWNER_BLOB ((TPM_STRUCTURE_TAG) 0x002A)
+#define TPM_TAG_EK_BLOB_ACTIVATE ((TPM_STRUCTURE_TAG) 0x002B)
+#define TPM_TAG_DAA_BLOB ((TPM_STRUCTURE_TAG) 0x002C)
+#define TPM_TAG_DAA_CONTEXT ((TPM_STRUCTURE_TAG) 0x002D)
+#define TPM_TAG_DAA_ENFORCE ((TPM_STRUCTURE_TAG) 0x002E)
+#define TPM_TAG_DAA_ISSUER ((TPM_STRUCTURE_TAG) 0x002F)
+#define TPM_TAG_CAP_VERSION_INFO ((TPM_STRUCTURE_TAG) 0x0030)
+#define TPM_TAG_DAA_SENSITIVE ((TPM_STRUCTURE_TAG) 0x0031)
+#define TPM_TAG_DAA_TPM ((TPM_STRUCTURE_TAG) 0x0032)
+#define TPM_TAG_CMK_MIGAUTH ((TPM_STRUCTURE_TAG) 0x0033)
+#define TPM_TAG_CMK_SIGTICKET ((TPM_STRUCTURE_TAG) 0x0034)
+#define TPM_TAG_CMK_MA_APPROVAL ((TPM_STRUCTURE_TAG) 0x0035)
+#define TPM_TAG_QUOTE_INFO2 ((TPM_STRUCTURE_TAG) 0x0036)
+
+//
+// Part 2, section 4: TPM Types
+//
+
+//
+// Part 2, section 4.1: TPM_RESOURCE_TYPE
+//
+#define TPM_RT_KEY ((TPM_RESOURCE_TYPE) 0x00000001) // The handle is a key handle and is the result of a LoadKey type operation
+#define TPM_RT_AUTH ((TPM_RESOURCE_TYPE) 0x00000002) // The handle is an authorization handle. Auth handles come from TPM_OIAP, TPM_OSAP and TPM_DSAP
+#define TPM_RT_HASH ((TPM_RESOURCE_TYPE) 0x00000003) // Reserved for hashes
+#define TPM_RT_TRANS ((TPM_RESOURCE_TYPE) 0x00000004) // The handle is for a transport session. Transport handles come from TPM_EstablishTransport
+#define TPM_RT_CONTEXT ((TPM_RESOURCE_TYPE) 0x00000005) // Resource wrapped and held outside the TPM using the context save/restore commands
+#define TPM_RT_COUNTER ((TPM_RESOURCE_TYPE) 0x00000006) // Reserved for counters
+#define TPM_RT_DELEGATE ((TPM_RESOURCE_TYPE) 0x00000007) // The handle is for a delegate row. These are the internal rows held in NV storage by the TPM
+#define TPM_RT_DAA_TPM ((TPM_RESOURCE_TYPE) 0x00000008) // The value is a DAA TPM specific blob
+#define TPM_RT_DAA_V0 ((TPM_RESOURCE_TYPE) 0x00000009) // The value is a DAA V0 parameter
+#define TPM_RT_DAA_V1 ((TPM_RESOURCE_TYPE) 0x0000000A) // The value is a DAA V1 parameter
+
+//
+// Part 2, section 4.2: TPM_PAYLOAD_TYPE
+//
+#define TPM_PT_ASYM ((TPM_PAYLOAD_TYPE) 0x01) // The entity is an asymmetric key
+#define TPM_PT_BIND ((TPM_PAYLOAD_TYPE) 0x02) // The entity is bound data
+#define TPM_PT_MIGRATE ((TPM_PAYLOAD_TYPE) 0x03) // The entity is a migration blob
+#define TPM_PT_MAINT ((TPM_PAYLOAD_TYPE) 0x04) // The entity is a maintenance blob
+#define TPM_PT_SEAL ((TPM_PAYLOAD_TYPE) 0x05) // The entity is sealed data
+#define TPM_PT_MIGRATE_RESTRICTED ((TPM_PAYLOAD_TYPE) 0x06) // The entity is a restricted-migration asymmetric key
+#define TPM_PT_MIGRATE_EXTERNAL ((TPM_PAYLOAD_TYPE) 0x07) // The entity is a external migratable key
+#define TPM_PT_CMK_MIGRATE ((TPM_PAYLOAD_TYPE) 0x08) // The entity is a CMK migratable blob
+#define TPM_PT_VENDOR_SPECIFIC ((TPM_PAYLOAD_TYPE) 0x80) // 0x80 - 0xFF Vendor specific payloads
+
+//
+// Part 2, section 4.3: TPM_ENTIRY_TYPE
+//
+#define TPM_ET_KEYHANDLE ((UINT16) 0x0001) // The entity is a keyHandle or key
+#define TPM_ET_OWNER ((UINT16) 0x0002) // The entity is the TPM Owner
+#define TPM_ET_DATA ((UINT16) 0x0003) // The entity is some data
+#define TPM_ET_SRK ((UINT16) 0x0004) // The entity is the SRK
+#define TPM_ET_KEY ((UINT16) 0x0005) // The entity is a key or keyHandle
+#define TPM_ET_REVOKE ((UINT16) 0x0006) // The entity is the RevokeTrust value
+#define TPM_ET_DEL_OWNER_BLOB ((UINT16) 0x0007) // The entity is a delegate owner blob
+#define TPM_ET_DEL_ROW ((UINT16) 0x0008) // The entity is a delegate row
+#define TPM_ET_DEL_KEY_BLOB ((UINT16) 0x0009) // The entity is a delegate key blob
+#define TPM_ET_COUNTER ((UINT16) 0x000A) // The entity is a counter
+#define TPM_ET_NV ((UINT16) 0x000B) // The entity is a NV index
+#define TPM_ET_RESERVED_HANDLE ((UINT16) 0x0040) // Reserved. This value avoids collisions with the handle MSB setting.
+//
+// TPM_ENTITY_TYPE MSB Values: The MSB is used to indicate the ADIP encryption sheme when applicable
+//
+#define TPM_ET_XOR ((UINT16) 0x0000) // ADIP encryption scheme: XOR
+#define TPM_ET_AES128 ((UINT16) 0x0006) // ADIP encryption scheme: AES 128 bits
+
+//
+// Part 2, section 4.4.1: Reserved Key Handles
+//
+#define TPM_KH_SRK ((TPM_KEY_HANDLE) 0x40000000) // The handle points to the SRK
+#define TPM_KH_OWNER ((TPM_KEY_HANDLE) 0x40000001) // The handle points to the TPM Owner
+#define TPM_KH_REVOKE ((TPM_KEY_HANDLE) 0x40000002) // The handle points to the RevokeTrust value
+#define TPM_KH_TRANSPORT ((TPM_KEY_HANDLE) 0x40000003) // The handle points to the EstablishTransport static authorization
+#define TPM_KH_OPERATOR ((TPM_KEY_HANDLE) 0x40000004) // The handle points to the Operator auth
+#define TPM_KH_ADMIN ((TPM_KEY_HANDLE) 0x40000005) // The handle points to the delegation administration auth
+#define TPM_KH_EK ((TPM_KEY_HANDLE) 0x40000006) // The handle points to the PUBEK, only usable with TPM_OwnerReadInternalPub
+
+//
+// Part 2, section 4.5: TPM_STARTUP_TYPE
+//
+#define TPM_ST_CLEAR ((TPM_STARTUP_TYPE) 0x0001) // The TPM is starting up from a clean state
+#define TPM_ST_STATE ((TPM_STARTUP_TYPE) 0x0002) // The TPM is starting up from a saved state
+#define TPM_ST_DEACTIVATED ((TPM_STARTUP_TYPE) 0x0003) // The TPM is to startup and set the deactivated flag to TRUE
+
+//
+// Part 2, section 4.6: TPM_STATUP_EFFECTS
+// The table makeup is still an open issue.
+//
+
+//
+// Part 2, section 4.7: TPM_PROTOCOL_ID
+//
+#define TPM_PID_OIAP ((TPM_PROTOCOL_ID) 0x0001) // The OIAP protocol.
+#define TPM_PID_OSAP ((TPM_PROTOCOL_ID) 0x0002) // The OSAP protocol.
+#define TPM_PID_ADIP ((TPM_PROTOCOL_ID) 0x0003) // The ADIP protocol.
+#define TPM_PID_ADCP ((TPM_PROTOCOL_ID) 0x0004) // The ADCP protocol.
+#define TPM_PID_OWNER ((TPM_PROTOCOL_ID) 0x0005) // The protocol for taking ownership of a TPM.
+#define TPM_PID_DSAP ((TPM_PROTOCOL_ID) 0x0006) // The DSAP protocol
+#define TPM_PID_TRANSPORT ((TPM_PROTOCOL_ID) 0x0007) // The transport protocol
+
+//
+// Part 2, section 4.8: TPM_ALGORITHM_ID
+// The TPM MUST support the algorithms TPM_ALG_RSA, TPM_ALG_SHA, TPM_ALG_HMAC,
+// TPM_ALG_MGF1
+//
+#define TPM_ALG_RSA ((TPM_ALGORITHM_ID) 0x00000001) // The RSA algorithm.
+#define TPM_ALG_DES ((TPM_ALGORITHM_ID) 0x00000002) // The DES algorithm
+#define TPM_ALG_3DES ((TPM_ALGORITHM_ID) 0x00000003) // The 3DES algorithm in EDE mode
+#define TPM_ALG_SHA ((TPM_ALGORITHM_ID) 0x00000004) // The SHA1 algorithm
+#define TPM_ALG_HMAC ((TPM_ALGORITHM_ID) 0x00000005) // The RFC 2104 HMAC algorithm
+#define TPM_ALG_AES128 ((TPM_ALGORITHM_ID) 0x00000006) // The AES algorithm, key size 128
+#define TPM_ALG_MGF1 ((TPM_ALGORITHM_ID) 0x00000007) // The XOR algorithm using MGF1 to create a string the size of the encrypted block
+#define TPM_ALG_AES192 ((TPM_ALGORITHM_ID) 0x00000008) // AES, key size 192
+#define TPM_ALG_AES256 ((TPM_ALGORITHM_ID) 0x00000009) // AES, key size 256
+#define TPM_ALG_XOR ((TPM_ALGORITHM_ID) 0x0000000A) // XOR using the rolling nonces
+
+//
+// Part 2, section 4.9: TPM_PHYSICAL_PRESENCE
+//
+#define TPM_PHYSICAL_PRESENCE_HW_DISABLE ((TPM_PHYSICAL_PRESENCE) 0x0200) // Sets the physicalPresenceHWEnable to FALSE
+#define TPM_PHYSICAL_PRESENCE_CMD_DISABLE ((TPM_PHYSICAL_PRESENCE) 0x0100) // Sets the physicalPresenceCMDEnable to FALSE
+#define TPM_PHYSICAL_PRESENCE_LIFETIME_LOCK ((TPM_PHYSICAL_PRESENCE) 0x0080) // Sets the physicalPresenceLifetimeLock to TRUE
+#define TPM_PHYSICAL_PRESENCE_HW_ENABLE ((TPM_PHYSICAL_PRESENCE) 0x0040) // Sets the physicalPresenceHWEnable to TRUE
+#define TPM_PHYSICAL_PRESENCE_CMD_ENABLE ((TPM_PHYSICAL_PRESENCE) 0x0020) // Sets the physicalPresenceCMDEnable to TRUE
+#define TPM_PHYSICAL_PRESENCE_NOTPRESENT ((TPM_PHYSICAL_PRESENCE) 0x0010) // Sets PhysicalPresence = FALSE
+#define TPM_PHYSICAL_PRESENCE_PRESENT ((TPM_PHYSICAL_PRESENCE) 0x0008) // Sets PhysicalPresence = TRUE
+#define TPM_PHYSICAL_PRESENCE_LOCK ((TPM_PHYSICAL_PRESENCE) 0x0004) // Sets PhysicalPresenceLock = TRUE
+
+//
+// Part 2, section 4.10: TPM_MIGRATE_SCHEME
+//
+#define TPM_MS_MIGRATE ((TPM_MIGRATE_SCHEME) 0x0001) // A public key that can be used with all TPM migration commands other than 'ReWrap' mode.
+#define TPM_MS_REWRAP ((TPM_MIGRATE_SCHEME) 0x0002) // A public key that can be used for the ReWrap mode of TPM_CreateMigrationBlob.
+#define TPM_MS_MAINT ((TPM_MIGRATE_SCHEME) 0x0003) // A public key that can be used for the Maintenance commands
+#define TPM_MS_RESTRICT_MIGRATE ((TPM_MIGRATE_SCHEME) 0x0004) // The key is to be migrated to a Migration Authority.
+#define TPM_MS_RESTRICT_APPROVE_DOUBLE ((TPM_MIGRATE_SCHEME) 0x0005) // The key is to be migrated to an entity approved by a Migration Authority using double wrapping
+
+//
+// Part 2, section 4.11: TPM_EK_TYPE
+//
+#define TPM_EK_TYPE_ACTIVATE ((TPM_EK_TYPE) 0x0001) // The blob MUST be TPM_EK_BLOB_ACTIVATE
+#define TPM_EK_TYPE_AUTH ((TPM_EK_TYPE) 0x0002) // The blob MUST be TPM_EK_BLOB_AUTH
+
+//
+// Part 2, section 4.12: TPM_PLATFORM_SPECIFIC
+//
+#define TPM_PS_PC_11 ((TPM_PLATFORM_SPECIFIC) 0x0001) // PC Specific version 1.1
+#define TPM_PS_PC_12 ((TPM_PLATFORM_SPECIFIC) 0x0002) // PC Specific version 1.2
+#define TPM_PS_PDA_12 ((TPM_PLATFORM_SPECIFIC) 0x0003) // PDA Specific version 1.2
+#define TPM_PS_Server_12 ((TPM_PLATFORM_SPECIFIC) 0x0004) // Server Specific version 1.2
+#define TPM_PS_Mobile_12 ((TPM_PLATFORM_SPECIFIC) 0x0005) // Mobil Specific version 1.2
+
+//
+// Part 2, section 5: Basic Structures
+//
+
+//
+// Part 2, section 5.1: TPM_STRUCT_VER
+//
+typedef struct tdTPM_STRUCT_VER
+{
+ UINT8 major;
+ UINT8 minor;
+ UINT8 revMajor;
+ UINT8 revMinor;
+} TPM_STRUCT_VER;
+
+//
+// Part 2, section 5.3: TPM_VERSION
+//
+typedef struct tdTPM_VERSION
+{
+ TPM_VERSION_BYTE major;
+ TPM_VERSION_BYTE minor;
+ UINT8 revMajor;
+ UINT8 revMinor;
+} TPM_VERSION;
+
+
+//
+// Part 2, section 5.4: TPM_DIGEST
+//
+#define TPM_SHA1_160_HASH_LEN 0x14
+#define TPM_SHA1BASED_NONCE_LEN TPM_SHA1_160_HASH_LEN
+
+#define TPM_SHA2_256_HASH_LEN 0x20
+#define TPM_SHA2BASED_NONCE_LEN TPM_SHA2_256_HASH_LEN
+
+
+//redefine TPM digest into a UNION so that we can support
+//sha1 and sha2 and other has functions at the same time
+typedef struct tdTPM_DIGEST
+{
+ UINT8 digest[TPM_SHA1_160_HASH_LEN];
+} TPM_DIGEST;
+
+typedef struct tdTCM_DIGEST
+{
+ UINT8 digest[TPM_SHA2BASED_NONCE_LEN];
+} TCM_DIGEST;
+
+
+typedef TPM_DIGEST TPM_CHOSENID_HASH; // This SHALL be the digest of the chosen identityLabel and privacyCA for a new TPM identity.
+typedef TPM_DIGEST TPM_COMPOSITE_HASH; // This SHALL be the hash of a list of PCR indexes and PCR values that a key or data is bound to.
+typedef TPM_DIGEST TPM_DIRVALUE; // This SHALL be the value of a DIR register
+typedef TPM_DIGEST TPM_HMAC;
+typedef TPM_DIGEST TPM_PCRVALUE; // The value inside of the PCR
+typedef TPM_DIGEST TPM_AUDITDIGEST; // This SHALL be the value of the current internal audit state
+typedef TPM_DIGEST TPM_DAA_TPM_SEED; // This SHALL be a random value generated by a TPM immediately after the EK is installed in that TPM, whenever an EK is installed in that TPM
+typedef TPM_DIGEST TPM_DAA_CONTEXT_SEED; // This SHALL be a random value
+
+//
+// Part 2, section 5.5: TPM_NONCE
+//
+typedef struct tdTPM_NONCE
+{
+ UINT8 nonce[20];
+} TPM_NONCE;
+
+//
+// Part 2, section 5.6: TPM_AUTHDATA
+//
+typedef UINT8 tdTPM_AUTHDATA[20];
+typedef tdTPM_AUTHDATA TPM_AUTHDATA;
+typedef TPM_AUTHDATA TPM_SECRET;
+typedef TPM_AUTHDATA TPM_ENCAUTH;
+
+//
+// Part 2, section 5.7: TPM_KEY_HANDLE_LIST
+// Size of handle is loaded * sizeof(TPM_KEY_HANDLE)
+//
+typedef struct tdTPM_KEY_HANDLE_LIST
+{
+ UINT16 loaded;
+ TPM_KEY_HANDLE handle[1];
+} TPM_KEY_HANDLE_LIST;
+
+//
+// Part 2, section 5.8: TPM_KEY_USAGE values
+//
+
+#define TPM_KEY_SIGNING ((UINT16) 0x0010)
+// TPM_KEY_SIGNING SHALL indicate a signing key. The [private] key SHALL be
+// used for signing operations, only. This means that it MUST be a leaf of the
+// Protected Storage key hierarchy.
+
+#define TPM_KEY_STORAGE ((UINT16) 0x0011)
+// TPM_KEY_STORAGE SHALL indicate a storage key. The key SHALL be used to wrap
+// and unwrap other keys in the Protected Storage hierarchy
+
+#define TPM_KEY_IDENTITY ((UINT16) 0x0012)
+// TPM_KEY_IDENTITY SHALL indicate an identity key. The key SHALL be used for
+// operations that require a TPM identity, only.
+
+#define TPM_KEY_AUTHCHANGE ((UINT16) 0x0013)
+// TPM_KEY_AUTHCHANGE SHALL indicate an ephemeral key that is in use during
+// the ChangeAuthAsym process, only.
+
+#define TPM_KEY_BIND ((UINT16) 0x0014)
+// TPM_KEY_BIND SHALL indicate a key that can be used for TPM_Bind and
+// TPM_Unbind operations only.
+
+#define TPM_KEY_LEGACY ((UINT16) 0x0015)
+// TPM_KEY_LEGACY SHALL indicate a key that can perform signing and binding
+// operations. The key MAY be used for both signing and binding operations.
+// The TPM_KEY_LEGACY key type is to allow for use by applications where both
+// signing and encryption operations occur with the same key. The use of this
+// key type is not recommended TPM_KEY_MIGRATE 0x0016 This SHALL indicate a
+// key in use for TPM_MigrateKey
+
+#define TPM_KEY_MIGRATE ((UINT16) 0x0016)
+// TPM_KEY_MIGRAGE SHALL indicate a key in use for TPM_MigrateKey
+
+//
+// Part 2, section 5.8.1: Encryption/Signature schemes
+//
+
+#define TPM_ES_NONE ((TPM_ENC_SCHEME) 0x0001)
+#define TPM_ES_RSAESPKCSv15 ((TPM_ENC_SCHEME) 0x0002)
+#define TPM_ES_RSAESOAEP_SHA1_MGF1 ((TPM_ENC_SCHEME) 0x0003)
+#define TPM_ES_SYM_CNT ((TPM_ENC_SCHEME) 0x0004)
+#define TPM_ES_SYM_OFB ((TPM_ENC_SCHEME) 0x0005)
+
+#define TPM_SS_NONE ((TPM_SIG_SCHEME) 0x0001)
+#define TPM_SS_RSASSAPKCS1v15_SHA1 ((TPM_SIG_SCHEME) 0x0002)
+#define TPM_SS_RSASSAPKCS1v15_DER ((TPM_SIG_SCHEME) 0x0003)
+#define TPM_SS_RSASSAPKCS1v15_INFO ((TPM_SIG_SCHEME) 0x0004)
+
+//
+// Part 2, section 5.9: TPM_AUTH_DATA_USAGE values
+//
+#define TPM_AUTH_NEVER ((TPM_AUTH_DATA_USAGE) 0x00)
+#define TPM_AUTH_ALWAYS ((TPM_AUTH_DATA_USAGE) 0x01)
+#define TPM_AUTH_PRIV_USE_ONLY ((TPM_AUTH_DATA_USAGE) 0x03)
+
+//
+// Part 2, section 5.10: TPM_KEY_FLAGS
+//
+enum tdTPM_KEY_FLAGS
+{
+ redirection = 0x00000001,
+ migratable = 0x00000002,
+ isVolatile = 0x00000004,
+ pcrIgnoredOnRead = 0x00000008,
+ migrateAuthority = 0x00000010
+};
+
+//
+// Part 2, section 5.11: TPM_CHANGEAUTH_VALIDATE
+//
+typedef struct tdTPM_CHANGEAUTH_VALIDATE
+{
+ TPM_SECRET newAuthSecret;
+ TPM_NONCE n1;
+} TPM_CHANGEAUTH_VALIDATE;
+
+//
+// Part 2, section 5.12: TPM_MIGRATIONKEYAUTH
+// decalared after section 10 to catch declaration of TPM_PUBKEY
+//
+// Part 2 section 10.1: TPM_KEY_PARMS
+// [size_is(parmSize)] BYTE* parms;
+//
+typedef struct tdTPM_KEY_PARMS
+{
+ TPM_ALGORITHM_ID algorithmID;
+ TPM_ENC_SCHEME encScheme;
+ TPM_SIG_SCHEME sigScheme;
+ UINT32 parmSize;
+ UINT8 *parms;
+} TPM_KEY_PARMS;
+
+//
+// Part 2, section 10.4: TPM_STORE_PUBKEY
+//
+typedef struct tdTPM_STORE_PUBKEY
+{
+ UINT32 keyLength;
+ UINT8 key[1];
+} TPM_STORE_PUBKEY;
+
+//
+// Part 2, section 10.5: TPM_PUBKEY
+//
+typedef struct tdTPM_PUBKEY
+{
+ TPM_KEY_PARMS algorithmParms;
+ TPM_STORE_PUBKEY pubKey;
+} TPM_PUBKEY;
+
+//
+// Part 2, section 5.12: TPM_MIGRATIONKEYAUTH
+//
+typedef struct tdTPM_MIGRATIONKEYAUTH
+{
+ TPM_PUBKEY migrationKey;
+ TPM_MIGRATE_SCHEME migrationScheme;
+ TPM_DIGEST digest;
+} TPM_MIGRATIONKEYAUTH;
+
+//
+// Part 2, section 5.13: TPM_COUNTER_VALUE
+//
+typedef struct tdTPM_COUNTER_VALUE
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT8 label[4];
+ TPM_ACTUAL_COUNT counter;
+} TPM_COUNTER_VALUE;
+
+//
+// Part 2, section 5.14: TPM_SIGN_INFO
+// Size of data indicated by dataLen
+//
+typedef struct tdTPM_SIGN_INFO
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT8 fixed[4];
+ TPM_NONCE replay;
+ UINT32 dataLen;
+ UINT8 *data;
+} TPM_SIGN_INFO;
+
+//
+// Part 2, section 5.15: TPM_MSA_COMPOSITE
+// Number of migAuthDigest indicated by MSAlist
+//
+typedef struct tdTPM_MSA_COMPOSITE
+{
+ UINT32 MSAlist;
+ TPM_DIGEST migAuthDigest[1];
+} TPM_MSA_COMPOSITE;
+
+//
+// Part 2, section 5.16: TPM_CMK_AUTH
+//
+typedef struct tdTPM_CMK_AUTH
+{
+ TPM_DIGEST migrationAuthorityDigest;
+ TPM_DIGEST destinationKeyDigest;
+ TPM_DIGEST sourceKeyDigest;
+} TPM_CMK_AUTH;
+
+//
+// Part 2, section 5.17: TPM_CMK_DELEGATE
+//
+#define TPM_CMK_DELEGATE_SIGNING (((TPM_CMK_DELEGATE)1) << 31)
+#define TPM_CMK_DELEGATE_STORAGE (((TPM_CMK_DELEGATE)1) << 30)
+#define TPM_CMK_DELEGATE_BIND (((TPM_CMK_DELEGATE)1) << 29)
+#define TPM_CMK_DELEGATE_LEGACY (((TPM_CMK_DELEGATE)1) << 28)
+#define TPM_CMK_DELEGATE_MIGRATE (((TPM_CMK_DELEGATE)1) << 27)
+
+//
+// Part 2, section 5.18: TPM_SELECT_SIZE
+//
+typedef struct tdTPM_SELECT_SIZE
+{
+ UINT8 major;
+ UINT8 minor;
+ UINT16 reqSize;
+} TPM_SELECT_SIZE;
+
+//
+// Part 2, section 5,19: TPM_CMK_MIGAUTH
+//
+typedef struct tdTPM_CMK_MIGAUTH
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST msaDigest;
+ TPM_DIGEST pubKeyDigest;
+} TPM_CMK_MIGAUTH;
+
+//
+// Part 2, section 5.20: TPM_CMK_SIGTICKET
+//
+typedef struct tdTPM_CMK_SIGTICKET
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST verKeyDigest;
+ TPM_DIGEST signedData;
+} TPM_CMK_SIGTICKET;
+
+//
+// Part 2, section 5.21: TPM_CMK_MA_APPROVAL
+//
+typedef struct tdTPM_CMK_MA_APPROVAL
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST migrationAuthorityDigest;
+} TPM_CMK_MA_APPROVAL;
+
+//
+// Part 2, section 6: Command Tags
+//
+#define TPM_TAG_RQU_COMMAND ((TPM_STRUCTURE_TAG) 0x00C1)
+#define TPM_TAG_RQU_AUTH1_COMMAND ((TPM_STRUCTURE_TAG) 0x00C2)
+#define TPM_TAG_RQU_AUTH2_COMMAND ((TPM_STRUCTURE_TAG) 0x00C3)
+#define TPM_TAG_RSP_COMMAND ((TPM_STRUCTURE_TAG) 0x00C4)
+#define TPM_TAG_RSP_AUTH1_COMMAND ((TPM_STRUCTURE_TAG) 0x00C5)
+#define TPM_TAG_RSP_AUTH2_COMMAND ((TPM_STRUCTURE_TAG) 0x00C6)
+
+//
+// Part 2, section 7.1: TPM_PERMANENT_FLAGS
+//
+typedef struct tdTPM_PERMANENT_FLAGS
+{
+ TPM_STRUCTURE_TAG tag;
+ BOOLEAN disable;
+ BOOLEAN ownership;
+ BOOLEAN deactivated;
+ BOOLEAN readPubek;
+ BOOLEAN disableOwnerClear;
+ BOOLEAN allowMaintenance;
+ BOOLEAN physicalPresenceLifetimeLock;
+ BOOLEAN physicalPresenceHWEnable;
+ BOOLEAN physicalPresenceCMDEnable;
+ BOOLEAN CEKPUsed;
+ BOOLEAN TPMpost;
+ BOOLEAN TPMpostLock;
+ BOOLEAN FIPS;
+ BOOLEAN operator;
+ BOOLEAN enableRevokeEK;
+ BOOLEAN nvLocked;
+ BOOLEAN readSRKPub;
+ BOOLEAN tpmEstablished;
+ BOOLEAN maintenanceDone;
+} TPM_PERMANENT_FLAGS;
+
+//
+// Part 2, section 7.1.1: PERMANENT_FLAGS Subcap for SetCapability
+//
+#define TPM_PF_DISABLE ((TPM_CAPABILITY_AREA) 1)
+#define TPM_PF_OWNERSHIP ((TPM_CAPABILITY_AREA) 2)
+#define TPM_PF_DEACTIVATED ((TPM_CAPABILITY_AREA) 3)
+#define TPM_PF_READPUBEK ((TPM_CAPABILITY_AREA) 4)
+#define TPM_PF_DISABLEOWNERCLEAR ((TPM_CAPABILITY_AREA) 5)
+#define TPM_PF_ALLOWMAINTENANCE ((TPM_CAPABILITY_AREA) 6)
+#define TPM_PF_PHYSICALPRESENCELIFETIMELOCK ((TPM_CAPABILITY_AREA) 7)
+#define TPM_PF_PHYSICALPRESENCEHWENABLE ((TPM_CAPABILITY_AREA) 8)
+#define TPM_PF_PHYSICALPRESENCECMDENABLE ((TPM_CAPABILITY_AREA) 9)
+#define TPM_PF_CEKPUSED ((TPM_CAPABILITY_AREA) 10)
+#define TPM_PF_TPMPOST ((TPM_CAPABILITY_AREA) 11)
+#define TPM_PF_TPMPOSTLOCK ((TPM_CAPABILITY_AREA) 12)
+#define TPM_PF_FIPS ((TPM_CAPABILITY_AREA) 13)
+#define TPM_PF_OPERATOR ((TPM_CAPABILITY_AREA) 14)
+#define TPM_PF_ENABLEREVOKEEK ((TPM_CAPABILITY_AREA) 15)
+#define TPM_PF_NV_LOCKED ((TPM_CAPABILITY_AREA) 16)
+#define TPM_PF_READSRKPUB ((TPM_CAPABILITY_AREA) 17)
+#define TPM_PF_TPMESTABLISHED ((TPM_CAPABILITY_AREA) 18)
+#define TPM_PF_MAINTENANCEDONE ((TPM_CAPABILITY_AREA) 19)
+
+//
+// Part 2, section 7.2: TPM_STCLEAR_FLAGS
+//
+typedef struct tdTPM_STCLEAR_FLAGS
+{
+ TPM_STRUCTURE_TAG tag;
+ BOOLEAN deactivated;
+ BOOLEAN disableForceClear;
+ BOOLEAN physicalPresence;
+ BOOLEAN physicalPresenceLock;
+ BOOLEAN bGlobalLock;
+} TPM_STCLEAR_FLAGS;
+
+//
+// Part 2, section 7.2.1: STCLEAR_FLAGS Subcap for SetCapability
+//
+#define TPM_SF_DEACTIVATED ((TPM_CAPABILITY_AREA) 1)
+#define TPM_SF_DISABLEFORCECLEAR ((TPM_CAPABILITY_AREA) 2)
+#define TPM_SF_PHYSICALPRESENCE ((TPM_CAPABILITY_AREA) 3)
+#define TPM_SF_PHYSICALPRESENCELOCK ((TPM_CAPABILITY_AREA) 4)
+#define TPM_SF_BGLOBALLOCK ((TPM_CAPABILITY_AREA) 5)
+
+//
+// Part 2, section 7.3: TPM_STANY_FLAGS
+//
+typedef struct tdTPM_STANY_FLAGS
+{
+ TPM_STRUCTURE_TAG tag;
+ BOOLEAN postInitialise;
+ TPM_MODIFIER_INDICATOR localityModifier;
+ BOOLEAN transportExclusive;
+ BOOLEAN TOSPresent;
+} TPM_STANY_FLAGS;
+
+//
+// Part 2, section 7.3.1: STANY_FLAGS Subcap for SetCapability
+//
+#define TPM_AF_POSTINITIALISE ((TPM_CAPABILITY_AREA) 1)
+#define TPM_AF_LOCALITYMODIFIER ((TPM_CAPABILITY_AREA) 2)
+#define TPM_AF_TRANSPORTEXCLUSIVE ((TPM_CAPABILITY_AREA) 3)
+#define TPM_AF_TOSPRESENT ((TPM_CAPABILITY_AREA) 4)
+
+//
+// All those structures (section 7.4, 7.5, 7.6) are not normative and
+// thus no definitions here
+//
+// Part 2, section 7.4: TPM_PERMANENT_DATA
+//
+//#define TPM_MIN_COUNTERS 4 // the minimum number of counters is 4
+//#define TPM_DELEGATE_KEY TPM_KEY
+//#define TPM_NUM_PCR 16
+//#define TPM_MAX_NV_WRITE_NOOWNER 64
+//typedef struct tdTPM_PERMANENT_DATA
+//{
+// TPM_STRUCTURE_TAG tag;
+// UINT8 revMajor;
+// UINT8 revMinor;
+// TPM_NONCE tpmProof;
+// TPM_NONCE ekReset;
+// TPM_SECRET ownerAuth;
+// TPM_SECRET operatorAuth;
+// TPM_DIRVALUE authDIR[1];
+// TPM_PUBKEY manuMaintPub;
+// TPM_KEY endorsementKey;
+// TPM_KEY srk;
+// TPM_KEY contextKey;
+// TPM_KEY delegateKey;
+// TPM_COUNTER_VALUE auditMonotonicCounter;
+// TPM_COUNTER_VALUE monitonicCounter[TPM_MIN_COUNTERS];
+// TPM_PCR_ATTRIBUTES pcrAttrib[TPM_NUM_PCR];
+// UINT8 ordinalAuditStatus[];
+// UINT8 *rngState;
+// TPM_FAMILY_TABLE familyTable;
+// TPM_DELEGATE_TABLE delegateTable;
+// UINT32 maxNVBufSize;
+// UINT32 lastFamilyID;
+// UINT32 noOwnerNVWrite;
+// TPM_CMK_DELEGATE restrictDelegate;
+// TPM_DAA_TPM_SEED tpmDAASeed;
+//} TPM_PERMANENT_DATA;
+
+//
+// Part 2, section 7.5: TPM_STCLEAR_DATA
+// available inside TPM only
+//
+//typedef struct tdTPM_STCLEAR_DATA
+//{
+// TPM_STRUCTURE_TAG tag;
+// TPM_NONCE contextNonceKey;
+// TPM_COUNT_ID countID;
+// UINT32 ownerReference;
+// BOOLEAN disableResetLock;
+//} TPM_STCLEAR_DATA;
+
+//
+// Part 2, section 7.6: TPM_STANY_DATA
+// available inside TPM only
+//
+//typedef struct tdTPM_STANY_DATA
+//{
+// TPM_STRUCTURE_TAG tag;
+// TPM_NONCE contextNonceSession;
+// TPM_DIGEST auditDigest;
+// TPM_CURRENT_TICKS currentTicks;
+// UINT32 contextCount;
+// UINT32 contextList[TPM_MIN_SESSION_LIST];
+// TPM_SESSION_DATA sessions[TPM_MIN_SESSIONS];
+//} TPM_STANY_DATA;
+
+//
+// Part 2, section 8: PCR Structures
+//
+
+//
+// Part 2, section 8.1: TPM_PCR_SELECTION
+// Size of pcrSelect[] indicated by sizeOfSelect
+//
+typedef struct tdTPM_PCR_SELECTION
+{
+ UINT16 sizeOfSelect;
+ UINT8 pcrSelect[1];
+} TPM_PCR_SELECTION;
+
+//
+// Part 2, section 8.2: TPM_PCR_COMPOSITE
+// Size of pcrValue[] indicated by valueSize
+//
+typedef struct tdTPM_PCR_COMPOSITE
+{
+ TPM_PCR_SELECTION select;
+ UINT32 valueSize;
+ TPM_PCRVALUE pcrValue[1];
+} TPM_PCR_COMPOSITE;
+
+//
+// Part 2, section 8.3: TPM_PCR_INFO
+//
+typedef struct tdTPM_PCR_INFO
+{
+ TPM_PCR_SELECTION pcrSelection;
+ TPM_COMPOSITE_HASH digestAtRelease;
+ TPM_COMPOSITE_HASH digestAtCreation;
+} TPM_PCR_INFO;
+
+//
+// Part 2, section 8.6: TPM_LOCALITY_SELECTION
+//
+typedef UINT8 TPM_LOCALITY_SELECTION;
+
+#define TPM_LOC_FOUR ((UINT8) 0x10)
+#define TPM_LOC_THREE ((UINT8) 0x08)
+#define TPM_LOC_TWO ((UINT8) 0x04)
+#define TPM_LOC_ONE ((UINT8) 0x02)
+#define TPM_LOC_ZERO ((UINT8) 0x01)
+
+//
+// Part 2, section 8.4: TPM_PCR_INFO_LONG
+//
+typedef struct tdTPM_PCR_INFO_LONG
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_LOCALITY_SELECTION localityAtCreation;
+ TPM_LOCALITY_SELECTION localityAtRelease;
+ TPM_PCR_SELECTION creationPCRSelection;
+ TPM_PCR_SELECTION releasePCRSelection;
+ TPM_COMPOSITE_HASH digestAtCreation;
+ TPM_COMPOSITE_HASH digestAtRelease;
+} TPM_PCR_INFO_LONG;
+
+//
+// Part 2, section 8.5: TPM_PCR_INFO_SHORT
+//
+typedef struct tdTPM_PCR_INFO_SHORT
+{
+ TPM_PCR_SELECTION pcrSelection;
+ TPM_LOCALITY_SELECTION localityAtRelease;
+ TPM_COMPOSITE_HASH digestAtRelease;
+} TPM_PCR_INFO_SHORT;
+
+//
+// Part 2, section 8.8: TPM_PCR_ATTRIBUTES
+//
+typedef struct tdTPM_PCR_ATTRIBUTES
+{
+ BOOLEAN pcrReset;
+ TPM_LOCALITY_SELECTION pcrExtendLocal;
+ TPM_LOCALITY_SELECTION pcrResetLocal;
+} TPM_PCR_ATTRIBUTES;
+
+//
+// Part 2, section 9: Storage Structures
+//
+
+//
+// Part 2, section 9.1: TPM_STORED_DATA
+// [size_is(sealInfoSize)] BYTE* sealInfo;
+// [size_is(encDataSize)] BYTE* encData;
+//
+typedef struct tdTPM_STORED_DATA
+{
+ TPM_STRUCT_VER ver;
+ UINT32 sealInfoSize;
+ UINT8 *sealInfo;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_STORED_DATA;
+
+//
+// Part 2, section 9.2: TPM_STORED_DATA12
+// [size_is(sealInfoSize)] BYTE* sealInfo;
+// [size_is(encDataSize)] BYTE* encData;
+//
+typedef struct tdTPM_STORED_DATA12
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_ENTITY_TYPE et;
+ UINT32 sealInfoSize;
+ UINT8 *sealInfo;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_STORED_DATA12;
+
+//
+// Part 2, section 9.3: TPM_SEALED_DATA
+// [size_is(dataSize)] BYTE* data;
+//
+typedef struct tdTPM_SEALED_DATA
+{
+ TPM_PAYLOAD_TYPE payload;
+ TPM_SECRET authData;
+ TPM_NONCE tpmProof;
+ TPM_DIGEST storedDigest;
+ UINT32 dataSize;
+ UINT8 *data;
+} TPM_SEALED_DATA;
+
+//
+// Part 2, section 9.4: TPM_SYMMETRIC_KEY
+// [size_is(size)] BYTE* data;
+//
+typedef struct tdTPM_SYMMETRIC_KEY
+{
+ TPM_ALGORITHM_ID algId;
+ TPM_ENC_SCHEME encScheme;
+ UINT16 dataSize;
+ UINT8 *data;
+} TPM_SYMMETRIC_KEY;
+
+//
+// Part 2, section 9.5: TPM_BOUND_DATA
+//
+typedef struct tdTPM_BOUND_DATA
+{
+ TPM_STRUCT_VER ver;
+ TPM_PAYLOAD_TYPE payload;
+ UINT8 payloadData[1];
+} TPM_BOUND_DATA;
+
+//
+// Part 2 section 10: TPM_KEY complex
+//
+
+//
+// Part 2, section 10.2: TPM_KEY
+// [size_is(encDataSize)] BYTE* encData;
+//
+typedef struct tdTPM_KEY
+{
+ TPM_STRUCT_VER ver;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+ TPM_STORE_PUBKEY pubKey;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_KEY;
+
+//
+// Part 2, section 10.3: TPM_KEY12
+// [size_is(encDataSize)] BYTE* encData;
+//
+typedef struct tdTPM_KEY12
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT16 fill;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+ TPM_STORE_PUBKEY pubKey;
+ UINT32 encDataSize;
+ UINT8 *encData;
+} TPM_KEY12;
+
+//
+// Part 2, section 10.7: TPM_STORE_PRIVKEY
+// [size_is(keyLength)] BYTE* key;
+//
+typedef struct tdTPM_STORE_PRIVKEY
+{
+ UINT32 keyLength;
+ UINT8 *key;
+} TPM_STORE_PRIVKEY;
+
+//
+// Part 2, section 10.6: TPM_STORE_ASYMKEY
+//
+typedef struct tdTPM_STORE_ASYMKEY // pos len total
+{
+ TPM_PAYLOAD_TYPE payload; // 0 1 1
+ TPM_SECRET usageAuth; // 1 20 21
+ TPM_SECRET migrationAuth; // 21 20 41
+ TPM_DIGEST pubDataDigest; // 41 20 61
+ TPM_STORE_PRIVKEY privKey; // 61 132-151 193-214
+} TPM_STORE_ASYMKEY;
+
+//
+// Part 2, section 10.8: TPM_MIGRATE_ASYMKEY
+// [size_is(partPrivKeyLen)] BYTE* partPrivKey;
+//
+typedef struct tdTPM_MIGRATE_ASYMKEY // pos len total
+{
+ TPM_PAYLOAD_TYPE payload; // 0 1 1
+ TPM_SECRET usageAuth; // 1 20 21
+ TPM_DIGEST pubDataDigest; // 21 20 41
+ UINT32 partPrivKeyLen; // 41 4 45
+ UINT8 *partPrivKey; // 45 112-127 157-172
+} TPM_MIGRATE_ASYMKEY;
+
+//
+// Part 2, section 10.9: TPM_KEY_CONTROL
+//
+#define TPM_KEY_CONTROL_OWNER_EVICT ((UINT32) 0x00000001)
+#define TPM_CAP_FLAG_STANY 0X0000011D
+
+//
+// Part 2, section 11: Signed Structures
+//
+
+typedef struct tdTPM_CERTIFY_INFO
+{
+ TPM_STRUCT_VER version;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ TPM_DIGEST pubkeyDigest;
+ TPM_NONCE data;
+ BOOLEAN parentPCRStatus;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+} TPM_CERTIFY_INFO;
+
+typedef struct tdTPM_CERTIFY_INFO2
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT8 fill;
+ TPM_PAYLOAD_TYPE payloadType;
+ TPM_KEY_USAGE keyUsage;
+ TPM_KEY_FLAGS keyFlags;
+ TPM_AUTH_DATA_USAGE authDataUsage;
+ TPM_KEY_PARMS algorithmParms;
+ TPM_DIGEST pubkeyDigest;
+ TPM_NONCE data;
+ BOOLEAN parentPCRStatus;
+ UINT32 PCRInfoSize;
+ UINT8 *PCRInfo;
+ UINT32 migrationAuthoritySize;
+ UINT8 *migrationAuthority;
+} TPM_CERTIFY_INFO2;
+
+typedef struct tdTPM_QUOTE_INFO
+{
+ TPM_STRUCT_VER version;
+ UINT8 fixed[4];
+ TPM_COMPOSITE_HASH digestValue;
+ TPM_NONCE externalData;
+} TPM_QUOTE_INFO;
+
+typedef struct tdTPM_QUOTE_INFO2
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT8 fixed[4];
+ TPM_NONCE externalData;
+ TPM_PCR_INFO_SHORT infoShort;
+} TPM_QUOTE_INFO2;
+
+//
+// Part 2, section 12: Identity Structures
+//
+
+typedef struct tdTPM_EK_BLOB
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_EK_TYPE ekType;
+ UINT32 blobSize;
+ UINT8 *blob;
+} TPM_EK_BLOB;
+
+typedef struct tdTPM_EK_BLOB_ACTIVATE
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_SYMMETRIC_KEY sessionKey;
+ TPM_DIGEST idDigest;
+ TPM_PCR_INFO_SHORT pcrInfo;
+} TPM_EK_BLOB_ACTIVATE;
+
+typedef struct tdTPM_EK_BLOB_AUTH
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_SECRET authValue;
+} TPM_EK_BLOB_AUTH;
+
+
+// TPM_CHOSENID_HASH = SHA(identityLabel || privacyCA)
+typedef TPM_DIGEST TPM_CHOSENID_HASH;
+
+typedef struct tdTPM_IDENTITY_CONTENTS
+{
+ TPM_STRUCT_VER ver;
+ UINT32 ordinal;
+ TPM_CHOSENID_HASH labelPrivCADigest;
+ TPM_PUBKEY identityPubKey;
+} TPM_IDENTITY_CONTENTS;
+
+typedef struct tdTPM_IDENTITY_REQ
+{
+ UINT32 asymSize;
+ UINT32 symSize;
+ TPM_KEY_PARMS asymAlgorithm;
+ TPM_KEY_PARMS symAlgorithm;
+ UINT8 *asymBlob;
+ UINT8 *symBlob;
+} TPM_IDENTITY_REQ;
+
+typedef struct tdTPM_IDENTITY_PROOF
+{
+ TPM_STRUCT_VER ver;
+ UINT32 labelSize;
+ UINT32 identityBindingSize;
+ UINT32 endorsementSize;
+ UINT32 platformSize;
+ UINT32 conformanceSize;
+ TPM_PUBKEY identityKey;
+ UINT8 *labelArea;
+ UINT8 *identityBinding;
+ UINT8 *endorsementCredential;
+ UINT8 *platformCredential;
+ UINT8 *conformanceCredential;
+} TPM_IDENTITY_PROOF;
+
+typedef struct tdTPM_ASYM_CA_CONTENTS
+{
+ TPM_SYMMETRIC_KEY sessionKey;
+ TPM_DIGEST idDigest;
+} TPM_ASYM_CA_CONTENTS;
+
+typedef struct tdTPM_SYM_CA_ATTESTATION
+{
+ UINT32 credSize;
+ TPM_KEY_PARMS algorithm;
+ UINT8 *credential;
+} TPM_SYM_CA_ATTESTATION;
+
+//
+// Part 2, section 15: TPM_CURRENT_TICKS
+// Placed here out of order because definitions are used in section 13.
+//
+typedef struct tdTPM_CURRENT_TICKS
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT64 currentTicks;
+ UINT16 tickRate;
+ TPM_NONCE tickNonce;
+} TPM_CURRENT_TICKS;
+
+//
+// Part 2, section 13: Transport structures
+//
+
+#define TPM_TRANSPORT_ENCRYPT ((UINT32)0x00000001)
+#define TPM_TRANSPORT_LOG ((UINT32)0x00000002)
+#define TPM_TRANSPORT_EXCLUSIVE ((UINT32)0x00000004)
+
+typedef struct tdTPM_TRANSPORT_PUBLIC
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_TRANSPORT_ATTRIBUTES transAttributes;
+ TPM_ALGORITHM_ID algId;
+ TPM_ENC_SCHEME encScheme;
+} TPM_TRANSPORT_PUBLIC;
+
+typedef struct tdTPM_TRANSPORT_INTERNAL
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_AUTHDATA authData;
+ TPM_TRANSPORT_PUBLIC transPublic;
+ TPM_TRANSHANDLE transHandle;
+ TPM_NONCE transNonceEven;
+ TPM_DIGEST transDigest;
+} TPM_TRANSPORT_INTERNAL;
+
+typedef struct tdTPM_TRANSPORT_LOG_IN
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST parameters;
+ TPM_DIGEST pubKeyHash;
+} TPM_TRANSPORT_LOG_IN;
+
+typedef struct tdTPM_TRANSPORT_LOG_OUT
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_CURRENT_TICKS currentTicks;
+ TPM_DIGEST parameters;
+ TPM_MODIFIER_INDICATOR locality;
+} TPM_TRANSPORT_LOG_OUT;
+
+typedef struct tdTPM_TRANSPORT_AUTH
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_AUTHDATA authData;
+} TPM_TRANSPORT_AUTH;
+
+//
+// Part 2, section 14: Audit Structures
+//
+
+typedef struct tdTPM_AUDIT_EVENT_IN
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST inputParms;
+ TPM_COUNTER_VALUE auditCount;
+} TPM_AUDIT_EVENT_IN;
+
+typedef struct tdTPM_AUDIT_EVENT_OUT
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_COMMAND_CODE ordinal;
+ TPM_DIGEST outputParms;
+ TPM_COUNTER_VALUE auditCount;
+ TPM_RESULT returnCode;
+} TPM_AUDIT_EVENT_OUT;
+
+//
+// Part 2, section 16: Return Codes
+//
+#define TPM_BASE (EFI_MAX_BIT + (EFI_MAX_BIT >> 1))
+
+#ifndef TPM_BASE
+ #error "TPM Error Codes require definition of TPM_BASE"
+#endif
+
+#define TPM_VENDOR_ERROR TPM_Vendor_Specific32
+#define TPM_NON_FATAL 0x00000800
+
+#define TPM_SUCCESS ((TPM_RESULT) TPM_BASE)
+#define TPM_AUTHFAIL ((TPM_RESULT) (TPM_BASE + 1))
+#define TPM_BADINDEX ((TPM_RESULT) (TPM_BASE + 2))
+#define TPM_BAD_PARAMETER ((TPM_RESULT) (TPM_BASE + 3))
+#define TPM_AUDITFAILURE ((TPM_RESULT) (TPM_BASE + 4))
+#define TPM_CLEAR_DISABLED ((TPM_RESULT) (TPM_BASE + 5))
+#define TPM_DEACTIVATED ((TPM_RESULT) (TPM_BASE + 6))
+#define TPM_DISABLED ((TPM_RESULT) (TPM_BASE + 7))
+#define TPM_DISABLED_CMD ((TPM_RESULT) (TPM_BASE + 8))
+#define TPM_FAIL ((TPM_RESULT) (TPM_BASE + 9))
+#define TPM_BAD_ORDINAL ((TPM_RESULT) (TPM_BASE + 10))
+#define TPM_INSTALL_DISABLED ((TPM_RESULT) (TPM_BASE + 11))
+#define TPM_INVALID_KEYHANDLE ((TPM_RESULT) (TPM_BASE + 12))
+#define TPM_KEYNOTFOUND ((TPM_RESULT) (TPM_BASE + 13))
+#define TPM_INAPPROPRIATE_ENC ((TPM_RESULT) (TPM_BASE + 14))
+#define TPM_MIGRATEFAIL ((TPM_RESULT) (TPM_BASE + 15))
+#define TPM_INVALID_PCR_INFO ((TPM_RESULT) (TPM_BASE + 16))
+#define TPM_NOSPACE ((TPM_RESULT) (TPM_BASE + 17))
+#define TPM_NOSRK ((TPM_RESULT) (TPM_BASE + 18))
+#define TPM_NOTSEALED_BLOB ((TPM_RESULT) (TPM_BASE + 19))
+#define TPM_OWNER_SET ((TPM_RESULT) (TPM_BASE + 20))
+#define TPM_RESOURCES ((TPM_RESULT) (TPM_BASE + 21))
+#define TPM_SHORTRANDOM ((TPM_RESULT) (TPM_BASE + 22))
+#define TPM_SIZE ((TPM_RESULT) (TPM_BASE + 23))
+#define TPM_WRONGPCRVAL ((TPM_RESULT) (TPM_BASE + 24))
+#define TPM_BAD_PARAM_SIZE ((TPM_RESULT) (TPM_BASE + 25))
+#define TPM_SHA_THREAD ((TPM_RESULT) (TPM_BASE + 26))
+#define TPM_SHA_ERROR ((TPM_RESULT) (TPM_BASE + 27))
+#define TPM_FAILEDSELFTEST ((TPM_RESULT) (TPM_BASE + 28))
+#define TPM_AUTH2FAIL ((TPM_RESULT) (TPM_BASE + 29))
+#define TPM_BADTAG ((TPM_RESULT) (TPM_BASE + 30))
+#define TPM_IOERROR ((TPM_RESULT) (TPM_BASE + 31))
+#define TPM_ENCRYPT_ERROR ((TPM_RESULT) (TPM_BASE + 32))
+#define TPM_DECRYPT_ERROR ((TPM_RESULT) (TPM_BASE + 33))
+#define TPM_INVALID_AUTHHANDLE ((TPM_RESULT) (TPM_BASE + 34))
+#define TPM_NO_ENDORSEMENT ((TPM_RESULT) (TPM_BASE + 35))
+#define TPM_INVALID_KEYUSAGE ((TPM_RESULT) (TPM_BASE + 36))
+#define TPM_WRONG_ENTITYTYPE ((TPM_RESULT) (TPM_BASE + 37))
+#define TPM_INVALID_POSTINIT ((TPM_RESULT) (TPM_BASE + 38))
+#define TPM_INAPPROPRIATE_SIG ((TPM_RESULT) (TPM_BASE + 39))
+#define TPM_BAD_KEY_PROPERTY ((TPM_RESULT) (TPM_BASE + 40))
+#define TPM_BAD_MIGRATION ((TPM_RESULT) (TPM_BASE + 41))
+#define TPM_BAD_SCHEME ((TPM_RESULT) (TPM_BASE + 42))
+#define TPM_BAD_DATASIZE ((TPM_RESULT) (TPM_BASE + 43))
+#define TPM_BAD_MODE ((TPM_RESULT) (TPM_BASE + 44))
+#define TPM_BAD_PRESENCE ((TPM_RESULT) (TPM_BASE + 45))
+#define TPM_BAD_VERSION ((TPM_RESULT) (TPM_BASE + 46))
+#define TPM_NO_WRAP_TRANSPORT ((TPM_RESULT) (TPM_BASE + 47))
+#define TPM_AUDITFAIL_UNSUCCESSFUL ((TPM_RESULT) (TPM_BASE + 48))
+#define TPM_AUDITFAIL_SUCCESSFUL ((TPM_RESULT) (TPM_BASE + 49))
+#define TPM_NOTRESETABLE ((TPM_RESULT) (TPM_BASE + 50))
+#define TPM_NOTLOCAL ((TPM_RESULT) (TPM_BASE + 51))
+#define TPM_BAD_TYPE ((TPM_RESULT) (TPM_BASE + 52))
+#define TPM_INVALID_RESOURCE ((TPM_RESULT) (TPM_BASE + 53))
+#define TPM_NOTFIPS ((TPM_RESULT) (TPM_BASE + 54))
+#define TPM_INVALID_FAMILY ((TPM_RESULT) (TPM_BASE + 55))
+#define TPM_NO_NV_PERMISSION ((TPM_RESULT) (TPM_BASE + 56))
+#define TPM_REQUIRES_SIGN ((TPM_RESULT) (TPM_BASE + 57))
+#define TPM_KEY_NOTSUPPORTED ((TPM_RESULT) (TPM_BASE + 58))
+#define TPM_AUTH_CONFLICT ((TPM_RESULT) (TPM_BASE + 59))
+#define TPM_AREA_LOCKED ((TPM_RESULT) (TPM_BASE + 60))
+#define TPM_BAD_LOCALITY ((TPM_RESULT) (TPM_BASE + 61))
+#define TPM_READ_ONLY ((TPM_RESULT) (TPM_BASE + 62))
+#define TPM_PER_NOWRITE ((TPM_RESULT) (TPM_BASE + 63))
+#define TPM_FAMILYCOUNT ((TPM_RESULT) (TPM_BASE + 64))
+#define TPM_WRITE_LOCKED ((TPM_RESULT) (TPM_BASE + 65))
+#define TPM_BAD_ATTRIBUTES ((TPM_RESULT) (TPM_BASE + 66))
+#define TPM_INVALID_STRUCTURE ((TPM_RESULT) (TPM_BASE + 67))
+#define TPM_KEY_OWNER_CONTROL ((TPM_RESULT) (TPM_BASE + 68))
+#define TPM_BAD_COUNTER ((TPM_RESULT) (TPM_BASE + 69))
+#define TPM_NOT_FULLWRITE ((TPM_RESULT) (TPM_BASE + 70))
+#define TPM_CONTEXT_GAP ((TPM_RESULT) (TPM_BASE + 71))
+#define TPM_MAXNVWRITES ((TPM_RESULT) (TPM_BASE + 72))
+#define TPM_NOOPERATOR ((TPM_RESULT) (TPM_BASE + 73))
+#define TPM_RESOURCEMISSING ((TPM_RESULT) (TPM_BASE + 74))
+#define TPM_DELEGATE_LOCK ((TPM_RESULT) (TPM_BASE + 75))
+#define TPM_DELEGATE_FAMILY ((TPM_RESULT) (TPM_BASE + 76))
+#define TPM_DELEGATE_ADMIN ((TPM_RESULT) (TPM_BASE + 77))
+#define TPM_TRANSPORT_NOTEXCLUSIVE ((TPM_RESULT) (TPM_BASE + 78))
+#define TPM_OWNER_CONTROL ((TPM_RESULT) (TPM_BASE + 79))
+#define TPM_DAA_RESOURCES ((TPM_RESULT) (TPM_BASE + 80))
+#define TPM_DAA_INPUT_DATA0 ((TPM_RESULT) (TPM_BASE + 81))
+#define TPM_DAA_INPUT_DATA1 ((TPM_RESULT) (TPM_BASE + 82))
+#define TPM_DAA_ISSUER_SETTINGS ((TPM_RESULT) (TPM_BASE + 83))
+#define TPM_DAA_TPM_SETTINGS ((TPM_RESULT) (TPM_BASE + 84))
+#define TPM_DAA_STAGE ((TPM_RESULT) (TPM_BASE + 85))
+#define TPM_DAA_ISSUER_VALIDITY ((TPM_RESULT) (TPM_BASE + 86))
+#define TPM_DAA_WRONG_W ((TPM_RESULT) (TPM_BASE + 87))
+#define TPM_BAD_HANDLE ((TPM_RESULT) (TPM_BASE + 88))
+#define TPM_BAD_DELEGATE ((TPM_RESULT) (TPM_BASE + 89))
+#define TPM_BADCONTEXT ((TPM_RESULT) (TPM_BASE + 90))
+#define TPM_TOOMANYCONTEXTS ((TPM_RESULT) (TPM_BASE + 91))
+#define TPM_MA_TICKET_SIGNATURE ((TPM_RESULT) (TPM_BASE + 92))
+#define TPM_MA_DESTINATION ((TPM_RESULT) (TPM_BASE + 93))
+#define TPM_MA_SOURCE ((TPM_RESULT) (TPM_BASE + 94))
+#define TPM_MA_AUTHORITY ((TPM_RESULT) (TPM_BASE + 95))
+#define TPM_PERMANENTEK ((TPM_RESULT) (TPM_BASE + 97))
+#define TPM_BAD_SIGNATURE ((TPM_RESULT) (TPM_BASE + 98))
+#define TPM_NOCONTEXTSPACE ((TPM_RESULT) (TPM_BASE + 99))
+
+#define TPM_RETRY ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL))
+#define TPM_NEEDS_SELFTEST ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 1))
+#define TPM_DOING_SELFTEST ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 2))
+#define TPM_DEFEND_LOCK_RUNNING ((TPM_RESULT) (TPM_BASE + TPM_NON_FATAL + 3))
+
+//
+// Part 2, section 17: Ordinals
+//
+// Ordinals are 32 bit values. The upper byte contains values that serve as
+// flag indicators, the next byte contains values indicating what committee
+// designated the ordinal, and the final two bytes contain the Command
+// Ordinal Index.
+// 3 2 1
+// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// |P|C|V| Reserved| Purview | Command Ordinal Index |
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// Where:
+//
+// * P is Protected/Unprotected command. When 0 the command is a Protected
+// command, when 1 the command is an Unprotected command.
+//
+// * C is Non-Connection/Connection related command. When 0 this command
+// passes through to either the protected (TPM) or unprotected (TSS)
+// components.
+//
+// * V is TPM/Vendor command. When 0 the command is TPM defined, when 1 the
+// command is vendor defined.
+//
+// * All reserved area bits are set to 0.
+//
+#define TPM_ORD_ActivateIdentity ((TPM_COMMAND_CODE) 0x0000007A)
+#define TPM_ORD_AuthorizeMigrationKey ((TPM_COMMAND_CODE) 0x0000002B)
+#define TPM_ORD_CertifyKey ((TPM_COMMAND_CODE) 0x00000032)
+#define TPM_ORD_CertifyKey2 ((TPM_COMMAND_CODE) 0x00000033)
+#define TPM_ORD_CertifySelfTest ((TPM_COMMAND_CODE) 0x00000052)
+#define TPM_ORD_ChangeAuth ((TPM_COMMAND_CODE) 0x0000000C)
+#define TPM_ORD_ChangeAuthAsymFinish ((TPM_COMMAND_CODE) 0x0000000F)
+#define TPM_ORD_ChangeAuthAsymStart ((TPM_COMMAND_CODE) 0x0000000E)
+#define TPM_ORD_ChangeAuthOwner ((TPM_COMMAND_CODE) 0x00000010)
+#define TPM_ORD_CMK_ApproveMA ((TPM_COMMAND_CODE) 0x0000001D)
+#define TPM_ORD_CMK_ConvertMigration ((TPM_COMMAND_CODE) 0x00000024)
+#define TPM_ORD_CMK_CreateBlob ((TPM_COMMAND_CODE) 0x0000001B)
+#define TPM_ORD_CMK_CreateKey ((TPM_COMMAND_CODE) 0x00000013)
+#define TPM_ORD_CMK_CreateTicket ((TPM_COMMAND_CODE) 0x00000012)
+#define TPM_ORD_CMK_SetRestrictions ((TPM_COMMAND_CODE) 0x0000001C)
+#define TPM_ORD_ContinueSelfTest ((TPM_COMMAND_CODE) 0x00000053)
+#define TPM_ORD_ConvertMigrationBlob ((TPM_COMMAND_CODE) 0x0000002A)
+#define TPM_ORD_CreateCounter ((TPM_COMMAND_CODE) 0x000000DC)
+#define TPM_ORD_CreateEndorsementKeyPair ((TPM_COMMAND_CODE) 0x00000078)
+#define TPM_ORD_CreateMaintenanceArchive ((TPM_COMMAND_CODE) 0x0000002C)
+#define TPM_ORD_CreateMigrationBlob ((TPM_COMMAND_CODE) 0x00000028)
+#define TPM_ORD_CreateRevocableEK ((TPM_COMMAND_CODE) 0x0000007F)
+#define TPM_ORD_CreateWrapKey ((TPM_COMMAND_CODE) 0x0000001F)
+#define TPM_ORD_DAA_JOIN ((TPM_COMMAND_CODE) 0x00000029)
+#define TPM_ORD_DAA_SIGN ((TPM_COMMAND_CODE) 0x00000031)
+#define TPM_ORD_Delegate_CreateKeyDelegation ((TPM_COMMAND_CODE) 0x000000D4)
+#define TPM_ORD_Delegate_CreateOwnerDelegation ((TPM_COMMAND_CODE) 0x000000D5)
+#define TPM_ORD_Delegate_LoadOwnerDelegation ((TPM_COMMAND_CODE) 0x000000D8)
+#define TPM_ORD_Delegate_Manage ((TPM_COMMAND_CODE) 0x000000D2)
+#define TPM_ORD_Delegate_ReadTable ((TPM_COMMAND_CODE) 0x000000DB)
+#define TPM_ORD_Delegate_UpdateVerification ((TPM_COMMAND_CODE) 0x000000D1)
+#define TPM_ORD_Delegate_VerifyDelegation ((TPM_COMMAND_CODE) 0x000000D6)
+#define TPM_ORD_DirRead ((TPM_COMMAND_CODE) 0x0000001A)
+#define TPM_ORD_DirWriteAuth ((TPM_COMMAND_CODE) 0x00000019)
+#define TPM_ORD_DisableForceClear ((TPM_COMMAND_CODE) 0x0000005E)
+#define TPM_ORD_DisableOwnerClear ((TPM_COMMAND_CODE) 0x0000005C)
+#define TPM_ORD_DisablePubekRead ((TPM_COMMAND_CODE) 0x0000007E)
+#define TPM_ORD_DSAP ((TPM_COMMAND_CODE) 0x00000011)
+#define TPM_ORD_EstablishTransport ((TPM_COMMAND_CODE) 0x000000E6)
+#define TPM_ORD_EvictKey ((TPM_COMMAND_CODE) 0x00000022)
+#define TPM_ORD_ExecuteTransport ((TPM_COMMAND_CODE) 0x000000E7)
+#define TPM_ORD_Extend ((TPM_COMMAND_CODE) 0x00000014)
+#define TPM_ORD_FieldUpgrade ((TPM_COMMAND_CODE) 0x000000AA)
+#define TPM_ORD_FlushSpecific ((TPM_COMMAND_CODE) 0x000000BA)
+#define TPM_ORD_ForceClear ((TPM_COMMAND_CODE) 0x0000005D)
+#define TPM_ORD_GetAuditDigest ((TPM_COMMAND_CODE) 0x00000085)
+#define TPM_ORD_GetAuditDigestSigned ((TPM_COMMAND_CODE) 0x00000086)
+#define TPM_ORD_GetAuditEvent ((TPM_COMMAND_CODE) 0x00000082)
+#define TPM_ORD_GetAuditEventSigned ((TPM_COMMAND_CODE) 0x00000083)
+#define TPM_ORD_GetCapability ((TPM_COMMAND_CODE) 0x00000065)
+#define TPM_ORD_GetCapabilityOwner ((TPM_COMMAND_CODE) 0x00000066)
+#define TPM_ORD_GetCapabilitySigned ((TPM_COMMAND_CODE) 0x00000064)
+#define TPM_ORD_GetOrdinalAuditStatus ((TPM_COMMAND_CODE) 0x0000008C)
+#define TPM_ORD_GetPubKey ((TPM_COMMAND_CODE) 0x00000021)
+#define TPM_ORD_GetRandom ((TPM_COMMAND_CODE) 0x00000046)
+#define TPM_ORD_GetTestResult ((TPM_COMMAND_CODE) 0x00000054)
+#define TPM_ORD_GetTicks ((TPM_COMMAND_CODE) 0x000000F1)
+#define TPM_ORD_IncrementCounter ((TPM_COMMAND_CODE) 0x000000DD)
+#define TPM_ORD_Init ((TPM_COMMAND_CODE) 0x00000097)
+#define TPM_ORD_KeyControlOwner ((TPM_COMMAND_CODE) 0x00000023)
+#define TPM_ORD_KillMaintenanceFeature ((TPM_COMMAND_CODE) 0x0000002E)
+#define TPM_ORD_LoadAuthContext ((TPM_COMMAND_CODE) 0x000000B7)
+#define TPM_ORD_LoadContext ((TPM_COMMAND_CODE) 0x000000B9)
+#define TPM_ORD_LoadKey ((TPM_COMMAND_CODE) 0x00000020)
+#define TPM_ORD_LoadKey2 ((TPM_COMMAND_CODE) 0x00000041)
+#define TPM_ORD_LoadKeyContext ((TPM_COMMAND_CODE) 0x000000B5)
+#define TPM_ORD_LoadMaintenanceArchive ((TPM_COMMAND_CODE) 0x0000002D)
+#define TPM_ORD_LoadManuMaintPub ((TPM_COMMAND_CODE) 0x0000002F)
+#define TPM_ORD_MakeIdentity ((TPM_COMMAND_CODE) 0x00000079)
+#define TPM_ORD_MigrateKey ((TPM_COMMAND_CODE) 0x00000025)
+#define TPM_ORD_NV_DefineSpace ((TPM_COMMAND_CODE) 0x000000CC)
+#define TPM_ORD_NV_ReadValue ((TPM_COMMAND_CODE) 0x000000CF)
+#define TPM_ORD_NV_ReadValueAuth ((TPM_COMMAND_CODE) 0x000000D0)
+#define TPM_ORD_NV_WriteValue ((TPM_COMMAND_CODE) 0x000000CD)
+#define TPM_ORD_NV_WriteValueAuth ((TPM_COMMAND_CODE) 0x000000CE)
+#define TPM_ORD_OIAP ((TPM_COMMAND_CODE) 0x0000000A)
+#define TPM_ORD_OSAP ((TPM_COMMAND_CODE) 0x0000000B)
+#define TPM_ORD_OwnerClear ((TPM_COMMAND_CODE) 0x0000005B)
+#define TPM_ORD_OwnerReadInternalPub ((TPM_COMMAND_CODE) 0x00000081)
+#define TPM_ORD_OwnerReadPubek ((TPM_COMMAND_CODE) 0x0000007D)
+#define TPM_ORD_OwnerSetDisable ((TPM_COMMAND_CODE) 0x0000006E)
+#define TPM_ORD_PCR_Reset ((TPM_COMMAND_CODE) 0x000000C8)
+#define TPM_ORD_PcrRead ((TPM_COMMAND_CODE) 0x00000015)
+#define TPM_ORD_PhysicalDisable ((TPM_COMMAND_CODE) 0x00000070)
+#define TPM_ORD_PhysicalEnable ((TPM_COMMAND_CODE) 0x0000006F)
+#define TPM_ORD_PhysicalSetDeactivated ((TPM_COMMAND_CODE) 0x00000072)
+#define TPM_ORD_Quote ((TPM_COMMAND_CODE) 0x00000016)
+#define TPM_ORD_Quote2 ((TPM_COMMAND_CODE) 0x0000003E)
+#define TPM_ORD_ReadCounter ((TPM_COMMAND_CODE) 0x000000DE)
+#define TPM_ORD_ReadManuMaintPub ((TPM_COMMAND_CODE) 0x00000030)
+#define TPM_ORD_ReadPubek ((TPM_COMMAND_CODE) 0x0000007C)
+#define TPM_ORD_ReleaseCounter ((TPM_COMMAND_CODE) 0x000000DF)
+#define TPM_ORD_ReleaseCounterOwner ((TPM_COMMAND_CODE) 0x000000E0)
+#define TPM_ORD_ReleaseTransportSigned ((TPM_COMMAND_CODE) 0x000000E8)
+#define TPM_ORD_Reset ((TPM_COMMAND_CODE) 0x0000005A)
+#define TPM_ORD_ResetLockValue ((TPM_COMMAND_CODE) 0x00000040)
+#define TPM_ORD_RevokeTrust ((TPM_COMMAND_CODE) 0x00000080)
+#define TPM_ORD_SaveAuthContext ((TPM_COMMAND_CODE) 0x000000B6)
+#define TPM_ORD_SaveContext ((TPM_COMMAND_CODE) 0x000000B8)
+#define TPM_ORD_SaveKeyContext ((TPM_COMMAND_CODE) 0x000000B4)
+#define TPM_ORD_SaveState ((TPM_COMMAND_CODE) 0x00000098)
+#define TPM_ORD_Seal ((TPM_COMMAND_CODE) 0x00000017)
+#define TPM_ORD_Sealx ((TPM_COMMAND_CODE) 0x0000003D)
+#define TPM_ORD_SelfTestFull ((TPM_COMMAND_CODE) 0x00000050)
+#define TPM_ORD_SetCapability ((TPM_COMMAND_CODE) 0x0000003F)
+#define TPM_ORD_SetOperatorAuth ((TPM_COMMAND_CODE) 0x00000074)
+#define TPM_ORD_SetOrdinalAuditStatus ((TPM_COMMAND_CODE) 0x0000008D)
+#define TPM_ORD_SetOwnerInstall ((TPM_COMMAND_CODE) 0x00000071)
+#define TPM_ORD_SetOwnerPointer ((TPM_COMMAND_CODE) 0x00000075)
+#define TPM_ORD_SetRedirection ((TPM_COMMAND_CODE) 0x0000009A)
+#define TPM_ORD_SetTempDeactivated ((TPM_COMMAND_CODE) 0x00000073)
+#define TPM_ORD_SHA1Complete ((TPM_COMMAND_CODE) 0x000000A2)
+#define TPM_ORD_SHA1CompleteExtend ((TPM_COMMAND_CODE) 0x000000A3)
+#define TPM_ORD_SHA1Start ((TPM_COMMAND_CODE) 0x000000A0)
+#define TPM_ORD_SHA1Update ((TPM_COMMAND_CODE) 0x000000A1)
+#define TPM_ORD_Sign ((TPM_COMMAND_CODE) 0x0000003C)
+#define TPM_ORD_Startup ((TPM_COMMAND_CODE) 0x00000099)
+#define TPM_ORD_StirRandom ((TPM_COMMAND_CODE) 0x00000047)
+#define TPM_ORD_TakeOwnership ((TPM_COMMAND_CODE) 0x0000000D)
+#define TPM_ORD_Terminate_Handle ((TPM_COMMAND_CODE) 0x00000096)
+#define TPM_ORD_TickStampBlob ((TPM_COMMAND_CODE) 0x000000F2)
+#define TPM_ORD_UnBind ((TPM_COMMAND_CODE) 0x0000001E)
+#define TPM_ORD_Unseal ((TPM_COMMAND_CODE) 0x00000018)
+#define TSC_ORD_PhysicalPresence ((TPM_COMMAND_CODE) 0x4000000A)
+#define TSC_ORD_ResetEstablishmentBit ((TPM_COMMAND_CODE) 0x4000000B)
+
+//
+// Part 2, section 18: Context structures
+//
+
+typedef struct tdTPM_CONTEXT_BLOB
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_RESOURCE_TYPE resourceType;
+ TPM_HANDLE handle;
+ UINT8 label[16];
+ UINT32 contextCount;
+ TPM_DIGEST integrityDigest;
+ UINT32 additionalSize;
+ UINT8 *additionalData;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveData;
+} TPM_CONTEXT_BLOB;
+
+typedef struct tdTPM_CONTEXT_SENSITIVE
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_NONCE contextNonce;
+ UINT32 internalSize;
+ UINT8 *internalData;
+} TPM_CONTEXT_SENSITIVE;
+
+//
+// Part 2, section 19: NV Structures
+//
+
+#define TPM_NV_INDEX_LOCK ((UINT32)0xffffffff)
+#define TPM_NV_INDEX0 ((UINT32)0x00000000)
+#define TPM_NV_INDEX_DIR ((UINT32)0x10000001)
+#define TPM_NV_INDEX_EKCert ((UINT32)0x0000f000)
+#define TPM_NV_INDEX_TPM_CC ((UINT32)0x0000f001)
+#define TPM_NV_INDEX_PlatformCert ((UINT32)0x0000f002)
+#define TPM_NV_INDEX_Platform_CC ((UINT32)0x0000f003)
+// The following define ranges of reserved indices.
+#define TPM_NV_INDEX_TSS_BASE ((UINT32)0x00011100)
+#define TPM_NV_INDEX_PC_BASE ((UINT32)0x00011200)
+#define TPM_NV_INDEX_SERVER_BASE ((UINT32)0x00011300)
+#define TPM_NV_INDEX_MOBILE_BASE ((UINT32)0x00011400)
+#define TPM_NV_INDEX_PERIPHERAL_BASE ((UINT32)0x00011500)
+#define TPM_NV_INDEX_GROUP_RESV_BASE ((UINT32)0x00010000)
+
+typedef UINT32 TPM_NV_PER_ATTRIBUTES;
+// The typedefs TPM_NV_PER_ATTRIBUTES (not present in TPM 1.2 Spec. have been added
+// and structure fields that were to hold the following values
+#define TPM_NV_PER_READ_STCLEAR (((UINT32)1) << 31)
+#define TPM_NV_PER_AUTHREAD (((UINT32)1) << 18)
+#define TPM_NV_PER_OWNERREAD (((UINT32)1) << 17)
+#define TPM_NV_PER_PPREAD (((UINT32)1) << 16)
+#define TPM_NV_PER_GLOBALLOCK (((UINT32)1) << 15)
+#define TPM_NV_PER_WRITE_STCLEAR (((UINT32)1) << 14)
+#define TPM_NV_PER_WRITEDEFINE (((UINT32)1) << 13)
+#define TPM_NV_PER_WRITEALL (((UINT32)1) << 12)
+#define TPM_NV_PER_AUTHWRITE (((UINT32)1) << 2)
+#define TPM_NV_PER_OWNERWRITE (((UINT32)1) << 1)
+#define TPM_NV_PER_PPWRITE (((UINT32)1) << 0)
+
+typedef struct tdTPM_NV_ATTRIBUTES
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_NV_PER_ATTRIBUTES attributes;
+} TPM_NV_ATTRIBUTES;
+
+
+typedef struct tdTPM_NV_DATA_PUBLIC
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_NV_INDEX nvIndex;
+ TPM_PCR_INFO_SHORT pcrInfoRead;
+ TPM_PCR_INFO_SHORT pcrInfoWrite;
+ TPM_NV_ATTRIBUTES permission;
+ BOOLEAN bReadSTClear;
+ BOOLEAN bWriteSTClear;
+ BOOLEAN bWriteDefine;
+ UINT32 dataSize;
+} TPM_NV_DATA_PUBLIC;
+
+
+
+// Internal to TPM:
+//typedef struct tdTPM_NV_DATA_SENSITIVE
+//{
+// TPM_STRUCTURE_TAG tag;
+// TPM_NV_DATA_PUBLIC pubInfo;
+// TPM_AUTHDATA authValue;
+// UINT8 *data;
+//} TPM_NV_DATA_SENSITIVE;
+
+
+//
+// Part 2, section 20: Delegation
+//
+
+//
+// Part 2, section 20.3: Owner Permissions Settings for per1 bits
+//
+#define TPM_DELEGATE_SetOrdinalAuditStatus (((UINT32)1) << 30)
+#define TPM_DELEGATE_DirWriteAuth (((UINT32)1) << 29)
+#define TPM_DELEGATE_CMK_ApproveMA (((UINT32)1) << 28)
+#define TPM_DELEGATE_CMK_CreateTicket (((UINT32)1) << 26)
+#define TPM_DELEGATE_Delegate_LoadOwnerDelegation (((UINT32)1) << 24)
+#define TPM_DELEGATE_DAA_Join (((UINT32)1) << 23)
+#define TPM_DELEGATE_AuthorizeMigrationKey (((UINT32)1) << 22)
+#define TPM_DELEGATE_CreateMaintenanceArchive (((UINT32)1) << 21)
+#define TPM_DELEGATE_LoadMaintenanceArchive (((UINT32)1) << 20)
+#define TPM_DELEGATE_KillMaintenanceFeature (((UINT32)1) << 19)
+#define TPM_DELEGATE_OwnerReadInteralPub (((UINT32)1) << 18)
+#define TPM_DELEGATE_ResetLockValue (((UINT32)1) << 17)
+#define TPM_DELEGATE_OwnerClear (((UINT32)1) << 16)
+#define TPM_DELEGATE_DisableOwnerClear (((UINT32)1) << 15)
+#define TPM_DELEGATE_OwnerSetDisable (((UINT32)1) << 13)
+#define TPM_DELEGATE_SetCapability (((UINT32)1) << 12)
+#define TPM_DELEGATE_MakeIdentity (((UINT32)1) << 11)
+#define TPM_DELEGATE_ActivateIdentity (((UINT32)1) << 10)
+#define TPM_DELEGATE_OwnerReadPubek (((UINT32)1) << 9)
+#define TPM_DELEGATE_DisablePubekRead (((UINT32)1) << 8)
+#define TPM_DELEGATE_SetRedirection (((UINT32)1) << 7)
+#define TPM_DELEGATE_FieldUpgrade (((UINT32)1) << 6)
+#define TPM_DELEGATE_Delegate_UpdateVerification (((UINT32)1) << 5)
+#define TPM_DELEGATE_CreateCounter (((UINT32)1) << 4)
+#define TPM_DELEGATE_ReleaseCounterOwner (((UINT32)1) << 3)
+#define TPM_DELEGATE_DelegateManage (((UINT32)1) << 2)
+#define TPM_DELEGATE_Delegate_CreateOwnerDelegation (((UINT32)1) << 1)
+#define TPM_DELEGATE_DAA_Sign (((UINT32)1) << 0)
+
+//
+// Part 2, section 20.3: Key Permissions Settings for per1 bits
+//
+#define TPM_KEY_DELEGATE_CMK_ConvertMigration (((UINT32)1) << 28)
+#define TPM_KEY_DELEGATE_TickStampBlob (((UINT32)1) << 27)
+#define TPM_KEY_DELEGATE_ChangeAuthAsymStart (((UINT32)1) << 26)
+#define TPM_KEY_DELEGATE_ChangeAuthAsymFinish (((UINT32)1) << 25)
+#define TPM_KEY_DELEGATE_CMK_CreateKey (((UINT32)1) << 24)
+#define TPM_KEY_DELEGATE_MigrateKey (((UINT32)1) << 23)
+#define TPM_KEY_DELEGATE_LoadKey2 (((UINT32)1) << 22)
+#define TPM_KEY_DELEGATE_EstablishTransport (((UINT32)1) << 21)
+#define TPM_KEY_DELEGATE_ReleaseTransportSigned (((UINT32)1) << 20)
+#define TPM_KEY_DELEGATE_Quote2 (((UINT32)1) << 19)
+#define TPM_KEY_DELEGATE_Sealx (((UINT32)1) << 18)
+#define TPM_KEY_DELEGATE_MakeIdentity (((UINT32)1) << 17)
+#define TPM_KEY_DELEGATE_ActivateIdentity (((UINT32)1) << 16)
+#define TPM_KEY_DELEGATE_GetAuditDigestSigned (((UINT32)1) << 15)
+#define TPM_KEY_DELEGATE_Sign (((UINT32)1) << 14)
+#define TPM_KEY_DELEGATE_CertifyKey2 (((UINT32)1) << 13)
+#define TPM_KEY_DELEGATE_CertifyKey (((UINT32)1) << 12)
+#define TPM_KEY_DELEGATE_CreateWrapKey (((UINT32)1) << 11)
+#define TPM_KEY_DELEGATE_CMK_CreateBlob (((UINT32)1) << 10)
+#define TPM_KEY_DELEGATE_CreateMigrationBlob (((UINT32)1) << 9)
+#define TPM_KEY_DELEGATE_ConvertMigrationBlob (((UINT32)1) << 8)
+#define TPM_KEY_DELEGATE_CreateKeyDelegation (((UINT32)1) << 7)
+#define TPM_KEY_DELEGATE_ChangeAuth (((UINT32)1) << 6)
+#define TPM_KEY_DELEGATE_GetPubKey (((UINT32)1) << 5)
+#define TPM_KEY_DELEGATE_UnBind (((UINT32)1) << 4)
+#define TPM_KEY_DELEGATE_Quote (((UINT32)1) << 3)
+#define TPM_KEY_DELEGATE_Unseal (((UINT32)1) << 2)
+#define TPM_KEY_DELEGATE_Seal (((UINT32)1) << 1)
+#define TPM_KEY_DELEGATE_LoadKey (((UINT32)1) << 0)
+
+#define TPM_FAMILY_CREATE ((UINT32)0x00000001)
+#define TPM_FAMILY_ENABLE ((UINT32)0x00000002)
+#define TPM_FAMILY_ADMIN ((UINT32)0x00000003)
+#define TPM_FAMILY_INVALIDATE ((UINT32)0x00000004)
+
+#define TPM_FAMFLAG_DELEGATE_ADMIN_LOCK (((UINT32)1) << 1)
+#define TPM_FAMFLAG_ENABLE (((UINT32)1) << 0)
+
+typedef struct tdTPM_FAMILY_LABEL
+{
+ UINT8 label;
+} TPM_FAMILY_LABEL;
+
+typedef struct tdTPM_FAMILY_TABLE_ENTRY
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_FAMILY_LABEL label;
+ TPM_FAMILY_ID familyID;
+ TPM_FAMILY_VERIFICATION verificationCount;
+ TPM_FAMILY_FLAGS flags;
+} TPM_FAMILY_TABLE_ENTRY;
+
+#define TPM_FAMILY_TABLE_ENTRY_MIN 8
+//typedef struct tdTPM_FAMILY_TABLE
+//{
+// TPM_FAMILY_TABLE_ENTRY FamTableRow[TPM_NUM_FAMILY_TABLE_ENTRY_MIN];
+//} TPM_FAMILY_TABLE;
+
+
+typedef struct tdTPM_DELEGATE_LABEL
+{
+ UINT8 label;
+} TPM_DELEGATE_LABEL;
+
+
+typedef UINT32 TPM_DELEGATE_TYPE;
+#define TPM_DEL_OWNER_BITS ((UINT32)0x00000001)
+#define TPM_DEL_KEY_BITS ((UINT32)0x00000002)
+
+typedef struct tdTPM_DELEGATIONS
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_TYPE delegateType;
+ UINT32 per1;
+ UINT32 per2;
+} TPM_DELEGATIONS;
+
+typedef struct tdTPM_DELEGATE_PUBLIC
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_LABEL label;
+ TPM_PCR_INFO_SHORT pcrInfo;
+ TPM_DELEGATIONS permissions;
+ TPM_FAMILY_ID familyID;
+ TPM_FAMILY_VERIFICATION verificationCount;
+} TPM_DELEGATE_PUBLIC;
+
+typedef struct tdTPM_DELEGATE_TABLE_ROW
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_PUBLIC pub;
+ TPM_SECRET authValue;
+} TPM_DELEGATE_TABLE_ROW;
+
+
+#define TPM_NUM_DELEGATE_TABLE_ENTRY_MIN 2
+//typedef struct tdTPM_DELEGATE_TABLE
+//{
+// TPM_DELEGATE_TABLE_ROW delRow[TPM_NUM_DELEGATE_TABLE_ENTRY_MIN];
+//} TPM_DELEGATE_TABLE;
+
+typedef struct tdTPM_DELEGATE_SENSITIVE
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_SECRET authValue;
+} TPM_DELEGATE_SENSITIVE;
+
+typedef struct tdTPM_DELEGATE_OWNER_BLOB
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_PUBLIC pub;
+ TPM_DIGEST integrityDigest;
+ UINT32 additionalSize;
+ UINT8 *additionalArea;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveArea;
+} TPM_DELEGATE_OWNER_BLOB;
+
+typedef struct tdTPM_DELEGATE_KEY_BLOB
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DELEGATE_PUBLIC pub;
+ TPM_DIGEST integrityDigest;
+ TPM_DIGEST pubKeyDigest;
+ UINT32 additionalSize;
+ UINT8 *additionalArea;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveArea;
+} TPM_DELEGATE_KEY_BLOB;
+
+//
+// Part 2, section 21.1: TPM_CAPABILITY_AREA for GetCapability
+//
+#define TPM_CAP_ORD ((TPM_CAPABILITY_AREA) 0x00000001)
+#define TPM_CAP_ALG ((TPM_CAPABILITY_AREA) 0x00000002)
+#define TPM_CAP_PID ((TPM_CAPABILITY_AREA) 0x00000003)
+#define TPM_CAP_FLAG ((TPM_CAPABILITY_AREA) 0x00000004)
+#define TPM_CAP_PROPERTY ((TPM_CAPABILITY_AREA) 0x00000005)
+#define TPM_CAP_VERSION ((TPM_CAPABILITY_AREA) 0x00000006)
+#define TPM_CAP_KEY_HANDLE ((TPM_CAPABILITY_AREA) 0x00000007)
+#define TPM_CAP_CHECK_LOADED ((TPM_CAPABILITY_AREA) 0x00000008)
+#define TPM_CAP_SYM_MODE ((TPM_CAPABILITY_AREA) 0x00000009)
+#define TPM_CAP_KEY_STATUS ((TPM_CAPABILITY_AREA) 0x0000000C)
+#define TPM_CAP_NV_LIST ((TPM_CAPABILITY_AREA) 0x0000000D)
+#define TPM_CAP_MFR ((TPM_CAPABILITY_AREA) 0x00000010)
+#define TPM_CAP_NV_INDEX ((TPM_CAPABILITY_AREA) 0x00000011)
+#define TPM_CAP_TRANS_ALG ((TPM_CAPABILITY_AREA) 0x00000012)
+#define TPM_CAP_HANDLE ((TPM_CAPABILITY_AREA) 0x00000014)
+#define TPM_CAP_TRANS_ES ((TPM_CAPABILITY_AREA) 0x00000015)
+#define TPM_CAP_AUTH_ENCRYPT ((TPM_CAPABILITY_AREA) 0x00000017)
+#define TPM_CAP_SELECT_SIZE ((TPM_CAPABILITY_AREA) 0x00000018)
+#define TPM_CAP_VERSION_VAL ((TPM_CAPABILITY_AREA) 0x0000001A)
+
+#define TPM_CAP_FLAG_PERMANENT ((TPM_CAPABILITY_AREA) 0x00000108)
+#define TPM_CAP_FLAG_VOLATILE ((TPM_CAPABILITY_AREA) 0x00000109)
+
+//
+// Part 2, section 21.2: CAP_PROPERTY Subcap values for GetCapability
+//
+#define TPM_CAP_PROP_PCR ((TPM_CAPABILITY_AREA) 0x00000101)
+#define TPM_CAP_PROP_DIR ((TPM_CAPABILITY_AREA) 0x00000102)
+#define TPM_CAP_PROP_MANUFACTURER ((TPM_CAPABILITY_AREA) 0x00000103)
+#define TPM_CAP_PROP_KEYS ((TPM_CAPABILITY_AREA) 0x00000104)
+#define TPM_CAP_PROP_MIN_COUNTER ((TPM_CAPABILITY_AREA) 0x00000107)
+#define TPM_CAP_PROP_AUTHSESS ((TPM_CAPABILITY_AREA) 0x0000010A)
+#define TPM_CAP_PROP_TRANSESS ((TPM_CAPABILITY_AREA) 0x0000010B)
+#define TPM_CAP_PROP_COUNTERS ((TPM_CAPABILITY_AREA) 0x0000010C)
+#define TPM_CAP_PROP_MAX_AUTHSESS ((TPM_CAPABILITY_AREA) 0x0000010D)
+#define TPM_CAP_PROP_MAX_TRANSESS ((TPM_CAPABILITY_AREA) 0x0000010E)
+#define TPM_CAP_PROP_MAX_COUNTERS ((TPM_CAPABILITY_AREA) 0x0000010F)
+#define TPM_CAP_PROP_MAX_KEYS ((TPM_CAPABILITY_AREA) 0x00000110)
+#define TPM_CAP_PROP_OWNER ((TPM_CAPABILITY_AREA) 0x00000111)
+#define TPM_CAP_PROP_CONTEXT ((TPM_CAPABILITY_AREA) 0x00000112)
+#define TPM_CAP_PROP_MAX_CONTEXT ((TPM_CAPABILITY_AREA) 0x00000113)
+#define TPM_CAP_PROP_FAMILYROWS ((TPM_CAPABILITY_AREA) 0x00000114)
+#define TPM_CAP_PROP_TIS_TIMEOUT ((TPM_CAPABILITY_AREA) 0x00000115)
+#define TPM_CAP_PROP_STARTUP_EFFECT ((TPM_CAPABILITY_AREA) 0x00000116)
+#define TPM_CAP_PROP_DELEGATE_ROW ((TPM_CAPABILITY_AREA) 0x00000117)
+#define TPM_CAP_PROP_DAA_MAX ((TPM_CAPABILITY_AREA) 0x00000119)
+#define CAP_PROP_SESSION_DAA ((TPM_CAPABILITY_AREA) 0x0000011A)
+#define TPM_CAP_PROP_CONTEXT_DIST ((TPM_CAPABILITY_AREA) 0x0000011B)
+#define TPM_CAP_PROP_DAA_INTERRUPT ((TPM_CAPABILITY_AREA) 0x0000011C)
+#define TPM_CAP_PROP_SESSIONS ((TPM_CAPABILITY_AREA) 0x0000011D)
+#define TPM_CAP_PROP_MAX_SESSIONS ((TPM_CAPABILITY_AREA) 0x0000011E)
+#define TPM_CAP_PROP_CMK_RESTRICTION ((TPM_CAPABILITY_AREA) 0x0000011F)
+#define TPM_CAP_PROP_DURATION ((TPM_CAPABILITY_AREA) 0x00000120)
+#define TPM_CAP_PROP_ACTIVE_COUNTER ((TPM_CAPABILITY_AREA) 0x00000122)
+#define TPM_CAP_PROP_MAX_NV_AVAILABLE ((TPM_CAPABILITY_AREA) 0x00000123)
+#define TPM_CAP_PROP_INPUT_BUFFER ((TPM_CAPABILITY_AREA) 0x00000124)
+
+//
+// Part 2, section 21.6: TPM_CAP_VERSION_INFO
+// [size_is(vendorSpecificSize)] BYTE* vendorSpecific;
+//
+typedef struct tdTPM_CAP_VERSION_INFO
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_VERSION version;
+ UINT16 specLevel;
+ UINT8 errataRev;
+ UINT8 tpmVendorID[4];
+ UINT16 vendorSpecificSize;
+ UINT8 *vendorSpecific;
+} TPM_CAP_VERSION_INFO;
+
+//
+// Part 2, section 22: DAA Structures
+//
+
+#define TPM_DAA_SIZE_r0 (43)
+#define TPM_DAA_SIZE_r1 (43)
+#define TPM_DAA_SIZE_r2 (128)
+#define TPM_DAA_SIZE_r3 (168)
+#define TPM_DAA_SIZE_r4 (219)
+#define TPM_DAA_SIZE_NT (20)
+#define TPM_DAA_SIZE_v0 (128)
+#define TPM_DAA_SIZE_v1 (192)
+#define TPM_DAA_SIZE_NE (256)
+#define TPM_DAA_SIZE_w (256)
+#define TPM_DAA_SIZE_issuerModulus (256)
+#define TPM_DAA_power0 (104)
+#define TPM_DAA_power1 (1024)
+
+typedef struct tdTPM_DAA_ISSUER
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST DAA_digest_R0;
+ TPM_DIGEST DAA_digest_R1;
+ TPM_DIGEST DAA_digest_S0;
+ TPM_DIGEST DAA_digest_S1;
+ TPM_DIGEST DAA_digest_n;
+ TPM_DIGEST DAA_digest_gamma;
+ UINT8 DAA_generic_q[26];
+} TPM_DAA_ISSUER;
+
+
+typedef struct tdTPM_DAA_TPM
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST DAA_digestIssuer;
+ TPM_DIGEST DAA_digest_v0;
+ TPM_DIGEST DAA_digest_v1;
+ TPM_DIGEST DAA_rekey;
+ UINT32 DAA_count;
+} TPM_DAA_TPM;
+
+typedef struct tdTPM_DAA_CONTEXT
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_DIGEST DAA_digestContext;
+ TPM_DIGEST DAA_digest;
+ TPM_DAA_CONTEXT_SEED DAA_contextSeed;
+ UINT8 DAA_scratch[256];
+ UINT8 DAA_stage;
+} TPM_DAA_CONTEXT;
+
+typedef struct tdTPM_DAA_JOINDATA
+{
+ UINT8 DAA_join_u0[128];
+ UINT8 DAA_join_u1[138];
+ TPM_DIGEST DAA_digest_n0;
+} TPM_DAA_JOINDATA;
+
+typedef struct tdTPM_DAA_BLOB
+{
+ TPM_STRUCTURE_TAG tag;
+ TPM_RESOURCE_TYPE resourceType;
+ UINT8 label[16];
+ TPM_DIGEST blobIntegrity;
+ UINT32 additionalSize;
+ UINT8 *additionalData;
+ UINT32 sensitiveSize;
+ UINT8 *sensitiveData;
+} TPM_DAA_BLOB;
+
+typedef struct tdTPM_DAA_SENSITIVE
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT32 internalSize;
+ UINT8 *internalData;
+} TPM_DAA_SENSITIVE;
+
+
+//
+// Part 2, section 23: Redirection
+//
+
+// This section of the TPM spec defines exactly one value but does not
+// give it a name. The definition of TPM_SetRedirection in Part3
+// refers to exactly one name but does not give its value. We join
+// them here.
+#define TPM_REDIR_GPIO (0x00000001)
+
+//
+// TPM Command & Response Headers
+//
+typedef struct tdTPM_RQU_COMMAND_HDR
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT32 paramSize;
+ TPM_COMMAND_CODE ordinal;
+} TPM_RQU_COMMAND_HDR;
+
+typedef struct tdTPM_RSP_COMMAND_HDR
+{
+ TPM_STRUCTURE_TAG tag;
+ UINT32 paramSize;
+ TPM_RESULT returnCode;
+} TPM_RSP_COMMAND_HDR;
+
+#pragma pack (pop)
+
+#endif // _TPM12_H_
diff --git a/Core/EM/TCG2/TisLib/TcmPc.h b/Core/EM/TCG2/TisLib/TcmPc.h
new file mode 100644
index 0000000..9431fa3
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TcmPc.h
@@ -0,0 +1,153 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcmPc.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TcmPc.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 2 3/29/11 12:27p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TcmPc.h
+//
+// Description:
+// Header file for Tcm structures
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#ifndef _TCMPC_H_
+#define _TCMPC_H_
+#include "TcgEfi12.h"
+
+
+#pragma pack (push)
+#pragma pack (1)
+
+
+
+typedef struct tdTCM_PCR_EVENT {
+ UINT32 PCRIndex; // PCRIndex event extended to
+ UINT32 EventType; // TCG EFI event type
+ TCM_DIGEST Digest; // Value extended into PCRIndex
+ UINT32 EventSize; // Size of the event data
+ UINT8 Event[1]; // The event data
+} TCM_PCR_EVENT;
+
+
+struct _EFI_TCM_EV_S_CRTM_VERSION {
+ EFI_GUID VersionGuid;
+};
+
+
+struct _EFI_TCM_EV_POST_CODE {
+ EFI_PHYSICAL_ADDRESS PostCodeAddress;
+ UINT64 PostCodeLength;
+};
+
+
+struct _EFI_TCM_EV_TAG_OPTION_ROM_EXECUTE
+{
+ UINT16 Reserved;
+ UINT16 PFA;
+ TCM_DIGEST Hash;
+};
+
+
+struct _EFI_TCM_EV_CPU_MICROCODE
+{
+ EFI_PHYSICAL_ADDRESS MicrocodeEntrypoint;
+};
+
+
+union _EFI_TCM_EV_TAG_EVENT_DATA
+{
+ struct _EFI_TCM_EV_TAG_OPTION_ROM_EXECUTE
+ OptionRomExecute;
+};
+
+
+struct _EFI_TCM_EV_TAG
+{
+ UINT32 EventID;
+ UINT32 EventSize;
+ union _EFI_TCM_EV_TAG_EVENT_DATA EventData;
+};
+
+
+typedef struct _EFI_TCM_PCR_EVENT_HEADER
+{
+ TPM_PCRINDEX PCRIndex;
+ UINT32 EventType;
+ TCM_DIGEST Digest;
+ UINT32 EventDataSize;
+} EFI_TCM_PCR_EVENT_HEADER;
+
+
+typedef union _EFI_TCM_PCR_EVENT_DATA
+{
+ struct _EFI_TCM_EV_S_CRTM_VERSION SCrtmVersion;
+ struct _EFI_TCM_EV_POST_CODE PostCode;
+ struct _EFI_TCM_EV_TAG Tagged;
+ struct _EFI_TCM_EV_CPU_MICROCODE Mcu;
+} EFI_TCM_PCR_EVENT_DATA;
+
+
+
+typedef struct _EFI_TCM_PCR_EVENT
+{
+ EFI_TCM_PCR_EVENT_HEADER Header;
+ EFI_TCM_PCR_EVENT_DATA Event;
+} EFI_TCM_PCR_EVENT;
+
+#pragma pack (pop)
+
+#endif // _TPMPC_H_
diff --git a/Core/EM/TCG2/TisLib/TisLib.cif b/Core/EM/TCG2/TisLib/TisLib.cif
new file mode 100644
index 0000000..fcafbfb
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TisLib.cif
@@ -0,0 +1,23 @@
+<component>
+ name = "TisLib"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\TisLib"
+ RefName = "TisLib"
+[files]
+"TisLib.mak"
+"TcgTpm12.h"
+"TpmLib.h"
+"TcgCommon.h"
+"ZTEICTcmOrdinals.h"
+"TpmLib.c"
+"TcgCommon.c"
+"TisLib.sdl"
+"sha.h"
+"INTTcgAcpi.h"
+"TcgPc.h"
+"TcmPc.h"
+"TcgEfiTpm.h"
+"TcgEFI12.h"
+[parts]
+"AmiTcmlib"
+<endComponent>
diff --git a/Core/EM/TCG2/TisLib/TisLib.mak b/Core/EM/TCG2/TisLib/TisLib.mak
new file mode 100644
index 0000000..1e79a4f
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TisLib.mak
@@ -0,0 +1,116 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TisLib.mak 1 4/21/14 2:14p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:14p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TisLib.mak $
+#
+# 1 4/21/14 2:14p Fredericko
+#
+# 1 10/08/13 11:58a Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 12:31p Fredericko
+#
+# 1 7/10/13 5:50p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+# [Files] TisLib.cif
+# TisLib.mak
+# TcgTpm12.h
+# TpmLib.h
+# TcgCommon.h
+# ZTEICTcmOrdinals.h
+# TpmLib.c
+# TcgCommon.c
+# TisLib.sdl
+# sha1.h
+# INTTcgAcpi.h
+# TcgPc.h
+# TcmPc.h
+# TcgEfiTpm.h
+# TcgEFI12.h
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Tpm12lib.mak
+#
+# Description: Make file for the tcglib component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+Tpm12_lib : $(BUILD_DIR)\TisLib.mak make_TisLib_lib make_TisLib_libPei
+$(BUILD_DIR)\TisLib.lib: Tpm12_lib
+$(BUILD_DIR)\IA32\TisLib.lib: Tpm12_lib
+
+tcg_lib_lite: $(BUILD_DIR)\TisLib.mak tcg_lib_liteBin
+$(tcgLibLite): tcg_lib_lite
+
+$(BUILD_DIR)\TisLib.mak : $(TPM12_DIR)\TisLib.cif $(TPM12_DIR)\TisLib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(TPM12_DIR)\TisLib.cif $(CIF2MAK_DEFAULTS)
+
+TCG12LIB_CFLAGS=$(CFLAGS)\
+ /I$(TPM12_DIR)\
+ /I$(TCG_DIR)\
+
+TCG_LIB_LITE_OBJS = \
+$(BUILD_DIR)\$(TPM12_DIR)\TpmLib.obj
+
+tcg_lib_liteBin: $(BUILD_DIR)\AmiTcmlib.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TisLib.mak all\
+ "CFLAGS=$(TCG12LIB_CFLAGS) "\
+ "OBJECTS=$(TCG_LIB_LITE_OBJS)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(tcgLibLite)
+
+!IF "$(PROCESSOR)"=="x64"
+make_TisLib_lib: $(BUILD_DIR)\AmiTcmlib.lib $(SHALIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TisLib.mak all\
+ "CFLAGS=$(TCG12LIB_CFLAGS) "\
+ TYPE=LIBRARY
+
+make_TisLib_libPei: $(BUILD_DIR)\AmiTcmlib.lib $(SHALIBPEI)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\TisLib.mak all\
+ "CFLAGS=$(TCG12LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TisLib.mak all\
+ "CFLAGS=$(TCG12LIB_CFLAGS) "\
+ TYPE=PEI_LIBRARY
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/TCG2/TisLib/TisLib.sdl b/Core/EM/TCG2/TisLib/TisLib.sdl
new file mode 100644
index 0000000..95ee12d
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TisLib.sdl
@@ -0,0 +1,46 @@
+TOKEN
+ Name = "TPM12_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TCG support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "TCG2Support" "=" "1"
+End
+
+TOKEN
+ Name = "TPM_DRIVER_WAIT"
+ Value = "005h"
+ Help = "Delay count for TPM wait loop. Default is 50us. Please dont change to less than 2 (4us)."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DELAY_AMOUNT"
+ Value = "010"
+ Help = "Delay amount for TPM wait loop. Default is 5us. Please dont change to less than 2 (2us)."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+PATH
+ Name = "TPM12_DIR"
+ Help = "Tcg Directory"
+End
+
+MODULE
+ Help = "Includes TCG.mak to Project"
+ File = "TisLib.mak"
+End
+
+TOKEN
+ Name = "tcgLibLite"
+ Value = "$(BUILD_DIR)\tcgLibLite.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End \ No newline at end of file
diff --git a/Core/EM/TCG2/TisLib/TpmLib.c b/Core/EM/TCG2/TisLib/TpmLib.c
new file mode 100644
index 0000000..66dd24a
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TpmLib.c
@@ -0,0 +1,614 @@
+/*++
+
+Copyright (c) 2005 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ TpmLib.h
+
+Abstract:
+
+ Common code of TPM driver in both PEI and DXE
+--*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TpmLib.c 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TpmLib.c $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 2 10/03/13 12:33p Fredericko
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 23 9/08/11 4:46p Fredericko
+// [TAG] EIPEIP0000
+// [Category] Improvement
+// [Description] Added ability to modify Delay Amount for TPM driver
+// [Files] Tcg.sdl
+// Tpmlib.c
+//
+// 22 8/26/11 12:31p Fredericko
+// [TAG] EIP64300
+// [Category] Improvement
+// [Description] Allow variations for TPM driver wait times.
+// [Files] Tpmlib.c
+// Tcg.sd
+//
+// 21 7/07/10 12:09p Fredericko
+// Make Wait variable a #define.
+//
+// 20 5/19/10 4:50p Fredericko
+// Included File Header
+//
+// 19 5/18/10 5:39p Fredericko
+// Code Beautification and Enhancement
+//
+// 18 5/18/10 11:32a Fredericko
+// Header modification for AMI code standard.
+//
+// 17 5/04/10 3:36p Fredericko
+// Source Enhancement. EIP 22208
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmLib.c
+//
+// Description:
+// Contains low level TCG functions
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Efi.h>
+#include "TpmLib.h"
+#include "AmiLib.h"
+#include <token.h>
+
+extern EFI_STATUS CountTime ( IN UINTN DelayTime, IN UINT16 BaseAddr); // only needs to be 16 bit for I/O address)
+#define Wait TPM_DRIVER_WAIT
+#define ACCESS_WAITCOUNT (750 * 1000 / 100) // 750MS (750 * 10000 /1000)
+#define ACCESS_WAITCOUNTB ( 3 * 1000000/100) // 3 seconds delay
+
+#define TIS_TIMEOUT_A ACCESS_WAITCOUNT
+#define TIS_TIMEOUT_B ACCESS_WAITCOUNTB
+#define TIS_TIMEOUT_C ACCESS_WAITCOUNT
+#define TIS_TIMEOUT_D ACCESS_WAITCOUNT
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: FixedDelay
+//
+// Description: This routine delays for specified number of micro seconds
+//
+// Input: IN UINT32 dCount Amount of delay (count in 20microsec)
+//
+// Output: NONE
+//
+// Modified:
+//
+// Referrals: Div64, CountTime
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+
+void
+__stdcall
+FixedDelay(UINT32 dCount)
+{
+ UINTN TickPeriod = 0x03;
+ UINTN Remainder = 0x1;
+ UINTN MicroSDelay = DELAY_AMOUNT;
+ UINT32 Data32, PrevData;
+ UINTN i=0;
+ UINT32 Counter = 0x00;
+
+ Counter = (UINT32)Div64((MicroSDelay * 10), TickPeriod, &Remainder);
+
+ if(Remainder != 0) {
+ Counter++;
+ }
+ while(dCount) {
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+ dCount--;
+ }
+}
+
+
+
+static
+UINT8
+__stdcall
+CheckAccessBit (
+ IN volatile UINT8 *Sts,
+ IN UINT8 Bit,
+ IN UINT32 Timeout
+ )
+/*++
+Routine Description:
+ Function to check bits in TPM access register
+Arguments:
+ *Sts - A Pointer to Status register
+ Bit - Bit position
+ Timeout - Timeout amount to wait till the specified bit
+Returns:
+ EFI_Status
+--*/
+{
+ UINT32 AccessCount = Timeout;
+
+ if(!(*Sts & TPM_STS_VALID))
+ return 0;
+
+ do {
+
+ FixedDelay((UINT32)Wait);
+ if((*Sts & Bit)){ return *Sts & Bit; }
+ AccessCount--;
+ } while (AccessCount);
+
+ return 0;
+}
+
+
+
+static
+UINT8
+__stdcall
+CheckStsBit (
+ IN volatile UINT8 *Sts,
+ IN UINT8 Bit
+ )
+/*++
+Routine Description:
+ Function to check status a specific TPM status bit
+Arguments:
+ *Sts - A Pointer to Status register
+ Bit - Bit position
+Returns:
+ EFI_Status
+--*/
+{
+ while (!(*Sts & TPM_STS_VALID));
+ return *Sts & Bit;
+}
+
+
+
+
+static
+UINT16
+__stdcall
+ReadBurstCount (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+)
+/*++
+Routine Description:
+ Gets the number of bytes (burstCount) that the TPM can return
+ on reads or accept on writes without inserting LPC long wait
+ states on the LPC bus.
+ burstCount is TPM_STS_x register bits 8..23
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+Returns:
+ 0 - Any Errors
+ burstCount - TPM_STS_x.burstCount
+--*/
+{
+ UINT16 burstCount;
+ UINT64 Deadline = TIS_TIMEOUT_D;
+
+ burstCount = 0;
+
+ do {
+ //
+ // burstCount is little-endian bit ordering
+ //
+ FixedDelay((UINT32)Wait);
+ Deadline--;
+ burstCount = TpmReg->BurstCount;
+ }while (!burstCount && (Deadline > 0));
+
+ return burstCount;
+}
+
+
+
+EFI_STATUS
+__stdcall
+TisRequestLocality (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+ )
+/*++
+Routine Description:
+ Requests TPM locality 0
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+Returns:
+ EFI_Status
+--*/
+{
+ if ((TpmReg->Access & TPM_ACC_ACTIVE_LOCALITY)==TPM_ACC_ACTIVE_LOCALITY){
+ return EFI_SUCCESS;//EFI_ALREADY_STARTED;
+ }
+ TpmReg->Access = TPM_ACC_REQUEST_USE;
+ if (CheckAccessBit(&TpmReg->Access, TPM_ACC_ACTIVE_LOCALITY, (UINT32)TIS_TIMEOUT_B)) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_NOT_READY;
+ }
+}
+
+
+
+#pragma optimize("",off)
+EFI_STATUS
+__stdcall
+TisReleaseLocality (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+ )
+/*++
+Routine Description:
+ Release TPM locality 0
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+Returns:
+ EFI_Status
+--*/
+{
+ UINT32 AccessCount=ACCESS_WAITCOUNT;
+ if (!CheckStsBit (&TpmReg->Access, TPM_ACC_ACTIVE_LOCALITY)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ TpmReg->Access = TPM_ACC_ACTIVE_LOCALITY;
+ if (CheckStsBit(&TpmReg->Access, TPM_ACC_ACTIVE_LOCALITY)) {
+ do{/*give locality time to be released*/
+ FixedDelay((UINT32)Wait);
+ AccessCount--;
+ }while(((CheckStsBit(&TpmReg->Access, TPM_ACC_ACTIVE_LOCALITY)) && AccessCount));
+ if(CheckStsBit(&TpmReg->Access, TPM_ACC_ACTIVE_LOCALITY)){return EFI_DEVICE_ERROR;}
+ else{return EFI_SUCCESS;}
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+#pragma optimize("",on)
+
+
+
+
+EFI_STATUS
+__stdcall
+TisPrepareSendCommand (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+ )
+/*++
+Routine Description:
+ Helper function to prepare to send a TPM command
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+Returns:
+ EFI_Status
+--*/
+{
+
+ if((TpmReg->Access & TPM_ACC_ACTIVE_LOCALITY)!=TPM_ACC_ACTIVE_LOCALITY){
+ return EFI_NOT_STARTED;
+ }
+
+ do {
+ TpmReg->Sts = TPM_STS_READY;
+ } while (!(TpmReg->Sts & TPM_STS_READY));
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+__stdcall
+TisSendCommand (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ IN const VOID *CmdStream,
+ IN UINTN Size,
+ IN BOOLEAN Last
+ )
+/*++
+Routine Description:
+ Function to send TPM command
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+ *CmdStream - A Pointer to the command stream to be sent to TPM Fifo
+ Size - Size in bytes of the command stream
+ Last - Boolean to signify the last byte?
+Returns:
+ EFI_Status
+--*/
+{
+ UINT8 *Ptr;
+ UINT16 burstCount;
+
+ if (Size == 0) {
+ return Last ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
+ }
+
+ if ((TpmReg->Access & TPM_ACC_ACTIVE_LOCALITY)!=TPM_ACC_ACTIVE_LOCALITY) {
+ return EFI_ABORTED;
+ }
+
+ Ptr = (UINT8*)CmdStream;
+
+ if (Last) {
+ Size--;
+ }
+
+ while (Size > 0) {
+ burstCount = ReadBurstCount(TpmReg);
+ if (burstCount == 0) {
+ // Cannot get the correct burstCount value
+ return EFI_TIMEOUT;
+ }
+
+ for (; burstCount > 0 && Size > 0; burstCount--) {
+ *(UINT8*)&TpmReg->DataFifo = *Ptr;
+ Ptr++;
+ Size--;
+ }
+ }
+
+ if (Last) {
+ if (!CheckStsBit (&TpmReg->Sts, TPM_STS_EXPECT)) {
+ return EFI_ABORTED;
+ }
+
+ *(UINT8*)&TpmReg->DataFifo = *Ptr;
+
+ if (CheckStsBit (&TpmReg->Sts, TPM_STS_EXPECT)) {
+ return EFI_ABORTED;
+ }
+
+ TpmReg->Sts = TPM_STS_GO;
+
+ }
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_STATUS
+__stdcall
+TisWaitForResponse (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+ )
+/*++
+Routine Description:
+ Waits till TPM result is available
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+Returns:
+ EFI_Status
+--*/
+{
+ if((TpmReg->Access & TPM_ACC_ACTIVE_LOCALITY)!=TPM_ACC_ACTIVE_LOCALITY){
+ return EFI_NOT_STARTED;
+ }
+
+ while (!CheckStsBit (&TpmReg->Sts, TPM_STS_DATA_AVAILABLE));
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_STATUS
+__stdcall
+TisReceiveResponse (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ OUT VOID *Buffer,
+ OUT UINTN *Size
+ )
+/*++
+Routine Description:
+ Function to recieve TPM command results
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+ *Buffer - A Pointer to buffer for recieving result data
+ Size - buffer size
+Returns:
+ EFI_Status
+--*/
+{
+ UINT8 *Ptr, *BufEnd;
+ UINT16 burstCount;
+
+ if((TpmReg->Access & TPM_ACC_ACTIVE_LOCALITY)!=TPM_ACC_ACTIVE_LOCALITY) {
+ return EFI_ABORTED;
+ }
+
+ Ptr = (UINT8*)Buffer;
+ BufEnd = Ptr + *Size;
+ while (Ptr < BufEnd &&
+ CheckStsBit (&TpmReg->Sts, TPM_STS_DATA_AVAILABLE)) {
+
+ burstCount = ReadBurstCount(TpmReg);
+ if (burstCount == 0) {
+ return EFI_TIMEOUT;
+ }
+ while(burstCount && Ptr < BufEnd && CheckStsBit (&TpmReg->Sts, TPM_STS_DATA_AVAILABLE )){
+ *Ptr++ = *(UINT8*)&TpmReg->DataFifo;
+ burstCount--; }
+ }
+
+ *Size -= BufEnd - Ptr;
+ if (CheckStsBit (&TpmReg->Sts, TPM_STS_DATA_AVAILABLE)) {
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ return EFI_SUCCESS;
+ }
+}
+
+
+
+VOID
+__stdcall
+TisResendResponse (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+ )
+/*++
+Routine Description:
+ Sets Bit to resend TPM command
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+Returns:
+ EFI_Status
+--*/
+{
+ TpmReg->Sts = TPM_STS_RESPONSE_RETRY;
+}
+
+EFI_STATUS
+__stdcall
+IsTpmPresent (
+ IN TPM_1_2_REGISTERS_PTR TpmReg
+ )
+{
+ if (TpmReg->Access == 0xff) {
+ return EFI_NOT_FOUND;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+
+
+EFI_STATUS
+__stdcall
+TpmLibPassThrough (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers
+ )
+/*++
+Routine Description:
+ Higher level function to send a recieve commands to the TPM
+Arguments:
+ TpmReg - A Pointer to the TPM Register Space
+ NoInputBuffers - Number count of Input buffers
+ *InputBuffers - Pointer to InputBuffers[0]
+ NoOutputBuffers - Number count of Output buffers
+ *OutputBuffers - Pointer to OutputBuffers[0]
+Returns:
+ EFI_Status
+--*/
+{
+ EFI_STATUS Status;
+ UINTN i;
+
+ if (NoInputBuffers == 0 || InputBuffers->Size < sizeof (TPM_1_2_CMD_HEADER)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ do {
+ NoInputBuffers--;
+ } while (InputBuffers[NoInputBuffers].Size == 0 && NoInputBuffers > 0);
+
+ if (InputBuffers[NoInputBuffers].Size == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = TisPrepareSendCommand (TpmReg);
+
+ for (i = 0; !EFI_ERROR (Status) && i < NoInputBuffers; i++) {
+ Status = TisSendCommand (
+ TpmReg,
+ InputBuffers[i].Buffer,
+ InputBuffers[i].Size,
+ FALSE
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = TisSendCommand (
+ TpmReg,
+ InputBuffers[i].Buffer,
+ InputBuffers[i].Size,
+ TRUE
+ );
+ }
+
+ if (!EFI_ERROR (Status)) {
+ Status = TisWaitForResponse (TpmReg);
+ }
+
+ if (EFI_ERROR (Status)) {
+ goto Exit;
+ }
+
+ Status = EFI_BUFFER_TOO_SMALL;
+ for (i = 0; Status == EFI_BUFFER_TOO_SMALL && i < NoOutputBuffers; i++) {
+ Status = TisReceiveResponse (
+ TpmReg,
+ OutputBuffers[i].Buffer,
+ &OutputBuffers[i].Size
+ );
+ }
+
+Exit:
+ TisCompleteCommand (TpmReg);
+ return Status;
+}
diff --git a/Core/EM/TCG2/TisLib/TpmLib.h b/Core/EM/TCG2/TisLib/TpmLib.h
new file mode 100644
index 0000000..1e98660
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/TpmLib.h
@@ -0,0 +1,136 @@
+/*++
+
+ Copyright (c) 2005 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ TpmLib.h
+
+ Abstract:
+
+ Header file for tpm device drivers
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TpmLib.h 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/TpmLib.h $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 3 5/19/10 5:11p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TpmLib.c
+//
+// Description:
+// Header file for TpmLib.c
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#ifndef _TPMLIB_H_
+#define _TPMLIB_H_
+
+#include "TcgPc.h"
+
+#define TisCompleteCommand TisPrepareSendCommand
+
+extern
+EFI_STATUS
+__stdcall TisRequestLocality (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+extern
+EFI_STATUS
+__stdcall TisReleaseLocality (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+extern
+EFI_STATUS
+__stdcall TisPrepareSendCommand (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+extern
+EFI_STATUS
+__stdcall TisSendCommand (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ IN const VOID *CmdStream,
+ IN UINTN Size,
+ IN BOOLEAN Last );
+
+extern
+EFI_STATUS
+__stdcall TisWaitForResponse (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+extern
+EFI_STATUS
+__stdcall TisReceiveResponse (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ OUT VOID *Buffer,
+ OUT UINTN *Size );
+
+extern
+EFI_STATUS
+__stdcall IsTpmPresent (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+extern
+EFI_STATUS
+__stdcall TpmLibPassThrough (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers );
+
+extern
+EFI_STATUS
+__stdcall TpmLibStartup (
+ IN UINT16 StartupType );
+
+#endif
diff --git a/Core/EM/TCG2/TisLib/ZTEICTcmOrdinals.h b/Core/EM/TCG2/TisLib/ZTEICTcmOrdinals.h
new file mode 100644
index 0000000..edf35ea
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/ZTEICTcmOrdinals.h
@@ -0,0 +1,203 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/ZTEICTcmOrdinals.h 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/ZTEICTcmOrdinals.h $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 7 3/29/11 12:26p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: ZTEICTcmOrdinals.h
+//
+// Description:
+// Header file for ZTEIC specific ordinals
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#define TCM_ORD_ActivateIdentity ((UINT32) 0x0000807A)
+#define TCM_ORD_AuthorizeMigrationKey ((UINT32) 0x0000802B)
+#define TCM_ORD_CertifyKey ((UINT32) 0x00008032)
+#define TCM_ORD_CertifyKey2 ((UINT32) 0x00008033)
+#define TCM_ORD_CertifySelfTest ((UINT32) 0x00008052)
+#define TCM_ORD_ChangeAuth ((UINT32) 0x0000800C)
+#define TCM_ORD_ChangeAuthAsymFinish ((UINT32) 0x0000800F)
+#define TCM_ORD_ChangeAuthAsymStart ((UINT32) 0x0000800E)
+#define TCM_ORD_ChangeAuthOwner ((UINT32) 0x00008010)
+#define TCM_ORD_CMK_ApproveMA ((UINT32) 0x0000801D)
+#define TCM_ORD_CMK_ConvertMigration ((UINT32) 0x00008024)
+#define TCM_ORD_CMK_CreateBlob ((UINT32) 0x0000801B)
+#define TCM_ORD_CMK_CreateKey ((UINT32) 0x00008013)
+#define TCM_ORD_CMK_CreateTicket ((UINT32) 0x00008012)
+#define TCM_ORD_CMK_SetRestrictions ((UINT32) 0x0000801C)
+#define TCM_ORD_ContinueSelfTest ((UINT32) 0x00008053)
+#define TCM_ORD_ConvertMigrationBlob ((UINT32) 0x0000802A)
+#define TCM_ORD_CreateCounter ((UINT32) 0x000080DC)
+#define TCM_ORD_CreateEndorsementKeyPair ((UINT32) 0x00008078)
+#define TCM_ORD_CreateMaintenanceArchive ((UINT32) 0x0000802C)
+#define TCM_ORD_CreateMigrationBlob ((UINT32) 0x00008028)
+#define TCM_ORD_CreateRevocableEK ((UINT32) 0x0000807F)
+#define TCM_ORD_CreateWrapKey ((UINT32) 0x0000801F)
+#define TCM_ORD_DAA_JOIN ((UINT32) 0x00008029)
+#define TCM_ORD_DAA_SIGN ((UINT32) 0x00008031)
+#define TCM_ORD_Delegate_CreateKeyDelegation ((UINT32) 0x000080D4)
+#define TCM_ORD_Delegate_CreateOwnerDelegation ((UINT32) 0x000080D5)
+#define TCM_ORD_Delegate_LoadOwnerDelegation ((UINT32) 0x000080D8)
+#define TCM_ORD_Delegate_Manage ((UINT32) 0x000080D2)
+#define TCM_ORD_Delegate_ReadTable ((UINT32) 0x000080DB)
+#define TCM_ORD_Delegate_UpdateVerification ((UINT32) 0x000080D1)
+#define TCM_ORD_Delegate_VerifyDelegation ((UINT32) 0x000080D6)
+#define TCM_ORD_DirRead ((UINT32) 0x0000801A)
+#define TCM_ORD_DirWriteAuth ((UINT32) 0x00008019)
+#define TCM_ORD_DisableForceClear ((UINT32) 0x0000805E)
+#define TCM_ORD_DisableOwnerClear ((UINT32) 0x0000805C)
+#define TCM_ORD_DisablePubekRead ((UINT32) 0x0000807E)
+#define TCM_ORD_DSAP ((UINT32) 0x00008011)
+#define TCM_ORD_EstablishTransport ((UINT32) 0x000080E6)
+#define TCM_ORD_EvictKey ((UINT32) 0x00008022)
+#define TCM_ORD_ExecuteTransport ((UINT32) 0x000080E7)
+#define TCM_ORD_Extend ((UINT32) 0x00008014)
+#define TCM_ORD_FieldUpgrade ((UINT32) 0x000080AA)
+#define TCM_ORD_FlushSpecific ((UINT32) 0x000080BA)
+#define TCM_ORD_ForceClear ((UINT32) 0x0000805D)
+#define TCM_ORD_GetAuditDigest ((UINT32) 0x00008085)
+#define TCM_ORD_GetAuditDigestSigned ((UINT32) 0x00008086)
+#define TCM_ORD_GetAuditEvent ((UINT32) 0x00008082)
+#define TCM_ORD_GetAuditEventSigned ((UINT32) 0x00008083)
+#define TCM_ORD_GetCapability ((UINT32) 0x00008065)
+#define TCM_ORD_GetCapabilityOwner ((UINT32) 0x00008066)
+#define TCM_ORD_GetCapabilitySigned ((UINT32) 0x00008064)
+#define TCM_ORD_GetOrdinalAuditStatus ((UINT32) 0x0000808C)
+#define TCM_ORD_GetPubKey ((UINT32) 0x00008021)
+#define TCM_ORD_GetRandom ((UINT32) 0x00008046)
+#define TCM_ORD_GetTestResult ((UINT32) 0x00008054)
+#define TCM_ORD_GetTicks ((UINT32) 0x000080F1)
+#define TCM_ORD_IncrementCounter ((UINT32) 0x000080DD)
+#define TCM_ORD_Init ((UINT32) 0x00008097)
+#define TCM_ORD_KeyControlOwner ((UINT32) 0x00008023)
+#define TCM_ORD_KillMaintenanceFeature ((UINT32) 0x0000802E)
+#define TCM_ORD_LoadAuthContext ((UINT32) 0x000080B7)
+#define TCM_ORD_LoadContext ((UINT32) 0x000080B9)
+#define TCM_ORD_LoadKey ((UINT32) 0x00008020)
+#define TCM_ORD_LoadKey2 ((UINT32) 0x00008041)
+#define TCM_ORD_LoadKeyContext ((UINT32) 0x000080B5)
+#define TCM_ORD_LoadMaintenanceArchive ((UINT32) 0x0000802D)
+#define TCM_ORD_LoadManuMaintPub ((UINT32) 0x0000802F)
+#define TCM_ORD_MakeIdentity ((UINT32) 0x00008079)
+#define TCM_ORD_MigrateKey ((UINT32) 0x00008025)
+#define TCM_ORD_NV_DefineSpace ((UINT32) 0x000080CC)
+#define TCM_ORD_NV_ReadValue ((UINT32) 0x000080CF)
+#define TCM_ORD_NV_ReadValueAuth ((UINT32) 0x000080D0)
+#define TCM_ORD_NV_WriteValue ((UINT32) 0x000080CD)
+#define TCM_ORD_NV_WriteValueAuth ((UINT32) 0x000080CE)
+#define TCM_ORD_OIAP ((UINT32) 0x0000800A)
+#define TCM_ORD_OSAP ((UINT32) 0x0000800B)
+#define TCM_ORD_OwnerClear ((UINT32) 0x0000805B)
+#define TCM_ORD_OwnerReadInternalPub ((UINT32) 0x00008081)
+#define TCM_ORD_OwnerReadPubek ((UINT32) 0x0000807D)
+#define TCM_ORD_OwnerSetDisable ((UINT32) 0x0000806E)
+#define TCM_ORD_PCR_Reset ((UINT32) 0x000080C8)
+#define TCM_ORD_PcrRead ((UINT32) 0x00008015)
+#define TCM_ORD_PhysicalDisable ((UINT32) 0x00008070)
+#define TCM_ORD_PhysicalEnable ((UINT32) 0x0000806F)
+#define TCM_ORD_PhysicalSetDeactivated ((UINT32) 0x00008072)
+#define TCM_ORD_Quote ((UINT32) 0x00008016)
+#define TCM_ORD_Quote2 ((UINT32) 0x0000803E)
+#define TCM_ORD_ReadCounter ((UINT32) 0x000080DE)
+#define TCM_ORD_ReadManuMaintPub ((UINT32) 0x00008030)
+#define TCM_ORD_ReadPubek ((UINT32) 0x0000807C)
+#define TCM_ORD_ReleaseCounter ((UINT32) 0x000080DF)
+#define TCM_ORD_ReleaseCounterOwner ((UINT32) 0x000080E0)
+#define TCM_ORD_ReleaseTransportSigned ((UINT32) 0x000080E8)
+#define TCM_ORD_Reset ((UINT32) 0x0000805A)
+#define TCM_ORD_ResetLockValue ((UINT32) 0x00008040)
+#define TCM_ORD_RevokeTrust ((UINT32) 0x00008080)
+#define TCM_ORD_SaveAuthContext ((UINT32) 0x000080B6)
+#define TCM_ORD_SaveContext ((UINT32) 0x000080B8)
+#define TCM_ORD_SaveKeyContext ((UINT32) 0x000080B4)
+#define TCM_ORD_SaveState ((UINT32) 0x00008098)
+#define TCM_ORD_Seal ((UINT32) 0x00008017)
+#define TCM_ORD_Sealx ((UINT32) 0x0000803D)
+#define TCM_ORD_SelfTestFull ((UINT32) 0x00008050)
+#define TCM_ORD_SetCapability ((UINT32) 0x0000803F)
+#define TCM_ORD_SetOperatorAuth ((UINT32) 0x00008074)
+#define TCM_ORD_SetOrdinalAuditStatus ((UINT32) 0x0000808D)
+#define TCM_ORD_SetOwnerInstall ((UINT32) 0x00008071)
+#define TCM_ORD_SetOwnerPointer ((UINT32) 0x00008075)
+#define TCM_ORD_SetRedirection ((UINT32) 0x0000809A)
+#define TCM_ORD_SetTempDeactivated ((UINT32) 0x00008073)
+#define TCM_ORD_SHA1CompleteExtend ((UINT32) 0x000080ED)
+#define TCM_ORD_SHA1Start ((UINT32) 0x000080EA)
+#define TCM_ORD_SHA1Update ((UINT32) 0x000080EB)
+#define TCM_ORD_Sign ((UINT32) 0x0000803C)
+#define TCM_ORD_Startup ((UINT32) 0x00008099)
+#define TCM_ORD_StirRandom ((UINT32) 0x00008047)
+#define TCM_ORD_TakeOwnership ((UINT32) 0x0000800D)
+#define TCM_ORD_Terminate_Handle ((UINT32) 0x00008096)
+#define TCM_ORD_TickStampBlob ((UINT32) 0x000080F2)
+#define TCM_ORD_UnBind ((UINT32) 0x0000801E)
+#define TCM_ORD_Unseal ((UINT32) 0x00008018)
+#define TCM_TSC_ORD_PhysicalPresence ((UINT32) 0x4000800A)
+#define TCM_TSC_ORD_ResetEstablishmentBit ((UINT32) 0x4000800B)
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/TisLib/sha.h b/Core/EM/TCG2/TisLib/sha.h
new file mode 100644
index 0000000..218bc34
--- /dev/null
+++ b/Core/EM/TCG2/TisLib/sha.h
@@ -0,0 +1,122 @@
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ sha1.h
+
+ Abstract:
+
+ --*/
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/sha.h 1 4/21/14 2:14p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:14p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/sha.h $
+//
+// 1 4/21/14 2:14p Fredericko
+//
+// 1 10/08/13 11:58a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 10/03/13 12:35p Fredericko
+// Sha256 support policy update
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+// [Files] TisLib.cif
+// TisLib.mak
+// TcgTpm12.h
+// TpmLib.h
+// TcgCommon.h
+// ZTEICTcmOrdinals.h
+// TpmLib.c
+// TcgCommon.c
+// TisLib.sdl
+// sha1.h
+// INTTcgAcpi.h
+// TcgPc.h
+// TcmPc.h
+// TcgEfiTpm.h
+// TcgEFI12.h
+//
+// 8 3/29/11 12:24p Fredericko
+//
+// 7 3/28/11 12:14p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+// 6 5/19/10 5:09p Fredericko
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Sha1.h
+//
+// Description:
+// Header file for sha1.c
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+#ifndef _CAL_SHA1_H_
+#define _CAL_SHA1_H_
+
+#include "TcgTpm12.h"
+#include "token.h"
+
+
+typedef TPM_ALGORITHM_ID TCG_ALGORITHM_ID;
+#define TCG_ALG_SHA 0x00000004 // The SHA1 algorithm
+typedef unsigned long u32;
+
+struct SHA1Context {
+ u32 state[5];
+ u32 count[2];
+ unsigned char buffer[64];
+};
+
+typedef struct SHA1Context SHA1_CTX;
+
+
+
+void SHA1Init(struct SHA1Context *context);
+void SHA1Update(struct SHA1Context *context, const void *data, u32 len);
+void SHA1Final(unsigned char digest[20], struct SHA1Context *context);
+
+struct sha256_state {
+ UINT64 length;
+ UINT32 state[8], curlen;
+ UINT8 buf[64];
+};
+
+typedef struct sha256_state SHA2_CTX;
+
+void sha256_init(struct sha256_state *md);
+int sha256_process(struct sha256_state *md, const unsigned char *in, unsigned long inlen);
+int sha256_done(struct sha256_state *md, unsigned char *out);
+
+#endif // _CAL_SHA1_H_
diff --git a/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.c b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.c
new file mode 100644
index 0000000..d1e5c44
--- /dev/null
+++ b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.c
@@ -0,0 +1,125 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.c 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.c $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 6 4/01/11 9:32a Fredericko
+// Updated function Header
+//
+// 5 3/31/11 4:48p Fredericko
+// Changes for TCG_Legacy support
+//
+// 4 3/29/11 4:51p Fredericko
+// Moved TCM device ID and Vendor ID check to tokens.
+//
+// 3 3/29/11 12:52p Fredericko
+//
+// 2 3/29/11 12:07p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiTcmlib.c
+//
+// Description:
+// AmiTcmlibrary functions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include "AmiTcmlib.h"
+#include "token.h"
+
+
+TCM_ID_STRUC TCMSupportedArray[NUMBER_OF_SUPPORTED_TCM_DEVICES]={
+ {SUPPORTED_TCM_DEVICE_1_VID,SUPPORTED_TCM_DEVICE_1_DID}, //ZTEIC
+ {SUPPORTED_TCM_DEVICE_2_VID,SUPPORTED_TCM_DEVICE_2_DID} //ZTEIC2
+};
+
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: AutoSupportType
+//
+// Description: verifies support for a TCM module on a platform
+//
+// Input: NONE
+//
+// Output: BOOLEAN
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+extern
+BOOLEAN
+__stdcall AutoSupportType ()
+{
+#if TCG_LEGACY == 0
+ UINTN i=0;
+
+ for(i=0;i<(sizeof(TCMSupportedArray)/sizeof(TCM_ID_STRUC));i++){
+ if((TCMSupportedArray[i].VID == *(UINT16 *)(UINTN)(PORT_TPM_IOMEMBASE + 0xF00)) &&
+ (TCMSupportedArray[i].DID == *(UINT16 *)(UINTN)(PORT_TPM_IOMEMBASE + 0xF02))){
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.cif b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.cif
new file mode 100644
index 0000000..f6aeaef
--- /dev/null
+++ b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "AmiTcmlib"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\Tpm1_2_lib"
+ RefName = "AmiTcmlib"
+[files]
+"AmiTcmlib.sdl"
+"AmiTcmlib.mak"
+"AmiTcmlib.h"
+"AmiTcmlib.dxs"
+"AmiTcmlib.c"
+<endComponent>
diff --git a/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.dxs b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.dxs
new file mode 100644
index 0000000..01c3223
--- /dev/null
+++ b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.dxs
@@ -0,0 +1,68 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.dxs 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.dxs $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 3/29/11 12:51p Fredericko
+//
+// 2 3/29/11 12:07p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiTcmlib.dxs
+//
+// Description: AmiTcmlib Dependency file
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.h b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.h
new file mode 100644
index 0000000..570e69b
--- /dev/null
+++ b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.h
@@ -0,0 +1,74 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.h 1 4/21/14 2:15p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:15p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.h $
+//
+// 1 4/21/14 2:15p Fredericko
+//
+// 1 10/08/13 11:59a Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:50p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 3/29/11 12:51p Fredericko
+//
+// 2 3/29/11 12:06p Fredericko
+// [TAG] EIP 54642
+// [Category] Improvement
+// [Description] 1. Checkin Files related to TCG function override
+// 2. Include TCM and TPM auto detection
+// [Files] Affects all TCG files
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiTcmlib.h
+//
+// Description: Header file for AmiTcmlib.h
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+//Array of supported TCM devices
+#include <efi.h>
+
+typedef struct
+{ UINT16 VID;
+ UINT16 DID;
+} TCM_ID_STRUC;
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.mak b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.mak
new file mode 100644
index 0000000..3ef0ed3
--- /dev/null
+++ b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.mak
@@ -0,0 +1,91 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.mak 1 4/21/14 2:15p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:15p $
+#*************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Libraries/TisLib/AmiTcmlib/AmiTcmlib.mak $
+#
+# 1 4/21/14 2:15p Fredericko
+#
+# 1 10/08/13 11:59a Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 1 7/10/13 5:50p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+# 7 3/29/11 12:51p Fredericko
+#
+# 6 3/29/11 11:52a Fredericko
+# [TAG] EIP 54642
+# [Category] Improvement
+# [Description] 1. Checkin Files related to TCG function override
+# 2. Include TCM and TPM auto detection
+# [Files] Affects all TCG files
+#
+#
+#*************************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiTcmlib.mak
+#
+# Description: Make file for AmiTcmlib
+#
+#<AMI_FHDR_END>
+#************************************************************************
+all : $(BUILD_DIR)\AmiTcmlib.lib
+
+#---------------------------------------------------------------------------
+# $(BUILD_DIR)\AmiTcgLibDxe.lib
+#---------------------------------------------------------------------------
+$(BUILD_DIR)\AmiTcmlib.lib : $(BUILD_DIR)\AmiTcmlib.mak MakeAmiTcmlib
+
+$(BUILD_DIR)\AmiTcmlib.mak : $(AMI_TCM_LIB)\AmiTcmlib.cif $(AMI_TCM_LIB)\AmiTcmlib.mak $(BUILD_RULES)
+ $(CIF2MAK) $(AMI_TCM_LIB)\AmiTcmlib.cif $(CIF2MAK_DEFAULTS)
+
+MakeAmiTcmlib:
+!IF "$(PROCESSOR)"=="x64"
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiTcmlib.mak all\
+ TYPE=LIBRARY
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\AmiTcmlib.mak all\
+ TYPE=PEI_LIBRARY
+!ELSE
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiTcmlib.mak all\
+ TYPE=LIBRARY
+!ENDIF
+
+#---------------------------------------------------------------------------
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.sdl b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.sdl
new file mode 100644
index 0000000..83cf885
--- /dev/null
+++ b/Core/EM/TCG2/Tpm1_2_lib/AmiTcmlib.sdl
@@ -0,0 +1,71 @@
+TOKEN
+ Name = "AmiTcmLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TCG support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "TCG2Support" "=" "1"
+End
+
+
+PATH
+ Name = "AMI_TCM_LIB"
+End
+
+MODULE
+ Help = "Includes AmiTcmlib.mak to Project"
+ File = "AmiTcmlib.mak"
+End
+
+TOKEN
+ Name = "SUPPORTED_TCM_DEVICE_1_VID"
+ Value = "19F5h"
+ Help = "Vendor ID of the a supported TCM device"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "SUPPORTED_TCM_DEVICE_1_DID"
+ Value = "0001h"
+ Help = "Device ID of the a supported TCM device"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+
+
+TOKEN
+ Name = "SUPPORTED_TCM_DEVICE_2_VID"
+ Value = "1b4eh"
+ Help = "Vendor ID of the a supported TCM device"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "SUPPORTED_TCM_DEVICE_2_DID"
+ Value = "0001h"
+ Help = "Device ID of the a supported TCM device"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+
+TOKEN
+ Name = "NUMBER_OF_SUPPORTED_TCM_DEVICES"
+ Value = "0002h"
+ Help = "number of supported tcm devices. Increase this number with addition of new DID and vendor ID"
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.c b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.c
new file mode 100644
index 0000000..2203432
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.c
@@ -0,0 +1,132 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.c 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.c $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:06p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//**********************************************************************
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name: TpmClearOnRollback
+//
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include "TpmClearOnRollback.h"
+#include <Protocol/AmiPostMgr.h>
+#include <PPI/FwVersion.h>
+#include <Hob.h>
+#include <Token.h>
+#include <AmiHobs.h>
+
+VOID DrawMessageBox(
+ IN CHAR16 *Caption,
+ IN CHAR16 *Message
+);
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: RecoveryClearTpmBeforeFlash
+//
+// Description:
+// Process TPM clear on Rollback policy
+//
+// Input:
+// VOID
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID RecoveryClearTpmBeforeFlash (VOID){
+ UINT8 ClearResults;
+ AMI_POST_MANAGER_PROTOCOL *TpmClearAmiPostMgr = NULL;
+ FW_VERSION Fid;
+ EFI_EVENT MyEvent;
+ FW_VERSION RecoveryFid;
+ EFI_HOB_HANDOFF_INFO_TABLE *TpmpHit;
+ EFI_GUID myGuidHob = HOB_LIST_GUID;
+ EFI_GUID TpmRecoveryHobGuid = AMI_RECOVERY_IMAGE_HOB_GUID;
+ UINT32 ProjectVersion, NewProjectVersion;
+ EFI_GUID gAmiPostManagerProtocolGuid = \
+ AMI_POST_MANAGER_PROTOCOL_GUID;
+ EFI_STATUS Status;
+
+ TpmpHit = GetEfiConfigurationTable(pST, &myGuidHob);
+ if(TpmpHit != NULL && !EFI_ERROR(FindNextHobByGuid(&TpmRecoveryHobGuid, &TpmpHit))) {
+
+ TpmGetFidFromBuffer(&RecoveryFid, (VOID *)(UINTN)((RECOVERY_IMAGE_HOB*)TpmpHit)->Address);
+ }
+
+ TpmRecoveryGetFidFromFv(&Fid);
+
+ ProjectVersion = Fid.ProjectMajorVersion[0] + Fid.ProjectMajorVersion[1] + Fid.ProjectMajorVersion[2];
+ ProjectVersion <<= 16;
+ ProjectVersion += Fid.ProjectMinorVersion[0] + Fid.ProjectMinorVersion[1] + Fid.ProjectMinorVersion[2];
+
+ NewProjectVersion = RecoveryFid.ProjectMajorVersion[0] + RecoveryFid.ProjectMajorVersion[1] + RecoveryFid.ProjectMajorVersion[2];
+ NewProjectVersion <<= 16;
+ NewProjectVersion += RecoveryFid.ProjectMinorVersion[0] + RecoveryFid.ProjectMinorVersion[1] + RecoveryFid.ProjectMinorVersion[2];
+
+ if(NewProjectVersion < ProjectVersion){
+ ClearResults = ClearTpmBeforeFlash();
+ if(ClearResults == TPM_CLEAR_RESET_REQUIRED)
+ {
+ Status = pBS->LocateProtocol(&gAmiPostManagerProtocolGuid, NULL, &TpmClearAmiPostMgr);
+ if(EFI_ERROR(Status))return;
+
+ if(TpmClearAmiPostMgr != NULL) {
+ Status = TpmClearAmiPostMgr->DisplayInfoBox(L"TPM CLEAR",\
+ L"Caution: A Reset is required to Clear the TPM for Flash Update. Enable Recovery after reset",20, &MyEvent);
+
+ FixedDelay(1000000); //10seconds delay
+ }
+
+ pRS->ResetSystem( EfiResetCold, 0, 0, NULL );
+ }
+ }
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.cif b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.cif
new file mode 100644
index 0000000..62c2814
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "TpmClearOnRollback"
+ category = ModulePart
+ LocalRoot = "Core\EM\TCG2\TpmClearOnRollback\"
+ RefName = "TpmClearOnRollback"
+[files]
+"TpmClearOnRollback.c"
+"TpmClearOnRollback.h"
+"TpmClearOnRollback.sdl"
+"TpmClearOnRollback.mak"
+"TpmClearOnRollback.dxs"
+"TpmClearOnRollbackSmiFlash.c"
+"TpmClearOnRollbackWrapperLib.c"
+"TpmClearOnRollbackWrapperLib.h"
+[parts]
+"AmiTpmClearOnRollbackProtocol"
+<endComponent>
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.dxs b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.dxs
new file mode 100644
index 0000000..c5f6e32
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.dxs
@@ -0,0 +1,75 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.dxs 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.dxs $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:06p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+// 3 7/25/11 3:21a Fredericko
+// [TAG] EIP65177
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] TCG Ppi Sec ver 1.2 update
+//
+// 2 5/20/10 8:54a Fredericko
+//
+// Included File Header
+// Included File Revision History
+// EIP 37653
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TCGSmm.dxs
+//
+// Description:
+// Dependency for TcgSmm
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+#include <Protocol\SmmBase2.h>
+
+DEPENDENCY_START
+ EFI_SMM_BASE2_PROTOCOL_GUID
+DEPENDENCY_END
+//*************************************************************************
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.h b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.h
new file mode 100644
index 0000000..23be079
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.h
@@ -0,0 +1,69 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.h 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.h $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:06p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name:
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _TPM_CLEAR_ON_ROLLBACK_H
+#define _TPM_CLEAR_ON_ROLLBACK_H
+
+#include <AmiDxeLib.h>
+#include <Protocol\TcgService.h>
+#include <TCGMisc.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\AmiTpmClearOnRollbackProtocol.h>
+#include "TpmClearOnRollbackWrapperLib.h"
+
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.mak b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.mak
new file mode 100644
index 0000000..f0423be
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.mak
@@ -0,0 +1,107 @@
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.mak 1 4/21/14 2:18p Fredericko $
+#
+# $Revision: 1 $
+#
+# $Date: 4/21/14 2:18p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollback.mak $
+#
+# 1 4/21/14 2:18p Fredericko
+#
+# 1 10/08/13 12:06p Fredericko
+# Initial Check-In for Tpm-Next module
+#
+# 2 10/03/13 2:48p Fredericko
+#
+# 1 7/10/13 5:57p Fredericko
+# [TAG] EIP120969
+# [Category] New Feature
+# [Description] TCG (TPM20)
+#
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name:
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : BuildTpmClearOnRollbackWrapperLib TPMCLEARONROLLBACK
+
+TPMCLEARONROLLBACK : $(BUILD_DIR)\TpmClearOnRollback.mak TpmClearRollBackSmmBin
+
+BuildTpmClearOnRollbackWrapperLib: $(BUILD_DIR)\TpmClearOnRollback.mak TpmClearOnRollbackWrapperLibBin
+$(TpmClearOnRollbackWrapperLib): BuildTpmClearOnRollbackWrapperLib
+
+$(BUILD_DIR)\TpmClearOnRollback.mak : $(TPMCLEARONROLLBACK_DIR)\$(@B).cif $(TPMCLEARONROLLBACK_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TPMCLEARONROLLBACK_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TCGCLEAR_CFLAGS=$(CFLAGS) \
+ /I$(TCG_DIR)\
+ /I$(TCG_DIR)\Common\
+ /I$(PROJECT_DIR)\Include\Protocol\
+ /I$(TCG_DIR)\Protocol
+
+
+TPM_CLEAR_ON_ROLLBACK_WRAPPEER_OBJS = \
+$(BUILD_DIR)\$(TPMCLEARONROLLBACK_DIR)\TpmClearOnRollbackWrapperLib.obj
+
+TpmClearOnRollbackWrapperLibBin: $(tcgLibLite)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TpmClearOnRollback.mak all\
+ "CFLAGS=$(TCGCLEAR_CFLAGS)" \
+ "OBJECTS=$(TPM_CLEAR_ON_ROLLBACK_WRAPPEER_OBJS)"\
+ TYPE=LIBRARY \
+ LIBRARY_NAME=$(TpmClearOnRollbackWrapperLib)
+
+TCGCLEAR_OBJECTS = \
+$(BUILD_DIR)\$(TPMCLEARONROLLBACK_DIR)\TpmClearOnRollbackSmiFlash.obj
+
+ReFlashBin: $(BUILD_DIR)\$(TCG)\TpmClearOnRollback.obj $(TpmClearOnRollbackWrapperLib)
+
+$(BUILD_DIR)\$(TCG)\TpmClearOnRollback.obj : $(TPMCLEARONROLLBACK_DIR)\TpmClearOnRollback.obj
+ $(CC) $(TCGCLEAR_CFLAGS) /Fo$(BUILD_DIR)\$(TCG)\TpmClearOnRollback.obj $(TPMCLEARONROLLBACK_DIR)\TpmClearOnRollback.c
+
+TpmClearRollBackSmmBin : $(TpmClearOnRollbackWrapperLib) $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\TpmClearOnRollback.mak all \
+ GUID=FD2CB3F1-9520-4c24-BCB3-2C73F0C2B7EC \
+ "CFLAGS=$(TCGCLEAR_CFLAGS)" \
+ ENTRY_POINT=TpmClearRollBackSmmInit \
+ TYPE=BS_DRIVER \
+ "OBJECTS=$(TCGCLEAR_OBJECTS)"\
+ DEPEX1=$(TPMCLEARONROLLBACK_DIR)\TpmClearOnRollback.DXS \
+ COMPRESS=1 \
+
+#*************************************************************************
+#*************************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#*************************************************************************
+#*************************************************************************
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.sdl b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.sdl
new file mode 100644
index 0000000..b616dae
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollback.sdl
@@ -0,0 +1,41 @@
+TOKEN
+ Name = "TPMCLEARONROLLBACK_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TcgPlatformSetupPolicy support in Project"
+ TokenType = Boolean
+ TargetH = Yes
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Token = "TPM12Enabled" "!=" "0"
+End
+
+
+PATH
+ Name = "TPMCLEARONROLLBACK_DIR"
+End
+
+MODULE
+ Help = "Includes AmtPlatformPolicy.mak to Project"
+ File = "TpmClearOnRollback.mak"
+End
+
+TOKEN
+ Name = "TpmClearOnRollbackWrapperLib"
+ Value = "$(BUILD_DIR)\TpmClearOnRollbackWrapperLib.lib"
+ TokenType = Expression
+ TargetMAK = Yes
+End
+
+
+ELINK
+ Name = "RecoveryClearTpmBeforeFlash,"
+ Parent = "OemBeforeFlashUpdateList"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\TpmClearOnRollback.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackSmiFlash.c b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackSmiFlash.c
new file mode 100644
index 0000000..720940b
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackSmiFlash.c
@@ -0,0 +1,160 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackSmiFlash.c 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackSmiFlash.c $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:06p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//**********************************************************************
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name:
+//
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include "TpmClearOnRollback.h"
+#include <Protocol/AmiPostMgr.h>
+
+CLEAR_TPM_ROLLBACK_PROTOCOL *PrivateProtocol;
+EFI_SMM_SYSTEM_TABLE2 *mSmst;
+static FW_VERSION Fid;
+
+
+UINT8 SmiFlashClearTpmBeforeFlash (){
+ return(ClearTpmBeforeFlash());
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InstallTpmClearProtocolInSmm
+//
+// Description: InstallTcgSmmFlash Protocol
+//
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS InstallTpmClearProtocolInSmm(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ EFI_SMM_BASE2_PROTOCOL *SmmBase;
+ EFI_HANDLE Handle=NULL;
+ EFI_STATUS Status;
+ EFI_GUID TpmRollbackSmmGuid = \
+ AMI_TPM_ROLLBACK_SMM_PROTOCOL_GUID;
+
+ Status = pBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, &SmmBase);
+ if((EFI_ERROR(Status)) || (SmmBase == NULL)){
+ return Status;
+ }
+
+ Status = SmmBase->GetSmstLocation(SmmBase, &mSmst);
+ if(EFI_ERROR(Status)){
+ return Status;
+ }
+
+ Status = mSmst->SmmAllocatePool (
+ EfiRuntimeServicesData,
+ sizeof (CLEAR_TPM_ON_ROLLBACK),
+ &PrivateProtocol
+ );
+
+ if((EFI_ERROR(Status)) || (PrivateProtocol == NULL)){
+ return Status;
+ }
+
+ TpmRecoveryGetFidFromFv(&Fid);
+
+ PrivateProtocol->ClearTpmOnRollBack = (VOID *)&SmiFlashClearTpmBeforeFlash;
+
+ Status = mSmst->SmmInstallProtocolInterface( &Handle, \
+ &TpmRollbackSmmGuid, \
+ EFI_NATIVE_INTERFACE, \
+ PrivateProtocol );
+
+ return Status;
+}
+
+
+
+//****************************************************** ****************
+//<AMI_PHDR_START>
+//
+// Procedure: TpmClearRollBackSmmInit
+//
+// Description: Entry point for subcomponent
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS TpmClearRollBackSmmInit(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable )
+{
+ InitAmiLib( ImageHandle, SystemTable );
+
+ return InitSmmHandler( ImageHandle, SystemTable, InstallTpmClearProtocolInSmm, NULL );
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c
new file mode 100644
index 0000000..dd71a11
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c
@@ -0,0 +1,584 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c 2 4/21/14 3:17p Fredericko $
+//
+// $Revision: 2 $
+//
+// $Date: 4/21/14 3:17p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.c $
+//
+// 2 4/21/14 3:17p Fredericko
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:06p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//**********************************************************************
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+// Name:
+//
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#include "TpmClearOnRollback.h"
+#include "TpmClearOnRollbackWrapperLib.h"
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TpmRecoveryGetFidFromFv
+//
+// Description:
+// Finds FID information in the Flash
+//
+// Input:
+//
+//
+// Output:
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TpmRecoveryGetFidFromFv(
+ OUT VOID *Fid
+)
+{
+ static EFI_GUID FidFileName = FID_FFS_FILE_NAME_GUID;
+ EFI_STATUS Status;
+ EFI_HANDLE *FvHandle;
+ UINTN FvCount;
+ UINTN i;
+ UINTN BufferSize;
+ VOID *Buffer;
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &FvCount, &FvHandle);
+ if (EFI_ERROR(Status))
+ return Status;
+
+ for(i = 0; i < FvCount; i++)
+ {
+ EFI_FIRMWARE_VOLUME_PROTOCOL *Fv;
+ UINT32 AuthStatus;
+ Status = pBS->HandleProtocol(FvHandle[i], &gEfiFirmwareVolume2ProtocolGuid, &Fv);
+ if (EFI_ERROR(Status))
+ continue;
+ Buffer = 0;
+ BufferSize = 0;
+ Status = Fv->ReadSection(Fv, &FidFileName, EFI_SECTION_FREEFORM_SUBTYPE_GUID, 0, &Buffer, &BufferSize, &AuthStatus);
+ TRACE((-1, "extracted section with guid %g\n", (EFI_GUID *)Buffer));
+ if (!EFI_ERROR(Status)) {
+ (UINT8 *)Buffer += sizeof(EFI_GUID);
+ MemCpy(Fid, Buffer, sizeof(FW_VERSION));
+ (UINT8 *)Buffer -= sizeof(EFI_GUID);
+ pBS->FreePool(Buffer);
+ return EFI_SUCCESS;
+ }
+ }
+ pBS->FreePool(FvHandle);
+ return EFI_NOT_FOUND;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: TpmGetFidFromBuffer
+//
+// Description:
+// Finds FID information in provided buffer
+//
+// Input:
+//
+//
+// Output:
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS TpmGetFidFromBuffer(
+ OUT VOID *Fid,
+ IN VOID *Buffer
+)
+{
+ static EFI_GUID FidSectionGuid = FID_FFS_FILE_SECTION_GUID;
+ UINT32 Signature;
+ UINT32 *SearchPointer;
+
+ SearchPointer = (UINT32 *)((UINT8 *)Buffer - sizeof(EFI_GUID) + FLASH_SIZE);
+ Signature = FidSectionGuid.Data1;
+
+ do {
+ if(*SearchPointer == Signature) {
+ if(!guidcmp(&FidSectionGuid, (EFI_GUID *)SearchPointer)) {
+ (UINT8 *)SearchPointer += sizeof(EFI_GUID);
+ MemCpy(Fid, SearchPointer, sizeof(FW_VERSION));
+ return EFI_SUCCESS;
+ }
+ }
+ } while(SearchPointer-- >= (UINT32 *)Buffer);
+
+ return EFI_NOT_FOUND;
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SendTpmCommandRecovery
+//
+// Description:
+// Generic send TPM Transaction
+//
+// Input:
+//
+//
+// Output:
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SendTpmCommandRecovery(UINT8 *Cmd, UINTN CmdSize,
+ UINT8 *RetBuff, UINTN RetBuffSize)
+{
+ EFI_STATUS Status;
+ TPM_TRANSMIT_BUFFER InBuffer[1], OutBuffer[1];
+
+ InBuffer[0].Buffer = Cmd;
+ InBuffer[0].Size = CmdSize;
+ OutBuffer[0].Buffer = RetBuff;
+ OutBuffer[0].Size = RetBuffSize;
+
+ Status = TpmLibPassThrough(((TPM_1_2_REGISTERS_PTR)(UINTN)TPM_BASE_ADDRESS),
+ sizeof (InBuffer)/sizeof (*InBuffer),
+ InBuffer,
+ sizeof (OutBuffer) / sizeof (*OutBuffer),
+ OutBuffer);
+
+ return Status;
+
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RecoverySetPhysicalPresence
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS RecoverySetPhysicalPresence()
+{
+ EFI_STATUS Status;
+ PHYSICAL_PRESENCE_CMD PpCmd;
+ TPM_1_2_RET_HEADER retHeader;
+
+
+ PpCmd.Hdr.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ PpCmd.Hdr.ParamSize = TPM_H2NL( sizeof (PHYSICAL_PRESENCE_CMD));
+ PpCmd.Hdr.Ordinal = TPM_H2NL( TSC_ORD_PhysicalPresence );
+ PpCmd.Data = TPM_H2NS(TPM_PHYSICAL_PRESENCE_CMD_ENABLE );
+
+ MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0);
+
+ Status = SendTpmCommandRecovery((UINT8 *)&PpCmd, sizeof(PHYSICAL_PRESENCE_CMD),
+ (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER));
+
+ //don't care about error case on setting physical presence CMD type
+ //care about actual physical presence failure
+ MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0);
+
+ PpCmd.Data = TPM_H2NS(TPM_PHYSICAL_PRESENCE_PRESENT);
+
+ Status = SendTpmCommandRecovery((UINT8 *)&PpCmd, sizeof(PHYSICAL_PRESENCE_CMD),
+ (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER));
+
+ if(retHeader.RetCode == 0)
+ {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_SECURITY_VIOLATION;
+
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RecoveryEnableActivate
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS RecoveryEnableActivate()
+{
+ EFI_STATUS Status;
+ DATA_CMD Command;
+ TPM_1_2_CMD_HEADER cmdEnable;
+ TPM_1_2_RET_HEADER retHeader;
+
+ cmdEnable.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdEnable.ParamSize = TPM_H2NL( sizeof (TPM_1_2_CMD_HEADER));
+ cmdEnable.Ordinal = TPM_H2NL( TPM_ORD_PhysicalEnable );
+
+ MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0);
+
+ Status = SendTpmCommandRecovery((UINT8 *)&cmdEnable, sizeof(TPM_1_2_CMD_HEADER),
+ (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER));
+
+ if(!EFI_ERROR(Status) && retHeader.RetCode == 0){
+ Command.Hdr.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ Command.Hdr.ParamSize = TPM_H2NL( sizeof (DATA_CMD));
+ Command.Hdr.Ordinal = TPM_H2NL( TPM_ORD_PhysicalSetDeactivated );
+ Command.Data = 0x0;
+
+ MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0);
+
+ Status = SendTpmCommandRecovery((UINT8 *)&Command, sizeof(DATA_CMD),
+ (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER));
+
+ if(retHeader.RetCode == 0)
+ {
+ return EFI_SUCCESS;
+ }
+ }
+
+ return EFI_SECURITY_VIOLATION;
+
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RecoverySendClearCmd
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+UINT8 RecoverySendClearCmd()
+{
+ EFI_STATUS Status;
+ TPM_1_2_CMD_HEADER cmdClear;
+ TPM_1_2_RET_HEADER retHeader;
+
+ cmdClear.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdClear.ParamSize = TPM_H2NL( sizeof (TPM_1_2_CMD_HEADER));
+ cmdClear.Ordinal = TPM_H2NL( TPM_ORD_ForceClear );
+
+ MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0);
+
+ Status = SendTpmCommandRecovery((UINT8 *)&cmdClear, sizeof(TPM_1_2_CMD_HEADER),
+ (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER));
+
+ if(retHeader.RetCode == 0)
+ {
+ return TPM_CLEAR_SUCCESSFUL;
+ }else if((retHeader.RetCode == TPM_H2NL(DISABLED))||
+ (retHeader.RetCode == TPM_H2NL(DEACTIVATED))){
+ //we need to send enable and activate command
+ //reset and then clear.
+ Status = RecoveryEnableActivate();
+
+ if(!EFI_ERROR(Status)){
+ return TPM_CLEAR_RESET_REQUIRED;
+ }
+ }
+
+ return TPM_FATAL_CONTINUE_FLASH;
+
+}
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: RecoverySendStartUpCmd
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS RecoverySendStartUpCmd()
+{
+ EFI_STATUS Status;
+ TPM_1_2_CMD_STARTUP cmdStartup;
+ TPM_1_2_RET_HEADER retHeader;
+ TPM_STARTUP_TYPE TpmSt = TPM_ST_CLEAR;
+
+ cmdStartup.Header.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdStartup.Header.ParamSize = TPM_H2NL( sizeof (cmdStartup));
+ cmdStartup.Header.Ordinal = TPM_H2NL( TPM_ORD_Startup );
+ cmdStartup.StartupType = TPM_H2NS( TpmSt );
+
+ MemSet(&retHeader, sizeof(TPM_1_2_RET_HEADER), 0);
+
+ Status = SendTpmCommandRecovery((UINT8 *)&cmdStartup, sizeof(TPM_1_2_CMD_STARTUP),
+ (UINT8 *)&retHeader, sizeof(TPM_1_2_RET_HEADER));
+
+ if(retHeader.RetCode == 0)
+ {
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetCapabilityCmd
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS GetCapabilityCmd(TPM_Capabilities_PermanentFlag *PermFlags)
+{
+ EFI_STATUS Status = EFI_ABORTED;
+ BOOLEAN Support = FALSE;
+ TPM_GetCapabilities_Input cmdGetCap;
+
+ cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap));
+
+ if(AutoSupportType()){
+ //not supported
+ return EFI_SUCCESS;
+ }else{
+ cmdGetCap.CommandCode = TPM_H2NL( TPM_ORD_GetCapability );
+ cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG );
+ }
+
+ cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long
+ cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_PERMANENT );
+
+ Status = SendTpmCommandRecovery((UINT8 *)&cmdGetCap, sizeof(TPM_GetCapabilities_Input),
+ (UINT8 *)PermFlags, sizeof(TPM_Capabilities_PermanentFlag));
+
+ if(PermFlags->RetCode == TPM_H2NL(INVALID_POSTINIT))
+ {
+ return EFI_NOT_READY;
+ }
+
+ if(PermFlags->RetCode == 0){
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetVolatileFlags
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS GetVolatileFlags(TPM_VOLATILE_FLAGS *VolatileFlags)
+{
+ EFI_STATUS Status = EFI_ABORTED;
+ BOOLEAN Support = FALSE;
+ TPM_GetCapabilities_Input cmdGetCap;
+
+ cmdGetCap.Tag = TPM_H2NS( TPM_TAG_RQU_COMMAND );
+ cmdGetCap.ParamSize = TPM_H2NL( sizeof (cmdGetCap));
+
+ if(AutoSupportType()){
+ return EFI_SUCCESS;
+ }else{
+ cmdGetCap.CommandCode = TPM_H2NL( TPM_ORD_GetCapability );
+ cmdGetCap.caparea = TPM_H2NL( TPM_CAP_FLAG );
+ }
+
+ cmdGetCap.subCapSize = TPM_H2NL( 4 ); // subCap is always 32bit long
+ cmdGetCap.subCap = TPM_H2NL( TPM_CAP_FLAG_VOLATILE );
+
+ Status = SendTpmCommandRecovery((UINT8 *)&cmdGetCap, sizeof(TPM_GetCapabilities_Input),
+ (UINT8 *)VolatileFlags, sizeof(TPM_VOLATILE_FLAGS));
+
+ if(VolatileFlags->RetCode == TPM_H2NL(INVALID_POSTINIT))
+ {
+ return EFI_NOT_READY;
+ }
+
+ if(VolatileFlags->RetCode == 0){
+ return EFI_SUCCESS;
+ }
+
+ return EFI_DEVICE_ERROR;
+}
+
+
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ClearTpmBeforeFlash
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//<AMI_PHDR_END>
+//**********************************************************************
+UINT8 ClearTpmBeforeFlash()
+{
+ TPM_Capabilities_PermanentFlag PermFlags;
+ UINT8 Result=0;
+ EFI_STATUS Status;
+ TPM_VOLATILE_FLAGS TpmVolatileFlags;
+
+ if(AutoSupportType())return TPM_CLEAR_SUCCESSFUL;
+
+ Status = IsTpmPresent((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_BASE_ADDRESS);
+ if(EFI_ERROR(Status)){
+ return TPM_CLEAR_SUCCESSFUL;
+ }
+
+ //else we have a TPM need to process to clear
+ TisRequestLocality((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_BASE_ADDRESS);
+
+ Status = GetCapabilityCmd(&PermFlags);
+ if(Status == EFI_NOT_READY)
+ {
+ Status = RecoverySendStartUpCmd();
+ if(EFI_ERROR(Status))
+ {
+ return TPM_FATAL_CONTINUE_FLASH;
+ }
+ }
+
+ if(EFI_ERROR(Status))return TPM_FATAL_CONTINUE_FLASH;
+
+ Status = RecoverySetPhysicalPresence();
+ if(!EFI_ERROR(Status))
+ {
+ Status = GetVolatileFlags(&TpmVolatileFlags);
+ if(!EFI_ERROR(Status)){
+ if(TpmVolatileFlags.physicalPresenceLock){
+ //we need to go into manufacturing mode\special mode
+ //to skip physical presence lock; Return we failed
+ //to clear TPM and flashing should be discontinued.
+ return TPM_FATAL_DISCONTINUE_FLASH;
+ }
+ }
+ Result = RecoverySendClearCmd();
+ }else{
+ if(EFI_ERROR(Status))return TPM_FATAL_CONTINUE_FLASH;
+ }
+
+ TisReleaseLocality((TPM_1_2_REGISTERS_PTR)( UINTN ) TPM_BASE_ADDRESS);
+
+ return Result;
+}
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
diff --git a/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.h b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.h
new file mode 100644
index 0000000..5c32d15
--- /dev/null
+++ b/Core/EM/TCG2/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.h
@@ -0,0 +1,198 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.h 1 4/21/14 2:18p Fredericko $
+//
+// $Revision: 1 $
+//
+// $Date: 4/21/14 2:18p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/TCG2/Common/TpmClearOnRollback/TpmClearOnRollbackWrapperLib.h $
+//
+// 1 4/21/14 2:18p Fredericko
+//
+// 1 10/08/13 12:06p Fredericko
+// Initial Check-In for Tpm-Next module
+//
+// 1 7/10/13 5:57p Fredericko
+// [TAG] EIP120969
+// [Category] New Feature
+// [Description] TCG (TPM20)
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name:
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#ifndef _TPM_CLEAR_ON_ROLLBACK_WRAPPER_H
+#define _TPM_CLEAR_ON_ROLLBACK_WRAPPER_H
+
+#include <AmiDxeLib.h>
+#include <Protocol\TcgService.h>
+#include <TCGMisc.h>
+#include <Protocol\SmmBase2.h>
+#include <Protocol\AmiTpmClearOnRollbackProtocol.h>
+#include <PPI/FwVersion.h>
+#include <Hob.h>
+#include <Token.h>
+#include <AmiHobs.h>
+
+#define FID_FFS_FILE_NAME_GUID \
+ { 0x3fd1d3a2, 0x99f7, 0x420b, 0xbc, 0x69, 0x8b, 0xb1, 0xd4, 0x92, 0xa3, 0x32 }
+
+#define FID_FFS_FILE_SECTION_GUID \
+ { 0x2EBE0275, 0x6458, 0x4AF9, 0x91, 0xED, 0xD3, 0xF4, 0xED, 0xB1, 0x00, 0xAA }
+
+#define TPM_BASE_ADDRESS 0xfed40000
+#define BASE 0x0
+#define INVALID_POSTINIT ((TPM_RESULT) (BASE + 38))
+#define DISABLED ((TPM_RESULT) (BASE + 7))
+#define DEACTIVATED ((TPM_RESULT) (BASE + 6))
+
+#define TPM_H2NS( x ) \
+ (((UINT16)(x) << 8) | ((UINT16)(x) >> 8))
+#define TPM_H2NL( x ) \
+ (UINT32)((((UINT32)(x)) >> 24) \
+ | (((x) >> 8) & 0xff00) \
+ | ((x) << 24) \
+ | (((x) & 0xff00) << 8))
+
+#define TPM_N2HS( x ) TPM_H2NS( x )
+#define TPM_N2HL( x ) TPM_H2NL( x )
+
+#pragma pack(1)
+
+typedef struct _TPM_1_2_REGISTERS {
+ UINT8 Access; // 0
+ UINT8 Reserved1[7]; // 1
+ UINT32 IntEnable; // 8
+ UINT8 IntVector; // 0ch
+ UINT8 Reserved2[3]; // 0dh
+ UINT32 IntSts; // 10h
+ UINT32 IntfCapability; // 14h
+ UINT8 Sts; // 18h
+ UINT16 BurstCount; // 19h
+ UINT8 Reserved3[9];
+ UINT32 DataFifo; // 24h
+ UINT8 Reserved4[0xed8]; // 28h
+ UINT16 Vid; // 0f00h
+ UINT16 Did; // 0f02h
+ UINT8 Rid; // 0f04h
+ UINT8 TcgDefined[0x7b]; // 0f05h
+ UINT32 LegacyAddress1; // 0f80h
+ UINT32 LegacyAddress1Ex; // 0f84h
+ UINT32 LegacyAddress2; // 0f88h
+ UINT32 LegacyAddress2Ex; // 0f8ch
+ UINT8 VendorDefined[0x70];// 0f90h
+} TPM_1_2_REGISTERS;
+
+typedef volatile TPM_1_2_REGISTERS *TPM_1_2_REGISTERS_PTR;
+
+typedef struct _TPM_TRANSMIT_BUFFER {
+ VOID *Buffer;
+ UINTN Size;
+} TPM_TRANSMIT_BUFFER;
+
+typedef struct _TPM_1_2_CMD_HEADER
+{
+ TPM_TAG Tag;
+ UINT32 ParamSize;
+ TPM_COMMAND_CODE Ordinal;
+} TPM_1_2_CMD_HEADER;
+
+typedef struct _TPM_1_2_RET_HEADER
+{
+ TPM_TAG Tag;
+ UINT32 ParamSize;
+ TPM_RESULT RetCode;
+} TPM_1_2_RET_HEADER;
+
+typedef struct _TPM_1_2_CMD_STARTUP
+{
+ TPM_1_2_CMD_HEADER Header;
+ TPM_STARTUP_TYPE StartupType;
+} TPM_1_2_CMD_STARTUP;
+
+typedef struct _PHYSICAL_PRESENCE_CMD{
+ TPM_1_2_CMD_HEADER Hdr;
+ UINT16 Data;
+} PHYSICAL_PRESENCE_CMD;
+
+typedef struct _DATA_CMD{
+ TPM_1_2_CMD_HEADER Hdr;
+ UINT8 Data;
+} DATA_CMD;
+
+#pragma pack()
+
+EFI_STATUS
+__stdcall IsTpmPresent (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+EFI_STATUS
+__stdcall TisReleaseLocality (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+EFI_STATUS
+__stdcall TisRequestLocality (
+ IN TPM_1_2_REGISTERS_PTR TpmReg );
+
+EFI_STATUS
+__stdcall TpmLibPassThrough (
+ IN TPM_1_2_REGISTERS_PTR TpmReg,
+ IN UINTN NoInputBuffers,
+ IN TPM_TRANSMIT_BUFFER *InputBuffers,
+ IN UINTN NoOutputBuffers,
+ IN OUT TPM_TRANSMIT_BUFFER *OutputBuffers );
+
+BOOLEAN
+__stdcall AutoSupportType ();
+
+EFI_STATUS TpmRecoveryGetFidFromFv(
+ OUT VOID *Fid
+);
+
+EFI_STATUS TpmGetFidFromBuffer(
+ OUT VOID *Fid,
+ IN VOID *Buffer
+);
+
+UINT8 ClearTpmBeforeFlash();
+
+void
+__stdcall
+FixedDelay(UINT32 dCount);
+
+#endif
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/Terminal/InitTerminalStrings.c b/Core/EM/Terminal/InitTerminalStrings.c
new file mode 100644
index 0000000..b7512e8
--- /dev/null
+++ b/Core/EM/Terminal/InitTerminalStrings.c
@@ -0,0 +1,349 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+// $Header: /Alaska/BIN/Modules/Terminal/InitTerminalStrings.c 22 12/12/11 6:51a Rajeshms $
+//
+// $Revision: 22 $
+//
+// $Date: 12/12/11 6:51a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Terminal/InitTerminalStrings.c $
+//
+// 22 12/12/11 6:51a Rajeshms
+// [TAG] EIP71636
+// [Category] New Feature
+// [Description] Implement the AMI_SERIAL_PROTOCOL for non-generic PCI
+// Serial Device.
+// [Files] AmiSerial.c, AmiSerial.sdl, AmiSerial.mak, AmiSerial.chm,
+// AmiSerial.dxs, AmiSerial.cif, Terminal.c, SerialIo.c, TerminalSetup.c,
+// InitTerminalStrings.c, TerminalSetupVar.h, Terminal.cif,
+// TerminalAmiSerial.h, LegacySredir_Setup.c
+//
+// 21 3/02/11 3:15a Rameshr
+// [TAG]- EIP 54313
+// [Category]-IMPROVEMENT
+// [Description]- Terminal driver Getvariable calls assumed to have valid
+// values. Added code to return the error code when there is an failure in
+// the getvariable call.
+// [Files]- TerminalSetup.c, InitTerminalString.c
+//
+// 20 11/02/10 4:17a Lavanyap
+// [TAG] - EIP42299
+// [Category] - IMPROVEMENT
+// [Description] - Console Redirection can support 10 COM Ports.
+// [Files] - InitTerminalStrings.c, SerialIo.c, Terminal.sd,
+// Terminal.sdl, Terminal.uni, TerminalSetup.c
+//
+// 19 10/19/10 8:35a Rajeshms
+// [TAG]- EIP 39562
+// [Category]-IMPROVEMENT
+// [Description]- Show entire PCI address of redirection device in Setup
+// [Files]- Terminal.c, TerminalSetup.c, InitTerminalStrings.c
+//
+// 18 1/20/10 4:47p Artems
+// EIP 34000 - made UEFI 2.1 changes backward compatible
+//
+// 17 12/16/09 4:33p Artems
+// EIP 31619 added UEFI 2.1 support
+//
+// 16 11/18/09 10:28a Fasihm
+// EIP#30023 - Fix added to resolve the NVRAM Corruption issue in the
+// projects.
+//
+// 15 7/02/09 5:01p Rameshr
+// Coding Standard and File header updated.
+//
+// 14 4/14/08 4:55p Ambikas
+//
+// 13 4/14/08 2:33p Ambikas
+//
+// 12 6/18/07 6:38p Ambikas
+//
+// 11 6/12/07 3:53p Ambikas
+//
+// 10 6/11/07 11:35a Ambikas
+//
+// 9 6/10/07 6:02p Ambikas
+//
+// 8 6/06/07 7:55p Ambikas
+// We no longer print segment and bus numbers of pci serial device, just
+// device and function numbers.
+//
+// 7 6/05/07 6:26p Ambikas
+//
+// 6 6/05/07 6:16p Ambikas
+//
+// 5 6/05/07 11:44a Ambikas
+//
+// 4 6/05/07 11:43a Ambikas
+//
+// 3 6/05/07 11:40a Ambikas
+//
+// 2 6/04/07 7:32p Ambikas
+// -Increased the max number of pci serial ports to 4. Added extra strings
+// for the additional ports.
+// -If TOTAL_SERIAL_PORTS is 0, then the setup data structures for the
+// serial ports in Terminal.sd will not be defined. So, we comment out
+// code which references those data structures and just return default
+// values.
+//
+// 1 5/24/2007 2:33p Ambikas
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: InitTerminalStrings.c
+//
+// Description: Contains InitTerminalStrings(), which is linked to
+// SetupStringInit in the sdl page. Before entering setup,
+// we do any modification or updating needed for the serial
+// port name strings (STR_SIO_SERIAL_PORT0, etc.).
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include <Token.h>
+#include "TerminalSetupVar.h"
+
+#ifndef HII_LIBRARY_FUNCTIONS_SUPPORT
+EFI_STATUS HiiLibGetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF StringId,
+ IN OUT UINTN *StringSize,
+ OUT EFI_STRING String
+);
+EFI_STATUS HiiLibSetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF StringId,
+ IN EFI_STRING String
+);
+#endif
+
+
+STRING_REF gSioSerialPortStrRef[MAX_SIO_SERIAL_PORTS] = {
+ STRING_TOKEN(STR_SIO_SERIAL_PORT0),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT1),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT2),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT3),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT4),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT5),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT6),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT7),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT8),
+ STRING_TOKEN(STR_SIO_SERIAL_PORT9)
+};
+
+STRING_REF gPciSerialPortStrRef[MAX_PCI_SERIAL_PORTS] = {
+ STRING_TOKEN(STR_PCI_SERIAL_PORT0),
+ STRING_TOKEN(STR_PCI_SERIAL_PORT1),
+ STRING_TOKEN(STR_PCI_SERIAL_PORT2),
+ STRING_TOKEN(STR_PCI_SERIAL_PORT3)
+};
+
+UINT32 gTotalSioSerialPorts = TOTAL_SIO_SERIAL_PORTS;
+UINT32 gTotalPciSerialPorts = TOTAL_PCI_SERIAL_PORTS;
+
+EFI_GUID gTerminalVarGuid = TERMINAL_VAR_GUID;
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: StrCat
+//
+// Description: Wrapper function around Wcscpy.
+// Concantenates the second Unicode string to the first.
+//
+// Input:
+// IN OUT CHAR16 *Destination
+// IN CHAR16 *Source
+//
+// Output: VOID
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID StrCat (IN OUT CHAR16 *Destination, IN CHAR16 *Source)
+{
+ Wcscpy (Destination + Wcslen (Destination), Source);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitTerminalStrings
+//
+// Input:
+// IN EFI_HII_HANDLE HiiHandle
+// IN UINT16 Class
+//
+// Output: VOID
+//
+// Description: Certain strings in the terminal setup page can only be
+// updated at runtime, which is what this function does.
+// The pci serial port names are changed to contain the
+// location (device and function numbers) of the port.
+// If any serial ports are disabled, "Disabled"
+// is concatenated to their names.
+//
+// Output:
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID InitTerminalStrings(IN EFI_HII_HANDLE HiiHandle, IN UINT16 Class)
+{
+#if (TOTAL_SERIAL_PORTS > 0)
+
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ UINTN SerialPortsEnabledVarSize = sizeof(SERIAL_PORTS_ENABLED_VAR);
+ SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar;
+ UINT32 SerialPortsEnabledVarAttributes=0;
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ UINTN PciSerialPortsLocationVarSize
+ = sizeof(PCI_SERIAL_PORTS_LOCATION_VAR);
+ PCI_SERIAL_PORTS_LOCATION_VAR PciSerialPortsLocationVar;
+ UINT32 PciSerialPortsLocationVarAttributes=0;
+#endif
+
+ UINT32 i = 0;
+
+ CHAR16 Str[512]=L"";
+ CHAR16 Str2[512]=L"";
+ UINTN Size=512;
+
+ if (Class==ADVANCED_FORM_SET_CLASS) {
+ Status = pRS->GetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &SerialPortsEnabledVarAttributes,
+ &SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ Status = pRS->GetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &PciSerialPortsLocationVarAttributes,
+ &PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+#endif
+
+ for (i = 0; i < gTotalSioSerialPorts; i++) {
+ if (!SerialPortsEnabledVar.PortsEnabled[i]) {
+ Size = 512;
+ Status = HiiLibGetString(HiiHandle,
+ gSioSerialPortStrRef[i],
+ &Size, Str);
+ if (!EFI_ERROR(Status)) {
+ StrCat(Str, L" (Disabled)");
+ InitString(HiiHandle, gSioSerialPortStrRef[i], Str);
+ }
+ }
+ }
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ for (i = 0; i < gTotalPciSerialPorts; i++) {
+ Size = 512;
+ Status = HiiLibGetString(HiiHandle,
+ gPciSerialPortStrRef[i],
+ &Size, Str);
+ if (!EFI_ERROR(Status)) {
+ if(PciSerialPortsLocationVar.AmiPciSerialPresent[i] == TRUE) {
+ //
+ // If AMI Serial Protcocol was installed for this PCI Serial device,
+ // then display the device like COM3(Pci Bus2,Dev10,Func1,Port0)
+ // with Port information.
+ //
+ Swprintf(Str2, L"COM%X(Pci Bus%d,Dev%d,Func%d,Port%d)",
+ gTotalSioSerialPorts+i,
+ PciSerialPortsLocationVar.Bus[i],
+ PciSerialPortsLocationVar.Device[i],
+ PciSerialPortsLocationVar.Function[i],
+ PciSerialPortsLocationVar.Port[i]);
+ } else {
+ Swprintf(Str2, L"COM%X(Pci Bus%d,Dev%d,Func%d)",
+ gTotalSioSerialPorts+i,
+ PciSerialPortsLocationVar.Bus[i],
+ PciSerialPortsLocationVar.Device[i],
+ PciSerialPortsLocationVar.Function[i]);
+ }
+
+ StrCat(Str, Str2);
+ if (!SerialPortsEnabledVar.PortsEnabled[gTotalSioSerialPorts+i]) {
+ StrCat(Str, L" (Disabled)");
+ }
+ InitString(HiiHandle, gPciSerialPortStrRef[i], Str);
+ }
+ }
+#endif
+ }
+#endif
+}
+
+#ifndef HII_LIBRARY_FUNCTIONS_SUPPORT
+#include <Protocol/Hii.h>
+
+static EFI_HII_PROTOCOL *Hii = NULL;
+
+static EFI_STATUS HiiLibGetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF StringId,
+ IN OUT UINTN *StringSize,
+ OUT EFI_STRING String
+)
+{
+ if (Hii == NULL && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiProtocolGuid, NULL, &Hii)))
+ return EFI_NOT_FOUND;
+
+ return Hii->GetString(Hii, HiiHandle, StringId, TRUE, NULL, StringSize, String);
+}
+
+static EFI_STATUS HiiLibSetString(
+ IN EFI_HII_HANDLE HiiHandle,
+ IN STRING_REF StringId,
+ IN EFI_STRING String
+)
+{
+ if (Hii == NULL && EFI_ERROR(pBS->LocateProtocol(&gEfiHiiProtocolGuid, NULL, &Hii)))
+ return EFI_NOT_FOUND;
+
+ return Hii->NewString(Hii, L" ", HiiHandle, &StringId, String);
+}
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//**************************************************************************** \ No newline at end of file
diff --git a/Core/EM/Terminal/Terminal.chm b/Core/EM/Terminal/Terminal.chm
new file mode 100644
index 0000000..f8a5683
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.chm
Binary files differ
diff --git a/Core/EM/Terminal/Terminal.cif b/Core/EM/Terminal/Terminal.cif
new file mode 100644
index 0000000..1834433
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.cif
@@ -0,0 +1,21 @@
+<component>
+ name = "Serial Redirection"
+ category = eModule
+ LocalRoot = "Core\EM\Terminal\"
+ RefName = "Terminal"
+[files]
+"Terminal.sdl"
+"Terminal.mak"
+"TerminalSetupVar.h"
+"TerminalSetup.c"
+"InitTerminalStrings.c"
+"Terminal.sd"
+"Terminal.uni"
+"Terminal.lib"
+"Terminalx64.lib"
+"Terminal.chm"
+"TerminalBoard.h"
+"TerminalAcpi.c"
+[parts]
+"TerminalAmiSerial Protocol"
+<endComponent>
diff --git a/Core/EM/Terminal/Terminal.lib b/Core/EM/Terminal/Terminal.lib
new file mode 100644
index 0000000..b065cf7
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.lib
Binary files differ
diff --git a/Core/EM/Terminal/Terminal.mak b/Core/EM/Terminal/Terminal.mak
new file mode 100644
index 0000000..daa0578
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.mak
@@ -0,0 +1,165 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Terminal/Terminal.mak 12 12/22/11 1:32a Rajeshms $
+#
+# $Revision: 12 $
+#
+# $Date: 12/22/11 1:32a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/Terminal/Terminal.mak $
+#
+# 12 12/22/11 1:32a Rajeshms
+# [TAG] EIP57579
+# [Category] Improvement
+# [Description] PCI legacy console redirection causes Legacy OS
+# installation slow because when Redirection is enabled for Legacy OS,
+# Legacy Serial Redirection enables the PCI Serial interrupt for
+# redirection and sometime after that OS uses its own IVT but still PCI
+# Serial interrupt is generated and not handled.So, disable redirection
+# at OS level. we disable redirection on ACPI enable/disable call and
+# reset the Interrupt Enable Register so that interrupt is not generated.
+# [Files] Terminal.sdl, Terminal.mak, Terminal.cif, TerminalAcpi.c
+#
+# 11 2/12/10 5:06p Felixp
+# Clean up (unneeded target removed)
+#
+# 10 7/02/09 5:00p Rameshr
+# Coding Standard and File header updated.
+#
+# 9 4/14/08 6:52p Ambikas
+#
+# 8 11/29/07 11:58a Ambikas
+# Fixed bug. If Terminal_SUPPORT was set to 0, InitTerminalStrings.c
+# would still be compiled and incorporated into SetupBin,
+# which would result in an assert while booting.
+# Made the compiling of InitTerminalStrings.obj and the generation of
+# Terminal.sdb dependent on the value of Terminal_SUPPORT.
+#
+# 7 11/07/07 4:53p Ambikas
+# Terminal.sd is dependent on token.h.
+#
+# 6 6/05/07 4:14p Ambikas
+#
+# 5 5/24/07 2:30p Ambikas
+# Added rule for InitTerminalStrings.c.
+#
+# 4 12/02/05 11:50a Felixp
+#
+# 3 11/11/05 2:07p Ambikas
+#
+# 2 2/11/05 5:49p Felixp
+# Binary files organization improved:
+# - extra layer of sub-component removed
+# - macros initialization moved to SDL tokens to eliminate undefined
+# macros situation
+# - debug and release binaries have different names now (workaround for
+# VeB limitation)
+# - binaries reside in the component home directory (eliminates
+# hardcoded paths)
+#
+# 1 1/28/05 12:47p Felixp
+#
+# 2 1/18/05 3:22p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 1 12/22/04 6:19p Admin
+#
+# 1 12/22/04 6:18p Admin
+#
+# 1 11/07/04 3:20p Markw
+# Adding unfinished code to source control. Partially works. Currently
+# turned off.
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Terminal_mak
+#
+# Description: Creates Terminal.efi.
+# Includes either Terminal.lib or Terminalx64.lib depending
+# on the cpu mode.
+#
+# These two files are not part of Terminal.efi:
+# The Terminal.sd file is compiled as part of the target SetupSdbs
+# in Setup.mak.
+# InitTerminalStrings.c is compiled as part of the target SetupBin
+# in Setup.mak.
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : TERMINAL
+
+TERMINAL : $(BUILD_DIR)\Terminal.mak TERMINALBIN
+
+$(BUILD_DIR)\Terminal.mak : $(TERMINAL_DIR)\$(@B).cif \
+ $(TERMINAL_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TERMINAL_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TERMINALBIN : $(AMIDXELIB) $(Terminal_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Terminal.mak all\
+ OBJECTS=$(BUILD_DIR)\$(TERMINAL_DIR)\TerminalSetup.obj\
+ GUID=7A08CB98-E9BC-41c3-BE19-B302F3F1F595\
+ ENTRY_POINT=TerminalEntryPoint \
+ "EXT_HEADERS=$(BUILD_DIR)\token.h"\
+ TYPE=BS_DRIVER LIBRARIES= \
+ COMPRESS=1\
+ "INIT_LIST=$(TerminalInitialize)"
+
+#***********************************************************************
+
+!IF "$(Terminal_SUPPORT)"=="1"
+SetupSdbs : TerminalSDB
+!ENDIF
+
+TerminalSDB : $(BUILD_DIR)\Terminal.mak
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Terminal.mak all\
+ TYPE=SDB NAME=Terminal STRING_CONSUMERS=$(TERMINAL_DIR)\Terminal.sd
+
+!IF "$(Terminal_SUPPORT)"=="1"
+SetupBin : $(BUILD_DIR)\InitTerminalStrings.obj
+!ENDIF
+
+$(BUILD_DIR)\InitTerminalStrings.obj : \
+ $(TERMINAL_DIR)\InitTerminalStrings.c \
+ $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(TERMINAL_DIR)\InitTerminalStrings.c
+
+#***********************************************************************
+
+!IF "$(DISABLE_PCI_REDIRECTION_ON_ACPI_ENABLE_DISABLE)"=="1"
+
+$(BUILD_DIR)\TerminalAcpi.obj: $(TERMINAL_DIR)\TerminalAcpi.c
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(TERMINAL_DIR)\TerminalAcpi.c /I$(TERMINAL_DIR)
+
+AcpiModeEnableBin: $(BUILD_DIR)\TerminalAcpi.obj
+!ENDIF
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2009, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
diff --git a/Core/EM/Terminal/Terminal.sd b/Core/EM/Terminal/Terminal.sd
new file mode 100644
index 0000000..35f2474
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.sd
@@ -0,0 +1,1533 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+// $Header: /Alaska/BIN/Modules/Terminal/Terminal.sd 46 6/16/14 7:52a Divyac $
+//
+// $Revision: 46 $
+//
+// $Date: 6/16/14 7:52a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Terminal/Terminal.sd $
+//
+// 46 6/16/14 7:52a Divyac
+// [TAG] EIP172073
+// [Category] Improvement
+// [Description] Setup option for Legacy Serial Redirection.
+// [Files] Terminal.sd, Terminal.uni, LegacySredir_Setup.c
+//
+// 45 3/14/14 8:37a Anbuprakashp
+// [TAG] EIP156273
+// [Category] Improvement
+// [Description] Avoid Build issue happened in Non english version of
+// the OS with Serial Redirection label 4.6.3_Terminal_53
+// [Files] Terminal.sd,TerminalSetup.c
+//
+// 44 9/04/13 3:25a Anbuprakashp
+// [TAG] EIP134648
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error occurs in Sharkbay platform if tokens
+// "TOTAL_SIO_SERIAL_PORTS" and "TOTAL_PCI_SERIAL_PORTS" are set to 0
+// [RootCause] TerminalSetup.c file Status Variable Initialization is
+// missing.Terminal.sd file, Condition (TOTAL_SERIAL_PORTS > 0) need to be
+// added to avoid build error.
+// [Solution] Terminal.sd file, Condition (TOTAL_SERIAL_PORTS > 0) added
+// to avoid build error.
+// Status variable initialzed properly.
+// [Files] Terminal.sd,TerminalSetup.c
+//
+// 43 12/12/11 1:57a Jittenkumarp
+// [TAG] EIP75982
+// [Category] New Feature
+// [Description] Redirection After BIOS POST item on the setup menu
+// [Files] Terminal.sd, Terminal.uni, LegacySredir.c,
+// LegacySredir_Setup.c
+//
+// 42 9/20/11 3:04a Rajeshms
+// [TAG] EIP70320
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] SPCR table is not created with EFI_SPECIFICATION_VERSION
+// 0x2000A
+// [RootCause] Comport was returned as 0xff from
+// GetAcpiSpcrTableValues() as the PORT number is zero indexed after
+// EFI_SPECIFICATION_VERSION 0x2000A.
+// [Solution] The comport number is not subtracted with 1 if
+// EFI_SPECIFICATION_VERSION is equal to greater than0x2000A
+// [Files] Terminal.sd, TerminalSetup.c
+//
+// 41 9/12/11 3:11a Rajeshms
+// [TAG]- EIP 63665
+// [Category]-IMPROVEMENT
+// [Description]- Install Linux(Legacy OS) through remote. Some Linux
+// versions are forced to text mode to redirect and some are redirected in
+// graphics mode itself. It might not work for all the Linux versions as
+// the Linux kernel's behave differently.
+// [Files]- Terminal.sdl, Terminal.uni, Terminal.sd, LegacySredir.c,
+// LegacySredir.h, LegacySredir_Setup.c, GRAPHREDIR.ASM, INT10REDIR.ASM,
+// OR_MOD.ASM, OR_MOD.EQU, SREDIR.ASM
+//
+// 40 7/29/11 2:22a Lavanyap
+// [TAG] EIP65854
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build errors on redefinition of symbols PORT(0-9) in some
+// projects.
+// [RootCause] Terminal module redefines symbols PORT(0-9).
+// [Solution] Symbol definition PORTx has been changed to
+// TERMINAL_PORTx.
+// [Files] Terminal.sd
+//
+// 39 7/13/11 2:48a Rajeshms
+// [TAG]- EIP 36616
+// [Category]- New Feature
+// [Description]- Add Setup option for Various Putty keyPad support in
+// Terminal driver.
+// [Files]- Terminal.c, Terminal.h, Terminal.sd, Terminal.sdl,
+// Terminal.uni, TerminalBoard.h, TerminalSetup.c, TerminalSimpleTextIn.c
+//
+// 38 6/21/11 7:06a Rameshr
+// [TAG] - EIP 62809
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - COM ports can't be select in Out-of-band mgmt port in setup
+// menu,it always show COM0..
+// [RootCause]- UEFI2.1 port index starts from 0.
+// [Solution] - Modified the values based on the Port0, Port1 etc
+// defination.
+// [Files] - Terminal.sd
+//
+// 37 4/12/11 4:30a Rameshr
+// [TAG]- EIP 57688
+// [Category]- New Feature
+// [Description]- Add Setup option for Vt-UTF8 combo key support in
+// terminal driver
+// [Files]- Terminal.c, Terminal.h, Terminal.sd, Terminal.sdl ,
+// Terminal.uni, Terminalboard.h, TerminalSetup.c, TerminalSimpletextin.c
+//
+// 36 1/24/11 4:05a Lavanyap
+// [TAG] - EIP48183
+// [Category] - IMPROVEMENT
+// [Description] - Update the Terminal eModule to utilize Setup
+// Customization
+// [Files] - Terminal.sd, TerminalSetupVar.h
+//
+// 35 11/02/10 4:17a Lavanyap
+// [TAG] - EIP42299
+// [Category] - IMPROVEMENT
+// [Description] - Console Redirection can support 10 COM Ports.
+// [Files] - InitTerminalStrings.c, SerialIo.c, Terminal.sd,
+// Terminal.sdl, Terminal.uni, TerminalSetup.c
+//
+// 34 9/24/10 12:40a Rameshr
+// [TAG] - EIP 44736
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - Terminal label 44 is not building in UEFI2.1 mode
+// [RootCause] - suppressif and grayoutif used in Single menu
+// [Solution] - Used SUPPRESS_GRAYOUT_ENDIF to resolve the build error
+// [Files] - Terminal.sd
+//
+// 33 6/01/10 12:29a Rameshr
+// Support for Baud Rate 38400 in Terminal Driver
+// EIP 38852
+//
+// 32 5/03/10 12:21a Rameshr
+// Issue:VT-UTF8 mode support for Console redirection with Debugger
+// Solution: Serial Port attribute Setup questions added for the debugger
+// console redirection port.
+// EIP 37440
+//
+// 31 3/31/10 12:29a Rameshr
+// Recorder mode support Added.
+// EIP 34388
+//
+// 30 3/30/10 1:02a Rameshr
+// Each Com port has SDL token for default value of console Redirection
+// setup option
+// EIP 15087
+//
+// 29 2/15/10 12:44p Pats
+// EIP 28461: Enabling Console Redirection COM4 locks SUT in POST
+// Added separate controls for PCI serial ports and a separate default.
+//
+//
+// 28 2/12/10 5:37p Felixp
+// Bug fix: the code didn't compile in UEFI 2.1 mode.
+//
+// 27 1/20/10 4:47p Artems
+// EIP 34000 - made UEFI 2.1 changes backward compatible
+//
+// 26 12/23/09 4:07a Rameshr
+// Software flowControl Removed as SerialIO doesnt support it.
+//
+// 25 12/16/09 5:08p Artems
+// EIP 31619 UEFI 2.1 support added
+//
+// 24 10/22/09 11:26a Yul
+// EIP 24167
+// Add Setup question to replace SDL token for LegacyOsResolution.
+//
+// 23 10/21/09 11:29a Artems
+// EIP 25955 - fixed switching mode mechanism
+//
+// 21 7/02/09 5:01p Rameshr
+// Coding Standard and File header updated.
+//
+// 20 11/14/08 10:56a Ambikas
+//
+// 18 11/12/08 5:55p Ambikas
+//
+// 17 10/21/08 4:49p Fasihm
+// Updated by adding more MANUFACTURING flags to missed setup questions.
+//
+// 16 8/13/08 5:56p Fasihm
+// Added the Manufacturing flags to the setup questions.
+//
+// 15 5/13/08 3:41p Rameshraju
+// Terminal Resolution 100 x 31 support Added
+//
+// 14 2/07/08 6:41p Ambikas
+//
+// 13 11/07/07 4:52p Ambikas
+// We have reverted the the VfrCompile convention of 1 based array.
+// Array indeces have been changed to accordingly.
+//
+// 12 6/12/07 3:52p Ambikas
+//
+// 11 6/11/07 11:35a Ambikas
+//
+// 10 6/05/07 6:31p Ambikas
+//
+// 9 6/05/07 12:43p Ambikas
+//
+// 8 6/05/07 12:41p Ambikas
+//
+// 7 6/04/07 7:26p Ambikas
+// -Serial port related setup vars are now only defined if
+// TOTAL_SERIAL_PORTS > 0.
+// -Increased max Pci Serial Ports to 4, and so added controls for the
+// additional ports.
+//
+// 6 5/24/07 2:32p Ambikas
+// Re-organized the file using macros.
+//
+// 5 4/32/07 4:25p Robert
+//
+// 4 4/02/07 4:25p Robert
+// Changed Default setup value to Disabled
+//
+// 3 5/05/06 5:34p Ambikas
+//
+// 2 12/02/05 7:44p Ambikas
+//
+// 1 11/11/05 2:07p Ambikas
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Terminal.sd
+//
+// Description: This is the setup page 'Serial Port Console Redirection.'
+// The link to the page is in the setup 'Advanced' tab.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef FORM_SET_TYPEDEF
+#include "TerminalSetupVar.h"
+#endif
+
+//Initialize Macro Arguments
+#define PORT_NUM 0
+#define DEFAULT_CONSOLE_REDIRECTION_ENABLE 0
+
+#if EFI_SPECIFICATION_VERSION>0x20000
+#define TERMINAL_PORT0 0
+#define TERMINAL_PORT1 1
+#define TERMINAL_PORT2 2
+#define TERMINAL_PORT3 3
+#define TERMINAL_PORT4 4
+#define TERMINAL_PORT5 5
+#define TERMINAL_PORT6 6
+#define TERMINAL_PORT7 7
+#define TERMINAL_PORT8 8
+#define TERMINAL_PORT9 9
+#else
+#define TERMINAL_PORT0 1
+#define TERMINAL_PORT1 2
+#define TERMINAL_PORT2 3
+#define TERMINAL_PORT3 4
+#define TERMINAL_PORT4 5
+#define TERMINAL_PORT5 6
+#define TERMINAL_PORT6 7
+#define TERMINAL_PORT7 8
+#define TERMINAL_PORT8 9
+#define TERMINAL_PORT9 10
+#endif
+#ifdef SETUP_DATA_DEFINITION
+ #if (TOTAL_SERIAL_PORTS > 0)
+
+ UINT8 BaudRate[ TOTAL_SERIAL_PORTS ];
+ UINT8 DataBits[ TOTAL_SERIAL_PORTS ];
+ UINT8 Parity[ TOTAL_SERIAL_PORTS ];
+ UINT8 StopBits[ TOTAL_SERIAL_PORTS ];
+ UINT8 FlowControl[ TOTAL_SERIAL_PORTS ];
+ UINT8 LoopbackEnable[ TOTAL_SERIAL_PORTS ];
+ UINT8 ConsoleRedirectionEnable[ TOTAL_SERIAL_PORTS ];
+ UINT8 TerminalType[ TOTAL_SERIAL_PORTS ];
+ UINT8 VtUtf8[ TOTAL_SERIAL_PORTS ];
+ UINT8 RecorderMode[ TOTAL_SERIAL_PORTS ];
+ UINT8 Resolution[ TOTAL_SERIAL_PORTS ];
+ UINT8 LegacyOsResolution[ TOTAL_SERIAL_PORTS ];
+ UINT8 PuttyFunctionKeyPad[ TOTAL_SERIAL_PORTS ];
+ UINT8 RedirectionAfterBiosPost[ TOTAL_SERIAL_PORTS ];
+#if (INSTALL_LEGACY_OS_THROUGH_REMOTE == 1)
+ UINT8 InstallLegacyOSthroughRemote[ TOTAL_SERIAL_PORTS ];
+#endif
+
+ UINT8 AcpiSpcrConsoleRedirectionEnable;
+ UINT8 AcpiSpcrPort;
+ UINT8 AcpiSpcrTerminalType;
+ UINT8 AcpiSpcrBaudRate;
+ UINT8 AcpiSpcrFlowControl;
+ UINT8 AcpiSpcrSetupDummyVar;
+ #endif //(TOTAL_SERIAL_PORTS > 0)
+ UINT8 DebuggerConsoleRedirectionEnable;
+ UINT8 DebuggerTerminalType;
+ UINT8 ComPortforLegacy;
+#endif //ifdef SETUP_DATA_DEFINITION
+
+////////////////////////////////////
+
+#if (TOTAL_SERIAL_PORTS > 0)
+ #ifdef FORM_SET_VARSTORE
+
+ varstore SERIAL_PORTS_ENABLED_VAR,
+ key = AUTO_ID(SERIAL_PORTS_ENABLED_VAR_KEY),
+ name = SerialPortsEnabledVar,
+ guid = TERMINAL_VAR_GUID;
+
+ #endif //FORM_SET_VARSTORE
+#endif //if (TOTAL_SERIAL_PORTS > 0)
+
+ #ifdef FORM_SET_VARSTORE
+
+ varstore DEBUGGER_SERIAL_PORTS_ENABLED_VAR,
+ key = AUTO_ID(DEBUGGER_SERIAL_PORTS_ENABLED_VAR_KEY),
+ name = DebuggerSerialPortsEnabledVar,
+ guid = DEBUGGER_TERMINAL_VAR_GUID;
+
+ #endif //FORM_SET_VARSTORE
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+#ifdef CONTROL_DEFINITION
+
+#ifdef CONSOLE_REDIRECTION_SUPPORT
+#if CONSOLE_REDIRECTION_SUPPORT == 1
+
+#define TERMINAL_CHECKBOX_DEBUGGERCONSOLEREDIRECTIONENABLE\
+ checkbox varid = SETUP_DATA.DebuggerConsoleRedirectionEnable,\
+ prompt = STRING_TOKEN(STR_CONSOLE_REDIRECTION),\
+ help = STRING_TOKEN(STR_CONSOLE_REDIRECTION_ENABLE_HELP),\
+ flags = DEFAULT_DEBUGGER_CONSOLE_REDIRECTION_ENABLE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+
+#define TERMINAL_ONEOF_DEBUGGERTERMINALTYPE\
+ oneof varid = SETUP_DATA.DebuggerTerminalType,\
+ prompt = STRING_TOKEN (STR_DEBUGGER_TERMINAL_TYPE),\
+ help = STRING_TOKEN (STR_DEBUGGER_TERMINAL_TYPE_HELP),\
+ option text = STRING_TOKEN (STR_VT100),\
+ value = 0,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_VT100_PLUS),\
+ value = 1,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_VT_UTF8),\
+ value = 2,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_ANSI),\
+ value = 3,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+#else
+ #define TERMINAL_CHECKBOX_DEBUGGERCONSOLEREDIRECTIONENABLE
+ #define TERMINAL_ONEOF_DEBUGGERTERMINALTYPE
+#endif // END #if CONSOLE_REDIRECTION_SUPPORT == 1
+#else
+ #define TERMINAL_CHECKBOX_DEBUGGERCONSOLEREDIRECTIONENABLE
+ #define TERMINAL_ONEOF_DEBUGGERTERMINALTYPE
+#endif // END #ifdef CONSOLE_REDIRECTION_SUPPORT
+
+//---------------------------------------------------------------------------
+// DEFINES USED IN PORT_SUB_PAGE MACRO START
+//---------------------------------------------------------------------------
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+#define TERMINAL_ONEOF_TERMINALTYPE(PORT_NUM)\
+ oneof varid = SETUP_DATA.TerminalType[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_TERMINAL_TYPE),\
+ help = STRING_TOKEN (STR_TERMINAL_TYPE_HELP),\
+ option text = STRING_TOKEN (STR_VT100),\
+ value = 0,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_VT100_PLUS),\
+ value = 1,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_VT_UTF8),\
+ value = 2,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_ANSI),\
+ value = 3,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define TERMINAL_ONEOF_BAUDRATE(PORT_NUM)\
+ oneof varid = SETUP_DATA.BaudRate[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_BAUD_RATE),\
+ help = STRING_TOKEN (STR_BAUD_RATE_HELP),\
+ option text = STRING_TOKEN (STR_9600),\
+ value = 3,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_19200),\
+ value = 4,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_38400),\
+ value = 5,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_57600),\
+ value = 6,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_115200),\
+ value = 7,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define TERMINAL_ONEOF_DATABITS(PORT_NUM)\
+ oneof varid = SETUP_DATA.DataBits[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_DATA_BITS),\
+ help = STRING_TOKEN (STR_DATA_BITS_HELP),\
+ option text = STRING_TOKEN (STR_7),\
+ value = 7,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_8),\
+ value = 8,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define TERMINAL_ONEOF_PARITY(PORT_NUM)\
+ oneof varid = SETUP_DATA.Parity[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_PARITY),\
+ help = STRING_TOKEN (STR_PARITY_HELP),\
+ option text = STRING_TOKEN (STR_NONE),\
+ value = 1,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_EVEN),\
+ value = 2,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_ODD),\
+ value = 3,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_MARK),\
+ value = 4,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_SPACE),\
+ value = 5,\
+ flags = 0;\
+ endoneof;
+
+#define TERMINAL_ONEOF_STOPBITS(PORT_NUM)\
+ oneof varid = SETUP_DATA.StopBits[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_STOP_BITS),\
+ help = STRING_TOKEN (STR_STOP_BITS_HELP),\
+ option text = STRING_TOKEN (STR_1),\
+ value = 1,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_2),\
+ value = 3,\
+ flags = 0;\
+ endoneof;
+
+#define TERMINAL_ONEOF_FLOWCONTROL(PORT_NUM)\
+ oneof varid = SETUP_DATA.FlowControl[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_FLOW_CTRL),\
+ help = STRING_TOKEN (STR_FLOW_CTRL_HELP),\
+ option text = STRING_TOKEN (STR_NONE),\
+ value = 0,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_HARDWARE_FLOW_CTRL),\
+ value = HARDWARE_FLOW_CONTROL_SETUP_OPTION,\
+ flags = 0;\
+ endoneof;
+
+#define TERMINAL_ONEOF_VTUTF8(PORT_NUM)\
+ checkbox varid = SETUP_DATA.VtUtf8[PORT_NUM],\
+ prompt = STRING_TOKEN(STR_TERMINAL_VTUTF8),\
+ help = STRING_TOKEN(STR_TERMINAL_VTUTF8_HELP),\
+ flags = VTUTF8_ENABLE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+
+#define TERMINAL_ONEOF_RECORDERMODE(PORT_NUM)\
+ checkbox varid = SETUP_DATA.RecorderMode[PORT_NUM],\
+ prompt = STRING_TOKEN(STR_TERMINAL_RECORDER_MODE),\
+ help = STRING_TOKEN(STR_TERMINAL_RECORDER_MODE_HELP),\
+ flags = RECORDER_MODE_ENABLE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+
+#define TERMINAL_ONEOF_RESOLUTION(PORT_NUM)\
+ checkbox varid = SETUP_DATA.Resolution[PORT_NUM],\
+ prompt = STRING_TOKEN(STR_TERMINAL_RESOLUTION),\
+ help = STRING_TOKEN(STR_TERMINAL_RESOLUTION_HELP),\
+ flags = EXTENDED_RESOLUTION_ENABLE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+
+#define TERMINAL_ONEOF_LEGACYOSRESOLUTION(PORT_NUM)\
+ oneof varid = SETUP_DATA.LegacyOsResolution[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_LEGACYOS_RESOLUTION),\
+ help = STRING_TOKEN (STR_LEGACYOS_RESOLUTION_HELP),\
+ option text = STRING_TOKEN (STR_80_24),\
+ value = 0,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_80_25),\
+ value = 1,\
+ flags = 0;\
+ endoneof;
+
+#define TERMINAL_ONEOF_PUTTYFUNCTIONKEYPAD(PORT_NUM)\
+ oneof varid = SETUP_DATA.PuttyFunctionKeyPad[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_PUTTYFUNCTION_KEYPAD),\
+ help = STRING_TOKEN (STR_PUTTYFUNCTION_KEYPAD_HELP),\
+ option text = STRING_TOKEN (STR_VT100), \
+ value = PUTTY_VT100, \
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED; \
+ option text = STRING_TOKEN (STR_LINUX), \
+ value = PUTTY_LINUX, \
+ flags = 0; \
+ option text = STRING_TOKEN (STR_XTERMR6), \
+ value = PUTTY_XTERMR6, \
+ flags = 0; \
+ option text = STRING_TOKEN (STR_SCO), \
+ value = PUTTY_SCO, \
+ flags = 0; \
+ option text = STRING_TOKEN (STR_ESCN), \
+ value = PUTTY_ESCN, \
+ flags = 0; \
+ option text = STRING_TOKEN (STR_VT400), \
+ value = PUTTY_VT400, \
+ flags = 0; \
+ endoneof;
+
+#if (INSTALL_LEGACY_OS_THROUGH_REMOTE == 1)
+#define TERMINAL_ONEOF_INSTALLLEGACYOSTHROUGHREMOTE(PORT_NUM)\
+ checkbox varid = SETUP_DATA.InstallLegacyOSthroughRemote[PORT_NUM],\
+ prompt = STRING_TOKEN(STR_FORCE_SYSTEM_VGA_TO_TEXT_MODE),\
+ help = STRING_TOKEN(STR_FORCE_SYSTEM_VGA_TO_TEXT_MODE_HELP),\
+ flags = INSTALL_LEGACY_OS_THROUGH_REMOTE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+#else
+#define TERMINAL_ONEOF_INSTALLLEGACYOSTHROUGHREMOTE(PORT_NUM)
+#endif
+
+#define TERMINAL_ONEOF_REDIRECTIONAFTERBIOSENABLE(PORT_NUM)\
+ oneof varid = SETUP_DATA.RedirectionAfterBiosPost[PORT_NUM],\
+ prompt = STRING_TOKEN (STR_REDIRECTION_AFTER_BIOS_POST),\
+ help = STRING_TOKEN (STR_REDIRECTION_AFTER_BIOS_POST_HELP),\
+ option text = STRING_TOKEN (STR_ALWAY_ENABLE),\
+ value = 0,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_BOOTLOADER),\
+ value = 1,\
+ flags = 0;\
+ endoneof;
+//---------------------------------------------------------------------------
+// DEFINES USED IN PORT_SUB_PAGE MACRO END
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// DEFINES USED IN PORT_CONTROLS and PORT_CONTROLS_PCI MACRO START
+//---------------------------------------------------------------------------
+
+#define TERMINAL_ONEOF_CONSOLEREDIRECTIONENABLE(PORT_NUM,DEFAULT_CONSOLE_REDIRECTION_ENABLE)\
+ checkbox varid = SETUP_DATA.ConsoleRedirectionEnable[PORT_NUM],\
+ prompt = STRING_TOKEN(STR_CONSOLE_REDIRECTION),\
+ help = STRING_TOKEN(STR_CONSOLE_REDIRECTION_ENABLE_HELP),\
+ flags = DEFAULT_CONSOLE_REDIRECTION_ENABLE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+
+#endif
+//---------------------------------------------------------------------------
+// DEFINES USED IN PORT_CONTROLS and PORT_CONTROLS_PCI MACRO END
+//---------------------------------------------------------------------------
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+#define TERMINAL_CHECKBOX_ACPISPCRCONSOLEREDIRECTIONENABLE\
+ checkbox varid = SETUP_DATA.AcpiSpcrConsoleRedirectionEnable,\
+ prompt = STRING_TOKEN(STR_CONSOLE_REDIRECTION),\
+ help = STRING_TOKEN(STR_CONSOLE_REDIRECTION_ENABLE_HELP),\
+ flags = DEFAULT_ACPI_SPCR_CONSOLE_REDIRECTION_ENABLE | MANUFACTURING | RESET_REQUIRED,\
+ endcheckbox;
+
+#define TERMINAL_ONEOF_ACPISPCRTERMINALTYPE\
+ oneof varid = SETUP_DATA.AcpiSpcrTerminalType,\
+ prompt = STRING_TOKEN (STR_TERMINAL_TYPE),\
+ help = STRING_TOKEN (STR_OUT_OF_BAND_MGMT_TERMINAL_TYPE_HELP),\
+ option text = STRING_TOKEN (STR_VT100),\
+ value = 0,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_VT100_PLUS),\
+ value = 1,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_VT_UTF8),\
+ value = 2,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_ANSI),\
+ value = 3,\
+ flags = 0;\
+ endoneof;
+
+#define TERMINAL_ONEOF_ACPISPCRBAUDRATE\
+ oneof varid = SETUP_DATA.AcpiSpcrBaudRate,\
+ prompt = STRING_TOKEN (STR_BAUD_RATE),\
+ help = STRING_TOKEN (STR_BAUD_RATE_HELP),\
+ option text = STRING_TOKEN (STR_9600),\
+ value = 3,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_19200),\
+ value = 4,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_57600),\
+ value = 6,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_115200),\
+ value = 7,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+
+#define TERMINAL_ONEOF_ACPISPCRFLOWCONTROL\
+ oneof varid = SETUP_DATA.AcpiSpcrFlowControl,\
+ prompt = STRING_TOKEN (STR_FLOW_CTRL),\
+ help = STRING_TOKEN (STR_FLOW_CTRL_HELP),\
+ option text = STRING_TOKEN (STR_NONE),\
+ value = 0,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_HARDWARE_FLOW_CTRL),\
+ value = HARDWARE_FLOW_CONTROL_SETUP_OPTION,\
+ flags = 0;\
+ option text = STRING_TOKEN (STR_SOFTWARE_FLOW_CTRL),\
+ value = SOFTWARE_FLOW_CONTROL_SETUP_OPTION,\
+ flags = 0;\
+ endoneof;
+
+#else
+ #define TERMINAL_CHECKBOX_ACPISPCRCONSOLEREDIRECTIONENABLE
+ #define TERMINAL_ONEOF_ACPISPCRTERMINALTYPE
+ #define TERMINAL_ONEOF_ACPISPCRBAUDRATE
+ #define TERMINAL_ONEOF_ACPISPCRFLOWCONTROL
+#endif // END #if (TOTAL_SERIAL_PORTS > 0)
+
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+//---------------------------------------------------------------------------
+// PCI PORT OPTION TEXT INDEX DEFINITION
+//---------------------------------------------------------------------------
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0) && (TOTAL_SIO_SERIAL_PORTS == 0)
+
+#define PCI_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT0),\
+ value = PCI_SERIAL_PORT_0_INDEX,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+
+#else
+
+#define PCI_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT0),\
+ value = PCI_SERIAL_PORT_0_INDEX,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_PCI_SERIAL_PORTS > 0) && (TOTAL_SIO_SERIAL_PORTS == 0)
+
+
+//---------------------------------------------------------------------------
+// PCI PORT OPTION TEXT DEFINITION START
+//---------------------------------------------------------------------------
+
+#if (TOTAL_PCI_SERIAL_PORTS == 0)
+
+ #define PCI_PORT_OPTION_TEXT
+
+#endif // END #if (TOTAL_PCI_SERIAL_PORTS == 0)
+
+#if (TOTAL_PCI_SERIAL_PORTS == 1)
+
+#define PCI_PORT_OPTION_TEXT\
+ PCI_PORT_OPTION_TEXT_INDEX
+
+#endif // END #if (TOTAL_PCI_SERIAL_PORTS == 1)
+
+#if (TOTAL_PCI_SERIAL_PORTS == 2)
+
+#define PCI_PORT_OPTION_TEXT\
+ PCI_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT1),\
+ value = PCI_SERIAL_PORT_1_INDEX,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_PCI_SERIAL_PORTS == 2)
+
+#if (TOTAL_PCI_SERIAL_PORTS == 3)
+
+#define PCI_PORT_OPTION_TEXT\
+ PCI_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT1),\
+ value = PCI_SERIAL_PORT_1_INDEX,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT2),\
+ value = PCI_SERIAL_PORT_2_INDEX,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_PCI_SERIAL_PORTS == 3)
+
+#if (TOTAL_PCI_SERIAL_PORTS == 4)
+
+#define PCI_PORT_OPTION_TEXT\
+ PCI_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT1),\
+ value = PCI_SERIAL_PORT_1_INDEX,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT2),\
+ value = PCI_SERIAL_PORT_2_INDEX,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_PCI_SERIAL_PORT3),\
+ value = PCI_SERIAL_PORT_3_INDEX,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_PCI_SERIAL_PORTS == 4)
+
+//---------------------------------------------------------------------------
+// PCI PORT OPTION TEXT DEFINITION END
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// SIO PORT OPTION TEXT INDEX DEFINITION START
+//---------------------------------------------------------------------------
+
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+
+#define SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT0),\
+ value = TERMINAL_PORT0,\
+ flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS > 0)
+
+//---------------------------------------------------------------------------
+// SIO PORT OPTION TEXT INDEX DEFINITION END
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// SIO PORT OPTION TEXT DEFINITION START
+//---------------------------------------------------------------------------
+
+#if (TOTAL_SIO_SERIAL_PORTS == 0)
+
+ #define SIO_PORT_OPTION_TEXT
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 0)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 1)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 1)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 2)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 2)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 3)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 3)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 4)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 4)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 5)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT4),\
+ value = TERMINAL_PORT4,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 5)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 6)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT4),\
+ value = TERMINAL_PORT4,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT5),\
+ value = TERMINAL_PORT5,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 6)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 7)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT4),\
+ value = TERMINAL_PORT4,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT5),\
+ value = TERMINAL_PORT5,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT6),\
+ value = TERMINAL_PORT6,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 7)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 8)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT4),\
+ value = TERMINAL_PORT4,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT5),\
+ value = TERMINAL_PORT5,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT6),\
+ value = TERMINAL_PORT6,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT7),\
+ value = TERMINAL_PORT7,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 8)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 9)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT4),\
+ value = TERMINAL_PORT4,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT5),\
+ value = TERMINAL_PORT5,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT6),\
+ value = TERMINAL_PORT6,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT7),\
+ value = TERMINAL_PORT7,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT8),\
+ value = TERMINAL_PORT8,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 9)
+
+#if (TOTAL_SIO_SERIAL_PORTS == 10)
+
+#define SIO_PORT_OPTION_TEXT\
+ SIO_PORT_OPTION_TEXT_INDEX\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT1),\
+ value = TERMINAL_PORT1,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT2),\
+ value = TERMINAL_PORT2,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT3),\
+ value = TERMINAL_PORT3,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT4),\
+ value = TERMINAL_PORT4,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT5),\
+ value = TERMINAL_PORT5,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT6),\
+ value = TERMINAL_PORT6,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT7),\
+ value = TERMINAL_PORT7,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT8),\
+ value = TERMINAL_PORT8,\
+ flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN (STR_SIO_SERIAL_PORT9),\
+ value = TERMINAL_PORT9,\
+ flags = RESET_REQUIRED;
+
+#endif // END #if (TOTAL_SIO_SERIAL_PORTS == 10)
+
+#endif // END #if ()
+
+//---------------------------------------------------------------------------
+// SIO PORT OPTION TEXT DEFINITION END
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// AcpiSpcrPort VARIABLE DEFINITION START
+//---------------------------------------------------------------------------
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+#define TERMINAL_ONEOF_ACPISPCRPORT\
+ oneof varid = SETUP_DATA.AcpiSpcrPort,\
+ prompt = STRING_TOKEN (STR_OUT_OF_BAND_MANAGEMENT_PORT),\
+ help = STRING_TOKEN (STR_OUT_OF_BAND_MANAGEMENT_PORT_HELP),\
+ SIO_PORT_OPTION_TEXT\
+ PCI_PORT_OPTION_TEXT\
+ endoneof;
+
+#endif // ((TOTAL_SERIAL_PORTS > 0)
+
+#ifndef TERMINAL_ONEOF_ACPISPCRPORT
+ #define TERMINAL_ONEOF_ACPISPCRPORT
+#endif // END #ifndef TERMINAL_ONEOF_ACPISPCRPORT
+
+//---------------------------------------------------------------------------
+// AcpiSpcrPort VARIABLE DEFINITION END
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// ComPortforLegacy VARIABLE DEFINITION START
+//---------------------------------------------------------------------------
+
+#if (TOTAL_SERIAL_PORTS > 1)
+
+#define TERMINAL_ONEOF_LEGACYPORT\
+ oneof varid = SETUP_DATA.ComPortforLegacy,\
+ prompt = STRING_TOKEN (STR_COM_FOR_LEGACY_REDIRECTION),\
+ help = STRING_TOKEN (STR_COM_FOR_LEGACY_REDIRECTION_HELP),\
+ SIO_PORT_OPTION_TEXT\
+ PCI_PORT_OPTION_TEXT\
+ endoneof;
+
+#endif // END #if (TOTAL_SERIAL_PORTS > 1)
+
+#ifndef TERMINAL_ONEOF_LEGACYPORT
+ #define TERMINAL_ONEOF_LEGACYPORT
+#endif // END #ifndef TERMINAL_ONEOF_LEGACYPORT
+
+//---------------------------------------------------------------------------
+// ComPortforLegacy VARIABLE DEFINITION END
+//---------------------------------------------------------------------------
+
+#endif // END #ifdef CONTROL_DEFINITION
+
+#ifdef CONTROLS_WITH_DEFAULTS
+ TERMINAL_CHECKBOX_DEBUGGERCONSOLEREDIRECTIONENABLE
+ TERMINAL_ONEOF_DEBUGGERTERMINALTYPE
+#if (TOTAL_SERIAL_PORTS > 0)
+ TERMINAL_ONEOF_TERMINALTYPE(PORT_NUM)
+ TERMINAL_ONEOF_BAUDRATE(PORT_NUM)
+ TERMINAL_ONEOF_DATABITS(PORT_NUM)
+ TERMINAL_ONEOF_PARITY(PORT_NUM)
+ TERMINAL_ONEOF_STOPBITS(PORT_NUM)
+ TERMINAL_ONEOF_FLOWCONTROL(PORT_NUM)
+ TERMINAL_ONEOF_VTUTF8(PORT_NUM)
+ TERMINAL_ONEOF_RECORDERMODE(PORT_NUM)
+ TERMINAL_ONEOF_RESOLUTION(PORT_NUM)
+ TERMINAL_ONEOF_LEGACYOSRESOLUTION(PORT_NUM)
+ TERMINAL_ONEOF_PUTTYFUNCTIONKEYPAD(PORT_NUM)
+ TERMINAL_ONEOF_REDIRECTIONAFTERBIOSENABLE(PORT_NUM)
+#if (INSTALL_LEGACY_OS_THROUGH_REMOTE == 1)
+ TERMINAL_ONEOF_INSTALLLEGACYOSTHROUGHREMOTE(PORT_NUM)
+#endif
+ TERMINAL_ONEOF_CONSOLEREDIRECTIONENABLE(PORT_NUM,DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+ TERMINAL_CHECKBOX_ACPISPCRCONSOLEREDIRECTIONENABLE
+ TERMINAL_ONEOF_ACPISPCRTERMINALTYPE
+ TERMINAL_ONEOF_ACPISPCRBAUDRATE
+ TERMINAL_ONEOF_ACPISPCRFLOWCONTROL
+ TERMINAL_ONEOF_ACPISPCRPORT
+#endif
+#endif // END #ifdef CONTROLS_WITH_DEFAULTS
+////////////////////////////////////
+
+#ifdef ADVANCED_FORM_SET
+
+#ifndef SUPPRESS_GRAYOUT_ENDIF //old Core
+#define SUPPRESS_GRAYOUT_ENDIF endif;
+#endif
+
+
+ #ifdef FORM_SET_GOTO
+ goto TERMINAL_FORM_ID,
+ prompt = STRING_TOKEN(STR_TERMINAL_FORM_TITLE),
+ help = STRING_TOKEN(STR_TERMINAL_FORM_TITLE);
+ #endif
+
+
+ #ifdef FORM_SET_FORM
+
+ #ifndef TERMINAL_FORM_MAIN
+ #define TERMINAL_FORM_MAIN
+ form formid = AUTO_ID(TERMINAL_FORM_ID),
+ title = STRING_TOKEN(STR_TERMINAL_FORM_TITLE);
+
+////////////////////////////////////
+
+#if (TOTAL_SERIAL_PORTS == 0)
+
+ SEPARATOR
+ SUBTITLE(STRING_TOKEN(STR_NO_SERIAL_PORTS_PRESENT))
+
+#else
+
+////////////////////////////////////
+
+#define PORT_CONTROLS(SUBTITLE_STR_TOKEN, FORM_ID, PORT_NUM,DEFAULT_CONSOLE_REDIRECTION_ENABLE) \
+ SEPARATOR \
+ SUBTITLE(SUBTITLE_STR_TOKEN) \
+\
+ suppressif ideqval SERIAL_PORTS_ENABLED_VAR.PortsEnabled[PORT_NUM]==1; \
+ text \
+ help = STRING_TOKEN(STR_BLANK), \
+ text = STRING_TOKEN(STR_CONSOLE_REDIRECTION), \
+ text = STRING_TOKEN(STR_PORT_IS_DISABLED), \
+ flags = 0, \
+ key = 0; \
+ endif; \
+\
+ suppressif ideqval SERIAL_PORTS_ENABLED_VAR.PortsEnabled[PORT_NUM]==0; \
+ TERMINAL_ONEOF_CONSOLEREDIRECTIONENABLE(PORT_NUM,DEFAULT_CONSOLE_REDIRECTION_ENABLE) \
+ endif; \
+\
+ suppressif ideqval SERIAL_PORTS_ENABLED_VAR.PortsEnabled[PORT_NUM]==0; \
+ grayoutif ideqval SETUP_DATA.ConsoleRedirectionEnable[PORT_NUM] == 0; \
+ goto FORM_ID, \
+ prompt = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS), \
+ help = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS_HELP); \
+ SUPPRESS_GRAYOUT_ENDIF
+
+#define PORT_CONTROLS_PCI(SUBTITLE_STR_TOKEN, FORM_ID, PORT_NUM, DEFAULT_PCI_CONSOLE_REDIRECTION_ENABLE) \
+ SEPARATOR \
+ SUBTITLE(SUBTITLE_STR_TOKEN) \
+\
+ suppressif ideqval SERIAL_PORTS_ENABLED_VAR.PortsEnabled[PORT_NUM]==1; \
+ text \
+ help = STRING_TOKEN(STR_BLANK), \
+ text = STRING_TOKEN(STR_CONSOLE_REDIRECTION), \
+ text = STRING_TOKEN(STR_PORT_IS_DISABLED), \
+ flags = 0, \
+ key = 0; \
+ endif; \
+\
+ suppressif ideqval SERIAL_PORTS_ENABLED_VAR.PortsEnabled[PORT_NUM]==0; \
+ TERMINAL_ONEOF_CONSOLEREDIRECTIONENABLE(PORT_NUM,DEFAULT_PCI_CONSOLE_REDIRECTION_ENABLE) \
+ endif; \
+\
+ suppressif ideqval SERIAL_PORTS_ENABLED_VAR.PortsEnabled[PORT_NUM]==0; \
+ grayoutif ideqval SETUP_DATA.ConsoleRedirectionEnable[PORT_NUM] == 0; \
+ goto FORM_ID, \
+ prompt = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS), \
+ help = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS_HELP); \
+ SUPPRESS_GRAYOUT_ENDIF
+
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT0), COM0_FORM_ID, TERMINAL_PORT0, COM0_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 1)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT1), COM1_FORM_ID, TERMINAL_PORT1, COM1_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 2)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT2), COM2_FORM_ID, TERMINAL_PORT2, COM2_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 3)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT3), COM3_FORM_ID, TERMINAL_PORT3, COM3_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 4)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT4), COM4_FORM_ID, TERMINAL_PORT4, COM4_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 5)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT5), COM5_FORM_ID, TERMINAL_PORT5, COM5_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 6)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT6), COM6_FORM_ID, TERMINAL_PORT6, COM6_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 7)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT7), COM7_FORM_ID, TERMINAL_PORT7, COM7_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 8)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT8), COM8_FORM_ID, TERMINAL_PORT8, COM8_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 9)
+ PORT_CONTROLS(STRING_TOKEN(STR_SIO_SERIAL_PORT9), COM9_FORM_ID, TERMINAL_PORT9, COM9_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+////////////////////////////////////
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ PORT_CONTROLS_PCI(STRING_TOKEN(STR_PCI_SERIAL_PORT0), PCI_SERIAL0_FORM_ID,
+ PCI_SERIAL_PORT_0_INDEX, PCI0_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 1)
+ PORT_CONTROLS_PCI(STRING_TOKEN(STR_PCI_SERIAL_PORT1), PCI_SERIAL1_FORM_ID,
+ PCI_SERIAL_PORT_1_INDEX, PCI1_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 2)
+ PORT_CONTROLS_PCI(STRING_TOKEN(STR_PCI_SERIAL_PORT2), PCI_SERIAL2_FORM_ID,
+ PCI_SERIAL_PORT_2_INDEX, PCI2_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 3)
+ PORT_CONTROLS_PCI(STRING_TOKEN(STR_PCI_SERIAL_PORT3), PCI_SERIAL3_FORM_ID,
+ PCI_SERIAL_PORT_3_INDEX, PCI3_DEFAULT_CONSOLE_REDIRECTION_ENABLE)
+#endif
+
+#endif
+////////////////////////////////////
+
+ SEPARATOR
+#ifdef CONSOLE_REDIRECTION_SUPPORT
+#if CONSOLE_REDIRECTION_SUPPORT == 1
+
+ SUBTITLE(STRING_TOKEN(STR_DEBUGGER_TERMINAL))
+
+ suppressif ideqval DEBUGGER_SERIAL_PORTS_ENABLED_VAR.PortEnabled == 1;
+ text
+ help = STRING_TOKEN(STR_BLANK),
+ text = STRING_TOKEN(STR_CONSOLE_REDIRECTION),
+ text = STRING_TOKEN(STR_PORT_IS_DISABLED),
+ flags = 0,
+ key = 0;
+ endif;
+
+
+ suppressif ideqval DEBUGGER_SERIAL_PORTS_ENABLED_VAR.PortEnabled==0;
+ TERMINAL_CHECKBOX_DEBUGGERCONSOLEREDIRECTIONENABLE
+ endif;
+
+ suppressif ideqval DEBUGGER_SERIAL_PORTS_ENABLED_VAR.PortEnabled==0;
+ grayoutif ideqval SETUP_DATA.DebuggerConsoleRedirectionEnable == 0;
+ TERMINAL_ONEOF_DEBUGGERTERMINALTYPE
+ SUPPRESS_GRAYOUT_ENDIF
+
+ SEPARATOR
+#endif
+#endif
+
+
+#if (TOTAL_SERIAL_PORTS > 0)
+ SUBTITLE(STRING_TOKEN(STR_LEGACY_CONSOLE_REDIRECTION))
+
+ goto LEGACYSREDIR_FORM_ID,
+ prompt = STRING_TOKEN(STR_LEGACY_CONSOLE_REDIRECTION_SETTINGS),
+ help = STRING_TOKEN(STR_LEGACY_CONSOLE_REDIRECTION_SETTINGS);
+
+ SEPARATOR
+#endif
+
+#if (TOTAL_SERIAL_PORTS > 0)
+ SUBTITLE(STRING_TOKEN(STR_SERIAL_PORT_FOR_OUT_OF_BAND_MGMT))
+#else
+ SUBTITLE(STRING_TOKEN(STR_NO_SERIAL_PORT_FOR_OUT_OF_BAND_MGMT))
+#endif
+
+ SUBTITLE(STRING_TOKEN(STR_EMERGENCY_MANAGEMENT_SERIVCES_EMS))
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+ TERMINAL_CHECKBOX_ACPISPCRCONSOLEREDIRECTIONENABLE
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ goto SPCR_FORM_ID,
+ prompt = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS),
+ help = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS_HELP);
+ endif;
+
+#endif
+ endform;
+#endif // END #if TERMINAL_FORM_MAIN
+
+ #ifndef TERMINAL_FORM_SPCR
+ #define TERMINAL_FORM_SPCR
+
+ form formid = AUTO_ID(SPCR_FORM_ID),
+ title = STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS);
+
+#if ((TOTAL_SERIAL_PORTS == 1) && (TOTAL_SIO_SERIAL_PORTS == 1))
+
+ suppressif ideqval SETUP_DATA.AcpiSpcrSetupDummyVar == 0;
+ TERMINAL_ONEOF_ACPISPCRPORT
+ endif;
+
+ text
+ help = STRING_TOKEN(STR_OUT_OF_BAND_MANAGEMENT_PORT_HELP),
+ text = STRING_TOKEN(STR_OUT_OF_BAND_MANAGEMENT_PORT),
+ text = STRING_TOKEN(STR_SIO_SERIAL_PORT0),
+ flags = 0,
+ key = 0;
+
+#endif //if ((TOTAL_SERIAL_PORTS == 1) && (TOTAL_SIO_SERIAL_PORTS == 1))
+
+#if ((TOTAL_SERIAL_PORTS == 1) && (TOTAL_PCI_SERIAL_PORTS == 1))
+
+ suppressif ideqval SETUP_DATA.AcpiSpcrSetupDummyVar == 0;
+ TERMINAL_ONEOF_ACPISPCRPORT
+ endif;
+
+ text
+ help = STRING_TOKEN(STR_OUT_OF_BAND_MANAGEMENT_PORT_HELP),
+ text = STRING_TOKEN(STR_OUT_OF_BAND_MANAGEMENT_PORT),
+ text = STRING_TOKEN(STR_PCI_SERIAL_PORT0),
+ flags = 0,
+ key = 0;
+
+#endif //if ((TOTAL_SERIAL_PORTS == 1) && (TOTAL_PCI_SERIAL_PORTS == 1))
+
+#if (TOTAL_SERIAL_PORTS > 1)
+
+ TERMINAL_ONEOF_ACPISPCRPORT
+
+#endif //if (TOTAL_SERIAL_PORTS > 1)
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ TERMINAL_ONEOF_ACPISPCRTERMINALTYPE
+ endif;
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ TERMINAL_ONEOF_ACPISPCRBAUDRATE
+ endif;
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ TERMINAL_ONEOF_ACPISPCRFLOWCONTROL
+ endif;
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ text
+ help = STRING_TOKEN(STR_DATA_BITS_HELP),
+ text = STRING_TOKEN(STR_DATA_BITS),
+ text = STRING_TOKEN(STR_8),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ text
+ help = STRING_TOKEN(STR_PARITY_HELP),
+ text = STRING_TOKEN(STR_PARITY),
+ text = STRING_TOKEN(STR_NONE),
+ flags = 0,
+ key = 0;
+ endif;
+
+ grayoutif ideqval SETUP_DATA.AcpiSpcrConsoleRedirectionEnable == 0;
+ text
+ help = STRING_TOKEN(STR_STOP_BITS_HELP),
+ text = STRING_TOKEN(STR_STOP_BITS),
+ text = STRING_TOKEN(STR_1),
+ flags = 0,
+ key = 0;
+ endif;
+
+#endif //if (TOTAL_SERIAL_PORTS > 0)
+
+ endform;
+
+#endif // END #if TERMINAL_FORM_SPCR
+
+#ifndef LEGACYSREDIR_FORM
+#define LEGACYSREDIR_FORM
+
+ form formid = AUTO_ID(LEGACYSREDIR_FORM_ID),
+ title = STRING_TOKEN(STR_LEGACY_CONSOLE_REDIRECTION_SETTINGS);
+
+ TERMINAL_ONEOF_LEGACYPORT
+
+ endform;
+#endif // END #if LEGACYSREDIR_FORM
+
+
+
+
+#endif //ifdef FORM_SET_FORM
+
+
+#define PORT_SUB_PAGE(TITLE_STR_TOKEN, SUBTITLE_STR_TOKEN, \
+ FORM_ID, PORT_NUM) \
+\
+ form formid = FORM_ID, \
+ title = TITLE_STR_TOKEN; \
+\
+ SUBTITLE_STR_TOKEN \
+ SUBTITLE(STRING_TOKEN(STR_CONSOLE_REDIRECTION_SETTINGS)) \
+ SEPARATOR \
+\
+ TERMINAL_ONEOF_TERMINALTYPE(PORT_NUM) \
+\
+ TERMINAL_ONEOF_BAUDRATE(PORT_NUM) \
+\
+ TERMINAL_ONEOF_DATABITS(PORT_NUM) \
+\
+ TERMINAL_ONEOF_PARITY(PORT_NUM) \
+\
+ TERMINAL_ONEOF_STOPBITS(PORT_NUM) \
+\
+ TERMINAL_ONEOF_FLOWCONTROL(PORT_NUM) \
+\
+ TERMINAL_ONEOF_VTUTF8(PORT_NUM) \
+\
+ TERMINAL_ONEOF_RECORDERMODE(PORT_NUM) \
+\
+ TERMINAL_ONEOF_RESOLUTION(PORT_NUM) \
+\
+ TERMINAL_ONEOF_LEGACYOSRESOLUTION(PORT_NUM) \
+\
+ TERMINAL_ONEOF_PUTTYFUNCTIONKEYPAD(PORT_NUM) \
+\
+ TERMINAL_ONEOF_INSTALLLEGACYOSTHROUGHREMOTE(PORT_NUM)\
+\
+ TERMINAL_ONEOF_REDIRECTIONAFTERBIOSENABLE(PORT_NUM)\
+\
+ SEPARATOR \
+\
+ endform;
+
+////////////////////////////////////
+
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT0),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT0)),
+ AUTO_ID(COM0_FORM_ID), TERMINAL_PORT0)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 1)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT1),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT1)),
+ AUTO_ID(COM1_FORM_ID), TERMINAL_PORT1)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 2)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT2),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT2)),
+ AUTO_ID(COM2_FORM_ID), TERMINAL_PORT2)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 3)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT3),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT3)),
+ AUTO_ID(COM3_FORM_ID), TERMINAL_PORT3)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 4)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT4),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT4)),
+ AUTO_ID(COM4_FORM_ID), TERMINAL_PORT4)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 5)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT5),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT5)),
+ AUTO_ID(COM5_FORM_ID), TERMINAL_PORT5)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 6)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT6),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT6)),
+ AUTO_ID(COM6_FORM_ID), TERMINAL_PORT6)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 7)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT7),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT7)),
+ AUTO_ID(COM7_FORM_ID), TERMINAL_PORT7)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 8)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT8),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT8)),
+ AUTO_ID(COM8_FORM_ID), TERMINAL_PORT8)
+ #endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 9)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_SIO_SERIAL_PORT9),
+ SUBTITLE(STRING_TOKEN(STR_SIO_SERIAL_PORT9)),
+ AUTO_ID(COM9_FORM_ID), TERMINAL_PORT9)
+ #endif
+#endif
+
+////////////////////////////////////
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_PCI_SERIAL_PORT0),
+ SUBTITLE(STRING_TOKEN(STR_PCI_SERIAL_PORT0)),
+ AUTO_ID(PCI_SERIAL0_FORM_ID), PCI_SERIAL_PORT_0_INDEX)
+ #endif
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 1)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_PCI_SERIAL_PORT1),
+ SUBTITLE(STRING_TOKEN(STR_PCI_SERIAL_PORT1)),
+ AUTO_ID(PCI_SERIAL1_FORM_ID), PCI_SERIAL_PORT_1_INDEX)
+ #endif
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 2)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_PCI_SERIAL_PORT2),
+ SUBTITLE(STRING_TOKEN(STR_PCI_SERIAL_PORT2)),
+ AUTO_ID(PCI_SERIAL2_FORM_ID), PCI_SERIAL_PORT_2_INDEX)
+ #endif
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 3)
+ #ifdef FORM_SET_FORM
+ PORT_SUB_PAGE(STRING_TOKEN(STR_PCI_SERIAL_PORT3),
+ SUBTITLE(STRING_TOKEN(STR_PCI_SERIAL_PORT3)),
+ AUTO_ID(PCI_SERIAL3_FORM_ID), PCI_SERIAL_PORT_3_INDEX)
+ #endif
+#endif
+////////////////////////////////////
+
+#endif //ifdef ADVANCED_FORM_SET
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/Terminal/Terminal.sdl b/Core/EM/Terminal/Terminal.sdl
new file mode 100644
index 0000000..d04fe5e
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.sdl
@@ -0,0 +1,796 @@
+TOKEN
+ Name = "Terminal_SUPPORT"
+ Value = "1"
+ Help = "Enable/Disable 'Serial Redirection' module. \This module contains Terminal.lib/Terminalx64.lib,\the compiled binary of module 'Serial Redirection \Sources.' It also contains all setup related material\for the module.\"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "SerialIo_SUPPORT"
+ Value = "1"
+ TokenType = Boolean
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SERIALIO_PCI_SERIAL_SUPPORT"
+ Value = "0"
+ Help = "0-Serial IO doesnt support the PCI serial Devices.1- Serial Io Driver installs the Serial IO for PCI serial Device."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DISABLE_TERMINAL_FOR_SCT_TEST"
+ Value = "0"
+ Help = "Set this token to 1 if running the SCT Test. It will result in console redirection being turned off. As of this revision, console redirection interferes wtih the SCT SerialIO test."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TOTAL_SIO_SERIAL_PORTS"
+ Value = "1"
+ Help = "**PORTING NEEDED** Total number of Super IO serial ports present."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "0-10"
+End
+
+TOKEN
+ Name = "TOTAL_PCI_SERIAL_PORTS"
+ Value = "0"
+ Help = "**PORTING NEEDED** Total number of PCI serial ports present."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "0-4"
+End
+
+TOKEN
+ Name = "TOTAL_SERIAL_PORTS"
+ Value = "$(TOTAL_SIO_SERIAL_PORTS)+$(TOTAL_PCI_SERIAL_PORTS)"
+ Help = "Total number of serial ports present (both Super IO and PCI)."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_SERIAL_MMIO_WIDTH"
+ Value = "1"
+ Help = "MMIO Com device width size. 1- Byte, 2- Word, 4-Dword. Default Set to Dword"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "1...4h"
+End
+
+TOKEN
+ Name = "MAX_SIO_SERIAL_PORTS"
+ Value = "10"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_PCI_SERIAL_PORTS"
+ Value = "4"
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_SERIAL_PORT_INDEX_BASE"
+ Value = "1"
+ Help = "Used in the Terminal.sd file."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "EFI_SPECIFICATION_VERSION" "<" "0x2000A"
+End
+
+TOKEN
+ Name = "PCI_SERIAL_PORT_INDEX_BASE"
+ Value = "0"
+ Help = "Used in the Terminal.sd file."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+ Token = "EFI_SPECIFICATION_VERSION" ">=" "0x2000A"
+End
+
+TOKEN
+ Name = "PCI_SERIAL_PORT_0_INDEX"
+ Value = "$(TOTAL_SIO_SERIAL_PORTS) + $(PCI_SERIAL_PORT_INDEX_BASE)"
+ Help = "Used in the Terminal.sd file."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_SERIAL_PORT_1_INDEX"
+ Value = "$(TOTAL_SIO_SERIAL_PORTS) + $(PCI_SERIAL_PORT_INDEX_BASE) + 1"
+ Help = "Used in the Terminal.sd file. VfrCompile does\ not allow the use of arithmetic expressions as \array indeces."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_SERIAL_PORT_2_INDEX"
+ Value = "$(TOTAL_SIO_SERIAL_PORTS) + $(PCI_SERIAL_PORT_INDEX_BASE) + 2"
+ Help = "Used in the Terminal.sd file. VfrCompile does\ not allow the use of arithmetic expressions as \array indeces."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_SERIAL_PORT_3_INDEX"
+ Value = "$(TOTAL_SIO_SERIAL_PORTS) + $(PCI_SERIAL_PORT_INDEX_BASE) + 3"
+ Help = "Used in the Terminal.sd file. VfrCompile does\ not allow the use of arithmetic expressions as \array indeces."
+ TokenType = Integer
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_BAUD_RATE"
+ Value = "115200"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_BAUD_RATE_INDEX"
+ Value = "7"
+ Help = "Index into array gAcpiSpcrTableComBaudRates."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_DATA_BITS"
+ Value = "8"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_PARITY"
+ Value = "1"
+ Help = "EFI_PARITY_TYPE NoParity, which has value 1."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_STOP_BITS"
+ Value = "1"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_FLOW_CONTROL"
+ Value = "0"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "UART_DEFAULT_LOOPBACK_ENABLE"
+ Value = "0"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI_UART_INPUT_CLOCK"
+ Value = "1843200"
+ Help = "This is PCI UART input clock. The default value is (24000000/13) = 1843200 MHz"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM0_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM1_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM2_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM3_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM4_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM5_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM6_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM7_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM8_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "COM9_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI0_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI1_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI2_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCI3_DEFAULT_CONSOLE_REDIRECTION_ENABLE"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_DEBUGGER_CONSOLE_REDIRECTION_ENABLE"
+ Value = "1"
+ Help = "Once Rx/Redir/Debugger port been detected, enable/disable Console Redirection."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_ACPI_SPCR_COM_PORT"
+ Value = "0"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_TERMINAL_TYPE"
+ Value = "3"
+ Help = "TERMINAL_TYPE ANSI, which is 3."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EXTENDED_RESOLUTION_ENABLE"
+ Value = "0"
+ Help = "Enable or disable 100 x 31 terminal resolution"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "VTUTF8_ENABLE"
+ Value = "1"
+ Help = "Enable or disable VT-UTF8 Combination Key Support for ANSI/VT100 terminals"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "RECORDER_MODE_ENABLE"
+ Value = "0"
+ Help = "Enable or disable Terminal Recorder Mode"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_ACPI_SPCR_CONSOLE_REDIRECTION_ENABLE"
+ Value = "1"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEFAULT_ACPI_SPCR_TABLE_TERMINAL_TYPE"
+ Value = "2"
+ Help = "TERMINAL_TYPE VT_UTF8, which is 2."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "HARDWARE_FLOW_CONTROL_SETUP_OPTION"
+ Value = "1"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAX_FAILURES_ALLOWED"
+ Value = "5"
+ Help = "The allowed range is 1 to 0xFF. This token value controls the hardware flow control retry count. Once the counter expired Redirection will be disabled and will be enabled again when host is ready to accept the data(i.e CTS is Set)."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SOFTWARE_FLOW_CONTROL_SETUP_OPTION"
+ Value = "2"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "TIMEOUT_FOR_DETERMINING_LONE_ESC_CHAR"
+ Value = "10000000"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "NUMBER_OF_TIME_FOR_ESC_SEQUENCE_CHECKING"
+ Value = "20"
+ TokenType = Integer
+ TargetH = Yes
+End
+TOKEN
+ Name = "SPCR_ACPI_OEM_ID"
+ Value = "A M I "
+ Help = "SPCR OEM Id -\a string value to be filled into SPCR ACPI table headers"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "1-6 characters"
+End
+
+TOKEN
+ Name = "SPCR_ACPI_OEM_TBL_ID"
+ Value = "APTIO4"
+ Help = "SPCR OEM table Id -\a string value to be filled into SPCR ACPI table headers"
+ TokenType = Expression
+ TargetMAK = Yes
+ TargetH = Yes
+ Range = "1-8 characters"
+End
+
+TOKEN
+ Name = "UART_FIFO_SIZE"
+ Value = "16"
+ TokenType = Integer
+ TargetH = Yes
+ Help = "UART fifo size. Maximum supported UART size is 16."
+ Range = "0-16."
+End
+
+TOKEN
+ Name = "REFRESH_SCREEN_KEY"
+ Value = "0x0012"
+ Help = "Unicode Value of Key to Refresh the Screen.Default it set to Ctrl+r"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "ASCII_CONTROL_CODE_SUPPORT"
+ Value = "1"
+ Help = "ASCII control code support 0 - Disabled 1- Enabled"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "spcr_interface_type"
+ Value = "0"
+ Help = "Indicate the type of the COM Port register interface.(ACPI 2.0 SPEC)."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0 = full 16550 interface; 1 = full 16450 interface; 2-255 = reserved."
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_addr_spc_id"
+ Value = "1"
+ Help = "UART BLK Register Id (Part of GAS_20 Structure, refer to ACPI v2.0 spec for details)"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0=System memory; 1=System I/O; 2=PCI Config Space; 3=Embeded Controller; 4=SMBus; 0x7F=Functional Fixed Hardware; All other values reserved"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_addr_bit_width"
+ Value = "8"
+ Help = "UART BLK Register Bit Width (Part of GAS_20 Structure, refer to ACPI v2.0 spec for details)"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "value range depends on other GAS_20 elements"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_addr_bit_offset"
+ Value = "0"
+ Help = "UART BLK Register Bit Offset (Part of GAS_20 Structure, refer to ACPI v2.0 spec for details)"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "value range depends on other GAS_20 elements"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_access_size"
+ Value = "0"
+ Help = "UART BLK Register Bit Offset (Part of GAS_20 Structure, refer to ACPI v2.0 spec for details)"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "value range depends on other GAS_20 elements"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_interrupt_type"
+ Value = "05h"
+ Help = "Interrupt type(s) used by the UART."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "Bit[0]=PC-AT dual-8259 PIC IRQ; Bit[1]=I/O APIC interrupt; Bit[2]=I/O SAPIC interrupt; Bit[3:7]=reserved (must be 0)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_global_system_int"
+ Value = "03h"
+ Help = "I/O APIC mode IRQ #."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-?: Depends on how many INTINs APIC has."
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_parity"
+ Value = "0"
+ Help = "UART parity check"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "(Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_stop_bits"
+ Value = "1"
+ Help = "UART stop bits"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "(Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_device_id"
+ Value = "0FFFFh"
+ Help = "if UART is on PCI bus - its device ID"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-0xffff (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_vendor_id"
+ Value = "0FFFFh"
+ Help = "if UART is on PCI bus - its vendor ID"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-0xffff (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_bus_number"
+ Value = "0"
+ Help = "if UART is on PCI bus - its BUS #"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-0xff (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_device_number"
+ Value = "0"
+ Help = "if UART is on PCI bus - its DEVICE #"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-31 (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_function_number"
+ Value = "0"
+ Help = "if UART is on PCI bus - its FUNCTION #"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-7 (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_flags"
+ Value = "0"
+ Help = "if UART is on PCI bus - PCI flags"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-0xff (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "spcr_pci_segment"
+ Value = "0"
+ Help = "if UART is on PCI bus - its PCI SEGMENT #"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "0-0xff (Refer to ACPI v2.0 spec for details)"
+ Token = "ACPI_BUILD_TABLES_2_0" "=" "1"
+End
+
+TOKEN
+ Name = "SERIAL_WRITE_ERROR_CHECK"
+ Value = "1"
+ Help = "Enable or disable Serial Port Write Error checking."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "MAXIMUM_SERIAL_WRITE_ERROR_COUNT"
+ Value = "10"
+ Help = "This token specifies the number of retry count for serial port write error. Once this count reaches all the serialWrite calls will be returned as error. This token is valid only when the SERIAL_WRITE_ERROR_CHECK is enabled"
+ TokenType = Integer
+ TargetH = Yes
+ Range = "1-0xffffffff "
+ Token = "SERIAL_WRITE_ERROR_CHECK" "=" "1"
+End
+
+TOKEN
+ Name = "CLEAR_TERMINAL_KB_BUFFER_AT_READYTOBOOT"
+ Value = "0"
+ Help = "ON- Terminal KB Buffer will be cleared at ReadyToBoot.\OFF - Terminal KB Buffer will not be cleared at ReadyToBoot."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "OEM_ESC_SEQUENCES"
+ Value = "1"
+ Help = "1- Enable OEM ESC Sequence.\0 - Disable OEM ESC Sequence."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PUTTY_VT100"
+ Value = "0x1"
+ Help = "Putty Vt100 KeyPad Value."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PUTTY_LINUX"
+ Value = "0x2"
+ Help = "Putty Linux KeyPad Value."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PUTTY_XTERMR6"
+ Value = "0x4"
+ Help = "Putty XtermR6 KeyPad Value."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PUTTY_SCO"
+ Value = "0x8"
+ Help = "Putty SCO KeyPad Value."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PUTTY_ESCN"
+ Value = "0x10"
+ Help = "Putty Escn KeyPad Value."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PUTTY_VT400"
+ Value = "0x20"
+ Help = "Putty Vt400 KeyPad Value."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "INSTALL_LEGACY_OS_THROUGH_REMOTE"
+ Value = "0"
+ Help = "Install Legacy OS like Linux through redirection. To make that happen some Linux are force to install in text mode and some others are redirected in graphics mode itseld. Note: All Linux Versions cannot be installed through remote as different Linux kernel's behave differently."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DONT_SEND_ASCII_CONTROL_PRINTABLE_CHARACTERS"
+ Value = "0"
+ Help = "Applications like HyperTerminal supports printable characters in the ASCII control characters value's(0 - 0x1F) but Putty does not. so,to print the printable ASCII control characters we will send the equivalent ASCII printable value(whichever is applicable) if the token is enabled."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DISABLE_PCI_REDIRECTION_ON_ACPI_ENABLE_DISABLE"
+ Value = "0"
+ Help = "When Redirection is enabled for Legacy OS, the system installation gets slow as Legacy Serial Redirection enables the PCI Serial interrupt for redirection and sometime after that OS uses its own IVT but PCI Serial interrupt is generated and not handled.So, disable redirection at OS level. we disable redirection on ACPI enable/disable call and reset the Interrupt Enable Register."
+ TokenType = Boolean
+ TargetH = Yes
+ TargetMAK = Yes
+End
+
+TOKEN
+ Name = "SERIAL_MOUSE_DETECTION"
+ Value = "0"
+ Help = "Detect the Serial Mouse in the Serial Port and if the Serial Mouse is present, redirection will not be enabled."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+PATH
+ Name = "TERMINAL_DIR"
+End
+
+MODULE
+ Help = "Includes Terminal.mak to Project"
+ File = "Terminal.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Terminal.sdb"
+ Parent = "SETUP_SDBS"
+ Priority = 80
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(TERMINAL_DIR)\Terminal.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 80
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "SerialIoEntryPoint,"
+ Parent = "TerminalInitialize"
+ Token = "SerialIo_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(TERMINAL_DIR)\Terminal$(ARCH).lib"
+ Parent = "Terminal_LIB"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "InitTerminalStrings,"
+ Parent = "SetupStringInit"
+ Token = "Terminal_SUPPORT" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "-i $(TERMINAL_DIR)"
+ Parent = "SETUP_VFR_INCLUDES"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Terminal.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TerminalInitialize"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "Terminal_LIB"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "TerminalAcpiEnableDisableCallBack,"
+ Parent = "AcpiEnableCallbackList"
+ Token = "DISABLE_PCI_REDIRECTION_ON_ACPI_ENABLE_DISABLE" "=" "1"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "TerminalAcpiEnableDisableCallBack,"
+ Parent = "AcpiDisableCallbackList"
+ Token = "DISABLE_PCI_REDIRECTION_ON_ACPI_ENABLE_DISABLE" "=" "1"
+ InvokeOrder = AfterParent
+End \ No newline at end of file
diff --git a/Core/EM/Terminal/Terminal.uni b/Core/EM/Terminal/Terminal.uni
new file mode 100644
index 0000000..827425c
--- /dev/null
+++ b/Core/EM/Terminal/Terminal.uni
Binary files differ
diff --git a/Core/EM/Terminal/TerminalAcpi.c b/Core/EM/Terminal/TerminalAcpi.c
new file mode 100644
index 0000000..da03372
--- /dev/null
+++ b/Core/EM/Terminal/TerminalAcpi.c
@@ -0,0 +1,179 @@
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//*************************************************************************
+
+//*************************************************************************
+// $Header: /Alaska/BIN/Modules/Terminal/TerminalAcpi.c 1 12/22/11 1:34a Rajeshms $
+//
+// $Revision: 1 $
+//
+// $Date: 12/22/11 1:34a $
+//*************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Terminal/TerminalAcpi.c $
+//
+// 1 12/22/11 1:34a Rajeshms
+// [TAG] EIP57579
+// [Category] Improvement
+// [Description] PCI legacy console redirection causes Legacy OS
+// installation slow because when Redirection is enabled for Legacy OS,
+// Legacy Serial Redirection enables the PCI Serial interrupt for
+// redirection and sometime after that OS uses its own IVT but still PCI
+// Serial interrupt is generated and not handled.So, disable redirection
+// at OS level. we disable redirection on ACPI enable/disable call and
+// reset the Interrupt Enable Register so that interrupt is not generated.
+// [Files] Terminal.sdl, Terminal.mak, Terminal.cif, TerminalAcpi.c
+//
+//
+//*************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TerminalAcpi.c
+//
+// Description: This file contains function to disable the PCI redirection
+// at ACPI enable call.
+//
+//<AMI_FHDR_END>
+//*************************************************************************
+
+//----------------------------------------------------------------------------
+// Include(s)
+//----------------------------------------------------------------------------
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol\SmmSwDispatch2.h>
+#define AMI_SMM_SW_DISPATCH_CONTEXT EFI_SMM_SW_REGISTER_CONTEXT
+#else
+#include <Protocol\SmmSwDispatch.h>
+#define AMI_SMM_SW_DISPATCH_CONTEXT EFI_SMM_SW_DISPATCH_CONTEXT
+#endif
+#include "TerminalSetupVar.h"
+
+#define CFG_SPACE_INDEX_REG 0xCF8
+#define CFG_SPACE_DATA_REG 0xCFC
+#define PCI_BAR0 0x0010
+#define INT08h_SEGMENT 0xF000
+#define INT08h_OFFSET 0xFEA5
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: TerminalAcpiEnableDisableCallBack
+//
+// Description: This routine will be called to disable PCI redirection at ACPI
+// enable/disable call and reset Interrupt Enable Register to
+// disable interrupt from PCI Serial device & replace actual INT08h.
+//
+// Input: None
+//
+// Output: None
+//
+// Notes: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+TerminalAcpiEnableDisableCallBack(
+ IN EFI_HANDLE DispatchHandle,
+ IN AMI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ EFI_STATUS Status;
+ UINT8 RegNum = PCI_BAR0;
+ UINT32 PciAddr;
+ UINT32 BarAddress;
+ UINT8 i,DevFunc;
+
+ UINT8 gTotalSioSerialPorts = TOTAL_SIO_SERIAL_PORTS;
+ EFI_GUID gTerminalVarGuid = TERMINAL_VAR_GUID;
+ UINTN PciSerialPortsLocationVarSize =
+ sizeof(PCI_SERIAL_PORTS_LOCATION_VAR);
+ PCI_SERIAL_PORTS_LOCATION_VAR PciSerialPortsLocationVar;
+
+ UINTN SerialPortsEnabledVarSize = sizeof(SERIAL_PORTS_ENABLED_VAR);
+ UINT32 SerialPortsEnabledVarAttributes=0;
+ SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar;
+
+
+ Status = pRS->GetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &SerialPortsEnabledVarAttributes,
+ &SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+
+ if (!EFI_ERROR(Status)) {
+ Status = pRS->GetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ NULL,
+ &PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+
+ if (!EFI_ERROR(Status)) {
+ for (i = 0; i < TOTAL_PCI_SERIAL_PORTS; i++) {
+ //
+ // Look for the PCI device that are enabled.
+ //
+ if (SerialPortsEnabledVar.PortsEnabled[gTotalSioSerialPorts+i]) {
+ if ((PciSerialPortsLocationVar.Bus[i] == 0) &&
+ (PciSerialPortsLocationVar.Device[i] == 0) &&
+ (PciSerialPortsLocationVar.Function[i] == 0)) {
+ continue;
+ }
+
+ DevFunc = (PciSerialPortsLocationVar.Device[i] << 3) + PciSerialPortsLocationVar.Function[i];
+ PciAddr = ((UINT32) (( (UINT16) PciSerialPortsLocationVar.Bus[i] ) << 8) + DevFunc) << 8;
+ PciAddr += (RegNum & 0xfc);
+ PciAddr |= 0x80000000;
+
+ IoWrite32(CFG_SPACE_INDEX_REG, PciAddr);
+ BarAddress = IoRead32(CFG_SPACE_DATA_REG);
+ //
+ // Reset the IER register of UART.
+ //
+ if(BarAddress & 1) {
+ IoWrite32(BarAddress, 0);
+ } else {
+ *(UINTN*)( (BarAddress & 0xfffffff0) + 1) = 0;
+ }
+ }
+ }
+ //
+ // Replace the Actual INT08h routine which was hooked by Legacy console Redirection
+ //
+ *(UINT16*)0x0020 = (UINT16)INT08h_OFFSET;
+ *(UINT16*)0x0022 = (UINT16)INT08h_SEGMENT;
+
+ IoWrite8(0x80,0x99);
+ }
+ }
+#endif
+ return;
+}
+
+//*************************************************************************
+//*************************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//*************************************************************************
+//************************************************************************* \ No newline at end of file
diff --git a/Core/EM/Terminal/TerminalBoard.h b/Core/EM/Terminal/TerminalBoard.h
new file mode 100644
index 0000000..36a78ef
--- /dev/null
+++ b/Core/EM/Terminal/TerminalBoard.h
@@ -0,0 +1,404 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/Terminal/TerminalBoard.h 4 12/08/11 6:30a Jittenkumarp $
+//
+// $Revision: 4 $
+//
+// $Date: 12/08/11 6:30a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Terminal/TerminalBoard.h $
+//
+// 4 12/08/11 6:30a Jittenkumarp
+// [TAG] EIP74239
+// [Category] New Feature
+// [Description] Added "Intel Key" ESC sequence support for Serial
+// Redirection.
+// [Files] Terminal.sdl, TerminalBoard.h
+//
+// 3 7/13/11 2:51a Rajeshms
+// [TAG]- EIP 36616
+// [Category]- New Feature
+// [Description]- Add Setup option for Various Putty keyPad support in
+// Terminal driver.
+// [Files]- Terminal.c, Terminal.h, Terminal.sd, Terminal.sdl,
+// Terminal.uni, TerminalBoard.h, TerminalSetup.c, TerminalSimpleTextIn.c
+//
+// 2 4/12/11 4:31a Rameshr
+// [TAG]- EIP 57688
+// [Category]- New Feature
+// [Description]- Add Setup option for Vt-UTF8 combo key support in
+// terminal driver
+// [Files]- Terminal.c, Terminal.h, Terminal.sd, Terminal.sdl ,
+// Terminal.uni, Terminalboard.h, TerminalSetup.c, TerminalSimpletextin.c
+//
+// 1 7/17/09 2:54p Rameshr
+// Initial check-in
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//--------------------------------------------------------------------------
+//
+// Name: TerminalBoard.h
+//
+// Description: Board file for the Terminal Module.
+//
+//--------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _TERMINAL_BOARD_H__
+#define _TERMINAL_BOARD_H__
+
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\SimpleTextInEx.h>
+#include <Protocol\AmiKeycode.h>
+
+
+#define ESC_SEQ_STATE_ARRAY_END_MARKER {0,0,0,0,0}
+#define RESET 0xFFFF
+#define ASCII_ESC 0x1B
+
+#define GLOBAL_ALL PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_SCO | PUTTY_ESCN | PUTTY_VT400
+
+
+typedef struct _STATE_DESCRIPTION STATE_DESCRIPTION;
+
+//
+// Esc Sequence defination.
+//
+struct _STATE_DESCRIPTION{
+ CHAR16 InputChar;
+ STATE_DESCRIPTION *NextEscSeqState;
+ UINT16 EfiInputKeyScanCode;
+ CHAR16 EfiInputKeyUnicodeChar;
+ UINT8 KeyPad;
+};
+
+STATE_DESCRIPTION EscSeqStateArrayEndMarker = ESC_SEQ_STATE_ARRAY_END_MARKER;
+STATE_DESCRIPTION *EscSeqStateArrayEndMarkerPtr = &EscSeqStateArrayEndMarker;
+
+STATE_DESCRIPTION PuttyLinuxEscSeq[] =
+{
+ {'A', NULL, EFI_SCAN_F1, 0, PUTTY_LINUX},
+ {'B', NULL, EFI_SCAN_F2, 0, PUTTY_LINUX},
+ {'C', NULL, EFI_SCAN_F3, 0, PUTTY_LINUX},
+ {'D', NULL, EFI_SCAN_F4, 0, PUTTY_LINUX},
+ {'E', NULL, EFI_SCAN_F5, 0, PUTTY_LINUX},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF6[] =
+{
+ {'~', NULL, EFI_SCAN_F6, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF7[] =
+{
+ {'~', NULL, EFI_SCAN_F7, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF8[] =
+{
+ {'~', NULL, EFI_SCAN_F8, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF9[] =
+{
+ {'~', NULL, EFI_SCAN_F9, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF10[] =
+{
+ {'~', NULL, EFI_SCAN_F10, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF11[] =
+{
+ {'~', NULL, EFI_SCAN_F11, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyLinuxF12[] =
+{
+ {'~', NULL, EFI_SCAN_F12, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+
+STATE_DESCRIPTION PuttyXterm86F5[] =
+{
+ {'~', NULL, EFI_SCAN_F5, 0, PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyEscNF1[] =
+{
+ {'~', NULL, EFI_SCAN_F1, 0, PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+STATE_DESCRIPTION PuttyEscNF2[] =
+{
+ {'~', NULL, EFI_SCAN_F2, 0, PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+STATE_DESCRIPTION PuttyEscNF3[] =
+{
+ {'~', NULL, EFI_SCAN_F3, 0, PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+STATE_DESCRIPTION PuttyEscNF4[] =
+{
+ {'~', NULL, EFI_SCAN_F4, 0, PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt100EscSeq1[] =
+{
+ {'~', NULL, EFI_SCAN_HOME, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN },
+ {'~', NULL, EFI_SCAN_INS, 0, PUTTY_VT400},
+ {'7', PuttyLinuxF6, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'8', PuttyLinuxF7, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'9', PuttyLinuxF8, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'5', PuttyXterm86F5, 0, 0, PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'1', PuttyEscNF1, 0, 0, PUTTY_ESCN | PUTTY_VT400},
+ {'2', PuttyEscNF2, 0, 0, PUTTY_ESCN | PUTTY_VT400},
+ {'3', PuttyEscNF3, 0, 0, PUTTY_ESCN | PUTTY_VT400},
+ {'4', PuttyEscNF4, 0, 0, PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt100EscSeq2[] =
+{
+ {'~', NULL, EFI_SCAN_INS, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN},
+ {'~', NULL, EFI_SCAN_HOME, 0, PUTTY_VT400},
+ {'0', PuttyLinuxF9, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'1', PuttyLinuxF10, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'3', PuttyLinuxF11, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ {'4', PuttyLinuxF12, 0, 0, PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt100EscSeq3[] =
+{
+ {'~', NULL, EFI_SCAN_DEL, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt100EscSeq4[] =
+{
+ {'~', NULL, EFI_SCAN_END, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt100EscSeq5[] =
+{
+ {'~', NULL, EFI_SCAN_PGUP, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt100EscSeq6[] =
+{
+ {'~', NULL, EFI_SCAN_PGDN, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt400EscSeq3[] =
+{
+ {'~', NULL, EFI_SCAN_PGUP, 0, PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt400EscSeq4[] =
+{
+ {'~', NULL, EFI_SCAN_DEL, 0, PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt400EscSeq5[] =
+{
+ {'~', NULL, EFI_SCAN_END, 0, PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION PuttyVt400EscSeq6[] =
+{
+ {'~', NULL, EFI_SCAN_PGDN, 0, PUTTY_VT400},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+
+STATE_DESCRIPTION OemEscSeqStateArray[]=
+{
+ {'P', NULL, EFI_SCAN_F1, 0, GLOBAL_ALL},
+ {'Q', NULL, EFI_SCAN_F2, 0, GLOBAL_ALL},
+ {'w', NULL, EFI_SCAN_F3, 0, GLOBAL_ALL},
+ {'x', NULL, EFI_SCAN_F4, 0, GLOBAL_ALL},
+ {'t', NULL, EFI_SCAN_F5, 0, GLOBAL_ALL},
+ {'u', NULL, EFI_SCAN_F6, 0, GLOBAL_ALL},
+ {'q', NULL, EFI_SCAN_F7, 0, GLOBAL_ALL},
+ {'r', NULL, EFI_SCAN_F8, 0, GLOBAL_ALL},
+ {'p', NULL, EFI_SCAN_F9, 0, GLOBAL_ALL},
+ {'M', NULL, EFI_SCAN_F10,0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+
+};
+
+STATE_DESCRIPTION CursorPositionEscSeqStateArray[] =
+{
+ {'C', NULL, EFI_SCAN_RIGHT, 0, GLOBAL_ALL},
+ {'D', NULL, EFI_SCAN_LEFT, 0, GLOBAL_ALL},
+ {'A', NULL, EFI_SCAN_UP, 0, GLOBAL_ALL},
+ {'B', NULL, EFI_SCAN_DN, 0, GLOBAL_ALL},
+ {'H', NULL, EFI_SCAN_HOME, 0, GLOBAL_ALL},
+ {'K', NULL, EFI_SCAN_END, 0, GLOBAL_ALL},
+ {'1', PuttyVt100EscSeq1, 0, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400 },
+ {'2', PuttyVt100EscSeq2, 0, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN | PUTTY_VT400 },
+ {'3', PuttyVt100EscSeq3, 0, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN },
+ {'4', PuttyVt100EscSeq4, 0, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN },
+ {'5', PuttyVt100EscSeq5, 0, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN },
+ {'6', PuttyVt100EscSeq6, 0, 0, PUTTY_VT100 | PUTTY_LINUX | PUTTY_XTERMR6 | PUTTY_ESCN },
+ {'3', PuttyVt400EscSeq3, 0, 0, PUTTY_VT400},
+ {'4', PuttyVt400EscSeq4, 0, 0, PUTTY_VT400},
+ {'5', PuttyVt400EscSeq5, 0, 0, PUTTY_VT400},
+ {'6', PuttyVt400EscSeq6, 0, 0, PUTTY_VT400},
+ {'[', PuttyLinuxEscSeq, 0, 0, PUTTY_LINUX},
+ {'M', NULL, EFI_SCAN_F1, 0, PUTTY_SCO},
+ {'N', NULL, EFI_SCAN_F2, 0, PUTTY_SCO},
+#if OEM_ESC_SEQUENCES
+ {'O', OemEscSeqStateArray, 0, 0, GLOBAL_ALL},
+#else
+ {'O', NULL, EFI_SCAN_F3, 0, PUTTY_SCO},
+#endif
+ {'P', NULL, EFI_SCAN_F4, 0, PUTTY_SCO},
+ {'Q', NULL, EFI_SCAN_F5, 0, PUTTY_SCO},
+ {'R', NULL, EFI_SCAN_F6, 0, PUTTY_SCO},
+ {'S', NULL, EFI_SCAN_F7, 0, PUTTY_SCO},
+ {'T', NULL, EFI_SCAN_F8, 0, PUTTY_SCO},
+ {'U', NULL, EFI_SCAN_F9, 0, PUTTY_SCO},
+ {'V', NULL, EFI_SCAN_F10, 0, PUTTY_SCO},
+ {'W', NULL, EFI_SCAN_F11, 0, PUTTY_SCO},
+ {'X', NULL, EFI_SCAN_F12, 0, PUTTY_SCO},
+ {'I', NULL, EFI_SCAN_PGUP, 0, PUTTY_SCO},
+ {'G', NULL, EFI_SCAN_PGDN, 0, PUTTY_SCO},
+ {'F', NULL, EFI_SCAN_END, 0, PUTTY_SCO},
+ {'L', NULL, EFI_SCAN_INS, 0, PUTTY_SCO},
+ {0x7F, NULL, EFI_SCAN_DEL, 0, PUTTY_SCO},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION FunctionKeyEscSeqStateArray[] =
+{
+ {'P', NULL, EFI_SCAN_F1, 0, GLOBAL_ALL},
+ {'Q', NULL, EFI_SCAN_F2, 0, GLOBAL_ALL},
+ {'R', NULL, EFI_SCAN_F3, 0, GLOBAL_ALL},
+ {'S', NULL, EFI_SCAN_F4, 0, GLOBAL_ALL},
+ {'T', NULL, EFI_SCAN_F5, 0, PUTTY_VT100},
+ {'U', NULL, EFI_SCAN_F6, 0, PUTTY_VT100},
+ {'V', NULL, EFI_SCAN_F7, 0, PUTTY_VT100},
+ {'W', NULL, EFI_SCAN_F8, 0, PUTTY_VT100},
+ {'X', NULL, EFI_SCAN_F9, 0, PUTTY_VT100},
+ {'Y', NULL, EFI_SCAN_F10, 0, PUTTY_VT100},
+ {'Z', NULL, EFI_SCAN_F11, 0, PUTTY_VT100},
+ {'[', NULL, EFI_SCAN_F12, 0, PUTTY_VT100},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+
+STATE_DESCRIPTION ResetSequenceState5[] =
+{
+ {'R', NULL, RESET, 0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION ResetSequenceState4[] =
+{
+ {ASCII_ESC, ResetSequenceState5, 0, 0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION ResetSequenceState3[] =
+{
+ {'r', ResetSequenceState4, 0, 0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION ResetSequenceState2[] =
+{
+ {ASCII_ESC, ResetSequenceState3, 0, 0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION EscSeqStateArray[] =
+{
+ {'[', CursorPositionEscSeqStateArray,
+ 0, 0, GLOBAL_ALL},
+ {'O', FunctionKeyEscSeqStateArray,
+ 0, 0, GLOBAL_ALL},
+ {'R', ResetSequenceState2,
+ 0, 0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+STATE_DESCRIPTION Vtutf8EscSeqStateArray[] =
+{
+ {'[', CursorPositionEscSeqStateArray,
+ 0, 0, GLOBAL_ALL},
+ {'O', FunctionKeyEscSeqStateArray,
+ 0, 0, GLOBAL_ALL},
+ {'h', NULL, EFI_SCAN_HOME, 0, GLOBAL_ALL},
+ {'k', NULL, EFI_SCAN_END, 0, GLOBAL_ALL},
+ {'+', NULL, EFI_SCAN_INS, 0, GLOBAL_ALL},
+ {'-', NULL, EFI_SCAN_DEL, 0, GLOBAL_ALL},
+ {'?', NULL, EFI_SCAN_PGUP, 0, GLOBAL_ALL},
+ {'/', NULL, EFI_SCAN_PGDN, 0, GLOBAL_ALL},
+ {'1', NULL, EFI_SCAN_F1, 0, GLOBAL_ALL},
+ {'2', NULL, EFI_SCAN_F2, 0, GLOBAL_ALL},
+ {'3', NULL, EFI_SCAN_F3, 0, GLOBAL_ALL},
+ {'4', NULL, EFI_SCAN_F4, 0, GLOBAL_ALL},
+ {'5', NULL, EFI_SCAN_F5, 0, GLOBAL_ALL},
+ {'6', NULL, EFI_SCAN_F6, 0, GLOBAL_ALL},
+ {'7', NULL, EFI_SCAN_F7, 0, GLOBAL_ALL},
+ {'8', NULL, EFI_SCAN_F8, 0, GLOBAL_ALL},
+ {'9', NULL, EFI_SCAN_F9, 0, GLOBAL_ALL},
+ {'0', NULL, EFI_SCAN_F10, 0, GLOBAL_ALL},
+ {'!', NULL, EFI_SCAN_F11, 0, GLOBAL_ALL},
+ {'@', NULL, EFI_SCAN_F12, 0, GLOBAL_ALL},
+ {'R', ResetSequenceState2,
+ 0, 0, GLOBAL_ALL},
+ ESC_SEQ_STATE_ARRAY_END_MARKER
+};
+
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//**************************************************************************** \ No newline at end of file
diff --git a/Core/EM/Terminal/TerminalSetup.c b/Core/EM/Terminal/TerminalSetup.c
new file mode 100644
index 0000000..312c0f1
--- /dev/null
+++ b/Core/EM/Terminal/TerminalSetup.c
@@ -0,0 +1,1788 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-20014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+// $Header: /Alaska/BIN/Modules/Terminal/TerminalSetup.c 68 5/29/14 5:20a Deepthins $
+//
+// $Revision: 68 $
+//
+// $Date: 5/29/14 5:20a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Terminal/TerminalSetup.c $
+//
+// 68 5/29/14 5:20a Deepthins
+// [TAG] EIP166561
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Runtime attribute set for the some of the variables used by
+// terminal driver.
+// [RootCause] Runtime attribute set for the some of the variables used
+// by terminal driver.
+// [Solution] Runtime attribute is removed
+// [Files] TerminalSetup.c
+//
+// 67 3/17/14 12:16a Anbuprakashp
+// [TAG] EIP156273
+// [Category] Improvement
+// [Description] Avoid Build issue happened in Non english version of
+// the OS with Serial Redirection label 4.6.3_Terminal_53
+// [Files] Terminal.sd,TerminalSetup.c
+//
+// 66 9/04/13 3:27a Anbuprakashp
+// [TAG] EIP134648
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Build error occurs in Sharkbay platform if tokens
+// "TOTAL_SIO_SERIAL_PORTS" and "TOTAL_PCI_SERIAL_PORTS" are set to 0
+// [RootCause] TerminalSetup.c file Status Variable Initialization is
+// missing.Terminal.sd file, Condition (TOTAL_SERIAL_PORTS > 0) need to be
+// added to avoid build error.
+// [Solution] Terminal.sd file, Condition (TOTAL_SERIAL_PORTS > 0) added
+// to avoid build error.
+// Status variable initialzed properly.
+// [Files] Terminal.sd,TerminalSetup.c
+//
+// 65 8/21/13 1:23a Anbuprakashp
+// [TAG] EIP131785
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Serial Redirection PCI COM port function numbers are
+// changing randomly for every reboot
+// [RootCause] COM port number and its associated PCI Function numbers
+// are
+// changing due to the funtion (ValidatePciSerialNvram) in TerminalSetup.c
+// file of the SerialRedirection module.Here, It fail to make particular
+// PCI COM port function number to Zero.
+// As it wrongly comparing device path for the PCI com port.
+//
+// [Solution] PCI serial COM port's Device Path comparing condition
+// commented.
+// [Files] TerminalSetup.c
+//
+// 64 5/27/13 6:34a Rameshr
+// [TAG] EIP121329
+// [Category] Improvement
+// [Description] Serial Mouse Detection added based on the SDL token and
+// by default kept disabled
+//
+// [Files] SerialIo.c, TerminalSetup.c , Terminal.sdl
+//
+// 63 5/02/13 9:27a Kapilporwal
+// [TAG] EIP117486
+// [Description] CppCheck error in Terminal label 4.6.3_Terminal_50
+// [Files] SerialIo.c, Terminal.c, TerminalSetup.c,
+// TerminalSimpleTextOut.c
+//
+// 62 2/11/13 3:00a Rameshr
+// [TAG] EIP113629
+// [Category] New Feature
+// [Description] Terminal driver support for ctrl+key(ASCII Control
+// Char) combinations
+// [Files] Terminal.sdl, TerminalSetup.c, TerminalSimpleTextIn.c
+//
+// 61 6/29/12 5:29a Srilathasc
+// [TAG] EIP93519
+// [Category] Improvement
+// [Description] make hardware flow control maximum re-try count as SDL
+// token.
+// [Files] Terminal.sdl, TerminalSetup.c, SerialIo.c
+//
+// 60 3/30/12 12:16a Rajeshms
+// [TAG] EIP86477
+// [Category] Improvement
+// [Description] PuttyKeyPad value is returned as non-zero(PUTTY_VT100)
+// from GetSetupValuesForTerminal() if there is any error in that
+// function.
+// [Files] TerminalSetup.c
+//
+// 59 3/29/12 11:58p Rajeshms
+// [TAG] EIP84341
+// [Category] Improvement
+// [Description] Added Separate PCI_UART_INPUT_CLOCK token for setting
+// the Clock for PCI Serial UART.
+// [Files] Terminal.sdl, TerminalSetup.c, SerialIo.c, LegacySredir.c,
+// LegacySredir_Setup.c
+//
+// 58 12/12/11 6:53a Rajeshms
+// [TAG] EIP71636
+// [Category] New Feature
+// [Description] Implement the AMI_SERIAL_PROTOCOL for non-generic PCI
+// Serial Device.
+// [Files] AmiSerial.c, AmiSerial.sdl, AmiSerial.mak, AmiSerial.chm,
+// AmiSerial.dxs, AmiSerial.cif, Terminal.c, SerialIo.c, TerminalSetup.c,
+// InitTerminalStrings.c, TerminalSetupVar.h, Terminal.cif,
+// TerminalAmiSerial.h, LegacySredir_Setup.c
+//
+// 57 11/03/11 4:47a Rameshr
+// [TAG] EIP73026
+// [Category] Improvement
+// [Description] SetNvramVariable used on line 1039, conditionally not
+// set
+// [Files] TerminalSetup.c
+//
+// 56 10/19/11 6:42a Rajeshms
+// [TAG] EIP71973
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ASCII Control characters that are used to display graphics
+// characters are not redirected to remote if Putty/teraterm application
+// is used.
+// [RootCause] Putty/Teraterm application does not use ASCII control
+// characters as Printable characters.
+// [Solution] DONT_SEND_ASCII_CONTROL_PRINTABLE_CHARACTERS token has
+// been created, if disabled it will not send the ASCII control
+// characters.
+// [Files] Terminal.sdl, TerminalSetup.c, TerminalSimpleTextOut.c
+//
+// 55 9/20/11 3:05a Rajeshms
+// [TAG] EIP70320
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] SPCR table is not created with EFI_SPECIFICATION_VERSION
+// 0x2000A
+// [RootCause] Comport was returned as 0xff from
+// GetAcpiSpcrTableValues() as the PORT number is zero indexed after
+// EFI_SPECIFICATION_VERSION 0x2000A.
+// [Solution] The comport number is not subtracted with 1 if
+// EFI_SPECIFICATION_VERSION is equal to greater than0x2000A
+// [Files] Terminal.sd, TerminalSetup.c
+//
+// 54 8/29/11 6:26a Rameshr
+// [TAG] - EIP 55335
+// [Category]- IMPROVEMENT
+// [Description]- Add optional code to clear keyboard buffer at
+// ReadyToBoot in Terminal driver
+// [Files] - Terminal.c , Terminal.h, Terminal.sdl, TerminalSetup.c
+//
+// 53 7/13/11 2:47a Rajeshms
+// [TAG]- EIP 36616
+// [Category]- New Feature
+// [Description]- Add Setup option for Various Putty keyPad support in
+// Terminal driver.
+// [Files]- Terminal.c, Terminal.h, Terminal.sd, Terminal.sdl,
+// Terminal.uni, TerminalBoard.h, TerminalSetup.c, TerminalSimpleTextIn.c
+//
+// 52 5/19/11 1:58a Rameshr
+// [TAG] - EIP 59741
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - System hangs if the Serial port doesn't work
+// [RootCause]- Serial Port says valid, but when we try to write, Terminal
+// Holding Register never gets Empty.
+// [Solution] - Added Error Count when the maximum error count reached,
+// SerialIoWrite has been stopped
+// [Files] - SerialIo.c, Terminal.sdl , TerminalSetup.c
+//
+// 51 4/29/11 5:04a Rameshr
+// [TAG] - EIP 54870
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - Legacy Console Redirection doesn't work on 2nd PCI Serial
+// Port
+// [RootCause]- Terminal creats the same Nvram variable name for all the
+// PCI Serial devices
+// [Solution] - Created seperate Nvram Variable name for each PCI serial
+// devices Ahci recovery driver shutdown code exectued only when the
+// Recovery from Ahci driver started
+// [Files] - TerminalSetup.c
+//
+// 50 4/12/11 4:31a Rameshr
+// [TAG]- EIP 57688
+// [Category]- New Feature
+// [Description]- Add Setup option for Vt-UTF8 combo key support in
+// terminal driver
+// [Files]- Terminal.c, Terminal.h, Terminal.sd, Terminal.sdl ,
+// Terminal.uni, Terminalboard.h, TerminalSetup.c, TerminalSimpletextin.c
+//
+// 49 3/02/11 3:14a Rameshr
+// [TAG]- EIP 54313
+// [Category]-IMPROVEMENT
+// [Description]- Terminal driver Getvariable calls assumed to have valid
+// values. Added code to return the error code when there is an failure in
+// the getvariable call.
+// [Files]- TerminalSetup.c, InitTerminalString.c
+//
+// 48 3/02/11 3:07a Rameshr
+// [TAG]- EIP 54526
+// [Category]-IMPROVEMENT
+// [Description]- PCI serial MMIO device width support added through SDL
+// token
+// [Files]- SerialIo.c , TerminalSetup.c , Terminal.sdl
+//
+// 47 2/07/11 12:55a Rameshr
+// [TAG] - EIP 53292
+// [Category]- BUG FIX
+// [Severity]- Minor
+// [Symptom] - CPU Exception D in Terminal when enabling more than 1
+// Serial Port.
+// [RootCause]- ComPort value is not initilized , that returns junk value
+// causing the invalid exection.
+// [Solution] - Initilized to 0xFF
+// [Files] - TerminalSetup.c
+//
+// 46 1/20/11 1:16a Lavanyap
+// [TAG] - EIP51898
+// [Category] - BUG FIX
+// [Severity] - Minor
+// [Symptom] - SDL tokens are not working in Terminal driver when Terminal
+// source module is not available in project.
+// [RootCause] - Tokens are defined in Terminal binary module and are used
+// in source module,so SDL token value changes cannot take effect when
+// source module is not present in the project.
+// [Solution] - Replaced SDL tokens used in source module with variables
+// defined in binary module.
+// [Files] - Terminal.c, TerminalSetup.c
+//
+// 45 11/29/10 11:58p Rajeshms
+// Build error resolved that caused because of previous Check-in.
+//
+// 44 11/29/10 7:28a Rajeshms
+// [TAG] - EIP 39842
+// [Category]- BUG FIX
+// [Severity]- Normal
+// [Symptom] - PCI Serial Doesn't work when we change the PCI Serial
+// device to different Slot(TOTAL_PCI_SERIAL_PORTS=1).
+// [RootCause] - NVRAM variable was not set to Zero once device was
+// removed from that slot so eventhough device(in another slot) is
+// detected its not shown in Setup.
+// [Solution] - NVRAM variable which was set previously when device was
+// present is set to ZERO if the device is not present in current slot.
+// [Files] - TerminalSetup.c
+//
+// 43 11/03/10 2:07a Rajeshms
+// [TAG] - EIP 46234
+// [Category]- BUG FIX
+// [Severity]- Normal
+// [Symptom] - If TOTAL_PCI_SERIAL_PORTS=1, the BIOS will hang in POST in
+// non-debug mode.Was reproduced in CrownBay.
+// [RootCause] - In non-debug mode terminal driver gets garbage value for
+// UINT8 ComPort; in some cases so it hangs.
+// [Solution] - UINT8 Comport is initialised to zero.
+// [Files] - TerminalSetup.c
+//
+// 42 11/02/10 4:15a Lavanyap
+// [TAG] - EIP42299
+// [Category] - IMPROVEMENT
+// [Description] - Console Redirection can support 10 COM Ports.
+// [Files] - InitTerminalStrings.c, SerialIo.c, Terminal.sd,
+// Terminal.sdl, Terminal.uni, TerminalSetup.c
+//
+// 41 10/19/10 8:35a Rajeshms
+// [TAG]- EIP 39562
+// [Category]-IMPROVEMENT
+// [Description]- Show entire PCI address of redirection device in Setup
+// [Files]- Terminal.c, TerminalSetup.c, InitTerminalStrings.c
+//
+// 40 6/01/10 12:32a Rameshr
+// Support for Baud Rate 38400 in Terminal Driver
+// EIP 38852
+//
+// 39 5/03/10 1:14a Rameshr
+// Issue:Need to handle different Base Hz values for SerialStatusCode,
+// Terminal, and Legacy Serial Redirection.
+// Solution: Moved Uart input clock into Core.sdl token and used in all
+// the above modules.
+// EIP: 37332
+//
+// 38 5/03/10 12:22a Rameshr
+// Issue:VT-UTF8 mode support for Console redirection with Debugger
+// Solution: Serial Port attribute Setup questions added for the debugger
+// console redirection port.
+// EIP 37440
+//
+// 37 4/19/10 1:44a Rameshr
+// Build problem resolved because of removing
+// DEFAULT_CONSOLE_REDIRECTION_ENABLE SDL token.
+//
+// 36 3/31/10 12:30a Rameshr
+// Recorder mode support Added.
+// EIP 34388
+//
+// 35 1/21/10 4:11p Artems
+//
+// 34 12/16/09 6:35p Artems
+//
+// 33 11/26/09 6:00a Rameshr
+// SPCR table OEMID and OEMTABLEID configured through SDL tokens.
+// EIP:26773
+//
+// 32 10/26/09 9:48a Yul
+// EIP 26401
+// Console Redirection freezes when "CTRL + R" (refresh screen) is used
+//
+// 31 10/21/09 11:28a Artems
+// EIP 25955 - fixed switching mode mechanism
+//
+// 30 10/08/09 6:02p Pats
+// EIP 23731: Need to remove SIO serial port from Console Redirection
+// Setup menu if TOTAL_SIO_SERIAL_PORTS is 0.
+// Solution: In SetSerialPortsEnabledVar_Sio(), "#if (TOTAL_SERIAL_PORTS >
+// 0)" changed to "#if (TOTAL_SIO_SERIAL_PORTS > 0)".
+//
+// 29 9/28/09 4:08p Rameshr
+// Terminal assumes UID to be started from 0. This assumption removed as
+// UID should be unique and not be started from 0.
+// EIP 17239
+//
+// 28 9/21/09 11:38a Rameshr
+// SerailIo driver to handle Pciserial device based on the SDL token
+// settings.
+// EIP 23764
+//
+// 27 9/04/09 3:55p Krishnakumarg
+// DEFAULT_DEBUGGER_CONSOLE_REDIRECTION_ENABLE token created for setting
+// default option for debugger port.
+//
+// 26 7/17/09 2:48p Rameshr
+// ESC sequence information moved from Lib to Board module.
+// Uart fifo size added as SDL token.
+// EIP 23064
+//
+// 25 7/02/09 5:01p Rameshr
+// Coding Standard and File header updated.
+//
+// 24 11/12/08 5:55p Ambikas
+//
+// 23 9/08/08 4:52p Ambikas
+//
+// 22 5/13/08 3:40p Rameshraju
+// Terminal Resolution 100 x 31 support Added
+//
+// 21 4/14/08 7:51p Ambikas
+//
+// 20 4/14/08 7:42p Ambikas
+//
+// 19 4/14/08 4:52p Ambikas
+//
+// 18 4/14/08 4:46p Ambikas
+//
+// 17 11/07/07 4:53p Ambikas
+// We have reverted to the version of VfrCompile which uses 1 based
+// arrays.
+// Array indeces have been changed accordingly.
+//
+// 16 10/11/07 7:42a Ambikas
+//
+// 15 6/12/07 3:58p Ambikas
+//
+// 14 6/11/07 11:36a Ambikas
+//
+// 13 6/10/07 6:02p Ambikas
+//
+// 12 6/06/07 7:52p Ambikas
+// We now save the pci device path of pci serial port rather than segment
+// and bus numbers.
+//
+// 11 6/05/07 6:26p Ambikas
+//
+// 10 6/05/07 11:55a Ambikas
+//
+// 9 6/4/2007 7:34p Ambikas
+//
+// 8 6/4/2007 7:30p Ambikas
+// If TOTAL_SERIAL_PORTS is 0, then the setup data structures for the
+// serial ports in Terminal.sd will not be defined. So, we comment out
+// code which references those data structures and just return default
+// values.
+//
+// 7 5/30/2007 12:18p Ambikas
+//
+// 6 5/29/2007 8:35p Ambikas
+//
+// 5 5/24/2007 2:33p Ambikas
+//
+// 4 8/24/2006 7:07p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 3 8/24/2006 3:34p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 2 5/05/2006 5:35p Ambikas
+//
+// 1 11/11/2005 2:07p Ambikas
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TerminalSetup.c
+//
+// Description: This file contains functions used by
+// Terminal.lib/Terminalx64.lib to get Terminal/Serial
+// related setup values.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+
+#include <Protocol\SerialIo.h> //for SERIAL_IO_MODE
+#include <Token.h> //for sdl tokens
+#include <AmiDxeLib.h> //for pRS
+#include "TerminalBoard.h"
+
+#include <Protocol\SerialIo.h>
+#include <Setup.h>
+#include "TerminalSetupVar.h"
+#include <protocol\PciRootBridgeIo.h>
+#include <Pci.h>
+
+#define PCI_CFG_ADDRESS(bus,dev,func,reg) \
+ ((UINT64)((((UINTN)bus) << 24) + (((UINTN)dev) << 16) + (((UINTN)func) << 8) + ((UINTN)reg)))& 0x00000000ffffffff
+
+#define HARDWARE_LOOPBACK 1
+#define SOFTWARE_LOOPBACK 2
+
+#ifdef UART_INPUT_CLOCK
+UINTN SioUartInputClock = UART_INPUT_CLOCK;
+#else
+//
+// Set the default value((24000000/13)MHz input clock) if the UART_INPUT_CLOCK SDL token is not present.
+//
+UINTN SioUartInputClock=1843200;
+#endif
+
+UINTN PciUartInputClock = PCI_UART_INPUT_CLOCK;
+
+//for serial io defaults
+UINT32 UartDefaultBaudRate = UART_DEFAULT_BAUD_RATE;
+EFI_PARITY_TYPE UartDefaultParity = UART_DEFAULT_PARITY;
+UINT8 UartDefaultDataBits = UART_DEFAULT_DATA_BITS;
+EFI_STOP_BITS_TYPE UartDefaultStopBits = UART_DEFAULT_STOP_BITS;
+UINT8 SerialIo_PciSerialSupport = SERIALIO_PCI_SERIAL_SUPPORT;
+BOOLEAN ValidateNvram = FALSE;
+
+UINT32 TimeoutForDeterminingLoneEscChar =
+ TIMEOUT_FOR_DETERMINING_LONE_ESC_CHAR;
+
+UINT32 EscSequenceCheckingIntervel =
+ (TIMEOUT_FOR_DETERMINING_LONE_ESC_CHAR/NUMBER_OF_TIME_FOR_ESC_SEQUENCE_CHECKING);
+
+CHAR16 RefreshScreenKey = REFRESH_SCREEN_KEY;
+UINT8 SPCR_OEM_ID[6] = CONVERT_TO_STRING(SPCR_ACPI_OEM_ID);
+UINT8 SPCR_OEM_TBL_ID[8] = CONVERT_TO_STRING(SPCR_ACPI_OEM_TBL_ID);
+UINT32 gTotalSioSerialPorts = TOTAL_SIO_SERIAL_PORTS;
+UINT32 gTotalPciSerialPorts = TOTAL_PCI_SERIAL_PORTS;
+UINTN TotalTerminalDev=TOTAL_SERIAL_PORTS;
+UINT32 Uart_Fifo_Size=UART_FIFO_SIZE;
+UINT8 PciComMmioWidth=PCI_SERIAL_MMIO_WIDTH;
+UINT8 MaxFailuresAllowed = MAX_FAILURES_ALLOWED;
+UINT32 MaximumSerialWriteErrorCount = MAXIMUM_SERIAL_WRITE_ERROR_COUNT;
+BOOLEAN SerialWriteErrorCheck= SERIAL_WRITE_ERROR_CHECK;
+BOOLEAN ClearTerminalKBBufferReadyToBoot= CLEAR_TERMINAL_KB_BUFFER_AT_READYTOBOOT;
+BOOLEAN ASCIIControlCodeSupport= ASCII_CONTROL_CODE_SUPPORT;
+BOOLEAN SerialMouseDetection=SERIAL_MOUSE_DETECTION;
+
+
+EFI_GUID gTerminalVarGuid = TERMINAL_VAR_GUID;
+EFI_GUID gSetupGuid = SETUP_GUID;
+EFI_GUID gDebuggerTerminalVarGuid = DEBUGGER_TERMINAL_VAR_GUID;
+EFI_GUID gEfiPciRootBridgeIoProtocolGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
+
+UINT64 gAcpiSpcrTableComBaudRates[8] =
+ {0, 0, 0, 9600, 19200, 38400, 57600, 115200};
+
+CHAR16 *gPciSerialPortsDevicePathVarName[MAX_PCI_SERIAL_PORTS];
+
+SETUP_DATA gSetupData;
+
+//Terminal Driver global variables for SDL tokens.
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: Dont_Send_Ascii_Control_Printable_Characters
+//
+// Description: Variable to replace DONT_SEND_ASCII_CONTROL_PRINTABLE_CHARACTERS.
+// token.
+// Notes: BOOLEAN
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+BOOLEAN Dont_Send_Ascii_Control_Printable_Characters =
+#ifdef DONT_SEND_ASCII_CONTROL_PRINTABLE_CHARACTERS
+ DONT_SEND_ASCII_CONTROL_PRINTABLE_CHARACTERS
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrInterfaceType
+//
+// Description: Variable to replace spcr_interface_type token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrInterfaceType =
+#ifdef spcr_interface_type
+ spcr_interface_type
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrAddrSpcId
+//
+// Description: Variable to replace spcr_addr_spc_id token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrAddrSpcId =
+#ifdef spcr_addr_spc_id
+ spcr_addr_spc_id
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrAddrBitWidth
+//
+// Description: Variable to replace spcr_addr_bit_width token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrAddrBitWidth =
+#ifdef spcr_addr_bit_width
+ spcr_addr_bit_width
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrAddrBitOffset
+//
+// Description: Variable to replace spcr_addr_bit_offset token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrAddrBitOffset =
+#ifdef spcr_addr_bit_offset
+ spcr_addr_bit_offset
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrAccessSize
+//
+// Description: Variable to replace spcr_access_size token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrAccessSize =
+#ifdef spcr_access_size
+ spcr_access_size
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrInterruptType
+//
+// Description: Variable to replace spcr_interrupt_type token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrInterruptType =
+#ifdef spcr_interrupt_type
+ spcr_interrupt_type
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrGlobalSystemInit
+//
+// Description: Variable to replace spcr_global_system_int token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrGlobalSystemInit =
+#ifdef spcr_global_system_int
+ spcr_global_system_int
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrParity
+//
+// Description: Variable to replace spcr_parity token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrParity =
+#ifdef spcr_parity
+ spcr_parity
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrStopBits
+//
+// Description: Variable to replace spcr_stop_bits token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrStopBits =
+#ifdef spcr_stop_bits
+ spcr_stop_bits
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciDeviceId
+//
+// Description: Variable to replace spcr_pci_device_id token.
+//
+// Notes: UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT16 SpcrPciDeviceId =
+#ifdef spcr_pci_device_id
+ spcr_pci_device_id
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciVendorId
+//
+// Description: Variable to replace spcr_pci_vendor_id token.
+//
+// Notes: UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT16 SpcrPciVendorId =
+#ifdef spcr_pci_vendor_id
+ spcr_pci_vendor_id
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciBusNumber
+//
+// Description: Variable to replace spcr_pci_bus_number token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrPciBusNumber =
+#ifdef spcr_pci_bus_number
+ spcr_pci_bus_number
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciDeviceNumber
+//
+// Description: Variable to replace spcr_interface_type token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrPciDeviceNumber =
+#ifdef spcr_pci_device_number
+ spcr_pci_device_number
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciFunctionNumber
+//
+// Description: Variable to replace spcr_pci_function_number token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrPciFunctionNumber =
+#ifdef spcr_pci_function_number
+ spcr_pci_function_number
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciFlags
+//
+// Description: Variable to replace spcr_pci_flags token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrPciFlags =
+#ifdef spcr_pci_flags
+ spcr_pci_flags
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: SpcrPciSegment
+//
+// Description: Variable to replace spcr_pci_segment token.
+//
+// Notes: UINT8
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 SpcrPciSegment =
+#ifdef spcr_pci_segment
+ spcr_pci_segment
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: AcpiOemRev
+//
+// Description: Variable to replace ACPI_OEM_REV token.
+//
+// Notes: UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT64 AcpiOemRev =
+#ifdef ACPI_OEM_REV
+ ACPI_OEM_REV
+#else
+ 0
+#endif
+ ;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: CoreRevision
+//
+// Description: Variable to replace CORE_REVISION token.
+//
+// Notes: UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+UINT8 CoreRevision =
+#ifdef CORE_REVISION
+ CORE_REVISION
+#else
+ 0
+#endif
+ ;
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: InitSerialPortsEnabledVar
+//
+// Input: VOID
+//
+// Output: VOID
+//
+// Description: Initializes the variables SERIAL_PORTS_ENABLED_VAR and
+// PCI_SERIAL_PORTS_LOCATION_VAR.
+// SERIAL_PORTS_ENABLED_VAR keeps track of which serial ports
+// (both SuperIO and PCI) are enabled.
+// PCI_SERIAL_PORTS_LOCATION_VAR keeps contains location
+// information about the pci serial ports (device and function
+// numbers).
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID InitSerialPortsEnabledVar(VOID)
+{
+ UINTN DebuggerSerialPortsEnabledVarSize = sizeof(DEBUGGER_SERIAL_PORTS_ENABLED_VAR);
+ DEBUGGER_SERIAL_PORTS_ENABLED_VAR DebuggerSerialPortsEnabledVar;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if (TOTAL_SERIAL_PORTS > 0)
+
+ UINTN SerialPortsEnabledVarSize = sizeof(SERIAL_PORTS_ENABLED_VAR);
+ SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar;
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ UINTN PciSerialPortsLocationVarSize =
+ sizeof(PCI_SERIAL_PORTS_LOCATION_VAR);
+ PCI_SERIAL_PORTS_LOCATION_VAR PciSerialPortsLocationVar;
+#endif
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+ UINTN SioSerialPortsLocationVarSize =
+ sizeof(SIO_SERIAL_PORTS_LOCATION_VAR);
+ SIO_SERIAL_PORTS_LOCATION_VAR SioSerialPortsLocationVar;
+#endif
+
+ pBS->SetMem(&SerialPortsEnabledVar,
+ sizeof(SERIAL_PORTS_ENABLED_VAR),
+ 0);
+ Status = pRS->SetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+ Status = pRS->GetVariable(SIO_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ NULL,
+ &SioSerialPortsLocationVarSize,
+ &SioSerialPortsLocationVar);
+ if (EFI_ERROR(Status)) {
+ pBS->SetMem(&SioSerialPortsLocationVar,
+ sizeof(SIO_SERIAL_PORTS_LOCATION_VAR),
+ 0);
+ Status = pRS->SetVariable(SIO_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ SioSerialPortsLocationVarSize,
+ &SioSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ Status = pRS->GetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ NULL,
+ &PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+ if (EFI_ERROR(Status)) {
+ pBS->SetMem(&PciSerialPortsLocationVar,
+ sizeof(PCI_SERIAL_PORTS_LOCATION_VAR),
+ 0);
+ Status = pRS->SetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+#endif
+ //
+ // Initilize the Amidebugger Serial Port variables.
+ //
+ pBS->SetMem(&DebuggerSerialPortsEnabledVar,
+ sizeof(DEBUGGER_SERIAL_PORTS_ENABLED_VAR),
+ 0);
+ Status = pRS->SetVariable(DEBUGGER_SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gDebuggerTerminalVarGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DebuggerSerialPortsEnabledVarSize,
+ &DebuggerSerialPortsEnabledVar);
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SetSerialPortsEnabledVar_Sio
+//
+// Input: IN UINT8 Port
+//
+// Output: VOID
+//
+// Description: Sets SERIAL_PORTS_ENABLED_VAR[Port] to 1.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+UINT8 SetSerialPortsEnabledVar_Sio(IN UINT8 Uid)
+{
+ UINTN DebuggerSerialPortsEnabledVarSize = sizeof(DEBUGGER_SERIAL_PORTS_ENABLED_VAR);
+ UINT32 DebuggerSerialPortsEnabledVarAttributes=0;
+ DEBUGGER_SERIAL_PORTS_ENABLED_VAR DebuggerSerialPortsEnabledVar;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if(Uid == 0xFF) {
+
+ //
+ // Handle the Serial Port that is coming from Ami debugger
+ //
+ Status = pRS->GetVariable(DEBUGGER_SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gDebuggerTerminalVarGuid,
+ &DebuggerSerialPortsEnabledVarAttributes,
+ &DebuggerSerialPortsEnabledVarSize,
+ &DebuggerSerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Port Present Status.
+ //
+ DebuggerSerialPortsEnabledVar.PortEnabled=1;
+
+ Status = pRS->SetVariable(DEBUGGER_SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gDebuggerTerminalVarGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ DebuggerSerialPortsEnabledVarSize,
+ &DebuggerSerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+ //
+ // Return 0xFF, so that it's known as this serial port is coming
+ // from AmiDebugger
+ //
+ return 0xFF;
+ }
+
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+{
+
+ UINTN SerialPortsEnabledVarSize = sizeof(SERIAL_PORTS_ENABLED_VAR);
+ UINT32 SerialPortsEnabledVarAttributes=0;
+ SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar;
+
+ UINTN SioSerialPortsLocationVarSize =
+ sizeof(SIO_SERIAL_PORTS_LOCATION_VAR);
+ UINT32 SioSerialPortsLocationVarAttributes=0;
+ SIO_SERIAL_PORTS_LOCATION_VAR SioSerialPortsLocationVar;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 i = 0;
+ UINT8 ComPort = 0xFF;
+
+ Status = pRS->GetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &SerialPortsEnabledVarAttributes,
+ &SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+
+ if(EFI_ERROR(Status)) {
+ return 0xFF;
+ }
+
+ Status = pRS->GetVariable(SIO_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &SioSerialPortsLocationVarAttributes,
+ &SioSerialPortsLocationVarSize,
+ &SioSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+
+ if(EFI_ERROR(Status)) {
+ return 0xFF;
+ }
+
+ for (i = 0; i < TOTAL_SIO_SERIAL_PORTS; i++) {
+ if ((SioSerialPortsLocationVar.PortUid[i] == Uid ) &&
+ (SioSerialPortsLocationVar.Valid[i] == 0xFF)) {
+ SerialPortsEnabledVar.PortsEnabled[i] = 1;
+ ComPort = i;
+ break;
+ }
+ }
+
+ if (i == TOTAL_SIO_SERIAL_PORTS) {
+ for (i = 0; i < TOTAL_SIO_SERIAL_PORTS; i++) {
+ if ((!SerialPortsEnabledVar.PortsEnabled[i]) &&
+ (SioSerialPortsLocationVar.Valid[i] == 0)) {
+
+ SerialPortsEnabledVar.PortsEnabled[i] = 1;
+ ComPort = i;
+
+ SioSerialPortsLocationVar.PortUid[i] = Uid;
+ SioSerialPortsLocationVar.Valid[i] = 0xFF;
+
+ Status = pRS->SetVariable(
+ SIO_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ SioSerialPortsLocationVarSize,
+ &SioSerialPortsLocationVar);
+
+ ASSERT_EFI_ERROR(Status);
+ break;
+ }
+ }
+ }
+
+ Status = pRS->SetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+
+ return ComPort;
+}
+#else
+
+ return 0xFF;
+
+#endif
+}
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: ValidatePciSerialNvram
+//
+// Input: IN SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar,
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+//
+// Output: EFI_STATUS
+//
+// Description: Checks for the Presence of PCI Serial device with values
+// present in the NVRAM Variable PciSerialPortsLocationVar.
+// If found donot change NVRAM variable.If not found delete
+// the NVRAM variable describing the device path and make
+// current PciSerialPortsLocationVar.Bus[i],Device[i] and
+// function[i] to zero.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+EFI_STATUS ValidatePciSerialNvram(
+ IN SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar,
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ UINT64 PciAddress;
+ UINT8 RevisionId[4];
+ UINT8 SetNvramVariable=0;
+ UINT8 i = 0;
+ EFI_STATUS Status;
+
+ UINTN PciSerialPortsLocationVarSize = sizeof(PCI_SERIAL_PORTS_LOCATION_VAR);
+ UINT32 PciSerialPortsLocationVarAttributes=0;
+ PCI_SERIAL_PORTS_LOCATION_VAR PciSerialPortsLocationVar;
+
+ UINTN PciSerialPortDevicePathVarSize = 0;
+ UINT32 PciSerialPortDevicePathVarAttributes = 0;
+ EFI_DEVICE_PATH_PROTOCOL *PciSerialPortDevicePathVar = NULL;
+
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *gPciRootBridgeIo=NULL;
+
+ if (ValidateNvram == TRUE) {
+ return EFI_SUCCESS;
+ }
+
+ Status = pBS->LocateProtocol( &gEfiPciRootBridgeIoProtocolGuid,
+ NULL,
+ &gPciRootBridgeIo );
+
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ ValidateNvram = TRUE;
+ Status = pRS->GetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &PciSerialPortsLocationVarAttributes,
+ &PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar );
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ for (i = 0; i < TOTAL_PCI_SERIAL_PORTS; i++) {
+ if (!SerialPortsEnabledVar.PortsEnabled[gTotalSioSerialPorts+i]) {
+ if ((PciSerialPortsLocationVar.Bus[i] == 0) &&
+ (PciSerialPortsLocationVar.Device[i] == 0) &&
+ (PciSerialPortsLocationVar.Function[i] == 0)) {
+ continue;
+ }
+
+ PciAddress = PCI_CFG_ADDRESS (PciSerialPortsLocationVar.Bus[i],
+ PciSerialPortsLocationVar.Device[i],
+ PciSerialPortsLocationVar.Function[i],
+ PCI_REV_ID_OFFSET
+ );
+ //
+ //Get the Class Code
+ //
+ Status = gPciRootBridgeIo->Pci.Read(
+ gPciRootBridgeIo,
+ EfiPciWidthUint32,
+ PciAddress,
+ 1,
+ &RevisionId);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = GetEfiVariable(gPciSerialPortsDevicePathVarName[i],
+ &gTerminalVarGuid,
+ &PciSerialPortDevicePathVarAttributes,
+ &PciSerialPortDevicePathVarSize,
+ &PciSerialPortDevicePathVar);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ //Check for the presence of the PCI Serial device
+ //
+ if ((RevisionId[3] == PCI_CL_COMM) &&
+ ((RevisionId[2] == PCI_CL_COMM_CSL_SERIAL) ||
+ (RevisionId[2] == PCI_CL_COMM_CSL_OTHER)) ) {
+ continue;
+ }
+
+ //
+ //Its not PCI serial Device,So delete NVRAM variable describing device path of the device.
+ //
+ SetNvramVariable = 1;
+ Status = pRS->SetVariable(gPciSerialPortsDevicePathVarName[i],
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ NULL,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ //
+ //Initialise Bus,Dev,func. to Zero and set variable to represent that device is not present.
+ //
+ PciSerialPortsLocationVar.Bus[i] = 0;
+ PciSerialPortsLocationVar.Device[i] = 0;
+ PciSerialPortsLocationVar.Function[i] = 0;
+ }
+ }
+ if (SetNvramVariable == 1) {
+ Status = pRS->SetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+ }
+ return EFI_SUCCESS;
+}
+#endif
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: SetSerialPortsEnabledVar_Pci
+//
+// Input:
+// IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+// IN UINT8 Device
+// IN UINT8 Function
+//
+// Output: the assigned com port number
+// UINT8
+//
+// Description: Keeping track of which pci serial ports are enabled
+// a bit complicated.
+// Unlike the SuperIO serial ports, pci serial ports do not
+// have UIDs.
+// We distinguish them by their locations.
+// For each pci serial port, we store the entire device
+// path under the variable names in
+// gPciSerialPortsDevicePathVarName ("COM5," "COM6", etc).
+// We check the parameter "DevicePath" against our stored
+// device paths.
+// If it matches, we return the com port number of that
+// device path.
+// If it doesn't match, we use a new entry in
+// SERIAL_PORTS_ENABLED_VAR for the pci serial port.
+// We also use a new entry in PCI_SERIAL_PORTS_LOCATION_VAR
+// and store the device and function numbers.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+UINT8 SetSerialPortsEnabledVar_Pci(
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINT8 Bus,
+ IN UINT8 Device,
+ IN UINT8 Function,
+ IN UINT8 Port,
+ IN BOOLEAN AmiPciSerialDetected)
+{
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ UINTN SerialPortsEnabledVarSize = sizeof(SERIAL_PORTS_ENABLED_VAR);
+ UINT32 SerialPortsEnabledVarAttributes=0;
+ SERIAL_PORTS_ENABLED_VAR SerialPortsEnabledVar;
+
+ UINTN PciSerialPortsLocationVarSize =
+ sizeof(PCI_SERIAL_PORTS_LOCATION_VAR);
+ UINT32 PciSerialPortsLocationVarAttributes=0;
+ PCI_SERIAL_PORTS_LOCATION_VAR PciSerialPortsLocationVar;
+
+ UINTN PciSerialPortDevicePathVarSize = 0;
+ UINT32 PciSerialPortDevicePathVarAttributes = 0;
+ EFI_DEVICE_PATH_PROTOCOL *PciSerialPortDevicePathVar = NULL;
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 i = 0;
+ UINT8 ComPort=0xFF;
+ CHAR16 PciSerialPortName[TOTAL_PCI_SERIAL_PORTS][6];
+
+ for ( i = 0; i < TOTAL_PCI_SERIAL_PORTS; i++) {
+ Swprintf(PciSerialPortName[i], L"COM%x", gTotalSioSerialPorts+i);
+ gPciSerialPortsDevicePathVarName[i] = PciSerialPortName[i];
+ }
+
+ Status = pRS->GetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &SerialPortsEnabledVarAttributes,
+ &SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+
+ if(EFI_ERROR(Status)) {
+ return 0xFF;
+ }
+
+ Status = ValidatePciSerialNvram(SerialPortsEnabledVar,DevicePath);
+
+ if (EFI_ERROR(Status)) {
+ return 0xFF;
+ }
+
+ Status = pRS->GetVariable(PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ &PciSerialPortsLocationVarAttributes,
+ &PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+
+ if(EFI_ERROR(Status)) {
+ return 0xFF;
+ }
+
+ for (i = 0; i < TOTAL_PCI_SERIAL_PORTS; i++) {
+ if ((PciSerialPortsLocationVar.Device[i] == Device) &&
+ (PciSerialPortsLocationVar.Function[i] == Function)) {
+ Status = GetEfiVariable(gPciSerialPortsDevicePathVarName[i],
+ &gTerminalVarGuid,
+ &PciSerialPortDevicePathVarAttributes,
+ &PciSerialPortDevicePathVarSize,
+ &PciSerialPortDevicePathVar);
+ if (!EFI_ERROR(Status)) {
+ if (!DPCmp(DevicePath, PciSerialPortDevicePathVar)) {
+ SerialPortsEnabledVar.PortsEnabled[gTotalSioSerialPorts+i] = 1;
+ ComPort = gTotalSioSerialPorts+i;
+ break;
+ }
+ }
+ }
+ }
+
+ if (i == TOTAL_PCI_SERIAL_PORTS) {
+ for (i = 0; i < TOTAL_PCI_SERIAL_PORTS; i++) {
+ if ((!SerialPortsEnabledVar.PortsEnabled[gTotalSioSerialPorts+i]) &&
+ (PciSerialPortsLocationVar.Device[i] == 0) &&
+ (PciSerialPortsLocationVar.Function[i] == 0)) {
+ Status = GetEfiVariable(
+ gPciSerialPortsDevicePathVarName[i],
+ &gTerminalVarGuid,
+ &PciSerialPortDevicePathVarAttributes,
+ &PciSerialPortDevicePathVarSize,
+ &PciSerialPortDevicePathVar);
+ if (Status == EFI_NOT_FOUND) {
+ SerialPortsEnabledVar.PortsEnabled[gTotalSioSerialPorts+i] = 1;
+ ComPort = gTotalSioSerialPorts+i;
+
+ PciSerialPortDevicePathVarSize = DPLength(DevicePath);
+ Status = pRS->SetVariable(
+ gPciSerialPortsDevicePathVarName[i],
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ PciSerialPortDevicePathVarSize,
+ DevicePath);
+ ASSERT_EFI_ERROR(Status);
+
+ PciSerialPortsLocationVar.Bus[i] = Bus;
+ PciSerialPortsLocationVar.Device[i] = Device;
+ PciSerialPortsLocationVar.Function[i] = Function;
+ if(AmiPciSerialDetected) {
+ PciSerialPortsLocationVar.AmiPciSerialPresent[i] = TRUE;
+ PciSerialPortsLocationVar.Port[i] = Port;
+ }
+
+ Status = pRS->SetVariable(
+ PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME,
+ &gTerminalVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS |
+ EFI_VARIABLE_NON_VOLATILE),
+ PciSerialPortsLocationVarSize,
+ &PciSerialPortsLocationVar);
+ ASSERT_EFI_ERROR(Status);
+
+ break;
+ }
+ }
+ }
+ }
+
+ Status = pRS->SetVariable(SERIAL_PORTS_ENABLED_VAR_C_NAME,
+ &gTerminalVarGuid,
+ EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ SerialPortsEnabledVarSize,
+ &SerialPortsEnabledVar);
+ ASSERT_EFI_ERROR(Status);
+
+ return ComPort;
+
+#else
+
+ return 0xFF;
+
+#endif
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetSetupValuesForSerialIoMode
+//
+// Input:
+// IN UINT8 Port
+// IN OUT SERIAL_IO_MODE *SerialIoMode
+//
+// Output: VOID
+//
+// Description: Returns the user configured SERIAL_IO_MODE values.
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID GetSetupValuesForSerialIoMode(
+ IN UINT8 Port,
+ IN OUT SERIAL_IO_MODE *SerialIoMode)
+{
+ UINT32 SetupDataAttributes = 0;
+ UINTN SetupDataVarSize = sizeof(SETUP_DATA);
+
+ UINT8 LoopbackEnable = 0;
+ UINT8 FlowControl = 0;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if (TOTAL_SERIAL_PORTS == 0)
+
+ LoopbackEnable = UART_DEFAULT_LOOPBACK_ENABLE;
+ FlowControl = UART_DEFAULT_FLOW_CONTROL;
+ SerialIoMode->BaudRate =
+ gAcpiSpcrTableComBaudRates[UART_DEFAULT_BAUD_RATE_INDEX];
+ SerialIoMode->Parity = UART_DEFAULT_PARITY;
+ SerialIoMode->DataBits = UART_DEFAULT_DATA_BITS;
+ SerialIoMode->StopBits = UART_DEFAULT_STOP_BITS;
+
+#else
+
+ Status = pRS->GetVariable(L"Setup", &gSetupGuid, &SetupDataAttributes,
+ &SetupDataVarSize, &gSetupData);
+
+ if (EFI_ERROR(Status)) {
+ LoopbackEnable = UART_DEFAULT_LOOPBACK_ENABLE;
+ FlowControl = UART_DEFAULT_FLOW_CONTROL;
+ SerialIoMode->BaudRate =
+ gAcpiSpcrTableComBaudRates[UART_DEFAULT_BAUD_RATE_INDEX];
+ SerialIoMode->Parity = UART_DEFAULT_PARITY;
+ SerialIoMode->DataBits = UART_DEFAULT_DATA_BITS;
+ SerialIoMode->StopBits = UART_DEFAULT_STOP_BITS;
+ } else {
+ LoopbackEnable = gSetupData.LoopbackEnable[Port];
+ FlowControl = gSetupData.FlowControl[Port];
+ SerialIoMode->BaudRate =
+ gAcpiSpcrTableComBaudRates[gSetupData.BaudRate[Port]];
+ SerialIoMode->Parity = gSetupData.Parity[Port];
+ SerialIoMode->DataBits = gSetupData.DataBits[Port];
+ SerialIoMode->StopBits = gSetupData.StopBits[Port];
+ }
+
+#endif
+
+ SerialIoMode->ControlMask = 0;
+ if (FlowControl == HARDWARE_FLOW_CONTROL_SETUP_OPTION)
+ SerialIoMode->ControlMask |= EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE;
+ else if (FlowControl == SOFTWARE_FLOW_CONTROL_SETUP_OPTION)
+ SerialIoMode->ControlMask |= EFI_SERIAL_SOFTWARE_FLOW_CONTROL_ENABLE;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetDefaultConsoleRedirectionStatus
+//
+// Description: Returns the default settings of the ConsoleRedirection
+// enable status
+//
+// Input: IN UINT8 Port
+//
+// Output: OUT UINT8 RedirectionStatus
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+UINT8 GetDefaultConsoleRedirectionStatus(
+ IN UINT8 Port
+)
+{
+ switch (Port) {
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+ case 0:
+ return COM0_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 1)
+ case 1:
+ return COM1_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 2)
+ case 2:
+ return COM2_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 3)
+ case 3:
+ return COM3_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 4)
+ case 4:
+ return COM4_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 5)
+ case 5:
+ return COM5_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 6)
+ case 6:
+ return COM6_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 7)
+ case 7:
+ return COM7_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 8)
+ case 8:
+ return COM8_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 9)
+ case 9:
+ return COM9_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+ case (TOTAL_SIO_SERIAL_PORTS):
+ return PCI0_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 1)
+ case (TOTAL_SIO_SERIAL_PORTS+1):
+ return PCI1_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 2)
+ case (TOTAL_SIO_SERIAL_PORTS+2):
+ return PCI2_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 3)
+ case (TOTAL_SIO_SERIAL_PORTS+3):
+ return PCI3_DEFAULT_CONSOLE_REDIRECTION_ENABLE;
+#endif
+
+ }
+
+ return 0;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetSetupValuesForTerminal
+//
+// Input:
+// IN UINT8 Port
+// IN OUT UINT8 *ConsoleRedirectionEnable
+// IN OUT UINT8 *TerminalType
+// IN OUT BOOLEAN *SupportExRes
+// IN OUT BOOLEAN *RecorderMode,
+// IN OUT UINT8 *Disable_Terminal_For_SCT_Test
+//
+// Output: VOID
+//
+// Description: Returns the Setup setttings for the terminal
+// (whether redirection is enabled and the terminal type).
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID GetSetupValuesForTerminal(
+ IN UINT8 Port,
+ IN OUT UINT8 *ConsoleRedirectionEnable,
+ IN OUT UINT8 *TerminalType,
+ IN OUT BOOLEAN *SupportExRes,
+ IN OUT BOOLEAN *VtUtf8,
+ IN OUT BOOLEAN *RecorderMode,
+ IN OUT BOOLEAN *PuttyKeyPad,
+ IN OUT UINT8 *Disable_Terminal_For_SCT_Test)
+{
+ UINT32 SetupDataAttributes = 0;
+ UINTN SetupDataSize = sizeof(SETUP_DATA);
+
+ EFI_STATUS Status ;
+
+ *Disable_Terminal_For_SCT_Test = DISABLE_TERMINAL_FOR_SCT_TEST;
+
+ Status = pRS->GetVariable(L"Setup", &gSetupGuid, &SetupDataAttributes,
+ &SetupDataSize, &gSetupData);
+
+ if(Port == (UINT8)-1){
+ //
+ // If the redirection comes Via Ami debugger
+ //
+#ifdef CONSOLE_REDIRECTION_SUPPORT
+#if CONSOLE_REDIRECTION_SUPPORT == 1
+ if(EFI_ERROR(Status)) {
+ //
+ // If the Setup Variable is not Found Return the Default values
+ //
+ *ConsoleRedirectionEnable = DEFAULT_DEBUGGER_CONSOLE_REDIRECTION_ENABLE;
+ *TerminalType = DEFAULT_TERMINAL_TYPE;
+ *SupportExRes = FALSE;
+ *VtUtf8 = VTUTF8_ENABLE;
+ *RecorderMode = FALSE;
+ *PuttyKeyPad = PUTTY_VT100;
+ } else {
+ //
+ // Setup Values Found for the Debugger Serial port.
+ //
+ *ConsoleRedirectionEnable=gSetupData.DebuggerConsoleRedirectionEnable;
+ *TerminalType = gSetupData.DebuggerTerminalType;
+ *SupportExRes = FALSE;
+ *VtUtf8 = VTUTF8_ENABLE;
+ *RecorderMode = FALSE;
+ *PuttyKeyPad = PUTTY_VT100;
+ }
+#else
+ //
+ // CONSOLE_REDIRECTION_SUPPORT token is defined in Amidebugger module.
+ // But if this token is disabled, return the default values.
+ //
+ *ConsoleRedirectionEnable = DEFAULT_DEBUGGER_CONSOLE_REDIRECTION_ENABLE;
+ *TerminalType = DEFAULT_TERMINAL_TYPE;
+ *SupportExRes = FALSE;
+ *VtUtf8 = VTUTF8_ENABLE;
+ *RecorderMode = FALSE;
+ *PuttyKeyPad = PUTTY_VT100;
+#endif
+#else
+ //
+ // CONSOLE_REDIRECTION_SUPPORT token is defined in Amidebugger module.
+ // If this token is not present, return the default values.
+ //
+ *ConsoleRedirectionEnable = DEFAULT_DEBUGGER_CONSOLE_REDIRECTION_ENABLE;
+ *TerminalType = DEFAULT_TERMINAL_TYPE;
+ *SupportExRes = FALSE;
+ *VtUtf8 = VTUTF8_ENABLE;
+ *RecorderMode = FALSE;
+ *PuttyKeyPad = PUTTY_VT100;
+
+#endif
+
+ return;
+ }
+
+#if (TOTAL_SERIAL_PORTS == 0)
+
+ *ConsoleRedirectionEnable = GetDefaultConsoleRedirectionStatus(Port);
+ *TerminalType = DEFAULT_TERMINAL_TYPE;
+ *SupportExRes = FALSE;
+ *VtUtf8 = VTUTF8_ENABLE;
+ *RecorderMode = FALSE;
+ *PuttyKeyPad = PUTTY_VT100;
+
+#else
+ if (EFI_ERROR(Status)) {
+ *ConsoleRedirectionEnable = GetDefaultConsoleRedirectionStatus(Port);
+ *TerminalType = DEFAULT_TERMINAL_TYPE;
+ *SupportExRes = FALSE;
+ *VtUtf8 = VTUTF8_ENABLE;
+ *RecorderMode = FALSE;
+ *PuttyKeyPad = PUTTY_VT100;
+ } else {
+ *ConsoleRedirectionEnable =
+ gSetupData.ConsoleRedirectionEnable[Port];
+ *TerminalType = gSetupData.TerminalType[Port];
+ *SupportExRes = (gSetupData.Resolution[Port] == 0) ? FALSE : TRUE;
+ *VtUtf8 = (gSetupData.VtUtf8[Port] == 0) ? FALSE : TRUE;
+ *RecorderMode = (gSetupData.RecorderMode[Port] == 0) ? FALSE : TRUE;
+ *PuttyKeyPad = gSetupData.PuttyFunctionKeyPad[Port];
+ }
+#endif
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: GetAcpiSpcrTableValues
+//
+// Input:
+// IN OUT UINT8 *AcpiSpcrTableComPort
+// IN OUT UINT8 *AcpiSpcrTableConsoleRedirectionEnable
+// IN OUT UINT8 *AcpiSpcrTableTerminalType
+// IN OUT UINT8 *AcpiSpcrTableBaudRate
+// IN OUT UINT8 *AcpiSpcrTableFlowControl
+//
+// Output: VOID
+//
+// Description: Returns the configurable aspects of the acpi spcr table
+// com port (the com port number, whether the console
+// redirection is enabled, the terminal type, baude rate,
+// and flow control type used).
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID GetAcpiSpcrTableValues(
+ IN OUT UINT8 *AcpiSpcrTableComPort,
+ IN OUT UINT8 *AcpiSpcrTableConsoleRedirectionEnable,
+ IN OUT UINT8 *AcpiSpcrTableTerminalType,
+ IN OUT UINT8 *AcpiSpcrTableBaudRate,
+ IN OUT UINT8 *AcpiSpcrTableFlowControl)
+{
+ UINT32 SetupDataAttributes = 0;
+ UINTN SetupDataSize = sizeof(SETUP_DATA);
+
+ EFI_STATUS Status = EFI_SUCCESS ;
+
+#if (TOTAL_SERIAL_PORTS == 0)
+
+ *AcpiSpcrTableComPort = DEFAULT_ACPI_SPCR_COM_PORT;
+ *AcpiSpcrTableConsoleRedirectionEnable =
+ DEFAULT_ACPI_SPCR_CONSOLE_REDIRECTION_ENABLE;
+ *AcpiSpcrTableTerminalType = DEFAULT_ACPI_SPCR_TABLE_TERMINAL_TYPE;
+ *AcpiSpcrTableBaudRate = UART_DEFAULT_BAUD_RATE_INDEX;
+ *AcpiSpcrTableFlowControl = UART_DEFAULT_FLOW_CONTROL;
+
+#else
+
+ Status = pRS->GetVariable(L"Setup", &gSetupGuid, &SetupDataAttributes,
+ &SetupDataSize, &gSetupData);
+
+ if (EFI_ERROR(Status)) {
+ *AcpiSpcrTableComPort = DEFAULT_ACPI_SPCR_COM_PORT;
+ *AcpiSpcrTableConsoleRedirectionEnable =
+ DEFAULT_ACPI_SPCR_CONSOLE_REDIRECTION_ENABLE;
+ *AcpiSpcrTableTerminalType = DEFAULT_ACPI_SPCR_TABLE_TERMINAL_TYPE;
+ *AcpiSpcrTableBaudRate = UART_DEFAULT_BAUD_RATE_INDEX;
+ *AcpiSpcrTableFlowControl = UART_DEFAULT_FLOW_CONTROL;
+ } else {
+#if EFI_SPECIFICATION_VERSION<0x2000A
+ *AcpiSpcrTableComPort = gSetupData.AcpiSpcrPort-1;
+#else
+ *AcpiSpcrTableComPort = gSetupData.AcpiSpcrPort;
+#endif
+
+ *AcpiSpcrTableConsoleRedirectionEnable =
+ gSetupData.AcpiSpcrConsoleRedirectionEnable;
+ *AcpiSpcrTableTerminalType = gSetupData.AcpiSpcrTerminalType;
+ *AcpiSpcrTableBaudRate =
+ gSetupData.AcpiSpcrBaudRate;
+ *AcpiSpcrTableFlowControl =
+ gSetupData.AcpiSpcrFlowControl;
+ }
+
+#endif
+}
+
+#include <Protocol\ComponentName.h>
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+#endif
+
+#ifndef LANGUAGE_CODE_ENGLISH
+CHAR8 SupportedLanguages[] = "eng";
+#else
+CHAR8 SupportedLanguages[] = LANGUAGE_CODE_ENGLISH;
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-20014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/Terminal/TerminalSetupVar.h b/Core/EM/Terminal/TerminalSetupVar.h
new file mode 100644
index 0000000..081679d
--- /dev/null
+++ b/Core/EM/Terminal/TerminalSetupVar.h
@@ -0,0 +1,167 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+// $Header: /Alaska/BIN/Modules/Terminal/TerminalSetupVar.h 14 12/12/11 6:55a Rajeshms $
+//
+// $Revision: 14 $
+//
+// $Date: 12/12/11 6:55a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Terminal/TerminalSetupVar.h $
+//
+// 14 12/12/11 6:55a Rajeshms
+// [TAG] EIP71636
+// [Category] New Feature
+// [Description] Implement the AMI_SERIAL_PROTOCOL for non-generic PCI
+// Serial Device.
+// [Files] AmiSerial.c, AmiSerial.sdl, AmiSerial.mak, AmiSerial.chm,
+// AmiSerial.dxs, AmiSerial.cif, Terminal.c, SerialIo.c, TerminalSetup.c,
+// InitTerminalStrings.c, TerminalSetupVar.h, Terminal.cif,
+// TerminalAmiSerial.h, LegacySredir_Setup.c
+//
+// 13 1/24/11 4:04a Lavanyap
+// [TAG] - EIP48183
+// [Category] - IMPROVEMENT
+// [Description] - Update the Terminal eModule to utilize Setup
+// Customization
+// [Files] - Terminal.sd, TerminalSetupVar.h
+//
+// 12 5/03/10 12:22a Rameshr
+// Issue:VT-UTF8 mode support for Console redirection with Debugger
+// Solution: Serial Port attribute Setup questions added for the debugger
+// console redirection port.
+// EIP 37440
+//
+// 11 9/28/09 4:09p Rameshr
+// Terminal assumes UID to be started from 0. This assumption removed as
+// UID should be unique and not be started from 0.
+// EIP 17239
+//
+// 10 7/02/09 5:01p Rameshr
+// Coding Standard and File header updated.
+//
+// 9 6/22/09 12:58p Ambikas
+//
+// 8 4/14/08 6:51p Ambikas
+//
+// 7 6/12/07 3:55p Ambikas
+//
+// 6 6/06/07 7:53p Ambikas
+// We no longer save segment and bus number of pci serial device.
+//
+// 5 6/05/07 6:16p Ambikas
+//
+// 4 6/05/07 11:47a Ambikas
+//
+// 3 6/4/2007 7:31p
+// The setup question related data structures for the serial ports will
+// not be defined if TOTAL_SERIAL_PORTS is 0.
+//
+// 2 5/24/2007 2:33p Ambikas
+//
+// 1 5/05/2006 5:33p Ambikas
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TerminalSetupVar.h
+//
+// Description: Contains definition of PCI_SERIAL_PORTS_LOCATION_VAR
+// and of varstore declaration SERIAL_PORTS_ENABLED_VAR.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _TERMINAL_SETUP_VAR_H
+#define _TERMINAL_SETUP_VAR_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <token.h>
+
+#define TERMINAL_VAR_GUID \
+{0x560bf58a, 0x1e0d, 0x4d7e, 0x95, 0x3f, 0x29, 0x80, 0xa2, 0x61, 0xe0, 0x31}
+
+#define SERIAL_PORTS_ENABLED_VAR_C_NAME L"SerialPortsEnabledVar"
+#define SIO_SERIAL_PORTS_LOCATION_VAR_C_NAME L"SioSerialPortsLocationVar"
+#define PCI_SERIAL_PORTS_LOCATION_VAR_C_NAME L"PciSerialPortsLocationVar"
+#define DEBUGGER_SERIAL_PORTS_ENABLED_VAR_C_NAME L"DebuggerSerialPortsEnabledVar"
+
+#define DEBUGGER_TERMINAL_VAR_GUID \
+{0x97ca1a5b, 0xb760, 0x4d1f, 0xa5, 0x4b, 0xd1, 0x90, 0x92, 0x3, 0x2c, 0x90}
+
+#pragma pack(1)
+
+#ifndef TYPEDEF_DEBUGGER_SERIAL_PORTS_ENABLED_VAR
+#define TYPEDEF_DEBUGGER_SERIAL_PORTS_ENABLED_VAR
+ typedef struct {
+ UINT8 PortEnabled;
+ } DEBUGGER_SERIAL_PORTS_ENABLED_VAR;
+#endif
+
+#if (TOTAL_SERIAL_PORTS > 0)
+#ifndef TYPEDEF_SERIAL_PORTS_ENABLED_VAR
+#define TYPEDEF_SERIAL_PORTS_ENABLED_VAR
+ typedef struct {
+ UINT8 PortsEnabled[ TOTAL_SERIAL_PORTS ];
+ } SERIAL_PORTS_ENABLED_VAR;
+#endif
+#endif
+
+#if (TOTAL_SIO_SERIAL_PORTS > 0)
+#ifndef TYPEDEF_SIO_SERIAL_PORTS_LOCATION_VAR
+#define TYPEDEF_SIO_SERIAL_PORTS_LOCATION_VAR
+ typedef struct {
+ UINT8 PortUid[ TOTAL_SIO_SERIAL_PORTS ];
+ UINT8 Valid[ TOTAL_SIO_SERIAL_PORTS ];
+ } SIO_SERIAL_PORTS_LOCATION_VAR;
+#endif
+#endif
+
+#if (TOTAL_PCI_SERIAL_PORTS > 0)
+#ifndef TYPEDEF_PCI_SERIAL_PORTS_LOCATION_VAR
+#define TYPEDEF_PCI_SERIAL_PORTS_LOCATION_VAR
+ typedef struct {
+ UINT8 Segment[ TOTAL_PCI_SERIAL_PORTS ];
+ UINT8 Bus[ TOTAL_PCI_SERIAL_PORTS ];
+ UINT8 Device[ TOTAL_PCI_SERIAL_PORTS ];
+ UINT8 Function[ TOTAL_PCI_SERIAL_PORTS ];
+ UINT8 AmiPciSerialPresent[ TOTAL_PCI_SERIAL_PORTS ];
+ UINT8 Port[ TOTAL_PCI_SERIAL_PORTS ];
+ } PCI_SERIAL_PORTS_LOCATION_VAR;
+#endif
+#endif
+
+#pragma pack()
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/Terminal/Terminalx64.lib b/Core/EM/Terminal/Terminalx64.lib
new file mode 100644
index 0000000..386f64c
--- /dev/null
+++ b/Core/EM/Terminal/Terminalx64.lib
Binary files differ
diff --git a/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.c b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.c
new file mode 100644
index 0000000..6938502
--- /dev/null
+++ b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.c
@@ -0,0 +1,208 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/TseDefaultBootOrder/TseDefaultBootOrder.c 6 1/03/13 10:51a Vyacheslava $
+//
+// $Revision: 6 $
+//
+// $Date: 1/03/13 10:51a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/TseDefaultBootOrder/TseDefaultBootOrder.c $
+//
+// 6 1/03/13 10:51a Vyacheslava
+// Added modification to check for LOAD_OPTION_HIDDEN and ignore hidden
+// boot options in creating "DefaultBootOrder" variable.
+//
+// 5 10/15/12 10:31a Vyacheslava
+// [TAG] EIP103603
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] DefaultLegacyDevOrder is corrupted
+// [RootCause] SetDefaultTseBootOrder () corrupts the data which is not
+// the Boot Order.
+// [Solution] for( i = 0; i < (Order->Length / (sizeof (UINT16)) - 1);
+// i++ )
+// [Files] TseDefaultBootOrder.c
+//
+// 4 9/13/11 9:09a Vyacheslava
+//
+// 3 4/27/11 11:26a Vyacheslava
+// [TAG] EIP58592
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Restore Defaults in the Setup will work incorrect after
+// second HDD has been disabled.
+//
+// 2 2/02/11 2:00p Vyacheslava
+// [TAG] EIP52313
+// [Category] New Feature
+//
+// 1 1/20/11 10:52a Felixp
+//
+// 6 1/13/10 2:13p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TseDefaultBootOrder.c
+//
+// Description: This is main file of the TseDefaultBootOrder eModule.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <BootOptions.h>
+#include "TseDefaultBootOrder.h"
+
+//----------------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CompareTagThenBbsIndex
+//
+// Description: This function returns result of compairing two DLINK tags.
+//
+// Input:
+// Link1 - pointer to the first tag for compare
+// Link1 - pointer to the second tag for compare
+//
+// Output: INT32 - result of comparing.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+INT32 CompareTagThenBbsIndex( IN DLINK *Link1, IN DLINK *Link2 )
+{
+ BOOT_OPTION *Option1 = (BOOT_OPTION*)Link1;
+ BOOT_OPTION *Option2 = (BOOT_OPTION*)Link2;
+
+ // Compare Tags first
+ if (Option1->Tag < Option2->Tag)
+ return -1;
+ else if (Option1->Tag > Option2->Tag)
+ return 1;
+
+ // Compare by BBS index
+ if (Option1->BbsIndex < Option2->BbsIndex)
+ return -1;
+ else if (Option1->BbsIndex > Option2->BbsIndex)
+ return 1;
+
+ return 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SetDefaultTseBootOrder
+//
+// Description:
+// This function sets variables: DefaultLegacyDevOrder and DefaultBootOrder.
+//
+// Input: VOID
+//
+// Output: VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SetDefaultTseBootOrder(VOID)
+{
+ UINTN DevOrderSize;
+ LEGACY_DEVICE_ORDER *DevOrder;
+ UINTN BootOrderSize;
+ UINT16 *BootOrder;
+ UINT16 PreviousBootOptionNumber;
+ DLINK *Link;
+ UINTN BootOrderIndex;
+ BOOT_OPTION *Option;
+ EFI_GUID DefaultLegacyDevOrderGuid = DEFAULT_LEGACY_DEV_ORDER_VARIABLE_GUID;
+ EFI_GUID DefaultBootOrderGuid = DEFAULT_BOOT_ORDER_VARIABLE_GUID;
+ LEGACY_DEVICE_ORDER *Order;
+ UINTN i;
+
+ // PRECONDITION: All Boot Option Numbers are set
+ BootOrderSize = BootOptionList->Size * sizeof(UINT16);
+ if (BootOrderSize == 0)
+ return;
+
+ // Build DefaultLegacyDevOrder variable
+ SortList(BootOptionList, CompareTagThenBbsIndex);
+ BuildLegacyDevOrderBuffer(&DevOrder, &DevOrderSize);
+
+ // Remove disable mask from buffer DevOrder
+ for( Order = DevOrder; (UINT8*)Order < (UINT8*)DevOrder + DevOrderSize;
+ Order = (LEGACY_DEVICE_ORDER*)((UINT8*)Order + Order->Length + sizeof(Order->Type)) )
+ {
+ // The order length includes their own length
+ for( i = 0; i < (Order->Length / sizeof(UINT16) - 1); i++ )
+ Order->Device[i] &= 0x00FF;
+ }
+
+ // Store "DefaultLegacyDevOrder" EFI variable
+ pRS->SetVariable(
+ L"DefaultLegacyDevOrder",
+ &DefaultLegacyDevOrderGuid,
+ BOOT_VARIABLE_ATTRIBUTES,
+ DevOrderSize,
+ DevOrder
+ );
+ pBS->FreePool(DevOrder);
+
+ // Build DefaultBootOrder variable
+ BootOrder = Malloc(BootOrderSize);
+ PreviousBootOptionNumber = INVALID_BOOT_OPTION_NUMBER;
+ BootOrderIndex = 0;
+
+ // Set boot option number for each boot option
+ FOR_EACH_BOOT_OPTION(BootOptionList,Link,Option)
+ {
+ if ( (PreviousBootOptionNumber == Option->BootOptionNumber) ||
+ (Option->Attributes & LOAD_OPTION_HIDDEN) )
+ continue;
+ BootOrder[BootOrderIndex++] = Option->BootOptionNumber;
+ PreviousBootOptionNumber = Option->BootOptionNumber;
+ }
+
+ // Store "DefaultBootOrder" EFI variable
+ pRS->SetVariable(
+ L"DefaultBootOrder",
+ &DefaultBootOrderGuid,
+ BOOT_VARIABLE_ATTRIBUTES,
+ BootOrderIndex * sizeof(UINT16),
+ BootOrder
+ );
+ pBS->FreePool(BootOrder);
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.chm b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.chm
new file mode 100644
index 0000000..104b201
--- /dev/null
+++ b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.chm
Binary files differ
diff --git a/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.cif b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.cif
new file mode 100644
index 0000000..512d76a
--- /dev/null
+++ b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "TseDefaultBootOrder"
+ category = eModule
+ LocalRoot = "Core\EM\TseDefaultBootOrder\"
+ RefName = "TseDefaultBootOrder"
+[files]
+"TseDefaultBootOrder.sdl"
+"TseDefaultBootOrder.mak"
+"TseDefaultBootOrder.c"
+"TseDefaultBootOrder.h"
+"TseDefaultBootOrder.chm"
+<endComponent>
diff --git a/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.h b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.h
new file mode 100644
index 0000000..172eff8
--- /dev/null
+++ b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.h
@@ -0,0 +1,70 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/BootOptionPolicies/TseDefaultBootOrder/TseDefaultBootOrder.h 2 2/02/11 2:12p Vyacheslava $
+//
+// $Revision: 2 $
+//
+// $Date: 2/02/11 2:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/BootOptionPolicies/TseDefaultBootOrder/TseDefaultBootOrder.h $
+//
+// 2 2/02/11 2:12p Vyacheslava
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: TseDefaultBootOrder.h
+//
+// Description: Internal header file for TseDefaultBootOrder eModule.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef __TseDefaultBootOrder__H__
+#define __TseDefaultBootOrder__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEFAULT_LEGACY_DEV_ORDER_VARIABLE_GUID \
+ { 0x3c4ead08, 0x45ae, 0x4315, 0x8d, 0x15, 0xa6, 0x0e, 0xaa, 0x8c, 0xaf, 0x69 }
+
+#define DEFAULT_BOOT_ORDER_VARIABLE_GUID \
+ { 0x45cf35f6, 0x0d6e, 0x4d04, 0x85, 0x6a, 0x03, 0x70, 0xa5, 0xb1, 0x6f, 0x53 }
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.mak b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.mak
new file mode 100644
index 0000000..0e76376
--- /dev/null
+++ b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.mak
@@ -0,0 +1,67 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/BootOptionPolicies/TseDefaultBootOrder/TseDefaultBootOrder.mak 1 1/20/11 10:52a Felixp $
+#
+# $Revision: 1 $
+#
+# $Date: 1/20/11 10:52a $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/BootOptionPolicies/TseDefaultBootOrder/TseDefaultBootOrder.mak $
+#
+# 1 1/20/11 10:52a Felixp
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: TseDefaultBootOrder.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+CORE_DXEBin : $(BUILD_DIR)\TseDefaultBootOrder.lib
+
+$(BUILD_DIR)\TseDefaultBootOrder.lib : TseDefaultBootOrder
+
+TseDefaultBootOrder : $(BUILD_DIR)\TseDefaultBootOrder.mak TseDefaultBootOrderBin
+
+$(BUILD_DIR)\TseDefaultBootOrder.mak : $(TseDefaultBootOrder_DIR)\$(@B).cif $(TseDefaultBootOrder_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(TseDefaultBootOrder_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+TseDefaultBootOrderBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\TseDefaultBootOrder.mak all\
+ "MY_INCLUDES=/I$(CORE_DXE_DIR)"\
+ TYPE=LIBRARY
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.sdl b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.sdl
new file mode 100644
index 0000000..39187a3
--- /dev/null
+++ b/Core/EM/TseDefaultBootOrder/TseDefaultBootOrder.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "TseDefaultBootOrder_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable TseDefaultBootOrder support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "TseDefaultBootOrder_DIR"
+End
+
+MODULE
+ Help = "Includes TseDefaultBootOrder.mak to Project"
+ File = "TseDefaultBootOrder.mak"
+End
+
+ELINK
+ Name = "SetDefaultTseBootOrder,"
+ Parent = "SaveLegacyDevOrder,"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/Arp/Arp.cif b/Core/EM/UEfiNetworkStack/Common/Arp/Arp.cif
new file mode 100644
index 0000000..7c019ea
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Arp/Arp.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Arp"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\Arp"
+ RefName = "Arp"
+[files]
+"Arp.sdl"
+"Arp.mak"
+"ArpDxeIa32.efi"
+"ArpDxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/Arp/Arp.mak b/Core/EM/UEfiNetworkStack/Common/Arp/Arp.mak
new file mode 100644
index 0000000..87c3c0a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Arp/Arp.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/Arp/Arp.mak 2 4/30/12 6:49p Hari $
+#
+# Revision: $
+#
+# $Date: 4/30/12 6:49p $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Arp.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Arp
+
+Arp : $(BUILD_DIR)\Arp.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Arp.ffs : $(Arp_DIR)\ArpDxe.efi
+!ELSE
+$(BUILD_DIR)\Arp.ffs : $(Arp_DIR)\ArpDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=8DD91798-EE87-4f0e-8A84-3F998311F930\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/Arp/Arp.sdl b/Core/EM/UEfiNetworkStack/Common/Arp/Arp.sdl
new file mode 100644
index 0000000..262e5ab
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Arp/Arp.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Arp_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Arp support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Arp_DIR"
+End
+
+MODULE
+ Help = "Includes Arp.mak to Project"
+ File = "Arp.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Arp.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/Arp/ArpDxe.efi b/Core/EM/UEfiNetworkStack/Common/Arp/ArpDxe.efi
new file mode 100644
index 0000000..a372087
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Arp/ArpDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Arp/ArpDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/Arp/ArpDxeIa32.efi
new file mode 100644
index 0000000..c382eab
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Arp/ArpDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.cif b/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.cif
new file mode 100644
index 0000000..608912f
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Dpc"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\Dpc"
+ RefName = "Dpc"
+[files]
+"Dpc.sdl"
+"Dpc.mak"
+"DpcDxe.efi"
+"DpcDxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.mak b/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.mak
new file mode 100644
index 0000000..7842d00
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/Dpc/Dpc.mak 2 4/30/12 6:48p Hari $
+#
+# Revision: $
+#
+# $Date: 4/30/12 6:48p $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Dpc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Dpc
+
+Dpc : $(BUILD_DIR)\Dpc.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Dpc.ffs : $(Dpc_DIR)\DpcDxe.efi
+!ELSE
+$(BUILD_DIR)\Dpc.ffs : $(Dpc_DIR)\DpcDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=399CF3A7-82C7-4d9b-9123-DB11842986D3\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.sdl b/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.sdl
new file mode 100644
index 0000000..0e96ec3
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Dpc/Dpc.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Dpc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Dpc support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Dpc_DIR"
+End
+
+MODULE
+ Help = "Includes Dpc.mak to Project"
+ File = "Dpc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Dpc.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxe.efi b/Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxe.efi
new file mode 100644
index 0000000..e93eac0
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxeIa32.efi
new file mode 100644
index 0000000..9a9361a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Dpc/DpcDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.cif b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.cif
new file mode 100644
index 0000000..fb9656a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "IpSec"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\IpSec"
+ RefName = "IpSec"
+[files]
+"IpSec.sdl"
+"IpSec.mak"
+"IpSecDxeIa32.efi"
+"IpSecDxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.mak b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.mak
new file mode 100644
index 0000000..59d9fc1
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/IpSec/IpSec.mak 2 5/01/12 9:57a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 9:57a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: IpSec.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : IpSec
+
+IpSec : $(BUILD_DIR)\IpSec.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\IpSec.ffs : $(IpSec_DIR)\IpSecDxe.efi
+!ELSE
+$(BUILD_DIR)\IpSec.ffs : $(IpSec_DIR)\IpSecDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=FCF94301-9763-4a64-AA84-7892C4712367\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.sdl b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.sdl
new file mode 100644
index 0000000..b403a5e
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSec.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "IpSec_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable IpSec support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "IpSec_DIR"
+End
+
+MODULE
+ Help = "Includes IpSec.mak to Project"
+ File = "IpSec.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\IpSec.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxe.efi b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxe.efi
new file mode 100644
index 0000000..5bc767d
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxeIa32.efi
new file mode 100644
index 0000000..5a75a8f
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/IpSec/IpSecDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.cif b/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.cif
new file mode 100644
index 0000000..bbee870
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Mnp"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\Mnp"
+ RefName = "Mnp"
+[files]
+"Mnp.sdl"
+"Mnp.mak"
+"MnpDxeIa32.efi"
+"MnpDxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.mak b/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.mak
new file mode 100644
index 0000000..9ebcc4b
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/Mnp/Mnp.mak 2 5/01/12 9:47a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 9:47a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Mnp.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Mnp
+
+Mnp : $(BUILD_DIR)\Mnp.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Mnp.ffs : $(Mnp_DIR)\MnpDxe.efi
+!ELSE
+$(BUILD_DIR)\Mnp.ffs : $(Mnp_DIR)\MnpDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=C30B94E3-C8F2-4ab0-91AB-FA8DF621B1C9\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.sdl b/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.sdl
new file mode 100644
index 0000000..31d40f8
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Mnp/Mnp.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Mnp_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Mnp support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Mnp_DIR"
+End
+
+MODULE
+ Help = "Includes Mnp.mak to Project"
+ File = "Mnp.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Mnp.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxe.efi b/Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxe.efi
new file mode 100644
index 0000000..b0a5e71
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxeIa32.efi
new file mode 100644
index 0000000..fed4444
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Mnp/MnpDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.c b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.c
new file mode 100644
index 0000000..c28650d
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.c
@@ -0,0 +1,93 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.c 3 6/09/14 4:10a Anushav $Revision:
+//
+// $Date:
+//**********************************************************************
+// Revision History
+// ----------------
+//
+//**********************************************************************
+
+#include <AmiDxeLib.h>
+#include <NetworkStackSetupScreen.h>
+
+NETWORK_STACK mNetworkStackData;
+EFI_GUID mNetworkStackGuid = NETWORK_STACK_GUID;
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Name: InitNetworkStackVar
+//
+// Description: Entry point of the network stack setup driver. This entry point is
+// necessary to initlialize the NetworkStack setup driver.
+//
+// Input:
+// ImageHandle EFI_HANDLE: A handle for the image that is initializing this driver
+// SystemTable EFI_SYSTEM_TABLE: A pointer to the EFI system table
+//
+// Output:
+// EFI_SUCCESS: Driver initialized successfully
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitNetworkStackVar (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+
+ UINTN Size;
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ Size = sizeof(NETWORK_STACK);
+ Status = pRS->GetVariable(L"NetworkStackVar",&mNetworkStackGuid, NULL, &Size, &mNetworkStackData);
+
+ if (Status == EFI_NOT_FOUND) {
+
+ pBS->SetMem(&mNetworkStackData,
+ sizeof(NETWORK_STACK),
+ 0);
+
+ pRS->SetVariable(
+ L"NetworkStackVar",&mNetworkStackGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(NETWORK_STACK), &mNetworkStackData
+ );
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.cif b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.cif
new file mode 100644
index 0000000..27b98c2
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "NetworkStackSetupScreen"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\NetworkStackSetupScreen\"
+ RefName = "NetworkStackSetupScreen"
+[files]
+"NetworkStackSetupScreen.sdl"
+"NetworkStackSetupScreen.mak"
+"NetworkStackSetupScreen.uni"
+"NetworkStackSetupScreen.h"
+"NetworkStackSetupScreen.sd"
+"NetworkStackSetupScreen.c"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.h b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.h
new file mode 100644
index 0000000..a8a3470
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.h
@@ -0,0 +1,82 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.h 7 1/08/14 5:27a Anushav $
+//
+// $Revision: 7 $
+//
+// $Date: 1/08/14 5:27a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.h $
+//
+// 7 1/08/14 5:27a Anushav
+// [TAG] EIP148764
+// [Category] Improvement
+// [Description] Add Media Detect Time setup option.
+// [Files] PxeBcImpl.c,
+// PxeBcDriver.c,
+// NetworkStackSetupScreen.uni,
+// NetworkStackSetupScreen.sd,
+// NetworkStackSetup.h,
+// NetworkStackSetupScreen.c.
+//
+// 6 3/01/13 3:29a Nareshk
+// [TAG]-EIP113577
+// [Category]-IMPROVEMENT
+// [Description]-Support to Handle ESC key to abort PXE boot.
+// [Files]-SnpDxe.efi, SnpDxeIa32.efi, UefiPxeBcDxe.efi,
+// UefiPxeBcDxeIa32.efi, NetworkStackSetupScreen.h,
+// NetworkStackSetupScreen.sd and NetworkStackSetupScreen.uni
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NetworkStackSetupScreen.h
+//
+// Description: Network stack setup data structure definintion
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#pragma pack (1)
+typedef struct{
+ UINT8 Enable;
+ UINT8 Ipv4Pxe;
+ UINT8 Ipv6Pxe;
+ UINT8 IpsecCertificate;
+ UINT8 PxeBootWaitTime;
+ UINT8 MediaDetectTime;
+} NETWORK_STACK;
+#pragma pack ()
+
+#define NETWORK_STACK_GUID \
+ { 0xD1405D16, 0x7AFC, 0x4695, 0xBB, 0x12, 0x41, 0x45, 0x9D, 0x36, 0x95, 0xA2 }
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.mak b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.mak
new file mode 100644
index 0000000..90b57a2
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.mak
@@ -0,0 +1,68 @@
+# #**********************************************************************#
+#**********************************************************************#
+#** **#
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **#
+#** **#
+#** All Rights Reserved. **#
+#** **#
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **#
+#** **#
+#** Phone: (770)-246-8600 **#
+#** **#
+#**********************************************************************#
+#**********************************************************************#
+#**********************************************************************#
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/COMMON/NetworkStackSetupScreen/NetworkStackSetupScreen.mak 1 6/02/11 11:47a Hari $
+#
+# $Revision: 1 $
+#
+# $Date: 6/02/11 11:47a $(BUILD_DIR)\NetworkStackSetupScreen.mak NETWORKSTACKSETUPSCREENSDB
+#**********************************************************************#
+# Revision History
+# ----------------
+
+#<AMI_FHDR_START>
+#---------------------------------------------------------------------------
+# Name: NetworkStackSetupScreen.mak
+#
+# Description: Make file for the NetworkStackSetupScreen component
+#
+#---------------------------------------------------------------------------
+#<AMI_FHDR_END>
+all : NetworkStackSetupScreen
+
+NetworkStackSetupScreen : $(BUILD_DIR)\NetworkStackSetupScreen.mak NetworkStackSetupScreenBin
+
+SetupSdbs : $(BUILD_DIR)\NetworkStackSetupScreen.mak NETWORKSTACKSETUPSCREENSDB
+
+$(BUILD_DIR)\NetworkStackSetupScreen.mak : $(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.cif $(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.mak $(BUILD_RULES)
+ $(CIF2MAK) $(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.cif $(CIF2MAK_DEFAULTS)
+
+NETWORKSTACKSETUPSCREENSDB :
+ copy $(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.h $(BUILD_DIR)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NetworkStackSetupScreen.mak all\
+ TYPE=SDB NAME=NETWORKSTACKSETUPSCREEN MAKEFILE=$(BUILD_DIR)\NetworkStackSetupScreen.mak STRING_CONSUMERS=$(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.sd
+
+NetworkStackSetupScreenBin : $(AMIDXELIB)
+ copy $(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.h $(BUILD_DIR)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\NetworkStackSetupScreen.mak all\
+ GUID=0029DE6A-E024-4eb8-A91D-9F23AA1F4E92\
+ ENTRY_POINT=InitNetworkStackVar\
+ TYPE=BS_DRIVER\
+ COMPRESS=1
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sd b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sd
new file mode 100644
index 0000000..925984e
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sd
@@ -0,0 +1,246 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sd 8 6/04/14 10:26a Anushav $
+//
+// $Revision: 8 $
+//
+// $Date: 6/04/14 10:26a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sd $
+//
+// 8 6/04/14 10:26a Anushav
+// [TAG] EIP147413
+// [Category] Improvement
+// [Description] Conversion of NetworkStackSetupScreen.sd to the new
+// setup format.
+// [Files] NetworkStackSetupScreen.sd
+//
+// 7 1/08/14 5:28a Anushav
+// [TAG] EIP148764
+// [Category] Improvement
+// [Description] Add Media Detect Time setup option.
+// [Files] PxeBcImpl.c,
+// PxeBcDriver.c,
+// NetworkStackSetupScreen.uni,
+// NetworkStackSetupScreen.sd,
+// NetworkStackSetup.h,
+// NetworkStackSetupScreen.c.
+//
+// 6 3/01/13 3:30a Nareshk
+// [TAG]-EIP113577
+// [Category]-IMPROVEMENT
+// [Description]-Support to Handle ESC key to abort PXE boot.
+// [Files]-SnpDxe.efi, SnpDxeIa32.efi, UefiPxeBcDxe.efi,
+// UefiPxeBcDxeIa32.efi, NetworkStackSetupScreen.h,
+// NetworkStackSetupScreen.sd and NetworkStackSetupScreen.uni
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: NetworkStackSetupScreen.sd
+//
+// Description: Setup definitions for NetworkStack setup screen
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+//**********************************************************************
+// Compatibility Section
+//**********************************************************************
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+ #define CONTROL_DEFINITION
+#endif
+
+//**********************************************************************
+// Controls Section
+//
+// The following section contains control macros that can be overridden
+// in external files. This allows customization of control content,
+// while ensuring the control's data is available.
+//**********************************************************************
+
+#ifdef CONTROL_DEFINITION
+ #define NETWORKSTACK_ONEOF_NETWORK_STACK_SUPPORT \
+ oneof varid = NETWORK_STACK.Enable,\
+ prompt = STRING_TOKEN(STR_NETWORK_STACK_ENABLE),\
+ help = STRING_TOKEN(STR_NETWORK_STACK_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value=0, flags= DEFAULT | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value=1, flags= 0 | RESET_REQUIRED;\
+ endoneof;
+
+ #if UefiIpv4StackII_SUPPORT == 1
+ #define NETWORKSTACK_ONEOF_IPV4_PXE_SUPPORT \
+ oneof varid = NETWORK_STACK.Ipv4Pxe,\
+ prompt = STRING_TOKEN(STR_IPV4_PXE_ENABLE),\
+ help = STRING_TOKEN(STR_IPV4_PXE_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value=0, flags= RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value=1, flags= DEFAULT | RESET_REQUIRED;\
+ endoneof;
+ #endif
+
+ #if UefiIpv6StackII_SUPPORT == 1
+ #define NETWORKSTACK_ONEOF_IPV6_PXE_SUPPORT \
+ oneof varid = NETWORK_STACK.Ipv6Pxe,\
+ prompt = STRING_TOKEN(STR_IPV6_PXE_ENABLE),\
+ help = STRING_TOKEN(STR_IPV6_PXE_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value=0, flags= RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value=1, flags= DEFAULT | RESET_REQUIRED;\
+ endoneof;
+ #endif
+
+ #if IpSec_SUPPORT == 1
+ #define NETWORKSTACK_ONEOF_IPSEC_CERTIFICATE \
+ oneof varid = NETWORK_STACK.IpsecCertificate,\
+ prompt = STRING_TOKEN(STR_IPSEC_CERTIFICATE_ENABLE),\
+ help = STRING_TOKEN(STR_IPSEC_CERTIFICATE_HELP),\
+ option text = STRING_TOKEN(STR_DISABLED), value=0, flags= RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_ENABLED), value=1, flags= DEFAULT | RESET_REQUIRED;\
+ endoneof;
+ #endif
+
+ #if UefiPxeBc_SUPPORT == 1
+ #define NETWORKSTACK_NUMERIC_PXE_BOOT_WAIT_TIME \
+ numeric varid = NETWORK_STACK.PxeBootWaitTime,\
+ prompt = STRING_TOKEN(STR_PXE_BOOT_WAIT_TIME),\
+ help = STRING_TOKEN(STR_PXE_BOOT_WAIT_TIME_HELP),\
+ flags = RESET_REQUIRED,\
+ minimum = 0,\
+ maximum = 5,\
+ step = 1,\
+ default = 0,\
+ endnumeric;
+
+ #define NETWORKSTACK_NUMERIC_MEDIA_DETECT_TIME \
+ numeric varid = NETWORK_STACK.MediaDetectTime,\
+ prompt = STRING_TOKEN(STR_MEDIA_DETECT_TIME),\
+ help = STRING_TOKEN(STR_MEDIA_DETECT_TIME_HELP),\
+ flags = RESET_REQUIRED,\
+ minimum = 0,\
+ maximum = 50,\
+ step = 1,\
+ default = 0,\
+ endnumeric;
+ #endif
+#endif //#ifdef CONTROL_DEFINITION
+
+//**********************************************************************
+// ADVANCED - Network Stack Configuration Form
+//**********************************************************************
+
+#ifdef ADVANCED_FORM_SET
+
+#ifdef CONTROLS_WITH_DEFAULTS
+ NETWORKSTACK_ONEOF_NETWORK_STACK_SUPPORT
+ #if UefiIpv4StackII_SUPPORT == 1
+ NETWORKSTACK_ONEOF_IPV4_PXE_SUPPORT
+ #endif
+ #if UefiIpv6StackII_SUPPORT == 1
+ NETWORKSTACK_ONEOF_IPV6_PXE_SUPPORT
+ #endif
+ #if IpSec_SUPPORT == 1
+ NETWORKSTACK_ONEOF_IPSEC_CERTIFICATE
+ #endif
+ #if UefiPxeBc_SUPPORT == 1
+ NETWORKSTACK_NUMERIC_PXE_BOOT_WAIT_TIME
+ NETWORKSTACK_NUMERIC_MEDIA_DETECT_TIME
+ #endif
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+#ifdef FORM_SET_TYPEDEF
+#include <NetworkStackSetupScreen.h>
+#endif
+
+
+#ifdef FORM_SET_VARSTORE
+ varstore NETWORK_STACK,
+ key = AUTO_ID(NETWORK_STACK_KEY_ID),
+ name = NetworkStackVar,
+ guid = NETWORK_STACK_GUID;
+#endif
+
+#ifdef FORM_SET_GOTO
+// Define goto commands for the forms defined in this file
+ goto STACK_FORM_ID,
+ prompt = STRING_TOKEN(STR_STACK_FORM),
+ help = STRING_TOKEN(STR_STACK_FORM_HELP);
+#endif
+
+
+#ifdef FORM_SET_FORM
+// Define forms
+ #ifndef NETWORK_STACK_FORM_SETUP
+ #define NETWORK_STACK_FORM_SETUP
+
+ form formid = AUTO_ID(STACK_FORM_ID),
+ title = STRING_TOKEN(STR_STACK_FORM);
+
+ NETWORKSTACK_ONEOF_NETWORK_STACK_SUPPORT
+
+#if UefiIpv4StackII_SUPPORT == 1
+
+ suppressif ideqval NETWORK_STACK.Enable == 0;
+ NETWORKSTACK_ONEOF_IPV4_PXE_SUPPORT
+ endif;
+#endif
+
+#if UefiIpv6StackII_SUPPORT == 1
+ suppressif ideqval NETWORK_STACK.Enable == 0;
+ NETWORKSTACK_ONEOF_IPV6_PXE_SUPPORT
+ endif;
+#endif
+
+
+#if IpSec_SUPPORT == 1
+ suppressif ideqval NETWORK_STACK.Enable == 0;
+ NETWORKSTACK_ONEOF_IPSEC_CERTIFICATE
+ endif;
+#endif
+
+#if UefiPxeBc_SUPPORT == 1
+
+ suppressif ideqval NETWORK_STACK.Enable == 0;
+ NETWORKSTACK_NUMERIC_PXE_BOOT_WAIT_TIME
+ endif;
+
+ suppressif ideqval NETWORK_STACK.Enable == 0;
+ NETWORKSTACK_NUMERIC_MEDIA_DETECT_TIME
+ endif;
+#endif // #if UefiPxeBc_SUPPORT == 1
+
+ endform;
+ #endif // NETWORK_STACK_FORM_SETUP
+#endif // #ifdef FORM_SET_GOTO
+
+#endif // ADVANCED_FORM_SET
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sdl b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sdl
new file mode 100644
index 0000000..e8a1995
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.sdl
@@ -0,0 +1,38 @@
+TOKEN
+ Name = NetworkStackSetupScreen_SUPPORT
+ Value = "1"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable NetworkStackSetupScreen support in Project"
+End
+
+MODULE
+ Help = "Includes NetworkStackSetupScreen.mak to Project"
+ File = "NetworkStackSetupScreen.mak"
+End
+
+PATH
+ Name = "NETWORK_STACK_SETUP_SCREEN_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NetworkStackSetupScreen.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\NetworkStackSetupScreen.sdb"
+ Parent = "SETUP_SDBS"
+ Priority = 254
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(NETWORK_STACK_SETUP_SCREEN_DIR)\NetworkStackSetupScreen.sd"
+ Parent = "SETUP_DEFINITIONS"
+ Priority = 254
+ InvokeOrder = AfterParent
+End
diff --git a/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.uni b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.uni
new file mode 100644
index 0000000..a15a050
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/NetworkStackSetupScreen/NetworkStackSetupScreen.uni
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Snp/Snp.cif b/Core/EM/UEfiNetworkStack/Common/Snp/Snp.cif
new file mode 100644
index 0000000..3753c3e
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Snp/Snp.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Snp"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\Snp"
+ RefName = "Snp"
+[files]
+"Snp.sdl"
+"Snp.mak"
+"SnpDxeIa32.efi"
+"SnpDxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/Snp/Snp.mak b/Core/EM/UEfiNetworkStack/Common/Snp/Snp.mak
new file mode 100644
index 0000000..dbd4bde
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Snp/Snp.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/Snp/Snp.mak 2 5/01/12 9:40a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 9:40a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Snp.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Snp
+
+Snp : $(BUILD_DIR)\Snp.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Snp.ffs : $(Snp_DIR)\SnpDxe.efi
+!ELSE
+$(BUILD_DIR)\Snp.ffs : $(Snp_DIR)\SnpDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=3DD7A87B-D5BD-44af-986F-2E13DB5D274C\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/Snp/Snp.sdl b/Core/EM/UEfiNetworkStack/Common/Snp/Snp.sdl
new file mode 100644
index 0000000..d232eea
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Snp/Snp.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Snp_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Snp support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Snp_DIR"
+End
+
+MODULE
+ Help = "Includes Snp.mak to Project"
+ File = "Snp.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Snp.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/Snp/SnpDxe.efi b/Core/EM/UEfiNetworkStack/Common/Snp/SnpDxe.efi
new file mode 100644
index 0000000..65b5296
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Snp/SnpDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Snp/SnpDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/Snp/SnpDxeIa32.efi
new file mode 100644
index 0000000..cd2f380
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Snp/SnpDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.cif b/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.cif
new file mode 100644
index 0000000..5c8741a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Tcp"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\Tcp"
+ RefName = "Tcp"
+[files]
+"Tcp.sdl"
+"Tcp.mak"
+"TcpDxeIa32.efi"
+"TcpDxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.mak b/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.mak
new file mode 100644
index 0000000..def4d98
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/Tcp/Tcp.mak 2 5/01/12 10:09a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:09a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Tcp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Tcp
+
+Tcp : $(BUILD_DIR)\Tcp.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Tcp.ffs : $(Tcp_DIR)\TcpDxe.efi
+!ELSE
+$(BUILD_DIR)\Tcp.ffs : $(Tcp_DIR)\TcpDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=B1625D3C-9D2D-4e0d-B864-8A763EE4EC50\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.sdl b/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.sdl
new file mode 100644
index 0000000..9b7beef
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Tcp/Tcp.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Tcp_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Tcp4 and Tcp6 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Tcp_DIR"
+End
+
+MODULE
+ Help = "Includes Tcp.mak to Project"
+ File = "Tcp.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Tcp.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxe.efi b/Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxe.efi
new file mode 100644
index 0000000..719067c
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxeIa32.efi
new file mode 100644
index 0000000..f2f2f28
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/Tcp/TcpDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/UefiCommonNetworkStackII.cif b/Core/EM/UEfiNetworkStack/Common/UefiCommonNetworkStackII.cif
new file mode 100644
index 0000000..cc601ed
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/UefiCommonNetworkStackII.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "UefiCommonNetworkStack II"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common"
+ RefName = "UefiCommonNetworkStack II"
+[parts]
+"Dpc"
+"Arp"
+"Snp"
+"Mnp"
+"UefiPxeBc"
+"IpSec"
+"NetworkStackSetupScreen"
+"Tcp"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.cif b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.cif
new file mode 100644
index 0000000..5ad3dbc
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "UefiPxeBc"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Common\UefiPxeBc"
+ RefName = "UefiPxeBc"
+[files]
+"UefiPxeBc.sdl"
+"UefiPxeBc.mak"
+"UefiPxeBcDxeIa32.efi"
+"UefiPxeBcDxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.mak b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.mak
new file mode 100644
index 0000000..3615490
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/Common/UefiPxeBc/UefiPxeBc.mak 2 5/01/12 9:49a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 9:49a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: UefiPxeBc.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : UefiPxeBc
+
+UefiPxeBc : $(BUILD_DIR)\UefiPxeBc.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\UefiPxeBc.ffs : $(UefiPxeBc_DIR)\UefiPxeBcDxe.efi
+!ELSE
+$(BUILD_DIR)\UefiPxeBc.ffs : $(UefiPxeBc_DIR)\UefiPxeBcDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=0EF8A3B1-388A-4b62-8BE6-C7877D50AEDF\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.sdl b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.sdl
new file mode 100644
index 0000000..957b34a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBc.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "UefiPxeBc_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UefiPxeBc support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "UefiPxeBc_DIR"
+End
+
+MODULE
+ Help = "Includes UefiPxeBc.mak to Project"
+ File = "UefiPxeBc.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\UefiPxeBc.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxe.efi b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxe.efi
new file mode 100644
index 0000000..6baf034
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxeIa32.efi b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxeIa32.efi
new file mode 100644
index 0000000..e1d73a9
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Common/UefiPxeBc/UefiPxeBcDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.cif b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.cif
new file mode 100644
index 0000000..dd176b4
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Dhcp4"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv4\Dhcp4"
+ RefName = "Dhcp4"
+[files]
+"Dhcp4.sdl"
+"Dhcp4.mak"
+"Dhcp4DxeIa32.efi"
+"Dhcp4Dxe.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.mak b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.mak
new file mode 100644
index 0000000..14ec757
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV4/Dhcp4/Dhcp4.mak 2 5/01/12 10:11a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:11a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Dhcp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Dhcp4
+
+Dhcp4 : $(BUILD_DIR)\Dhcp4.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Dhcp4.ffs : $(Dhcp4_DIR)\Dhcp4Dxe.efi
+!ELSE
+$(BUILD_DIR)\Dhcp4.ffs : $(Dhcp4_DIR)\Dhcp4DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=8DD9176E-EE87-4f0e-8A84-3F998311F930\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.sdl b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.sdl
new file mode 100644
index 0000000..ccc7898
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Dhcp4_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Dhcp6 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Dhcp4_DIR"
+End
+
+MODULE
+ Help = "Includes Dhcp4.mak to Project"
+ File = "Dhcp4.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Dhcp4.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4Dxe.efi
new file mode 100644
index 0000000..c6ad14a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4DxeIa32.efi
new file mode 100644
index 0000000..3522014
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Dhcp4/Dhcp4DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.cif b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.cif
new file mode 100644
index 0000000..9f533d9
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Ip4"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv4\Ip4"
+ RefName = "Ip4"
+[files]
+"Ip4.sdl"
+"Ip4.mak"
+"Ip4Dxe.efi"
+"Ip4DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.mak b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.mak
new file mode 100644
index 0000000..e1bdd5b
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV4/Ip4/Ip4.mak 2 5/01/12 10:19a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:19a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Ip6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Ip4
+
+Ip4 : $(BUILD_DIR)\Ip4.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Ip4.ffs : $(Ip4_DIR)\Ip4Dxe.efi
+!ELSE
+$(BUILD_DIR)\Ip4.ffs : $(Ip4_DIR)\Ip4DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=8F92960F-2880-4659-B857-915A8901BDC8\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.sdl b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.sdl
new file mode 100644
index 0000000..77e107a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Ip4_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Ip4 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Ip4_DIR"
+End
+
+MODULE
+ Help = "Includes Ip4.mak to Project"
+ File = "Ip4.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Ip4.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4Dxe.efi
new file mode 100644
index 0000000..7a6948a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4DxeIa32.efi
new file mode 100644
index 0000000..db337e6
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4/Ip4DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.cif b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.cif
new file mode 100644
index 0000000..4a50502
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Ip4Config"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv4\Ip4Config"
+ RefName = "Ip4Config"
+[files]
+"Ip4Config.sdl"
+"Ip4Config.mak"
+"Ip4ConfigDxe.efi"
+"Ip4ConfigDxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.mak b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.mak
new file mode 100644
index 0000000..3b65570
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV4/Ip4Config/Ip4Config.mak 2 5/01/12 10:13a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:13a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Ip6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Ip4Config
+
+Ip4Config : $(BUILD_DIR)\Ip4Config.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Ip4Config.ffs : $(Ip4Config_DIR)\Ip4ConfigDxe.efi
+!ELSE
+$(BUILD_DIR)\Ip4Config.ffs : $(Ip4Config_DIR)\Ip4ConfigDxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=8F9296EF-2880-4659-B857-915A8901BDC8\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.sdl b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.sdl
new file mode 100644
index 0000000..919ed5f
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4Config.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Ip4Config_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Ip4Config support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Ip4Config_DIR"
+End
+
+MODULE
+ Help = "Includes Ip4Config.mak to Project"
+ File = "Ip4Config.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Ip4Config.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxe.efi b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxe.efi
new file mode 100644
index 0000000..14e4385
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxeIa32.efi
new file mode 100644
index 0000000..187fd74
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Ip4Config/Ip4ConfigDxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.cif b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.cif
new file mode 100644
index 0000000..07543ff
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Mtftp4"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv4\Mtftp4"
+ RefName = "Mtftp4"
+[files]
+"Mtftp4.sdl"
+"Mtftp4.mak"
+"Mtftp4Dxe.efi"
+"Mtftp4DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.mak b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.mak
new file mode 100644
index 0000000..1bd5438
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV4/MtFtp4/Mtftp4.mak 2 5/01/12 10:21a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:21a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Mtftp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Mtftp4
+
+Mtftp4 : $(BUILD_DIR)\Mtftp4.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Mtftp4.ffs : $(Mtftp4_DIR)\Mtftp4Dxe.efi
+!ELSE
+$(BUILD_DIR)\Mtftp4.ffs : $(Mtftp4_DIR)\Mtftp4DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=61AFA223-8AC8-4440-9AB5-762B1BF05156\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.sdl b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.sdl
new file mode 100644
index 0000000..5853e9c
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Mtftp4_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Mtftp4 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Mtftp4_DIR"
+End
+
+MODULE
+ Help = "Includes Mtftp4.mak to Project"
+ File = "Mtftp4.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Mtftp4.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4Dxe.efi
new file mode 100644
index 0000000..704bdf4
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4DxeIa32.efi
new file mode 100644
index 0000000..8522d8f
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Mtftp4/Mtftp4DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.cif b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.cif
new file mode 100644
index 0000000..f7e930a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Udp4"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv4\Udp4"
+ RefName = "Udp4"
+[files]
+"Udp4.sdl"
+"Udp4.mak"
+"Udp4Dxe.efi"
+"Udp4DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.mak b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.mak
new file mode 100644
index 0000000..4e7738c
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV4/Udp4/Udp4.mak 2 5/01/12 10:24a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:24a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Udp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Udp4
+
+Udp4 : $(BUILD_DIR)\Udp4.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Udp4.ffs : $(Udp4_DIR)\Udp4Dxe.efi
+!ELSE
+$(BUILD_DIR)\Udp4.ffs : $(Udp4_DIR)\Udp4DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=10EE5462-B207-4a4f-ABD8-CB522ECAA3A4\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.sdl b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.sdl
new file mode 100644
index 0000000..5ec2978
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Udp4_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Udp4 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Udp4_DIR"
+End
+
+MODULE
+ Help = "Includes Udp4.mak to Project"
+ File = "Udp4.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Udp4.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4Dxe.efi
new file mode 100644
index 0000000..1629871
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4DxeIa32.efi
new file mode 100644
index 0000000..560b0f1
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/Udp4/Udp4DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.cif b/Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.cif
new file mode 100644
index 0000000..de13ce8
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "UefiIpv4Stack II"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv4"
+ RefName = "UefiIpv4Stack II"
+[files]
+"UefiIpv4StackII.sdl"
+[parts]
+"Dhcp4"
+"Ip4Config"
+"Ip4"
+"Mtftp4"
+"Udp4"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.sdl b/Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.sdl
new file mode 100644
index 0000000..4fc06cf
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv4/UefiIpv4StackII.sdl
@@ -0,0 +1,11 @@
+TOKEN
+ Name = "UefiIpv4StackII_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UefiIpv4StackII support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.cif b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.cif
new file mode 100644
index 0000000..f415c2c
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Dhcp6"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv6\Dhcp6"
+ RefName = "Dhcp6"
+[files]
+"Dhcp6.sdl"
+"Dhcp6.mak"
+"Dhcp6Dxe.efi"
+"Dhcp6DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.mak b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.mak
new file mode 100644
index 0000000..9e7dba2
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV6/Dhcp6/Dhcp6.mak 2 5/01/12 10:27a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 10:27a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Dhcp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Dhcp6
+
+Dhcp6 : $(BUILD_DIR)\Dhcp6.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Dhcp6.ffs : $(Dhcp6_DIR)\Dhcp6Dxe.efi
+!ELSE
+$(BUILD_DIR)\Dhcp6.ffs : $(Dhcp6_DIR)\Dhcp6DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=8DD9176D-EE87-4f0e-8A84-3F998311F930\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.sdl b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.sdl
new file mode 100644
index 0000000..b7a2028
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Dhcp6_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Dhcp6 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Dhcp6_DIR"
+End
+
+MODULE
+ Help = "Includes Dhcp6.mak to Project"
+ File = "Dhcp6.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Dhcp6.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6Dxe.efi
new file mode 100644
index 0000000..48a0645
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6DxeIa32.efi
new file mode 100644
index 0000000..353e859
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Dhcp6/Dhcp6DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.cif b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.cif
new file mode 100644
index 0000000..0fd6f08
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Ip6"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv6\Ip6"
+ RefName = "Ip6"
+[files]
+"Ip6.sdl"
+"Ip6.mak"
+"Ip6Dxe.efi"
+"Ip6DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.mak b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.mak
new file mode 100644
index 0000000..26df788
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV6/Ip6/Ip6.mak 2 5/01/12 11:23a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 11:23a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Ip6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Ip6
+
+Ip6 : $(BUILD_DIR)\Ip6.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Ip6.ffs : $(Ip6_DIR)\Ip6Dxe.efi
+!ELSE
+$(BUILD_DIR)\Ip6.ffs : $(Ip6_DIR)\Ip6DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=8F92960E-2880-4659-B857-915A8901BDC8\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.sdl b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.sdl
new file mode 100644
index 0000000..4403ed4
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Ip6_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Ip6 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Ip6_DIR"
+End
+
+MODULE
+ Help = "Includes Ip6.mak to Project"
+ File = "Ip6.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Ip6.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6Dxe.efi
new file mode 100644
index 0000000..c4f133a
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6DxeIa32.efi
new file mode 100644
index 0000000..3bb64fe
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Ip6/Ip6DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.cif b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.cif
new file mode 100644
index 0000000..151ac6b
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Mtftp6"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv6\Mtftp6"
+ RefName = "Mtftp6"
+[files]
+"Mtftp6.sdl"
+"Mtftp6.mak"
+"Mtftp6Dxe.efi"
+"Mtftp6DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.mak b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.mak
new file mode 100644
index 0000000..ac066c4
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV6/MtFtp6/Mtftp6.mak 2 5/01/12 11:24a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 11:24a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Mtftp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Mtftp6
+
+Mtftp6 : $(BUILD_DIR)\Mtftp6.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Mtftp6.ffs : $(Mtftp6_DIR)\Mtftp6Dxe.efi
+!ELSE
+$(BUILD_DIR)\Mtftp6.ffs : $(Mtftp6_DIR)\Mtftp6DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=61AFA251-8AC8-4440-9AB5-762B1BF05156\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.sdl b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.sdl
new file mode 100644
index 0000000..4e07382
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Mtftp6_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Mtftp6 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Mtftp6_DIR"
+End
+
+MODULE
+ Help = "Includes Mtftp6.mak to Project"
+ File = "Mtftp6.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Mtftp6.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6Dxe.efi
new file mode 100644
index 0000000..aea5e37
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6DxeIa32.efi
new file mode 100644
index 0000000..f7a41de
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Mtftp6/Mtftp6DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.cif b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.cif
new file mode 100644
index 0000000..5339b49
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "Udp6"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv6\Udp6"
+ RefName = "Udp6"
+[files]
+"Udp6.sdl"
+"Udp6.mak"
+"Udp6Dxe.efi"
+"Udp6DxeIa32.efi"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.mak b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.mak
new file mode 100644
index 0000000..dbfba7c
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.mak
@@ -0,0 +1,59 @@
+#//**********************************************************************
+#//**********************************************************************
+#//** **
+#//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#//** **
+#//** All Rights Reserved. **
+#//** **
+#//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#//** **
+#//** Phone: (770)-246-8600 **
+#//** **
+#//**********************************************************************
+#//**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/Network/UEFINetworkStack II/IPV6/Udp6/Udp6.mak 2 5/01/12 11:33a Hari $
+#
+# Revision: $
+#
+# $Date: 5/01/12 11:33a $
+#**********************************************************************
+# Revision History
+# ----------------
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Udp6.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Udp6
+
+Udp6 : $(BUILD_DIR)\Udp6.ffs
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\Udp6.ffs : $(Udp6_DIR)\Udp6Dxe.efi
+!ELSE
+$(BUILD_DIR)\Udp6.ffs : $(Udp6_DIR)\Udp6DxeIa32.efi
+!ENDIF
+ $(MAKE) /f Core\FFS.mak \
+ BUILD_DIR=$(BUILD_DIR) \
+ GUID=10EE54AE-B207-4a4f-ABD8-CB522ECAA3A4\
+ TYPE=EFI_FV_FILETYPE_DRIVER \
+ PEFILE=$** FFSFILE=$@ COMPRESS=1 NAME=$(**B)
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2004, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.sdl b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.sdl
new file mode 100644
index 0000000..4d453ec
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6.sdl
@@ -0,0 +1,26 @@
+TOKEN
+ Name = "Udp6_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Udp6 support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Udp6_DIR"
+End
+
+MODULE
+ Help = "Includes Udp6.mak to Project"
+ File = "Udp6.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\Udp6.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6Dxe.efi b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6Dxe.efi
new file mode 100644
index 0000000..8b16224
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6Dxe.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6DxeIa32.efi b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6DxeIa32.efi
new file mode 100644
index 0000000..0500afb
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/Udp6/Udp6DxeIa32.efi
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.cif b/Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.cif
new file mode 100644
index 0000000..5a6ea94
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "UefiIpv6Stack II"
+ category = ModulePart
+ LocalRoot = "Core\EM\UEfiNetworkStack\Ipv6"
+ RefName = "UefiIpv6Stack II"
+[files]
+"UefiIpv6StackII.sdl"
+[parts]
+"Dhcp6"
+"Ip6"
+"Mtftp6"
+"Udp6"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.sdl b/Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.sdl
new file mode 100644
index 0000000..842c251
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/Ipv6/UefiIpv6StackII.sdl
@@ -0,0 +1,11 @@
+TOKEN
+ Name = "UefiIpv6StackII_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UefiIpv6StackII support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
diff --git a/Core/EM/UEfiNetworkStack/UefiNetworkStackII.chm b/Core/EM/UEfiNetworkStack/UefiNetworkStackII.chm
new file mode 100644
index 0000000..bdbdefa
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/UefiNetworkStackII.chm
Binary files differ
diff --git a/Core/EM/UEfiNetworkStack/UefiNetworkStackII.cif b/Core/EM/UEfiNetworkStack/UefiNetworkStackII.cif
new file mode 100644
index 0000000..c91a221
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/UefiNetworkStackII.cif
@@ -0,0 +1,13 @@
+<component>
+ name = "UefiNetworkStack II"
+ category = eModule
+ LocalRoot = "Core\EM\UEfiNetworkStack"
+ RefName = "UefiNetworkStack II"
+[files]
+"UefiNetworkStackII.sdl"
+"UefiNetworkStackII.chm"
+[parts]
+"UefiCommonNetworkStack II"
+"UefiIpv4Stack II"
+"UefiIpv6Stack II"
+<endComponent>
diff --git a/Core/EM/UEfiNetworkStack/UefiNetworkStackII.sdl b/Core/EM/UEfiNetworkStack/UefiNetworkStackII.sdl
new file mode 100644
index 0000000..6981f36
--- /dev/null
+++ b/Core/EM/UEfiNetworkStack/UefiNetworkStackII.sdl
@@ -0,0 +1,11 @@
+TOKEN
+ Name = "UefiNetworkStackII"
+ Value = "1"
+ Help = "Main switch to enable netwwork stack drivers support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
diff --git a/Core/EM/UsbRecovery/AmiMapping.h b/Core/EM/UsbRecovery/AmiMapping.h
new file mode 100644
index 0000000..0307957
--- /dev/null
+++ b/Core/EM/UsbRecovery/AmiMapping.h
@@ -0,0 +1,102 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/AmiMapping.h 3 7/10/08 6:33p Michaela $
+//
+// $Revision: 3 $
+//
+// $Date: 7/10/08 6:33p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/AmiMapping.h $
+//
+// 3 7/10/08 6:33p Michaela
+// Updated to support OHCI controllers
+//
+// 2 4/16/07 1:08p Sivagarn
+// - Updated as per coding standard
+//
+// 1 Initial checkin
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AMIMAPPING.H
+//
+// Description: This file is the mapping header file that maps Tiano related
+// equates to AMI equates
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#ifndef __AMI_MAPPING__H__
+#define __AMI_MAPPING__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define STATIC static
+#define EFI_PPI_DEFINITION( a ) EFI_STRINGIZE(Ppi/a.h)
+#define EFI_STRINGIZE( a ) #a
+//Compatibility
+// PPI's
+#define PEI_CPU_IO_PPI EFI_PEI_CPU_IO_PPI
+#define PEI_STALL_PPI EFI_PEI_STALL_PPI
+#define PEI_STALL_PPI_GUID EFI_PEI_STALL_PPI_GUID
+//
+// Define macros to build data structure signatures from characters.
+//
+#define EFI_SIGNATURE_16( A, B ) ( (A) | (B << 8) )
+#define EFI_SIGNATURE_32( A, B, C, D ) ( EFI_SIGNATURE_16( A, B ) | \
+ (EFI_SIGNATURE_16( C, D ) << 16) )
+#define EFI_SIGNATURE_64( A, B, C, D, E, F, G, H ) \
+ ( EFI_SIGNATURE_32( A, B, C, D ) | ( (UINT64) \
+ ( EFI_SIGNATURE_32 \ (E, F, G,\
+ H) ) << 32 ) )
+
+#define PEI_CR( Record, TYPE, Field, Signature ) \
+ _CR( Record, TYPE, Field )
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#define _CR( Record, TYPE, Field ) ( (TYPE *) \
+ ( (CHAR8 *) (Record) -\
+ (CHAR8 *) &( ( (TYPE *) 0 )->Field ) ) )
+
+#define EFI_D_ERROR 0x80000000 // Error
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/EhciPEI/EhciPei.c b/Core/EM/UsbRecovery/EhciPEI/EhciPei.c
new file mode 100644
index 0000000..a5f617f
--- /dev/null
+++ b/Core/EM/UsbRecovery/EhciPEI/EhciPei.c
@@ -0,0 +1,1847 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/EhciPei.c 14 11/24/12 5:44a Ryanchou $
+//
+// $Revision: 14 $
+//
+// $Date: 11/24/12 5:44a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/EhciPei.c $
+//
+// 14 11/24/12 5:44a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 13 9/28/12 2:56a Roberthsu
+// [TAG] EIP99922
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hanged on CP:9C during USB Recovery from cold
+// boot.
+// [RootCause] Usb controller need reset when pei exit.
+// [Solution] Reset usb controller when pei exit
+// [Files] EhciPei.c
+//
+// 12 8/23/12 9:57p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 11 8/09/11 4:59p Yul
+// [TAG] EIP60439
+// [Category] Improvement
+// [Description] Generically handle the assignments of MMIO base address
+// from Rx and UsbRecovery modules.
+// [Files] EhciPei.c
+//
+// 10 1/18/11 12:52a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 9 1/11/11 11:12a Olegi
+// [TAG] EIP51517
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Recovery fails when using USB port behind HUB
+// [RootCause] Port Power was not set
+// [Solution] Set Port Power if Port Power Control bit is 1.
+// [Files] EHCIPEI.C
+//
+// 8 10/11/10 4:51p Olegi
+// XHCI support added.
+//
+// 7 4/26/10 4:16p Krishnakumarg
+// DebugRx causes the system to hang in Recovery mode EIP#34401
+//
+// 6 10/20/09 9:15a Olegi
+// EIP#28255: EhciHcGetRootHubPortStatus returns proper status.
+//
+// 5 7/30/09 6:23p Krishnakumarg
+// Symptom :During recovery,system hangs while entering setup.
+// RootCause:USB Host controller Status registers are not cleared and HC
+// is not HALTed after loading recovery capsule.
+// Solution: HC is set to HALT state after loading recovery module so USB
+// driver clears the status Registers.
+//
+// 4 4/29/09 1:56p Rameshr
+// EHCIStopAsyncSchedule gets called always when the
+// EHCIStartAsyncSchedule function is called
+//
+// 3 3/17/09 5:08p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 2 3/04/09 11:56a Olegi
+//
+// 1 3/03/09 7:28p Olegi
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EhciPei.c
+//
+// Description:
+// This file is the main source file for the EHCI PEI USB
+// recovery module. Its entry point at EhciPeiUsbEntryPoint
+// will be executed from the UsbRecoveryInitialize INIT_LIST.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <PPI\PeiGetUCtrl.h>
+#include <PPI\stall.h>
+#include "Ppi\UsbHostController.h"
+#include "UsbPeim.h"
+#include "EhciPei.h"
+#include "usb.h"
+
+extern EFI_GUID gPeiStallPpiGuid;
+extern EFI_GUID gPeiUsbHostControllerPpiGuid;
+
+EFI_STATUS EhciPeiBoardInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi,
+ EFI_PEI_STALL_PPI *StallPpi );
+
+UINT32 gEhciControllerPciTable[] = PEI_EHCI_PCI_BDFS;
+UINT16 gEhciControllerCount = \
+ sizeof(gEhciControllerPciTable) / sizeof(UINT32);
+
+UINT32 gEhciControllerBaseAddress[] = PEI_EHCI_MEM_BASE_ADDRESSES;
+
+EFI_GUID guidEndOfPei = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+
+EFI_STATUS
+EFIAPI NotifyOnRecoveryCapsuleLoaded (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi );
+
+
+static EFI_PEI_NOTIFY_DESCRIPTOR lNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidEndOfPei,
+ NotifyOnRecoveryCapsuleLoaded
+};
+
+BOOLEAN EHCIDbg_PortUsed = FALSE;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciGetOperationalRegisterBase
+//
+// Description:
+// This function uses ControllerIndex and the global PCI_BUS_DEV_FUNCTION
+// array to access a particular controller's PCI configuration space in
+// order to obtain the Operational Register base address.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN UINT16 ControllerIndex
+// -- Index of the controller in the global
+// PCI_BUS_DEV_FUNCTION array
+//
+// Output:
+// UINT32 (Return Value)
+// = Base address for this controller's operational
+// registers.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 EhciGetOperationalRegisterBase (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 ControllerIndex )
+{
+ UINT32 EhciBaseAddress;
+
+ (*PeiServices)->PciCfg->Read(
+ PeiServices,
+ (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint32,
+ gEhciControllerPciTable[ControllerIndex] + EHCI_BASE_ADDR_REG,
+ &EhciBaseAddress
+ );
+
+ return EhciBaseAddress;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: Update_EHCIDbg_PortUsed
+//
+// Description:
+// Check debugport of a controlller is in use or not.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN UINT16 ControllerIndex
+// -- Index of the controller in the global
+// PCI_BUS_DEV_FUNCTION array
+//
+// Output :
+//
+// Note : EHCIDbg_PortUsed used to maintain the debugport usage of
+// CURRENT processing controller.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID Update_EHCIDbg_PortUsed(EFI_PEI_SERVICES **PeiServices,UINT8 Index)
+{
+ UINT8 CmdReg = 0;
+ UINT16 DebugBase = 0;
+ UINT32 EhciBaseMem = 0;
+
+//
+// Read Command register and check MMIO enabled or not
+//
+ (*PeiServices)->PciCfg->Read( PeiServices, (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint8,
+ gEhciControllerPciTable[Index] + EHCI_CMD_REGISTER,
+ &CmdReg );
+
+ if(!(CmdReg & 2)){ //MMIO is disabled
+ EHCIDbg_PortUsed = FALSE;
+ return;
+ }
+//
+// Retrieve the debugport base offset address
+//
+ (*PeiServices)->PciCfg->Read( PeiServices, (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint16,
+ gEhciControllerPciTable[Index] + DEBUG_BASE,
+ &DebugBase );
+
+ DebugBase = DebugBase & 0x1FFF; // Bar number hardwired to 001b
+
+ EhciBaseMem = EhciGetOperationalRegisterBase(PeiServices,Index);
+
+//
+// Check ENABLED_CNT bit of DEBUG status register
+//
+ if ((*(volatile UINT32*)(UINTN)(EhciBaseMem + DebugBase)) & BIT28){
+ EHCIDbg_PortUsed = TRUE;
+ }else{
+ EHCIDbg_PortUsed = FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciPeiUsbEntryPoint
+//
+// Description:
+// This is the entry point into the EHCI controller initialization
+// subsystem.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// -- EFI_FFS_FILE_HEADER pointer
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ UINT8 Index;
+ UINTN MemPages;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TempPtr;
+ PEI_EHCI_DEV *EhciDevPtr;
+ EFI_PEI_STALL_PPI *StallPpi;
+ UINT8 ByteData;
+
+ //-------------------------------------------
+ // Initialize the EFI_PEI_STALL_PPI interface
+ //-------------------------------------------
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //-----------------------------------------
+ // board specific initialization to program
+ // PCI bridges and enable MMIO
+ //-----------------------------------------
+
+ Status = EhciPeiBoardInit(
+ PeiServices,
+ (*PeiServices)->PciCfg,
+ StallPpi );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //----------------------------------------------------------
+ // Allocate EHCI DEVICE OBJECT that holds all necessary
+ // information for the Host Controller operational registers
+ // for each controller. Initialze the controller and setup
+ // data structures for ready for operation
+ //----------------------------------------------------------
+
+ for (Index = 0; Index < gEhciControllerCount; Index++)
+ {
+
+
+ if(!(EhciGetOperationalRegisterBase( PeiServices, Index ))){
+ // Program PCI BAR and command register
+ (*PeiServices)->PciCfg->Write( PeiServices, (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint32,
+ gEhciControllerPciTable[Index] + EHCI_BASE_ADDR_REG,
+ &gEhciControllerBaseAddress[Index] );
+ }
+
+ ByteData = 6; // Enable MMIO and BusMaster
+ (*PeiServices)->PciCfg->Write( PeiServices, (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint8,
+ gEhciControllerPciTable[Index] + EHCI_CMD_REGISTER,
+ &ByteData );
+
+
+ Update_EHCIDbg_PortUsed(PeiServices,Index);
+
+ // PAGESIZE = 0x1000
+ MemPages = sizeof (PEI_EHCI_DEV) / 0x1000 + 1;
+ Status = (**PeiServices).AllocatePages(
+ PeiServices,
+ EfiConventionalMemory,
+ MemPages,
+ &TempPtr
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ (**PeiServices).SetMem((VOID*)TempPtr, sizeof (PEI_EHCI_DEV), 0);
+
+ EhciDevPtr = (PEI_EHCI_DEV *) ( (UINTN) TempPtr );
+ EhciDevPtr->Signature = PEI_EHCI_DEV_SIGNATURE;
+ EhciDevPtr->PeiServices = PeiServices;
+ EhciDevPtr->CpuIoPpi = (*PeiServices)->CpuIo;
+ EhciDevPtr->StallPpi = StallPpi;
+ EhciDevPtr->PciCfgPpi = (*PeiServices)->PciCfg;
+
+ EhciDevPtr->UsbHostControllerBaseAddress =
+ EhciGetOperationalRegisterBase( PeiServices, Index );
+
+ //Initialize the EHCI Controller for operation
+
+ EhciInitHC( PeiServices, EhciDevPtr );
+
+ //Setup PPI entry point
+ EhciDevPtr->UsbHostControllerPpi.ControlTransfer = EhciHcControlTransfer;
+ EhciDevPtr->UsbHostControllerPpi.BulkTransfer = EhciHcBulkTransfer;
+ EhciDevPtr->UsbHostControllerPpi.GetRootHubPortNumber = EhciHcGetRootHubPortNumber;
+ EhciDevPtr->UsbHostControllerPpi.GetRootHubPortStatus = EhciHcGetRootHubPortStatus;
+ EhciDevPtr->UsbHostControllerPpi.SetRootHubPortFeature = EhciHcSetRootHubPortFeature;
+ EhciDevPtr->UsbHostControllerPpi.ClearRootHubPortFeature = EhciHcClearRootHubPortFeature;
+
+ EhciDevPtr->UsbHostControllerPpi.DebugPortUsed = EHCIDbg_PortUsed;
+ EhciDevPtr->UsbHostControllerPpi.PreConfigureDevice = NULL;
+ EhciDevPtr->UsbHostControllerPpi.EnableEndpoints = NULL;
+
+ EhciDevPtr->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ EhciDevPtr->PpiDescriptor.Guid = &gPeiUsbHostControllerPpiGuid;
+ EhciDevPtr->PpiDescriptor.Ppi = &EhciDevPtr->UsbHostControllerPpi;
+
+ //Now is the time to install the PPI
+ Status = (**PeiServices).InstallPpi( PeiServices, &EhciDevPtr->PpiDescriptor );
+ if ( EFI_ERROR( Status ) )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ }
+ (**PeiServices).NotifyPpi (PeiServices, &lNotifyList);
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciInitHC
+//
+// Description: EHCI controller initialization.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_EHCI_DEV *EhciDevPtr
+// -- PEI_EHCI_DEV pointer
+// IN UINT8 Index
+// -- Index of this controller in the global
+// PCI_BUS_DEV_FUNCTION array
+//
+// Output:
+// VOID (Return Value)
+//
+// Note:
+// EhciDevPtr->UsbHostControllerBaseAddress is is initialized
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EhciInitHC (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_EHCI_DEV *EhciDevPtr)
+{
+ UINT8 *pPtr;
+ UINTN MemPages;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TempPtr;
+ EHCI_HC_CAP_REG *EhciHcCapReg =
+ (EHCI_HC_CAP_REG *)(UINTN)EhciDevPtr->UsbHostControllerBaseAddress;
+ EHCI_HC_OPER_REG *EhciHcOpReg;
+ EHCI_DESC_PTRS *pstEHCIDescPtrs;
+
+
+ // Allocate memory for control transfers and bulk transfers
+ // Allocate a block of memory and define/initialize
+ // Setup Control and Bulk EDs/TDs
+ pstEHCIDescPtrs = &(EhciDevPtr->stEHCIDescPtrs);
+
+ MemPages = (( 4 * sizeof (EHCI_QTD) ) + (2 * sizeof(EHCI_QH) )) / 0x1000 + 1;
+ Status = (**PeiServices).AllocatePages(
+ PeiServices,
+ EfiConventionalMemory,
+ MemPages,
+ &TempPtr
+ );
+
+ pPtr = (UINT8 *) ( (UINTN) TempPtr );
+ if (pPtr == NULL) {
+ return;
+ }
+ MemSet( pPtr, 4 * sizeof (EHCI_QTD) + 2 * sizeof(EHCI_QH), 0 );
+
+ pstEHCIDescPtrs->fpQHControl = (EHCI_QH*) pPtr;
+ pPtr += sizeof (EHCI_QH);
+ pstEHCIDescPtrs->fpqTDControlSetup = (EHCI_QTD*) pPtr;
+ pPtr += sizeof (EHCI_QTD);
+ pstEHCIDescPtrs->fpqTDControlData = (EHCI_QTD*) pPtr;
+ pPtr += sizeof (EHCI_QTD);
+ pstEHCIDescPtrs->fpqTDControlStatus = (EHCI_QTD*) pPtr;
+ pPtr += sizeof (EHCI_QTD);
+ pstEHCIDescPtrs->fpQHBulk = (EHCI_QH*) pPtr;
+ pPtr += sizeof (EHCI_QH);
+ pstEHCIDescPtrs->fpqTDBulkData = (EHCI_QTD*) pPtr;
+
+ // Store number of downstream ports into PEI_EHCI_DEV struct
+ EhciDevPtr->bNumPorts = (UINT8)(EhciHcCapReg->HcsParams.Field.NumberOfPorts);
+
+ // Read the Capability Registers Length to find the Offset address for the
+ // beginning of the operational registers
+ EhciHcOpReg = (EHCI_HC_OPER_REG *)((UINTN)EhciHcCapReg + EhciHcCapReg->CapLength);
+ EhciDevPtr->EhciHcOpReg = EhciHcOpReg;
+
+ EhciDevPtr->HcStatus = 0;
+
+ // Do a Host Controller reset first
+ if(!EHCIDbg_PortUsed)
+ EhciHcReset( PeiServices, EhciDevPtr );
+
+ // Do not do any periodic schedule related initialization
+
+ // Clear status register - all R/WC bits
+ EhciHcOpReg->UsbSts.AllBits =
+ (EHCI_USB_INTERRUPT | // Interrupt
+ EHCI_USB_ERROR_INTERRUPT | // Error interrupt
+ EHCI_PORT_CHANGE_DETECT | // Port Change Detect
+ EHCI_FRAME_LIST_ROLLOVER | // Frame List Rollover
+ EHCI_HOST_SYSTEM_ERROR | // Host System Error
+ EHCI_INT_ASYNC_ADVANCE); // Interrupt on Async Advance
+
+ // Turn HC on
+ EhciHcOpReg->UsbCmd.AllBits = EHCI_RUNSTOP | EHCI_INTTHRESHOLD;
+
+ // Disconnect all ports from companion HC (if any) and route them to EHCI
+ EhciHcOpReg->ConfigFlag = 1;
+
+ EHCI_FIXED_DELAY_MS(EhciDevPtr, 100); // 100msec delay to stabilize
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcReset
+//
+// Description:
+// This function performs a software reset of the host controller.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_EHCI_DEV *EhciDevPtr
+// -- PEI_EHCI_DEV pointer
+//
+// Output:
+// VOID (Return Value)
+//
+// Notes:
+// It is assumed that all necessary operational register data has been
+// saved prior to calling this function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EhciHcReset (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_EHCI_DEV *EhciDevPtr )
+{
+ UINT32 UsbCmd;
+ UINT8 Count;
+
+ // Check HC is halted: attempting to reset an actively running HC will
+ // result in undefined behavior.
+ if (EhciDevPtr->EhciHcOpReg->UsbSts.Field.HCHalted == 0)
+ {
+ PEI_TRACE ((EFI_D_ERROR, PeiServices, "EHCI HC RESET ERROR: HC is running.\n"));
+ EhciDevPtr->HcStatus = EHCI_RESET_ERROR;
+ return;
+ }
+
+ // Issue reset
+ UsbCmd = EhciDevPtr->EhciHcOpReg->UsbCmd.AllBits | EHCI_HCRESET;
+ EhciDevPtr->EhciHcOpReg->UsbCmd.AllBits = UsbCmd;
+
+ // EHCI_HCRESET bit is set to zero by the Host Controller when the reset
+ // process is complete.
+ for (Count = 0; Count < 10; Count++)
+ {
+ EHCI_FIXED_DELAY_MS( EhciDevPtr, 10); // 10msec delay
+ if (EhciDevPtr->EhciHcOpReg->UsbCmd.Field.HcReset == 0)
+ {
+ return;
+ }
+ }
+
+ PEI_TRACE ((EFI_D_ERROR, PeiServices, "EHCI HC RESET ERROR: timeout.\n"));
+ EhciDevPtr->HcStatus = EHCI_RESET_ERROR;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciReleasePortOwner
+//
+// Description:
+//
+// Input:
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EhciReleasePortOwner (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_EHCI_DEV *EhciDevPtr,
+ UINT8 PortNumber
+)
+{
+ EHCI_PORTSC *PortScReg = &EhciDevPtr->EhciHcOpReg->PortSC[PortNumber - 1];
+ UINT8 i = 0;
+
+ // Clear connect status change bit
+ PortScReg->Field.ConnectStatusChange = 1;
+
+ // Release port owner
+ PortScReg->Field.PortOwner = 1;
+ for (i = 0; i < 20; i++) {
+ if (PortScReg->Field.ConnectStatusChange != 0) {
+ break;
+ }
+ EHCI_FIXED_DELAY_MS( EhciDevPtr, 1); // 1 msec delay
+ }
+
+ PortScReg->Field.ConnectStatusChange = 1;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcGetRootHubPortStatus
+//
+// Description:
+// This function obtains the port status and port change status for
+// a port specified by PortNumber and updates the EFI_USB_PORT_STATUS
+// data structure as specified the the PortStatus pointer parameter.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 PortNumber
+// -- Port number for which status is requested
+// OUT EFI_USB_PORT_STATUS *PortStatus
+// -- EFI_USB_PORT_STATUS pointer's data is updated
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciHcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus )
+{
+ PEI_EHCI_DEV *EhciDevPtr = PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( This );
+ EHCI_PORTSC *PortScReg = &EhciDevPtr->EhciHcOpReg->PortSC[PortNumber - 1];
+ UINT8 i = 0;
+
+ if (PortNumber > EhciDevPtr->bNumPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //PEI_TRACE((-1, PeiServices, "EHCI port[%d] status: %08x\n", PortNumber, PortScReg->AllBits));
+ PortStatus->PortStatus = 0;
+ PortStatus->PortChangeStatus = 0;
+
+ if (PortScReg->Field.CurrentConnectStatus != 0 &&
+ PortScReg->Field.PortEnable == 0 &&
+ PortScReg->Field.LineStatus == 0x1) {
+ EhciReleasePortOwner(PeiServices, EhciDevPtr, PortNumber);
+ }
+
+ if (PortScReg->Field.CurrentConnectStatus != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+ if (PortScReg->Field.PortEnable != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+ PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;
+ }
+ }
+ if (PortScReg->Field.ConnectStatusChange != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+ }
+ if (PortScReg->Field.PortEnableChange != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+ }
+ if (PortScReg->Field.OvercurrentActive != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;
+ }
+ if (PortScReg->Field.OvercurrentChange != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;
+ }
+ if (PortScReg->Field.Suspend != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+ }
+ if (PortScReg->Field.PortReset != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+ }
+ if (PortScReg->Field.PortPower != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_POWER;
+ }
+ if (PortScReg->Field.PortOwner != 1) {
+ PortStatus->PortStatus |= USB_PORT_STAT_OWNER;
+ }
+ if (EhciDevPtr->PortResetStatusChangeMap & (1 << (PortNumber - 1))) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_RESET;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcGetRootHubPortNumber
+//
+// Description:
+// This function returns the number of downstream ports as specified
+// in the HcRhDescriptorA operational register.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// OUT UINT8 *PortNumber
+// -- Number of downstream ports
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciHcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber )
+{
+
+ PEI_EHCI_DEV *EhciDevPtr = PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( This );
+
+ if (PortNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *PortNumber = EhciDevPtr->bNumPorts;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcSetRootHubPortFeature
+//
+// Description:
+// This function sets port feature as specified by
+// PortFeature for the port specified by PortNumber.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 PortNumber
+// -- Port number whose feature is to be set
+// IN EFI_USB_PORT_FEATURE PortFeature
+// -- Feature to set
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciHcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ PEI_EHCI_DEV *EhciDevPtr = PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( This );
+ EHCI_PORTSC *PortScReg = &EhciDevPtr->EhciHcOpReg->PortSC[PortNumber - 1];
+ UINT32 PortSc = 0;
+ UINT8 i = 0;
+
+ if (PortNumber > EhciDevPtr->bNumPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PortSc = PortScReg->AllBits;
+ PortSc &= ~(EHCI_CONNECTSTATUSCHANGE | EHCI_PORTENABLESTATUSCHANGE | EHCI_OVERCURRENTCAHGE);
+
+ switch (PortFeature) {
+ case EfiUsbPortEnable:
+ break;
+
+ case EfiUsbPortSuspend:
+ PortSc |= EHCI_SUSPEND;
+ break;
+
+ case EfiUsbPortReset:
+ PortSc = PortScReg->AllBits;
+ PortSc &= ~(EHCI_CONNECTSTATUSCHANGE | EHCI_PORTENABLESTATUSCHANGE | EHCI_OVERCURRENTCAHGE);
+ PortScReg->AllBits = (PortSc & ~EHCI_PORTENABLE) | EHCI_PORTRESET;
+ EHCI_FIXED_DELAY_MS( EhciDevPtr, 50); // 50 msec delay
+
+ PortSc = PortScReg->AllBits;
+ PortSc &= ~(EHCI_PORTRESET | EHCI_CONNECTSTATUSCHANGE | EHCI_PORTENABLESTATUSCHANGE |
+ EHCI_OVERCURRENTCAHGE);
+ PortScReg->AllBits = PortSc;
+
+ for (i = 0; i < 10; i++) {
+ if (PortScReg->Field.PortReset == 0) {
+ break;
+ }
+ EHCI_FIXED_DELAY_MS( EhciDevPtr, 1); // 50 msec delay
+ }
+
+ if (PortScReg->Field.PortEnable != 0) {
+ EhciDevPtr->PortResetStatusChangeMap |= (1 << (PortNumber - 1));
+ } else {
+ EhciReleasePortOwner(PeiServices, EhciDevPtr, PortNumber);
+ }
+ //break;
+ return EFI_SUCCESS;
+
+ case EfiUsbPortPower:
+ PortSc |= EHCI_PORTPOWER;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ PortScReg->AllBits = PortSc;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcClearRootHubPortFeature
+//
+// Description:
+// This function clears an EHCI specification port feature as specified
+// by PortFeature for the port specified by PortNumber.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 PortNumber
+// -- Port number whose feature is to be set
+// IN EFI_USB_PORT_FEATURE PortFeature
+// -- Feature to set
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciHcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ PEI_EHCI_DEV *EhciDevPtr = PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( This );
+ UINT32 PortSc = 0;
+
+ if (PortNumber > EhciDevPtr->bNumPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PortSc = EhciDevPtr->EhciHcOpReg->PortSC[PortNumber - 1].AllBits;
+ PortSc &= ~(EHCI_CONNECTSTATUSCHANGE | EHCI_PORTENABLESTATUSCHANGE | EHCI_OVERCURRENTCAHGE);
+
+ switch (PortFeature) {
+ case EfiUsbPortEnable:
+ PortSc &= ~EHCI_PORTENABLE;
+ break;
+
+ case EfiUsbPortSuspend:
+ PortSc |= EHCI_FORCEPORTRESUME;
+ break;
+
+ case EfiUsbPortReset:
+ PortSc &= ~EHCI_PORTRESET;
+ break;
+
+ case EfiUsbPortPower:
+ PortSc &= ~EHCI_PORTPOWER;
+ break;
+
+ case EfiUsbPortOwner:
+ //PortSc |= EHCI_PORTOWNER;
+ EhciReleasePortOwner(PeiServices, EhciDevPtr, PortNumber);
+ //break;
+ return EFI_SUCCESS;
+
+ case EfiUsbPortConnectChange:
+ PortSc |= EHCI_CONNECTSTATUSCHANGE;
+ break;
+
+ case EfiUsbPortEnableChange:
+ PortSc |= EHCI_PORTENABLESTATUSCHANGE;
+ break;
+
+ case EfiUsbPortSuspendChange:
+ break;
+
+ case EfiUsbPortOverCurrentChange:
+ PortSc |= EHCI_OVERCURRENTCAHGE;
+ break;
+
+ case EfiUsbPortResetChange:
+ EhciDevPtr->PortResetStatusChangeMap &= ~(1 << (PortNumber - 1));
+ //break;
+ return EFI_SUCCESS;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ EhciDevPtr->EhciHcOpReg->PortSC[PortNumber - 1].AllBits = PortSc;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EHCIInitializeQueueHead
+//
+// Description: This function initializes the queue head with default values
+//
+// Input: fpQH Pointer to queue head
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EHCIInitializeQueueHead(EHCI_QH *fpQH)
+{
+ fpQH->dNextqTDPtr = 1;
+ fpQH->dAltNextqTDPtr = 1;
+ fpQH->dCurqTDPtr = 1;
+
+ fpQH->dEndPntCap = QH_ONE_XFER;
+ fpQH->dToken = 0;
+ fpQH->dEndPntCharac = 0;
+ fpQH->dBufferPtr0 = 0;
+ fpQH->dBufferPtr1 = 0;
+ fpQH->dBufferPtr2 = 0;
+ fpQH->dBufferPtr3 = 0;
+ fpQH->dBufferPtr4 = 0;
+ fpQH->bErrorStatus = 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EHCISetQTDBufferPointers
+//
+// Description: This function will set the 5 buffer pointer in the qTD
+// appropriately depending upon the input size
+//
+// Input: fpQtd - Pointer to the qTD
+// fpBuf - 32bit absolute buffer pointer
+// wSize - Amount of data to be transferred
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EHCISetQTDBufferPointers(
+ EHCI_QTD *fpQtd,
+ UINT8 *fpBuf,
+ UINT32 dSize
+)
+{
+ UINT16 wBufSize;
+ UINT8 *fpBuffer = fpBuf;
+ UINT32 *fpBufferPtr;
+ UINT16 w4KRemainder;
+
+ //
+ // Fill the buffer pointers with 0s
+ //
+ fpQtd->dBufferPtr0 = 0;
+ fpQtd->dBufferPtr1 = 0;
+ fpQtd->dBufferPtr2 = 0;
+ fpQtd->dBufferPtr3 = 0;
+ fpQtd->dBufferPtr4 = 0;
+ fpQtd->dAltNextqTDPtr = 1;
+
+ //
+ // If size to transfer is 0 skip updating pointers
+ //
+ if (!dSize)
+ {
+ return;
+ }
+
+ //
+ // Make sure the amount of data to be xferred is 16K or less
+ //
+ wBufSize = (UINT16)((dSize > PEI_MAX_EHCI_DATA_SIZE) ? PEI_MAX_EHCI_DATA_SIZE : dSize);
+
+ fpBufferPtr = &fpQtd->dBufferPtr0;
+
+ for (;;)
+ {
+ *fpBufferPtr = (UINT32)(UINTN)fpBuffer;
+ //
+ // Calculate the number of bytes that can be transferred using current
+ // buffer pointer
+ //
+ w4KRemainder = (UINT16)((((UINT32)((UINTN)fpBuffer+0x1000)) & 0xFFFFF000) -
+ (UINT32)(UINTN)fpBuffer);
+
+ //
+ // Check whether all the bytes can be accomadated in the current buffer
+ //
+ if (w4KRemainder >= wBufSize)
+ {
+ break; // Yes. Current Buffer is sufficient for the rest of data
+ }
+
+ //
+ // We have more data to transfer - adjust data and store it in the next pointer
+ //
+ wBufSize = (UINT16)(wBufSize - w4KRemainder); // Amount of data remaining
+ fpBuffer = fpBuffer + w4KRemainder; // Adjust buffer (4K bound)
+ fpBufferPtr++; // Next buffer pointer
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStartAsyncSchedule
+//
+// Description: This function starts the asynchronous schedule
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EHCIStartAsyncSchedule(
+ EHCI_HC_OPER_REG *HcOpReg
+)
+{
+ // Start the Async schedule
+ HcOpReg->UsbCmd.AllBits |= EHCI_ASYNC_SCHED_ENABLE;
+
+ // Make sure the HC started the async. execution
+ for (;HcOpReg->UsbSts.Field.AsyncSheduleStatus == 0;) {}
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStopAsyncSchedule
+//
+// Description: This function stops the asynchronous transfer and sets the
+// asynchronous pointer to null
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EHCIStopAsyncSchedule(
+ EHCI_HC_OPER_REG *HcOpReg
+)
+{
+ // Stop the Async schedule
+ HcOpReg->UsbCmd.AllBits &= ~EHCI_ASYNC_SCHED_ENABLE;
+
+ // Make sure the HC stopped the async. execution
+ for (;HcOpReg->UsbSts.Field.AsyncSheduleStatus != 0;) {}
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EHCIProcessQH
+//
+// Description: This function whether all the TD's in the QH is completed
+//
+// Input: fpQH - Pointer to the QH which has to be completed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EHCIProcessQH(
+ EHCI_QH *fpQH
+)
+{
+ EHCI_QTD *fpQTD = fpQH->fpFirstqTD;
+
+ for (;;) {
+ //
+ // Check whether the qTD is active, if so. Exit!
+ //
+ if (fpQTD->dToken & QTD_ACTIVE) {
+ return; // Not complete
+ }
+
+ //
+ // Check for halt condition, if halted - exit
+ //
+ if (fpQTD->dToken & QTD_HALTED) {
+ //
+ // Set the QH halted status
+ //
+ fpQH->bErrorStatus = QTD_HALTED;
+ //
+ // Set the QH as in-active
+ //
+ fpQH->bActive = FALSE;
+
+ return; // Complete
+ }
+ //
+ // qTD is not active and not halted. That is it is completed successfully
+ // Check whether this qTD is the last one in the list
+ //
+ if (fpQTD->dNextqTDPtr & EHCI_TERMINATE) {
+ //
+ // Set the QH as in-active
+ //
+ fpQH->bActive = FALSE;
+ return; // Complete
+ }
+ //
+ // More qTDs are in the list. Process next qTD
+ //
+ fpQTD = (EHCI_QTD*)(UINTN)fpQTD->dNextqTDPtr;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIWaitForAsyncTransferComplete
+//
+// Description: This function waits for asynchronous transfer completion.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EHCIWaitForAsyncTransferComplete (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_EHCI_DEV *EhciDevPtr,
+ EHCI_QH *QHead
+)
+{
+ UINT32 Count;
+ UINT32 TimeOut = 15000; // 5 sec
+
+ for(Count = 0; Count < TimeOut; Count++)
+ {
+ EHCIProcessQH(QHead);
+
+ if(QHead->bActive == FALSE)
+ {
+ return;
+ }
+ EHCI_FIXED_DELAY_MS( EhciDevPtr, 1); // 1 msec delay
+ }
+
+ PEI_TRACE ((EFI_D_ERROR, PeiServices, "EHCI Time-Out:\n"));
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcControlTransfer
+//
+// Description:
+// This function intiates a USB control transfer and waits on it to
+// complete.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 bDeviceAddress
+// -- USB address of the device for which the control
+// transfer is to be issued
+// IN UINT8 DeviceSpeed
+// -- Not used
+// IN UINT8 MaximumPacketLength
+// -- Maximum number of bytes that can be sent to or
+// received from the endpoint in a single data packet
+// IN EFI_USB_DEVICE_REQUEST *Request
+// -- EFI_USB_DEVICE_REQUEST pointer
+// IN EFI_USB_DATA_DIRECTION TransferDirection
+// -- Direction of transfer
+// OPTIONAL IN OUT VOID *DataBuffer
+// -- Pointer to source or destination buffer
+// OPTIONAL IN OUT UINTN *DataLength
+// -- Length of buffer
+// IN UINTN TimeOut
+// -- Not used
+// OUT UINT32 *TransferResult
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciHcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 bDeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *DataBuffer OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ UINT16 WordRequest;
+ UINT16 WordIndex;
+ UINT16 WordValue;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+
+ PEI_EHCI_DEV *EhciDevPtr = PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( This );
+ EHCI_HC_OPER_REG *HcOpReg = EhciDevPtr->EhciHcOpReg;
+ EHCI_DESC_PTRS *DescPtrs = &EhciDevPtr->stEHCIDescPtrs;
+ UINT16 wLength = (DataLength != NULL)? (UINT16) *DataLength : 0;
+ EHCI_QH *fpQHCtl;
+ EHCI_QTD *fpQTDCtlSetup, *fpQTDCtlData, *fpQTDCtlStatus;
+
+ UINT32 dTmp, dTmp1;
+
+ WordRequest = (Request->Request << 8) | Request->RequestType;
+ WordValue = Request->Value;
+ WordIndex = Request->Index;
+
+ //
+ // Intialize the queue head with null pointers
+ //
+ fpQHCtl = DescPtrs->fpQHControl;
+ EHCIInitializeQueueHead(fpQHCtl);
+
+ //
+ // Assume as a high speed device
+ //
+ dTmp = QH_HIGH_SPEED; // 10b - High speed
+
+ if (DeviceSpeed != USB_HIGH_SPEED_DEVICE && TransactionTranslator != 0)
+ {
+ // Low/Full speed device OR device is connected to a root port
+ // DeviceSpeed = 1 (low) or 2 (full)
+ dTmp = (UINT32)((DeviceSpeed & 1) << 12); // Bit 12 = full/low speed flag
+ dTmp |= QH_CONTROL_ENDPOINT;
+ //
+ // Set the hub address and port number
+ //
+ dTmp1 = (TransactionTranslator << 16) | (BIT10+BIT11+BIT12); // Split complete Xaction
+ fpQHCtl->dEndPntCap |= dTmp1;
+ }
+
+ dTmp |= (QH_USE_QTD_DT | QH_HEAD_OF_LIST);
+ dTmp |= (UINT32)bDeviceAddress;
+
+ //
+ // dTmp[Bits 6:0] = Dev. Addr
+ // dTmp[Bit7] = I bit(0)
+ // dTmp[Bits11:8] = Endpoint (0)
+ //
+ dTmp1 = MaximumPacketLength;
+ dTmp |= (dTmp1 << 16); // Tmp[Bits26:16] = device's packet size
+ fpQHCtl->dEndPntCharac = dTmp;
+
+ //
+ // Fill in various fields in the qTDControlSetup.
+ //
+ fpQTDCtlSetup = DescPtrs->fpqTDControlSetup;
+
+ //
+ // The token field will be set so
+ // Direction PID = QTD_SETUP_TOKEN,
+ // Size = size of the data,
+ // Data Toggle = QTD_SETUP_TOGGLE,
+ // Error Count = QTD_NO_ERRORS,
+ // Status code = QTD_DO_OUT + QTD_ACTIVE
+ // The buffer pointers field will point to the aControlSetupData buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The dNextqTDPtr field will point to the qTDControlData if data will
+ // be sent/received or to the qTDControlStatus if no data is expected.
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ fpQTDCtlSetup->dToken = QTD_SETUP_TOKEN | QTD_SETUP_TOGGLE | QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_DO_OUT | QTD_ACTIVE |
+ (8 << 16); // Data size
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(fpQTDCtlSetup,
+ (UINT8*)Request,
+ 8);
+ fpQTDCtlData = DescPtrs->fpqTDControlData;
+
+ if (wLength != 0 && DataBuffer != NULL) // br if no data to transfer
+ {
+ //
+ // Fill in various fields in the qTDControlData
+ //
+ // The token field will be set so
+ // Direction PID = QTD_OUT_TOKEN/QTD_IN_TOKEN,
+ // Size = size of the data,
+ // Data Toggle = QTD_DATA1_TOGGLE,
+ // Error Count = QTD_NO_ERRORS,
+ // Status code = QTD_DO_OUT(if it is out) + QTD_ACTIVE
+ // The buffer pointers field will point to the fpBuffer buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The dNextqTDPtr field will point to the qTDControlSetup
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ fpQTDCtlData->dToken = QTD_IN_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_ACTIVE;
+ if ((WordRequest & BIT7) == 0) // Br if host sending data to device (OUT)
+ {
+ fpQTDCtlData->dToken = QTD_OUT_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_DO_OUT | QTD_ACTIVE;
+ }
+
+ //
+ // Set length
+ //
+ fpQTDCtlData->dToken |= ((UINT32)wLength << 16);
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(fpQTDCtlData,
+ (UINT8*)DataBuffer,
+ (UINT32)wLength);
+ }
+
+ //
+ // Fill in various fields in the qTDControlStatus
+ //
+ fpQTDCtlStatus = DescPtrs->fpqTDControlStatus;
+
+ //
+ // The token field will be set so
+ // Direction PID = QTD_OUT_TOKEN/QTD_IN_TOKEN,
+ // Size = 0,
+ // Data Toggle = QTD_DATA1_TOGGLE,
+ // Error Count = QTD_NO_ERRORS,
+ // Status code = QTD_DO_OUT(if it is out) + QTD_ACTIVE
+ // The buffer pointers field will be 0
+ // The dNextqTDPtr field will set to EHCI_TERMINATE
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ // For OUT control transfer status should be IN and
+ // for IN cotrol transfer, status should be OUT
+ //
+ fpQTDCtlStatus->dToken = QTD_IN_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_ACTIVE;
+ if((WordRequest & BIT7) != 0)
+ {
+ fpQTDCtlStatus->dToken = QTD_OUT_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_DO_OUT | QTD_ACTIVE;
+ }
+
+ EHCISetQTDBufferPointers(fpQTDCtlStatus, NULL, 0);
+
+ //
+ // Link the qTD formed now and connect them with the control queue head
+ //
+ fpQHCtl->fpFirstqTD = fpQTDCtlSetup;
+ fpQHCtl->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlSetup;
+
+ if (wLength != 0)
+ {
+ fpQTDCtlSetup->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlData;
+ fpQTDCtlData->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlStatus;
+ }
+ else
+ {
+ fpQTDCtlSetup->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlStatus;
+ }
+
+ fpQTDCtlStatus->dNextqTDPtr = EHCI_TERMINATE;
+
+ //
+ // Set the ASYNCLISTADDR register to point to the QHControl
+ //
+ HcOpReg->AsyncListAddr = (UINT32)(UINTN)fpQHCtl;
+
+ //
+ // Set next QH pointer to itself (circular link)
+ //
+ fpQHCtl->dLinkPointer = (UINT32)((UINTN)fpQHCtl | EHCI_QUEUE_HEAD);
+ fpQHCtl->bActive = TRUE;
+
+ //
+ // Now put the control setup, data and status into the HC's schedule by
+ // setting the Async. schedule enabled field of USBCMD register
+ // This will cause the HC to execute the transaction in the next active frame.
+ //
+ EHCIStartAsyncSchedule(HcOpReg);
+
+ EHCIWaitForAsyncTransferComplete(PeiServices, EhciDevPtr, fpQHCtl);
+
+ //
+ // Stop the Async transfer
+ //
+ EHCIStopAsyncSchedule(HcOpReg);
+
+ //
+ // Check whether the QH stopped or timed out
+ //
+ if (fpQHCtl->bActive == TRUE)
+ {
+
+ fpQHCtl->bActive = FALSE;
+ }
+ else
+ {
+ //
+ // Check for the stall condition
+ //
+ if (fpQHCtl->bErrorStatus & QTD_HALTED)
+ {
+ //
+ // Command stalled set the error bit appropriately
+ //
+ Status = EFI_DEVICE_ERROR;
+ }
+ }
+
+ fpQHCtl->fpFirstqTD = 0;
+ fpQHCtl->dNextqTDPtr = EHCI_TERMINATE;
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciHcBulkTransfer
+//
+// Description:
+// This function intiates a USB bulk transfer and waits on it to
+// complete.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 DeviceAddress
+// -- USB address of the device for which the control
+// transfer is to be issued
+// IN UINT8 EndPointAddress
+// -- Particular endpoint for the device
+// IN UINT8 MaximumPacketLength
+// -- Maximum number of bytes that can be sent to or
+// received from the endpoint in a single data packet
+// OPTIONAL IN OUT VOID *DataBuffer
+// -- Pointer to source or destination buffer
+// OPTIONAL IN OUT UINTN *DataLength
+// -- Length of buffer
+// IN OUT UINT8 *DataToggle
+// -- Used to update the control/status DataToggle field
+// of the Transfer Descriptor
+// IN UINTN TimeOut
+// -- Not used
+// OUT UINT32 *TransferResult
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciHcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *DataBuffer,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ PEI_EHCI_DEV *EhciDevPtr = PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( This );
+ EHCI_HC_OPER_REG *HcOpReg = EhciDevPtr->EhciHcOpReg;
+ EHCI_DESC_PTRS *DescPtrs = &EhciDevPtr->stEHCIDescPtrs;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 dBytesToTransfer;
+ UINT32 dTmp, dTmp1;
+ EHCI_QH *fpQHBulk;
+ EHCI_QTD *fpQTDBulkData;
+
+//PEI_TRACE ((EFI_D_ERROR, PeiServices, "bulk..%x, device address %d\n", *DataLength, DeviceAddress));
+
+ dBytesToTransfer =
+ (*DataLength < PEI_MAX_EHCI_DATA_SIZE)? (UINT32)*DataLength : PEI_MAX_EHCI_DATA_SIZE;
+
+ //
+ // Set the QH's dNextqTDPtr field to bulk data qTD and dAltqTDPtr field to
+ // EHCI_TERMINATE. Also set QH's link pointer to itself
+ //
+ fpQHBulk = DescPtrs->fpQHBulk;
+ fpQTDBulkData = DescPtrs->fpqTDBulkData;
+
+ //
+ // Intialize the queue head
+ //
+ EHCIInitializeQueueHead(fpQHBulk);
+
+ //
+ // Set the first qTD pointer
+ //
+ fpQHBulk->fpFirstqTD = fpQTDBulkData;
+ fpQHBulk->dNextqTDPtr = (UINT32)(UINTN)fpQTDBulkData;
+ fpQHBulk->dLinkPointer = (UINT32)((UINTN)fpQHBulk | EHCI_QUEUE_HEAD);
+
+ //
+ // Device address, Endpoint, max packet size, data toggle control
+ //
+ dTmp = (UINT32)(DeviceAddress | (EndPointAddress << 8));
+ dTmp |= ((UINT32)MaximumPacketLength << 16);
+ dTmp |= (QH_USE_QTD_DT | QH_HEAD_OF_LIST);
+
+ //
+ // Assume as a high speed device
+ //
+ dTmp |= QH_HIGH_SPEED; // 10b - High speed
+
+ if (DeviceSpeed != USB_HIGH_SPEED_DEVICE && TransactionTranslator != 0)
+ {
+ // Note: low speed bulk endpoints are not supported
+ dTmp1 = BIT12; // Bit 12 = full speed flag
+ dTmp &= ~(QH_ENDPOINT_SPEED);
+ dTmp |= dTmp1;
+ //
+ // Set the hub address and port number
+ //
+ dTmp1 = (TransactionTranslator << 16) | BIT14; // Hispeed hub port number & device number
+ fpQHBulk->dEndPntCap |= dTmp1; // Split complete Xaction
+ }
+
+ //
+ // Update the endpoint characteristcs field with the data formed
+ //
+ fpQHBulk->dEndPntCharac = dTmp;
+
+ //
+ // Fill the bulk data qTD with relevant information
+ //
+ if ((EndPointAddress & BIT7) != 0)
+ {
+ fpQTDBulkData->dToken = QTD_IN_TOKEN |
+ QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_ACTIVE;
+ }
+ else
+ {
+ fpQTDBulkData->dToken = QTD_OUT_TOKEN |
+ QTD_IOC_BIT |
+ QTD_NO_ERRORS | QTD_DO_OUT | QTD_ACTIVE;
+ }
+
+ //
+ // Set the data toggle depending on the DatToggle value
+ //
+ fpQTDBulkData->dToken |= ((UINT32)(*DataToggle)) << 31;
+
+ //
+ // Set length
+ //
+ fpQTDBulkData->dToken |= (dBytesToTransfer << 16);
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(
+ fpQTDBulkData, (UINT8*)DataBuffer, dBytesToTransfer);
+
+ //
+ // Update next & alternate next qTD pointers
+ //
+ fpQTDBulkData->dNextqTDPtr = EHCI_TERMINATE;
+ fpQTDBulkData->dAltNextqTDPtr = EHCI_TERMINATE;
+
+ //
+ // Set the ASYNCLISTADDR register to point to the QHBulk
+ //
+ HcOpReg->AsyncListAddr = (UINT32)(UINTN)fpQHBulk;
+
+ fpQHBulk->bActive = TRUE;
+
+ //
+ // Now put the bulk QH into the HC's schedule by
+ // setting the Async. schedule enabled field of USBCMD register
+ // This will cause the HC to execute the transaction in the next active frame.
+ //
+ EHCIStartAsyncSchedule(HcOpReg);
+
+ EHCIWaitForAsyncTransferComplete(PeiServices, EhciDevPtr, fpQHBulk);
+
+ //
+ // Stop the Async transfer
+ //
+ EHCIStopAsyncSchedule(HcOpReg);
+
+ dTmp = 0; // Return value
+
+ //
+ // Check whether the QH stopped or timed out
+ //
+ if(fpQHBulk->bActive == TRUE)
+ {
+
+ fpQHBulk->bActive = FALSE;
+
+ //
+ // TODO: Set time out status
+ //
+ Status = EFI_DEVICE_ERROR;
+ }
+ else
+ {
+ //
+ // Check for the error conditions - if possible recover from them
+ //
+ if (fpQHBulk->bErrorStatus & QTD_HALTED)
+ {
+ //
+ // TODO:: Indicate Stall condition
+ //
+ Status = EFI_DEVICE_ERROR;
+ }
+ else
+ {
+ dTmp = 0xFFFFFFFF; // Indicate success
+ }
+ }
+ if (dTmp != 0)
+ {
+ *DataToggle = (UINT8)(((fpQHBulk->dToken & QH_DATA_TOGGLE) >> 31) & 1);
+ //
+ // Get the size of data transferred
+ //
+ dTmp = (fpQTDBulkData->dToken & ~(QTD_DATA_TOGGLE)) >> 16;
+ dTmp = (dTmp != 0)? dBytesToTransfer-dTmp : dBytesToTransfer;
+ }
+
+ fpQHBulk->fpFirstqTD = 0;
+ fpQHBulk->dNextqTDPtr = EHCI_TERMINATE;
+
+ *DataLength = (UINTN)dTmp;
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordReadMem
+//
+// Description: This routine reads a DWORD from the specified Memory Address
+//
+// Input: dBaseAddr - Memory address to read
+// bOffset - Offset of dBaseAddr
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+DwordReadMem(UINT32 dBaseAddr, UINT16 wOffset)
+{
+ return *(volatile UINT32*)(UINTN)(dBaseAddr+wOffset);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordWriteMem
+//
+// Description: This routine writes a DWORD to a specified Memory Address
+//
+// Input: dBaseAddr - Memory address to write
+// bOffset - Offset of dBaseAddr
+// dValue - Data to write
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+DwordWriteMem(UINT32 dBaseAddr, UINT16 wOffset, UINT32 dValue)
+{
+ *(volatile UINT32*)(UINTN)(dBaseAddr+wOffset) = dValue;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: NotifyOnRecoveryCapsuleLoaded
+//
+// Description: This routine halts the all available EHCI host controller
+//
+// Input: PeiServices
+// dMemAddr - EHCI HC Mem_Base address
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS NotifyOnRecoveryCapsuleLoaded (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi )
+{
+ //(EIP99922)>
+ EFI_PEI_STALL_PPI *StallPpi = NULL;
+ EFI_GUID gPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+ EFI_STATUS Status;
+ UINT8 ControllerIndex = 0;
+ EHCI_HC_CAP_REG *EhciHcCapReg;
+ EHCI_HC_OPER_REG *EhciHcOpReg;
+ UINTN i;
+ UINT8 ByteData;
+ UINT32 EhciBaseAddress;
+
+ // Locate PeiStall
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &StallPpi
+ );
+
+ for ( ControllerIndex = 0; ControllerIndex < gEhciControllerCount; ControllerIndex++) {
+
+ EhciBaseAddress = EhciGetOperationalRegisterBase(PeiServices, ControllerIndex);
+
+ //
+ // Read the Capability Registers Length to find the Offset address for the
+ // beginning of the operational registers and set bMemAddr to its offset
+ //
+ EhciHcCapReg = (EHCI_HC_CAP_REG*)EhciBaseAddress;
+ EhciHcOpReg = (EHCI_HC_OPER_REG *)((UINTN)EhciHcCapReg + EhciHcCapReg->CapLength);
+
+ // Stop periodic schedule
+ EhciHcOpReg->UsbCmd.AllBits &= ~EHCI_PER_SCHED_ENABLE;
+ for (i = 0; i < 100; i++) {
+ StallPpi->Stall (PeiServices, StallPpi, 10); // 10us delay
+ if (EhciHcOpReg->UsbSts.Field.PeriodicSheduleStatus == 0) {
+ break;
+ }
+ }
+ EhciHcOpReg->PeriodicListBase = 0;
+
+ // Clear USB status register
+ EhciHcOpReg->UsbSts.AllBits = EhciHcOpReg->UsbSts.AllBits;
+ //
+ // Check HC is runnning, if so STOP before proceeding
+ //
+ if (EhciHcOpReg->UsbSts.Field.HCHalted == 0) {
+ EhciHcOpReg->UsbCmd.AllBits &= ~(EHCI_RUNSTOP | EHCI_PER_SCHED_ENABLE);
+ for (i = 0; i < 16; i++) {
+ StallPpi->Stall (PeiServices, StallPpi, 125); // 125us delay
+ if (EhciHcOpReg->UsbSts.Field.HCHalted) {
+ break;
+ }
+ }
+ }
+
+ // Reset controller
+ EhciHcOpReg->UsbCmd.Field.HcReset = 1;
+ for (i = 0; i < 100; i++) {
+ StallPpi->Stall (PeiServices, StallPpi, 1000); // 1ms delay
+ if (EhciHcOpReg->UsbCmd.Field.HcReset == 0) {
+ break;
+ }
+ }
+
+ ByteData= 0;
+ (*PeiServices)->PciCfg->Write( PeiServices, (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint8,
+ gEhciControllerPciTable[ControllerIndex] + EHCI_CMD_REGISTER,
+ &ByteData);
+
+ EhciBaseAddress = 0;
+ (*PeiServices)->PciCfg->Write( PeiServices, (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint32,
+ gEhciControllerPciTable[ControllerIndex] + EHCI_BASE_ADDR_REG,
+ &EhciBaseAddress);
+ }//end of for
+ //<(EIP99922)
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/EhciPEI/EhciPei.cif b/Core/EM/UsbRecovery/EhciPEI/EhciPei.cif
new file mode 100644
index 0000000..6bc2930
--- /dev/null
+++ b/Core/EM/UsbRecovery/EhciPEI/EhciPei.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "EhciPei"
+ category = ModulePart
+ LocalRoot = "core\em\UsbRecovery\EhciPEI\"
+ RefName = "EhciPei"
+[files]
+"EhciPei.c"
+"EhciPei.h"
+"EhciPeiBoard.c"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/EhciPEI/EhciPei.h b/Core/EM/UsbRecovery/EhciPEI/EhciPei.h
new file mode 100644
index 0000000..7f7c2c6
--- /dev/null
+++ b/Core/EM/UsbRecovery/EhciPEI/EhciPei.h
@@ -0,0 +1,592 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/EhciPei.h 8 11/24/12 5:44a Ryanchou $
+//
+// $Revision: 8 $
+//
+// $Date: 11/24/12 5:44a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/EhciPei.h $
+//
+// 8 11/24/12 5:44a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 7 8/23/12 9:58p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 6 1/18/11 12:53a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 5 4/26/10 4:16p Krishnakumarg
+// DebugRx causes the system to hang in Recovery mode EIP#34401
+//
+// 4 7/30/09 6:23p Krishnakumarg
+// Symptom :During recovery,system hangs while entering setup.
+// RootCause:USB Host controller Status registers are not cleared and HC
+// is not HALTed after loading recovery capsule.
+// Solution: HC is set to HALT state after loading recovery module so USB
+// driver clears the status Registers.
+//
+// 3 5/01/09 9:27a Rameshr
+// Symptom :Sometime system hang on recovery path.
+// Issue: Optimization makes Usbstatus value not updated from memory
+// everytime before checking it.
+// Solution: UsbStatus made as Volatile to get the current data from
+// memory before checking.
+//
+// 2 3/17/09 5:08p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 1 3/03/09 7:28p Olegi
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EhciPei.h
+//
+// Description: This file is the main header file for the EHCI PEI USB
+// recovery module. It contains generic constant and type
+// declarations/definitions.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _EHCIPEI_H
+#define _EHCIPEI_H
+
+#include "Efi.h"
+#include "Pei.h"
+#include "Ppi\UsbHostController.h"
+#include "AmiMapping.h"
+
+//----------------------------------------------------------------------------
+// EHCI_FIXED_DELAY_MS( EhciDevPtr, milliseconds )
+//
+// invokes a delay specified in milliseconds using the PEI_EHCI_DEV.StallPpi
+// member interface pointer, which is initialized from a EFI_PEI_STALL_PPI
+// interface.
+#define EHCI_FIXED_DELAY_MS( EhciDevPtr, milliseconds ) \
+ EhciDevPtr->StallPpi->Stall( EhciDevPtr->PeiServices, \
+ EhciDevPtr->StallPpi, milliseconds * 1000 );
+
+
+//----------------------------------------------------------------------------
+// PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( a )
+//
+// uses the _CR macro to obtain a pointer to a PEI_EHCI_DEV structure from
+// a PEI_USB_HOST_CONTROLLER_PPI interface pointer
+#define _CR( Record, TYPE, Field ) \
+ ( (TYPE *) ( (CHAR8 *) (Record) - (CHAR8 *) &( ( (TYPE *) 0 )->Field ) ) )
+#define PEI_RECOVERY_USB_EHCI_DEV_FROM_THIS( a ) \
+ _CR( a, PEI_EHCI_DEV, UsbHostControllerPpi )
+
+
+//----------------------------------------------------------------------------
+// Constants
+//
+// Notes:
+// 1) These constants are not associated with a particular structure
+// and are used globally withing EHCI-specific code
+//----------------------------------------------------------------------------
+
+
+
+// Standard EHCI PCI configuration space registers
+#define EHCI_BASE_ADDR_REG 0x10 // EHCI BAR register
+#define EHCI_CMD_REGISTER 0x04 // EHCI command register
+#define DEBUG_BASE 0x5A // DEBUG_BASE offset address
+
+// EHCI controller status definitions
+#define EHCI_RESET_ERROR BIT0
+#define EHCI_VERCAPLENGTH 0 // Interface Version and Capability
+#define EHCI_USBCMD_REG 0 // USB Command
+
+// Bit definition for queue transfer descriptor token fields
+//-------------------------------------------------------------------------
+#define QTD_DATA_TOGGLE 0x80000000 // BIT 31
+ #define QTD_SETUP_TOGGLE 0x00000000
+ #define QTD_DATA0_TOGGLE 0x00000000
+ #define QTD_DATA1_TOGGLE 0x80000000
+ #define QTD_STATUS_TOGGLE 0x80000000
+#define QTD_XFER_DATA_SIZE 0x7FFF0000 // BIT 30:16
+#define QTD_IOC_BIT 0x00008000 // BIT 15
+#define QTD_ERROR_COUNT 0x00000C00
+ #define QTD_NO_ERRORS 0x00000000
+ #define QTD_ONE_ERROR 0x00000400
+ #define QTD_TWO_ERRORS 0x00000800
+ #define QTD_THREE_ERRORS 0x00000C00
+#define QTD_DIRECTION_PID 0x00000300
+ #define QTD_OUT_TOKEN 0x00000000
+ #define QTD_IN_TOKEN 0x00000100
+ #define QTD_SETUP_TOKEN 0x00000200
+#define QTD_STATUS_FIELD 0x000000FF
+ #define QTD_ACTIVE 0x00000080
+ #define QTD_HALTED 0x00000040
+ #define QTD_BUFFER_ERROR 0x00000020
+ #define QTD_BABBLE 0x00000010
+ #define QTD_XACT_ERROR 0x00000008
+ #define QTD_MISSED_UFRAME 0x00000004
+ #define QTD_SPLIT_XSTATE 0x00000002
+ #define QTD_START_SPLIT 0x00000000
+ #define QTD_COMPLETE_SPLIT 0x00000002
+ #define QTD_SPLIT_ERROR 0x00000001
+ #define QTD_PING_STATE 0x00000001
+ #define QTD_DO_OUT 0x00000000
+ #define QTD_DO_PING 0x00000001
+//-------------------------------------------------------------------------
+
+#define QH_I_BIT 0x00000080 // BIT 7
+#define QH_ENDPOINT_SPEED 0x00003000 // BIT 13:12
+ #define QH_FULL_SPEED 0x00000000
+ #define QH_LOW_SPEED 0x00001000
+ #define QH_HIGH_SPEED 0x00002000
+#define QH_DATA_TOGGLE_CONTROL 0x00004000 // BIT 14
+ #define QH_IGNORE_QTD_DT 0x00000000
+ #define QH_USE_QTD_DT 0x00004000
+#define QH_HEAD_OF_LIST 0x00008000 // BIT 15
+#define QH_CONTROL_ENDPOINT 0x08000000 // BIT 27
+#define QH_DATA_TOGGLE 0x80000000 // BIT 31
+
+#define QH_MULT_SETTING 0xC0000000 // BIT 31:30
+ #define QH_ONE_XFER 0x40000000
+ #define QH_TWO_XFER 0x80000000
+ #define QH_THREE_XFER 0xC0000000
+
+#define EHCI_QUEUE_HEAD 2 // Queue head id
+
+
+#define EHCI_TERMINATE 1
+
+//----------------------------------------------------------------------------
+// Structure types
+//
+// Notes:
+// 1) Constants that are associated with a particular structure
+// are defined locally within the structure to facilitate easier
+// maintenance.
+//----------------------------------------------------------------------------
+
+#pragma pack(push,1)
+
+
+//
+// Notes:
+// To ensure proper updating, follow these guidelines:
+//
+// 1) Write all bits using the AllBits union element
+// (OR bit-constants if modifying multiple fields).
+//
+// * Writing individual bits may have adverse
+// effects.
+//
+// 2) Typically you will read individual bits using the
+// Field union element.
+//
+// 3) Writing a zero to any field in this register has
+// no effect.
+//
+
+typedef struct _EHCI_HCS_PARAMS
+{
+ union {
+ UINT32 AllBits;
+ #define EHCI_HCSP_N_PORTS (BIT0+BIT1+BIT2+BIT3)
+ #define EHCI_HCSP_PPC BIT4
+ #define EHCI_HCSP_PRR BIT7
+ #define EHCI_HCSP_N_PCC (BIT8+BIT9+BIT10+BIT11)
+ #define EHCI_N_CC (BIT12+BIT13+BIT14+BIT15)
+ #define EHCI_P_INDICATOR BIT16
+ #define EHCI_DEBUG_N (BIT20+BIT21+BIT22+BIT23)
+ struct
+ {
+ UINT32 NumberOfPorts : 4; // [3:0]
+ UINT32 PortPowerControl : 1; // [4]
+ UINT32 Reserved1 : 2; // [6:5]
+ UINT32 PortRoutingRules : 1; // [7]
+ UINT32 PortPerCompanion : 4; // [11:8]
+ UINT32 NumberOfCompanions : 4; // [15:12]
+ UINT32 PortIndicators : 1; // [16]
+ UINT32 Reserved2 : 3; // [19:17]
+ UINT32 DebugPortNumber : 4; // [23:20]
+ UINT32 Reserved3 : 8; // [31:24]
+ } Field;
+ };
+} EHCI_HCS_PARAMS;
+
+typedef struct _EHCI_HCC_PARAMS
+{
+ union {
+ UINT32 AllBits;
+ #define EHCI_64BIT_CAP 0x01 // 64-bit addressing capability
+ #define EHCI_PFLFLAG 0x02 // Programmable Frame List Flag
+ #define EHCI_ASP_CAP 0x04 // Asynchronous Schedule Park Capability
+ #define EHCI_IST 0xF0 // Isochronous Scheduling Threshold
+ #define EHCI_EECP 0xFF00 // EHCI Extended Capabilities Pointer
+ struct
+ {
+ UINT32 AddressingCap64 : 1; // [0]
+ UINT32 FrameListFlag : 1; // [1]
+ UINT32 AsyncShedParkCap : 1; // [2]
+ UINT32 Reserved1 : 1; // [3]
+ UINT32 IsochShedThreshold : 4; // [7:4]
+ UINT32 ExtCapPointer : 8; // [15:8]
+ UINT32 Reserved2 : 16; // [31:8]
+ } Field;
+ };
+} EHCI_HCC_PARAMS;
+
+typedef struct _EHCI_HC_CAP_REG {
+ UINT8 CapLength;
+ UINT8 Reserved;
+ UINT16 HciVersion;
+ EHCI_HCS_PARAMS HcsParams;
+ EHCI_HCC_PARAMS HccParams;
+ UINT8 HcspPortRoute[15];
+} EHCI_HC_CAP_REG;
+
+
+typedef struct _EHCI_USBCMD
+{
+ union {
+ UINT32 AllBits;
+ #define EHCI_RUNSTOP BIT0
+ #define EHCI_HCRESET BIT1
+ #define EHCI_FRM1024 0 // Reset BIT2 and BIT3 before
+ #define EHCI_FRM512 BIT2 // setting the new Frame List Size
+ #define EHCI_FRM256 BIT3
+ #define EHCI_PER_SCHED_ENABLE BIT4
+ #define EHCI_ASYNC_SCHED_ENABLE BIT5
+ #define EHCI_INT_ASYNC_ADVANCE_ENABLE BIT6
+ #define EHCI_INTTHRESHOLD (8 << 16)
+ struct
+ {
+ UINT32 RunStop : 1; // [0]
+ UINT32 HcReset : 1; // [1]
+ UINT32 FrameListSize : 2; // [3:2]
+ UINT32 PeriodicSheduleEnable : 1; // [4]
+ UINT32 AsyncSheduleEnable : 1; // [5]
+ UINT32 IntAsyncAdvDorbell : 1; // [6]
+ UINT32 LightHcReset : 1; // [7]
+ UINT32 Reserved1 : 8; // [16:8]
+ UINT32 IntThresholdCtl : 8; // [23:16]
+ UINT32 Reserved2 : 8; // [31:24]
+ } Field;
+ };
+} EHCI_USBCMD;
+
+typedef struct _EHCI_USBSTS
+{
+ union {
+ UINT32 AllBits;
+ #define EHCI_USB_INTERRUPT BIT0 // Interrupt
+ #define EHCI_USB_ERROR_INTERRUPT BIT1 // Error interrupt
+ #define EHCI_PORT_CHANGE_DETECT BIT2 // Port Change Detect
+ #define EHCI_FRAME_LIST_ROLLOVER BIT3 // Frame List Rollover
+ #define EHCI_HOST_SYSTEM_ERROR BIT4 // Host System Error
+ #define EHCI_INT_ASYNC_ADVANCE BIT5 // Interrupt on Async Advance
+ #define EHCI_HCHALTED BIT12 // HCHalted
+ #define EHCI_RECLAIM BIT13 // Reclamation
+ #define EHCI_PER_SCHED_STATUS BIT14 // Periodic Schedule Status
+ #define EHCI_ASYNC_SCHED_STATUS BIT15 // Asynchronous Schedule Status
+ struct
+ {
+ UINT32 UsbInt : 1; // [0]
+ UINT32 UsbErrInt : 1; // [1]
+ UINT32 PortChangeDetect : 1; // [2]
+ UINT32 FrameListRollover : 1; // [3]
+ UINT32 HostSystemError : 1; // [4]
+ UINT32 IntOnAsyncAdvance : 1; // [5]
+ UINT32 Reserved1 : 6; // [11:6]
+ UINT32 HCHalted : 1; // [12]
+ UINT32 Reclamation : 1; // [13]
+ UINT32 PeriodicSheduleStatus : 1; // [14]
+ UINT32 AsyncSheduleStatus : 1; // [15]
+ UINT32 Reserved2 : 16; // [31:16]
+ } Field;
+ };
+} EHCI_USBSTS;
+
+typedef struct _EHCI_USBINTR
+{
+ union {
+ UINT32 AllBits;
+ #define EHCI_USBINT_EN BIT0 // Interrupt Enable
+ #define EHCI_USBERRINT_EN BIT1 // Error Interrupt Enable
+ #define EHCI_PCDINT_EN BIT2 // Port Change Detect Interrupt Enable
+ #define EHCI_FLRINT_EN BIT3 // Frame List Rollover Interrupt Enable
+ #define EHCI_HSEINT_EN BIT4 // Host System Error Interrupt Enable
+ #define EHCI_IAAINT_EN BIT5 // Interrupt on Async Advance Enable
+ struct
+ {
+ UINT32 UsbIntEnable : 1; // [0]
+ UINT32 UsbErrIntEnable : 1; // [1]
+ UINT32 PortChangeIntEnable : 1; // [2]
+ UINT32 FrameListRolloverEnable : 1; // [3]
+ UINT32 HostSystemErrorEnable : 1; // [4]
+ UINT32 IntOnAsyncAdvanceEnable : 1; // [5]
+ UINT32 Reserved : 26; // [31:6]
+ } Field;
+ };
+} EHCI_USBINTR;
+
+typedef struct _EHCI_PORTSC
+{
+ union {
+ UINT32 AllBits;
+ #define EHCI_CURRENTCONNECTSTATUS BIT0
+ #define EHCI_CONNECTSTATUSCHANGE BIT1
+ #define EHCI_PORTENABLE BIT2
+ #define EHCI_PORTENABLESTATUSCHANGE BIT3
+ #define EHCI_OVERCURRENTACTIVE BIT4
+ #define EHCI_OVERCURRENTCAHGE BIT5
+ #define EHCI_FORCEPORTRESUME BIT6
+ #define EHCI_SUSPEND BIT7
+ #define EHCI_PORTRESET BIT8
+ #define EHCI_DMINUSBIT BIT10
+ #define EHCI_DPLUSBIT BIT11
+ #define EHCI_PORTPOWER BIT12
+ #define EHCI_PORTOWNER BIT13
+ #define EHCI_WKCNNT_E BIT20 // Wake On Connect Enable
+ #define EHCI_WKDSCNNT_E BIT21 // Wake On Disconnect Enable
+ #define EHCI_WKOC_E BIT22 // Wake On Over-current Enable
+ struct
+ {
+ UINT32 CurrentConnectStatus : 1; // [0]
+ UINT32 ConnectStatusChange : 1; // [1]
+ UINT32 PortEnable : 1; // [2]
+ UINT32 PortEnableChange : 1; // [3]
+ UINT32 OvercurrentActive : 1; // [4]
+ UINT32 OvercurrentChange : 1; // [5]
+ UINT32 ForcePortResume : 1; // [6]
+ UINT32 Suspend : 1; // [7]
+ UINT32 PortReset : 1; // [8]
+ UINT32 Reserved1 : 1; // [9]
+ UINT32 LineStatus : 2; // [11:10]
+ UINT32 PortPower : 1; // [12]
+ UINT32 PortOwner : 1; // [13]
+ UINT32 PortIndicatorControl : 2; // [15:14]
+ UINT32 PortTestControl : 4; // [19:16]
+ UINT32 WakeOnConnectEnable : 1; // [20]
+ UINT32 WakeOnDisconnectEnable : 1; // [21]
+ UINT32 WakeOnOvercurrentEnable : 1; // [22]
+ UINT32 Reserved2 : 9; // [31:23]
+ } Field;
+ };
+} EHCI_PORTSC;
+
+
+
+typedef struct _EHCI_HC_OPER_REG {
+ EHCI_USBCMD UsbCmd;
+ volatile EHCI_USBSTS UsbSts;
+ EHCI_USBINTR UsbIntr;
+ UINT32 FrIndex;
+ UINT32 CtrlDsSegment;
+ UINT32 PeriodicListBase;
+ UINT32 AsyncListAddr;
+ UINT8 Reserved[36];
+ UINT32 ConfigFlag;
+ EHCI_PORTSC PortSC[16];
+} EHCI_HC_OPER_REG;
+
+
+typedef struct {
+ UINT32 dNextqTDPtr;
+ UINT32 dAltNextqTDPtr;
+ UINT32 dToken;
+ UINT32 dBufferPtr0;
+ UINT32 dBufferPtr1;
+ UINT32 dBufferPtr2;
+ UINT32 dBufferPtr3;
+ UINT32 dBufferPtr4;
+ UINT32 dReserved[8];
+} EHCI_QTD;
+
+
+typedef struct {
+ UINT32 dLinkPointer;
+ UINT32 dEndPntCharac;
+ UINT32 dEndPntCap;
+ UINT32 dCurqTDPtr;
+ UINT32 dNextqTDPtr;
+ UINT32 dAltNextqTDPtr;
+ UINT32 dToken;
+ UINT32 dBufferPtr0;
+ UINT32 dBufferPtr1;
+ UINT32 dBufferPtr2;
+ UINT32 dBufferPtr3;
+ UINT32 dBufferPtr4;
+ UINT32 dReserved[8];
+ VOID *fpCallBackFunc;
+ EHCI_QTD *fpFirstqTD;
+ UINT8 bActive;
+ UINT8 bErrorStatus;
+ UINT8 *fpDevInfoPtr;
+ UINT8 aDataBuffer[8];
+ UINT8 Pad[38-3*sizeof(VOID*)]; // sizeof(EHCI_QH)should be divisible by 32
+} EHCI_QH; // because of 32 bin pointers; the size of
+ // the structure has to be 32 bytes aligned
+
+typedef struct _EHCI_DESC_PTRS_
+{
+ EHCI_QH *fpQHControl;
+ EHCI_QTD *fpqTDControlSetup;
+ EHCI_QTD *fpqTDControlData;
+ EHCI_QTD *fpqTDControlStatus;
+ EHCI_QH *fpQHBulk;
+ EHCI_QTD *fpqTDBulkData;
+
+} EHCI_DESC_PTRS;
+
+typedef struct _PEI_EHCI_DEV
+{
+ UINTN Signature;
+ #define PEI_EHCI_DEV_SIGNATURE EFI_SIGNATURE_32( 'p', 'e', 'h', 'c' )
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ EFI_PEI_CPU_IO_PPI *CpuIoPpi;
+ EFI_PEI_STALL_PPI *StallPpi;
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi;
+ UINT32 UsbHostControllerBaseAddress;
+ EHCI_HC_OPER_REG *EhciHcOpReg;
+ UINT8 bNumPorts;
+ UINT32 HcStatus;
+ EHCI_DESC_PTRS stEHCIDescPtrs;
+ UINT16 PortResetStatusChangeMap;
+ UINT16 HiSpeedDevicesMap;
+
+} PEI_EHCI_DEV;
+
+#pragma pack(pop)
+
+#define PEI_MAX_EHCI_DATA_SIZE 20 * 1024
+
+//----------------------------------------------------------------------------
+// Function prototypes
+//----------------------------------------------------------------------------
+
+
+
+EFI_STATUS InitializeUsbHC (
+ PEI_EHCI_DEV *UhcDev );
+
+VOID EhciInitHC (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_EHCI_DEV *pEhcDev );
+
+VOID EhciHcReset (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_EHCI_DEV *pEhcDev );
+
+
+VOID EhciHcEnableRootHub (
+ PEI_EHCI_DEV *EhciDevPtr,
+ UINT8 PortNumber );
+
+VOID EHCIWaitForAsyncTransferComplete (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_EHCI_DEV *EhciDevPtr,
+ EHCI_QH *QHead);
+
+EFI_STATUS EhciHcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS EhciHcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS EhciHcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber );
+
+EFI_STATUS EhciHcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus );
+
+EFI_STATUS EhciHcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+EFI_STATUS EhciHcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/EhciPEI/EhciPeiBoard.c b/Core/EM/UsbRecovery/EhciPEI/EhciPeiBoard.c
new file mode 100644
index 0000000..a883ac2
--- /dev/null
+++ b/Core/EM/UsbRecovery/EhciPEI/EhciPeiBoard.c
@@ -0,0 +1,108 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/EhciPeiBoard.c 1 3/03/09 7:28p Olegi $
+//
+// $Revision: 1 $
+//
+// $Date: 3/03/09 7:28p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/EhciPeiBoard.c $
+//
+// 1 3/03/09 7:28p Olegi
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EhciPeiBoard.c
+//
+// Description: This file contains routines that are board specific for
+// initializing the EHCI controller in the USB Recovery module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <PPI/PeiGetUCtrl.h>
+#include <PPI/OhciPPI.h>
+#include <PPI/stall.h>
+#include "EhciPei.h"
+
+
+//----------------------------------------------------------------------------
+// Porting Steps:
+//
+// 1) define/undefine the appropriate southbridge type
+// 2) define registers and their set/clear bits for each register to be
+// modified in each controller's PCI configuration space
+// 3) do not do any generic initialization - programming of BAR and command
+// register is done generically
+//
+//----------------------------------------------------------------------------
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciPeiBoardInit
+//
+// Description:
+// This is a porting hook for board-specific EHCI controller
+// initialization
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices -
+// IN EFI_PEI_PCI_CFG_PPI *Pci -
+// IN EFI_PEI_STALL_PPI *StallPpi -
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EhciPeiBoardInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *Pci,
+ IN EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ return Status;
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/HubPeim.h b/Core/EM/UsbRecovery/HubPeim.h
new file mode 100644
index 0000000..7f0a114
--- /dev/null
+++ b/Core/EM/UsbRecovery/HubPeim.h
@@ -0,0 +1,317 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/HubPeim.h 4 11/24/12 5:42a Ryanchou $
+//
+// $Revision: 4 $
+//
+// $Date: 11/24/12 5:42a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/HubPeim.h $
+//
+// 4 11/24/12 5:42a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 3 1/18/11 12:55a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 2 7/10/08 6:33p Michaela
+// Updated to support OHCI controllers
+//
+// 1 9/22/06 4:06p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HubPeim.H
+//
+// Description: This file belongs to "Framework" and included here for
+// compatibility purposes. This file is modified by AMI to include
+// copyright message, appropriate header and integration code
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains 'Framework Code' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may not be modified, except as allowed by
+// additional terms of your license agreement.
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ HubPeim.h
+
+ Abstract:
+
+ Constants definitions for Usb Hub Peim
+
+ Revision History
+
+ --*/
+
+#ifndef _PEI_HUB_PEIM_H
+#define _PEI_HUB_PEIM_H
+
+#include "Efi.h"
+#include "Pei.h"
+#include "usb.h"
+#include "usbpeim.h"
+
+#include "Ppi\UsbIo.h"
+//
+// Hub feature numbers
+//
+#define C_HUB_LOCAL_POWER 0
+#define C_HUB_OVER_CURRENT 1
+
+
+//
+// Hub class code & sub class code
+//
+#define CLASS_CODE_HUB 0x09
+#define SUB_CLASS_CODE_HUB 0
+
+//
+// Hub Status & Hub Change bit masks
+//
+#define HUB_STATUS_LOCAL_POWER 0x0001
+#define HUB_STATUS_OVERCURRENT 0x0002
+
+#define HUB_CHANGE_LOCAL_POWER 0x0001
+#define HUB_CHANGE_OVERCURRENT 0x0002
+
+//
+// Hub Characteristics
+//
+#define HUB_CHAR_LPSM 0x0003
+#define HUB_CHAR_COMPOUND 0x0004
+#define HUB_CHAR_OCPM 0x0018
+
+//
+// Hub specific request
+//
+#define HUB_CLEAR_FEATURE 0x01
+#define HUB_CLEAR_FEATURE_REQ_TYPE 0x20
+
+#define HUB_CLEAR_FEATURE_PORT 0x01
+#define HUB_CLEAR_FEATURE_PORT_REQ_TYPE 0x23
+
+#define HUB_GET_BUS_STATE 0x02
+#define HUB_GET_BUS_STATE_REQ_TYPE 0xa3
+
+#define HUB_GET_DESCRIPTOR 0x06
+#define HUB_GET_DESCRIPTOR_REQ_TYPE 0xa0
+
+#define HUB_GET_HUB_STATUS 0x00
+#define HUB_GET_HUB_STATUS_REQ_TYPE 0xa0
+
+#define HUB_GET_PORT_STATUS 0x00
+#define HUB_GET_PORT_STATUS_REQ_TYPE 0xa3
+
+#define HUB_SET_DESCRIPTOR 0x07
+#define HUB_SET_DESCRIPTOR_REQ_TYPE 0x20
+
+#define HUB_SET_HUB_FEATURE 0x03
+#define HUB_SET_HUB_FEATURE_REQ_TYPE 0x20
+
+#define HUB_SET_HUB_DEPTH 0x0C
+#define HUB_SET_HUB_DEPTH_REQ_TYPE 0x20
+
+#define HUB_SET_PORT_FEATURE 0x03
+#define HUB_SET_PORT_FEATURE_REQ_TYPE 0x23
+
+// Hub port status and port change status bits
+#define HUB_PORT_CONNECTION 0x0001
+#define HUB_PORT_ENABLE 0x0002
+#define HUB_PORT_SUSPEND 0x0004
+#define HUB_PORT_OVER_CURRENT 0x0008
+#define HUB_PORT_RESET 0x0010
+#define HUB_PORT_POWER 0x0100
+#define HUB_PORT_LOW_SPEED 0x0200
+#define HUB_PORT_HIGH_SPEED 0x0400
+#define HUB_PORT_TEST 0x0800
+#define HUB_PORT_INDICATOR 0x1000
+
+#define HUB_C_PORT_CONNECTION 0x0001
+#define HUB_C_PORT_ENABLE 0x0002
+#define HUB_C_PORT_SUSPEND 0x0004
+#define HUB_C_PORT_OVER_CURRENT 0x0008
+#define HUB_C_PORT_RESET 0x0010
+
+// Super speed hub definition
+#define SS_HUB_PORT_CONNECTION 0x0001
+#define SS_HUB_PORT_ENABLE 0x0002
+#define SS_HUB_PORT_OVER_CURRENT 0x0008
+#define SS_HUB_PORT_RESET 0x0010
+#define SS_HUB_PORT_LINK_STATE 0x01E0
+#define SS_HUB_PORT_POWER 0x0200
+#define SS_HUB_PORT_SPEED 0x1800
+
+#define SS_HUB_C_PORT_CONNECTION 0x0001
+#define SS_HUB_C_PORT_ENABLE 0x0002
+#define SS_HUB_C_PORT_SUSPEND 0x0004
+#define SS_HUB_C_PORT_OVER_CURRENT 0x0008
+#define SS_HUB_C_PORT_RESET 0x0010
+#define SS_HUB_C_BH_PORT_RESET 0x0020
+#define SS_HUB_C_PORT_LINK_STATE 0x0040
+#define SS_HUB_C_PORT_CONFIG_ERROR 0x0080
+
+#pragma pack(1)
+typedef struct usb_hub_status
+{
+ UINT16 HubStatus;
+ UINT16 HubChange;
+} EFI_USB_HUB_STATUS;
+
+typedef struct {
+ struct {
+ UINT16 Connected :1;
+ UINT16 Enabled :1;
+ UINT16 Reserved :1;
+ UINT16 OverCurrent :1;
+ UINT16 Reset :1;
+ UINT16 LinkState :4;
+ UINT16 Power :1;
+ UINT16 Speed :3;
+ UINT16 Reserved1 :3;
+ } PortStatus;
+ struct {
+ UINT16 ConnectChange :1;
+ UINT16 Reserved :2;
+ UINT16 OverCurrentChange :1;
+ UINT16 ResetChange :1;
+ UINT16 BhResetChange :1;
+ UINT16 LinkStateChange :1;
+ UINT16 ConfigErrorChange :1;
+ UINT16 Reserved1 :8;
+ } PortChange;
+} USB3_HUB_PORT_STATUS;
+
+#pragma pack()
+
+EFI_STATUS
+PeiHubGetPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ OUT UINT32 *PortStatus );
+
+EFI_STATUS
+PeiHubSetPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ IN UINT8 Value );
+
+EFI_STATUS
+PeiHubSetHubFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Value );
+
+EFI_STATUS
+PeiHubGetHubStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ OUT UINT32 *HubStatus );
+
+EFI_STATUS
+PeiHubClearPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ IN UINT8 Value );
+
+EFI_STATUS
+PeiHubClearHubFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Value );
+
+EFI_STATUS
+PeiSetHubDepth (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 HubDepth);
+
+EFI_STATUS
+PeiGetHubDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINTN DescriptorSize,
+ OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor );
+
+EFI_STATUS
+PeiDoHubConfig (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice );
+
+VOID
+PeiResetHubPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ UINT8 PortNum );
+
+#endif
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/OhciPEI/OhciPei.c b/Core/EM/UsbRecovery/OhciPEI/OhciPei.c
new file mode 100644
index 0000000..7ecb23d
--- /dev/null
+++ b/Core/EM/UsbRecovery/OhciPEI/OhciPei.c
@@ -0,0 +1,1455 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/OhciPei.c 12 11/24/12 5:44a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 11/24/12 5:44a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/OhciPei.c $
+//
+// 12 11/24/12 5:44a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 11 8/23/12 9:59p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 10 1/18/11 12:59a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 9 10/11/10 4:51p Olegi
+// XHCI support added.
+//
+// 8 3/17/09 5:09p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 7 3/03/09 7:26p Olegi
+// MaximumPacketLength changed from UINT8 to UINT16.
+//
+// 6 10/21/08 5:57p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 5 7/29/08 5:50p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 4 7/18/08 5:04p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 3 7/10/08 6:36p Michaela
+// Updated to support OHCI controllers
+//
+// 2 9/22/06 12:23p Sivagarn
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+// - Merged multiple MAK and SDL files into one MAK and SDL file
+// - Removed unnecessary files
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: OhciPei.c
+//
+// Description:
+// This file is the main source file for the OHCI PEI USB
+// recovery module. Its entry point at OhciPeiUsbEntryPoint
+// will be executed from the UsbRecoveryInitialize INIT_LIST.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <PPI\PeiGetUCtrl.h>
+#include <PPI\OhciPPI.h>
+#include <PPI\stall.h>
+#include "Ppi\UsbHostController.h"
+#include "OhciPei.h"
+#include "usb.h"
+
+// List of PCI addresses for OHCI controllers
+extern PCI_BUS_DEV_FUNCTION gOhciControllerPciTable[];
+extern UINT16 gOhciControllerCount;
+
+extern EFI_GUID gPeiStallPpiGuid;
+extern EFI_GUID gPeiUsbHostControllerPpiGuid;
+extern EFI_STATUS OhciPeiBoardInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi,
+ EFI_PEI_STALL_PPI *StallPpi );
+extern VOID ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Size );
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciGetOperationalRegisterBase
+//
+// Description:
+// This function uses ControllerIndex and the global PCI_BUS_DEV_FUNCTION
+// array to access a particular controller's PCI configuration space in
+// order to obtain the Operational Register base address.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN UINT16 ControllerIndex
+// -- Index of the controller in the global
+// PCI_BUS_DEV_FUNCTION array
+//
+// Output:
+// UINT32 (Return Value)
+// = Base address for this controller's operational
+// registers.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 OhciGetOperationalRegisterBase (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 ControllerIndex )
+{
+ UINT32 OhciBaseAddress;
+
+ (*PeiServices)->PciCfg->Read(
+ PeiServices,
+ (*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint32,
+ OHCI_PCI_ADDRESS( ControllerIndex, OHCI_BASE_ADDR_REG ),
+ &OhciBaseAddress
+ );
+
+
+ return OhciBaseAddress &= 0xfffffff0; // Mask lower bits
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciPeiUsbEntryPoint
+//
+// Description:
+// This is the entry point into the OHCI controller initialization
+// subsystem.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// -- EFI_FFS_FILE_HEADER pointer
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ UINT8 Index;
+ UINTN MemPages;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TempPtr;
+ PEI_OHCI_DEV *OhciDevPtr;
+ EFI_PEI_STALL_PPI *StallPpi;
+
+ //-------------------------------------------
+ // Initialize the EFI_PEI_STALL_PPI interface
+ //-------------------------------------------
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //-----------------------------------------
+ // board specific initialization to program
+ // PCI bridges and enable MMIO
+ //-----------------------------------------
+
+ Status = OhciPeiBoardInit(
+ PeiServices,
+ (*PeiServices)->PciCfg,
+ StallPpi );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //----------------------------------------------------------
+ // Allocate OHCI DEVICE OBJECT that holds all necessary
+ // information for the Host Controller operational registers
+ // for each controller. Initialze the controller and setup
+ // data structures for ready for operation
+ //----------------------------------------------------------
+
+ for (Index = 0; Index < gOhciControllerCount; Index++)
+ {
+
+ // PAGESIZE = 0x1000
+ MemPages = sizeof (PEI_OHCI_DEV) / 0x1000 + 1;
+ Status = (**PeiServices).AllocatePages(
+ PeiServices,
+ EfiConventionalMemory,
+ MemPages,
+ &TempPtr
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ OhciDevPtr = (PEI_OHCI_DEV *) ( (UINTN) TempPtr );
+ OhciDevPtr->Signature = PEI_OHCI_DEV_SIGNATURE;
+ OhciDevPtr->PeiServices = PeiServices;
+ OhciDevPtr->CpuIoPpi = (*PeiServices)->CpuIo;
+ OhciDevPtr->StallPpi = StallPpi;
+ OhciDevPtr->PciCfgPpi = (*PeiServices)->PciCfg;
+ ;
+ OhciDevPtr->UsbHostControllerBaseAddress =
+ OhciGetOperationalRegisterBase( PeiServices, Index );
+
+ //Initialize the OHCI Controller for operation
+
+ OhciInitHC( PeiServices, OhciDevPtr, Index ); // 0xff03
+
+ //Setup PPI entry point
+ OhciDevPtr->UsbHostControllerPpi.ControlTransfer =
+ OhciHcControlTransfer;
+ OhciDevPtr->UsbHostControllerPpi.BulkTransfer =
+ OhciHcBulkTransfer;
+ OhciDevPtr->UsbHostControllerPpi.GetRootHubPortNumber =
+ OhciHcGetRootHubPortNumber;
+ OhciDevPtr->UsbHostControllerPpi.GetRootHubPortStatus =
+ OhciHcGetRootHubPortStatus;
+ OhciDevPtr->UsbHostControllerPpi.SetRootHubPortFeature =
+ OhciHcSetRootHubPortFeature;
+ OhciDevPtr->UsbHostControllerPpi.ClearRootHubPortFeature =
+ OhciHcClearRootHubPortFeature;
+ OhciDevPtr->UsbHostControllerPpi.PreConfigureDevice = NULL;
+ OhciDevPtr->UsbHostControllerPpi.EnableEndpoints = NULL;
+
+ OhciDevPtr->PpiDescriptor.Flags =
+ (EFI_PEI_PPI_DESCRIPTOR_PPI |
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ OhciDevPtr->PpiDescriptor.Guid = &gPeiUsbHostControllerPpiGuid;
+ OhciDevPtr->PpiDescriptor.Ppi = &OhciDevPtr->UsbHostControllerPpi;
+
+ //Now is the time to install the PPI
+ Status = (**PeiServices).InstallPpi(
+ PeiServices, &OhciDevPtr->PpiDescriptor );
+ if ( EFI_ERROR( Status ) )
+ {
+ return EFI_NOT_FOUND;
+ }
+
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciInitHcca
+//
+// Description:
+// This routine allocates memory for the the Host Controller
+// Communications Area (HCCA), aligned on a 256 byte boundary,
+// and updates the HcHcca operational register pointer, as
+// well as the corresponding PEI_OHCI_DEV.pFrameList
+// pointer.
+//
+// Input:
+// IN PEI_OHCI_DEV *OhciDevPtr
+// -- This is a pointer to a PEI_OHCI_DEV structure
+// for an OHCI controller.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciInitHcca (
+ IN PEI_OHCI_DEV *OhciDevPtr )
+{
+ OHCI_HC_REGISTERS *OhciHcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ // Allocate 256 byte aligned Communication Channel area
+ // to the PEI_OHCI_DEV.pFrameList pointer.
+ ABORT_ON_ERROR(
+ (*OhciDevPtr->PeiServices)->AllocatePages(
+ OhciDevPtr->PeiServices,
+ EfiConventionalMemory,
+ (UINTN) (256 / 0x1000) + 1,
+ (EFI_PHYSICAL_ADDRESS *) &OhciDevPtr->pFrameList )
+ );
+
+ // Zero the memory and update the HcHCCA Host Controller
+ // Operational Register.
+ ZeroMem((VOID*)OhciDevPtr->pFrameList, sizeof(HC_HCCA));
+ OhciHcReg->HcHcca = (HC_HCCA*) OhciDevPtr->pFrameList;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciInitHC
+//
+// Description: All leading whitespace on this line is removed by Helpbuilder
+// Description of this function can be block aligned in this section.
+// The first tab that Helpbuilder will recognize will be at tab stop 21,
+// which will indent 4 spaces in Helpbuilder.
+//
+// This text is indented 4 spaces in Helpbuilder
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_OHCI_DEV *OhciDevPtr
+// -- PEI_OHCI_DEV pointer
+// IN UINT8 Index
+// -- Index of this controller in the global
+// PCI_BUS_DEV_FUNCTION array
+//
+// Output:
+// VOID (Return Value)
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID OhciInitHC (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_OHCI_DEV *OhciDevPtr,
+ IN UINT8 Index )
+{
+ UINT8 bPortNum;
+ UINT8 *pPtr;
+ UINTN MemPages;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TempPtr;
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi = OhciDevPtr->PciCfgPpi;
+ POHCI_DESC_PTRS pstOHCIDescPtrs = &(OhciDevPtr->stOHCIDescPtrs);
+ OHCI_HC_REGISTERS *OhciHcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ OhciDevPtr->wAsyncListSize = 0; // not used
+ OhciDevPtr->dMaxBulkDataSize = MAX_OHCI_BULK_DATA_SIZE;
+ //OhciDevPtr->wEndp0MaxPacket = 0x40;
+ //OhciDevPtr->bEndpointSpeed = USBSPEED_FULL;
+
+
+ // Do a Host Controller reset first
+ OhciHcReset( PeiServices, OhciDevPtr );
+
+
+ //-----------------------------------------------------------------
+ // Allocate and initialize the Host Controller Communication
+ // area aligned on a 256 byte boundary.
+ //
+ // This is needed only to poll the HccaDoneHead register
+ // in the HCCA, as the periodic list is not implemented.
+ //-----------------------------------------------------------------
+
+ // Store number of downstream ports into PEI_OHCI_DEV struct
+ OhciDevPtr->bNumPorts =
+ OhciHcReg->HcRhDescriptorA.Field.NumberDownstreamPorts;
+
+ // Program root hub characteristics:
+ OhciHcReg->HcRhDescriptorA.AllBits =
+ (NO_OVERCURRENT_PROTECTION | // No over current protection
+ POWERED_INDIVIDUALLY | // Ports powered individually
+ POWER_SWITCHED); // Ports individually power switched
+ OhciHcReg->HcRhDescriptorB.AllBits =
+ (ALL_REMOVEABLE | // All devices are removbale
+ ALL_PER_PORT_POWER_SWITCHED); // Power control is per-port
+
+ OhciHcReg->HcRhStatus.Field.LocalPowerStatusChange =
+ SET_GLOBAL_POWER; // Turn on power to all ports
+
+ // Initialize the frame interval register
+ OhciHcReg->HcFmInterval.Field.FrameInterval =
+ FM_INTERVAL_DEFAULT; // Between Start of Frames (SOFs)
+ OhciHcReg->HcFmInterval.Field.FsLargestDataPacket =
+ FS_LARGEST_PACKET_DEFAULT; // Largest for single transaction
+
+ // Enable the host controller list processing (Bulk/Control only)
+ OhciHcReg->HcControl.Field.BulkListEnable = TRUE;
+ OhciHcReg->HcControl.Field.ControlListEnable = TRUE;
+
+ // Set the operational bit in the host controller so that power
+ // can be applied to the ports.
+ OhciHcReg->HcControl.Field.HostControllerFunctionalState =
+ SET_USB_OPERATIONAL;
+
+ // Enable all the ports.
+ for ( bPortNum = 0; bPortNum < OhciDevPtr->bNumPorts; bPortNum++ ) {
+ OhciHcReg->HcRhPortStatus[bPortNum].AllBits = SET_PORT_POWER;
+ }
+
+ // Allocate a block of memory and define/initialize
+ // Setup Control and Bulk EDs/TDs
+ pstOHCIDescPtrs = &(OhciDevPtr->stOHCIDescPtrs);
+
+ MemPages = ( 3 *
+ sizeof (OHCI_ED) ) + ( 5 * sizeof(OHCI_TD) ) / 0x1000 + 1;
+ Status = (**PeiServices).AllocatePages(
+ PeiServices,
+ EfiConventionalMemory,
+ MemPages,
+ &TempPtr
+ );
+
+ pPtr = (UINT8 *) ( (UINTN) TempPtr );
+ MemSet( pPtr, 3 * sizeof (OHCI_ED) + 5 * sizeof(OHCI_TD), 0 );
+ if (!pPtr) {
+ return;
+ }
+ pstOHCIDescPtrs->pstEDControl = (POHCI_ED) pPtr;
+ pPtr += sizeof (OHCI_ED); //This should be okay
+ pstOHCIDescPtrs->pstTDControlSetup = (POHCI_TD) pPtr;
+ pPtr += sizeof (OHCI_TD);
+ pstOHCIDescPtrs->pstTDControlData = (POHCI_TD) pPtr;
+ pPtr += sizeof (OHCI_TD);
+ pstOHCIDescPtrs->pstTDControlStatus = (POHCI_TD) pPtr;
+ pPtr += sizeof (OHCI_TD);
+ pstOHCIDescPtrs->pstEDBulk = (POHCI_ED) pPtr;
+ pPtr += sizeof (OHCI_ED);
+ pstOHCIDescPtrs->pstTDBulkData = (POHCI_TD) pPtr;
+ pPtr += sizeof (OHCI_TD);
+ pstOHCIDescPtrs->pstEDInterrupt = (POHCI_ED) pPtr;
+ pPtr += sizeof (OHCI_ED);
+ pstOHCIDescPtrs->pstTDInterruptData = (POHCI_TD) pPtr;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcReset
+//
+// Description:
+// This function performs a software reset of the host controller.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_OHCI_DEV *OhciDevPtr
+// -- PEI_OHCI_DEV pointer
+//
+// Output:
+// VOID (Return Value)
+//
+// Notes:
+// It is assumed that all necessary operational register data has been
+// saved prior to calling this function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID OhciHcReset (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_OHCI_DEV *OhciDevPtr )
+{
+ OHCI_HC_REGISTERS *OhciHcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ // Initiate a software reset
+ OhciHcReg->HcCommandStatus.AllBits = SET_CONTROLLER_RESET;
+
+ //Wait for 2ms
+ OHCI_FIXED_DELAY_MS( OhciDevPtr, 2);
+
+ //Do USBRESET to reset roothub and downstream port
+ OhciHcReg->HcControl.Field.HostControllerFunctionalState = SET_USB_RESET;
+
+ //wait for 10ms
+ OHCI_FIXED_DELAY_MS( OhciDevPtr, 10);
+
+ // Note: HcInterruptStatus.Field.RootHubStatusChange bit should
+ // now be set if any devices are connected to a port
+ // on this controller.
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcGetRootHubPortStatus
+//
+// Description:
+// This function obtains the port status and port change status for
+// a port specified by PortNumber and updates the EFI_USB_PORT_STATUS
+// data structure as specified the the PortStatus pointer parameter.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 PortNumber
+// -- Port number for which status is requested
+// OUT EFI_USB_PORT_STATUS *PortStatus
+// -- EFI_USB_PORT_STATUS pointer's data is updated
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciHcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus )
+{
+ PEI_OHCI_DEV *OhciDevPtr =
+ PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( This );
+ HC_RH_PORT_STATUS HcPortStatus;
+
+ HcPortStatus = ( (OHCI_HC_REGISTERS *)
+ OhciDevPtr->UsbHostControllerBaseAddress )->
+ HcRhPortStatus[PortNumber - 1];
+
+ PortStatus->PortStatus = 0;
+ PortStatus->PortChangeStatus = 0;
+
+ if (HcPortStatus.Field.CurrentConnectStatus) {
+ PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+ }
+ if (HcPortStatus.Field.PortEnableStatus) {
+ PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+ }
+ if (HcPortStatus.Field.PortSuspendStatus) {
+ PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+ }
+ if (HcPortStatus.Field.PortResetStatus) {
+ PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+ }
+ if (HcPortStatus.Field.LowSpeedDeviceAttached) {
+ PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
+ }
+ if (HcPortStatus.Field.ConnectStatusChange) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+ }
+ if (HcPortStatus.Field.PortEnableStatusChange) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+ }
+ if (HcPortStatus.Field.CurrentConnectStatus) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcGetRootHubPortNumber
+//
+// Description:
+// This function returns the number of downstream ports as specified
+// in the HcRhDescriptorA operational register.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// OUT UINT8 *PortNumber
+// -- Number of downstream ports
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciHcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber )
+{
+
+ PEI_OHCI_DEV *OhciDevPtr = PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( This );
+ OHCI_HC_REGISTERS *OhciHcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ if (PortNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *PortNumber = OhciHcReg->HcRhDescriptorA.Field.NumberDownstreamPorts;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcSetRootHubPortFeature
+//
+// Description:
+// This function sets an OHCI specification port feature as specified by
+// PortFeature for the port specified by PortNumber.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 PortNumber
+// -- Port number whose feature is to be set
+// IN EFI_USB_PORT_FEATURE PortFeature
+// -- Feature to set
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciHcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ PEI_OHCI_DEV *OhciDevPtr =
+ PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( This );
+ OHCI_HC_REGISTERS *OhciHcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ if (PortNumber > OhciHcReg->HcRhDescriptorA.Field.NumberDownstreamPorts){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (PortFeature)
+ {
+
+ case EfiUsbPortSuspend:
+ OhciHcReg->HcRhPortStatus[PortNumber - 1].AllBits = SET_PORT_SUSPEND;
+ break;
+
+ case EfiUsbPortReset:
+ OhciHcReg->HcRhPortStatus[PortNumber - 1].AllBits = SET_PORT_RESET;
+ break;
+
+ case EfiUsbPortPower:
+ break;
+
+ case EfiUsbPortEnable:
+ OhciHcReg->HcRhPortStatus[PortNumber - 1].AllBits = SET_PORT_ENABLE;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcClearRootHubPortFeature
+//
+// Description:
+// This function clears an OHCI specification port feature as specified
+// by PortFeature for the port specified by PortNumber.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 PortNumber
+// -- Port number whose feature is to be set
+// IN EFI_USB_PORT_FEATURE PortFeature
+// -- Feature to set
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciHcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ PEI_OHCI_DEV *OhciDevPtr =
+ PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( This );
+ OHCI_HC_REGISTERS *OhciHcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+ HC_RH_PORT_STATUS *Pstatus;
+
+ if (PortNumber > OhciHcReg->HcRhDescriptorA.Field.NumberDownstreamPorts){
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Pstatus = &OhciHcReg->HcRhPortStatus[PortNumber - 1];
+
+ switch (PortFeature)
+ {
+ // clear PORT_ENABLE feature means disable port.
+ // This is accomplished by writing a 1 to the CurrentConnectStatus
+ // field.
+ case EfiUsbPortEnable:
+ Pstatus->AllBits = CLEAR_PORT_ENABLE;
+ break;
+
+ // clear PORT_SUSPEND feature means resume the port.
+ // (cause a resume on the specified port if in suspend mode)
+ // This is accomplished by writing a 1 to the PortOverCurrentIndicator
+ // field.
+ case EfiUsbPortSuspend:
+ Pstatus->AllBits = CLEAR_SUSPEND_STATUS;
+ break;
+
+ case EfiUsbPortPower:
+ break;
+
+
+ // clear PORT_RESET means clear the reset signal.
+ // This is accomplished by writing a 1 to the PortResetStatusChange
+ // field. No assumption is made that the appropriate delay
+ // was implemented.
+ case EfiUsbPortReset:
+
+ break;
+
+ // clear connect status change by writing
+ // a 1 to the ConnectStatusChange field
+ case EfiUsbPortConnectChange:
+ Pstatus->AllBits = CLEAR_CONNECT_STATUS_CHANGE;
+ break;
+
+ // clear enable/disable status change by writing
+ // a 1 to the PortEnableStatusChange field
+ case EfiUsbPortEnableChange:
+ Pstatus->AllBits = CLEAR_PORT_ENABLE_STATUS_CHANGE;
+ break;
+
+ // root hub does not support these requests
+ case EfiUsbPortSuspendChange:
+ case EfiUsbPortOverCurrentChange:
+ case EfiUsbPortResetChange:
+ Pstatus->AllBits = CLEAR_PORT_RESET_STATUS_CHANGE;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcControlTransfer
+//
+// Description:
+// This function intiates a USB control transfer and waits on it to
+// complete.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 bDeviceAddress
+// -- USB address of the device for which the control
+// transfer is to be issued
+// IN UINT8 DeviceType
+// -- Not used
+// IN UINT8 MaximumPacketLength
+// -- Maximum number of bytes that can be sent to or
+// received from the endpoint in a single data packet
+// IN EFI_USB_DEVICE_REQUEST *Request
+// -- EFI_USB_DEVICE_REQUEST pointer
+// IN EFI_USB_DATA_DIRECTION TransferDirection
+// -- Direction of transfer
+// OPTIONAL IN OUT VOID *DataBuffer
+// -- Pointer to source or destination buffer
+// OPTIONAL IN OUT UINTN *DataLength
+// -- Length of buffer
+// IN UINTN TimeOut
+// -- Not used
+// OUT UINT32 *TransferResult
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+typedef struct _D_REQUEST
+{
+ UINT8 RequestType;
+ UINT8 Request;
+ UINT16 Value;
+ UINT16 Index;
+ UINT16 Length;
+} D_REQUEST;
+
+EFI_STATUS OhciHcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 bDeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *DataBuffer OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ UINT16 *fpData;
+ POHCI_ED fpED;
+ POHCI_TD fpTD;
+ UINT32 DwordData;
+ UINT16 WordData;
+ UINT16 WordRequest;
+ UINT16 WordIndex;
+ UINT16 WordValue;
+ EFI_STATUS Status = EFI_SUCCESS;
+ PEI_OHCI_DEV *OhciDevPtr =
+ PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( This );
+ POHCI_DESC_PTRS fpDescPtrs =
+ &(OhciDevPtr->stOHCIDescPtrs);
+ OHCI_HC_REGISTERS *HcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ // 5 ms delay is necessary for OHCI host controllers
+ OHCI_FIXED_DELAY_MS( OhciDevPtr, 5 );
+
+ WordRequest = (Request->Request << 8) | Request->RequestType;
+ WordValue = Request->Value;
+ WordIndex = Request->Index;
+
+ //
+ // Build the device request in the data area of the control setup qTD
+ //
+ fpData = (UINT16 *) fpDescPtrs->pstTDControlSetup->aSetupData;
+ *fpData++ = WordRequest;
+ *fpData++ = WordValue;
+ *fpData++ = WordIndex;
+ *fpData++ = (UINT16) *DataLength;
+ *(UINT32 *) fpData = (UINT32) DataBuffer;
+
+ //
+ // Prepare some registers that will be used in building the TDs below.
+ // wLength contains the data length.
+ // fpBuffer contains the absolute address of the data buffer.
+ // WordRequest contains the request type (bit 7 = 0/1 for Out/In).
+ // fpDevInfo will contain a pointer to the DeviceInfo structure for
+ // the given device.
+ //
+ // Ready the EDControl for the control transfer.
+ //
+ fpED = fpDescPtrs->pstEDControl;
+ //
+ // The ED control field will be set so
+ // Function address & Endpoint number = ESI,
+ // Direction = From TD,
+ // Speed = DeviceInfo.bEndpointSpeed,
+ // Skip = 1, Format = 0,
+ // Max packet size = DeviceInfo.wEndp0MaxPacket
+ // The HeadPointer field will be set to TDControlSetup
+ // The TailPointer field will be set to OHCI_TERMINATE
+ // The LinkPointer field will be set to OHCI_TERMINATE
+ //
+
+ // if wEndp0MaxPacket is NULL, then use default
+ // packet size
+ DwordData = MaximumPacketLength;
+
+ // Force the max packet size to 64 bytes
+ if (DwordData > 0x40 || DwordData == 0) {
+ DwordData = 0x40;
+ }
+ DwordData <<= 16; // DwordData[26:16] = device's packet size
+ WordData = (UINT16) DeviceSpeed; // 00/01/10 for HI/LO/FULL
+ WordData = (WordData & 1) << 13; // WordData[13] = full/low speed flag
+ WordData |= bDeviceAddress | ED_SKIP_TDQ;
+ fpED->dControl = DwordData | WordData;
+ fpED->fpTailPointer = 0;
+ fpED->fpEDLinkPointer = 0;
+
+ fpTD = fpDescPtrs->pstTDControlSetup;
+ //
+ // The ControlStatus field will be set so
+ // Buffer Rounding = 1,
+ // Direction PID = GTD_SETUP_PACKET,
+ // Delay Interrupt = GTD_INTD,
+ // Data Toggle = GTD_SETUP_TOGGLE,
+ // Error Count = GTD_NO_ERRORS,
+ // Condition Code = GTD_NOT_ACCESSED
+ // The CurrentBufferPointer field will point to the TD's SetupData buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The BufferEnd field will point to the last byte of the TD's SetupData
+ // buffer.
+ // The LinkPointer field will point to the TDControlData if data will
+ // be sent/received or to the TDControlStatus if no data is expected.
+ // The CSReloadValue field will contain 0 because this is a "one shot"
+ // packet.
+ // The pCallback will be set to point to the OHCI_ControlTDCallback
+ // routine.
+ // The ActiveFlag field will be set to TRUE.
+ // The DeviceAddress field does not need to be set since the Control TDs
+ // do not need rebinding to the EDControl.
+ //
+ fpTD->dControlStatus = (UINT32) ( GTD_BUFFER_ROUNDING |
+ GTD_SETUP_PACKET | GTD_SETUP_TOGGLE |
+ GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28) );
+
+ fpTD->fpCurrentBufferPointer = fpTD->aSetupData;
+ fpTD->fpBufferEnd = fpTD->aSetupData + 7; // size of aSetupData - 1
+
+ if (*DataLength) { // some data to transfer
+
+ // Fill in various fields in the TDControlData.
+ fpTD = fpDescPtrs->pstTDControlData;
+ //
+ // The ControlStatus field will be set so
+ // Buffer Rounding = 1,
+ // Direction PID = GTD_OUT_PACKET/GTD_IN_PACKET,
+ // Delay Interrupt = GTD_INTD,
+ // Data Toggle = GTD_DATA1_TOGGLE,
+ // Error Count = GTD_NO_ERRORS,
+ // Condition Code = GTD_NOT_ACCESSED
+ // The CurrentBufferPointer field will point to the caller's buffer
+ // which is now in EBP.
+ // The BufferEnd field will point to the last byte of the caller's
+ // buffer.
+ // The LinkPointer field will point to the TDControlStatus.
+ // The CSReloadValue field will contain 0 because this is a
+ // "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTDCallback
+ // routine.
+ // The ActiveFlag field will be set to TRUE.
+ // The DeviceAddress field does not need to be set since the Control
+ // TDs do not need rebinding to the EDControl.
+ // The CSReloadValue field will contain 0 because this is a
+ // "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTDCallback
+ // routine.
+ // The ActiveFlag field will be set to TRUE. return USB_SUCCESS;
+ // The DeviceAddress field does not need to be set since the Control
+ // TDs do not need rebinding to the EDControl.
+ //
+ DwordData = (UINT32) ( GTD_BUFFER_ROUNDING | GTD_DATA1_TOGGLE
+ | GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28) );
+ DwordData = (WordRequest & BIT7)
+ ? (DwordData | GTD_IN_PACKET | GTD_INTD)
+ : (DwordData | GTD_OUT_PACKET);
+ fpTD->dControlStatus = DwordData;
+ fpTD->fpCurrentBufferPointer = (UINT8 *) DataBuffer;
+
+ WordData = (*DataLength < MAX_CONTROL_DATA_SIZE)
+ ? *DataLength
+ : MAX_CONTROL_DATA_SIZE;
+ fpTD->fpBufferEnd = (UINT8 *) DataBuffer + WordData - 1;
+ }
+
+ // Fill in various fields in the TDControlStatus.
+ fpTD = fpDescPtrs->pstTDControlStatus;
+ //
+ // The ControlStaus field will be set so
+ // Buffer Rounding = 1,
+ // Direction PID = GTD_OUT_PACKET/GTD_IN_PACKET,
+ // Delay Interrupt = GTD_INTD,
+ // Data Toggle = GTD_DATA1_TOGGLE,
+ // Error Count = GTD_NO_ERRORS,
+ // Condition Code = GTD_NOT_ACCESSED
+ // The CurrentBufferPointer field will point to NULL
+ // The BufferEnd field will point to NULL.
+ // The LinkPointer field will point to OHCI_TERMINATE.
+ // The CSReloadValue field will contain 0 because this is a
+ // "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTdCallback
+ // routine.
+ // The ActiveFlag field will be set to TRUE.
+ // The DeviceAddress field does not need to be set since the Control
+ // TDs do not need rebinding to the EdControl.
+ //
+ // Note: For OUT control transfer status should be IN and
+ // for IN cotrol transfer, status should be OUT.
+ //
+ DwordData = (UINT32) ( GTD_BUFFER_ROUNDING | GTD_DATA1_TOGGLE
+ | GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28) );
+ DwordData = (WordRequest & BIT7)
+ ? (DwordData | GTD_OUT_PACKET)
+ : (DwordData | GTD_IN_PACKET | GTD_INTD);
+ fpTD->dControlStatus = DwordData;
+ fpTD->fpCurrentBufferPointer = NULL;
+ fpTD->fpBufferEnd = NULL;
+ fpTD->fpLinkPointer = NULL;
+
+ //
+ // Link all the pointers together
+ //
+ fpTD = fpDescPtrs->pstTDControlSetup;
+ fpED->fpHeadPointer = fpTD;
+ if (*DataLength) { // chain in data TD
+ fpTD->fpLinkPointer = (UINT8 *) fpDescPtrs->pstTDControlData;
+ fpTD = fpDescPtrs->pstTDControlData;
+ }
+ fpTD->fpLinkPointer = (UINT8 *) fpDescPtrs->pstTDControlStatus;
+
+ fpDescPtrs->pstTDControlStatus->fpLinkPointer = NULL;
+
+ fpTD = fpDescPtrs->pstTDControlSetup;
+ do {
+ fpTD->dCSReloadValue = 0;
+ fpTD->bActiveFlag = TRUE;
+ fpTD = (POHCI_TD) fpTD->fpLinkPointer;
+ } while (fpTD);
+
+ // clear the WriteBackDoneHead status bit in
+ // the HcInterruptStatus register
+ HcReg->HcInterruptStatus.Field.WriteBackDoneHead = HCINT_STATUS_CLEAR;
+
+ //
+ // Now control queue is complete, so set ED_SKIP_TDQ=0
+ //
+ fpED->dControl &= ~ED_SKIP_TDQ;
+ //
+ // Set the HcControlHeadED register to point to the EDControl.
+ //
+ HcReg->HcControlHeadEd = (UINTN) fpED;
+
+ //
+ // Now put the control setup, data and status into the HC's schedule by
+ // setting the ControllListFilled field of HcCommandStatus reg.
+ // This will cause the HC to execute the transaction in the next
+ // active frame.
+ //
+ HcReg->HcCommandStatus.AllBits = SET_CONTROL_LIST_FILLED;
+
+ //
+ // Now wait for the control status TD to complete. When it has completed,
+ // the OHCI_ControlTDCallback will set its active flag to FALSE.
+ Status = OhciHcWaitForTransferComplete( PeiServices, OhciDevPtr,
+ fpDescPtrs->pstTDControlStatus );
+
+ //
+ // Stop the HC from processing the EDControl by setting its Skip bit.
+ //
+ fpED->dControl |= ED_SKIP_TDQ;
+
+ //
+ // Finally check for any error bits set in both the TDControlStatus.
+ // If the TD did not complete successfully, return STC.
+ //
+
+ // DwordData[3:0] = Completion status
+ DwordData = fpDescPtrs->pstTDControlStatus->dControlStatus >> 28;
+
+ return ( (UINT8) DwordData == 0 ) ? EFI_SUCCESS : EFI_DEVICE_ERROR;
+ //TODO: CHange the return status more meaningfull
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcBulkTransfer
+//
+// Description:
+// This function intiates a USB bulk transfer and waits on it to
+// complete.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 DeviceAddress
+// -- USB address of the device for which the control
+// transfer is to be issued
+// IN UINT8 EndPointAddress
+// -- Particular endpoint for the device
+// IN UINT8 MaximumPacketLength
+// -- Maximum number of bytes that can be sent to or
+// received from the endpoint in a single data packet
+// OPTIONAL IN OUT VOID *DataBuffer
+// -- Pointer to source or destination buffer
+// OPTIONAL IN OUT UINTN *DataLength
+// -- Length of buffer
+// IN OUT UINT8 *DataToggle
+// -- Used to update the control/status DataToggle field
+// of the Transfer Descriptor
+// IN UINTN TimeOut
+// -- Not used
+// OUT UINT32 *TransferResult
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciHcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *DataBuffer,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ UINT32 DwordData;
+ UINT8 ByteData;
+ UINT16 wMaxPkt;
+ EFI_STATUS Status;
+ UINT8 bEndp;
+ UINT8 Toggle;
+ PEI_OHCI_DEV *OhciDevPtr =
+ PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( This );
+ POHCI_DESC_PTRS fpDescPtrs = &(OhciDevPtr->stOHCIDescPtrs);
+ OHCI_HC_REGISTERS *HcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+
+ wMaxPkt = MaximumPacketLength;
+
+ if (wMaxPkt == 0) {
+ *DataLength = 0;
+ return EFI_NOT_FOUND;
+ }
+
+ //Clear Bulk ED and TD
+ MemSet( fpDescPtrs->pstEDBulk, sizeof(OHCI_ED), 0 );
+ MemSet( fpDescPtrs->pstTDBulkData, sizeof(OHCI_TD), 0 );
+ //
+ // Set the SKIP bit in the EdBulk to avoid accidental scheduling
+ //
+ fpDescPtrs->pstEDBulk->dControl = ED_SKIP_TDQ;
+ //
+ // Set the ED's head pointer field to bulk data TD and tail pointer
+ // field to OHCI_TERMINATE. Also set ED's link pointer to
+ // OHCI_TERMINATE.
+ //
+ fpDescPtrs->pstEDBulk->fpHeadPointer = fpDescPtrs->pstTDBulkData;
+ fpDescPtrs->pstEDBulk->fpTailPointer = OHCI_TERMINATE;
+ fpDescPtrs->pstEDBulk->fpEDLinkPointer = OHCI_TERMINATE;
+ //
+ // Form the data needed for ED's control field with the available
+ // information
+ //
+ bEndp = EndPointAddress & 0x7f;
+ DwordData = (EndPointAddress & 0x80) ? ED_IN_PACKET : ED_OUT_PACKET;
+ DwordData |= DeviceAddress;
+ DwordData |= (UINT16) bEndp << 7;
+ DwordData |= (UINT32) wMaxPkt << 16;
+
+ //
+ // Update the ED's control field with the data formed
+ // ASSUME ALL MASS DEVICES ARE FULL SPEED DEVICES.
+ //
+ fpDescPtrs->pstEDBulk->dControl = DwordData;
+ //
+ // Fill the general bulk data TD with relevant information. Set the
+ // TD's control field with buffer rounding set to 1, direction PID to
+ // don't care, delay interrupt to INTD, data toggle to the latest data
+ // toggle value, error count to no errors and condition code to not
+ // accessed.
+ //
+ // Set the data toggle to DATA0 (SETUP_TOGGLE)
+ fpDescPtrs->pstTDBulkData->dControlStatus = (UINT32) (
+ GTD_BUFFER_ROUNDING |
+ GTD_IN_PACKET |
+ GTD_INTD |
+ GTD_SETUP_TOGGLE |
+ GTD_NO_ERRORS |
+ (GTD_NOT_ACCESSED << 28)
+ );
+ fpDescPtrs->pstTDBulkData->dControlStatus |= (UINT32) *DataToggle << 24;
+
+ //
+ // GTD current buffer pointer field will point to the caller's buffer which
+ // now in the variable fpBuffer
+ //
+ fpDescPtrs->pstTDBulkData->fpCurrentBufferPointer = (UINT8 *) DataBuffer;
+ fpDescPtrs->pstTDBulkData->fpBufferEnd = (UINT8 *) DataBuffer +
+ *DataLength - 1;
+ fpDescPtrs->pstTDBulkData->fpLinkPointer = OHCI_TERMINATE;
+ //
+ // GTD's CSReloadValue field will contain 0 because this is a
+ // "one shot" packet
+ //
+ fpDescPtrs->pstTDBulkData->dCSReloadValue = 0;
+ fpDescPtrs->pstTDBulkData->bActiveFlag = TRUE;
+
+ // Set the HCBulkHeadED register to point to the bulk ED
+ fpDescPtrs->pstEDBulk->dControl &= ~ED_SKIP_TDQ;
+ HcReg->HcBulkHeadEd = (UINT32) fpDescPtrs->pstEDBulk;
+
+ // Enable the bulk list processing
+ HcReg->HcCommandStatus.AllBits = SET_BULK_LIST_FILLED;
+
+ Status = OhciHcWaitForTransferComplete( PeiServices, OhciDevPtr,
+ fpDescPtrs->pstTDBulkData );
+ //
+ // Stop the HC from processing the EDBulk by setting its Skip bit.
+ //
+ fpDescPtrs->pstEDBulk->dControl |= ED_SKIP_TDQ;
+ //
+ // Update the data toggle value into the mass info structure
+ //
+
+ *DataToggle = (UINT8) ( ( (fpDescPtrs->pstTDBulkData->dControlStatus &
+ GTD_DATA_TOGGLE) >> 24 ) & 1 );
+ Toggle = (UINT8) ( (fpDescPtrs->pstTDBulkData->dControlStatus &
+ GTD_DATA_TOGGLE) >> 24 );
+ if ( (Toggle & 0x02) == 0 )
+ {
+ //Use the Carry
+ DwordData = (UINT32) fpDescPtrs->pstEDBulk->fpHeadPointer;
+ DwordData &= 0x00000002;
+ DwordData = DwordData >> 1;
+ DwordData &= 0x00000001;
+ *DataToggle = DwordData;
+ }
+ //
+ // Check for the error conditions - if possible recover from them
+ //
+ ByteData = (UINT8) (fpDescPtrs->pstTDBulkData->dControlStatus >> 28);
+ if (ByteData) {
+ if (ByteData == GTD_DEVICE_NOT_RESPOND) {
+ //TODO fpUSBData->bLastCommandStatus |= USB_BULK_TIMEDOUT;
+ *DataLength = 0;
+ return EFI_NOT_FOUND;
+ }
+ if (ByteData == GTD_STALL) {
+ //TODO fpUSBData->bLastCommandStatus |= USB_BULK_STALLED;
+ *DataLength = 0;
+ return EFI_NOT_FOUND;
+ }
+ }
+ //
+ // Get the size of data transferred
+ //
+ // Size transferred is calculated by subtracting end address with current
+ // buffer pointer and subtracting that value from the total size
+ //
+ if (!fpDescPtrs->pstTDBulkData->fpCurrentBufferPointer)
+ {
+ //All data are transfered.
+ return EFI_SUCCESS;
+ }
+ DwordData = (UINT32) fpDescPtrs->pstTDBulkData->fpBufferEnd;
+ DwordData = DwordData -
+ (UINT32) fpDescPtrs->pstTDBulkData->fpCurrentBufferPointer;
+ if (DwordData != 0)
+ {
+ *DataLength = *DataLength - DwordData - 1;
+ }
+ else {
+ ;
+ }
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: OhciHcWaitForTransferComplete
+//
+// Description:
+// This function waits for a tranfer to complete by polling the
+// HcInterruptStatus register's WritebackDoneHead field.
+//
+// Input:
+// IN PEI_OHCI_DEV *OhciDevPtr
+// -- PEI_OHCI_DEV pointer
+// IN POHCI_TD Td
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciHcWaitForTransferComplete (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_OHCI_DEV *OhciDevPtr,
+ IN POHCI_TD Td )
+{
+ UINT32 Count;
+ OHCI_HC_REGISTERS *HcReg =
+ (OHCI_HC_REGISTERS *) OhciDevPtr->UsbHostControllerBaseAddress;
+ HC_INTERRUPT_STATUS *HcIntStatus = &HcReg->HcInterruptStatus;
+ UINT32 DoneHead = 0;
+
+ // Poll (up to 4 seconds) or until the
+ // WriteBackDoneHead status bit is set in
+ // the HcInterruptStatus operational register.
+
+ // if the WriteBackDoneHead is set, then clear
+ // HccaDoneHead in the HCCA and WriteBackDoneHead
+ // and then return EFI_SUCCESS to continue execution.
+
+ for (Count = 0; Count < 1000; Count++) {
+ if (HcIntStatus->Field.WriteBackDoneHead == HCINT_WB_DONE ) {
+ DoneHead = HcReg->HcHcca->HccaDoneHead;
+ HcReg->HcHcca->HccaDoneHead = 0;
+ HcIntStatus->Field.WriteBackDoneHead = HCINT_STATUS_CLEAR;
+ if (DoneHead == (UINT32)Td) {
+ return EFI_SUCCESS;
+ }
+ }
+ OHCI_FIXED_DELAY_MS( OhciDevPtr, 4 ); // 4 ms
+
+ }
+
+ PEI_TRACE ((EFI_D_ERROR, PeiServices, "OHCI Time-Out:\n"));
+ return EFI_NOT_FOUND;
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/OhciPEI/OhciPei.cif b/Core/EM/UsbRecovery/OhciPEI/OhciPei.cif
new file mode 100644
index 0000000..49ec85b
--- /dev/null
+++ b/Core/EM/UsbRecovery/OhciPEI/OhciPei.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "OhciPei"
+ category = ModulePart
+ LocalRoot = "core\em\UsbRecovery\OhciPEI\"
+ RefName = "OhciPei"
+[files]
+"OhciPei.c"
+"OhciPei.h"
+"OhciPeiBoard.c"
+[parts]
+"OHCI PPI"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/OhciPEI/OhciPei.h b/Core/EM/UsbRecovery/OhciPEI/OhciPei.h
new file mode 100644
index 0000000..d743f61
--- /dev/null
+++ b/Core/EM/UsbRecovery/OhciPEI/OhciPei.h
@@ -0,0 +1,909 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/OhciPei.h 9 11/24/12 5:44a Ryanchou $
+//
+// $Revision: 9 $
+//
+// $Date: 11/24/12 5:44a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/OhciPei.h $
+//
+// 9 11/24/12 5:44a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 8 8/23/12 9:59p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 7 1/18/11 1:00a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 6 3/17/09 5:09p Olegi
+//
+// 5 3/03/09 7:26p Olegi
+// MaximumPacketLength changed from UINT8 to UINT16.
+//
+// 4 7/18/08 5:04p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 3 7/10/08 6:36p Michaela
+// Updated to support OHCI controllers
+//
+// 2 9/22/06 12:23p Sivagarn
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+// - Merged multiple MAK and SDL files into one MAK and SDL file
+// - Removed unnecessary files
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: OhciPei.h
+//
+// Description: This file is the main header file for the OHCI PEI USB
+// recovery module. It contains generic constant and type
+// declarations/definitions.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _OHCIPEI_H
+#define _OHCIPEI_H
+
+#include "Efi.h"
+#include "Pei.h"
+#include "Ppi\UsbHostController.h"
+
+
+
+//----------------------------------------------------------------------------
+// Macros
+//----------------------------------------------------------------------------
+
+
+
+//----------------------------------------------------------------------------
+// OHCI_FIXED_DELAY_MS( OhciDevPtr, milliseconds )
+//
+// invokes a delay specified in milliseconds using the PEI_OHCI_DEV.StallPpi
+// member interface pointer, which is initialized from a EFI_PEI_STALL_PPI
+// interface.
+#define OHCI_FIXED_DELAY_MS( OhciDevPtr, milliseconds ) \
+ OhciDevPtr->StallPpi->Stall( OhciDevPtr->PeiServices, \
+ OhciDevPtr->StallPpi, milliseconds * 1000 );
+
+
+//----------------------------------------------------------------------------
+// MASK(high,low)
+//
+// defines a bit mask value with bits set in the bit
+// range specified from high down to low (zero-based)
+//
+// Notes:
+// 1) this is expected to be used only in 32-bit compiled code
+#ifndef MASK
+#define MAX_VAL 0xffffffff // maximum value supported by CPU
+#define MAX_BIT 31 // highest bit position in MAX_VAL
+#define MASK( high, low ) (\
+ ( MAX_VAL >> ( MAX_BIT - ( (high) - (low) ) ) ) \
+ << (low) \
+)
+#endif
+
+
+//----------------------------------------------------------------------------
+// READ_BITS(src,high,low)
+//
+// extracts a bit field shifted down to bit position 0 from src, where high
+// and low define the bit range (zero-based).
+//
+// Notes:
+// 1) this is expected to be used only in 32-bit compiled code
+#ifndef READ_BITS
+#define READ_BITS( src, high, low ) (\
+ ( (src) & MASK( (high), (low) ) ) \
+ >> (low) \
+)
+#endif
+
+
+//----------------------------------------------------------------------------
+// WRITE_BITS( src, val, high, low )
+//
+// returns the modified src after writing a bit field with val, where the bit
+// field's range is specified by high down to low.
+//
+// Notes:
+// 1) the user must ensure that the val fits in the bit range
+// 2) the bits in the range high:low are the only bits touched and
+// they are cleared and replaced with val
+// 3) this is expected to be used only in 32-bit compiled code
+#ifndef WRITE_BITS
+#define WRITE_BITS( src, val, high, low ) (\
+ ( (src) & ~MASK( (high), (low) ) ) \
+ | ( (val) << (low) ) \
+)
+#endif
+
+
+//----------------------------------------------------------------------------
+// ABORT_ON_ERROR( call )
+//
+// simplifies the task of returning EFI_STATUS value after an unsuccessful
+// function execution.
+#define ABORT_ON_ERROR( call ) {\
+ EFI_STATUS status = call; \
+ if ( EFI_ERROR( status ) ) {\
+ return status;}}
+
+
+//----------------------------------------------------------------------------
+// OHCI_PCI_ADDRESS( ControllerIndex, Register )
+//
+// allows easy generation of a valid PCI address using an index into the
+// gOhciControllerPciTable and a register number
+#define OHCI_PCI_ADDRESS( ControllerIndex, Register ) PEI_PCI_CFG_ADDRESS( \
+ gOhciControllerPciTable[ControllerIndex].Bus, \
+ gOhciControllerPciTable[ControllerIndex].Device, \
+ gOhciControllerPciTable[ControllerIndex].Function, \
+ Register )
+
+
+//----------------------------------------------------------------------------
+// EFI_SIGNATURE_32( A, B, C, D)
+//
+// defines a signature that can be used with the PEI_CR macro to return a
+// pointer to the data structure that contains the specified field and
+// signature
+#define EFI_SIGNATURE_16(A,B) ((A) | ((B)<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) \
+ (EFI_SIGNATURE_16((A),(B)) | (EFI_SIGNATURE_16((C),(D)) << 16))
+
+
+//----------------------------------------------------------------------------
+// PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( a )
+//
+// uses the _CR macro to obtain a pointer to a PEI_OHCI_DEV structure from
+// a PEI_USB_HOST_CONTROLLER_PPI interface pointer
+#define _CR( Record, TYPE, Field ) \
+ ( (TYPE *) ( (CHAR8 *) (Record) - (CHAR8 *) &( ( (TYPE *) 0 )->Field ) ) )
+#define PEI_RECOVERY_USB_OHCI_DEV_FROM_THIS( a ) \
+ _CR( a, PEI_OHCI_DEV, UsbHostControllerPpi )
+
+
+//----------------------------------------------------------------------------
+// GET_PORT_STATUS_REG_OFFSET( x )
+//
+//Macro to get the RhPortStatus register offset
+#define GET_PORT_STATUS_REG_OFFSET( x ) ( (x) + 21 ) // 0x54 / 4 = 21
+
+
+
+//----------------------------------------------------------------------------
+// Constants
+//
+// Notes:
+// 1) These constants are not associated with a particular structure
+// and are used globally withing OHCI-specific code
+//----------------------------------------------------------------------------
+
+
+
+// Standard OHCI PCI configuration space registers
+#define OHCI_BASE_ADDR_REG 0x10 // OHCI BAR register
+#define OHCI_CMD_REGISTER 0x04 // OHCI command register
+
+// Stantdard ED and TD list structure constants
+#define OHCI_TERMINATE 0x00000000
+
+
+
+//----------------------------------------------------------------------------
+// Structure types
+//
+// Notes:
+// 1) Constants that are associated with a particular structure
+// are defined locally within the structure to facilitate easier
+// maintenance.
+//----------------------------------------------------------------------------
+
+
+
+#pragma pack(push,1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: PCI_BUS_DEV_FUNCTION
+//
+// Description:
+// This structure type defines the bus, device and function number
+// that compose a PCI address.
+//
+// Fields: Type Name Description
+// ----------------------------------
+// UINT8 Bus PCI Bus on which a particular OHCI controller resides
+// UINT8 Device PCI Device number for a particular OHCI controller
+// UINT8 Function PCI Function number for a particular OHCI controller
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct
+{
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+} PCI_BUS_DEV_FUNCTION;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCI_PCI_PROGRAMMING_TABLE
+//
+// Description:
+// This structure type defines the parameters to be used in a call
+// to EFI_PEI_PCI_CFG_PPI.Modify(), when programming the PCI
+// configuration space for a particular OHCI controller.
+//
+// Fields: Type Name Description
+// ----------------------------------
+// EFI_PEI_PCI_CFG_PPI_WIDTH Size Size of the access
+// UINT32 Register Register/offset within the PCI configuration space
+// UINT32 SetBits Bits to set
+// UINT32 ClearBits Bits to clear
+//
+// Notes:
+// See also
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct
+{
+ EFI_PEI_PCI_CFG_PPI_WIDTH Size;
+ UINT32 Register;
+ UINT32 SetBits;
+ UINT32 ClearBits;
+} OHCI_PCI_PROGRAMMING_TABLE;
+
+
+typedef struct _HC_CONTROL
+{
+ union {
+ UINT32 AllBits;
+ // Set bits using the following
+ #define CONTROL_LIST_ENABLE BIT4
+ #define BULK_LIST_ENABLE BIT5
+ #define USB_RESET 0 << 6
+ #define USB_RESUME 1 << 6
+ #define USB_OPERATIONAL 2 << 6
+ #define USB_SUSPEND 3 << 6
+
+ struct
+ {
+ UINT32 ControlBulkServiceRatio : 2; // [1:0] CBSR
+ UINT32 PeriodicListEnable : 1; // [2] PLE
+ UINT32 IsochronousEnable : 1; // [3] IE
+ UINT32 ControlListEnable : 1; // [4] CLE
+ // Read: TRUE or FALSE
+
+ UINT32 BulkListEnable : 1; // [5] BLE
+ // Read: TRUE or FALSE
+
+ UINT32 HostControllerFunctionalState : 2; // [7:6] HCFS
+ // Write:
+ #define SET_USB_RESET 0
+ #define SET_USB_RESUME 1
+ #define SET_USB_OPERATIONAL 2
+ #define SET_USB_SUSPEND 3
+
+ UINT32 InterruptRouting : 1; // [8] IR
+ UINT32 RemoteWakeupConnected : 1; // [9] RWC
+ UINT32 RemoteWakeupEnable : 1; // [10] RWE
+ UINT32 Reserved : 21; // [31:11]
+ } Field;
+ };
+} HC_CONTROL;
+
+//
+// Notes:
+// To ensure proper updating, follow these guidelines:
+//
+// 1) Write all bits using the AllBits union element
+// (OR bit-constants if modifying multiple fields).
+//
+// * Writing individual bits may have adverse
+// effects.
+//
+// 2) Typically you will read individual bits using the
+// Field union element.
+//
+// 3) Writing a zero to any field in this register has
+// no effect.
+//
+typedef struct _HC_RH_PORT_STATUS
+{
+ union {
+ UINT32 AllBits;
+ #define SET_PORT_ENABLE BIT1
+ #define SET_PORT_SUSPEND BIT2
+ #define SET_PORT_RESET BIT4
+ #define SET_PORT_POWER BIT8
+
+ #define CLEAR_PORT_ENABLE BIT0
+ #define CLEAR_SUSPEND_STATUS BIT3
+ #define CLEAR_PORT_POWER BIT9
+ #define CLEAR_CONNECT_STATUS_CHANGE BIT16
+ #define CLEAR_PORT_ENABLE_STATUS_CHANGE BIT17
+ #define CLEAR_PORT_SUSPEND_STATUS_CHANGE BIT18
+ #define CLEAR_PORT_OVERCURRENT_INDICATOR_CHANGE BIT19
+ #define CLEAR_PORT_RESET_STATUS_CHANGE BIT20
+
+ struct
+ {
+ UINT32 CurrentConnectStatus : 1; // [0] CCS
+ #define RH_PORT_CLEAR_ENABLE 1
+ UINT32 PortEnableStatus : 1; // [1] PES
+ #define RH_PORT_SET_ENABLE 1
+ UINT32 PortSuspendStatus : 1; // [2] PSS
+ #define RH_PORT_SET_SUSPEND 1
+ UINT32 PortOverCurrentIndicator : 1; // [3] POCI
+ #define RH_PORT_CLEAR_SUSPEND 1
+ UINT32 PortResetStatus : 1; // [4] PRS
+ #define RH_SET_PORT_RESET 1 // write to initiate reset
+ #define RH_RESET_ACTIVE 1 // read set if reset active
+ UINT32 Reserved1 : 3; // [7:5]
+ UINT32 PortPowerStatus : 1; // [8] PPS
+ #define RH_PORT_POWER_ON 1
+
+ UINT32 LowSpeedDeviceAttached : 1; // [9] LSDA
+ UINT32 Reserved2 : 6; // [15:10]
+ UINT32 ConnectStatusChange : 1; // [16] CSC
+ #define RH_PORT_CLEAR_CONNECT_CHANGE 1
+ UINT32 PortEnableStatusChange : 1; // [17] PESC
+ #define RH_PORT_CLEAR_ENABLE_CHANGE 1
+ UINT32 PortSuspendStatusChange : 1; // [18] PSSC
+ UINT32 PortOverCurrentIndicatorChange : 1; // [19] OCIC
+ UINT32 PortResetStatusChange : 1; // [20] PRSC
+ #define RH_PORT_CLEAR_RESET_CHANGE 1
+ #define PORT_RESET_NOT_COMPLETE 0
+ #define PORT_RESET_COMPLETE 1
+ UINT32 Reserved3 : 11; // [31:21]
+ } Field;
+ };
+} HC_RH_PORT_STATUS;
+
+
+typedef struct _HC_INTERRUPT_STATUS
+{
+ union {
+ UINT32 AllBits;
+ struct
+ {
+ #define HCINT_STATUS_CLEAR 1 // write 1 to clear a status bit
+
+ UINT32 SchedulingOverrun : 1; // [0] SO
+ UINT32 WriteBackDoneHead : 1; // [1] WDH
+ #define HCINT_WB_DONE 1
+
+ UINT32 StartofFrame : 1; // [2] SF
+ UINT32 ResumeDetected : 1; // [3] RD
+ UINT32 UnrecoverableError : 1; // [4] UE
+ UINT32 FrameNumberOverflow : 1; // [5] FNO
+ UINT32 RootHubStatusChange : 1; // [6] RHSC
+ UINT32 Reserved1 : 23; // [29:7]
+ UINT32 OwnershipChange : 1; // [30] OC
+ UINT32 Reserved2 : 1; // [31]
+ } Field;
+ };
+} HC_INTERRUPT_STATUS;
+
+
+typedef struct _HC_RH_DESCRIPTORA
+{
+ union {
+ UINT32 AllBits;
+ #define POWERED_SAME (0 << 8)
+ #define POWERED_INDIVIDUALLY (1 << 8)
+ #define POWER_SWITCHED (0 << 9)
+ #define ALWAYS_POWERED (1 << 9)
+ #define OVERCURRENT_REPORTED_COLLECTIVELY (0 << 11)
+ #define OVERCURRENT_REPORTED_PER_PORT (1 << 11)
+ #define OVERCURRENT_COLLECTIVE_PROTECTION (0 << 12)
+ #define NO_OVERCURRENT_PROTECTION (1 << 12)
+
+ struct
+ {
+ UINT32 NumberDownstreamPorts : 8; // [7:0] NDP
+ UINT32 PowerSwitchingMode : 1; // [8] PSM
+ #define PSM_COLLECTIVE 0 // all ports powered same
+ #define PSM_PER_PORT 1 // ports powered individually
+
+ UINT32 NoPowerSwitching : 1; // [9] NPS
+ #define NPS_SWITCHED 0 // ports are individually
+ // power switched
+ #define NPS_NOT_SWITCHED 1 // ports are always on when
+ // HC is powered
+
+ UINT32 DeviceType : 1; // [10] DT (always 0)
+ UINT32 OverCurrentProtectionMode : 1; // [11] OCPM
+ #define OCPM_COLLECTIVE 0 // reported collectively
+ #define OCPM_PER_PORT 1 // reported per-port
+
+ UINT32 NoOverCurrentProtection : 1; // [12] NOCP
+ #define NOCP_PROTECTED 0 // reported collectively
+ #define NOCP_NOT_PROTECTED 1 // no support
+
+ UINT32 Reservered : 11; // [23:13]
+ UINT32 PowerOnToPowerGoodTime : 8; // [31:24] POTPGT
+ // (in units of 2ms)
+ } Field;
+ };
+} HC_RH_DESCRIPTORA;
+
+
+typedef struct _HC_RH_DESCRIPTORB
+{
+ union {
+ UINT32 AllBits;
+ #define ALL_REMOVEABLE (0x0000 << 0)
+ #define ALL_PER_PORT_POWER_SWITCHED (0xfffe << 15)
+ struct
+ {
+ UINT32 DeviceRemovable : 16; // [15:0] DR
+ // Each bit represents a port
+ // 0 = removable
+ // 1 = not removable
+ UINT32 PortPowerControlMask : 16; // [31:16] PPCM
+ // Each bit represents a port
+ // 0 = controlled by global
+ // power switch
+ // 1 = per-port power control
+ } Field;
+ };
+} HC_RH_DESCRIPTORB;
+
+typedef struct _HC_RH_STATUS
+{
+ union {
+ UINT32 AllBits;
+ struct
+ {
+ UINT32 LocalPowerStatus : 1; // [0] LPS
+ UINT32 OverCurrentIndicator : 1; // [1] OCI
+ UINT32 Reserved1 : 13; // [14:2]
+ UINT32 DeviceRemoteWakeupEnable : 1; // [15] DRWE
+ UINT32 LocalPowerStatusChange : 1; // [16] LPSC
+ // Write 1 to turn on power to all ports or to ports
+ // specified by PortPowerControlMask, depending on
+ // PowerSwitchingMode.
+ #define SET_GLOBAL_POWER 1
+
+ UINT32 OverCurrentIndicatorChange : 1; // [17] OCIC
+ UINT32 Reserved2 : 13; // [30:18]
+ UINT32 ClearRemoteWakeupEnable : 1; // [31] CRWE
+ } Field;
+ };
+} HC_RH_STATUS;
+
+typedef struct _HC_FM_INTERVAL
+{
+ union {
+ UINT32 AllBits;
+ struct
+ {
+ UINT32 FrameInterval : 14; // [13:0] FI
+ #define FM_INTERVAL_DEFAULT 0x2edf
+
+ UINT32 Reserved : 2; // [15:14]
+ UINT32 FsLargestDataPacket : 15; // [30:16] FSMPS
+ // (FrameInterval-210) * 6/7 ==> 0x2778
+ // (See OHCI specification)
+ #define FS_LARGEST_PACKET_DEFAULT 0x2778
+
+ UINT32 FrameIntervalToggle : 1; // [31] FIT
+ } Field;
+ };
+} HC_FM_INTERVAL;
+
+typedef struct _HC_HCCA
+{
+ #define OHCI_FRAME_LIST_SIZE 32
+ UINT32 HccaInterrruptTable[OHCI_FRAME_LIST_SIZE]; // Offset 0x00
+ UINT16 HccaFrameNumber; // Offset 0x80
+ UINT16 HccaPad1; // Offset 0x82
+ UINT32 HccaDoneHead; // Offset 0x84
+ UINT8 HccaReserved[120]; // Offset 0x88
+} HC_HCCA;
+
+typedef struct _HC_COMMAND_STATUS
+{
+ union {
+ UINT32 AllBits;
+ // Typically write to this entire register
+ #define SET_CONTROLLER_RESET (1 << 0)
+ #define SET_CONTROL_LIST_FILLED (1 << 1)
+ #define SET_BULK_LIST_FILLED (1 << 2)
+
+ struct
+ {
+ UINT32 HostControllerReset : 1; // [0] HCR
+ UINT32 ControlListFilled : 1; // [1] CLF
+ UINT32 BulkListFilled : 1; // [2] BLF
+ UINT32 OwnershipChangeRequest : 1; // [3] OCR
+ UINT32 Reserved1 : 12; // [15:4]
+ UINT32 SchedulingOverrunCount : 2; // [17:16] SOC
+ UINT32 Reserved2 : 14; // [31:18]
+ } Field;
+ };
+} HC_COMMAND_STATUS;
+
+typedef struct _OHCI_HC_REGISTERS_
+{
+ UINT32 HcRevision; // [31:0] (Offset 00)
+ HC_CONTROL HcControl; // [63:32] (Offset 04)
+ HC_COMMAND_STATUS HcCommandStatus; // [95:64] (Offset 08)
+ HC_INTERRUPT_STATUS HcInterruptStatus; // [127:96] (Offset 0C)
+ UINT32 HcInterruptEnable; // [159:128] (Offset 10)
+ UINT32 HcInterruptDisable; // [191:160] (Offset 14)
+ HC_HCCA *HcHcca; // [223:192] (Offset 18)
+ UINT32 HcPeriodCurrentEd; // [255:224] (Offset 1C)
+ UINT32 HcControlHeadEd; // [287:256] (Offset 20)
+ UINT32 HcControlCurrentEd; // [319:288] (Offset 24)
+ UINT32 HcBulkHeadEd; // [351:320] (Offset 28)
+ UINT32 HcBulkCurrentEd; // [383:352] (Offset 2C)
+ UINT32 HcDoneHead; // [415:384] (Offset 30)
+ HC_FM_INTERVAL HcFmInterval; // [447:416] (Offset 34)
+ UINT32 HcFmRemaining; // [479:448] (Offset 38)
+ HC_FM_INTERVAL HcFmNumber; // [511:480] (Offset 3C)
+ UINT32 HcPeriodicStart; // [543:512] (Offset 40)
+ UINT32 HcLsThreshold; // [575:544] (Offset 44)
+ HC_RH_DESCRIPTORA HcRhDescriptorA; // [607:576] (Offset 48)
+ HC_RH_DESCRIPTORB HcRhDescriptorB; // [639:608] (Offset 4C)
+ HC_RH_STATUS HcRhStatus; // [671:640] (Offset 50)
+ HC_RH_PORT_STATUS HcRhPortStatus[3]; // [767:672] (Offset 54)
+ UINT32 Reserved[40]; // [2047:768] (Offset 60)
+ UINT32 HceControl; // [2079:2048] (Offset 100)
+ UINT32 HceInput; // [2111:2080] (Offset 104)
+ UINT32 HceOutput; // [2143:2112] (Offset 108)
+ UINT32 HceStatus; // [2175:2144] (Offset 10C)
+} OHCI_HC_REGISTERS;
+
+
+typedef struct _OHCI_TD_
+{
+ UINT32 dControlStatus; // Control and status fields
+ #define GTD_BUFFER_ROUNDING (1 << 18) // [18] BufferRounding
+ #define GTD_SETUP_PACKET (0 << 19) // [20:19] Direction/PID
+ #define GTD_OUT_PACKET (1 << 19)
+ #define GTD_IN_PACKET (2 << 19)
+ #define GTD_INTD (0 << 21) // [23:21] DelayInterrupt
+ // depends on device
+ #define GTD_DATA_TOGGLE (3 << 24) // [25:24] DataToggle
+ #define GTD_SETUP_TOGGLE (2 << 24) // (see MSB of data toggle)
+ #define GTD_DATA1_TOGGLE (3 << 24)
+ #define GTD_NO_ERRORS (0 << 26) // [27:26] ErrorCount
+ #define GTD_STALL 0x04 // [31:28] ConditionCode
+ #define GTD_DEVICE_NOT_RESPOND 0x05
+ #define GTD_NOT_ACCESSED 0x0f
+
+ UINT8 *fpCurrentBufferPointer; // Current buffer pointer
+ UINT8 *fpLinkPointer; // Pointer to the next TD
+ UINT8 *fpBufferEnd; // End pointer of data buffer
+ #define MAX_CONTROL_DATA_SIZE 0x200
+
+ UINT32 dCSReloadValue; // Control status reload value
+ UINT8 bCallBackIndex; // Index of the routine to
+ // call
+ // on completion
+ UINT8 bActiveFlag; // Routine to call on
+ // completion
+ UINT8 bDeviceAddr; // Device Address
+ UINT8 bResvd;
+ UINT8 aSetupData[8]; // Used for setup packet
+} OHCI_TD, *POHCI_TD;
+
+typedef struct _OHCI_TD_DESCRIPTOR OHCI_TD_DESCRIPTOR;
+typedef struct _OHCI_TD_DESCRIPTOR
+{
+ union {
+ UINT32 AllBits;
+ struct
+ {
+ UINT32 Reserved : 18; // [17:0]
+ UINT32 BufferRounding : 1; // [18] R
+ UINT32 DirectionPid : 2; // [20:19] DP
+ UINT32 DelayInterrupt : 3; // [23:21] DI
+ UINT32 DataToggle : 2; // [25:24] T
+ UINT32 ErrorCount : 2; // [27:26] EC
+ UINT32 ConditionCode : 4; // [31:28] CC
+ // 0000 NOERROR
+ // 0001 CRC
+ // 0010 BITSTUFFING
+ // 0011 DATATOGGLEMISMATCH
+ // 0100 STALL
+ // 0101 DEVICENOTRESPONDING
+ // 0110 PIDCHECKFAILURE
+ // 0111 UNEXPECTEDPID
+ // 1000 DATAOVERRUN
+ // 1001 DATAUNDERRUN
+ // 1010 reserved
+ // 1011 reserved
+ // 1100 BUFFEROVERRUN
+ // 1101 BUFFERUNDERRUN
+ // 111x NOT ACCESSED
+ } Field;
+ } Controlfield;
+ UINT32 CurrentBufferPointer;
+ UINT32 NextTd;
+ UINT32 BufferEnd;
+} OHCI_TD_DESCRIPTOR;
+
+
+typedef struct _OHCI_ED_
+{
+ UINT32 dControl; // ED control fields
+ #define ED_OUT_PACKET 0x00000800
+ #define ED_IN_PACKET 0x00001000
+ #define ED_SKIP_TDQ BIT14
+ POHCI_TD fpTailPointer; // TD queue tail pointer
+ POHCI_TD fpHeadPointer; // TD queue head pointer
+ struct _OHCI_ED_ *fpEDLinkPointer; // Pointer to next ED
+ UINT8 aReserved[16];
+} OHCI_ED, *POHCI_ED;
+
+typedef struct _OHCI_EP_DESCRIPTOR OHCI_EP_DESCRIPTOR;
+typedef struct _OHCI_EP_DESCRIPTOR
+{
+ union {
+ UINT32 AllBits;
+ struct
+ {
+ UINT32 FunctionAddress : 7; // [6:0] FA
+ UINT32 EndpointNumber : 4; // [10:7] EN
+ UINT32 Direction : 2; // [12:11] D
+ UINT32 Speed : 1; // [13] S
+ UINT32 Skip : 1; // [14] K
+ UINT32 Format : 1; // [15] F
+ UINT32 MaximumPacketSize : 11; // [26:16] MPS
+ UINT32 Reserved : 5; // [31:27] Reserved
+ } Field;
+ } Controlfield;
+ UINT32 TailPointer;
+ union {
+ UINT32 AllBits;
+ struct
+ {
+ UINT32 Halted : 1; // [0] H
+ UINT32 ToggleCarry : 1; // [1] C
+ UINT32 Reserved : 29; // [31:2] Reserved
+ } Field;
+ } HeadPointer;
+ OHCI_EP_DESCRIPTOR *NextEndpointDescriptor;
+} OHCI_EP_DESCRIPTOR;
+
+
+typedef struct _OHCI_DESC_PTRS_
+{
+ POHCI_ED pstED1ms;
+ POHCI_ED pstED2ms;
+ POHCI_ED pstED8ms;
+ // Do not change the following order of ED32ms and TD32ms
+ POHCI_ED pstED32ms;
+ POHCI_TD pstTD32ms;
+ // Do not change the following order of EDRepeat and TDRepeat
+ POHCI_ED pstEDRepeat;
+ POHCI_TD pstTDRepeat;
+
+ POHCI_ED pstEDControl;
+ POHCI_TD pstTDControlSetup;
+ POHCI_TD pstTDControlData;
+ POHCI_TD pstTDControlStatus;
+
+ POHCI_ED pstEDInterrupt;
+ POHCI_TD pstTDInterruptData;
+
+ POHCI_ED pstEDBulk;
+ POHCI_TD pstTDBulkData;
+
+} OHCI_DESC_PTRS, *POHCI_DESC_PTRS;
+
+typedef struct _USB_HC_INFO_
+{
+ UINT32 dStateFlag;
+ UINT8 bHCNum;
+ UINT8 bHCType;
+ UINTN *HCCommArea;
+ UINTN BaseAddr;
+ UINT8 bPortNum;
+ UINT16 wBusDevFuncNum;
+ // FPIRQ_INFO
+ UINT16 wAsyncListSize;
+ UINT8 bOpRegOffset;
+ UINT32 dMaxBulkDataSize;
+ UINT8 bHCFlag;
+ // UINT8 bExtCapPtr; //EHCI
+ // UINT8 bRegOff;
+ VOID *usb_bus_data;
+ // EFI_HANDLE Controller;
+ // EFI_DEVICE_PATH_PROTOCOL *pHCdp;
+
+} USB_HC_INFO, *PUSB_HC_INFO;
+
+
+typedef struct _PEI_OHCI_DEV
+{
+ UINTN Signature;
+ #define PEI_OHCI_DEV_SIGNATURE EFI_SIGNATURE_32( 'p', 'u', 'h', 'c' )
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ EFI_PEI_CPU_IO_PPI *CpuIoPpi;
+ EFI_PEI_STALL_PPI *StallPpi;
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi;
+ UINT32 UsbHostControllerBaseAddress;
+
+ UINT8 bNumPorts;
+ OHCI_DESC_PTRS stOHCIDescPtrs;
+ UINT16 wAsyncListSize;
+ UINT32 dMaxBulkDataSize;
+ #define MAX_OHCI_BULK_DATA_SIZE 4096
+
+ UINT32 *pFrameList; // HC Communication Area base
+ // & HccaInterruptTable base
+} PEI_OHCI_DEV, *PPEI_OHCI_DEV;
+
+#pragma pack(pop)
+
+
+
+//----------------------------------------------------------------------------
+// Function prototypes
+//----------------------------------------------------------------------------
+
+
+
+EFI_STATUS InitializeUsbHC (
+ PEI_OHCI_DEV *UhcDev );
+
+VOID OhciInitHC (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_OHCI_DEV *pUhcDev,
+ UINT8 Index );
+
+VOID OhciHcReset (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_OHCI_DEV *pUhcDev );
+
+
+VOID OhciHcEnableRootHub (
+ PEI_OHCI_DEV *OhciDevPtr,
+ UINT8 PortNumber );
+
+EFI_STATUS OhciHcWaitForTransferComplete (
+ EFI_PEI_SERVICES **PeiServices,
+ PEI_OHCI_DEV *OhciDevPtr,
+ POHCI_TD Td );
+
+EFI_STATUS OhciHcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS OhciHcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS OhciHcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber );
+
+EFI_STATUS OhciHcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus );
+
+EFI_STATUS OhciHcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+EFI_STATUS OhciHcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c b/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c
new file mode 100644
index 0000000..4256cdf
--- /dev/null
+++ b/Core/EM/UsbRecovery/OhciPEI/OhciPeiBoard.c
@@ -0,0 +1,508 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/OhciPeiBoard.c 6 4/11/11 11:59p Rameshr $
+//
+// $Revision: 6 $
+//
+// $Date: 4/11/11 11:59p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/OhciPeiBoard.c $
+//
+// 6 4/11/11 11:59p Rameshr
+// [TAG]- EIP 57444
+// [Category]-IMPROVEMENT
+// [Description]- PI1.1 Support.
+// [Files]- OhciPeiboard.c,Xhcipei.c, Peiusblib.c
+//
+// 5 10/21/08 5:57p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 4 7/29/08 7:50p Michaela
+// cleaned-up SB700-specific code
+//
+// 3 7/29/08 5:50p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 2 7/18/08 5:04p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 1 7/10/08 6:35p Michaela
+// Updated to support OHCI controllers
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: OhciPeiBoard.c
+//
+// Description: This file contains routines that are board specific for
+// initializing the OHCI controller in the USB Recovery module.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <PPI/PeiGetUCtrl.h>
+#include <PPI/OhciPPI.h>
+#include <PPI/stall.h>
+#include "OhciPei.h"
+
+#ifndef PI_SPECIFICATION_VERSION //old Core
+extern EFI_STATUS PciCfgModify(
+IN CONST EFI_PEI_SERVICES **PeiServices,
+IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+IN UINT64 Address,
+IN UINTN SetBits,
+IN UINTN ClearBits
+);
+#endif
+
+//----------------------------------------------------------------------------
+// Porting Steps:
+//
+// 1) define/undefine the appropriate southbridge type
+// 2) define the OHCI_BASE register
+// 3) define registers and their set/clear bits for each register to be
+// modified in each controller's PCI configuration space
+//
+//----------------------------------------------------------------------------
+
+
+// #define AMD_8111 // define to initialize AMD 8111 SB
+
+// #define AMD_SB700 // define to initialize AMD SB700 SB
+
+#define OHCI_BASE PEI_OHCI_IOBASE // first OHCI device is defined
+ // by SDL token and others
+ // are programmatically
+ // determined
+
+#define OHCI_MMIO_SIZE 0x1000 // size of each MMIO region
+
+// For the SB700, the SMBUS PCI configuration space is used
+// to enable USB hardware in the Southbridge
+#define SMBUS_PCI_USB_ENABLE_CFG PEI_PCI_CFG_ADDRESS( 0, 0x14, 0, 0x68 )
+#define SMBUS_PCI_EHCI_BITS BIT2 | BIT6
+#define SMBUS_PCI_OHCI_BITS BIT0 | BIT1 | BIT4 | BIT5 | BIT7
+
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gOhciControllerPciTable
+//
+// Description:
+// This is an array of type: PCI_BUS_DEV_FUNCTION
+//
+// This array is initialized from the PEI_OHCI_PCI_DEVICES SDL
+// token, which specifies a {bus,device,function} entry for each OHCI
+// controller. If no OHCI controllers exist, there will be only one
+// NULL entry.
+//
+// This array is used for PCI initialization of OHCI controllers,
+// as well as access to PCI configuration registers.
+//
+// Notes:
+// gOhciControllerPciTable and gOhciControllerCount are accessed via
+// extern declarations by OHCI generic code to access PCI configuration
+// space registers.
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+PCI_BUS_DEV_FUNCTION gOhciControllerPciTable[] = {USBR_OHCI_CONTROLLER_PCI_ADDRESS};
+UINT16 gOhciControllerCount = \
+ sizeof(gOhciControllerPciTable) / sizeof(PCI_BUS_DEV_FUNCTION);
+
+
+//<AMI_THDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: gOhciPciRegisterTable
+//
+// Description:
+// This is an array of type: OHCI_PCI_PROGRAMMING_TABLE
+//
+// This array is initialized from the OHCI_CONTROLLER_PCI_REGISTER_VALUE
+// SDL eLink, which specifies a { RegisterSize, Register, BitsToSet,
+// BitsToClear } entry for each register in the PCI configuration space
+// that needs to be modified.
+//
+// This array is used for PCI initialization of OHCI controllers.
+//
+// Notes:
+// If no OHCI controllers exist, there will be only one
+// NULL entry.
+//
+// When this table is used, it is assumed that all OHCI controllers
+// are identically programmed for the platform.
+//
+// Other important notes are:
+//
+// 1) do not include the BAR register (the first BAR is
+// PEI_OHCI_IOBASE and subsequent BAR values are
+// calculated from there),
+// 2) the command register should be last, as it enables
+// the devices MMIO access space.
+//
+//---------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+OHCI_PCI_PROGRAMMING_TABLE gOhciPciRegisterTable[] = {USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE};
+#define OHCI_PCI_REGISTER_TABLE_SIZE \
+ sizeof(gOhciPciRegisterTable) / sizeof(OHCI_PCI_PROGRAMMING_TABLE)
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DefaultInit
+//
+// Description:
+// This function generically initializes the PCI configuration space
+// registers for all the OHCI controllers whose PCI addresses are
+// specified by the global PCI_BUS_DEV_FUNCTION array and whose PCI
+// register programming details are specified by the global
+// OHCI_PCI_PROGRAMMING_TABLE array.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN EFI_PEI_PCI_CFG_PPI *Pci
+// -- EFI_PEI_PCI_CFG_PPI pointer
+// IN EFI_PEI_STALL_PPI *StallPpi
+// -- EFI_PEI_STALL_PPI pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+// Notes:
+// This function should not need porting. All porting is accomplished
+// in the global PCI_BUS_DEV_FUNCTION and OHCI_PCI_PROGRAMMING_TABLE
+// arrays, where the former is defined by the
+// USBR_OHCI_CONTROLLER_PCI_ADDRESS SDL eLink and the latter is defined
+// by the USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE SDL eLink.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS DefaultInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *Pci,
+ IN EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status;
+ UINT32 OhciBaseAddress = OHCI_BASE;
+ UINT16 ControllerIndex;
+ UINT16 RegisterIndex;
+
+
+ //------------------------------------------------------------------------
+ // PCI configuration space programming for all OHCI controllers
+ //------------------------------------------------------------------------
+ for (ControllerIndex = 0;
+ ControllerIndex < gOhciControllerCount;
+ ControllerIndex++, OhciBaseAddress += OHCI_MMIO_SIZE)
+ {
+
+ // Program the BAR
+ //~~~~~~~~~~~~~~~~
+ ABORT_ON_ERROR(
+ Pci->Write( PeiServices, Pci,
+ EfiPeiPciCfgWidthUint32,
+ OHCI_PCI_ADDRESS( ControllerIndex, OHCI_BASE_ADDR_REG ),
+ &OhciBaseAddress );
+ )
+
+ // Program all other registers using gOhciPciRegisterTable[]
+ //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ for (RegisterIndex = 0;
+ RegisterIndex < OHCI_PCI_REGISTER_TABLE_SIZE;
+ RegisterIndex++)
+ {
+ EFI_PEI_PCI_CFG_PPI_WIDTH Width;
+
+ switch (gOhciPciRegisterTable[RegisterIndex].Size)
+ {
+ case 8:
+ Width = EfiPeiPciCfgWidthUint8;
+ break;
+ case 16:
+ Width = EfiPeiPciCfgWidthUint16;
+ break;
+ case 32:
+ Width = EfiPeiPciCfgWidthUint32;
+ break;
+ case 64:
+ Width = EfiPeiPciCfgWidthUint64;
+ break;
+ default:
+ continue;
+ }
+
+ ABORT_ON_ERROR(
+ PciCfgModify(
+ PeiServices,
+ Width,
+ OHCI_PCI_ADDRESS( ControllerIndex,
+ gOhciPciRegisterTable[RegisterIndex].Register ),
+ gOhciPciRegisterTable[RegisterIndex].SetBits,
+ gOhciPciRegisterTable[RegisterIndex].ClearBits );
+ )
+ }
+ }
+
+ return Status = EFI_SUCCESS;
+}
+
+
+#ifdef AMD_8111
+//-----------------------------------------------------
+// This code is not tested, it is simply preserved here
+//-----------------------------------------------------
+
+#define REG_PRI_MEMBASE 0x20
+#define REG_PRI_MEMLIM 0x22
+
+EFI_STATUS Amd8111Init (
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_PCI_CFG_PPI *Pci,
+ EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status;
+ UINT32 Buffer32;
+ UINT16 Buffer16;
+ UINT16 CmdReg;
+ volatile UINT32 BaseAddress;
+
+ //
+ // OHCI is sits behind the PCI brige. So program the PCI bridge
+ // First program bus numbers so that PCI slots are available
+ //
+ Buffer32 = 0x080800;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint32,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, REG_PRI_BNUM ),
+ &Buffer32
+ );
+
+
+ // Defines the base of memory range for PCI. 15:4 this 12 bits corresponds
+ // to 31:20 of mem addr 1MB boundary
+ BaseAddress = 0xc0c00000;
+ BaseAddress >>= 16;
+ BaseAddress &= 0xfffffff0;
+ Buffer16 = (UINT16) BaseAddress;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, REG_PRI_MEMBASE ),
+ &Buffer16
+ );
+
+ //Defines the top of the memory range
+ // BaseAddress = 0xc0c00000;
+ // BaseAddress += 0x00100000;
+ // BaseAddress >>= 16;
+ // BaseAddress &= 0xfffffff0;
+ // Buffer16 = (UINT16)BaseAddress;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, REG_PRI_MEMLIM ),
+ &Buffer16
+ );
+
+ //Program the prefectable memory space also.
+ BaseAddress = 0xc0c00000;
+ BaseAddress += 0x00100000;
+ BaseAddress >>= 16;
+ BaseAddress &= 0xfffffff0;
+ Buffer16 = (UINT16) BaseAddress;
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x24 ),
+ &Buffer16
+ );
+
+ Pci->Write( PeiServices, Pci, EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x26 ),
+ &Buffer16
+ );
+
+
+ //Enable memory space, bus mastering of the root bridge
+ Pci->Read(
+ PeiServices,
+ Pci,
+ EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x04 ),
+ &CmdReg
+ );
+ CmdReg = (UINT16) (CmdReg | 0x06);
+ Pci->Write(
+ PeiServices,
+ Pci,
+ EfiPeiPciCfgWidthUint16,
+ PEI_PCI_CFG_ADDRESS( 0, 30, 0, 0x04 ),
+ &CmdReg
+ );
+}
+#endif // #ifdef AMD_8111
+
+
+#ifdef AMD_SB700
+EFI_STATUS AmdSb700Init (
+ IN EFI_PEI_SERVICES **PeiServices,
+ EFI_PEI_PCI_CFG_PPI *Pci,
+ EFI_PEI_STALL_PPI *StallPpi )
+{
+
+ //-----------------------------------------------------------------------
+ // Enable OHCI controllers from the SMBUS PCI configuration space
+ // using the SMBUS PCI space USB enable register
+ //
+ // By default, the companion controller (OHCI) should be the owner
+ // of the root hub port, so the EHCI controller hardware block
+ // does not need to be disabled.
+ //-----------------------------------------------------------------------
+ ABORT_ON_ERROR(
+ PciCfgModify( PeiServices,
+ EfiPeiPciCfgWidthUint8,
+ SMBUS_PCI_USB_ENABLE_CFG,
+ SMBUS_PCI_OHCI_BITS + SMBUS_PCI_EHCI_BITS,
+ 0
+ )
+ )
+
+ return EFI_SUCCESS;
+}
+#endif // #ifdef AMD_SB700
+
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OhciPeiBoardInit
+//
+// Description:
+// This is a porting hook for board-specific OHCI controller
+// initialization
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices -
+// IN EFI_PEI_PCI_CFG_PPI *Pci -
+// IN EFI_PEI_STALL_PPI *StallPpi -
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS OhciPeiBoardInit (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *Pci,
+ IN EFI_PEI_STALL_PPI *StallPpi )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ // SB-specific programming
+ #if defined (AMD_8111)
+ Status = Amd8111Init( PeiServices, Pci, StallPpi );
+ #elif defined (AMD_SB700)
+ Status = AmdSb700Init( PeiServices, Pci, StallPpi );
+ #endif
+
+ // Generic programming for all OHCI SB, should be called
+ // for all types of southbridges after platform-specific
+ // programming has been done.
+ if (!EFI_ERROR(Status)){
+ Status = DefaultInit( PeiServices, Pci, StallPpi );
+ }
+
+ // PCI root bridge programming is done.
+ // At this stage the OHCI controller should be visible and
+ // Memory mapped IO space should be visible
+
+ return Status;
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/PeiUsbLib.c b/Core/EM/UsbRecovery/PeiUsbLib.c
new file mode 100644
index 0000000..2348910
--- /dev/null
+++ b/Core/EM/UsbRecovery/PeiUsbLib.c
@@ -0,0 +1,825 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/PeiUsbLib.c 10 11/24/12 5:43a Ryanchou $
+//
+// $Revision: 10 $
+//
+// $Date: 11/24/12 5:43a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/PeiUsbLib.c $
+//
+// 10 11/24/12 5:43a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 9 4/12/11 12:00a Rameshr
+// [TAG]- EIP 57444
+// [Category]-IMPROVEMENT
+// [Description]- PI1.1 Support.
+// [Files]- OhciPeiboard.c,Xhcipei.c, Peiusblib.c
+//
+// 8 10/11/10 4:51p Olegi
+// XHCI support added.
+//
+// 7 4/06/10 3:37p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 6 3/17/09 5:10p Olegi
+// Added IsPortHighSpeedDeviceAttached function.
+//
+// 5 7/18/08 5:03p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 4 7/10/08 6:33p Michaela
+// Updated to support OHCI controllers
+//
+// 3 4/16/07 1:02p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:07a Meenakshim
+// Removed dependency on core source files..Added amimapping file.
+//
+// 1 9/22/06 4:07p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: PeiUsbLib.C
+//
+// Description:
+// This file belongs to "Framework" and included here for
+// compatibility purposes. This file is modified by AMI to include
+// copyright message, appropriate header and integration code.
+// This file contains generic routines needed for USB recover
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ PeiUsbLib.c
+
+ Abstract:
+
+ Common Libarary for PEI USB
+
+ Revision History
+
+ --*/
+
+#include "Efi.h"
+#include "Pei.h"
+#include "usb.h"
+#include "UsbPeim.h"
+#include "PeiUsbLib.h"
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ZeroMem
+//
+// Description: This library function initializes provided buffer with Zero
+//
+// Input: *Buffer Pointer to the buffer whose content to be inited
+// Size Number of bytes to be filled in
+//
+// Output: Returns None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ZeroMem (
+ OUT VOID *Buffer,
+ IN UINTN Size )
+{
+ UINT8 *Ptr;
+
+ Ptr = Buffer;
+ while (Size--) {
+ *(Ptr++) = 0;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiCopyMem
+//
+// Description:
+// This library function copies bytes specified by Length from the memory
+// location specified by Source to the memory location specified by
+// Destination.
+//
+// Input:
+// OUT VOID *Destination
+// -- Target memory location of copy
+// IN VOID *Source
+// -- Source memory location
+// IN UINTN Length
+// -- Number of bytes to copy
+//
+// Output:
+// VOID (No Return Value)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PeiCopyMem (
+ OUT VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length )
+{
+ CHAR8 *Destination8;
+ CHAR8 *Source8;
+
+ Destination8 = Destination;
+ Source8 = Source;
+ while (Length--) {
+ *(Destination8++) = *(Source8++);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiUsbGetDescriptor
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to obtain a device
+// descriptor.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+// IN UINT16 Value
+// -- The upper byte of Value specifies the type of
+// descriptor and the lower byte of Value specifies
+// the index (for configuration and string descriptors)
+// IN UINT16 Index
+// -- Specifies the Language ID for string descriptors
+// or zero for all other descriptors
+// IN UINT16 DescriptorLength
+// -- Specifies the length of the descriptor to be
+// retrieved
+// IN VOID *Descriptor
+// -- Allocated buffer in which the descriptor will be
+// returned
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+// Notes:
+// The lower byte of Value is typically zero and the upper byte of
+// Value specifies the type of descriptor:
+//
+// READ_BITS(Value,15,8) Descriptor
+// -------------------------------------------------
+// 1 DEVICE
+// 2 CONFIGURATION
+// 3 STRING
+// 4 INTERFACE
+// 5 ENDPOINT
+// 6 DEVICE_QUALIFIER
+// 7 OTHER_SPEED_CONFIGURATION
+// 8 INTERFACE_POWER
+//
+// For additional reference, read the USB Device Framework chapter in
+// the USB Specification (Revision 2.0)
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbGetDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 Value,
+ IN UINT16 Index,
+ IN UINT16 DescriptorLength,
+ IN VOID *Descriptor )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 Timeout;
+
+ if (UsbIoPpi == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
+ DevReq.Request = USB_DEV_GET_DESCRIPTOR;
+ DevReq.Value = Value;
+ DevReq.Index = Index;
+ DevReq.Length = DescriptorLength;
+
+ Timeout = 3000;
+
+ return UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ Descriptor,
+ DescriptorLength
+ );
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiUsbSetDeviceAddress
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to set the device's
+// address on the USB bus for all future accesses.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+// IN UINT16 AddressValue
+// -- The device address to be set
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbSetDeviceAddress (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 AddressValue )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 Timeout;
+
+ if (UsbIoPpi == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DevReq.RequestType = USB_DEV_SET_ADDRESS_REQ_TYPE;
+ DevReq.Request = USB_DEV_SET_ADDRESS;
+ DevReq.Value = AddressValue;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+
+ return UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiUsbClearDeviceFeature
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to clear or disable a
+// specific feature.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+// IN EFI_USB_RECIPIENT Recipient
+// -- The recipient of the request can be a device,
+// an interface or an endpoint respectively specified
+// by EfiUsbDevice, EfiUsbInterface or EfiUsbEndpoint.
+// IN UINT16 Value
+// -- The feature selector to be cleared or disabled
+// IN UINT16 Target
+// -- This value specifies an index for a specific
+// interface/endpoint or zero for device recipients.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbClearDeviceFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN EFI_USB_RECIPIENT Recipient,
+ IN UINT16 Value,
+ IN UINT16 Target )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 Timeout;
+
+ if (UsbIoPpi == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ switch (Recipient)
+ {
+ case EfiUsbDevice:
+ DevReq.RequestType = 0x00;
+ break;
+
+ case EfiUsbInterface:
+ DevReq.RequestType = 0x01;
+ break;
+
+ case EfiUsbEndpoint:
+ DevReq.RequestType = 0x02;
+ break;
+ }
+
+ DevReq.Request = USB_DEV_CLEAR_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = Target;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+
+ return UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiUsbSetConfiguration
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to set the device's
+// default configuration index of 1.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbSetConfiguration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
+ DevReq.Request = USB_DEV_SET_CONFIGURATION;
+ DevReq.Value = 1; // default
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+
+ return UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiUsbClearEndpointHalt
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to clear a bulk Endpoint
+// halt condition (and resetting the Halt status bit) for a specified
+// Endpoint.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+// IN UINT8 EndpointAddress
+// -- The endpoint for which the Halt condition is to be
+// cleared
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbClearEndpointHalt (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 EndpointAddress )
+{
+ EFI_STATUS Status;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
+ UINT8 EndpointIndex = 0;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+
+ while (EndpointIndex < MAX_ENDPOINT) {
+ Status = UsbIoPpi->UsbGetEndpointDescriptor( PeiServices, UsbIoPpi,
+ EndpointIndex, &EndpointDescriptor );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (EndpointDescriptor->EndpointAddress == EndpointAddress) {
+ break;
+ }
+
+ EndpointIndex++;
+ }
+
+ if (EndpointIndex == MAX_ENDPOINT) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = PeiUsbClearDeviceFeature(
+ PeiServices,
+ UsbIoPpi,
+ EfiUsbEndpoint,
+ EfiUsbEndpointHalt,
+ EndpointAddress
+ );
+
+ //
+ // set data toggle to zero.
+ //
+ if ( ( PeiUsbDev->DataToggle & (1 << EndpointIndex) ) != 0 ) {
+ PeiUsbDev->DataToggle =
+ (UINT8) ( PeiUsbDev->DataToggle ^ (1 << EndpointIndex) );
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsPortConnect
+//
+// Description:
+// This function returns true if the Hub Class device's Current Connect
+// Status bit is set in the port status value specified by PortStatus.
+//
+// Input:
+// IN UINT16 PortStatus
+// -- This value is the USB Specification (Revision 2.0)
+// Hub Port Status Field value as returned by the Get
+// Port Status Hub Class device standard request.
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if a device is present or FALSE if a device is not
+// present
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsPortConnect (
+ IN UINT16 PortStatus )
+{
+ //
+ // return the bit 0 value of PortStatus
+ //
+ if ( (PortStatus & USB_PORT_STAT_CONNECTION) != 0 ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsPortEnable
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsPortEnable (
+ IN UINT16 PortStatus )
+{
+ //
+ // return the bit 0 value of PortStatus
+ //
+ if ( (PortStatus & USB_PORT_STAT_ENABLE) != 0 ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsPortLowSpeedDeviceAttached
+//
+// Description:
+// This function returns true if the Hub Class device's Low-Speed
+// Device Attached bit is set in the port status value specified by
+// PortStatus.
+//
+// Input:
+// IN UINT16 PortStatus
+// -- This value is the USB Specification (Revision 2.0)
+// Hub Port Status Field value as returned by the Get
+// Port Status Hub Class device standard request.
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if a low-speed device is present or FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsPortLowSpeedDeviceAttached (
+ UINT16 PortStatus )
+{
+ //
+ // return the bit 9 value of PortStatus
+ //
+ if ( (PortStatus & USB_PORT_STAT_LOW_SPEED) != 0 ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsPortHighSpeedDeviceAttached
+//
+// Description:
+// This function returns true if the Hub Class device's High-Speed
+// Device Attached bit is set in the port status value specified by
+// PortStatus.
+//
+// Input:
+// IN UINT16 PortStatus
+// -- This value is the USB Specification (Revision 2.0)
+// Hub Port Status Field value as returned by the Get
+// Port Status Hub Class device standard request.
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if a high-speed device is present or FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsPortHighSpeedDeviceAttached (
+ UINT16 PortStatus )
+{
+ //
+ // return the bit 10 value of PortStatus
+ //
+ if ( (PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0 ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsPortSuperSpeedDeviceAttached
+//
+// Description:
+// This function returns true if connect status indicates the SuperSpeed
+// device.
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if a super-speed device is present or FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsPortSuperSpeedDeviceAttached (
+ UINT16 PortStatus )
+{
+ //
+ // return the bit 10 value of PortStatus
+ //
+ if ( (PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0 ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IsPortConnectChange
+//
+// Description:
+// This function returns true if the Hub Class device's Connect Status
+// Change bit is set in the port change status value specified
+// by PortChangeStatus.
+//
+// Input:
+// IN UINT16 PortStatus
+// -- This value is the USB Specification (Revision 2.0)
+// Hub Port Change Field value as returned by the Get
+// Port Status Hub Class device standard request.
+//
+// Output:
+// BOOLEAN (Return Value)
+// = TRUE if Current Connect status has changed or FALSE
+// if no change has occurred to Current Connect status
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsPortConnectChange (
+ UINT16 PortChangeStatus )
+{
+ //
+ // return the bit 0 value of PortChangeStatus
+ //
+ if ( (PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0 ) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+#ifndef PI_SPECIFICATION_VERSION //old Core
+
+EFI_STATUS PciCfgModify(
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+ IN UINT64 Address,
+ IN UINTN SetBits,
+ IN UINTN ClearBits)
+{
+ if((*PeiServices)->PciCfg==NULL)
+ return EFI_NOT_AVAILABLE_YET;
+
+ return (*PeiServices)->PciCfg->Modify(
+ (EFI_PEI_SERVICES**)PeiServices,
+ (*PeiServices)->PciCfg,
+ Width, Address,
+ SetBits, ClearBits);
+}
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/PeiUsbLib.h b/Core/EM/UsbRecovery/PeiUsbLib.h
new file mode 100644
index 0000000..d6c14dd
--- /dev/null
+++ b/Core/EM/UsbRecovery/PeiUsbLib.h
@@ -0,0 +1,171 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/PeiUsbLib.h 5 11/24/12 5:43a Ryanchou $
+//
+// $Revision: 5 $
+//
+// $Date: 11/24/12 5:43a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/PeiUsbLib.h $
+//
+// 5 11/24/12 5:43a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 4 10/11/10 4:51p Olegi
+// XHCI support added.
+//
+// 3 3/17/09 5:10p Olegi
+//
+// 2 7/10/08 6:33p Michaela
+// Updated to support OHCI controllers
+//
+// 1 9/22/06 4:07p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: PeiUsbLib.H
+//
+// Description: This file belongs to "Framework" and included here for
+// compatibility purposes. This file is modified by AMI to include
+// copyright message, appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains 'Framework Code' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may not be modified, except as allowed by
+// additional terms of your license agreement.
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ PeiUsbLib.h
+
+ Abstract:
+
+ Common Libarary for PEI USB
+
+ Revision History
+
+ --*/
+
+#ifndef _PEI_USB_LIB_H
+#define _PEI_USB_LIB_H
+
+EFI_STATUS
+PeiUsbGetDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 Value,
+ IN UINT16 Index,
+ IN UINT16 DescriptorLength,
+ IN VOID *Descriptor );
+
+EFI_STATUS
+PeiUsbSetDeviceAddress (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 AddressValue );
+
+EFI_STATUS
+PeiUsbClearDeviceFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN EFI_USB_RECIPIENT Recipient,
+ IN UINT16 Value,
+ IN UINT16 Target );
+
+EFI_STATUS
+PeiUsbSetConfiguration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi );
+
+EFI_STATUS
+PeiUsbClearEndpointHalt (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 EndpointAddress );
+
+BOOLEAN
+IsPortConnect (
+ UINT16 PortStatus );
+
+BOOLEAN
+IsPortEnable (
+ UINT16 PortStatus );
+
+BOOLEAN
+IsPortLowSpeedDeviceAttached (
+ UINT16 PortStatus );
+
+BOOLEAN
+IsPortHighSpeedDeviceAttached (
+ UINT16 PortStatus );
+
+BOOLEAN
+IsPortSuperSpeedDeviceAttached (
+ UINT16 PortStatus );
+
+BOOLEAN
+IsPortConnectChange (
+ UINT16 PortChangeStatus );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/USBRecoverySrc.chm b/Core/EM/UsbRecovery/USBRecoverySrc.chm
new file mode 100644
index 0000000..fdee69a
--- /dev/null
+++ b/Core/EM/UsbRecovery/USBRecoverySrc.chm
Binary files differ
diff --git a/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.c b/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.c
new file mode 100644
index 0000000..ee535dd
--- /dev/null
+++ b/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.c
@@ -0,0 +1,3575 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UhcPeimSrc/UhcPeim.c 17 11/24/12 5:45a Ryanchou $
+//
+// $Revision: 17 $
+//
+// $Date: 11/24/12 5:45a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UhcPeimSrc/UhcPeim.c $
+//
+// 17 11/24/12 5:45a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 16 8/23/12 10:00p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 15 1/18/11 1:01a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 14 10/22/10 2:53a Rameshr
+// [TAG]- EIP 43687
+// [Category]-IMPROVEMENT
+// [Description]- Build warning from UsbRecovery driver -
+// UsbHostController.obj : warning LNK4221: no public symbols found;
+// archive member will be inaccessible.
+// [Files]- uhcpeim.c, usbpeim.c, UsbHostcontroller.h
+//
+// 13 10/12/10 11:19a Olegi
+// XHCI support added.
+//
+// 12 4/06/10 3:32p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 11 4/29/09 2:13p Olegi
+// Added TreansactionTranslator to UHCI Bulk transfer.
+//
+// 10 3/17/09 5:06p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 9 3/03/09 7:20p Olegi
+// Changed the type of MaxPktSize from UINT8 to UINT16.
+//
+// 8 11/19/08 12:03p Rameshraju
+// Continue to initilize other UCHI controllers on the system when Uchi
+// controller initilization is failed.
+//
+// 7 10/23/08 2:00p Michaela
+// Removed UsbDebug.h include
+//
+// 6 10/21/08 5:57p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 5 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 4 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 3 10/23/07 5:40p Ambikas
+//
+// 2 8/17/07 4:06p Ambikas
+//
+// 1 9/22/06 12:21p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UhcPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UhcPeim.c
+
+ Abstract:
+
+ Usb Host Controller PEIM
+
+ --*/
+
+#include "UhcPeim.h"
+
+#include EFI_PPI_DEFINITION( LoadFile )
+//#include "PeiUsbLib.h"
+
+EFI_GUID guidGetUhciController = EFI_PEI_GET_UHCI_CTRLER_GUID;
+static EFI_GUID gPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+EFI_GUID gPeiCpuIoPpiInServiceTableGuid =
+ EFI_PEI_CPU_IO_PPI_INSTALLED_GUID;
+
+#define PAGESIZE 4096
+#include EFI_PPI_DEFINITION( LoadFile )
+
+
+//
+// PEIM Entry Ppint
+//
+EFI_STATUS
+UhcPeimEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+
+UINT32
+USBReadPortDW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port );
+void
+PrintTD (
+ TD_STRUCT *ptrTD,
+ USB_UHC_DEV *UhcDev );
+void
+PrintQH (
+ QH_STRUCT *ptrQH,
+ USB_UHC_DEV *UhcDev );
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+
+EFI_STATUS UhcPeimEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ PEI_CPU_IO_PPI *CpuIoPpi;
+ PEI_STALL_PPI *StallPpi;
+ EFI_PEI_USB_CONTROLLER_PPI *ChipSetUsbControllerPpi;
+ EFI_STATUS Status;
+ UINT8 Index;
+ UINTN ControllerType;
+ UINTN BaseAddress;
+ USB_UHC_DEV *UhcDev;
+
+ // Locate the PEI_CPU_IO_PPI interface
+ if ( EFI_ERROR( (**PeiServices).LocatePpi(
+ PeiServices, &gPeiCpuIoPpiInServiceTableGuid, 0, NULL,
+ &CpuIoPpi ) ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Locate the PEI_STALL_PPI interface
+ if ( EFI_ERROR( (**PeiServices).LocatePpi(
+ PeiServices, &gPeiStallPpiGuid, 0, NULL, &StallPpi ) ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Locate the EFI_PEI_USB_CONTROLLER_PPI interface
+ if ( EFI_ERROR( (**PeiServices).LocatePpi(
+ PeiServices, &guidGetUhciController, 0, NULL,
+ &ChipSetUsbControllerPpi ) ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //--------------------------------------------------
+ // For each UHCI controller found:
+ //
+ // 1) Verify it is a UHCI controller
+ // 2) Allocate and initialize a USB_UHC_DEV structure
+ // to manage the controller.
+ // 3) Initialize the controller.
+ // 4) Install the PEI_USB_HOST_CONTROLLER_PPI interface.
+ //
+ //--------------------------------------------------
+ Index = 0;
+ while (TRUE) {
+
+ // GetUhciControllerPpi() returns error if no more controllers
+ if ( EFI_ERROR( ChipSetUsbControllerPpi->GetUhciControllerPpi(
+ PeiServices, ChipSetUsbControllerPpi, Index,
+ &ControllerType,
+ &BaseAddress ) ) ) {
+ break;
+ }
+
+ // This PEIM is for UHC type controller.
+ if (ControllerType != PEI_UHCI_CONTROLLER) {
+ Index++;
+ continue;
+ }
+
+ // Allocate and initialize USB_UHC_DEV members
+ if ( EFI_ERROR( (**PeiServices).AllocatePages(
+ PeiServices, EfiConventionalMemory,
+ sizeof(USB_UHC_DEV) / PAGESIZE + 1,
+ (EFI_PHYSICAL_ADDRESS *) &UhcDev ) ) ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ UhcDev->Signature = USB_UHC_DEV_SIGNATURE;
+ UhcDev->PeiServices = PeiServices;
+ UhcDev->CpuIoPpi = (*PeiServices)->CpuIo;
+ UhcDev->StallPpi = StallPpi;
+ UhcDev->UsbHostControllerBaseAddress = (UINT32) BaseAddress;
+
+ // Initialize Uhc's hardware
+ Status = InitializeUsbHC( UhcDev );
+ if ( EFI_ERROR( Status ) ) {
+ PEI_TRACE( (EFI_D_ERROR, PeiServices,
+ "UHCPEIM: BaseAddress %x\n", BaseAddress) );
+ PEI_TRACE( (EFI_D_ERROR, PeiServices,
+ "UHCPEIM: InitializeUSbHC Status %r\n", Status) );
+ // error in initilizing the controller , so try for next controller
+ Index++;
+ continue;
+ }
+
+ // Init local memory management service
+ Status = InitializeMemoryManagement( UhcDev );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ // Update PEI_USB_HOST_CONTROLLER_PPI members
+ UhcDev->UsbHostControllerPpi.ControlTransfer = UhcControlTransfer;
+ UhcDev->UsbHostControllerPpi.BulkTransfer = UhcBulkTransfer;
+ UhcDev->UsbHostControllerPpi.GetRootHubPortNumber =
+ UhcGetRootHubPortNumber;
+ UhcDev->UsbHostControllerPpi.GetRootHubPortStatus =
+ UhcGetRootHubPortStatus;
+ UhcDev->UsbHostControllerPpi.SetRootHubPortFeature =
+ UhcSetRootHubPortFeature;
+ UhcDev->UsbHostControllerPpi.ClearRootHubPortFeature =
+ UhcClearRootHubPortFeature;
+ UhcDev->UsbHostControllerPpi.PreConfigureDevice = NULL;
+ UhcDev->UsbHostControllerPpi.EnableEndpoints = NULL;
+
+ // Install the PEI_USB_HOST_CONTROLLER_PPI interface
+ // for this controller
+ UhcDev->PpiDescriptor.Flags = (EFI_PEI_PPI_DESCRIPTOR_PPI
+ |
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ UhcDev->PpiDescriptor.Guid = &gPeiUsbHostControllerPpiGuid;
+ UhcDev->PpiDescriptor.Ppi = &UhcDev->UsbHostControllerPpi;
+ if ( EFI_ERROR( (**PeiServices).InstallPpi(
+ PeiServices, &UhcDev->PpiDescriptor ) ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Index++;
+ }
+
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "UHCPEIM: Exit() \n") );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS UhcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ USB_UHC_DEV *UhcDev;
+ UINT32 StatusReg;
+ UINT32 FrameNumReg;
+ UINT8 PktID;
+ QH_STRUCT *ptrQH;
+ TD_STRUCT *ptrTD;
+ TD_STRUCT *ptrPreTD;
+ TD_STRUCT *ptrSetupTD;
+ TD_STRUCT *ptrStatusTD;
+ EFI_STATUS Status;
+ UINTN i;
+ UINT32 DataLen;
+ UINT8 *ptrDataSource;
+ UINT8 *ptr;
+ UINT8 DataToggle;
+ UINT16 LoadFrameListIndex;
+
+ UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( This );
+
+ StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS;
+ FrameNumReg = UhcDev->UsbHostControllerBaseAddress + USBFRNUM;
+
+ PktID = INPUT_PACKET_ID;
+ // PEI_TRACE ((EFI_D_ERROR, PeiServices, "Enter UhcControlTransfer\n"));
+
+ if (Request == NULL || TransferResult == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // if errors exist that cause host controller halt,
+ // then return EFI_DEVICE_ERROR.
+ //
+ if ( IsHCHalted( UhcDev, StatusReg ) ||
+ IsHCProcessErr( UhcDev, StatusReg ) ||
+ IsHostSysErr( UhcDev, StatusReg ) ) {
+
+ ClearStatusReg( UhcDev, StatusReg );
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "UHCIPEIM: Ctrler halted\n") );
+ return EFI_DEVICE_ERROR;
+ }
+
+ ClearStatusReg( UhcDev, StatusReg );
+
+ //
+ // Setup Stage of Control Transfer
+ //
+
+ //
+ // create QH structure and init
+ //
+ Status = CreateQH( UhcDev, &ptrQH );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //
+ // generate Setup Stage TD
+ //
+
+ GenSetupStageTD( UhcDev, DeviceAddress, 0,
+ DeviceSpeed, (UINT8 *) Request,
+ sizeof(EFI_USB_DEVICE_REQUEST), &ptrSetupTD );
+
+ //
+ // link setup TD structures to QH structure
+ //
+ LinkTDToQH( ptrQH, ptrSetupTD );
+
+ ptrPreTD = ptrSetupTD;
+
+ //
+ // Data Stage of Control Transfer
+ //
+ switch (TransferDirection)
+ {
+
+ case EfiUsbDataIn:
+ PktID = INPUT_PACKET_ID;
+ ptrDataSource = Data;
+ DataLen = (UINT32) *DataLength;
+ ptr = ptrDataSource;
+ break;
+
+ case EfiUsbDataOut:
+ PktID = OUTPUT_PACKET_ID;
+ ptrDataSource = Data;
+ DataLen = (UINT32) *DataLength;
+ ptr = ptrDataSource;
+ break;
+
+ //
+ // no data stage
+ //
+ case EfiUsbNoData:
+ if (*DataLength != 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+ PktID = OUTPUT_PACKET_ID;
+ ptrDataSource = NULL;
+ DataLen = 0;
+ ptr = NULL;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DataToggle = 1;
+
+ ptrTD = ptrSetupTD;
+ while (DataLen > 0) {
+
+ //
+ // create TD structures and link together
+ //
+
+ UINT8 pktsize;
+
+ //
+ // pktsize is the data load size of each TD carries.
+ //
+ pktsize = (UINT8) DataLen;
+ if (DataLen > MaximumPacketLength) {
+ pktsize = MaximumPacketLength;
+ }
+ GenDataTD( UhcDev, DeviceAddress, 0, ptr, pktsize, PktID, DataToggle,
+ DeviceSpeed, &ptrTD );
+
+ //
+ // Link two TDs in vertical depth
+ //
+ LinkTDToTD( ptrPreTD, ptrTD );
+ ptrPreTD = ptrTD;
+
+ DataToggle ^= 1;
+ ptr += pktsize;
+ DataLen -= pktsize;
+ }
+
+ //
+ // ptrPreTD points to the last TD before the Setup-Stage TD.
+ //
+ ptrPreTD = ptrTD;
+
+ //
+ // Status Stage of Control Transfer
+ //
+ if (PktID == OUTPUT_PACKET_ID) {
+ PktID = INPUT_PACKET_ID;
+ }
+ else {
+ PktID = OUTPUT_PACKET_ID;
+ }
+ //
+ // create Status Stage TD structure
+ //
+ CreateStatusTD( UhcDev,
+ DeviceAddress,
+ 0,
+ PktID,
+ DeviceSpeed,
+ &ptrStatusTD );
+
+ LinkTDToTD( ptrPreTD, ptrStatusTD );
+
+ //
+ // get the frame list index that the QH-TDs will be linked to.
+ //
+ LoadFrameListIndex = (UINT16) ( ( GetCurrentFrameNumber
+ ( UhcDev, FrameNumReg ) ) % 1024 );
+
+ //
+ // link QH-TDs to total 500 frame list entry to speed up the execution.
+ //
+ for (i = 0; i < 500; i++) {
+
+ //
+ // put the QH-TDs directly or indirectly into the proper place in
+ // the Frame List
+ //
+ LinkQHToFrameList( UhcDev->FrameListEntry,
+ (UINT16) ( (LoadFrameListIndex + i) % 1024 ), ptrQH );
+ }
+
+ //
+ // Poll QH-TDs execution and get result.
+ // detail status is returned
+ //
+ //TimeOut = 1000; //bala
+
+ Status = ExecuteControlTransfer( UhcDev, ptrSetupTD,
+ LoadFrameListIndex, DataLength,
+ TimeOut, TransferResult );
+ //
+ // TRUE means must search other framelistindex
+ //
+ DeleteSingleQH( UhcDev, ptrQH, LoadFrameListIndex, TRUE );
+ DeleteQueuedTDs( UhcDev, ptrSetupTD );
+
+ //
+ // if has errors that cause host controller halt, then return
+ // EFI_DEVICE_ERROR directly.
+ //
+ if ( IsHCHalted( UhcDev, StatusReg ) ||
+ IsHCProcessErr( UhcDev, StatusReg ) ||
+ IsHostSysErr( UhcDev, StatusReg ) ) {
+
+ ClearStatusReg( UhcDev, StatusReg );
+ *TransferResult |= EFI_USB_ERR_SYSTEM;
+ PEI_TRACE( (EFI_D_ERROR, PeiServices,
+ "UHCIPEIM: Ctrl transfer failed\n") );
+ return EFI_DEVICE_ERROR;
+ }
+
+ ClearStatusReg( UhcDev, StatusReg );
+
+ // PEI_TRACE ((EFI_D_ERROR, PeiServices, "Exit UhcControlTransfer\n"));
+ return Status;
+}
+
+
+void PrintTD (
+ TD_STRUCT *ptrTD,
+ USB_UHC_DEV *UhcDev )
+{
+ EFI_PEI_SERVICES **PeiServices;
+ UINT8 i;
+ UINT32 *Tmp;
+
+ PeiServices = UhcDev->PeiServices;
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "UHCPIM: TD ... \n") );
+
+ Tmp = (UINT32 *) ptrTD;
+ for (i = 0; i < 4; i++)
+ {
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, " %x", Tmp[i]) );
+
+ }
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "\n") );
+
+}
+
+
+void PrintQH (
+ QH_STRUCT *ptrQH,
+ USB_UHC_DEV *UhcDev )
+{
+ EFI_PEI_SERVICES **PeiServices;
+ UINT8 i;
+ UINT32 *Tmp;
+
+ PeiServices = UhcDev->PeiServices;
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "UHCPIM: QH ... \n") );
+
+ Tmp = (UINT32 *) ptrQH;
+ for (i = 0; i < 2; i++)
+ {
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, " %x", Tmp[i]) );
+
+ }
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "\n") );
+
+}
+
+
+EFI_STATUS UhcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ USB_UHC_DEV *UhcDev;
+ UINT32 StatusReg;
+ UINT32 FrameNumReg;
+
+ UINT32 DataLen;
+
+ QH_STRUCT *ptrQH;
+ TD_STRUCT *ptrFirstTD;
+ TD_STRUCT *ptrTD;
+ TD_STRUCT *ptrPreTD;
+
+ UINT16 LoadFrameListIndex;
+ UINT16 SavedFrameListIndex;
+
+ UINT8 PktID;
+ UINT8 *ptrDataSource;
+ UINT8 *ptr;
+
+ BOOLEAN IsFirstTD;
+
+ EFI_STATUS Status;
+ UINT32 i;
+
+ EFI_USB_DATA_DIRECTION TransferDirection;
+ //
+ // Used to calculate how many entries are linked to the specified bulk
+ // transfer QH-TDs
+ //
+ UINT32 LinkTimes;
+
+ BOOLEAN ShortPacketEnable;
+
+ UINT16 CommandContent;
+
+ UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( This );
+
+ //
+ // Enable the maximum packet size (64bytes)
+ // that can be used for full speed bandwidth reclamation
+ // at the end of a frame.
+ //
+ CommandContent = USBReadPortW( UhcDev,
+ UhcDev->UsbHostControllerBaseAddress + USBCMD );
+
+ if ( (CommandContent & USBCMD_MAXP) != USBCMD_MAXP ) {
+ CommandContent |= USBCMD_MAXP;
+ USBWritePortW( UhcDev, UhcDev->UsbHostControllerBaseAddress + USBCMD,
+ CommandContent );
+
+ }
+
+ StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS;
+ FrameNumReg = UhcDev->UsbHostControllerBaseAddress + USBFRNUM;
+
+ //
+ // these code lines are added here per complier's strict demand
+ //
+ PktID = INPUT_PACKET_ID;
+ ptrTD = NULL;
+ ptrFirstTD = NULL;
+ ptrPreTD = NULL;
+ LinkTimes = 1;
+ DataLen = 0;
+ ptr = NULL;
+
+ ShortPacketEnable = FALSE;
+
+ if ( (DataLength == 0) || (Data == NULL)
+ || (TransferResult == NULL) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( (*DataToggle != 1) && (*DataToggle != 0) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (MaximumPacketLength != 8 && MaximumPacketLength != 16
+ && MaximumPacketLength != 32 && MaximumPacketLength != 64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // if has errors that cause host controller halt, then return
+ // EFI_DEVICE_ERROR directly.
+ //
+ if ( IsHCHalted( UhcDev, StatusReg ) ||
+ IsHCProcessErr( UhcDev, StatusReg ) ||
+ IsHostSysErr( UhcDev, StatusReg ) ) {
+
+ ClearStatusReg( UhcDev, StatusReg );
+ *TransferResult = EFI_USB_ERR_SYSTEM;
+ return EFI_DEVICE_ERROR;
+ }
+
+ ClearStatusReg( UhcDev, StatusReg );
+
+ //
+ // construct QH and TD data structures,
+ // and link them together
+ //
+ if (EndPointAddress & 0x80) {
+ TransferDirection = EfiUsbDataIn;
+ }
+ else {
+ TransferDirection = EfiUsbDataOut;
+ }
+
+ switch (TransferDirection)
+ {
+
+ case EfiUsbDataIn:
+ ShortPacketEnable = TRUE;
+ PktID = INPUT_PACKET_ID;
+ ptrDataSource = Data;
+ DataLen = (UINT32) *DataLength;
+ ptr = ptrDataSource;
+ break;
+
+ case EfiUsbDataOut:
+ PktID = OUTPUT_PACKET_ID;
+ ptrDataSource = Data;
+ DataLen = (UINT32) *DataLength;
+ ptr = ptrDataSource;
+ break;
+ }
+
+ //
+ // create QH structure and init
+ //
+ Status = CreateQH( UhcDev, &ptrQH );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //
+ // Self link the QH, to make NAK TD retried in one frame.
+ //
+ //SelfLinkBulkTransferQH (ptrQH);
+
+ //
+ // i is used to calculate the total number of TDs.
+ //
+ i = 0;
+
+ IsFirstTD = TRUE;
+ while (DataLen > 0) {
+
+ //
+ // create TD structures and link together
+ //
+ UINT16 pktsize;
+
+ pktsize = (UINT16) DataLen;
+ if (DataLen > MaximumPacketLength) {
+ pktsize = MaximumPacketLength;
+ }
+ GenDataTD( UhcDev, DeviceAddress, EndPointAddress, ptr,
+ pktsize, PktID, *DataToggle, USB_FULL_SPEED_DEVICE, &ptrTD );
+
+ //
+ // Enable short packet detection.
+ // (default action is disabling short packet detection)
+ //
+ if (ShortPacketEnable) {
+ EnableorDisableTDShortPacket( ptrTD, TRUE );
+ }
+
+ if (IsFirstTD) {
+ ptrFirstTD = ptrTD;
+ ptrFirstTD->ptrNextTD = NULL;
+ IsFirstTD = FALSE;
+ }
+ else {
+ //
+ // Link two TDs in vertical depth
+ //
+ LinkTDToTD( ptrPreTD, ptrTD );
+ }
+
+ i++;
+
+ ptrPreTD = ptrTD;
+
+ *DataToggle ^= 1;
+ ptr += pktsize;
+ DataLen -= pktsize;
+ }
+
+ //
+ // link TD structures to QH structure
+ //
+ LinkTDToQH( ptrQH, ptrFirstTD );
+
+ //
+ // calculate how many entries are linked to the specified bulk
+ // transfer QH-TDs the below values are referred to the USB spec
+ // revision1.1.
+ //
+ switch (MaximumPacketLength)
+ {
+ case 8:
+ LinkTimes = i / 71 + 1;
+ break;
+
+ case 16:
+ LinkTimes = i / 51 + 1;
+ break;
+
+ case 32:
+ LinkTimes = i / 33 + 1;
+ break;
+
+ case 64:
+ LinkTimes = i / 19 + 1;
+ break;
+ }
+ LinkTimes += 200; // redundant
+
+ //
+ // put QH-TDs into Frame list
+ //
+
+ LoadFrameListIndex = (UINT16)
+ ( ( GetCurrentFrameNumber( UhcDev,
+ FrameNumReg ) ) % 1024 );
+ SavedFrameListIndex = LoadFrameListIndex;
+
+ for (i = 0; i <= LinkTimes; i++) {
+
+ //
+ // put the QH-TD directly or indirectly into the proper
+ // place in the Frame List
+ //
+ LinkQHToFrameList( UhcDev->FrameListEntry, LoadFrameListIndex, ptrQH );
+
+ LoadFrameListIndex += 1;
+ LoadFrameListIndex %= 1024;
+ }
+
+ LoadFrameListIndex = SavedFrameListIndex;
+
+ //
+ // Execute QH-TD and get result
+ //
+ //
+ // detail status is put into the Result field in the pIRP
+ // the Data Toggle value is also re-updated to the value
+ // of the last successful TD
+ //
+ Status = ExecBulkTransfer( UhcDev, ptrFirstTD,
+ LoadFrameListIndex, DataLength,
+ DataToggle, TimeOut, TransferResult );
+
+ //
+ // Delete Bulk transfer QH-TD structure
+ // and maitain the pointers in the Frame List
+ // and other pointers in related QH structure
+ //
+
+
+ // TRUE means must search other framelistindex
+ DeleteSingleQH( UhcDev, ptrQH, LoadFrameListIndex, TRUE );
+ DeleteQueuedTDs( UhcDev, ptrFirstTD );
+
+ //
+ // if has errors that cause host controller halt, then
+ // return EFI_DEVICE_ERROR directly.
+ //
+ if ( IsHCHalted( UhcDev, StatusReg ) ||
+ IsHCProcessErr( UhcDev, StatusReg ) ||
+ IsHostSysErr( UhcDev, StatusReg ) ) {
+
+ ClearStatusReg( UhcDev, StatusReg );
+ *TransferResult |= EFI_USB_ERR_SYSTEM;
+ return EFI_DEVICE_ERROR;
+ }
+
+ ClearStatusReg( UhcDev, StatusReg );
+
+ return Status;
+}
+
+
+EFI_STATUS UhcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber )
+{
+ USB_UHC_DEV *UhcDev;
+ UINT32 PSAddr;
+ UINT16 RHPortControl;
+ UINT32 i;
+
+ UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( This );
+
+ if (PortNumber == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *PortNumber = 0;
+
+ for (i = 0; i < 2; i++) {
+ PSAddr = UhcDev->UsbHostControllerBaseAddress + USBPORTSC1 + i * 2;
+ //RHPortControl = ReadRootPortReg(UhcDev->CpuIoPpi,PSAddr);
+ RHPortControl = USBReadPortW( UhcDev, PSAddr );
+ //
+ // Port Register content is valid
+ //
+ if (RHPortControl != 0xff) {
+ (*PortNumber)++;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS UhcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus )
+{
+ USB_UHC_DEV *UhcDev;
+ UINT32 PSAddr;
+ UINT16 RHPortStatus; // root hub port status
+ UINT8 TotalPortNumber;
+
+ if (PortStatus == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UhcGetRootHubPortNumber( PeiServices, This, &TotalPortNumber );
+ if (PortNumber > TotalPortNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( This );
+ PSAddr = UhcDev->UsbHostControllerBaseAddress +
+ USBPORTSC1 + (PortNumber - 1) * 2;
+
+ PortStatus->PortStatus = 0;
+ PortStatus->PortChangeStatus = 0;
+
+ //RHPortStatus = ReadRootPortReg (UhcDev->CpuIoPpi,PSAddr) ;
+ RHPortStatus = USBReadPortW( UhcDev, PSAddr );
+
+ //
+ // Fill Port Status bits
+ //
+
+ //
+ // Current Connect Status
+ //
+ if (RHPortStatus & USBPORTSC_CCS) {
+ PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+ }
+
+ //
+ // Port Enabled/Disabled
+ //
+ if (RHPortStatus & USBPORTSC_PED) {
+ PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+ }
+
+ //
+ // Port Suspend
+ //
+ if (RHPortStatus & USBPORTSC_SUSP) {
+ PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;
+ }
+
+ //
+ // Port Reset
+ //
+ if (RHPortStatus & USBPORTSC_PR) {
+ PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+ }
+
+ //
+ // Low Speed Device Attached
+ //
+ if (RHPortStatus & USBPORTSC_LSDA) {
+ PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;
+ }
+
+ //
+ // Fill Port Status Change bits
+ //
+
+ //
+ // Connect Status Change
+ //
+ if (RHPortStatus & USBPORTSC_CSC) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+ }
+
+ //
+ // Port Enabled/Disabled Change
+ //
+ if (RHPortStatus & USBPORTSC_PEDC) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+ }
+ if (UhcDev->PortResetStatusChangeMap & (1 << (PortNumber - 1))) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_RESET;
+ }
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS UhcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ USB_UHC_DEV *UhcDev;
+ UINT32 PSAddr;
+ UINT32 CommandRegAddr;
+ UINT16 RHPortControl; // root hub port status
+ UINT8 TotalPortNumber;
+
+ UhcGetRootHubPortNumber( PeiServices, This, &TotalPortNumber );
+ if (PortNumber > TotalPortNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( This );
+ PSAddr = UhcDev->UsbHostControllerBaseAddress +
+ USBPORTSC1 + (PortNumber - 1) * 2;
+ CommandRegAddr = UhcDev->UsbHostControllerBaseAddress + USBCMD;
+
+ RHPortControl = USBReadPortW( UhcDev, PSAddr );
+
+ switch (PortFeature)
+ {
+
+ case EfiUsbPortSuspend:
+ if ( !(USBReadPortW( UhcDev, CommandRegAddr ) & USBCMD_EGSM) ) {
+ //
+ // if global suspend is not active, can set port suspend
+ //
+ RHPortControl &= 0xfff5;
+ RHPortControl |= USBPORTSC_SUSP;
+ }
+ break;
+
+ case EfiUsbPortReset:
+ RHPortControl &= 0xfff5;
+ RHPortControl |= USBPORTSC_PR; // Set the reset bit
+ USBWritePortW( UhcDev, PSAddr, RHPortControl );
+ UhcDev->StallPpi->Stall (UhcDev->PeiServices,UhcDev->StallPpi,10 * 1000);
+ RHPortControl = USBReadPortW( UhcDev, PSAddr );
+ RHPortControl &= 0xfff5;
+ RHPortControl &= ~USBPORTSC_PR;
+ USBWritePortW( UhcDev, PSAddr, RHPortControl );
+ UhcDev->PortResetStatusChangeMap |= (1 << (PortNumber - 1));
+ return EFI_SUCCESS;
+
+ case EfiUsbPortPower:
+ break;
+
+ case EfiUsbPortEnable:
+ RHPortControl &= 0xfff5;
+ RHPortControl |= USBPORTSC_PED;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //WriteRootPortReg(UhcDev->CpuIoPpi,PSAddr,RHPortControl) ;
+ USBWritePortW( UhcDev, PSAddr, RHPortControl );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS UhcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ USB_UHC_DEV *UhcDev;
+ UINT32 PSAddr;
+ UINT16 RHPortControl;
+ UINT8 TotalPortNumber;
+
+ UhcGetRootHubPortNumber( PeiServices, This, &TotalPortNumber );
+
+ if (PortNumber > TotalPortNumber) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UhcDev = PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( This );
+ PSAddr = UhcDev->UsbHostControllerBaseAddress +
+ USBPORTSC1 + (PortNumber - 1) * 2;
+
+ //RHPortControl = ReadRootPortReg (UhcDev->CpuIoPpi,PSAddr) ;
+ RHPortControl = USBReadPortW( UhcDev, PSAddr );
+
+ switch (PortFeature)
+ {
+
+ //
+ // clear PORT_ENABLE feature means disable port.
+ //
+ case EfiUsbPortEnable:
+ RHPortControl &= 0xfff5;
+ RHPortControl &= ~USBPORTSC_PED;
+ break;
+
+ //
+ // clear PORT_SUSPEND feature means resume the port.
+ // (cause a resume on the specified port if in suspend mode)
+ //
+ case EfiUsbPortSuspend:
+ RHPortControl &= 0xfff5;
+ RHPortControl &= ~USBPORTSC_SUSP;
+ break;
+
+ //
+ // no operation
+ //
+ case EfiUsbPortPower:
+ break;
+
+ //
+ // clear PORT_RESET means clear the reset signal.
+ //
+ case EfiUsbPortReset:
+ RHPortControl &= 0xfff5;
+ RHPortControl &= ~USBPORTSC_PR;
+ break;
+
+ //
+ // clear connect status change
+ //
+ case EfiUsbPortConnectChange:
+ RHPortControl &= 0xfff5;
+ RHPortControl |= USBPORTSC_CSC;
+ break;
+
+ //
+ // clear enable/disable status change
+ //
+ case EfiUsbPortEnableChange:
+ RHPortControl &= 0xfff5;
+ RHPortControl |= USBPORTSC_PEDC;
+ break;
+
+ //
+ // root hub does not support this request
+ //
+ case EfiUsbPortSuspendChange:
+ break;
+
+ //
+ // root hub does not support this request
+ //
+ case EfiUsbPortOverCurrentChange:
+ break;
+
+ //
+ // root hub does not support this request
+ //
+ case EfiUsbPortResetChange:
+ UhcDev->PortResetStatusChangeMap &= ~(1 << (PortNumber - 1));
+ return EFI_SUCCESS;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //WriteRootPortReg(UhcDev->CpuIoPpi,PSAddr,RHPortControl) ;
+ USBWritePortW( UhcDev, PSAddr, RHPortControl );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS InitializeUsbHC (
+ USB_UHC_DEV *UhcDev )
+{
+ EFI_STATUS Status;
+ UINT32 FrameListBaseAddrReg;
+ UINT32 StatusReg;
+ UINT32 CommandReg;
+ UINT16 Command;
+ UINTN Delay;
+
+ // Create and Initialize Frame List For the Host Controller.
+ Status = CreateFrameList( UhcDev );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ FrameListBaseAddrReg = UhcDev->UsbHostControllerBaseAddress +
+ USBFLBASEADD;
+ StatusReg = UhcDev->UsbHostControllerBaseAddress + USBSTS;
+ CommandReg = UhcDev->UsbHostControllerBaseAddress + USBCMD;
+
+ //Issue a Global reset
+ Command = USBReadPortW (UhcDev,CommandReg);
+ Command |= USBCMD_GRESET ;
+ USBWritePortW (UhcDev,CommandReg,Command);
+
+ Delay = (100 * STALL_1_MILLI_SECOND / 50) + 1;
+
+ do {
+ UhcDev->StallPpi->Stall (UhcDev->PeiServices,UhcDev->StallPpi,50);
+ } while(Delay--);
+
+ Command = USBReadPortW (UhcDev,CommandReg);
+ Command &= !USBCMD_GRESET ;
+ USBWritePortW (UhcDev,CommandReg,Command);
+
+ Delay = (100 * STALL_1_MILLI_SECOND / 50) + 1;
+
+ do {
+ UhcDev->StallPpi->Stall (UhcDev->PeiServices,UhcDev->StallPpi,50);
+ } while(Delay--);
+
+ // Set Frame List Base Address to the specific register to
+ // inform the hardware.
+ SetFrameListBaseAddress( UhcDev, FrameListBaseAddrReg,
+ (UINT32) (UINTN) (UhcDev->FrameListEntry) );
+
+ // Make the Host Controller in Run state.
+ if ( IsHostSysErr( UhcDev, StatusReg )
+ || IsHCProcessErr( UhcDev, StatusReg ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Command = USBReadPortW( UhcDev, CommandReg );
+ Command |= USBCMD_RS;
+
+ USBWritePortW( UhcDev, CommandReg, Command );
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS CreateFrameList (
+ USB_UHC_DEV *UhcDev )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS FrameListBaseAddr;
+
+ //
+ // The Frame List ocupies 4K bytes,
+ // and must be aligned on 4-Kbyte boundaries.
+ //
+ Status = ( **(UhcDev->PeiServices) ).AllocatePages(
+ UhcDev->PeiServices,
+ EfiConventionalMemory,
+ 1,
+ &FrameListBaseAddr );
+
+ if (Status != EFI_SUCCESS) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ UhcDev->FrameListEntry = (FRAMELIST_ENTRY *) ( (UINTN) FrameListBaseAddr );
+
+ InitFrameList( UhcDev );
+
+ return EFI_SUCCESS;
+}
+
+
+VOID InitFrameList (
+ USB_UHC_DEV *UhcDev )
+{
+ FRAMELIST_ENTRY *FrameListPtr;
+ UINTN i;
+
+ //
+ // Validate each Frame List Entry
+ //
+ FrameListPtr = UhcDev->FrameListEntry;
+ for (i = 0; i < 1024; i++) {
+ FrameListPtr->FrameListPtrTerminate = 1;
+ FrameListPtr->FrameListPtr = 0;
+ FrameListPtr->FrameListPtrQSelect = 0;
+ FrameListPtr->FrameListRsvd = 0;
+ FrameListPtr++;
+ }
+}
+
+
+UINT16 USBReadPortW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port )
+{
+ UINT16 Data;
+
+ //
+ // Perform 16bit Read
+ //
+ UhcDev->CpuIoPpi->Io.Read(
+ UhcDev->PeiServices,
+ UhcDev->CpuIoPpi,
+ EfiPeiCpuIoWidthUint16,
+ (UINT64) Port,
+ 1,
+ &Data
+ );
+
+ return Data;
+}
+
+
+VOID USBWritePortW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port,
+ IN UINT16 Data )
+{
+ //
+ // Perform 16bit Write
+ //
+ UhcDev->CpuIoPpi->Io.Write(
+ UhcDev->PeiServices,
+ UhcDev->CpuIoPpi,
+ EfiPeiCpuIoWidthUint16,
+ (UINT64) Port,
+ 1,
+ &Data
+ );
+}
+
+
+VOID USBWritePortDW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port,
+ IN UINT32 Data )
+{
+ //
+ // Perform 32bit Write
+ //
+
+ UhcDev->CpuIoPpi->Io.Write(
+ UhcDev->PeiServices,
+ UhcDev->CpuIoPpi,
+ EfiPeiCpuIoWidthUint32,
+ (UINT64) Port,
+ 1,
+ &Data
+ );
+}
+
+
+UINT32 USBReadPortDW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port )
+{
+ UINT32 Data;
+
+ //
+ // Perform 16bit Read
+ //
+ UhcDev->CpuIoPpi->Io.Read(
+ UhcDev->PeiServices,
+ UhcDev->CpuIoPpi,
+ EfiPeiCpuIoWidthUint32,
+ (UINT64) Port,
+ 1,
+ &Data
+ );
+ return Data;
+}
+
+
+//
+// USB register-base helper functions
+//
+
+VOID ClearStatusReg (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 STSAddr )
+{
+ UINT16 UsbSts;
+
+ //
+ // Clear the content of UHC's Status Register
+ //
+ UsbSts = 0x003f;
+ USBWritePortW( UhcDev, STSAddr, UsbSts );
+ //WriteUHCStatusReg (PciIo,STSAddr,UsbSts);
+}
+
+
+BOOLEAN IsHostSysErr (
+ USB_UHC_DEV *UhcDev,
+ UINT32 StatusRegAddr )
+{
+ UINT16 StatusValue;
+
+ //
+ // Detect whether the interrupt is caused by serious error.
+ // see "UHCI Design Guid".
+ //
+ StatusValue = USBReadPortW( UhcDev, StatusRegAddr );
+
+ if (StatusValue & USBSTS_HSE) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+BOOLEAN IsHCProcessErr (
+ USB_UHC_DEV *UhcDev,
+ UINT32 StatusRegAddr )
+{
+ UINT16 StatusValue;
+
+ //
+ // Detect whether the interrupt is caused by fatal error.
+ // see "UHCI Design Guid".
+ //
+ StatusValue = USBReadPortW( UhcDev, StatusRegAddr );
+
+ if (StatusValue & USBSTS_HCPE) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+BOOLEAN IsHCHalted (
+ USB_UHC_DEV *UhcDev,
+ UINT32 StatusRegAddr )
+{
+ UINT16 StatusValue;
+
+ //
+ // Detect whether the the Host Controller is halted.
+ //
+ StatusValue = USBReadPortW( UhcDev, StatusRegAddr );
+
+ if (StatusValue & USBSTS_HCH) {
+ return TRUE;
+ }
+ else {
+ return FALSE;
+ }
+}
+
+
+UINT16 GetCurrentFrameNumber (
+ USB_UHC_DEV *UhcDev,
+ UINT32 FRNUMAddr )
+{
+ //
+ // Gets value in the USB frame number register.
+ //
+
+ return (UINT16) (USBReadPortW( UhcDev, FRNUMAddr ) & 0x03ff);
+}
+
+
+VOID SetFrameListBaseAddress (
+ USB_UHC_DEV *UhcDev,
+ UINT32 FLBASEADDRReg,
+ UINT32 Addr )
+{
+ //
+ // Sets value in the USB Frame List Base Address register.
+ //
+ USBWritePortDW( UhcDev, FLBASEADDRReg, (UINT32) (Addr & 0xfffff000) );
+}
+
+
+////////////////////////////////////////////////////////////////
+//
+// QH TD related Helper Functions
+//
+////////////////////////////////////////////////////////////////
+
+//
+// functions for QH
+//
+EFI_STATUS AllocateQHStruct (
+ USB_UHC_DEV *UhcDev,
+ QH_STRUCT **ppQHStruct )
+{
+ EFI_STATUS Status;
+
+ *ppQHStruct = NULL;
+
+ Status = UhcAllocatePool( UhcDev, MEM_QH_TD_TYPE,
+ (UINT8 **) ppQHStruct, sizeof(QH_STRUCT) );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ ZeroMem( *ppQHStruct, sizeof(QH_STRUCT) );
+
+ return EFI_SUCCESS;
+}
+
+
+VOID InitQH (
+ IN QH_STRUCT *ptrQH )
+{
+ //
+ // Make QH ready
+ //
+ SetQHHorizontalValidorInvalid( ptrQH, FALSE );
+ SetQHVerticalValidorInvalid( ptrQH, FALSE );
+}
+
+
+EFI_STATUS CreateQH (
+ USB_UHC_DEV *UhcDev,
+ QH_STRUCT **pptrQH )
+{
+ EFI_STATUS Status;
+
+ //
+ // allocate align memory for QH_STRUCT
+ //
+ Status = AllocateQHStruct( UhcDev, pptrQH );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // init each field of the QH_STRUCT
+ //
+ InitQH( *pptrQH );
+
+ return EFI_SUCCESS;
+}
+
+
+VOID SetQHHorizontalLinkPtr (
+ IN QH_STRUCT *ptrQH,
+ IN VOID *ptrNext )
+{
+ //
+ // Since the QH_STRUCT is aligned on 16-byte boundaries,
+ // Only the highest 28bit of the address is valid
+ // (take 32bit address as an example).
+ //
+ ptrQH->QH.QHHorizontalPtr = (UINT32) (UINTN) ptrNext >> 4;
+}
+
+
+VOID *GetQHHorizontalLinkPtr (
+ IN QH_STRUCT *ptrQH )
+{
+ //
+ // Restore the 28bit address to 32bit address
+ //(take 32bit address as an example)
+ //
+ return ( (VOID *) (UINTN) ( (ptrQH->QH.QHHorizontalPtr) << 4 ) );
+}
+
+
+VOID SetQHHorizontalQHorTDSelect (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bQH )
+{
+ //
+ // if QH is connected, the specified bit is set,
+ // if TD is connected, the specified bit is cleared.
+ //
+ ptrQH->QH.QHHorizontalQSelect = bQH ? 1 : 0;
+}
+
+
+VOID SetQHHorizontalValidorInvalid (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bValid )
+{
+ //
+ // Valid means the horizontal link pointer is valid,
+ // else, it's invalid.
+ //
+ ptrQH->QH.QHHorizontalTerminate = bValid ? 0 : 1;
+}
+
+
+VOID SetQHVerticalLinkPtr (
+ IN QH_STRUCT *ptrQH,
+ IN VOID *ptrNext )
+{
+ //
+ // Since the QH_STRUCT is aligned on 16-byte boundaries,
+ // Only the highest 28bit of the address is valid
+ // (take 32bit address as an example).
+ //
+ ptrQH->QH.QHVerticalPtr = (UINT32) (UINTN) ptrNext >> 4;
+}
+
+
+VOID SetQHVerticalQHorTDSelect (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bQH )
+{
+ //
+ // Set the specified bit if the Vertical Link Pointer pointing to a QH,
+ // Clear the specified bit if the Vertical Link Pointer pointing to a TD.
+ //
+ ptrQH->QH.QHVerticalQSelect = bQH ? 1 : 0;
+}
+
+
+VOID SetQHVerticalValidorInvalid (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bValid )
+{
+ //
+ // If TRUE, meaning the Vertical Link Pointer field is valid,
+ // else, the field is invalid.
+ //
+ ptrQH->QH.QHVerticalTerminate = bValid ? 0 : 1;
+}
+
+
+BOOLEAN GetQHHorizontalValidorInvalid (
+ IN QH_STRUCT *ptrQH )
+{
+ //
+ // If TRUE, meaning the Horizontal Link Pointer field is valid,
+ // else, the field is invalid.
+ //
+ return (BOOLEAN) ( !(ptrQH->QH.QHHorizontalTerminate) );
+}
+
+
+//
+// functions for TD
+//
+
+EFI_STATUS AllocateTDStruct (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT **ppTDStruct )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ *ppTDStruct = NULL;
+
+ Status = UhcAllocatePool( UhcDev, MEM_QH_TD_TYPE,
+ (UINT8 **) ppTDStruct, sizeof(TD_STRUCT) );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ ZeroMem( *ppTDStruct, sizeof (TD_STRUCT) );
+
+ return Status;
+}
+
+
+VOID InitTD (
+ IN TD_STRUCT *ptrTD )
+{
+ //
+ // Make TD ready.
+ //
+ SetTDLinkPtrValidorInvalid( ptrTD, FALSE );
+}
+
+
+EFI_STATUS CreateTD (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT **pptrTD )
+{
+ EFI_STATUS Status;
+
+ //
+ // create memory for TD_STRUCT, and align the memory.
+ //
+ Status = AllocateTDStruct( UhcDev, pptrTD );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ InitTD( *pptrTD );
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS GenSetupStageTD (
+ USB_UHC_DEV *UhcDev,
+ UINT8 DevAddr,
+ UINT8 Endpoint,
+ UINT8 DeviceSpeed,
+ UINT8 *pDevReq,
+ UINT8 RequestLen,
+ TD_STRUCT **ppTD )
+{
+ TD_STRUCT *pTDStruct;
+ EFI_STATUS Status;
+
+ Status = CreateTD( UhcDev, &pTDStruct );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ SetTDLinkPtr( pTDStruct, NULL );
+
+ //
+ // Depth first fashion
+ //
+ SetTDLinkPtrDepthorBreadth( pTDStruct, TRUE );
+
+ //SetTDLinkPtrQHorTDSelect(pTDStruct,FALSE) ;
+
+ //
+ // initialize as the last TD in the QH context,
+ // this field will be updated in the TD linkage process.
+ //
+ SetTDLinkPtrValidorInvalid( pTDStruct, FALSE );
+
+ //
+ // Disable Short Packet Detection by default
+ //
+ EnableorDisableTDShortPacket( pTDStruct, FALSE );
+
+ //
+ // Max error counter is 3, retry 3 times when error encountered.
+ //
+ SetTDControlErrorCounter( pTDStruct, 3 );
+
+ //
+ // set device speed attribute
+ // (TRUE - Slow Device; FALSE - Full Speed Device)
+ //
+ switch (DeviceSpeed)
+ {
+ case USB_SLOW_SPEED_DEVICE:
+ SetTDLoworFullSpeedDevice( pTDStruct, TRUE );
+ break;
+
+ case USB_FULL_SPEED_DEVICE:
+ SetTDLoworFullSpeedDevice( pTDStruct, FALSE );
+ break;
+ }
+
+ //
+ // Non isochronous transfer TD
+ //
+ SetTDControlIsochronousorNot( pTDStruct, FALSE );
+
+ //
+ // Interrupt On Complete bit be set to zero,
+ // Disable IOC interrupt.
+ //
+ SetorClearTDControlIOC( pTDStruct, FALSE );
+
+ //
+ // Set TD Active bit
+ //
+ SetTDStatusActiveorInactive( pTDStruct, TRUE );
+
+ SetTDTokenMaxLength( pTDStruct, RequestLen );
+
+ SetTDTokenDataToggle0( pTDStruct );
+
+ SetTDTokenEndPoint( pTDStruct, Endpoint );
+
+ SetTDTokenDeviceAddress( pTDStruct, DevAddr );
+
+ SetTDTokenPacketID( pTDStruct, SETUP_PACKET_ID );
+
+ pTDStruct->pTDBuffer = (UINT8 *) pDevReq;
+ pTDStruct->TDBufferLength = RequestLen;
+ SetTDDataBuffer( pTDStruct );
+
+ *ppTD = pTDStruct;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS GenDataTD (
+ USB_UHC_DEV *UhcDev,
+ UINT8 DevAddr,
+ UINT8 Endpoint,
+ UINT8 *pData,
+ UINT16 Len,
+ UINT8 PktID,
+ UINT8 Toggle,
+ UINT8 DeviceSpeed,
+ TD_STRUCT **ppTD )
+{
+ TD_STRUCT *pTDStruct;
+ EFI_STATUS Status;
+
+ Status = CreateTD( UhcDev, &pTDStruct );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ SetTDLinkPtr( pTDStruct, NULL );
+
+ //
+ // Depth first fashion
+ //
+ SetTDLinkPtrDepthorBreadth( pTDStruct, TRUE );
+
+ //
+ // Link pointer pointing to TD struct
+ //
+ SetTDLinkPtrQHorTDSelect( pTDStruct, FALSE );
+
+ //
+ // initialize as the last TD in the QH context,
+ // this field will be updated in the TD linkage process.
+ //
+ SetTDLinkPtrValidorInvalid( pTDStruct, FALSE );
+
+ //
+ // Disable short packet detect
+ //
+ EnableorDisableTDShortPacket( pTDStruct, FALSE );
+ //
+ // Max error counter is 3
+ //
+ SetTDControlErrorCounter( pTDStruct, 3 );
+
+ //
+ // set device speed attribute
+ // (TRUE - Slow Device; FALSE - Full Speed Device)
+ //
+ switch (DeviceSpeed)
+ {
+ case USB_SLOW_SPEED_DEVICE:
+ SetTDLoworFullSpeedDevice( pTDStruct, TRUE );
+ break;
+
+ case USB_FULL_SPEED_DEVICE:
+ SetTDLoworFullSpeedDevice( pTDStruct, FALSE );
+ break;
+ }
+ //
+ // Non isochronous transfer TD
+ //
+ SetTDControlIsochronousorNot( pTDStruct, FALSE );
+
+ //
+ // Disable Interrupt On Complete
+ // Disable IOC interrupt.
+ //
+ SetorClearTDControlIOC( pTDStruct, FALSE );
+
+ //
+ // Set Active bit
+ //
+ SetTDStatusActiveorInactive( pTDStruct, TRUE );
+
+ SetTDTokenMaxLength( pTDStruct, Len );
+
+ if (Toggle) {
+ SetTDTokenDataToggle1( pTDStruct );
+ }
+ else {
+ SetTDTokenDataToggle0( pTDStruct );
+ }
+
+ SetTDTokenEndPoint( pTDStruct, Endpoint );
+
+ SetTDTokenDeviceAddress( pTDStruct, DevAddr );
+
+ SetTDTokenPacketID( pTDStruct, PktID );
+
+ pTDStruct->pTDBuffer = (UINT8 *) pData;
+ pTDStruct->TDBufferLength = Len;
+ SetTDDataBuffer( pTDStruct );
+
+ *ppTD = pTDStruct;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS CreateStatusTD (
+ USB_UHC_DEV *UhcDev,
+ UINT8 DevAddr,
+ UINT8 Endpoint,
+ UINT8 PktID,
+ UINT8 DeviceSpeed,
+ TD_STRUCT **ppTD )
+{
+ TD_STRUCT *ptrTDStruct;
+ EFI_STATUS Status;
+
+ Status = CreateTD( UhcDev, &ptrTDStruct );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ SetTDLinkPtr( ptrTDStruct, NULL );
+
+ // Depth first fashion
+ SetTDLinkPtrDepthorBreadth( ptrTDStruct, TRUE );
+
+ //SetTDLinkPtrQHorTDSelect(pTDStruct,FALSE) ;
+
+ //
+ // initialize as the last TD in the QH context,
+ // this field will be updated in the TD linkage process.
+ //
+ SetTDLinkPtrValidorInvalid( ptrTDStruct, FALSE );
+
+ //
+ // Disable short packet detect
+ //
+ EnableorDisableTDShortPacket( ptrTDStruct, FALSE );
+
+ //
+ // Max error counter is 3
+ //
+ SetTDControlErrorCounter( ptrTDStruct, 3 );
+
+ //
+ // set device speed attribute
+ // (TRUE - Slow Device; FALSE - Full Speed Device)
+ //
+ switch (DeviceSpeed)
+ {
+ case USB_SLOW_SPEED_DEVICE:
+ SetTDLoworFullSpeedDevice( ptrTDStruct, TRUE );
+ break;
+
+ case USB_FULL_SPEED_DEVICE:
+ SetTDLoworFullSpeedDevice( ptrTDStruct, FALSE );
+ break;
+ }
+
+ //
+ // Non isochronous transfer TD
+ //
+ SetTDControlIsochronousorNot( ptrTDStruct, FALSE );
+
+ //
+ // Disable Interrupt On Complete
+ // Disable IOC interrupt.
+ //
+ SetorClearTDControlIOC( ptrTDStruct, FALSE );
+
+ //
+ // Set TD Active bit
+ //
+ SetTDStatusActiveorInactive( ptrTDStruct, TRUE );
+
+ SetTDTokenMaxLength( ptrTDStruct, 0 );
+
+ SetTDTokenDataToggle1( ptrTDStruct );
+
+ SetTDTokenEndPoint( ptrTDStruct, Endpoint );
+
+ SetTDTokenDeviceAddress( ptrTDStruct, DevAddr );
+
+ SetTDTokenPacketID( ptrTDStruct, PktID );
+
+ ptrTDStruct->pTDBuffer = NULL;
+ ptrTDStruct->TDBufferLength = 0;
+ SetTDDataBuffer( ptrTDStruct );
+
+ *ppTD = ptrTDStruct;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID SetTDLinkPtrValidorInvalid (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bValid )
+{
+ //
+ // Valid means the link pointer is valid,
+ // else, it's invalid.
+ //
+ ptrTDStruct->TDData.TDLinkPtrTerminate = (bValid ? 0 : 1);
+}
+
+
+VOID SetTDLinkPtrQHorTDSelect (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bQH )
+{
+ //
+ // Indicate whether the Link Pointer pointing to a QH or TD
+ //
+ ptrTDStruct->TDData.TDLinkPtrQSelect = (bQH ? 1 : 0);
+}
+
+
+VOID SetTDLinkPtrDepthorBreadth (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bDepth )
+{
+ //
+ // If TRUE, indicating the host controller should process in
+ // depth first fashion, else, the host controller should process
+ // in breadth first fashion
+ //
+ ptrTDStruct->TDData.TDLinkPtrDepthSelect = (bDepth ? 1 : 0);
+}
+
+
+VOID SetTDLinkPtr (
+ IN TD_STRUCT *ptrTDStruct,
+ IN VOID *ptrNext )
+{
+ //
+ // Set TD Link Pointer. Since QH,TD align on 16-byte boundaries,
+ // only the highest 28 bits are valid. (if take 32bit address as an example)
+ //
+ ptrTDStruct->TDData.TDLinkPtr = (UINT32) (UINTN) ptrNext >> 4;
+}
+
+
+VOID *GetTDLinkPtr (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Get TD Link Pointer. Restore it back to 32bit
+ // (if take 32bit address as an example)
+ //
+ return ( (VOID *) (UINTN) ( (ptrTDStruct->TDData.TDLinkPtr) << 4 ) );
+}
+
+
+BOOLEAN IsTDLinkPtrQHOrTD (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Get the information about whether the Link Pointer field pointing to
+ // a QH or a TD.
+ //
+ return (BOOLEAN) (ptrTDStruct->TDData.TDLinkPtrQSelect);
+}
+
+
+VOID EnableorDisableTDShortPacket (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bEnable )
+{
+ //
+ // TRUE means enable short packet detection mechanism.
+ //
+ ptrTDStruct->TDData.TDStatusSPD = (bEnable ? 1 : 0);
+}
+
+
+VOID SetTDControlErrorCounter (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINT8 nMaxErrors )
+{
+ //
+ // valid value of nMaxErrors is 0,1,2,3
+ //
+ if (nMaxErrors > 3) {
+ nMaxErrors = 3;
+ }
+ ptrTDStruct->TDData.TDStatusErr = nMaxErrors;
+}
+
+
+VOID SetTDLoworFullSpeedDevice (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bLowSpeedDevice )
+{
+ //
+ // TRUE means the TD is targeting at a Low-speed device
+ //
+ ptrTDStruct->TDData.TDStatusLS = (bLowSpeedDevice ? 1 : 0);
+}
+
+
+VOID SetTDControlIsochronousorNot (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bIsochronous )
+{
+ //
+ // TRUE means the TD belongs to Isochronous transfer type.
+ //
+ ptrTDStruct->TDData.TDStatusIOS = (bIsochronous ? 1 : 0);
+}
+
+
+VOID SetorClearTDControlIOC (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bSet )
+{
+ //
+ // If this bit is set, it indicates that the host controller should issue
+ // an interrupt on completion of the frame in which this TD is executed.
+ //
+ ptrTDStruct->TDData.TDStatusIOC = bSet ? 1 : 0;
+}
+
+
+VOID SetTDStatusActiveorInactive (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bActive )
+{
+ //
+ // If this bit is set, it indicates that the TD is active and can be
+ // executed.
+ //
+ if (bActive) {
+ ptrTDStruct->TDData.TDStatus |= 0x80;
+ }
+ else {
+ ptrTDStruct->TDData.TDStatus &= 0x7f;
+ }
+}
+
+
+UINT16 SetTDTokenMaxLength (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINT16 nMaxLen )
+{
+ //
+ // Specifies the maximum number of data bytes allowed for the transfer.
+ // the legal value extent is 0 ~ 0x500.
+ //
+ if (nMaxLen > 0x500) {
+ nMaxLen = 0x500;
+ }
+ ptrTDStruct->TDData.TDTokenMaxLen = nMaxLen - 1;
+
+ return nMaxLen;
+}
+
+
+VOID SetTDTokenDataToggle1 (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Set the data toggle bit to DATA1
+ //
+ ptrTDStruct->TDData.TDTokenDataToggle = 1;
+}
+
+
+VOID SetTDTokenDataToggle0 (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Set the data toggle bit to DATA0
+ //
+ ptrTDStruct->TDData.TDTokenDataToggle = 0;
+}
+
+
+VOID SetTDTokenEndPoint (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINTN nEndPoint )
+{
+ //
+ // Set EndPoint Number the TD is targeting at.
+ //
+ ptrTDStruct->TDData.TDTokenEndPt = (UINT8) nEndPoint;
+}
+
+
+VOID SetTDTokenDeviceAddress (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINTN nDevAddr )
+{
+ //
+ // Set Device Address the TD is targeting at.
+ //
+ ptrTDStruct->TDData.TDTokenDevAddr = (UINT8) nDevAddr;
+}
+
+
+VOID SetTDTokenPacketID (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINT8 nPID )
+{
+ //
+ // Set the Packet Identification to be used for this transaction.
+ //
+ ptrTDStruct->TDData.TDTokenPID = nPID;
+}
+
+
+VOID SetTDDataBuffer (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Set the beginning address of the data buffer that will be used
+ // during the transaction.
+ //
+ ptrTDStruct->TDData.TDBufferPtr = (UINT32) (UINTN) (ptrTDStruct->
+ pTDBuffer);
+}
+
+
+BOOLEAN IsTDStatusActive (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether the TD is active.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x80);
+}
+
+
+BOOLEAN IsTDStatusStalled (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether the device/endpoint addressed by this TD is stalled.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x40);
+}
+
+
+BOOLEAN IsTDStatusBufferError (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether Data Buffer Error is happened.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x20);
+}
+
+
+BOOLEAN IsTDStatusBabbleError (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether Babble Error is happened.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x10);
+}
+
+
+BOOLEAN IsTDStatusNAKReceived (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether NAK is received.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x08);
+}
+
+
+BOOLEAN IsTDStatusCRCTimeOutError (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether CRC/Time Out Error is encountered.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x04);
+}
+
+
+BOOLEAN IsTDStatusBitStuffError (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ UINT8 TDStatus;
+
+ //
+ // Detect whether Bitstuff Error is received.
+ //
+ TDStatus = (UINT8) (ptrTDStruct->TDData.TDStatus);
+ return (BOOLEAN) (TDStatus & 0x02);
+}
+
+
+UINT16 GetTDStatusActualLength (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Retrieve the actual number of bytes that were tansferred.
+ // the value is encoded as n-1. so return the decoded value.
+ //
+ return (UINT16) ( (ptrTDStruct->TDData.TDStatusActualLength) + 1 );
+}
+
+
+BOOLEAN GetTDLinkPtrValidorInvalid (
+ IN TD_STRUCT *ptrTDStruct )
+{
+ //
+ // Retrieve the information of whether the Link Pointer field
+ // is valid or not.
+ //
+ if (ptrTDStruct->TDData.TDLinkPtrTerminate) {
+ return FALSE;
+ }
+ else {
+ return TRUE;
+ }
+
+}
+
+
+UINTN CountTDsNumber (
+ IN TD_STRUCT *ptrFirstTD )
+{
+ UINTN Number;
+ TD_STRUCT *ptr;
+
+ //
+ // Count the queued TDs number.
+ //
+ Number = 0;
+ ptr = ptrFirstTD;
+ while (ptr) {
+ ptr = (TD_STRUCT *) ptr->ptrNextTD;
+ Number++;
+ }
+
+ return Number;
+}
+
+
+VOID LinkTDToQH (
+ IN QH_STRUCT *ptrQH,
+ IN TD_STRUCT *ptrTD )
+{
+ if (ptrQH == NULL || ptrTD == NULL) {
+ return;
+ }
+ //
+ // Validate QH Vertical Ptr field
+ //
+ SetQHVerticalValidorInvalid( ptrQH, TRUE );
+
+ //
+ // Vertical Ptr pointing to TD structure
+ //
+ SetQHVerticalQHorTDSelect( ptrQH, FALSE );
+
+ SetQHVerticalLinkPtr( ptrQH, (VOID *) ptrTD );
+
+ ptrQH->ptrDown = (VOID *) ptrTD;
+}
+
+
+VOID LinkTDToTD (
+ IN TD_STRUCT *ptrPreTD,
+ IN TD_STRUCT *ptrTD )
+{
+ if (ptrPreTD == NULL || ptrTD == NULL) {
+ return;
+ }
+ //
+ // Depth first fashion
+ //
+ SetTDLinkPtrDepthorBreadth( ptrPreTD, TRUE );
+
+ //
+ // Link pointer pointing to TD struct
+ //
+ SetTDLinkPtrQHorTDSelect( ptrPreTD, FALSE );
+
+ //
+ // Validate the link pointer valid bit
+ //
+ SetTDLinkPtrValidorInvalid( ptrPreTD, TRUE );
+
+ SetTDLinkPtr( ptrPreTD, ptrTD );
+
+ ptrPreTD->ptrNextTD = (VOID *) ptrTD;
+
+ ptrTD->ptrNextTD = NULL;
+}
+
+
+//
+// Transfer Schedule related Helper Functions
+//
+VOID SetorClearCurFrameListTerminate (
+ IN FRAMELIST_ENTRY *pCurEntry,
+ IN BOOLEAN bSet )
+{
+ //
+ // If TRUE, empty the frame. If FALSE, indicate the Pointer field is valid.
+ //
+ pCurEntry->FrameListPtrTerminate = (bSet ? 1 : 0);
+}
+
+
+VOID SetCurFrameListQHorTD (
+ IN FRAMELIST_ENTRY *pCurEntry,
+ IN BOOLEAN bQH )
+{
+ //
+ // This bit indicates to the hardware whether the item referenced by the
+ // link pointer is a TD or a QH.
+ //
+ pCurEntry->FrameListPtrQSelect = (bQH ? 1 : 0);
+}
+
+
+BOOLEAN IsCurFrameListQHorTD (
+ IN FRAMELIST_ENTRY *pCurEntry )
+{
+ //
+ //TRUE is QH
+ //FALSE is TD
+ //
+ return (BOOLEAN) (pCurEntry->FrameListPtrQSelect);
+}
+
+
+BOOLEAN GetCurFrameListTerminate (
+ IN FRAMELIST_ENTRY *pCurEntry )
+{
+ //
+ // TRUE means the frame is empty,
+ // FALSE means the link pointer field is valid.
+ //
+ return (BOOLEAN) (pCurEntry->FrameListPtrTerminate);
+}
+
+
+VOID SetCurFrameListPointer (
+ IN FRAMELIST_ENTRY *pCurEntry,
+ IN UINT8 *ptr )
+{
+ //
+ // Set the pointer field of the frame.
+ //
+ pCurEntry->FrameListPtr = (UINT32) (UINTN) ptr >> 4;
+}
+
+
+VOID *GetCurFrameListPointer (
+ IN FRAMELIST_ENTRY *pCurEntry )
+{
+ VOID *ptr;
+
+ //
+ // Get the link pointer of the frame.
+ //
+ ptr = (VOID *) (UINTN) ( (pCurEntry->FrameListPtr) << 4 );
+ return ptr;
+}
+
+
+VOID LinkQHToFrameList (
+ IN FRAMELIST_ENTRY *pEntry,
+ IN UINT16 FrameListIndex,
+ IN QH_STRUCT *ptrQH )
+{
+ FRAMELIST_ENTRY *pCurFrame;
+ QH_STRUCT *TempQH, *NextTempQH;
+ TD_STRUCT *TempTD;
+ BOOLEAN LINK;
+
+ //
+ // Get frame list entry that the link process will begin from.
+ //
+ pCurFrame = pEntry + FrameListIndex;
+
+ //
+ // if current frame is empty
+ // then link the specified QH directly to the Frame List.
+ //
+ if ( GetCurFrameListTerminate( pCurFrame ) ) {
+
+ //
+ // Link new QH to the frame list entry.
+ //
+ SetCurFrameListQHorTD( pCurFrame, TRUE );
+
+ SetCurFrameListPointer( pCurFrame, (UINT8 *) ptrQH );
+
+ //
+ // clear T bit in the Frame List, means that the frame list
+ // entry is no longer empty.
+ //
+ SetorClearCurFrameListTerminate( pCurFrame, FALSE );
+
+ return;
+
+ }
+ else {
+ //
+ // current frame list has link pointer
+ //
+ if ( !IsCurFrameListQHorTD( pCurFrame ) ) {
+ //
+ // a TD is linked to the framelist entry
+ //
+ TempTD = (TD_STRUCT *) GetCurFrameListPointer( pCurFrame );
+
+ while ( GetTDLinkPtrValidorInvalid( TempTD ) ) {
+
+ if ( IsTDLinkPtrQHOrTD( TempTD ) ) { // QH linked next to the TD
+ break;
+ }
+
+ TempTD = (TD_STRUCT *) GetTDLinkPtr( TempTD );
+ }
+
+ //
+ // either no ptr linked next to the TD or QH is linked next to the TD
+ //
+ if ( !GetTDLinkPtrValidorInvalid( TempTD ) ) {
+
+ //
+ // no ptr linked next to the TD
+ //
+ TempTD->ptrNextQH = ptrQH;
+ SetTDLinkPtrQHorTDSelect( TempTD, TRUE );
+ SetTDLinkPtr( TempTD, ptrQH );
+ SetTDLinkPtrValidorInvalid( TempTD, TRUE );
+ //ptrQH->ptrNext = NULL;
+
+ return;
+
+ }
+ else {
+ //
+ // QH is linked next to the TD
+ //
+ TempQH = (QH_STRUCT *) GetTDLinkPtr( TempTD );
+ }
+
+ }
+ else {
+ //
+ // a QH is linked to the framelist entry
+ //
+ TempQH = (QH_STRUCT *) GetCurFrameListPointer( pCurFrame );
+ }
+
+ //
+ // Set up Flag
+ //
+ LINK = TRUE;
+
+ //
+ // aVOID the same qh repeated linking in one frame entry
+ //
+ if (TempQH == ptrQH) {
+ LINK = FALSE;
+ }
+ //
+ // if current QH has next QH connected
+ //
+ while ( GetQHHorizontalValidorInvalid( TempQH ) ) {
+
+ //
+ // Get next QH pointer
+ //
+ NextTempQH = (QH_STRUCT *) GetQHHorizontalLinkPtr( TempQH );
+
+ //
+ // Bulk transfer qh may be self-linked,
+ // so, the code below is to aVOID dead-loop when meeting self-linked qh
+ //
+ if (NextTempQH == TempQH) {
+ LINK = FALSE;
+ break;
+ }
+
+ TempQH = NextTempQH;
+
+ //
+ // aVOID the same qh repeated linking in one frame entry
+ //
+ if (TempQH == ptrQH) {
+ LINK = FALSE;
+ }
+ }
+
+ if (LINK) {
+ // Link
+ TempQH->ptrNext = ptrQH;
+ SetQHHorizontalQHorTDSelect( TempQH, TRUE );
+ SetQHHorizontalLinkPtr( TempQH, ptrQH );
+ SetQHHorizontalValidorInvalid( TempQH, TRUE );
+ //ptrQH->ptrNext = NULL;
+ }
+
+ return;
+
+ }
+
+}
+
+
+EFI_STATUS ExecuteControlTransfer (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT *ptrTD,
+ UINT32 wIndex,
+ UINTN *ActualLen,
+ UINTN TimeOut,
+ UINT32 *TransferResult )
+{
+ UINT32 StatusAddr;
+ UINT32 FrameListBaseReg;
+ UINTN ErrTDPos;
+ UINTN Delay;
+ CHAR8 *ErrorStr;
+
+ //
+ // Retrieve the Registers' address
+ //
+ StatusAddr = UhcDev->UsbHostControllerBaseAddress + USBSTS;
+ FrameListBaseReg = UhcDev->UsbHostControllerBaseAddress + USBFLBASEADD;
+
+ ErrTDPos = 0;
+ *TransferResult = EFI_USB_NOERROR;
+ *ActualLen = 0;
+ Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
+
+ do {
+
+ CheckTDsResults( ptrTD, TransferResult, &ErrTDPos, ActualLen );
+
+ //
+ // TD is inactive, means the control transfer is end.
+ //
+ if ( (*TransferResult & EFI_USB_ERR_NOTEXECUTE) !=
+ EFI_USB_ERR_NOTEXECUTE ) {
+ break;
+ }
+ UhcDev->StallPpi->Stall( UhcDev->PeiServices, UhcDev->StallPpi, 50 );
+
+ } while (Delay--);
+
+
+ if (*TransferResult != EFI_USB_NOERROR) {
+ switch (*TransferResult)
+ {
+ case EFI_USB_ERR_NOTEXECUTE: ErrorStr = gUsbErrorStrings[0];
+ break;
+
+ case EFI_USB_ERR_STALL: ErrorStr = gUsbErrorStrings[1];
+ break;
+
+ case EFI_USB_ERR_BUFFER: ErrorStr = gUsbErrorStrings[2];
+ break;
+
+ case EFI_USB_ERR_BABBLE: ErrorStr = gUsbErrorStrings[3];
+ break;
+
+ case EFI_USB_ERR_NAK: ErrorStr = gUsbErrorStrings[4];
+ break;
+
+ case EFI_USB_ERR_CRC: ErrorStr = gUsbErrorStrings[5];
+ break;
+
+ case EFI_USB_ERR_TIMEOUT: ErrorStr = gUsbErrorStrings[6];
+ break;
+
+ case EFI_USB_ERR_BITSTUFF: ErrorStr = gUsbErrorStrings[7];
+ break;
+
+ case EFI_USB_ERR_SYSTEM: ErrorStr = gUsbErrorStrings[8];
+ break;
+ }
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS ExecBulkTransfer (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT *ptrTD,
+ UINT32 wIndex,
+ UINTN *ActualLen,
+ UINT8 *DataToggle,
+ UINTN TimeOut,
+ UINT32 *TransferResult )
+{
+ UINT32 StatusAddr;
+ UINT32 FrameListBaseReg;
+ UINTN ErrTDPos;
+ UINTN ScrollNum;
+ UINTN Delay;
+
+ StatusAddr = UhcDev->UsbHostControllerBaseAddress + USBSTS;
+ FrameListBaseReg = UhcDev->UsbHostControllerBaseAddress + USBFLBASEADD;
+
+ ErrTDPos = 0;
+ *TransferResult = EFI_USB_NOERROR;
+ *ActualLen = 0;
+
+ Delay = (TimeOut * STALL_1_MILLI_SECOND / 50) + 1;
+
+ do {
+
+ CheckTDsResults( ptrTD, TransferResult, &ErrTDPos, ActualLen );
+ //
+ // TD is inactive, thus meaning bulk transfer's end.
+ //
+ if ( (*TransferResult & EFI_USB_ERR_NOTEXECUTE) !=
+ EFI_USB_ERR_NOTEXECUTE ) {
+ break;
+ }
+ UhcDev->StallPpi->Stall( UhcDev->PeiServices, UhcDev->StallPpi, 50 );
+
+ } while (Delay--);
+
+ //
+ // has error
+ //
+ if (*TransferResult != EFI_USB_NOERROR) {
+
+ //
+ // scroll the Data Toggle back to the last success TD
+ //
+ ScrollNum = CountTDsNumber( ptrTD ) - ErrTDPos;
+ if (ScrollNum % 2) {
+ *DataToggle ^= 1;
+ }
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+VOID DeleteSingleQH (
+ USB_UHC_DEV *UhcDev,
+ QH_STRUCT *ptrQH,
+ UINT16 FrameListIndex,
+ BOOLEAN SearchOther )
+{
+ FRAMELIST_ENTRY *pCurFrame;
+ UINTN i;
+ UINTN BeginFrame;
+ UINTN EndFrame;
+ QH_STRUCT *TempQH;
+ TD_STRUCT *TempTD;
+ VOID *PtrPreQH = NULL;
+ BOOLEAN Found = FALSE;
+
+ if (ptrQH == NULL) {
+ return;
+ }
+
+ if (SearchOther) {
+ BeginFrame = 0;
+ EndFrame = 1024;
+ }
+ else {
+ BeginFrame = FrameListIndex % 1024;
+ EndFrame = (FrameListIndex + 1) % 1024;
+ }
+
+ for (i = BeginFrame; i < EndFrame; i++) {
+
+ pCurFrame = UhcDev->FrameListEntry + i;
+
+ if ( GetCurFrameListTerminate( pCurFrame ) ) {
+ //
+ // current frame list is empty,search next frame list entry
+ //
+ continue;
+ }
+
+ if ( !IsCurFrameListQHorTD( pCurFrame ) ) {
+ //
+ // TD linked to current framelist
+ //
+ TempTD = (TD_STRUCT *) GetCurFrameListPointer( pCurFrame );
+
+ while ( GetTDLinkPtrValidorInvalid( TempTD ) ) {
+
+ if ( IsTDLinkPtrQHOrTD( TempTD ) ) {
+ //
+ // QH linked next to the TD,break while()
+ //
+ break;
+ }
+
+ TempTD = (TD_STRUCT *) GetTDLinkPtr( TempTD );
+ }
+
+ if ( !GetTDLinkPtrValidorInvalid( TempTD ) ) {
+ //
+ // no QH linked next to the last TD,
+ // search next frame list
+ //
+ continue;
+ }
+
+ //
+ // a QH linked next to the last TD
+ //
+ TempQH = (QH_STRUCT *) GetTDLinkPtr( TempTD );
+
+ PtrPreQH = TempTD;
+
+ }
+ else {
+ //
+ // a QH linked to current framelist
+ //
+ TempQH = (QH_STRUCT *) GetCurFrameListPointer( pCurFrame );
+
+ PtrPreQH = NULL;
+ }
+
+ if (TempQH == ptrQH) {
+
+ if (PtrPreQH) { // QH linked to a TD struct
+
+ TempTD = (TD_STRUCT *) PtrPreQH;
+ SetTDLinkPtrValidorInvalid( TempTD, FALSE );
+ SetTDLinkPtr( TempTD, NULL );
+ TempTD->ptrNextQH = NULL;
+
+ }
+ else { // QH linked directly to current framelist entry
+
+ SetorClearCurFrameListTerminate( pCurFrame, TRUE );
+ SetCurFrameListPointer( pCurFrame, NULL );
+ }
+
+ Found = TRUE;
+ //
+ // search next framelist entry
+ //
+ continue;
+ }
+
+ while (TempQH != ptrQH) {
+
+ PtrPreQH = TempQH;
+
+ //
+ // Get next horizontal linked QH
+ //
+ TempQH = (QH_STRUCT *) GetQHHorizontalLinkPtr( TempQH );
+
+ //
+ // if has no valid QH linked,break the while()
+ //
+ if (TempQH == NULL) {
+ break;
+ }
+
+ //
+ // detect self-linked QH, then break the loop
+ //
+ if (TempQH == PtrPreQH) {
+ break;
+ }
+ }
+
+ if (TempQH != ptrQH) {
+ //
+ // search next frame list entry
+ //
+ continue;
+ }
+
+ //
+ // TempQH == ptrQH,
+ // Update the related QHs
+ //
+ if ( GetQHHorizontalValidorInvalid( ptrQH ) ) {
+ //
+ // if has QH connected after the deleted QH
+ //
+ //
+ // get next QH of the deleted QH
+ //
+ TempQH = GetQHHorizontalLinkPtr( ptrQH );
+
+ //----------------------------------------------
+ //
+ // Bulk transfer qh may be self link to itself to enhance performance
+ // so, only if the qh is not self linked, can we link the next qh to
+ // the previous qh
+ //
+ if (TempQH != ptrQH) {
+ //
+ // link the next QH to the previous QH
+ //
+ SetQHHorizontalLinkPtr( (QH_STRUCT *) PtrPreQH, TempQH );
+
+ ( (QH_STRUCT *) PtrPreQH )->ptrNext = TempQH;
+ }
+ //----------------------------------------------
+
+ //
+ // if the qh is self linked, also need to update the previous qh,
+ // the situation just the same as that there is no qh connected after
+ // the deleted qh
+ //
+ }
+ //
+ // has no QH connected after the deleted QH,
+ // or the deleted QH is self-linked,
+ //
+ //
+ // NULL the previous QH's link ptr and set Terminate field.
+ //
+ SetQHHorizontalValidorInvalid( (QH_STRUCT *) PtrPreQH, FALSE );
+ SetQHHorizontalLinkPtr( (QH_STRUCT *) PtrPreQH, NULL );
+ ( (QH_STRUCT *) PtrPreQH )->ptrNext = NULL;
+
+ Found = TRUE;
+ }
+
+ if (Found) {
+ //
+ // free memory once used by deleted QH
+ //
+ UhcFreePool( UhcDev, MEM_QH_TD_TYPE, (UINT8 *) ptrQH,
+ sizeof(QH_STRUCT) );
+ }
+
+ return;
+}
+
+
+VOID DeleteQueuedTDs (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT *ptrFirstTD )
+{
+ TD_STRUCT *Tptr1, *Tptr2;
+
+ Tptr1 = ptrFirstTD;
+ //
+ // Delete all the TDs in a queue.
+ //
+ while (Tptr1) {
+
+ Tptr2 = Tptr1;
+
+ if ( !GetTDLinkPtrValidorInvalid( Tptr2 ) ) {
+ Tptr1 = NULL;
+ }
+ else {
+ //
+ // has more than one TD in the queue.
+ //
+ Tptr1 = GetTDLinkPtr( Tptr2 );
+ }
+
+ UhcFreePool( UhcDev, MEM_QH_TD_TYPE, (UINT8 *) Tptr2,
+ sizeof(TD_STRUCT) );
+ }
+
+ return;
+}
+
+
+BOOLEAN CheckTDsResults (
+ IN TD_STRUCT *ptrTD,
+ OUT UINT32 *Result,
+ OUT UINTN *ErrTDPos,
+ OUT UINTN *ActualTransferSize )
+{
+ UINTN Len;
+
+ *Result = EFI_USB_NOERROR;
+ *ErrTDPos = 0;
+
+ //
+ // Init to zero.
+ //
+ *ActualTransferSize = 0;
+
+ while (ptrTD) {
+
+ if ( IsTDStatusActive( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_NOTEXECUTE;
+ }
+
+ if ( IsTDStatusStalled( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_STALL;
+ }
+
+
+ if ( IsTDStatusBufferError( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_BUFFER;
+ }
+
+ if ( IsTDStatusBabbleError( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_BABBLE;
+ }
+
+ if ( IsTDStatusNAKReceived( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_NAK;
+ }
+
+ if ( IsTDStatusCRCTimeOutError( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_TIMEOUT;
+ }
+
+ if ( IsTDStatusBitStuffError( ptrTD ) ) {
+ *Result |= EFI_USB_ERR_BITSTUFF;
+ }
+
+ //
+ // Accumulate actual transferred data length in each TD.
+ //
+ Len = GetTDStatusActualLength( ptrTD ) % 0x800;
+ *ActualTransferSize += Len;
+
+ //
+ // if any error encountered, stop processing the left TDs.
+ //
+ if (*Result) {
+ return FALSE;
+ }
+
+ ptrTD = (TD_STRUCT *) (ptrTD->ptrNextTD);
+ //
+ // Record the first Error TD's position in the queue,
+ // this value is zero-based.
+ //
+ (*ErrTDPos)++;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ VOID
+ SelfLinkBulkTransferQH (
+ IN QH_STRUCT *ptrQH
+ )
+ {
+ if (ptrQH == NULL) {
+ return;
+ }
+
+ //
+ // Make the QH's horizontal link pointer pointing to itself.
+ //
+ ptrQH->ptrNext = ptrQH;
+ SetQHHorizontalQHorTDSelect(ptrQH,TRUE);
+ SetQHHorizontalLinkPtr(ptrQH,ptrQH);
+ SetQHHorizontalValidorInvalid(ptrQH,TRUE);
+ }
+ */
+
+EFI_STATUS CreateMemoryBlock (
+ USB_UHC_DEV *UhcDev,
+ MEMORY_MANAGE_HEADER **MemoryHeader,
+ UINTN MemoryBlockSizeInPages )
+{
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS TempPtr;
+ UINTN MemPages;
+ UINT8 *Ptr;
+
+ //
+ // Memory Block uses MemoryBlockSizeInPages pages,
+ // memory management header and bit array use 1 page
+ //
+ MemPages = MemoryBlockSizeInPages + 1;
+ Status = ( **(UhcDev->PeiServices) ).AllocatePages(
+ UhcDev->PeiServices,
+ EfiConventionalMemory,
+ MemPages,
+ &TempPtr
+ );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ Ptr = (UINT8 *) ( (UINTN) TempPtr );
+
+ ZeroMem( Ptr, MemPages * PAGESIZE );
+
+ *MemoryHeader = (MEMORY_MANAGE_HEADER *) Ptr;
+ //
+ // adjust Ptr pointer to the next empty memory
+ //
+ Ptr += sizeof(MEMORY_MANAGE_HEADER);
+ //
+ // Set Bit Array initial address
+ //
+ (*MemoryHeader)->BitArrayPtr = Ptr;
+
+ (*MemoryHeader)->Next = NULL;
+
+ //
+ // Memory block initial address
+ //
+ Ptr = (UINT8 *) ( (UINTN) TempPtr );
+ Ptr += PAGESIZE;
+ (*MemoryHeader)->MemoryBlockPtr = Ptr;
+ //
+ // set Memory block size
+ //
+ (*MemoryHeader)->MemoryBlockSizeInBytes = MemoryBlockSizeInPages *
+ PAGESIZE;
+ //
+ // each bit in Bit Array will manage 32byte memory in memory block
+ //
+ (*MemoryHeader)->BitArraySizeInBytes =
+ ( (*MemoryHeader)->MemoryBlockSizeInBytes / 32 ) / 8;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS InitializeMemoryManagement (
+ USB_UHC_DEV *UhcDev )
+{
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ EFI_STATUS Status;
+ UINTN MemPages;
+
+ MemPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
+ Status = CreateMemoryBlock( UhcDev, &MemoryHeader, MemPages );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ UhcDev->Header1 = MemoryHeader;
+
+ Status = CreateMemoryBlock( UhcDev, &MemoryHeader, MemPages );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ UhcDev->Header2 = MemoryHeader;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS UhcAllocatePool (
+ USB_UHC_DEV *UhcDev,
+ UINT8 Type,
+ UINT8 **Pool,
+ UINTN AllocSize )
+{
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+ MEMORY_MANAGE_HEADER *NewMemoryHeader;
+ UINTN RealAllocSize;
+ UINTN MemoryBlockSizeInPages;
+ EFI_STATUS Status;
+
+ *Pool = NULL;
+
+ switch (Type)
+ {
+ case MEM_QH_TD_TYPE:
+ MemoryHeader = UhcDev->Header1;
+ break;
+
+ case MEM_DATA_BUFFER_TYPE:
+ MemoryHeader = UhcDev->Header2;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // allocate unit is 32 byte (align on 32 byte)
+ //
+ if (AllocSize % 32) {
+ RealAllocSize = (AllocSize / 32 + 1) * 32;
+ }
+ else {
+ RealAllocSize = AllocSize;
+ }
+ //RealAllocSize = (AllocSize / 32 + 1) * 32;
+
+ Status = EFI_NOT_FOUND;
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;
+ TempHeaderPtr = TempHeaderPtr->Next) {
+
+ Status = AllocMemInMemoryBlock(
+ TempHeaderPtr,
+ Pool,
+ RealAllocSize / 32
+ );
+ if ( !EFI_ERROR( Status ) ) {
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // There is no enough memory,
+ // Create a new Memory Block
+ //
+
+ //
+ // if pool size is larger than NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES,
+ // just allocate a large enough memory block.
+ //
+ if ( RealAllocSize > (NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES * PAGESIZE) ) {
+ MemoryBlockSizeInPages = RealAllocSize / PAGESIZE + 1;
+ }
+ else {
+ MemoryBlockSizeInPages = NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES;
+ }
+ Status = CreateMemoryBlock( UhcDev,
+ &NewMemoryHeader,
+ MemoryBlockSizeInPages );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ //
+ // Link the new Memory Block to the Memory Header list
+ //
+ InsertMemoryHeaderToList( MemoryHeader, NewMemoryHeader );
+
+ Status = AllocMemInMemoryBlock( NewMemoryHeader,
+ Pool,
+ RealAllocSize / 32
+ );
+ return Status;
+}
+
+
+EFI_STATUS AllocMemInMemoryBlock (
+ MEMORY_MANAGE_HEADER *MemoryHeader,
+ VOID **Pool,
+ UINTN NumberOfMemoryUnit )
+{
+ UINTN TempBytePos;
+ UINTN FoundBytePos = 0;
+ UINT8 i;
+ UINT8 FoundBitPos = 0;
+ UINT8 ByteValue;
+ UINT8 BitValue;
+ UINTN NumberOfZeros;
+ UINTN Count;
+
+ ByteValue = MemoryHeader->BitArrayPtr[0];
+ NumberOfZeros = 0;
+ i = 0;
+ for (TempBytePos = 0; TempBytePos < MemoryHeader->BitArraySizeInBytes;
+ ) {
+
+ //
+ // Pop out BitValue from a byte in TempBytePos.
+ //
+ BitValue = (UINT8) (ByteValue % 2);
+
+ if (BitValue == 0) {
+ //
+ // Found a free bit, the NumberOfZeros only record the number
+ // of those consecutive zeros
+ //
+ NumberOfZeros++;
+ //
+ // Found enough consecutive free space, break the loop
+ //
+ if (NumberOfZeros >= NumberOfMemoryUnit) {
+ break;
+ }
+ }
+ else {
+ //
+ // Encountering a '1', meant the bit is ocupied.
+ //
+ if (NumberOfZeros >= NumberOfMemoryUnit) {
+ //
+ // Found enough consecutive free space,break the loop
+ //
+ break;
+ }
+ else {
+ //
+ // the NumberOfZeros only record the number of those consecutive zeros,
+ // so reset the NumberOfZeros to 0 when encountering '1' before finding
+ // enough consecutive '0's
+ //
+ NumberOfZeros = 0;
+ //
+ // reset the (FoundBytePos,FoundBitPos) to the position of '1'
+ //
+ FoundBytePos = TempBytePos;
+ FoundBitPos = i;
+ }
+ }
+
+ //
+ // right shift the byte
+ //
+ ByteValue /= 2;
+
+ //
+ // step forward a bit
+ //
+ i++;
+ if (i == 8) {
+ //
+ // step forward a byte, getting the byte value,
+ // and reset the bit pos.
+ //
+ TempBytePos += 1;
+ ByteValue = MemoryHeader->BitArrayPtr[TempBytePos];
+ i = 0;
+ }
+ }
+
+ if (NumberOfZeros < NumberOfMemoryUnit) {
+ return EFI_NOT_FOUND;
+ }
+
+ //
+ // Found enough free space.
+ //
+
+ //
+ // The values recorded in (FoundBytePos,FoundBitPos) have two conditions:
+ // 1)(FoundBytePos,FoundBitPos) record the position
+ // of the last '1' before the consecutive '0's, it must
+ // be adjusted to the start position of the consecutive '0's.
+ // 2)the start address of the consecutive '0's is just the start of
+ // the bitarray. so no need to adjust the values of
+ // (FoundBytePos,FoundBitPos).
+ //
+ if ( ( MemoryHeader->BitArrayPtr[0] & bit( 0 ) ) != 0 ) {
+ FoundBitPos += 1;
+ }
+
+ //
+ // Have the (FoundBytePos,FoundBitPos) make sense.
+ //
+ if (FoundBitPos > 7) {
+ FoundBytePos += 1;
+ FoundBitPos -= 8;
+ }
+
+ //
+ // Set the memory as allocated
+ //
+ for (TempBytePos = FoundBytePos, i = FoundBitPos, Count = 0;
+ Count < NumberOfMemoryUnit; Count++) {
+
+ MemoryHeader->BitArrayPtr[TempBytePos] |= bit( i );
+ i++;
+ if (i == 8) {
+ TempBytePos += 1;
+ i = 0;
+ }
+ }
+
+ *Pool = MemoryHeader->MemoryBlockPtr +
+ (FoundBytePos * 8 + FoundBitPos) * 32;
+
+ return EFI_SUCCESS;
+}
+
+
+VOID UhcFreePool (
+ USB_UHC_DEV *UhcDev,
+ UINT8 Type,
+ UINT8 *Pool,
+ UINTN AllocSize )
+{
+ MEMORY_MANAGE_HEADER *MemoryHeader;
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+ UINTN StartBytePos;
+ UINTN i;
+ UINT8 StartBitPos;
+ UINT8 j;
+ UINTN Count;
+ UINTN RealAllocSize;
+
+ // UINTN MemPages;
+ // EFI_PHYSICAL_ADDRESS TempPtr;
+
+ switch (Type)
+ {
+ case MEM_QH_TD_TYPE:
+ MemoryHeader = UhcDev->Header1;
+ break;
+
+ case MEM_DATA_BUFFER_TYPE:
+ MemoryHeader = UhcDev->Header2;
+ break;
+
+ default:
+ return;
+ }
+
+ //
+ // allocate unit is 32 byte (align on 32 byte)
+ //
+ if (AllocSize % 32) {
+ RealAllocSize = (AllocSize / 32 + 1) * 32;
+ }
+ else {
+ RealAllocSize = AllocSize;
+ }
+ //RealAllocSize = (AllocSize / 32 + 1) * 32;
+
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;
+ TempHeaderPtr = TempHeaderPtr->Next) {
+
+ if ( (Pool >= TempHeaderPtr->MemoryBlockPtr) &&
+ ( (Pool + RealAllocSize) <= (TempHeaderPtr->MemoryBlockPtr +
+ TempHeaderPtr->
+ MemoryBlockSizeInBytes) ) ) {
+
+ //
+ // Pool is in the Memory Block area,
+ // find the start byte and bit in the bit array
+ //
+ StartBytePos = ( (Pool -
+ TempHeaderPtr->MemoryBlockPtr) / 32 ) / 8;
+ StartBitPos = (UINT8)
+ ( ( (Pool -
+ TempHeaderPtr->MemoryBlockPtr) / 32 ) % 8 );
+
+ //
+ // reset associated bits in bit arry
+ //
+ for (i = StartBytePos, j = StartBitPos, Count = 0;
+ Count < (RealAllocSize / 32); Count++) {
+
+ TempHeaderPtr->BitArrayPtr[i] ^= (UINT8) ( bit( j ) );
+ j++;
+ if (j == 8) {
+ i += 1;
+ j = 0;
+ }
+ }
+ //
+ // break the loop
+ //
+ break;
+ }
+ }
+
+}
+
+
+VOID InsertMemoryHeaderToList (
+ MEMORY_MANAGE_HEADER *MemoryHeader,
+ MEMORY_MANAGE_HEADER *NewMemoryHeader )
+{
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+
+ for (TempHeaderPtr = MemoryHeader; TempHeaderPtr != NULL;
+ TempHeaderPtr = TempHeaderPtr->Next) {
+ if (TempHeaderPtr->Next == NULL) {
+ TempHeaderPtr->Next = NewMemoryHeader;
+ break;
+ }
+ }
+}
+
+
+BOOLEAN IsMemoryBlockEmptied (
+ MEMORY_MANAGE_HEADER *MemoryHeaderPtr )
+{
+ UINTN i;
+
+ for (i = 0; i < MemoryHeaderPtr->BitArraySizeInBytes; i++) {
+ if (MemoryHeaderPtr->BitArrayPtr[i] != 0) {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+VOID DelinkMemoryBlock (
+ MEMORY_MANAGE_HEADER *FirstMemoryHeader,
+ MEMORY_MANAGE_HEADER *FreeMemoryHeader )
+{
+ MEMORY_MANAGE_HEADER *TempHeaderPtr;
+
+ if ( (FirstMemoryHeader == NULL) || (FreeMemoryHeader == NULL) ) {
+ return;
+ }
+ for (TempHeaderPtr = FirstMemoryHeader; TempHeaderPtr != NULL;
+ TempHeaderPtr = TempHeaderPtr->Next) {
+
+ if (TempHeaderPtr->Next == FreeMemoryHeader) {
+ //
+ // Link the before and after
+ //
+ TempHeaderPtr->Next = FreeMemoryHeader->Next;
+ break;
+ }
+ }
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.h b/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.h
new file mode 100644
index 0000000..6c167c7
--- /dev/null
+++ b/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeim.h
@@ -0,0 +1,865 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UhcPeimSrc/UhcPeim.h 9 8/23/12 10:01p Wilsonlee $
+//
+// $Revision: 9 $
+//
+// $Date: 8/23/12 10:01p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UhcPeimSrc/UhcPeim.h $
+//
+// 9 8/23/12 10:01p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 8 1/18/11 1:01a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 7 4/29/09 2:13p Olegi
+// Added TreansactionTranslator to UHCI Bulk transfer.
+//
+// 6 3/17/09 5:06p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 5 3/03/09 7:21p Olegi
+// Changed the type of MaxPktSize from UINT8 to UINT16.
+//
+// 4 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 3 4/16/07 12:44p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:34a Meenakshim
+//
+// 1 9/22/06 12:21p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UhcPeim.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains a 'Sample Driver' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may be modified by the user, subject to
+// the additional terms of the license agreement
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UhcPeim.h
+
+ Abstract:
+
+ Header file for Usb Host Controller PEIM
+
+ --*/
+#ifndef _RECOVERY_UHC_H
+#define _RECOVERY_UHC_H
+
+#include "Efi.h"
+#include "Pei.h"
+#include "AmiPeiLib.h"
+#include "AmiMapping.h"
+//#include "PeiHob.h" // NOT NEEDED FOR APTIO
+//#include "PeiLib.h" // NOT NEEDED FOR APTIO
+
+//
+// Driver Produced PPI Prototypes
+//
+#include "Ppi\UsbHostController.h"
+//
+// Driver Consumed PPI Prototypes
+//
+#include EFI_PPI_DEFINITION( CpuIo )
+#include EFI_PPI_DEFINITION( Stall )
+#include "Ppi\PeiGetUCtrl.h"
+
+#define bit( a ) (1 << (a))
+
+#define USB_SLOW_SPEED_DEVICE 0x01
+#define USB_FULL_SPEED_DEVICE 0x02
+
+//
+// One memory block uses 16 page
+//
+#define NORMAL_MEMORY_BLOCK_UNIT_IN_PAGES 16
+
+#define USBCMD 0 // Command Register Offset 00-01h
+#define USBCMD_RS bit( 0 ) // Run/Stop
+#define USBCMD_HCRESET bit( 1 ) // Host reset
+#define USBCMD_GRESET bit( 2 ) // Global reset
+#define USBCMD_EGSM bit( 3 ) // Global Suspend Mode
+#define USBCMD_FGR bit( 4 ) // Force Global Resume
+#define USBCMD_SWDBG bit( 5 ) // SW Debug mode
+#define USBCMD_CF bit( 6 ) // Config Flag (sw only)
+#define USBCMD_MAXP bit( 7 ) // Max Packet (0 = 32, 1 = 64)
+
+// Status register
+#define USBSTS 2 // Status Register Offset 02-03h
+#define USBSTS_USBINT bit( 0 ) // Interrupt due to IOC
+#define USBSTS_ERROR bit( 1 ) // Interrupt due to error
+#define USBSTS_RD bit( 2 ) // Resume Detect
+#define USBSTS_HSE bit( 3 ) // Host System Error
+ // - basically PCI problems
+#define USBSTS_HCPE bit( 4 ) // Host Controller Process Error
+ // - the scripts were buggy
+#define USBSTS_HCH bit( 5 ) // HC Halted
+
+// Interrupt enable register
+#define USBINTR 4 // Interrupt Enable Register 04-05h
+#define USBINTR_TIMEOUT bit( 0 ) // Timeout/CRC error enable
+#define USBINTR_RESUME bit( 1 ) // Resume interrupt enable
+#define USBINTR_IOC bit( 2 ) // Interrupt On Complete enable
+#define USBINTR_SP bit( 3 ) // Short packet interrupt enable
+
+// Frame Number Register Offset 06-08h
+#define USBFRNUM 6
+
+// Frame List Base Address Register Offset 08-0Bh
+#define USBFLBASEADD 8
+
+// Start of Frame Modify Register Offset 0Ch
+#define USBSOF 0x0c
+
+// USB port status and control registers
+#define USBPORTSC1 0x10 //Port 1 offset 10-11h
+#define USBPORTSC2 0x12 //Port 2 offset 12-13h
+
+#define USBPORTSC_CCS bit( 0 ) // Current Connect Status ("device present")
+#define USBPORTSC_CSC bit( 1 ) // Connect Status Change
+#define USBPORTSC_PED bit( 2 ) // Port Enable / Disable
+#define USBPORTSC_PEDC bit( 3 ) // Port Enable / Disable Change
+#define USBPORTSC_LSL bit( 4 ) // Line Status Low bit
+#define USBPORTSC_LSH bit( 5 ) // Line Status High bit
+#define USBPORTSC_RD bit( 6 ) // Resume Detect
+#define USBPORTSC_LSDA bit( 8 ) // Low Speed Device Attached
+#define USBPORTSC_PR bit( 9 ) // Port Reset
+#define USBPORTSC_SUSP bit( 12 ) // Suspend
+
+#define SETUP_PACKET_ID 0x2d
+#define INPUT_PACKET_ID 0x69
+#define OUTPUT_PACKET_ID 0xe1
+#define ERROR_PACKET_ID 0x55
+
+#define MEM_QH_TD_TYPE 0
+#define MEM_DATA_BUFFER_TYPE 1
+
+#define STALL_1_MILLI_SECOND 1000
+//#define STALL_1_MILLI_SECOND 10
+
+//#pragma pack(1)
+
+#pragma pack(push, 16)
+typedef struct
+{
+ UINT32 FrameListPtrTerminate : 1;
+ UINT32 FrameListPtrQSelect : 1;
+ UINT32 FrameListRsvd : 2;
+ UINT32 FrameListPtr : 28;
+} FRAMELIST_ENTRY;
+
+typedef struct
+{
+ UINT32 QHHorizontalTerminate : 1;
+ UINT32 QHHorizontalQSelect : 1;
+ UINT32 QHHorizontalRsvd : 2;
+ UINT32 QHHorizontalPtr : 28;
+ UINT32 QHVerticalTerminate : 1;
+ UINT32 QHVerticalQSelect : 1;
+ UINT32 QHVerticalRsvd : 2;
+ UINT32 QHVerticalPtr : 28;
+} QUEUE_HEAD;
+
+typedef struct
+{
+ QUEUE_HEAD QH;
+ UINT32 reserved1;
+ UINT32 reserved2;
+ VOID *ptrNext;
+ VOID *ptrDown;
+ VOID *reserved3;
+ UINT32 reserved4;
+} QH_STRUCT;
+
+typedef struct
+{
+ UINT32 TDLinkPtrTerminate : 1;
+ UINT32 TDLinkPtrQSelect : 1;
+ UINT32 TDLinkPtrDepthSelect : 1;
+ UINT32 TDLinkPtrRsvd : 1;
+ UINT32 TDLinkPtr : 28;
+ UINT32 TDStatusActualLength : 11;
+ UINT32 TDStatusRsvd : 5;
+ UINT32 TDStatus : 8;
+ UINT32 TDStatusIOC : 1;
+ UINT32 TDStatusIOS : 1;
+ UINT32 TDStatusLS : 1;
+ UINT32 TDStatusErr : 2;
+ UINT32 TDStatusSPD : 1;
+ UINT32 TDStatusRsvd2 : 2;
+ UINT32 TDTokenPID : 8;
+ UINT32 TDTokenDevAddr : 7;
+ UINT32 TDTokenEndPt : 4;
+ UINT32 TDTokenDataToggle : 1;
+ UINT32 TDTokenRsvd : 1;
+ UINT32 TDTokenMaxLen : 11;
+ UINT32 TDBufferPtr;
+} TD;
+
+typedef struct
+{
+ TD TDData;
+ UINT8 *pTDBuffer;
+ VOID *ptrNextTD;
+ VOID *ptrNextQH;
+ UINT16 TDBufferLength;
+ UINT16 reserved;
+} TD_STRUCT;
+
+//#pragma pack()
+#pragma pack(pop)
+
+typedef struct _MEMORY_MANAGE_HEADER
+{
+ UINT8 *BitArrayPtr;
+ UINTN BitArraySizeInBytes;
+ UINT8 *MemoryBlockPtr;
+ UINTN MemoryBlockSizeInBytes;
+ struct _MEMORY_MANAGE_HEADER *Next;
+} MEMORY_MANAGE_HEADER;
+
+#define USB_UHC_DEV_SIGNATURE EFI_SIGNATURE_32( 'p', 'u', 'h', 'c' )
+typedef struct
+{
+ UINTN Signature;
+
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ PEI_CPU_IO_PPI *CpuIoPpi;
+ PEI_STALL_PPI *StallPpi;
+
+ UINT32 UsbHostControllerBaseAddress;
+ FRAMELIST_ENTRY *FrameListEntry;
+ //
+ // Header1 used for QH,TD memory blocks management
+ //
+ MEMORY_MANAGE_HEADER *Header1;
+ //
+ // Header2 used for Data transfer memory blocks management
+ //
+ MEMORY_MANAGE_HEADER *Header2;
+ UINT16 PortResetStatusChangeMap;
+} USB_UHC_DEV;
+
+#define PEI_RECOVERY_USB_UHC_DEV_FROM_UHCI_THIS( a ) \
+ PEI_CR( a, USB_UHC_DEV, UsbHostControllerPpi, USB_UHC_DEV_SIGNATURE )
+
+EFI_STATUS
+UhcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS
+UhcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS
+UhcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber );
+
+EFI_STATUS
+UhcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus );
+
+EFI_STATUS
+UhcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+EFI_STATUS
+UhcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+EFI_STATUS
+InitializeUsbHC (
+ USB_UHC_DEV *UhcDev );
+
+EFI_STATUS
+CreateFrameList (
+ USB_UHC_DEV *UhcDev );
+
+VOID
+InitFrameList (
+ USB_UHC_DEV *UhcDev );
+
+UINT16
+USBReadPortW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port );
+
+
+UINT32
+USBReadPortDW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port );
+
+VOID
+USBWritePortW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port,
+ IN UINT16 Data );
+
+VOID
+USBWritePortDW (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 Port,
+ IN UINT32 Data );
+
+
+VOID
+ClearStatusReg (
+ IN USB_UHC_DEV *UhcDev,
+ IN UINT32 STSAddr );
+
+
+UINT32
+GetFrameListBaseAddrFromRegister (
+ USB_UHC_DEV *UhcDev,
+ UINT32 FLBAAddr );
+
+BOOLEAN
+IsHostSysErr (
+ USB_UHC_DEV *UhcDev,
+ UINT32 StatusRegAddr );
+
+BOOLEAN
+IsHCProcessErr (
+ USB_UHC_DEV *UhcDev,
+ UINT32 StatusRegAddr );
+
+BOOLEAN
+IsHCHalted (
+ USB_UHC_DEV *UhcDev,
+ UINT32 StatusRegAddr );
+
+
+UINT16
+GetCurrentFrameNumber (
+ USB_UHC_DEV *UhcDev,
+ UINT32 FRNUMAddr );
+
+VOID
+SetFrameListBaseAddress (
+ USB_UHC_DEV *UhcDev,
+ UINT32 FLBASEADDRReg,
+ UINT32 Addr );
+
+
+EFI_STATUS
+AllocateQHStruct (
+ USB_UHC_DEV *UhcDev,
+ QH_STRUCT **ppQHStruct );
+
+VOID
+InitQH (
+ IN QH_STRUCT *ptrQH );
+
+
+EFI_STATUS
+CreateQH (
+ USB_UHC_DEV *UhcDev,
+ QH_STRUCT **pptrQH );
+
+VOID
+SetQHHorizontalLinkPtr (
+ IN QH_STRUCT *ptrQH,
+ IN VOID *ptrNext );
+
+VOID *
+GetQHHorizontalLinkPtr (
+ IN QH_STRUCT *ptrQH );
+
+VOID
+SetQHHorizontalQHorTDSelect (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bQH );
+
+
+VOID
+SetQHHorizontalValidorInvalid (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bValid );
+
+VOID
+SetQHVerticalLinkPtr (
+ IN QH_STRUCT *ptrQH,
+ IN VOID *ptrNext );
+
+VOID *
+GetQHVerticalLinkPtr (
+ IN QH_STRUCT *ptrQH );
+
+VOID
+SetQHVerticalQHorTDSelect (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bQH );
+
+BOOLEAN
+IsQHHorizontalQHSelect (
+ IN QH_STRUCT *ptrQH );
+
+VOID
+SetQHVerticalValidorInvalid (
+ IN QH_STRUCT *ptrQH,
+ IN BOOLEAN bValid );
+
+
+BOOLEAN
+GetQHVerticalValidorInvalid (
+ IN QH_STRUCT *ptrQH );
+
+BOOLEAN
+GetQHHorizontalValidorInvalid (
+ IN QH_STRUCT *ptrQH );
+
+
+EFI_STATUS
+AllocateTDStruct (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT **ppTDStruct );
+
+VOID
+InitTD (
+ IN TD_STRUCT *ptrTD );
+
+EFI_STATUS
+CreateTD (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT **pptrTD );
+
+EFI_STATUS
+GenSetupStageTD (
+ USB_UHC_DEV *UhcDev,
+ UINT8 DevAddr,
+ UINT8 Endpoint,
+ UINT8 DeviceSpeed,
+ UINT8 *pDevReq,
+ UINT8 RequestLen,
+ TD_STRUCT **ppTD );
+
+EFI_STATUS
+GenDataTD (
+ USB_UHC_DEV *UhcDev,
+ UINT8 DevAddr,
+ UINT8 Endpoint,
+ UINT8 *pData,
+ UINT16 Len,
+ UINT8 PktID,
+ UINT8 Toggle,
+ UINT8 DeviceSpeed,
+ TD_STRUCT **ppTD );
+
+EFI_STATUS
+CreateStatusTD (
+ USB_UHC_DEV *UhcDev,
+ UINT8 DevAddr,
+ UINT8 Endpoint,
+ UINT8 PktID,
+ UINT8 DeviceSpeed,
+ TD_STRUCT **ppTD );
+
+
+VOID
+SetTDLinkPtrValidorInvalid (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bValid );
+
+VOID
+SetTDLinkPtrQHorTDSelect (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bQH );
+
+VOID
+SetTDLinkPtrDepthorBreadth (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bDepth );
+
+VOID
+SetTDLinkPtr (
+ IN TD_STRUCT *ptrTDStruct,
+ IN VOID *ptrNext );
+
+VOID *
+GetTDLinkPtr (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDLinkPtrQHOrTD (
+ IN TD_STRUCT *ptrTDStruct );
+
+VOID
+EnableorDisableTDShortPacket (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bEnable );
+
+VOID
+SetTDControlErrorCounter (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINT8 nMaxErrors );
+
+
+VOID
+SetTDLoworFullSpeedDevice (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bLowSpeedDevice );
+
+VOID
+SetTDControlIsochronousorNot (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bIsochronous );
+
+VOID
+SetorClearTDControlIOC (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bSet );
+
+VOID
+SetTDStatusActiveorInactive (
+ IN TD_STRUCT *ptrTDStruct,
+ IN BOOLEAN bActive );
+
+UINT16
+SetTDTokenMaxLength (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINT16 nMaxLen );
+
+VOID
+SetTDTokenDataToggle1 (
+ IN TD_STRUCT *ptrTDStruct );
+
+VOID
+SetTDTokenDataToggle0 (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT8
+GetTDTokenDataToggle (
+ IN TD_STRUCT *ptrTDStruct );
+
+VOID
+SetTDTokenEndPoint (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINTN nEndPoint );
+
+VOID
+SetTDTokenDeviceAddress (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINTN nDevAddr );
+
+VOID
+SetTDTokenPacketID (
+ IN TD_STRUCT *ptrTDStruct,
+ IN UINT8 nPID );
+
+VOID
+SetTDDataBuffer (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusActive (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusStalled (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusBufferError (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusBabbleError (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusNAKReceived (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusCRCTimeOutError (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+IsTDStatusBitStuffError (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT16
+GetTDStatusActualLength (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT16
+GetTDTokenMaxLength (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT8
+GetTDTokenEndPoint (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT8
+GetTDTokenDeviceAddress (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT8
+GetTDTokenPacketID (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINT8 *
+GetTDDataBuffer (
+ IN TD_STRUCT *ptrTDStruct );
+
+BOOLEAN
+GetTDLinkPtrValidorInvalid (
+ IN TD_STRUCT *ptrTDStruct );
+
+UINTN
+CountTDsNumber (
+ IN TD_STRUCT *ptrFirstTD );
+
+VOID
+LinkTDToQH (
+ IN QH_STRUCT *ptrQH,
+ IN TD_STRUCT *ptrTD );
+
+VOID
+LinkTDToTD (
+ IN TD_STRUCT *ptrPreTD,
+ IN TD_STRUCT *ptrTD );
+
+
+//
+// Transfer Schedule related Helper Functions
+//
+VOID
+SetorClearCurFrameListTerminate (
+ IN FRAMELIST_ENTRY *pCurEntry,
+ IN BOOLEAN bSet );
+
+VOID
+SetCurFrameListQHorTD (
+ IN FRAMELIST_ENTRY *pCurEntry,
+ IN BOOLEAN bQH );
+
+BOOLEAN
+IsCurFrameListQHorTD (
+ IN FRAMELIST_ENTRY *pCurEntry );
+
+BOOLEAN
+GetCurFrameListTerminate (
+ IN FRAMELIST_ENTRY *pCurEntry );
+
+VOID
+SetCurFrameListPointer (
+ IN FRAMELIST_ENTRY *pCurEntry,
+ IN UINT8 *ptr );
+
+VOID *
+GetCurFrameListPointer (
+ IN FRAMELIST_ENTRY *pCurEntry );
+
+VOID
+LinkQHToFrameList (
+ IN FRAMELIST_ENTRY *pEntry,
+ IN UINT16 FrameListIndex,
+ IN QH_STRUCT *ptrQH );
+
+EFI_STATUS
+ExecuteControlTransfer (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT *ptrTD,
+ UINT32 wIndex,
+ UINTN *ActualLen,
+ UINTN TimeOut,
+ UINT32 *TransferResult );
+
+EFI_STATUS
+ExecBulkTransfer (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT *ptrTD,
+ UINT32 wIndex,
+ UINTN *ActualLen,
+ UINT8 *DataToggle,
+ UINTN TimeOut,
+ UINT32 *TransferResult );
+
+VOID
+DeleteSingleQH (
+ USB_UHC_DEV *UhcDev,
+ QH_STRUCT *ptrQH,
+ UINT16 FrameListIndex,
+ BOOLEAN SearchOther );
+
+VOID
+DeleteQueuedTDs (
+ USB_UHC_DEV *UhcDev,
+ TD_STRUCT *ptrFirstTD );
+
+
+BOOLEAN
+CheckTDsResults (
+ IN TD_STRUCT *ptrTD,
+ OUT UINT32 *Result,
+ OUT UINTN *ErrTDPos,
+ OUT UINTN *ActualTransferSize );
+
+VOID
+ClearTDStatus (
+ IN TD_STRUCT *ptrTD );
+
+VOID
+SelfLinkBulkTransferQH (
+ IN QH_STRUCT *ptrQH );
+
+EFI_STATUS
+CreateMemoryBlock (
+ USB_UHC_DEV *UhcDev,
+ MEMORY_MANAGE_HEADER **MemoryHeader,
+ UINTN MemoryBlockSizeInPages );
+
+EFI_STATUS
+InitializeMemoryManagement (
+ USB_UHC_DEV *UhcDev );
+
+EFI_STATUS
+UhcAllocatePool (
+ USB_UHC_DEV *UhcDev,
+ UINT8 Type,
+ UINT8 **Pool,
+ UINTN AllocSize );
+
+EFI_STATUS
+AllocMemInMemoryBlock (
+ MEMORY_MANAGE_HEADER *MemoryHeader,
+ VOID **Pool,
+ UINTN NumberOfMemoryUnit );
+
+
+VOID
+UhcFreePool (
+ USB_UHC_DEV *UhcDev,
+ UINT8 Type,
+ UINT8 *Pool,
+ UINTN AllocSize );
+
+VOID
+InsertMemoryHeaderToList (
+ MEMORY_MANAGE_HEADER *MemoryHeader,
+ MEMORY_MANAGE_HEADER *NewMemoryHeader );
+
+BOOLEAN
+IsMemoryBlockEmptied (
+ MEMORY_MANAGE_HEADER *MemoryHeaderPtr );
+
+VOID
+DelinkMemoryBlock (
+ MEMORY_MANAGE_HEADER *FirstMemoryHeader,
+ MEMORY_MANAGE_HEADER *FreeMemoryHeader );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeimSrc.cif b/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeimSrc.cif
new file mode 100644
index 0000000..582376f
--- /dev/null
+++ b/Core/EM/UsbRecovery/UhcPeimSrc/UhcPeimSrc.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "UhcPeimSrc"
+ category = ModulePart
+ LocalRoot = "Core\em\UsbRecovery\UhcPeimSrc"
+ RefName = "UhcPeimSrc"
+[files]
+"UhcPeim.c"
+"UhcPeim.h"
+[parts]
+"UsbHCPpi"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.c b/Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.c
new file mode 100644
index 0000000..953d37c
--- /dev/null
+++ b/Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.c
@@ -0,0 +1,376 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UhciPeiUsb.c 10 10/23/08 1:59p Michaela $
+//
+// $Revision: 10 $
+//
+// $Date: 10/23/08 1:59p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UhciPeiUsb.c $
+//
+// 10 10/23/08 1:59p Michaela
+// Removed UsbDebug.h include
+//
+// 9 10/21/08 5:56p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 8 7/10/08 6:34p Michaela
+// Updated to support OHCI controllers
+//
+// 7 10/23/07 5:56p Ambikas
+//
+// 6 10/23/07 5:39p Ambikas
+//
+// 5 8/17/07 4:05p Ambikas
+//
+// 4 9/22/06 4:03p Sivagarn
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UhciPeiUsb.C
+//
+// Description: This file is the main source file for the UHCI PEI USB
+// recovery module
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <PEI.h>
+#include <AmiPeiLib.h>
+#include <PPI/PeiGetUCtrl.h>
+#include <token.h>
+
+
+//----------------------------------------------------------------------------
+// Global Constants
+//----------------------------------------------------------------------------
+
+#define PCI_REG_UHCI_COMMAND_REGISTER 0x04
+#define PCI_REG_UHCI_BASE_ADDRESS_REGISTER 0x20
+#define PCI_REG_UHCI_LEGACY_CONTROL_REGISTER 0xc0
+#define PCI_REG_UHCI_RESUME_ENABLE_REGISTER 0xc4
+
+#define PEI_UHCI_CONTROLLER 0x01
+
+#define PCI_REG_EHCI_MEMORY_BAR 0x10
+
+#define EHCI_HC_OPERATIONAL_CONFIG_FLAG_REG 0x40
+
+UINTN gUhciPciReg[] = PEI_UHCI_PCI_DEVICES;
+#define MAX_USB_CTRLERS sizeof(gUhciPciReg) / sizeof(UINTN)
+
+
+//----------------------------------------------------------------------------
+// Type definitions
+//----------------------------------------------------------------------------
+
+typedef struct
+{
+ // UINTN Signature;
+ // PEI_USB_CONTROLLER_PPI UsbControllerPpi;
+ // EFI_PEI_PPI_DESCRIPTOR PpiList;
+ // PEI_PCI_CFG_PPI *PciCfgPpi;
+ // UINTN TotalUsbControllers;
+ UINTN IoBase[MAX_USB_CTRLERS];
+} PCI_UHCI_DEVICE;
+
+//----------------------------------------------------------------------------
+// Function Prototypes
+//----------------------------------------------------------------------------
+
+EFI_STATUS GetUhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_USB_CONTROLLER_PPI *This,
+ IN UINT8 UsbControllerId,
+ IN UINTN *ControllerType,
+ IN UINTN *IoBaseAddress );
+
+EFI_STATUS
+EnableUhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *PciCfgPpi,
+ IN UINTN BaseAddress,
+ IN UINT8 UsbControllerId );
+
+VOID
+ClearEhciConfigFlagReg (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *PciCfgPpi );
+
+//----------------------------------------------------------------------------
+// Global Variables
+//----------------------------------------------------------------------------
+
+#ifdef PEI_EHCI_MEM_BASE_ADDRESSES
+UINTN mEhciPciBDFs[USB_EHCI] = PEI_EHCI_PCI_BDFS;
+UINT32 mEhciMemBaseAddresses[USB_EHCI] = PEI_EHCI_MEM_BASE_ADDRESSES;
+#endif
+
+static EFI_GUID guidGetUhciController = EFI_PEI_GET_UHCI_CTRLER_GUID;
+PCI_UHCI_DEVICE gPeiUhciDev;
+EFI_PEI_USB_CONTROLLER_PPI GetUhciControllerPpi = {
+ GetUhciController
+};
+
+// PPI to be installed
+static
+EFI_PEI_PPI_DESCRIPTOR PpiList[] = {
+ {EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &guidGetUhciController, &GetUhciControllerPpi}
+};
+
+//----------------------------------------------------------------------------
+// Function Definitions
+//----------------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UhciPeiUsbEntryPoint
+//
+// Description: This function is the entry point for this PEI. This function
+// initializes the UHCI Controller
+//
+// Input: FfsHeader Pointer to the FFS file header
+// PeiServices Pointer to the PEI services table
+//
+// Output: Return Status based on errors that occurred while waiting for
+// time to expire.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+
+ UINTN i;
+ EFI_STATUS Status;
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi;
+
+ // Set PCI Config pointer
+ PciCfgPpi = (*PeiServices)->PciCfg;
+
+ #ifdef PEI_EHCI_MEM_BASE_ADDRESSES
+ ClearEhciConfigFlagReg( PeiServices, PciCfgPpi );
+ #endif
+
+ // Assign resources and enable UHCI controllers
+ for (i = 0; i < MAX_USB_CTRLERS; i++) {
+ // PEI_UHCI_IOBASE = 0x4000
+ gPeiUhciDev.IoBase[i] = PEI_UHCI_IOBASE + 0x40 * i;
+ Status = EnableUhciController( PeiServices, PciCfgPpi,
+ gPeiUhciDev.IoBase[i], (UINT8) i );
+ }
+
+ // Install USB Controller PPI
+ return (*PeiServices)->InstallPpi( PeiServices, PpiList );
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: EnableUhciController
+//
+// Description: This function enables the UHCI controller
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PciCfgPpi Pointer to the PCI Configuration PPI
+// BaseAddress I/O base Address to be programmed for the
+// UHCI controller
+// UsbControllerId USB Controller ID
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EnableUhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *PciCfgPpi,
+ IN UINTN BaseAddress,
+ IN UINT8 UsbControllerId )
+{
+ UINT16 CmdReg;
+
+
+ // Validate USB Controller ID
+ if (UsbControllerId >= MAX_USB_CTRLERS) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Assign base address register
+ PciCfgPpi->Write( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint32,
+ gUhciPciReg[UsbControllerId] |
+ PCI_REG_UHCI_BASE_ADDRESS_REGISTER, &BaseAddress );
+
+ // Enable UHCI PCI Command register
+ PciCfgPpi->Read( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint16,
+ gUhciPciReg[UsbControllerId] |
+ PCI_REG_UHCI_COMMAND_REGISTER, &CmdReg );
+
+ CmdReg = (UINT16) (CmdReg | 0x05);
+
+ PciCfgPpi->Write( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint16,
+ gUhciPciReg[UsbControllerId] |
+ PCI_REG_UHCI_COMMAND_REGISTER, &CmdReg );
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ClearEhciConfigFlagReg
+//
+// Description:
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PciCfgPpi Pointer to the PCI Configuration PPI
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+#ifdef PEI_EHCI_MEM_BASE_ADDRESSES
+VOID ClearEhciConfigFlagReg (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PCI_CFG_PPI *PciCfgPpi )
+{
+ UINT32 i;
+ UINT16 CmdReg;
+ UINT32 ConfigureFlagAddress;
+
+
+ for (i = 0; i < USB_EHCI; i++) {
+ // Assign Memory Base Address
+ PciCfgPpi->Write( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint32,
+ mEhciPciBDFs[i] |
+ PCI_REG_EHCI_MEMORY_BAR,
+ &mEhciMemBaseAddresses[i] );
+
+ // Set the Memory Space Enable and Bus Master Enable bits in the
+ // PCI Command register.
+ PciCfgPpi->Read( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint16,
+ mEhciPciBDFs[i] |
+ PCI_REG_UHCI_COMMAND_REGISTER, &CmdReg );
+
+ CmdReg = (UINT16) (CmdReg | 0x06);
+
+ PciCfgPpi->Write( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint16,
+ mEhciPciBDFs[i] |
+ PCI_REG_UHCI_COMMAND_REGISTER, &CmdReg );
+
+ //Clear Config Flag Register
+ ConfigureFlagAddress=mEhciMemBaseAddresses[i]+(UINT32)MMIO_READ8(mEhciMemBaseAddresses[i])+EHCI_HC_OPERATIONAL_CONFIG_FLAG_REG;
+ MMIO_WRITE32(ConfigureFlagAddress, 0);
+
+ // Clear the Memory Space Enable and Bus Master Enable bits in the
+ // PCI Command register.
+ PciCfgPpi->Read( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint16,
+ mEhciPciBDFs[i] |
+ PCI_REG_UHCI_COMMAND_REGISTER, &CmdReg );
+
+ CmdReg = (UINT16) ( CmdReg &= ~(0x6) );
+
+ PciCfgPpi->Write( PeiServices, PciCfgPpi, EfiPeiPciCfgWidthUint16,
+ mEhciPciBDFs[i] |
+ PCI_REG_UHCI_COMMAND_REGISTER, &CmdReg );
+ }
+}
+
+
+#endif
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetUhciController
+//
+// Description: This function returns controller type and I/O base address
+// value for the controller specified
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PciCfgPpi Pointer to the PCI Configuration PPI
+// UsbControllerId USB Controller ID
+//
+// Output: EFI_STATUS
+// *ControllerType Type of the USB controller
+// *IoBaseAddress I/O base Address programmed for this
+// controller
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS GetUhciController (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_USB_CONTROLLER_PPI *This,
+ IN UINT8 UsbControllerId,
+ OUT UINTN *ControllerType,
+ OUT UINTN *IoBaseAddress )
+{
+
+ if (UsbControllerId >= MAX_USB_CTRLERS) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *ControllerType = PEI_UHCI_CONTROLLER;
+ *IoBaseAddress = gPeiUhciDev.IoBase[UsbControllerId];
+
+ return EFI_SUCCESS;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.cif b/Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.cif
new file mode 100644
index 0000000..9dd2315
--- /dev/null
+++ b/Core/EM/UsbRecovery/UhciPeiUsb/UhciPeiUsb.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "UhciPeiUsb"
+ category = ModulePart
+ LocalRoot = "core\em\UsbRecovery\UhciPeiUsb\"
+ RefName = "UhciPeiUsb"
+[files]
+"UhciPeiUsb.c"
+[parts]
+"UHCI PPI"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c
new file mode 100644
index 0000000..7ebdb88
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.c
@@ -0,0 +1,482 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/BotPeim.c 7 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 7 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/BotPeim.c $
+//
+// 7 11/24/12 5:47a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 6 4/16/11 3:41a Ryanchou
+// [TAG] EIP50311
+// [Category] New Feature
+// [Description] Multiple LUN device support added.
+// [Files] BotPeim.c, UsbBotPeim.c, UsbBotPeim.h
+//
+// 5 2/18/11 2:13a Ryanchou
+// [TAG] EIP52191
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Recovery from card reader causes "EHCI Time-Out".
+// [RootCause] The card reader returns zero length during BOT data
+// transport, BIOS will do data transport again if the remain data length
+// isn't zero, then CSW will be received in data transport phase.
+// [Solution] Added the code that check if the transfered length is less
+// than expect length, break the loop.
+// [Files] BotPeim.c
+//
+// 4 4/06/10 3:27p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 3 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 2 8/17/07 4:12p Ambikas
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BotPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// Mass Storage BOT PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ BotPeim.c
+
+ Abstract:
+
+ BOT Transportation implementation
+
+ --*/
+
+#include "UsbBotPeim.h"
+#include "BotPeim.h"
+#include "PeiUsbLib.h"
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+extern VOID PeiCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length );
+
+
+STATIC
+EFI_STATUS BotRecoveryReset (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 Timeout;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINT8 EndpointAddr;
+ EFI_STATUS Status;
+
+ UsbIoPpi = PeiBotDev->UsbIoPpi;
+
+ if (UsbIoPpi == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ DevReq.RequestType = 0x21;
+ DevReq.Request = 0xff;
+ DevReq.Value = 0;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+
+ Status = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ //
+ // clear bulk in endpoint stall feature
+ //
+ EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
+ PeiUsbClearEndpointHalt( PeiServices, UsbIoPpi, EndpointAddr );
+
+ //
+ // clear bulk out endpoint stall feature
+ //
+ EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress;
+ PeiUsbClearEndpointHalt( PeiServices, UsbIoPpi, EndpointAddr );
+
+ return Status;
+}
+
+
+STATIC
+EFI_STATUS BotCommandPhase (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev,
+ IN VOID *Command,
+ IN UINT8 CommandSize,
+ IN UINT32 DataTransferLength,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT16 Timeout )
+{
+ CBW cbw;
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINTN DataSize;
+
+ UsbIoPpi = PeiBotDev->UsbIoPpi;
+
+ ZeroMem( &cbw, sizeof(CBW) );
+
+ //
+ // Fill the command block, detailed see BOT spec
+ //
+ cbw.dCBWSignature = CBWSIG;
+ cbw.dCBWTag = 0x01;
+ cbw.dCBWDataTransferLength = DataTransferLength;
+ cbw.bmCBWFlags = (Direction == EfiUsbDataIn)? 0x80 : 0;
+ cbw.bCBWLUN = PeiBotDev->Lun;
+ cbw.bCBWCBLength = CommandSize;
+
+ PeiCopyMem( cbw.CBWCB, Command, CommandSize );
+
+ DataSize = sizeof(CBW);
+
+ Status = UsbIoPpi->UsbBulkTransfer(
+ PeiServices,
+ UsbIoPpi,
+ (PeiBotDev->BulkOutEndpoint)->EndpointAddress,
+ (UINT8 *) &cbw,
+ &DataSize,
+ Timeout
+ );
+ if ( EFI_ERROR( Status ) ) {
+ //
+ // Command phase fail, we need to recovery reset this device
+ //
+ BotRecoveryReset( PeiServices, PeiBotDev );
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS BotDataPhase (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev,
+ IN UINT32 *DataSize,
+ IN OUT VOID *DataBuffer,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT16 Timeout )
+{
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINT8 EndpointAddr;
+ UINTN Remain;
+ UINTN Increment;
+ UINT32 MaxPacketLen;
+ UINT8 *BufferPtr;
+ UINTN TransferredSize;
+ UINTN TransferSize;
+
+ UsbIoPpi = PeiBotDev->UsbIoPpi;
+
+ Remain = *DataSize;
+ BufferPtr = (UINT8 *) DataBuffer;
+ TransferredSize = 0;
+
+ //
+ // retrieve the the max packet length of the given endpoint
+ //
+ if (Direction == EfiUsbDataIn) {
+ MaxPacketLen = (PeiBotDev->BulkInEndpoint)->MaxPacketSize;
+ EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
+ }
+ else {
+ MaxPacketLen = (PeiBotDev->BulkOutEndpoint)->MaxPacketSize;
+ EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress;
+ }
+
+ while (Remain > 0) {
+ //
+ // Using 15 packets to avoid Bitstuff error
+ //
+ if (Remain > 16 * MaxPacketLen) {
+ TransferSize = 16 * MaxPacketLen;
+ }
+ else {
+ TransferSize = Remain;
+ }
+
+ Increment = TransferSize;
+
+ Status = UsbIoPpi->UsbBulkTransfer(
+ PeiServices,
+ UsbIoPpi,
+ EndpointAddr,
+ BufferPtr,
+ &Increment,
+ Timeout
+ );
+
+ TransferredSize += Increment;
+
+ if ( EFI_ERROR( Status ) ) {
+ PeiUsbClearEndpointHalt( PeiServices, UsbIoPpi, EndpointAddr );
+ return Status;
+ }
+
+ if (Increment < TransferSize) {
+ break;
+ }
+
+ BufferPtr += Increment;
+ Remain -= Increment;
+ }
+
+ *DataSize = (UINT32) TransferredSize;
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS BotStatusPhase (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev,
+ OUT UINT8 *TransferStatus,
+ IN UINT16 Timeout )
+{
+ CSW csw;
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINT8 EndpointAddr;
+ UINTN DataSize;
+
+ //UINT32 Temp;
+
+ UsbIoPpi = PeiBotDev->UsbIoPpi;
+
+ ZeroMem( &csw, sizeof(CSW) );
+
+ EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
+
+ // DataSize = sizeof(CSW);
+ DataSize = 0x0d; //bala changed
+
+ //
+ // Get the status field from bulk transfer
+ //
+ Status = UsbIoPpi->UsbBulkTransfer(
+ PeiServices,
+ UsbIoPpi,
+ EndpointAddr,
+ &csw,
+ &DataSize,
+ Timeout
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ if (csw.dCSWSignature == CSWSIG)
+ {
+ *TransferStatus = csw.bCSWStatus;
+ }
+ else {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiAtapiCommand (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev,
+ IN VOID *Command,
+ IN UINT8 CommandSize,
+ IN VOID *DataBuffer,
+ IN UINT32 BufferLength,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT16 TimeOutInMilliSeconds )
+
+/*++
+
+ Routine Description:
+ Send ATAPI command using BOT protocol.
+
+ Arguments:
+ This - Protocol instance pointer.
+ Command - Command buffer
+ CommandSize - Size of Command Buffer
+ DataBuffer - Data buffer
+ BufferLength - Length of Data buffer
+ Direction - Data direction of this command
+ TimeoutInMilliseconds - Timeout value in ms
+
+ Returns:
+ EFI_SUCCES - Commond succeeded.
+ EFI_DEVICE_ERROR - Command failed.
+
+ --*/
+{
+ EFI_STATUS Status;
+ EFI_STATUS BotDataStatus = EFI_SUCCESS;
+ UINT8 TransferStatus;
+ UINT32 BufferSize;
+ UINT8 *Tmp;
+ UINT32 Temp;
+
+ Tmp = (UINT8 *) Command;
+ Temp = Tmp[0];
+ PEI_TRACE( (EFI_D_ERROR, PeiServices, "Executing ScsiCmd(%x)\n", Temp) );
+ //
+ // First send ATAPI command through Bot
+ //
+ Status = BotCommandPhase(
+ PeiServices,
+ PeiBotDev,
+ Command,
+ CommandSize,
+ BufferLength,
+ Direction,
+ TimeOutInMilliSeconds
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Send/Get Data if there is a Data Stage
+ //
+ switch (Direction)
+ {
+ case EfiUsbDataIn:
+ case EfiUsbDataOut:
+ BufferSize = BufferLength;
+
+ BotDataStatus = BotDataPhase(
+ PeiServices,
+ PeiBotDev,
+ &BufferSize,
+ DataBuffer,
+ Direction,
+ TimeOutInMilliSeconds
+ );
+
+ break;
+
+ case EfiUsbNoData:
+ break;
+ }
+
+ //
+ // Status Phase
+ //
+
+ Status = BotStatusPhase(
+ PeiServices,
+ PeiBotDev,
+ &TransferStatus,
+ TimeOutInMilliSeconds
+ );
+ if ( EFI_ERROR( Status ) ) {
+ BotRecoveryReset( PeiServices, PeiBotDev );
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (TransferStatus == 0x01) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return BotDataStatus;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h
new file mode 100644
index 0000000..25c3e56
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/BotPeim.h
@@ -0,0 +1,201 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/BotPeim.h 5 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 5 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/BotPeim.h $
+//
+// 5 11/24/12 5:47a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 4 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 3 4/16/07 12:46p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:40a Meenakshim
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BotPeim.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains a 'Sample Driver' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may be modified by the user, subject to
+// the additional terms of the license agreement
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ BotPeim.h
+
+ Abstract:
+
+ BOT Transportation implementation
+
+ --*/
+
+#ifndef _PEI_BOT_PEIM_H
+#define _PEI_BOT_PEIM_H
+
+#define STATIC static
+
+#include "Atapi.h"
+#include "AmiPeiLib.h"
+
+#pragma pack(1)
+
+//
+//Bulk Only device protocol
+//
+typedef struct
+{
+ UINT32 dCBWSignature;
+ UINT32 dCBWTag;
+ UINT32 dCBWDataTransferLength;
+ UINT8 bmCBWFlags;
+ UINT8 bCBWLUN;
+ UINT8 bCBWCBLength;
+ UINT8 CBWCB[16];
+} CBW;
+
+typedef struct
+{
+ UINT32 dCSWSignature;
+ UINT32 dCSWTag;
+ UINT32 dCSWDataResidue;
+ UINT8 bCSWStatus;
+ UINT8 Filler[18];
+} CSW;
+
+#pragma pack()
+
+//
+// Status code, see Usb Bot device spec
+//
+#define CSWSIG 0x53425355
+#define CBWSIG 0x43425355
+
+EFI_STATUS
+PeiUsbInquiry (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbTestUnitReady (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbRequestSense (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN UINT8 *SenseKeyBuffer );
+
+EFI_STATUS
+PeiUsbReadCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbReadFormattedCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice );
+
+EFI_STATUS
+PeiUsbRead10 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN VOID *Buffer,
+ IN EFI_PEI_LBA Lba,
+ IN UINTN NumberOfBlocks );
+
+BOOLEAN
+IsNoMedia (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts );
+
+BOOLEAN
+IsMediaError (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts );
+
+BOOLEAN
+IsMediaChange (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c b/Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c
new file mode 100644
index 0000000..24917af
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/PeiAtapi.c
@@ -0,0 +1,832 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/PeiAtapi.c 11 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 11 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/PeiAtapi.c $
+//
+// 11 11/24/12 5:47a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 10 10/24/11 5:59a Ryanchou
+// [TAG] EIP69936
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB ODD recovery fail
+// [RootCause] The device needs 4 sec to respond to Inquiry command, the
+// current timeout value is 2 sec
+// [Solution] Increase the timeout value to 4 sec.
+// [Files] PeiAtapi.c
+//
+// 9 8/18/10 4:19p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 8 4/06/10 3:27p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 7 10/21/08 5:58p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 6 7/29/08 5:51p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 5 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 4 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 3 8/17/07 4:35p Ambikas
+//
+// 2 10/02/06 7:24p Sivagarn
+// - Fixed the bug in identifying partition table entries
+// - Updated function headers and converted to AMI coding standard
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: PeiAtapi.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ PeiAtapi.c
+
+ Abstract:
+
+ Pei USB ATATPI command implementations
+
+ --*/
+
+#include "UsbBotPeim.h"
+#include "BotPeim.h"
+#include "Atapi.h"
+
+#define MAXSENSEKEY 5
+
+// External function declaration
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+// Function prototype
+
+VOID PeiUsbValidatePartitionTable (
+ EFI_PEI_SERVICES **PeiServices,
+ UINT8 *Buffer,
+ UINTN LastBlock,
+ UINT32 *FdEmulOffset );
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbInquiry
+//
+// Description: This function issues the ATA Inquiry command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbInquiry (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ ATAPI_PACKET_COMMAND Packet;
+ EFI_STATUS Status;
+ USB_INQUIRY_DATA Idata;
+
+ // Fill command packet
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ ZeroMem( &Idata, sizeof(USB_INQUIRY_DATA) );
+
+ Packet.Inquiry.opcode = INQUIRY;
+ Packet.Inquiry.page_code = 0;
+ Packet.Inquiry.allocation_length = sizeof(USB_INQUIRY_DATA);
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), &Idata,
+ sizeof(USB_INQUIRY_DATA), EfiUsbDataIn, 4000 ); //(EIP69936)
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if ( (Idata.peripheral_type & 0x1f) == 0x05 ) {
+ PeiBotDevice->DeviceType = USBCDROM;
+ PeiBotDevice->Media.BlockSize = 0x800;
+ }
+ else {
+ PeiBotDevice->DeviceType = USBFLOPPY;
+ PeiBotDevice->Media.BlockSize = 0x200;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbTestUnitReady
+//
+// Description: This function issues the ATA Test Unit Ready command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbTestUnitReady (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+
+ // Fill command packet
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ Packet.TestUnitReady.opcode = TEST_UNIT_READY;
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), NULL, 0, EfiUsbNoData,
+ 2000 );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbRequestSense
+//
+// Description: This function issues the ATA Request Sense command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+// *SenseCounts Buffer to return sense key data
+// *SenseKeyBuffer Buffer used for internal use
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbRequestSense (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN UINT8 *SenseKeyBuffer )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+
+ // Fill command packet for Request Sense Packet Command
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ Packet.RequestSence.opcode = REQUEST_SENSE;
+ Packet.RequestSence.allocation_length = sizeof(REQUEST_SENSE_DATA);
+
+
+ // Send out Request Sense Packet Command and get one Sense
+ // data form device.
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND),
+ (VOID *) SenseKeyBuffer,
+ sizeof(REQUEST_SENSE_DATA),
+ EfiUsbDataIn,
+ 2000 );
+
+ // Failed to get Sense data
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbReadCapacity
+//
+// Description: This function issues the ATA Read Capacity command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbReadCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+ READ_CAPACITY_DATA Data;
+ UINT8 Buffer[512];
+
+
+ ZeroMem( &Data, sizeof(READ_CAPACITY_DATA) );
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+
+ Packet.Inquiry.opcode = READ_CAPACITY;
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND),
+ (VOID *) &Data,
+ sizeof(READ_CAPACITY_DATA),
+ EfiUsbDataIn,
+ 2000 );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ PeiBotDevice->Media.LastBlock = (Data.LastLba3 << 24) |
+ (Data.LastLba2 << 16) |
+ (Data.LastLba1 << 8) |
+ Data.LastLba0;
+
+ // AMI Changes ->>
+ //This is the right place to set Medium BlockSize.
+ PeiBotDevice->Media.BlockSize = (Data.BlockSize3 << 24) |
+ (Data.BlockSize2 << 16) |
+ (Data.BlockSize1 << 8) |
+ Data.BlockSize0;
+ // <-- AMI Changes
+
+ PeiBotDevice->Media.MediaPresent = TRUE;
+
+ // BIOS Forced FDD option to emulate USB Key Hard Drive as Floppy
+ // Do Floppy emulation only for Harddrive/Direct Access Device
+ if (PeiBotDevice->DeviceType == USBFLOPPY) {
+ Status = PeiUsbRead10( PeiServices, PeiBotDevice, Buffer,
+ 0, /*StartLBA*/ 1 /*NumberOfBlocks*/ );
+ if ( EFI_ERROR( Status ) ) {
+ // Don't return error, as this shouldn't
+ // messup with ReadCapacity
+ return EFI_SUCCESS;
+ }
+ PeiUsbValidatePartitionTable( PeiServices, Buffer,
+ PeiBotDevice->Media.LastBlock, &(PeiBotDevice->FdEmulOffset) );
+ }
+ return EFI_SUCCESS;
+}
+
+
+// AMI Changes ->>
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbValidatePartitionTable
+//
+// Description: This function validates the existence of the partition table
+// from the LBA 0 data provided and return FdEmulOffset value
+// (hidden sector) from the partition table
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *Buffer Pointer to the buffer containing LBA 0
+// data
+// LastBlock Last LBA address
+//
+// *FdEmulOffset Returned FD emulation hidden sector value
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID PeiUsbValidatePartitionTable (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 *Buffer,
+ IN UINTN LastBlock,
+ OUT UINT32 *FdEmulOffset )
+{
+ UINT8 i;
+ UINT8 *pTable = Buffer + 0x1be; // Start offset of partition
+ // table
+ UINT8 *active_partition_addr = NULL;
+ UINT8 PartitionFound = 0; // Total number of valid
+ // partitions
+ UINT8 *PartitionTableEntries[4];
+
+ for (i = 0; i < 4; i++) {
+ PartitionTableEntries[i] = 0;
+
+ // Boot flag check added to ensure that boot sector will not be
+ // treated as a valid partation table.
+ if (*pTable & 0x7f) {
+ return; // BootFlag should be 0x0 or 0x80
+
+ }
+ // Check whether beginning LBA is reasonable
+ if (*(UINT32 *) (pTable + 8) > LastBlock) {
+ return;
+ }
+
+ // Check whether the size is reasonable
+
+ /** This check has to be refined
+ #if HDD_PART_SIZE_CHECK
+ if (*(UINT32*)(pTable + 0xc) > LastBlock)
+ return;
+ #endif
+ **/
+ PartitionFound++;
+ PartitionTableEntries[i] = pTable;
+ // Update active entry offset
+ if (*pTable & 0x80) {
+ active_partition_addr = pTable;
+ }
+
+ pTable += 0x10; //Get next Partition
+ }
+
+ if (PartitionFound == 0) {
+ return;
+ }
+
+ // If no active partition table entry found use first entry
+ if (active_partition_addr == NULL) {
+ for (i = 0; (i < 4) && !PartitionTableEntries[i]; i++) {
+ ;
+ }
+ if (i == 4) return;
+ active_partition_addr = PartitionTableEntries[i];
+ }
+
+ *FdEmulOffset = *( (UINT32 *) (active_partition_addr + 8) );
+ PEI_TRACE( (EFI_D_ERROR, PeiServices,
+ "USBPEIM: PeiUsbValidatePartitionTable() FdEmulOffset %x\n",
+ *FdEmulOffset) );
+}
+
+
+// <-- AMI Changes
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbReadFormattedCapacity
+//
+// Description: This function issues the ATA Read Formatted Capacity command
+// to the USB mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbReadFormattedCapacity (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice )
+{
+ EFI_STATUS Status;
+ ATAPI_PACKET_COMMAND Packet;
+ READ_FORMAT_CAPACITY_DATA FormatData;
+
+ ZeroMem( &FormatData, sizeof(READ_FORMAT_CAPACITY_DATA) );
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+
+ Packet.ReadFormatCapacity.opcode = READ_FORMAT_CAPACITY;
+ Packet.ReadFormatCapacity.allocation_length_lo = 12;
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), (VOID *) &FormatData,
+ sizeof(READ_FORMAT_CAPACITY_DATA), EfiUsbDataIn, 2000 );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (FormatData.DesCode == 3) {
+ // Media is not present
+ PeiBotDevice->Media.MediaPresent = FALSE;
+ PeiBotDevice->Media.LastBlock = 0;
+ }
+ else {
+ PeiBotDevice->Media.LastBlock = (FormatData.LastLba3 << 24) |
+ (FormatData.LastLba2 << 16) |
+ (FormatData.LastLba1 << 8) |
+ FormatData.LastLba0;
+
+ PeiBotDevice->Media.LastBlock--;
+ PeiBotDevice->Media.MediaPresent = TRUE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PeiUsbRead10
+//
+// Description: This function issues the ATA Read (10) command to the USB
+// mass storage device
+//
+// Input: **PeiServices Pointer to the PEI services table
+// *PeiBotDevice Pointer to the PEI_BOT_DEVICE structure
+// *Buffer Buffer to read the data into
+// Lba Start LBA Number
+// NumberOfBlocks Number of blocks to read
+//
+// Output: Return Status based on the command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiUsbRead10 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDevice,
+ IN VOID *Buffer,
+ IN EFI_PEI_LBA Lba,
+ IN UINTN NumberOfBlocks )
+{
+ VOID *ptrBuffer;
+ UINT16 MaxBlock;
+ UINT16 BlocksRemaining;
+ UINT16 SectorCount;
+ UINT16 TimeOut;
+ // UINT32 BufferSize;
+ UINT32 Lba32;
+ UINT32 BlockSize;
+ UINT32 ByteCount;
+ EFI_STATUS Status;
+ READ10_CMD *Read10Packet;
+ ATAPI_PACKET_COMMAND Packet;
+
+ // Prepare command packet for the Inquiry Packet Command.
+ ZeroMem( &Packet, sizeof(ATAPI_PACKET_COMMAND) );
+ Read10Packet = &Packet.Read10;
+ Lba32 = (UINT32) Lba;
+ ptrBuffer = Buffer;
+
+ BlockSize = (UINT32) PeiBotDevice->Media.BlockSize;
+ // AMI Changes -->
+ MaxBlock = (UINT16) (65536 / BlockSize);
+ // BufferSize = NumberOfBlocks * BlockSize;
+ // MaxBlock = (UINT16)(BufferSize /BlockSize);
+ // <-- AMI Changes
+ BlocksRemaining = (UINT16) NumberOfBlocks;
+
+ Status = EFI_SUCCESS;
+ while (BlocksRemaining > 0) {
+ if (BlocksRemaining <= MaxBlock) {
+ SectorCount = BlocksRemaining;
+ }
+ else {
+ SectorCount = MaxBlock;
+ }
+
+ // Fill the Packet data structure
+ Read10Packet->opcode = READ_10;
+
+ // Lba0 ~ Lba3 specify the start logical block
+ // address of the data transfer.
+ // Lba0 is MSB, Lba3 is LSB
+ Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
+ Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);
+ Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);
+ Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);
+
+ // TranLen0 ~ TranLen1 specify the transfer length in block unit.
+ // TranLen0 is MSB, TranLen is LSB
+ Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
+ Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);
+
+ ByteCount = SectorCount * BlockSize;
+
+ TimeOut = (UINT16) (SectorCount * 2000);
+
+ // Send command packet
+ Status = PeiAtapiCommand( PeiServices, PeiBotDevice, &Packet,
+ sizeof(ATAPI_PACKET_COMMAND), (VOID *) ptrBuffer, ByteCount,
+ EfiUsbDataIn, TimeOut );
+ if (Status != EFI_SUCCESS) {
+ return Status;
+ }
+
+ Lba32 += SectorCount;
+ ptrBuffer = (UINT8 *) ptrBuffer + SectorCount * BlockSize;
+ BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsNoMedia
+//
+// Description: This function verifies whether Media is present in the drive
+// or not by checking the Sense Data obtained from the drive
+//
+// Input: *SenseData Sense data obtained from the drive
+// SenseCounts Sense count value
+//
+// Output: Returns TRUE if media is present
+// FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsNoMedia (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts )
+{
+ UINTN i;
+ BOOLEAN NoMedia;
+ REQUEST_SENSE_DATA *SensePtr;
+
+ NoMedia = FALSE;
+ SensePtr = SenseData;
+
+ for (i = 0; i < SenseCounts; i++) {
+ switch (SensePtr->sense_key)
+ {
+ case SK_NOT_READY:
+ switch (SensePtr->addnl_sense_code)
+ {
+ // If no media, fill IdeDev parameter with specific info.
+ case ASC_NO_MEDIA:
+ NoMedia = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ SensePtr++;
+ }
+
+ return NoMedia;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMediaError
+//
+// Description: This function verifies whether Media access is having problem
+// or not by checking the Sense Data obtained from the drive
+//
+// Input: *SenseData Sense data obtained from the drive
+// SenseCounts Sense count value
+//
+// Output: Returns TRUE if media has error
+// FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsMediaError (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts )
+{
+ UINTN i;
+ BOOLEAN Error;
+ REQUEST_SENSE_DATA *SensePtr;
+
+ SensePtr = SenseData;
+ Error = FALSE;
+
+ for (i = 0; i < SenseCounts; i++) {
+ switch (SensePtr->sense_key)
+ {
+ // Medium error case
+ case SK_MEDIUM_ERROR:
+ switch (SensePtr->addnl_sense_code)
+ {
+ case ASC_MEDIA_ERR1: // fall through
+ case ASC_MEDIA_ERR2: // fall through
+ case ASC_MEDIA_ERR3: // fall through
+ case ASC_MEDIA_ERR4:
+ Error = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ // Medium upside-down case
+ case SK_NOT_READY:
+ switch (SensePtr->addnl_sense_code)
+ {
+ case ASC_MEDIA_UPSIDE_DOWN:
+ Error = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ SensePtr++;
+ }
+
+ return Error;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: IsMediaChange
+//
+// Description: This function verifies whether Media change had happened
+// or not by checking the Sense Data obtained from the drive
+//
+// Input: *SenseData Sense data obtained from the drive
+// SenseCounts Sense count value
+//
+// Output: Returns TRUE if media has changed
+// FALSE otherwise
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN IsMediaChange (
+ IN REQUEST_SENSE_DATA *SenseData,
+ IN UINTN SenseCounts )
+{
+ UINTN i;
+ BOOLEAN MediaChange;
+ REQUEST_SENSE_DATA *SensePtr;
+
+ MediaChange = FALSE;
+ SensePtr = SenseData;
+ for (i = 0; i < SenseCounts; i++) {
+ // Catch media change sense key and addition sense data
+ switch (SensePtr->sense_key)
+ {
+ case SK_UNIT_ATTENTION:
+ switch (SensePtr->addnl_sense_code)
+ {
+ case ASC_MEDIA_CHANGE:
+ MediaChange = TRUE;
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ default:
+ break;
+ }
+ SensePtr++;
+ }
+
+ return MediaChange;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c
new file mode 100644
index 0000000..6a0ce90
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.c
@@ -0,0 +1,726 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.c 13 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 13 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.c $
+//
+// 13 11/24/12 5:47a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 12 4/16/11 3:42a Ryanchou
+// [TAG] EIP50311
+// [Category] New Feature
+// [Description] Multiple LUN device support added.
+// [Files] BotPeim.c, UsbBotPeim.c, UsbBotPeim.h
+//
+// 11 10/12/10 11:20a Olegi
+// XHCI support added.
+//
+// 10 2/23/10 3:36p Olegi
+// Bugfixes found by Coverity tests: EIP34507.
+//
+// 9 3/03/09 7:22p Olegi
+// Added EHCI support.
+//
+// 8 10/21/08 5:58p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 7 7/29/08 5:51p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 6 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 5 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 4 10/23/07 5:42p Ambikas
+//
+// 3 8/17/07 4:35p Ambikas
+//
+// 2 8/17/07 4:11p Ambikas
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbbotPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbBotPeim.c
+
+ Abstract:
+
+ Usb Bus PPI
+
+ --*/
+
+#include "UsbBotPeim.h"
+#include "BotPeim.h"
+#define PAGESIZE 4096
+#include EFI_PPI_DEFINITION( Stall )
+#include EFI_PPI_DEFINITION( LoadFile )
+
+static EFI_GUID gPeiStallPpiGuid = PEI_STALL_PPI_GUID;
+static EFI_GUID gPeiBlockIoPpiGuid = EFI_PEI_VIRTUAL_BLOCK_IO_PPI;
+static EFI_GUID gPeiUsbIoPpiGuid = PEI_USB_IO_PPI_GUID;
+
+//
+// Global function
+//
+STATIC
+EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+ EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH |
+ EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiUsbIoPpiGuid,
+ NotifyOnUsbIoPpi
+};
+
+STATIC
+EFI_PEI_RECOVERY_BLOCK_IO_PPI mRecoveryBlkIoPpi = {
+ BotGetNumberOfBlockDevices,
+ BotGetMediaInfo,
+ BotReadBlocks
+};
+
+STATIC
+EFI_PEI_PPI_DESCRIPTOR mPpiList = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gPeiBlockIoPpiGuid,
+ NULL
+};
+
+//
+// Driver Entry Point
+//
+EFI_STATUS
+PeimInitializeUsbBot (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+STATIC
+EFI_STATUS
+PeiBotDetectMedia (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev );
+
+EFI_STATUS PeimInitializeUsbBot (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ UINTN UsbIoPpiInstance;
+ EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINTN PpiInstance;
+
+ for (PpiInstance = 0; PpiInstance < PEI_MAX_USB_RECOVERY_INIT_PPI; PpiInstance++)
+ {
+ PEI_USB_CHIP_INIT_PPI *UsbChipsetRecoveryInitPpi;
+ static EFI_GUID gPeiChipUsbRecoveryInitPpiGuid = PEI_USB_CHIP_INIT_PPI_GUID;
+
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiChipUsbRecoveryInitPpiGuid,
+ PpiInstance, NULL, &UsbChipsetRecoveryInitPpi );
+ if (EFI_ERROR( Status ) ) break;
+
+ UsbChipsetRecoveryInitPpi->EnableChipUsbRecovery(PeiServices);
+ }
+
+ #if (PEI_EHCI_SUPPORT == 1)
+ EhciPeiUsbEntryPoint( FfsHeader, PeiServices );
+ #endif
+ #if (PEI_UHCI_SUPPORT == 1)
+ UhciPeiUsbEntryPoint( FfsHeader, PeiServices );
+ UhcPeimEntry( FfsHeader, PeiServices );
+ #endif
+ #if (PEI_OHCI_SUPPORT == 1)
+ OhciPeiUsbEntryPoint( FfsHeader, PeiServices ); // 0xff02
+ #endif
+ #if (PEI_XHCI_SUPPORT == 1)
+ XhciPeiUsbEntryPoint( FfsHeader, PeiServices ); // 0xff02
+ #endif
+ PeimInitializeUsb( FfsHeader, PeiServices ); // 0xff05
+
+
+ //
+ // locate all usb io PPIs
+ //
+ for (UsbIoPpiInstance = 0;
+ UsbIoPpiInstance < PEI_FAT_MAX_USB_IO_PPI;
+ UsbIoPpiInstance++)
+ {
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiUsbIoPpiGuid,
+ UsbIoPpiInstance,
+ &TempPpiDescriptor,
+ &UsbIoPpi
+ );
+ if ( EFI_ERROR( Status ) ) {
+ break;
+ }
+
+ InitUsbBot( PeiServices, UsbIoPpi );
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS NotifyOnUsbIoPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi )
+{
+ PEI_USB_IO_PPI *UsbIoPpi;
+
+ UsbIoPpi = (PEI_USB_IO_PPI *) InvokePpi;
+
+ InitUsbBot( PeiServices, UsbIoPpi );
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS GetMaxLun (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ OUT UINT8 *MaxLun )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = 0xA1;
+ DevReq.Request = 0x0FE;
+ DevReq.Value = 0;
+ DevReq.Index = Port;
+ DevReq.Length = sizeof(UINT8);
+
+ Timeout = 3000;
+
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ UsbDataIn,
+ Timeout,
+ MaxLun,
+ sizeof(UINT8)
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS InitUsbBot (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi )
+{
+ STATIC UINTN UsbIoPpiIndex = 0;
+
+ PEI_BOT_DEVICE *PeiBotDevice;
+ EFI_STATUS Status;
+ EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDesc;
+ UINT8 *AllocateAddress;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc;
+ UINT8 i;
+ UINT8 MaxLun = 0;
+ UINT8 CurrentLun;
+
+ //
+ // Check its interface
+ //
+ Status = UsbIoPpi->UsbGetInterfaceDescriptor( PeiServices,
+ UsbIoPpi, &InterfaceDesc );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //
+ // Check if it is the BOT device we support
+ //
+
+ if ( (InterfaceDesc->InterfaceClass != BASE_CLASS_MASS_STORAGE)
+ || (InterfaceDesc->InterfaceProtocol != PROTOCOL_BOT) ) {
+
+ return EFI_NOT_FOUND;
+ }
+
+ Status = GetMaxLun(PeiServices,UsbIoPpi,InterfaceDesc->InterfaceNumber,&MaxLun);
+
+ for(CurrentLun = 0; CurrentLun <= MaxLun; CurrentLun++) {
+
+ Status = (*PeiServices)->AllocatePool( PeiServices,
+ sizeof(PEI_BOT_DEVICE), &AllocateAddress );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ PeiBotDevice = (PEI_BOT_DEVICE *) ( (UINTN) AllocateAddress );
+ (**PeiServices).SetMem(PeiBotDevice, sizeof(PEI_BOT_DEVICE), 0);
+
+ PeiBotDevice->Signature = PEI_BOT_DEVICE_SIGNATURE;
+ PeiBotDevice->UsbIoPpi = UsbIoPpi;
+ PeiBotDevice->BotInterface = InterfaceDesc;
+ PeiBotDevice->FdEmulOffset = 0; //bala
+ //
+ // Default value
+ //
+ PeiBotDevice->Media.DeviceType = UsbMassStorage;
+ PeiBotDevice->Media.BlockSize = 0x200;
+ PeiBotDevice->Lun = CurrentLun;
+
+ //
+ // Check its Bulk-in/Bulk-out endpoint
+ //
+ for (i = 0; i < 2; i++) {
+ Status = UsbIoPpi->UsbGetEndpointDescriptor( PeiServices,
+ UsbIoPpi, i, &EndpointDesc );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ if (EndpointDesc->Attributes != 2) {
+ continue;
+ }
+
+ if ( (EndpointDesc->EndpointAddress & 0x80) != 0 ) {
+ PeiBotDevice->BulkInEndpoint = EndpointDesc;
+ }
+ else {
+ PeiBotDevice->BulkOutEndpoint = EndpointDesc;
+ }
+
+ }
+
+ PeiBotDevice->BlkIoPpi = mRecoveryBlkIoPpi;
+ PeiBotDevice->BlkIoPpiList = mPpiList;
+ PeiBotDevice->BlkIoPpiList.Ppi = &PeiBotDevice->BlkIoPpi;
+
+ Status = PeiUsbInquiry( PeiServices, PeiBotDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ Status = (**PeiServices).InstallPpi( PeiServices,
+ &PeiBotDevice->BlkIoPpiList );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS BotGetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices )
+{
+ //
+ // For Usb devices, this value should be always 1
+ //
+
+ *NumberBlockDevices = 1;
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS BotGetMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo )
+{
+ PEI_BOT_DEVICE *PeiBotDev;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ PeiBotDev = PEI_BOT_DEVICE_FROM_THIS( This );
+
+ Status = PeiBotDetectMedia(
+ PeiServices,
+ PeiBotDev
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ *MediaInfo = PeiBotDev->Media;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiBotDetectMedia (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev )
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *AllocateAddress;
+ REQUEST_SENSE_DATA *SensePtr;
+ UINT8 SenseKey, ASC, ASCQ;
+ UINT8 RetryCount, RetryReq = 0;
+ PEI_STALL_PPI *StallPpi;
+ UINT32 Temp;
+ UINT32 Temp1, Temp2, Temp3;
+
+ //PeiUsbReadCapacity fills PeiBotDev structure for
+ //BlockSize, LastBlock, Media Present
+ for (RetryCount = 0; RetryCount < 25; RetryCount++)
+ {
+ Status = PeiUsbReadCapacity(
+ PeiServices,
+ PeiBotDev
+ );
+
+ if ( EFI_ERROR( Status ) )
+ {
+ Temp = RetryCount;
+
+ //If ReadCapcity fails, then find out type of error
+ if (RetryCount == 0)
+ {
+ if (PeiBotDev->SensePtr == NULL) {
+ //During the first retry allocate the memory
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof(REQUEST_SENSE_DATA),
+ &AllocateAddress
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ return Status;
+ }
+ PeiBotDev->SensePtr = (REQUEST_SENSE_DATA *)AllocateAddress;
+ }
+ SensePtr = PeiBotDev->SensePtr;
+ (**PeiServices).SetMem((VOID*)SensePtr, sizeof(REQUEST_SENSE_DATA), 0);
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiStallPpiGuid, 0, NULL, &StallPpi );
+ }
+
+ Status = PeiUsbRequestSense(
+ PeiServices,
+ PeiBotDev,
+ (UINT8 *) SensePtr
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ //If RequestSense also fails, then there is an serious error
+ //Return to the caller with appropriate error code
+ // PeiBotDev->Media.MediaPresent = FALSE;
+ // PeiBotDev->Media.BlockSize = 0;
+ // Status = EFI_DEVICE_ERROR;
+ // return EFI_DEVICE_ERROR;
+ }
+ //TODO:Parse the sense buffer for the error
+ //If media getting ready, then wait for few mSec, then
+ //retry ReadCapacity
+ //For all other errors, return with error condition
+
+ SenseKey = SensePtr->sense_key;
+ ASC = SensePtr->addnl_sense_code;
+ ASCQ = SensePtr->addnl_sense_code_qualifier;
+ Temp1 = SenseKey;
+ Temp2 = ASC;
+ Temp3 = ASCQ;
+
+ if ( (SenseKey == 0x02) && (ASC == 0x3a) && (ASCQ == 00) )
+ {
+ //medium Not Present.
+ //Don't retry.
+ return EFI_DEVICE_ERROR;
+
+ }
+ // The following retry logic is broken, assigning RetryReq 1 does
+ // not make sense and leads to a dead code later: "if (!RetryReq)"
+ // Remove this assignment. EIP34507
+ //For all error retry ReadCapacity 25 times
+ //RetryReq = 1; //Do retry
+ if (SenseKey == 0x02)
+ {
+ //Logical Unit Problem
+ if (ASC == 0x04)
+ {
+ //Becoming Ready/Init Required/ Busy/ Format in Progress.
+ RetryReq = 1; //Do retry
+
+ }
+ if ( (ASC == 0x06) || (ASC == 0x08) )
+ {
+ //No ref. found/ Comm failure
+ RetryReq = 1; //Do retry
+ }
+ }
+
+
+ PeiBotDev->Media.MediaPresent = FALSE;
+ PeiBotDev->Media.BlockSize = 0;
+ Status = EFI_DEVICE_ERROR;
+ if (!RetryReq) {
+ return Status;
+ }
+ }
+ else {
+ Status = EFI_SUCCESS;
+ return Status; //Command Passed so return to caller
+ }
+
+ //Wait for 100 msec
+ StallPpi->Stall( PeiServices, StallPpi, 100 * 1000 );
+ }
+ return Status;
+}
+
+
+EFI_STATUS BotReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer )
+{
+ PEI_BOT_DEVICE *PeiBotDev;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINTN BlockSize;
+ UINTN NumberOfBlocks;
+ UINT8 *AllocateAddress;
+ REQUEST_SENSE_DATA *SensePtr;
+ UINT8 SenseKey, ASC, ASCQ;
+ UINT8 RetryCount;
+ PEI_STALL_PPI *StallPpi;
+ UINT32 Temp1, Temp2, Temp3;
+
+ PeiBotDev = PEI_BOT_DEVICE_FROM_THIS( This );
+
+ Temp1 = (UINT32) StartLBA;
+
+ StartLBA += PeiBotDev->FdEmulOffset;
+
+ //
+ // Check parameters
+ //
+ if (Buffer == NULL)
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize == 0)
+ {
+ return EFI_SUCCESS;
+ }
+
+ BlockSize = PeiBotDev->Media.BlockSize;
+
+ if (BufferSize % BlockSize != 0)
+ {
+ Status = EFI_BAD_BUFFER_SIZE;
+ }
+
+ if (!PeiBotDev->Media.MediaPresent)
+ {
+ return EFI_NO_MEDIA;
+ }
+
+ if (StartLBA > PeiBotDev->Media.LastBlock)
+ {
+ Status = EFI_INVALID_PARAMETER;
+ }
+
+ NumberOfBlocks = BufferSize / (PeiBotDev->Media.BlockSize);
+
+ for (RetryCount = 0; RetryCount < 3; RetryCount++)
+ {
+ Status = PeiUsbRead10(
+ PeiServices,
+ PeiBotDev,
+ Buffer,
+ StartLBA,
+ NumberOfBlocks
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+
+ if (RetryCount == 0)
+ {
+ if (PeiBotDev->SensePtr == NULL) {
+ Status = (**PeiServices).AllocatePool(
+ PeiServices,
+ sizeof(REQUEST_SENSE_DATA),
+ &AllocateAddress
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ return Status;
+ }
+ PeiBotDev->SensePtr = (REQUEST_SENSE_DATA *) AllocateAddress;
+ }
+ SensePtr = PeiBotDev->SensePtr;
+ (**PeiServices).SetMem((VOID*)SensePtr, sizeof(REQUEST_SENSE_DATA), 0);
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiStallPpiGuid, 0, NULL, &StallPpi );
+ }
+
+ Status = PeiUsbRequestSense(
+ PeiServices,
+ PeiBotDev,
+ (UINT8 *) SensePtr
+ );
+ if ( EFI_ERROR( Status ) )
+ {
+ //If RequestSense also fails, then there is an serious error
+ //Return to the caller with appropriate error code
+ return EFI_DEVICE_ERROR;
+ }
+ //TODO:Parse the sense buffer for the error
+ //If media getting ready, then wait for few mSec, then
+ //retry ReadCapacity
+ //For all other errors, return with error condition
+
+ SenseKey = SensePtr->sense_key;
+ ASC = SensePtr->addnl_sense_code;
+ ASCQ = SensePtr->addnl_sense_code_qualifier;
+ Temp1 = SenseKey;
+ Temp2 = ASC;
+ Temp3 = ASCQ;
+ StallPpi->Stall( PeiServices, StallPpi, 9000 );
+
+ }
+ break; //break the for loop
+ }
+ return EFI_SUCCESS;
+
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif
new file mode 100644
index 0000000..ec62a8d
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "UsbBotPeimSrc"
+ category = ModulePart
+ LocalRoot = "Core\em\UsbRecovery\UsbBotPeimSrc"
+ RefName = "UsbBotPeimSrc"
+[files]
+"UsbBotPeim.dxs" = "dxs"
+"BotPeim.c"
+"BotPeim.h"
+"PeiAtapi.c"
+"UsbBotPeim.c"
+"UsbBotPeim.h"
+"atapi.h"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs
new file mode 100644
index 0000000..baa6bb6
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.dxs
@@ -0,0 +1,106 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.dxs 4 7/10/08 6:38p Michaela $
+//
+// $Revision: 4 $
+//
+// $Date: 7/10/08 6:38p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.dxs $
+//
+// 4 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 3 10/23/07 5:41p Ambikas
+//
+// 2 8/17/07 4:12p Ambikas
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbBotPeim.DXS
+//
+// Description: This file is the dependency file for the USB BOT protocol PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains a 'Sample Driver' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may be modified by the user, subject to
+ the additional terms of the license agreement
+--*/
+/*++
+
+Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+This software and associated documentation (if any) is furnished
+under a license and may only be used or copied in accordance
+with the terms of the license. Except as permitted by such
+license, no part of this software or documentation may be
+reproduced, stored in a retrieval system, or transmitted in any
+form or by any means without the express written consent of
+Intel Corporation.
+
+
+Module Name:
+
+ UsbBotPeim.dxs
+
+Abstract:
+
+ Dependency expression file for Usb Bot PEIM.
+ PEI_USB_IO_PPI_GUID AND
+--*/
+
+#include "pei.h"
+#include "ppi\LoadFile.h"
+#include "ppi\UsbIo.h"
+
+DEPENDENCY_START
+ EFI_PEI_FV_FILE_LOADER_GUID AND
+ EFI_PEI_BOOT_IN_RECOVERY_MODE_PEIM_PPI AND
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+DEPENDENCY_END
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h
new file mode 100644
index 0000000..92a8668
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/UsbBotPeim.h
@@ -0,0 +1,362 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.h 12 11/24/12 5:47a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 11/24/12 5:47a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/UsbBotPeim.h $
+//
+// 12 11/24/12 5:47a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 11 4/16/11 3:42a Ryanchou
+// [TAG] EIP50311
+// [Category] New Feature
+// [Description] Multiple LUN device support added.
+// [Files] BotPeim.c, UsbBotPeim.c, UsbBotPeim.h
+//
+// 10 10/12/10 11:20a Olegi
+// XHCI support added.
+//
+// 9 3/03/09 7:23p Olegi
+// Added EHCI support.
+//
+// 8 10/21/08 5:58p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 7 7/29/08 5:51p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 6 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 5 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 4 8/17/07 4:11p Ambikas
+//
+// 3 4/16/07 12:49p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:52a Meenakshim
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbBotPeim.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+//
+// This file contains a 'Sample Driver' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may be modified by the user, subject to
+// the additional terms of the license agreement
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbBotPeim.h
+
+ Abstract:
+
+ Usb BOT Peim definition
+
+ --*/
+
+#ifndef _PEI_USB_BOT_PEIM_H
+#define _PEI_USB_BOT_PEIM_H
+
+#include "Efi.h"
+#include "Pei.h"
+// #include "PeiLib.h"
+#include "usb.h"
+#include "Atapi.h"
+#include "AmiMapping.h"
+
+//
+// Driver consumed PPI Prototypes
+//
+#include "Include\Ppi\UsbIo.h"
+
+//
+// Driver produces PPI Prototypes
+//
+#include "Include\Ppi\DeviceRecoveryBlockIo.h"
+#include <Token.h>
+
+#define PEI_FAT_MAX_USB_IO_PPI 127
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.BaseClass
+//---------------------------------------------------------------------------
+#define BASE_CLASS_HID 0x03
+#define BASE_CLASS_MASS_STORAGE 0x08
+#define BASE_CLASS_HUB 0x09
+//----------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.Protocol
+//---------------------------------------------------------------------------
+#define PROTOCOL_KEYBOARD 0x01 // Keyboard device protocol
+#define PROTOCOL_MOUSE 0x02 // Mouse device protocol?
+
+// Mass storage related protocol equates
+#define PROTOCOL_CBI 0x00 // Mass Storage Control/Bulk/Interrupt
+ // with command completion interrupt
+#define PROTOCOL_CBI_NO_INT 0x01 // MASS STORAGE Control/Bulk/Interrupt
+ // with NO command completion interrupt
+#define PROTOCOL_BOT 0x50 // Mass Storage Bulk-Only Transport
+#define PROTOCOL_VENDOR 0xff // Vendor specific mass protocol
+//---------------------------------------------------------------------------
+
+//
+// BlockIo PPI prototype
+//
+EFI_STATUS
+BotGetNumberOfBlockDevices (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ OUT UINTN *NumberBlockDevices );
+
+EFI_STATUS
+BotGetMediaInfo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo );
+
+EFI_STATUS
+BotReadBlocks (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
+ IN UINTN DeviceIndex,
+ IN EFI_PEI_LBA StartLBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer );
+
+//
+// UsbIo PPI Notification
+//
+EFI_STATUS
+NotifyOnUsbIoPpi (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
+ IN VOID *InvokePpi );
+
+EFI_STATUS
+InitUsbBot (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi );
+
+#define USBFLOPPY 1
+#define USBFLOPPY2 2 // for those that use ReadCapacity(0x25)
+ // command to retrieve media capacity
+#define USBCDROM 3
+//
+// Bot device structure
+//
+#define PEI_BOT_DEVICE_SIGNATURE EFI_SIGNATURE_32( 'U', 'B', 'O', 'T' )
+typedef struct
+{
+ UINTN Signature;
+ EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi;
+ EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;
+ EFI_PEI_BLOCK_IO_MEDIA Media;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ EFI_USB_INTERFACE_DESCRIPTOR *BotInterface;
+ EFI_USB_ENDPOINT_DESCRIPTOR *BulkInEndpoint;
+ EFI_USB_ENDPOINT_DESCRIPTOR *BulkOutEndpoint;
+ UINTN DeviceType;
+ REQUEST_SENSE_DATA *SensePtr;
+ UINT32 FdEmulOffset;
+ UINT8 Lun;
+} PEI_BOT_DEVICE;
+
+#define PEI_BOT_DEVICE_FROM_THIS( a ) \
+ PEI_CR( a, PEI_BOT_DEVICE, BlkIoPpi, PEI_BOT_DEVICE_SIGNATURE )
+
+//
+// USB ATATPI command
+//
+EFI_STATUS
+PeiAtapiCommand (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_BOT_DEVICE *PeiBotDev,
+ IN VOID *Command,
+ IN UINT8 CommandSize,
+ IN VOID *DataBuffer,
+ IN UINT32 BufferLength,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT16 TimeOutInMilliSeconds );
+
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+#define ONE_SECOND_DELAY 1000000 // 1 second = 1000000 microseconds
+
+// Controller-specific externs
+#if (PEI_UHCI_SUPPORT == 1)
+EFI_STATUS UhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+extern EFI_STATUS UhcPeimEntry (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+#if (PEI_OHCI_SUPPORT == 1)
+EFI_STATUS OhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+#if (PEI_EHCI_SUPPORT == 1)
+EFI_STATUS EhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+#if (PEI_XHCI_SUPPORT == 1)
+EFI_STATUS XhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+#endif
+
+extern EFI_STATUS PeimInitializeUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+#define PEI_MAX_USB_RECOVERY_INIT_PPI 16
+
+// The following section should eventually go to SBPPI.H.
+#ifndef PEI_USB_CHIP_INIT_PPI_GUID
+#define PEI_USB_CHIP_INIT_PPI_GUID \
+ { 0xdb75358d, 0xfef0, 0x4471, 0xa8, 0xd, 0x2e, 0xeb, 0x13, 0x8, 0x2d, 0x2d }
+
+typedef EFI_STATUS (EFIAPI *PEI_ENABLE_CHIP_USB_RECOVERY) (
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+
+typedef struct _PEI_USB_CHIP_INIT_PPI PEI_USB_CHIP_INIT_PPI;
+
+typedef struct _PEI_USB_CHIP_INIT_PPI {
+ PEI_ENABLE_CHIP_USB_RECOVERY EnableChipUsbRecovery;
+} PEI_USB_CHIP_INIT_PPI;
+#endif
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h b/Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h
new file mode 100644
index 0000000..2d6d376
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbBotPeimSrc/atapi.h
@@ -0,0 +1,418 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/atapi.h 2 7/10/08 6:38p Michaela $
+//
+// $Revision: 2 $
+//
+// $Date: 7/10/08 6:38p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbBotPeimSrc/atapi.h $
+//
+// 2 7/10/08 6:38p Michaela
+// Updated to support OHCI controllers
+//
+// 1 9/22/06 12:17p Sivagarn
+// - Included Recovery code in Source
+//
+// 1 9/22/06 12:14p Sivagarn
+// - Initial checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Atapi.h
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains 'Framework Code' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may not be modified, except as allowed by
+// additional terms of your license agreement.
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ Atapi.h
+
+ Abstract:
+
+
+ Revision History
+ --*/
+
+#ifndef _PEI_RECOVERY_ATAPI_H
+#define _PEI_RECOVERY_ATAPI_H
+
+#include "Efi.h"
+
+#pragma pack(1)
+
+typedef struct
+{
+ UINT16 config; // General Configuration
+ UINT16 cylinders; // Number of Cylinders
+ UINT16 reserved_2;
+ UINT16 heads; // Number of logical heads
+ UINT16 vendor_data1;
+ UINT16 vendoe_data2;
+ UINT16 sectors_per_track;
+ UINT16 vendor_specific_7_9[3];
+ CHAR8 SerialNo[20]; // ASCII
+ UINT16 vendor_specific_20_21[2];
+ UINT16 ecc_bytes_available;
+ CHAR8 FirmwareVer[8]; // ASCII
+ CHAR8 ModelName[40]; // ASCII
+ UINT16 multi_sector_cmd_max_sct_cnt;
+ UINT16 reserved_48;
+ UINT16 capabilities;
+ UINT16 reserved_50;
+ UINT16 pio_cycle_timing;
+ UINT16 reserved_52;
+ UINT16 field_validity;
+ UINT16 current_cylinders;
+ UINT16 current_heads;
+ UINT16 current_sectors;
+ UINT16 CurrentCapacityLsb;
+ UINT16 CurrentCapacityMsb;
+ UINT16 reserved_59;
+ UINT16 user_addressable_sectors_lo;
+ UINT16 user_addressable_sectors_hi;
+ UINT16 reserved_62;
+ UINT16 multi_word_dma_mode;
+ UINT16 advanced_pio_modes;
+ UINT16 min_multi_word_dma_cycle_time;
+ UINT16 rec_multi_word_dma_cycle_time;
+ UINT16 min_pio_cycle_time_without_flow_control;
+ UINT16 min_pio_cycle_time_with_flow_control;
+ UINT16 reserved_69_79[11];
+ UINT16 major_version_no;
+ UINT16 minor_version_no;
+ UINT16 reserved_82_127[46];
+ UINT16 security_status;
+ UINT16 vendor_data_129_159[31];
+ UINT16 reserved_160_255[96];
+} IDENTIFY;
+
+typedef struct
+{
+ UINT8 peripheral_type;
+ UINT8 RMB;
+ UINT8 version;
+ UINT8 response_data_format;
+ UINT8 addnl_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 vendor_info[8];
+ UINT8 product_id[12];
+ UINT8 eeprom_product_code[4];
+ UINT8 firmware_rev_level[4];
+ UINT8 firmware_sub_rev_level[1];
+ UINT8 reserved_37;
+ UINT8 reserved_38;
+ UINT8 reserved_39;
+ UINT8 max_capacity_hi;
+ UINT8 max_capacity_mid;
+ UINT8 max_capacity_lo;
+ UINT8 reserved_43_95[95 - 43 + 1];
+ UINT8 vendor_id[20];
+ UINT8 eeprom_drive_sno[12];
+} INQUIRY_DATA;
+
+typedef struct
+{
+ UINT8 error_code : 7;
+ UINT8 valid : 1;
+ UINT8 reserved_1;
+ UINT8 sense_key : 4;
+ UINT8 reserved_21 : 1;
+ UINT8 ILI : 1;
+ UINT8 reserved_22 : 2;
+ UINT8 vendor_specific_3;
+ UINT8 vendor_specific_4;
+ UINT8 vendor_specific_5;
+ UINT8 vendor_specific_6;
+ UINT8 addnl_sense_length; // n - 7
+ UINT8 vendor_specific_8;
+ UINT8 vendor_specific_9;
+ UINT8 vendor_specific_10;
+ UINT8 vendor_specific_11;
+ UINT8 addnl_sense_code; // mandatory
+ UINT8 addnl_sense_code_qualifier; // mandatory
+ UINT8 field_replaceable_unit_code; // optional
+ UINT8 reserved_15;
+ UINT8 reserved_16;
+ UINT8 reserved_17;
+ // Followed by additional sense bytes : FIXME
+} REQUEST_SENSE_DATA;
+
+typedef struct
+{
+ UINT8 LastLba3;
+ UINT8 LastLba2;
+ UINT8 LastLba1;
+ UINT8 LastLba0;
+ UINT8 BlockSize3;
+ UINT8 BlockSize2;
+ UINT8 BlockSize1;
+ UINT8 BlockSize0;
+} READ_CAPACITY_DATA;
+
+typedef struct
+{
+ UINT8 reserved_0;
+ UINT8 reserved_1;
+ UINT8 reserved_2;
+ UINT8 Capacity_Length;
+ UINT8 LastLba3;
+ UINT8 LastLba2;
+ UINT8 LastLba1;
+ UINT8 LastLba0;
+ UINT8 DesCode : 2;
+ UINT8 reserved_9 : 6;
+ UINT8 BlockSize2;
+ UINT8 BlockSize1;
+ UINT8 BlockSize0;
+} READ_FORMAT_CAPACITY_DATA;
+
+#pragma pack()
+
+//
+// ATAPI Command
+//
+#define ATAPI_SOFT_RESET_CMD 0x08
+#define PACKET_CMD 0xa0
+#define ATAPI_IDENTIFY_DEVICE_CMD 0xa1
+#define ATAPI_SERVICE_CMD 0xa2
+
+//
+// ATAPI Packet Command
+//
+#pragma pack(1)
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1;
+ UINT8 reserved_2;
+ UINT8 reserved_3;
+ UINT8 reserved_4;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 reserved_8;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} TEST_UNIT_READY_CMD;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1 : 4;
+ UINT8 lun : 4;
+ UINT8 page_code;
+ UINT8 reserved_3;
+ UINT8 allocation_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 reserved_8;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} INQUIRY_CMD;
+
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1 : 4;
+ UINT8 lun : 4;
+ UINT8 reserved_2;
+ UINT8 reserved_3;
+ UINT8 allocation_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 reserved_8;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} REQUEST_SENSE_CMD;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1 : 5;
+ UINT8 lun : 3;
+ UINT8 Lba0;
+ UINT8 Lba1;
+ UINT8 Lba2;
+ UINT8 Lba3;
+ UINT8 reserved_6;
+ UINT8 TranLen0;
+ UINT8 TranLen1;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} READ10_CMD;
+
+typedef struct
+{
+ UINT8 opcode;
+ UINT8 reserved_1;
+ UINT8 reserved_2;
+ UINT8 reserved_3;
+ UINT8 reserved_4;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 allocation_length_hi;
+ UINT8 allocation_length_lo;
+ UINT8 reserved_9;
+ UINT8 reserved_10;
+ UINT8 reserved_11;
+} READ_FORMAT_CAP_CMD;
+
+typedef struct
+{
+ UINT8 peripheral_type;
+ UINT8 RMB;
+ UINT8 version;
+ UINT8 response_data_format;
+ UINT8 addnl_length;
+ UINT8 reserved_5;
+ UINT8 reserved_6;
+ UINT8 reserved_7;
+ UINT8 vendor_info[8];
+ UINT8 product_id[12];
+ UINT8 eeprom_product_code[4];
+ UINT8 firmware_rev_level[4];
+} USB_INQUIRY_DATA;
+
+typedef union {
+ UINT16 Data16[6];
+ TEST_UNIT_READY_CMD TestUnitReady;
+ READ10_CMD Read10;
+ REQUEST_SENSE_CMD RequestSence;
+ INQUIRY_CMD Inquiry;
+ READ_FORMAT_CAP_CMD ReadFormatCapacity;
+} ATAPI_PACKET_COMMAND;
+
+#pragma pack()
+
+//
+// Packet Command Code
+//
+#define TEST_UNIT_READY 0x00
+#define REQUEST_SENSE 0x03
+#define INQUIRY 0x12
+#define READ_FORMAT_CAPACITY 0x23
+#define READ_CAPACITY 0x25
+#define READ_10 0x28
+
+#define DEFAULT_CTL (0x0a) // default content of device
+ // control register,
+ // disable INT
+#define DEFAULT_CMD (0xa0)
+
+#define MAX_ATAPI_BYTE_COUNT (0xfffe)
+
+//
+// Sense Key
+//
+#define REQUEST_SENSE_ERROR (0x70)
+#define SK_NO_SENSE (0x0)
+#define SK_RECOVERY_ERROR (0x1)
+#define SK_NOT_READY (0x2)
+#define SK_MEDIUM_ERROR (0x3)
+#define SK_HARDWARE_ERROR (0x4)
+#define SK_ILLEGAL_REQUEST (0x5)
+#define SK_UNIT_ATTENTION (0x6)
+#define SK_DATA_PROTECT (0x7)
+#define SK_BLANK_CHECK (0x8)
+#define SK_VENDOR_SPECIFIC (0x9)
+#define SK_RESERVED_A (0xa)
+#define SK_ABORT (0xb)
+#define SK_RESERVED_C (0xc)
+#define SK_OVERFLOW (0xd)
+#define SK_MISCOMPARE (0xe)
+#define SK_RESERVED_F (0xf)
+
+//
+// Additional Sense Codes
+//
+#define ASC_NOT_READY (0x04)
+#define ASC_MEDIA_ERR1 (0x10)
+#define ASC_MEDIA_ERR2 (0x11)
+#define ASC_MEDIA_ERR3 (0x14)
+#define ASC_MEDIA_ERR4 (0x30)
+#define ASC_MEDIA_UPSIDE_DOWN (0x06)
+#define ASC_INVALID_CMD (0x20)
+#define ASC_LBA_OUT_OF_RANGE (0x21)
+#define ASC_INVALID_FIELD (0x24)
+#define ASC_WRITE_PROTECTED (0x27)
+#define ASC_MEDIA_CHANGE (0x28)
+#define ASC_RESET (0x29) // Power On Reset or Bus Reset occurred
+#define ASC_ILLEGAL_FIELD (0x26)
+#define ASC_NO_MEDIA (0x3a)
+#define ASC_ILLEGAL_MODE_FOR_THIS_TRACK (0x64)
+
+//
+// Additional Sense Code Qualifier
+//
+#define ASCQ_IN_PROGRESS (0x01)
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeim.h b/Core/EM/UsbRecovery/UsbPeim.h
new file mode 100644
index 0000000..b87ded6
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeim.h
@@ -0,0 +1,244 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeim.h 8 11/24/12 5:43a Ryanchou $
+//
+// $Revision: 8 $
+//
+// $Date: 11/24/12 5:43a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeim.h $
+//
+// 8 11/24/12 5:43a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 7 1/18/11 12:50a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 6 10/11/10 4:51p Olegi
+// XHCI support added.
+//
+// 5 3/17/09 5:11p Olegi
+//
+// 4 7/10/08 6:33p Michaela
+// Updated to support OHCI controllers
+//
+// 3 4/16/07 1:03p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:07a Meenakshim
+// Removed dependency on core source files..Added amimapping file.
+//
+// 1 9/22/06 4:06p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbPeim.H
+//
+// Description: This file belongs to "Framework" and included here for
+// compatibility purposes. This file is modified by AMI to include
+// copyright message, appropriate header and integration code
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains 'Framework Code' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may not be modified, except as allowed by
+// additional terms of your license agreement.
+//
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbPeim.h
+
+ Abstract:
+
+ Usb Peim definition
+
+ --*/
+
+#ifndef _PEI_USB_PEIM_H
+#define _PEI_USB_PEIM_H
+
+#include "Efi.h"
+#include "Pei.h"
+#include "AmiMapping.h"
+#include "AmiPeiLib.h"
+
+#include "usb.h"
+
+//
+// Driver Produced PPI Prototypes
+//
+#include "Ppi\UsbIo.h"
+
+//
+// Driver Consumed PPI Prototypes
+//
+#include "Ppi\UsbHostController.h"
+
+#define MAX_ROOT_PORT 2
+#define MAX_ENDPOINT 16
+#define HUB_TIME_OUT 3000
+#define STALL_1_MILLI_SECOND 1000 // stall 1 ms
+
+
+#define USB_SLOW_SPEED_DEVICE 0x01
+#define USB_FULL_SPEED_DEVICE 0x02
+#define USB_HIGH_SPEED_DEVICE 0x03
+#define USB_SUPER_SPEED_DEVICE 0x04
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.BaseClass
+//---------------------------------------------------------------------------
+#define BASE_CLASS_HID 0x03
+#define BASE_CLASS_MASS_STORAGE 0x08
+#define BASE_CLASS_HUB 0x09
+//----------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.Protocol
+//---------------------------------------------------------------------------
+#define PROTOCOL_KEYBOARD 0x01 // Keyboard device protocol
+#define PROTOCOL_MOUSE 0x02 // Mouse device protocol?
+
+// Mass storage related protocol equates
+#define PROTOCOL_CBI 0x00 // Mass Storage Control/Bulk/Interrupt
+ // with command completion interrupt
+#define PROTOCOL_CBI_NO_INT 0x01 // MASS STORAGE Control/Bulk/Interrupt
+ // with NO command completion interrupt
+#define PROTOCOL_BOT 0x50 // Mass Storage Bulk-Only Transport
+#define PROTOCOL_VENDOR 0xff // Vendor specific mass protocol
+//---------------------------------------------------------------------------
+
+#define PEI_USB_DEVICE_SIGNATURE EFI_SIGNATURE_32( 'U', 's', 'b', 'D' )
+typedef struct
+{
+ UINTN Signature;
+ PEI_USB_IO_PPI UsbIoPpi;
+ EFI_PEI_PPI_DESCRIPTOR UsbIoPpiList;
+ UINT8 DeviceAddress;
+ UINT8 MaxPacketSize0;
+ UINT8 DeviceSpeed;
+ UINT8 DataToggle;
+ UINT8 IsHub;
+ UINT8 DownStreamPortNo;
+ UINT8 Reserved[2]; // Padding for IPF
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+ UINT8 *ConfigurationData;
+ EFI_USB_CONFIG_DESCRIPTOR *ConfigDesc;
+ EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDesc;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc[MAX_ENDPOINT];
+ UINT16 TransactionTranslator;
+ UINT8 HubDepth;
+} PEI_USB_DEVICE;
+
+#define PEI_USB_DEVICE_FROM_THIS( a ) \
+ PEI_CR( a, PEI_USB_DEVICE, UsbIoPpi, PEI_USB_DEVICE_SIGNATURE )
+
+//
+// Peim UsbIo prototype
+//
+
+EFI_STATUS
+PeiUsbControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT32 Timeout,
+ IN OUT VOID *Data OPTIONAL,
+ IN UINTN DataLength OPTIONAL );
+
+EFI_STATUS
+PeiUsbBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN UINT8 DeviceEndpoint,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout );
+
+EFI_STATUS
+PeiUsbGetInterfaceDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor );
+
+EFI_STATUS
+PeiUsbGetEndpointDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN UINT8 EndpointIndex,
+ IN EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor );
+
+EFI_STATUS
+PeiUsbPortReset (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This );
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c
new file mode 100644
index 0000000..a2a2246
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/HubPeim.c
@@ -0,0 +1,889 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/HubPeim.c 12 11/24/12 5:46a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 11/24/12 5:46a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/HubPeim.c $
+//
+// 12 11/24/12 5:46a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 11 8/24/11 4:24a Roberthsu
+// [TAG] EIP67320
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB recovery will fail when plug-in USB touch panel on
+// Oaktrail platform
+// [RootCause] Usbrecovery will exit when get portchanged.Touch panel
+// port status is early than usbkey.So usbrecovery fail.
+// [Solution] Add delay after hub set port power.
+// [Files] HubPeim.c
+//
+// 10 1/18/11 12:54a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 9 4/26/10 4:17p Krishnakumarg
+// DebugRx causes the system to hang in Recovery mode EIP#34401
+//
+// 8 4/06/10 3:31p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 7 3/17/09 5:03p Olegi
+// Removed unnecessary CLEAR_FEATURE (Reset) and SET_FEATURE (Enable) in
+// the hub enumeration routine.
+//
+// 6 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 5 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 4 8/17/07 4:14p Ambikas
+//
+// 3 4/16/07 12:54p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:38a Meenakshim
+//
+// 1 9/22/06 12:19p Sivagarn
+// - Initial Checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: HubPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ HubPeim.c
+
+ Abstract:
+
+ Usb Hub Request Support In PEI Phase
+
+ Revision History
+
+ --*/
+//NOT NEEDED FOR APTIO
+//#include "Efi.h"
+//#include "EfiDriverLib.h"
+//#include "usb.h"
+
+#include "HubPeim.h"
+#include "UsbPeim.h"
+#include "PeiUsbLib.h"
+
+#include EFI_PPI_DEFINITION( Stall )
+static EFI_GUID gPeiStallPpiGuid = EFI_PEI_STALL_PPI_GUID;
+
+//NOT NEEDED FOR APTIO
+//#include "usbbus.h"
+//#include "usblib.h"
+//#include "hub.h"
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+typedef struct {
+ UINT32 HubPortStatus;
+ UINT32 EfiPortStatus;
+} EFI_USB_PORT_STATUS_MAP;
+
+EFI_USB_PORT_STATUS_MAP HubPortStatusMap[] = {
+ // Port status bits
+ {HUB_PORT_CONNECTION, USB_PORT_STAT_CONNECTION},
+ {HUB_PORT_ENABLE, USB_PORT_STAT_ENABLE},
+ {HUB_PORT_SUSPEND, USB_PORT_STAT_SUSPEND},
+ {HUB_PORT_OVER_CURRENT, USB_PORT_STAT_OVERCURRENT},
+ {HUB_PORT_RESET, USB_PORT_STAT_RESET},
+ {HUB_PORT_POWER, USB_PORT_STAT_POWER},
+ {HUB_PORT_LOW_SPEED, USB_PORT_STAT_LOW_SPEED},
+ {HUB_PORT_HIGH_SPEED, USB_PORT_STAT_HIGH_SPEED},
+ // Port status change bits
+ {HUB_C_PORT_CONNECTION << 16, USB_PORT_STAT_C_CONNECTION << 16},
+ {HUB_C_PORT_ENABLE << 16, USB_PORT_STAT_C_ENABLE << 16},
+ {HUB_C_PORT_SUSPEND << 16, USB_PORT_STAT_C_SUSPEND << 16},
+ {HUB_C_PORT_OVER_CURRENT << 16, USB_PORT_STAT_C_OVERCURRENT << 16},
+ {HUB_C_PORT_RESET << 16, USB_PORT_STAT_C_RESET << 16}
+};
+
+EFI_USB_PORT_STATUS_MAP SsHubPortStatusMap[] = {
+ // Port status bits
+ {SS_HUB_PORT_CONNECTION, USB_PORT_STAT_CONNECTION | USB_PORT_STAT_SUPER_SPEED},
+ {SS_HUB_PORT_ENABLE, USB_PORT_STAT_ENABLE},
+ {SS_HUB_PORT_OVER_CURRENT, USB_PORT_STAT_OVERCURRENT},
+ {SS_HUB_PORT_RESET, USB_PORT_STAT_RESET},
+ {SS_HUB_PORT_POWER, USB_PORT_STAT_POWER},
+ // Port status change bits
+ {SS_HUB_C_PORT_CONNECTION << 16, USB_PORT_STAT_C_CONNECTION << 16},
+ {SS_HUB_C_PORT_ENABLE << 16, USB_PORT_STAT_C_ENABLE << 16},
+ {SS_HUB_C_PORT_SUSPEND << 16, USB_PORT_STAT_C_SUSPEND << 16},
+ {SS_HUB_C_PORT_OVER_CURRENT << 16, USB_PORT_STAT_C_OVERCURRENT << 16},
+ {SS_HUB_C_PORT_RESET << 16, USB_PORT_STAT_C_RESET << 16}
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PeiHubGetPortStatus
+//
+// Description:
+// This function uses a device's PEI_USB_IO_PPI interface to execute a
+// control transfer on the default control pipe to issue a Hub
+// Class-specific request to obtain the port status and port status
+// change bits.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- PEI Sevices table pointer
+// IN PEI_USB_IO_PPI *UsbIoPpi
+// -- PEI_USB_IO_PPI interface pointer for the device
+// that is being accessed
+// IN UINT8 Port
+// -- This value is the hub port number for which the
+// status is to be returned.
+// OUT UINT32 *PortStatus
+// -- This output value is the USB Specification
+// (Revision 2.0) Hub Port Status field (upper word)
+// and Change Status field (lower word) values as
+// returned by the Get Port Status Hub Class device
+// standard request.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS PeiHubGetPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ OUT UINT32 *PortStatus )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS EfiStatus;
+ UINT32 HubPortStatus = 0;
+ UINT32 Timeout;
+ EFI_USB_PORT_STATUS_MAP *PortStatusMap;
+ UINT8 Index;
+ UINT8 Count;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_GET_PORT_STATUS_REQ_TYPE;
+ DevReq.Request = HUB_GET_PORT_STATUS;
+ DevReq.Value = 0;
+ DevReq.Index = Port;
+ DevReq.Length = sizeof(UINT32);
+
+ Timeout = 3000;
+
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ &HubPortStatus,
+ sizeof(UINT32)
+ );
+
+ if (PeiUsbDev->DeviceSpeed != USB_SUPER_SPEED_DEVICE) {
+ PortStatusMap = HubPortStatusMap;
+ Count = sizeof(HubPortStatusMap) / sizeof(EFI_USB_PORT_STATUS_MAP);
+ } else {
+ PortStatusMap = SsHubPortStatusMap;
+ Count = sizeof(SsHubPortStatusMap) / sizeof(EFI_USB_PORT_STATUS_MAP);
+ }
+
+ for (*PortStatus = 0, Index = 0; Index < Count; Index++) {
+ if (HubPortStatus & PortStatusMap[Index].HubPortStatus) {
+ *PortStatus |= PortStatusMap[Index].EfiPortStatus;
+ }
+ }
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubSetPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Set specified feature to a give hub port
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Port - Usb hub port number (starting from 1).
+ Value - New feature value.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+ EFI_INVALID_PARAMETER
+
+ --*/
+
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_SET_PORT_FEATURE_REQ_TYPE;
+ DevReq.Request = HUB_SET_PORT_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = Port;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubClearPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Port,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Clear a specified feature of a given hub port
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Port - Usb hub port number (starting from 1).
+ Value - Feature value that will be cleared from
+ that hub port.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+ EFI_INVALID_PARAMETER
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_CLEAR_FEATURE_PORT_REQ_TYPE;
+ DevReq.Request = HUB_CLEAR_FEATURE_PORT;
+ DevReq.Value = Value;
+ DevReq.Index = Port;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubGetHubStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ OUT UINT32 *HubStatus )
+
+/*++
+
+ Routine Description:
+ Get Hub Status
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ HubStatus - Current Hub status and change status.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_GET_HUB_STATUS_REQ_TYPE;
+ DevReq.Request = HUB_GET_HUB_STATUS;
+ DevReq.Value = 0;
+ DevReq.Index = 0;
+ DevReq.Length = sizeof(UINT32);
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ HubStatus,
+ sizeof(UINT32)
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubSetHubFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Set a specified feature to the hub
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Value - Feature value that will be set to the hub.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_SET_HUB_FEATURE_REQ_TYPE;
+ DevReq.Request = HUB_SET_HUB_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+
+EFI_STATUS PeiHubClearHubFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT8 Value )
+
+/*++
+
+ Routine Description:
+ Set a specified feature to the hub
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ Value - Feature value that will be cleared from the hub.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_CLEAR_FEATURE_REQ_TYPE;
+ DevReq.Request = HUB_CLEAR_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+
+}
+
+EFI_STATUS PeiSetHubDepth (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINT16 HubDepth)
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+ if (PeiUsbDev->DeviceSpeed != USB_SUPER_SPEED_DEVICE) {
+ return EFI_SUCCESS;
+ }
+
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = HUB_SET_HUB_DEPTH_REQ_TYPE;
+ DevReq.Request = HUB_SET_HUB_DEPTH;
+ DevReq.Value = HubDepth;
+ DevReq.Index = 0;
+ DevReq.Length = 0;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbNoData,
+ Timeout,
+ NULL,
+ 0
+ );
+
+ return EfiStatus;
+}
+
+EFI_STATUS PeiGetHubDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ IN UINTN DescriptorSize,
+ OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor )
+
+/*++
+
+ Routine Description:
+ Get the hub descriptor
+
+ Arguments:
+ UsbIoPpi - EFI_USB_IO_PROTOCOL instance
+ DescriptorSize - The length of Hub Descriptor buffer.
+ HubDescriptor - Caller allocated buffer to store the hub descriptor
+ if successfully returned.
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE
+ EFI_TIME_OUT
+
+ --*/
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS EfiStatus;
+ UINT32 Timeout;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( UsbIoPpi );
+ ZeroMem( &DevReq, sizeof(EFI_USB_DEVICE_REQUEST) );
+
+ //
+ // Fill Device request packet
+ //
+ DevReq.RequestType = USB_RT_HUB | 0x80;
+ DevReq.Request = HUB_GET_DESCRIPTOR;
+ DevReq.Value = PeiUsbDev->DeviceSpeed == USB_SUPER_SPEED_DEVICE ?
+ USB_DT_SS_HUB << 8: USB_DT_HUB << 8;
+ DevReq.Index = 0;
+ DevReq.Length = (UINT16) DescriptorSize;
+
+ Timeout = 3000;
+ EfiStatus = UsbIoPpi->UsbControlTransfer(
+ PeiServices,
+ UsbIoPpi,
+ &DevReq,
+ EfiUsbDataIn,
+ Timeout,
+ HubDescriptor,
+ (UINT16) DescriptorSize
+ );
+
+ return EfiStatus;
+
+}
+
+
+EFI_STATUS PeiDoHubConfig (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice )
+
+/*++
+
+ Routine Description:
+ Configure the hub
+
+ Arguments:
+ PeiUsbDevice - Indicating the hub controller device that
+ will be configured
+
+ Returns:
+ EFI_SUCCESS
+ EFI_DEVICE_ERROR
+
+ --*/
+{
+ EFI_USB_HUB_DESCRIPTOR HubDescriptor;
+ EFI_STATUS Status;
+ EFI_USB_HUB_STATUS HubStatus;
+ UINTN i;
+ UINT32 PortStatus;
+ PEI_USB_IO_PPI *UsbIoPpi;
+
+ BOOLEAN SkipDebugPort = PeiUsbDevice->UsbHcPpi->DebugPortUsed;
+//(EIP67320+)>
+ PEI_STALL_PPI *PeiStall;
+ (**PeiServices).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+//<(EIP67320+)
+ ZeroMem( &HubDescriptor, sizeof(HubDescriptor) );
+ UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
+
+ Status = PeiSetHubDepth(PeiServices,
+ UsbIoPpi,
+ PeiUsbDevice->HubDepth);
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // First get the whole descriptor, then
+ // get the number of hub ports
+ //
+ Status = PeiGetHubDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ sizeof(EFI_USB_HUB_DESCRIPTOR),
+ &HubDescriptor
+ );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts;
+
+ Status = PeiHubGetHubStatus( PeiServices,
+ UsbIoPpi,
+ (UINT32 *) &HubStatus
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Get all hub ports status
+ //
+ for (i = 0; i < PeiUsbDevice->DownStreamPortNo; i++) {
+
+// Intel Debug port - Second port of the controller
+ if(SkipDebugPort && (i == 1) )
+ continue;
+
+ Status = PeiHubGetPortStatus( PeiServices,
+ UsbIoPpi,
+ (UINT8) (i + 1),
+ &PortStatus
+ );
+ if ( EFI_ERROR( Status ) ) {
+ continue;
+ }
+ }
+
+ //
+ // Power all the hub ports
+ //
+ for (i = 0; i < PeiUsbDevice->DownStreamPortNo; i++) {
+// Intel Debug port - Second port of the controller
+ if( SkipDebugPort && (i == 1) )
+ continue;
+
+ Status = PeiHubSetPortFeature( PeiServices,
+ UsbIoPpi,
+ (UINT8) (i + 1),
+ EfiUsbPortPower
+ );
+ if ( EFI_ERROR( Status ) ) {
+ continue;
+ }
+ }
+
+ //
+ // Clear Hub Status Change
+ //
+ Status = PeiHubGetHubStatus( PeiServices,
+ UsbIoPpi,
+ (UINT32 *) &HubStatus
+ );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_DEVICE_ERROR;
+ }
+ else {
+ //
+ // Hub power supply change happens
+ //
+ if (HubStatus.HubChange & HUB_CHANGE_LOCAL_POWER) {
+ PeiHubClearHubFeature( PeiServices,
+ UsbIoPpi,
+ C_HUB_LOCAL_POWER
+ );
+ }
+
+ //
+ // Hub change overcurrent happens
+ //
+ if (HubStatus.HubChange & HUB_CHANGE_OVERCURRENT) {
+ PeiHubClearHubFeature( PeiServices,
+ UsbIoPpi,
+ C_HUB_OVER_CURRENT
+ );
+ }
+ }
+ PeiStall->Stall( PeiServices, PeiStall, (HubDescriptor.PwrOn2PwrGood << 1) *1000); //(EIP67320)
+ return EFI_SUCCESS;
+
+}
+
+
+//
+// Send reset signal over the given root hub port
+//
+VOID PeiResetHubPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *UsbIoPpi,
+ UINT8 PortNum )
+{
+ PEI_STALL_PPI *PeiStall;
+ UINT8 n;
+ EFI_USB_PORT_STATUS HubPortStatus;
+
+
+ (**PeiServices).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+
+ //
+ // reset root port
+ //
+ PeiHubSetPortFeature(
+ PeiServices,
+ UsbIoPpi,
+ PortNum,
+ EfiUsbPortReset
+ );
+
+ n = 20;
+ do {
+ PeiHubGetPortStatus(
+ PeiServices,
+ UsbIoPpi,
+ PortNum,
+ (UINT32 *) &HubPortStatus
+ );
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 1000
+ );
+ n -= 1;
+ } while ( (HubPortStatus.PortChangeStatus &
+ USB_PORT_STAT_C_RESET) == 0 && n > 0 );
+
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 500
+ );
+ //
+ // Clear any change status
+ //
+ PeiHubClearPortFeature(
+ PeiServices,
+ UsbIoPpi,
+ PortNum,
+ EfiUsbPortResetChange
+ );
+
+ return;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2007, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c
new file mode 100644
index 0000000..157cb9b
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbIoPeim.c
@@ -0,0 +1,334 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbIoPeim.c 6 1/18/11 1:05a Ryanchou $
+//
+// $Revision: 6 $
+//
+// $Date: 1/18/11 1:05a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbIoPeim.c $
+//
+// 6 1/18/11 1:05a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 5 3/17/09 5:04p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 4 3/03/09 7:21p Olegi
+// Changed the type of MaxPktSize from UINT8 to UINT16.
+//
+// 3 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 2 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 1 9/22/06 12:19p Sivagarn
+// - Initial Checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbIoPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbIoPeim.c
+
+ Abstract:
+
+ Usb Io PPI
+
+ --*/
+
+#include "UsbPeim.h"
+#include "PeiUsbLib.h"
+
+#define PAGESIZE 4096
+
+VOID
+ResetRootPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi,
+ UINT8 PortNum );
+
+EFI_STATUS PeiUsbControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT32 Timeout,
+ IN OUT VOID *Data OPTIONAL,
+ IN UINTN DataLength OPTIONAL )
+{
+ EFI_STATUS Status;
+ PEI_USB_DEVICE *PeiUsbDev;
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+ UINT32 TransferResult;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+ UsbHcPpi = PeiUsbDev->UsbHcPpi;
+
+ Status = UsbHcPpi->ControlTransfer(
+ PeiServices,
+ UsbHcPpi,
+ PeiUsbDev->DeviceAddress,
+ PeiUsbDev->DeviceSpeed,
+ PeiUsbDev->MaxPacketSize0,
+ PeiUsbDev->TransactionTranslator,
+ Request,
+ Direction,
+ Data,
+ &DataLength,
+ Timeout,
+ &TransferResult
+ );
+
+ return Status;
+}
+
+
+EFI_STATUS PeiUsbBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN UINT8 DeviceEndpoint,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout )
+{
+ EFI_STATUS Status;
+ PEI_USB_DEVICE *PeiUsbDev;
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+ UINT32 TransferResult;
+ UINT16 MaxPacketLength;
+ UINT8 DataToggle;
+ UINT8 OldToggle;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
+ UINT8 EndpointIndex;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+ UsbHcPpi = PeiUsbDev->UsbHcPpi;
+
+ EndpointIndex = 0;
+
+ while (EndpointIndex < MAX_ENDPOINT) {
+ Status = PeiUsbGetEndpointDescriptor( PeiServices,
+ This, EndpointIndex, &EndpointDescriptor );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) {
+ break;
+ }
+
+ EndpointIndex++;
+ }
+
+ if (EndpointIndex == MAX_ENDPOINT) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MaxPacketLength = (PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize);
+ if ( ( PeiUsbDev->DataToggle & (1 << EndpointIndex) ) != 0 ) {
+ DataToggle = 1;
+ }
+ else {
+ DataToggle = 0;
+ }
+
+ OldToggle = DataToggle;
+
+ Status = UsbHcPpi->BulkTransfer(
+ PeiServices,
+ UsbHcPpi,
+ PeiUsbDev->DeviceAddress,
+ DeviceEndpoint,
+ PeiUsbDev->DeviceSpeed,
+ MaxPacketLength,
+ PeiUsbDev->TransactionTranslator,
+ Data,
+ DataLength,
+ &DataToggle,
+ Timeout,
+ &TransferResult
+ );
+
+ if (OldToggle != DataToggle) {
+ PeiUsbDev->DataToggle =
+ (UINT8) ( PeiUsbDev->DataToggle ^ (1 << EndpointIndex) );
+ }
+
+ return Status;
+}
+
+
+EFI_STATUS PeiUsbGetInterfaceDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor )
+{
+ PEI_USB_DEVICE *PeiUsbDev;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+
+ *InterfaceDescriptor = PeiUsbDev->InterfaceDesc;
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiUsbGetEndpointDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This,
+ IN UINT8 EndpointIndex,
+ IN EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor )
+{
+ PEI_USB_DEVICE *PeiUsbDev;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+
+ if (EndpointIndex >= PeiUsbDev->InterfaceDesc->NumEndpoints) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ *EndpointDescriptor = PeiUsbDev->EndpointDesc[EndpointIndex];
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS PeiUsbPortReset (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_IO_PPI *This )
+{
+ PEI_USB_DEVICE *PeiUsbDev;
+ EFI_STATUS Status;
+ UINT8 Address;
+
+ PeiUsbDev = PEI_USB_DEVICE_FROM_THIS( This );
+
+ ResetRootPort(
+ PeiServices,
+ PeiUsbDev->UsbHcPpi,
+ PeiUsbDev->DeviceAddress
+ );
+
+ //
+ // Set address
+ //
+ Address = PeiUsbDev->DeviceAddress;
+ PeiUsbDev->DeviceAddress = 0;
+
+ Status = PeiUsbSetDeviceAddress(
+ PeiServices,
+ This,
+ Address
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ PeiUsbDev->DeviceAddress = Address;
+
+ //
+ // Set default configuration
+ //
+ Status = PeiUsbSetConfiguration(
+ PeiServices,
+ This
+ );
+
+ return Status;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c
new file mode 100644
index 0000000..87afc78
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeim.c
@@ -0,0 +1,1006 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbPeim.c 17 11/24/12 5:46a Ryanchou $
+//
+// $Revision: 17 $
+//
+// $Date: 11/24/12 5:46a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbPeimSrc/UsbPeim.c $
+//
+// 17 11/24/12 5:46a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 16 8/23/12 10:01p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 15 1/18/11 1:06a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 14 10/22/10 2:55a Rameshr
+// [TAG]- EIP 43687
+// [Category]-IMPROVEMENT
+// [Description]- Build warning from UsbRecovery driver -
+// UsbHostController.obj : warning LNK4221: no public symbols found;
+// archive member will be inaccessible.
+// [Files]- uhcpeim.c, usbpeim.c, UsbHostcontroller.h
+//
+// 13 10/12/10 11:20a Olegi
+// XHCI support added.
+//
+// 12 1/06/10 11:23a Olegi
+// Fix for EIP32503: The Interface descriptor of some devices is not
+// directly after the configuration descriptor, and the first Endpoint
+// descriptor is not directly after the Interface either. Changed the
+// descriptior data parser.
+//
+// 11 10/20/09 9:17a Olegi
+// EIP#28255: Set proper TransactionTranslator field for a non-hispeed USB
+// device.
+//
+// 10 3/17/09 5:07p Olegi
+// Added TransactionTranslator for slow/full speed devices behind USB2
+// hub.
+//
+// 9 10/21/08 5:57p Michaela
+// Added EHCI-related fixes for issues
+// that may occur if EHCI is used before
+// USB Recovery is invoked:
+// Added SDL Tokens:
+// PEI_EHCI_PCI_BDFS and
+// PEI_EHCI_MEM_BASE_ADDRESSES.
+//
+// Removed/modified some debugging
+// development code:
+// Removed SDL Tokens:
+// USBR_DEBUG_SUPPORT and
+// USBR_SERIAL_PORT_AVAILABLE
+// Removed Elinks:
+// UsbRecoveryDebug_DIR and
+// $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+// Modified SDL Token:
+// FORCE_RECOVERY to default value of 0.
+//
+// (See this module's Help documentation
+// for more information.)
+//
+// 8 7/29/08 5:52p Michaela
+// 1) Updated code to move most porting tasks to SDL
+// 2) Added more debug break points and improved interactive
+// debugging capability for when a serial port is not available.
+// 3) Updated help files
+//
+// 7 7/18/08 5:05p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 6 7/10/08 6:37p Michaela
+// Updated to support OHCI controllers
+//
+// 5 10/23/07 5:41p Ambikas
+//
+// 4 8/17/07 4:13p Ambikas
+//
+// 3 4/16/07 12:55p Sivagarn
+// - Updated as per coding standard review
+// - In previous check-in, TIANO.H file is removed and AMIMAPPING.H file
+// is included
+//
+// 2 3/28/07 3:36a Meenakshim
+//
+// 1 9/22/06 12:19p Sivagarn
+// - Initial Checkin
+// - Included Recovery code in Source
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbPeim.C
+//
+// Description: This file belongs to "Framework".
+// This file is modified by AMI to include copyright message,
+// appropriate header and integration code.
+// This file contains generic routines needed for USB recovery
+// PEIM
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+/*++
+ This file contains 'Framework Code' and is licensed as such
+ under the terms of your license agreement with Intel or your
+ vendor. This file may not be modified, except as allowed by
+ additional terms of your license agreement.
+ --*/
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ UsbPeim.c
+
+ Abstract:
+
+ Usb Bus PPI
+
+ --*/
+
+#include "UsbPeim.h"
+#include "HubPeim.h"
+#include "PeiUsbLib.h"
+
+
+#include EFI_PPI_DEFINITION (Stall)
+#include EFI_PPI_DEFINITION (LoadFile)
+
+EFI_GUID gPeiUsbIoPpiGuid = PEI_USB_IO_PPI_GUID;
+
+extern EFI_GUID gPeiStallPpiGuid;
+
+
+#define PAGESIZE 4096
+
+//static BOOLEAN mImageInMemory = FALSE;
+
+
+//
+// Driver Entry Point
+//
+
+
+EFI_STATUS
+PeimInitializeUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices );
+
+//
+// UsbIo PPI interface function
+//
+STATIC PEI_USB_IO_PPI mUsbIoPpi = {
+ PeiUsbControlTransfer,
+ PeiUsbBulkTransfer,
+ PeiUsbGetInterfaceDescriptor,
+ PeiUsbGetEndpointDescriptor,
+ PeiUsbPortReset
+};
+
+STATIC EFI_PEI_PPI_DESCRIPTOR mUsbIoPpiList = {
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gPeiUsbIoPpiGuid,
+ NULL
+};
+
+//
+// Helper functions
+//
+STATIC
+EFI_STATUS
+PeiUsbEnumeration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi );
+
+STATIC
+EFI_STATUS
+PeiConfigureUsbDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice,
+ IN UINT8 Port,
+ IN OUT UINT8 *DeviceAddress );
+
+STATIC
+EFI_STATUS
+PeiUsbGetAllConfiguration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice );
+
+
+VOID
+ResetRootPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi,
+ UINT8 PortNum );
+
+extern VOID ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size );
+
+
+
+//
+// PEIM Entry Point
+//
+// EFI_PEIM_ENTRY_POINT (PeimInitializeUsb);
+
+EFI_STATUS PeimInitializeUsb (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+ EFI_STATUS Status;
+ UINTN i;
+ PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi;
+
+ // Assign resources and enable UHCI controllers
+ //
+ // when the image is in flash, the global variable
+ // mImageInMemory could not be modified;
+ // when the image is successfully loaded into memory,
+ // mImageInMemory could be modified to TRUE.
+ //
+
+ i = 0;
+ while (TRUE) {
+ //
+ // Get UsbHcPpi at first.
+ //
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &gPeiUsbHostControllerPpiGuid, i, NULL, &UsbHcPpi );
+
+ if ( EFI_ERROR( Status ) ) {
+ break;
+ }
+
+ PeiUsbEnumeration( PeiServices, UsbHcPpi ); // 0xff06
+ i++;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS PeiHubEnumeration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice,
+ IN UINT8 *CurrentAddress )
+//
+// Since we are not going to support hot-plug, we will do a
+// dedicated polling process to get all ports change event
+// discovered. This can help to avoid introduce interrupt
+// transfer into the system, for each hub, we will wait for
+// 3s and if one port is enabled we will not wait for others
+// We will start parsing each of them in sequence.
+//
+{
+ UINTN Delay;
+ UINT8 Port;
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ EFI_USB_PORT_STATUS PortStatus;
+ BOOLEAN PortChanged;
+ UINT8 *AllocateAddress;
+ PEI_USB_DEVICE *NewPeiUsbDevice;
+ PEI_STALL_PPI *StallPpi;
+
+
+ PortChanged = FALSE;
+
+ UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+
+ Delay = (HUB_TIME_OUT * STALL_1_MILLI_SECOND / 50000) + 1;
+
+ //
+ // Do while will do a 3s scan for the USB HUB for a connected
+ // device. If we have found one, the waiting process will be
+ // breaked since we assue other ports will be discovered at
+ // the same time.
+ //
+ do {
+ for (Port = 1; Port <= PeiUsbDevice->DownStreamPortNo; Port++) {
+
+ Status = PeiHubGetPortStatus( PeiServices, UsbIoPpi,
+ Port, (UINT32 *) &PortStatus );
+
+ if ( EFI_ERROR( Status ) ) {
+ continue;
+ }
+
+ if ( IsPortConnectChange( PortStatus.PortChangeStatus ) ) {
+ PortChanged = TRUE;
+ PeiHubClearPortFeature( PeiServices, UsbIoPpi,
+ Port, EfiUsbPortConnectChange );
+
+ if ( IsPortConnect( PortStatus.PortStatus ) ) {
+
+ if (IsPortEnable(PortStatus.PortStatus) == FALSE) {
+ //
+ // First reset and enable this port
+ //
+ PeiResetHubPort( PeiServices, UsbIoPpi, Port );
+
+ PeiHubGetPortStatus( PeiServices, UsbIoPpi,
+ Port, (UINT32 *) &PortStatus );
+ }
+
+ //
+ // Begin to deal with the new device
+ //
+ Status = (*PeiServices)->AllocatePool( PeiServices,
+ sizeof(PEI_USB_DEVICE), &AllocateAddress );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ NewPeiUsbDevice = (PEI_USB_DEVICE *)AllocateAddress;
+
+ ZeroMem( NewPeiUsbDevice, sizeof(PEI_USB_DEVICE) );
+
+ NewPeiUsbDevice->Signature =
+ PEI_USB_DEVICE_SIGNATURE;
+ NewPeiUsbDevice->DeviceAddress = 0;
+ NewPeiUsbDevice->MaxPacketSize0 = 8;
+ NewPeiUsbDevice->DataToggle = 0;
+ NewPeiUsbDevice->UsbIoPpi = mUsbIoPpi;
+ NewPeiUsbDevice->UsbIoPpiList = mUsbIoPpiList;
+ NewPeiUsbDevice->UsbIoPpiList.Ppi =
+ &NewPeiUsbDevice->UsbIoPpi;
+ NewPeiUsbDevice->UsbHcPpi =
+ PeiUsbDevice->UsbHcPpi;
+ NewPeiUsbDevice->DeviceSpeed =
+ USB_FULL_SPEED_DEVICE;
+ NewPeiUsbDevice->IsHub = 0x0;
+ NewPeiUsbDevice->DownStreamPortNo = 0x0;
+ NewPeiUsbDevice->TransactionTranslator =
+ (UINT16)(Port << 7) + PeiUsbDevice->DeviceAddress;
+ NewPeiUsbDevice->HubDepth = 0x0;
+ //(EIP28255+)>
+ if ( (PeiUsbDevice->DeviceSpeed == USB_SLOW_SPEED_DEVICE) ||
+ (PeiUsbDevice->DeviceSpeed == USB_FULL_SPEED_DEVICE) )
+ {
+ NewPeiUsbDevice->TransactionTranslator = PeiUsbDevice->TransactionTranslator;
+ }
+ //<(EIP28255+)
+ if ( IsPortLowSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ NewPeiUsbDevice->DeviceSpeed = USB_SLOW_SPEED_DEVICE;
+ }
+
+ if ( IsPortHighSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ NewPeiUsbDevice->DeviceSpeed = USB_HIGH_SPEED_DEVICE;
+ }
+
+ if ( IsPortSuperSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ NewPeiUsbDevice->DeviceSpeed = USB_SUPER_SPEED_DEVICE;
+ }
+
+ //
+ // Configure that Usb Device
+ //
+ Status = PeiConfigureUsbDevice( PeiServices,
+ NewPeiUsbDevice, Port, CurrentAddress );
+
+ if ( EFI_ERROR( Status ) ) {
+ PeiHubClearPortFeature( PeiServices, UsbIoPpi,
+ Port, EfiUsbPortEnable );
+ continue;
+ }
+
+ Status = (**PeiServices).InstallPpi( PeiServices,
+ &NewPeiUsbDevice->UsbIoPpiList );
+
+ if (NewPeiUsbDevice->InterfaceDesc->InterfaceClass
+ == BASE_CLASS_HUB)
+ {
+ NewPeiUsbDevice->IsHub = 0x1;
+ NewPeiUsbDevice->HubDepth = PeiUsbDevice->HubDepth + 1;
+
+ Status = PeiDoHubConfig( PeiServices,
+ NewPeiUsbDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ PeiHubEnumeration( PeiServices, NewPeiUsbDevice,
+ CurrentAddress );
+ }
+ }
+
+ }
+ }
+
+ if (PortChanged) {
+ break;
+ }
+ StallPpi->Stall( PeiServices, StallPpi, 50000 );
+
+ } while (Delay--);
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC
+EFI_STATUS PeiUsbEnumeration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi )
+{
+ UINT8 NumOfRootPort;
+ EFI_STATUS Status;
+ UINT8 Port;
+ EFI_USB_PORT_STATUS PortStatus;
+ PEI_USB_DEVICE *PeiUsbDevice;
+ UINT8 *AllocateAddress;
+ UINT8 CurrentAddress;
+ PEI_STALL_PPI *PeiStall;
+
+ (**PeiServices).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+
+ CurrentAddress = 0;
+ UsbHcPpi->GetRootHubPortNumber(
+ PeiServices,
+ UsbHcPpi,
+ (UINT8 *) &NumOfRootPort
+ );
+
+
+ for (Port = 1; Port <= NumOfRootPort; Port++) {
+ //
+ // First get root port status to detect changes happen
+ //
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ &PortStatus
+ );
+
+ if ( IsPortConnectChange( PortStatus.PortChangeStatus ) ) {
+
+ //
+ // Changes happen, first clear this change status
+ //
+ UsbHcPpi->ClearRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ EfiUsbPortConnectChange
+ );
+
+ if ( IsPortConnect( PortStatus.PortStatus ) ) {
+
+ if (IsPortEnable(PortStatus.PortStatus) == FALSE) {
+ //
+ // First reset and enable this port
+ //
+ ResetRootPort( PeiServices, UsbHcPpi, Port );
+
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ &PortStatus
+ );
+ }
+
+ //
+ // Connect change happen
+ //
+ Status = (*PeiServices)->AllocatePool(
+ PeiServices,
+ sizeof(PEI_USB_DEVICE),
+ &AllocateAddress
+ );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ PeiUsbDevice = (PEI_USB_DEVICE *) ( (UINTN) AllocateAddress );
+ ZeroMem( PeiUsbDevice, sizeof(PEI_USB_DEVICE) );
+
+ PeiUsbDevice->Signature = PEI_USB_DEVICE_SIGNATURE;
+ PeiUsbDevice->DeviceAddress = 0;
+ PeiUsbDevice->MaxPacketSize0 = 8;
+ PeiUsbDevice->DataToggle = 0;
+ PeiUsbDevice->UsbIoPpi = mUsbIoPpi;
+ PeiUsbDevice->UsbIoPpiList = mUsbIoPpiList;
+ PeiUsbDevice->UsbIoPpiList.Ppi = &PeiUsbDevice->UsbIoPpi;
+ PeiUsbDevice->UsbHcPpi = UsbHcPpi;
+ PeiUsbDevice->DeviceSpeed = USB_FULL_SPEED_DEVICE;
+ PeiUsbDevice->IsHub = 0x0;
+ PeiUsbDevice->DownStreamPortNo = 0x0;
+ PeiUsbDevice->TransactionTranslator = 0x0;
+ PeiUsbDevice->HubDepth = 0x0;
+
+ if ( IsPortLowSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ PeiUsbDevice->DeviceSpeed = USB_SLOW_SPEED_DEVICE;
+ }
+
+ if ( IsPortHighSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ PeiUsbDevice->DeviceSpeed = USB_HIGH_SPEED_DEVICE;
+ }
+
+ if ( IsPortSuperSpeedDeviceAttached( PortStatus.PortStatus ) )
+ {
+ PeiUsbDevice->DeviceSpeed = USB_SUPER_SPEED_DEVICE;
+ }
+
+ //
+ // Delay some times to enable usb devices to initiate.
+ //
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 5000
+ );
+
+ //
+ // Configure that Usb Device
+ //
+ Status = PeiConfigureUsbDevice(
+ PeiServices,
+ PeiUsbDevice,
+ Port,
+ &CurrentAddress
+ );
+
+ if ( EFI_ERROR( Status ) ) {
+ UsbHcPpi->ClearRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ Port,
+ EfiUsbPortEnable
+ );
+ continue;
+ }
+
+ Status = (**PeiServices).InstallPpi(
+ PeiServices,
+ &PeiUsbDevice->UsbIoPpiList
+ );
+
+ if (PeiUsbDevice->InterfaceDesc->InterfaceClass
+ == BASE_CLASS_HUB)
+ {
+ PeiUsbDevice->IsHub = 0x1;
+
+ Status = PeiDoHubConfig( PeiServices, PeiUsbDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ PeiHubEnumeration( PeiServices, PeiUsbDevice,
+ &CurrentAddress );
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC EFI_STATUS PeiConfigureUsbDevice (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *PeiUsbDevice,
+ IN UINT8 Port,
+ IN OUT UINT8 *DeviceAddress )
+{
+ EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor;
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi;
+ UINT8 i;
+ PEI_STALL_PPI *StallPpi = NULL;
+ UINT8 Retry = 2;
+
+ ( **PeiServices ).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+
+ if (PeiUsbDevice->UsbHcPpi->PreConfigureDevice != NULL) {
+ Status = PeiUsbDevice->UsbHcPpi->PreConfigureDevice( PeiServices,
+ PeiUsbDevice->UsbHcPpi, Port, PeiUsbDevice->DeviceSpeed,
+ PeiUsbDevice->TransactionTranslator);
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ }
+
+ UsbIoPpi = &PeiUsbDevice->UsbIoPpi;
+
+ //-----------------------------------------------------------------------
+ // Try 5 times to read the first 8 bytes to determine the size
+ for (i = 0; i < 5; i++) {
+ Status = PeiUsbGetDescriptor( PeiServices,
+ UsbIoPpi,
+ SET_DESCRIPTOR_TYPE( USB_DT_DEVICE ), // Value = Type << 8 | Index
+ 0, // Index
+ 8, // DescriptorLength
+ &DeviceDescriptor );
+ if ( !EFI_ERROR( Status ) ) {
+ break;
+ }
+ StallPpi->Stall( PeiServices, StallPpi, 100 * 1000 ); // 100msec delay
+ }
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //-----------------------------------------------------------------------
+ // Set MaxPacketSize0 = 0x40 if packet size is not specified
+ PeiUsbDevice->MaxPacketSize0 = (DeviceDescriptor.MaxPacketSize0)
+ ? DeviceDescriptor.MaxPacketSize0
+ : 0x40;
+
+
+ //-----------------------------------------------------------------------
+ // Get the entire USB device descriptor
+ StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay
+ Status = PeiUsbGetDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ SET_DESCRIPTOR_TYPE( USB_DT_DEVICE ), // Value = Type << 8 | Index
+ 0, // Index
+ sizeof(EFI_USB_DEVICE_DESCRIPTOR), // DescriptorLength
+ &DeviceDescriptor );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //-----------------------------------------------------------------------
+ // Get its default configuration and its first interface
+ StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay
+ Status = PeiUsbGetAllConfiguration(
+ PeiServices,
+ PeiUsbDevice );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ //-----------------------------------------------------------------------
+ // Set the device's address
+ StallPpi->Stall( PeiServices, StallPpi, 10 * 1000 ); // 10msec delay
+ (*DeviceAddress)++;
+ Status = PeiUsbSetDeviceAddress(
+ PeiServices,
+ UsbIoPpi,
+ *DeviceAddress );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ PeiUsbDevice->DeviceAddress = *DeviceAddress;
+
+
+ StallPpi->Stall( PeiServices, StallPpi, 200 * 1000 ); // 200msec delay
+
+ Status = PeiUsbSetConfiguration(
+ PeiServices,
+ UsbIoPpi );
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+STATIC EFI_STATUS PeiUsbGetAllConfiguration (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_DEVICE *Device )
+{
+ EFI_USB_CONFIG_DESCRIPTOR ConfigDesc = {0};
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndPointDesc = NULL; //(EIP32503+)
+ EFI_STATUS Status;
+ PEI_USB_IO_PPI *UsbIoPpi = &Device->UsbIoPpi;
+ UINTN i;
+ UINT8 *LastAddress = 0;
+
+
+ // Here we are parsing the descriptors for the device
+ // configurations where the hierarchy of descriptors
+ // is as follows:
+ //
+ // +----------------+
+ // | Configuration1 |
+ // +----------------+
+ // | +------------+
+ // +---------| Interface1 |----+------------------+
+ // | +------------+ | |
+ // | +-----------+ +-------------+
+ // | | Endpoint1 | ... | EndpointMax |
+ // | +-----------+ +-------------+
+ // | :
+ // | :
+ // | :
+ // |
+ // | +--------------+
+ // +---------| InterfaceMax |----+------------------+
+ // +--------------+ | |
+ // : +-----------+ +-------------+
+ // : | Endpoint1 | ... | EndpointMax |
+ // +-----------+ +-------------+
+ // +------------------+
+ // | ConfigurationMax |
+ // +------------------+
+ // | +------------+
+ // +---------| Interface1 |----+------------------+
+ // | +------------+ | |
+ // | +-----------+ +-------------+
+ // | | Endpoint1 | ... | EndpointMax |
+ // | +-----------+ +-------------+
+ // | :
+ // | :
+ // | :
+ // | +--------------+
+ // +---------| InterfaceMax |----+------------------+
+ // +--------------+ | |
+ // +-----------+ +-------------+
+ // | Endpoint1 | ... | EndpointMax |
+ // +-----------+ +-------------+
+
+
+ //-------------------------------------------------------------
+ // Fortunately, we are only interested in the first/default
+ // configuration and its first/default interface, so life is
+ // simple!
+ //-------------------------------------------------------------
+
+ //-------------------------------------------------------------
+ // First get the device's 9-byte configuration descriptor to
+ // determine the length of all descriptors
+ Status = PeiUsbGetDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ USB_DT_CONFIG << 8,
+ 0,
+ 9,
+ &ConfigDesc );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+
+ Status = (*PeiServices)->AllocatePool( PeiServices,
+ ConfigDesc.TotalLength, &Device->ConfigurationData );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ //-------------------------------------------------------------
+ // Get all the descriptors for this configuration using
+ // TotalLength from the first 9 bytes previously read.
+ // Then, save the Configuration descriptor into the
+ // device management structure.
+ Status = PeiUsbGetDescriptor(
+ PeiServices,
+ UsbIoPpi,
+ USB_DT_CONFIG << 8,
+ 0,
+ ConfigDesc.TotalLength,
+ (VOID *) Device->ConfigurationData );
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ Device->ConfigDesc =
+ (EFI_USB_CONFIG_DESCRIPTOR *) Device->ConfigurationData;
+
+ LastAddress = Device->ConfigurationData +
+ Device->ConfigDesc->TotalLength - 1;
+
+ if (Device->UsbHcPpi->EnableEndpoints != NULL) {
+ Status = Device->UsbHcPpi->EnableEndpoints(PeiServices,
+ Device->UsbHcPpi, Device->ConfigurationData);
+
+ if ( EFI_ERROR( Status ) ) {
+ return Status;
+ }
+ }
+
+ //--------------------------------------------------------------
+ // Assume the Interface descriptor is directly after the
+ // configuration descriptor.
+ //--------------------------------------------------------------
+ Device->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *)
+ ( (UINT8 *) Device->ConfigDesc +
+ Device->ConfigDesc->Length );
+ //(EIP32503+)>
+ while ((UINT8 *)Device->InterfaceDesc < LastAddress &&
+ Device->InterfaceDesc->DescriptorType != USB_DT_INTERFACE)
+ {
+ Device->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *)
+ ( (UINT8 *) Device->InterfaceDesc +
+ Device->InterfaceDesc->Length );
+ }
+ //<(EIP32503+)
+ //--------------------------------------------------------------
+ // Assume the first Endpoint descriptor is directly after the
+ // Interface descriptor.
+ //--------------------------------------------------------------
+ //(EIP32503)>
+ EndPointDesc = (EFI_USB_ENDPOINT_DESCRIPTOR *)
+ ( (UINT8 *) Device->InterfaceDesc +
+ Device->InterfaceDesc->Length );
+
+ for (i = 0; i < Device->InterfaceDesc->NumEndpoints &&
+ (UINT8 *)EndPointDesc < LastAddress; )
+ {
+ if(EndPointDesc->DescriptorType == USB_DT_ENDPOINT)
+ {
+ Device->EndpointDesc[i++] = EndPointDesc;
+ }
+ EndPointDesc = (EFI_USB_ENDPOINT_DESCRIPTOR *)
+ ( (UINT8 *) EndPointDesc +
+ EndPointDesc->Length );
+ }
+ //<(EIP32503)
+ return EFI_SUCCESS;
+}
+
+
+//
+// Send reset signal over the given root hub port
+//
+VOID ResetRootPort (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi,
+ UINT8 PortNum )
+{
+ EFI_PEI_STALL_PPI *PeiStall;
+ EFI_USB_PORT_STATUS PortStatus;
+ UINT8 i;
+
+ ( **PeiServices ).LocatePpi(
+ PeiServices,
+ &gPeiStallPpiGuid,
+ 0,
+ NULL,
+ &PeiStall
+ );
+
+
+ //
+ // reset root port
+ //
+ UsbHcPpi->SetRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ EfiUsbPortReset
+ );
+
+ for (i = 0; i < 100; i++) {
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ &PortStatus
+ );
+
+ if ((PortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) != 0) {
+ break;
+ }
+
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 1 * 1000 // NVS - Changed to 10 msec (as per AMI USB Code)
+ );
+ }
+
+ if ((PortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0) {
+ return;
+ }
+
+ //
+ // clear reset root port
+ //
+ UsbHcPpi->ClearRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ EfiUsbPortResetChange
+ );
+
+
+ UsbHcPpi->GetRootHubPortStatus(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ &PortStatus
+ );
+
+ if ((PortStatus.PortChangeStatus & USB_PORT_STAT_ENABLE) == 0) {
+ //
+ // Set port enable
+ //
+ UsbHcPpi->SetRootHubPortFeature(
+ PeiServices,
+ UsbHcPpi,
+ PortNum,
+ EfiUsbPortEnable
+ );
+ PeiStall->Stall(
+ PeiServices,
+ PeiStall,
+ 100 * 1000 // NVS - Changed to 100msec as per AMI USB code
+ );
+ }
+
+ return;
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif
new file mode 100644
index 0000000..4eca72e
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbPeimSrc/UsbPeimSrc.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "UsbPeimSrc"
+ category = ModulePart
+ LocalRoot = "Core\EM\UsbRecovery\UsbPeimSrc\"
+ RefName = "UsbPeimSrc"
+[files]
+"HubPeim.c"
+"UsbIoPeim.c"
+"UsbPeim.c"
+[parts]
+"UsbIoPpi"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/UsbRecov.mak b/Core/EM/UsbRecovery/UsbRecov.mak
new file mode 100644
index 0000000..5cb7fea
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbRecov.mak
@@ -0,0 +1,457 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+#
+# $Header: /Alaska/SOURCE/Modules/USBRecovery/UsbRecov.mak 12 10/17/12 5:06a Roberthsu $
+#
+# $Revision: 12 $
+#
+# $Date: 10/17/12 5:06a $
+#
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/USBRecovery/UsbRecov.mak $
+#
+# 12 10/17/12 5:06a Roberthsu
+# [TAG] EIP77332
+# [Category] Improvement
+# [Description] Implement pei loadfirmware.
+# [Files] LoadFirmware.cif,LoadFirmware.sdl,LoadFirmware.mak,PeiRenesa
+# s.c,PeiRenesas.h,DxeRenesas.c,DxeRenesas.h,UsbRecov.mak
+#
+# 11 10/14/10 2:42p Olegi
+#
+# 10 10/11/10 4:51p Olegi
+# XHCI support added.
+#
+# 9 3/03/09 7:24p Olegi
+# Added EHCI support.
+#
+# 8 10/21/08 5:56p Michaela
+# Added EHCI-related fixes for issues
+# that may occur if EHCI is used before
+# USB Recovery is invoked:
+# Added SDL Tokens:
+# PEI_EHCI_PCI_BDFS and
+# PEI_EHCI_MEM_BASE_ADDRESSES.
+#
+# Removed/modified some debugging
+# development code:
+# Removed SDL Tokens:
+# USBR_DEBUG_SUPPORT and
+# USBR_SERIAL_PORT_AVAILABLE
+# Removed Elinks:
+# UsbRecoveryDebug_DIR and
+# $(BUILD_DIR)\UsbRecoveryDebugDxe.ffs
+# Modified SDL Token:
+# FORCE_RECOVERY to default value of 0.
+#
+# (See this module's Help documentation
+# for more information.)
+#
+# 7 7/29/08 5:50p Michaela
+# 1) Updated code to move most porting tasks to SDL
+# 2) Added more debug break points and improved interactive
+# debugging capability for when a serial port is not available.
+# 3) Updated help files
+#
+# 6 7/18/08 5:03p Michaela
+# 1 File-level debugging is now available
+# 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+# the keypress so that conditional debugging can
+# be dynamic (alphanumeric keys only)
+# 3 Added more function headers.
+# 4 Removed code that will never be used (I.e., Bala?).
+# 5 Moved typedef, contants and extern declarations
+# into header files.
+# 6 Now all controller blocks are enabled for SB700
+# (EHCI controllers route to companion controller
+# by default)
+# 7 Removed unused constants and typedefs n OhciPei.h
+# (also reorganized the file to make it more
+# readable.)
+# 8 Renamed many functions/variables according to
+# coding standard.
+# 9 Removed code initializing data structures for
+# periodic lists, as this is not needed.
+# 10 Removed the CONTROLLER_TYPE SDL token to
+# allow UHCI and OHCI controllers to supported
+# simultaneously. (modified MAKE files
+# accordingly)
+#
+# 5 7/10/08 6:33p Michaela
+# Updated to support OHCI controllers
+#
+# 4 8/17/07 4:29p Ambikas
+#
+# 3 3/28/07 3:06a Meenakshim
+# Removed dependency on core source files..Added amimapping file.
+#
+# 2 9/22/06 4:07p Sivagarn
+# - Initial Check-in
+# - Included Recovery code in Source
+# - Included appropriate headers for flies and functions
+# - Updated copyright messages
+# - Merged multiple MAK and SDL files into one MAK and SDL file
+# - Removed unnecessary files
+#
+#**********************************************************************
+
+
+#<AMI_FHDR_START>
+#-----------------------------------------------------------------------
+#
+# Name: UsbRecov.mak
+#
+# Description: Contains make script to build USB Recovery related
+# PEIM. This script file generates UhciPeiUsb, OhciPei,
+# UhcPeim, UsbPeim and UsbBotPeim
+#
+#-----------------------------------------------------------------------
+#<AMI_FHDR_END>
+
+# Define the target list based the RECOVERY_DEBUG_SUPPORT SDL token
+# which enables/disables generic USB console debugging routines.
+
+USB_RECOVERY_TARGETS = \
+ UsbBotPeimSrc
+
+all : $(USB_RECOVERY_TARGETS)
+
+
+#-----------------------------------------------------------------------
+# Build script for UhciPeiUsb.lib
+#-----------------------------------------------------------------------
+UhciPeiUsb : $(BUILD_DIR)\UhcipeiUsb.mak UhcipeiUsbBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UhcipeiUsb.mak
+
+UHCI_PEI_USB_MAK_DEPS = \
+ $(UhcipeiUsb_DIR)\UhcipeiUsb.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+UHCI_PEI_USB_CIF2MAK_ARGS = \
+ $(UhcipeiUsb_DIR)\UhcipeiUsb.cif \
+ $(CIF2MAK_DEFAULTS) \
+ $(UsbRecovery_DIR)\UsbRecovery.cif
+
+$(BUILD_DIR)\UhcipeiUsb.mak : $(UHCI_PEI_USB_MAK_DEPS)
+ $(CIF2MAK) $(UHCI_PEI_USB_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UhciPeiUsb.lib
+
+UHCI_PEI_USB_LIB_CFLAGS = $(CFLAGS) \
+ /I $(UhcipeiUsb_DIR) \
+ /I $(UsbRecovery_DIR)
+
+UHCI_PEI_USB_LIB_DEPS = \
+ $(AMIPEILIB)
+
+UhcipeiUsbBin : $(UHCI_PEI_USB_LIB_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\UhciPeiUsb.mak all\
+ GUID=6895F6F0-8879-45B8-A9D9-9639E532319E\
+ "CFLAGS=$(UHCI_PEI_USB_LIB_CFLAGS)"\
+ TYPE=PEI_LIBRARY
+
+
+#-----------------------------------------------------------------------
+# Build script for UhcPeim.lib
+#-----------------------------------------------------------------------
+UhcPeim : $(BUILD_DIR)\UhcPeim.mak UhcPeimBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UhcPeim.mak
+
+UHC_PEIM_MAK_DEPS = \
+ $(UhcPeimSrc_DIR)\UhcPeimSrc.cif \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+UHC_PEIM_CIF2MAK_ARGS = \
+ $(UhcPeimSrc_DIR)\UhcPeimSrc.cif \
+ $(CIF2MAK_DEFAULTS) \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+
+$(BUILD_DIR)\UhcPeim.mak : $(UHC_PEIM_MAK_DEPS)
+ $(CIF2MAK) $(UHC_PEIM_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UhcPeim.lib
+
+UHC_PEIM_LIB_CFLAGS= $(CFLAGS) \
+ /I $(UhcPeimSrc_DIR) \
+ /I $(UsbRecovery_DIR)
+
+UHC_PEIM_LIB_DEPS = \
+ $(AMIPEILIB)
+
+UhcPeimBin : $(UHC_PEIM_LIB_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\UhcPeim.mak all \
+ NAME=UhcPeim\
+ MAKEFILE=$(BUILD_DIR)\UhcPeim.mak \
+ "CFLAGS=$(UHC_PEIM_LIB_CFLAGS)" \
+ GUID=C463CEAC-FC57-4f36-88B7-356C750C3BCA \
+ TYPE=PEI_LIBRARY
+
+
+#-----------------------------------------------------------------------
+# Build script for OhciPei.lib
+#-----------------------------------------------------------------------
+OhciPei : $(BUILD_DIR)\OhciPei.mak OhcipeiBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate OhciPei.mak
+
+OHCI_PEI_MAK_DEPS = \
+ $(OhciPei_DIR)\OhciPei.cif \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+OHCI_PEI_CIF2MAK_ARGS = \
+ $(OhciPei_DIR)\OhciPei.cif \
+ $(CIF2MAK_DEFAULTS) \
+ $(UsbRecovery_DIR)\UsbRecovery.cif
+
+$(BUILD_DIR)\OhciPei.mak : $(OHCI_PEI_MAK_DEPS)
+ $(CIF2MAK) $(OHCI_PEI_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate OhciPei.lib
+
+OHCI_PEI_LIB_CFLAGS = \
+ $(CFLAGS) \
+ /I $(UsbRecovery_DIR) \
+ /D\"USBR_OHCI_CONTROLLER_PCI_ADDRESS=$(USBR_OHCI_CONTROLLER_PCI_ADDRESS)\" \
+ /D\"USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE=$(USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE)\"
+
+OHCI_PEI_LIB_DEPS = \
+ $(AMIPEILIB)
+
+OhciPeiBin : $(OHCI_PEI_LIB_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\OhciPei.mak all \
+ NAME=OhciPei \
+ MAKEFILE=$(BUILD_DIR)\OhciPei.mak \
+ GUID=52DAA304-DEB3-449b-AFB8-A88A54F28F95 \
+ "CFLAGS=$(OHCI_PEI_LIB_CFLAGS)" \
+ TYPE=PEI_LIBRARY
+
+
+#-----------------------------------------------------------------------
+# Build script for XhciPei.lib
+#-----------------------------------------------------------------------
+XhciPei : $(BUILD_DIR)\XhciPei.mak XhciPeiBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate XhciPei.mak
+
+XHCI_PEI_MAK_DEPS = \
+ $(XHCIPEI_DIR)\XhciPei.cif \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+XHCI_PEI_CIF2MAK_ARGS = \
+ $(XHCIPEI_DIR)\XhciPei.cif \
+ $(CIF2MAK_DEFAULTS) \
+ $(UsbRecovery_DIR)\UsbRecovery.cif
+
+$(BUILD_DIR)\XhciPei.mak : $(XHCI_PEI_MAK_DEPS)
+ $(CIF2MAK) $(XHCI_PEI_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate XhciPei.lib
+
+XHCI_PEI_LIB_CFLAGS = \
+ $(CFLAGS) \
+ /I $(UsbRecovery_DIR) \
+
+XHCI_PEI_LIB_DEPS = \
+ $(AMIPEILIB)
+
+XhciPeiBin : $(XHCI_PEI_LIB_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\XhciPei.mak all \
+ NAME=XhciPei \
+ MAKEFILE=$(BUILD_DIR)\XhciPei.mak \
+ GUID=45D68DB9-8B4E-48c0-99E9-F21F262DB653 \
+ "CFLAGS=$(XHCI_PEI_LIB_CFLAGS)" \
+ TYPE=PEI_LIBRARY
+
+#// {45D68DB9-8B4E-48c0-99E9-F21F262DB653}
+#0x45d68db9, 0x8b4e, 0x48c0, 0x99, 0xe9, 0xf2, 0x1f, 0x26, 0x2d, 0xb6, 0x53);
+
+#-----------------------------------------------------------------------
+# Build script for EhciPei.lib
+#-----------------------------------------------------------------------
+EhciPei : $(BUILD_DIR)\EhciPei.mak EhcipeiBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate EhciPei.mak
+
+EHCI_PEI_MAK_DEPS = \
+ $(EHCIPEI_DIR)\EhciPei.cif \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+EHCI_PEI_CIF2MAK_ARGS = \
+ $(EHCIPEI_DIR)\EhciPei.cif \
+ $(CIF2MAK_DEFAULTS) \
+ $(UsbRecovery_DIR)\UsbRecovery.cif
+
+$(BUILD_DIR)\EhciPei.mak : $(EHCI_PEI_MAK_DEPS)
+ $(CIF2MAK) $(EHCI_PEI_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate EhciPei.lib
+
+EHCI_PEI_LIB_CFLAGS = \
+ $(CFLAGS) \
+ /I $(UsbRecovery_DIR)
+
+EHCI_PEI_LIB_DEPS = \
+ $(AMIPEILIB)
+
+EhciPeiBin : $(EHCI_PEI_LIB_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\EhciPei.mak all \
+ NAME=EhciPei \
+ MAKEFILE=$(BUILD_DIR)\EhciPei.mak \
+ GUID=D56A4094-570F-4D3D-8F5F-8D8AA0B396CB \
+ "CFLAGS=$(EHCI_PEI_LIB_CFLAGS)" \
+ TYPE=PEI_LIBRARY
+
+#-----------------------------------------------------------------------
+# Build script for UsbPeim.lib
+#-----------------------------------------------------------------------
+UsbPeimSrc : $(BUILD_DIR)\UsbPeimSrc.mak UsbPeimSrcBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UsbPeimSrc.mak
+
+USB_PEIM_MAK_DEPS = \
+ $(UsbPeimSrc_DIR)\UsbPeimSrc.cif \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+USB_PEIM_CIF2MAK_ARGS = \
+ $(UsbPeimSrc_DIR)\UsbPeimSrc.cif \
+ $(CIF2MAK_DEFAULTS) \
+ $(UsbRecovery_DIR)\UsbRecovery.cif
+
+$(BUILD_DIR)\UsbPeimSrc.mak : $(USB_PEIM_MAK_DEPS)
+ $(CIF2MAK) $(USB_PEIM_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UsbPeim.lib
+
+USB_PEIM_LIB_CFLAGS = \
+ $(CFLAGS) \
+ /I $(UsbRecovery_DIR)
+
+USB_PEIM_LIB_DEPS = \
+ $(AMIPEILIB)
+
+UsbPeimSrcBin : $(USB_PEIM_LIB_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\UsbPeimSrc.mak all \
+ NAME=UsbPeim \
+ MAKEFILE=$(BUILD_DIR)\UsbPeimSrc.mak \
+ "CFLAGS=$(USB_PEIM_LIB_CFLAGS)" \
+ TYPE=PEI_LIBRARY
+
+
+#-----------------------------------------------------------------------
+# Build script for UsbBotPeim.ffs
+#-----------------------------------------------------------------------
+UsbBotPeimSrc: $(BUILD_DIR)\UsbBotPeimSrc.mak UsbBotPeimSrcBin
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UsbPeimSrc.mak using Cif2Mak.exe
+
+USB_BOT_PEIM_MAK_DEPS = \
+ $(UsbBotPeimSrc_DIR)\UsbBotPeim.cif \
+ $(UsbRecovery_DIR)\UsbRecovery.cif \
+ $(UsbRecovery_DIR)\UsbRecov.mak \
+ $(BUILD_RULES)
+
+USB_BOT_PEIM_CIF2MAK_ARGS = \
+ $(UsbBotPeimSrc_DIR)\UsbBotPeim.cif \
+ $(CIF2MAK_DEFAULTS)
+
+$(BUILD_DIR)\UsbBotPeimSrc.mak : $(USB_BOT_PEIM_MAK_DEPS)
+ $(CIF2MAK) $(USB_BOT_PEIM_CIF2MAK_ARGS)
+
+#~~~~~~~~~~~~~~~~~~~~~~~ Generate UsbBotPeim.ffs
+
+USB_BOT_PEIM_FFS_CFLAGS= \
+ $(CFLAGS) \
+ /I $(UsbBotPeimSrc_DIR) \
+ /I $(UsbRecovery_DIR) \
+ /I $(UhcPeimSrc_DIR) \
+ /I $(UhcipeiUsb_DIR) \
+ /I $(UsbPeimSrc_DIR) \
+ /I $(OhciPei_DIR) \
+ /I $(EHCIPEI_DIR) \
+ /I $(XHCIPEI_DIR)
+
+$(BUILD_DIR)\UhcPeim.lib : UhcPeim
+$(BUILD_DIR)\UsbPeim.lib : UsbPeimSrc
+$(BUILD_DIR)\UhcipeiUsb.lib : UhcipeiUsb
+$(BUILD_DIR)\OhciPei.lib : OhciPei
+$(BUILD_DIR)\EhciPei.lib : EhciPei
+$(BUILD_DIR)\XhciPei.lib : XhciPei
+
+USB_BOT_PEIM_FFS_DEPS = \
+ $(AMIPEILIB) \
+ $(BUILD_DIR)\UsbPeim.lib \
+!if $(PEI_UHCI_SUPPORT)
+ $(BUILD_DIR)\UhcPeim.lib \
+ $(BUILD_DIR)\UhcipeiUsb.lib \
+!endif
+!if $(PEI_OHCI_SUPPORT)
+ $(BUILD_DIR)\OhciPei.lib \
+!endif
+!if $(PEI_EHCI_SUPPORT)
+ $(BUILD_DIR)\EhciPei.lib \
+!endif
+!if $(PEI_XHCI_SUPPORT)
+ $(BUILD_DIR)\XhciPei.lib \
+!endif
+
+UsbBotPeimSrcBin : $(USB_BOT_PEIM_FFS_DEPS)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS) \
+ /f $(BUILD_DIR)\UsbBotPeimSrc.mak all \
+ NAME=UsbBotPeim \
+ MAKEFILE=$(BUILD_DIR)\UsbBotPeimSrc.mak \
+ GUID=8401A046-6F70-4505-8471-7015B40355E3 \
+ ENTRY_POINT=PeimInitializeUsbBot \
+ "CFLAGS=$(USB_BOT_PEIM_FFS_CFLAGS)" \
+ DEPEX1=$(UsbBotPeimSrc_DIR)\UsbBotPeim.dxs DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM \
+ COMPRESS=1\
+ "INIT_LIST=$(BeforeUsbRecovery)"
+
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
diff --git a/Core/EM/UsbRecovery/UsbRecov.sdl b/Core/EM/UsbRecovery/UsbRecov.sdl
new file mode 100644
index 0000000..681c70d
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbRecov.sdl
@@ -0,0 +1,237 @@
+TOKEN
+ Name = "UsbRecov_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UsbRecovery support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "PEI_UHCI_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable UHCI Controller support for USB recovery"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_OHCI_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable OhciPei support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_EHCI_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable EhciPei support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_XHCI_SUPPORT"
+ Value = "0"
+ Help = "Main switch to enable XhciPei support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_UHCI_IOBASE"
+ Value = "0x4000"
+ Help = "IO Base Address for UHCI Controller during PEI phase"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_UHCI_PCI_DEVICES"
+ Value = "{0x1D0000, 0x1D0100, 0x1D0200, 0x1D0300, 0x1A0000, 0x1A0100}"
+ Help = "List of supported UHCI controllers in the following format: {devfunc1, devfunc2,...,devfuncN}\devfunc represents the location of UHCI controller on PCI bus: dev = Bus << 24 + Dev << 16 + Func << 8. Value followed by dev is the PCI device interface, for UHCI it must be 0.\Note: number of entries {devfunc} must not be less than a number of supported UHCI controllers specified in USB_UHCI token."
+ TokenType = Expression
+ TargetH = Yes
+ Token = "PEI_UHCI_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "PEI_UHCI_PCI_DEVICES"
+ Value = "{0}"
+ Help = "Default value if not using UHCI controller"
+ TokenType = Expression
+ TargetH = Yes
+ Token = "PEI_UHCI_SUPPORT" "=" "0"
+End
+
+TOKEN
+ Name = "PEI_EHCI_PCI_BDFS"
+ Value = "{0x1A0700, 0x1D0700}"
+ Help = "List of supported EHCI controllers in the following format: {devfunc1, devfunc2,...,devfuncN}\devfunc represents the location of EHCI controller on PCI bus: dev = Bus << 24 + Dev << 16 + Func << 8. Value followed by dev is the PCI device interface, for EHCI it must be 0.\Note: number of entries {devfunc} must not be less than a number of supported EHCI controllers specified in PEI_NUM_EHCI token."
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_EHCI_MEM_BASE_ADDRESSES"
+ Value = "{0xDFFFF000, 0xDFFFFC00}"
+ Help = "List of base addresses for the respective EHCI controllers specified by PEI_EHCI_PCI_BDFS"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_OHCI_IOBASE"
+ Value = "0xFC087000"
+ Help = "Memory Mapped IO Base Address for first Recovery module OHCI Controller during PEI phase"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_XHCI_MMIOBASE"
+ Value = "0xFE400000"
+ Help = "MMIO Base Address for first XHCI Controller during PEI phase"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_XHCI_CONTROLLER_PCI_ADDRESS"
+ Value = "{0x1, 0x0, 0x0},"
+ Help = "Default value if XHCI controllers are not supported"
+ Token = "PEI_XHCI_SUPPORT" "=" "1"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PEI_XHCI_CONTROLLER_PCI_REGISTER_VALUES"
+ Value = "{0,0x1c,0,0x19,8,1,0},{0,0x1c,0,0x1a,8,1,0},{0,0x1c,0,0x20,16,0xfe40,0},{0,0x1c,0,0x22,16,0xfe40,0},{0,0x1c,0,4,8,6,0},"
+ Help = "Enable PCIe slot by programming bridge with the secondary/subordinate bus number and memory window.\Information format (AccessWidth is decimal), with a comma at the end:\ {Bus, Device, Function, Register, AccessWidth, BitsToSet, BitsToClear},"
+ Token = "PEI_XHCI_SUPPORT" "=" "1"
+ TokenType = Expression
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FORCE_RECOVERY"
+ Value = "0"
+ Help = "Force recovery execution by forcing BootMode = BOOT_IN_RECOVERY_MODE in SbPei.c"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+ELINK
+ Name = "USBR_OHCI_CONTROLLER_PCI_ADDRESS"
+ Help = "Specifies the location of supported OHCI controllers on the PCI bus. Use the following format with hexadecimal values, with a comma at the end: \ {bus, device, function},"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{0x0, 0x0, 0x0},"
+ Parent = "USBR_OHCI_CONTROLLER_PCI_ADDRESS"
+ InvokeOrder = AfterParent
+ Help = "Default value if OHCI controllers are not supported"
+ Token = "PEI_OHCI_SUPPORT" "=" "0"
+End
+
+
+ELINK
+ Name = "USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE"
+ Help = "Specifies the PCI register values to be programmed for each of the supported OHCI controllers specified by OHCI_CONTROLLER_PCI_ADDRESS. Use the following format with hexadecimal values (AccessWidth is decimal), with a comma at the end:\ {AccessWidth, Register, BitsToSet, BitsToClear},"
+ InvokeOrder = ReplaceParent
+End
+
+ELINK
+ Name = "{ 0, 0, 0, 0 },"
+ Parent = "USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE"
+ InvokeOrder = AfterParent
+ Help = "Default value if OHCI controllers are not supported"
+ Token = "PEI_OHCI_SUPPORT" "=" "0"
+End
+
+ELINK
+ Name = "{ 32, 0x4, 0x6, 0x0 },"
+ Parent = "USBR_OHCI_CONTROLLER_PCI_REGISTER_VALUE"
+ Help = "Enable bus mastering and MMIO space (this register is typically programmed for all chipsets. Priority is set to a large number to ensure it gets updated last.)"
+ InvokeOrder = AfterParent
+ Priority = 255
+ Token = "PEI_OHCI_SUPPORT" "=" "1"
+End
+
+PATH
+ Name = "UsbRecovery_DIR"
+End
+
+PATH
+ Name = "UHCIPEIUSB"
+ Path = "$(UsbRecovery_DIR)\UhciPeiUsb"
+End
+
+PATH
+ Name = "UhcipeiUsb_DIR"
+ Path = "$(UsbRecovery_DIR)\UhciPeiUsb"
+End
+
+PATH
+ Name = "OHCIPEI"
+ Path = "$(UsbRecovery_DIR)\OhciPei"
+End
+
+PATH
+ Name = "OhciPei_DIR"
+ Path = "$(UsbRecovery_DIR)\OhciPei"
+End
+
+PATH
+ Name = "EHCIPEI_DIR"
+ Path = "$(UsbRecovery_DIR)\EhciPei"
+End
+
+PATH
+ Name = "XHCIPEI_DIR"
+ Path = "$(UsbRecovery_DIR)\XhciPei"
+End
+
+PATH
+ Name = "UhcPeimSrc_DIR"
+ Path = "$(UsbRecovery_DIR)\UhcPeimSrc"
+End
+
+PATH
+ Name = "UsbPeimSrc_DIR"
+ Path = "$(UsbRecovery_DIR)\UsbPeimSrc"
+End
+
+PATH
+ Name = "UsbBotPeimSrc_DIR"
+ Path = "$(UsbRecovery_DIR)\UsbBotPeimSrc"
+ Help = "UsbBotPeimSrc file source directory"
+End
+
+MODULE
+ Help = "Includes UsbRecov.mak to Project"
+ File = "UsbRecov.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\UsbBotPeim.ffs"
+ Parent = "FV_BB"
+ InvokeOrder = AfterParent
+ Token = "UsbRecov_SUPPORT" "=" "1"
+End
+
+
+
+
diff --git a/Core/EM/UsbRecovery/UsbRecovery.cif b/Core/EM/UsbRecovery/UsbRecovery.cif
new file mode 100644
index 0000000..91d1795
--- /dev/null
+++ b/Core/EM/UsbRecovery/UsbRecovery.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "UsbRecovery"
+ category = eModule
+ LocalRoot = "Core\em\UsbRecovery\"
+ RefName = "UsbRecovery"
+[files]
+"UsbRecov.sdl"
+"UsbRecov.mak"
+"UsbPeim.h"
+"HubPeim.h"
+"PeiUsbLib.c"
+"PeiUsbLib.h"
+"usb.h"
+"USBRecoverySrc.chm"
+"AmiMapping.h"
+[parts]
+"UhciPeiUsb"
+"OhciPei"
+"EhciPei"
+"XhciPei"
+"UhcPeimSrc"
+"UsbPeimSrc"
+"UsbBotPeimSrc"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/XhciPEI/XhciPei.c b/Core/EM/UsbRecovery/XhciPEI/XhciPei.c
new file mode 100644
index 0000000..ae926ca
--- /dev/null
+++ b/Core/EM/UsbRecovery/XhciPEI/XhciPei.c
@@ -0,0 +1,2314 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/XhciPei.c 10 11/24/12 5:45a Ryanchou $
+//
+// $Revision: 10 $
+//
+// $Date: 11/24/12 5:45a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/XhciPei.c $
+//
+// 10 11/24/12 5:45a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 9 4/24/12 10:16p Wilsonlee
+// [TAG] EIP75547
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Xhci recovery funtion failed when SS devices on USB 3.0
+// port.
+// [RootCause] The SS device connected to USB2 port.
+// [Solution] Reset the USB2 port when initial xhci controller, then the
+// SS device reconnect to USB3 port.
+// [Files] XhciPei.c, XhciPei.h
+//
+// 8 4/12/11 12:00a Rameshr
+// [TAG]- EIP 57444
+// [Category]-IMPROVEMENT
+// [Description]- PI1.1 Support.
+// [Files]- OhciPeiboard.c,Xhcipei.c, Peiusblib.c
+//
+// 7 1/18/11 1:08a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 6 1/17/11 7:08a Ryanchou
+// [TAG] EIP48013
+// [Category] Improvement
+// [Description] Use 32 or 64 byte Context data structures dynamically.
+// [Files] XhciPei.c, XhciPei.h
+//
+// 5 10/27/10 11:27a Olegi
+// [TAG] EIP46147
+// [Category] Bug Fix
+//
+// 4 10/20/10 10:44a Olegi
+// [TAG] EIP46492
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TdSize variable should be declared as a 32bit integer
+// instead of a 8bit one.
+//
+// 3 10/14/10 3:57p Olegi
+// Added code that check for PCI device presence.
+//
+// 2 10/12/10 5:57p Olegi
+// Added (UINTN) typecast when converting pointers to UINT64. Without it
+// pointers that have BIT31 will have bits 32..63 set.
+//
+// 1 10/11/10 4:53p Olegi
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: XhciPei.c
+//
+// Description:
+// This file is the main source file for the xHCI PEI USB recovery module.
+// Its entry point at XhciPeiUsbEntryPoint will be executed from the
+// UsbRecoveryInitialize INIT_LIST.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiPeiLib.h>
+#include "XhciPei.h"
+#include <PPI\stall.h>
+#include "token.h"
+#include "pci.h"
+#include "usbpeim.h"
+
+PCI_BUS_DEV_FUNCTION gXhciControllerPciTable[] = {PEI_XHCI_CONTROLLER_PCI_ADDRESS {0,0,0}};
+UINT16 gXhciControllerCount = \
+ sizeof(gXhciControllerPciTable) / sizeof(PCI_BUS_DEV_FUNCTION) - 1;
+
+PCI_DEV_REGISTER_VALUE gPeiXhciInitPciTable[] = {PEI_XHCI_CONTROLLER_PCI_REGISTER_VALUES {0,0,0,0,0,0,0}};
+UINT16 gPeiXhciInitPciTableCount = \
+ sizeof(gPeiXhciInitPciTable) / sizeof(PCI_DEV_REGISTER_VALUE) - 1;
+
+UINT8 gSlotBeingConfigured;
+
+#ifndef PI_SPECIFICATION_VERSION //old Core
+extern EFI_STATUS PciCfgModify(
+IN CONST EFI_PEI_SERVICES **PeiServices,
+IN EFI_PEI_PCI_CFG_PPI_WIDTH Width,
+IN UINT64 Address,
+IN UINTN SetBits,
+IN UINTN ClearBits
+);
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XhciPeiUsbEntryPoint
+//
+// Description:
+// This is the entry point into the XHCI initialization.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// -- EFI_FFS_FILE_HEADER pointer
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciPeiUsbEntryPoint (
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices )
+{
+
+ EFI_STATUS Status;
+ EFI_PEI_STALL_PPI *StallPpi;
+ UINT32 XhciBaseAddress = PEI_XHCI_MMIOBASE;
+ EFI_PHYSICAL_ADDRESS TempPtr;
+ USB3_CONTROLLER *Usb3Hc;
+ UINTN MemPages;
+ UINT8 ControllerIndex;
+ UINT8 PciDevIndex;
+ UINT8 CmdRegisterValue = 6;
+
+ //-------------------------------------------
+ // Initialize the EFI_PEI_STALL_PPI interface
+ //-------------------------------------------
+ Status = (**PeiServices).LocatePpi( PeiServices, &gPeiStallPpiGuid,
+ 0, NULL, &StallPpi );
+ if ( EFI_ERROR( Status ) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ // Program PCI registers of the host controller and other relevant PCI
+ // devices (e.g. bridges that enable this host).
+
+ for (PciDevIndex = 0; PciDevIndex < gPeiXhciInitPciTableCount; PciDevIndex++) {
+
+ EFI_PEI_PCI_CFG_PPI_WIDTH Width;
+
+ switch (gPeiXhciInitPciTable[PciDevIndex].Size) {
+ case 8: Width = EfiPeiPciCfgWidthUint8; break;
+ case 16: Width = EfiPeiPciCfgWidthUint16; break;
+ case 32: Width = EfiPeiPciCfgWidthUint32; break;
+ case 64: Width = EfiPeiPciCfgWidthUint64; break;
+ default: continue;
+ }
+
+ Status = PciCfgModify(
+ PeiServices,
+ Width,
+ PEI_PCI_CFG_ADDRESS(
+ gPeiXhciInitPciTable[PciDevIndex].Bus,
+ gPeiXhciInitPciTable[PciDevIndex].Device,
+ gPeiXhciInitPciTable[PciDevIndex].Function,
+ gPeiXhciInitPciTable[PciDevIndex].Register
+ ),
+ gPeiXhciInitPciTable[PciDevIndex].SetBits,
+ gPeiXhciInitPciTable[PciDevIndex].ClearBits);
+ }
+
+ for (ControllerIndex = 0; ControllerIndex < gXhciControllerCount;
+ ControllerIndex++, XhciBaseAddress+=0x10000)
+ {
+ UINT16 Vid;
+ UINT16 Did;
+
+ // Get VID/DID, see if controller is visible on PCI
+ (*PeiServices)->PciCfg->Read(PeiServices,(*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint16, XHCI_PCI_ADDRESS( ControllerIndex, PCI_VID ),&Vid);
+ if (Vid == 0xffff) continue; // Controller not present
+
+ (*PeiServices)->PciCfg->Read(PeiServices,(*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint16, XHCI_PCI_ADDRESS( ControllerIndex, PCI_DID ), &Did);
+
+ //----------------------------------------------------------
+ // Allocate USB3_CONTROLLER object that holds all necessary
+ // information for the Host Controller operational registers
+ // for each controller. Initialze the controller and setup
+ // data structures, get it ready for operation.
+ //----------------------------------------------------------
+ MemPages = sizeof(USB3_CONTROLLER) / 0x1000 + 1;
+ Status = (**PeiServices).AllocatePages(PeiServices,
+ EfiConventionalMemory,
+ MemPages,
+ &TempPtr);
+ if (EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+
+ (**PeiServices).SetMem((VOID*)TempPtr, MemPages*4096, 0); // Clear allocated memory
+
+ Usb3Hc = (USB3_CONTROLLER*)(UINTN)TempPtr;
+
+ //----------------------------------------------------------
+ // USB3 controller data area is allocated, start stuff it in
+ // with the useful filling in with the useful data.
+ //----------------------------------------------------------
+
+ // Program BAR
+ (*PeiServices)->PciCfg->Write(PeiServices,(*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint32,
+ XHCI_PCI_ADDRESS( ControllerIndex, PCI_BAR0 ),
+ &XhciBaseAddress
+ );
+ Usb3Hc->CapRegs = (XHCI_HC_CAP_REGS*)(UINTN)XhciBaseAddress;
+
+ // Enable MMIO access and BM
+ (*PeiServices)->PciCfg->Write(PeiServices,(*PeiServices)->PciCfg,
+ EfiPeiPciCfgWidthUint8,
+ XHCI_PCI_ADDRESS( ControllerIndex, PCI_CMD ),
+ &CmdRegisterValue
+ );
+
+ (UINT8)(UINTN)Usb3Hc->CapRegs &= ~(0x7F); // Clear attributes
+
+ Usb3Hc->Did = Did;
+ Usb3Hc->Vid = Vid;
+ Usb3Hc->Access64 = Usb3Hc->CapRegs->HcParams.Ac64;
+ Usb3Hc->HciVersion = Usb3Hc->CapRegs->HciVersion;
+ Usb3Hc->MaxPorts = Usb3Hc->CapRegs->HcParams1.MaxPorts;
+ Usb3Hc->OpRegs = (XHCI_HC_OP_REGS*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->CapRegs->CapLength);
+ Usb3Hc->PageSize4K = Usb3Hc->OpRegs->PageSize;
+ Usb3Hc->ContextSize = 0x20 << Usb3Hc->CapRegs->HcParams.Csz;
+ Usb3Hc->MaxIntrs = Usb3Hc->CapRegs->HcParams1.MaxIntrs; // Get maximum number of interrupters
+ Usb3Hc->DbOffset = Usb3Hc->CapRegs->DbOff; // Doorbell offset
+ Usb3Hc->MaxSlots = PEI_XHCI_MAX_SLOTS;
+
+ Usb3Hc->InputContext = (VOID*)&Usb3Hc->InpCtx;
+ Usb3Hc->XfrRings = Usb3Hc->XfrRing;
+ Usb3Hc->XfrTrbs = (UINTN)Usb3Hc->XfrTrb;
+ Usb3Hc->DeviceContext = (VOID*)Usb3Hc->DevCtx;
+
+ XhciExtCapParser(PeiServices, Usb3Hc); //(EIP75547+)
+
+ PEI_TRACE ((-1, PeiServices, "USB recovery xHCI[%d] controller initialization details:\n", ControllerIndex));
+ PEI_TRACE ((-1, PeiServices, " PCI location: B%x/D%x/F%x, VID:DID = %x:%x, BAR0 = %x\n",
+ gXhciControllerPciTable[ControllerIndex].Bus,
+ gXhciControllerPciTable[ControllerIndex].Device,
+ gXhciControllerPciTable[ControllerIndex].Function,
+ Usb3Hc->Vid,
+ Usb3Hc->Did,
+ Usb3Hc->CapRegs
+ ));
+ PEI_TRACE((-1, PeiServices, " MaxSlots = %x, InputCtx %x, Device Ctx %x\n",
+ Usb3Hc->MaxSlots, (UINT8*)Usb3Hc->InputContext, (UINT8*)Usb3Hc->DeviceContext));
+
+ Usb3Hc->PeiServices = PeiServices;
+ Usb3Hc->CpuIoPpi = (*PeiServices)->CpuIo;
+ Usb3Hc->StallPpi = StallPpi;
+ Usb3Hc->PciCfgPpi = (*PeiServices)->PciCfg;
+
+ // Initialize the xHCI Controller for operation
+ Status = XhciInitHC(PeiServices, Usb3Hc, ControllerIndex);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+ if (EFI_ERROR(Status)) return Status;
+
+ // Setup PPI entry point
+ Usb3Hc->UsbHostControllerPpi.ControlTransfer = XhciHcControlTransfer;
+ Usb3Hc->UsbHostControllerPpi.BulkTransfer = XhciHcBulkTransfer;
+ Usb3Hc->UsbHostControllerPpi.GetRootHubPortNumber = XhciHcGetRootHubPortNumber;
+ Usb3Hc->UsbHostControllerPpi.GetRootHubPortStatus = XhciHcGetRootHubPortStatus;
+ Usb3Hc->UsbHostControllerPpi.SetRootHubPortFeature = XhciHcSetRootHubPortFeature;
+ Usb3Hc->UsbHostControllerPpi.ClearRootHubPortFeature = XhciHcClearRootHubPortFeature;
+ Usb3Hc->UsbHostControllerPpi.PreConfigureDevice = XhciHcPreConfigureDevice;
+ Usb3Hc->UsbHostControllerPpi.EnableEndpoints = XhciEnableEndpoints;
+
+ Usb3Hc->PpiDescriptor.Flags =(EFI_PEI_PPI_DESCRIPTOR_PPI |EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST);
+ Usb3Hc->PpiDescriptor.Guid = &gPeiUsbHostControllerPpiGuid;
+ Usb3Hc->PpiDescriptor.Ppi = &Usb3Hc->UsbHostControllerPpi;
+
+ Status = (**PeiServices).InstallPpi(PeiServices, &Usb3Hc->PpiDescriptor);
+ if (EFI_ERROR(Status)) return EFI_NOT_FOUND;
+
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XhciInitHC
+//
+// Description:
+// This function initializes xHCI controller registers and starts it.
+//
+// Input:
+// EFI_PEI_SERVICES **PeiServices
+// -- PEI_SERVICES pointer
+// USB3_CONTROLLER *Usb3Hc
+// -- XHCI controller data structure pointer
+// UINT8 ControllerIndex
+// -- 0-based index of the controller to be initialized
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful initialization completion
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciInitHC(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 ControllerIndex
+)
+{
+ XHCI_INTERRUPTER_REGS *Interrupter;
+ XHCI_ER_SEGMENT_ENTRY *Erst0Entry;
+ BOOLEAN PpSet = FALSE;
+ UINT8 PortNumber;
+ volatile XHCI_PORTSC *PortSC;
+ UINT32 CurrentPortOffset = 0;
+ UINT32 i;
+
+ // Wait controller ready
+ for (i = 0; i < 100; i++) {
+ if (Usb3Hc->OpRegs->UsbSts.Field.Cnr == 0) break;
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 1);
+ }
+ PEI_ASSERT(PeiServices, Usb3Hc->OpRegs->UsbSts.Field.Cnr == 0);
+ if (Usb3Hc->OpRegs->UsbSts.Field.Cnr) return EFI_DEVICE_ERROR;
+
+ // Check if the xHC is halted
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0)
+ {
+ Usb3Hc->OpRegs->UsbCmd.RunStop = 0;
+ // The xHC should halt within 16 ms. Section 5.4.1.1
+ for (i = 0; i < 16; i++) {
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 1);
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) break;
+ }
+ PEI_ASSERT(PeiServices, Usb3Hc->OpRegs->UsbSts.Field.HcHalted);
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0) return EFI_DEVICE_ERROR;
+ }
+
+ // Reset controller
+ Usb3Hc->OpRegs->UsbCmd.HcRst = 1;
+ for (i = 0; i < 400; i++) {
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 1);
+ if (Usb3Hc->OpRegs->UsbCmd.HcRst == 0) break;
+ }
+
+ PEI_ASSERT(PeiServices, Usb3Hc->OpRegs->UsbCmd.HcRst == 0);
+ if (Usb3Hc->OpRegs->UsbCmd.HcRst) return EFI_DEVICE_ERROR; // Controller can not be reset
+
+ // Wait controller ready
+ for (i = 0; i < 100; i++) {
+ if (Usb3Hc->OpRegs->UsbSts.Field.Cnr == 0) break;
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 1);
+ }
+ PEI_ASSERT(PeiServices, Usb3Hc->OpRegs->UsbSts.Field.Cnr == 0);
+ if (Usb3Hc->OpRegs->UsbSts.Field.Cnr) return EFI_DEVICE_ERROR;
+
+ Usb3Hc->RtRegs = (XHCI_HC_RT_REGS*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->CapRegs->RtsOff);
+ PEI_TRACE ((-1, PeiServices, "PEI_XHCI: RT registers are at %x\n", Usb3Hc->RtRegs));
+
+ Usb3Hc->OpRegs->Config = Usb3Hc->MaxSlots; // Max device slots enabled
+ Usb3Hc->DcbaaPtr = (XHCI_DCBAA*)Usb3Hc->Dcbaa;
+
+ XhciMmio64Write(Usb3Hc, (UINTN)&Usb3Hc->OpRegs->DcbAap, (UINT64)(UINTN)Usb3Hc->DcbaaPtr);
+
+ // Define the Command Ring Dequeue Pointer by programming the Command Ring
+ // Control Register (5.4.5) with a 64-bit address pointing to the starting
+ // address of the first TRB of the Command Ring.
+
+ // Initialize Command Ring Segment: Size TRBS_PER_SEGMENT*16, 64 Bytes aligned
+ XhciInitRing(&Usb3Hc->CmdRing, (UINTN)Usb3Hc->CommandRing, TRBS_PER_SEGMENT, TRUE);
+ PEI_TRACE ((-1, PeiServices, "CMD Ring is at %x\n", (UINTN)&Usb3Hc->CmdRing));
+
+ // Write CRCR HC register with the allocated address. Set Ring Cycle State to 1.
+ XhciMmio64Write(Usb3Hc, (UINTN)&Usb3Hc->OpRegs->Crcr,
+ (UINT64)(UINTN)Usb3Hc->CmdRing.Base + CRCR_RING_CYCLE_STATE);
+
+ // Initialize and assign Event Ring
+ XhciInitRing(&Usb3Hc->EvtRing, (UINTN)Usb3Hc->EventRing, TRBS_PER_SEGMENT, FALSE);
+ PEI_TRACE ((-1, PeiServices, "EVT Ring is at %x\n", (UINTN)&Usb3Hc->EvtRing));
+
+ // NOTE: This driver supports one Interrupter, hence it uses
+ // one Event Ring segment with TRBS_PER_SEGMENT TRBs in it.
+
+ // Initialize ERST[0]
+ Erst0Entry = &Usb3Hc->Erst;
+ Erst0Entry->RsBase = (UINT64)(UINTN)Usb3Hc->EvtRing.Base;
+ Erst0Entry->RsSize = TRBS_PER_SEGMENT;
+
+ Interrupter = Usb3Hc->RtRegs->IntRegs;
+
+ // Initialize Interrupter fields
+ Interrupter->Erstz = 1; // # of segments
+ // ER dequeue pointer
+ XhciMmio64Write(Usb3Hc, (UINTN)&Interrupter->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr);
+ // Seg Table location
+ XhciMmio64Write(Usb3Hc, (UINTN)&Interrupter->Erstba, (UINT64)(UINTN)Erst0Entry);
+ Interrupter->IMod = XHCI_IMODI; // Max interrupt rate
+ Interrupter->IMan |= 2; // Enable interrupt
+
+ PEI_TRACE((-1, PeiServices, "Transfer Rings structures start at %x\n", Usb3Hc->XfrRings));
+
+ // Set PortPower unless PowerPortControl indicates otherwise
+ if (Usb3Hc->CapRegs->HcParams.Ppc != 0) {
+ for (PortNumber = 0; PortNumber<Usb3Hc->MaxPorts;
+ PortNumber++, CurrentPortOffset+=0x10) {
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + CurrentPortOffset);
+ if (PortSC->Field.Pp == 0) {
+ PortSC->Field.Pp = 1; // Set port power
+ PpSet = TRUE;
+ }
+ }
+ if (PpSet) XHCI_FIXED_DELAY_MS(Usb3Hc, 20); // Wait for 20 ms, Section 5.4.8
+ }
+
+ Usb3Hc->OpRegs->UsbCmd.Inte = 1;
+ Usb3Hc->OpRegs->UsbCmd.RunStop = 1;
+
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 100);
+
+ XhciResetUsb2Port(PeiServices, Usb3Hc); //(EIP75547+)
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XhciHcPreConfigureDevice
+//
+// Description:
+// This function does preliminary device initialization: enables slot and
+// sets the address.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful pre-configuration completion
+// = EFI_DEVICE_ERROR on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciHcPreConfigureDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 Port,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 TransactionTranslator
+)
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ UINT8 *Device;
+ UINT8 *ParentHubDevice;
+ TRB_RING *XfrRing;
+ UINT8 Speed;
+ static UINT16 aMaxPacketSize[5] = {0, 8, 8, 64, 512};
+ EFI_STATUS Status;
+ UINT8 SlotId;
+ XHCI_INPUT_CONTROL_CONTEXT *CtlCtx;
+ XHCI_SLOT_CONTEXT *SlotCtx;
+ XHCI_SLOT_CONTEXT *ParentHubSlotCtx;
+ XHCI_EP_CONTEXT *Ep0Ctx;
+ UINT8 ParentHubSlotId;
+ UINT8 i;
+
+// XHCI_FIXED_DELAY_MS(Usb3Hc, 1000);
+
+ // Obtain device slot using Enable Slot command, 4.3.2, 4.6.3
+ Status = XhciExecuteCommand(PeiServices, Usb3Hc, XhciTEnableSlotCmd, &SlotId);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+ PEI_ASSERT(PeiServices, SlotId != 0);
+ if (Status != EFI_SUCCESS) return Status;
+
+ Device = (UINT8*)XhciGetDeviceContext(Usb3Hc, SlotId);
+
+ // Update DCBAA with the new device pointer (index = SlotId)
+ Usb3Hc->DcbaaPtr->DevCntxtAddr[SlotId-1] = (UINT64)(UINTN)Device;
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Slot[%d] enabled, device context at %x\n", SlotId, Device));
+
+ // Initialize data structures associated with the slot 4.3.3
+
+ // Zero the InputContext and DeviceContext
+ (**PeiServices).SetMem((UINT8*)Usb3Hc->InputContext, XHCI_INPUT_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+ (**PeiServices).SetMem(Device, XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ // Initialize the Input Control Context of the Input Context
+ // by setting the A0 and A1 flags to 1
+
+ CtlCtx = (XHCI_INPUT_CONTROL_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 0);
+ CtlCtx->AddContextFlags = BIT0 + BIT1;
+
+ // Initialize the Input Slot Context data structure
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 1);
+ SlotCtx->RouteString = 0;
+ SlotCtx->ContextEntries = 1;
+ if (TransactionTranslator == 0) {
+ SlotCtx->RootHubPort = Port;
+ } else {
+ Status = GetSlotId(Usb3Hc->DeviceMap, &ParentHubSlotId, (UINT8)(TransactionTranslator & 0xF));
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+ ParentHubDevice = (UINT8*)XhciGetDeviceContext(Usb3Hc, ParentHubSlotId);
+ ParentHubSlotCtx = (XHCI_SLOT_CONTEXT*)XhciGetContextEntry(Usb3Hc, ParentHubDevice, 0);
+ SlotCtx->RootHubPort = ParentHubSlotCtx->RootHubPort;
+ }
+
+ switch (DeviceSpeed) {
+ case USB_HIGH_SPEED_DEVICE: Speed = XHCI_DEVSPEED_HIGH; break;
+ case USB_SLOW_SPEED_DEVICE: Speed = XHCI_DEVSPEED_LOW; break;
+ case USB_FULL_SPEED_DEVICE: Speed = XHCI_DEVSPEED_FULL; break;
+ case USB_SUPER_SPEED_DEVICE: Speed = XHCI_DEVSPEED_SUPER;
+ }
+
+ SlotCtx->Speed = Speed;
+
+ XfrRing = XhciInitXfrRing(Usb3Hc, SlotId, 0);
+
+ // Initialize the Input default control Endpoint 0 Context
+ Ep0Ctx = (XHCI_EP_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 2);
+ Ep0Ctx->EpType = XHCI_EPTYPE_CTL;
+ Ep0Ctx->MaxPacketSize = aMaxPacketSize[Speed];
+ Ep0Ctx->TrDequeuePtr = (UINT64)(UINTN)XfrRing->Base + 1;
+ Ep0Ctx->AvgTrbLength = 8;
+ Ep0Ctx->ErrorCount = 3;
+
+ // Initialize Route String and TT fields
+ if (TransactionTranslator != 0) {
+ if (ParentHubSlotCtx->Speed == XHCI_DEVSPEED_SUPER) {
+ for (i = 0; i < 5; i++) {
+ if (((ParentHubSlotCtx->RouteString >> (i << 2)) & 0xF) == 0) {
+ break;
+ }
+ }
+ SlotCtx->RouteString = ParentHubSlotCtx->RouteString | (Port << (i << 2));
+ } else {
+ // Update TT fields in the Slot context for LS/FS device connected to HS hub
+ if (SlotCtx->Speed == XHCI_DEVSPEED_FULL || SlotCtx->Speed == XHCI_DEVSPEED_LOW) {
+ if(ParentHubSlotCtx->Speed == XHCI_DEVSPEED_HIGH) {
+ SlotCtx->TtHubSlotId = ParentHubSlotId;
+ SlotCtx->TtPortNumber = (UINT8)(TransactionTranslator >> 7);
+ SlotCtx->MultiTT = ParentHubSlotCtx->MultiTT;
+ } else {
+ SlotCtx->TtHubSlotId = ParentHubSlotCtx->TtHubSlotId;
+ SlotCtx->TtPortNumber = ParentHubSlotCtx->TtPortNumber;
+ SlotCtx->MultiTT = ParentHubSlotCtx->MultiTT;
+ }
+ }
+ }
+ }
+
+ // Assign a new address 4.3.4, 4.6.5
+ Status = XhciExecuteCommand(PeiServices, Usb3Hc, XhciTAddressDeviceCmd, &SlotId);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+ if (Status != EFI_SUCCESS) {
+ XhciExecuteCommand(PeiServices, Usb3Hc, XhciTDisableSlotCmd, &SlotId);
+ Usb3Hc->DcbaaPtr->DevCntxtAddr[SlotId-1] = 0;
+ return Status;
+ }
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: new device address %d\n", ((XHCI_SLOT_CONTEXT*)Device)->DevAddr));
+
+ gSlotBeingConfigured = SlotId; // Valid from now til SetAddress
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdateDeviceMap
+//
+// Description:
+// This function updates SlotId<->Address mapping table.
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if update is successful
+// = EFI_NOT_FOUND if there is no room for a new entry in the map
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UpdateDeviceMap(
+ PEI_XHCI_SLOTADDR_MAP *DeviceMap,
+ UINT8 SlotId,
+ UINT8 DevAddr
+)
+{
+ UINT8 i;
+ PEI_XHCI_SLOTADDR_MAP *Map = DeviceMap;
+
+ for (i = 0; i < PEI_XHCI_MAX_SLOTS; i++, Map++) {
+ if (Map->SlotId == 0) {
+ Map->SlotId = SlotId;
+ Map->DevAddr = DevAddr;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetSlotId
+//
+// Description:
+// This function retrieves SlotId from the Slot<->Address mapping table.
+//
+// Output:
+// SlotId variable is updated
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS if update is successful
+// = EFI_NOT_FOUND if the requested Slot is not found in the mapping table
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetSlotId(
+ PEI_XHCI_SLOTADDR_MAP *DeviceMap,
+ UINT8 *SlotId,
+ UINT8 DevAddr
+)
+{
+ UINT8 i;
+ PEI_XHCI_SLOTADDR_MAP *Map = DeviceMap;
+
+ for (i = 0; i < PEI_XHCI_MAX_SLOTS; i++, Map++) {
+ if (Map->DevAddr == DevAddr) {
+ *SlotId = Map->SlotId;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciClearStalledEp
+//
+// Description:
+// This function is called to restart endpoint. After Endpoint STALLs, it
+// transitions from Halted to Stopped state. It is restored back to Running
+// state by moving the endpoint ring dequeue pointer past the failed control
+// transfer with a Set TR Dequeue Pointer. Then it is restarted by ringing the
+// doorbell. Alternatively endpint is restarted using Configure Endpoint command.
+//
+// Input:
+// Stalled EP data - SlotId and DCI
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciClearStalledEp(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 SlotId,
+ UINT8 Dci
+)
+{
+ UINT16 EpInfo;
+ TRB_RING *XfrRing;
+ EFI_STATUS Status;
+ XHCI_SET_TRPTR_CMD_TRB Trb;
+
+ // Reset stalled endpoint
+ EpInfo = (Dci << 8) + SlotId;
+ Status = XhciExecuteCommand(PeiServices, Usb3Hc, XhciTResetEndpointCmd, &EpInfo);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+
+ XfrRing = XhciGetXfrRing(Usb3Hc, SlotId, Dci-1);
+
+ Trb.TrPointer = (UINT64)((UINTN)XfrRing->QueuePtr + XfrRing->CycleBit); // Set up DCS
+ Trb.EndpointId = Dci;
+ Trb.SlotId = SlotId;
+
+ Status = XhciExecuteCommand(PeiServices, Usb3Hc, XhciTSetTRDequeuePointerCmd, &Trb);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciUpdateEp0MaxPacket
+//
+// Description:
+// This function verifies the MaxPacket size of the control pipe. If it does
+// not match the one received as a part of GET_DESCRIPTOR, then this function
+// updates the MaxPacket data in DeviceContext and HC is notified via
+// EvaluateContext command.
+//
+// Input:
+// Usb3Hc Pointer to the HC structure
+// Device Evaluated device context pointer
+// SlotId Device context index in DCBAA
+// Endp0MaxPacket Max packet size obtained from the device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+XhciUpdateEp0MaxPacket(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 SlotId,
+ UINT8 Endp0MaxPacket
+)
+{
+ UINT8 Status;
+ UINT8 *DevCtx;
+ XHCI_INPUT_CONTROL_CONTEXT *CtlCtx;
+ XHCI_SLOT_CONTEXT *SlotCtx;
+ XHCI_EP_CONTEXT *EpCtx;
+
+ DevCtx = (UINT8*)XhciGetDeviceContext(Usb3Hc, SlotId);
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XhciGetContextEntry(Usb3Hc, DevCtx, 0);
+ if (SlotCtx->Speed != XHCI_DEVSPEED_FULL) return;
+
+ EpCtx = (XHCI_EP_CONTEXT*)XhciGetContextEntry(Usb3Hc, DevCtx, 1);
+ if (EpCtx->MaxPacketSize == Endp0MaxPacket) return;
+
+ // Prepare input context for EvaluateContext comand
+ (**PeiServices).SetMem((UINT8*)Usb3Hc->InputContext, XHCI_INPUT_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ CtlCtx = (XHCI_INPUT_CONTROL_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 0);
+ CtlCtx->AddContextFlags = BIT1;
+
+ EpCtx = (XHCI_EP_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 2);
+ EpCtx->MaxPacketSize = Endp0MaxPacket;
+
+ Status = XhciExecuteCommand(PeiServices, Usb3Hc, XhciTEvaluateContextCmd, &SlotId);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XhciHcControlTransfer
+//
+// Description:
+// This function intiates a USB control transfer and waits on it to
+// complete.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 bDeviceAddress
+// -- USB address of the device for which the control
+// transfer is to be issued
+// IN UINT8 DeviceType
+// -- Not used
+// IN UINT8 MaximumPacketLength
+// -- Maximum number of bytes that can be sent to or
+// received from the endpoint in a single data packet
+// IN EFI_USB_DEVICE_REQUEST *Request
+// -- EFI_USB_DEVICE_REQUEST pointer
+// IN EFI_USB_DATA_DIRECTION TransferDirection
+// -- Direction of transfer
+// OPTIONAL IN OUT VOID *DataBuffer
+// -- Pointer to source or destination buffer
+// OPTIONAL IN OUT UINTN *DataLength
+// -- Length of buffer
+// IN UINTN TimeOut
+// -- Not used
+// OUT UINT32 *TransferResult
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciHcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ XHCI_TRB *Trb;
+ volatile UINT32 *Doorbell;
+ UINT8 SlotId;
+ UINT8 CompletionCode;
+ UINT8 Status;
+ TRB_RING *XfrRing;
+ UINT16 Rq = ((UINT16)Request->Request << 8) + Request->RequestType;
+
+ // Skip SET_ADDRESS request
+ if (Request->RequestType == USB_DEV_SET_ADDRESS_REQ_TYPE &&
+ Request->Request == USB_DEV_SET_ADDRESS)
+ {
+ Status = UpdateDeviceMap(Usb3Hc->DeviceMap, gSlotBeingConfigured, (UINT8)Request->Value);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+ return EFI_SUCCESS;
+ }
+
+ if (DeviceAddress == 0) {
+ SlotId = gSlotBeingConfigured;
+ } else {
+ Status = GetSlotId(Usb3Hc->DeviceMap, &SlotId, DeviceAddress);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+ }
+
+ // Insert Setup, Data(if needed), and Status TRBs into the transfer ring
+ XfrRing = XhciGetXfrRing(Usb3Hc, SlotId, 0);
+
+ // Setup TRB
+ Trb = XhciAdvanceEnqueuePtr(XfrRing);
+ Trb->TrbType = XhciTSetupStage;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Idt = 1;
+ *(UINT16*)&((XHCI_SETUP_XFR_TRB*)Trb)->bmRequestType = Rq;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->wValue = Request->Value;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->wIndex = Request->Index;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->wLength = (UINT16)(*DataLength);
+ ((XHCI_SETUP_XFR_TRB*)Trb)->XferLength = 8;
+
+ if (Usb3Hc->HciVersion == 0x100) {
+ if (*DataLength != 0) {
+ if ((Rq & BIT7) != 0) {
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Trt = XHCI_XFER_TYPE_DATA_IN;
+ } else {
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Trt = XHCI_XFER_TYPE_DATA_OUT;
+ }
+ } else {
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Trt = XHCI_XFER_TYPE_NO_DATA;
+ }
+ }
+
+ // Data TRB
+ if (*DataLength != 0) {
+ Trb = XhciAdvanceEnqueuePtr(XfrRing);
+ Trb->TrbType = XhciTDataStage;
+ ((XHCI_DATA_XFR_TRB*)Trb)->Dir = ((Rq & BIT7) != 0)? 1 : 0;
+ ((XHCI_DATA_XFR_TRB*)Trb)->XferLength = *DataLength;
+ ((XHCI_DATA_XFR_TRB*)Trb)->DataBuffer = (UINT64)(UINTN)Data;
+ }
+
+ // Status TRB
+ Trb = XhciAdvanceEnqueuePtr(XfrRing);
+ Trb->TrbType = XhciTStatusStage;
+ ((XHCI_STATUS_XFR_TRB*)Trb)->Ioc = 1;
+ if ((Rq & BIT7) == 0) {
+ ((XHCI_STATUS_XFR_TRB*)Trb)->Dir = 1; // Status is IN
+ }
+
+ // Ring the doorbell and see Event Ring update
+ Doorbell = XhciGetTheDoorbell(Usb3Hc, SlotId);
+ *Doorbell = 1; // Control EP0 Enqueue Pointer Update
+
+ Status = XhciWaitForEvent(
+ PeiServices, Usb3Hc, Trb, XhciTTransferEvt,
+ &CompletionCode, XHCI_CTL_COMPLETE_TIMEOUT_MS, NULL);
+
+
+ if (CompletionCode == XHCI_TRB_STALL_ERROR) {
+ Status = XhciClearStalledEp(PeiServices,
+ Usb3Hc, SlotId, 1); // Dci = 1 for control endpoint
+ return 0;
+ }
+
+ if (Request->Request == USB_DEV_GET_DESCRIPTOR && *DataLength == 8) {
+ // Full speed device requires the update of MaxPacket size
+ XhciUpdateEp0MaxPacket(PeiServices, Usb3Hc, SlotId,
+ ((EFI_USB_DEVICE_DESCRIPTOR*)Data)->MaxPacketSize0);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XhciHcBulkTransfer
+//
+// Description:
+// This function intiates a USB bulk transfer and waits on it to
+// complete.
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// -- EFI_PEI_SERVICES pointer
+// IN PEI_USB_HOST_CONTROLLER_PPI *This
+// -- PEI_USB_HOST_CONTROLLER_PPI pointer
+// IN UINT8 DeviceAddress
+// -- USB address of the device for which the control
+// transfer is to be issued
+// IN UINT8 EndPointAddress
+// -- Particular endpoint for the device
+// IN UINT8 MaximumPacketLength
+// -- Maximum number of bytes that can be sent to or
+// received from the endpoint in a single data packet
+// OPTIONAL IN OUT VOID *DataBuffer
+// -- Pointer to source or destination buffer
+// OPTIONAL IN OUT UINTN *DataLength
+// -- Length of buffer
+// IN OUT UINT8 *DataToggle
+// -- Used to update the control/status DataToggle field
+// of the Transfer Descriptor
+// IN UINTN TimeOut
+// -- Not used
+// OUT UINT32 *TransferResult
+// -- Not used
+//
+// Output:
+// EFI_STATUS (Return Value)
+// = EFI_SUCCESS on successful completion
+// or valid EFI error code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciHcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult )
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ XHCI_TRB *Trb;
+ UINTN FirstTrb;
+ volatile UINT32 *Doorbell;
+ UINT8 SlotId;
+ UINT8 CompletionCode;
+ EFI_STATUS Status;
+ TRB_RING *XfrRing;
+ UINT8 Endpoint;
+ UINT8 Dci;
+ UINT64 DataPointer;
+ UINT32 ResidualData; // Transferred amount return by Transfer Event
+ UINT32 TransferredSize; // Total transfer amount
+ UINT32 RingDataSize; // One TRB ring transfer amount
+ UINT32 RemainingXfrSize;
+ UINT32 RemainingDataSize;
+ UINT32 XfrSize;
+ UINT32 XfrTdSize;
+ UINT32 TdPktCnt;
+ UINT32 TdSize;
+
+ Endpoint = EndPointAddress;
+ Dci = (Endpoint & 0xf)* 2;
+ if (Endpoint & BIT7) Dci++;
+
+ GetSlotId(Usb3Hc->DeviceMap, &SlotId, DeviceAddress);
+
+ Doorbell = XhciGetTheDoorbell(Usb3Hc, SlotId);
+
+ XfrRing = XhciGetXfrRing(Usb3Hc, SlotId, Dci-1);
+
+ // Make a chain of TDs to transfer the requested amount of data. If necessary,
+ // make multiple transfers in a loop.
+
+ DataPointer = (UINTN)Data;
+ RemainingDataSize = *DataLength;
+
+ // Two loops are executing the transfer:
+ // The inner loop creates a transfer ring of chained TDs, XHCI_BOT_TD_MAXSIZE
+ // bytes each. This makes a ring capable of transferring
+ // XHCI_BOT_TD_MAXSIZE * (TRBS_PER_SEGMENT-1) bytes.
+ // The outter loop repeats the transfer if the requested transfer size exceeds
+ // XHCI_BOT_TD_MAXSIZE * (TRBS_PER_SEGMENT-1).
+
+ for (TransferredSize = 0; TransferredSize < *DataLength;) {
+ // Calculate the amount of data to transfer in the ring
+ RingDataSize = (RemainingDataSize > XHCI_BOT_MAX_XFR_SIZE)?
+ XHCI_BOT_MAX_XFR_SIZE : RemainingDataSize;
+
+ RemainingXfrSize = RingDataSize;
+ TdPktCnt = RingDataSize / MaximumPacketLength;
+
+ for (Trb = NULL, XfrSize = 0, FirstTrb = 0; XfrSize < RingDataSize;)
+ {
+ Trb = XhciAdvanceEnqueuePtr(XfrRing);
+ if (FirstTrb == 0) FirstTrb = (UINTN)Trb;
+
+ Trb->TrbType = XhciTNormal;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Isp = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->DataBuffer = DataPointer;
+
+ // See if we need a TD chain. Note that we do not need to
+ // place the chained TRB into Event Ring, since we will not be
+ // looking for it anyway. Set IOC only for the last-in-chain TRB.
+ if (RemainingXfrSize > XHCI_BOT_TD_MAXSIZE) {
+ XfrTdSize = XHCI_BOT_TD_MAXSIZE;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Chain = 1;
+ } else {
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Ioc = 1;
+ XfrTdSize = RemainingXfrSize;
+ }
+ // Data buffers referenced by Transfer TRBs shall not span 64KB boundaries.
+ // If a physical data buffer spans a 64KB boundary, software shall chain
+ // multiple TRBs to describe the buffer.
+ if (XfrTdSize > (UINT32)(0x10000 - (DataPointer & (0x10000 - 1))))
+ {
+ XfrTdSize = (UINT32)(0x10000 - (DataPointer & (0x10000 - 1)));
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Chain = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Ioc = 0;
+ }
+
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->XferLength = XfrTdSize;
+ if(Usb3Hc->HciVersion == 0x100) {
+ TdSize = TdPktCnt - ((XfrSize + XfrTdSize)/MaximumPacketLength);
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->TdSize = (TdSize > 31)? 31 : TdSize;
+ } else {
+ TdSize = RemainingXfrSize - XfrTdSize;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->TdSize = (TdSize < 32768)? (TdSize >> 10) : 31;
+ }
+
+ XfrSize += XfrTdSize;
+ DataPointer += XfrTdSize;
+ RemainingXfrSize -= XfrTdSize;
+ }
+
+ // If transfer ring crossed Link TRB, set its Chain flag
+ if ((UINTN)Trb < FirstTrb) {
+ ((XHCI_NORMAL_XFR_TRB*)XfrRing->LastTrb)->Chain = 1;
+ }
+
+ // Ring the door bell and see Event Ring update
+ *Doorbell = Dci;
+
+ Status = XhciWaitForEvent(
+ PeiServices, Usb3Hc, Trb, XhciTTransferEvt,
+ &CompletionCode, XHCI_BULK_COMPLETE_TIMEOUT_MS, &ResidualData);
+
+ // Clear Link TRB chain flag
+ ((XHCI_NORMAL_XFR_TRB*)XfrRing->LastTrb)->Chain = 0;
+
+ if (CompletionCode == XHCI_TRB_STALL_ERROR) {
+ XhciClearStalledEp(PeiServices, Usb3Hc, SlotId, Dci);
+ break;
+ }
+ TransferredSize += (RingDataSize - ResidualData);
+ if (ResidualData != 0) break; // Short packet detected, no more transfers
+ RemainingDataSize -= RingDataSize;
+ }
+
+ *DataLength = TransferredSize;
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciHcGetRootHubPortNumber
+//
+// Description:
+// This function returns number of root ports supported by the controller.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciHcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber )
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+
+ *PortNumber = Usb3Hc->MaxPorts;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UpdatePortStatusSpeed
+//
+// Description:
+// This function converts XHCI speed definition into the terms
+// of PEI_USB_HOST_CONTROLLER_PPI (namely XHCI_DEVSPEED_xyz is converted
+// into USB_PORT_STAT_xyz).
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UpdatePortStatusSpeed(
+ EFI_PEI_SERVICES **PeiServices,
+ UINT8 Speed,
+ UINT16 *PortStatus
+)
+{
+ switch (Speed) {
+ case XHCI_DEVSPEED_UNDEFINED:
+ case XHCI_DEVSPEED_FULL:
+ break;
+ case XHCI_DEVSPEED_LOW:
+ *PortStatus |= USB_PORT_STAT_LOW_SPEED;
+ break;
+ case XHCI_DEVSPEED_HIGH:
+ *PortStatus |= USB_PORT_STAT_HIGH_SPEED;
+ break;
+ case XHCI_DEVSPEED_SUPER:
+ *PortStatus |= USB_PORT_STAT_SUPER_SPEED;
+ break;
+ default:
+ PEI_TRACE((-1, PeiServices, "XHCI ERROR: unknown device speed.\n"));
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciHcGetRootHubPortStatus
+//
+// Description:
+// Host controller API function; returns root hub port status in terms of
+// PEI_USB_HOST_CONTROLLER_PPI definition.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciHcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus )
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ volatile XHCI_PORTSC *PortSC;
+
+ // Find the proper MMIO access offset for a given port
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNumber - 1)));
+
+ PEI_TRACE((-1, PeiServices, "XHCI port[%d] status: %08x\n", PortNumber, PortSC->AllBits));
+
+ *(UINT32*)PortStatus = 0;
+
+ if (PortSC->Field.Ccs != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;
+ }
+ if (PortSC->Field.Ped != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;
+ }
+ if (PortSC->Field.Oca != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_OVERCURRENT;
+ }
+ if (PortSC->Field.Pr != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_RESET;
+ }
+ if (PortSC->Field.Pp != 0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_POWER;
+ }
+ if (PortSC->Field.Csc != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;
+ }
+ if (PortSC->Field.Pec != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;
+ }
+ if (PortSC->Field.Occ != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_OVERCURRENT;
+ }
+ if (PortSC->Field.Prc != 0) {
+ PortStatus->PortChangeStatus |= USB_PORT_STAT_C_RESET;
+ }
+
+ UpdatePortStatusSpeed(PeiServices, PortSC->Field.PortSpeed, &PortStatus->PortStatus);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciHcSetRootHubPortFeature
+//
+// Description:
+// Host controller PEI_USB_HOST_CONTROLLER_PPI API function; sets a requested
+// feature of a root hub port.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciHcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ volatile XHCI_PORTSC *PortSC;
+
+ if (PortNumber > Usb3Hc->MaxPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNumber - 1)));
+ switch (PortFeature) {
+ case EfiUsbPortEnable:
+ case EfiUsbPortSuspend:
+ break;
+
+ case EfiUsbPortReset:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) | XHCI_PCS_PR;
+ break;
+
+ case EfiUsbPortPower:
+ PortSC->AllBits = XHCI_PCS_PP;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciHcClearRootHubPortFeature
+//
+// Description:
+// Host controller PEI_USB_HOST_CONTROLLER_PPI API function; clears a requested
+// feature of a root hub port.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS XhciHcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature )
+{
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ volatile XHCI_PORTSC *PortSC;
+
+ if (PortNumber > Usb3Hc->MaxPorts) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNumber - 1)));
+
+ switch (PortFeature) {
+ case EfiUsbPortEnable:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) | XHCI_PCS_PED;
+ break;
+
+ case EfiUsbPortSuspend:
+ case EfiUsbPortReset:
+ break;
+
+ case EfiUsbPortPower:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) & ~(XHCI_PCS_PP);
+ break;
+
+ case EfiUsbPortOwner:
+ break;
+
+ case EfiUsbPortConnectChange:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) | XHCI_PCS_CSC;
+ break;
+
+ case EfiUsbPortEnableChange:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) | XHCI_PCS_PEC;
+ break;
+
+ case EfiUsbPortSuspendChange:
+ break;
+
+ case EfiUsbPortOverCurrentChange:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) | XHCI_PCS_OCC;
+ break;
+
+ case EfiUsbPortResetChange:
+ PortSC->AllBits = (PortSC->AllBits & XHCI_PCS_PP) | XHCI_PCS_PRC;
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciMmio64Write
+//
+// Description:
+// MMIO write; depending on 64-bit access availability executes either one
+// 64-bit write or two 32-bit writes.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+XhciMmio64Write(
+ USB3_CONTROLLER *Usb3Hc,
+ UINTN Address,
+ UINT64 Data
+)
+{
+ if (Usb3Hc->Access64) {
+ *(UINT64*)Address = Data;
+ }
+ else {
+ *(UINT32*)Address = (UINT32)Data;
+ *(UINT32*)(Address + sizeof(UINT32)) = (UINT32)(Shr64(Data, 32));
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciInitRing
+//
+// Description:
+// Transfer ring initialization. There is an option to create a Link TRB in
+// the end of the ring.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciInitRing (
+ IN OUT TRB_RING *Ring,
+ IN UINTN RingBase,
+ IN UINT32 RingSize,
+ IN BOOLEAN PlaceLinkTrb
+)
+{
+ XHCI_LINK_TRB *LinkTrb;
+
+ Ring->Base = (XHCI_TRB*)RingBase;
+ Ring->Size = RingSize;
+ Ring->LastTrb = Ring->Base + RingSize - 1;
+ Ring->CycleBit = 1;
+ Ring->QueuePtr = (XHCI_TRB*)RingBase;
+
+ // Initialize ring with zeroes
+ {
+ UINT8 *p = (UINT8*)RingBase;
+ UINTN i;
+ for (i = 0; i < RingSize*sizeof(XHCI_TRB); i++, p++) *p = 0;
+ }
+
+ if (PlaceLinkTrb) {
+ // Place a Link TRB in the end of the ring pointing to the beginning
+ LinkTrb = (XHCI_LINK_TRB*)Ring->LastTrb;
+ LinkTrb->NextSegPtr = (UINT64)(UINTN)RingBase;
+ LinkTrb->ToggleCycle = 1;
+ LinkTrb->TrbType = XhciTLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XhciAdvanceEnqueuePtr
+//
+// Description:
+// This function advances returns the pointer to the current TRB and anvances
+// dequeue pointer. If the advance pointer is Link TRB, then it: 1) activates
+// Link TRB by updating its cycle bit, 2) updates dequeue pointer to the value
+// pointed by Link TRB.
+//
+// Input:
+// Ring - TRB ring to be updated
+//
+// Output:
+// TRB that can be used for command, transfer, etc.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+XHCI_TRB*
+XhciAdvanceEnqueuePtr(
+ TRB_RING *Ring
+)
+{
+ XHCI_TRB* Trb = Ring->QueuePtr;
+
+ if (Trb->TrbType == XhciTLink) {
+ Trb->CycleBit = Ring->CycleBit;
+ Ring->CycleBit ^= 1;
+ Ring->QueuePtr = Ring->Base;
+
+ Trb = Ring->QueuePtr;
+ }
+ // Clear the TRB
+ {
+ UINT32 *p = (UINT32*)Trb;
+ UINT8 i = 0;
+ for (i=0; i<(sizeof(XHCI_TRB)/sizeof(UINT32)); i++) {
+ *p++ = 0;
+ }
+ }
+
+ Trb->CycleBit = Ring->CycleBit;
+ Ring->QueuePtr++;
+
+ return Trb;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XHCI_ProcessInterrupt
+//
+// Description: This is the XHCI controller event handler. It walks through
+// the Event Ring and executes the event associated code if needed. Updates
+// the Event Ring Data Pointer in the xHC to let it know which events are
+// completed.
+//
+// Output:
+// EFI_NOT_READY - Need more Interrupt processing
+// EFI_SUCCESS - No interrupts pending
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciProcessInterrupt(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc
+)
+{
+ XHCI_TRB *Trb;
+ XHCI_EVENT_TRB *EvTrb;
+
+ if ((UINT32)Usb3Hc->OpRegs->DcbAap != (UINT32)Usb3Hc->DcbaaPtr) return EFI_SUCCESS;
+/*
+ if (Usb3Hc->OpRegs->UsbSts.Field.Pcd) {
+ XHCI_EnumeratePorts(HcStruc);
+ Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_PCD; // Clear PortChangeDetect
+ }
+*/
+ if (Usb3Hc->OpRegs->UsbSts.Field.Eint)
+ {
+ Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_EVT_INTERRUPT;
+ Usb3Hc->RtRegs->IntRegs[0].IMan |= BIT0;
+ }
+
+ // Check for pending interrupts:
+ // check the USBSTS[3] and IMAN [0] to determine if any interrupt generated
+ if (Usb3Hc->EvtRing.QueuePtr->CycleBit != Usb3Hc->EvtRing.CycleBit) return EFI_SUCCESS;
+
+ // See if there are any TRBs waiting in the event ring
+ //for (Count = 0; Count < Usb3Hc->EvtRing.Size; Count++) {
+ for (;;) {
+ Trb = Usb3Hc->EvtRing.QueuePtr;
+
+ if (Trb->CycleBit != Usb3Hc->EvtRing.CycleBit) break; // past the last
+
+ if (Usb3Hc->EvtRing.QueuePtr == Usb3Hc->EvtRing.LastTrb) {
+ // Reached the end of the ring, wrap around
+ Usb3Hc->EvtRing.QueuePtr = Usb3Hc->EvtRing.Base;
+ Usb3Hc->EvtRing.CycleBit ^= 1;
+ } else {
+ Usb3Hc->EvtRing.QueuePtr++;
+ }
+ // TODO:: error manager
+ if (Trb->CompletionCode == XHCI_TRB_SHORTPACKET) {
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: short packet detected."));
+ }
+
+ if (Trb->CompletionCode == XHCI_TRB_STALL_ERROR) {
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: device STALLs."));
+ }
+
+ if (Trb->CompletionCode != XHCI_TRB_SUCCESS
+ && Trb->CompletionCode != XHCI_TRB_STALL_ERROR
+ && Trb->CompletionCode != XHCI_TRB_SHORTPACKET) {
+ PEI_TRACE((-1, PeiServices, "Trb completion code: %d\n", Trb->CompletionCode));
+ PEI_ASSERT(PeiServices, FALSE);
+ }
+
+ // Process TRB pointed by Usb3Hc->EvtRing->QueuePtr
+ EvTrb = (XHCI_EVENT_TRB*)Trb;
+
+ switch (Trb->TrbType) {
+ case XhciTTransferEvt:
+// very frequent, debug message here might affect timings,
+// uncomment only when needed
+// PEI_TRACE((-1, PeiServices, "TransferEvt\n"));
+
+// DEBUG
+/* XhciProcessXferEvt(
+ PeiServices,
+ Usb3Hc,
+ EvTrb->TransferEvt.TrbPtr,
+ EvTrb->TransferEvt.SlotId,
+ EvTrb->TransferEvt.EndpointId);*/
+ break;
+ case XhciTCmdCompleteEvt:
+ PEI_TRACE((-1, PeiServices, "CmdCompleteEvt\n"));
+ break;
+ case XhciTPortStatusChgEvt:
+ PEI_TRACE((-1, PeiServices, "PortStatusChgEvt, port #%d\n", EvTrb->PortStsChgEvt.PortId));
+ break;
+ case XhciTDoorbellEvt:
+ PEI_TRACE((-1, PeiServices, "DoorbellEvt\n"));
+ break;
+ case XhciTHostControllerEvt:
+ PEI_TRACE((-1, PeiServices, "HostControllerEvt\n"));
+ break;
+ case XhciTDevNotificationEvt:
+ PEI_TRACE((-1, PeiServices, "DevNotificationEvt\n"));
+ break;
+ case XhciTMfIndexWrapEvt:
+ PEI_TRACE((-1, PeiServices, "MfIndexWrapEvt\n"));
+ break;
+ default:
+ PEI_TRACE((-1, PeiServices, "UNKNOWN EVENT\n"));
+ }
+ }
+ //PEI_ASSERT(PeiServices, Count<Usb3Hc->EvtRing.Size); // Event ring is full
+
+ // Update ERDP to inform xHC that we have processed another TRB
+ XhciMmio64Write(Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr | BIT3);
+
+ return EFI_SUCCESS; // Set as interrupt processed
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XhciWaitForEvent
+//
+// Description:
+// This function walks through the active TRBs in the event ring and looks for
+// the command TRB to be complete. If found, returns SlotId and CompletionCode
+// from the completed event TRB. In the end it processes the event ring,
+// adjusting its Dequeue Pointer.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciWaitForEvent(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ XHCI_TRB *TrbToCheck,
+ TRB_TYPE EventType,
+ UINT8 *CompletionCode,
+ UINT16 TimeOutMs,
+ VOID *Data
+)
+{
+ XHCI_TRB *Trb;
+ UINT32 TimeOut;
+ EFI_STATUS Status;
+ UINT8 CycleBit;
+// UINT32 TimeOutValue = TimeOutMs << 6; // *64, 15 us unit
+ UINT32 TimeOutValue = TimeOutMs + 1;
+
+ for (TimeOut = 0; TimeOut < TimeOutValue; TimeOut++) {
+ for (Trb = Usb3Hc->EvtRing.QueuePtr,
+ CycleBit = Usb3Hc->EvtRing.CycleBit;;) {
+ if (Trb->CycleBit != CycleBit) {
+ // Command is not complete, break and retry
+ break;
+ }
+
+ *CompletionCode = Trb->CompletionCode;
+ if (Trb->CompletionCode == XHCI_TRB_STALL_ERROR ||
+ Trb->CompletionCode == XHCI_TRB_TRANSACTION_ERROR) {
+ Status = EFI_DEVICE_ERROR;
+ goto DoneWaiting;
+ }
+
+ // Active TRB found
+ if (Trb->TrbType == EventType) {
+ if ((*(UINTN*)&Trb->Param1) == (UINTN)TrbToCheck) {
+
+ if (Trb->CompletionCode != XHCI_TRB_SUCCESS && Trb->CompletionCode != XHCI_TRB_SHORTPACKET) {
+ PEI_TRACE((-1, PeiServices, "TRB Completion Error: %d\n", Trb->CompletionCode));
+ PEI_ASSERT(PeiServices, FALSE);
+ }
+
+ if (EventType == XhciTCmdCompleteEvt) {
+ *(UINT8*)Data = ((XHCI_CMDCOMPLETE_EVT_TRB*)Trb)->SlotId;
+ }
+ if (EventType == XhciTTransferEvt) {
+ if (Data != NULL) {
+ *(UINT32*)Data = ((XHCI_TRANSFER_EVT_TRB*)Trb)->TransferLength;
+ }
+ }
+
+ Status = (Trb->CompletionCode == XHCI_TRB_SUCCESS ||
+ Trb->CompletionCode == XHCI_TRB_SHORTPACKET)? EFI_SUCCESS:EFI_DEVICE_ERROR;
+ goto DoneWaiting;
+ }
+ }
+ // Advance TRB pointer
+ if (Trb == Usb3Hc->EvtRing.LastTrb) {
+ Trb = Usb3Hc->EvtRing.Base;
+ CycleBit ^= 1;
+ } else {
+ Trb++;
+ }
+ if (Trb == Usb3Hc->EvtRing.QueuePtr) {
+ // Event ring is full, return error
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Event Ring is full...\n"));
+ PEI_ASSERT(PeiServices, FALSE);
+ *CompletionCode = XHCI_TRB_EVENTRINGFULL_ERROR;
+ Status = EFI_DEVICE_ERROR;
+ break;
+ }
+ }
+// XHCI_FIXED_DELAY_15MCS(Usb3Hc, 1); // 15 us out of TimeOutMs
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 1); // 1 ms out of TimeOutMs
+ }
+
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: execution time-out.\n"));
+
+ *CompletionCode = XHCI_TRB_EXECUTION_TIMEOUT_ERROR;
+ Status = EFI_DEVICE_ERROR;
+
+DoneWaiting:
+ XhciProcessInterrupt(PeiServices, Usb3Hc);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XhciExecuteCommand
+//
+// Description:
+// This function places a given command in the Command Ring, rings HC doorbell,
+// and waits for the command completion.
+//
+// Output:
+// EFI_DEVICE_ERROR on execution failure, otherwise EFI_SUCCESS
+// Params - pointer to the command specific data.
+//
+// Notes:
+// Caller is responsible for a data placeholder.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciExecuteCommand(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ TRB_TYPE Cmd,
+ VOID *Params
+)
+{
+ volatile UINT32 *Doorbell;
+ UINT8 CompletionCode;
+ UINT8 SlotId;
+ EFI_STATUS Status;
+ XHCI_TRB *Trb = XhciAdvanceEnqueuePtr(&Usb3Hc->CmdRing);
+
+ Trb->TrbType = Cmd; // Set TRB type
+
+ // Fill in the command TRB fields
+ switch (Cmd) {
+ case XhciTAddressDeviceCmd:
+ case XhciTEvaluateContextCmd:
+ case XhciTConfigureEndpointCmd:
+ ((XHCI_ADDRESSDEV_CMD_TRB*)Trb)->InpCtxAddress = (UINT64)(UINTN)Usb3Hc->InputContext;
+ ((XHCI_ADDRESSDEV_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ ((XHCI_ADDRESSDEV_CMD_TRB*)Trb)->Bsr = 0;
+ break;
+ case XhciTResetEndpointCmd:
+ ((XHCI_RESET_EP_CMD_TRB*)Trb)->Tsp = 0;
+ ((XHCI_RESET_EP_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ ((XHCI_RESET_EP_CMD_TRB*)Trb)->EndpointId = *((UINT8*)Params+1);
+ break;
+ case XhciTSetTRDequeuePointerCmd:
+ ((XHCI_SET_TRPTR_CMD_TRB*)Trb)->TrPointer = ((XHCI_SET_TRPTR_CMD_TRB*)Params)->TrPointer;
+ ((XHCI_SET_TRPTR_CMD_TRB*)Trb)->EndpointId = ((XHCI_SET_TRPTR_CMD_TRB*)Params)->EndpointId;
+ ((XHCI_SET_TRPTR_CMD_TRB*)Trb)->SlotId = ((XHCI_SET_TRPTR_CMD_TRB*)Params)->SlotId;
+ break;
+ case XhciTDisableSlotCmd:
+ ((XHCI_DISABLESLOT_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ break;
+ }
+
+ // Ring the door bell and see Event Ring update
+ Doorbell = (UINT32*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->DbOffset);
+ *Doorbell = 0; // HC doorbell is #0
+
+ Status = XhciWaitForEvent(
+ PeiServices, Usb3Hc, Trb, XhciTCmdCompleteEvt,
+ &CompletionCode, XHCI_CMD_COMPLETE_TIMEOUT_MS, &SlotId);
+
+ if (Status == EFI_DEVICE_ERROR) {
+ PEI_TRACE((-1, PeiServices, "XHCI command completion error code: %d\n", CompletionCode));
+ PEI_ASSERT(PeiServices, Status != EFI_DEVICE_ERROR);
+ return Status;
+ }
+
+ switch (Cmd) {
+ case XhciTEnableSlotCmd:
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Enable Slot command complete, SlotID %d\n", SlotId));
+ *((UINT8*)Params) = SlotId;
+ break;
+ case XhciTEvaluateContextCmd:
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Evaluate Context command complete.\n"));
+ break;
+ case XhciTConfigureEndpointCmd:
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Configure Endpoint command complete.\n"));
+ break;
+ case XhciTResetEndpointCmd:
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Reset Endpoint command complete (slot#%x dci#%x).\n",
+ *((UINT8*)Params), *((UINT8*)Params+1)));
+ break;
+ case XhciTSetTRDequeuePointerCmd:
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: Set TR pointer command complete.\n"));
+ break;
+ case XhciTDisableSlotCmd:
+ PEI_TRACE((-1, PeiServices, "PEI_XHCI: DisableSlot command complete.\n"));
+ break;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciInitXfrRing
+//
+// Description:
+// This function initializes transfer ring of given endpoint
+//
+// Output:
+// Pointer to the transfer ring
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TRB_RING*
+XhciInitXfrRing(
+ USB3_CONTROLLER* Usb3Hc,
+ UINT8 Slot,
+ UINT8 Ep
+)
+{
+ TRB_RING *XfrRing = Usb3Hc->XfrRings + (Slot-1)*32 + Ep;
+ UINTN Base = Usb3Hc->XfrTrbs + ((Slot-1)*32+Ep)*RING_SIZE;
+
+ XhciInitRing(XfrRing, Base, TRBS_PER_SEGMENT, TRUE);
+
+ return XfrRing;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciTranslateInterval
+//
+// Description:
+// This routine calculates the Interval field to be used in device's endpoint
+// context. Interval is calculated using the following rules (Section 6.2.3.6):
+//
+// For SuperSpeed bulk and control endpoints, the Interval field shall not be
+// used by the xHC. For all other endpoint types and speeds, system software
+// shall translate the bInterval field in the USB Endpoint Descriptor to the
+// appropriate value for this field.
+//
+// For high-speed and SuperSpeed Interrupt and Isoch endpoints the bInterval
+// field the Endpoint Descriptor is computed as 125æs * 2^(bInterval-1), where
+// bInterval = 1 to 16, therefore Interval = bInterval - 1.
+//
+// For low-speed Interrupt and full-speed Interrupt and Isoch endpoints the
+// bInterval field declared by a Full or Low-speed device is computed as
+// bInterval * 1ms., where bInterval = 1 to 255.
+//
+// For Full- and Low-speed devices software shall round the value of Endpoint
+// Context Interval field down to the nearest base 2 multiple of bInterval * 8.
+//
+// Input:
+// EpType Endpoint type, see XHCI_EP_CONTEXT.DW1.EpType field definitions
+// Speed Endpoint speed, 1..4 for XHCI_DEVSPEED_FULL, _LOW, _HIGH, _SUPER
+// Interval Poll interval value from endpoint descriptor
+//
+// Output:
+// Interval value to be written to the endpoint context
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XhciTranslateInterval(
+ UINT8 EpType,
+ UINT8 Speed,
+ UINT8 Interval
+)
+{
+ UINT8 TempData;
+ UINT8 BitCount;
+
+ if (EpType == XHCI_EPTYPE_CTL ||
+ EpType == XHCI_EPTYPE_BULK_OUT ||
+ EpType == XHCI_EPTYPE_BULK_IN) {
+
+ if (Speed == XHCI_DEVSPEED_HIGH) {
+ return Interval;
+ } else {
+ return 0; // Interval field will not be used for LS, FS and SS
+ }
+ }
+
+ // Control and Bulk endpoints are processed; translate intervals for Isoc and Interrupt
+ // endpoints
+
+ // Translate SS and HS endpoints
+ if (Speed == XHCI_DEVSPEED_SUPER || Speed == XHCI_DEVSPEED_HIGH) {
+ return (Interval - 1);
+ }
+
+ for (TempData = Interval, BitCount = 0; TempData != 0; BitCount++) {
+ TempData >>= 1;
+ }
+ return (BitCount + 2); // return value, where Interval = 0.125*2^value
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciEnableEndpoints
+//
+// Description:
+// This function parses the device descriptor data and enables the endpoints
+// by 1)assigning the Transfer TRB and 2)executing ConfigureEndpoint command
+// for the slot. Section 4.3.5.
+//
+// Input:
+// Desc - Device Configuration Descriptor data pointer
+//
+// Output:
+// EFI_DEVICE_ERROR on error, EFI_SUCCESS on success
+//
+// Notes:
+// 1) This call is executed before SET_CONFIGURATION control transfer
+// 2) Device slot is addressed by gSlotBeingConfigured
+// 3) EP0 information is valid in the Device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciEnableEndpoints (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 *Desc
+)
+{
+ UINT16 TotalLength;
+ UINT16 CurPos;
+ UINT8 Dci;
+ EFI_USB_INTERFACE_DESCRIPTOR *IntrfDesc;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EpDesc;
+ TRB_RING *XfrRing;
+ UINT8 EpType;
+ UINT8 Status;
+ UINT8 IsHub;
+ UINT8 DevSpeed;
+ XHCI_INPUT_CONTROL_CONTEXT *CtlCtx;
+ XHCI_SLOT_CONTEXT *SlotCtx;
+ XHCI_EP_CONTEXT *EpCtx;
+
+ USB3_CONTROLLER *Usb3Hc = PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS(This);
+ UINT8 SlotId = gSlotBeingConfigured;
+ UINT8 *DevCtx = (UINT8*)XhciGetDeviceContext(Usb3Hc, SlotId);
+
+ if (((EFI_USB_CONFIG_DESCRIPTOR*)Desc)->DescriptorType != USB_DT_CONFIG) return EFI_DEVICE_ERROR;
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XhciGetContextEntry(Usb3Hc, DevCtx, 0);
+ DevSpeed = SlotCtx->Speed;
+
+ // Note (From 4.6.6): The Add Context flag A1 and Drop Context flags D0 and D1
+ // of the Input Control Context (in the Input Context) shall be cleared to 0.
+ // Endpoint 0 Context does not apply to the Configure Endpoint Command and
+ // shall be ignored by the xHC. A0 shall be set to 1.
+
+ // Note (From 6.2.2.2): If Hub = 1 and Speed = High-Speed (3), then the
+ // TT Think Time and Multi-TT (MTT) fields shall be initialized.
+ // If Hub = 1, then the Number of Ports field shall be initialized, else
+ // Number of Ports = 0.
+
+ // Prepare input context for EvaluateContext comand
+ (**PeiServices).SetMem((UINT8*)Usb3Hc->InputContext, XHCI_INPUT_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ CtlCtx = (XHCI_INPUT_CONTROL_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 0);
+ CtlCtx->AddContextFlags = BIT0; // EP0
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 1);
+
+ // Collect the endpoint information and update the Device Input Context
+ TotalLength = ((EFI_USB_CONFIG_DESCRIPTOR*)Desc)->TotalLength;
+
+ if (TotalLength > (MAX_CONTROL_DATA_SIZE - 1)) {
+ TotalLength = MAX_CONTROL_DATA_SIZE - 1;
+ }
+
+ for (CurPos = 0; CurPos < TotalLength; CurPos += EpDesc->Length) {
+ EpDesc = (EFI_USB_ENDPOINT_DESCRIPTOR*)(IntrfDesc = (EFI_USB_INTERFACE_DESCRIPTOR*)(Desc + CurPos));
+
+ if (IntrfDesc->DescriptorType == USB_DT_INTERFACE) {
+ IsHub = IntrfDesc->InterfaceClass == BASE_CLASS_HUB;
+ continue;
+ }
+
+ if (EpDesc->DescriptorType != USB_DT_ENDPOINT) continue;
+
+ // Found Endpoint, fill up the information in the InputContext
+
+ // Calculate Device Context Index (DCI), Section 4.5.1.
+ // 1) For Isoch, Interrupt, or Bulk type endpoints the DCI is calculated
+ // from the Endpoint Number and Direction with the following formula:
+ // DCI = (Endpoint Number * 2) + Direction, where Direction = 0 for OUT
+ // endpoints and 1 for IN endpoints.
+ // 2) For Control type endpoints:
+ // DCI = (Endpoint Number * 2) + 1
+ //
+ // Also calculate XHCI EP type out of EpDesc->bEndpointFlags
+
+ if ((EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS) == EP_DESC_FLAG_TYPE_CONT) {
+ Dci = (EpDesc->EndpointAddress & 0xf) * 2 + 1;
+ EpType = XHCI_EPTYPE_CTL;
+ } else {
+ // Isoc, Bulk or Interrupt endpoint
+ Dci = (EpDesc->EndpointAddress & 0xf) * 2;
+ EpType = EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS; // 1, 2, or 3
+
+ if (EpDesc->EndpointAddress & BIT7) {
+ Dci++; // IN
+ EpType += 4; // 5, 6, or 7
+ }
+ }
+
+ // Update ContextEntries in the Slot context
+ if (Dci > SlotCtx->ContextEntries) {
+ SlotCtx->ContextEntries = Dci;
+ }
+
+ EpCtx = (XHCI_EP_CONTEXT*)XhciGetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, Dci + 1);
+
+ EpCtx->EpType = EpType;
+ EpCtx->MaxPacketSize = EpDesc->MaxPacketSize;
+ EpCtx->ErrorCount = 3;
+
+ // Set Interval
+ EpCtx->Interval = XhciTranslateInterval(EpType, DevSpeed, EpDesc->Interval);
+
+ XfrRing = XhciInitXfrRing(Usb3Hc, SlotId, Dci - 1);
+ EpCtx->TrDequeuePtr = (UINT64)(UINTN)XfrRing->Base + 1;
+
+ CtlCtx->AddContextFlags |= (1 << Dci);
+ }
+
+ // For a HUB update NumberOfPorts and TTT fields in the Slot context. For that get hub descriptor
+ // and use bNbrPorts and TT Think time fields (11.23.2.1 of USB2 specification)
+ // Notes:
+ // - Slot.Hub field is already updated
+ // - Do not set NumberOfPorts and TTT fields for 0.95 controllers
+
+ if (IsHub) {
+
+ EFI_STATUS Status;
+ EFI_USB_HUB_DESCRIPTOR HubDesc;
+ UINT8 Speed;
+ EFI_USB_DEVICE_REQUEST DevReq;
+ UINT32 Timeout;
+ UINTN DataLength = sizeof(EFI_USB_HUB_DESCRIPTOR);
+ UINT32 TransferResult;
+
+ //
+ // Fill Device request packet
+ //
+ (**PeiServices).SetMem((VOID*)&DevReq, sizeof(EFI_USB_DEVICE_REQUEST), 0);
+ DevReq.RequestType = USB_RT_HUB | 0x80;
+ DevReq.Request = USB_DEV_GET_DESCRIPTOR;
+ DevReq.Value = DevSpeed == XHCI_DEVSPEED_SUPER ? USB_DT_SS_HUB << 8 : USB_DT_HUB << 8;
+ DevReq.Index = 0;
+ DevReq.Length = sizeof(EFI_USB_HUB_DESCRIPTOR);
+
+ Timeout = 3000;
+
+ switch (DevSpeed) {
+ case XHCI_DEVSPEED_HIGH: Speed = USB_HIGH_SPEED_DEVICE; break;
+ case XHCI_DEVSPEED_LOW: Speed = USB_SLOW_SPEED_DEVICE; break;
+ case XHCI_DEVSPEED_FULL: Speed = USB_FULL_SPEED_DEVICE; break;
+ case XHCI_DEVSPEED_SUPER: Speed = USB_SUPER_SPEED_DEVICE;
+ }
+
+ EpCtx = (XHCI_EP_CONTEXT*)XhciGetContextEntry(Usb3Hc, DevCtx, 1);
+
+ Status = XhciHcControlTransfer(PeiServices, This,
+ 0, // Current address
+ Speed,
+ EpCtx->MaxPacketSize,
+ 0, // Transaction translator
+ &DevReq,
+ EfiUsbDataIn,
+ &HubDesc,
+ &DataLength,
+ Timeout,
+ &TransferResult);
+
+ if (!EFI_ERROR(Status)) {
+ SlotCtx->Hub = 1;
+ SlotCtx->PortsNum = HubDesc.NbrPorts;
+
+ if (DevSpeed == XHCI_DEVSPEED_HIGH) {
+ SlotCtx->TThinkTime = (HubDesc.HubCharacteristics[0] >> 5) & 0x3;
+ }
+ }
+ }
+
+// check route string here
+ // Input context is updated with the endpoint information. Execute ConfigureEndpoint command.
+ Status = XhciExecuteCommand(PeiServices, Usb3Hc, XhciTConfigureEndpointCmd, &SlotId);
+ PEI_ASSERT(PeiServices, Status == EFI_SUCCESS);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciGetXfrRing
+//
+// Description:
+// This routine calculates the address of the address ring of a particular
+// Slot/Endpoint.
+//
+// Output:
+// Pointer to the transfer ring
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TRB_RING*
+XhciGetXfrRing(
+ USB3_CONTROLLER* Usb3Hc,
+ UINT8 Slot,
+ UINT8 Ep
+)
+{
+ return Usb3Hc->XfrRings + (Slot-1)*32 + Ep;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XhciGetTheDoorbell
+//
+// Description:
+// This function calculates and returns the pointer to a doorbell for a
+// given Slot.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32*
+XhciGetTheDoorbell(
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 SlotId
+)
+{
+ return (UINT32*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->DbOffset + sizeof(UINT32)*SlotId);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XhciGetDeviceContext
+//
+// Description:
+// This function calculates and returns the pointer to a device context for
+// a given Slot.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8*
+XhciGetDeviceContext(
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 SlotId
+)
+{
+ UINT32 DevCtxSize = XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize;
+ return (UINT8*)((UINTN)Usb3Hc->DeviceContext + (SlotId - 1) * DevCtxSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XhciGetContextEntry
+//
+// Description:
+// This function calculates and returns the pointer to a context entry for
+// a given index.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8*
+XhciGetContextEntry(
+ USB3_CONTROLLER *Usb3Hc,
+ VOID *Context,
+ UINT8 Index
+)
+{
+ return (UINT8*)((UINTN)Context + Index * Usb3Hc->ContextSize);
+}
+ //(EIP75547+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciEnableUsb2Port
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+XhciResetUsb2Port(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc
+)
+{
+ UINT8 Count;
+ UINT8 PortNumber;
+ volatile XHCI_PORTSC *PortSC;
+ UINT32 i;
+
+ if (Usb3Hc->Usb2Protocol) {
+ for(Count = 0; Count < Usb3Hc->Usb2Protocol->PortCount; Count++) {
+ PortNumber = Count + Usb3Hc->Usb2Protocol->PortOffset;
+ PortSC =(XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNumber - 1)));
+ if (PortSC->Field.Ccs) {
+ if(!(PortSC->Field.Ped)) {
+ PortSC->AllBits = XHCI_PCS_PR | XHCI_PCS_PP;
+ for (i = 0; i < 200; i++) {
+ XHCI_FIXED_DELAY_MS(Usb3Hc, 1);
+ if (PortSC->Field.Prc) break;
+ }
+ PortSC->AllBits = XHCI_PCS_WRC | XHCI_PCS_PRC | XHCI_PCS_PP;
+ }
+ }
+ }
+ }
+
+ }
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciExtCapParser
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciExtCapParser(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc
+)
+{
+ XHCI_EXT_CAP *CurPtr;
+
+ if (Usb3Hc->CapRegs->HcParams.Xecp == 0) return EFI_SUCCESS;
+
+ // Starts from first capability
+ CurPtr = (XHCI_EXT_CAP *)((UINTN)Usb3Hc->CapRegs + (Usb3Hc->CapRegs->HcParams.Xecp << 2));
+
+ // Traverse all capability structures
+ for(;;) {
+ switch (CurPtr->CapId) {
+ case XHCI_EXT_CAP_USB_LEGACY:
+ break;
+ case XHCI_EXT_CAP_SUPPORTED_PROTOCOL:
+ if (((XHCI_EXT_PROTOCOL*)CurPtr)->MajorRev == 0x02) {
+ Usb3Hc->Usb2Protocol = (XHCI_EXT_PROTOCOL*)CurPtr;
+ PEI_TRACE((-1, PeiServices, "XHCI: USB2 Support Protocol %x, PortOffset %x PortCount %x\n",
+ Usb3Hc->Usb2Protocol, Usb3Hc->Usb2Protocol->PortOffset, Usb3Hc->Usb2Protocol->PortCount));
+ } else if (((XHCI_EXT_PROTOCOL*)CurPtr)->MajorRev == 0x03) {
+ Usb3Hc->Usb3Protocol = (XHCI_EXT_PROTOCOL*)CurPtr;
+ PEI_TRACE((-1, PeiServices, "XHCI: USB3 Support Protocol %x, PortOffset %x PortCount %x\n",
+ Usb3Hc->Usb3Protocol, Usb3Hc->Usb3Protocol->PortOffset, Usb3Hc->Usb3Protocol->PortCount));
+ }
+ break;
+
+ case XHCI_EXT_CAP_POWERMANAGEMENT:
+ case XHCI_EXT_CAP_IO_VIRTUALIZATION:
+ case XHCI_EXT_CAP_USB_DEBUG_PORT:
+ break;
+ }
+ if(CurPtr->NextCapPtr == 0) break;
+ // Point to next capability
+ CurPtr=(XHCI_EXT_CAP *)((UINTN)CurPtr+ (((UINTN)CurPtr->NextCapPtr) << 2));
+ }
+
+ return EFI_SUCCESS;
+}
+ //(EIP75547+)
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/UsbRecovery/XhciPEI/XhciPei.cif b/Core/EM/UsbRecovery/XhciPEI/XhciPei.cif
new file mode 100644
index 0000000..918bf2a
--- /dev/null
+++ b/Core/EM/UsbRecovery/XhciPEI/XhciPei.cif
@@ -0,0 +1,9 @@
+<component>
+ name = "XhciPei"
+ category = ModulePart
+ LocalRoot = "core\em\UsbRecovery\XhciPEI\"
+ RefName = "XhciPei"
+[files]
+"XhciPei.c"
+"XhciPei.h"
+<endComponent>
diff --git a/Core/EM/UsbRecovery/XhciPEI/XhciPei.h b/Core/EM/UsbRecovery/XhciPEI/XhciPei.h
new file mode 100644
index 0000000..bb9f667
--- /dev/null
+++ b/Core/EM/UsbRecovery/XhciPEI/XhciPei.h
@@ -0,0 +1,1245 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/XhciPei.h 5 11/24/12 5:45a Ryanchou $
+//
+// $Revision: 5 $
+//
+// $Date: 11/24/12 5:45a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/XhciPei.h $
+//
+// 5 11/24/12 5:45a Ryanchou
+// [TAG] EIP103990
+// [Category] Improvement
+// [Description] Synchronized with USB PEI module 4.6.3_USB_08.10.24.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// BotPeim.c, BotPeim.h, PeiAtapi.c, UsbBotPeim.c, UsbBotPeim.h,
+// HubPeim.c, UsbPeim.c, XhciPei.c, XhciPei.h, HubPeim.h, PeiUsbLib.c,
+// PeiUsbLib.h, UsbPeim.h
+//
+// 4 4/24/12 10:19p Wilsonlee
+// [TAG] EIP75547
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Xhci recovery funtion failed when SS devices on USB 3.0
+// port.
+// [RootCause] The SS device connected to USB2 port.
+// [Solution] Reset the USB2 port when initial xhci controller, then the
+// SS device reconnect to USB3 port.
+// [Files] XhciPei.c, XhciPei.h
+//
+// 3 1/18/11 1:09a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 2 1/17/11 7:09a Ryanchou
+// [TAG] EIP48013
+// [Category] Improvement
+// [Description] Use 32 or 64 byte Context data structures dynamically.
+// [Files] XhciPei.c, XhciPei.h
+//
+// 1 10/11/10 4:53p Olegi
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: XhciPei.h
+//
+// Description:
+// This file is the main header file for the EHCI PEI USB recovery module. It
+// contains generic constant and type declarations/definitions.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _XHCIPEI_H
+#define _XHCIPEI_H
+
+#include <PEI.h>
+#include "PPI\UsbHostController.h"
+#include "PPI\Stall.h"
+
+//----------------------------------------------------------------------------
+// XHCI_PCI_ADDRESS( ControllerIndex, Register )
+//
+// allows easy generation of a valid PCI address using an index into the
+// gXhciControllerPciTable and a register number
+#define XHCI_PCI_ADDRESS( ControllerIndex, Register ) PEI_PCI_CFG_ADDRESS( \
+ gXhciControllerPciTable[ControllerIndex].Bus, \
+ gXhciControllerPciTable[ControllerIndex].Device, \
+ gXhciControllerPciTable[ControllerIndex].Function, \
+ Register )
+
+#define XHCI_FIXED_DELAY_MS( Usb3Hc, milliseconds ) \
+ Usb3Hc->StallPpi->Stall( Usb3Hc->PeiServices, Usb3Hc->StallPpi, milliseconds * 1000 );
+
+#define XHCI_FIXED_DELAY_15MCS( Usb3Hc, units ) \
+ Usb3Hc->StallPpi->Stall( Usb3Hc->PeiServices, Usb3Hc->StallPpi, units * 15 );
+
+// CountTime(milliseconds * 1000, PM_BASE_ADDRESS);
+
+#define XHCI_SWITCH2SS_DELAY_MS 5
+#define MAX_CONTROL_DATA_SIZE 0x200
+
+#define EP_DESC_FLAG_TYPE_BITS 0x03 //Bit 1-0: Indicate type of transfer on endpoint
+#define EP_DESC_FLAG_TYPE_CONT 0x00 //Bit 1-0: 00 = Endpoint does control transfers
+#define EP_DESC_FLAG_TYPE_ISOC 0x01 //Bit 1-0: 01 = Endpoint does isochronous transfers
+#define EP_DESC_FLAG_TYPE_BULK 0x02 //Bit 1-0: 10 = Endpoint does bulk transfers
+#define EP_DESC_FLAG_TYPE_INT 0x03 //Bit 1-0: 11 = Endpoint does interrupt transfers
+
+#pragma pack(push,1)
+
+typedef struct {
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+} PCI_BUS_DEV_FUNCTION;
+
+typedef struct {
+ UINT8 Bus;
+ UINT8 Device;
+ UINT8 Function;
+ UINT32 Register;
+ UINT8 Size;
+ UINT32 SetBits;
+ UINT32 ClearBits;
+} PCI_DEV_REGISTER_VALUE;
+/*
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT16 wUsbSpecVersion;
+ UINT8 bBaseClass;
+ UINT8 bSubClass;
+ UINT8 bProtocol;
+ UINT8 bEndp0MaxPacket;
+ UINT16 wVendorId;
+ UINT16 wDeviceId;
+ UINT16 wDeviceRev;
+ UINT8 bMfgStr;
+ UINT8 bProductStr;
+ UINT8 bSerialStr;
+ UINT8 bNumConfigs;
+} DEV_DESC;
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT16 wTotalLength;
+ UINT8 bNumInterfaces;
+ UINT8 bConfigValue;
+ UINT8 bConfigString;
+ UINT8 bConfigFlags;
+ UINT8 bConfigPower;
+} CNFG_DESC;
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT8 bInterfaceNum;
+ UINT8 bAltSettingNum;
+ UINT8 bNumEndpoints;
+ UINT8 bBaseClass;
+ UINT8 bSubClass;
+ UINT8 bProtocol;
+ UINT8 bInterfaceString;
+}INTRF_DESC;
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT8 bNumPorts; // Number of downstream ports on hub
+ UINT16 wHubFlags; // See HUB_FLAG_xxx bit definitions below
+ UINT8 bPowerOnDelay; // Time to delay after turning on power to port (in 2ms units)
+ UINT8 bHubControlAmps; // Milliamps of current needed by hub controller
+
+ UINT8 bDeviceRemovable; // Variable size array of bits (one for each port)
+} HUB_DESC;
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT8 bEndpointAddr;
+ UINT8 bEndpointFlags;
+ UINT16 wMaxPacketSize;
+ UINT8 bPollInterval;
+} ENDP_DESC;
+*/
+// XHCI_EP_CONTEXT.DW0.State definitions
+#define XHCI_EP_STATE_DISABLED 0
+#define XHCI_EP_STATE_RUNNING 1
+#define XHCI_EP_STATE_HALTED 2
+#define XHCI_EP_STATE_STOPPED 3
+#define XHCI_EP_STATE_ERROR 4
+
+// XHCI_EP_CONTEXT.DW1.EpType definitions
+#define XHCI_EP_TYPE_NOTVALID 0
+#define XHCI_EP_TYPE_ISO_OUT 1
+#define XHCI_EP_TYPE_BLK_OUT 2
+#define XHCI_EP_TYPE_INT_OUT 3
+#define XHCI_EP_TYPE_CONTROL 4
+#define XHCI_EP_TYPE_ISO_IN 5
+#define XHCI_EP_TYPE_BLK_IN 6
+#define XHCI_EP_TYPE_INT_IN 7
+
+//---------------------------------------------------------
+// Device context definition
+//---------------------------------------------------------
+
+// TRB completion codes Table 130
+#define XHCI_TRB_INVALID 0
+#define XHCI_TRB_SUCCESS 1
+#define XHCI_TRB_DATABUF_ERROR 2
+#define XHCI_TRB_BABBLE_ERROR 3
+#define XHCI_TRB_TRANSACTION_ERROR 4
+#define XHCI_TRB_TRB_ERROR 5
+#define XHCI_TRB_STALL_ERROR 6
+#define XHCI_TRB_RESOURCE_ERROR 7
+#define XHCI_TRB_BANDWIDTH_ERROR 8
+#define XHCI_TRB_OUTOFSLOTS_ERROR 9
+#define XHCI_TRB_INVALIDSTREAMTYPE_ERROR 10
+#define XHCI_TRB_SLOTNOTENABLED_ERROR 11
+#define XHCI_TRB_ENDPOINTNOTENABLED_ERROR 12
+#define XHCI_TRB_SHORTPACKET 13
+#define XHCI_TRB_RINGUNDERRUN 14
+#define XHCI_TRB_RINGOVERRUN 15
+#define XHCI_TRB_VFRINGFULL_ERROR 16
+#define XHCI_TRB_PARAMETER_ERROR 17
+#define XHCI_TRB_BANDWIDTHOVERRUN_ERROR 18
+#define XHCI_TRB_CONTEXTSTATE_ERROR 19
+#define XHCI_TRB_NOPINGRESPONSE_ERROR 20
+#define XHCI_TRB_EVENTRINGFULL_ERROR 21
+#define XHCI_TRB_MISSEDSERVICE_ERROR 23
+#define XHCI_TRB_CMDRINGSTOPPED 24
+#define XHCI_TRB_COMMANDABORTED 25
+#define XHCI_TRB_STOPPED 26
+#define XHCI_TRB_STOPPEDLENGTHINVALID 27
+#define XHCI_TRB_CONTROLABORT_ERROR 28
+#define XHCI_TRB_ISOCHBUFOVERRUN 31
+#define XHCI_TRB_EVENTLOST_ERROR 32
+#define XHCI_TRB_UNDEFINED_ERROR 33
+#define XHCI_TRB_INVALIDSTREAMID_ERROR 34
+#define XHCI_TRB_SECONDARYBANDWIDTH_ERROR 35
+#define XHCI_TRB_SPLITTRANSACTION_ERROR 36
+
+#define XHCI_TRB_EXECUTION_TIMEOUT_ERROR 255
+
+//---------------------------------------------------------
+// Transfer Descriptor Block (TRB) definitions, section 4.11
+//---------------------------------------------------------
+// TRB Template
+typedef struct {
+ UINT32 Param1;
+ UINT32 Param2;
+
+ UINT32 RsvdZ1 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 16;
+} XHCI_TRB;
+
+// Event TRB types, Section 6.4.2
+typedef struct {
+ UINT64 TrbPtr;
+
+ UINT32 TransferLength : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ1 : 1;
+ UINT32 EventData : 1;
+ UINT32 RsvdZ2 : 7;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RzvdZ3 : 3;
+ UINT32 SlotId : 8;
+} XHCI_TRANSFER_EVT_TRB;
+
+typedef struct {
+ UINT64 CmdTrbPtr;
+
+ UINT32 RsvdZ1 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 VfId : 8;
+ UINT32 SlotId : 8;
+} XHCI_CMDCOMPLETE_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1 : 24;
+ UINT32 PortId : 8;
+
+ UINT32 RsvdZ2;
+
+ UINT32 RsvdZ3 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ4 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ5 : 16;
+} XHCI_PORTSTSCHG_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[2];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 8;
+ UINT32 SlotId : 8;
+} XHCI_BANDWIDTHRQ_EVT_TRB;
+
+typedef struct {
+ UINT32 DbReason : 5;
+ UINT32 RsvdZ1 : 27;
+
+ UINT32 Rsvd2;
+
+ UINT32 RsvdZ3 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ4 : 9;
+ UINT32 TrbType : 6;
+ UINT32 VfId : 8;
+ UINT32 SlotId : 8;
+} XHCI_DORBELL_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[2];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 16;
+} XHCI_HC_EVT_TRB;
+
+typedef struct {
+ UINT8 RsvdZ1 : 4;
+ UINT8 NtfType : 4;
+
+ UINT8 DevNtfData[7];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 8;
+ UINT32 SlotId : 8;
+} XHCI_DEVNOTIFY_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ[2];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 16;
+} XHCI_MFINDXWRAP_EVT_TRB;
+
+typedef union {
+ XHCI_TRANSFER_EVT_TRB TransferEvt;
+ XHCI_CMDCOMPLETE_EVT_TRB CmdEvt;
+ XHCI_PORTSTSCHG_EVT_TRB PortStsChgEvt;
+ XHCI_BANDWIDTHRQ_EVT_TRB BandwidthRqEvt;
+ XHCI_DORBELL_EVT_TRB DoorbellEvt;
+ XHCI_HC_EVT_TRB HcEvt;
+ XHCI_DEVNOTIFY_EVT_TRB DevNotificationEvt;
+ XHCI_MFINDXWRAP_EVT_TRB MicroframeIndxWrapEvt;
+} XHCI_EVENT_TRB;
+
+// Command TRB types, Section 6.4.3
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 16;
+} XHCI_COMMON_CMD_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 8;
+ UINT32 SlotId : 8;
+} XHCI_DISABLESLOT_CMD_TRB;
+
+typedef struct {
+ UINT64 InpCtxAddress;
+ UINT32 RsvdZ1;
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 8;
+ UINT32 Bsr : 1;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 8;
+ UINT32 SlotId : 8;
+} XHCI_ADDRESSDEV_CMD_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 8;
+ UINT32 Tsp : 1;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RsvdZ3 : 3;
+ UINT32 SlotId : 8;
+} XHCI_RESET_EP_CMD_TRB;
+
+typedef struct {
+ UINT64 TrPointer;
+
+ UINT32 RsvdZ1 :16;
+ UINT32 StreamId :16;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RsvdZ3 : 3;
+ UINT32 SlotId : 8;
+} XHCI_SET_TRPTR_CMD_TRB;
+
+typedef union {
+ XHCI_COMMON_CMD_TRB GenericCmdTrb;
+ XHCI_COMMON_CMD_TRB NoOpCmdTrb;
+ XHCI_COMMON_CMD_TRB EnableSlotCmdTrb;
+ XHCI_DISABLESLOT_CMD_TRB DisableSlotCmdTrb;
+ XHCI_ADDRESSDEV_CMD_TRB AddressDevCmdTrb;
+ XHCI_SET_TRPTR_CMD_TRB SetTrPtrCmdTrb;
+} XHCI_CMD_TRB;
+
+// Transfer TRB types, Section 6.4.1
+
+typedef struct {
+ UINT64 DataBuffer;
+
+ UINT32 XferLength : 17;
+ UINT32 TdSize : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 Isp : 1;
+ UINT32 NoSnoop : 1;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ1 : 2;
+ UINT32 Bei : 1;
+ UINT32 TrbType : 6;
+ UINT32 Rsvd2 : 16;
+} XHCI_NORMAL_XFR_TRB;
+
+#define XHCI_XFER_TYPE_NO_DATA 0
+#define XHCI_XFER_TYPE_DATA_OUT 2
+#define XHCI_XFER_TYPE_DATA_IN 3
+
+typedef struct {
+ UINT8 bmRequestType;
+ UINT8 bRequest;
+ UINT16 wValue;
+ UINT16 wIndex;
+ UINT16 wLength;
+
+ UINT32 XferLength : 17;
+ UINT32 RsvdZ1 : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 4;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ3 : 3;
+ UINT32 TrbType : 6;
+ UINT32 Trt : 2;
+ UINT32 RsvdZ4 : 14;
+} XHCI_SETUP_XFR_TRB;
+
+typedef struct {
+ UINT64 DataBuffer;
+
+ UINT32 XferLength : 17;
+ UINT32 TdLength : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 Isp : 1;
+ UINT32 NoSnoop : 1;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ1 : 3;
+ UINT32 TrbType : 6;
+ UINT32 Dir : 1;
+ UINT32 Rsvd2 : 15;
+} XHCI_DATA_XFR_TRB;
+
+typedef struct {
+ UINT64 RsvdZ1;
+
+ UINT32 RsvdZ2 : 22;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 RsvdZ3 : 2;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 RsvdZ4 : 4;
+ UINT32 TrbType : 6;
+ UINT32 Dir : 1;
+ UINT32 Rsvd2 : 15;
+} XHCI_STATUS_XFR_TRB;
+
+typedef struct {
+ UINT64 DataBuffer;
+
+ UINT32 XferLength : 17;
+ UINT32 TdLength : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 Isp : 1;
+ UINT32 NoSnoop : 1;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ1 : 3;
+ UINT32 TrbType : 6;
+ UINT32 Rsvd2 : 4;
+ UINT32 FrameId : 11;
+ UINT32 Sia : 1;
+} XHCI_ISOCH_XFR_TRB;
+
+typedef struct {
+ UINT64 RsvdZ1;
+
+ UINT32 RsvdZ2 : 22;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 RsvdZ3 : 2;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 RsvdZ4 : 4;
+ UINT32 TrbType : 6;
+ UINT32 Rsvd2 : 16;
+} XHCI_NOOP_XFR_TRB;
+
+typedef union {
+ XHCI_NORMAL_XFR_TRB NormalXfrTrb;
+ XHCI_SETUP_XFR_TRB SetupXfrTrb;
+ XHCI_DATA_XFR_TRB DataXfrTrb;
+ XHCI_STATUS_XFR_TRB StatusXfrTrb;
+ XHCI_ISOCH_XFR_TRB IsockXfrTrb;
+ XHCI_NOOP_XFR_TRB NoopXfrTrb;
+} XHCI_XFR_TRB;
+
+
+// Other TRB types
+typedef struct {
+ UINT64 NextSegPtr;
+
+ UINT32 RsvdZ1 : 22;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 ToggleCycle : 1;
+ UINT32 RsvdZ2 : 2;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 RsvdZ3 : 4;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 16;
+} XHCI_LINK_TRB;
+
+typedef struct {
+ XHCI_TRB *Base;
+ UINT32 Size; // #of TRBs in the ring
+ XHCI_TRB* LastTrb;
+ XHCI_TRB* QueuePtr;
+ UINT8 CycleBit;
+ UINT8 Pad[27-3*sizeof(VOID*)]; // Make size 32 Bytes
+} TRB_RING;
+
+// The following definition fixes the size of ring
+// segment to TRBS_PER_SEGMENT * sizeof(XHCI_TRB)
+#define TRBS_PER_SEGMENT 64
+#define RING_SIZE TRBS_PER_SEGMENT*sizeof(XHCI_TRB)
+
+// Default timeouts
+#define XHCI_CMD_COMPLETE_TIMEOUT_MS 500
+#define XHCI_CTL_COMPLETE_TIMEOUT_MS 2000
+#define XHCI_BULK_COMPLETE_TIMEOUT_MS 10000
+#define XHCI_INT_COMPLETE_TIMEOUT_MS 1500
+
+//#define XHCI_BOT_TD_MAXSIZE 512
+#define XHCI_BOT_TD_MAXSIZE 0x10000
+#define XHCI_BOT_MAX_XFR_SIZE XHCI_BOT_TD_MAXSIZE*8
+
+typedef struct {
+ UINT32 RouteString : 20;
+ UINT32 Speed : 4;
+ UINT32 RsvdZ1 : 1;
+ UINT32 MultiTT : 1;
+ UINT32 Hub : 1;
+ UINT32 ContextEntries : 5;
+
+ UINT32 MaxExitLatency : 16;
+ UINT32 RootHubPort : 8;
+ UINT32 PortsNum : 8;
+
+ UINT32 TtHubSlotId : 8;
+ UINT32 TtPortNumber : 8;
+ UINT32 TThinkTime : 2;
+ UINT32 RsvdZ3 : 4;
+ UINT32 Interrupter : 10;
+
+ UINT32 DevAddr : 8;
+ UINT32 RsvdZ4 : 19;
+ UINT32 SlotState : 5;
+
+ UINT32 RsvdO[4];
+} XHCI_SLOT_CONTEXT;
+
+// XHCI_SLOT_CONTEXT.DW3.SlotState definitions
+#define XHCI_SLOT_STATE_DISABLED 0
+#define XHCI_SLOT_STATE_DEFAULT 1
+#define XHCI_SLOT_STATE_ADDRESSED 2
+#define XHCI_SLOT_STATE_CONFIGURED 3
+
+// Endpoint types, Table 57
+#define XHCI_EPTYPE_NOT_VALID 0
+#define XHCI_EPTYPE_ISOCH_OUT 1
+#define XHCI_EPTYPE_BULK_OUT 2
+#define XHCI_EPTYPE_INT_OUT 3
+#define XHCI_EPTYPE_CTL 4
+#define XHCI_EPTYPE_ISOCH_IN 5
+#define XHCI_EPTYPE_BULK_IN 6
+#define XHCI_EPTYPE_INT_IN 7
+
+typedef struct {
+ UINT32 EpState : 3;
+ UINT32 RsvdZ1 : 5;
+ UINT32 Mult : 2;
+ UINT32 MaxPStreams : 5;
+ UINT32 Lsa : 1;
+ UINT32 Interval : 8;
+ UINT32 RzvdZ2 : 8;
+
+ UINT32 ForceEvent : 1;
+ UINT32 ErrorCount : 2;
+ UINT32 EpType : 3;
+ UINT32 RsvdZ : 1;
+ UINT32 Hid : 1;
+ UINT32 MaxBurstSize : 8;
+ UINT32 MaxPacketSize : 16;
+
+ UINT64 TrDequeuePtr; // BIT0 of this field is DCS (Dequeue Cycle State)
+ UINT16 AvgTrbLength;
+ UINT16 MaxEsitPayload;
+ UINT32 RsvdO[3];
+} XHCI_EP_CONTEXT;
+
+typedef struct {
+ UINT32 DropContextFlags;
+ UINT32 AddContextFlags;
+ UINT32 RzvdZ[6];
+} XHCI_INPUT_CONTROL_CONTEXT;
+
+typedef struct {
+ XHCI_SLOT_CONTEXT Slot;
+ XHCI_EP_CONTEXT Ep[31];
+} XHCI_DEVICE_CONTEXT;
+
+#define XHCI_DEVICE_CONTEXT_ENTRIES 32
+
+typedef struct {
+ XHCI_INPUT_CONTROL_CONTEXT CtlCtx;
+ XHCI_DEVICE_CONTEXT DevCtx;
+} XHCI_INPUT_CONTEXT;
+
+#define XHCI_INPUT_CONTEXT_ENTRIES 33
+
+ //(EIP75547+)>
+//---------------------------------------------------------
+// Extended Capabilities
+//---------------------------------------------------------
+#define XHCI_EXT_CAP_USB_LEGACY 1
+#define XHCI_EXT_CAP_SUPPORTED_PROTOCOL 2
+#define XHCI_EXT_CAP_POWERMANAGEMENT 3
+#define XHCI_EXT_CAP_IO_VIRTUALIZATION 4
+#define XHCI_EXT_CAP_USB_DEBUG_PORT 10
+
+typedef struct {
+ UINT32 CapId:8; // Capability ID
+ UINT32 NextCapPtr:8; // Next xHCI Extended Capability Pointer
+ UINT32 Cap:16; // Capability Specific
+} XHCI_EXT_CAP;
+ //<(EIP75547+)
+
+typedef struct {
+ UINT64 ScratchpadBufArrayPtr;
+ UINT64 DevCntxtAddr[255];
+} XHCI_DCBAA; // Total size is 256 64-bit entries, or 2K Bytes (section 6.1)
+// XHCI PCI Configuration Registers
+//---------------------------------------------------------------------------
+
+// Serial Bus Release Number Register
+#define XHCI_PCI_SBRN 0x60
+
+// Frame Length Adjustment Register
+#define XHCI_PCI_FLADJ 0x61
+
+// Host Controller Capability Registers
+//---------------------------------------------------------------------------
+
+typedef struct {
+ UINT32 MaxSlots : 8; // Number of Device Slots
+ UINT32 MaxIntrs : 11; // Number of Interrupters
+ UINT32 Rsvd : 5; // Reserved
+ UINT32 MaxPorts : 8; // Number of ports
+} HCPARAMS1;
+
+typedef struct {
+ UINT32 Ist : 4; // Isochronous Scheduling Threshold
+ UINT32 ErstMax : 4; // Event Ring Segment Table Max
+ UINT32 Rsvd : 18;
+ UINT32 Spr : 1; // Scratchpad restore
+ UINT32 MaxScratchPadBufs : 5; // Number of scratchpad buffers
+} HCPARAMS2;
+
+typedef struct {
+ UINT32 U1DevExitLatency : 8; // Worst case latency of U1->U0, mks
+ UINT32 Rsvd : 8;
+ UINT32 U2DevExitLatency : 16; // Worst case latency of U2->U0, mks
+} HCPARAMS3;
+
+typedef struct {
+ UINT32 Ac64 : 1; // 64-bit Addressing Capability
+ UINT32 Bnc : 1; // Bandwidth Negotiation Capability
+ UINT32 Csz : 1; // Context data structures width (32 or 64 bit)
+ UINT32 Ppc : 1; // Power Port Control
+ UINT32 Pind : 1; // Port Indicators
+ UINT32 Lhrc : 1; // Light HC Reset Capability
+ UINT32 Ltc : 1; // Latency Tolerance Capability
+ UINT32 Nss : 1; // No Secondary SID Support
+ UINT32 Rsvd : 4;
+ UINT32 MaxPsaSize : 4; // Maximum Primary Stream Array Size
+ UINT32 Xecp : 16; // xHCI Extended Capabilities Pointer
+} HCPARAMS;
+
+typedef struct {
+ UINT8 CapLength; // 00
+ UINT8 Rsvd; // 01
+ UINT16 HciVersion; // 02
+ HCPARAMS1 HcParams1; // 04
+ HCPARAMS2 HcParams2; // 08
+ HCPARAMS3 HcParams3; // 0C
+ HCPARAMS HcParams; // 10
+ UINT32 DbOff; // 14
+ UINT32 RtsOff; // 18
+} XHCI_HC_CAP_REGS;
+
+//-----------------------------------------------------------
+// Host Controller Operational Registers
+//-----------------------------------------------------------
+typedef struct {
+ UINT32 RunStop : 1;
+ UINT32 HcRst : 1; // HC Reset
+ UINT32 Inte : 1; // Interrupter Enable
+ UINT32 HsEe : 1; // Host System Error Enable
+ UINT32 Rsvd : 3;
+ UINT32 LhcRst : 1; // Light Host Controller Reset
+ UINT32 Css : 1; // Controller Save State
+ UINT32 Crs : 1; // Controller Restore State
+ UINT32 Ewe : 1; // Enable Wrap Event
+ UINT32 Eu3S : 1; // Enable U3 MFINDEX Stop
+ UINT32 Rsvd1 : 20;
+} XHCI_USBCMD;
+
+typedef struct {
+ union {
+ UINT32 AllBits; // can be used for clearing status
+ #define XHCI_STS_HALTED BIT0
+ #define XHCI_STS_HOSTSYSTEM_ERROR BIT2
+ #define XHCI_STS_EVT_INTERRUPT BIT3
+ #define XHCI_STS_PCD BIT4
+ struct {
+ UINT32 HcHalted : 1;
+ UINT32 Rsvd1 : 1;
+ UINT32 Hse : 1; // Host System Error
+ UINT32 Eint : 1; // Event Interrupt
+ UINT32 Pcd : 1; // Port Change Detect
+ UINT32 Rsvd2 : 3;
+ UINT32 Sss : 1; // Save State Status
+ UINT32 Rss : 1; // Restore State Status
+ UINT32 Sre : 1; // Save/Restore Error
+ UINT32 Cnr : 1; // Controller Not Ready
+ UINT32 Hce : 1; // Host Controller Error
+ UINT32 Rsvd3 : 19;
+ } Field;
+ };
+} XHCI_USBSTS;
+
+typedef struct {
+ UINT32 Rcs : 1; // Ring Cycle State
+ UINT32 Cs : 1; // Command Stop
+ UINT32 Ca : 1; // Command Abort
+ UINT32 Crr : 1; // Command Ring Running
+ UINT32 Rsvd : 2;
+ UINT32 CrPointer : 26; // Command Ring Pointer
+} XHCI_CRCR;
+
+#define XHCI_PORT_CONNECT BIT0
+#define XHCI_PORT_ENABLE BIT1
+#define XHCI_PORT_RESET BIT4
+#define XHCI_PORT_RESET_CHG BIT21
+
+#define XHCI_PORTSC_OFFSET 0x400
+
+// Port speed definitions as read from PortSpeed field of PORTSC
+#define XHCI_DEVSPEED_UNDEFINED 0
+#define XHCI_DEVSPEED_FULL 1
+#define XHCI_DEVSPEED_LOW 2
+#define XHCI_DEVSPEED_HIGH 3
+#define XHCI_DEVSPEED_SUPER 4
+
+typedef struct {
+ union {
+ UINT32 AllBits; // can be used for clearing status
+ #define XHCI_PCS_CCS BIT0
+ #define XHCI_PCS_PED BIT1
+ #define XHCI_PCS_OCA BIT3
+ #define XHCI_PCS_PR BIT4
+ #define XHCI_PCS_PP BIT9
+ #define XHCI_PCS_CSC BIT17
+ #define XHCI_PCS_PEC BIT18
+ #define XHCI_PCS_WRC BIT19 //(EIP75547+)
+ #define XHCI_PCS_OCC BIT20
+ #define XHCI_PCS_PRC BIT21
+ #define XHCI_PCS_WPR BIT31 //(EIP75547+)
+ struct {
+ UINT32 Ccs : 1; // 0 Current Connect Status - RO
+ UINT32 Ped : 1; // 1 Port Enabled/Disabled - RW1CS
+ UINT32 RsvdZ1 : 1; // 2
+ UINT32 Oca : 1; // 3 Over-current Active - RO
+ UINT32 Pr : 1; // 4 Port Reset - RW1S
+ UINT32 Pls : 4; // 5..8 Port Link State - RWS
+ UINT32 Pp : 1; // 9 Port Power - RWS
+ UINT32 PortSpeed : 4; // 10..13 Port Speed - RO
+ UINT32 Pic : 2; // 14..15 Port Indicator Ctl - RWS
+ UINT32 Lws : 1; // 16 Port Link State Write Strobe - RW
+ UINT32 Csc : 1; // 17 Connect Status Change - RW1CS
+ UINT32 Pec : 1; // 18 Port Enabled/Disabled Change - RW1CS
+ UINT32 Wrc : 1; // 19 Warm Port Reset Change - RW1CS/RsvdZ
+ UINT32 Occ : 1; // 20 Over-current Change - RW1CS
+ UINT32 Prc : 1; // 21 Port Reset Change - RW1CS
+ UINT32 Plc : 1; // 22 Port Link State Change - RW1CS
+ UINT32 Cec : 1; // 23 Port Config Error Change - RW1CS/RsvdZ
+ UINT32 Cas : 1; // 24 Cold Attach Status - RO //(EIP75547)
+ UINT32 Wce : 1; // 25 Wake on Connect Enable - RWS
+ UINT32 Wde : 1; // 26 Wake on Disconnect Enable - RWS
+ UINT32 Woe : 1; // 27 Wake on Over-current Enable - RWS
+ UINT32 RsvdZ2 : 2; // 28..29 //(EIP75547)
+ UINT32 Dr : 1; // 30 Device Removable (0 removable) - RO
+ UINT32 Wpr : 1; // 31 Warm Port Reset - RW1S/RsvdZ
+ } Field;
+ };
+} XHCI_PORTSC;
+
+typedef struct {
+ XHCI_USBCMD UsbCmd; // 00
+ XHCI_USBSTS UsbSts; // 04
+ UINT32 PageSize; // 08
+ UINT8 Rsvd1[8]; // 0C
+ UINT32 DnCtrl; // 14 Device Notification Control
+ UINT64 Crcr; // 18 Command Ring Control
+ UINT8 Rsvd2[16]; // 20
+ UINT64 DcbAap; // 30 Device Context Base Address Array Pointer
+ UINT32 Config; // 38 Max Device Slots Enabled
+} XHCI_HC_OP_REGS;
+
+// Minimum inter-interrupt interval, in 250ns units. The value of 4000 makes 1ms interval.
+#define XHCI_IMODI 4000
+
+// Note: the following structure defines 32-bit and 64-bits fields
+// without detailing; this MMIO data must be accessed using Dword
+// access for 32-bit fields and Qword access for 64-bit, Section 5.5.
+typedef struct {
+ UINT32 IMan; // Interrupter Management
+ UINT32 IMod; // Interrupter Moderation
+ UINT32 Erstz; // Event Ring Segment Table Size
+ UINT32 RsrvP;
+ UINT64 Erstba; // Event Ring Segment Table Base Address
+ UINT64 Erdp; // Event Ring Dequeue Pointer
+} XHCI_INTERRUPTER_REGS;
+
+typedef struct {
+ UINT32 MfIndex;
+ UINT32 Reserved[7];
+ XHCI_INTERRUPTER_REGS IntRegs[1024];
+} XHCI_HC_RT_REGS;
+
+typedef enum {
+ XhciTNormal = 1,
+ XhciTSetupStage, // 2
+ XhciTDataStage, // 3
+ XhciTStatusStage,// 4
+ XhciTIsoch, // 5
+ XhciTLink, // 6
+ XhciTEventData, // 7
+ XhciTNoOp, // 8
+ XhciTEnableSlotCmd, // 9
+ XhciTDisableSlotCmd, // 10
+ XhciTAddressDeviceCmd, // 11
+ XhciTConfigureEndpointCmd, //12
+ XhciTEvaluateContextCmd, //13
+ XhciTResetEndpointCmd, //14
+ XhciTStopEndpointCmd, // 15
+ XhciTSetTRDequeuePointerCmd, //16
+ XhciTResetDeviceCmd, // 17
+ XhciTForceEventCmd, // 18
+ XhciTNegotiateBandwidthCmd, // 19
+ XhciTSetLatencyToleranceCmd, // 20
+ XhciTGetPortBandwidthCmd, // 21
+ XhciTForceHeaderCmd, // 22
+ XhciTNoOpCmd, // 23
+// 24..31 reserved
+ XhciTTransferEvt = 32,
+ XhciTCmdCompleteEvt, // 33
+ XhciTPortStatusChgEvt, // 34
+ XhciTBandwidthRequestEvt, // 35
+ XhciTDoorbellEvt, // 36
+ XhciTHostControllerEvt, // 37
+ XhciTDevNotificationEvt, // 38
+ XhciTMfIndexWrapEvt // 39
+} TRB_TYPE;
+
+typedef struct {
+ UINT64 RsBase;
+ UINT16 RsSize;
+ UINT16 Rsvd1;
+ UINT32 Rsvd2;
+} XHCI_ER_SEGMENT_ENTRY;
+
+#define CRCR_RING_CYCLE_STATE BIT0
+
+#define TRBS_PER_SEGMENT 64
+#define RING_SIZE TRBS_PER_SEGMENT*sizeof(XHCI_TRB)
+
+typedef struct {
+ UINT8 SlotId;
+ UINT8 DevAddr;
+} PEI_XHCI_SLOTADDR_MAP;
+
+// Note that MaxSlots affects the size of USB3_CONTROLLER structure as
+// well as its data boundaries and alignment. Default value is 32; if a
+// different value needs to be assigned, make sure that boundaries and
+// alignment meets the requirements; do the padding as needed.
+// See XHCI specification Chapter 6 for the details.
+
+#define PEI_XHCI_MAX_SLOTS 32
+
+ //(EIP75547+)>
+typedef struct {
+ struct {
+ UINT32 CapId:8;
+ UINT32 NextCapPtr:8;
+ UINT32 MinorRev:8;
+ UINT32 MajorRev:8;
+ };
+
+ UINT32 NameString;
+
+ struct {
+ UINT32 PortOffset:8;
+ UINT32 PortCount:8;
+ UINT32 L1c:1; // L1 Capability
+ UINT32 Hso:1; // High-speed Only
+ UINT32 Ihi:1; // Integrated Hub Implemented
+ UINT32 RsvdZ:13;
+ };
+} XHCI_EXT_PROTOCOL;
+ //<(EIP75547+)
+
+typedef struct _USB3_CONTROLLER {
+ UINTN Dcbaa[PEI_XHCI_MAX_SLOTS]; // 32*4 = 128
+ UINT8 XfrTrb[RING_SIZE*PEI_XHCI_MAX_SLOTS*32];
+ UINT8 CommandRing[RING_SIZE];
+ UINT8 EventRing[RING_SIZE];
+
+ UINT8 DevCtx[PEI_XHCI_MAX_SLOTS * 0x800];
+ UINT8 InpCtx[0x840];
+ XHCI_ER_SEGMENT_ENTRY Erst;
+
+ UINT16 Vid;
+ UINT16 Did;
+ BOOLEAN Access64;
+ UINT16 HciVersion;
+ UINT8 MaxPorts;
+ UINT32 PageSize4K;
+ UINT8 ContextSize;
+ UINT16 MaxIntrs;
+ UINT32 DbOffset;
+ UINT8 MaxSlots;
+ VOID *InputContext;
+ TRB_RING CmdRing;
+ TRB_RING EvtRing;
+ TRB_RING XfrRing[PEI_XHCI_MAX_SLOTS*32]; // 32 endpoints per device
+ TRB_RING *XfrRings;
+ UINTN XfrTrbs;
+ VOID *DeviceContext;
+ XHCI_DCBAA *DcbaaPtr;
+ XHCI_HC_CAP_REGS *CapRegs;
+ XHCI_HC_OP_REGS *OpRegs;
+ XHCI_HC_RT_REGS *RtRegs;
+ XHCI_EXT_PROTOCOL *Usb2Protocol; //(EIP75547+)
+ XHCI_EXT_PROTOCOL *Usb3Protocol; //(EIP75547+)
+
+ PEI_XHCI_SLOTADDR_MAP DeviceMap[PEI_XHCI_MAX_SLOTS];
+
+ EFI_PEI_SERVICES **PeiServices;
+ PEI_USB_HOST_CONTROLLER_PPI UsbHostControllerPpi;
+ EFI_PEI_PPI_DESCRIPTOR PpiDescriptor;
+ EFI_PEI_CPU_IO_PPI *CpuIoPpi;
+ EFI_PEI_STALL_PPI *StallPpi;
+ EFI_PEI_PCI_CFG_PPI *PciCfgPpi;
+
+} USB3_CONTROLLER;
+
+#pragma pack(pop)
+
+//----------------------------------------------------------------------------
+// Function prototypes
+//----------------------------------------------------------------------------
+EFI_STATUS XhciHcControlTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT8 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data OPTIONAL,
+ IN OUT UINTN *DataLength OPTIONAL,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS XhciHcBulkTransfer (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINT16 MaximumPacketLength,
+ IN UINT16 TransactionTranslator OPTIONAL,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN TimeOut,
+ OUT UINT32 *TransferResult );
+
+EFI_STATUS XhciHcGetRootHubPortNumber (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ OUT UINT8 *PortNumber );
+
+EFI_STATUS XhciHcGetRootHubPortStatus (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ OUT EFI_USB_PORT_STATUS *PortStatus );
+
+EFI_STATUS XhciHcSetRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+EFI_STATUS XhciHcClearRootHubPortFeature (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature );
+
+EFI_STATUS XhciInitHC(
+ EFI_PEI_SERVICES **PeiServices,
+ struct _USB3_CONTROLLER *Usb3Hc,
+ UINT8 ControllerIndex);
+
+EFI_STATUS XhciHcPreConfigureDevice(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 Port,
+ IN UINT8 Speed,
+ IN UINT16 TransactionTranslator);
+
+EFI_STATUS XhciEnableEndpoints (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This,
+ IN UINT8 *Desc);
+
+VOID
+XhciMmio64Write(
+ USB3_CONTROLLER *Usb3Hc,
+ UINTN Address,
+ UINT64 Data);
+
+EFI_STATUS XhciInitRing(TRB_RING*, UINTN, UINT32, BOOLEAN);
+EFI_STATUS XhciExecuteCommand(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ TRB_TYPE Cmd,
+ VOID *Params
+);
+
+TRB_RING*
+XhciInitXfrRing(
+ USB3_CONTROLLER* Usb3Hc,
+ UINT8 Slot,
+ UINT8 Ep);
+
+EFI_STATUS
+UpdateDeviceMap(
+ PEI_XHCI_SLOTADDR_MAP *DeviceMap,
+ UINT8 SlotId,
+ UINT8 DevAddr);
+
+EFI_STATUS
+GetSlotId(
+ PEI_XHCI_SLOTADDR_MAP *DeviceMap,
+ UINT8 *SlotId,
+ UINT8 DevAddr);
+
+EFI_STATUS Stall(EFI_PEI_SERVICES**, EFI_PEI_STALL_PPI*, UINTN);
+EFI_STATUS CountTime(UINT, UINT16);
+EFI_STATUS XhciInitDeviceData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_USB_HOST_CONTROLLER_PPI *This
+// HC_STRUC *HcStruc,
+// DEV_INFO *DevInfo,
+// UINT8 PortStatus,
+// UINT8 **DeviceData
+);
+
+TRB_RING* XhciGetXfrRing(
+ USB3_CONTROLLER* Usb3Hc,
+ UINT8 Slot,
+ UINT8 Ep);
+
+UINT32* XhciGetTheDoorbell(
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 SlotId);
+
+XHCI_TRB* XhciAdvanceEnqueuePtr(
+ TRB_RING *Ring);
+
+EFI_STATUS XhciWaitForEvent(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc,
+ XHCI_TRB *TrbToCheck,
+ TRB_TYPE EventType,
+ UINT8 *CompletionCode,
+ UINT16 TimeOutMs,
+ VOID *Data
+);
+
+UINT8*
+XhciGetDeviceContext(
+ USB3_CONTROLLER *Usb3Hc,
+ UINT8 SlotId
+);
+
+UINT8*
+XhciGetContextEntry(
+ USB3_CONTROLLER *Usb3Hc,
+ VOID *Context,
+ UINT8 Index
+);
+
+ //(EIP75547+)>
+VOID
+XhciResetUsb2Port(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc
+);
+
+EFI_STATUS
+XhciExtCapParser(
+ EFI_PEI_SERVICES **PeiServices,
+ USB3_CONTROLLER *Usb3Hc
+);
+ //<(EIP75547+)
+
+#define _CR( Record, TYPE, Field ) \
+ ( (TYPE *) ( (CHAR8 *) (Record) - (CHAR8 *) &( ( (TYPE *) 0 )->Field ) ) )
+#define PEI_RECOVERY_USB_XHCI_DEV_FROM_THIS( a ) \
+ _CR( a, USB3_CONTROLLER, UsbHostControllerPpi )
+
+#endif // _XHCIPEI_H
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/UsbRecovery/usb.h b/Core/EM/UsbRecovery/usb.h
new file mode 100644
index 0000000..3d120cf
--- /dev/null
+++ b/Core/EM/UsbRecovery/usb.h
@@ -0,0 +1,511 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//**********************************************************************
+//
+// $Header: /Alaska/SOURCE/Modules/USBRecovery/usb.h 10 8/23/12 10:02p Wilsonlee $
+//
+// $Revision: 10 $
+//
+// $Date: 8/23/12 10:02p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USBRecovery/usb.h $
+//
+// 10 8/23/12 10:02p Wilsonlee
+// [TAG] EIP97069
+// [Category] Improvement
+// [Description] Reset root port algorythm update.
+// [Files] EhciPei.c, EhciPei.h, OhciPei.c, OhciPei.h, UhcPeim.c,
+// UhcPeim.h, UsbPeim.c, usb.h
+//
+// 9 1/18/11 1:03a Ryanchou
+// [TAG] EIP47931
+// [Category] Improvement
+// [Description] Added USB 3.0 hub support.
+// [Files] EhciPei.c, EhciPei.h, HubPeim.c, HubPeim.h, OhciPei.c,
+// OhciPei.h, UhcPeim.c, UhcPeim.h, usb.h, UsbHostController.h,
+// UsbIoPeim.c, UsbPeim.c, UsbPeim.h, XhciPei.c, XhciPei.h
+//
+// 8 10/11/10 4:51p Olegi
+// XHCI support added.
+//
+// 7 4/06/10 3:35p Fasihm
+// EIP#31987 - Added the generic USBRecovery Fix in the module.
+//
+// 6 11/16/09 1:49p Fasihm
+// Corrected the order of the enum constants in EFI_USB_DATA_DIRECTION.
+//
+// 5 3/17/09 5:10p Olegi
+//
+// 4 7/18/08 5:03p Michaela
+// 1 File-level debugging is now available
+// 2 AMI_USB_DEBUG_INTERFACE.WaitConsoleKey() now returns
+// the keypress so that conditional debugging can
+// be dynamic (alphanumeric keys only)
+// 3 Added more function headers.
+// 4 Removed code that will never be used (I.e., Bala?).
+// 5 Moved typedef, contants and extern declarations
+// into header files.
+// 6 Now all controller blocks are enabled for SB700
+// (EHCI controllers route to companion controller
+// by default)
+// 7 Removed unused constants and typedefs n OhciPei.h
+// (also reorganized the file to make it more
+// readable.)
+// 8 Renamed many functions/variables according to
+// coding standard.
+// 9 Removed code initializing data structures for
+// periodic lists, as this is not needed.
+// 10 Removed the CONTROLLER_TYPE SDL token to
+// allow UHCI and OHCI controllers to supported
+// simultaneously. (modified MAKE files
+// accordingly)
+//
+// 3 7/10/08 6:33p Michaela
+// Updated to support OHCI controllers
+//
+// 2 10/23/07 4:39p Ambikas
+//
+// 1 9/22/06 4:07p Sivagarn
+// - Initial Check-in
+// - Included Recovery code in Source
+// - Included appropriate headers for flies and functions
+// - Updated copyright messages
+//
+//*****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: USB.H
+//
+// Description: This file belongs to "Framework" and included here for
+// compatibility purposes. This file is modified by AMI to include
+// copyright message and appropriate header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+//
+// This file contains 'Framework Code' and is licensed as such
+// under the terms of your license agreement with Intel or your
+// vendor. This file may not be modified, except as allowed by
+// additional terms of your license agreement.
+//
+#ifndef _USB_H
+#define _USB_H
+
+/*++
+
+ Copyright (c) 1999 - 2002 Intel Corporation. All rights reserved
+ This software and associated documentation (if any) is furnished
+ under a license and may only be used or copied in accordance
+ with the terms of the license. Except as permitted by such
+ license, no part of this software or documentation may be
+ reproduced, stored in a retrieval system, or transmitted in any
+ form or by any means without the express written consent of
+ Intel Corporation.
+
+
+ Module Name:
+
+ usb.h
+
+ Abstract:
+ Support for USB 1.1 standard.
+
+
+
+
+ Revision History
+
+ --*/
+
+// BIT(a) defines a value with one bit set as specified by a.
+#ifndef BIT
+#define BIT( a ) (1 << (a))
+#endif
+
+
+// MASK(high,low) defines a bit mask value with bits set in the bit
+// range specified from high down to low (zero-based)
+#ifndef MASK
+#define MAX_VAL 0xffffffff // maximum value supported by CPU
+#define MAX_BIT 31 // highest bit position in MAX_VAL
+#define MASK( high, low ) (\
+ ( MAX_VAL >> ( MAX_BIT - ( (high) - (low) ) ) ) \
+ << (low) \
+)
+#endif
+
+
+// READ_BITS(src,high,low) extracts a bit field shifted down to bit
+// position 0 from src, where high and low define the bit range
+// (zero-based).
+#ifndef READ_BITS
+#define READ_BITS( src, high, low ) (\
+ ( (src) & MASK( (high), (low) ) ) \
+ >> (low) \
+)
+#endif
+
+// return the modified src after writing a bit field with val, where the bit
+// field's range is specified by high down to low
+// (Note, the user must ensure that the val fits in the bit range)
+#ifndef WRITE_BITS
+#define WRITE_BITS( src, val, high, low ) (\
+ ( (src) & ~MASK( (high), (low) ) ) \
+ | ( (val) << (low) ) \
+)
+#endif
+
+//
+// USB Descriptor types
+//
+#define USB_DT_DEVICE 0x01
+#define USB_DT_CONFIG 0x02
+#define USB_DT_STRING 0x03
+#define USB_DT_INTERFACE 0x04
+#define USB_DT_ENDPOINT 0x05
+#define USB_DT_HUB 0x29
+#define USB_DT_SS_HUB 0x2A
+#define USB_DT_HID 0x21
+
+#define SET_DESCRIPTOR_TYPE( x ) WRITE_BITS( 0x0, x, 15, 8 )
+
+//
+// USB request type
+//
+#define USB_TYPE_STANDARD (0x00 << 5)
+#define USB_TYPE_CLASS (0x01 << 5)
+#define USB_TYPE_VENDOR (0x02 << 5)
+#define USB_TYPE_RESERVED (0x03 << 5)
+
+//
+// USB request targer device
+//
+#define USB_RECIP_DEVICE 0x00
+#define USB_RECIP_INTERFACE 0x01
+#define USB_RECIP_ENDPOINT 0x02
+#define USB_RECIP_OTHER 0x03
+
+//
+// Request target types.
+//
+#define USB_RT_DEVICE 0x00
+#define USB_RT_INTERFACE 0x01
+#define USB_RT_ENDPOINT 0x02
+#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE)
+#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER)
+
+
+//
+// USB Transfer Results
+//
+#define EFI_USB_NOERROR 0x00
+#define EFI_USB_ERR_NOTEXECUTE 0x01
+#define EFI_USB_ERR_STALL 0x02
+#define EFI_USB_ERR_BUFFER 0x04
+#define EFI_USB_ERR_BABBLE 0x08
+#define EFI_USB_ERR_NAK 0x10
+#define EFI_USB_ERR_CRC 0x20
+#define EFI_USB_ERR_TIMEOUT 0x40
+#define EFI_USB_ERR_BITSTUFF 0x80
+#define EFI_USB_ERR_SYSTEM 0x100
+
+static CHAR8 *gUsbErrorStrings[] =
+{
+ "EFI_USB_ERR_NOTEXECUTE",
+ "EFI_USB_ERR_STALL",
+ "EFI_USB_ERR_BUFFER",
+ "EFI_USB_ERR_BABBLE",
+ "EFI_USB_ERR_NAK",
+ "EFI_USB_ERR_CRC",
+ "EFI_USB_ERR_TIMEOUT",
+ "EFI_USB_ERR_BITSTUFF",
+ "EFI_USB_ERR_SYSTEM"
+};
+
+#define EFI_USB_INTERRUPT_DELAY 0x10000000
+
+#define EFI_USB_STALL_ERROR \
+ (EFI_USB_ERR_STALL | EFI_USB_ERR_CRC | \
+ EFI_USB_ERR_TIMEOUT | EFI_USB_ERR_BABBLE)
+
+//
+// USB transation direction
+//
+typedef enum {
+ EfiUsbDataIn,
+ EfiUsbDataOut,
+ EfiUsbNoData
+} EFI_USB_DATA_DIRECTION;
+
+//
+// This is how UsbData in/out described in USB spec.
+//
+typedef enum {
+ UsbDataOut,
+ UsbDataIn,
+ UsbNoData
+} USB_DATA_DIRECTION;
+
+//
+// Usb Data recipient type
+//
+typedef enum {
+ EfiUsbDevice,
+ EfiUsbInterface,
+ EfiUsbEndpoint
+} EFI_USB_RECIPIENT;
+
+typedef enum {
+ EfiUsbEndpointHalt,
+ EfiUsbDeviceRemoteWakeup
+} EFI_USB_STANDARD_FEATURE_SELECTOR;
+
+#pragma pack(push,1)
+
+//
+// Usb device request structure
+//
+typedef struct
+{
+ UINT8 RequestType;
+ UINT8 Request;
+ UINT16 Value;
+ UINT16 Index;
+ UINT16 Length;
+} EFI_USB_DEVICE_REQUEST;
+
+
+//
+// Standard USB request
+//
+#define USB_DEV_GET_STATUS 0x00
+
+#define USB_DEV_CLEAR_FEATURE 0x01
+
+#define USB_DEV_SET_FEATURE 0x03
+
+#define USB_DEV_SET_ADDRESS 0x05
+#define USB_DEV_SET_ADDRESS_REQ_TYPE 0x00
+
+#define USB_DEV_GET_DESCRIPTOR 0x06
+#define USB_DEV_GET_DESCRIPTOR_REQ_TYPE 0x80
+
+#define USB_DEV_SET_DESCRIPTOR 0x07
+#define USB_DEV_SET_DESCRIPTOR_REQ_TYPE 0x00
+
+#define USB_DEV_GET_CONFIGURATION 0x08
+#define USB_DEV_GET_CONFIGURATION_REQ_TYPE 0x80
+
+#define USB_DEV_SET_CONFIGURATION 0x09
+#define USB_DEV_SET_CONFIGURATION_REQ_TYPE 0x00
+
+#define USB_DEV_GET_INTERFACE 0x0a
+#define USB_DEV_GET_INTERFACE_REQ_TYPE 0x81
+
+#define USB_DEV_SET_INTERFACE 0x0b
+#define USB_DEV_SET_INTERFACE_REQ_TYPE 0x01
+
+#define USB_DEV_SYNCH_FRAME 0x0c
+#define USB_DEV_SYNCH_FRAME_REQ_TYPE 0x82
+
+
+//
+// Device descriptor. refer USB1.1
+//
+typedef struct usb_device_descriptor
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ UINT16 BcdUSB;
+ UINT8 DeviceClass;
+ UINT8 DeviceSubClass;
+ UINT8 DeviceProtocol;
+ UINT8 MaxPacketSize0;
+ UINT16 IdVendor;
+ UINT16 IdProduct;
+ UINT16 BcdDevice;
+ UINT8 StrManufacturer;
+ UINT8 StrProduct;
+ UINT8 StrSerialNumber;
+ UINT8 NumConfigurations;
+} EFI_USB_DEVICE_DESCRIPTOR;
+
+//
+// Endpoint descriptor
+//
+typedef struct
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ UINT8 EndpointAddress;
+ UINT8 Attributes;
+ UINT16 MaxPacketSize;
+ UINT8 Interval;
+} EFI_USB_ENDPOINT_DESCRIPTOR;
+
+//
+// Interface descriptor
+//
+typedef struct
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ UINT8 InterfaceNumber;
+ UINT8 AlternateSetting;
+ UINT8 NumEndpoints;
+ UINT8 InterfaceClass;
+ UINT8 InterfaceSubClass;
+ UINT8 InterfaceProtocol;
+ UINT8 Interface;
+} EFI_USB_INTERFACE_DESCRIPTOR;
+
+//
+// USB alternate setting
+//
+typedef struct
+{
+ EFI_USB_INTERFACE_DESCRIPTOR *Interface;
+} USB_ALT_SETTING;
+
+//
+// Configuration descriptor
+//
+typedef struct
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ UINT16 TotalLength;
+ UINT8 NumInterfaces;
+ UINT8 ConfigurationValue;
+ UINT8 Configuration;
+ UINT8 Attributes;
+ UINT8 MaxPower;
+} EFI_USB_CONFIG_DESCRIPTOR;
+
+//
+// Supported String Languages
+//
+typedef struct
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ UINT16 SupportedLanID[1];
+} EFI_USB_SUPPORTED_LANGUAGES;
+
+//
+// String descriptor
+//
+typedef struct
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ CHAR16 String[1];
+} EFI_USB_STRING_DESCRIPTOR;
+
+//
+// Hub descriptor
+//
+//#define MAXBYTES 8
+typedef struct
+{
+ UINT8 Length;
+ UINT8 DescriptorType;
+ UINT8 NbrPorts;
+ UINT8 HubCharacteristics[2];
+ UINT8 PwrOn2PwrGood;
+ UINT8 HubContrCurrent;
+ UINT8 HubHdrDecLat;
+ UINT16 HubDelay;
+ UINT16 DeviceRemovable;
+} EFI_USB_HUB_DESCRIPTOR;
+
+typedef struct
+{
+ UINT16 PortStatus;
+ UINT16 PortChangeStatus;
+} EFI_USB_PORT_STATUS;
+
+//
+// Constant value for Port Status & Port Change Status
+//
+#define USB_PORT_STAT_CONNECTION BIT(0)
+#define USB_PORT_STAT_ENABLE BIT(1)
+#define USB_PORT_STAT_SUSPEND BIT(2)
+#define USB_PORT_STAT_OVERCURRENT BIT(3)
+#define USB_PORT_STAT_RESET BIT(4)
+#define USB_PORT_STAT_POWER BIT(8)
+#define USB_PORT_STAT_LOW_SPEED BIT(9)
+#define USB_PORT_STAT_HIGH_SPEED BIT(10)
+#define USB_PORT_STAT_SUPER_SPEED BIT(11)
+#define USB_PORT_STAT_OWNER BIT(13)
+
+#define USB_PORT_STAT_C_CONNECTION BIT(0)
+#define USB_PORT_STAT_C_ENABLE BIT(1)
+#define USB_PORT_STAT_C_SUSPEND BIT(2)
+#define USB_PORT_STAT_C_OVERCURRENT BIT(3)
+#define USB_PORT_STAT_C_RESET BIT(4)
+
+//
+// Used for set/clear port feature request
+//
+typedef enum {
+ EfiUsbPortConnection = 0,
+ EfiUsbPortEnable = 1,
+ EfiUsbPortSuspend = 2,
+ EfiUsbPortOverCurrent = 3,
+ EfiUsbPortReset = 4,
+ EfiUsbPortLinkState = 5,
+ EfiUsbPortPower = 8,
+ EfiUsbPortOwner = 13,
+ EfiUsbPortConnectChange = 16,
+ EfiUsbPortEnableChange = 17,
+ EfiUsbPortSuspendChange = 18,
+ EfiUsbPortOverCurrentChange = 19,
+ EfiUsbPortResetChange = 20,
+ EfiUsbPortTest = 21,
+ EfiUsbPortIndicator = 22,
+ EfiUsbPortU1Timeout = 23,
+ EfiUsbPortU2Timeout = 24,
+ EfiUsbPortLinkStateChange = 25,
+ EfiUsbPortConfigErrorChange = 26,
+ EfiUsbPortRemoteWakeMask = 27,
+ EfiUsbPortBhPortReset = 28,
+ EfiUsbPortBhPortResetChange = 29,
+ EfiUsbPortForceLinkPmAccept = 30
+} EFI_USB_PORT_FEATURE;
+
+#pragma pack(pop)
+
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2010, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/usb/AmiUsbLib/AmiUsbLib.cif b/Core/EM/usb/AmiUsbLib/AmiUsbLib.cif
new file mode 100644
index 0000000..f0a87e5
--- /dev/null
+++ b/Core/EM/usb/AmiUsbLib/AmiUsbLib.cif
@@ -0,0 +1,11 @@
+<component>
+ name = "AmiUsbLib"
+ category = ModulePart
+ LocalRoot = "core\em\usb\AmiUsbLib"
+ RefName = "AmiUsbLib"
+[files]
+"AmiUsbLib.sdl"
+[parts]
+"AmiUsbLibInclude"
+"AmiUsbSmmGlobalDataValidationLib"
+<endComponent> \ No newline at end of file
diff --git a/Core/EM/usb/AmiUsbLib/AmiUsbLib.sdl b/Core/EM/usb/AmiUsbLib/AmiUsbLib.sdl
new file mode 100644
index 0000000..c4767cb
--- /dev/null
+++ b/Core/EM/usb/AmiUsbLib/AmiUsbLib.sdl
@@ -0,0 +1,20 @@
+TOKEN
+ Name = "AmiUsbLib_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable AmiUsbLib support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "AMIUSBLIB_DIR"
+End
+
+MODULE
+ Help = "Includes AmiUsbSmmGlobalDataValidationLib.mak into project"
+ Path = "$(AMIUSBLIB_DIR)"
+ File = "AmiUsbSmmGlobalDataValidationLib.mak"
+End
diff --git a/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.c b/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.c
new file mode 100644
index 0000000..e5ec2d2
--- /dev/null
+++ b/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.c
@@ -0,0 +1,487 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmiUsbSmmGlobalDataValidationLib.c
+//
+// Description: Source code for the AmiUsbSmmGlobalDataValidationLib library class.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Token.h>
+#include <AmiDxeLib.h>
+#include <AmiBufferValidationLib.h>
+#include <AmiUsbSmmGlobalDataValidationLib.h>
+#include <Protocol/SmmAccess2.h>
+#include <Protocol/SmmBase2.h>
+#include "../rt/UsbDef.h"
+#include "../rt/Xhci.h"
+
+extern UINT32 mCrcTable[256];
+extern EFI_STATUS EFIAPI RuntimeDriverCalculateCrc32(VOID *, UINTN, UINT32*);
+extern VOID RuntimeDriverInitializeCrc32Table(VOID);
+
+AMI_USB_SMM_PROTOCOL *gAmiUsbSmmProtocol = NULL;
+EFI_SMM_SYSTEM_TABLE2 *gSmst2 = NULL;
+
+typedef struct {
+ UINT32 UsbLegSupOffSet;
+ XHCI_DCBAA *DcbaaPtr;
+ TRB_RING *XfrRings;
+ UINTN XfrTrbs;
+ VOID *DeviceContext;
+ VOID *InputContext;
+ UINT64 *ScratchBufEntry;
+ UINT8 ContextSize;
+ UINT32 HashValue;
+} USB3_HC_CONSTANT_DATA;
+
+typedef struct {
+ UINT8 HcType;
+ UINT8 OpRegOffset;
+ UINT8 ExtCapPtr;
+ UINT16 BusDevFuncNum;
+ UINT16 AsyncListSize;
+ UINT32 *FrameList;
+ UINTN BaseAddressSize;
+ VOID *UsbBusData;
+ VOID *IsocTds;
+ UINT32 HashValue;
+} USB_HC_CONSTANT_DATA;
+
+typedef struct {
+ HCD_HEADER HcdriverTable[MAX_HC_TYPES];
+ DEV_DRIVER DevDriverTable[MAX_DEVICE_TYPES];
+ DEV_DRIVER DelayedDrivers[MAX_DEVICE_TYPES];
+ CALLBACK_FUNC CallBackFunctionTable[MAX_CALLBACK_FUNCTION];
+ VOID *EfiKeyboardBuffer;
+ UINT8 *MemBlockStart;
+ UINT32 MemPages;
+ UINT8 *UsbTempBuffer;
+ UINT8 *UsbMassConsumeBuffer;
+ UINT32 *MemBlkSts;
+ UINTN PciExpressBaseAddress;
+ VOID *QueueCnnctDiscData;
+ int QueueCnnctDiscMaxSize;
+ VOID *IccQueueCnnctDiscData;
+ int IccQueueCnnctDiscMaxSize;
+ UINT32 HashValue;
+} USB_CONSTANT_DATA;
+
+EFI_STATUS
+CalculateUsbGlobalConstantDataCrc32(
+ USB_GLOBAL_DATA *UsbData,
+ UINT32 *Crc32
+)
+{
+ USB_CONSTANT_DATA UsbConStantData = {0};
+ UINTN Index = 0;
+ HC_STRUC *HcStruc;
+ USB3_HOST_CONTROLLER *Usb3Hc = NULL;
+ UINTN HcInitializedNumber = 0;
+ UINTN Usb3HcInitializedNumber = 0;
+ UINTN HcStrucDataIndex = 0;
+ UINTN Usb3HcStrucDataIndex = 0;
+ USB_HC_CONSTANT_DATA *HcStrucData = NULL;
+ USB3_HC_CONSTANT_DATA *Usb3HcStrucData = NULL;
+ EFI_STATUS Status;
+ UINT32 Crc32Value[3] = {0};
+
+ if (gAmiUsbSmmProtocol == NULL) {
+ return EFI_NOT_READY;
+ }
+
+ MemCpy(UsbConStantData.HcdriverTable, UsbData->aHCDriverTable, sizeof(UsbConStantData.HcdriverTable));
+ MemCpy(UsbConStantData.DevDriverTable, UsbData->aDevDriverTable, sizeof(UsbConStantData.DevDriverTable));
+ MemCpy(UsbConStantData.DelayedDrivers, UsbData->aDelayedDrivers, sizeof(UsbConStantData.DelayedDrivers));
+ MemCpy(UsbConStantData.CallBackFunctionTable, UsbData->aCallBackFunctionTable, sizeof(UsbConStantData.CallBackFunctionTable));
+
+ UsbConStantData.EfiKeyboardBuffer = UsbData->EfiKeyboardBuffer;
+ UsbConStantData.UsbTempBuffer = UsbData->fpUSBTempBuffer;
+ UsbConStantData.UsbMassConsumeBuffer = UsbData->fpUSBMassConsumeBuffer;
+ UsbConStantData.MemBlkSts = UsbData->aMemBlkSts;
+ UsbConStantData.MemBlockStart = UsbData->fpMemBlockStart;
+ UsbConStantData.MemPages = UsbData->MemPages;
+ UsbConStantData.QueueCnnctDiscData = UsbData->QueueCnnctDisc.data;
+ UsbConStantData.QueueCnnctDiscMaxSize = UsbData->QueueCnnctDisc.maxsize;
+ UsbConStantData.IccQueueCnnctDiscData = UsbData->ICCQueueCnnctDisc.data;
+ UsbConStantData.IccQueueCnnctDiscMaxSize = UsbData->ICCQueueCnnctDisc.maxsize;
+ UsbConStantData.HashValue = gAmiUsbSmmProtocol->GlobalDataValidation.Crc32Hash;
+
+ for (Index = 0; Index < UsbData->HcTableCount; Index++) {
+ HcStruc = UsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if (HcStruc->dHCFlag & (HC_STATE_RUNNING |HC_STATE_INITIALIZED)) {
+ HcInitializedNumber++;
+ if (HcStruc->usbbus_data) {
+ Usb3HcInitializedNumber++;
+ }
+ }
+ }
+
+ if (HcInitializedNumber != 0) {
+ Status = gSmst2->SmmAllocatePool(EfiRuntimeServicesData,
+ sizeof(USB_HC_CONSTANT_DATA) * HcInitializedNumber,
+ (VOID**)&HcStrucData);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ MemSet(HcStrucData, sizeof(USB_HC_CONSTANT_DATA) * HcInitializedNumber, 0);
+ }
+
+ if (Usb3HcInitializedNumber != 0) {
+
+ Status = gSmst2->SmmAllocatePool(EfiRuntimeServicesData,
+ sizeof(USB3_HC_CONSTANT_DATA) * Usb3HcInitializedNumber,
+ (VOID**)&Usb3HcStrucData);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ MemSet(Usb3HcStrucData, sizeof(USB3_HC_CONSTANT_DATA) * Usb3HcInitializedNumber, 0);
+ }
+
+ for (Index = 0; Index < UsbData->HcTableCount; Index++) {
+ HcStruc = UsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ Status = AmiValidateMemoryBuffer((VOID*)HcStruc, sizeof(HC_STRUC));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (HcStruc->dHCFlag & (HC_STATE_RUNNING |HC_STATE_INITIALIZED)) {
+ HcStrucData[HcStrucDataIndex].HcType = HcStruc->bHCType;
+ HcStrucData[HcStrucDataIndex].AsyncListSize = HcStruc->wAsyncListSize;
+ HcStrucData[HcStrucDataIndex].FrameList = HcStruc->fpFrameList;
+ HcStrucData[HcStrucDataIndex].BaseAddressSize = HcStruc->BaseAddressSize;
+ HcStrucData[HcStrucDataIndex].BusDevFuncNum = HcStruc->wBusDevFuncNum;
+ HcStrucData[HcStrucDataIndex].OpRegOffset = HcStruc->bOpRegOffset;
+ HcStrucData[HcStrucDataIndex].ExtCapPtr = HcStruc->bExtCapPtr;
+ HcStrucData[HcStrucDataIndex].UsbBusData = HcStruc->usbbus_data;
+ HcStrucData[HcStrucDataIndex].HashValue = gAmiUsbSmmProtocol->GlobalDataValidation.Crc32Hash;
+ HcStrucDataIndex++;
+ if (HcStruc->usbbus_data) {
+ Usb3Hc = HcStruc->usbbus_data;
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc, sizeof(USB3_HOST_CONTROLLER));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (Usb3Hc->CapRegs) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->CapRegs, sizeof(XHCI_HC_CAP_REGS));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ if (Usb3Hc->OpRegs) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->OpRegs, sizeof(XHCI_HC_OP_REGS));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ if (Usb3Hc->RtRegs) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->RtRegs,
+ (sizeof(UINT32) * 8) + (sizeof(XHCI_INTERRUPTER_REGS) * Usb3Hc->CapRegs->HcsParams1.MaxIntrs));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ if (Usb3Hc->ExtLegCap) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->ExtLegCap, sizeof(XHCI_EXT_LEG_CAP));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ if (Usb3Hc->Usb2Protocol) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->Usb2Protocol, sizeof(XHCI_EXT_PROTOCOL));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ if (Usb3Hc->Usb3Protocol) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->Usb3Protocol, sizeof(XHCI_EXT_PROTOCOL));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ if (Usb3Hc->DbCapRegs) {
+ Status = AmiValidateMemoryBuffer((VOID*)Usb3Hc->DbCapRegs, sizeof(XHCI_DB_CAP_REGS));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ Usb3HcStrucData[Usb3HcStrucDataIndex].DcbaaPtr = Usb3Hc->DcbaaPtr;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].XfrRings = Usb3Hc->XfrRings;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].XfrTrbs = Usb3Hc->XfrTrbs;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].DeviceContext = Usb3Hc->DeviceContext;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].InputContext = Usb3Hc->InputContext;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].ScratchBufEntry = Usb3Hc->ScratchBufEntry;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].ContextSize = Usb3Hc->ContextSize;
+ Usb3HcStrucData[Usb3HcStrucDataIndex].HashValue = gAmiUsbSmmProtocol->GlobalDataValidation.Crc32Hash;
+ Usb3HcStrucDataIndex++;
+ }
+ }
+ }
+
+ if (HcInitializedNumber != 0) {
+ Status = RuntimeDriverCalculateCrc32((UINT8*)HcStrucData,
+ (UINTN)(sizeof(USB_HC_CONSTANT_DATA) * HcInitializedNumber), &Crc32Value[0]);
+ Status = gSmst2->SmmFreePool(HcStrucData);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ if (Usb3HcInitializedNumber != 0) {
+ Status = RuntimeDriverCalculateCrc32((UINT8*)Usb3HcStrucData,
+ (UINTN)(sizeof(USB3_HC_CONSTANT_DATA) * Usb3HcInitializedNumber), &Crc32Value[1]);
+ Status = gSmst2->SmmFreePool(Usb3HcStrucData);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ Status = RuntimeDriverCalculateCrc32((UINT8*)&UsbConStantData, sizeof(UsbConStantData), &Crc32Value[2]);
+
+ RuntimeDriverCalculateCrc32((UINT8*)Crc32Value, sizeof(Crc32Value), Crc32);
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UpdateAmiUsbSmmGlobalDataCrc32(
+ VOID *UsbGlobdaData
+)
+{
+ EFI_STATUS Status;
+ UINT32 Crc32;
+
+
+ Status = CalculateUsbGlobalConstantDataCrc32(UsbGlobdaData, &Crc32);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ gAmiUsbSmmProtocol->GlobalDataValidation.ConstantDataCrc32 = Crc32;
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+CheckAmiUsbSmmGlobalDataCrc32(
+ VOID *UsbGlobdaData
+)
+{
+ EFI_STATUS Status;
+ UINT32 Crc32;
+
+ Status = CalculateUsbGlobalConstantDataCrc32(UsbGlobdaData, &Crc32);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ if (gAmiUsbSmmProtocol->GlobalDataValidation.ConstantDataCrc32 != Crc32) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS
+EFIAPI
+AmiUsbSmmGlobalDataValidation(
+ VOID *UsbGlobalData
+)
+{
+ USB_GLOBAL_DATA *UsbData;
+ EFI_STATUS Status;
+ UINT8 *MouseInputBufferEnd;
+ UINT8 *KbcharacterBufferEnd;
+ UINT8 *KbcScanCodeBufferEnd;
+ UINT8 *KbcUsbDataBufferEnd;
+ UINTN Index;
+ DEV_INFO *DevInfoTableEnd;
+ HC_STRUC *HcStruc;
+
+ UsbData = (USB_GLOBAL_DATA*)UsbGlobalData;
+
+ MouseInputBufferEnd = UsbData->aMouseInputBuffer + sizeof(UsbData->aMouseInputBuffer);
+
+ if ((UsbData->fpMouseInputBufferHeadPtr < UsbData->aMouseInputBuffer) ||
+ (UsbData->fpMouseInputBufferHeadPtr > MouseInputBufferEnd) ||
+ (UsbData->fpMouseInputBufferTailPtr < UsbData->aMouseInputBuffer) ||
+ (UsbData->fpMouseInputBufferTailPtr > MouseInputBufferEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ KbcUsbDataBufferEnd = UsbData->aKBCUsbDataBufferStart + sizeof(UsbData->aKBCUsbDataBufferStart);
+
+ if ((UsbData->aKBCUsbDataBufferHead < UsbData->aKBCUsbDataBufferStart) ||
+ (UsbData->aKBCUsbDataBufferHead > KbcUsbDataBufferEnd) ||
+ (UsbData->aKBCUsbDataBufferTail < UsbData->aKBCUsbDataBufferStart) ||
+ (UsbData->aKBCUsbDataBufferTail > KbcUsbDataBufferEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ KbcharacterBufferEnd = UsbData->aKBCCharacterBufferStart + sizeof(UsbData->aKBCCharacterBufferStart);
+
+ if ((UsbData->fpKBCCharacterBufferHead < UsbData->aKBCCharacterBufferStart) ||
+ (UsbData->fpKBCCharacterBufferHead > KbcharacterBufferEnd) ||
+ (UsbData->fpKBCCharacterBufferTail < UsbData->aKBCCharacterBufferStart) ||
+ (UsbData->fpKBCCharacterBufferTail > KbcharacterBufferEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ KbcScanCodeBufferEnd = UsbData->aKBCScanCodeBufferStart + sizeof(UsbData->aKBCScanCodeBufferStart);
+
+ if ((UsbData->fpKBCScanCodeBufferPtr < UsbData->aKBCScanCodeBufferStart) ||
+ (UsbData->fpKBCScanCodeBufferPtr > KbcScanCodeBufferEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ DevInfoTableEnd = UsbData->aDevInfoTable + sizeof(UsbData->aDevInfoTable);
+
+ if (UsbData->fpKeyRepeatDevInfo != NULL) {
+ if ((UsbData->fpKeyRepeatDevInfo < UsbData->aDevInfoTable) ||
+ (UsbData->fpKeyRepeatDevInfo > DevInfoTableEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+
+ for (Index = 0; Index < USB_DEV_HID_COUNT; Index++) {
+ if (UsbData->aUSBKBDeviceTable[Index] != NULL) {
+ if ((UsbData->aUSBKBDeviceTable[Index] < UsbData->aDevInfoTable) ||
+ (UsbData->aUSBKBDeviceTable[Index] > DevInfoTableEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ }
+
+ if (UsbData->HcTableCount != 0) {
+ Status = AmiValidateMemoryBuffer((VOID*)UsbData->HcTable, sizeof(HC_STRUC) * UsbData->HcTableCount);
+ if (EFI_ERROR(Status)) {
+ return EFI_ACCESS_DENIED;
+ }
+ for (Index = 0; Index < UsbData->HcTableCount; Index++) {
+ HcStruc = UsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ //Check if MMIO address space of usb controller resides in SMRAM region. If yes, don't proceed.
+ if (HcStruc->bHCType != USB_HC_UHCI) {
+ if (HcStruc->BaseAddress != 0) {
+ Status = AmiValidateMmioBuffer((VOID*)HcStruc->BaseAddress, HcStruc->BaseAddressSize);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "Usb Mmio address is invalid, it is in SMRAM\n"));
+ return EFI_ACCESS_DENIED;
+ }
+ }
+ }
+ }
+ }
+
+ Status = CheckAmiUsbSmmGlobalDataCrc32(UsbData);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+UsbSmmProtocolCallback(
+ CONST EFI_GUID *Protocol,
+ VOID *Interface,
+ EFI_HANDLE Handle
+)
+{
+ EFI_STATUS Status;
+
+ Status = gSmst2->SmmLocateProtocol(
+ &gAmiUsbSmmProtocolGuid,
+ NULL,
+ &gAmiUsbSmmProtocol);
+
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+InitAmiUsbSmmGlobalDataValidationLib(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable)
+{
+ EFI_STATUS Status;
+ VOID *ProtocolNotifyRegistration;
+ EFI_SMM_BASE2_PROTOCOL *SmmBase2;
+
+ InitAmiSmmLib(ImageHandle,SystemTable);
+
+ Status = pBS->LocateProtocol(&gEfiSmmBase2ProtocolGuid, NULL, &SmmBase2);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = SmmBase2->GetSmstLocation(SmmBase2, &gSmst2);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ RuntimeDriverInitializeCrc32Table();
+
+ Status = gSmst2->SmmLocateProtocol(
+ &gAmiUsbSmmProtocolGuid,
+ NULL,
+ &gAmiUsbSmmProtocol);
+
+ if (EFI_ERROR(Status)) {
+ Status = gSmst2->SmmRegisterProtocolNotify(
+ &gAmiUsbSmmProtocolGuid,
+ UsbSmmProtocolCallback,
+ &ProtocolNotifyRegistration
+ );
+ }
+
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.cif b/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.cif
new file mode 100644
index 0000000..e3612f6
--- /dev/null
+++ b/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "AmiUsbSmmGlobalDataValidationLib"
+ category = ModulePart
+ LocalRoot = "core\em\usb\AmiUsbLib"
+ RefName = "AmiUsbSmmGlobalDataValidationLib"
+[files]
+"AmiUsbSmmGlobalDataValidationLib.c"
+"AmiUsbSmmGlobalDataValidationLib.mak"
+"Crc32.c"
+<endComponent> \ No newline at end of file
diff --git a/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.mak b/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.mak
new file mode 100644
index 0000000..f560957
--- /dev/null
+++ b/Core/EM/usb/AmiUsbLib/AmiUsbSmmGlobalDataValidationLib.mak
@@ -0,0 +1,51 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2016, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: AmiUsbSmmGlobalDataValidationLib.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : AmiUsbSmmGlobalDataValidationLib
+
+AmiUsbSmmGlobalDataValidationLib : $(BUILD_DIR)\AmiUsbSmmGlobalDataValidationLib.mak AmiUsbSmmGlobalDataValidationLibBin
+
+$(BUILD_DIR)\AmiUsbSmmGlobalDataValidationLib.mak : $(AMIUSBLIB_DIR)\$(@B).cif $(AMIUSBLIB_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(AMIUSBLIB_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+AmiUsbSmmGlobalDataValidationLibBin : $(AMIDXELIB) $(BUILD_DIR)\AmiBufferValidationLib.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\AmiUsbSmmGlobalDataValidationLib.mak all\
+ TYPE=LIBRARY
+
+$(BUILD_DIR)\AmiUsbSmmGlobalDataValidationLib.lib : AmiUsbSmmGlobalDataValidationLib
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2016, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/usb/AmiUsbLib/Crc32.c b/Core/EM/usb/AmiUsbLib/Crc32.c
new file mode 100644
index 0000000..895eee7
--- /dev/null
+++ b/Core/EM/usb/AmiUsbLib/Crc32.c
@@ -0,0 +1,117 @@
+/** @file
+ This file implements CalculateCrc32 Boot Services as defined in
+ Platform Initialization specification 1.0 VOLUME 2 DXE Core Interface.
+
+ This Boot Services is in the Runtime Driver because this service is
+ also required by SetVirtualAddressMap() when the EFI System Table and
+ EFI Runtime Services Table are converted from physical address to
+ virtual addresses. This requires that the 32-bit CRC be recomputed.
+
+Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+//#include <Uefi.h>
+#include <Token.h>
+#include <AmiDxeLib.h>
+
+UINT32 mCrcTable[256];
+
+/**
+ Calculate CRC32 for target data.
+
+ @param Data The target data.
+ @param DataSize The target data size.
+ @param CrcOut The CRC32 for target data.
+
+ @retval EFI_SUCCESS The CRC32 for target data is calculated successfully.
+ @retval EFI_INVALID_PARAMETER Some parameter is not valid, so the CRC32 is not
+ calculated.
+
+**/
+EFI_STATUS
+EFIAPI
+RuntimeDriverCalculateCrc32 (
+ IN VOID *Data,
+ IN UINTN DataSize,
+ OUT UINT32 *CrcOut
+ )
+{
+ UINT32 Crc;
+ UINTN Index;
+ UINT8 *Ptr;
+
+ if (Data == NULL || DataSize == 0 || CrcOut == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Crc = 0xffffffff;
+ for (Index = 0, Ptr = Data; Index < DataSize; Index++, Ptr++) {
+ Crc = (Crc >> 8) ^ mCrcTable[(UINT8) Crc ^ *Ptr];
+ }
+
+ *CrcOut = Crc ^ 0xffffffff;
+ return EFI_SUCCESS;
+}
+
+
+/**
+ This internal function reverses bits for 32bit data.
+
+ @param Value The data to be reversed.
+
+ @return Data reversed.
+
+**/
+UINT32
+ReverseBits (
+ UINT32 Value
+ )
+{
+ UINTN Index;
+ UINT32 NewValue;
+
+ NewValue = 0;
+ for (Index = 0; Index < 32; Index++) {
+ if ((Value & (1 << Index)) != 0) {
+ NewValue = NewValue | (1 << (31 - Index));
+ }
+ }
+
+ return NewValue;
+}
+
+/**
+ Initialize CRC32 table.
+
+**/
+VOID
+RuntimeDriverInitializeCrc32Table (
+ VOID
+ )
+{
+ UINTN TableEntry;
+ UINTN Index;
+ UINT32 Value;
+
+ for (TableEntry = 0; TableEntry < 256; TableEntry++) {
+ Value = ReverseBits ((UINT32) TableEntry);
+ for (Index = 0; Index < 8; Index++) {
+ if ((Value & 0x80000000) != 0) {
+ Value = (Value << 1) ^ 0x04c11db7;
+ } else {
+ Value = Value << 1;
+ }
+ }
+
+ mCrcTable[TableEntry] = ReverseBits (Value);
+ }
+}
diff --git a/Core/EM/usb/UsbLegacy.cif b/Core/EM/usb/UsbLegacy.cif
new file mode 100644
index 0000000..7775574
--- /dev/null
+++ b/Core/EM/usb/UsbLegacy.cif
@@ -0,0 +1,8 @@
+<component>
+ name = "UsbLegacy"
+ category = ModulePart
+ LocalRoot = "Core\EM\usb\"
+ RefName = "USB_LEGACY"
+[parts]
+"USBINT13"
+<endComponent>
diff --git a/Core/EM/usb/amiusbhc.c b/Core/EM/usb/amiusbhc.c
new file mode 100644
index 0000000..7f90434
--- /dev/null
+++ b/Core/EM/usb/amiusbhc.c
@@ -0,0 +1,3330 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/core/em/usb/amiusbhc.c 1 3/01/17 2:28a Chienhsieh $
+//
+// $Revision: 1 $
+//
+// $Date: 3/01/17 2:28a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/core/em/usb/amiusbhc.c $
+//
+// 1 3/01/17 2:28a Chienhsieh
+// [TAG] EIP320994
+// [Description] Fixed Reconnect XHCI controller fail in shell with USB,
+// 4.6.5.1_USB_08.10.36 (XHCI Mode: Enabled)
+//
+// 99 10/28/16 3:59a Wilsonlee
+// [TAG] EIP300142
+// [Category] Improvement
+// [Description] Remove USB Int1C module part because we use the other
+// method to service xhci.
+// [Files] usbport.c, amidef.h, amiusbhc.c, UsbLegacy.cif
+//
+// 98 10/16/16 10:18p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 97 7/28/16 4:55a Wilsonlee
+// [TAG] EIP264662
+// [Category] Improvement
+// [Description] Don't install usb hw smi after reconnecting usb
+// controllers.
+// [Files] uhcd.c, usb.c, ohci.c, amiusb.c, amiusbhc.c
+//
+// 96 7/07/16 1:12a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 95 3/31/16 5:49a Wilsonlee
+// [TAG] EIP259282
+// [Category] Improvement
+// [Description] Update AmiUsbHcGetRootHubPortStatus function to support
+// super speed devices.
+// [Files] amiusbhc.c
+//
+// 94 3/02/16 9:42p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 93 1/19/16 3:19a Wilsonlee
+// [TAG] EIP251667
+// [Category] Improvement
+// [Description] Implement EFI_USB2_HC_PROTOCOL.SetState() function.
+// [Files] amiusbhc.c, uhcd.h
+//
+// 92 1/19/16 2:47a Wilsonlee
+// [TAG] EIP251519
+// [Category] Improvement
+// [Description] Return current state of the USB host controller on
+// EFI_USB2_HC_PROTOCOL.GetState().
+// [Files] amiusbhc.c
+//
+// 91 1/19/16 2:12a Wilsonlee
+// [TAG] EIP252487
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Static code analysis issues found in Usb module.
+// [RootCause] Wrong function called due to copy-paste error.
+// [Solution] Replace AmiUsbHcClearRootHubPortFeature with
+// AmiUsbHcSetRootHubPortFeature.
+// [Files] amiusbhc.c
+//
+// 90 12/03/15 1:31a Wilsonlee
+// [TAG] EIP247363
+// [Category] Improvement
+// [Description] MajorRevision is 3 and MinorRevision is 1 for xhci 1.1
+// controllers.
+// [Files] amiusbhc.c
+//
+// 89 7/24/15 5:03a Wilsonlee
+// [TAG] EIP230092
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] Usb devices don't work in VL801 / VL805 under BIOS.
+// [RootCause] Bit[0..5] are reserved in Device Context Base Address
+// Array Element 0.
+// [Solution] Allcate a PAGESIZE boundary for Scratchpad Buffer Array
+// Base Address.
+// [Files] amiusbhc.c
+//
+// 88 5/13/15 2:46a Wilsonlee
+// [TAG] EIP216587
+// [Category] Improvement
+// [Description] Add 64-bit addressing buffer support for usb transfers.
+// [Files] amiusbhc.c, efiusbmass.c
+//
+// 87 4/10/15 3:05a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 86 2/09/15 4:16a Wilsonlee
+// [TAG] EIP202592
+// [Category] Improvement
+// [Description] Don't reset xhci controller if it's Debug Capability is
+// enabled.
+// [Files] xhci.c, xhci.h, amiusbhc.c
+//
+// 85 1/22/15 10:20p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 84 12/24/14 6:12a Wilsonlee
+// [TAG] EIP196753
+// [Category] Improvement
+// [Description] Check Max Scratchpad Buffers (Max Scratchpad Bufs Hi)
+// register and allocate Scratchpad buffers.
+// [Files] amiusbhc.c, xhci.h
+//
+// 83 6/29/14 10:40p Wilsonlee
+// [TAG] EIP175328
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Bluetooth module asserts in AmiUsb_07.
+// [RootCause] For ActivatePolling function, we use new parameter,
+// PollingLength, in AmiUsb_07, but it's undefined in
+// AmiUsb2HcAsyncInterruptTransfer.
+// [Solution] Initialize PollingLength in
+// AmiUsb2HcAsyncInterruptTransfer.
+// [Files] amiusbhc.c
+//
+// 82 4/30/14 5:27a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 81 12/30/13 3:17a Ryanchou
+// Corrent max packet size check for full speed device in
+// AmiUsb2HcSyncInterruptTransfer().
+//
+// 80 7/26/13 2:41a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 79 3/25/13 9:36p Wilsonlee
+// [TAG] EIP118926
+// [Category] Improvement
+// [Description] Add the token "EFI_USB_HC_INTERRUPT_OUT_SUPPORT" to
+// control whether support EFI_USB2_HC_PROTOCOL.AsyncInterruptTransfer and
+// EFI_USB2_HC_PROTOCOL.SyncInterruptTransfer() on OUT endpoints.
+// [Files] amiusbhc.c, usbsrc.sdl
+//
+// 78 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 77 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 76 11/10/12 6:41a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 75 9/28/12 3:00a Wilsonlee
+// [TAG] EIP101226
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Chief River fails to boot when Above 4G Decoding is
+// enabled.
+// [RootCause] We read 32 bits width memory base address even if it is
+// 64 bits wide.
+// [Solution] Read 64 bits width memory base address if it is 64 bits
+// wide.
+// [Files] amiusbhc.c
+//
+// 74 8/29/12 8:34a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 73 8/29/12 6:25a Ryanchou
+// [TAG] EIP93932
+// [Category] Improvement
+// [Description] Fix the SCT test failure in AsyncInterruptTransfer
+// item.
+// [Files] amiusbhc.c
+//
+// 72 7/25/12 4:51a Wilsonlee
+// [TAG] EIP91840
+// [Category] Improvement
+// [Description] Initialize the variable Params.ApiData.CoreProc.retVal
+// and Params.bRetValue.
+// [Files] amiusbhc.c
+//
+// 71 5/04/12 6:41a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 70 5/03/12 5:53a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 69 4/10/12 10:14p Wilsonlee
+// [TAG] EIP84790
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB IO PROTOCOL under XHCI issue
+// [RootCause] The DevMiscInfo is NULL.
+// [Solution] Fill the DevMiscInfo for the xhci controller.
+// [Files] ehci.c, xhci.c, amiusbhc.c
+//
+// 68 2/16/12 8:55p Wilsonlee
+// [TAG] EIP81612
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] Add EFI_USB_SPEED_SUPER in EFI_USB2_HC_PROTOCOL
+// according to UEFI 2.3.1 spec
+// [Files] usb.c, usbbus.c, amiusbhc.c
+//
+// 67 1/13/12 4:26a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 66 12/14/11 2:07a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 65 9/28/11 10:47a Ryanchou
+// [TAG] EIP66064
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System hangs when waiting for finger swipe
+// [RootCause] USB driver save the URP pointer to EBDA in function
+// UsbSmiCore and UsbSmiHc, the pointer will be destroyed if someone also
+// invoke the two functions.
+// [Solution] Save the URP pointer before generate SW SMI and restore it
+// after return from SMI.
+// [Files] amiusb.c, amiusbhc.c, usbport.c
+//
+// 64 7/15/11 6:23a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 62 4/06/11 3:00a Ryanchou
+// [TAG] EIP57691
+// [Category] Improvement
+// [Description] The MP version of FL1009 doesn't need the EIP46210
+// workaround, remove the EIP46210 change.
+// [Files] amiusbhc.c
+//
+// 61 2/18/11 12:24a Ryanchou
+// [TAG] EIP51495
+// [Category] Improvement
+// [Description] Clear 'HC OS Owned Semaphore' bit during XHCI legacy
+// initialization.
+// [Files] amiusbhc.c, ehci.c
+//
+// 60 12/28/10 4:00a Ryanchou
+// [TAG] EIP48009
+// [Category] Improvement
+// [Description] Use 32 or 64 byte Context data structures dynamically.
+// [Files] amiusbhc.c, usbsrc.sdl, xhci.c, xhci.h
+//
+// 59 12/02/10 2:19p Olegi
+// [TAG] EIP48695
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] SCT Error for USB HC SyncInterruptTransfer API
+// [RootCause] Checking for endpoint being IN was missing.
+// [Solution] - Added checking for BIT7 of the interrupt endpoint
+// address, if not set return EFI_INVALID_PARAMETER.
+// - Corrected EFI USB mouse driver that issues the SyncInterruptTransfer
+// with the wrong endpoint address.
+// [Files] amiusbhc.c
+// efiusbms.c
+//
+// 58 10/30/10 2:32a Ryanchou
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 57 10/22/10 9:07a Ryanchou
+// EIP46210: Added FL1009 USB 3.0 connection linkup workaround.
+//
+// 56 10/22/10 8:58a Ryanchou
+// EIP46693: Clear xHCI BIOS owned semaphore bit and SMI enable bit in
+// PreInitXhci.
+//
+// 55 10/21/10 10:16a Ryanchou
+//
+// 54 9/16/10 12:47p Olegi
+// Changed the parameters validation code in
+// AmiUsb2HcSyncInterruptTransfer function:
+// - MaxPacketLength does not have to be 8, it is 4 for a mouse
+// - Endpoint does not have to be in (BIT7)
+//
+// 53 9/07/10 6:03a Tonylo
+// EIP43742 - Wrong 64bit-Addressing Capability bit acquired for
+// reference.
+//
+// 52 8/31/10 9:01a Tonylo
+// EIP41544 - Add EntronTech XHCI support.
+//
+// Category: New Feature
+//
+// Description: Add EntronTech XHCI support.
+//
+// Files: amiusbhc.c
+// usbport.c
+// uhcd.h
+//
+//
+// 51 8/17/10 4:26p Olegi
+// Klockwork issues fixes. EIP37978
+//
+// 50 6/07/10 5:00p Olegi
+// Corrected the transfer routines output values. EIP34492.
+//
+// 49 5/19/10 4:04p Olegi
+// Remove the assertion on not-successful return from SMI handler. Errors
+// are legitimate, they are handled on the callers' level.
+//
+// 48 4/02/10 8:59a Olegi
+//
+// 47 2/27/10 12:00p Olegi
+//
+// 46 2/26/10 4:08p Olegi
+//
+// 45 2/08/10 9:56a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 44 1/27/10 5:26p Olegi
+//
+// 43 1/19/10 11:59a Olegi
+//
+// 42 12/22/09 8:47a Olegi
+//
+// 41 11/25/09 8:06a Olegi
+//
+// 40 11/09/09 5:40p Olegi
+//
+// 39 10/30/09 5:48p Olegi
+//
+// 38 10/09/09 5:57p Olegi
+//
+// 37 8/11/09 9:30a Olegi
+// Update for a bugfix #24507.
+//
+// 36 8/05/09 6:01p Olegi
+// Bugfix in the controller version reporting. EIP#24507.
+//
+// 34 12/16/08 10:50a Olegi
+// Correction in the return values: 0 changed to NULL. EIP#17767.
+//
+// 32 10/03/08 3:31p Olegi
+// gUsbData->dLastCommandStatusExtended is initialized before every
+// transfer.
+//
+// 31 9/26/08 5:06p Olegi
+// Added one more stall check condition.
+//
+// 30 9/02/08 10:33a Olegi
+// Modifications in GetRootHubStatus and ControlTransfer to return proper
+// error codes.
+//
+// 29 8/08/08 2:39p Olegi
+// Bugfix in AmiUsbHcGetRootHubPortStatus - port number passed there is
+// 0-based.
+//
+// 28 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 23 12/22/06 4:05p Olegi
+// Timeout implementation.
+//
+// 18 10/26/06 3:57p Olegi
+// EFI_USB2_HC_PROTOCOL implementatin.
+//
+// 12 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 8 6/15/05 1:58p Andriyn
+// Comments were changed
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AmuUsbHc.c
+//
+// Description: USB_HC_PROTOCOL implementation
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "Efi.h"
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+
+#include "tree.h"
+#include "uhci.h"
+#include "pci.h"
+#include "protocol\cpu.h"
+#include "protocol\legacy8259.h"
+
+#define INTERRUPTQUEUESIZE 10
+
+extern EFI_GUID gEfiUsb2HcProtocolGuid;
+extern USB_GLOBAL_DATA *gUsbData;
+extern EFI_USB_PROTOCOL *gAmiUsbController;
+
+static UINT8 SpeedMap[] = { 0x10, 0x01, 0, 0 };
+
+EFI_LEGACY_8259_PROTOCOL *gPic;
+UINT32 gVector = 0;
+
+UINT8 *gUsbBusTempBuffer = NULL;
+UINTN gTempBufferPages = 0;
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetThis
+//
+// Description:
+// Function returns a pointer to HcProtocol2 record of a given protocol
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static HC_DXE_RECORD* GetThis(EFI_USB2_HC_PROTOCOL* Protocol)
+{
+ return (HC_DXE_RECORD*)(
+ (char*)Protocol - (UINTN)&((HC_DXE_RECORD*)0)->hcprotocol2 );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetThis1
+//
+// Description:
+// Function returns a pointer to HcProtocol record of a given protocol
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static HC_DXE_RECORD* GetThis1 (EFI_USB_HC_PROTOCOL* Protocol)
+{
+ return (HC_DXE_RECORD*)(
+ (char*)Protocol - (UINTN)&((HC_DXE_RECORD*)0)->hcprotocol );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetTransferStatus
+//
+// Description:
+// Function converts the bitmap of gUsbData->dLastCommandStatusExtended into
+// a valid USB error.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static UINT32 GetTransferStatus()
+{
+ static struct { int BitDst, BitSrc; } ErrorMap[] = {
+ EFI_USB_ERR_STALL, USB_TRSFR_STALLED,
+ EFI_USB_ERR_STALL, USB_BULK_STALLED,
+ EFI_USB_ERR_STALL, USB_CONTROL_STALLED,
+ EFI_USB_ERR_BUFFER, USB_TRSFR_BUFFER_ERROR,
+ EFI_USB_ERR_BABBLE, USB_TRNSFR_BABBLE,
+ EFI_USB_ERR_NAK, USB_TRNSFR_NAK,
+ EFI_USB_ERR_CRC, USB_TRNSFR_CRCERROR,
+ EFI_USB_ERR_TIMEOUT, USB_TRNSFR_TIMEOUT, //(EIP84790)
+ EFI_USB_ERR_BITSTUFF, USB_TRNSFR_BITSTUFF,
+ EFI_USB_ERR_SYSTEM, 0
+ };
+ UINT32 Err = 0;
+ UINT32 Status = gUsbData->dLastCommandStatusExtended;
+ UINT8 i;
+
+ for (i = 0; i<COUNTOF(ErrorMap); ++i){
+ if( Status & ErrorMap[i].BitSrc ) {
+ Err |= ErrorMap[i].BitDst;
+ }
+ }
+
+ if( Status == 0 ) {
+ return EFI_USB_NOERROR;
+ } else {
+ return Err;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiCore
+//
+// Description:
+// Bridge between DXE code and function in USB Core proc table which is inside
+// our SMI code.
+//
+// Input:
+// Func - function number opUSBCORE_XXX which corresponds to index in Core Proc table.
+// Rest of the parameters coresponds the callee interface
+//
+// Output:
+// Whatever callee returns
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+enum {
+ opUSBCORE_GetDescriptor,
+ opUSBCORE_ReConfigDevice,
+ opUSBCORE_ReConfigDevice2,
+ opUSBCORE_AllocDevInfo,
+ opUSBCORE_PrepareForLegacyOS,
+ opUSBCORE_ResetAndReconfigDev,
+ opUSBCORE_DevDriverDisconnect,
+ opUSBCORE_PeriodicEvent,
+ opUSBCORE_Last,
+};
+
+
+int CoreprocStackSize[] = {
+ 6*sizeof(VOID*), // opUSBSMI_GetDescriptor
+ 2*sizeof(VOID*), // opUSBCORE_ReConfigDevice
+ 4*sizeof(VOID*), // opUSBCORE_ReConfigDevice2
+ 1*sizeof(VOID*), // opUSBCORE_AllocDevInfo
+ 1*sizeof(VOID*), // opUSBCORE_PrepareForLegacyOS
+ 2*sizeof(VOID*), // opUSBCORE_ResetAndReconfigDev
+ 2*sizeof(VOID*), // opUSBCORE_DevDriverDisconnect
+ 0, // opUSBCORE_PeriodicEvent
+};
+
+UINTN UsbSmiCore( UINT8 Func, ... )
+{
+ URP_STRUC Params;
+ VA_LIST ArgList;
+
+ ASSERT(Func < COUNTOF(CoreprocStackSize));
+// ASSERT(CoreprocStackSize[Func] > 0);
+
+ VA_START(ArgList, Func);
+
+ Params.bFuncNumber = USB_API_CORE_PROC;
+ Params.bSubFunc = Func;
+ Params.bRetValue = USB_ERROR; //(EIP91840+)
+ Params.ApiData.CoreProc.paramBuffer = &VA_ARG(ArgList, int);
+ Params.ApiData.CoreProc.paramSize = CoreprocStackSize[Func];
+ Params.ApiData.CoreProc.retVal = 0; //(EIP91840+)
+ USB_DEBUG(DEBUG_USBHC_LEVEL8,
+ "call CORE SMI proc(%d); params: %x\n", Func, Params.ApiData.CoreProc.paramBuffer);
+
+ InvokeUsbApi(&Params);
+
+ VA_END(ArgList);
+
+// ASSERT(Params.bRetValue == USB_SUCCESS);
+
+ return Params.ApiData.CoreProc.retVal;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiGetDescriptor
+//
+// Description:
+// SW SMI to execute GetDescriptor transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8*
+UsbSmiGetDescriptor (
+ HC_STRUC* HostController,
+ DEV_INFO* Device,
+ UINT8* Buffer,
+ UINT16 Length,
+ UINT8 DescType,
+ UINT8 DescIndex
+)
+{
+ EFI_STATUS Status;
+ UINT8 *DataBuffer = Buffer;
+ UINTN ReturnValue;
+
+ if (Shr64((UINTN)Buffer, 32)) {
+ if (gUsbBusTempBuffer == NULL || Length > (gTempBufferPages << 12)) {
+ if (gUsbBusTempBuffer) {
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)gUsbBusTempBuffer, gTempBufferPages);
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ gTempBufferPages = EFI_SIZE_TO_PAGES(Length);
+ gUsbBusTempBuffer = (UINT8*)0xFFFFFFFF;
+ Status = gBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ gTempBufferPages, (EFI_PHYSICAL_ADDRESS*)&gUsbBusTempBuffer);
+ if (!EFI_ERROR(Status)) {
+ gBS->SetMem (gUsbBusTempBuffer, gTempBufferPages << 12, 0);
+ } else {
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ }
+
+ if (gUsbBusTempBuffer) {
+ DataBuffer = gUsbBusTempBuffer;
+ }
+ }
+ ReturnValue = UsbSmiCore(opUSBCORE_GetDescriptor,
+ HostController, Device, DataBuffer, Length, DescType, DescIndex);
+
+ if (ReturnValue == 0) {
+ return NULL;
+ }
+
+ if (DataBuffer != Buffer) {
+ gBS->CopyMem (Buffer, DataBuffer, Length);
+ }
+
+ return Buffer;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiReConfigDevice
+//
+// Description:
+// Perform the device specific configuration
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbSmiReConfigDevice(
+ HC_STRUC* HostController,
+ DEV_INFO* Device
+)
+{
+ return (UINT8)UsbSmiCore(opUSBCORE_ReConfigDevice, HostController, Device);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbAllocDevInfo
+//
+// Description:
+// Allocate the empty buffer for USB device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+UsbAllocDevInfo()
+{
+ return (DEV_INFO*)UsbSmiCore(opUSBCORE_AllocDevInfo, 1);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbPrepareForLegacyOS
+//
+// Description:
+// Callback on LEGACY_BOOT event
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UsbPrepareForLegacyOS()
+{
+ UsbSmiCore(opUSBCORE_PrepareForLegacyOS, 1);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbResetAndReconfigDev
+//
+// Description:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbResetAndReconfigDev(
+ HC_STRUC* HostController,
+ DEV_INFO* Device
+)
+{
+ return (UINT8)UsbSmiCore(opUSBCORE_ResetAndReconfigDev, HostController, Device);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbDevDriverDisconnect
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbDevDriverDisconnect(
+ HC_STRUC* HostController,
+ DEV_INFO* Device
+)
+{
+ return (UINT8)UsbSmiCore(opUSBCORE_DevDriverDisconnect, HostController, Device);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiHc
+//
+// Description:
+// Bridge between DXE code and SMI function in USB HC driver.
+//
+// Input:
+// Func - function number opHC_XXX which corresponds to index in HCD_HEADER
+// HcType - type of USB HC controller; selects an HC driver to call
+// Rest of the parameters coresponds the callee interface
+//
+// Output:
+// Whatever callee returns
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int HcprocStackSize[] = {
+ sizeof(VOID*) * 1, // opHC_Start
+ sizeof(VOID*) * 1, // opHC_Stop
+ sizeof(VOID*) * 1, // opHC_EnumeratePorts
+ sizeof(VOID*) * 1, // opHC_DisableInterrupts
+ sizeof(VOID*) * 1, // opHC_EnableInterrupts
+ sizeof(VOID*) * 1, // opHC_ProcessInterrupt
+ sizeof(VOID*) * 3, // opHC_GetRootHubStatus
+ sizeof(VOID*) * 2, // opHC_DisableRootHub
+ sizeof(VOID*) * 2, // opHC_EnableRootHub
+ sizeof(VOID*) * 7, // opHC_ControlTransfer
+ sizeof(VOID*) * 5, // opHC_BulkTransfer
+ sizeof(VOID*) * 6, // opHC_InterruptTransfer
+ sizeof(VOID*) * 2, // opHC_DeactivatePolling
+ sizeof(VOID*) * 2, // opHC_ActivatePolling
+ sizeof(VOID*) * 1, // opHC_DisableKeyRepeat
+ sizeof(VOID*) * 1, // opHC_EnableKeyRepeat
+ sizeof(VOID*) * 3, // opHC_EnableEndpoints
+ sizeof(VOID*) * 4, // opHC_InitDeviceData
+ sizeof(VOID*) * 2, // opHC_DeinitDeviceData
+ sizeof(VOID*) * 2, // opHC_ResetRootHub
+ sizeof(VOID*) * 3, // opHC_ClearEndpointState
+ sizeof(VOID*) * 1, // opHC_GlobalSuspend
+};
+
+UINTN
+UsbSmiHc(
+ UINT8 Func,
+ UINT8 HcType,
+ ...
+)
+{
+ URP_STRUC Params;
+ VA_LIST ArgList;
+
+ ASSERT(Func < sizeof(HcprocStackSize)/sizeof(int));
+ ASSERT( HcprocStackSize[Func] > 0);
+
+ VA_START(ArgList, HcType);
+
+ Params.bFuncNumber = USB_API_HC_PROC;
+ Params.bSubFunc = Func;
+ Params.bRetValue = USB_ERROR; //(EIP91840+)
+ Params.ApiData.HcProc.paramBuffer = &VA_ARG(ArgList, int);
+ Params.ApiData.HcProc.paramSize = HcprocStackSize[Func];
+ Params.ApiData.HcProc.bHCType = HcType;
+ Params.ApiData.HcProc.retVal = 0; //(EIP91840+)
+ USB_DEBUG(DEBUG_USBHC_LEVEL8,
+ "call HC SMI driver(type:%d;func:%d); params at %x\n",
+ HcType, Func, Params.ApiData.HcProc.paramBuffer);
+
+ InvokeUsbApi(&Params);
+
+ VA_END(ArgList);
+// ASSERT(Params.bRetValue == USB_SUCCESS);
+
+ return Params.ApiData.HcProc.retVal;
+}
+
+VOID
+UsbSmiPeriodicEvent(VOID)
+{
+// UsbSmiCore(opUSBCORE_PeriodicEvent);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiGetRootHubStatus, UsbSmiEnableRootHub, UsbSmiDisableRootHub
+//
+// Description:
+// Wrappers for calling USB HC driver functions in USBSMI service
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 UsbSmiGetRootHubStatus(HC_STRUC* HcStruc, UINT8 PortNum, BOOLEAN ClearChangeBits)
+{
+ return (UINT8)UsbSmiHc(
+ opHC_GetRootHubStatus, HcStruc->bHCType, HcStruc, PortNum, ClearChangeBits);
+}
+
+UINT8 UsbSmiEnableRootHub(HC_STRUC* HcStruc, UINT8 PortNum)
+{
+ return (UINT8)UsbSmiHc(
+ opHC_EnableRootHub, HcStruc->bHCType, HcStruc, PortNum);
+}
+
+UINT8 UsbSmiDisableRootHub(HC_STRUC* HcStruc, UINT8 PortNum)
+{
+ return (UINT8)UsbSmiHc(
+ opHC_DisableRootHub, HcStruc->bHCType, HcStruc, PortNum);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiControlTransfer, UsbSmiBulkTransfer, UsbSmiInterruptTransfer
+//
+// Description:
+// Wrappers for calling USB HC driver USB transfer functions
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+UINT16
+UsbSmiControlTransfer (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT16 Request,
+ UINT16 Index,
+ UINT16 Value,
+ UINT8 *Buffer,
+ UINT16 Length)
+{
+ EFI_STATUS Status;
+ UINT8 *DataBuffer = Buffer;
+ UINTN ReturnValue;
+
+ if (Shr64((UINTN)Buffer, 32)) {
+ if (gUsbBusTempBuffer == NULL || Length > (gTempBufferPages << 12)) {
+ if (gUsbBusTempBuffer) {
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)gUsbBusTempBuffer, gTempBufferPages);
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ gTempBufferPages = EFI_SIZE_TO_PAGES(Length);
+ gUsbBusTempBuffer = (UINT8*)0xFFFFFFFF;
+ Status = gBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ gTempBufferPages, (EFI_PHYSICAL_ADDRESS*)&gUsbBusTempBuffer);
+ if (!EFI_ERROR(Status)) {
+ gBS->SetMem (gUsbBusTempBuffer, gTempBufferPages << 12, 0);
+ } else {
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ }
+ if (gUsbBusTempBuffer) {
+ DataBuffer = gUsbBusTempBuffer;
+ }
+ }
+
+ if (DataBuffer != Buffer) {
+ if (!(Request & USB_REQ_TYPE_INPUT)) {
+ gBS->CopyMem(DataBuffer, Buffer, Length);
+ }
+ }
+
+ ReturnValue = UsbSmiHc(opHC_ControlTransfer,
+ HcStruc->bHCType, HcStruc, DevInfo,
+ Request, Index, Value, DataBuffer, Length);
+
+ if (DataBuffer != Buffer) {
+ if (Request & USB_REQ_TYPE_INPUT) {
+ gBS->CopyMem(Buffer, DataBuffer, Length);
+ }
+ }
+
+ return (UINT16)ReturnValue;
+}
+
+UINT32
+UsbSmiBulkTransfer(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 XferDir,
+ UINT8 *Buffer,
+ UINT32 Length
+)
+{
+ EFI_STATUS Status;
+ UINT8 *DataBuffer = Buffer;
+ UINTN ReturnValue;
+
+ if (Shr64((UINTN)Buffer, 32)) {
+ if (gUsbBusTempBuffer == NULL || Length > (gTempBufferPages << 12)) {
+ if (gUsbBusTempBuffer) {
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)gUsbBusTempBuffer, gTempBufferPages);
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ gTempBufferPages = EFI_SIZE_TO_PAGES(Length);
+ gUsbBusTempBuffer = (UINT8*)0xFFFFFFFF;
+ Status = gBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ gTempBufferPages, (EFI_PHYSICAL_ADDRESS*)&gUsbBusTempBuffer);
+ if (!EFI_ERROR(Status)) {
+ gBS->SetMem (gUsbBusTempBuffer, gTempBufferPages << 12, 0);
+ } else {
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ }
+ if (gUsbBusTempBuffer) {
+ DataBuffer = gUsbBusTempBuffer;
+ }
+ }
+
+ if (DataBuffer != Buffer) {
+ if (!(XferDir & BIT7)) {
+ gBS->CopyMem(DataBuffer, Buffer, Length);
+ }
+ }
+
+ ReturnValue = UsbSmiHc(opHC_BulkTransfer,
+ HcStruc->bHCType, HcStruc, DevInfo, XferDir, DataBuffer, Length);
+
+ if (DataBuffer != Buffer) {
+ if (XferDir & BIT7) {
+ gBS->CopyMem(Buffer, DataBuffer, Length);
+ }
+ }
+
+ return (UINT32)ReturnValue;
+}
+
+UINT16
+UsbSmiInterruptTransfer (
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 EndpointAddress,
+ UINT16 MaxPktSize,
+ UINT8 *Buffer,
+ UINT16 Length
+)
+{
+ EFI_STATUS Status;
+ UINT8 *DataBuffer = Buffer;
+ UINTN ReturnValue;
+
+ if (Shr64((UINTN)Buffer, 32)) {
+ if (gUsbBusTempBuffer == NULL || Length > (gTempBufferPages << 12)) {
+ if (gUsbBusTempBuffer) {
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)gUsbBusTempBuffer, gTempBufferPages);
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ gTempBufferPages = EFI_SIZE_TO_PAGES(Length);
+ gUsbBusTempBuffer = (UINT8*)0xFFFFFFFF;
+ Status = gBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ gTempBufferPages, (EFI_PHYSICAL_ADDRESS*)&gUsbBusTempBuffer);
+ if (!EFI_ERROR(Status)) {
+ gBS->SetMem (gUsbBusTempBuffer, gTempBufferPages << 12, 0);
+ } else {
+ gUsbBusTempBuffer = NULL;
+ gTempBufferPages = 0;
+ }
+ }
+ if (gUsbBusTempBuffer) {
+ DataBuffer = gUsbBusTempBuffer;
+ }
+ }
+
+ if (DataBuffer != Buffer) {
+ if (EndpointAddress & BIT7) {
+ gBS->CopyMem(DataBuffer, Buffer, Length);
+ }
+ }
+
+ ReturnValue = UsbSmiHc(opHC_InterruptTransfer,
+ HcStruc->bHCType, HcStruc, DevInfo, EndpointAddress, MaxPktSize, Length);
+
+ if (DataBuffer != Buffer) {
+ if (EndpointAddress & BIT7) {
+ gBS->CopyMem(Buffer, DataBuffer, Length);
+ }
+ }
+
+ return (UINT8)ReturnValue;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbSmiActivatePolling, UsbSmiDeactivatePolling
+//
+// Description:
+// Wrappers for calling USB HC driver USB polling functions
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 UsbSmiDeactivatePolling (HC_STRUC* HostController, DEV_INFO* DevInfo )
+{
+ return (UINT8)UsbSmiHc( opHC_DeactivatePolling,
+ HostController->bHCType, HostController, DevInfo );
+}
+
+UINT8 UsbSmiActivatePolling (HC_STRUC* HostController, DEV_INFO* DevInfo )
+{
+ return (UINT8)UsbSmiHc( opHC_ActivatePolling,
+ HostController->bHCType, HostController, DevInfo );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ConvertBitmaps
+//
+// Description:
+// Converts one bit-strng to another using a convertion table
+//
+// Input:
+// Val - intial 32 bit wide bit-string
+// BitT- array of bitmaptable_t recodrds
+// Cnt - number of records in array BitT
+//
+// Output:
+// 32-bit wide bit-string - result of conversion applied to Val
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+struct BITMAPTABLE_T {unsigned int src; unsigned int dst;};
+
+UINT32
+ConvertBitmaps(
+ UINT32 Val,
+ struct BITMAPTABLE_T* BitT,
+ UINT32 Cnt
+)
+{
+ UINT32 Res = 0;
+ UINT32 i;
+ for( i=0; (BitT->src !=0)&& ( i < Cnt); ++i, BitT++ ){
+ if( BitT->src & Val )
+ Res |= BitT->dst;
+ }
+ return Res;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SearchDevinfoByAdr
+//
+// Description:
+// Enumerates DEV_INFO structures in aDevInfoTable array of USB data to find
+// one that matches the specified USB address and connects to a specified USB
+// host controller.
+//
+// Input:
+// DEV_INFO Start Pointer to the device info structure from
+// where the search begins (if 0 start from first entry)
+// DevAddr Device address
+// HcStruc Pointer to the HCStruc structure
+//
+// Output:
+// Pointer to DEV_INFO structure, NULL if device is not found
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+SearchDevinfoByAdr(
+ DEV_INFO* Start,
+ UINT8 DevAddr,
+ HC_STRUC* HcStruc
+)
+{
+ DEV_INFO* DevInfo;
+ DEV_INFO* Dev = gUsbData->aDevInfoTable + COUNTOF(gUsbData->aDevInfoTable);
+
+ for ( DevInfo = Start!=NULL?Start:&gUsbData->aDevInfoTable[1];
+ DevInfo != Dev; ++DevInfo ){
+ if ((DevInfo->Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_DUMMY)) ==
+ DEV_INFO_VALID_STRUC) {
+ if(( gUsbData->HcTable[DevInfo->bHCNumber - 1] == HcStruc) &&
+ ( DevInfo->bDeviceAddress == DevAddr )){
+ return DevInfo;
+ }
+ }
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DevAddr2Info
+//
+// Description:
+// Returns a DEV_INFO that corresponds to a device that is connected to a
+// specified host controller and has a specified address
+//
+// Input:
+// Addr Device address
+// Hc Pointer to the HCStruc structure
+//
+// Output:
+// Pointer to DEV_INFO structure, NULL if device is not found
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+DevAddr2Info(
+ UINT8 Addr,
+ HC_STRUC* Hc
+)
+{
+ DEV_INFO* Dev = SearchDevinfoByAdr(NULL, Addr, Hc);
+ USB_DEBUG(DEBUG_USBHC_LEVEL8,
+ "\tDevAddr2Info %x -> %x(hc:%x;hub:%x;port:%x;if:%x)\n",
+ Addr, Dev, Dev->bHCNumber, Dev->bHubDeviceNumber,
+ Dev->bHubPortNumber, Dev->bInterfaceNum );
+ return Dev;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FindOldTransfer
+//
+// Description:
+// Searches a DEV_INFO that was used as a temporary structure for the USB transfer.
+//
+// Input:
+// Device address
+// EndPoint Interrupt Endpoint number that was assigned to temporary structure
+// HCStruc Pointer to the HCStruc structure
+//
+// Output:
+// Pointer to DeviceInfo Structure NULL if device is not found
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+FindOldTransfer(
+ UINT8 DevAddr,
+ UINT8 EndPoint,
+ HC_STRUC* HcStruc
+)
+{
+ DEV_INFO *Dev;
+ DEV_INFO *LastDev = gUsbData->aDevInfoTable +
+ COUNTOF(gUsbData->aDevInfoTable);
+
+ for ( Dev = &gUsbData->aDevInfoTable[1]; Dev != LastDev; ++Dev ){
+ if( ((Dev->Flag & (DEV_INFO_VALID_STRUC|DEV_INFO_DEV_PRESENT) )==
+ (DEV_INFO_VALID_STRUC|DEV_INFO_DEV_PRESENT)) &&
+ (Dev->bHCNumber == HcStruc->bHCNumber ) &&
+ (Dev->bDeviceAddress == DevAddr ) &&
+ (Dev->IntInEndpoint == EndPoint ))
+ {
+ return Dev;
+ }
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AllocDevInfo
+//
+// Description:
+// Allocates temporary DEV_INFO structure in USB data area for use in USB transfer.
+//
+// Output:
+// Pointer to a DEV_INFO structure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+AllocDevInfo()
+{
+ DEV_INFO* Dev = UsbAllocDevInfo();
+ ASSERT(Dev);
+ if(Dev){
+ Dev->bDeviceType = BIOS_DEV_TYPE_USBBUS_SHADOW;
+ Dev->Flag |= DEV_INFO_DEV_DUMMY;
+ }
+ return Dev;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FreeDevInfo
+//
+// Description:
+// Marks DEV_INFO structure that it is free for use in consequent operations.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+FreeDevInfo(
+ DEV_INFO* Dev
+)
+{
+ ASSERT(Dev);
+ if (Dev) {
+ Dev->Flag &= ~(DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT | DEV_INFO_DEV_DUMMY);
+ }
+}
+
+UINT8
+TranslateInterval(
+ UINT8 Speed,
+ UINTN Interval
+)
+{
+ UINT8 BitCount = 0;
+
+ if (Speed == EFI_USB_SPEED_LOW ||
+ Speed == EFI_USB_SPEED_FULL) {
+ return (UINT8)Interval;
+ }
+
+ for (BitCount = 0; Interval != 0; BitCount++) {
+ Interval >>= 1;
+ }
+ return (BitCount + 2);
+}
+
+/////////////////////////////////////////////////////////////////////////////
+// USB Host Controller API functions
+/////////////////////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcReset
+//
+// Description:
+// Provides software reset for the USB host controller.
+//
+// Input:
+// This A pointer to the EFI_USB_HC_PROTOCOL instance. Type
+// EFI_USB_HC_PROTOCOL is defined in Section 14.1.
+// Attributes A bit mask of the reset operation to perform.
+//
+// Output:
+// EFI_SUCCESS The reset operation succeeded.
+// EFI_INVALID_PARAMETER Attributes is not valid.
+// EFI_UNSUPPORTED The type of reset specified by Attributes is
+// not currently supported by the host controller
+// hardware.
+// EFI_DEVICE_ERROR An error was encountered while attempting to
+// perform the reset operation.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcReset(
+ IN EFI_USB_HC_PROTOCOL *This,
+ IN UINT16 attributes
+)
+{
+ PROGRESS_CODE(DXE_USB_RESET);
+
+ if (!(attributes & (EFI_USB_HC_RESET_GLOBAL | EFI_USB_HC_RESET_HOST_CONTROLLER)))
+ return EFI_INVALID_PARAMETER;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL, "AmiUsbHcReset:");
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcGetState
+//
+// Description:
+// Protocol USB HC function that returns Host Controller state.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbHcGetState(
+ IN EFI_USB_HC_PROTOCOL *This,
+ OUT EFI_USB_HC_STATE *State
+)
+{
+ return AmiUsb2HcGetState(&GetThis1(This)->hcprotocol2, State);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcSetState
+//
+// Description:
+// Protocol USB HC function that sets Host Controller state.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbHcSetState(
+ IN EFI_USB_HC_PROTOCOL *This,
+ IN EFI_USB_HC_STATE State
+)
+{
+ USB_DEBUG(DEBUG_USBHC_LEVEL, "USB HC:\t\tsetState, %d\n", State);
+ return AmiUsb2HcSetState(&GetThis1(This)->hcprotocol2, State);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcTransfer
+//
+// Description:
+// Protocol USB HC function that performs USB transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcControlTransfer(
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN BOOLEAN IsSlowDevice,
+ IN UINT8 MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout,
+ OUT UINT32 *TransferResult
+)
+{
+ return AmiUsb2HcControlTransfer(&GetThis1(HcProtocol)->hcprotocol2,
+ DeviceAddress,
+ IsSlowDevice?EFI_USB_SPEED_LOW:EFI_USB_SPEED_FULL,
+ MaximumPacketLength, Request, TransferDirection, Data,
+ DataLength, Timeout, NULL, TransferResult);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcBulkTransfer
+//
+// Description:
+// Protocol USB HC function that performs USB bulk transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI AmiUsbHcBulkTransfer(
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN UINT8 MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN Timeout,
+ OUT UINT32 *TransferResult
+)
+{
+ //
+ // Check for valid maximum packet length is 8, 16, 32 or 64
+ //
+ if ( MaximumPacketLength != 8 &&
+ MaximumPacketLength != 16 &&
+ MaximumPacketLength != 32 &&
+ MaximumPacketLength != 64 ) return EFI_INVALID_PARAMETER;
+
+ return AmiUsb2HcBulkTransfer(&GetThis1(HcProtocol)->hcprotocol2,
+ DeviceAddress, EndpointAddress, EFI_USB_SPEED_FULL,
+ MaximumPacketLength, 1, &Data, DataLength,
+ DataToggle, Timeout, NULL, TransferResult);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcAsyncInterruptTransfer
+//
+// Description:
+// Protocol USB HC function that performs USB async interrupt transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcAsyncInterruptTransfer(
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN BOOLEAN IsSlowDevice,
+ IN UINT8 MaxPacket,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval ,
+ IN UINTN DataLength,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallbackFunction ,
+ IN VOID *Context)
+{
+ return AmiUsb2HcAsyncInterruptTransfer(
+ &GetThis1(HcProtocol)->hcprotocol2,
+ DeviceAddress, EndpointAddress,
+ IsSlowDevice?EFI_USB_SPEED_LOW:EFI_USB_SPEED_FULL,
+ MaxPacket, IsNewTransfer, DataToggle,
+ PollingInterval, DataLength, NULL, CallbackFunction, Context);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcSyncInterruptTransfer
+//
+// Description:
+// Protocol USB HC function that performs USB sync interrupt transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EFIAPI
+AmiUsbHcSyncInterruptTransfer(
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN BOOLEAN IsSlowDevice,
+ IN UINT8 MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN Timeout,
+ OUT UINT32 *TransferResult
+)
+{
+ return AmiUsb2HcSyncInterruptTransfer(
+ &GetThis1(HcProtocol)->hcprotocol2,
+ DeviceAddress, EndpointAddress,
+ IsSlowDevice?EFI_USB_SPEED_LOW:EFI_USB_SPEED_FULL,
+ MaximumPacketLength,
+ Data, DataLength, DataToggle, Timeout, NULL, TransferResult );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcIsochronousTransfer
+//
+// Description:
+// Protocol USB HC function that performs USB sync isochronous transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcIsochronousTransfer(
+ IN EFI_USB_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN UINT8 MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN DataLength,
+ OUT UINT32 *TransferResult
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcAsyncIsochronousTransfer
+//
+// Description:
+// Protocol USB HC function that performs USB async isochronous transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcAsyncIsochronousTransfer(
+ IN EFI_USB_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN UINT8 MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN UINTN DataLength,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallback,
+ IN VOID *Context
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcGetRootHubPortNumber
+//
+// Description:
+// Protocol USB HC function that returns the number of ports of a root hub
+// on a given controller.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcGetRootHubPortNumber (
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ OUT UINT8 *PortNumber
+)
+{
+ HC_DXE_RECORD *This = GetThis1(HcProtocol);
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB HC:\t\tget_roothub_port_number\n");
+
+ if (PortNumber == NULL) return EFI_INVALID_PARAMETER;
+
+ *PortNumber = This->hc_data->bNumPorts;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcGetRootHubPortStatus
+//
+// Description:
+// Protocol USB HC function that returns the root port status
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcGetRootHubPortStatus (
+ EFI_USB_HC_PROTOCOL *HcProtocol,
+ UINT8 PortNumber,
+ EFI_USB_PORT_STATUS *PortStatus
+)
+{
+ HC_DXE_RECORD *This = GetThis1( HcProtocol );
+
+ static struct BITMAPTABLE_T MapTable[] = {
+ {USB_PORT_STAT_DEV_CONNECTED,USB_PORT_STAT_CONNECTION},
+ {USB_PORT_STAT_DEV_LOWSPEED,USB_PORT_STAT_LOW_SPEED},
+ {USB_PORT_STAT_DEV_SUPERSPEED, USB_PORT_STAT_SUPER_SPEED},
+ {USB_PORT_STAT_DEV_SUPERSPEED_PLUS, USB_PORT_STAT_SUPER_SPEED},
+ {USB_PORT_STAT_DEV_ENABLED, USB_PORT_STAT_ENABLE},
+ {USB_PORT_STAT_DEV_OWNER, USB_PORT_STAT_OWNER}
+ };
+ static struct BITMAPTABLE_T MapTable2[] = {
+ {USB_PORT_STAT_DEV_CONNECT_CHANGED,USB_PORT_STAT_C_CONNECTION},
+ };
+
+ UINT8 Status1;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL, "USB HC:\t\tget_roothub_port_status\n" );
+
+ if (PortStatus == NULL || PortNumber >= This->hc_data->bNumPorts)
+ return EFI_INVALID_PARAMETER;
+
+ Status1 = UsbSmiGetRootHubStatus(This->hc_data,(UINT8)PortNumber + 1, TRUE);
+
+ PortStatus->PortStatus = (UINT16)ConvertBitmaps(
+ Status1, MapTable, COUNTOF(MapTable));
+ PortStatus->PortChangeStatus = (UINT16)ConvertBitmaps(
+ Status1, MapTable2, COUNTOF(MapTable2)) ;
+
+ if (((Status1 & USB_PORT_STAT_DEV_CONNECTED) != 0) &&
+ (Status1 & (USB_PORT_STAT_DEV_LOWSPEED | USB_PORT_STAT_DEV_FULLSPEED
+ | USB_PORT_STAT_DEV_SUPERSPEED | USB_PORT_STAT_DEV_SUPERSPEED_PLUS))==0) {
+ PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;
+ }
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL, "\t\tStatus=%x, PortStatus=%x, PortChangeStatus=%x\n",
+ Status1, PortStatus->PortStatus, PortStatus->PortChangeStatus );
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcSetRootHubPortFeature
+//
+// Description:
+// Protocol USB HC function set root hub port feature
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcSetRootHubPortFeature(
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+)
+{
+ HC_DXE_RECORD *This = GetThis1(HcProtocol);
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL, "USB HC:\t\tset_roothub_port_feature\n" );
+
+ if ( PortNumber >= This->hc_data->bNumPorts)
+ return EFI_INVALID_PARAMETER;
+
+ switch( PortFeature ){
+ case EfiUsbPortEnable:
+ UsbSmiEnableRootHub(This->hc_data, PortNumber + 1);
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbHcClearRootHubPortFeature
+//
+// Description:
+// Protocol USB HC function clear root hub port feature
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsbHcClearRootHubPortFeature(
+ IN EFI_USB_HC_PROTOCOL *HcProtocol,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+)
+{
+ HC_DXE_RECORD *This = GetThis1(HcProtocol);
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL, "USB HC:\t\tclear_roothub_port_feature\n");
+
+ if (PortNumber >= This->hc_data->bNumPorts) return EFI_INVALID_PARAMETER;
+
+ switch (PortFeature ) {
+ case EfiUsbPortEnable:
+ UsbSmiDisableRootHub(This->hc_data, PortNumber + 1);
+ break;
+
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+ return EFI_SUCCESS;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// USB2 Host Controller API functions
+/////////////////////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcGetCapability
+//
+// Description:
+// This is USB2HC API to get the host controller capability.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsb2HcGetCapability(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ OUT UINT8 *MaxSpeed,
+ OUT UINT8 *PortNumber,
+ OUT UINT8 *Is64BitCapable
+)
+{
+ HC_DXE_RECORD *Rec = GetThis(This);
+
+ if (MaxSpeed == NULL || PortNumber == NULL || Is64BitCapable == NULL)
+ return EFI_INVALID_PARAMETER;
+ *Is64BitCapable = FALSE; // Driver currently does not support >4GB allocations
+ // even if controller does
+ //(EIP81612)>
+ //*MaxSpeed = (Rec->hc_data->bHCType==USB_HC_EHCI)?
+ // EFI_USB_SPEED_HIGH : EFI_USB_SPEED_FULL;
+ switch (Rec->hc_data->bHCType) {
+ case USB_HC_OHCI:
+ case USB_HC_UHCI:
+ *MaxSpeed = EFI_USB_SPEED_FULL;
+ break;
+ case USB_HC_EHCI:
+ *MaxSpeed = EFI_USB_SPEED_HIGH;
+ break;
+ case USB_HC_XHCI:
+ *MaxSpeed = EFI_USB_SPEED_SUPER;
+ break;
+ }
+ //<(EIP81612)
+
+ *PortNumber = Rec->hc_data->bNumPorts;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcReset
+//
+// Description:
+// This is USB2HC API to perform host controller reset.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsb2HcReset(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT16 Attributes
+)
+{
+ PROGRESS_CODE(DXE_USB_RESET);
+
+ if (Attributes == 0 || (Attributes & ~(EFI_USB_HC_RESET_GLOBAL
+ | EFI_USB_HC_RESET_HOST_CONTROLLER | EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG
+ | EFI_USB_HC_RESET_HOST_WITH_DEBUG))==0 )
+ {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcGetState
+//
+// Description:
+// This is USB2HC API to get the host controller state.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsb2HcGetState(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ OUT EFI_USB_HC_STATE *State
+)
+{
+ HC_DXE_RECORD *Rec = GetThis(This);
+
+ if (State == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (Rec->hc_data->dHCFlag & HC_STATE_RUNNING) {
+ *State = EfiUsbHcStateOperational;
+ return EFI_SUCCESS;
+ }
+
+ if (Rec->hc_data->dHCFlag & HC_STATE_SUSPEND) {
+ *State = EfiUsbHcStateSuspend;
+ return EFI_SUCCESS;
+ }
+
+ *State = EfiUsbHcStateHalt;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcSetState
+//
+// Description:
+// This is USB2HC API to set the host controller state.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsb2HcSetState(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN EFI_USB_HC_STATE State
+)
+{
+ HC_DXE_RECORD *Rec = GetThis(This);
+ EFI_USB_HC_STATE CurrentState;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 UsbStatus = USB_SUCCESS;
+
+ Status = AmiUsb2HcGetState(This, &CurrentState);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if (CurrentState == State) {
+ return Status;
+ }
+
+ switch (State) {
+ case EfiUsbHcStateHalt:
+ UsbStatus = (UINT8)UsbSmiHc(opHC_Stop, Rec->hc_data->bHCType, Rec->hc_data);
+ break;
+ case EfiUsbHcStateOperational:
+ UsbStatus = (UINT8)UsbSmiHc(opHC_Start, Rec->hc_data->bHCType, Rec->hc_data);
+ break;
+ case EfiUsbHcStateSuspend:
+ UsbStatus = (UINT8)UsbSmiHc(opHC_GlobalSuspend, Rec->hc_data->bHCType, Rec->hc_data);
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ break;
+ }
+
+ if (UsbStatus != USB_SUCCESS) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AsyncInterruptOnTimer
+//
+// Description:
+// This function checks if queue has a new transfer. If yes, calls a
+// callback with data from transfer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EFIAPI
+AsyncInterruptOnTimer (
+ EFI_EVENT Event,
+ VOID *Ctx
+)
+{
+ USBHC_INTERRUPT_DEVNINFO_T *Idi = (USBHC_INTERRUPT_DEVNINFO_T*)Ctx;
+ UINT8 Lock;
+ VOID *Data;
+
+ //
+ // Check re-entrance
+ //
+ ATOMIC({Lock = Idi->Lock; Idi->Lock = 1;});
+ if(Lock) {
+ return; //control is already inside
+ }
+
+ while((UINTN)QueueSize(&Idi->QCompleted) >= Idi->DataLength ){
+ ATOMIC(Data = QueueRemoveMsg( &Idi->QCompleted, (int)Idi->DataLength ));
+ //TRACE((-1,"USBHC: AsyncInterruptOnTimer: calling callback...\n"));
+ Idi->CallbackFunction(
+ Data, Idi->DataLength, Idi->Context, EFI_USB_NOERROR);
+ }
+
+ Idi->Lock = 0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcBulkTransfer
+//
+// Description:
+// This function performs USB2 HC Bulk Transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcBulkTransfer(
+ IN EFI_USB2_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN Timeout,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+)
+{
+ UINT32 SmiRes;
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ DEV_INFO* DevInfo;
+ DEV_INFO* DevSrc = DevAddr2Info( DeviceAddress, This->hc_data );
+ UINT8 XferDir = 0;
+ UINT16 CurrentTimeout;
+ UINT8 ToggleBit = (EndpointAddress & 0xF) - 1;
+
+ //
+ // Check Params
+ //
+ //(EIP81612)>
+ if( DevSrc == NULL || Data == NULL || Data[0] == NULL ||
+ (*DataToggle != 0 && *DataToggle != 1) ||
+ (DeviceSpeed != EFI_USB_SPEED_SUPER && DeviceSpeed != EFI_USB_SPEED_HIGH
+ && DeviceSpeed != EFI_USB_SPEED_FULL) ||
+ *DataLength == 0 || TransferResult == NULL ||
+ MaximumPacketLength == 0 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Check for valid maximum packet length
+ //
+ if ( DeviceSpeed == EFI_USB_SPEED_SUPER && MaximumPacketLength > 1024 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //<(EIP81612)
+ if ( DeviceSpeed == EFI_USB_SPEED_HIGH && MaximumPacketLength > 512 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if ( DeviceSpeed == EFI_USB_SPEED_FULL && MaximumPacketLength > 64 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Alloc DEV_INFO
+ //
+ DevInfo = AllocDevInfo();
+
+ if(DevInfo == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Fill DEV_INFO
+ //
+ DevInfo->bDeviceAddress = DeviceAddress;
+ DevInfo->bHCNumber = This->hc_data->bHCNumber;
+ DevInfo->bEndpointSpeed = SpeedMap[DeviceSpeed];
+ DevInfo->bHubDeviceNumber = DevSrc->bHubDeviceNumber;
+ DevInfo->bHubPortNumber = DevSrc->bHubPortNumber;
+ DevInfo->DevMiscInfo = DevSrc->DevMiscInfo; //(EIP84790+)
+
+ if( EndpointAddress & 0x80 ){
+ XferDir = 0x80;
+ DevInfo->bBulkInEndpoint = EndpointAddress & 0xF;
+ DevInfo->wBulkInMaxPkt = (UINT16)MaximumPacketLength;
+ DevInfo->wDataInSync = (UINT16)(*DataToggle) << ToggleBit;
+ } else {
+ XferDir = 0x0;
+ DevInfo->bBulkOutEndpoint = EndpointAddress & 0xF;
+ DevInfo->wBulkOutMaxPkt = (UINT16)MaximumPacketLength;
+ DevInfo->wDataOutSync = (UINT16)(*DataToggle) << ToggleBit;
+ }
+
+ //
+ // Call SMI routine and retrieve last status
+ // if any error
+ //
+ CRITICAL_CODE( EFI_TPL_NOTIFY,
+ {
+ CurrentTimeout = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = (UINT16)Timeout;
+ gUsbData->dLastCommandStatusExtended = 0;
+ SmiRes = UsbSmiBulkTransfer(
+ This->hc_data, DevInfo,
+ XferDir,
+ (UINT8*)Data[0],
+ (UINT32)*DataLength );
+ *TransferResult = GetTransferStatus();
+ gUsbData->wTimeOutValue = CurrentTimeout;
+ });
+
+ //
+ // Update the data length
+ //
+ *DataLength = (UINTN)SmiRes;
+
+ //
+ // Update Toggle bit
+ //
+ if( XferDir ){
+ *DataToggle = (UINT8)(DevInfo->wDataInSync >> ToggleBit) & 0x1;
+ } else {
+ *DataToggle = (UINT8)(DevInfo->wDataOutSync >> ToggleBit) & 0x1;
+ }
+ FreeDevInfo(DevInfo);
+
+ if( (*TransferResult) & EFI_USB_ERR_TIMEOUT ) {
+ return EFI_TIMEOUT;
+ }
+ return (*TransferResult)? EFI_DEVICE_ERROR:EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcAsyncInterruptTransfer
+//
+// Description:
+// This function performs USB2 HC Async Interrupt Transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcAsyncInterruptTransfer(
+ IN EFI_USB2_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaxPacket,
+ IN BOOLEAN IsNewTransfer,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallbackFunction ,
+ IN VOID *Context)
+{
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ DEV_INFO* DevInfo;
+ USBHC_INTERRUPT_DEVNINFO_T* AsyncTransfer = 0;
+ UINT8 SmiStatus = USB_SUCCESS;
+ UINT8 ToggleBit = (EndpointAddress & 0xF) - 1;
+
+ if (DeviceSpeed != EFI_USB_SPEED_SUPER &&
+ DeviceSpeed != EFI_USB_SPEED_HIGH &&
+ DeviceSpeed != EFI_USB_SPEED_FULL &&
+ DeviceSpeed != EFI_USB_SPEED_LOW){
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if !EFI_USB_HC_INTERRUPT_OUT_SUPPORT
+ if (!(EndpointAddress & BIT7)) {
+ return EFI_INVALID_PARAMETER;
+ }
+#endif
+ //<(EIP81612)
+ if (IsNewTransfer){
+ DEV_INFO* DevInfoSrc = DevAddr2Info( DeviceAddress, This->hc_data );
+ DevInfo = FindOldTransfer( DeviceAddress, EndpointAddress, This->hc_data );
+
+ if (DataLength == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*DataToggle != 0 && *DataToggle != 1) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (PollingInterval < 1 || PollingInterval > 255) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if( DevInfoSrc == NULL || CallbackFunction == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if( DevInfo != NULL ){
+ USB_DEBUG(DEBUG_LEVEL_3,"Stacked AsyncInterrupt request are not supported\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ DevInfo = AllocDevInfo();
+ *DevInfo = *DevInfoSrc;
+ DevInfo->IntInEndpoint = EndpointAddress;
+ DevInfo->bEndpointSpeed = SpeedMap[DeviceSpeed];
+ DevInfo->IntInMaxPkt = (UINT16)MaxPacket; //(EIP84790+)
+ DevInfo->bPollInterval = TranslateInterval(DeviceSpeed, PollingInterval);
+ DevInfo->PollingLength = (UINT16)DataLength;
+
+ //create new transfer
+ gBS->AllocatePool (EfiBootServicesData,
+ sizeof(USBHC_INTERRUPT_DEVNINFO_T) + DataLength*INTERRUPTQUEUESIZE,
+ &AsyncTransfer );
+ EfiZeroMem(AsyncTransfer, sizeof(USBHC_INTERRUPT_DEVNINFO_T)+
+ DataLength*INTERRUPTQUEUESIZE);
+ DevInfo->pExtra = (UINT8*)AsyncTransfer;
+ AsyncTransfer->QCompleted.data = (VOID *volatile *)AsyncTransfer->Data;
+ AsyncTransfer->QCompleted.maxsize = (int)DataLength * INTERRUPTQUEUESIZE;
+ AsyncTransfer->DataLength = DataLength;
+ AsyncTransfer->EndpointAddress = EndpointAddress;
+
+ DevInfo->Flag |= DEV_INFO_DEV_DUMMY;
+ VERIFY_EFI_ERROR(
+ gBS->CreateEvent ( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK, AsyncInterruptOnTimer,
+ AsyncTransfer,&AsyncTransfer->Event));
+
+ PollingInterval = PollingInterval < 32 ? 32 : PollingInterval;
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( AsyncTransfer->Event, TimerPeriodic,
+ PollingInterval * MILLISECOND));
+ AsyncTransfer->CallbackFunction = CallbackFunction;
+ AsyncTransfer->Context = Context;
+ if(EndpointAddress & 0x80) {
+ DevInfo->wDataInSync = (UINT16)(*DataToggle) << ToggleBit;
+ } else {
+ DevInfo->wDataOutSync = (UINT16)(*DataToggle) << ToggleBit;
+ }
+
+ //
+ // Activate transfer
+ //
+ SmiStatus = UsbSmiActivatePolling(This->hc_data, DevInfo);
+ ASSERT(SmiStatus==USB_SUCCESS);
+ } else {
+ //
+ // Find old transfer
+ //
+ DevInfo = FindOldTransfer(
+ DeviceAddress,
+ EndpointAddress,
+ This->hc_data );
+ if( DevInfo == NULL || DevInfo->pExtra == NULL ){
+ USB_DEBUG(DEBUG_LEVEL_3,"Canceling bad AsyncInterrupt request\n");
+ return EFI_INVALID_PARAMETER;
+ }
+ AsyncTransfer = (USBHC_INTERRUPT_DEVNINFO_T*)DevInfo->pExtra;
+ DevInfo->pExtra = 0;
+ //
+ // Deactivate transfer
+ //
+ SmiStatus = UsbSmiDeactivatePolling (This->hc_data, DevInfo);
+ if (DataToggle){
+ if(EndpointAddress & 0x80) {
+ *DataToggle = (UINT8)(DevInfo->wDataInSync >> ToggleBit) & 0x1;
+ } else {
+ *DataToggle = (UINT8)(DevInfo->wDataOutSync >> ToggleBit) & 0x1;
+ }
+ }
+ VERIFY_EFI_ERROR(gBS->SetTimer(AsyncTransfer->Event, TimerCancel, 0));
+ VERIFY_EFI_ERROR(gBS->CloseEvent (AsyncTransfer->Event));
+ gBS->FreePool(AsyncTransfer);
+ FreeDevInfo(DevInfo);
+ }
+
+ return SmiStatus == USB_SUCCESS? EFI_SUCCESS : EFI_DEVICE_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcSyncInterruptTransfer
+//
+// Description:
+// This function performs USB2 HC Sync Interrupt Transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcSyncInterruptTransfer(
+ IN EFI_USB2_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndpointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN OUT UINT8 *DataToggle,
+ IN UINTN Timeout,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult )
+{
+ UINT16 SmiRes;
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ DEV_INFO *DevInfo;
+ DEV_INFO* DevSrc = DevAddr2Info( DeviceAddress, This->hc_data );
+ UINT16 CurrentTimeout;
+ UINT8 ToggleBit = (EndpointAddress & 0xF) - 1;
+ UINT16 *wDataSync;
+
+ if (DeviceSpeed != EFI_USB_SPEED_SUPER &&
+ DeviceSpeed != EFI_USB_SPEED_HIGH &&
+ DeviceSpeed != EFI_USB_SPEED_FULL &&
+ DeviceSpeed != EFI_USB_SPEED_LOW) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+#if !EFI_USB_HC_INTERRUPT_OUT_SUPPORT
+ if (!(EndpointAddress & BIT7)) {
+ return EFI_INVALID_PARAMETER;
+ }
+#endif
+
+ if (Data == NULL || DataLength == NULL ||
+ *DataLength == 0 || TransferResult == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( DeviceSpeed == EFI_USB_SPEED_LOW && MaximumPacketLength > 8) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DeviceSpeed == EFI_USB_SPEED_FULL && MaximumPacketLength > 64) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (DeviceSpeed == EFI_USB_SPEED_HIGH && MaximumPacketLength > 3072 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (*DataToggle != 0 && *DataToggle != 1) return EFI_INVALID_PARAMETER;
+
+ if(DevSrc == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ DevInfo = AllocDevInfo();
+ DevInfo->bDeviceAddress = DeviceAddress;
+ DevInfo->bHCNumber = This->hc_data->bHCNumber;
+ DevInfo->bEndpointSpeed = SpeedMap[DeviceSpeed];
+ DevInfo->bPollInterval = TranslateInterval(DeviceSpeed, 1);
+ DevInfo->bHubDeviceNumber = DevSrc->bHubDeviceNumber;
+ DevInfo->bHubPortNumber = DevSrc->bHubPortNumber;
+ DevInfo->DevMiscInfo = DevSrc->DevMiscInfo; //(EIP84790+)
+
+ wDataSync = EndpointAddress & 0x80 ? &DevInfo->wDataInSync :
+ &DevInfo->wDataOutSync;
+
+ *wDataSync = (UINT16)(*DataToggle) << ToggleBit;
+
+ CRITICAL_CODE( EFI_TPL_NOTIFY,
+ {
+ CurrentTimeout = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = (UINT16)Timeout;
+ gUsbData->dLastCommandStatusExtended = 0;
+ SmiRes = UsbSmiInterruptTransfer(
+ This->hc_data,
+ DevInfo,
+ EndpointAddress,
+ (UINT16)MaximumPacketLength,
+ (UINT8*)Data,
+ (UINT16)*DataLength);
+ *TransferResult = GetTransferStatus();
+ gUsbData->wTimeOutValue = CurrentTimeout;
+ });
+
+ *DataLength = (UINTN)SmiRes;
+ *DataToggle = (UINT8)(*wDataSync >> ToggleBit) & 0x1;
+
+ FreeDevInfo(DevInfo);
+ //
+ // Return with error or success
+ //
+ if ( (*TransferResult) & EFI_USB_ERR_TIMEOUT ) return EFI_TIMEOUT;
+ return (*TransferResult)? EFI_DEVICE_ERROR:EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcIsochronousTransfer
+//
+// Description:
+// This function performs USB2 HC Isochronous Transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EFIAPI
+AmiUsb2HcIsochronousTransfer(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+)
+{
+ //(EIP81612)>
+ if ( Data == NULL || Data[0] == NULL || DataLength == 0 ||
+ (DeviceSpeed != EFI_USB_SPEED_SUPER && DeviceSpeed != EFI_USB_SPEED_HIGH
+ && DeviceSpeed != EFI_USB_SPEED_FULL) ||
+ MaximumPacketLength > 1023 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //<(EIP81612)
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcAsyncIsochronousTransfer
+//
+// Description:
+// This function performs USB2 HC Async Isochronous Transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+EFIAPI
+AmiUsb2HcAsyncIsochronousTransfer(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN UINT8 DeviceAddress,
+ IN UINT8 EndPointAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
+ IN UINTN DataLength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallBack,
+ IN VOID *Context OPTIONAL
+)
+{
+ //(EIP81612)>
+ if( Data == NULL || Data[0] == NULL || DataLength == 0 ||
+ (DeviceSpeed != EFI_USB_SPEED_SUPER && DeviceSpeed != EFI_USB_SPEED_HIGH
+ && DeviceSpeed != EFI_USB_SPEED_FULL) ||
+ MaximumPacketLength > 1023 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //<EIP81612)
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcTransfer
+//
+// Description:
+// This function performs USB2 HC Control Transfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcControlTransfer(
+ IN EFI_USB2_HC_PROTOCOL *HcProtocol,
+ IN UINT8 DeviceAddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN MaximumPacketLength,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION TransferDirection,
+ IN OUT VOID *Data ,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *TransferResult
+)
+{
+ UINT16 SmiRes;
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ DEV_INFO *DevInfo;
+ DEV_INFO *DevSrc = DevAddr2Info( DeviceAddress, This->hc_data );
+ UINT16 CurrentTimeout;
+ EFI_STATUS Status;
+
+ //(EIP81612)>
+ if ( (DeviceSpeed != EFI_USB_SPEED_SUPER && DeviceSpeed != EFI_USB_SPEED_HIGH
+ && DeviceSpeed != EFI_USB_SPEED_FULL && DeviceSpeed != EFI_USB_SPEED_LOW)
+ || DevSrc == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //<(EIP81612)
+ if ( TransferDirection < EfiUsbDataIn || TransferDirection > EfiUsbNoData ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( TransferDirection == EfiUsbNoData && (Data != NULL || *DataLength != 0) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( TransferDirection != EfiUsbNoData && (Data == NULL || *DataLength == 0) ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if( Request == NULL || TransferResult == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( DeviceSpeed == EFI_USB_SPEED_LOW && MaximumPacketLength != 8 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((DeviceSpeed == EFI_USB_SPEED_HIGH || DeviceSpeed == EFI_USB_SPEED_FULL) &&
+ ( MaximumPacketLength != 8 &&
+ MaximumPacketLength != 16 &&
+ MaximumPacketLength != 32 &&
+ MaximumPacketLength != 64 )
+ ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //(EIP81612+)>
+ if ( DeviceSpeed == EFI_USB_SPEED_SUPER && MaximumPacketLength != 512 ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ //<(EIP81612+)
+
+ DevInfo = AllocDevInfo();
+ DevInfo->bDeviceAddress = DeviceAddress;
+ DevInfo->bHCNumber = This->hc_data->bHCNumber;
+ DevInfo->bEndpointSpeed = SpeedMap[DeviceSpeed];
+ DevInfo->wEndp0MaxPacket = (UINT16)MaximumPacketLength;
+ DevInfo->bHubDeviceNumber = DevSrc->bHubDeviceNumber;
+ DevInfo->bHubDeviceNumber = DevSrc->bHubDeviceNumber;
+ DevInfo->bHubPortNumber = DevSrc->bHubPortNumber;
+ DevInfo->DevMiscInfo = DevSrc->DevMiscInfo; //(EIP84790+)
+
+ CRITICAL_CODE( EFI_TPL_NOTIFY,
+ {
+ CurrentTimeout = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = (UINT16)Timeout;
+ gUsbData->dLastCommandStatusExtended = 0;
+ SmiRes = UsbSmiControlTransfer(This->hc_data, DevInfo,
+ (UINT16)((( TransferDirection == EfiUsbDataIn?1:0) << 7) |
+ (((UINT16)Request->RequestType)) |
+ (((UINT16)Request->Request)<<8)),
+ (UINT16)Request->Index, (UINT16)Request->Value,
+ (UINT8*)Data, (UINT16)Request->Length);
+ *TransferResult = GetTransferStatus();
+ gUsbData->wTimeOutValue = CurrentTimeout;
+ });
+
+ Status = EFI_SUCCESS;
+/*
+ if (TransferDirection == EfiUsbDataIn
+ && *DataLength != 0
+ && SmiRes == 0)
+ {
+ //
+ // Some data is expected, no data is returned
+ //
+ Status = EFI_DEVICE_ERROR;
+ }
+*/
+ if( (*TransferResult) & EFI_USB_ERR_TIMEOUT ) Status = EFI_TIMEOUT;
+ if( (*TransferResult) & ~EFI_USB_ERR_TIMEOUT ) Status = EFI_DEVICE_ERROR;
+
+ *DataLength = (UINTN)SmiRes;
+
+ FreeDevInfo(DevInfo);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcGetRootHubPortStatus
+//
+// Description:
+// This function returns HC root port status.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcGetRootHubPortStatus (
+ EFI_USB2_HC_PROTOCOL *HcProtocol,
+ UINT8 PortNumber,
+ EFI_USB_PORT_STATUS *PortStatus
+)
+{
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ return AmiUsbHcGetRootHubPortStatus(
+ &This->hcprotocol, PortNumber, PortStatus);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcSetRootHubPortFeature
+//
+// Description:
+// This function set root hub port features.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcSetRootHubPortFeature(
+ IN EFI_USB2_HC_PROTOCOL *HcProtocol,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+)
+{
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ return AmiUsbHcSetRootHubPortFeature(
+ &This->hcprotocol, PortNumber, PortFeature);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsb2HcClearRootHubPortFeature
+//
+// Description:
+// This function clears root hub port feature.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+AmiUsb2HcClearRootHubPortFeature(
+ IN EFI_USB2_HC_PROTOCOL *HcProtocol,
+ IN UINT8 PortNumber,
+ IN EFI_USB_PORT_FEATURE PortFeature
+)
+{
+ HC_DXE_RECORD *This = GetThis( HcProtocol );
+ return AmiUsbHcClearRootHubPortFeature(
+ &This->hcprotocol, PortNumber, PortFeature);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FindHcStruc
+//
+// Description:
+// Search gUsbData for information about HC linked to an EFI handle
+//
+// Input:
+// Controller - Host Controller handle
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+HC_STRUC* FindHcStruc(
+ EFI_HANDLE Controller
+)
+{
+ unsigned i;
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ if (gUsbData->HcTable[i] == NULL) {
+ continue;
+ }
+ if (!(gUsbData->HcTable[i]->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+ if (gUsbData->HcTable[i]->Controller == Controller )
+ return gUsbData->HcTable[i];
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbHcSupported
+//
+// Description:
+// This function is a part of Driver Binding Protocol interface.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UsbHcSupported (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ EFI_STATUS Status;
+ VOID* Ptr;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ &Ptr,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller, &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+ if (FindHcStruc(Controller) == NULL) {
+ return EFI_UNSUPPORTED;
+ } else
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbHcStop
+//
+// Description:
+// This function is a part of Driver Binding Protocol interface.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS EFIAPI
+UsbHcStop (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children )
+{
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallHcProtocols
+//
+// Description:
+// Start the AMI USB driver; Sets USB_FLAG_DRIVER_STARTED
+//
+// Input:
+// This - Protocol instance pointer.
+// ControllerHandle - Handle of device to test
+// RemainingDevicePath - Not used
+//
+// Output:
+// EFI_SUCCESS - USB HC devices were initialized.
+// EFI_UNSUPPORTED - pThis device is not supported by USB driver.
+// EFI_DEVICE_ERROR - pThis driver cannot be started due to device error
+// EFI_OUT_OF_RESOURCES
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallHcProtocols(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN HC_STRUC *HcData
+)
+{
+ HC_DXE_RECORD *Rec;
+ USB3_HOST_CONTROLLER *Usb3Hc;
+
+ //
+ // Create HcDxeRecord
+ //
+ VERIFY_EFI_ERROR(
+ gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(HC_DXE_RECORD),
+ &Rec ));
+ Rec->hc_data = HcData;
+ Rec->pciIo = PciIo;
+ Rec->AsyncTransfers.pHead = NULL;
+ Rec->AsyncTransfers.pTail = NULL;
+ Rec->AsyncTransfers.Size = 0;
+
+ Rec->hcprotocol.Reset = AmiUsbHcReset;
+ Rec->hcprotocol.GetState = AmiUsbHcGetState;
+ Rec->hcprotocol.SetState = AmiUsbHcSetState;
+ Rec->hcprotocol.ControlTransfer = AmiUsbHcControlTransfer;
+ Rec->hcprotocol.BulkTransfer = AmiUsbHcBulkTransfer;
+ Rec->hcprotocol.AsyncInterruptTransfer = AmiUsbHcAsyncInterruptTransfer;
+ Rec->hcprotocol.SyncInterruptTransfer = AmiUsbHcSyncInterruptTransfer;
+ Rec->hcprotocol.IsochronousTransfer = AmiUsbHcIsochronousTransfer;
+ Rec->hcprotocol.AsyncIsochronousTransfer = AmiUsbHcAsyncIsochronousTransfer;
+ Rec->hcprotocol.GetRootHubPortNumber = AmiUsbHcGetRootHubPortNumber;
+ Rec->hcprotocol.GetRootHubPortStatus = AmiUsbHcGetRootHubPortStatus;
+ Rec->hcprotocol.SetRootHubPortFeature = AmiUsbHcSetRootHubPortFeature;
+ Rec->hcprotocol.ClearRootHubPortFeature = AmiUsbHcClearRootHubPortFeature;
+
+ //
+ // Fill USB Revision fields based on type of HC
+ //
+ // USB_HC_UHCI USB_HC_OHCI -> 1.1
+ // USB_HC_EHCI -> 2.0
+ // USB_HC_XHCI 0.96, 1.0 -> 3.0
+ // USB_HC_XHCI 1.1 -> 3.1
+
+ switch (HcData->bHCType) {
+ case USB_HC_UHCI:
+ case USB_HC_OHCI:
+ Rec->hcprotocol.MajorRevision = 1;
+ Rec->hcprotocol.MinorRevision = 1;
+ break;
+ case USB_HC_EHCI:
+ Rec->hcprotocol.MajorRevision = 2;
+ Rec->hcprotocol.MinorRevision = 0;
+ break;
+ case USB_HC_XHCI:
+ Rec->hcprotocol.MajorRevision = 3;
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcData->usbbus_data;
+ if (Usb3Hc->HciVersion <= 0x0100) {
+ Rec->hcprotocol.MinorRevision = 0;
+ } else {
+ Rec->hcprotocol.MinorRevision = 1;
+ }
+ break;
+ default:
+ break;
+ }
+
+ Rec->hcprotocol2.GetCapability = AmiUsb2HcGetCapability;
+ Rec->hcprotocol2.Reset = AmiUsb2HcReset;
+ Rec->hcprotocol2.GetState = AmiUsb2HcGetState;
+ Rec->hcprotocol2.SetState = AmiUsb2HcSetState;
+ Rec->hcprotocol2.ControlTransfer = AmiUsb2HcControlTransfer;
+ Rec->hcprotocol2.BulkTransfer = AmiUsb2HcBulkTransfer;
+ Rec->hcprotocol2.AsyncInterruptTransfer = AmiUsb2HcAsyncInterruptTransfer;
+ Rec->hcprotocol2.SyncInterruptTransfer = AmiUsb2HcSyncInterruptTransfer;
+ Rec->hcprotocol2.IsochronousTransfer = AmiUsb2HcIsochronousTransfer;
+ Rec->hcprotocol2.AsyncIsochronousTransfer = AmiUsb2HcAsyncIsochronousTransfer;
+ Rec->hcprotocol2.GetRootHubPortStatus = AmiUsb2HcGetRootHubPortStatus;
+ Rec->hcprotocol2.SetRootHubPortFeature = AmiUsb2HcSetRootHubPortFeature;
+ Rec->hcprotocol2.ClearRootHubPortFeature = AmiUsb2HcClearRootHubPortFeature;
+ Rec->hcprotocol2.MajorRevision = Rec->hcprotocol.MajorRevision;
+ Rec->hcprotocol2.MinorRevision = Rec->hcprotocol.MinorRevision;
+
+
+ //
+ // Instal USB_HC_PROTOCOL
+ //
+ VERIFY_EFI_ERROR(
+ gBS->InstallProtocolInterface( &Controller,
+ &gEfiUsbHcProtocolGuid, EFI_NATIVE_INTERFACE, &Rec->hcprotocol ));
+ VERIFY_EFI_ERROR(
+ gBS->InstallProtocolInterface( &Controller,
+ &gEfiUsb2HcProtocolGuid, EFI_NATIVE_INTERFACE, &Rec->hcprotocol2 ));
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciAllocateScratchpadBuffers
+//
+// Description:
+// This function allocates XHCI scratchpad buffers. Data initialization will
+// be done later, in SMI XhciStart function.
+//
+// Notes:
+// Usb3Hc->DcbaaPtr points to the beginning of memory block first 2048 Bytes
+// of which is used for DCBAA.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciAllocateScratchpadBuffers (
+ IN USB3_HOST_CONTROLLER *Usb3Hc
+)
+{
+ UINT16 NumBufs = ((Usb3Hc->CapRegs->HcsParams2.MaxScratchPadBufsHi) << 5) +
+ Usb3Hc->CapRegs->HcsParams2.MaxScratchPadBufsLo;
+ UINT16 Count;
+ VOID *Buffer;
+
+ if (NumBufs == 0) {
+ return EFI_SUCCESS;
+ }
+
+ if (Usb3Hc->ScratchBufEntry == NULL) {
+ // Allcate a PAGESIZE boundary for Scratchpad Buffer Array Base Address
+ // because bit[0..5] are reserved in Device Context Base Address Array Element 0.
+ Usb3Hc->ScratchBufEntry = AllocateHcMemory(Usb3Hc->PciIo,
+ EFI_SIZE_TO_PAGES((sizeof(UINT64) * NumBufs)), 0x1000);
+
+ if (Usb3Hc->ScratchBufEntry == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ gBS->SetMem(Usb3Hc->ScratchBufEntry, (sizeof(UINT64) * NumBufs), 0);
+
+ for (Count = 0; Count < NumBufs; Count++) {
+
+ // Allocate scratchpad buffer: PAGESIZE block located on
+ // a PAGESIZE boundary. Section 4.20.
+ Buffer = AllocateHcMemory(Usb3Hc->PciIo,
+ Usb3Hc->PageSize4K, Usb3Hc->PageSize4K << 12);
+ ASSERT(Buffer != NULL); // See if allocation is successful
+
+ if (Buffer == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Update *ScratchBufArrayBase
+ Usb3Hc->ScratchBufEntry[Count] = (UINTN)Buffer;
+ }
+ }
+
+ // Update scratchpad pointer only if # of scratch buffers >0
+ if (NumBufs > 0) {
+ *(UINTN*)Usb3Hc->DcbaaPtr = (UINTN)Usb3Hc->ScratchBufEntry;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciInitMemory
+//
+// Description:
+// This function allocates XHCI memory buffers. Data initialization will be
+// done later, in SMI XhciStart function. These are the memory blocks:
+//
+// 1. DCBAAP + ScrPadBuf pointers + InpCtx + ERST <-- 8KB
+// 2. CommandRing <-- 1KB
+// 3. EventRing <-- 1KB
+// 4. XferRings <-- 1KB*MaxSlots, 1KB = 32EP per slot times 32 (padded size of TRB_RING)
+// 4. N*sizeof(XHCI_DEVICE_CONTEXT) for device context segment <-- N KB or 2*N KB,
+// N is SlotNumber from CONFIG register
+//
+// 5. TransferRings <-- MaxSlots*32*1KB
+//
+// Notes:
+// Scratchpad buffers are optional, they are allocated and initialized separately.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciInitMemory (
+ IN USB3_HOST_CONTROLLER *Usb3Hc
+)
+{
+ EFI_STATUS Status;
+ UINTN MemSize;
+ UINTN DeviceContextSize;
+ UINTN XfrRingsSize;
+ UINTN XfrTrbsSize;
+
+ XfrRingsSize = Usb3Hc->MaxSlots * 32 * 32; // 32 endpoints per device, 32 padded size of TRB_RING
+ XfrTrbsSize = RING_SIZE*Usb3Hc->MaxSlots*32;
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->MaxSlots;
+
+ MemSize = 0x2800 + XfrRingsSize + XfrTrbsSize + DeviceContextSize;
+ if (Usb3Hc->DcbaaPtr == NULL) {
+ Usb3Hc->DcbaaPtr = (XHCI_DCBAA*)AllocateHcMemory(Usb3Hc->PciIo,
+ EFI_SIZE_TO_PAGES(MemSize), 0x1000);
+ }
+ gBS->SetMem(Usb3Hc->DcbaaPtr, MemSize, 0); // Clear buffer
+
+ USB_DEBUG(3, "XHCI: Memory allocation - total %x Bytes:\n 0x2800+XfrRings(%x)+XfrTrbs(%x)+DevCtx(%x)\n",
+ MemSize, XfrRingsSize, XfrTrbsSize, DeviceContextSize);
+
+ // Assign DCBAA (Device Context Base Address); program the
+ // DCBAA Pointer (DCBAAP) register (5.4.6) with a 64-bit address
+ // pointing to where the Device Context Base Address Array is located.
+ //
+ // DCBAA: size 2048 Bytes, within PAGESIZE, 64 Bytes aligned.
+ //
+ // These requirements can be met by allocating 1 page using
+ // pBS->AllocatePages; the address will be 4K aligned and will
+ // not span PAGESIZE boundary.
+
+ Status = XhciAllocateScratchpadBuffers(Usb3Hc);
+ ASSERT_EFI_ERROR(Status);
+
+ // Assign Input Context; the size of Input Context is either
+ // 0x420 or 0x840 depending on HCPARAMS.Csz
+ if (Usb3Hc->InputContext == NULL) {
+ Usb3Hc->InputContext = (VOID*)((UINTN)Usb3Hc->DcbaaPtr + 0x940);
+ }
+
+ // Initialize Transfer Rings pointer and store it in Usb3Hc; actual
+ // xfer ring initialization happens later, when the EP is being enabled
+ if (Usb3Hc->XfrRings == NULL) {
+ Usb3Hc->XfrRings = (TRB_RING*)((UINTN)Usb3Hc->DcbaaPtr + 0x2800);
+ }
+
+ // 1024 = 32 bytes is padded sizeof(TRB_RING) times 32 EP per device
+ if (Usb3Hc->XfrTrbs == NULL) {
+ Usb3Hc->XfrTrbs = (UINTN)Usb3Hc->XfrRings + XfrRingsSize;
+ }
+
+ // Assign device context memory: Usb3Hc->MaxSlots devices,
+ // 1024 (2048 if HCPARAMS.Csz is set) Bytes each
+ if (Usb3Hc->DeviceContext == NULL) {
+ Usb3Hc->DeviceContext = (VOID*)((UINTN)Usb3Hc->XfrTrbs + XfrTrbsSize);
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciExtCapParser
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciExtCapParser(
+ IN USB3_HOST_CONTROLLER *Usb3Hc
+)
+{
+ XHCI_EXT_CAP *CurPtr;
+
+ if (Usb3Hc->CapRegs->HccParams1.Xecp == 0) return EFI_SUCCESS;
+
+ // Starts from first capability
+ CurPtr = (XHCI_EXT_CAP *)((UINTN)Usb3Hc->CapRegs + (Usb3Hc->CapRegs->HccParams1.Xecp << 2));
+
+ // Traverse all capability structures
+ for(;;) {
+ switch (CurPtr->CapId) {
+ case XHCI_EXT_CAP_USB_LEGACY:
+ Usb3Hc->ExtLegCap = (XHCI_EXT_LEG_CAP *)CurPtr;
+ // Clear HC BIOS Owned Semaphore bit
+ Usb3Hc->ExtLegCap->LegSup.HcBiosOwned = 0;
+ // Clear HC OS Owned Semaphore bit
+ Usb3Hc->ExtLegCap->LegSup.HcOsOwned = 0;
+ // Clear SMI enable bit
+ Usb3Hc->ExtLegCap->LegCtlSts.UsbSmiEnable = 0;
+ Usb3Hc->ExtLegCap->LegCtlSts.UsbOwnershipChangeSmiEnable = 0;
+ USB_DEBUG(3, "XHCI: USB Legacy Ext Cap Ptr %x\n", Usb3Hc->ExtLegCap);
+ break;
+
+ case XHCI_EXT_CAP_SUPPORTED_PROTOCOL:
+ if (((XHCI_EXT_PROTOCOL*)CurPtr)->MajorRev == 0x02) {
+ Usb3Hc->Usb2Protocol = (XHCI_EXT_PROTOCOL*)CurPtr;
+ USB_DEBUG(3, "XHCI: USB2 Support Protocol %x, PortOffset %x PortCount %x\n",
+ Usb3Hc->Usb2Protocol, Usb3Hc->Usb2Protocol->PortOffset, Usb3Hc->Usb2Protocol->PortCount);
+ } else if (((XHCI_EXT_PROTOCOL*)CurPtr)->MajorRev == 0x03) {
+ Usb3Hc->Usb3Protocol = (XHCI_EXT_PROTOCOL*)CurPtr;
+ USB_DEBUG(3, "XHCI: USB3 Support Protocol %x, PortOffset %x PortCount %x\n",
+ Usb3Hc->Usb3Protocol, Usb3Hc->Usb3Protocol->PortOffset, Usb3Hc->Usb3Protocol->PortCount);
+ }
+ break;
+
+ case XHCI_EXT_CAP_POWERMANAGEMENT:
+ case XHCI_EXT_CAP_IO_VIRTUALIZATION:
+ break;
+ case XHCI_EXT_CAP_USB_DEBUG_PORT:
+ Usb3Hc->DbCapRegs = (XHCI_DB_CAP_REGS*)CurPtr;
+ USB_DEBUG(3, "XHCI: USB Debug Capability Ptr %x\n", Usb3Hc->DbCapRegs);
+ break;
+ }
+ if(CurPtr->NextCapPtr == 0) break;
+ // Point to next capability
+ CurPtr=(XHCI_EXT_CAP *)((UINTN)CurPtr+ (((UINTN)CurPtr->NextCapPtr) << 2));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PreInitXhci
+//
+// Description:
+// This function initializes XHCI data structures, allocates HC memory and
+// updates the relevant fields in HcStruc. At this point the controller's
+// resources are assigned and accessible.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PreInitXhci(
+ EFI_HANDLE Handle,
+ HC_STRUC *HcStruc
+)
+{
+#if XHCI_SUPPORT
+ UINT8 MaxSlots;
+ EFI_STATUS Status;
+ USB3_HOST_CONTROLLER *Usb3Hc = NULL;
+
+ if (HcStruc->usbbus_data == NULL) {
+ Status = gBS->AllocatePool(EfiRuntimeServicesData,
+ sizeof(USB3_HOST_CONTROLLER), &Usb3Hc);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ gBS->SetMem(Usb3Hc, sizeof(USB3_HOST_CONTROLLER), 0);
+ } else {
+ Usb3Hc = HcStruc->usbbus_data;
+ }
+
+ Usb3Hc->Controller = Handle;
+ Status = gBS->HandleProtocol(Handle, &gEfiPciIoProtocolGuid, &Usb3Hc->PciIo);
+ ASSERT_EFI_ERROR(Status);
+
+ // Get Capability Registers offset off the BAR
+ //(EIP101226)>
+ Status = Usb3Hc->PciIo->Pci.Read(Usb3Hc->PciIo,
+ EfiPciIoWidthUint32, PCI_BAR0, 1, &Usb3Hc->CapRegs);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if (((UINT8)(UINTN)Usb3Hc->CapRegs & (BIT1 |BIT2)) == BIT2) {
+ Status = Usb3Hc->PciIo->Pci.Read(Usb3Hc->PciIo,
+ EfiPciIoWidthUint32, PCI_BAR0, sizeof(VOID*)/sizeof(UINT32), &Usb3Hc->CapRegs);
+ }
+
+ //<(EIP101226)
+ //clear all attributes before use
+ (UINT8)(UINTN)Usb3Hc->CapRegs &= ~(0x7F); // Clear attributes
+
+ Usb3Hc->PciIo->Pci.Read(Usb3Hc->PciIo,
+ EfiPciIoWidthUint16, PCI_VID, 1, &Usb3Hc->Vid);
+
+ Usb3Hc->PciIo->Pci.Read(Usb3Hc->PciIo,
+ EfiPciIoWidthUint16, PCI_DID, 1, &Usb3Hc->Did);
+
+ Usb3Hc->Access64 = Usb3Hc->CapRegs->HccParams1.Ac64;
+
+ Usb3Hc->HciVersion = Usb3Hc->CapRegs->HciVersion;
+ Usb3Hc->MaxPorts = Usb3Hc->CapRegs->HcsParams1.MaxPorts;
+
+ Usb3Hc->OpRegs = (XHCI_HC_OP_REGS*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->CapRegs->CapLength);
+ Usb3Hc->PageSize4K = Usb3Hc->OpRegs->PageSize;
+ Usb3Hc->ContextSize = 0x20 << Usb3Hc->CapRegs->HccParams1.Csz;
+
+ USB_DEBUG(3, "XHCI: Cap %x, OpRegs: %x Ver %x,\n MaxPorts 0x%x, PageSize %x*4K\n",
+ Usb3Hc->CapRegs, Usb3Hc->OpRegs, Usb3Hc->HciVersion, Usb3Hc->MaxPorts, Usb3Hc->PageSize4K);
+
+ ASSERT(Usb3Hc->PageSize4K < 0x8000); // Maximum possible page size is 128MB
+
+ Status = Usb3Hc->PciIo->Pci.Read(
+ Usb3Hc->PciIo, EfiPciIoWidthUint8, XHCI_PCI_SBRN, 1, &Usb3Hc->SBRN);
+ ASSERT_EFI_ERROR(Status);
+ USB_DEBUG(3, "XHCI: Serial Bus Release Number is %x\n", Usb3Hc->SBRN);
+
+ // OEM might change the default number of MaxSlots
+ Status = Usb3OemGetMaxDeviceSlots(&MaxSlots);
+
+ if (EFI_ERROR(Status)) {
+ // Use default number of slots
+ MaxSlots = Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+ }
+ else {
+ // Validate the porting function output
+ ASSERT(MaxSlots > 0 && MaxSlots <= Usb3Hc->CapRegs->HcsParams1.MaxSlots);
+ }
+ Usb3Hc->MaxSlots = MaxSlots;
+
+ // Get maximum number of interrupters
+ Usb3Hc->MaxIntrs = Usb3Hc->CapRegs->HcsParams1.MaxIntrs;
+
+ Usb3Hc->DbOffset = Usb3Hc->CapRegs->DbOff;
+
+ USB_DEBUG(3, "XHCI: MaxSlots %x, MaxIntrs %x, Doorbell Offset %x\n", Usb3Hc->MaxSlots, Usb3Hc->MaxIntrs, Usb3Hc->DbOffset);
+
+ // Parse all capability structures
+ XhciExtCapParser(Usb3Hc);
+
+ if (gUsbData->UsbXhciSupport == 0) {
+ gBS->FreePool(Usb3Hc);
+ return EFI_UNSUPPORTED;
+ }
+
+ // Allocate and initialize memory blocks
+ Status = XhciInitMemory(Usb3Hc);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ gBS->FreePool(Usb3Hc);
+ return Status;
+ }
+
+ HcStruc->usbbus_data = (VOID*)Usb3Hc;
+
+#endif
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PostStopXhci
+//
+// Description:
+// This function frees the HC memory and clears XHCI data structures.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+PostStopXhci(
+ EFI_HANDLE Handle,
+ HC_STRUC *HcStruc
+)
+{
+#if XHCI_SUPPORT
+/*
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+ UINT16 NumBufs = ((Usb3Hc->CapRegs->HcsParams2.MaxScratchPadBufsHi) << 5) +
+ Usb3Hc->CapRegs->HcsParams2.MaxScratchPadBufsLo;
+ UINT16 Count;
+ UINTN MemSize;
+ UINTN DeviceContextSize;
+ UINTN XfrRingsSize;
+ UINTN XfrTrbsSize;
+
+ for (Count = 0; Count < NumBufs; Count++) {
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)(Usb3Hc->ScratchBufEntry[Count]), Usb3Hc->PageSize4K);
+ }
+
+ XfrRingsSize = Usb3Hc->MaxSlots * 32 * 32; // 32 endpoints per device, 32 padded size of TRB_RING
+ XfrTrbsSize = RING_SIZE * Usb3Hc->MaxSlots * 32;
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->MaxSlots;
+
+ MemSize = 0x2800 + XfrRingsSize + XfrTrbsSize + DeviceContextSize;
+
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)Usb3Hc->DcbaaPtr, EFI_SIZE_TO_PAGES(MemSize));
+ if (Usb3Hc->ScratchBufEntry) {
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)Usb3Hc->ScratchBufEntry, EFI_SIZE_TO_PAGES((sizeof(UINT64) * NumBufs)));
+ }
+ gBS->FreePool(Usb3Hc);
+*/
+#endif
+ return EFI_SUCCESS;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/componentname.c b/Core/EM/usb/componentname.c
new file mode 100644
index 0000000..f9e1599
--- /dev/null
+++ b/Core/EM/usb/componentname.c
@@ -0,0 +1,331 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/componentname.c 12 1/11/13 4:19a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 1/11/13 4:19a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/componentname.c $
+//
+// 12 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 11 10/24/11 8:22a Wilsonlee
+// [TAG] EIP69250
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB driver doesn't pass SCT 2.3 ComponentName2 protocol.
+// [RootCause] There is no checking if passed controller handle is NULL
+// in AMIUSBComponentNameGetControllerName function.
+// [Solution] Check controller handle is NULL in
+// AMIUSBComponentNameGetControllerName function.
+// [Files] componentname.c efiusbccid.c efiusbhid.c
+//
+// 10 5/03/11 10:48a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 9 3/04/11 1:31p Olegi
+//
+// 8 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 7 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 6 3/20/07 1:29p Olegi
+//
+// 4 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 3 5/19/05 8:06p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ComponentName.c
+//
+// Description: AMI USB Component Name definitions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "Efi.h"
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "componentname.h"
+#include <Protocol\ComponentName.h>
+
+ //(EIP59272)>
+#ifndef EFI_COMPONENT_NAME2_PROTOCOL_GUID //old Core
+#ifndef LANGUAGE_CODE_ENGLISH
+#define LANGUAGE_CODE_ENGLISH "eng"
+#endif
+static BOOLEAN LanguageCodesEqual(
+ CONST CHAR8* LangCode1, CONST CHAR8* LangCode2
+){
+ return LangCode1[0]==LangCode2[0]
+ && LangCode1[1]==LangCode2[1]
+ && LangCode1[2]==LangCode2[2];
+}
+EFI_GUID gEfiComponentName2ProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+#endif
+
+static NAME_SERVICE_T cn_template = {
+ AMIUSBComponentNameGetDriverName,
+ AMIUSBComponentNameGetControllerName,
+ LANGUAGE_CODE_ENGLISH
+};
+ //<(EIP59272)
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitNamesStatic
+//
+// Description: USB device and controller names initializer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_COMPONENT_NAME_PROTOCOL*
+InitNamesStatic(
+ NAME_SERVICE_T* NameService,
+ CHAR16* Driver,
+ CHAR16* Component
+)
+{
+ *NameService = cn_template;
+ NameService->driver_name = Driver;
+ NameService->component_static = Component;
+ NameService->component_cb = 0;
+ return &NameService->icn;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitNamesProtocol
+//
+// Description: Component names protocol initializer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_COMPONENT_NAME_PROTOCOL*
+InitNamesProtocol(
+ NAME_SERVICE_T* NameService,
+ CHAR16* Driver,
+ COMPONENT_CB_T ComponentCb
+)
+{
+ *NameService = cn_template;
+ NameService->driver_name = Driver;
+ NameService->component_static = 0;
+ NameService->component_cb = ComponentCb;
+ return &NameService->icn;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AMIUSBComponentNameGetDriverName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// Input:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// Output:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AMIUSBComponentNameGetDriverName (
+ EFI_COMPONENT_NAME_PROTOCOL *ComponentNameProtocol,
+ CHAR8 *Language,
+ CHAR16 **DriverName
+ )
+{
+
+ NAME_SERVICE_T* This = (NAME_SERVICE_T*)ComponentNameProtocol;
+ //(EIP59272)>
+ if(!Language || !DriverName) {
+ return EFI_INVALID_PARAMETER;
+ }
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) {
+ return EFI_UNSUPPORTED;
+ }
+ //<(EIP59272)
+ *DriverName = This->driver_name;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AMIUSBComponentNameGetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Input:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// Output:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AMIUSBComponentNameGetControllerName (
+ EFI_COMPONENT_NAME_PROTOCOL *ComponentNameProtocol,
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child,
+ CHAR8 *Language,
+ CHAR16 **ControllerName
+ )
+{
+ NAME_SERVICE_T* This = (NAME_SERVICE_T*)ComponentNameProtocol;
+ //(EIP59272)>
+ if(!Language || !ControllerName || !Controller) { //(EIP69250)
+ return EFI_INVALID_PARAMETER;
+ }
+ if ( !LanguageCodesEqual( Language, LANGUAGE_CODE_ENGLISH) ) {
+ return EFI_UNSUPPORTED;
+ }
+ //<(EIP59272)
+ if( This->component_cb != 0){
+ CHAR16 *Str = This->component_cb(Controller, Child);
+ if(Str==0) return EFI_UNSUPPORTED;
+ *ControllerName = Str;
+ } else {
+ if (Child != NULL) {
+ return EFI_UNSUPPORTED;
+ }
+ *ControllerName = This->component_static;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/componentname.h b/Core/EM/usb/componentname.h
new file mode 100644
index 0000000..a417828
--- /dev/null
+++ b/Core/EM/usb/componentname.h
@@ -0,0 +1,117 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/componentname.h 9 5/03/11 10:49a Ryanchou $
+//
+// $Revision: 9 $
+//
+// $Date: 5/03/11 10:49a $
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/componentname.h $
+//
+// 9 5/03/11 10:49a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 8 3/04/11 1:31p Olegi
+//
+// 7 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 6 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ComponentName.h
+//
+// Description: AMI USB driver component name header file
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __COMPONENTNAME_H__
+#define __COMPONENTNAME_H__
+
+//#include <Protocol\ComponentName.h>
+typedef CHAR16* (*COMPONENT_CB_T)(EFI_HANDLE controller,EFI_HANDLE child);
+
+typedef struct {
+ EFI_COMPONENT_NAME_PROTOCOL icn;
+ CHAR16 *driver_name;
+ CHAR16 *component_static;
+ COMPONENT_CB_T component_cb;
+} NAME_SERVICE_T;
+ //(EIP59272)>
+EFI_COMPONENT_NAME_PROTOCOL*
+InitNamesStatic( NAME_SERVICE_T* n , CHAR16* driver, CHAR16* component );
+
+EFI_COMPONENT_NAME_PROTOCOL*
+InitNamesProtocol( NAME_SERVICE_T* n , CHAR16* driver, COMPONENT_CB_T component_cb);
+
+//
+// EFI Component Name Functions
+//
+EFI_STATUS
+AMIUSBComponentNameGetDriverName (
+ EFI_COMPONENT_NAME_PROTOCOL *This,
+ CHAR8 *Language,
+ CHAR16 **DriverName
+ );
+
+EFI_STATUS
+AMIUSBComponentNameGetControllerName (
+ EFI_COMPONENT_NAME_PROTOCOL *This,
+ EFI_HANDLE ControllerHandle,
+ EFI_HANDLE ChildHandle OPTIONAL,
+ CHAR8 *Language,
+ CHAR16 **ControllerName
+ );
+ //<(EIP59272)
+#endif //__COMPONENTNAME_H__
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbccid.c b/Core/EM/usb/efiusbccid.c
new file mode 100644
index 0000000..d80c705
--- /dev/null
+++ b/Core/EM/usb/efiusbccid.c
@@ -0,0 +1,1285 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbccid.c 9 10/16/16 10:18p Wilsonlee $
+//
+// $Revision: 9 $
+//
+// $Date: 10/16/16 10:18p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbccid.c $
+//
+// 9 10/16/16 10:18p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 8 7/07/16 1:12a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 7 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 6 1/23/13 4:39a Wilsonlee
+// [TAG] EIP109538
+// [Category] Improvement
+// [Description] Fix the code check error result.
+// [Files] usbkbd.c, usbCCID.c, usbbus.c, efiusbccid.c
+//
+// 5 8/29/12 8:35a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 4 5/02/12 2:01a Rajeshms
+// [TAG] EIP83117
+// [Category] Improvement
+// [Description] Extend the Support to different smart card Readers and
+// smart Cards.
+// [Files] usbCCID.c, amiusbrtCCID.h, usbdef.h, efiusbccid.c,
+// AmiusbCCID.h
+//
+// 3 10/24/11 8:30a Wilsonlee
+// [TAG] EIP69250
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB driver doesn't pass SCT 2.3 ComponentName2 protocol.
+// [RootCause] There is no checking if passed controller handle is NULL
+// in AMIUSBComponentNameGetControllerName function.
+// [Solution] Check controller handle is NULL in
+// AMIUSBComponentNameGetControllerName function.
+// [Files] componentname.c efiusbccid.c efiusbhid.c
+//
+// 2 10/14/11 4:56a Rajeshms
+// [TAG] EIP70315
+// [Category] Improvement
+// [Description] Removed Slot number in the USB CCID API's
+// [Files] efiusbccid.c, AmiUsbCCID.h
+//
+// 1 7/12/11 8:14a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+//****************************************************************************
+
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiUsbccid.c
+//
+// Description: USB CCID EFI driver implementation
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "componentname.h"
+#include "usbbus.h"
+#include "amidxelib.h"
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+EFI_STATUS
+SupportedUSBCCID(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+EFI_STATUS
+StartUSBCCID(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+EFI_STATUS
+StopUSBCCID(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+);
+
+EFI_STATUS
+GetReturnValue(
+ UINT8 bRetValue
+);
+
+ICC_DEVICE*
+GetICCDevice(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+);
+
+EFI_STATUS
+USBCCIDAPISmartClassDescriptor (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *ResponseBuffer
+);
+
+EFI_STATUS
+USBCCIDAPIGetAtr (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ UINT8 Slot,
+ UINT8 *ATRData
+);
+
+EFI_STATUS
+USBCCIDAPIPowerupSlot (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ OUT UINT8 *ATRData
+);
+
+EFI_STATUS
+USBCCIDAPIPowerDownSlot (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError
+);
+
+EFI_STATUS
+USBCCIDAPIGetSlotStatus (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ OUT UINT8 *bClockStatus
+
+);
+
+EFI_STATUS
+USBCCIDAPIXfrBlock (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ IN UINTN CmdLength,
+ IN UINT8 *CmdBuffer,
+ IN UINT8 ISBlock,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ IN OUT UINTN *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+);
+
+EFI_STATUS
+USBCCIDAPIGetParameters (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ IN OUT UINTN *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+);
+
+EFI_GUID gAmiCCIDIoProtocolGuid = AMI_CCID_IO_PROTOCOL_GUID;
+EFI_GUID gAmiCCIDPresenceGuid = AMI_CCID_PRESENCE_GUID;
+
+EFI_EVENT gEvICCEnumTimer = 0;
+UINTN gCounterCCIDEnumTimer = 0;
+UINTN gICCLock = 0;
+
+#define USBCCID_DRIVER_VERSION 1
+
+NAME_SERVICE_T Names;
+
+EFI_DRIVER_BINDING_PROTOCOL CcidBindingProtocol = {
+ SupportedUSBCCID,
+ StartUSBCCID,
+ StopUSBCCID,
+ USBCCID_DRIVER_VERSION,
+ NULL,
+ NULL
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallUSBCCID
+//
+// Description: Install AMI_CCID_IO_PROTOCOL_GUID for each slot
+//
+// Input:
+// EFI_HANDLE CCIDHandle
+// DEV_INFO *fpCCIDDevice
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+InstallUSBCCID(
+ EFI_HANDLE CCIDHandle,
+ DEV_INFO *fpCCIDDevice,
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_INVALID_PARAMETER;
+ USB_ICC_DEV *ICCDev;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "InstallUSBCCID ....\n" );
+
+ //
+ // Install Protocol irrespective of device found or not.
+ // By checking ChildHandle here, avoid repeated protocol installation.
+ //
+
+ if (fpICCDevice && !fpICCDevice->ChildHandle) {
+
+ gBS->AllocatePool(EfiBootServicesData, sizeof(USB_ICC_DEV), &ICCDev);
+ ICCDev->ChildHandle = 0;
+ ICCDev->ControllerHandle = 0;
+ ICCDev->DevInfo = fpCCIDDevice;
+ ICCDev->Slot = fpICCDevice->Slot;
+
+
+ ICCDev->CCIDIoProtocol.USBCCIDAPISmartClassDescriptor = USBCCIDAPISmartClassDescriptor;
+ ICCDev->CCIDIoProtocol.USBCCIDAPIGetAtr = USBCCIDAPIGetAtr;
+ ICCDev->CCIDIoProtocol.USBCCIDAPIPowerupSlot = USBCCIDAPIPowerupSlot;
+ ICCDev->CCIDIoProtocol.USBCCIDAPIPowerDownSlot = USBCCIDAPIPowerDownSlot;
+ ICCDev->CCIDIoProtocol.USBCCIDAPIGetSlotStatus = USBCCIDAPIGetSlotStatus;
+ ICCDev->CCIDIoProtocol.USBCCIDAPIXfrBlock = USBCCIDAPIXfrBlock;
+ ICCDev->CCIDIoProtocol.USBCCIDAPIGetParameters = USBCCIDAPIGetParameters;
+
+ Status = gBS->InstallProtocolInterface(
+ &ICCDev->ChildHandle,
+ &gAmiCCIDIoProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &ICCDev->CCIDIoProtocol
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ fpICCDevice->ChildHandle = ICCDev->ChildHandle;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "ICCDev->ChildHandle = %x\n", ICCDev->ChildHandle);
+
+ Status = gBS->OpenProtocol (
+ CCIDHandle,
+ &gEfiUsbIoProtocolGuid,
+ &UsbIo,
+ CcidBindingProtocol.DriverBindingHandle,
+ ICCDev->ChildHandle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER );
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Install CCID on %x status = %r\n", CCIDHandle, Status);
+ ASSERT_EFI_ERROR(Status);
+
+ }
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UnInstallUSBCCID
+//
+// Description: Uninstall AMI_CCID_IO_PROTOCOL_GUID for each slot
+//
+// Input:
+// EFI_HANDLE CCIDHandle - SmartCard Reader Handle
+// EFI_HANDLE ChildHandle - Smart Card Handle
+//
+// output:
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UnInstallUSBCCID (
+ EFI_HANDLE CCIDHandle,
+ EFI_HANDLE ChildHandle
+)
+{
+
+ EFI_STATUS Status;
+ AMI_CCID_IO_PROTOCOL *CCIDIoProtocol;
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "UnInstallUSBCCID ....\n" );
+
+ Status = gBS->OpenProtocol ( ChildHandle,
+ &gAmiCCIDIoProtocolGuid,
+ &CCIDIoProtocol,
+ CcidBindingProtocol.DriverBindingHandle,
+ ChildHandle,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ //
+ // CCID protocol not found on ChildHandle. return with error.
+ //
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // If CCID protocol Found, close the protocol and uninstall the protocol interface.
+ //
+ Status = gBS->CloseProtocol (CCIDHandle,
+ &gEfiUsbIoProtocolGuid,
+ CcidBindingProtocol.DriverBindingHandle,
+ ChildHandle);
+
+ Status = pBS->UninstallProtocolInterface ( ChildHandle,
+ &gAmiCCIDIoProtocolGuid,
+ CCIDIoProtocol);
+
+ if(!EFI_ERROR(Status)){
+ gBS->FreePool(CCIDIoProtocol);
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPISmartClassDescriptor
+//
+// Description: Generates a SW SMI to get the SMART Class Descriptor for the CCID device
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This
+// OUT UINT8 *ResponseBuffer
+//
+// Output:
+// EFI_STATUS and returns SMART Class Descriptor in ResponseBuffer
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPISmartClassDescriptor(
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *ResponseBuffer
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_SMARTCLASSDESCRIPTOR;
+
+ Parameters.ApiData.CCIDSmartClassDescriptor.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDSmartClassDescriptor.Slot = ((USB_ICC_DEV *)This)->Slot;
+ Parameters.ApiData.CCIDSmartClassDescriptor.fpResponseBuffer = (UINTN)ResponseBuffer;
+
+ InvokeUsbApi(&Parameters);
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPIGetAtr
+//
+// Description: Generates a SW SMI to get the ATR data
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This
+// IN UINT8 Slot,
+// OUT UINT8 *ATRData
+//
+// Output:
+// EFI_STATUS and returns ATR data if available
+//
+// Notes:
+// ATRData buffer length should be 32 bytes long. Caller should allocate
+// memory for *ATRData.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPIGetAtr (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ IN UINT8 Slot,
+ OUT UINT8 *ATRData
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_ATR;
+
+ Parameters.ApiData.CCIDAtr.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDAtr.Slot = ((USB_ICC_DEV *)This)->Slot;
+ Parameters.ApiData.CCIDAtr.ATRData = (UINTN)ATRData;
+
+ InvokeUsbApi(&Parameters);
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPIPowerupSlot
+//
+// Description: Generates a SW SMI to power up the slot in CCID
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This,
+// IN UINT8 Slot,
+// OUT UINT8 *bStatus,
+// OUT UINT8 *bError,
+// OUT UINT8 *ATRData
+//
+// Output:
+// EFI_STATUS and returns ATR data if Card powered up successfully.
+//
+// Notes:
+// ATRData buffer length should be 32 bytes long. Caller should allocate memory for *ATRData.
+// Presence/Absence of card can be determined from *bStatus/*bError.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPIPowerupSlot (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ OUT UINT8 *ATRData
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_POWERUP_SLOT;
+
+ Parameters.ApiData.CCIDPowerupSlot.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDPowerupSlot.Slot = ((USB_ICC_DEV *)This)->Slot;
+ Parameters.ApiData.CCIDPowerupSlot.ATRData = (UINTN)ATRData;
+
+ InvokeUsbApi(&Parameters);
+
+ *bStatus = Parameters.ApiData.CCIDPowerupSlot.bStatus;
+ *bError = Parameters.ApiData.CCIDPowerupSlot.bError;
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPIPowerDownSlot
+//
+// Description: Generates a SW SMI to power down the slot in CCID.
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This,
+// IN UINT8 Slot,
+// OUT UINT8 *bStatus,
+// OUT UINT8 *bError,
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPIPowerDownSlot (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_POWERDOWN_SLOT;
+
+ Parameters.ApiData.CCIDPowerdownSlot.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDPowerdownSlot.Slot = ((USB_ICC_DEV *)This)->Slot;
+
+ InvokeUsbApi(&Parameters);
+
+ *bStatus = Parameters.ApiData.CCIDPowerdownSlot.bStatus;
+ *bError = Parameters.ApiData.CCIDPowerdownSlot.bError;
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPIGetSlotStatus
+//
+// Description: This API returns data from RDR_to_PC_SlotStatus
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This
+// OUT UINT8 *bStatus
+// OUT UINT8 *bError
+// OUT UINT8 *bClockStatus
+//
+// Output:
+// OUT UINT8 *bStatus - Sec 6.2.6 if CCID spec ver 1.2
+// OUT UINT8 *bError - Sec 6.2.6 if CCID spec ver 1.2
+// OUT UINT8 *bClockStatus
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPIGetSlotStatus (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ OUT UINT8 *bClockStatus
+
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_GET_SLOT_STATUS;
+
+ Parameters.ApiData.CCIDGetSlotStatus.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDGetSlotStatus.Slot = ((USB_ICC_DEV *)This)->Slot;
+
+ InvokeUsbApi(&Parameters);
+
+ *bStatus = Parameters.ApiData.CCIDGetSlotStatus.bStatus;
+ *bError = Parameters.ApiData.CCIDGetSlotStatus.bError;
+ *bClockStatus = Parameters.ApiData.CCIDGetSlotStatus.bClockStatus;
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPIXfrBlock
+//
+// Description: This API generates a SWSMI to execute the USB_CCID_XFRBLOCK API.
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This
+// IN UINTN CmdLength - Length of CmdBuffer
+// IN UINT8 *CmdBuffer - Buffer prepared to be sent to ICC through PC_TO_RDR_XFRBLOCK cmd
+// IN UINT8 ISBlock - Valid only in T1 TDPU
+// OUT UINT8 *bStatus
+// OUT UINT8 *bError
+// IN OUT UINTN *ResponseLength - Lenght of the Responsebuffer
+// OUT UINT8 *ResponseBuffer
+//
+// Output:
+// EFI_STATUS
+// OUT UINT8 *bStatus - Sec 6.2.6 if CCID spec ver 1.2
+// OUT UINT8 *bError - Sec 6.2.6 if CCID spec ver 1.2
+// IN OUT UINTN *ResponseLength - Actual number of Bytes returned in ResponseBuffer
+// OUT UINT8 *ResponseBuffer - Response bytes
+//
+// Notes:
+// ISBlock is valid only for T1. For updating IFS use S_IFS_REQUEST(0xC1).
+// For WTX request use S_WTX_REQUEST (0xC3). For all others use I_BLOCK(0x0)
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPIXfrBlock (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ IN UINTN CmdLength,
+ IN UINT8 *CmdBuffer,
+ IN UINT8 ISBlock,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ IN OUT UINTN *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_XFRBLOCK;
+ Parameters.ApiData.CCIDXfrBlock.CmdLength = CmdLength;
+ Parameters.ApiData.CCIDXfrBlock.fpCmdBuffer = (UINT32)(UINTN)CmdBuffer;
+ Parameters.ApiData.CCIDXfrBlock.ISBlock = I_BLOCK;
+ Parameters.ApiData.CCIDXfrBlock.ResponseLength = *ResponseLength;
+ Parameters.ApiData.CCIDXfrBlock.fpResponseBuffer = (UINTN)ResponseBuffer;
+
+ Parameters.ApiData.CCIDXfrBlock.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDXfrBlock.Slot = ((USB_ICC_DEV *)This)->Slot;
+
+ InvokeUsbApi(&Parameters);
+
+ *bStatus = Parameters.ApiData.CCIDXfrBlock.bStatus ;
+ *bError = Parameters.ApiData.CCIDXfrBlock.bError;
+ *ResponseLength = Parameters.ApiData.CCIDXfrBlock.ResponseLength;
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBCCIDAPIGetParameters
+//
+// Description: Returns data from PC_TO_RDR_GETPARAMETERS/RDR_to_PCParameters cmd
+//
+// Input:
+// IN AMI_CCID_IO_PROTOCOL *This,
+// OUT UINT8 *bStatus,
+// OUT UINT8 *bError,
+// IN OUT UINTN *ResponseLength,
+// OUT UINT8 *ResponseBuffer
+//
+// Output:
+// IN AMI_CCID_IO_PROTOCOL *This,
+// OUT UINT8 *bStatus,
+// OUT UINT8 *bError,
+// IN OUT UINTN *ResponseLength,
+// OUT UINT8 *ResponseBuffer
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+USBCCIDAPIGetParameters (
+ IN AMI_CCID_IO_PROTOCOL *This,
+ OUT UINT8 *bStatus,
+ OUT UINT8 *bError,
+ IN OUT UINTN *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+)
+{
+
+ EFI_STATUS Status;
+ URP_STRUC Parameters = { 0 };
+
+ Parameters.bFuncNumber = USB_API_CCID_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_CCID_GET_PARAMETERS;
+ Parameters.ApiData.CCIDGetParameters.ResponseLength = *ResponseLength;
+ Parameters.ApiData.CCIDGetParameters.fpResponseBuffer = (UINT32)(UINTN)ResponseBuffer;
+
+ Parameters.ApiData.CCIDGetParameters.fpDevInfo = (UINTN)((USB_ICC_DEV *)This)->DevInfo;
+ Parameters.ApiData.CCIDGetParameters.Slot = ((USB_ICC_DEV *)This)->Slot;
+
+ InvokeUsbApi(&Parameters);
+
+ *bStatus = Parameters.ApiData.CCIDGetParameters.bStatus ;
+ *bError = Parameters.ApiData.CCIDGetParameters.bError;
+ *ResponseLength = Parameters.ApiData.CCIDGetParameters.ResponseLength;
+
+ Status = GetReturnValue(Parameters.bRetValue);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetICCDevice
+//
+// Description: Search the linked list to find the ICC_DEVICE for the given slot #.
+//
+// Input:
+// DEV_INFO *fpDevInfo,
+// UINT8 Slot
+//
+// Output:
+// ICC_DEVICE Pointer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ICC_DEVICE*
+GetICCDevice(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+)
+{
+
+ ICC_DEVICE *fpICCDevice;
+ DLINK *dlink;
+
+ dlink = fpDevInfo->ICCDeviceList.pHead;
+
+ for ( ; dlink; dlink = dlink->pNext) {
+
+ fpICCDevice = OUTTER(dlink, ICCDeviceLink, ICC_DEVICE);
+
+ //
+ // Slot # matches
+ //
+ if (fpICCDevice->Slot == Slot) {
+ return fpICCDevice;
+ }
+
+ }
+
+ //
+ // No Device Found. Return with NULL pointer
+ //
+ return NULL;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCCIDDevice
+//
+// Description: Search the linked list to find the CCID Device for the given ICC
+//
+// Input:
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// DEV_INFO Pointer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+DEV_INFO*
+GetCCIDDevice(
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+
+ DEV_INFO *fpCCIDDevice;
+ ICC_DEVICE *fpTempICCDevice;
+ DLINK *dlink;
+ UINTN i;
+
+ for (i = 0; i < MAX_DEVICES; i++ ){
+
+ fpCCIDDevice = &(gUsbData->aDevInfoTable[i]);
+
+ //
+ // If not a CCID device continue the loop
+ //
+ if (!(fpCCIDDevice->bDeviceType == BIOS_DEV_TYPE_CCID)) continue;
+
+ dlink = fpCCIDDevice->ICCDeviceList.pHead;
+
+ for ( ; dlink; dlink = dlink->pNext) {
+
+ fpTempICCDevice = OUTTER(dlink, ICCDeviceLink, ICC_DEVICE);
+
+ //
+ // Match found?
+ //
+ if (fpICCDevice == fpTempICCDevice) {
+ return fpCCIDDevice;
+ }
+
+ }
+
+ }
+
+ //
+ // Device Not Found, Return with NULL
+ //
+ return NULL;
+}
+
+
+//---------------------------------------------------------------------------
+//
+// Name: GetReturnValue
+//
+// Description: Convert CCID return Value to EFI_STATUS
+//
+// Input:
+// UINT8 bRetValue
+//
+// Output:
+// EFI_STATUS - Return the EFI Status
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetReturnValue(
+ UINT8 bRetValue
+)
+{
+ EFI_STATUS Status;
+
+ switch (bRetValue) {
+
+ case USB_SUCCESS:
+ Status = EFI_SUCCESS;
+ break;
+
+ default:
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ICCOnTimer
+//
+// Description: Timer call-back routine that is used to monitor insertion/removal
+// of ICC(Smart card) in the smart card reader.
+//
+// Input:
+// EFI_EVENT Event,
+// VOID *Context
+//
+// Output:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ICCOnTimer(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ ICC_DEVICE *fpICCDevice = NULL;
+ DEV_INFO *fpCCIDDevice;
+ UINTN Lock;
+ EFI_HANDLE CCIDHandle;
+
+ ATOMIC({Lock = gICCLock; gICCLock=1;});
+
+ if( Lock ){
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "ICCOnTimer:: is locked; return\n" );
+ return;
+ }
+
+ do {
+
+ ATOMIC({fpICCDevice = (ICC_DEVICE *)QueueGet(&gUsbData->ICCQueueCnnctDisc);});
+
+ if (fpICCDevice == NULL) {
+ break;
+ }
+
+ fpCCIDDevice = GetCCIDDevice(fpICCDevice);
+
+ if (!fpCCIDDevice) {
+ continue;
+ }
+
+ CCIDHandle = (EFI_HANDLE) *(UINTN*)fpCCIDDevice->Handle;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Controller %x\n", CCIDHandle);
+ USB_DEBUG(DEBUG_LEVEL_3, "Insert/Removal: fpDevInfo %x fpICCDevice %x\n", fpCCIDDevice, fpICCDevice);
+
+#if CCID_USE_INTERRUPT_INSERTION_REMOVAL
+ if (fpICCDevice->ConfiguredStatus & ICCPRESENT) {
+ //
+ // Install EFI interface to communicate with Smart Card/CCID
+ //
+ InstallUSBCCID(CCIDHandle, fpCCIDDevice, fpICCDevice);
+ }
+ else{
+ //
+ // Device Removed. Uninstall the existing Device
+ //
+ UnInstallUSBCCID (CCIDHandle, fpICCDevice->ChildHandle);
+ }
+#else
+ InstallUSBCCID(CCIDHandle, fpCCIDDevice, fpICCDevice);
+#endif
+
+ } while ( 1 );
+
+ gICCLock = 0;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SupportedUSBCCID
+//
+// Description: Verifies if usb CCID support can be installed on a device
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver supports given controller
+// EFI_UNSUPPORTED - driver doesn't support given controller
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SupportedUSBCCID(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR Desc;
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if( EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &Desc);
+
+ if(EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ( Desc.InterfaceClass == BASE_CLASS_CCID_STORAGE &&
+ Desc.InterfaceSubClass == SUB_CLASS_CCID &&
+ Desc.InterfaceProtocol == PROTOCOL_CCID) {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: StartUSBCCID
+//
+// Description: Installs CCID protocol on a given handle
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath - pointer to device path
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver started successfully
+// EFI_UNSUPPORTED - driver didn't start
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+StartUSBCCID(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: installUSBCCID: starting...\n");
+
+ //
+ // Open Protocols
+ //
+ //ALREADY_STARTED is a normal condition
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if( EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ {
+ USBDEV_T* CCIDDev = UsbIo2Dev(UsbIo);
+ HC_STRUC* HcData;
+ UINT8 UsbStatus;
+
+ ASSERT(CCIDDev);
+ HcData = gUsbData->HcTable[CCIDDev->dev_info->bHCNumber - 1];
+ UsbStatus = UsbSmiReConfigDevice(HcData, CCIDDev->dev_info);
+
+ if(UsbStatus != USB_SUCCESS) {
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "installUSBCCID: failed to Reconfigure KBD: %d\n", UsbStatus );
+
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Install AMI CCID Presence protocol to identify SMART Card reader is detected
+ //
+ Status = gBS->InstallProtocolInterface(
+ &Controller,
+ &gAmiCCIDPresenceGuid,
+ EFI_NATIVE_INTERFACE,
+ NULL
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Setting up Timer to to detect ICC card insertion removal
+ //
+ gCounterCCIDEnumTimer++;
+ if (gEvICCEnumTimer == 0) {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: Start: setup timer callback %x\n", &ICCOnTimer );
+ VERIFY_EFI_ERROR(
+ gBS->CreateEvent ( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK, ICCOnTimer,0,&gEvICCEnumTimer));
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gEvICCEnumTimer, TimerPeriodic, MILLISECOND));
+ }
+
+ }
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: installCCID: done (%x).\n", Status);
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: StopSBCCID
+//
+// Description: Uninstalls CCID protocol on a given handle
+//
+// Input:
+// IN EFI_DRIVER_BINDING_PROTOCOL *This - pointer to driver binding protocol
+// IN EFI_HANDLE ControllerHandle - controller handle to install driver on
+// IN UINTN NumberOfChildren - number of childs on this handle
+// IN OPTIONAL EFI_HANDLE *ChildHandleBuffer - pointer to child handles array
+//
+// Output:
+// EFI_STATUS
+// EFI_SUCCESS - driver stopped successfully
+// EFI_INVALID_PARAMETER - invalid values passed for NumberOfChildren or
+// ChildHandleBuffer
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+StopUSBCCID(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+
+ EFI_STATUS Status;
+
+ if (!NumberOfChildren) {
+
+ // Closer the timer event when all CCID devices have been stopped
+ if(--gCounterCCIDEnumTimer==0){
+
+ VERIFY_EFI_ERROR(gBS->SetTimer ( gEvICCEnumTimer, TimerCancel, ONESECOND));
+ VERIFY_EFI_ERROR(gBS->CloseEvent (gEvICCEnumTimer));
+ gEvICCEnumTimer=0;
+
+ }
+
+ //
+ // uninstall gAmiCCIDPresenceGuid
+ //
+ Status = pBS->UninstallProtocolInterface ( Controller,
+ &gAmiCCIDPresenceGuid,
+ NULL);
+
+ Status = gBS->CloseProtocol (Controller,
+ &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ ASSERT_EFI_ERROR(Status);
+
+ }
+
+ while (NumberOfChildren){
+
+ //
+ // Uninstall AMI_CCID_IO_PROTOCOL for each slot
+ //
+ Status = UnInstallUSBCCID (Controller, Children[NumberOfChildren - 1]);
+ ASSERT_EFI_ERROR(Status);
+ NumberOfChildren--;
+
+ }
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbCCIDGetControllerName
+//
+// Description: Returns the Controller Name
+//
+// Input:
+// EFI_HANDLE Controller,
+// EFI_HANDLE Child
+//
+// Output:
+// CHAR16* - Pointer to the buffer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+UsbCCIDGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbCCIDInit
+//
+// Description: CCID driver entry point
+//
+// Input:
+// EFI_HANDLE ImageHandle,
+// EFI_HANDLE ServiceHandle
+//
+// Output:
+// EFI_STATUS - Efi Status.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbCCIDInit(
+ EFI_HANDLE ImageHandle,
+ EFI_HANDLE ServiceHandle
+)
+{
+
+ CcidBindingProtocol.DriverBindingHandle = ServiceHandle;
+ CcidBindingProtocol.ImageHandle = ImageHandle;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USB CCID binding:\n\t");
+ USB_DEBUG(DEBUG_LEVEL_3, "SupportedUSBCCID:%x\n", &SupportedUSBCCID );
+ USB_DEBUG(DEBUG_LEVEL_3, "\tInstallUSBCCID:%x\n", &StartUSBCCID);
+ USB_DEBUG(DEBUG_LEVEL_3, "\tUninstallUSBCCID:%x\n", &StopUSBCCID );
+
+ return gBS->InstallMultipleProtocolInterfaces(
+ &CcidBindingProtocol.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &CcidBindingProtocol,
+ &gEfiComponentName2ProtocolGuid, InitNamesProtocol(&Names, //(EIP69250)
+ L"AMI USB CCID driver", UsbCCIDGetControllerName),
+ NULL);
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbhid.c b/Core/EM/usb/efiusbhid.c
new file mode 100644
index 0000000..aa859ae
--- /dev/null
+++ b/Core/EM/usb/efiusbhid.c
@@ -0,0 +1,534 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbhid.c 17 5/28/15 5:01a Wilsonlee $
+//
+// $Revision: 17 $
+//
+// $Date: 5/28/15 5:01a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbhid.c $
+//
+// 17 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 16 8/12/14 3:04a Wilsonlee
+// [TAG] EIP180970
+// [Category] Improvement
+// [Description] Update X and Y data to usbmousedata and install
+// SimplePointerProtocol interface if the mouses are using boot protocol
+// interface.
+// [Files] efiusbhid.c, usbms.c
+//
+// 15 5/06/14 5:17a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 14 10/19/13 7:08a Ryanchou
+// [TAG] EIP138257
+// [Category] Improvement
+// [Description] Correct USB HID device type.
+// [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c
+//
+// 13 7/24/13 2:31a Roberthsu
+// [TAG] EIP121333
+// [Category] Improvement
+// [Description] Multiple USB mouse support for UEFI USB mouse driver
+// [Files] efiusbhid.c,efiusbkb.h,efiusbms.c
+//
+// 12 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 11 11/29/12 7:48a Ryanchou
+// [TAG] EIP107586
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Unplug USB keyboard does not uninstall EFI USB keyboard
+// driver properly
+// [RootCause] The EIP99431 changes clear DEV_INFO.bSubDeviceType in
+// runtime keyboard driver, that cause EFI keyboard driver does not know
+// what type of the device is.
+// [Solution] Do not clear DEV_INFO.bSubDeviceType in runtime keyboard
+// driver.
+// [Files] usb.c, usbhid.c, efiusbhid.c
+//
+// 10 11/10/12 6:41a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 9 8/29/12 8:35a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 8 5/04/12 5:19a Roberthsu
+//
+// 7 5/03/12 5:55a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 6 12/29/11 1:54a Deepthins
+// [TAG] EIP77537
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Multiple USB keyboard are not synchronized properly
+// [RootCause] In USB driver for the new Simpletextin ( USB keyboard)
+// device, the memory allocated for the device is saved in gUsbKbd
+// pointer. The same pointer is used when multiple simple text in device
+// installed.
+// [Solution] USB_KB_DEV structure is divided into 2 structure, one is
+// common for all the Simpletextin and another structure is for specific
+// to the SimpleTextin Device.Based on it, allocate the memory for
+// structure and use it. When the stop function is called, we should free
+// only the structure that is specific for device.
+//
+// [Files] Efiusbkb.c, Efiusbhid.c, efiusbkb.c
+//
+// 5 12/14/11 2:10a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 4 10/24/11 8:31a Wilsonlee
+// [TAG] EIP69250
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB driver doesn't pass SCT 2.3 ComponentName2 protocol.
+// [RootCause] There is no checking if passed controller handle is NULL
+// in AMIUSBComponentNameGetControllerName function.
+// [Solution] Check controller handle is NULL in
+// AMIUSBComponentNameGetControllerName function.
+// [Files] componentname.c efiusbccid.c efiusbhid.c
+//
+// 3 9/23/11 12:31a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h, efiusbhid.c
+//
+// 2 8/05/11 7:28a Ryanchou
+// [TAG] EIP66231
+// [Category] Improvement
+// [Description] Remove token POINT_SUPPORT.Add token USB_DEV_POINT.Add
+// check core version in point driver.Add check device descriptor to send
+// get lang id command.Modify check button usage page.
+// [Files] efiusbhid.c, efiusbpoint.c, usbbus.c, usbhid.c, usbpoint.c,
+// usbsrc.sdl
+//
+// 1 7/15/11 6:26a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EfiUsbHid.C
+//
+// Description: EFI USB HID device Driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "efiusbkb.h"
+#include "usbkbd.h"
+
+#include "componentname.h"
+#include "usbbus.h"
+
+extern DLIST mUsbKeyboardData;
+extern USB_GLOBAL_DATA *gUsbData;
+EFI_EVENT UsbKeyEvent;
+extern USB_KEYBOARD_DATA* gUsbKeyboardData;
+
+#define AMI_HID_DEVICE_GUID \
+ {0x1fede521, 0x31c, 0x4bc5, 0x80, 0x50, 0xf3, 0xd6, 0x16, 0x1e, 0x2e, 0x92}
+
+EFI_GUID gAmiHidDeviceGuid = AMI_HID_DEVICE_GUID;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbHidGetControllerName
+//
+// Description: USB EFI keyboard driver driver protocol function that
+// returns the keyboard controller name.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+UsbHidGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbHidInit
+//
+// Description: HID EFI driver entry point
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbHidInit(
+ EFI_HANDLE ImageHandle,
+ EFI_HANDLE ServiceHandle
+)
+{
+ EFI_STATUS Status;
+ static NAME_SERVICE_T Names;
+ static EFI_DRIVER_BINDING_PROTOCOL Binding = {
+ SupportedUSBHid,
+ InstallUSBHid,
+ UninstallUSBHid,
+ USBKB_DRIVER_VERSION,
+ NULL,
+ NULL };
+
+ Binding.DriverBindingHandle = ServiceHandle;
+ Binding.ImageHandle = ImageHandle;
+
+ DListInit(&mUsbKeyboardData);
+
+ //
+ // Create a event to Poll a key when there is RegisterKeyNotify
+ //
+ pBS->CreateEvent(
+ EVT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ TPL_NOTIFY,
+ StartPollingKey,
+ NULL,
+ &UsbKeyEvent
+ );
+
+ InitUSBMouse();
+ //
+ // Allocate the memory for gUsbKeyboardData and calling InitUSBKeyboard
+ // to initialize the USB keyboard.
+ //
+ Status = gBS->AllocatePool( EfiBootServicesData,sizeof(USB_KEYBOARD_DATA), &gUsbKeyboardData );
+ ASSERT_EFI_ERROR(Status);
+ EfiZeroMem(gUsbKeyboardData, sizeof(USB_KEYBOARD_DATA));
+ Status = InitUSBKeyboard();
+
+ return gBS->InstallMultipleProtocolInterfaces(
+ &Binding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &Binding,
+ &gEfiComponentName2ProtocolGuid, InitNamesProtocol(&Names, //(EIP69250)
+ L"USB Hid driver", UsbHidGetControllerName),
+ NULL);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SupportedUSBHid
+//
+// Description: Verifies if usb hid support can be installed on a device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SupportedUSBHid(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR Desc;
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+ Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &Desc );
+ if(EFI_ERROR(Status))
+ return EFI_UNSUPPORTED;
+
+ if ( Desc.InterfaceClass == BASE_CLASS_HID)
+ {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallUSBHid
+//
+// Description: Installs SimpleTxtIn protocol on a given handle
+//
+// Input: Controller - controller handle to install protocol on.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUSBHid(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ USBDEV_T* HidDev;
+ HC_STRUC* HcData;
+ UINT8 UsbStatus;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: InstallUSBHid: starting...\n");
+ //
+ // Open Protocols
+ //
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status))
+ return Status;
+
+ HidDev = UsbIo2Dev(UsbIo);
+//Find DEV_INFO
+ ASSERT(HidDev);
+ HcData = gUsbData->HcTable[HidDev->dev_info->bHCNumber - 1];
+ UsbStatus = UsbSmiReConfigDevice(HcData, HidDev->dev_info);
+ if(UsbStatus != USB_SUCCESS) {
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "InstallUSBHid: failed to Reconfigure Hid: %d\n", UsbStatus );
+ gBS->CloseProtocol (
+ Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = gBS->InstallMultipleProtocolInterfaces (&Controller,
+ &gAmiHidDeviceGuid, NULL,
+ NULL
+ );
+
+ if(HidDev->dev_info->HidDevType & HID_DEV_TYPE_KEYBOARD) {
+ InstallUSBKeyboard(This,Controller,DevicePath,HidDev->dev_info,UsbIo);
+ }
+
+ if (HidDev->dev_info->HidDevType & (HID_DEV_TYPE_MOUSE | HID_DEV_TYPE_POINT)) {
+ if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) {
+ if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_RELATIVE_DATA) {
+ InstallUSBMouse(Controller, UsbIo, HidDev->dev_info);
+ }
+#if USB_DEV_POINT
+ if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_ABSOLUTE_DATA) {
+ InstallUSBAbsMouse(Controller, HidDev->dev_info);
+ }
+#endif
+ } else {
+ InstallUSBMouse(Controller, UsbIo, HidDev->dev_info);
+ }
+ }
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UninstallHid
+//
+// Description: Uninstalls protocol on a given handle
+//
+// Input: Controller - controller handle.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UninstallUSBHid(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ VOID *Ptr;
+ UINT8 UsbSatus;
+ USBDEV_T* HidDev;
+ HC_STRUC* HcData;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "\n USB: UnInstallUSBHid: stoping...\n");
+
+ Status = gBS->OpenProtocol(Controller, &gAmiHidDeviceGuid,
+ &Ptr, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //
+ // Open Protocols
+ //
+ Status = gBS->OpenProtocol(Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ HidDev = UsbIo2Dev(UsbIo);
+ HcData = gUsbData->HcTable[HidDev->dev_info->bHCNumber - 1];
+
+ UsbSatus = UsbDevDriverDisconnect(HcData, HidDev->dev_info);
+ ASSERT(UsbSatus == USB_SUCCESS);
+
+ if (HidDev->dev_info->HidDevType & HID_DEV_TYPE_KEYBOARD) {
+ Status = UninstallUSBKeyboard(This,Controller,NumberOfChildren,Children);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+
+ if (HidDev->dev_info->HidDevType & (HID_DEV_TYPE_MOUSE | HID_DEV_TYPE_POINT)) {
+ if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) {
+ if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_RELATIVE_DATA) {
+ Status = UninstallUSBMouse(This, Controller, NumberOfChildren, Children);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+#if USB_DEV_POINT
+ if (HidDev->dev_info->HidReport.Flag & HID_REPORT_FLAG_ABSOLUTE_DATA) {
+ Status = UninstallUSBAbsMouse(Controller);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+#endif
+ } else {
+ Status = UninstallUSBMouse(This, Controller, NumberOfChildren, Children);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ }
+ }
+
+ Status = gBS->UninstallMultipleProtocolInterfaces (Controller,
+ &gAmiHidDeviceGuid, NULL,
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //Close usbio protocol
+ Status = gBS->CloseProtocol(Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+ return Status;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbkb.c b/Core/EM/usb/efiusbkb.c
new file mode 100644
index 0000000..19802c8
--- /dev/null
+++ b/Core/EM/usb/efiusbkb.c
@@ -0,0 +1,3036 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbkb.c 87 5/28/15 5:01a Wilsonlee $
+//
+// $Revision: 87 $
+//
+// $Date: 5/28/15 5:01a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbkb.c $
+//
+// 87 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 86 4/23/15 11:28p Wilsonlee
+// [TAG] EIP213823
+// [Category] Improvement
+// [Description] The memory type for "mUsbKeyboardRecord" is changed
+// from EfiRuntimeServicesData to EfiBootServicesData.
+// [Files] efiusbkb.c
+//
+// 85 6/05/14 9:04p Wilsonlee
+// [TAG] EIP171786
+// [Category] Improvement
+// [Description] The PS2 scan code of "0x64 Keyboard Non-US \ and |" is
+// 0x56 and "0x67 Keypad =" is 0x59.
+// [Files] efiusbkb.c
+//
+// 84 12/20/13 7:36a Ryanchou
+// [TAG] EIP145616
+// [Category] Improvement
+// [Description] Check if the key has been registered before.
+// [Files] efiusbkb.c
+//
+// 83 11/26/13 4:09a Ryanchou
+// [TAG] EIP142509
+// [Category] Improvement
+// [Description] Added usage 0x87 and 0x89.
+// [Files] efiusbkb.c, efiusbkb.h
+//
+// 82 11/05/13 4:47a Ryanchou
+// [TAG] EIP135636
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NumLock LED cannot be on/off properly.
+// [RootCause] It is the side effect of EIP #107429 changes, the
+// keyboard does not generate break code when pressing NumLock.
+// [Solution] Remove the EIP #107429 changes.
+// [Files] amiusb.c, usbkbd.c, efiusbkb.c
+//
+// 81 7/15/13 8:33a Rameshr
+// [TAG] EIP124584
+// [Category] Improvement
+// [Description] Tab, Backspace, Enter Key's are considerd as Non
+// printable Key's.
+// [Files] efiusbkb.c
+//
+// 80 3/07/13 9:10a Ryanchou
+// [TAG] EIP114307
+// [Category] Improvement
+// [Description] Verified the record present in the linked list and if
+// it's not present, start from the head node again.
+// [Files] efiusbkb.c
+//
+// 79 2/21/13 10:10a Ryanchou
+//
+// 77 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 76 12/09/12 12:12a Wilsonlee
+// [TAG] EIP107429
+// [Category] Improvement
+// [Description] Process the make code even if there is no break code.
+// [Files] efiusbkb.c, amiusb.c
+//
+// 75 11/26/12 9:57p Wilsonlee
+// [TAG] EIP100370
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The root cause is that a timer event of
+// UsbKeyEvent(KEY_POLLING_INTERVAL(500000)) would be created while the
+// function of SimpleTextInEX->RegisterKeyNotify() being invoked, but if
+// we disconnect the Simple text in controllers through
+// pBS->DisconnectController (HandleBuffer[Index], NULL, NULL), this timer
+// still alive.
+// [RootCause] The registered keys in mUsbKeyboardData queue are not
+// cleaned when the USB keyboard driver is removed, which cause the timer
+// to keep running and the stopping condition in function
+// UsbKbdUnregisterKeyNotify could not be reached.
+// [Solution] Examine the mUsbKeyboardData queue at UninstallUSBKeyboard
+// and remove the registered keys inside if they are not empty.
+// [Files] efiusbkb.c
+//
+// 74 11/15/12 3:47a Ryanchou
+//
+// 72 11/01/12 6:32a Deepthins
+// [TAG] EIP101102
+// [Category] Improvement
+// [Description] Multi Language is supported in USB driver
+// [Files] efiusbkb.c, efiusbkb.h
+//
+// 71 10/24/12 1:24a Wilsonlee
+// [TAG] EIP100370
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The root cause is that a timer event of
+// UsbKeyEvent(KEY_POLLING_INTERVAL(500000)) would be created while the
+// function of SimpleTextInEX->RegisterKeyNotify() being invoked, but if
+// we disconnect the Simple text in controllers through
+// pBS->DisconnectController (HandleBuffer[Index], NULL, NULL), this timer
+// still alive.
+// [RootCause] The registered keys in mUsbKeyboardData queue are not
+// cleaned when the USB keyboard driver is removed, which cause the timer
+// to keep running and the stopping condition in function
+// UsbKbdUnregisterKeyNotify could not be reached.
+// [Solution] Examine the mUsbKeyboardData queue at UninstallUSBKeyboard
+// and remove the registered keys inside if they are not empty.
+// [Files] efiusbkb.c
+//
+// 70 9/24/12 8:37a Ryanchou
+// Correct the KeyToggleState check in UsbKbdSetState.
+//
+// 69 8/29/12 8:36a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 68 8/06/12 11:45p Roberthsu
+// [TAG] EIP91889
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CSInSetState has no function when Bootup NumLock State
+// is set to OFF
+// [RootCause] UsbKbdSetState does not work.
+// [Solution] Store ToggleState in function UsbKbdSetState.
+// [Files] efiusbkb.c
+//
+// 67 5/22/12 10:32a Lavanyap
+// [TAG] EIP88049
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Keyboard LED status is synchronised when it is plugged out
+// and in.
+// [RootCause] Existing LED state is not updated when a keyboard is
+// installed.
+// [Solution] Updated existing LED state when a keyboard is installed.
+// [Files] efiusbkb.c
+//
+// 66 5/03/12 5:56a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 65 5/03/12 4:03a Ryanchou
+// [TAG] EIP85918
+// [Category] Improvement
+// [Description] Change the reset type of Ctrl+Alt+Del to EfiResetWarm.
+// [Files] efiusbkb.c
+//
+// 64 4/24/12 3:37a Roberthsu
+// [TAG] EIP83888
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Can not catch F8 key event on Keyboard
+// [RootCause] OS only call readkeystroke once.If OS get break key
+// readkeystroke will return EFI_NOT_READY.
+// [Solution] UsbKbdReadKeyStroke will serach available key in usb
+// data buffer.Fixed key repeat can not
+// work when efi to legacy or legacy to efi.
+// [Files] efiusbkb.c,usbkbd.c
+//
+// 63 4/24/12 2:14a Deepthins
+// [TAG] EIP85747
+// [Category] Improvement
+// [Description] USB-ReadKeyStrokeEx is returning EFI_SUCCESS with
+// KEY_STATE_EXPOSED for Caps, Num and Scroll Lock Key's.
+// KEY_STATE_EXPOSED only for the ShiftState Key's and not for togglestate
+// key's.
+// [Files] Efiusbkb.c, ps2kbd.c and kbc.h
+//
+// 62 4/10/12 2:38a Rameshr
+// [TAG] EIP87058
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Not able to recognise Pause Key Click using ReadKeyStroke
+// [RootCause] Pause Key detection should be done always and only the
+// pause key action should be controlled by PAUSEKEY_SUPPORT SDL token
+// [Solution] SDL token checking removed for the Pause Key detection
+// [Files] efiusbkb.c
+//
+// 61 3/20/12 10:32p Wilsonlee
+// [TAG] EIP83295
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System will hang at B2 when do S3/S4 long run test or DOS
+// reboot test.
+// [RootCause] It causes the stack problem when we call
+// IsUSBKeyboardBufferEmpty function.
+// [Solution] Change to use pointer as parameter to
+// IsUSBKeyboardBufferEmpty function.
+// [Files] efiusbkb.c, efisubkb.h, usbmass.c, ehci.c
+//
+// 60 3/02/12 3:55a Rameshr
+// [TAG] EIP81563
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Press SHIFT key will result in the ReadKeyStroke return
+// unexpected ScanCode and UnicodeChar
+// [RootCause] When the Partial Key returned, ScanCode and Unicode are
+// not filled correctly.
+// [Solution] Initilized the Scan code and UniCode to NULL Value.
+// [Files] Efiusbkb.c
+//
+// 59 2/21/12 5:24a Rameshr
+// [TAG] EIP82772
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Usb Keyboard works even if the SimpleTextin uninstalled for
+// the UsbKeyboard
+// [RootCause] RegsiterKeyNotify Function event not stopped even after
+// SimpleTextin Uninstalled
+// [Solution] Stopped the KeyPolling Event if no more USB keyboard in
+// the system
+// [Files] efiusbkb.c
+//
+// 58 12/29/11 12:37a Deepthins
+// [TAG] EIP77537
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Multiple USB keyboard are not synchronized properly
+// [RootCause] In USB driver for the new Simpletextin ( USB keyboard)
+// device, the memory allocated for the device is saved in gUsbKbd
+// pointer. The same pointer is used when multiple simple text in device
+// installed.
+// [Solution] USB_KB_DEV structure is divided into 2 structure, one is
+// common for all the Simpletextin and another structure is for specific
+// to the SimpleTextin Device.Based on it, allocate the memory for
+// structure and use it. When the stop function is called, we should free
+// only the structure that is specific for device.
+// [Files] Efiusbkb.c, Efiusbhid.c, efiusbkb.c
+//
+// 57 12/14/11 2:09a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 56 9/23/11 12:32a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h, efiusbhid.c
+//
+// 55 8/25/11 11:49a Davidd
+// [TAG] EIPEIP55336
+// [Description] Removed EFI_DEADLOOP() in ClearUsbKbBuffer function
+// from previous check-in file version 54. It was used during testing and
+// inadvertently left over at the time of check-in.
+// [Files] efiusbkb.c
+//
+// 54 8/16/11 2:29p Davidd
+// [TAG] EIP55336
+// [Category] New Feature
+// [Description] Add optional code to clear keyboard buffer at
+// ReadyToBoot in USB driver
+// [Files] Efiusbkb.c
+// Usbsrc.sdl
+//
+// 53 7/15/11 6:23a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 52 5/30/11 2:54a Ryanchou
+// [TAG] EIP60562
+// [Category] Improvement
+// [Description] F11/F12 efi scan code correction.
+// [Files] efiusbkb.c
+//
+// 51 5/03/11 10:47a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 50 3/04/11 1:30p Olegi
+//
+// 49 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 48 10/12/10 4:37a Rameshr
+// [TAG] - EIP 42956
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - KeyNotificationFunction gets control twice for every key
+// press in USB keyboard
+// [RootCause] - KeyNotificationFunction gets called for each Key Press
+// and Key Release
+// [Solution] - Previous check-in has the wrong solution and corrected
+// now.
+// [Files] - EfiUsbKb.c
+//
+// 47 9/13/10 1:56a Rameshr
+// [TAG] - EIP 42956
+// [Category]- BUG FIX
+// [Severity]- Major
+// [Symptom] - KeyNotificationFunction gets control twice for every key
+// press in USB keyboard
+// [RootCause] - KeyNotificationFunction gets called for each Key Press
+// and Key Release
+// [Solution] - Added code to check only call KeyNotificationFunction on
+// Key Press.
+// [Files] - EfiUsbKb.c
+//
+// 46 7/20/10 4:34a Rameshr
+// Corrected the FreePool call in UnRegisterKeyNotify function
+//
+// 45 5/14/10 10:57a Olegi
+// - Tabs converted to spaces
+// - Added FreePool call in UnregisterKeyNotify function
+//
+// 44 5/10/10 2:31a Rameshr
+// Issue:Usb Keyboard driver doesn't handle the Shift Key properly in
+// RegsiterkeyNotify function
+// Solution: ShiftKeyState and KeyToggleState verified for
+// RegisterKeyNotify callback function.
+// EIP 38213
+//
+// 43 5/10/10 2:04a Rameshr
+// PrintScreen/SysRq key, Menu Key, Left Logo and Right Logo Key support
+// in USB Keyboard driver
+// EIP 38214
+//
+// 42 5/10/10 1:57a Rameshr
+// Issue:UsbKeyboard Driver doesn’t differentiate between Left Shift and
+// Right Shift Key.
+// Solution: modified the driver to differentiate between Left
+// Shift/Alt/Ctrl and Right Shift/Alt/Ctrl Key's.
+// EIP 38256
+//
+// 41 2/24/10 3:52p Olegi
+// Updated PS2ScanCodeIsValid field while returning AMI_KEYCODE from USB
+// keyboard.
+//
+// 40 2/23/10 1:36p Olegi
+// Work around Klockwork issues. EIP34370
+//
+// 39 9/15/09 12:01p Olegi
+// Implemented a circular buffer in KeypressCallback; related (indirectly)
+// to EIP#25841
+//
+// 38 8/13/09 2:59p Rameshr
+// When item "num-lock status" set off, Num-lock will keep open until in
+// DOS.
+// EIP:21757
+//
+// 37 5/07/09 5:20p Olegi
+// Numeric keypad scancode correction.
+//
+// 36 3/30/09 10:33a Pats
+// Issue: EIP 19547 - Pause key support needed in Aptio
+// Solution: Functions UsbParseKey and USBKeyCodeToEFIScanCode modified to
+// pass EFI_KEY vaule of pause key on rather than rejecting it.
+//
+// 35 1/22/09 3:00p Olegi
+// Bugfix for EIP#19039.
+//
+// 34 1/07/09 11:01a Olegi
+// Bugfix for EIP#18267
+//
+// 33 11/17/08 10:20a Rameshraju
+// Problem:SCT failure on RegisterKeyNotify, SetState and
+// UnregisterKeyNotify.
+// Fix : Validated the input parameters for RegisterKeyNotify, SetState
+// and UnregisterKeyNotify.
+// EIP:17578
+//
+// 32 10/08/08 4:34p Olegi
+// Implemented the Register/Unregister key notofocation function in
+// SimpletextinEx protocol.
+//
+// 31 10/03/08 3:32p Olegi
+//
+// 30 9/05/08 4:15p Olegi
+// fpCallbackNotify functions removed.
+//
+// 29 8/07/08 11:52a Olegi
+// Bugfix in UsbKbdReadKeyStrokeEx.
+//
+// 28 6/05/08 3:34p Olegi
+//
+// 27 6/05/08 3:27p Olegi
+// Bugfix in processing '5' key on a keypad: when NumLock is off, it
+// should not produce a character.
+//
+// 26 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 25 12/17/07 5:42p Rameshraju
+// Added the core revision check for the AMI Keycode to build with OLD
+// core.
+//
+// 24 10/25/07 4:47p Olegi
+//
+// 23 10/23/07 4:16p Olegi
+// AmiKeycode protocol implementation.
+//
+// 22 9/18/07 12:18p Olegi
+//
+// 19 7/26/07 4:26p Olegi
+// F11 and F12 keys are not ignored anymore.
+//
+// 18 7/13/07 11:44a Olegi
+// F11 and F12 codes added.
+//
+// 17 4/17/07 8:22a Olegi
+// Bugfix in UninstallUSBKeyboard function.
+//
+// 16 3/20/07 1:29p Olegi
+//
+// 15 12/08/06 3:25p Olegi
+// Bugfix in the sequence of multiple keyboard
+// installation/deinstallation.
+//
+// 13 10/12/06 7:12p Andriyn
+// Support unexpected plug-off USB device
+//
+// 12 7/19/06 3:54p Olegi
+//
+// 11 5/03/06 9:59a Olegi
+//
+// 10 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 9 3/01/06 3:53p Olegi
+// Added USB_LEGACY_PLATFORM_SUPPORT.
+//
+// 8 1/11/06 11:54a Olegi
+// EfiResetShutdown has changed to EfiResetCold.
+//
+// 7 11/22/05 4:06p Andriyn
+// Fix: EFI shell hangs when Ctrl-Al-Del reset the system from USB
+// keyboard
+//
+// 6 6/15/05 4:05p Olegi
+// EfiResetShutdown is replaced with EfiResetWarm on Ctl+Alt+Del.
+//
+// 5 6/01/05 5:10p Olegi
+// Debug message shortened.
+//
+// 4 5/19/05 8:06p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EfiUsbKb.c
+//
+// Description: USB Keyboard Efi driver implementation
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "efiusbkb.h"
+#include "usbkbd.h"
+
+#include "componentname.h"
+#include "usbbus.h"
+
+#ifndef KEY_STATE_EXPOSED
+#define KEY_STATE_EXPOSED 0x40
+#endif
+
+#define KEY_POLLING_INTERVAL 500000
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern EFI_GUID gEfiHotPlugDeviceGuid;
+extern EFI_EVENT UsbKeyEvent;
+
+EFI_STATUS UsbCheckKeyNotify(UINT8 Key);
+
+USB_KEYBOARD_DATA* gUsbKeyboardData;
+
+#if CLEAR_USB_KB_BUFFER_AT_READYTOBOOT
+EFI_EVENT gClearUsbKbBufferEvent;
+#endif
+
+typedef struct _KEY_WAITING_RECORD{
+ DLINK Link;
+ USB_KB_DEV* UsbKbDev; //(EIP100370+)
+ EFI_KEY_DATA Context;
+ EFI_KEY_NOTIFY_FUNCTION Callback;
+ BOOLEAN CallbackStatus;
+} KEY_WAITING_RECORD;
+
+DLIST mUsbKeyboardData;
+KEY_WAITING_RECORD *mUsbKeyboardRecord;
+BOOLEAN KeyProcessed=TRUE;
+static EFI_GUID gAmiMultiLangSupportGuid = AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID;
+AMI_MULTI_LANG_SUPPORT_PROTOCOL *gMultiLangSupportProtocol;
+
+
+//
+// USB Key Code to Efi key mapping table
+// Format:
+// <efi scan code>, <unicode w/o shift>, <unicode w shift>, <PS2 scan code>
+//
+static
+UINT8 KeyConvertionTable[USB_KEYCODE_MAX_MAKE][4] = {
+ SCAN_NULL, 'a', 'A', 0x1e, // 0x04
+ SCAN_NULL, 'b', 'B', 0x30, // 0x05
+ SCAN_NULL, 'c', 'C', 0x2e, // 0x06
+ SCAN_NULL, 'd', 'D', 0x20, // 0x07
+ SCAN_NULL, 'e', 'E', 0x12, // 0x08
+ SCAN_NULL, 'f', 'F', 0x21, // 0x09
+ SCAN_NULL, 'g', 'G', 0x22, // 0x0A
+ SCAN_NULL, 'h', 'H', 0x23, // 0x0B
+ SCAN_NULL, 'i', 'I', 0x17, // 0x0C
+ SCAN_NULL, 'j', 'J', 0x24, // 0x0D
+ SCAN_NULL, 'k', 'K', 0x25, // 0x0E
+ SCAN_NULL, 'l', 'L', 0x26, // 0x0F
+ SCAN_NULL, 'm', 'M', 0x32, // 0x10
+ SCAN_NULL, 'n', 'N', 0x31, // 0x11
+ SCAN_NULL, 'o', 'O', 0x18, // 0x12
+ SCAN_NULL, 'p', 'P', 0x19, // 0x13
+ SCAN_NULL, 'q', 'Q', 0x10, // 0x14
+ SCAN_NULL, 'r', 'R', 0x13, // 0x15
+ SCAN_NULL, 's', 'S', 0x1f, // 0x16
+ SCAN_NULL, 't', 'T', 0x14, // 0x17
+ SCAN_NULL, 'u', 'U', 0x16, // 0x18
+ SCAN_NULL, 'v', 'V', 0x2f, // 0x19
+ SCAN_NULL, 'w', 'W', 0x11, // 0x1A
+ SCAN_NULL, 'x', 'X', 0x2d, // 0x1B
+ SCAN_NULL, 'y', 'Y', 0x15, // 0x1C
+ SCAN_NULL, 'z', 'Z', 0x2c, // 0x1D
+ SCAN_NULL, '1', '!', 0x02, // 0x1E
+ SCAN_NULL, '2', '@', 0x03, // 0x1F
+ SCAN_NULL, '3', '#', 0x04, // 0x20
+ SCAN_NULL, '4', '$', 0x05, // 0x21
+ SCAN_NULL, '5', '%', 0x06, // 0x22
+ SCAN_NULL, '6', '^', 0x07, // 0x23
+ SCAN_NULL, '7', '&', 0x08, // 0x24
+ SCAN_NULL, '8', '*', 0x09, // 0x25
+ SCAN_NULL, '9', '(', 0x0a, // 0x26
+ SCAN_NULL, '0', ')', 0x0b, // 0x27
+ SCAN_NULL, 0x0d, 0x0d, 0x1c, // 0x28 Enter
+ SCAN_ESC, 0x00, 0x00, 0x01, // 0x29 Esc
+ SCAN_NULL, 0x08, 0x08, 0x0e, // 0x2A Backspace
+ SCAN_NULL, 0x09, 0x09, 0x0f, // 0x2B Tab
+ SCAN_NULL, ' ', ' ', 0x39, // 0x2C Spacebar
+ SCAN_NULL, '-', '_', 0x0c, // 0x2D
+ SCAN_NULL, '=', '+', 0x0d, // 0x2E
+ SCAN_NULL, '[', '{', 0x1a, // 0x2F
+ SCAN_NULL, ']', '}', 0x1b, // 0x30
+ SCAN_NULL, '\\', '|', 0x2b, // 0x31
+ SCAN_NULL, '\\', '|', 0x2b, // 0x32 Keyboard US \ and |
+ SCAN_NULL, ';', ':', 0x27, // 0x33
+ SCAN_NULL, '\'', '"', 0x28, // 0x34
+ SCAN_NULL, '`', '~', 0x29, // 0x35 Keyboard Grave Accent and Tlide
+ SCAN_NULL, ',', '<', 0x33, // 0x36
+ SCAN_NULL, '.', '>', 0x34, // 0x37
+ SCAN_NULL, '/', '?', 0x35, // 0x38
+ SCAN_NULL, 0x00, 0x00, 0x3a, // 0x39 CapsLock
+ SCAN_F1, 0x00, 0x00, 0x3b, // 0x3A
+ SCAN_F2, 0x00, 0x00, 0x3c, // 0x3B
+ SCAN_F3, 0x00, 0x00, 0x3d, // 0x3C
+ SCAN_F4, 0x00, 0x00, 0x3e, // 0x3D
+ SCAN_F5, 0x00, 0x00, 0x3f, // 0x3E
+ SCAN_F6, 0x00, 0x00, 0x40, // 0x3F
+ SCAN_F7, 0x00, 0x00, 0x41, // 0x40
+ SCAN_F8, 0x00, 0x00, 0x42, // 0x41
+ SCAN_F9, 0x00, 0x00, 0x43, // 0x42
+ SCAN_F10, 0x00, 0x00, 0x44, // 0x43
+ //(EIP60562)>
+ SCAN_F11, 0x00, 0x00, 0x57, // 0x44 F11
+ SCAN_F12, 0x00, 0x00, 0x58, // 0x45 F12
+ //<(EIP60562)
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x46 PrintScreen
+ SCAN_NULL, 0x00, 0x00, 0x46, // 0x47 Scroll Lock
+ SCAN_PAUSE, 0x00, 0x00, 0x00, // 0x48 Pause
+ SCAN_INSERT, 0x00, 0x00, 0x52, // 0x49
+ SCAN_HOME, 0x00, 0x00, 0x47, // 0x4A
+ SCAN_PAGE_UP, 0x00, 0x00, 0x49, // 0x4B
+ SCAN_DELETE, 0x00, 0x00, 0x53, // 0x4C
+ SCAN_END, 0x00, 0x00, 0x4f, // 0x4D
+ SCAN_PAGE_DOWN, 0x00, 0x00, 0x51, // 0x4E
+ SCAN_RIGHT, 0x00, 0x00, 0x4d, // 0x4F
+ SCAN_LEFT, 0x00, 0x00, 0x4b, // 0x50
+ SCAN_DOWN, 0x00, 0x00, 0x50, // 0x51
+ SCAN_UP, 0x00, 0x00, 0x48, // 0x52
+ SCAN_NULL, 0x00, 0x00, 0x45, // 0x53 NumLock
+ SCAN_NULL, '/', '/', 0x35, // 0x54
+ SCAN_NULL, '*', '*', 0x37, // 0x55
+ SCAN_NULL, '-', '-', 0x4a, // 0x56
+ SCAN_NULL, '+', '+', 0x4e, // 0x57
+ SCAN_NULL, 0x0d, 0x0d, 0x1c, // 0x58
+ SCAN_END, '1', '1', 0x4f, // 0x59
+ SCAN_DOWN, '2', '2', 0x50, // 0x5A
+ SCAN_PAGE_DOWN, '3', '3', 0x51, // 0x5B
+ SCAN_LEFT, '4', '4', 0x4b, // 0x5C
+ SCAN_NULL, '5', '5', 0x4c, // 0x5D
+ SCAN_RIGHT, '6', '6', 0x4d, // 0x5E
+ SCAN_HOME, '7', '7', 0x47, // 0x5F
+ SCAN_UP, '8', '8', 0x48, // 0x60
+ SCAN_PAGE_UP, '9', '9', 0x49, // 0x61
+ SCAN_INSERT, '0', '0', 0x52, // 0x62
+ SCAN_DELETE, '.', '.', 0x53, // 0x63
+ SCAN_NULL, '\\', '|', 0x56, // 0x64 Keyboard Non-US \ and |
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x65 Keyboard Application
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x66 Keyboard Power
+ SCAN_NULL, '=' , '=', 0x59, // 0x67 Keypad =
+
+ SCAN_F13, 0x00, 0x00, 0x64, // 0x68 F13
+ SCAN_F14, 0x00, 0x00, 0x65, // 0x69 F14
+ SCAN_F15, 0x00, 0x00, 0x66, // 0x6A F15
+ SCAN_F16, 0x00, 0x00, 0x67, // 0x6B F16
+ SCAN_F17, 0x00, 0x00, 0x68, // 0x6C F17
+ SCAN_F18, 0x00, 0x00, 0x69, // 0x6D F18
+ SCAN_F19, 0x00, 0x00, 0x6A, // 0x6E F19
+ SCAN_F20, 0x00, 0x00, 0x6B, // 0x6F F20
+ SCAN_F21, 0x00, 0x00, 0x6C, // 0x70 F21
+ SCAN_F22, 0x00, 0x00, 0x6D, // 0x71 F22
+ SCAN_F23, 0x00, 0x00, 0x6E, // 0x72 F23
+ SCAN_F24, 0x00, 0x00, 0x76, // 0x73 F24
+
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x74
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x75
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x76
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x77
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x78
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x79
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7A
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7B
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7C
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7D
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x7E
+ SCAN_MUTE, 0x00, 0x00, 0x00, // 0x7F
+ SCAN_VOLUME_UP, 0x00, 0x00, 0x00, // 0x80
+ SCAN_VOLUME_DOWN, 0x00, 0x00, 0x00, // 0x81
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x82
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x83
+ SCAN_NULL, 0x00, 0x00, 0x00, // 0x84
+ SCAN_NULL, '.', 0x00, 0x7E, // 0x85
+ SCAN_NULL, '=', 0x00, 0x00, // 0x86
+ SCAN_NULL, '\\', '_', 0x73, // 0x87 backslash
+ SCAN_NULL, 0x00, 0x00, 0x70, // 0x88
+ SCAN_NULL, 0xA5, '|', 0x7D, // 0x89 Yen Symbol
+ };
+
+KB_MODIFIER KB_Mod[8] = {
+ { MOD_CONTROL_L, 0xe0 }, // 11100000
+ { MOD_CONTROL_R, 0xe4 }, // 11100100
+ { MOD_SHIFT_L, 0xe1 }, // 11100001
+ { MOD_SHIFT_R, 0xe5 }, // 11100101
+ { MOD_ALT_L, 0xe2 }, // 11100010
+ { MOD_ALT_R, 0xe6 }, // 11100110
+ { MOD_WIN_L, 0xe3 }, // 11100011
+ { MOD_WIN_R, 0xe7 }, // 11100111
+};
+
+
+UINT8 UsbToEfiKeyTable[USB_KEYCODE_MAX_MAKE] = {
+ EfiKeyC1, // 'a', 'A', 0x1e, // 0x04
+ EfiKeyB5, // 'b', 'B', 0x30, // 0x05
+ EfiKeyB3, // 'c', 'C', 0x2e, // 0x06
+ EfiKeyC3, // 'd', 'D', 0x20, // 0x07
+ EfiKeyD3, // 'e', 'E', 0x12, // 0x08
+ EfiKeyC4, // 'f', 'F', 0x21, // 0x09
+ EfiKeyC5, // 'g', 'G', 0x22, // 0x0A
+ EfiKeyC6, // 'h', 'H', 0x23, // 0x0B
+ EfiKeyD8, // 'i', 'I', 0x17, // 0x0C
+ EfiKeyC7, // 'j', 'J', 0x24, // 0x0D
+ EfiKeyC8, // 'k', 'K', 0x25, // 0x0E
+ EfiKeyC9, // 'l', 'L', 0x26, // 0x0F
+ EfiKeyB7, // 'm', 'M', 0x32, // 0x10
+ EfiKeyB6, // 'n', 'N', 0x31, // 0x11
+ EfiKeyD9, // 'o', 'O', 0x18, // 0x12
+ EfiKeyD10,// 'p', 'P', 0x19, // 0x13
+ EfiKeyD1, // 'q', 'Q', 0x10, // 0x14
+ EfiKeyD4, // 'r', 'R', 0x13, // 0x15
+ EfiKeyC2, // 's', 'S', 0x1f, // 0x16
+ EfiKeyD5, // 't', 'T', 0x14, // 0x17
+ EfiKeyD7, // 'u', 'U', 0x16, // 0x18
+ EfiKeyB4, // 'v', 'V', 0x2f, // 0x19
+ EfiKeyD2, // 'w', 'W', 0x11, // 0x1A
+ EfiKeyB2, // 'x', 'X', 0x2d, // 0x1B
+ EfiKeyD6, // 'y', 'Y', 0x15, // 0x1C
+ EfiKeyB1, // 'z', 'Z', 0x2c, // 0x1D
+ EfiKeyE1, // '1', '!', 0x02, // 0x1E
+ EfiKeyE2, // '2', '@', 0x03, // 0x1F
+ EfiKeyE3, // '3', '#', 0x04, // 0x20
+ EfiKeyE4, // '4', '$', 0x05, // 0x21
+ EfiKeyE5, // '5', '%', 0x06, // 0x22
+ EfiKeyE6, // '6', '^', 0x07, // 0x23
+ EfiKeyE7, // '7', '&', 0x08, // 0x24
+ EfiKeyE8, // '8', '*', 0x09, // 0x25
+ EfiKeyE9, // '9', '(', 0x0a, // 0x26
+ EfiKeyE10, // '0', ')', 0x0b, // 0x27
+ EfiKeyEnter,// 0x0d, 0x0d, 0x1c, // 0x28 Enter
+ EfiKeyEsc, // 0x00, 0x00, 0x01, // 0x29 Esc
+ EfiKeyBackSpace, // 0x08, 0x08, 0x0e, // 0x2A Backspace
+ EfiKeyTab, // 0x09, 0x09, 0x0f, // 0x2B Tab
+ EfiKeySpaceBar, // ' ', ' ', 0x39, // 0x2C Spacebar
+ EfiKeyE11, // '-', '_', 0x0c, // 0x2D
+ EfiKeyE12, // '=', '+', 0x0d, // 0x2E
+ EfiKeyD11, // '[', '{', 0x1a, // 0x2F
+ EfiKeyD12, // ']', '}', 0x1b, // 0x30
+ EfiKeyD13, // '\\', '|', 0x2b, // 0x31
+ EfiKeyC12, // '\\', '|', 0x2b, // 0x32 Keyboard Non-US # and ~
+ EfiKeyC10, // ';', ':', 0x27, // 0x33
+ EfiKeyC11, // '\'', '"', 0x28, // 0x34
+ EfiKeyE0, // '`', '~', 0x29, // 0x35 Keyboard Grave Accent and Tlide
+ EfiKeyB8, // ',', '<', 0x33, // 0x36
+ EfiKeyB9, // '.', '>', 0x34, // 0x37
+ EfiKeyB10, // '/', '?', 0x35, // 0x38
+ EfiKeyCapsLock, // 0x00, 0x00, 0x00, // 0x39 CapsLock
+ EfiKeyF1, // 0x00, 0x00, 0x3b, // 0x3A
+ EfiKeyF2, // 0x00, 0x00, 0x3c, // 0x3B
+ EfiKeyF3, // 0x00, 0x00, 0x3d, // 0x3C
+ EfiKeyF4, // 0x00, 0x00, 0x3e, // 0x3D
+ EfiKeyF5, // 0x00, 0x00, 0x3f, // 0x3E
+ EfiKeyF6, // 0x00, 0x00, 0x40, // 0x3F
+ EfiKeyF7, // 0x00, 0x00, 0x41, // 0x40
+ EfiKeyF8, // 0x00, 0x00, 0x42, // 0x41
+ EfiKeyF9, // 0x00, 0x00, 0x43, // 0x42
+ EfiKeyF10, // 0x00, 0x00, 0x44, // 0x43
+ EfiKeyF11, // 0x00, 0x00, 0x85, // 0x44 F11
+ EfiKeyF12, // 0x00, 0x00, 0x86, // 0x45 F12
+ EfiKeyPrint, // 0x00, 0x00, 0x00, // 0x46 PrintScreen
+ EfiKeySLck, // 0x00, 0x00, 0x00, // 0x47 Scroll Lock
+ EfiKeyPause, // 0x00, 0x00, 0x00, // 0x48 Pause
+ EfiKeyIns, // 0x00, 0x00, 0x52, // 0x49
+ EfiKeyHome, // 0x00, 0x00, 0x47, // 0x4A
+ EfiKeyPgUp, // 0x00, 0x00, 0x49, // 0x4B
+ EfiKeyDel, // 0x00, 0x00, 0x53, // 0x4C
+ EfiKeyEnd, // 0x00, 0x00, 0x4f, // 0x4D
+ EfiKeyPgDn, // 0x00, 0x00, 0x51, // 0x4E
+ EfiKeyRightArrow, // 0x00, 0x00, 0x4d, // 0x4F
+ EfiKeyLeftArrow, // 0x00, 0x00, 0x4b, // 0x50
+ EfiKeyDownArrow, // 0x00, 0x00, 0x50, // 0x51
+ EfiKeyUpArrow, // 0x00, 0x00, 0x48, // 0x52
+ EfiKeyNLck, // 0x00, 0x00, 0x00, // 0x53 NumLock
+ EfiKeySlash, // '/', '/', 0x35, // 0x54
+ EfiKeyAsterisk, // '*', '*', 0x37, // 0x55
+ EfiKeyMinus, // '-', '-', 0x4a, // 0x56
+ EfiKeyPlus, // '+', '+', 0x4e, // 0x57
+ EfiKeyEnter, // 0x0d, 0x0d, 0x1c, // 0x58
+ EfiKeyOne, // '1', '1', 0x02, // 0x59
+ EfiKeyTwo, // '2', '2', 0x03, // 0x5A
+ EfiKeyThree, // '3', '3', 0x04, // 0x5B
+ EfiKeyFour, // '4', '4', 0x05, // 0x5C
+ EfiKeyFive, // '5', '5', 0x06, // 0x5D
+ EfiKeySix, // '6', '6', 0x07, // 0x5E
+ EfiKeySeven, // '7', '7', 0x08, // 0x5F
+ EfiKeyEight, // '8', '8', 0x09, // 0x60
+ EfiKeyNine, // '9', '9', 0x0a, // 0x61
+ EfiKeyZero, // '0', '0', 0x0b, // 0x62
+ EfiKeyPeriod, // '.', '.', 0x53, // 0x63
+ EfiKeyD13, // '\\', '|', 0x2b, // 0x64 Keyboard Non-US \ and |
+ 0, // 0x00, 0x00, 0x00, // 0x65 Keyboard Application
+ 0, // 0x00, 0x00, 0x00, // 0x66 Keyboard Power
+ 0, // '=' , '=', 0x0d // 0x67 Keypad =
+
+ 0, // 0x00, 0x00, 0x08, // 0x68 F13
+ 0, // 0x00, 0x00, 0x10, // 0x69 F14
+ 0, // 0x00, 0x00, 0x18, // 0x6A F15
+ 0, // 0x00, 0x00, 0x20, // 0x6B F16
+ 0, // 0x00, 0x00, 0x28, // 0x6C F17
+ 0, // 0x00, 0x00, 0x30, // 0x6D F18
+ 0, // 0x00, 0x00, 0x38, // 0x6E F19
+ 0, // 0x00, 0x00, 0x40, // 0x6F F20
+ 0, // 0x00, 0x00, 0x48, // 0x70 F21
+ 0, // 0x00, 0x00, 0x50, // 0x71 F22
+ 0, // 0x00, 0x00, 0x57, // 0x72 F23
+ 0, // 0x00, 0x00, 0x5F, // 0x73 F24
+
+ 0, // 0x00, 0x00, 0x00, // 0x74
+ 0, // 0x00, 0x00, 0x00, // 0x75
+ 0, // 0x00, 0x00, 0x00, // 0x76
+ 0, // 0x00, 0x00, 0x00, // 0x77
+ 0, // 0x00, 0x00, 0x00, // 0x78
+ 0, // 0x00, 0x00, 0x00, // 0x79
+ 0, // 0x00, 0x00, 0x00, // 0x7A
+ 0, // 0x00, 0x00, 0x00, // 0x7B
+ 0, // 0x00, 0x00, 0x00, // 0x7C
+ 0, // 0x00, 0x00, 0x00, // 0x7D
+ 0, // 0x00, 0x00, 0x00, // 0x7E
+ 0, // 0x00, 0x00, 0x00, // 0x7F
+ 0, // 0x00, 0x00, 0x00, // 0x80
+ 0, // 0x00, 0x00, 0x00, // 0x81
+ 0, // 0x00, 0x00, 0x00, // 0x82
+ 0, // 0x00, 0x00, 0x00, // 0x83
+ 0, // 0x00, 0x00, 0x00, // 0x84
+ 0, // '.', 0x00, 0x6D, // 0x85
+ 0, // '=', 0x00, 0x00, // 0x86
+ EfiKeyB0, // 0x00, 0x00, 0x51, // 0x87
+ 0, // '\\', 0x00, 0x13, // 0x88
+ EfiKeyD13, // 0xA5, 0x00, 0x6A, // 0x89 Yen Symbol
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdGetControllerName
+//
+// Description: USB EFI keyboard driver driver protocol function that
+// returns the keyboard controller name.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+UsbKbdGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBKeyboard
+//
+// Description: Initialize USB Keyboard device and all private data structures.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS or EFI_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBKeyboard()
+{
+ InitUSBKeyBuffer(&(gUsbKeyboardData->KeyboardBuffer));
+ InitUSBKeyCharBuffer();
+ gUsbData->EfiKeyboardBuffer = &gUsbKeyboardData->KeyboardBuffer;
+
+ gUsbKeyboardData->LeftCtrlOn = 0;
+ gUsbKeyboardData->LeftAltOn = 0;
+ gUsbKeyboardData->LeftShiftOn = 0;
+ gUsbKeyboardData->RightCtrlOn = 0;
+ gUsbKeyboardData->RightAltOn = 0;
+ gUsbKeyboardData->RightShiftOn = 0;
+ gUsbKeyboardData->SysRqOn = 0;
+ gUsbKeyboardData->MenuOn = 0;
+ gUsbKeyboardData->LeftLogoOn = 0;
+ gUsbKeyboardData->RightLogoOn = 0;
+ gUsbKeyboardData->NumLockOn = 0;
+ gUsbKeyboardData->CapsOn = 0;
+ gUsbKeyboardData->ScrLkOn = 0;
+ //(EIP91889-)>
+// gUsbKeyboardData->ToggleState =0;
+// SetKeyLED();
+ //<(EIP91889-)
+ gBS->SetMem(gUsbKeyboardData->LastKeyCodeArray, sizeof(UINT8)*8, 0);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KeypressCallback
+//
+// Description: This routine is called every time the keyboard data is updated
+//
+// Input: HcStruc, DevInfo, fpBuf2 always NULL
+// Buf1 - Pointer to 8 bytes USB data array
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KeypressCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Buf1,
+ UINT8* Buf2)
+
+{
+
+ UINT8 *CurKeyCodeBuffer;
+ UINT8 *OldKeyCodeBuffer;
+ UINT8 CurModifierMap;
+ UINT8 OldModifierMap;
+ UINT8 i;
+ UINT8 j;
+ BOOLEAN Down;
+ BOOLEAN KeyRelease,KeyPress;
+ UINT8 SavedTail;
+ USB_KEY UsbKey;
+ UINT8 NewRepeatKey = 0;
+ UINT8 *fPtr, *fPtrEnd;
+
+ OldKeyCodeBuffer = gUsbKeyboardData->LastKeyCodeArray;
+
+ if(gUsbData->aKBCUsbDataBufferHead == gUsbData->aKBCUsbDataBufferTail) {
+ return EFI_SUCCESS;
+ }
+
+ fPtrEnd = gUsbData->aKBCUsbDataBufferStart +
+ sizeof (gUsbData->aKBCUsbDataBufferStart);
+
+ fPtr = gUsbData->aKBCUsbDataBufferTail;
+ CurKeyCodeBuffer = fPtr;
+ fPtr+=8;
+
+ //
+ // Check for buffer end condition
+ //
+ if(fPtr >= fPtrEnd)
+ fPtr = gUsbData->aKBCUsbDataBufferStart;
+ gUsbData->aKBCUsbDataBufferTail = fPtr;
+
+ //
+ // checks for new key stroke.
+ // if no new key got, return immediately.
+ //
+ for (i = 0; i < 8; i ++) {
+ if(OldKeyCodeBuffer[i] != CurKeyCodeBuffer[i]) {
+ break;
+ }
+ }
+
+ if(i == 8) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Parse the modifier key
+ //
+ CurModifierMap = CurKeyCodeBuffer[0];
+ OldModifierMap = OldKeyCodeBuffer[0];
+
+ //
+ // handle modifier key's pressing or releasing situation.
+ //
+ for (i = 0; i < 8; i ++) {
+ if ((CurModifierMap & KB_Mod[i].Mask) !=
+ (OldModifierMap & KB_Mod[i].Mask)) {
+ //
+ // if current modifier key is up, then
+ // CurModifierMap & KB_Mod[i].Mask = 0;
+ // otherwize it is a non-zero value.
+ // Inserts the pressed modifier key into key buffer.
+ //
+ Down = (UINT8)(CurModifierMap & KB_Mod[i].Mask);
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),KB_Mod[i].Key,Down);
+ }
+ }
+
+ //
+ // handle normal key's releasing situation
+ //
+ KeyRelease = FALSE;
+ for (i = 2; i < 8; i ++) {
+
+ if(!USBKBD_VALID_KEYCODE(OldKeyCodeBuffer[i])) {
+ continue;
+ }
+
+ KeyRelease = TRUE;
+ for (j = 2; j < 8; j ++) {
+
+ if(!USBKBD_VALID_KEYCODE(CurKeyCodeBuffer[j])) {
+ continue;
+ }
+
+ if (OldKeyCodeBuffer[i] == CurKeyCodeBuffer[j]) {
+ KeyRelease = FALSE;
+ break;
+ }
+ }
+
+ if (KeyRelease) {
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),OldKeyCodeBuffer[i],0);
+ //
+ // the original reapeat key is released.
+ //
+ if (OldKeyCodeBuffer[i] == gUsbData->RepeatKey) {
+ gUsbData->RepeatKey = 0;
+ }
+ }
+ }
+ //
+ // handle normal key's pressing situation
+ //
+ KeyPress = FALSE;
+ for (i = 2; i < 8; i ++) {
+ if(!USBKBD_VALID_KEYCODE(CurKeyCodeBuffer[i])) {
+ continue;
+ }
+
+ KeyPress = TRUE;
+ for (j = 2; j < 8; j ++) {
+ if(!USBKBD_VALID_KEYCODE(OldKeyCodeBuffer[j])) {
+ continue;
+ }
+
+ if (CurKeyCodeBuffer[i] == OldKeyCodeBuffer[j]) {
+ KeyPress = FALSE;
+ break;
+ }
+ }
+
+ if(KeyPress) {
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),CurKeyCodeBuffer[i],1);
+ //
+ // NumLock, ScrollLock or CapsLock pressed
+ //
+ if(CurKeyCodeBuffer[i] == 0x53 ||
+ CurKeyCodeBuffer[i] == 0x47 ||
+ CurKeyCodeBuffer[i] == 0x39) {
+ gUsbData->RepeatKey = 0;
+ }
+ else
+ {
+ NewRepeatKey = CurKeyCodeBuffer[i];
+ //
+ // do not repeat the original repeated key
+ //
+ gUsbData->RepeatKey = 0;
+ }
+ }
+ }
+
+ //
+ // Update LastKeycodeArray[] buffer in the
+ // Usb Keyboard Device data structure.
+ //
+ for (i = 0; i < 8; i ++) {
+ gUsbKeyboardData->LastKeyCodeArray[i] = CurKeyCodeBuffer[i];
+ }
+
+ //
+ // pre-process KeyboardBuffer, pop out the ctrl,alt,del key in sequence
+ // and judge whether it will invoke reset event.
+ //
+ SavedTail = gUsbKeyboardData->KeyboardBuffer.bTail;
+ i = gUsbKeyboardData->KeyboardBuffer.bHead;
+ KeyProcessed=FALSE;
+ while(i != SavedTail) {
+ RemoveKeyCode(&(gUsbKeyboardData->KeyboardBuffer),&UsbKey);
+ //(EIP84455+)>
+ switch(UsbKey.KeyCode) {
+ case 0xe0:
+ if(UsbKey.Down)
+ gUsbKeyboardData->LeftCtrlOn = 1;
+ break;
+
+ case 0xe4:
+ if(UsbKey.Down)
+ gUsbKeyboardData->RightCtrlOn = 1;
+ break;
+
+ case 0xe2:
+ if(UsbKey.Down)
+ gUsbKeyboardData->LeftAltOn = 1;
+ break;
+ case 0xe6:
+ if(UsbKey.Down)
+ gUsbKeyboardData->RightAltOn = 1;
+ break;
+ //<(EIP84455+)
+ case 0x4c: // Del Key Code
+ case 0x63:
+ if(UsbKey.Down) {
+ if((gUsbKeyboardData->LeftCtrlOn | gUsbKeyboardData->RightCtrlOn) && (gUsbKeyboardData->LeftAltOn | gUsbKeyboardData->RightAltOn)) {
+ gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ //
+ // insert the key back to the buffer.
+ // so the key sequence will not be destroyed.
+ //
+ InsertKeyCode(&(gUsbKeyboardData->KeyboardBuffer),
+ UsbKey.KeyCode,
+ UsbKey.Down);
+
+ i = gUsbKeyboardData->KeyboardBuffer.bHead;
+
+ }
+ KeyProcessed=TRUE;
+ //
+ // If have new key pressed, update the RepeatKey value
+ //
+ if(NewRepeatKey != 0) {
+ gUsbData->RepeatKey = NewRepeatKey;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KeyrepeatCallback
+//
+// Description: This routine is called every time the key repeat is requested
+//
+// Input: All input pointers are NULL, need them for callback function
+// parameters list
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KeyrepeatCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Buf1,
+ UINT8* Buf2)
+
+{
+ //
+ // Do nothing when there is no repeat key.
+ //
+ if(gUsbData->RepeatKey) {
+ //
+ // Inserts one Repeat key into keyboard buffer,
+ //
+ InsertKeyCode(
+ &(gUsbKeyboardData->KeyboardBuffer),
+ gUsbData->RepeatKey,
+ 1
+ );
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBParseKey
+//
+// Description: Retrieves a key character after parsing the raw data
+// in keyboard buffer.
+//
+// Input: KeyChar - pointer to the key character after key parsing.
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS USBParseKey (
+ UINT8 *KeyChar)
+{
+ USB_KEY UsbKey;
+
+ *KeyChar = 0;
+
+ while (!IsUSBKeyboardBufferEmpty(&(gUsbKeyboardData->KeyboardBuffer))) { //(EIP83295)
+ //
+ // pops one raw data off.
+ //
+ RemoveKeyCode(&(gUsbKeyboardData->KeyboardBuffer),&UsbKey);
+
+ //
+ // Key Release
+ //
+ if (!UsbKey.Down) {
+ switch(UsbKey.KeyCode) {
+ case 0xe0: // fall through
+ gUsbKeyboardData->LeftCtrlOn = 0;
+ break;
+
+ case 0xe4:
+ gUsbKeyboardData->RightCtrlOn = 0;
+ break;
+
+ case 0xe1: // fall through
+ gUsbKeyboardData->LeftShiftOn = 0;
+ break;
+ case 0xe5:
+ gUsbKeyboardData->RightShiftOn = 0;
+ break;
+
+ case 0xe2: // fall through
+ gUsbKeyboardData->LeftAltOn = 0;
+ break;
+ case 0xe6:
+ gUsbKeyboardData->RightAltOn = 0;
+ break;
+
+ case 0xe3: // fall through
+ gUsbKeyboardData->LeftLogoOn = 0;
+ break;
+ case 0xe7:
+ gUsbKeyboardData->RightLogoOn = 0;
+ break;
+
+ case 0x46:
+ gUsbKeyboardData->SysRqOn = 0;
+ break;
+
+ case 0x65:
+ gUsbKeyboardData->MenuOn = 0;
+ break;
+
+ default:
+ break;
+ }
+ continue;
+ }
+
+ //
+ // Analyzes key pressing situation
+ //
+ switch (UsbKey.KeyCode) {
+ case 0xe0: // fall through
+ gUsbKeyboardData->LeftCtrlOn = 1;
+ continue;
+ case 0xe4:
+ gUsbKeyboardData->RightCtrlOn = 1;
+ continue;
+
+ case 0xe1: // fall through
+ gUsbKeyboardData->LeftShiftOn = 1;
+ continue;
+ case 0xe5:
+ gUsbKeyboardData->RightShiftOn = 1;
+ continue;
+
+ case 0xe2: // fall through
+ gUsbKeyboardData->LeftAltOn = 1;
+ continue;
+ case 0xe6:
+ gUsbKeyboardData->RightAltOn = 1;
+ continue;
+
+ case 0xe3: // fall through
+ gUsbKeyboardData->LeftLogoOn = 1;
+ continue;
+ case 0xe7:
+ gUsbKeyboardData->RightLogoOn = 1;
+ continue;
+ //
+ // SysRq Key
+ //
+ case 0x46:
+ gUsbKeyboardData->SysRqOn = 1;
+ continue;
+ //
+ // Menu Key
+ //
+ case 0x65:
+ gUsbKeyboardData->MenuOn = 1;
+ continue;
+
+ case 0x53:
+ gUsbKeyboardData->NumLockOn ^= 1;
+ SetKeyLED();
+ break;
+
+ case 0x39:
+ gUsbKeyboardData->CapsOn ^= 1;
+ SetKeyLED();
+ break;
+
+ case 0x47:
+ gUsbKeyboardData->ScrLkOn ^= 1;
+ SetKeyLED();
+ break;
+
+ //
+ // PrintScreen,ScrollLock,Pause,Application,Power
+ // keys are not valid EFI key
+ //
+ case 0x66:
+ continue;
+
+ default:
+ break;
+ }
+
+ //
+ // When encountered Del Key...
+ //
+ if (UsbKey.KeyCode == 0x4c || UsbKey.KeyCode == 0x63) {
+ if((gUsbKeyboardData->LeftCtrlOn | gUsbKeyboardData->RightCtrlOn) && (gUsbKeyboardData->LeftAltOn | gUsbKeyboardData->RightAltOn)) {
+ gRT->ResetSystem(EfiResetWarm, EFI_SUCCESS, 0, NULL);
+ }
+ }
+
+ *KeyChar = UsbKey.KeyCode;
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_READY;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKeyCodeToEFIScanCode
+//
+// Description: Converts USB Keyboard code to EFI Scan Code
+//
+// Input: KeyChar - Indicates the key code that will be interpreted.
+// Key - A pointer to a buffer that is filled in with
+// the keystroke information for the key that
+// was pressed.
+//
+// Output: EFI_SUCCESS, EFI_NOT_READY
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+USBKeyCodeToEFIScanCode(
+ UINT8 KeyChar,
+ EFI_INPUT_KEY *Key
+)
+{
+ UINT8 Index;
+
+ if (!USBKBD_VALID_KEYCODE(KeyChar)) {
+ return EFI_NOT_READY;
+ }
+
+ //
+ // valid USB Key Code starts from 4
+ //
+ Index = (UINT8)(KeyChar - 4);
+
+ if (Index >= USB_KEYCODE_MAX_MAKE){
+ return EFI_NOT_READY;
+ }
+
+ Key->ScanCode = KeyConvertionTable[Index][0];
+
+ if (gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->RightShiftOn) {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][2];
+
+ } else {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][1];
+ }
+
+ if ((gUsbKeyboardData->NumLockOn == 0) && gUsbKeyboardData->LeftShiftOn == 0 && gUsbKeyboardData->RightShiftOn == 0 && (Index == 0x5d-4)) {
+ Key->UnicodeChar = 0;
+ }
+
+ if (gUsbKeyboardData->CapsOn) {
+
+ if (Key->UnicodeChar >= 'a' && Key->UnicodeChar <= 'z') {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][2];
+
+ } else if (Key->UnicodeChar >= 'A' && Key->UnicodeChar <= 'Z') {
+
+ Key->UnicodeChar = KeyConvertionTable[Index][1];
+
+ }
+ }
+
+ if (KeyChar >= 0x59 && KeyChar <=0x63 && Key->ScanCode != SCAN_NULL) {
+
+ if (gUsbKeyboardData->NumLockOn && !(gUsbKeyboardData->LeftShiftOn | gUsbKeyboardData->RightShiftOn)) {
+
+ Key->ScanCode = SCAN_NULL;
+
+ } else {
+
+ Key->UnicodeChar = 0x00;
+ }
+ }
+ //
+ // CapsLock, NumLock and ScrLock must be reported as valid keys even though their
+ // ScanCode and UnicodeChar are zeroes
+ //
+// if (KeyChar == 0x53 || KeyChar == 0x39 || KeyChar == 0x47 ) return EFI_SUCCESS;
+
+ if (KeyChar == 0x53 || KeyChar == 0x39 || KeyChar == 0x47 || KeyChar == 0x48 ) {
+ return EFI_SUCCESS;
+ }
+
+ if(Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBKeyBuffer
+//
+// Description: Initialize USB Keyboard Buffer.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBKeyBuffer(USB_KB_BUFFER *KeyboardBuffer)
+{
+ EfiZeroMem(KeyboardBuffer,sizeof(USB_KB_BUFFER));
+
+ KeyboardBuffer->bHead = KeyboardBuffer->bTail;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyboardBufferEmpty
+//
+// Description: Check whether USB Keyboard buffer is empty.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+//
+// Output: TRUE if buffer is empty, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP83295)>
+BOOLEAN
+IsUSBKeyboardBufferEmpty(USB_KB_BUFFER *KeyboardBuffer)
+{
+ //
+ // meet FIFO empty condition
+ //
+ return (BOOLEAN)(KeyboardBuffer->bHead == KeyboardBuffer->bTail);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyboardBufferFull
+//
+// Description: Check whether USB Keyboard buffer is full.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+//
+// Output: TRUE if buffer is full, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsUSBKeyboardBufferFull(USB_KB_BUFFER *KeyboardBuffer)
+{
+ return (BOOLEAN)(((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
+ KeyboardBuffer->bHead);
+}
+ //<(EIP83295)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InsertKeyCode
+//
+// Description: Inserts a key code into keyboard buffer.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertKeyCode(
+ USB_KB_BUFFER *KeyboardBuffer,
+ UINT8 Key,
+ UINT8 Down
+ )
+{
+ USB_KEY UsbKey;
+
+ if(KeyProcessed && Down) {
+ UsbCheckKeyNotify(Key);
+ }
+
+ //
+ // if keyboard buffer is full, throw the
+ // first key out of the keyboard buffer.
+ //
+ if (IsUSBKeyboardBufferFull (KeyboardBuffer)) { //(EIP83295)
+ RemoveKeyCode(KeyboardBuffer,&UsbKey);
+ }
+
+ KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = Key;
+ KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = Down;
+
+ //
+ // adjust the tail pointer of the FIFO keyboard buffer.
+ //
+ KeyboardBuffer->bTail = (UINT8)((KeyboardBuffer->bTail + 1)
+ % (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveKeyCode
+//
+// Description: Removes a key code from the keyboard buffer.
+//
+// Input: KeyboardBuffer - pointer to USB Keyboard Buffer.
+// UsbKey - pointer to buffer that contains usb key code.
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveKeyCode(
+ USB_KB_BUFFER *KeyboardBuffer,
+ USB_KEY *UsbKey
+)
+{
+ if (IsUSBKeyboardBufferEmpty (KeyboardBuffer)) { //(EIP83295)
+ return EFI_DEVICE_ERROR;
+ }
+
+ UsbKey->KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
+ UsbKey->Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
+
+ //
+ // adjust the head pointer of the FIFO keyboard buffer.
+ //
+ KeyboardBuffer->bHead = (UINT8)((KeyboardBuffer->bHead + 1) %
+ (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBKeyCharBuffer
+//
+// Description: Initialize USB Keyboard Buffer for Keyboard ASCII data.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBKeyCharBuffer()
+{
+ EfiZeroMem((VOID*)&(gUsbKeyboardData->KeyChar[0]),sizeof(UINT8) * MAX_KEY_ALLOWED + 1 );
+
+ gUsbKeyboardData->bHead = gUsbKeyboardData->bTail;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyCharEmpty
+//
+// Description: Check whether USB Keyboard ASCII data buffer is empty.
+//
+// Input: None
+//
+// Output: TRUE if buffer is empty, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsUSBKeyCharEmpty()
+{
+ //
+ // meet FIFO empty condition
+ //
+ return (BOOLEAN)(gUsbKeyboardData->bHead == gUsbKeyboardData->bTail);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsUSBKeyboardBufferFull
+//
+// Description: Check whether USB Keyboard ASCII data buffer is full.
+//
+// Input: None
+//
+// Output: TRUE if buffer is full, FALSE otherwise
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsUSBKeyCharFull()
+{
+ return (BOOLEAN)(((gUsbKeyboardData->bTail + 1) % (MAX_KEY_ALLOWED + 1)) ==
+ gUsbKeyboardData->bHead);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InsertKeyCode
+//
+// Description: Inserts a USB Keyboard ASCII data into keyboard buffer.
+//
+// Input: UINT8 KeyChar - USB Key Data
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InsertKeyChar(
+ UINT8 KeyChar
+ )
+{
+ UINT8 TempKey;
+
+ //
+ // if keyboard buffer is full, throw the
+ // first key out of the keyboard buffer.
+ //
+ if (IsUSBKeyCharFull()) {
+ RemoveKeyChar(&TempKey);
+ }
+
+ gUsbKeyboardData->KeyChar[gUsbKeyboardData->bTail] = KeyChar;
+
+ //
+ // adjust the tail pointer of the FIFO keyboard buffer.
+ //
+ gUsbKeyboardData->bTail = (UINT8)((gUsbKeyboardData->bTail + 1)
+ % (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveKeyCode
+//
+// Description: Removes a USB Keyboard ASCII data from the keyboard buffer.
+//
+// Input: UINT8 KeyChar - USB Keyboard Data
+//
+// Output: EFI_SUCCESS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveKeyChar(
+ UINT8 *KeyChar
+)
+{
+ if (IsUSBKeyCharEmpty()) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ *KeyChar = gUsbKeyboardData->KeyChar[gUsbKeyboardData->bHead];
+
+ //
+ // adjust the head pointer of the FIFO keyboard buffer.
+ //
+ gUsbKeyboardData->bHead = (UINT8)((gUsbKeyboardData->bHead + 1) %
+ (MAX_KEY_ALLOWED + 1)) ;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SetKeyLED
+//
+// Description: Sets USB Keyboard LED state.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS
+//
+// Notes: UsbKbd can be NULL; in this case LEDs on all keyboards will
+// be refreshed. This is useful when the new keyboard is connected
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SetKeyLED()
+{
+ LED_MAP Led;
+ URP_STRUC Urp; // USB Request Packet
+
+ //
+ // Set each field in Led map.
+ //
+ if (gUsbKeyboardData)
+ {
+ Led.NumLock = (UINT8)gUsbKeyboardData->NumLockOn;
+ Led.CapsLock = (UINT8)gUsbKeyboardData->CapsOn;
+ Led.ScrLock = (UINT8)gUsbKeyboardData->ScrLkOn;
+ Led.Resrvd = 0;
+ Urp.ApiData.KbLedsData.fpLedMap = (UINT32)(UINTN)&Led;
+ }
+ else
+ {
+ Urp.ApiData.KbLedsData.fpLedMap = 0;
+ }
+ //
+ // Lighten up LEDs.
+ //
+ Urp.bFuncNumber = USB_API_LIGHTEN_KEYBOARD_LEDS;
+ Urp.bSubFunc = 0;
+
+ InvokeUsbApi(&Urp);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SupportedUSBKeyboard
+//
+// Description: Verifies if usb keyboard support can be installed on a device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SupportedUSBKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR Desc;
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ if( EFI_ERROR(Status))
+ return Status;
+
+ Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &Desc );
+ if(EFI_ERROR(Status))
+ return EFI_UNSUPPORTED;
+
+ if ( Desc.InterfaceClass == BASE_CLASS_HID &&
+ Desc.InterfaceSubClass == SUB_CLASS_BOOT_DEVICE &&
+ Desc.InterfaceProtocol == PROTOCOL_KEYBOARD)
+ {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+#if CLEAR_USB_KB_BUFFER_AT_READYTOBOOT
+// <AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ClearUsbKbBuffer
+//
+// Description:
+// This function clear USB KB buffers
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - pointer to event context
+//
+// Output:
+// VOID
+//
+// Modified:
+//
+// Referrals:
+//
+// Notes:
+//
+//--------------------------------------------------------------------------
+// <AMI_PHDR_END>
+
+EFI_STATUS
+ClearUsbKbBuffer(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ InitUSBKeyBuffer(&(gUsbKeyboardData->KeyboardBuffer));
+ gUsbKeyboardData->CurKeyChar = 0;
+
+ // Clear KB buffers in USB_GLOBAL_DATA
+ EfiZeroMem(gUsbData->aKBCCharacterBufferStart, 128);
+ gUsbData->fpKBCCharacterBufferHead = gUsbData->aKBCCharacterBufferStart;
+ gUsbData->fpKBCCharacterBufferTail = gUsbData->aKBCCharacterBufferStart;
+
+ EfiZeroMem(gUsbData->aKBCScanCodeBufferStart, 16);
+ gUsbData->fpKBCScanCodeBufferPtr = gUsbData->aKBCScanCodeBufferStart;
+
+ EfiZeroMem(gUsbData->aKBCUsbDataBufferStart, 32);
+ gUsbData->aKBCUsbDataBufferHead = gUsbData->aKBCUsbDataBufferStart;
+ gUsbData->aKBCUsbDataBufferTail = gUsbData->aKBCUsbDataBufferStart;
+
+ EfiZeroMem(gUsbData->aKBInputBuffer, 16);
+
+ pBS->CloseEvent(Event);
+
+ return EFI_SUCCESS;
+}
+#endif
+
+
+ //(EIP38434+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallUSBKeyboard
+//
+// Description: Installs SimpleTxtIn protocol on a given handle
+//
+// Input: Controller - controller handle to install protocol on.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUSBKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ DEV_INFO* Dev_info,
+ EFI_USB_IO_PROTOCOL *UsbIo
+)
+{
+ EFI_STATUS Status;
+ USB_KB_DEV* UsbKbd;
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: InstallUSBKeyboard: starting...\n");
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->AllocatePool( EfiBootServicesData,
+ sizeof(USB_KB_DEV), &UsbKbd ));
+ EfiZeroMem(UsbKbd, sizeof(USB_KB_DEV));
+
+ UsbKbd->dev_info = Dev_info;
+ //
+ // Initialize UsbKbd
+ //
+ ASSERT_EFI_ERROR(Status);
+
+ UsbKbd->io = UsbIo;
+ UsbKbd->Signature = USB_KB_DEV_SIGNATURE;
+ UsbKbd->SimpleInput.Reset = UsbKbdReset;
+ UsbKbd->SimpleInput.ReadKeyStroke = UsbKbdReadKeyStroke;
+
+#if (CORE_REVISION >= 0x3)
+ UsbKbd->SimpleInputEx.Reset = UsbKbdResetEx;
+ UsbKbd->SimpleInputEx.ReadKeyStrokeEx = UsbKbdReadKeyStrokeEx;
+ UsbKbd->SimpleInputEx.SetState = UsbKbdSetState;
+ UsbKbd->SimpleInputEx.RegisterKeyNotify = UsbKbdRegisterKeyNotify;
+ UsbKbd->SimpleInputEx.UnregisterKeyNotify = UsbKbdUnregisterKeyNotify;
+
+ UsbKbd->KeycodeInput.Reset = UsbKbdResetEx;
+ UsbKbd->KeycodeInput.ReadEfikey = UsbKbdReadEfiKey;
+ UsbKbd->KeycodeInput.SetState = UsbKbdSetState;
+ UsbKbd->KeycodeInput.RegisterKeyNotify = UsbKbdRegisterKeyNotify;
+ UsbKbd->KeycodeInput.UnregisterKeyNotify = UsbKbdUnregisterKeyNotify;
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbKbdWaitForKey,
+ UsbKbd,
+ &UsbKbd->SimpleInputEx.WaitForKeyEx));
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbKbdWaitForKey,
+ UsbKbd,
+ &UsbKbd->KeycodeInput.WaitForKeyEx));
+
+#endif
+
+#if CLEAR_USB_KB_BUFFER_AT_READYTOBOOT
+ // Create event on ready to boot to clear KB buffer
+ VERIFY_EFI_ERROR(
+ Status = pBS->CreateEvent(
+ EFI_EVENT_SIGNAL_READY_TO_BOOT,
+ TPL_NOTIFY,
+ ClearUsbKbBuffer,
+ NULL,
+ &gClearUsbKbBufferEvent));
+#endif
+
+ // Setup the WaitForKey event
+ //
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbKbdWaitForKey,
+ UsbKbd,
+ &UsbKbd->SimpleInput.WaitForKey));
+
+ //
+ // Install protocol interfaces for the USB keyboard device:
+ //
+ // Install simple txt in protocol interface
+ // for the usb keyboard device.
+ // Usb keyboard is a hot plug device, and expected to work immediately
+ // when plugging into system, so a HotPlugDeviceGuid is installed onto
+ // the usb keyboard device handle, to distinguish it from other conventional
+ // console devices.
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (&Controller,
+ &gEfiHotPlugDeviceGuid, NULL,
+ &gEfiSimpleTextInProtocolGuid,&UsbKbd->SimpleInput,
+#if (CORE_REVISION >= 0x3)
+ &gEfiSimpleTextInExProtocolGuid,&UsbKbd->SimpleInputEx,
+ &gAmiEfiKeycodeProtocolGuid,&UsbKbd->KeycodeInput,
+#endif
+ NULL
+ );
+
+ ASSERT_EFI_ERROR (Status);
+
+ USB_DEBUG(DEBUG_USBHC_LEVEL,
+ "USB: InstallUSBKeyboard: done (%x).\n", Status);
+
+ SetKeyLED();
+
+ return Status;
+}
+ //<(EIP38434+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UninstallUSBKeyboard
+//
+// Description: Uninstalls SimpleTxtIn protocol on a given handle
+//
+// Input: Controller - controller handle.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UninstallUSBKeyboard(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+ EFI_STATUS Status;
+ USB_KB_DEV* UsbKbd=0;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL *SimpleIn;
+ DLINK *ListPtr = NULL; //(EIP100370+)
+ KEY_WAITING_RECORD *UsbKeyIn = NULL; //(EIP100370+)
+
+
+ Status = pBS->OpenProtocol( Controller,
+ &gEfiSimpleTextInProtocolGuid,
+ (VOID **)&SimpleIn,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+
+ UsbKbd = USB_KB_DEV_FROM_THIS(SimpleIn, SimpleInput);
+
+ //(EIP100370+)>
+#if (CORE_REVISION >= 0x3)
+ ListPtr = mUsbKeyboardData.pHead;
+ while (ListPtr != NULL) {
+ UsbKeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ ListPtr = ListPtr->pNext;
+ if (UsbKbd == UsbKeyIn->UsbKbDev) {
+ DListDelete(&mUsbKeyboardData, &UsbKeyIn->Link);
+ pBS->FreePool(UsbKeyIn);
+ }
+ }
+
+ if (mUsbKeyboardData.Size == 0) {
+ pBS->SetTimer(UsbKeyEvent,
+ TimerCancel,
+ 0);
+ }
+#endif
+ //<(EIP100370+)
+
+ //
+ // Uninstall protocol interfaces for the USB keyboard device
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces ( Controller,
+ &gEfiHotPlugDeviceGuid, NULL,
+ &gEfiSimpleTextInProtocolGuid, &UsbKbd->SimpleInput,
+#if (CORE_REVISION >= 0x3)
+ &gEfiSimpleTextInExProtocolGuid,&UsbKbd->SimpleInputEx,
+ &gAmiEfiKeycodeProtocolGuid,&UsbKbd->KeycodeInput,
+#endif
+ NULL);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ //(EIP38434+)>
+// VERIFY_EFI_ERROR(
+// gBS->CloseProtocol (
+// Controller, &gEfiUsbIoProtocolGuid,
+// This->DriverBindingHandle, Controller));
+ //<(EIP38434+)
+ //
+ // Close the WaitForKey event
+ //
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (UsbKbd->SimpleInput.WaitForKey));
+
+#if (CORE_REVISION >= 0x3)
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (UsbKbd->SimpleInputEx.WaitForKeyEx));
+
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (UsbKbd->KeycodeInput.WaitForKeyEx));
+#endif
+
+ VERIFY_EFI_ERROR(
+ gBS->FreePool(UsbKbd));
+
+ return Status;
+}
+
+
+/***********************************************************************/
+/* */
+/* SimpleTextIn Protocol implementation routines */
+/* */
+/***********************************************************************/
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReset
+//
+// Description: Reset USB keyboard
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ EFI_STATUS Status;
+
+ //
+ // Non Exhaustive reset: only reset private data structures.
+ //
+ if(!ExtendedVerification) {
+ InitUSBKeyBuffer(&(gUsbKeyboardData->KeyboardBuffer));
+ InitUSBKeyCharBuffer();
+
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Exhaustive reset
+ //
+ Status = InitUSBKeyboard();
+ InitUSBKeyCharBuffer();
+ if(EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReadKeyStroke
+//
+// Description: Retrieves the key stroke from the keyboard buffer.
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+)
+{
+ EFI_STATUS Status;
+
+ Status = ReadAndProcessKey(Key, sizeof(EFI_INPUT_KEY));
+ if(Key->UnicodeChar == 0 && Key->ScanCode == SCAN_NULL) {
+ return EFI_NOT_READY;
+ }
+
+ return Status;
+
+}
+
+#if (CORE_REVISION >= 0x3)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdResetEx
+//
+// Description: Reset USB keyboard
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UsbKbdResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+)
+{
+ return UsbKbdReset(0, ExtendedVerification);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReadKeyStrokeEx
+//
+// Description: Retrieves the key stroke from the keyboard buffer.
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UsbKbdReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+)
+{
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return ReadAndProcessKey(KeyData, sizeof(EFI_KEY_DATA));
+}
+
+EFI_STATUS UsbKbdReadEfiKey(
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+
+ if(KeyData == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ Status = ReadAndProcessKey(KeyData, sizeof(AMI_EFI_KEY_DATA));
+ if (Status == EFI_SUCCESS && !(KeyData->KeyState.KeyToggleState & KEY_STATE_EXPOSED)) {
+ KeyData->EfiKeyIsValid = 1;
+ KeyData->PS2ScanCodeIsValid = 1;
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: UsbKbdSetState
+//
+// Description: Set certain state for the input device.
+//
+// Paremeters: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyToggleState - Pointer to the EFI_KEY_TOGGLE_STATE to
+// set the state for the input device.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+)
+{
+ BOOLEAN ChgSL = FALSE;
+ BOOLEAN ChgCL = FALSE;
+ BOOLEAN ChgNL = FALSE;
+
+ if(KeyToggleState == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(*KeyToggleState & TOGGLE_STATE_VALID) ||
+ ((*KeyToggleState & (~(TOGGLE_STATE_VALID | KEY_STATE_EXPOSED |
+ SCROLL_LOCK_ACTIVE | NUM_LOCK_ACTIVE | CAPS_LOCK_ACTIVE)))) ) {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // Set the new modifier's state only if the requested state is different from the
+ // current one.
+ //
+ if((UINT8)*KeyToggleState != gUsbKeyboardData->ToggleState){ //(EIP91889)
+ gUsbKeyboardData->ToggleState = (*KeyToggleState); //(EIP91889+)
+ gUsbKeyboardData->ScrLkOn = (*KeyToggleState & SCROLL_LOCK_ACTIVE)? 1 : 0;
+ gUsbKeyboardData->NumLockOn = (*KeyToggleState & NUM_LOCK_ACTIVE)? 1 : 0;
+ gUsbKeyboardData->CapsOn = (*KeyToggleState & CAPS_LOCK_ACTIVE)? 1 : 0;
+
+ SetKeyLED();
+ }
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ValidateKeyRecord
+//
+// Description: Check for Record is present or Not
+//
+// Paremeters: KEY_WAITING_RECORD - *UsbKeyIn
+//
+// Output: FALSE - If Record is deleted from list
+// TRUE - If Record is present in List
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN
+ValidateKeyRecord (
+ IN KEY_WAITING_RECORD *UsbKeyIn
+)
+{
+ KEY_WAITING_RECORD *TempRecord = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+
+ while ( TempRecord != NULL) {
+ if(TempRecord == UsbKeyIn) {
+ return TRUE;
+ }
+ // go to the next element in the list
+ TempRecord = OUTTER(TempRecord->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: CheckKeyNotify
+//
+// Description: Call the notification function based on the key pressed
+//
+// Paremeters: Key - Key pressed
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UsbCheckKeyNotify(UINT8 KeyChar)
+{
+
+ EFI_INPUT_KEY Key;
+ EFI_STATUS Status;
+ KEY_WAITING_RECORD *UsbKeyIn = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ BOOLEAN KeyScanCodeMatch=FALSE;
+ BOOLEAN KeyUniCodeMatch=FALSE;
+ BOOLEAN ShiftKeyMatch=FALSE;
+ BOOLEAN CtrlKeyMatch=FALSE;
+ BOOLEAN AltKeyMatch=FALSE;
+ BOOLEAN LogoKeyMatch=FALSE;
+ BOOLEAN MenuKeyMatch=FALSE;
+ BOOLEAN SysRqKeyMatch=FALSE;
+ BOOLEAN KeyShiftCodeMatch=FALSE;
+ BOOLEAN KeyToggleKeyMatch=FALSE;
+ BOOLEAN CallBackCalled=FALSE;
+
+ // if the list is empty return the status that was passed in
+ if (UsbKeyIn == NULL)
+ return EFI_SUCCESS;
+
+ EfiZeroMem((VOID*)&Key,sizeof(EFI_INPUT_KEY));
+
+ //
+ // Translate saved ASCII byte into EFI_INPUT_KEY and PS/2 Scan Code
+ //
+ Status = USBKeyCodeToEFIScanCode(KeyChar,&Key);
+
+ // check for a handle that was already identified
+ while ( UsbKeyIn != NULL)
+ {
+ KeyScanCodeMatch=FALSE;
+ KeyUniCodeMatch=FALSE;
+ ShiftKeyMatch=FALSE;
+ CtrlKeyMatch=FALSE;
+ AltKeyMatch=FALSE;
+ LogoKeyMatch=FALSE;
+ MenuKeyMatch=FALSE;
+ SysRqKeyMatch=FALSE;
+ KeyShiftCodeMatch=FALSE;
+ KeyToggleKeyMatch=FALSE;
+
+ //
+ // Check the Scan Code if the Scan code is not 0
+ //
+ if (UsbKeyIn->Context.Key.ScanCode != 0) {
+ if( UsbKeyIn->Context.Key.ScanCode == Key.ScanCode) {
+ KeyScanCodeMatch=TRUE;
+ }
+ } else {
+ KeyScanCodeMatch=TRUE;
+ }
+
+ //
+ // Check the Uncide Code Matching
+ //
+
+ if(UsbKeyIn->Context.Key.UnicodeChar == Key.UnicodeChar) {
+ KeyUniCodeMatch=TRUE;
+ }
+
+ if(UsbKeyIn->Context.KeyState.KeyShiftState & SHIFT_STATE_VALID){
+
+ //
+ // Check the ShiftKey Matching. Left Shift Key is matched with
+ // Left or Right Shift Key. Same for Right Shift Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED)) {
+ if(gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->RightShiftOn) {
+ ShiftKeyMatch=TRUE;
+ }
+ } else {
+ ShiftKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Ctrl Matching. Left Ctrl Key is matched with
+ // Left or Right Ctrl Key. Same for Right Ctrl Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_CONTROL_PRESSED | LEFT_CONTROL_PRESSED)) {
+ if(gUsbKeyboardData->LeftCtrlOn || gUsbKeyboardData->RightCtrlOn) {
+ CtrlKeyMatch=TRUE;
+ }
+ } else {
+ CtrlKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Alt Matching. Left Alt Key is matched with
+ // Left or Right Alt Key. Same for Right Alt Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)) {
+ if(gUsbKeyboardData->LeftAltOn || gUsbKeyboardData->RightAltOn) {
+ AltKeyMatch=TRUE;
+ }
+ } else {
+ AltKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Logo Matching. Left Logo Key is matched with
+ // Left or Right Logo Key. Same for Right Logo Key
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & (RIGHT_LOGO_PRESSED | LEFT_LOGO_PRESSED)) {
+ if(gUsbKeyboardData->LeftLogoOn || gUsbKeyboardData->RightLogoOn) {
+ LogoKeyMatch=TRUE;
+ }
+ } else {
+ LogoKeyMatch=TRUE;
+ }
+
+ //
+ // Check the Menu Key Matching
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & MENU_KEY_PRESSED) {
+ if(gUsbKeyboardData->MenuOn) {
+ MenuKeyMatch=TRUE;
+ }
+ } else {
+ MenuKeyMatch=TRUE;
+ }
+
+ //
+ // Check the SysRq Key Matching
+ //
+ if (UsbKeyIn->Context.KeyState.KeyShiftState & SYS_REQ_PRESSED) {
+ if(gUsbKeyboardData->SysRqOn) {
+ SysRqKeyMatch=TRUE;
+ }
+ } else {
+ SysRqKeyMatch=TRUE;
+ }
+
+ KeyShiftCodeMatch=ShiftKeyMatch & CtrlKeyMatch & AltKeyMatch
+ & LogoKeyMatch & MenuKeyMatch & SysRqKeyMatch;
+ }else {
+ KeyShiftCodeMatch=TRUE;
+ }
+ //
+ // Check the Key Toggle State
+ //
+ if(UsbKeyIn->Context.KeyState.KeyToggleState & TOGGLE_STATE_VALID){
+ if((UsbKeyIn->Context.KeyState.KeyToggleState & ~KEY_STATE_EXPOSED) ==
+ (TOGGLE_STATE_VALID | gUsbKeyboardData->ScrLkOn | gUsbKeyboardData->NumLockOn | gUsbKeyboardData->CapsOn)) {
+ KeyToggleKeyMatch=TRUE;
+ }
+ } else {
+ KeyToggleKeyMatch=TRUE;
+ }
+
+ //
+ // If everything matched, call the callback function.
+ //
+ if(KeyScanCodeMatch && KeyUniCodeMatch && KeyShiftCodeMatch && KeyToggleKeyMatch && (!UsbKeyIn->CallbackStatus)) {
+
+ //Call the notification function
+ UsbKeyIn->CallbackStatus=TRUE;
+ CallBackCalled=TRUE;
+ UsbKeyIn->Callback(&UsbKeyIn->Context);
+
+ if(ValidateKeyRecord(UsbKeyIn)) {
+
+ // go to the next element in the list
+ UsbKeyIn = OUTTER(UsbKeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ } else {
+
+ // Record deleted. So go to the first element in the list
+ UsbKeyIn = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ }
+ continue;
+ }
+ // go to the next element in the list
+ UsbKeyIn = OUTTER(UsbKeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+
+ if(CallBackCalled) {
+ UsbKeyIn = OUTTER(mUsbKeyboardData.pHead, Link, KEY_WAITING_RECORD);
+ while ( UsbKeyIn != NULL) {
+ UsbKeyIn->CallbackStatus=FALSE;
+ // go to the next element in the list
+ UsbKeyIn = OUTTER(UsbKeyIn->Link.pNext, Link, KEY_WAITING_RECORD);
+ }
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdRegisterKeyNotify
+//
+// Description: Installs a callback notification function on a key
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// KeyData - Key value
+// KeyNotificationFunction- Pointer to the Notification Function
+// NotificationHandle - Handle to be unregisterd
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+)
+{
+ EFI_STATUS Status;
+ USB_KB_DEV *UsbKbd = 0; //(EIP100370+)
+ DLINK *Link = NULL;
+ KEY_WAITING_RECORD *NotifyLink = NULL;
+
+ if (KeyData == NULL || KeyNotificationFunction == NULL || NotifyHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ // Check if the key has been reistered
+ for (Link = mUsbKeyboardData.pHead; Link != NULL; Link = Link->pNext) {
+ NotifyLink = OUTTER(Link, Link, KEY_WAITING_RECORD);
+ if (MemCmp(&NotifyLink->Context, KeyData, sizeof(EFI_KEY_DATA)) == 0 &&
+ NotifyLink->Callback == KeyNotificationFunction) {
+ *NotifyHandle = (EFI_HANDLE)(&NotifyLink->Link);
+ return EFI_SUCCESS;
+ }
+ }
+
+ //
+ // Create database record and add to database
+ //
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof (KEY_WAITING_RECORD),
+ &mUsbKeyboardRecord
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ UsbKbd = USB_KB_DEV_FROM_THIS (This, SimpleInputEx); //(EIP100370+)
+ //
+ // Gather information about the registration request
+ //
+
+ mUsbKeyboardRecord->UsbKbDev = UsbKbd; //(EIP100370+)
+ mUsbKeyboardRecord->Context = *KeyData;
+ mUsbKeyboardRecord->Callback = KeyNotificationFunction;
+ mUsbKeyboardRecord->CallbackStatus = FALSE;
+
+ DListAdd (&mUsbKeyboardData, &(mUsbKeyboardRecord->Link));
+
+ //
+ // Child's handle will be the address linked list link in the record
+ //
+ *NotifyHandle = (EFI_HANDLE) (&mUsbKeyboardRecord->Link);
+
+ if(mUsbKeyboardData.Size == 1) {
+ pBS->SetTimer(UsbKeyEvent,
+ TimerPeriodic,
+ KEY_POLLING_INTERVAL);
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdRegisterKeyNotify
+//
+// Description: Uninstalls a callback notification function on a key
+//
+// Input: This - A pointer to the EFI_SIMPLE_TEXT_INPUT_PROTOCOL_EX
+// instance.
+// NotificationHandle - Handle to be unregisterd
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbKbdUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+)
+{
+ DLINK *ListPtr;
+ KEY_WAITING_RECORD *UsbKeyIn;
+ USB_KB_DEV* UsbKbd = USB_KB_DEV_FROM_THIS (This, SimpleInputEx); //(EIP100370+)
+
+ if(NotificationHandle == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ ListPtr = mUsbKeyboardData.pHead;
+ //(EIP100370)>
+ while (ListPtr != NULL) {
+ UsbKeyIn = OUTTER(ListPtr, Link, KEY_WAITING_RECORD);
+ if ((&UsbKeyIn->Link) == NotificationHandle &&
+ UsbKeyIn->UsbKbDev == UsbKbd) {
+ DListDelete(&mUsbKeyboardData, ListPtr);
+ pBS->FreePool(UsbKeyIn);
+ break;
+ }
+
+ ListPtr = ListPtr->pNext;
+ }
+
+ if (ListPtr == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (mUsbKeyboardData.Size == 0) {
+ pBS->SetTimer(UsbKeyEvent,
+ TimerCancel,
+ 0);
+ }
+
+ return EFI_SUCCESS;
+ //<(EIP100370)
+}
+
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdWaitForKey
+//
+// Description: Checks if a key is pending, if so - signals the event.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbKbdWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ if(IsUSBKeyCharEmpty()) {
+ if (EFI_ERROR(USBKeyboardCheckForKey())) {
+ return;
+ }
+ }
+ //
+ // If has key pending, signal the event.
+ //
+ gBS->SignalEvent(Event);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdReadKeyStroke
+//
+// Description: Checks if a key is pending, if so - signals the event.
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+USBKeyboardCheckForKey ()
+{
+ EFI_STATUS Status;
+ UINT8 KeyChar;
+
+ KeypressCallback (NULL, NULL, gUsbData->aKBCScanCodeBufferStart, NULL);
+
+ //
+ // Fetch raw data from the USB keyboard input,
+ // and translate it into ASCII data.
+ //
+ Status = USBParseKey(&KeyChar);
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ InsertKeyChar(KeyChar);
+ return EFI_SUCCESS;
+}
+
+//**********************************************************************
+//<AMI_PHDR_START>
+//
+// Procedure: StartPollingKey
+//
+// Description: Get the keys from the USB Keyboard buffer and process it
+//
+// Paremeters: IN EFI_EVENT Event event that has been signaled
+// IN VOID *Context
+//
+// Output: None
+//
+//
+//<AMI_PHDR_END>
+//**********************************************************************
+VOID StartPollingKey(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 KeyChar;
+
+ KeypressCallback (NULL, NULL, gUsbData->aKBCScanCodeBufferStart, NULL);
+
+ //
+ // Fetch raw data from the USB keyboard input,
+ // and translate it into ASCII data.
+ //
+ Status = USBParseKey(&KeyChar);
+
+ if(EFI_ERROR(Status)) {
+ //
+ //If the Key ShiftState has valid key, report as Partial Key
+ //
+ if (gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->LeftCtrlOn || gUsbKeyboardData->LeftAltOn ||
+ gUsbKeyboardData->LeftLogoOn || gUsbKeyboardData->RightShiftOn || gUsbKeyboardData->RightCtrlOn ||
+ gUsbKeyboardData->RightAltOn || gUsbKeyboardData->RightLogoOn || gUsbKeyboardData->SysRqOn || gUsbKeyboardData->MenuOn) {
+
+ //
+ // Check the Partial Key for the RegsiterKeyNotify callback function
+ //
+// gUsbKeyboardData->ToggleState = (gUsbKeyboardData->ScrLkOn | gUsbKeyboardData->NumLockOn << 1 | gUsbKeyboardData->CapsOn << 2); //(EIP91889-)
+ UsbCheckKeyNotify(0);
+ }
+
+ return;
+ }
+
+ InsertKeyChar(KeyChar);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ReadAndProcessKey
+//
+// Description: It processes the key and sets its states.
+//
+// Paremeters: Key - VOID Pointer
+// KeySize - Size of the structure.
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS ReadAndProcessKey(
+ VOID *Key,
+ UINT8 KeySize
+)
+{
+
+ AMI_EFI_KEY_DATA TempKey;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 KeyChar;
+
+ TempKey.Key.UnicodeChar = 0;
+ TempKey.Key.ScanCode = SCAN_NULL;
+ EfiZeroMem(&(TempKey.KeyState),sizeof(EFI_KEY_STATE));
+
+ //
+ // if there is no saved ASCII byte, fetch it
+ // by calling USBKeyboardCheckForKey().
+ //
+ if(IsUSBKeyCharEmpty()) {
+ //(EIP83888+)>
+ do {
+ Status = USBKeyboardCheckForKey();
+ if(!(EFI_ERROR(Status)))
+ break;
+ }while(gUsbData->aKBCUsbDataBufferHead != gUsbData->aKBCUsbDataBufferTail);
+ if(EFI_ERROR(Status)) {
+ if (gUsbKeyboardData->LeftShiftOn || gUsbKeyboardData->LeftCtrlOn || gUsbKeyboardData->LeftAltOn ||
+ gUsbKeyboardData->LeftLogoOn || gUsbKeyboardData->RightShiftOn || gUsbKeyboardData->RightCtrlOn ||
+ gUsbKeyboardData->RightAltOn || gUsbKeyboardData->RightLogoOn || gUsbKeyboardData->SysRqOn || gUsbKeyboardData->MenuOn) {
+
+ TempKey.KeyState.KeyToggleState = KEY_STATE_EXPOSED;
+ }
+ else {
+ return Status;
+ }
+ }
+
+ }
+
+ if(!EFI_ERROR(Status)) {
+ RemoveKeyChar(&KeyChar);
+
+ //
+ // Translate saved ASCII byte into EFI_INPUT_KEY and PS/2 Scan Code
+ //
+ Status = USBKeyCodeToEFIScanCode(KeyChar,&(TempKey.Key));
+ if(EFI_ERROR(Status)) {
+ return Status;
+ }
+ TempKey.EfiKey = UsbToEfiKeyTable[KeyChar-4];
+ TempKey.PS2ScanCode = KeyConvertionTable[KeyChar-4][3];
+ }
+
+
+// gUsbKeyboardData->ToggleState = (gUsbKeyboardData->ScrLkOn | gUsbKeyboardData->NumLockOn << 1 | gUsbKeyboardData->CapsOn << 2); //(EIP91889-)
+
+ TempKey.KeyState.KeyToggleState |= TOGGLE_STATE_VALID;
+ if (gUsbKeyboardData->ScrLkOn) {
+ TempKey.KeyState.KeyToggleState |= SCROLL_LOCK_ACTIVE;
+ }
+ if (gUsbKeyboardData->NumLockOn) {
+ TempKey.KeyState.KeyToggleState |= NUM_LOCK_ACTIVE;
+ }
+ if (gUsbKeyboardData->CapsOn) {
+ TempKey.KeyState.KeyToggleState |= CAPS_LOCK_ACTIVE;
+ }
+
+ TempKey.KeyState.KeyShiftState = SHIFT_STATE_VALID;
+ if (gUsbKeyboardData->LeftShiftOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_SHIFT_PRESSED;
+ }
+ if (gUsbKeyboardData->LeftCtrlOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_CONTROL_PRESSED;
+ }
+ if (gUsbKeyboardData->LeftAltOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_ALT_PRESSED;
+ }
+ if (gUsbKeyboardData->LeftLogoOn) {
+ TempKey.KeyState.KeyShiftState |= LEFT_LOGO_PRESSED;
+ }
+
+ if (gUsbKeyboardData->RightShiftOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_SHIFT_PRESSED;
+ }
+ if (gUsbKeyboardData->RightCtrlOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_CONTROL_PRESSED;
+ }
+ if (gUsbKeyboardData->RightAltOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_ALT_PRESSED;
+ }
+ if (gUsbKeyboardData->RightLogoOn) {
+ TempKey.KeyState.KeyShiftState |= RIGHT_LOGO_PRESSED;
+ }
+ if (gUsbKeyboardData->SysRqOn) {
+ TempKey.KeyState.KeyShiftState |= SYS_REQ_PRESSED;
+ }
+ if (gUsbKeyboardData->MenuOn) {
+ TempKey.KeyState.KeyShiftState |= MENU_KEY_PRESSED;
+ }
+
+ ProcessMultiLanguage(&TempKey);
+
+
+ // Tab, BackSpace and Enter Key are considerd that it's non Printable
+ // Char and returned the ShiftKey status as it is.
+
+ if( TempKey.Key.UnicodeChar != 9 && TempKey.Key.UnicodeChar != 8
+ && TempKey.Key.UnicodeChar != 13 && TempKey.Key.UnicodeChar != 0) {
+ TempKey.KeyState.KeyShiftState &= ~(RIGHT_SHIFT_PRESSED | LEFT_SHIFT_PRESSED);
+ }
+
+ pBS->CopyMem(Key, &TempKey, KeySize);
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------
+//
+// Procedure: ProcessMultiLanguage
+//
+// Description: It maps the current key to a Unicode character from
+// the keyboard layout
+//
+// Paremeters: KeyData - Pointer to the AMI_EFI_KEY_DATA .
+//
+// Output: None
+//
+//----------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ProcessMultiLanguage(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+)
+{
+ EFI_STATUS Status;
+
+ if(gMultiLangSupportProtocol == NULL) {
+ Status= pBS->LocateProtocol (
+ &gAmiMultiLangSupportGuid,
+ NULL,
+ &gMultiLangSupportProtocol
+ );
+ if(EFI_ERROR(Status)) {
+ return EFI_NOT_FOUND;
+ }
+ }
+
+ return gMultiLangSupportProtocol->KeyboardLayoutMap(gMultiLangSupportProtocol,KeyData);
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbkb.h b/Core/EM/usb/efiusbkb.h
new file mode 100644
index 0000000..bad8cfc
--- /dev/null
+++ b/Core/EM/usb/efiusbkb.h
@@ -0,0 +1,462 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbkb.h 25 11/26/13 4:09a Ryanchou $
+//
+// $Revision: 25 $
+//
+// $Date: 11/26/13 4:09a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbkb.h $
+//
+// 25 11/26/13 4:09a Ryanchou
+// [TAG] EIP142509
+// [Category] Improvement
+// [Description] Added usage 0x87 and 0x89.
+// [Files] efiusbkb.c, efiusbkb.h
+//
+// 24 8/23/13 6:08a Ryanchou
+// Fix the AMI_MULTI_LANG_SUPPORT_PROTOCOL redefinition problem.
+//
+// 23 7/24/13 2:33a Roberthsu
+// [TAG] EIP121333
+// [Category] Improvement
+// [Description] Multiple USB mouse support for UEFI USB mouse driver
+// [Files] efiusbhid.c,efiusbkb.h,efiusbms.c
+//
+// 22 11/20/12 1:54a Deepthins
+// [TAG] EIP106155
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Build error with lastest USB module and old core label
+// [RootCause] Backward compatibility problem with old core label .
+// [Solution] Provided required definations when core label is 4.6.5.4
+// or below.
+// [Files] efiusbkb.h
+//
+// 21 11/15/12 3:47a Ryanchou
+//
+// 19 11/01/12 6:33a Deepthins
+// [TAG] EIP101102
+// [Category] Improvement
+// [Description] Multi Language is supported in USB driver
+// [Files] efiusbkb.c, efiusbkb.h
+//
+// 18 3/20/12 10:32p Wilsonlee
+// [TAG] EIP83295
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System will hang at B2 when do S3/S4 long run test or DOS
+// reboot test.
+// [RootCause] It causes the stack problem when we call
+// IsUSBKeyboardBufferEmpty function.
+// [Solution] Change to use pointer as parameter to
+// IsUSBKeyboardBufferEmpty function.
+// [Files] efiusbkb.c, efisubkb.h, usbmass.c, ehci.c
+//
+// 17 12/29/11 1:56a Deepthins
+// [TAG] EIP77537
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Multiple USB keyboard are not synchronized properly
+// [RootCause] In USB driver for the new Simpletextin ( USB keyboard)
+// device, the memory allocated for the device is saved in gUsbKbd
+// pointer. The same pointer is used when multiple simple text in device
+// installed.
+// [Solution] USB_KB_DEV structure is divided into 2 structure, one is
+// common for all the Simpletextin and another structure is for specific
+// to the SimpleTextin Device.Based on it, allocate the memory for
+// structure and use it. When the stop function is called, we should free
+// only the structure that is specific for device.
+//
+// [Files] Efiusbkb.c, Efiusbhid.c, efiusbkb.c
+//
+// 16 9/23/11 12:33a Rameshr
+// [TAG] EIP63054
+// [Category] New Feature
+// [Description] 0000790: Add warning to ReadKeyStrokeEx for partial key
+// press
+// [Files] KeyboardCommonDefinitions.h, In.c, Kbc.h, Ps2Kbd.c,
+// Efiusbkb.c, efiusbkb.h, efiusbhid.c
+//
+// 15 7/15/11 6:23a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 14 5/14/10 10:55a Olegi
+// PrintScreen/SysRq key, Menu Key, Left Logo and Right Logo Key support
+// in USB Keyboard driver
+// EIP 38214
+//
+// 13 5/10/10 1:57a Rameshr
+// Issue:UsbKeyboard Driver doesn’t differentiate between Left Shift and
+// Right Shift Key.
+// Solution: modified the driver to differentiate between Left
+// Shift/Alt/Ctrl and Right Shift/Alt/Ctrl Key's.
+// EIP 38256
+//
+// 12 9/05/08 4:14p Olegi
+// RepeatKey is moved from USB_KB_DEV structure to global data area.
+//
+// 11 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 10 12/17/07 5:43p Rameshraju
+// Added the core revision check for the AMI Keycode to build with OLD
+// core.
+//
+// 9 10/23/07 4:16p Olegi
+// AmiKeycode protocol implementation.
+//
+// 8 9/18/07 12:35p Olegi
+//
+// 6 3/20/07 1:29p Olegi
+//
+// 4 5/03/06 9:59a Olegi
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EfiUsbKb.h
+//
+// Description: AMI USB keyboard driver header file
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _AMI_USB_KB_H
+#define _AMI_USB_KB_H
+
+
+#include "amidef.h"
+#include "usbdef.h"
+#if (CORE_REVISION >= 0x3)
+#include "Protocol\AmiKeycode.h" // Available starting from Core 4.6.3
+#endif
+
+#define USBKB_DRIVER_VERSION 1
+
+EFI_STATUS SupportedUSBKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, EFI_DEVICE_PATH_PROTOCOL *dp);
+EFI_STATUS InstallUSBKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, EFI_DEVICE_PATH_PROTOCOL *dp,DEV_INFO *Dev_info,EFI_USB_IO_PROTOCOL *UsbIo ); //(EIP38434+)
+EFI_STATUS UninstallUSBKeyboard(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, UINTN numberOfChildren, EFI_HANDLE *children );
+
+ //(EIP38434+)>
+EFI_STATUS InstallUSBAbsMouse(EFI_HANDLE Controller,DEV_INFO *pDevInfo);
+EFI_STATUS UninstallUSBAbsMouse(IN EFI_HANDLE Controller);
+
+EFI_STATUS InstallUSBMouse(EFI_HANDLE Controller,EFI_USB_IO_PROTOCOL *UsbIo,DEV_INFO *DevInfo);
+EFI_STATUS UninstallUSBMouse(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, UINTN numberOfChildren, EFI_HANDLE *children );
+
+EFI_STATUS UsbHidInit(EFI_HANDLE ImageHandle,EFI_HANDLE ServiceHandle);
+EFI_STATUS SupportedUSBHid(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, EFI_DEVICE_PATH_PROTOCOL *dp);
+EFI_STATUS InstallUSBHid(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, EFI_DEVICE_PATH_PROTOCOL *dp);
+EFI_STATUS UninstallUSBHid(EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE, UINTN numberOfChildren, EFI_HANDLE *children );
+ //<(EIP38434+)
+#define USB_KB_DEV_SIGNATURE EFI_SIGNATURE_32('u','k','b','d')
+typedef struct
+{
+ UINTN Signature;
+ EFI_SIMPLE_TEXT_INPUT_PROTOCOL SimpleInput;
+#if (CORE_REVISION >= 0x3)
+ EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL SimpleInputEx;
+ AMI_EFIKEYCODE_PROTOCOL KeycodeInput;
+#endif
+
+ EFI_USB_IO_PROTOCOL *io;
+ DEV_INFO *dev_info;
+
+} USB_KB_DEV;
+
+typedef struct
+{
+ USB_KB_BUFFER KeyboardBuffer;
+ UINT8 LeftCtrlOn;
+ UINT8 LeftAltOn;
+ UINT8 LeftShiftOn;
+ UINT8 RightCtrlOn;
+ UINT8 RightAltOn;
+ UINT8 RightShiftOn;
+ UINT8 SysRqOn;
+ UINT8 MenuOn;
+ UINT8 LeftLogoOn;
+ UINT8 RightLogoOn;
+ UINT8 NumLockOn;
+ UINT8 CapsOn;
+ UINT8 ScrLkOn;
+ UINT8 LastKeyCodeArray[8];
+ UINT8 CurKeyChar;
+ UINT8 KeyChar[MAX_KEY_ALLOWED + 1];
+ UINT8 bHead;
+ UINT8 bTail;
+ UINT8 ToggleState;
+}USB_KEYBOARD_DATA;
+//
+// Global Variables
+//
+
+#ifndef CR
+#define CR(record, TYPE, field, signature) _CR(record, TYPE, field)
+#endif
+#define USB_KB_DEV_FROM_THIS(a,b) \
+ CR(a, USB_KB_DEV, b, USB_KB_DEV_SIGNATURE)
+
+#define MOD_CONTROL_L 0x01
+#define MOD_CONTROL_R 0x10
+#define MOD_SHIFT_L 0x02
+#define MOD_SHIFT_R 0x20
+#define MOD_ALT_L 0x04
+#define MOD_ALT_R 0x40
+#define MOD_WIN_L 0x08
+#define MOD_WIN_R 0x80
+
+typedef struct
+{
+ UINT8 Mask;
+ UINT8 Key;
+} KB_MODIFIER;
+
+#define USB_KEYCODE_MAX_MAKE 0x86
+
+
+#define USBKBD_VALID_KEYCODE(key) ((UINT8)(key) > 3)
+
+//
+// Backward compatibility for Multi Language support
+//
+#if CORE_COMBINED_VERSION <= 0x4028E
+#ifndef AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID
+
+#define AMI_MULTI_LANG_SUPPORT_PROTOCOL_GUID \
+ {0xb295bd1c, 0x63e3, 0x48e3, 0xb2, 0x65, 0xf7, 0xdf, 0xa2, 0x7, 0x1, 0x23}
+
+typedef struct _AMI_MULTI_LANG_SUPPORT_PROTOCOL AMI_MULTI_LANG_SUPPORT_PROTOCOL;
+
+typedef EFI_STATUS (EFIAPI *EFI_KEYBOARD_LAYOUT_MAP)(
+ IN AMI_MULTI_LANG_SUPPORT_PROTOCOL *This,
+ IN OUT AMI_EFI_KEY_DATA *Keydata );
+
+typedef struct _AMI_MULTI_LANG_SUPPORT_PROTOCOL {
+ EFI_KEYBOARD_LAYOUT_MAP KeyboardLayoutMap;
+} AMI_MULTI_LANG_SUPPORT_PROTOCOL;
+
+#endif
+#endif
+
+EFI_STATUS InitUSBKeyboard();
+EFI_STATUS InitUSBMouse();
+
+UINT8
+KeypressCallback(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpBuf1,
+ UINT8* fpBuf2
+ );
+
+UINT8
+KeyrepeatCallback(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpBuf1,
+ UINT8* fpBuf2);
+EFI_STATUS
+
+USBParseKey(
+ OUT UINT8 *KeyChar
+ );
+
+
+EFI_STATUS
+USBKeyCodeToEFIScanCode(
+ IN UINT8 KeyChar,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+
+EFI_STATUS
+InitUSBKeyBuffer(
+ IN OUT USB_KB_BUFFER *KeyboardBuffer
+ );
+ //(EIP83295)>
+BOOLEAN
+IsUSBKeyboardBufferEmpty(
+ IN USB_KB_BUFFER *KeyboardBuffer
+ );
+
+
+BOOLEAN
+IsUSBKeyboardBufferFull(
+ IN USB_KB_BUFFER *KeyboardBuffer
+ );
+ //<(EIP83295)
+
+EFI_STATUS
+InsertKeyCode(
+ IN OUT USB_KB_BUFFER *KeyboardBuffer,
+ IN UINT8 Key,
+ IN UINT8 Down
+ );
+
+
+EFI_STATUS
+RemoveKeyCode(
+ IN OUT USB_KB_BUFFER *KeyboardBuffer,
+ OUT USB_KEY *UsbKey
+ );
+
+
+EFI_STATUS
+InitUSBKeyCharBuffer();
+
+BOOLEAN
+IsUSBKeyCharEmpty();
+
+BOOLEAN
+IsUSBKeyCharFull();
+
+EFI_STATUS
+InsertKeyChar(
+ UINT8 KeyChar
+ );
+
+
+EFI_STATUS
+RemoveKeyChar(
+ OUT UINT8 *KeyChar
+ );
+
+EFI_STATUS
+SetKeyLED();
+
+EFI_STATUS
+EFIAPI
+UsbKbdReset (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+EFI_STATUS
+EFIAPI
+UsbKbdReadKeyStroke (
+ IN EFI_SIMPLE_TEXT_INPUT_PROTOCOL *This,
+ OUT EFI_INPUT_KEY *Key
+ );
+
+#if (CORE_REVISION >= 0x3)
+EFI_STATUS
+UsbKbdResetEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+EFI_STATUS
+EFIAPI
+UsbKbdReadKeyStrokeEx (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ OUT EFI_KEY_DATA *KeyData
+ );
+
+EFI_STATUS UsbKbdReadEfiKey(
+ IN AMI_EFIKEYCODE_PROTOCOL *This,
+ OUT AMI_EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS
+UsbKbdSetState (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_TOGGLE_STATE *KeyToggleState
+);
+
+EFI_STATUS
+UsbKbdRegisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_KEY_DATA *KeyData,
+ IN EFI_KEY_NOTIFY_FUNCTION KeyNotificationFunction,
+ OUT EFI_HANDLE *NotifyHandle
+);
+
+EFI_STATUS
+UsbKbdUnregisterKeyNotify (
+ IN EFI_SIMPLE_TEXT_INPUT_EX_PROTOCOL *This,
+ IN EFI_HANDLE NotificationHandle
+ );
+#endif
+VOID
+EFIAPI
+UsbKbdWaitForKey (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS
+USBKeyboardCheckForKey (
+);
+
+VOID StartPollingKey(
+ EFI_EVENT Event,
+ VOID *Context
+);
+
+EFI_STATUS ProcessMultiLanguage(
+ IN OUT AMI_EFI_KEY_DATA *KeyData
+);
+
+EFI_STATUS ReadAndProcessKey(
+ VOID *Key,
+ UINT8 KeySize
+);
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbmass.c b/Core/EM/usb/efiusbmass.c
new file mode 100644
index 0000000..d80fc1c
--- /dev/null
+++ b/Core/EM/usb/efiusbmass.c
@@ -0,0 +1,1235 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbmass.c 65 10/20/16 11:20p Wilsonlee $
+//
+// $Revision: 65 $
+//
+// $Date: 10/20/16 11:20p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbmass.c $
+//
+// 65 10/20/16 11:20p Wilsonlee
+// [TAG] EIP297268
+// [Category] Improvement
+// [Description] Update Media information only in EfiUsbMass driver when
+// Media is changed.
+// [Files] usbmass.c, efiusbmass.c
+//
+// 64 10/16/16 10:18p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 63 7/07/16 1:12a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 62 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 61 5/27/15 2:15a Wilsonlee
+// [TAG] EIP220162
+// [Category] Improvement
+// [Description] The read / write request contain the latest LBA that
+// are valid.
+// [Files] usbmass.c, efiusbmass.c
+//
+// 60 5/13/15 2:46a Wilsonlee
+// [TAG] EIP216587
+// [Category] Improvement
+// [Description] Add 64-bit addressing buffer support for usb transfers.
+// [Files] amiusbhc.c, efiusbmass.c
+//
+// 59 4/29/15 11:28p Wilsonlee
+// [TAG] EIP215031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Transcend USB 3.0 HDD is disappeared in the setup menu by
+// cold boot.
+// [RootCause] We only can get SerialNumber string descriptor before
+// setting configuration for this device, otherwise it is failed at
+// getting this descriptor and inquiry command is also failed.
+// [Solution] Retry inquiry command.
+// [Files] usb.c, usbmass.c, efiusbmass.c, usbbus.c, usbdef.h
+//
+// 58 9/30/14 2:04a Wilsonlee
+// [TAG] EIP183572
+// [Category] Improvement
+// [Description] Change tpl of UsbHcOnTimer to EFI_TPL_CALLBACK
+// [Files] efiusbmass.c, usbbus.c
+//
+// 57 9/30/14 1:30a Wilsonlee
+// [TAG] EIP186438
+// [Category] Improvement
+// [Description] We should close UsbIoProtocol if it has any error in
+// InstallUsbMass.
+// [Files] efiusbmass.c
+//
+// 56 8/20/14 5:25a Wilsonlee
+// [TAG] EIP182011
+// [Category] Improvement
+// [Description] We don't need to update NVRAM variables in
+// InstallUsbMass and UninstallUSBMass functions.
+// [Files] efiusbmass.c, usbsetup.c
+//
+// 55 7/18/14 11:39p Wilsonlee
+// [TAG] EIP174022
+// [Category] Improvement
+// [Description] Check if the mass storage device is present before
+// installing BlkIo protocol.
+// [Files] xhci.c, efiusbmass.c
+//
+// 54 4/30/14 5:27a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 53 4/07/14 2:08a Wilsonlee
+// [TAG] EIP156126
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The power Format of UEFI can not be identified when we
+// install OS from USB CD-ROM.
+// [RootCause] The media information is incorrect when we install
+// BlockIoProtocol for usb CD / DVD devices.
+// [Solution] Get the media status before we install BlockIoProtocol.
+// [Files] usbmass.c, usbdef.h, efiusbmass.c
+//
+// 52 12/24/13 3:21a Wilsonlee
+// [TAG] EIP148177
+// [Category] Improvement
+// [Description] change from EFI_MBR_WRITE_PROTECTION_PROTOCOL to
+// AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL
+// [Files] efiusbmass.c
+//
+// 51 12/18/13 3:59a Wilsonlee
+// [TAG] EIP147574
+// [Category] Improvement
+// [Description] MbrWriteProtectionProtocol file name changesd to
+// AmiMbrWriteProtectionProtocol.h
+// [Files] efiusbmass.c
+//
+// 50 12/15/13 10:17p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 49 8/16/13 4:18a Ryanchou
+//
+// 48 7/29/13 5:29a Roberthsu
+// [TAG] EIP126741
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Cannot boot to uefi usb device with Sophos software.
+// [RootCause] When boot into tool. Ownership to os event occur.Usb
+// will disconnect device.And record this disconnect event. Then ownership
+// to bios,bios will connect all device.Run legacy to efi function. Bios
+// run disconnect event first.Then reconnect device.Because usb key behind
+// hub. So usb key disconnect also.
+// [Solution] Check device when device reconnect.If device and port
+// number the same.Use the same device info.
+// [Files] usb.c,usbmass.c,efiusbmass.c,uhcd.c
+//
+// 47 7/03/13 5:23a Ryanchou
+// [TAG] EIP123988
+// [Category] Improvement
+// [Description] Move the code creating BBS table to end of POST.
+// [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+// UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 46 7/03/13 4:49a Ryanchou
+// [TAG] EIP127800
+// [Category] Improvement
+// [Description] Add non-bootable device type handing
+// [Files] usbmass.c, efiusbmass.c
+//
+// 45 7/01/13 5:45a Kapilporwal
+// [TAG] EIP125560
+// [Category] Improvement
+// [Description] Please support Boot Sector Virus Protection for CSM
+// Disabled Mode
+// [Files] VirusProtect.c, VirusProtect.dxs, AhciBus.c,
+// AhciController.c, CsmBlockIo.c, CsmInt13.c, Ata.c, IdeBus.c,
+// SdioBlkIo.c, SdioDriver.c, efiusbmass.c
+//
+// 44 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 43 1/22/13 3:11a Wilsonlee
+// [TAG] EIP112938
+// [Category] Improvement
+// [Description] Create a header file for usb mass storage driver.
+// [Files] UsbMass.h, usbmass.c, usbdef.h, amiusb.c, efiusbmass.c
+//
+// 42 1/22/13 2:40a Wilsonlee
+// [TAG] EIP110305
+// [Category] Improvement
+// [Description] Set the device address after we send the first
+// get-device-descriptor command.
+// [Files] usbmass.c, usb.c, usbdef.h, usbbus.c, efiusbmass.c, uhcd.c,
+// usbport.c
+//
+// 41 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 40 9/04/12 8:04a Wilsonlee
+// [TAG] EIP99882
+// [Category] New Feature
+// [Description] Add the usb setup item and usbpolicyprotocol to enable
+// or disable the usb mass storage driver.
+// [Files] UsbPolicy.h, usb.uni, usb.sd, usbmass.c, usbdef.h,
+// efiusbmass.c, usbport.c, uhcd.c
+//
+// 39 8/29/12 8:36a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 38 5/04/12 5:30a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 37 1/10/12 5:47a Deepthins
+// [TAG] EIP73939
+// [Category] Improvement
+// [Description] For USB BlockIo driver , AmiUsbBlkIoReadWrite function
+// should return EFI_ EFI_MEDIA_CHANGED if media id does not match and if
+// alignment is not proper then it should return EFI_INVALID_PARAMETER.
+// [Files] efiusbmass.c
+//
+// 36 11/05/11 3:39a Ryanchou
+// [TAG] EIP71108
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The token of "REMOVE_USB_STORAGE_FROM_BBS_IF_NO_MEDIA¡§
+// can't work normal
+// [RootCause] While a SD card is not plugged into the card reader, its
+// wBlockSize is actually 0xFFFF, which this
+// gAmiUsbController->UsbInstallLegacyDevice(MassDev) is not being
+// executed, that is why whatever values the token
+// REMOVE_USB_STORAGE_FROM_BBS_IF_NO_MEDIA are, the card reader won't be
+// seen from the "boot option" in the SETUP.
+// [Solution] Add one condition in the function InstallUSBMass.
+// [Files] efiusbmass.c
+//
+// 35 6/22/11 1:42a Ryanchou
+// [TAG] EIP59738
+// [Category] Improvement
+// [Description] Support Block size other than 512 bytes USB HDD in UEFI
+// mode.
+// [Files] efiusbmass.c, uhci.c, usb.c, usbdef.h, usbmass.c
+//
+// 34 5/27/11 7:39a Rameshr
+// [TAG]- EIP 58689
+// [Category]-IMPROVEMENT
+// [Description]- Update implementation of EFI_BLOCK_IO_PROTOCOL as
+// described in UEFI specification v 2.3.1, page 12.8
+// [Files]- efiusbmass.c
+//
+// 33 5/03/11 10:47a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 32 3/04/11 1:30p Olegi
+//
+// 31 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 30 9/07/10 4:41a Tonylo
+// Remove user tags for coding standard.
+//
+// 29 8/17/10 11:39p Ryanchou
+// EIP41547: Fixed system hangs if hot plug USB device during
+// initialization.
+//
+// 28 6/17/10 10:36a Olegi
+// EIP39092: Change the order of protocol installation in InstallUSBMass.
+//
+// 27 2/23/10 1:36p Olegi
+// Work around Klockwork issues. EIP34370
+//
+// 26 8/04/09 11:01a Olegi
+// Install legacy mass storage device only when USB legacy support is
+// enabled. EIP#24484
+//
+// 25 6/16/09 10:40a Olegi
+// Fix for EIP#14848: EFI_BLOCK_IO_PROTOCOL.EFI_BLOCK_IO_MEDIA->ReadOnly
+//
+// 24 5/21/09 5:16p Olegi
+//
+// 23 3/26/09 2:17p Olegi
+// All setup related code is moved to OEMPORT.C to maximize the porting
+// capabilities.
+//
+// 22 2/18/09 3:46p Olegi
+// Added a feature that allows to skip mass storage device installation
+// depending on physical media presence. EIP#19260.
+//
+// 21 12/16/08 10:52a Olegi
+// Correction in the return values: 0 changed to NULL. EIP#17767.
+//
+// 19 6/27/08 5:58p Olegi
+//
+// 18 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 17 4/17/07 10:51a Olegi
+//
+// 16 3/20/07 1:29p Olegi
+//
+// 14 10/12/06 7:12p Andriyn
+// Support unexpected plug-off USB device
+//
+// 13 4/14/06 6:41p Olegi
+//
+// 12 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 11 3/16/06 2:34p Olegi
+//
+// 9 3/06/06 6:27p Olegi
+// Lun devices support modifications: supported using the index in
+// DEV_INFO table, not through dedicated massLun table.
+//
+// 8 1/11/06 1:44p Olegi
+//
+// 7 11/04/05 6:20p Olegi
+// Multiple LUN support.
+//
+// 6 10/20/05 2:45p Olegi
+//
+// 5 8/23/05 5:55p Olegi
+//
+// 4 6/03/05 9:33a Olegi
+// - Correction in reporting status code from Read/Write routines
+// - MediaId manipulation fix
+//
+// 3 5/19/05 8:06p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 2 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EFIUSBMASS.C
+//
+// Description: EFI USB Mass Storage Driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "componentname.h"
+#include "usbbus.h"
+#include "setup.h"
+#include "UsbMass.h"
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+#include <Protocol\AmiBlockIoWriteProtection.h>
+AMI_BLOCKIO_WRITE_PROTECTION_PROTOCOL *AmiBlkWriteProtection = NULL;
+#endif
+
+#define USBMASS_DRIVER_VERSION 1
+#define READ 1
+#define WRITE 0
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern EFI_USB_PROTOCOL *gAmiUsbController;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InstallUsbMass
+//
+// Description: Installs BlkIo protocol on a USB Mass Storage device
+//
+// Input: DevInfo - pointer to a USB device structure to install the protocol.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUsbMass(
+ EFI_HANDLE Controller,
+ DEV_INFO* DevInfo
+)
+{
+ USB_MASS_DEV *MassDev;
+ EFI_STATUS Status;
+ UINT8 LogicalAddress;
+ URP_STRUC Parameters;
+
+ //Applying check to media not present device only
+ if (!(DevInfo->bLastStatus & USB_MASS_MEDIA_PRESENT)) {
+ if (gUsbData->dUSBStateFlag & USB_FLAG_MASS_MEDIA_CHECK) {
+ if (gUsbData->dUSBStateFlag & USB_FLAG_MASS_SKIP_FDD_MEDIA_CHECK) {
+ if (!(DevInfo->bSubClass == SUB_CLASS_UFI)) {
+ return EFI_DEVICE_ERROR;
+ }
+ } else {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ }
+
+ for (LogicalAddress=1; LogicalAddress < MAX_DEVICES; LogicalAddress++) {
+ if (&gUsbData->aDevInfoTable[LogicalAddress] == DevInfo) {
+ break;
+ }
+ }
+ ASSERT(LogicalAddress < MAX_DEVICES);
+
+ if (LogicalAddress >= MAX_DEVICES) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Parameters.bFuncNumber = USB_API_MASS_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_MASSAPI_GET_MEDIA_STATUS;
+ Parameters.ApiData.MassGetDevSts.bDevAddr = LogicalAddress;
+ Parameters.ApiData.MassGetDevSts.bDeviceStatus = 0;
+ InvokeUsbApi(&Parameters);
+
+ gBS->AllocatePool(EfiBootServicesData, sizeof(USB_MASS_DEV), &MassDev);
+
+ //
+ // Handshaking...
+ //
+ MassDev->DevInfo = DevInfo;
+ DevInfo->MassDev = (VOID*)&MassDev->BlockIoProtocol;
+ MassDev->Handle = Controller;
+ MassDev->DevString = (UINT8*)&DevInfo->DevNameString;
+ MassDev->StorageType = DevInfo->bStorageType;
+
+ //
+ // Install BLOCK_IO protocol interface
+ //
+ gBS->AllocatePool(EfiBootServicesData, sizeof(EFI_BLOCK_IO_MEDIA), &MassDev->Media);
+
+ MassDev->Media->MediaId = 0; // Media change indicator
+ MassDev->Media->LogicalPartition = FALSE;
+ MassDev->Media->ReadOnly = FALSE;
+ MassDev->Media->WriteCaching = FALSE;
+ MassDev->Media->BlockSize = DevInfo->wBlockSize;
+ MassDev->Media->IoAlign = 0;
+
+ if (DevInfo->bLastStatus & USB_MASS_MEDIA_REMOVEABLE) {
+ MassDev->Media->RemovableMedia = TRUE;
+ } else {
+ MassDev->Media->RemovableMedia = FALSE;
+ }
+ if ((DevInfo->bLastStatus & USB_MASS_MEDIA_PRESENT) &&
+ (DevInfo->MaxLba != 0) && (DevInfo->wBlockSize != 0)) {
+ // For SCSI devices, this is reported in the READ CAPACITY (16) parameter
+ // data Returned Logical Block Address field (see SBC-3) minus one.
+ MassDev->Media->LastBlock = DevInfo->MaxLba - 1; // LastBlock is 0-based
+ MassDev->Media->MediaPresent = TRUE;
+ } else {
+ MassDev->Media->LastBlock = 0;
+ MassDev->Media->MediaPresent = FALSE;
+ }
+
+#if defined CORE_COMBINED_VERSION && CORE_COMBINED_VERSION > 0x4028a
+ if(pST->Hdr.Revision >= 0x0002001F) {
+ MassDev->BlockIoProtocol.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
+ //
+ // Default value set to 1 logical blocks per PhysicalBlock
+ //
+ MassDev->Media->LogicalBlocksPerPhysicalBlock=1;
+
+ //
+ // Default value set to 0 for Lowest Aligned LBA
+ //
+ MassDev->Media->LowestAlignedLba=0;
+
+ MassDev->Media->OptimalTransferLengthGranularity=MassDev->Media->BlockSize;
+ } else {
+ MassDev->BlockIoProtocol.Revision = 1;
+ }
+#else
+ MassDev->BlockIoProtocol.Revision = 1;
+#endif
+
+ MassDev->BlockIoProtocol.Media = MassDev->Media;
+ MassDev->BlockIoProtocol.Reset = AmiUsbBlkIoReset;
+ MassDev->BlockIoProtocol.ReadBlocks = AmiUsbBlkIoReadBlocks;
+ MassDev->BlockIoProtocol.WriteBlocks = AmiUsbBlkIoWriteBlocks;
+ MassDev->BlockIoProtocol.FlushBlocks = AmiUsbBlkIoFlushBlocks;
+
+ MassDev->LogicalAddress = LogicalAddress;
+
+ MassDev->PciBDF = gUsbData->HcTable[DevInfo->bHCNumber - 1]->wBusDevFuncNum;
+
+#if !defined (CORE_COMBINED_VERSION) || CORE_COMBINED_VERSION <= 0x40280
+ // Install INT13 device if Legacy USB support is enabled
+ if((gUsbData->dUSBStateFlag & USB_FLAG_DISABLE_LEGACY_SUPPORT) == 0) {
+ if (DevInfo->bPhyDevType != USB_MASS_DEV_UNKNOWN &&
+ !(DevInfo->bPhyDevType != USB_MASS_DEV_CDROM &&
+ (DevInfo->wBlockSize > 0x200 && DevInfo->wBlockSize != 0xFFFF))){
+ gAmiUsbController->UsbInstallLegacyDevice(MassDev);
+ }
+ }
+#endif
+
+ USB_DEBUG(DEBUG_LEVEL_3, "InstallUSBMass(%x): BS %d, MaxLBA %lx, LA: %x %s\n",
+ DevInfo, DevInfo->wBlockSize, DevInfo->MaxLba,
+ MassDev->LogicalAddress, &DevInfo->DevNameString);
+
+ Status = gBS->InstallProtocolInterface(
+ &MassDev->Handle,
+ &gEfiBlockIoProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &MassDev->BlockIoProtocol
+ );
+ USB_DEBUG(DEBUG_LEVEL_3, "Install BlockIO on %x status = %r\n", Controller, Status);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UninstallUSBMass
+//
+// Description: Removes BlkIo protocol from USB Mass Storage device
+//
+// Input: DevInfo - pointer to a USB device structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UninstallUSBMass(USB_MASS_DEV *MassDev)
+{
+ EFI_STATUS Status;
+ DEV_INFO *DevInfo = MassDev->DevInfo;
+ HC_STRUC* HcData;
+ UINT8 UsbStatus;
+
+ HcData = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+ UsbStatus = UsbDevDriverDisconnect(HcData, DevInfo);
+ ASSERT(UsbStatus == USB_SUCCESS);
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Uninstall mass storage device %x: ", MassDev->Handle);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces(
+ MassDev->Handle,
+ &gEfiBlockIoProtocolGuid,
+ &MassDev->BlockIoProtocol,
+ NULL);
+
+#if !defined (CORE_COMBINED_VERSION) || CORE_COMBINED_VERSION <= 0x40280
+ gAmiUsbController->UsbUninstallLegacyDevice(MassDev);
+#endif
+
+ USB_DEBUG(DEBUG_LEVEL_3, "%r\n", Status);
+ if(!EFI_ERROR(Status)){
+ gBS->FreePool(MassDev->Media);
+ gBS->FreePool(MassDev);
+ DevInfo->MassDev = NULL;
+ }
+
+ return Status;
+}
+
+/************ BlockIO Protocol implementation routines******************/
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiUsbBlkIoReset
+//
+// Description: Reset the USB Logic Drive
+//
+// Input: This: A pointer to the Block I/O protocol interface
+//
+// ExtendedVerification: Indicate that the driver may perform
+// an exhaustive verification operation of the device during
+// reset
+//
+// Output: EFI_SUCCESS: The USB Logic Drive is reset
+// EFI_DEVICE_ERROR: The Floppy Logic Drive is not functioning
+// correctly and can not be reset
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbBlkIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+
+{
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiUsbBlkIoFlushBlocks
+//
+// Description: Flush USB Mass Storage Device
+//
+// Input: This: A pointer to the Block I/O protocol interface
+//
+// Output: EFI_SUCCESS: The USB Logic Drive successfully flushed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbBlkIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+ )
+{
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiUsbBlkIoReadWrite
+//
+// Description: This routine is invoked from AmiUsbBlkIoReadBlocks and
+// AmiUsbBlkIoWriteBlocks. See these for parameters reference.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbBlkIoReadWrite (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer,
+ UINT8 ReadWrite
+ )
+{
+ USB_MASS_DEV *MassDev;
+ URP_STRUC Parameters;
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT32 Buf;
+ UINT32 BytesToTransfer;
+ UINT32 BytesRemaining;
+ UINT16 BlockSize;
+ UINTN BufferAddress;
+ UINT8 *DataBuffer;
+ UINTN Pages;
+ DEV_INFO *DevInfo;
+
+ MassDev = (USB_MASS_DEV*)This;
+ BlockSize = ((DEV_INFO*)(MassDev->DevInfo))->wBlockSize;
+
+ //
+ // Check if media id matches
+ //
+ if ( This->Media->MediaId != MediaId ) {
+ return EFI_MEDIA_CHANGED;
+ }
+
+ if (BufferSize == 0) return EFI_SUCCESS;
+ if (Buffer == NULL) return EFI_INVALID_PARAMETER;
+
+ //
+ // If IoAlign values is 0 or 1, means that the buffer can be placed
+ // anywhere in memory or else IoAlign value should be power of 2. To be
+ // properly aligned the buffer address should be divisible by IoAlign
+ // with no remainder.
+ //
+ BufferAddress = (UINTN)Buffer;
+ if((This->Media->IoAlign > 1 ) && (BufferAddress % This->Media->IoAlign)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+
+ //
+ // Get media status
+ //
+ This->Media->MediaPresent = TRUE; // Initialize, to be updated if no media
+
+ Parameters.bFuncNumber = USB_API_MASS_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_MASSAPI_GET_MEDIA_STATUS;
+ Parameters.ApiData.MassGetDevSts.bDevAddr = (UINT8)MassDev->LogicalAddress;
+ Parameters.ApiData.MassGetDevSts.bDeviceStatus = 0;
+
+ InvokeUsbApi(&Parameters);
+
+ DevInfo = (DEV_INFO*)MassDev->DevInfo;
+
+ if ((Parameters.ApiData.MassGetDevSts.bDeviceStatus & USB_MASS_MEDIA_PRESENT) &&
+ (DevInfo->MaxLba != 0) && (DevInfo->wBlockSize != 0)) {
+ if ((DevInfo->wBlockSize != This->Media->BlockSize) ||
+ ((DevInfo->MaxLba -1)!= This->Media->LastBlock) ||
+ (Parameters.ApiData.MassGetDevSts.bDeviceStatus & USB_MASS_MEDIA_CHANGED)) {
+ This->Media->MediaId++;
+ This->Media->ReadOnly = FALSE;
+ This->Media->LastBlock = DevInfo->MaxLba - 1;
+ This->Media->BlockSize = DevInfo->wBlockSize;
+ }
+ } else {
+ This->Media->LastBlock = 0;
+ }
+
+ if ((!(Parameters.ApiData.MassGetDevSts.bDeviceStatus & USB_MASS_MEDIA_PRESENT))
+ ||(This->Media->LastBlock == 0) || (This->Media->BlockSize == 0)) {
+ This->Media->MediaPresent = FALSE;
+ This->Media->LastBlock = 0;
+ return EFI_NO_MEDIA;
+ }
+
+ if (MediaId != This->Media->MediaId) {
+ return EFI_MEDIA_CHANGED;
+ }
+ //
+ // Check Parameter to comply with EFI 1.1 Spec
+ //
+ if (Lba > This->Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ BlockSize = ((DEV_INFO*)(MassDev->DevInfo))->wBlockSize;
+
+ if ((Lba + (BufferSize / BlockSize) - 1) > This->Media->LastBlock) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (BufferSize % BlockSize != 0) {
+ return EFI_BAD_BUFFER_SIZE;
+ }
+
+ DataBuffer = (UINT8*)(UINTN)Buffer;
+ if (Shr64((UINTN)Buffer, 32)) {
+ Pages = EFI_SIZE_TO_PAGES(BufferSize);
+ DataBuffer = (UINT8*)0xFFFFFFFF;
+ Status = gBS->AllocatePages(AllocateMaxAddress, EfiBootServicesData,
+ Pages, (EFI_PHYSICAL_ADDRESS*)&DataBuffer);
+ if (!(EFI_ERROR(Status))) {
+ if (ReadWrite == WRITE) {
+ gBS->CopyMem(DataBuffer, Buffer, BufferSize);
+ }
+ } else {
+ DataBuffer = (UINT8*)(UINTN)Buffer;
+ }
+ }
+
+ BytesRemaining = (UINT32)BufferSize;
+ Buf = (UINT32)(UINTN)DataBuffer;
+ while (BytesRemaining) {
+ BytesToTransfer = (BytesRemaining > 0x10000)? 0x10000 : BytesRemaining;
+ //
+ // Prepare URP_STRUC with USB_MassRead attributes
+ //
+ Parameters.bFuncNumber = USB_API_MASS_DEVICE_REQUEST;
+ Parameters.bSubFunc = (ReadWrite == READ)? USB_MASSAPI_READ_DEVICE : USB_MASSAPI_WRITE_DEVICE;
+ Parameters.ApiData.MassRead.DevAddr = (UINT8)MassDev->LogicalAddress;//MassDev->DevInfo->bDeviceAddress;
+ Parameters.ApiData.MassRead.StartLba = Lba;
+ Parameters.ApiData.MassRead.NumBlks = (UINT16)(BytesToTransfer/((DEV_INFO*)MassDev->DevInfo)->wBlockSize);
+ Parameters.ApiData.MassRead.PreSkipSize = 0;
+ Parameters.ApiData.MassRead.PostSkipSize = 0;
+ Parameters.ApiData.MassRead.BufferPtr = Buf;
+
+ /*
+ if (ReadWrite == READ) {
+ USB_DEBUG(DEBUG_LEVEL_3, "Reading...%x bytes, Lba %x ", BytesToTransfer, CurrentLba);
+ } else {
+ USB_DEBUG(DEBUG_LEVEL_3, "Writng...%x bytes, Lba %x ", BytesToTransfer, CurrentLba);
+ }
+ */
+ InvokeUsbApi(&Parameters);
+
+ switch (Parameters.bRetValue) {
+ case USB_ATA_NO_MEDIA_ERR:
+ Status = EFI_NO_MEDIA; // No media in drive
+ This->Media->MediaPresent = FALSE;
+ break;
+ case USB_ATA_WRITE_PROTECT_ERR:
+ Status = (ReadWrite == READ)? EFI_SUCCESS : EFI_WRITE_PROTECTED;
+ if (Status == EFI_WRITE_PROTECTED)
+ This->Media->ReadOnly = TRUE;
+ break;
+ case USB_ATA_TIME_OUT_ERR: // 0x080 Command timed out error
+ case USB_ATA_DRIVE_NOT_READY_ERR: // 0x0AA Drive not ready error
+ case USB_ATA_DATA_CORRECTED_ERR: // 0x011 Data corrected error
+ case USB_ATA_PARAMETER_FAILED: // 0x007 Bad parameter error
+ case USB_ATA_MARK_NOT_FOUND_ERR: // 0x002 Address mark not found error
+ case USB_ATA_READ_ERR: // 0x004 Read error
+ case USB_ATA_UNCORRECTABLE_ERR: // 0x010 Uncorrectable data error
+ case USB_ATA_BAD_SECTOR_ERR: // 0x00A Bad sector error
+ case USB_ATA_GENERAL_FAILURE: // 0x020 Controller general failure
+ Status = EFI_DEVICE_ERROR;
+ break;
+ default:
+ Status = EFI_SUCCESS;
+ }
+ // USB_DEBUG(DEBUG_LEVEL_3, "Status= %r\n", Status);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ BytesRemaining = BytesRemaining - BytesToTransfer;
+ Buf = Buf + BytesToTransfer;
+ Lba = Lba + (UINT32)BytesToTransfer/((DEV_INFO*)(MassDev->DevInfo))->wBlockSize;
+ }
+
+ if (DataBuffer != Buffer) {
+ if (ReadWrite == READ) {
+ gBS->CopyMem(Buffer, DataBuffer, BufferSize - BytesRemaining);
+ }
+ gBS->FreePages((EFI_PHYSICAL_ADDRESS)DataBuffer, Pages);
+ }
+
+ return Status;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiUsbBlkIoReadBlocks
+//
+// Description: Read the requested number of blocks from the device
+//
+// Input: This EFI_BLOCK_IO *: A pointer to the Block I/O protocol
+// interface
+// MediaId UINT32: The media id that the read request is for
+// LBA EFI_LBA: The starting logic block address to read from
+// on the device
+// BufferSize UINTN: The size of the Buffer in bytes
+// Buffer VOID *: A pointer to the destination buffer for the data
+//
+//
+// Output: EFI_SUCCESS: The data was read correctly from the device
+// EFI_DEVICE_ERROR:The device reported an error while attempting
+// to perform the read operation
+// EFI_NO_MEDIA: There is no media in the device
+// EFI_MEDIA_CHANGED: The MediaId is not for the current media
+// EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple
+// of the intrinsic block size of the device
+// EFI_INVALID_PARAMETER:The read request contains LBAs that are
+// not valid, or the buffer is not on proper alignment
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbBlkIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+)
+
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+ Status = AmiUsbBlkIoReadWrite(This, MediaId, Lba, BufferSize, Buffer, READ);
+
+ gBS->RestoreTPL(OldTpl);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: AmiUsbBlkIoWriteBlocks
+//
+// Description: Write a specified number of blocks to the device
+//
+// Input: This EFI_BLOCK_IO *: A pointer to the Block I/O protocol
+// interface
+// MediaId UINT32: The media id that the write request is for
+// LBA EFI_LBA: The starting logic block address to written
+// BufferSize UINTN: The size of the Buffer in bytes
+// Buffer VOID *: A pointer to the destination buffer for the data
+//
+//
+// Output: EFI_SUCCESS: The data were written correctly to the device
+// EFI_WRITE_PROTECTED: The device can not be written to
+// EFI_NO_MEDIA: There is no media in the device
+// EFI_MEDIA_CHANGED: The MediaId is not for the current media
+// EFI_DEVICE_ERROR: The device reported an error while attempting
+// to perform the write operation
+// EFI_BAD_BUFFER_SIZE: The BufferSize parameter is not a multiple
+// of the intrinsic block size of the device
+// EFI_INVALID_PARAMETER:The read request contains LBAs that are
+// not valid, or the buffer is not on proper alignment
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbBlkIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA Lba,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+ )
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ if(AmiBlkWriteProtection != NULL) {
+ // Get user input
+ Status = AmiBlkWriteProtection->BlockIoWriteProtectionCheck(
+ AmiBlkWriteProtection,
+ This,
+ Lba,
+ BufferSize
+ );
+ // Abort operation if denied
+ if(Status == EFI_ACCESS_DENIED) {
+ return Status;
+ }
+ }
+#endif
+ OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+ Status = AmiUsbBlkIoReadWrite(This, MediaId, Lba, BufferSize, Buffer, WRITE);
+
+ gBS->RestoreTPL(OldTpl);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbMassSupported
+//
+// Description: Verifies if usb mouse support can be installed on a device
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static
+EFI_STATUS
+UsbMassSupported (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *Dp)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR Desc;
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ //(EIP99882+)>
+ if (!gUsbData->UsbSetupData.UsbMassDriverSupport) {
+ return EFI_UNSUPPORTED;
+ }
+ //<(EIP99882+)
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if( EFI_ERROR(Status))
+ return Status;
+
+ VERIFY_EFI_ERROR(
+ gBS->CloseProtocol (
+ Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller));
+
+ Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &Desc );
+ if(EFI_ERROR(Status))
+ return EFI_UNSUPPORTED;
+
+ if ( Desc.InterfaceClass == BASE_CLASS_MASS_STORAGE &&
+ (
+ Desc.InterfaceProtocol == PROTOCOL_CBI ||
+ Desc.InterfaceProtocol == PROTOCOL_CBI_NO_INT ||
+ Desc.InterfaceProtocol == PROTOCOL_BOT ))
+ {
+ return EFI_SUCCESS;
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbMassStart
+//
+// Description: Starts USB mass storage device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static
+EFI_STATUS
+UsbMassStart(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *Dp
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ DEV_INFO *DevInfo;
+ USBDEV_T* Dev;
+ HC_STRUC* HcData;
+ UINT8 UsbStatus;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USB: UsbMassStart: starting...\n");
+ //
+ // Open Protocols
+ //
+ Status = gBS->OpenProtocol(Controller, &gEfiUsbIoProtocolGuid,
+ &UsbIo, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_BY_DRIVER);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Dev = UsbIo2Dev(UsbIo);
+
+ if (Dev == NULL) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ DevInfo = Dev->dev_info;
+
+ if (DevInfo->bLUN) {
+ USB_DEBUG(DEBUG_LEVEL_3, "USB: Skiping LUN %d\n", DevInfo->bLUN);
+ } else {
+ HcData = gUsbData->HcTable[Dev->dev_info->bHCNumber - 1];
+ UsbStatus = UsbSmiReConfigDevice(HcData, Dev->dev_info);
+ if (UsbStatus != USB_SUCCESS) {
+ USB_DEBUG(DEBUG_LEVEL_3,
+ "USB: UsbMassStart: failed to Reconfigure: %d\n", UsbStatus);
+ gBS->CloseProtocol(Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+ return EFI_DEVICE_ERROR;
+ }
+ } //End Reconfigure
+
+ if (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT)) {
+ gBS->CloseProtocol(Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = InstallUsbMass(Controller, DevInfo);
+
+ if (EFI_ERROR(Status)) {
+
+ gBS->CloseProtocol(Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller);
+ return Status;
+ }
+
+#if defined CORE_COMBINED_VERSION && (CORE_COMBINED_VERSION > 0x4028E)
+ if(AmiBlkWriteProtection == NULL) {
+ Status = pBS->LocateProtocol(&gAmiBlockIoWriteProtectionProtocolGuid, NULL, &AmiBlkWriteProtection);
+ if(EFI_ERROR(Status)) {
+ AmiBlkWriteProtection = NULL;
+ }
+ }
+#endif
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbMassStop
+//
+// Description: Stops USB mass storage device and removes BlkIo
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbMassStop(
+ EFI_DRIVER_BINDING_PROTOCOL *Binding,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+ EFI_STATUS Status;
+ EFI_BLOCK_IO_PROTOCOL *BlockIo;
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->OpenProtocol ( Controller, &gEfiBlockIoProtocolGuid,
+ &BlockIo, Binding->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL ));
+ if (EFI_ERROR(Status))
+ return Status;
+
+ Status = UninstallUSBMass((USB_MASS_DEV*)BlockIo);
+
+ VERIFY_EFI_ERROR(
+ gBS->CloseProtocol (
+ Controller, &gEfiUsbIoProtocolGuid,
+ Binding->DriverBindingHandle, Controller));
+
+ return Status;
+}
+
+
+CHAR16*
+UsbMassGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbMassInit
+//
+// Description: USB Mass storage driver entry point
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbMassInit(
+ EFI_HANDLE ImageHandle,
+ EFI_HANDLE ServiceHandle
+)
+{
+ //(EIP59272)>
+ static NAME_SERVICE_T Names;
+ static EFI_DRIVER_BINDING_PROTOCOL Binding = {
+ UsbMassSupported,
+ UsbMassStart,
+ UsbMassStop,
+ USBMASS_DRIVER_VERSION,
+ NULL,
+ NULL };
+
+ Binding.DriverBindingHandle = ServiceHandle;
+ Binding.ImageHandle = ImageHandle;
+
+ return gBS->InstallMultipleProtocolInterfaces(
+ &Binding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &Binding,
+ &gEfiComponentName2ProtocolGuid, InitNamesProtocol(&Names,
+ L"USB Mass Storage driver", UsbMassGetControllerName),
+ NULL);
+ //<(EIP59272)
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbms.c b/Core/EM/usb/efiusbms.c
new file mode 100644
index 0000000..e180985
--- /dev/null
+++ b/Core/EM/usb/efiusbms.c
@@ -0,0 +1,670 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbms.c 30 3/02/16 9:43p Wilsonlee $
+//
+// $Revision: 30 $
+//
+// $Date: 3/02/16 9:43p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbms.c $
+//
+// 30 3/02/16 9:43p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 29 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 28 2/18/14 9:54p Wilsonlee
+// Add a #ifndef CR around the definition of the CR MACRO.
+//
+// 27 12/30/13 3:48a Wilsonlee
+// [TAG] EIP148707
+// [Category] Improvement
+// [Description] We need to store wheel data before clearing the buffer.
+// [Files] usbms.c, efiusbms.c
+//
+// 26 10/24/13 10:25p Wilsonlee
+// [TAG] EIP131339
+// [Category] Improvement
+// [Description] Synchronize USB\Touch device mouse pointer position.
+// [Files] efiusbms.c, efiusbpoint.c
+//
+// 25 7/24/13 2:35a Roberthsu
+// [TAG] EIP121333
+// [Category] Improvement
+// [Description] Multiple USB mouse support for UEFI USB mouse driver
+// [Files] efiusbhid.c,efiusbkb.h,efiusbms.c
+//
+// 24 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 23 10/27/12 10:26a Ryanchou
+// [TAG] EIP104380
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB mouse button are lost in Wave application
+// [RootCause] WaitForInput() clears button state, button is incorrect
+// when calling GetState().
+// [Solution] Keep the button state in WaitForInput().
+// [Files] efiusbms.c
+//
+// 22 9/19/11 9:31a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 21 7/12/11 11:40p Ryanchou
+// [TAG] EIP63752
+// [Bug fix] Left click status lost on USB Mousee.
+// [Symptom] First time Getstate will return that Left Click is Pressed.
+// On the Second GetState Call it will return that Left click released.
+// [Root Cause] We are clearing the Button status once we send the data.
+// So next time getstate will return that left click is released.
+// [Solution] We should not clear the ButtonStatus.Insteed of OR the data,
+// we should have taken directly from the fpBuffer.
+//
+// 20 5/03/11 10:48a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 19 3/04/11 1:31p Olegi
+//
+// 18 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 17 12/02/10 2:24p Olegi
+// [TAG] EIP48695
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] SCT Error for USB HC SyncInterruptTransfer API
+// [RootCause] Checking for endpoint being IN was missing.
+// [Solution] Corrected EFI USB mouse driver that issues the
+// SyncInterruptTransfer with the wrong endpoint address.
+//
+// 16 10/30/10 2:40a Ryanchou
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 15 9/16/10 12:59p Olegi
+// EIP40959:: Modifications in UpdateUsbMouseData. Depending on the
+// project settings mouse data is either obtained via polling TD, or using
+// direct mouse access.
+//
+// 14 5/11/10 9:33a Olegi
+// Corrected the mouse data report. EIP37798
+//
+// 13 2/23/10 1:36p Olegi
+// Work around Klockwork issues. EIP34370
+//
+// 12 1/07/09 3:11p Olegi
+// EIP#16970: Fix for the USB mouse right click issue:
+// If the right mouse button is pressed, value of variable "RightButton"
+// is not updated properly.
+// The variable "RightButton" is BOOLEAN. But when right click is done on
+// USB mouse, the value of "RightButton" is 0x02, which is not correct.
+// The value should be TRUE if right click is done.
+// Changed the code to save TRUE in RightButton instead of saving as 0x02.
+// Even if we typecast the result of (bData & 0x02) to BOOLEAN and save it
+// in a BOOLEAN variable RightButton, it is saved as 0x02. Hence changed
+// the code to save TRUE if BIT 1 in variable bData is set else save FALSE
+// in variable RightButton.
+//
+// 10 9/16/08 2:05p Olegi
+// Modifications in UpdateUsbMouseData, EIP#15780.
+//
+// 9 7/07/08 4:01p Olegi
+//
+// 8 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 7 3/20/07 1:29p Olegi
+//
+// 5 10/12/06 7:12p Andriyn
+// Support unexpected plug-off USB device
+//
+// 4 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 3 5/19/05 8:06p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 2 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EFIUSBMS.C
+//
+// Description: EFI USB Mouse Driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "componentname.h"
+#include "usbbus.h"
+
+#define USBMS_DRIVER_VERSION 2
+
+#define USB_MOUSE_DEV_SIGNATURE EFI_SIGNATURE_32('u','m','o','u')
+
+#ifndef CR
+#define CR(record, TYPE, field, signature) _CR(record, TYPE, field)
+#endif
+#define USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL(a,b) \
+ CR(a, USB_MOUSE_DEV, b, USB_MOUSE_DEV_SIGNATURE)
+
+typedef struct
+{
+ UINTN Signature;
+ UINT8 NumberOfButtons;
+ INT32 XLogicMax;
+ INT32 XLogicMin;
+ INT32 YLogicMax;
+ INT32 YLogicMin;
+ EFI_SIMPLE_POINTER_PROTOCOL SimplePointerProtocol;
+ EFI_SIMPLE_POINTER_MODE Mode;
+ UINT8 Endpoint;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+} USB_MOUSE_DEV;
+
+static VOID
+UsbMouseWaitForInput (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+static EFI_STATUS
+UpdateUsbMouseData (
+ EFI_SIMPLE_POINTER_PROTOCOL *This,
+ EFI_SIMPLE_POINTER_STATE *State
+ );
+
+//
+// Mouse Protocol
+//
+static EFI_STATUS
+GetMouseState(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ OUT EFI_SIMPLE_POINTER_STATE *MouseState
+);
+
+static EFI_STATUS
+UsbMouseReset(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+BOOLEAN StateChanged;
+UINT8 ButtonsState;
+EFI_SIMPLE_POINTER_STATE MsState;
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitUSBMouse
+//
+// Description: Initialize USB mouse device and all private data structures.
+//
+// Input: None
+//
+// Output: EFI_SUCCESS or EFI_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitUSBMouse()
+{
+ EfiZeroMem (&MsState, sizeof(EFI_SIMPLE_POINTER_STATE));
+ ButtonsState = 0;
+ StateChanged = FALSE;
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallUSBMouse
+//
+// Description: Installs SimplePointerProtocol interface on a given controller.
+//
+// Input: Controller - controller handle to install interface on.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+InstallUSBMouse(
+ EFI_HANDLE Controller,
+ EFI_USB_IO_PROTOCOL *UsbIo,
+ DEV_INFO *DevInfo
+)
+{
+ USB_MOUSE_DEV *UsbMouse;
+ EFI_STATUS Status;
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(USB_MOUSE_DEV),
+ &UsbMouse));
+
+ EfiZeroMem(UsbMouse, sizeof(USB_MOUSE_DEV));
+
+ //
+ // Initialize UsbMouseDevice
+ //
+ UsbMouse->Signature = USB_MOUSE_DEV_SIGNATURE;
+ UsbMouse->SimplePointerProtocol.GetState = GetMouseState;
+ UsbMouse->SimplePointerProtocol.Reset = UsbMouseReset;
+ UsbMouse->SimplePointerProtocol.Mode = &UsbMouse->Mode;
+
+ UsbMouse->NumberOfButtons = 2;
+ UsbMouse->XLogicMax = UsbMouse->YLogicMax = 127;
+ UsbMouse->XLogicMin = UsbMouse->YLogicMin = -127;
+
+ UsbMouse->Mode.LeftButton = TRUE;
+ UsbMouse->Mode.RightButton = TRUE;
+ UsbMouse->Mode.ResolutionX = 8;
+ UsbMouse->Mode.ResolutionY = 8;
+ UsbMouse->Mode.ResolutionZ = 1;
+
+ UsbMouse->UsbIo = UsbIo;
+ UsbMouse->Endpoint = DevInfo->IntInEndpoint;
+
+ UsbMouseReset(NULL, FALSE);
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbMouseWaitForInput,
+ UsbMouse,
+ &((UsbMouse->SimplePointerProtocol).WaitForInput)
+ ));
+
+ USB_DEBUG(DEBUG_LEVEL_4, "Mouse event is created, status = %r\n", Status);
+
+ //
+ // Install protocol interfaces for the USB mouse device
+ //
+ VERIFY_EFI_ERROR(
+ Status = gBS->InstallProtocolInterface(
+ &Controller,
+ &gEfiSimplePointerProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &UsbMouse->SimplePointerProtocol));
+
+ USB_DEBUG(DEBUG_LEVEL_4, "Mouse protocol is installed, status = %r\n", Status);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UninstallUSBMouse
+//
+// Description: Stops USB mouse device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UninstallUSBMouse (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+ EFI_STATUS Status;
+ EFI_SIMPLE_POINTER_PROTOCOL *SimplePoint;
+ USB_MOUSE_DEV *UsbMouse = 0;
+
+
+ Status = gBS->OpenProtocol(Controller,
+ &gEfiSimplePointerProtocolGuid,
+ (VOID **)&SimplePoint,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL);
+
+ UsbMouse = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL(SimplePoint,SimplePointerProtocol);
+
+ Status = gBS->UninstallProtocolInterface(Controller, &gEfiSimplePointerProtocolGuid,
+ &UsbMouse->SimplePointerProtocol);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ VERIFY_EFI_ERROR(gBS->CloseEvent(
+ (UsbMouse->SimplePointerProtocol).WaitForInput));
+
+ gBS->FreePool(UsbMouse);
+
+ return Status;
+}
+
+
+/************ SimplePointer Protocol implementation routines*************/
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbMouseReset
+//
+// Description: This routine is a part of SimplePointerProtocol implementation;
+// it resets USB mouse.
+//
+// Input: This - A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
+// ExtendedVerification - Indicates that the driver may perform
+// a more exhaustive verification operation of the device during
+// reset.
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS
+UsbMouseReset(
+ IN EFI_SIMPLE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+ EfiZeroMem (
+ &MsState,
+ sizeof(EFI_SIMPLE_POINTER_STATE)
+ );
+ StateChanged = FALSE;
+
+ EfiZeroMem (&gUsbData->MouseData, sizeof(MOUSE_DATA));
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetMouseState
+//
+// Description: This routine is a part of SimplePointerProtocol implementation;
+// it retrieves the current state of a pointer device.
+//
+// Input: This - A pointer to the EFI_SIMPLE_POINTER_PROTOCOL instance.
+// MouseState - A pointer to the state information on the pointer
+// device. Type EFI_SIMPLE_POINTER_STATE is defined as follows:
+// typedef struct {
+// INT32 RelativeMovementX;
+// INT32 RelativeMovementY;
+// INT32 RelativeMovementZ;
+// BOOLEAN LeftButton;
+// BOOLEAN RightButton;
+// } EFI_SIMPLE_POINTER_STATE;
+//
+// Output: EFI_SUCCESS - The state of the pointer device was returned
+// in MouseState.
+// EFI_NOT_READY - The state of the pointer device has not changed
+// since the last call to GetMouseState().
+// EFI_DEVICE_ERROR - A device error occurred while attempting to
+// retrieve the pointer device’s current state.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS
+GetMouseState(
+ EFI_SIMPLE_POINTER_PROTOCOL *This,
+ EFI_SIMPLE_POINTER_STATE *MouseState
+)
+{
+ if (MouseState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ return UpdateUsbMouseData(This,MouseState);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateUsbMouseData
+//
+// Description: This routine updates current mouse data.
+//
+// Input: Data* - pointer to the data area to be updated.
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS
+UpdateUsbMouseData (
+ EFI_SIMPLE_POINTER_PROTOCOL *This,
+ EFI_SIMPLE_POINTER_STATE *State
+)
+{
+ BOOLEAN LeftButton, RightButton;
+ INT32 rX, rY, rZ;
+ UINT8 bData;
+ EFI_STATUS Status;
+ UINT8 MouseData[4];
+ UINTN DataLength;
+ UINT32 UsbStatus;
+ INT32 Coordinates;
+ USB_MOUSE_DEV *UsbMouse = 0;
+
+ if ((gUsbData->dUSBStateFlag & USB_FLAG_EFIMS_DIRECT_ACCESS) && (This != NULL) ){
+ UsbMouse = USB_MOUSE_DEV_FROM_MOUSE_PROTOCOL(This,SimplePointerProtocol);
+ // Get the data from mouse
+ DataLength = 4;
+
+ Status = UsbMouse->UsbIo->UsbSyncInterruptTransfer(
+ UsbMouse->UsbIo,
+ UsbMouse->Endpoint | 0x80, // IN
+ MouseData,
+ &DataLength,
+ 0, // Timeout
+ &UsbStatus
+ );
+
+ gUsbData->MouseData.ButtonStatus = MouseData[0];
+
+ Coordinates = (INT8)MouseData[1];
+ gUsbData->MouseData.MouseX += Coordinates;
+ Coordinates = (INT8)MouseData[2];
+ gUsbData->MouseData.MouseY += Coordinates;
+ }
+
+ bData = gUsbData->MouseData.ButtonStatus & 7;
+
+ //
+ // Check mouse Data
+ //
+ LeftButton=(BOOLEAN)(bData & 0x01)?TRUE:FALSE;
+ RightButton=(BOOLEAN)(bData & 0x02)?TRUE:FALSE;
+
+ rX = gUsbData->MouseData.MouseX;
+ rY = gUsbData->MouseData.MouseY;
+ rZ = - (gUsbData->MouseData.MouseZ);
+
+ if (StateChanged == FALSE) {
+ if (rX == 0 && rY == 0 && rZ == 0 &&
+ bData == ButtonsState) {
+ return EFI_NOT_READY;
+ }
+ StateChanged = TRUE;
+ }
+
+ gUsbData->MouseData.MouseX=0;
+ gUsbData->MouseData.MouseY=0;
+ gUsbData->MouseData.MouseZ=0;
+
+ ButtonsState = bData;
+ MsState.LeftButton = LeftButton;
+ MsState.RightButton = RightButton;
+ MsState.RelativeMovementX += rX;
+ MsState.RelativeMovementY += rY;
+ MsState.RelativeMovementZ += rZ;
+
+
+ if (State != NULL) {
+ EfiCopyMem(State, &MsState, sizeof(EFI_SIMPLE_POINTER_STATE));
+ //
+ // Clear previous move state
+ //
+ MsState.RelativeMovementX = 0;
+ MsState.RelativeMovementY = 0;
+ MsState.RelativeMovementZ = 0;
+ StateChanged = FALSE;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbMouseWaitForInput
+//
+// Description: Event notification function for SIMPLE_POINTER.WaitForInput
+// event. Signal the event if there is input from mouse.
+//
+// Input: Event - event to signal in case of mouse activity
+// Context - data to pass along with the event.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static VOID
+EFIAPI
+UsbMouseWaitForInput (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ USB_MOUSE_DEV *UsbMouse = (USB_MOUSE_DEV*)Context;
+
+ Status = UpdateUsbMouseData (&UsbMouse->SimplePointerProtocol,NULL);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ //
+ // Someone is waiting on the mouse event, if there's
+ // input from mouse, signal the event
+ //
+ gBS->SignalEvent(Event);
+
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbMsInit
+//
+// Description: Initialize USB Mouse driver
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+UsbMsGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ return 0;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/efiusbpoint.c b/Core/EM/usb/efiusbpoint.c
new file mode 100644
index 0000000..d8ba13b
--- /dev/null
+++ b/Core/EM/usb/efiusbpoint.c
@@ -0,0 +1,500 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbpoint.c 7 5/28/15 5:01a Wilsonlee $
+//
+// $Revision: 7 $
+//
+// $Date: 5/28/15 5:01a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/efiusbpoint.c $
+//
+// 7 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 6 5/06/14 5:17a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 5 10/24/13 10:25p Wilsonlee
+// [TAG] EIP131339
+// [Category] Improvement
+// [Description] Synchronize USB\Touch device mouse pointer position.
+// [Files] efiusbms.c, efiusbpoint.c
+//
+// 4 11/05/12 12:56a Rameshr
+// [TAG] EIP103791
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] WaitForInput function destroys the absolute device data
+// [RootCause] WaitforInput checks for the Input data and throws the
+// data out from local buffer
+// [Solution] Data availability checking done in current buffer, instead
+// using the UpdateUsbAbsMouseData function
+// [Files] efiusbpoint.c
+//
+// 3 11/23/11 4:46a Roberthsu
+// [TAG] EIP74509
+// [Category] Improvement
+// [Description] Correct comment header
+// [Files] efiusbpoint.c
+//
+// 2 8/05/11 7:29a Ryanchou
+// [TAG] EIP66231
+// [Category] Improvement
+// [Description] Remove token POINT_SUPPORT.Add token USB_DEV_POINT.Add
+// check core version in point driver.Add check device descriptor to send
+// get lang id command.Modify check button usage page.
+// [Files] efiusbhid.c, efiusbpoint.c, usbbus.c, usbhid.c, usbpoint.c,
+// usbsrc.sdl
+//
+// 1 7/15/11 6:26a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EfiusbAbs.C
+//
+// Description: EFI USB Absolute pointer Driver
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+#include "componentname.h"
+#include "usbbus.h"
+
+#if USB_DEV_POINT //(EIP66231)
+
+#include "Protocol\AbsPointerProtocol.h"
+#define USB_ABSOLUTE_MOUSE_DRIVER_VERSION 1
+
+#define USB_ABSOLUTE_MOUSE_DEV_SIGNATURE EFI_SIGNATURE_32('u','a','b','s')
+#define USB_ABSOLUTE_MOUSE_DEV_FROM_ABSOLUTE_PROTOCOL(a) \
+ CR(a, USB_ABSOLUTE_MOUSE_DEV, AbsolutePointerProtocol, USB_ABSOLUTE_MOUSE_DEV_SIGNATURE)
+
+EFI_GUID gEfiAbsolutePointerProtocolGuid=EFI_ABSOLUTE_POINTER_PROTOCOL_GUID;
+
+typedef struct
+{
+ UINTN Signature;
+ EFI_ABSOLUTE_POINTER_PROTOCOL AbsolutePointerProtocol;
+ EFI_ABSOLUTE_POINTER_STATE State;
+ EFI_ABSOLUTE_POINTER_MODE Mode;
+ BOOLEAN StateChanged;
+} USB_ABSOLUTE_MOUSE_DEV;
+
+static VOID
+UsbAbsMouseWaitForInput (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+static EFI_STATUS
+UpdateUsbAbsMouseData (
+ IN ABS_MOUSE *Data
+ );
+
+//
+// ABS Protocol
+//
+static EFI_STATUS
+GetAbsMouseState(
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
+ OUT EFI_ABSOLUTE_POINTER_STATE *AbsState
+);
+
+static EFI_STATUS
+UsbAbsMouseReset(
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ );
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+USB_ABSOLUTE_MOUSE_DEV *UsbAbsMouseDevice=0;
+static int gAbsMouseRefCount=0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: InstallUSBAbsMouse
+//
+// Description: Installs ABSOLUTEPointerProtocol interface on a given controller.
+//
+// Input: Controller - controller handle to install interface on.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUSBAbsMouse(
+ EFI_HANDLE Controller,
+ DEV_INFO *pDevInfo
+)
+{
+ EFI_STATUS Status;
+ int RefCount;
+
+ ATOMIC( RefCount = gAbsMouseRefCount++ );
+
+ if (RefCount == 0){
+ VERIFY_EFI_ERROR(
+ Status = gBS->AllocatePool(
+ EfiBootServicesData,
+ sizeof(USB_ABSOLUTE_MOUSE_DEV),
+ &UsbAbsMouseDevice));
+
+ EfiZeroMem(UsbAbsMouseDevice, sizeof(USB_ABSOLUTE_MOUSE_DEV));
+
+ //
+ // Initialize UsbABSDevice
+ //
+ UsbAbsMouseDevice->Signature = USB_ABSOLUTE_MOUSE_DEV_SIGNATURE;
+
+ UsbAbsMouseDevice->AbsolutePointerProtocol.GetState = GetAbsMouseState;
+ UsbAbsMouseDevice->AbsolutePointerProtocol.Reset = UsbAbsMouseReset;
+ UsbAbsMouseDevice->AbsolutePointerProtocol.Mode = &UsbAbsMouseDevice->Mode;
+
+ UsbAbsMouseDevice->Mode.Attributes = EFI_ABSP_SupportsPressureAsZ;
+
+ UsbAbsMouseDevice->Mode.AbsoluteMinX = 0;
+ UsbAbsMouseDevice->Mode.AbsoluteMinY = 0;
+ UsbAbsMouseDevice->Mode.AbsoluteMinZ = 0;
+ UsbAbsMouseDevice->Mode.AbsoluteMaxX = pDevInfo->HidReport.AbsMaxX;
+ UsbAbsMouseDevice->Mode.AbsoluteMaxY = pDevInfo->HidReport.AbsMaxY;
+ UsbAbsMouseDevice->Mode.AbsoluteMaxZ = 0;
+
+ EfiZeroMem (&UsbAbsMouseDevice->State, sizeof(EFI_ABSOLUTE_POINTER_STATE));
+ UsbAbsMouseDevice->StateChanged = FALSE;
+
+ UsbAbsMouseReset(NULL, FALSE);
+
+ VERIFY_EFI_ERROR(
+ Status = gBS->CreateEvent (
+ EFI_EVENT_NOTIFY_WAIT,
+ EFI_TPL_NOTIFY,
+ UsbAbsMouseWaitForInput,
+ UsbAbsMouseDevice,
+ &((UsbAbsMouseDevice->AbsolutePointerProtocol).WaitForInput)
+ ));
+
+ USB_DEBUG(DEBUG_LEVEL_4, "ABS event is created, status = %r\n", Status);
+ }
+ //
+ // Install protocol interfaces for the USB ABS device
+ //
+ VERIFY_EFI_ERROR(
+ Status = gBS->InstallProtocolInterface(
+ &Controller,
+ &gEfiAbsolutePointerProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &UsbAbsMouseDevice->AbsolutePointerProtocol));
+
+ USB_DEBUG(DEBUG_LEVEL_4, "ABS protocol is installed, status = %r\n", Status);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UninstallUSBAbsMouse
+//
+// Description: Uninstalls ABSOLUTEPointerProtocol interface.
+//
+// Input: Controller - controller handle.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UninstallUSBAbsMouse(
+ IN EFI_HANDLE Controller
+)
+{
+ EFI_STATUS Status;
+ int RefCount;
+
+ Status = gBS->UninstallProtocolInterface(
+ Controller,
+ &gEfiAbsolutePointerProtocolGuid,
+ &UsbAbsMouseDevice->AbsolutePointerProtocol);
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ ATOMIC( RefCount = --gAbsMouseRefCount );
+ if (RefCount == 0) {
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (
+ (UsbAbsMouseDevice->AbsolutePointerProtocol).WaitForInput));
+
+ gBS->FreePool(UsbAbsMouseDevice);
+ UsbAbsMouseDevice = 0;
+ }
+ return Status;
+}
+
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbAbsMouseReset
+//
+// Description: This routine is a part of ABSOLUTEPointerProtocol implementation;
+// it resets USB ABS.
+//
+// Input: This - A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.
+// ExtendedVerification - Indicates that the driver may perform
+// a more exhaustive verification operation of the device during
+// reset.
+//
+// Output: EFI_SUCCESS or EFI_DEVICE_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS
+UsbAbsMouseReset(
+ IN EFI_ABSOLUTE_POINTER_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+ )
+{
+
+ EfiZeroMem (
+ &UsbAbsMouseDevice->State,
+ sizeof(EFI_ABSOLUTE_POINTER_STATE)
+ );
+ UsbAbsMouseDevice->StateChanged = FALSE;
+
+ EfiZeroMem (&gUsbData->AbsMouseData, 10 * sizeof(ABS_MOUSE));
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: GetAbsMouseState
+//
+// Description: This routine is a part of ABSOLUTEPointerProtocol implementation;
+// it retrieves the current state of a pointer device.
+//
+// Input: This - A pointer to the EFI_ABSOLUTE_POINTER_PROTOCOL instance.
+// ABSState - A pointer to the state information on the pointer
+// device. Type EFI_ABSOLUTE_POINTER_STATE is defined as follows:
+// typedef struct {
+// INT32 RelativeMovementX;
+// INT32 RelativeMovementY;
+// INT32 RelativeMovementZ;
+// BOOLEAN LeftButton;
+// BOOLEAN RightButton;
+// } EFI_ABSOLUTE_POINTER_STATE;
+//
+// Output: EFI_SUCCESS - The state of the pointer device was returned
+// in ABSState.
+// EFI_NOT_READY - The state of the pointer device has not changed
+// since the last call to GetABSState().
+// EFI_DEVICE_ERROR - A device error occurred while attempting to
+// retrieve the pointer device’s current state.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS
+GetAbsMouseState(
+ EFI_ABSOLUTE_POINTER_PROTOCOL *This,
+ EFI_ABSOLUTE_POINTER_STATE *AbsMouseState
+)
+{
+ if (AbsMouseState == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ UpdateUsbAbsMouseData (&gUsbData->AbsMouseData[0]);
+
+ if (UsbAbsMouseDevice->StateChanged == FALSE) {
+ return EFI_NOT_READY;
+ }
+
+ EfiCopyMem(
+ AbsMouseState,
+ &UsbAbsMouseDevice->State,
+ sizeof(EFI_ABSOLUTE_POINTER_STATE)
+ );
+ UsbAbsMouseDevice->StateChanged = FALSE;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UpdateUsbAbsMouseData
+//
+// Description: This routine updates current AbsMouse data.
+//
+// Input: Data* - pointer to the data area to be updated.
+//
+// Output: EFI_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static EFI_STATUS
+UpdateUsbAbsMouseData (
+ ABS_MOUSE *AbsData
+)
+{
+ if(UsbAbsMouseDevice->State.CurrentX != (UINT64)AbsData->Xcoordinate ||
+ UsbAbsMouseDevice->State.CurrentY != (UINT64)AbsData->Ycoordinate ||
+ UsbAbsMouseDevice->State.CurrentZ != (UINT64)AbsData->Pressure ||
+ UsbAbsMouseDevice->State.ActiveButtons != (UINT32)AbsData->ButtonStauts) {
+ UsbAbsMouseDevice->StateChanged=TRUE;
+ } else {
+ UsbAbsMouseDevice->StateChanged=FALSE;
+ }
+
+ if(UsbAbsMouseDevice->StateChanged) {
+ UsbAbsMouseDevice->State.ActiveButtons = (UINT32)AbsData->ButtonStauts;
+ UsbAbsMouseDevice->State.CurrentX = (UINT64)AbsData->Xcoordinate;
+ UsbAbsMouseDevice->State.CurrentY = (UINT64)AbsData->Ycoordinate;
+ UsbAbsMouseDevice->State.CurrentZ = (UINT64)AbsData->Pressure;
+ UsbAbsMouseDevice->Mode.AbsoluteMaxX= (UINT64)AbsData->Max_X;
+ UsbAbsMouseDevice->Mode.AbsoluteMaxY= (UINT64)AbsData->Max_Y;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbAbsMouseWaitForInput
+//
+// Description: Event notification function for AbsMouseOLUTE_POINTER.WaitForInput
+// event. Signal the event if there is input from AbsMouse.
+//
+// Input: Event - event to signal in case of AbsMouse activity
+// Context - data to pass along with the event.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+static VOID
+EFIAPI
+UsbAbsMouseWaitForInput (
+ EFI_EVENT Event,
+ VOID *Context
+ )
+{
+
+ //
+ // Someone is waiting on the AbsMouse event, if there's
+ // input from AbsMouse, signal the event
+ //
+ if(UsbAbsMouseDevice->State.CurrentX != (UINT64)gUsbData->AbsMouseData[0].Xcoordinate ||
+ UsbAbsMouseDevice->State.CurrentY != (UINT64)gUsbData->AbsMouseData[0].Ycoordinate ||
+ UsbAbsMouseDevice->State.CurrentZ != (UINT64)gUsbData->AbsMouseData[0].Pressure ||
+ UsbAbsMouseDevice->State.ActiveButtons != (UINT32)gUsbData->AbsMouseData[0].ButtonStauts) {
+ gBS->SignalEvent(Event);
+ }
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbAbsMsStop
+//
+// Description: Stops USB ABS device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbAbsMsStop (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+)
+{
+ EFI_STATUS Status;
+
+ Status = UninstallUSBAbsMouse(Controller);
+ VERIFY_EFI_ERROR(
+ gBS->CloseProtocol (
+ Controller, &gEfiUsbIoProtocolGuid,
+ This->DriverBindingHandle, Controller));
+ return Status;
+}
+
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/framework.cif b/Core/EM/usb/framework.cif
new file mode 100644
index 0000000..c38ec4f
--- /dev/null
+++ b/Core/EM/usb/framework.cif
@@ -0,0 +1,16 @@
+<component>
+ name = "Framework"
+ category = ModulePart
+ LocalRoot = "core\em\usb\"
+ RefName = "FRAMEWORK"
+[files]
+"\uhcd.mak"
+"\uhcd.h"
+"\rt\usbdef.h"
+"\rt\amidef.h"
+"\uhcd.dxs"
+"\rt\amiusb.dxs"
+"\rt\usbrt.mak"
+"\rt\amiusb.h"
+"\rt\amiusbrtCCID.h"
+<endComponent>
diff --git a/Core/EM/usb/int13/UsbBbs.c b/Core/EM/usb/int13/UsbBbs.c
new file mode 100644
index 0000000..a7aba39
--- /dev/null
+++ b/Core/EM/usb/int13/UsbBbs.c
@@ -0,0 +1,87 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbBbs.c 1 7/03/13 5:25a Ryanchou $
+//
+// $Revision: 1 $
+//
+// $Date: 7/03/13 5:25a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbBbs.c $
+//
+// 1 7/03/13 5:25a Ryanchou
+// [TAG] EIP123988
+// [Category] Improvement
+// [Description] Move the code creating BBS table to end of POST.
+// [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+// UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: UsbBbs.c
+// Description:
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include <AmiDxeLib.h>
+#include <Protocol\AmiUsbController.h>
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CollectUsbBbsDevices
+//
+// Description: Create BBS table for each USB mass storage device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+CollectUsbBbsDevices (
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *AmiUsb;
+
+ Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &AmiUsb);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ AmiUsb->InstallUsbLegacyBootDevices();
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/int13/UsbInt13.c b/Core/EM/usb/int13/UsbInt13.c
new file mode 100644
index 0000000..bae3b21
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.c
@@ -0,0 +1,995 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13.c 30 5/26/15 10:47p Wilsonlee $
+//
+// $Revision: 30 $
+//
+// $Date: 5/26/15 10:47p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13.c $
+//
+// 30 5/26/15 10:47p Wilsonlee
+// [TAG] EIP219177
+// [Category] Improvement
+// [Description] Fixed static code analysis issues in Usb module.
+// [Files] UsbInt13.c, ehci.c, usbbus.c
+//
+// 29 12/24/14 1:12a Wilsonlee
+// [TAG] EIP192517
+// [Category] Improvement
+// [Description] USB Driver handles 0x100 NumHeads as a valid value.
+// [Files] usbmass.c, usbdef.h, UsbInt13.c, UsbInt13.h, UI13.bin,
+// Bfiusb.equ, Bfiusb.asm
+//
+// 28 4/30/14 5:29a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 27 12/15/13 10:13p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 26 11/25/13 10:56p Wilsonlee
+// [TAG] EIP142992
+// [Category] Improvement
+// [Description] Install usb legacy boot device only if the class is
+// mass storage.
+// [Files] UsbInt13.c
+//
+// 25 7/23/13 2:11a Wilsonlee
+// [TAG] EIP127941
+// [Category] Improvement
+// [Description] Replace UI13HDDFunc08 with UI13FDDFunc08 if the media
+// descriptor is a fixed disk.
+// [Files] UsbInt13.h, UsbInt13.c, usbmass.c, usbdef.h, Bfiusb.asm,
+// Bfiusb.equ
+//
+// 24 7/03/13 5:21a Ryanchou
+// [TAG] EIP123988
+// [Category] Improvement
+// [Description] Move the code creating BBS table to end of POST.
+// [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+// UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 23 3/14/12 11:34a Ryanchou
+// [TAG] EIP83895
+// [Category] Improvement
+// [Description] Null-pointer dereference if installation of USBINT13
+// Legacy BIN fails.
+// [Files] UsbInt13.c
+//
+// 22 1/06/12 12:59a Rajeshms
+// [TAG] EIP62737
+// [Category] Improvement
+// [Description] Added USB Device number into USB mass device name
+// string based on SDL Token.
+// [Files] Usb.sdl, usbport.c, usbmass.c, UsbInt13.h, UsbInt13.c,
+// usbbus.c, Bfiusb.equ
+//
+// 21 11/04/11 7:51a Ryanchou
+// [TAG] EIP73024
+// [Category] Improvement
+// [Description] Initial the variable value.
+// [Files] UsbInt13.c
+//
+// 20 10/14/11 4:53a Rajeshms
+// [TAG] EIP70214
+// [Category] New Feature
+// [Description] USB Devices will be reported as BBS_USB devices if
+// BBS_USB_DEVICE_TYPE_SUPPORT is enabled and in setup USB devices will
+// also be shown under USB Device BBS Priorities in Boot Page.
+// [Files] UsbInt13.c
+//
+// 19 7/13/11 4:15a Ryanchou
+// [TAG] EIP59332
+// [Category] Improvement
+// [Description] Modified the Stop function for UHCD and USBBUS to
+// properly stop devices and uninstall the protocols.
+// [Files] uhcd.c, uhcd.h, uhci.c, usbbus.c, UsbInt13.c, usbmisc.c
+//
+// 18 3/04/11 11:42a Olegi
+// [TAG] EIP51927
+// [Category] Improvement
+// [Description] Support for the interface path reporting in USB INT13
+// function 48.
+// [Files] UsbInt13.c
+// UsbInt13.h
+//
+// 17 10/28/10 12:28a Ryanchou
+// EIP45643: Fixed system hangs when hot plug USB mass storage quickly on
+// USB 3.0 port.
+//
+// 16 6/03/09 2:22p Olegi
+//
+// 15 5/21/09 5:13p Olegi
+// Added hotplug devices support.
+//
+// 14 1/21/09 3:39p Olegi
+// Bugfix in the previous change.
+//
+// 13 1/21/09 10:57a Olegi
+// Dependency on AMIUSB and CSM has been added, callback notification is
+// removed.
+//
+// 12 1/13/09 1:18p Olegi
+// Bugfix in the previous change related to EIP#18693.
+//
+// 11 1/13/09 11:44a Olegi
+// Modified the callback notify function installation to cover the
+// situation when the protocol we want to get notified is already
+// installed. EIP#18693.
+//
+// 10 12/05/08 9:51a Olegi
+// GetBbsInfo call moved to ReadyToBoot callback.
+//
+// 9 11/25/08 6:01p Olegi
+// Support for OEM USB Boot Override feature. EIP#17052.
+//
+// 8 11/07/08 9:28a Olegi
+//
+// 7 11/07/08 9:06a Olegi
+//
+// 6 11/03/08 3:53p Olegi
+//
+// 5 11/03/08 9:53a Olegi
+// Update USB SMM data information.
+//
+// 4 10/24/08 3:06p Olegi
+//
+// 3 6/27/08 5:49p Olegi
+//
+// 2 6/27/08 5:48p Olegi
+//
+// 1 5/16/08 12:12p Olegi
+// First check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//****************************************************************************
+//
+// Name: UsbInt13.c
+// Description: USB Int13 driver
+//
+//****************************************************************************
+//<AMI_FHDR_END>
+
+#include "AmiDxeLib.h"
+
+#include "Protocol\AmiUsbController.h"
+#include <Protocol\ComponentName.h>
+#include <Protocol\LegacyBiosExt.h>
+#include <Protocol\LegacyBios.h>
+#include "UsbInt13.h"
+#include "token.h"
+#include "pci.h"
+#include "usbdef.h"
+#include "protocol\usbpolicy.h"
+
+EFI_STATUS InitInt13RuntimeImage();
+
+EFI_LEGACY_BIOS_EXT_PROTOCOL *gBiosExtensions = NULL;
+LEGACY16_TO_EFI_DATA_TABLE_STRUC *gLegacy16Data = 0;
+BOOLEAN gCdromInstalled = FALSE;
+UINT13_DATA *gI13BinData = NULL;
+EFI_USB_PROTOCOL *gAmiUsb = NULL;
+UINT8 gBootOverrideDeviceIndx = 0;
+USB_GLOBAL_DATA *gUsbData = NULL;
+
+
+UINT8 gHotplugFddName[] = "USB Hotplug FDD";
+USB_MASS_DEV gHotplugFloppy;
+
+UINT8 gHotplugHddName[] = "USB Hotplug HDD";
+USB_MASS_DEV gHotplugHardDrive;
+
+UINT8 gHotplugCdromName[] = "USB Hotplug CDROM";
+USB_MASS_DEV gHotplugCDROM;
+
+USB_PCI_LOCATION* gUsbPciLocationTable = NULL;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: UsbInt13EntryPoint
+//
+// Description: USB INT13 driver entry point. Installs callback notification
+// on gEfiUSBProtocolGuid installation.
+//
+// Input: IN EFI_HANDLE ImageHandle,
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output: EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbInt13EntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_EVENT Event;
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+ Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &gAmiUsb);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ gUsbData = gAmiUsb->USBDataPtr;
+
+ Status = InitInt13RuntimeImage();
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ gAmiUsb->InstallUsbLegacyBootDevices = InstallUsbLegacyBootDevices;
+ gAmiUsb->UsbInstallLegacyDevice = UsbInstallLegacyDevice;
+ gAmiUsb->UsbUninstallLegacyDevice = UsbUninstallLegacyDevice;
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK, ReadyToBootNotify, NULL, &Event);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitInt13RuntimeImage
+//
+// Description: Initialization of data structures and placement of runtime
+// code of USB INT13
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitInt13RuntimeImage()
+{
+ EFI_STATUS Status;
+ VOID *Image;
+ UINTN ImageSize = 0;
+
+ //
+ // Check the version of CSM16, support is available for ver 7.55 or later
+ //
+ {
+ UINT8 MjCsmVer = *(UINT8*)0xF0018;
+ UINT8 MnCsmVer = *(UINT8*)0xF0019;
+
+ if (MjCsmVer<8 && MnCsmVer<0x55) return EFI_UNSUPPORTED;
+ }
+
+ gLegacy16Data = (LEGACY16_TO_EFI_DATA_TABLE_STRUC*)(UINTN)(0xF0000 + *(UINT16*)0xFFF4C);
+
+ //
+ // Get the USB INT13 runtime image
+ //
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosExtProtocolGuid, NULL, &gBiosExtensions);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = gBiosExtensions->GetEmbeddedRom(
+ CSM16_MODULEID, CSM16_VENDORID, CSM16_USB_RT_DID, &Image, &ImageSize);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Do the necessary RT data initialization here using Image before it is shadowed
+ //..............................
+ {
+#pragma pack(push, 1)
+ // Update USB SMI information
+ typedef struct _USB_SMM_RTS {
+ UINT8 MiscInfo;
+ UINT16 SmmAttr;
+ UINT32 SmmPort;
+ UINT32 SmmData;
+ } USB_SMM_RTS;
+
+ static USB_SMM_RTS UsbSmmRt = {1, 0, SW_SMI_IO_ADDRESS, USB_SWSMI};
+
+ *(USB_SMM_RTS*)((UINTN)Image + ((UINT13_DATA*)Image)->UsbSmmDataOffset) = UsbSmmRt;
+
+#pragma pack(pop)
+ }
+
+ // Copy image to shadow E000/F000 area
+ (UINTN)gI13BinData = gBiosExtensions->CopyLegacyTable(Image, (UINT16)ImageSize, 0x10, 2);
+ if (gI13BinData == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ gUsbPciLocationTable =
+ (USB_PCI_LOCATION*)((UINTN)gI13BinData + ((UINT13_DATA*)gI13BinData)->UsbPciLocationTableOffset);
+
+ return EFI_SUCCESS;
+}
+
+
+
+BOOLEAN
+HotplugEnabled (
+ HOTPLUG_DEVICE DeviceType
+)
+{
+ if (DeviceType == Floppy)
+ {
+ return ((gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED) ||
+ (gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO));
+ }
+
+ if (DeviceType == HardDrive)
+ {
+ return ((gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED) ||
+ (gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO));
+ }
+
+ if (DeviceType == CDROM)
+ {
+ return ((gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED) ||
+ (gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_AUTO));
+ }
+
+ return FALSE;
+}
+
+
+
+EFI_STATUS
+InitializeHotplugDevices()
+{
+ gHotplugFloppy.DevInfo = &gUsbData->FddHotplugDev;
+ gHotplugFloppy.LogicalAddress = USB_HOTPLUG_FDD_ADDRESS;
+ gHotplugFloppy.Handle = NULL;
+ gHotplugFloppy.PciBDF = 0xffff;
+ gHotplugFloppy.DevString = gHotplugFddName;
+ gHotplugFloppy.StorageType = USB_MASS_DEV_ARMD;
+
+ gHotplugHardDrive.DevInfo = &gUsbData->HddHotplugDev;
+ gHotplugHardDrive.LogicalAddress = USB_HOTPLUG_HDD_ADDRESS;
+ gHotplugHardDrive.Handle = NULL;
+ gHotplugHardDrive.PciBDF = 0xffff;
+ gHotplugHardDrive.DevString = gHotplugHddName;
+ gHotplugHardDrive.StorageType = USB_MASS_DEV_HDD;
+
+ gHotplugCDROM.DevInfo = &gUsbData->CdromHotplugDev;
+ gHotplugCDROM.LogicalAddress = USB_HOTPLUG_CDROM_ADDRESS;
+ gHotplugCDROM.Handle = NULL;
+ gHotplugCDROM.PciBDF = 0xffff;
+ gHotplugCDROM.DevString = gHotplugCdromName;
+ gHotplugCDROM.StorageType = USB_MASS_DEV_CDROM;
+
+ if (HotplugEnabled(Floppy))
+ UsbInstallLegacyDevice(&gHotplugFloppy);
+
+ if (HotplugEnabled(HardDrive))
+ UsbInstallLegacyDevice(&gHotplugHardDrive);
+
+ if (HotplugEnabled(CDROM))
+ UsbInstallLegacyDevice(&gHotplugCDROM);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ReadyToBootNotify
+//
+// Description: READY_TO_BOOT event notification callback. It locates BBS
+// table and changes the priority of device located at index
+// gBootOverrideDeviceIndx to 0 (highest). It also verifies
+// the hotplug devices are properly installed.
+//
+// Input: Event - event signaled by the DXE Core upon installation
+// Context - event context
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID ReadyToBootNotify(EFI_EVENT Event, VOID *Context)
+{
+ UINT16 Priority;
+ UINT16 Index, Index1;
+ BBS_TABLE *BbsTable = NULL;
+ UINT16 HddCount;
+ HDD_INFO *HddInfo;
+ UINT16 BbsCount;
+ EFI_STATUS Status;
+ EFI_LEGACY_BIOS_PROTOCOL *Bios = NULL;
+
+ //
+ // Find BBS table pointer
+ //
+ Status = pBS->LocateProtocol(
+ &gEfiLegacyBiosProtocolGuid, NULL, &Bios);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ Status = Bios->GetBbsInfo(Bios, &HddCount, &HddInfo, &BbsCount, &BbsTable);
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Kill the Event.
+ //
+ pBS->CloseEvent( Event );
+
+ //
+ // Report BBS_USB type devices as other normal Boot devices
+ // like HDD/CDROM/Floppy based on the storagetype by changing
+ // the devicetype in the BBS table.
+ //
+#if BBS_USB_DEVICE_TYPE_SUPPORT
+ for(Index=0; Index<BbsCount; Index++) {
+ if(BbsTable[Index].DeviceType == BBS_USB) {
+ switch( (((BbsTable[Index].InitPerReserved) >> 24) & 0xf) ) {
+ case BAID_TYPE_RMD_FDD:
+ BbsTable[Index].DeviceType = BBS_FLOPPY;
+ break;
+ case BAID_TYPE_RMD_HDD:
+ BbsTable[Index].DeviceType = BBS_HARDDISK;
+ break;
+ case BAID_TYPE_CDROM:
+ BbsTable[Index].DeviceType = BBS_CDROM;
+ break;
+ default:
+ BbsTable[Index].DeviceType = BBS_UNKNOWN;
+ }
+ }
+ }
+#endif
+
+ if (gBootOverrideDeviceIndx == 0)
+ {
+ return; // No override needed
+ }
+
+
+ //
+ // Find a device with the highest priority and swap it with priority of
+ // a device located at gBootOverrideDeviceIndex.
+ //
+ Priority = BbsTable[gBootOverrideDeviceIndx].BootPriority;
+
+ for (Index = 0, Index1 = MAX_BBS_ENTRIES_NO;
+ Index < MAX_BBS_ENTRIES_NO;
+ Index++)
+ {
+ if (Index == gBootOverrideDeviceIndx) continue;
+
+ if (BbsTable[Index].BootPriority < Priority)
+ {
+ Index1 = Index;
+ }
+ }
+ //
+ // Index1 has entry with lowest priority, otherwise MAX_BBS_ENTRIES_NO
+ //
+ if (Index1 < MAX_BBS_ENTRIES_NO)
+ {
+ BbsTable[gBootOverrideDeviceIndx].BootPriority = BbsTable[Index1].BootPriority;
+ BbsTable[Index1].BootPriority = Priority;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CreateDeviceName
+//
+// Description: This function retrieves USB device name, copies it into
+// lower memory and returns a pointer to the string.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateDeviceName(
+ UINT8 DevIndex,
+ UINT8 *DevNameStringSrc,
+ UINT16 *StringDestinationSegment,
+ UINT16 *StringDestinationOffset,
+ UINT16 *MfgStringDestinationSegment,
+ UINT16 *MfgStringDestinationOffset
+)
+{
+ UINT8 *DevName = (gI13BinData->UsbMassI13Dev)[DevIndex].DeviceNameString;
+ UINT8 i;
+
+ //
+ // Copy the string, compact it on the way (no more that one ' ' in a row)
+ //
+ for (i=0; i < 63 && *DevNameStringSrc != 0; i++, DevNameStringSrc++)
+ {
+ if ((*DevNameStringSrc == 0x20) && (*(DevNameStringSrc-1) == 0x20)) continue;
+ *DevName++ = *DevNameStringSrc; // DevNameStringSrc incremented unconditionally
+ }
+ *DevName = 0; // string terminator
+
+ DevName = (gI13BinData->UsbMassI13Dev)[DevIndex].DeviceNameString;
+
+ *StringDestinationSegment = (UINT16)(((UINTN)DevName & 0xf0000) >> 4);
+ *StringDestinationOffset = (UINT16)((UINTN)DevName & 0xffff);
+
+ *MfgStringDestinationSegment = (UINT16)(((UINTN)gI13BinData->MfgGenericName & 0xf0000) >> 4);
+ *MfgStringDestinationOffset = (UINT16)((UINTN)gI13BinData->MfgGenericName & 0xffff);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CreateBbsEntry
+//
+// Description: This function takes the device index within USBMASS_INT13_DEV
+// list and prepares BBS entry for this device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+CreateBbsEntry(
+ UINT8 DevIndex,
+ IN USB_MASS_DEV *UsbMassDevice,
+ OUT BBS_TABLE *BbsEntry
+)
+{
+ EFI_STATUS Status;
+ UINT8 Handle;
+ UINT8 DevAndSysType;
+ UINT8 BaidDeviceType = 0; //(EIP73024)
+ BBS_STATUS_FLAGS StatusFlags = {0}; //(EIP73024)
+ UINT16 CheckForUsbCdromOffset;
+ UINT32 CheckForUsbCdromAddress;
+ UINT8 *PatchAddr;
+
+ ASSERT(DevIndex < USBDEVS_MAX_ENTRIES);
+
+ if (gBiosExtensions == NULL) return EFI_NOT_FOUND;
+
+ pBS->SetMem(BbsEntry, sizeof(BBS_TABLE), 0);
+
+ //
+ // Get the HC PCI location
+ //
+ BbsEntry->Bus = (UINT32)(UsbMassDevice->PciBDF >> 8);
+ BbsEntry->Device = (UINT32)((UsbMassDevice->PciBDF & 0xFF) >> 3);
+ BbsEntry->Function = (UINT32)(UsbMassDevice->PciBDF & 7);
+
+ //
+ // Update class/subclass information
+ //
+ BbsEntry->Class = PCI_CL_SER_BUS;
+ BbsEntry->SubClass = PCI_CL_SER_BUS_SCL_USB;
+
+ StatusFlags.Enabled = 1; StatusFlags.MediaPresent = 1;
+ BbsEntry->StatusFlags = StatusFlags; // Enabled, Unknown media
+
+ //
+ // Copy the device name string into low memory at gLegacyMemoryAddress, and
+ // update the string pointer in BBS table entry
+ //
+ Status = CreateDeviceName(
+ DevIndex,
+ UsbMassDevice->DevString,
+ &BbsEntry->DescStringSegment,
+ &BbsEntry->DescStringOffset,
+ &BbsEntry->MfgStringSegment,
+ &BbsEntry->MfgStringOffset
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ DevAndSysType = 0x11;
+ Handle = (UINT8)UsbMassDevice->LogicalAddress;
+
+ switch (UsbMassDevice->StorageType) {
+ case USB_MASS_DEV_ARMD:
+#if BBS_USB_DEVICE_TYPE_SUPPORT
+ BbsEntry->DeviceType = BBS_USB;
+#else
+ BbsEntry->DeviceType = BBS_FLOPPY;
+#endif
+ BaidDeviceType = BAID_TYPE_RMD_FDD;
+ BbsEntry->BootHandlerSegment = (UINT16)((UINTN)gI13BinData >> 4);
+ BbsEntry->BootHandlerOffset = gI13BinData->BcvOffset + DevIndex*4;
+ break;
+
+ case USB_MASS_DEV_HDD:
+#if BBS_USB_DEVICE_TYPE_SUPPORT
+ BbsEntry->DeviceType = BBS_USB;
+#else
+ BbsEntry->DeviceType = BBS_HARDDISK;
+#endif
+ BaidDeviceType = BAID_TYPE_RMD_HDD;
+ Handle |= 0x80;
+ BbsEntry->BootHandlerSegment = (UINT16)((UINTN)gI13BinData >> 4);
+ BbsEntry->BootHandlerOffset = gI13BinData->BcvOffset + DevIndex*4;
+ break;
+
+ case USB_MASS_DEV_CDROM:
+#if BBS_USB_DEVICE_TYPE_SUPPORT
+ BbsEntry->DeviceType = BBS_USB;
+#else
+ BbsEntry->DeviceType = BBS_CDROM;
+#endif
+ BaidDeviceType = BAID_TYPE_CDROM;
+ BbsEntry->BootHandlerSegment = 0xf000;
+ BbsEntry->BootHandlerOffset = gLegacy16Data->CdrBevOffset;
+ if (gCdromInstalled) break;
+ //
+ // Patch farReturnCDROMSupportAPIPointer routine with "call farCheckForUSBCdrom"
+ //
+ CheckForUsbCdromOffset = gI13BinData->CheckForUsbCDROMOffset;
+ CheckForUsbCdromAddress =
+ (UINT32)((UINTN)gI13BinData<<12) + (UINT32)CheckForUsbCdromOffset;
+
+ PatchAddr = (UINT8*)(UINTN)(0xF0000+gLegacy16Data->CDROMSupportAPIOfs+5);
+ *PatchAddr++ = 0x9A; // far call opcode
+ *(UINT32*)PatchAddr = CheckForUsbCdromAddress;
+ gCdromInstalled = TRUE;
+ break;
+ default:
+ BbsEntry->DeviceType = BBS_UNKNOWN;
+ }
+
+ BbsEntry->InitPerReserved = ((UINT32)BaidDeviceType<<24)
+ +((UINT32)Handle<<8)
+ +(UINT32)DevAndSysType;
+
+ *(UINTN*)(&BbsEntry->IBV1) = (UINTN)UsbMassDevice->Handle;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallUsbLegacyBootDevices
+//
+// Description: This function installs USB INT13 devices
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUsbLegacyBootDevices (
+ VOID
+)
+{
+ EFI_STATUS Status;
+ UINTN NumberOfHandles = 0;
+ EFI_HANDLE *HandleBuffer = NULL;
+ UINTN Index;
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ EFI_USB_INTERFACE_DESCRIPTOR InterfaceDesc;
+ EFI_BLOCK_IO_PROTOCOL *BlkIo;
+ USB_MASS_DEV *MassDev;
+ DEV_INFO *DevInfo;
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_DISABLE_LEGACY_SUPPORT) {
+ return EFI_UNSUPPORTED;
+ }
+
+ InitializeHotplugDevices();
+
+ Status = pBS->LocateHandleBuffer(ByProtocol, &gEfiBlockIoProtocolGuid,
+ NULL, &NumberOfHandles, &HandleBuffer);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < NumberOfHandles; Index++) {
+ Status = pBS->HandleProtocol(HandleBuffer[Index], &gEfiUsbIoProtocolGuid, &UsbIo);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ Status = UsbIo->UsbGetInterfaceDescriptor(UsbIo, &InterfaceDesc);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+ if (InterfaceDesc.InterfaceClass != BASE_CLASS_MASS_STORAGE) {
+ continue;
+ }
+
+ Status = pBS->HandleProtocol(HandleBuffer[Index],
+ &gEfiBlockIoProtocolGuid, &BlkIo);
+ if (EFI_ERROR(Status)) {
+ continue;
+ }
+
+ MassDev = (USB_MASS_DEV*)BlkIo;
+ DevInfo = (DEV_INFO*)MassDev->DevInfo;
+ if ((DevInfo->bPhyDevType != USB_MASS_DEV_UNKNOWN) &&
+ !(DevInfo->bPhyDevType != USB_MASS_DEV_CDROM &&
+ (DevInfo->wBlockSize > 0x200 && DevInfo->wBlockSize != 0xFFFF))){
+ UsbInstallLegacyDevice(MassDev);
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbInstallLegacyDevice
+//
+// Description: This function installs USB INT13 device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbInstallLegacyDevice (
+ USB_MASS_DEV *UsbMassDevice
+)
+{
+ BBS_TABLE BbsEntry;
+ EFI_STATUS Status;
+ UINT8 EntryNumber = 0xff;
+ UINT8 Index;
+ DEV_INFO *Device;
+ UINT8 HcIndx;
+ UINT8 PortIndx;
+
+ //TRACE((-1, "Installing USB INT13 device %x\n", UsbMassDevice));
+
+ //
+ // See if device is already in the list, if yes - return error.
+ //
+ for (Index=0; Index<USBDEVS_MAX_ENTRIES; Index++) {
+ if ((gI13BinData->UsbMassI13Dev)[Index].Handle == (UINT8)UsbMassDevice->LogicalAddress) {
+ ASSERT(FALSE); // ERROR: Device already exists
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Look for an empty slot in BcvLookupTable
+ //
+ for (Index=0; Index<USBDEVS_MAX_ENTRIES; Index++) {
+ if ((gI13BinData->UsbMassI13Dev)[Index].Handle == 0) {
+ break;
+ }
+ }
+ ASSERT(Index<USBDEVS_MAX_ENTRIES);
+ if (Index==USBDEVS_MAX_ENTRIES) return EFI_OUT_OF_RESOURCES;
+
+ Status = gBiosExtensions->UnlockShadow(0, 0, 0, 0);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CreateBbsEntry(Index, UsbMassDevice, &BbsEntry);
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBiosExtensions->InsertBbsEntryAt(gBiosExtensions,
+ &BbsEntry,
+ &EntryNumber); // This function returns EntryNumber
+ ASSERT_EFI_ERROR(Status);
+
+ //
+ // Entry has been successfully added, update the lookup table
+ //
+ (gI13BinData->UsbMassI13Dev)[Index].Handle = (UINT8)UsbMassDevice->LogicalAddress;
+ (gI13BinData->UsbMassI13Dev)[Index].BbsEntryNo = EntryNumber;
+ (gI13BinData->UsbMassI13Dev)[Index].DevBaidType = (UINT8)(BbsEntry.InitPerReserved>>24);
+
+ //
+ // Update device geometry related information
+ //
+ Device = (DEV_INFO*)UsbMassDevice->DevInfo;
+ (gI13BinData->UsbMassI13Dev)[Index].NumHeads = Device->NonLBAHeads;
+ (gI13BinData->UsbMassI13Dev)[Index].LBANumHeads = Device->Heads;
+ (gI13BinData->UsbMassI13Dev)[Index].NumCylinders = Device->wNonLBACylinders;
+ (gI13BinData->UsbMassI13Dev)[Index].LBANumCyls = Device->wCylinders;
+ (gI13BinData->UsbMassI13Dev)[Index].NumSectors = Device->bNonLBASectors;
+ (gI13BinData->UsbMassI13Dev)[Index].LBANumSectors = Device->bSectors;
+ (gI13BinData->UsbMassI13Dev)[Index].BytesPerSector = Device->wBlockSize;
+ (gI13BinData->UsbMassI13Dev)[Index].MediaType = Device->bMediaType;
+ (gI13BinData->UsbMassI13Dev)[Index].LastLBA = Device->MaxLba;
+ (gI13BinData->UsbMassI13Dev)[Index].BpbMediaDesc = Device->BpbMediaDesc;
+
+ // Update PCI location of the controller this device is connected to
+ gUsbPciLocationTable[Index].Handle = (UINT8)UsbMassDevice->LogicalAddress;
+ gUsbPciLocationTable[Index].PciLocation = UsbMassDevice->PciBDF;
+
+ Status = gBiosExtensions->LockShadow(0, 0);
+ ASSERT_EFI_ERROR(Status);
+
+ // Set the device as registered
+ Device->Flag |= DEV_INFO_MASS_DEV_REGD;
+
+ //
+ // See if OEM asks for USB boot override for this device. If yes, store
+ // BBS index of this device, later at READY_TO_BOOT this BBS device will
+ // be assigned priority 0 (highest).
+ //
+ // Note1: There is no need to check if gAmiUsb is valid, because this
+ // function itself is one of the members of gAmiUsb structure.
+ //
+ // Note2: This feature will only be available for the devices connected
+ // directly to the root port; devices behind the hub(s) will be ignored.
+ //
+ if (Device->bHubDeviceNumber & 0x80)
+ {
+ Status = gAmiUsb->UsbGetAssignBootPort(&HcIndx, &PortIndx);
+ if ((!EFI_ERROR(Status)) && (gBootOverrideDeviceIndx == 0))
+ {
+ TRACE((-1,"OemUsbGetAssignBootPort: HC %d, Port %d; current HC %d, Port %d\n",
+ HcIndx, PortIndx, Device->bHCNumber, Device->bHubPortNumber));
+
+ if ((Device->bHCNumber == HcIndx) && (Device->bHubPortNumber == PortIndx))
+ {
+ TRACE((-1,"---OemUsbGetAssignBootPort: BBS Entry# %d\n", EntryNumber));
+
+ gBootOverrideDeviceIndx = EntryNumber;
+ }
+ }
+ }
+
+ //
+ // Process the "Auto" settings of Hotplug devices: if the device being installed
+ // have already had a "Hotplug" clone, uninstall the clone.
+ //
+
+ // Process hotplug floppy
+ if ( (UsbMassDevice != &gHotplugFloppy) &&
+ (UsbMassDevice->StorageType == USB_MASS_DEV_ARMD) &&
+ (gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) )
+ {
+ TRACE((-1, "Uninstalling Hotplug Floppy (Setup 'Auto' option)\n"));
+ UsbUninstallLegacyDevice(&gHotplugFloppy); // Okay not to be successful
+ }
+
+ // Process hotplug HDD
+ if ( (UsbMassDevice != &gHotplugHardDrive) &&
+ (UsbMassDevice->StorageType == USB_MASS_DEV_HDD) &&
+ (gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) )
+ {
+ TRACE((-1, "Uninstalling Hotplug HDD (Setup 'Auto' option)\n"));
+ UsbUninstallLegacyDevice(&gHotplugHardDrive); // Okay not to be successful
+ }
+ // Process hotplug CDROM
+ if ( (UsbMassDevice != &gHotplugCDROM) &&
+ (UsbMassDevice->StorageType == USB_MASS_DEV_CDROM) &&
+ (gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) )
+ {
+ TRACE((-1, "Uninstalling Hotplug CDROM (Setup 'Auto' option)\n"));
+ UsbUninstallLegacyDevice(&gHotplugCDROM); // Okay not to be successful
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbUninstallLegacyDevice
+//
+// Description: This function uninstalls USB INT13 device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbUninstallLegacyDevice (
+ USB_MASS_DEV* UsbMassDevice
+)
+{
+ EFI_STATUS Status;
+ UINT8 Index;
+
+ TRACE((-1, "Uninstalling INT13 device %x\n", UsbMassDevice));
+
+ Status = gBiosExtensions->UnlockShadow(0, 0, 0, 0);
+ ASSERT_EFI_ERROR(Status);
+
+ for (Index=0; Index<USBDEVS_MAX_ENTRIES; Index++) {
+ if ((gI13BinData->UsbMassI13Dev)[Index].Handle == (UINT8)UsbMassDevice->LogicalAddress) {
+ (gI13BinData->UsbMassI13Dev)[Index].Handle = 0; // Mark as unused
+ Status = gBiosExtensions->RemoveBbsEntryAt(
+ gBiosExtensions,
+ (gI13BinData->UsbMassI13Dev)[Index].BbsEntryNo
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ if ((gBootOverrideDeviceIndx != 0)
+ && (gBootOverrideDeviceIndx == (gI13BinData->UsbMassI13Dev)[Index].BbsEntryNo))
+ {
+ gBootOverrideDeviceIndx = 0;
+ }
+ gUsbPciLocationTable[Index].Handle = 0; // Make invalid handle
+
+ break;
+ }
+ }
+ ASSERT_EFI_ERROR(Status);
+
+ gBiosExtensions->LockShadow(0, 0);
+
+ ((DEV_INFO*)UsbMassDevice->DevInfo)->Flag &= ~(DEV_INFO_VALID_STRUC | DEV_INFO_MASS_DEV_REGD);
+
+ //
+ // Process the "Auto" settings of Hotplug devices: if the device being uninstalled
+ // is the last one of a kind, and "Auto" Setup option is selected for the hotplug
+ // device of this kind, then install the hotplug device.
+ //
+
+ // Process hotplug floppy
+ if ( (UsbMassDevice != &gHotplugFloppy) &&
+ (UsbMassDevice->StorageType == USB_MASS_DEV_ARMD) &&
+ (gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) &&
+ (gUsbData->NumberOfFDDs == 0))
+ {
+ TRACE((-1, "Installing Hotplug Floppy (Setup 'Auto' option)\n"));
+ UsbInstallLegacyDevice(&gHotplugFloppy);
+ }
+
+ if ( (UsbMassDevice != &gHotplugHardDrive) &&
+ (UsbMassDevice->StorageType == USB_MASS_DEV_HDD) &&
+ (gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) &&
+ (gUsbData->NumberOfHDDs == 0))
+ {
+ TRACE((-1, "Installing Hotplug HDD (Setup 'Auto' option)\n"));
+ UsbInstallLegacyDevice(&gHotplugHardDrive);
+ }
+ if ( (UsbMassDevice != &gHotplugCDROM) &&
+ (UsbMassDevice->StorageType == USB_MASS_DEV_CDROM) &&
+ (gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) &&
+ (gUsbData->NumberOfCDROMs == 0))
+ {
+ TRACE((-1, "Installing Hotplug CDROM (Setup 'Auto' option)\n"));
+ UsbInstallLegacyDevice(&gHotplugCDROM);
+ }
+
+ return Status;
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/int13/UsbInt13.cif b/Core/EM/usb/int13/UsbInt13.cif
new file mode 100644
index 0000000..e0e9fa6
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.cif
@@ -0,0 +1,17 @@
+<component>
+ name = "USB Int13"
+ category = ModulePart
+ LocalRoot = "Core\eM\USB\int13"
+ RefName = "USBINT13"
+[files]
+"UsbInt13.sdl"
+"UsbInt13.mak"
+"UsbInt13.inf"
+"UsbInt13.c"
+"UsbInt13.h"
+"UsbInt13ComponentName.c"
+"UsbInt13.dxs"
+"UsbBbs.c"
+[parts]
+"USB_I13_BINARY"
+<endComponent>
diff --git a/Core/EM/usb/int13/UsbInt13.dxs b/Core/EM/usb/int13/UsbInt13.dxs
new file mode 100644
index 0000000..0e13f3f
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.dxs
@@ -0,0 +1,39 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+#include "token.h"
+#ifdef CSM_SUPPORT
+#include <Protocol/LegacyBios.h>
+#endif
+#include <Protocol/AmiUsbController.h>
+
+DEPENDENCY_START
+#if CSM_SUPPORT
+ EFI_LEGACY_BIOS_PROTOCOL_GUID AND
+#endif
+ EFI_USB_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/int13/UsbInt13.h b/Core/EM/usb/int13/UsbInt13.h
new file mode 100644
index 0000000..eb05b02
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.h
@@ -0,0 +1,178 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13.h 13 12/24/14 1:13a Wilsonlee $
+//
+// $Revision: 13 $
+//
+// $Date: 12/24/14 1:13a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13.h $
+//
+// 13 12/24/14 1:13a Wilsonlee
+// [TAG] EIP192517
+// [Category] Improvement
+// [Description] USB Driver handles 0x100 NumHeads as a valid value.
+// [Files] usbmass.c, usbdef.h, UsbInt13.c, UsbInt13.h, UI13.bin,
+// Bfiusb.equ, Bfiusb.asm
+//
+// 12 12/15/13 10:13p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 11 7/23/13 2:11a Wilsonlee
+// [TAG] EIP127941
+// [Category] Improvement
+// [Description] Replace UI13HDDFunc08 with UI13FDDFunc08 if the media
+// descriptor is a fixed disk.
+// [Files] UsbInt13.h, UsbInt13.c, usbmass.c, usbdef.h, Bfiusb.asm,
+// Bfiusb.equ
+//
+// 10 7/03/13 5:21a Ryanchou
+// [TAG] EIP123988
+// [Category] Improvement
+// [Description] Move the code creating BBS table to end of POST.
+// [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+// UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 9 1/06/12 1:01a Rajeshms
+// [TAG] EIP62737
+// [Category] Improvement
+// [Description] Added USB Device number into USB mass device name
+// string based on SDL Token.
+// [Files] Usb.sdl, usbport.c, usbmass.c, UsbInt13.h, UsbInt13.c,
+// usbbus.c, Bfiusb.equ
+//
+// 8 3/04/11 11:42a Olegi
+// [TAG] EIP51927
+// [Category] Improvement
+// [Description] Support for the interface path reporting in USB INT13
+// function 48.
+// [Files] UsbInt13.c
+// UsbInt13.h
+//
+// 7 10/12/10 2:07a Rameshr
+// [TAG]- EIP 44585
+// [Category]-IMPROVEMENT
+// [Description]- Number of maximum supported USB Mass Storage device
+// increased from 8 to 16.
+// [Files]- Uin13.bin, UsbPort.c, UsbInt13.h, Usb.c, Usbdef.h, Uasbmass.c,
+// Usb.sd, usb.uni, UsbSetup.c, UsbSrc.sdl, UsbPolicy.h
+//
+// 6 5/21/09 5:14p Olegi
+//
+// 5 11/25/08 5:59p Olegi
+//
+// 4 11/03/08 9:53a Olegi
+//
+// 3 10/24/08 3:06p Olegi
+//
+// 2 6/27/08 5:50p Olegi
+//
+// 1 5/16/08 12:12p Olegi
+// First check-in.
+//
+//****************************************************************************
+
+#ifndef __UI13_HEADER__
+#define __UI13_HEADER__
+
+#include "efi.h"
+
+#pragma pack(1)
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UINT13.H
+// Description: Definitions and structures for USB INT13
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+VOID AmiUsbNotifyCallback (EFI_EVENT, VOID*);
+VOID ReadyToBootNotify(EFI_EVENT, VOID*);
+EFI_STATUS InstallUsbLegacyBootDevices (VOID);
+EFI_STATUS UsbInstallLegacyDevice (USB_MASS_DEV*);
+EFI_STATUS UsbUninstallLegacyDevice (USB_MASS_DEV*);
+
+#define USBDEVS_MAX_ENTRIES 16
+
+typedef struct _USBMASS_INT13_DEV {
+ UINT8 Handle;
+ UINT8 BbsEntryNo;
+ UINT8 DevBaidType;
+ UINT16 NumHeads;
+ UINT16 LBANumHeads;
+ UINT16 NumCylinders;
+ UINT16 LBANumCyls;
+ UINT8 NumSectors;
+ UINT8 LBANumSectors;
+ UINT16 BytesPerSector;
+ UINT8 MediaType;
+ UINT64 LastLBA;
+ UINT8 BpbMediaDesc;
+ UINT8 DeviceNameString[64];
+} USBMASS_INT13_DEV;
+
+//
+// The following data structure is located in UI13.BIN
+//
+typedef struct _UINT13_DATA {
+ USBMASS_INT13_DEV UsbMassI13Dev[USBDEVS_MAX_ENTRIES];
+ UINT8 MfgGenericName[12]; // "USB Storage", 0
+ UINT16 BcvOffset;
+ UINT16 CheckForUsbCDROMOffset;
+ UINT16 UsbSmmDataOffset;
+ UINT16 UsbPciLocationTableOffset;
+} UINT13_DATA;
+
+typedef struct _USB_PCI_LOCATION {
+ UINT8 Handle; // USB device address
+ UINT16 PciLocation; // Bus[15..8] Device[7..3] Function[2..0]
+} USB_PCI_LOCATION;
+
+#pragma pack()
+
+typedef enum {
+ Floppy,
+ HardDrive,
+ CDROM
+} HOTPLUG_DEVICE;
+
+EFI_STATUS InitializeHotplugDevices();
+
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/int13/UsbInt13.inf b/Core/EM/usb/int13/UsbInt13.inf
new file mode 100644
index 0000000..f3b0eb2
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.inf
@@ -0,0 +1,5 @@
+[MODULE]
+ModuleID = 1
+VendorID = 0
+DeviceID = 2
+File = Addon\UI13.BIN
diff --git a/Core/EM/usb/int13/UsbInt13.mak b/Core/EM/usb/int13/UsbInt13.mak
new file mode 100644
index 0000000..9de1e1e
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.mak
@@ -0,0 +1,79 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#***********************************************************************
+# $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13.mak 4 7/03/13 5:21a Ryanchou $
+#
+# $Revision: 4 $
+#
+# $Date: 7/03/13 5:21a $
+#***********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13.mak $
+#
+# 4 7/03/13 5:21a Ryanchou
+# [TAG] EIP123988
+# [Category] Improvement
+# [Description] Move the code creating BBS table to end of POST.
+# [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+# UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+# AmiUsbController.h
+#
+# 3 1/21/09 10:58a Olegi
+# Dependency on AMIUSB and CSM has been added, callback notification is
+# removed.
+#
+# 2 10/24/08 3:05p Olegi
+#
+# 1 5/16/08 12:12p Olegi
+# First check-in.
+#
+#***********************************************************************
+
+all: USBINT13
+
+USBINT13 : $(BUILD_DIR)\usbint13.mak USBI13
+
+$(BUILD_DIR)\usbint13.mak: $(UINT13_DIR)\usbint13.cif $(UINT13_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(CIF2MAK_DEFAULTS) $(UINT13_DIR)\usbint13.cif
+
+USBI13: $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\usbint13.mak all\
+ GUID=4C006CD9-19BA-4617-8483-609194A1ACFC\
+ ENTRY_POINT=UsbInt13EntryPoint\
+ TYPE=BS_DRIVER\
+ "CFLAGS=$(CFLAGS) /I$(USBRT_DIR)"\
+ COMPRESS=1\
+ DEPEX1=$(UINT13_DIR)\usbint13.dxs \
+
+$(BUILD_DIR)\UsbBbs.obj: $(UINT13_DIR)\$(@B).c
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(UINT13_DIR)\$(@B).c
+
+CORE_DXE_LIBBin : $(BUILD_DIR)\UsbBbs.obj
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/usb/int13/UsbInt13.sdl b/Core/EM/usb/int13/UsbInt13.sdl
new file mode 100644
index 0000000..211cd8b
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13.sdl
@@ -0,0 +1,48 @@
+TOKEN
+ Name = "UINT13_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable USB Int13 support in the project."
+ TokenType = Boolean
+ TargetMAK = Yes
+ TargetH = Yes
+ Master = Yes
+ Token = "CSM_SUPPORT" "=" "1"
+ Token = "USB_RUNTIME_DRIVER_IN_SMM" "=" "1"
+End
+
+TOKEN
+ Name = "USB_I13_DRIVER_VERSION"
+ Value = "1"
+ Help = "Driver version. Reported in DriverBinding protocol."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+PATH
+ Name = "UINT13_DIR"
+End
+
+MODULE
+ Help = "Includes usbint13.mak into project"
+ Path = "$(UINT13_DIR)"
+ File = "usbint13.mak"
+End
+
+ELINK
+ Name = "$(UINT13_DIR)\usbint13.inf"
+ Parent = "CSM_CUSTOM_INFS"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\usbint13.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+ELINK
+ Name = "CollectUsbBbsDevices,"
+ Parent = "CollectBootDevices,"
+ InvokeOrder = BeforeParent
+End
+
diff --git a/Core/EM/usb/int13/UsbInt13ComponentName.c b/Core/EM/usb/int13/UsbInt13ComponentName.c
new file mode 100644
index 0000000..bca8f86
--- /dev/null
+++ b/Core/EM/usb/int13/UsbInt13ComponentName.c
@@ -0,0 +1,195 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13ComponentName.c 1 5/16/08 12:12p Olegi $
+//
+// $Revision: 1 $
+//
+// $Date: 5/16/08 12:12p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Int13/UsbInt13ComponentName.c $
+//
+// 1 5/16/08 12:12p Olegi
+// First check-in.
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbInt13ComponentName.c
+//
+// Description: Component Name Protocol Member Functions for USB Int13.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "Efi.h"
+#include "AmiLib.h"
+#include <Protocol/ComponentName.h>
+
+EFI_STATUS
+UsbInt13CtlDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+);
+
+EFI_STATUS
+UsbInt13CtlGetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+);
+
+
+CHAR16 *gUsbInt13DriverName = L"AMI USB INT13 Driver";
+CHAR16 *gUsbInt13ControllerName = L"USB Mass Storage Legacy Device";
+
+
+EFI_COMPONENT_NAME_PROTOCOL gUsbInt13ControllerDriverName = {
+ UsbInt13CtlDriverName,
+ UsbInt13CtlGetControllerName,
+ "eng"
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbInt13CtlDriverName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the EFI Driver.
+//
+//
+// Parameters:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// Language - A pointer to a three character ISO 639-2 language identifier.
+// This is the language of the driver name that that the caller
+// is requesting, and it must match one of the languages specified
+// in SupportedLanguages. The number of languages supported by a
+// driver is up to the driver writer.
+// DriverName - A pointer to the Unicode string to return. This Unicode string
+// is the name of the driver specified by This in the language
+// specified by Language.
+//
+// Output:
+// EFI_SUCCES - The Unicode string for the Driver specified by This
+// and the language specified by Language was returned
+// in DriverName.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - DriverName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbInt13CtlDriverName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+)
+{
+ //Supports only "eng"
+ if(!Language || !DriverName) return EFI_INVALID_PARAMETER;
+ if (MemCmp(Language, "eng", 3)) return EFI_UNSUPPORTED;
+ *DriverName = gUsbInt13DriverName;
+ return EFI_SUCCESS;
+}
+
+
+
+//---------------------------------------------------------------------------
+//<AMI_PHDR_START>
+//
+// Name: UsbInt13CtlGetControllerName
+//
+// Description: Retrieves a Unicode string that is the user readable name of
+// the controller that is being managed by an EFI Driver.
+//
+// Parameters:
+// This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
+// ControllerHandle - The handle of a controller that the driver specified by
+// This is managing. This handle specifies the controller
+// whose name is to be returned.
+// ChildHandle - The handle of the child controller to retrieve the name
+// of. This is an optional parameter that may be NULL. It
+// will be NULL for device drivers. It will also be NULL
+// for a bus drivers that wish to retrieve the name of the
+// bus controller. It will not be NULL for a bus driver
+// that wishes to retrieve the name of a child controller.
+// Language - A pointer to a three character ISO 639-2 language
+// identifier. This is the language of the controller name
+// that that the caller is requesting, and it must match one
+// of the languages specified in SupportedLanguages. The
+// number of languages supported by a driver is up to the
+// driver writer.
+// ControllerName - A pointer to the Unicode string to return. This Unicode
+// string is the name of the controller specified by
+// ControllerHandle and ChildHandle in the language
+// specified by Language from the point of view of the
+// driver specified by This.
+//
+// Output:
+// EFI_SUCCESS - The Unicode string for the user readable name in the
+// language specified by Language for the driver
+// specified by This was returned in DriverName.
+// EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
+// EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid
+// EFI_HANDLE.
+// EFI_INVALID_PARAMETER - Language is NULL.
+// EFI_INVALID_PARAMETER - ControllerName is NULL.
+// EFI_UNSUPPORTED - The driver specified by This is not currently
+// managing the controller specified by
+// ControllerHandle and ChildHandle.
+// EFI_UNSUPPORTED - The driver specified by This does not support the
+// language specified by Language.
+//
+//<AMI_PHDR_END>
+//---------------------------------------------------------------------------
+EFI_STATUS
+UsbInt13CtlGetControllerName(
+ IN EFI_COMPONENT_NAME_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+)
+{
+ *ControllerName = gUsbInt13ControllerName;
+ return EFI_SUCCESS;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/UsbMass.h b/Core/EM/usb/rt/UsbMass.h
new file mode 100644
index 0000000..5fb4e9f
--- /dev/null
+++ b/Core/EM/usb/rt/UsbMass.h
@@ -0,0 +1,465 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/UsbMass.h 3 7/04/14 5:34a Wilsonlee $
+//
+// $Revision: 3 $
+//
+// $Date: 7/04/14 5:34a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/UsbMass.h $
+//
+// 3 7/04/14 5:34a Wilsonlee
+// [TAG] EIP175485
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB key can't be save during secure boot key.
+// [RootCause] The usb key, MSI 8G Team, has two luns. One is CD-ROM, it
+// always reports there is no media until we send "Get_Configuration"
+// command to it, then it causes the other lun will report media change
+// when we read/write data later.
+// [Solution] Send "Get_Configuration" command for CD/DVD devices.
+// [Files] usbmass.c, UsbMass.h
+//
+// 2 12/15/13 10:16p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 1 1/22/13 3:08a Wilsonlee
+// [TAG] EIP112938
+// [Category] Improvement
+// [Description] Create a header file for usb mass storage driver.
+// [Files] UsbMass.h, usbmass.c, usbdef.h, amiusb.c, efiusbmass.c
+//
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: UsbMass.h
+//
+// Description: AMI USB Mass Storage support header
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __USBMASS__H__
+#define __USBMASS__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: BOT_STATUS_BLOCK
+//
+// Description: USB mass device boot only protocol status block structure.
+// Referred as CSW - Command status wrapper. Refer Bulk-Only
+// transport specification for more detail.
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// dCswSignature DWORD CBS signature "USBS"
+// dCswTag DWORD Tag used to link the command with status response
+// dCswDataResidue DWORD Size of remaining data that is not processed in this transfer
+// bmCswStatus BYTE CSW status byte
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 dCswSignature; // 0-3h, CSW signature = "USBS"
+ UINT32 dCswTag; // 4-7h, Tag
+ UINT32 dCswDataResidue; // 8-0Bh, Data residue
+ UINT8 bmCswStatus; // 0Ch, CSW status
+} BOT_STATUS_BLOCK;
+
+#pragma pack(pop)
+
+// Common device specific command structures and values
+//----------------------------------------------------------------------------
+#define COMMON_INQUIRY_OPCODE 0x12
+#define COMMON_READ_CAPACITY_10_OPCODE 0x25
+#define COMMON_READ_CAPACITY_16_OPCODE 0x9E
+#define COMMON_READ_10_OPCODE 0x28
+#define COMMON_READ_16_OPCODE 0x88
+#define COMMON_WRITE_10_OPCODE 0x2A
+#define COMMON_WRITE_16_OPCODE 0x8A
+#define COMMON_MODE_SENSE_6_OPCODE 0x1A
+#define COMMON_MODE_SENSE_10_OPCODE 0x5A
+#define COMMON_SEND_DIAGNOSTIC_OPCODE 0x1D
+#define COMMON_TEST_UNIT_READY_OPCODE 0x00
+#define COMMON_REQUEST_SENSE_OPCODE 0x03
+#define COMMON_START_STOP_UNIT_OPCODE 0x1B
+#define COMMON_FORMAT_UNIT_OPCODE 0x04
+#define COMMON_VERIFY_10_OPCODE 0x2F
+#define COMMON_VERIFY_16_OPCODE 0x8F
+#define COMMON_READ_FORMAT_CAPACITY_OPCODE 0x23
+#define COMMON_GET_CONFIGURATION_OPCODE 0x46
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT8 bPageCode; // 02h, Page Code
+ UINT8 bReserved; // 03h, Reserved
+ UINT8 bAllocLength; // 04h, Allocation Length
+ UINT8 bControl; // 05h, Control/Reserved
+ UINT8 aReserved[6]; // 06h-0Bh, Reserved
+} COMMON_INQ_CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT32 dLba; // 02h-05h, Logical Block Address
+ UINT16 wbReserved; // 06h-07, Reserved
+ UINT8 bPMI; // 08h, PMI - bit 0
+ UINT8 bControl; // 09h, Control/Reserved
+ UINT16 wdReserved; // 0Ah-0Bh, Reserved
+} COMN_READ_CAPACITY_10_CMD;
+
+typedef struct {
+ UINT8 OpCode; // 00h, Operation Code
+ UINT8 ServiceAction; // 01h, Service Action - bit0..bit4
+ UINT64 Lba; // 02h-09h, Logical Block Address
+ UINT32 AllocLength; // 10h-0Dh, Allocation Length
+ UINT8 PMI; // 0Eh, PMI - bit 0
+ UINT8 Control; // 0Fh, Control
+} COMN_READ_CAPACITY_16_CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT8 aReserved[5]; // 02-06h, Reserved
+ UINT16 wAllocLength; // 07h-08h, Allocation Length(BIG ENDIAN)
+ UINT8 aReserved1[3]; // 09h-0Bh, Reserved
+} COMN_READ_FMT_CAPACITY;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT32 dLba; // 02h-05h, Logical Block Address
+ UINT8 bReserved; // 06h, Reserved
+ UINT16 wTransferLength;// 07h-08h, Transfer Length(BIG ENDIAN)
+ UINT8 bControl; // 09h, Control/Reserved
+ UINT16 wReserved; // 0Ah-0Bh, Reserved
+} COMN_RWV_10_CMD;
+
+typedef struct {
+ UINT8 OpCode; // 00h, Operation Code
+ UINT8 Lun; // 01h, Logical Unit Number, etc
+ UINT64 Lba; // 02h-09h, Logical Block Address
+ UINT32 TransferLength; // 0Ah-0Dh, Transfer Length(BIG ENDIAN)
+ UINT8 GroupNum; // 0Eh, Group Number, etc
+ UINT8 Control; // 0Fh, Control
+} COMN_RWV_16_CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT8 bPageCode; // 02h, Page Code
+ UINT8 bReserved; // 03h, Reserved
+ UINT8 bAllocLength; // 04h, Allocation Length
+ UINT8 bControl; // 05h, Control/Reserved
+} COMN_MODE_SENSE_6CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT8 bPageCode; // 02h, Page Code
+ UINT32 dReserved; // 03-06h, Reserved
+ UINT16 wAllocLength; // 07h-08h, Allocation Length(BIG ENDIAN)
+ UINT8 bControl; // 09h, Control/Reserved
+ UINT16 wReserved; // 0Ah-0Bh, Reserved
+} COMN_MODE_SENSE_10CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code (1D)
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT8 bReserved[10]; // 02h-0Bh, Reserved
+} COMN_SEND_DIAG_CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number
+ UINT8 bReserved[10]; // 02h-0Bh, Reserved
+} COMN_TEST_UNIT_READY_CMD;
+
+typedef struct {
+ UINT8 bOpCode; //00h, Operation Code
+ UINT8 bLun; //01h, Logical Unit Number
+ UINT16 wReserved; //02-03h, Reserved
+ UINT8 bAllocLength; //04h, Allocation Length
+ UINT8 aReserved[7]; //05h-0Bh, Reserved
+} COMMON_REQ_SENSE_CMD;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT16 wReserved; // 02-03h, Reserved
+ UINT8 bStart; // 04h, LoEj, Start bits
+ UINT8 aReserved[7]; // 05h-0Bh, Reserved
+} COMMON_START_STOP_UNIT_CMD;
+
+typedef struct {
+ UINT8 OpCode; // 00h, Operation Code
+ UINT8 Rt; // 01h, Logical Unit Number, etc
+ UINT16 StartingFeatureNumber; // 02h, StartingFeatureNumber
+ UINT8 Reserved[3]; // 03-06h, Reserved
+ UINT16 AllocLength; // 07h, Allocation Length
+ UINT8 Control; // 09h, Control
+} COMMON_GET_CONFIGURATION;
+
+typedef struct {
+ UINT8 bOpCode; // 00h, Operation Code
+ UINT8 bLun; // 01h, Logical Unit Number, etc
+ UINT8 bTrackNumber; // 02h, Track Number
+ UINT16 wInterleave; // 03h-04h, Interleave (BIG ENDIAN)
+ UINT16 wReserved; // 05-06h, Reserved
+ UINT16 wParamLength; // 07h-08h, Parameter List Length(BIG ENDIAN)
+ UINT8 aReserved[3]; // 09h-0Bh, Reserved
+} UFI_FMT_UNIT_CMD;
+
+typedef struct {
+ UINT16 wLength;
+ UINT8 bMediaType;
+ UINT8 aReserved[3];
+ UINT16 wBlkDescSize;
+} MODE_SENSE_10_HEADER;
+
+typedef struct {
+ UINT32 dCbwSignature; // 0-3h, CBW signature = "USBC"
+ UINT32 dCbwTag; // 4-7h, Tag
+ UINT32 dCbwDataLength; // 8-0Bh, Data transfer length
+ UINT8 bmCbwFlags; // 0Ch, Flags
+ UINT8 bCbwLun; // 0Dh, Logical unit number
+ UINT8 bCbwLength; // 0Eh, Command block length
+ UINT8 aCBWCB[16]; // 0Fh-1Eh, Command block buffer
+} BOT_CMD_BLK;
+
+typedef struct {
+ UINT8 bPageCode;
+ UINT8 bPageSize;
+ UINT16 wXferRate;
+ UINT8 bHeads;
+ UINT8 bSectors;
+ UINT16 wBlockSize;
+ UINT16 wCylinders;
+ UINT8 aReserved[22];
+} PAGE_CODE_5;
+
+typedef struct {
+ UINT8 aReserved[3];
+ UINT8 bCapListLength; // Amount of capacity format data after the header
+} READ_FMT_CAP_HDR;
+
+typedef struct {
+ READ_FMT_CAP_HDR stCapHeader;
+ UINT32 dNumBlocks;
+ UINT8 bDescCode;
+ UINT8 bReserved;
+ UINT16 wBlockSize;
+}READ_FMT_CAPACITY;
+
+#pragma pack(pop)
+
+#define MODE_SENSE_COMMAND_EXECUTED BIT0
+#define READ_CAPACITY_COMMAND_EXECUTED BIT1
+
+//----------------------------------------------------------------------------
+// Physical Device Type Constants for BIOS internal use
+//----------------------------------------------------------------------------
+#define USB_MASS_DEV_TYPE_FLOPPY 1 // USB FD drive
+#define USB_MASS_DEV_TYPE_CDROM 2 // USB CDROM drive
+#define USB_MASS_DEV_TYPE_ZIP 3 // USB ZIP drive
+#define USB_MASS_DEV_TYPE_ZIP_FLOPPY 4 // USB ZIP drive as floppy emulated
+#define USB_MASS_DEV_TYPE_SUPER_DISK 5 // USB super disk (LS120/240)
+#define USB_MASS_DEV_TYPE_HARD_DISK 6 // USB HD drive
+#define USB_MASS_DEV_TYPE_DISKONKEY 7 // USB Disk On Key
+
+//----------------------------------------------------------------------------
+// USB Mass Storage Related Data Structures and Equates
+//----------------------------------------------------------------------------
+//#define MAX_SIZE_FOR_FLOPPY_EMULATION 530 // 530MB //(EIP80382-)
+//#define MAX_LBA_FOR_FLOPPY_EMULATION 0x109000 // 530MB //(EIP80382-)
+
+// LBA to CHS conversion parameters
+#define USB_FIXED_LBA_HPT_ABOVE_1GB 0xFF
+#define USB_FIXED_LBA_SPT_ABOVE_1GB 0x3F
+#define USB_FIXED_LBA_HPT_BELOW_1GB 0x40
+#define USB_FIXED_LBA_SPT_BELOW_1GB 0x20
+
+// Parameters regarding 1.44MB FDD
+#define USB_144MB_FDD_MAX_LBA 0xB40
+#define USB_144MB_FDD_MEDIA_TYPE 0x94
+#define USB_144MB_FDD_MAX_HEADS 0x02
+#define USB_144MB_FDD_MAX_SECTORS 0x12
+#define USB_144MB_FDD_MAX_CYLINDERS 0x50
+#define USB_144MB_FDD_MAX_BLOCK_SIZE 0x200
+
+// Parameters regarding 720KB FDD
+#define USB_720KB_FDD_MAX_LBA 0x5A0
+#define USB_720KB_FDD_MEDIA_TYPE 0x1E
+#define USB_720KB_FDD_MAX_HEADS 0x02
+#define USB_720KB_FDD_MAX_SECTORS 0x09
+#define USB_720KB_FDD_MAX_CYLINDERS 0x50
+#define USB_720KB_FDD_MAX_BLOCK_SIZE 0x200
+
+#define USB_UNKNOWN_MEDIA_TYPE 0x0F0
+
+//-----------------------------------------------
+// ATAPI ERROR CODE REPORTED TO CALLER
+//-----------------------------------------------
+#define USB_ATA_WRITE_PROTECT_ERR 0x003 // Write protect error
+#define USB_ATA_TIME_OUT_ERR 0x080 // Command timed out error
+#define USB_ATA_DRIVE_NOT_READY_ERR 0x0AA // Drive not ready error
+#define USB_ATA_DATA_CORRECTED_ERR 0x011 // Data corrected error
+#define USB_ATA_PARAMETER_FAILED 0x007 // Bad parameter error
+#define USB_ATA_MARK_NOT_FOUND_ERR 0x002 // Address mark not found error
+#define USB_ATA_NO_MEDIA_ERR 0x031 // No media in drive
+#define USB_ATA_READ_ERR 0x004 // Read error
+#define USB_ATA_UNCORRECTABLE_ERR 0x010 // Uncorrectable data error
+#define USB_ATA_BAD_SECTOR_ERR 0x00A // Bad sector error
+#define USB_ATA_GENERAL_FAILURE 0x020 // Controller general failure
+
+#define atapi_cntlr_not_ready_err 0x080 // ATAPI controller not ready/media not present
+#define atapi_check_condition_err 0x0fd // check condition reported by ATAPI controller
+#define atapi_resend_err 0x0fe // resend the command to ATAPI controller
+#define atapi_media_change_err 0x006 // ATAPI media change error
+#define atapi_reset_err 0x005 // ATAPI reset error
+#define atapi_invalid_func 0x001 // ATAPI invalid function
+
+#define atapi_volume_not_locked_err 0x0B0 // volume not locked in drive
+#define atapi_volume_locked_err 0x0B1 // volume locked in drive
+#define atapi_volume_not_removable_err 0x0B2 // volume not removable
+#define atapi_volume_in_use_err 0x0B3 // volume in use
+#define atapi_lock_count_exceeded_err 0x0B4 // lock count exceeded
+#define atapi_eject_request_failed_err 0x0B5 // valid eject request failed
+
+#define atapi_sense_failed 0x0ff // Sense key command failed
+
+//-----------------------------------------------------------------------
+// Bulk-Only Mass Storage Reset (Class Specific Request)
+//-----------------------------------------------------------------------
+#define BOT_RESET_REQUEST_CODE 0x0FF // Reset Request code
+
+//-----------------------------------------------------------------------
+// Bulk-Only Get Max Lun (Class Specific Request)
+//-----------------------------------------------------------------------
+#define BOT_GET_MAX_LUN_REQUEST_CODE 0x0FE // Get Max Lun Request code
+
+//-----------------------------------------------------------------------
+// USB Command Status Wrapper Structure
+//-----------------------------------------------------------------------
+#define BOT_CSW_SIGNATURE 0x53425355 // 0-3h, signature = "USBS"
+
+//-----------------------------------------------------------------------
+// USB Command Block Wrapper Structure
+//-----------------------------------------------------------------------
+#define BOT_CBW_SIGNATURE 0x43425355 // 0-3h, signature = "USBC"
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 BootIndicator;
+ UINT8 StartHead;
+ UINT8 StartSector;
+ UINT8 StartTrack;
+ UINT8 OSType;
+ UINT8 EndHead;
+ UINT8 EndSector;
+ UINT8 EndTrack;
+ UINT32 StartingLba;
+ UINT32 SizeInLba;
+} MBR_PARTITION;
+
+typedef struct {
+ UINT8 BootCode[440];
+ UINT32 UniqueMbrSig;
+ UINT16 Unknown;
+ MBR_PARTITION PartRec[4];
+ UINT16 Sig;
+} MASTER_BOOT_RECORD;
+
+typedef struct {
+ UINT8 jmp[3]; //0x0
+ CHAR8 OEMName[8]; //0x3
+ UINT16 BytsPerSec; //0xB
+ UINT8 SecPerClus; //0xD
+ UINT16 RsvdSecCnt; //0xE
+ UINT8 NumFATs; //0x10
+ UINT16 RootEntCnt; //0x11
+ UINT16 TotSec16; //0x13
+ UINT8 Media; //0x15
+ UINT16 FATSz16; //0x16
+ UINT16 SecPerTrk; //0x18
+ UINT16 NumHeads; //0x1A
+ UINT32 HiddSec; //0x1C
+ UINT32 TotSec32; //0x20
+ union {
+ struct {
+ UINT8 DrvNum; //0x24
+ UINT8 Reserved1; //0x25
+ UINT8 BootSig; //0x26
+ UINT32 VolID; //0x27
+ CHAR8 VolLab[11]; //0x2B
+ CHAR8 FilSysType[8]; //0x36
+ UINT8 Padding[510 - 0x3E]; //0x3E
+ } Fat16;
+ struct {
+ UINT32 FATSz32; //0x24
+ UINT16 ExtFlags; //0x28
+ UINT16 FSVer; //0x2A
+ UINT32 RootClus; //0x2C
+ UINT16 FSInfo; //0x30
+ UINT16 BkBootSec; //0x32
+ UINT8 Reserved[12]; //0x34
+ UINT8 DrvNum; //0x40
+ UINT8 Reserved1; //0x41
+ UINT8 BootSig; //0x42
+ UINT32 VolID; //0x43
+ CHAR8 VolLab[11]; //0x47
+ CHAR8 FilSysType[8]; //0x52
+ UINT8 Padding2[510 - 0x5A]; //0x5A
+ } Fat32;
+ } Fat;
+ UINT16 Signature;
+} BOOT_SECTOR;
+
+#pragma pack(pop)
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2013, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/usb/rt/amidef.h b/Core/EM/usb/rt/amidef.h
new file mode 100644
index 0000000..a679e7b
--- /dev/null
+++ b/Core/EM/usb/rt/amidef.h
@@ -0,0 +1,503 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/rt/amidef.h 40 10/28/16 3:57a Wilsonlee $
+//
+// $Revision: 40 $
+//
+// $Date: 10/28/16 3:57a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/rt/amidef.h $
+//
+// 40 10/28/16 3:57a Wilsonlee
+// [TAG] EIP300142
+// [Category] Improvement
+// [Description] Remove USB Int1C module part because we use the other
+// method to service xhci.
+// [Files] usbport.c, amidef.h, amiusbhc.c, UsbLegacy.cif
+//
+// 39 10/28/16 1:29a Wilsonlee
+// [TAG] EIP300142
+// [Category] Improvement
+// [Description] Get vector value from memory 0x1c directly and check
+// it's not zero.
+// [Files] usbport.c, amidef.h
+//
+// 38 12/16/13 1:41a Ryanchou
+// [TAG] EIP142509
+// [Category] Improvement
+// [Description] Added usage 0x87 and 0x89.
+// [Files] efiusbkb.c, efiusbkb.h. amidef.h
+//
+// 37 5/22/12 10:03a Ryanchou
+// [TAG] EIP90154
+// [Category] Improvement
+// [Description] Remove the USBSB_EnableSmmPeriodicSmi and
+// USBSB_DisableSmmPeriodicSmi hooks.
+// [Files] amidef.h, amiusb.c, usb.c, usbsb.c
+//
+// 36 5/04/12 5:20a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 35 11/08/11 2:01a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 34 4/06/11 3:26a Ryanchou
+// [TAG] EIP55275
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] EBDA:108 conflict
+// [RootCause] The EIP48064 save EFI_USB_PROTOCOL pointer in EBDA:108,
+// but Keymon filter driver used the same location.
+// [Solution] Use the EBDA:32 to save EFI_USB_PROTOCOL pointer and add a
+// signature in EFI_USB_PROTOCOL.
+// [Files] amidef.h, AmiUsbController.h, uhcd.c, usbsb.c
+//
+// 33 11/22/10 8:44a Ryanchou
+// [TAG] EIP48064
+// [Category] Improvement
+// [Description] The SB template implemented elink
+// AcpiEnableCallbackList, the XHCI/EHCI hand off function should be
+// invoked via the elink AcpiEnableCallbackList.
+// [Files] amidef.h, amiusb.c, amiusb.dxs, amiusb.h,
+// AmiUsbController.h, usb.sdl, usbrt.mak, usbsb.c
+//
+// 32 10/07/10 10:14a Ryanchou
+// EIP41379: Move the code that install xHCI hardware SMI handler in
+// XHCI_Start function.
+//
+// 31 3/25/10 9:47a Olegi
+//
+// 30 3/19/10 10:06a Olegi
+//
+// 29 11/30/09 6:11p Olegi
+//
+// 28 11/30/09 9:08a Olegi
+//
+// 27 10/02/09 10:50a Olegi
+// Code cleanup.
+//
+// 26 10/03/08 3:33p Olegi
+//
+// 25 9/05/08 3:45p Olegi
+// Definitions related to USB SMI code isolation.
+//
+// 24 5/16/08 12:03p Olegi
+// Compliance with AMI coding standard.
+//
+// 23 7/13/07 11:42a Olegi
+// F11 and F12 codes added.
+//
+// 22 3/20/07 1:26p Olegi
+//
+// 21 3/07/07 5:59p Olegi
+//
+// 20 10/25/06 10:59a Olegi
+//
+// 19 10/12/06 9:11p Andriyn
+//
+// 18 10/12/06 5:17p Olegi
+//
+// 17 10/12/06 5:01p Felixp
+// EfiCreateEventLegacyBoot added
+//
+// 16 10/12/06 4:42p Olegi
+//
+// 15 5/31/06 6:56p Mirk
+// Core 4.5 compliant - DP Length manipulation changes.
+//
+// 14 5/03/06 10:00a Olegi
+//
+// 13 4/14/06 6:43p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 10 1/11/06 1:42p Olegi
+//
+// 9 11/10/05 11:11a Olegi
+//
+// 8 8/26/05 12:25p Andriyn
+//
+// 7 8/15/05 3:59p Olegi
+//
+// 6 8/05/05 3:38p Andriyn
+// Complience with EFI EDK
+//
+// 5 6/03/05 6:32p Andriyn
+// Redifinition of library function for source complience with Aptio
+//
+// 4 5/20/05 11:05a Andriyn
+// reconcile Aptio changes with Alaska
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/29/05 10:40a Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AmiDef.h
+//
+// Description: AMI USB driver definitions, framework specific
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+// Avoid including multiple instance of this file
+
+#ifndef __AMI_H
+#define __AMI_H
+
+#include "token.h"
+
+#define USB_DRIVER_VERSION (USB_DRIVER_MAJOR_VER << 4) + USB_DRIVER_MINOR_VER
+
+#include "Efi.h"
+#include <AmiDxeLib.h>
+#define _FAR_
+
+// Basic type definitions of various size
+
+#if (__STDC_VERSION__ < 199901L )
+
+ /* No ANSI C 1999/2000 stdint.h integer width declarations */
+
+ #if _MSC_EXTENSIONS
+
+ /* Use Microsoft C compiler integer width declarations */
+#if _64_BIT_EXTENSIONS
+ typedef unsigned __int64 UINT64;
+ typedef __int64 INT64;
+typedef UINT64 QWORD;
+typedef QWORD * PQWORD;
+typedef QWORD _FAR_ * FPQWORD;
+typedef UINT64 * PUINT64;
+typedef INT64 * PINT64;
+typedef UINT64 _FAR_ * FPUINT64;
+typedef INT64 _FAR_ * FPINT64;
+#endif
+// typedef unsigned __int32 UINT32;
+// typedef __int32 INT32;
+// typedef unsigned __int16 UINT16;
+// typedef __int16 INT16;
+// typedef unsigned __int8 UINT8;
+// typedef __int8 INT8;
+ #else
+#if _64_BIT_EXTENSIONS
+#endif
+ #endif
+#endif
+
+// Return code definition
+typedef INT16 RETCODE;
+
+// 64-bit extenstion definition
+#if _64_BIT_EXTENSIONS
+#endif
+
+#ifndef NULL
+#define NULL 0
+#endif
+
+// Private and public definitions
+#define PRIVATE static
+#define PUBLIC
+
+// Function IN/OUT definitions
+#define IN
+#define OUT
+#define IN_OUT
+
+// Return codes
+#define SUCCESS 0
+#define FAILURE -1
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+#ifndef FALSE
+#define FALSE 0
+#endif
+// Bit equates
+#define BIT0 0x01
+#define BIT1 0x02
+#define BIT2 0x04
+#define BIT3 0x08
+#define BIT4 0x10
+#define BIT5 0x20
+#define BIT6 0x40
+#define BIT7 0x80
+#define BIT8 0x100
+#define BIT9 0x200
+/* defined in AmiDxeLib
+#define BIT10 0x400
+#define BIT11 0x800
+#define BIT12 0x1000
+#define BIT13 0x2000
+#define BIT14 0x4000
+#define BIT15 0x8000
+#define BIT16 0x10000
+#define BIT17 0x20000
+#define BIT18 0x40000
+#define BIT19 0x80000
+#define BIT20 0x100000
+#define BIT21 0x200000
+#define BIT22 0x400000
+#define BIT23 0x800000
+#define BIT24 0x1000000
+#define BIT25 0x2000000
+#define BIT26 0x4000000
+#define BIT27 0x8000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+*/
+#define SCAN_NULL EFI_SCAN_NULL
+#define SCAN_ESC EFI_SCAN_ESC
+#define SCAN_F1 EFI_SCAN_F1
+#define SCAN_F2 EFI_SCAN_F2
+#define SCAN_F3 EFI_SCAN_F3
+#define SCAN_F4 EFI_SCAN_F4
+#define SCAN_F5 EFI_SCAN_F5
+#define SCAN_F6 EFI_SCAN_F6
+#define SCAN_F7 EFI_SCAN_F7
+#define SCAN_F8 EFI_SCAN_F8
+#define SCAN_F9 EFI_SCAN_F9
+#define SCAN_F10 EFI_SCAN_F10
+#define SCAN_F11 EFI_SCAN_F11
+#define SCAN_F12 EFI_SCAN_F12
+#define SCAN_INSERT EFI_SCAN_INS
+#define SCAN_HOME EFI_SCAN_HOME
+#define SCAN_PAGE_UP EFI_SCAN_PGUP
+#define SCAN_DELETE EFI_SCAN_DEL
+#define SCAN_END EFI_SCAN_END
+#define SCAN_PAGE_DOWN EFI_SCAN_PGDN
+#define SCAN_RIGHT EFI_SCAN_RIGHT
+#define SCAN_LEFT EFI_SCAN_LEFT
+#define SCAN_DOWN EFI_SCAN_DN
+#define SCAN_UP EFI_SCAN_UP
+
+#ifndef SCAN_PAUSE
+#define SCAN_PAUSE 0x0048
+#define SCAN_F13 0x0068
+#define SCAN_F14 0x0069
+#define SCAN_F15 0x006A
+#define SCAN_F16 0x006B
+#define SCAN_F17 0x006C
+#define SCAN_F18 0x006D
+#define SCAN_F19 0x006E
+#define SCAN_F20 0x006F
+#define SCAN_F21 0x0070
+#define SCAN_F22 0x0071
+#define SCAN_F23 0x0072
+#define SCAN_F24 0x0073
+#define SCAN_MUTE 0x007F
+#define SCAN_VOLUME_UP 0x0080
+#define SCAN_VOLUME_DOWN 0x0081
+#define SCAN_BRIGHTNESS_UP 0x0100
+#define SCAN_BRIGHTNESS_DOWN 0x0101
+#define SCAN_SUSPEND 0x0102
+#define SCAN_HIBERNATE 0x0103
+#define SCAN_TOGGLE_DISPLAY 0x0104
+#define SCAN_RECOVERY 0x0105
+#define SCAN_EJECT 0x0106
+#endif
+
+#define EFI_BLOCK_IO_PROTOCOL EFI_BLOCK_IO
+#define EFI_SIMPLE_TEXT_IN_PROTOCOL SIMPLE_INPUT_INTERFACE
+
+//#define MESSAGING_DEVICE_PATH MESSAGING_DEVICE_PATH_TYPE
+//#define MSG_USB_CLASS_DP MSG_USB_CLASS_DEVICE_PATH_SUBTYPE
+#define EFI_END_ENTIRE_DEVICE_PATH END_DEVICE_PATH
+#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE END_ENTIRE_SUBTYPE
+//#define MSG_SCSI_DP MSG_SCSI_DEVICE_PATH_SUBTYPE
+//#define Pun TargetId
+
+#define EFI_DRIVER_ENTRY_POINT(x)
+//#define EFI_LOADED_IMAGE_PROTOCOL EFI_LOADED_IMAGE
+#define EfiInitializeSmmDriverLib(ImageHandle, SystemTable) InitAmiLib(ImageHandle, SystemTable)
+#define EfiInitializeDriverLib(ImageHandle, SystemTable) InitAmiLib(ImageHandle,SystemTable)
+#define gBS pBS
+#define gRT pRS
+#define EfiDuplicateDevicePath DPCopy
+
+
+// Loop forever macro
+#define LOOP_FOREVER while(1)
+
+#if defined(DEBUG_SWITCH) && (DEBUG_SWITCH == 1)
+#define EfiDebugVPrint(EFI_D_ERROR, Message, ArgList) PrintDebugMessageVaList(-1, Message, ArgList)
+
+extern RETCODE PrintDebugMsg (int, char *, ...);
+#define USB_DEBUG PrintDebugMsg
+#define USB_DEBUG_LEVEL DEBUG_LEVEL_3
+void DEBUG_DELAY();
+#else
+extern RETCODE PrintDebugMsg (int, char *, ...);
+#define USB_DEBUG 1?0:PrintDebugMsg
+#define DEBUG_DELAY
+#endif
+
+#if GENERIC_USB_CABLE_SUPPORT
+#undef USB_DEBUG
+#define USB_DEBUG
+#endif
+
+#define MAX_DEBUG_LEVEL 8
+
+#define DEBUG_LEVEL_8 8
+#define DEBUG_LEVEL_7 7
+#define DEBUG_LEVEL_6 6
+#define DEBUG_LEVEL_5 5
+#define DEBUG_LEVEL_4 4
+#define DEBUG_LEVEL_3 3
+#define DEBUG_LEVEL_2 2
+#define DEBUG_LEVEL_1 1
+#define DEBUG_LEVEL_0 0
+
+#define MICROSECOND 10
+#define MILLISECOND (1000 * MICROSECOND)
+#define ONESECOND (1000 * MILLISECOND)
+
+#define USB_DATA_EBDA_OFFSET 0x104
+#define USB_PROTOCOL_EBDA_OFFSET 0x32 //(EIP55275)
+
+#define GET_CPUSAVESTATE_REG(x) (URP_STRUC*)(UINTN)gSmst->CpuSaveState->Ia32SaveState.x
+//#define GET_FV_NAME(pImage) &((FV_FILE_PATH_DEVICE_PATH*)(pImage->FilePath))->Name
+#define GET_FV_NAME(pImage) &((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH*)(pImage->FilePath))->NameGuid
+#define EfiDevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8))
+//#define EfiNextDevicePathNode(a) ((EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + \
+// EfiDevicePathNodeLength(a)))
+#define EfiNextDevicePathNode(a) NEXT_NODE(a)
+
+#define EfiDevicePathType(a) ( ((a)->Type) & 0x7f )
+#define EfiIsDevicePathEndType(a) (EfiDevicePathType(a) == 0x7f)
+
+
+#define EfiIsDevicePathEndSubType(a) ((a)->SubType == 0xFF)
+#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == 1)
+
+#define EfiIsDevicePathEnd(a) ( EfiIsDevicePathEndType(a) && \
+ EfiIsDevicePathEndSubType(a) )
+#define EfiIsDevicePathEndInstance(a) ( EfiIsDevicePathEndType(a) && \
+ EfiIsDevicePathEndInstanceSubType(a) )
+//#define SetDevicePathNodeLength(a,l) { (a)->Length = (l); }
+#define SetDevicePathNodeLength(a,l) ( SET_NODE_LENGTH(a,l) )
+//#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
+#define DevicePathNodeLength(a) ( NODE_LENGTH(a) )
+//#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
+#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + NODE_LENGTH(a)))
+#define SetDevicePathEndNode(a) { \
+ (a)->Type = 0x7F; \
+ (a)->SubType = 0xFF; \
+ (a)->Length = sizeof(EFI_DEVICE_PATH_PROTOCOL); \
+ }
+
+#define VA_LIST va_list
+#define VA_START va_start
+#define VA_ARG va_arg
+#define VA_END va_end
+
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#define _CR(Record, TYPE, Field) \
+ ((TYPE *) ( (CHAR8 *)(Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define EFI_SIGNATURE_16(A,B) ((A) | (B<<8))
+#define EFI_SIGNATURE_32(A,B,C,D) (EFI_SIGNATURE_16(A,B) | (EFI_SIGNATURE_16(C,D) << 16))
+#define EFI_SIGNATURE_64(A,B,C,D,E,F,G,H) (EFI_SIGNATURE_32(A,B,C,D) | ((UINT64)(EFI_SIGNATURE_32(E,F,G,H)) << 32))
+
+#define EfiCopyMem(_Destination, _Source, _Length) gBS->CopyMem ((_Destination), (_Source), (_Length))
+#define EfiSetMem(_Destination, _Length, _Value) gBS->SetMem ((_Destination), (_Length), (_Value))
+#define EfiZeroMem(_Destination, _Length) gBS->SetMem ((_Destination), (_Length), 0)
+
+#define EFI_TPL_NOTIFY TPL_NOTIFY
+#define EFI_TPL_CALLBACK TPL_CALLBACK
+#define EFI_TPL_HIGH_LEVEL TPL_HIGH_LEVEL
+
+#define EFI_CHECK(x) {EFI_STATUS status = (x);if(status!=EFI_SUCCESS)return status;}
+#define COUNTOF(x) (sizeof(x)/sizeof((x)[0]))
+
+#define EfiAppendDevicePathNode DPAddNode
+// redefined in core 4.05 #define DPLENGTH(x) ((x).Length)
+
+void cp( UINT8 code);
+
+#define EfiCreateEventLegacyBoot CreateLegacyBootEvent
+
+VOID USB_SmiQueuePut(VOID*);
+
+typedef struct
+{
+ UINT8 Down;
+ UINT8 KeyCode;
+} USB_KEY;
+
+#define MAX_KEY_ALLOWED 32
+
+typedef struct
+{
+ USB_KEY buffer[MAX_KEY_ALLOWED + 1];
+ UINT8 bHead;
+ UINT8 bTail;
+} USB_KB_BUFFER;
+
+EFI_STATUS USBSB_InstallSmiEventHandlers(VOID);
+EFI_STATUS USBSB_InstallXhciHwSmiHandler(VOID);
+EFI_STATUS USBSB_InstallUsbIntTimerHandler(VOID);
+EFI_STATUS USBSB_UninstallTimerHandlers(VOID);
+
+#endif // __AMI_H
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/amiusb.c b/Core/EM/usb/rt/amiusb.c
new file mode 100644
index 0000000..89a2975
--- /dev/null
+++ b/Core/EM/usb/rt/amiusb.c
@@ -0,0 +1,3402 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/amiusb.c 121 10/16/16 10:11p Wilsonlee $
+//
+// $Revision: 121 $
+//
+// $Date: 10/16/16 10:11p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/amiusb.c $
+//
+// 121 10/16/16 10:11p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 120 7/29/16 3:13a Wilsonlee
+// [TAG] EIP264662
+// [Category] Improvement
+// [Description] Don't install usb hw smi after reconnecting usb
+// controllers.
+// [Files] uhcd.c, usb.c, ohci.c, amiusb.c, amiusbhc.c
+//
+// 119 7/29/16 3:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 117 7/07/16 1:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 116 10/16/15 3:34a Wilsonlee
+// [TAG] EIP241977
+// [Category] Improvement
+// [Description] Improve UsbKbcAccessControl api function.
+// [Files] amiusb.c
+//
+// 115 4/10/15 3:12a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 114 2/10/15 12:20a Wilsonlee
+// Fixed build error in non-smm projects.
+//
+// 113 12/03/14 9:36p Wilsonlee
+// [TAG] EIP193805
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in USB module.
+// [Files] amiusb.c, uhcd.c, usbrt.mak, usbdef.h, usbsb.c
+//
+// 112 11/23/14 10:10p Wilsonlee
+// [TAG] EIP189293
+// [Category] Improvement
+// [Description] Implement XHCI key repeat function.
+// [Files] usb.c, xhci.c , xhci.h, amiusb.c
+//
+// 111 6/05/14 9:15p Wilsonlee
+// [TAG] EIP171837
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] When use afuwin update BIOS or read ROMID under pure Win8.1
+// OS, sometimes the system will blue screen.
+// [RootCause] UsbData->EfiKeyboardBuffer is EfiBootServicesData. This
+// memory isn't reserved in OS. We can't write data to this memory in OS.
+// [Solution] We clear the buffer at USBKBDProcessKeyboardData function
+// if the system is under EFI.
+// [Files] amiusb.c
+//
+// 110 4/30/14 5:25a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 109 4/07/14 1:28a Wilsonlee
+// [TAG] EIP157193
+// [Category] Improvement
+// [Description] Stop the usb host controllers at AcpiModeEnable if they
+// art extend cards or don't support HW SMI.
+// [Files] amiusb.c
+//
+// 108 2/10/14 1:19a Ryanchou
+// [TAG] EIP149929
+// [Category] Improvement
+// [Description] Stop all external EHCI HCs in ACPI enable call.
+// [Files] amiusb.c
+//
+// 107 12/15/13 10:16p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 106 11/05/13 4:46a Ryanchou
+// [TAG] EIP135636
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NumLock LED cannot be on/off properly.
+// [RootCause] It is the side effect of EIP #107429 changes, the
+// keyboard does not generate break code when pressing NumLock.
+// [Solution] Remove the EIP #107429 changes.
+// [Files] amiusb.c, usbkbd.c, efiusbkb.c
+//
+// 105 10/19/13 7:06a Ryanchou
+// [TAG] EIP138257
+// [Category] Improvement
+// [Description] Correct USB HID device type.
+// [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c
+//
+// 104 8/06/13 4:21a Wilsonlee
+// [TAG] EIP128970
+// [Category] Improvement
+// [Description] UsbInstallHwSmiHandler returns EFI_UNSUPPORTED if
+// HCType is invalid.
+// [Files] amiusb.c
+//
+// 103 6/02/13 11:43p Wilsonlee
+// [TAG] EIP123235
+// [Category] Improvement
+// [Description] Stop the usb host controller at ExitBootService if it
+// is an extend card or it doesn't support HW SMI.
+// [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c,
+// uhcd.c
+//
+// 102 4/10/13 9:29p Wilsonlee
+// [TAG] EIP120573
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Afuwinx64/Safuwinx64 hang up issue.
+// [RootCause] EfiZeroMem is a boot service function, we can't use it
+// during runtime.
+// [Solution] Use MemFill function to clear the KBC buffers.
+// [Files] amiusb.c
+//
+// 101 3/19/13 3:58a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 100 1/23/13 4:15a Ryanchou
+// [TAG] EIP111280
+// [Category] Improvement
+// [Description] Add USB APIs for external driver.
+// [Files] amiusb.c, amiusb.h, usbdef.h
+//
+// 99 1/22/13 3:09a Wilsonlee
+// [TAG] EIP112938
+// [Category] Improvement
+// [Description] Create a header file for usb mass storage driver.
+// [Files] UsbMass.h, usbmass.c, usbdef.h, amiusb.c, efiusbmass.c
+//
+// 98 12/21/12 5:02a Ryanchou
+// [TAG] EIP71730
+// [Category] New Feature
+// [Description] Added OHCI handoff support.
+// [Files] usb.sdl, usbport.c, amiusb.c, usbdef.h, UsbPolicy.h, usb.sd,
+// usb.uni
+//
+// 97 12/09/12 12:12a Wilsonlee
+// [TAG] EIP107429
+// [Category] Improvement
+// [Description] Process the make code even if there is no break code.
+// [Files] efiusbkb.c, amiusb.c
+//
+// 96 12/02/12 10:23p Roberthsu
+// [TAG] EIP102150
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Push key and unplug KB , character repeat can not.
+// stop
+// [RootCause] Because repeat key does not clear when usb keyboard
+// unplug.
+// [Solution] When keyboard disconnrct, clear keyboard device id with
+// device id buffer and scancode buffer.
+// [Files] amiusb.c,syskbc.c,uhcd.c,usbkbd.c
+//
+// 95 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 94 8/29/12 8:10a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 93 8/07/12 9:39p Wilsonlee
+// [TAG] EIP96366
+// [Category] New Feature
+// [Description] Add the token "DEFAULT_USB_EMUL6064_OPTION" that
+// control the default value of the I/O port 60h/64h emulation support
+// option.
+// [Files] usb.sd, usb.sdl, amiusb.c, amiusb.h
+//
+// 92 6/13/12 7:31a Lavanyap
+// [TAG] EIP89825
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System get's hangs inside the SMI handler while flashing
+// the Bios.
+// [RootCause] Port 60/64 access SMI will not be generated immediately
+// if accessed inside an SMI handler when KbcEmulation is enabled.
+// [Solution] Emulation is disabled while accessing the Port 60/64.
+// [Files] amiusb.c
+//
+// 91 5/22/12 10:03a Ryanchou
+// [TAG] EIP90154
+// [Category] Improvement
+// [Description] Remove the USBSB_EnableSmmPeriodicSmi and
+// USBSB_DisableSmmPeriodicSmi hooks.
+// [Files] amidef.h, amiusb.c, usb.c, usbsb.c
+//
+// 90 5/04/12 6:37a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 89 5/04/12 5:21a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 88 5/03/12 5:50a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 87 1/16/12 6:01a Ryanchou
+// [TAG] EIP81132
+// [Description] Add core version check for EIP80609 solution.
+// [Files] amiusb.c, usbrt.mak, usbsb.c
+//
+// 86 1/14/12 4:09a Ryanchou
+// [TAG] EIP80609
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] If to enable debug mode and set launch CSM is "Never" in
+// setup, system will hang at 0xB1
+// [RootCause] The pointer AmiUsb is invalid if CSM is not launched,
+// that may cause CPU exception.
+// [Solution] Added USB smm protocol, and use SmmLocateProtocol to get
+// the pointer.
+// [Files] amiusb.c, AmiUsbController.h, usbrt.mak, usbsb.c
+//
+// 85 1/13/12 4:23a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 84 12/09/11 3:09p Ryanchou
+// [TAG] EIP7768
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] USB mass storage can't work after unplug and plug under DOS
+// [RootCause] The SW SMI handler checks USB_FLAG_RUNNING_UNDER_EFI flag
+// to get the URP from USB global data area or EBDA. Legacy boot event
+// clears the flag, and UsbPrepareForLegacyOS will not be invoked.
+// [Solution] Check the URP in USB global data area, if it is not empty,
+// get it in USB global data area, or get it in EBDA.
+// [Files] amiusb.c
+//
+// 83 11/08/11 8:22a Wilsonlee
+// [TAG] EIP74876
+// [Category] New Feature
+// [Description] Add USB API for shutdown single USB controller.
+// [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 82 11/08/11 1:41a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 81 11/05/11 3:26a Ryanchou
+// [TAG] EIP70094
+// [Category] Improvement
+// [Description] Microsoft CSM Opt-Out feature implementation.
+// [Files] amiusb.c, uhcd.c
+//
+// 80 10/17/11 2:24a Ryanchou
+// [TAG] EIP69136
+// [Category] Improvement
+// [Description] Remove the dependency of EBDA in USB module for CSM
+// disabling.
+// [Files] amiusb.c, uhcd.c, usbport.c, usbsb.c
+//
+// 79 9/28/11 10:45a Ryanchou
+// [TAG] EIP66064
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System hangs when waiting for finger swipe
+// [RootCause] USB driver save the URP pointer to EBDA in function
+// UsbSmiCore and UsbSmiHc, the pointer will be destroyed if someone also
+// invoke the two functions.
+// [Solution] Save the URP pointer before generate SW SMI and restore it
+// after return from SMI.
+// [Files] amiusb.c, amiusbhc.c, usbport.c
+//
+// 78 8/08/11 6:57a Ryanchou
+// [TAG] EIP54018
+// [Category] New Feature
+// [Description] Added USB S5 wake up support.
+// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h,
+// usbsb.c xhci.c
+//
+// 77 8/05/11 6:18a Ryanchou
+// [TAG] EIP60706
+// [Category] Improvement
+// [Description] Move gUsbBadDeviceTable into SMRAM.
+// [Files] usbport.c, amiusb.c, usb.c, uhcd.c, AmiUsbController.h
+//
+// 76 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 75 7/12/11 8:09a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 74 5/03/11 8:44a Ryanchou
+// [TAG] EIP57521
+// [Category] Improvement
+// [Description] Enumerate root hub ports after start host controllers
+// in USB_StartLegacy.
+// [Files] amiusb.c
+//
+// 73 3/30/11 9:02a Ryanchou
+// [TAG] EIP41483
+// [Category] Improvement
+// [Description] Stop timer SMI after legacy shutdown.
+// [Files] amiusb.c, AmiUsbController.h, ohci.c
+//
+// 72 3/29/11 10:07a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 71 12/24/10 5:02a Tonylo
+// [TAG] EIP48323
+// [Category] Improvement
+// [Description] Reflush USB keyboard data buffer to avoid junk data
+// sent after enable USB keyboard data throughput.
+// [Files] AMIUSB.C
+//
+// 70 11/22/10 8:42a Ryanchou
+// [TAG] EIP48064
+// [Category] Improvement
+// [Description] The SB template implemented elink
+// AcpiEnableCallbackList, the XHCI/EHCI hand off function should be
+// invoked via the elink AcpiEnableCallbackList.
+// [Files] amidef.h, amiusb.c, amiusb.dxs, amiusb.h,
+// AmiUsbController.h, usb.sdl, usbrt.mak, usbsb.c
+//
+// 69 10/07/10 9:32a Ryanchou
+// EIP42986: Remove the retry loop in UsbHwSmiHandler.
+//
+// 68 8/31/10 8:57a Tonylo
+// Remove user tags for coding standard.
+//
+// Description: Remove user tags for coding standard.
+//
+// 67 8/18/10 4:22p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 66 7/27/10 9:11a Ryanchou
+// EIP41216: Return correct error code when device isn't present.
+//
+// 65 7/15/10 4:33a Tonylo
+// EIP21649 - USB mass storage device still appear in BBS menu when USB
+// legacy support is disabled.
+//
+// 64 6/07/10 8:56a Ryanchou
+// EIP38547: Fixed system halt when installing FreeBSD.
+//
+// 63 3/31/10 6:26p Olegi
+//
+// 62 3/25/10 9:45a Olegi
+//
+// 61 3/19/10 10:05a Olegi
+//
+// 60 1/27/10 5:19p Olegi
+// Added chipset porting hook to initialize timers.
+//
+// 59 12/01/09 10:06a Olegi
+// EIP31535: RWV error code corrected.
+//
+// 58 11/25/09 8:05a Olegi
+// EIPEIP29733: Added KBC access control API
+//
+// 57 10/30/09 5:47p Olegi
+//
+// 56 10/02/09 10:49a Olegi
+// Code cleanup.
+//
+// 54 9/15/09 10:21a Olegi
+// Added USB_INCMPT_HID_DATA_OVERFLOW incompatibility type.
+//
+// 53 8/26/09 11:41a Olegi
+// Changes that prevent collision of keyboard activity and mass storage
+// access. EIP#22808
+//
+// 52 5/22/09 1:46p Olegi
+// Added the special treatment for in-built hubs.
+//
+// 51 5/21/09 5:11p Olegi
+// Added checking for hotplug fake drives in Read/Write/Verify functions.
+//
+// 50 1/29/09 2:31p Olegi
+// USB API CheckDevicePresence is extended with USB_SRCH_DEVBASECLASS_NUM
+// search key.
+//
+// 49 1/23/09 4:28p Olegi
+// Added EXTRA_CHECK_DEVICE_READY condition for the fix to EIP#15037.
+//
+// 48 1/05/09 9:40a Olegi
+// Changes for EIP#15037. Extra CheckDeviceReady call added to read/write
+// functions.
+//
+// 46 10/06/08 3:33p Olegi
+// EHCI change ownership testing in DOS fix (EIP#14855).
+//
+// 44 9/24/08 4:01p Olegi
+// Modified USBAPI_ChangeOwner so that it allows multiple calls to
+// acquiring the ownership without releasing it.
+//
+// 43 7/04/08 1:07p Olegi
+// Device "Ultra-X, Inc.: Ultra-X QTP USB HD 1.01" is removed from
+// incompatible device list.
+//
+// 42 6/27/08 5:52p Olegi
+// Added incompatible devices.
+//
+// 41 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 40 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 39 12/05/07 4:36p Olegi
+// Modification in USBSWSMIHandler() related to the 64/32-bit pointers.
+//
+// 36 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 34 6/11/07 2:53p Olegi
+// Bugfix in device read/write routine: do not issue RWV command if there
+// is no media present.
+//
+// 32 3/20/07 12:16p Olegi
+// SMITHUNK removed.
+//
+// 28 10/18/06 9:40a Andriyn
+// Fix: race condition on hot-plug in / plug-off
+//
+// 27 10/12/06 4:41p Olegi
+// Modified the method of passing arguments into USBSWSMIHandler: it is
+// done through memory location, not using CPU register. This change is
+// only valid for CSM16 versions 31 and later.
+//
+// 26 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 24 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 23 3/06/06 6:22p Olegi
+// Lun devices support modifications: supported using the index in
+// DEV_INFO table, not through dedicated massLun table.
+//
+// 21 1/11/06 11:51a Olegi
+// LegacyUsbSupport setup question functionality added.
+//
+// 18 10/20/05 3:08p Olegi
+// ReadDevice correction (EST change).
+//
+// 14 8/25/05 7:19p Andriyn
+// USB Keyboard and mouse to use EMUL 60/64 for passing data to KBC.
+// Fall-back when EMUL 60/64 is not present
+//
+// 13 8/23/05 5:50p Olegi
+// USBMassGetDeviceParameters function added.
+//
+// 12 8/11/05 9:53a Olegi
+// 60/64 port emulation related fixes for EMU6064 driver.
+//
+// 11 8/04/05 5:58p Andriyn
+// Legacy over LegacyFree
+//
+// 10 6/20/05 8:55a Olegi
+// .NET compiler with highest warning level and warning-as-error
+// modification.
+//
+// 9 6/15/05 1:59p Andriyn
+// Comments were changed
+//
+// 6 6/03/05 6:06p Olegi
+// UsbHwSmiHandler modified to be called individually from UHCI, OHCI and
+// EHCI drivers.
+//
+// 5 6/03/05 9:28a Olegi
+// ATA Error reporting is corrected in USBWrapGetATAErrorCode.
+//
+// 4 6/01/05 5:21p Olegi
+// Debug message shortened.
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:11p Andriyn
+// USBBUS implementation
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AMIUSB.C
+//
+// Description: AMI USB API implementation. The following code will be
+// copied to SMM; only RT functions can be used. gUsbData
+// is obtained from AMIUHCD in the entry point and can be
+// used afterwards.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiDxeLib.h>
+#include "amiusb.h"
+#include "amidef.h"
+#include <UsbDevDriverElinks.h> //(EIP71750+)
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#include <AmiUsbSmmGlobalDataValidationLib.h>
+#endif
+
+#if USB_DEV_KBD
+#include "usbkbd.h"
+#endif
+#include "UsbMass.h"
+
+ //(EIP54018+)>
+#if USB_S5_WAKEUP_SUPPORT
+#include <Protocol\SmmSxDispatch.h>
+#include <Protocol\SmmPowerButtonDispatch.h>
+#endif
+ //<(EIP54018+)
+//#pragma warning (disable: 4152)
+
+extern UINT8 IsKbcAccessBlocked; //(EIP29733+)
+EFI_EMUL6064MSINPUT_PROTOCOL* gMsInput = 0;
+EFI_EMUL6064KBDINPUT_PROTOCOL* gKbdInput = 0;
+EFI_EMUL6064TRAP_PROTOCOL* gEmulationTrap = 0;
+
+USB_GLOBAL_DATA *gUsbData;
+//USB_BADDEV_STRUC *gUsbBadDeviceTable; //(EIP60706-)
+
+AMI_USB_SMM_PROTOCOL gUsbSmmProtocol = {0};
+
+BOOLEAN gLockSmiHandler = FALSE;
+BOOLEAN gLockHwSmiHandler = FALSE;
+BOOLEAN gCheckUsbApiParameter = FALSE;
+
+VOID StopControllerType(UINT8);
+VOID StartControllerType(UINT8);
+UINT8 USB_StopDevice (HC_STRUC*, UINT8, UINT8);
+UINT8 USB_EnumerateRootHubPorts(UINT8); //(EIP57521+)
+VOID StopControllerBdf(UINT16); //(EIP74876+)
+
+VOID FillHcdEntries();
+ //(EIP71750+)>
+typedef VOID USB_DEV_DELAYED_DRIVER_CHECK (DEV_DRIVER*);
+extern USB_DEV_DELAYED_DRIVER_CHECK USB_DEV_DELAYED_DRIVER EndOfUsbDevDelayedDriverList;
+USB_DEV_DELAYED_DRIVER_CHECK* UsbDevDelayedDrivers[]= {USB_DEV_DELAYED_DRIVER NULL};
+
+typedef VOID USB_DEV_DRIVER_CHECK (DEV_DRIVER*);
+extern USB_DEV_DRIVER_CHECK USB_DEV_DRIVER EndOfUsbDevDriverList;
+USB_DEV_DRIVER_CHECK* UsbDevDrivers[]= {USB_DEV_DRIVER NULL};
+ //<(EIP71750+)
+ //(EIP54018+)>
+#if USB_S5_WAKEUP_SUPPORT
+VOID UsbSuspend(VOID);
+#endif
+
+#if USB_S5_WAKEUP_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbS5SmiCallback
+//
+// Description:
+// This function enter usb s5 callback.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UsbS5SmiCallback(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SX_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+#endif
+ UsbSuspend();
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbPowerButtonSmiCallback
+//
+// Description:
+// This function enter s5 callback if press power button.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UsbPowerButtonSmiCallback(
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+#endif
+ UsbSuspend();
+}
+#endif
+ //<(EIP54018+)
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: aUsbApiTable - USB API Function Dispatch Table
+//
+// Type: Function Dispatch Table
+//
+// Description: This is the table of functions used by USB API
+//
+// Notes: This functions are invoked via software SMI
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+API_FUNC aUsbApiTable[] = {
+ USBAPI_CheckPresence,
+ USBAPI_Start,
+ USBAPI_Stop,
+ USBAPI_DisableInterrupts,
+ USBAPI_EnableInterrupts,
+ USBAPI_MoveDataArea,
+ USBAPI_GetDeviceInfo,
+ USBAPI_CheckDevicePresence,
+ USBAPI_MassDeviceRequest,
+ USBAPI_PowerManageUSB,
+ USBAPI_PrepareForOS,
+ USBAPI_SecureInterface,
+ USBAPI_LightenKeyboardLEDs,
+ USBAPI_ChangeOwner,
+ USBAPI_HC_Proc,
+ USBAPI_Core_Proc,
+ USBAPI_LightenKeyboardLEDs_Compatible,
+ USBAPI_KbcAccessControl,
+ USBAPI_LegacyControl,
+ USBAPI_GetDeviceAddress,
+ USBAPI_ExtDriverRequest,
+ USBAPI_CCIDRequest,
+ USBAPI_UsbStopController, //(EIP74876+)
+ USBAPI_HcStartStop
+};
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: USBMassAPITable - USB Mass Storage API Function Dispatch Table
+//
+// Type: Function Dispatch Table
+//
+// Description: This is the table of functions used by USB Mass Storage API
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+API_FUNC aUsbMassApiTable[] = {
+ USBMassAPIGetDeviceInformation, // USB Mass API Sub-Func 00h
+ USBMassAPIGetDeviceGeometry, // USB Mass API Sub-Func 01h
+ USBMassAPIResetDevice, // USB Mass API Sub-Func 02h
+ USBMassAPIReadDevice, // USB Mass API Sub-Func 03h
+ USBMassAPIWriteDevice, // USB Mass API Sub-Func 04h
+ USBMassAPIVerifyDevice, // USB Mass API Sub-Func 05h
+ USBMassAPIFormatDevice, // USB Mass API Sub-Func 06h
+ USBMassAPICommandPassThru, // USB Mass API Sub-Func 07h
+ USBMassAPIAssignDriveNumber, // USB BIOS API function 08h
+ USBMassAPICheckDevStatus, // USB BIOS API function 09h
+ USBMassAPIGetDevStatus, // USB BIOS API function 0Ah
+ USBMassAPIGetDeviceParameters // USB BIOS API function 0Bh
+};
+
+EFI_DRIVER_ENTRY_POINT(USBDriverEntryPoint)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: USBDriverEntryPoint
+//
+// Description: USB Driver entry point
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+USBDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle, SystemTable);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = InitSmmHandler(ImageHandle, SystemTable, InSmmFunction, NULL);
+#else
+ Status = InstallUsbProtocols();
+ InitializeUsbGlobalData();
+#endif
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InitializeUsbGlobalData
+//
+// Description: This function initializes the USB global data.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InitializeUsbGlobalData(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ UINT8 bDriverIndex;
+ UINT8 bDelayedIndex;
+
+ //
+ // Initialize host controller drivers
+ //
+ FillHcdEntries(); // This routine is implemented in $(BUILD_DIR)\dummyusbrt.c
+
+ //
+ // Initialize the device driver pointers
+ //
+ bDriverIndex = 0;
+ bDelayedIndex = 0;
+ //(EIP71750)>
+ while(UsbDevDelayedDrivers[bDelayedIndex]) {
+ UsbDevDelayedDrivers[bDelayedIndex](&gUsbData->aDelayedDrivers[bDelayedIndex]);
+ if (gUsbData->aDelayedDrivers[bDelayedIndex].pfnDeviceInit) {
+ (*gUsbData->aDelayedDrivers[bDelayedIndex].pfnDeviceInit)();
+ }
+ if (gUsbData->aDelayedDrivers[bDelayedIndex].bDevType) {
+ bDelayedIndex++;
+ }
+ }
+
+ while(UsbDevDrivers[bDriverIndex]) {
+ UsbDevDrivers[bDriverIndex](&gUsbData->aDevDriverTable[bDriverIndex]);
+ if (gUsbData->aDevDriverTable[bDriverIndex].pfnDeviceInit) {
+ (*gUsbData->aDevDriverTable[bDriverIndex].pfnDeviceInit)();
+ }
+ if (gUsbData->aDevDriverTable[bDriverIndex].bDevType) {
+ bDriverIndex++;
+ }
+ }
+
+ //
+ // Allocate a block of memory to be used as a temporary
+ // buffer for USB mass transfer
+ //
+ Status = pBS->AllocatePool (EfiRuntimeServicesData, MAX_CONSUME_BUFFER_SIZE,
+ &gUsbData->fpUSBMassConsumeBuffer);
+ ASSERT_EFI_ERROR(Status);
+ pBS->SetMem(gUsbData->fpUSBMassConsumeBuffer, MAX_CONSUME_BUFFER_SIZE, 0);
+
+ //
+ // Allocate a block of memory for the temporary buffer
+ //
+ Status = gBS->AllocatePool (EfiRuntimeServicesData, MAX_TEMP_BUFFER_SIZE,
+ &gUsbData->fpUSBTempBuffer);
+ ASSERT_EFI_ERROR(Status);
+ pBS->SetMem(gUsbData->fpUSBTempBuffer, MAX_TEMP_BUFFER_SIZE, 0);
+
+ //
+ // Allow to enumerate ports
+ //
+ gUsbData->bEnumFlag = FALSE;
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbApiHandler
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbApiHandler(VOID* Param)
+{
+ URP_STRUC *fpURP = (URP_STRUC*)Param;
+ UINT8 bFuncIndex;
+ UINT8 bNumberOfFunctions;
+
+ if (fpURP == NULL) {
+ return;
+ }
+
+ bFuncIndex = fpURP->bFuncNumber;
+ bNumberOfFunctions = sizeof aUsbApiTable / sizeof (API_FUNC *);
+
+ //
+ // Make sure function number is valid; if function number is not zero
+ // check for valid extended USB API function
+ //
+ if (bFuncIndex && ((bFuncIndex < USB_NEW_API_START_FUNC ) ||
+ bFuncIndex > (bNumberOfFunctions + USB_NEW_API_START_FUNC))) {
+ //fpURP->bRetValue = USBAPI_INVALID_FUNCTION;
+ USB_DEBUG(3, "UsbApiHandler Invalid function#%x\n", bFuncIndex);
+ return;
+ }
+
+ if (bFuncIndex) {
+ bFuncIndex = (UINT8)(bFuncIndex - USB_NEW_API_START_FUNC + 1);
+ }
+
+ aUsbApiTable[bFuncIndex](fpURP); // Call the appropriate function
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallUsbProtocols
+//
+// Description: This function initializes the USB global data.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InstallUsbProtocols(
+ VOID
+)
+{
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *UsbProtocol;
+
+ Status = pBS->LocateProtocol(&gEfiUsbProtocolGuid, NULL, &UsbProtocol);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ gUsbData = UsbProtocol->USBDataPtr;
+
+ UsbProtocol->UsbRtKbcAccessControl = UsbKbcAccessControl;
+
+ //Hook USB legacy control function for shutdown/init USB legacy support
+ UsbProtocol->UsbLegacyControl = USBRT_LegacyControl;
+ UsbProtocol->UsbStopUnsupportedHc = USB_StopUnsupportedHc;
+#if !USB_RUNTIME_DRIVER_IN_SMM
+ UsbProtocol->UsbInvokeApi = UsbApiHandler;
+#endif
+
+ return Status;
+}
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InSmmFunction
+//
+// Description: SMM entry point of AMIUSB driver
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+InSmmFunction(
+ EFI_HANDLE ImageHandle,
+ EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_STATUS Status;
+
+ EFI_SMM_SW_DISPATCH_CONTEXT SwSmiContext;
+ EFI_HANDLE SwSmiHandle = NULL;
+ EFI_SMM_SW_DISPATCH_PROTOCOL *SwSmiDispatch;
+
+ UINT32 KbcEmulFeature = 0;
+ VOID *ProtocolNotifyRegistration;
+ EFI_EVENT Emul6064Event = NULL;
+
+ //(EIP54018+)>
+#if USB_S5_WAKEUP_SUPPORT
+ EFI_SMM_SX_DISPATCH_CONTEXT S5DispatchContext;
+ EFI_SMM_SX_DISPATCH_PROTOCOL *SxDispatchProtocol;
+ EFI_SMM_POWER_BUTTON_DISPATCH_CONTEXT PbDispatchContext;
+ EFI_SMM_POWER_BUTTON_DISPATCH_PROTOCOL *PbDispatchProtocol;
+ EFI_HANDLE S5DispatchHandle;
+ EFI_HANDLE PbDispatchHandle;
+#endif
+ //<(EIP54018+)
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ EFI_HANDLE UsbSmmProtocolHandle = NULL;
+
+ Status = InitAmiSmmLib(ImageHandle, SystemTable);
+ if (EFI_ERROR(Status)) return Status;
+#endif
+
+ InitAmiBufferValidationLib(ImageHandle, SystemTable);
+
+ InstallUsbProtocols();
+ InitializeUsbGlobalData();
+
+
+ Status = pBS->LocateProtocol (&gEmul6064TrapProtocolGuid, NULL, &gEmulationTrap);
+ if (EFI_ERROR(Status)) {
+ Status = RegisterProtocolCallback(&gEmul6064TrapProtocolGuid,
+ Emul6064TrapCallback,
+ NULL,
+ &Emul6064Event,
+ &ProtocolNotifyRegistration);
+ }
+
+ if(!gUsbData->kbc_support) {
+ Status = gBS->LocateProtocol (&gEmul6064MsInputProtocolGuid, NULL, &gMsInput);
+ pBS->LocateProtocol (&gEmul6064KbdInputProtocolGuid, NULL, &gKbdInput);
+
+ if (Status == EFI_SUCCESS) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_ON;
+ if(gEmulationTrap)
+ KbcEmulFeature = gEmulationTrap->FeatureSupported(gEmulationTrap);
+ if(KbcEmulFeature & IRQ_SUPPORTED) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_IRQ_SUPPORT;
+ }
+ } else {
+ InitSysKbc( &gKbdInput, &gMsInput );
+ }
+ } else {
+ //
+ //Init Fake Emulation interface
+ //
+ InitSysKbc( &gKbdInput, &gMsInput );
+ }
+
+ Status = USBSB_InstallSmiEventHandlers();
+
+ USB_DEBUG(DEBUG_LEVEL_3,"AMIUSB global data at 0x%x\n", gUsbData);
+
+ //
+ // Register the USB SW SMI handler
+ //
+ Status = pBS->LocateProtocol (&gEfiSmmSwDispatchProtocolGuid, NULL, &SwSmiDispatch);
+
+ if (EFI_ERROR (Status)) {
+ USB_DEBUG(DEBUG_LEVEL_0, "SmmSwDispatch protocol: %r\n", Status);
+ return Status;
+ }
+
+ SwSmiContext.SwSmiInputValue = USB_SWSMI;
+ Status = SwSmiDispatch->Register (SwSmiDispatch, USBSWSMIHandler, &SwSmiContext, &SwSmiHandle);
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AMIUSB SW SMI registration:: %r\n", Status);
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ gUsbSmmProtocol.UsbStopUnsupportedHc = USB_StopUnsupportedHc;
+ gUsbSmmProtocol.UsbApiTable = aUsbApiTable;
+ gUsbSmmProtocol.UsbMassApiTable = aUsbMassApiTable;
+ gUsbSmmProtocol.GlobalDataValidation.ConstantDataCrc32 = 0;
+ gUsbSmmProtocol.GlobalDataValidation.Crc32Hash = (UINT32)GetCpuTimer();
+
+ Status = pSmst->SmmInstallProtocolInterface(
+ &UsbSmmProtocolHandle,
+ &gAmiUsbSmmProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &gUsbSmmProtocol
+ );
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AMIUSB SMM protocol: %r\n", Status);
+#endif
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ InitAmiUsbSmmGlobalDataValidationLib(ImageHandle, SystemTable);
+ UpdateAmiUsbSmmGlobalDataCrc32(gUsbData);
+#endif
+
+ //(EIP54018+)>
+#if USB_S5_WAKEUP_SUPPORT
+ Status = pBS->LocateProtocol(
+ &gEfiSmmSxDispatchProtocolGuid,
+ NULL,
+ &SxDispatchProtocol
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ S5DispatchContext.Type = SxS5;
+ S5DispatchContext.Phase = SxEntry;
+ Status = SxDispatchProtocol->Register(
+ SxDispatchProtocol,
+ UsbS5SmiCallback,
+ &S5DispatchContext,
+ &S5DispatchHandle
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Locate Power Button Dispatch Protocol
+ Status = pBS->LocateProtocol(
+ &gEfiSmmPowerButtonDispatchProtocolGuid,
+ NULL,
+ &PbDispatchProtocol
+ );
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Register the handler for power button presses
+ PbDispatchContext.Phase = PowerButtonEntry;
+ Status = PbDispatchProtocol->Register(
+ PbDispatchProtocol,
+ UsbPowerButtonSmiCallback,
+ &PbDispatchContext,
+ &PbDispatchHandle
+ );
+#endif
+ //<(EIP54018+)
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBSWSMIHandler
+//
+// Description: Invoked on reads from SW SMI port with value USB_SWSMI. This
+// function dispatches the USB Request Packets (URP) to the
+// appropriate functions.
+//
+// Input: EBDA:USB_DATA_EBDA_OFFSET - Pointer to the URP (USB Request
+// Packet structure)
+// DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+//
+// Output: bRetValue Zero on successfull completion
+// Non-zero on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBSWSMIHandler (
+ EFI_HANDLE DispatchHandle,
+ EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+)
+{
+ URP_STRUC *UsbUrp;
+ UINT16 EbdaSeg;
+ EFI_STATUS Status;
+
+ if (gLockSmiHandler == TRUE) {
+ return;
+ }
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ gLockHwSmiHandler = TRUE;
+ gLockSmiHandler = TRUE;
+ return;
+ }
+#endif
+
+ if (gUsbData->fpURP) { // Call from AMIUSB C area
+ Status = AmiValidateMemoryBuffer((VOID*)gUsbData->fpURP, sizeof(URP_STRUC));
+ if (EFI_ERROR(Status)) {
+ USB_DEBUG(3, "UsbApiHandler Invalid Pointer, the address is in SMRAM.\n");
+ return;
+ }
+ UsbUrp = gUsbData->fpURP;
+ gUsbData->fpURP = 0; // Clear the switch
+ } else {
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_OS) {
+ return;
+ }
+ //
+ // Get the fpURP pointer from EBDA
+ //
+ EbdaSeg = *((UINT16*)0x40E);
+ UsbUrp = *(URP_STRUC**)(UINTN)(((UINT32)EbdaSeg << 4) + USB_DATA_EBDA_OFFSET);
+ UsbUrp = (URP_STRUC*)((UINTN)UsbUrp & 0xFFFFFFFF);
+ Status = AmiValidateMemoryBuffer((VOID*)UsbUrp, sizeof(URP_STRUC));
+ if (EFI_ERROR(Status)) {
+ USB_DEBUG(3, "UsbApiHandler Invalid Pointer, the address is in SMRAM.\n");
+ return;
+ }
+ }
+
+ if (UsbUrp == NULL) {
+ return;
+ }
+
+ gCheckUsbApiParameter = TRUE;
+
+ UsbApiHandler(UsbUrp);
+
+ gCheckUsbApiParameter = FALSE;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHwSmiHandler
+//
+// Description: USB Hardware SMI handler.
+//
+// Input: Host controller type.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbHwSmiHandler (UINT8 HcType)
+{
+ UINT8 Index;
+ HC_STRUC *HcStruc;
+ EFI_STATUS Status;
+
+ if (gLockHwSmiHandler == TRUE) {
+ return;
+ }
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ gLockHwSmiHandler = TRUE;
+ gLockSmiHandler = TRUE;
+ return;
+ }
+#endif
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ HcStruc = gUsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if (!(HcStruc->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+ if (HcStruc->bHCType == HcType) { // Process appropriate interrupt
+ (*gUsbData->aHCDriverTable
+ [GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDProcessInterrupt)(HcStruc);
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: xhciHWSMIHandler
+//
+// Description: USB Hardware SMI handler.
+//
+// Input: DispatchHandle - EFI Handle
+// DispatchContext - Pointer to the EFI_SMM_SW_DISPATCH_CONTEXT
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UhciHWSMIHandler (
+ EFI_HANDLE DispatchHandle,
+ EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UsbHwSmiHandler(USB_HC_UHCI);
+}
+VOID
+OhciHWSMIHandler (
+ EFI_HANDLE DispatchHandle,
+ EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UsbHwSmiHandler(USB_HC_OHCI);
+}
+VOID
+EhciHWSMIHandler (
+ EFI_HANDLE DispatchHandle,
+ EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext
+ )
+{
+ UsbHwSmiHandler(USB_HC_EHCI);
+}
+
+VOID
+XhciHwSmiHandler (
+ EFI_HANDLE DispatchHandle,
+ VOID *DispatchContext
+ )
+{
+ UsbHwSmiHandler(USB_HC_XHCI);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBInstallHwSmiHandler
+//
+// Description:
+// This function registers USB hardware SMI callback function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbInstallHwSmiHandler(
+ HC_STRUC *HcStruc
+)
+{
+ EFI_STATUS Status;
+ EFI_SMM_USB_DISPATCH_CONTEXT UsbContext;
+ EFI_SMM_USB_DISPATCH_PROTOCOL *UsbDispatch;
+ EFI_SMM_USB_DISPATCH UsbCallback;
+ EFI_HANDLE Handle = NULL;
+
+ if (HcStruc->HwSmiHandle != NULL) {
+ return EFI_SUCCESS;
+ }
+
+ Status = gBS->LocateProtocol(
+ &gEfiSmmUsbDispatchProtocolGuid,
+ NULL,
+ &UsbDispatch);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ switch (HcStruc->bHCType) {
+ case USB_HC_UHCI:
+ UsbCallback = UhciHWSMIHandler;
+ break;
+
+ case USB_HC_OHCI:
+ UsbCallback = OhciHWSMIHandler;
+ break;
+
+ case USB_HC_EHCI:
+ UsbCallback = EhciHWSMIHandler;
+ break;
+
+ case USB_HC_XHCI:
+ UsbCallback = XhciHwSmiHandler;
+ break;
+
+ default:
+ return EFI_UNSUPPORTED;
+ }
+
+ UsbContext.Type = UsbLegacy;
+ UsbContext.Device = HcStruc->pHCdp;
+
+ Status = UsbDispatch->Register(
+ UsbDispatch,
+ UsbCallback,
+ &UsbContext,
+ &Handle);
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AMIUSB HC type %x HW SMI registation status:: %r\n", HcStruc->bHCType, Status);
+
+ if (!EFI_ERROR(Status)) {
+ HcStruc->HwSmiHandle = Handle;
+ }
+
+ return Status;
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Emul6064TrapCallback
+//
+// Description:
+// Update the KbcEmul feature when the Emul6064Trap Protocol becomes available.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+Emul6064TrapCallback (
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ EFI_STATUS Status;
+ UINT32 KbcEmulFeature = 0;
+
+ Status = gBS->LocateProtocol(
+ &gEmul6064TrapProtocolGuid,
+ NULL,
+ &gEmulationTrap);
+
+ if(!gUsbData->kbc_support) {
+ Status = gBS->LocateProtocol(
+ &gEmul6064MsInputProtocolGuid,
+ NULL,
+ &gMsInput);
+
+ gBS->LocateProtocol(
+ &gEmul6064KbdInputProtocolGuid,
+ NULL,
+ &gKbdInput);
+
+ if (Status == EFI_SUCCESS) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_ON;
+ if(gEmulationTrap)
+ KbcEmulFeature = gEmulationTrap->FeatureSupported(gEmulationTrap);
+ if(KbcEmulFeature & IRQ_SUPPORTED) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_6064EMULATION_IRQ_SUPPORT;
+ }
+ } else {
+ InitSysKbc( &gKbdInput, &gMsInput );
+ }
+ } else {
+ //
+ //Init Fake Emulation interface
+ //
+ InitSysKbc( &gKbdInput, &gMsInput );
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+//
+// USB API Functions
+//
+//////////////////////////////////////////////////////////////////////////////
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_MassDeviceRequest
+//
+// Description: This routine services the USB API function number 27h. It
+// handles all the mass storage related calls from the higher
+// layer. Different sub-functions are invoked depending on
+// the sub-function number
+//
+// Input: fpURPPointer Pointer to the URP structure
+// fpURPPointer.bSubFunc Subfunction number
+// 00 Get Device Information
+// 01 Get Device Parameter
+// 02 Reset Device
+// 03 Read Device
+// 04 Write Device
+// 05 Verify Device
+// 06 Format Device
+// 07 Request Sense
+// 08 Test Unit Ready
+// 09 Start Stop Unit
+// 0A Read Capacity
+// 0B Mode Sense
+// 0C Device Inquiry
+// 0D Send Command
+// 0E Assign drive number
+//
+// Output: URP structure is updated with the relevant information
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_MassDeviceRequest (URP_STRUC *fpURP)
+{
+ UINT8 bMassFuncIndex = fpURP->bSubFunc;
+ UINT8 bNumberOfMassFunctions = sizeof aUsbMassApiTable / sizeof (API_FUNC *);
+
+ //
+ // Make sure function number is valid
+ //
+ if (bMassFuncIndex >= bNumberOfMassFunctions) {
+ //fpURP->bRetValue = USBAPI_INVALID_FUNCTION;
+ USB_DEBUG(3, "UsbApi MassDeviceRequet Invalid function#%x\n", bMassFuncIndex);
+ return;
+ }
+ gUsbData->bUSBKBC_MassStorage = 01;
+ //
+ // Function number is valid - call it
+ //
+ aUsbMassApiTable[bMassFuncIndex](fpURP);
+ gUsbData->bUSBKBC_MassStorage = 00;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_CheckPresence
+//
+// Description: This routine services the USB API function number 0. It
+// reports the USB BIOS presence, its version number and
+// its current status information
+//
+// Input: fpURPPointer - Pointer to the URP structure
+//
+// Output: URP structure is updated with the following information
+// CkPresence.wBiosRev USB BIOS revision (0210h means r2.10)
+// CkPresence.bBiosActive 0 - if USB BIOS is not running
+// CkPresence.bNumBootDev Number of USB boot devices found
+// CkPresence.bNumHC Number of host controller present
+// CkPresence.bNumPorts Number of root hub ports
+// CkPresence.dUsbDataArea Current USB data area
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_CheckPresence (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_SUCCESS;
+ fpURP->ApiData.CkPresence.bBiosActive = 0;
+
+ fpURP->ApiData.CkPresence.bNumBootDev = 0; // Number of USB boot devices found
+ fpURP->ApiData.CkPresence.bNumKeyboards = 0; // Number of USB keyboards present
+ fpURP->ApiData.CkPresence.bNumMice = 0; // Number of USB mice present
+ fpURP->ApiData.CkPresence.bNumPoint = 0; // Number of USB Point present //(EIP38434+)
+ fpURP->ApiData.CkPresence.bNumHubs = 0; // Number of USB hubs present
+ fpURP->ApiData.CkPresence.bNumStorage = 0; // Number of USB storage devices present
+
+ fpURP->ApiData.CkPresence.wBiosRev = (USB_DRIVER_MAJOR_VER << 4) + USB_DRIVER_MINOR_VER;
+ fpURP->ApiData.CkPresence.bBiosActive = USB_ACTIVE; // Set USB BIOS as active
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_DISABLE_LEGACY_SUPPORT)) {
+ fpURP->ApiData.CkPresence.bBiosActive |= USB_LEGACY_ENABLE;
+ }
+ if (gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_ON) {
+ fpURP->ApiData.CkPresence.bBiosActive |= USB_6064_ENABLE;
+ }
+ USBWrap_GetDeviceCount(fpURP); // Get active USB devices
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_Start
+//
+// Description: This API routine configures the USB host controllers and
+// enumerate the devices
+//
+// Input: fpURPPointer URP structure with input parameters
+// StartHc.wDataAreaFlag Indicates which data area to use
+//
+// Output: StartHc.wDataAreaFlag Returns current data area pointer
+// bRetValue - USB_SUCCESS on success, USB_ERROR on error.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_Start (URP_STRUC *fpURP)
+{
+ USB_DEBUG(DEBUG_LEVEL_3, "USBSMI: Start\n");
+ USB_DEBUG(DEBUG_LEVEL_3, "\tUSBAPI_HC_Proc:%x\n", &USBAPI_HC_Proc);
+ USB_DEBUG(DEBUG_LEVEL_3, "\tUSBAPI_Core_Proc:%x\n", &USBAPI_Core_Proc);
+ USB_DEBUG(DEBUG_LEVEL_3, "\tUSB_ReConfigDevice:%x\n", &USB_ReConfigDevice);
+ fpURP->bRetValue = USB_StartHostControllers (gUsbData);
+ USB_DEBUG(DEBUG_LEVEL_3, "USB_StartHostControllers returns %d\n", fpURP->bRetValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_Stop
+//
+// Description: This routine stops the USB host controllers
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: bRetValue USB_SUCCESS on success
+// USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_Stop (URP_STRUC *fpURP)
+{
+ gCheckUsbApiParameter = FALSE;
+ fpURP->bRetValue = USB_StopHostControllers (gUsbData);
+ USB_DEBUG(DEBUG_LEVEL_3, "USB_StopHostControllers returns %d\n", fpURP->bRetValue);
+ gUsbData->dUSBStateFlag &= ~(USB_FLAG_DRIVER_STARTED);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_PowerManageUSB
+//
+// Description: This routine suspends the USB host controllers
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_PowerManageUSB (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_PrepareForOS
+//
+// Description: This routine updates data structures to reflect that
+// POST is completed
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_PrepareForOS (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_SecureInterface
+//
+// Description: This routine handles the calls related to security device
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_SecureInterface (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_DisableInterrupts
+//
+// Description: This routine stops the USB host controllers interrupts
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: bRetValue USB_SUCCESS on success
+// USB_ERROR on error (Like data area not found)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_DisableInterrupts (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_EnableInterrupts
+//
+// Description: This routine re-enable the USB host controller interrupts
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: bRetValue USB_SUCCESS on success
+// USB_ERROR on error (Like data area not found)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_EnableInterrupts (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_MoveDataArea
+//
+// Description: This routine stops the USB host controllers and moves
+// the data area used by host controllers to a new area.
+// The host controller is started from the new place.
+//
+// Input: fpURPPointer URP structure with input parameters
+// StartHc.wDataAreaFlag Indicates which data area to use
+//
+// Output: bRetValue USB_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_MoveDataArea(URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_GetDeviceInfo
+//
+// Description: This routine returns the information regarding
+// a USB device like keyboard, mouse, floppy drive etc
+//
+// Input: fpURPPointer URP structure with input parameters
+// GetDevInfo.bDevNumber Device number (1-based) whose
+// information is requested
+//
+// Output: URP structure is updated with the following information
+// GetDevInfo.bHCNumber - HC number in which the device is found
+// GetDevInfo.bDevType - Type of the device
+// bRetValue will be one of the following value
+// USB_SUCCESS on successfull completion
+// USB_PARAMETER_ERROR if bDevNumber is invalid
+// USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID USBAPI_GetDeviceInfo (URP_STRUC *fpURP)
+{
+ DEV_INFO* fpDevInfo;
+
+ //
+ // Initialize the return values
+ //
+ fpURP->ApiData.GetDevInfo.bHCNumber = 0;
+ fpURP->ApiData.GetDevInfo.bDevType = 0;
+ fpURP->bRetValue = USB_ERROR;
+
+ //
+ // Check for parameter validity
+ //
+ if ( !fpURP->ApiData.GetDevInfo.bDevNumber ) return;
+
+ fpURP->bRetValue = USB_PARAMETER_ERROR;
+
+ //
+ // Get the device information structure for the 'n'th device
+ //
+ fpDevInfo = USBWrap_GetnthDeviceInfoStructure(fpURP->ApiData.GetDevInfo.bDevNumber);
+// if (!wRetCode) return; // USB_PARAMETER_ERROR
+
+ //
+ // Return value
+ //
+ fpURP->ApiData.GetDevInfo.bDevType = fpDevInfo->bDeviceType;
+ fpURP->ApiData.GetDevInfo.bHCNumber = fpDevInfo->bHCNumber;
+ fpURP->bRetValue = USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_CheckDevicePresence
+//
+// Description: This routine checks whether a particular type of USB device
+// is installed in the system or not.
+//
+// Input: fpURPPointer URP structure with input parameters
+// ChkDevPrsnc.bDevType Device type to find
+// ChkDevPrsnc.fpHCStruc Pointer to HC being checked for device
+// connection; if NULL then the total number of devices
+// connected to ANY controller is returned.
+// ChkDevPrsnc.bNumber Number of devices connected
+//
+// Output: bRetValue will be one of the following value
+// USB_SUCCESS if device type present, ChkDevPrsnc.bNumber <> 0
+// USB_ERROR if device type absent, ChkDevPrsnc.bNumber returns 0
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_CheckDevicePresence (URP_STRUC *fpURP)
+{
+ UINT8 bSearchFlag;
+ UINTN dData;
+
+ bSearchFlag = USB_SRCH_DEV_NUM;
+ if (fpURP->bSubFunc == 1)
+ {
+ bSearchFlag = USB_SRCH_DEVBASECLASS_NUM;
+ }
+ //
+ // The total number of devices connected to ANY controller has been requested
+ //
+ dData = (UINTN) USB_GetDeviceInfoStruc( bSearchFlag,
+ 0, fpURP->ApiData.ChkDevPrsnc.bDevType, fpURP->ApiData.ChkDevPrsnc.fpHCStruc);
+
+ fpURP->ApiData.ChkDevPrsnc.bNumber = (UINT8)dData;
+ fpURP->bRetValue = (UINT8)((fpURP->ApiData.ChkDevPrsnc.bNumber)?
+ USB_SUCCESS : USB_ERROR);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIGetDeviceInformation
+//
+// Description: This function is part of the USB BIOS MASS API. This function
+// returns the device information of the mass storage device
+//
+// Input: fpURPPointer Pointer to the URP structure
+// bDevAddr USB device address of the device
+//
+// Output: bRetValue Return value
+// fpURPPointer Pointer to the URP structure
+// dSenseData Sense data of the last command
+// bDevType Device type byte (HDD, CD, Removable)
+// bEmuType Emulation type used
+// fpDevId Far pointer to the device ID
+// dInt13Entry INT 13h entry point
+//
+// Notes: Initially the bDevAddr should be set to 0 as input. This
+// function returns the information regarding the first mass
+// storage device (if no device found it returns bDevAddr as
+// 0FFh) and also updates bDevAddr to the device address of
+// the current mass storage device. If no other mass storage
+// device is found then the routine sets the bit7 to 1
+// indicating current information is valid but no more mass
+// device found in the system. The caller can get the next
+// device info if bDevAddr is not 0FFh and bit7 is not set
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIGetDeviceInformation (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USBMassGetDeviceInfo (&fpURP->ApiData.MassGetDevInfo);
+}
+
+VOID
+USBMassAPIGetDeviceParameters (URP_STRUC *fpURP)
+{
+ DEV_INFO *DevInfo;
+ EFI_STATUS Status;
+
+ DevInfo = fpURP->ApiData.MassGetDevParms.fpDevInfo;
+
+ Status = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ Status = AmiValidateMemoryBuffer((VOID*)fpURP->ApiData.MassGetDevParms.fpInqData, sizeof(MASS_INQUIRY));
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ fpURP->ApiData.MassGetDevParms.fpInqData = USBMassGetDeviceParameters(DevInfo);
+ fpURP->bRetValue = (fpURP->ApiData.MassGetDevParms.fpInqData == NULL)? USB_ERROR : USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBMassAPIGetDevStatus
+//
+// Description: This function returns the drive status and media presence
+// status
+//
+// Input: fpURPPointer Pointer to the URP structure
+// fpURP->ApiData.fpDevInfo - pointer to USB device that is
+// requested to be checked
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIGetDevStatus(URP_STRUC *fpURP)
+{
+#if USB_DEV_MASS
+ fpURP->bRetValue = USBMassGetDeviceStatus (&fpURP->ApiData.MassGetDevSts);
+// USB_DEBUG(DEBUG_LEVEL_3, "USBMassAPIGetDevStatus ... check function call correct?\n");
+#endif
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIGetDeviceGeometry
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input: fpURPPointer Pointer to the URP structure
+// bDevAddr USB device address of the device
+//
+// Output: bRetValue Return value
+// fpURPPointer Pointer to the URP structure
+// dSenseData Sense data of the last command
+// bNumHeads Number of heads
+// wNumCylinders Number of cylinders
+// bNumSectors Number of sectors
+// wBytesPerSector Number of bytes per sector
+// bMediaType Media type
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIGetDeviceGeometry(URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USBMassGetDeviceGeometry (&fpURP->ApiData.MassGetDevGeo);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIResetDevice
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: bRetValue Return value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIResetDevice (URP_STRUC *fpURP)
+{
+ UINT8 bDevAddr;
+ DEV_INFO *fpDevInfo;
+ UINT16 wResult;
+
+ bDevAddr = fpURP->ApiData.MassReset.bDevAddr;
+
+ //
+ // Get the device info structure for the matching device address
+ //
+ fpDevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, bDevAddr, 0);
+ if((fpDevInfo == NULL)|| (!(fpDevInfo->Flag & DEV_INFO_DEV_PRESENT))) {
+ fpURP->bRetValue = USB_ATA_TIME_OUT_ERR;
+ return;
+ }
+ //
+ // Send Start/Stop Unit command to UFI class device only
+ //
+ fpURP->bRetValue = USB_SUCCESS;
+ if(fpDevInfo->bSubClass == SUB_CLASS_UFI) {
+ wResult = USBMassStartUnitCommand (fpDevInfo);
+ if (wResult) {
+ fpURP->bRetValue = USBWrapGetATAErrorCode(fpURP->ApiData.MassReset.dSenseData);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIReadDevice
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input: fpURPPointer Pointer to the URP structure, it contains the following:
+// bDevAddr USB device address of the device
+// dStartLBA Starting LBA address
+// wNumBlks Number of blocks to read
+// wPreSkipSize Number of bytes to skip before
+// wPostSkipSize Number of bytes to skip after
+// fpBufferPtr Far buffer pointer
+//
+// Output: fpURPPointer Pointer to the URP structure
+// bRetValue Return value
+// dSenseData Sense data of the last command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIReadDevice (
+ URP_STRUC *Urp
+)
+{
+ DEV_INFO *DevInfo;
+ UINT8 DevAddr;
+ UINT16 Result;
+ UINT32 Data = 0;
+ UINT8 OpCode;
+
+ DevAddr = Urp->ApiData.MassRead.DevAddr;
+
+ if (((DevAddr == USB_HOTPLUG_FDD_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED) == FALSE)) ||
+ ((DevAddr == USB_HOTPLUG_HDD_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED) == FALSE)) ||
+ ((DevAddr == USB_HOTPLUG_CDROM_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED) == FALSE))) {
+ Urp->bRetValue = USB_ATA_DRIVE_NOT_READY_ERR;
+ return;
+ }
+
+ //
+ // Get the device info structure for the matching device address
+ //
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+ if ((DevInfo == NULL)|| (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) {
+ Urp->bRetValue = USB_ATA_TIME_OUT_ERR;
+ return;
+ }
+
+ //(EIP15037+)>
+#if EXTRA_CHECK_DEVICE_READY
+ //
+ // Check device ready
+ //
+ Data = USBMassCheckDeviceReady(DevInfo);
+ if (Data) {
+ Urp->ApiData.MassRead.dSenseData = Data;
+ Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassRead.dSenseData); //(EIP31535)
+ return;
+ }
+#endif
+ //<(EIP15037+)
+
+ //
+ // Issue read command
+ //
+ if (Shr64(DevInfo->MaxLba, 32)) {
+ OpCode = COMMON_READ_16_OPCODE;
+ } else {
+ OpCode = COMMON_READ_10_OPCODE;
+ }
+ Result = USBMassRWVCommand(DevInfo, OpCode, &Urp->ApiData.MassRead);
+ //USB_DEBUG(DEBUG_LEVEL_3, " wr(%x):%x %x", DevAddr, Result, Urp->ApiData.MassRead.dSenseData);
+ if (Result) {
+ Urp->bRetValue = USB_SUCCESS;
+ return;
+ }
+ Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassRead.SenseData);
+ //USB_DEBUG(DEBUG_LEVEL_3, " er(%x):%x", DevAddr, Urp->bRetValue);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIWriteDevice
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input: fpURPPointer Pointer to the URP structure
+// bDevAddr USB device address of the device
+// dStartLBA Starting LBA address
+// wNumBlks Number of blocks to write
+// wPreSkipSize Number of bytes to skip before
+// wPostSkipSize Number of bytes to skip after
+// fpBufferPtr Far buffer pointer
+//
+// Output: fpURPPointer Pointer to the URP structure
+// bRetValue Return value
+// dSenseData Sense data of the last command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIWriteDevice(
+ URP_STRUC *Urp
+)
+{
+ DEV_INFO *DevInfo;
+ UINT8 DevAddr;
+ UINT16 Result;
+ UINT32 Data = 0;
+ UINT8 OpCode;
+
+ DevAddr = Urp->ApiData.MassWrite.DevAddr;
+
+ if (((DevAddr == USB_HOTPLUG_FDD_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED) == FALSE)) ||
+ ((DevAddr == USB_HOTPLUG_HDD_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED) == FALSE)) ||
+ ((DevAddr == USB_HOTPLUG_CDROM_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED) == FALSE))) {
+ Urp->bRetValue = USB_ATA_DRIVE_NOT_READY_ERR;
+ return;
+ }
+
+ //
+ // Get the device info structure for the matching device address
+ //
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+ if((DevInfo == NULL)|| (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) {
+ Urp->bRetValue = USB_ATA_TIME_OUT_ERR;
+ return;
+ }
+/*
+ if (!(DevInfo->bLastStatus & USB_MASS_MEDIA_PRESENT)) {
+ Urp->bRetValue = USB_ATA_NO_MEDIA_ERR;
+ return;
+ }
+*/
+ //(EIP15037+)>
+#if EXTRA_CHECK_DEVICE_READY
+ //
+ // Check device ready
+ //
+ Data = USBMassCheckDeviceReady(DevInfo);
+ if (Data) {
+ Urp->ApiData.MassRead.dSenseData = Data;
+ Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassWrite.dSenseData); //(EIP31535)
+ return;
+ }
+#endif
+ //<(EIP15037+)
+
+ //
+ // Issue write command
+ //
+ if (Shr64(DevInfo->MaxLba, 32)) {
+ OpCode = COMMON_WRITE_16_OPCODE;
+ } else {
+ OpCode = COMMON_WRITE_10_OPCODE;
+ }
+ Result = USBMassRWVCommand(DevInfo, OpCode, &Urp->ApiData.MassWrite);
+ if (Result) {
+ Urp->bRetValue = USB_SUCCESS;
+ return;
+ }
+
+ Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassWrite.SenseData);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIVerifyDevice
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input: fpURPPointer Pointer to the URP structure
+// bDevAddr USB device address of the device
+// dStartLBA Starting LBA address
+// wNumBlks Number of blocks to write
+// wPreSkipSize Number of bytes to skip before
+// wPostSkipSize Number of bytes to skip after
+// fpBufferPtr Far buffer pointer
+//
+// Output: fpURPPointer Pointer to the URP structure
+// bRetValue Return value
+// dSenseData Sense data of the last command
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIVerifyDevice(
+ URP_STRUC *Urp
+)
+{
+ DEV_INFO *DevInfo;
+ UINT8 DevAddr;
+ UINT16 Result;
+ UINT32 Data = 0;
+ UINT8 OpCode;
+
+ DevAddr = Urp->ApiData.MassVerify.DevAddr;
+
+ if (((DevAddr == USB_HOTPLUG_FDD_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED) == FALSE)) ||
+ ((DevAddr == USB_HOTPLUG_HDD_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED) == FALSE)) ||
+ ((DevAddr == USB_HOTPLUG_CDROM_ADDRESS) &&
+ ((gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED) == FALSE))) {
+ Urp->bRetValue = USB_ATA_DRIVE_NOT_READY_ERR;
+ return;
+ }
+
+ //
+ // Get the device info structure for the matching device address
+ //
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+ if ((DevInfo == NULL)|| (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) {
+ Urp->bRetValue = USB_ATA_TIME_OUT_ERR;
+ return;
+ }
+ //(EIP15037+)>
+#if EXTRA_CHECK_DEVICE_READY
+ //
+ // Check device ready
+ //
+ Data = USBMassCheckDeviceReady(DevInfo);
+ if (Data) {
+ Urp->ApiData.MassRead.dSenseData = Data;
+ Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassVerify.dSenseData); //(EIP31535)
+ return;
+ }
+#endif
+ //<(EIP15037+)
+
+ //
+ // Issue write command
+ //
+ if (Shr64(DevInfo->MaxLba, 32)) {
+ OpCode = COMMON_VERIFY_16_OPCODE;
+ } else {
+ OpCode = COMMON_VERIFY_10_OPCODE;
+ }
+ Result = USBMassRWVCommand(DevInfo, OpCode, &Urp->ApiData.MassVerify);
+ if (Result) {
+ Urp->bRetValue = USB_SUCCESS;
+ return;
+ }
+
+ Urp->bRetValue = USBWrapGetATAErrorCode(Urp->ApiData.MassVerify.SenseData);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPIFormatDevice
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: bRetValue Return value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIFormatDevice(URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassAPICommandPassThru
+//
+// Description: This function is part of the USB BIOS MASS API. This
+// function can be used to pass raw command/data sequence to
+// the USB mass storage device
+//
+// Input: fpURPPointer Pointer to the URP structure
+//
+// Output: bRetValue Return value
+//
+// Modified: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPICommandPassThru (URP_STRUC *fpURP)
+{
+ UINT8 Result;
+ MASS_CMD_PASS_THRU *MassCmdPassThru;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ MassCmdPassThru = &fpURP->ApiData.MassCmdPassThru;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ Status = AmiValidateMemoryBuffer((VOID*)MassCmdPassThru->fpCmdBuffer, MassCmdPassThru->wCmdLength);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ Status = AmiValidateMemoryBuffer((VOID*)MassCmdPassThru->fpDataBuffer, MassCmdPassThru->wDataLength);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ Result = USBMassCmdPassThru(MassCmdPassThru);
+
+ fpURP->bRetValue = Result;
+}
+
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBMassAPIAssignDriveNumber
+//
+// Description: This function is part of the USB BIOS MASS API. This function
+// assigns the logical drive device according to the information of the
+// mass storage device
+//
+// Input: fpURPPointer Pointer to the URP structure
+// bDevAddr USB device address of the device
+// bLogDevNum Logical Drive Number to assign to the device
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPIAssignDriveNumber (URP_STRUC *fpURP)
+{
+ fpURP->bRetValue = USB_SUCCESS; // No errors expected after this point
+}
+
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBMassAPICheckDevStatus
+//
+// Description: This function is part of the USB BIOS MASS API. This function
+// invokes USB Mass Storage API handler to check whether device
+// is ready. If called for the first time, this function retrieves
+// the mass storage device geometry and fills the corresponding
+// fpDevInfo fields.
+//
+// Input: fpURPPointer Pointer to the URP structure
+// fpURP->ApiData.fpDevInfo - pointer to USB device that is
+// requested to be checked
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USBMassAPICheckDevStatus(URP_STRUC *fpURP)
+{
+#if USB_DEV_MASS
+ UINT32 Result;
+ DEV_INFO *DevInfo;
+ EFI_STATUS Status;
+
+ DevInfo = fpURP->ApiData.MassChkDevReady.fpDevInfo;
+
+ Status = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ gCheckUsbApiParameter = FALSE;
+
+ Result = USBMassCheckDeviceReady(fpURP->ApiData.MassChkDevReady.fpDevInfo);
+ fpURP->bRetValue = (UINT8)Result;
+#endif
+}
+
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_LightenKeyboardLEDs
+//
+// Description: This function is part of the USB BIOS API. This function
+// controls LED state on the connected USB keyboards
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_LightenKeyboardLEDs(URP_STRUC *fpURP)
+{
+#if USB_DEV_KBD
+
+ gCheckUsbApiParameter = FALSE;
+
+ if(fpURP->ApiData.KbLedsData.fpLedMap) {
+ gUsbData->bUSBKBShiftKeyStatus = 0;
+ if(((LED_MAP*)fpURP->ApiData.KbLedsData.fpLedMap)->NumLock) {
+ gUsbData->bUSBKBShiftKeyStatus |= KB_NUM_LOCK_BIT_MASK;
+ }
+ if(((LED_MAP*)fpURP->ApiData.KbLedsData.fpLedMap)->CapsLock) {
+ gUsbData->bUSBKBShiftKeyStatus |= KB_CAPS_LOCK_BIT_MASK;
+ }
+ if(((LED_MAP*)fpURP->ApiData.KbLedsData.fpLedMap)->ScrLock) {
+ gUsbData->bUSBKBShiftKeyStatus |= KB_SCROLL_LOCK_BIT_MASK;
+ }
+ }
+ //USB_DEBUG(DEBUG_LEVEL_3," LEDs: %d\n", gUsbData->bUSBKBShiftKeyStatus);
+ USBKB_LEDOn();
+
+ fpURP->bRetValue = USB_SUCCESS;
+ return;
+#else
+ fpURP->bRetValue = USB_NOT_SUPPORTED;
+#endif
+
+}
+
+VOID
+USBAPI_LightenKeyboardLEDs_Compatible(URP_STRUC *fpURP)
+{
+ USBAPI_LightenKeyboardLEDs(fpURP);
+}
+
+ //(EIP29733+)>
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_KbcAccessControl
+//
+// Description: This function is part of the USB BIOS API. This function
+// is used to control whether KBC access in USB module
+// should be blocked or not.
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+
+VOID
+UsbKbcAccessControl(
+ UINT8 ControlSwitch
+)
+{
+ UINT8 Index;
+ HC_STRUC *HcStruc;
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ gLockHwSmiHandler = TRUE;
+ gLockSmiHandler = TRUE;
+ return;
+ }
+#endif
+
+ gCheckUsbApiParameter = FALSE;
+
+ IsKbcAccessBlocked = (ControlSwitch != 0)? TRUE : FALSE;
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ HcStruc = gUsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if (HcStruc->dHCFlag & HC_STATE_RUNNING) {
+ break;
+ }
+ }
+
+ if (Index == gUsbData->HcTableCount) {
+ return;
+ }
+/*
+ //
+ // Check if the USB access in Legacy mode. If it's legacy mode enable/disable
+ // the Kbcemulation based on the ControlSwitch
+ //
+ if(!(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)) {
+
+ if(IsKbcAccessBlocked) {
+ if(gEmulationTrap) {
+ //
+ // Keyboard access blocked. Disable the Emulation
+ //
+ gEmulationTrap->TrapDisable(gEmulationTrap);
+ }
+ } else {
+ if(gEmulationTrap) {
+ //
+ // Keyboard access enabled. Enable the KbcEmulation
+ //
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ }
+ }
+ }
+*/
+ //(EIP48323+)>
+ //Reflush USB data buffer if intend to disable usb keyboard data throughput.
+ if (IsKbcAccessBlocked) {
+ USBKeyRepeat(NULL, 1); // Disable Key repeat
+ gUsbData->RepeatKey = 0;
+
+ // Clear Legacy USB keyboard buffer
+ MemFill(gUsbData->aKBCCharacterBufferStart, sizeof(gUsbData->aKBCCharacterBufferStart), 0);
+ gUsbData->fpKBCCharacterBufferHead = gUsbData->aKBCCharacterBufferStart;
+ gUsbData->fpKBCCharacterBufferTail = gUsbData->aKBCCharacterBufferStart;
+
+ MemFill(gUsbData->aKBCScanCodeBufferStart, sizeof(gUsbData->aKBCScanCodeBufferStart), 0);
+ gUsbData->fpKBCScanCodeBufferPtr = gUsbData->aKBCScanCodeBufferStart;
+
+ MemFill(gUsbData->aKBCDeviceIDBufferStart, sizeof(gUsbData->aKBCDeviceIDBufferStart), 0);
+ MemFill(gUsbData->aKBCShiftKeyStatusBufferStart, sizeof(gUsbData->aKBCShiftKeyStatusBufferStart), 0);
+
+ MemFill(gUsbData->aKBInputBuffer, sizeof(gUsbData->aKBInputBuffer), 0);
+ }
+ //<(EIP48323+)
+}
+
+
+VOID
+USBAPI_KbcAccessControl(URP_STRUC *fpURP)
+{
+ UsbKbcAccessControl(fpURP->ApiData.KbcControlCode);
+}
+ //<(EIP29733+)
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USB_StopLegacy
+//
+// Description: This function is part of the USB BIOS API. This function init USB
+// legacy support.
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: None
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+VOID
+USB_StopLegacy(URP_STRUC *fpURP)
+{
+ //shutdown device first
+ UINT8 bIndex;
+ DEV_INFO *fpDevInfo;
+ HC_STRUC *fpHCStruc;
+
+ for (bIndex = 1; bIndex < MAX_DEVICES; bIndex ++){
+ fpDevInfo = gUsbData->aDevInfoTable +bIndex;
+ if ((fpDevInfo->Flag &
+ (DEV_INFO_VALID_STRUC |DEV_INFO_DEV_PRESENT) ) ==
+ (DEV_INFO_VALID_STRUC |DEV_INFO_DEV_PRESENT) ){
+ //
+ fpHCStruc = gUsbData->HcTable[fpDevInfo->bHCNumber - 1];
+ //
+ USB_StopDevice (fpHCStruc, fpDevInfo->bHubDeviceNumber, fpDevInfo->bHubPortNumber);
+ }
+ }
+
+ StopControllerType(USB_HC_XHCI); //(EIP57521+)
+ StopControllerType(USB_HC_EHCI);
+ StopControllerType(USB_HC_UHCI);
+ StopControllerType(USB_HC_OHCI);
+
+ //return as success
+ fpURP->bRetValue = USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USB_StartLegacy
+//
+// Description: This function is part of the USB BIOS API. This function init USB
+// legacy support.
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: None
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+VOID
+USB_StartLegacy(URP_STRUC *fpURP)
+{
+ //(EIP57521)>
+ gUsbData->bHandOverInProgress = FALSE;
+ //Start XHCI
+ StartControllerType(USB_HC_XHCI);
+ USB_EnumerateRootHubPorts(USB_HC_XHCI);
+ //Start EHCI
+ StartControllerType(USB_HC_EHCI);
+ USB_EnumerateRootHubPorts(USB_HC_EHCI);
+ //Start UHCI
+ StartControllerType(USB_HC_UHCI);
+ USB_EnumerateRootHubPorts(USB_HC_UHCI);
+ //Start OHCI
+ StartControllerType(USB_HC_OHCI);
+ USB_EnumerateRootHubPorts(USB_HC_OHCI);
+ //<(EIP57521)
+ //return as success
+ fpURP->bRetValue = USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_LegacyControl
+//
+// Description: This function is part of the USB BIOS API. This function
+// is used to shutdown/init USB legacy support.
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: None
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+VOID USBAPI_LegacyControl (URP_STRUC *fpURP)
+{
+ UINT8 bSubLegacyFunc = fpURP->bSubFunc,i; //(EIP102150+)
+ UINT8 Count = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart); //(EIP102150+)
+
+ gCheckUsbApiParameter = FALSE;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USBAPI_LegacyControl %d\n", fpURP->bSubFunc);
+ if(bSubLegacyFunc==STOP_USB_CONTROLLER){ //(EIP43475+)>
+ USB_StopLegacy (fpURP);
+ //(EIP102150+)>
+ for(i = Count; i > 0; i--)
+ USBKB_DiscardCharacter(&gUsbData->aKBCShiftKeyStatusBufferStart[i-1]);
+ //<(EIP102150+)
+ if(gEmulationTrap)
+ gEmulationTrap->TrapDisable(gEmulationTrap);
+ }
+
+ if(bSubLegacyFunc==START_USB_CONTROLLER){
+ USB_StartLegacy (fpURP);
+ if(gEmulationTrap)
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ } //<(EIP43475+)
+ USB_DEBUG(DEBUG_LEVEL_3, "Result %d\n", fpURP->bRetValue);
+}
+ //(EIP74876+)>
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_UsbStopController
+//
+// Description: This function is part of the USB BIOS API. This function stops
+// the USB host controller.
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: None
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+VOID USBAPI_UsbStopController (URP_STRUC *fpURP)
+{
+ gCheckUsbApiParameter = FALSE;
+ StopControllerBdf(fpURP->ApiData.HcBusDevFuncNum);
+}
+ //<(EIP74876+)
+//-----------------------------------------------------
+//
+//-----------------------------------------------------
+EFI_STATUS USBRT_LegacyControl (VOID *fpURP)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ gLockHwSmiHandler = TRUE;
+ gLockSmiHandler = TRUE;
+ return EFI_SUCCESS;
+ }
+#endif
+ //
+ USBAPI_LegacyControl ((URP_STRUC *)fpURP);
+ //
+ return((EFI_STATUS)(((URP_STRUC *)fpURP)->bRetValue));
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_GetDeviceAddress
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_GetDeviceAddress(
+ URP_STRUC *Urp
+)
+{
+ UINT8 i;
+ DEV_INFO *DevInfo = NULL;
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+ if (!(gUsbData->aDevInfoTable[i].Flag & DEV_INFO_VALID_STRUC)) {
+ continue;
+ }
+ if ((gUsbData->aDevInfoTable[i].wVendorId == Urp->ApiData.GetDevAddr.Vid) &&
+ (gUsbData->aDevInfoTable[i].wDeviceId == Urp->ApiData.GetDevAddr.Did)) {
+ DevInfo = &gUsbData->aDevInfoTable[i];
+ }
+ }
+ if (DevInfo == NULL) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ Urp->ApiData.GetDevAddr.DevAddr = DevInfo->bDeviceAddress;
+ Urp->bRetValue = USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_ExtDriverRequest
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_ExtDriverRequest (
+ URP_STRUC *Urp
+)
+{
+ DEV_INFO *DevInfo = NULL;
+ DEV_DRIVER *DevDriver;
+
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR, 0, Urp->ApiData.DevAddr, 0);
+ if (DevInfo == NULL) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ DevDriver = UsbFindDeviceDriverEntry(DevInfo->fpDeviceDriver);
+
+ if (DevDriver != NULL) {
+ DevDriver->pfnDriverRequest(DevInfo, Urp);
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USB_StopUnsupportedHc
+//
+// Description: This routine is called, from host controllers that supports
+// OS handover functionality, when OS wants the BIOS to hand-over
+// the host controllers to the OS. This routine will stop HC that
+// does not support this functionality.
+//
+// Input: None
+//
+// Output: None
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USB_StopUnsupportedHc()
+{
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ UINT8 Index;
+ HC_STRUC* HcStruc;
+ EFI_STATUS Status;
+
+ Status = AmiUsbSmmGlobalDataValidation(gUsbData);
+
+ ASSERT_EFI_ERROR(Status);
+
+ if (EFI_ERROR(Status)) {
+ gLockHwSmiHandler = TRUE;
+ gLockSmiHandler = TRUE;
+ return;
+ }
+
+ USBSB_UninstallTimerHandlers();
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Stopping all external HCs");
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ HcStruc = gUsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if (HcStruc->HwSmiHandle != NULL) {
+ continue;
+ }
+ if (HcStruc->dHCFlag & HC_STATE_RUNNING) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDStop)(HcStruc);
+ USB_DEBUG(DEBUG_LEVEL_3, ".");
+ }
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "\n");
+
+#endif
+
+ if(gUsbData->UsbXhciHandoff) {
+ StopControllerType(USB_HC_XHCI);
+ }
+ if(gUsbData->UsbEhciHandoff) {
+ gUsbData->bHandOverInProgress = TRUE;
+ StopControllerType(USB_HC_EHCI);
+ }
+ if(gUsbData->UsbOhciHandoff) {
+ StopControllerType(USB_HC_OHCI);
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_ChangeOwner
+//
+// Description: This function is part of the USB BIOS API. This function
+// updates the global variables according to the new owner
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+// Notes: It is a caller responsibility to release the keyboard only if it
+// was previously acquired.
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_ChangeOwner(URP_STRUC *fpURP)
+{
+//USB_DEBUG(DEBUG_LEVEL_3, "USBAPI_ChangeOwner..");
+
+ if(fpURP->ApiData.Owner) { // Changing to Efi driver
+//USB_DEBUG(DEBUG_LEVEL_3, "fpURP->ApiData.Owner=%d\n", fpURP->ApiData.Owner);
+ if(gEmulationTrap) {
+ gEmulationTrap->TrapDisable(gEmulationTrap);
+ }
+ gUsbData->dUSBStateFlag |= USB_FLAG_RUNNING_UNDER_EFI;
+ } else { // Acquiring - check the current condition first
+//USB_DEBUG(DEBUG_LEVEL_3, "fpURP->ApiData.Owner=%d...", fpURP->ApiData.Owner);
+ if(gEmulationTrap) {
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ }
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+//USB_DEBUG(DEBUG_LEVEL_3, "USB_FLAG_RUNNING_UNDER_EFI\n");
+ gUsbData->dUSBStateFlag &= ~USB_FLAG_RUNNING_UNDER_EFI;
+ } else {
+//USB_DEBUG(DEBUG_LEVEL_3, "not USB_FLAG_RUNNING_UNDER_EFI\n");
+ }
+ }
+ fpURP->bRetValue = USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_HcStartStop
+//
+// Description: This function is part of the USB BIOS API. This function
+// starts/stops the USB host controller.
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: None
+//
+// Notes:
+//
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_HcStartStop(URP_STRUC *Urp)
+{
+ HC_STRUC* HcStruc;
+ EFI_STATUS Status;
+
+ HcStruc = Urp->ApiData.HcStartStop.HcStruc;
+
+ Status = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ if ((HcStruc->bHCType != USB_HC_UHCI) && (HcStruc->bHCType != USB_HC_OHCI) &&
+ (HcStruc->bHCType != USB_HC_EHCI) && (HcStruc->bHCType != USB_HC_XHCI)) {
+ return;
+ }
+
+ gCheckUsbApiParameter = FALSE;
+
+ if (Urp->ApiData.HcStartStop.Start) {
+ Urp->bRetValue = UsbHcStart(HcStruc);
+ } else {
+ Urp->bRetValue = UsbHcStop(HcStruc);
+ }
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_invoke_in_frame
+//
+// Description: Invokes procedure passing parameters supplied in the buffer
+// It replicates the stack frame so that target procedure can
+// see the parameters passed to the stub.
+//
+// Output: Returns result of invoked proc
+//
+//------------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+//
+// The following typedef corresponds to the min width type that can be passed
+// into function call as a parameter without padding
+//
+typedef UINTN STACKWORD;
+
+UINTN
+USBAPI_invoke_in_frame(
+ VOID* pProc,
+ VOID* buffer,
+ UINT32 paramSize )
+{
+ STACKWORD* params = (STACKWORD*)buffer;
+
+ switch(paramSize/sizeof(STACKWORD)){
+ case 0: return ((STACKWORD (*)())pProc)();
+ case 1: return ((STACKWORD (*)(STACKWORD))pProc)(params[0]);
+ case 2: return ((STACKWORD (*)(STACKWORD,STACKWORD))pProc)(params[0],
+ params[1]);
+ case 3: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD))pProc)(
+ params[0],params[1],params[2]);
+ case 4: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,
+ STACKWORD))pProc)(
+ params[0],params[1],params[2],params[3]);
+ case 5: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,STACKWORD,
+ STACKWORD))pProc)(
+ params[0],params[1],params[2],params[3],params[4]);
+ case 6: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,STACKWORD,
+ STACKWORD,STACKWORD))pProc)(
+ params[0],params[1],params[2],params[3],params[4],params[5]);
+ case 7: return ((STACKWORD (*)(STACKWORD,STACKWORD,STACKWORD,STACKWORD,
+ STACKWORD,STACKWORD,STACKWORD))pProc)(
+ params[0],params[1],params[2],params[3],params[4],params[5],
+ params[6]);
+ default:
+ ASSERT(paramSize/sizeof(STACKWORD) < 4);
+ return 0;
+ }
+/* kept for reference
+ __asm {
+ push ecx
+ push esi
+ pushf
+ //Copy stak frame
+ std
+ mov esi, buffer
+ mov ecx, paramSize
+ add esi, ecx
+ sub esi, 4
+ shr ecx, 2
+loop1:
+ lodsd //DWORD PTR ds:edi
+ push eax
+ loop loop1
+ //Call proc
+ mov eax, pProc
+ cld
+ call eax
+ //Read return value
+ mov retVal, eax
+
+ //Restore stack and registers
+ add esp, paramSize
+ popf
+ pop esi
+ pop ecx
+ }
+ return retVal;*/
+}
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_HC_Proc
+//
+// Description: Bridge to a number of procedures supplied by HC driver
+//
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success)
+//
+// Notes:
+// Assumes that buffer has a correct image of the stack that
+// corresponding function reads argument from
+// Size of the buffer can be biger than actually used.
+//
+// Following code copies the buffer (some stack frame) into new
+// stack frame such that invoked dirver proc can read parametes
+// supplied by buffer
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+VOID USBAPI_HC_Proc(URP_STRUC *fpURP)
+{
+ VOID* buffer = fpURP->ApiData.HcProc.paramBuffer;
+ UINT32 paramSize = // align size on DWORD
+ (fpURP->ApiData.HcProc.paramSize + 3) & ~0x3;
+ UN_HCD_HEADER* pHdr;
+
+ ASSERT( GET_HCD_INDEX(fpURP->ApiData.HcProc.bHCType) <
+ sizeof(gUsbData->aHCDriverTable)/sizeof(HCD_HEADER));
+ ASSERT( fpURP->bSubFunc < sizeof(pHdr->asArray.proc)/sizeof(VOID*));
+
+ pHdr = (UN_HCD_HEADER*)(gUsbData->aHCDriverTable +
+ GET_HCD_INDEX(fpURP->ApiData.HcProc.bHCType));
+ fpURP->ApiData.HcProc.retVal = USBAPI_invoke_in_frame(
+ pHdr->asArray.proc[fpURP->bSubFunc],buffer,paramSize);
+ fpURP->bRetValue = USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//-----------------------------------------------------------------------------
+// Procedure: USBAPI_Core_Proc
+//
+// Description: Bridge to a number of procedures supplied by Core proc table
+//
+// Input: fpURP Pointer to the URP structure
+//
+// Output: Return code USB_ERROR - Failure, USB_SUCCESS - Success
+//
+// Notes:
+// Assumes that buffer has a correct image of the stack that
+// corresponding function reads argument from
+// Size of the buffer can be biger than actually used.
+//
+// Following code copies the buffer (some stack frame) into new
+// stack frame such that invoked proc can read parametes
+// supplied by buffer
+//------------------------------------------------------------------------------;
+//<AMI_PHDR_END>
+
+
+VOID* core_proc_table[] = {
+ USB_GetDescriptor,
+ USB_ReConfigDevice,
+ USB_ReConfigDevice2,
+ UsbAllocDevInfo,
+ prepareForLegacyOS,
+ USB_ResetAndReconfigDev,
+ USB_DevDriverDisconnect,
+// USB_GetDataPtr,
+// MemCopy,
+ };
+
+VOID USBAPI_Core_Proc(URP_STRUC *fpURP)
+{
+ VOID* buffer = fpURP->ApiData.CoreProc.paramBuffer;
+ UINT32 paramSize = // align size on DWORD
+ (fpURP->ApiData.CoreProc.paramSize + 3) & ~0x3;
+
+ ASSERT( fpURP->bSubFunc < COUNTOF(core_proc_table));
+
+ fpURP->ApiData.CoreProc.retVal = USBAPI_invoke_in_frame(
+ core_proc_table[fpURP->bSubFunc],buffer,paramSize);
+
+ fpURP->bRetValue = USB_SUCCESS;
+}
+
+
+//----------------------------------------------------------------------------
+// USB API Procedures Ends
+//----------------------------------------------------------------------------
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBWrapGetATAError
+//
+// Description: This routine converts the sense data information into
+// ATAPI error code
+//
+// Input: dSenseData Sense data obtained from the device
+//
+// Output: BYTE - ATAPI error code
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 USBWrapGetATAErrorCode (UINT32 dSenseData)
+{
+ UINT8 sc = (UINT8)dSenseData; // Sense code
+ UINT8 asc = (UINT8)(dSenseData >> 16); // Additional Sense Code (ASC)
+ UINT8 ascq = (UINT8)(dSenseData >> 8); // Additional Sense Code Qualifier (ASCQ)
+
+ if (ascq == 0x28) return USB_ATA_DRIVE_NOT_READY_ERR;
+ if (sc == 7) return USB_ATA_WRITE_PROTECT_ERR;
+ if ((asc == 0x80) && (ascq == 0x80)) return USB_ATA_TIME_OUT_ERR;
+ if (ascq == 0x18) return USB_ATA_DATA_CORRECTED_ERR;
+ if ((ascq==6) && (asc == 0)) return USB_ATA_MARK_NOT_FOUND_ERR;
+ if ((ascq==0x3a) && (asc == 0)) return USB_ATA_NO_MEDIA_ERR;
+ if ((ascq==0x11) && (asc == 0)) return USB_ATA_READ_ERR;
+ if ((ascq==0x11) && (asc == 6)) return USB_ATA_UNCORRECTABLE_ERR;
+ if (ascq==0x30) return USB_ATA_BAD_SECTOR_ERR;
+ if ((ascq<0x20) || (ascq>0x26)) return USB_ATA_GENERAL_FAILURE;
+
+ return USB_ATA_PARAMETER_FAILED;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBWrap_GetnthDeviceInfoStructure
+//
+// Description: This routine finds the 'n'th device's DeviceInfo entry.
+//
+// Input: bDevNumber Device number (1-based)
+//
+// Output: DeviceInfo structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBWrap_GetnthDeviceInfoStructure(UINT8 bDevNumber)
+{
+ return &gUsbData->aDevInfoTable[bDevNumber];
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBWrap_GetDeviceCount
+//
+// Description: This routine searches through the device entry table
+// and returns number of active USB devices configured
+// by the BIOS.
+//
+// Input: fpURPPointer Pointer to the URP
+//
+// Output: Following fields in the URP are modified
+// CkPresence.bNumBootDev Number of USB boot devices found
+// CkPresence.bNumKeyboards Number of USB keyboards present
+// CkPresence.bNumMice Number of USB mice present
+// CkPresence.bNumHubs Number of USB hubs present
+// CkPresence.bNumStorage Number of USB storage devices present
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBWrap_GetDeviceCount(URP_STRUC *fpURP)
+{
+ DEV_INFO *fpDevInfo;
+ UINT8 i;
+
+ for (i=1; i<MAX_DEVICES; i++) {
+ fpDevInfo = &gUsbData->aDevInfoTable[i];
+
+ if ( (fpDevInfo->Flag & DEV_INFO_VALID_STRUC) &&
+ (fpDevInfo->Flag & DEV_INFO_DEV_PRESENT)) {
+ fpURP->ApiData.CkPresence.bNumBootDev++;
+
+ switch (fpDevInfo->bDeviceType) {
+ case BIOS_DEV_TYPE_HID:
+ if (fpDevInfo->HidDevType & HID_DEV_TYPE_KEYBOARD) {
+ fpURP->ApiData.CkPresence.bNumKeyboards++;
+ }
+ if (fpDevInfo->HidDevType & HID_DEV_TYPE_MOUSE) {
+ fpURP->ApiData.CkPresence.bNumMice++;
+ }
+ if (fpDevInfo->HidDevType & HID_DEV_TYPE_POINT) {
+ fpURP->ApiData.CkPresence.bNumPoint++;
+ }
+ break;
+ //<(EIP84455+)
+ case BIOS_DEV_TYPE_HUB:
+ fpURP->ApiData.CkPresence.bNumHubs++;
+ break;
+ case BIOS_DEV_TYPE_STORAGE:
+ fpURP->ApiData.CkPresence.bNumStorage++;
+ break;
+ case BIOS_DEV_TYPE_SECURITY:
+ break;
+ }
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemFill
+//
+// Description: This routine fills the given memory range with the given value.
+//
+// Input:
+// fpPtr - Pointer to the memory region to fill.
+// wSize - Size in bytes of the area to be filled.
+// Value - Byte value to fill the given range with.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+MemFill (
+ UINT8* fpPtr,
+ UINT32 dSize,
+ UINT8 Value)
+{
+ UINT32 dCount;
+
+ if (fpPtr) { // Check for pointer validity
+ for(dCount = 0; dCount < dSize; dCount++) {
+ fpPtr[dCount] = Value;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: MemCopy
+//
+// Description: This routine copies data from source to destination.
+//
+// Input:
+// fpSrc - Pointer to the source.
+// fpDest - Pointer to the destination.
+// wSize - Number of bytes to copy.
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+MemCopy (
+ UINT8* fpSrc,
+ UINT8* fpDest,
+ UINT32 dSize)
+{
+ UINT32 dCount;
+
+ //
+ // Check for pointer validity
+ //
+ if ((fpSrc) && (fpDest)) {
+ for(dCount = 0; dCount < dSize; dCount++) {
+ fpDest[dCount] = fpSrc[dCount];
+ }
+ }
+}
+
+
+UINTN DevicePathSize (
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!EfiIsDevicePathEnd (DevicePath)) {
+ DevicePath = EfiNextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN)DevicePath - (UINTN)Start) + sizeof(EFI_DEVICE_PATH_PROTOCOL);
+}
+
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ IN EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL
+ //
+ Size1 = DevicePathSize (Src1);
+ Size2 = DevicePathSize (Src2);
+ Size = Size1 + Size2;
+
+ if (Size1 != 0 && Size2 != 0) {
+ Size -= sizeof(EFI_DEVICE_PATH_PROTOCOL);
+ }
+
+ Status = gBS->AllocatePool (EfiBootServicesData, Size, (VOID **)&NewDevicePath);
+
+ if (EFI_ERROR(Status)) {
+ return NULL;
+ }
+
+ gBS->CopyMem (NewDevicePath, Src1, Size1);
+
+ //
+ // Over write Src1 EndNode and do the copy
+ //
+ if (Size1 != 0) {
+ SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *)((CHAR8 *)NewDevicePath + (Size1 - sizeof(EFI_DEVICE_PATH_PROTOCOL)));
+ }
+ else {
+ SecondDevicePath = NewDevicePath;
+ }
+ gBS->CopyMem (SecondDevicePath, Src2, Size2);
+ return NewDevicePath;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/amiusb.dxs b/Core/EM/usb/rt/amiusb.dxs
new file mode 100644
index 0000000..170a6ef
--- /dev/null
+++ b/Core/EM/usb/rt/amiusb.dxs
@@ -0,0 +1,44 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+#include <token.h>
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#endif
+#include <Protocol/PciRootBridgeIo.h>
+#include <Protocol/AmiUsbController.h>
+
+DEPENDENCY_START
+ EFI_USB_PROTOCOL_GUID AND
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+#endif
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/amiusb.h b/Core/EM/usb/rt/amiusb.h
new file mode 100644
index 0000000..accb29f
--- /dev/null
+++ b/Core/EM/usb/rt/amiusb.h
@@ -0,0 +1,437 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/rt/amiusb.h 40 10/16/16 10:15p Wilsonlee $
+//
+// $Revision: 40 $
+//
+// $Date: 10/16/16 10:15p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/rt/amiusb.h $
+//
+// 40 10/16/16 10:15p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 39 3/02/16 9:44p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 38 9/01/15 10:18p Wilsonlee
+// [TAG] EIP235482
+// [Category] Improvement
+// [Description] Select this alternate setting for multiple TTs hubs.
+// [Files] usbhub.c, usb.c, amiusb.h, usbdef.h
+//
+// 37 4/10/15 3:09a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 36 3/08/15 10:51p Wilsonlee
+// [TAG] EIP207774
+// [Category] Improvement
+// [Description] Set USB_FLAG_DRIVER_STARTED flag when HC is running and
+// clear it if we don't start any HC.
+// [Files] uhci.c, usb.c, ehci.c, ohci.c, xhci.c, amiusb.h
+//
+// 35 4/29/14 8:14p Wilsonlee
+// [TAG] EIP163828
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The mouses stop more than 4 seconds during TP 0xB4 when
+// power on several times.
+// [RootCause] The device sometime doesn't respond the set report
+// command.
+// [Solution] Change the timeout of set report command to 100 ms.
+// [Files] syskbc.c, sysnokbc.c, usbhid.c, amiusb.h
+//
+// 34 1/23/13 5:14a Ryanchou
+// [TAG] EIP111280
+// [Category] Improvement
+// [Description] Add USB APIs for external driver.
+// [Files] amiusb.c, amiusb.h, usbdef.h
+//
+// 33 11/10/12 6:43a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 32 9/28/12 2:36a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 31 8/29/12 8:40a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 30 8/07/12 9:40p Wilsonlee
+// [TAG] EIP96366
+// [Category] New Feature
+// [Description] Add the token "DEFAULT_USB_EMUL6064_OPTION" that
+// control the default value of the I/O port 60h/64h emulation support
+// option.
+// [Files] usb.sd, usb.sdl, amiusb.c, amiusb.h
+//
+// 29 5/04/12 6:44a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 28 1/13/12 4:29a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 27 11/08/11 8:25a Wilsonlee
+// [TAG] EIP74876
+// [Category] New Feature
+// [Description] Add USB API for shutdown single USB controller.
+// [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 26 7/12/11 8:16a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 25 4/06/11 3:30a Tonylo
+// [TAG] EIP57354
+// [Category] Improvement
+// [Description] Core 4.6.5.0 compliant. UEFI 2.3 and PI 1.x support.
+//
+// 24 3/29/11 10:21a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 23 11/22/10 8:45a Ryanchou
+// [TAG] EIP48064
+// [Category] Improvement
+// [Description] The SB template implemented elink
+// AcpiEnableCallbackList, the XHCI/EHCI hand off function should be
+// invoked via the elink AcpiEnableCallbackList.
+// [Files] amidef.h, amiusb.c, amiusb.dxs, amiusb.h,
+// AmiUsbController.h, usb.sdl, usbrt.mak, usbsb.c
+//
+// 22 7/15/10 4:43a Tonylo
+// EIP15489 - Add USB HandOff function for shurdown/init USB legacy
+// through USB API function.
+//
+// 21 4/02/10 9:00a Olegi
+//
+// 20 3/19/10 10:06a Olegi
+//
+// 19 3/11/10 9:17a Olegi
+//
+// 18 2/27/10 12:01p Olegi
+//
+// 17 1/27/10 4:38p Olegi
+//
+// 16 12/23/09 11:59a Olegi
+//
+// 15 12/22/09 9:02a Olegi
+//
+// 14 11/24/09 11:34a Olegi
+// EIP#29733 - BIOS adds an USB API (Block KBC Access)
+//
+// 13 11/13/09 9:14a Olegi
+//
+// 12 10/30/09 5:48p Olegi
+//
+// 11 10/02/09 10:50a Olegi
+// Code cleanup.
+//
+// 10 5/16/08 12:03p Olegi
+// Compliance with AMI coding standard.
+//
+// 9 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 7 3/20/06 3:38p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 3 8/05/05 3:38p Andriyn
+// Complience with EFI EDK
+//
+// 2 6/03/05 6:34p Andriyn
+// EFI_SMM_USB_DISPATCH_CONTEXT param was added to SMI handlers to comply
+// with Aptio framework
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AmiUsb.h
+//
+// Description: AMI UsbRt driver definitions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _EFI_USB_H
+#define _EFI_USB_H
+
+#include "token.h"
+
+#include <Protocol\DevicePath.h>
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <Protocol\SmmBase.h>
+ //(EIP57354)>
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol\SmmControl2.h>
+#else
+#include <Protocol\SmmControl.h>
+#endif
+ //<(EIP57354)
+#include <Protocol\SmmSwDispatch.h>
+#include <Protocol\SmmUSBDispatch.h>
+#endif
+
+#include <Protocol\PciRootBridgeIo.h>
+#include <Protocol\AmiUsbController.h>
+#include <Protocol\LoadedImage.h>
+#include <Protocol\BlockIo.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\SimplePointer.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\ComponentName.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\FirmwareVolume.h >
+#include <Protocol\UsbPolicy.h>
+#include <Protocol\Emul6064Kbdinput.h>
+#include <Protocol\Emul6064MsInput.h>
+#include <Protocol\Emul6064Trap.h>
+#include "usbdef.h"
+
+EFI_STATUS
+USBDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+VOID
+USBSWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_SW_DISPATCH_CONTEXT *DispatchContext
+ );
+
+VOID
+UhciHWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext
+ );
+
+VOID
+OhciHWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext
+ );
+
+VOID
+EhciHWSMIHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN EFI_SMM_USB_DISPATCH_CONTEXT *DispatchContext
+ );
+
+VOID
+XhciHwSmiHandler (
+ IN EFI_HANDLE DispatchHandle,
+ IN VOID *DispatchContext
+ );
+#endif
+
+VOID UsbApiHandler(VOID*);
+EFI_STATUS InstallUsbProtocols(VOID);
+
+VOID
+Emul6064TrapCallback (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+EFI_STATUS UsbInstallHwSmiHandler(HC_STRUC*);
+
+UINT8 ByteReadIO (UINT16);
+VOID ByteWriteIO (UINT16, UINT8);
+UINT32 ReadPCIConfig(UINT16, UINT8);
+VOID WordWritePCIConfig(UINT16, UINT8, UINT16);
+UINT32 DwordReadMem(UINT32, UINT16);
+VOID USBAPI_CheckPresence(URP_STRUC*); // API 00h
+VOID USBAPI_Start(URP_STRUC*); // API 20h
+VOID USBAPI_Stop(URP_STRUC*); // API 21h
+VOID USBAPI_DisableInterrupts(URP_STRUC*); // API 22h
+VOID USBAPI_EnableInterrupts(URP_STRUC*); // API 23h
+VOID USBAPI_MoveDataArea(URP_STRUC*); // API 24h
+VOID USBAPI_GetDeviceInfo(URP_STRUC*); // API 25h
+VOID USBAPI_CheckDevicePresence(URP_STRUC*); // API 26h
+VOID USBAPI_MassDeviceRequest(URP_STRUC*); // API 27h
+VOID USBAPI_PowerManageUSB(URP_STRUC*); // API 28h
+VOID USBAPI_PrepareForOS(URP_STRUC*); // API 29h
+VOID USBAPI_SecureInterface(URP_STRUC*); // API 2Ah
+VOID USBAPI_LightenKeyboardLEDs(URP_STRUC*); // API 2Bh
+VOID USBAPI_ChangeOwner(URP_STRUC*); // API 2Ch
+VOID USBAPI_HC_Proc(URP_STRUC*); // API 2Dh
+VOID USBAPI_Core_Proc(URP_STRUC*); // API 2eh
+VOID USBAPI_LightenKeyboardLEDs_Compatible(URP_STRUC*); // API 2Fh
+VOID USBAPI_KbcAccessControl(URP_STRUC*); // API 30h //(EIP29733+)
+VOID USBAPI_LegacyControl(URP_STRUC*); // API 31h //
+VOID USBAPI_GetDeviceAddress(URP_STRUC*); // API 32h
+VOID USBAPI_ExtDriverRequest(URP_STRUC*); // API 33h
+VOID USBAPI_CCIDRequest(URP_STRUC*); // API 34h
+VOID USBAPI_UsbStopController(URP_STRUC*); // API 35h //(EIP74876+)
+VOID USBAPI_HcStartStop(URP_STRUC *Urp); // API 36h
+
+VOID USBMassAPIGetDeviceInformation(URP_STRUC*); // USB Mass API Sub-Func 00h
+VOID USBMassAPIGetDeviceGeometry(URP_STRUC*); // USB Mass API Sub-Func 01h
+VOID USBMassAPIResetDevice(URP_STRUC*); // USB Mass API Sub-Func 02h
+VOID USBMassAPIReadDevice(URP_STRUC*); // USB Mass API Sub-Func 03h
+VOID USBMassAPIWriteDevice(URP_STRUC*); // USB Mass API Sub-Func 04h
+VOID USBMassAPIVerifyDevice(URP_STRUC*); // USB Mass API Sub-Func 05h
+VOID USBMassAPIFormatDevice(URP_STRUC*); // USB Mass API Sub-Func 06h
+VOID USBMassAPICommandPassThru(URP_STRUC*); // USB Mass API Sub-Func 07h
+VOID USBMassAPIAssignDriveNumber(URP_STRUC*); // USB BIOS API function 08h
+VOID USBMassAPICheckDevStatus(URP_STRUC*); // USB BIOS API function 09h
+VOID USBMassAPIGetDevStatus(URP_STRUC*); // USB BIOS API function 0Ah
+VOID USBMassAPIGetDeviceParameters(URP_STRUC*); // USB BIOS API function 0Bh
+
+DEV_INFO* USBWrap_GetnthDeviceInfoStructure(UINT8);
+VOID USBWrap_GetDeviceCount(URP_STRUC*);
+UINT8 USBWrapGetATAErrorCode(UINT32);
+UINT16 USBMassRWVCommand(DEV_INFO*, UINT8, VOID*);
+UINT8* USB_GetDescriptor(HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT8, UINT8);
+UINT8 UsbSetInterface(HC_STRUC*, DEV_INFO*, UINT8);
+
+UINT32 USB_ReConfigDevice(HC_STRUC*, DEV_INFO*);
+UINT32 USB_ReConfigDevice2(HC_STRUC*, DEV_INFO*, CNFG_DESC*, INTRF_DESC*);
+DEV_INFO* UsbAllocDevInfo();
+VOID prepareForLegacyOS();
+UINT32 USB_ResetAndReconfigDev(HC_STRUC*, DEV_INFO*);
+UINT32 USB_DevDriverDisconnect(HC_STRUC*, DEV_INFO*);
+VOID USBKB_LEDOn();
+
+
+EFI_DEVICE_PATH_PROTOCOL *AppendDevicePath (EFI_DEVICE_PATH_PROTOCOL*, EFI_DEVICE_PATH_PROTOCOL*);
+
+UINT8 USB_StartHostControllers(USB_GLOBAL_DATA*);
+UINT8 USB_StopHostControllers(USB_GLOBAL_DATA*);
+EFI_STATUS InitializeUsbGlobalData(VOID);
+UINT8 UsbHcStart(HC_STRUC*);
+UINT8 UsbHcStop(HC_STRUC*);
+VOID FixedDelay(UINTN);
+DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*);
+UINT8 USBMassGetDeviceInfo(MASS_GET_DEV_INFO*);
+UINT8 USBMassGetDeviceGeometry(MASS_GET_DEV_GEO*);
+
+UINT16 USBMassStartUnitCommand (DEV_INFO*);
+UINT8 USBMassCmdPassThru (MASS_CMD_PASS_THRU*);
+UINT8 USBMassGetDeviceStatus (MASS_GET_DEV_STATUS*);
+UINT32 USBMassCheckDeviceReady(DEV_INFO*);
+MASS_INQUIRY *USBMassGetDeviceParameters(DEV_INFO*);
+VOID InitSysKbc(EFI_EMUL6064KBDINPUT_PROTOCOL**, EFI_EMUL6064MSINPUT_PROTOCOL**);
+EFI_STATUS InSmmFunction(EFI_HANDLE, EFI_SYSTEM_TABLE*);
+VOID UsbPeriodicEvent();
+DEV_INFO* USB_DetectNewDevice(HC_STRUC*, UINT8, UINT8, UINT8);
+UINT8 USB_EnableEndpointsDummy (HC_STRUC*, DEV_INFO*, UINT8*);
+UINT8 USB_InitDeviceDataDummy (HC_STRUC*,DEV_INFO*,UINT8,UINT8**);
+UINT8 USB_DeinitDeviceDataDummy (HC_STRUC*,DEV_INFO*);
+VOID* USB_MemAlloc(UINT16);
+UINT8 USB_MemFree(VOID*, UINT16);
+UINT8 USBCheckPortChange (HC_STRUC*, UINT8, UINT8);
+VOID UsbKbcAccessControl(UINT8);
+EFI_STATUS USBRT_LegacyControl (VOID *fpURP);
+VOID USB_StopUnsupportedHc();
+UINT8 UsbControlTransfer(HC_STRUC*, DEV_INFO*, DEV_REQ, UINT16, VOID*);
+UINT8 UsbInterruptTransfer(HC_STRUC*, DEV_INFO*, UINT8, UINT16, VOID*, UINT16, UINT16);
+VOID CheckBiosOwnedHc(VOID);
+DEV_DRIVER* UsbFindDeviceDriverEntry(DEV_DRIVER*);
+
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/amiusbrtCCID.h b/Core/EM/usb/rt/amiusbrtCCID.h
new file mode 100644
index 0000000..1a70891
--- /dev/null
+++ b/Core/EM/usb/rt/amiusbrtCCID.h
@@ -0,0 +1,836 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/rt/amiusbrtCCID.h 3 4/10/15 3:08a Wilsonlee $
+//
+// $Revision: 3 $
+//
+// $Date: 4/10/15 3:08a $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/rt/amiusbrtCCID.h $
+//
+// 3 4/10/15 3:08a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 2 5/02/12 1:59a Rajeshms
+// [TAG] EIP83117
+// [Category] Improvement
+// [Description] Extend the Support to different smart card Readers and
+// smart Cards.
+// [Files] usbCCID.c, amiusbrtCCID.h, usbdef.h, efiusbccid.c,
+// AmiusbCCID.h
+//
+// 1 7/12/11 8:17a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AmiUsbrtCCID.h
+//
+// Description: AMI Usb CCID driver definitions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _EFI_CCID_RT_H
+#define _EFI_CCID_RT_H
+
+#include "efi.h"
+#include "token.h"
+#include <AmiDxeLib.h>
+
+//CCID APIs
+#define USB_CCID_SMARTCLASSDESCRIPTOR 0x000
+#define USB_CCID_ATR 0x001
+#define USB_CCID_POWERUP_SLOT 0x002
+#define USB_CCID_POWERDOWN_SLOT 0x003
+#define USB_CCID_GET_SLOT_STATUS 0x004
+#define USB_CCID_XFRBLOCK 0x005
+#define USB_CCID_GET_PARAMETERS 0x006
+
+typedef struct _ICC_DEVICE ICC_DEVICE;
+typedef struct _SMARTCLASS_DESC SMARTCLASS_DESC;
+typedef struct _ATR_DATA ATR_DATA;
+typedef struct _DEV_INFO DEV_INFO;
+typedef struct _HC_STRUC HC_STRUC;
+typedef struct _URP_STRUC URP_STRUC;
+
+#pragma pack(push, 1)
+
+#define BASE_CLASS_CCID_STORAGE 0x0B // SMART device class
+#define SUB_CLASS_CCID 0x00 // SubClass
+#define PROTOCOL_CCID 0x00 // Interface Protocol
+#define DESC_TYPE_SMART_CARD 0x21 // Smart Card Descriptor (Type 21h)
+
+
+#define MAX_ATR_LENGTH 32
+// ATR data dequence is T0, TA1, TB1, TC1, TD1, TA2, TB2, TC2, TD2, TA3... etcs
+
+//
+// equates for bVoltageSupport
+//
+#define AUTO_VOLT 0x00
+#define VOLT_5 0x01
+#define VOLT_3 0x02
+#define VOLT_18 0x04
+
+
+//
+// equates for dwFeatures
+//
+#define AUTO_PARAMETER_CONFIG 0x02
+#define AUTO_ACTIVATION_OF_ICC 0x04
+#define AUTO_ACTIVATION_VOLT_SELECTION 0x08
+#define AUTO_ICC_CLOCK_FREQ 0x10
+#define AUTO_BAUD_RATE_SELECTION 0x20
+#define AUTO_PPS_NEGOTIATION_CCID 0x40
+#define AUTO_PPS_NEGOTIATION_ACTIVE 0x80
+#define STOP_CLOCK_MODE 0x100
+#define NAD_OTHER_THAN_00 0x200
+#define AUTO_IFSD_EXCHANGE 0x400
+#define CHARACTER_LEVEL_EXCHANGE 0x00000
+#define TDPU_LEVEL_EXCHANGE 0x10000
+#define SHORT_ADPU_LEVEL_EXCHANGE 0x20000
+#define EXT_ADPU_LEVEL_EXCHANGE 0x40000
+
+#define PC_TO_RDR_ICCPOWERON 0x62
+#define PC_TO_RDR_ICCPOWEROFF 0x63
+#define PC_TO_RDR_GETSLOTSTATUS 0x65
+#define PC_TO_RDR_XFRBLOCK 0x6F
+#define PC_TO_RDR_GETPARAMETERS 0x6C
+#define PC_TO_RDR_RESETPARAMETERS 0x6D
+#define PC_TO_RDR_SETPARAMETERS 0x61
+#define PC_TO_RDR_ESCAPE 0x6B
+#define PC_TO_RDR_ICCCLOCK 0x6E
+#define PC_TO_RDR_T0APDU 0x6A
+#define PC_TO_RDR_SECURE 0x69
+#define PC_TO_RDR_MECHANICAL 0x71
+#define PC_TO_RDR_ABORT 0x72
+#define PC_TO_RDR_SETDATARATEANDCLOCK 0x73
+
+
+#define RDR_TO_PC_DATABLOCK 0x80
+#define RDR_TO_PC_SLOTSTATUS 0x81
+#define RDR_TO_PC_PARAMETERS 0x82
+#define RDR_TO_PC_ESCAPE 0x83
+#define RDR_TO_PC_DATARATEANDCLOCK 0x84
+
+#define RDR_TO_PC_NOTIFYSLOTCHANGE 0x50
+#define RDR_TO_PC_HARDWAREERROR 0x51
+//
+// BIT definition for ConfiguredStatus
+//
+#define ICCPRESENT 0x01
+#define VOLTAGEAPPLIED 0x02
+#define BAUDRATEPROGRAMMED 0x04
+#define ATRDATAPRESENT 0x08
+#define CONFIGFAILED 0x80
+
+#define IBLOCK 0x00
+#define RBLOCK 0x80
+#define SBLOCK 0xC0
+
+
+
+//CCID Class specific request
+#define CCID_CLASS_SPECIFIC_ABORT (0x01 << 8) | USB_REQ_TYPE_DEVICE | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE
+#define CCID_CLASS_SPECIFIC_GET_CLOCK_FREQUENCIES (0x02 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE
+#define CCID_CLASS_SPECIFIC_GET_DATA_RATES (0x03 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE
+
+typedef enum {
+ T0_PROTOCOL,
+ T1_PROTOCOL
+} TRANSMISSION_PROTOCOL;
+
+//I-Block information
+#define NSBIT 0x40
+#define MBIT 0x20
+
+// S-Block Information
+#define RESYNCH_REQUEST 0xC0
+#define IFS_REQUEST 0xC1
+#define ABORT_REQUEST 0xC2
+#define WTX_REQUEST 0xC3
+
+#define WTX_RESPONSE 0xE3
+#define ABORT_RESPONSE 0xE2
+#define IFS_RESPONSE 0xE1
+#define RESYNCH_RESPONSE 0xE0
+
+
+#define I_BLOCK_MATCH 0x01
+#define I_BLOCK_RESEND 0x02
+
+#define SEND_R_BLOCK_0 0x03
+#define SEND_R_BLOCK_1 0x04
+
+#define GET_DATA_T1_CHAR 0x05
+
+#define T1_CHAR_CMD_PHASE 0x06
+#define T1_CHAR_DATA_PHASE 0x07
+#define RESEND_BLOCK 0x08
+
+
+
+#define BLOCK_TRANSMISSION_TERMINATE 0xFF
+#define BLOCK_TRANSMISION_SUCCESS 0x00
+
+
+// Time extension Calculation (worst case scenario assumed)
+
+//1ETU = F/D * 1/f = 2048/1*1/4Mhz = 0.000512sec
+
+// Use Maximum value for BWI which is 9 and minimum Freq 4Mhz for calculation
+//BWT = 11 ETU + (2BWI * 960 * 372/Clock Frequency) = 11ETU + ( 2* 9 * 960* 372/4000000) = 11+1.607040 = 12ETU = 0.00614sec = 6msec
+
+//WWT = 960 * WI * F / Clock Frequency
+// Character Level
+//The "waiting time" (see 7.2) shall be: WT =WI x960x Fi/f = 255 * 960 * 2048/4000000 = 125ETU = 0.064sec = 64msec
+
+#define INITWAITTIME 64 // 64msec worst case assuming T0
+
+struct _ATR_DATA {
+ UINT8 TS;
+ UINT8 T0;
+ BOOLEAN TA1Present;
+ UINT8 TA1;
+ BOOLEAN TB1Present;
+ UINT8 TB1;
+ BOOLEAN TC1Present;
+ UINT8 TC1;
+ BOOLEAN TD1Present;
+ UINT8 TD1;
+
+ BOOLEAN TA2Present;
+ UINT8 TA2;
+ BOOLEAN TB2Present;
+ UINT8 TB2;
+ BOOLEAN TC2Present;
+ UINT8 TC2;
+ BOOLEAN TD2Present;
+ UINT8 TD2;
+
+ BOOLEAN TD15Present;
+ UINT8 TD15;
+ BOOLEAN TA15Present;
+ UINT8 TA15;
+
+ UINT8 NumberofHystoricalBytes;
+
+};
+
+struct _ICC_DEVICE {
+
+ EFI_HANDLE ChildHandle;
+ UINT8 Slot; // slot number
+ UINT8 RawATRData[32];
+ ATR_DATA AtrData; // Processed ATR data
+ UINT8 TransmissionProtocolSupported; // BitMap
+ UINT8 NumofTransmissionProtocolSupported; // Count 1 based
+ UINT8 Current;
+ UINT8 bStatus; // Holds the status of the last cmd
+ UINT8 bError; // Holds the Slot error value of the last cmd
+ UINT8 ConfiguredStatus; // See the bit defenitions above ICCPresent etc
+
+ UINT16 etu; // 1etu = F/D * 1/f (Elementary time unit) This will hold the timing in Micro sec
+ UINT16 GlobalFi; // Clock Rate Conversion Integer
+ UINT8 GlobalDi; // Baude rate Adjustment
+ UINT8 GlobalFmax; // Max Frequency
+ UINT8 TransmissionProtocol; // Higher nibble what is supported, Lower nibble what is selected
+
+ UINT8 ExtraGuardTime; // N = TC1
+ UINT8 BWI; // From TB of T=1
+ UINT8 CWI; // From TB of T=1
+ UINT8 BWT; // Max. Block width time
+ UINT8 IFSC; // Default Information Filed Size (IFSC)
+ UINT8 IFSD; //
+ UINT8 NAD;
+
+ UINT8 EpilogueFields; // First TC for T=1
+
+ BOOLEAN SpecificMode; // BIT7 set in TA2
+
+ UINT8 ClassABC; // Updated from T15->TA
+ UINT8 StopClockSupport; // Updated from T15->TA 00: Not supported, 1 : State L, 2 : State H, 3 : No preference
+
+ UINT8 bClockStatus; // PlaceHolder for Clockstatus from the last RDR_to_PC_SlotStatus cmd
+ UINT8 bChainParameter; // PlaceHolder for ChainParameter from the last RDR_to_PC_DataBlock
+
+ // This structure should be same as RDR_TO_PC_PARAMETERS_T1_STRUC. Don't add or remove the next 8 bytes
+ UINT8 bProtocolNum; // PlaceHolder for bProtocolNum from RDR_to_PC_Parameters
+ UINT8 bmFindIndex;
+ UINT8 bmTCCKST;
+ UINT8 bGuardTime;
+ UINT8 bWaitingInteger;
+ UINT8 bClockStop;
+ UINT8 bIFSC;
+ UINT8 nNadValue;
+ //End
+
+ // From GetDataRateAndClockFrequency
+ UINT32 dwClockFrequency;
+ UINT32 dwDataRate;
+
+ UINT32 WTwaittime; // (in ETU units) Based on T0 BWT/WWT time will be updated once ATR data is available
+ UINT32 WaitTime; // Final Wait time used in msec
+
+ // Information stored for TDPU transmission
+ UINT8 NaSInterface; // This holds the last N(S) value transmitted.
+ UINT8 NaSCard; // This holds the last N(S) received from card
+ UINT8 RBlockCounter;
+ UINT8 bIFSD; // Max. size of the information field of blocks that can be received by the interface device.
+ BOOLEAN Chaining; // Indicates M bit is set or not
+
+ BOOLEAN T1CharCmdDataPhase; // TRUE for Cmd Phase/False for Data Phase
+
+ DLINK ICCDeviceLink; // Linked to ICCDeviceList
+
+};
+
+struct _SMARTCLASS_DESC{
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT16 bcdCCID;
+ UINT8 bMaxSlotIndex;
+ UINT8 bVoltageSupport;
+ UINT32 dwProtocols;
+ UINT32 dwDefaultClock;
+ UINT32 dwMaximumClock;
+ UINT8 bNumClockSupported;
+ UINT32 dwDataRate;
+ UINT32 dwMaxDataRate;
+ UINT8 bNumDataRatesSupported;
+ UINT32 dwMaxIFSD;
+ UINT32 dwSynchProtocols;
+ UINT32 dwMechanical;
+ UINT32 dwFeatures;
+ UINT32 dwMaxCCIDMessageLength;
+ UINT8 bClassGetResponse;
+ UINT8 bClassEnvelope;
+ UINT16 wLcdLayout;
+ UINT8 bPINSupport;
+ UINT8 bMaxCCIDBusySlots;
+};
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bPowerSlot;
+ UINT16 abRFU;
+} PC_TO_RDR_ICCPOWERON_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+} PC_TO_RDR_ICCPOWEROFF_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+} PC_TO_RDR_GETSLOT_STATUS_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bBWI;
+ UINT16 wLevelParameter;
+} PC_TO_RDR_XFRBLOCK_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+} PC_TO_RDR_GETPARAMETERS_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+} PC_TO_RDR_RESETPARAMETERS_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bProtocolNum;
+ UINT8 abRFU[2];
+ UINT8 bmFindDindex;
+ UINT8 bmTCCKST0;
+ UINT8 bGuardTimeT0;
+ UINT8 bWaitingIntergerT0;
+ UINT8 bClockStop;
+} PC_TO_RDR_SETPARAMETERS_T0_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bProtocolNum;
+ UINT8 abRFU[2];
+ UINT8 bmFindDindex;
+ UINT8 bmTCCKST1;
+ UINT8 bGuardTimeT1;
+ UINT8 bWaitingIntergersT1;
+ UINT8 bClockStop;
+ UINT8 bIFSC;
+ UINT8 bNadValue;
+} PC_TO_RDR_SETPARAMETERS_T1_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+} PC_TO_RDR_ESCAPE_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bClockCommand;
+ UINT8 abRFU[2];
+} PC_TO_RDR_ICCCLOCK_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bmChanges;
+ UINT8 bClassGetResponse;
+ UINT8 bClassEnvelope;
+} PC_TO_RDR_T0APDU_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bBWI;
+ UINT16 wLevelParameter;
+} PC_TO_RDR_SECURE_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bFunction;
+ UINT8 abRFU[2];
+} PC_TO_RDR_MECHANICAL_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+} PC_TO_RDR_ABORT_STRUC;
+
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 abRFU[3];
+ UINT32 dwCloclFrequency;
+ UINT32 dwDataRate;
+} PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength; // Size of abData
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bStatus;
+ UINT8 bError;
+ UINT8 Data; // Usage depends on diffeent Message type
+} RDR_HEADER;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength; // Size of abData
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bStatus;
+ UINT8 bError;
+ UINT8 bChainParameter;
+} RDR_TO_PC_DATABLOCK_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength;
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bStatus;
+ UINT8 bError;
+ UINT8 bClockStatus;
+} RDR_TO_PC_SLOTSTATUS_STRUC;
+
+typedef struct {
+ UINT8 bmFindDindex;
+ UINT8 bmTCCKST0;
+ UINT8 bGuardTimeT0;
+ UINT8 bWaitingIntergerT0;
+ UINT8 bClockStop;
+} PROTOCOL_DATA_T0;
+
+typedef struct {
+ UINT8 bmFindDindex;
+ UINT8 bmTCCKST1;
+ UINT8 bGuardTimeT1;
+ UINT8 bWaitingIntergersT1;
+ UINT8 bClockStop;
+ UINT8 bIFSC;
+ UINT8 bNadValue;
+} PROTOCOL_DATA_T1;
+
+typedef struct {
+ RDR_HEADER Header;
+ PROTOCOL_DATA_T0 ProtocolData;
+} RDR_TO_PC_PARAMETERS_T0_STRUC;
+
+typedef struct {
+ RDR_HEADER Header;
+ PROTOCOL_DATA_T1 ProtocolData;
+} RDR_TO_PC_PARAMETERS_T1_STRUC;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength; // Size of abData
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bStatus;
+ UINT8 bError;
+ UINT8 bRFU;
+} RDR_TO_PC_ESCAPE_STATUS;
+
+typedef struct {
+ UINT8 bMessageType;
+ UINT32 dwLength; // Should be 8
+ UINT8 bSlot;
+ UINT8 bSeq;
+ UINT8 bStatus;
+ UINT8 bError;
+ UINT8 bRFU;
+ UINT32 dwClockFrequency;
+ UINT32 dwDataRate;
+} RDR_TO_PC_DATARATEANDCLOCKFREQUENCY_STRUC;
+
+#pragma pack(pop)
+
+VOID
+USBCCIDInitialize(
+ VOID
+);
+
+UINT8
+USBCCIDCheckForDevice (
+ DEV_INFO *fpDevInfo,
+ UINT8 bBaseClass,
+ UINT8 bSubClass,
+ UINT8 bProtocol
+);
+
+UINT8
+USBCCIDDisconnectDevice (
+ DEV_INFO *fpDevInfo
+);
+
+DEV_INFO*
+USBCCIDConfigureDevice (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 *fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd
+);
+
+UINT32
+USBCCIDIssueBulkTransfer (
+ DEV_INFO* fpDevInfo,
+ UINT8 bXferDir,
+ UINT8* fpCmdBuffer,
+ UINT32 dSize
+);
+
+UINT32
+USBCCIDIssueControlTransfer(
+ DEV_INFO* fpDevInfo,
+ UINT16 wRequest,
+ UINT16 wIndex,
+ UINT16 wValue,
+ UINT8 *fpBuffer,
+ UINT16 wLength
+);
+
+EFI_STATUS
+PCToRDRXfrBlock (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 CmdLength,
+ IN UINT8 *CmdBuffer,
+ IN UINT8 BlockWaitingTime,
+ IN UINT16 LevelParameter
+
+);
+
+EFI_STATUS
+ConstructBlockFrame(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT8 Nad,
+ IN UINT8 PCB,
+ IN UINT32 InfLength,
+ IN UINT8 *InfBuffer,
+ OUT UINT8 *wLevelParameter,
+ OUT UINT32 *BlockFrameLength,
+ OUT UINT8 **BlockFrame
+);
+
+UINT8
+HandleReceivedBlock (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 OriginalBlockFrameLength,
+ IN UINT8 *OriginalBlockFrame,
+ IN UINT32 SentBlockFrameLength,
+ IN UINT8 *SentBlockFrame,
+ IN UINT8 *ReceivedBlockFrame
+);
+
+EFI_STATUS
+TxRxT1TDPUChar (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 CmdLength,
+ IN UINT8 *CmdBuffer,
+ IN UINT8 ISBlock,
+ OUT UINT32 *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+);
+
+EFI_STATUS
+TxRxT1Adpu (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 CmdLength,
+ IN UINT8 *CmdBuffer,
+ OUT UINT32 *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+);
+
+EFI_STATUS
+PCToRDRGetSlotStatus(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+);
+
+EFI_STATUS
+RDRToPCSlotStatus(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+);
+
+EFI_STATUS
+PCToRDRGetParameters(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+);
+
+EFI_STATUS
+RDRToPCParameters(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+);
+
+EFI_STATUS
+RDRToPCDataBlock(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN OUT UINT32 *dwLength,
+ OUT UINT8 *Buffer
+
+);
+
+EFI_STATUS
+ICCInsertEvent(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+);
+
+EFI_STATUS
+ICCRemovalEvent(
+ IN DEV_INFO *fpDevInfo,
+ IN UINT8 Slot
+);
+
+VOID
+ICC_SmiQueuePut(
+ IN VOID *d
+);
+
+VOID
+PrintPCParameters(
+ IN UINT8 *Data
+);
+
+TRANSMISSION_PROTOCOL GetDefaultProtocol (
+ IN ICC_DEVICE *fpICCDevice
+);
+
+VOID
+CalculateLRCChecksum (
+ IN UINT8 *BlockFrame,
+ IN UINT32 BlockFrameLength
+);
+
+EFI_STATUS
+PCtoRDRIccPowerOff(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+);
+
+VOID
+PrintDescriptorInformation (
+ SMARTCLASS_DESC *fpCCIDDesc
+);
+
+VOID
+USBCCIDAPISmartClassDescriptorSMM (
+ IN OUT URP_STRUC *fpURP
+);
+
+VOID
+USBCCIDAPIAtrSMM (
+ IN OUT URP_STRUC *fpURP
+);
+
+VOID
+USBCCIDAPIPowerupSlotSMM (
+ IN OUT URP_STRUC *fpURP
+
+);
+
+VOID
+USBCCIDAPIPowerDownSlotSMM (
+ IN OUT URP_STRUC *fpURP
+
+);
+
+VOID
+USBCCIDAPIGetSlotStatusSMM (
+ IN OUT URP_STRUC *fpURP
+);
+
+VOID
+USBCCIDAPIXfrBlockSMM (
+ IN OUT URP_STRUC *fpURP
+);
+
+VOID
+USBCCIDAPIGetParametersSMM (
+ IN OUT URP_STRUC *fpURP
+
+);
+
+ICC_DEVICE*
+GetICCDevice(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+);
+
+VOID
+PrintTimingInfo(
+ ICC_DEVICE *fpICCDevice
+);
+
+VOID
+PrintATRData(
+ UINT8 *ATRData
+);
+
+UINT8
+FindNumberOfTs(
+ UINT8 Data
+);
+
+VOID
+MemFill (
+ UINT8* fpPtr,
+ UINT32 dSize,
+ UINT8 Value
+);
+
+
+VOID
+MemCopy (
+ UINT8* fpSrc,
+ UINT8* fpDest,
+ UINT32 dSize
+);
+
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/debug.c b/Core/EM/usb/rt/debug.c
new file mode 100644
index 0000000..32e6798
--- /dev/null
+++ b/Core/EM/usb/rt/debug.c
@@ -0,0 +1,110 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/debug.c 7 5/16/08 12:01p Olegi $
+//
+// $Revision: 7 $
+//
+// $Date: 5/16/08 12:01p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/debug.c $
+//
+// 7 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 6 3/20/07 12:18p Olegi
+//
+// 4 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 8/26/05 12:25p Andriyn
+// Simulate Mouse Sampling rate by disabling Mouse Polling (reduce USB
+// SMI# generation)
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Debug.c
+//
+// Description: AMI USB Debug output implementation routnes
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PrintDebugMessage (variable param)
+//
+// Description: This routine prints the debug message
+//
+// Parameters: Variable
+//
+// Output: Status: SUCCESS = Success
+// FAILURE = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+RETCODE
+PrintDebugMsg(
+ int MsgLevel,
+ char * Message, ...)
+{
+ VA_LIST ArgList;
+
+ VA_START(ArgList, Message);
+
+ if ((MsgLevel == 0) ||
+ ((MsgLevel <= TopDebugLevel) &&
+ (MsgLevel >= BottomDebugLevel)))
+ {
+#if DEBUG_SWITCH == 1
+ EfiDebugVPrint(EFI_D_ERROR, Message, ArgList);
+#endif
+ }
+
+ VA_END(ArgList);
+
+ return SUCCESS;
+}
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/ehci.c b/Core/EM/usb/rt/ehci.c
new file mode 100644
index 0000000..faeb5fa
--- /dev/null
+++ b/Core/EM/usb/rt/ehci.c
@@ -0,0 +1,5916 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ehci.c 152 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 152 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ehci.c $
+//
+// 152 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 151 7/22/16 3:50a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 150 7/07/16 2:08a Wilsonlee
+// [TAG] EIP268836
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The system will loop in USB runtime module during IPMI are
+// resetting USB controller.
+// [RootCause] Qh->dLinkPointer is invalid after device is disconnected.
+// [Solution] Check if Qh is changed after we process it.
+// [Files] ehci.c
+//
+// 149 7/07/16 1:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 148 3/14/16 10:21p Wilsonlee
+// [TAG] EIP257506
+// [Category] Improvement
+// [Description] Add USB_KEYREPEAT_INTERVAL token to change the key
+// repeat interval.
+// [Files] usb.sdl, xhci.h, usbkbd.h, uhci.c, ohci.c, ehci.c
+//
+// 147 3/02/16 9:42p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 146 9/06/15 10:05p Wilsonlee
+//
+// 145 7/24/15 4:41a Wilsonlee
+// [TAG] EIP226493
+// [Category] Improvement
+// [Description] Block to process periodic list to prevent that we might
+// send the wrong command sequences to the same device.
+// [Files] usbmass.c, ehci.c, xhci.h, xhci.c, usbdef.h, uhcd.c
+//
+// 144 5/26/15 10:48p Wilsonlee
+// [TAG] EIP219177
+// [Category] Improvement
+// [Description] Fixed static code analysis issues in Usb module.
+// [Files] UsbInt13.c, ehci.c, usbbus.c
+//
+// 143 4/10/15 3:11a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 142 4/07/15 4:36a Wilsonlee
+// [TAG] EIP212211
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB transfer speed is slower than before in EHCI.
+// [RootCause] If we parse through the all periodic list, the
+// performance is low in AMD platforms.
+// [Solution] Only parse the first entry through
+// MAX_SPLIT_PERIODIC_NUMBER.
+// [Files] ehci.c
+//
+// 141 3/22/15 11:12p Wilsonlee
+// [TAG] EIP206118
+// [Category] Improvement
+// [Description] Remove dead loop in EHCIStartAsyncSchedule and
+// EHCIStopAsyncSchedule functions.
+// [Files] ehci.c
+//
+// 140 3/08/15 10:50p Wilsonlee
+// [TAG] EIP207774
+// [Category] Improvement
+// [Description] Set USB_FLAG_DRIVER_STARTED flag when HC is running and
+// clear it if we don't start any HC.
+// [Files] uhci.c, usb.c, ehci.c, ohci.c, xhci.c, amiusb.h
+//
+// 139 2/24/15 9:53p Wilsonlee
+// [TAG] EIP205784
+// [Category] Improvement
+// [Description] Don't read Periodic Frame List Base Address Register if
+// the controller doesn't support periodic schedule.
+// [Files] ehci.c
+//
+// 138 2/24/15 9:35p Wilsonlee
+// [TAG] EIP206118
+// [Category] Improvement
+// [Description] Remove dead loop in EHCIStartAsyncSchedule and
+// EHCIStopAsyncSchedule functions.
+// [Files] ehci.c
+//
+// 137 1/22/15 10:19p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 136 12/21/14 9:30p Wilsonlee
+// [TAG] EIP194553
+// [Category] Improvement
+// [Description] Realtek 8111EP EHCI controller workaround, this
+// controller doesn't work if the buffer address isn't DWORD alignment
+// (current offset of qTD). Provide the workaround to locate DWORD
+// alignment buffer.
+// [Files] ehci.c
+//
+// 135 11/24/14 12:50a Wilsonlee
+// [TAG] EIP185972
+// [Category] Improvement
+// [Description] To acquire more bandwidth, a dynamically transfer queue
+// allocation mechanism is required.
+// [Files] ehci.c, usbdef.h
+//
+// 134 5/01/14 3:56a Ryanchou
+// [TAG] EIP162589
+// [Category] Improvement
+// [Description] Do not register external controller as key repeat
+// controller.
+// [Files] ehci.c, ohci.c, uhci.c
+//
+// 133 4/30/14 6:12a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 132 4/30/14 5:25a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 131 2/26/14 1:56a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 130 11/26/13 4:15a Ryanchou
+// [TAG] EIP142940
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB keyboard cannot work if token USB_RUNTIME_DRIVER_IN_SMM
+// is disabled.
+// [RootCause] The variable Qh in EhciAddPeriodicQh() does not have
+// initialize value.
+// [Solution] Check if the value of variable Qh is valid first.
+// [Files] ehci.c
+//
+// 129 9/05/13 12:14a Wilsonlee
+// [TAG] EIP135237
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB can't work when turn on AMIDEBUG_RX_SUPPORT.
+// [RootCause] EHCI_PORT_CHANGE_DETECT bit isn't set when turn on
+// AMIDEBUG_RX_SUPPORT.
+// [Solution] Ignore the EHCI_PORT_CHANGE_DETECT bit to check the root
+// hub ports at first time.
+// [Files] ehci.c
+//
+// 128 7/26/13 2:33a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 127 7/22/13 10:31p Wilsonlee
+// [TAG] EIP125357
+// [Category] Improvement
+// [Description] Check if the port releases to a select host controller.
+// [Files] uhci.c, usb.c, usbhub.c, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 126 6/26/13 2:18a Roberthsu
+// [TAG] EIP122174
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Usb keyboard can not work.When special usb key insert
+// [RootCause] This keyboard detect connect status signal during this
+// key initial. So port detect not service.
+// [Solution] Clear port detect status before check port change.
+// [Files] ehci.c
+//
+// 125 6/02/13 11:41p Wilsonlee
+// [TAG] EIP123235
+// [Category] Improvement
+// [Description] Stop the usb host controller at ExitBootService if it
+// is an extend card or it doesn't support HW SMI.
+// [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c,
+// uhcd.c
+//
+// 124 5/12/13 11:52p Wilsonlee
+// Set the data toggle to QH at EHCI_ActivatePolling and
+// EHCI_InterruptTransfer.
+//
+// 123 5/02/13 2:35a Wilsonlee
+// [TAG] EIP121790
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The usb keyboard doesn't work fine behind usb 2.0 hub.
+// [RootCause] Teradici ehci controlle doesn't preserves DT bit in the
+// qTD.
+// [Solution] Don't set "Data toggle control" bit and check DT bit in
+// the queue head.
+// [Files] ehci.c
+//
+// 122 5/01/13 9:54p Wilsonlee
+// [TAG] EIP121643
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot detect the usb floppy.
+// [RootCause] This device doesn't return data when we sned
+// get-config-descriptor command.
+// [Solution] We retry to send get-config-descriptor command if there is
+// no data.
+// [Files] usb.c, ehci.c
+//
+// 121 4/18/13 1:02p Ryanchou
+// Add Teradici USB controller support.
+//
+// 120 4/16/13 6:44a Ryanchou
+// [TAG] EIP118912
+// [Category] Improvement
+// [Description] Add VIA VT6212 EHCI controller support.
+// [Files] ehci.c, uhci.c, usbdef.h, uhcd.c
+//
+// 119 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 118 3/18/13 4:47a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 117 2/24/13 8:59p Wilsonlee
+// [TAG] EIP113541
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] System hangs at checkpoint 0xA2 when Win8 resume from S4.
+// [RootCause] The "HCHalted" bit and "Port Change Detect" bit are set
+// when the system S4 resume to Win8 OS.
+// [Solution] We need to clear the interrupt status even if the
+// "HCHalted" bit is set.
+// [Files] ehci.c, ohci.c, uhci.c
+//
+// 116 1/24/13 3:20a Roberthsu
+// [TAG] EIP111010
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Touch panel button not work.
+// [RootCause] Device write wrong buffer.
+// [Solution] Clear bufferptr in pollingtdcallback.
+// [Files] ehci.c
+//
+// 115 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 114 12/24/12 5:06a Ryanchou
+// [TAG] EIP103031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hans when loading QNX 6.5.0
+// [RootCause] The EHCI port detect change SMI is generated after
+// ownership change to OS.
+// [Solution] Clear the SMI enable bits and status bits even the
+// controller is OS owned.
+// [Files] ehci.c, ohci.c
+//
+// 113 12/06/12 12:38a Wilsonlee
+// [TAG] EIP103186
+// [Category] Improvement
+// [Description] Handle the error case "MEMIO was disabled" in USB
+// driver.
+// [Files] uhci.c, ohci.c, ehci.c, xhci.c
+//
+// 112 11/24/12 9:00p Wilsonlee
+// [TAG] EIP107513
+// [Category] Improvement
+// [Description] Stop periodic schedule before removing QH.
+// [Files] ehci.c
+//
+// 111 11/13/12 7:11a Wilsonlee
+// [TAG] EIP82553
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for XHCI.
+// [Files] usb.c, ehci.c, ohci.c, xhci.c, xhci.h
+//
+// 110 11/10/12 6:40a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 109 10/26/12 8:58a Roberthsu
+// [TAG] EIP102781
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] After update usb module, DebugRx hang at UHCD.Start().
+// [RootCause] dHCSParams vaule not vaild.
+// [Solution] Function EhciIsolateDebugPort move after variable
+// dHCSParams fill.
+// [Files] ehci.c
+//
+// 108 10/25/12 4:28a Wilsonlee
+// [TAG] EIP103051
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] With USB3.0 flash on USB3.0 port and set to USB mode2,
+// system will hang at post code 0x92 during the first cold boot after
+// connecting AC power.
+// [RootCause] This device connects to ehci first and it was
+// disconnected after we reset the port.
+// [Solution] We need to check the connect status after resetting the
+// port.
+// [Files] ehci.c
+//
+// 107 10/25/12 4:15a Wilsonlee
+// [TAG] EIP82354
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for OHCI.
+// [Files] usb.c, ehci.c, ohci.c
+//
+// 106 9/28/12 2:37a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 105 8/29/12 9:32a Ryanchou
+// [TAG] EIP88307
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Key repeat cannot be stopped if the keyboard is connected
+// to xHCI.
+// [RootCause] Periodic timer SMI stop generating when USB SMI and
+// periodic timer SMI is generated frequently.
+// [Solution] Reduces the key repeat rate to avoid this issue.
+// [Files] ehci.c, usb.c, usb.sdl
+//
+// 104 8/29/12 8:16a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 103 5/04/12 6:38a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 102 5/03/12 5:59a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 101 5/03/12 5:17a Ryanchou
+// [TAG] EIP88085
+// [Category] Improvement
+// [Description] Added 1 ms delay after port reset completed.
+// [Files] ehci.c
+//
+// 100 5/03/12 5:08a Ryanchou
+// [TAG] EIP83361
+// [Category] New Feature
+// [Description] Added "USB 2.0 Controller Mode" setup item.
+// [Files] ehci.c, usb.sd, usb.sdl, usb.uni, usbdef.h, UsbPolicy.h,
+// usbport.c
+//
+// 99 4/10/12 10:12p Wilsonlee
+// [TAG] EIP84790
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB IO PROTOCOL under XHCI issue
+// [RootCause] The DevMiscInfo is NULL.
+// [Solution] Fill the DevMiscInfo for the xhci controller.
+// [Files] ehci.c, xhci.c, amiusbhc.c
+//
+// 98 4/05/12 7:42a Wilsonlee
+// [TAG] EIP86001
+// [Category] Improvement
+// [Description] Free the chunk of memory allocated using the
+// USBMem_Alloc call when we didn't use it.
+// [Files] usbhid.c, ehci.c
+//
+// 97 3/20/12 10:34p Wilsonlee
+// [TAG] EIP83295
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System will hang at B2 when do S3/S4 long run test or DOS
+// reboot test.
+// [RootCause] It causes the stack problem when we call
+// IsUSBKeyboardBufferEmpty function.
+// [Solution] Change to use pointer as parameter to
+// IsUSBKeyboardBufferEmpty function.
+// [Files] efiusbkb.c, efisubkb.h, usbmass.c, ehci.c
+//
+// 96 2/16/12 9:04p Wilsonlee
+// [TAG] EIP82307
+// [Category] Improvement
+// [Description] Port routing route to EHCI when EHCI initialization.
+// [Files] ehci.c
+//
+// 95 1/16/12 1:05a Wilsonlee
+// [TAG] EIP81030
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] System hangs randomly at POST.
+// [RootCause] This is EIP71067 side effect. It uses error memory
+// address.
+// [Solution] The change used the correct memory address.
+// [Files] ehci.c
+//
+// 94 12/23/11 8:39p Wilsonlee
+// [TAG] EIP71067
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] SMI Timeout with USB FD and USB Flash Memory
+// [RootCause] It uses the same area to bulk transfer on EHCI/
+// [Solution] It uses local QH and QTD for each control and bulk
+// transfer on EHCI
+// [Files] ehci.c
+//
+// 93 11/09/11 3:30a Ryanchou
+// [TAG] EIP73692
+// [Category] Improvement
+// [Description] Implement the ownership change mechanism for PCH.
+// [Files] ehci.c, usbdef.h, usbsrc.sdl
+//
+// 92 11/08/11 1:57a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 91 9/09/11 5:06a Roberthsu
+// [TAG] EIP68865
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] VIA plug in USB KB/MS cause system hang
+// [RootCause] After release port.Ehci_line_status still exist.
+// [Solution] Release port owner when connect status change.
+// [Files] ehci.c
+//
+// 90 8/08/11 6:58a Ryanchou
+// [TAG] EIP54018
+// [Category] New Feature
+// [Description] Added USB S5 wake up support.
+// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h,
+// usbsb.c xhci.c
+//
+// 89 8/08/11 5:14a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 88 7/19/11 5:16a Ryanchou
+// [TAG] EIP64498
+// [Category] New Feature
+// [Description] Implement EHCI key repeat function.
+// [Files] ehci.c, ehci.h, usb.c, usbdef.h
+//
+// 87 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 86 7/12/11 8:09a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 85 7/01/11 3:18a Ryanchou
+// [TAG] EIP61385
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] USB devices can't detected.
+// [RootCause] This is the side effect of EIP59663, the port status
+// doesn't reflect connect status and connect status change.
+// [Solution] Add 100 us delay.
+// [Files] ehci.c, uhci.c
+//
+// 84 6/21/11 10:26a Ryanchou
+// [TAG] EIP60632
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Generic Usb Redirection caused system hung at checkpoint A2
+// [RootCause] The timeout value is zero, and the bulk transfer never
+// completed.
+// [Solution] UEFI spec defines "If Timeout is 0, then the
+// caller must wait for the function to be completed until
+// EFI_SUCCESS or EFI_DEVICE_ERROR is returned".
+// [Files] ehci.c
+//
+// 83 6/21/11 10:00a Ryanchou
+// [TAG] EIP62708
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Unexpected USB SMI after USB Owner Ship Change
+// [RootCause] Unexpected USB SMI causes an expection after USB onwer
+// ship change
+// executed.
+// [Solution] Check if HC is still under BIOS control before service USB
+// interrupts.
+// [Files] ehci.c
+//
+// 82 6/21/11 9:55a Ryanchou
+// [TAG] EIP59663
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Plug USB WLAN device may causes OHCI malfunction.
+// [RootCause] The devices have to connect to OHCI first, or it can't be
+// configured.
+// [Solution] Port routing route to EHCI after OHCI initialization.
+// [Files] ehci.c, ohci.c
+//
+// 81 5/30/11 8:41a Ryanchou
+// [TAG] EIP61030
+// [Category] Improvement
+// [Description] PORTSC register should be read before write the
+// register, and set the USB_PORT_STAT_DEV_CONNECT_CHANGED flag if
+// bIgnoreConnectStsChng is set and connect status change bit is not set.
+// [Files] ehci.c
+//
+// 80 5/03/11 10:10a Ryanchou
+// [TAG] EIP54283
+// [Category] Improvement
+// [Description] Follow XHCI spec ver 1.0 section 4.6.8 to recovery
+// endpoint halt.
+// [Files] ehci.c, ohci.c, uhci.c, usbdef.h, usbmass.c, xhci.c
+//
+// 79 5/03/11 8:54a Ryanchou
+// [TAG] EIP58108
+// [Category] Improvement
+// [Description] Disable port only if this port is enabled and remove
+// the delay after port disable.
+// [Files] ehci.c
+//
+// 78 4/06/11 3:52a Ryanchou
+// [TAG] EIP55960
+// [Category] Improvement
+// [Description] The Host Controller must halt within 16 micro-frames
+// after software clears the Run bit.
+// [Files] ehci.c, elib.c
+//
+// 77 4/06/11 1:32a Ryanchou
+// [TAG] EIP54782
+// [Category] Improvement
+// [Description] Change polling data size of HID devices to max packet
+// size of interrupt endpoint.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, xhci.c
+//
+// 76 3/29/11 10:47p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 75 3/29/11 10:10a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 74 2/17/11 8:03a Ryanchou
+// [TAG] EIP48592
+// [Category] Improvement
+// [Description] Add timeout check in EHCIStartPeriodicSchedule and
+// EHCIStopPeriodicSchedule to avoid the endless loop.
+// [Files] ehci.c
+//
+// 73 11/11/10 11:32p Ryanchou
+// [TAG] EIP45578
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB 3.0 device can't be detected.
+// [RootCause] Address Device Command fails.
+// [Solution] Reset the device and attempt the Address Device Command
+// again.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c, xhci.c
+//
+// 72 10/20/10 1:02a Ryanchou
+// EIP45689: Uncomment code in EHCI_GetRootHubStatus that wait 20ms for
+// host controller could report accurate port status properly.
+//
+// 71 9/24/10 5:38p Olegi
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 70 8/09/10 1:29a Ryanchou
+// EIP41187: Set CERR field as 3 in a qTD, and service all interrupts
+// after transfer complete.
+//
+// 69 7/13/10 7:16a Ryanchou
+// EIP38356: Implement shutdown USB legacy support in ACPI enable call.
+//
+// 68 6/10/10 3:07a Ryanchou
+// EIP38648: Enable USB Error SMI.
+//
+// 67 3/11/10 9:42a Olegi
+//
+// 66 3/02/10 4:51p Olegi
+// Undone changes in EHCI_ControlTransfer for EIP32956.
+//
+// 65 2/27/10 11:59a Olegi
+//
+// 64 2/26/10 5:14p Olegi
+//
+// 63 2/08/10 9:59a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 62 1/26/10 10:21a Olegi
+// EIP32624: fix Change in InterruptTransfer.
+//
+// 61 1/04/10 9:20a Olegi
+// EIP32956: Polling rate for the keyboards has been changed from 8 ms to
+// 32 ms.
+//
+// 60 12/23/09 11:59a Olegi
+//
+// 59 12/09/09 1:07p Davidd
+// Corrected the USBkeyboard can't hotplug in DOS issue. (EIP 26477)
+//
+// 58 12/09/09 12:33p Olegi
+// Code cleanup.
+//
+// 57 11/30/09 6:13p Olegi
+//
+// 56 11/25/09 1:48p Olegi
+//
+// 55 11/18/09 7:10p Olegi
+// Restored EHCIResetHC call in Start function that was removed for
+// EIP23479. This EIP is resolved differently.
+//
+// 54 10/30/09 5:47p Olegi
+//
+// 52 10/15/09 3:12p Olegi
+// EIP24437: Change EHCI_ProcessInterrupt to handle the HC error bit in
+// the periodic TDs.
+//
+// 51 10/07/09 9:48a Olegi
+// USB Hub error handling improvement. EIP#25601.
+//
+// 50 9/17/09 11:13a Olegi
+// Change in ProcessInterrupt:
+// There may be a condition in which OS changes the base address before
+// owning the semaphore and SMI may occur on USB complete or port change
+// detect. This may cause SMI storm. Disabling SMI will not affect
+// anything since we dont have any control over it.
+//
+// 49 9/15/09 10:28a Olegi
+// EIP26685: uncommented code in EHCI_Stop that disconnects all devices.
+//
+// 48 9/15/09 10:21a Olegi
+// Added USB_INCMPT_HID_DATA_OVERFLOW incompatibility type.
+//
+// 47 8/28/09 11:49a Olegi
+// EIP#25760: change the sequence of periodic schedule and async schedule
+// execution.
+//
+// 46 7/02/09 10:06a Olegi
+// Fix for EIP#23479: while processing EHCI change ownership request, we
+// will not reset the HC. This change will preserve the state of
+// EHCI_CONFIGURE register (MMIO reg 60h, bit0) so the controller
+// switching will not occur.
+//
+// 45 6/24/09 2:35p Olegi
+// Correction in EHCIInitializePeriodicSchedule(); fix for the EIP#23498.
+//
+// 44 6/02/09 2:47p Olegi
+//
+// 43 5/22/09 1:48p Olegi
+// Bugfix in EHCI_GetRootHubStatus.
+//
+// 42 5/15/09 6:16p Olegi
+// Skip enabling PortPower for the ports that already have it enabled.
+// Saves ~100ms per controller.
+//
+// 41 3/19/09 4:56p Olegi
+//
+// 40 3/09/09 8:49a Olegi
+// Modified EHCIProgramLegacyRegisters, EIP#20084.
+//
+// 39 2/20/09 2:30p Olegi
+// Modifications in ProcessOwnerShipChangeSMI function, EIP#19525
+//
+// 38 2/18/09 10:10a Olegi
+// Fast unplug/insert fix, EIP#19206.
+//
+// 37 2/17/09 4:01p Olegi
+//
+// 36 1/16/09 4:11p Olegi
+// Added dependency on MAX_BULK_DATA in EHCI_BulkTransfer.
+//
+// 35 11/06/08 1:59p Olegi
+// Change in EHCI_EnumeratePorts that will avoid unnecessary delays during
+// enabling the port power.
+//
+// 34 10/06/08 3:33p Olegi
+// EHCI change ownership testing in DOS fix (EIP#14855).
+//
+// 33 9/02/08 10:28a Olegi
+// EIP14855 bugfix: change ownership request is not processed properly in
+// case of multiple controllers of the same type.
+//
+// 32 8/08/08 2:37p Olegi
+// Fix in EHCI_GetRootHubStatus that did not report connection properly in
+// some cases.
+//
+// 31 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 30 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 29 4/17/07 8:24a Olegi
+// Device detection algorythm update, in sync with Core8.
+//
+// 28 3/20/07 12:21p Olegi
+//
+// 27 1/25/07 10:19a Olegi
+//
+// 26 12/28/06 5:27p Olegi
+//
+// 25 12/26/06 10:23a Olegi
+//
+// 24 12/22/06 4:05p Olegi
+// Timeout implementation.
+//
+// 23 12/20/06 2:30p Olegi
+//
+// 22 11/21/06 5:35p Olegi
+//
+// 21 11/16/06 6:10p Olegi
+// DebugPort support initial changes.
+//
+// 19 10/19/06 5:16p Andriyn
+//
+// 18 10/12/06 9:37p Andriyn
+// Fix: unexpected plug-off hangs with endless TIMEOUTs
+//
+// 17 10/12/06 9:07p Andriyn
+//
+// 16 7/21/06 6:34p Olegi
+//
+// 15 7/19/06 3:53p Olegi
+// Bugfix in EHCIRemoveQH routine.
+//
+// 14 6/09/06 10:29a Olegi
+// USB_FLAG_ENABLE_BEEP_MESSAGE flag is reset while handling change of the
+// controller ownership.
+//
+// 13 5/22/06 9:08a Olegi
+// ASYNC_BELL_SUPPORT modifications
+//
+// 12 5/16/06 11:23a Olegi
+//
+// 11 5/16/06 11:19a Olegi
+// Removed DisconnectDevice call from EHCI_Stop
+//
+// 10 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 9 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 8 3/16/06 2:34p Olegi
+//
+// 7 3/06/06 6:25p Olegi
+//
+// 6 1/11/06 11:52a Olegi
+//
+// 5 11/29/05 12:33p Andriyn
+//
+// 4 6/03/05 6:09p Olegi
+// HW SMI registration change.
+//
+// 3 5/19/05 8:07p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 2 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Ehci.h
+//
+// Description: AMI USB EHCI support
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#endif
+
+UINT8 EHCI_Start (HC_STRUC*);
+UINT8 EHCI_Stop (HC_STRUC*);
+UINT8 EHCI_EnumeratePorts (HC_STRUC*);
+UINT8 EHCI_DisableInterrupts (HC_STRUC*);
+UINT8 EHCI_EnableInterrupts (HC_STRUC*);
+UINT8 EHCI_ProcessInterrupt(HC_STRUC*);
+UINT8 EHCI_GetRootHubStatus (HC_STRUC*,UINT8, BOOLEAN);
+UINT8 EHCI_DisableRootHub (HC_STRUC*,UINT8);
+UINT8 EHCI_EnableRootHub (HC_STRUC*,UINT8);
+UINT16 EHCI_ControlTransfer (HC_STRUC*,DEV_INFO*,UINT16,UINT16,UINT16,UINT8*,UINT16);
+UINT32 EHCI_BulkTransfer (HC_STRUC*,DEV_INFO*,UINT8,UINT8*,UINT32);
+UINT16 EHCI_InterruptTransfer (HC_STRUC*, DEV_INFO*, UINT8, UINT16, UINT8*, UINT16);
+UINT8 EHCI_DeactivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 EHCI_ActivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 EHCI_DisableKeyRepeat (HC_STRUC*);
+UINT8 EHCI_EnableKeyRepeat (HC_STRUC*);
+UINT8 EHCI_ResetRootHub (HC_STRUC*,UINT8);
+UINT8 EHCI_GlobalSuspend (HC_STRUC*); //(EIP54018+)
+
+UINT8 EHCIResetHC(HC_STRUC*);
+UINT8 EHCIInitializePeriodicSchedule(HC_STRUC*, UINT32);
+UINT8 EHCIProgramLegacyRegisters(HC_STRUC*, UINT8);
+UINT8 EHCIStartAsyncSchedule(HC_STRUC*);
+UINT8 EHCIStopAsyncSchedule(HC_STRUC*);
+UINT8 EHCIStartPeriodicSchedule(HC_STRUC*);
+UINT8 EHCIStopPeriodicSchedule(HC_STRUC*);
+UINT8 EHCIProcessQH(HC_STRUC*, EHCI_QH*);
+VOID EHCIProcessPeriodicList(HC_STRUC*);
+VOID EHCIInitializeQueueHead (EHCI_QH*);
+VOID EHCISetQTDBufferPointers(EHCI_QTD*, UINT8*, UINT32);
+UINT16 EHCIWaitForTransferComplete(HC_STRUC*, EHCI_QH*,DEV_INFO* );
+UINT8 EhciAddPeriodicQh(HC_STRUC*,EHCI_QH*);
+UINT8 EhciRemovePeriodicQh(HC_STRUC*,EHCI_QH*);
+VOID ProcessOwnerShipChangeSMI(HC_STRUC*);
+VOID ProcessSmiChangeToEHCD(HC_STRUC*);
+VOID ProcessSmiChangeToBIOS(HC_STRUC*);
+UINT8 EHCIGetLegacySupportOffset(HC_STRUC*, UINT16);
+VOID EHCIRemoveQHFromAsyncList(HC_STRUC*, EHCI_QH*);
+UINT8 EhciPollingTDCallback(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 EhciRepeatTDCallback(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+
+UINT32 ReadPCIConfig(UINT16, UINT8);
+VOID WordWritePCIConfig(UINT16, UINT8, UINT16);
+VOID DwordWritePCIConfig(UINT16, UINT8, UINT32);
+
+UINT32 DwordReadMem(UINT32, UINT16);
+VOID DwordWriteMem(UINT32, UINT16, UINT32);
+VOID DwordResetMem(UINT32, UINT16, UINT32);
+VOID DwordSetMem(UINT32, UINT16, UINT32);
+
+UINT32 EhciReadPciReg(HC_STRUC*, UINT32);
+VOID EhciWritePciReg(HC_STRUC*, UINT32, UINT32);
+UINT32 EhciReadHcMem(HC_STRUC*, UINT32);
+VOID EhciWriteHcMem(HC_STRUC*, UINT32, UINT32);
+UINT32 EhciReadOpReg(HC_STRUC*, UINT32);
+VOID EhciWriteOpReg(HC_STRUC*, UINT32, UINT32);
+VOID EhciClearOpReg(HC_STRUC*, UINT32, UINT32);
+VOID EhciSetOpReg(HC_STRUC*, UINT32, UINT32);
+UINT32 EhciReadDebugReg(HC_STRUC*, UINT8, UINT32);
+VOID* EhciMemAlloc(HC_STRUC*, UINT16);
+VOID EhciMemFree(HC_STRUC*, VOID*, UINT16);
+UINT8 EhciDmaMap(HC_STRUC*, UINT8, UINT8*, UINT32, UINT8**, VOID**);
+UINT8 EhciDmaUnmap(HC_STRUC*, VOID*);
+BOOLEAN EhciIsHalted(HC_STRUC*);
+UINT16 EhciTranslateInterval(UINT8, UINT8);
+
+UINT8 USBCheckPortChange (HC_STRUC*, UINT8, UINT8);
+UINT8 USBLogError(UINT16);
+UINT8 UsbGetDataToggle(DEV_INFO*,UINT8);
+VOID UsbUpdateDataToggle(DEV_INFO*, UINT8, UINT8);
+
+VOID USB_InitFrameList (HC_STRUC*, UINT32);
+VOID FixedDelay(UINTN);
+
+VOID* USB_MemAlloc (UINT16);
+UINT8 USB_MemFree (VOID _FAR_ *, UINT16);
+UINT8 USB_DisconnectDevice (HC_STRUC*, UINT8, UINT8);
+DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*);
+UINT8 USB_StopDevice (HC_STRUC*, UINT8, UINT8);
+UINT8 USB_InstallCallBackFunction (CALLBACK_FUNC);
+VOID USBKeyRepeat(HC_STRUC*, UINT8);
+
+#if USB_DEV_KBD
+VOID USBKBDPeriodicInterruptHandler(HC_STRUC*);
+#endif
+
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gCheckUsbApiParameter;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_FillHCDEntries (HCD_HEADER *fpHCDHeader)
+//
+// Description: This function fills the host controller driver
+// routine pointers
+//
+// Parameters: fpHCDHeader Ptr to the host controller header structure
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_FillHCDEntries (HCD_HEADER *fpHCDHeader)
+{
+ fpHCDHeader->pfnHCDStart = EHCI_Start;
+ fpHCDHeader->pfnHCDStop = EHCI_Stop;
+ fpHCDHeader->pfnHCDEnumeratePorts = EHCI_EnumeratePorts;
+ fpHCDHeader->pfnHCDDisableInterrupts = EHCI_DisableInterrupts;
+ fpHCDHeader->pfnHCDEnableInterrupts = EHCI_EnableInterrupts;
+ fpHCDHeader->pfnHCDProcessInterrupt = EHCI_ProcessInterrupt;
+ fpHCDHeader->pfnHCDGetRootHubStatus = EHCI_GetRootHubStatus;
+ fpHCDHeader->pfnHCDDisableRootHub = EHCI_DisableRootHub;
+ fpHCDHeader->pfnHCDEnableRootHub = EHCI_EnableRootHub;
+ fpHCDHeader->pfnHCDControlTransfer = EHCI_ControlTransfer;
+ fpHCDHeader->pfnHCDBulkTransfer = EHCI_BulkTransfer;
+ fpHCDHeader->pfnHCDInterruptTransfer = EHCI_InterruptTransfer;
+ fpHCDHeader->pfnHCDDeactivatePolling = EHCI_DeactivatePolling;
+ fpHCDHeader->pfnHCDActivatePolling = EHCI_ActivatePolling;
+ fpHCDHeader->pfnHCDDisableKeyRepeat = EHCI_DisableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableKeyRepeat = EHCI_EnableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableEndpoints = USB_EnableEndpointsDummy;
+ fpHCDHeader->pfnHCDInitDeviceData = USB_InitDeviceDataDummy;
+ fpHCDHeader->pfnHCDDeinitDeviceData = USB_DeinitDeviceDataDummy;
+ fpHCDHeader->pfnHCDResetRootHub = EHCI_ResetRootHub;
+ fpHCDHeader->pfnHCDClearEndpointState = 0; //(EIP54283+)
+ fpHCDHeader->pfnHCDGlobalSuspend = EHCI_GlobalSuspend; //(EIP54018+)
+
+ USB_InstallCallBackFunction(EhciRepeatTDCallback);
+ USB_InstallCallBackFunction(EhciPollingTDCallback);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EhciIsolateDebugPort
+//
+// Description: This routine locates EHCI debug port and determines whether
+// or not the debug port is initialized and being used by other
+// agents. If so, the global flag will be set to instruct the
+// EHCI runtime routines about debug port presence and prevent
+// any unwanted reset/reconfiguration of this port.
+//
+// Parameters: fpHCStruc Ptr to the host controller structure
+//
+// Output: fpHCStruc->DebugPort is updated if Debug Port is active on
+// this controller; otherwise it will remain 0.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID EhciIsolateDebugPort(HC_STRUC *fpHCStruc)
+{
+ UINT32 HcSParams = fpHCStruc->dHCSParams; // Host Controller Structural Parameters
+ UINT8 DebugPortNo;
+ UINT32 NextCap;
+ UINT8 DebugPortBarIndex;
+ UINT16 DebugPortOffset;
+
+ //
+ // Locate debug port by looking at the PCI capabilities
+ //
+ DebugPortNo = (UINT8)((HcSParams & (EHCI_DEBUG_N)) >> 20);
+
+ //ASSERT(DebugPortNo); // No debug port implemented
+ fpHCStruc->DebugPort = 0;
+ if (DebugPortNo == 0) return;
+
+ ASSERT(DebugPortNo <= (UINT8)(HcSParams & (EHCI_N_PORTS))); // Invalid debug port number
+ if (DebugPortNo > (UINT8)(HcSParams & (EHCI_N_PORTS))) return;
+
+ //
+ // Check whether device implements Capability list that starts at register 0x34
+ //
+ if (!(EhciReadPciReg(fpHCStruc, 4) & BIT20)) {
+ //ASSERT(FALSE); // Capabilities list is not implemented
+ return;
+ }
+
+ //
+ // Find the beginning of Debug Port registers block
+ //
+ for (NextCap = EhciReadPciReg(fpHCStruc, 0x34);
+ (UINT8)NextCap > 0;
+ )
+ {
+ NextCap = EhciReadPciReg(fpHCStruc, (UINT8)NextCap);
+ if ((UINT8)NextCap == 0xA) break; // Debug port capability found
+ NextCap >>= 8;
+ }
+ if ((UINT8)NextCap == 0) {
+ //ASSERT(FALSE); // Debug capabilities not found
+ return;
+ }
+ DebugPortBarIndex = (UINT8)((NextCap >> 29) - 1);
+ DebugPortOffset = (UINT16)((NextCap >> 16) & 0x1FFF);
+ ASSERT(DebugPortBarIndex >= 0 && DebugPortBarIndex <= 5); // Wrong BAR
+ if (!(DebugPortBarIndex >= 0 && DebugPortBarIndex <= 5)) return;
+ //
+ // See whether Debug Port is acquired by other software
+ //
+ if (EhciReadDebugReg(fpHCStruc, DebugPortBarIndex, DebugPortOffset) & BIT28) {
+ fpHCStruc->DebugPort = DebugPortNo;
+ USB_DEBUG(DEBUG_LEVEL_3, "EHCI HC Debug Port #%d enabled.\n", DebugPortNo);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_Start
+//
+// Description: This API function is called to start a EHCI host controller.
+// The input to the routine is the pointer to the HC structure
+// that defines this host controller
+//
+// Parameters: fpHCStruc Ptr to the host controller structure
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_Start (HC_STRUC* fpHCStruc)
+{
+ UINT32 dTemp;
+//#if EHCI_ASYNC_BELL_SUPPORT
+// EHCI_QH *fpQHAsyncXfer;
+//#endif
+ EHCI_QH *fpQHRepeat = NULL;
+ EHCI_QTD *fpqTDRepeat = NULL;
+ UINT32 i; //(EIP55960+)
+ BOOLEAN SetPortPower = FALSE;
+ UINT16 PortReg;
+ EHCI_DESC_PTRS *DescPtr = NULL;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+/*
+USB_DEBUG(DEBUG_LEVEL_3, "Enabling MEM/BM for EHCI HC %02X\n", fpHCStruc->wBusDevFuncNum);
+
+ //
+ // Enable IO access and Bus Mastering
+ //
+ WordWritePCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, 4, BIT1 + BIT2);
+*/
+ //
+ // Get memory base address of the HC and store it in the HCStruc
+ //
+ fpHCStruc->BaseAddress = EhciReadPciReg(fpHCStruc, USB_MEM_BASE_ADDRESS) & 0xFFFFFFF0;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "EHCI HC Mem Addr: %X\n", fpHCStruc->BaseAddress);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)fpHCStruc->BaseAddress, fpHCStruc->BaseAddressSize);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Usb Mmio address is invalid, it is in SMRAM\n");
+ return USB_ERROR;
+ }
+#endif
+ //
+ // Get the number of ports supported by the host controller (Offset 4)
+ // and store it in HCStruc
+ //
+ fpHCStruc->dHCSParams = EhciReadHcMem(fpHCStruc, EHCI_HCSPARAMS);
+ fpHCStruc->bNumPorts = (UINT8)(fpHCStruc->dHCSParams & EHCI_N_PORTS);
+ USB_DEBUG(DEBUG_LEVEL_3, "EHCI HC Number of ports: %d\n", fpHCStruc->bNumPorts);
+
+ EhciIsolateDebugPort(fpHCStruc); //(EIP102781)
+
+ //
+ // Read the Capability Registers Length to find the Offset address for the
+ // beginning of the operational registers
+ //
+ fpHCStruc->bOpRegOffset = (UINT8)EhciReadHcMem(fpHCStruc, EHCI_VERCAPLENGTH);
+ USB_DEBUG(DEBUG_LEVEL_3, "EHCI HC Operational Registers Offset: %d\n", fpHCStruc->bOpRegOffset);
+
+ //
+ // Read and store the HCCPARAMS value
+ //
+ fpHCStruc->dHCCParams = EhciReadHcMem(fpHCStruc, EHCI_HCCPARAMS);
+ //USB_DEBUG(DEBUG_LEVEL_3, "EHCI HC HCPARAMS: %x\n", gUsbData->dHCCParams);
+
+ //
+ // Get PCI register offset for the legacy support in EHCI controller
+ // and store it in HC_STRUC
+ //
+ fpHCStruc->bExtCapPtr = EHCIGetLegacySupportOffset(
+ fpHCStruc,
+ fpHCStruc->wBusDevFuncNum);
+
+#if EHCI_64BIT_DATA_STRUCTURE == 0
+ //
+ // 64bit data structures are not enabled. So check whether this host controller
+ // needs 64bit data structure or not.
+ //
+ if (fpHCStruc->dHCCParams & EHCI_64BIT_CAP)
+ {
+ //
+ // Engineer has to enable the 64bit capability. Post an error message
+ //
+ USBLogError(ERRUSB_EHCI_64BIT_DATA_STRUC);
+ ASSERT(FALSE);
+
+ //
+ // Connect all ports to the classic host controller
+ //
+ EhciClearOpReg(fpHCStruc, EHCI_CONFIGFLAG, BIT0);
+ return USB_ERROR;
+ }
+#endif
+
+#if HIDE_USB_HISPEED_SUPPORT_SETUP_QUESTION == 0
+ if ((gUsbData->UsbHiSpeedSupport == 0) && ((fpHCStruc->dHCSParams & EHCI_N_CC) != 0)) {
+ EhciClearOpReg(fpHCStruc, EHCI_CONFIGFLAG, BIT0);
+ return USB_ERROR;
+ }
+#endif
+
+//----------------------------------------------------------------------------
+// Note: after this point any access to the operational registers is through
+// the macros EHCI_DWORD_READ_MEM and EHCI_DWORD_WRITE_MEM; access to the
+// capability registers is through the macro USBPORT_DWORD_READ_MEM and
+// there is no macro to write to the registers
+//----------------------------------------------------------------------------
+ //(EIP55960)>
+ if ((EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_HCHALTED) == 0) {
+ // Turn HC off and wait for the Halted bit to get set
+ EhciClearOpReg(fpHCStruc, EHCI_USBCMD, EHCI_RUNSTOP);
+
+ // The Host Controller must halt within 16 micro-frames after
+ // software clears the Run bit.
+ for (i = 0; i < 16; i++) {
+ if (EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_HCHALTED) {
+ break;
+ }
+ FixedDelay(125); // 125 us delay
+ }
+ //while ((DwordReadMem(dMemAddr, EHCI_USBSTS) & EHCI_HCHALTED) == 0) {};
+ }
+ //<(EIP55960)
+// /* EIP#23479
+ //
+ // Reset the host controller (HC must be halted)
+ //
+ if (EHCIResetHC(fpHCStruc) == USB_ERROR)
+ {
+ return USB_ERROR; // HC reset error, error log is updated
+ }
+//*/
+ //
+ // Get the frame list size from the EHCI command register
+ //
+ dTemp = EhciReadOpReg(fpHCStruc, EHCI_USBCMD);
+ dTemp = (dTemp & (BIT2 + BIT3)) >> 2;
+
+ //
+ // Calculate number of elements in the asynchronous list
+ // and store the value in the HCStruc
+ //
+ switch (dTemp)
+ {
+ case 0: fpHCStruc->wAsyncListSize = 1024;
+ break;
+ case 1: fpHCStruc->wAsyncListSize = 512;
+ break;
+ case 2: fpHCStruc->wAsyncListSize = 256;
+ break;
+ case 3: return USB_ERROR;
+
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "EHCI AsyncListSize: %d\n", fpHCStruc->wAsyncListSize);
+
+ //
+ // Set the max bulk data size
+ //
+ fpHCStruc->dMaxBulkDataSize = MAX_EHCI_DATA_SIZE;
+
+ //
+ // Initialize the frame list pointers
+ //
+ USB_InitFrameList (fpHCStruc, EHCI_TERMINATE);
+
+ //
+ // Write the base address of the Periodic Frame List to the PERIODIC BASE
+ // register
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_PERIODICLISTBASE, (UINT32)(UINTN)fpHCStruc->fpFrameList);
+
+ //
+ // Initialize the periodic schedule
+ //
+ EHCIInitializePeriodicSchedule(fpHCStruc, (UINT32)fpHCStruc->BaseAddress);
+/*
+#if EHCI_ASYNC_BELL_SUPPORT
+ //
+ // Allocate and initialize an queue head for Async transfer
+ // Set the QHDummy as Async list head
+ //
+ fpQHAsyncXfer = EhciMemAlloc (fpHCStruc, GET_MEM_BLK_COUNT_STRUC(EHCI_QH));
+
+ if (!fpQHAsyncXfer) {
+ return USB_ERROR;
+ }
+
+ gUsbData->fpQHAsyncXfer = fpQHAsyncXfer;
+
+ fpQHAsyncXfer->dEndPntCap = QH_ONE_XFER;
+ fpQHAsyncXfer->fpFirstqTD = 0;
+ fpQHAsyncXfer->dAltNextqTDPtr = EHCI_TERMINATE;
+ fpQHAsyncXfer->dNextqTDPtr = EHCI_TERMINATE;
+
+ //
+ // Assume as a high speed device
+ //
+ dTemp = QH_HIGH_SPEED; // 10b - High speed
+
+ //
+ // Use data toggle from qTD and this QH is the head of the queue
+ //
+ dTemp |= (QH_USE_QTD_DT | QH_HEAD_OF_LIST | DUMMY_DEVICE_ADDR); // Endpoint is 0
+
+ //
+ // dTemp[6:0] = Dev. Addr, dTemp[7] = I bit(0) & dTemp[11:8] = Endpoint (0)
+ //
+ fpQHAsyncXfer->dEndPntCharac = dTemp;
+
+ //
+ // Set the ASYNCLISTADDR register to point to the QHDummy
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_ASYNCLISTADDR, (UINT32)(UINTN)fpQHAsyncXfer);
+
+ //
+ // Set next QH pointer to itself (circular link)
+ //
+ fpQHAsyncXfer->dLinkPointer = (UINT32)(UINTN)fpQHAsyncXfer | EHCI_QUEUE_HEAD;
+ fpQHAsyncXfer->bActive = TRUE;
+#endif // EHCI_ASYNC_BELL_SUPPORT
+*/
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ // Check whether no companion host controllers
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL) &&
+ (fpHCStruc->dHCSParams & EHCI_N_CC) == 0) {
+ //
+ // Allocate a QH/qTD for QHRepeat/qTDRepeat
+ //
+ fpQHRepeat = EhciMemAlloc(fpHCStruc,
+ GET_MEM_BLK_COUNT(sizeof(EHCI_QH)+sizeof(EHCI_QTD)));
+
+ if (!fpQHRepeat) {
+ return USB_ERROR; // Memory allocation error
+ }
+ DescPtr = fpHCStruc->stDescPtrs.fpEHCIDescPtrs;
+ DescPtr->fpQHRepeat = fpQHRepeat;
+ fpqTDRepeat = (EHCI_QTD*)((UINT32)fpQHRepeat + sizeof(EHCI_QH));
+ DescPtr->fpqTDRepeat = fpqTDRepeat;
+//
+// Setup QHRepeat and qTDRepeat. It will run a interrupt transaction to a
+// nonexistant dummy device. This will have the effect of generating
+// a periodic interrupt used to generate keyboard repeat. This QH/qTD
+// is normally inactive, and is only activated when a key is pressed.
+//
+ //
+ // Set the first qTD pointer
+ //
+ fpQHRepeat->fpFirstqTD = fpqTDRepeat;
+
+ //fpQHRepeat->fpDevInfoPtr = (UINT8*)fpDevInfo;
+ fpQHRepeat->dNextqTDPtr = (UINT32)fpqTDRepeat;
+
+ //
+ // Intialize the queue head
+ //
+ fpQHRepeat->dAltNextqTDPtr = EHCI_TERMINATE;
+ fpQHRepeat->dLinkPointer = EHCI_TERMINATE;
+
+ //
+ // Set max packet size, address, endpoint and high speed
+ // Update the AH's endpoint characteristcs field with the data formed
+ //
+ fpQHRepeat->dEndPntCharac |= ((0x40 << 16) | DUMMY_DEVICE_ADDR |
+ QH_HIGH_SPEED);
+
+ //
+ // Set a bit in interrupt mask
+ //
+ fpQHRepeat->dEndPntCap = (BIT0 | QH_ONE_XFER);
+ fpQHRepeat->Interval = REPEAT_INTERVAL;
+
+//
+// Fill the repeat qTD with relevant information
+// The token field will be set so
+// Direction PID = QTD_IN_TOKEN,
+// Size = size of the data,
+// Data Toggle = QTD_DATA0_TOGGLE,
+// Error Count = QTD_NO_ERRORS,
+// Status code = QTD_ACTIVE
+// The buffer pointers field will point to the fpBuffer buffer
+// which was before initialized to contain a DeviceRequest struc.
+// The dNextqTDPtr field will point to the qTDControlSetup
+// The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+//
+ fpQHRepeat->dTokenReload = ((UINT32)8 << 16) | QTD_IN_TOKEN | QTD_ONE_ERROR;
+ fpqTDRepeat->dToken = ((UINT32)8 << 16) | QTD_IN_TOKEN | QTD_ONE_ERROR;
+
+ EHCISetQTDBufferPointers(fpqTDRepeat,
+ &fpQHRepeat->aDataBuffer[0], 8);
+
+ //
+ // Update next & alternate next qTD pointers
+ //
+ fpqTDRepeat->dNextqTDPtr = EHCI_TERMINATE;
+ fpqTDRepeat->dAltNextqTDPtr = EHCI_TERMINATE;
+
+ //
+ // Schedule the QHRepeat to 8ms schedule
+ //
+ EhciAddPeriodicQh(fpHCStruc,fpQHRepeat);
+
+ fpQHRepeat->bCallBackIndex = USB_InstallCallBackFunction(EhciRepeatTDCallback);
+ fpQHRepeat->bActive = FALSE;
+
+ USBKeyRepeat(fpHCStruc, 0);
+ }
+#endif
+
+ //
+ // Clear status register - all R/WC bits
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_USBSTS,
+ EHCI_USB_INTERRUPT | // Interrupt
+ EHCI_USB_ERROR_INTERRUPT | // Error interrupt
+ EHCI_PORT_CHANGE_DETECT | // Port Change Detect
+ EHCI_FRAME_LIST_ROLLOVER | // Frame List Rollover
+ EHCI_HOST_SYSTEM_ERROR | // Host System Error
+ EHCI_INT_ASYNC_ADVANCE); // Interrupt on Async Advance
+ //
+ // Program the HC BIOS owned bit and return the legacy support register offset
+ //
+ if (fpHCStruc->bExtCapPtr) {
+ EHCIProgramLegacyRegisters(fpHCStruc, 1); // Set HC BIOS owned semaphore
+
+ //
+ // Enable USB SMI, SMI on port change and SMI on ownership change
+ //
+ dTemp = EHCI_SMI + EHCI_PORT_CHANGE_SMI + EHCI_OWNERSHIP_CHANGE_SMI;
+
+ EhciWritePciReg(fpHCStruc, fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG, dTemp);
+ }
+
+ //
+ // Turn HC on
+ //
+ EhciSetOpReg(fpHCStruc, EHCI_USBCMD, \
+ (EHCI_RUNSTOP | EHCI_PER_SCHED_ENABLE));
+
+ // Wait for halt bit get cleared
+ for (i = 0; i < 20; i++) {
+ if (!(EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_HCHALTED)) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+
+ //
+ // If the port has the power switch then enable the port. Otherwise
+ // Power for the port is already present. So don't need to enable the power.
+ // ( Refer EHCI Spec 2.2.3 HCSPARAMS Structural Parameters Bit 4 (PPC) )
+ if (fpHCStruc->dHCSParams & EHCI_PPC) {
+ //
+ // Enable port power
+ //
+ for (i = 1, PortReg = EHCI_PORTSC; i <= fpHCStruc->bNumPorts; i++, PortReg += 4) {
+ //
+ // Skip enabling DebugPort
+ //
+ if (fpHCStruc->DebugPort && fpHCStruc->DebugPort == i) continue;
+
+ if (EhciReadOpReg(fpHCStruc, PortReg) & EHCI_PORTPOWER) {
+ continue;
+ }
+
+ EhciSetOpReg(fpHCStruc, PortReg, EHCI_PORTPOWER);
+ SetPortPower = TRUE;
+ }
+ //
+ // Delay till the ports power is stabilised
+ //
+ if (SetPortPower) {
+ FixedDelay(20 * 1000); // 20 msec delay
+ }
+ }
+
+ // Set HC flag as running
+ fpHCStruc->dHCFlag |= HC_STATE_RUNNING;
+
+ // Set USB_FLAG_DRIVER_STARTED flag when HC is running.
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_DRIVER_STARTED)) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_DRIVER_STARTED;
+ }
+
+ //
+ // Disconnect all ports from companion HC (if any) and route them to EHCI
+ //
+ EhciSetOpReg(fpHCStruc, EHCI_CONFIGFLAG, BIT0); //(EIP59663-) //(EIP80307+)
+
+ if (fpHCStruc->dHCFlag & HC_STATE_CONTROLLER_WITH_RMH) {
+ // Wait for port change detect bit set
+ for (i = 0; i < 50; i++) {
+ if (EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_PORT_CHANGE_DETECT) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ } else {
+ FixedDelay(100); // 100 us delay
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ //
+ // Register the USB HW SMI handler
+ //
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ UsbInstallHwSmiHandler(fpHCStruc);
+ } else {
+ USBSB_InstallUsbIntTimerHandler();
+ }
+#endif
+
+ return USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIGetLegacySupportOffset
+//
+// Description: This function returns the PCI register offset for the legacy
+// support in EHCI controller
+//
+// Input: fpHCStruc - HCStruc pointer
+// wPciAddr - PCI address of the EHCI host controller
+//
+// Output: 0 If the feature is not present
+// <>0 Legacy support capability offset
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIGetLegacySupportOffset(
+ HC_STRUC* fpHCStruc,
+ UINT16 wPciAddr)
+{
+ UINT8 bData = 0;
+ UINT32 dData = 0;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+
+ if (fpHCStruc->dHCFlag & HC_STATE_EXTERNAL) {
+ return 0;
+ }
+
+ //
+ // Get EHCI Extended Capabilities Pointer
+ //
+ bData = (UINT8)((fpHCStruc->dHCCParams >> 8) & 0xFF);
+
+ if (!bData)
+ {
+ return 0; // No extended capabilities are implemented.
+ }
+
+ dData = EhciReadPciReg(fpHCStruc, bData);
+ if (!((UINT8)dData & 1)) {
+ return 0;
+ }
+#endif
+ return bData;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIProgramLegacyRegisters
+//
+// Description: This function programs the EHCI legacy registers as per the
+// input. Also this routine returns the PCI register offset
+// for the legacy support in EHCI controller
+//
+// Input: fpHCStruc HCStruc pointer
+// bSetReset:
+// 0 Reset HC BIOS owned bit
+// 1 Set HC BIOS owned bit
+//
+// Output: 0 If the feature is not present
+// <>0 Legacy support capability offset
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIProgramLegacyRegisters(
+ HC_STRUC* fpHCStruc,
+ UINT8 bSetReset)
+{
+ UINT32 dTemp;
+
+ //
+ // Check whether EHCI extended capabilities pointer is present
+ //
+ if (!fpHCStruc->bExtCapPtr)
+ {
+ return 0; // No extended capabilities are implemented.
+ }
+
+ //
+ // Program 'HC BIOS owned semaphore bit'
+ //
+ dTemp = EhciReadPciReg(fpHCStruc, fpHCStruc->bExtCapPtr);
+ dTemp &= ~BIT16;
+
+ if (bSetReset)
+ {
+ dTemp |= BIT16;
+ }
+
+ // (USB_S4_RESUME_ISSUE, EIP#20084)>
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)
+ dTemp &= ~BIT24;
+ // <(USB_S4_RESUME_ISSUE, EIP#20084)
+
+ EhciWritePciReg(fpHCStruc, fpHCStruc->bExtCapPtr, dTemp);
+
+ //
+ // Reset all enable bits and clear the status
+ //
+ dTemp = 0xE0000000 | EHCI_OWNERSHIP_CHANGE_SMI;
+
+ EhciWritePciReg(fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG,
+ dTemp);
+
+ return fpHCStruc->bExtCapPtr;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ClearEECPstatus
+//
+// Description: This procedure clear EHCI legacy support status.
+//
+// Input: fpHCStruc - HCStruc pointer
+// wSTatus - Legacy status to clear
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ClearEECPstatus(
+ HC_STRUC* fpHCStruc,
+ UINT16 wStatus)
+{
+ UINT32 dTemp;
+
+ if (!fpHCStruc->bExtCapPtr)
+ {
+ return; // No extended capabilities are implemented.
+ }
+
+ //
+ // Read control and status register
+ //
+ dTemp = EhciReadPciReg(fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG);
+
+ //
+ // Keep enable bits and set clear status bit
+ //
+ dTemp = (dTemp & 0xFFFF) | ((UINT32)wStatus << 16);
+ EhciWritePciReg(
+ fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG,
+ dTemp);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: GetEhciUSBLEGSUP
+//
+// Description: This routine return USBLEGSUP register content. It could be
+// used to check EHCI semaphore owened by BIOS or OS.
+//
+// Input: fpHCStruc HCStruc pointer
+//
+// Output: UINT32 Legacy support extended capability register content.
+// -1 if no extended capabilities are implemented.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+GetEhciUSBLEGSUP(HC_STRUC* fpHCStruc)
+{
+ UINT32 dTemp;
+
+ //
+ // Check whether EHCI extended capabilities pointer is present
+ //
+ if (!fpHCStruc->bExtCapPtr)
+ {
+ return 0xFFFFFFFF; // No extended capabilities are implemented.
+ }
+
+ //
+ // Read Legacy support register
+ //
+ dTemp = EhciReadPciReg(
+ fpHCStruc,
+ fpHCStruc->bExtCapPtr);
+
+ return dTemp;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_EnumeratePorts
+//
+// Description: This function enumerates the HC ports for devices
+//
+// Input: fpHCStruc Host controller's HCStruc structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_EnumeratePorts(HC_STRUC* fpHCStruc)
+{
+ UINT16 wPortCtl = EHCI_PORTSC; // Port Status and Control Register (44h)
+ UINT8 bHCNumber;
+ UINT8 bPortNum;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (EhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ bHCNumber = (UINT8)(fpHCStruc->bHCNumber | BIT7);
+
+
+ //
+ // Enable port power so that new devices can be detected.
+ //
+ // Check whether enumeration flag is set by us or by somebody else by checking
+ // local enum flag.
+ //
+ if (gUsbData->bEnumFlag == FALSE)
+ {
+ gUsbData->bIgnoreConnectStsChng = TRUE;
+ gUsbData->bEnumFlag = TRUE;
+ //(EIP122174+)>
+ do {
+ //
+ // Clear the EHCI_PCD bit of the interrupt status register EHCI_USBSTS
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_USBSTS, EHCI_PORT_CHANGE_DETECT);
+
+ //
+ // Check the root hub ports to see if a device is connected. If so, then
+ // call USBCheckPortChange to handle the attachment of a new device.
+ //
+ for ( bPortNum = 1; bPortNum <= fpHCStruc->bNumPorts; bPortNum++) {
+ //
+ // Skip DebugPort enumeration
+ //
+ if (fpHCStruc->DebugPort && fpHCStruc->DebugPort==bPortNum) continue;
+
+ //
+ // Process device connect/disconnect
+ //
+ USBCheckPortChange(fpHCStruc, bHCNumber, bPortNum);
+ }
+ } while ((EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_PORT_CHANGE_DETECT));
+ //<(EIP122174+)
+ gUsbData->bIgnoreConnectStsChng = FALSE;
+
+ //
+ // Reset enumeration flag and enable hub enumeration
+ //
+ gUsbData->bEnumFlag = FALSE;
+ }
+
+ //
+ // Enable appropriate interrupts
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_USBINTR, EHCI_USBINT_EN | EHCI_PCDINT_EN);
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCICheckHCStatus
+//
+// Description: This function checks whether the host controller is still
+// under BIOS
+//
+// Input: fpHCStruc - Host controller's HCStruc structure
+//
+// Output: USB_SUCCESS - If the control is with the BIOS
+// USB_ERROR - If the control is not with the BIOS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCICheckHCStatus(
+ HC_STRUC* HcStruc
+)
+{
+ UINT32 Cmd;
+ UINT32 Sts;
+
+ Cmd = EhciReadOpReg(HcStruc, EHCI_USBCMD);
+ Sts = EhciReadOpReg(HcStruc, EHCI_USBSTS);
+
+ // Don't read Periodic Frame List Base Address Register if the controller
+ // doesn't support periodic schedule.
+ if (Cmd & EHCI_PER_SCHED_ENABLE) {
+ if (!(Sts & EHCI_PER_SCHED_STATUS)) {
+ return USB_SUCCESS;
+ }
+ }
+ //
+ // Check whether the controller is still under BIOS control
+ // Read the base address of the Periodic Frame List to the PERIODIC BASE
+ // register and compare with stored value
+ //
+ if ((UINTN)HcStruc->fpFrameList ==
+ (EhciReadOpReg(HcStruc, EHCI_PERIODICLISTBASE) & 0xFFFFF000))
+ {
+ return USB_SUCCESS; // Control is with BIOS
+ }
+ return USB_ERROR; // HC is controlled by someone else
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStop
+//
+// Description: This function stops the EHCI controller.
+//
+// Input: fpHCStruc Host controller's HCStruc structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_Stop (HC_STRUC* fpHCStruc)
+{
+ UINT8 bPortNum; //(EIP26685+)
+ UINT8 Status;
+ UINT8 i; //(EIP55960+)
+ EHCI_DESC_PTRS *DescPtr;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ DescPtr = fpHCStruc->stDescPtrs.fpEHCIDescPtrs;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (((UINT8*)DescPtr < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtr + sizeof(EHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+#endif
+ //
+ // Check whether the control is with BIOS or not
+ //
+ if (EHCICheckHCStatus(fpHCStruc) == USB_SUCCESS) // Controlled by BIOS
+ {
+#if PCH_EHCI_OWNERSHIP_CHANGE_MECHANISM
+ if (fpHCStruc->dHCFlag & HC_STATE_OWNERSHIP_CHANGE_IN_PROGRESS) {
+ UINT16 PortReg;
+ UINT32 PortSts;
+ UINT32 Data32;
+
+ // Disconnect all the devices connected to its ports
+ for (bPortNum = 1; bPortNum <= fpHCStruc->bNumPorts; bPortNum++) {
+ USB_StopDevice(fpHCStruc, (UINT8)(fpHCStruc->bHCNumber | BIT7), bPortNum);
+ }
+
+ // Stop the asynchronous schedule
+ EHCIStopAsyncSchedule(fpHCStruc);
+
+ // Stop the periodic schedule
+ EHCIStopPeriodicSchedule(fpHCStruc);
+
+ for (bPortNum = 1; bPortNum <= fpHCStruc->bNumPorts; bPortNum++) {
+ PortReg = (UINT16)((bPortNum-1)*4 + EHCI_PORTSC);
+ PortSts = EhciReadOpReg(fpHCStruc, PortReg);
+
+ if (!(PortSts & EHCI_PORTENABLE)) {
+ continue;
+ }
+ EhciWriteOpReg(fpHCStruc, PortReg, PortSts | EHCI_SUSPEND);
+ }
+ FixedDelay(250); // 250 us delay
+
+ // Stop the host controller (Reset bit 0)
+ EhciClearOpReg(fpHCStruc, EHCI_USBCMD, EHCI_RUNSTOP);
+
+ // The Host Controller must halt within 16 micro-frames after
+ // software clears the Run bit.
+ for (i = 0; i < 16; i++) {
+ if (EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_HCHALTED) {
+ break;
+ }
+ FixedDelay(125); // 125 us delay
+ }
+
+ // Clear the SMI enable bits
+ if (fpHCStruc->bExtCapPtr) {
+ Data32 = EhciReadPciReg(fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG);
+
+ EhciWritePciReg(fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG, Data32 & ~(0x3F));
+ }
+
+ // Clear the USBSTS register bits
+ EhciWriteOpReg(fpHCStruc, EHCI_USBSTS, EhciReadOpReg(fpHCStruc, EHCI_USBSTS));
+
+ // Clear the Configure Flag bit
+ EhciClearOpReg(fpHCStruc, EHCI_CONFIGFLAG, BIT0);
+ } else
+#endif
+ {
+ //(EIP26685+)>
+ //
+ // Disconnect all the devices connected to its ports
+ //
+ for (bPortNum = 1; bPortNum <= fpHCStruc->bNumPorts; bPortNum++)
+ {
+ USB_DisconnectDevice(fpHCStruc,
+ (UINT8)(fpHCStruc->bHCNumber | BIT7), bPortNum);
+ }
+ //<(EIP26685+)
+
+ if (fpHCStruc->DebugPort == 0) {
+ //
+ // Stop the host controller (Reset bit 0)
+ //
+ EhciClearOpReg(fpHCStruc, EHCI_USBCMD, EHCI_RUNSTOP);
+ //(EIP55960)>
+ // The Host Controller must halt within 16 micro-frames after
+ // software clears the Run bit.
+ for (i = 0; i < 16; i++) {
+ if (EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_HCHALTED) {
+ break;
+ }
+ FixedDelay(125); // 125 us delay
+ }
+ //<(EIP55960)
+ //
+ // Reset the host controller
+ //
+// EIP#23479 EHCIResetHC(fpHCStruc); // ERROR CONDITION RETURNED IS NOT TAKEN CARE
+ Status = EHCIResetHC(fpHCStruc);
+ ASSERT(Status == USB_SUCCESS);
+ }
+ }
+ //
+ // Program the HC BIOS owned bit and return the legacy
+ // support register offset
+ //
+ EHCIProgramLegacyRegisters(fpHCStruc, 0); // Reset HC BIOS owned semaphore
+ // ERROR CONDITION IS NOT HANDLED
+
+ //
+ // Clear the frame list pointers
+ //
+ USB_InitFrameList (fpHCStruc, EHCI_TERMINATE);
+
+ //
+ // Disable TD schedule and free the data structures
+ //
+ if (DescPtr->fpQHRepeat) {
+ EhciMemFree(fpHCStruc, DescPtr->fpQHRepeat,
+ GET_MEM_BLK_COUNT(sizeof(EHCI_QH) + sizeof(EHCI_QTD) ));
+ }
+
+ //
+ // Free the scheduling QHs
+ //
+ EhciMemFree(fpHCStruc, DescPtr->PeriodicQh,
+ GET_MEM_BLK_COUNT(1 * sizeof(EHCI_QH)));
+
+ //
+ // Free descriptor structure
+ //
+ EhciMemFree(fpHCStruc, DescPtr,
+ GET_MEM_BLK_COUNT_STRUC(EHCI_DESC_PTRS));
+
+//#if EHCI_ASYNC_BELL_SUPPORT
+ //
+ // Free the Async transfer QH
+ //
+// EhciMemFree(fpHCStruc, gUsbData->fpQHAsyncXfer, GET_MEM_BLK_COUNT_STRUC(EHCI_QH));
+//#endif
+
+ USBKeyRepeat(fpHCStruc, 3);
+ }
+ else // not controlled by BIOS
+ {
+ //
+ // Program the HC BIOS owned bit and return the legacy
+ // support register offset
+ //
+ EHCIProgramLegacyRegisters(fpHCStruc, 0); // Reset HC BIOS owned semaphore
+ }
+
+ //
+ // Set the HC state to stopped
+ //
+ fpHCStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+
+ CheckBiosOwnedHc();
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_DisableInterrupts
+//
+// Description: This function disables the HC interrupts
+//
+// Input: fpHCStruc Pointer to the HCStruc structure
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_DisableInterrupts (HC_STRUC* fpHCStruc)
+{
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ //
+ // Disable interrupt generation
+ //
+ EhciClearOpReg(fpHCStruc, EHCI_USBINTR, EHCI_USBINT_EN | EHCI_PCDINT_EN);
+
+ //
+ // Stop periodic and asynchoronous schedule
+ //
+ EHCIStopAsyncSchedule(fpHCStruc);
+ EHCIStopPeriodicSchedule(fpHCStruc);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_EnableInterrupts
+//
+// Description: This function enables the HC interrupts
+//
+// Input: fpHCStruc Pointer to the HCStruc structure
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_EnableInterrupts (HC_STRUC* fpHCStruc)
+{
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ //
+ // Start periodic and asynchoronous schedule
+ //
+ EHCIStartAsyncSchedule(fpHCStruc);
+ EHCIStartPeriodicSchedule(fpHCStruc);
+
+ //
+ // Enable interrupt generation
+ //
+ EhciSetOpReg(fpHCStruc, EHCI_USBINTR, EHCI_USBINT_EN | EHCI_PCDINT_EN);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ProcessRootHubChanges
+//
+// Description: Root hub change processing code
+//
+// Parameters: fpHCStruc Pointer to the HCStruc structure
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+ProcessRootHubChanges(
+ HC_STRUC* fpHCStruc
+)
+{
+ UINT8 bPortNum;
+
+ //
+ // Check bEnumFlag before enumerating devices behind root hub
+ //
+ if ((gUsbData->bEnumFlag) == TRUE) {
+ return USB_ERROR;
+ }
+
+ //
+ // Clear the port change bit of the interrupt status register EHCI_USBSTS
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_USBSTS, EHCI_PORT_CHANGE_DETECT);
+
+ //
+ // Check all the ports on the root hub for any change in connect status.
+ // If the connect status has been changed on either or both of these ports,
+ // then call the routine UsbHubPortChange for each changed port.
+ //
+ // Set enumeration flag and avoid hub port enumeration
+ //
+ gUsbData->bEnumFlag = TRUE;
+
+ for (bPortNum = 1; bPortNum <= fpHCStruc->bNumPorts; bPortNum++) {
+ if (fpHCStruc->DebugPort && fpHCStruc->DebugPort==bPortNum) continue;
+ //
+ // Process device connect/disconnect
+ // Note: port connect status is cleared while processing
+ // connect/disconnect (EHCIGetRootHubStatus)
+ //
+ USBCheckPortChange(fpHCStruc, (UINT8)(fpHCStruc->bHCNumber | BIT7), bPortNum);
+ }
+
+ //
+ // Reset enumeration flag and enable hub enumeration
+ //
+ gUsbData->bEnumFlag = FALSE;
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_ProcessInterrupt
+//
+// Description: This function is called when the USB interrupt bit is
+// set. This function will parse through the TDs and QHs to
+// find out completed TDs and call their respective call
+// back functions
+//
+// Parameters: fpHCStruc Pointer to the HCStruc structure
+//
+// Output: USB_ERROR - Need more Interrupt processing
+// USB_SUCCESS - No interrupts pending
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_ProcessInterrupt(HC_STRUC* fpHCStruc)
+{
+ UINT32 dSts, dTmp;
+ UINT16 wStatus;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ //(EIP71067-)>
+//#if (EHCI_ASYNC_BELL_SUPPORT==0)
+// EHCI_QH *fpQH;
+//#endif
+ //<(EIP71067-)
+ //
+ // If EHCI extended capabilities pointer is present,
+ // then service OwnerShipChange SMI
+ //
+ if (fpHCStruc->bExtCapPtr) {
+ //
+ // Read control and status register
+ //
+ dTmp = EhciReadPciReg(
+ fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG);
+ wStatus = (UINT16)dTmp;
+ wStatus &= (UINT16)(dTmp >> 16); // "And" enable and status bits
+ if (wStatus & EHCI_OWNERSHIP_CHANGE_SMI_STS) {
+ ClearEECPstatus(fpHCStruc, wStatus);
+ ProcessOwnerShipChangeSMI(fpHCStruc);
+ return USB_SUCCESS; // Break from Interrupt process loop
+ }
+ }
+
+ //
+ // Check whether the controller is still under BIOS control
+ // Read the base address of the Periodic Frame List to the PERIODIC BASE
+ // register and compare with stored value
+ //
+ if (EHCICheckHCStatus(fpHCStruc) == USB_ERROR) {
+ //
+ // Control is not with us anymore, we should disable SMI generation
+ // and come out.
+ //
+ if (fpHCStruc->bExtCapPtr) {
+ //
+ // Read control and status register
+ //
+ dTmp = EhciReadPciReg(
+ fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG);
+
+ //
+ // Leave only Ownership SMI active.
+ //
+ dTmp &= 0xE0002000;
+ EhciWritePciReg(
+ fpHCStruc,
+ fpHCStruc->bExtCapPtr + EHCI_LEGACY_CTRL_STS_REG,
+ dTmp);
+ }
+ return USB_SUCCESS;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_SUCCESS;
+ }
+
+ while(TRUE){
+ //
+ // Get the interrupt status
+ //
+ dSts = EhciReadOpReg(fpHCStruc, EHCI_USBSTS);
+
+ //USB_DEBUG(DEBUG_LEVEL_3, "-->> %x <<--\n", dSts);
+
+ if (dSts & EHCI_HOST_SYSTEM_ERROR) {
+ gUsbData->dUSBStateFlag &= (~USB_FLAG_ENABLE_BEEP_MESSAGE);
+ EHCI_Start(fpHCStruc);
+ EHCI_EnumeratePorts(fpHCStruc);
+ gUsbData->dUSBStateFlag |= USB_FLAG_ENABLE_BEEP_MESSAGE;
+ continue;
+ }
+
+ if (dSts & EHCI_HCHALTED) {
+ // Clear the USBSTS register bits
+ EhciWriteOpReg(fpHCStruc, EHCI_USBSTS, EhciReadOpReg(fpHCStruc, EHCI_USBSTS));
+ break;
+ }
+
+ //
+ // Check for transaction complete
+ //
+ if ((gUsbData->ProcessingPeriodicList == TRUE) && (dSts & EHCI_USB_INTERRUPT)) {
+
+ //
+ // Clear the interrupt status
+ //
+ EhciWriteOpReg(fpHCStruc, EHCI_USBSTS, EHCI_USB_INTERRUPT);
+
+ //Section 4.4 Schedule traversal rules.
+ //if the periodic schedule is enabled (see Section 4.6) then the host controller must
+ //execute from the periodic schedule before executing from the asynchronous schedule.
+ //It will only execute from the asynchronous schedule after it encounters the end of
+ //the periodic schedule.
+
+ //
+ // Check and process periodic schedule
+ //
+ if (dSts & EHCI_PER_SCHED_STATUS) {
+ //
+ // Check the command register for Async status
+ //
+ dTmp = EhciReadOpReg(fpHCStruc, EHCI_USBCMD);
+
+ if (dTmp & EHCI_PER_SCHED_ENABLE) {
+ EHCIProcessPeriodicList(fpHCStruc);
+ }
+ }
+
+ //
+ // Check for Asynchronous schedule completion
+ //
+/* //(EIP71067-)>
+ if (dSts & EHCI_ASYNC_SCHED_STATUS) {
+ dTmp = DwordReadMem(dMemAddr, EHCI_USBCMD);
+ if (dTmp & EHCI_ASYNC_SCHED_ENABLE) {
+ //
+ // Check and process Async. QH
+ //
+#if EHCI_ASYNC_BELL_SUPPORT
+ EHCIProcessQH(fpHCStruc, fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpQHControl);
+ EHCIProcessQH(fpHCStruc, fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpQHBulk);
+#else
+ //
+ // Get the Async list address
+ //
+ fpQH = (EHCI_QH*)(UINTN)DwordReadMem(dMemAddr, EHCI_ASYNCLISTADDR);
+ if (EHCIProcessQH(fpHCStruc, fpQH) == USB_ERROR) {
+ //continue;
+ //return USB_SUCCESS;
+ } else {
+ //
+ // Async list processed; stop the Async transfer
+ //
+ EHCIStopAsyncSchedule(fpHCStruc);
+ }
+#endif
+ }
+ }
+*/ //<(EIP71067-)
+ continue;
+ }
+
+ //
+ // Check PORT_CHANGE_DETECT bit
+ //
+ if ((dSts & EHCI_PORT_CHANGE_DETECT )) {
+ if(ProcessRootHubChanges(fpHCStruc) == USB_SUCCESS) {
+ continue;
+ }
+ }
+ break; // No more statuses to process
+ }
+ return USB_SUCCESS; // Set as interrupt processed
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ProcessOwnerShipChangeSMI
+//
+// Description: This procedure process EHCI OwnerShipChange SMI.
+//
+// Input: fpHCStruc HCStruc pointer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ProcessOwnerShipChangeSMI(HC_STRUC* fpHCStruc)
+{
+ UINT32 dTemp = GetEhciUSBLEGSUP(fpHCStruc);
+ fpHCStruc->dHCFlag |= HC_STATE_OWNERSHIP_CHANGE_IN_PROGRESS;
+ if (dTemp & EHCI_HC_OS) {
+ gUsbData->dUSBStateFlag &= (~USB_FLAG_ENABLE_BEEP_MESSAGE);
+ ProcessSmiChangeToEHCD(fpHCStruc);
+ }
+ else {
+ gUsbData->dUSBStateFlag |= USB_FLAG_ENABLE_BEEP_MESSAGE;
+ ProcessSmiChangeToBIOS(fpHCStruc);
+ }
+ fpHCStruc->dHCFlag &= ~(HC_STATE_OWNERSHIP_CHANGE_IN_PROGRESS);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ProcessSmiChangeToEHCD
+//
+// Description: This procedure process OwnerShipChange for BIOS -> EHCD.
+//
+// Input: fpHCStruc HCStruc pointer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ProcessSmiChangeToEHCD (HC_STRUC* fpHCStruc)
+{
+ EHCI_Stop(fpHCStruc); // Stop EHCI legacy
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ProcessSmiChangeToBIOS
+//
+// Description: This procedure process OwnerShipChange for EHCD -> BIOS.
+//
+// Input: SI HCStruc pointer
+//
+// Output: None
+//
+// Modified: None
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessSmiChangeToBIOS (
+ HC_STRUC *fpHCStruc
+)
+{
+ HC_STRUC *Hc;
+ UINT8 Count;
+ DEV_INFO *Device;
+
+ // Stop UHCI devices connected to the companions
+ // Core8 executes this under MKF_PCCHECK_PATCH==1 condition, EIP10272
+ for (Count = 1; Count < MAX_DEVICES; Count++) {
+ Device = &gUsbData->aDevInfoTable[Count];
+ Hc = gUsbData->HcTable[Device->bHCNumber - 1];
+
+ if (Hc->bHCType != USB_HC_UHCI) continue; // Not UHCI
+
+ if ((Device->Flag & DEV_INFO_VALID_STRUC)==0) continue; // Not valid
+
+ if ((Hc->wBusDevFuncNum & 0xfff8) !=
+ (fpHCStruc->wBusDevFuncNum & 0xfff8)) continue; // Not a companion
+
+ // Found a device connected to UHCI companion controller. Stop it.
+ USB_StopDevice(Hc, Device->bHubDeviceNumber, Device->bHubPortNumber);
+ }
+
+ EHCI_Start(fpHCStruc); // Reinitialize EHCI host controller
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_ReleasePortOwner
+//
+// Description:
+//
+// Input: HcStruc - Pointer to HCStruc of the host controller
+// PortNum - Port in the HC whose status is requested
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_ReleasePortOwner(
+ HC_STRUC* HcStruc,
+ UINT8 PortNum
+)
+{
+ UINT16 PortReg = (UINT16)((PortNum-1)*4 + EHCI_PORTSC);
+ UINT16 i;
+
+ if ((HcStruc->dHCSParams & EHCI_N_CC) == 0) {
+ return USB_SUCCESS;
+ }
+
+ if (!(EhciReadOpReg(HcStruc, PortReg) & EHCI_CURRENTCONNECTSTATUS)) {
+ return USB_ERROR;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Release EHCI port %d\n", PortNum);
+ EhciSetOpReg(HcStruc, PortReg, EHCI_PORTOWNER);
+
+ // Loop until Full speed device disconnect event process done.
+ // This change is done in sync with Core8 except the extra 400mS delay
+ for (i = 0; i < 200; i++) {
+ if (EhciReadOpReg(HcStruc, PortReg) & EHCI_CONNECTSTATUSCHANGE) {
+ break;
+ }
+ FixedDelay(100);
+ }
+
+ EhciSetOpReg(HcStruc, PortReg, EHCI_CONNECTSTATUSCHANGE);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIGetRootHubStatus
+//
+// Description: This function returns the port connect status for the
+// root hub port
+//
+// Input: fpHCStruc - Pointer to HCStruc of the host controller
+// bPortNum - Port in the HC whose status is requested
+//
+// Output: Port status flags (see USB_PORT_STAT_XX equates)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_GetRootHubStatus(
+ HC_STRUC* fpHCStruc,
+ UINT8 bPortNum,
+ BOOLEAN ClearChangeBits
+)
+{
+ UINT32 dTmp;
+ UINT8 bStatus = USB_PORT_STAT_DEV_OWNER;
+ UINT16 wPortReg = (UINT16)((bPortNum-1)*4 + EHCI_PORTSC);
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (fpHCStruc->DebugPort && fpHCStruc->DebugPort==bPortNum) return 0;
+
+ //
+ // Read the status of the port
+ //
+ dTmp = EhciReadOpReg(fpHCStruc, wPortReg);
+ USB_DEBUG(3, "Ehci port[%d] status: %08x\n", bPortNum, dTmp);
+
+ // Detect the high-speed device.
+ // In case of low-speed or full-speed change the ownership to a
+ // companion 1.1 controller (if any)
+ if (dTmp & EHCI_CURRENTCONNECTSTATUS) {
+ // Analyze Line Status
+ if ((dTmp & EHCI_LINE_STATUS) == EHCI_DMINUSBIT) { // Low speed device connected
+ EHCI_ReleasePortOwner(fpHCStruc, bPortNum);
+ dTmp = EhciReadOpReg(fpHCStruc, wPortReg);
+ }
+ }
+
+ //
+ // Check the connect status change bit
+ //
+ if (dTmp & EHCI_CONNECTSTATUSCHANGE) {
+ //
+ // Set connect status change flag
+ //
+ bStatus |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+
+ //
+ // Wait 20ms for host controller could report accurate port status properly.
+ //
+ //FixedDelay(gUsbData->UsbTimingPolicy.EhciPortConnect * 1000); // 20ms delay
+
+ //
+ // Read the status of the port
+ //
+ //dTmp = EhciReadOpReg(fpHCStruc, wPortReg);
+
+ // Clear connect status change
+ if (ClearChangeBits == TRUE) {
+ EhciSetOpReg(fpHCStruc, wPortReg, EHCI_CONNECTSTATUSCHANGE); //(EIP61030+)
+ }
+ }
+
+ if (dTmp & EHCI_CURRENTCONNECTSTATUS) {
+ bStatus |= USB_PORT_STAT_DEV_CONNECTED;
+
+ if (dTmp & EHCI_PORTENABLE) {
+ bStatus |= USB_PORT_STAT_DEV_HISPEED;
+
+ // Patch for CloverTrail
+ if (fpHCStruc->Vid == 0x8086 &&
+ (fpHCStruc->Did == 0xE006 || fpHCStruc->Did == 0x08F2)) {
+ if ((dTmp & EHCI_LINE_STATUS) == EHCI_DMINUSBIT) {
+ bStatus &= ~USB_PORT_STAT_DEV_HISPEED;
+ bStatus |= USB_PORT_STAT_DEV_LOWSPEED;
+ } else if ((dTmp & EHCI_LINE_STATUS) == EHCI_DPLUSBIT) {
+ bStatus &= ~USB_PORT_STAT_DEV_HISPEED;
+ bStatus |= USB_PORT_STAT_DEV_FULLSPEED;
+ }
+ }
+ bStatus |= USB_PORT_STAT_DEV_ENABLED;
+ //(EIP61030+)>
+ } else {
+ if (gUsbData->bIgnoreConnectStsChng == TRUE) {
+ if (!(dTmp & EHCI_CONNECTSTATUSCHANGE)) {
+ bStatus |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ }
+ }
+ //<(EIP61030+)
+ }
+ }
+
+ if (dTmp & EHCI_PORTOWNER) {
+ bStatus &= ~USB_PORT_STAT_DEV_OWNER;
+ }
+
+ return bStatus;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIDisableRootHub
+//
+// Description: This function disables the EHCI HC Ruoot hub port.
+//
+// Input: fpHCStruc - Pointer to HCStruc of the host controller
+// bPortNum - Port in the HC to disable
+//
+// Output: USB_SUCCESS on success
+// USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_DisableRootHub(
+ HC_STRUC* fpHCStruc,
+ UINT8 bPortNum)
+{
+ //(EIP58108+)>
+ UINT16 PortReg = (UINT16)((bPortNum-1)*4 + EHCI_PORTSC);
+ UINT32 i;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (fpHCStruc->DebugPort && fpHCStruc->DebugPort==bPortNum) return USB_SUCCESS;
+
+ if (!(EhciReadOpReg(fpHCStruc, PortReg) & EHCI_PORTENABLE)) {
+ return USB_SUCCESS;
+ }
+ EhciClearOpReg(fpHCStruc, PortReg, EHCI_PORTENABLE);
+
+ for (i = 0; i < 100; i++) {
+ if ((EhciReadOpReg(fpHCStruc, PortReg) & EHCI_PORTENABLE) == 0) {
+ break;
+ }
+ FixedDelay(100);
+ }
+ //<(EIP58108+)
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIEnableRootHub
+//
+// Description: This function enables the EHCI HC Root hub port.
+//
+// Input: fpHCStruc - Pointer to HCStruc of the host controller
+// bPortNum - Port in the HC to enable
+//
+// Output: USB_SUCCESS on success
+// USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_EnableRootHub(
+ HC_STRUC* fpHCStruc,
+ UINT8 bPortNum)
+{
+//
+// Software can only enable the EHCI root hub ports by port RESET. HC will
+// enable the port only if it is a high speed device
+//
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_ResetRootHub
+//
+// Description: This function resets the EHCI HC Root hub port.
+//
+// Input: HcStruc - Pointer to HCStruc of the host controller
+// PortNum - Port in the HC to enable
+//
+// Output: USB_SUCCESS on success
+// USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_ResetRootHub(
+ HC_STRUC* HcStruc,
+ UINT8 PortNum
+)
+{
+ UINT16 PortReg = (UINT16)((PortNum-1)*4 + EHCI_PORTSC);
+ UINT32 i;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ // Disable the port if it is enabled
+ if (EhciReadOpReg(HcStruc, PortReg) & EHCI_PORTENABLE) {
+ EhciClearOpReg(HcStruc, PortReg, EHCI_PORTENABLE);
+
+ // There may be a delay in disabling or enabling a port due to other
+ // host controller and bus events.
+ for (i = 0; i < 100; i++) {
+ if ((EhciReadOpReg(HcStruc, PortReg) & EHCI_PORTENABLE) == 0) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ }
+
+ // Reset the port
+ EhciSetOpReg(HcStruc, PortReg, EHCI_PORTRESET);
+
+ if ((HcStruc->dHCFlag & HC_STATE_CONTROLLER_WITH_RMH) && (PortNum == 1)) {
+ FixedDelay(3 * 1000); // 3 ms delay
+ } else {
+ // Wait til port disable is complete (Tdrstr=50ms Ref 7.1.7.5 of USB Spec 2.0)
+ FixedDelay(50 * 1000); // 50 ms delay
+ }
+
+ EhciClearOpReg(HcStruc, PortReg, EHCI_PORTRESET); // Terminate reset
+
+ if (!(EhciReadOpReg(HcStruc, PortReg) & EHCI_CURRENTCONNECTSTATUS)) {
+ return USB_ERROR;
+ }
+
+ // if the port detects that the attached device is high-speed during reset,
+ // then the host controller must have the port in the enabled state within 2ms
+ // of software writing this bit to a zero.
+ for (i = 0; i < 20; i++) {
+ if ((EhciReadOpReg(HcStruc, PortReg) & (EHCI_PORTRESET |
+ EHCI_PORTENABLE)) == EHCI_PORTENABLE) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+
+ if (EhciReadOpReg(HcStruc, PortReg) & EHCI_PORTRESET) { // Reset failed
+ USBLogError(USB_ERR_PORT_RESET_FAILED);
+ return USB_ERROR;
+ }
+
+ if (!(EhciReadOpReg(HcStruc, PortReg) & EHCI_PORTENABLE)) {
+ if (!(EhciReadOpReg(HcStruc, PortReg) & EHCI_CURRENTCONNECTSTATUS)) {
+ return USB_ERROR;
+ } else {
+ EHCI_ReleasePortOwner(HcStruc, PortNum);
+ return USB_ERROR;
+ }
+ }
+
+ FixedDelay(1 * 1000); // 1 ms delay
+
+ return USB_SUCCESS;
+}
+
+ //(EIP54018+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EHCI_GlobalSuspend
+//
+// Description:
+// This function suspend the EHCI HC.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_GlobalSuspend(
+ HC_STRUC* HcStruc
+)
+{
+ UINT16 PortReg;
+ UINT32 PortSts;
+ UINT8 PortNum;
+ UINT8 i;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (EhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ for (PortNum = 1; PortNum <= HcStruc->bNumPorts; PortNum++) {
+ PortReg = (UINT16)(EHCI_PORTSC + (PortNum - 1) * 4 );
+ PortSts = EhciReadOpReg(HcStruc, PortReg );
+ USB_DEBUG(DEBUG_LEVEL_3,"EHCI PortSts[%x] %x \n",
+ PortNum, PortSts);
+ // Check if port is disabled or suspended.
+ if((PortSts & EHCI_PORTENABLE) && (!(PortSts & EHCI_SUSPEND))) {
+ // Suspend if necessary.
+ EhciClearOpReg(HcStruc, PortReg,
+ EHCI_WKOC_E | EHCI_WKDSCNNT_E | EHCI_WKCNNT_E);
+ EhciSetOpReg(HcStruc, PortReg, EHCI_SUSPEND);
+ // Read PortSc until port shows suspended.
+ for(i = 0; i < 100; i++) {
+ if(EhciReadOpReg(HcStruc, PortReg) & EHCI_SUSPEND) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ }
+ }
+
+ // Turn HC off and wait for the Halted bit to get set
+ EhciClearOpReg(HcStruc, EHCI_USBCMD, EHCI_RUNSTOP);
+ // The Host Controller must halt within 16 micro-frames after
+ // software clears the Run bit.
+ for (i = 0; i < 16; i++) {
+ if(EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_HCHALTED) {
+ break;
+ }
+ FixedDelay(125); // 125 us delay
+ }
+
+ HcStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+ HcStruc->dHCFlag |= HC_STATE_SUSPEND;
+
+ return USB_SUCCESS;
+}
+ //<(EIP54018+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_GetHiSpeedHubPortNumber
+//
+// Description: This function gets the hi-speed hub's device and port number
+// to which this low speed device is connected. It parses
+// through its parents until it finds the correct device. This
+// information is used for split transaction
+//
+// Input: fpDevInfo - Device info pointer of the device
+//
+// Output: UINT16 - Device/port number of the hi-speed hub
+//
+// Notes: This low/full speed device may be behind different hubs as
+// shown below. In any case this routine will get the device
+// address of the hub number HISP_A :
+// Notations used:
+// MBPortX Motherboard USB port
+// HISP_X Hi-speed hub number X
+// FUSP_X Full-speed hub number X
+// Device Low/Full speed device
+// Config 1:
+// MBPortX --> HISP_A --> Device
+// Config 2:
+// MBPortX --> HISP_A --> FUSP_1 --> Device
+// Config 3:
+// MBPortX --> HISP_B --> HISP_A --> Device
+// Config 4:
+// MBPortX --> HISP_A --> FUSP_1 --> HISP_B --> Device
+// In the above configuration the HISP_B will be operated in
+// full speed rather than hi-speed since it is connected to a
+// full speed hub
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+EHCI_GetHiSpeedHubPortNumber(DEV_INFO* fpDevInfo)
+{
+ DEV_INFO* fpHubDev = fpDevInfo;
+ DEV_INFO* fpParentHubDev;
+ UINT16 wRetCode;
+
+ if( !VALID_DEVINFO( fpDevInfo) )
+ return 0;
+
+//
+// Get the device info structure for the matching device address
+//
+ //
+ // Get the device number of the immediate hub, then get the device
+ // info structure for this device number
+ //
+ for(;;)
+ {
+ fpParentHubDev = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR,
+ 0, fpHubDev->bHubDeviceNumber, 0);
+ if ( !fpParentHubDev ) // Error. Exit !
+ {
+ return 0;
+ }
+ if (((fpParentHubDev->bEndpointSpeed << USB_PORT_STAT_DEV_SPEED_MASK_SHIFT)
+ & USB_PORT_STAT_DEV_SPEED_MASK) == 0) break;
+ fpHubDev = fpParentHubDev;
+ }
+ //
+ // The first USB 2.0 hub found as fpHubDev to which the low/full speed
+ // device is connected
+ //
+ wRetCode = (UINT16)((fpHubDev->bHubPortNumber << 7) |
+ fpHubDev->bHubDeviceNumber);
+
+ return wRetCode;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciExexuteAsyncSchedule
+//
+// Description: This function insert the requested QH to asynchronous schedule
+// and waits until the QH completes or the transaction time-out.
+//
+// Input: HcStruc - Pointer to HCStruc of the host controller
+// XferQh - Pointer to the QH which has to be completed
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+EhciExexuteAsyncSchedule(
+ HC_STRUC *HcStruc,
+ EHCI_QH *XferQh
+)
+{
+ UINT16 Status = USB_SUCCESS;
+ UINT32 Count;
+ UINT32 TimeOut = gUsbData->wTimeOutValue * 100; // in 10 macrosecond unit
+//
+//#if EHCI_ASYNC_BELL_SUPPORT
+// UINT32 Tmp;
+
+// XferQh->dLinkPointer = EHCI_TERMINATE;
+// XferQh->bActive = TRUE;
+
+ //
+ // Insert the Control/Bulk QH into the Async list
+ //
+// Tmp = gUsbData->fpQHAsyncXfer->dLinkPointer;
+// gUsbData->fpQHAsyncXfer->dLinkPointer = (UINT32)XferQh | EHCI_QUEUE_HEAD;
+// XferQh->dLinkPointer = Tmp;
+//#else
+ //
+ // Set the ASYNCLISTADDR register to point to the Control/Bulk QH
+ //
+ EhciWriteOpReg(HcStruc, EHCI_ASYNCLISTADDR, (UINT32)(UINTN)XferQh);
+
+ //
+ // Set next QH pointer to itself (circular link)
+ //
+ XferQh->dLinkPointer = (UINT32)((UINTN)XferQh | EHCI_QUEUE_HEAD);
+ XferQh->bActive = TRUE;
+//#endif
+
+ //
+ // Now put the Control/Bulk QH into the HC's schedule by
+ // setting the Async. schedule enabled field of USBCMD register
+ // This will cause the HC to execute the transaction in the next active frame.
+ //
+ Status = EHCIStartAsyncSchedule(HcStruc);
+
+ if (Status == USB_ERROR) {
+ return Status;
+ }
+
+ // Wait for tansfer complete
+ for(Count = 0; !TimeOut || Count < TimeOut; Count++) {
+ EHCIProcessQH(HcStruc, XferQh);
+ if(XferQh->bActive == FALSE) {
+ break;
+ }
+ FixedDelay(10); // 10 microsec
+ }
+
+//#if EHCI_ASYNC_BELL_SUPPORT
+ //
+ // Disconnect Control/Bulk QH from the Async list
+ //
+// EHCIRemoveQHFromAsyncList(HcStruc, XferQh);
+//#else
+ //
+ // Stop the Async transfer
+ //
+ EHCIStopAsyncSchedule(HcStruc);
+//#endif
+
+ if(XferQh->bActive == TRUE) {
+ XferQh->bActive = FALSE;
+ Status = USB_ERROR;
+ USB_DEBUG (DEBUG_LEVEL_3, "EHCI Time-Out\n");
+ }
+
+ // Service all interrupts
+ EHCI_ProcessInterrupt(HcStruc);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_ControlTransfer
+//
+// Description: This function executes a device request command transaction
+// on the USB. One setup packet is generated containing the
+// device request parameters supplied by the caller. The setup
+// packet may be followed by data in or data out packets
+// containing data sent from the host to the device
+// or vice-versa. This function will not return until the
+// request either completes successfully or completes in error
+// (due to time out, etc.)
+//
+// Parameters: fpHCStruc Pointer to HCStruc of the host controller
+// pDevInfo DeviceInfo structure (if available else 0)
+// wRequest Request type (low byte)
+// Bit 7 : Data direction
+// 0 = Host sending data to device
+// 1 = Device sending data to host
+// Bit 6-5 : Type
+// 00 = Standard USB request
+// 01 = Class specific
+// 10 = Vendor specific
+// 11 = Reserved
+// Bit 4-0 : Recipient
+// 00000 = Device
+// 00001 = Interface
+// 00010 = Endpoint
+// 00100 - 11111 = Reserved
+// Request code, a one byte code describing
+// the actual device request to be executed
+// (ex: Get Configuration, Set Address etc)
+// wIndex wIndex request parameter (meaning varies)
+// wValue wValue request parameter (meaning varies)
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// wLength wLength request parameter, number of bytes
+// of data to be transferred in or out
+// of the host controller
+//
+//
+// Output: Number of bytes actually transferred
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+EHCI_ControlTransfer (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT16 wRequest,
+ UINT16 wIndex,
+ UINT16 wValue,
+ UINT8 *fpBuffer,
+ UINT16 wLength)
+{
+ UINT32 dTmp, dTmp1;
+ UINT16 wRetCode = 0; // Initialize with error
+ EHCI_QH *fpQHCtl;
+ EHCI_QTD *fpQTDCtlSetup, *fpQTDCtlData, *fpQTDCtlStatus;
+ DEV_REQ *fpRequest = NULL;
+ UINT8 bEndpointSpeed;
+ UINT8 *BufPhyAddr = NULL;
+ VOID *BufferMapping = NULL;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ if (wLength != 0) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Ehci ControlTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (EhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ if( !VALID_DEVINFO( fpDevInfo) )
+ return 0;
+
+ gUsbData->dLastCommandStatusExtended = 0; //(EIP84790+)
+
+//USB_DEBUG(DEBUG_LEVEL_3, "EHCI_ControlTransfer..\n");
+ //
+ // Build the device request in the data area of the control setup qTD
+ //
+ fpRequest = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT(sizeof(DEV_REQ)));
+ ASSERT(fpRequest);
+ if (fpRequest == NULL) {
+ return 0;
+ }
+
+ fpRequest->wRequestType = wRequest;
+ fpRequest->wIndex = wIndex;
+ fpRequest->wValue = wValue;
+ fpRequest->wDataLength = wLength;
+
+//
+// The QH endpoint characteristic field will be set so
+// Function address & Endpoint number = From DeviceInfo structure,
+// Direction = From TD,
+// Speed = DeviceInfo.bEndpointSpeed,
+// Skip = 1, Format = 0,
+// Max packet size = DeviceInfo.wEndp0MaxPacket
+// The dNextqTDPtr field will be set to qTDControlSetup
+// The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+// The dCurrentqTDPtr field will be set to 0
+//
+ //
+ // Intialize the queue head with null pointers
+ //
+ //(EIP71067)>
+ fpQHCtl = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT((1 * sizeof(EHCI_QH))+
+ (3 * sizeof(EHCI_QTD))));
+ //(EIP83295+)>
+ if(!fpQHCtl) {
+ return 0;
+ }
+ //<(EIP83295+)
+ //(EIP81030)>
+ fpQTDCtlSetup = (EHCI_QTD*)((UINTN)fpQHCtl + sizeof(EHCI_QH));
+ fpQTDCtlData = (EHCI_QTD*)((UINTN)fpQTDCtlSetup + sizeof(EHCI_QTD));
+ fpQTDCtlStatus = (EHCI_QTD*)((UINTN)fpQTDCtlData + sizeof(EHCI_QTD));
+ //<(EIP71067)
+ //<EIP81030)
+ EHCIInitializeQueueHead(fpQHCtl);
+
+ bEndpointSpeed = fpDevInfo->bEndpointSpeed; // 00/01/10 for HI/LO/FULL
+
+ //
+ // Assume as a high speed device
+ //
+ dTmp = QH_HIGH_SPEED; // 10b - High speed
+
+ //
+ // Check for high speed
+ //
+ if (bEndpointSpeed) // Low/Full speed device
+ {
+ dTmp = ((UINT32)bEndpointSpeed & 1) << 12; // Bit 12 = full/low speed flag
+ dTmp |= QH_CONTROL_ENDPOINT;
+ //
+ // Set the hub address and port number
+ // Get the Hispeed hub port number & device number
+ //
+ dTmp1 = (UINT32)EHCI_GetHiSpeedHubPortNumber(fpDevInfo);
+ dTmp1 = (dTmp1 << 16); // Split complete Xaction
+ fpQHCtl->dEndPntCap |= dTmp1;
+ }
+
+//USB_DEBUG(DEBUG_LEVEL_3, "Tmp1..%x\n", dTmp);
+
+ //
+ // Use data toggle from qTD and this QH is the head of the queue
+ //
+//#if EHCI_ASYNC_BELL_SUPPORT
+// dTmp |= QH_USE_QTD_DT;
+//#else
+ dTmp |= QH_USE_QTD_DT;
+ // Do not set QH_HEAD_OF_LIST bit on VIA controller
+ if (fpHCStruc->Vid != 0x1106) {
+ dTmp |= QH_HEAD_OF_LIST;
+ }
+//#endif
+ dTmp |= (UINT32)fpDevInfo->bDeviceAddress;
+ //
+ // dTmp[Bits 6:0] = Dev. Addr
+ // dTmp[Bit7] = I bit(0)
+ // dTmp[Bits11:8] = Endpoint (0)
+ //
+
+ dTmp1 = (UINT32)fpDevInfo->wEndp0MaxPacket;
+ dTmp |= (dTmp1 << 16); // Tmp[Bits26:16] = device's packet size
+ fpQHCtl->dEndPntCharac = dTmp;
+
+ //
+ // Fill in various fields in the qTDControlSetup.
+ //
+ //fpQTDCtlSetup = fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpqTDControlSetup; //(EIP71067-)
+
+ //
+ // The token field will be set so
+ // Direction PID = QTD_SETUP_TOKEN,
+ // Size = size of the data,
+ // Data Toggle = QTD_SETUP_TOGGLE,
+ // Error Count = QTD_THREE_ERRORS,
+ // Status code = QTD_DO_OUT + QTD_ACTIVE
+ // The buffer pointers field will point to the aControlSetupData buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The dNextqTDPtr field will point to the qTDControlData if data will
+ // be sent/received or to the qTDControlStatus if no data is expected.
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ fpQTDCtlSetup->dToken = QTD_SETUP_TOKEN |
+ QTD_SETUP_TOGGLE | QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_DO_OUT | QTD_ACTIVE |
+ (8 << 16); // Data size
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(fpQTDCtlSetup, (UINT8*)fpRequest, 8);
+ //fpQTDCtlData = fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpqTDControlData; //(EIP71067-)
+
+ if (wLength) // br if no data to transfer
+ {
+ //
+ // Fill in various fields in the qTDControlData
+ //
+ // The token field will be set so
+ // Direction PID = QTD_OUT_TOKEN/QTD_IN_TOKEN,
+ // Size = size of the data,
+ // Data Toggle = QTD_DATA1_TOGGLE,
+ // Error Count = QTD_THREE_ERRORS,
+ // Status code = QTD_DO_OUT(if it is out) + QTD_ACTIVE
+ // The buffer pointers field will point to the fpBuffer buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The dNextqTDPtr field will point to the qTDControlSetup
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ fpQTDCtlData->dToken = QTD_IN_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_ACTIVE;
+ if (!(wRequest & BIT7)) // Br if host sending data to device (OUT)
+ {
+ fpQTDCtlData->dToken = QTD_OUT_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_DO_OUT | QTD_ACTIVE;
+ }
+
+ //
+ // Set length
+ //
+ fpQTDCtlData->dToken |= ((UINT32)wLength << 16);
+
+ EhciDmaMap(fpHCStruc, (UINT8)(wRequest & BIT7), fpBuffer, wLength,
+ &BufPhyAddr, &BufferMapping);
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(fpQTDCtlData,
+ (UINT8*)BufPhyAddr,
+ (UINT32)wLength);
+ }
+
+ //
+ // Fill in various fields in the qTDControlStatus
+ //
+ //fpQTDCtlStatus = fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpqTDControlStatus; //(EIP71067-)
+
+ //
+ // The token field will be set so
+ // Direction PID = QTD_OUT_TOKEN/QTD_IN_TOKEN,
+ // Size = 0,
+ // Data Toggle = QTD_DATA1_TOGGLE,
+ // Error Count = QTD_THREE_ERRORS,
+ // Status code = QTD_DO_OUT(if it is out) + QTD_ACTIVE
+ // The buffer pointers field will be 0
+ // The dNextqTDPtr field will set to EHCI_TERMINATE
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ // For OUT control transfer status should be IN and
+ // for IN cotrol transfer, status should be OUT
+ //
+ fpQTDCtlStatus->dToken = QTD_IN_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_ACTIVE;
+ if(wRequest & BIT7)
+ {
+ fpQTDCtlStatus->dToken = QTD_OUT_TOKEN |
+ QTD_DATA1_TOGGLE | QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_DO_OUT | QTD_ACTIVE;
+ }
+
+ EHCISetQTDBufferPointers(fpQTDCtlStatus, NULL, 0);
+
+ //
+ // Link the qTD formed now and connect them with the control queue head
+ //
+ fpQHCtl->fpFirstqTD = fpQTDCtlSetup;
+ fpQHCtl->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlSetup;
+
+ if(wLength)
+ {
+ fpQTDCtlSetup->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlData;
+ fpQTDCtlData->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlStatus;
+ }
+ else
+ {
+ fpQTDCtlSetup->dNextqTDPtr = (UINT32)(UINTN)fpQTDCtlStatus;
+ }
+
+ fpQTDCtlStatus->dNextqTDPtr = EHCI_TERMINATE;
+
+ wRetCode = EhciExexuteAsyncSchedule(fpHCStruc, fpQHCtl);
+ fpQHCtl->fpFirstqTD = 0;
+ fpQHCtl->dNextqTDPtr = EHCI_TERMINATE;
+
+ if (wLength) {
+ EhciDmaUnmap(fpHCStruc, BufferMapping);
+ wLength = wLength - (UINT16)((fpQTDCtlData->dToken & ~(QTD_DATA_TOGGLE)) >> 16);
+ }
+
+ //
+ // Clear the stalled condition flag
+ //
+ gUsbData->bLastCommandStatus &= ~USB_CONTROL_STALLED;
+
+ //
+ // Check whether the QH stopped or timed out
+ //
+ if (wRetCode != USB_SUCCESS) {
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT; //(EIP84790+)
+ wLength = 0; //(EIP71067)
+ }
+
+ if (fpQHCtl->bErrorStatus & QTD_HALTED) {
+ //
+ // Command stalled set the error bit appropriately
+ //
+ gUsbData->bLastCommandStatus |= USB_CONTROL_STALLED;
+ wLength = 0; //(EIP71067)
+ }
+ //(EIP71067+)>
+ EhciMemFree(fpHCStruc, fpQHCtl, GET_MEM_BLK_COUNT((1 * sizeof(EHCI_QH))+
+ (3 * sizeof(EHCI_QTD))));
+ //<(EIP71067+)
+ EhciMemFree(fpHCStruc, fpRequest, GET_MEM_BLK_COUNT(sizeof(DEV_REQ)));
+
+ return wLength;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_BulkTransfer
+//
+// Description: This function executes a bulk transaction on the USB. The
+// transfer may be either DATA_IN or DATA_OUT packets containing
+// data sent from the host to the device or vice-versa. This
+// function wil not return until the request either completes
+// successfully or completes with error (due to time out, etc.)
+// NOTE: Make sure that amount of bytes to transfer should not
+// exceed MAX_EHCI_DATA_SIZE
+//
+// Parameters: pHCStruc Pointer to HCStruc of the host controller
+// pDevInfo DeviceInfo structure (if available else 0)
+// bXferDir Transfer direction
+// Bit 7: Data direction
+// 0 Host sending data to device
+// 1 Device sending data to host
+// Bit 6-0 : Reserved
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// value in Segment:Offset format
+// dwLength dwLength request parameter, number of bytes
+// of data to be transferred in or out
+// of the host controller
+//
+// Output: Amount of data transferred
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+EHCI_BulkTransfer(
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 bXferDir,
+ UINT8 *fpBuffer,
+ UINT32 dwLength)
+{
+ UINT16 wMaxPkt;
+ UINT8 bEndp, bDatToggle;
+ EHCI_QH *fpQHBulk;
+ EHCI_QTD *fpQTDBulkData;
+ UINT32 dTmp, dTmp1;
+ UINT16 Status;
+ UINT32 dBytesToTransfer, dBytesRemaining;
+ UINT32 dBytesTransferred;
+ UINT8 *BufPhyAddr = NULL;
+ VOID *BufferMapping = NULL;
+ UINT8 *TempBuffer = NULL;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, dwLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Ehci BulkTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (EhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ if (!VALID_DEVINFO(fpDevInfo)) {
+ return 0;
+ }
+
+ // Realtek 8111EP EHCI controller workaround
+ // The controller doesn't work if the buffer address isn't DWORD alignment
+ // (current offset of qTD). Provide the workaround to locate DWORD alignment buffer.
+
+ if ((fpHCStruc->Vid == 0x10EC) && (fpHCStruc->Did == 0x816D)) {
+ if ((UINTN)fpBuffer & (BIT0 | BIT1)) {
+ if (dwLength < HIGHSPEED_MAX_BULK_DATA_SIZE) {
+ TempBuffer = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT((UINT16)dwLength));
+ } else {
+ TempBuffer = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT(HIGHSPEED_MAX_BULK_DATA_SIZE));
+ }
+ }
+ }
+
+ //clear HW source of error
+ gUsbData->dLastCommandStatusExtended = 0;
+
+
+ dBytesRemaining = dwLength;
+ dBytesTransferred = 0;
+
+ //
+ // Get Bulk IN/OUT enpoint number, data sync value & max packet size
+ //
+ if (bXferDir & BIT7)
+ {
+ wMaxPkt = fpDevInfo->wBulkInMaxPkt;
+ bEndp = fpDevInfo->bBulkInEndpoint;
+ }
+ else
+ {
+ wMaxPkt = fpDevInfo->wBulkOutMaxPkt;
+ bEndp = fpDevInfo->bBulkOutEndpoint;
+ }
+ if( wMaxPkt == 0){
+ return 0;
+ }
+ //(EIP71067+)>
+ fpQHBulk = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT((1 * sizeof(EHCI_QH))+
+ (1 * sizeof(EHCI_QTD))));
+ //(EIP83295+)>
+ if(!fpQHBulk) {
+ return 0;
+ }
+ //<(EIP83295+)
+ fpQTDBulkData = (EHCI_QTD*)((UINTN)fpQHBulk + sizeof(EHCI_QH)); //(EIP81030)
+ //<(EIP71067+)
+ EhciDmaMap(fpHCStruc, bXferDir, fpBuffer, dwLength, &BufPhyAddr, &BufferMapping);
+
+ while (dBytesRemaining) {
+ dBytesToTransfer =
+ (dBytesRemaining < HIGHSPEED_MAX_BULK_DATA_SIZE)?
+ dBytesRemaining : HIGHSPEED_MAX_BULK_DATA_SIZE;
+
+ //
+ // Get data toggle value
+ //
+ bDatToggle = UsbGetDataToggle(fpDevInfo, bEndp | bXferDir);
+
+ //
+ // Set the QH's dNextqTDPtr field to bulk data qTD and dAltqTDPtr field to
+ // EHCI_TERMINATE. Also set QH's link pointer to itself
+ //
+ //(EIP71067-)>
+ //fpQHBulk = fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpQHBulk;
+ //fpQTDBulkData = fpHCStruc->stDescPtrs.fpEHCIDescPtrs->fpqTDBulkData;
+ //<(EIP71067-)
+ //
+ // Intialize the queue head
+ //
+ EHCIInitializeQueueHead(fpQHBulk);
+
+ //
+ // Set the first qTD pointer
+ //
+ fpQHBulk->fpFirstqTD = fpQTDBulkData;
+ fpQHBulk->dNextqTDPtr = (UINT32)(UINTN)fpQTDBulkData;
+ fpQHBulk->dLinkPointer = (UINT32)((UINTN)fpQHBulk | EHCI_QUEUE_HEAD);
+
+ //
+ // Device address & Endpoint
+ //
+ dTmp = (UINT32)(fpDevInfo->bDeviceAddress | (bEndp << 8));
+
+ //
+ // Set max packet size
+ //
+ dTmp = dTmp | ((UINT32)wMaxPkt << 16);
+
+ //
+ // Set the data toggle control
+ //
+// #if EHCI_ASYNC_BELL_SUPPORT
+// dTmp |= QH_USE_QTD_DT;
+// #else
+ dTmp |= QH_USE_QTD_DT;
+ // Do not set QH_HEAD_OF_LIST bit on VIA controller
+ if (fpHCStruc->Vid != 0x1106) {
+ dTmp |= QH_HEAD_OF_LIST;
+ }
+// #endif
+
+ //
+ // Set the device speed
+ // Reset the device speed bits
+ //
+ dTmp1 = (UINT32)fpDevInfo->bEndpointSpeed; // 00/01/10 for HI/LO/FULL
+
+ //
+ // Assume as a high speed device
+ //
+ dTmp |= QH_HIGH_SPEED; // 10b - High speed
+
+ //
+ // Check for high speed
+ //
+ if (dTmp1)
+ {
+ dTmp1 = (dTmp1 & 1) << 12; // Bit 12 = full/low speed flag
+ dTmp &= ~(QH_ENDPOINT_SPEED);
+ dTmp |= dTmp1;
+ //
+ // Set the hub address and port number
+ //
+ dTmp1 = (UINT32)EHCI_GetHiSpeedHubPortNumber(fpDevInfo);
+ dTmp1 = (dTmp1 << 16); // Hispeed hub port number & device number
+ fpQHBulk->dEndPntCap |= dTmp1; // Split complete Xaction
+ }
+
+ //
+ // Update the endpoint characteristcs field with the data formed
+ //
+ fpQHBulk->dEndPntCharac = dTmp;
+
+ //
+ // Fill the bulk data qTD with relevant information
+ // The token field will be set so
+ // Direction PID = QTD_OUT_TOKEN/QTD_IN_TOKEN,
+ // Size = size of the data,
+ // Data Toggle = bDatToggle,
+ // Error Count = QTD_THREE_ERRORS,
+ // Status code = QTD_DO_OUT(if it is out) + QTD_ACTIVE
+ // The buffer pointers field will point to the fpBuffer buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The dNextqTDPtr field will point to the qTDControlSetup
+ // The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+ //
+ if (bXferDir & BIT7) {
+ fpQTDBulkData->dToken = QTD_IN_TOKEN |
+ QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_ACTIVE;
+ } else {
+ fpQTDBulkData->dToken = QTD_OUT_TOKEN |
+ QTD_IOC_BIT |
+ QTD_THREE_ERRORS | QTD_DO_OUT | QTD_ACTIVE;
+ if (TempBuffer != NULL) {
+ MemCpy(BufPhyAddr, TempBuffer, dBytesToTransfer);
+ }
+ }
+
+ //
+ // Set the data toggle depending on the bDatToggle value
+ //
+ fpQTDBulkData->dToken |= (UINT32)bDatToggle << 31;
+
+ //
+ // Set length
+ //
+ fpQTDBulkData->dToken |= (dBytesToTransfer << 16);
+
+ //
+ // Update buffer pointers
+ //
+ if (TempBuffer != NULL) {
+ EHCISetQTDBufferPointers(fpQTDBulkData, TempBuffer, dBytesToTransfer);
+ } else {
+ EHCISetQTDBufferPointers(fpQTDBulkData, BufPhyAddr, dBytesToTransfer);
+ }
+
+ //
+ // Update next & alternate next qTD pointers
+ //
+ fpQTDBulkData->dNextqTDPtr = EHCI_TERMINATE;
+ fpQTDBulkData->dAltNextqTDPtr = EHCI_TERMINATE;
+
+ fpQHBulk->bActive = TRUE;
+
+
+ //
+ // Set bulk condition as not stalled
+ //
+ gUsbData->bLastCommandStatus &= ~(USB_BULK_STALLED + USB_BULK_TIMEDOUT);
+
+ //
+ // Now wait for bulk transaction to be complete
+ // the EHCIProcessInterrupt will set its active flag to FALSE.
+ // Now wait for the bulk transfer to complete
+ //
+ Status = EhciExexuteAsyncSchedule(fpHCStruc, fpQHBulk);
+
+ fpQHBulk->fpFirstqTD = 0;
+ fpQHBulk->dNextqTDPtr = EHCI_TERMINATE;
+
+ if (Status != USB_SUCCESS) {
+ //
+ // Set time out status
+ //
+ gUsbData->bLastCommandStatus |= USB_BULK_TIMEDOUT;
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ break;
+ }
+
+ if (fpQHBulk->bErrorStatus & QTD_HALTED) {
+ //
+ // Stall condition
+ //
+ gUsbData->bLastCommandStatus &= ~(USB_BULK_TIMEDOUT);
+ gUsbData->bLastCommandStatus |= USB_BULK_STALLED;
+ gUsbData->dLastCommandStatusExtended |= USB_TRSFR_STALLED;
+ break;
+ }
+
+ //
+ // Update the data toggle value into the mass info structure
+ //
+ bDatToggle =
+ (UINT8)(((fpQHBulk->dToken & QH_DATA_TOGGLE) >> 31) & 1);
+ UsbUpdateDataToggle(fpDevInfo, bEndp | bXferDir, bDatToggle);
+
+ //
+ // Get the size of data transferred
+ //
+ dTmp = (fpQTDBulkData->dToken & ~(QTD_DATA_TOGGLE)) >> 16;
+ dTmp = (dTmp)? dBytesToTransfer-dTmp : dBytesToTransfer;
+
+ if (!dTmp) {
+ break;
+ }
+
+ if (TempBuffer != NULL) {
+ if (bXferDir & BIT7) {
+ MemCpy(TempBuffer, BufPhyAddr, dTmp);
+ }
+ }
+
+ //
+ // Adjust loop variables
+ //
+ dBytesRemaining = dBytesRemaining - dTmp;
+ dBytesTransferred += dTmp;
+
+ if (dTmp < dBytesToTransfer) {
+ break;
+ }
+
+ BufPhyAddr += dTmp;
+ }
+
+ EhciDmaUnmap(fpHCStruc, BufferMapping);
+ //(EIP71067+)>
+ EhciMemFree(fpHCStruc, fpQHBulk, GET_MEM_BLK_COUNT( (1 * sizeof(EHCI_QH)) +
+ (1 * sizeof(EHCI_QTD))));
+ //<(EIP71067+)
+ if (TempBuffer != NULL) {
+ if (dwLength < HIGHSPEED_MAX_BULK_DATA_SIZE) {
+ EhciMemFree(fpHCStruc, TempBuffer, GET_MEM_BLK_COUNT((UINT16)dwLength));
+ } else {
+ EhciMemFree(fpHCStruc, TempBuffer, GET_MEM_BLK_COUNT(HIGHSPEED_MAX_BULK_DATA_SIZE));
+ }
+ }
+
+ return dBytesTransferred;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_InterruptTransfer
+//
+// Description: This function executes an interrupt transaction on the USB.
+// The data transfer direction is always DATA_IN. This
+// function wil not return until the request either completes
+// successfully or completes in error (due to time out, etc.)
+//
+// Parameters: fpHCStruc Pointer to HCStruc of the host controller
+// fpDevInfo DeviceInfo structure (if available else 0)
+// EndpointAddress The destination USB device endpoint to which the device request
+// is being sent.
+// MaxPktSize Indicates the maximum packet size the target endpoint is capable
+// of sending or receiving.
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// wLength wLength request parameter, number of bytes
+// of data to be transferred in
+//
+// Output: Number of bytes transferred
+//
+//
+// Notes: DO NOT TOUCH THE LINK POINTER OF THE TDInterruptData. It is
+// statically allocated and linked with other items in the
+// 1ms schedule
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+EHCI_InterruptTransfer (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 EndpointAddress,
+ UINT16 MaxPktSize,
+ UINT8 *fpBuffer,
+ UINT16 wLength
+)
+{
+
+ UINT8 bDatToggle;
+ EHCI_QH *fpQHInt;
+ UINT32 dTmp, dTmp1;
+ EHCI_QTD *fpqTDIntData;
+ UINT32 Count;
+ UINT32 Timeout;
+ UINT32 BytesTransferred;
+ UINT8 *BufPhyAddr = NULL;
+ VOID *BufferMapping = NULL;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Ehci InterruptTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (EhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ bDatToggle = UsbGetDataToggle(fpDevInfo, EndpointAddress);
+
+ //
+ // Get the QHInterrupt pointer
+ //
+ fpQHInt = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT((1 * sizeof(EHCI_QH))+
+ (1 * sizeof(EHCI_QTD))));
+ if (fpQHInt == NULL) {
+ return 0;
+ }
+
+ fpqTDIntData = (EHCI_QTD*)((UINTN)fpQHInt + sizeof(EHCI_QH));
+
+ //
+ // Intialize the queue head
+ //
+ EHCIInitializeQueueHead(fpQHInt);
+
+ //
+ // Set the first qTD pointer
+ //
+ fpQHInt->fpFirstqTD = fpqTDIntData;
+ fpQHInt->dNextqTDPtr = (UINT32)(UINTN)fpqTDIntData;
+ fpQHInt->dLinkPointer = EHCI_TERMINATE;
+
+ //
+ // Get Device address & Endpoint
+ //
+ dTmp = (UINT32)fpDevInfo->bDeviceAddress;
+ dTmp |= (UINT32)(EndpointAddress & 0xF) << 8;
+
+ //
+ // Set max packet size
+ //
+ dTmp |= (UINT32)(MaxPktSize) << 16;
+
+ //
+ // Set the device speed, reset the device speed bits
+ //
+ dTmp1 = (UINT32)fpDevInfo->bEndpointSpeed; // 00/01/10 for HI/LO/FULL
+
+ //
+ // Assume as a high speed device
+ //
+ dTmp |= QH_HIGH_SPEED; // 10b - High speed
+
+ //
+ // Check for high speed
+ //
+ if (dTmp1)
+ {
+ dTmp1 = (dTmp1 & 1) << 12; // Bit 12 = full/low speed flag
+ dTmp &= ~(QH_ENDPOINT_SPEED);
+ dTmp |= dTmp1;
+ //
+ // Set the hub address and port number
+ //
+ dTmp1 = (UINT32)EHCI_GetHiSpeedHubPortNumber(fpDevInfo);
+ dTmp1 = (dTmp1 << 16) | BIT10 | BIT11 | BIT12;
+ fpQHInt->dEndPntCap |= dTmp1; // Split complete Xaction
+ }
+ //
+ // Update the endpoint characteristcs field with the data formed
+ //
+ fpQHInt->dEndPntCharac = dTmp;
+ fpQHInt->dEndPntCap |= (BIT0 | QH_ONE_XFER); // Interrupt schedule mask
+ fpQHInt->Interval = EhciTranslateInterval(fpDevInfo->bEndpointSpeed,
+ fpDevInfo->bPollInterval);
+
+ //
+ // Set the data toggle depending on the bDatToggle value
+ //
+ fpQHInt->dToken |= (UINT32)bDatToggle << 31;
+
+//
+// Fill the interrupt data qTD with relevant information
+// The token field will be set so
+// Direction PID = QTD_IN_TOKEN,
+// Size = size of the data,
+// Data Toggle = bDatToggle,
+// Error Count = QTD_THREE_ERRORS,
+// Status code = QTD_ACTIVE
+// The buffer pointers field will point to the EDX
+// which was before initialized to contain a DeviceRequest struc.
+// The dNextqTDPtr field will point to the qTDControlSetup
+// The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+//
+ fpqTDIntData->dToken = QTD_IOC_BIT | QTD_THREE_ERRORS | QTD_ACTIVE;
+ if (EndpointAddress & BIT7) {
+ fpqTDIntData->dToken |= QTD_IN_TOKEN;
+ } else {
+ fpqTDIntData->dToken |= QTD_OUT_TOKEN;
+ }
+
+ //
+ // Set length
+ //
+ fpqTDIntData->dToken |= (UINT32)wLength << 16;
+
+ EhciDmaMap(fpHCStruc, EndpointAddress & BIT7, fpBuffer, wLength,
+ &BufPhyAddr, &BufferMapping);
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(fpqTDIntData, BufPhyAddr, (UINT32)wLength);
+
+ //
+ // Update next & alternate next qTD pointers
+ //
+ fpqTDIntData->dNextqTDPtr = EHCI_TERMINATE;
+ fpqTDIntData->dAltNextqTDPtr = EHCI_TERMINATE;
+
+ //
+ // Schedule the QHInterrupt to 1msec schedule
+ //
+ EhciAddPeriodicQh(fpHCStruc,fpQHInt);
+
+ // Set the QH as active
+ fpQHInt->bActive = TRUE;
+
+ //
+ // Now wait for interrupt transaction to be complete;
+ // the EHCIProcessInterrupt will set its active flag to FALSE.
+ //
+ Timeout = gUsbData->wTimeOutValue * 100; // makes it number of 10 macrosecond units
+
+ for (Count = 0; Timeout == 0 || Count < Timeout; Count++) {
+ if (!(fpqTDIntData->dToken & QTD_ACTIVE)) {
+ break;
+ }
+ FixedDelay(10); // 60 microsec
+ }
+ //Status = EHCIWaitForTransferComplete(fpHCStruc, fpQHInt, fpDevInfo);
+
+ // Remove the QH from periodic schedule
+ EhciRemovePeriodicQh(fpHCStruc,(EHCI_QH*)fpQHInt);
+
+ //
+ // Check whether the QH stopped or timed out
+ //
+ BytesTransferred = 0;
+ if (fpqTDIntData->dToken & QTD_ACTIVE) {
+ USB_DEBUG (DEBUG_LEVEL_3, "EHCI Time-Out\n");
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ } else if (fpqTDIntData->dToken & QTD_HALTED) {
+ gUsbData->dLastCommandStatusExtended |= USB_TRSFR_STALLED;
+ } else {
+ BytesTransferred = (UINT16)(wLength - ((fpqTDIntData->dToken &
+ ~(QTD_DATA_TOGGLE)) >> 16));
+ //
+ // Update the data toggle value into the mass info structure
+ //
+ bDatToggle = (UINT8)(((fpQHInt->dToken & QH_DATA_TOGGLE) >> 31) & 1);
+ UsbUpdateDataToggle(fpDevInfo, EndpointAddress, bDatToggle);
+ }
+
+ EhciDmaUnmap(fpHCStruc, BufferMapping);
+
+ // Free the allocated QH and qTD
+ EhciMemFree(fpHCStruc, fpQHInt, GET_MEM_BLK_COUNT((1 * sizeof(EHCI_QH)) +
+ (1 * sizeof(EHCI_QTD))));
+
+ // Service all interrupts
+ EHCI_ProcessInterrupt(fpHCStruc);
+
+ return (UINT16)BytesTransferred;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_DeactivatePolling
+//
+// Description: This function de-activates the polling QH for the requested
+// device. The device may be a USB keyboard or USB hub
+//
+// Input: fpHCStruc - Pointer to the HC structure
+// fpDevInfo - Pointer to the device information structure
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_DeactivatePolling(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo)
+{
+ UINT8 *fpPollED;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (EhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ //
+ // Get a pointer to the device's QH from the poll QH pointer and remove
+ // the polling ED from the schedule
+ //
+ fpPollED = fpDevInfo->fpPollEDPtr;
+ if(!fpPollED) return USB_ERROR;
+
+ ((EHCI_QH*)fpPollED)->bActive = FALSE;
+
+ EhciRemovePeriodicQh(fpHCStruc,(EHCI_QH*)fpPollED);
+
+ UsbUpdateDataToggle(fpDevInfo, fpDevInfo->IntInEndpoint,
+ (UINT8)((((EHCI_QH*)fpPollED)->dToken & QH_DATA_TOGGLE) >> 31));
+
+ EhciMemFree(fpHCStruc, fpPollED, GET_MEM_BLK_COUNT(sizeof(EHCI_QH)+sizeof(EHCI_QTD)));
+ fpDevInfo->fpPollEDPtr = NULL;
+ fpDevInfo->fpPollTDPtr = NULL;
+
+ if(fpDevInfo->fpPollDataBuffer) {
+ EhciMemFree(fpHCStruc, fpDevInfo->fpPollDataBuffer,
+ GET_MEM_BLK_COUNT(fpDevInfo->PollingLength));
+ fpDevInfo->fpPollDataBuffer = 0;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCI_ActivatePolling
+//
+// Description: This function activates the polling QH for the requested
+// device. The device may be a USB keyboard or USB hub
+//
+// Input: fpHCStruc - Pointer to the HC structure
+// fpDevInfo - Pointer to the device information structure
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+// Notes: For the keyboard device this routine allocates TDRepeat
+// also, if it is not already allocated. This routine allocate
+// a polling TD and schedule it to 8ms schedule for keyboards
+// and to 1024ms schedule for hubs.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_ActivatePolling(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo)
+{
+ EHCI_QH *fpPollED;
+ EHCI_QTD *fpPollTD;
+ UINT32 dTmp, dTmp1;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ USB_DEBUG (DEBUG_LEVEL_3, "EHCI_AP dev type %d\n", fpDevInfo->bDeviceType);
+
+ if (EhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ //
+ // Allocate a QH/qTD for polling QH & qTD
+ //
+ fpPollED = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT(
+ sizeof(EHCI_QH)+sizeof(EHCI_QTD)));
+ if (!fpPollED)
+ {
+ return USB_ERROR; // Memory allocation error
+ }
+
+ //
+ // Save the pointers in DeviceInfo structure
+ //
+ fpDevInfo->fpPollEDPtr = (UINT8*)fpPollED;
+ fpPollTD = (EHCI_QTD*)((UINTN)fpPollED + sizeof(EHCI_QH));
+ fpDevInfo->fpPollTDPtr = (UINT8*)fpPollTD;
+
+//
+// Setup the polling QH
+// Set the QH's dNextqTDPtr field to polling qTD and dAltqTDPtr field to
+// EHCI_TERMINATE
+//
+
+ fpPollED->fpFirstqTD = fpPollTD;
+ fpPollED->dNextqTDPtr = (UINT32)(UINTN)fpPollTD;
+
+ //
+ // Intialize the queue head
+ //
+ fpPollED->dAltNextqTDPtr = EHCI_TERMINATE;
+ fpPollED->dLinkPointer = EHCI_TERMINATE;
+
+ //
+ // Set the device info pointer in the QH
+ //
+ fpPollED->fpDevInfoPtr = (UINT8*)fpDevInfo;
+
+ //
+ // Get Device address & Endpoint
+ //
+ dTmp = ((UINT32)fpDevInfo->bDeviceAddress) |
+ ((UINT32)(fpDevInfo->IntInEndpoint & 0xF) << 8);
+
+ dTmp |= ((UINT32)fpDevInfo->IntInMaxPkt) << 16; // Set max packet size //(EIP54782)
+
+ dTmp1 = (UINT32)fpDevInfo->bEndpointSpeed; // 00/01/10 for HI/LO/FULL
+
+ //
+ // Assume as a high speed device
+ //
+ dTmp |= QH_HIGH_SPEED; // 10b - High speed
+
+ //
+ // Check for high speed
+ //
+ if (dTmp1)
+ {
+ dTmp1 = (dTmp1 & 1) << 12; // Bit 12 = full/low speed flag
+ dTmp &= ~(QH_ENDPOINT_SPEED);
+ dTmp |= dTmp1;
+ //
+ // Set the hub address and port number
+ //
+ dTmp1 = (UINT32)EHCI_GetHiSpeedHubPortNumber(fpDevInfo);
+ dTmp1 = (dTmp1 << 16) | (BIT10 + BIT11 + BIT12); // Split complete Xaction
+ fpPollED->dEndPntCap |= dTmp1;
+ }
+
+ //
+ // Update the endpoint characteristcs field with the data formed
+ //
+ fpPollED->dEndPntCharac = dTmp;
+
+ //
+ // Set a bit in interrupt mask
+ //
+ fpPollED->dEndPntCap |= (BIT0 + QH_ONE_XFER);
+ fpPollED->Interval = EhciTranslateInterval(fpDevInfo->bEndpointSpeed,
+ fpDevInfo->bPollInterval);
+
+ //
+ // Set the data toggle
+ //
+ fpPollED->dToken |= (UINT32)(UsbGetDataToggle(fpDevInfo, fpDevInfo->IntInEndpoint) << 31);
+
+//
+// Fill the polling qTD with relevant information
+// The token field will be set so
+// Direction PID = QTD_IN_TOKEN,
+// Size = size of the data,
+// Data Toggle = QTD_DATA0_TOGGLE,
+// Error Count = QTD_THREE_ERRORS,
+// Status code = QTD_ACTIVE
+// The buffer pointers field will point to the fpBuffer buffer
+// which was before initialized to contain a DeviceRequest struc.
+// The dNextqTDPtr field will point to the qTDControlSetup
+// The dAltNextqTDPtr field will be set to EHCI_TERMINATE
+//
+ fpPollTD->dToken = QTD_IN_TOKEN |
+ QTD_IOC_BIT |
+ QTD_THREE_ERRORS |
+ QTD_ACTIVE;
+ //
+ // Set length
+ //
+ fpPollTD->dToken |= (UINT32)fpDevInfo->PollingLength << 16;
+ fpDevInfo->fpPollDataBuffer = EhciMemAlloc(fpHCStruc,
+ GET_MEM_BLK_COUNT(fpDevInfo->PollingLength));
+ ASSERT(fpDevInfo->fpPollDataBuffer);
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(fpPollTD,
+ fpDevInfo->fpPollDataBuffer, fpDevInfo->PollingLength);
+
+ //
+ // Update next & alternate next qTD pointers
+ //
+ fpPollTD->dNextqTDPtr = EHCI_TERMINATE;
+ fpPollTD->dAltNextqTDPtr = EHCI_TERMINATE;
+
+ EhciAddPeriodicQh(fpHCStruc,fpPollED);
+
+ fpPollED->bCallBackIndex = USB_InstallCallBackFunction(EhciPollingTDCallback);
+ fpPollED->bActive = TRUE;
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIDisableKeyRepeat
+//
+// Description: This function disables the keyboard repeat rate logic by
+// enabling the repeat TD
+//
+// Input: fpHCStruc - Pointer to the HCStruc structure
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_DisableKeyRepeat (
+ HC_STRUC *HcStruc
+)
+{
+ EHCI_DESC_PTRS *DescPtr;
+ EHCI_QH *RepeatQh;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (EhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ DescPtr = HcStruc->stDescPtrs.fpEHCIDescPtrs;
+
+ if (DescPtr == NULL) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (((UINT8*)DescPtr < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtr + sizeof(EHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+#endif
+
+ RepeatQh = DescPtr->fpQHRepeat;
+
+ if (RepeatQh == NULL) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (((UINT8*)RepeatQh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(RepeatQh + sizeof(EHCI_QH)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+#endif
+
+ if (RepeatQh) {
+ RepeatQh->dTokenReload = ((UINT32)8 << 16) | QTD_IN_TOKEN | QTD_ONE_ERROR;
+ RepeatQh->bActive = FALSE;
+ }
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EHCI_EnableKeyRepeat
+//
+// Description: This function disables the keyboard repeat rate logic by
+// enabling the repeat TD
+//
+// Parameters: fpHCStruc Pointer to the HCStruc structure
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCI_EnableKeyRepeat (
+ HC_STRUC* HcStruc
+)
+{
+ EHCI_DESC_PTRS *DescPtr;
+ EHCI_QH *RepeatQh;
+ EHCI_QTD *RepeatQtd;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (EhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ DescPtr = HcStruc->stDescPtrs.fpEHCIDescPtrs;
+
+ if (DescPtr == NULL) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (((UINT8*)DescPtr < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtr + sizeof(EHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+#endif
+
+ RepeatQh = DescPtr->fpQHRepeat;
+
+ if (RepeatQh == NULL) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (((UINT8*)RepeatQh < gUsbData->fpMemBlockStart) ||
+ (((UINT8*)RepeatQh + sizeof(EHCI_QH)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+#endif
+
+ if ((RepeatQh->dTokenReload & QTD_ACTIVE) == 0) {
+ RepeatQtd = DescPtr->fpqTDRepeat;
+ if (RepeatQtd == NULL) {
+ return USB_ERROR;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (((UINT8*)RepeatQtd < gUsbData->fpMemBlockStart) ||
+ (((UINT8*)RepeatQtd + sizeof(EHCI_QTD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+#endif
+ RepeatQh->dTokenReload = ((UINT32)8 << 16) | QTD_IN_TOKEN |
+ QTD_ONE_ERROR | QTD_IOC_BIT | QTD_ACTIVE;
+
+ // Update buffer pointers
+ EHCISetQTDBufferPointers(RepeatQtd,
+ &RepeatQh->aDataBuffer[0], 8);
+
+ // Re-init the QH pointers
+ RepeatQh->dCurqTDPtr = 0;
+ RepeatQh->dAltNextqTDPtr = EHCI_TERMINATE;
+ RepeatQh->dNextqTDPtr = (UINT32)(UINTN)RepeatQtd;
+
+ //
+ // Restart the qTD
+ //
+ RepeatQh->dToken = 0;
+ RepeatQtd->dToken = RepeatQh->dTokenReload;
+
+ RepeatQh->bActive = TRUE;
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIResetHC
+//
+// Description: This function resets the EHCI controller
+//
+// Input: Pointer to the HCStruc structure
+//
+// Output: USB_SUCCESS HC successfully reset
+// USB_ERROR Error, error log is updated
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIResetHC(HC_STRUC* fpHCStruc)
+{
+ UINT16 count;
+
+ if (fpHCStruc->DebugPort) return USB_SUCCESS;
+ //
+ // Check HC is halted: attempting to reset an actively running HC will
+ // result in undefined behavior.
+ //
+ if (EhciReadOpReg(fpHCStruc, EHCI_USBSTS) & EHCI_HCHALTED)
+ {
+ //
+ // Issue reset
+ //
+ EhciSetOpReg(fpHCStruc, EHCI_USBCMD, EHCI_HCRESET);
+
+ //
+ // EHCI_HCRESET bit is set to zero by the Host Controller when the reset
+ // process is complete.
+ //
+ for (count = 0; count < 500; count++) {
+ if (!(EhciReadOpReg(fpHCStruc, EHCI_USBCMD) & EHCI_HCRESET)) {
+ return USB_SUCCESS;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ }
+
+ //
+ // Error - HC reset failed
+ //
+ USBLogError(USB_ERR_HC_RESET_FAILED);
+
+ return USB_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIInitializesPeriodicSchedule
+//
+// Description: This function initializes the periodic schedules for the
+// EHCI host controller
+//
+// Input: fpHCStruc - HCStruc for the controller
+// dMemAddr - Membase address
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+// Notes: This routine creates 8ms and 32ms schedules
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIInitializePeriodicSchedule(
+ HC_STRUC* fpHCStruc,
+ UINT32 dMemBase)
+{
+ UINT8 *fpPtr;
+ EHCI_DESC_PTRS *fpDescPtr;
+ //
+ // Allocate descriptor structure and fill it in HCStruc
+ //
+ fpDescPtr = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT_STRUC(EHCI_DESC_PTRS));
+ if (fpDescPtr == NULL) {
+ USB_DEBUG(DEBUG_LEVEL_4, "EHCI Descriptor struc alloc failed. %d \n",
+ GET_MEM_BLK_COUNT_STRUC(EHCI_DESC_PTRS));
+ return USB_ERROR;
+ }
+
+ //
+ // Save the value in the HC struc
+ //
+ fpHCStruc->stDescPtrs.fpEHCIDescPtrs = fpDescPtr;
+
+ // Allocate QH/qTD for PeriodicQh
+ fpPtr = EhciMemAlloc(fpHCStruc, GET_MEM_BLK_COUNT((1 * sizeof(EHCI_QH))+
+ (0 * sizeof(EHCI_QTD))));
+ if (fpPtr == NULL) {
+ USB_DEBUG(DEBUG_LEVEL_4, "Schedule of EHCI QH alloc failed.\n");
+ return USB_ERROR;
+ }
+
+ // Save the 1 QH in appropriate location
+ fpDescPtr->PeriodicQh = (EHCI_QH*)fpPtr;
+
+ EHCIInitializeQueueHead(fpDescPtr->PeriodicQh);
+ fpDescPtr->PeriodicQh->dNextqTDPtr = EHCI_TERMINATE;
+ fpDescPtr->PeriodicQh->dAltNextqTDPtr = EHCI_TERMINATE;
+ fpDescPtr->PeriodicQh->dEndPntCharac = ((UINT32)0x40 << 16) + QH_HIGH_SPEED;
+ fpDescPtr->PeriodicQh->dLinkPointer = EHCI_TERMINATE;
+ fpDescPtr->PeriodicQh->dToken = QTD_HALTED;
+ fpDescPtr->PeriodicQh->Interval = 1;
+
+ EhciAddPeriodicQh(fpHCStruc, fpDescPtr->PeriodicQh);
+
+ return USB_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIInitializeQueueHead
+//
+// Description: This function initializes the queue head with default values
+//
+// Input: fpQH Pointer to queue head
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EHCIInitializeQueueHead(EHCI_QH *fpQH)
+{
+ fpQH->dNextqTDPtr = 1;
+ fpQH->dAltNextqTDPtr = 1;
+ fpQH->dCurqTDPtr = 0;
+
+ fpQH->dEndPntCap = QH_ONE_XFER;
+ fpQH->dToken = 0;
+ fpQH->dEndPntCharac = 0;
+ fpQH->dBufferPtr0 = 0;
+ fpQH->dBufferPtr1 = 0;
+ fpQH->dBufferPtr2 = 0;
+ fpQH->dBufferPtr3 = 0;
+ fpQH->dBufferPtr4 = 0;
+ fpQH->bErrorStatus = 0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStartPeriodicSchedule
+//
+// Description: This function starts the periodic schedule for the
+// EHCI host controller
+//
+// Input: Pointer to HcStruc
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIStartPeriodicSchedule(
+ HC_STRUC* HcStruc
+)
+{
+ UINT16 i;
+ //
+ // Start periodic schedule
+ //
+ EhciSetOpReg(HcStruc, EHCI_USBCMD, EHCI_PER_SCHED_ENABLE);
+
+ //
+ // Make sure the HC started the schedules
+ //
+ for (i = 0; i < 1000; i++) {
+ if (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_PER_SCHED_STATUS) {
+ break;
+ }
+ FixedDelay(10);
+ }
+ if (!(EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_PER_SCHED_STATUS)) {
+ return USB_ERROR;
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStopPeriodicSchedule
+//
+// Description: This function stops the periodic schedule for the
+// EHCI USB host controller
+//
+// Input: HcStruc for the controller
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIStopPeriodicSchedule(
+ HC_STRUC* HcStruc
+)
+{
+ UINT16 i;
+ //
+ // Stop periodic schedule
+ //
+ EhciClearOpReg(HcStruc, EHCI_USBCMD, EHCI_PER_SCHED_ENABLE);
+
+ //
+ // Make sure the HC stopped the schedules
+ //
+ for (i = 0; i < 1000; i++) {
+ if (!(EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_PER_SCHED_STATUS)) {
+ break;
+ }
+ FixedDelay(10);
+ }
+ if (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_PER_SCHED_STATUS) {
+ return USB_ERROR;
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStartAsyncSchedule
+//
+// Description: This function starts the asynchronous schedule
+//
+// Input: Pointer to HcStruc
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIStartAsyncSchedule(
+ HC_STRUC* HcStruc
+)
+{
+ UINT16 i;
+ //
+ // Start the Async schedule
+ //
+ EhciSetOpReg(HcStruc, EHCI_USBCMD, EHCI_ASYNC_SCHED_ENABLE);
+
+ //
+ // Make sure the HC started the async. execution
+ //
+ for (i = 0; i < 1000; i++) {
+ if (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_ASYNC_SCHED_STATUS) {
+ break;
+ }
+ FixedDelay(10);
+ }
+ if (!(EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_ASYNC_SCHED_STATUS)) {
+ //
+ // Stop the host controller (Reset bit 0)
+ //
+ EhciClearOpReg(HcStruc, EHCI_USBCMD, EHCI_RUNSTOP);
+ // The Host Controller must halt within 16 micro-frames after
+ // software clears the Run bit.
+ for (i = 0; i < 16; i++) {
+ if (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_HCHALTED) {
+ break;
+ }
+ FixedDelay(125); // 125 us delay
+ }
+ return USB_ERROR;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIStopAsyncSchedule
+//
+// Description: This function stops the asynchronous transfer and sets the
+// asynchronous pointer to null
+//
+// Input: Pointer to HcStruc
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIStopAsyncSchedule(
+ HC_STRUC* HcStruc
+)
+{
+ UINT16 i;
+
+ if (!(EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_ASYNC_SCHED_STATUS)) {
+ return USB_SUCCESS;
+ }
+
+ //
+ // Stop periodic schedule
+ //
+ EhciClearOpReg(HcStruc, EHCI_USBCMD, EHCI_ASYNC_SCHED_ENABLE);
+
+ //
+ // Make sure the HC stopped the async. execution
+ //
+ for (i = 0; i < 1000; i++) {
+ if (!(EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_ASYNC_SCHED_STATUS)) {
+ break;
+ }
+ FixedDelay(10);
+ }
+ if (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_ASYNC_SCHED_STATUS) {
+ //
+ // Stop the host controller (Reset bit 0)
+ //
+ EhciClearOpReg(HcStruc, EHCI_USBCMD, EHCI_RUNSTOP);
+ // The Host Controller must halt within 16 micro-frames after
+ // software clears the Run bit.
+ for (i = 0; i < 16; i++) {
+ if (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_HCHALTED) {
+ break;
+ }
+ FixedDelay(125); // 125 us delay
+ }
+ return USB_ERROR;
+ }
+
+ return USB_SUCCESS;
+}
+
+/*
+#if EHCI_ASYNC_BELL_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIRemoveQHFromAsyncList
+//
+// Description: This function stops the asynchronous transfer and sets the
+// asynchronous pointer to null
+//
+// Input: Pointer to HCStruc
+// Pointer to the Queue head that has to be removed
+// from the asynchronous schedule
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EHCIRemoveQHFromAsyncList(
+ HC_STRUC *fpHCStruc,
+ EHCI_QH *fpQH
+)
+{
+ //
+ // Stop the Async transfer
+ //
+ EHCIStopAsyncSchedule(fpHCStruc);
+
+ //
+ // Remove the queue head from the Async list
+ //
+ gUsbData->fpQHAsyncXfer->dLinkPointer = fpQH->dLinkPointer;
+
+ //
+ // Pointer is advanced. The queue head is totally removed from the list!
+ //
+}
+#endif
+*/
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIAddPeriodicQH
+//
+// Description: This function adds a QH to the frame list
+//
+// Input: Pointer to the QH to be added
+// Absolute pointer to the frame list
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EhciAddPeriodicQh(
+ HC_STRUC *HcStruc,
+ EHCI_QH *NewQh
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ UINT32 LinkPtr;
+ EHCI_QH *Qh;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (NewQh == NULL || NewQh->Interval == 0) {
+ return USB_ERROR;
+ }
+
+ for (Index = HcStruc->SplitPeriodicIndex; Index < HcStruc->wAsyncListSize; Index += NewQh->Interval) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ LinkPtr = *PrevPtr;
+ while (!(LinkPtr & EHCI_TERMINATE)){
+ Qh = (EHCI_QH*)(LinkPtr & EHCI_POINTER_MASK);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Qh, sizeof(EHCI_QH));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ if (Qh->Interval <= NewQh->Interval) {
+ break;
+ }
+ PrevPtr = &Qh->dLinkPointer;
+ LinkPtr = *PrevPtr;
+ }
+
+ if (!(LinkPtr & EHCI_TERMINATE) && (Qh == NewQh)) {
+ continue;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PrevPtr, sizeof(UINT32));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ NewQh->dLinkPointer = *PrevPtr;
+ *PrevPtr = (UINT32)((UINTN)NewQh | EHCI_QUEUE_HEAD);
+
+ }
+
+ if (HcStruc->SplitPeriodicIndex == MAX_SPLIT_PERIODIC_NUMBER) {
+ HcStruc->SplitPeriodicIndex = 0;
+ } else {
+ HcStruc->SplitPeriodicIndex++;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciRemovePeriodicQh
+//
+// Description: This function removes a QH from the frame list
+//
+// Input: Pointer to the QH to be added
+// Absolute pointer to the frame list
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EhciRemovePeriodicQh (
+ HC_STRUC *HcStruc,
+ EHCI_QH *RetiredQh
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ UINT32 LinkPtr;
+ EHCI_QH *Qh;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (RetiredQh == NULL || RetiredQh->Interval == 0) {
+ return USB_ERROR;
+ }
+
+ EHCIStopPeriodicSchedule(HcStruc);
+
+ for (Index = 0; Index < HcStruc->wAsyncListSize; Index++) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ LinkPtr = *PrevPtr;
+
+ while (!(LinkPtr & EHCI_TERMINATE)){
+ Qh = (EHCI_QH*)(LinkPtr & EHCI_POINTER_MASK);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Qh, sizeof(EHCI_QH));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ if (Qh == RetiredQh) {
+ break;
+ }
+ PrevPtr = &Qh->dLinkPointer;
+ LinkPtr = *PrevPtr;
+ }
+
+ if (LinkPtr & EHCI_TERMINATE) {
+ continue;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PrevPtr, sizeof(UINT32));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ *PrevPtr = RetiredQh->dLinkPointer;
+ }
+
+ RetiredQh->dLinkPointer = EHCI_TERMINATE;
+
+ EHCIStartPeriodicSchedule(HcStruc);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCISetQTDBufferPointers
+//
+// Description: This function will set the 5 buffer pointer in the qTD
+// appropriately depending upon the input size
+//
+// Input: fpQtd - Pointer to the qTD
+// fpBuf - 32bit absolute buffer pointer
+// wSize - Amount of data to be transferred
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EHCISetQTDBufferPointers(
+ EHCI_QTD *fpQtd,
+ UINT8 *fpBuf,
+ UINT32 dSize
+)
+{
+ UINT16 wBufSize;
+ UINT8 *fpBuffer = fpBuf;
+ UINT32 *fpBufferPtr;
+ UINT16 w4KRemainder;
+
+ //
+ // Fill the buffer pointers with 0s
+ //
+ fpQtd->dBufferPtr0 = 0;
+ fpQtd->dBufferPtr1 = 0;
+ fpQtd->dBufferPtr2 = 0;
+ fpQtd->dBufferPtr3 = 0;
+ fpQtd->dBufferPtr4 = 0;
+ fpQtd->dAltNextqTDPtr = 1;
+
+ //
+ // If size to transfer is 0 skip updating pointers
+ //
+ if (!dSize)
+ {
+ return;
+ }
+
+ //
+ // Make sure the amount of data to be xferred is 16K or less
+ //
+ wBufSize = (UINT16)((dSize > MAX_EHCI_DATA_SIZE) ? MAX_EHCI_DATA_SIZE : dSize);
+
+ fpBufferPtr = &fpQtd->dBufferPtr0;
+
+ for (;;)
+ {
+ *fpBufferPtr = (UINT32)(UINTN)fpBuffer;
+ //
+ // Calculate the number of bytes that can be transferred using current
+ // buffer pointer
+ //
+ w4KRemainder = (UINT16)((((UINT32)((UINTN)fpBuffer+0x1000)) & 0xFFFFF000) -
+ (UINT32)(UINTN)fpBuffer);
+
+ //
+ // Check whether all the bytes can be accomadated in the current buffer
+ //
+ if (w4KRemainder >= wBufSize)
+ {
+ break; // Yes. Current Buffer is sufficient for the rest of data
+ }
+
+ //
+ // We have more data to transfer - adjust data and store it in the next pointer
+ //
+ wBufSize = (UINT16)(wBufSize - w4KRemainder); // Amount of data remaining
+ fpBuffer = fpBuffer + w4KRemainder; // Adjust buffer (4K bound)
+ fpBufferPtr++; // Next buffer pointer
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIWaitForTransferComplete
+//
+// Description: This function waits until the requested QH completes or
+// the transaction time-out
+//
+// Input: fpHCStruc - Pointer to HCStruc of the host controller
+// fpQH - Pointer to the QH which has to be completed
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+EHCIWaitForTransferComplete(
+ HC_STRUC *fpHCStruc,
+ EHCI_QH *fpQH,
+ DEV_INFO* fpDevInfo
+
+)
+{
+ UINT32 dCount ;
+ UINT32 countLimit = gUsbData->wTimeOutValue * 100; // makes it number of macrosecond units
+ UINT16 Status = USB_ERROR;
+
+ //
+ // Check status change loop iteration
+ //
+ for(dCount = 0; !countLimit || dCount < countLimit; dCount++)
+ {
+ EHCIProcessQH(fpHCStruc, fpQH);
+ if(fpQH->bActive == FALSE) {
+ Status = USB_SUCCESS;
+ break;
+ }
+ FixedDelay(10); // 60 microsec
+ }
+
+ if(fpQH->bActive == TRUE) {
+ // Set the QH as in-active
+ fpQH->bActive = FALSE;
+ Status = USB_ERROR;
+ USB_DEBUG (DEBUG_LEVEL_3, "EHCI Time-Out\n");
+ }
+
+ // Service all interrupts
+ EHCI_ProcessInterrupt(fpHCStruc);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIProcessQH
+//
+// Description: This function whether all the TD's in the QH is completed
+//
+// Input: fpQH - Pointer to the QH which has to be completed
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EHCIProcessQH(
+ HC_STRUC *fpHCStruc,
+ EHCI_QH *fpQH
+)
+{
+ EHCI_QTD *fpQTD = fpQH->fpFirstqTD;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ for (;;) {
+ if (fpQTD == NULL) {
+ return USB_ERROR;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)fpQTD, sizeof(EHCI_QTD));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ //
+ // Check whether the qTD is active, if so. Exit!
+ //
+ if (fpQTD->dToken & QTD_ACTIVE) {
+ return USB_ERROR;
+ }
+
+ //
+ // Check for halt condition, if halted - exit
+ //
+ if (fpQTD->dToken & QTD_HALTED) {
+ //
+ // Set the QH halted status
+ //
+ fpQH->bErrorStatus = QTD_HALTED;
+ //
+ // Set the QH as in-active
+ //
+ fpQH->bActive = FALSE;
+ break;
+ }
+ //
+ // qTD is not active and not halted. That is it is completed successfully
+ // Check whether this qTD is the last one in the list
+ //
+ if (fpQTD->dNextqTDPtr & EHCI_TERMINATE) {
+ //
+ // Set the QH as in-active
+ //
+ fpQH->bActive = FALSE;
+ break;
+ }
+
+ //
+ // More qTDs are in the list. Process next qTD
+ //
+ fpQTD = (EHCI_QTD*)(UINTN)fpQTD->dNextqTDPtr;
+ }
+
+ if ((fpQH->bCallBackIndex) && (fpQH->bCallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ if (gUsbData->aCallBackFunctionTable[fpQH->bCallBackIndex - 1]) {
+ if ((gUsbData->aCallBackFunctionTable[fpQH->bCallBackIndex - 1])
+ != EhciRepeatTDCallback) {
+ Status = UsbDevInfoValidation((DEV_INFO*)fpQH->fpDevInfoPtr);
+
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+ }
+ (*gUsbData->aCallBackFunctionTable[fpQH->bCallBackIndex - 1])
+ (fpHCStruc, (DEV_INFO*)fpQH->fpDevInfoPtr,
+ (UINT8*)fpQH, NULL, 0);
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIProcessPeriodicList
+//
+// Description: This function parses through the periodic list to find
+// completed qTD. If a qTD is done it will call its associated
+// call back function (in device info structure) and restarts
+// the polling qTD
+//
+// Input: fpHCStruc - Pointer to HCStruc of the host controller
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EHCIProcessPeriodicList(
+ HC_STRUC *HcStruc
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ UINT32 LinkPtr;
+ EHCI_QH *Qh;
+ UINT32 OrgQhLinkPointer;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+
+ //
+ // Get the first entry in the periodic list. This QH list will link to all
+ // the periodic QH's
+ //
+
+ for (Index = 0; Index <= MAX_SPLIT_PERIODIC_NUMBER; Index ++) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ LinkPtr = *PrevPtr;
+
+ while (!(LinkPtr & EHCI_TERMINATE)) {
+ Qh = (EHCI_QH*)(LinkPtr & EHCI_POINTER_MASK);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Qh, sizeof(EHCI_QH));
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+#endif
+ // Process only QHeads, skip the other types
+ if ((Qh->dLinkPointer & 6) == EHCI_QUEUE_HEAD) {
+
+ // Check whether this QH is actived
+ if (Qh->bActive == TRUE) {
+ OrgQhLinkPointer = Qh->dLinkPointer;
+ EHCIProcessQH(HcStruc, Qh);
+ // Qh is changed, we re-parses through the list.
+ if (Qh->dLinkPointer != OrgQhLinkPointer) {
+ LinkPtr = *PrevPtr;
+ continue;
+ }
+ }
+ }
+
+ LinkPtr = Qh->dLinkPointer;
+ }
+
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciPollingTDCallback
+//
+// Description: This function is called when a polling TD from the TD pool
+// completes an interrupt transaction to its assigned device.
+// This routine should process any data in the TD's data buffer,
+// handle any errors, and then copy the TD's CSReloadValue field
+// into its control status field to put the TD back into service.
+//
+// Input: HcStruc Pointer to the HCStruc structure
+// DevInfo NULL (pDevInfo is not valid)
+// QueueHead Pointer to the QH that completed
+// Buffer Not used
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EhciPollingTDCallback(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *QueueHead,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ EHCI_QH* PollQh = (EHCI_QH*)QueueHead;
+ EHCI_QTD *PollQtd = PollQh->fpFirstqTD;
+ UINT16 BytesTransferred;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PollQtd, sizeof(EHCI_QTD));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+
+ // Update datat toggle value
+ UsbUpdateDataToggle(DevInfo, DevInfo->IntInEndpoint,
+ (UINT8)((PollQh->dToken & QH_DATA_TOGGLE) >> 31));
+
+ if (!(PollQh->dToken & QTD_STATUS_FIELD)) {
+ if ((DevInfo->bCallBackIndex) && (DevInfo->bCallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ if (gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex-1]) {
+ //
+ // Get the size of data transferred
+ //
+ BytesTransferred = DevInfo->PollingLength - (UINT16)((PollQtd->dToken & ~(QTD_DATA_TOGGLE)) >> 16);
+ (*gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex-1])
+ (HcStruc, DevInfo, (UINT8*)PollQtd, DevInfo->fpPollDataBuffer, BytesTransferred);
+ }
+ }
+ }
+
+ // Keep the PID code bit in the qTD
+ PollQtd->dToken &= QTD_DIRECTION_PID;
+
+ //
+ // Set length
+ //
+ PollQtd->dToken |= (UINT32)DevInfo->PollingLength << 16;
+
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(PollQtd,
+ DevInfo->fpPollDataBuffer, DevInfo->PollingLength);
+
+ //
+ // Re-init the QH pointers
+ //
+ PollQh->dToken &= QH_DATA_TOGGLE;
+ PollQh->dCurqTDPtr = 0;
+ PollQh->dAltNextqTDPtr = EHCI_TERMINATE;
+ PollQh->dBufferPtr0 = 0;
+ PollQh->dBufferPtr1 = 0;
+ PollQh->dBufferPtr2 = 0;
+ PollQh->dBufferPtr3 = 0;
+ PollQh->dBufferPtr4 = 0;
+ //
+ // Update next & alternate next qTD pointers
+ //
+ PollQtd->dNextqTDPtr = EHCI_TERMINATE;
+ PollQtd->dAltNextqTDPtr = EHCI_TERMINATE;
+ PollQh->dNextqTDPtr = (UINT32)(UINTN)PollQtd;
+
+ //
+ // Restart the qTD
+ //
+ PollQtd->dToken |= (QTD_IOC_BIT | QTD_THREE_ERRORS | QTD_ACTIVE);
+ PollQh->bActive = TRUE;
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EHCIRepeatTDCallback
+//
+// Description: This function is called when qTdRepeat completes
+// a transaction. This qTD runs a dummy interrupt transaction
+// to a non-existant device address for the purpose of
+// generating a periodic timeout interrupt which in turn
+// is used to generate keyboard repeat or update LED status.
+//
+// Input: HcStruc Pointer to the HCStruc structure
+// DevInfo NULL (pDevInfo is not valid)
+// QueueHead Pointer to the QH that completed
+// Buffer Not used
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+EhciRepeatTDCallback(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *QueueHead,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ EHCI_QH *RepeatQh = (EHCI_QH*)QueueHead;
+ EHCI_QTD *RepeatQtd = RepeatQh->fpFirstqTD;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)RepeatQtd, sizeof(EHCI_QTD));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+
+#if USB_DEV_KBD
+ USBKBDPeriodicInterruptHandler(HcStruc);
+#endif
+
+ if (RepeatQh->dTokenReload & QTD_ACTIVE) {
+ //
+ // Update buffer pointers
+ //
+ EHCISetQTDBufferPointers(RepeatQtd,
+ &RepeatQh->aDataBuffer[0], 8);
+
+ //
+ // Re-init the QH pointers
+ //
+ RepeatQh->dToken &= QH_DATA_TOGGLE;
+ RepeatQh->dCurqTDPtr = 0;
+ RepeatQh->dAltNextqTDPtr = EHCI_TERMINATE;
+ RepeatQh->dBufferPtr0 = 0;
+ RepeatQh->dBufferPtr1 = 0;
+ RepeatQh->dBufferPtr2 = 0;
+ RepeatQh->dBufferPtr3 = 0;
+ RepeatQh->dBufferPtr4 = 0;
+ RepeatQh->dNextqTDPtr = (UINT32)(UINTN)RepeatQtd;
+
+ //
+ // Restart the qTD
+ //
+ RepeatQh->dToken = 0;
+ RepeatQtd->dToken = RepeatQh->dTokenReload;
+
+ RepeatQh->bActive = TRUE;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciIsHalted
+//
+// Description: This function check whether HC is halted.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+EhciIsHalted (
+ HC_STRUC *HcStruc
+)
+{
+ return (EhciReadOpReg(HcStruc, EHCI_USBSTS) & EHCI_HCHALTED) == EHCI_HCHALTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: EhciTranslateInterval
+//
+// Description: This function calculates the polling rate in frames unit.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+EhciTranslateInterval(
+ UINT8 Speed,
+ UINT8 Interval
+)
+{
+ UINT8 BitCount = 0;
+ UINT16 PollingRate = 0;
+
+ if (Speed == USB_PORT_STAT_DEV_HISPEED) {
+ // For high-speed interrupt endpoints, the Interval value must be
+ // from 1 to 16
+ ASSERT(Interval >= 1 && Interval <= 16);
+
+ PollingRate = (1 << (Interval - 1)) >> 3;
+ return PollingRate != 0 ? PollingRate : 1;
+ }
+
+ // For full-/low-speed interrupt endpoints, the Interval value should
+ // be from 1 to 255
+ ASSERT(Interval >= 1 && Interval <= 255);
+
+ for (BitCount = 0; Interval != 0; BitCount++) {
+ Interval >>= 1;
+ }
+ return (1 << (BitCount - 1));
+}
+
+//==========================================================================
+
+UINT32
+EhciReadPciReg(
+ HC_STRUC *HcStruc,
+ UINT32 Offset
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ return ReadPCIConfig(HcStruc->wBusDevFuncNum, Offset);
+#else
+ EFI_STATUS Status;
+ UINT32 Data = 0;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ Offset,
+ 1,
+ &Data);
+ ASSERT_EFI_ERROR(Status);
+ return Data;
+#endif
+}
+
+
+VOID
+EhciWritePciReg(
+ HC_STRUC *HcStruc,
+ UINT32 Offset,
+ UINT32 Data
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ DwordWritePCIConfig(HcStruc->wBusDevFuncNum, Offset, Data);
+ return;
+#else
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ Status = PciIo->Pci.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ Offset,
+ 1,
+ &Data);
+ ASSERT_EFI_ERROR(Status);
+ return;
+#endif
+}
+
+UINT32
+EhciReadHcMem(
+ HC_STRUC *HcStruc,
+ UINT32 Offset
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (Offset > HcStruc->BaseAddressSize) {
+ return 0;
+ }
+ return DwordReadMem((UINT32)HcStruc->BaseAddress, Offset);
+#else
+ EFI_STATUS Status;
+ UINT32 Data = 0;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ Status = PciIo->Mem.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ Offset,
+ 1,
+ &Data);
+ ASSERT_EFI_ERROR(Status);
+ return Data;
+#endif
+}
+
+VOID
+EhciWriteHcMem(
+ HC_STRUC *HcStruc,
+ UINT32 Offset,
+ UINT32 Data
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (Offset > HcStruc->BaseAddressSize) {
+ return;
+ }
+ DwordWriteMem((UINT32)HcStruc->BaseAddress, Offset, Data);
+ return;
+#else
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ Status = PciIo->Mem.Write (
+ PciIo,
+ EfiPciIoWidthUint32,
+ 0,
+ Offset,
+ 1,
+ &Data);
+ ASSERT_EFI_ERROR(Status);
+ return;
+#endif
+}
+
+UINT32
+EhciReadOpReg(
+ HC_STRUC *HcStruc,
+ UINT32 Offset
+)
+{
+ return EhciReadHcMem(HcStruc, HcStruc->bOpRegOffset + Offset);
+}
+
+VOID
+EhciWriteOpReg(
+ HC_STRUC *HcStruc,
+ UINT32 Offset,
+ UINT32 Data
+)
+{
+ EhciWriteHcMem(HcStruc, HcStruc->bOpRegOffset + Offset, Data);
+ return;
+}
+
+VOID
+EhciSetOpReg(
+ HC_STRUC *HcStruc,
+ UINT32 Offset,
+ UINT32 Bit
+)
+{
+ UINT32 Data;
+
+ Data = EhciReadOpReg(HcStruc, Offset) | Bit;
+ EhciWriteOpReg(HcStruc, Offset, Data);
+ return;
+}
+
+VOID
+EhciClearOpReg(
+ HC_STRUC *HcStruc,
+ UINT32 Offset,
+ UINT32 Bit
+)
+{
+ UINT32 Data;
+
+ Data = EhciReadOpReg(HcStruc, Offset) & ~Bit;
+ EhciWriteOpReg(HcStruc, Offset, Data);
+ return;
+}
+
+UINT32
+EhciReadDebugReg(
+ HC_STRUC *HcStruc,
+ UINT8 BarIndex,
+ UINT32 Offset
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ UINT8 BarOffset[6] = {0x10, 0x14, 0x18, 0x1C, 0x20, 0x24};
+ UINT32 DebugPortsMem;
+
+ DebugPortsMem = EhciReadPciReg(HcStruc, BarOffset[BarIndex]);
+ return DwordReadMem(DebugPortsMem, Offset);
+#else
+ EFI_STATUS Status;
+ UINT32 Data = 0;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ Status = PciIo->Mem.Read (
+ PciIo,
+ EfiPciIoWidthUint32,
+ BarIndex,
+ Offset,
+ 1,
+ &Data);
+ ASSERT_EFI_ERROR(Status);
+ return Data;
+#endif
+}
+
+VOID*
+EhciMemAlloc(
+ HC_STRUC *HcStruc,
+ UINT16 NumBlks
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ return USB_MemAlloc(NumBlks);
+#else
+ UINT32 SavedMemPages = gUsbData->MemPages;
+ UINT8 *SavedMemPool = gUsbData->fpMemBlockStart;
+ UINT32 SavedMemBlkStsBytes = gUsbData->MemBlkStsBytes;
+ UINT32 *SavedMemBlsSts = gUsbData->aMemBlkSts;
+ VOID* MemPtr;
+
+ gUsbData->MemPages = HcStruc->MemPoolPages;
+ gUsbData->fpMemBlockStart = HcStruc->MemPool;
+ gUsbData->MemBlkStsBytes = HcStruc->MemBlkStsBytes;
+ gUsbData->aMemBlkSts = HcStruc->MemBlkSts;
+
+ MemPtr = USB_MemAlloc(NumBlks);
+
+ gUsbData->MemPages = SavedMemPages;
+ gUsbData->fpMemBlockStart = SavedMemPool;
+ gUsbData->MemBlkStsBytes = SavedMemBlkStsBytes;
+ gUsbData->aMemBlkSts = SavedMemBlsSts;
+
+ return MemPtr;
+#endif
+}
+
+VOID
+EhciMemFree(
+ HC_STRUC *HcStruc,
+ VOID* MemPtr,
+ UINT16 NumBlks
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ USB_MemFree(MemPtr, NumBlks);
+#else
+ UINT32 SavedMemPages = gUsbData->MemPages;
+ UINT8 *SavedMemPool = gUsbData->fpMemBlockStart;
+ UINT32 SavedMemBlkStsBytes = gUsbData->MemBlkStsBytes;
+ UINT32 *SavedMemBlsSts = gUsbData->aMemBlkSts;
+
+ gUsbData->MemPages = HcStruc->MemPoolPages;
+ gUsbData->fpMemBlockStart = HcStruc->MemPool;
+ gUsbData->MemBlkStsBytes = HcStruc->MemBlkStsBytes;
+ gUsbData->aMemBlkSts = HcStruc->MemBlkSts;
+
+ USB_MemFree(MemPtr, NumBlks);
+
+ gUsbData->MemPages = SavedMemPages;
+ gUsbData->fpMemBlockStart = SavedMemPool;
+ gUsbData->MemBlkStsBytes = SavedMemBlkStsBytes;
+ gUsbData->aMemBlkSts = SavedMemBlsSts;
+
+ return;
+#endif
+}
+
+UINT8
+EhciDmaMap(
+ HC_STRUC *HcStruc,
+ UINT8 Direction,
+ UINT8 *BufferAddr,
+ UINT32 BufferSize,
+ UINT8 **PhyAddr,
+ VOID **Mapping
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ *PhyAddr = BufferAddr;
+#else
+ EFI_PCI_IO_PROTOCOL_OPERATION Operation;
+ EFI_PHYSICAL_ADDRESS Addr;
+ EFI_STATUS Status;
+ UINTN Bytes = BufferSize;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ if (Direction & BIT7) {
+ Operation = EfiPciIoOperationBusMasterWrite;
+ } else {
+ Operation = EfiPciIoOperationBusMasterRead;
+ }
+
+ Status = PciIo->Map (
+ PciIo,
+ Operation,
+ BufferAddr,
+ &Bytes,
+ &Addr,
+ Mapping
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status) || Bytes != BufferSize) {
+ return USB_ERROR;
+ }
+
+ *PhyAddr = (UINT8*)Addr;
+#endif
+ return USB_SUCCESS;
+}
+
+UINT8
+EhciDmaUnmap(
+ HC_STRUC *HcStruc,
+ VOID *Mapping
+)
+{
+#if !USB_RUNTIME_DRIVER_IN_SMM
+
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo = HcStruc->PciIo;
+
+ Status = PciIo->Unmap(PciIo, Mapping);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ return USB_SUCCESS;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/ehci.h b/Core/EM/usb/rt/ehci.h
new file mode 100644
index 0000000..2dbc894
--- /dev/null
+++ b/Core/EM/usb/rt/ehci.h
@@ -0,0 +1,420 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ehci.h 12 7/26/13 2:33a Ryanchou $
+//
+// $Revision: 12 $
+//
+// $Date: 7/26/13 2:33a $
+//****************************************************************************//---------------------------------------------------------------------------
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ehci.h $
+//
+// 12 7/26/13 2:33a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 11 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 10 5/04/12 5:24a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 9 7/19/11 5:17a Ryanchou
+// [TAG] EIP64498
+// [Category] New Feature
+// [Description] Implement EHCI key repeat function.
+// [Files] ehci.c, ehci.h, usb.c, usbdef.h
+//
+// 8 3/29/11 10:49p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 7 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 6 3/20/07 12:21p Olegi
+//
+// 4 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 12/22/05 9:43a Olegi
+// Ownership definitons corrected.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Ehci.h
+//
+// Description: AMI USB EHCI support header
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+// Avoid including multiple instance of this file
+#ifndef __EHCI_H
+#define __EHCI_H
+
+// Global equates for EHCI
+//-------------------------------------------------------------------------
+#define EHCI_FRAMELISTSIZE 1024 // Number of DWORDs in frame list
+
+// Maximum data that can be transferred in a transaction
+#define MAX_EHCI_DATA_SIZE 16 * 1024
+
+// Mask for masking unwanted bits in the QH & qTD pointers
+#define EHCI_POINTER_MASK 0xFFFFFFE0 // Mask bit 0-4
+
+// Capability Registers
+//-------------------------------------------------------------------------
+// These registers specify the limits, restrictions and capabilities of the
+// host controller implementation
+//-------------------------------------------------------------------------
+#define EHCI_VERCAPLENGTH 0 // Interface Version and Capability
+ // Register Length
+#define EHCI_HCSPARAMS 4 // Structural Parameters
+ // EHCI_HCSPARAMS bit definitions
+ #define EHCI_N_PORTS BIT0+BIT1+BIT2+BIT3 // Number of implemented
+ // ports
+ #define EHCI_PPC BIT4 // Port Power Control
+ #define EHCI_PRR BIT7 // Port Routing Rules
+ #define EHCI_N_PCC BIT8+BIT9+BIT10+BIT11 // Number of Ports per
+ // Companion Controller
+ #define EHCI_N_CC BIT12+BIT13+BIT14+BIT15 // Number of Companion
+ // Controllers
+ #define EHCI_P_INDICATOR BIT16 // Port Indicators
+ #define EHCI_DEBUG_N BIT20+BIT21+BIT22+BIT23 // Debug Port Number
+//---------------------------------------
+#define EHCI_HCCPARAMS 8 // Capability Parameters
+ // EHCI_HCCPARAMS bit definitions
+ #define EHCI_64BIT_CAP 0x01 // 64-bit addressing capability
+ #define EHCI_PFLFLAG 0x02 // Programmable Frame List Flag
+ #define EHCI_ASP_CAP 0x04 // Asynchronous Schedule Park Capability
+ #define EHCI_IST 0xF0 // Isochronous Scheduling Threshold
+ #define EHCI_EECP 0xFF00 // EHCI Extended Capabilities Pointer
+//---------------------------------------
+#define EHCI_HCSP_PORTROUTE 0x0C // Companion Port Route Description
+
+// Host Controller operational registers
+//-------------------------------------------------------------------------
+// The following equates specify the HC operational registers as offsets of
+// the operational register base. Operational register base is calculated by
+// adding the value in the first capabilities register (EHCI_VERCAPLENGTH) to
+// the base address of EHCI HC register address space.
+//-------------------------------------------------------------------------
+#define EHCI_USBCMD 0 // USB Command
+ // EHCI_USBCMD bit definitions
+ #define EHCI_RUNSTOP BIT0
+ #define EHCI_HCRESET BIT1
+ #define EHCI_FRM1024 0 // Reset BIT2 and BIT3 before
+ #define EHCI_FRM512 BIT2 // setting the new Frame List Size
+ #define EHCI_FRM256 BIT3
+ #define EHCI_PER_SCHED_ENABLE BIT4
+ #define EHCI_ASYNC_SCHED_ENABLE BIT5
+ #define EHCI_INT_ASYNC_ADVANCE_ENABLE BIT6
+ #define EHCI_INTTHRESHOLD (8 << 16)
+//---------------------------------------
+#define EHCI_USBSTS 4 // USB Status
+ // EHCI_USBSTS bit definitions
+ #define EHCI_USB_INTERRUPT BIT0 // Interrupt
+ #define EHCI_USB_ERROR_INTERRUPT BIT1 // Error interrupt
+ #define EHCI_PORT_CHANGE_DETECT BIT2 // Port Change Detect
+ #define EHCI_FRAME_LIST_ROLLOVER BIT3 // Frame List Rollover
+ #define EHCI_HOST_SYSTEM_ERROR BIT4 // Host System Error
+ #define EHCI_INT_ASYNC_ADVANCE BIT5 // Interrupt on Async Advance
+ #define EHCI_HCHALTED BIT12 // HCHalted
+ #define EHCI_RECLAIM BIT13 // Reclamation
+ #define EHCI_PER_SCHED_STATUS BIT14 // Periodic Schedule Status
+ #define EHCI_ASYNC_SCHED_STATUS BIT15 // Asynchronous Schedule Status
+//---------------------------------------
+#define EHCI_USBINTR 8 // USB Interrupt Enable
+ // EHCI_USBINTR bit definitions
+ #define EHCI_USBINT_EN BIT0 // Interrupt Enable
+ #define EHCI_USBERRINT_EN BIT1 // Error Interrupt Enable
+ #define EHCI_PCDINT_EN BIT2 // Port Change Detect Interrupt Enable
+ #define EHCI_FLRINT_EN BIT3 // Frame List Rollover Interrupt Enable
+ #define EHCI_HSEINT_EN BIT4 // Host System Error Interrupt Enable
+ #define EHCI_IAAINT_EN BIT5 // Interrupt on Async Advance Enable
+//---------------------------------------
+#define EHCI_FRINDEX 0x0C // USB Frame Index
+#define EHCI_CTRLDSSEGMENT 0x10 // 4G Segment Selector
+#define EHCI_PERIODICLISTBASE 0x14 // Frame List Base Address
+#define EHCI_ASYNCLISTADDR 0x18 // Next Asynchronous List Address
+#define EHCI_CONFIGFLAG 0x40 // Configured Flag Register
+
+#define EHCI_PORTSC 0x44 // Port Status/Control
+ // EHCI_PORTSC bit definitions
+ #define EHCI_CURRENTCONNECTSTATUS BIT0
+ #define EHCI_CONNECTSTATUSCHANGE BIT1
+ #define EHCI_PORTENABLE BIT2
+ #define EHCI_PORTENABLESTATUSCHANGE BIT3
+ #define EHCI_OVERCURRENTACTIVE BIT4
+ #define EHCI_OVERCURRENTCAHGE BIT5
+ #define EHCI_FORCEPORTRESUME BIT6
+ #define EHCI_SUSPEND BIT7
+ #define EHCI_PORTRESET BIT8
+ #define EHCI_LINE_STATUS (BIT10 | BIT11)
+ #define EHCI_DMINUSBIT BIT10
+ #define EHCI_DPLUSBIT BIT11
+ #define EHCI_PORTPOWER BIT12
+ #define EHCI_PORTOWNER BIT13
+ #define EHCI_WKCNNT_E BIT20 // Wake On Connect Enable
+ #define EHCI_WKDSCNNT_E BIT21 // Wake On Disconnect Enable
+ #define EHCI_WKOC_E BIT22 // Wake On Over-current Enable
+
+//EHCI Extended Capability registers
+//------------------------------------------------
+#define EHCI_LEGACY_REG 0x00
+#define EHCI_LEGACY_CTRL_STS_REG 0x04
+
+//USB Legacy Suport Extended Capibility
+//------------------------------------------------
+#define EHCI_CAP_ID 0x000000FF
+#define EHCI_NEXT_EECP 0x0000FF00
+#define EHCI_HC_BIOS 0x00010000
+#define EHCI_HC_OS 0x01000000
+
+//USB Legacy Suport Control/Status
+//------------------------------------------------
+#define EHCI_SMI 0x001
+#define EHCI_ERROR_SMI 0x002
+#define EHCI_PORT_CHANGE_SMI 0x004
+#define EHCI_FRAME_LIST_ROLL_OVER_SMI 0x008
+#define EHCI_HOST_SYSTEM_ERROR_SMI 0x010
+#define EHCI_ASYNC_ADVANCE_SMI 0x020
+#define EHCI_OWNERSHIP_CHANGE_SMI 0x2000
+#define EHCI_SMI_PCI_COMMAND 0x4000
+#define EHCI_SMI_ON_BAR 0x8000
+#define EHCI_SMI_STS 0x0001
+#define EHCI_ERROR_SMI_STS 0x0002
+#define EHCI_PORT_CHANGE_STS 0x0004
+#define EHCI_FRAME_LIST_ROLL_OVER_SMI_STS 0x0008
+#define EHCI_SMI_HOST_SYSTEM_ERROR 0x0010
+#define EHCI_ASYNC_ADVANCE_SMI_STS 0x0020
+#define EHCI_OWNERSHIP_CHANGE_SMI_STS 0x2000
+#define EHCI_SMI_PCI_COMMAND_STS 0x4000
+#define EHCI_SMI_ON_BAR_STS 0x8000
+
+#define EHCI_PCI_TRAP_SMI EHCI_OWNERSHIP_CHANGE_SMI
+#define EHCI_ALL_SMI 0x0E03F
+#define EHCI_ALL_LEGACY_SMI 0x0003F
+
+//-------------------------------------------------------------------------
+// Descriptor structure used to store TD and ED addresses
+//-------------------------------------------------------------------------
+//
+// Bit definitions for a generic pointer
+//
+#define EHCI_TERMINATE 1
+
+#pragma pack(push, 1)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EHCI_QTD
+//
+// Description: This is EHCI queue TD data structure used to perform
+// non-isochronous transaction in EHCI based HC
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// dNextqTDPtr DWORD Pointer to next qTD
+// dAltNextqTDPtr DWORD Pointer to alternate next qTD
+// dToken DWORD Token double word
+// dBufferPtr0 DWORD Buffer pointer page 0
+// dBufferPtr1 DWORD Buffer pointer page 1
+// dBufferPtr2 DWORD Buffer pointer page 2
+// dBufferPtr3 DWORD Buffer pointer page 3
+// dBufferPtr4 DWORD Buffer pointer page 4
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT32 dNextqTDPtr;
+ UINT32 dAltNextqTDPtr;
+ UINT32 dToken;
+ UINT32 dBufferPtr0;
+ UINT32 dBufferPtr1;
+ UINT32 dBufferPtr2;
+ UINT32 dBufferPtr3;
+ UINT32 dBufferPtr4;
+#if EHCI_64BIT_DATA_STRUCTURE
+// For 64bit data structure
+ UINT32 dReserved[8];
+#endif
+} EHCI_QTD;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: EHCI_QH
+//
+// Description: This is EHCI queue head data structure used to perform
+// non-isochronous transaction in EHCI based HC
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// dLinkPointer DWORD Pointer to the next queue head
+// dEndPntCharac DWORD Endpoint characteristics settings
+// dEndPntCap DWORD Endpoint capability settings
+// dCurqTDPtr DWORD Pointer to current qTD
+// dNextqTDPtr DWORD Pointer to next qTD
+// dAltNextqTDPtr DWORD Pointer to alternate next qTD
+// dToken DWORD Token double word
+// dBufferPtr0 DWORD Buffer pointer page 0
+// dBufferPtr1 DWORD Buffer pointer page 1
+// dBufferPtr2 DWORD Buffer pointer page 2
+// dBufferPtr3 DWORD Buffer pointer page 3
+// dBufferPtr4 DWORD Buffer pointer page 4
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT32 dLinkPointer;
+ UINT32 dEndPntCharac;
+ UINT32 dEndPntCap;
+ UINT32 dCurqTDPtr;
+ UINT32 dNextqTDPtr;
+ UINT32 dAltNextqTDPtr;
+ UINT32 dToken;
+ UINT32 dBufferPtr0;
+ UINT32 dBufferPtr1;
+ UINT32 dBufferPtr2;
+ UINT32 dBufferPtr3;
+ UINT32 dBufferPtr4;
+#if EHCI_64BIT_DATA_STRUCTURE
+// For 64bit data structure
+ UINT32 dReserved[8];
+#endif
+ UINT8 bCallBackIndex;
+ EHCI_QTD *fpFirstqTD;
+ UINT8 bActive;
+ UINT8 bErrorStatus;
+ UINT8 *fpDevInfoPtr;
+ UINT8 aDataBuffer[8];
+ UINT32 dTokenReload;
+ UINT16 Interval;
+ UINT8 Pad[31-2*sizeof(void*)]; // sizeof(EHCI_QH)should be divisible by 32
+} EHCI_QH; // because of 32 bin pointers; the size of
+ // the structure has to be 32 bytes aligned
+#pragma pack(pop)
+
+#define EHCI_QUEUE_HEAD 2 // Queue head id
+
+// Bit definition for queue transfer descriptor token fields
+//-------------------------------------------------------------------------
+#define QTD_DATA_TOGGLE 0x80000000 // BIT 31
+ #define QTD_SETUP_TOGGLE 0x00000000
+ #define QTD_DATA0_TOGGLE 0x00000000
+ #define QTD_DATA1_TOGGLE 0x80000000
+ #define QTD_STATUS_TOGGLE 0x80000000
+#define QTD_XFER_DATA_SIZE 0x7FFF0000 // BIT 30:16
+#define QTD_IOC_BIT 0x00008000 // BIT 15
+#define QTD_ERROR_COUNT 0x00000C00
+ #define QTD_NO_ERRORS 0x00000000
+ #define QTD_ONE_ERROR 0x00000400
+ #define QTD_TWO_ERRORS 0x00000800
+ #define QTD_THREE_ERRORS 0x00000C00
+#define QTD_DIRECTION_PID 0x00000300
+ #define QTD_OUT_TOKEN 0x00000000
+ #define QTD_IN_TOKEN 0x00000100
+ #define QTD_SETUP_TOKEN 0x00000200
+#define QTD_STATUS_FIELD 0x000000FF
+ #define QTD_ACTIVE 0x00000080
+ #define QTD_HALTED 0x00000040
+ #define QTD_BUFFER_ERROR 0x00000020
+ #define QTD_BABBLE 0x00000010
+ #define QTD_XACT_ERROR 0x00000008
+ #define QTD_MISSED_UFRAME 0x00000004
+ #define QTD_SPLIT_XSTATE 0x00000002
+ #define QTD_START_SPLIT 0x00000000
+ #define QTD_COMPLETE_SPLIT 0x00000002
+ #define QTD_SPLIT_ERROR 0x00000001
+ #define QTD_PING_STATE 0x00000001
+ #define QTD_DO_OUT 0x00000000
+ #define QTD_DO_PING 0x00000001
+//-------------------------------------------------------------------------
+
+#define QH_I_BIT 0x00000080 // BIT 7
+#define QH_ENDPOINT_SPEED 0x00003000 // BIT 13:12
+ #define QH_FULL_SPEED 0x00000000
+ #define QH_LOW_SPEED 0x00001000
+ #define QH_HIGH_SPEED 0x00002000
+#define QH_DATA_TOGGLE_CONTROL 0x00004000 // BIT 14
+ #define QH_IGNORE_QTD_DT 0x00000000
+ #define QH_USE_QTD_DT 0x00004000
+#define QH_HEAD_OF_LIST 0x00008000 // BIT 15
+#define QH_CONTROL_ENDPOINT 0x08000000 // BIT 27
+#define QH_DATA_TOGGLE 0x80000000 // BIT 31
+
+#define QH_MULT_SETTING 0xC0000000 // BIT 31:30
+ #define QH_ONE_XFER 0x40000000
+ #define QH_TWO_XFER 0x80000000
+ #define QH_THREE_XFER 0xC0000000
+
+//-------------------------------------------------------------------------
+// Descriptor structure used to store qTD and QH addresses
+//-------------------------------------------------------------------------
+typedef struct {
+ EHCI_QH *PeriodicQh;
+ EHCI_QH *fpQHRepeat;
+ EHCI_QTD *fpqTDRepeat;
+} EHCI_DESC_PTRS;
+
+#endif // __EHCI_H
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/elib.c b/Core/EM/usb/rt/elib.c
new file mode 100644
index 0000000..1f21b78
--- /dev/null
+++ b/Core/EM/usb/rt/elib.c
@@ -0,0 +1,659 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/elib.c 22 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 22 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/elib.c $
+//
+// 22 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 21 3/18/13 4:47a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 20 9/28/12 2:39a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 19 8/29/12 8:16a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 18 4/07/11 3:48a Ryanchou
+// [TAG] EIP57802
+// [Category] Improvement
+// [Description] The variable dCount should not be increase, undo the
+// EIP55960 change in elib.c.
+// [Files] elib.c
+//
+// 17 4/06/11 3:53a Ryanchou
+// [TAG] EIP55960
+// [Category] Improvement
+// [Description] The Host Controller must halt within 16 micro-frames
+// after software clears the Run bit.
+// [Files] ehci.c, elib.c
+//
+// 16 3/31/11 9:45a Tonylo
+// [TAG] EIP56841
+// [Category] Improvement
+// [Description] Remove IO port 0x61 dependency.
+// [Files] elib.c
+//
+// 15 10/02/09 10:49a Olegi
+// Code cleanup.
+//
+// 14 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 13 5/22/07 12:28p Olegi
+// Added USB_BEEP_ENABLE token functionality.
+//
+// 12 4/26/07 6:10p Olegi
+// DwordReadMem and DwordWriteMem work with volatile memory.
+//
+// 7 10/12/06 9:03p Andriyn
+// Debug DELAY function: slow down portion of code
+//
+// 6 7/24/06 6:05p Olegi
+// FixedDelay optimization (by Stacy Howell)
+//
+// 5 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 12/19/05 10:14a Olegi
+// Beep routine modified.
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Elib.c
+//
+// Description: AMI USB MEM/IO/PCI access routines
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+
+extern USB_GLOBAL_DATA *gUsbData;
+//extern EFI_SMM_SYSTEM_TABLE *gSmst;
+
+UINT8 ByteReadIO(UINT16);
+UINT16 WritePCIConfig(UINT16, UINT8);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FixedDelay
+//
+// Description: This routine delays for specified number of micro seconds
+//
+// Input: wCount Amount of delay (count in 1 microsec)
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+FixedDelay(
+ UINTN Usec
+ )
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ UINTN Counter, i;
+ UINT32 Data32, PrevData;
+
+ Counter = Usec * 3;
+ Counter += Usec / 2;
+ Counter += (Usec * 2) / 25;
+
+ //
+ // Call WaitForTick for Counter + 1 ticks to try to guarantee Counter tick
+ // periods, thus attempting to ensure Microseconds of stall time.
+ //
+ if (Counter != 0) {
+
+ PrevData = IoRead32(PM_BASE_ADDRESS + 8);
+ for (i=0; i < Counter; ) {
+ Data32 = IoRead32(PM_BASE_ADDRESS + 8);
+ if (Data32 < PrevData) { // Reset if there is a overlap
+ PrevData=Data32;
+ continue;
+ }
+ i += (Data32 - PrevData);
+ PrevData = Data32;
+ }
+ }
+#else
+ pBS->Stall(Usec);
+#endif
+ return;
+}
+
+EFI_STATUS
+UsbHcStrucValidation(
+ HC_STRUC* HcStruc
+)
+{
+ UINTN Index;
+
+ if (HcStruc == NULL) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ if (HcStruc == gUsbData->HcTable[Index]) {
+ break;
+ }
+ }
+
+ if (Index == gUsbData->HcTableCount) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_USED)) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+UsbDevInfoValidation(
+ DEV_INFO* DevInfo
+)
+{
+ UINTN Index;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (DevInfo == NULL) {
+ return EFI_ACCESS_DENIED;
+ }
+
+ for (Index = 0; Index < MAX_DEVICES; Index++) {
+ if (DevInfo == &gUsbData->aDevInfoTable[Index]) {
+ break;
+ }
+ }
+
+ if (Index == MAX_DEVICES) {
+ return EFI_ACCESS_DENIED;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (DevInfo->fpPollEDPtr) {
+ if ((DevInfo->fpPollEDPtr < gUsbData->fpMemBlockStart) ||
+ ((DevInfo->fpPollEDPtr + sizeof(MEM_BLK)) > MemBlockEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+
+ if (DevInfo->fpPollTDPtr) {
+ if ((DevInfo->fpPollTDPtr < gUsbData->fpMemBlockStart) ||
+ ((DevInfo->fpPollTDPtr + sizeof(MEM_BLK)) > MemBlockEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+
+ if (DevInfo->fpPollDataBuffer) {
+ if ((DevInfo->fpPollDataBuffer < gUsbData->fpMemBlockStart) ||
+ ((DevInfo->fpPollDataBuffer + DevInfo->PollingLength) > MemBlockEnd)) {
+ return EFI_ACCESS_DENIED;
+ }
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordReadMem
+//
+// Description: This routine reads a DWORD from the specified Memory Address
+//
+// Input: dBaseAddr - Memory address to read
+// bOffset - Offset of dBaseAddr
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+DwordReadMem(UINT32 dBaseAddr, UINT16 wOffset)
+{
+ return *(volatile UINT32*)(UINTN)(dBaseAddr+wOffset);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordWriteMem
+//
+// Description: This routine writes a DWORD to a specified Memory Address
+//
+// Input: dBaseAddr - Memory address to write
+// bOffset - Offset of dBaseAddr
+// dValue - Data to write
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+DwordWriteMem(UINT32 dBaseAddr, UINT16 wOffset, UINT32 dValue)
+{
+ *(volatile UINT32*)(UINTN)(dBaseAddr+wOffset) = dValue;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordResetMem
+//
+// Description: This routine resets the specified bits at specified memory address
+//
+// Input: dBaseAddr - Memory address to read
+// bOffset - Offset of dBaseAddr
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+DwordResetMem(UINT32 dBaseAddr, UINT16 wOffset, UINT32 dValue)
+{
+ UINT32 data = DwordReadMem(dBaseAddr, wOffset);
+ data &= ~dValue;
+ DwordWriteMem(dBaseAddr, wOffset, data);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordSetMem
+//
+// Description: This routine sets the specified bits at specified memory address
+//
+// Input: dBaseAddr - Memory address to read
+// bOffset - Offset of dBaseAddr
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+DwordSetMem(UINT32 dBaseAddr, UINT16 wOffset, UINT32 dValue)
+{
+ UINT32 data = DwordReadMem(dBaseAddr, wOffset);
+ data |= dValue;
+ DwordWriteMem(dBaseAddr, wOffset, data);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ByteReadIO
+//
+// Description: This routine reads a Byte from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+ByteReadIO(UINT16 wIOAddr)
+{
+// UINT8 value;
+// gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT8, (UINT64)wIOAddr, 1, &value);
+// return value;
+ return IoRead8(wIOAddr);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ByteWriteIO
+//
+// Description: This routine writes a byte to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// bValue Byte value to write
+//
+// Output: None
+//
+// Modified: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ByteWriteIO (UINT16 wIOAddr, UINT8 bValue)
+{
+// gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT8, (UINT64)wIOAddr, 1, &bValue);
+ IoWrite8(wIOAddr, bValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WordReadIO
+//
+// Description: This routine reads a Word from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+WordReadIO(UINT16 wIOAddr)
+{
+// UINT16 value;
+// gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT16, (UINT64)wIOAddr, 1, &value);
+// return value;
+ return IoRead16(wIOAddr);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WordWriteIO
+//
+// Description: This routine writes a word to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// wValue Word value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+WordWriteIO (UINT16 wIOAddr, UINT16 wValue)
+{
+// gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT16, (UINT64)wIOAddr, 1, &wValue);
+ IoWrite16(wIOAddr, wValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordReadIO
+//
+// Description: This routine reads a dword from the specified IO address
+//
+// Input: wIOAddr I/O address to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+DwordReadIO(UINT16 wIOAddr)
+{
+// UINT32 value;
+// gSmst->SmmIo.Io.Read(&gSmst->SmmIo, SMM_IO_UINT32, (UINT64)wIOAddr, 1, &value);
+// return value;
+ return IoRead32(wIOAddr);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordWriteIO
+//
+// Description: This routine writes a double word to the specified IO address
+//
+// Input: wIOAddr I/O address to write
+// dValue Double word value to write
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+DwordWriteIO(UINT16 wIOAddr, UINT32 dValue)
+{
+// gSmst->SmmIo.Io.Write(&gSmst->SmmIo, SMM_IO_UINT32, (UINT64)wIOAddr, 1, &dValue);
+ IoWrite32(wIOAddr, dValue);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ReadPCIConfig
+//
+// Description: This routine reads from the PCI configuration space register
+// the value can be typecasted to 8bits - 32bits
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+//
+// Output: Value read
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+ReadPCIConfig(UINT16 BusDevFunc, UINT8 Register)
+{
+ UINT32 data;
+ DwordWriteIO(0xCF8, (UINT32)(0x80000000 | (BusDevFunc<<8) | (Register & 0xFC)));
+ data = DwordReadIO(0xCFC);
+ return (data >> ((Register & 3) << 3)); // Adjust uneven register
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ByteWritePCIConfig
+//
+// Description: This routine writes a byte value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ByteWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT8 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = WritePCIConfig(BusDevFunc, Register);
+ ByteWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WordWritePCIConfig
+//
+// Description: This routine writes a byte value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+WordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT16 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = WritePCIConfig(BusDevFunc, Register);
+ WordWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DwordWritePCIConfig
+//
+// Description: This routine writes a Dword value to the PCI configuration
+// register space
+//
+// Input: BusDevFunc - Bus, device & function number of the PCI device
+// Register - Register offset to read
+// Value - Value to write
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+DwordWritePCIConfig(UINT16 BusDevFunc, UINT8 Register, UINT32 Value)
+{
+ UINT16 wIOAddr;
+ wIOAddr = WritePCIConfig(BusDevFunc, Register);
+ DwordWriteIO (wIOAddr, Value);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: WritePCIConfig
+//
+// Description: This function opens PCI configuration for a given register
+//
+// Input: wBDF - Bus, device and function number
+// bReg - Register number to read
+//
+// Output: IO register to write the value
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+WritePCIConfig(UINT16 wBDF, UINT8 bReg)
+{
+ DwordWriteIO(0xCF8, (UINT32)(0x80000000 | (wBDF<<8) | (bReg & 0xFC)));
+ return (UINT16)(0xCFC+(bReg & 3));
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SpeakerBeep
+//
+// Description: This routine produces a sound on the internal PC speaker
+//
+// Input: bFreq - Sound frequency
+// wDuration - Sound duration in 15 microsecond units
+// fpHCStruc - Pointer to HCStruc
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SpeakerBeep (UINT8 bFreq, UINT16 wDuration, HC_STRUC* fpHCStruc)
+{
+#if USB_BEEP_ENABLE
+ UINT8 bValue;
+ if(gUsbData->dUSBStateFlag & USB_FLAG_ENABLE_BEEP_MESSAGE) {
+ ByteWriteIO((UINT8)0x43, (UINT8)0xB6);
+ ByteWriteIO((UINT8)0x42, (UINT8)bFreq);
+ ByteWriteIO((UINT8)0x42, (UINT8)bFreq);
+ bValue = ByteReadIO((UINT8)0x61);
+ ByteWriteIO((UINT8)0x61, (UINT8)(bValue | 03));
+ FixedDelay((UINTN)wDuration * 15);
+ ByteWriteIO((UINT8)0x61, (UINT8)(bValue));
+ }
+#endif
+}
+
+#if defined(DEBUG_SWITCH) && (DEBUG_SWITCH == 1)
+VOID DEBUG_DELAY()
+{
+ int i;
+ PrintDebugMsg(3,"\nDELAY: ");
+ for(i=0;i<10;i++){
+ PrintDebugMsg(3,"%d..",i);
+ FixedDelay(300 * 1000); // 200 msec delay
+ }
+ PrintDebugMsg(3,"\n");
+}
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/guids.c b/Core/EM/usb/rt/guids.c
new file mode 100644
index 0000000..fa0255d
--- /dev/null
+++ b/Core/EM/usb/rt/guids.c
@@ -0,0 +1,147 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/guids.c 21 8/08/11 5:28a Ryanchou $
+//
+// $Revision: 21 $
+//
+// $Date: 8/08/11 5:28a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/guids.c $
+//
+// 21 8/08/11 5:28a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 20 10/02/09 10:49a Olegi
+// Code cleanup.
+//
+// 19 2/04/09 12:54p Olegi
+// Added NonSmmEmul6064TrapProtocol GUID definition.
+//
+// 18 9/24/08 10:19a Rameshraju
+// Removed Usblegacyplatform support.
+//
+// 17 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 16 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 15 3/20/07 12:22p Olegi
+//
+// 14 11/15/06 3:42p Olegi
+//
+// 13 10/26/06 3:58p Olegi
+//
+// 12 5/03/06 9:59a Olegi
+//
+// 11 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 10 3/13/06 3:24p Felixp
+//
+// 9 3/01/06 3:51p Olegi
+//
+// 8 11/10/05 11:11a Olegi
+//
+// 7 10/20/05 2:44p Olegi
+//
+// 6 8/27/05 11:44a Andriyn
+//
+// 5 8/23/05 5:53p Olegi
+//
+// 4 8/05/05 3:38p Andriyn
+// Complience with EFI EDK
+//
+// 3 5/20/05 12:09p Andriyn
+//
+// 2 5/20/05 11:05a Andriyn
+// reconcile Aptio changes with Alaska
+//
+// 1 3/29/05 10:40a Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: guids.c
+//
+// Description: AMI USB guids library
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "amiusb.h"
+#include <Protocol\UsbHC.h>
+#include <Protocol\UsbPolicy.h>
+#include <setup.h>
+
+//
+// GUID variables
+//
+//EFI_GUID mAMIUsbCoreGuid = {0x4eaaaa1, 0x29a1, 0x11d7, 0x88, 0x38, 0x0, 0x50, 0x4, 0x73, 0xd4, 0xeb};
+//EFI_GUID gEfiLoadedImageGuid =
+//EFI_GUID gEfiSmmBaseProtocolGuid = EFI_SMM_BASE_PROTOCOL_GUID;
+//EFI_GUID gEfiSmmSwDispatchProtocolGuid = EFI_SMM_SW_DISPATCH_PROTOCOL_GUID;
+//EFI_GUID gEfiSmmUsbDispatchProtocolGuid = EFI_SMM_USB_DISPATCH_PROTOCOL_GUID;
+//EFI_GUID gEfiLoadedImageProtocolGuid = EFI_LOADED_IMAGE_PROTOCOL_GUID;
+//EFI_GUID gEfiDevicePathProtocolGuid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+//EFI_GUID gEfiUSBProtocolGuid = EFI_USB_PROTOCOL_GUID;
+//EFI_GUID gEfiSimplePointerProtocolGuid = EFI_SIMPLE_POINTER_PROTOCOL_GUID;
+//EFI_GUID gEfiSimpleTextInProtocolGuid = EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID;
+//EFI_GUID gEfiDriverBindingProtocolGuid = EFI_DRIVER_BINDING_PROTOCOL_GUID;
+EFI_GUID gEfiHotPlugDeviceGuid = { 0x220ac432, 0x1d43, 0x49e5, 0xa7, 0x4f, 0x4c, 0x9d, 0xa6, 0x7a, 0xd2, 0x3b };
+//EFI_GUID gEfiPciIoProtocolGuid = EFI_PCI_IO_PROTOCOL_GUID;
+//EFI_GUID gEfiBlockIoProtocolGuid = EFI_BLOCK_IO_PROTOCOL_GUID;
+//EFI_GUID gEfiComponentNameProtocolGuid = EFI_COMPONENT_NAME_PROTOCOL_GUID;
+//EFI_GUID gEfiSmmControlProtocolGuid = EFI_SMM_CONTROL_PROTOCOL_GUID;
+//EFI_GUID gEfiUsb2HcProtocolGuid = EFI_USB2_HC_PROTOCOL_GUID;
+//EFI_GUID gEfiUsbHcProtocolGuid = EFI_USB_HC_PROTOCOL_GUID;
+//EFI_GUID gEfiFirmwareVolumeProtocolGuid = EFI_FIRMWARE_VOLUME_PROTOCOL_GUID;
+EFI_GUID gEfiUsbPolicyProtocolGuid = EFI_USB_POLICY_PROTOCOL_GUID;
+EFI_GUID gEmul6064MsInputProtocolGuid = EFI_EMUL6064MSINPUT_PROTOCOL_GUID;
+EFI_GUID gEmul6064KbdInputProtocolGuid = EFI_EMUL6064KBDINPUT_PROTOCOL_GUID;
+EFI_GUID gEmul6064TrapProtocolGuid = EFI_EMUL6064TRAP_PROTOCOL_GUID;
+EFI_GUID gNonSmmEmul6064TrapProtocolGuid = EFI_NONSMMEMUL6064TRAP_PROTOCOL_GUID;
+EFI_GUID gUsbTimingPolicyProtocolGuid = USB_TIMING_POLICY_PROTOCOL_GUID;
+
+EFI_GUID gEfiSetupGuid = SETUP_GUID;
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/ohci.c b/Core/EM/usb/rt/ohci.c
new file mode 100644
index 0000000..2389a93
--- /dev/null
+++ b/Core/EM/usb/rt/ohci.c
@@ -0,0 +1,3379 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ohci.c 98 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 98 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ohci.c $
+//
+// 98 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 97 7/28/16 4:56a Wilsonlee
+// [TAG] EIP264662
+// [Category] Improvement
+// [Description] Don't install usb hw smi after reconnecting usb
+// controllers.
+// [Files] uhcd.c, usb.c, ohci.c, amiusb.c, amiusbhc.c
+//
+// 96 7/22/16 3:50a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 95 7/07/16 1:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 94 3/14/16 10:21p Wilsonlee
+// [TAG] EIP257506
+// [Category] Improvement
+// [Description] Add USB_KEYREPEAT_INTERVAL token to change the key
+// repeat interval.
+// [Files] usb.sdl, xhci.h, usbkbd.h, uhci.c, ohci.c, ehci.c
+//
+// 93 3/02/16 9:42p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 92 9/01/15 10:46p Wilsonlee
+// [TAG] EIP235977
+// [Category] Improvement
+// [Description] Break the loop which we check list processing TD if
+// NextTd is the same as Td.
+// [Files] ohci.c
+//
+// 91 3/08/15 10:50p Wilsonlee
+// [TAG] EIP207774
+// [Category] Improvement
+// [Description] Set USB_FLAG_DRIVER_STARTED flag when HC is running and
+// clear it if we don't start any HC.
+// [Files] uhci.c, usb.c, ehci.c, ohci.c, xhci.c, amiusb.h
+//
+// 90 1/22/15 10:19p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 89 5/01/14 3:56a Ryanchou
+// [TAG] EIP162589
+// [Category] Improvement
+// [Description] Do not register external controller as key repeat
+// controller.
+// [Files] ehci.c, ohci.c, uhci.c
+//
+// 88 4/30/14 6:13a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 87 4/30/14 5:25a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 86 2/26/14 1:56a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 85 7/26/13 2:36a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 84 7/22/13 10:31p Wilsonlee
+// [TAG] EIP125357
+// [Category] Improvement
+// [Description] Check if the port releases to a select host controller.
+// [Files] uhci.c, usb.c, usbhub.c, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 83 6/28/13 2:29a Roberthsu
+// [TAG] EIP124581
+// [Category] Improvement
+// [Description] Controller driver always return the length passed in
+// parameter, devices may return zero length data, it should be corrected.
+// [Files] ohci.c
+//
+// 82 6/02/13 11:42p Wilsonlee
+// [TAG] EIP123235
+// [Category] Improvement
+// [Description] Stop the usb host controller at ExitBootService if it
+// is an extend card or it doesn't support HW SMI.
+// [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c,
+// uhcd.c
+//
+// 81 4/18/13 1:02p Ryanchou
+// Add Teradici USB controller support.
+//
+// 80 4/10/13 11:23p Ryanchou
+// [TAG] EIP111483
+// [Category] Improvement
+// [Description] Increase the delay when OHCI port reset complete.
+// [Files] ohci.c
+//
+// 79 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 78 3/18/13 4:48a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 77 2/24/13 9:00p Wilsonlee
+// [TAG] EIP113541
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] System hangs at checkpoint 0xA2 when Win8 resume from S4.
+// [RootCause] The "HCHalted" bit and "Port Change Detect" bit are set
+// when the system S4 resume to Win8 OS.
+// [Solution] We need to clear the interrupt status even if the
+// "HCHalted" bit is set.
+// [Files] ehci.c, ohci.c, uhci.c
+//
+// 76 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 75 12/24/12 5:06a Ryanchou
+// [TAG] EIP103031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hans when loading QNX 6.5.0
+// [RootCause] The EHCI port detect change SMI is generated after
+// ownership change to OS.
+// [Solution] Clear the SMI enable bits and status bits even the
+// controller is OS owned.
+// [Files] ehci.c, ohci.c
+//
+// 74 12/06/12 12:39a Wilsonlee
+// [TAG] EIP103186
+// [Category] Improvement
+// [Description] Handle the error case "MEMIO was disabled" in USB
+// driver.
+// [Files] uhci.c, ohci.c, ehci.c, xhci.c
+//
+// 73 11/13/12 7:12a Wilsonlee
+// [TAG] EIP82553
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for XHCI.
+// [Files] usb.c, ehci.c, ohci.c, xhci.c, xhci.h
+//
+// 72 11/10/12 6:40a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 71 10/25/12 4:16a Wilsonlee
+// [TAG] EIP82354
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for OHCI.
+// [Files] usb.c, ehci.c, ohci.c
+//
+// 70 9/28/12 2:37a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 69 8/29/12 8:17a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 68 8/28/12 5:19a Ryanchou
+// [TAG] EIP98857
+// [Category] Improvement
+// [Description] WriteBackDoneHead status bit shall be cleared even
+// HccaDoneHead is zero.
+// [Files] ohci.c
+//
+// 67 7/25/12 4:44a Wilsonlee
+// [TAG] EIP95959
+// [Category] Improvement
+// [Description] Don't set INTERRUPT_ROUTING if the ohci is external usb
+// pci controller card.
+// [Files] ohci.c
+//
+// 66 5/04/12 6:38a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 65 5/04/12 5:25a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 64 5/03/12 6:01a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 63 11/08/11 1:57a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 62 9/26/11 11:40p Roberthsu
+// [TAG] EIP67230
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ntrig touch panel can not use on CedarTrail
+// [RootCause] Because ntrig report data over than 512 byte.Control
+// transfer check if over 512 than set length is 512.
+// [Solution] Remove check transfer length.
+// [Files] ohci.c,uhci.c,usbhid.c
+//
+// 61 8/24/11 2:14a Ryanchou
+// [TAG] EIP66448
+// [Category] New Feature
+// [Description] Clear connect status change and port enable status
+// change.
+// [Files] ohci.c
+//
+// 60 8/08/11 6:58a Ryanchou
+// [TAG] EIP54018
+// [Category] New Feature
+// [Description] Added USB S5 wake up support.
+// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h,
+// usbsb.c xhci.c
+//
+// 59 8/08/11 5:15a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 58 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 57 7/12/11 8:10a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 56 7/12/11 6:17a Ryanchou
+// [TAG] EIP59707
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The wireless USB keyboard does not work after boot into
+// windows loader.
+// [RootCause] The amount of data returned by the device exceeded the
+// size of the maximum data packet allowed, that causes babble error, and
+// BIOS does not re-init the polling TD.
+// [Solution] Re-init polling TD even the last transaction get error.
+// [Files] ohci.c
+//
+// 55 6/21/11 9:56a Ryanchou
+// [TAG] EIP59663
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Plug USB WLAN device may causes OHCI malfunction.
+// [RootCause] The devices have to connect to OHCI first, or it can't be
+// configured.
+// [Solution] Port routing route to EHCI after OHCI initialization.
+// [Files] ehci.c, ohci.c
+//
+// 54 5/03/11 10:10a Ryanchou
+// [TAG] EIP54283
+// [Category] Improvement
+// [Description] Follow XHCI spec ver 1.0 section 4.6.8 to recovery
+// endpoint halt.
+// [Files] ehci.c, ohci.c, uhci.c, usbdef.h, usbmass.c, xhci.c
+//
+// 53 4/06/11 1:33a Ryanchou
+// [TAG] EIP54782
+// [Category] Improvement
+// [Description] Change polling data size of HID devices to max packet
+// size of interrupt endpoint.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, xhci.c
+//
+// 52 3/30/11 9:04a Ryanchou
+//
+// 51 3/29/11 10:50p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 50 3/29/11 10:11a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 49 3/16/11 8:51a Ryanchou
+// [TAG] EIP55025
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Finger Print function fail
+// [RootCause] Wrong tranferred data size on short packet condition.
+// [Files] ohci.c
+//
+// 48 11/11/10 11:34p Ryanchou
+// [TAG] EIP45578
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB 3.0 device can't be detected.
+// [RootCause] Address Device Command fails.
+// [Solution] Reset the device and attempt the Address Device Command
+// again.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c, xhci.c
+//
+// 47 9/24/10 5:38p Olegi
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 46 6/07/10 8:55a Ryanchou
+// EIP38547: Fixed system halt when installing FreeBSD.
+//
+// 45 3/10/10 6:35p Olegi
+//
+// 44 3/06/10 1:11p Olegi
+//
+// 43 2/26/10 4:23p Olegi
+//
+// 42 2/23/10 1:21p Olegi
+// Work around Klockwork issues. EIP34370
+//
+// 41 2/08/10 10:00a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 40 1/04/10 9:20a Olegi
+// EIP32956: Polling rate for the keyboards has been changed from 8 ms to
+// 32 ms.
+//
+// 39 12/23/09 11:59a Olegi
+//
+// 38 12/08/09 3:33p Olegi
+// EIP32387: Bugfix in OHCI_FreeAllStruc; memory was not released properly
+// when USB_FORCE_64BIT_ALIGNMENT is set.
+//
+// 37 11/24/09 12:43p Olegi
+// EIP#26693: fixed OHCI_DISABLE_32MS_POLLING implementation.
+//
+// 36 10/30/09 5:47p Olegi
+//
+// 35 10/13/09 9:11a Olegi
+// EIP28707: OHCI ownership change modifications.
+//
+// 34 10/07/09 9:48a Olegi
+// USB Hub error handling improvement. EIP#25601.
+//
+// 33 9/15/09 10:21a Olegi
+// Added USB_INCMPT_HID_DATA_OVERFLOW incompatibility type.
+//
+// 32 2/17/09 4:01p Olegi
+//
+// 31 2/17/09 8:59a Olegi
+// Additional modifications in BulkTransfer routine to maximize the
+// bandwidth.
+//
+// 30 1/30/09 10:08a Olegi
+// MAX_BULK_DATA_SIZE limitation moved to individual HC drivers.
+//
+// 29 10/06/08 3:33p Olegi
+// EHCI change ownership testing in DOS fix (EIP#14855).
+//
+// 28 9/24/08 3:58p Olegi
+// Bugfix in the memory allocation in OHCI_ActivatePolling.
+//
+// 27 6/16/08 10:07a Olegi
+// Bugfix in OHCI_Start.
+//
+// 26 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 25 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 24 4/17/07 8:24a Olegi
+// Device detection algorythm update, in sync with Core8.
+//
+// 23 3/20/07 12:22p Olegi
+//
+// 22 1/16/07 3:24p Olegi
+// Change in OHCI_ControlTransfer: return 0 if transfer stalled.
+//
+// 21 1/02/07 12:17p Olegi
+//
+// 20 1/02/07 11:13a Olegi
+//
+// 19 12/28/06 4:32p Olegi
+// OHCI_ProcessRootHubStatusChange is modified to properly clear the
+// connect change status bit
+//
+// 18 12/22/06 4:05p Olegi
+// Timeout implementation.
+//
+// 17 12/20/06 2:30p Olegi
+//
+// 16 12/13/06 5:40p Olegi
+// X64 build update
+//
+// 14 11/09/06 10:16a Olegi
+//
+// 13 10/18/06 9:43a Andriyn
+// Fix: race condition on hot-plug in / plug-off
+//
+// 12 10/12/06 9:37p Andriyn
+// Fix: unexpected plug-off hangs with endless TIMEOUTs
+//
+// 11 6/09/06 10:29a Olegi
+// USB_FLAG_ENABLE_BEEP_MESSAGE flag is reset while handling change of the
+// controller ownership.
+//
+// 10 5/16/06 11:22a Olegi
+//
+// 9 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 8 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 7 3/06/06 6:26p Olegi
+//
+// 6 1/11/06 11:53a Olegi
+//
+// 5 12/01/05 5:48p Olegi
+//
+// 4 11/29/05 12:33p Andriyn
+//
+// 3 6/20/05 8:55a Olegi
+// .NET compiler with highest warning level and warning-as-error
+// modification.
+//
+// 2 6/03/05 6:09p Olegi
+// HW SMI registration change.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Ohci.c
+//
+// Description: AMI USB OHCI driver source file
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#endif
+
+#pragma warning (disable :4213)
+#pragma warning (disable :4706)
+
+UINT8 OHCI_FillHCDEntries(HCD_HEADER*);
+UINT8 OHCI_Start (HC_STRUC*);
+UINT8 OHCI_Stop (HC_STRUC*);
+UINT8 OHCI_DisableInterrupts (HC_STRUC*);
+UINT8 OHCI_EnableInterrupts (HC_STRUC*);
+UINT8 OHCI_ProcessInterrupt(HC_STRUC*);
+UINT8 OHCI_GetRootHubStatus (HC_STRUC*,UINT8, BOOLEAN);
+UINT8 OHCI_DisableRootHub (HC_STRUC*,UINT8);
+UINT8 OHCI_EnableRootHub (HC_STRUC*,UINT8);
+UINT16 OHCI_ControlTransfer (HC_STRUC*,DEV_INFO*,UINT16,UINT16,UINT16,UINT8*,UINT16);
+UINT32 OHCI_BulkTransfer (HC_STRUC*,DEV_INFO*,UINT8,UINT8*,UINT32);
+UINT16 OHCI_InterruptTransfer (HC_STRUC*, DEV_INFO*, UINT8, UINT16, UINT8*, UINT16);
+UINT8 OHCI_DeactivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 OHCI_ActivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 OHCI_DisableKeyRepeat (HC_STRUC*);
+UINT8 OHCI_EnableKeyRepeat (HC_STRUC*);
+UINT8 OHCI_ResetRootHub (HC_STRUC*,UINT8);
+UINT8 OHCI_GlobalSuspend (HC_STRUC*); //(EIP54018+)
+
+UINT8 OHCI_EnumeratePorts(HC_STRUC*);
+UINT8 OHCI_StartEDSchedule(HC_STRUC*);
+UINT8 OhciAddPeriodicEd (HC_STRUC*, OHCI_ED*);
+UINT8 OhciRemovePeriodicEd (HC_STRUC*, OHCI_ED*);
+UINT8 OHCI_RepeatTDCallBack(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 OHCI_ResetHC(HC_STRUC*);
+UINT8 OHCI_StopUnsupportedHC(HC_STRUC*);
+UINT32 OHCI_ProcessRootHubStatusChange(HC_STRUC*);
+UINT8 OHCIWaitForTransferComplete(HC_STRUC*, OHCI_ED*, OHCI_TD*,DEV_INFO*);
+UINT8 OHCI_ControlTDCallback(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+VOID OHCI_ProcessTD(HC_STRUC*, OHCI_TD*);
+UINT8 OHCI_GeneralTDCallback(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 OHCI_PollingTDCallback(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+VOID StopControllerType(UINT8);
+UINT8 USBCheckPortChange (HC_STRUC*, UINT8, UINT8);
+VOID OHCI_FreeAllStruc(HC_STRUC* fpHCStruc); //(EIP28707+)
+BOOLEAN OhciIsHalted(HC_STRUC*);
+UINT8 OhciTranslateInterval(UINT8);
+
+UINT8 UsbGetDataToggle(DEV_INFO*,UINT8);
+VOID UsbUpdateDataToggle(DEV_INFO*, UINT8, UINT8);
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gCheckUsbApiParameter;
+
+extern void USB_InitFrameList (HC_STRUC*, UINT32);
+extern UINT32 ReadPCIConfig(UINT16, UINT8);
+extern void WordWritePCIConfig(UINT16, UINT8, UINT16);
+extern void DwordWritePCIConfig(UINT16, UINT8, UINT32);
+extern UINT32 DwordReadMem(UINT32, UINT16);
+extern void DwordWriteMem(UINT32, UINT16, UINT32);
+extern void DwordSetMem(UINT32, UINT16, UINT32);
+extern void DwordResetMem(UINT32, UINT16, UINT32);
+extern void FixedDelay(UINTN);
+extern void* USB_MemAlloc (UINT16);
+extern UINT8 USB_InstallCallBackFunction (CALLBACK_FUNC);
+extern DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*);
+extern UINT8 USB_MemFree(void _FAR_*, UINT16);
+extern UINT8 USB_DisconnectDevice(HC_STRUC*, UINT8, UINT8); //(EIP28707+)
+#if USB_DEV_KBD
+extern void USBKBDPeriodicInterruptHandler(HC_STRUC*);
+extern void USBKeyRepeat(HC_STRUC*, UINT8);
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_FillHCDEntries
+//
+// DESCRIPTION: This function fills the host controller driver
+// routine pointers
+//
+// PARAMETERS: fpHCDHeader Ptr to the host controller header structure
+//
+// RETURN: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_FillHCDEntries(HCD_HEADER *fpHCDHeader)
+{
+ //
+ // Fill the routines here
+ //
+ fpHCDHeader->pfnHCDStart = OHCI_Start;
+ fpHCDHeader->pfnHCDStop = OHCI_Stop;
+ fpHCDHeader->pfnHCDEnumeratePorts = OHCI_EnumeratePorts;
+ fpHCDHeader->pfnHCDDisableInterrupts = OHCI_DisableInterrupts;
+ fpHCDHeader->pfnHCDEnableInterrupts = OHCI_EnableInterrupts;
+ fpHCDHeader->pfnHCDProcessInterrupt = OHCI_ProcessInterrupt;
+ fpHCDHeader->pfnHCDGetRootHubStatus = OHCI_GetRootHubStatus;
+ fpHCDHeader->pfnHCDDisableRootHub = OHCI_DisableRootHub;
+ fpHCDHeader->pfnHCDEnableRootHub = OHCI_EnableRootHub;
+ fpHCDHeader->pfnHCDControlTransfer = OHCI_ControlTransfer;
+ fpHCDHeader->pfnHCDBulkTransfer = OHCI_BulkTransfer;
+ fpHCDHeader->pfnHCDInterruptTransfer = OHCI_InterruptTransfer;
+ fpHCDHeader->pfnHCDDeactivatePolling = OHCI_DeactivatePolling;
+ fpHCDHeader->pfnHCDActivatePolling = OHCI_ActivatePolling;
+ fpHCDHeader->pfnHCDDisableKeyRepeat = OHCI_DisableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableKeyRepeat = OHCI_EnableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableEndpoints = USB_EnableEndpointsDummy;
+ fpHCDHeader->pfnHCDInitDeviceData = USB_InitDeviceDataDummy;
+ fpHCDHeader->pfnHCDDeinitDeviceData = USB_DeinitDeviceDataDummy;
+ fpHCDHeader->pfnHCDResetRootHub = OHCI_ResetRootHub;
+ fpHCDHeader->pfnHCDClearEndpointState = 0; //(EIP54283+)
+ fpHCDHeader->pfnHCDGlobalSuspend = OHCI_GlobalSuspend; //(EIP54018+)
+
+ USB_InstallCallBackFunction(OHCI_ControlTDCallback);
+ USB_InstallCallBackFunction(OHCI_GeneralTDCallback);
+ USB_InstallCallBackFunction(OHCI_PollingTDCallback);
+ USB_InstallCallBackFunction(OHCI_RepeatTDCallBack);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_Start
+//
+// DESCRIPTION: This API function is called to start a OHCI host controller.
+// The input to the routine is the pointer to the HC structure
+// that defines this host controller
+//
+// PARAMETERS: fpHCStruc Ptr to the host controller structure
+//
+// RETURN: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_Start (HC_STRUC* fpHCStruc)
+{
+ UINT32 OhciControlReg = 0;
+ UINT32 BaseAddr;
+ UINT32 HcFmInterval;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ fpHCStruc->wAsyncListSize = OHCI_FRAME_LIST_SIZE;
+ fpHCStruc->dMaxBulkDataSize = MAX_OHCI_BULK_DATA_SIZE;
+
+ //
+ // Get memory base address of the HC and store it in the HCStruc
+ //
+ BaseAddr = ReadPCIConfig(fpHCStruc->wBusDevFuncNum, USB_MEM_BASE_ADDRESS);
+ BaseAddr &= 0xFFFFFFF0; // Mask lower bits
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)BaseAddr, fpHCStruc->BaseAddressSize);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Usb Mmio address is invalid, it is in SMRAM\n");
+ return USB_ERROR;
+ }
+ EfiStatus = AmiValidateMmioBuffer((VOID*)fpHCStruc->fpFrameList, 0x100);
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+
+ fpHCStruc->BaseAddress = BaseAddr;
+
+ //
+ // Get the number of ports supported by the host controller (Offset 48h)
+ //
+ fpHCStruc->bNumPorts = (UINT8)DwordReadMem(BaseAddr, OHCI_RH_DESCRIPTOR_A);
+
+ USB_InitFrameList (fpHCStruc, 0);
+
+ //
+ // Enable the ED schedules
+ //
+ if (OHCI_StartEDSchedule(fpHCStruc) == USB_ERROR) return USB_ERROR;
+
+ //
+ // First stop the host controller if it is at all active
+ //
+ if (OHCI_DisableInterrupts(fpHCStruc) == USB_ERROR) return USB_ERROR;
+
+ // Save the contents of the HcFmInterval register
+ HcFmInterval = DwordReadMem(BaseAddr, OHCI_FRAME_INTERVAL);
+ HcFmInterval &= 0x3FFF;
+ if (HcFmInterval != 0x2EDF) {
+ USB_DEBUG(3, "OHCI: HcFmInterval %x\n", HcFmInterval);
+ }
+ HcFmInterval |= (((6 * (HcFmInterval - 210)) / 7) & 0x7FFF) << 16;
+
+ // Issue a controller reset
+ if (OHCI_ResetHC(fpHCStruc) != USB_SUCCESS) {
+ return USB_ERROR;
+ }
+
+ // Restore the value of the HcFmInterval register
+ DwordWriteMem(BaseAddr, OHCI_FRAME_INTERVAL, HcFmInterval);
+
+ //
+ // Program the frame list base address register
+ //
+ DwordWriteMem(BaseAddr, OHCI_HCCA_REG, (UINT32)(UINTN)fpHCStruc->fpFrameList);
+
+ //
+ // Set the periodic start time = 2A27h (10% off from HcFmInterval-2EDFh)
+ //
+ DwordWriteMem(BaseAddr, OHCI_PERIODIC_START, (((HcFmInterval & 0x3FFF) * 9) / 10) & 0x3FFF);
+
+ //
+ // Start the host controller for periodic list and control list.
+ //
+ OhciControlReg = (PERIODIC_LIST_ENABLE | CONTROL_LIST_ENABLE |
+ BULK_LIST_ENABLE | USBOPERATIONAL);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ OhciControlReg |= INTERRUPT_ROUTING;
+ }
+#endif
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_REG,
+ OhciControlReg);
+
+ //
+ // Enable interrupts from the host controller, enable SOF, WDH, RHSC interrupts
+ //
+ DwordWriteMem(BaseAddr, OHCI_INTERRUPT_ENABLE,
+ MASTER_INTERRUPT_ENABLE | WRITEBACK_DONEHEAD_ENABLE |
+ RH_STATUS_CHANGE_ENABLE | OWNERSHIP_CHANGE_ENABLE);
+
+ //
+ // Set the HC state to running
+ //
+ fpHCStruc->dHCFlag |= HC_STATE_RUNNING;
+
+ // Set USB_FLAG_DRIVER_STARTED flag when HC is running.
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_DRIVER_STARTED)) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_DRIVER_STARTED;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ //
+ // Register the USB HW SMI handler
+ //
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ UsbInstallHwSmiHandler(fpHCStruc);
+ } else {
+ USBSB_InstallUsbIntTimerHandler();
+ }
+#endif
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_Stop
+//
+// DESCRIPTION: This API function is called to stop the OHCI controller.
+// The input to the routine is the pointer to the HC structure
+// that defines this host controller.
+//
+// PARAMETERS: fpHCStruc Ptr to the host controller structure
+//
+// RETURN: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_Stop (HC_STRUC* fpHCStruc)
+{
+ UINT8 Port;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ for (Port = 1; Port <= fpHCStruc->bNumPorts; Port++) {
+ USB_DisconnectDevice(fpHCStruc, (UINT8)(fpHCStruc->bHCNumber | BIT7), Port);
+ }
+
+ //
+ // Reset Host Controller
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_REG, USBRESET);
+ FixedDelay(gUsbData->UsbTimingPolicy.OhciHcResetDelay * 1000); // Wait 10ms for assertion of reset
+
+ //
+ // Disable interrupts
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_DISABLE, 0xffffffff);
+
+ //
+ // Disable OHCI KBC Emulation
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_HCE_CONTROL, 0);
+
+ USB_InitFrameList (fpHCStruc, 0);
+ OHCI_FreeAllStruc(fpHCStruc); //(EIP28707+)
+
+ USBKeyRepeat(fpHCStruc, 3);
+
+ fpHCStruc->dHCFlag &= ~HC_STATE_RUNNING;
+
+ CheckBiosOwnedHc();
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_RepeatTDCallBack
+//
+// DESCRIPTION: This function is called when TdRepeat/TD32ms completes
+// a transaction. This TD runs a dummy interrupt transaction
+// to a non-existant device address for the purpose of
+// generating a periodic timeout interrupt which in turn
+// is used to generate keyboard repeat or update LED status.
+//
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+// fpDevInfo NULL (pDevInfo is not valid)
+// fpTD Pointer to the TD that completed
+// fpBuffer Not used
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_RepeatTDCallBack(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ OHCI_DESC_PTRS *DescPtrs = HcStruc->stDescPtrs.fpOHCIDescPtrs;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)DescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs + sizeof(OHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->fpTDRepeat < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->fpTDRepeat + sizeof(OHCI_TD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ DescPtrs->fpTDRepeat->bActiveFlag = FALSE;
+
+#if USB_DEV_KBD
+ USBKBDPeriodicInterruptHandler(HcStruc);
+#endif
+
+ if (((UINT8*)DescPtrs->fpEDRepeat < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->fpEDRepeat + sizeof(OHCI_ED)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (!(DescPtrs->fpEDRepeat->dControl & ED_SKIP_TDQ)) {
+ //
+ // Rebind the TD to its parent ED
+ //
+ DescPtrs->fpEDRepeat->fpHeadPointer = (UINT32)(UINTN)DescPtrs->fpTDRepeat;
+
+ //
+ // Clear the link pointer. It may point to some other TD
+ //
+ DescPtrs->fpTDRepeat->fpLinkPointer = OHCI_TERMINATE;
+
+ //
+ // Reactivate the TD
+ //
+ DescPtrs->fpTDRepeat->dControlStatus = DescPtrs->fpTDRepeat->dCSReloadValue;
+ DescPtrs->fpTDRepeat->bActiveFlag = TRUE;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_DisableInterrupts
+//
+// DESCRIPTION: This API function is called to disable the interrupts
+// generated by the OHCI host controller. The input to the
+// routine is the pointer to the HC structure that defines this
+// host controller. This routine will stop the HC to avoid
+// further interrupts.
+//
+// PARAMETERS: fpHCStruc Ptr to the host controller structure
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_DisableInterrupts (HC_STRUC* fpHCStruc)
+{
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ //
+ // Disable interrupt generation (global) bit (Set bit31)
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_DISABLE, MASTER_INTERRUPT_ENABLE);
+ //
+ // Disable periodic, isochronous, control and bulk list processing, reset bits 2 to 5
+ //
+ DwordResetMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_REG, BIT2 + BIT3 + BIT4 + BIT5);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_EnableInterrupts
+//
+// DESCRIPTION: This function enables the HC interrupts
+//
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_EnableInterrupts (HC_STRUC* fpHCStruc)
+{
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ //
+ // Enable periodic, control and bulk list processing
+ // Set bit 2, 4 & 5
+ //
+ DwordSetMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_REG, BIT2 + BIT4 + BIT5);
+ //
+ // Enable interrupt generation (global) bit
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_ENABLE, MASTER_INTERRUPT_ENABLE);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_ProcessInterrupt
+//
+// DESCRIPTION: This function is called when the USB interrupt bit is
+// set. This function will parse through the TDs and QHs to
+// find out completed TDs and call their respective call
+// back functions
+//
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+//
+// RETURN: USB_ERROR - Interrupt not processed
+// USB_SUCCESS - Interrupt processed
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_ProcessInterrupt(HC_STRUC* fpHCStruc)
+{
+ OHCI_TD *fpTD, *fpTD1;
+ UINT8 bIntProcessFlag = USB_ERROR; // Set as interrupt not processed
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ // Make sure MEMIO & Bus mastering are enabled
+ if (((UINT8)ReadPCIConfig(fpHCStruc->wBusDevFuncNum, USB_REG_COMMAND) & 0x6) != 0x6) {
+ return bIntProcessFlag;
+ }
+
+ if ((ReadPCIConfig(fpHCStruc->wBusDevFuncNum, USB_MEM_BASE_ADDRESS) & ~(0x7F)) !=
+ (UINT32)fpHCStruc->BaseAddress) {
+ return bIntProcessFlag;
+ }
+ //
+ // Check the interrupt status register for an ownership change. If this bit
+ // is set, it means that the O/S USB device driver is attempting to takeover
+ // control of the host controller. In this case the host controller is
+ // shut down and the interrupt routing bit in the control register is cleared
+ // (this disables SMI generation and enebles standard IRQ generation from
+ // the USB host controller.
+ //
+ if (DwordReadMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS) & OWNERSHIP_CHANGE) {
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS, OWNERSHIP_CHANGE);
+ if (DwordReadMem((UINT32)fpHCStruc->BaseAddress, OHCI_HCCA_REG) == (UINT32)(UINTN)fpHCStruc->fpFrameList) {
+ //
+ // OS tries to take the control over HC
+ //
+ gUsbData->dUSBStateFlag &= (~USB_FLAG_ENABLE_BEEP_MESSAGE);
+
+ OHCI_StopUnsupportedHC(fpHCStruc);
+
+ OHCI_Stop(fpHCStruc);
+ return USB_SUCCESS; // Set interrupt as processed
+ } else { // Ownership comes back to the driver - reinit
+ gUsbData->bHandOverInProgress = FALSE;
+ gUsbData->dUSBStateFlag |= (USB_FLAG_ENABLE_BEEP_MESSAGE);
+ OHCI_Start(fpHCStruc);
+ return USB_SUCCESS; // Set interrupt as processed
+ }
+ } // ownership change
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) return USB_ERROR;
+
+ if (OhciIsHalted(fpHCStruc)) {
+ // Clear All bits of the interrupt status
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS,
+ DwordReadMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS));
+ return bIntProcessFlag;
+ }
+ //
+ // Check whether the controller is still under BIOS control
+ // Read the base address of the Periodic Frame List to the OHCI HCCA
+ // register and compare with stored value
+ //
+ if ((DwordReadMem((UINT32)fpHCStruc->BaseAddress, OHCI_HCCA_REG) & 0xFFFFFF00) !=
+ (UINT32)(UINTN)fpHCStruc->fpFrameList) {
+ return bIntProcessFlag;
+ }
+ //
+ // Check the interrupt status register for a root hub status change. If
+ // this bit is set, then a device has been attached or removed from one of
+ // the ports on the root hub.
+ //
+ if (DwordReadMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS) & RH_STATUS_CHANGE) {
+ //
+ // Stop the periodic list processing to avoid more interrupts from HC
+ //
+ DwordResetMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_REG, PERIODIC_LIST_ENABLE);
+// USB_DEBUG(3, "before OHCI_ProcessRootHubStatusChange\n");
+ // Handle root hub change
+ bIntProcessFlag = (UINT8)OHCI_ProcessRootHubStatusChange(fpHCStruc);
+// USB_DEBUG(3, "after OHCI_ProcessRootHubStatusChange\n");
+ //
+ // Re-enable the periodic list processing
+ //
+ DwordSetMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_REG, PERIODIC_LIST_ENABLE);
+ }
+
+ //
+ // Check the interrupt status register for a one or more TDs completing.
+ //
+ if (!(DwordReadMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS) & WRITEBACK_DONEHEAD)) {
+ return USB_SUCCESS;
+ }
+ bIntProcessFlag = USB_SUCCESS; // Set interrupt as processed
+
+ //
+ // The memory dword at HCCADONEHEAD has been updated to contain the head
+ // pointer of the linked list of TDs that have completed. Walk through
+ // this list processing TDs as we go.
+ //
+ for (;;) {
+ fpTD = (OHCI_TD*)(UINTN)(((OHCI_HCCA_PTRS*)fpHCStruc->fpFrameList)->dHccaDoneHead);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpTD, sizeof(OHCI_TD));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+ ((OHCI_HCCA_PTRS*)fpHCStruc->fpFrameList)->dHccaDoneHead = 0;
+
+ //
+ // Clear the WRITEBACK_DONEHEAD bit of the interrupt status register
+ // in the host controller
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS, WRITEBACK_DONEHEAD);
+
+ if (!fpTD) break; // no TDs in the list
+
+ do {
+ fpTD = (OHCI_TD*)((UINTN)fpTD & 0xfffffff0);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpTD, sizeof(OHCI_TD));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+ fpTD1 = (OHCI_TD*)fpTD->fpLinkPointer;
+ OHCI_ProcessTD(fpHCStruc, fpTD);
+ // Host controllers might change NextTD pointer to Td, then it causes
+ // infinite loop in this routing. Break this loop if NextTd is the same as Td.
+ if (fpTD == fpTD1) {
+ break;
+ }
+ fpTD = fpTD1;
+ } while (fpTD);
+ } // Check if any TDs completed while processing
+
+ return bIntProcessFlag;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_GetRootHubStatus
+//
+// DESCRIPTION: This function returns the port connect status for the
+// root hub port
+//
+// PARAMETERS: pHCStruc Pointer to HCStruc of the host controller
+// bPortNum Port in the HC whose status is requested
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_GetRootHubStatus(
+ HC_STRUC* fpHCStruc,
+ UINT8 bPortNum,
+ BOOLEAN ClearChangeBits
+)
+{
+ UINT8 bRHStatus = USB_PORT_STAT_DEV_OWNER;
+ UINT32 dPortStatus;
+ UINT16 wPortReg = ((UINT16)bPortNum << 2) + (OHCI_RH_PORT1_STATUS - 4);
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ dPortStatus = DwordReadMem((UINT32)fpHCStruc->BaseAddress, wPortReg);
+ USB_DEBUG(3, "Ohci port[%d] status: %08x\n", bPortNum, dPortStatus);
+
+ if (dPortStatus & CURRENT_CONNECT_STATUS) {
+ bRHStatus |= USB_PORT_STAT_DEV_CONNECTED;
+ if (dPortStatus & PORT_ENABLE_STATUS) {
+ bRHStatus |= USB_PORT_STAT_DEV_ENABLED;
+ }
+ }
+
+ bRHStatus |= USB_PORT_STAT_DEV_FULLSPEED; // Assume full speed and set the flag
+ if (dPortStatus & LOW_SPEED_DEVICE_ATTACHED) {
+ bRHStatus &= ~USB_PORT_STAT_DEV_FULLSPEED; // Reset full speed
+ bRHStatus |= USB_PORT_STAT_DEV_LOWSPEED; // Set low speed flag
+ }
+
+ if (dPortStatus & CONNECT_STATUS_CHANGE) {
+ if (ClearChangeBits == TRUE)
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, wPortReg, CONNECT_STATUS_CHANGE); //(EIP66448+)
+ bRHStatus |= USB_PORT_STAT_DEV_CONNECT_CHANGED; // Set connect status change flag
+ }
+ //(EIP66448+)>
+ if (dPortStatus & PORT_ENABLE_STATUS_CHANGE) {
+ if (ClearChangeBits == TRUE) {
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, wPortReg, PORT_ENABLE_STATUS_CHANGE);
+ }
+ }
+ //<(EIP66448+)
+ return bRHStatus;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_DisableRootHub
+//
+// DESCRIPTION: This function disables the specified root hub port.
+//
+// PARAMETERS: fpHCStruc Pointer to HCStruc of the host controller
+// bPortNum Port in the HC to be disabled.
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_DisableRootHub (HC_STRUC* fpHCStruc, UINT8 bPortNum)
+{
+ UINT32 dPortReg = ((UINT32)bPortNum << 2) + (OHCI_RH_PORT1_STATUS - 4);
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, (UINT16)dPortReg, CLEAR_PORT_ENABLE);
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_EnableRootHub
+//
+// DESCRIPTION: This function enables the specified root hub port.
+//
+// PARAMETERS: fpHCStruc Pointer to HCStruc of the host controller
+// bPortNum Port in the HC to be enabled.
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_EnableRootHub (HC_STRUC* fpHCStruc,UINT8 bPortNum)
+{
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_ResetRootHub
+//
+// DESCRIPTION: This function resets the specified root hub port.
+//
+// PARAMETERS: HcStruc Pointer to HCStruc of the host controller
+// PortNum Port in the HC to be disabled.
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_ResetRootHub (HC_STRUC* HcStruc, UINT8 PortNum)
+{
+ UINT32 BaseAddr = (UINT32)HcStruc->BaseAddress;
+ UINT16 PortReg = ((UINT16)PortNum << 2) + (OHCI_RH_PORT1_STATUS - 4);
+ UINT32 i;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ DwordWriteMem(BaseAddr, PortReg, SET_PORT_RESET); // Reset the port
+
+ // The reset signaling must be driven for a minimum of 10ms
+ FixedDelay(10 * 1000);
+
+ //
+ // Wait for reset to complete
+ //
+ for (i = 0; i < 500; i++) {
+ if (DwordReadMem(BaseAddr, PortReg) & PORT_RESET_STATUS_CHANGE) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+
+ if (!(DwordReadMem(BaseAddr, PortReg) & PORT_RESET_STATUS_CHANGE)) {
+ USB_DEBUG(3, "OHCI: port reset timeout, status: %08x\n",
+ DwordReadMem(BaseAddr, PortReg));
+ return USB_ERROR;
+ }
+
+ //
+ // Clear the reset status change status
+ //
+ DwordWriteMem(BaseAddr, PortReg, PORT_RESET_STATUS_CHANGE);
+
+ // Some devices need a delay here
+ FixedDelay(3 * 1000); // 3 ms delay
+
+ return USB_SUCCESS;
+}
+
+ //(EIP54018+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: OHCI_GlobalSuspend
+//
+// Description:
+// This function suspend the OHCI HC.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_GlobalSuspend(
+ HC_STRUC* HcStruc
+)
+{
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (OhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ DwordWriteMem((UINT32)HcStruc->BaseAddress, OHCI_INTERRUPT_ENABLE,
+ RESUME_DETECTED_ENABLE);
+ FixedDelay(40 * 1000);
+ DwordWriteMem((UINT32)HcStruc->BaseAddress, OHCI_CONTROL_REG,
+ USBSUSPEND | REMOTE_WAKEUP_ENABLE);
+ FixedDelay(20 * 1000);
+
+ HcStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+ HcStruc->dHCFlag |= HC_STATE_SUSPEND;
+
+ return USB_SUCCESS;
+}
+ //<(EIP54018+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_ControlTransfer
+//
+// DESCRIPTION: This function executes a device request command transaction
+// on the USB. One setup packet is generated containing the
+// device request parameters supplied by the caller. The setup
+// packet may be followed by data in or data out packets
+// containing data sent from the host to the device
+// or vice-versa. This function will not return until the
+// request either completes successfully or completes in error
+// (due to time out, etc.)
+//
+// PARAMETERS: fpHCStruc Pointer to HCStruc of the host controller
+// pDevInfo DeviceInfo structure (if available else 0)
+// wRequest Request type (low byte)
+// Bit 7 : Data direction
+// 0 = Host sending data to device
+// 1 = Device sending data to host
+// Bit 6-5 : Type
+// 00 = Standard USB request
+// 01 = Class specific
+// 10 = Vendor specific
+// 11 = Reserved
+// Bit 4-0 : Recipient
+// 00000 = Device
+// 00001 = Interface
+// 00010 = Endpoint
+// 00100 - 11111 = Reserved
+// Request code, a one byte code describing
+// the actual device request to be executed
+// (ex: Get Configuration, Set Address etc)
+// wIndex wIndex request parameter (meaning varies)
+// wValue wValue request parameter (meaning varies)
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// wLength wLength request parameter, number of bytes
+// of data to be transferred in or out
+// of the host controller
+//
+//
+// RETURN: Number of bytes transferred
+//
+//
+// NOTES: Do not use USB_SUCCESS or USB_ERROR as returned values
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+OHCI_ControlTransfer (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT16 wRequest,
+ UINT16 wIndex,
+ UINT16 wValue,
+ UINT8 *fpBuffer,
+ UINT16 wLength)
+{
+ UINT16 *fpData;
+ OHCI_DESC_PTRS *fpDescPtrs = fpHCStruc->stDescPtrs.fpOHCIDescPtrs;
+ OHCI_ED *fpED;
+ OHCI_TD *fpTD;
+ UINT32 dData;
+ UINT16 wData;
+ UINT8 CompletionCode;
+ UINT32 TransferLength;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ if (wLength != 0) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Ohci ControlTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (OhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+ //FixedDelay(5 * 1000); // 5 ms delay is necessary for OHCI host controllers
+
+ if( !VALID_DEVINFO( fpDevInfo) )
+ return 0;
+ if (((UINT8*)fpDescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs + sizeof(OHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return 0;
+ }
+ if (((UINT8*)fpDescPtrs->fpEDControl < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs->fpEDControl + sizeof(OHCI_ED)) > MemBlockEnd)) {
+ return 0;
+ }
+ if (((UINT8*)fpDescPtrs->fpTDControlSetup < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs->fpTDControlSetup + sizeof(OHCI_TD)) > MemBlockEnd)) {
+ return 0;
+ }
+ if (((UINT8*)fpDescPtrs->fpTDControlData < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs->fpTDControlData + sizeof(OHCI_TD)) > MemBlockEnd)) {
+ return 0;
+ }
+ if (((UINT8*)fpDescPtrs->fpTDControlStatus < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs->fpTDControlStatus + sizeof(OHCI_TD)) > MemBlockEnd)) {
+ return 0;
+ }
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ //
+ // Build the device request in the data area of the control setup qTD
+ //
+ fpData = (UINT16*)fpDescPtrs->fpTDControlSetup->aSetupData;
+ *fpData++ = wRequest;
+ *fpData++ = wValue;
+ *fpData++ = wIndex;
+ *fpData++ = wLength;
+ *(UINTN*)fpData = (UINTN)fpBuffer;
+ //
+ // Prepare some registers that will be used in building the TDs below.
+ // wLength contains the data length.
+ // fpBuffer contains the absolute address of the data buffer.
+ // wRequest contains the request type (bit 7 = 0/1 for Out/In).
+ // fpDevInfo will contain a pointer to the DeviceInfo structure for the given device.
+ //
+ // Ready the EDControl for the control transfer.
+ //
+ fpED = fpDescPtrs->fpEDControl;
+ //
+ // The ED control field will be set so
+ // Function address & Endpoint number = ESI,
+ // Direction = From TD,
+ // Speed = DeviceInfo.bEndpointSpeed,
+ // Skip = 1, Format = 0,
+ // Max packet size = DeviceInfo.wEndp0MaxPacket
+ // The HeadPointer field will be set to TDControlSetup
+ // The TailPointer field will be set to OHCI_TERMINATE
+ // The LinkPointer field will be set to OHCI_TERMINATE
+ //
+ dData = (UINT32)fpDevInfo->wEndp0MaxPacket;
+ if (dData > 0x40) dData = 0x40; // Force the max packet size to 64 bytes
+ dData <<= 16; // dData[26:16] = device's packet size
+ wData = (UINT16)fpDevInfo->bEndpointSpeed; // 00/01/10 for HI/LO/FULL
+ wData = (wData & 1) << 13; // wData[13] = full/low speed flag
+ wData |= fpDevInfo->bDeviceAddress | ED_SKIP_TDQ;
+ fpED->dControl = dData | wData;
+ fpED->fpTailPointer = 0;
+ fpED->fpEDLinkPointer = 0;
+
+ fpTD = fpDescPtrs->fpTDControlSetup;
+ //
+ // The ControlStatus field will be set so
+ // Buffer Rounding = 1,
+ // Direction PID = GTD_SETUP_PACKET,
+ // Delay Interrupt = GTD_IntD,
+ // Data Toggle = GTD_SETUP_TOGGLE,
+ // Error Count = GTD_NO_ERRORS,
+ // Condition Code = GTD_NOT_ACCESSED
+ // The CurrentBufferPointer field will point to the TD's SetupData buffer
+ // which was before initialized to contain a DeviceRequest struc.
+ // The BufferEnd field will point to the last byte of the TD's SetupData
+ // buffer.
+ // The LinkPointer field will point to the TDControlData if data will
+ // be sent/received or to the TDControlStatus if no data is expected.
+ // The CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTDCallback routine.
+ // The ActiveFlag field will be set to TRUE.
+ // The DeviceAddress field does not need to be set since the Control TDs do
+ // not need rebinding to the EDControl.
+ //
+ fpTD->dControlStatus = (UINT32)(GTD_BUFFER_ROUNDING | GTD_SETUP_PACKET | GTD_SETUP_TOGGLE |
+ GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+
+ fpTD->fpCurrentBufferPointer = (UINT32)(UINTN)fpTD->aSetupData;
+ fpTD->fpBufferEnd = (UINT32)(UINTN)fpTD->aSetupData + 7; // size of aSetupData - 1
+
+ wData = wLength ; //(EIP67230)
+
+ if (wLength) { // some data to transfer
+ fpTD = fpDescPtrs->fpTDControlData; // Fill in various fields in the TDControlData.
+ //
+ // The ControlStatus field will be set so
+ // Buffer Rounding = 1,
+ // Direction PID = GTD_OUT_PACKET/GTD_IN_PACKET,
+ // Delay Interrupt = GTD_IntD,
+ // Data Toggle = GTD_DATA1_TOGGLE,
+ // Error Count = GTD_NO_ERRORS,
+ // Condition Code = GTD_NOT_ACCESSED
+ // The CurrentBufferPointer field will point to the caller's buffer
+ // which is now in EBP.
+ // The BufferEnd field will point to the last byte of the caller's buffer.
+ // The LinkPointer field will point to the TDControlStatus.
+ // The CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTDCallback routine.
+ // The ActiveFlag field will be set to TRUE.
+ // The DeviceAddress field does not need to be set since the Control TDs do
+ // not need rebinding to the EDControl.
+ // The CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTDCallback routine.
+ // The ActiveFlag field will be set to TRUE. return USB_SUCCESS;
+ // The DeviceAddress field does not need to be set since the Control TDs do}
+ // not need rebinding to the EDControl.
+ //
+ dData = (UINT32)(GTD_BUFFER_ROUNDING | GTD_DATA1_TOGGLE | GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ dData = (wRequest & BIT7)? (dData | GTD_IN_PACKET | GTD_IntD) : (dData | GTD_OUT_PACKET);
+ fpTD->dControlStatus = dData;
+ fpTD->fpCurrentBufferPointer = (UINT32)(UINTN)fpBuffer;
+ fpTD->fpBufferEnd = (UINT32)((UINTN)fpBuffer + wData - 1);
+ }
+ fpTD = fpDescPtrs->fpTDControlStatus; // Fill in various fields in the TDControlStatus.
+ //
+ // The ControlStaus field will be set so
+ // Buffer Rounding = 1,
+ // Direction PID = GTD_OUT_PACKET/GTD_IN_PACKET,
+ // Delay Interrupt = GTD_IntD,
+ // Data Toggle = GTD_DATA1_TOGGLE,
+ // Error Count = GTD_NO_ERRORS,
+ // Condition Code = GTD_NOT_ACCESSED
+ // The CurrentBufferPointer field will point to NULL
+ // The BufferEnd field will point to NULL.
+ // The LinkPointer field will point to OHCI_TERMINATE.
+ // The CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // The pCallback will be set to point to the OHCI_ControlTdCallback routine.
+ // The ActiveFlag field will be set to TRUE.
+ // The DeviceAddress field does not need to be set since the Control TDs do
+ // not need rebinding to the EdControl.
+ //
+ // Note: For OUT control transfer status should be IN and
+ // for IN cotrol transfer, status should be OUT.
+ //
+ dData = (UINT32)(GTD_BUFFER_ROUNDING | GTD_DATA1_TOGGLE | GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ dData = (wRequest & BIT7)? (dData | GTD_OUT_PACKET) : (dData | GTD_IN_PACKET | GTD_IntD);
+ fpTD->dControlStatus = dData;
+ fpTD->fpCurrentBufferPointer = 0;
+ fpTD->fpBufferEnd = 0;
+ fpTD->fpLinkPointer = 0;
+ //
+ // Link all the pointers together
+ //
+ fpTD = fpDescPtrs->fpTDControlSetup;
+ fpED->fpHeadPointer = (UINT32)(UINTN)fpTD;
+ if (wLength) { // chain in data TD
+ fpTD->fpLinkPointer = (UINT32)(UINTN)fpDescPtrs->fpTDControlData;
+ fpTD = fpDescPtrs->fpTDControlData;
+ }
+ fpTD->fpLinkPointer = (UINT32)(UINTN)fpDescPtrs->fpTDControlStatus;
+
+ fpDescPtrs->fpTDControlStatus->fpLinkPointer = 0;
+
+ fpTD = fpDescPtrs->fpTDControlSetup;
+ do {
+ fpTD->dCSReloadValue = 0;
+ fpTD->bCallBackIndex = USB_InstallCallBackFunction(OHCI_ControlTDCallback);
+ fpTD->bActiveFlag = TRUE;
+ fpTD = (OHCI_TD*)fpTD->fpLinkPointer;
+ } while (fpTD);
+ //
+ // Now control queue is complete, so set ED_SKIP_TDQ=0
+ //
+ fpED->dControl &= ~ED_SKIP_TDQ;
+ //
+ // Set the HcControlHeadED register to point to the EDControl.
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_CONTROL_HEAD_ED, (UINT32)(UINTN)fpED);
+ //
+ // Now put the control setup, data and status into the HC's schedule by
+ // setting the ControllListFilled field of HcCommandStatus reg.
+ // This will cause the HC to execute the transaction in the next active frame.
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_COMMAND_STATUS, CONTROL_LIST_FILLED);
+ //
+ // Now wait for the control status TD to complete. When it has completed,
+ // the OHCI_ControlTDCallback will set its active flag to FALSE.
+ //
+ OHCIWaitForTransferComplete(fpHCStruc, fpED, fpDescPtrs->fpTDControlStatus,fpDevInfo);
+ //
+ // Stop the HC from processing the EDControl by setting its Skip bit.
+ //
+ fpED->dControl |= ED_SKIP_TDQ;
+
+ //
+ // Finally check for any error bits set in both the TDControlStatus.
+ // If the TD did not complete successfully, return STC.
+ //
+ CompletionCode = (UINT8)(fpDescPtrs->fpTDControlStatus->dControlStatus >> 28); // dData[3:0] = Completion status
+ gUsbData->bLastCommandStatus &= ~USB_CONTROL_STALLED;
+
+ fpTD = fpDescPtrs->fpTDControlData;
+ TransferLength = wLength ;
+ if(fpTD->fpCurrentBufferPointer != 0){
+ TransferLength = fpTD->fpCurrentBufferPointer - (UINT32)(UINTN)fpBuffer;
+ }
+
+
+ wData = 0;
+ switch (CompletionCode) {
+ case GTD_NO_ERROR:
+ wData = TransferLength;
+ break;
+ case GTD_STALL:
+ gUsbData->bLastCommandStatus |= USB_CONTROL_STALLED;
+ gUsbData->dLastCommandStatusExtended |= USB_TRSFR_STALLED;
+ break;
+ case GTD_NOT_ACCESSED:
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ break;
+ default:
+ break;
+ }
+
+ return wData;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_BulkTransfer
+//
+// DESCRIPTION: This function executes a bulk transaction on the USB. The
+// transfer may be either DATA_IN or DATA_OUT packets containing
+// data sent from the host to the device or vice-versa. This
+// function wil not return until the request either completes
+// successfully or completes with error (due to time out, etc.)
+// Size of data can be upto 64K
+//
+// PARAMETERS: pHCStruc Pointer to HCStruc of the host controller
+// pDevInfo DeviceInfo structure (if available else 0)
+// bXferDir Transfer direction
+// Bit 7: Data direction
+// 0 Host sending data to device
+// 1 Device sending data to host
+// Bit 6-0 : Reserved
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// value in Segment:Offset format
+// dwLength dwLength request parameter, number of bytes
+// of data to be transferred in or out
+// of the host controller
+//
+// RETURN: Amount of data transferred
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+OHCI_BulkTransfer (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 bXferDir,
+ UINT8 *fpBuffer,
+ UINT32 dwLength)
+{
+ UINT32 dData;
+ UINT8 bData;
+ OHCI_DESC_PTRS *fpDescPtrs;
+ UINT16 wMaxPkt;
+ UINT8 bEndp;
+ UINT8 bDatToggle;
+ UINT32 dBytesToTransfer, dBytesRemaining;
+ UINT32 dBytesTransferred;
+ UINT32 Buffer;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, dwLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Ohci BulkTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (OhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ if( !VALID_DEVINFO( fpDevInfo) )
+ return 0;
+
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ fpDescPtrs = fpHCStruc->stDescPtrs.fpOHCIDescPtrs;
+
+ if (((UINT8*)fpDescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs + sizeof(OHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return 0;
+ }
+
+ if (((UINT8*)fpDescPtrs->fpEDBulk < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs->fpEDBulk + sizeof(OHCI_ED)) > MemBlockEnd)) {
+ return 0;
+ }
+
+ if (((UINT8*)fpDescPtrs->fpTDBulkData < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(fpDescPtrs->fpTDBulkData + sizeof(OHCI_TD)) > MemBlockEnd)) {
+ return 0;
+ }
+
+ wMaxPkt = (bXferDir & 0x80)? fpDevInfo->wBulkInMaxPkt : fpDevInfo->wBulkOutMaxPkt;
+ bEndp = (bXferDir & 0x80)? fpDevInfo->bBulkInEndpoint : fpDevInfo->bBulkOutEndpoint;
+ bDatToggle = UsbGetDataToggle(fpDevInfo, bEndp | bXferDir);
+
+ if( wMaxPkt == 0){
+ return 0;
+ }
+
+ dBytesRemaining = dwLength;
+ dBytesTransferred = 0;
+ dBytesToTransfer = 0;
+
+ for (;dBytesRemaining != 0; dBytesRemaining -= dBytesToTransfer) {
+ dBytesToTransfer =
+ (dBytesRemaining < FULLSPEED_MAX_BULK_DATA_SIZE_PER_FRAME)?
+ dBytesRemaining : FULLSPEED_MAX_BULK_DATA_SIZE_PER_FRAME;
+
+ Buffer = (UINT32)(UINTN)fpBuffer + dBytesTransferred;
+
+ //
+ // Set the SKIP bit in the EdBulk to avoid accidental scheduling
+ //
+ fpDescPtrs->fpEDBulk->dControl = ED_SKIP_TDQ;
+ //
+ // Set the ED's head pointer field to bulk data TD and tail pointer field to
+ // OHCI_TERMINATE. Also set ED's link pointer to OHCI_TERMINATE.
+ //
+ fpDescPtrs->fpEDBulk->fpHeadPointer = (UINT32)(UINTN)fpDescPtrs->fpTDBulkData;
+ fpDescPtrs->fpEDBulk->fpTailPointer = OHCI_TERMINATE;
+ fpDescPtrs->fpEDBulk->fpEDLinkPointer = OHCI_TERMINATE;
+ //
+ // Form the data needed for ED's control field with the available information
+ //
+ dData = (bXferDir & 0x80)? ED_IN_PACKET : ED_OUT_PACKET;
+ dData |= fpDevInfo->bDeviceAddress;
+ dData |= (UINT16)bEndp << 7;
+ dData |= (UINT32)wMaxPkt << 16;
+ //
+ // Update the ED's control field with the data formed
+ // ASSUME ALL MASS DEVICES ARE FULL SPEED DEVICES.
+ //
+ fpDescPtrs->fpEDBulk->dControl = dData;
+ //
+ // Fill the general bulk data TD with relevant information. Set the
+ // TD's control field with buffer rounding set to 1, direction PID to
+ // don't care, delay interrupt to INTD, data toggle to the latest data
+ // toggle value, error count to no errors and condition code to not accessed.
+ //
+ // Set the data toggle to DATA0 (SETUP_TOGGLE)
+ fpDescPtrs->fpTDBulkData->dControlStatus = (UINT32)(GTD_BUFFER_ROUNDING | GTD_IN_PACKET |
+ GTD_IntD | GTD_SETUP_TOGGLE | GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ fpDescPtrs->fpTDBulkData->dControlStatus |= (UINT32)bDatToggle << 24;
+ //
+ // GTD current buffer pointer field will point to the caller's buffer which
+ // now in the variable fpBuffer
+ //
+ fpDescPtrs->fpTDBulkData->fpCurrentBufferPointer = Buffer;
+ fpDescPtrs->fpTDBulkData->fpBufferEnd = Buffer + dBytesToTransfer - 1;
+ fpDescPtrs->fpTDBulkData->fpLinkPointer = OHCI_TERMINATE;
+ //
+ // GTD's CSReloadValue field will contain 0 because this is a "one shot" packet
+ //
+ fpDescPtrs->fpTDBulkData->dCSReloadValue = 0;
+ fpDescPtrs->fpTDBulkData->bCallBackIndex = USB_InstallCallBackFunction(OHCI_GeneralTDCallback);
+ fpDescPtrs->fpTDBulkData->bActiveFlag = TRUE;
+
+ fpDescPtrs->fpEDBulk->dControl &= ~ED_SKIP_TDQ;
+ //
+ // Set the HCBulkHeadED register to point to the bulk ED
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_BULK_HEAD_ED, (UINT32)(UINTN)fpDescPtrs->fpEDBulk);
+ //
+ // Clear bulk stall/time out condition flag
+ //
+ gUsbData->bLastCommandStatus &= ~(USB_BULK_STALLED + USB_BULK_TIMEDOUT);
+ //
+ // Enable the bulk list processing
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_COMMAND_STATUS, BULK_LIST_FILLED);
+
+ OHCIWaitForTransferComplete(fpHCStruc, fpDescPtrs->fpEDBulk, fpDescPtrs->fpTDBulkData,fpDevInfo);
+ //
+ // Stop the HC from processing the EDBulk by setting its Skip bit.
+ //
+ fpDescPtrs->fpEDBulk->dControl |= ED_SKIP_TDQ;
+ //
+ // Update the data toggle value into the mass info structure
+ //
+ UsbUpdateDataToggle(fpDevInfo, bEndp | bXferDir,
+ (UINT8)(((fpDescPtrs->fpTDBulkData->dControlStatus & GTD_DATA_TOGGLE) >> 24) & 1));
+ //
+ // Check for the error conditions - if possible recover from them
+ //
+ bData = (UINT8)(fpDescPtrs->fpTDBulkData->dControlStatus >> 28);
+ switch (bData) {
+ case GTD_STALL:
+ gUsbData->bLastCommandStatus |= USB_BULK_STALLED;
+ gUsbData->dLastCommandStatusExtended |= USB_TRSFR_STALLED;
+ break;
+ case GTD_NOT_ACCESSED:
+ gUsbData->bLastCommandStatus |= USB_BULK_TIMEDOUT;
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ break;
+ default:
+ break;
+ }
+
+ if (bData != GTD_NO_ERROR) {
+ break;
+ }
+
+ //
+ // Get the size of data transferred
+ //
+ dData = fpDescPtrs->fpTDBulkData->fpCurrentBufferPointer;
+ if (dData != 0)
+ {
+ //
+ // Device sent less data than requested, calculate the
+ // transferred size and exit
+ //
+ //dBytesTransferred += (UINT32)(UINTN)fpDescPtrs->fpTDBulkData->fpBufferEnd - dData; //(EIP55025-)
+ dBytesTransferred += dData - Buffer; //Short Packet (OHCI Spec 4.3.1.3.5 Transfer Completion, Pg.23) //<(EIP55025)+
+ break;
+ }
+
+ //
+ // CurrentBufferPointer equals 0. This indicates the successfull TD completion,
+ // all data is transferred. Adjust the total amount and continue.
+ //
+ dBytesTransferred += dBytesToTransfer;
+ }
+
+ return dBytesTransferred;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_InterruptTransfer
+//
+// DESCRIPTION: This function executes an interrupt transaction on the USB.
+// The data transfer direction is always DATA_IN. This
+// function wil not return until the request either completes
+// successfully or completes in error (due to time out, etc.)
+//
+// PARAMETERS: fpHCStruc Pointer to HCStruc of the host controller
+// fpDevInfo DeviceInfo structure (if available else 0)
+// EndpointAddress The destination USB device endpoint to which the device request
+// is being sent.
+// MaxPktSize Indicates the maximum packet size the target endpoint is capable
+// of sending or receiving.
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// wLength wLength request parameter, number of bytes
+// of data to be transferred in
+//
+// RETURN: Number of bytes transferred
+//
+//
+// NOTES: DO NOT TOUCH THE LINK POINTER OF THE TDInterruptData. It is
+// statically allocated and linked with other items in the
+// 1ms schedule
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+OHCI_InterruptTransfer (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 EndpointAddress,
+ UINT16 MaxPktSize,
+ UINT8 *fpBuffer,
+ UINT16 wLength)
+{
+ UINT8 bEndp, bDatToggle;
+ UINT32 dData;
+ OHCI_ED *IntEd;
+ OHCI_TD *IntTd;
+ UINT8 CompletionCode;
+ UINT32 BytesTransferred;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Ohci InterruptTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (OhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ if(!VALID_DEVINFO( fpDevInfo)) {
+ return 0;
+ }
+
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ IntEd = USB_MemAlloc(GET_MEM_BLK_COUNT(sizeof(OHCI_ED) + sizeof(OHCI_TD)));
+
+ if (IntEd == NULL) {
+ return 0;
+ }
+
+ IntTd = (OHCI_TD*)((UINTN)IntEd + sizeof(OHCI_ED));
+
+ //
+ // Set the SKIP bit to avoid accidental scheduling
+ //
+ IntEd->dControl = ED_SKIP_TDQ;
+ //
+ // Set the ED's head pointer field to interrupt data TD and tail pointer
+ // field to OHCI_TERMINATE. Also set ED's link pointer to OHCI_TERMINATE.
+ //
+ IntEd->fpHeadPointer = (UINT32)(UINTN)IntTd;
+ IntEd->fpTailPointer = OHCI_TERMINATE;
+ IntEd->fpEDLinkPointer = OHCI_TERMINATE;
+ IntEd->Interval = OhciTranslateInterval(fpDevInfo->bPollInterval);
+
+ //
+ // Get maximum packet size from device info structure
+ //
+ bEndp = EndpointAddress & 0xF;
+ bDatToggle = UsbGetDataToggle(fpDevInfo, EndpointAddress);
+
+ //
+ // Form the data needed for ED's control field with the available information
+ //
+ dData = (EndpointAddress & BIT7)? ED_IN_PACKET : ED_OUT_PACKET;
+ dData |= fpDevInfo->bDeviceAddress | ((UINT16)bEndp << 7);
+ dData |= ((UINT32)MaxPktSize << 16);
+ dData |= (UINT32)(fpDevInfo->bEndpointSpeed & 1) << 13;
+ //
+ // Update the ED's control field with the data formed
+ // ASSUME ALL MASS DEVICES ARE FULL SPEED DEVICES.
+ //
+ IntEd->dControl = dData;
+ //
+ // Fill the general interrupt data TD with relevant information. Set the
+ // TD's control field with buffer rounding set to 1, direction PID to
+ // don't care, delay interrupt to INTD, data toggle to the latest data
+ // toggle value, error count to no errors and condition code to not accessed.
+ //
+ // Set the data toggle to DATA0 (SETUP_TOGGLE)
+ //
+ dData = (UINT32)(GTD_BUFFER_ROUNDING | GTD_IN_PACKET | GTD_IntD | GTD_SETUP_TOGGLE |
+ GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ IntTd->dControlStatus = dData;
+ //
+ // Set the data toggle depending on the bDatToggle value
+ //
+ IntTd->dControlStatus |= ((UINT32)bDatToggle << 24);
+ //
+ // GTD current buffer pointer field will point to the caller's buffer
+ //
+ IntTd->fpCurrentBufferPointer = (UINT32)(UINTN)fpBuffer;
+ //
+ // GTD's buffer end field will point to the last byte of the caller's buffer
+ //
+ IntTd->fpBufferEnd = (UINT32)(UINTN)(fpBuffer + wLength - 1);
+ //
+ // GTD's link pointer field will be set to OHCI_TERMINATE
+ //
+ IntTd->fpLinkPointer = OHCI_TERMINATE;
+ //
+ // GTD's CSReloadValue field will contain 0 because this is a "one shot" packet
+ //
+ IntTd->dCSReloadValue = 0;
+ //
+ // GTD's pCallback will point to the OHCI_GeneralTDCallback routine
+ //
+ IntTd->bCallBackIndex = USB_InstallCallBackFunction(OHCI_GeneralTDCallback);
+ //
+ // GTD's ActiveFlag field will be set to TRUE.
+ //
+ OhciAddPeriodicEd(fpHCStruc, IntEd);
+
+ IntTd->bActiveFlag = TRUE;
+ IntEd->dControl &= ~ED_SKIP_TDQ;
+
+ //
+ // Now wait for the interrupt data TD to complete.
+ //
+ OHCIWaitForTransferComplete(fpHCStruc, IntEd, IntTd, fpDevInfo);
+ //
+ // Stop the HC from processing the EDInterrupt by setting its Skip bit.
+ //
+ OhciRemovePeriodicEd(fpHCStruc, IntEd);
+ //
+ // Get appropriate data sync shift value
+ //
+ bDatToggle = (UINT8)((IntTd->dControlStatus & GTD_DATA_TOGGLE) >> 24) & 1;
+ UsbUpdateDataToggle(fpDevInfo, EndpointAddress, bDatToggle);
+
+ //
+ // Check for the error conditions - if possible recover from them
+ //
+ CompletionCode = (UINT8)(IntTd->dControlStatus >> 28);
+ switch (CompletionCode) {
+ case GTD_STALL:
+ gUsbData->dLastCommandStatusExtended |= USB_TRSFR_STALLED;
+ break;
+ case GTD_NOT_ACCESSED:
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ break;
+ default:
+ break;
+ }
+
+ BytesTransferred = IntTd->fpCurrentBufferPointer == 0 ? wLength :
+ IntTd->fpCurrentBufferPointer - (UINT32)fpBuffer;
+
+ USB_MemFree(IntEd, GET_MEM_BLK_COUNT(sizeof(OHCI_ED) + sizeof(OHCI_TD)));
+
+ return (UINT16)BytesTransferred;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_ActivatePolling
+//
+// DESCRIPTION: This function activates the polling TD for the requested
+// device. The device may be a USB keyboard or USB hub
+//
+// PARAMETERS: fpHCStruc Pointer to the HC structure
+// fpDevInfo Pointer to the device information structure
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+// NOTES: For the keyboard device this routine allocates TDRepeat
+// also, if it is not already allocated. This routine allocate
+// a polling TD and schedule it to 8ms schedule for keyboards
+// and to 1024ms schedule for hubs.
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_ActivatePolling (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo)
+{
+ UINT32 dData;
+ UINT8 *fpPtr;
+ UINT8 bDatToggle;
+
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (OhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ if (!VALID_DEVINFO(fpDevInfo)) {
+ return USB_ERROR;
+ }
+
+ bDatToggle = UsbGetDataToggle(fpDevInfo, fpDevInfo->IntInEndpoint);
+
+ fpPtr = USB_MemAlloc(1);
+ ASSERT(fpPtr);
+ fpDevInfo->fpPollEDPtr = fpPtr;
+ fpPtr = USB_MemAlloc(1);
+ ASSERT(fpPtr);
+ fpDevInfo->fpPollTDPtr = fpPtr;
+
+ dData = (fpDevInfo->IntInEndpoint & BIT7)? ED_IN_PACKET : ED_OUT_PACKET;
+ dData |= (UINT32)fpDevInfo->bDeviceAddress | ((fpDevInfo->IntInEndpoint & 0xF) << 7);
+ dData |= ((UINT32)fpDevInfo->IntInMaxPkt << 16);
+ dData |= (UINT32)(fpDevInfo->bEndpointSpeed & 1) << 13;
+ dData |= ED_SKIP_TDQ;
+
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->dControl = dData;
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->fpHeadPointer = (UINT32)(UINTN)fpDevInfo->fpPollTDPtr;
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->fpHeadPointer |= bDatToggle << 1;
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->fpEDLinkPointer = OHCI_TERMINATE;
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->fpTailPointer = OHCI_TERMINATE;
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->Interval = OhciTranslateInterval(fpDevInfo->bPollInterval);
+
+ fpDevInfo->fpPollDataBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT(fpDevInfo->PollingLength));
+ ASSERT(fpDevInfo->fpPollDataBuffer);
+
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->dControlStatus = (UINT32)(GTD_BUFFER_ROUNDING | GTD_IN_PACKET | GTD_IntD |
+ GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->dCSReloadValue = (UINT32)(GTD_BUFFER_ROUNDING | GTD_IN_PACKET | GTD_IntD |
+ GTD_NO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->fpCurrentBufferPointer =
+ (UINT32)(fpDevInfo->fpPollDataBuffer); //(EIP54782)
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->fpBufferEnd =
+ (UINT32)(fpDevInfo->fpPollDataBuffer + fpDevInfo->PollingLength - 1);
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->fpLinkPointer = OHCI_TERMINATE;
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->bCallBackIndex = USB_InstallCallBackFunction(OHCI_PollingTDCallback);
+
+ OhciAddPeriodicEd(fpHCStruc, (OHCI_ED*)fpDevInfo->fpPollEDPtr);
+
+ ((OHCI_TD*)fpDevInfo->fpPollTDPtr)->bActiveFlag = TRUE;
+ ((OHCI_ED*)fpDevInfo->fpPollEDPtr)->dControl &= ~ED_SKIP_TDQ;
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_DeactivatePolling
+//
+// DESCRIPTION: This function de-activates the polling TD for the requested
+// device. The device may be a USB keyboard or USB hub
+//
+// PARAMETERS: fpHCStruc Pointer to the HC structure
+// fpDevInfo Pointer to the device information structure
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_DeactivatePolling (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo)
+{
+ OHCI_ED *fpOHCIED = (OHCI_ED*)fpDevInfo->fpPollEDPtr;
+ OHCI_TD *fpOHCITD = (OHCI_TD*)fpDevInfo->fpPollTDPtr;
+
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (OhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ if(!fpOHCIED) {
+ return USB_SUCCESS;
+ }
+
+ fpOHCITD->dControlStatus = 0;
+ fpOHCITD->dCSReloadValue = 0;
+ fpOHCITD->bActiveFlag = FALSE;
+
+ OhciRemovePeriodicEd(fpHCStruc, fpOHCIED);
+
+ UsbUpdateDataToggle(fpDevInfo, fpDevInfo->IntInEndpoint,
+ (UINT8)((fpOHCIED->fpHeadPointer & ED_TOGGLE_CARRY) >> 1));
+
+ USB_MemFree(fpOHCITD, GET_MEM_BLK_COUNT_STRUC(OHCI_TD));
+ fpDevInfo->fpPollTDPtr = NULL;
+
+ USB_MemFree(fpOHCIED, GET_MEM_BLK_COUNT_STRUC(OHCI_ED));
+ fpDevInfo->fpPollEDPtr = NULL;
+
+ if(fpDevInfo->fpPollDataBuffer) {
+ USB_MemFree(fpDevInfo->fpPollDataBuffer,
+ GET_MEM_BLK_COUNT(fpDevInfo->PollingLength));
+ fpDevInfo->fpPollDataBuffer = 0;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_PollingTDCallback
+//
+// DESCRIPTION: This function is called when a polling TD from the TD pool
+// completes an interrupt transaction to its assigned device.
+// This routine should process any data in the TD's data buffer,
+// handle any errors, and then copy the TD's CSReloadValue
+// field into its control status field to put the TD back
+// into service.
+//
+//
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_PollingTDCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Td,
+ UINT8* Buffer,
+ UINT16 DataLength
+)
+{
+ UINT8 i;
+ UINT16 BytesTransferred;
+
+ if (((OHCI_TD*)Td)->bActiveFlag == FALSE) {
+ return USB_SUCCESS;
+ }
+
+ ((OHCI_TD*)Td)->bActiveFlag = FALSE;
+ DwordResetMem((UINT32)HcStruc->BaseAddress, OHCI_CONTROL_REG, PERIODIC_LIST_ENABLE);
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+ DevInfo = &gUsbData->aDevInfoTable[i];
+ if (DevInfo->Flag & DEV_INFO_DEV_PRESENT) {
+ if (DevInfo->fpPollTDPtr == Td) {
+ break;
+ }
+ }
+ }
+
+ if (i == MAX_DEVICES) {
+ return USB_ERROR;
+ }
+
+ UsbUpdateDataToggle(DevInfo, DevInfo->IntInEndpoint,
+ (UINT8)((((OHCI_ED*)DevInfo->fpPollEDPtr)->fpHeadPointer & ED_TOGGLE_CARRY) >> 1));
+
+ //(EIP59707)>
+ if ((((OHCI_TD*)Td)->dControlStatus & GTD_STATUS_FIELD) == GTD_NO_ERROR) {
+ //
+ // Get the size of data transferred
+ //
+ if (((OHCI_TD*)Td)->fpCurrentBufferPointer != 0) {
+ BytesTransferred = ((OHCI_TD*)Td)->fpCurrentBufferPointer -
+ (UINT32)(UINTN)(DevInfo->fpPollDataBuffer);
+ } else {
+ BytesTransferred = DevInfo->PollingLength;
+ }
+ if ((DevInfo->bCallBackIndex) && (DevInfo->bCallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ (*gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex-1])(
+ HcStruc,
+ DevInfo,
+ (UINT8*)Td,
+ DevInfo->fpPollDataBuffer,
+ BytesTransferred);
+ }
+ }
+ //<(EIP59707)
+ DwordSetMem((UINT32)HcStruc->BaseAddress, OHCI_CONTROL_REG, PERIODIC_LIST_ENABLE);
+
+ // Clear the link pointer. It may point to some other TD
+ ((OHCI_TD*)Td)->fpLinkPointer = OHCI_TERMINATE;
+ ((OHCI_TD*)Td)->dControlStatus = ((OHCI_TD*)Td)->dCSReloadValue;
+ ((OHCI_TD*)Td)->fpCurrentBufferPointer = (UINT32)(UINTN)(DevInfo->fpPollDataBuffer); //(EIP54782)
+ ((OHCI_ED*)DevInfo->fpPollEDPtr)->fpHeadPointer &= ED_TOGGLE_CARRY;
+ ((OHCI_ED*)DevInfo->fpPollEDPtr)->fpHeadPointer |= (UINTN)((OHCI_TD*)Td);
+ ((OHCI_TD*)Td)->bActiveFlag = TRUE;
+ // Reset the TD's control and buffer pointer fields to their original values.
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_DisableKeyRepeat
+//
+// DESCRIPTION: This function disables the keyboard repeat rate logic by
+// enabling the repeat TD
+//
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_DisableKeyRepeat (
+ HC_STRUC *HcStruc
+)
+{
+ OHCI_DESC_PTRS *DescPtrs;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (OhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ DescPtrs = HcStruc->stDescPtrs.fpOHCIDescPtrs;
+
+ if (DescPtrs == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs + sizeof(OHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (DescPtrs->fpEDRepeat == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->fpEDRepeat < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->fpEDRepeat + sizeof(OHCI_ED)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ DescPtrs->fpEDRepeat->dControl |= ED_SKIP_TDQ; // Inactive
+ DescPtrs->fpTDRepeat->bActiveFlag = FALSE;
+
+ return USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_EnableKeyRepeat
+//
+// DESCRIPTION: This function enables the keyboard repeat rate logic by
+// enabling the repeat TD
+//
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_EnableKeyRepeat (
+ HC_STRUC *HcStruc
+)
+{
+ OHCI_DESC_PTRS *DescPtrs;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (OhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ DescPtrs = HcStruc->stDescPtrs.fpOHCIDescPtrs;
+
+ if (DescPtrs == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs + sizeof(OHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (DescPtrs->fpEDRepeat == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->fpEDRepeat < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->fpEDRepeat + sizeof(OHCI_ED)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ DescPtrs->fpTDRepeat->fpLinkPointer = OHCI_TERMINATE;
+ DescPtrs->fpEDRepeat->fpHeadPointer = (UINT32)(UINTN)DescPtrs->fpTDRepeat;
+ DescPtrs->fpTDRepeat->dControlStatus =
+ DescPtrs->fpTDRepeat->dCSReloadValue;
+ DescPtrs->fpTDRepeat->bActiveFlag = TRUE;
+ DescPtrs->fpEDRepeat->dControl &= (~ED_SKIP_TDQ); // Active
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_EnumeratePorts
+//
+// DESCRIPTION: This API function is called to enumerate the root hub ports
+// in the OHCI controller. The input to the routine is the
+// pointer to the HC structure that defines this host controller
+//
+// PARAMETERS: fpHCStruc Ptr to the host controller structure
+//
+// RETURN: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_EnumeratePorts(HC_STRUC* fpHCStruc)
+{
+ UINT32 BaseAddr = (UINT32)fpHCStruc->BaseAddress;
+ UINT32 RhDescriptorA = 0;
+ UINT8 PowerOnDelay = 0;
+ UINT8 Index = 0;
+ UINT16 PortReg = OHCI_RH_PORT1_STATUS;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (OhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ RhDescriptorA = DwordReadMem(BaseAddr, OHCI_RH_DESCRIPTOR_A);
+ if (!(RhDescriptorA & NO_POWER_SWITCH)) {
+ if (!(RhDescriptorA & POWER_SWITCH_MODE)) {
+ // All ports are powered at the same time, enable global port power
+ DwordWriteMem(BaseAddr, OHCI_RH_STATUS, SET_GLOBAL_POWER);
+ } else {
+ // Each port is powered individually, enable individual port's power
+ for (Index = 0; Index < fpHCStruc->bNumPorts; PortReg+=4, Index++) {
+ // Set PortPowerControlMask bit
+ DwordSetMem(BaseAddr, OHCI_RH_DESCRIPTOR_B, ((1 << (Index + 1)) << 16));
+ // Set PortPower bit
+ DwordWriteMem(BaseAddr, PortReg, SET_PORT_POWER);
+ }
+ }
+ PowerOnDelay = ((RhDescriptorA & POWERON2POWERGOOD_TIME) >> 24) << 1;
+ FixedDelay(PowerOnDelay * 1000);
+ }
+
+ OHCI_ProcessRootHubStatusChange(fpHCStruc);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OhciAddPeriodicEd
+//
+// DESCRIPTION: This function adds a ED to the frame list
+//
+// PARAMETERS: HcStruc - Ptr to the host controller structure
+// Ed - ED will be added in periodic schedule
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OhciAddPeriodicEd (
+ HC_STRUC *HcStruc,
+ OHCI_ED *Ed
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ OHCI_ED *Current;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (Ed == NULL || Ed->Interval == 0) {
+ return USB_ERROR;
+ }
+
+ for (Index = 0; Index < HcStruc->wAsyncListSize; Index += Ed->Interval) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ Current = (OHCI_ED*)(*PrevPtr);
+
+ while (Current != NULL) {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Current, sizeof(OHCI_ED));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ if (Current->Interval <= Ed->Interval) {
+ break;
+ }
+
+ PrevPtr = &Current->fpEDLinkPointer;
+ Current = (OHCI_ED*)Current->fpEDLinkPointer;
+ }
+
+ if (Current == Ed) {
+ continue;
+ }
+ Ed->fpEDLinkPointer = (UINT32)(UINTN)Current;
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PrevPtr, sizeof(UINT32));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ *PrevPtr = (UINT32)(UINTN)Ed;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OhciRemovePeriodicEd
+//
+// DESCRIPTION: This function removes a ED from the frame list
+//
+// PARAMETERS: HcStruc - Ptr to the host controller structure
+// Ed - ED will be removed from periodic schedule
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OhciRemovePeriodicEd (
+ HC_STRUC *HcStruc,
+ OHCI_ED *Ed
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ OHCI_ED *Current;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (Ed == NULL || Ed->Interval == 0) {
+ return USB_ERROR;
+ }
+
+ Ed->dControl |= ED_SKIP_TDQ;
+
+ for (Index = 0; Index < HcStruc->wAsyncListSize; Index += Ed->Interval) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ Current = (OHCI_ED*)(*PrevPtr);
+
+ while (Current != NULL) {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Current, sizeof(OHCI_ED));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ if (Current == Ed) {
+ break;
+ }
+
+ PrevPtr = &Current->fpEDLinkPointer;
+ Current = (OHCI_ED*)Current->fpEDLinkPointer;
+ }
+
+ if (Current == NULL) {
+ continue;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PrevPtr, sizeof(UINT32));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ *PrevPtr = Ed->fpEDLinkPointer;
+ }
+
+ DwordWriteMem((UINT32)HcStruc->BaseAddress, OHCI_INTERRUPT_STATUS, START_OF_FRAME);
+ DwordWriteMem((UINT32)HcStruc->BaseAddress, OHCI_INTERRUPT_ENABLE, START_OF_FRAME_ENABLE);
+
+ for (Index = 0; Index < 100; Index++) {
+ if (DwordReadMem((UINT32)HcStruc->BaseAddress,
+ OHCI_INTERRUPT_STATUS) & START_OF_FRAME) {
+ break;
+ }
+ FixedDelay(10); // 10 us delay
+ }
+ ASSERT(Index < 100);
+ ASSERT(DwordReadMem((UINT32)HcStruc->BaseAddress, OHCI_INTERRUPT_STATUS) & START_OF_FRAME);
+ DwordWriteMem((UINT32)HcStruc->BaseAddress, OHCI_INTERRUPT_DISABLE, START_OF_FRAME_DISABLE);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI_StartEDSchedule
+//
+// DESCRIPTION: This function starts the standard TD schedules for the
+// USB host controller
+//
+// PARAMETERS: HCStruc for the controller
+//
+// RETURN: USB_ERROR on error, USB_SUCCESS on success
+//
+// NOTES: This routine creates 1, 2, 8, 32 and 1024ms schedules
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_StartEDSchedule(
+ HC_STRUC *HcStruc
+)
+{
+ OHCI_DESC_PTRS *DescPtrs;
+ UINT8 *Ptr;
+
+ //
+ // Allocate descriptor structure and fill it in HCStruc
+ //
+ DescPtrs = (OHCI_DESC_PTRS*)USB_MemAlloc (GET_MEM_BLK_COUNT_STRUC(OHCI_DESC_PTRS));
+ ASSERT(DescPtrs);
+ if (!DescPtrs) return USB_ERROR;
+
+ //
+ // Save the value in the HC struc
+ //
+ HcStruc->stDescPtrs.fpOHCIDescPtrs = DescPtrs;
+
+ //
+ // Allocate 4 EDs + 1 TDs and put them in Descriptor list
+ //
+ Ptr = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(OHCI_ED));
+ ASSERT(Ptr);
+ if (!Ptr) return USB_ERROR;
+
+ DescPtrs->PeriodicEd = (OHCI_ED*)Ptr;
+ DescPtrs->PeriodicEd->dControl = ED_SKIP_TDQ;
+ DescPtrs->PeriodicEd->fpEDLinkPointer = 0;
+ DescPtrs->PeriodicEd->Interval = 1;
+
+ // Initialize each entry of Interrupt Table as statically disable ED
+ OhciAddPeriodicEd(HcStruc, DescPtrs->PeriodicEd);
+
+ //
+ // Allocate ED/TD for EDControl, TDControlSetup, TDControlData,
+ // TDControlStatus, EDBulk, TDBulkData, EDInterrupt and TDInterruptData
+ //
+ Ptr = USB_MemAlloc(GET_MEM_BLK_COUNT(2 * sizeof(OHCI_ED) + 4 * sizeof(OHCI_TD)));
+ ASSERT(Ptr);
+ if (!Ptr) return USB_ERROR;
+
+ //
+ // Save the 8 ED/TD in their proper position. Note: fpHCStruc->stDescPtrs.fpEHCIDescPtrs
+ // is initialized earlier in OHCI_StartEDSchedule.
+ //
+ DescPtrs->fpEDControl = (OHCI_ED*)Ptr;
+ Ptr += sizeof (OHCI_ED);
+
+ DescPtrs->fpTDControlSetup = (OHCI_TD*)Ptr;
+ Ptr += sizeof (OHCI_TD);
+
+ DescPtrs->fpTDControlData = (OHCI_TD*)Ptr;
+ Ptr += sizeof (OHCI_TD);
+
+ DescPtrs->fpTDControlStatus = (OHCI_TD*)Ptr;
+ Ptr += sizeof (OHCI_TD);
+
+ DescPtrs->fpEDBulk = (OHCI_ED*)Ptr;
+ Ptr += sizeof (OHCI_ED);
+
+ DescPtrs->fpTDBulkData = (OHCI_TD*)Ptr;
+
+ if (HcStruc->dHCFlag & HC_STATE_EXTERNAL) {
+ return USB_SUCCESS;
+ }
+
+ // Allocate a ED/TD for EDRepeat/TDRepeat
+ Ptr = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(OHCI_ED));
+ ASSERT(Ptr);
+ DescPtrs->fpEDRepeat = (OHCI_ED*)Ptr;
+
+ Ptr = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(OHCI_TD));
+ ASSERT(Ptr);
+ DescPtrs->fpTDRepeat = (OHCI_TD*)Ptr;
+
+ DescPtrs->fpEDRepeat->dControl = (DUMMY_DEVICE_ADDR |
+ ED_IN_PACKET | ED_SKIP_TDQ | (DEFAULT_PACKET_LENGTH << 16));
+ DescPtrs->fpEDRepeat->fpHeadPointer = (UINT32)(UINTN)DescPtrs->fpTDRepeat;
+ DescPtrs->fpEDRepeat->fpEDLinkPointer = OHCI_TERMINATE;
+ DescPtrs->fpEDRepeat->fpTailPointer = OHCI_TERMINATE;
+ DescPtrs->fpEDRepeat->Interval = REPEAT_INTERVAL;
+
+ DescPtrs->fpTDRepeat->dControlStatus = (UINT32)(GTD_BUFFER_ROUNDING | GTD_IN_PACKET | GTD_IntD |
+ GTD_TWO_ERRORS | (GTD_NOT_ACCESSED << 28));
+ DescPtrs->fpTDRepeat->dCSReloadValue = (UINT32)(GTD_BUFFER_ROUNDING | GTD_IN_PACKET | GTD_IntD |
+ GTD_TWO_ERRORS | (GTD_NOT_ACCESSED << 28));
+
+ DescPtrs->fpTDRepeat->fpCurrentBufferPointer =
+ (UINT32)(UINTN)DescPtrs->fpTDRepeat->aSetupData;
+ DescPtrs->fpTDRepeat->fpBufferEnd =
+ (UINT32)(UINTN)DescPtrs->fpTDRepeat->aSetupData;
+ DescPtrs->fpTDRepeat->fpLinkPointer = OHCI_TERMINATE;
+ DescPtrs->fpTDRepeat->bCallBackIndex = USB_InstallCallBackFunction(OHCI_RepeatTDCallBack);
+ DescPtrs->fpTDRepeat->bActiveFlag = FALSE;
+
+ OhciAddPeriodicEd(HcStruc, DescPtrs->fpEDRepeat);
+
+ USBKeyRepeat(HcStruc, 0);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI_ResetHC
+//
+// DESCRIPTION: This function resets the OHCI controller
+//
+// PARAMETERS: Pointer to the HCStruc structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 OHCI_ResetHC(HC_STRUC* fpHCStruc)
+{
+ UINT32 BaseAddr = (UINT32)fpHCStruc->BaseAddress;
+ UINT8 i;
+ //
+ // Issue a software reset and HC go to UsbSuspend state
+ //
+ DwordWriteMem(BaseAddr, OHCI_COMMAND_STATUS, HC_RESET);
+
+ // The reset operation must be completed within 10 us
+ for (i = 0; i < 100; i++) {
+ FixedDelay(1); // 1 us delay
+ if (!(DwordReadMem(BaseAddr, OHCI_COMMAND_STATUS) & HC_RESET)) {
+ return USB_SUCCESS;
+ }
+ }
+
+ return USB_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI_ProcessRootHubStatusChange
+//
+// DESCRIPTION: This function is called when TD1024ms completes
+// a transaction. This TD runs a dummy interrupt transaction
+// to a non-existant device address for the purpose of
+// generating a periodic timeout interrupt. This periodic
+// interrupt may be used to check for new devices on the
+// root hub etc.
+//
+// PARAMETERS: Pointer to HC Struc
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 OHCI_ProcessRootHubStatusChange(HC_STRUC* fpHCStruc)
+{
+ UINT8 bHCNumber, bPort;//, bPortStatus; //(EIP59663)
+
+ //
+ // Check bEnumFlag before enumerating devices behind root hub
+ //
+ if (gUsbData->bEnumFlag == TRUE) return USB_ERROR;
+ gUsbData->bEnumFlag = TRUE; // Set enumeration flag and avoid hub port enumeration
+ //
+ // Mask the Host Controller interrupt so the ISR does not get re-entered due
+ // to an IOC interrupt from any TDs that complete in frames while we are
+ // configuring a new device that has just been plugged in.
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_DISABLE, 0x80000000);
+ //
+ // Check all the ports on the root hub for any change in connect status.
+ // If the connect status has been changed on either or both of these ports,
+ // then call the routine UsbHubPortChange for each changed port.
+ //
+ bHCNumber = fpHCStruc->bHCNumber | BIT7;
+
+ for (bPort = 1; bPort <= fpHCStruc->bNumPorts; bPort++) {
+ //(EIP59663)>
+ //bPortStatus = OHCI_GetRootHubStatus (fpHCStruc, bPort+1);
+ //DwordResetMem((UINT32)fpHCStruc->BaseAddress, OHCI_RH_PORT1_STATUS+bPort*4, 0xFFFF);
+ //if (bPortStatus & USB_PORT_STAT_DEV_CONNECT_CHANGED) {
+ USBCheckPortChange(fpHCStruc, bHCNumber, bPort);
+ //}
+ //DwordResetMem((UINT32)fpHCStruc->BaseAddress, OHCI_RH_PORT1_STATUS+bPort*4, 0xFFFF);
+ //<(EIP59663)
+ }
+ //
+ // Clear the RH_STATUS_CHANGE bit of the interrupt status register
+ // in the host controller: write 1 to bit to clear it
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_STATUS, RH_STATUS_CHANGE);
+
+ //
+ // Renable interrupts from the host controller
+ //
+ DwordWriteMem((UINT32)fpHCStruc->BaseAddress, OHCI_INTERRUPT_ENABLE, MASTER_INTERRUPT_ENABLE);
+
+ gUsbData->bEnumFlag = FALSE;
+ return USB_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCIWaitForTransferComplete
+//
+// DESCRIPTION: This function executes a device request command transaction
+//
+// PARAMETERS: fpHCStruc Pointer to HCStruc of the host controller
+// fpTD Pointer to the TD which has to be completed
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCIWaitForTransferComplete(
+ HC_STRUC *fpHCStruc,
+ OHCI_ED *XferED,
+ OHCI_TD *LastTD,
+ DEV_INFO* fpDevInfo
+)
+{
+ UINT32 Count ;
+ UINT32 Timeout = gUsbData->wTimeOutValue << 4; // *16, makes it number of 60mcs units
+
+ //
+ // Check status change loop iteration
+ //
+ for(Count = 0; !Timeout || Count < Timeout; Count++) {
+ OHCI_ProcessInterrupt(fpHCStruc);
+ if(!LastTD->bActiveFlag )
+ return USB_SUCCESS;
+ else if(!VALID_DEVINFO(fpDevInfo)){
+ USB_DEBUG (DEBUG_LEVEL_3, "OHCI Abort: devinfo: %x\n",fpDevInfo );
+ return USB_ERROR;
+ }
+ FixedDelay(60); // 60 microseconds
+ }
+
+ XferED->dControl |= ED_SKIP_TDQ;
+ OHCI_ProcessInterrupt(fpHCStruc);
+
+ if(!LastTD->bActiveFlag) {
+ return USB_SUCCESS;
+ }
+
+ USB_DEBUG (DEBUG_LEVEL_3, "OHCI Time-Out\n");
+
+ return USB_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI__StopUnsupportedHC
+//
+// DESCRIPTION: This routine is called, from host controllers that supports
+// OS handover functionality (currently from OHCI driver only), when OS
+// wants the BIOS to hand-over the host controllers to the OS. This routine
+// will stop HC that does not support this functionality.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_StopUnsupportedHC(
+ HC_STRUC* HcStruc
+)
+{
+ UINT8 i;
+
+ if (!gUsbData->UsbEhciHandoff) {
+ return USB_SUCCESS;
+ }
+
+//
+// Currently this host controller stops only the EHCI host controllers
+// Find the EHCI host controller HCStruc
+//
+ for (i = 0; i < gUsbData->HcTableCount; i++ ) {
+ if (gUsbData->HcTable[i] == NULL) {
+ continue;
+ }
+ if (!(gUsbData->HcTable[i]->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+ if (!(gUsbData->HcTable[i]->dHCFlag & HC_STATE_RUNNING) ||
+ (gUsbData->HcTable[i]->bHCType != USB_HC_EHCI) ||
+ ((gUsbData->HcTable[i]->wBusDevFuncNum & ~0x7) !=
+ (HcStruc->wBusDevFuncNum & ~0x7))) {
+ continue;
+ }
+
+ gUsbData->bHandOverInProgress = TRUE;
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ gUsbData->HcTable[i]->bHCType)].pfnHCDStop)(gUsbData->HcTable[i]);
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI_GeneralTDCallback
+//
+// DESCRIPTION: This function is called when bulk data or interrupt data TD
+// is completed. This routine just deactivates the TD.
+//
+// PARAMETERS: Pointer to the HCStruc structure
+// Pointer to the TD that completed
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_GeneralTDCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Td,
+ UINT8* Buffer,
+ UINT16 DataLength
+ )
+{
+ ((OHCI_TD*)Td)->bActiveFlag = FALSE;
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: OHCI_ControlTDCallback
+//
+// DESCRIPTION: This function is called when the control transfer scheduled
+// is completed.
+//
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+// fpDevInfo NULL (pDevInfo is not valid)
+// fpTD Pointer to the TD that completed
+// fpBuffer Not used
+//
+// RETURN: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OHCI_ControlTDCallback(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Td,
+ UINT8* Buffer,
+ UINT16 DataLength
+)
+{
+ OHCI_DESC_PTRS *DescPtrs;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ //
+ // Check to see if the TD that just completed has any error bits set. If
+ // any of the control TDs (Setup, Data, or Status) complete with an error, set
+ // ActiveFlag of the control status TD and copy the error information from the
+ // TD that just completed into the control status TD.
+ //
+ if ((UINT8)(((OHCI_TD*)Td)->dControlStatus >> 28)) {
+ DescPtrs = HcStruc->stDescPtrs.fpOHCIDescPtrs;
+ if (((UINT8*)DescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs + sizeof(OHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+ if (((UINT8*)DescPtrs->fpTDControlStatus < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->fpTDControlStatus + sizeof(OHCI_TD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+ if (DescPtrs->fpTDControlStatus != (OHCI_TD*)Td) {
+ DescPtrs->fpTDControlStatus->dControlStatus = ((OHCI_TD*)Td)->dControlStatus;
+ DescPtrs->fpTDControlStatus->bActiveFlag = FALSE;
+ }
+ }
+ //
+ // Make the TD that just completed inactive. It may be the control setup TD,
+ // one of the control data TDs, or the control status TD.
+ //
+ ((OHCI_TD*)Td)->bActiveFlag = FALSE;
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI_ProcessTD
+//
+// DESCRIPTION: This function will check whether the TD is completed
+// if so, it will call the call back routine associated with
+// this TD.
+//
+// PARAMETERS: HCStruc structure, Pointer to the TD
+//
+// NOTES: For any TD whose ActiveFlag is TRUE and its ControlStatus
+// bit 23 is clear (completed), process the TD by calling
+// its call back routine, if one is present.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void OHCI_ProcessTD(
+ HC_STRUC *HcStruc,
+ OHCI_TD *Td
+)
+{
+ if (!Td) {
+ return; // Check for NULL
+ }
+ if (Td->bActiveFlag != TRUE) {
+ return; // TD is not active
+ }
+ if ((Td->bCallBackIndex) && (Td->bCallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ if (gUsbData->aCallBackFunctionTable[Td->bCallBackIndex-1]) {
+ (*gUsbData->aCallBackFunctionTable[Td->bCallBackIndex-1])(
+ HcStruc,
+ 0,
+ (UINT8*)Td,
+ 0,
+ 0);
+ }
+ }
+}
+
+ //(EIP28707+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// FUNCTION: OHCI_FreeAllStruc
+//
+// DESCRIPTION: This function is used to free the all the allocated TDs,
+// QH and DescriptorPtr structure. This function only frees
+// the entries in the DescriptorPtr and the descriptor pointer
+// only.
+// ;
+// PARAMETERS: fpHCStruc Pointer to the HCStruc structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID OHCI_FreeAllStruc(HC_STRUC* fpHCStruc)
+{
+ OHCI_DESC_PTRS *fpDescPtrs;
+
+ fpDescPtrs = fpHCStruc->stDescPtrs.fpOHCIDescPtrs;
+
+// Free the EDs & TDs
+ USB_MemFree(fpDescPtrs->PeriodicEd, GET_MEM_BLK_COUNT_STRUC(OHCI_ED));
+ if (fpDescPtrs->fpEDRepeat) {
+ USB_MemFree(fpDescPtrs->fpEDRepeat, GET_MEM_BLK_COUNT_STRUC(OHCI_ED));
+ }
+ if (fpDescPtrs->fpTDRepeat) {
+ USB_MemFree(fpDescPtrs->fpTDRepeat, GET_MEM_BLK_COUNT_STRUC(OHCI_TD));
+ }
+
+ USB_MemFree(fpDescPtrs->fpEDControl,
+ GET_MEM_BLK_COUNT(2 * sizeof(OHCI_ED) + 4 * sizeof(OHCI_TD)));
+
+// Free descriptor structure (in BX)
+ USB_MemFree(fpDescPtrs, GET_MEM_BLK_COUNT_STRUC(OHCI_DESC_PTRS));
+}
+ //<(EIP28707+)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OhciIsHalted
+//
+// Description: This function check whether HC is halted.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+OhciIsHalted (
+ HC_STRUC *HcStruc
+)
+{
+ return (DwordReadMem((UINT32)HcStruc->BaseAddress, OHCI_CONTROL_REG) & HC_FUNCTION_STATE) != USBOPERATIONAL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: OhciTranslateInterval
+//
+// Description: This function calculates the polling rate.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+OhciTranslateInterval(
+ UINT8 Interval
+)
+{
+ UINT8 BitCount = 0;
+
+ // The Interval value should be from 1 to 255
+ ASSERT(Interval >= 1 && Interval <= 255);
+
+ for (BitCount = 0; Interval != 0; BitCount++) {
+ Interval >>= 1;
+ }
+ return (1 << (BitCount - 1));
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/ohci.h b/Core/EM/usb/rt/ohci.h
new file mode 100644
index 0000000..ca38dde
--- /dev/null
+++ b/Core/EM/usb/rt/ohci.h
@@ -0,0 +1,609 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ohci.h 9 7/26/13 2:36a Ryanchou $
+//
+// $Revision: 9 $
+//
+// 01/08/05 11:10a
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/ohci.h $
+//
+// 9 7/26/13 2:36a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 8 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 7 5/04/12 5:25a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 6 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 5 3/20/07 12:22p Olegi
+//
+// 4 12/13/06 5:40p Olegi
+// X64 build update
+//
+// 2 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Ohci.h
+//
+// Description: AMI USB OHCI driver header
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+// Avoid including multiple instance of this file
+#ifndef __OHCI_H
+#define __OHCI_H
+
+// Global equates for OHCI
+//-------------------------------------------------------------------------
+#define OHCI_FRAME_LIST_SIZE 32 // Number of DWORDs in interrupt list
+#define MAX_OHCI_BULK_DATA_SIZE (4 * 1024) // 4K
+
+// HCCA - Host Controller Commumications Area
+//----------------------------------------------------------------------------
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCIHCCA
+//
+// Description: OHCI host controller communications area is used by the
+// host controller driver(BIOS) to communicate with the
+// OHCI based host controller. This data area should be
+// bus master capable. Refer OHCI data sheet for more
+// information.
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// INTERRUPTLIST ARRAY 32 entries of periodic transfer pointer
+// HCCAFRAMENUMBER WORD Current frame number
+// HCCAPAD1 WORD Reserved
+// HCCADONEHEAD DWORD Location where the done head pointers will be placed
+// RES_HCCA ARRAY 120 bytes of reserved data
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+//OHCIHCCA STRUC
+// INTERRUPTLIST DD OHCI_FRAME_LIST_SIZE DUP (?)
+// HCCAFRAMENUMBER DW ?
+// HCCAPAD1 DW ?
+// HCCADONEHEAD DD ?
+// RES_HCCA DB 120 DUP (?)
+//OHCIHCCA ENDS
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT32 aInterruptList[OHCI_FRAME_LIST_SIZE];
+ UINT16 wHccaFrameNumber;
+ UINT16 wHccaPad1;
+ UINT32 dHccaDoneHead;
+ UINT8 aResHcca[120];
+} OHCI_HCCA_PTRS;
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCI_TD
+//
+// Description: OHCI general transfer descriptor structure. This structure is
+// used for bulk, interrupt and control transfers. This structure
+// holds the information needed for the transfer like buffer
+// size, address etc. Refer to OHCI specification for more
+// information. The last sixteen bytes in the structure (after
+// BufferEnd) is AMIBIOS internal data structure.
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// dControlStatus DWORD Control & status (OHCI_TD_CONTROL)
+// fpCurrentBufferPointer DWORD Current buffer pointer
+// fpLinkPointer DWORD Pointer to the next GTD
+// fpBufferEnd DWORD Pointer to the end of the buffer
+// dCSReloadValue DWORD Copy of control status during scheduling
+// bCallBack NEAR Pointer to call back function
+// bActiveFlag BYTE Non-zero value indicates TD is active
+// bDeviceAddr BYTE USB device address
+// aSetupData ARRAY 8 byte setup data buffer
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+/*
+OHCI_TD STRUC
+
+ ControlStatus DD ? ; Control and status fields
+ CurrentBufferPointer DD ? ; Current buffer pointer
+ LinkPointer DD ? ; Pointer to the next TD
+ BufferEnd DD ? ; End pointer of data buffer
+
+ CSReloadValue DD ? ; Reload value for control
+ pCallback PTRFUNCTDCALLBACK ? ; Routine to call on completion
+ ActiveFlag DB ? ; If nonzero, TD is active
+ DeviceAddress DB ? ; Device address
+ SetupData DB 8 dup (?) ; Used for setup packet
+
+OHCI_TD ENDS*/
+
+typedef struct {
+ UINT32 dControlStatus; // Control and status fields
+ UINT32 fpCurrentBufferPointer; // Current buffer pointer
+ UINT32 fpLinkPointer; // Pointer to the next TD
+ UINT32 fpBufferEnd; // End pointer of data buffer
+
+ UINT32 dCSReloadValue; // Control status reload value
+ UINT8 bCallBackIndex; // Index of the routine to call on completion
+ UINT8 bActiveFlag; // Routine to call on completion
+ UINT8 bDeviceAddr; // Device Address
+ UINT8 bResvd;
+ UINT8 aSetupData[8]; // Used for setup packet
+} OHCI_TD;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCI_ED
+//
+// Description: OHCI Endpoint descriptor structure. This structure is needed
+// for all the USB transaction. This structure had the
+// information regarding the transfer. Refer to OHCI specification
+// for more information
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// dControl DWORD ED control fields (refer OHCI_ED_CONTROL)
+// fpTDTailPtr DWORD TD queue tail pointer
+// fpTDHeadPointer DWORD TD queue head pointer
+// fpEDLinkPointer DWORD Pointer to the next ED
+// aReserved ARRAY 16 bytes of reserved data
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _OHCI_ED {
+ UINT32 dControl; // ED control fields
+ UINT32 fpTailPointer; // TD queue tail pointer
+ UINT32 fpHeadPointer; // TD queue head pointer
+ UINT32 fpEDLinkPointer; // Pointer to next ED
+ UINT8 Interval;
+ UINT8 aReserved[15];
+} OHCI_ED;
+
+#pragma pack(pop)
+
+/*
+typedef struct
+{
+ UINT32 dControlStatus;
+ PHY_ADDR pCurBufPtr;
+ PHY_ADDR pLinkPtr;
+ PHY_ADDR pBufEnd;
+
+// AMI defined fields
+ UINT32 dCSReload; // Control status reload value
+ UINT8 bCallBackIndex;
+ UINT8 bActiveFlag;
+ UINT8 bDevAddr;
+ UINT8 bReserved;
+ UINT8 aDataArea[8];
+} OHCI_GTD, _FAR_ *FPOHCI_GTD;
+*/
+//typedef struct
+//{
+// OHCI_GTD _FAR_ * fpSomeGTD;
+// OHCI_ED _FAR_ * fpSomeED;
+//} OHCI_DESC_PTRS, _FAR_ *FPOHCI_DESC_PTRS;
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCIDescriptors
+//
+// Description: Descriptors structure is used to hold the host controller
+// instance specific general transfer descriptor and endpoint
+// descriptor pointers. The following structure defines such
+// the descriptors for OHCI based host controller instances.
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// fpED1ms OHCI_ED ED scheduled in 1ms timeframe
+// fpED2ms OHCI_ED ED scheduled in 2ms timeframe
+// fpED8ms OHCI_ED ED scheduled in 8ms timeframe
+// fpED32ms OHCI_ED ED scheduled in 32ms timeframe
+// fpTD32ms OHCI_TD TD scheduled in 32ms timeframe
+// fpEDRepeat OHCI_ED ED scheduled for keyboard repeat rate generator
+// fpTDRepeat OHCI_TD TD scheduled for keybord repeat rate generator
+// TDRepeat OHCI_TD TD associated with generation of repeat data
+// fpEDControl OHCI_ED ED associated for control transfer
+// fpTDControlSetup OHCI_TD TD associated with control setup
+// fpTDControlData OHCI_TD TD associated with control data
+// fpTDControlStatus OHCI_TD TD associated with control status
+// fpEDInterrupt OHCI_ED ED associated for interrupt transfer
+// fpTDInterruptData OHCI_TD TD associated to transfer interrupt data
+// fpEDBulk OHCI_ED ED associated for bulk transfer
+// fpTDBulkData OHCI_TD TD associated to transfer bulk data
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+/*
+OHCIDescriptors STRUC
+ ED1ms DW ?
+ ED2ms DW ?
+ ED8ms DW ?
+// Do not change the following order of ED32ms and TD32ms
+ ED32ms DW ?
+ TD32ms DW ?
+// Do not change the following order of EDRepeat and TDRepeat
+ EDRepeat DW ?
+ TDRepeat DW ?
+ EDControl DW ?
+ TDControlSetup DW ?
+ TDControlData DW ?
+ TDControlStatus DW ?
+ EDInterrupt DW ?
+ TDInterruptData DW ?
+ EDBulk DW ?
+ TDBulkData DW ?
+OHCIDescriptors ENDS
+*/
+
+typedef struct {
+ OHCI_ED *PeriodicEd;
+// Do not change the following order of EDRepeat and TDRepeat
+ OHCI_ED *fpEDRepeat;
+ OHCI_TD *fpTDRepeat;
+
+ OHCI_ED *fpEDControl;
+ OHCI_TD *fpTDControlSetup;
+ OHCI_TD *fpTDControlData;
+ OHCI_TD *fpTDControlStatus;
+
+ OHCI_ED *fpEDInterrupt;
+ OHCI_TD *fpTDInterruptData;
+
+ OHCI_ED *fpEDBulk;
+ OHCI_TD *fpTDBulkData;
+} OHCI_DESC_PTRS;
+
+#define USB_OHCI_DESCRIPTOR_SIZE_BLK ((size of OHCIDescriptors + USB_MEM_BLK_SIZE - 1) >> USB_MEM_BLK_SIZE_SHIFT)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCI_ED_CONTROL
+//
+// Description: Bit definition for OHCI_ED control field
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// FuncAddress BITS:06-00 USB device address
+// EndpointNum BITS:10-07 Endpoint number
+// Direction BITS:12-11 Direction of data flow
+// Speed BITS:13 Endpoint speed
+// Skip BITS:14 If set ED will be skipped
+// Format BITS:15 Set for isochronous endpoint
+// MaxPacketSize BITS:26-16 Endpoint max packet size
+// Reserved BITS:31-27 Reserved bits
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+
+// Bit definitions for endpoint descriptor control field
+//-------------------------------------------------------------------------
+#define ED_FUNCTION_ADDRESS 0x0000007f
+#define ED_ENDPOINT 0x00000780
+#define ED_DIRECTION 0x00001800
+#define ED_OUT_PACKET 0x00000800
+#define ED_IN_PACKET 0x00001000
+#define ED_LOW_SPEED 0x00002000
+#define ED_SKIP_TDQ 0x00004000
+#define ED_FORMAT 0x00008000
+#define ED_MAX_PACK_SIZE 0x07ff0000
+
+//Bit definition for endpoint descriptor direction
+//-------------------------------------------------------------------------
+#define ED_DATA_OUT 0x01
+#define ED_DATA_IN 0x02
+
+// Bit definition for endpoint descriptor TD queue tail pointer
+//-------------------------------------------------------------------------
+#define ED_HALTED 0x00000001
+#define ED_TOGGLE_CARRY 0x00000002
+
+//Bit define for general pointer
+//------------------------------------------------------------------------
+#define OHCI_TERMINATE 0x00000000
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: OHCI_TD_CONTROL
+//
+// Description: Bit definition for OHCI_TD ControlStatus field
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// Reserved BITS:17-00 Reserved bits
+// BufferRounding BITS:18 Buffer rounding (1-Allow small packets)
+// DirectionPid BITS:20-19 Direction & PID (SETUP/IN/OUT etc)
+// DelayInt BITS:23-21 Num. frames to wait before interrupting
+// DataToggle BITS:25-24 Data toggle
+// ErrorCount BITS:27-26 Error count
+// ConditionCode BITS:31-28 Completion condition code
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>*/
+
+// Bit definition for general transfer descriptor control fields
+//-------------------------------------------------------------------------
+#define GTD_BUFFER_ROUNDING 0x000040000
+#define GTD_DIRECTION_PID 0x000180000
+#define GTD_SETUP_PACKET 0x000000000
+#define GTD_OUT_PACKET 0x000080000
+#define GTD_IN_PACKET 0x000100000
+#define GTD_DELAY_INTERRUPT 0x000e00000
+#define GTD_IntD 0x000000000 // depend on device,now guest 0
+#define GTD_DATA_TOGGLE 0x003000000
+#define GTD_SETUP_TOGGLE 0x002000000 // same as MSB of data toggle
+#define GTD_DATA1_TOGGLE 0x003000000
+#define GTD_STATUS_TOGGLE 0x003000000
+#define GTD_ERROR_COUNT 0x00c000000
+#define GTD_NO_ERRORS 0x000000000
+#define GTD_ONE_ERROR 0x004000000
+#define GTD_TWO_ERRORS 0x008000000
+#define GTD_THREE_ERRORS 0x00C000000
+#define GTD_CONDITION_CODE 0x0f0000000
+//------------------------------------------------------------------------
+
+// Bit define for ConditionCode or CompletionCode use for each CallBack func
+// transmission error
+//-------------------------------------------------------------------------
+#define GTD_STATUS_FIELD 0x0f0000000 //include NOT_ACCESS
+#define GTD_NO_ERROR 0x00
+#define GTD_CRC_ERROR 0x01
+#define GTD_BIT_STUFF 0x02
+#define GTD_TOGGLE_MISMATCH 0x03
+#define GTD_STALL 0x04
+#define GTD_DEVICE_NOT_RESPOND 0x05
+#define GTD_PID_CHECK_ERROR 0x06
+#define GTD_UNEXPECTED_PID 0x07
+#define GTD_DATA_OVERRUN 0x08
+#define GTD_DATA_UNDERRUN 0x09
+#define GTD_BUFFER_OVERRUN 0x0c // not used for GTD
+#define GTD_BUFFER_UNDERRUN 0x0d // not used for GTD
+#define GTD_NOT_ACCESSED 0x0f
+
+//-------------------------------------------------------------------------
+// Equates for Host Controller Operational Register
+// reg for control and status
+//-------------------------------------------------------------------------
+#define OHCI_REVISION_REG 0x00
+#define OHCI_CONTROL_REG 0x04
+#define OHCI_COMMAND_STATUS 0x08
+#define OHCI_INTERRUPT_STATUS 0x0c
+#define OHCI_INTERRUPT_ENABLE 0x10
+#define OHCI_INTERRUPT_DISABLE 0x14
+// reg for memory pointer
+#define OHCI_HCCA_REG 0x18
+#define OHCI_PERIOD_CURRENT_ED 0x1c
+#define OHCI_CONTROL_HEAD_ED 0x20
+#define OHCI_CONTROL_CURRENT_ED 0x24
+#define OHCI_BULK_HEAD_ED 0x28
+#define OHCI_BULK_CURRENT_ED 0x2c
+#define OHCI_DONE_HEAD 0x30
+// reg for frame counter
+#define OHCI_FRAME_INTERVAL 0x34
+#define OHCI_FRAME_REMAINING 0x38
+#define OHCI_FRAME_NUMBER 0x3c
+#define OHCI_PERIODIC_START 0x40
+#define OHCI_LS_THRESHOLD 0x44
+// reg for root hub
+#define OHCI_RH_DESCRIPTOR_A 0x48
+#define OHCI_RH_DESCRIPTOR_B 0x4c
+#define OHCI_RH_STATUS 0x50
+#define OHCI_RH_PORT1_STATUS 0x54
+#define OHCI_RH_PORT2_STATUS 0x58
+
+// OHCI emulation register equates
+#define OHCI_HCE_CONTROL 0x100
+#define OHCI_HCE_INPUT 0x104
+#define OHCI_HCE_OUTPUT 0x108
+#define OHCI_HCE_STATUS 0x10C
+
+// Bit definitions for emulation registers
+#define HCE_CNTRL_EMULATION_ENABLE BIT0
+#define HCE_CNTRL_EMULATION_INTERRUPT BIT1
+#define HCE_CNTRL_CHARACTER_PENDING BIT2
+#define HCE_CNTRL_IRQ_ENABLE BIT3
+#define HCE_CNTRL_EXT_IRQ_ENABLE BIT4
+#define HCE_CNTRL_GA20_SEQ BIT5
+#define HCE_CNTRL_IRQ1_ACTIVE BIT6
+#define HCE_CNTRL_IRQ12_ACTIVE BIT7
+#define HCE_CNTRL_A20_STATE BIT8
+
+
+#define HCE_STS_OUTPUTFULL BIT0
+#define HCE_STS_INPUTFULL BIT1
+#define HCE_STS_FLAG BIT2
+#define HCE_STS_CMDDATA BIT3
+#define HCE_STS_INHIBIT_SWITCH BIT4
+#define HCE_STS_AUXOUTPUTFULL BIT5
+#define HCE_STS_TIMEOUT BIT6
+#define HCE_STS_PARITY BIT7
+//-------------------------------------------------------------------------
+// Bit define for HC control register
+//-------------------------------------------------------------------------
+#define CONTROL_BULK_RATE 0x0003
+#define PERIODIC_LIST_ENABLE 0x0004
+#define ISOCHRONOUS_ENABLE 0x0008
+#define CONTROL_LIST_ENABLE 0x0010
+#define BULK_LIST_ENABLE 0x0020
+#define HC_FUNCTION_STATE 0x00c0
+#define USBRESET 0x0000
+#define USBRESUME 0x0040
+#define USBOPERATIONAL 0x0080
+#define USBSUSPEND 0x00c0
+#define INTERRUPT_ROUTING 0x0100
+#define REMOTE_WAKEUP_CONNECT 0x0200
+#define REMOTE_WAKEUP_ENABLE 0x0400
+//-------------------------------------------------------------------------
+
+// Bit define for HC command status register
+//-------------------------------------------------------------------------
+#define HC_RESET 0x00001
+#define CONTROL_LIST_FILLED 0x00002
+#define BULK_LIST_FILLED 0x00004
+#define OWNERSHIP_CHANGE_REQUEST 0x00008
+#define SCHEDULING_OVERRUN_COUNT 0x30000
+
+// Bit define for HC interrupt status register
+//-------------------------------------------------------------------------
+#define SCHEDULING_OVERRUN 0x00000001
+#define WRITEBACK_DONEHEAD 0x00000002
+#define START_OF_FRAME 0x00000004
+#define RESUME_DETECTED 0x00000008
+#define UNCOVERABLE_ERR 0x00000010
+#define FRAMENUMBER_OVERFLOW 0x00000020
+#define RH_STATUS_CHANGE 0x00000040
+#define OWNERSHIP_CHANGE 0x40000000
+
+// Bit define for HC interrupt enable register
+//-------------------------------------------------------------------------
+#define SCHEDULING_OVERRUN_ENABLE 0x00000001
+#define WRITEBACK_DONEHEAD_ENABLE 0x00000002
+#define START_OF_FRAME_ENABLE 0x00000004
+#define RESUME_DETECTED_ENABLE 0x00000008
+#define UNCOVERABLE_ERR_ENABLE 0x00000010
+#define FRAMENUMBER_OVERFLOW_ENABLE 0x00000020
+#define RH_STATUS_CHANGE_ENABLE 0x00000040
+#define OWNERSHIP_CHANGE_ENABLE 0x40000000
+#define MASTER_INTERRUPT_ENABLE 0x80000000
+
+// Bit define for HC interrupt disable register
+//-------------------------------------------------------------------------
+#define SCHEDULING_OVERRUN_DISABLE 0x00000001
+#define WRITEBACK_DONEHEAD_DISABLE 0x00000002
+#define START_OF_FRAME_DISABLE 0x00000004
+#define RESUME_DETECTED_DISABLE 0x00000008
+#define UNCOVERABLE_ERR_DISABLE 0x00000010
+#define FRAMENUMBER_OVERFLOW_DISABLE 0x00000020
+#define RH_STATUS_CHANGE_DISABLE 0x00000040
+#define OWNERSHIP_CHANGE_DISABLE 0x40000000
+#define MASTER_INTERRUPT_DISABLE 0x80000000
+
+// Bit define for HC frame interval register
+//-------------------------------------------------------------------------
+#define FRAME_INTERVAL 0x00003fff
+#define FS_LARGEST_DATA_PACKET 0x4fff0000
+#define FRAME_INTERVAL_TOGGLE 0x80000000
+
+// Bit define for HC frame remaining register
+//-------------------------------------------------------------------------
+#define FRAME_REMAINING 0x00003fff
+#define FRAME_REMAINING_TOGGLE 0x80000000
+
+// Bit define for HC root hub descriptor A register
+//-------------------------------------------------------------------------
+#define RH_PORT_NUMBER 0x000000ff
+#define POWER_SWITCH_MODE 0x00000100
+#define NO_POWER_SWITCH 0x00000200
+#define DEVICE_TYPE 0x00000400
+#define OVERCURRENT_PROTECT 0x00000800
+#define NO_OVERCURRENT_PROTECT 0x00001000
+#define POWERON2POWERGOOD_TIME 0x0ff000000
+
+
+// Bit define for HC root hub descriptor B register
+//-------------------------------------------------------------------------
+#define DEVICE_REMOVABLE 0x0000ffff
+#define PORT_POWER_MASK 0x0ffff0000
+
+// Bit define for HC root hub status register
+//-------------------------------------------------------------------------
+#define LOCAL_POWER_STATUS 0x00000001
+#define CLEAR_GLOBAL_POWER 0x00000001
+#define OVERCURRENT 0x00000002
+#define DEVICE_REMOTE_WAKEUP 0x00008000
+#define SET_REMOTE_WAKEUP 0x00008000
+#define LOCAL_POWER_CHANGE 0x00010000
+#define SET_GLOBAL_POWER 0x00010000
+#define OVERCURRENT_CHANGE 0x00020000
+#define CLEAR_REMOTE_WAKEUP 0x80000000
+
+// Bit define for HC root hub port1,2 status register
+//-------------------------------------------------------------------------
+#define CURRENT_CONNECT_STATUS 0x00000001
+#define CLEAR_PORT_ENABLE 0x00000001
+#define PORT_ENABLE_STATUS 0x00000002
+#define SET_PORT_ENABLE 0x00000002
+#define PORT_SUSPEND_STATUS 0x00000004
+#define SET_PORT_SUSPEND 0x00000004
+#define PORT_OVERCURRENT 0x00000008
+#define CLEAR_PORT_SUSPEND 0x00000004
+#define PORT_RESET_STATUS 0x00000010
+#define SET_PORT_RESET 0x00000010
+#define PORT_POWER_STATUS 0x00000100
+#define SET_PORT_POWER 0x00000100
+#define LOW_SPEED_DEVICE_ATTACHED 0x00000200
+#define CLEAR_PORT_POWER 0x00000200
+#define CONNECT_STATUS_CHANGE 0x00010000
+#define PORT_ENABLE_STATUS_CHANGE 0x00020000
+#define PORT_SUSPEND_STATUS_CHANGE 0x00040000
+#define PORT_OVERCURRENT_CHANGE 0x00080000
+#define PORT_RESET_STATUS_CHANGE 0x00100000
+
+#endif // __OHCI_H
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/syskbc.c b/Core/EM/usb/rt/syskbc.c
new file mode 100644
index 0000000..157a9bd
--- /dev/null
+++ b/Core/EM/usb/rt/syskbc.c
@@ -0,0 +1,3225 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/syskbc.c 41 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 41 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/syskbc.c $
+//
+// 41 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 40 2/24/15 5:50a Wilsonlee
+// [TAG] EIP149716
+// [Category] Improvement
+// [Description] Error Handling in USB mouse data.
+// [Files] usbms.c, usbkbd.h, syskbc.c, xhci.c
+//
+// 39 7/23/14 10:23p Wilsonlee
+// [TAG] EIP177642
+// [Category] Improvement
+// [Description] SysKbcAutoRepeat handles the error case, the
+// kbdInput_Send return error status.
+// [Files] syskbc.c
+//
+// 38 6/26/14 1:15a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 37 5/06/14 5:14a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 36 5/01/14 4:24a Ryanchou
+// [TAG] EIP151894
+// [Category] Improvement
+// [Description] Correct the break code of arrow keys.
+// [Files] syskbc.c
+//
+// 35 4/29/14 7:53p Wilsonlee
+// [TAG] EIP163828
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The mouses stop more than 4 seconds during TP 0xB4 when
+// power on several times.
+// [RootCause] The device sometime doesn't respond the set report
+// command.
+// [Solution] Change the timeout of set report command to 100 ms.
+// [Files] syskbc.c, sysnokbc.c, usbhid.c, amiusb.h
+//
+// 34 12/30/13 3:42a Wilsonlee
+// [TAG] EIP148411
+// [Category] Improvement
+// [Description] Check if CCB_MOUSE_INTRPT is set before we sent mouse
+// data.
+// [Files] usbkbd.h, syskbc.c
+//
+// 33 8/22/13 6:32a Wilsonlee
+// [TAG] EIP122944
+// [Category] Improvement
+// [Description] Remove mouse_flag3 and check the mouse interface status
+// in the CCB byte before we send the data to KBC.
+// [Files] syskbc.c, usbms.c
+//
+// 32 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 31 12/02/12 10:29p Roberthsu
+// [TAG] EIP102150
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Push key and unplug KB , character repeat can not.
+// stop
+// [RootCause] Because repeat key does not clear when usb keyboard
+// unplug.
+// [Solution] When keyboard disconnrct, clear keyboard device id with
+// device id buffer and scancode buffer.
+// [Files] amiusb.c,syskbc.c,uhcd.c,usbkbd.c
+//
+// 30 8/27/12 5:08a Roberthsu
+// [TAG] EIP98251
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] RF KB NumLock/ScrollLock/CapsLock indicator is not
+// available during post or BIOS setup menu
+// [RootCause] Set led command lost report id.
+// [Solution] Check report id exist.
+// [Files] syskbc.c,usbhid.c
+//
+// 29 5/22/12 10:55a Jittenkumarp
+// [TAG] EIP87959
+// [Category] New Feature
+// [Description] Proper Error path in the USB driver, incase KBC Input
+// buffer is full
+// [Files] usbkbd.h, syskbc.c
+//
+// 28 5/22/12 6:32a Ryanchou
+// [TAG] EIP89608
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Barcode reader does not scan line-word
+// [RootCause] The EIP72505 change breaks the loop of processing scan
+// code buffer.
+// [Solution] All the character should be processed.
+// [Files] syskbc.c
+//
+// 27 1/04/12 6:54a Ryanchou
+// [TAG] EIP72505
+// [Category] Improvement
+// [Description] Clear the legacy USB keyboard buffer when switching
+// between EFI and legacy.
+// [Files] syskbc.c, uhcd.c, usbkbd.c
+//
+// 26 12/08/11 4:04a Ryanchou
+// [TAG] EIP75266
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] There are garbage characters if press arrow key for a while
+// [RootCause] The arrow generates 4 bytes of repeat key for scan code
+// set 1, it should be 2 bytes.
+// [Solution] Correct the repeat key generation.
+// [Files] syskbc.c
+//
+// 25 9/27/11 12:07a Roberthsu
+// [TAG] EIP65344
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Razer mouse will hang in post
+// [RootCause] Razer has report keyboard interface.But not report led
+// usage.
+// [Solution] Check if not report led usage page.Do not send led
+// command.
+// [Files] syskbc.c,usbhid.c,usbdef.h
+//
+// 24 7/13/11 3:24a Ryanchou
+// [TAG] EIP60380
+// [Bug fix] USB keyboard can't repeat character under DOS
+// [Symptom] Insert the wireless USB keyboard. It can't repeat character
+// under DOS
+// [Root Cause] Because wRepeatCounter always clear by every time.
+// [Solution] Do not clear wRepeatCounter everytime.
+//
+// 23 5/24/11 12:04p Olegi
+// [TAG] EIP56557
+// [Category] Improvement
+// [Description] Modified SendMouseData function.
+// [Files] syskbc.c
+//
+// 22 5/24/11 12:00p Olegi
+// [TAG] EIP60261
+// [Category] Improvement
+// [Description] Ultrasound keyboard fails the LED related transfer.
+// [Files] syskbc.c
+//
+// 21 5/03/11 6:56a Ryanchou
+// [TAG] EIP57745
+// [Category] Improvement
+// [Description] The token CHECK_MOUSE_FLAG is depend on CSM version,
+// remove the token and check CSM verion to support this feature or not.
+// [Files] syskbc.c, usbms.c, usbsrc.sdl
+//
+// 20 9/08/10 8:06a Ryanchou
+// EIP43822: Add a toekn "CHECK_MOUSE_FLAG", the token controls whether
+// apply EIP40121 solution.
+//
+// 19 8/18/10 4:27p Olegi
+// - Klockwork related fixes; EIP37978
+// - Send mouse driver only when driver is active; EIP40121
+//
+// 18 7/08/10 2:21a Rameshr
+// Ohci Emulation support Added.
+// EIP 39712
+//
+// 17 11/24/09 11:33a Olegi
+// BIOS adds an USB API (Block KBC Access)
+//
+// 16 11/18/09 11:49a Olegi
+//
+// 15 11/18/09 11:48a Olegi
+// Modified the codes returned on Shift-NumLock-ExtKeys(Home, Ins,...)
+// combination. For these combinations NumLock cancels Shift. EIP#27889
+//
+// 14 9/15/09 12:21p Olegi
+// Added KEY_REPEAT_LOGIC functionality. EIP#25841
+//
+// 13 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 12 12/19/07 12:20p Rameshraju
+// Emulation disabled before getting the CCB and Enabled back again if the
+// Emulation is active.
+//
+// 11 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 10 9/27/07 4:12p Olegi
+//
+// 9 9/26/07 9:25a Olegi
+//
+// 8 8/14/07 11:03a Olegi
+// USBSendMouseData is using USB_MOUSE_UPDATE_EBDA_DATA token.
+//
+// 7 3/29/07 6:42p Olegi
+// Code improvement in USBMSSendMouseData to avoid sync problems between
+// PS/2 and USB mice.
+//
+// 6 3/20/07 12:22p Olegi
+//
+// 4 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 11/15/05 3:42p Andriyn
+// Fix: 2-byte keys get lost.
+//
+// 1 8/25/05 7:15p Andriyn
+//
+// 5 8/11/05 9:53a Olegi
+// 60/64 port emulation related fixes for EMU6064 driver.
+//
+// 4 8/04/05 5:58p Andriyn
+// Legacy over LegacyFree
+//
+// 2 6/01/05 5:22p Olegi
+// Debug message shortened.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: SysKbc.c
+//
+// Description: AMI USB keyboard driver data conversion and presentation
+// routines, KBC is present
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+extern UINT8 aTypematicRateDelayTable[];
+extern EFI_EMUL6064KBDINPUT_PROTOCOL* gKbdInput;
+extern EFI_EMUL6064MSINPUT_PROTOCOL* gMsInput;
+extern EFI_EMUL6064TRAP_PROTOCOL* gEmulationTrap;
+extern void USBKB_LEDOn();
+
+UINT8 IsKbcAccessBlocked=FALSE; //(EIP29733+)
+
+UINT8 aStaticSet2ToSet1ScanCode[133] =
+ { 0x000,0x0E5,0x0F5,0x006,0x016,0x026,0x01E,0x03D, //; 00h - 07h
+ 0x0DC,0x0DD,0x0ED,0x0FD,0x00E,0x087,0x0B6,0x035, //; 08h - 0Fh
+ 0x0D4,0x03E,0x0AE,0x07C,0x017,0x07F,0x0EF,0x02D, //; 10h - 17h
+ 0x0CC,0x074,0x09E,0x007,0x00F,0x077,0x0E7,0x025, //; 18h - 1Fh
+ 0x0C4,0x08E,0x096,0x0FE,0x06F,0x0D7,0x0DF,0x01D, //; 20h - 27h
+ 0x0BC,0x036,0x086,0x0F6,0x05F,0x067,0x0CF,0x015, //; 28h - 2Fh
+ 0x0B4,0x076,0x07E,0x0E6,0x0EE,0x057,0x0C7,0x00D, //; 30h - 37h
+ 0x0AC,0x06C,0x06E,0x0DE,0x04F,0x0BF,0x0B7,0x005, //; 38h - 3Fh
+ 0x0A4,0x066,0x0D6,0x047,0x03F,0x0A7,0x0AF,0x0FC, //; 40h - 47h
+ 0x09C,0x05E,0x056,0x0CE,0x0C6,0x037,0x09F,0x0F4, //; 48h - 4Fh
+ 0x094,0x064,0x0BE,0x05C,0x02F,0x097,0x0EC,0x08C, //; 50h - 57h
+ 0x02E,0x04E,0x01F,0x027,0x054,0x0A6,0x0E4,0x04C, //; 58h - 5Fh
+ 0x055,0x04D,0x044,0x03C,0x034,0x02C,0x08F,0x024, //; 60h - 67h
+ 0x01C,0x085,0x014,0x0A5,0x0C5,0x00C,0x004,0x084, //; 68h - 6Fh
+ 0x06D,0x065,0x07D,0x09D,0x095,0x0BD,0x0F7,0x0D5, //; 70h - 77h
+ 0x045,0x08D,0x075,0x0AD,0x046,0x0B5,0x0CD,0x05D, //; 78h - 7Fh
+ 0x0FB,0x0F3,0x0EB,0x0F5,0x05D //; 80h - 84h
+ };
+
+//----------------------------------------------------------------------------
+//------ USA ENGLISH keyboard -------
+// USB Key Code to Scan Code Set 2
+
+UINT8 aUSBKeyCodeToScanCodeSet2Table[256] =
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x1C, 0x32, 0x21, 0x23, //00 - 07h
+ 0x24, 0x2B, 0x34, 0x33, 0x43, 0x3B, 0x42, 0x4B, //08 - 0Fh
+ 0x3A, 0x31, 0x44, 0x4D, 0x15, 0x2D, 0x1B, 0x2C, //10 - 17h
+ 0x3C, 0x2A, 0x1D, 0x22, 0x35, 0x1A, 0x16, 0x1E, //18 - 1Fh
+ 0x26, 0x25, 0x2E, 0x36, 0x3D, 0x3E, 0x46, 0x45, //20 - 27h
+ 0x5A, 0x76, 0x66, 0x0D, 0x29, 0x4E, 0x55, 0x54, //28 - 2Fh
+ 0x5B, 0x5D, 0x5D, 0x4C, 0x52, 0x0E, 0x41, 0x49, //30 - 37h
+ 0x4A, 0x58, 0x05, 0x06, 0x04, 0x0C, 0x03, 0x0B, //38 - 3Fh
+ 0x83, 0x0A, 0x01, 0x09, // 40 - 43h
+ 0x78, 0x07, PRINT_SCREEN,0x7E, // 44 - 47h
+ PAUSE_KEY, INSERT_KEY, HOME_KEY, // 48 - 4Ah
+ PAGE_UP_KEY, DEL_KEY, END_KEY, // 4B - 4Dh
+ PAGE_DOWN_KEY, RIGHT_KEY, // 4E - 4Fh
+ LEFT_KEY, DOWN_KEY, UP_KEY, 0x77, // 50 - 53h
+ SLASH_KEY, 0x7C, 0x7B, 0x79, // 54 - 57h
+ RIGHT_ENTER, 0x69, 0x72, 0x7A, // 58 - 5Ch
+ 0x6B, 0x73, 0x74, 0x6C, // 5D - 5Fh
+ 0x75, 0x7D, 0x70, 0x71, 0x61, APP_MS_KEY,00, 0x00, // 60 - 67h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 68 - 6Fh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 70 - 77h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, //78 - 7Fh
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, // 80 - 87h
+ 0x13, 0x6A, 0x64, 0x67, 0x00, 0x00, 0x00, 0x00, // 88 - 8Fh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90 - 97h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 98 - 9Fh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // A0 - A7h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // A8 - AFh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B0 - B7h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // B8 - BFh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // C0 - C7h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // C8 - CFh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // D0 - D7h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // D8 - DFh
+ 0x14, 0x12, 0x11, LEFT_MS_KEY, // E0 - E3h
+ RIGHT_CTRL, 0x59, RIGHT_ALT, RIGHT_MS_KEY, // E4 - E7h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // E8 - EFh
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // F0 - F7h
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // F8 - FFh
+ };
+// Keyboard Scan Code Set 3 Table
+#define SCAN_CODE_SET_TABLE_SIZE_DW 8 // In double word
+UINT8 aStaticScanCodeSet3Table[32] =
+ {
+ 0x00, 0x15, 0x00, 0x28, 0x94, 0x29, 0xA4, 0x2A,
+ 0xA8, 0x2A, 0xA8, 0x2A, 0xA8, 0x2A, 0xA0, 0x2A,
+ 0xA8, 0x2A, 0xA8, 0x2A, 0xA8, 0x0A, 0xA4, 0x0A,
+ 0x8A, 0x22, 0x20, 0x00, 0x00, 0x00, 0x00, 0x02
+ };
+
+
+UINT8 aStaticExtendedKeyScan2Table[6] =
+ { RIGHT_ALT, RIGHT_CTRL, RIGHT_ENTER, LEFT_MS_KEY,
+ RIGHT_MS_KEY, APP_MS_KEY };
+
+UINT8 aStaticKeyPadScan2Table[10] =
+ { END_KEY, LEFT_KEY, HOME_KEY, INSERT_KEY,
+ DEL_KEY, DOWN_KEY, RIGHT_KEY, UP_KEY,
+ PAGE_DOWN_KEY, PAGE_UP_KEY };
+
+
+UINT8 aStaticExtendedKeyScan3Table[6] =
+ { 0x39, 0x58, 0x79, 0x8B, 0x8C, 0x8D};
+UINT8 aStaticKeyPadScan3Table[10] =
+ { 0x65, 0x61, 0x6E, 0x67, 0x64, 0x60, 0x6A, 0x63, 0x6D, 0x6F };
+
+//----------------------------------------------------------------------------
+// Table used to find length of scan code needed. Please refer to comments
+// in the code below (somewhere) for the usage.
+//
+UINT8 aScanCodeLengthTable_1112[4] = {0x01, 0x01, 0x01, 0x02};
+UINT8 aScanCodeLengthTable_2223[4] = {0x02, 0x02, 0x02, 0x003};
+UINT8 aScanCodeLengthTable_4446[4] = {0x04, 0x04, 0x04, 0x06};
+UINT8 aScanCodeLengthTable_4500[4] = {0x04, 0x05, 0x00, 0x00};
+UINT8 aScanCodeLengthTable_4545[4] = {0x04, 0x05, 0x04, 0x05};
+UINT8 aScanCodeLengthTable_6800[4] = {0x06, 0x08, 0x00, 0x00};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_WaitForInputBufferToBeFree
+//
+// Description: This routine checks the input buffer free bit and waits till
+// it is set by the keyboard controller
+//
+// Input: Nothing
+//
+// Output: USB_SUCCESS - If Input buffer is Empty
+// USB_ERROR - If Input buffer is Full
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBC_WaitForInputBufferToBeFree ()
+{
+ UINT8 bCount = 16,
+ bStatus;
+ UINT16 wCount = 0xFFFF;
+ do {
+ bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT1);
+ while(bStatus) {
+ if(wCount == 0)
+ break;
+ bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT1);
+ --wCount;
+ }
+ --bCount;
+ } while (bCount && bStatus);
+
+ if (!bStatus) {
+ return USB_SUCCESS;
+ } else {
+ return USB_ERROR;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_WaitForOutputBufferToBeFilled
+//
+// Description: This routine checks the output buffer full bit and waits till
+// it is set by the keyboard controller
+//
+// Input: Nothing
+//
+// Output: USB_SUCCESS - If OutPut buffer is Full
+// USB_ERROR - If Output buffer Empty
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBC_WaitForOutputBufferToBeFilled ()
+{
+ UINT8 bCount = 16,
+ bStatus;
+ UINT16 wCount = 0xffff;
+ do {
+ bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT0);
+ while (!bStatus) {
+ if(wCount == 0) break;
+ bStatus = (UINT8)(ByteReadIO(KBC_STATUS_REG) & BIT0);
+ wCount--;
+ }
+ bCount--;
+ } while (bCount && (!bStatus));
+
+ if (bStatus) {
+ return USB_SUCCESS;
+ } else {
+ return USB_ERROR;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_ReadDataByte
+//
+// Description: This routine till the keyboard controller sends a data byte
+//
+// Input: Nothing
+//
+// Output: Status - USB_SUCCESS
+// - USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBC_ReadDataByte (
+ IN UINT8 *Data )
+{
+ UINT8 Status;
+
+ Status = KBC_WaitForOutputBufferToBeFilled();
+
+ if (Status == USB_SUCCESS) {
+ *Data = ByteReadIO(KBC_DATA_REG);
+ }
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_WriteCommandByte
+//
+// Description: This routine sends the command byte to the keyboard
+// controller
+//
+// Input: IN UNIT8 bCmd - Command byte
+//
+// Output: Status - USB_SUCCESS
+// - USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBC_WriteCommandByte (
+ IN UINT8 bCmd )
+{
+ UINT8 Status;
+
+ Status = KBC_WaitForInputBufferToBeFree();
+
+ if (Status == USB_SUCCESS) {
+ ByteWriteIO(KBC_COMMAND_REG, bCmd);
+ }
+
+ Status = KBC_WaitForInputBufferToBeFree();
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_WriteSubCommandByte
+//
+// Description: This routine sends the sub-command byte to the keyboard
+// controller
+//
+// Input: bCmd Sub-command byte
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+KBC_WriteSubCommandByte (UINT8 bCmd)
+{
+ ByteWriteIO(KBC_SUBCOMMAND_REG, bCmd);
+ KBC_WaitForInputBufferToBeFree();
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_ReadKeyboardControllerData
+//
+// Description: This routine sends a command and receives the response byte
+// for that command
+//
+// Input: IN UINT8 bCmd - Command to be sent
+// In UINT8 *Data - Data to be Read
+//
+// Output: Status - USB_SUCCESS
+// - USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBC_ReadKeyboardControllerData (
+ IN UINT8 bCmd,
+ IN UINT8 *Data )
+{
+ UINT8 Status;
+
+ Status = KBC_WaitForInputBufferToBeFree(); // Wait for input buffer to be free
+
+ if (Status == USB_SUCCESS) {
+ Status = KBC_WriteCommandByte(bCmd); // Send the command
+ if (Status == USB_SUCCESS) {
+ Status = KBC_ReadDataByte(Data); // Read the data
+ }
+ }
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: KBC_WriteKeyboardControllerData
+//
+// Description: This routine writes a data byte to the keyboard controller
+// by first sending a command byte first
+//
+// Input: IN UINT8 bCmd - Command to be sent
+// IN UINT8 bData - Data to be sent
+//
+// Output: Status - USB_SUCCESS
+// USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+KBC_WriteKeyboardControllerData (
+ IN UINT8 bCmd,
+ IN UINT8 bData )
+{
+ UINT8 Status;
+
+ Status = KBC_WaitForInputBufferToBeFree(); // Wait for input buffer to be free
+
+ if (Status == USB_SUCCESS) {
+ Status = KBC_WriteCommandByte(bCmd); // Send the command
+ if (Status == USB_SUCCESS) {
+ ByteWriteIO(KBC_DATA_REG, bData); // Write the data
+ }
+ }
+
+ Status = KBC_WaitForInputBufferToBeFree(); // Wait for input buffer to be free
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SYSKBC_UpdateLEDState
+//
+// Description: This routine updates LEDs on Legacy keyboard
+//
+// Input: LED state data
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SYSKBC_UpdateLEDState (
+ EFI_EMUL6064KBDINPUT_PROTOCOL* pThis,
+ UINT8 bData
+)
+{
+/*
+ UINT8 bCmd,
+ bKBData = 0,
+ bSave;
+
+ //
+ // Wait for input buffer to be free
+ //
+ KBC_WaitForInputBufferToBeFree();
+ KBC_WriteCommandByte(USB_SEND_COMMAND_TO_KBC);
+ bSave = ByteReadIO(KBC_STATUS_REG);
+
+ //
+ // Data is pending. Read it in AL
+ //
+ if(bSave & BIT0)
+ {
+ bKBData = ByteReadIO(KBC_DATA_REG);
+ }
+ KBC_WriteCommandByte(0xAE);
+ KBC_WriteSubCommandByte(0xED);
+ KBC_ReadDataByte();
+ KBC_WriteSubCommandByte(bData);
+ KBC_ReadDataByte();
+
+ if((bSave & BIT0) == 0)
+ {
+ return EFI_SUCCESS;
+ }
+ bCmd = 0xD2;
+ if(bSave & BIT5)
+ {
+ bCmd = 0xD3;
+ }
+ KBC_WriteKeyboardControllerData(bCmd, bKBData);
+*/
+ return EFI_SUCCESS;
+}
+
+void
+SYSKBC_GetAndStoreCCB()
+{
+ UINT8 bStatus,
+ bCmd,
+ bData = 0;
+ UINT8 Temp;
+ UINT8 Status;
+
+
+ //
+ //If Emulation Active disable the SMI Generation
+ //
+ if(gEmulationTrap)
+ gEmulationTrap->TrapDisable(gEmulationTrap);
+
+ bStatus = ByteReadIO(KBC_STATUS_REG);
+ if(bStatus & BIT0)
+ {
+ bData = ByteReadIO(KBC_DATA_REG);
+ }
+
+ Status = KBC_ReadKeyboardControllerData(0x20, &Temp);
+ if (Status == USB_SUCCESS) {
+ gUsbData->bCCB = Temp;
+ }
+
+ if(bStatus & BIT0)
+ {
+ bCmd = 0xD2;
+ if(bStatus & BIT5)
+ {
+ bCmd = 0xD3;
+ }
+ KBC_WriteKeyboardControllerData(bCmd, bData);
+ }
+ //
+ //If Emulation Active Enable the SMI Generation
+ //
+ if(gEmulationTrap)
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMSUpdateMouseInterface
+//
+// Description: This routine is called to enable or disable the mouse
+// interface
+//
+// Input: None
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+/*
+void USBMSUpdateMouseInterface()
+{
+ UINT8 bCmd = 0xA8; // Enable mouse interface
+
+ if (!(gUsbData->bMouseStatusFlag & MOUSE_DATA_READY_BIT_MASK))
+ {
+ if(gUsbData->fpMouseInputBufferHeadPtr !=
+ gUsbData->fpMouseInputBufferTailPtr)
+ {
+ bCmd = 0xA7; // Disable mouse interface
+ }
+ }
+ KBC_WriteCommandByte(bCmd); // Send command to KBC
+
+}
+*/
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBMSSendMouseData
+//
+// Description: This routine is called to send the mouse data to the KB
+// controller
+//
+// Input: Nothing
+//
+// Output: 0xFF data processed
+// 0 data not processed
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 USBMSSendMouseData()
+{
+ UINT16 ebdaSeg = *(UINT16*)0x40E;
+ UINT8 bData;
+ UINT8 *ebda = (UINT8*)((UINTN)ebdaSeg<<4);
+ UINT8 packageSize = ebda[0x27] & 7;
+ UINT8 index=0;
+/*
+ if (gUsbData->bMouseStatusFlag & MOUSE_DATA_READY_BIT_MASK) {
+ if (gUsbData->bCCB & 0x20)
+ {
+ gUsbData->fpMouseInputBufferHeadPtr = &gUsbData->aMouseInputBuffer[0];
+ gUsbData->fpMouseInputBufferTailPtr = &gUsbData->aMouseInputBuffer[0];
+ return 0;
+ } else {
+ ebda[0x26] &= ~7;
+ KBC_WriteCommandByte(0xA7); // Disable mouse interface
+ }
+ }
+*/
+ if (gUsbData->fpMouseInputBufferHeadPtr == gUsbData->fpMouseInputBufferTailPtr) {
+ return 0;
+ }
+
+ if ((gUsbData->bCCB & CCB_MOUSE_DISABLED) ||
+ !(gUsbData->bCCB & CCB_MOUSE_INTRPT)) {
+ gUsbData->fpMouseInputBufferHeadPtr = &gUsbData->aMouseInputBuffer[0];
+ gUsbData->fpMouseInputBufferTailPtr = &gUsbData->aMouseInputBuffer[0];
+ return 0;
+ }
+
+ ebda[0x26] &= ~7;
+
+#if USB_MOUSE_UPDATE_EBDA_DATA
+ for (; index<packageSize; index++) {
+ ebda[0x28+index] = USBMouse_GetFromMouseBuffer();
+ ebda[0x26]++;
+ }
+#endif
+ bData = USBMouse_GetFromMouseBuffer();
+ KBC_WriteKeyboardControllerData(0xD3, bData); // Send the last byte of data
+
+ //
+ // Flag indicates data from USB mouse
+ //
+ //gUsbData->bMouseStatusFlag |= MOUSE_DATA_FROM_USB_BIT_MASK;
+
+ //
+ // Indicate that first byte already sent
+ //
+ //gUsbData->bMouseStatusFlag &= ~(MOUSE_DATA_READY_BIT_MASK);
+
+ //USBMSUpdateMouseInterface(); // Enable/disable mouse interface
+
+ return 0xFF;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMouse_SendToMouseBuffer
+//
+// Description: This routine puts a byte into the mouse input buffer.
+// Mouse input buffer pointers are also updated
+//
+// Input: bData - Byte to be put in the mouse input buffer
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+void
+USBMouse_SendToMouseBuffer(UINT8 bData)
+{
+ *gUsbData->fpMouseInputBufferHeadPtr = bData; // Put the byte in the buffer
+ gUsbData->fpMouseInputBufferHeadPtr++; // Advance the buffer pointer
+
+ //
+ // Check whether the buffer end is reached, if buffer end reached
+ // then position the buffer pointer to the start
+ //
+ if (gUsbData->fpMouseInputBufferHeadPtr ==
+ (gUsbData->aMouseInputBuffer + sizeof(gUsbData->aMouseInputBuffer)))
+ {
+ gUsbData->fpMouseInputBufferHeadPtr = gUsbData->aMouseInputBuffer;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMouse_GetFromMouseBuffer
+//
+// Description: This routine retrieves a byte from the mouse input buffer.
+// Mouse input buffer pointers are also updated
+//
+// Input: None
+//
+// Output: bData - Byte to be taken from the mouse input buffer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 USBMouse_GetFromMouseBuffer ()
+{
+ UINT8 bData = *gUsbData->fpMouseInputBufferTailPtr;
+ *gUsbData->fpMouseInputBufferTailPtr = 0;
+ gUsbData->fpMouseInputBufferTailPtr++;
+
+ //
+ // Check whether the buffer end is reached, if buffer end reached
+ // then wrap around to the start
+ //
+ if (gUsbData->fpMouseInputBufferTailPtr ==
+ (&gUsbData->aMouseInputBuffer[0] + sizeof(gUsbData->aMouseInputBuffer)))
+ {
+ gUsbData->fpMouseInputBufferTailPtr = &gUsbData->aMouseInputBuffer[0];
+ }
+ return bData;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SYSKBC_SendKBCData
+//
+// Description: This routine is invoked periodically (every 8msec) to send
+// USB keyboard and mouse data to the keyboard controller
+// or to the keyboard controller emulation code
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SYSKBC_SendKBCData()
+{
+ UINT8 bCmd = 0,
+ bTemp1 = 0,
+ bTemp = 0,
+ bFlag = 1;
+ UINT16 wTemp;
+// UINT16 ebdaSeg = *(UINT16*)0x40E;
+// UINT8 *ebda = (UINT8*)((UINTN)ebdaSeg<<4);
+// UINT8 mouse_flag3;
+ UINT8 Status;
+ UINT8 Temp;
+
+ //Is KBC access allowed?
+ if(IsKbcAccessBlocked) {
+ return EFI_NOT_READY;
+ }
+// USBKBC_CheckAutoRepeat();
+
+ //
+ //If Emulation Active disable the SMI Generation
+ //
+ if(gEmulationTrap){
+ if (!gEmulationTrap->TrapDisable(gEmulationTrap)) {
+ // Data is still pending. So don't push data.
+ goto enableRepeat_Exit;
+ }
+ }
+
+ //
+ // Check whether BIOS is processing IRQ1 or IRQ12
+ //
+ ByteWriteIO(0x20, 0xB);
+ if (ByteReadIO(0x20) & 2) {
+ goto enableRepeat_Exit;
+ }
+
+ ByteWriteIO(0xA0, 0xB);
+ if (ByteReadIO(0xA0) & 0x10) {
+ goto enableRepeat_Exit;
+ }
+
+ if (ByteReadIO(KBC_STATUS_REG) & BIT0){
+ goto enableRepeat_Exit;
+ }
+
+ for(;;) {
+ //
+ // Check the data transmit order
+ //
+ wTemp = (UINT16)(gUsbData->wUSBKBC_StatusFlag &
+ KBC_DATA_TX_ORDER_BIT_MASK);
+ if(wTemp == KBC_DATA_TX_ORDER_KB_FIRST) {
+ bFlag = 0;
+ bCmd = 0xD2; // Send keyboard data
+ //
+ // Check for keyboard data and then for mouse data
+ //
+ if(gUsbData->fpKBCCharacterBufferHead !=
+ gUsbData->fpKBCCharacterBufferTail)
+ break;
+ //
+ // Check for mouse data
+ //
+ #if USB_DEV_MOUSE
+ bCmd = 0xD3;
+ if(gUsbData->fpMouseInputBufferHeadPtr !=
+ gUsbData->fpMouseInputBufferTailPtr)
+ {
+ break;
+ }
+ #endif
+ bFlag = 1;
+ } else {
+ bFlag = 0;
+ #if USB_DEV_MOUSE
+ bCmd = 0xD3;
+ if(gUsbData->fpMouseInputBufferHeadPtr !=
+ gUsbData->fpMouseInputBufferTailPtr)
+ {
+ //
+ // Check for keyboard data and then for mouse data
+ //
+ break;
+ }
+ #endif
+ //
+ // Check for keyboard data
+ //
+ bCmd = 0xD2;
+ if(gUsbData->fpKBCCharacterBufferHead !=
+ gUsbData->fpKBCCharacterBufferTail)
+ break;
+ bFlag = 1;
+ }
+ break;
+ }
+
+ if(bFlag) {
+ USB_DEBUG (DEBUG_LEVEL_8, "USBKBC_SendKBCData: Scan Code Buffer Empty \n");
+ //
+ // Check whether the scan code buffer is empty
+ //
+ if(gUsbData->fpKBCScanCodeBufferPtr != gUsbData->aKBCScanCodeBufferStart)
+ {
+ goto enableRepeat_Exit;
+ }
+ //
+ // Get pointer to the HC driver
+ // Scan code buffer is empty. Stop the key repeat by stopping repeat TD
+ //
+ USB_DEBUG (DEBUG_LEVEL_8, "HCDDisableKeyRepeat \n");
+ USBKeyRepeat(NULL, 1); // Disable Key repeat
+
+ if(gEmulationTrap) {
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ }
+ return EFI_SUCCESS;
+ }
+
+ for (;;) {
+ Status = KBC_WaitForInputBufferToBeFree();
+ if (Status == USB_SUCCESS) {
+ ByteWriteIO(KBC_COMMAND_REG, USB_SEND_COMMAND_TO_KBC);
+ } else {
+ goto enableRepeat_Exit;
+ }
+ //
+ // Check the return status
+ //
+ do {
+ bTemp1 = ByteReadIO(KBC_STATUS_REG);
+ if(bTemp1 & BIT0) {
+ bFlag = 3 ;
+ break;
+ }
+ } while (bTemp1 & BIT1);
+ USB_DEBUG (DEBUG_LEVEL_8, "USBKBC_SendKBCData: bFlag %x\n",bFlag);
+ if (bFlag == 3) break;
+ //
+ // Update the data transmit order
+ //
+ gUsbData->wUSBKBC_StatusFlag =
+ (UINT16)((gUsbData->wUSBKBC_StatusFlag) +
+ (KBC_DATA_TX_ORDER_INC_VALUE));
+ wTemp = (UINT16)(gUsbData->wUSBKBC_StatusFlag &
+ KBC_DATA_TX_ORDER_BIT_MASK);
+ if((wTemp & KBC_DATA_TX_ORDER_BIT_MASK) == 0) {
+ gUsbData->wUSBKBC_StatusFlag &=
+ ~((UINT16)KBC_DATA_TX_ORDER_BIT_MASK);
+ }
+
+ //
+ // Get the CCB
+ //
+ Status = KBC_WriteCommandByte(0x20); // Send command to KBC
+ if (Status == USB_SUCCESS) {
+ Status = KBC_ReadDataByte(&Temp); // Get data from KBC
+ if (EFI_ERROR(Status)) {
+ goto enableRepeat_Exit;
+ }
+ gUsbData->bCCB = Temp;
+ } else {
+ goto enableRepeat_Exit ;
+ }
+
+ //
+ // Check for mouse data
+ //
+ if((bCmd & 1) == 0) {
+ //
+ // Check whether keyboard is disabled
+ //
+ if((gUsbData->bCCB & CCB_KEYBOARD_DISABLED) == 0) {
+ //
+ // Check whether the current mode is IRQ
+ // Check whether password is enabled
+ //
+ if((gUsbData->wUSBKBC_StatusFlag &
+ KBC_PASSWORD_FLAG_BIT_MASK) == 0)
+ bTemp = USBKBC_GetFromCharacterBuffer();
+
+ if (bTemp == 0xff) {
+ goto enableRepeat_Exit;
+ }
+ KBC_WriteKeyboardControllerData(bCmd , bTemp);
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ if (gEmulationTrap) {
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ }
+ return EFI_SUCCESS;
+ }
+ bTemp = 0xFF;
+ } else {
+ #if USB_DEV_MOUSE
+ if (USBMSSendMouseData()) {
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+
+/*
+ //(EIP57745+)>
+ //
+ // Check the version of CSM16, support is available for ver 7.64 or later
+ //
+ {
+ UINT8 MjCsmVer = *(UINT8*)0xF0018;
+ UINT8 MnCsmVer = *(UINT8*)0xF0019;
+
+ if (MjCsmVer > 7 || MnCsmVer > 0x63)
+ {
+ mouse_flag3 = ebda[0x30] & 1; //check mouse driver
+ if(mouse_flag3) {
+ if(USBMSSendMouseData()) {
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+ } else {
+ gUsbData->fpMouseInputBufferHeadPtr = &gUsbData->aMouseInputBuffer[0];
+ gUsbData->fpMouseInputBufferTailPtr = &gUsbData->aMouseInputBuffer[0];
+ }
+ }
+ else
+ {
+ if(USBMSSendMouseData()) {
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+ }
+ }
+ //<(EIP57745+)
+*/
+ if(gEmulationTrap)
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ return EFI_SUCCESS;
+ #else
+ bTemp = 0xFF;
+ #endif
+ }
+ break;
+ }
+
+ if(bFlag == 3) {
+ bTemp = 0xAE;
+ if(bTemp1 & 0x20) { // 0/1 = KB/Mouse data
+ #if USB_DEV_MOUSE
+ //
+ // Enable/disable mouse depending on the data
+ //
+ //USBMSUpdateMouseInterface();
+ #endif
+ goto enableRepeat_Exit;
+ }
+ }
+ KBC_WriteCommandByte(bTemp);
+
+enableRepeat_Exit:
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ if (gEmulationTrap) {
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ }
+ return EFI_NOT_READY;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SYSKBC_KbdInput_Send
+//
+// Description: This routine sends the Keyboard Data to Controller
+//
+// Input:
+// IN EFI_EMUL6064KBDINPUT_PROTOCOL* This,
+// IN UINT8* Data,
+// IN UINT32 Count
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SYSKBC_KbdInput_Send(
+ IN EFI_EMUL6064KBDINPUT_PROTOCOL* This,
+ IN UINT8* Data,
+ IN UINT32 Count
+)
+{
+ EFI_STATUS Status;
+
+ if (Count == 0) {
+ return EFI_SUCCESS;
+ }
+
+ do {
+ Status=SYSKBC_SendKBCData();
+ Count--;
+ } while (Count != 0 && Status == EFI_SUCCESS);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SYSKBC_MouseInput_Send
+//
+// Description: This routine sends the Mouse Data to Controller
+//
+// Input:
+// IN EFI_EMUL6064MSINPUT_PROTOCOL* This,
+// IN PS2MouseData* Data
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SYSKBC_MouseInput_Send(
+ IN EFI_EMUL6064MSINPUT_PROTOCOL* This,
+ IN PS2MouseData* Data
+)
+{
+ return SYSKBC_SendKBCData();
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SendMouseData
+//
+// Description: This routine sends the Mouse Data to Local Mouse Buffer
+//
+// Input:
+// IN PS2MouseData* Data
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SendMouseData(
+ IN PS2MouseData* Data
+)
+{
+ USBMouse_SendToMouseBuffer(Data->flags); // Send status byte
+ USBMouse_SendToMouseBuffer(Data->x); // Send X-axis information
+ USBMouse_SendToMouseBuffer(Data->y); // Send Y-axis information
+
+ //
+ // Check for 4-byte mouse data and send the 4th dummy data if needed
+ //
+ //if(gUsbData->bMouseStatusFlag & MOUSE_4BYTE_DATA_BIT_MASK)
+ //{
+ // USBMouse_SendToMouseBuffer(0);
+ //}
+ //
+ // Set flag to indicate mouse data ready
+ //
+ //gUsbData->bMouseStatusFlag |= MOUSE_DATA_READY_BIT_MASK;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SYSKBC_GetTranslation
+//
+// Description: This routine Get the KBC SCAN code transalation value
+//
+// Input:
+// IN EFI_EMUL6064KBDINPUT_PROTOCOL* This,
+// OUT KBC_KBDTRANSLATION* OutTrans
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+SYSKBC_GetTranslation(
+ IN EFI_EMUL6064KBDINPUT_PROTOCOL* This,
+ OUT KBC_KBDTRANSLATION* OutTrans
+)
+{
+ static BOOLEAN IsCcbLoaded = FALSE;
+
+ if (!IsCcbLoaded) {
+ IsCcbLoaded = TRUE;
+ SYSKBC_GetAndStoreCCB();
+ }
+
+ *OutTrans = (gUsbData->bCCB & CCB_TRANSLATE_SCAN_CODE_BIT_MASK) != 0?
+ KBC_KBDTRANS_PCXT : KBC_KBDTRANS_AT;
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_Scanner
+//
+// Description: This routine converts the USB keyboard input data into
+// IBM PC format scan code
+//
+// Input: fpDevInfo Pointer to the device info. structure
+// fpBuffer Pointer to the 8byte USB keyboard data
+//
+// Output: Nothing
+//
+// Notes: The format of the 8byte USB keyboard data is as follows:
+//----------------------------------------------------------------------------
+// Byte Description
+//----------------------------------------------------------------------------
+// Byte 0 Contains modifier key bits like SHIFT, CTRL, ALT etc
+// Byte 1 Reserved
+// Byte 2 - 7 Keycode (1-6) of the keys pressed
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_Scanner (
+ DEV_INFO *fpDevInfo,
+ UINT8 *fpBuffer
+)
+{
+ UINT8 bKeyCode;
+ UINT8 bValue;
+ UINT8 bTemp1;
+
+ UINT16 wWorkOffset;
+ UINT16 wCount;
+ UINT16 wTemp;
+
+ UINT8 *fptKBInputBuffer;
+ UINT8 *fptBuffer;
+ UINT8 *fPointer;
+
+ fptKBInputBuffer = gUsbData->aKBInputBuffer ;
+ fptBuffer = (UINT8*)fpBuffer;
+
+ //
+ // Convert the device address (1,2,3 .. 8) into
+ // device ID bit pattern (001h, 002h, 004h .. 080h)
+ //
+ gUsbData->bCurrentDeviceID = (UINT8)(1 << ((fpDevInfo->bDeviceAddress) -1));
+
+ bTemp1 = 0xE0;
+ wCount = 0x0;
+ bValue = (UINT8)(*fptBuffer);
+
+ do {
+ if(bValue & 0x01) {
+ *fptKBInputBuffer = bTemp1; // Modifier key pressed. Send appropriate byte to the input buffer
+ ++fptKBInputBuffer;
+ }
+ bValue >>= 1;
+ ++bTemp1;
+ } while (bTemp1 <= 0xE7);
+
+ //
+ // Discard the reserved byte from the USB KB input data stream
+ //
+ ++fptBuffer;
+ ++fptBuffer;
+
+ //
+ // Process the remaining 6 input bytes
+ //
+ wCount = 6;
+
+ do {
+ if(*fptBuffer) {
+ //
+ // Check whether the input is overrun. Overrun condition occurs if more than
+ // 6 keys are pressed at a same time. In that case, USB KB sends 01h in all
+ // its 6 key code bytes
+ //
+ if(*fptBuffer == 1) { // Keyboard error roll over (overrun) ?
+// USB_DEBUG (DEBUG_LEVEL_5, "USBKB_Scanner: Overrun condition occur\n");
+ //
+ // Check the space availability for the overrun code in the
+ // character buffer
+ // Overrun code needs 1 byte (0+1)
+ //
+ bTemp1 = USBKBC_CheckCharacterBufferFull(0);
+ if(bTemp1 == 0) {
+ return;
+ }
+ bTemp1 = 0xFF; // Scan code set 2 & 3 overrun code
+#if USB_6064_TRAP
+//
+// The following routine returns overrun code depending upon the scan code
+// set chosen. This facility is available only when 60/64h port trapping
+// is enabled. Otherwise the scan code set is locked to set 2.
+//
+ bTemp1 = USBTrap_GetOverrunCode();
+#endif
+ USBKBC_SendToCharacterBuffer(bTemp1);
+ //
+ // Invalidate the last key code processed data
+ //
+// gUsbData->bLastUSBKeyCode = 0x00; //(EIP102150-)
+ return;
+ }
+ else {
+ *fptKBInputBuffer = *fptBuffer;
+ ++fptKBInputBuffer;
+ ++fptBuffer;
+ }
+ }
+ else {
+ ++fptBuffer;
+ }
+ --wCount;
+ } while (wCount);
+
+ *fptKBInputBuffer = 0; // Null terminate the input buffer
+ ++fptKBInputBuffer;
+
+ //
+ // Check for break code generation condition
+ //
+ wCount = (UINT16)(fptKBInputBuffer - gUsbData->aKBInputBuffer);
+ fptKBInputBuffer = gUsbData->aKBInputBuffer;
+ bValue = 0;
+ //
+ // wCount = Length of the buffer
+ //
+ while(wCount) {
+ if (*fptKBInputBuffer)
+ break;
+ ++fptKBInputBuffer;
+ --wCount;
+ }
+
+ if(!wCount) {
+ //
+ // No key pressed. Set flags to generate break code
+ //
+ gUsbData->bBreakCodeDeviceID |= gUsbData->bCurrentDeviceID;
+ }
+
+ fptKBInputBuffer = gUsbData->aKBInputBuffer;
+ //(EIP60380-)>
+/*
+ //
+ // Check and load typematic rate setting
+ //
+ wTemp = (UINT16)(gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_DELAY_BIT_MASK);
+ wTemp >>= KBC_TYPE_DELAY_BIT_SHIFT;
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[wTemp];
+ gUsbData->wRepeatCounter = 0;
+*/
+ //<(EIP60380-)
+//
+// Save the keycode in the local variable
+//
+UKS_KeyCodeGenerateLoop:
+
+ bKeyCode = *fptKBInputBuffer;
+ ++fptKBInputBuffer;
+
+ if(bKeyCode) { // Check end of the list
+ //
+ // Get scan code buffer size
+ //
+ wCount = (UINT16)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart);
+ bTemp1 = 0;
+
+ while(wCount) {
+ if(bKeyCode == gUsbData->aKBCScanCodeBufferStart[bTemp1]) {
+ gUsbData->aKBCDeviceIDBufferStart[bTemp1] |=
+ gUsbData->bCurrentDeviceID;
+ goto UKS_KeyCodeGenerateLoop;
+ }
+ ++bTemp1;
+ --wCount;
+ };
+ if(bTemp1 >= sizeof (gUsbData->aKBCScanCodeBufferStart))
+ goto UKS_CheckBreakCodeGen;
+ //
+ // The key code is not in the buffer and also the buffer is not full. So
+ // generate the make code for the newly pressed key.
+ //
+ USBKB_GenerateScanCode(USB_GEN_MAKE_CODE, bKeyCode, 0);
+// gUsbData->bLastUSBKeyCode = bKeyCode; //(EIP102150-)
+ gUsbData->aKBCScanCodeBufferStart[bTemp1] = bKeyCode;
+ //
+ // Store the device ID
+ //
+ gUsbData->aKBCDeviceIDBufferStart[bTemp1] = gUsbData->bCurrentDeviceID;
+ //
+ // Store the shift key status
+ //
+ gUsbData->aKBCShiftKeyStatusBufferStart[bTemp1] = gUsbData->bUSBKBShiftKeyStatus;
+ ++(gUsbData->fpKBCScanCodeBufferPtr); // Update pointer index
+ //(EIP60380+)>
+ //
+ // Check and load typematic rate setting
+ //
+ wTemp = (UINT16)(gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_DELAY_BIT_MASK);
+ wTemp >>= KBC_TYPE_DELAY_BIT_SHIFT;
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[wTemp];
+ gUsbData->wRepeatCounter = 0;
+ //<(EIP60380+)
+ goto UKS_KeyCodeGenerateLoop;
+ }
+UKS_CheckBreakCodeGen:
+ --fptKBInputBuffer;
+
+ fPointer = (UINT8*)(gUsbData->aKBCScanCodeBufferStart);
+ wTemp = (UINT16)(fptKBInputBuffer - gUsbData->aKBInputBuffer);
+
+UKS_ProcessNextCharacter:
+ if(fPointer >= gUsbData->fpKBCScanCodeBufferPtr)
+ goto UKS_BreakCodeGenCompleted;
+
+ bKeyCode = *fPointer;
+ ++fPointer;
+
+ fptKBInputBuffer = gUsbData->aKBInputBuffer;
+ wCount = wTemp;
+ while(wCount) {
+ if(bKeyCode == *fptKBInputBuffer)
+ goto UKS_ProcessNextCharacter;
+
+ ++fptKBInputBuffer;
+ --wCount;
+ }
+
+ --fPointer;
+ wWorkOffset = (UINT16)(fPointer - gUsbData->aKBCScanCodeBufferStart);
+
+ gUsbData->aKBCDeviceIDBufferStart[wWorkOffset] &= ~((UINT8)(gUsbData->bCurrentDeviceID));
+ if(gUsbData->aKBCDeviceIDBufferStart[wWorkOffset] ) {
+ ++fPointer;
+ goto UKS_ProcessNextCharacter;
+ }
+ bValue = gUsbData->aKBCShiftKeyStatusBufferStart[wWorkOffset];
+ gUsbData->aKBCShiftKeyStatusBufferStart[wWorkOffset] =
+ gUsbData->bUSBKBShiftKeyStatus;
+ gUsbData->bUSBKBShiftKeyStatus = bValue;
+ USBKB_GenerateScanCode(USB_GEN_BREAK_CODE,(UINT8)*fPointer, wWorkOffset);
+ //
+ // Restore shift key status
+ //
+ bValue = gUsbData->aKBCShiftKeyStatusBufferStart[wWorkOffset];
+ gUsbData->aKBCShiftKeyStatusBufferStart[wWorkOffset] = gUsbData->bUSBKBShiftKeyStatus;
+ gUsbData->bUSBKBShiftKeyStatus = bValue;
+ bValue = *fPointer;
+ USBKB_DiscardCharacter(&gUsbData->aKBCShiftKeyStatusBufferStart[wWorkOffset]);
+
+ --(gUsbData->fpKBCScanCodeBufferPtr);
+ //
+ // Stop auto repeat
+ //
+// gUsbData->bLastUSBKeyCode = 0; //(EIP102150-)
+ goto UKS_ProcessNextCharacter;
+UKS_BreakCodeGenCompleted:
+ gUsbData->bBreakCodeDeviceID &= ~((UINT8)(gUsbData->bCurrentDeviceID));
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_Scanner: End\n");
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_GenerateScanCode
+//
+// Description: This routine generates the make/break code for th key
+// pressed depending on the make/break flag
+//
+// Input: bCodeGenFlag Flag indicating whether it is a make or
+// break code sequence
+// bKeyCode USB key code for the key pressed
+// wWorkOffset Offset into the buffers which has the
+// code we are processing
+//
+// Output: 0xFFFF -on success , 0 on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_GenerateScanCode (
+ UINT8 bCodeGenFlag,
+ UINT8 bKeyCode,
+ UINT16 wWorkOffset)
+{
+ UINT8 bMakeCode,
+ bTemp = 0,
+ bValue;
+ UINT16 wScanCode,
+ wTemp;
+ UINT8 *fPointer;
+ UINT8 ScanCodeCount; //(EIP102150+)
+ UINT16 i=0; //(EIP102150+)
+
+USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: bKeyCode %x:\n",bKeyCode);
+
+ //
+ // Set the flag to indicate that make code is generated
+ //
+ gUsbData->wUSBKBC_StatusFlag &= ~((UINT16) KBC_MK_BRK_CODE_BIT_MASK);
+
+ //
+ // Set the approprate flag indicating make or break code sequence
+ //
+ if (bCodeGenFlag != USB_GEN_MAKE_CODE)
+ {
+ //
+ // Set the flag to indicate that break code is generated
+ //
+ gUsbData->wUSBKBC_StatusFlag |= KBC_MK_BRK_CODE_BIT_MASK;
+ }
+
+ //
+ // Save the current USB key code
+ //
+ gUsbData->bCurrentUSBKeyCode = bKeyCode;
+
+ //
+ // Convert the USB key code into scan code (Set 2)
+ //
+ bMakeCode = USBKB_ConvertUSBKeyCodeToScanCodeSet2(bKeyCode);
+ USB_DEBUG (DEBUG_LEVEL_8, "USBKB_GenerateScanCode: bMakeCode %x:\n",bMakeCode);
+
+ //
+ // Save the make code in the temporary variable
+ //
+ gUsbData->bSet2ScanCode = bMakeCode;
+ //
+ // Check whether any modifier keys (ALT, CTRL & SHIFT) are pressed
+ //
+ wScanCode = USBKB_CheckModifierKeyPress(bMakeCode);
+ wTemp = (UINT16)(wScanCode >> 8);
+
+ if(wTemp)
+ {
+ //
+ // Check whether it is a make or break code generation
+ //
+ if(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK)
+ {
+ //
+ // Generating the break code, so clear the modifier status.
+ // Check for left/right shift key press
+ //
+ if(!(wTemp & (KB_LSHIFT_KEY_BIT_MASK + KB_RSHIFT_KEY_BIT_MASK)))
+ {
+ fPointer = gUsbData->fpKBCScanCodeBufferPtr ;
+
+ while(fPointer != (gUsbData->aKBCScanCodeBufferStart))
+ {
+ --fPointer; // Decrement scan code buffer pointer
+ bTemp = USBKB_ConvertUSBKeyCodeToScanCodeSet2(*fPointer);
+ if(bTemp == (wScanCode & 0xFF))
+ {
+ break;
+ }
+ }
+ }
+
+ if(bTemp != (wScanCode & 0xFF) ||
+ (wTemp & (KB_LSHIFT_KEY_BIT_MASK + KB_RSHIFT_KEY_BIT_MASK)))
+ {
+ wTemp = (UINT16)(~wTemp);
+ gUsbData->bUSBKBShiftKeyStatus &= wTemp;
+ gUsbData->aKBCShiftKeyStatusBufferStart[wWorkOffset] &= wTemp;
+ }
+ }
+ else
+ {
+ gUsbData->bUSBKBShiftKeyStatus |= wTemp; // Set proper bits
+ }
+ }
+
+#if USB_KBC_EMULATION
+ bScanNum = USBTrap_GetCurrentScanCodeSetNumber();
+ if(bScanNum == 3)
+ {
+ USBTrap_ProcessScanCodeSet3();
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: Return 1.\n");
+ return;
+ }
+#endif
+ //
+ // Check and process pause key
+ //
+ if(gUsbData->bSet2ScanCode == PAUSE_KEY )
+ {
+//
+// It is scan code for pause key. No need to auto repeat pause key and
+// also pause key doesn't have break key. Check the above two conditions
+// and take care of them properly
+//
+ //
+ // Check whether it is to generate make or break code
+ //
+ if(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK)
+ {
+ USB_DEBUG (DEBUG_LEVEL_5, "USBKB_GenerateScanCode: Return 2.\n");
+ return;
+ }
+//
+// It is not a break code check whether it is for auto repeat
+// Compare old key code and the current key code
+//
+ //(EIP102150+)>
+ ScanCodeCount = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart);
+ for (i = 0; i < ScanCodeCount; i++) {
+ if ((gUsbData->aKBCDeviceIDBufferStart[i] & gUsbData->bCurrentDeviceID) &&
+ (gUsbData->bCurrentUSBKeyCode == gUsbData->aKBCScanCodeBufferStart[i])) {
+ return;
+ }
+ }
+ //<(EIP102150+)
+//
+// Pause key can have
+// 4 bytes of make code for scan code set 1, if CTRL key is also pressed
+// 5 bytes of make code for scan code set 2, if CTRL key is also pressed
+// 6 bytes of make code for scan code set 1, if CTRL key is not pressed
+// 8 bytes of make code for scan code set 2, if CTRL key is not pressed
+// 0 bytes if it is a break code for pause key.
+// The above conditions are handled generically using two tables
+// pScanCodeLengthTable_4500 & pScanCodeLengthTable_6800. If CTRL key is
+// pressed then _4500 table will be used or else _6800 table will be used.
+// The logic in the later stage of the code can then choose one entry from
+// this table depending on whether it is make or break code and whether
+// it is for scan code set 1 or 2.
+//
+ fPointer = aScanCodeLengthTable_4500; // CTRL + PAUSE
+ if((gUsbData->bUSBKBShiftKeyStatus &
+ KB_CTRL_KEY_BIT_MASK) == 0)
+ fPointer = aScanCodeLengthTable_6800; // PAUSE
+ }
+ else
+ if(gUsbData->bSet2ScanCode == PRINT_SCREEN )
+ {
+/*---
+ Print screen key can have
+ 1 bytes of make code for scan code set 1, if pressed with ALT key
+ 1 bytes of make code for scan code set 2, if pressed with ALT key
+ 1 bytes of break code for scan code set 1, if pressed with ALT key
+ 2 bytes of break code for scan code set 2, if pressed with ALT key
+ 2 bytes of make code for scan code set 1, if pressed with CTRL+SFT key
+ 2 bytes of make code for scan code set 2, if pressed with CTRL+SFT key
+ 2 bytes of break code for scan code set 1, if pressed with CTRL+SFT key
+ 4 bytes of make code for scan code set 1, if no other key is pressed
+ 4 bytes of make code for scan code set 2, if no other key is pressed
+ 4 bytes of break code for scan code set 1, if no other key is pressed
+ 6 bytes of break code for scan code set 2, if no other key is pressed
+ The above conditions are handled generically using three tables
+ pScanCodeLengthTable_1112, pScanCodeLengthTable_2223
+ & pScanCodeLengthTable_4446. If ALT key is pressed then _1112 table
+ will be used. If CTRL key is pressed then _2223 table will be used or
+ else _4446 table will be used.
+ The logic in the later stage of the code can then choose one entry from
+ this table depending on whether it is make or break code and whether
+ it is for scan code set 1 or 2.
+---*/
+ if(gUsbData->bUSBKBShiftKeyStatus &
+ KB_ALT_KEY_BIT_MASK)
+ fPointer = aScanCodeLengthTable_1112;
+ else if(gUsbData->bUSBKBShiftKeyStatus &
+ ( KB_CTRL_KEY_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK))
+ fPointer = aScanCodeLengthTable_2223;
+ else
+ fPointer = aScanCodeLengthTable_4446;
+
+ /* fPointer = aScanCodeLengthTable_1112;
+ if((gUsbData->bUSBKBShiftKeyStatus & KB_ALT_KEY_BIT_MASK) == 0)
+ {
+ fPointer = aScanCodeLengthTable_2223;
+ if((gUsbData->bUSBKBShiftKeyStatus & (KB_NUM_LOCK_BIT_MASK + KB_LSHIFT_KEY_BIT_MASK + KB_RSHIFT_KEY_BIT_MASK)) == 0)
+ {
+ fPointer = aScanCodeLengthTable_4446;
+ bTemp = (UINT8)USBKB_CheckForNumericKeyPadKey(gUsbData->bSet2ScanCode);
+ if(bTemp)
+ {
+// goto UKGSC_NotANumericKeyPadKey;
+ }
+ fPointer = aScanCodeLengthTable_2223;
+ if(gUsbData->bUSBKBShiftKeyStatus & (KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK))
+ {
+ fPointer = aScanCodeLengthTable_4446;
+ if((gUsbData->bUSBKBShiftKeyStatus & KB_NUM_LOCK_BIT_MASK) == 0)
+ {
+ if((gUsbData->bUSBKBShiftKeyStatus & KB_NUM_LOCK_BIT_MASK) == 0)
+ {
+ fPointer = aScanCodeLengthTable_4545;
+ }
+ }
+ }
+ }
+ } */
+ }
+ else
+ {
+ wScanCode = USBKB_CheckForNumericKeyPadKey(gUsbData->bSet2ScanCode);
+ wTemp = (UINT16)(wScanCode & 0xFF);
+ if(!wTemp)
+ {
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: Extended Key Pressed\n");
+
+/*---
+ It is a numeric key pad key. It can have
+ if no key is pressed or (NUMLOCK is ENABLED and SHIFT key is pressed)
+ 2 bytes of make code for scan code set 1
+ 2 bytes of make code for scan code set 2
+ 2 bytes of break code for scan code set 1
+ 3 bytes of break code for scan code set 2
+ if NUMLOCK is ENABLED
+ 4 bytes of make code for scan code set 1
+ 4 bytes of make code for scan code set 2
+ 4 bytes of break code for scan code set 1
+ 6 bytes of break code for scan code set 2
+ if pressed with SHIFT key
+ 4 bytes of make code for scan code set 1
+ 5 bytes of make code for scan code set 2
+ 4 bytes of break code for scan code set 1
+ 5 bytes of break code for scan code set 2
+ The above conditions are handled generically using three tables
+ pScanCodeLengthTable_2223, pScanCodeLengthTable_4446
+ & pScanCodeLengthTable_4545. If no other key is pressed then _2223 table
+ will be used. If NUMLOCK is enabled then _4446 table will be used or
+ else _4545 table will be used.
+ The logic in the later stage of the code can then choose one entry from
+ this table depending on whether it is make or break code and whether
+ it is for scan code set 1 or 2.
+---*/
+ //(EIP27889)>
+ if( (!(gUsbData->bUSBKBShiftKeyStatus &
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK))) ||
+ ((gUsbData->bUSBKBShiftKeyStatus &
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK)) ==
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK)) ||
+ ((gUsbData->bUSBKBShiftKeyStatus &
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK)) ==
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK)) )
+ fPointer = aScanCodeLengthTable_2223;
+ //<(EIP27889)
+ else if(gUsbData->bUSBKBShiftKeyStatus &
+ KB_NUM_LOCK_BIT_MASK)
+ {
+ //(EIP102150+)>
+ fPointer = aScanCodeLengthTable_4446;
+ if (!(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK)) {
+ ScanCodeCount = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart);
+ for (i = 0; i < ScanCodeCount; i++) {
+ if ((gUsbData->aKBCDeviceIDBufferStart[i] & gUsbData->bCurrentDeviceID) &&
+ (gUsbData->bCurrentUSBKeyCode == gUsbData->aKBCScanCodeBufferStart[i])) {
+ fPointer = aScanCodeLengthTable_2223;
+ break;
+ }
+ }
+ }
+ //<(EIP102150+)
+ }
+ else
+ fPointer = aScanCodeLengthTable_4545;
+ }
+ else
+ {
+ // UKGSC_NotANumericKeyPadKey
+/*---
+ The extended keys will have
+ 2 bytes of make code for scan code set 1
+ 2 bytes of make code for scan code set 2
+ 2 bytes of break code for scan code set 1
+ 3 bytes of break code for scan code set 2
+---*/
+ wScanCode = USBKB_CheckForExtendedKey(gUsbData->bSet2ScanCode);
+ if(!(wScanCode & 0xff))
+ fPointer = aScanCodeLengthTable_2223;
+ else if(gUsbData->bSet2ScanCode == SLASH_KEY)
+ {
+/*---
+ The slash key will normally have
+ 2 bytes of make code for scan code set 1
+ 2 bytes of make code for scan code set 2
+ 2 bytes of break code for scan code set 1
+ 3 bytes of break code for scan code set 2
+ But if pressed with slash key it has
+ 4 bytes of make code for scan code set 1
+ 5 bytes of make code for scan code set 2
+ 4 bytes of break code for scan code set 1
+ 5 bytes of break code for scan code set 2
+---*/
+ if(!(gUsbData->bUSBKBShiftKeyStatus &
+ (KB_LSHIFT_KEY_BIT_MASK +
+ KB_RSHIFT_KEY_BIT_MASK)))
+ fPointer = aScanCodeLengthTable_2223;
+ else
+ fPointer = aScanCodeLengthTable_4545;
+ }
+ else // UKGSC_NotSlashKey:
+ /*---
+ Regular keys will have
+ 1 bytes of make code for scan code set 1
+ 1 bytes of make code for scan code set 2
+ 1 bytes of break code for scan code set 1
+ 2 bytes of break code for scan code set 2
+ ---*/
+ fPointer = aScanCodeLengthTable_1112;
+ }
+ }
+ //
+ // Find the appropriate scan code length from the table
+ // bOffset = Offset in the table
+ //
+ bValue = 0; // Assume make code for set 1
+
+ //
+ // Check whether to generate make or break code
+ //
+ if(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK)
+ {
+ bValue = 2;
+ }
+ //
+ // Check whether to generate set 1 scan code or set 2
+ //
+ if((gUsbData->bCCB & CCB_TRANSLATE_SCAN_CODE_BIT_MASK) == 0 )
+ {
+ ++bValue; // Update offset (for scan code set 2)
+ }
+
+ bValue = fPointer[bValue];
+
+ bValue = USBKBC_CheckCharacterBufferFull(bValue);
+
+ if (!bValue) return;
+
+ //
+ // We had found out correct scan code length to generate and also we
+ // verified we have enough space. Now generate the scan code
+ //
+ bValue = gUsbData->bSet2ScanCode;
+
+ if(bValue == PAUSE_KEY )
+ {
+ //
+ // Check whether CTRL key is pressed
+ //
+ if(!(gUsbData->bUSBKBShiftKeyStatus & KB_CTRL_KEY_BIT_MASK))
+ {
+ //
+ // Pause key scan code generation
+ //
+ USBKBC_SendToCharacterBuffer(0x0E1);
+ gUsbData->bSet2ScanCode = 0x14;
+ USBKB_GenerateType1MakeCode();
+ gUsbData->bSet2ScanCode = 0x77;
+ USBKB_GenerateType1MakeCode();
+ USBKBC_SendToCharacterBuffer(0xE1);
+ gUsbData->bSet2ScanCode = 0x14;
+ USBKB_GenerateType1BreakCode();
+ gUsbData->bSet2ScanCode = 0x77;
+ USBKB_GenerateType1BreakCode();
+ return;
+ }
+ else
+ {
+ gUsbData->bSet2ScanCode = 0x7E;
+ USBKB_GenerateType2MakeCode();
+ USBKB_GenerateType2BreakCode();
+ }
+
+ }
+ else if(bValue == PRINT_SCREEN )
+ {
+ gUsbData->bSet2ScanCode = 0x7C; // PRNSCRN for scan code set 2
+ //
+ // Check for ALT+PRNSCRN key combination
+ //
+ if(!(gUsbData->bUSBKBShiftKeyStatus & KB_ALT_KEY_BIT_MASK ))
+ {
+ //
+ // Check for CTRL or SHIFT+PRNSCRN key combination
+ //
+ if(!(gUsbData->bUSBKBShiftKeyStatus &
+ (KB_CTRL_KEY_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK)))
+ {
+ UKGSC_KeyCombination2:
+//
+// Process PRNSCRN only key processing, NUMLOCK + any numeric key press
+// processing at this point. Generate either (E0,12,E0,xx) or
+// (E0,F0,xx,E0,F0,12). Where xx bSet2ScanCode
+//
+ //
+ // Check whether to generate make or break code
+ //
+ if(!(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK))
+ {
+ bTemp = gUsbData->bSet2ScanCode;
+ gUsbData->bSet2ScanCode = 0x12;
+ USBKB_GenerateType2MakeCode();
+ gUsbData->bSet2ScanCode = bTemp;
+ USBKB_GenerateType2MakeCode();
+ USB_DEBUG (DEBUG_LEVEL_5, "USBKB_GenerateScanCode: Return 5.\n");
+ return;
+
+ }
+ else
+ {
+ USBKB_GenerateType2BreakCode();
+ gUsbData->bSet2ScanCode = 0x12;
+ USBKB_GenerateType2BreakCode();
+ USB_DEBUG (DEBUG_LEVEL_5, "USBKB_GenerateScanCode: Return 6.\n");
+ return;
+ }
+ }
+ else
+ goto UKGSC_KeyCombination1;
+
+ }
+ else
+ {
+ gUsbData->bSet2ScanCode = 0x84;
+UKGSC_ProcessRegularKey:
+//
+// Regular key press make & break code generation (xx or 0F0h, xx)
+// Check whether to generate make or break code
+//
+ if((gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK ) == 0)
+ {
+ USBKB_GenerateType1MakeCode();
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: Return 7.\n");
+ return;
+ }
+ USBKB_GenerateType1BreakCode();
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: Return 8.\n");
+ return;
+ }
+
+ }
+ else
+ {
+ //
+ // Check for numeric key pad keys
+ //
+ wScanCode = USBKB_CheckForNumericKeyPadKey(gUsbData->bSet2ScanCode);
+ wTemp = (UINT16)(wScanCode & 0xFF);
+ if(wTemp == 0)
+ {
+ gUsbData->bSet2ScanCode &= 0x7F;
+ //(EIP27889)>
+ if( (!(gUsbData->bUSBKBShiftKeyStatus &
+ (KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK))) ||
+ ((gUsbData->bUSBKBShiftKeyStatus &
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK)) ==
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_LSHIFT_KEY_BIT_MASK)) ||
+ ((gUsbData->bUSBKBShiftKeyStatus &
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK)) ==
+ ( KB_NUM_LOCK_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK)) )
+ //<(EIP27889)
+ goto UKGSC_KeyCombination1;
+
+ if(gUsbData->bUSBKBShiftKeyStatus & KB_NUM_LOCK_BIT_MASK)
+ //(EIP102150+)>
+ {
+ if (!(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK)) {
+ ScanCodeCount = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart);
+ for (i = 0; i < ScanCodeCount; i++) {
+ if ((gUsbData->aKBCDeviceIDBufferStart[i] & gUsbData->bCurrentDeviceID) &&
+ (gUsbData->bCurrentUSBKeyCode == gUsbData->aKBCScanCodeBufferStart[i])) {
+ goto UKGSC_KeyCombination1;
+ }
+ }
+ }
+ goto UKGSC_KeyCombination2;
+ }
+ //<(EIP102150+)
+UKGSC_KeyCombination3:
+//
+// The following code will generate scan code for SHIFT+Numeric key pad
+// key combination. It will generate one of the following sequence
+// (0E0h, 0F0h, 012H or 059h, 0E0h, xx) or
+// (0E0h, 0F0h, xx, 0E0h, 012H or 059h)
+//
+ if((gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK) == 0)
+ {
+ //
+ // Check whether to generate make or break code
+ //
+ bTemp = gUsbData->bSet2ScanCode;
+ if(gUsbData->bUSBKBShiftKeyStatus & KB_LSHIFT_KEY_BIT_MASK)
+ {
+ gUsbData->bSet2ScanCode = 0x12; // Save current scan code (xx)
+ USBKB_GenerateType2BreakCode(); // 0E0h, 0F0h, 012h
+ }
+ if(gUsbData->bUSBKBShiftKeyStatus & KB_RSHIFT_KEY_BIT_MASK)
+ {
+ gUsbData->bSet2ScanCode = 0x59;
+ USBKB_GenerateType2BreakCode(); // 0E0h, 0F0h, 059h
+ }
+ gUsbData->bSet2ScanCode = bTemp; // Restore current code (xx)
+ USBKB_GenerateType2MakeCode(); // 0E0h, xx
+ USB_DEBUG (DEBUG_LEVEL_5, "USBKB_GenerateScanCode: Return 9.\n");
+ return;
+ }
+ else
+ {
+ USBKB_GenerateType2BreakCode();
+ if(gUsbData->bUSBKBShiftKeyStatus & KB_RSHIFT_KEY_BIT_MASK)
+ {
+ gUsbData->bSet2ScanCode = 0x59; // Save current scan code (xx)
+ USBKB_GenerateType2MakeCode(); // 0E0h, 59h
+ }
+ if(gUsbData->bUSBKBShiftKeyStatus & KB_LSHIFT_KEY_BIT_MASK)
+ {
+ gUsbData->bSet2ScanCode = 0x12; // Save current scan code (xx)
+ USBKB_GenerateType2MakeCode(); // 0E0h, 12h
+ }
+ USB_DEBUG (DEBUG_LEVEL_5, "USBKB_GenerateScanCode: Return 10.\n");
+ return;
+ }
+ }
+ else
+ {
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: Notnumeric key\n");
+ //
+ // Check and process extended key press
+ //
+ bValue = (UINT8)USBKB_CheckForExtendedKey(gUsbData->bSet2ScanCode);
+ if(bValue == 0)
+ {
+ gUsbData->bSet2ScanCode &= 0x7F;
+UKGSC_KeyCombination1:
+//
+// Following code processes the following key combinations:
+// Extended key make & break code generation
+// CTRL or SHIFT + PRNSCRN key combination
+// Numeric key pad key code generation
+// One of the following sequence will be generated (0E0h, xx) or
+// (0E0h, 0F0h, xx)
+//
+ if(gUsbData->wUSBKBC_StatusFlag & KBC_MK_BRK_CODE_BIT_MASK)
+ {
+ USBKB_GenerateType2BreakCode();
+ return;
+ }
+ USBKB_GenerateType2MakeCode();
+ return;
+ }
+ else
+ {
+ //
+ // Check and process '/' key
+ //
+ if (gUsbData->bSet2ScanCode != SLASH_KEY)
+ {
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKB_GenerateScanCode: Regular Key.\n");
+ goto UKGSC_ProcessRegularKey;
+ }
+ //
+ // Generate make or break code for '/' key
+ //
+ gUsbData->bSet2ScanCode = 0x4A;
+ if(!(gUsbData->wUSBKBC_StatusFlag &
+ ( KB_LSHIFT_KEY_BIT_MASK
+ + KB_RSHIFT_KEY_BIT_MASK)))
+ goto UKGSC_KeyCombination1;
+ goto UKGSC_KeyCombination3;
+ return;
+ }
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_UpdateLEDState
+//
+// Description: This routine is used to update the LED state between the
+// USB & PS/2 keyboard
+//
+// Input: bFlag Indicates how the LED local variables are adjusted
+//
+// Output: Nothing
+//
+// NOTE: This routine is not executed during EFI phase
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_UpdateLEDState (UINT8 bFlag)
+{
+ UINT8 bLStatus,
+ bHStatus;
+
+ UINT8* fPtr;
+
+ fPtr = (UINT8*)(UINTN)0x417;
+ //
+ // Make sure the password LED status is not changed. If KBC password is
+ // enabled then the LED state for NUMLOCK should be off, SCROLL-LOCK LED
+ // state should be on and CAPSLOCK LED state is in dont-care state.
+ //
+ bLStatus = gUsbData->bNonUSBKBShiftKeyStatus;
+ bLStatus &= 0x07 ; // Masking BIT0, BIT1 and BIT2
+ if (bLStatus & 1)
+ {
+ //
+ // None of the LED is ON. Make Scroll LOCK LED to be ON
+ //
+ bLStatus = 0x04;
+ }
+ else
+ {
+ bLStatus >>= 1;
+ }
+
+ gUsbData->bNonUSBKBShiftKeyStatus &= 0xF8;
+ gUsbData->bNonUSBKBShiftKeyStatus |= bLStatus;
+
+ //
+ // Check whether password is disabled
+ //
+ if (gUsbData->wUSBKBC_StatusFlag & KBC_PASSWORD_FLAG_BIT_MASK)
+ {
+ bHStatus = (UINT8)(gUsbData->bUSBKBShiftKeyStatus & 0x70);
+ bLStatus = (UINT8)((gUsbData->bNonUSBKBShiftKeyStatus & 0x07) << 0x04);
+
+ if(bHStatus == bLStatus)
+ {
+ return;
+ }
+ gUsbData->bUSBKBShiftKeyStatus &=
+ ~ (KB_CAPS_LOCK_BIT_MASK +
+ KB_NUM_LOCK_BIT_MASK +
+ KB_SCROLL_LOCK_BIT_MASK);
+
+ gUsbData->bUSBKBShiftKeyStatus |= bLStatus;
+ //
+ // Check whether SCROLL-LOCK is ON
+ //
+ bLStatus = (UINT8)(bLStatus >> 3);
+ if(bLStatus & 0x08)
+ {
+ bLStatus ^= 0x09;
+ }
+ //
+ // ScrollOff
+ //
+ USBKB_LEDOn();
+ return;
+ }
+
+ //
+ // Get the current PS/2 keyboard LED state
+ //
+// USB_DEBUG(DEBUG_LEVEL_5, "USBKB_UpdateLEDState : [0:417] = %x\n", *fPtr);
+ bLStatus = (UINT8)(((*fPtr) & 0x70) >> 1);
+ bHStatus = (UINT8)((gUsbData->bUSBKBShiftKeyStatus) & 0x70);
+ if(bLStatus & 0x08)
+ bLStatus ^= 0x48;
+
+ if(bLStatus == bHStatus)
+ return;
+
+ gUsbData->bUSBKBShiftKeyStatus &=
+ ~ (KB_CAPS_LOCK_BIT_MASK +
+ KB_NUM_LOCK_BIT_MASK +
+ KB_SCROLL_LOCK_BIT_MASK);
+
+ gUsbData->bUSBKBShiftKeyStatus |= bLStatus;
+ USBKB_LEDOn();
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_LEDOn
+//
+// Description: This routine updates the keyboard LED status for all the
+// USB keyboards present in the sytem
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBKB_LEDOn(
+)
+{
+ UINT8 LByte;
+ UINT8 Count;
+ DEV_INFO* DevInfo;
+ EFI_STATUS Status;
+ //
+ // Set the LED update progress status
+ //
+ gUsbData->bUSBKBC_ExtStatusFlag |= KBCEXT_LED_UPDATE_IN_PROGRESS_BIT;
+
+ //
+ // Get the current USB LED status
+ //
+ USB_DEBUG(DEBUG_LEVEL_7, "USBKB_LEDOn: LedStatus %x\n", gUsbData->bUSBKBShiftKeyStatus);
+ //
+ // Form the byte to be transmitted to the USB keyboard
+ //
+ LByte = (UINT8)(((gUsbData->bUSBKBShiftKeyStatus) >> 4) & 0x07);
+ USB_DEBUG(DEBUG_LEVEL_4, "USBKB_LEDOn: LedStatus %x, bLByte %x\n",
+ gUsbData->bUSBKBShiftKeyStatus, LByte);
+
+ //
+ // Update LED status in every USB keyboard on the system
+ //
+ for(Count = 0; Count < USB_DEV_HID_COUNT; Count++) {
+ DevInfo = gUsbData->aUSBKBDeviceTable[Count];
+ if (DevInfo != NULL) {
+ Status = UsbDevInfoValidation(DevInfo);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ UsbKbdSetLed(DevInfo, LByte);
+ }
+ }
+ //
+ // Reset the LED update progress status
+ //
+ gUsbData->bUSBKBC_ExtStatusFlag &= ~(KBCEXT_LED_UPDATE_IN_PROGRESS_BIT);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_ConvertSet2CodeToSet1Code
+//
+// Description: Converts the set 2 scan code to set 1 scan code
+//
+// Input: bScanCode Set 2 scan code
+//
+// Output: Set 1 scan code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKB_ConvertSet2CodeToSet1Code(UINT8 bScanCode)
+{
+ return USBKB_ConvertScanCodeBetweenCodeSet(
+ bScanCode,
+ aStaticSet2ToSet1ScanCode);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_ConvertScanCodeBetweenCodeSet
+//
+// Description: Converts the set 2 scan code to set 3/1 scan code
+//
+// Input: bScanCode Set 2 scan code
+// bConvTable Pointer to the code set conversion table
+//
+// Output: Set 1/3 scan code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKB_ConvertScanCodeBetweenCodeSet(
+ UINT8 bScanCode,
+ UINT8 *fPointer
+)
+{
+ UINT8 bValue;
+ //
+ // Load the parameter from the stack to register
+ //
+ bScanCode = fPointer[bScanCode];
+ bScanCode = (UINT8)((bScanCode << 4) | (bScanCode >> 4));
+ bValue = (UINT8)((bScanCode & 0x80) >> 7);
+ bScanCode = (UINT8)(~((bScanCode << 1) | bValue));
+ return bScanCode;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_GenerateType1MakeCode
+//
+// Description: This routine generates the type 1 make code for the byte
+// in the variable bSet2ScanCode
+//
+// Input: bSet2ScanCode - Byte containing the scan code
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_GenerateType1MakeCode()
+{
+ UINT8 bValue =0;
+
+// USB_DEBUG (DEBUG_LEVEL_5, "USBKB_GenerateType1MakeCode");
+#if USB_KBC_EMULATION
+ bValue = USBTrap_GetCurrentScanCodeSetNumber();
+#endif
+// Check whether conversion (from set 2 to set 1) is opted
+ if(bValue != 1)
+ {
+ if(((UINT32)(gUsbData->bCCB) & (UINT32)CCB_TRANSLATE_SCAN_CODE_BIT_MASK ) == 0)
+ {
+ USBKBC_SendToCharacterBuffer(gUsbData->bSet2ScanCode);
+ return;
+ }
+ }
+ bValue = USBKB_ConvertSet2CodeToSet1Code(gUsbData->bSet2ScanCode);
+
+ USBKBC_SendToCharacterBuffer(bValue);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_GenerateType1BreakCode
+//
+// Description: This routine generates the type 1 break code for the byte
+// in the variable bSet2ScanCode
+//
+// Input: bSet2ScanCode - Byte containing the scan code
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_GenerateType1BreakCode()
+{
+ UINT8 bValue =0;
+
+ USB_DEBUG (DEBUG_LEVEL_8, "USBKB_GenerateType1BreakCode \n");
+
+#if USB_KBC_EMULATION
+ bValue = USBTrap_GetCurrentScanCodeSetNumber();
+#endif
+ //
+ // Check whether conversion (from set 2 to set 1) is opted
+ //
+ if(bValue != 1)
+ {
+ if(((UINT32)(gUsbData->bCCB) & (UINT32)CCB_TRANSLATE_SCAN_CODE_BIT_MASK ) == 0)
+ {
+ USBKBC_SendToCharacterBuffer(0xF0);
+ USBKBC_SendToCharacterBuffer(gUsbData->bSet2ScanCode);
+ return;
+ }
+ }
+ bValue = USBKB_ConvertSet2CodeToSet1Code(gUsbData->bSet2ScanCode);
+ bValue |= 0x80;
+ USBKBC_SendToCharacterBuffer(bValue);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_GenerateType2MakeCode
+//
+// Description: This routine generates the type 2 make code for the byte
+// in the variable bSet2ScanCode
+//
+// Input: bSet2ScanCode - Byte containing the scan code
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_GenerateType2MakeCode()
+{
+ USBKBC_SendToCharacterBuffer(0xE0);
+ USBKB_GenerateType1MakeCode();
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_GenerateType2BreakCode
+//
+// Description: This routine generates the type 2 break code for the byte
+// in the variable bSet2ScanCode
+//
+// Input: bSet2ScanCode - Byte containing the scan code
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_GenerateType2BreakCode()
+{
+ USBKBC_SendToCharacterBuffer(0xE0);
+ USBKB_GenerateType1BreakCode();
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBTrap_GetCurrentScanCodeSetNumber
+//
+// Description: Returns the current scan code set number
+//
+// Input: Nothing
+//
+// Output: Scan code set number (1, 2 or 3)
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBTrap_GetCurrentScanCodeSetNumber()
+{
+ UINT16 wStatus;
+ wStatus = (UINT16)(gUsbData->wUSBKBC_StatusFlag & KBC_SCAN_CODE_SET_BIT_MASK);
+ wStatus >>= KBC_SCAN_CODE_SET_BIT_SHIFT;
+
+ return (UINT8)wStatus;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBTrap_GetOverrunCode
+//
+// Description: Returns the overrun code depending on the current
+// scan code set
+//
+// Input: Nothing
+//
+// Output: Overrun code
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBTrap_GetOverrunCode()
+{
+ return 0xFF;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_DiscardCharacter
+//
+// Description: This routine discards the top character in the scan
+// code buffer, keyboard status flag buffer and device ID
+// buffer
+//
+// Input: fPointer Points to the keyboard status flag buffer
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKB_DiscardCharacter (UINT8* fPointer)
+{
+ UINT8 bCount;
+ UINT32 dCount = 0;
+ UINT8* fPtrEnd;
+
+ fPtrEnd = gUsbData->aKBCShiftKeyStatusBufferStart +
+ sizeof (gUsbData->aKBCShiftKeyStatusBufferStart);
+ bCount = (UINT8)(fPtrEnd - (fPointer + 1));
+
+ do
+ {
+ fPointer[dCount] = fPointer[dCount+1];
+ ++dCount;
+ --bCount;
+ } while(bCount);
+
+ //
+ // Calculate offset
+ //
+ dCount = (UINT32)(fPointer -
+ (UINT8*)gUsbData->aKBCShiftKeyStatusBufferStart);
+ bCount = (UINT8)(fPtrEnd - (fPointer + 1));
+ do
+ {
+ gUsbData->aKBCDeviceIDBufferStart[dCount] =
+ gUsbData->aKBCDeviceIDBufferStart[dCount+1];
+ ++dCount;
+ --bCount;
+ } while(bCount);
+
+ dCount = (UINT32)(fPointer -
+ (UINT8*)gUsbData->aKBCShiftKeyStatusBufferStart);
+ //
+ // Update device ID buf
+ //
+ bCount = (UINT8)(fPtrEnd - (fPointer + 1));
+ do
+ {
+ gUsbData->aKBCScanCodeBufferStart[dCount] =
+ gUsbData->aKBCScanCodeBufferStart[dCount+1];
+ ++dCount;
+ --bCount;
+ } while(bCount);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_CheckForExtendedKey
+//
+// Description: Checks whether the key pressed is a extended key
+//
+// Input: bScanCode Set 2 scan code for the key pressed
+//
+// Output: 0 Key pressed matches the numeric key pad key
+// <> 0 It is not a numeric key pad key
+// Set 3 scan code for the key pressed
+// (if set 3 is chosen)
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBKB_CheckForExtendedKey (UINT8 bScanCode)
+{
+ UINT8 bCount,
+ bFound = FALSE;
+ UINT16 wRetValue = 0xff;
+
+ bCount = 0;
+ while(bCount < sizeof (aStaticExtendedKeyScan2Table))
+ {
+ if(aStaticExtendedKeyScan2Table[bCount] == bScanCode)
+ {
+ bFound = TRUE;
+ break;
+ }
+ ++bCount;
+ }
+ if(bFound == TRUE)
+ {
+#if USB_KBC_EMULATION
+ wRetValue = (UINT16)aStaticExtendedKeyScan3Table[bCount];
+ wRetValue = wRetValue << 8;
+#endif
+ wRetValue &= 0xff00;
+ }
+
+ return(wRetValue);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_CheckForNumericKeyPadKey
+//
+// Description: Checks whether the key pressed is from numeric key pad
+//
+// Input: bScanCode Set 2 scan code for the key pressed
+//
+// Output: 0 Key pressed matches the numeric key pad key
+// <> 0 It is not a numeric key pad key
+// Set 3 scan code for the key pressed
+// (if set 3 is chosen)
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBKB_CheckForNumericKeyPadKey (UINT8 bScanCode)
+{
+ UINT8 bCount,
+ bFound = FALSE;
+ UINT16 wRetValue = 0xff;
+
+ bCount = 0;
+ while(bCount < sizeof (aStaticKeyPadScan2Table))
+ {
+ if(aStaticKeyPadScan2Table[bCount] == bScanCode)
+ {
+ bFound = TRUE;
+ break;
+ }
+ ++bCount;
+ }
+ if(bFound == TRUE)
+ {
+#if USB_KBC_EMULATION
+ wRetValue = aStaticKeyPadScan3Table[bCount];
+ wRetValue = wRetValue SHL 8;
+#endif
+ wRetValue &= 0xff00;
+ }
+ return(wRetValue);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_CheckCharacterBufferFull
+//
+// Description: This routine checks whether the character buffer can hold
+// 'N'+1 character
+//
+// Input: bCount Space needed in the buffer (in characters)
+//
+// Output: 0 If buffer is full
+// <> 0 If buffer is not full
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKBC_CheckCharacterBufferFull (UINT8 bCount)
+{
+ UINT8 *dHead, *dTail, *dStart, *dEnd;
+
+ dHead = gUsbData->fpKBCCharacterBufferHead;
+ dTail = gUsbData->fpKBCCharacterBufferTail;
+ dStart = gUsbData->aKBCCharacterBufferStart;
+ dEnd = dHead + sizeof (gUsbData->aKBCCharacterBufferStart);
+ ++bCount;
+ do {
+ ++dHead;
+ if(dHead == dEnd) dHead = dStart;
+ if(dHead == dTail) return 0;
+ --bCount;
+ } while(bCount);
+
+ return 0xFF;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_GetFromCharacterBuffer
+//
+// Description: This routine gets a character from the character buffer.
+// Character buffer pointers are also updated
+//
+// Input: Nothing
+//
+// Output: Character taken from the character buffer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKBC_GetFromCharacterBuffer()
+{
+ UINT8 bValue;
+ UINT8 *fPtr, *fPtrEnd;
+
+ fPtrEnd = gUsbData->aKBCCharacterBufferStart +
+ sizeof (gUsbData->aKBCCharacterBufferStart);
+ fPtr = gUsbData->fpKBCCharacterBufferTail;
+ bValue = *fPtr;
+ ++fPtr;
+ //
+ // Check for buffer end condition
+ //
+ if(fPtr == fPtrEnd)
+ fPtr = gUsbData->aKBCCharacterBufferStart;
+ gUsbData->fpKBCCharacterBufferTail = fPtr;
+
+ return bValue;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_SendToCharacterBuffer
+//
+// Description: This routine puts a character into the character buffer.
+// Character buffer pointers are also updated
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKBC_SendToCharacterBuffer (UINT8 bChar)
+{
+ UINT8 *fPointer, *fPtrEnd;
+
+ fPtrEnd = gUsbData->aKBCCharacterBufferStart +
+ sizeof (gUsbData->aKBCCharacterBufferStart);
+
+ fPointer = gUsbData->fpKBCCharacterBufferHead;
+ *fPointer = bChar;
+ ++fPointer;
+
+ if(fPointer == fPtrEnd) {
+ fPointer = gUsbData->aKBCCharacterBufferStart;
+ }
+
+ gUsbData->fpKBCCharacterBufferHead = fPointer;
+
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_ConvertUSBKeyCodeToScanCodeSet2
+//
+// Description: This routine converts the USB keycode into scan code set
+// 2 scan code. Conversion is accomplished using a static table.
+//
+// Input: bKeyCode USB Key code
+//
+// Output: Set 2 scan code for the key
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKB_ConvertUSBKeyCodeToScanCodeSet2 (UINT8 bKeyCode)
+{
+ return aUSBKeyCodeToScanCodeSet2Table[bKeyCode];
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_CheckModifierKeyPress
+//
+// Description: This routine checks whether any of the modifier keys, like
+// shift, control or alternate keys, are pressed
+//
+// Input: bScanCode Scan code set 2 scan code
+//
+// Output: 0 None of the modifier keys are pressed
+// Modifier key is pressed
+// High Byte, Low Byte = Modifier key identifier
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBKB_CheckModifierKeyPress (UINT8 bScanCode)
+{
+ UINT8 bLByte = 0,
+ bHByte = 0;
+ UINT16 wValue;
+ //
+ // Check for left shift key status
+ //
+ if(bScanCode == LEFT_SHIFT)
+ bHByte = KB_LSHIFT_KEY_BIT_MASK;
+ //
+ // Check for right shift key status
+ //
+ if (bScanCode == RIGHT_SHIFT)
+ bHByte = KB_RSHIFT_KEY_BIT_MASK;
+ //
+ // Check for left control key status
+ //
+ if (bScanCode == LEFT_CTRL)
+ {
+ bHByte = KB_CTRL_KEY_BIT_MASK;
+ bLByte = RIGHT_CTRL;
+ }
+ //
+ // Check for left control key status
+ //
+ if (bScanCode == RIGHT_CTRL)
+ {
+ bHByte = KB_CTRL_KEY_BIT_MASK;
+ bLByte = LEFT_CTRL;
+ }
+ //
+ // Check for left alternate key status
+ //
+ if (bScanCode == LEFT_ALT)
+ {
+ bHByte = KB_ALT_KEY_BIT_MASK;
+ bLByte = RIGHT_ALT;
+ }
+ //
+ // Check for left alternate key status
+ //
+ if (bScanCode == RIGHT_ALT)
+ {
+ bHByte = KB_ALT_KEY_BIT_MASK;
+ bLByte = LEFT_ALT;
+ }
+ wValue = (UINT16)(bLByte + (bHByte << 8));
+ return(wValue);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_GetAndStoreCCB
+//
+// Description: This routine will read the CCB from the keyboard controller
+// and store it in a local variable
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKBC_GetAndStoreCCB()
+{
+ KBC_KBDTRANSLATION tr;
+
+ ASSERT(gKbdInput);
+ //
+ // CCB is internal buisness of KBC relted code
+ // USB code only need to know about translation type
+ //
+ VERIFY_EFI_ERROR(
+ gKbdInput->GetTranslation(gKbdInput,&tr));
+ gUsbData->bCCB = tr == KBC_KBDTRANS_PCXT? 0x40 : 0;
+ return ;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_CheckAutoRepeat
+//
+// Description: This routine will check the repeat counter and repeat rate
+// and perform the auto repeat appropriately
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKBC_CheckAutoRepeat()
+{
+ //(EIP102150+)>
+ UINT8 ScanCodeCount = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart);
+ UINT8 i;
+
+ if(ScanCodeCount){
+ USB_DEBUG (DEBUG_LEVEL_7, "USBKBC_CheckAutoRepeat: \n");
+
+ //
+ // Update repeat counter
+ //
+ gUsbData->wRepeatCounter++;
+
+ if (gUsbData->wRepeatCounter >= gUsbData->wRepeatRate) {
+
+ //
+ // Repeat rate reached. Reload repeat delay counter
+ //
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[
+ (gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_RATE_BIT_MASK) >>
+ KBC_TYPE_RATE_BIT_SHIFT];
+ gUsbData->wRepeatCounter = 0;
+
+ //
+ // Check for scan code in the buffer
+ //
+ if(gUsbData->fpKBCCharacterBufferHead ==
+ gUsbData->fpKBCCharacterBufferTail)
+ {
+ //
+ // Buffer has character to process.
+ //
+ for(i = 0; i < ScanCodeCount; i++)
+ {
+ USBKB_GenerateScanCode(USB_GEN_MAKE_CODE,
+ gUsbData->aKBCScanCodeBufferStart[i], 0);
+ }
+ }
+ }
+ }
+ //<(EIP102150+)
+}
+
+
+VOID
+SysKbcAutoRepeat(
+ HC_STRUC* HcStruc
+)
+{
+ UINT8 BreakCodeDeviceId;
+ UINT8 DevAddr;
+ UINT8 *KbInputBuffer;
+ DEV_INFO *DevInfo;
+ PS2MouseData MouseData;
+ EFI_STATUS EfiStatus;
+ UINT8 DummyData;
+ static UINT8 Buffer[64];
+ UINT32 Count = 1;
+
+ USBKB_UpdateLEDState(0x0);
+
+ BreakCodeDeviceId = gUsbData->bBreakCodeDeviceID;
+
+ USB_DEBUG (DEBUG_LEVEL_8, "USBKBDpih: BreakCodeID %x \n", BreakCodeDeviceId);
+
+ if (BreakCodeDeviceId) {
+ DevAddr = 1;
+
+ while (!(BreakCodeDeviceId & 1)) {
+ BreakCodeDeviceId >>= 1;
+ ++DevAddr;
+ }
+ DevInfo = USB_GetDeviceInfoStruc(
+ USB_SRCH_DEV_ADDR,
+ (DEV_INFO*)0,
+ DevAddr,
+ HcStruc);
+ ASSERT(DevInfo != NULL);
+ if (DevInfo == NULL) {
+ return;
+ }
+
+ KbInputBuffer = gUsbData->aKBInputBuffer;
+ *KbInputBuffer = 0;
+ ++KbInputBuffer;
+ *KbInputBuffer = 0;
+ --KbInputBuffer;
+
+ USBKB_Scanner(DevInfo, KbInputBuffer);
+ }
+
+ USBKBC_CheckAutoRepeat();
+ if (gUsbData->fpKBCCharacterBufferTail != gUsbData->fpKBCCharacterBufferHead) {
+ // Get the Data from aKBInputBuffer Local Buffer
+ *Buffer = *gUsbData->fpKBCCharacterBufferTail;
+ //Optimization: Enable the code below; it must be more efficient
+ // UINT8 *p;
+ // for( p = Buffer; gUsbData->fpKBCCharacterBufferTail != gUsbData->fpKBCCharacterBufferHead;
+ // ++Count)
+ // *p++ = USBKBC_GetFromCharacterBuffer();
+
+ if (gKbdInput->Send == SYSKBC_KbdInput_Send) {
+
+ // USB driver Emulation function already working on the aKBInputBuffer buffer
+ // So we don't need to remove the data from aKBInputBuffer incase if data send
+ // Successfully
+ EfiStatus = gKbdInput->Send(gKbdInput, Buffer, Count);
+ } else {
+ // Other Emulation drivers doesn't use the aKBInputBuffer.
+ // So remove the data from aKBInputBuffer if the data sent successfully.
+ EfiStatus = gKbdInput->Send(gKbdInput, Buffer, Count);
+
+ if (!EFI_ERROR(EfiStatus)) {
+ *Buffer = USBKBC_GetFromCharacterBuffer();
+ }
+ }
+
+ USBKBC_GetAndStoreCCB();
+ USBKeyRepeat(NULL, 2);
+ } else if (gUsbData->fpMouseInputBufferHeadPtr !=
+ gUsbData->fpMouseInputBufferTailPtr) {
+
+ // Get the Mouse data Packet from aMouseInputBuffer buffer
+ MouseData.flags = *gUsbData->fpMouseInputBufferTailPtr;
+ MouseData.x = *(gUsbData->fpMouseInputBufferTailPtr + 1);
+ MouseData.y = *(gUsbData->fpMouseInputBufferTailPtr + 2);
+
+ if (gMsInput->Send == SYSKBC_MouseInput_Send) {
+
+ // USB driver Emulation function already working on the aMouseInputBuffer buffer
+ // So we don't need to remove the data from aMouseInputBuffer incase if data send
+ // Successfully
+ EfiStatus = gMsInput->Send(gMsInput, &MouseData);
+ } else {
+ // Other Emulation drivers doesn't use the aMouseInputBuffer.
+ // So remove the data from aMouseInputBuffer if the data sent successfully.
+ EfiStatus = gMsInput->Send(gMsInput, &MouseData);
+ if (!EFI_ERROR(EfiStatus)) {
+ DummyData = USBMouse_GetFromMouseBuffer();
+ DummyData = USBMouse_GetFromMouseBuffer();
+ DummyData = USBMouse_GetFromMouseBuffer();
+ }
+ }
+
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+
+ } else if(gUsbData->fpKBCScanCodeBufferPtr != gUsbData->aKBCScanCodeBufferStart ) {
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ } else {
+ USBKeyRepeat(NULL, 1); // Disable Key repeat
+ }
+}
+
+static EFI_EMUL6064KBDINPUT_PROTOCOL theKbdInput =
+{
+SYSKBC_KbdInput_Send,
+SYSKBC_GetTranslation,
+SYSKBC_UpdateLEDState
+};
+
+EFI_EMUL6064MSINPUT_PROTOCOL theMsInput =
+{
+ SYSKBC_MouseInput_Send
+};
+
+void InitSysKbc(
+ EFI_EMUL6064KBDINPUT_PROTOCOL** ppKbd,
+ EFI_EMUL6064MSINPUT_PROTOCOL** ppMouse )
+{
+ *ppKbd = &theKbdInput;
+ *ppMouse = &theMsInput;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/sysnokbc.c b/Core/EM/usb/rt/sysnokbc.c
new file mode 100644
index 0000000..d38812f
--- /dev/null
+++ b/Core/EM/usb/rt/sysnokbc.c
@@ -0,0 +1,1146 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/sysnokbc.c 14 5/06/14 5:14a Ryanchou $
+//
+// $Revision: 14 $
+//
+// $Date: 5/06/14 5:14a $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/sysnokbc.c $
+//
+// 14 5/06/14 5:14a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 13 4/29/14 7:54p Wilsonlee
+// [TAG] EIP163828
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The mouses stop more than 4 seconds during TP 0xB4 when
+// power on several times.
+// [RootCause] The device sometime doesn't respond the set report
+// command.
+// [Solution] Change the timeout of set report command to 100 ms.
+// [Files] syskbc.c, sysnokbc.c, usbhid.c, amiusb.h
+//
+// 12 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 11 2/21/12 4:53a Rameshr
+// [TAG] EIP67630
+// [Category] Improvement
+// [Description] With the SCAN code matching , attribute also needs to
+// be matched in AMIUSB driver for the Keymon support.
+// [Files] sysnokbc.c
+//
+// 10 9/23/11 12:19a Rajeshms
+// [TAG] EIP69580
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NumLock is not working fine when pressed, while booting to
+// windows XP in a KBC absent platform.
+// [RootCause] The USB INT9 updates the LED state in BDA by checking
+// 0x497 location which is not updated correctly in case of OS (which
+// doesn't not use INT16h)
+// [Solution] The LED state is compared with 0x417 location and if
+// changed, 0x497 location is also updated and LED is glown based on the
+// state.
+// [Files] sysnokbc.c
+//
+// 9 4/30/10 3:39p Fredericko
+// Fixed EIP:38028:USB AutoKeyRepeat is not working properly
+//
+// 8 2/01/10 1:29p Olegi
+// EIP32867: added checking for the validity of KeyMon pointer.
+//
+// 7 9/24/08 10:21a Rameshraju
+// KeymonFilter support added
+//
+// 6 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 4 10/26/07 11:10a Olegi
+// Added Europe1 and Europe2 keys.
+//
+// 3 9/27/07 5:04p Olegi
+//
+// 2 9/27/07 4:12p Olegi
+//
+// 1 3/20/07 12:22p Olegi
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: SysNoKbc.c
+//
+// Description: AMI USB keyboard driver data conversion and presentation
+// routines, KBC is not present
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+
+#if KEYMONFILTER_SUPPORT
+#include <protocol\KeyMonPlatform.h>
+#define KEYMON_MAP 0x108
+#define KEYMON_DATA_ADDRESS 0x10C
+#endif
+
+VOID UpdateKeyMon(UINT8 KeyCode);
+
+extern LEGACY_USB_KEYBOARD mLegacyKeyboard;
+extern USB_GLOBAL_DATA *gUsbData;
+extern UINT8 aTypematicRateDelayTable[];
+
+VOID UpdateLEDs();
+
+//
+// USB scan codes and the corresponding data that will be used during key translation
+//
+/*
+0, //0 00 Reserved (no event indicated)
+0, //1 01 Keyboard ErrorRollOver
+0, //2 02 Keyboard POSTFail
+0, //3 03 Keyboard ErrorUndefined
+*/
+UINT8 aLetters[] = {
+ 0x1e, //4 04 Keyboard a and A
+ 0x30, //5 05 Keyboard b and B
+ 0x2e, //6 06 Keyboard c and C
+ 0x20, //7 07 Keyboard d and D
+ 0x12, //8 08 Keyboard e and E
+ 0x21, //9 09 Keyboard f and F
+ 0x22, //10 0A Keyboard g and G
+ 0x23, //11 0B Keyboard h and H
+ 0x17, //12 0C Keyboard i and I
+ 0x24, //13 0D Keyboard j and J
+ 0x25, //14 0E Keyboard k and K
+ 0x26, //15 0F Keyboard l and L
+ 0x32, //16 10 Keyboard m and M
+ 0x31, //17 11 Keyboard n and N
+ 0x18, //18 12 Keyboard o and O
+ 0x19, //19 13 Keyboard p and P
+ 0x10, //20 14 Keyboard q and Q
+ 0x13, //21 15 Keyboard r and R
+ 0x1f, //22 16 Keyboard s and S
+ 0x14, //23 17 Keyboard t and T
+ 0x16, //24 18 Keyboard u and U
+ 0x2f, //25 19 Keyboard v and V
+ 0x11, //26 1A Keyboard w and W
+ 0x2d, //27 1B Keyboard x and X
+ 0x15, //28 1C Keyboard y and Y
+ 0x2c, //29 1D Keyboard z and Z
+};
+
+struct TNumbers {
+ UINT8 NormalNumber;
+ UINT8 ShiftedNumber;
+} aNumbers[] = {
+ 0x31, 0x21, //30 1E Keyboard 1 and !
+ 0x32, 0x40, //31 1F Keyboard 2 and @
+ 0x33, 0x23, //32 20 Keyboard 3 and #
+ 0x34, 0x24, //33 21 Keyboard 4 and $
+ 0x35, 0x25, //34 22 Keyboard 5 and %
+ 0x36, 0x5e, //35 23 Keyboard 6 and ^
+ 0x37, 0x26, //36 24 Keyboard 7 and &
+ 0x38, 0x2a, //37 25 Keyboard 8 and *
+ 0x39, 0x28, //38 26 Keyboard 9 and (
+ 0x30, 0x29, //39 27 Keyboard 0 and )
+};
+
+struct TBasicKeys {
+ UINT8 BasicKeyScancode;
+ UINT8 BasicKeyAsciiNormal;
+ UINT8 BasicKeyAsciiShifted;
+ UINT16 BasicKeyCodeCtrl;
+ UINT8 BasicKeyAsciiAlt;
+} aBasicKey[] = {
+ 0x1c, 0x0d, 0x0d, 0x1c0a, 0xa6, //40 28 Keyboard Return (ENTER)
+ 0x01, 0x1b, 0x1b, 0x011b, 0x01, //41 29 Keyboard ESCAPE
+ 0x0e, 0x08, 0x08, 0x0e7f, 0x0e, //42 2A Keyboard DELETE (Backspace)
+ 0x0f, 0x09, 0x00, 0x9400, 0xa5, //43 2B Keyboard Tab
+ 0x00, 0x00, 0x00, 0x0000, 0x00, //44 2C Keyboard Spacebar, processed separately
+ 0x0c, 0x2d, 0x5f, 0x0c1f, 0x82, //45 2D Keyboard - and (underscore
+ 0x0d, 0x3d, 0x2b, 0x0000, 0x83, //46 2E Keyboard = and +
+ 0x1a, 0x5b, 0x7b, 0x1a1b, 0x1a, //47 2F Keyboard [ and {
+ 0x1b, 0x5d, 0x7d, 0x1b1d, 0x1b, //48 30 Keyboard ] and }
+ 0x2b, 0x5c, 0x7c, 0x2b1c, 0x26, //49 31 Keyboard \ and |
+ 0x2b, 0x5c, 0x7c, 0x2b1c, 0x26, //50 32 Keyboard Non-US # and ~
+ 0x27, 0x3b, 0x3a, 0x0000, 0x27, //51 33 Keyboard ; and :
+ 0x28, 0x27, 0x22, 0x0000, 0x00, //52 34 Keyboard ` and "
+ 0x29, 0x60, 0x7e, 0x0000, 0x00, //53 35 Keyboard Grave Accent and Tilde
+ 0x33, 0x2c, 0x3c, 0x0000, 0x00, //54 36 Keyboard, and <
+ 0x34, 0x2e, 0x3e, 0x0000, 0x00, //55 37 Keyboard . and >
+ 0x35, 0x2f, 0x3f, 0x0000, 0x00, //56 38 Keyboard / and ?
+};
+/*
+//0x0000, //57 39 Keyboard Caps Lock
+*/
+UINT8 aF1_10Key[] = {
+ 0x3b, //58 3A Keyboard F1
+ 0x3c, //59 3B Keyboard F2
+ 0x3d, //60 3C Keyboard F3
+ 0x3e, //61 3D Keyboard F4
+ 0x3f, //62 3E Keyboard F5
+ 0x40, //63 3F Keyboard F6
+ 0x41, //64 40 Keyboard F7
+ 0x42, //65 41 Keyboard F8
+ 0x43, //66 42 Keyboard F9
+ 0x44, //67 43 Keyboard F10
+};
+/*
+0x85, //68 44 Keyboard F11
+0x86, //69 45 Keyboard F12
+
+
+0x00, //70 46 Keyboard PrintScreen
+0x00, //71 47 Keyboard Scroll Lock
+0x00, //72 48 Keyboard Pause
+*/
+/* apparently the PS/2's int9 implementation returns the same
+scan/ascii for extended keys, keeping the table below for
+reference only.
+struct TExtKeys {
+ UINT8 NormalShiftedScanCode;
+ UINT8 ShiftedAsciiCode;
+ UINT8 wCtrlScanCode;
+ UINT8 wAltScanCode;
+} aExtKeys[] = {
+ 0x52, 0x30, 0x92, 0xA2, //73 49 Keyboard Insert
+ 0x47, 0x37, 0x77, 0x97, //74 4A Keyboard Home
+ 0x49, 0x39, 0x84, 0x99, //75 4B Keyboard PageUp
+ 0x53, 0x2e, 0x93, 0xA3, //76 4C Keyboard Delete Forward
+ 0x4f, 0x31, 0x75, 0x9F, //77 4D Keyboard End
+ 0x51, 0x33, 0x76, 0xA1, //78 4E Keyboard PageDown
+ 0x4d, 0x36, 0x74, 0x9D, //79 4F Keyboard RightArrow
+ 0x4b, 0x34, 0x73, 0x9B, //80 50 Keyboard LeftArrow
+ 0x50, 0x32, 0x91, 0xA0, //81 51 Keyboard DownArrow
+ 0x48, 0x38, 0x8D, 0x98, //82 52 Keyboard UpArrow
+};
+*/
+UINT8 aExtKeys[] = {0x52,0x47,0x49,0x53,0x4f,0x51,0x4d,0x4b,0x50,0x48,};
+/*
+0x, //83 53 Keypad Num Lock and Clear
+*/
+
+UINT16 aKeypad1[] = {
+ 0x352f, //84 54 Keypad /
+ 0x372a, //85 55 Keypad *
+ 0x4a2d, //86 56 Keypad -
+ 0x4e2b, //87 57 Keypad +
+ 0x1c0d, //88 58 Keypad ENTER
+};
+
+struct TKeypadNumbers {
+ UINT8 NormalScanCode; // ascii code is 0
+ UINT8 ShiftedAsciiCode; // altered by both NumLock and Shift
+ UINT8 CtrlScanCode; // ascii code is 0
+ UINT8 AltScanCode; // ascii code is 0
+} aKeypad2[] = {
+ 0x4f, 0x31, 0x75, 0x9f, //89 59 Keypad 1 and End
+ 0x50, 0x32, 0x91, 0xa0, //90 5A Keypad 2 and Down Arrow
+ 0x51, 0x33, 0x76, 0xa1, //91 5B Keypad 3 and PageDn
+ 0x4b, 0x34, 0x73, 0x9b, //92 5C Keypad 4 and Left Arrow
+ 0x4c, 0x35, 0x8f, 0x00, //93 5D Keypad 5 (special, no code if lowercase)
+ 0x4d, 0x36, 0x74, 0x9d, //94 5E Keypad 6 and Right Arrow
+ 0x47, 0x37, 0x77, 0x97, //95 5F Keypad 7 and Home
+ 0x48, 0x38, 0x8d, 0x98, //96 60 Keypad 8 and Up Arrow
+ 0x49, 0x39, 0x84, 0x99, //97 61 Keypad 9 and PageUp
+ 0x52, 0x30, 0x92, 0xa2, //98 62 Keypad 0 and Insert
+ 0x53, 0x2e, 0x93, 0xa3, //99 63 Keypad . and Delete
+};
+/*
+0x, //100 64 Keyboard Non-US \ and |
+0x, //101 65 Keyboard Application
+*/
+
+typedef UINT16 (*GETCODE_FUNC) (UINT8 usbcode);
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_Letter
+//
+// Description: Returns the scan/ascii code for letter charachters, USB
+// code from 4 to 1D.
+// Keys from 'A' to 'Z' are interpreted using the following logic:
+// 1) first_keycode is 04
+// 2) last_keycode is 1D
+// 3) scan_code = letters[key-first_keycode].scancode
+// 4) ascii_code (normal) = 0x61+(key-first_keycode)
+// 5) ascii_code (shifted) = 0x41+(key-first_keycode)
+// 6) ascii_code (w/Ctrl) = key-first_keycode+1
+//
+// Input: Key index (key code - 4)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_Letter(UINT8 usbcode)
+{
+ UINT8 scan_code = aLetters[usbcode];
+ UINT8 ascii_code = 0x61 + usbcode;
+ BOOLEAN changecase = mLegacyKeyboard.KeyModifierState.CapsLock
+ || mLegacyKeyboard.KeyModifierState.Shift;
+
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(scan_code);
+
+ if (mLegacyKeyboard.KeyModifierState.CapsLock
+ && mLegacyKeyboard.KeyModifierState.Shift) changecase = FALSE;
+ if (changecase) ascii_code -= 0x20;
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) ascii_code = usbcode+1;
+ return (UINT16)(scan_code << 8) + ascii_code;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_Number
+//
+// Description: Returns the scan/ascii code for numbers, USB code from 1E to 27.
+// Keys from '1' to '0' are interpreted using the following logic:
+// 1) first_keycode is 1E
+// 2) last_keycode is 27
+// 3) scan_code = key-first_keycode + 2
+// 4) ascii_code (normal) = aNumbers[key-first_keycode].NormalNumber
+// 5) ascii_code (shifted) = aNumbers[key-first_keycode].ShiftedNumber
+// 6) scan_code (w/Alt) = key-first_keycode + 0x78
+//
+// Input: Key index (key code - 1E)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_Number(UINT8 usbcode)
+{
+ UINT8 scan_code = usbcode+2;
+ UINT8 ascii_code = aNumbers[usbcode].NormalNumber;
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(scan_code);
+ if (mLegacyKeyboard.KeyModifierState.Shift) {
+ ascii_code = aNumbers[usbcode].ShiftedNumber;
+ }
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) {
+ ascii_code = 0; scan_code = 0;
+ if (usbcode == 1) { // "2"
+ scan_code = 3;
+ }
+ if (usbcode == 5) { // "6"
+ scan_code = 7;
+ ascii_code = 0x1E;
+ }
+ }
+ if (mLegacyKeyboard.KeyModifierState.Alt) {
+ scan_code = usbcode + 0x78;
+ }
+
+ return (UINT16)(scan_code << 8) + ascii_code;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_BasicKey
+//
+// Description: Returns the scan/ascii code for "basic keys" - not letters, not
+// numbers (Enter, Escape, '[', '/', etc.); USB code from 28 to 38.
+//
+// Input: Key index (key code - 28)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_BasicKey(UINT8 usbcode)
+{
+ UINT8 scan_code = aBasicKey[usbcode].BasicKeyScancode;
+ UINT8 ascii_code = (mLegacyKeyboard.KeyModifierState.Shift)?
+ aBasicKey[usbcode].BasicKeyAsciiShifted : aBasicKey[usbcode].BasicKeyAsciiNormal;
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(scan_code);
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) return aBasicKey[usbcode].BasicKeyCodeCtrl;
+ if (mLegacyKeyboard.KeyModifierState.Alt) {
+ ascii_code = aBasicKey[usbcode].BasicKeyAsciiAlt;
+ if (ascii_code == 0) scan_code = 0;
+ }
+
+ return (UINT16)(scan_code << 8) + ascii_code;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_F1_10Key
+//
+// Description: Returns the scan/ascii code for functional keys F1..F10;
+// USB code from 3A to 43.
+//
+// Input: Key index (key code - 3A)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_F1_10Key(UINT8 usbcode)
+{
+ UINT8 code = aF1_10Key[usbcode];
+ //
+ // ASCII codes are 0s
+ // Scan codes:
+ // shifted = normal+0x19
+ // w/Ctrl = normal+0x23
+ // w/Alt = normal+0x2d
+ //
+
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(code);
+
+ if (mLegacyKeyboard.KeyModifierState.Shift) return (UINT16)(code+0x19) << 8;
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) return (UINT16)(code+0x23) << 8;
+ if (mLegacyKeyboard.KeyModifierState.Alt) return (UINT16)(code+0x2d) << 8;
+
+ return (UINT16)code << 8;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_F11F12Key
+//
+// Description: Returns the scan/ascii code for functional keys F11 and F12;
+// USB code 44 and 45.
+//
+// Input: Key index (key code - 44)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_F11F12Key(UINT8 usbcode)
+{
+ UINT16 aF11_F12[2] = {0x8500, 0x8600};
+ //
+ // ASCII codes are 0s
+ // Scan codes: Normal Shifted w/Ctrl w/Alt
+ // F11 0x85 0x87 0x89 0x8B
+ // F12 0x86 0x88 0x8A 0x8C
+ //
+
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon((UINT8)(aF11_F12[usbcode] >> 8));
+
+ if (mLegacyKeyboard.KeyModifierState.Shift) return aF11_F12[usbcode]+0x200;
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) return aF11_F12[usbcode]+0x400;
+ if (mLegacyKeyboard.KeyModifierState.Alt) return aF11_F12[usbcode]+0x600;
+
+ return aF11_F12[usbcode];
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_ExtKey
+//
+// Description: Returns the scan/ascii code for extended keys such as Home,
+// End, arrows, PgUp/Dn; USB code from 49 to 52.
+//
+// Input: Key index (key code - 49)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_ExtKey(UINT8 usbcode)
+{
+/* UINT8 scan_code = aExtKeys[usbcode].NormalShiftedScanCode;
+ UINT8 ascii_code = 0;
+
+ if (mLegacyKeyboard.KeyModifierState.Shift) {
+ ascii_code = aExtKeys[usbcode].ShiftedAsciiCode;
+ } else {
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) {
+ scan_code = aExtKeys[usbcode].wCtrlScanCode;
+ } else {
+ if (mLegacyKeyboard.KeyModifierState.Alt) {
+ scan_code = aExtKeys[usbcode].wAltScanCode;
+ }
+ }
+ }
+ return ((UINT16)scan_code << 8) + ascii_code;*/
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(aExtKeys[usbcode]);
+
+ return (UINT16)aExtKeys[usbcode]<<8;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_Keypad1
+//
+// Description: Returns the scan/ascii code for non-numeric part of the keypad,
+// such as '/', '*', etc.; USB code from 54 to 58.
+//
+// Input: Key index (key code - 54)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_Keypad1(UINT8 usbcode)
+{
+ if (mLegacyKeyboard.KeyModifierState.Ctrl || mLegacyKeyboard.KeyModifierState.Alt) {
+ return 0;
+ }
+
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon((UINT8)(aKeypad1[usbcode] >> 8));
+
+ return aKeypad1[usbcode];
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_Keypad2
+//
+// Description: Returns the scan/ascii code for numeric part of the keypad;
+// USB code from 59 to 63.
+//
+// Input: Key index (key code - 59)
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+// Notes: The ascii_code is altered depending on the combination of
+// Shift and NumLock.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_Keypad2(UINT8 usbcode)
+{
+ UINT8 scan_code = aKeypad2[usbcode].NormalScanCode;
+ UINT8 ascii_code = 0;
+ BOOLEAN changecase = mLegacyKeyboard.KeyModifierState.NumLock
+ || mLegacyKeyboard.KeyModifierState.Shift;
+
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(scan_code);
+
+ if (mLegacyKeyboard.KeyModifierState.NumLock
+ && mLegacyKeyboard.KeyModifierState.Shift) changecase = FALSE;
+
+ if (changecase) ascii_code = aKeypad2[usbcode].ShiftedAsciiCode;
+ if (mLegacyKeyboard.KeyModifierState.Ctrl) {
+ return (UINT16)aKeypad2[usbcode].CtrlScanCode << 8;
+ }
+ if (mLegacyKeyboard.KeyModifierState.Alt) {
+ return (UINT16)aKeypad2[usbcode].AltScanCode << 8;
+ }
+ return ((UINT16)scan_code<<8) + ascii_code;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetCode_64
+//
+// Description: Returns the scan/ascii code for USB Key 0x64, a.k.a. Europe2
+// Europe2 is typically in AT-101 Key Position 45, between Left
+// Shift and Z keys.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16 GetCode_64(UINT8 usbcode)
+{
+ //
+ // Check for Hot Key from the KeyMon driver
+ //
+ UpdateKeyMon(0x56);
+
+ if (mLegacyKeyboard.KeyModifierState.Shift) return 0x567C;
+ return 0x565C;
+}
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: TKEYGROUP
+//
+// Description: This structure describes the range of the USB keys and the
+// function that is called if the USB key is found within this
+// range.
+//
+// Fields: Name Type Description
+//------------------------------------------------------------
+// first_keycode UINT8 first key code in the range
+// last_keycode UINT8 last key code in the range
+// GetCode GETCODE_FUNC function to call if the code is in the range
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT8 first_keycode;
+ UINT8 last_keycode;
+ GETCODE_FUNC GetCode;
+} TKEYGROUP;
+
+TKEYGROUP aGetKey[] = {
+ {0x04, 0x1d, GetCode_Letter},
+ {0x1e, 0x27, GetCode_Number},
+ {0x28, 0x38, GetCode_BasicKey},
+ {0x3A, 0x43, GetCode_F1_10Key},
+ {0x44, 0x45, GetCode_F11F12Key},
+ {0x49, 0x52, GetCode_ExtKey},
+ {0x54, 0x58, GetCode_Keypad1},
+ {0x59, 0x63, GetCode_Keypad2},
+ {0x64, 0x64, GetCode_64},
+ {0, 0, 0}
+};
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: SysNoKbcAutoRepeat
+//
+// Description: This function performs the key autorepeat
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID SysNoKbcAutoRepeat()
+{
+ UINT8 i;
+ UINT8 bdaKbdLedFlags = *(UINT8*)0x417;
+ UINT8 ledstate;
+
+ gUsbData->wRepeatCounter++;
+ if (gUsbData->wRepeatCounter >= gUsbData->wRepeatRate) {
+
+ //
+ // Repeat rate is reached.
+ // Reload repeat delay counter with keyrepeat delay value; original
+ // type delay value will be restored in ProcessKeyboardData
+ //
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[
+ (gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_RATE_BIT_MASK) >>
+ KBC_TYPE_RATE_BIT_SHIFT];
+ gUsbData->wRepeatCounter = 0;
+
+ for (i=6; i>0; i--) if (mLegacyKeyboard.KeyCodeStorage[i-1] != 0) break;
+
+ if (i != 0) { // Some keys to repeat
+ if (mLegacyKeyboard.KeyCodeStorage[i-1]==mLegacyKeyboard.KeyToRepeat) {
+ ProcessKeyCode(mLegacyKeyboard.KeyToRepeat);
+ } else {
+ mLegacyKeyboard.KeyToRepeat = mLegacyKeyboard.KeyCodeStorage[i-1];
+ }
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+ }
+
+ //
+ // See if current NumLock/ScrlLock/CapsLock matches the 40:17 values; update
+ // the local data and LEDs accordingly.
+ //
+ ledstate = *(UINT8*)&mLegacyKeyboard.KeyModifierState & 7;
+ if (((bdaKbdLedFlags>>4) & 7) != ledstate) { // 7 is a mask for Scrl/Num/Caps locks
+ *(UINT8*)&mLegacyKeyboard.KeyModifierState &= 0xF8;
+ *(UINT8*)&mLegacyKeyboard.KeyModifierState |= ((bdaKbdLedFlags>>4) & 7);
+ UpdateLEDs(); // Turn on/off Ctrl, Alt, NumLock LEDs
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetAsciiScan
+//
+// Description: Calls the service routine for the given keycode. Returns the
+// scan/ascii code.
+//
+// Input: Key code
+//
+// Output: scan code in upper byte, ascii code in lower byte
+//
+// Referrals: TKEYGROUP
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+GetAsciiScan(UINT8 keyCode)
+{
+ TKEYGROUP *KeyGroup;
+ UINT16 code;
+
+ if (keyCode == 0x2C) return 0x3920; // Space Bar
+ for (KeyGroup = aGetKey; KeyGroup->GetCode != 0; KeyGroup++) {
+ if (keyCode >= KeyGroup->first_keycode && keyCode <= KeyGroup->last_keycode) {
+ code = KeyGroup->GetCode(keyCode-KeyGroup->first_keycode);
+ if (mLegacyKeyboard.KeyModifierState.Alt) code &= 0xFF00;
+ return code;
+ }
+ }
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UpdateKeyMon
+//
+// Description: This function takes the keyboard scan code and checks if it is present
+// in the Key Monitor table. If found, it updates the corresponding bit in
+// the Key Monitor map.
+// Key monitor data structure pointer is at 9FC0:10C
+// Key monitor map (32 bit) updated by this routine is at 9FC0:108
+// Map element is {BYTE, DWORD}; BYTE - scan code, DWORD - attribute
+//
+// Input: Key code
+//
+//Output Key monitor map is updated accordingly
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateKeyMon(UINT8 KeyCode)
+{
+
+#if KEYMONFILTER_SUPPORT
+ KEY_ELEMENT *KeyMonData;
+ UINT32 *KeyMonMap;
+ UINT16 EbdaSeg = *(UINT16*)0x40e;
+ UINTN i;
+ UINTN KeyMonSize;
+
+ KeyMonMap=(UINT32 *)((EbdaSeg << 4)+ KEYMON_MAP);
+ //
+ //KeyMon data Seg is located in EBDA:10E and Offset is EBDA:0x10C
+ //
+ KeyMonData=(KEY_ELEMENT*)((*(UINT16 *)((EbdaSeg << 4) + KEYMON_DATA_ADDRESS + 2) << 4) + \
+ *(UINT16 *)((EbdaSeg << 4) + KEYMON_DATA_ADDRESS));
+
+ if(KeyMonData == 0) {
+ //
+ //Nobody registerd the Hot key with KeyMon driver.
+ //
+ return;
+ }
+
+ KeyMonSize=*(UINT32 *)KeyMonData;
+ (UINT8 *)KeyMonData+=4;
+
+ for(i=0;i<=KeyMonSize;i++) {
+ if(KeyMonData[i].ScanCode == KeyCode &&
+ KeyMonData[i].Keyattribute.ShiftKey == mLegacyKeyboard.KeyModifierState.Shift &&
+ KeyMonData[i].Keyattribute.CtrlKey == mLegacyKeyboard.KeyModifierState.Ctrl &&
+ KeyMonData[i].Keyattribute.AltKey == mLegacyKeyboard.KeyModifierState.Alt ) {
+ //
+ //Update the Keymon Map in the EBDA:0x108 area.
+ //
+ *KeyMonMap= (*KeyMonMap) | (1<< i);
+ }
+
+ }
+ return;
+#else
+ return;
+#endif
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InsertChar
+//
+// Description: Insert the given scan/ascii code in the BDA keyboard queue.
+// Updates the necessary BDA pointers, head and tail.
+//
+// Input: Key code, scan code in upper byte, ascii code in lower byte
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InsertChar(UINT16 keyCode)
+{
+ UINT16 bufHead = *(UINT16*)0x41a;
+ UINT16 bufTail = *(UINT16*)0x41c;
+ UINT16 bufStart = *(UINT16*)0x480;
+ UINT16 bufEnd = *(UINT16*)0x482;
+
+ *(UINT16*)(UINTN)(0x400+bufTail) = keyCode;
+ bufTail+=2;
+ if (bufTail >= bufEnd) {
+ bufTail = bufStart;
+ }
+
+ if (bufTail == bufHead) {
+ //
+ // Buffer overflow should be indicated here
+ //
+ return;
+ }
+ *(UINT16*)0x41c = bufTail;
+
+ return;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UpdateLEDs
+//
+// Description: Updates USB keyboard(s) LEDs according to the value of
+// mLegacyKeyboard.KeyModifierState.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UpdateLEDs(
+)
+{
+ UINT8 i;
+ DEV_INFO *KbdDev;
+ UINT8 Rb;
+
+ //
+ // Update LED status in every USB keyboard on the system
+ //
+ // BIT0 ScrlLock, BIT1 NumLock, BIT2 CapsLock
+ Rb = (mLegacyKeyboard.KeyModifierState.NumLock)? 1 : 0;
+ Rb = (mLegacyKeyboard.KeyModifierState.CapsLock)? Rb |2 : Rb;
+ Rb = (mLegacyKeyboard.KeyModifierState.ScrlLock)? Rb |4 : Rb;
+ //
+ // Update the LED status in BDA.
+ //
+ *(UINT8*)0x497 = ((*(UINT8*)0x497) & 0xF8 ) | ((mLegacyKeyboard.KeyModifierState.NumLock)? 2 : 0)
+ | ((mLegacyKeyboard.KeyModifierState.CapsLock)? 4:0) | ((mLegacyKeyboard.KeyModifierState.ScrlLock)? 1 : 0) ;
+
+ for (i = 0; i < USB_DEV_HID_COUNT; i++) {
+ KbdDev = gUsbData->aUSBKBDeviceTable[i];
+ if (KbdDev != NULL) {
+ UsbKbdSetLed(KbdDev, Rb);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ProcessCtrlAltShift
+//
+// Description: Updates mLegacyKeyboard.KeyModifierState according to the value
+// of the 1st byte of the USB keyboard data.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessCtrlAltShift(
+ UINT8 *usbKeys
+)
+{
+ UINT8 i;
+
+ mLegacyKeyboard.KeyModifierState.Ctrl = (usbKeys[0] & 0x11)? 1 : 0;
+ mLegacyKeyboard.KeyModifierState.Shift = (usbKeys[0] & 0x22)? 1 : 0;
+ mLegacyKeyboard.KeyModifierState.Alt = (usbKeys[0] & 0x44)? 1 : 0;
+
+ //
+ // Process Ctrl-Alt-Del combination
+ //
+ if (mLegacyKeyboard.KeyModifierState.Ctrl
+ && mLegacyKeyboard.KeyModifierState.Alt) {
+ for (i=2; i<6;i++) {
+ if (usbKeys[i]==0x4C || usbKeys[i]==0x63) {
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ ASSERT(gRT);
+ gRT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
+ } else {
+ ByteWriteIO(0xcf9, 6);
+ }
+ }
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ProcessLockKeys
+//
+// Description: Process the keys that alter NumLock/ScrollLock/CapsLock; updates
+// mLegacyKeyboard.KeyModifierState and 0:417 accordingly.
+//
+// Input: USB key buffer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessLockKeys(
+ UINT8 *usbKeys
+)
+{
+ UINT8 i;
+
+ for (i=2; i<8; i++) {
+ switch (usbKeys[i]) {
+ case 0x53: // NumLock
+ *(UINT8*)0x417 ^= 0x20; // Toggle BIT5
+ // *(UINT8*)0x497 ^= 0x02; // Toggle BIT1
+ mLegacyKeyboard.KeyModifierState.NumLock ^= 1; // Toggle numlock state
+ break;
+ case 0x39: // CapsLock
+ *(UINT8*)0x417 ^= 0x40; // Toggle BIT6
+ // *(UINT8*)0x497 ^= 0x04; // Toggle BIT2
+ mLegacyKeyboard.KeyModifierState.CapsLock ^= 1; // Toggle capslock state
+ break;
+ case 0x47: // ScrlLock
+ *(UINT8*)0x417 ^= 0x10; // Toggle BIT4
+ // *(UINT8*)0x497 ^= 0x01; // Toggle BIT0
+ mLegacyKeyboard.KeyModifierState.ScrlLock ^= 1; // Toggle scrollock state
+ break;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AdjustKeyBuffer
+//
+// Description: There is often the new key is pressed on a USB keyboard while
+// the previous one is not quite released. In this case usbKeys
+// buffer contains the old keys and the new ones. User, on the
+// other hand, expects only the new ones to be processed.
+// This requires the buffer data modification so that the "old"
+// keys are removed.
+// The only time we do not do this analysis is when the buffer
+// is clear that indicates that all keys are released.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+AdjustKeyBuffer(
+ UINT8 *usbKeys
+)
+{
+ UINT8 aData[6];
+ UINT8 i, j;
+
+ // Save the buffer
+ for (i=0; i<6; i++) aData[i]=usbKeys[i];
+
+ // Patch the buffer
+ for (j=0; j<6; j++) {
+ if (mLegacyKeyboard.KeyCodeStorage[j]==0) continue;
+ for (i=0; i<6; i++) {
+ if (usbKeys[i] == 0) continue;
+ if (usbKeys[i] == mLegacyKeyboard.KeyCodeStorage[j]) {
+ usbKeys[i] = 0;
+ }
+ }
+ }
+ // Store the original buffer
+ for (i=0; i<6; i++) mLegacyKeyboard.KeyCodeStorage[i] = aData[i];
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ProcessKeyCode
+//
+// Description: This routine converts USB code into UINT16 with ASCII code in the
+// lower byte and PS/2 scan code in the upper byte and inserts this
+// UINT16 in the legacy keyboard queue in BDA.
+//
+// Input: USB key
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ProcessKeyCode(UINT8 code)
+{
+ UINT16 ascii_scan;
+ ascii_scan = GetAsciiScan(code);
+ if (ascii_scan != 0) {
+ InsertChar(ascii_scan);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKB_Int9
+//
+// Description: This routine is called from when the new data from USB keyboard
+// is transmitted and available for processing. The functionality is
+// similar to legacy INT9 handler - data is converted into PS/2
+// ASCII/Scan codes and placed in BDA.
+//
+// Input: Buffer with USB keys
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBKB_Int9(
+ UINT8 *usbKeys
+)
+{
+ UINT8 *keyCode;
+ UINT8 i;
+ UINT8 ledstate;
+ UINT8 bdaKbdLedFlags = (*(UINT8*)0x417) >> 4;
+
+ AdjustKeyBuffer(&usbKeys[2]);
+
+ //
+ // See if current NumLock/ScrlLock/CapsLock matches the 40:17 values.
+ // ; update the local data and LEDs accordingly.
+ //
+ ledstate = *(UINT8*)&mLegacyKeyboard.KeyModifierState & 7;
+ if ((bdaKbdLedFlags & 7) != ledstate) { // 7 is a mask for Scrl/Num/Caps locks
+ *(UINT8*)&mLegacyKeyboard.KeyModifierState &= 0xF8;
+ *(UINT8*)&mLegacyKeyboard.KeyModifierState |= (bdaKbdLedFlags & 7);
+ UpdateLEDs(); // Turn on/off Ctrl, Alt, NumLock LEDs
+ //
+ // Update to current Ctrl, Alt, NumLock LEDs state.
+ //
+ ledstate = *(UINT8*)&mLegacyKeyboard.KeyModifierState & 7;
+ }
+
+ ProcessLockKeys(usbKeys);
+ ProcessCtrlAltShift(usbKeys);
+
+ for (keyCode=usbKeys+2, i=0; i<6; i++, keyCode++) {
+ if (*keyCode==0) continue;
+ ProcessKeyCode(*keyCode);
+ }
+
+ if (ledstate != (*(UINT8*)&mLegacyKeyboard.KeyModifierState & 7)) {
+ UpdateLEDs(); // Turn on/off Ctrl, Alt, NumLock LEDs
+ }
+
+ //
+ // Reload the typematic rate value
+ //
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[
+ (gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_DELAY_BIT_MASK) >>
+ KBC_TYPE_DELAY_BIT_SHIFT];
+ gUsbData->wRepeatCounter = 0;
+
+ //
+ // Buffer might be modified, original buffer is stored
+ // in mLegacyKeyboard.KeyCodeStorage
+ //
+ if (mLegacyKeyboard.KeyCodeStorage[0] == 0) {
+ USBKeyRepeat(NULL, 1); // Disable Key repeat
+ } else {
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+}
+
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/uhci.c b/Core/EM/usb/rt/uhci.c
new file mode 100644
index 0000000..f5f4664
--- /dev/null
+++ b/Core/EM/usb/rt/uhci.c
@@ -0,0 +1,3981 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/uhci.c 114 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 114 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/uhci.c $
+//
+// 114 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 113 7/22/16 3:50a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 112 7/07/16 1:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 111 3/14/16 10:21p Wilsonlee
+// [TAG] EIP257506
+// [Category] Improvement
+// [Description] Add USB_KEYREPEAT_INTERVAL token to change the key
+// repeat interval.
+// [Files] usb.sdl, xhci.h, usbkbd.h, uhci.c, ohci.c, ehci.c
+//
+// 110 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 109 12/03/15 1:48a Wilsonlee
+// [TAG] EIP247625
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB hot-plug function is failed in external uhci
+// controllers.
+// [RootCause] We don't install UhciRootHubQhCallBack for external uhci
+// controllers.
+// [Solution] Handle the hot-plug function in the periodic timer smi
+// handler if the uhci controller is external.
+// [Files] uhci.c
+//
+// 108 4/10/15 3:11a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 107 3/08/15 10:49p Wilsonlee
+// [TAG] EIP207774
+// [Category] Improvement
+// [Description] Set USB_FLAG_DRIVER_STARTED flag when HC is running and
+// clear it if we don't start any HC.
+// [Files] uhci.c, usb.c, ehci.c, ohci.c, xhci.c, amiusb.h
+//
+// 106 1/22/15 10:19p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 105 6/26/14 1:15a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 104 5/01/14 3:57a Ryanchou
+// [TAG] EIP162589
+// [Category] Improvement
+// [Description] Do not register external controller as key repeat
+// controller.
+// [Files] ehci.c, ohci.c, uhci.c
+//
+// 103 4/30/14 8:56a Ryanchou
+// [TAG] EIP160289
+// [Category] Improvement
+// [Description] Handle zero length of short packet.
+// [Files] uhci.c
+//
+// 102 4/30/14 6:13a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 101 2/26/14 1:55a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 100 9/24/13 5:39a Ryanchou
+// [TAG] EIP132985
+// [Category] Improvement
+// [Description] Clear the SMI enable bit if UHCI is not controlled by
+// BIOS.
+// [Files] uhci.c
+//
+// 99 8/16/13 2:15a Ryanchou
+//
+// 98 7/26/13 2:40a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 97 7/22/13 10:31p Wilsonlee
+// [TAG] EIP125357
+// [Category] Improvement
+// [Description] Check if the port releases to a select host controller.
+// [Files] uhci.c, usb.c, usbhub.c, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 96 6/02/13 11:42p Wilsonlee
+// [TAG] EIP123235
+// [Category] Improvement
+// [Description] Stop the usb host controller at ExitBootService if it
+// is an extend card or it doesn't support HW SMI.
+// [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c,
+// uhcd.c
+//
+// 95 4/16/13 6:45a Ryanchou
+// [TAG] EIP118912
+// [Category] Improvement
+// [Description] Add VIA VT6212 EHCI controller support.
+// [Files] ehci.c, uhci.c, usbdef.h, uhcd.c
+//
+// 94 3/19/13 3:58a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 93 3/18/13 4:49a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 92 2/24/13 9:00p Wilsonlee
+// [TAG] EIP113541
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] System hangs at checkpoint 0xA2 when Win8 resume from S4.
+// [RootCause] The "HCHalted" bit and "Port Change Detect" bit are set
+// when the system S4 resume to Win8 OS.
+// [Solution] We need to clear the interrupt status even if the
+// "HCHalted" bit is set.
+// [Files] ehci.c, ohci.c, uhci.c
+//
+// 91 12/06/12 12:39a Wilsonlee
+// [TAG] EIP103186
+// [Category] Improvement
+// [Description] Handle the error case "MEMIO was disabled" in USB
+// driver.
+// [Files] uhci.c, ohci.c, ehci.c, xhci.c
+//
+// 90 11/22/12 9:21p Wilsonlee
+// [TAG] EIP106887
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for UHCI.
+// [Files] usb.c, uhci.c, uhci.h
+//
+// 89 11/10/12 6:48a Ryanchou
+//
+// 88 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 87 9/28/12 2:37a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 86 8/29/12 8:17a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 85 5/04/12 6:39a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 84 5/03/12 6:23a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 83 11/08/11 1:56a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 82 9/26/11 11:43p Roberthsu
+// [TAG] EIP67230
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ntrig touch panel can not use on CedarTrail
+// [RootCause] Because ntrig report data over than 512 byte.Control
+// transfer check if over 512 than set length is 512.
+// [Solution] Remove check transfer length.
+// [Files] ohci.c,uhci.c,usbhid.c
+//
+// 81 8/08/11 6:59a Ryanchou
+// [TAG] EIP54018
+// [Category] New Feature
+// [Description] Added USB S5 wake up support.
+// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h,
+// usbsb.c xhci.c
+//
+// 80 8/08/11 5:15a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 79 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 78 7/13/11 4:09a Ryanchou
+// [TAG] EIP59332
+// [Category] Improvement
+// [Description] Modified the Stop function for UHCD and USBBUS to
+// properly stop devices and uninstall the protocols.
+// [Files] uhcd.c, uhcd.h, uhci.c, usbbus.c, UsbInt13.c, usbmisc.c
+//
+// 77 7/12/11 8:09a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 76 7/01/11 3:19a Ryanchou
+// [TAG] EIP61385
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] USB devices can't detected.
+// [RootCause] This is the side effect of EIP59663, the port status
+// doesn't reflect connect status and connect status change.
+// [Solution] Add 100 us delay.
+// [Files] ehci.c, uhci.c
+//
+// 75 6/22/11 1:44a Ryanchou
+// [TAG] EIP59738
+// [Category] Improvement
+// [Description] Support Block size other than 512 bytes USB HDD in UEFI
+// mode.
+// [Files] efiusbmass.c, uhci.c, usb.c, usbdef.h, usbmass.c
+//
+// 74 5/03/11 10:09a Ryanchou
+// [TAG] EIP54283
+// [Category] Improvement
+// [Description] Follow XHCI spec ver 1.0 section 4.6.8 to recovery
+// endpoint halt.
+// [Files] ehci.c, ohci.c, uhci.c, usbdef.h, usbmass.c, xhci.c
+//
+// 73 4/06/11 1:33a Ryanchou
+// [TAG] EIP54782
+// [Category] Improvement
+// [Description] Change polling data size of HID devices to max packet
+// size of interrupt endpoint.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, xhci.c
+//
+// 72 3/29/11 10:51p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 71 3/29/11 10:08a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 70 11/11/10 11:35p Ryanchou
+// [TAG] EIP45578
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB 3.0 device can't be detected.
+// [RootCause] Address Device Command fails.
+// [Solution] Reset the device and attempt the Address Device Command
+// again.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c, xhci.c
+//
+// 69 9/24/10 5:38p Olegi
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 68 9/07/10 4:11a Tonylo
+// Remove user tags for coding standard.
+//
+// 67 8/18/10 4:22p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 66 4/30/10 3:36p Fredericko
+// Fixed EIP : 38028: USB AutoKeyRepeat is not working properly
+//
+// 65 3/10/10 6:35p Olegi
+//
+// 64 3/10/10 10:51a Olegi
+// Function headers corrected.
+//
+// 63 3/06/10 1:11p Olegi
+//
+// 62 2/26/10 4:23p Olegi
+//
+// 61 2/08/10 10:11a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 60 2/08/10 9:40a Olegi
+// EIP34448: Changes in UHCIWaitForTransferComplete and transfer routines.
+//
+// 59 1/26/10 4:35p Olegi
+//
+// 55 12/23/09 11:59a Olegi
+//
+// 54 12/22/09 8:57a Olegi
+//
+// 53 12/10/09 10:06a Olegi
+// Added timeout in UHCI_WaitForBulkTransferComplete, EIP32048.
+//
+// 52 11/13/09 12:37p Olegi
+//
+// 51 10/30/09 5:47p Olegi
+//
+// 50 10/07/09 9:48a Olegi
+// USB Hub error handling improvement. EIP#25601.
+//
+// 49 9/15/09 10:21a Olegi
+// Added USB_INCMPT_HID_DATA_OVERFLOW incompatibility type.
+//
+// 48 8/26/09 11:41a Olegi
+// Changes that prevent collision of keyboard activity and mass storage
+// access. EIP#22808
+//
+// 47 2/23/09 12:56p Olegi
+//
+// 46 2/20/09 4:43p Olegi
+//
+// 45 2/17/09 4:01p Olegi
+//
+// 44 2/17/09 8:58a Olegi
+//
+// 43 2/06/09 4:06p Olegi
+//
+// 42 1/16/09 3:50p Olegi
+// Optimization in BulkTransfer scheduling.
+//
+// 41 10/06/08 3:33p Olegi
+// EHCI change ownership testing in DOS fix (EIP#14855).
+//
+// 40 9/02/08 10:29a Olegi
+// EIP14855 bugfix: change ownership request is not processed properly in
+// case of multiple controllers of the same type.
+//
+// 39 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 38 2/05/08 3:13p Olegi
+// Bugfix in BulkTdCallback that showed when data TD returns with stall
+// condition.
+//
+// 37 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 36 10/15/07 5:13p Olegi
+// ControlTransfer cleanup.
+//
+// 35 9/26/07 9:15a Olegi
+// Added USB_FORCE_64BIT_ALIGNMENT flag as well as a call ty sync the LEDs
+// between keyboards in DOS.
+//
+// 34 9/21/07 5:10p Davidd
+// Allocation TDs is forced to be 64-bytes aligned.
+//
+// 33 9/06/07 6:12p Olegi
+//
+// 32 9/06/07 5:52p Olegi
+// Tracker 27603 fix added.
+//
+// 31 8/14/07 11:56a Olegi
+// Reverted buggy BulkTransfer changes to make floppy work.
+//
+// 30 8/14/07 10:59a Olegi
+//
+// 29 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 28 4/17/07 6:13p Fredericko
+// Modified UHCI_EnableRootHub to preserve the Connect Status Change bit.
+//
+// 27 4/17/07 8:24a Olegi
+// Device detection algorythm update, in sync with Core8.
+//
+// 26 3/20/07 12:18p Olegi
+//
+// 25 1/26/07 2:52p Olegi
+// Bugfix in UHCI_BulkTDCallback.
+//
+// 24 1/25/07 4:25p Olegi
+//
+// 23 1/25/07 10:19a Olegi
+//
+// 22 1/02/07 2:08p Olegi
+//
+// 21 12/28/06 5:27p Olegi
+//
+// 20 12/26/06 10:52a Olegi
+//
+// 19 12/20/06 2:30p Olegi
+//
+// 17 10/19/06 5:24p Andriyn
+//
+// 15 10/12/06 9:37p Andriyn
+// Fix: unexpected plug-off hangs with endless TIMEOUTs
+//
+// 14 7/10/06 2:57p Andriyn
+// Fix: double delocation of descriptors used for control transfer
+//
+// 13 6/29/06 11:54a Andriyn
+// Removed commented code
+//
+// 12 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 11 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 10 3/06/06 6:23p Olegi
+//
+// 9 11/29/05 12:33p Andriyn
+//
+// 8 9/23/05 12:01p Olegi
+//
+// 7 9/23/05 11:58a Olegi
+//
+// 6 8/27/05 3:43p Andriyn
+// Fix: lost mouse click when mouse is not moving
+//
+// 5 8/11/05 9:53a Olegi
+// 60/64 port emulation related fixes for EMU6064 driver.
+//
+// 4 6/03/05 6:08p Olegi
+// HW SMI registration change.
+//
+// 3 5/19/05 8:07p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 2 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Uhci.c
+//
+// Description: AMI USB UHCI driver
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#endif
+
+extern VOID* USB_MemAlloc (UINT16);
+extern UINT8 USB_MemFree (VOID _FAR_ *, UINT16);
+extern UINT8 USBCheckPortChange (HC_STRUC*, UINT8, UINT8);
+extern UINT8 USB_InstallCallBackFunction (CALLBACK_FUNC);
+
+extern UINT32 ReadPCIConfig(UINT16, UINT8);
+extern VOID WordWritePCIConfig(UINT16, UINT8, UINT16);
+extern UINT8 ByteReadIO(UINT16);
+extern VOID ByteWriteIO(UINT16, UINT8);
+extern UINT16 WordReadIO(UINT16);
+extern VOID WordWriteIO(UINT16, UINT16);
+extern UINT32 DwordReadIO(UINT16);
+extern VOID DwordWriteIO(UINT16, UINT32);
+extern VOID FixedDelay(UINTN);
+extern DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*);
+extern UINT8 USBLogError(UINT16);
+extern VOID USB_InitFrameList (HC_STRUC*, UINT32);
+#if USB_DEV_KBD
+extern VOID USBKBDPeriodicInterruptHandler(HC_STRUC*);
+extern VOID USBKeyRepeat(HC_STRUC*, UINT8);
+#endif
+
+UINT8 USB_DisconnectDevice (HC_STRUC*, UINT8, UINT8);
+UINT8 UsbGetDataToggle(DEV_INFO*,UINT8);
+VOID UsbUpdateDataToggle(DEV_INFO*, UINT8, UINT8);
+
+//---------------------------------------------------------------------------
+
+// Public function declaration
+UINT8 UHCI_Start (HC_STRUC*);
+UINT8 UHCI_Stop (HC_STRUC*);
+UINT8 UHCI_EnumeratePorts (HC_STRUC*);
+UINT8 UHCI_DisableInterrupts (HC_STRUC*);
+UINT8 UHCI_EnableInterrupts (HC_STRUC*);
+UINT8 UHCI_ProcessInterrupt(HC_STRUC*);
+UINT8 UHCI_GetRootHubStatus (HC_STRUC*,UINT8, BOOLEAN);
+UINT8 UHCI_DisableRootHub (HC_STRUC*,UINT8);
+UINT8 UHCI_EnableRootHub (HC_STRUC*,UINT8);
+UINT8 UHCI_ResetRootHub (HC_STRUC*,UINT8);
+UINT16 UHCI_ControlTransfer (HC_STRUC*,DEV_INFO*,UINT16,UINT16,UINT16,UINT8*,UINT16);
+UINT32 UHCI_BulkTransfer (HC_STRUC*,DEV_INFO*,UINT8,UINT8*,UINT32);
+UINT16 UHCI_InterruptTransfer (HC_STRUC*, DEV_INFO*, UINT8, UINT16, UINT8*, UINT16);
+UINT8 UHCI_DeactivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 UHCI_ActivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 UHCI_DisableKeyRepeat (HC_STRUC*);
+UINT8 UHCI_EnableKeyRepeat (HC_STRUC*);
+UINT8 UHCI_GlobalSuspend (HC_STRUC*); //(EIP54018+)
+
+UINT8 UhciProcessQh (HC_STRUC*, UHCI_QH*);
+UINT8 UhciProcessTd (HC_STRUC*, UHCI_TD*);
+UINT8 UhciProcessFrameList (HC_STRUC*);
+
+UINT8 UHCI_DisableHCPorts (HC_STRUC*);
+UINT8 UHCI_StartTDSchedule (HC_STRUC*);
+UINT8 UHCI_StopTDSchedule (HC_STRUC*);
+UINT8 UHCI_InterruptTDCallback (HC_STRUC*, DEV_INFO*, UINT8*, UINT8*);
+UINT8 UhciAddQhToFrameList (HC_STRUC*, UHCI_QH*);
+UINT8 UhciRemoveQhFromFrameList (HC_STRUC*, UHCI_QH*);
+VOID UhciInitQh (UHCI_QH*);
+BOOLEAN UhciIsHalted(HC_STRUC*);
+UINT8 UhciTranslateInterval(UINT8);
+
+UHCI_TD*
+UhciAllocGeneralTds (
+ IN UINT8 DeviceAddr,
+ IN BOOLEAN LowSpeed,
+ IN UINT8 PacketId,
+ IN UINT8 EndpointAddr,
+ IN UINT16 MaxPacket,
+ IN BOOLEAN ShortPacket,
+ IN OUT UINTN *BufferAddr,
+ IN OUT UINT32 *Length,
+ IN OUT UINT8 *DataToggle
+);
+
+VOID
+UhciFreeTds (
+ IN UHCI_TD *FirstTd
+);
+
+VOID
+UhciActivateTds (
+ IN UHCI_TD *FirstTd,
+ IN UINT8 DataToggle
+);
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gCheckUsbApiParameter;
+
+UINT8 UhciRootHubQhCallBack(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 UhciRepeatQhCallback (HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 UhciPollingQhCallback (HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_FillHCDEntries
+//
+// Description:
+// This function fills the host controller driver routine pointers
+//
+// Input:
+// fpHCDHeader Ptr to the host controller header structure
+//
+// Output:
+// USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_FillHCDEntries(HCD_HEADER *fpHCDHeader)
+{
+ //
+ // Fill the routines here
+ //
+ fpHCDHeader->pfnHCDStart = UHCI_Start;
+ fpHCDHeader->pfnHCDStop = UHCI_Stop;
+ fpHCDHeader->pfnHCDEnumeratePorts = UHCI_EnumeratePorts;
+ fpHCDHeader->pfnHCDDisableInterrupts = UHCI_DisableInterrupts;
+ fpHCDHeader->pfnHCDEnableInterrupts = UHCI_EnableInterrupts;
+ fpHCDHeader->pfnHCDProcessInterrupt = UHCI_ProcessInterrupt;
+ fpHCDHeader->pfnHCDGetRootHubStatus = UHCI_GetRootHubStatus;
+ fpHCDHeader->pfnHCDDisableRootHub = UHCI_DisableRootHub;
+ fpHCDHeader->pfnHCDEnableRootHub = UHCI_EnableRootHub;
+ fpHCDHeader->pfnHCDControlTransfer = UHCI_ControlTransfer;
+ fpHCDHeader->pfnHCDBulkTransfer = UHCI_BulkTransfer;
+ fpHCDHeader->pfnHCDInterruptTransfer = UHCI_InterruptTransfer;
+ fpHCDHeader->pfnHCDDeactivatePolling = UHCI_DeactivatePolling;
+ fpHCDHeader->pfnHCDActivatePolling = UHCI_ActivatePolling;
+ fpHCDHeader->pfnHCDDisableKeyRepeat = UHCI_DisableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableKeyRepeat = UHCI_EnableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableEndpoints = USB_EnableEndpointsDummy;
+ fpHCDHeader->pfnHCDInitDeviceData = USB_InitDeviceDataDummy;
+ fpHCDHeader->pfnHCDDeinitDeviceData = USB_DeinitDeviceDataDummy;
+ fpHCDHeader->pfnHCDResetRootHub = UHCI_ResetRootHub;
+ fpHCDHeader->pfnHCDClearEndpointState = 0; //(EIP54283+)
+ fpHCDHeader->pfnHCDGlobalSuspend = UHCI_GlobalSuspend; //(EIP54018+)
+
+ USB_InstallCallBackFunction(UhciPollingQhCallback);
+ USB_InstallCallBackFunction(UhciRepeatQhCallback);
+ USB_InstallCallBackFunction(UhciRootHubQhCallBack);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_Start
+//
+// Description:
+// This API function is called to start a UHCI host controller. The input to the
+// routine is the pointer to the HC structure that defines this host controller
+//
+// Input:
+// fpHCStruc Ptr to the host controller structure
+//
+// Output:
+// Status: USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_Start (HC_STRUC* fpHCStruc)
+{
+ UINT16 wIOAddr;
+ UINT16 LegSupReg;
+ UINT16 Index;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)fpHCStruc->fpFrameList, 0x1000);
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+
+/*
+USB_DEBUG(DEBUG_LEVEL_3, "Enabling IO/BM for UHCI HC %02X\n", fpHCStruc->wBusDevFuncNum);
+ //
+ // Enable IO access and Bus Mastering
+ //
+ WordWritePCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, 4, BIT0 + BIT2);
+*/
+ //
+ // Set number of root hub ports present
+ //
+ fpHCStruc->bNumPorts = 2;
+
+ //
+ // Get the I/O base address for the host controller
+ //
+ wIOAddr = (UINT16)ReadPCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, USB_IO_BASE_ADDRESS);
+
+ //
+ // Mask the low order two bits and store the value in HCStruc
+ //
+ wIOAddr = (UINT16)(wIOAddr & (~(BIT0+BIT1)));
+ USB_DEBUG(DEBUG_LEVEL_4, "HC I/O Address : %X\n", wIOAddr);
+ fpHCStruc->BaseAddress = wIOAddr;
+
+ fpHCStruc->wAsyncListSize = UHCI_FRAME_LIST_SIZE;
+
+ //
+ // Disable hardware interrupt generation by programming legacy registers
+ //
+ LegSupReg = (UINT16)ReadPCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP);
+
+ //
+ // Disable generation of SMI/IRQ and clear status bits
+ //
+ LegSupReg = (UINT16)(LegSupReg & (~BIT4));
+ WordWritePCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP, LegSupReg);
+
+ //
+ // Disable the interrupts (to aVOID spurious interrupts)
+ //
+ UHCI_DisableInterrupts(fpHCStruc);
+
+ //
+ // Disable the host controller root hub ports
+ //
+ UHCI_DisableHCPorts(fpHCStruc);
+
+ //
+ // Check whether HC is already stopped
+ //
+ if (!UhciIsHalted(fpHCStruc)) {
+ //
+ // HC is still running. Stop it by programming HC run bit
+ //
+ ByteWriteIO ((UINT16)(wIOAddr + UHCI_COMMAND_REG),
+ ByteReadIO((UINT16)(wIOAddr + UHCI_COMMAND_REG)) & ~UHC_HOST_CONTROLLER_RUN);
+
+ //
+ // Check whether the host controller is halted (check for 50 ms)
+ //
+ for (Index = 0; Index < 500; Index++) {
+ if ((ByteReadIO((UINT16)(wIOAddr + UHCI_STATUS_REG))) & UHC_HC_HALTED) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ }
+ ASSERT((ByteReadIO((UINT16)(wIOAddr + UHCI_STATUS_REG))) & UHC_HC_HALTED);
+ if (!((ByteReadIO((UINT16)(wIOAddr + UHCI_STATUS_REG))) & UHC_HC_HALTED)) {
+ return USB_ERROR;
+ }
+
+ //
+ // Reset the host controller
+ //
+ ByteWriteIO((UINT16)(wIOAddr + UHCI_COMMAND_REG), UHC_GLOBAL_RESET);
+
+ FixedDelay(10 * 1000); // Recommended 10msec delay, UHCI Spec, p.12, GRESET description
+
+ ByteWriteIO((UINT16)(wIOAddr + UHCI_COMMAND_REG), 0);
+
+ //
+ // Memory has been allocated in AMIUHCD
+ //
+ if (!fpHCStruc->fpFrameList) {
+ return USB_ERROR;
+ }
+
+ USB_InitFrameList (fpHCStruc, UHCI_TERMINATE);
+
+ //
+ // Program frame list pointer to the HC
+ //
+ USB_DEBUG(DEBUG_LEVEL_4, "Frame list pointer : %x\n", fpHCStruc->fpFrameList);
+ DwordWriteIO((UINT16)(wIOAddr + UHCI_FRAME_LIST_BASE), (UINT32)(UINTN)fpHCStruc->fpFrameList);
+
+ USB_DEBUG(DEBUG_LEVEL_6, "UHCI_StartTDSchedule\n");
+
+ //
+ // Start the TD schedule
+ //
+ if (UHCI_StartTDSchedule(fpHCStruc) != USB_SUCCESS)
+ return USB_ERROR;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ //
+ // Enable hardware interrupt generation by programming legacy registers
+ //
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ LegSupReg = (UINT16)ReadPCIConfig(fpHCStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP);
+ // Enable generation of SMI/IRQ
+ LegSupReg = (UINT16)(LegSupReg | BIT4) & ~BIT13;
+ WordWritePCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP, LegSupReg);
+ }
+#endif
+ //
+ // Start the host controller by setting the run and configure bit
+ //
+ WordWriteIO((UINT16)(wIOAddr + UHCI_COMMAND_REG),
+ UHC_HOST_CONTROLLER_RUN |
+ UHC_CONFIGURE_FLAG |
+ UHC_MAX_PACKET_64_BYTE);
+
+ //
+ // Enable interrupt generation
+ //
+// WordWriteIO((UINT16)(wIOAddr + UHCI_INTERRUPT_ENABLE), (UHC_IOC_ENABLE | UHC_TIMEOUT_CRC_ENABLE));
+ WordWriteIO((UINT16)(wIOAddr + UHCI_INTERRUPT_ENABLE), UHC_IOC_ENABLE);
+
+ fpHCStruc->dHCFlag |= HC_STATE_RUNNING;
+
+ // Set USB_FLAG_DRIVER_STARTED flag when HC is running.
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_DRIVER_STARTED)) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_DRIVER_STARTED;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ //
+ // Register the USB HW SMI handler
+ //
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ UsbInstallHwSmiHandler(fpHCStruc);
+ } else {
+ USBSB_InstallUsbIntTimerHandler();
+ }
+#endif
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_Stop
+//
+// Description:
+// This API function is called to stop the UHCI controller. The input to the
+// routine is the pointer to the HC structure that defines this host controller.
+//
+// Input:
+// fpHCStruc Ptr to the host controller structure
+//
+// Output:
+// Status: USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_Stop (HC_STRUC* fpHCStruc)
+{
+ UINT16 wIOAddr = (UINT16)fpHCStruc->BaseAddress;
+ UINT16 LegSupReg;
+ UINT16 Index;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+ //
+ // Disable hardware interrupt generation by programming legacy registers
+ //
+ if (!(fpHCStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ LegSupReg = (UINT16)ReadPCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP);
+
+ //
+ // Disable generation of SMI/IRQ and clear status bits
+ //
+ LegSupReg = (UINT16)(LegSupReg & ~(BIT4));
+ WordWritePCIConfig((UINT16)fpHCStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP, LegSupReg);
+ }
+
+ //
+ // Disable the host controller interrupt generation
+ //
+ UHCI_DisableInterrupts (fpHCStruc);
+
+ // Disconnect all devices
+ USB_DisconnectDevice(fpHCStruc, fpHCStruc->bHCNumber | BIT7, 1);
+ USB_DisconnectDevice(fpHCStruc, fpHCStruc->bHCNumber | BIT7, 2);
+
+ //
+ // Stop the host controller
+ //
+ if (!UhciIsHalted(fpHCStruc)) {
+ //
+ // Clear HC run bit
+ //
+ ByteWriteIO ((UINT16)(wIOAddr + UHCI_COMMAND_REG),
+ ByteReadIO((UINT16)(wIOAddr + UHCI_COMMAND_REG)) & ~(UHC_HOST_CONTROLLER_RUN));
+
+ //
+ // Check whether the host controller is halted (check for 50 ms)
+ //
+ for (Index = 0; Index < 500; Index++) {
+ if ((ByteReadIO((UINT16)(wIOAddr + UHCI_STATUS_REG))) & UHC_HC_HALTED) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ }
+ ASSERT((ByteReadIO((UINT16)(wIOAddr + UHCI_STATUS_REG))) & UHC_HC_HALTED);
+
+ // Reset the host controller
+ ByteWriteIO((UINT16)(wIOAddr + UHCI_COMMAND_REG), UHC_GLOBAL_RESET);
+ // Recommended 10msec delay, UHCI Spec, p.12, GRESET description
+ FixedDelay(10 * 1000);
+ ByteWriteIO((UINT16)(wIOAddr + UHCI_COMMAND_REG), 0);
+
+ //
+ // Clear the frame list pointers
+ //
+ USB_InitFrameList (fpHCStruc, UHCI_TERMINATE);
+
+ //
+ // Disable and free the TD schedule data structures
+ //
+ UHCI_StopTDSchedule (fpHCStruc);
+
+ //
+ // Set the HC state to stopped
+ //
+ fpHCStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+
+ CheckBiosOwnedHc();
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_EnumeratePorts
+//
+// Description:
+// This API function is called to enumerate the root hub ports in the UHCI
+// controller. The input to the routine is the pointer to the HC structure
+// that defines this host controller
+//
+// Input:
+// fpHCStruc Ptr to the host controller structure
+//
+// Output:
+// Status: USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_EnumeratePorts(HC_STRUC* fpHCStruc)
+{
+ UINT8 bHCNumber;
+ UINT16 wIOAddr, wPortAddr;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (UhciIsHalted(fpHCStruc)) {
+ return USB_ERROR;
+ }
+
+ wIOAddr = (UINT16)fpHCStruc->BaseAddress;
+
+//(USB0061+)>
+ //
+ // Check whether USB host controllers are accessible to aVOID system
+ // hang in ports enumeration.
+ //
+ if (ByteReadIO(wIOAddr) == 0xFF) return USB_ERROR;
+//<(USB0061+)
+ //
+ // Check whether enumeration is already began
+ //
+ if(gUsbData->bEnumFlag == TRUE) return USB_SUCCESS;
+
+ gUsbData->bEnumFlag = TRUE;
+ bHCNumber = (UINT8)(fpHCStruc->bHCNumber | BIT7);
+ //(EIP61385)>
+ //
+ // Process Port#1 and clear Port#1 status bit
+ //
+ wPortAddr = wIOAddr + UHCI_PORT1_CONTROL;
+ if ((WordReadIO(wPortAddr) & (UHC_CONNECT_STATUS_CHANGE |
+ UHC_CONNECT_STATUS)) == UHC_CONNECT_STATUS_CHANGE) {
+ WordWriteIO(wPortAddr, UHC_CONNECT_STATUS_CHANGE);
+ }
+ USBCheckPortChange(fpHCStruc, bHCNumber, 1);
+ WordWriteIO(wPortAddr, WordReadIO(wPortAddr));
+
+ //
+ // Process Port#2 and clear Port#2 status bit
+ //
+ wPortAddr = wIOAddr + UHCI_PORT2_CONTROL;
+ if ((WordReadIO(wPortAddr) & (UHC_CONNECT_STATUS_CHANGE |
+ UHC_CONNECT_STATUS)) == UHC_CONNECT_STATUS_CHANGE) {
+ WordWriteIO(wPortAddr, UHC_CONNECT_STATUS_CHANGE);
+ }
+ USBCheckPortChange(fpHCStruc, bHCNumber, 2);
+ WordWriteIO(wPortAddr, WordReadIO(wPortAddr));
+ //<(EIP61385)
+ gUsbData->bEnumFlag = FALSE;
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_DisableInterrupts
+//
+// Description:
+// This API function is called to disable the interrupts generated by the UHCI
+// host controller. The input to the routine is the pointer to the HC structure
+// that defines this host controller.
+//
+// Input:
+// fpHCStruc Ptr to the host controller structure
+//
+// Output:
+// Status: USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_DisableInterrupts (HC_STRUC* fpHCStruc)
+{
+ UINT8 IntEnReg;
+ UINT16 IoAddr = (UINT16)fpHCStruc->BaseAddress;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ IntEnReg = ByteReadIO((UINT16)(IoAddr + UHCI_INTERRUPT_ENABLE));
+ IntEnReg &= ~(UHC_IOC_ENABLE);
+ ByteWriteIO((UINT16)(IoAddr + UHCI_INTERRUPT_ENABLE), IntEnReg);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_EnableInterrupts
+//
+// Description:
+// This function enables the HC interrupts
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+//
+// Output:
+// USB_SUCCESS of USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_EnableInterrupts (HC_STRUC* fpHCStruc)
+{
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_ProcessInterrupt
+//
+// Description:
+// This function is called when the USB interrupt bit is set. This function
+// will parse through the TDs and QHs to find out completed TDs and call
+// their respective callback functions.
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+//
+// Output:
+// USB_ERROR - Need more Interrupt processing
+// USB_SUCCESS - No interrupts pending
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_ProcessInterrupt(
+ HC_STRUC *HcStruc
+)
+{
+ UINT16 IoPort = (UINT16)HcStruc->BaseAddress;
+ UINT16 LegSupReg = 0;
+ UINT16 UsbSts = 0;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (!(HcStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ LegSupReg = (UINT16)ReadPCIConfig(HcStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP);
+ if (!(LegSupReg & BIT4)) {
+ return USB_ERROR;
+ }
+ }
+#endif
+
+ //
+ // Check whether the controller is still under BIOS control
+ // Read the frame list base address and compare with stored value
+ //
+ if (((UINTN)DwordReadIO(IoPort + UHCI_FRAME_LIST_BASE) & 0xFFFFF000) !=
+ (UINTN)HcStruc->fpFrameList) {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (!(HcStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ // Disable the SMI on IRQ enable bit
+ WordWritePCIConfig(HcStruc->wBusDevFuncNum, USB_UHCI_REG_LEGSUP, LegSupReg & ~BIT4);
+ }
+#endif
+ return USB_ERROR; // Control is not with us anymore
+ }
+
+ UsbSts = WordReadIO(IoPort + UHCI_STATUS_REG);
+
+ if (UsbSts & UHC_HC_HALTED) {
+ return USB_ERROR;
+ }
+
+ if (UsbSts & UHC_USB_INTERRUPT) {
+ WordWriteIO(IoPort + UHCI_STATUS_REG, UsbSts);
+ UhciProcessFrameList(HcStruc);
+ }
+
+ if (HcStruc->dHCFlag & HC_STATE_EXTERNAL) {
+ UhciRootHubQhCallBack(HcStruc, NULL, NULL, NULL, 0);
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_GetRootHubStatus
+//
+// Description:
+// This function returns the port connect status for the root hub port
+//
+// Input:
+// pHCStruc Pointer to HCStruc of the host controller
+// bPortNum Port in the HC whose status is requested
+//
+// Output:
+// NewPortNum Port in the HC that can possibly replace bPortNum
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_GetRootHubStatus(
+ HC_STRUC* fpHCStruc,
+ UINT8 bPortNum,
+ BOOLEAN ClearChangeBits
+)
+{
+ UINT16 wPortAddr, wPortStatus, wPortTemp;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ wPortStatus = USB_PORT_STAT_DEV_OWNER;
+ wPortAddr = (UINT16)((bPortNum<<1)+UHCI_PORT1_CONTROL-2+fpHCStruc->BaseAddress);
+
+ //
+ // Read the port status
+ //
+ wPortTemp = WordReadIO(wPortAddr);
+ USB_DEBUG(3, "UHCI port[%d] status: %04x\n", bPortNum, wPortTemp);
+
+ //
+ // Check for port connect status
+ //
+ if (wPortTemp & UHC_CONNECT_STATUS) {
+ wPortStatus |= USB_PORT_STAT_DEV_CONNECTED;
+
+ //
+ // Identify the speed of the device (full or low speed)
+ //
+ if (wPortTemp & UHC_LOW_SPEED_ATTACHED) {
+ wPortStatus |= USB_PORT_STAT_DEV_LOWSPEED;
+ }
+ else {
+ wPortStatus |= USB_PORT_STAT_DEV_FULLSPEED;
+ }
+
+ if (wPortTemp & UHC_PORT_ENABLE) {
+ wPortStatus |= USB_PORT_STAT_DEV_ENABLED;
+ }
+ }
+
+ //
+ // Check for connect status change
+ //
+ if (wPortTemp & UHC_CONNECT_STATUS_CHANGE) {
+ wPortStatus |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ if (ClearChangeBits == TRUE) {
+ WordWriteIO(wPortAddr, UHC_CONNECT_STATUS_CHANGE); //(EIP61385+)
+ }
+ }
+
+ return (UINT8)wPortStatus;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_DisableRootHub
+//
+// Description:
+// This function disables the root hub of the UHCI controller.
+//
+// Input:
+// fpHCStruc Pointer to HCStruc of the host controller
+// bPortNum Root port to be disabled
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_DisableRootHub (HC_STRUC* fpHCStruc,UINT8 bPortNum)
+{
+ UINT16 wPortAddr =
+ (UINT16)(fpHCStruc->BaseAddress + (bPortNum << 1) + UHCI_PORT1_CONTROL - 2);
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ //
+ // Reset the enable bit
+ //
+ WordWriteIO(
+ wPortAddr,
+ (UINT16)(WordReadIO(wPortAddr) & (~UHC_PORT_ENABLE)));
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_EnableRootHub
+//
+// Description:
+// This function enables the root hub port specified
+//
+// Input:
+// fpHCStruc Pointer to HCStruc of the host controller
+// bPortNum Root port to be enabled
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_EnableRootHub (
+ HC_STRUC *HcStruc,
+ UINT8 PortNum)
+{
+ UINT16 PortStatus;
+ UINT16 PortAddr =
+ (UINT16)(HcStruc->BaseAddress + (PortNum << 1) + UHCI_PORT1_CONTROL - 2);
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ PortStatus = WordReadIO(PortAddr);
+
+ //
+ // Set the enable & reset bit, preserve Connect Status Change bit
+ //
+ PortStatus &= ~(UHC_CONNECT_STATUS_CHANGE | UHC_PORT_ENABLE_CHANGE);
+ WordWriteIO(PortAddr, PortStatus | UHC_PORT_RESET);
+
+ //
+ // Wait for 10ms
+ //
+ FixedDelay(10 * 1000); // 10msec delay
+
+ //
+ // Clear the reset bit and set the enable, preserve Connect Status Change bit
+ //
+ PortStatus = WordReadIO(PortAddr);
+ PortStatus &= ~(UHC_CONNECT_STATUS_CHANGE | UHC_PORT_ENABLE_CHANGE);
+ WordWriteIO(PortAddr, PortStatus & (~UHC_PORT_RESET));
+
+ // Wait 1 ms for stabilize the port status
+ FixedDelay(1 * 1000); // 1 ms delay
+
+ // Clear Connect Status Change bit and Port Enable Change bit
+ WordWriteIO(PortAddr, WordReadIO(PortAddr));
+
+ //
+ // Set the enable bit
+ //
+ PortStatus = WordReadIO(PortAddr);
+ PortStatus &= ~(UHC_CONNECT_STATUS_CHANGE | UHC_PORT_ENABLE_CHANGE);
+ WordWriteIO(PortAddr, PortStatus | UHC_PORT_ENABLE);
+
+ //
+ // Wait for 100ms
+ //
+ //FixedDelay(gUsbData->UsbTimingPolicy.UhciPortEnable * 1000); // 100msec delay
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_ResetRootHub
+//
+// Description:
+// This function resets the UHCI HC root hub port
+//
+// Input:
+// HcStruc Pointer to HCStruc of the host controller
+// PortNum Root port to be enabled
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_ResetRootHub (
+ HC_STRUC* HcStruc,
+ UINT8 PortNum)
+{
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UHCI_GlobalSuspend
+//
+// Description:
+// This function suspend the UHCI HC.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_GlobalSuspend(
+ HC_STRUC* HcStruc
+)
+{
+
+ UINT16 IoAddr = (UINT16)HcStruc->BaseAddress;
+ UINT16 UhciCommand;
+ UINT16 UhciStatus;
+ UINT32 i;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (UhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ UhciCommand = WordReadIO(IoAddr + UHCI_COMMAND_REG);
+ UhciCommand &= ~UHC_HOST_CONTROLLER_RUN;
+ WordWriteIO(IoAddr + UHCI_COMMAND_REG, UhciCommand);
+ for (i = 0; i < 1024; i++) {
+ UhciStatus = WordReadIO(IoAddr + UHCI_STATUS_REG);
+ if (UhciStatus & UHC_HC_HALTED) {
+ break;
+ }
+ FixedDelay(1 * 1000);
+ }
+
+ WordWriteIO((UINT16)(IoAddr + UHCI_INTERRUPT_ENABLE), UHC_RESUME_ENABLE);
+
+ UhciStatus = WordReadIO(IoAddr + UHCI_STATUS_REG);
+ UhciStatus |= 0x1F;
+ WordWriteIO(IoAddr + UHCI_STATUS_REG, UhciStatus);
+
+ UhciCommand = WordReadIO(IoAddr + UHCI_COMMAND_REG);
+ UhciCommand |= UHC_ENTER_SUSPEND;
+ WordWriteIO(IoAddr + UHCI_COMMAND_REG, UhciCommand);
+ FixedDelay(50 * 1000);
+
+ HcStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+ HcStruc->dHCFlag |= HC_STATE_SUSPEND;
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhciExecuteTransfer
+//
+// Description:
+// This function execites a transfer and waits for the completion of
+// the transfer, and returns the transfer results.
+//
+// Input:
+// Pointers to the first data TD and last data TD in the TD list
+//
+// Output:
+// Return value is the size of transferred data, Bytes
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+UhciExecuteTransfer (
+ HC_STRUC *HcStruc,
+ UHCI_QH *TransferQh
+)
+{
+ UINT32 Timeout = gUsbData->wTimeOutValue * 100; // *100, makes it number of 10 usec units
+ BOOLEAN InfiniteLoop = (Timeout == 0);
+
+ TransferQh->ActiveFlag = TRUE;
+ UhciAddQhToFrameList(HcStruc, TransferQh);
+
+ while (InfiniteLoop || Timeout--) {
+ UhciProcessQh(HcStruc, TransferQh);
+ if (TransferQh->ActiveFlag == FALSE) {
+ break;
+ }
+
+ FixedDelay(10); // 10 microseconds
+ }
+
+ UhciRemoveQhFromFrameList(HcStruc, TransferQh);
+ UhciProcessQh(HcStruc, TransferQh);
+
+ if (TransferQh->ActiveFlag) {
+ USB_DEBUG (DEBUG_LEVEL_3, "UHCI Time-Out\n");
+ }
+
+ return TransferQh->BytesTransferred;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_ControlTransfer
+//
+// Description:
+// This function executes a device request command transaction on the USB. One
+// setup packet is generated containing the device request parameters supplied
+// by the caller. The setup packet may be followed by data in or data out packets
+// containing data sent from the host to the device or vice-versa. This function
+// will not return until the request either completes successfully or completes in
+// error (due to time out, etc.)
+//
+// Input:
+// fpHCStruc Pointer to HCStruc of the host controller
+// pDevInfo DeviceInfo structure (if available else 0)
+// wRequest Request type (low byte)
+// Bit 7 : Data direction
+// 0 = Host sending data to device
+// 1 = Device sending data to host
+// Bit 6-5 : Type
+// 00 = Standard USB request
+// 01 = Class specific
+// 10 = Vendor specific
+// 11 = Reserved
+// Bit 4-0 : Recipient
+// 00000 = Device
+// 00001 = Interface
+// 00010 = Endpoint
+// 00100 - 11111 = Reserved
+// Request code, a one byte code describing
+// the actual device request to be executed
+// (ex: Get Configuration, Set Address etc)
+// wIndex wIndex request parameter (meaning varies)
+// wValue wValue request parameter (meaning varies)
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// wLength wLength request parameter, number of bytes
+// of data to be transferred in or out
+// of the host controller
+//
+//
+// Output:
+// Number of bytes transferred: 0 - Failure, <>0 - Success
+//
+//
+// Notes:
+// Do not use USB_SUCCESS or USB_ERROR as returned values
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+UHCI_ControlTransfer (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT16 wRequest,
+ UINT16 wIndex,
+ UINT16 wValue,
+ UINT8 *fpBuffer,
+ UINT16 wLength)
+{
+ UINT16 wTemp;
+ UINT32 dTemp;
+ UINT32 dValue;
+
+ DEV_REQ *fpDevReq;
+ UHCI_TD *SetupTd = NULL;
+ UHCI_TD *DataTDs = NULL;
+ UHCI_TD *StatusTd = NULL;
+ UHCI_TD *LastTd = NULL;
+ UHCI_TD *CurrentTd = NULL;
+ UHCI_QH *CtrlQh;
+ UINT16 NumDataTDs = 0;
+ UINT16 BytesRemaining;
+ UINT16 BytesTransferred;
+ UINT8 DataToggle;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ if (wLength != 0) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Uhci ControlTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (UhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ if (!VALID_DEVINFO(fpDevInfo)) return 0;
+
+ gUsbData->bLastCommandStatus &= ~( USB_CONTROL_STALLED );
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ //
+ // Allocate TDs for control setup and control status packets
+ //
+ SetupTd = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ if(SetupTd == NULL) {
+ return 0;
+ }
+
+ //
+ // Build the device request in the data area of the control setup TD
+ //
+ fpDevReq = (DEV_REQ*)SetupTd->aDataArea;
+ fpDevReq->wRequestType = wRequest;
+ fpDevReq->wValue = wValue;
+ fpDevReq->wIndex = wIndex;
+ fpDevReq->wDataLength = wLength;
+
+ //
+ // dTemp will contain the device address and endpoint shifted and ready to go
+ // into the TDs' token field.
+ // 10:0] = Dev. Addr & Endpoint
+ // [18:8] = Dev. Addr & Endpoint
+ //
+ dTemp = ((UINT32)(fpDevInfo->bDeviceAddress)) << 8;
+
+ //
+ // Fill in various fields in the control setup TD.
+ // The LinkPointer field will point to the control data TD if data will
+ // be sent/received or to the control status TD if no data is expected.
+ // The ControlStatus field will be set to active and interrupt on complete.
+ // The Token field will contain the packet size (size of DeviceRequest
+ // struc), the device address, endpoint, and a setup PID.
+ // The BufferPointer field will point to the TD's DataArea buffer which
+ // was just initialized to contain a DeviceRequest struc.
+ // The CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // The pCallback will be set to point to the UHCI_ControlTDCallback routine.
+ // The ActiveFlag field will be set to TRUE.
+ //
+
+ //
+ // 11/01/10 for HI/LO/FULL
+ //
+ dValue = (((UINT32)fpDevInfo->bEndpointSpeed) & 1) << 26;
+ //(EIP34448)>
+ dValue |= (UINT32)(UHCI_TD_THREE_ERRORS | UHCI_TD_ACTIVE);
+ //<(EIP34448)
+
+ SetupTd->dControlStatus = dValue;
+
+ dValue = dTemp |
+ ((UINT32)UHCI_TD_SETUP_PACKET |
+ ((UINT32)(sizeof(DEV_REQ) - 1) << 21));
+
+ //
+ // Set PID=Setup, and MaxLen
+ //
+ SetupTd->dToken = dValue;
+ SetupTd->pBufferPtr = (UINT32)(UINTN)SetupTd->aDataArea;
+ SetupTd->dCSReload = 0;
+ SetupTd->bActiveFlag = 1;
+
+ LastTd = SetupTd;
+ //
+ // Fill in various fields in the control data TD.
+ // Enough control data TDs must be initialized to handle the amount of
+ // data expected. The length of the data transfer is currently in wLength.
+ // LinkPointer field will be set to the next data TD or the status TD.
+ // ControlStatus field will be se to active and interrupt on complete.
+ // Token field will contain the data transfer size (still in wLength), device
+ // address (in pDevInfo), endpoint (in dTemp), and an in or out PID
+ // (in wReqType).
+ // BufferPointer field will point to the data buffer passed in by the
+ // caller (currently in fpBuffer).
+ // CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // pCallback will be set to point to the UHCI_ControlTDCallback routine.
+ // ActiveFlag field will be set to TRUE.
+ //
+ if(wLength) {
+ NumDataTDs = wLength / fpDevInfo->wEndp0MaxPacket;
+ if (wLength % fpDevInfo->wEndp0MaxPacket) {
+ NumDataTDs++;
+ }
+
+ DataTDs = USB_MemAlloc(GET_MEM_BLK_COUNT(NumDataTDs * sizeof(UHCI_TD)));
+ if (DataTDs == NULL) {
+ USB_MemFree(SetupTd, GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ return 0;
+ }
+
+ CurrentTd = DataTDs;
+
+ DataToggle = 1;
+ BytesRemaining = wLength;
+
+ //
+ // Allocate one more TD to be used either for more data or for TD Status
+ //
+ do {
+ //
+ // 11/01/10 for HI/LO/FULL
+ //
+ dValue = (((UINT32)(fpDevInfo->bEndpointSpeed) & 1) << 26);
+ dValue = dValue |
+ (UINT32)(UHCI_TD_THREE_ERRORS | UHCI_TD_ACTIVE);
+ if(wRequest & BIT7) {
+ dValue |= UHCI_TD_SHORT_PACKET_DETECT;
+ }
+ CurrentTd->dControlStatus = dValue;
+ CurrentTd->pBufferPtr = (UINT32)(UINTN)fpBuffer;
+ wTemp = (UINT16)((BytesRemaining > (fpDevInfo->wEndp0MaxPacket)) ?
+ fpDevInfo->wEndp0MaxPacket : BytesRemaining);
+ //
+ // Packet size is valid
+ //
+ BytesRemaining = (UINT16)(BytesRemaining - wTemp);
+ fpBuffer = fpBuffer + wTemp;
+ --wTemp;
+
+ //
+ // [18:8]=Dev. addr & endp
+ //
+ dValue = dTemp | (((UINT32)wTemp) << 21);
+ dValue = (dValue & 0xFFFFFF00) | UHCI_TD_OUT_PACKET;
+
+ if(wRequest & BIT7)
+ {
+ dValue = (dValue & 0xFFFFFF00) | UHCI_TD_IN_PACKET;
+ }
+ if(DataToggle & 1)
+ {
+ dValue = dValue | UHCI_TD_DATA_TOGGLE; // Make packet into a data 1
+ }
+ CurrentTd->dToken = dValue;
+ CurrentTd->dCSReload = 0;
+ CurrentTd->bActiveFlag = 1;
+
+ LastTd->pLinkPtr = (UINT32)((UINTN)CurrentTd | UHCI_VERTICAL_FLAG);
+ LastTd = CurrentTd;
+ CurrentTd++;
+
+ DataToggle ^= 1;
+ } while (BytesRemaining); // End the data TD list
+ }
+ //
+ // Fill in various fields in the TD control status.
+ // LinkPointer field will point to TERMINATE.
+ // ControlStatus field will be set to active and interrupt on complete.
+ // Token field will contain the packet size (0), the device address,
+ // endpoint, and a setup PID with opposite data direction as that defined
+ // in the request type (wReqType).
+ // BufferPointer field will point to the TD's DataArea buffer even though
+ // we are not expecting any data transfer.
+ // CSReloadValue field will contain 0 because this is a "one shot" packet.
+ // pCallback will be set to point to the UHCI_ControlTDCallback routine.
+ // ActiveFlag field will be set to TRUE.
+ //
+ StatusTd = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ if (StatusTd == NULL) {
+ return 0;
+ }
+
+ LastTd->pLinkPtr = (UINT32)((UINTN)StatusTd | UHCI_VERTICAL_FLAG);
+ LastTd = StatusTd;
+ StatusTd->pLinkPtr = UHCI_TERMINATE;
+ dValue = (((UINT32)(fpDevInfo->bEndpointSpeed) & 1) << 26);
+ //(EIP34448)>
+ dValue = dValue | (UINT32)(UHCI_TD_THREE_ERRORS | UHCI_TD_ACTIVE);
+ //<(EIP34448)
+ StatusTd->dControlStatus = dValue;
+ dValue = dTemp;
+ dValue = (dValue & 0xFFFFFF00) | (UINT32)UHCI_TD_OUT_PACKET;
+ if((wRequest & BIT7) == 0)
+ {
+ dValue = (dValue & 0xFFFFFF00) | (UINT32)UHCI_TD_IN_PACKET;
+ }
+ dValue |= (UHCI_TD_DATA_TOGGLE | ((UINT32)UHCI_TD_ACTUAL_LENGTH << 21));
+ StatusTd->dToken = dValue;
+ dValue = (UINT32)(UINTN)StatusTd->aDataArea;
+ StatusTd->pBufferPtr = dValue;
+ StatusTd->dCSReload = 0;
+ StatusTd->bActiveFlag = 1;
+ //
+ // Now put the control setup, data and status into the HC's schedule by
+ // pointing QhControl's link pointer to control setup TD.
+ // This will cause the HC to execute the transaction in the next active frame.
+
+ CtrlQh = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+ if (CtrlQh == NULL) {
+ return 0;
+ }
+
+ UhciInitQh(CtrlQh);
+ CtrlQh->pElementPtr = (UINT32)(UINTN)SetupTd;
+ CtrlQh->CurrentTd = SetupTd;
+ CtrlQh->Type = Control;
+ CtrlQh->FirstTd = SetupTd;
+
+ // Wait till transfer complete
+ BytesTransferred = UhciExecuteTransfer(fpHCStruc, CtrlQh);
+
+ // Calculate the transferred length
+ BytesTransferred -= (((SetupTd->dControlStatus & UHCI_TD_ACTUAL_LENGTH) + 1) & 0x7FF);
+
+ // Save error information in global variable
+ gUsbData->dLastCommandStatusExtended =
+ (CtrlQh->CurrentTd->dControlStatus & UHCI_TD_STATUS_FIELD) >> 17;
+
+ if (CtrlQh->CurrentTd->dControlStatus & UHCI_TD_STALLED ){
+ gUsbData->bLastCommandStatus |= USB_CONTROL_STALLED;
+ BytesTransferred = 0;
+ }
+
+ USB_MemFree(SetupTd, GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ if (DataTDs) {
+ USB_MemFree(DataTDs, GET_MEM_BLK_COUNT(NumDataTDs * sizeof(UHCI_TD)));
+ }
+ USB_MemFree(StatusTd, GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ USB_MemFree(CtrlQh, GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+
+ return BytesTransferred;
+} // UHCI_ControlTransfer
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_InitBulkTdCommon
+//
+// Description:
+// This function creates a chain of two TDs for bulk data transfer. It fills
+// in the following fields in TD:
+// pLinkPtr - NextTd address
+// dToken - All bits except length and data toggle
+//
+// Input:
+// BulkDataTd0 1st TD in the chain
+// BulkDataTd1 2nd TD in the chain
+// TokenData Data for dToken
+// NumBulkTds # of bulk TDs
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UHCI_InitBulkTdCommon (
+ UHCI_TD *BulkDataTd0,
+ UINT32 TokenData,
+ UINT16 NumBulkTds
+)
+{
+ UINT16 i;
+ UHCI_TD *Td0 = BulkDataTd0;
+ UHCI_TD *Td1 = Td0;
+ UINT16 NumTd = NumBulkTds*2;
+
+ for (i=0; i<NumTd; i++)
+ {
+ Td0 = Td1;
+ Td0->dToken = TokenData;
+ Td1 = (UHCI_TD*)((UINTN)Td0 + sizeof(UHCI_TD));
+ Td0->pLinkPtr = (UINT32)(UINTN)Td1 | UHCI_VERTICAL_FLAG;
+ }
+ // Terminated later in UHCI_InitBulkDataTds
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_InitBulkDataTds
+//
+// Description:
+// This function initializes the fields in bulk data TD list that remain after
+// UHCI_InitBulkTdCommon:
+// - Data buffer pointer
+// - Data length
+// - Data toggle (DAT0/DAT1)
+//
+// Output:
+// Pointer to the last TD in the chain
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UHCI_TD*
+UHCI_InitBulkDataTds(
+ IN UHCI_TD *BulkDataTd,
+ IN UINT16 MaxPkt,
+ IN UINT32 EndpointSpeed,
+ IN OUT UINT32 *Address,
+ IN OUT UINT8 *DatToggle,
+ IN OUT UINT32 *BytesRemaining,
+ IN UINT16 NumBulkTds
+)
+{
+ UINT16 i;
+ UINT32 Length = *BytesRemaining;
+ UHCI_TD *Td = BulkDataTd;
+ UINT32 Addr = *Address;
+ UINT8 Toggle = *DatToggle;
+ BOOLEAN TheLastTd = FALSE;
+
+ for (i = 0; i < NumBulkTds; i++)
+ {
+ Length = *BytesRemaining;
+
+ if (Length > (UINT32)MaxPkt)
+ {
+ Length = (UINT32)MaxPkt;
+ }
+ else
+ {
+ TheLastTd = TRUE;
+ }
+ Td->dToken &= 0x1FFFFF;
+ Td->dToken |= (Length - 1) << 21;
+
+ Td->dToken &= ~UHCI_TD_DATA_TOGGLE; // Make packet go into DAT0
+ if (Toggle == 1)
+ {
+ Td->dToken |= UHCI_TD_DATA_TOGGLE; // Make packet go into DAT1
+ }
+
+ Td->dControlStatus = EndpointSpeed |
+ (UHCI_TD_THREE_ERRORS | UHCI_TD_ACTIVE);
+ if ((Td->dToken & UHCI_TD_PACKET_ID) == UHCI_TD_IN_PACKET) {
+ Td->dControlStatus |= UHCI_TD_SHORT_PACKET_DETECT;
+ }
+
+ Td->pBufferPtr = Addr;
+ Addr += MaxPkt;
+ Toggle ^= 1;
+ Td = (UHCI_TD*)((UINTN)Td + sizeof(UHCI_TD));
+ *BytesRemaining -= Length;
+
+ if (TheLastTd) break;
+ }
+
+ Td = (UHCI_TD*)((UINTN)Td - sizeof(UHCI_TD));
+ Td->pLinkPtr = UHCI_TERMINATE;
+
+ *Address = Addr;
+ *DatToggle = Toggle;
+
+ return Td;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_BulkTransfer
+//
+// Description:
+// This function executes a bulk transaction on the USB. The transfer may be
+// either DATA_IN or DATA_OUT packets containing data sent from the host to
+// the device or vice-versa. This function wil not return until the request
+// either completes successfully or completes with error (due to time out, etc.)
+//
+// Input:
+// HcStruc Pointer to HCStruc of the host controller
+// DevInfo DeviceInfo structure (if available else 0)
+// XferDir Transfer direction
+// Bit 7: Data direction
+// 0 Host sending data to device
+// 1 Device sending data to host
+// Bit 6-0 : Reserved
+// Buffer Buffer containing data to be sent to the device or buffer to be
+// used to receive data value in Segment:Offset format
+// Length Length request parameter, number of bytes of data to be transferred
+// in or out of the host controller
+//
+// Output:
+// Amount of data transferred
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+UHCI_BulkTransfer (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 XferDir,
+ UINT8 *Buffer,
+ UINT32 Length
+)
+{
+ UINT16 MaxPkt;
+ UINT8 Endp;
+ UINT32 Data;
+ UINT8 DatToggle;
+ UINT32 TransferError;
+ UHCI_QH *BulkQh;
+ UHCI_TD *BulkDataTd;
+ UHCI_TD *NextBulkDataTd;
+ UHCI_TD *BulkDataTd0;
+ UHCI_TD *BulkDataTd1;
+ UHCI_TD *LastTd;
+ UHCI_TD *NextLastTd;
+ UINT16 NumAllocTDs;
+ UINT16 NumBulkTDs;
+ UINT32 BytesRemaining;
+ UINT32 BytesTransferred;
+ UINT32 BytesTransferredNow;
+ UINT32 Address;
+ UINT32 Eps;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Buffer, Length);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Uhci BulkTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (UhciIsHalted(HcStruc)) {
+ return 0;
+ }
+
+ if ( !VALID_DEVINFO( DevInfo) ) return 0;
+
+ if (Length == 0) return 0;
+
+ // Clear HW source of error
+ gUsbData->bLastCommandStatus &= ~(USB_BULK_STALLED | USB_BULK_TIMEDOUT );
+ gUsbData->dLastCommandStatusExtended = 0;
+ //
+ // Get Bulk IN/OUT enpoint number, data sync value & max packet size
+ // Store the appropriate max packet size and endpoint number
+ // in the local variables
+ //
+ MaxPkt = (XferDir & BIT7)? DevInfo->wBulkInMaxPkt : DevInfo->wBulkOutMaxPkt;
+
+ if (MaxPkt == 0) return 0;
+
+ Endp = (XferDir & BIT7)? DevInfo->bBulkInEndpoint : DevInfo->bBulkOutEndpoint;
+
+ //
+ // For multiple LUN devices toggle is maintained by LUN0
+ //
+ DatToggle = UsbGetDataToggle(DevInfo, Endp | XferDir);
+
+ //
+ // Form TD token data, less the transfer length and toggle information
+ //
+ Data = (UINT32)Endp << 7;
+ Data = (Data | DevInfo->bDeviceAddress) << 8;
+ Data = (XferDir & BIT7)? Data | UHCI_TD_IN_PACKET : Data | UHCI_TD_OUT_PACKET;
+
+ BulkQh = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+ if (BulkQh == NULL) return 0;
+
+ BulkQh->Type = Bulk;
+
+ // Allocate data TDs.
+ NumBulkTDs = FULLSPEED_MAX_BULK_DATA_SIZE_PER_FRAME/MaxPkt;
+ ASSERT(NumBulkTDs != 0);
+
+ NumAllocTDs = NumBulkTDs*2;
+
+ BulkDataTd0 = (UHCI_TD*)USB_MemAlloc(GET_MEM_BLK_COUNT(NumAllocTDs * sizeof(UHCI_TD)));
+ ASSERT(BulkDataTd0 != NULL);
+
+ UHCI_InitBulkTdCommon (BulkDataTd0, Data, NumBulkTDs);
+
+ BulkDataTd1 = (UHCI_TD*)((UINTN)BulkDataTd0 + (NumBulkTDs * sizeof(UHCI_TD)));
+
+ BulkDataTd = BulkDataTd0;
+ NextBulkDataTd = BulkDataTd1;
+ BytesRemaining = Length;
+ BytesTransferred = 0;
+ BytesTransferredNow = 0;
+ Address = (UINT32)(UINTN)Buffer;
+ TransferError = 0;
+ Eps = ((UINT32)(DevInfo->bEndpointSpeed) & 1) << 26;
+
+ LastTd = UHCI_InitBulkDataTds(
+ BulkDataTd, MaxPkt, Eps, &Address, &DatToggle, &BytesRemaining, NumBulkTDs);
+ NextLastTd = LastTd;
+
+ do {
+ // Start the transfer by adding TD in the bulk queue head
+ UhciInitQh(BulkQh);
+ BulkQh->pElementPtr = (UINT32)(UINTN)BulkDataTd;
+ BulkQh->CurrentTd = BulkDataTd;
+ BulkQh->FirstTd = BulkDataTd;
+
+ // Initialize the next TD block and wait for the current one to complete.
+ // In case MaxPkt is 64 Bytes, we have approx. NumBulkTDs*50mcs for this.
+ if (BytesRemaining != 0) {
+ NextLastTd = UHCI_InitBulkDataTds(
+ NextBulkDataTd, MaxPkt, Eps, &Address, &DatToggle, &BytesRemaining, NumBulkTDs);
+ }
+
+ // Wait til BulkDataTd is complete, check for errors
+ BytesTransferredNow = UhciExecuteTransfer(HcStruc, BulkQh);
+
+ DatToggle = BulkQh->DataToggle;
+ TransferError = (BulkQh->CurrentTd->dControlStatus & UHCI_TD_STATUS_FIELD) >> 17;
+ if (TransferError) {
+ break;
+ }
+ BytesTransferred += BytesTransferredNow;
+
+ NextBulkDataTd = BulkDataTd;
+ LastTd = NextLastTd;
+ BulkDataTd = (BulkDataTd == BulkDataTd0)? BulkDataTd1 : BulkDataTd0;
+
+ } while ((BytesTransferred < Length) && !BulkQh->ShortPacketDetected);
+
+ UsbUpdateDataToggle(DevInfo, Endp | XferDir, DatToggle);
+ gUsbData->dLastCommandStatusExtended = TransferError;
+ if (BulkQh->CurrentTd->dControlStatus & UHCI_TD_STALLED){
+ gUsbData->bLastCommandStatus |= USB_BULK_STALLED;
+ }
+ if (BulkQh->CurrentTd->dControlStatus & UHCI_TD_ACTIVE) {
+ gUsbData->bLastCommandStatus |= USB_BULK_TIMEDOUT;
+ }
+ //
+ // Deallocate memory and return the transferred data size
+ //
+ USB_MemFree(BulkDataTd0, GET_MEM_BLK_COUNT(NumAllocTDs * sizeof(UHCI_TD)));
+ USB_MemFree(BulkQh, GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+
+ return BytesTransferred;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_InterruptTransfer
+//
+// Description:
+// This function executes an interrupt transaction on the USB. The data transfer
+// direction is always DATA_IN. This function wil not return until the request
+// either completes successfully or completes in error (due to time out, etc.)
+//
+// Input:
+// fpHCStruc Pointer to HCStruc of the host controller
+// fpDevInfo DeviceInfo structure (if available else 0)
+// EndpointAddress The destination USB device endpoint to which the device request
+// is being sent.
+// MaxPktSize Indicates the maximum packet size the target endpoint is capable
+// of sending or receiving.
+// fpBuffer Buffer containing data to be sent to the device or buffer to be
+// used to receive data
+// wLength wLength request parameter, number of bytes of data to be transferred
+//
+// Output:
+// Number of bytes transferred
+//
+//
+// Notes:
+// DO NOT TOUCH THE LINK POINTER OF THE TDInterruptData. It is statically allocated
+// and linked with other items in the 1ms schedule
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+UHCI_InterruptTransfer(
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 EndpointAddress,
+ UINT16 MaxPktSize,
+ UINT8 *fpBuffer,
+ UINT16 wLength)
+{
+ UINT8 bEndp;
+ UINT8 DataToggle;
+ UINT32 dTemp, dValue;
+ UHCI_QH *IntQh;
+ UHCI_TD *IntTd;
+ UINT32 BytesTransferred;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Uhci InterruptTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (UhciIsHalted(fpHCStruc)) {
+ return 0;
+ }
+
+ if( !VALID_DEVINFO( fpDevInfo) )
+ return 0;
+
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ //
+ // Check for 0 length transfer (if so, exit)
+ //
+ if(wLength == 0) {
+ return 0;
+ }
+
+ //
+ // Store the descriptor pointer in a local variable
+ //
+ IntTd = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ if (IntTd == NULL) {
+ return 0;
+ }
+
+ IntTd->pLinkPtr = UHCI_TERMINATE;
+
+ //
+ // It is an interrupt IN transaction get appropriate size
+ //
+ bEndp = EndpointAddress & 0xF;
+ DataToggle = UsbGetDataToggle(fpDevInfo, EndpointAddress);
+
+ //
+ // Form device address and endpoint in proper order and bit position
+ //
+ dTemp = (UINT32)bEndp << 7;
+ dTemp = (dTemp | (fpDevInfo->bDeviceAddress)) << 8; //[10:0] = Dev. Addr & Endpoint
+ //[18:8] = Dev. Addr & Endpoint
+ //
+ // Fill in various fields in the interrupt data TD
+ //
+ IntTd->dControlStatus = (((UINT32)(fpDevInfo->bEndpointSpeed) & 1) << 26) |
+ UHCI_TD_THREE_ERRORS | UHCI_TD_ACTIVE;
+ //
+ // Set the buffer pointer. Note that currently UHCI Interrupt Transfer
+ // implementation assumes IN packet; the direction is not passed here as
+ // parameter. Should this change in future, make a branch to use
+ // UHCI_TD_OUT_PACKET while constructing dToken.
+ //
+ IntTd->pBufferPtr = (UINT32)(UINTN)fpBuffer;
+ dValue = (UINT32)(wLength - 1);
+ dValue = ((dValue << 21) | dTemp) & 0xffffff00;
+ dValue |= EndpointAddress & BIT7 ? UHCI_TD_IN_PACKET :
+ UHCI_TD_OUT_PACKET;
+
+ if(DataToggle & 1) {
+ dValue |= UHCI_TD_DATA_TOGGLE; // Make packet into a data 1
+ }
+
+ IntTd->dToken = dValue;
+ IntTd->dCSReload = 0;
+ IntTd->bActiveFlag = 1;
+
+ IntQh = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+ if (IntQh == NULL) {
+ return 0;
+ }
+
+ UhciInitQh(IntQh);
+ IntQh->pElementPtr = (UINT32)(UINTN)IntTd;
+ IntQh->CurrentTd = IntTd;
+ IntQh->Type = Interrupt;
+ IntQh->FirstTd = IntTd;
+ IntQh->Interval = UhciTranslateInterval(fpDevInfo->bPollInterval);
+
+ BytesTransferred = UhciExecuteTransfer(fpHCStruc, IntQh);
+
+ gUsbData->dLastCommandStatusExtended =
+ (IntQh->CurrentTd->dControlStatus & UHCI_TD_STATUS_FIELD) >> 17;
+
+ UsbUpdateDataToggle(fpDevInfo, EndpointAddress, IntQh->DataToggle);
+
+ USB_MemFree(IntTd, GET_MEM_BLK_COUNT_STRUC(UHCI_TD));
+ USB_MemFree(IntQh, GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+
+ return (UINT16)BytesTransferred;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_DeactivatePolling
+//
+// Description:
+// This function de-activates the polling TD for the requested device. The
+// device may be a USB keyboard or USB hub
+//
+// Input:
+// fpHCStruc Pointer to the HC structure
+// fpDevInfo Pointer to the device information structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_DeactivatePolling (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo
+)
+{
+ UHCI_QH *PollQh;
+ UINT8 DataToggle;
+
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (UhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ if (DevInfo->fpPollTDPtr == NULL) {
+ return USB_ERROR;
+ }
+
+ PollQh = (UHCI_QH*)DevInfo->fpPollTDPtr;
+
+ UhciRemoveQhFromFrameList(HcStruc, PollQh);
+
+ DataToggle = (PollQh->FirstTd->dToken & UHCI_TD_DATA_TOGGLE)? 1 : 0;
+ if (!(PollQh->FirstTd->dControlStatus & UHCI_TD_STATUS_FIELD)) {
+ UsbUpdateDataToggle(DevInfo, DevInfo->IntInEndpoint, DataToggle ^ 1);
+ }
+
+ UhciFreeTds(PollQh->FirstTd);
+ USB_MemFree(PollQh, GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+ DevInfo->fpPollTDPtr = NULL;
+
+ if (DevInfo->fpPollDataBuffer) {
+ USB_MemFree(DevInfo->fpPollDataBuffer, GET_MEM_BLK_COUNT(DevInfo->PollingLength));
+ DevInfo->fpPollDataBuffer = NULL;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_ActivatePolling
+//
+// Description:
+// This function activates the polling TD for the requested device. The device
+// may be a USB keyboard or USB hub
+//
+// Input:
+// fpHCStruc Pointer to the HC structure
+// fpDevInfo Pointer to the device information structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+// Notes:
+// For the keyboard device this routine allocates TDRepeat also, if it is not
+// already allocated. This routine allocate a polling TD and schedule it to 8ms
+// schedule for keyboards and to 1024ms schedule for hubs.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_ActivatePolling (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo)
+{
+ UHCI_TD *PollTd;
+ UHCI_QH *PollQh;
+ BOOLEAN LowSpeed;
+ UINT8 PacketId;
+ UINTN BufferAddr;
+ UINT32 DataLen;
+ UINT8 DataToggle;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (UhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ if( !VALID_DEVINFO(DevInfo) )
+ return USB_ERROR;
+
+ DevInfo->fpPollDataBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT(DevInfo->PollingLength));
+ if (DevInfo->fpPollDataBuffer == NULL) {
+ return USB_ERROR;
+ }
+
+ LowSpeed = (DevInfo->bEndpointSpeed & 1) != 0;
+ PacketId = DevInfo->IntInEndpoint & BIT7 ? UHCI_TD_IN_PACKET : UHCI_TD_OUT_PACKET;
+ BufferAddr = (UINTN)DevInfo->fpPollDataBuffer;
+ DataLen = DevInfo->PollingLength;
+ DataToggle = UsbGetDataToggle(DevInfo, DevInfo->IntInEndpoint);
+
+ PollTd = UhciAllocGeneralTds(DevInfo->bDeviceAddress, LowSpeed, PacketId,
+ DevInfo->IntInEndpoint & 0xF, DevInfo->IntInMaxPkt, TRUE,
+ &BufferAddr, &DataLen, &DataToggle);
+ if (PollTd == NULL) {
+ USB_MemFree(DevInfo->fpPollDataBuffer, GET_MEM_BLK_COUNT(DevInfo->PollingLength));
+ return USB_ERROR;
+ }
+
+ PollQh = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(UHCI_QH));
+ if (PollQh == NULL) {
+ USB_MemFree(DevInfo->fpPollDataBuffer, GET_MEM_BLK_COUNT(DevInfo->PollingLength));
+ UhciFreeTds(PollTd);
+ return USB_ERROR;
+ }
+
+ DevInfo->fpPollTDPtr = (UINT8*)PollQh;
+
+ UhciInitQh(PollQh);
+ PollQh->pElementPtr = (UINT32)(UINTN)PollTd;
+ PollQh->CurrentTd = PollTd;
+ PollQh->Type = Interrupt;
+ PollQh->FirstTd = PollTd;
+ PollQh->Interval = UhciTranslateInterval(DevInfo->bPollInterval);
+ PollQh->CallBackIndex = USB_InstallCallBackFunction(UhciPollingQhCallback);
+ PollQh->DevInfoPtr = DevInfo;
+ PollQh->ActiveFlag = TRUE;
+
+ UhciAddQhToFrameList(HcStruc, PollQh);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_DisableKeyRepeat
+//
+// Description:
+// This function disables the keyboard repeat rate logic
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_DisableKeyRepeat (
+ HC_STRUC *HcStruc
+)
+{
+ UHCI_DESC_PTRS *UhicDescPtrs;
+ UHCI_QH *Qh;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (UhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ UhicDescPtrs = HcStruc->stDescPtrs.fpUHCIDescPtrs;
+
+ if (UhicDescPtrs == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)UhicDescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(UhicDescPtrs + sizeof(UHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ Qh = UhicDescPtrs->RepeatQh;
+
+ if (Qh == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)Qh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(Qh + sizeof(UHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)Qh->FirstTd < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(Qh->FirstTd + sizeof(UHCI_TD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ Qh->FirstTd->dCSReload = UHCI_TD_ONE_ERROR;
+ Qh->FirstTd->dControlStatus= UHCI_TD_ONE_ERROR;
+ Qh->FirstTd->bActiveFlag = 0;
+ Qh->ActiveFlag = FALSE;
+ Qh->pElementPtr = UHCI_TERMINATE;
+
+ return USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_EnableKeyRepeat
+//
+// Description:
+// This function enables the keyboard repeat rate logic
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_EnableKeyRepeat (
+ HC_STRUC *HcStruc
+)
+{
+ UHCI_DESC_PTRS *UhicDescPtrs;
+ UHCI_QH *Qh;
+ EFI_STATUS EfiStatus;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (UhciIsHalted(HcStruc)) {
+ return USB_ERROR;
+ }
+
+ UhicDescPtrs = HcStruc->stDescPtrs.fpUHCIDescPtrs;
+
+ if (UhicDescPtrs == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)UhicDescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(UhicDescPtrs + sizeof(UHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ Qh = UhicDescPtrs->RepeatQh;
+
+ if (((UINT8*)Qh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(Qh + sizeof(UHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)Qh->FirstTd < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(Qh->FirstTd + sizeof(UHCI_TD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ Qh->FirstTd->dCSReload = (UHCI_TD_INTERRUPT_ON_COMPLETE |
+ UHCI_TD_ONE_ERROR | UHCI_TD_ACTIVE);
+ Qh->FirstTd->dControlStatus = Qh->FirstTd->dCSReload;
+ Qh->FirstTd->bActiveFlag = 1;
+ Qh->pElementPtr = (UINT32)(UINTN)Qh->FirstTd;
+ Qh->CurrentTd = Qh->FirstTd;
+ Qh->ActiveFlag = TRUE;
+
+ return USB_SUCCESS;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_DisableHCPorts (fpHCStruc)
+//
+// Description:
+// This routine disables the UHCI HC root hub ports
+//
+// Input:
+// fpHCStruc Ptr to the host controller structure
+//
+// Output:
+// Status: USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_DisableHCPorts (HC_STRUC* fpHCStruc)
+{
+ UINT16 wIOAddr = (UINT16)fpHCStruc->BaseAddress;
+
+ //
+ // Disable the root hub port 1
+ //
+ ByteWriteIO((UINT16)(wIOAddr+UHCI_PORT1_CONTROL),
+ (UINT8)(ByteReadIO(
+ (UINT16)(wIOAddr+UHCI_PORT1_CONTROL)) & (~UHC_PORT_ENABLE)));
+ //
+ // Disable the root hub port 2
+ //
+ ByteWriteIO((UINT16)(wIOAddr+UHCI_PORT2_CONTROL),
+ (UINT8)(ByteReadIO(
+ (UINT16)(wIOAddr+UHCI_PORT2_CONTROL)) & (~UHC_PORT_ENABLE)));
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhciAddQhToFrameList
+//
+// Description:
+// This routine will add the particular QH into the frame list
+//
+// Input:
+// HcStruc Pointerr to the host controller structure
+// NewQh Address of the QH to be linked
+//
+// Output:
+// USB_SUCCESS/USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciAddQhToFrameList (
+ HC_STRUC *HcStruc,
+ UHCI_QH *NewQh
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ UINT32 LinkPtr;
+ UHCI_QH *Qh;
+ BOOLEAN ByInterval = FALSE;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (NewQh == NULL) {
+ return USB_ERROR;
+ }
+
+ switch (NewQh->Type) {
+ case Control:
+ case Bulk:
+ ByInterval = FALSE;
+ break;
+ case Interrupt:
+ ByInterval = TRUE;
+ break;
+ case Isochronous:
+ ASSERT(FALSE);
+ default:
+ return USB_ERROR;
+ }
+
+ if (ByInterval && NewQh->Interval == 0) {
+ return USB_ERROR;
+ }
+
+ for (Index = 0; Index < HcStruc->wAsyncListSize;
+ ByInterval ? Index += NewQh->Interval : Index++) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ LinkPtr = *PrevPtr;
+
+ while (!(LinkPtr & UHCI_TERMINATE)) {
+ Qh = (UHCI_QH*)(LinkPtr & UHCI_POINTER_MASK);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Qh, sizeof(UHCI_QH));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ if (Qh->Type <= NewQh->Type) {
+ if (ByInterval == FALSE ||
+ Qh->Interval <= NewQh->Interval) {
+ break;
+ }
+ }
+ PrevPtr = &Qh->pLinkPtr;
+ LinkPtr = *PrevPtr;
+ }
+ if (Qh == NewQh) {
+ continue;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PrevPtr, sizeof(UINT32));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ NewQh->pLinkPtr = *PrevPtr;
+ *PrevPtr = (UINT32)((UINTN)NewQh | UHCI_QUEUE_HEAD);
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhciRemoveQhFromFrameList
+//
+// Description:
+// This routine will remove a QH from the the frame list
+//
+// Input:
+// HcStruc Pointerr to the host controller structure
+// RetiredQh Address of the QH to be removed
+//
+// Output:
+// USB_SUCCESS/USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciRemoveQhFromFrameList (
+ HC_STRUC *HcStruc,
+ UHCI_QH *RetiredQh
+)
+{
+ UINT16 Index;
+ UINT32 *PrevPtr;
+ UINT32 LinkPtr;
+ UHCI_QH *Qh;
+ BOOLEAN ByInterval = FALSE;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (RetiredQh == NULL) {
+ return USB_ERROR;
+ }
+
+ switch (RetiredQh->Type) {
+ case Control:
+ case Bulk:
+ ByInterval = FALSE;
+ break;
+ case Interrupt:
+ ByInterval = TRUE;
+ break;
+ case Isochronous:
+ ASSERT(FALSE);
+ default:
+ return USB_ERROR;
+ }
+
+ if (ByInterval && RetiredQh->Interval == 0) {
+ return USB_ERROR;
+ }
+
+ RetiredQh->pElementPtr = UHCI_TERMINATE;
+
+ for (Index = 0; Index < HcStruc->wAsyncListSize;
+ ByInterval ? Index += RetiredQh->Interval : Index++) {
+ PrevPtr = &HcStruc->fpFrameList[Index];
+ LinkPtr = *PrevPtr;
+
+ while (!(LinkPtr & UHCI_TERMINATE)) {
+ Qh = (UHCI_QH*)(LinkPtr & UHCI_POINTER_MASK);
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Qh, sizeof(UHCI_QH));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ if (Qh == RetiredQh) {
+ break;
+ }
+ PrevPtr = &Qh->pLinkPtr;
+ LinkPtr = *PrevPtr;
+ }
+
+ if (LinkPtr & UHCI_TERMINATE) {
+ continue;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)PrevPtr, sizeof(UINT32));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ *PrevPtr = RetiredQh->pLinkPtr;
+ }
+
+ RetiredQh->pLinkPtr = UHCI_TERMINATE;
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_StartTDSchedule (fpHCStruc)
+//
+// Description:
+// This routine will start the TD schedule for the UHCI controller. After this
+// routine TD's can be scheduled for execution.
+//
+// Input:
+// fpHCStruc Pointer to the HC information structure
+//
+// Output:
+// USB_SUCCESS/USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_StartTDSchedule (
+ HC_STRUC *HcStruc
+)
+{
+ UHCI_DESC_PTRS *DescPtr;
+ UHCI_TD *Td;
+
+ //
+ // Allocate the UHCI descriptor pointer structure
+ //
+ DescPtr = (UHCI_DESC_PTRS*) USB_MemAlloc (GET_MEM_BLK_COUNT_STRUC(UHCI_DESC_PTRS));
+ if (DescPtr == NULL) {
+ USB_DEBUG(DEBUG_LEVEL_4, "UHCI Descriptor struc alloc failed.\n");
+ return USB_ERROR;
+ }
+
+ //
+ // Save the value in the HC struc
+ //
+ HcStruc->stDescPtrs.fpUHCIDescPtrs = DescPtr;
+
+ DescPtr->StaticQh = USB_MemAlloc(GET_MEM_BLK_COUNT(1 * sizeof(UHCI_QH)));
+ if (DescPtr->StaticQh == NULL) {
+ return USB_ERROR;
+ }
+
+ UhciInitQh(DescPtr->StaticQh);
+ DescPtr->StaticQh->Type = Interrupt;
+ DescPtr->StaticQh->Interval = 1;
+ UhciAddQhToFrameList(HcStruc, DescPtr->StaticQh);
+
+ if (HcStruc->dHCFlag & HC_STATE_EXTERNAL) {
+ return USB_SUCCESS;
+ }
+
+ DescPtr->RepeatQh = USB_MemAlloc(GET_MEM_BLK_COUNT(1 * sizeof(UHCI_QH) +
+ 1 * sizeof(UHCI_TD)));
+ if(DescPtr->RepeatQh == NULL) {
+ return USB_ERROR;
+ }
+
+ Td = (UHCI_TD*)((UINTN)DescPtr->RepeatQh + sizeof (UHCI_QH));
+
+ //
+ // Initialize the body of TdRepeat. It will run a interrupt transaction
+ // to a non-existant dummy device. This will have the effect of generating
+ // a periodic interrupt used to generate keyboard repeat. This TD is normally
+ // inactive, and is only activated when a key is pressed. TdRepeat will be
+ // set to timeout after two attempts. Since the TD is in the schedule
+ // at 16ms intervals, this will generate an interrupt at intervals of 32ms
+ // (when the TD is active). This 32ms periodic interrupt may then
+ // approximate the fastest keyboard repeat rate of 30 characters per second.
+ //
+ Td->pLinkPtr = UHCI_TERMINATE;
+ Td->dControlStatus = UHCI_TD_ONE_ERROR;
+ Td->dToken = (UHCI_TD_IN_PACKET |
+ ((UINT32)DUMMY_DEVICE_ADDR << 8) |
+ ((UINT32)(DEFAULT_PACKET_LENGTH - 1) << 21));
+ Td->pBufferPtr = (UINT32)(UINTN)Td->aDataArea;
+ Td->dCSReload = UHCI_TD_ONE_ERROR;
+ Td->bActiveFlag = 0;
+
+ UhciInitQh(DescPtr->RepeatQh);
+ DescPtr->RepeatQh->Type = Interrupt;
+ DescPtr->RepeatQh->FirstTd = Td;
+ DescPtr->RepeatQh->Interval = REPEAT_INTERVAL;
+ DescPtr->RepeatQh->CallBackIndex = USB_InstallCallBackFunction(UhciRepeatQhCallback);
+ DescPtr->RepeatQh->ActiveFlag = FALSE;
+
+ //
+ // Schedule the TDRepeat to 8ms schedule
+ //
+ UhciAddQhToFrameList(HcStruc, DescPtr->RepeatQh);
+
+ //
+ // Inform the common code that key repeat is implemented
+ //
+ USBKeyRepeat(HcStruc, 0);
+
+ //
+ // Initialize the body of root hub TD. It will run a interrupt
+ // transaction to a nonexistent dummy device. This will have the effect
+ // of generating a periodic interrupt for the purpose of checking for
+ // attach/detach on the root hub's ports
+ // This initialization is done only once for the first HC
+ //
+ DescPtr->RootHubQh = USB_MemAlloc(GET_MEM_BLK_COUNT(1 * sizeof(UHCI_QH) +
+ 1 * sizeof(UHCI_TD)));
+ ASSERT(DescPtr->RootHubQh != NULL);
+ if (DescPtr->RootHubQh == NULL) {
+ return USB_ERROR;
+ }
+
+ Td = (UHCI_TD*)((UINTN)DescPtr->RootHubQh + sizeof (UHCI_QH));
+
+ Td->pLinkPtr = UHCI_TERMINATE;
+ Td->dControlStatus = 0;
+ Td->dToken =
+ (UHCI_TD_IN_PACKET | ((UINT32)DUMMY_DEVICE_ADDR << 8) |
+ ((UINT32)(DEFAULT_PACKET_LENGTH - 1) << 21));
+ Td->pBufferPtr = (UINT32)(UINTN)Td->aDataArea;
+ Td->dCSReload = 0;
+ Td->bActiveFlag = 0;
+
+ UhciInitQh(DescPtr->RootHubQh);
+ DescPtr->RootHubQh->Type = Interrupt;
+ DescPtr->RootHubQh->FirstTd = Td;
+ DescPtr->RootHubQh->Interval = 128;
+ DescPtr->RootHubQh->CallBackIndex = USB_InstallCallBackFunction(UhciRootHubQhCallBack);
+ DescPtr->RootHubQh->ActiveFlag = FALSE;
+
+ //
+ // Schedule the root hub TD to 256ms schedule
+ //
+ UhciAddQhToFrameList(HcStruc, DescPtr->RootHubQh);
+
+ if (gUsbData->RootHubHcStruc == NULL) {
+ Td->dCSReload =
+ UHCI_TD_INTERRUPT_ON_COMPLETE |
+ UHCI_TD_ONE_ERROR |
+ UHCI_TD_ACTIVE;
+ Td->bActiveFlag = 1;
+ Td->dControlStatus = Td->dCSReload;
+ DescPtr->RootHubQh->pElementPtr = (UINT32)(UINTN)Td;
+ DescPtr->RootHubQh->CurrentTd = Td;
+ DescPtr->RootHubQh->ActiveFlag = TRUE;;
+ gUsbData->RootHubHcStruc = HcStruc;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_4, "TD's are scheduled\n");
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_StopTDSchedule (fpHCStruc)
+//
+// Description:
+// This routine will stop the TD schedules and frees the data structures
+//
+// Input:
+// fpHCStruc Pointer to the HC information structure
+//
+// Output:
+// USB_SUCCESS/USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UHCI_StopTDSchedule (
+ HC_STRUC *HcStruc
+)
+{
+ UINT8 i;
+ UHCI_DESC_PTRS *DescPtrs = HcStruc->stDescPtrs.fpUHCIDescPtrs;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+ //
+ // Free all the TD/QH data structures
+ //
+ if (DescPtrs == NULL) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs + sizeof(UHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->StaticQh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->StaticQh + sizeof(UHCI_QH)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->RootHubQh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->RootHubQh + sizeof(UHCI_QH)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->RepeatQh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->RepeatQh + sizeof(UHCI_QH)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ USB_MemFree (DescPtrs->StaticQh, GET_MEM_BLK_COUNT(sizeof(UHCI_QH)));
+ if (DescPtrs->RootHubQh) {
+ USB_MemFree (DescPtrs->RootHubQh,
+ GET_MEM_BLK_COUNT(sizeof(UHCI_QH) + sizeof(UHCI_TD)));
+ }
+ if (DescPtrs->RepeatQh) {
+ USB_MemFree (DescPtrs->RepeatQh,
+ GET_MEM_BLK_COUNT(sizeof(UHCI_QH) + sizeof(UHCI_TD)));
+ }
+
+ //
+ // Finally free the descriptor pointer
+ //
+ USB_MemFree (DescPtrs, GET_MEM_BLK_COUNT_STRUC(UHCI_DESC_PTRS));
+
+ USBKeyRepeat(HcStruc, 3);
+
+ if (gUsbData->RootHubHcStruc == HcStruc) {
+ gUsbData->RootHubHcStruc = NULL;
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ if (gUsbData->HcTable[i] == NULL) {
+ continue;
+ }
+ if ((gUsbData->HcTable[i]->bHCNumber) &&
+ (gUsbData->HcTable[i]->bHCType == USB_HC_UHCI) &&
+ (gUsbData->HcTable[i]->dHCFlag & HC_STATE_RUNNING) &&
+ (HcStruc != gUsbData->HcTable[i])) {
+
+ DescPtrs = gUsbData->HcTable[i]->stDescPtrs.fpUHCIDescPtrs;
+
+ if (((UINT8*)DescPtrs < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs + sizeof(UHCI_DESC_PTRS)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+ if (((UINT8*)DescPtrs->RootHubQh < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->RootHubQh + sizeof(UHCI_QH)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->RootHubQh->FirstTd < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->RootHubQh->FirstTd + sizeof(UHCI_TD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ if (((UINT8*)DescPtrs->RootHubQh->CurrentTd < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)(DescPtrs->RootHubQh->CurrentTd + sizeof(UHCI_TD)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ DescPtrs->RootHubQh->FirstTd->dCSReload =
+ UHCI_TD_INTERRUPT_ON_COMPLETE |
+ UHCI_TD_ONE_ERROR |
+ UHCI_TD_ACTIVE;
+ DescPtrs->RootHubQh->FirstTd->bActiveFlag = 1;
+ DescPtrs->RootHubQh->FirstTd->dControlStatus =
+ DescPtrs->RootHubQh->FirstTd->dCSReload;
+ DescPtrs->RootHubQh->pElementPtr =
+ (UINT32)(UINTN)DescPtrs->RootHubQh->FirstTd;
+ DescPtrs->RootHubQh->CurrentTd =
+ DescPtrs->RootHubQh->FirstTd;
+ DescPtrs->RootHubQh->ActiveFlag = TRUE;;
+ gUsbData->RootHubHcStruc = gUsbData->HcTable[i];
+ }
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhciProcessQh
+//
+// Description:
+// This function will check whether the QH is completed if so, it will call
+// the call back routine associated with the TDs present in the QH
+//
+// Input:
+// HcStruc HCStruc structure
+// Qh Pointer to the QH
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciProcessQh(
+ HC_STRUC *HcStruc,
+ UHCI_QH *Qh
+)
+{
+ UHCI_TD *Td;
+ UINT16 Length;
+ EFI_STATUS Status;
+
+ if (Qh == NULL) {
+ return USB_ERROR;
+ }
+
+ if (Qh->ActiveFlag == FALSE) {
+ return USB_SUCCESS;
+ }
+
+ if (Qh->FirstTd == NULL) {
+ return USB_SUCCESS;
+ }
+
+ if (Qh->CurrentTd == NULL) {
+ Qh->CurrentTd = Qh->FirstTd;
+ }
+
+ Td = Qh->CurrentTd;
+ while (Td) {
+ Qh->CurrentTd = Td;
+ Qh->DataToggle = Td->dToken & UHCI_TD_DATA_TOGGLE ? 1 : 0;
+
+ if (Td->dControlStatus & UHCI_TD_ACTIVE) {
+ return USB_ERROR;
+ }
+
+ Length = (UINT16)((Td->dControlStatus + 1) & UHCI_TD_ACTUAL_LENGTH);
+ Qh->BytesTransferred += Length;
+
+ if (Td->dControlStatus & UHCI_TD_STATUS_FIELD) {
+ break;
+ }
+
+ Qh->DataToggle ^= 1;
+ Qh->ShortPacketDetected = (Length < (((Td->dToken >> 21) + 1) & 0x7FF));
+
+ if (Qh->ShortPacketDetected) {
+ if (Qh->Type == Control) {
+ while (!(Td->pLinkPtr & UHCI_TERMINATE)) {
+ Td = (UHCI_TD*)((UINTN)Td->pLinkPtr & UHCI_POINTER_MASK);
+ }
+ Qh->pElementPtr = (UINT32)(UINTN)Td;
+ continue;
+ }
+ break;
+ }
+
+ Td = Td->pLinkPtr & UHCI_TERMINATE ?
+ NULL : (UHCI_TD*)(Td->pLinkPtr & UHCI_POINTER_MASK);
+ }
+
+ Qh->ActiveFlag = FALSE;
+ if (Qh->CallBackIndex == 0) {
+ return USB_SUCCESS;
+ }
+
+ if ((Qh->CallBackIndex) && (Qh->CallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ if (gUsbData->aCallBackFunctionTable[Qh->CallBackIndex - 1]) {
+ if ((gUsbData->aCallBackFunctionTable[Qh->CallBackIndex - 1] != UhciRepeatQhCallback) &&
+ (gUsbData->aCallBackFunctionTable[Qh->CallBackIndex - 1] != UhciRootHubQhCallBack)) {
+ Status = UsbDevInfoValidation(Qh->DevInfoPtr);
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+ }
+ (*gUsbData->aCallBackFunctionTable[Qh->CallBackIndex - 1])(
+ HcStruc,
+ (DEV_INFO*)Qh->DevInfoPtr,
+ (UINT8*)Qh,
+ 0,
+ 0);
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhciProcessTd
+//
+// Description:
+// This function will check whether the TD is completed if so, it will call
+// the call back routine associated with this TD
+//
+// Input:
+// HcStruc HCStruc structure
+// Td Pointer to the TD
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+// Notes:
+// For any TD whose ActiveFlag is TRUE and its ControlStatus bit 23 is clear
+// (completed), process the TD by calling its callback routine, if one is present.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciProcessTd(
+ HC_STRUC *HcStruc,
+ UHCI_TD *Td
+)
+{
+ UINT8 DevAddr;
+ DEV_INFO *DevInfo;
+
+ if (Td == NULL) { // Check for NULL
+ return USB_ERROR;
+ }
+
+ if (Td->bActiveFlag == 0) {
+ return USB_SUCCESS;
+ }
+
+ if (Td->dControlStatus & UHCI_TD_ACTIVE) {
+ return USB_ERROR;
+ }
+
+ Td->bActiveFlag = 0;
+ if ((Td->bCallBackIndex) && (Td->bCallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ //
+ // Get the device address from the completed TD
+ //
+ DevAddr = (UINT8)(((Td->dToken) >> 8) & 0x7F);
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR, 0,
+ DevAddr, HcStruc);
+
+ if (gUsbData->aCallBackFunctionTable[Td->bCallBackIndex - 1]) {
+ (*gUsbData->aCallBackFunctionTable[Td->bCallBackIndex - 1])(
+ HcStruc,
+ DevInfo,
+ (UINT8*)Td,
+ 0,
+ 0);
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhciProcessFrameList
+//
+// Description:
+// This function will parse through frame list to find completed QH/TD
+// and invoke corresponding call back routine
+//
+// Input:
+// HcStruc HCStruc structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+// Notes:
+// For any TD whose ActiveFlag is TRUE and its ControlStatus bit 23 is clear
+// (completed), process the TD by calling its call back routine, if one is present.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciProcessFrameList (
+ HC_STRUC *HcStruc
+)
+{
+ UINT32 ListPtr;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ ListPtr = HcStruc->fpFrameList[0];
+
+ while (!(ListPtr & UHCI_TERMINATE)) {
+ if (ListPtr & UHCI_QUEUE_HEAD) {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)ListPtr, sizeof(UHCI_QH));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ UhciProcessQh(HcStruc, (UHCI_QH*)(ListPtr & UHCI_POINTER_MASK));
+ ListPtr = ((UHCI_QH*)(ListPtr & UHCI_POINTER_MASK))->pLinkPtr;
+ } else {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)ListPtr, sizeof(UHCI_TD));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+ UhciProcessTd(HcStruc, (UHCI_TD*)(ListPtr & UHCI_POINTER_MASK));
+ ListPtr = ((UHCI_TD*)(ListPtr & UHCI_POINTER_MASK))->pLinkPtr;
+ }
+ }
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_RootHubTDCallBack
+//
+// Description:
+// This function is called when TD256ms completes a transaction. This TD runs
+// a dummy interrupt transaction to a non-existant device address for the
+// purpose of generating a periodic timeout interrupt. This periodic interrupt
+// may be used to check for new devices on the root hub etc.
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+// fpDevInfo NULL (pDevInfo is not valid)
+// fpTD Pointer to the TD that completed
+// fpBuffer Not used
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciRootHubQhCallBack(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Qh,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ UINT8 Index;
+ HC_STRUC *Hc;
+ UINT16 IoPort;
+ UINT16 PortAddr;
+ UHCI_QH *RootHubQh;
+
+ //
+ // First deactivate the TDRootHub so this callback function will not get
+ // reentered.
+ //
+ if (Qh != NULL) {
+ RootHubQh = (UHCI_QH*)Qh;
+ RootHubQh->FirstTd->bActiveFlag = 0;
+ }
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ Hc = gUsbData->HcTable[Index];
+ if (Hc == NULL) {
+ continue;
+ }
+
+ if (Hc->bHCType != USB_HC_UHCI) { // Process for UHCI only
+ continue;
+ }
+
+ if (!(Hc->dHCFlag & HC_STATE_RUNNING)) {
+ continue;
+ }
+
+ //
+ // Check whether the controller is still under BIOS control
+ // Read the frame list base address and compare with stored value
+ //
+ IoPort = (UINT16)Hc->BaseAddress;
+ if ((DwordReadIO(IoPort + UHCI_FRAME_LIST_BASE) & 0xFFFFF000)
+ != (UINT32)Hc->fpFrameList) {
+ continue;
+ }
+
+ //
+ // Check whether USB host controllers are accessible to aVOID system
+ // hang in ports enumeration.
+ //
+ if (ByteReadIO(IoPort) == 0xFF) {
+ continue;
+ }
+
+ //
+ // Check whether enumeration is already began
+ //
+ if(gUsbData->bEnumFlag == FALSE) {
+ gUsbData->bEnumFlag = TRUE;
+
+ //
+ // Mask the Host Controller interrupt so the ISR does not get re-entered due
+ // to an IOC interrupt from any TDs that complete in frames while we are
+ // configuring a new device that has just been plugged in.
+ //
+ // Disable IOC, timeout & CRC interrupt
+ //
+ WordWriteIO((UINT16)(IoPort + UHCI_INTERRUPT_ENABLE), 0);
+
+ //
+ // Process Port#1 and clear Port#1 status bit
+ //
+ PortAddr = IoPort + UHCI_PORT1_CONTROL;
+ if (WordReadIO(PortAddr) & UHC_CONNECT_STATUS_CHANGE) {
+ USBCheckPortChange(Hc, Hc->bHCNumber | BIT7, 1);
+ WordWriteIO(PortAddr, WordReadIO(PortAddr));
+ }
+
+ //
+ // Process Port#2 and clear Port#2 status bit
+ //
+ PortAddr = IoPort + UHCI_PORT2_CONTROL;
+ if (WordReadIO(PortAddr) & UHC_CONNECT_STATUS_CHANGE) {
+ USBCheckPortChange(Hc, Hc->bHCNumber | BIT7, 2);
+ WordWriteIO(PortAddr, WordReadIO(PortAddr));
+ }
+
+ //
+ // Renable interrupts from the host controller
+ // Enable IOC, timeout & CRC interrupt
+ //
+ WordWriteIO((UINT16)(IoPort + UHCI_INTERRUPT_ENABLE), (UINT16)(UHC_IOC_ENABLE));
+
+ gUsbData->bEnumFlag = FALSE;
+ }
+ }
+
+ //
+ // Reactivate the TdRootHub
+ //
+ if (Qh != NULL) {
+ RootHubQh->FirstTd->dControlStatus = RootHubQh->FirstTd->dCSReload;
+ RootHubQh->FirstTd->bActiveFlag = 1;
+ RootHubQh->pElementPtr = (UINT32)(UINTN)RootHubQh->FirstTd;
+ RootHubQh->CurrentTd = RootHubQh->FirstTd;
+ RootHubQh->ActiveFlag = TRUE;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_RepeatTDCallback
+//
+// Description:
+// This function is called when TdRepeat completes a transaction. This TD
+// runs a dummy interrupt transaction to a non-existant device address for
+// the purpose of generating a periodic timeout interrupt which in turn is
+// used to generate keyboard repeat.
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+// fpDevInfo NULL (pDevInfo is not valid)
+// fpTD Pointer to the TD that completed
+// fpBuffer Not used
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciRepeatQhCallback(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Qh,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ UHCI_QH *RepeatQh = (UHCI_QH*)Qh;
+
+ USB_DEBUG(DEBUG_LEVEL_8, "Processing Repeat TD ...\n");
+ //
+ // First deactivate the TdRepeat so this callback function will not get
+ // re-entered.
+ //
+ RepeatQh->FirstTd->bActiveFlag = 0;
+
+#if USB_DEV_KBD
+ USBKBDPeriodicInterruptHandler(HcStruc);
+#endif
+ //
+ // Reactivate the TdRepeat
+ //
+ if (RepeatQh->FirstTd->dCSReload & UHCI_TD_ACTIVE) {
+ RepeatQh->FirstTd->dControlStatus = RepeatQh->FirstTd->dCSReload;
+ RepeatQh->FirstTd->bActiveFlag = 1;
+ RepeatQh->pElementPtr = (UINT32)(UINTN)RepeatQh->FirstTd;
+ RepeatQh->CurrentTd = RepeatQh->FirstTd;
+ RepeatQh->ActiveFlag = TRUE;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UHCI_PollingTDCallback
+//
+// Description:
+// This function is called when a polling TD from the TD pool completes an
+// interrupt transaction to its assigned device.
+// This routine should process any data in the TD's data buffer, handle any
+// errors, and then copy the TD's CSReloadValue field into its control status
+// field to put the TD back into service.
+//
+// Input:
+// fpHCStruc Pointer to the HCStruc structure
+// fpDevInfo NULL (pDevInfo is not valid)
+// fpTD Pointer to the TD that completed
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciPollingQhCallback(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Qh,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ UHCI_QH *PollQh = (UHCI_QH*)Qh;
+
+ USB_DEBUG(DEBUG_LEVEL_8, "Processing polling TD ...\n");
+
+ UsbUpdateDataToggle(DevInfo, DevInfo->IntInEndpoint,
+ PollQh->DataToggle);
+
+ if ((PollQh->CurrentTd->dControlStatus & UHCI_TD_STATUS_FIELD) == 0) {
+ if ((DevInfo->bCallBackIndex) && (DevInfo->bCallBackIndex <= MAX_CALLBACK_FUNCTION)) {
+ if (gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex - 1]) {
+ (*gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex-1])(
+ HcStruc,
+ DevInfo,
+ Qh,
+ DevInfo->fpPollDataBuffer,
+ PollQh->BytesTransferred);
+ }
+ }
+ }
+
+ UhciActivateTds(PollQh->FirstTd, PollQh->DataToggle);
+
+ PollQh->pElementPtr = (UINT32)(UINTN)PollQh->FirstTd;
+ PollQh->CurrentTd = PollQh->FirstTd;
+ PollQh->BytesTransferred = 0;
+ PollQh->ActiveFlag = TRUE;
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UhciInitQh
+//
+// Description: This function check whether HC is halted.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UhciInitQh (
+ UHCI_QH *Qh
+)
+{
+ Qh->pLinkPtr = UHCI_TERMINATE;
+ Qh->pElementPtr = UHCI_TERMINATE;
+ Qh->CurrentTd = NULL;
+ Qh->DataToggle = 0;
+ Qh->BytesTransferred = 0;
+ Qh->ShortPacketDetected = FALSE;
+ Qh->FirstTd = NULL;
+ Qh->Interval = 0;
+ Qh->CallBackIndex = 0;
+ Qh->ActiveFlag = FALSE;
+ Qh->DevInfoPtr = NULL;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UhciIsHalted
+//
+// Description: This function check whether HC is halted.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+UhciIsHalted (
+ HC_STRUC *HcStruc
+)
+{
+ return (ByteReadIO((UINT16)(HcStruc->BaseAddress + UHCI_STATUS_REG)) & UHC_HC_HALTED) == UHC_HC_HALTED;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UhciTranslateInterval
+//
+// Description: This function calculates the polling rate.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UhciTranslateInterval(
+ UINT8 Interval
+)
+{
+ UINT8 BitCount = 0;
+
+ // The Interval value should be from 1 to 255
+ ASSERT(Interval >= 1 && Interval <= 255);
+
+ for (BitCount = 0; Interval != 0; BitCount++) {
+ Interval >>= 1;
+ }
+ return (1 << (BitCount - 1));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UhciAllocGeneralTds
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UHCI_TD*
+UhciAllocGeneralTds (
+ IN UINT8 DeviceAddr,
+ IN BOOLEAN LowSpeed,
+ IN UINT8 PacketId,
+ IN UINT8 EndpointAddr,
+ IN UINT16 MaxPacket,
+ IN BOOLEAN ShortPacket,
+ IN OUT UINTN *BufferAddr,
+ IN OUT UINT32 *Length,
+ IN OUT UINT8 *DataToggle
+)
+{
+ UINT16 NumTds = 0;
+ UHCI_TD *FirstTd = NULL;
+ UHCI_TD *Td = NULL;
+ UINTN Address = *BufferAddr;
+ UINT32 BytesRemaining = *Length;
+ UINT8 Toggle = *DataToggle;
+ UINT16 MaxLen = 0;
+
+ if (BytesRemaining == 0) {
+ return NULL;
+ }
+
+ NumTds = BytesRemaining / MaxPacket;
+ if (BytesRemaining % MaxPacket) {
+ NumTds++;
+ }
+
+ FirstTd = USB_MemAlloc(GET_MEM_BLK_COUNT(NumTds * sizeof(UHCI_TD)));
+ if (FirstTd == NULL) {
+ return NULL;
+ }
+
+ for (Td = FirstTd;;) {
+ MaxLen = BytesRemaining > MaxPacket ? MaxPacket : BytesRemaining;
+
+ Td->pLinkPtr = UHCI_TERMINATE;
+ Td->dToken = (UINT32)PacketId | ((UINT32)DeviceAddr << 8) |
+ ((UINT32)EndpointAddr << 15) | ((MaxLen - 1) << 21);
+ if (Toggle) {
+ Td->dToken |= UHCI_TD_DATA_TOGGLE;
+ }
+
+ Td->pBufferPtr = (UINT32)Address;
+ Td->dCSReload = UHCI_TD_THREE_ERRORS | UHCI_TD_ACTIVE;
+ if (LowSpeed) {
+ Td->dCSReload |= UHCI_TD_LOW_SPEED_DEVICE;
+ }
+ if (ShortPacket) {
+ Td->dCSReload |= UHCI_TD_SHORT_PACKET_DETECT;
+ }
+ Td->dControlStatus = Td->dCSReload;
+ Td->bActiveFlag = 1;
+
+ BytesRemaining -= MaxLen;
+ Address += MaxLen;
+ Toggle ^= 1;
+
+ if (BytesRemaining == 0) {
+ break;
+ }
+
+ Td->pLinkPtr = (UINT32)(((UINTN)Td + sizeof(UHCI_TD)) | UHCI_VERTICAL_FLAG);
+ Td = (UHCI_TD*)((UINTN)Td->pLinkPtr & UHCI_POINTER_MASK);
+ }
+
+ Td->dCSReload |= UHCI_TD_INTERRUPT_ON_COMPLETE;
+ Td->dControlStatus = Td->dCSReload;
+
+ *Length = BytesRemaining;
+ *BufferAddr = Address;
+ *DataToggle = Toggle;
+
+ return FirstTd;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UhciFreeTds
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UhciFreeTds (
+ IN UHCI_TD *FirstTd
+)
+{
+ UHCI_TD *Td = FirstTd;
+ UINT16 NumTds = 0;
+
+ if (FirstTd == NULL) {
+ return;
+ }
+
+ while (Td) {
+ NumTds++;
+ Td = Td->pLinkPtr & UHCI_TERMINATE ?
+ NULL : (UHCI_TD*)((UINTN)Td->pLinkPtr & UHCI_POINTER_MASK);
+ }
+
+ USB_MemFree(FirstTd, GET_MEM_BLK_COUNT(NumTds * sizeof(UHCI_TD)));
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: UhciActivateTds
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UhciActivateTds (
+ IN UHCI_TD *FirstTd,
+ IN UINT8 DataToggle
+)
+{
+ UHCI_TD *Td = FirstTd;
+ UINT8 Toogle = DataToggle;
+
+ if (FirstTd == NULL) {
+ return;
+ }
+
+ while (Td) {
+ Td->dToken &= ~UHCI_TD_DATA_TOGGLE;
+ if (Toogle) {
+ Td->dToken |= UHCI_TD_DATA_TOGGLE;
+ }
+ Td->dControlStatus = Td->dCSReload;
+ Td->bActiveFlag = 1;
+
+ Toogle ^= 1;
+ Td = Td->pLinkPtr & UHCI_TERMINATE ?
+ NULL : (UHCI_TD*)((UINTN)Td->pLinkPtr & UHCI_POINTER_MASK);
+ }
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/uhci.h b/Core/EM/usb/rt/uhci.h
new file mode 100644
index 0000000..445c8a3
--- /dev/null
+++ b/Core/EM/usb/rt/uhci.h
@@ -0,0 +1,271 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/uhci.h 11 7/26/13 2:40a Ryanchou $
+//
+// $Revision: 11 $
+//
+// $Date: 7/26/13 2:40a $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/uhci.h $
+//
+// 11 7/26/13 2:40a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 10 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 9 11/22/12 9:21p Wilsonlee
+// [TAG] EIP106887
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for UHCI.
+// [Files] usb.c, uhci.c, uhci.h
+//
+// 8 5/04/12 6:39a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 7 5/04/12 5:26a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 6 1/04/10 9:20a Olegi
+// EIP32956: Polling rate for the keyboards has been changed from 8 ms to
+// 32 ms.
+//
+// 5 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 4 3/20/07 12:20p Olegi
+//
+// 2 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Uhci.h
+//
+// Description: AMI USB UHCI header file
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+// Avoid including multiple instance of this file
+#ifndef __UHCI_H
+#define __UHCI_H
+
+#define UHCI_DATA_AREA_SIZE 0x1000
+#define UHCI_FRAME_LIST_SIZE 1024
+
+#define USB_UHCI_REG_LEGSUP 0xC0
+
+//---------------------------------------------------------------------------
+// UHCI I/O register read access definitions
+//---------------------------------------------------------------------------
+
+// Equates for UHCI I/O mapped registers (offsets from base address)
+
+#define UHCI_COMMAND_REG 0x00
+#define UHCI_STATUS_REG 0x02
+#define UHCI_INTERRUPT_ENABLE 0x04
+#define UHCI_FRAME_NUM 0x06
+#define UHCI_FRAME_LIST_BASE 0x08
+#define UHCI_SOF_MODIFY 0x0C
+#define UHCI_PORT1_CONTROL 0x10
+#define UHCI_PORT2_CONTROL 0x12
+
+// Bit definitions for UHCI command register
+
+#define UHC_HOST_CONTROLLER_RUN BIT0
+#define UHC_HOST_CONTROLLER_RESET BIT1
+#define UHC_GLOBAL_RESET BIT2
+#define UHC_ENTER_SUSPEND BIT3
+#define UHC_FORCE_RESUME BIT4
+#define UHC_CONFIGURE_FLAG BIT6
+#define UHC_MAX_PACKET_64_BYTE BIT7
+
+// Bit definitions for UHCI status register
+
+#define UHC_USB_INTERRUPT BIT0
+#define UHC_USB_ERROR_INTERRUPT BIT1
+#define UHC_RESUME_RECEIVED BIT2
+#define UHC_PCI_BUS_ERROR BIT3
+#define UHC_HC_PROCESS_ERROR BIT4
+#define UHC_HC_HALTED BIT5
+
+// Bit definitions for USB interrupt enable register
+
+#define UHC_TIMEOUT_CRC_ENABLE BIT0
+#define UHC_RESUME_ENABLE BIT1
+#define UHC_IOC_ENABLE BIT2
+#define UHC_SHORT_PACKET_ENABLE BIT3
+
+// Bit definitions for Port Status and Control
+
+#define UHC_CONNECT_STATUS BIT0
+#define UHC_CONNECT_STATUS_CHANGE BIT1
+#define UHC_PORT_ENABLE BIT2
+#define UHC_PORT_ENABLE_CHANGE BIT3
+#define UHC_LINE_STATUS 0x30
+#define UHC_LINE_STATUS_CHANGE BIT6
+#define UHC_LOW_SPEED_ATTACHED BIT8
+#define UHC_PORT_RESET BIT9
+#define UHC_PORT_SUSPEND BIT12
+
+//---------------------------------------------------------------------------
+// UHCI Controller Port 60/64h trapping flags
+//---------------------------------------------------------------------------
+#define UHCI_TRAP_PORT_60h_READ BIT0
+#define UHCI_TRAP_PORT_60h_WRITE BIT1
+#define UHCI_TRAP_PORT_64h_READ BIT2
+#define UHCI_TRAP_PORT_64h_WRITE BIT3
+#define UHCI_SMI_ON_USB_INTERRUPT BIT4
+#define UHCI_TRAP_FLAG (UHCI_SMI_ON_USB_INTERRUPT)
+
+//---------------------------------------------------------------------------
+// Bit definitions for a generic pointer
+//---------------------------------------------------------------------------
+#define UHCI_TERMINATE BIT0
+#define UHCI_QUEUE_HEAD BIT1
+#define UHCI_VERTICAL_FLAG BIT2
+#define UHCI_POINTER_MASK 0xFFFFFFF0
+
+//---------------------------------------------------------------------------
+// Bit definitions for transfer descriptor control and status
+//---------------------------------------------------------------------------
+
+#define UHCI_TD_ACTUAL_LENGTH 0x7FF
+#define UHCI_TD_STATUS_FIELD 0xFE0000
+#define UHCI_TD_BITSTUFF_ERROR 0x20000
+#define UHCI_TD_CRC_TIMEOUT_ERROR 0x40000
+#define UHCI_TD_NAK_RECEIVED 0x80000
+#define UHCI_TD_BABBLE_DETECTED 0x100000
+#define UHCI_TD_DATA_BUFFER_ERROR 0x200000
+#define UHCI_TD_STALLED 0x400000
+#define UHCI_TD_ACTIVE 0x800000
+#define UHCI_TD_INTERRUPT_ON_COMPLETE 0x1000000
+#define UHCI_TD_ISOCHRONOUS_SELECT 0x2000000
+#define UHCI_TD_LOW_SPEED_DEVICE 0x4000000
+#define UHCI_TD_ERROR_COUNTER 0x18000000
+#define UHCI_TD_ONE_ERROR 0x8000000
+#define UHCI_TD_TWO_ERRORS 0x10000000
+#define UHCI_TD_THREE_ERRORS 0x18000000
+#define UHCI_TD_SHORT_PACKET_DETECT 0x20000000
+
+//---------------------------------------------------------------------------
+// Bit definitions for transfer descriptor token
+//---------------------------------------------------------------------------
+#define UHCI_TD_PACKET_ID 0xFF
+#define UHCI_TD_IN_PACKET 0x69
+#define UHCI_TD_OUT_PACKET 0xE1
+#define UHCI_TD_SETUP_PACKET 0x2D
+#define UHCI_TD_DEVICE_ADDRESS 0x7F00
+#define UHCI_TD_ENDPOINT 0x78000
+#define UHCI_TD_DATA_TOGGLE 0x80000
+#define UHCI_TD_MAX_LENGTH 0xFFE00000
+
+typedef enum {
+ Control = 1,
+ Bulk = 0,
+ Interrupt = 2,
+ Isochronous = 3
+} XFER_TYPE;
+
+#pragma pack(push, 1)
+
+// UHCI TD structure
+typedef struct {
+ UINT32 pLinkPtr;
+ UINT32 dControlStatus;
+ UINT32 dToken;
+ UINT32 pBufferPtr;
+
+// AMI defined fields
+ UINT32 dCSReload; // Control status reload value
+ UINT8 bCallBackIndex;
+ UINT8 bActiveFlag;
+ UINT16 wReserved;
+ UINT8 aDataArea[8];
+} UHCI_TD;
+
+typedef struct {
+ UINT32 pLinkPtr;
+ UINT32 pElementPtr;
+ UHCI_TD *CurrentTd;
+ UINT8 DataToggle;
+ UINT32 BytesTransferred;
+ BOOLEAN ShortPacketDetected;
+ XFER_TYPE Type;
+ UHCI_TD *FirstTd;
+ UINT8 Interval;
+ UINT8 CallBackIndex;
+ BOOLEAN ActiveFlag;
+ VOID *DevInfoPtr;
+ UINT8 aReserved[47 - 3 * sizeof(VOID*) - sizeof(XFER_TYPE)];
+} UHCI_QH;
+
+#pragma pack(pop)
+
+typedef struct {
+ UHCI_QH *StaticQh;
+ UHCI_QH *RootHubQh;
+ UHCI_QH *RepeatQh;
+} UHCI_DESC_PTRS;
+
+#endif // __UHCI_H
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usb.c b/Core/EM/usb/rt/usb.c
new file mode 100644
index 0000000..b1baa4a
--- /dev/null
+++ b/Core/EM/usb/rt/usb.c
@@ -0,0 +1,5300 @@
+#pragma warning(disable: 4001)
+#pragma warning(disable: 4127)
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usb.c 183 10/21/16 1:48a Wilsonlee $
+//
+// $Revision: 183 $
+//
+// $Date: 10/21/16 1:48a $
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usb.c $
+//
+// 183 10/21/16 1:48a Wilsonlee
+// Fixed Cppcheck error.
+//
+// 182 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 181 7/28/16 4:56a Wilsonlee
+// [TAG] EIP264662
+// [Category] Improvement
+// [Description] Don't install usb hw smi after reconnecting usb
+// controllers.
+// [Files] uhcd.c, usb.c, ohci.c, amiusb.c, amiusbhc.c
+//
+// 180 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 179 11/04/15 9:51p Wilsonlee
+// [TAG] EIP241067
+// [Category] Improvement
+// [Description] Add the device descriptor to the DEV_INFO structure.
+// [Files] usb.c, usbdef.h, xhci.c, usbbus.c, AmiUsbController.h
+//
+// 178 9/01/15 10:17p Wilsonlee
+// [TAG] EIP235482
+// [Category] Improvement
+// [Description] Select this alternate setting for multiple TTs hubs.
+// [Files] usbhub.c, usb.c, amiusb.h, usbdef.h
+//
+// 177 7/24/15 3:30a Wilsonlee
+// [TAG] EIP229294
+// [Category] Improvement
+// [Description] If the device descriptor returns with a value in its
+// length field that is greater 18, it is valid and we should ignore the
+// extra bytes.
+// [Files] usb.c
+//
+// 176 5/28/15 4:29a Wilsonlee
+// [TAG] EIP219785
+// [Category] Improvement
+// [Description] Suspend usb devices which are connected to Hubs.
+// [Files] usb.c, usbdef.h
+//
+// 175 4/29/15 11:26p Wilsonlee
+// [TAG] EIP215031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Transcend USB 3.0 HDD is disappeared in the setup menu by
+// cold boot.
+// [RootCause] We only can get SerialNumber string descriptor before
+// setting configuration for this device, otherwise it is failed at
+// getting this descriptor and inquiry command is also failed.
+// [Solution] Retry inquiry command.
+// [Files] usb.c, usbmass.c, efiusbmass.c, usbbus.c, usbdef.h
+//
+// 174 4/27/15 2:25a Wilsonlee
+// [TAG] EIP211855
+// [Category] Improvement
+// [Description] Set the default interface if the device has alternate
+// setting for the interface.
+// [Files] usb.c, usbdef.h
+//
+// 173 4/07/15 4:03a Wilsonlee
+// [TAG] EIP211598
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Keyboard/Mouse sometimes cannot work when connected to USB
+// 3.0 HUB.
+// [RootCause] It's failed at setting device address.
+// [Solution] Wait 10 ms for stable before we set device address.
+// [Files] usb.c
+//
+// 172 3/08/15 10:49p Wilsonlee
+// [TAG] EIP207774
+// [Category] Improvement
+// [Description] Set USB_FLAG_DRIVER_STARTED flag when HC is running and
+// clear it if we don't start any HC.
+// [Files] uhci.c, usb.c, ehci.c, ohci.c, xhci.c, amiusb.h
+//
+// 171 2/16/15 2:44a Wilsonlee
+// [TAG] EIP205373
+// [Category] Improvement
+// [Description] Cppcheck errors in Usb module.
+// [Files] usb.c, usbport.c, uhcd.c, usbCCID.c
+//
+// 170 1/22/15 10:19p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 169 12/15/14 2:16a Wilsonlee
+// [TAG] EIP194720
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System shutdown delay when connect with cardreader.
+// [RootCause] When we reenumerate devices, we still reserve the
+// original device info, then we will use the wrong info to send command
+// and the device may not respond.
+// [Solution] Remove the present flag of devices before we reenumerate.
+// [Files] usb.c
+//
+// 168 11/23/14 10:09p Wilsonlee
+// [TAG] EIP189293
+// [Category] Improvement
+// [Description] Implement XHCI key repeat function.
+// [Files] usb.c, xhci.c , xhci.h, amiusb.c
+//
+// 167 9/29/14 11:35p Wilsonlee
+// [TAG] EIP181169
+// [Category] Improvement
+// [Description] Support XHCI 1.1/USB 3.1.
+// [Files] xhci.c, xhci.h, usb.c, usbbus.c, usbdef.h, UsbHc.h
+//
+// 166 9/02/14 3:53a Wilsonlee
+// [TAG] EIP182567
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] POST B4h sometimes stays about 30 sec if using special
+// KB/Ms.
+// [RootCause] t's timeout in getting config or report descriptor
+// commands.
+// [Solution] Set the timeout to 500 ms.
+// [Files] usb.c, usbhid.c, usbdef.h
+//
+// 165 7/30/14 5:17a Wilsonlee
+// [TAG] EIP176293
+// [Category] Improvement
+// [Description] The changes are for DisplayLink USB Network driver.
+// [Files] usbbus.c, usb.c
+//
+// 164 7/28/14 7:39a Wilsonlee
+// [TAG] EIP176070
+// [Category] Improvement
+// [Description] Add 100 microseconds before we send get configuration
+// descriptor command if the device is full speed.
+// [Files] usb.c
+//
+// 163 6/26/14 1:16a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 162 6/20/14 2:11a Wilsonlee
+// [TAG] EIP174589
+// [Category] Improvement
+// [Description] Fix build error if USB_HID_KEYREPEAT_USE_SETIDLE is 1.
+// [Files] usb.c
+//
+// 161 5/12/14 4:29a Wilsonlee
+// [TAG] EIP168515
+// [Category] New Feature
+// [Description] Add the token "USB_CONTROLLERS_INITIAL_DELAY_LIST" if
+// usb controllers need to delay for stabilization.
+// [Files] usb.sdl, usb.c
+//
+// 160 4/30/14 5:25a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 159 4/29/14 8:30p Wilsonlee
+// [TAG] EIP164772
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System would auto wake up if USB hot-plug in S5 state via
+// USB hub.
+// [RootCause] The usb hubs have connnect / disconnect wakeup function
+// if we send remote wakeup command
+// [Solution] Don't send remote wakeup command to the usb hubs.
+// [Files] usb.c
+//
+// 158 2/26/14 1:55a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 157 11/26/13 1:23a Wilsonlee
+// [TAG] EIP143251
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The usb mouse lost if it behinds TI TUSB8040A1 hub under
+// BIOS.
+// [RootCause] The device may connect later, then we clear connect
+// change without setting the device is connected.
+// [Solution] Don't get port status again before we clear the changes.
+// [Files] usb.c, usbhub.c
+//
+// 156 11/04/13 3:26a Wilsonlee
+// [TAG] EIP139714
+// [Category] Improvement
+// [Description] Improve the UsbIoPortReset function to support the xhci
+// controller.
+// [Files] usb.c
+//
+// 155 9/04/13 5:46a Wilsonlee
+// [TAG] EIP134478
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The devices which behind the hub don't install successfully
+// in shell.
+// [RootCause] Find the wrong root hub port.
+// [Solution] Check DEV_INFO_VALID_STRUC and DEV_INFO_DEV_PRESENT flag
+// to find the root hub port.
+// [Files] usb.c, xhci.c, usbbus.c
+//
+// 154 8/16/13 4:17a Ryanchou
+//
+// 153 8/02/13 6:16a Ryanchou
+//
+// 152 7/29/13 5:19a Roberthsu
+// [TAG] EIP126741
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Cannot boot to uefi usb device with Sophos software.
+// [RootCause] When boot into tool. Ownership to os event occur.Usb
+// will disconnect device.And record this disconnect event. Then ownership
+// to bios,bios will connect all device.Run legacy to efi function. Bios
+// run disconnect event first.Then reconnect device.Because usb key behind
+// hub. So usb key disconnect also.
+// [Solution] Check device when device reconnect.If device and port
+// number the same.Use the same device info.
+// [Files] usb.c,usbmass.c,efiusbmass.c,uhcd.c
+//
+// 151 7/22/13 10:31p Wilsonlee
+// [TAG] EIP125357
+// [Category] Improvement
+// [Description] Check if the port releases to a select host controller.
+// [Files] uhci.c, usb.c, usbhub.c, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 150 7/17/13 4:14a Roberthsu
+// [TAG] EIP126319
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] TEAC floppy can not detect when cold boot.
+// [RootCause] Device need more delay after get config descriptor.
+// [Solution] Add delay to 1ms.
+// [Files] usb.c
+//
+// 149 6/26/13 3:36a Roberthsu
+// [TAG] EIP125792
+// [Category] Bug Fix
+// [Severity:] Normal
+// [Symptom:] Keep function not work
+// [Root Cause] When check port change. We can not get baseclass.
+// [Solution] Add Vaild base class flag.
+// [Files] UsbPort.c,Usb.c
+//
+// 148 5/01/13 9:54p Wilsonlee
+// [TAG] EIP121643
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot detect the usb floppy.
+// [RootCause] This device doesn't return data when we sned
+// get-config-descriptor command.
+// [Solution] We retry to send get-config-descriptor command if there is
+// no data.
+// [Files] usb.c, ehci.c
+//
+// 147 4/19/13 12:44a Wilsonlee
+// Fix build error if token USB_S5_WAKEUP_SUPPORT is enabled.
+//
+// 146 4/18/13 11:22a Ryanchou
+// Fix build error if token x64_BUILD is 0.
+//
+// 145 3/19/13 3:58a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 144 3/15/13 5:57a Ryanchou
+//
+// 143 3/15/13 4:59a Ryanchou
+// [TAG] EIP117211
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB Memory Allocation Failure for Sizes Above 4k
+// [RootCause] The variable count will be reset when across a page
+// boundary.
+// [Solution] Only reset the variable Count if the allocated blocks less
+// than a page.
+// [Files] usb.c
+//
+// 142 3/07/13 9:25p Wilsonlee
+// [TAG] EIP116044
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] TEAC FDD is not recognized after hot plugging under DOS.
+// [RootCause] Setting the device configuration is failed.
+// [Solution] This device configure successfully by that we set the
+// device address after sending the first get-device-descriptor command.
+// [Files] usb.c
+//
+// 141 3/07/13 8:52a Ryanchou
+// [TAG] EIP113218
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB keyboard cannot work after ownership change back to
+// BIOS
+// [RootCause] The key repeat SMI does not generated because the HC is
+// stopped.
+// [Solution] Use the other HC to generate key repeat SMI
+// [Files] usb.c, usbhid.c, usbkbd.c
+//
+// 140 1/23/13 8:33p Wilsonlee
+// [TAG] EIP108891
+// [Category] Improvement
+// [Description] For usb wakp up function, we need to add some delay to
+// wait the usb devces connect.
+// [Files] usb.c
+//
+// 139 1/22/13 2:38a Wilsonlee
+// [TAG] EIP110305
+// [Category] Improvement
+// [Description] Set the device address after we send the first
+// get-device-descriptor command.
+// [Files] usbmass.c, usb.c, usbdef.h, usbbus.c, efiusbmass.c, uhcd.c,
+// usbport.c
+//
+// 138 1/11/13 4:15a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 137 12/05/12 4:23a Roberthsu
+// [TAG] EIP96616
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When Legacy to EFI, USB KB can't be used.
+// [RootCause] Usb device driver content incorrect driver entry.Legacy
+// insert a devicet,when legacy to efi,device does not install efi driver.
+// [Solution] When legacy to efi, scan device info table and put it
+// to smiqueue.
+// [Files] usb.sdl,uhcd.c,usb.c
+//
+// 136 11/29/12 7:47a Ryanchou
+// [TAG] EIP107586
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Unplug USB keyboard does not uninstall EFI USB keyboard
+// driver properly
+// [RootCause] The EIP99431 changes clear DEV_INFO.bSubDeviceType in
+// runtime keyboard driver, that cause EFI keyboard driver does not know
+// what type of the device is.
+// [Solution] Do not clear DEV_INFO.bSubDeviceType in runtime keyboard
+// driver.
+// [Files] usb.c, usbhid.c, efiusbhid.c
+//
+// 135 11/22/12 9:20p Wilsonlee
+// [TAG] EIP106887
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for UHCI.
+// [Files] usb.c, uhci.c, uhci.h
+//
+// 134 11/13/12 7:11a Wilsonlee
+// [TAG] EIP82553
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for XHCI.
+// [Files] usb.c, ehci.c, ohci.c, xhci.c, xhci.h
+//
+// 133 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 132 10/25/12 4:14a Wilsonlee
+// [TAG] EIP82354
+// [Category] New Feature
+// [Description] Support usb S5 wake up function for OHCI.
+// [Files] usb.c, ehci.c, ohci.c
+//
+// 131 9/28/12 2:38a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 130 9/03/12 4:55a Roberthsu
+// [TAG] EIP98145
+// [Category] Improvement
+// [Description] Add skip function message.
+// [Files] usb.c,usbsrc.sdl
+//
+// 129 8/29/12 9:32a Ryanchou
+// [TAG] EIP88307
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Key repeat cannot be stopped if the keyboard is connected
+// to xHCI.
+// [RootCause] Periodic timer SMI stop generating when USB SMI and
+// periodic timer SMI is generated frequently.
+// [Solution] Reduces the key repeat rate to avoid this issue.
+// [Files] ehci.c, usb.c, usb.sdl
+//
+// 128 8/29/12 8:18a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 127 8/22/12 4:59a Wilsonlee
+// [TAG] EIP98230
+// [Category] Improvement
+// [Description] Set the default of the MaxPacket for endpoint 0 by the
+// device speed.
+// [Files] usb.c
+//
+// 126 6/13/12 2:39a Roberthsu
+// [TAG] EIP90124
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Insert barcode when pxe option rom running.Barcode will not
+// work under dos.
+// [RootCause] Because pxe option under legacy mode.Back to efi mode
+// barcode after reinit will fail under dos.
+// [Solution] In function USB_ReConfigDevice check device initial done.
+// [Files] usb.c
+//
+// 125 5/22/12 10:04a Ryanchou
+// [TAG] EIP90154
+// [Category] Improvement
+// [Description] Remove the USBSB_EnableSmmPeriodicSmi and
+// USBSB_DisableSmmPeriodicSmi hooks.
+// [Files] amidef.h, amiusb.c, usb.c, usbsb.c
+//
+// 124 5/22/12 4:48a Wilsonlee
+// [TAG] EIP89641
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB Keyboard driver overwrites INT0 vector (address 0:0)
+// [RootCause] The Queue Head cross the page boundary.
+// [Solution] Added page alignment restriction into memory allocation
+// routine.
+// [Files] usb.c
+//
+// 123 5/04/12 6:40a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 122 5/04/12 5:27a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 121 4/24/12 3:36a Wilsonlee
+// [TAG] EIP81761
+// [Category] Improvement
+// [Description] Determine the limit of devices after checking whether
+// this device is reconnected.
+// [Files] usb.c
+//
+// 120 2/16/12 8:53p Wilsonlee
+// [TAG] EIP81612
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] Add EFI_USB_SPEED_SUPER in EFI_USB2_HC_PROTOCOL
+// according to UEFI 2.3.1 spec
+// [Files] usb.c, usbbus.c, amiusbhc.c
+//
+// 119 1/13/12 4:24a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 118 1/04/12 6:23a Ryanchou
+//
+// 117 1/04/12 6:22a Ryanchou
+// [TAG] EIP78861
+// [Category] Improvement
+// [Description] Some device will be disconnected after port
+// reset, and reconnected for a while, added 100 ms delay in this case.
+// [Files] usb.c
+//
+// 116 12/26/11 2:24a Roberthsu
+// [TAG] EIP74609
+// [Category] Improvement
+// [Description] Add check oemskiplist at check port change.
+// [Files] usbport.c,usb.c,AmiUsbController.h
+//
+// 115 12/08/11 1:46a Ryanchou
+// [TAG] EIP75441
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs at 0xB4 after restart from Win7
+// [RootCause] The device does not use standard BOT protocol under
+// Windows.
+// [Solution] Add the device into bad device table.
+// [Files] usb.c usbport.c
+//
+// 114 11/28/11 8:36p Wilsonlee
+// [TAG] EIP73803
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The mouse can't work under setup after hot-plug.
+// [RootCause] The device may fail at the get device descriptor or set
+// device configuration.
+// [Solution] Add 10 msec delay before getting device descriptor if the
+// device is low or full speed and add 2 msec delay after setting the
+// device's address.
+// [Files] usb.c
+//
+// 113 11/08/11 8:21a Wilsonlee
+// [TAG] EIP74876
+// [Category] New Feature
+// [Description] Add USB API for shutdown single USB controller.
+// [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 112 11/05/11 7:36a Wilsonlee
+// [TAG] EIP64781
+// [Category] New Feature
+// [Description] Added SDL token
+// SKIP_CARD_READER_CONNECT_BEEP_IF_NO_MEDIA that skip the connect beep if
+// no media present in USB card reader.
+// [Files] usbport.c, usbmass.c, usb.c, usbdef.h, uhcd.c, usbsrc.sdl
+//
+// 111 10/25/11 8:23a Wilsonlee
+// [TAG] EIP71750
+// [Category] New Feature
+// [Description] Support extraUSB device driver hook by elink.
+//
+// 110 10/25/11 3:51a Ryanchou
+// [TAG] EIP70933
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System hangs at checkpoint 0x98 when webcam plugged
+// [RootCause] The webcam return invalid data in configuration
+// descriptor.
+// [Solution] Get the configuration descriptor twice, the first time is
+// to receive the returned configure descriptor to get the total length
+// and the second time is to feed the length to the function again.
+// [Files] usb.c, usbdef.h
+//
+// 109 8/08/11 6:59a Ryanchou
+// [TAG] EIP54018
+// [Category] New Feature
+// [Description] Added USB S5 wake up support.
+// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h,
+// usbsb.c xhci.c
+//
+// 108 8/08/11 5:17a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 107 8/05/11 6:18a Ryanchou
+// [TAG] EIP60706
+// [Category] Improvement
+// [Description] Move gUsbBadDeviceTable into SMRAM.
+// [Files] usbport.c, amiusb.c, usb.c, uhcd.c, AmiUsbController.h
+//
+// 106 7/22/11 5:37a Ryanchou
+// [TAG] EIP65385
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB mouse can not be detected.
+// [RootCause] The device is connected in disconnect progress, port
+// reset is not issued.
+// [Solution] Remove the code that check device connection in disconnect
+// progress.
+// [Files] usb.c
+//
+// 105 7/19/11 5:17a Ryanchou
+// [TAG] EIP64498
+// [Category] New Feature
+// [Description] Implement EHCI key repeat function.
+// [Files] ehci.c, ehci.h, usb.c, usbdef.h
+//
+// 104 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 103 7/13/11 2:47a Ryanchou
+// [TAG] EIP60460
+// [Category] Improvement
+// [Description] Adds a flag when device disconnected during data
+// transfer, BIOS will not issue a transfer to the devicce if this flag is
+// set. This change is for Fresco USB 3.0 controller.
+// [Files] usb.c, usbdef.h, xhci.c, xhci.h
+//
+// 102 7/12/11 8:09a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 101 6/22/11 9:36a Ryanchou
+// [TAG] EIP60640
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Logitec USB keyboard has no function in DOS.
+// [RootCause] The USB keybaord may stall get configuration descriptor
+// request or set address request.
+// [Solution] Retry five times when the device stalls these request.
+// [Files] usb.c, usbbus.c
+//
+// 100 6/22/11 1:44a Ryanchou
+// [TAG] EIP59738
+// [Category] Improvement
+// [Description] Support Block size other than 512 bytes USB HDD in UEFI
+// mode.
+// [Files] efiusbmass.c, uhci.c, usb.c, usbdef.h, usbmass.c
+//
+// 99 6/21/11 9:33a Ryanchou
+// [TAG] EIP59601
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB devices can't be detected if webcam is connected.
+// [RootCause] The configuration descriptor length is greater than
+// buffer length, the causes the last descriptor is invalid.
+// [Solution] If the next descriptor cross the buffer boundary, skip the
+// descriptor.
+// [Files] usb.c
+//
+// 98 4/06/11 5:27a Tonylo
+// [TAG] EIP52339
+// [Category] New Feature
+// [Description] USB changes of USB host safe disabling solution.
+//
+// 97 4/06/11 1:33a Ryanchou
+// [TAG] EIP54782
+// [Category] Improvement
+// [Description] Change polling data size of HID devices to max packet
+// size of interrupt endpoint.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, xhci.c
+//
+// 96 4/06/11 12:49a Ryanchou
+// [TAG] EIP51653
+// [Category] New Feature
+// [Description] Added an interface that skips specific port
+// enumeration.
+// [Files] AmiUsbController.h, uhcd.c, uhcd.h, usb.c, usbdef.h,
+// usbport.c
+//
+// 95 3/30/11 8:13a Ryanchou
+// [TAG] EIP54126
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Sometimes system hangs at checkpoint 0xB4.
+// [RootCause] The bLength field of configuration descriptor is zero.
+// [Solution] Check wether bLength field is zero before paring next
+// descriptor.
+// [Files] usb.c, usbbus.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c
+//
+// 94 3/29/11 10:52p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 93 3/29/11 10:08a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 92 1/17/11 3:51a Ryanchou
+// [TAG] EIP50361
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Hot plug USB 3.0 flash drive in setup will cause system
+// hang.
+// [RootCause] The memory may be destroyed if the Address Device command
+// fails.
+// [Solution] Check the memory has been allocated when free the memory.
+// [Files] usb.c xhci.c xhci.h
+//
+// 91 11/11/10 11:36p Ryanchou
+// [TAG] EIP45578
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB 3.0 device can't be detected.
+// [RootCause] Address Device Command fails.
+// [Solution] Reset the device and attempt the Address Device Command
+// again.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c, xhci.c
+//
+// 90 10/28/10 12:34a Ryanchou
+// EIP46865: Comment out unnecessary ASSERT macro.
+//
+// 89 10/28/10 12:24a Ryanchou
+// EIP45643: Fixed system hangs when hot plug USB mass storage quickly on
+// USB 3.0 port.
+//
+// 88 10/21/10 10:12a Ryanchou
+// EIP45121: Added xHCI Supported Protocol Capability and fix the problem
+// that USB 3.0 device can't be detected.
+//
+// 87 10/20/10 10:24a Ryanchou
+// EIP44702: Added USB 3.0 hub support.
+//
+// 86 10/20/10 12:55a Ryanchou
+// EIP45828: If the flag DEV_INFO_MASS_DEV_REGD is set, check if the
+// controller type is difference between old DevInfo and new one.
+//
+// 85 9/16/10 9:22a Ryanchou
+// EIP44149: Disable slot if the Address Device command was unsuccessful.
+//
+// 84 9/07/10 4:12a Tonylo
+// Remove user tags for coding standard.
+//
+// 83 8/18/10 4:23p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 82 8/13/10 4:10p Olegi
+// Bugfix in CheckDeviceLimit function. EIP41442
+//
+// 81 7/15/10 4:39a Tonylo
+// EIP15489 - Add USB HandOff function for shurdown/init USB legacy
+// through USB API function.
+//
+// 80 7/13/10 5:09a Ryanchou
+// EIP39838: Fixed configure USB hub fail.
+//
+// 79 7/02/10 1:59a Ryanchou
+// Update DevMiscInfo field when hot plug USB mass storage.
+//
+// 78 6/22/10 9:29a Ryanchou
+// EIP39374: Fixed USB mass storage hot plug issue.
+//
+// 77 6/11/10 1:43a Ryanchou
+// EIP36720: Fixed USB keyboard hot plug in setup issue.
+//
+// 76 5/11/10 11:02a Olegi
+// Bugfix in USB_InitDeviceDataDummy; EIP37974
+//
+// 75 3/19/10 10:05a Olegi
+//
+// 74 3/11/10 9:42a Olegi
+//
+// 73 3/10/10 6:36p Olegi
+//
+// 72 3/10/10 6:35p Olegi
+//
+// 71 3/06/10 1:11p Olegi
+//
+// 70 2/27/10 11:58a Olegi
+// Change in the arguments of pfnHCDInitDeviceData function.
+//
+// 69 2/26/10 4:23p Olegi
+//
+// 68 2/23/10 1:20p Olegi
+// Work around Klockwork issues. EIP34370
+//
+// 67 2/08/10 9:38a Olegi
+// EIP34448: Bugfix in prepareForLegacyOS.
+//
+// 66 1/13/10 3:20p Olegi
+// Correction in CheckDeviceLimit routine, EIP32804.
+//
+// 65 12/31/09 9:53a Olegi
+//
+// 64 12/10/09 10:12a Olegi
+// Added UsbControlTimeout setup selection. EIP30079.
+//
+// 63 11/12/09 6:09p Olegi
+//
+// 62 11/09/09 5:40p Olegi
+//
+// 61 10/30/09 5:47p Olegi
+//
+// 60 10/13/09 8:55a Olegi
+// EIP28323: Change in USBGetProperDeviceInfoStructure:
+// - Undo the checking for DEV_INFO_DEV_BUS so that in device structure
+// re-used.
+//
+// 59 10/09/09 5:57p Olegi
+//
+// 58 10/08/09 10:18a Olegi
+// EIP28031: USB_SmiQueuePut must not be called after OS booted as it
+// modifies the BS memory.
+//
+// 57 10/07/09 9:48a Olegi
+// USB Hub error handling improvement. EIP#25601.
+//
+// 56 10/02/09 10:49a Olegi
+// Code cleanup.
+//
+// 55 9/15/09 12:21p Olegi
+// Added KEY_REPEAT_LOGIC functionality. EIP#25841
+//
+// 54 8/26/09 11:41a Olegi
+// Changes that prevent collision of keyboard activity and mass storage
+// access. EIP#22808
+//
+// 53 8/18/09 2:36p Rameshr
+// Symptom: When the system is inside the Option rom, connect uSb keyboard
+// and it doesn't work.
+// Rootcause: In post only EFI driver configure the USB keyboard. So Once
+// comes out from option rom Usbkeyboard works.
+// Solution: When you are inside the option rom configure the newly
+// connected USB keyboard and notify EFI driver.
+//
+// 52 8/06/09 4:15p Olegi
+// Changes related to EIP#23335: connect status change is not maintained
+// properly when device is disconnected while connection is in progress.
+//
+// 51 6/11/09 5:29p Olegi
+// Increased the default timeout value to 20 sec. Thermlake external HDD
+// is not responding to the first READ_10 command for 14 seconds.
+//
+// 50 6/04/09 3:42p Olegi
+// USB_ConfigureDevice: for the existing devices copy the information
+// about the parent controller/hub/port# into the new device structure.
+//
+// 49 6/01/09 2:48p Olegi
+// EIP#22046: while detecting the new device we get the configuration
+// descriptor, assuming it is followed by the interface descriptor; if it
+// is not an interface descriptor, we used to think it is not the first
+// one, so we never send set address and configuration request.
+//
+// 47 5/08/09 8:56a Olegi
+// Increased the timeout value from 5 sec to 10 sec. Several types of
+// external USB HDDs require this change to be properly enumerated.
+//
+// 46 1/29/09 2:32p Olegi
+// Added the check for device limit before device is configured.
+//
+// 44 9/05/08 4:21p Olegi
+// fpCallbackNotify4 is replaced with the local function.
+//
+// 42 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 39 10/30/07 12:07p Olegi
+// Set configuration one more time: it was found that for some devices
+// SET_CONFIGURATION must be the executed right before issuing device
+// specific commands. Example is USB Netac Key (VID 0x0644 DID 0x0000).
+//
+// 38 10/15/07 5:20p Olegi
+// Modified USB_on_identifyDev() routine.
+//
+// 37 9/26/07 9:15a Olegi
+// Added USB_FORCE_64BIT_ALIGNMENT flag.
+//
+// 36 9/06/07 5:59p Olegi
+// Added support for 64-byte pool allocation byte alignment.
+//
+// 35 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 32 5/05/07 1:54p Olegi
+// Persistent DOS drives.
+//
+// 31 4/17/07 8:43a Michaela
+// Bugfix in USB_DetectNewDevice function.
+//
+// 30 4/17/07 8:24a Olegi
+// Device detection algorythm update, in sync with Core8.
+//
+// 24 12/22/06 4:05p Olegi
+// Timeout implementation.
+//
+// 17 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 16 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 14 3/06/06 6:24p Olegi
+// Lun devices support modifications: supported using the index in
+// DEV_INFO table, not through dedicated massLun table.
+//
+// 13 3/01/06 3:50p Olegi
+// USB_FLAG_RUNNING_UNDER_OS flag added.
+//
+// 11 1/11/06 11:51a Olegi
+// Multi-functional devices handling changed.
+//
+// 10 12/19/05 10:17a Olegi
+// USB_StopHostControllers modified to control the sequence of stopping
+// (EHCI first, others follow).
+//
+// 9 11/03/05 6:31p Andriyn
+// LUN Support changes
+//
+// 7 6/20/05 8:55a Olegi
+// .NET compiler with highest warning level and warning-as-error
+// modification.
+//
+// 6 6/16/05 12:19p Andriyn
+// Fix usb device lost after boot to legacy OS: don't disable port even if
+// device is not
+// supported by USBRT: there could be another device at the same address
+//
+// 5 6/15/05 1:59p Andriyn
+// Comments were changed
+//
+// 4 6/01/05 5:34p Olegi
+// Bugfix in USB_DetectNewDevice.
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:11p Andriyn
+// USBBUS implementation
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: Usb.c
+//
+// Description: AMI USB main wrapper
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Token.h>
+#include "amidef.h"
+#include "usbdef.h"
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#include <AmiUsbSmmGlobalDataValidationLib.h>
+#endif
+
+#include <PCI.h> //(EIP54018+)
+
+BOOLEAN gKeyRepeatStatus = FALSE;
+extern BOOLEAN gCheckUsbApiParameter;
+
+BOOLEAN OEMSkipList(UINT8,UINT8,UINT16,UINT8,UINT8); //(EIP74609+)
+
+#if USB_DEV_HUB
+UINT8 USBHub_EnablePort(HC_STRUC*, UINT8, UINT8);
+UINT8 USBHub_DisablePort(HC_STRUC*, UINT8, UINT8);
+UINT8 USBHub_ResetPort(HC_STRUC*, UINT8, UINT8);
+//VOID USBHubFillDriverEntries (DEV_DRIVER*); //(EIP71750-)
+UINT8 USBHub_GetPortStatus (HC_STRUC*, UINT8, UINT8, BOOLEAN);
+#endif
+
+VOID SpeakerBeep (UINT8, UINT16, HC_STRUC*);
+VOID FixedDelay(UINTN);
+//VOID BusFillDriverEntries(DEV_DRIVER*); //(EIP71750-)
+ //(EIP38434+)>
+//#if USB_DEV_KBD
+//VOID USBKBDFillDriverEntries (DEV_DRIVER*);
+//#endif
+//#if USB_DEV_MOUSE
+//VOID USBMSFillDriverEntries (DEV_DRIVER*);
+//#endif
+ //(EIP71750-)>
+//VOID USBHIDFillDriverEntries (DEV_DRIVER*);
+ //<(EIP38434+)
+//#if USB_DEV_MASS
+//VOID USBMassFillDriverEntries (DEV_DRIVER*);
+//#endif
+//#if USB_DEV_CCID
+//VOID USBCCIDFillDriverEntries (DEV_DRIVER*);
+//#endif
+ //<(EIP71750-)
+VOID MemFill (UINT8*, UINT32, UINT8);
+VOID MemCopy (UINT8*, UINT8*, UINT32);
+
+VOID USBAPI_CheckDevicePresence (URP_STRUC*);
+
+extern USB_BADDEV_STRUC gUsbBadDeviceTable[]; //(EIP60706)
+
+DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*); //(EIP98145)
+VOID* USB_MemAlloc(UINT16);
+UINT8 USB_MemFree (VOID*, UINT16);
+UINT8* USB_GetDescriptor (HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT8 , UINT8);
+UINT8 USB_SetAddress(HC_STRUC*,DEV_INFO*, UINT8);
+DEV_INFO* USBIdentifyAndConfigureDevice (HC_STRUC* , DEV_INFO* , UINT8* , UINT16 ,UINT16 );
+UINT8 USB_DisconnectDevice (HC_STRUC*, UINT8, UINT8 );
+VOID USB_InitFrameList (HC_STRUC*, UINT32);
+DEV_DRIVER* UsbFindDeviceDriverEntry(DEV_DRIVER*);
+
+UINT8 USB_MemInit (VOID);
+UINT8 USBInitHostController(UINT16 *, UINT8);
+UINT8 USB_EnumerateRootHubPorts(UINT8);
+UINT8 USBLogError(UINT16);
+BOOLEAN CheckDeviceLimit(UINT8);
+VOID USB_SmiQueuePutMsg(QUEUE_T*, VOID*, int);
+
+ //(EIP54018+)>
+UINT32 ReadPCIConfig(UINT16, UINT8);
+#if USB_S5_WAKEUP_SUPPORT
+VOID DwordWritePCIConfig(UINT16, UINT8, UINT32);
+VOID WordWritePCIConfig(UINT16, UINT8, UINT16);
+VOID ByteWritePCIConfig(UINT16, UINT8, UINT8);
+VOID UsbSbEnablePme(VOID);
+#endif
+ //<(EIP54018+)
+
+extern USB_GLOBAL_DATA *gUsbData; // Defined in AMIUHCD
+
+#ifdef USB_CONTROLLERS_INITIAL_DELAY_LIST
+typedef struct {
+ UINT16 Vid;
+ UINT16 Did;
+ UINT16 DelayTime;
+} CONTROLLERS_INITIAL_DELAY_LIST;
+
+CONTROLLERS_INITIAL_DELAY_LIST gControllersInitialDelayList[] = {USB_CONTROLLERS_INITIAL_DELAY_LIST};
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_StartHostControllers
+//
+// Description: This function initializes the USB host controllers and
+// enumerate the root hub ports for possible USB devices.
+//
+// Output: fpGlobalDataArea Far pointer to the global data area
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_StartHostControllers(UINT8* fpGlobalDataArea)
+{
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: StopControllerType
+//
+// Description: This function stops all USB host controllers of a given type
+//
+// Output: HC type
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+StopControllerType(
+ UINT8 hc_type
+)
+{
+ UINT8 i;
+ HC_STRUC* fpHCStruc;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "stopping all HC type %x:", hc_type);
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ fpHCStruc = gUsbData->HcTable[i];
+ if (fpHCStruc == NULL) {
+ continue;
+ }
+ if ((fpHCStruc->bHCType == hc_type) &&
+ (fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDStop)(fpHCStruc);
+ USB_DEBUG(DEBUG_LEVEL_3, ".");
+ }
+ }
+ USB_DEBUG(DEBUG_LEVEL_3, "\n");
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: StartControllerType
+//
+// Description: This function start all USB host controllers of a given type
+//
+// Output: HC type
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+StartControllerType(
+ UINT8 hc_type
+)
+{
+ UINT8 i;
+ HC_STRUC* fpHCStruc;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "starting all HC type %x:", hc_type);
+ for (i=0; i<gUsbData->HcTableCount; i++) {
+ fpHCStruc = gUsbData->HcTable[i];
+ if (fpHCStruc == NULL) {
+ continue;
+ }
+ if (!(fpHCStruc->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+ if ((fpHCStruc->bHCType == hc_type) ) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDStart)(fpHCStruc);
+ USB_DEBUG(DEBUG_LEVEL_3, ".");
+ }
+ }
+ USB_DEBUG(DEBUG_LEVEL_3, "\n");
+}
+
+ //(EIP74876+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: StopControllerBdf
+//
+// Description: This function stops the USB host controllers of a given Bus Dev Function
+//
+// Input: BusDevFuncNum
+//
+// Output: None
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+StopControllerBdf(
+ UINT16 BusDevFuncNum
+)
+{
+ UINT8 i;
+ HC_STRUC* HcStruc;
+
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ HcStruc = gUsbData->HcTable[i];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if ((HcStruc->wBusDevFuncNum == BusDevFuncNum) &&
+ (HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDStop)(HcStruc);
+ break;
+ }
+ }
+}
+ //<(EIP74876+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_StopHostControllers
+//
+// Description: This function stops the USB host controllers and
+// frees the data structures associated with the host controllers
+// In case of USB2.0 first stop USB1.1 controllers, then USB2.0.
+//
+// Output: None
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_StopHostControllers (VOID)
+{
+ // Suppress disconnect beeps as they might be confusing
+ gUsbData->dUSBStateFlag &= (~USB_FLAG_ENABLE_BEEP_MESSAGE);
+
+ StopControllerType(USB_HC_XHCI); //(EIP52339+)
+ StopControllerType(USB_HC_UHCI);
+ StopControllerType(USB_HC_OHCI);
+ StopControllerType(USB_HC_EHCI);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: UsbHcStart
+//
+// Description: This function initializes the USB host controller and
+// enumerate the root hub ports for possible USB devices.
+//
+// Input: HcStruc HC struc pointer
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHcStart(HC_STRUC* HcStruc)
+{
+ UINT8 Index = 0;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Starting HC %X, HCNum %d, type %x\n",
+ HcStruc->wBusDevFuncNum, HcStruc->bHCNumber, HcStruc->bHCType);
+
+ // Execute start routine of the host controller driver
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDStart)(HcStruc);
+
+ // Check if the HC is running
+ if ((HcStruc->dHCFlag & HC_STATE_RUNNING) == 0) {
+ return USB_ERROR;
+ }
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ if (gUsbData->HcTable[Index] == NULL) {
+ continue;
+ }
+ if (HcStruc == gUsbData->HcTable[Index]) {
+ continue;
+ }
+ if (HcStruc->BaseAddress == gUsbData->HcTable[Index]->BaseAddress) {
+ break;
+ }
+ if (HcStruc->fpFrameList != NULL) {
+ if (HcStruc->fpFrameList == gUsbData->HcTable[Index]->fpFrameList) {
+ break;
+ }
+ }
+ if (HcStruc->usbbus_data != NULL) {
+ if (HcStruc->usbbus_data == gUsbData->HcTable[Index]->usbbus_data) {
+ break;
+ }
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (HcStruc->wBusDevFuncNum == gUsbData->HcTable[Index]->wBusDevFuncNum) {
+ break;
+ }
+#endif
+ }
+
+ if (Index != gUsbData->HcTableCount) {
+ HcStruc->dHCFlag &= ~HC_STATE_RUNNING;
+ return USB_ERROR;
+ }
+
+ HcStruc->dHCFlag |= HC_STATE_INITIALIZED;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)&&(CORE_COMBINED_VERSION >= 0x4028B)
+ UpdateAmiUsbSmmGlobalDataCrc32(gUsbData);
+#endif
+#endif
+
+#ifdef USB_CONTROLLERS_INITIAL_DELAY_LIST
+ for (Index = 0; Index < COUNTOF(gControllersInitialDelayList); Index++) {
+ if ((gControllersInitialDelayList[Index].Vid == HcStruc->Vid) &&
+ (gControllersInitialDelayList[Index].Did == HcStruc->Did)) {
+ if (gControllersInitialDelayList[Index].DelayTime) {
+ FixedDelay(gControllersInitialDelayList[Index].DelayTime * 1000);
+ }
+ break;
+ }
+ }
+#endif
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Enumerating HC#%d, type 0x%x\n", HcStruc->bHCNumber, HcStruc->bHCType);
+ // Issue enumerate call for this HC
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDEnumeratePorts)(HcStruc);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: UsbHcStop
+//
+// Description: This function stops the USB host controller.
+//
+// Input: HcStruc HC struc pointer
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHcStop(HC_STRUC* HcStruc)
+{
+ if ((HcStruc->dHCFlag & HC_STATE_RUNNING) == 0) {
+ return USB_ERROR;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Stopping HC %X, HCNum %d, type %x\n",
+ HcStruc->wBusDevFuncNum, HcStruc->bHCNumber, HcStruc->bHCType);
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDStop)(HcStruc);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: CheckBiosOwnedHc
+//
+// Description: This function checks bios owned hc.
+// Clear USB_FLAG_DRIVER_STARTED if we don't start
+// any host controller.
+//
+// Input: None
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+CheckBiosOwnedHc(
+ VOID
+)
+{
+ UINT8 Index;
+ HC_STRUC *HcStruc;
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ HcStruc = gUsbData->HcTable[Index];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if (HcStruc->dHCFlag & HC_STATE_RUNNING) {
+ return;
+ }
+ }
+
+ gUsbData->dUSBStateFlag &= ~(USB_FLAG_DRIVER_STARTED);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_EnmumerateRootHubPorts
+//
+// Description: This function enumerates the root hub ports of the all
+// selected type HCs
+//
+//
+// Output: bType - HC type
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_EnumerateRootHubPorts (UINT8 bType)
+{
+ UINT8 Index;
+ HC_STRUC* fpHCStruc;
+
+ USB_DEBUG(DEBUG_LEVEL_4, "Enumerating HC Ports.\n");
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ //
+ // Get the HCStruc pointer associated with this controller
+ //
+ fpHCStruc = gUsbData->HcTable[Index];
+ if (fpHCStruc == NULL) {
+ continue;
+ }
+
+ if((fpHCStruc->bHCType) == bType && (fpHCStruc->dHCFlag & HC_STATE_RUNNING)) {
+ USB_DEBUG(DEBUG_LEVEL_3, "Enumerating HC#%d, type 0x%x\n", fpHCStruc->bHCNumber, bType);
+ //
+ // Issue enumerate call for this HC
+ //
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(bType)].pfnHCDEnumeratePorts)(fpHCStruc);
+ }
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_InitHostControllers
+//
+// Description: This function initializes the specified type of the HC
+// from the provided list of host controller PCI addresses
+//
+// Output: pHCPCIAddrList Pointer to table of HC PCI addresses in the system
+// bHCType Type of HC to be initialized (EHCI, OHCI etc)
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBInitHostController(
+ UINT16 * pHCPCIAddrList,
+ UINT8 bHCType)
+{
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_GetHubPortStatus
+//
+// Description: This function returns the hub port status
+//
+// Input: HcStruc HC struc pointer
+// HubAddr USB device address of the hub or HC number
+// BIT7 = 1/0 Roothub/Hub
+// PortNum Port number
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_GetHubPortStatus (
+ HC_STRUC* HcStruc,
+ UINT8 HubAddr,
+ UINT8 PortNum,
+ BOOLEAN ClearChangeBits
+)
+{
+ //
+ // Check whether the request is for root hub or generic hub
+ //
+ if (HubAddr & BIT7) {
+ // Root hub
+ return (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDGetRootHubStatus)(
+ HcStruc, PortNum, ClearChangeBits);
+ } else {
+ #if USB_DEV_HUB
+ return USBHub_GetPortStatus (HcStruc, HubAddr, PortNum, ClearChangeBits);
+ #else
+ return 0;
+ #endif
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_DisableHubPort
+//
+// Description: This function disables the hub port
+//
+// Output: fpHCStruc HC struc pointer
+// bHubAddr USB device address of the hub or HC number
+// BIT7 = 1/0 Roothub/Hub
+// bPortNum Port number
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_DisableHubPort(
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bPortNum)
+{
+ //
+ // Check whether the request is for root hub or generic hub
+ //
+ if (bHubAddr & BIT7) {
+ //
+ // Issue the disable root hub call to disable the hub port
+ //
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDDisableRootHub)(
+ fpHCStruc,
+ bPortNum);
+#if USB_DEV_HUB
+ }
+ else {
+ USBHub_DisablePort (fpHCStruc, bHubAddr, bPortNum);
+#endif
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_EnableHubPort
+//
+// Description: This function enables the hub port
+//
+// Output: fpHCStruc HC struc pointer
+// bHubAddr USB device address of the hub or HC number
+// BIT7 = 1/0 Roothub/Hub
+// bPortNum Port number
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_EnableHubPort (
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bPortNum)
+{
+ //
+ // Check whether the request is for root hub or generic hub
+ //
+ if (bHubAddr & BIT7) {
+ //
+ // Root hub
+ // Issue the disable root hub call to disable the hub port
+ //
+ return (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDEnableRootHub)(fpHCStruc, bPortNum);
+ } else {
+ #if USB_DEV_HUB
+ return USBHub_EnablePort (fpHCStruc, bHubAddr, bPortNum);
+ #else
+ return USB_ERROR; // Only root hub could be successfully enabled
+ #endif
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_ResetHubPort
+//
+// Description: This function resets the hub port
+//
+// Input: HcStruc HC struc pointer
+// HubAddr USB device address of the hub or HC number
+// BIT7 = 1/0 Roothub/Hub
+// PortNum Port number
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_ResetHubPort (
+ HC_STRUC* HcStruc,
+ UINT8 HubAddr,
+ UINT8 PortNum)
+{
+ //
+ // Check whether the request is for root hub or generic hub
+ //
+ if (HubAddr & BIT7) {
+ //
+ // Root hub
+ // Issue the reset root hub call to reset the hub port
+ //
+ return (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDResetRootHub)(HcStruc, PortNum);
+ } else {
+ #if USB_DEV_HUB
+ return USBHub_ResetPort (HcStruc, HubAddr, PortNum);
+ #else
+ return USB_ERROR; // Only root hub could be successfully reset
+ #endif
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_DetectNewDevice
+//
+// Description: This function checks the port status provided and depending
+// on the status it invokes device connect/disconnect routine
+//
+// Output: fpHCStruc Pointer to HCStruc
+// bHubAddr For root port this is the host controller index
+// in gUsbData->aHCStrucTable combined with BIT7;
+// For devices connected to a hub this is parent
+// hub USB address
+// bHubPort Parent hub port number
+// bPortStatus Port status read
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USB_DetectNewDevice(
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bHubPort,
+ UINT8 bPortStatus
+)
+{
+ UINT8 bErrorFlag = 0;
+ UINT16 wDescLength;
+ UINT8 bDevConfigured;
+ UINTN ConfigLevel = 0;
+ UINT16 wTotalLength;
+ UINT8 *fpBuffer = NULL;
+ DEV_INFO *fpDevInfo,
+ *fPointer;
+ DEV_DESC *fpDevDesc;
+ CNFG_DESC *fpCnfgDesc;
+ INTRF_DESC *fpIntrfDesc;
+ UINT8 *DevMiscInfo;
+ UINT8 Status;
+ BOOLEAN SkipConnectBeep = FALSE; //(EIP64781+)
+ UINT16 OrgTimeOutValue; //(EIP75441+)
+ UINT8 DeviceAddress;
+
+ //
+ // Get the temporary device info structure pointer (index 0)
+ //
+ fpDevInfo = gUsbData->aDevInfoTable;
+
+ //
+ // Fill the necessary entries in the device info
+ //
+ fpDevInfo->Flag = DEV_INFO_VALID_STRUC;
+ fpDevInfo->bDeviceAddress = 0;
+ //fpDevInfo->wEndp0MaxPacket = 0x40; //(EIP98230-)
+ fpDevInfo->bDeviceType = 0;
+ fpDevInfo->wIncompatFlags = 0;
+ fpDevInfo->DevMiscInfo = NULL;
+
+ //
+ // Fill the hub/host controller information
+ //
+ fpDevInfo->bHubDeviceNumber = bHubAddr;
+ fpDevInfo->bHubPortNumber = bHubPort;
+
+ //
+ // Fill the device speed
+ //
+USB_DEBUG(DEBUG_LEVEL_3, "USB_DetectNewDevice: wPS = %x\n", bPortStatus);
+ fpDevInfo->bEndpointSpeed = (bPortStatus & USB_PORT_STAT_DEV_SPEED_MASK) >>
+ USB_PORT_STAT_DEV_SPEED_MASK_SHIFT;
+
+ //(EIP98145+)>
+#if SHOW_SKIP_PORT_INFORMATION
+{
+ UINT8 i;
+ DEV_INFO *tmpDevInfo;
+ tmpDevInfo = fpDevInfo;
+ USB_DEBUG(3, "==== SHOW_SKIP_PORT_INFORMATION ==== \n");
+ USB_DEBUG(DEBUG_LEVEL_3, "BDF %x \nRoutePath = ",fpHCStruc->wBusDevFuncNum);
+ for(i=0;i<5;i++)
+ {
+ if(tmpDevInfo->bHubDeviceNumber & BIT7)
+ {
+ USB_DEBUG(3, "\nRootPort %x \n",tmpDevInfo->bHubPortNumber);
+ break;
+ }
+ USB_DEBUG(3, "%x ",tmpDevInfo->bHubPortNumber);
+ tmpDevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR, 0, tmpDevInfo->bHubDeviceNumber, 0);
+ if(tmpDevInfo == NULL) break;
+ }
+ USB_DEBUG(3, "==== SHOW_SKIP_PORT_INFORMATION ==== \n");
+}
+#endif
+ //<(EIP98145+)
+ //(EIP98230+)>
+ switch (fpDevInfo->bEndpointSpeed) {
+ case USB_DEV_SPEED_SUPER_PLUS:
+ case USB_DEV_SPEED_SUPER:
+ fpDevInfo->wEndp0MaxPacket = 0x200;
+ break;
+ case USB_DEV_SPEED_HIGH:
+ fpDevInfo->wEndp0MaxPacket = 0x40;
+ break;
+ case USB_DEV_SPEED_FULL:
+ case USB_DEV_SPEED_LOW:
+ fpDevInfo->wEndp0MaxPacket = 0x08;
+ break;
+ }
+ //<(EIP98230+)
+
+ //
+ // Fill the HC struc index value
+ //
+ fpDevInfo->bHCNumber = fpHCStruc->bHCNumber;
+
+ bErrorFlag = TRUE; // Assume as error
+ bDevConfigured = FALSE; // No device configured
+
+ //
+ // Allocate memory for device requests
+ //
+ ConfigLevel = USB_ERR_DEV_INIT_MEM_ALLOC; // For proper error handling
+ fpBuffer = USB_MemAlloc (GET_MEM_BLK_COUNT(MAX_CONTROL_DATA_SIZE));
+ if (fpBuffer == NULL) {
+ SpeakerBeep(8, 0x2000, fpHCStruc);
+ return (DEV_INFO*)ConfigLevel;
+ }
+ ConfigLevel = USB_ERR_DEV_INIT_GET_DESC_8;
+
+ // Initialize HC specific data before device configuration
+ Status = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDInitDeviceData)(
+ fpHCStruc, fpDevInfo, bPortStatus, &DevMiscInfo);
+ if(Status != USB_SUCCESS) {
+ USB_MemFree(fpBuffer, (UINT8)(MAX_CONTROL_DATA_SIZE / sizeof(MEM_BLK)));
+ SpeakerBeep(8, 0x2000, fpHCStruc);
+ return (DEV_INFO*)ConfigLevel;
+ }
+ fpDevInfo->DevMiscInfo = (VOID*)DevMiscInfo;
+
+//
+// Next send a GetDescriptor command to the device to get its Device
+// Descriptor. Assume a MaxPacket size of 64 bytes (the device will use 8,
+// 16, 32, or 64). Regardless of the packet size used by te device we can
+// always get the real MaxPacket size that the device is using, because
+// this piece of information is at offset 7 in the device descriptor.
+//
+ OrgTimeOutValue = gUsbData->wTimeOutValue; //(EIP75441+)
+ gUsbData->wTimeOutValue = 1000; //(EIP75441+)
+
+ fpDevDesc = (DEV_DESC*)USB_GetDescriptor(
+ fpHCStruc,
+ fpDevInfo,
+ fpBuffer,
+ 8,
+ DESC_TYPE_DEVICE,
+ 0);
+
+ gUsbData->wTimeOutValue = OrgTimeOutValue; //(EIP75441+)
+ if(fpDevDesc == NULL) {
+ goto detection_complete;
+ }
+
+ //
+ // Get and store the endpoint 0 max packet size
+ //
+ ConfigLevel = USB_ERR_DEV_INIT_SET_ADDR;
+ //
+ // Endpoint 0 max packet size check.
+ // CyQ've USB modem(Model:MQ4UFM560) return invalid device descriptor after
+ // warm reset.
+ //
+ //(EIP81612)>
+ if (fpDevDesc->BcdUsb >= 0x0300) {
+ fpDevInfo->wEndp0MaxPacket = (UINT16)1 << fpDevDesc->MaxPacketSize0;
+ } else {
+ fpDevInfo->wEndp0MaxPacket = (fpDevDesc->MaxPacketSize0)?
+ (UINT16)fpDevDesc->MaxPacketSize0 : 0x40;
+ }
+ //<(EIP81612)
+ //(EIP73803)>
+ if((fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_LOW) ||
+ (fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_FULL) ||
+ (fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_HIGH)){
+ FixedDelay(10 * 1000); // 10msec delay
+ }
+ //<(EIP73803)
+
+ //To assign an address to a USB device, the USB device transitions the state
+ //from the Default to the Address state.
+ for (DeviceAddress = 1; DeviceAddress < 64; DeviceAddress++) {
+ if (gUsbData->DeviceAddressMap & Shl64(1, DeviceAddress)) {
+ break;
+ }
+ }
+
+ if (DeviceAddress == 64) {
+ goto detection_complete;
+ }
+ Status = USB_SetAddress(fpHCStruc, fpDevInfo, DeviceAddress);
+ if (Status == USB_ERROR) {
+ goto detection_complete;
+ }
+ gUsbData->DeviceAddressMap &= ~(Shl64(1, DeviceAddress));
+ fpDevInfo->bDeviceAddress = DeviceAddress;
+ FixedDelay(2 * 1000);
+
+ //
+ // Now send a GetDescriptor command to the device to get its device descriptor.
+ //
+ fpDevDesc = (DEV_DESC*)USB_GetDescriptor(
+ fpHCStruc,
+ fpDevInfo,
+ fpBuffer,
+ 18,
+ DESC_TYPE_DEVICE,
+ 0);
+
+ //ASSERT(fpDevDesc != NULL);
+ if (fpDevDesc == NULL) {
+ goto detection_complete;
+ }
+ // If a descriptor returns with a value in its length field that is
+ // less than defined by USB specification, the descriptor is invalid.
+ if (fpDevDesc->DescLength < 18) {
+ goto detection_complete;
+ }
+ if (fpDevDesc->NumConfigs == 0) {
+ fpDevDesc->NumConfigs = 1;
+ }
+
+ MemCopy((UINT8*)fpDevDesc, (UINT8*)&fpDevInfo->DevDesc, sizeof(DEV_DESC));
+
+ ConfigLevel = USB_ERR_DEV_INIT_GET_DESC_200;
+ //
+ // Get the relevant information from the descriptor and store it in
+ // device information struture
+ //
+ fpDevInfo->wVendorId = fpDevDesc->VendorId;
+ fpDevInfo->wDeviceId = fpDevDesc->DeviceId;
+//
+// Look at each of the device's ConfigDescriptors and InterfaceDescriptors
+// until an InterfaceDescriptor is found with BaseClass, SubClass, and
+// Protocol fields indicating boot keyboard, mouse, hub or storage support.
+//
+ fpDevInfo->bConfigNum = 0;
+
+ if (fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_FULL) {
+ FixedDelay(100);
+ }
+
+ do { // For processing multiple configurations
+ //(EIP70933+)>
+ fpCnfgDesc = (CNFG_DESC*)USB_GetDescriptor(
+ fpHCStruc,
+ fpDevInfo,
+ fpBuffer,
+ 0xFF,
+ DESC_TYPE_CONFIG,
+ fpDevInfo->bConfigNum);
+ if(fpCnfgDesc == NULL) {
+ break;
+ }
+ wTotalLength = fpCnfgDesc->wTotalLength;
+ if (wTotalLength > 0xFF) {
+ if(wTotalLength > (MAX_CONTROL_DATA_SIZE - 1)) {
+ wTotalLength = MAX_CONTROL_DATA_SIZE - 1;
+ }
+ fpCnfgDesc = (CNFG_DESC*)USB_GetDescriptor(
+ fpHCStruc,
+ fpDevInfo,
+ fpBuffer,
+ wTotalLength,
+ DESC_TYPE_CONFIG,
+ fpDevInfo->bConfigNum);
+ //<(EIP70933+)
+ if(fpCnfgDesc == NULL) {
+ break;
+ }
+ }
+ if (fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_FULL) {
+ FixedDelay(100);
+ }
+//
+// fpCnfgDesc should now point to a ConfigDescriptor. Verify this and
+// then get some fields out of it. Then point to the next descriptor.
+//
+ if(fpCnfgDesc->bDescType == DESC_TYPE_CONFIG) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDEnableEndpoints)(
+ fpHCStruc, fpDevInfo, (UINT8*)fpCnfgDesc);
+
+ //wTotalLength = fpCnfgDesc->wTotalLength; //(EIP70933-)
+ wDescLength = (UINT8)fpCnfgDesc->bDescLength;
+ fpDevInfo->bConfigNum = fpCnfgDesc->bConfigValue;
+
+ //(EIP70933-)>
+/*
+ if(wTotalLength > (MAX_CONTROL_DATA_SIZE - 1)) {
+ wTotalLength = MAX_CONTROL_DATA_SIZE - 1;
+ }
+*/
+ //<(EIP70933-)
+
+ // Check if the device has alternate setting for the interface.
+ for (;wDescLength < wTotalLength;) {
+ //
+ // fpIntrfDesc should now point to an InterfaceDescriptor. Verify this
+ // and then check its BaseClass, SubClass, and Protocol fields for
+ // usable devices.
+ //
+ fpIntrfDesc = (INTRF_DESC*)((UINT8*)fpCnfgDesc + wDescLength);
+ //(EIP59601+)>
+ if ((fpIntrfDesc->bDescLength == 0) ||
+ ((fpIntrfDesc->bDescLength + wDescLength) > wTotalLength)) {
+ break;
+ }
+ if ((fpIntrfDesc->bDescType == DESC_TYPE_INTERFACE) && (fpIntrfDesc->bAltSettingNum != 0)) {
+ fpDevInfo->Flag |= DEV_INFO_ALT_SETTING_IF;
+ break;
+ }
+ if (fpIntrfDesc->bDescLength) {
+ wDescLength += (UINT16)fpIntrfDesc->bDescLength;
+ } else {
+ break;
+ }
+ }
+
+ wDescLength = (UINT8)fpCnfgDesc->bDescLength;
+
+ for (;wDescLength < wTotalLength;) {
+ //
+ // fpIntrfDesc should now point to an InterfaceDescriptor. Verify this
+ // and then check its BaseClass, SubClass, and Protocol fields for
+ // usable devices.
+ //
+ fpIntrfDesc = (INTRF_DESC*)((UINT8*)fpCnfgDesc + wDescLength);
+ //(EIP59601+)>
+ if ((fpIntrfDesc->bDescLength == 0) ||
+ ((fpIntrfDesc->bDescLength + wDescLength) > wTotalLength)) {
+ break;
+ }
+ //<(EIP59601+)
+ if ((fpIntrfDesc->bDescType == DESC_TYPE_INTERFACE) && (fpIntrfDesc->bAltSettingNum == 0)) {
+ fpDevInfo->bInterfaceNum = fpIntrfDesc->bInterfaceNum;
+ fpDevInfo->bAltSettingNum = 0;
+ //USB_DEBUG(DEBUG_LEVEL_6, "USBIdentifyAndConfigureDevice::fpIntrfDesc %lx\n",fpIntrfDesc);
+ USB_DEBUG(DEBUG_LEVEL_3, "USBIdentifyAndConfigureDevice:: %04x/%04x Intrf %d, AltSetting %d\n",
+ fpDevInfo->wVendorId, fpDevInfo->wDeviceId, fpIntrfDesc->bInterfaceNum, fpIntrfDesc->bAltSettingNum);
+ USB_DEBUG(3, "fpCnfgDesc %x, wDescLength 0x%x, wTotalLength 0x%x\n", fpCnfgDesc, wDescLength, wTotalLength);
+ fPointer = USBIdentifyAndConfigureDevice(
+ fpHCStruc,
+ fpDevInfo,
+ (UINT8*)fpCnfgDesc,
+ wDescLength,
+ wTotalLength);
+ if(fPointer != NULL) {
+ fpDevInfo = fPointer;
+ bDevConfigured = TRUE; // At-least one device is configured
+ //(EIP64781+)>
+ if(gUsbData->dUSBStateFlag & USB_FLAG_SKIP_CARD_READER_CONNECT_BEEP) {
+ if(fpDevInfo->bBaseClass == BASE_CLASS_MASS_STORAGE) {
+ SkipConnectBeep = TRUE;
+ }
+ }
+ //<(EIP64781+)
+ }
+ //(EIP22046+)>
+ //
+ // There is one more config. Set device info structure entry 0 for it
+ //
+ if ((fpCnfgDesc->bNumInterfaces > 1) && bDevConfigured) {
+ gUsbData->aDevInfoTable[0].Flag |= DEV_INFO_MULTI_IF;
+ }
+ //<(EIP22046+)
+ }
+ if (fpIntrfDesc->bDescLength &&
+ !(fpIntrfDesc->bDescType == DESC_TYPE_INTERFACE &&
+ fpIntrfDesc->bBaseClass == BASE_CLASS_HUB)) {
+ wDescLength += (UINT16)fpIntrfDesc->bDescLength;
+ if (wDescLength < wTotalLength) {
+ //(EIP22046-)>
+ //
+ // There is one more config. Set device info structure entry 0 for it
+ //
+ /*
+ if (fpDevInfo->bInterfaceNum > 0) {
+ fpDevInfo->Flag |= DEV_INFO_MULTI_IF;
+ }
+ gUsbData->aDevInfoTable[0].Flag |= DEV_INFO_MULTI_IF;
+ */
+ //<(EIP22046-)
+ fpDevInfo = gUsbData->aDevInfoTable;
+ }
+ } else {
+ break; // fpIntrfDesc->bDescLength == 0
+ }
+ } // while ()
+ } // if
+ //
+ // Check if we have at least one usable device
+ //
+ if (bDevConfigured) {
+ bErrorFlag = FALSE; // Device successfully configured
+ ConfigLevel = (UINTN)gUsbData->aDevInfoTable;
+ goto detection_complete;
+ }
+ else {
+ fpDevInfo->bConfigNum++;
+ }
+ } while (fpDevInfo->bConfigNum < fpDevInfo->DevDesc.NumConfigs); // while
+
+detection_complete:
+ //
+ // At this point, if bErrorFlag is FALSE then we successfully configured
+ // atleast a device.
+ // If bErrorFlag is TRUE then there is error in configuring the device
+ //
+ if (bErrorFlag) {
+ USBLogError((UINT16)ConfigLevel); // Log configuration level
+
+ SpeakerBeep(8, 0x2000, fpHCStruc);
+
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDDeinitDeviceData)
+ (fpHCStruc, fpDevInfo);
+ if(ConfigLevel != USB_ERR_DEV_INIT_GET_DESC_8) {
+ //
+ // Disable the hub port
+ //
+ USB_DisableHubPort(
+ fpHCStruc,
+ fpDevInfo->bHubDeviceNumber,
+ fpDevInfo->bHubPortNumber);
+ ConfigLevel = 0;
+ }
+ if (fpDevInfo->bDeviceAddress) {
+ gUsbData->DeviceAddressMap |= Shl64(1, fpDevInfo->bDeviceAddress);
+ }
+ }
+ else {
+ //(EIP64781+)>
+ if(!SkipConnectBeep) {
+ SpeakerBeep(4, 0x1000, fpHCStruc);
+ }
+ //<(EIP64781+)
+ }
+ USB_MemFree(fpBuffer, (UINT8)(MAX_CONTROL_DATA_SIZE / sizeof(MEM_BLK)));
+
+ return (DEV_INFO*)ConfigLevel;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_StopDevice
+//
+// Description: This function stops the device:
+// - calls its disconnect function if available
+// - stops polling the device's interrupt endpoint
+// - updates device address memory map
+//
+//
+// Output: fpHCStruc Pointer to HCStruc
+// bHCNubAddr Hub address
+// bHCPort Port number
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_StopDevice(
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bHCPort)
+{
+ UINT8 bCount;
+ DEV_DRIVER* fpDevDriver;
+ DEV_INFO* fpDevice;
+ UINT8 Status;
+
+ Status = USB_ERROR;
+ //
+ // Find the device entry that would match the input.
+ //
+ for (bCount = 1; bCount < MAX_DEVICES; bCount++)
+ {
+ fpDevice = &gUsbData->aDevInfoTable[bCount];
+ if((fpDevice->Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_DUMMY)) ==
+ DEV_INFO_VALID_STRUC) {
+ if((fpDevice->bHubDeviceNumber == bHubAddr) &&
+ (fpDevice->bHubPortNumber == bHCPort))
+ {
+ //
+ // Device found - issue disconnect call for the device
+ //
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ if (!(fpDevice->Flag & DEV_INFO_IN_QUEUE)) {
+ USB_SmiQueuePut(fpDevice);
+ fpDevice->Flag |= DEV_INFO_IN_QUEUE;
+ }
+ }
+
+ fpDevDriver = UsbFindDeviceDriverEntry(fpDevice->fpDeviceDriver);
+ //
+ // Check disconnect function is valid, if yes - execute it
+ //
+ if (fpDevDriver && fpDevDriver->pfnDisconnectDevice)
+ {
+ fpDevDriver->pfnDisconnectDevice(fpDevice);
+ fpDevice->fpDeviceDriver = NULL;
+ } else {
+ //
+ // Stop polling the device's interrupt endpoint
+ //
+ if (fpDevice->IntInEndpoint) {
+ Status = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDDeactivatePolling)
+ (fpHCStruc, fpDevice);
+ fpDevice->IntInEndpoint = 0;
+ }
+ }
+
+ // HC device removal call
+ Status = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDDeinitDeviceData)
+ (fpHCStruc, fpDevice);
+
+ // Reset the disconnecting flag
+ fpDevice->Flag &= ~DEV_INFO_DEV_DISCONNECTING;
+
+ //
+ // Update Device Address Map, preserving the address for registered devices
+ //
+ gUsbData->DeviceAddressMap |= Shl64(1, fpDevice->bDeviceAddress);
+ fpDevice->Flag &= ~DEV_INFO_DEV_PRESENT;
+ if (!(fpDevice->Flag & (DEV_INFO_DEV_BUS | DEV_INFO_MASS_DEV_REGD))) {
+ // Reset the device info structure validity ~flag
+ fpDevice->Flag &= ~DEV_INFO_VALID_STRUC;
+ }
+ USB_DEBUG(3, "Release Dev[%d]: %x, flag %x\n", bCount, fpDevice, fpDevice->Flag);
+ }
+ }
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_DisconnectDevice
+//
+// Description: This function is called when a device disconnect is
+// detected. This routine disables the hub port and stops the
+// device and its children by calling another routine.
+//
+// Output: fpHCStruc Far pointer to HCStruc of the host controller
+// bHubAddr USB device address of the hub whose status
+// has changed
+// bit 7 : 1 - Root hub, 0 for other hubs
+// bit 6-0 : Device address of the hub
+// bPortNum Port number
+//
+// Output: Status: USB_SUCCESS = Success
+// USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_DisconnectDevice(
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bHCPort)
+{
+ //
+ // A device has been disconnected from the USB. First disable the hub port
+ // that the device was plugged into. Then free up the device's entry in the
+ // DeviceTable. If there an error occurs while disabling the port, assume
+ // that the device is still present an leave its DeviceTable entry in place.
+ //
+ USB_DisableHubPort(fpHCStruc, bHubAddr, bHCPort);
+
+ USB_StopDevice(fpHCStruc, bHubAddr, bHCPort);
+
+ return USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: USBCheckPortChange
+//
+// Description: This routine processes the port status change (like connect,
+// disconnect, etc.) for the root hub and external hubs.
+//
+// Output: HcStruc Pointer to Host Controller structure
+// HubAddr Device address of the hub whose status
+// has changed:
+// bit 7 : 1 - Root hub, 0 for other hubs
+// bit 6-0 : Device address of the hub
+// PortNum Hub port number
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBCheckPortChange (
+ HC_STRUC *HcStruc,
+ UINT8 HubAddr,
+ UINT8 PortNum
+)
+{
+ UINT8 PortStatus;
+ DEV_INFO *Dev;
+ UINT8 Count;
+
+ for (Count = 0; Count < 5; Count++) {
+ PortStatus = USB_GetHubPortStatus(HcStruc, HubAddr, PortNum, TRUE);
+
+ //
+ // Check the obtained port status
+ //
+ if (PortStatus == USB_ERROR) {
+ return USB_ERROR;
+ }
+ if (!(PortStatus & USB_PORT_STAT_DEV_OWNER)) {
+ return USB_SUCCESS;
+ }
+ if (OEMSkipList(HubAddr,PortNum,HcStruc->wBusDevFuncNum,0,0)) {
+ USB_DEBUG(3, "Match the skip table ; skipping this device.\n"); //(EIP98145)
+ return USB_SUCCESS;
+ }
+ if (!Count && !(PortStatus & USB_PORT_STAT_DEV_CONNECT_CHANGED)) {
+ return USB_SUCCESS;
+ }
+
+ if (PortStatus & USB_PORT_STAT_DEV_CONNECTED) {
+ if (gUsbData->bHandOverInProgress) {
+ USB_DisableHubPort(HcStruc, HubAddr, PortNum);
+ return USB_SUCCESS;
+ }
+ if ((Count != 0) || !(PortStatus & USB_PORT_STAT_DEV_ENABLED)) {
+ // Reset and enable the port
+ USB_ResetHubPort(HcStruc, HubAddr, PortNum);
+ USB_EnableHubPort(HcStruc, HubAddr, PortNum);
+ PortStatus = USB_GetHubPortStatus(HcStruc, HubAddr, PortNum, TRUE);
+
+ if (PortStatus == USB_ERROR) {
+ return USB_ERROR;
+ }
+ if (!(PortStatus & USB_PORT_STAT_DEV_OWNER)) {
+ return USB_SUCCESS;
+ }
+ if (!(PortStatus & USB_PORT_STAT_DEV_CONNECTED)) {
+ // Some device will be disconnected after
+ // port reset, and reconnected for a while.
+ FixedDelay(100 * 1000);
+ continue;
+ }
+ // Check whether port is enabled
+ if (!(PortStatus & USB_PORT_STAT_DEV_ENABLED)) {
+ FixedDelay(100 * 1000); // 100msec delay
+ continue;
+ }
+ }
+ Dev = USB_DetectNewDevice(HcStruc, HubAddr, PortNum, PortStatus);
+ if ((UINTN)Dev == USB_ERR_DEV_INIT_GET_DESC_8) {
+ FixedDelay(100 * 1000); // 100msec delay
+ continue;
+ }
+ if ((UINTN)Dev == 0) {
+ return USB_ERROR;
+ }
+ if ((UINTN)Dev > USB_ERR_DEV_INIT_GET_DESC_200) {
+ return USB_SUCCESS;
+ }
+ SpeakerBeep(16, 0x4000, HcStruc); // Issue error beep
+ return USB_ERROR;
+ } else { // Disconnect
+ USB_DisconnectDevice(HcStruc, HubAddr, PortNum);
+ SpeakerBeep(8, 0x1000, HcStruc);
+ return USB_SUCCESS;
+ }
+ }
+ if (Count == 5) {
+ USB_DisableHubPort(HcStruc, HubAddr, PortNum);
+ return USB_ERROR;
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_MemAlloc
+//
+// Description: This routine allocates blocks of memory from the global
+// memory pool
+//
+// Output: bNumBlocks Number of 32 byte blocks needed
+//
+// Output: Start offset to the allocated block (NULL on error)
+//
+// NOTES: This routine allocates continuous 32 byte memory blocks.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID _FAR_ *
+USB_MemAlloc(UINT16 wNumBlk)
+{
+ UINT8 bMemIsFound = FALSE,
+ bBitCount = 0,
+ bStart = 0;
+ UINT16 wCount;
+ UINT16 Count = 0; // Contiguous blocks counter
+
+ UINT16 BlkOffset = 0,
+ wMapDwordPtr;
+ //(EIP89641)>
+ UINT16 PageCount = 0;
+ UINT16 MapDwordCount = 0;
+ UINT32 BlksStsDwordsPerPage = 0;
+
+ UINT32 dMask,
+ dTemp;
+
+ if (wNumBlk == 0) return NULL;
+
+#if USB_FORCE_64BIT_ALIGNMENT
+ if (wNumBlk % 2) wNumBlk++;
+#endif
+ wCount = wNumBlk;
+
+ BlksStsDwordsPerPage = (gUsbData->MemBlkStsBytes >> 2) / gUsbData->MemPages;
+
+ //
+ // Locate wNumBlk contiguous blocks from each memory page
+ //
+ for(PageCount = 0; (PageCount < gUsbData->MemPages) && !bMemIsFound; PageCount++) {
+
+ // Do not reset the counter if the allocated blocks greater than a page.
+ if (wNumBlk <= (0x1000 / sizeof(MEM_BLK))) {
+ Count = 0; // Reset contiguous blocks counter
+ }
+
+ for (MapDwordCount = 0; MapDwordCount < BlksStsDwordsPerPage; MapDwordCount++) {
+ //
+ // Read the next DWORD memory map data
+ //
+ wMapDwordPtr = (PageCount * BlksStsDwordsPerPage) + MapDwordCount;
+ dTemp = gUsbData->aMemBlkSts[wMapDwordPtr];
+
+ for (bBitCount = 0; bBitCount < 32; bBitCount++) {
+ BlkOffset++;
+ if (dTemp & (UINT32)(1 << bBitCount)) {
+ Count++; // Found another free block
+ if(Count == wCount) {
+ BlkOffset = (UINT16)(BlkOffset-Count);
+ bMemIsFound = TRUE;
+ break; // Found the requested number of free blocks
+ }
+ }
+ else
+ {
+ Count = 0; // Reset contiguous blocks counter
+ }
+ }
+ if (bMemIsFound) break;
+ }
+ }
+ //<(EIP89641)
+ if (!bMemIsFound) {
+ ASSERT(FALSE);
+ return NULL;
+ }
+
+//
+// Change the appropriate bits in the memory map to indicate that some memory
+// is being allocated
+//
+// At this point,
+// bBitCount points to the end of the block within DWORD
+// wMapDwordPtr points to the status dword in question
+
+// We have to reset bCount number of bits starting from
+// wMapDwordPtr[bBitCount] to wStsX[BitPosY]
+// where wStsX is the status double word of the starting block,
+// BitPosY is the bit position of the starting block.
+//
+ USB_DEBUG(DEBUG_LEVEL_4, "wMapDwordPtr = %d\n", wMapDwordPtr);
+//
+// Let us have a do loop to do the trick
+//
+ do {
+ //
+ // Find out how many bits we can reset in current (pointed by wMapDwordPtr)
+ // double word
+ //
+ Count = (UINT16)((bBitCount >= (wCount-1)) ? wCount : bBitCount+1);
+ //
+ // Find out the starting bit offset
+ //
+ bStart = (UINT8)(bBitCount + 1 - Count);
+ //
+ // Form the 32bit mask for the AND operation
+ // First prepare the bits left on the left
+ //
+ // Note: FFFFFFFF << 32 treated differently by different compilers; it
+ // results as 0 for 16 bit compiler and FFFFFFFF for 32 bit. That's why
+ // we use caution while preparing the AND mask for the memory map update.
+ //
+ dMask = ((Count + bStart) < 32) ? (0xFFFFFFFF << (Count + bStart)) : 0;
+
+ //
+ // Second, prepare the bits on the right
+ //
+ if (bStart)
+ {
+ dMask = dMask | ~(0xFFFFFFFF << bStart);
+ }
+
+ //
+ // Reset the specified number of bits
+ //
+ gUsbData->aMemBlkSts[wMapDwordPtr] &= dMask;
+
+ //
+ // Update the bCount, StsWordCount & BitCount
+ //
+ bBitCount = 31; // End of previous double word where we have to start
+ wMapDwordPtr--; // Previous double word
+ wCount = wCount - Count;
+ } while ( wCount );
+
+ USB_DEBUG(DEBUG_LEVEL_4, "MemAlloc: %d block(s) at %x %x %x\n",
+ wNumBlk,
+ gUsbData->fpMemBlockStart + BlkOffset * sizeof(MEM_BLK),
+ gUsbData->aMemBlkSts[0],
+ gUsbData->aMemBlkSts[1]);
+
+ return ((VOID _FAR_ *)
+ (gUsbData->fpMemBlockStart + (UINT32)BlkOffset * sizeof(MEM_BLK)));
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_MemFree
+//
+// Description: This routine frees the chunk of memory allocated using
+// the USBMem_Alloc call
+//
+// Output: fpPtr Pointer to the memory block to be freed
+// bNumBlocks Number of 32 byte blocks to be freed
+//
+// Output: Start offset to the allocated block (NULL on error)
+//
+// NOTES: This routine frees continuous memory blocks starting
+// from the fpPtr.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_MemFree (
+ VOID _FAR_ * fpPtr,
+ UINT16 wNumBlk)
+{
+ UINT8 bOffset, bCount;
+ UINT16 wBlkCount, wBlkOffset, wStsWord;
+
+#if USB_FORCE_64BIT_ALIGNMENT
+ if (wNumBlk % 2) wNumBlk++;
+#endif
+ wBlkCount = wNumBlk;
+ wBlkOffset = 0;
+
+ //
+ // Check for pointer validity
+ //
+ if (fpPtr == NULL) return USB_ERROR;
+
+ if ((fpPtr < (VOID *)gUsbData->fpMemBlockStart) ||
+ (fpPtr > (VOID *)(gUsbData->fpMemBlockStart +
+ (MEM_BLK_COUNT+1)*sizeof(MEM_BLK)))) {
+ return USB_ERROR;
+ }
+
+ wBlkOffset = (UINT16)((UINTN)fpPtr - (UINTN)gUsbData->fpMemBlockStart) / sizeof (MEM_BLK);
+
+ if (wBlkOffset >= MEM_BLK_COUNT) {
+ return USB_ERROR;
+ }
+
+ wStsWord = (UINT16)(wBlkOffset >> 5); // Divide by 32
+ bOffset = (UINT8)(wBlkOffset & 0x1F); // Mod 32
+ bCount = 0;
+
+ do {
+ gUsbData->aMemBlkSts[wStsWord] |= ((UINT32)1 << (bCount + bOffset));
+ wBlkCount--;
+ bCount++;
+
+ if ((bCount + bOffset) && (!((bCount + bOffset) & 0x1F))) {
+ wStsWord ++;
+ bCount = bOffset = 0;
+ }
+ } while (wBlkCount);
+
+ USB_DEBUG(DEBUG_LEVEL_4, "MemFree: %d block(s) at %x %x %x\n",
+ wNumBlk, fpPtr,
+ gUsbData->aMemBlkSts[0], gUsbData->aMemBlkSts[1]);
+ //
+ // Pointer is valid. Fill the memory with 0's
+ //
+ MemFill (fpPtr, (UINT32)(wNumBlk * sizeof (MEM_BLK)), 0);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_InstallCallBackFunction
+//
+// Description: This function adds a new callback function to the globall
+// callback function list and returns the index of it.
+//
+// Output: pfnCallBackFunction Callback function address
+//
+// Output: Callback function index
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_InstallCallBackFunction (
+ CALLBACK_FUNC CallBackFunction
+)
+{
+ UINT8 Index;
+ //
+ // Check whether this function is already installed or none found
+ //
+ for (Index = 0; Index < MAX_CALLBACK_FUNCTION; Index++) {
+ //
+ // Check for null entry
+ //
+ if (gUsbData->aCallBackFunctionTable[Index] == 0) {
+ break; // No entry found
+ }
+
+ if (gUsbData->aCallBackFunctionTable[Index] == CallBackFunction) {
+ return (UINT8)(Index+1);
+ }
+ }
+
+ ASSERT(Index != MAX_CALLBACK_FUNCTION);
+ if (Index == MAX_CALLBACK_FUNCTION) {
+ EFI_DEADLOOP(); // Exceeding max # of callback function is illegal
+ } else {
+ //
+ // Store the call back function
+ //
+ gUsbData->aCallBackFunctionTable[Index] = CallBackFunction;
+ }
+
+ return (UINT8)(Index + 1);
+}
+
+DEV_DRIVER*
+UsbFindDeviceDriverEntry(
+ DEV_DRIVER* DevDriver
+)
+{
+ UINTN Index;
+
+ if (DevDriver == NULL) {
+ return DevDriver;
+ }
+
+ for (Index = 0; Index < MAX_DEVICE_TYPES; Index++) {
+ if (DevDriver == &gUsbData->aDevDriverTable[Index]) {
+ return &gUsbData->aDevDriverTable[Index];
+ }
+ if (DevDriver == &gUsbData->aDelayedDrivers[Index]) {
+ return &gUsbData->aDelayedDrivers[Index];
+ }
+ }
+
+ return NULL;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_GetDescriptor
+//
+// Description: This function executes a get descriptor command to the
+// given USB device and endpoint
+//
+// Output: fpHCStruc HCStruc pointer
+// fpDevInfo Device info pointer
+// fpBuffer Buffer to be used for the transfer
+// wLength Size of the requested descriptor
+// bDescType Requested descriptor type
+// bDescIndex Descriptor index
+//
+// Output: Pointer to memory buffer containing the descriptor
+// NULL on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8*
+USB_GetDescriptor(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpBuffer,
+ UINT16 wLength,
+ UINT8 bDescType,
+ UINT8 bDescIndex)
+{
+ UINT8 bGetDescIteration;
+ UINT16 wReg,
+ wStatus;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return NULL;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return NULL;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpBuffer, wLength);
+ if (EFI_ERROR(EfiStatus)) {
+ return NULL;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+ //(EIP60640)>
+ for (bGetDescIteration = 0; bGetDescIteration < 5; bGetDescIteration++) {
+ wReg = (UINT16)((bDescType << 8) + bDescIndex);
+ wStatus = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDControlTransfer)(
+ fpHCStruc,
+ fpDevInfo,
+ (UINT16)USB_RQ_GET_DESCRIPTOR,
+ (UINT16)0,
+ wReg,
+ fpBuffer,
+ wLength);
+ if (wStatus) {
+ return fpBuffer;
+ }
+ if (gUsbData->dLastCommandStatusExtended & USB_TRNSFR_TIMEOUT) {
+ break;
+ }
+ FixedDelay(10 * 1000);
+ }
+ //<(EIP60640)
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_SetAddress
+//
+// Description: This function sets the USB device address of device 0 to
+// the given value. After this call the USB device will respond
+// at its new address.
+//
+// Output: fpHCStruc Pointer to HCStruc structure
+// fpDevInfo Pointer to device info structure
+// bNewDevAddr New device address to set
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+// Notes: Skip SET_ADDRESS request for XHCI controllers
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_SetAddress(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8 bNewDevAddr)
+{
+ //(EIP60640)>
+ UINT8 SetAddressIteration;
+
+ for (SetAddressIteration = 0; SetAddressIteration < 5; SetAddressIteration++) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDControlTransfer)(
+ fpHCStruc,
+ fpDevInfo,
+ (UINT16)USB_RQ_SET_ADDRESS,
+ 0,
+ (UINT16)bNewDevAddr,
+ 0,
+ 0);
+ if (!(gUsbData->bLastCommandStatus & USB_CONTROL_STALLED )) {
+ USB_DEBUG(DEBUG_LEVEL_5, "USB_SetAddress#%d\n",bNewDevAddr);
+ return USB_SUCCESS;
+ }
+ }
+ return USB_ERROR;
+ //<(EIP60640)
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_SetConfig
+//
+// Description: This function sets the device configuration.
+//
+// Input: HcStruc Pointer to HCStruc structure
+// DevInfo Pointer to device info structure
+// ConfigNum Configuration Value
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_SetConfig(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 ConfigNum)
+{
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDControlTransfer)(
+ HcStruc,
+ DevInfo,
+ USB_RQ_SET_CONFIGURATION,
+ 0,
+ (UINT16)ConfigNum,
+ 0,
+ 0);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: UsbSetInterface
+//
+// Description: This function sets the device interface.
+//
+// Input: HcStruc Pointer to HCStruc structure
+// DevInfo Pointer to device info structure
+// InterfaceNum Interface Value
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbSetInterface(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 InterfaceNum
+)
+{
+ USB_DEBUG(3, "UsbSetInterface %d\n", InterfaceNum);
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDControlTransfer)(
+ HcStruc,
+ DevInfo,
+ USB_RQ_SET_INTERFACE,
+ 0,
+ (UINT16)InterfaceNum,
+ 0,
+ 0);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USBLogError
+//
+// Description: This routine logs the USB error in the data area. This
+// logged errors will be displayed during the POST.
+//
+// Output: wErrorCode Error code to log
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBLogError(UINT16 wErrorCode)
+{
+ //
+ // First check for end of the buffer
+ //
+ if(gUsbData->bErrorLogIndex < MAX_USB_ERRORS_NUM)
+ {
+ //
+ // Still have space to log errors
+ //
+ gUsbData->aErrorLogBuffer[gUsbData->bErrorLogIndex] = wErrorCode;
+ gUsbData->bErrorLogIndex++;
+ }
+ return USB_ERROR;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_GetDeviceInfoStruc
+//
+// Description: This function is used to retrieve the device info structure
+// for the particular device address & HCStruc
+//
+// Output: bSearchFlag Flag indicating search type
+// = USB_SRCH_DEV_ADDR to search by device address and
+// HCStruc pointer
+// = USB_SRCH_DEV_TYPE to search by device type
+// = USB_SRCH_HC_STRUC to search by HC struc pointer
+// = USB_SRCH_DEV_NUM to count the number of devices connected:
+// if fpHCStruc is not NULL - count only devices connected to
+// certain controller, otherwise - all devices of requested
+// type.
+// = USB_SERCH_DEV_INDX to search by device location in the DEV_INFO:
+// a) if fpDevInfo <> 0 return index or the fpDevInfo
+// b) if bDevAddr <> 0 return the corresponding fpDevInfo
+// c) if both bDevAddr <> 0 and fpDevInfo <> 0, consider a)
+//
+// fpDevInfoPtr Pointer to the device info structure from where the
+// search begins (if 0 start from first entry)
+// bDev Device address/drive number/device type
+// pHCStruc Pointer to the HCStruc structure
+//
+// Output: Depending on bSearchFlag this function returns:
+// - pointer to DEV_INFO structure
+// - table index
+// - number of devices
+// Function returns NULL if device is not found.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USB_GetDeviceInfoStruc(
+ UINT8 bSearchFlag,
+ DEV_INFO* fpDev_Info,
+ UINT8 bDev,
+ HC_STRUC* fpHcStruc
+)
+{
+ UINT8 Index;
+ BOOLEAN TerminateSearch = FALSE;
+ UINT32 dDeviceCounter = 0;
+
+ if (bSearchFlag == USB_SRCH_DEV_INDX) {
+ if (fpDev_Info) {
+ for (Index=1; Index < MAX_DEVICES; Index++) {
+ if (&gUsbData->aDevInfoTable[Index] == fpDev_Info) {
+ return (DEV_INFO*)(UINTN)Index;
+ }
+ }
+ return NULL; // Device address not found in the table
+ }
+ if (bDev == USB_HOTPLUG_FDD_ADDRESS) return &gUsbData->FddHotplugDev;
+ if (bDev == USB_HOTPLUG_HDD_ADDRESS) return &gUsbData->HddHotplugDev;
+ if (bDev == USB_HOTPLUG_CDROM_ADDRESS) return &gUsbData->CdromHotplugDev;
+
+ if (bDev) return &gUsbData->aDevInfoTable[bDev];
+ return NULL; // Invalid input - both bDev and fpDevInfo are zeroes.
+ }
+
+ for (Index = 1; Index < MAX_DEVICES; Index ++) {
+ //
+ // if fpDev_Info is not null then position the search at the correct
+ // index that matches the fpDev_Info
+ //
+ if (fpDev_Info) {
+ if (&gUsbData->aDevInfoTable[Index] != fpDev_Info)
+ continue;
+ else {
+ fpDev_Info = 0;
+ continue;
+ }
+ }
+ //
+ // For USB_SRCH_DEVBASECLASS_NUM devices are counted regardless of their
+ // DEV_INFO_VALID_STRUC flag
+ //
+ if (bSearchFlag == USB_SRCH_DEVBASECLASS_NUM)
+ {
+ if(gUsbData->aDevInfoTable[Index].bBaseClass == bDev) {
+ if (fpHcStruc) {
+ //
+ // Check if device belongs to the specified HC
+ //
+ if (gUsbData->aDevInfoTable[Index].bHCNumber != fpHcStruc->bHCNumber)
+ {
+ continue;
+ }
+ }
+ if (gUsbData->aDevInfoTable[Index].Flag & DEV_INFO_DEV_PRESENT)
+ {
+ dDeviceCounter++;
+ }
+ }
+ continue;
+ }
+
+ if ((gUsbData->aDevInfoTable[Index].Flag & DEV_INFO_VALIDPRESENT) ==
+ DEV_INFO_VALIDPRESENT){
+ switch(bSearchFlag) {
+ case USB_SRCH_HC_STRUC:
+ if (fpHcStruc == NULL) return NULL;
+ if (gUsbData->HcTable
+ [gUsbData->aDevInfoTable[Index].bHCNumber-1] == fpHcStruc) {
+ TerminateSearch = TRUE;
+ }
+ break;
+
+ case USB_SRCH_DEV_TYPE:
+ if (gUsbData->aDevInfoTable[Index].bDeviceType == bDev) {
+ TerminateSearch = TRUE;
+ }
+ break;
+ case USB_SRCH_DEV_NUM:
+ if (gUsbData->aDevInfoTable[Index].bDeviceType == bDev) {
+ if (fpHcStruc) {
+ //
+ // Check if device belongs to the specified HC
+ //
+ if (gUsbData->aDevInfoTable[Index].bHCNumber != fpHcStruc->bHCNumber)
+ {
+ break;
+ }
+ }
+ dDeviceCounter++;
+ }
+ break; // Do not change TerminateSearch so loop continues
+ case USB_SRCH_DEV_ADDR:
+ if (gUsbData->aDevInfoTable[Index].bDeviceAddress == bDev) {
+ if ((fpHcStruc == NULL) ||
+ (gUsbData->HcTable
+ [gUsbData->aDevInfoTable[Index].bHCNumber-1] == fpHcStruc)) {
+ TerminateSearch = TRUE;
+ }
+ }
+ break;
+
+ default:
+ return NULL;
+ }
+ }
+ if (TerminateSearch) return ((DEV_INFO*)&gUsbData->aDevInfoTable[Index]);
+ }
+ if ( (bSearchFlag == USB_SRCH_DEV_NUM) || (bSearchFlag == USB_SRCH_DEVBASECLASS_NUM) )
+ return (DEV_INFO*)(UINTN)dDeviceCounter;
+
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// PROCEDURE: UsbAllocDevInfo
+//
+// Description: Finds a non-used DEV_INFO record in aDevInfoTable and marks it
+// reserved. To free the user need to clear DEV_INFO_VALID_STRUC
+// bit in bFlag of DEV_INFO
+//
+// Output: Pointer to new device info. struc. 0 on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+DEV_INFO* UsbAllocDevInfo()
+{
+ UINT8 bIndex;
+ DEV_INFO *fpNewDevInfo;
+
+ for (bIndex = 1; bIndex < MAX_DEVICES; bIndex ++){
+ fpNewDevInfo = gUsbData->aDevInfoTable +bIndex;
+ if ((fpNewDevInfo->Flag &
+ ( DEV_INFO_VALID_STRUC | DEV_INFO_DEV_BUS)) == 0 ){
+ //
+ // Free device info structure. Save it if not.
+ //
+ fpNewDevInfo->Flag |= DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT;
+ return fpNewDevInfo;
+ }
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBGetProperDeviceInfoStructure
+//
+// Description: This routine searches for a device info structure that
+// matches the vendor and device id, and LUN of the device
+// found. If such a device info structure not found, then it
+// will return a free device info structure
+//
+// Input: Vendor, Device ID, Current LUN
+//
+// Output: Pointer to new device info. struc. NULL on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBGetProperDeviceInfoStructure(
+ DEV_INFO* Dev,
+ UINT8 Lun)
+{
+ UINT8 bCount;
+ DEV_INFO *fpDevInfo, *fpFreeDevInfo;
+
+ fpFreeDevInfo = NULL;
+
+//
+// Scan through the device info table for a free entry. Also if the device
+// connected is a mass storage device look for a device info structure whose
+// device is disconnected and its vendor & device id matches the one of
+// current device. If such a structure found that means this device may be
+// reconnected - use the same structure
+//
+ for (bCount = 1; bCount < MAX_DEVICES; bCount++)
+ {
+ fpDevInfo = (DEV_INFO*) &gUsbData->aDevInfoTable[bCount];
+
+ if (fpDevInfo->Flag & DEV_INFO_DEV_DUMMY) {
+ continue;
+ }
+
+ // Check whether the structure is valid
+ if (!(fpDevInfo->Flag & DEV_INFO_VALID_STRUC)) {
+ if (fpFreeDevInfo == NULL) {
+ fpFreeDevInfo = fpDevInfo; // Store the value of the free device info
+ }
+ } else {
+ //
+ // Yes, structure is valid. Check for device presence
+ //
+ if (fpDevInfo->Flag & DEV_INFO_DEV_PRESENT) {
+ if ((fpDevInfo->bHubDeviceNumber != Dev->bHubDeviceNumber) ||
+ (fpDevInfo->bHubPortNumber != Dev->bHubPortNumber)) {
+ continue;
+ }
+ }
+ //
+ // Device is not present. Match the vendor, device id and LUN with
+ // current device info
+ //
+ if ((fpDevInfo->wVendorId == Dev->wVendorId) &&
+ (fpDevInfo->wDeviceId == Dev->wDeviceId) &&
+ (fpDevInfo->bInterfaceNum == Dev->bInterfaceNum) &&
+ (fpDevInfo->bEndpointSpeed == Dev->bEndpointSpeed) &&
+ (fpDevInfo->bLUN == Lun)) {
+ return fpDevInfo; // "Abandoned" device entry found
+ }
+ }
+ }
+ return fpFreeDevInfo;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// PROCEDURE: USB_ConfigureDevice
+//
+// Description: This routine completes the USB device configuration for
+// the devices supported by USB BIOS. This routine
+// handles the generic configuration for the devices.
+//
+// Output: pHCStruc HCStruc pointer
+// pDevInfo Device information structure pointer
+// pDesc Pointer to the descriptor structure
+// wStart Offset within interface descriptor
+// supported by the device
+// wEnd End offset of the device descriptor
+//
+// Output: Pointer to new device info. struc. 0 on error
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USB_ConfigureDevice (
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Desc,
+ UINT16 Start,
+ UINT16 End
+)
+{
+ DEV_INFO *NewDevInfo;
+
+ NewDevInfo = USBGetProperDeviceInfoStructure(DevInfo, 0);
+
+ if (NewDevInfo == NULL) {
+ return NULL;
+ }
+ //
+ // Check whether this device is reconnected by checking the valid
+ // structure flag
+ //
+ if (NewDevInfo->Flag & DEV_INFO_VALID_STRUC) {
+ USB_DEBUG(DEBUG_LEVEL_3, "USB_ConfigureDevice: Existing device.\n");
+ //
+ // This device is reconnected. Reuse the old device address so that
+ // INT13h can identify this drive properly
+ //
+ DevInfo->Flag |= NewDevInfo->Flag;
+ NewDevInfo->wDataInSync = 0;
+ NewDevInfo->wDataOutSync = 0;
+ }
+ else {
+ //
+ // Check whether we reached the limit of devices of this type
+ //
+ if (CheckDeviceLimit(DevInfo->bBaseClass) == TRUE) {
+ return NULL;
+ }
+ }
+
+ //
+ // For registered devices skip updating bFlag
+ //
+ if (!(NewDevInfo->Flag & DEV_INFO_MASS_DEV_REGD)) {
+ //
+ // Since DeviceInfo[0] already has many fields filled in, the new entry
+ // should be initialized with a copy of DeviceInfo[0]. But, the new
+ // DeviceInfo should not be marked as "present" until the device
+ // is successfully initialized.
+ //
+ // Copy old DeviceInfo struc to new DeviceInfo struc and zero device[0]
+ //
+ MemCopy ((UINT8*)DevInfo, (UINT8*)NewDevInfo, sizeof (DEV_INFO));
+ NewDevInfo->Flag &= DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT |
+ DEV_INFO_MASS_DEV_REGD | DEV_INFO_DEV_BUS |
+ DEV_INFO_IN_QUEUE | DEV_INFO_ALT_SETTING_IF;
+ } else {
+ // Change the parent HC number and port number in the existing DEV_INFO
+ NewDevInfo->bHCNumber = DevInfo->bHCNumber;
+ NewDevInfo->bHubDeviceNumber = DevInfo->bHubDeviceNumber;
+ NewDevInfo->bHubPortNumber = DevInfo->bHubPortNumber;
+ NewDevInfo->bEndpointSpeed = DevInfo->bEndpointSpeed;
+ NewDevInfo->wEndp0MaxPacket = DevInfo->wEndp0MaxPacket;
+ NewDevInfo->DevMiscInfo = DevInfo->DevMiscInfo;
+ NewDevInfo->bDeviceAddress = DevInfo->bDeviceAddress;
+ }
+
+ //
+ // Do a SetConfiguration command to the device to set it to its
+ // HID/Boot configuration.
+ //
+ NewDevInfo->Flag |= DEV_INFO_VALIDPRESENT;
+ if (!(DevInfo->Flag & DEV_INFO_MULTI_IF)) {
+ USB_SetConfig(HcStruc, NewDevInfo, NewDevInfo->bConfigNum);
+ if (DevInfo->Flag & DEV_INFO_ALT_SETTING_IF) {
+ UsbSetInterface(HcStruc, NewDevInfo, NewDevInfo->bAltSettingNum);
+ }
+ }
+
+ USB_DEBUG(3, "new dev: %x, flag: %x, addr %d\n",
+ NewDevInfo, NewDevInfo->Flag, NewDevInfo->bDeviceAddress);
+
+ return NewDevInfo;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCheckNonCompliantDevice
+//
+// Description: This function checks for non-compliant USB devices by
+// by comparing the device's vendor and device id with
+// the non-compliant device table list and updates the
+// data structures appropriately to support the device.
+//
+// Input: fpHCStruc - HCStruc pointer
+// fpDevInfo - Device information structure pointer
+// fpDesc - Pointer to the descriptor structure
+// wDescLength - End offset of the device descriptor
+//
+// Output: Updated fpDevInfo->wIncompatFlags field
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBCheckNonCompliantDevice(
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpDesc,
+ UINT16 wLength,
+ UINT16 wDescLength
+)
+{
+ USB_BADDEV_STRUC *fpBadDevice;
+ INTRF_DESC *fpIntrfDesc;
+
+ fpIntrfDesc = (INTRF_DESC*)((UINT8*)fpDesc + wLength);
+
+ //
+ // Search the bad device table to get the structure for this device
+ //
+ for (fpBadDevice = gUsbBadDeviceTable;
+ fpBadDevice->wDID | fpBadDevice->wVID; fpBadDevice++) {
+
+ if ((fpBadDevice->wDID != fpDevInfo->wDeviceId) ||
+ (fpBadDevice->wVID != fpDevInfo->wVendorId)) {
+ continue;
+ }
+USB_DEBUG(DEBUG_LEVEL_3, "Found non-compatible device: DID=%x, VID=%x\n", fpBadDevice->wDID, fpBadDevice->wVID);
+ //
+ // Save the incompatibility flag into device info structure
+ //
+ fpDevInfo->wIncompatFlags = fpBadDevice->wFlags;
+
+ //
+ // Check which fields to update in the interface descriptor
+ //
+ // Check for base class field
+ //
+ if (fpBadDevice->bBaseClass) {
+ //
+ // Update base class field in the interface descriptor
+ //
+ fpIntrfDesc->bBaseClass = fpBadDevice->bBaseClass;
+ }
+ //
+ // Check for base sub class field
+ //
+ if (fpBadDevice->bSubClass) {
+ //
+ // Update sub class field in the interface descriptor
+ //
+ fpIntrfDesc->bSubClass = fpBadDevice->bSubClass;
+ }
+ //
+ // Check for protocol field
+ //
+ if (fpBadDevice->bProtocol) {
+ //
+ // Update protocol field in the interface descriptor
+ //
+ fpIntrfDesc->bProtocol = fpBadDevice->bProtocol;
+ }
+ break;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// PROCEDURE: USBIdentifyAndConfigureDevice
+//
+// Description: This routine invokes the device drivers 'check device type'
+// routine and identifies the device type.
+//
+// Output: pHCStruc HCStruc pointer
+// pDevInfo Device information structure pointer
+// pDesc Pointer to the descriptor structure
+// wStart Offset within interface descriptor
+// supported by the device
+// wEnd End offset of the device descriptor
+//
+// Output: Pointer to new device info. struc, NULL on error
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBIdentifyAndConfigureDevice (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpDesc,
+ UINT16 wLength,
+ UINT16 wDescLength)
+{
+ UINT8 bBaseClass, bSubClass, bProtocol,
+ bIndex, bRetValue;
+ DEV_INFO* fpDevInfoLocal;
+ DEV_DRIVER* fpDevDriver;
+ INTRF_DESC* fpIntrfDesc;
+
+ //
+ // Check for non-compliant device. If non-compliant device found then
+ // the descriptor values will get updated depending on the need.
+ //
+ USBCheckNonCompliantDevice (
+ fpHCStruc,
+ fpDevInfo,
+ fpDesc,
+ wLength,
+ wDescLength);
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USBIdentifyAndConfigureDevice...");
+
+ //
+ // Check whether device needs to be disable
+ //
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_DISABLE_DEVICE) {
+ USB_DEBUG(DEBUG_LEVEL_3, "not compatible device.\n");
+ return NULL;
+ }
+
+ fpIntrfDesc = (INTRF_DESC*)(fpDesc + wLength);
+
+//(EIP74609+)>
+ if(OEMSkipList(fpDevInfo->bHubDeviceNumber,fpDevInfo->bHubPortNumber,fpHCStruc->wBusDevFuncNum,fpIntrfDesc->bBaseClass,1)) {
+ USB_DEBUG(3, "Match the skip table ; skipping this device.\n"); //(EIP98145)
+ return NULL;
+ }
+//<(EIP74609+)
+ //
+ // Get the base, sub class & protocol values
+ //
+ bBaseClass = fpIntrfDesc->bBaseClass;
+ bSubClass = fpIntrfDesc->bSubClass;
+ bProtocol = fpIntrfDesc->bProtocol;
+
+ //
+ // Check for matching device driver
+ //
+ fpDevInfoLocal = NULL;
+ bRetValue = USB_ERROR;
+
+ //(EIP96616+)>
+ for (bIndex = 0; bIndex < MAX_DEVICE_TYPES; bIndex ++) {
+ fpDevDriver = &gUsbData->aDevDriverTable[bIndex];
+ //
+ // Check structure validity
+ //
+ if (!fpDevDriver->bDevType) {
+ continue; // Driver table not valid
+ }
+ //
+ // Verify presence of Check Device routine
+ //
+ if (fpDevDriver->pfnCheckDeviceType) {
+ //
+ // Check device type is implemented. Execute it!
+ //
+ bRetValue = (*fpDevDriver->pfnCheckDeviceType)(
+ fpDevInfo,bBaseClass,
+ bSubClass,bProtocol);
+ if (bRetValue != USB_ERROR)
+ break;
+ } else {
+ //
+ // Check device type is not implemented. Compare the class codes
+ //
+ if((fpDevDriver->bBaseClass == bBaseClass) ||
+ (fpDevDriver->bSubClass == bSubClass) ||
+ (fpDevDriver->bProtocol == bProtocol)) {
+ //
+ // If the class codes match set bRetValue with the bDevType from the Device Driver
+ //
+ bRetValue = fpDevDriver->bDevType;
+ break;
+ }
+ }
+ }
+ if(bRetValue != USB_ERROR){
+ //
+ // Check whether we reached the limit of devices of this type
+ //
+ //if (CheckDeviceLimit(bBaseClass) == TRUE) continue; //(EIP81761-)
+
+ //
+ // Set the device type in the Device Info structure
+ //
+ fpDevInfo->bDeviceType = bRetValue;
+
+ //
+ // Set Base Class, Subclass and Protocol information
+ //
+ fpDevInfo->bBaseClass = bBaseClass;
+ fpDevInfo->bProtocol = bProtocol;
+ fpDevInfo->bSubClass = bSubClass;
+
+ //
+ // Device identified. Issue common configure call
+ // Call a common routine to handle the remaining initialization that is done
+ // for all devices.
+ //
+ fpDevInfoLocal = USB_ConfigureDevice(
+ fpHCStruc,
+ fpDevInfo,
+ fpDesc,
+ wLength,
+ wDescLength);
+
+ if (fpDevInfoLocal == NULL) {
+ USB_DEBUG(DEBUG_LEVEL_3, "USB: Common configure failed.\n");
+ return fpDevInfoLocal;
+ }
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ if (!(fpDevInfoLocal->Flag & DEV_INFO_IN_QUEUE)) {
+ USB_SmiQueuePut(fpDevInfoLocal);
+ fpDevInfoLocal->Flag |= DEV_INFO_IN_QUEUE;
+ }
+ }
+
+ fpDevInfoLocal->fpDeviceDriver = fpDevDriver;
+ fpDevInfoLocal = (*fpDevDriver->pfnConfigureDevice)(
+ fpHCStruc,
+ fpDevInfoLocal,
+ fpDesc,
+ wLength,
+ wDescLength);
+ if (!fpDevInfoLocal ||
+ !(fpDevInfoLocal->Flag & DEV_INFO_VALID_STRUC) )
+ {
+ fpDevInfoLocal = 0;
+ USB_DEBUG(DEBUG_LEVEL_3, "USB: Device specific configure failed.\n");
+ return fpDevInfoLocal;
+ }
+
+ //<(EIP96616+)
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "%x\n", fpDevInfoLocal);
+
+ return fpDevInfoLocal;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USB_InitFrameList
+//
+// Description: This routine initializes the frame list pointed by fpPtr
+// with the dValue provided
+//
+// Output: fpHCStruc Pointer to the Host Controller structure
+// dValue Value to be initialized with
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+
+VOID
+USB_InitFrameList(
+ HC_STRUC* fpHCStruc,
+ UINT32 dValue)
+{
+ UINT16 wIndex;
+ UINT32 *fpPtr = (UINT32*)fpHCStruc->fpFrameList;
+
+ for (wIndex = 0; wIndex < fpHCStruc->wAsyncListSize; wIndex ++) {
+ fpPtr[wIndex] = dValue;
+ }
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBKeyRepeat
+//
+// Description: This function handles different key repeat related functions
+// depending on the input
+//
+// Input: fpHCStruc - pointer for the HC that implements the key repeat function
+// bAction - sub-function index:
+// 0 Install key repeat HCStruc
+// 1 Disable key repeat
+// 2 Enable key repeat
+// 3 Uninstall key repeat HCStruc
+//
+// Output: None
+//
+// Note: fpHCStruc is only relevant for sub-function 0.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBKeyRepeat(
+ HC_STRUC* HcStruc,
+ UINT8 Action
+)
+{
+
+//USB_DEBUG(DEBUG_LEVEL_3, "KR%d\n", bAction);
+ UINT8 i;
+
+ switch (Action) {
+ case 0: // Sub-function 0: Save the HCStruc value for later use
+ if (gKeyRepeatStatus == FALSE) {
+ gUsbData->fpKeyRepeatHCStruc = HcStruc;
+ }
+ break;
+ case 1: // Sub-function 0: Disable key repeat
+ if (gKeyRepeatStatus) {
+#if USB_HID_KEYREPEAT_USE_SETIDLE == 1
+ if (gUsbData->fpKeyRepeatDevInfo != NULL) {
+ //
+ // Set the HID SET_IDLE request to 0
+ //
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable[gUsbData->fpKeyRepeatDevInfo->bHCNumber - 1]->bHCType)].pfnHCDControlTransfer)
+ (gUsbData->HcTable[gUsbData->fpKeyRepeatDevInfo->bHCNumber - 1],
+ gUsbData->fpKeyRepeatDevInfo,(UINT16)HID_RQ_SET_IDLE, gUsbData->fpKeyRepeatDevInfo->bInterfaceNum, 0, 0, 0); //(EIP54782)
+ }
+#else
+ if (gUsbData->fpKeyRepeatHCStruc) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ gUsbData->fpKeyRepeatHCStruc->bHCType)].pfnHCDDisableKeyRepeat)(
+ gUsbData->fpKeyRepeatHCStruc);
+ }
+#endif
+ gKeyRepeatStatus = FALSE;
+ }
+ break;
+ case 2: // Sub-function 0: Enable key repeat
+ if (!gKeyRepeatStatus) {
+#if USB_HID_KEYREPEAT_USE_SETIDLE == 1
+ if(gUsbData->fpKeyRepeatDevInfo != NULL) {
+ //
+ // Set the HID SET_IDLE request to 0x200 (8ms)
+ //
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable[gUsbData->fpKeyRepeatDevInfo->bHCNumber - 1]->bHCType)].pfnHCDControlTransfer)
+ (gUsbData->HcTable[gUsbData->fpKeyRepeatDevInfo->bHCNumber - 1],
+ gUsbData->fpKeyRepeatDevInfo,(UINT16)HID_RQ_SET_IDLE, gUsbData->fpKeyRepeatDevInfo->bInterfaceNum, 0x400, 0, 0); //(EIP54782)
+ }
+#else
+ if (gUsbData->fpKeyRepeatHCStruc) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ gUsbData->fpKeyRepeatHCStruc->bHCType)].pfnHCDEnableKeyRepeat)(
+ gUsbData->fpKeyRepeatHCStruc);
+ }
+#endif
+ gKeyRepeatStatus=TRUE;
+ }
+ break;
+ case 3:
+ if (gUsbData->fpKeyRepeatHCStruc == HcStruc) {
+ gUsbData->fpKeyRepeatHCStruc = NULL;
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ if (gUsbData->HcTable[i] == NULL) {
+ continue;
+ }
+ if (gUsbData->HcTable[i] == HcStruc) {
+ continue;
+ }
+ if (gUsbData->HcTable[i]->dHCFlag & HC_STATE_RUNNING) {
+ gUsbData->fpKeyRepeatHCStruc = gUsbData->HcTable[i];
+ if (gKeyRepeatStatus) {
+ gKeyRepeatStatus = FALSE;
+ USBKeyRepeat(NULL, 2);
+ }
+ break;
+ }
+ }
+ }
+ break;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: BusFillDriverEntries
+//
+// Description: Install drivers that redirects ...????
+//
+// Input: fpDevDriver - record that the routine can use to install the drive
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_bus_interrupt_handler (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ USBHC_INTERRUPT_DEVNINFO_T *Idi = (USBHC_INTERRUPT_DEVNINFO_T *)DevInfo->pExtra;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ ASSERT(Idi);
+ if (Idi == NULL) {
+ return USB_SUCCESS;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Idi, sizeof(USBHC_INTERRUPT_DEVNINFO_T));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+#endif
+
+ USB_SmiQueuePutMsg(&Idi->QCompleted, Buffer, (int)Idi->DataLength);
+ return USB_SUCCESS;
+}
+
+VOID
+UsbBusDeviceInit(
+ VOID
+)
+{
+ USB_InstallCallBackFunction(USB_bus_interrupt_handler);
+ return;
+}
+
+DEV_INFO*
+USB_on_configDev(
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 *fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd
+)
+{
+ fpDevInfo->bDeviceType = (UINT8)BIOS_DEV_TYPE_USBBUS;
+ fpDevInfo->bCallBackIndex = USB_InstallCallBackFunction(USB_bus_interrupt_handler);
+ return(fpDevInfo);
+}
+
+UINT8
+USB_on_identifyDev(
+ DEV_INFO* fpDevInfo,
+ UINT8 bBaseClass,
+ UINT8 bSubClass,
+ UINT8 bProtocol
+)
+{
+ //(EIP96616+)>
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)
+ return BIOS_DEV_TYPE_USBBUS;
+ else
+ return USB_ERROR;
+ //<(EIP96616+)
+}
+
+UINT8
+USB_on_disconnectDev(
+ DEV_INFO* fpDevInfo
+)
+{
+ return USB_SUCCESS;
+}
+
+VOID
+BusFillDriverEntries(
+ DEV_DRIVER *fpDevDriver
+)
+{
+ fpDevDriver->bDevType = BIOS_DEV_TYPE_USBBUS;
+ fpDevDriver->bBaseClass = 0;
+ fpDevDriver->bSubClass = 0;
+ fpDevDriver->bProtocol = 0;
+ fpDevDriver->pfnDeviceInit = UsbBusDeviceInit;
+ fpDevDriver->pfnCheckDeviceType = USB_on_identifyDev;
+ fpDevDriver->pfnConfigureDevice = USB_on_configDev;
+ fpDevDriver->pfnDisconnectDevice = USB_on_disconnectDev;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USB_ReConfigDevice, USB_ReConfigDevice2
+//
+// Description: EFI code will call this function to give a chance for
+// SMI dev driver to complete the configuration of device
+//
+// Before call, USB device is connected, address is assigned
+// and configuration is set. DEV_INFO structure is initalized
+// from information parsed from descriptors and linked
+// to USBBUS dev driver. Device driver specific to the type
+// of USB device wasn't called on this device
+//
+// After the call returns, a specific device driver
+// initialization was performed by calling pfnCheckDeviceType
+// and pfnConfigureDevice functions of device driver. Parameters
+// to those functions are taken from descriptors downloaded from
+// the device. Device preserve old address and active configuration
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+int USB_ReConfigDevice2( HC_STRUC* fpHCStruc, DEV_INFO* fpDevInfo,
+ CNFG_DESC *fpCnfgDesc,
+ INTRF_DESC * fpIntrfDesc );
+
+int USB_ReConfigDevice( HC_STRUC* fpHCStruc, DEV_INFO* fpDevInfo )
+{
+ INTRF_DESC *fpIntrfDesc=NULL;
+
+ UINT8 iConfig;
+ int status = USB_SUCCESS; //(EIP90124)
+ UINT8* fpBuffer;
+ CNFG_DESC *fpCnfgDesc=NULL;
+ UINT16 OrgTimeOutValue;
+
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ gCheckUsbApiParameter = FALSE;
+
+ if (fpDevInfo->bDeviceType != 0 &&
+ fpDevInfo->bDeviceType != BIOS_DEV_TYPE_USBBUS) {
+ return USB_SUCCESS;
+ }
+
+ fpBuffer = USB_MemAlloc (GET_MEM_BLK_COUNT(MAX_CONTROL_DATA_SIZE));
+ if (fpBuffer == NULL) {
+ return USB_ERROR;
+ }
+ //
+ // Find configuration desc
+ //
+ for (iConfig = 0; iConfig < fpDevInfo->DevDesc.NumConfigs;++iConfig){
+
+ OrgTimeOutValue = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = USB_GET_CONFIG_DESC_TIMEOUT_MS;
+
+ fpCnfgDesc = (CNFG_DESC*)USB_GetDescriptor(
+ fpHCStruc,
+ fpDevInfo,
+ fpBuffer,
+ (MAX_CONTROL_DATA_SIZE - 1),
+ DESC_TYPE_CONFIG,
+ iConfig);
+
+ gUsbData->wTimeOutValue = OrgTimeOutValue;
+
+ if (fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_FULL) {
+ FixedDelay(1000);
+ }
+ if(fpCnfgDesc != NULL && fpCnfgDesc->bDescType == DESC_TYPE_CONFIG &&
+ fpDevInfo->bConfigNum == fpCnfgDesc->bConfigValue ){
+ break;
+ }
+
+ fpCnfgDesc = NULL;
+ }
+
+ if( fpCnfgDesc ){
+ UINT16 offset;
+ UINT16 wDescLength;
+ INTRF_DESC *pIntrf;
+
+ if(fpCnfgDesc->wTotalLength > MAX_CONTROL_DATA_SIZE - 1)
+ fpCnfgDesc->wTotalLength = MAX_CONTROL_DATA_SIZE - 1;
+ wDescLength = fpCnfgDesc->wTotalLength;
+ for(offset=(UINT16)fpCnfgDesc->bDescLength;offset <wDescLength ;offset = offset + (UINT16)pIntrf->bDescLength){
+ pIntrf = (INTRF_DESC*)((UINT8*)fpCnfgDesc + offset);
+ if(pIntrf->bDescLength == 0) {
+ break;
+ }
+ if (pIntrf->bDescType == DESC_TYPE_INTERFACE &&
+ fpDevInfo->bInterfaceNum == pIntrf->bInterfaceNum &&
+ fpDevInfo->bAltSettingNum == pIntrf->bAltSettingNum ) {
+ fpIntrfDesc =pIntrf;
+ break;
+ }
+ }
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3,
+ "USB_reConfigDev:: CfgDsc=%x; IntrfDsc=%x\n",
+ fpCnfgDesc, fpIntrfDesc);
+
+ if (fpIntrfDesc && fpCnfgDesc) {
+ status = USB_ReConfigDevice2(fpHCStruc, fpDevInfo,
+ fpCnfgDesc, fpIntrfDesc);
+ } else {
+ status = USB_ERROR;
+ }
+
+ USB_MemFree(fpBuffer, (UINT8)(MAX_CONTROL_DATA_SIZE / sizeof(MEM_BLK)));
+
+ return status;
+}
+
+//----------------------------------------------------------------------------
+// USB_ReConfigDevice2
+//----------------------------------------------------------------------------
+int
+USB_ReConfigDevice2(
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ CNFG_DESC *fpCnfgDesc,
+ INTRF_DESC *fpIntrfDesc
+)
+{
+// int abort=0;
+ int bIndex;
+ UINT8 bRetValue = USB_ERROR;
+ DEV_DRIVER *fpDevDriver = NULL;
+ DEV_INFO *fpDevInfoLocal;
+ UINT8 bBaseClass, bSubClass, bProtocol;
+ EFI_STATUS EfiStatus;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USB_ReConfigDevice2.\n");
+
+
+ EfiStatus = UsbHcStrucValidation(fpHCStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpCnfgDesc, sizeof(CNFG_DESC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpCnfgDesc, fpCnfgDesc->wTotalLength);
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)fpIntrfDesc, sizeof(INTRF_DESC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ //
+ // Check for non-compliant device. If non-compliant device found then
+ // the descriptor values will get updated depending on the need.
+ //
+ USBCheckNonCompliantDevice (
+ fpHCStruc,
+ fpDevInfo,
+ (UINT8*)fpCnfgDesc,
+ fpCnfgDesc->bDescLength,
+ fpCnfgDesc->wTotalLength);
+
+ //
+ // Check whether device needs to be disable
+ //
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_DISABLE_DEVICE)
+ {
+ return USB_ERROR;
+ }
+
+ //
+ // Get the base, sub class & protocol values
+ //
+ bBaseClass = fpIntrfDesc->bBaseClass;
+ bSubClass = fpIntrfDesc->bSubClass;
+ bProtocol = fpIntrfDesc->bProtocol;
+
+ //
+ // Check for matching device driver
+ //
+ fpDevInfoLocal = NULL;
+ for (bIndex = 0, bRetValue = USB_ERROR;
+ bIndex < MAX_DEVICE_TYPES && bRetValue == USB_ERROR; bIndex ++) {
+ fpDevDriver = &gUsbData->aDelayedDrivers[bIndex];
+ if (!fpDevDriver->bDevType)
+ continue;
+ if (fpDevDriver->pfnCheckDeviceType){
+ bRetValue = (*fpDevDriver->pfnCheckDeviceType)(
+ fpDevInfo,bBaseClass,bSubClass,bProtocol);
+ }else if((fpDevDriver->bBaseClass == bBaseClass) &&
+ (fpDevDriver->bSubClass == bSubClass) &&
+ (fpDevDriver->bProtocol == bProtocol)){
+ bRetValue = fpDevDriver->bDevType;
+ }
+ }
+ if(bRetValue == USB_ERROR)
+ return bRetValue;
+
+ //driver was found
+
+ fpDevInfo->bDeviceType = bRetValue;
+ fpDevInfo->fpDeviceDriver = fpDevDriver;
+ fpDevInfoLocal = (*fpDevDriver->pfnConfigureDevice)(
+ fpHCStruc,fpDevInfo,(UINT8*)fpCnfgDesc,
+ (UINT16)(UINTN)((char*)fpIntrfDesc - (char*)fpCnfgDesc),fpCnfgDesc->wTotalLength);
+ if (!fpDevInfoLocal)
+ {
+ USB_DEBUG(DEBUG_LEVEL_0, "USB_ReConfigDevice2: Device specific configure failed.\n");
+ return USB_ERROR;
+ }
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: hcnum2hcstruc
+//
+// Description: Search for the HC_STRUC with specified bHCNumber
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+HC_STRUC*
+hcnum2hcstruc(
+ UINT8 bHCNumber
+)
+{
+ return gUsbData->HcTable[bHCNumber - 1];
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: prepareForLegacyOS
+//
+// Description: Changes global state of USBSMI module to function properly
+// in non-EFI OS - without support from EFI drivers
+//
+// Before call USB BUS is a driver that handles all devices (
+// except hub) and rest of the drivers are delayed. Number of
+// devices are supported by SUBBUS driver and custom EFI driver
+//
+// After call returns, USBBUS driver is removed and all drivers
+// that where
+// delayed became active. All USBBUS devices are reconfigured.
+// Devices that are not supported by now active drivers are decon-
+// figured.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+prepareForLegacyOS()
+{
+ //(EIP96616)>
+ DEV_INFO* di;
+ HC_STRUC* fpHCStruc;
+ DEV_INFO* e = gUsbData->aDevInfoTable + COUNTOF(gUsbData->aDevInfoTable);
+ int status;
+
+ gCheckUsbApiParameter = FALSE;
+
+
+ //
+ //First Reconfigure all USBBUS device (while drivers are in delayed array)
+ //
+ for( di = &gUsbData->aDevInfoTable[1]; di != e; ++di ){ //(EIP34448)
+ if((di->Flag & DEV_INFO_VALIDPRESENT) == DEV_INFO_VALIDPRESENT &&
+ di->bDeviceType == BIOS_DEV_TYPE_USBBUS )
+ {
+ fpHCStruc = hcnum2hcstruc(di->bHCNumber);
+ status = USB_ReConfigDevice(fpHCStruc, di );
+ if(status == USB_ERROR){
+ //
+ // Release DEV_INFO
+ //
+ di->Flag &= ~DEV_INFO_VALIDPRESENT;
+ }
+ }
+ //di->Flag &= ~DEV_INFO_DEV_BUS;
+ }
+ //<(EIP96616)
+
+
+ USBKeyRepeat(NULL, 1); // Disable key repeat
+ //gUsbData->dUSBStateFlag |= USB_FLAG_RUNNING_UNDER_OS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USB_ResetAndReconfigDev
+//
+// Description: This routine resets and reconfigures the device.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USB_ResetAndReconfigDev(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo
+)
+{
+ DEV_INFO *Dev;
+ UINT32 Status;
+ UINT8 DevAddr;
+ UINT8 *Buffer;
+ DEV_DESC *DevDesc;
+ CNFG_DESC *CnfgDesc;
+ INTRF_DESC *IntrfDesc;
+ UINT8 ConfigIndx;
+ UINT8 IntrfIndx;
+ DEV_DRIVER *DevDriver;
+ UINT8 i;
+ UINT8 PortStatus;
+ UINT8 *DevMiscInfo;
+ UINT16 TotalLength;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ gCheckUsbApiParameter = FALSE;
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+ Dev = &gUsbData->aDevInfoTable[i];
+ if ((Dev->Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT |
+ DEV_INFO_DEV_DUMMY)) != (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT)) {
+ continue;
+ }
+ if ((Dev->bHubDeviceNumber == DevInfo->bHubDeviceNumber) &&
+ (Dev->bHubPortNumber == DevInfo->bHubPortNumber) &&
+ (Dev->bDeviceType != BIOS_DEV_TYPE_USBBUS)) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ HcStruc->bHCType)].pfnHCDDeactivatePolling)(HcStruc, Dev);
+ }
+ }
+
+ Status = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDDeinitDeviceData)
+ (HcStruc, DevInfo);
+ if (Status != USB_SUCCESS) {
+ return Status;
+ }
+
+ Status = USB_ResetHubPort(HcStruc, DevInfo->bHubDeviceNumber, DevInfo->bHubPortNumber);
+ if (Status != USB_SUCCESS) {
+ return Status;
+ }
+
+ Status = USB_EnableHubPort(HcStruc, DevInfo->bHubDeviceNumber, DevInfo->bHubPortNumber);
+ if (Status != USB_SUCCESS) {
+ return Status;
+ }
+
+ PortStatus = USB_GetHubPortStatus(HcStruc, DevInfo->bHubDeviceNumber, DevInfo->bHubPortNumber, TRUE);
+
+ if (PortStatus == USB_ERROR) {
+ return USB_ERROR;
+ }
+
+ if (!(PortStatus & USB_PORT_STAT_DEV_ENABLED)) {
+ return USB_ERROR;
+ }
+
+ // Initialize HC specific data before device configuration
+ Status = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDInitDeviceData)(
+ HcStruc, DevInfo, PortStatus, &DevMiscInfo);
+ if (Status != USB_SUCCESS) {
+ return Status;
+ }
+
+ DevInfo->DevMiscInfo = (VOID*)DevMiscInfo;
+
+ Buffer = USB_MemAlloc(GET_MEM_BLK_COUNT(sizeof(DEV_DESC)));
+ if (Buffer == NULL) {
+ return USB_ERROR;
+ }
+
+ DevAddr = DevInfo->bDeviceAddress;
+ DevInfo->bDeviceAddress = 0;
+
+ DevDesc = (DEV_DESC*)USB_GetDescriptor(HcStruc, DevInfo, Buffer, sizeof(DEV_DESC),
+ DESC_TYPE_DEVICE, 0);
+ if(DevDesc == NULL) {
+ USB_MemFree(Buffer, GET_MEM_BLK_COUNT(sizeof(DEV_DESC)));
+ return USB_ERROR;
+ }
+
+ Status = USB_SetAddress(HcStruc, DevInfo, DevAddr);
+ if (Status != USB_SUCCESS) {
+ USB_MemFree(DevDesc, GET_MEM_BLK_COUNT(sizeof(DEV_DESC)));
+ return Status;
+ }
+
+ DevInfo->bDeviceAddress = DevAddr;
+
+ Buffer = USB_MemAlloc(GET_MEM_BLK_COUNT(MAX_CONTROL_DATA_SIZE));
+ if (Buffer == NULL) {
+ USB_MemFree(DevDesc, GET_MEM_BLK_COUNT(sizeof(DEV_DESC)));
+ return USB_ERROR;
+ }
+
+ for (ConfigIndx = 0; ConfigIndx < DevDesc->NumConfigs; ConfigIndx++) {
+ CnfgDesc = (CNFG_DESC*)USB_GetDescriptor(HcStruc, DevInfo, Buffer,
+ 0xFF, DESC_TYPE_CONFIG, ConfigIndx);
+ if (CnfgDesc == NULL) {
+ continue;
+ }
+ TotalLength = CnfgDesc->wTotalLength;
+ if (TotalLength > 0xFF) {
+ if (TotalLength > (MAX_CONTROL_DATA_SIZE - 1)) {
+ TotalLength = MAX_CONTROL_DATA_SIZE - 1;
+ }
+ CnfgDesc = (CNFG_DESC*)USB_GetDescriptor(HcStruc, DevInfo, Buffer,
+ TotalLength, DESC_TYPE_CONFIG, ConfigIndx);
+ if (CnfgDesc == NULL) {
+ continue;
+ }
+ }
+
+ if (CnfgDesc->bDescType == DESC_TYPE_CONFIG) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDEnableEndpoints)(
+ HcStruc, DevInfo, (UINT8*)CnfgDesc);
+ }
+
+ USB_SetConfig(HcStruc, DevInfo, CnfgDesc->bConfigValue);
+
+ IntrfDesc = (INTRF_DESC*)CnfgDesc;
+ for (IntrfIndx = 0; IntrfIndx < CnfgDesc->bNumInterfaces; IntrfIndx++) {
+ do {
+ IntrfDesc = (INTRF_DESC*)((UINTN)IntrfDesc + IntrfDesc->bDescLength);
+ if ((UINTN)IntrfDesc > ((UINTN)CnfgDesc + CnfgDesc->wTotalLength) ||
+ (UINTN)IntrfDesc > ((UINTN)CnfgDesc + MAX_CONTROL_DATA_SIZE)) {
+ break;
+ }
+ } while (IntrfDesc->bDescType != DESC_TYPE_INTERFACE);
+
+ if (IntrfDesc->bDescType != DESC_TYPE_INTERFACE) {
+ break;
+ }
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+ Dev = &gUsbData->aDevInfoTable[i];
+ if ((Dev->Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT |
+ DEV_INFO_DEV_DUMMY)) != (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT)) {
+ continue;
+ }
+ if ((Dev->bHubDeviceNumber == DevInfo->bHubDeviceNumber) &&
+ (Dev->bHubPortNumber == DevInfo->bHubPortNumber) &&
+ (Dev->bConfigNum == CnfgDesc->bConfigValue) &&
+ (Dev->bInterfaceNum == IntrfDesc->bInterfaceNum) &&
+ (Dev->bAltSettingNum == IntrfDesc->bAltSettingNum)) {
+ break;
+ }
+ }
+ if (i == MAX_DEVICES) {
+ continue;
+ }
+
+ Dev->wVendorId = DevDesc->VendorId;
+ Dev->wDeviceId = DevDesc->DeviceId;
+
+ if (Dev->bDeviceType != BIOS_DEV_TYPE_USBBUS) {
+ DevDriver = UsbFindDeviceDriverEntry(Dev->fpDeviceDriver);
+ if (DevDriver != NULL) {
+ (*DevDriver->pfnConfigureDevice)(HcStruc, Dev, (UINT8*)CnfgDesc,
+ (UINT16)((UINTN)IntrfDesc - (UINTN)CnfgDesc), CnfgDesc->wTotalLength);
+ }
+ }
+ }
+ }
+
+ USB_MemFree(DevDesc, GET_MEM_BLK_COUNT(sizeof(DEV_DESC)));
+ USB_MemFree(Buffer, GET_MEM_BLK_COUNT(MAX_CONTROL_DATA_SIZE));
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USB_DevDriverDisconnect
+//
+// Description:
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USB_DevDriverDisconnect(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo
+)
+{
+ DEV_DRIVER* DevDriver;
+ UINT8 Index;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ gCheckUsbApiParameter = FALSE;
+
+ DevDriver = UsbFindDeviceDriverEntry(DevInfo->fpDeviceDriver);
+
+ if (DevDriver && DevDriver->pfnDisconnectDevice) {
+ DevDriver->pfnDisconnectDevice(DevInfo);
+
+ DevInfo->bDeviceType = 0;
+ DevInfo->fpDeviceDriver = NULL;
+
+ for (Index = 0; Index < MAX_DEVICE_TYPES; Index++) {
+ DevDriver = &gUsbData->aDevDriverTable[Index];
+
+ if (DevDriver->bDevType == BIOS_DEV_TYPE_USBBUS) {
+ DevInfo->bDeviceType = DevDriver->bDevType;
+ DevDriver->pfnConfigureDevice(HcStruc, DevInfo, NULL, 0, 0);
+ break;
+ }
+ }
+ } else {
+ if (DevInfo->IntInEndpoint) {
+ // Stop polling the device's interrupt endpoint
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDDeactivatePolling)
+ (HcStruc, DevInfo);
+ DevInfo->IntInEndpoint = 0;
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: VALID_DEVINFO
+//
+// Description: Checks if DEV_INFO is a valid connected device info
+// Due to hot-plug a DEV_INFO can become invalid in the
+// midle of configuration
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+int VALID_DEVINFO(DEV_INFO* pDevInfo)
+{
+ return (pDevInfo->Flag & DEV_INFO_VALIDPRESENT)!=0;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: USB_AbortConnectHubChildren
+//
+// Description: Mark DEV_INFO not valid for all the devices connected to a
+// given hub.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USB_AbortConnectHubChildren(
+ UINT8 HubAddr
+)
+{
+ UINT8 i;
+ DEV_INFO *Dev = &gUsbData->aDevInfoTable[1];
+
+ for (i=1; i<MAX_DEVICES; i++, Dev++) {
+ if ((Dev->bHubDeviceNumber == HubAddr) && (Dev->Flag & DEV_INFO_VALIDPRESENT)) {
+ Dev->Flag &= ~DEV_INFO_DEV_PRESENT;
+ if (!(Dev->Flag & DEV_INFO_MASS_DEV_REGD)) {
+ Dev->Flag &= ~DEV_INFO_VALID_STRUC;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USB: abort device [%x] connected to hub[%x]\n",
+ Dev->bDeviceAddress, HubAddr);
+
+ if (Dev->bDeviceType == BIOS_DEV_TYPE_HUB) {
+ USB_AbortConnectHubChildren(Dev->bDeviceAddress);
+ }
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: USB_FreeDeviceAddress
+//
+// Description: This routine releases the given device's address by
+// updating gUsbData->dDeviceAddressMap.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USB_FreeDeviceAddress(
+ DEV_INFO *DevInfo
+)
+{
+ UINT8 i;
+ UINT8 Found = 0;
+
+ if (DevInfo->bDeviceAddress)
+ {
+ for (i=1; i<MAX_DEVICES; i++) {
+ if (gUsbData->aDevInfoTable+i != DevInfo &&
+ gUsbData->aDevInfoTable[i].bDeviceAddress == DevInfo->bDeviceAddress)
+ {
+ Found++;
+ }
+ }
+ if (Found == 0){
+ //The DevInfo was the only function with allocated address -
+ // return the address to the pool
+ gUsbData->DeviceAddressMap |= Shl64(1, DevInfo->bDeviceAddress);
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USB_AbortConnectDev
+//
+// Description: Mark DEV_INFO not valid and release its device address
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USB_AbortConnectDev(
+ DEV_INFO* pDevInfo
+)
+{
+ USB_DEBUG(DEBUG_LEVEL_3, "USB: abort connect [%x].flag = %x\n",
+ pDevInfo, pDevInfo->Flag);
+
+ pDevInfo->Flag &= ~DEV_INFO_DEV_PRESENT;
+
+ if (!(pDevInfo->Flag & DEV_INFO_MASS_DEV_REGD)) {
+ pDevInfo->Flag &= ~DEV_INFO_VALID_STRUC;
+ if (pDevInfo->bDeviceAddress == 0) return;
+
+ USB_FreeDeviceAddress(pDevInfo);
+ }
+
+ // Remove children (if any) from aborted parent hub device.
+ // Assume the child device has not been connected since
+ // the hub has to be connected first.
+ if (pDevInfo->bDeviceType == BIOS_DEV_TYPE_HUB) {
+ USB_AbortConnectHubChildren(pDevInfo->bDeviceAddress);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: USB_SmiQueuePut
+//
+// Description: Puts the pointer pointer into the queue for processing,
+// updates queue head and tail.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USB_SmiQueuePut(VOID * d)
+{
+ QUEUE_T* q = &gUsbData->QueueCnnctDisc;
+
+ while (q->head >= q->maxsize) {
+ q->head -= q->maxsize;
+ }
+
+ q->data[q->head++] = d;
+ if (q->head == q->maxsize) {
+ q->head -= q->maxsize;
+ }
+ if (q->head == q->tail) {
+ //Drop data from queue
+ q->tail++;
+ while (q->tail >= q->maxsize) {
+ q->tail -= q->maxsize;
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: QueuePutMsg
+//
+// Description: Add a variable size item to the queue
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USB_SmiQueuePutMsg( QUEUE_T* q, VOID * d, int sz )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (q->head + sz > q->maxsize) {
+ q->head = 0;
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)((UINTN)q->data + q->head), sz);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+#endif
+ MemCopy((UINT8*)d, (UINT8*)((UINTN)q->data + q->head), sz);
+ q->head += sz;
+ if(q->head==q->maxsize) q->head = 0;
+ if(q->head==q->tail){
+ //Drop data from queue
+ q->tail+=sz;
+ if( q->tail >= q->maxsize ) q->tail = 0;
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: CheckDeviceLimit
+//
+// Description: Verifies whether the number of initialized devices of a given
+// class has reached the limit.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+CheckDeviceLimit(
+ UINT8 BaseClass
+)
+{
+ URP_STRUC Urp;
+ UINT8 DevNumber;
+
+ Urp.bFuncNumber = USB_API_CHECK_DEVICE_PRESENCE;
+ Urp.bSubFunc = 1;
+ Urp.ApiData.ChkDevPrsnc.fpHCStruc = NULL;
+ Urp.ApiData.ChkDevPrsnc.bDevType = BaseClass;
+
+ USBAPI_CheckDevicePresence(&Urp);
+
+ if (Urp.bRetValue == USB_SUCCESS)
+ {
+ DevNumber = Urp.ApiData.ChkDevPrsnc.bNumber;
+ if ((BaseClass == BASE_CLASS_HID)
+ && ((USB_DEV_HID_COUNT == 0) || (DevNumber == USB_DEV_HID_COUNT)))
+ {
+ USB_DEBUG(3, "Reached the limit of supported HIDs (%d); skipping this device.\n", USB_DEV_HID_COUNT);
+ return TRUE;
+ }
+
+ if ((BaseClass == BASE_CLASS_HUB)
+ && ((USB_DEV_HUB_COUNT == 0) || (DevNumber == USB_DEV_HUB_COUNT)))
+ {
+ USB_DEBUG(3, "Reached the limit of supported HUBs (%d); skipping this device.\n", USB_DEV_HUB_COUNT);
+ return TRUE;
+ }
+
+ if ((BaseClass == BASE_CLASS_MASS_STORAGE)
+ && ((USB_DEV_MASS_COUNT == 0) || (DevNumber == USB_DEV_MASS_COUNT)))
+ {
+ USB_DEBUG(3, "Reached the limit of supported Mass Storage Devices (%d); skipping this device.\n", USB_DEV_MASS_COUNT);
+ return TRUE;
+ }
+ if ((BaseClass == BASE_CLASS_CCID_STORAGE)
+ && ((USB_DEV_CCID_COUNT == 0) || (DevNumber == USB_DEV_CCID_COUNT+1)))
+ {
+ USB_DEBUG(3, "Reached the limit of supported CCID Devices (%d); skipping this device.\n", USB_DEV_CCID_COUNT);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbControlTransfer
+//
+// Description:
+//
+// Input:
+//
+// Output:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbControlTransfer(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ DEV_REQ DevReq,
+ UINT16 Timeout,
+ VOID* Buffer)
+{
+ UINT16 Status;
+ UINT16 SavedTimeout;
+
+ SavedTimeout = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = Timeout;
+
+ Status = (*gUsbData->aHCDriverTable[
+ GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDControlTransfer)(
+ HcStruc,
+ DevInfo,
+ DevReq.wRequestType,
+ DevReq.wIndex,
+ DevReq.wValue,
+ Buffer,
+ DevReq.wDataLength);
+
+ gUsbData->wTimeOutValue = SavedTimeout;
+
+ return DevReq.wDataLength && (Status == 0)? USB_ERROR : USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbInterruptTransfer
+//
+// Description: This function executes an interrupt transaction on the USB.
+//
+// Input:
+// HcStruc Pointer to HCStruc of the host controller.
+// DevInfo DeviceInfo structure (if available else 0).
+// EndpointAddress The destination USB device endpoint to which the device request
+// is being sent.
+// MaxPktSize Indicates the maximum packet size the target endpoint is capable
+// of sending or receiving.
+// Buffer Buffer containing data to be sent to the device or buffer to be
+// used to receive data.
+// Length Length request parameter, number of bytes of data to be transferred.
+// Timeout Indicates the maximum time, in milliseconds, which the transfer
+// is allowed to complete.
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbInterruptTransfer (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 EndpointAddress,
+ UINT16 MaxPktSize,
+ VOID *Buffer,
+ UINT16 Length,
+ UINT16 Timeout
+)
+{
+ UINT16 SavedTimeout;
+ UINT16 BytesTransferred;
+
+ SavedTimeout = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = Timeout;
+
+ BytesTransferred = (*gUsbData->aHCDriverTable[
+ GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDInterruptTransfer)(
+ HcStruc,
+ DevInfo,
+ EndpointAddress,
+ MaxPktSize,
+ Buffer,
+ Length);
+
+ gUsbData->wTimeOutValue = SavedTimeout;
+
+ if (BytesTransferred == 0) {
+ return USB_ERROR;
+ } else {
+ return USB_SUCCESS;
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: USB_EnableEndpointsDummy
+//
+// Description: Dummy HC API function used by the HC drivers that do not need
+// to implement enable endpoint function.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USB_EnableEndpointsDummy (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Desc
+)
+{
+ return USB_SUCCESS;
+}
+
+UINT8
+USB_InitDeviceDataDummy (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 PortStatus,
+ UINT8 **DeviceData
+)
+{
+ *DeviceData = NULL;
+ return USB_SUCCESS;
+}
+
+UINT8
+USB_DeinitDeviceDataDummy (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo
+)
+{
+ return USB_SUCCESS;
+}
+
+ //(EIP54018+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: LocatePwrCapOffset
+//
+// Description:
+// This function locate power management capability offset
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+LocatePwrCapOffset (
+ IN UINT16 BusDevFunc
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ UINT16 StatusReg;
+ UINT8 CapOffset;
+ EFI_PCI_CAPABILITY_HDR CapHeader;
+
+ // Check if device supports extended capabilities
+ StatusReg = (UINT16)ReadPCIConfig(BusDevFunc, PCI_STATUS_REGISTER_OFFSET);
+ if((StatusReg & PCI_STS_CAPABILITY) == 0) {
+ return 0;
+ }
+ // Get offset of first capability structure
+ CapOffset = (UINT8)ReadPCIConfig(BusDevFunc, EFI_PCI_CAPABILITY_PTR);
+ // Check capabilities until PMI is found or no more capabilities
+ while (CapOffset) {
+ CapHeader.CAP_HDR = (UINT16)ReadPCIConfig(BusDevFunc, CapOffset);
+ // If PMI block, return offset
+ if(CapHeader.CapabilityID == PCI_CAP_ID_PMI) {
+ return CapOffset;
+ }
+ // If not, check for next offset
+ CapOffset = CapHeader.NextItemPtr;
+ }
+#endif
+ return 0;
+}
+
+#if USB_S5_WAKEUP_SUPPORT
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: ResumePciBridge
+//
+// Description:
+// This function resumed PciBridge
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+ResumePciBridge(
+ UINT16 BusDevFun
+)
+{
+ UINT32 PmStaCtlReg;
+ UINT32 PmCapReg;
+ UINT8 PwrCapPtr;
+ UINT8 PciCommand;
+
+ PwrCapPtr = LocatePwrCapOffset(BusDevFun);
+
+ if (PwrCapPtr) {
+ PmCapReg = ReadPCIConfig(BusDevFun, PwrCapPtr);
+ PmStaCtlReg = ReadPCIConfig(BusDevFun, PwrCapPtr + 0x04);
+ if (PmCapReg & (BIT31 | BIT30)) {
+ PmStaCtlReg |= BIT8;
+ }
+ if (PmStaCtlReg & (BIT0 | BIT1)) {
+ PmStaCtlReg &= ~(BIT0 | BIT1);
+ }
+ DwordWritePCIConfig(BusDevFun, PwrCapPtr + 0x04, PmStaCtlReg);
+ }
+
+ PciCommand = (UINT8)ReadPCIConfig(BusDevFun, PCI_COMMAND_REGISTER_OFFSET);
+ PciCommand |= (PCI_CMD_MEMORY_SPACE + PCI_CMD_BUS_MASTER);
+ ByteWritePCIConfig(BusDevFun, PCI_COMMAND_REGISTER_OFFSET, PciCommand);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: StopPciBridge
+//
+// Description:
+// This function stopped PciBridge
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+StopPciBridge(
+ UINT16 BusDevFun
+)
+{
+ UINT32 PmStaCtlReg;
+ UINT8 PwrCapPtr;
+ UINT8 PciCommand;
+
+ PwrCapPtr = LocatePwrCapOffset(BusDevFun);
+
+ if (PwrCapPtr) {
+ PmStaCtlReg = ReadPCIConfig(BusDevFun, PwrCapPtr + 0x04);
+ PmStaCtlReg |= (BIT0 + BIT1);
+ DwordWritePCIConfig(BusDevFun, PwrCapPtr + 0x04, PmStaCtlReg);
+ }
+
+ PciCommand = (UINT8)ReadPCIConfig(BusDevFun, PCI_COMMAND_REGISTER_OFFSET);
+ PciCommand &= (~PCI_CMD_BUS_MASTER);
+ ByteWritePCIConfig(BusDevFun, PCI_COMMAND_REGISTER_OFFSET, PciCommand);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: EnablePciBridge
+//
+// Description:
+// This function scaned PciBridge
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ScanPciBridge(
+ UINT16 *BridgePciAddr
+)
+{
+ HC_STRUC *HcStruc;
+ UINT8 HcBus[256];
+ UINT16 HcBusIndex = 0;
+ UINT16 MaxHcBus = 0;
+ UINT16 i;
+ UINT16 PciAddr;
+ UINT16 PciBus;
+ UINT16 PciDev;
+ UINT16 PciFun;
+ UINT16 BridgeIndex = 255;
+ UINT16 DownstreamBus;
+
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ HcStruc = gUsbData->HcTable[i];
+ if (HcStruc == NULL) {
+ continue;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+
+ if (HcStruc->dHCFlag & HC_STATE_EXTERNAL) {
+ HcBus[HcBusIndex] = (UINT8)(HcStruc->wBusDevFuncNum >> 8);
+ if(MaxHcBus < HcBus[HcBusIndex]) {
+ MaxHcBus = HcBus[HcBusIndex];
+ }
+ HcBusIndex++;
+ }
+ }
+
+ for (PciBus = 0; PciBus < MaxHcBus; PciBus++) {
+ for (PciDev = 0; PciDev < 0x20 ; PciDev++) {
+ PciAddr = (UINT16)((PciBus << 8) | (PciDev << 3) | 0);
+ if (ReadPCIConfig(PciAddr, PCI_VID) != 0xffffffff) {
+ PciFun = ((UINT8)ReadPCIConfig(PciAddr, PCI_HDR) & 0x80) ? 8 : 1;
+ do {
+ PciFun--;
+ PciAddr = (UINT16)((PciBus << 8) | (PciDev << 3) | PciFun);
+ if (PciFun != 0) {
+ if (ReadPCIConfig(PciAddr, PCI_VID) == 0xffffffff) {
+ continue;
+ }
+ }
+ if (ReadPCIConfig(PciAddr, PCI_SCC) == 0x0604) {
+ DownstreamBus = (UINT16)ReadPCIConfig(PciAddr, PCI_SBUS);
+ for (i = 0; i < HcBusIndex; i++) {
+ if ((HcBus[i] >= (UINT8)(DownstreamBus)) &&
+ (HcBus[i] <= (UINT8)(DownstreamBus >> 8))) {
+ ResumePciBridge(PciAddr);
+ BridgePciAddr[BridgeIndex] = PciAddr;
+ BridgeIndex--;
+ break;
+ }
+ }
+ }
+ } while (PciFun);
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: UsbSuspendHubPort
+//
+// Description: This function suspends the hub port
+//
+// Input: DevInfo Device info pointer
+//
+// Output: Status: EFI_SUCCESS = Success
+// EFI_DEVICE_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbSuspendHubPort (
+ DEV_INFO *DevInfo
+)
+{
+ UINT32 Index;
+ DEV_INFO *HubDevInfo;
+ HC_STRUC *HcStruc;
+ UINT16 OrgTimeOutValue;
+
+ if (DevInfo->bHubDeviceNumber & BIT7) {
+ return EFI_SUCCESS;
+ }
+
+ for (Index = 1; Index < MAX_DEVICES; Index++) {
+ HubDevInfo = &gUsbData->aDevInfoTable[Index];
+ if ((HubDevInfo->Flag & DEV_INFO_VALIDPRESENT) != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+ if (DevInfo->bHubDeviceNumber == HubDevInfo->bDeviceAddress) {
+ HcStruc = gUsbData->HcTable[HubDevInfo->bHCNumber - 1];
+
+ OrgTimeOutValue = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = USB_SUSPEND_HUB_PORT_TIMEOUT_MS;
+
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ HcStruc->bHCType)].pfnHCDControlTransfer)(
+ HcStruc,
+ HubDevInfo,
+ (UINT16)HUB_RQ_SET_PORT_FEATURE,
+ DevInfo->bHubPortNumber,
+ (UINT16)PortSuspend,
+ 0, 0);
+
+ gUsbData->wTimeOutValue = OrgTimeOutValue;
+ return EFI_SUCCESS;
+ }
+ }
+ return EFI_DEVICE_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbSuspendDevices
+//
+// Description:
+// This function suspends usb devices.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbSuspendDevices (
+ VOID
+)
+{
+ UINT32 Index;
+ DEV_INFO *DevInfo;
+
+ for (Index = MAX_DEVICES; Index > 0; Index--) {
+
+ DevInfo = &gUsbData->aDevInfoTable[Index];
+
+ if ((DevInfo->Flag & DEV_INFO_VALIDPRESENT) != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+ UsbSuspendHubPort(DevInfo);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbSuspend
+//
+// Description:
+// This function suspend USB
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbSuspend(
+ VOID
+)
+{
+ HC_STRUC *HcStruc;
+ DEV_INFO *DevInfo;
+ CNFG_DESC *CnfgDesc;
+ UINT8 *Buffer;
+ UINT16 i;
+ UINT32 PmStaCtlReg;
+ UINT32 PmCapReg;
+ UINT16 BridgePciAddr[256];
+ UINT32 HcLowBaseAddress;
+ UINT32 HcHighBaseAddress;
+ UINT16 HcIoAddress;
+ UINT16 OrgTimeOutValue;
+
+ for (i = 0; i < 256; i++) {
+ BridgePciAddr[i] = 0;
+ }
+
+ ScanPciBridge(BridgePciAddr);
+
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ HcStruc = gUsbData->HcTable[i];
+ if (HcStruc == NULL) {
+ continue;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+
+ HcStruc->PwrCapPtr = LocatePwrCapOffset(HcStruc->wBusDevFuncNum);
+ if (HcStruc->PwrCapPtr) {
+ PmCapReg = ReadPCIConfig(HcStruc->wBusDevFuncNum,
+ HcStruc->PwrCapPtr);
+ PmStaCtlReg = ReadPCIConfig(HcStruc->wBusDevFuncNum,
+ HcStruc->PwrCapPtr + 0x04);
+ if (PmCapReg & (BIT31 | BIT30)) {
+ PmStaCtlReg |= BIT8;
+ }
+ if (PmStaCtlReg & (BIT0 | BIT1)) {
+ PmStaCtlReg &= ~(BIT0 | BIT1);
+ }
+ DwordWritePCIConfig(HcStruc->wBusDevFuncNum,
+ HcStruc->PwrCapPtr + 0x04, PmStaCtlReg);
+ }
+ if (HcStruc->bHCType == USB_HC_UHCI) {
+ HcIoAddress = (UINT16)ReadPCIConfig(HcStruc->wBusDevFuncNum, USB_IO_BASE_ADDRESS);
+ if (HcStruc->BaseAddress != HcIoAddress) {
+ WordWritePCIConfig(HcStruc->wBusDevFuncNum,
+ USB_IO_BASE_ADDRESS, (UINT32)HcStruc->BaseAddress);
+ }
+ ByteWritePCIConfig(HcStruc->wBusDevFuncNum,
+ PCI_CMD, PCI_CMD_IO_SPACE | PCI_CMD_BUS_MASTER);
+ } else {
+ HcLowBaseAddress = ReadPCIConfig(HcStruc->wBusDevFuncNum, PCI_BAR0);
+ if ((((UINT8)HcLowBaseAddress & (BIT1 |BIT2)) == BIT2) && ((sizeof(VOID*) / sizeof(UINT32)) == 2)) {
+ HcHighBaseAddress = ReadPCIConfig(HcStruc->wBusDevFuncNum, PCI_BAR1);
+ if(HcStruc->BaseAddress != ((UINTN)(HcLowBaseAddress & 0xFFFFFFF0)) +
+ (Shl64((UINTN)HcHighBaseAddress, 32))) {
+ DwordWritePCIConfig(HcStruc->wBusDevFuncNum,
+ PCI_BAR0, (UINT32)HcStruc->BaseAddress);
+ DwordWritePCIConfig(HcStruc->wBusDevFuncNum,
+ PCI_BAR1, (UINT32)(Shr64(HcStruc->BaseAddress, 32)));
+ }
+ } else {
+ if (HcStruc->BaseAddress != (HcLowBaseAddress & 0xFFFFFFF0)) {
+ DwordWritePCIConfig(HcStruc->wBusDevFuncNum,
+ PCI_BAR0, (UINT32)HcStruc->BaseAddress);
+ }
+ }
+ ByteWritePCIConfig(HcStruc->wBusDevFuncNum,
+ PCI_CMD, PCI_CMD_MEMORY_SPACE | PCI_CMD_BUS_MASTER);
+ }
+ }
+
+ // Remove the prsent flag of devices before we reenumerate.
+ for (i = 1; i < MAX_DEVICES; i++) {
+ DevInfo = &gUsbData->aDevInfoTable[i];
+ DevInfo->Flag &= ~DEV_INFO_DEV_PRESENT;
+ }
+
+ gUsbData->UsbSetupData.UsbMassDriverSupport = FALSE;
+ gUsbData->bHandOverInProgress = FALSE;
+
+ //Start XHCI
+ StartControllerType(USB_HC_XHCI);
+ //Start EHCI
+ StartControllerType(USB_HC_EHCI);
+ //Start UHCI
+ StartControllerType(USB_HC_UHCI);
+ //Start OHCI
+ StartControllerType(USB_HC_OHCI);
+
+ //Wait for the usb devices connect.
+ FixedDelay(50 * 1000);
+
+ USB_EnumerateRootHubPorts(USB_HC_XHCI);
+ USB_EnumerateRootHubPorts(USB_HC_EHCI);
+ USB_EnumerateRootHubPorts(USB_HC_UHCI);
+ USB_EnumerateRootHubPorts(USB_HC_OHCI);
+
+ Buffer = USB_MemAlloc(sizeof(CNFG_DESC));
+
+ OrgTimeOutValue = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = 500;
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+
+ DevInfo = &gUsbData->aDevInfoTable[i];
+
+ if ((DevInfo->Flag & DEV_INFO_VALIDPRESENT) != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+
+ if (DevInfo->bDeviceType == BIOS_DEV_TYPE_HUB) {
+ continue;
+ }
+
+ HcStruc = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+
+ CnfgDesc = (CNFG_DESC*)USB_GetDescriptor(
+ HcStruc,
+ DevInfo,
+ Buffer,
+ sizeof(CNFG_DESC),
+ DESC_TYPE_CONFIG,
+ 0);
+
+ if (CnfgDesc == NULL) {
+ continue;
+ }
+
+ //Check the device have the capable of remote wakeup
+ if (CnfgDesc ->bConfigFlags & BIT5) {
+ //Send device wakeup command to the device
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ HcStruc->bHCType)].pfnHCDControlTransfer)(
+ HcStruc,
+ DevInfo,
+ (UINT16)USB_RQ_SET_FEATURE,
+ 0,
+ (UINT16)USB_FSEL_DEV_REMOTE_WAKEUP,
+ 0, 0);
+
+ }
+
+ }
+
+ gUsbData->wTimeOutValue = OrgTimeOutValue;
+
+ USB_MemFree(Buffer, sizeof(CNFG_DESC));
+
+ UsbSuspendDevices();
+
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ HcStruc = gUsbData->HcTable[i];
+ if (HcStruc == NULL) {
+ continue;
+ }
+
+ //Global suspend host
+ if (HcStruc->dHCFlag & HC_STATE_RUNNING) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(
+ HcStruc->bHCType)].pfnHCDGlobalSuspend)(HcStruc);
+ if (HcStruc->PwrCapPtr) {
+ PmStaCtlReg = ReadPCIConfig(HcStruc->wBusDevFuncNum,
+ HcStruc->PwrCapPtr + 0x04);
+ PmStaCtlReg |= (BIT0 + BIT1);
+ DwordWritePCIConfig(HcStruc->wBusDevFuncNum,
+ HcStruc->PwrCapPtr + 0x04, PmStaCtlReg);
+ }
+ }
+ }
+
+ for (i = 0; i < 256; i++) {
+ if (BridgePciAddr[i] != 0) {
+ StopPciBridge(BridgePciAddr[i]);
+ }
+ }
+
+ UsbSbEnablePme();
+
+}
+
+#endif
+ //<(EIP54018+)
+UINT8
+UsbGetDataToggle(
+ DEV_INFO *DevInfo,
+ UINT8 EndpointAddr
+)
+{
+ DEV_INFO *DevInfoToToggle;
+ UINT8 ToggleBit = (EndpointAddr & 0xF) - 1;
+ UINT16 *DataSync;
+ EFI_STATUS Status;
+
+ if (DevInfo->fpLUN0DevInfoPtr) {
+ Status = UsbDevInfoValidation(DevInfo->fpLUN0DevInfoPtr);
+ if (EFI_ERROR(Status)) {
+ return 0;
+ }
+ DevInfoToToggle = DevInfo->fpLUN0DevInfoPtr;
+ } else {
+ DevInfoToToggle = DevInfo;
+ }
+
+ if (EndpointAddr & BIT7) {
+ DataSync = &DevInfoToToggle->wDataInSync;
+ } else {
+ DataSync = &DevInfoToToggle->wDataOutSync;
+ }
+
+ return (UINT8)((*DataSync) >> ToggleBit) & 0x1;
+}
+
+VOID
+UsbUpdateDataToggle(
+ DEV_INFO *DevInfo,
+ UINT8 EndpointAddr,
+ UINT8 DataToggle
+)
+{
+ DEV_INFO *DevInfoToToggle;
+ UINT8 ToggleBit = (EndpointAddr & 0xF) - 1;
+ UINT16 *DataSync;
+ EFI_STATUS Status;
+
+ if (DevInfo->fpLUN0DevInfoPtr) {
+ Status = UsbDevInfoValidation(DevInfo->fpLUN0DevInfoPtr);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+ DevInfoToToggle = DevInfo->fpLUN0DevInfoPtr;
+ } else {
+ DevInfoToToggle = DevInfo;
+ }
+
+ if (EndpointAddr & BIT7) {
+ DataSync = &DevInfoToToggle->wDataInSync;
+ } else {
+ DataSync = &DevInfoToToggle->wDataOutSync;
+ }
+
+ *DataSync &= (UINT16)~(1 << ToggleBit);
+ *DataSync |= (UINT16)(DataToggle << ToggleBit);
+ return;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbCCID.c b/Core/EM/usb/rt/usbCCID.c
new file mode 100644
index 0000000..c5bac50
--- /dev/null
+++ b/Core/EM/usb/rt/usbCCID.c
@@ -0,0 +1,5033 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbCCID.c 19 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 19 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+//
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbCCID.c $
+//
+// 19 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 18 7/07/16 1:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 17 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 16 4/10/15 3:10a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 15 3/05/15 3:54a Wilsonlee
+// [TAG] EIP203888
+// [Category] Improvement
+// [Description] RateAndProtocolManagement() default return changed from
+// EFI_DEVICE_ERROR to EFI_SUCCESS.
+// [Files] usbCCID.c
+//
+// 14 2/16/15 2:45a Wilsonlee
+// [TAG] EIP205373
+// [Category] Improvement
+// [Description] Cppcheck errors in Usb module.
+// [Files] usb.c, usbport.c, uhcd.c, usbCCID.c
+//
+// 13 6/26/14 1:16a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 12 4/30/14 6:14a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 11 2/26/14 1:55a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 10 2/11/14 11:47p Rameshr
+// [TAG] EIP152203
+// [Category] Improvement
+// [Description] Hardcoded value for bProtocolNum removed.
+// [Files] usbCCID.c
+//
+// 9 6/20/13 10:22p Wilsonlee
+// [TAG] EIP126814
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Security code check fail in the function
+// USBAPI_CCIDRequest() in usbCCID.c.
+// [RootCause] The function USBAPI_CCIDRequest() in usbCCID.c reads data
+// from just outside the bounds of aUsbCCIDApiTable.
+// [Solution] Condition is fixed from ">" to ">=".
+// [Files] usbCCID.c
+//
+// 8 4/02/13 7:54a Rameshr
+// [TAG] EIP119028
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Insert smart card incorrectly (backwards), system will hang
+// 0xA0 .
+// [RootCause] Invalid Status returned
+// [Solution] Add a check whether ATR data is successfully read and
+// processed, If not return error
+//
+// 7 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 6 1/23/13 4:36a Wilsonlee
+// [TAG] EIP109538
+// [Category] Improvement
+// [Description] Fix the code check error result.
+// [Files] usbkbd.c, usbCCID.c, usbbus.c, efiusbccid.c
+//
+// 5 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 4 9/28/12 2:38a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 3 5/02/12 1:55a Rajeshms
+// [TAG] EIP83117
+// [Category] Improvement
+// [Description] Extend the Support to different smart card Readers and
+// smart Cards.
+// [Files] usbCCID.c, amiusbrtCCID.h, usbdef.h, efiusbccid.c,
+// AmiusbCCID.h
+//
+// 2 9/22/11 1:24a Rajeshms
+// [TAG] EIP67832
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] When ICC(Smart Card) is unplugged and inserted again , it
+// is not detected.
+// [RootCause] The ChildHandle for the smart card where protocol is
+// installed is not made to zero when it was unplugged.
+// [Solution] The ChilHandle is changed to zero when smart card is
+// unplugged.
+// [Files] usbCCID.c
+//
+// 1 7/12/11 8:04a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbCCID.c
+//
+// Description: AMI USB CCID Device class support driver
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "amidxelib.h"
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#endif
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gCheckUsbApiParameter;
+
+UINT8 gSequence = 0;
+
+VOID _FAR_ *
+USB_MemAlloc(
+ UINT16 wNumBlk
+);
+
+UINT8
+USB_MemFree (
+ VOID _FAR_ * fpPtr,
+ UINT16 wNumBlk
+);
+
+void FixedDelay(
+ IN UINTN
+);
+
+typedef VOID (*API_FUNC)(URP_STRUC*);
+
+extern UINT8 USB_InstallCallBackFunction (CALLBACK_FUNC pfnCallBackFunction);
+
+// Fi Max Di
+UINT16 FiFmaxDi[] = { 372, 4, 0,
+ 372, 5, 1,
+ 558, 6, 2,
+ 744, 8, 4,
+ 1116, 12, 8,
+ 1488, 16, 16,
+ 1860, 20, 32,
+ 0, 0, 64,
+ 0, 0, 12,
+ 512, 5, 20,
+ 768, 7, 0,
+ 1024, 10, 0,
+ 1536, 15, 0,
+ 2048, 20, 0,
+ 0, 0, 0,
+ 0, 0, 0
+ };
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: USBCCIDAPITable - USB CCID API Function Dispatch Table
+//
+// Type: Function Dispatch Table
+//
+// Description: This is the table of functions used by USB CCID API
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+API_FUNC aUsbCCIDApiTable[] = {
+
+ USBCCIDAPISmartClassDescriptorSMM, // USB Mass API Sub-Func 00h
+ USBCCIDAPIAtrSMM, // USB Mass API Sub-Func 01h
+ USBCCIDAPIPowerupSlotSMM, // USB Mass API Sub-Func 02h
+ USBCCIDAPIPowerDownSlotSMM, // USB Mass API Sub-Func 03h
+ USBCCIDAPIGetSlotStatusSMM, // USB Mass API Sub-Func 04h
+ USBCCIDAPIXfrBlockSMM, // USB Mass API Sub-Func 05h
+ USBCCIDAPIGetParametersSMM, // USB Mass API Sub-Func 06h
+
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDFillDriverEntries
+//
+// Description: This function fills DEV_DRIVER structure
+//
+// Input:
+// fpDevDriver Pointer to the DEV driver
+//
+// Output:
+// None
+//
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBCCIDFillDriverEntries (
+ IN OUT DEV_DRIVER *fpDevDriver
+)
+{
+
+ fpDevDriver->bDevType = BIOS_DEV_TYPE_STORAGE;
+ fpDevDriver->bBaseClass = BASE_CLASS_CCID_STORAGE;
+ fpDevDriver->bSubClass = SUB_CLASS_CCID;
+ fpDevDriver->bProtocol = PROTOCOL_CCID;
+ fpDevDriver->bProtocol = 0;
+ fpDevDriver->pfnDeviceInit = USBCCIDInitialize;
+ fpDevDriver->pfnCheckDeviceType = USBCCIDCheckForDevice;
+ fpDevDriver->pfnConfigureDevice = USBCCIDConfigureDevice;
+ fpDevDriver->pfnDisconnectDevice = USBCCIDDisconnectDevice;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPISmartClassDescriptorSMM
+//
+// Description: This function is part of the USB BIOS MASS API inside SMM
+//
+// Input:
+// fpURPPointer Pointer to the URP structure
+//
+// Output:
+// fpURPPointer Pointer to the URP structure
+// fpURP->bRetValue USB_SUCESS if data is returned
+//
+// Notes: This API returns 36h bytes of SMART Class Descriptor to the caller.
+// Input Buffer of 36h bytes long is provided by the caller. Caller is
+// USBCCIDAPISmartClassDescriptor in EfiUsbCCID.C
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBCCIDAPISmartClassDescriptorSMM(
+ IN OUT URP_STRUC *Urp
+)
+{
+
+ DEV_INFO *DevInfo;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)(Urp->ApiData.CCIDSmartClassDescriptor.fpResponseBuffer),
+ (UINT32)sizeof(SMARTCLASS_DESC));
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "UsbCcid Invalid Pointer, Buffer is in SMRAM.\n");
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ DevInfo = (DEV_INFO *)(Urp->ApiData.CCIDSmartClassDescriptor.fpDevInfo);
+
+ // Check whether it is a valid CCID Device
+ if (!DevInfo || !DevInfo->pCCIDDescriptor) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ Urp->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)DevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)DevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ MemCopy((UINT8 *)DevInfo->pCCIDDescriptor,
+ (UINT8 *)(Urp->ApiData.CCIDSmartClassDescriptor.fpResponseBuffer),
+ (UINT32)sizeof(SMARTCLASS_DESC)
+ );
+
+ Urp->bRetValue = USB_SUCCESS;
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPIAtrSMM
+//
+// Description: This function is part of the USB BIOS MASS API inside SMM
+//
+// Input: fpURPPointer Pointer to the URP structure, it contains the following:
+//
+// Output: fpURPPointer Pointer to the URP structure
+// fpURP->bRetValue : USB_SUCESS if data is returned
+//
+// Notes: This API returns ATR data if present
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBCCIDAPIAtrSMM (
+ IN OUT URP_STRUC *Urp
+
+)
+{
+
+ DEV_INFO *DevInfo;
+ ICC_DEVICE *IccDevice;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)(Urp->ApiData.CCIDAtr.ATRData),
+ MAX_ATR_LENGTH);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "UsbCcid Invalid Pointer, Buffer is in SMRAM.\n");
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ DevInfo = (DEV_INFO *)(Urp->ApiData.CCIDAtr.fpDevInfo);
+ //
+ // Check whether it is a valid CCID Device
+ //
+ if (!DevInfo || !DevInfo->pCCIDDescriptor) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ Urp->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)DevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)DevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ Urp->bRetValue = USB_ERROR;
+
+ //
+ // Locate the ICCDevice
+ //
+ IccDevice = GetICCDevice(DevInfo, Urp->ApiData.CCIDAtr.Slot);
+
+ if (IccDevice) {
+ if (IccDevice->ConfiguredStatus & ATRDATAPRESENT) {
+ MemCopy((UINT8 *)IccDevice->RawATRData, (UINT8 *)(Urp->ApiData.CCIDAtr.ATRData), MAX_ATR_LENGTH);
+ Urp->bRetValue = USB_SUCCESS;
+ }
+ }
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPIPowerupSlotSMM
+//
+// Description: This function is part of the USB BIOS MASS API inside SMM
+//
+// Input:
+// fpURPPointer Pointer to the URP structure
+//
+// Output:
+// fpURPPointer Pointer to the URP structure
+// fpURP->bRetValue : USB_SUCESS if data is returned
+//
+// Notes: This API powers up the particular slot in CCID and returns ATR data if successful
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBCCIDAPIPowerupSlotSMM (
+ IN OUT URP_STRUC *Urp
+
+)
+{
+
+ EFI_STATUS Status;
+ DEV_INFO *DevInfo;
+ ICC_DEVICE *IccDevice;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ Status = AmiValidateMemoryBuffer((VOID*)(Urp->ApiData.CCIDPowerupSlot.ATRData),
+ MAX_ATR_LENGTH);
+ if (EFI_ERROR(Status)) {
+ USB_DEBUG(3, "UsbCcid Invalid Pointer, Buffer is in SMRAM.\n");
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ DevInfo = (DEV_INFO *)(Urp->ApiData.CCIDPowerupSlot.fpDevInfo);
+
+ //
+ // Check whether it is a valid CCID Device
+ //
+ if (!DevInfo || !DevInfo->pCCIDDescriptor) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ Status = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(Status)) {
+ Urp->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)DevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)DevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Locate the ICCDevice
+ //
+ IccDevice = GetICCDevice(DevInfo, Urp->ApiData.CCIDPowerupSlot.Slot);
+
+ if (IccDevice) {
+ //
+ // The slot has been already discovered. Check the status.
+ //
+ if (IccDevice->ConfiguredStatus & VOLTAGEAPPLIED) {
+ //
+ // Power down the device
+ //
+ PCtoRDRIccPowerOff (DevInfo, IccDevice);
+ RDRToPCSlotStatus(DevInfo, IccDevice);
+ }
+ }
+
+ Status = ICCInsertEvent(DevInfo, Urp->ApiData.CCIDPowerupSlot.Slot);
+
+ //
+ // If the card has been successfully poweredup copy ATR data
+ //
+ if (!IccDevice) {
+ IccDevice = GetICCDevice(DevInfo, Urp->ApiData.CCIDPowerupSlot.Slot);
+ if (!IccDevice) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ }
+ Urp->ApiData.CCIDPowerupSlot.bStatus = IccDevice->bStatus;
+ Urp->ApiData.CCIDPowerupSlot.bError = IccDevice->bError;
+
+ if (IccDevice->ConfiguredStatus & ATRDATAPRESENT) {
+ MemCopy((UINT8 *)IccDevice->RawATRData, (UINT8 *)(Urp->ApiData.CCIDPowerupSlot.ATRData), MAX_ATR_LENGTH);
+ }
+
+ Urp->bRetValue = USB_SUCCESS;
+
+ if (Status == EFI_DEVICE_ERROR) {
+ Urp->bRetValue = USB_ERROR;
+ }
+
+ return;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPIPowerDownSlotSMM
+//
+// Description: This function is part of the USB BIOS MASS API inside SMM
+//
+// Input:
+// fpURPPointer Pointer to the URP structure, it contains the following:
+//
+// Output:
+// fpURPPointer Pointer to the URP structure
+// fpURP->bRetValue : USB_SUCESS if data is returned
+//
+// Notes: This API powers down the particular slot.
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+USBCCIDAPIPowerDownSlotSMM (
+ IN OUT URP_STRUC *fpURP
+
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ DEV_INFO *fpDevInfo;
+ ICC_DEVICE *fpICCDevice;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ fpDevInfo = (DEV_INFO *) (fpURP->ApiData.CCIDPowerdownSlot.fpDevInfo);
+
+ fpURP->bRetValue = USB_ERROR;
+
+ //
+ // Check whether it is a valid CCID Device
+ //
+ if (!fpDevInfo || !fpDevInfo->pCCIDDescriptor) {
+
+ return;
+
+ }
+
+ Status = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(Status)) {
+ fpURP->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ fpURP->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Locate the ICCDevice
+ //
+ fpICCDevice = GetICCDevice(fpDevInfo, fpURP->ApiData.CCIDPowerdownSlot.Slot);
+
+ if (fpICCDevice) {
+ //
+ // The slot has been already discovered. Check the status.
+ //
+ if (fpICCDevice->ConfiguredStatus & ICCPRESENT) {
+
+ //
+ // Power down the device
+ //
+ Status = PCtoRDRIccPowerOff (fpDevInfo, fpICCDevice);
+ RDRToPCSlotStatus(fpDevInfo, fpICCDevice);
+
+ fpICCDevice->ConfiguredStatus &= (~VOLTAGEAPPLIED);
+
+ fpURP->ApiData.CCIDPowerdownSlot.bStatus = fpICCDevice->bStatus;
+ fpURP->ApiData.CCIDPowerdownSlot.bError = fpICCDevice->bError;
+
+ }
+ }
+
+ fpURP->bRetValue = USB_SUCCESS;
+
+ if (Status == EFI_DEVICE_ERROR){
+ fpURP->bRetValue = USB_ERROR;
+ }
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPIGetSlotStatusSMM
+//
+// Description: This function is part of the USB BIOS MASS API inside SMM
+//
+// Input:
+// fpURPPointer Pointer to the URP structure, it contains the following:
+// UINT8 *bStatus;
+// UINT8 *bError;
+//
+// Output:
+// fpURPPointer Pointer to the URP structure
+// bRetValue Return value
+// bClockStatus Return Value
+//
+// Notes: This API returns information from RDR_to_PC_SlotStatus.
+// Caller is USBCCIDAPIGetSlotStatus in EfiUsbCCID.C
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBCCIDAPIGetSlotStatusSMM (
+ IN OUT URP_STRUC *fpURP
+)
+{
+
+ EFI_STATUS Status;
+ DEV_INFO *fpDevInfo;
+ ICC_DEVICE *fpICCDevice;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ fpDevInfo = (DEV_INFO *) (fpURP->ApiData.CCIDGetSlotStatus.fpDevInfo);
+
+ //
+ // Check whether it is a valid CCID Device
+ //
+ if (!fpDevInfo || !fpDevInfo->pCCIDDescriptor) {
+
+ fpURP->bRetValue = USB_ERROR;
+ return;
+
+ }
+
+ Status = UsbDevInfoValidation(fpDevInfo);
+
+ if (EFI_ERROR(Status)) {
+ fpURP->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ fpURP->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Locate the ICCDevice
+ //
+ fpICCDevice = GetICCDevice(fpDevInfo, fpURP->ApiData.CCIDGetSlotStatus.Slot);
+ if (!fpICCDevice || !(fpICCDevice->ConfiguredStatus & ICCPRESENT)) {
+
+ fpURP->ApiData.CCIDGetSlotStatus.bStatus = 0x42;
+ fpURP->ApiData.CCIDGetSlotStatus.bError = 0xFE;
+ fpURP->bRetValue = USB_ERROR;
+ return;
+
+ }
+
+ //
+ // Issue the cmd
+ //
+ Status = PCToRDRGetSlotStatus(fpDevInfo, fpICCDevice);
+
+ if (EFI_ERROR(Status)){
+ fpURP->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Get the response
+ //
+ Status = RDRToPCSlotStatus(fpDevInfo, fpICCDevice);
+
+ fpURP->ApiData.CCIDGetSlotStatus.bStatus = fpICCDevice->bStatus;
+ fpURP->ApiData.CCIDGetSlotStatus.bError = fpICCDevice->bError;
+ fpURP->ApiData.CCIDGetSlotStatus.bClockStatus = fpICCDevice->bClockStatus;
+
+ fpURP->bRetValue = USB_SUCCESS;
+
+ if (Status == EFI_DEVICE_ERROR){
+ fpURP->bRetValue = USB_ERROR;
+ }
+
+ return;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPIXfrBlockSMM
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input:
+// fpURPPointer Pointer to the URP structure, it contains the following:
+// IN UINTN CmdLength
+// IN UINTN fpCmdBuffer
+// OUT UINT8 bStatus
+// OUT UINT8 bError
+// IN OUT UINTN ResponseLength - Points to the buffer length of fpResponseBuffer
+// OUT UINTN fpResponseBuffer
+//
+// Output:
+// fpURPPointer Pointer to the URP structure
+// OUT UINT8 bStatus
+// OUT UINT8 bError
+// IN OUT UINTN ResponseLength - Points to the actual response bytes in fpResponseBuffer on return
+// OUT UINTN fpResponseBuffer
+//
+// Note: This API excutes PC_to_RDR_XfrBlock cmd and returns the response from
+// RDR_to_PC_DataBlock to the caller.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBCCIDAPIXfrBlockSMM (
+ IN OUT URP_STRUC *Urp
+)
+{
+
+ EFI_STATUS Status;
+ DEV_INFO *DevInfo;
+ ICC_DEVICE *IccDevice;
+ UINT32 CmdLength = (UINT32)Urp->ApiData.CCIDXfrBlock.CmdLength;
+ UINT8 *CmdBuffer = (UINT8 *)Urp->ApiData.CCIDXfrBlock.fpCmdBuffer;
+ UINT8 IsBlock = (BOOLEAN)Urp->ApiData.CCIDXfrBlock.ISBlock;
+ UINT32 *ResponseLength = (UINT32 *)&(Urp->ApiData.CCIDXfrBlock.ResponseLength);
+ UINT8 *ResponseBuffer = (UINT8 *)(Urp->ApiData.CCIDXfrBlock.fpResponseBuffer);
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ Status = AmiValidateMemoryBuffer((VOID*)(Urp->ApiData.CCIDXfrBlock.fpCmdBuffer),
+ Urp->ApiData.CCIDXfrBlock.CmdLength);
+ if (EFI_ERROR(Status)) {
+ USB_DEBUG(3, "UsbCcid Invalid Pointer, Buffer is in SMRAM.\n");
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ Status = AmiValidateMemoryBuffer((VOID*)(Urp->ApiData.CCIDXfrBlock.fpResponseBuffer),
+ Urp->ApiData.CCIDXfrBlock.ResponseLength);
+ if (EFI_ERROR(Status)) {
+ USB_DEBUG(3, "UsbCcid Invalid Pointer, Buffer is in SMRAM.\n");
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ DevInfo = (DEV_INFO *)(Urp->ApiData.CCIDXfrBlock.fpDevInfo);
+
+ //
+ // Check whether it is a valid CCID Device
+ //
+ if (!DevInfo || !DevInfo->pCCIDDescriptor) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ Status = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(Status)) {
+ Urp->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)DevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)DevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Locate the ICCDevice
+ //
+ IccDevice = GetICCDevice(DevInfo, Urp->ApiData.CCIDXfrBlock.Slot);
+
+ if (!IccDevice || !(IccDevice->ConfiguredStatus & ICCPRESENT)) {
+
+ Urp->ApiData.CCIDXfrBlock.bStatus = 0x42;
+ Urp->ApiData.CCIDXfrBlock.bError = 0xFE;
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+
+ //
+ // Only T0/T1 are recognized
+ //
+ if (IccDevice->bProtocolNum > 1) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Check for T0/T1
+ //
+ if (IccDevice->bProtocolNum){
+ switch (((SMARTCLASS_DESC*)DevInfo->pCCIDDescriptor)->dwFeatures & 0x70000) {
+
+ case TDPU_LEVEL_EXCHANGE:
+
+ Status = TxRxT1TDPUChar(DevInfo, IccDevice, CmdLength, CmdBuffer, IsBlock, ResponseLength, ResponseBuffer);
+ break;
+
+ case CHARACTER_LEVEL_EXCHANGE:
+
+ Status = TxRxT1TDPUChar(DevInfo, IccDevice, CmdLength, CmdBuffer, IsBlock, ResponseLength, ResponseBuffer);
+ break;
+
+ case SHORT_ADPU_LEVEL_EXCHANGE:
+ case EXT_ADPU_LEVEL_EXCHANGE:
+ Status = TxRxT1Adpu(DevInfo, IccDevice, CmdLength, CmdBuffer, ResponseLength, ResponseBuffer);
+ break;
+ }
+ } else {
+ // T0 not supported yet
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ Urp->ApiData.CCIDXfrBlock.bStatus = IccDevice->bStatus;
+ Urp->ApiData.CCIDXfrBlock.bError = IccDevice->bError;
+
+ Urp->bRetValue = USB_SUCCESS;
+
+ if (Status == EFI_DEVICE_ERROR) {
+ Urp->bRetValue = USB_ERROR;
+ }
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDAPIGetParametersSMM
+//
+// Description: This function is part of the USB BIOS MASS API.
+//
+// Input:
+// fpURPPointer Pointer to the URP structure, it contains the following:
+// OUT UINT8 bStatus;
+// OUT UINT8 bError;
+// IN OUT UINTN ResponseLength;
+// OUT UINTN fpResponseBuffer;
+// IN UINT8 Slot;
+// OUT UINTN fpDevInfo;
+//
+// Output:
+// fpURPPointer Pointer to the URP structure
+// bRetValue Return value
+//
+// Notes: This API returns the response to RDR_to_PCParameters cmd
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBCCIDAPIGetParametersSMM (
+ IN OUT URP_STRUC *Urp
+
+)
+{
+
+ EFI_STATUS Status;
+ DEV_INFO *DevInfo;
+ ICC_DEVICE *IccDevice;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ Status = AmiValidateMemoryBuffer((VOID*)(Urp->ApiData.CCIDGetParameters.fpResponseBuffer),
+ Urp->ApiData.CCIDGetParameters.ResponseLength);
+ if (EFI_ERROR(Status)) {
+ USB_DEBUG(3, "UsbCcid Invalid Pointer, Buffer is in SMRAM.\n");
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ DevInfo = (DEV_INFO *)(Urp->ApiData.CCIDGetParameters.fpDevInfo);
+
+ //
+ // Check whether it is a valid CCID Device
+ //
+ if (!DevInfo || !DevInfo->pCCIDDescriptor) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ Status = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(Status)) {
+ Urp->bRetValue = USB_PARAMETER_ERROR;
+ return;
+ }
+
+ if (((UINT8*)DevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)DevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Locate the ICCDevice
+ //
+ IccDevice = GetICCDevice(DevInfo, Urp->ApiData.CCIDGetParameters.Slot);
+ if (!IccDevice || !(IccDevice->ConfiguredStatus & ICCPRESENT)) {
+ Urp->ApiData.CCIDGetParameters.bStatus = 0x42;
+ Urp->ApiData.CCIDGetParameters.bError = 0xFE;
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ // Should we check for device presence in data area. The call will find that out anyways.
+
+ //
+ // Issue the cmd
+ //
+ Status = PCToRDRGetParameters(DevInfo, IccDevice);
+
+ if (EFI_ERROR(Status)){
+ Urp->bRetValue = USB_ERROR;
+ return;
+ }
+
+ //
+ // Get the response
+ //
+ Status = RDRToPCParameters(DevInfo, IccDevice);
+ if (!EFI_ERROR(Status)) {
+ Urp->ApiData.CCIDGetParameters.ResponseLength = 6;
+ if (IccDevice->bProtocolNum){
+ Urp->ApiData.CCIDGetParameters.ResponseLength = 8;
+ }
+ //
+ // Update the Data
+ //
+ MemCopy((UINT8 *)&(IccDevice->bProtocolNum),
+ (UINT8 *)(Urp->ApiData.CCIDGetParameters.fpResponseBuffer),
+ (UINT32)(Urp->ApiData.CCIDGetParameters.ResponseLength)
+ );
+ }
+
+ Urp->ApiData.CCIDGetParameters.bStatus = IccDevice->bStatus;
+ Urp->ApiData.CCIDGetParameters.bError = IccDevice->bError;
+
+ Urp->bRetValue = USB_SUCCESS;
+
+ if (Status == EFI_DEVICE_ERROR) {
+ Urp->bRetValue = USB_ERROR;
+ }
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAPI_CCIDRequest
+//
+// Description: This routine services the USB API function number 30h. It
+// handles all the CCID related calls from the higher
+// layer. Different sub-functions are invoked depending on
+// the sub-function number
+//
+// Input:
+// fpURPPointer Pointer to the URP structure
+// fpURPPointer.bSubFunc Subfunction number
+//
+// Output:
+// URP structure is updated with the relevant information
+//
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBAPI_CCIDRequest (
+ URP_STRUC *fpURP
+)
+{
+ UINT8 bCCIDFuncIndex = fpURP->bSubFunc;
+ UINT8 bNumberOfCCIDFunctions = sizeof aUsbCCIDApiTable / sizeof (API_FUNC *);
+
+ //
+ // Make sure function number is valid
+ //
+ if (bCCIDFuncIndex >= bNumberOfCCIDFunctions) {
+ //fpURP->bRetValue = USBAPI_INVALID_FUNCTION;
+ USB_DEBUG(3, "UsbApi CCIDRequest Invalid function#%x\n", bCCIDFuncIndex);
+ return;
+ }
+ //
+ // Function number is valid - call it
+ //
+ aUsbCCIDApiTable[bCCIDFuncIndex](fpURP);
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCtoRDRIccPowerOn
+//
+// Description: PC_TO_RDR_XFRBLOCK cmd is issued to the device
+//
+// Input
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice,
+// IN UINT32 CmdLength,
+// IN UINT8 *CmdBuffer,
+// IN UINT8 BlockWaitingTime,
+// IN UINT16 LevelParameter
+//
+// Output :
+// EFI_STATUS
+//
+// Notes: This function sends PC_TO_RDR_XFRBLOCK to the device.
+// See section 6.1.4 of CCID spec 1.1 for the details.
+// CmdBuffer points to abData.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCToRDRXfrBlock (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 CmdLength,
+ IN UINT8 *CmdBuffer,
+ IN UINT8 BlockWaitingTime,
+ IN UINT16 LevelParameter
+
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_XFRBLOCK_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+ UINT32 i;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCToRDRXfrBlock ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_XFRBLOCK_STRUC) + CmdLength));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, sizeof(PC_TO_RDR_XFRBLOCK_STRUC) + CmdLength, 0);
+
+ //
+ // Prepare the cmd buffer
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_XFRBLOCK;
+ fpCmdBuffer->dwLength = CmdLength;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+ fpCmdBuffer->bBWI = BlockWaitingTime;
+ fpCmdBuffer->wLevelParameter = LevelParameter;
+
+ //
+ // Copy the cmd
+ //
+ if (CmdLength) {
+ MemCopy(CmdBuffer, (UINT8 *)fpCmdBuffer + sizeof(PC_TO_RDR_XFRBLOCK_STRUC), CmdLength);
+ }
+
+
+ USB_DEBUG (DEBUG_LEVEL_3, "\n");
+ for (i=0; i< sizeof(PC_TO_RDR_XFRBLOCK_STRUC) + CmdLength; i++) {
+ USB_DEBUG (DEBUG_LEVEL_3, "%02X ", ((UINT8 *)fpCmdBuffer)[i]);
+ }
+ USB_DEBUG (DEBUG_LEVEL_3, "\n");
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ sizeof(PC_TO_RDR_XFRBLOCK_STRUC) + CmdLength
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_XFRBLOCK_STRUC) + CmdLength));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCtoRDRIccPowerOn
+//
+// Description: PC_TO_RDR_ICCPOWERON cmd is issued to the CCID
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice,
+// IN UINT8 PowerLevel - 00:Automatic Voltage selection, 01:5.0v, 02:3.0v, 03:1.8v
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: See section 6.1.1 of CCID spec Rev 1.1 for more details
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCtoRDRIccPowerOn(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT8 PowerLevel
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_ICCPOWERON_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCtoRDRIccPowerOn ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_ICCPOWERON_STRUC)));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, sizeof(PC_TO_RDR_ICCPOWERON_STRUC), 0);
+
+ //
+ // Prepare the cmd buffer
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_ICCPOWERON;
+ fpCmdBuffer->dwLength = 0;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+ fpCmdBuffer->bPowerSlot = PowerLevel;
+ fpCmdBuffer->abRFU = 0;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ sizeof(PC_TO_RDR_ICCPOWERON_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_ICCPOWERON_STRUC)));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCtoRDRIccPowerOff
+//
+// Description: PC_TO_RDR_ICCPOWEROFF cmd is issued to the CCID
+//
+// Input :
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice
+//
+// Output :
+// EFI_STATUS
+//
+// Notes: See section 6.1.2 of CCID spec Rev 1.1 for more details
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCtoRDRIccPowerOff(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_ICCPOWEROFF_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCtoRDRIccPowerOff ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_ICCPOWEROFF_STRUC)));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, sizeof(PC_TO_RDR_ICCPOWEROFF_STRUC), 0);
+
+ //
+ // Prepare the buffer
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_ICCPOWEROFF;
+ fpCmdBuffer->dwLength = 0;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ sizeof(PC_TO_RDR_ICCPOWEROFF_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+ else {
+ fpICCDevice->ConfiguredStatus = 0;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_ICCPOWEROFF_STRUC)));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCToRDRGetSlotStatus
+//
+// Description: PC_TO_RDR_GETSLOTSTATUS cmd is issued to CCID
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+//Notes: See section 6.1.3 of CCID spec Rev 1.1 for more details
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCToRDRGetSlotStatus(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_GETSLOT_STATUS_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCToRDRGetSlotStatus ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_GETSLOT_STATUS_STRUC)));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, sizeof(PC_TO_RDR_GETPARAMETERS_STRUC), 0);
+
+ //
+ // Prepare cmd buffer
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_GETSLOTSTATUS;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ sizeof(PC_TO_RDR_GETSLOT_STATUS_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_GETSLOT_STATUS_STRUC)));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCToRDRGetParameters
+//
+// Description: PC_TO_RDR_GETPARAMETERS cmd is issued to CCID
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: See section 6.1.5 of CCID spec Rev 1.1 for more details
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCToRDRGetParameters(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_GETPARAMETERS_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCToRDRGetParameters ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_GETPARAMETERS_STRUC)));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, sizeof(PC_TO_RDR_GETPARAMETERS_STRUC), 0);
+
+ //
+ // Prepare cmd buffer
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_GETPARAMETERS;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ sizeof(PC_TO_RDR_GETPARAMETERS_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_GETPARAMETERS_STRUC)));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCToRDRSetParameters
+//
+// Description: PC_TO_RDR_SETPARAMETERS cmd is issued to CCID
+//
+// Input :
+// IN DEV_INFO *fpDevInfo
+// IN ICC_DEVICE *fpICCDevice
+// IN UINT8 ProtocolNum - 0 : T=0, 1 : T=1
+// IN VOID *Data - Points to data from abProtocolDataStructure
+// in PC_TO_RDR_SETPARAMETERS
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: See section 6.1.7 of CCID spec Rev 1.1 for more details
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCToRDRSetParameters(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT8 ProtocolNum,
+ IN VOID *Data
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_SETPARAMETERS_T0_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+ UINT8 Length = ProtocolNum == 0 ? sizeof(PROTOCOL_DATA_T0) : sizeof(PROTOCOL_DATA_T1);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCToRDRSetParameters ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(Length + sizeof(RDR_HEADER)));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, Length + sizeof(RDR_HEADER), 0);
+
+ //
+ // Prepare
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_SETPARAMETERS;
+ fpCmdBuffer->dwLength = Length;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+ fpCmdBuffer->bProtocolNum = ProtocolNum;
+
+ MemCopy ((UINT8 *)Data, (UINT8 *)fpCmdBuffer +sizeof(RDR_HEADER), Length);
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ Length + sizeof(RDR_HEADER)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(Length + sizeof(RDR_HEADER)));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: PCToRDRSetDataRateAndClockFrequency
+//
+// Description: PC_TO_RDR_SETDATARATEANDCLOCK cmd is issued.
+// Response for this cmd is from RDR_TO_PC_DATARATEANDCLOCK
+//
+// Input:
+// IN DEV_INFO *fpDevInfo
+// IN ICC_DEVICE *fpICCDevice
+// IN UINT32 ClockFrequency - ICC Clock Frequency in KHz
+// IN UINT32 DataRate - ICC data rate in bpd
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: See section 6.1.14 of CCID spec Rev 1.1 for more details
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+PCToRDRSetDataRateAndClockFrequency(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 ClockFrequency,
+ IN UINT32 DataRate
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY_STRUC *fpCmdBuffer;
+ UINT32 dwData;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "PCToRDRGetParameters ....");
+
+ fpCmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY_STRUC)));
+ ASSERT(fpCmdBuffer);
+ if (!fpCmdBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpCmdBuffer, sizeof(PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY_STRUC), 0);
+
+ //
+ // Prepare cmd buffer
+ //
+ fpCmdBuffer->bMessageType = PC_TO_RDR_SETDATARATEANDCLOCK;
+ fpCmdBuffer->dwLength = 8;
+ fpCmdBuffer->bSlot = fpICCDevice->Slot;
+ fpCmdBuffer->bSeq = gSequence;
+ fpCmdBuffer->dwCloclFrequency = ClockFrequency;
+ fpCmdBuffer->dwDataRate = DataRate;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, 0,
+ (UINT8 *)fpCmdBuffer,
+ sizeof(PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ USB_MemFree(fpCmdBuffer, (UINT8)GET_MEM_BLK_COUNT(sizeof(PC_TO_RDR_SETDATARATEANDCLOCKFREQUENCY_STRUC)));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "%r ....", Status);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RDRToPCDataBlock
+//
+// Description: RDR_TO_PC_DATABLOCK cmd is issued to the CCID.
+// This is on response to PCI_to_RDR_XfrBlock
+//
+// Input:
+// IN DEV_INFO *fpDevInfo
+// IN ICC_DEVICE *fpICCDevice
+// IN OUT UINT32 *dwLength - # of bytes in Buffer
+// OUT UINT8 *Buffer - Points to abData in RDR_TO_PC_DATABLOCK
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: See section 6.2.1 of CCID spec Rev 1.1 for more details
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+RDRToPCDataBlock(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN OUT UINT32 *dwLength,
+ OUT UINT8 *Buffer
+
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ RDR_TO_PC_DATABLOCK_STRUC* fpReceiveBuffer;
+ UINT32 dwData;
+ UINT8 Iterations = 3;
+ UINT32 InputLength = *dwLength;
+ UINT32 i;
+
+ //
+ // Allocate memory for receiving data
+ //
+ fpReceiveBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_DATABLOCK_STRUC) + *dwLength));
+ ASSERT(fpReceiveBuffer);
+ if (!fpReceiveBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpReceiveBuffer, sizeof(RDR_TO_PC_DATABLOCK_STRUC) + *dwLength, 0);
+
+ do {
+ //
+ // Get the response
+ //
+ fpReceiveBuffer->bMessageType = RDR_TO_PC_DATABLOCK;
+ fpReceiveBuffer->dwLength = *dwLength;
+ fpReceiveBuffer->bSlot = fpICCDevice->Slot;
+ fpReceiveBuffer->bSeq = gSequence;
+ fpReceiveBuffer->bStatus = 0;
+ fpReceiveBuffer->bError = 0;
+ fpReceiveBuffer->bChainParameter = 0;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, BIT7,
+ (UINT8 *)fpReceiveBuffer,
+ sizeof(RDR_TO_PC_DATABLOCK_STRUC) + *dwLength
+ );
+
+ USB_DEBUG (DEBUG_LEVEL_3, "\n");
+
+ for (i=0; i< sizeof(RDR_TO_PC_DATABLOCK_STRUC) + fpReceiveBuffer->dwLength; i++) {
+ USB_DEBUG (DEBUG_LEVEL_3, "%02X ", ((UINT8 *)fpReceiveBuffer)[i]);
+ }
+
+ USB_DEBUG (DEBUG_LEVEL_3, "\n");
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit_RDRToPCDataBlock;
+ }
+
+ //
+ // Check for time extension
+ //
+ if ((fpReceiveBuffer->bStatus & 0xC0) == 0x80) {
+ FixedDelay(fpReceiveBuffer->bError * fpICCDevice->WaitTime * 1000);
+ } else {
+ break;
+ }
+
+ Iterations--;
+ } while (Iterations);
+
+ // Should the cmd be aborted if the response isn't received???
+
+ //
+ // Processed without error if Zero
+ //
+ if (fpReceiveBuffer->bStatus & 0xC0) {
+ Status = EFI_DEVICE_ERROR;
+
+ if ((fpReceiveBuffer->bStatus & 0x3) == 0x2) {
+ Status = EFI_NOT_FOUND;
+ }
+ }
+
+ if (Iterations && !EFI_ERROR(Status)) {
+
+ fpICCDevice->bChainParameter = fpReceiveBuffer->bChainParameter;
+
+ //
+ // If response is successful get the data
+ //
+ if (fpReceiveBuffer->dwLength && fpReceiveBuffer->dwLength <= *dwLength) {
+
+ // Copy data
+ MemCopy ((UINT8 *)fpReceiveBuffer + sizeof(RDR_TO_PC_DATABLOCK_STRUC),
+ Buffer,
+ fpReceiveBuffer->dwLength
+ );
+
+ }
+
+ if (fpReceiveBuffer->dwLength > *dwLength) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Update the o/p buffer length
+ //
+ *dwLength = fpReceiveBuffer->dwLength;
+
+ } else {
+
+ Status = EFI_DEVICE_ERROR;
+ *dwLength = 0;
+ }
+
+ //
+ // Save the last cmd status
+ //
+ fpICCDevice->bStatus = fpReceiveBuffer->bStatus;
+ fpICCDevice->bError = fpReceiveBuffer->bError;
+
+
+ //
+ // if success exit
+ //
+ if (!EFI_ERROR(Status) && !fpICCDevice->bStatus) {
+ Status = EFI_SUCCESS;
+ goto exit_RDRToPCDataBlock;
+ }
+
+ // Card not present?
+ Status = EFI_NOT_FOUND;
+ if ((fpReceiveBuffer->bStatus & 7) == 2) goto exit_RDRToPCDataBlock;
+
+ //
+ // Other errors
+ //
+ Status = EFI_DEVICE_ERROR;
+
+exit_RDRToPCDataBlock:
+
+ gSequence++;
+
+ USB_MemFree(fpReceiveBuffer,
+ (UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_DATABLOCK_STRUC) + InputLength)
+ );
+
+ USB_DEBUG (DEBUG_LEVEL_3, " Status : %r bStatus : %02X bError : %02X\n", Status, fpICCDevice->bStatus, fpICCDevice->bError);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RDRToPCSlotStatus
+//
+// Description: RDR_TO_PC_SLOTSTATUS cmd is issued to CCID.
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: bStatus, BError and bClockStatus is updated.
+// See section 6.2.2 of CCID spec Rev 1.1 for more details.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+RDRToPCSlotStatus(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ RDR_TO_PC_SLOTSTATUS_STRUC *fpReceiveBuffer;
+ UINT32 dwData;
+ UINT8 Iterations = 3;
+
+ fpReceiveBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_SLOTSTATUS_STRUC)));
+ ASSERT(fpReceiveBuffer);
+ if (!fpReceiveBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpReceiveBuffer, sizeof(RDR_TO_PC_SLOTSTATUS_STRUC), 0);
+ do {
+ //
+ // Read the PCSlot Status
+ //
+ fpReceiveBuffer->bMessageType = RDR_TO_PC_SLOTSTATUS;
+ fpReceiveBuffer->dwLength = 0;
+ fpReceiveBuffer->bSlot = fpICCDevice->Slot;
+ fpReceiveBuffer->bSeq = gSequence;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, BIT7,
+ (UINT8 *)fpReceiveBuffer,
+ sizeof(RDR_TO_PC_SLOTSTATUS_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit_RDRToPCSlotStatus;
+ }
+
+ //
+ // Check for time extension
+ //
+ if ((fpReceiveBuffer->bStatus & 0xC0) == 0x80) {
+ FixedDelay(fpReceiveBuffer->bError * fpICCDevice->WaitTime * 1000);
+ } else {
+ break;
+ }
+
+ Iterations--;
+ } while (Iterations);
+
+
+ //
+ // Save the last cmd status
+ //
+ fpICCDevice->bStatus = fpReceiveBuffer->bStatus;
+ fpICCDevice->bError = fpReceiveBuffer->bError;
+
+ // Processed without error if Zero
+ if (fpReceiveBuffer->bStatus & 0xC0) {
+ Status = EFI_DEVICE_ERROR;
+
+ if ((fpReceiveBuffer->bStatus & 0x3) == 0x2) {
+ Status = EFI_NOT_FOUND;
+ }
+
+ }
+
+ if (Iterations && !EFI_ERROR(Status)) {
+ //
+ // Update the last ClockStatus
+ //
+ fpICCDevice->bClockStatus = fpReceiveBuffer->bClockStatus;
+ } else {
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit_RDRToPCSlotStatus:
+
+ gSequence++;
+
+ USB_MemFree(fpReceiveBuffer,
+ (UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_SLOTSTATUS_STRUC))
+ );
+
+ USB_DEBUG (DEBUG_LEVEL_3, " Status : %r bStatus : %02X bError : %02X\n", Status, fpICCDevice->bStatus, fpICCDevice->bError);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RDRToPCParameters
+//
+// Description: RDR_TO_PC_SLOTSTATUS cmd is issued
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+// abProtocolDataStructure is copied
+//
+//
+// Notes: bStatus, BErroris updated. See section 6.2.3 of CCID spec
+// Rev 1.1 for more details.
+// bProtocolNum and abProtocolDatStructure is captured.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+RDRToPCParameters(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ RDR_TO_PC_PARAMETERS_T1_STRUC *fpReceiveBuffer;
+ UINT32 dwData;
+ UINT8 Iterations = 3;
+
+ fpReceiveBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_PARAMETERS_T1_STRUC)));
+ ASSERT(fpReceiveBuffer);
+ if (!fpReceiveBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpReceiveBuffer, sizeof(RDR_TO_PC_PARAMETERS_T1_STRUC), 0);
+
+ do {
+
+ //
+ // Read the PCSlot Status
+ //
+ fpReceiveBuffer->Header.bMessageType = RDR_TO_PC_PARAMETERS;
+ fpReceiveBuffer->Header.dwLength = 0;
+ fpReceiveBuffer->Header.bSlot = fpICCDevice->Slot;
+ fpReceiveBuffer->Header.bSeq = gSequence;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, BIT7,
+ (UINT8 *)fpReceiveBuffer,
+ sizeof(RDR_TO_PC_PARAMETERS_T1_STRUC)
+ );
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit_RDRToPCParameters;
+ }
+
+ //
+ // Check for time extension
+ //
+ if ((fpReceiveBuffer->Header.bStatus & 0xC0) == 0x80) {
+ FixedDelay(fpReceiveBuffer->Header.bError * fpICCDevice->WaitTime * fpICCDevice->etu);
+ } else {
+ break;
+ }
+
+ Iterations--;
+
+ } while (Iterations);
+
+ //
+ // Save the last cmd status
+ //
+ fpICCDevice->bStatus = fpReceiveBuffer->Header.bStatus;
+ fpICCDevice->bError = fpReceiveBuffer->Header.bError;
+
+ //
+ // Processed without error if Zero
+ //
+ if (fpReceiveBuffer->Header.bStatus & 0xC0) {
+ Status = EFI_DEVICE_ERROR;
+
+ if ((fpReceiveBuffer->Header.bStatus & 0x3) == 0x2) {
+ Status = EFI_NOT_FOUND;
+ }
+
+ }
+
+ if (Iterations && !EFI_ERROR(Status)) {
+
+ //
+ // Update the Data
+ //
+ MemCopy((UINT8 *)&(fpReceiveBuffer->Header.Data),
+ (UINT8 *)&(fpICCDevice->bProtocolNum),
+ sizeof(RDR_TO_PC_PARAMETERS_T1_STRUC) - 9);
+
+ } else {
+
+ Status = EFI_DEVICE_ERROR;
+ }
+
+exit_RDRToPCParameters:
+
+ gSequence++;
+
+ USB_MemFree(fpReceiveBuffer,
+ (UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_PARAMETERS_T1_STRUC))
+ );
+
+ USB_DEBUG (DEBUG_LEVEL_3, " Status : %r bStatus : %02X bError : %02X\n", Status, fpICCDevice->bStatus, fpICCDevice->bError);
+
+ PrintPCParameters((UINT8 *)&(fpICCDevice->bProtocolNum));
+
+ return Status;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RDRToPCDataRateAndClockFrequency
+//
+// Description: RDR_TO_PC_DATARATEANDCLOCK cmd is issued.
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: Returns dwClockFrequency and dwDataRate.
+// See section 6.2.5 of CCID spec Rev 1.1 for more details.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+RDRToPCDataRateAndClockFrequency(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ RDR_TO_PC_DATARATEANDCLOCKFREQUENCY_STRUC *fpReceiveBuffer;
+ UINT32 dwData;
+ UINT8 Iterations = 3;
+
+ fpReceiveBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_DATARATEANDCLOCKFREQUENCY_STRUC)));
+ ASSERT(fpReceiveBuffer);
+ if (!fpReceiveBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpReceiveBuffer, sizeof(RDR_TO_PC_DATARATEANDCLOCKFREQUENCY_STRUC), 0);
+
+ do {
+
+ //
+ // Read the PCSlot Status
+ //
+ fpReceiveBuffer->bMessageType = RDR_TO_PC_DATARATEANDCLOCK;
+ fpReceiveBuffer->dwLength = 8;
+ fpReceiveBuffer->bSlot = fpICCDevice->Slot;
+ fpReceiveBuffer->bSeq = gSequence;
+
+ dwData = USBCCIDIssueBulkTransfer(fpDevInfo, BIT7,
+ (UINT8 *)fpReceiveBuffer,
+ sizeof(RDR_TO_PC_DATARATEANDCLOCKFREQUENCY_STRUC));
+
+ //
+ // Handle Error if any. This error is due to blk transfer
+ //
+ if (!dwData) {
+ Status = EFI_DEVICE_ERROR;
+ goto exit_RDRToPCDataRateAndClockFrequency;
+ }
+
+ //
+ // Check for time extension
+ //
+ if ((fpReceiveBuffer->bStatus & 0xC0) == 0x80) {
+ FixedDelay(fpReceiveBuffer->bError * fpICCDevice->WaitTime * 1000);
+ } else {
+ break;
+ }
+
+ Iterations--;
+
+ } while (Iterations);
+
+
+ //
+ // Processed without error if Zero
+ //
+ if (fpReceiveBuffer->bStatus & 0xC0) {
+ Status = EFI_DEVICE_ERROR;
+
+ if ((fpReceiveBuffer->bStatus & 0x3) == 0x2) {
+ Status = EFI_NOT_FOUND;
+ }
+ }
+
+ if (Iterations && !EFI_ERROR(Status)) {
+
+ fpICCDevice->dwClockFrequency = fpReceiveBuffer->dwClockFrequency;
+ fpICCDevice->dwDataRate = fpReceiveBuffer->dwDataRate;
+
+ } else {
+
+ Status = EFI_DEVICE_ERROR;
+
+ }
+
+ //
+ // Save the last cmd status
+ //
+ fpICCDevice->bStatus = fpReceiveBuffer->bStatus;
+ fpICCDevice->bError = fpReceiveBuffer->bError;
+
+exit_RDRToPCDataRateAndClockFrequency:
+
+ gSequence++;
+
+ USB_MemFree(fpReceiveBuffer,
+ (UINT8)GET_MEM_BLK_COUNT(sizeof(RDR_TO_PC_DATARATEANDCLOCKFREQUENCY_STRUC))
+ );
+
+ USB_DEBUG (DEBUG_LEVEL_3, " Status : %r bStatus : %02X bError : %02X\n",
+ Status, fpICCDevice->bStatus, fpICCDevice->bError);
+
+ USB_DEBUG (DEBUG_LEVEL_3, " dwClockFrequency : %4x dwDataRate : %4x\n",
+ fpICCDevice->dwClockFrequency, fpICCDevice->dwDataRate);
+
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: TxRxT1Adpu
+//
+// Description: Transmit/Receive T1 ADPU
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice,
+// IN UINT32 CmdLength,
+// IN UINT8 *CmdBuffer,
+// IN UINT8 BlockWaitingTime,
+// IN UINT16 LevelParameter
+//
+// Output:
+//
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+TxRxT1Adpu (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 CmdLength,
+ IN UINT8 *CmdBuffer,
+ OUT UINT32 *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+)
+{
+
+ EFI_STATUS Status;
+
+ //
+ // Issue the cmd
+ //
+ Status = PCToRDRXfrBlock(fpDevInfo, fpICCDevice, CmdLength, CmdBuffer, 0, 0);
+
+ if (EFI_ERROR(Status)){
+ return Status;
+ }
+
+ //
+ // Get the response
+ //
+ Status = RDRToPCDataBlock(fpDevInfo, fpICCDevice, ResponseLength, ResponseBuffer);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: TxRxT1TDPUChar
+//
+// Description: Transmit/Receive T1 TDPU/Character
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice,
+// IN UINT32 CmdLength,
+// IN UINT8 *CmdBuffer,
+// IN UINT8 ISBlock,
+// OUT UINT32 *ResponseLength,
+// OUT UINT8 *ResponseBuffer
+//
+// Output:
+//
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+TxRxT1TDPUChar (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 CmdLength,
+ IN UINT8 *CmdBuffer,
+ IN UINT8 ISBlock,
+ IN OUT UINT32 *ResponseLength,
+ OUT UINT8 *ResponseBuffer
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 Pcb = ISBlock;
+ UINT32 InfLength = CmdLength;
+ UINT8 *InfBuffer = CmdBuffer;
+
+ UINT32 IBlockFrameLength = 0; // Used for I-Block
+ UINT8 *IBlockFrame = NULL;
+
+ UINT32 SendBlockFrameLength = 0; // Place holder for the block currently sent
+ UINT8 *SendBlockFrame = NULL;
+
+ UINT32 RBlockFrameLength = 0; // Used for R-Block
+ UINT8 *RBlockFrame = NULL;
+
+ UINT32 SBlockFrameLength = 0; // Used for S-Block
+ UINT8 *SBlockFrame = NULL;
+
+ UINT32 lResponseLength = 0; // Response buffer for all the blocks I/S/R
+ UINT32 OrglResponseLength = 0;
+ UINT8 *lResponseBuffer;
+
+ UINT8 wLevelParameter = 0;
+
+ UINT8 ReceiveStatus;
+ UINT8 bBWIByte = 0;
+
+ UINT32 UserBufferLength = *ResponseLength;
+ UINT32 lResponseBufferAddDataPtr = 0;
+
+ BOOLEAN T1Char = ((SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor)->dwFeatures & TDPU_LEVEL_EXCHANGE ? FALSE : TRUE;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return EFI_DEVICE_ERROR;
+ }
+ // Initialize Chaining is off
+ fpICCDevice->Chaining = FALSE;
+ *ResponseLength = 0;
+
+ // Update Pcb with Nas only for IBlocks
+ if (!ISBlock) {
+ Pcb = ((fpICCDevice->NaSInterface & 1) << 6);
+ }
+
+ Status = ConstructBlockFrame(fpDevInfo, fpICCDevice,
+ fpICCDevice->NAD, Pcb,
+ CmdLength, CmdBuffer,
+ &wLevelParameter, &IBlockFrameLength,
+ &IBlockFrame
+ );
+
+
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ SendBlockFrameLength = IBlockFrameLength;
+ SendBlockFrame = IBlockFrame;
+
+ if (UserBufferLength < 2) lResponseLength = 2;
+
+ lResponseLength += (UserBufferLength + 3 + (fpICCDevice->EpilogueFields == 0 ? 1 : 2));
+
+ lResponseBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(lResponseLength));
+ ASSERT(lResponseBuffer);
+ if (!lResponseBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill(lResponseBuffer, lResponseLength, 0);
+
+ OrglResponseLength = lResponseLength;
+
+ fpICCDevice->T1CharCmdDataPhase = TRUE; // Always Cmd Phase first
+
+ do {
+
+ Status = PCToRDRXfrBlock(fpDevInfo, fpICCDevice,
+ SendBlockFrameLength, SendBlockFrame,
+ bBWIByte, wLevelParameter
+ );
+
+ if (EFI_ERROR(Status)){
+ break;
+ }
+
+ //
+ // Get the response
+ //
+ lResponseLength = OrglResponseLength - lResponseBufferAddDataPtr;
+ Status = RDRToPCDataBlock(fpDevInfo, fpICCDevice, &lResponseLength, lResponseBuffer + lResponseBufferAddDataPtr);
+
+ if (EFI_ERROR(Status)){
+ break;
+ }
+
+ // Check for errors
+ ReceiveStatus = HandleReceivedBlock(fpDevInfo, fpICCDevice,
+ IBlockFrameLength, IBlockFrame,
+ SendBlockFrameLength, SendBlockFrame,
+ lResponseBuffer
+ );
+
+ bBWIByte = 0;
+
+ switch (ReceiveStatus) {
+
+ case BLOCK_TRANSMISION_SUCCESS:
+ break;
+
+ case RESEND_BLOCK:
+ break;
+
+ case SEND_R_BLOCK_1:
+ case SEND_R_BLOCK_0:
+
+ // Check if Chaining is in progress
+ if (fpICCDevice->Chaining) {
+
+ // Copy the data from lResponseBuffer to the user buffer
+ //
+ // If success copy the data to Response buffer
+ //
+ if (lResponseBuffer[2] && ((UserBufferLength - *ResponseLength) < lResponseBuffer[2])) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ MemCopy(lResponseBuffer+3, ResponseBuffer + *ResponseLength, lResponseBuffer[2]);
+ *ResponseLength += lResponseBuffer[2];
+ lResponseBufferAddDataPtr = 0; // Reset to use the lResponseBuffer from the beginning
+
+ // Clear out the PCB/length feild so that by mistake the buffer is interpreted as valid data
+ lResponseBuffer[1] = 0;
+ lResponseBuffer[2] = 0;
+ lResponseLength = OrglResponseLength;
+
+ }
+ Status = ConstructBlockFrame(fpDevInfo, fpICCDevice,
+ fpICCDevice->NAD, ReceiveStatus == SEND_R_BLOCK_1 ? 0x80 | 0x10 : 0x80,
+ 0, NULL, &wLevelParameter,
+ &RBlockFrameLength, &RBlockFrame
+ );
+
+ if (EFI_ERROR(Status)) {
+ ReceiveStatus = BLOCK_TRANSMISSION_TERMINATE;
+ }
+ SendBlockFrameLength = RBlockFrameLength;
+ SendBlockFrame = RBlockFrame;
+ fpICCDevice->T1CharCmdDataPhase = TRUE;
+ break;
+
+ case I_BLOCK_RESEND:
+
+ Status = ConstructBlockFrame(fpDevInfo, fpICCDevice,
+ fpICCDevice->NAD, Pcb, CmdLength,
+ CmdBuffer, &wLevelParameter,
+ &IBlockFrameLength, &IBlockFrame
+ );
+
+ if (EFI_ERROR(Status)) {
+ ReceiveStatus = BLOCK_TRANSMISSION_TERMINATE;
+ }
+ SendBlockFrameLength = IBlockFrameLength;
+ SendBlockFrame = IBlockFrame;
+ fpICCDevice->T1CharCmdDataPhase = TRUE;
+ break;
+
+ case WTX_RESPONSE:
+
+ bBWIByte = lResponseBuffer[3];
+
+ Status = ConstructBlockFrame(fpDevInfo, fpICCDevice,
+ fpICCDevice->NAD, WTX_RESPONSE,
+ lResponseBuffer[2], lResponseBuffer + 3,
+ &wLevelParameter, &SBlockFrameLength,
+ &SBlockFrame
+ );
+
+ if (EFI_ERROR(Status)) {
+ ReceiveStatus = BLOCK_TRANSMISSION_TERMINATE;
+ }
+
+ SendBlockFrameLength = SBlockFrameLength;
+ SendBlockFrame = SBlockFrame;
+ fpICCDevice->T1CharCmdDataPhase = TRUE;
+ break;
+
+ case GET_DATA_T1_CHAR:
+
+ //
+ // Issue a PCToRDRXfrBlock with dwLength to zero.
+ // Check Page 68 of CCID spec Rev 1.1, Apr 22, 2005
+ //
+
+ SendBlockFrameLength = 0;
+ // Assumption : only LRC is supported
+ wLevelParameter = lResponseBuffer[2] + 1;
+
+ //
+ // Since the prologue is received in the first three bytes increment
+ // the address so that data is recived after that
+ //
+ lResponseBufferAddDataPtr += 3;
+
+ //
+ // Indicate it is data phase now
+ //
+ fpICCDevice->T1CharCmdDataPhase = FALSE;
+ break;
+
+ case IFS_RESPONSE:
+ Status = ConstructBlockFrame(fpDevInfo, fpICCDevice,
+ fpICCDevice->NAD, IFS_RESPONSE,
+ lResponseBuffer[2], lResponseBuffer + 3,
+ &wLevelParameter, &SBlockFrameLength,
+ &SBlockFrame
+ );
+
+ if (EFI_ERROR(Status)) {
+ ReceiveStatus = BLOCK_TRANSMISSION_TERMINATE;
+ }
+
+ SendBlockFrameLength = SBlockFrameLength;
+ SendBlockFrame = SBlockFrame;
+ fpICCDevice->T1CharCmdDataPhase = TRUE;
+ break;
+
+ case ABORT_RESPONSE:
+ Status = ConstructBlockFrame(fpDevInfo, fpICCDevice,
+ fpICCDevice->NAD, ABORT_RESPONSE,
+ lResponseBuffer[2], lResponseBuffer + 3,
+ &wLevelParameter, &SBlockFrameLength,
+ &SBlockFrame
+ );
+
+ if (EFI_ERROR(Status)) {
+ ReceiveStatus = BLOCK_TRANSMISSION_TERMINATE;
+ }
+
+ SendBlockFrameLength = SBlockFrameLength;
+ SendBlockFrame = SBlockFrame;
+ fpICCDevice->T1CharCmdDataPhase = TRUE;
+ break;
+
+ default:
+ break;
+
+ }
+
+ if (ReceiveStatus == BLOCK_TRANSMISION_SUCCESS) {
+ break;
+ }
+ }while (1);
+
+ //
+ // If success copy the data to Response buffer for the last I-Block that was received.
+ //
+ if (lResponseBuffer[2] && ((UserBufferLength - *ResponseLength) < lResponseBuffer[2])) {
+ Status = EFI_BUFFER_TOO_SMALL;
+ }
+
+ if (lResponseBuffer[2] && ((UserBufferLength - *ResponseLength) >= lResponseBuffer[2])) {
+ MemCopy(lResponseBuffer+3, ResponseBuffer + *ResponseLength, lResponseBuffer[2]);
+ *ResponseLength += lResponseBuffer[2];
+ }
+
+ //
+ // Free up memory I-Block allocated here
+ //
+ if (IBlockFrame && IBlockFrameLength) {
+ USB_MemFree(IBlockFrame, (UINT8)GET_MEM_BLK_COUNT(IBlockFrameLength));
+ }
+
+ //
+ // Free up S-Block memory allocated here
+ //
+ if (SBlockFrame && SBlockFrameLength) {
+ USB_MemFree(SBlockFrame, (UINT8)GET_MEM_BLK_COUNT(SBlockFrameLength));
+ }
+
+ if (lResponseBuffer && OrglResponseLength) {
+ USB_MemFree(lResponseBuffer, (UINT8)GET_MEM_BLK_COUNT(OrglResponseLength));
+ }
+
+
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ConstructBlockFrame
+//
+// Description: Construct the Block Frame for the CCID
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice,
+// IN UINT8 Nad,
+// IN UINT8 PCB,
+// IN UINT32 InfLength,
+// IN UINT8 *InfBuffer,
+// OUT UINT8 *wLevelParameter,
+// OUT UINT32 *BlockFrameLength,
+// OUT UINT8 **BlockFrame
+//
+// Output:
+// EFI_STATUS EFI Status
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConstructBlockFrame(
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT8 Nad,
+ IN UINT8 PCB,
+ IN UINT32 InfLength,
+ IN UINT8 *InfBuffer,
+ OUT UINT8 *wLevelParameter,
+ OUT UINT32 *BlockFrameLength,
+ OUT UINT8 **BlockFrame
+)
+{
+
+ UINT32 BufLengthRequired = InfLength + 3 +
+ (fpICCDevice->EpilogueFields == 0 ? 1 : 2);
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Check if the input buffer if already allocated is enough for the current case.
+ // If not free it up and allocate again.
+ //
+
+ if (BufLengthRequired > *BlockFrameLength) {
+ if (*BlockFrame) {
+ USB_MemFree(*BlockFrame, (UINT8)GET_MEM_BLK_COUNT(*BlockFrameLength));
+ *BlockFrame = NULL;
+
+ }
+ }
+
+ *BlockFrameLength = InfLength + 3 + (fpICCDevice->EpilogueFields == 0 ? 1 : 2);
+
+ //
+ // if BlockFrame is NULL only then allocate memory. Assumption is if Memory
+ // has been allocated before then it is sufficent enough for the length needed.
+ //
+ if (!*BlockFrame) {
+ //
+ // Allocate length needed to contruct the Block Frame
+ //
+ *BlockFrame = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(*BlockFrameLength));
+
+ if (!*BlockFrame) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ MemFill(*BlockFrame, *BlockFrameLength, 0);
+
+ (*BlockFrame)[0] = Nad;
+ (*BlockFrame)[1] = PCB;
+ (*BlockFrame)[2] = InfLength;
+
+ if (InfLength) {
+ MemCopy((UINT8 *)InfBuffer, (UINT8 *)(*BlockFrame + 3), InfLength);
+ }
+
+ //
+ // Update Checksum
+ //
+ (*BlockFrame)[*BlockFrameLength - 1] = 0;
+
+ if (fpICCDevice->EpilogueFields == 0) {
+ CalculateLRCChecksum(*BlockFrame, *BlockFrameLength);
+ } else {
+ return EFI_UNSUPPORTED;
+ }
+
+ //
+ // For Character transfer update wLevelParameter also
+ //
+ if (!(((SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor)->dwFeatures & 0x70000)) {
+ *wLevelParameter = 3;
+ }
+
+ return EFI_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: HandleReceivedBlock
+//
+// Description: Process the Recevied data from CCID device
+//
+// Input:
+// IN DEV_INFO *fpDevInfo,
+// IN ICC_DEVICE *fpICCDevice,
+// IN UINT32 OriginalBlockFrameLength,
+// IN UINT8 *OriginalBlockFrame,
+// IN UINT32 SentBlockFrameLength,
+// IN UINT8 *SentBlockFrame,
+// IN UINT8 *ReceivedBlockFrame
+//
+// Output:
+//
+//
+// Notes:
+// For Character exchange control will come twice for S(Response), I-Block with M bit set. So while counting
+// number of exchnages this needs to be taken care of.
+// Refer to ISO/IEC 7816-1 First edition 1998-10-15 for different scenarios mentioned in this function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+HandleReceivedBlock (
+ IN DEV_INFO *fpDevInfo,
+ IN ICC_DEVICE *fpICCDevice,
+ IN UINT32 OriginalBlockFrameLength,
+ IN UINT8 *OriginalBlockFrame,
+ IN UINT32 SentBlockFrameLength,
+ IN UINT8 *SentBlockFrame,
+ IN UINT8 *ReceivedBlockFrame
+)
+{
+
+ UINT8 ReturnParameter = BLOCK_TRANSMISION_SUCCESS;
+ BOOLEAN T1Char = ((SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor)->dwFeatures & 0x70000 ? FALSE : TRUE;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return BLOCK_TRANSMISSION_TERMINATE;
+ }
+
+ // It is easy to support T1 TDPU & CHAR as they are almost same except that
+ // prologue and data are received separatly in T1 Char.
+ // The trick here will be that when data is received we can combine the
+ // previously received prologue and the INF/Epilogue received
+ // later so that it will be similar to T1 TDPU. Then all the processing will be same.
+
+ if (!ReceivedBlockFrame){ // if no response
+
+ if (fpICCDevice->RBlockCounter == 2) {
+ return BLOCK_TRANSMISSION_TERMINATE;
+ }
+
+
+
+ // If I-Block sent before and no response, send R-Block with the expected I Block(N(R). Rule 7.1/Rule 7.6
+ if (!(SentBlockFrame[1] & 0x80)) {
+
+ fpICCDevice->RBlockCounter++;
+
+ if (fpICCDevice->NaSCard) {
+ return SEND_R_BLOCK_0;
+ } else {
+ return SEND_R_BLOCK_1;
+ }
+ }
+
+ }
+
+ // Reset the RBlock Counter if the response we received isn't a R-Block.
+ if ((ReceivedBlockFrame[1] & 0xC0) != RBLOCK) {
+ fpICCDevice->RBlockCounter = 0;
+ }
+
+ //
+ // Is the block received an I-Block?
+ //
+ if (!(ReceivedBlockFrame[1] & 0x80)) {
+
+ //
+ // It is T1 Char and also if in cmd phase handle it.
+ //
+ if (T1Char && fpICCDevice->T1CharCmdDataPhase) {
+
+ // Save the N(s) from the card for later use.
+ fpICCDevice->NaSCard = (ReceivedBlockFrame[1] & NSBIT) >> 6;
+
+ // If data needs to be received
+ if (ReceivedBlockFrame[2]){
+ return GET_DATA_T1_CHAR;
+ } else {
+ return BLOCK_TRANSMISION_SUCCESS;
+ }
+
+ }
+
+ // It is T1TDPU or it is T1 Char but in data phase
+
+
+ // Is Mbit set, then nothing more to do
+ if (!(ReceivedBlockFrame[1] & 0x20)) {
+ //
+ // Toggle N(S) bit only after a successful I Block Transmission
+ //
+ fpICCDevice->Chaining = FALSE;
+ fpICCDevice->NaSInterface = !(fpICCDevice->NaSInterface);
+
+ return BLOCK_TRANSMISION_SUCCESS;
+ }
+ else {
+ // Since Mbit is set, Send R-Block with the next N(s) expected from card. Section 5, Rules 2.2 and 5
+
+ fpICCDevice->Chaining = TRUE;
+
+ if (fpICCDevice->NaSCard){
+ return SEND_R_BLOCK_0;
+ }
+ else {
+ return SEND_R_BLOCK_1;
+ }
+ }
+ }
+
+ // No difference between T1 Char and T1 Tdpu in R-phase
+
+ //
+ // Is the Block received is a R block?
+ //
+ if ((ReceivedBlockFrame[1] & 0xC0) == RBLOCK) {
+
+
+ // Is there an error?
+ if (ReceivedBlockFrame[1] & 0x03) {
+ //Re-transmit it
+ if ((SentBlockFrame[1] & 0xc0) == 0x00) {
+ return I_BLOCK_RESEND;
+ }
+ else {
+ return RESEND_BLOCK;
+ }
+ }
+
+ if (T1Char && fpICCDevice->T1CharCmdDataPhase) {
+ return GET_DATA_T1_CHAR;
+ }
+
+ if (fpICCDevice->RBlockCounter == 3) {
+ fpICCDevice->RBlockCounter = 0;
+ return BLOCK_TRANSMISSION_TERMINATE;
+ }
+ fpICCDevice->RBlockCounter++;
+
+ if (fpICCDevice->Chaining == FALSE) {
+
+ //
+ // if the received R-Block is same as the last sent I-Block AND Chaining is not in progress, resend I-Block. Scenario 8
+ //
+ if ((ReceivedBlockFrame[1] & 0x10) >> 4 == (fpICCDevice->NaSInterface & 1) << 6) {
+ return I_BLOCK_RESEND;
+ }
+ else {
+ //
+ // Scenario 11/12
+ //
+ if (fpICCDevice->NaSInterface & 1) {
+ return SEND_R_BLOCK_1;
+ } else {
+ return SEND_R_BLOCK_0;
+ }
+ }
+ }
+ else {
+ //
+ // Chaining is in progress...
+ //
+ //
+ // Scenario 5
+ //
+ if ((ReceivedBlockFrame[1] & 0x10) >> 4 != (fpICCDevice->NaSInterface & 1) << 6) {
+ // return I_BLOCK;
+ }
+ //
+ // Scenario 23
+ //
+ if (ReceivedBlockFrame[1] == SentBlockFrame[1]) {
+ if (ReceivedBlockFrame[1] & 0x10) {
+ return SEND_R_BLOCK_1;
+ } else {
+ return SEND_R_BLOCK_0;
+ }
+ }
+
+ }
+
+ // We can try giving S-Synch also if it doesn't respond to R-Block.
+ // S-Synch can be done only for 2nd Iblock on-wards.
+ }
+
+ //
+ // Is the Block Received is a S block?
+ //
+ if ((ReceivedBlockFrame[1] & 0xC0) == 0xC0) {
+
+ switch (ReceivedBlockFrame[1]) {
+
+ case IFS_REQUEST:
+
+ if (T1Char && fpICCDevice->T1CharCmdDataPhase) {
+ ReturnParameter = GET_DATA_T1_CHAR;
+ break;
+ }
+ // Save the new IFSD data
+ fpICCDevice->IFSD = ReceivedBlockFrame[3];
+ ReturnParameter = IFS_RESPONSE;
+ break;
+
+ case IFS_RESPONSE:
+ //
+ // It is T1 Char and also if in cmd phase handle it.
+ //
+ if (T1Char && fpICCDevice->T1CharCmdDataPhase) {
+
+ // If data needs to be received
+ if (ReceivedBlockFrame[2]){
+ return GET_DATA_T1_CHAR;
+ } else {
+ return BLOCK_TRANSMISION_SUCCESS;
+ }
+ }
+ break;
+
+ case ABORT_REQUEST:
+ fpICCDevice->Chaining = FALSE;
+ ReturnParameter = ABORT_RESPONSE;
+ break;
+
+ case ABORT_RESPONSE:
+ break;
+
+ case WTX_REQUEST:
+
+ if (T1Char && fpICCDevice->T1CharCmdDataPhase) {
+ ReturnParameter = GET_DATA_T1_CHAR;
+ break;
+ }
+
+ ReturnParameter = WTX_RESPONSE;
+ break;
+
+ case RESYNCH_RESPONSE:
+ break;
+
+ case WTX_RESPONSE: // Won't be received from card. Card will only generate WTX request.
+ break;
+ case RESYNCH_REQUEST: // Card won't issue ReSynch
+ break;
+ default:
+ break;
+
+ }
+
+ }
+
+ return ReturnParameter;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateLRCChecksum
+//
+// Description: Calculates LRC checksum
+//
+// Input:
+// UINT8 *BlockFrame
+// UINT32 BlockFrameLength
+//
+// Output:
+// ICC_DEVICE* or NULL
+//
+// Notes:
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CalculateLRCChecksum (
+ UINT8 *BlockFrame,
+ UINT32 BlockFrameLength
+)
+{
+ UINT32 i = 0;
+
+ for (; i < BlockFrameLength - 1; i++ ){
+ BlockFrame[BlockFrameLength-1] ^= BlockFrame[i];
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetICCDevice
+//
+// Description: Search the linked list to find the ICC_DEVICE for the given slot #.
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// UINT8 Slot
+//
+// Output:
+// ICC_DEVICE* or NULL
+//
+// Notes:
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ICC_DEVICE*
+GetICCDevice(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+)
+{
+ ICC_DEVICE *fpICCDevice;
+ DLINK *dlink;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ dlink = fpDevInfo->ICCDeviceList.pHead;
+
+ for ( ; dlink; dlink = dlink->pNext) {
+
+ fpICCDevice = OUTTER(dlink, ICCDeviceLink, ICC_DEVICE);
+
+ //
+ // Slot # matches
+ //
+ if (fpICCDevice->Slot == Slot) {
+ if (((UINT8*)fpICCDevice < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)((UINTN)fpICCDevice + sizeof(ICC_DEVICE)) > MemBlockEnd)) {
+ return NULL;
+ }
+ return fpICCDevice;
+ }
+
+ }
+
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdateATRDataInfo
+//
+// Description: The routine update the Transmision protocol supported and other
+// timing related data
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// None
+//
+// Notes: This function looks into ATR data and updates CLASS A/B/C information,
+// calculates ETU, WaitTime etc
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+UpdateATRDataInfo(
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice
+)
+{
+ UINT8 bData;
+ UINT8 i=1;
+
+ //
+ // T0 is mandatory
+ //
+ fpICCDevice->AtrData.T0 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.NumberofHystoricalBytes = fpICCDevice->RawATRData[i] & 0xF;
+ i++;
+
+ //
+ // Update TA1
+ //
+ if (fpICCDevice->AtrData.T0 & 0x10) {
+ fpICCDevice->AtrData.TA1 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TA1Present = TRUE;
+ i++;
+ } else {
+ //
+ // Default value if TA1 is not present
+ //
+ fpICCDevice->AtrData.TA1 = 0x11;
+ }
+
+ bData = fpICCDevice->AtrData.TA1;
+ fpICCDevice->GlobalFi = FiFmaxDi[(bData >> 4) * 3];
+ fpICCDevice->GlobalFmax = (UINT8)FiFmaxDi[(bData >> 4) * 3 + 1];
+ fpICCDevice->GlobalDi = (UINT8)FiFmaxDi[(bData& 0xF) * 3 + 2];
+
+
+ //
+ // Update TB1
+ //
+ if (fpICCDevice->AtrData.T0 & 0x20) {
+ fpICCDevice->AtrData.TB1 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TB1Present = TRUE;
+ i++;
+ }
+
+ //
+ // Update TC1
+ //
+ if (fpICCDevice->AtrData.T0 & 0x40) {
+ fpICCDevice->AtrData.TC1 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TC1Present = TRUE;
+ i++;
+ }
+
+ //
+ // Update TD1
+ //
+ if (fpICCDevice->AtrData.T0 & 0x80) {
+ fpICCDevice->AtrData.TD1 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TD1Present = TRUE;
+ i++;
+ }
+
+ if (fpICCDevice->AtrData.TD1) {
+
+ //
+ // Update TA2
+ //
+ if (fpICCDevice->AtrData.TD1 & 0x10) {
+ fpICCDevice->AtrData.TA2 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TA2Present = TRUE;
+ fpICCDevice->SpecificMode = fpICCDevice->AtrData.TA2 & BIT7 ? TRUE : FALSE;
+ i++;
+ }
+
+ //
+ // Update TB2
+ //
+ if (fpICCDevice->AtrData.TD1 & 0x20) {
+ fpICCDevice->AtrData.TB2 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TB2Present = TRUE;
+ i++;
+ }
+
+ //
+ // Update TC2
+ //
+ if (fpICCDevice->AtrData.TD1 & 0x40) {
+ fpICCDevice->AtrData.TC2 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TC2Present = TRUE;
+ i++;
+ }
+
+ //
+ // Update TD2
+ //
+ if (fpICCDevice->AtrData.TD1 & 0x80) {
+ fpICCDevice->AtrData.TD2 = fpICCDevice->RawATRData[i];
+ fpICCDevice->AtrData.TD2Present = TRUE;
+ i++;
+ }
+ }
+
+ //
+ // Check if T15 is present else only CLASS A is supported.
+ // By default CLASS A is supported
+ //
+ fpICCDevice->ClassABC = 1;
+
+ for (bData = 1; bData < MAX_ATR_LENGTH ;){
+
+ //
+ // Is it T15?
+ //
+ if ((fpICCDevice->RawATRData[bData] & 0xF) == 0xF){
+ fpICCDevice->ClassABC = fpICCDevice->RawATRData[bData + 1] & 0x3F;
+ fpICCDevice->StopClockSupport = fpICCDevice->RawATRData[bData + 1] >> 5;
+
+ fpICCDevice->AtrData.TD15 = fpICCDevice->RawATRData[bData];
+ fpICCDevice->AtrData.TD15Present = TRUE;
+
+ fpICCDevice->AtrData.TA15 = fpICCDevice->RawATRData[bData + 1];
+ fpICCDevice->AtrData.TA15Present = TRUE;
+
+ break;
+ } else {
+ // We need info on how many Transmission Protocols are supported by the
+ // card and what are those. Use these loop to do that.
+ if (bData > 1) { // Skip T0
+ i = fpICCDevice->TransmissionProtocolSupported;
+ fpICCDevice->TransmissionProtocolSupported |= ( 1 << (fpICCDevice->RawATRData[bData] & 0x0F));
+ if (i != fpICCDevice->TransmissionProtocolSupported) {
+ fpICCDevice->NumofTransmissionProtocolSupported++;
+ }
+ }
+
+ // No more valid TDx?
+ if (!(fpICCDevice->RawATRData[bData] & 0x80)) break;
+ bData += FindNumberOfTs(fpICCDevice->RawATRData[bData]);
+ }
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: GetDefaultProtocol
+//
+// Description: Find the First offerred Transmission protocol.
+//
+// Input:
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// TRANSMISSION_PROTOCOL
+//
+// Notes: Section 8.2.3 ISO 7816-3 2006-11-01: TD1 encodes first offered protocol.
+// If TD1 not present assume T0.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+TRANSMISSION_PROTOCOL GetDefaultProtocol (
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ if (fpICCDevice->AtrData.TD1Present) {
+ return fpICCDevice->AtrData.TD1 & 0xf;
+ }
+
+ return T0_PROTOCOL;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: FindBestTA1Value
+//
+// Description: CCID which doesn't perform "Automatic parameter config. based on ATR
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// UINT8 Best TA1 value
+//
+// Notes:
+// 1. Calculate the Baud rate using TA1 value
+//
+// 2. If in CCID bNumDataRatesSupported = 0 then any value between dwDatRate
+// and dwMaxDataRate is supported
+//
+// 3. Check if ICC baud rate is less tha dwMaxDataRate. If yes use that.
+//
+// 4. If bNumDataRatesSupported is not zero get all possible values and try to
+// match it and use that value.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+FindBestTA1Value (
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ UINT32 ICCBaudrate;
+ UINT8 Di = fpICCDevice->GlobalDi;
+ SMARTCLASS_DESC *CCIDDescriptor = (SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return 0;
+ }
+ //
+ // If Automatic parameter conf. based on ATR data is
+ //
+ if (CCIDDescriptor->dwFeatures & AUTO_PARAMETER_CONFIG) {
+ return fpICCDevice->AtrData.TA1;
+ }
+
+ ICCBaudrate = (fpICCDevice->GlobalFmax * 1000 * fpICCDevice->GlobalDi)/fpICCDevice->GlobalFi;
+
+ if (fpDevInfo->DataRates && fpDevInfo->ClockFrequencies) {
+ /*
+ // Find the match
+ for (i = fpDevInfo->pCCIDDescriptor->bNumDataRatesSupported; i; --i) {
+ // Since the values may not match exactly give some leeway
+ if (ICCBaudrate >= (fpDevInfo->DataRates[i] - 1000) && ICCBaudrate <= (fpDevInfo->DataRates[i] + 1000)){
+ // See whether the matched baud rate can be achieved with the supported frequencies
+ for (j = fpDevInfo->pCCIDDescriptor->bNumDataRatesSupported; j; --j) {
+ if (fpICCDevice->GlobalFmax == fpDevInfo->ClockFrequencies[i]) break;
+ }
+ if (j) {
+ CalcBaudRate =
+ }
+ else {
+ }
+ break;
+ }
+ }
+ */
+ } else {
+ if (ICCBaudrate <= CCIDDescriptor->dwMaxDataRate) {
+ return fpICCDevice->AtrData.TA1;
+ } else {
+ //
+ // Can we decrement the Di value and try to match it
+ //
+ for ( ; Di ; --Di){
+ ICCBaudrate = (fpICCDevice->GlobalFmax * 1000 * Di)/fpICCDevice->GlobalFi;
+ if (ICCBaudrate <= CCIDDescriptor->dwMaxDataRate) {
+ return ((fpICCDevice->AtrData.TA1 & 0xF0) | Di);
+ }
+ }
+ }
+ }
+
+ //
+ // Worst case return the default value.
+ // Actuall we should fail saying this CCID/ICC combination isn't supported.
+ //
+ return fpICCDevice->AtrData.TA1;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: CalculateTimingValues
+//
+// Description: Based on the agreed upon TA1 value and Transmission protocol
+// calculate the timing values
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// None
+//
+// Notes:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CalculateTimingValues (
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ UINT8 NValue;
+ UINT8 bData;
+ UINT8 TDCount = 0;
+
+ fpICCDevice->bmFindIndex = fpICCDevice->AtrData.TA1;
+
+ //
+ // NValue defaults to zero if TC1 not present
+ //
+ NValue = fpICCDevice->AtrData.TC1Present == TRUE ? fpICCDevice->AtrData.TC1 : 0;
+
+ //
+ // Calculate 1 etu in micro sec
+ //
+ fpICCDevice->etu = fpICCDevice->GlobalFi / (fpICCDevice->GlobalDi * fpICCDevice->GlobalFmax);
+
+ //
+ // Extra Gaurd Time GT in etu units (section 8.3)
+ //
+ if (fpICCDevice->AtrData.TA15Present) {
+ fpICCDevice->ExtraGuardTime = 12 +
+ (NValue / fpICCDevice->GlobalFmax * fpICCDevice->GlobalFi/ fpICCDevice->GlobalDi);
+ } else {
+ fpICCDevice->ExtraGuardTime = 12 + (NValue / fpICCDevice->GlobalFmax) ;
+ }
+
+ // Update Wait Time (see section 10.2)
+ // WT = WI * 960 * Fi /f where WI is TC2
+ // Default if TC2 is not present
+ bData = 10;
+
+ if (fpICCDevice->AtrData.TC2Present) {
+ bData = fpICCDevice->AtrData.TC2;
+ }
+
+ //
+ // Calculate WT (wait time between two characters) in ETU units
+ //
+ fpICCDevice->WTwaittime = 960 * fpICCDevice->GlobalFi/(fpICCDevice->GlobalFmax);
+
+
+ // update Block Width time and Epilogue bit
+ // BWT = 11etu + 2 ^ BWI * 960 * Fd /f (Section 11.4.3)
+ // Default BWI is 4. Bit 7:4 in first TB for T1 encodes BWI
+ // Fd = 372 (sec section 8.1)
+
+ // Default values (11.4.3)
+ fpICCDevice->BWI = 4;
+ fpICCDevice->CWI = 13;
+ fpICCDevice->IFSC = 32;
+ fpICCDevice->IFSD = 32;
+ fpICCDevice->NAD = 0;
+
+ for (bData = 1; bData < MAX_ATR_LENGTH; ){
+
+ // Look for the First TD for T= 1. It should from TD2
+ if (TDCount < 2) {
+ if (fpICCDevice->RawATRData[bData] & 0x80) {
+ TDCount++;
+ bData += FindNumberOfTs(fpICCDevice->RawATRData[bData]);
+ continue;
+ } else {
+ break;
+ }
+ }
+
+ // Is it T1?
+ if ((fpICCDevice->RawATRData[bData] & 0xF) == 0x1){
+
+ if (fpICCDevice->RawATRData[bData] & 0x10) {
+ fpICCDevice->IFSC = fpICCDevice->RawATRData[bData + 1];
+ }
+
+ if (fpICCDevice->RawATRData[bData] & 0x20) {
+ fpICCDevice->BWI = (fpICCDevice->RawATRData[bData + 2] & 0xF0) >> 4;
+ fpICCDevice->CWI = fpICCDevice->RawATRData[bData + 2] & 0xF;
+ }
+
+ // Section 11.4.4
+ if (fpICCDevice->RawATRData[bData] & 0x40) {
+ fpICCDevice->EpilogueFields = (fpICCDevice->RawATRData[bData + 3] & 0x1);
+ }
+
+ break;
+ }
+
+ //
+ // No more valid TDx?
+ //
+ if (!(fpICCDevice->RawATRData[bData] & 0x80)) break;
+
+ bData += FindNumberOfTs(fpICCDevice->RawATRData[bData]);
+
+ }
+
+ //
+ // Block Widthtime in ETU units
+ //
+ fpICCDevice->BWT = ((1 << (fpICCDevice->BWI - 1)) * 960 * 372 /(fpICCDevice->GlobalFmax)) + 11;
+
+ PrintTimingInfo(fpICCDevice);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: IssuePPSCmd
+//
+// Description: Issue PPS cmd to select T0/T1
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// ICC_DEVICE *fpICCDevice
+// UINT8 *Data : Points to the buffer which is sent to CCID.
+// Refer Section 9.2 of 7816-3 spec for the format
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// This command is issued to CCID which doesn't support AUTO_PARAMETER_CONFIG
+// or when default values or not acceptable
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+IssuePPSCmd(
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice,
+ UINT8 *Data,
+ UINT8 DataLength
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ UINT8 *ResponseBuffer;
+ UINT32 ResponseLength = DataLength;
+ SMARTCLASS_DESC *CCIDDescriptor = (SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Allocate memory for receiving data
+ //
+ ResponseBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(DataLength));
+ ASSERT(ResponseBuffer);
+ if (!ResponseBuffer) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)ResponseBuffer, DataLength, 0);
+
+
+ //
+ //Check what level of Transmission Protocol is supported
+ //
+ ResponseLength = 0;
+ if (!(CCIDDescriptor->dwFeatures & 0x70000)){
+ ResponseLength = 2; // For Character exchange only 2 bytes expected.
+ }
+
+
+ Status = PCToRDRXfrBlock(fpDevInfo, fpICCDevice, DataLength, Data, 0, ResponseLength);
+ if (CCIDDescriptor->dwFeatures & 0x70000){
+ ResponseLength = 4; // For TDPU expected data is 4
+ }
+ Status = RDRToPCDataBlock(fpDevInfo, fpICCDevice, &ResponseLength, ResponseBuffer);
+
+ // If length is not same and only Character level Transmission is supported,
+ // issue another XfrBlock cmd to get the rest of the data
+ if ((ResponseLength != DataLength) && !(CCIDDescriptor->dwFeatures & 0x70000)) {
+
+ DataLength = ResponseLength;
+ ResponseLength = 2;
+ Status = PCToRDRXfrBlock(fpDevInfo, fpICCDevice, 0, Data, 0, ResponseLength);
+ Status = RDRToPCDataBlock(fpDevInfo, fpICCDevice, &ResponseLength, ResponseBuffer + DataLength);
+
+ }
+
+ //
+ // I/P and O/P should be identical for success
+ //
+ USB_MemFree(ResponseBuffer, (UINT8)GET_MEM_BLK_COUNT(DataLength));
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: VoltageSelection
+//
+// Description: Based on the dwFeatures register setting, power up CCID/ICC
+//
+// Input:
+// DEV_INFO *fpDevInfo,
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: Based on dwFeatures value from SMART Class Descriptor either
+// do an automatic Power-on or go through a manual
+// power up sequence and then callect the ATR data.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+VoltageSelection(
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_DEVICE_ERROR;
+ EFI_STATUS ATRStatus = EFI_DEVICE_ERROR;
+ SMARTCLASS_DESC *CCIDDescriptor = (SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor;
+ //
+ // Get all voltage level supported by CCID
+ //
+ UINT8 VoltageLevelCCID = CCIDDescriptor->bVoltageSupport;
+ //
+ // Select the lowest voltage
+ //
+ UINT8 VoltageMask = VOLT_18;
+ //
+ // Successful poweron will result in ATR data
+ //
+ UINT32 BufferLength = MAX_ATR_LENGTH;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return EFI_DEVICE_ERROR;
+ }
+ //
+ // Make sure the first selection is valid
+ //
+ do {
+
+ if (VoltageLevelCCID & VoltageMask) {
+ break;
+ }
+
+ VoltageMask = VoltageMask >> 1;
+
+ }while (VoltageMask);
+
+ //
+ // If Automatic Voltage selection is supported go for it.
+ // Discard the initialization done above
+ if (CCIDDescriptor->dwFeatures & AUTO_ACTIVATION_VOLT_SELECTION){
+ //
+ // Automatic Voltage selection is supported
+ //
+ VoltageLevelCCID = AUTO_VOLT;
+ VoltageMask = 0;
+ }
+
+ do {
+
+ //
+ // Issue the cmd to Power it up
+ //
+ Status = PCtoRDRIccPowerOn (fpDevInfo,
+ fpICCDevice,
+ ((VoltageLevelCCID & VoltageMask) == 4) ? 3 : VoltageMask);
+
+ if(EFI_ERROR(Status)) {
+ break;
+ }
+
+ //
+ // Get the response to IccPoweron
+ //
+ BufferLength = MAX_ATR_LENGTH;
+ Status = RDRToPCDataBlock ( fpDevInfo,
+ fpICCDevice,
+ &BufferLength,
+ fpICCDevice->RawATRData
+ );
+
+ //
+ // if successfully powered up, ATR data should be available
+ //
+ if (!EFI_ERROR(Status) && BufferLength) {
+
+ fpICCDevice->ConfiguredStatus |= (ICCPRESENT | VOLTAGEAPPLIED | ATRDATAPRESENT);
+
+ PrintATRData(fpICCDevice->RawATRData);
+
+ // From the ATR data, get the required information
+ UpdateATRDataInfo(fpDevInfo, fpICCDevice);
+
+ // ATR data got successfully and configured successfully.
+ ATRStatus = EFI_SUCCESS;
+ break;
+
+ }
+
+ //
+ // if Card not present
+ //
+ if ((fpICCDevice->bStatus & 7) == 2) {
+ Status = EFI_NOT_FOUND;
+ break;
+ }
+
+ //
+ // ICC is present but some error
+ //
+ fpICCDevice->ConfiguredStatus |= ICCPRESENT;
+
+ //
+ // Card present but voltage selection is not OK. Power it off and select next voltage
+ //
+ Status = PCtoRDRIccPowerOff (fpDevInfo, fpICCDevice);
+ if (EFI_ERROR(Status)) break;
+
+ Status = RDRToPCSlotStatus(fpDevInfo, fpICCDevice);
+ if (EFI_ERROR(Status)) break;
+
+ VoltageMask = VoltageMask >> 1;
+
+ //
+ // 10 msec delay before applying the next power class Spec 6.2.3
+ //
+ FixedDelay (10 * 1000);
+
+ } while (VoltageMask);
+
+ // Return the status of the ATR data read and configuration
+ return ATRStatus;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: RateAndProtocolManagement
+//
+// Description: Based on the ATR data and the dwFeature register contend
+// do the Rate and Protocol programming
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: Based on data received from Power-on sequence (ATR data) and dwFetaures value,
+// Speed of communicatin is established.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+RateAndProtocolManagement(
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ EFI_STATUS Status = EFI_SUCCESS;
+ PROTOCOL_DATA_T1 Data = {0};
+ UINT8 PPSData[] = {0xFF, 0x10, 0x11, 0x00};
+ UINT8 Counter;
+ SMARTCLASS_DESC *CCIDDescriptor = (SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor;
+ UINT32 ClockFrequency = CCIDDescriptor->dwMaximumClock;
+ UINT32 DataRate = CCIDDescriptor->dwMaxDataRate;
+ BOOLEAN FlagToIssueSetParameters = FALSE;
+ TRANSMISSION_PROTOCOL FirstOfferredProtocol;
+ UINT8 DefaultTA1 = fpICCDevice->AtrData.TA1;
+ UINT8 SetIFS[] = {0xFC};
+ UINT32 ResponseLength;
+ UINT8 ResponseBuffer[20];
+ UINT32 ExchangeLevel = (CCIDDescriptor->dwFeatures & 0x70000);
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return EFI_DEVICE_ERROR;
+ }
+ FirstOfferredProtocol = GetDefaultProtocol(fpICCDevice);
+
+ fpICCDevice->bProtocolNum = (UINT8)FirstOfferredProtocol;
+
+ //
+ // Check whether TA1 value is good enough for the reader. If not get the right value
+ //
+ fpICCDevice->AtrData.TA1 = FindBestTA1Value(fpDevInfo, fpICCDevice);
+
+
+ //
+ // Check if more than one transmission protocol is supported.
+ // If yes then there may be a need for PPSCmd (ISO 7816-3:2006(E) Sec: 6.3.1)
+ // Check if Automatic PPS negotiation done by CCID or not. If not issue one.
+ // If TA2 is present Card is in Specific mode. So no need for PPS (7816-3:2006 see sec 6.3 fig 4)
+ //
+
+ // When PPS exchange must be made? (Page 19 CCID Rev 1.1)
+ // 1. If both AUTO_PPS_NEGOTIATION_CCID AND AUTO_PPS_NEGOTIATION_ACTIVE are not set PPS must be given in case of TDPU or Character
+ // OR
+ // 2. if AUTO_PPS_NEGOTIATION_ACTIVE is present AND TA2 not present AND the preferred protocol isn't USE_T0_T1_PROTOCOL
+
+ if (((CCIDDescriptor->dwFeatures & (AUTO_PPS_NEGOTIATION_CCID | AUTO_PPS_NEGOTIATION_ACTIVE)) == 0 &&
+ (ExchangeLevel <= 0x10000 ) && !fpICCDevice->AtrData.TA2Present) ||
+ ((CCIDDescriptor->dwFeatures & AUTO_PPS_NEGOTIATION_ACTIVE) && !fpICCDevice->AtrData.TA2Present &&
+ fpICCDevice->NumofTransmissionProtocolSupported > 1 && FirstOfferredProtocol != USE_T0_T1_PROTOCOL)) {
+ //
+ // Update PPS data if in case PPSCmd needs to be issued
+ //
+ PPSData[1] |= FirstOfferredProtocol;
+
+ //
+ // Update PPS2
+ //
+ PPSData[2] = fpICCDevice->AtrData.TA1;
+
+ //
+ // Update checksum
+ //
+ for (Counter = 0; Counter < sizeof (PPSData) - 1; Counter++) {
+ PPSData[sizeof (PPSData) - 1] ^= PPSData[Counter];
+ }
+
+ Status = IssuePPSCmd(fpDevInfo, fpICCDevice, PPSData, sizeof (PPSData));
+ }
+
+ if (CCIDDescriptor->dwFeatures & AUTO_PARAMETER_CONFIG) {
+
+ //
+ // Issue GetParameters to get the Transmission Protocol and other parameters
+ //
+ Status = PCToRDRGetParameters(fpDevInfo, fpICCDevice);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = RDRToPCParameters(fpDevInfo, fpICCDevice);
+ if (EFI_ERROR(Status)) return Status;
+
+ fpICCDevice->ExtraGuardTime = fpICCDevice->bGuardTime;
+ fpICCDevice->WTwaittime = fpICCDevice->bWaitingInteger;
+ fpICCDevice->IFSC = fpICCDevice->bIFSC;
+ fpICCDevice->NAD = fpICCDevice->nNadValue;
+
+ } else {
+
+ //
+ // Now that the TA1 value and the protocol has been finalized,
+ // It is time to calculate the different timing parameters.
+ //
+ CalculateTimingValues (fpDevInfo, fpICCDevice);
+ }
+
+ //
+ //If Automatic Parameters config. based on ATR data is not
+ //supported then issue SetParameters cmd
+ //
+ if (!(CCIDDescriptor->dwFeatures & AUTO_PPS_NEGOTIATION_ACTIVE)){ // 0x80
+
+ //
+ // Use the superset of the T0/T1 structure (ie T1 structure) even if it is T0. It should work.
+ //
+ Data.bmFindDindex = fpICCDevice->bmFindIndex;
+ Data.bmTCCKST1 = fpICCDevice->bProtocolNum == 0 ? 0 : (fpICCDevice->EpilogueFields | 0x10);
+ Data.bGuardTimeT1 = fpICCDevice->ExtraGuardTime;
+
+ Data.bWaitingIntergersT1 = fpICCDevice->bProtocolNum == 0 ?
+ fpICCDevice->WTwaittime : (fpICCDevice->BWI << 4 | fpICCDevice->CWI);
+
+ Data.bClockStop = fpICCDevice->bClockStop;
+ Data.bIFSC = fpICCDevice->IFSC;
+ Data.bNadValue = fpICCDevice->NAD;
+
+ Status = PCToRDRSetParameters(fpDevInfo, fpICCDevice, fpICCDevice->bProtocolNum, (VOID *)&Data);
+
+ if (!EFI_ERROR(Status)){
+ Status = RDRToPCParameters(fpDevInfo, fpICCDevice);
+ } else {
+ //
+ // Handle failure cases. Look at it later.
+ //
+ }
+ }
+
+ //
+ // Based on T0 or T1 update Waittime. For T0 use WTWaittime, for T1 use BWT.
+ //
+ if (fpICCDevice->bProtocolNum) {
+ fpICCDevice->WaitTime = fpICCDevice->BWT;
+ } else {
+ fpICCDevice->WaitTime = fpICCDevice->WTwaittime;
+ }
+
+ //
+ // If Automatic ICC Clock Freq AND Automatic Buad Rate selection
+ // isn't supported issue SetDataRateAndClock cmd
+ //
+ if (!(CCIDDescriptor->dwFeatures & (AUTO_BAUD_RATE_SELECTION |AUTO_ICC_CLOCK_FREQ))){
+
+ }
+
+ //
+ // Check if IFSC/IFSD needs to be increased. Default value is 0x20. T1 and TDPU/Char needs this cmd.
+ //
+ if (fpICCDevice->bProtocolNum){
+ switch(CCIDDescriptor->dwFeatures & 0x70000) {
+ case CHARACTER_LEVEL_EXCHANGE:
+ // Both SUZCR90 and O2Micro oz77c6l1 didn't respond to SBlock call below without this delay
+ FixedDelay(10 * 1000); // 10msec delay. No break. Let the flow continue below.
+ case TDPU_LEVEL_EXCHANGE:
+ ResponseLength = 1;
+ SetIFS[0] = (UINT8)CCIDDescriptor->dwMaxIFSD;
+ Status = TxRxT1TDPUChar (fpDevInfo, fpICCDevice, sizeof (SetIFS), SetIFS, IFS_REQUEST, &ResponseLength, ResponseBuffer);
+ // Update the received IFSD
+ if (!EFI_ERROR(Status) && ResponseLength == 1){
+ fpICCDevice->IFSD = ResponseBuffer[0];
+ }
+ break;
+ default:
+ break;
+ }
+ }
+ return Status;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: ConfigureCCID
+//
+// Description: This function powers up, sets the clock/rate etc
+// (configure CCID based on device capability)
+//
+// Input:
+// DEV_INFO *fpDevInfo,
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: VoltageSelection, RateAndProtocolManagement
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ConfigureCCID(
+ DEV_INFO *fpDevInfo,
+ ICC_DEVICE *fpICCDevice
+)
+{
+ EFI_STATUS Status;
+ UINT8 RetryCount = 3;
+
+ //
+ // Power up the device
+ //
+ do {
+ Status = VoltageSelection(fpDevInfo, fpICCDevice);
+ RetryCount--;
+
+ //
+ // check for errors and do try to recover
+ //
+ if(EFI_ERROR(Status) || fpICCDevice->bStatus) {
+ //
+ // If card present but not powered up retry it.
+ // If card not present the exit immediatly
+ //
+ if (fpICCDevice->bStatus == 2) {
+ break;
+ }
+ } else {
+ break;
+ }
+
+ }while (RetryCount);
+
+ //
+ //Configure the data Rate and select the Protocol
+ //
+ if (!EFI_ERROR(Status)){
+ Status = RateAndProtocolManagement (fpDevInfo, fpICCDevice);
+ }
+
+ if (EFI_ERROR(Status)) {
+ fpICCDevice->ConfiguredStatus = CONFIGFAILED;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDIssueBulkTransfer
+//
+// Description: This function executes a bulk transaction on the USB. The
+// transfer may be either DATA_IN or DATA_OUT packets containing
+// data sent from the host to the device or vice-versa. This
+// function wil not return until the request either completes
+// successfully or completes with error (due to time out, etc.)
+// Size of data can be upto 64K
+//
+// Input: - DeviceInfo structure (if available else 0)
+// - Transfer direction
+// Bit 7 : Data direction
+// 0 Host sending data to device
+// 1 Device sending data to host
+// Bit 6-0 : Reserved
+// - Buffer containing data to be sent to the device or
+// buffer to be used to receive data. Value in
+// - Length request parameter, number of bytes of data
+// to be transferred in or out of the host controller
+//
+// Output: Amount of data transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBCCIDIssueBulkTransfer (
+ DEV_INFO* fpDevInfo,
+ UINT8 bXferDir,
+ UINT8* fpCmdBuffer,
+ UINT32 dSize
+)
+{
+ return (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [fpDevInfo->bHCNumber - 1]->bHCType)].pfnHCDBulkTransfer)
+ (gUsbData->HcTable[fpDevInfo->bHCNumber -1],
+ fpDevInfo, bXferDir,
+ fpCmdBuffer, dSize);
+
+ // Handle Bulk Transfer error here
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDIssueControlTransfer
+//
+// Description: Issues Control Pipe request to default pipe
+//
+// Parameters: pDevInfo DeviceInfo structure (if available else 0)
+// wRequest Request type (low byte)
+// Bit 7 : Data direction
+// 0 = Host sending data to device
+// 1 = Device sending data to host
+// Bit 6-5 : Type
+// 00 = Standard USB request
+// 01 = Class specific
+// 10 = Vendor specific
+// 11 = Reserved
+// Bit 4-0 : Recipient
+// 00000 = Device
+// 00001 = Interface
+// 00010 = Endpoint
+// 00100 - 11111 = Reserved
+// Request code, a one byte code describing
+// the actual device request to be executed
+// (ex: 1 : ABORT, 2 : GET_CLOCK_FREQUENCIES, 3: GET_DATA_RATES)
+// wIndex wIndex request parameter (meaning varies)
+// wValue wValue request parameter (meaning varies)
+// fpBuffer Buffer containing data to be sent to the
+// device or buffer to be used to receive data
+// wLength wLength request parameter, number of bytes
+// of data to be transferred in or out
+// of the host controller
+//
+// Output: Number of bytes actually transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBCCIDIssueControlTransfer(
+ DEV_INFO* fpDevInfo,
+ UINT16 wRequest,
+ UINT16 wIndex,
+ UINT16 wValue,
+ UINT8 *fpBuffer,
+ UINT16 wLength
+)
+{
+
+ //
+ // Not tested due to lack of H/W which supports it
+ //
+ return (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [fpDevInfo->bHCNumber - 1]->bHCType)].pfnHCDControlTransfer)
+ (gUsbData->HcTable[fpDevInfo->bHCNumber - 1],
+ fpDevInfo,
+ wRequest,
+ wIndex,
+ wValue,
+ fpBuffer,
+ wLength);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: FindNumberOfTs
+//
+// Description: Returns the # of Ts present in TDx
+//
+// Input:
+// UINT8 Data
+//
+// Output:
+// UINT8 - Returns number of TDx present in ATR data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+FindNumberOfTs(
+ UINT8 Data
+)
+{
+ UINT8 Count = 0;
+ UINT8 Mask = 0x10;
+
+ for ( ;Mask; Mask = Mask << 1){
+ if (Data & Mask) {
+ Count++;
+ }
+ }
+
+ return Count;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintPCParameters
+//
+// Description: This function prints the information gathered from GetPCParameters
+//
+// Input:
+// UINT8 * Data
+//
+// OutPut:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PrintPCParameters(
+ UINT8 * Data
+)
+{
+
+ USB_DEBUG (DEBUG_LEVEL_3, "bProtocolNum : %02X\n", Data[0]);
+ USB_DEBUG (DEBUG_LEVEL_3, "bmFindexDIndex : %02X\n", Data[1]);
+ USB_DEBUG (DEBUG_LEVEL_3, "bmTCCKST0 : %02X\n", Data[2]);
+ USB_DEBUG (DEBUG_LEVEL_3, "bGaurdTime : %02X\n", Data[3]);
+ USB_DEBUG (DEBUG_LEVEL_3, "bWaitingInterger : %02X\n", Data[4]);
+ USB_DEBUG (DEBUG_LEVEL_3, "bClockStop : %02X\n", Data[5]);
+ USB_DEBUG (DEBUG_LEVEL_3, "bIFSC : %02X\n", Data[6]); // Valid only for T1
+ USB_DEBUG (DEBUG_LEVEL_3, "bNadValue : %02X\n", Data[7]); // Valid only for T1
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintTimingInfo
+//
+// Description: This function prints the information gathered from ATR data
+//
+// Input:
+// ICC_DEVICE *fpICCDevice
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PrintTimingInfo(
+ ICC_DEVICE *fpICCDevice
+)
+{
+
+ USB_DEBUG (DEBUG_LEVEL_3, "etu : %02X \n", fpICCDevice->etu);
+ USB_DEBUG (DEBUG_LEVEL_3, "GlobalFi : %04x \n", fpICCDevice->GlobalFi);
+ USB_DEBUG (DEBUG_LEVEL_3, "GlobalFmax : %02X \n", fpICCDevice->GlobalFmax);
+ USB_DEBUG (DEBUG_LEVEL_3, "GlobalDi : %02X \n", fpICCDevice->GlobalDi);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "SpecificMode : %02X \n", fpICCDevice->SpecificMode);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "ClassABC : %02X \n", fpICCDevice->ClassABC);
+ USB_DEBUG (DEBUG_LEVEL_3, "StopClockSupport : %02X \n", fpICCDevice->StopClockSupport);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "ExtraGuardTime : %02X \n", fpICCDevice->ExtraGuardTime);
+ USB_DEBUG (DEBUG_LEVEL_3, "WTwaittime : %08x \n", fpICCDevice->WTwaittime);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "BWI : %02X \n", fpICCDevice->BWI);
+ USB_DEBUG (DEBUG_LEVEL_3, "CWI : %02X \n", fpICCDevice->CWI);
+ USB_DEBUG (DEBUG_LEVEL_3, "IFSC : %02X \n", fpICCDevice->IFSC);
+ USB_DEBUG (DEBUG_LEVEL_3, "NAD : %02X \n", fpICCDevice->NAD);
+ USB_DEBUG (DEBUG_LEVEL_3, "EpilogueFields : %02X \n", fpICCDevice->EpilogueFields);
+ USB_DEBUG (DEBUG_LEVEL_3, "BWT : %02X \n", fpICCDevice->BWT);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintATRData
+//
+// Description: This function Prints the RAW ATR Data
+//
+// Input:
+// UINT8 *ATRData
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PrintATRData(
+ UINT8 *ATRData
+)
+{
+
+ UINT8 TDx = 2;
+ UINT8 i;
+
+
+ USB_DEBUG (DEBUG_LEVEL_3, " ATR Data \n");
+
+ for (i=0; i< 32; i++) {
+ USB_DEBUG (DEBUG_LEVEL_3, "%02X ", ATRData[i]);
+ }
+
+ i = 0;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "\nTS : %02X \n", ATRData[i++]);
+
+ TDx = ATRData[i];
+ USB_DEBUG (DEBUG_LEVEL_3, "T0 : %02X \n", ATRData[i++]);
+ USB_DEBUG (DEBUG_LEVEL_3, "TA1 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB1 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC1 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD1 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ if (!(TDx & 0x80)) return;
+ TDx = ATRData[i-1];
+
+
+ USB_DEBUG (DEBUG_LEVEL_3, "TA2 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB2 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC2 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD2 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ if (!(TDx & 0x80)) return;
+ TDx = ATRData[i-1];
+
+ USB_DEBUG (DEBUG_LEVEL_3, "TA3 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB3 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC3 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD3 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ if (!(TDx & 0x80)) return;
+ TDx = ATRData[i-1];
+
+ USB_DEBUG (DEBUG_LEVEL_3, "TA4 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB4 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC4 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD4 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ if (!(TDx & 0x80)) return;
+ TDx = ATRData[i-1];
+
+ USB_DEBUG (DEBUG_LEVEL_3, "TA5 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB5 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC5 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD5 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ if (!(TDx & 0x80)) return;
+ TDx = ATRData[i-1];
+
+ USB_DEBUG (DEBUG_LEVEL_3, "TA6 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB6 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC6 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD6 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ if (!(TDx & 0x80)) return;
+ TDx = ATRData[i-1];
+
+ USB_DEBUG (DEBUG_LEVEL_3, "TA7 : %02X \n", TDx & 0x10 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TB7 : %02X \n", TDx & 0x20 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TC7 : %02X \n", TDx & 0x40 ? ATRData[i++] : 0);
+ USB_DEBUG (DEBUG_LEVEL_3, "TD7 : %02X \n", TDx & 0x80 ? ATRData[i++] : 0);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: PrintDescriptorInformation
+//
+// Description: Prints SMART class Descriptor data
+//
+// Input:
+// SMARTCLASS_DESC *fpCCIDDesc
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+PrintDescriptorInformation (
+ SMARTCLASS_DESC *fpCCIDDesc
+)
+{
+
+ CHAR8 *Strings[] = {"CHARACTER", "TDPU", "Short ADPU", "Extended ADPU"};
+ UINT8 Exchange = (fpCCIDDesc->dwFeatures & 0x70000) >> 16;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "Sizeof SMART Class Descriptor : %X\n", sizeof (SMARTCLASS_DESC));
+ USB_DEBUG (DEBUG_LEVEL_3, "bDescLength : %04X\n", fpCCIDDesc->bDescLength);
+ USB_DEBUG (DEBUG_LEVEL_3, "bDescType : %04X\n", fpCCIDDesc->bDescType);
+ USB_DEBUG (DEBUG_LEVEL_3, "bcdCCID : %04X\n", fpCCIDDesc->bcdCCID);
+ USB_DEBUG (DEBUG_LEVEL_3, "bMaxSlotIndex : %04X\n", fpCCIDDesc->bMaxSlotIndex);
+ USB_DEBUG (DEBUG_LEVEL_3, "bVoltageSupport : %04X\n", fpCCIDDesc->bVoltageSupport);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwProtocols : %04X\n", fpCCIDDesc->dwProtocols);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwDefaultClock : %04X\n", fpCCIDDesc->dwDefaultClock);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwMaximumClock : %04X\n", fpCCIDDesc->dwMaximumClock);
+ USB_DEBUG (DEBUG_LEVEL_3, "bNumClockSupported : %04X\n", fpCCIDDesc->bNumClockSupported);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwDataRate : %04X\n", fpCCIDDesc->dwDataRate);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwMaxDataRate : %04X\n", fpCCIDDesc->dwMaxDataRate);
+ USB_DEBUG (DEBUG_LEVEL_3, "bNumDataRatesSupported : %04X\n", fpCCIDDesc->bNumDataRatesSupported);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwMaxIFSD : %04X\n", fpCCIDDesc->dwMaxIFSD);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwSynchProtocols : %04X\n", fpCCIDDesc->dwSynchProtocols);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwMechanical : %04X\n", fpCCIDDesc->dwMechanical);
+ USB_DEBUG (DEBUG_LEVEL_3, "dwFeatures : %04X\n", fpCCIDDesc->dwFeatures);
+ USB_DEBUG (DEBUG_LEVEL_3, "bClassGetResponse : %04X\n", fpCCIDDesc->dwMaxCCIDMessageLength);
+ USB_DEBUG (DEBUG_LEVEL_3, "bClassGetResponse : %04X\n", fpCCIDDesc->bClassGetResponse);
+ USB_DEBUG (DEBUG_LEVEL_3, "bClassEnvelope : %04X\n", fpCCIDDesc->bClassEnvelope);
+ USB_DEBUG (DEBUG_LEVEL_3, "wLcdLayout : %04X\n", fpCCIDDesc->wLcdLayout);
+ USB_DEBUG (DEBUG_LEVEL_3, "bPINSupport : %04X\n", fpCCIDDesc->bPINSupport);
+ USB_DEBUG (DEBUG_LEVEL_3, "bMaxCCIDBusySlots : %04X\n", fpCCIDDesc->bMaxCCIDBusySlots);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "*************************************\n");
+ USB_DEBUG (DEBUG_LEVEL_3, " Device is in:");
+ USB_DEBUG (DEBUG_LEVEL_3, "%s Exchange mode\n", Strings[Exchange]);
+ USB_DEBUG (DEBUG_LEVEL_3, "*************************************\n");
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCID_ProcessInterruptData
+//
+// Description: This routine is called when InterruptIN messages is generated
+//
+// Input: pHCStruc Pointer to HCStruc
+// pDevInfo Pointer to device information structure
+// pTD Pointer to the polling TD
+// pBuffer Pointer to the data buffer
+//
+// Output:
+// UEB_ERROR/USB_SUCCESS
+//
+// Notes: When an ICC card is inserted or removed Interrupt message is generated.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBCCID_ProcessInterruptData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+
+ EFI_STATUS Status;
+ UINT8 Data;
+ UINT8 Slot = 0;
+ UINT8 bmSlotICCByte = 0;
+ UINT32 SlotICCStatus = *(UINT32 *)(Buffer + 1);
+ SMARTCLASS_DESC *CCIDDescriptor = (SMARTCLASS_DESC*)DevInfo->pCCIDDescriptor;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+
+ if (((UINT8*)DevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)DevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USBCCID_ProcessInterruptData.... %X %X %X %X\n",
+ *Buffer, *(Buffer +1), *(Buffer + 2), *(Buffer + 3));
+
+
+ switch (*Buffer) {
+
+ //
+ // ICC Card either inserted or Removed
+ //
+ case RDR_TO_PC_NOTIFYSLOTCHANGE:
+
+ //
+ // Find the # of bytes in this notification
+ //
+ Slot = CCIDDescriptor->bMaxSlotIndex + 1; // Make it 1 based
+ bmSlotICCByte = (CCIDDescriptor->bMaxSlotIndex + 1) >> 2;
+
+ if (Slot & 0x3) {
+ bmSlotICCByte++;
+ }
+
+ Slot = 0;
+ do {
+ Data = (SlotICCStatus >> Slot) & 0x3;
+ //
+ // Is there a change in status
+ //
+ if ((Data & 0x3) == 3) {
+ Status = ICCInsertEvent (DevInfo, Slot);
+ }
+ if ((Data & 0x3) == 2) {
+ Status = ICCRemovalEvent (DevInfo, Slot);
+ }
+ Slot++;
+ } while (Slot < (CCIDDescriptor->bMaxSlotIndex + 1));
+
+ break;
+
+ case RDR_TO_PC_HARDWAREERROR:
+
+ USB_DEBUG(DEBUG_LEVEL_3, "RDR To PC Hardware Error Slot %X Sequence %X Error Code %X \n",
+ *Buffer, *(Buffer +1), *(Buffer + 2));
+ break;
+
+ default:
+ break;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ICCRemovalEvent
+//
+// Description: In response to Device removal, Interrupt-in message is received.
+// Icc Device is removed from the linked list.
+//
+// Input:
+// DEV_INFO *fpDevInfo,
+// UINT8 Slot
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ICCRemovalEvent(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+)
+{
+
+ ICC_DEVICE *fpICCDevice;
+
+ fpICCDevice = GetICCDevice(fpDevInfo, Slot);
+
+ if (fpICCDevice) {
+
+ // Don't free up the memory. EFI driver (EfiUsbCCID) makes use of this data area to
+ // find whether ICC has been removed or added.
+ // Before freeing up, clear the bytes
+
+// MemFill((UINT8 *)fpICCDevice, sizeof(ICC_DEVICE), 0);
+
+ //
+ //Free up the memory and remove it from linked list
+ //
+// DListDelete (&(fpDevInfo->ICCDeviceList), &(fpICCDevice->ICCDeviceLink));
+// USB_MemFree(fpICCDevice, (UINT8)GET_MEM_BLK_COUNT(sizeof(ICC_DEVICE)));
+
+ if (fpICCDevice->ConfiguredStatus) {
+ fpICCDevice->ConfiguredStatus = 0;
+ } else {
+ //
+ // Handle if IccRemovalEven is called multiple times
+ //
+ return EFI_SUCCESS;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "ICC device removed - Slot : %X\n", Slot);
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ ICC_SmiQueuePut((void *)fpICCDevice);
+ }
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Removal: fpDevInfo %X fpICCDevice %X\n", fpDevInfo, fpICCDevice);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ICCInsertEvent
+//
+// Description: In response to Device Insertion, Interrupt-in message is received.
+// Icc Device is added to the linked list and configured.
+//
+// Input:
+// DEV_INFO *fpDevInfo,
+// UINT8 Slot
+//
+// Output:
+// EFI_STATUS
+//
+// Notes: ConfigureCCID, GetICCDevice
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+ICCInsertEvent(
+ DEV_INFO *fpDevInfo,
+ UINT8 Slot
+)
+{
+
+ EFI_STATUS Status;
+ ICC_DEVICE *fpICCDevice;
+ BOOLEAN NewDeviceAdded = FALSE;
+
+ //
+ // Check if the device already exist. if so use it.
+ //
+ fpICCDevice = GetICCDevice(fpDevInfo, Slot);
+
+ if (!fpICCDevice) {
+ //
+ // Alocate memory for ICC_DEVICE and attach it to the linked list
+ //
+ fpICCDevice = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(ICC_DEVICE)));
+ ASSERT(fpICCDevice);
+ if (!fpICCDevice) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemFill((UINT8 *)fpICCDevice, sizeof(ICC_DEVICE), 0);
+
+ //
+ // Add to the slot list
+ //
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (fpDevInfo->ICCDeviceList.pHead != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)(fpDevInfo->ICCDeviceList.pHead),
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ if (fpDevInfo->ICCDeviceList.pTail != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)(fpDevInfo->ICCDeviceList.pTail),
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+#endif
+ DListAdd(&(fpDevInfo->ICCDeviceList), &(fpICCDevice->ICCDeviceLink));
+ NewDeviceAdded = TRUE;
+
+ }
+
+#if CCID_USE_INTERRUPT_INSERTION_REMOVAL
+ // Handle Multiple ICCInsertEvent calls. Some cards generate
+ // Interrupt in Interrupt-IN endpoint and some don't.
+ // For card which don't generate the intterupt, CCID API should be used to power up the device.
+ if (fpICCDevice->ConfiguredStatus) {
+
+ if (fpICCDevice->ConfiguredStatus == CONFIGFAILED) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+
+ }
+#endif
+
+ fpICCDevice->ChildHandle = 0;
+ fpICCDevice->Slot = Slot;
+ fpICCDevice->WaitTime = INITWAITTIME;
+
+ Status = ConfigureCCID(fpDevInfo, fpICCDevice);
+
+#if CCID_USE_INTERRUPT_INSERTION_REMOVAL
+ if(EFI_ERROR(Status)){
+
+ //
+ //Free up the memory and remove it from linked list
+ //
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (fpDevInfo->ICCDeviceList.pHead != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)(fpDevInfo->ICCDeviceList.pHead),
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ if (fpDevInfo->ICCDeviceList.pTail != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)(fpDevInfo->ICCDeviceList.pTail),
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+#endif
+ DListDelete (&(fpDevInfo->ICCDeviceList), &(fpICCDevice->ICCDeviceLink));
+ USB_MemFree(fpICCDevice, (UINT8)GET_MEM_BLK_COUNT(sizeof(ICC_DEVICE)));
+
+ } else {
+ USB_DEBUG(DEBUG_LEVEL_3, "ICC device added - Slot : %X\n", Slot);
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ ICC_SmiQueuePut((void *)fpICCDevice);
+ }
+ }
+
+#else
+ //
+ // Even if configuration failed install the protocol in polling mode.
+ //
+ USB_DEBUG(DEBUG_LEVEL_3, "ICC device added - Slot : %X\n", Slot);
+
+ if ((gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) && NewDeviceAdded) {
+ ICC_SmiQueuePut((void *)fpICCDevice);
+ }
+#endif
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Insert : fpDevInfo %X fpICCDevice %X\n", fpDevInfo, fpICCDevice);
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ICC_SmiQueuePut
+//
+// Description: Puts the pointer into the queue for processing.
+// updates queue head and tail. This data is read from EfiUSBCCID.C
+// which installs AMI_CCID_IO_PROTOCOL
+//
+// Input:
+// (void *)fpICCDevice
+//
+// Output:
+// None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ICC_SmiQueuePut(
+ VOID * d
+)
+{
+ QUEUE_T* q = &gUsbData->ICCQueueCnnctDisc;
+
+ while (q->head >= q->maxsize) {
+ q->head -= q->maxsize;
+ }
+
+ q->data[q->head++] = d;
+ if (q->head == q->maxsize) {
+ q->head -= q->maxsize;
+ }
+ if (q->head == q->tail) {
+ //Drop data from queue
+ q->tail++;
+ while (q->tail >= q->maxsize) {
+ q->tail -= q->maxsize;
+ }
+ }
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: DoDevInfoInitialization
+//
+// Description: Do some USB device info data initialization
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// UINT8 *fpDesc
+// UINT16 wStart
+// UINT16 wEnd
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+DoDevInfoInitialization (
+ DEV_INFO *fpDevInfo,
+ UINT8 *fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd
+)
+{
+
+ UINT8 bTemp;
+ ENDP_DESC *fpEndpDesc;
+ INTRF_DESC *fpIntrfDesc;
+ SMARTCLASS_DESC *fpCCIDDesc = NULL;
+
+ fpDevInfo->bDeviceType = BIOS_DEV_TYPE_CCID;
+ fpDevInfo->fpPollTDPtr = 0;
+
+ fpDevInfo->bCallBackIndex = USB_InstallCallBackFunction(USBCCID_ProcessInterruptData);
+
+ //
+ // Initialize the Initlist to hold data for each Slot
+ //
+ DListInit(&(fpDevInfo->ICCDeviceList));
+ fpIntrfDesc = (INTRF_DESC*)(fpDesc + wStart);
+
+ //
+ // Calculate the end of descriptor block
+ //
+ fpDesc+=((CNFG_DESC*)fpDesc)->wTotalLength;
+ fpEndpDesc = (ENDP_DESC*)((char*)fpIntrfDesc + fpIntrfDesc->bDescLength);
+
+ do {
+ if (fpIntrfDesc->bDescType == DESC_TYPE_SMART_CARD) {
+ fpCCIDDesc = (SMARTCLASS_DESC *)fpIntrfDesc;
+ break;
+ }
+ fpIntrfDesc = (INTRF_DESC*) ((UINT8 *)fpIntrfDesc + fpIntrfDesc->bDescLength);
+ }while ((UINT8 *)fpIntrfDesc < fpDesc);
+
+ if (!fpCCIDDesc) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ fpDevInfo->pCCIDDescriptor = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(sizeof(SMARTCLASS_DESC)));
+ ASSERT(fpDevInfo->pCCIDDescriptor);
+ if (!fpDevInfo->pCCIDDescriptor) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ MemCopy((UINT8 *)fpCCIDDesc, (UINT8 *)(fpDevInfo->pCCIDDescriptor), sizeof(SMARTCLASS_DESC));
+ fpCCIDDesc = (SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor;
+
+ if (fpCCIDDesc->bNumDataRatesSupported) {
+
+ fpDevInfo->DataRates = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(
+ fpCCIDDesc->bNumDataRatesSupported * sizeof(UINT32)));
+ ASSERT(fpDevInfo->DataRates);
+ if (!fpDevInfo->DataRates) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Issue GET_DATA_RATES cmd. Should interface number be zero?
+ //
+ USBCCIDIssueControlTransfer(fpDevInfo,
+ CCID_CLASS_SPECIFIC_GET_DATA_RATES,
+ 0x0, 0, (UINT8 *)fpDevInfo->DataRates,
+ fpCCIDDesc->bNumDataRatesSupported * sizeof(UINT32)
+ );
+
+ } else {
+ fpDevInfo->DataRates = 0;
+ }
+
+ if (fpCCIDDesc->bNumClockSupported) {
+
+ fpDevInfo->ClockFrequencies = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(
+ fpCCIDDesc->bNumClockSupported * sizeof(UINT32)));
+ ASSERT(fpDevInfo->ClockFrequencies);
+ if (!fpDevInfo->ClockFrequencies) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ //
+ // Issue GET_CLOCK_FREQUENCIES. Should interface number be zero?
+ //
+ USBCCIDIssueControlTransfer(fpDevInfo,
+ CCID_CLASS_SPECIFIC_GET_CLOCK_FREQUENCIES,
+ 0x0, 0, (UINT8 *)fpDevInfo->DataRates,
+ fpCCIDDesc->bNumClockSupported * sizeof(UINT32));
+ } else {
+ fpDevInfo->ClockFrequencies = 0;
+ }
+
+ PrintDescriptorInformation(fpDevInfo->pCCIDDescriptor);
+
+ bTemp = 0x03; // bit 1 = Bulk In, bit 0 = Bulk Out
+
+ for( ;(fpEndpDesc->bDescType != DESC_TYPE_INTERFACE) && ((UINT8*)fpEndpDesc < fpDesc);
+ fpEndpDesc = (ENDP_DESC*)((UINT8 *)fpEndpDesc + fpEndpDesc->bDescLength)){
+
+ if(!(fpEndpDesc->bDescLength)) {
+ // Br if 0 length desc (should never happen, but...)
+ break;
+ }
+
+ if( fpEndpDesc->bDescType != DESC_TYPE_ENDPOINT ) {
+ continue;
+ }
+
+ if ((fpEndpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) ==
+ EP_DESC_FLAG_TYPE_BULK) { // Bit 1-0: 10 = Endpoint does bulk transfers
+ if(!(fpEndpDesc->bEndpointAddr & EP_DESC_ADDR_DIR_BIT)) {
+ //
+ // Bit 7: Dir. of the endpoint: 1/0 = In/Out
+ // If Bulk-Out endpoint already found then skip subsequent ones
+ // on the interface.
+ //
+ if (bTemp & 1) {
+ fpDevInfo->bBulkOutEndpoint = (UINT8)(fpEndpDesc->bEndpointAddr
+ & EP_DESC_ADDR_EP_NUM);
+ fpDevInfo->wBulkOutMaxPkt = fpEndpDesc->wMaxPacketSize;
+ bTemp &= 0xFE;
+ }
+ } else {
+ //
+ // If Bulk-In endpoint already found then skip subsequent ones
+ // on the interface
+ //
+ if (bTemp & 2) {
+ fpDevInfo->bBulkInEndpoint = (UINT8)(fpEndpDesc->bEndpointAddr
+ & EP_DESC_ADDR_EP_NUM);
+ fpDevInfo->wBulkInMaxPkt = fpEndpDesc->wMaxPacketSize;
+ bTemp &= 0xFD;
+ }
+ }
+ }
+
+ //
+ // Check for and configure Interrupt endpoint if present
+ //
+ if ((fpEndpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) !=
+ EP_DESC_FLAG_TYPE_INT) { // Bit 1-0: 10 = Endpoint does interrupt transfers
+ continue;
+ }
+
+ if (fpEndpDesc->bEndpointAddr & EP_DESC_ADDR_DIR_BIT) {
+ fpDevInfo->IntInEndpoint = fpEndpDesc->bEndpointAddr;
+ fpDevInfo->IntInMaxPkt = fpEndpDesc->wMaxPacketSize;
+ fpDevInfo->bPollInterval = fpEndpDesc->bPollInterval;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: USBCCIDInitialize
+//
+// Description: This function initializes CCID device related data
+//
+// Input:
+// None
+//
+// Output:
+// None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBCCIDInitialize ()
+{
+ USB_InstallCallBackFunction(USBCCID_ProcessInterruptData);
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDCheckForDevice
+//
+// Description: This routine checks for CCID type device from the
+// interface data provided
+//
+// Input:
+// DEV_INFO *fpDevInfo
+// UINT8 bBaseClass
+// UINT8 bSubClass
+// UINT8 bProtocol
+//
+// Output:
+// BIOS_DEV_TYPE_STORAGE type on success or 0FFH on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBCCIDCheckForDevice (
+ DEV_INFO *fpDevInfo,
+ UINT8 bBaseClass,
+ UINT8 bSubClass,
+ UINT8 bProtocol
+)
+{
+
+ if(bBaseClass == BASE_CLASS_CCID_STORAGE && bProtocol == PROTOCOL_CCID) {
+ return BIOS_DEV_TYPE_CCID;
+ }
+
+ return USB_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDConfigureDevice
+//
+// Description: This function checks an interface descriptor of a device
+// to see if it describes a USB CCID device. If the device
+// is a CCID device, then it is configured
+// and initialized.
+//
+// Input:
+// pHCStruc HCStruc pointer
+// pDevInfo Device information structure pointer
+// pDesc Pointer to the descriptor structure
+// wEnd End offset of the device descriptor
+//
+// Output:
+// New device info structure, NULL on error
+//
+// Notes: DoDevInfoInitialization
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBCCIDConfigureDevice (
+ HC_STRUC *fpHCStruc,
+ DEV_INFO *fpDevInfo,
+ UINT8 *fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd
+)
+{
+
+ EFI_STATUS Status;
+ INTRF_DESC *fpIntrfDesc = (INTRF_DESC*)(fpDesc + wStart);
+
+ USB_DEBUG (DEBUG_LEVEL_3, "USBCCIDConfigureDevice ....\n");
+
+ //
+ // Do some house keeping related DEV_INFO structure. No H/W access
+ //
+ Status = DoDevInfoInitialization(fpDevInfo, fpDesc, wStart, wEnd);
+
+ if (EFI_ERROR(Status)) {
+ return NULL;
+ }
+
+#if CCID_USE_INTERRUPT_INSERTION_REMOVAL
+ //
+ // if Interrupt EndPoint is supported
+ //
+ if (fpIntrfDesc->bNumEndpoints == 3) {
+ fpDevInfo->PollingLength = fpDevInfo->IntInMaxPkt;
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDActivatePolling)
+ (fpHCStruc, fpDevInfo);
+ }
+
+#else
+
+ Status = ICCInsertEvent(fpDevInfo, 0);
+
+#endif
+
+ //
+ // Should we support CCID which doesn't support interrupt-IN Message.
+ // Maybe not for now.
+ //
+ return fpDevInfo;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBCCIDDisconnectDevice
+//
+// Description: This function disconnects the CCID device.
+//
+// Input:
+// pDevInfo Device info structure pointer
+//
+// Output:
+// None
+//
+//Notes: Free up all memory allocated to the device.
+// Remove ICC device from the device list.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBCCIDDisconnectDevice (
+ DEV_INFO *fpDevInfo
+)
+{
+
+ ICC_DEVICE *fpICCDevice;
+ DLINK *dlink = fpDevInfo->ICCDeviceList.pHead;
+ HC_STRUC *fpHCStruc = gUsbData->HcTable[fpDevInfo->bHCNumber - 1];
+ SMARTCLASS_DESC *CCIDDescriptor = (SMARTCLASS_DESC*)fpDevInfo->pCCIDDescriptor;
+ UINT8 *MemBlockEnd = gUsbData->fpMemBlockStart + (gUsbData->MemPages << 12);
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (((UINT8*)fpDevInfo->pCCIDDescriptor < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)fpDevInfo->pCCIDDescriptor > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (dlink != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)dlink,
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+ }
+#endif
+
+#if CCID_USE_INTERRUPT_INSERTION_REMOVAL
+ // Stop polling the endpoint
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDDeactivatePolling)(fpHCStruc,fpDevInfo);
+ fpDevInfo->IntInEndpoint = 0;
+
+#endif
+
+ //
+ // Free up all the memory allocated for each ICC device
+ //
+ while (dlink) {
+ fpICCDevice = OUTTER(dlink, ICCDeviceLink, ICC_DEVICE);
+ if (((UINT8*)fpICCDevice < gUsbData->fpMemBlockStart) ||
+ ((UINT8*)((UINTN)fpICCDevice + sizeof(ICC_DEVICE)) > MemBlockEnd)) {
+ return USB_ERROR;
+ }
+ USB_MemFree(fpICCDevice, (UINT8)GET_MEM_BLK_COUNT(sizeof(ICC_DEVICE)));
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (fpDevInfo->ICCDeviceList.pHead != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)(fpDevInfo->ICCDeviceList.pHead),
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+ }
+ if (fpDevInfo->ICCDeviceList.pTail != NULL) {
+ Status = AmiValidateMemoryBuffer((VOID*)(fpDevInfo->ICCDeviceList.pTail),
+ (UINT32)sizeof(DLINK));
+ if (EFI_ERROR(Status)) {
+ return USB_ERROR;
+ }
+ }
+#endif
+ DListDelete (&(fpDevInfo->ICCDeviceList), &(fpICCDevice->ICCDeviceLink));
+ if (!dlink->pNext) break;
+ dlink = dlink->pNext;
+ }
+
+ if (fpDevInfo->DataRates) {
+ USB_MemFree(fpDevInfo->DataRates,
+ (UINT8)GET_MEM_BLK_COUNT(CCIDDescriptor->bNumDataRatesSupported * sizeof(UINT32))
+ );
+ }
+
+ if (fpDevInfo->ClockFrequencies) {
+ USB_MemFree(fpDevInfo->ClockFrequencies,
+ (UINT8)GET_MEM_BLK_COUNT(CCIDDescriptor->bNumClockSupported * sizeof(UINT32))
+ );
+ }
+
+ //
+ // Free up all the memory allocated for CCID Descriptor
+ //
+ USB_MemFree(CCIDDescriptor,
+ (UINT8)GET_MEM_BLK_COUNT(sizeof(SMARTCLASS_DESC))
+ );
+
+ fpDevInfo->pCCIDDescriptor = 0;
+
+ return USB_SUCCESS;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbdef.h b/Core/EM/usb/rt/usbdef.h
new file mode 100644
index 0000000..1367c27
--- /dev/null
+++ b/Core/EM/usb/rt/usbdef.h
@@ -0,0 +1,2221 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/rt/usbdef.h 149 10/16/16 10:15p Wilsonlee $
+//
+// $Revision: 149 $
+//
+// $Date: 10/16/16 10:15p $
+//
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/rt/usbdef.h $
+//
+// 149 10/16/16 10:15p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 148 7/07/16 1:13a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 147 3/02/16 9:44p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 146 11/04/15 9:53p Wilsonlee
+// TAG] EIP241067
+// [Category] Improvement
+// [Description] Add the device descriptor to the DEV_INFO structure.
+// [Files] usb.c, usbdef.h, xhci.c, usbbus.c, AmiUsbController.h
+//
+// 145 9/01/15 10:18p Wilsonlee
+// [TAG] EIP235482
+// [Category] Improvement
+// [Description] Select this alternate setting for multiple TTs hubs.
+// [Files] usbhub.c, usb.c, amiusb.h, usbdef.h
+//
+// 144 7/24/15 4:43a Wilsonlee
+// [TAG] EIP226493
+// [Category] Improvement
+// [Description] Block to process periodic list to prevent that we might
+// send the wrong command sequences to the same device.
+// [Files] usbmass.c, ehci.c, xhci.h, xhci.c, usbdef.h, uhcd.c
+//
+// 143 5/28/15 4:29a Wilsonlee
+// [TAG] EIP219785
+// [Category] Improvement
+// [Description] Suspend usb devices which are connected to Hubs.
+// [Files] usb.c, usbdef.h
+//
+// 142 5/26/15 11:39p Wilsonlee
+// [TAG] EIP219658
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] It is failed at executing ConfigureEndpoint command for
+// DisplayLink devices.
+// [RootCause] The value of Average TRB Length should not be 0.
+// [Solution] Reasonable initial values of Average TRB Length for
+// Control endpoints Control endpoints would be 8B, Interrupt endpoints
+// 1KB, and Bulk and Isoch endpoints 3KB.
+// [Files] xhci.c, usbdef.h
+//
+// 141 4/29/15 11:29p Wilsonlee
+// [TAG] EIP215031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Transcend USB 3.0 HDD is disappeared in the setup menu by
+// cold boot.
+// [RootCause] We only can get SerialNumber string descriptor before
+// setting configuration for this device, otherwise it is failed at
+// getting this descriptor and inquiry command is also failed.
+// [Solution] Retry inquiry command.
+// [Files] usb.c, usbmass.c, efiusbmass.c, usbbus.c, usbdef.h
+//
+// 140 4/27/15 2:26a Wilsonlee
+// [TAG] EIP211855
+// [Category] Improvement
+// [Description] Set the default interface if the device has alternate
+// setting for the interface.
+// [Files] usb.c, usbdef.h
+//
+// 139 4/10/15 3:07a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 138 3/26/15 3:25a Wilsonlee
+// [TAG] EIP210432
+// [Category] Improvement
+// [Description] Change ReportCount to UINT32.
+// [Files] usbdef.h
+//
+// 137 1/22/15 10:21p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 136 12/24/14 9:34p Wilsonlee
+// [TAG] EIP194683
+// [Category] Improvement
+// [Description] Add the flag "USB_INCMPT_HID_BOOT_PROTOCOL_ONLY" of usb
+// bad device table to keep devices use boot protocol.
+// [Files] usbkbd.c, usbms.c, usbhid.c, usbdef.h
+//
+// 135 12/24/14 1:11a Wilsonlee
+// [TAG] EIP192517
+// [Category] Improvement
+// [Description] USB Driver handles 0x100 NumHeads as a valid value.
+// [Files] usbmass.c, usbdef.h, UsbInt13.c, UsbInt13.h, UI13.bin,
+// Bfiusb.equ, Bfiusb.asm
+//
+// 134 12/03/14 9:37p Wilsonlee
+// [TAG] EIP193805
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in USB module.
+// [Files] amiusb.c, uhcd.c, usbrt.mak, usbdef.h, usbsb.c
+//
+// 133 11/24/14 12:50a Wilsonlee
+// [TAG] EIP185972
+// [Category] Improvement
+// [Description] To acquire more bandwidth, a dynamically transfer queue
+// allocation mechanism is required.
+// [Files] ehci.c, usbdef.h
+//
+// 132 9/29/14 11:38p Wilsonlee
+// [TAG] EIP181169
+// [Category] Improvement
+// [Description] Support XHCI 1.1/USB 3.1.
+// [Files] xhci.c, xhci.h, usb.c, usbbus.c, usbdef.h, UsbHc.h
+//
+// 131 9/02/14 3:54a Wilsonlee
+// [TAG] EIP182567
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] POST B4h sometimes stays about 30 sec if using special
+// KB/Ms.
+// [RootCause] It's timeout in getting config or report descriptor
+// commands.
+// [Solution] Set the timeout to 500 ms.
+// [Files] usb.c, usbhid.c, usbdef.h
+//
+// 130 8/20/14 10:04p Wilsonlee
+// [TAG] EIP180089
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] After updated to AMI_USB_07, we get EHCI TIMEOUT for
+// specific mouse.
+// [RootCause] This device may not respond getting string descriptors
+// which describing manufacturer, product and the device's serial number.
+// [Solution] Set the timeout value to 100 ms, the original is 20 secs.
+// [Files] usbbus.c, usbdef.h
+//
+// 129 8/07/14 2:20a Wilsonlee
+// [TAG] EIP176549
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Microstep USB Keyboard issue.
+// [RootCause] The report descriptor of Microstep USB Keyboard (Sonix
+// Technology Co chip) has an error, Modifier keys is bitmap data, but it
+// reports as array data.
+// [Solution] We need to force variable flag for Modifier keys input
+// item.
+// [Files] usbhid.c, usbkbd.c, usbdef.h
+//
+// 128 7/06/14 10:22p Wilsonlee
+// [TAG] EIP176288
+// [Category] Improvement
+// [Description] Change the value of MAX_CONTROL_DATA_SIZE to 0x800.
+// [Files] usbdef.h
+//
+// 127 5/06/14 5:18a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 126 4/30/14 6:15a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 125 4/30/14 5:28a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 124 4/07/14 2:08a Wilsonlee
+// [TAG] EIP156126
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The power Format of UEFI can not be identified when we
+// install OS from USB CD-ROM.
+// [RootCause] The media information is incorrect when we install
+// BlockIoProtocol for usb CD / DVD devices.
+// [Solution] Get the media status before we install BlockIoProtocol.
+// [Files] usbmass.c, usbdef.h, efiusbmass.c
+//
+// 123 2/26/14 1:57a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 122 12/15/13 10:15p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 121 10/19/13 7:09a Ryanchou
+// [TAG] EIP138257
+// [Category] Improvement
+// [Description] Correct USB HID device type.
+// [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c
+//
+// 120 7/26/13 2:42a Ryanchou
+// [TAG] EIP122142
+// [Category] Improvement
+// [Description] Improve periodic schedule mechanism
+// [Files] ehci.c, ehci.h, ohci.c, ohci.h, uhci.c, uhci.h, usbdef.h,
+// amiusbhc.c
+//
+// 119 7/23/13 2:12a Wilsonlee
+// [TAG] EIP127941
+// [Category] Improvement
+// [Description] Replace UI13HDDFunc08 with UI13FDDFunc08 if the media
+// descriptor is a fixed disk.
+// [Files] UsbInt13.h, UsbInt13.c, usbmass.c, usbdef.h, Bfiusb.asm,
+// Bfiusb.equ
+//
+// 118 7/22/13 10:32p Wilsonlee
+// [TAG] EIP125357
+// [Category] Improvement
+// [Description] Check if the port releases to a select host controller.
+// [Files] uhci.c, usb.c, usbhub.c, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 117 7/04/13 5:50a Roberthsu
+// [TAG] EIP127014
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse drifting not smooth
+// [RootCause] Bbecause Efi simple point protocol RelativeMovementX
+// type is INT32.
+// [Solution] Transfer data type to INT32.
+// [Files] usbdef.h,usbhid.c,usbms.c,usbkbd.h
+//
+// 116 6/30/13 11:41p Wilsonlee
+// [TAG] EIP121374
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB flash is not recognized after re-plugged on DOS.
+// [RootCause] Some devices need to wait for that they are being settle.
+// [Solution] Delay for 50 ms allowing port to settle when pluged in
+// devices.
+// [Files] usbhub.c, usbdef.h
+//
+// 115 6/02/13 11:44p Wilsonlee
+// [TAG] EIP123235
+// [Category] Improvement
+// [Description] Stop the usb host controller at ExitBootService if it
+// is an extend card or it doesn't support HW SMI.
+// [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c,
+// uhcd.c
+//
+// 114 4/16/13 6:47a Ryanchou
+// [TAG] EIP118912
+// [Category] Improvement
+// [Description] Add VIA VT6212 EHCI controller support.
+// [Files] ehci.c, uhci.c, usbdef.h, uhcd.c
+//
+// 113 3/19/13 4:02a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 112 3/18/13 4:51a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 111 1/23/13 5:21a Ryanchou
+// [TAG] EIP111280
+// [Category] Improvement
+// [Description] Add USB APIs for external driver.
+// [Files] amiusb.c, amiusb.h, usbdef.h
+//
+// 110 1/22/13 3:10a Wilsonlee
+// [TAG] EIP112938
+// [Category] Improvement
+// [Description] Create a header file for usb mass storage driver.
+// [Files] UsbMass.h, usbmass.c, usbdef.h, amiusb.c, efiusbmass.c
+//
+// 109 1/22/13 2:39a Wilsonlee
+// [TAG] EIP110305
+// [Category] Improvement
+// [Description] Set the device address after we send the first
+// get-device-descriptor command.
+// [Files] usbmass.c, usb.c, usbdef.h, usbbus.c, efiusbmass.c, uhcd.c,
+// usbport.c
+//
+// 108 1/11/13 4:22a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 107 12/21/12 5:03a Ryanchou
+// [TAG] EIP71730
+// [Category] New Feature
+// [Description] Added OHCI handoff support.
+// [Files] usb.sdl, usbport.c, amiusb.c, usbdef.h, UsbPolicy.h, usb.sd,
+// usb.uni
+//
+// 106 11/10/12 6:43a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 105 9/04/12 8:04a Wilsonlee
+// [TAG] EIP99882
+// [Category] New Feature
+// [Description] Add the usb setup item and usbpolicyprotocol to enable
+// or disable the usb mass storage driver.
+// [Files] UsbPolicy.h, usb.uni, usb.sd, usbmass.c, usbdef.h,
+// efiusbmass.c, usbport.c, uhcd.c
+//
+// 104 8/29/12 8:41a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 103 8/13/12 3:26a Roberthsu
+// [TAG] EIP96010
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The KB can not work under bios.
+// [RootCause] Usage count overflow.
+// [Solution] Add usage count check.
+// [Files] usbdef.h,usbhid.c
+//
+// 102 5/04/12 6:46a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 101 5/04/12 5:28a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 100 5/03/12 6:24a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 99 5/03/12 5:10a Ryanchou
+// [TAG] EIP83361
+// [Category] New Feature
+// [Description] Added "USB 2.0 Controller Mode" setup item.
+// [Files] ehci.c, usb.sd, usb.sdl, usb.uni, usbdef.h, UsbPolicy.h,
+// usbport.c
+//
+// 98 5/02/12 8:08a Wilsonlee
+// [TAG] EIP86793
+// [Category] New Feature
+// [Description] Add the SDL token "USB_MASS_EMULATION_FOR_NO_MEDIA" for
+// determine the USB mass storage device emulation type without media.
+// [Files] usbmass.c, usbport.c, uhcd.c, usbdef.h, usbsrc.sdl
+//
+// 97 5/02/12 2:00a Rajeshms
+// [TAG] EIP83117
+// [Category] Improvement
+// [Description] Extend the Support to different smart card Readers and
+// smart Cards.
+// [Files] usbCCID.c, amiusbrtCCID.h, usbdef.h, efiusbccid.c,
+// AmiusbCCID.h~
+//
+// 96 4/03/12 5:52a Roberthsu
+// [TAG] EIP80948
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When insert the touch board, it will block the function
+// of rear USB ports.
+// [RootCause] Report item not enough.
+// [Solution] Create buffer use report length.
+// [Files] usbhid.c,usbdef.h
+//
+// 95 1/14/12 6:41a Wilsonlee
+// [TAG] EIP80382
+// [Category] New Feature
+// [Description] Add the SDL token "USB_MASS_EMULATION_BY_SIZE" for
+// determine the USB mass storage device emulation type by size only.
+// [Files] usbmass.c, usbport.c, uhcd.c, usbdef.h, usbsrc.sdl
+//
+// 94 11/09/11 3:35a Ryanchou
+// [TAG] EIP73692
+// [Category] Improvement
+// [Description] Implement the ownership change mechanism for PCH.
+// [Files] ehci.c, usbdef.h, usbsrc.sdl
+//
+// 93 11/08/11 8:24a Wilsonlee
+// [TAG] EIP74876
+// [Category] New Feature
+// [Description] Add USB API for shutdown single USB controller.
+// [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 92 11/08/11 2:00a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 91 11/05/11 7:37a Wilsonlee
+// [TAG] EIP64781
+// [Category] New Feature
+// [Description] Added SDL token
+// SKIP_CARD_READER_CONNECT_BEEP_IF_NO_MEDIA that skip the connect beep if
+// no media present in USB card reader.
+// [Files] usbport.c, usbmass.c, usb.c, usbdef.h, uhcd.c, usbsrc.sdl
+//
+// 90 10/25/11 3:52a Ryanchou
+// [TAG] EIP70933
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System hangs at checkpoint 0x98 when webcam plugged
+// [RootCause] The webcam return invalid data in configuration
+// descriptor.
+// [Solution] Get the configuration descriptor twice, the first time is
+// to receive the returned configure descriptor to get the total length
+// and the second time is to feed the length to the function again.
+// [Files] usb.c, usbdef.h
+//
+// 89 9/27/11 12:08a Roberthsu
+// [TAG] EIP65344
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Razer mouse will hang in post
+// [RootCause] Razer has report keyboard interface.But not report led
+// usage.
+// [Solution] Check if not report led usage page.Do not send led
+// command.
+// [Files] syskbc.c,usbhid.c,usbdef.h
+//
+// 88 9/19/11 9:28a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 87 8/08/11 7:02a Ryanchou
+// [TAG] EIP54018
+// [Category] New Feature
+// [Description] Added USB S5 wake up support.
+// [Files] amiusb.c, ehci.c, ohci.c, uhci.c, usb.c, usb.sdl, usbdef.h,
+// usbsb.c xhci.c
+//
+// 86 8/08/11 5:25a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 85 7/19/11 5:22a Ryanchou
+// [TAG] EIP64498
+// [Category] New Feature
+// [Description] Implement EHCI key repeat function.
+// [Files] ehci.c, ehci.h, usb.c, usbdef.h
+//
+// 84 7/15/11 6:30a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 83 7/13/11 2:50a Ryanchou
+// [TAG] EIP60460
+// [Category] Improvement
+// [Description] Adds a flag when device disconnected during data
+// transfer, BIOS will not issue a transfer to the devicce if this flag is
+// set. This change is for Fresco USB 3.0 controller.
+// [Files] usb.c, usbdef.h, xhci.c, xhci.h
+//
+// 82 7/12/11 8:16a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 81 6/22/11 1:46a Ryanchou
+// [TAG] EIP59738
+// [Category] Improvement
+// [Description] Support Block size other than 512 bytes USB HDD in UEFI
+// mode.
+// [Files] efiusbmass.c, uhci.c, usb.c, usbdef.h, usbmass.c
+//
+// 80 5/03/11 10:13a Ryanchou
+// [TAG] EIP54283
+// [Category] Improvement
+// [Description] Follow XHCI spec ver 1.0 section 4.6.8 to recovery
+// endpoint halt.
+// [Files] ehci.c, ohci.c, uhci.c, usbdef.h, usbmass.c, xhci.c
+//
+// 79 4/06/11 1:34a Ryanchou
+// [TAG] EIP54782
+// [Category] Improvement
+// [Description] Change polling data size of HID devices to max packet
+// size of interrupt endpoint.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, xhci.c
+//
+// 78 4/06/11 12:50a Ryanchou
+// [TAG] EIP51653
+// [Category] New Feature
+// [Description] Added an interface that skips specific port
+// enumeration.
+// [Files] AmiUsbController.h, uhcd.c, uhcd.h, usb.c, usbdef.h,
+// usbport.c
+//
+// 77 3/29/11 10:55p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 76 3/29/11 10:19a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 75 11/11/10 11:38p Ryanchou
+// [TAG] EIP45578
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB 3.0 device can't be detected.
+// [RootCause] Address Device Command fails.
+// [Solution] Reset the device and attempt the Address Device Command
+// again.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c, xhci.c
+//
+// 74 10/22/10 8:59a Ryanchou
+// EIP46693: Clear xHCI BIOS owned semaphore bit and SMI enable bit in
+// PreInitXhci.
+//
+// 73 10/20/10 10:26a Ryanchou
+// EIP44702: Added USB 3.0 hub support.
+//
+// 72 10/12/10 2:11a Rameshr
+// [TAG]- EIP 44585
+// [Category]-IMPROVEMENT
+// [Description]- Number of maximum supported USB Mass Storage device
+// increased from 8 to 16.
+// [Files]- Uin13.bin, UsbPort.c, UsbInt13.h, Usb.c, Usbdef.h, Uasbmass.c,
+// Usb.sd, usb.uni, UsbSetup.c, UsbSrc.sdl, UsbPolicy.h
+//
+// 71 9/16/10 12:49p Olegi
+// Added USB_FLAG_EFIMS_DIRECT_ACCESS flag definition.
+//
+// 70 9/07/10 4:42a Tonylo
+// Remove user tags for coding standard.
+//
+// 69 7/15/10 4:43a Tonylo
+// EIP15489 - Add USB HandOff function for shurdown/init USB legacy
+// through USB API function.
+//
+// 68 7/13/10 7:13a Ryanchou
+// EIP38356: Implement shutdown USB legacy support in ACPI enable call.
+//
+// 67 6/22/10 9:10p Olegi
+// EIP39708: Added new incompatibility type for HIDs that ignore boot
+// protocol.
+//
+// 66 6/17/10 10:34a Olegi
+// EIP39326: Runtime data moved to runtime memory region.
+//
+// 65 5/30/10 10:24p Tonylo
+// Name tags clean up for coding standard.
+//
+// 64 5/11/10 9:33a Olegi
+// Corrected the mouse data report. EIP37798
+//
+// 63 4/19/10 1:52p Olegi
+//
+// 62 3/11/10 9:49a Olegi
+//
+// 61 3/11/10 9:21a Olegi
+//
+// 60 2/27/10 12:00p Olegi
+//
+// 59 2/26/10 4:08p Olegi
+//
+// 58 2/08/10 10:05a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 57 1/19/10 12:00p Olegi
+//
+// 56 12/23/09 11:59a Olegi
+//
+// 55 11/24/09 11:36a Olegi
+// EIP#29733 - BIOS adds an USB API (Block KBC Access)
+//
+// 54 11/13/09 9:14a Olegi
+//
+// 53 11/04/09 12:46p Olegi
+//
+// 52 11/04/09 11:10a Olegi
+// Increased KBC character buffer. (EIP29345)
+//
+// 51 10/30/09 5:48p Olegi
+//
+// 50 10/09/09 5:57p Olegi
+//
+// 49 10/02/09 10:50a Olegi
+// Code cleanup.
+//
+// 48 9/15/09 12:21p Olegi
+// Added KEY_REPEAT_LOGIC functionality. EIP#25841
+//
+// 47 8/26/09 11:44a Olegi
+// Changes that prevent collision of keyboard activity and mass storage
+// access. EIP#22808
+//
+// 46 5/22/09 1:49p Olegi
+// Added the definition of USB_INCMPT_BUILT_IN_HUB.
+//
+// 45 5/21/09 5:17p Olegi
+// Added HDD hotplug support definitions.
+//
+// 44 2/20/09 2:32p Olegi
+// Added USB_SAFE_DISABLE_INTERRUPT, EIP#19525
+//
+// 43 2/18/09 3:45p Olegi
+// Added a feature that allows to skip mass storage device installation
+// depending on physical media presence. EIP#19260.
+//
+// 42 2/17/09 8:44a Olegi
+// Modified the value of DESC_TYPE_CLASS_HUB.
+//
+// 38 9/05/08 4:11p Olegi
+// fpCallbackNotifyX were removed from global data area.
+//
+// 33 5/16/08 12:03p Olegi
+// Compliance with AMI coding standard.
+//
+// 32 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 30 9/26/07 9:27a Olegi
+// Added USB_FORCE_64BIT_ALIGNMENT flag.
+//
+// 28 9/06/07 6:08p Olegi
+// USB_FLAG_DRIVER_CONSISTENT flag added.
+//
+// 27 7/09/07 2:12p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 19 10/12/06 9:09p Andriyn
+// Fix: unexpected plug-off lead to endless timeout
+//
+// 17 4/14/06 6:42p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 16 3/20/06 3:38p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 14 3/06/06 6:28p Olegi
+// Lun devices support modifications: supported using the index in
+// DEV_INFO table, not through dedicated massLun table.
+//
+// 13 3/01/06 3:54p Olegi
+// Added definition of USB_FLAG_RUNNING_UNDER_OS flag.
+//
+// 7 8/04/05 5:59p Andriyn
+// Legacy over LegacyFree
+//
+// 6 6/03/05 6:31p Andriyn
+// Device path added to HC_STRUC for the need of Aptio framework
+//
+// 5 5/20/05 12:10p Andriyn
+// HC driver to support both protocols
+//
+// 4 5/20/05 11:05a Andriyn
+// reconcile Aptio changes with Alaska
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbDef.h
+//
+// Description: AMI USB driver definitions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+// AVOID including multiple instance of this file
+#ifndef __USB_H
+#define __USB_H
+
+typedef struct _EFI_PCI_IO_PROTOCOL EFI_PCI_IO_PROTOCOL;
+
+#include "efi.h"
+
+#include "Protocol\UsbHC.h"
+#include <Protocol/AmiUsbController.h>
+#include "token.h"
+
+#include "uhci.h"
+#include "ohci.h"
+#include "ehci.h"
+#include "xhci.h"
+
+#include <Protocol\DevicePath.h>
+#include <Protocol\UsbPolicy.h>
+#include <AmiDxeLib.h>
+#include "AmiusbrtCCID.h"
+
+//
+// USB Module version number
+//
+#define USB_MAJOR_VER USB_DRIVER_MAJOR_VER
+#define USB_MINOR_VER USB_DRIVER_MINOR_VER
+#define USB_BUG_RELEASE_VER USB_DRIVER_BUILD_VER
+#define USB_ACTIVE 0xFC
+#define USB_LEGACY_ENABLE 0x01
+#define USB_6064_ENABLE 0x02
+
+#define MAX_DEVICE_TYPES 0x07 // 7 different types of devices
+#define MAX_HC_TYPES 0x04 // 4 different types of host controllers
+#define MAX_MASS_DEVICES 0x06
+#define MAX_CCID_DEVICES 0x06
+
+#define BIOS_DEV_TYPE_HID 0x01
+//#define BIOS_DEV_TYPE_KEYBOARD 0x01
+//#define BIOS_DEV_TYPE_MOUSE 0x02
+#define BIOS_DEV_TYPE_HUB 0x03
+#define BIOS_DEV_TYPE_STORAGE 0x04
+#define BIOS_DEV_TYPE_SECURITY 0x05
+#define BIOS_DEV_TYPE_USBBUS 0x06 // Generic USB device driver
+#define BIOS_DEV_TYPE_USBBUS_SHADOW 0x07 // Dummy device type for temp usage
+#define BIOS_DEV_TYPE_CCID 0x08 // CCID device type
+
+#define HID_DEV_TYPE_KEYBOARD BIT0
+#define HID_DEV_TYPE_MOUSE BIT1
+#define HID_DEV_TYPE_POINT BIT2
+
+#define MAX_DEVICES (USB_DEV_HID_COUNT+USB_DEV_MASS_COUNT+USB_DEV_HUB_COUNT+USB_DEV_CCID_COUNT+USB_DEV_UNSUPPORTED)
+
+
+// USB HC type
+#define USB_HC_UHCI 0x10
+#define USB_HC_OHCI 0x20
+#define USB_HC_EHCI 0x30
+#define USB_HC_XHCI 0x40
+#define GET_HCD_INDEX(bHCType) (((bHCType) - USB_HC_UHCI) >> 4)
+#define USB_INDEX_UHCI (GET_HCD_INDEX(USB_HC_UHCI))
+#define USB_INDEX_OHCI (GET_HCD_INDEX(USB_HC_OHCI))
+#define USB_INDEX_EHCI (GET_HCD_INDEX(USB_HC_EHCI))
+#define USB_INDEX_XHCI (GET_HCD_INDEX(USB_HC_XHCI))
+
+#define USB_MEM_BLK_SIZE 32 // 32 bytes
+#define USB_MEM_BLK_SIZE_SHIFT 5 // log2 (USB_MEM_BLK_SIZE)
+
+#define USB_FORCE_64BIT_ALIGNMENT 1
+
+#if USB_FORCE_64BIT_ALIGNMENT
+#define USB_MEM_ALLOCATION_UNIT_SIZE 64
+#else
+#define USB_MEM_ALLOCATION_UNIT_SIZE 32
+#endif
+
+// The following macro returns number of memory blocks needed for the structure provided
+#define GET_MEM_BLK_COUNT_STRUC(Struc) ((sizeof(Struc)+(sizeof(MEM_BLK)-1))/sizeof(MEM_BLK))
+
+// The following macro returns number of memory blocks needed for the size of data provided
+#define GET_MEM_BLK_COUNT(Size) (((Size) + (sizeof(MEM_BLK)-1))/sizeof(MEM_BLK))
+
+#define MAX_SPLIT_PERIODIC_NUMBER 0x07
+//#define TEMP_BUFFER_SIZE 0x80 // Size of temp buffer
+//#define CONTROL_DATA_SIZE 0x100
+#define MAX_CONTROL_DATA_SIZE 0x800
+#define MAX_TEMP_BUFFER_SIZE 0x80 // Size of temp buffer
+#define MAX_CONSUME_BUFFER_SIZE 0x1000 //(EIP59738+)
+// USB state flag equates
+#define USB_FLAG_ENABLE_BEEP_MESSAGE 0x0001 // BIT 0
+#define USB_FLAG_RUNNING_UNDER_EFI 0x0002 // BIT 1
+#define USB_FLAG_DISABLE_LEGACY_SUPPORT 0x0004 // BIT 2
+#define USB_FLAG_6064EMULATION_ON 0x0008 // BIT 3
+#define USB_FLAG_RUNNING_UNDER_OS 0x0010 // BIT 4
+#define USB_FLAG_DRIVER_CONSISTENT 0x0020 // BIT 5 //AMI Tracker 27603
+#define USB_FLAG_DRIVER_STARTED 0x0080 // BIT 7
+#define USB_FLAG_6064EMULATION_IRQ_SUPPORT 0x0100 // BIT 8
+#define USB_HOTPLUG_FDD_ENABLED 0x0200 // BIT 9
+#define USB_HOTPLUG_HDD_ENABLED 0x0400 // BIT 10
+#define USB_HOTPLUG_CDROM_ENABLED 0x0800 // BIT 11
+#define USB_FLAG_MASS_NATIVE_EMULATION 0x1000 // BIT 12
+#define USB_FLAG_MASS_MEDIA_CHECK 0x2000 // BIT 13
+#define USB_FLAG_MASS_SKIP_FDD_MEDIA_CHECK 0x4000 // BIT 14
+#define USB_FLAG_EFIMS_DIRECT_ACCESS 0x8000 // BIT15
+#define USB_FLAG_SKIP_CARD_READER_CONNECT_BEEP 0x10000 //BIT16 //(EIP64781+)
+#define USB_FLAG_MASS_SIZE_EMULATION 0x20000 //BIT17 //(EIP80382+)
+#define USB_FLAG_MASS_EMULATION_FOR_NO_MEDIA 0x40000 //BIT18 //(EIP86793+)
+
+// PCI related equates
+ // Invalid PCI register address bits
+#define PCI_REG_MAX_ADDRESS 0xFF00
+#define PCI_REG_ADDRESS_BYTE PCI_REG_MAX_ADDRESS + 0x000
+#define PCI_REG_ADDRESS_WORD PCI_REG_MAX_ADDRESS + 0x001
+#define PCI_REG_ADDRESS_DWORD PCI_REG_MAX_ADDRESS + 0x003
+
+// For systems with config mechanism 1
+#define CFG_SPACE_INDEX_REG 0xCF8
+#define CFG_SPACE_DATA_REG 0xCFC
+
+// Standard PCI configuration register offsets and relevant values
+//------------------------------------------------------------------------------
+#define PCI_REG_VENDID 0x00 //PCI vendor ID register
+#define PCI_REG_DEVID 0x02 //PCI device ID register
+#define PCI_REG_COMMAND 0x04 //PCI command register
+
+//----------------------------------------------------------------------------
+// USB API equates
+//----------------------------------------------------------------------------
+#define USB_NEW_API_START_FUNC 0x20
+
+#define USB_API_CHECK_PRESENCE 0x00
+#define USB_API_START 0x20
+#define USB_API_STOP 0x21
+#define USB_API_DISABLE_INTERRUPTS 0x22
+#define USB_API_ENABLE_INTERRUPTS 0x23
+#define USB_API_MOVE_DATA_AREA 0x24
+#define USB_API_GET_DEVICE_INFO 0x25
+#define USB_API_CHECK_DEVICE_PRESENCE 0x26
+#define USB_API_MASS_DEVICE_REQUEST 0x27
+#define USB_API_POWER_MANAGEMENT 0x28
+#define USB_API_PREPARE_FOR_OS 0x29
+#define USB_API_SECURITY_INTERFACE 0x2A
+#define USB_API_LIGHTEN_KEYBOARD_LEDS 0x2B
+#define USB_API_CHANGE_OWNER 0x2C
+#define USB_API_HC_PROC 0x2D
+#define USB_API_CORE_PROC 0x2E
+#define USB_API_KBC_ACCESS_CONTROL 0x30 //(EIP29733+)
+#define USB_API_LEGACY_CONTROL 0x31 //
+#define USB_API_GET_DEV_ADDR 0x32
+#define USB_API_EXT_DRIVER_REQUEST 0x33
+#define USB_API_CCID_DEVICE_REQUEST 0x34
+#define USB_API_USB_STOP_CONTROLLER 0x35 //(EIP74876+)
+#define USB_API_HC_START_STOP 0x36
+
+#define USB_MASSAPI_GET_DEVICE_INFO 0x000
+#define USB_MASSAPI_GET_DEVICE_GEOMETRY 0x001
+#define USB_MASSAPI_RESET_DEVICE 0x002
+#define USB_MASSAPI_READ_DEVICE 0x003
+#define USB_MASSAPI_WRITE_DEVICE 0x004
+#define USB_MASSAPI_VERIFY_DEVICE 0x005
+#define USB_MASSAPI_FORMAT_DEVICE 0x006
+#define USB_MASSAPI_CMD_PASS_THRU 0x007
+#define USB_MASSAPI_ASSIGN_DRIVE_NUMBER 0x008
+#define USB_MASSAPI_CHECK_DEVICE 0x009
+#define USB_MASSAPI_GET_MEDIA_STATUS 0x00A
+#define USB_MASSAPI_GET_DEV_PARMS 0x00B
+
+#define USB_MASS_MEDIA_PRESENT BIT0
+#define USB_MASS_MEDIA_CHANGED BIT1
+#define USB_MASS_GET_MEDIA_FORMAT BIT2 //(EIP13457+)
+#define USB_MASS_MEDIA_REMOVEABLE BIT3
+
+#define USB_SECURITY_API_READ_DEVICE 0x000
+#define USB_SECURITY_API_WRITE_DEVICE 0x001
+
+#define USB_PM_SUSPEND 0x010
+#define USB_PM_RESUME 0x020
+
+// Error returned from API handler
+#define USB_SUCCESS 0x000
+#define USB_PARAMETER_ERROR 0x010
+#define USB_NOT_SUPPORTED 0x020
+#define USBAPI_INVALID_FUNCTION 0x0F0
+#define USB_ERROR 0x0FF
+
+//
+// Bit definitions for a generic pointer
+//
+#define TERMINATE 0x00000001
+#define QUEUE_HEAD 0x00000002
+#define VERTICAL_FLAG 0x00000004
+#define LINK_POINTER 0xFFFFFFF0
+// Mass storage data sync equates
+#define USB_BULK_IN_DATA_SYNC BIT0
+#define USB_BULK_IN_DATA_SYNC_SHIFT 0
+#define USB_BULK_OUT_DATA_SYNC BIT1
+#define USB_BULK_OUT_DATA_SYNC_SHIFT 1
+#define USB_INT_DATA_SYNC BIT2
+#define USB_INT_DATA_SYNC_SHIFT 2
+
+// Highest possible device address
+#define MAX_DEVICE_ADDR MAX_DEVICES
+// Addr that is guaranted not to be used
+#define DUMMY_DEVICE_ADDR (MAX_DEVICE_ADDR + 1)
+
+#define DEFAULT_PACKET_LENGTH 8 // Max size of packet data
+
+// USB BIOS related error codes
+#define USB_ERROR_CODE_START 0x8100
+#define ERRUSB_HC_NOT_FOUND (USB_ERROR_CODE_START + 1)
+#define ERRUSB_DEVICE_INIT (USB_ERROR_CODE_START + 2)
+#define ERRUSB_DEVICE_DISABLED (USB_ERROR_CODE_START + 3)
+#define ERRUSB_OHCI_EMUL_NOT_SUPPORTED (USB_ERROR_CODE_START + 4)
+#define ERRUSB_EHCI_64BIT_DATA_STRUC (USB_ERROR_CODE_START + 5)
+
+// USB internal error codes
+#define USB_ERR_DEV_INIT_MEM_ALLOC 0x01
+#define USB_ERR_DEV_INIT_GET_DESC_8 0x02
+#define USB_ERR_DEV_INIT_SET_ADDR 0x03
+#define USB_ERR_DEV_INIT_GET_DESC_100 0x04
+#define USB_ERR_DEV_INIT_GET_DESC_200 0x05
+#define USB_ERR_NO_DRIVER 0x20
+#define USB_ERR_NO_HCSTRUC 0x21
+#define USB_ERR_STARTHC_NO_MEMORY 0x22
+#define USB_ERR_KBCONNECT_FAILED 0x23
+#define USB_ERR_HC_RESET_FAILED 0x24
+#define USB_ERR_PORT_RESET_FAILED 0x25
+#define USB_ERR_CONTROL_XFER_TIMEOUT 0x80
+//----------------------------------------------------------------------------
+// Descriptor Type Values
+//---------------------------------------------------------------------------
+#define DESC_TYPE_DEVICE 1 // Device Descriptor (Type 1)
+#define DESC_TYPE_CONFIG 2 // Configuration Descriptor (Type 2)
+#define DESC_TYPE_STRING 3 // String Descriptor (Type 3)
+#define DESC_TYPE_INTERFACE 4 // Interface Descriptor (Type 4)
+#define DESC_TYPE_ENDPOINT 5 // Endpoint Descriptor (Type 5)
+ //(EIP38434+)>
+#define DESC_TYPE_REPORT 0x22 // Report Descriptor (Type 22h)
+#define DESC_TYPE_HID 0x21 // HID Descriptor (Type 21h)
+ //<(EIP38434+)
+#define DESC_TYPE_HUB 0x29 // Hub Descriptor (Type 29h)
+#define DESC_TYPE_SS_HUB 0x2A
+
+#define DESC_TYPE_SS_EP_COMP 48 //SuperSpeed Endpoint Companion Decsriptor
+
+#define DESC_TYPE_CLASS_HUB 0x2900 // Hub Class Descriptor (Type 0)
+
+
+//----------------------------------------------------------------------------
+// Usb device requests timeout
+//---------------------------------------------------------------------------
+
+#ifndef USB_GET_CONFIG_DESC_TIMEOUT_MS
+#define USB_GET_CONFIG_DESC_TIMEOUT_MS 500
+#endif
+
+#ifndef USB_GET_STRING_DESC_TIMEOUT_MS
+#define USB_GET_STRING_DESC_TIMEOUT_MS 100
+#endif
+
+#ifndef USB_GET_SERIAL_NUMBER_DESC_TIMEOUT_MS
+#define USB_GET_SERIAL_NUMBER_DESC_TIMEOUT_MS 3000
+#endif
+
+#ifndef USB_GET_REPORT_DESC_TIMEOUT_MS
+#define USB_GET_REPORT_DESC_TIMEOUT_MS 500
+#endif
+
+#ifndef USB_SUSPEND_HUB_PORT_TIMEOUT_MS
+#define USB_SUSPEND_HUB_PORT_TIMEOUT_MS 200
+#endif
+
+//----------------------------------------------------------------------------
+// USB protocol related routines
+//----------------------------------------------------------------------------
+
+#define MAX_USB_ERROR_RETRY 01
+
+// USB Version structure
+typedef struct {
+ UINT8 bMajor;
+ UINT8 bMinor;
+ UINT8 bBugRel;
+} USB_VERSION;
+
+typedef struct {
+ UINT8 aBuf[32];
+} MEM_BLK;
+
+#define MEM_BLK_COUNT (MEM_PAGE_COUNT * (4096 / USB_MEM_BLK_SIZE))
+#define MEM_BLK_STS_COUNT (MEM_BLK_COUNT / 32)
+
+
+typedef struct {
+ UINT16 wPCIDev;
+ UINT16 wHCType;
+} HC_PCI_INFO;
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT16 wTotalLength;
+ UINT8 bNumInterfaces;
+ UINT8 bConfigValue;
+ UINT8 bConfigString;
+ UINT8 bConfigFlags;
+ UINT8 bConfigPower;
+} CNFG_DESC;
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT8 bInterfaceNum;
+ UINT8 bAltSettingNum;
+ UINT8 bNumEndpoints;
+ UINT8 bBaseClass;
+ UINT8 bSubClass;
+ UINT8 bProtocol;
+ UINT8 bInterfaceString;
+}INTRF_DESC;
+
+typedef struct {
+ UINT8 DescLength;
+ UINT8 DescType;
+ UINT8 MaxBurst;
+ UINT8 Attributes;
+ UINT16 BytesPerInterval;
+} SS_ENDP_COMP_DESC;
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT8 bEndpointAddr;
+ UINT8 bEndpointFlags;
+ UINT16 wMaxPacketSize;
+ UINT8 bPollInterval;
+} ENDP_DESC;
+
+ //(EIP38434+)>
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT16 bcdHID;
+ UINT8 bCountryCode;
+ UINT8 bNumEndpoints;
+ UINT8 bDescriptorType;
+ UINT16 bDescriptorLength;
+} HID_DESC;
+
+#pragma pack(pop)
+
+//----------------------------------------------------------------------------
+// Report descriptor struct define
+//----------------------------------------------------------------------------
+#define HID_REPORT_FIELD_FLAG_CONSTANT BIT0 //0:DATA 1:CONSTANT
+#define HID_REPORT_FIELD_FLAG_VARIABLE BIT1 //0:ARRAY 1:VARIABLE
+#define HID_REPORT_FIELD_FLAG_RELATIVE BIT2 //0:ABSOLUTE 1:RELATIVE
+#define HID_REPORT_FIELD_FLAG_INPUT BIT4 //0:OUTPUT 1:INPUT
+
+#define HID_BTYPE_KEYBOARD 0x1
+#define HID_BTYPE_MOUSE 0x2
+#define HID_BTYPE_POINT 0X3
+
+#define HID_REPORT_FLAG_REPORT_PROTOCOL BIT0 //If use report protocol
+#define HID_REPORT_FLAG_REPORT_ID BIT1 //1:REPORT_ID EXIST
+#define HID_REPORT_FLAG_TOUCH_BUTTON_FLAG BIT2
+#define HID_REPORT_FLAG_LED_FLAG BIT3 //1:LED //EIP65344
+#define HID_REPORT_FLAG_RELATIVE_DATA BIT4
+#define HID_REPORT_FLAG_ABSOLUTE_DATA BIT5
+
+//----------------------------------------------------------------------------
+// Report descriptor's hid_item
+//----------------------------------------------------------------------------
+typedef struct {
+ UINT8 bSize;
+ UINT8 bType;
+ UINT8 bTag;
+ union {
+ UINT8 u8;
+ UINT16 u16;
+ UINT32 u32;
+ } data;
+} HID_ITEM;
+
+
+//----------------------------------------------------------------------------
+// HID Report define start
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// HID report item format
+//----------------------------------------------------------------------------
+#define HID_ITEM_FORMAT_SHORT 0
+#define HID_ITEM_FORMAT_LONG 1
+
+//----------------------------------------------------------------------------
+// HID report descriptor item type (prefix bit 2,3)
+//----------------------------------------------------------------------------
+#define HID_ITEM_TYPE_MAIN 0
+#define HID_ITEM_TYPE_GLOBAL 1
+#define HID_ITEM_TYPE_LOCAL 2
+#define HID_ITEM_TYPE_RESERVED 3
+
+//----------------------------------------------------------------------------
+// HID report descriptor main item tags
+//----------------------------------------------------------------------------
+#define HID_MAIN_ITEM_TAG_INPUT 8
+#define HID_MAIN_ITEM_TAG_OUTPUT 9
+#define HID_MAIN_ITEM_TAG_FEATURE 0xb
+#define HID_MAIN_ITEM_TAG_BEGIN_COLLECTION 0xa
+#define HID_MAIN_ITEM_TAG_END_COLLECTION 0xc
+
+//----------------------------------------------------------------------------
+// HID report descriptor main item contents
+//----------------------------------------------------------------------------
+#define HID_MAIN_ITEM_CONSTANT 0x001
+#define HID_MAIN_ITEM_VARIABLE 0x002
+#define HID_MAIN_ITEM_RELATIVE 0x004
+#define HID_MAIN_ITEM_WRAP 0x008
+#define HID_MAIN_ITEM_NONLINEAR 0x010
+#define HID_MAIN_ITEM_NO_PREFERRED 0x020
+#define HID_MAIN_ITEM_NULL_STATE 0x040
+#define HID_MAIN_ITEM_VOLATILE 0x080
+#define HID_MAIN_ITEM_BUFFERED_BYTE 0x100
+
+//----------------------------------------------------------------------------
+// HID report descriptor collection item types
+//----------------------------------------------------------------------------
+#define HID_COLLECTION_PHYSICAL 0
+#define HID_COLLECTION_APPLICATION 1
+#define HID_COLLECTION_LOGICAL 2
+
+//----------------------------------------------------------------------------
+// HID report descriptor global item tags
+//----------------------------------------------------------------------------
+#define HID_GLOBAL_ITEM_TAG_USAGE_PAGE 0
+#define HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM 1
+#define HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM 2
+#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM 3
+#define HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM 4
+#define HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT 5
+#define HID_GLOBAL_ITEM_TAG_UNIT 6
+#define HID_GLOBAL_ITEM_TAG_REPORT_SIZE 7
+#define HID_GLOBAL_ITEM_TAG_REPORT_ID 8
+#define HID_GLOBAL_ITEM_TAG_REPORT_COUNT 9
+#define HID_GLOBAL_ITEM_TAG_PUSH 0x0a
+#define HID_GLOBAL_ITEM_TAG_POP 0x0b
+
+//----------------------------------------------------------------------------
+// HID report descriptor local item tags
+//----------------------------------------------------------------------------
+#define HID_LOCAL_ITEM_TAG_USAGE 0
+#define HID_LOCAL_ITEM_TAG_USAGE_MINIMUM 1
+#define HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM 2
+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_INDEX 3
+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MINIMUM 4
+#define HID_LOCAL_ITEM_TAG_DESIGNATOR_MAXIMUM 5
+#define HID_LOCAL_ITEM_TAG_STRING_INDEX 7
+#define HID_LOCAL_ITEM_TAG_STRING_MINIMUM 8
+#define HID_LOCAL_ITEM_TAG_STRING_MAXIMUM 9
+#define HID_LOCAL_ITEM_TAG_DELIMITER 0x0a
+
+
+//----------------------------------------------------------------------------
+// HID usage pages
+//----------------------------------------------------------------------------
+#define HID_UP_GENDESK 0x01
+#define HID_UP_KEYBOARD 0x07
+#define HID_UP_BUTTON 0x08
+
+#define HID_UP_KEYBOARD_LEFT_CTRL 0xE0
+#define HID_UP_KEYBOARD_LEFT_SHIFT 0xE1
+#define HID_UP_KEYBOARD_LEFT_ALT 0xE2
+#define HID_UP_KEYBOARD_LEFT _GUI 0xE3
+#define HID_UP_KEYBOARD_RIGHT_CTRL 0xE4
+#define HID_UP_KEYBOARD_RIGHT_SHIFT 0xE5
+#define HID_UP_KEYBOARD_RIGHT_ALT 0xE6
+#define HID_UP_KEYBOARD_RIGHT_GUI 0xE7
+
+//----------------------------------------------------------------------------
+// HID Report define end
+//----------------------------------------------------------------------------
+ //<(EIP38434+)
+//----------------------------------------------------------------------------
+// Bit definitions for EndpointDescriptor.EndpointAddr
+//----------------------------------------------------------------------------
+#define EP_DESC_ADDR_EP_NUM 0x0F //Bit 3-0: Endpoint number
+#define EP_DESC_ADDR_DIR_BIT 0x80 //Bit 7: Direction of endpoint, 1/0 = In/Out
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// Bit definitions for EndpointDescriptor.EndpointFlags
+//----------------------------------------------------------------------------
+#define EP_DESC_FLAG_TYPE_BITS 0x03 //Bit 1-0: Indicate type of transfer on endpoint
+#define EP_DESC_FLAG_TYPE_CONT 0x00 //Bit 1-0: 00 = Endpoint does control transfers
+#define EP_DESC_FLAG_TYPE_ISOC 0x01 //Bit 1-0: 01 = Endpoint does isochronous transfers
+#define EP_DESC_FLAG_TYPE_BULK 0x02 //Bit 1-0: 10 = Endpoint does bulk transfers
+#define EP_DESC_FLAG_TYPE_INT 0x03 //Bit 1-0: 11 = Endpoint does interrupt transfers
+//----------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.BaseClass
+//---------------------------------------------------------------------------
+#define BASE_CLASS_HID 0x03
+#define BASE_CLASS_MASS_STORAGE 0x08
+#define BASE_CLASS_HUB 0x09
+//----------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.SubClass
+//---------------------------------------------------------------------------
+#define SUB_CLASS_BOOT_DEVICE 0x01 // Boot device sub-class
+#define SUB_CLASS_HUB 0x00 //Hub Device Sub Class?
+
+// Mass storage related sub-class equates
+#define SUB_CLASS_RBC 0x01 // RBC T10 project,1240-D, e.g. Flash
+#define SUB_CLASS_SFF8020I 0x02 // SFF8020I, e.g. ATAPI CD-ROM
+#define SUB_CLASS_QIC157 0x03 // QIC-157, e.g. ATAPI Tape device
+#define SUB_CLASS_UFI 0x04 // UFI, e.g. Floppy
+#define SUB_CLASS_SFF8070I 0x05 // SFF8070I, e.g. ATAPI Floppy
+#define SUB_CLASS_SCSI 0x06 // SCSI transparent command set
+
+// Vendor specific mass storage related sub-class equates
+#define SUB_CLASS_PL2307 0x80 // Prolific 2307 ,USB to IDE
+#define SUB_CLASS_SL11R 0x81 // ScanLogic SL11R-IDE
+#define SUB_CLASS_THUMB_DRV 0x82 // ThumbDrive
+#define SUB_CLASS_DFUSB01 0x83 // DataFab ATA Bridge
+#define SUB_CLASS_DOK 0x84 // Disk On Key
+#define SUB_CLASS_VENDOR_SPECIFIC 0xFF // Vendor Specific
+//---------------------------------------------------------------------------
+
+
+//---------------------------------------------------------------------------
+// Values for InterfaceDescriptor.Protocol
+//---------------------------------------------------------------------------
+#define PROTOCOL_KEYBOARD 0x01 // Keyboard device protocol
+#define PROTOCOL_MOUSE 0x02 // Mouse device protocol?
+
+#define PROTOCOL_HUB_SINGLE_TT 0x00 // Hub single TT protocol
+#define PROTOCOL_HUB_MULTIPLE_TTS 0x02 // Hub multiple TTs protocol
+
+// Mass storage related protocol equates
+#define PROTOCOL_CBI 0x00 // Mass Storage Control/Bulk/Interrupt
+ // with command completion interrupt
+#define PROTOCOL_CBI_NO_INT 0x01 // MASS STORAGE Control/Bulk/Interrupt
+ // with NO command completion interrupt
+#define PROTOCOL_BOT 0x50 // Mass Storage Bulk-Only Transport
+#define PROTOCOL_VENDOR 0xFF // Vendor specific mass protocol
+//---------------------------------------------------------------------------
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT16 wRequestType;
+ UINT16 wValue;
+ UINT16 wIndex;
+ UINT16 wDataLength;
+} DEV_REQ;
+
+#pragma pack(pop)
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: HCD_HEADER
+//
+// Description: USB Host Controller Driver function list structure.
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// bFlag UINT8 Driver Header Status
+// pfnHCDStart UINT8 Driver Start
+// pfnHCDStop UINT8 Driver Stop
+// pfnHCDEnumeratePorts UINT8 Enumerate Root Ports
+// pfnHCDDisableInterrupts UINT8 Disable Interrupts
+// pfnHCDEnableInterrupts UINT8 Enable Interrupts
+// pfnHCDProcessInterrupt UINT8 Process Interrupt
+// pfnHCDGetRootHubStatus UINT8 Get Root Hub Ports Status
+// pfnHCDDisableRootHub UINT8 Disable Root Hub
+// pfnHCDEnableRootHub UINT8 Enable Root Hub
+// pfnHCDControlTransfer UINT16 Perform Control Transfer
+// pfnHCDBulkTransfer UINT32 Perform Bulk Transfer
+// pfnHCDInterruptTransfer UINT8 Perform Interrupt Transfer
+// pfnHCDDeactivatePolling UINT8 Deactivate Polling
+// pfnHCDActivatePolling UINT8 Activate Polling
+// pfnHCDDisableKeyRepeat UINT8 Disable Key Repead
+// pfnHCDEnableKeyRepeat UINT8 Enable Key Repeat
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+//!!!!
+//!!!! If you change this structure, please, check UN_HCD_HEADER also.
+//!!!!
+typedef struct {
+ UINT8 bFlag;
+ UINT8 (*pfnHCDStart) (HC_STRUC*);
+ UINT8 (*pfnHCDStop) (HC_STRUC*);
+ UINT8 (*pfnHCDEnumeratePorts) (HC_STRUC*);
+ UINT8 (*pfnHCDDisableInterrupts) (HC_STRUC*);
+ UINT8 (*pfnHCDEnableInterrupts) (HC_STRUC*);
+ UINT8 (*pfnHCDProcessInterrupt) (HC_STRUC*);
+ UINT8 (*pfnHCDGetRootHubStatus) (HC_STRUC*,UINT8, BOOLEAN);
+ UINT8 (*pfnHCDDisableRootHub) (HC_STRUC*,UINT8);
+ UINT8 (*pfnHCDEnableRootHub) (HC_STRUC*,UINT8);
+ UINT16 (*pfnHCDControlTransfer) (HC_STRUC*,DEV_INFO*,UINT16,UINT16,UINT16,UINT8*,UINT16);
+ UINT32 (*pfnHCDBulkTransfer) (HC_STRUC*,DEV_INFO*,UINT8,UINT8*,UINT32);
+ UINT16 (*pfnHCDInterruptTransfer) (HC_STRUC*, DEV_INFO*, UINT8, UINT16, UINT8*, UINT16);
+ UINT8 (*pfnHCDDeactivatePolling) (HC_STRUC*,DEV_INFO*);
+ UINT8 (*pfnHCDActivatePolling) (HC_STRUC*,DEV_INFO*);
+ UINT8 (*pfnHCDDisableKeyRepeat) (HC_STRUC*);
+ UINT8 (*pfnHCDEnableKeyRepeat) (HC_STRUC*);
+ UINT8 (*pfnHCDEnableEndpoints) (HC_STRUC*,DEV_INFO*,UINT8*);
+ UINT8 (*pfnHCDInitDeviceData) (HC_STRUC*,DEV_INFO*,UINT8,UINT8**);
+ UINT8 (*pfnHCDDeinitDeviceData) (HC_STRUC*,DEV_INFO*);
+ UINT8 (*pfnHCDResetRootHub) (HC_STRUC*,UINT8);
+ UINT8 (*pfnHCDClearEndpointState) (HC_STRUC*,DEV_INFO*,UINT8); //(EIP54283+)
+ UINT8 (*pfnHCDGlobalSuspend) (HC_STRUC*); //(EIP54018+)
+} HCD_HEADER;
+
+typedef union {
+ HCD_HEADER hcd_header;
+ struct {
+ UINT8 bFlag;
+ VOID* proc[(sizeof(HCD_HEADER)-1)/sizeof(VOID*)];
+ } asArray;
+} UN_HCD_HEADER;
+
+// Equates related to host controller state
+#define HC_STATE_RUNNING BIT0
+#define HC_STATE_SUSPEND BIT1
+#define HC_STATE_USED BIT2
+#define HC_STATE_INITIALIZED BIT3
+#define HC_STATE_EXTERNAL BIT4
+#define HC_STATE_OWNERSHIP_CHANGE_IN_PROGRESS BIT5
+#define HC_STATE_CONTROLLER_WITH_RMH BIT6
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 bDescLength;
+ UINT8 bDescType;
+ UINT8 bNumPorts; // Number of downstream ports on hub
+ UINT16 wHubFlags; // See HUB_FLAG_xxx bit definitions below
+ UINT8 bPowerOnDelay; // Time to delay after turning on power to port (in 2ms units)
+ UINT8 bHubControlAmps; // Milliamps of current needed by hub controller
+ UINT8 bHubHdrDecLat;
+ UINT16 wHubDelay;
+ UINT16 DeviceRemovable; // Variable size array of bits (one for each port)
+} HUB_DESC;
+
+#pragma pack(pop)
+
+#define DEV_INFO_VALID_STRUC BIT0 // Structure validity
+#define DEV_INFO_DEV_PRESENT BIT1 // Device presence status
+#define DEV_INFO_MASS_DEV_REGD BIT2 // Mass device registered(have
+ // drive number assigned)
+#define DEV_INFO_MULTI_IF BIT3 // Indicates that the device
+ // is a part of multiple
+ // interface device
+#define DEV_INFO_HOTPLUG BIT4 // Indicates that this device
+ // is a hotplugged device
+#define DEV_INFO_DEV_DUMMY BIT5
+#define DEV_INFO_DEV_BUS BIT6 // Device info is locked by the bus
+#define DEV_INFO_DEV_DISCONNECTING BIT7 //(EIP60460+)
+#define DEV_INFO_IN_QUEUE BIT8
+#define DEV_INFO_ALT_SETTING_IF BIT9 // Indicates that the device
+ // has alternate setting for the
+ // interface
+
+
+#define DEV_INFO_VALIDPRESENT (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT)
+// Call back routine type definition
+typedef UINT8 (*CALLBACK_FUNC) (HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+
+#define MAX_CALLBACK_FUNCTION 50
+
+#define MAX_USB_ERRORS_NUM 0x30 // 48 errors max
+
+
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: MASS_HOTPLUG
+//
+// Description: This is a Mass URP (Mass USB Request Packet) structure for
+// the BIOS API call USBMass_HotPlugDeviceSupport
+// (API #27h, SubFunc 09h)
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// bDevAddr BYTE USB device address of the device
+// bNumUSBFDD BYTE Number of USB FDD's installed
+// bNumUSBCDROM BYTE Number of USB CDROM's installed
+// bDeviceFlag BYTE Flag indicating what hot plug devices to be added
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _MASS_HOTPLUG {
+ UINT8 bDevAddr; // USB Device Address
+ UINT8 bNumUSBFDD; // Number of USB FDD's installed
+ UINT8 bNumUSBCDROM; // Number of USB CDROM's installed
+ UINT8 bDeviceFlag; // Flag indicating what hot plug devices to be added
+} MASS_HOTPLUG;
+
+#define USB_HOTPLUG_ENABLE_FDD BIT0
+#define USB_HOTPLUG_ENABLE_CDROM BIT1
+#define USB_HOTPLUG_HDD_ADDRESS 0x7D
+#define USB_HOTPLUG_FDD_ADDRESS 0x7E
+#define USB_HOTPLUG_CDROM_ADDRESS 0x7F
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: MASS_XACT_STRUC
+//
+// Description: This structure holds the information needed for the mass
+// transaction (for CBI or BULK)
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// pCmdBuffer UINT16 Pointer to the mass transaction command buffer
+// bCmdSize UINT8 Size of the command buffer
+// bXferDir UINT8 Transfer direction (BIT7)
+// fpBuffer UINT32 Far pointer of the data buffer (IN/OUT)
+// dwLength UINT32 Length of the data buffer
+// wPreSkip UINT16 Number of bytes to skip before getting actual data
+// wPostSkip UINT16 Number of bytes to skip after getting actual data
+// wMiscFlag UINT16 Flag for special cases refer USBM_XACT_FLAG_XXX
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT8 *fpCmdBuffer;
+ UINT8 bCmdSize;
+ UINT8 bXferDir;
+ UINT8 *fpBuffer;
+ UINT32 dLength;
+ UINT16 wPreSkip;
+ UINT16 wPostSkip;
+ UINT16 wMiscFlag;
+} MASS_XACT_STRUC;
+
+#define USBM_XACT_FLAG_32BIT_DATA_BUFFER BIT0
+
+typedef struct _QUEUE_T{
+ VOID* volatile* data;
+ int maxsize;
+ volatile int head;
+ volatile int tail;
+} QUEUE_T;
+ //(EIP38434+)>
+typedef struct _ABS_MOUSE{
+ UINT8 ReportID;
+ UINT8 ButtonStauts;
+ UINT16 Xcoordinate;
+ UINT16 Ycoordinate;
+ UINT16 Pressure;
+ UINT16 Max_X;
+ UINT16 Max_Y;
+} ABS_MOUSE;
+ //<(EIP38434+)
+typedef struct MOUSE_DATA{
+ UINT8 ButtonStatus;
+ INT32 MouseX;
+ INT32 MouseY;
+ INT32 MouseZ;
+} MOUSE_DATA;
+
+
+#define MAX_NOTIFICATIONS_COUNT 100
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: USB_GLOBAL_DATA
+//
+// Description: USB Global Data Area structure
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ USB_VERSION stUSBVersion;
+ UINT32 dUSBStateFlag;
+ UINT16 aErrorLogBuffer[MAX_USB_ERRORS_NUM];
+ UINT8 bErrorLogIndex;
+ HCD_HEADER aHCDriverTable[MAX_HC_TYPES]; // For 4 type of HC
+ DEV_DRIVER aDevDriverTable[MAX_DEVICE_TYPES]; // For 5 types of devices
+ DEV_DRIVER aDelayedDrivers[MAX_DEVICE_TYPES]; // For 5 types of devices
+ DEV_INFO aDevInfoTable[MAX_DEVICES];
+ HC_STRUC **HcTable;
+ UINT8 HcTableCount;
+ UINT8 NumOfHc;
+ DEV_INFO FddHotplugDev;
+ DEV_INFO HddHotplugDev;
+ DEV_INFO CdromHotplugDev;
+ UINT8 bCallBackFunctionIndex;
+ CALLBACK_FUNC aCallBackFunctionTable[MAX_CALLBACK_FUNCTION];
+ UINT64 DeviceAddressMap;
+ UINT8 bEnumFlag;
+ UINT32 MemPages;
+ UINT8 *fpMemBlockStart;
+ UINT32 MemBlkStsBytes;
+ UINT32 *aMemBlkSts;
+//Hub related fields
+ UINT32 dHubPortStatus;
+ //UINT16 wHubPortStatus;
+//KBD related fields
+// Buffer to store keyboard shift key status bytes. This is correlated with
+// scan code buffer to generate proper scan code sequence
+ UINT8 aKBCShiftKeyStatusBufferStart[16];
+ UINT8 aKBCDeviceIDBufferStart[16]; // Buffer to store keyboard device ID
+// Buffer to store keyboard shift key status bytes. This is correlated with
+// scan code buffer to generate proper scan code sequence
+ UINT8 aKBCScanCodeBufferStart[16];
+
+ UINT8 aKBCUsbDataBufferStart[32];
+ UINT8 *aKBCUsbDataBufferHead; // Keyboard character buffer head and tail pointers
+ UINT8 *aKBCUsbDataBufferTail;
+ UINT8 aKBCCharacterBufferStart[128]; //(EIP29345)
+ UINT8 bCurrentUSBKeyCode;
+ UINT8 bUSBKBShiftKeyStatus;
+ UINT8 bNonUSBKBShiftKeyStatus;
+ UINT8 bUSBKBC_ExtStatusFlag;
+ UINT8 bUSBDeviceList;
+ UINT8 bSet2ScanCode; // Temporary storage for the scan code set 2 scan code
+ UINT8 bLastUSBKeyCode; // Last USB key code processed
+ UINT8 bBreakCodeDeviceID; // Device IDs for the keyboards generating break code
+ UINT8 bCurrentDeviceID; // Current USB keyboard device ID
+ UINT16 wUSBKBC_StatusFlag;
+ UINT16 wRepeatCounter; // Typematic repeat counter
+ UINT16 wRepeatRate; // Typematic repeat rate
+ UINT8 *fpKBCCharacterBufferHead; // Keyboard character buffer head and tail pointers
+ UINT8 *fpKBCCharacterBufferTail;
+ UINT8 *fpKBCScanCodeBufferPtr; // Keyboard scan code buffer pointer
+ UINT8 bUSBKBC_MassStorage;
+ UINT8 bKbdDataReady;
+ UINT8 aKBInputBuffer[16]; // Keyboard expanded input buffer pointer (null-terminated)
+ UINT8 bCCB;
+ VOID *EfiKeyboardBuffer;
+ UINT8 RepeatKey;
+ HC_STRUC *fpKeyRepeatHCStruc;
+ DEV_INFO *fpKeyRepeatDevInfo;
+ DEV_INFO *aUSBKBDeviceTable[USB_DEV_HID_COUNT];
+// Added by mouse driver
+ MOUSE_DATA MouseData;
+ UINT8 aMouseInputBuffer[15];
+ ABS_MOUSE AbsMouseData[10]; //(EIP38434+)
+// Mouse input buffer head and tail pointers
+ UINT8 *fpMouseInputBufferHeadPtr;
+ UINT8 *fpMouseInputBufferTailPtr;
+ UINT8 bMouseStatusFlag;
+ // Bit 7 : Mouse enabled bit (1/0)
+ // Bit 6 : Mouse data ready (1/0)
+ // BIT 5 : Mouse data from USB (1/0)
+ // BIT 4 : 4-byte mouse data (1/0)
+ // Bit 3-0 : Reserved
+ UINT8 *fpUSBTempBuffer;
+ UINT8 *fpUSBMassConsumeBuffer;
+ UINT32 wInterruptStatus;
+ URP_STRUC *fpURP; // Request Packet pointer
+// BOTCommandTag used to maintain BOT command block number
+ UINT32 dBOTCommandTag;
+ //UINT16 wMassTempData;
+ UINT8 bUSBStorageDeviceDelayCount;
+ UINT16 wBulkDataXferDelay;
+// Flag that allows mass storage device to handle special conditions. The
+// bit pattern is defined by the USBMASS_MISC_FLAG_XXX equates in USB.EQU
+ UINT16 wMassStorageMiscFlag;
+ UINT8 bGeometryCommandStatus;
+ UINT8 bModeSenseSectors;
+ UINT8 bModeSenseHeads;
+ UINT16 wModeSenseCylinders;
+ UINT16 wModeSenseBlockSize;
+ UINT32 dModeSenseMaxLBA;
+ UINT8 bReadCapSectors;
+ UINT8 bReadCapHeads;
+ UINT16 wReadCapCylinders;
+ UINT16 wReadCapBlockSize;
+ UINT32 dReadCapMaxLBA;
+ UINT8 bDiskMediaType;
+ UINT16 wTimeOutValue;
+ UINT8 bLastCommandStatus;
+ UINT32 dLastCommandStatusExtended;
+// Added by EHCI driver
+ //UINT8 aControlSetupData[8];
+// EHCI_QH *fpQHAsyncXfer;
+ UINT8 bIgnoreConnectStsChng;
+ UINT8 ProcessingPeriodicList;
+ UINT8 bHandOverInProgress;
+ HC_STRUC *RootHubHcStruc;
+
+// Tokens representation for the module binary
+ UINT8 kbc_support;
+ UINT8 fdd_hotplug_support;
+ UINT8 hdd_hotplug_support;
+ UINT8 cdrom_hotplug_support;
+ UINT8 UsbMassResetDelay; // 0/1/2/3 for 10/20/30/40 seconds
+ UINT8 PowerGoodDeviceDelay; // 0/1/5/6/../10 seconds
+ UINT8 UsbXhciSupport; // 0/1 for Disabled/Enabled
+ UINT8 UsbXhciHandoff; // 0/1 for Disabled/Enabled
+ UINT8 UsbEhciHandoff; // 0/1 for Disabled/Enabled
+ UINT8 UsbOhciHandoff; // 0/1 for Disabled/Enabled
+ UINT8 UsbEmul6064; // 0/1 for Disabled/Enabled
+ UINT8 NumberOfFDDs;
+ UINT8 NumberOfHDDs;
+ UINT8 NumberOfCDROMs;
+ UINT8 USBMassEmulationOptionTable[16];
+ QUEUE_T QueueCnnctDisc;
+ QUEUE_T ICCQueueCnnctDisc; //QueueCnnctDisc will work of USB devices. Smart Card reader will work in that queue. But Smart Card(ICC) isn't a USB device. So create a new queue to handle it.
+ DEV_INFO *QueueData1[MAX_NOTIFICATIONS_COUNT];
+ UINT8 *gUsbSkipListTable; //(EIP51653+)
+ UINT8 UsbHiSpeedSupport;
+ USB_TIMING_POLICY UsbTimingPolicy;
+ USB_SUPPORT_SETUP UsbSetupData; //(EIP99882+)
+} USB_GLOBAL_DATA;
+
+// Note: If additional space is needed in USB data segment,
+// MAX_BULK_DATA_SIZE can be changed to 200h without significant
+// decrease in mass storage data transfer performance
+// .. moved to SDL
+//#define MAX_BULK_DATA_SIZE 0x0400 // Maximum amount of data to transfer
+
+#define USB_HC_CLASS_CODE 0x0C03
+
+#define MAX_NUM_HC_MODULES 0x03
+
+// Equates to disable/enable USB port interrupt generation and
+// 060/064h trapping
+#define USB_DISABLE_INTERRUPT 0x000
+#define USB_SAFE_DISABLE_INTERRUPT 0x001
+#define USB_ENABLE_INTERRUPT 0x00F
+
+#define TRAP_REQUEST_CLEAR 0x000
+#define TRAP_REQUEST_DISABLE 0x0FF
+
+//---------------------------------------------------------------------------
+// Equates for Generic USB specific registers in the PCI config space
+//---------------------------------------------------------------------------
+#define USB_REG_COMMAND 0x004
+#define USB_MEM_BASE_ADDRESS 0x010 // Offset 10-13h
+#define USB_IO_BASE_ADDRESS 0x020
+#define USB_IRQ_LEVEL 0x03C
+#define USB_RELEASE_NUM 0x060
+#define USB_HC_CLASS_CODE 0x0C03
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Equates common to all host controllers
+//---------------------------------------------------------------------------
+#define USB_PORT_STAT_DEV_CONNECTED BIT0
+#define USB_PORT_STAT_DEV_LOWSPEED BIT1
+#define USB_PORT_STAT_DEV_FULLSPEED BIT2
+#define USB_PORT_STAT_DEV_HISPEED 0//(BIT1 + BIT2)
+#define USB_PORT_STAT_DEV_SUPERSPEED BIT3
+#define USB_PORT_STAT_DEV_SPEED_MASK (BIT1 + BIT2 + BIT3 + BIT7)
+#define USB_PORT_STAT_DEV_SPEED_MASK_SHIFT 0x1
+#define USB_PORT_STAT_DEV_CONNECT_CHANGED BIT4
+#define USB_PORT_STAT_DEV_ENABLED BIT5
+#define USB_PORT_STAT_DEV_OWNER BIT6
+#define USB_PORT_STAT_DEV_SUPERSPEED_PLUS BIT7
+
+#define USB_DEV_SPEED_LOW (USB_PORT_STAT_DEV_LOWSPEED >> USB_PORT_STAT_DEV_SPEED_MASK_SHIFT)
+#define USB_DEV_SPEED_FULL (USB_PORT_STAT_DEV_FULLSPEED >> USB_PORT_STAT_DEV_SPEED_MASK_SHIFT)
+#define USB_DEV_SPEED_HIGH (USB_PORT_STAT_DEV_HISPEED >> USB_PORT_STAT_DEV_SPEED_MASK_SHIFT)
+#define USB_DEV_SPEED_SUPER (USB_PORT_STAT_DEV_SUPERSPEED >> USB_PORT_STAT_DEV_SPEED_MASK_SHIFT)
+#define USB_DEV_SPEED_SUPER_PLUS (USB_PORT_STAT_DEV_SUPERSPEED_PLUS >> USB_PORT_STAT_DEV_SPEED_MASK_SHIFT)
+
+//---------------------------------------------------------------------------
+
+//---------------------------------------------------------------------------
+// Equates related to USB equipment list
+//---------------------------------------------------------------------------
+ //(EIP84455+)>
+#define USB_TYPE_KEYBOARD BIT0
+#define USB_TYPE_MOUSE BIT1
+#define USB_TYPE_POINT BIT2
+#define USB_TYPE_HUB BIT3
+#define USB_TYPE_MASS_STORAGE BIT4
+ //<(EIP84455+)
+
+// Bulk transfer error status (bLastCommandStatus)
+#define USB_BULK_STALLED BIT0
+#define USB_BULK_TIMEDOUT BIT1
+#define USB_CONTROL_STALLED BIT2
+
+#define USB_TRNSFR_ERRBIT_SHIFT 0
+#define USB_TRNSFR_BITSTUFF BIT0
+#define USB_TRNSFR_CRCERROR BIT1
+#define USB_TRNSFR_NAK BIT2
+#define USB_TRNSFR_BABBLE BIT3
+#define USB_TRSFR_BUFFER_ERROR BIT4
+#define USB_TRSFR_STALLED BIT5
+#define USB_TRNSF_ERRORS_MASK (USB_TRNSFR_ERRBIT_SHIFT | \
+ USB_TRNSFR_BITSTUFF | USB_TRNSFR_CRCERROR |\
+ USB_TRNSFR_NAK|USB_TRNSFR_BABBLE|USB_TRSFR_BUFFER_ERROR )
+#define USB_TRNSFR_TIMEOUT BIT6
+
+//----------------------------------------------------------------------------
+// Equates regarding USB device info structure search parameter
+//----------------------------------------------------------------------------
+#define USB_SRCH_DEV_ADDR 0x10 //
+#define USB_SRCH_DEV_TYPE 0x20 // Next device of a given type
+#define USB_SRCH_DEV_NUM 0x30 // Number of devices of certain type
+#define USB_SRCH_DEVBASECLASS_NUM 0x31 // Number of devices of certain base class
+#define USB_SRCH_HC_STRUC 0x40 // Next device of a given HC
+#define USB_SRCH_DEV_INDX 0x80 // Device of a given index
+/*
+// USB Initialization Flags - passed in when USB is initialized
+//----------------------------------------------------------------------------
+#define INIT_FLAG_MANUAL 0x07 //Bit 2-0: 000 = Auto enum
+ // 001 = KB on port 1
+ // ... ...
+ // 111 = KB on port 7
+#define INIT_FLAG_ENUM_DISABLE 0x08 // 3: If set, do not enum the USB
+#define INIT_FLAG_BEEP_DISABLE 0x10 // 4: If set, do not beep on new devices
+#define INIT_FLAG_USB_STOP_EHCI_IN_OHCI_HANDOVER 0x20
+*/
+//----------------------------------------------------------------------------
+// Bit definitions for DeviceRequest.RequestType
+//----------------------------------------------------------------------------
+// Bit 7: Data direction
+#define USB_REQ_TYPE_OUTPUT 0x00 // 0 = Host sending data to device
+#define USB_REQ_TYPE_INPUT 0x80 // 1 = Device sending data to host
+
+// Bit 6-5: Type
+#define USB_REQ_TYPE_STANDARD 0x00 // 00 = Standard USB request
+#define USB_REQ_TYPE_CLASS 0x20 // 01 = Class specific
+#define USB_REQ_TYPE_VENDOR 0x40 // 10 = Vendor specific
+
+// Bit 4-0: Recipient
+#define USB_REQ_TYPE_DEVICE 0x00 // 00000 = Device
+#define USB_REQ_TYPE_INTERFACE 0x01 // 00001 = Interface
+#define USB_REQ_TYPE_ENDPOINT 0x02 // 00010 = Endpoint
+#define USB_REQ_TYPE_OTHER 0x03 // 00011 = Other
+
+//----------------------------------------------------------------------------
+// Values for DeviceRequest.RequestType and DeviceRequest.RequestCode fields
+// combined as a word value.
+//---------------------------------------------------------------------------
+#define USB_RQ_SET_ADDRESS ((0x05 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE)
+#define USB_RQ_GET_DESCRIPTOR ((0x06 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE)
+#define USB_RQ_GET_CONFIGURATION ((0x08 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE)
+#define USB_RQ_SET_CONFIGURATION ((0x09 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE)
+#define USB_RQ_SET_INTERFACE ((0x0B << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE)
+#define USB_RQ_SET_FEATURE ((0x03 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_DEVICE)
+
+#define USB_FSEL_DEV_REMOTE_WAKEUP 01
+
+#define USB_RQ_GET_CLASS_DESCRIPTOR ((0x06 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE)
+#define HID_RQ_GET_DESCRIPTOR ((0x06 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_INTERFACE) //(EIP38434+)
+#define HID_RQ_SET_PROTOCOL ((0x0B << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE)
+#define HID_RQ_SET_REPORT ((0x09 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE)
+#define HID_RQ_SET_IDLE ((0x0A << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE)
+#define HUB_RQ_GET_PORT_STATUS ((0x00 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER)
+#define HUB_RQ_SET_PORT_FEATURE ((0x03 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER)
+#define HUB_RQ_CLEAR_PORT_FEATURE ((0x01 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_OTHER)
+#define HUB_RQ_SET_HUB_DEPTH ((0x0C << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_DEVICE)
+
+//----------------------------------------------------------------------------
+// Bit definitions for HubDescriptor.HubFlags
+//----------------------------------------------------------------------------
+#define HUB_FLAG_PWR_MODE_BITS 0x03 //Bit 1-0: Power switching mode used by hub
+#define HUB_FLAG_PWR_MODE_GANG 0x00 // =00: All ports power on/off together
+#define HUB_FLAG_PWR_MODE_INDIV 0x01 // =01: Ports power on/off individually
+#define HUB_FLAG_PWR_MODE_FIXED 0x02 // =1x: Ports power is always on
+#define HUB_FLAG_COMPOUND_DEV 0x04 //Bit 2: If set, hub is part of a compound device
+#define HUB_FLAG_OVR_CUR_BITS 0x18 //Bit 4-3: Over-current protection mode used by hub
+#define HUB_FLAG_OVR_CUR_GLOBAL 0x00 // =00: Hub reports only global over-current status
+#define HUB_FLAG_OVR_CUR_INDIV 0x08 // =01: Hub reports individual over-current status
+#define HUB_FLAG_OVR_CUR_NONE 0x10 // =1x: Hub has no over-current protection
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// Hub Class Feature Selectors
+//----------------------------------------------------------------------------
+#define HUB_FEATURE_C_HUB_LOCAL_POWER 0
+#define HUB_FEATURE_C_HUB_OVER_CURRENT 1
+#define HUB_FEATURE_PORT_CONNECTION 0
+#define HUB_FEATURE_PORT_ENABLE 1 //Hub port enable feature
+#define HUB_FEATURE_PORT_SUSPEND 2
+#define HUB_FEATURE_PORT_OVER_CURRENT 3
+#define HUB_FEATURE_PORT_RESET 4 //Hub port reset feature
+#define HUB_FEATURE_PORT_LINK_STATE 5
+#define HUB_FEATURE_PORT_POWER 8 //Hub port power feature
+#define HUB_FEATURE_PORT_LOW_SPEED 9 //Hub port low speed feature
+#define HUB_FEATURE_C_PORT_CONNECTION 16 //Hub port connect change feature
+#define HUB_FEATURE_C_PORT_ENABLE 17 //Hub port enable change feature
+#define HUB_FEATURE_C_PORT_SUSPEND 18
+#define HUB_FEATURE_C_PORT_OVER_CURRENT 19
+#define HUB_FEATURE_C_PORT_RESET 20 //Hub port reset change feature
+#define HUB_FEATURE_PORT_U1_TIMEOUT 23
+#define HUB_FEATURE_PORT_U2_TIMEOUT 24
+#define HUB_FEATURE_C_PORT_LINK_STATE 25
+#define HUB_FEATURE_C_PORT_CONFIG_ERROR 26
+#define HUB_FEATURE_PORT_REMOTE_WAKE_MASK 27
+#define HUB_FEATURE_BH_PORT_RESET 28
+#define HUB_FEATURE_C_BH_PORT_RESET 29
+#define HUB_FEATURE_FORCE_LINKPM_ACCEPT 30
+
+typedef enum {
+ HubLocalPower = 0,
+ HubOverCurrent,
+ PortConnection = 0,
+ PortEnable,
+ PortSuspend,
+ PortOverCurrent,
+ PortReset,
+ PortLinkState,
+ PortPower = 8,
+ PortLowSpeed,
+ PortConnectChange = 16,
+ PortEnableChange,
+ PortSuspendChange,
+ PortOverCurrentChange,
+ PortResetChange,
+ PortTest,
+ PortIndicator,
+ PortU1Timeout,
+ PortU2Timeout,
+ PortLinkStateChange,
+ PortConfigErrorChange,
+ PortRemoteWakeMask,
+ BhPortReset,
+ BhPortResetChange,
+ ForceLinkPmAccept
+} HUB_FEATURE;
+
+//----------------------------------------------------------------------------
+
+//----------------------------------------------------------------------------
+// Hub Port Status Bit Definitions
+//----------------------------------------------------------------------------
+#define HUB_PORT_STATUS_PORT_CONNECTION BIT0 //Bit 0: Set if device present
+#define HUB_PORT_STATUS_PORT_ENABLED BIT1 //Bit 1: Set if port is enabled
+#define HUB_PORT_STATUS_PORT_SUSPEND BIT2 //Bit 2: Set if device on port is suspended
+#define HUB_PORT_STATUS_PORT_OVER_CURRENT BIT3 //Bit 3: Set if port has been powered down due to over-current
+#define HUB_PORT_STATUS_PORT_RESET BIT4 //Bit 4: Set if reset sigaling is active
+#define HUB_PORT_STATUS_PORT_POWER BIT8 //Bit 8: Set if port is enabled
+#define HUB_PORT_STATUS_PORT_LOW_SPEED BIT9 //Bit 9: Set if a low speed device is attached
+#define HUB_PORT_STATUS_PORT_HIGH_SPEED BIT10 //Bit 10: Set if a high speed device is attached
+#define HUB_PORT_STATUS_PORT_TEST BIT11
+#define HUB_PORT_STATUS_PORT_INDICATOR BIT12
+#define HUB_PORT_STATUS_C_PORT_CONNECTION (BIT0 << 16) //Bit 0: Set if device has been attached/removed
+#define HUB_PORT_STATUS_C_PORT_ENABLE (BIT1 << 16) //Bit 1: Set if port has been enabled/disabled by hardware in hub
+#define HUB_PORT_STATUS_C_PORT_SUSPEND (BIT2 << 16) //Bit 2: Set if device has entered/left suspend state
+#define HUB_PORT_STATUS_C_PORT_OVER_CURRENT (BIT3 << 16) //Bit 3: Set if over current indicator has changed
+#define HUB_PORT_STATUS_C_PORT_RESET (BIT4 << 16) //Bit 4: Set when port reset sequence is complete
+
+#define USB3_HUB_PORT_STATUS_PORT_CONNECTION BIT0
+#define USB3_HUB_PORT_STATUS_PORT_ENABLED BIT1
+#define USB3_HUB_PORT_STATUS_PORT_OVER_CURRENT BIT3
+#define USB3_HUB_PORT_STATUS_PORT_RESET BIT4
+#define USB3_HUB_PORT_STATUS_PORT_LINK_STATE (BIT5 | BIT6 | BIT7 | BIT8)
+#define USB3_HUB_PORT_STATUS_PORT_POWER BIT9
+#define USB3_HUB_PORT_STATUS_PORT_SPEED (BIT10 | BIT11 | BIT12)
+#define USB3_HUB_PORT_STATUS_C_PORT_CONNECTION (BIT0 << 16)
+#define USB3_HUB_PORT_STATUS_C_PORT_OVER_CURRENT (BIT3 << 16)
+#define USB3_HUB_PORT_STATUS_C_PORT_RESET (BIT4 << 16)
+#define USB3_HUB_PORT_STATUS_C_BH_PORT_RESET (BIT5 << 16)
+#define USB3_HUB_PORT_STATUS_C_PORT_LINK_STATE (BIT6 << 16)
+#define USB3_HUB_PORT_STATUS_C_PORT_CONFIG_ERROR (BIT7 << 16)
+
+#define USB3_HUB_PORT_LINK_U0 0x00
+#define USB3_HUB_PORT_LINK_U1 0x01
+#define USB3_HUB_PORT_LINK_U2 0x02
+#define USB3_HUB_PORT_LINK_U3 0x03
+#define USB3_HUB_PORT_LINK_DISABLED 0x04
+#define USB3_HUB_PORT_LINK_RXDETECT 0x05
+#define USB3_HUB_PORT_LINK_INACTIVE 0x06
+#define USB3_HUB_PORT_LINK_POLLING 0x07
+#define USB3_HUB_PORT_LINK_RECOVERY 0x08
+#define USB3_HUB_PORT_LINK_HOT_RESET 0x09
+#define USB3_HUB_PORT_LINK_COMPLIANCE_MODE 0x0A
+#define USB3_HUB_PORT_LINK_LOOPBACK 0x0B
+
+#pragma pack(push, 1)
+
+typedef struct {
+ struct {
+ UINT16 Connected :1;
+ UINT16 Enabled :1;
+ UINT16 Suspend :1;
+ UINT16 OverCurrent :1;
+ UINT16 Reset :1;
+ UINT16 Reserved :3;
+ UINT16 Power :1;
+ UINT16 LowSpeed :1;
+ UINT16 HighSpeed :1;
+ UINT16 TestMode :1;
+ UINT16 Indicator :1;
+ UINT16 Reserved1 :3;
+ } PortStatus;
+ struct {
+ UINT16 ConnectChange :1;
+ UINT16 EnableChange :1;
+ UINT16 SuspendChange :1;
+ UINT16 OverCurrentChange :1;
+ UINT16 ResetChange :1;
+ UINT16 Reserved :11;
+ } PortChange;
+} HUB_PORT_STATUS;
+
+typedef struct {
+ struct {
+ UINT16 Connected :1;
+ UINT16 Enabled :1;
+ UINT16 Reserved :1;
+ UINT16 OverCurrent :1;
+ UINT16 Reset :1;
+ UINT16 LinkState :4;
+ UINT16 Power :1;
+ UINT16 Speed :3;
+ UINT16 Reserved1 :3;
+ } PortStatus;
+ struct {
+ UINT16 ConnectChange :1;
+ UINT16 Reserved :2;
+ UINT16 OverCurrentChange :1;
+ UINT16 ResetChange :1;
+ UINT16 BhResetChange :1;
+ UINT16 LinkStateChange :1;
+ UINT16 ConfigErrorChange :1;
+ UINT16 Reserved1 :8;
+ } PortChange;
+} USB3_HUB_PORT_STATUS;
+
+#pragma pack(pop)
+
+#define ENDPOINT_CLEAR_PORT_FEATURE (0x01 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_STANDARD | USB_REQ_TYPE_ENDPOINT
+
+#define ADSC_OUT_REQUEST_TYPE (0x00 << 8) | USB_REQ_TYPE_OUTPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE
+#define ADSC_IN_REQUEST_TYPE (0x00 << 8) | USB_REQ_TYPE_INPUT | USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE
+
+#define ENDPOINT_HALT 00
+
+// Standard PCI configuration register offsets and relevant values
+//------------------------------------------------------------------------------
+#define PCI_REG_VENDID 0x00 //PCI vendor ID register
+#define PCI_REG_DEVID 0x02 //PCI device ID register
+#define PCI_REG_COMMAND 0x04 //PCI command register
+#define CMD_DEV_DISABLE 0x00 //Disables device when written to cmd reg
+#define CMD_IO_SPACE 0x01 //IO space enable bit
+#define CMD_MEM_SPACE 0x02 //Memory space enable bit
+#define CMD_BUS_MASTER 0x4 //Bus master enable bit
+#define CMD_SPECIAL_CYCLE 0x08 //Special cycle enable bit
+#define CMD_MEM_INVALIDATE 0x10 //Memory write & invalidate enable bit
+#define CMD_PAL_SNOOP 0x20 //VGA palette snoop enable bit
+#define CMD_PARITY 0x40 //Parity error enable bit
+#define CMD_WAIT_CYCLE 0x80 //Wait cycle control bit
+#define CMD_SERR 0x100 //SERR# enable bit
+#define CMD_FAST_BTOB 0x200 //Fast back-to-back enable bit
+#define PCI_REG_STATUS 0x06 //PCI status register
+#define STAT_RESET_ALL 0x0FFFF //Resets all status bits
+#define PCI_REG_REVID 0x08 //PCI revision ID register
+#define PCI_REG_IF_TYPE 0x09 //PCI interface type register
+#define PCI_REG_SUB_TYPE 0x0A //PCI sub type register
+#define PCI_REG_BASE_TYPE 0x0B //PCI base type register
+#define PCI_REG_LINE_SIZE 0x0C //PCI cache line size register
+#define PCI_REG_LATENCY 0x0D //PCI latency timer register
+#define PCI_REG_LATENCY 0x0D //PCI latency timer register
+#define PCI_REG_HEADER_TYPE 0x0E //PCI header type register
+#define MULTI_FUNC_BIT 0x80 //If set, device is multi function
+#define PCI_CFG_HEADER_STD 0x00 //Standard PCI config space
+#define PCI_CFG_HEADER_PPB 0x01 //PCI-PCI bridge config space
+#define PCI_REG_BIST 0x0F //PCI built in self test register
+#define PCI_REG_FIRST_BASE_ADD 0x10 //PCI first base address register
+#define PCI_REG_LAST_BASE_ADD 0x24 //PCI last base address register
+#define PCI_BASE_ADD_PORT_BIT 0x01 //If set, base add reg is for I/O port
+#define PCI_BASE_ADD_MEMTYPE 0x06 //Bits in lower word that are mem type
+#define PCI_BASE_ADD_MT_32 0x00 //Memory must be located at 32 bit add
+#define PCI_BASE_ADD_MT_20 0x02 //Memory must be located at 20 bit add
+#define PCI_BASE_ADD_MT_64 0x04 //Memory must be located at 64 bit add
+#define PCI_BASE_ADD_PREFETCH 0x08 //If set, memory is prefetchable
+#define PCI_BASE_ADD_MEMMASK 0x0FFF0 //Bits in lower word that are memory mask
+#define PCI_BASE_ADD_PORTMASK 0x0FFFC //Bits in lower word that are port mask
+#define PCI_REG_ROM_BASE_ADD 0x30 //PCI expansion ROM base address register
+#define PCI_BASE_ADD_ROMMASK 0x0FC00 //Bits in lower word that are ROM mask
+#define PCI_REG_INT_LINE 0x3C //PCI interrupt line register
+#define PCI_REG_INT_PIN 0x3D //PCI interrupt pin register
+#define PCI_REG_MAX_GNT 0x3E //PCI max grant register
+#define PCI_REG_MAX_LAT 0x3F //PCI max latency register
+
+#define INTR_CNTRLR_MASTER_PORT 0x020
+#define INTR_CNTRLR_SLAVE_PORT 0x0A0
+#define READ_IN_SERVICE_REGISTER 0x00B
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: USB_BADDEV_STRUC
+//
+// Description: This structure is used to define a non-compliant USB device
+//
+// Fields: Name Type Description
+// ------------------------------------------------------------
+// wVID WORD Vendor ID of the device
+// wDID WORD Device ID of the device
+// bBaseClass BYTE Base class of the device
+// bSubClass BYTE Sub class of the device
+// bProtocol BYTE Protocol used by the device
+// wFlags INCMPT_FLAGS Incompatibility flags
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct {
+ UINT16 wVID;
+ UINT16 wDID;
+ UINT8 bBaseClass;
+ UINT8 bSubClass;
+ UINT8 bProtocol;
+ UINT16 wFlags;
+} USB_BADDEV_STRUC;
+
+
+//<AMI_GHDR_START>
+//----------------------------------------------------------------------------
+// Name: INCMPT_FLAGS (Incompatibility attributes)
+//
+// Type: Equates
+//
+// Description: This equates are used to describe the incompatible USB mass
+// storage devices. The bits defined are:
+// BIT Description
+// =============================================================
+// 0 1, indicates this device does not support mode sense command
+// 1 1, indicates that this is a single LUN device (even though it is reporting as multiple LUN)
+// 2 1, indicates that this device should be disabled
+// 3 1, indicates this device does not support test unit ready command
+// 4 1, indicates this device responds with wrong BOT status value
+// 5 1, indicates that this device does not support start unit command
+// 6 1, indicates that this device does not support read format capacity command
+// 7 1, indicates that this hispeed device has to be in full speed always
+// 8 1, indicates that this hispeed device has to be in hispeed always
+//
+// Notes: The device is identified by the vendor id and device id
+// associated with the flags above
+//
+// Referrals: USB_BADDEV_STRUC
+//
+//----------------------------------------------------------------------------
+//<AMI_GHDR_END>
+
+#define USB_INCMPT_MODE_SENSE_NOT_SUPPORTED BIT0
+#define USB_INCMPT_SINGLE_LUN_DEVICE BIT1
+#define USB_INCMPT_DISABLE_DEVICE BIT2
+#define USB_INCMPT_TEST_UNIT_READY_FAILED BIT3
+#define USB_INCMPT_BOT_STATUS_FAILED BIT4
+#define USB_INCMPT_START_UNIT_NOT_SUPPORTED BIT5
+#define USB_INCMPT_FORMAT_CAPACITY_NOT_SUPPORTED BIT6
+#define USB_INCMPT_KEEP_FULLSPEED BIT7
+#define USB_INCMPT_KEEP_HISPEED BIT8
+#define USB_INCMPT_SET_BOOT_PROTOCOL_NOT_SUPPORTED BIT9
+#define USB_INCMPT_GETMAXLUN_NOT_SUPPORTED BIT10
+#define USB_INCMPT_RMH_DEVICE BIT11
+#define USB_INCMPT_HID_DATA_OVERFLOW BIT12
+#define USB_INCMPT_BOOT_PROTOCOL_IGNORED BIT13
+#define USB_INCMPT_REPORT_PROTOCOL_ONLY BIT14 //(EIP38434+)
+#define USB_INCMPT_HID_BOOT_PROTOCOL_ONLY BIT15
+
+//<AMI_SHDR_START>
+//----------------------------------------------------------------------------
+// Name: HcDxeRecord
+//
+// Description: state information for USB_HC_PROTOCOL implementation
+//
+//----------------------------------------------------------------------------
+//<AMI_SHDR_END>
+
+typedef struct _HC_DXE_RECORD {
+ EFI_USB_HC_PROTOCOL hcprotocol;
+ EFI_USB2_HC_PROTOCOL hcprotocol2;
+ HC_STRUC *hc_data;
+ EFI_PCI_IO_PROTOCOL *pciIo;
+ DLIST AsyncTransfers;
+} HC_DXE_RECORD;
+
+typedef struct {
+ QUEUE_T QCompleted;
+ UINTN DataLength; //size of each transfer
+ EFI_ASYNC_USB_TRANSFER_CALLBACK CallbackFunction;
+ VOID* Context;
+ EFI_EVENT Event;
+ DLINK Link;
+ UINT8 Lock;
+ UINT8 EndpointAddress;
+ UINT8 Data[1];
+} USBHC_INTERRUPT_DEVNINFO_T;
+
+int VALID_DEVINFO(DEV_INFO* pDevInfo);
+VOID USB_AbortConnectDev(DEV_INFO* );
+EFI_STATUS UsbHcStrucValidation(HC_STRUC*);
+EFI_STATUS UsbDevInfoValidation(DEV_INFO*);
+
+#endif // __USB_H
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbhid.c b/Core/EM/usb/rt/usbhid.c
new file mode 100644
index 0000000..aa9eec6
--- /dev/null
+++ b/Core/EM/usb/rt/usbhid.c
@@ -0,0 +1,1474 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbhid.c 39 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 39 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+//
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbhid.c $
+//
+// 39 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 38 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 37 4/29/15 5:29a Wilsonlee
+// [TAG] EIP215830
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CYBORG R.A.T3 Gaming Mouse left/right button has no
+// function, instead DPI UP/DOWN config button has left/right click
+// function.
+// [RootCause] We get mouuse button data from constant data offset.
+// [Solution] Mouse Data should be defining report fields that contain
+// modifiable device data.
+// [Files] usbms.c, usbhid.c, usbpoint.c
+//
+// 36 2/05/15 5:54a Wilsonlee
+// [TAG] EIP203944
+// [Category] Improvement
+// [Description] If InputReportDataLength is less than IntMaxPkt, we
+// need to use IntMaxPkt polling interrupt data.
+// [Files] usbhid.c
+//
+// 35 12/24/14 9:33p Wilsonlee
+// [TAG] EIP194683
+// [Category] Improvement
+// [Description] Add the flag "USB_INCMPT_HID_BOOT_PROTOCOL_ONLY" of usb
+// bad device table to keep devices use boot protocol.
+// [Files] usbkbd.c, usbms.c, usbhid.c, usbdef.h
+//
+// 34 10/05/14 10:06p Wilsonlee
+// [TAG] EIP186639
+// [Category] Improvement
+// [Description] Medigenic-Esterline USB keboard (Advanced Input Devices
+// chip) workaround.
+// [Files] usbhid.c
+//
+// 33 9/30/14 2:42a Wilsonlee
+// [TAG] EIP183901
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System will hang up when attach special docking.
+// [RootCause] It hangs at HidParserLocal function because it caused
+// dead loop if Field->UsageMax is 0xFFFF.
+// [Solution] Change Data to UINT32.
+// [Files] usbhid.c
+//
+// 32 9/02/14 3:53a Wilsonlee
+// [TAG] EIP182567
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] POST B4h sometimes stays about 30 sec if using special
+// KB/Ms.
+// [RootCause] t's timeout in getting config or report descriptor
+// commands.
+// [Solution] Set the timeout to 500 ms.
+// [Files] usb.c, usbhid.c, usbdef.h
+//
+// 31 8/07/14 2:19a Wilsonlee
+// [TAG] EIP176549
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Microstep USB Keyboard issue.
+// [RootCause] The report descriptor of Microstep USB Keyboard (Sonix
+// Technology Co chip) has an error, Modifier keys is bitmap data, but it
+// reports as array data.
+// [Solution] We need to force variable flag for Modifier keys input
+// item.
+// [Files] usbhid.c, usbkbd.c, usbdef.h
+//
+// 30 5/06/14 5:15a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 29 4/30/14 6:14a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 28 4/29/14 7:54p Wilsonlee
+// [TAG] EIP163828
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The mouses stop more than 4 seconds during TP 0xB4 when
+// power on several times.
+// [RootCause] The device sometime doesn't respond the set report
+// command.
+// [Solution] Change the timeout of set report command to 100 ms.
+// [Files] syskbc.c, sysnokbc.c, usbhid.c, amiusb.h
+//
+// 27 4/23/14 10:59p Wilsonlee
+// [TAG] EIP158723
+// [Category] Improvement
+// [Description] It sends set idle command before getting report
+// descriptor command.
+// [Files] usbhid.c
+//
+// 26 2/26/14 1:56a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 25 11/05/13 5:38a Ryanchou
+// [TAG] EIP139807
+// [Category] Improvement
+// [Description] Handle the 4 bytes of item size.
+// [Files] usbhid.c
+//
+// 24 10/19/13 7:07a Ryanchou
+// [TAG] EIP138257
+// [Category] Improvement
+// [Description] Correct USB HID device type.
+// [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c
+//
+// 23 9/04/13 11:56p Ryanchou
+// [TAG] N/A
+// [Category] Improvement
+// [Description] Add usage page check for HID set feature request.
+// [Files] usbhid.c
+//
+// 22 7/04/13 5:48a Roberthsu
+// [TAG] EIP127014
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse drifting not smooth
+// [RootCause] Bbecause Efi simple point protocol RelativeMovementX
+// type is INT32.
+// [Solution] Transfer data type to INT32.
+// [Files] usbdef.h,usbhid.c,usbms.c,usbkbd.h
+//
+// 21 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 20 3/07/13 8:52a Ryanchou
+// [TAG] EIP113218
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB keyboard cannot work after ownership change back to
+// BIOS
+// [RootCause] The key repeat SMI does not generated because the HC is
+// stopped.
+// [Solution] Use the other HC to generate key repeat SMI
+// [Files] usb.c, usbhid.c, usbkbd.c
+//
+// 19 1/11/13 4:15a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 18 11/29/12 7:47a Ryanchou
+// [TAG] EIP107586
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Unplug USB keyboard does not uninstall EFI USB keyboard
+// driver properly
+// [RootCause] The EIP99431 changes clear DEV_INFO.bSubDeviceType in
+// runtime keyboard driver, that cause EFI keyboard driver does not know
+// what type of the device is.
+// [Solution] Do not clear DEV_INFO.bSubDeviceType in runtime keyboard
+// driver.
+// [Files] usb.c, usbhid.c, efiusbhid.c
+//
+// 17 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 16 10/26/12 8:50a Roberthsu
+// [TAG] EIP101990
+// [Category] Improvement
+// [Description] Add check inpurt mode.
+// [Files] usbhid.c,usbpoint.c
+//
+// 15 8/27/12 5:07a Roberthsu
+// [TAG] EIP98251
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] RF KB NumLock/ScrollLock/CapsLock indicator is not
+// available during post or BIOS setup menu
+// [RootCause] Set led command lost report id.
+// [Solution] Check report id exist.
+// [Files] syskbc.c,usbhid.c
+//
+// 14 8/13/12 3:24a Roberthsu
+// [TAG] EIP96010
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The KB can not work under bios.
+// [RootCause] Usage count overflow.
+// [Solution] Add usage count check.
+// [Files] usbdef.h,usbhid.c
+//
+// 13 5/04/12 2:37a Roberthsu
+// [TAG] EIP89279
+// [Category] Improvement
+// [Description] Add check totalcount condition.
+// [Files] usbhid.c
+//
+// 12 5/03/12 6:25a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 11 4/24/12 3:52a Roberthsu
+// [TAG] EIP84336
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When insert the touch board, it will block the function
+// of rear USB ports.
+// [RootCause] Report buffer size not enough.
+// [Solution] Create Report buffer by report item count.
+// [Files] usbhid.c
+//
+// 10 4/05/12 7:42a Wilsonlee
+// [TAG] EIP86001
+// [Category] Improvement
+// [Description] Free the chunk of memory allocated using the
+// USBMem_Alloc call when we didn't use it.
+// [Files] usbhid.c, ehci.c
+//
+// 9 4/03/12 5:52a Roberthsu
+// [TAG] EIP80948
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When insert the touch board, it will block the function
+// of rear USB ports.
+// [RootCause] Report item not enough.
+// [Solution] Create buffer use report length.
+// [Files] usbhid.c,usbdef.h
+//
+// 8 3/23/12 4:28a Roberthsu
+// [TAG] EIP84264
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] After updating usb module, system will hang at BIOS
+// LOGO display.
+// [RootCause] Allocate memory not enough.
+// [Solution] Allocate memory by report length
+// [Files] usbhid.c
+//
+// 7 12/14/11 2:12a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 6 10/21/11 2:35a Roberthsu
+// [TAG] EIP71068
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Thermaltake mouse is not work
+// [RootCause] Because some undefine usage page report.
+// [Solution] Get all input report.
+// [Files] usbhid.c
+//
+// 5 9/27/11 1:41a Roberthsu
+// [TAG] EIP67400
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Microsoft wireless Media Desktop 1000 can¡¦t work normal.
+// [RootCause] Wireless ms report data contains usage page keyboard.And
+// output data not contains vaild report id.
+// [Solution] Check usage page led to decide kb or ms.Check correct
+// report id with report data.
+// [Files] usbkbd.c,usbhid.c,usbms.c
+//
+// 4 9/27/11 12:05a Roberthsu
+// [TAG] EIP65344
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Razer mouse will hang in post
+// [RootCause] Razer has report keyboard interface.But not report led
+// usage.
+// [Solution] Check if not report led usage page.Do not send led
+// command.
+// [Files] syskbc.c,usbhid.c,usbdef.h
+//
+// 3 9/26/11 11:45p Roberthsu
+// [TAG] EIP67230
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ntrig touch panel can not use on CedarTrail
+// [RootCause] Because ntrig report data over than 512 byte.Control
+// transfer check if over 512 than set length is 512.
+// [Solution] Remove check transfer length.
+// [Files] ohci.c,uhci.c,usbhid.c
+//
+// 2 8/05/11 7:32a Ryanchou
+// [TAG] EIP66231
+// [Category] Improvement
+// [Description] Remove token POINT_SUPPORT.Add token USB_DEV_POINT.Add
+// check core version in point driver.Add check device descriptor to send
+// get lang id command.Modify check button usage page.
+// [Files] efiusbhid.c, efiusbpoint.c, usbbus.c, usbhid.c, usbpoint.c,
+// usbsrc.sdl
+//
+// 1 7/15/11 6:16a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: usbhid.c
+//
+// Description: USB HID class device driver
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+UINT8 UsbControlTransfer(HC_STRUC*, DEV_INFO*, DEV_REQ, UINT16, VOID*);
+
+VOID USBHIDInitialize (VOID);
+UINT8 USBHIDCheckForDevice (DEV_INFO*, UINT8, UINT8, UINT8);
+DEV_INFO* USBHIDConfigureDevice (HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT16);
+UINT8 USBHIDProcessData ( HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 USBHIDDisconnectDevice (DEV_INFO*);
+
+UINT8 HidGetReportDescriptor(HC_STRUC*, DEV_INFO*, HID_DESC*);
+
+VOID USBMSInitialize (VOID);
+DEV_INFO* USBMSConfigureDevice (HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT16);
+DEV_INFO* USBKBDConfigureDevice (DEV_INFO*); //(EIP84455)
+DEV_INFO* USBAbsConfigureDevice (HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT16);
+VOID CheckInputMode(DEV_INFO *DevInfo, HID_REPORT_FIELD * Field); //(EIP101990)
+
+VOID
+USBHIDFillDriverEntries (DEV_DRIVER *fpDevDriver)
+{
+ fpDevDriver->bDevType = BIOS_DEV_TYPE_HID;
+ fpDevDriver->bBaseClass = BASE_CLASS_HID;
+ fpDevDriver->bSubClass = 0;
+ fpDevDriver->bProtocol = 0;
+ fpDevDriver->pfnDeviceInit = USBHIDInitialize;
+ fpDevDriver->pfnCheckDeviceType = USBHIDCheckForDevice;
+ fpDevDriver->pfnConfigureDevice = USBHIDConfigureDevice;
+ fpDevDriver->pfnDisconnectDevice = USBHIDDisconnectDevice;
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBHIDInitialize (VOID)
+//
+// Description: This function returns fills the host controller driver
+// routine pointers in the structure provided
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBHIDInitialize (VOID)
+{
+ USBKBDInitialize();
+ USBMSInitialize();
+ USB_InstallCallBackFunction(USBHIDProcessData);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMSCheckForMouse
+//
+// Description: This routine checks for mouse type device from the
+// interface data provided
+//
+// Input: bBaseClass USB base class code
+// bSubClass USB sub-class code
+// bProtocol USB protocol code
+//
+// Output: BIOS_DEV_TYPE_MOUSE type on success or 0FFH on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHIDCheckForDevice (
+ DEV_INFO* fpDevInfo,
+ UINT8 bBaseClass,
+ UINT8 bSubClass,
+ UINT8 bProtocol
+)
+{
+ //
+ // Check the BaseClass, SubClass and Protocol for a HID/Boot/Mouse device.
+ //
+ if (bBaseClass != BASE_CLASS_HID) {
+ return USB_ERROR;
+ }
+
+ if ((BOOT_PROTOCOL_SUPPORT != 0) ||
+ (fpDevInfo->wIncompatFlags & USB_INCMPT_HID_BOOT_PROTOCOL_ONLY)) {
+ if (bSubClass != SUB_CLASS_BOOT_DEVICE) {
+ return USB_ERROR;
+ }
+
+ if (bProtocol != PROTOCOL_KEYBOARD &&
+ bProtocol != PROTOCOL_MOUSE) {
+ return USB_ERROR;
+ }
+ }
+
+ return BIOS_DEV_TYPE_HID;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHIDConfigureKeyboard
+//
+// Description: This routine checks an interface descriptor of the USB device
+// detected to see if it describes a HID/Boot/Keyboard device.
+// If the device matches the above criteria, then the device is
+// configured and initialized
+//
+// Input: fpHCStruc HCStruc pointer
+// fpDevInfo Device information structure pointer
+// fpDesc Pointer to the descriptor structure
+// wStart Offset within interface descriptor
+// supported by the device
+// wEnd End offset of the device descriptor
+//
+// Output: FPDEV_INFO New device info structure, 0 on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP84455+)>
+DEV_INFO*
+USBHIDConfigureDevice (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd)
+{
+ ENDP_DESC *fpEndpDesc;
+ INTRF_DESC *fpIntrfDesc;
+ UINT8 *DescEnd;
+ HID_DESC *HidDesc = NULL;
+ DEV_REQ Request = {0};
+
+ fpDevInfo->bDeviceType = (UINT8)BIOS_DEV_TYPE_HID;
+ fpDevInfo->HidDevType = 0;
+ fpDevInfo->IntInEndpoint = 0;
+ fpDevInfo->IntOutEndpoint = 0;
+
+ MemSet(&fpDevInfo->HidReport, sizeof(fpDevInfo->HidReport), 0);
+
+ USB_DEBUG(3, "USBHIDConfigureDevice... \n");
+
+ fpDevInfo->bCallBackIndex = USB_InstallCallBackFunction(USBHIDProcessData);
+
+ fpIntrfDesc = (INTRF_DESC*)(fpDesc + wStart);
+ DescEnd = fpDesc + ((CNFG_DESC*)fpDesc)->wTotalLength; // Calculate the end of descriptor block
+ fpEndpDesc = (ENDP_DESC*)((char*)fpIntrfDesc + fpIntrfDesc->bDescLength);
+
+ //Select correct endpoint
+ for (;(fpEndpDesc->bDescType != DESC_TYPE_INTERFACE) && ((UINT8*)fpEndpDesc < DescEnd);
+ fpEndpDesc = (ENDP_DESC*)((UINT8 *)fpEndpDesc + fpEndpDesc->bDescLength)){
+ if(!(fpEndpDesc->bDescLength)) {
+ break; // Br if 0 length desc (should never happen, but...)
+ }
+
+ if (fpEndpDesc->bDescType == DESC_TYPE_HID ) {
+ HidDesc = (HID_DESC*)fpEndpDesc;
+ continue;
+ }
+
+ if (fpEndpDesc->bDescType != DESC_TYPE_ENDPOINT ) {
+ continue;
+ }
+
+ //
+ // Check for and configure Interrupt endpoint if present
+ //
+ if ((fpEndpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) !=
+ EP_DESC_FLAG_TYPE_INT) { // Bit 1-0: 10 = Endpoint does interrupt transfers
+ continue;
+ }
+ if (fpEndpDesc->bEndpointAddr & EP_DESC_ADDR_DIR_BIT) {
+ if (fpDevInfo->IntInEndpoint == 0) {
+ fpDevInfo->IntInEndpoint = fpEndpDesc->bEndpointAddr;
+ fpDevInfo->IntInMaxPkt = fpEndpDesc->wMaxPacketSize;
+ fpDevInfo->bPollInterval = fpEndpDesc->bPollInterval;
+ }
+ } else {
+ if (fpDevInfo->IntOutEndpoint == 0) {
+ fpDevInfo->IntOutEndpoint = fpEndpDesc->bEndpointAddr;
+ fpDevInfo->IntOutMaxPkt = fpEndpDesc->wMaxPacketSize;
+ }
+ }
+ }
+
+ if (fpDevInfo->IntInEndpoint == 0) {
+ return 0;
+ }
+
+ //Set protocol (Option)
+ if ((BOOT_PROTOCOL_SUPPORT != 0) &&
+ !(fpDevInfo->wIncompatFlags & USB_INCMPT_SET_BOOT_PROTOCOL_NOT_SUPPORTED) ||
+ (fpDevInfo->wIncompatFlags & USB_INCMPT_HID_BOOT_PROTOCOL_ONLY)) {
+ //
+ // Send the set protocol command, wValue = 0 (Boot protocol)
+ //
+ Request.wRequestType = HID_RQ_SET_PROTOCOL;
+ Request.wValue = 0; // 0: Boot Protocol
+ Request.wIndex = fpDevInfo->bInterfaceNum;
+ Request.wDataLength = 0;
+
+ UsbControlTransfer(fpHCStruc, fpDevInfo, Request, 100, NULL);
+ }
+
+ //Send Set_Idle command
+ Request.wRequestType = HID_RQ_SET_IDLE;
+ Request.wValue = 0;
+ Request.wIndex = fpDevInfo->bInterfaceNum;
+ Request.wDataLength = 0;
+
+ UsbControlTransfer(fpHCStruc, fpDevInfo, Request, 100, NULL);
+
+ if ((BOOT_PROTOCOL_SUPPORT == 0) &&
+ !(fpDevInfo->wIncompatFlags & USB_INCMPT_HID_BOOT_PROTOCOL_ONLY)) {
+ HidGetReportDescriptor(fpHCStruc, fpDevInfo, HidDesc);
+ fpDevInfo->HidReport.Flag |= HID_REPORT_FLAG_REPORT_PROTOCOL;
+ if (fpDevInfo->PollingLength < fpDevInfo->IntInMaxPkt) {
+ fpDevInfo->PollingLength = fpDevInfo->IntInMaxPkt;
+ }
+ } else {
+ fpDevInfo->PollingLength = fpDevInfo->IntInMaxPkt;
+ switch (fpDevInfo->bProtocol) {
+ case PROTOCOL_KEYBOARD:
+ fpDevInfo->HidDevType = HID_DEV_TYPE_KEYBOARD;
+ break;
+
+ case PROTOCOL_MOUSE:
+ fpDevInfo->HidDevType = HID_DEV_TYPE_MOUSE;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (fpDevInfo->HidDevType & HID_DEV_TYPE_KEYBOARD) {
+ if (!(USBKBDConfigureDevice(fpDevInfo))) {
+ return 0;
+ }
+ }
+
+//Active polling
+ if ((fpDevInfo->PollingLength != 0) && (fpDevInfo->bPollInterval != 0)) {
+ if (!((fpDevInfo->HidDevType & HID_DEV_TYPE_MOUSE) && (gUsbData->dUSBStateFlag & USB_FLAG_EFIMS_DIRECT_ACCESS))) {
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDActivatePolling)(fpHCStruc,fpDevInfo);
+ }
+ }
+
+
+ return fpDevInfo;
+}
+ //<(EIP84455+)
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBHIDDisconnectDevice
+//
+// Description: This routine disconnects the keyboard by freeing
+// the USB keyboard device table entry
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+//
+// Output: USB_SUCCESS/USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHIDDisconnectDevice (
+ DEV_INFO *DevInfo
+)
+{
+ HC_STRUC *HcStruc = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+ UINT16 Index;
+
+ // Stop polling the endpoint
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDDeactivatePolling)(HcStruc, DevInfo);
+ DevInfo->IntInEndpoint = 0;
+
+ if (DevInfo->HidDevType & HID_DEV_TYPE_KEYBOARD) {
+ USBKBDDisconnectDevice(DevInfo);
+ }
+
+ if (DevInfo->HidReport.Fields != NULL) {
+ for (Index = 0; Index < DevInfo->HidReport.FieldCount; Index++) {
+ if (DevInfo->HidReport.Fields[Index]->Usages != NULL) {
+ USB_MemFree(DevInfo->HidReport.Fields[Index]->Usages,
+ GET_MEM_BLK_COUNT(DevInfo->HidReport.Fields[Index]->UsageCount * sizeof(UINT16)));
+ DevInfo->HidReport.Fields[Index]->Usages = NULL;
+ }
+ USB_MemFree(DevInfo->HidReport.Fields[Index], GET_MEM_BLK_COUNT(sizeof(HID_REPORT_FIELD)));
+ DevInfo->HidReport.Fields[Index] = NULL;
+ }
+
+ USB_MemFree(DevInfo->HidReport.Fields, GET_MEM_BLK_COUNT(DevInfo->HidReport.FieldCount * sizeof(HID_REPORT_FIELD*)));
+ DevInfo->HidReport.Fields = NULL;
+ DevInfo->HidReport.ReportDescLen = 0;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: ExtractInputReportData
+//
+// Description:
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+ExtractInputReportData (
+ UINT8 *Report,
+ UINT16 Offset,
+ UINT16 Size
+)
+{
+ UINT32 *Start;
+ UINT8 BitOffset;
+ UINT32 Data = 0;
+
+ ASSERT(Data <= 32);
+ Start = (UINT32*)((UINTN)Report + (Offset >> 3));
+ BitOffset = Offset & 0x7;
+ Data = (*Start >> BitOffset) & ((0x1 << Size) - 1);
+ return Data;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: GetItemData
+//
+// Description: This funtion copy data of the item to buffer.
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+GetItemData (
+ HID_ITEM *Item,
+ VOID *Buffer,
+ UINT32 BufferSize
+)
+{
+ UINT32 Size = Item->bSize > BufferSize ? BufferSize : Item->bSize;
+ MemSet(Buffer, BufferSize, 0);
+ MemCpy(Buffer, &Item->data, Size);
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: AddUsage
+//
+// Description: This funtion adds usage into usage table.
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+AddUsage (
+ HID_REPORT_FIELD *Field,
+ UINT16 Usage
+)
+{
+ if (Field->UsageCount >= Field->MaxUsages) {
+ return;
+ }
+
+ Field->Usages[Field->UsageCount++] = Usage;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: Add_Hid_Field
+//
+// Description: Add input or output item.
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP84455+)>
+VOID
+AddField (
+ HID_REPORT *Report,
+ HID_REPORT_FIELD *Field
+)
+{
+ HID_REPORT_FIELD *NewField;
+ HID_REPORT_FIELD **Fields;
+ UINT16 Index;
+
+ NewField = USB_MemAlloc(GET_MEM_BLK_COUNT(sizeof(HID_REPORT_FIELD)));
+ ASSERT(NewField != NULL);
+ if (NewField == NULL) {
+ return;
+ }
+
+ if (Field->ReportId != 0) {
+ Report->Flag |= HID_REPORT_FLAG_REPORT_ID;
+ }
+
+ MemCpy(NewField, Field, sizeof(HID_REPORT_FIELD));
+ NewField->Usages = NULL;
+
+ USB_DEBUG(4, "============================================== \n");
+ USB_DEBUG(4, "Field index = %02x, \t", Report->FieldCount);
+ USB_DEBUG(4, "Flag = %02x\n", NewField->Flag);
+ USB_DEBUG(4, "UsagePage = %4x, \t", NewField->UsagePage);
+ USB_DEBUG(4, "ReportId = %02x\n", NewField->ReportId);
+ USB_DEBUG(4, "ReportCount = %02x, \t", NewField->ReportCount);
+ USB_DEBUG(4, "bReportSize = %02x\n", NewField->ReportSize);
+ USB_DEBUG(4, "LogicalMin = %4x, \t", NewField->LogicalMin);
+ USB_DEBUG(4, "LogicalMax = %4x\n", NewField->LogicalMax);
+ USB_DEBUG(4, "PhysicalMax = %4x, \t", NewField->PhysicalMax);
+ USB_DEBUG(4, "PhysicalMin = %4x\n", NewField->PhysicalMin);
+ USB_DEBUG(4, "UnitExponent = %2x, \t", NewField->UnitExponent);
+ USB_DEBUG(4, "UsageCount = %4x\n", NewField->UsageCount);
+
+ if (NewField->UsageCount != 0) {
+ NewField->Usages = USB_MemAlloc (GET_MEM_BLK_COUNT(NewField->UsageCount * sizeof(UINT16)));
+ ASSERT(NewField->Usages != NULL);
+ if (NewField->Usages == NULL) {
+ return;
+ }
+
+ MemCpy(NewField->Usages, Field->Usages, NewField->UsageCount * sizeof(UINT16));
+
+ USB_DEBUG(4, "Usages:\n");
+ for (Index = 0; Index < NewField->UsageCount; Index++) {
+ if ((NewField->UsagePage == 0x01) && (NewField->Usages[Index] == 0x30)) {
+ if (NewField->Flag & HID_REPORT_FIELD_FLAG_RELATIVE) {
+ Report->Flag |= HID_REPORT_FLAG_RELATIVE_DATA;
+ } else {
+ Report->Flag |= HID_REPORT_FLAG_ABSOLUTE_DATA;
+ }
+ Report->AbsMaxX = NewField->LogicalMax;
+ }
+ if (NewField->Usages[Index] == 0x31) {
+ Report->AbsMaxY= NewField->LogicalMax;
+ }
+ USB_DEBUG(4, "%02X ", NewField->Usages[Index]);
+ if ((Index & 0xF) == 0xF) {
+ USB_DEBUG(4, "\n");
+ }
+ }
+ }
+ USB_DEBUG(4, "\n============================================== \n");
+
+ Fields = USB_MemAlloc(GET_MEM_BLK_COUNT((Report->FieldCount + 1) * sizeof(HID_REPORT_FIELD*)));
+ ASSERT(Fields != NULL);
+ if (Fields == NULL) {
+ return;
+ }
+
+ if (Report->Fields != NULL) {
+ MemCpy(Fields, Report->Fields, Report->FieldCount * sizeof(HID_REPORT_FIELD*));
+ USB_MemFree(Report->Fields, GET_MEM_BLK_COUNT(Report->FieldCount * sizeof(HID_REPORT_FIELD*)));
+ }
+
+ Report->Fields = Fields;
+ Report->Fields[Report->FieldCount++] = NewField;
+
+ return;
+}
+ //<(EIP84455+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: HidParserMain
+//
+// Description:
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+HidParserMain (
+ DEV_INFO *DevInfo,
+ HID_REPORT_FIELD *Field,
+ HID_ITEM *Item
+)
+{
+ UINT8 Data = 0;
+ //(EIP71068)>
+ switch (Item->bTag) {
+ case HID_MAIN_ITEM_TAG_BEGIN_COLLECTION:
+ GetItemData(Item, &Data, sizeof(Data));
+
+ // Check if it is application collection
+ if (Data == 0x01) {
+ if (Field->UsagePage == 0x01) { // Generic Desktop
+ switch (Field->Usages[Field->UsageCount - 1]) {
+ case 0x01: // Pointer
+ case 0x02: // Mouse
+ DevInfo->HidDevType |= HID_DEV_TYPE_MOUSE;
+ break;
+ case 0x06: // Keyboard
+ case 0x07: // KeyPad
+ DevInfo->HidDevType |= HID_DEV_TYPE_KEYBOARD;
+ break;
+ default:
+ break;
+ }
+ } else if (Field->UsagePage == 0x0D) { // Digitizer
+ if (Field->Usages[Field->UsageCount - 1] == 0x04) {
+ DevInfo->HidDevType |= HID_DEV_TYPE_POINT;
+ }
+ }
+ }
+ break;
+
+ case HID_MAIN_ITEM_TAG_END_COLLECTION:
+ break;
+
+ case HID_MAIN_ITEM_TAG_INPUT:
+ GetItemData(Item, &Field->Flag, sizeof(Field->Flag));
+ Field->Flag = (Field->Flag & 7) | HID_REPORT_FIELD_FLAG_INPUT;
+
+ // Microstep USB Keyboard (Sonix Technology Co chip) workaround
+ // The report descriptor has an error, Modifier keys is bitmap data, but
+ // it reports as array data. We force variable flag for Modifier keys input item.
+ if ((DevInfo->wVendorId == 0x0C45) &&
+ ((DevInfo->wDeviceId == 0x7603) || (DevInfo->wDeviceId == 0x7624))) {
+ if ((Field->UsagePage == HID_UP_KEYBOARD) &&
+ (Field->UsageMin == HID_UP_KEYBOARD_LEFT_CTRL) &&
+ (Field->UsageMax == HID_UP_KEYBOARD_RIGHT_GUI)) {
+ Field->Flag |= HID_REPORT_FIELD_FLAG_VARIABLE;
+ }
+ }
+
+ AddField(&DevInfo->HidReport, Field);
+ break;
+
+ case HID_MAIN_ITEM_TAG_OUTPUT:
+ GetItemData(Item, &Field->Flag, sizeof(Field->Flag));
+ Field->Flag &= 7;
+ //(EIP98251+)>
+ if (Field->UsagePage == 0x8) {
+ AddField(&DevInfo->HidReport, Field);
+ } //<(EIP98251+)
+ break;
+
+ case HID_MAIN_ITEM_TAG_FEATURE:
+ CheckInputMode(DevInfo, Field); //(EIP101990)
+ break;
+
+ default:
+ break;
+ }
+ //<(EIP71068)
+ //(EIP84455+)>
+//Clear Local Item
+ MemSet(Field->Usages, Field->UsageCount * sizeof(UINT16), 0);
+ Field->UsageCount = 0;
+ Field->UsageMin = 0;
+ Field->UsageMax = 0;
+
+ //<(EIP84455+)
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: HidParserGlobal
+//
+// Description: Parsing Global item
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+HidParserGlobal (
+ DEV_INFO *DevInfo,
+ HID_REPORT_FIELD *Field,
+ HID_ITEM *Item
+)
+{
+ switch (Item->bTag) {
+ case HID_GLOBAL_ITEM_TAG_USAGE_PAGE:
+ GetItemData(Item, &Field->UsagePage, sizeof(Field->UsagePage));
+ //(EIP65344+)>
+ //Get Led usage page
+ if (Field->UsagePage == 0x8) {
+ DevInfo->HidReport.Flag |= HID_REPORT_FLAG_LED_FLAG;
+ }
+ //<(EIP65344+)
+ break;
+
+ case HID_GLOBAL_ITEM_TAG_LOGICAL_MINIMUM:
+ GetItemData(Item, &Field->LogicalMin, sizeof(Field->LogicalMin));
+ break;
+
+ case HID_GLOBAL_ITEM_TAG_LOGICAL_MAXIMUM:
+ GetItemData(Item, &Field->LogicalMax, sizeof(Field->LogicalMax));
+ break;
+ //(EIP127014+)>
+ case HID_GLOBAL_ITEM_TAG_PHYSICAL_MINIMUM:
+ GetItemData(Item, &Field->PhysicalMin, sizeof(Field->PhysicalMin));
+ break;
+
+ case HID_GLOBAL_ITEM_TAG_PHYSICAL_MAXIMUM:
+ GetItemData(Item, &Field->PhysicalMax, sizeof(Field->PhysicalMax));
+ break;
+
+ case HID_GLOBAL_ITEM_TAG_UNIT_EXPONENT:
+ GetItemData(Item, &Field->UnitExponent, sizeof(Field->UnitExponent));
+ break;
+ //<(EIP127014+)
+ case HID_GLOBAL_ITEM_TAG_REPORT_SIZE:
+ GetItemData(Item, &Field->ReportSize, sizeof(Field->ReportSize));
+ break;
+
+ case HID_GLOBAL_ITEM_TAG_REPORT_COUNT:
+ GetItemData(Item, &Field->ReportCount, sizeof(Field->ReportCount));
+ break;
+
+ case HID_GLOBAL_ITEM_TAG_REPORT_ID:
+ GetItemData(Item, &Field->ReportId, sizeof(Field->ReportId));
+ break;
+
+ default:
+ break;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: HidParserLocal
+//
+// Description: Parsing Local item
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+HidParserLocal (
+ DEV_INFO *DevInfo,
+ HID_REPORT_FIELD *Field,
+ HID_ITEM *Item
+)
+{
+ UINT32 Data;
+
+ GetItemData(Item, &Data, sizeof(Data));
+
+ switch (Item->bTag) {
+ case HID_LOCAL_ITEM_TAG_USAGE:
+ AddUsage(Field, Data);
+ break;
+
+ case HID_LOCAL_ITEM_TAG_USAGE_MINIMUM:
+ Field->UsageMin = Data;
+ break;
+
+ case HID_LOCAL_ITEM_TAG_USAGE_MAXIMUM:
+ Field->UsageMax = Data;
+
+ // Medigenic-Esterline USB keboard (Advanced Input Devices chip)
+ // workaround. This device reports the wrong local minimum for
+ // keyboard data in its report descriptor, local minimum should be 0x00.
+
+ if ((DevInfo->wVendorId == 0x059d) && (DevInfo->wDeviceId == 0x0708)) {
+ if ((Field->UsageMin == 0x01) && (Field->UsageMax == 0x65)) {
+ Field->UsageMin = 0x00;
+ }
+ }
+
+ for (Data = Field->UsageMin; Data <= Field->UsageMax; Data++) {
+ AddUsage(Field, Data);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: HidParserReserved
+//
+// Description: Parsing Reserved item
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+HidParserReserved(
+ DEV_INFO *DevInfo,
+ HID_REPORT_FIELD *Field,
+ HID_ITEM *Item
+)
+{
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: HidParseReportDescriptor
+//
+// Description:
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+HidParseReportDescriptor (
+ DEV_INFO *DevInfo,
+ UINT8 *ReportDesc
+)
+{
+ HID_REPORT *Report = &DevInfo->HidReport;
+ UINT8 *Start = ReportDesc;
+ UINT8 *End = Start + Report->ReportDescLen;
+ UINT16 Usages[0x300] = {0};
+ HID_REPORT_FIELD Field = {0};
+ HID_ITEM Item = {0};
+ UINT8 Data;
+ UINT8 DataSize[] = {0, 1, 2, 4};
+
+ static UINT8 (*DispatchType[]) (DEV_INFO *DevInfo,
+ HID_REPORT_FIELD *Field, HID_ITEM *Item) = {
+ HidParserMain,
+ HidParserGlobal,
+ HidParserLocal,
+ HidParserReserved
+ };
+
+ Field.Usages = Usages;
+ Field.MaxUsages = COUNTOF(Usages);
+
+ while (Start < End) {
+ Data = *Start++;
+
+ Item.bType = (Data >> 2) & 0x3;
+ Item.bTag = (Data >> 4) & 0xF;
+ Item.bSize = DataSize[Data & 0x3];
+
+ if ((Start + Item.bSize) > End) {
+ break;
+ }
+
+ MemCpy(&Item.data.u32, Start, Item.bSize);
+ Start += Item.bSize;
+ DispatchType[Item.bType](DevInfo, &Field, &Item);
+ }
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: CalculateInputReportDataLength
+//
+// Description: This function calculates max data length to be reported
+// in the HID device.
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+CalculateInputReportDataLength (
+ DEV_INFO *DevInfo
+)
+{
+ UINT8 Index = 0;
+ HID_REPORT_FIELD *Field = NULL;
+ UINT16 ReportLen[256] = {0};
+ UINT16 Length = 0;
+ UINT16 MaxLength = 0;
+ UINT16 ReportId = 0;
+
+ for (Index = 0; Index < DevInfo->HidReport.FieldCount; Index++) {
+ Field = DevInfo->HidReport.Fields[Index];
+ if (!(Field->Flag & HID_REPORT_FIELD_FLAG_INPUT)) {
+ continue;
+ }
+
+ ReportId = Field->ReportId;
+ ReportLen[ReportId] += Field->ReportCount * Field->ReportSize;
+ }
+
+ for (ReportId = 0; ReportId < COUNTOF(ReportLen); ReportId++) {
+ if (ReportLen[ReportId] == 0) {
+ continue;
+ }
+
+ Length = (ReportLen[ReportId] + 7) >> 3;
+ if (ReportId != 0) {
+ Length++;
+ }
+
+ MaxLength = MaxLength < Length ? Length : MaxLength;
+ }
+
+ return MaxLength;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: HidGetReportDescriptor
+//
+// Description:
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+HidGetReportDescriptor(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ HID_DESC *HidDesc
+)
+{
+ UINT8 *ReportDesc = NULL;
+ UINT8 Index = 0;
+ UINT8 Status = USB_ERROR;
+ DEV_REQ Request = {0};
+
+ if (HidDesc == NULL) {
+ return USB_ERROR;
+ }
+
+ if (HidDesc->bDescriptorLength == 0) {
+ return USB_SUCCESS;
+ }
+
+ ReportDesc = USB_MemAlloc(GET_MEM_BLK_COUNT(HidDesc->bDescriptorLength));
+ if (ReportDesc == NULL) {
+ return USB_ERROR;
+ }
+
+ Request.wRequestType = HID_RQ_GET_DESCRIPTOR;
+ Request.wValue = DESC_TYPE_REPORT << 8;
+ Request.wIndex = DevInfo->bInterfaceNum;
+ Request.wDataLength = HidDesc->bDescriptorLength;
+
+ for (Index = 0; Index < 3; Index++) {
+ Status = UsbControlTransfer(HcStruc, DevInfo, Request, USB_GET_REPORT_DESC_TIMEOUT_MS, ReportDesc);
+ if (Status == USB_SUCCESS) {
+ break;
+ }
+ }
+
+ DevInfo->HidReport.ReportDescLen = HidDesc->bDescriptorLength ;
+ HidParseReportDescriptor(DevInfo, ReportDesc);
+ DevInfo->PollingLength = CalculateInputReportDataLength(DevInfo);
+
+ USB_MemFree(ReportDesc, GET_MEM_BLK_COUNT(HidDesc->bDescriptorLength));
+ return USB_SUCCESS;
+}
+ //(EIP84455+)>
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: USBHIDProcessData
+//
+// Description:
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHIDProcessData(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ UINT8 DataType = 0;
+ UINT8 i;
+ UINT16 j;
+ HID_REPORT_FIELD *Field = NULL;
+
+ DataType = DevInfo->bProtocol;
+
+ if (DevInfo->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) {
+ for (i = 0; i < DevInfo->HidReport.FieldCount; i++) {
+ Field = DevInfo->HidReport.Fields[i];
+
+ //Check is input?
+ if (!(Field->Flag & HID_REPORT_FIELD_FLAG_INPUT)) {
+ continue;
+ }
+ //if report id exist, check first byte
+ if (Field->ReportId != 0 && Field->ReportId != Buffer[0]) {
+ continue;
+ }
+
+ if (Field->UsagePage == 7) {
+ DataType = HID_BTYPE_KEYBOARD;
+ }
+ //Check X,Y
+ if ((Field->UsagePage == 1) && (Field->UsageCount != 0)) {
+ for (j = 0; j < Field->UsageCount; j++) {
+ //find X
+ if (Field->Usages[j] == 0x30) {
+ if (Field->Flag & HID_REPORT_FIELD_FLAG_RELATIVE) {
+ DataType = HID_BTYPE_MOUSE;
+ } else {
+ DataType = HID_BTYPE_POINT;
+ }
+ }
+
+ }
+ }
+ }
+ }
+
+ switch(DataType) {
+ case HID_BTYPE_KEYBOARD:
+ USBKBDProcessKeyboardData(HcStruc, DevInfo, Td, Buffer, DataLength);
+ break;
+ case HID_BTYPE_MOUSE:
+ USBMSProcessMouseData(HcStruc, DevInfo, Td, Buffer, DataLength);
+ break;
+ case HID_BTYPE_POINT:
+ USBAbsProcessMouseData(HcStruc, DevInfo, Td, Buffer, DataLength);
+ break;
+ default:
+ break;
+ }
+ return USB_SUCCESS;
+}
+ //<(EIP84455+)
+
+ //(EIP101990+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Input: CheckInputMode
+//
+// Description:
+//
+// intput:
+//
+// Output:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID
+CheckInputMode(
+ DEV_INFO *DevInfo,
+ HID_REPORT_FIELD *Field
+)
+{
+ HC_STRUC *HcStruc = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+ DEV_REQ Request = {0};
+ UINT8 *Buffer;
+ UINT16 Index;
+
+ for (Index = 0; Index < Field->UsageCount; Index++) {
+ if (Field->UsagePage == 0xd) {
+ if (Field->Usages[Index] == 0x52 && Field->Usages[Index + 1] == 0x53) {
+ Request.wRequestType = HID_RQ_SET_REPORT;
+ Request.wValue = (0x03 << 8) | Field->ReportId;
+ Request.wIndex = DevInfo->bInterfaceNum;
+ Request.wDataLength = 3;
+
+ Buffer = USB_MemAlloc (1);
+ Buffer[0] = Field->ReportId;
+ Buffer[1] = 2;
+ Buffer[2] = 0;
+
+ UsbControlTransfer(HcStruc, DevInfo, Request, 100, Buffer);
+
+ USB_MemFree(Buffer, 1);
+ break;
+ }
+ }
+ }
+}
+ //<(EIP101990+)
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
diff --git a/Core/EM/usb/rt/usbhub.c b/Core/EM/usb/rt/usbhub.c
new file mode 100644
index 0000000..dda111d
--- /dev/null
+++ b/Core/EM/usb/rt/usbhub.c
@@ -0,0 +1,1491 @@
+ //****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbhub.c 54 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 54 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbhub.c $
+//
+// 54 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 53 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 52 9/01/15 10:17p Wilsonlee
+// [TAG] EIP235482
+// [Category] Improvement
+// [Description] Select this alternate setting for multiple TTs hubs.
+// [Files] usbhub.c, usb.c, amiusb.h, usbdef.h
+//
+// 51 5/11/15 4:32a Wilsonlee
+// [TAG] EIP216986
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BIOS can't find Realtek usb Lan dongle if this device is in
+// some hubs.
+// [RootCause] USB 3.0 hub may not set Connect Status Change bit.
+// [Solution] Set the connect change flag if the BH Reset change or
+// Reset change is set.
+// [Files] usbhub.c
+//
+// 50 2/24/15 10:33p Wilsonlee
+// [TAG] EIP204948
+// [Category] Improvement
+// [Description] Reset the port if the link is Inactive.
+// [Files] usbhub.c
+//
+// 49 2/05/15 5:46a Wilsonlee
+// [TAG] EIP202436
+// [Category] Improvement
+// [Description] Issues a SetPortFeature(PORT_POWER) request for hub
+// ports over-current recovery.
+// [Files] usbhub.c
+//
+// 48 1/22/15 10:19p Wilsonlee
+// [TAG] EIP201434
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Number of connected devices isn't correct if we plug out
+// keyboards or mice behind hub in xhci.
+// [RootCause] The PortConnectChange bit is cleared when we check port
+// status for interrupt endpoint transaction error.
+// [Solution] Don't clear change bits if we check port status for
+// interrupt endpoint transaction error.
+// [Files] xhci.c, usbhub.c, usbdef.h, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusbhc.c
+//
+// 47 6/20/14 3:14a Wilsonlee
+// [TAG] EIP173968
+// [Category] Improvement
+// [Description] Use MaxPacketSize of hubs to poll data for the device
+// compatibility issue.
+// [Files] usbhub.c
+//
+// 46 5/01/14 3:38a Ryanchou
+// [TAG] EIP165208
+// [Category] Improvement
+// [Description] Add 20 ms delay after port reset completed.
+// [Files] usbhub.c
+//
+// 45 4/30/14 6:15a Ryanchou
+// [TAG] EIP151374
+// [Category] Improvement
+// [Description] Calculates maximum data length to be reported in the
+// HID device.
+// [Files] ehci.c, ohci.c, uhci.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, xhci.c
+//
+// 44 2/26/14 1:55a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 43 11/26/13 4:18a Ryanchou
+// [TAG] EIP143124
+// [Category] Improvement
+// [Description] Added 1 ms delay after HUB port reset.
+// [Files] usbhub.c
+//
+// 42 11/26/13 1:25a Wilsonlee
+// [TAG] EIP143251
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The usb mouse lost if it behinds TI TUSB8040A1 hub under
+// BIOS.
+// [RootCause] The device may connect later, then we clear connect
+// change without setting the device is connected.
+// [Solution] Don't get port status again before we clear the changes.
+// [Files] usb.c, usbhub.c
+//
+// 41 7/22/13 10:31p Wilsonlee
+// [TAG] EIP125357
+// [Category] Improvement
+// [Description] Check if the port releases to a select host controller.
+// [Files] uhci.c, usb.c, usbhub.c, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 40 6/30/13 11:40p Wilsonlee
+// [TAG] EIP121374
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB flash is not recognized after re-plugged on DOS.
+// [RootCause] Some devices need to wait for that they are being settle.
+// [Solution] Delay for 50 ms allowing port to settle when pluged in
+// devices.
+// [Files] usbhub.c, usbdef.h
+//
+// 39 3/19/13 3:58a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 38 3/18/13 4:49a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 37 1/23/13 4:05a Wilsonlee
+// [TAG] EIP111239
+// [Category] Improvement
+// [Description] Handle the recovery state of the devces which are
+// behind the USB3 hub.
+// [Files] usbhub.c
+//
+// 36 1/11/13 4:15a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 35 12/07/12 3:04a Ryanchou
+//
+// 34 11/10/12 7:03a Ryanchou
+// [TAG] EIP103966
+// [Category] Improvement
+// [Description] Always issue set port power request to HiSpeed USB hub.
+// [Files] usbhub.c
+//
+// 33 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 32 9/28/12 2:39a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 31 5/03/12 6:26a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 30 3/04/12 4:40a Wilsonlee
+// [TAG] EIP77526
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] BBS is not correct to detect BMC's USB virtual device
+// [RootCause] It is failed to sets port feature for resetting hub
+// ports.
+// [Solution] We enlarge the timeout value for setting port feature.
+// [Files] usbhub.c
+//
+// 29 8/08/11 5:18a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 28 6/21/11 11:04a Ryanchou
+// [TAG] EIP59579
+// [Category] Improvement
+// [Description] USB device information structure should be reserved for
+// the UsbIO to use even install driver fail.
+// [Files] usbmass.c, usbkbd.c, usbhub.c
+//
+// 27 3/30/11 8:14a Ryanchou
+// [TAG] EIP54126
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Sometimes system hangs at checkpoint 0xB4.
+// [RootCause] The bLength field of configuration descriptor is zero.
+// [Solution] Check wether bLength field is zero before paring next
+// descriptor.
+// [Files] usb.c, usbbus.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c
+//
+// 26 3/29/11 10:56p Ryanchou
+// [TAG] EIP55401
+// [Category] Improvement
+// [Description] Improve the USB 3.0 device compatibility.
+// [Files] ehci.c, ehci.h, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c,
+// xhci.c
+//
+// 25 2/22/11 5:07a Ryanchou
+// [TAG] EIP53108
+// [Category] Improvement
+// [Description] Change the order of the request "Set Hub Depth".
+// [Files] usbhub.c
+//
+// 24 2/18/11 1:50a Ryanchou
+// [TAG] EIP52299
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB device can't detected after warm reset.
+// [RootCause] If configure device fail first time, the connect status
+// change will be clear, and second time port reset will not be issued.
+// [Solution] Remove check connect status change.
+// [Files] usbhub.c
+//
+// 23 11/11/10 11:37p Ryanchou
+// [TAG] EIP45578
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB 3.0 device can't be detected.
+// [RootCause] Address Device Command fails.
+// [Solution] Reset the device and attempt the Address Device Command
+// again.
+// [Files] ehci.c, ohci.c, uhci.c, usb.c, usbdef.h, usbhub.c, xhci.c
+//
+// 22 10/20/10 10:24a Ryanchou
+// EIP44702: Added USB 3.0 hub support.
+//
+// 21 9/24/10 5:38p Olegi
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 20 7/13/10 5:10a Ryanchou
+// EIP39838: Fixed configure USB hub fail.
+//
+// 19 6/28/10 2:55a Ryanchou
+// Add back 50ms delay after reseting a USB device.
+//
+// 18 6/22/10 9:30a Ryanchou
+// EIP39374: Fixed USB key hot plug issue.
+//
+// 17 4/19/10 1:53p Olegi
+//
+// 16 10/07/09 9:48a Olegi
+// USB Hub error handling improvement. EIP#25601.
+//
+// 15 5/22/09 1:47p Olegi
+// Added the special treatment for in-built hubs.
+//
+// 14 5/08/09 8:58a Olegi
+// Bugfix in USBHub_ProcessHubData.
+//
+// 13 12/16/08 10:49a Olegi
+// Correction in the return values: 0 changed to NULL. EIP#17767.
+//
+// 11 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 10 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 9 4/17/07 8:24a Olegi
+// Device detection algorythm update, in sync with Core8.
+//
+// 8 3/20/07 12:19p Olegi
+//
+// 7 12/20/06 2:30p Olegi
+//
+// 5 10/26/06 4:01p Andriyn
+//
+// 4 7/10/06 2:58p Andriyn
+// Fix: code simplifications
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 3/06/06 6:24p Olegi
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbHub.c
+//
+// Description: AMI USB Hub support implementation
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+VOID* USB_MemAlloc(UINT16);
+UINT8 USB_MemFree(void _FAR_*, UINT16);
+DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*);
+UINT8 USB_StopDevice (HC_STRUC*, UINT8, UINT8);
+VOID FixedDelay(UINTN);
+UINT8 USB_ProcessPortChange (HC_STRUC*, UINT8, UINT8, UINT8);
+UINT8 USB_InstallCallBackFunction (CALLBACK_FUNC pfnCallBackFunction);
+UINT8 USBCheckPortChange (HC_STRUC*, UINT8, UINT8);
+UINT8 UsbControlTransfer(HC_STRUC*, DEV_INFO*, DEV_REQ, UINT16, VOID*);
+
+UINT8 USBHUBDisconnectDevice (DEV_INFO*);
+UINT8 USBHub_EnablePort(HC_STRUC*, UINT8, UINT8);
+UINT8 USBHub_DisablePort(HC_STRUC*, UINT8, UINT8);
+UINT8 USBHub_ResetPort(HC_STRUC*, UINT8, UINT8);
+
+VOID UsbHubDeviceInit(VOID);
+UINT8 USBHubCheckDeviceType (DEV_INFO*, UINT8, UINT8, UINT8);
+UINT8 USBHub_ProcessHubData(HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+DEV_INFO* USBHUBConfigureDevice (HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT16);
+UINT8 UsbHubResetPort(HC_STRUC*, DEV_INFO*, UINT8, BOOLEAN);
+
+UINT8 UsbHubCearHubFeature(HC_STRUC*, DEV_INFO*, HUB_FEATURE);
+UINT8 UsbHubClearPortFeature(HC_STRUC*, DEV_INFO*, UINT8, HUB_FEATURE);
+UINT8 UsbHubGetHubDescriptor(HC_STRUC*, DEV_INFO*, VOID*, UINT16);
+UINT8 UsbHubGetHubStatus(HC_STRUC*, DEV_INFO*, UINT32*);
+UINT8 UsbHubGetPortStatus(HC_STRUC*, DEV_INFO*, UINT8, UINT32*);
+UINT8 UsbHubGetErrorCount(HC_STRUC*, DEV_INFO*, UINT8, UINT16*);
+UINT8 UsbHubSetHubDescriptor(HC_STRUC*, DEV_INFO*, VOID*, UINT16);
+UINT8 UsbHubSetHubFeature(HC_STRUC*, DEV_INFO*, HUB_FEATURE);
+UINT8 UsbHubSetHubDepth(HC_STRUC*, DEV_INFO*, UINT16);
+UINT8 UsbHubSetPortFeature(HC_STRUC*, DEV_INFO*, UINT8, HUB_FEATURE);
+
+PUBLIC
+void
+USBHubFillDriverEntries (DEV_DRIVER *fpDevDriver)
+{
+ fpDevDriver->bDevType = BIOS_DEV_TYPE_HUB;
+// fpDevDriver->bBaseClass = BASE_CLASS_HUB;
+// fpDevDriver->bSubClass = SUB_CLASS_HUB;
+ fpDevDriver->bProtocol = 0;
+ fpDevDriver->pfnDeviceInit = UsbHubDeviceInit;
+ fpDevDriver->pfnCheckDeviceType = USBHubCheckDeviceType;
+ fpDevDriver->pfnConfigureDevice = USBHUBConfigureDevice;
+ fpDevDriver->pfnDisconnectDevice = USBHUBDisconnectDevice;
+}
+
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHUBConfigureDevice
+//
+// Description: This function checks an interface descriptor of a device
+// to see if it describes a USB hub. If the device is a hub,
+// then it is configured and initialized.
+//
+// Input: pHCStruc HCStruc pointer
+// pDevInfo Device information structure pointer
+// pDesc Pointer to the descriptor structure
+// supported by the device
+// wStart Start offset of the device descriptor
+// wEnd End offset of the device descriptor
+//
+// Output: New device info structure, 0 on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBHUBConfigureDevice (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd)
+{
+ UINT8 bPortNum;
+ UINTN DelayValue;
+ UINT8* fpBuffer;
+ HUB_DESC *fpHubDesc;
+ UINT8 Status;
+ DEV_INFO* ParentHub;
+ BOOLEAN SetPortPower = FALSE;
+ ENDP_DESC *fpEndpDesc;
+ INTRF_DESC *fpIntrfDesc;
+ INTRF_DESC *AltIntrfDesc;
+ UINT16 DescLength;
+ UINT16 TotalLength;
+
+ USB3_HUB_PORT_STATUS* Usb3HubPortSts = (USB3_HUB_PORT_STATUS*)&gUsbData->dHubPortStatus;
+
+ //
+ // Set the BiosDeviceType field in DeviceTableEntry[0]. This serves as a flag
+ // that indicates a usable interface has been found in the current
+ // configuration. This is needed so we can check for other usable interfaces
+ // in the current configuration (i.e. composite device), but not try to search
+ // in other configurations.
+ //
+ fpDevInfo->bDeviceType = BIOS_DEV_TYPE_HUB;
+ fpDevInfo->bCallBackIndex = USB_InstallCallBackFunction(USBHub_ProcessHubData);
+
+ fpIntrfDesc = (INTRF_DESC*)(fpDesc + wStart);
+
+ // Check if the hub supports multiple TTs.
+ if (fpDevInfo->Flag & DEV_INFO_ALT_SETTING_IF) {
+ DescLength = wStart;
+ TotalLength = ((CNFG_DESC*)fpDesc)->wTotalLength;
+ for (;DescLength < TotalLength;) {
+ AltIntrfDesc = (INTRF_DESC*)(fpDesc + DescLength);
+ if ((AltIntrfDesc->bDescLength == 0) ||
+ ((AltIntrfDesc->bDescLength + DescLength) > TotalLength)) {
+ break;
+ }
+ if ((AltIntrfDesc->bDescType == DESC_TYPE_INTERFACE) && (AltIntrfDesc->bAltSettingNum != 0)) {
+ if ((AltIntrfDesc->bBaseClass == BASE_CLASS_HUB) &&
+ (AltIntrfDesc->bSubClass == SUB_CLASS_HUB) &&
+ (AltIntrfDesc->bProtocol == PROTOCOL_HUB_MULTIPLE_TTS)) {
+ fpDevInfo->bProtocol = AltIntrfDesc->bProtocol;
+ fpDevInfo->bAltSettingNum = AltIntrfDesc->bAltSettingNum;
+ fpIntrfDesc = AltIntrfDesc;
+ break;
+ }
+ }
+ if (AltIntrfDesc->bDescLength) {
+ DescLength += (UINT16)AltIntrfDesc->bDescLength;
+ } else {
+ break;
+ }
+ }
+ }
+
+ fpDesc+=((CNFG_DESC*)fpDesc)->wTotalLength; // Calculate the end of descriptor block
+ fpEndpDesc = (ENDP_DESC*)((char*)fpIntrfDesc + fpIntrfDesc->bDescLength);
+
+ for( ;(fpEndpDesc->bDescType != DESC_TYPE_INTERFACE) && ((UINT8*)fpEndpDesc < fpDesc);
+ fpEndpDesc = (ENDP_DESC*)((UINT8 *)fpEndpDesc + fpEndpDesc->bDescLength)){
+
+ if(!(fpEndpDesc->bDescLength)) {
+ break; // Br if 0 length desc (should never happen, but...)
+ }
+
+ if( fpEndpDesc->bDescType != DESC_TYPE_ENDPOINT ) {
+ continue;
+ }
+
+ //
+ // Check for and configure Interrupt endpoint if present
+ //
+ if ((fpEndpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) !=
+ EP_DESC_FLAG_TYPE_INT) { // Bit 1-0: 10 = Endpoint does interrupt transfers
+ continue;
+ }
+
+ if (fpEndpDesc->bEndpointAddr & EP_DESC_ADDR_DIR_BIT) {
+ fpDevInfo->IntInEndpoint = fpEndpDesc->bEndpointAddr;
+ fpDevInfo->IntInMaxPkt = fpEndpDesc->wMaxPacketSize;
+ fpDevInfo->bPollInterval = fpEndpDesc->bPollInterval;
+ break;
+ }
+ }
+
+ if ((fpHCStruc->dHCFlag & HC_STATE_CONTROLLER_WITH_RMH) &&
+ (fpDevInfo->bHubDeviceNumber & BIT7)) {
+ fpDevInfo->wIncompatFlags |= USB_INCMPT_RMH_DEVICE;
+ }
+
+ fpDevInfo->HubDepth = 0;
+ ParentHub = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR,
+ NULL, fpDevInfo->bHubDeviceNumber, NULL);
+ if(ParentHub) {
+ fpDevInfo->HubDepth = ParentHub->HubDepth + 1;
+ }
+
+ if(fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) {
+ UsbHubSetHubDepth(fpHCStruc, fpDevInfo, fpDevInfo->HubDepth);
+ }
+
+ //
+ // Allocate memory for getting hub descriptor
+ //
+ fpBuffer = USB_MemAlloc(sizeof(MEM_BLK));
+ if (!fpBuffer) {
+ //USB_AbortConnectDev(fpDevInfo); //(EIP59579-)
+ return NULL;
+ }
+
+ Status = UsbHubGetHubDescriptor(fpHCStruc, fpDevInfo, fpBuffer, sizeof(MEM_BLK));
+ if(Status != USB_SUCCESS) { // Error
+ USB_MemFree(fpBuffer, sizeof(MEM_BLK));
+ //USB_AbortConnectDev(fpDevInfo); //(EIP59579-)
+ return NULL;
+ }
+ fpHubDesc = (HUB_DESC*)fpBuffer;
+ fpDevInfo->bHubNumPorts = fpHubDesc->bNumPorts;
+ fpDevInfo->bHubPowerOnDelay = fpHubDesc->bPowerOnDelay; // Hub's ports have not been enumerated
+
+ if (fpDevInfo->Flag & DEV_INFO_ALT_SETTING_IF) {
+ if (fpDevInfo->bAltSettingNum != 0) {
+ // Select this alternate setting for multiple TTs.
+ UsbSetInterface(fpHCStruc, fpDevInfo, fpDevInfo->bAltSettingNum);
+ }
+ }
+
+ //
+ // Turn on power to all of the hub's ports by setting its port power features.
+ // This is needed because hubs cannot detect a device attach until port power
+ // is turned on.
+ //
+ for (bPortNum = 1; bPortNum <= fpDevInfo->bHubNumPorts; bPortNum++)
+ {
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE &&
+ bPortNum == fpHCStruc->DebugPort)
+ {
+ continue;
+ }
+
+ if (fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) {
+ UsbHubGetPortStatus(fpHCStruc, fpDevInfo, bPortNum, &gUsbData->dHubPortStatus);
+ if (Usb3HubPortSts->PortStatus.Power == 1) {
+ continue;
+ }
+ }
+
+ UsbHubSetPortFeature(fpHCStruc, fpDevInfo, bPortNum, PortPower);
+ SetPortPower = TRUE;
+ }
+
+ //
+ // Delay the amount of time specified in the PowerOnDelay field of
+ // the hub descriptor: in ms, add 30 ms to the normal time and multiply
+ // by 64 (in 15us).
+ //
+ if(SetPortPower) {
+ if (!(fpDevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE)) {
+ if (gUsbData->PowerGoodDeviceDelay == 0) {
+ DelayValue = (UINTN)fpDevInfo->bHubPowerOnDelay * 2 * 1000; // "Auto"
+ } else {
+ DelayValue = (UINTN)gUsbData->PowerGoodDeviceDelay * 1000* 1000; // convert sec->15 mcs units
+ }
+ FixedDelay(DelayValue);
+ }
+ }
+
+ fpDevInfo->fpPollTDPtr = 0;
+ fpDevInfo->fpPollEDPtr = 0;
+
+ //
+ // Free the allocated buffer
+ //
+ USB_MemFree(fpBuffer, sizeof(MEM_BLK));
+
+ fpDevInfo->HubPortConnectMap = 0;
+
+ //
+ // Check for new devices behind the hub
+ //
+ for (bPortNum = 1; bPortNum <= fpDevInfo->bHubNumPorts; bPortNum++) {
+ USBCheckPortChange(fpHCStruc, fpDevInfo->bDeviceAddress, bPortNum);
+ }
+
+ fpDevInfo->PollingLength = fpDevInfo->IntInMaxPkt;
+
+ // Start polling the new device's interrupt endpoint.
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDActivatePolling)
+ (fpHCStruc, fpDevInfo);
+
+ return fpDevInfo;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHubDisconnect
+//
+// Description: This routine disconnects the hub by disconnecting all the
+// devices behind it
+//
+// Input: pDevInfo Device info structure pointer
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHUBDisconnectDevice (DEV_INFO* fpDevInfo)
+{
+ HC_STRUC* fpHCStruc = gUsbData->HcTable[fpDevInfo->bHCNumber - 1];
+ UINT8 bPort;
+
+ // Stop polling the endpoint
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(fpHCStruc->bHCType)].pfnHCDDeactivatePolling)(fpHCStruc,fpDevInfo);
+ fpDevInfo->IntInEndpoint = 0;
+
+ //
+ // A hub device is being disconnected. For each of the hub's ports disconnect
+ // any child device connected.
+ //
+ fpHCStruc = gUsbData->HcTable[fpDevInfo->bHCNumber - 1];
+
+ for (bPort = 1; bPort <= (UINT8)fpDevInfo->bHubNumPorts; bPort++)
+ {
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE &&
+ bPort == fpHCStruc->DebugPort)
+ {
+ continue;
+ }
+
+ USB_StopDevice (fpHCStruc, fpDevInfo->bDeviceAddress, bPort);
+ }
+
+ return USB_SUCCESS;
+
+}
+
+VOID
+UsbHubDeviceInit(
+ VOID
+)
+{
+ USB_InstallCallBackFunction(USBHub_ProcessHubData);
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHubCheckDeviceType
+//
+// Description: This routine checks for hub type device from the
+// interface data provided
+//
+// Input: bBaseClass USB base class code
+// bSubClass USB sub-class code
+// bProtocol USB protocol code
+//
+// Output: BIOS_DEV_TYPE_HUB type on success or 0FFH on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHubCheckDeviceType(
+ DEV_INFO *DevInfo,
+ UINT8 BaseClass,
+ UINT8 SubClass,
+ UINT8 Protocol
+)
+{
+ if (BaseClass == BASE_CLASS_HUB) {
+ return BIOS_DEV_TYPE_HUB;
+ } else {
+ return USB_ERROR;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHub_GetPortStatus
+//
+// Description: This routine returns the hub port status
+//
+// Input: fpDevInfo USB device - the hub whose status has changed
+// bit 7 : 1 - Root hub, 0 for other hubs
+// bit 6-0 : Device address of the hub
+// bPortNum Port number
+// pHCStruc HCStruc of the host controller
+//
+// Output: Port status flags (Refer USB_PORT_STAT_XX equates)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHub_GetPortStatus (
+ HC_STRUC* HcStruc,
+ UINT8 HubAddr,
+ UINT8 PortNum,
+ BOOLEAN ClearChangeBits
+)
+{
+ UINT8 PortSts = USB_PORT_STAT_DEV_OWNER;
+ UINT8 Status;
+ DEV_INFO *DevInfo;
+ HUB_FEATURE Feature;
+ UINT16 PortChange;
+ UINT8 i = 0;
+
+ HUB_PORT_STATUS* HubPortSts = (HUB_PORT_STATUS*)&gUsbData->dHubPortStatus;
+ USB3_HUB_PORT_STATUS* Usb3HubPortSts = (USB3_HUB_PORT_STATUS*)&gUsbData->dHubPortStatus;
+
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR, NULL, HubAddr, HcStruc);
+ ASSERT(DevInfo);
+ if (DevInfo == NULL) {
+ return 0;
+ }
+
+ if (DevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE &&
+ PortNum == HcStruc->DebugPort){
+ return 0;
+ }
+
+ Status = UsbHubGetPortStatus(HcStruc, DevInfo, PortNum, &gUsbData->dHubPortStatus);
+ if (Status == USB_ERROR) {
+ return USB_ERROR;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_3, "Hub port[%d] status: %08x\n", PortNum, gUsbData->dHubPortStatus);
+
+ if (DevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) {
+ for (i = 0; i < 20; i++) {
+ if (Usb3HubPortSts->PortStatus.Reset == 0) {
+ break;
+ }
+ FixedDelay(10 * 1000); // 10ms
+ UsbHubGetPortStatus(HcStruc, DevInfo, PortNum, &gUsbData->dHubPortStatus);
+ }
+
+ switch (Usb3HubPortSts->PortStatus.LinkState) {
+ case USB3_HUB_PORT_LINK_U0:
+ case USB3_HUB_PORT_LINK_RXDETECT:
+ break;
+ case USB3_HUB_PORT_LINK_RECOVERY:
+ for (i = 0; i < 20; i++) {
+ FixedDelay(10 * 1000);
+ UsbHubGetPortStatus(HcStruc, DevInfo, PortNum, &gUsbData->dHubPortStatus);
+ if (Usb3HubPortSts->PortStatus.LinkState != USB3_HUB_PORT_LINK_RECOVERY) {
+ break;
+ }
+ }
+ break;
+ case USB3_HUB_PORT_LINK_POLLING:
+ for (i = 0; i < 50; i++) {
+ FixedDelay(10 * 1000);
+ UsbHubGetPortStatus(HcStruc, DevInfo, PortNum, &gUsbData->dHubPortStatus);
+ if (Usb3HubPortSts->PortStatus.LinkState != USB3_HUB_PORT_LINK_POLLING) {
+ break;
+ }
+ }
+ if (Usb3HubPortSts->PortStatus.LinkState == USB3_HUB_PORT_LINK_U0 ||
+ Usb3HubPortSts->PortStatus.LinkState == USB3_HUB_PORT_LINK_RXDETECT) {
+ break;
+ }
+ case USB3_HUB_PORT_LINK_INACTIVE:
+ // A downstream port can only exit from this state when directed,
+ // or upon detection of an absence of a far-end receiver termination
+ // or upon a Warm Reset.
+ // The Timeout of SS.Inactive.Quiet is 12 ms.
+ FixedDelay(12 * 1000);
+ UsbHubGetPortStatus(HcStruc, DevInfo, PortNum, &gUsbData->dHubPortStatus);
+ if (Usb3HubPortSts->PortStatus.LinkState == USB3_HUB_PORT_LINK_RXDETECT) {
+ break;
+ }
+ case USB3_HUB_PORT_LINK_COMPLIANCE_MODE:
+ UsbHubResetPort(HcStruc, DevInfo, PortNum, TRUE);
+ break;
+ default:
+ PortSts |= USB_PORT_STAT_DEV_CONNECTED;
+ break;
+ }
+ if (Usb3HubPortSts->PortChange.ConnectChange) {
+ PortSts |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ DevInfo->HubPortConnectMap &= (UINT16) (~(1 << PortNum));
+ //UsbHubClearPortFeature(HcStruc, DevInfo, PortNum, PortConnectChange);
+ }
+ if (Usb3HubPortSts->PortStatus.Connected) {
+ DevInfo->HubPortConnectMap |= (UINT16) (1 << PortNum);
+ PortSts |= USB_PORT_STAT_DEV_CONNECTED | USB_PORT_STAT_DEV_SUPERSPEED;
+
+ // USB 3.0 hub may not set Connect Status Change bit,
+ // set the connect change flag if the BH Reset change or Reset change is set.
+ if (Usb3HubPortSts->PortChange.BhResetChange || Usb3HubPortSts->PortChange.ResetChange) {
+ PortSts |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ }
+ if (Usb3HubPortSts->PortStatus.Enabled) {
+ PortSts |= USB_PORT_STAT_DEV_ENABLED;
+ }
+ }
+ if (Usb3HubPortSts->PortChange.OverCurrentChange) {
+ if ((Usb3HubPortSts->PortStatus.OverCurrent == 0) &&
+ (Usb3HubPortSts->PortStatus.Power == 0)) {
+ UsbHubSetPortFeature(HcStruc, DevInfo, PortNum, PortPower);
+ FixedDelay((UINTN)(DevInfo->bHubPowerOnDelay * 2 * 1000));
+ }
+ }
+ } else {
+ if (HubPortSts->PortChange.ConnectChange) {
+ PortSts |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ //UsbHubClearPortFeature(HcStruc, DevInfo, PortNum, PortConnectChange);
+ DevInfo->HubPortConnectMap &= (UINT16) (~(1 << PortNum));
+ //if(HubPortSts->PortStatus.Connected) {
+ // Delay for 100ms allowing power to settle.
+ //FixedDelay(gUsbData->UsbTimingPolicy.HubPortConnect * 1000); // 50ms
+ //}
+ }
+ if (HubPortSts->PortStatus.Connected) {
+ PortSts |= USB_PORT_STAT_DEV_CONNECTED;
+ DevInfo->HubPortConnectMap |= (UINT16) (1 << PortNum);
+ if (HubPortSts->PortStatus.LowSpeed) {
+ PortSts |= USB_PORT_STAT_DEV_LOWSPEED;
+ } else if (HubPortSts->PortStatus.HighSpeed) {
+ PortSts |= USB_PORT_STAT_DEV_HISPEED;
+ } else {
+ PortSts |= USB_PORT_STAT_DEV_FULLSPEED;
+ }
+ if (HubPortSts->PortStatus.Enabled) {
+ PortSts |= USB_PORT_STAT_DEV_ENABLED;
+ }
+ }
+ if (HubPortSts->PortChange.OverCurrentChange) {
+ if ((HubPortSts->PortStatus.OverCurrent == 0) &&
+ (HubPortSts->PortStatus.Power == 0)) {
+ UsbHubSetPortFeature(HcStruc, DevInfo, PortNum, PortPower);
+ FixedDelay((UINTN)(DevInfo->bHubPowerOnDelay * 2 * 1000));
+ }
+ }
+ }
+
+ // Clear all port status change
+ //UsbHubGetPortStatus(HcStruc, DevInfo, PortNum, &gUsbData->dHubPortStatus);
+ if (ClearChangeBits == TRUE) {
+ PortChange = (*((UINT16*)&HubPortSts->PortChange));
+ for (Feature = PortConnectChange; Feature <= PortResetChange; Feature++) {
+ if (PortChange & 1) {
+ UsbHubClearPortFeature(HcStruc, DevInfo, PortNum, Feature);
+ }
+ PortChange >>= 1;
+ }
+
+ if (DevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) {
+ if (Usb3HubPortSts->PortChange.LinkStateChange) {
+ UsbHubClearPortFeature(HcStruc, DevInfo, PortNum, PortLinkStateChange);
+ }
+ if (Usb3HubPortSts->PortChange.ConfigErrorChange) {
+ UsbHubClearPortFeature(HcStruc, DevInfo, PortNum, PortConfigErrorChange);
+ }
+ if (Usb3HubPortSts->PortChange.BhResetChange) {
+ UsbHubClearPortFeature(HcStruc, DevInfo, PortNum, BhPortResetChange);
+ }
+ }
+ }
+
+ return PortSts;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHub_DisablePort
+//
+// Description: This routine disables the hub port
+//
+// Input: bHubAddr USB device address of the hub whose status
+// has changed
+// bit 7 : 1 - Root hub, 0 for other hubs
+// bit 6-0 : Device address of the hub
+// bPortNum Port number
+// pHCStruc HCStruc of the host controller
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHub_DisablePort(
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bPortNum)
+{
+ DEV_INFO* fpDevInfo;
+
+ HUB_PORT_STATUS* HubPortSts = (HUB_PORT_STATUS*)&gUsbData->dHubPortStatus;
+
+ //
+ // Get DeviceInfo pointer
+ //
+ fpDevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR,
+ (DEV_INFO*)0,
+ bHubAddr,
+ fpHCStruc);
+//
+// Disable the hub/port by clearing its Enable feature
+//
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE &&
+ bPortNum == fpHCStruc->DebugPort)
+ {
+ return USB_SUCCESS;
+ }
+
+ if(fpDevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) return USB_SUCCESS;
+
+ UsbHubGetPortStatus(fpHCStruc, fpDevInfo, bPortNum, &gUsbData->dHubPortStatus);
+
+ // Perform control transfer with device request as HUB_RQ_CLEAR_PORT_FEATURE,
+ // wIndex = Port number, wValue = HUB_FEATURE_PORT_ENABLE,
+ // fpBuffer = 0 and wlength = 0
+ //
+ if(HubPortSts->PortStatus.Enabled) {
+ UsbHubClearPortFeature(fpHCStruc, fpDevInfo, bPortNum, PortEnable);
+ }
+
+ return USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHub_EnablePort
+//
+// Description: This routine enables the hub port
+//
+// Input: bHubAddr USB device address of the hub whose status
+// has changed
+// bit 7 : 1 - Root hub, 0 for other hubs
+// bit 6-0 : Device address of the hub
+// bPortNum Port number
+// pHCStruc HCStruc of the host controller
+//
+// Output: USB_SUCCESS if the hub port is enabled. USB_ERROR otherwise
+//
+// Modified: Nothing
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHub_EnablePort(
+ HC_STRUC* fpHCStruc,
+ UINT8 bHubAddr,
+ UINT8 bPortNum)
+{
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHub_ResetPort
+//
+// Description: This routine resets the hub port
+//
+// Input: HCStruc HCStruc of the host controller
+// HubAddr USB device address of the hub whose status
+// has changed
+// bit 7 : 1 - Root hub, 0 for other hubs
+// bit 6-0 : Device address of the hub
+// PortNum Port number
+//
+// Output: USB_SUCCESS if the hub port is enabled. USB_ERROR otherwise
+//
+// Modified: Nothing
+//
+// Referrals:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHub_ResetPort(
+ HC_STRUC* HcStruc,
+ UINT8 HubAddr,
+ UINT8 PortNum)
+{
+ UINT8 Status;
+ DEV_INFO* DevInfo;
+
+ //
+ // Get DeviceInfo pointer
+ //
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR,
+ (DEV_INFO*)0, HubAddr, HcStruc);
+ if (DevInfo == NULL) return USB_ERROR;
+
+ if ((DevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE) &&
+ (PortNum == HcStruc->DebugPort)) {
+ return USB_SUCCESS;
+ }
+ Status = UsbHubResetPort(HcStruc, DevInfo, PortNum, FALSE);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBHub_ProcessHubData
+//
+// Description: This routine is called with USB hub status change
+// report data
+//
+// Input: pHCStruc Pointer to HCStruc
+// pDevInfo Pointer to device information structure
+// pTD Pointer to the polling TD
+// pBuffer Pointer to the data buffer
+//
+//
+// Notes: The status change data is an array of bit flags:
+// Bit Description
+// ----------------------------------------------------------
+// 0 Indicate connect change status for all ports
+// 1 Indicate connect change status for port 1
+// 2 Indicate connect change status for port 2
+// ... ..............
+// n Indicate connect change status for port n
+// -----------------------------------------------------------
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBHub_ProcessHubData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+ )
+{
+ UINT8 PortNum;
+ UINT16 PortMap;
+ BOOLEAN ConnectDelay = FALSE;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "USBHub_ProcessHubData, gUsbData->bEnumFlag = %d\n", gUsbData->bEnumFlag);
+ //
+ // Check for enum flag and avoid hub port enumeration if needed
+ //
+ if (gUsbData->bEnumFlag == TRUE) return USB_SUCCESS;
+
+ for (PortNum = 1; PortNum <= DevInfo->bHubNumPorts; PortNum++) {
+ PortMap = (UINT16)(1 << PortNum);
+ if (*(UINT16*)Buffer & PortMap) {
+ if (!ConnectDelay && ((~DevInfo->HubPortConnectMap) & PortMap)) {
+ //Delay for 50 ms allowing port to settle.
+ FixedDelay(50 * 1000);
+ ConnectDelay = TRUE;
+ }
+ //
+ // Set enumeration flag so that another device will not get enabled
+ //
+ gUsbData->bEnumFlag = TRUE;
+
+ USBCheckPortChange(HcStruc, DevInfo->bDeviceAddress, PortNum);
+
+ //
+ // Reset enumeration flag so that other devices can be enumerated
+ //
+ gUsbData->bEnumFlag = FALSE;
+ }
+ }
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubResetPort
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubResetPort(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 Port,
+ BOOLEAN WarmReset)
+{
+ UINT8 Status;
+ UINT8 i;
+ BOOLEAN IsResetChange;
+
+ HUB_PORT_STATUS* HubPortSts = (HUB_PORT_STATUS*)&gUsbData->dHubPortStatus;
+ USB3_HUB_PORT_STATUS* Usb3HubPortSts = (USB3_HUB_PORT_STATUS*)&gUsbData->dHubPortStatus;
+
+ if (WarmReset && DevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) {
+ Status = UsbHubSetPortFeature(HcStruc, DevInfo, Port, BhPortReset);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ for(i = 0; i < 10; i++) {
+ FixedDelay(10 * 1000);
+ Status = UsbHubGetPortStatus(HcStruc, DevInfo, Port, &gUsbData->dHubPortStatus);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ if(Usb3HubPortSts->PortChange.BhResetChange) break;
+ }
+ if (!Usb3HubPortSts->PortChange.BhResetChange) {
+ return USB_ERROR;
+ }
+
+ Status = UsbHubClearPortFeature(HcStruc, DevInfo, Port, BhPortResetChange);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ Status = UsbHubClearPortFeature(HcStruc, DevInfo, Port, PortResetChange);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ } else {
+ Status = UsbHubSetPortFeature(HcStruc, DevInfo, Port, PortReset);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ // The duration of the Resetting state is nominally 10 ms to 20 ms
+ FixedDelay(20 * 1000); // 20 ms delay
+
+ for(i = 0; i < 10; i++) {
+ Status = UsbHubGetPortStatus(HcStruc, DevInfo, Port, &gUsbData->dHubPortStatus);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ if(DevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) {
+ IsResetChange = Usb3HubPortSts->PortChange.ResetChange ? TRUE : FALSE;
+ } else {
+ IsResetChange = HubPortSts->PortChange.ResetChange ? TRUE : FALSE;
+ }
+
+ if(IsResetChange) break;
+
+ FixedDelay(5 * 1000); // 5 ms delay
+ }
+ if (!IsResetChange) {
+ return USB_ERROR;
+ }
+
+ Status = UsbHubClearPortFeature(HcStruc, DevInfo, Port, PortResetChange);
+ if(Status != USB_SUCCESS) return USB_ERROR;
+
+ if (DevInfo->bEndpointSpeed != USB_DEV_SPEED_SUPER) {
+ if (!(DevInfo->wIncompatFlags & USB_INCMPT_RMH_DEVICE)) {
+ FixedDelay(20 * 1000); // 20 ms
+ } else if (HubPortSts->PortStatus.LowSpeed == 1) {
+ // 1 ms delay for Low-Speed device
+ FixedDelay(1 * 1000);
+ }
+ }
+ }
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubCearHubFeature
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubCearHubFeature(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ HUB_FEATURE HubFeature)
+{
+ return USB_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubClearPortFeature
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubClearPortFeature(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 Port,
+ HUB_FEATURE PortFeature)
+{
+ DEV_REQ DevReq;
+
+ DevReq.wRequestType = HUB_RQ_CLEAR_PORT_FEATURE;
+ DevReq.wValue = PortFeature;
+ DevReq.wIndex = Port;
+ DevReq.wDataLength = 0;
+
+ return UsbControlTransfer(HcStruc, DevInfo, DevReq, 50, NULL);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubGetHubDescriptor
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubGetHubDescriptor(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ VOID* Buffer,
+ UINT16 Length)
+{
+ DEV_REQ DevReq;
+
+ DevReq.wRequestType = USB_RQ_GET_CLASS_DESCRIPTOR;
+ DevReq.wValue = DevInfo->bEndpointSpeed ==
+ USB_DEV_SPEED_SUPER ? DESC_TYPE_SS_HUB << 8 : DESC_TYPE_HUB << 8;
+ DevReq.wIndex = 0;
+ DevReq.wDataLength = Length;
+
+ return UsbControlTransfer(HcStruc, DevInfo, DevReq, 150, Buffer);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubGetHubStatus
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubGetHubStatus(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT32* HubStatus)
+{
+ return USB_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubGetPortStatus
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubGetPortStatus(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 Port,
+ UINT32* PortStatus)
+{
+ DEV_REQ DevReq;
+
+ DevReq.wRequestType = HUB_RQ_GET_PORT_STATUS;
+ DevReq.wValue = 0;
+ DevReq.wIndex = Port;
+ DevReq.wDataLength = 4;
+
+ return UsbControlTransfer(HcStruc, DevInfo, DevReq, 150, PortStatus);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubGetErrorCount
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubGetErrorCount(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 Port,
+ UINT16* ErrorCount)
+{
+ return USB_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubSetHubDescriptor
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubSetHubDescriptor(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ VOID* Buffer,
+ UINT16 Length)
+{
+ return USB_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubSetHubFeature
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubSetHubFeature(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ HUB_FEATURE HubFeature)
+{
+ return USB_ERROR;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubSetHubDepth
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubSetHubDepth(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT16 HubDepth)
+{
+ DEV_REQ DevReq;
+
+ DevReq.wRequestType = HUB_RQ_SET_HUB_DEPTH;
+ DevReq.wValue = HubDepth;
+ DevReq.wIndex = 0;
+ DevReq.wDataLength = 0;
+
+ return UsbControlTransfer(HcStruc, DevInfo, DevReq, 50, NULL);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UsbHubSetPortFeature
+//
+// Description:
+//
+// Input:
+//
+// Output: USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbHubSetPortFeature(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8 Port,
+ HUB_FEATURE PortFeature)
+{
+ DEV_REQ DevReq;
+
+ DevReq.wRequestType = HUB_RQ_SET_PORT_FEATURE;
+ DevReq.wValue = PortFeature;
+ DevReq.wIndex = Port;
+ DevReq.wDataLength = 0;
+
+ return UsbControlTransfer(HcStruc, DevInfo, DevReq, 100, NULL); //(EIP77526)
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbkbd.c b/Core/EM/usb/rt/usbkbd.c
new file mode 100644
index 0000000..e7240ad
--- /dev/null
+++ b/Core/EM/usb/rt/usbkbd.c
@@ -0,0 +1,1315 @@
+#pragma warning(disable: 4001)
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbkbd.c 70 10/16/16 10:11p Wilsonlee $
+//
+// $Revision: 70 $
+//
+// $Date: 10/16/16 10:11p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbkbd.c $
+//
+// 70 10/16/16 10:11p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 69 7/21/16 11:00p Wilsonlee
+// Build error if USB_HID_KEYREPEAT_USE_SETIDLE is 1.
+//
+// 68 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 67 12/24/14 9:33p Wilsonlee
+// [TAG] EIP194683
+// [Category] Improvement
+// [Description] Add the flag "USB_INCMPT_HID_BOOT_PROTOCOL_ONLY" of usb
+// bad device table to keep devices use boot protocol.
+// [Files] usbkbd.c, usbms.c, usbhid.c, usbdef.h
+//
+// 66 11/23/14 9:24p Wilsonlee
+// [TAG] EIP190127
+// [Category] Improvement
+// [Description] Remove scan code algorithm update.
+// [Files] usbkbd.c
+//
+// 65 11/23/14 9:10p Wilsonlee
+// [TAG] EIP188119
+// [Category] Improvement
+// [Description] Disconnect devices and uninstall usb device related
+// protocols if we call stop api for the host controllers.
+// [Files] usbkbd.c, usbbus.c, uhcd.h, uhcd.c
+//
+// 64 8/07/14 2:20a Wilsonlee
+// [TAG] EIP176549
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Microstep USB Keyboard issue.
+// [RootCause] The report descriptor of Microstep USB Keyboard (Sonix
+// Technology Co chip) has an error, Modifier keys is bitmap data, but it
+// reports as array data.
+// [Solution] We need to force variable flag for Modifier keys input
+// item.
+// [Files] usbhid.c, usbkbd.c, usbdef.h
+//
+// 63 7/04/14 7:31a Wilsonlee
+// [TAG] EIP176044
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NEC USB keyboard doesn't work
+// [RootCause] When we extract input report data, the report offset is
+// incorrect if ReportId isn't 0.
+// [Solution] Adjust report offset.
+// [Files] usbkbd.c
+//
+// 62 5/15/14 5:41a Wilsonlee
+// Fix the code check error result.
+//
+// 61 5/06/14 5:15a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 60 2/26/14 1:55a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 59 11/05/13 4:47a Ryanchou
+// [TAG] EIP135636
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] NumLock LED cannot be on/off properly.
+// [RootCause] It is the side effect of EIP #107429 changes, the
+// keyboard does not generate break code when pressing NumLock.
+// [Solution] Remove the EIP #107429 changes.
+// [Files] amiusb.c, usbkbd.c, efiusbkb.c
+//
+// 58 3/07/13 8:53a Ryanchou
+// [TAG] EIP113218
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB keyboard cannot work after ownership change back to
+// BIOS
+// [RootCause] The key repeat SMI does not generated because the HC is
+// stopped.
+// [Solution] Use the other HC to generate key repeat SMI
+// [Files] usb.c, usbhid.c, usbkbd.c
+//
+// 57 1/23/13 4:35a Wilsonlee
+// [TAG] EIP109538
+// [Category] Improvement
+// [Description] Fix the code check error result.
+// [Files] usbkbd.c, usbCCID.c, usbbus.c, efiusbccid.c
+//
+// 56 1/11/13 4:15a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 55 1/07/13 12:56a Wilsonlee
+// [TAG] EIP111305
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] It is failed at reloading the usb keyboard driver.
+// [RootCause] The DEV_INFO_VALID_STRUC and DEV_INFO_DEV_PRESENT flag
+// were cleared when the usb driver is disconnecting.
+// [Solution] We should not clear the DEV_INFO_VALID_STRUC and
+// DEV_INFO_DEV_PRESENT flag at USBKBDDisconnectDevice.
+// [Files] usbkbd.c, usbbus.c
+//
+// 54 12/19/12 3:38a Roberthsu
+// [TAG] EIP107262
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CHOC keyboard can not work.
+// [RootCause] Usage offset error.
+// [Solution] Count correct usage offset.Ceck correct usage offset.
+// [Files] usbkbd.c
+//
+// 53 12/02/12 10:34p Roberthsu
+// [TAG] EIP102150
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Push key and unplug KB , character repeat can not.
+// stop
+// [RootCause] Because repeat key does not clear when usb keyboard
+// unplug.
+// [Solution] When keyboard disconnrct, clear keyboard device id with
+// device id buffer and scancode buffer.
+// [Files] amiusb.c,syskbc.c,uhcd.c,usbkbd.c
+//
+// 52 11/20/12 9:08p Wilsonlee
+// [TAG] EIP90887
+// [Category] New Feature
+// [Description] Add a hook to check keyboard buffer for speicial chars.
+// [Files] usb.sdl, usbrt.mak, usbkbd.c
+//
+// 51 11/14/12 4:26a Roberthsu
+// [TAG] EIP105587
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Rapoo keyboard press key have some garbage key.
+// [RootCause] Get report descriptor need skip constant data.
+// [Solution] Skip constant data.
+// [Files] usbkbd.c
+//
+// 50 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 49 8/07/12 4:47a Roberthsu
+// [TAG] EIP93637
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Keyboard operate incorrectly in BIOS
+// [RootCause] When keyboard disconnect.Usb keyboard buffer does not
+// clear.
+// [Solution] Clear usb keyboard buffer and repeat key.
+// [Files] usbkbd.c
+//
+// 48 8/06/12 11:53p Roberthsu
+// [TAG] EIP95349
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Roccat ISKU Keyboard can not work
+// [RootCause] Variable value overflow.
+// [Solution] Change variable type.
+// [Files] usbkbd.c
+//
+// 47 5/23/12 7:56a Roberthsu
+// [TAG] EIP90797
+// [Category] Improvement
+// [Description] Fix keyboard buffer transfer error
+// [Files] usbkbd.c
+//
+// 46 5/03/12 6:27a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 45 4/24/12 3:40a Roberthsu
+// [TAG] EIP83888
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Can not catch F8 key event on Keyboard
+// [RootCause] OS only call readkeystroke once.If OS get break key
+// readkeystroke will return EFI_NOT_READY.
+// [Solution] UsbKbdReadKeyStroke will serach available key in usb
+// data buffer.Fixed key repeat can not work when efi to legacy or legacy
+// to efi.
+// [Files] efiusbkb.c,usbkbd.c
+//
+// 44 3/05/12 1:26a Rameshr
+// [TAG] EIP81057
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Stall after RAID BIOS
+// [RootCause] Make code and break code handled by different environment
+// ( EFI, Legacy)
+// [Solution] If the Makecode processed by Legacy, the breakcode also
+// send to Legacy. The same applies for EFI also.
+// [Files] UsbKbd.c
+//
+// 43 1/04/12 6:56a Ryanchou
+// [TAG] EIP72505
+// [Category] Improvement
+// [Description] Clear the legacy USB keyboard buffer when switching
+// between EFI and legacy.
+// [Files] syskbc.c, uhcd.c, usbkbd.c
+//
+// 42 12/22/11 6:36a Roberthsu
+// [TAG] EIP77936
+// [Category] Improvement
+// [Description] Chang set_idle command timeout to 1sec
+// [Files] usbkbd.c
+//
+// 41 11/03/11 11:51p Roberthsu
+// [TAG] EIP73685
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ducky keyboard can not work.
+// [RootCause] Ducky keyboard report key usage is by usage keyboard
+// arrow.
+// [Solution] Get start offset by keyboard usage page .
+// [Files] usbkbd.c
+//
+// 40 9/27/11 1:37a Roberthsu
+// [TAG] EIP67400
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Microsoft wireless Media Desktop 1000 can¡¦t work normal.
+// [RootCause] Wireless ms report data contains usage page keyboard.And
+// output data not contains vaild report id.
+// [Solution] Check usage page led to decide kb or ms.Check correct
+// report id with report data.
+// [Files] usbkbd.c,usbhid.c,usbms.c
+//
+// 39 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 38 7/13/11 3:32a Ryanchou
+// [TAG] EIP63973
+// [Category] Improvement
+// [Description] Change the order of Set Protocol command and Set Idle
+// command.
+// [Files] usbkbd.c
+//
+// 37 6/21/11 11:02a Ryanchou
+// [TAG] EIP59579
+// [Category] Improvement
+// [Description] USB device information structure should be reserved for
+// the UsbIO to use even install driver fail.
+// [Files] usbmass.c, usbkbd.c, usbms.c
+//
+// 36 3/30/11 8:17a Ryanchou
+// [TAG] EIP54126
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Sometimes system hangs at checkpoint 0xB4.
+// [RootCause] The bLength field of configuration descriptor is zero.
+// [Solution] Check wether bLength field is zero before paring next
+// descriptor.
+// [Files] usb.c, usbbus.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c
+//
+// 35 2/10/11 7:40a Ryanchou
+// [TAG] EIP52206
+// [Category] Improvement
+// [Description] Remote wakeup command should be sent before sleep,
+// comment out the command.
+// [Files] usbkbd.c, usbms.c
+//
+// 34 1/17/11 4:34a Ryanchou
+// [TAG] EIP51108
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Some HID devices that has two interfaces can't work.
+// [RootCause] BIOS using the wrong endpoint to poll KBD/MS data.
+// [Solution] Get the first interrupt in endpoint when parsing
+// descriptors.
+// [Files] usbkbd.c, usbms.c
+//
+// 33 9/24/10 5:38p Olegi
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 32 3/11/10 9:41a Olegi
+//
+// 31 11/24/09 11:38a Olegi
+// EIP#29733 - BIOS adds an USB API (Block KBC Access)
+//
+// 30 11/13/09 9:13a Olegi
+// EIP31023: key repeat rates are defined by SDL tokens.
+//
+// 29 9/15/09 12:21p Olegi
+// Added KEY_REPEAT_LOGIC functionality. EIP#25841
+//
+// 28 5/05/09 10:21a Olegi
+// Modification in USBKBDConnectKeyboard. Resolves the problem of device
+// being reconnected using the SW (DisconnectController->ConnectController
+// sequence). EIP#21456.
+//
+// 27 4/20/09 9:26a Olegi
+// Completion of the fix for EIP#19563.
+//
+// 26 3/27/09 10:15a Olegi
+// Modifications in USBKBDProcessKeyboardData: keypress and key release
+// are synchronized between the modes (EFI/Legacy). If key is pressed in
+// one mode and released in the other, then keypress is discarded. This
+// fixes the problem of accidental key repeat sequence due to the mode
+// change. EIP #19563.
+//
+// 25 9/19/08 4:44p Olegi
+// Bugfix in USBKBDPeriodicInterruptHandler (EIP#16452) that takes care of
+// the key release situation.
+//
+// 24 9/05/08 4:19p Olegi
+// Removed calls to fpCallbackNotify functions, they are implemented in
+// SMI.
+//
+// 23 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 21 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 20 30/10/07 2:02p Anandakrishnanl
+// Updated USBKBDPeriodicInterruptHandler to see if CallbackNotify2 is not
+// NULL beforfe calling it.
+//
+// 19 30/10/07 12:20p Anandakrishnanl
+// Updated USBKBDPeriodicInterruptHandler to see if CallbackNotify3 is not
+// NULL beforfe calling it.
+//
+// 18 9/27/07 4:12p Olegi
+//
+// 17 3/20/07 12:17p Olegi
+// Legacy free related changes.
+//
+// 15 10/18/06 9:40a Andriyn
+// Fix: race condition on hot-plug in / plug-off
+//
+// 14 5/17/06 3:52p Fredericko
+// Fix: Mouse Button events get lost: no auto-repeat
+//
+// 13 4/26/06 12:26p Olegi
+//
+// 12 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 11 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 10 3/06/06 6:23p Olegi
+//
+// 9 3/01/06 3:50p Olegi
+// ProcessKeyboardData is change to use USB_FLAG_RUNNING_UNDER_OS flag.
+//
+// 8 2/06/06 9:34a Andriyn
+//
+// 7 8/26/05 12:25p Andriyn
+// Simulate Mouse Sampling rate by disabling Mouse Polling (reduce USB
+// SMI# generation)
+//
+// 6 8/25/05 7:19p Andriyn
+// USB Keyboard and mouse to use EMUL 60/64 for passing data to KBC.
+// Fall-back when EMUL 60/64 is not present
+//
+// 5 8/11/05 9:53a Olegi
+// 60/64 port emulation related fixes for EMU6064 driver.
+//
+// 4 8/04/05 5:58p Andriyn
+// Legacy over LegacyFree
+//
+// 2 6/01/05 5:22p Olegi
+// Debug message shortened.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbKbd.c
+//
+// Description: USB keyboard driver SMI routines
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "USBKBD.H"
+#include <UsbDevDriverElinks.h> //(EIP90887+)
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gKeyRepeatStatus;
+extern UINT16 gKbcSetTypeRate11CharsSec;
+extern UINT16 gKbcSetTypeDelay500MSec;
+UINT8 gLastKeyCodeArray[8]={0,0,0,0,0,0,0,0};
+
+//----------------------------------------------------------------------------
+// Typematic rate delay table will have counts to generate key repeat delays.
+// Since the periodic interrupt is set to 8msec the following repeat times
+// will generate necessary delay.
+// First three numbers are meant to define the frequency of the repeated keys;
+// four other numbers are used to define the amount of delay between the first
+// keypress-and-hold til the key actually starts repeating; the appropriate values
+// of this table are selected using the equates defined in UsbKbd.h
+//
+UINT8 aTypematicRateDelayTable[] = {2, 4, 8, 16, 32, 48, 64, 96};
+
+//
+// The global data variables are stored in USB_GLOBAL_DATA structure and can be accessed through
+// gUsbData->xxx
+//
+
+LEGACY_USB_KEYBOARD mLegacyKeyboard;
+
+extern UINT8 IsKbcAccessBlocked; //(EIP29733+)
+extern VOID USBKB_LEDOn();
+
+BOOLEAN gEfiMakeCodeGenerated=FALSE;
+BOOLEAN gLegacyMakeCodeGenerated=FALSE;
+
+extern EFI_EMUL6064KBDINPUT_PROTOCOL* gKbdInput ;
+
+UINT8 UsbControlTransfer(HC_STRUC*, DEV_INFO*, DEV_REQ, UINT16, VOID*);
+
+UINT32 ExtractInputReportData (UINT8 *Report, UINT16 Offset, UINT16 Size);
+ //(EIP90887+)>
+typedef BOOLEAN (KBD_BUFFER_CHECK_FUNCTIONS)(
+ DEV_INFO* DevInfo,
+ UINT8 *Buffer
+ );
+extern KBD_BUFFER_CHECK_FUNCTIONS KBD_BUFFER_CHECK_ELINK_LIST EndOfInitList;
+KBD_BUFFER_CHECK_FUNCTIONS* KbdBufferCheckFunctionsList[] = {KBD_BUFFER_CHECK_ELINK_LIST NULL};
+ //<(EIP90887+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBDInitialize (VOID)
+//
+// Description: This function returns fills the host controller driver
+// routine pointers in the structure provided
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBKBDInitialize (VOID)
+{
+ UINT8 bTemp;
+
+ //
+ // Initialize the typematic rate to 500 ms, 10.9 Char/Sec and auto repeat flag
+ // to disabled
+ //
+ gUsbData->wUSBKBC_StatusFlag |= ((gKbcSetTypeRate11CharsSec << KBC_TYPE_RATE_BIT_SHIFT) +
+ (gKbcSetTypeDelay500MSec << KBC_TYPE_DELAY_BIT_SHIFT));
+
+ USB_DEBUG (DEBUG_LEVEL_5, "USBKBDInitialize: CodeBufferStart : %lx\n", gUsbData->aKBCScanCodeBufferStart);
+
+ //
+ // Initialize the scanner buffer
+ //
+ gUsbData->fpKBCScanCodeBufferPtr = gUsbData->aKBCScanCodeBufferStart;
+ gUsbData->bLastUSBKeyCode = 0;
+
+ //
+ // Initialize the character buffer
+ //
+ gUsbData->fpKBCCharacterBufferHead = gUsbData->aKBCCharacterBufferStart;
+ gUsbData->fpKBCCharacterBufferTail = gUsbData->aKBCCharacterBufferStart;
+
+ //
+ // Initialize the USB Data buffer
+ //
+ gUsbData->aKBCUsbDataBufferHead = gUsbData->aKBCUsbDataBufferStart;
+ gUsbData->aKBCUsbDataBufferTail = gUsbData->aKBCUsbDataBufferStart;
+
+ gUsbData->fpKeyRepeatDevInfo=NULL;
+
+ //
+ // Set scan code set to 2 in the scanner flag
+ //
+ gUsbData->wUSBKBC_StatusFlag |= KBC_SET_SCAN_CODE_SET2;
+
+ gUsbData->bUSBKBShiftKeyStatus = 0;
+
+ //
+ // Get the keyboard controller command byte (CCB) and store it locally
+ //
+ //USBKBC_GetAndStoreCCB();
+ gUsbData->bCCB = 0x40;
+
+ for (bTemp=0; bTemp<6; bTemp++) mLegacyKeyboard.KeyCodeStorage[bTemp] = 0;
+ mLegacyKeyboard.KeyToRepeat = 0;
+
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBKBDConfigureKeyboard
+//
+// Description: This routine checks an interface descriptor of the USB device
+// detected to see if it describes a HID/Boot/Keyboard device.
+// If the device matches the above criteria, then the device is
+// configured and initialized
+//
+// Input: fpHCStruc HCStruc pointer
+// fpDevInfo Device information structure pointer
+// fpDesc Pointer to the descriptor structure
+// wStart Offset within interface descriptor
+// supported by the device
+// wEnd End offset of the device descriptor
+//
+// Output: FPDEV_INFO New device info structure, 0 on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP84455+)>
+DEV_INFO*
+USBKBDConfigureDevice (
+ DEV_INFO* DevInfo
+)
+{
+ UINT16 Index;
+
+ DevInfo->fpPollTDPtr = 0;
+ Index = USBKBDFindUSBKBDeviceTableEntry(DevInfo);
+ if (Index == 0xFFFF) {
+ Index = USBKBDFindUSBKBDeviceTableEntry(NULL);
+ }
+ if (Index != 0xFFFF) {
+ gUsbData->aUSBKBDeviceTable[Index] = DevInfo;
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)) {
+ if (BOOT_PROTOCOL_SUPPORT || (DevInfo->HidReport.Flag & HID_REPORT_FLAG_LED_FLAG) ||
+ (DevInfo->wIncompatFlags & USB_INCMPT_HID_BOOT_PROTOCOL_ONLY)) {
+ USBKB_LEDOn();
+ }
+ }
+ } else {
+ return 0;
+ }
+
+ return DevInfo;
+}
+ //<(EIP84455+)
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBDFindUSBKBDeviceTableEntry
+//
+// Description: This routine searches for the HID table entry which matches
+// the provided device info structure
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+//
+// Output: offset of the HID table for the requested fpDevinfo
+// 0xFFFF -on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBKBDFindUSBKBDeviceTableEntry(DEV_INFO* fpDevinfo)
+{
+ UINT16 wCount ;
+
+ for (wCount = 0; wCount < USB_DEV_HID_COUNT; wCount++)
+ {
+ if(gUsbData->aUSBKBDeviceTable[wCount] == fpDevinfo )
+ return wCount;
+ }
+ USB_DEBUG (DEBUG_LEVEL_3, "No Free KBD DevInfo Entry\n");
+ return 0xFFFF;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBDDisconnectDevice
+//
+// Description: This routine disconnects the keyboard by freeing
+// the USB keyboard device table entry
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+//
+// Output: USB_SUCCESS/USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKBDDisconnectDevice (
+ DEV_INFO* DevInfo
+)
+{
+ UINT16 Index;
+ //(EIP93637+)>
+ UINT8 ScanCodeCount = (UINT8)(gUsbData->fpKBCScanCodeBufferPtr -
+ (UINT8*)gUsbData->aKBCScanCodeBufferStart); //(EIP102150+)
+ UINT8 i = 0;
+ UINT8 CurrentDeviceId;
+ UINT8 Key;
+
+ USB_KB_BUFFER *KeyboardBuffer;
+ KeyboardBuffer = gUsbData->EfiKeyboardBuffer;
+
+ Index = USBKBDFindUSBKBDeviceTableEntry(DevInfo);
+ if (Index == 0xFFFF) {
+ USBLogError(USB_ERR_KBCONNECT_FAILED);
+ return USB_ERROR;
+ } else {
+ CurrentDeviceId = (UINT8)(1 << ((DevInfo->bDeviceAddress) -1));
+ while ((i < ScanCodeCount) && (ScanCodeCount != 0)) {
+ if (gUsbData->aKBCDeviceIDBufferStart[i] & CurrentDeviceId) {
+ gUsbData->aKBCDeviceIDBufferStart[i] &= ~CurrentDeviceId;
+ if (gUsbData->aKBCDeviceIDBufferStart[i] == 0) {
+ Key = gUsbData->aKBCScanCodeBufferStart[i];
+ if ((Key == HID_UP_KEYBOARD_RIGHT_SHIFT) ||
+ (Key == HID_UP_KEYBOARD_LEFT_SHIFT)) {
+ gUsbData->bUSBKBShiftKeyStatus &= ~(KB_RSHIFT_KEY_BIT_MASK+KB_LSHIFT_KEY_BIT_MASK);
+ }
+ USBKB_DiscardCharacter(&gUsbData->aKBCShiftKeyStatusBufferStart[i]);
+ gUsbData->fpKBCScanCodeBufferPtr--;
+ ScanCodeCount--;
+ continue;
+ }
+ }
+ i++;
+ }
+ if (gUsbData->fpKeyRepeatDevInfo == DevInfo) {
+ for (i = 0; i < 8; i++) {
+ *(gLastKeyCodeArray + i) = 0;
+ }
+ if(KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode == gUsbData->RepeatKey)
+ {
+ gUsbData->RepeatKey = 0;
+ KeyboardBuffer->bHead = KeyboardBuffer->bTail;
+ }
+ }
+ gUsbData->aUSBKBDeviceTable[Index] = 0;
+ return USB_SUCCESS;
+ }
+ //<(EIP93637+)
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_CheckCharacterBufferFull
+//
+// Description: This routine checks whether the character buffer can hold
+// 'N'+1 character
+//
+// Input: bCount Space needed in the buffer (in characters)
+//
+// Output: 0 If buffer is full
+// <> 0 If buffer is not full
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT8
+USBKBC_CheckUsbDataBufferFull (UINT8 bCount)
+{
+ UINT8 *dHead, *dTail, *dStart, *dEnd;
+
+ dHead = gUsbData->aKBCUsbDataBufferHead;
+ dTail = gUsbData->aKBCUsbDataBufferTail;
+ dStart = gUsbData->aKBCUsbDataBufferStart;
+ dEnd = dStart + sizeof (gUsbData->aKBCUsbDataBufferStart);
+ ++bCount;
+ do {
+ ++dHead;
+ if(dHead == dEnd) dHead = dStart;
+ if(dHead == dTail) return 0;
+ --bCount;
+ } while(bCount);
+
+ return 0xFF;
+}
+
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBC_SendToCharacterBuffer
+//
+// Description: This routine puts a character into the character buffer.
+// Character buffer pointers are also updated
+//
+// Input: Nothing
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+void
+USBKBC_SendToUsbDataBuffer (UINT8 *fpSrc)
+{
+ UINT8 *fPointer;
+ UINT8 *fPtrEnd;
+ UINT8 i;
+
+ fPtrEnd = ( gUsbData->aKBCUsbDataBufferStart +
+ sizeof (gUsbData->aKBCUsbDataBufferStart));
+
+ fPointer = gUsbData->aKBCUsbDataBufferHead;
+
+ for (i = 0; i < 8; i++) {
+ *fPointer++ = *fpSrc++;
+ }
+
+ if(fPointer == fPtrEnd) {
+ fPointer = gUsbData->aKBCUsbDataBufferStart;
+ }
+
+ gUsbData->aKBCUsbDataBufferHead = fPointer;
+
+ return;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBDProcessKeyboardData
+//
+// Description: This routine is called with USB keyboard report data. This
+// routine handles the translation of USB keyboard data
+// into PS/2 keyboard data, and makes the PS/2 data available
+// to software using ports 60/64h by communicating with
+// PS/2 keyboard controller.
+//
+// Input: fpHCStruc Pointer to HCStruc
+// fpDevInfo Pointer to device information structure
+// fpTD Pointer to the polling TD
+// fpBuffer Pointer to the data buffer
+//
+// Output: Nothing
+//
+// Notes: TD's control status field has the packet length (0 based).
+// It could be one of three values 0,1 or 7 indicating packet
+// lengths of 1, 2 & 8 repectively.
+// The format of 8 byte data packet is as follow:
+// Byte Description
+// -----------------------------------------------------------
+// 0 Modifier key (like shift, cntr & LED status)
+// 1 Reserved
+// 2 Keycode of 1st key pressed
+// 3 Keycode of 2nd key pressed
+// 4 Keycode of 3rd key pressed
+// 5 Keycode of 4th key pressed
+// 6 Keycode of 5th key pressed
+// 7 Keycode of 6th key pressed
+// -----------------------------------------------------------
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBKBDProcessKeyboardData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ UINT8 Count = 8;
+ HID_REPORT_FIELD *Field = NULL;
+ UINT8 FieldIndex = 0;
+ UINT32 BitOffset = 0;
+ BOOLEAN ValidData = FALSE;
+ UINT8 Data = 0;
+ UINT16 Index = 0;
+ UINT8 UsageBuffer[32] = {0};
+ UINT16 UsageIndex = 0;
+ UINT8 i;
+ UINTN OemHookIndex;
+
+ if (DevInfo->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) {
+ for (FieldIndex = 0; FieldIndex < DevInfo->HidReport.FieldCount; FieldIndex++) {
+ Field = DevInfo->HidReport.Fields[FieldIndex];
+
+ // Check if the field is input report.
+ if (!(Field->Flag & HID_REPORT_FIELD_FLAG_INPUT)) {
+ continue;
+ }
+
+ //if report id exist, check first byte
+ if ((Field->ReportId != 0) && (Field->ReportId != Buffer[0])) {
+ continue;
+ }
+
+ // Check if the field is contant.
+ if (Field->Flag & HID_REPORT_FIELD_FLAG_CONSTANT) {
+ BitOffset += Field->ReportCount * Field->ReportSize;
+ continue;
+ }
+
+ //find start offset
+ if (Field->UsagePage == HID_UP_KEYBOARD) {
+ ValidData = TRUE;
+
+ // If Report ID tags are used in the report descriptor, the first byte is
+ // report id, we offset 8 bits to get data.
+ if (Field->ReportId != 0) {
+ BitOffset += 8;
+ }
+
+ for (Index = 0; Index < Field->ReportCount; Index++) {
+ Data = ExtractInputReportData(Buffer,
+ BitOffset + (Index * Field->ReportSize), Field->ReportSize);
+
+ if ((Data < Field->LogicalMin) || (Data > Field->LogicalMax)) {
+ continue;
+ }
+
+ Data = Field->Flag & HID_REPORT_FIELD_FLAG_VARIABLE ?
+ (Data != 0 ? Field->Usages[Index] : Data) :
+ Field->Usages[Data - Field->LogicalMin];
+
+ if ((Data != 0) && (UsageIndex < COUNTOF(UsageBuffer))) {
+ UsageBuffer[UsageIndex++] = Data;
+ }
+ }
+ if (Field->ReportId != 0) {
+ BitOffset -= 8;
+ }
+ }
+ BitOffset += Field->ReportCount * Field->ReportSize;
+ }
+
+ if (ValidData == FALSE) {
+ return USB_SUCCESS;
+ }
+
+ MemSet(Buffer, 8, 0);
+
+ // Translate the report data to boot protocol data.
+
+ // 0 Modifier key (like shift, cntr & LED status)
+ // 1 Reserved
+ // 2 Keycode of 1st key pressed
+ // 3 Keycode of 2nd key pressed
+ // 4 Keycode of 3rd key pressed
+ // 5 Keycode of 4th key pressed
+ // 6 Keycode of 5th key pressed
+ // 7 Keycode of 6th key pressed
+
+ for (Index = 0, i = 0; Index < UsageIndex; Index++) {
+ if (UsageBuffer[Index] >= HID_UP_KEYBOARD_LEFT_CTRL &&
+ UsageBuffer[Index] <= HID_UP_KEYBOARD_RIGHT_GUI) {
+ Buffer[0] |= 1 << (UsageBuffer[Index] - HID_UP_KEYBOARD_LEFT_CTRL);
+ } else {
+ if (i < 6) {
+ Buffer[i + 2] = UsageBuffer[Index];
+ i++;
+ }
+ }
+ }
+ }
+ //(EIP90887+)>
+ // Call all the OEM hooks that wants to check KBD buffer
+ for (OemHookIndex = 0; KbdBufferCheckFunctionsList[OemHookIndex]; OemHookIndex++) {
+ if (KbdBufferCheckFunctionsList[OemHookIndex](DevInfo, Buffer)) {
+ return USB_SUCCESS;
+ }
+ }
+ //<(EIP90887+)
+ //Is KBC access allowed?
+ if (IsKbcAccessBlocked) {
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) || !gEfiMakeCodeGenerated) {
+ return USB_SUCCESS;
+ }
+ MemSet(Buffer, 8, 0);
+ }
+
+ //
+ // Save the device info pointer for later use
+ //
+ gUsbData->fpKeyRepeatDevInfo = DevInfo;
+
+ for (i = 0, Count = 8; i < 8; i++, Count--) {
+ if (Buffer[i]) {
+ break;
+ }
+ }
+
+ if ((gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)) {
+ if (Count==0) {
+ gEfiMakeCodeGenerated=FALSE;
+ } else {
+ gEfiMakeCodeGenerated=TRUE;
+ gLegacyMakeCodeGenerated=FALSE;
+ }
+ } else {
+ if (Count==0) {
+ gLegacyMakeCodeGenerated=FALSE;
+ } else {
+ gLegacyMakeCodeGenerated=TRUE;
+ gEfiMakeCodeGenerated=FALSE;
+ }
+ }
+
+ //
+ // checks for new key stroke.
+ // if no new key got, return immediately.
+ //
+ for (i = 0; i < 8; i ++) {
+ if (Buffer[i] != gLastKeyCodeArray[i]) {
+ break;
+ }
+ }
+
+#if USB_HID_KEYREPEAT_USE_SETIDLE == 1
+ if ((i == 8) && gKeyRepeatStatus) {
+ USBKBDPeriodicInterruptHandler(HcStruc);
+ return USB_SUCCESS;
+ }
+#endif
+
+ //
+ // Update LastKeycodeArray[] buffer in the
+ // Usb Keyboard Device data structure.
+ //
+ for (i = 0; i < 8; i ++) {
+ gLastKeyCodeArray[i] = Buffer[i];
+ }
+
+ if ((!(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) || gLegacyMakeCodeGenerated) &&(!gEfiMakeCodeGenerated))
+ {
+ if (Count==0) {
+ gLegacyMakeCodeGenerated=FALSE;
+ }
+ UsbScanner(DevInfo, Buffer);
+ } else {
+ if(Count==0) {
+ gEfiMakeCodeGenerated=FALSE;
+ }
+
+ if(USBKBC_CheckUsbDataBufferFull(8) == 0) {
+ return EFI_SUCCESS;
+ }
+
+ USBKBC_SendToUsbDataBuffer(Buffer);
+
+ //
+ // Reload the typematic rate value
+ //
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[
+ (gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_DELAY_BIT_MASK) >>
+ KBC_TYPE_DELAY_BIT_SHIFT];
+ gUsbData->wRepeatCounter = 0;
+
+ //
+ // Enable periodic interrupt to catch the repeat key
+ //
+ if (Count==0) {
+ USBKeyRepeat(NULL, 1); // Disable Key repeat
+ } else {
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBDPeriodicInterruptHandler
+//
+// Description: This routine is called every 16ms and is used to send
+// the characters read from USB keyboard to the keyboard
+// controller for legacy operation. Also this function updates
+// the keyboard LED status
+//
+// Input: fpHCStruc Pointer to the HCStruc structure
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBKBDPeriodicInterruptHandler (HC_STRUC* fpHcStruc)
+{
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ //(EIP83888+)>
+ if (!(*(UINT32*)gLastKeyCodeArray ||
+ *(UINT32*)(gLastKeyCodeArray + 4))) { //(EIP93637)
+ //<(EIP83888+)
+ //
+ // Keyboard data is zero, the key is released - stop repeating the key
+ //
+ USBKeyRepeat(NULL, 1); // Disable Key repeat
+ return;
+ } else {
+ //
+ // Check whether keyboard buffer is not empty;
+ // Execute Efi callback function if repeat counter is expired
+ //
+ gUsbData->wRepeatCounter++;
+ if (gUsbData->wRepeatCounter >= gUsbData->wRepeatRate) {
+ //
+ // Repeat rate is reached.
+ // Reload repeat delay counter with keyrepeat delay value; original
+ // type delay value will be restored in ProcessKeyboardData
+ //
+ gUsbData->wRepeatRate = aTypematicRateDelayTable[
+ (gUsbData->wUSBKBC_StatusFlag & KBC_TYPE_RATE_BIT_MASK) >>
+ KBC_TYPE_RATE_BIT_SHIFT];
+ gUsbData->wRepeatCounter = 0;
+
+ USBKBKeyrepeatCallback();
+ }
+ //
+ // Reenable periodic interrupt handler
+ //
+ USBKeyRepeat(NULL, 2); // Enable Key repeat
+ }
+ } else { // Not under EFI
+ LegacyAutoRepeat(fpHcStruc);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbScanner
+//
+// Description: This routine is executed to convert USB scan codes into PS/2
+// make/bread codes.
+//
+// Input: fpDevInfo - USB keyboard device
+// fpBuffer - USB scan codes data buffer
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbScanner(
+ DEV_INFO *fpDevInfo,
+ UINT8 *fpBuffer
+)
+{
+ if(gUsbData->kbc_support || ((gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_ON)
+ && (gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_IRQ_SUPPORT))) {
+ USBKBC_GetAndStoreCCB();
+ USBKB_Scanner (fpDevInfo, fpBuffer);
+ USBKB_UpdateLEDState (0xFF);
+ }else {
+ USBKB_Int9(fpBuffer);
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: LegacyAutoRepeat
+//
+// Description: This routine is called periodically based on 8ms TD and used
+// to implement the key repeat.
+//
+// Input: Hc Pointer to the HCStruc structure
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+LegacyAutoRepeat(
+ HC_STRUC *Hc
+)
+{
+ if(gUsbData->kbc_support || ((gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_ON)
+ && (gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_IRQ_SUPPORT))) {
+ SysKbcAutoRepeat(Hc);
+ } else {
+ SysNoKbcAutoRepeat();
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBKBKeyrepeatCallback
+//
+// Description: This routine is called every time the key repeat is requested
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBKBKeyrepeatCallback()
+{
+ USB_KEY UsbKey;
+ USB_KB_BUFFER *KeyboardBuffer;
+
+ if(!gUsbData->RepeatKey) return; // Do nothing when there is no repeat key.
+
+ KeyboardBuffer = gUsbData->EfiKeyboardBuffer;
+
+ //
+ // If keyboard buffer is full, throw the first key out of the keyboard buffer.
+ //
+ if (((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1)) == KeyboardBuffer->bHead) {
+
+ UsbKey.KeyCode = KeyboardBuffer->buffer[KeyboardBuffer->bHead].KeyCode;
+ UsbKey.Down = KeyboardBuffer->buffer[KeyboardBuffer->bHead].Down;
+
+ //
+ // adjust the head pointer of the FIFO keyboard buffer.
+ //
+ KeyboardBuffer->bHead = (UINT8)((KeyboardBuffer->bHead + 1) % (MAX_KEY_ALLOWED + 1));
+ }
+
+ KeyboardBuffer->buffer[KeyboardBuffer->bTail].KeyCode = gUsbData->RepeatKey;
+ KeyboardBuffer->buffer[KeyboardBuffer->bTail].Down = 1;
+
+ //
+ // adjust the tail pointer of the FIFO keyboard buffer.
+ //
+ KeyboardBuffer->bTail = (UINT8)((KeyboardBuffer->bTail + 1) % (MAX_KEY_ALLOWED + 1));
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbKbdSetLed
+//
+// Description: This routine set the USB keyboard LED status.
+//
+// Input: DevInfo Pointer to device information structure
+// LedStatus LED status
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+UsbKbdSetLed (
+ DEV_INFO *DevInfo,
+ UINT8 LedStatus
+)
+{
+ HC_STRUC *HcStruc = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+ DEV_REQ DevReq = {0};
+ UINT8 Status;
+ UINT8 ReportId = 0;
+ UINT16 ReportLen;
+ UINT8 *ReportData = NULL;
+ UINT8 Index;
+
+ if ((DevInfo->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) &&
+ !(DevInfo->HidReport.Flag & HID_REPORT_FLAG_LED_FLAG)) {
+ return USB_ERROR;
+ }
+
+ ReportData = USB_MemAlloc(GET_MEM_BLK_COUNT(4));
+ if (ReportData == NULL) return USB_ERROR;
+
+ ReportLen = 1;
+ ReportData[0] = LedStatus & 0x7;
+
+ if (DevInfo->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) {
+ if (DevInfo->HidReport.Fields == NULL) {
+ USB_MemFree(ReportData, GET_MEM_BLK_COUNT(4));
+ return USB_ERROR;
+ }
+ for (Index = 0; Index < DevInfo->HidReport.FieldCount; Index++) {
+ //find start offset
+ if ((DevInfo->HidReport.Fields[Index]->UsagePage == 0x8) &&
+ (DevInfo->HidReport.Fields[Index]->ReportId != 0) &&
+ (DevInfo->HidReport.Fields[Index]->Usages[0] == 1)) {
+ ReportId = DevInfo->HidReport.Fields[Index]->ReportId;
+ ReportData[1] = ReportData[0];
+ ReportData[0] = ReportId;
+ ReportLen++;
+ }
+ }
+ }
+ if (DevInfo->IntOutEndpoint == 0) {
+ DevReq.wRequestType = HID_RQ_SET_REPORT;
+ DevReq.wValue = (0x02 << 8) | ReportId; // Output
+ DevReq.wIndex = DevInfo->bInterfaceNum;
+ DevReq.wDataLength = ReportLen;
+
+ Status = UsbControlTransfer(HcStruc, DevInfo, DevReq, USB_KBD_SET_LED_TIMEOUT_MS, ReportData);
+ } else {
+ Status = UsbInterruptTransfer(HcStruc, DevInfo, DevInfo->IntOutEndpoint,
+ DevInfo->IntOutMaxPkt, ReportData, ReportLen, USB_KBD_SET_LED_TIMEOUT_MS);
+ }
+
+ USB_MemFree(ReportData, GET_MEM_BLK_COUNT(4));
+ return Status;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbkbd.h b/Core/EM/usb/rt/usbkbd.h
new file mode 100644
index 0000000..674a2f8
--- /dev/null
+++ b/Core/EM/usb/rt/usbkbd.h
@@ -0,0 +1,436 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbkbd.h 20 3/18/16 12:03a Wilsonlee $
+//
+// $Revision: 20 $
+//
+// $Date: 3/18/16 12:03a $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbkbd.h $
+//
+// 20 3/18/16 12:03a Wilsonlee
+// [TAG] EIP257506
+// [Category] Improvement
+// [Description] Add USB_KEYREPEAT_INTERVAL token to change the key
+// repeat interval.
+// [Files] usb.sdl, xhci.h, usbkbd.h, uhci.c, ohci.c, ehci.c
+//
+// 19 3/02/16 9:42p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 18 2/24/15 5:50a Wilsonlee
+// [TAG] EIP149716
+// [Category] Improvement
+// [Description] Error Handling in USB mouse data.
+// [Files] usbms.c, usbkbd.h, syskbc.c, xhci.c
+//
+// 17 5/06/14 5:16a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 16 2/26/14 1:56a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 15 12/30/13 3:42a Wilsonlee
+// [TAG] EIP148411
+// [Category] Improvement
+// [Description] Check if CCB_MOUSE_INTRPT is set before we sent mouse
+// data.
+// [Files] usbkbd.h, syskbc.c
+//
+// 14 7/04/13 5:49a Roberthsu
+// [[TAG] EIP127014
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse drifting not smooth
+// [RootCause] Bbecause Efi simple point protocol RelativeMovementX
+// type is INT32.
+// [Solution] Transfer data type to INT32.
+// [Files] usbdef.h,usbhid.c,usbms.c,usbkbd.h
+//
+// 13 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 12 5/22/12 10:57a Jittenkumarp
+// [TAG] EIP87959
+// [Category] New Feature
+// [Description] Proper Error path in the USB driver, incase KBC Input
+// buffer is full
+// [Files] usbkbd.h, syskbc.c
+//
+// 11 5/03/12 6:28a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 10 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 9 9/16/09 11:10a Olegi
+//
+// 8 9/15/09 12:21p Olegi
+// Added KEY_REPEAT_LOGIC functionality. EIP#25841
+//
+// 7 9/05/08 4:22p Olegi
+//
+// 6 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 5 3/20/07 12:21p Olegi
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 8/25/05 7:19p Andriyn
+// USB Keyboard and mouse to use EMUL 60/64 for passing data to KBC.
+// Fall-back when EMUL 60/64 is not present
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbKbd.h
+//
+// Description: AMI USB keyboard support header
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+// Avoid including multiple instance of this file
+#ifndef __USBKBD_H
+#define __USBKBD_H
+
+#include "token.h"
+
+// Make/break code equates
+
+#define KBC_AUTO_REPEAT_BIT_MASK (0x01 << 9)
+#define KBC_PASSWORD_FLAG_BIT_MASK (0x01 << 10)
+#define KBC_SCANNER_STATUS_BIT_MASK (0x01 << 11)
+#define KBC_PORT6064_TRAP_BIT_MASK (0x01 << 12)
+#define KBC_MK_BRK_CODE_BIT_MASK (0x01 << 13)
+
+#define USB_GEN_MAKE_CODE 0x020
+#define USB_GEN_BREAK_CODE 0x030
+
+
+// Equates used by keyboard controller scanner code
+#define LEFT_ALT 0x011 // Left-ALT scan code (set 2)
+#define LEFT_CTRL 0x014 // Left-CTRL scan code (set 2)
+#define LEFT_SHIFT 0x012 // Left-SHIFT scan code (set 2)
+#define RIGHT_SHIFT 0x059 // Right-SHIFT scan code (set 2)
+
+// Extended status flag bit definitions
+#define KBCEXT_LED_UPDATE_IN_PROGRESS_BIT BIT0
+
+// Scan code for base case only
+#define RIGHT_ALT 0x011+0x80 // Local code id (scan-2)
+#define RIGHT_CTRL 0x014+0x80 // Local code id (scan-2)
+#define LEFT_MS_KEY 0x01F+0x80 // Microsoft left key
+#define RIGHT_MS_KEY 0x027+0x80 // Microsoft right key
+#define APP_MS_KEY 0x02F+0x80 // Microsoft application key
+#define RIGHT_ENTER 0x05A+0x80 // Local code id (scan-2)
+
+// Equates for KB shift key status information
+#define KB_FUNCTION_BIT 7 // Function key LED bit
+#define KB_FUNCTION_BIT_MASK (1 << KB_FUNCTION_BIT)
+#define KB_SCROLL_LOCK_BIT 6 // Scroll key LED bit
+#define KB_SCROLL_LOCK_BIT_MASK (1 << KB_SCROLL_LOCK_BIT)
+#define KB_CAPS_LOCK_BIT 5 // CAPS lock key LED bit
+#define KB_CAPS_LOCK_BIT_MASK (1 << KB_CAPS_LOCK_BIT)
+#define KB_NUM_LOCK_BIT 4 // NUM lock key LED bit
+#define KB_NUM_LOCK_BIT_MASK (1 << KB_NUM_LOCK_BIT )
+#define KB_ALT_KEY_BIT 3 // ALT key status bit
+#define KB_ALT_KEY_BIT_MASK (1 << KB_ALT_KEY_BIT )
+#define KB_CTRL_KEY_BIT 2 // CTRL key status bit
+#define KB_CTRL_KEY_BIT_MASK (1 << KB_CTRL_KEY_BIT )
+#define KB_LSHIFT_KEY_BIT 1 // LSHIFT key status bit
+#define KB_LSHIFT_KEY_BIT_MASK (1 << KB_LSHIFT_KEY_BIT)
+#define KB_RSHIFT_KEY_BIT 0 // RSHIFT key status bit
+#define KB_RSHIFT_KEY_BIT_MASK (1 << KB_RSHIFT_KEY_BIT)
+
+#define KBC_SCAN_CODE_SET_BIT_SHIFT 0
+#define KBC_SET_SCAN_CODE_SET2 (0x02 << KBC_SCAN_CODE_SET_BIT_SHIFT)
+#define KBC_SCAN_CODE_SET_BIT_MASK (0x03 << KBC_SCAN_CODE_SET_BIT_SHIFT)
+
+#if USB_KEYREPEAT_INTERVAL
+#define REPEAT_INTERVAL 16
+#define KBC_TYPE_RATE_BIT_SHIFT 1
+#define KBC_TYPE_RATE_BIT_MASK (0x05 << KBC_TYPE_RATE_BIT_SHIFT)
+
+#define KBC_TYPE_DELAY_BIT_SHIFT 4
+#define KBC_TYPE_DELAY_BIT_MASK (0x05 << KBC_TYPE_DELAY_BIT_SHIFT)
+
+#else
+#define REPEAT_INTERVAL 8
+#define KBC_TYPE_RATE_BIT_SHIFT 2
+#define KBC_TYPE_RATE_BIT_MASK (0x07 << KBC_TYPE_RATE_BIT_SHIFT)
+
+#define KBC_TYPE_DELAY_BIT_SHIFT 6
+#define KBC_TYPE_DELAY_BIT_MASK (0x07 << KBC_TYPE_DELAY_BIT_SHIFT)
+#endif
+
+
+// Scan code common to all the cases (base, control, shift and alt cases)
+#define PRINT_SCREEN (0x07C + 0x80) // Local code id (scan-2)
+
+// Scan code common to base and control cases
+#define PAUSE_KEY (0x07E + 0x80) // Local code id (scan-2)
+
+// Scan code common to base and shift cases
+#define SLASH_KEY (0x4A + 0x80) // Local code id (scan-2)
+
+// Scan code common to base, shift and num lock cases
+#define END_KEY (0x069 + 0x80) // Local code id (scan-2)
+#define LEFT_KEY (0x06B + 0x80) // Local code id (scan-2)
+#define HOME_KEY (0x06C + 0x80) // Local code id (scan-2)
+#define INSERT_KEY (0x070 + 0x80) // Local code id (scan-2)
+#define DEL_KEY (0x071 + 0x80) // Local code id (scan-2)
+#define DOWN_KEY (0x072 + 0x80) // Local code id (scan-2)
+#define RIGHT_KEY (0x074 + 0x80) // Local code id (scan-2)
+#define UP_KEY (0x075 + 0x80) // Local code id (scan-2)
+#define PAGE_DOWN_KEY (0x07A + 0x80) // Local code id (scan-2)
+#define PAGE_UP_KEY (0x07D + 0x80) // Local code id (scan-2)
+
+#define CCB_TRANSLATE_SCAN_CODE_BIT_MASK BIT6
+#define KBC_COMMAND_REG 0x64
+#define KBC_SUBCOMMAND_REG 0x60
+#define KBC_STATUS_REG 0x64
+#define KBC_DATA_REG 0x60
+
+#define MOUSE_ENABLED_BIT 7
+#define MOUSE_ENABLED_BIT_MASK (1 << MOUSE_ENABLED_BIT)
+#define MOUSE_DATA_READY_BIT 6
+#define MOUSE_DATA_READY_BIT_MASK (1 << MOUSE_DATA_READY_BIT)
+#define MOUSE_DATA_FROM_USB_BIT 5
+#define MOUSE_DATA_FROM_USB_BIT_MASK (1 << MOUSE_DATA_FROM_USB_BIT)
+ // Mouse data size = 1:4byte data, 0:3byte data
+#define MOUSE_4BYTE_DATA_BIT 4
+#define MOUSE_4BYTE_DATA_BIT_MASK (1 << MOUSE_4BYTE_DATA_BIT)
+
+#define KBC_DATA_TX_ORDER_BIT_MASK 0x03 << 14
+#define KBC_DATA_TX_ORDER_INC_VALUE 0x01 << 14
+#define KBC_DATA_TX_ORDER_KB_FIRST 0x02 << 14
+
+#define CCB_KEYBOARD_INTRPT BIT0
+#define CCB_MOUSE_INTRPT BIT1
+#define CCB_KEYBOARD_DISABLED BIT4
+#define CCB_MOUSE_DISABLED BIT5
+#define CCB_TRANSLATE_SCAN_CODE_BIT_MASK BIT6
+
+#ifndef USB_KBD_SET_LED_TIMEOUT_MS
+#define USB_KBD_SET_LED_TIMEOUT_MS 100
+#endif
+
+UINT8 ByteReadIO(UINT16);
+void ByteWriteIO(UINT16, UINT8);
+
+UINT8 USBMouse_GetFromMouseBuffer ();
+void USBKeyRepeat(HC_STRUC*, UINT8);
+UINT8 USBKBC_GetFromCharacterBuffer();
+
+UINT8 USBKB_ConvertSet2CodeToSet1Code(UINT8);
+void USBKBC_SendToCharacterBuffer(UINT8);
+UINT8 USBTrap_GetCurrentScanCodeSetNumber();
+UINT8 USBKB_ConvertScanCodeBetweenCodeSet(UINT8, UINT8*);
+//void SYSKBC_UpdateLEDState(UINT8);
+UINT8 KBC_WaitForInputBufferToBeFree( );
+UINT8 KBC_WaitForOutputBufferToBeFilled( );
+void USBKB_GenerateType1MakeCode( );
+void USBKB_GenerateType1BreakCode( );
+void USBKB_GenerateType2MakeCode( );
+void USBKB_GenerateType2BreakCode( );
+UINT8 USBTrap_GetOverrunCode( );
+void USBKB_DiscardCharacter(UINT8*);
+UINT16 USBKB_CheckForExtendedKey(UINT8);
+UINT16 USBKB_CheckForNumericKeyPadKey(UINT8);
+UINT8 USBKBC_CheckCharacterBufferFull(UINT8);
+void USBKB_UpdateLEDState(UINT8);
+UINT8 USBKB_ConvertUSBKeyCodeToScanCodeSet2 (UINT8);
+UINT16 USBKB_CheckModifierKeyPress (UINT8);
+UINT8 KBC_WriteCommandByte(UINT8);
+UINT8 KBC_ReadDataByte(UINT8 *);
+void KBC_WriteSubCommandByte(UINT8);
+EFI_STATUS SYSKBC_SendKBCData();
+
+extern UINT8 USB_InstallCallBackFunction (CALLBACK_FUNC);
+
+extern DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*,UINT8, HC_STRUC*);
+extern UINT8 USBLogError(UINT16);
+extern void USBKeyRepeat(HC_STRUC*, UINT8);
+#if USB_DEV_MOUSE
+extern UINT8 USBMSSendMouseData();
+extern void USBMSUpdateMouseInterface();
+#endif
+
+void USBKBDInitialize (void);
+UINT8 USBKBDDisconnectDevice (DEV_INFO*);
+
+void USBKBC_GetAndStoreCCB();
+DEV_INFO* USBKBDConfigureDevice (DEV_INFO*); //(EIP84455)
+UINT16 USBKBDFindUSBKBDeviceTableEntry(DEV_INFO*);
+UINT16 USBKBDConnectKeyboard(DEV_INFO*);
+UINT8 USBKBDProcessKeyboardData ( HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 UsbKbdSetLed(DEV_INFO*, UINT8);
+
+void USBKB_GenerateScanCode ( UINT8, UINT8, UINT16 );
+
+VOID UsbScanner(DEV_INFO*, UINT8*);
+VOID USBKB_Scanner (DEV_INFO*, UINT8*);
+VOID USBKB_Int9(UINT8*);
+
+VOID ProcessKeyCode(UINT8);
+
+VOID LegacyAutoRepeat(HC_STRUC*);
+VOID SysKbcAutoRepeat(HC_STRUC*);
+VOID SysNoKbcAutoRepeat();
+VOID USBKBKeyrepeatCallback();
+VOID USBKBDPeriodicInterruptHandler(HC_STRUC*);
+ //(EIP84455+)>
+UINT8 USBHIDProcessData( HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 USBMSProcessMouseData ( HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+UINT8 USBAbsProcessMouseData ( HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+ //<(EIP84455+)
+
+typedef struct _LEGACY_USB_KEY_MODIFIERS {
+ UINT8 ScrlLock : 1;
+ UINT8 NumLock : 1;
+ UINT8 CapsLock : 1;
+ UINT8 Ctrl : 1;
+ UINT8 Alt : 1;
+ UINT8 Shift : 1;
+} LEGACY_USB_KEY_MODIFIERS;
+
+typedef struct _LEGACY_USB_KEYBOARD {
+ UINT8 KeyCodeStorage[6];
+ LEGACY_USB_KEY_MODIFIERS KeyModifierState;
+ UINT8 KeyToRepeat;
+} LEGACY_USB_KEYBOARD;
+
+ //(EIP38434+)>
+typedef struct {
+ union {
+ UINT8 Modifier;
+ struct {
+ UINT8 KB_RSHIFT : 1;// RSHIFT key status bit
+ UINT8 KB_LSHIFT : 1;// LSHIFT key status bit
+ UINT8 KB_CTRL : 1;// CTRL key status bit
+ UINT8 KB_ALT : 1;// ALT key status bit
+ UINT8 KB_NUM_LOCK : 1;// NUM lock key LED bit
+ UINT8 KB_CAPS_LOCK : 1;// CAPS lock key LED bit
+ UINT8 KB_SCROLL_LOCK : 1;// Scroll key LED bit
+ UINT8 KB_FUNCTION : 1;// Function key LED bit
+ } Modify;
+ };
+ UINT8 Reserved;
+ UINT8 Keycode[6];
+}USBKBD_DATA;
+
+// 0 Bit Description
+// -------------------------------------------
+// 0 If set, button 1 is pressed
+// 1 If set, button 2 is pressed
+// 2 If set, button 3 is pressed
+// 3-7 Reserved
+// -------------------------------------------
+// 1 X displacement value
+// 2 Y displacement value
+typedef struct {
+ union {
+ UINT8 ButtonByte;
+ struct {
+ UINT8 BUTTON1 : 1;// RSHIFT key status bit
+ UINT8 BUTTON2 : 1;// LSHIFT key status bit
+ UINT8 BUTTON3 : 1;// CTRL key status bit
+ UINT8 RESERVED : 5;// ALT key status bit
+ } BUTTON;
+ };
+ UINT8 X;
+ UINT8 Y;
+ UINT8 Z;
+ UINT16 EfiX; //(EIP127014)
+ UINT16 EfiY; //(EIP127014)
+ UINT8 FillUsage; //(EIP127014)
+}USBMS_DATA;
+
+typedef struct {
+ UINT8 Button;
+ UINT16 X;
+ UINT16 Y;
+ UINT16 Pressure;
+}USBABS_DATA;
+ //<(EIP38434+)
+#endif // __USB_H
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbmass.c b/Core/EM/usb/rt/usbmass.c
new file mode 100644
index 0000000..0bdb683
--- /dev/null
+++ b/Core/EM/usb/rt/usbmass.c
@@ -0,0 +1,5506 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbmass.c 174 10/20/16 11:19p Wilsonlee $
+//
+// $Revision: 174 $
+//
+// $Date: 10/20/16 11:19p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+//
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbmass.c $
+//
+// 174 10/20/16 11:19p Wilsonlee
+// [TAG] EIP297268
+// [Category] Improvement
+// [Description] Update Media information only in EfiUsbMass driver when
+// Media is changed.
+// [Files] usbmass.c, efiusbmass.c
+//
+// 173 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 172 7/22/16 3:51a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 171 7/07/16 1:09a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 170 4/08/16 3:54a Wilsonlee
+// [TAG] EIP260113
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] We return success for writing data to to the
+// write-protected device.
+// [RootCause] Command Block Status is Command Failed when we send the
+// write command to the write-protected device.
+// [Solution] When CSW isn't Valid, we should issue a REQUEST SENSE
+// command to receive the sense data describing what caused the error
+// condition.
+// [Files] usbmass.c
+//
+// 169 3/02/16 9:41p Wilsonlee
+// [TAG] EIP254309
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] GK-FORCE K83 USB KB function abnormal.
+// [RootCause] This device has an interrupt out endpoint and doesn't
+// support "Set Report" request.
+// [Solution] Use the interrupt out endpoint instead of sending "Set
+// Report" request.
+// [Files] AmiUsbController.h, xhci.c, usbmass.c, usbkbd.h, usbkbd.c,
+// usbhub.c, usbhid.c, usbdef.h, usbCCID.c, usb.c, uhci.c, ohci.c, ehci.c,
+// amiusb.h, efiusbms,c, amiusbhc.c
+//
+// 168 2/14/16 9:46p Wilsonlee
+// [TAG] EIP254924
+// [Category] Improvement
+// [Description] Issue a Set TR Dequeue Pointer Command after issuing
+// for a ClearFeature(ENDPOINT_HALT) request to device.
+// [Files] usbmass.c, xhci.c
+//
+// 167 7/24/15 4:41a Wilsonlee
+// [TAG] EIP226493
+// [Category] Improvement
+// [Description] Block to process periodic list to prevent that we might
+// send the wrong command sequences to the same device.
+// [Files] usbmass.c, ehci.c, xhci.h, xhci.c, usbdef.h, uhcd.c
+//
+// 166 5/27/15 2:13a Wilsonlee
+// [TAG] EIP220162
+// [Category] Improvement
+// [Description] The read / write request contain the latest LBA that
+// are valid.
+// [Files] usbmass.c, efiusbmass.c
+//
+// 165 4/29/15 11:26p Wilsonlee
+// [TAG] EIP215031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Transcend USB 3.0 HDD is disappeared in the setup menu by
+// cold boot.
+// [RootCause] We only can get SerialNumber string descriptor before
+// setting configuration for this device, otherwise it is failed at
+// getting this descriptor and inquiry command is also failed.
+// [Solution] Retry inquiry command.
+// [Files] usb.c, usbmass.c, efiusbmass.c, usbbus.c, usbdef.h
+//
+// 164 1/15/15 9:54p Wilsonlee
+// [TAG] EIP198806
+// [Category] Improvement
+// [Description] Send "RequestSense" command only if "TestUnitReady"
+// command is failed.
+// [Files] usbmass.c
+//
+// 163 12/24/14 1:08a Wilsonlee
+// [TAG] EIP192517
+// [Category] Improvement
+// [Description] SB Driver handles 0x100 NumHeads as a valid value.
+// [Files] usbmass.c, usbdef.h, UsbInt13.c, UsbInt13.h, UI13.bin,
+// Bfiusb.equ, Bfiusb.asm
+//
+// 162 11/30/14 10:30p Wilsonlee
+// [TAG] EIP193829
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Ghost on multiple USB dvd rom span (Legacy Dos )fails if
+// boot disk is smaller than second disk.
+// [RootCause] RWVCommand gets one byte data after we change Media, but
+// data isn't correct.
+// [Solution] Check if data length processed is correct.
+// [Files] usbmass.c
+//
+// 161 11/24/14 12:56a Wilsonlee
+// [TAG] EIP192326
+// [Category] Improvement
+// [Description] Check that division by zero exception doesn't occur.
+// [Files] usbmass.c
+//
+// 160 11/23/14 10:53p Wilsonlee
+// [TAG] EIP186754
+// [Category] Improvement
+// [Description] The minimum of sector should be 1.
+// [Files] usbmass.c
+//
+// 159 11/23/14 10:36p Wilsonlee
+// [TAG] EIP188492
+// [Category] Improvement
+// [Description] Create a token to keep usb mass storage devices are
+// RemovableMedia.
+// [Files] usbmass.c, usb.sdl
+//
+// 158 9/02/14 4:09a Wilsonlee
+// [TAG] EIP183522
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Heads, Sectors and Cylinders aren't correct if usb mass
+// storages report media change.
+// [RootCause] We update CHS from read capacity parameters if media
+// change.
+// [Solution] We already update CHS from boot record and legacy boot
+// doesn't support dynamic media insertion, we should not update it from
+// read capacity parameters.
+// [Files] usbmass.c
+//
+// 157 8/07/14 5:35a Wilsonlee
+// [TAG] EIP180686
+// [Category] Improvement
+// [Description] Right shifts 64bit values that should be using Shr64().
+// [Files] usbmass.c
+//
+// 156 7/04/14 5:23a Wilsonlee
+// [TAG] EIP175485
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] USB key can't be save during secure boot key.
+// [RootCause] The usb key, MSI 8G Team, has two luns. One is CD-ROM, it
+// always reports there is no media until we send "Get_Configuration"
+// command to it, then it causes the other lun will report media change
+// when we read/write data later.
+// [Solution] Send "Get_Configuration" command for CD/DVD devices.
+// [Files] usbmass.c
+//
+// 155 6/26/14 1:16a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 154 4/30/14 5:25a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 153 4/30/14 1:59a Wilsonlee
+// [TAG] EIP162993
+// [Category] Improvement
+// [Description] We need to return success on INT 13 func 2 even if
+// there is no media.
+// [Files] usbmass.c, UI13.bin, Bfiusb.asm
+//
+// 152 4/29/14 8:55p Wilsonlee
+// [TAG] EIP165610
+// [Category] Improvement
+// [Description] We still need to try readformatcapacity command even if
+// the subclass isn't UFI.
+// [Files] usbmass.c
+//
+// 151 4/29/14 8:47p Wilsonlee
+// [TAG] EIP152539
+// [Category] Improvement
+// [Description] If the pervious device status is that media not present
+// and current device status comes as media present, modified the code to
+// report as media changed along with current status in the usbmass.c.
+// [Files] usbmass.c
+//
+// 150 4/07/14 2:07a Wilsonlee
+// [TAG] EIP156126
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] The power Format of UEFI can not be identified when we
+// install OS from USB CD-ROM.
+// [RootCause] The media information is incorrect when we install
+// BlockIoProtocol for usb CD / DVD devices.
+// [Solution] Get the media status before we install BlockIoProtocol.
+// [Files] usbmass.c, usbdef.h, efiusbmass.c
+//
+// 149 4/03/14 3:32a Wilsonlee
+// [TAG] EIP161240
+// [Category] Improvement
+// [Description] Use Div64 if variables is UINT64.
+// [Files] usbmass.c
+//
+// 148 2/25/14 10:15p Wilsonlee
+// [TAG] EIP155805
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] WinCE loader can't boot.
+// [RootCause] It can't boot if the mass storage doesn't have validate
+// partition table.
+// [Solution] We should set the type to FORCED_FDD if it's not a Floppy
+// and doesn't have validate partition table.
+// [Files] usbmass.c
+//
+// 147 12/23/13 1:56a Ryanchou
+// [TAG] EIP147532
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Dynamic DVD Insertion failed to Read the files
+// [RootCause] The Last Block is not updated properly when the new CD is
+// inserted.
+// [Solution] Update geometry if media is changed.
+// [Files] usbmass.c
+//
+// 146 12/15/13 10:16p Wilsonlee
+// [TAG] EIP136594
+// [Category] New Feature
+// [Description] Support 64 bits LBA of usb mass storages.
+// [Files] Bfiusb.asm, Bfiusb.equ, UsbInt13.c, UsbInt13.h, amiusb.c,
+// usbdef.h, usbmass.c, UsbMass.h, efiusbmass.c, UI13.bin
+//
+// 145 10/20/13 11:32p Wilsonlee
+// [TAG] EIP139719
+// [Category] Improvement
+// [Description] Ignore the bulk data if the status transport causes
+// time out.
+// [Files] usbmass.c
+//
+// 144 9/04/13 5:35a Wilsonlee
+// [TAG] EIP135036
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MultilUN deviices don't install successfully after hotplug
+// in shell.
+// [RootCause] We skip to get maximum LUN if this mass storage is
+// already registered.
+// [Solution] Get maximum LUN even if this mass storage is already
+// registered.
+// [Files] usbmass.c
+//
+// 143 9/04/13 4:49a Wilsonlee
+// [TAG] EIP133270
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Sony MS card reader sometimes cause system hang at 0xD5.
+// [RootCause] This device may return the wrong data when we send "read
+// format capacities" command.
+// [Solution] Return error if capacity list header is wrong.
+// [Files] usbmass.c
+//
+// 142 8/23/13 5:41a Ryanchou
+// [TAG] EIP131624
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB mass storage configured fails
+// [RootCause] USB Mass Storage driver canot find the correct DeviccInfo
+// structure if it is a multiple interface device and the first interface
+// is not mass storage class
+// [Solution] Compare the DeviceInfo pointer to find the correct one,
+// not device address
+// [Files] usbmass.c
+//
+// 141 8/02/13 6:17a Ryanchou
+//
+// 140 7/29/13 5:21a Roberthsu
+// [TAG] EIP126741
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Cannot boot to uefi usb device with Sophos software.
+// [RootCause] When boot into tool. Ownership to os event occur.Usb
+// will disconnect device.And record this disconnect event. Then ownership
+// to bios,bios will connect all device.Run legacy to efi function. Bios
+// run disconnect event first.Then reconnect device.Because usb key behind
+// hub. So usb key disconnect also.
+// [Solution] Check device when device reconnect.If device and port
+// number the same.Use the same device info.
+// [Files] usb.c,usbmass.c,efiusbmass.c,uhcd.c
+//
+// 139 7/23/13 11:50a Pats
+// [TAG] EIP128964
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Int 13 Function 08 doesn't work right for USB mass storage
+// devices.
+// [RootCause] The default Head and Sector values for USB mass storage
+// devices are fixed, resulting in a Cylinder value that is too large for
+// the CHS format, when the device is over 2095104 sectors in size.
+// [Solution] Modify function USBMassSetDefaultGeometry() to use Head and
+// Sector values based ot total size.
+// [Files] usbmass.c
+//
+// 138 7/23/13 2:14a Wilsonlee
+// [TAG] EIP127941
+// [Category] Improvement
+// [Description] Replace UI13HDDFunc08 with UI13FDDFunc08 if the media
+// descriptor is a fixed disk.
+// [Files] UsbInt13.h, UsbInt13.c, usbmass.c, usbdef.h, Bfiusb.asm,
+// Bfiusb.equ
+//
+// 137 7/03/13 4:48a Ryanchou
+// [TAG] EIP127800
+// [Category] Improvement
+// [Description] Add non-bootable device type handing
+// [Files] usbmass.c, efiusbmass.c
+//
+// 136 3/19/13 3:59a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 135 3/08/13 4:04a Roberthsu
+// [TAG] EIP113379
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB MBR data read with 125MB USB key will get wrong
+// value
+// [RootCause] When device emu force floppy.Read command will clear
+// some information when read mbr.
+// [Solution] If device emu force floppy.Only change mbr data when
+// legacy.
+// [Files] usbmass.c
+//
+// 134 1/22/13 5:10a Wilsonlee
+// [TAG] EIP110635
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] ReadOnly attribute is not properly updated for USB FDD.
+// [RootCause] The Media change status never gets refelected in
+// AmiUsbBlkIoReadWrite function.
+// [Solution] We should pass this information if the media has changed.
+// [Files] usbmass.c
+//
+// 133 1/22/13 3:09a Wilsonlee
+// [TAG] EIP112938
+// [Category] Improvement
+// [Description] Create a header file for usb mass storage driver.
+// [Files] UsbMass.h, usbmass.c, usbdef.h, amiusb.c, efiusbmass.c
+//
+// 132 1/22/13 2:38a Wilsonlee
+// [TAG] EIP110305
+// [Category] Improvement
+// [Description] Set the device address after we send the first
+// get-device-descriptor command.
+// [Files] usbmass.c, usb.c, usbdef.h, usbbus.c, efiusbmass.c, uhcd.c,
+// usbport.c
+//
+// 131 1/11/13 4:15a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 130 12/24/12 1:43a Roberthsu
+// [TAG] EIP107198
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Run gdisk.exe fail
+// [RootCause] Device no media, gdisk call int13 get worng geometry.
+// [Solution] If device no present.Do not return geometry.
+// [Files] usbmass.c
+//
+// 129 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 128 10/03/12 5:40a Wilsonlee
+// [TAG] EIP101623
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Fingerprint reader causes system waiting a long period at
+// PC B4.
+// [RootCause] The fingerprint reader returns sense key 0x02 instead of
+// 0x00 if it doesn't have error sense key for request sense command.
+// Which causes our code to repeatly wait for correct sense key.
+// [Solution] We should send the request sense command only if the CSW
+// is failed. However, current architecture has side-effect with this
+// method. So we skip the sense key 0x02 as a workaround here.
+// [Files] usbmass.c
+//
+// 127 9/28/12 2:38a Wilsonlee
+// [TAG] EIP93154
+// [Category] Improvement
+// [Description] Change the unit of the FixedDelay from 15 us to 1 us.
+// [Files] amiusb.h, xhci.c, ehci.c, ohci.c, uhci.c, usb.c, usbCCID.c,
+// usbmass.c, usbhub.c, elib.c
+//
+// 126 9/04/12 8:03a Wilsonlee
+// [TAG] EIP99882
+// [Category] New Feature
+// [Description] Add the usb setup item and usbpolicyprotocol to enable
+// or disable the usb mass storage driver.
+// [Files] UsbPolicy.h, usb.uni, usb.sd, usbmass.c, usbdef.h,
+// efiusbmass.c, usbport.c, uhcd.c
+//
+// 125 8/13/12 2:10a Roberthsu
+// [TAG] EIP94060
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB key can not boot to DOS after Ctrl+Alt+Del
+// [RootCause] Because some device does not support mode sense
+// command.
+// [Solution] Send mode sense command when device type is UFI .
+// [Files] usbmass.c
+//
+// 124 7/12/12 2:39a Roberthsu
+// [TAG] EIP93460
+// [Category] Improvement
+// [Description] Add token decide mass available under efi application
+// when legacy support disabled.
+// [Files] usb.sd,usb.uni,usbmass.c,usbsrc.sdl
+//
+// 123 6/28/12 10:21p Wilsonlee
+// [TAG] EIP90503
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Plug USB card reader cause time too long to boot
+// [RootCause] t sometimes happens "STALL" when data transport, then the
+// next command will causes device timeout (20 seconds).
+// [Solution] We perform reset recovery if there is the second "STALL"
+// when we attempt to read CSW from Bulk-in endpoint.
+// [Files] usbmass.c
+//
+// 122 6/14/12 2:59a Ryanchou
+// [TAG] EIP91363
+// [Category] Improvement
+// [Description] Correct the initial value of variable "bRetValue" in
+// USBMassReadSector.
+// [Files] usbmass.c
+//
+// 121 5/03/12 4:36a Ryanchou
+// [TAG] EIP88240
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Disconnect and Connect USB Mass Driver will cause system
+// hang up.
+// [RootCause] The data toggle is not sync with device.
+// [Solution] Remove the code that reset data toggle in
+// USBMassConfigureStorageDevice.
+// [Files] usbmass.c
+//
+// 120 5/02/12 8:12a Wilsonlee
+// [TAG] EIP86793
+// [Category] New Feature
+// [Description] Add the SDL token "USB_MASS_EMULATION_FOR_NO_MEDIA" for
+// determine the USB mass storage device emulation type without media.
+// [Files] usbmass.c, usbport.c, uhcd.c, usbdef.h, usbsrc.sdl
+//
+// 119 4/10/12 9:51p Wilsonlee
+// [TAG] EIP84684
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Access SD Card In Auto Mode Test Fail - 1APUY012 BQA (F1)
+// [RootCause] Usb module token MAX_SIZE_FOR_FLOPPY_EMULATION
+// redefinition.
+// [Solution] Change the token name to
+// MAX_SIZE_FOR_USB_FLOPPY_EMULATION.
+// [Files] usbmass.c, usbsrc.sdl
+//
+// 118 4/06/12 5:01a Ryanchou
+// [TAG] EIP83321
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System hangs at checkpoint 0xBd with specific USB key.
+// [RootCause] The device report itself as floppy after reset, the
+// subclass is UFI device and protocol is CBI with command completion
+// interrupt, but there is the interrupt endpoint in the configuration
+// descriptor.
+// [Solution] Check if the interrupt is invalid, if it is invalid, skip
+// the status transport.
+// [Files] usbmass.c
+//
+// 116 4/05/12 7:28a Wilsonlee
+// [TAG] EIP86125
+// [Category] Improvement
+// [Description] Clear the flag ¡§USB_MASS_MEDIA_CHANGED¡¨when the
+// sensekey is 0.
+// [Files] usbmass.c
+//
+// 115 3/20/12 10:34p Wilsonlee
+// [TAG] EIP83295
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] System will hang at B2 when do S3/S4 long run test or DOS
+// reboot test.
+// [RootCause] It causes the stack problem when we call
+// IsUSBKeyboardBufferEmpty function.
+// [Solution] Change to use pointer as parameter to
+// IsUSBKeyboardBufferEmpty function.
+// [Files] efiusbkb.c, efisubkb.h, usbmass.c, ehci.c
+//
+// 114 1/14/12 6:39a Wilsonlee
+// [TAG] EIP80382
+// [Category] New Feature
+// [Description] Add the SDL token "USB_MASS_EMULATION_BY_SIZE" for
+// determine the USB mass storage device emulation type by size only.
+// [Files] usbmass.c, usbport.c, uhcd.c, usbdef.h, usbsrc.sdl
+//
+// 113 1/13/12 4:25a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 112 1/06/12 12:58a Rajeshms
+// [TAG] EIP62737
+// [Category] Improvement
+// [Description] Added USB Device number into USB mass device name
+// string based on SDL Token.
+// [Files] Usb.sdl, usbport.c, usbmass.c, UsbInt13.h, UsbInt13.c,
+// usbbus.c, Bfiusb.equ
+//
+// 111 11/08/11 7:39a Ryanchou
+// [TAG] EIP71262
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Sanyo ICR-PS401RM cause system hang at PC B4
+// [RootCause] The data length of Read Format Capacity command returned
+// exceed allocation length.
+// [Solution] Increase the allocation length to avoid this issue.
+// [Files] usbmass.c
+//
+// 110 11/08/11 2:23a Ryanchou
+// [TAG] EIP63706
+// [Category] Improvement
+// [Description] Filter out the character if it is invisible.
+// [Files] usbmass.c
+//
+// 109 11/05/11 7:36a Wilsonlee
+// [TAG] EIP64781
+// [Category] New Feature
+// [Description] Added SDL token
+// SKIP_CARD_READER_CONNECT_BEEP_IF_NO_MEDIA that skip the connect beep if
+// no media present in USB card reader.
+// [Files] usbport.c, usbmass.c, usb.c, usbdef.h, uhcd.c, usbsrc.sdl
+//
+// 108 10/24/11 4:55a Ryanchou
+// [TAG] EIP70814
+// [Category] Improvement
+// [Description] Read a block size each time to avoid out of memory
+// problem.
+// [Files] usbmass.c
+//
+// 107 8/08/11 5:18a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 106 7/12/11 11:34p Ryanchou
+// [TAG] EIP61388
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] FreeDOS will hang at USB storage device while selecting Force
+// FDD.
+// [RootCause] Hidden sector is not 0.
+// [Solution] Force #of hidden sectors to 0
+// [Files] usbmass.c
+//
+// 105 7/12/11 6:32a Ryanchou
+// [TAG] EIP63308
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] POST hang with USB WiMAX Dongle plugged on USB3.0 port
+// [RootCause] The device always return invalid Command Status Wrapper.
+// [Solution] Do nothing if CSW is invalid.
+// [Files] usbmass.c
+//
+// 104 6/27/11 12:33a Ryanchou
+// Correct EIP51158 changes.
+//
+// 103 6/22/11 1:45a Ryanchou
+// [TAG] EIP59738
+// [Category] Improvement
+// [Description] Support Block size other than 512 bytes USB HDD in UEFI
+// mode.
+// [Files] efiusbmass.c, uhci.c, usb.c, usbdef.h, usbmass.c
+//
+// 102 6/22/11 12:43a Ryanchou
+// [TAG] EIP51158
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Samsung i7500 mobile phone can't be recognized
+// [RootCause] The data packet length of UFI command is not same as SCSI
+// command, the device stalls the UFI command.
+// [Solution] Use SCSI command if the subclass code indicate the device
+// support SCSI command set.
+// [Files] usbmass.c
+//
+// 101 6/21/11 11:02a Ryanchou
+// [TAG] EIP59579
+// [Category] Improvement
+// [Description] USB device information structure should be reserved for
+// the UsbIO to use even install driver fail.
+// [Files] usbmass.c, usbkbd.c, usbms.c
+//
+// 100 6/21/11 10:54a Ryanchou
+// [TAG] EIP60588
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] MS-DOS 7.1 boot by USB 2.0 Flash Drive will crash system at
+// black screen.
+// [RootCause] The LBA that will be read is greater than the max LBA.
+// [Solution] Set the the starting LBA address to (the last LBA - number
+// of blocks to process) if dStartLBA is greater than (dMaxLba -
+// wNumBlks).
+// [Files] usbmass.c
+//
+// 99 5/03/11 10:11a Ryanchou
+// [TAG] EIP54283
+// [Category] Improvement
+// [Description] Follow XHCI spec ver 1.0 section 4.6.8 to recovery
+// endpoint halt.
+// [Files] ehci.c, ohci.c, uhci.c, usbdef.h, usbmass.c, xhci.c
+//
+// 98 5/03/11 8:29a Ryanchou
+// [TAG] EIP43711
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB-FDD will be recognized as USB-HDD in BIOS Setup.
+// [RootCause] The media reports valid partition which is same as HDD.
+// [Solution] Check the device class to fix this issue.
+// [Files] usbmass.c
+//
+// 97 5/03/11 7:51a Ryanchou
+// [TAG] EIP53416
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Iomega Zip250 hang at StatusCode 0xB4
+// [RootCause] Fail to calculate CHS values from max LBA if device is
+// not ready.
+// [Solution] Should not get device geometry if device is not ready.
+// [Files] usbmass.c
+//
+// 96 4/06/11 4:29a Ryanchou
+// [TAG] EIP57573
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Can't boot to USB 3.0 device
+// [RootCause] Some device haven't indicate Test Unit Ready command
+// failure in the CSW status.
+// [Solution] Undo the EIP55440 changes and send Test Unit Ready command
+// again if the Sense key is MEDIUM ERROR.
+// [Files] usbmass.c
+//
+// 95 3/30/11 8:15a Ryanchou
+// [TAG] EIP54126
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Sometimes system hangs at checkpoint 0xB4.
+// [RootCause] The bLength field of configuration descriptor is zero.
+// [Solution] Check wether bLength field is zero before paring next
+// descriptor.
+// [Files] usb.c, usbbus.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c
+//
+// 94 3/26/11 4:13a Ryanchou
+// [TAG] EIP55440
+// [Category] Improvement
+// [Description] Request Sense command should be sent only if the CSW of
+// the storage command isn't Success.
+// [Files] usbmass.c
+//
+// 93 3/16/11 11:45p Ryanchou
+// [TAG] EIP52719
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB 3.0 HDD is detected as USB FDD
+// [RootCause] Fail to read MBR while configure the device.
+// [Solution] Retry 10 times.
+// [Files] usbmass.c
+//
+// 92 1/25/11 5:30p Olegi
+// [TAG] EIP52205
+// [Category] Improvement
+// [Description] System can not boot from a certain FD image. Changed
+// MBR validation routine to check the valid partition(s) size.
+// [Files] usbmass.c
+//
+// 91 12/28/10 4:45a Ryanchou
+// [TAG] EIP50968
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BIOS can't boot to WD My Book 3.0.
+// [RootCause] The USB 3.0 device returns sense data 0x800000 when
+// device is ready.
+// [Solution] Ignore the ASC and ASCQ, check the Sense key only.
+// [Files] usbmass.c, xhci.h
+//
+// 90 12/27/10 12:44a Ryanchou
+// [TAG] EIP50458
+// [Category] Improvement
+// [Description] If pre skip and post skip is not zero, allocate a
+// buffer for data transfer.
+// [Files] usbmass.c
+//
+// 89 12/12/10 11:14p Ryanchou
+// [TAG] EIP48166
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] POST takes a long time if USB ODD is connected.
+// [RootCause] USB driver determines media not present when Sense Data
+// is 0x003A02. the USB ODD returns 0x013A02 for no media condition.
+// [Solution] Check Sense key and ASC only for no media condition.
+//
+// 88 11/11/10 8:50a Ryanchou
+// [TAG] EIP47638
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] The command block of read command is invalid
+// [RootCause] The command block is destoyed in USBMassSendBOTCommand.
+// [Solution] Reinitialize the command block.
+// [Files] usbmass.c
+//
+// 87 10/28/10 12:25a Ryanchou
+// EIP45643: Fixed system hangs when hot plug USB mass storage quickly on
+// USB 3.0 port.
+//
+// 86 10/21/10 10:13a Ryanchou
+// EIP45121: Added xHCI Supported Protocol Capability and fix the problem
+// that USB 3.0 device can't be detected.
+//
+// 85 10/20/10 9:16a Ryanchou
+// EIP44239: Delay for the device to get ready if sense key is 0x06.
+//
+// 84 10/20/10 12:56a Ryanchou
+// EIP45828: If the flag DEV_INFO_MASS_DEV_REGD is set, check if the
+// controller type is difference between old DevInfo and new one.
+//
+// 83 10/12/10 2:13a Rameshr
+// [TAG]- EIP 44585
+// [Category]-IMPROVEMENT
+// [Description]- Number of maximum supported USB Mass Storage device
+// increased from 8 to 16.
+// [Files]- Uin13.bin, UsbPort.c, UsbInt13.h, Usb.c, Usbdef.h, Uasbmass.c,
+// Usb.sd, usb.uni, UsbSetup.c, UsbSrc.sdl, UsbPolicy.h
+//
+// 82 9/07/10 4:34a Tonylo
+// Remove user tags for coding standard.
+//
+// 81 9/01/10 8:32a Ryanchou
+// EIP42297: Fixed boot to hot plug USB HDD fail.
+//
+// 80 8/18/10 4:23p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 79 7/15/10 4:40a Tonylo
+// EIP21649 - USB mass storage device still appear in BBS menu when USB
+// legacy support is disabled.
+//
+// 78 6/22/10 9:31a Ryanchou
+// EIP39374: Fixed USB key hot plug issue.
+//
+// 77 6/10/10 11:27p Ryanchou
+// The USB0089 patch is for card reader, floppy doesn't need.
+//
+// 76 5/05/10 12:02p Olegi
+// Send Start Unit command to the device when sense data is 0x020402.
+// EIP36909
+//
+// 75 4/12/10 4:17p Olegi
+// Slow MSD may return invalid block size and max lba when device is not
+// ready. Check the value of block Size and max lba returned by Read
+// Capacity Command. EIP37167.
+//
+// 74 3/02/10 9:52a Olegi
+// Bugfix in USBMassUpdateCHSFromBootRecord, EIP34794.
+//
+// 73 2/08/10 10:03a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 72 12/18/09 12:12p Olegi
+// Added SDL token USB_START_UNIT_BEFORE_MSD_ENUMERATION that controls the
+// execution of bugfix for EIP25229. Disable by default.
+//
+// 71 11/30/09 11:33a Olegi
+// Change in USBMassGetFreeMassDeviceInfoStruc, zero device info structure
+// can not be returned. EIP27635.
+//
+// 70 10/02/09 10:49a Olegi
+// Code cleanup.
+//
+// 69 9/09/09 11:28a Olegi
+// Increased R/W command timeout delay from 10 to 20 swconds. EIP#24326
+//
+// 68 8/26/09 11:52a Olegi
+// xUbuntu on USB fix: Start unit command before access it. EIP#25229
+// (Core8 EIP#23581)
+//
+// 67 6/05/09 2:34p Olegi
+// Do not enumerate device if it is not a CD-ROM and has the block size
+// different from 512 Bytes. EIP#15595, iPod nano makes POST hang.
+//
+// 66 6/04/09 3:46p Olegi
+// EIP21970: support for hotplug drives, re-inserting them to a different
+// controller/port.
+//
+// 65 6/01/09 10:02a Olegi
+// Fix for EIP#21681: The problem is in the Read Format Capacities command
+// (0x23), the DataTransferLength is 0x40 in the CBW, but the Allocation
+// Length is 0x80 in the CDB. Thus, the driver return Status = Phase
+// Error.
+//
+// 64 5/21/09 5:12p Olegi
+// Added HDD hotplug support.
+//
+// 63 5/15/09 5:50p Olegi
+// EIP#21179 - failure of Transcend Card reader configuration fix.
+//
+// 62 4/24/09 9:32a Olegi
+// Bugfix for EIP#20863.
+//
+// 61 2/17/09 9:18a Olegi
+//
+// 60 1/29/09 2:40p Olegi
+// Added a check for Mass Storage device limit before creating a new LUN
+// device.
+//
+// 59 1/23/09 10:17a Olegi
+// Modified the resolution of EIP#18553
+//
+// 58 1/16/09 4:04p Olegi
+// - Removed the limitation of MAX_BULK_DATA_SIZE in
+// USBMassIssueBulkTransfer.
+// - Modified USBMassCheckDeviceReady, EIP18553.
+//
+// 57 11/20/08 1:12p Olegi
+// EIP#17634 fix: added StartStopUnit command if TestUnitReady returns the
+// value of 0x020402.
+// Note: current fix is done only for the device VID 0x0DC4 DID 0x0207; in
+// future we may want to extend this fix for other devices. This will
+// require additional testing.
+//
+// 56 11/06/08 11:40a Olegi
+// Fixed device configuration for multi-LUN devices.
+//
+// 55 9/05/08 5:39p Olegi
+//
+// 54 9/05/08 4:22p Olegi
+// fpCallbackNotify4 is replaced with the call within SMI.
+//
+// 53 8/25/08 12:09p Olegi
+//
+// 52 8/25/08 12:00p Olegi
+// Added USBMassReadCapacityBlockSizePatch function.
+//
+// 51 8/21/08 12:28p Olegi
+// Modification in CreateLogicalUnits function:
+// - At the point of the new unit creation, the Lun0 device might be
+// locked by the bus driver (USBBUS.usbhc_on_timer); clear the lock
+// indicator for the new LUN.
+//
+// 50 8/13/08 5:32p Olegi
+//
+// 49 8/13/08 5:27p Olegi
+// Bugfix in USBMassGetFormatType.
+//
+// 48 7/04/08 1:08p Olegi
+// Added REQUEST_SENSE command in the sequence of failed MODE_SENSE.
+//
+// 47 6/27/08 5:54p Olegi
+// Mass Device name field is populated in DEV_INFO structure.
+//
+// 46 6/13/08 3:54p Olegi
+// Additions related to 720KB floppy support.
+//
+// 45 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 44 1/30/08 12:43p Olegi
+// - change in USBMassGetDeviceGeometry that returns default geometry for
+// those devices with BlockSize reported as 0.
+// - change in USBMassGetDeviceInfo that reports PCI bus/dev/function.
+//
+// 43 10/15/07 5:15p Olegi
+// - Modification in USBMassCreateLogicalUnits that allows different
+// emulation type for different LUNs
+// - Bugfix in USBMassGetFormatType that clears bHiddenSectors field in
+// multiple-LUN device
+//
+// 42 9/17/07 3:33p Olegi
+//
+// 41 7/10/07 10:25a Olegi
+//
+// 40 7/09/07 2:11p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+// 39 6/14/07 12:28p Olegi
+//
+// 38 5/29/07 6:11p Olegi
+//
+// 37 5/24/07 4:09p Olegi
+//
+// 36 5/18/07 10:53a Olegi
+// Bugfix in USBMassGetDeviceGeometry that used the device ID instead of
+// DEV_INFO index for USBMassGetDeviceStatus call.
+//
+// 35 5/05/07 1:54p Olegi
+// Persistent DOS drives.
+//
+// 34 4/18/07 2:51p Fredericko
+// Bugfix in USBMassUpdateDeviceGeometry, removed redundant code that
+// corrupted memory.
+//
+// 32 4/17/07 11:05a Olegi
+//
+// 30 3/29/07 6:40p Olegi
+// Modified USBMassUpdateDeviceGeometry to take care of USB floppy drive
+// with no floppy in it.
+//
+// 29 3/20/07 12:19p Olegi
+//
+// 28 2/27/07 10:45a Olegi
+//
+// 27 12/22/06 4:05p Olegi
+// Timeout implementation.
+//
+// 26 12/20/06 3:38p Olegi
+//
+// 25 12/20/06 2:30p Olegi
+//
+// 24 12/12/06 12:32p Olegi
+//
+// 22 11/09/06 4:57p Olegi
+//
+// 18 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 17 3/21/06 12:01p Olegi
+//
+// 16 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 15 3/16/06 2:33p Olegi
+//
+// 14 3/06/06 6:25p Olegi
+// Lun devices support modifications: supported using the index in
+// DEV_INFO table, not through dedicated massLun table.
+//
+// 13 1/11/06 11:52a Olegi
+// Setup related modifications.
+//
+// 12 12/19/05 10:17a Olegi
+// DeviceDelayCount is Setup driven.
+//
+// 11 12/01/05 5:49p Olegi
+//
+// 10 11/10/05 11:11a Olegi
+//
+// 9 11/04/05 6:22p Olegi
+// Multiple LUN support.
+//
+// 8 10/17/05 5:12p Olegi
+//
+// 7 9/22/05 6:28p Olegi
+//
+// 6 9/15/05 6:10p Andriyn
+// Fix: Mass Storage name gets corrupted in setup
+//
+// 5 8/23/05 5:53p Olegi
+// Latest USB mass storage updates from AMIBIOS USB module are applied.
+//
+// 4 6/03/05 9:31a Olegi
+// MediaId update moved to EFI mass strorage driver.
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 4/26/05 5:09p Olegi
+// Modifications in USBMassRWVCommand, USBMassCheckDeviceReady to properly
+// handle USB FDDs with no media in them.
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbMass.c
+//
+// Description: AMI USB Mass Storage support implementation
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "UsbMass.h"
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#endif
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gCheckUsbApiParameter;
+
+VOID USBMassInitialize(VOID);
+UINT8 USBMassCheckForStorageDevice(DEV_INFO*, UINT8, UINT8, UINT8);
+DEV_INFO* USBMassConfigureStorageDevice(HC_STRUC*, DEV_INFO*,
+ UINT8*, UINT16, UINT16);
+UINT8 USBMassDisconnectStorageDevice(DEV_INFO*);
+UINT16 USBMassSendCBICommand(DEV_INFO*, MASS_XACT_STRUC*);
+UINT32 USBMassProcessBulkData(DEV_INFO*, MASS_XACT_STRUC*);
+UINT8 USBMassConsumeBulkData(DEV_INFO*,UINT8,UINT16);
+UINT32 USBMassIssueBOTTransaction(DEV_INFO*, MASS_XACT_STRUC*);
+VOID USBMassClearBulkEndpointStall(DEV_INFO*, UINT8);
+VOID USBMassBOTResetRecovery(DEV_INFO*);
+UINT16 USBMassSendBOTCommand(DEV_INFO*, MASS_XACT_STRUC*);
+UINT8 USBMassGetBOTStatus(DEV_INFO*, MASS_XACT_STRUC*);
+UINT16 USBMassCBIGetStatus(DEV_INFO*);
+UINT32 USBMassIssueCBITransaction(DEV_INFO*, MASS_XACT_STRUC*);
+UINT8 USBMassReadCapacity10Command(DEV_INFO*);
+UINT32 USBMassCheckDeviceReady(DEV_INFO*);
+UINT32 USBMassRequestSense(DEV_INFO* fpDevInfo);
+VOID USBMassSenseKeyParsing(DEV_INFO* , UINT32);
+MASS_INQUIRY *USBMassInquiryCommand(DEV_INFO*);
+UINT8 USBMassUpdateDeviceGeometry( DEV_INFO* fpDevInfo );
+UINT16 USBMassBOTGetMaxLUN(DEV_INFO*);
+VOID USBMassIdentifyDeviceType(DEV_INFO*, UINT8*);
+UINT32 USBMassIssueBulkTransfer(DEV_INFO*, UINT8, UINT8*, UINT32);
+VOID iPodShufflePatch(MASS_GET_DEV_INFO*);
+VOID USBMassUpdateCylinderInfo(DEV_INFO*, UINT64);
+UINT8 USBMassSetDefaultGeometry(DEV_INFO*, UINT64);
+UINT8 USBMassValidatePartitionTable(MASTER_BOOT_RECORD*, UINT64, MBR_PARTITION*);
+UINT16 USBMassSetDefaultType(DEV_INFO*, UINT64);
+VOID USBMassGetPhysicalDeviceType(DEV_INFO*, UINT8*);
+UINT8 USB_SetAddress(HC_STRUC*, DEV_INFO*, UINT8);
+UINT32 dabc_to_abcd(UINT32);
+DEV_INFO* USBGetProperDeviceInfoStructure(DEV_INFO*, UINT8);
+UINT32 USBMassTestUnitReady(DEV_INFO*);
+VOID StoreUsbMassDeviceName(DEV_INFO*, UINT8*);
+extern VOID AddPortNumbertoDeviceString(DEV_INFO*);
+UINT8 USBMassGetConfiguration(DEV_INFO*);
+
+VOID MemFill (UINT8*, UINT32, UINT8);
+VOID MemCopy (UINT8*, UINT8*, UINT32);
+VOID* USB_MemAlloc (UINT16);
+DEV_INFO* USB_GetDeviceInfoStruc(UINT8, DEV_INFO*, UINT8, HC_STRUC*);
+MASS_INQUIRY* USBMassGetDeviceParameters(DEV_INFO*);
+
+UINT8 USB_MemFree (VOID*, UINT16);
+VOID FixedDelay(UINTN);
+VOID SpeakerBeep (UINT8, UINT16, HC_STRUC*); //(EIP64781+)
+
+static char* IOMegaZIPString = "IOMEGA ZIP";
+#define IOMegaZIPStringLength 11
+
+static char* MSysDiskOnKeyString = "M-Sys DiskOnKey";
+#define MSysDiskOnKeyStringLength 17
+
+BOOLEAN CheckDeviceLimit(UINT8);
+
+VOID
+USBMassFillDriverEntries (DEV_DRIVER *fpDevDriver)
+{
+ fpDevDriver->bDevType = BIOS_DEV_TYPE_STORAGE;
+ fpDevDriver->bProtocol = 0;
+ fpDevDriver->pfnDeviceInit = USBMassInitialize;
+ fpDevDriver->pfnCheckDeviceType = USBMassCheckForStorageDevice;
+ fpDevDriver->pfnConfigureDevice = USBMassConfigureStorageDevice;
+ fpDevDriver->pfnDisconnectDevice = USBMassDisconnectStorageDevice;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// FUNCTION: USBMassInitialize
+//
+// DESCRIPTION: This function initializes mass storage device related data
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassInitialize ()
+{
+ //
+ // Set default value for the delay. Selections are: 20,40,60,80 for 10,20,30,40 sec.
+ //
+ gUsbData->bUSBStorageDeviceDelayCount = (gUsbData->UsbMassResetDelay + 1)*10;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassCheckForStorageDevice
+//
+// DESCRIPTION: This routine checks for hub type device from the
+// interface data provided
+//
+// PARAMETERS: bBaseClass USB base class code
+// bSubClass USB sub-class code
+// bProtocol USB protocol code
+//
+// RETURN: BIOS_DEV_TYPE_STORAGE type on success or 0FFH on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassCheckForStorageDevice (
+ DEV_INFO* DevInfo,
+ UINT8 BaseClass,
+ UINT8 SubClass,
+ UINT8 Protocol
+)
+{
+ if (BaseClass != BASE_CLASS_MASS_STORAGE) {
+ return USB_ERROR;
+ }
+ //(EIP99882+)>
+ if (!gUsbData->UsbSetupData.UsbMassDriverSupport) {
+ return USB_ERROR;
+ }
+ //<(EIP99882+)
+//Skip USB mass storage devices enumeration when legacy is disabled
+ if (gUsbData->dUSBStateFlag & USB_FLAG_DISABLE_LEGACY_SUPPORT) {
+ if (LEGACY_USB_DISABLE_FOR_USB_MASS) { //(EIP93469)
+ return USB_ERROR;
+ }
+ }
+ //
+ // Base class is okay. Check the protocol field for supported protocols.
+ // Currently we support CBI, CB and BOT protocols.
+ //
+ if ((Protocol != PROTOCOL_CBI) &&
+ (Protocol != PROTOCOL_CBI_NO_INT) &&
+ (Protocol != PROTOCOL_BOT)) {
+ return USB_ERROR;
+ }
+
+ return BIOS_DEV_TYPE_STORAGE;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetFreeMassDeviceInfoStruc
+//
+// Description: This function finds a free mass device info structure and
+// returns the pointer to it
+//
+// Input: None
+//
+// Output: Pointer to the Mass Device Info (0 on failure)
+// The number mass storage DeviceInfo structure (0-based)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBMassGetFreeMassDeviceInfoStruc(
+ DEV_INFO *DevInfo,
+ UINT8 *Indx
+)
+{
+ DEV_INFO* Dev = &gUsbData->aDevInfoTable[1];
+ UINT8 Count;
+ UINT8 MassDevIndx = 0;
+
+ for (Count = 0; Count < (MAX_DEVICES-1); Count++, Dev++) {
+ if (!(Dev->Flag & DEV_INFO_VALID_STRUC)) {
+ continue;
+ }
+ if (Dev->bDeviceType == BIOS_DEV_TYPE_STORAGE) {
+ MassDevIndx++;
+ }
+ if (Dev == DevInfo) {
+ break;
+ }
+ }
+ if (Count == (MAX_DEVICES-1)) {
+ return NULL;
+ }
+ *Indx = MassDevIndx;
+
+ return Dev;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassFindFreeMassDeviceInfo
+//
+// Description: This function finds a free mass device info structure and
+// copies the current mass device info structure into it
+//
+// Input: Current mass device info structure
+//
+// Output: New mass device info
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBMassFindFreeMassDeviceInfo(
+ DEV_INFO* Dev,
+ UINT8 *EmulIndex
+)
+{
+ UINT8 Indx = 0;
+ DEV_INFO *NewDev;
+
+ // Get the free mass device info structure pointer
+ NewDev = USBMassGetFreeMassDeviceInfoStruc(Dev, &Indx);
+
+ if (NewDev == NULL) {
+ return NULL; // No free entry found.
+ }
+
+ // Get the emulation type setup question associated with this device
+ ASSERT(Indx>0 && Indx<17);
+ if ((Indx == 0) || (Indx > 16)) {
+ return NULL;
+ }
+
+ Dev->wEmulationOption = gUsbData->USBMassEmulationOptionTable[Indx-1];
+ USB_DEBUG(DEBUG_LEVEL_3, "USBMassFindFreeMassDeviceInfo-------- indx %d, emu %d\n", Indx, Dev->wEmulationOption);
+
+ // Set default device type and emulation type to 0
+ Dev->bStorageType = 0;
+ Dev->fpLUN0DevInfoPtr = 0;
+ Dev->Flag |= DEV_INFO_DEV_PRESENT;
+
+ *EmulIndex = Indx-1;
+
+ return Dev;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassCreateLogicalUnits
+//
+// Description: This function verifies the presence of logical units (LUN)
+// in the USB mass device and creates appropriate device info
+// structures for them
+//
+// Input: fpDevInfo - Device information structure pointer
+// bMaxLun - Maximum number of logical units present (non-ZERO)
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On successfull completion
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassCreateLogicalUnits(
+ DEV_INFO* DevInfo,
+ UINT8 MaxLun,
+ UINT8 EmulIndex
+)
+{
+ UINT8 Lun;
+ DEV_INFO* NewDevInfo;
+ MASS_INQUIRY *Inq;
+
+ for (Lun = 1; Lun <= MaxLun; Lun++) {
+
+ if (CheckDeviceLimit(BASE_CLASS_MASS_STORAGE) == TRUE) {
+ break;
+ }
+ //
+ // Get the proper device info structure
+ //
+ NewDevInfo = USBGetProperDeviceInfoStructure(DevInfo, Lun);
+ if (!NewDevInfo) {
+ return USB_ERROR;
+ }
+ //
+ // Check whether this device is reconnected by checking the
+ // valid structure flag
+ //
+ if ((NewDevInfo->Flag & DEV_INFO_MASS_DEV_REGD)) {
+ //
+ // Indicate device as connected
+ //
+ NewDevInfo->Flag |= DEV_INFO_DEV_PRESENT;
+
+ // Change the parent HC number and port number in the existing DEV_INFO
+ NewDevInfo->bHCNumber = DevInfo->bHCNumber;
+ NewDevInfo->bHubDeviceNumber = DevInfo->bHubDeviceNumber;
+ NewDevInfo->bHubPortNumber = DevInfo->bHubPortNumber;
+ NewDevInfo->bEndpointSpeed = DevInfo->bEndpointSpeed;
+ NewDevInfo->wEndp0MaxPacket = DevInfo->wEndp0MaxPacket;
+ NewDevInfo->DevMiscInfo = DevInfo->DevMiscInfo;
+ NewDevInfo->bDeviceAddress = DevInfo->bDeviceAddress;
+ NewDevInfo->bBulkInEndpoint = DevInfo->bBulkInEndpoint;
+ NewDevInfo->wBulkInMaxPkt = DevInfo->wBulkInMaxPkt;
+ NewDevInfo->bBulkOutEndpoint = DevInfo->bBulkOutEndpoint;
+ NewDevInfo->wBulkOutMaxPkt = DevInfo->wBulkOutMaxPkt;
+ NewDevInfo->IntInEndpoint = DevInfo->IntInEndpoint;
+ NewDevInfo->IntInMaxPkt = DevInfo->IntInMaxPkt;
+ NewDevInfo->bPollInterval = DevInfo->bPollInterval;
+ NewDevInfo->fpLUN0DevInfoPtr = DevInfo;
+ } else { // This is different device, it was not reconnected
+ //
+ // Copy the old device info structure into the new one
+ //
+ MemCopy((UINT8*)DevInfo,
+ (UINT8*)NewDevInfo,
+ sizeof (DEV_INFO));
+ NewDevInfo->bLUN = Lun; // Change LUN number
+ NewDevInfo->wEmulationOption = gUsbData->USBMassEmulationOptionTable[EmulIndex + Lun];
+ MemFill(NewDevInfo->DevNameString, 64, 0);
+ //
+ // Save the Lun0 device info pointer in the current LUN
+ //
+ NewDevInfo->fpLUN0DevInfoPtr = DevInfo;
+
+ //
+ // The Lun0 device might have been already locked by the
+ // bus (USBBUS.usbhc_on_timer), clear it for current LUN.
+ //
+ NewDevInfo->Flag &= ~DEV_INFO_DEV_BUS;
+
+ Inq = USBMassGetDeviceParameters(NewDevInfo);
+ ASSERT(Inq);
+ StoreUsbMassDeviceName(NewDevInfo, (UINT8*)Inq + 8);
+ if (NewDevInfo->bStorageType == USB_MASS_DEV_CDROM) {
+ USBMassGetConfiguration(NewDevInfo);
+ }
+ }
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ if (!(NewDevInfo->Flag & DEV_INFO_IN_QUEUE)) {
+ USB_SmiQueuePut(NewDevInfo);
+ NewDevInfo->Flag |= DEV_INFO_IN_QUEUE;
+ }
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+
+VOID
+StoreUsbMassDeviceName(
+ DEV_INFO *Device,
+ UINT8 *Str
+)
+{
+ UINT8 i;
+ UINT8 j;
+
+ for (i = 0; i < 64; i++) {
+ if (Device->DevNameString[i] != 0) {
+ return;
+ }
+ }
+
+ for (i = 0, j = 0; i < 32; i++) {
+ if (*Str == 0) {
+ Str++; j++; // supress leading zeroes
+ }
+ }
+
+ for (i = 0; i < (32-j); i++, Str++) {
+ // supress spaces if more than one
+ if ((i>0) && (Device->DevNameString[i-1]==' ') && (*Str==' ')) {
+ i--;
+ continue;
+ }
+ //(EIP63706+)>
+ // Filter out the character if it is invisible.
+ if (((*Str != 0) && (*Str < 0x20)) || (*Str > 0x7E)) {
+ i--;
+ continue;
+ }
+ //<(EIP63706+)
+
+ Device->DevNameString[i] = *Str;
+ }
+
+ //
+ // Add Device number to the USB device string
+ //
+#if USB_DIFFERENTIATE_IDENTICAL_DEVICE_NAME
+ AddPortNumbertoDeviceString(Device);
+#endif
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassConfigureStorageDevice
+//
+// DESCRIPTION: This function checks an interface descriptor of a device
+// to see if it describes a USB mass device. If the device
+// is a mass storage device, then it is configured
+// and initialized.
+//
+// PARAMETERS: pHCStruc HCStruc pointer
+// pDevInfo Device information structure pointer
+// pDesc Pointer to the descriptor structure
+// wEnd End offset of the device descriptor
+//
+// RETURN: New device info structure, NULL on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBMassConfigureStorageDevice (
+ HC_STRUC* fpHCStruc,
+ DEV_INFO* fpDevInfo,
+ UINT8* fpDesc,
+ UINT16 wStart,
+ UINT16 wEnd)
+{
+ UINT8 bTemp;
+ UINT16 wRetValue;
+ ENDP_DESC *fpEndpDesc;
+ INTRF_DESC *fpIntrfDesc;
+ UINT8 bMaxLUN;
+ DEV_INFO* newDev;
+ MASS_INQUIRY *inq;
+ BOOLEAN checkFDDhotplug, checkCDROMhotplug, checkHDDhotplug;
+ UINT8 EmulIndex;
+ UINT8 i; //(EIP64781+)
+
+ wRetValue = 0;
+ bMaxLUN = 0;
+
+//
+// Set fpDevInfo->bDeviceType. This serves as a flag
+// that indicates a usable interface has been found in the current
+// configuration. This is needed so we can check for other usable interfaces
+// in the current configuration (composite device) without trying to search
+// in other configurations.
+//
+ fpDevInfo->bDeviceType = BIOS_DEV_TYPE_STORAGE;
+ fpDevInfo->fpPollTDPtr = 0;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "USBMassConfigureDevice ....\n");
+
+ bTemp = 0x03; // bit 1 = Bulk In, bit 0 = Bulk Out
+
+ fpDevInfo->bBulkOutEndpoint = 0;
+ fpDevInfo->bBulkInEndpoint = 0;
+ fpDevInfo->IntInEndpoint = 0;
+
+ fpIntrfDesc = (INTRF_DESC*)(fpDesc + wStart);
+ fpDesc+=((CNFG_DESC*)fpDesc)->wTotalLength; // Calculate the end of descriptor block
+ fpEndpDesc = (ENDP_DESC*)((char*)fpIntrfDesc + fpIntrfDesc->bDescLength);
+ for( ;(fpEndpDesc->bDescType != DESC_TYPE_INTERFACE) && ((UINT8*)fpEndpDesc < fpDesc);
+ fpEndpDesc = (ENDP_DESC*)((char*)fpEndpDesc + fpEndpDesc->bDescLength)){
+
+ if(!(fpEndpDesc->bDescLength)) {
+ break; // Br if 0 length desc (should never happen, but...)
+ }
+
+ if( fpEndpDesc->bDescType != DESC_TYPE_ENDPOINT ) {
+ continue;
+ }
+
+ if ((fpEndpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) ==
+ EP_DESC_FLAG_TYPE_BULK) { // Bit 1-0: 10 = Endpoint does bulk transfers
+ if(!(fpEndpDesc->bEndpointAddr & EP_DESC_ADDR_DIR_BIT)) {
+ //
+ // Bit 7: Dir. of the endpoint: 1/0 = In/Out
+ // If Bulk-Out endpoint already found then skip subsequent ones
+ // on the interface.
+ //
+ if (bTemp & 1) {
+ fpDevInfo->bBulkOutEndpoint = (UINT8)(fpEndpDesc->bEndpointAddr
+ & EP_DESC_ADDR_EP_NUM);
+ fpDevInfo->wBulkOutMaxPkt = fpEndpDesc->wMaxPacketSize;
+ bTemp &= 0xFE;
+ USB_DEBUG(3, "bulk out endpoint addr: %x, max packet size: %x\n",
+ fpDevInfo->bBulkOutEndpoint, fpDevInfo->wBulkOutMaxPkt);
+ }
+ } else {
+ //
+ // If Bulk-In endpoint already found then skip subsequent ones
+ // on the interface
+ //
+ if (bTemp & 2) {
+ fpDevInfo->bBulkInEndpoint = (UINT8)(fpEndpDesc->bEndpointAddr
+ & EP_DESC_ADDR_EP_NUM);
+ fpDevInfo->wBulkInMaxPkt = fpEndpDesc->wMaxPacketSize;
+ bTemp &= 0xFD;
+ USB_DEBUG(3, "bulk in endpoint addr: %x, max packet size: %x\n",
+ fpDevInfo->bBulkInEndpoint, fpDevInfo->wBulkInMaxPkt);
+ }
+ }
+ }
+
+ //
+ // Check for and configure Interrupt endpoint if present
+ //
+ if ((fpEndpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) !=
+ EP_DESC_FLAG_TYPE_INT) { // Bit 1-0: 10 = Endpoint does interrupt transfers
+ continue;
+ }
+
+ if (fpEndpDesc->bEndpointAddr & EP_DESC_ADDR_DIR_BIT ) {
+ fpDevInfo->IntInEndpoint = fpEndpDesc->bEndpointAddr;
+ fpDevInfo->IntInMaxPkt = fpEndpDesc->wMaxPacketSize;
+ fpDevInfo->bPollInterval = fpEndpDesc->bPollInterval;
+ USB_DEBUG(3, "interrupt in endpoint addr: %x, max packet size: %x\n",
+ fpDevInfo->IntInEndpoint, fpDevInfo->IntInMaxPkt);
+ }
+ }
+
+ //
+ // Check the compatibility flag for LUN support
+ //
+ if (!(fpDevInfo->wIncompatFlags & USB_INCMPT_SINGLE_LUN_DEVICE)) {
+ //
+ // If it is a BOT device, get maximum LUN supported
+ //
+ if (fpDevInfo->bProtocol == PROTOCOL_BOT) {
+ bMaxLUN = (UINT8)USBMassBOTGetMaxLUN(fpDevInfo);
+ }
+ }
+
+ //
+ // Check whether the device is already registered. If so, proceed with current
+ // mass info structure
+ //
+ if (fpDevInfo->Flag & DEV_INFO_MASS_DEV_REGD) {
+ newDev = fpDevInfo;
+
+ goto UMCM_MassDeviceOkay;
+ }
+
+ // Find a new mass device info structure and copy the old one into the new one
+ // Note: this is called before GetDeviceParameters because it sets up dev->wEmulationOption
+ newDev = USBMassFindFreeMassDeviceInfo(fpDevInfo, &EmulIndex);
+
+ if (newDev == NULL) goto UMCM_Error;
+ fpDevInfo = newDev;
+
+ inq = USBMassGetDeviceParameters(fpDevInfo);
+ if (inq == NULL) goto UMCM_Error;
+
+ //
+ // Do not enumerate device if it is not a CD-ROM and has the block size different from 512 Bytes
+ // EIP#15595, iPod nano makes POST hang.
+ //
+ //(EIP59738-)>
+ //if ( fpDevInfo->bPhyDevType!=USB_MASS_DEV_CDROM ) {
+ // if( fpDevInfo->wBlockSize!=0x200 && fpDevInfo->wBlockSize!=0xFFFF && fpDevInfo->wBlockSize!=0 )
+ // goto UMCM_Error;
+ //}
+ //<(EIP59738-)
+ StoreUsbMassDeviceName(fpDevInfo, (UINT8*)inq+8);
+
+ // Check for the hotplug devices current status, install the new one if needed
+ if ( !(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) ) {
+ // Find out if FDD/HDD/CDROM hotplugging is a valid option
+ checkFDDhotplug = ((gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED) ||
+ ((gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) &&
+ (gUsbData->NumberOfFDDs == 0))) &&
+ !(BOOLEAN)(gUsbData->dUSBStateFlag & USB_HOTPLUG_FDD_ENABLED);
+
+ checkHDDhotplug = ((gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED) ||
+ ((gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) &&
+ (gUsbData->NumberOfHDDs == 0))) &&
+ !(BOOLEAN)(gUsbData->dUSBStateFlag & USB_HOTPLUG_HDD_ENABLED);
+
+ checkCDROMhotplug = ((gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED) ||
+ ((gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_AUTO) &&
+ (gUsbData->NumberOfCDROMs == 0))) &&
+ !(BOOLEAN)(gUsbData->dUSBStateFlag & USB_HOTPLUG_CDROM_ENABLED);
+
+ if ( checkFDDhotplug || checkCDROMhotplug || checkHDDhotplug ) {
+ USB_DEBUG(DEBUG_LEVEL_3, "connecting hotplug...");
+// inq = USBMassGetDeviceParameters(fpDevInfo);
+// if (inq == NULL) goto UMCM_Error;
+ USB_DEBUG(DEBUG_LEVEL_3, "devtype phy %d, emu %d...", fpDevInfo->bPhyDevType, fpDevInfo->bEmuType);
+
+ if ( checkFDDhotplug &&
+ (fpDevInfo->bStorageType == USB_MASS_DEV_ARMD) ) {
+ newDev = &gUsbData->FddHotplugDev;
+ gUsbData->dUSBStateFlag |= USB_HOTPLUG_FDD_ENABLED;
+ }
+
+ if ( checkHDDhotplug && (fpDevInfo->bEmuType == USB_EMU_HDD_ONLY) ) {
+ newDev = &gUsbData->HddHotplugDev;
+ gUsbData->dUSBStateFlag |= USB_HOTPLUG_HDD_ENABLED;
+ }
+
+ if ( checkCDROMhotplug && (fpDevInfo->bPhyDevType == USB_MASS_DEV_CDROM) ) {
+ newDev = &gUsbData->CdromHotplugDev;
+ gUsbData->dUSBStateFlag |= USB_HOTPLUG_CDROM_ENABLED;
+ }
+
+ fpDevInfo->Flag |= DEV_INFO_HOTPLUG;
+ *newDev = *fpDevInfo; // Copy device into DevInfo dedicated to hotplug
+ fpDevInfo->Flag &= ~DEV_INFO_VALIDPRESENT; // Release fpDevInfo
+ fpDevInfo = newDev;
+ }
+ }
+
+UMCM_MassDeviceOkay:
+ if ( (newDev->bEmuType == USB_EMU_FLOPPY_ONLY) ||
+ (newDev->bEmuType == USB_EMU_FORCED_FDD) ) {
+ gUsbData->NumberOfFDDs++;
+ }
+
+ if ( newDev->bEmuType == USB_EMU_HDD_ONLY ) {
+ gUsbData->NumberOfHDDs++;
+ }
+
+// if ( newDev->bPhyDevType == USB_EMU_HDD_OR_FDD ) {
+ if ( newDev->bPhyDevType == USB_MASS_DEV_CDROM ) {
+ gUsbData->NumberOfCDROMs++;
+ USBMassGetConfiguration(newDev);
+ }
+
+ if (bMaxLUN) {
+ USBMassCreateLogicalUnits(newDev, bMaxLUN, EmulIndex);
+ }
+
+ //(EIP64781+)>
+ if (gUsbData->dUSBStateFlag & USB_FLAG_SKIP_CARD_READER_CONNECT_BEEP) {
+ if ((newDev->bLastStatus & USB_MASS_MEDIA_PRESENT) ||
+ newDev->bPhyDevType == USB_MASS_DEV_CDROM ||
+ newDev->bPhyDevType == USB_MASS_DEV_FDD) {
+ SpeakerBeep(4, 0x1000, fpHCStruc);
+ } else if (bMaxLUN) {
+ for(i = 1; i < MAX_DEVICES; i++) {
+ if (gUsbData->aDevInfoTable[i].fpLUN0DevInfoPtr == newDev) {
+ if (gUsbData->aDevInfoTable[i].bLastStatus & USB_MASS_MEDIA_PRESENT) {
+ SpeakerBeep(4, 0x1000, fpHCStruc);
+ break;
+ }
+ }
+ }
+ }
+ }
+ //<(EIP64781+)
+
+ return newDev;
+
+UMCM_Error:
+ //USB_AbortConnectDev(fpDevInfo); //(EIP59579-)
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassDisconnectStorageDevice
+//
+// DESCRIPTION: This function disconnects the storage device
+//
+// PARAMETERS: pDevInfo Device info structure pointer
+//
+// RETURN: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassDisconnectStorageDevice (
+ DEV_INFO* DevInfo
+)
+{
+// USB_DEBUG (DEBUG_LEVEL_5, "USBMassDisconnectDevice .... \n");
+
+ DevInfo->bBulkOutEndpoint = 0;
+ DevInfo->bBulkInEndpoint = 0;
+ DevInfo->IntInEndpoint = 0;
+
+ if ((DevInfo->bEmuType == USB_EMU_FLOPPY_ONLY) ||
+ (DevInfo->bEmuType == USB_EMU_FORCED_FDD)) {
+ gUsbData->NumberOfFDDs--;
+ }
+
+ if (DevInfo->bEmuType == USB_EMU_HDD_ONLY) {
+ gUsbData->NumberOfHDDs--;
+ }
+
+// if ( newDev->bPhyDevType == USB_EMU_HDD_OR_FDD ) {
+ if ( DevInfo->bPhyDevType == USB_MASS_DEV_CDROM ) {
+ gUsbData->NumberOfCDROMs--;
+ }
+
+ if (DevInfo->Flag & DEV_INFO_HOTPLUG) {
+ DevInfo->Flag &= ~DEV_INFO_HOTPLUG;
+ if (DevInfo == &gUsbData->FddHotplugDev) {
+ gUsbData->dUSBStateFlag &= ~USB_HOTPLUG_FDD_ENABLED;
+ } else if (DevInfo == &gUsbData->HddHotplugDev) {
+ gUsbData->dUSBStateFlag &= ~USB_HOTPLUG_HDD_ENABLED;
+ } else if (DevInfo == &gUsbData->CdromHotplugDev) {
+ gUsbData->dUSBStateFlag &= ~USB_HOTPLUG_CDROM_ENABLED;
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassClearMassXactStruc
+//
+// Description: This function clears the mass transaction structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassClearMassXactStruc(
+ MASS_XACT_STRUC *MassXactStruc
+)
+{
+ UINT8 i;
+ UINT8* Cleaner = (UINT8*)MassXactStruc;
+
+ for (i = 0; i < sizeof (MASS_XACT_STRUC); i++ ) {
+ *Cleaner++ = 0;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassClearBulkEndpointStall
+//
+// Description: This function clears the bulk endpoint stall by sending
+// CLEAR_FEATURE command to bulk endpoints
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+// bDirec Endpoint direction
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassClearBulkEndpointStall(
+ DEV_INFO* DevInfo,
+ UINT8 Direc
+)
+{
+ UINT8 Shift;
+ UINT16 EndPoint;
+ HC_STRUC *HcStruc;
+ HCD_HEADER *HcdDriver;
+
+ HcStruc = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+ HcdDriver = &gUsbData->aHCDriverTable[GET_HCD_INDEX(HcStruc->bHCType)];
+
+ EndPoint = (UINT16)((DevInfo->bBulkInEndpoint) | BIT7);
+
+ if (!(Direc & BIT7)) {
+ EndPoint = DevInfo->bBulkOutEndpoint;
+ }
+ //
+ // Issue clear port feature command
+ //
+ HcdDriver->pfnHCDControlTransfer(HcStruc, DevInfo, (UINT16)ENDPOINT_CLEAR_PORT_FEATURE,
+ EndPoint,(UINT16)ENDPOINT_HALT, 0, 0);
+
+ //if (HcdDriver->pfnHCDClearEndpointState) {
+ // HcdDriver->pfnHCDClearEndpointState(HcStruc, DevInfo, (UINT8)EndPoint);
+ //} else {
+
+ //
+ // Reset the toggle bit
+ //
+ Shift = (EndPoint & 0xF) - 1;
+
+ if (Direc & BIT7) {
+ DevInfo->wDataInSync &= ~((UINT16)(1 << Shift));
+ } else {
+ DevInfo->wDataOutSync &= ~((UINT16)(1 << Shift));
+ }
+
+ if (DevInfo->fpLUN0DevInfoPtr == NULL) {
+ return;
+ }
+
+ if (Direc & BIT7) {
+ DevInfo->fpLUN0DevInfoPtr->wDataInSync &= ~((UINT16)(1 << Shift));
+ } else {
+ DevInfo->fpLUN0DevInfoPtr->wDataOutSync &= ~((UINT16)(1 << Shift));
+ }
+ //}
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassIssueMassTransaction
+//
+// Description: This function performs a mass storage transaction by
+// invoking proper transaction protocol.
+//
+// Input: Pointer to DeviceInfo structure
+// stMassXactStruc
+// pCmdBuffer Pointer to command buffer
+// bCmdSize Size of command block
+// bXferDir Transfer direction
+// fpBuffer Data buffer far pointer
+// dwLength Amount of data to be transferred
+// wPreSkip Number of bytes to skip before data
+// wPostSkip Number of bytes to skip after data
+//
+// Output: Amount of data actually transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+UINT32
+USBMassIssueMassTransaction(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+{
+ UINT32 DataLength;
+ HC_STRUC *HcStruc;
+
+ if ((DevInfo->bProtocol == PROTOCOL_CBI) ||
+ (DevInfo->bProtocol == PROTOCOL_CBI_NO_INT)) {
+ return USBMassIssueCBITransaction(DevInfo, MassXactStruc);
+ }
+
+ if (DevInfo->bProtocol == PROTOCOL_BOT) {
+
+ // Block to process periodic list to prevent that we might send the wrong
+ // command sequences to the same device.
+ gUsbData->ProcessingPeriodicList = FALSE;
+
+ DataLength = USBMassIssueBOTTransaction(DevInfo, MassXactStruc);
+
+ // To process any pending periodic list.
+ gUsbData->ProcessingPeriodicList = TRUE;
+ HcStruc = gUsbData->HcTable[DevInfo->bHCNumber - 1];
+ (*gUsbData->aHCDriverTable
+ [GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDProcessInterrupt)(HcStruc);
+
+ return DataLength;
+ }
+
+ return 0;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetDeviceParameters
+//
+// Description: This function gets the USB mass device parameters such as
+// max cylinder, head, sector, block size and
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: Pointer to the temp buffer, NULL on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MASS_INQUIRY*
+USBMassGetDeviceParameters(
+ DEV_INFO* DevInfo
+)
+{
+ MASS_INQUIRY *Inq;
+ UINT8 i;
+
+ for (i = 0; i < 2; i++) {
+ Inq = USBMassInquiryCommand(DevInfo);
+ if (Inq) {
+ break;
+ }
+ if (!(gUsbData->bLastCommandStatus & USB_BULK_STALLED)) {
+ break;
+ }
+ }
+
+ //USB_DEBUG(DEBUG_LEVEL_3, "fpMassInquiry = %x\n", Inq);
+
+ if (!Inq) {
+ return NULL;
+ }
+
+ DevInfo->wBlockSize = 0xFFFF; // Clear the cached block size
+
+ //
+ // Find the device type and update the device type structure accordingly
+ //
+ USBMassIdentifyDeviceType(DevInfo, (UINT8*)Inq);
+
+ return Inq;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: ValidateDeviceName
+//
+// Description: This procedure check whether device return valid device name
+// if no valid device name returned, assign default name for it
+//
+// Input: Inquiry Data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID ValidateDeviceName (
+ MASS_INQUIRY *InqData
+)
+{
+ static UINT8 DefaultName[] = "USB Storage Device";
+ UINT8 *Name = ((UINT8*)InqData) + 8;
+ UINT8 *DefName = DefaultName;
+ UINT8 Count;
+
+ // check for a blank name
+ if (*Name) return;
+
+// for (Count = 0; Count < 28; Count++) {
+// if (*(Name + Count)) return; // Not blank
+// }
+
+ // copy default name
+ for (Count = 0; Count < sizeof(DefaultName); Count++) {
+ *(Name + Count) = *(DefName + Count);
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetDeviceInfo
+//
+// Description: This function fills and returns the mass get device info
+// structure
+//
+// Input: fpMassGetDevInfo Pointer to the mass get info struc
+// bDevAddr USB device address of the device
+//
+// Output: USB_SUCCESS or USB_ERROR
+// fpMassGetDevInfo Pointer to the mass get info struc
+// dSenseData Sense data of the last command
+// bDevType Device type byte (HDD, CD, Removable)
+// bEmuType Emulation type used
+// fpDevId Far pointer to the device ID
+//
+// Notes: Initially the bDevAddr should be set to 0 as input. This
+// function returns the information regarding the first mass
+// storage device (if no device found it returns bDevAddr as
+// 0FFh) and also updates bDevAddr to the device address of
+// the current mass storage device. If no other mass storage
+// device is found then the routine sets the bit7 to 1
+// indicating current information is valid but no more mass
+// device found in the system. The caller can get the next
+// device info if bDevAddr is not 0FFh and bit7 is not set
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassGetDeviceInfo (
+ MASS_GET_DEV_INFO *MassGetDevInfo
+)
+{
+ DEV_INFO *DevInfo;
+ MASS_INQUIRY *MassInq;
+ UINT8 Dev = MassGetDevInfo->bDevAddr;
+
+ //
+ // Get the total number of Mass Storage Devices
+ //
+ MassGetDevInfo->bTotalMassDev = (UINT8)(UINTN)USB_GetDeviceInfoStruc(USB_SRCH_DEV_NUM,
+ 0, BIOS_DEV_TYPE_STORAGE, 0);
+
+ if (Dev == 0) {
+ iPodShufflePatch(MassGetDevInfo);
+ }
+
+ if (Dev & BIT7) {
+ return USB_ERROR; // Check for device address validity
+ }
+
+ //
+ // If bDev = 0 then get information about first mass storage device
+ //
+ if (!Dev) {
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_TYPE, 0, BIOS_DEV_TYPE_STORAGE, 0);
+ //USB_DEBUG(DEBUG_LEVEL_3, "Get Mass0 info: %x\n", DevInfo);
+
+ if (!DevInfo) { // Set as no more device found
+ MassGetDevInfo->bDevAddr = 0xFF;
+ return USB_SUCCESS;
+ }
+ } else { // Not the first mass device
+ //
+ // Get the device info structure for the matching device index
+ //
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, Dev, 0);
+ ASSERT(DevInfo);
+ if ( (!DevInfo) || (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT)) ) { // Error
+ return USB_ERROR;
+ }
+ //
+ // Get device info structure for next device
+ //
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_TYPE, DevInfo, BIOS_DEV_TYPE_STORAGE, 0);
+ ASSERT(DevInfo);
+ if (!DevInfo) { // Error. Exit !
+ return USB_ERROR;
+ }
+ }
+ MassInq = USBMassGetDeviceParameters(DevInfo);
+
+ if (!MassInq) {
+ return USB_ERROR;
+ }
+
+ MassGetDevInfo->bDevType = DevInfo->bPhyDevType;
+// MassGetDevInfo->bPhyDevType = fpDevInfo->bPhyDevType;
+ MassGetDevInfo->bEmuType = DevInfo->bEmuType;
+ MassGetDevInfo->wPciInfo =
+ gUsbData->HcTable[DevInfo->bHCNumber - 1]->wBusDevFuncNum;
+ MassGetDevInfo->fpDevId = (UINT32)(UINTN)((UINT8*)MassInq + 8);
+// MassGetDevInfo->fpDevId = USBMassAdjustIdString((UINT32)MassInq + 8);
+
+ Dev = (UINT8)(UINTN)USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, DevInfo, 0, 0);
+ ASSERT(Dev);
+
+ Dev |= BIT7; // Assume that no more mass device present
+
+ //
+ // Check whether more mass device is present
+ //
+ if (USB_GetDeviceInfoStruc(USB_SRCH_DEV_TYPE, DevInfo, BIOS_DEV_TYPE_STORAGE, 0)) {
+ Dev &= ~BIT7;
+ }
+
+ DevInfo->Flag |= DEV_INFO_MASS_DEV_REGD;
+ MassGetDevInfo->bDevAddr = Dev;
+
+ *(UINTN*)MassGetDevInfo->Handle = *(UINTN*)DevInfo->Handle;
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: iPodShufflePatch
+//
+// Description: This check whether iPod shuffle attached to system and move
+// iPod shuffle to first initial device.
+//
+// Input: Pointer to the mass get info struc
+//
+// Output: None
+//
+// Notes: Attaching iPod shuffle and iPod mini to system causes BIOS POST
+// stop. iPod shuffle must be initialized as early as possible.
+// iPod mini cosumes about 2 seconds to complete initialization,
+// init iPod shuffle first to fix problem.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+iPodShufflePatch(
+ MASS_GET_DEV_INFO *MassGetDevInfo
+)
+{
+ //TO BE IMPLEMENTED
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetDeviceStatus
+//
+// Description: Get USB MassStorage device status. Include Media Informarion.
+// Refer to USB_MASS_MEDIA_XXX in USBDEF.H
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR or USB_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassGetDeviceStatus (
+ MASS_GET_DEV_STATUS *MassGetDevSts
+)
+{
+ DEV_INFO* DevInfo;
+ UINT8 DevAddr = MassGetDevSts->bDevAddr;
+ UINT8 LastStatus;
+
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+
+ ASSERT(DevInfo != NULL);
+ if (DevInfo == NULL) {
+ return USB_ERROR;
+ }
+
+ LastStatus= DevInfo->bLastStatus;
+
+ USBMassCheckDeviceReady(DevInfo);
+
+ // When the Media is not present in the drive and insert the Media
+ // it's just sends the status as Media Present. So check the last status
+ // and if the media not present and current stauts is media present
+ // report it as Media changed
+ if ((LastStatus ^ DevInfo->bLastStatus) & USB_MASS_MEDIA_PRESENT) {
+ // Report the Last Status along with Media Changed status
+ DevInfo->bLastStatus |= USB_MASS_MEDIA_CHANGED;
+ }
+
+ MassGetDevSts->bDeviceStatus = DevInfo->bLastStatus;
+
+ if (DevInfo->bLastStatus & USB_MASS_MEDIA_CHANGED) {
+ //
+ // Clear Media Change Status.
+ //
+ DevInfo->bLastStatus &= (UINT8)(~USB_MASS_MEDIA_CHANGED);
+ }
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassCmdPassThru
+//
+// Description: This function issues the command/data sequence provided
+// as input. This function can be used to send raw data
+// to the USB mass storage device
+//
+// Input: fpDevInfo Pointer to Device Info structure
+// fpMassCmdPassThru Pointer to the mass command pass
+// through structure
+// bDevAddr USB device address of the device
+// dSenseData Sense data of the last command
+// fpCmdBuffer Far pointer to the command buffer
+// wCmdLength Command length
+// fpDataBuffer Far pointer for data buffer
+// wDataLength Data length
+// bXferDir Data transfer direction
+//
+// Output: USB_SUCCESS or USB_ERROR
+// dSenseData Sense data of the last command
+// fpDataBuffer Updated with returned data if the transfer
+// is an IN transaction
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassCmdPassThru (
+ MASS_CMD_PASS_THRU *MassCmdPassThru
+)
+{
+ UINT8 *CmdBuffer;
+ UINT8 *Src;
+ UINT8 *Dst;
+ DEV_INFO *DevInfo;
+// UINT8 CommandRetried = FALSE;
+ UINT8 CmdBlkSize;
+ UINT8 Count;
+ UINT16 Data16;
+ UINT32 Data32;
+ UINT8 DevAddr = MassCmdPassThru->bDevAddr;
+ MASS_XACT_STRUC MassXactStruc;
+
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+ if ( (!DevInfo) || (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT)) ) { // Error
+ return USB_ERROR;
+ }
+
+ CmdBlkSize = (UINT8)((MassCmdPassThru->wCmdLength +
+ USB_MEM_BLK_SIZE - 1) >> USB_MEM_BLK_SIZE_SHIFT);
+
+ //
+ // Check whether the drive is ready for read TOC command
+ //
+ USBMassCheckDeviceReady(DevInfo);
+
+ //
+ // Allocate memory for the command buffer
+ //
+ CmdBuffer = USB_MemAlloc((UINT8)GET_MEM_BLK_COUNT(CmdBlkSize));
+ if (!CmdBuffer) {
+ return USB_ERROR;
+ }
+
+ //
+ // Copy the command into (just allocated) mass command buffer
+ //
+ Src = (UINT8*)(UINTN)MassCmdPassThru->fpCmdBuffer;
+ Dst = CmdBuffer;
+ for (Count = 0; Count < MassCmdPassThru->wCmdLength; Count++) {
+ *Dst++ = *Src++;
+ }
+
+ //
+ // Clear the common bulk transaction structure
+ //
+ USBMassClearMassXactStruc(&MassXactStruc);
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = CmdBuffer;
+ MassXactStruc.bCmdSize = (UINT8)MassCmdPassThru->wCmdLength;
+ MassXactStruc.bXferDir = MassCmdPassThru->bXferDir;
+ MassXactStruc.fpBuffer = (UINT8*)(UINTN)MassCmdPassThru->fpDataBuffer;
+ MassXactStruc.dLength = (UINT32)MassCmdPassThru->wDataLength;
+
+ Data16 = (UINT16)USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+
+ //
+ // Update the actual data length processed/returned
+ //
+ MassCmdPassThru->wDataLength = Data16;
+
+ Data32 = USBMassRequestSense (DevInfo);
+
+ MassCmdPassThru->dSenseData = Data32;
+
+ //
+ // Check and free command buffer
+ //
+ if (!CmdBuffer) {
+ return USB_ERROR;
+ }
+
+ USB_MemFree(CmdBuffer, (UINT16)GET_MEM_BLK_COUNT(CmdBlkSize));
+
+ return USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassReadCapacity16Command
+//
+// Description: This function issues read capacity of the mass storage
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR or USB_SUCCESS
+//
+// Notes: This routine will update the MassDeviceInfo structure
+// with the block size & last LBA values obtained from the
+// device
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassReadCapacity16Command (
+ DEV_INFO* DevInfo
+)
+{
+ UINT32 Data;
+ COMN_READ_CAPACITY_16_CMD *CmdBuffer;
+ MASS_XACT_STRUC MassXactStruc;
+
+ if (!VALID_DEVINFO(DevInfo)) {
+ return USB_ERROR;
+ }
+ //
+ // Allocate memory for the command buffer
+ //
+ CmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_16_CMD));
+
+ if (!CmdBuffer) {
+ return USB_ERROR;
+ }
+
+ CmdBuffer->OpCode = COMMON_READ_CAPACITY_16_OPCODE;
+ CmdBuffer->ServiceAction = 0x10;
+ CmdBuffer->AllocLength = 0x0C000000;
+
+ //
+ // Clear the common bulk transaction structure
+ //
+ USBMassClearMassXactStruc(&MassXactStruc);
+
+ //
+ // Change the bulk transfer delay to 10 seconds (For CDROM drives)
+ //
+ gUsbData->wBulkDataXferDelay = 10000;
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)CmdBuffer;
+
+ MassXactStruc.bCmdSize = sizeof(COMN_RWV_16_CMD);
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = gUsbData->fpUSBTempBuffer;
+ MassXactStruc.dLength = 0xC;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "rcc..");
+ Data = USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+
+ //
+ // Reset the delay back
+ //
+ gUsbData->wBulkDataXferDelay = 0;
+
+ if (!Data) {
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_16_CMD));
+
+ USB_DEBUG (DEBUG_LEVEL_3, "err ");
+ return USB_ERROR;
+ }
+
+ Data = *((UINT32*)(gUsbData->fpUSBTempBuffer + 8));
+
+ //
+ // Change little endian format to big endian(INTEL) format
+ //
+ Data = dabc_to_abcd(Data);
+ //(EIP37167+)>
+ if (!Data) {
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_16_CMD));
+ USB_DEBUG (DEBUG_LEVEL_3, "err ");
+ return USB_ERROR;
+ }
+
+ DevInfo->wBlockSize = (UINT16)Data;
+
+ USB_DEBUG(3,"BlockSize %x\n", DevInfo->wBlockSize);
+
+ //
+ // Store the last LBA number in the mass info structure
+ //
+ Data = *((UINT32*)(gUsbData->fpUSBTempBuffer));
+
+ Data = dabc_to_abcd(Data);
+
+ DevInfo->MaxLba = Shl64(Data, 32);
+
+ Data = *((UINT32*)(gUsbData->fpUSBTempBuffer + 4));
+
+ Data = dabc_to_abcd(Data);
+
+ DevInfo->MaxLba |= Data;
+
+ USB_DEBUG(3,"MaxLba %lx\n", DevInfo->MaxLba);
+
+ return USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassReadCapacity10Command
+//
+// Description: This function issues read capacity of the mass storage
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR or USB_SUCCESS
+//
+// Notes: This routine will update the MassDeviceInfo structure
+// with the block size & last LBA values obtained from the
+// device
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassReadCapacity10Command (
+ DEV_INFO* DevInfo
+)
+{
+ UINT32 Data;
+ COMN_READ_CAPACITY_10_CMD *CmdBuffer;
+ MASS_XACT_STRUC MassXactStruc;
+
+ if (!VALID_DEVINFO(DevInfo)) {
+ return USB_ERROR;
+ }
+
+ if (Shr64(DevInfo->MaxLba, 32)) {
+ USBMassReadCapacity16Command(DevInfo);
+ return USB_SUCCESS;
+ }
+ //
+ // Allocate memory for the command buffer
+ //
+ CmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_10_CMD));
+
+ if (!CmdBuffer) {
+ return USB_ERROR;
+ }
+
+ CmdBuffer->bOpCode = COMMON_READ_CAPACITY_10_OPCODE;
+
+ //
+ // Clear the common bulk transaction structure
+ //
+ USBMassClearMassXactStruc(&MassXactStruc);
+
+ //
+ // Change the bulk transfer delay to 10 seconds (For CDROM drives)
+ //
+ gUsbData->wBulkDataXferDelay = 10000;
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)CmdBuffer;
+ //(EIP51158+)>
+ if (DevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x0A; //SBC-3_66
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMN_READ_CAPACITY_10_CMD);
+ }
+ //<(EIP51158+)
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = gUsbData->fpUSBTempBuffer;
+ MassXactStruc.dLength = 8;
+
+ USB_DEBUG (DEBUG_LEVEL_3, "rcc..");
+ Data = USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+
+ //
+ // Reset the delay back
+ //
+ gUsbData->wBulkDataXferDelay = 0;
+
+ if (!Data) {
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_10_CMD));
+ USB_DEBUG (DEBUG_LEVEL_3, "err ");
+ return USB_ERROR;
+ }
+
+ USB_DEBUG(3,"Read Capacity 10 LBA %x\n", *(UINT32*)gUsbData->fpUSBTempBuffer);
+
+ if (*(UINT32*)gUsbData->fpUSBTempBuffer == 0xFFFFFFFF) {
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_10_CMD));
+ USBMassReadCapacity16Command(DevInfo);
+ return USB_SUCCESS;
+ }
+
+ Data = *((UINT32*)(gUsbData->fpUSBTempBuffer + 4));
+
+ //
+ // Change little endian format to big endian(INTEL) format
+ //
+ Data = dabc_to_abcd(Data);
+ //(EIP37167+)>
+ if (!Data) {
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_10_CMD));
+ USB_DEBUG(DEBUG_LEVEL_3, "err ");
+ return USB_ERROR;
+ }
+ //<(EIP37167+)
+
+ DevInfo->wBlockSize = (UINT16)Data;
+//USB_DEBUG(DEBUG_LEVEL_3, "succ: %x, %x\n", dData, fpDevInfo);
+ //
+ // Store the last LBA number in the mass info structure
+ //
+ Data = *((UINT32*)(gUsbData->fpUSBTempBuffer));
+
+ Data = dabc_to_abcd(Data);
+
+ if (!Data) {
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_10_CMD));
+ USB_DEBUG (DEBUG_LEVEL_3, "err ");
+ return USB_ERROR;
+ }
+
+ DevInfo->MaxLba = Data + 1; // 1-based value
+
+ USB_DEBUG(DEBUG_LEVEL_3, "%x ", DevInfo->MaxLba);
+
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_CAPACITY_10_CMD));
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassReadFormatCapacity
+//
+// Description: This function sends read format capacity command to the USB
+// mass storage device
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR or USB_SUCCESS
+//
+// Notes: This routine will update the MassDeviceInfo structure
+// with the block size & last LBA values obtained from the
+// device
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassReadFormatCapacity (DEV_INFO* fpDevInfo)
+{
+ COMN_READ_FMT_CAPACITY *fpCmdBuffer;
+ UINT32 dData;
+ UINT16 wData;
+ UINT8* DataBuffer;
+ UINT16 DataBufferSize = 0xFC;
+ MASS_XACT_STRUC MassXactStruc;
+
+ //
+ // Allocate memory for the command buffer
+ //
+ fpCmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMN_READ_FMT_CAPACITY));
+
+ if(!fpCmdBuffer) {
+ return USB_ERROR;
+ }
+
+ DataBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT(DataBufferSize));
+ if (DataBuffer == NULL) {
+ return USB_ERROR;
+ }
+
+ fpCmdBuffer->bOpCode = COMMON_READ_FORMAT_CAPACITY_OPCODE;
+ fpCmdBuffer->wAllocLength = (UINT16)((DataBufferSize << 8) + (DataBufferSize >> 8));
+
+ USBMassClearMassXactStruc(&MassXactStruc); // Clear the common bulk transaction structure
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)fpCmdBuffer;
+ //(EIP51158+)>
+ if (fpDevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x0A;
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMN_READ_FMT_CAPACITY);
+ }
+ //<(EIP51158+)
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = DataBuffer;
+// MassXactStruc.dLength = MAX_TEMP_BUFFER_SIZE;
+//
+// Temp buffer 40h-64h was used as device name string buffer.
+// Limit Transaction size to 40h to prevent name string display problem.
+//
+ MassXactStruc.dLength = DataBufferSize;
+
+USB_DEBUG (DEBUG_LEVEL_5, "Issue ReadFormatCapacityCommand .... \n");
+
+ dData = USBMassIssueMassTransaction(fpDevInfo, &MassXactStruc);
+
+ //
+ // The amount of data obtained should be atleast of read format capacity structure size
+ //
+ if (dData < sizeof (COMN_READ_FMT_CAPACITY)) {
+ USB_MemFree(DataBuffer, GET_MEM_BLK_COUNT(DataBufferSize));
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_FMT_CAPACITY));
+ return USB_ERROR;
+ }
+
+
+ if ((DataBuffer[0] != 0) || (DataBuffer[1] != 0) || (DataBuffer[2] != 0) || (DataBuffer[3] < 0x08)) {
+ USB_MemFree(DataBuffer, GET_MEM_BLK_COUNT(DataBufferSize));
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_FMT_CAPACITY));
+ return USB_ERROR;
+ }
+
+ wData = *((UINT16*)(DataBuffer + 10)); // Offset 10
+ if (wData == 0) {
+ USB_MemFree(DataBuffer, GET_MEM_BLK_COUNT(DataBufferSize));
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_FMT_CAPACITY));
+ return USB_ERROR;
+ }
+ fpDevInfo->wBlockSize = (UINT16)((wData << 8) + (wData >> 8));
+
+ dData = *((UINT32*)(DataBuffer + 4)); // Offset 4
+ if (dData == 0) {
+ USB_MemFree(DataBuffer, GET_MEM_BLK_COUNT(DataBufferSize));
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_FMT_CAPACITY));
+ return USB_ERROR;
+ }
+ dData = dabc_to_abcd(dData);
+ fpDevInfo->MaxLba = dData;
+
+ if (dData == USB_144MB_FDD_MAX_LBA) {
+ //
+ // Return parameters for 1.44MB floppy
+ //
+ fpDevInfo->Heads = USB_144MB_FDD_MAX_HEADS;
+ fpDevInfo->NonLBAHeads = USB_144MB_FDD_MAX_HEADS;
+ fpDevInfo->bSectors = USB_144MB_FDD_MAX_SECTORS;
+ fpDevInfo->bNonLBASectors = USB_144MB_FDD_MAX_SECTORS;
+ fpDevInfo->wCylinders = USB_144MB_FDD_MAX_CYLINDERS;
+ fpDevInfo->wNonLBACylinders = USB_144MB_FDD_MAX_CYLINDERS;
+ fpDevInfo->bMediaType = USB_144MB_FDD_MEDIA_TYPE;
+ }
+
+ USB_MemFree(DataBuffer, GET_MEM_BLK_COUNT(DataBufferSize));
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_READ_FMT_CAPACITY));
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetConfiguration
+//
+// Description: This function sends get configuration command to the USB
+// mass storage device
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR or USB_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassGetConfiguration(
+ DEV_INFO* DevInfo
+)
+{
+ COMMON_GET_CONFIGURATION *CmdBuffer;
+ UINT32 Data;
+ UINT8 *DataBuffer;
+ UINT16 DataBufferSize = 0x8;
+ MASS_XACT_STRUC MassXactStruc;
+
+ //
+ // Allocate memory for the command buffer
+ //
+ CmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMMON_GET_CONFIGURATION));
+
+ if (!CmdBuffer) {
+ return USB_ERROR;
+ }
+
+ DataBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT(DataBufferSize));
+ if (DataBuffer == NULL) {
+ return USB_ERROR;
+ }
+
+ CmdBuffer->OpCode = COMMON_GET_CONFIGURATION_OPCODE;
+ CmdBuffer->AllocLength = (UINT16)((DataBufferSize << 8) + (DataBufferSize >> 8));
+
+ USBMassClearMassXactStruc(&MassXactStruc); // Clear the common bulk transaction structure
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)CmdBuffer;
+ MassXactStruc.bCmdSize = sizeof (COMMON_GET_CONFIGURATION);
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = DataBuffer;
+
+ MassXactStruc.dLength = DataBufferSize;
+
+ USB_DEBUG(DEBUG_LEVEL_5, "Issue GetConfigurationCommand .... \n");
+
+ Data = USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+
+ USB_MemFree(DataBuffer, GET_MEM_BLK_COUNT(DataBufferSize));
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMMON_GET_CONFIGURATION));
+
+ if (Data) {
+ return USB_SUCCESS;
+ } else {
+ return USB_ERROR;
+ }
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassReadSector
+//
+// Description: This function a sector at the LBA specified
+//
+// Input: Pointer to DeviceInfo structure
+// LBA to read
+// DS:DI Data buffer pointer
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassReadSector(
+ DEV_INFO* DevInfo,
+ UINT32 Lba,
+ UINT8* Buffer
+)
+{
+ COMN_RWV_10_CMD *CmdBuffer;
+ UINT32 Data;
+ UINT8 Counter;
+ UINT8 RetValue = USB_ERROR;
+ MASS_XACT_STRUC MassXactStruc;
+
+ //
+ // Allocate memory for the command buffer
+ //
+ CmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMN_RWV_10_CMD));
+
+ if (!CmdBuffer) {
+ return USB_ERROR;
+ }
+
+ USBMassClearMassXactStruc(&MassXactStruc);
+
+ Counter = 10;
+ do {
+ //
+ // Set opcode to read command
+ //
+ CmdBuffer->bOpCode = COMMON_READ_10_OPCODE;
+ CmdBuffer->wTransferLength = 0x100; // Big endian to little endian: 0x0001 -> 0x0100
+ Data = Lba;
+ //
+ // Change LBA from big endian to little endian
+ //
+ Data = dabc_to_abcd(Data);
+
+ CmdBuffer->dLba = Data;
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)CmdBuffer;
+ //(EIP51158+)>
+ if (DevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x0A; //SBC-3_60
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMN_RWV_10_CMD);
+ }
+ //<(EIP51158+)
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = Buffer;
+ MassXactStruc.dLength = DevInfo->wBlockSize; //(EIP59738)
+ MassXactStruc.wPreSkip = 0;
+ MassXactStruc.wPostSkip= 0;
+
+ USB_DEBUG (DEBUG_LEVEL_5, "Read Sector .... \n");
+
+ Data = USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+ if(Data) {
+ RetValue = USB_SUCCESS;
+ break; // Success
+ }
+ //
+ // May be drive error. Try to correct from it !
+ // Check whether the drive is ready for read/write/verify command
+ //
+ Data = USBMassCheckDeviceReady(DevInfo);
+ if (Data) { // Device is not ready.
+ RetValue = USB_ERROR;
+ break;
+ }
+ MemFill((UINT8*)CmdBuffer, sizeof(COMN_RWV_10_CMD), 0);
+ } while (Counter--);
+
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_RWV_10_CMD));
+
+ return RetValue;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassUpdateCHSFromBootRecord
+//
+// Description: This function parses the boot record and extract the CHS
+// information of the formatted media from the boot record.
+// This routine checks for DOS & NTFS formats only
+//
+// Input: Pointer to DeviceInfo structure
+// Maximum LBA in the device
+// Boot record of the device
+//
+// Output: USB_ERROR If the boot record is un-recognizable and CHS info
+// is not extracted
+// USB_SUCCESS If the boot record is recognizable and CHS info
+// is extracted. CHS information is updated in the
+// mass device info structure
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassUpdateCHSFromBootRecord(
+ DEV_INFO *DevInfo,
+ UINT64 MaxLba,
+ BOOT_SECTOR *BootSetor
+)
+{
+ UINT32 OemName = 0;
+ UINT32 Fat16SysType = 0;
+ UINT32 Fat32SysType = 0;
+
+ if (BootSetor->Signature != 0xAA55) {
+ return USB_ERROR;
+ }
+
+ //
+ // Check for valid MSDOS/MSWIN/NTFS boot record
+ //
+ MemCopy((UINT8*)BootSetor->OEMName, (UINT8*)&OemName, sizeof(OemName));
+ if ((OemName != 0x4F44534D) && // "ODSM", MSDO...
+ (OemName != 0x4957534D) && // "IWSM", MSWI...
+ (OemName != 0x5346544E)) { // "SFTN", NTFS
+ //
+ // Check for valid FAT,FAT16 or FAT32 boot records
+ //
+ BootSetor->Fat.Fat16.FilSysType[3] = 0x20;
+ MemCopy((UINT8*)BootSetor->Fat.Fat16.FilSysType, (UINT8*)&Fat16SysType,
+ sizeof(Fat16SysType));
+ MemCopy((UINT8*)BootSetor->Fat.Fat32.FilSysType, (UINT8*)&Fat32SysType,
+ sizeof(Fat32SysType));
+ if ((Fat16SysType != 0x20544146) && // " TAF", FAT
+ (Fat32SysType != 0x33544146)) { // "3TAF", FAT3
+
+ //
+ // None of the conditions met - boot record is invalid. Return with error
+ //
+ return USB_ERROR;
+ }
+ }
+
+ // zero check added to prevent invalid sector/head information in BPB
+ if (BootSetor->SecPerTrk == 0) {
+ return USB_ERROR;
+ }
+
+ DevInfo->bSectors = (UINT8)BootSetor->SecPerTrk;
+ DevInfo->bNonLBASectors = (UINT8)BootSetor->SecPerTrk;
+
+ // Wrong BPB in MSI MegaStick 128; this is preformat usility issue, wrong BPB
+ // information built in device.
+ if (BootSetor->NumHeads == 0) {
+ return USB_ERROR;
+ }
+
+ DevInfo->Heads = BootSetor->NumHeads;
+ DevInfo->NonLBAHeads = BootSetor->NumHeads;
+ DevInfo->BpbMediaDesc = BootSetor->Media;
+
+ USBMassUpdateCylinderInfo(DevInfo, MaxLba);
+
+ USB_DEBUG (DEBUG_LEVEL_4, "CHS: %x %x %x\n",
+ DevInfo->bSectors,
+ DevInfo->Heads,
+ DevInfo->wCylinders);
+
+ return USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassUpdateCylinderInfo
+//
+// Description: This procedure update cylinder parameter for device geometry.
+// head and sector paramaters are required before invoke this
+// function.
+//
+// Input: Pointer to DeviceInfo structure
+// Maximum LBA in the device
+// dev->bHeads
+// dev->bSectors
+//
+// Output: None
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassUpdateCylinderInfo(
+ DEV_INFO* Dev,
+ UINT64 Lba
+)
+{
+ UINT64 Data;
+
+ if ((Dev->bSectors != 0) && (Dev->Heads != 0)) {
+ Data = Div64(Lba, (Dev->bSectors * Dev->Heads), NULL);
+ } else {
+ Data = 0;
+ }
+
+ if (Data <= 1) {
+ Data++;
+ }
+ if (Data > 0xFFFF) {
+ Data = 0xFFFF; // DOS workaround
+ }
+ Dev->wCylinders = (UINT16)Data;
+ Dev->wNonLBACylinders = (UINT16)Data;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetFormatType
+//
+// Description: This function reads the first sector from the mass storage
+// device and identifies the formatted type.
+//
+// Input: Pointer to DeviceInfo structure
+// Maximum LBA of the device
+//
+// Output: USB_ERROR If could not identify the formatted type
+// USB_SUCCESS If formatted type is identified
+// MSB of emu - Emulation type
+// LSB of emu - Device type (Floppy, Harddisk or CDROM)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassGetFormatType(
+ DEV_INFO* DevInfo,
+ UINT64 MaxLba,
+ UINT16 *Emu
+)
+{
+
+ MBR_PARTITION Partition = {0};
+
+ //
+ // Read the first sector of the device
+ //
+ if (USBMassReadSector(DevInfo, 0, gUsbData->fpUSBMassConsumeBuffer) == USB_ERROR) {
+ return USB_ERROR;
+ }
+
+ DevInfo->bHiddenSectors = 0;
+
+ //
+ // Check for validity of the partition table/boot record
+ //
+ if (*((UINT16*)(gUsbData->fpUSBMassConsumeBuffer + 0x1FE)) != 0xAA55) {
+ USBMassSetDefaultGeometry(DevInfo, MaxLba);
+ return USB_ERROR;
+ }
+
+ if (USBMassValidatePartitionTable((MASTER_BOOT_RECORD*)gUsbData->fpUSBMassConsumeBuffer,
+ MaxLba, &Partition) == USB_SUCCESS) {
+ //
+ // Only one partition present, check the device size, if the device size
+ // is less than 530 MB assume FDD or else assume the emulation as HDD
+ //
+
+ //if (((MaxLba >> 11) < MAX_SIZE_FOR_USB_FLOPPY_EMULATION) && //(EIP80382)
+ // !(gUsbData->dUSBStateFlag & USB_FLAG_MASS_NATIVE_EMULATION)) {
+ // emu_ = (UINT16)(USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD;
+ //}else {
+ // emu_ = (UINT16)(USB_EMU_HDD_ONLY << 8) + USB_MASS_DEV_HDD;
+ //}
+ //
+ // Read boot sector, set the LBA number to boot record LBA number
+ //
+ DevInfo->bHiddenSectors = Partition.StartingLba;
+
+ if (USBMassReadSector(DevInfo, Partition.StartingLba,
+ gUsbData->fpUSBMassConsumeBuffer) == USB_ERROR) {
+ return USB_ERROR;
+ }
+
+ if (USBMassUpdateCHSFromBootRecord(DevInfo, MaxLba,
+ (BOOT_SECTOR*)gUsbData->fpUSBMassConsumeBuffer) == USB_SUCCESS) {
+ if (((Shr64(MaxLba, 11)) < MAX_SIZE_FOR_USB_FLOPPY_EMULATION) &&
+ !(gUsbData->dUSBStateFlag & USB_FLAG_MASS_NATIVE_EMULATION)) {
+ if (DevInfo->bSubClass != SUB_CLASS_UFI) {
+ *Emu = (UINT16)(USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD;
+ }
+ }
+ return USB_SUCCESS;
+ } else { // Reset hidden sector value and return HDD emulation
+ USBMassSetDefaultGeometry(DevInfo, MaxLba);
+ DevInfo->bHiddenSectors = 0;
+ //(EIP43711)>
+ //don't emulate as HDD for UFI class even media has valid partition like HDD
+ if (gUsbData->dUSBStateFlag & USB_FLAG_MASS_SIZE_EMULATION) {
+ if (DevInfo->bSubClass != SUB_CLASS_UFI) {
+ if ((Shr64(MaxLba, 11)) < MAX_SIZE_FOR_USB_FLOPPY_EMULATION) {
+ *Emu = (UINT16)(USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD;
+ }
+ }
+ }
+ //<(EIP43711)
+ return USB_SUCCESS;
+ }
+ }
+
+ *Emu = USBMassSetDefaultType(DevInfo, MaxLba);
+
+ if (USBMassUpdateCHSFromBootRecord(DevInfo, MaxLba,
+ (BOOT_SECTOR*)gUsbData->fpUSBMassConsumeBuffer) == USB_SUCCESS) {
+ //*emu = USBMassSetDefaultType(fpDevInfo, MaxLba);
+ if (gUsbData->dUSBStateFlag & USB_FLAG_MASS_SIZE_EMULATION) {
+ if (DevInfo->bSubClass != SUB_CLASS_UFI) {
+ if ((Shr64(MaxLba, 11)) >= MAX_SIZE_FOR_USB_FLOPPY_EMULATION) {
+ *Emu = (UINT16)(USB_EMU_HDD_ONLY << 8) + USB_MASS_DEV_HDD;
+ }
+ }
+ }
+ return USB_SUCCESS;
+ }
+ USBMassSetDefaultGeometry(DevInfo, MaxLba);
+
+ //*emu = USBMassSetDefaultType(fpDevInfo, MaxLba);
+
+ if (((Shr64(MaxLba, 11)) >= MAX_SIZE_FOR_USB_FLOPPY_EMULATION) &&
+ !(gUsbData->dUSBStateFlag & USB_FLAG_MASS_NATIVE_EMULATION)) {
+ if (DevInfo->bSubClass != SUB_CLASS_UFI) {
+ *Emu = (UINT16)(USB_EMU_HDD_ONLY << 8) + USB_MASS_DEV_HDD;
+ }
+ DevInfo->bHiddenSectors = 0;
+ }
+ //*emu = emu_;
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassSetDefaultType
+//
+// Description: This procedure set device type depend on device class.
+//
+// Input: Pointer to DeviceInfo structure
+// Maximum LBA in the device (DWORD)
+//
+// Output: Device Type (WORD)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassSetDefaultType(
+ DEV_INFO* Dev,
+ UINT64 Lba
+)
+{
+ UINT16 DevType = (UINT16)(USB_EMU_FLOPPY_ONLY << 8) + USB_MASS_DEV_ARMD;
+
+ if (Dev->bSubClass != SUB_CLASS_UFI) { // Check whether UFI class device
+ // Assume force FDD emulation for non-UFI class device
+ DevType = (UINT16)(USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD;
+ }
+ return DevType;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassValidatePartitionTable
+//
+// Description: This procedure check whether partition table valid.
+//
+// Input: Partition table content
+// Maximum LBA in the device
+//
+// Output: USB_SUCCESS - partion table is valid:
+// Possible valid entry count(1-based)
+// Table entry counts(0-based, 4 means all entries scaned)
+// Activate entry offset(Absolute offset)
+// USB_ERROR - Invalid partition table
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassValidatePartitionTable(
+ IN MASTER_BOOT_RECORD *Mbr,
+ IN UINT64 Lba,
+ OUT MBR_PARTITION *Partition)
+{
+ UINT8 Index = 0;
+ UINT8 ActivateIndex = 0;
+
+ // The partition table area could be all 0's, and it would pass the below tests,
+ // So test for that here (test sector count for all partitions).
+ if ((Mbr->PartRec[0].SizeInLba == 0) &&
+ (Mbr->PartRec[1].SizeInLba == 0) &&
+ (Mbr->PartRec[2].SizeInLba == 0) &&
+ (Mbr->PartRec[3].SizeInLba == 0)) {
+ return USB_ERROR;
+ }
+
+ for (Index = 0; Index < 4; Index++) {
+ // Boot flag check added to ensure that boot sector will not be treated as
+ // a valid partation table.
+ if (Mbr->PartRec[Index].BootIndicator & 0x7F) {
+ return USB_ERROR; // BootFlag should be 0x0 or 0x80
+ }
+
+ // Check whether beginning LBA is reasonable
+ if (Mbr->PartRec[Index].StartingLba > Lba) {
+ return USB_ERROR;
+ }
+
+ // Check whether the size is reasonable
+#if HDD_PART_SIZE_CHECK
+ if (Mbr->PartRec[Index].SizeInLba > Lba) {
+ return USB_ERROR;
+ }
+#endif
+ // Update activate entry offset
+ if (!(Mbr->PartRec[Index].BootIndicator & 0x80)) {
+ continue;
+ }
+
+ ActivateIndex = Index;
+ }
+
+ // If no activate partition table entry found use first entry
+ MemCopy((UINT8*)&Mbr->PartRec[ActivateIndex], (UINT8*)Partition,
+ sizeof(MBR_PARTITION));
+
+ return USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassSetDefaultGeometry
+//
+// Description: This procedure set default geometry for mass storage devices.
+//
+// Input: Pointer to DeviceInfo structure
+// Maximum LBA in the device
+//
+// Output: USB_ERROR If could not identify the formatted type
+// USB_SUCCESS If formatted type is identified
+// Emulation type - bits 8..15
+// Device type (Floppy, Harddisk or CDROM) - bits 0..7
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 USBMassSetDefaultGeometry(DEV_INFO* dev, UINT64 lba)
+{
+ if (dev->bSubClass == SUB_CLASS_UFI) {
+ dev->Heads = 0x02;
+ dev->NonLBAHeads = 0x02;
+ dev->bSectors = 0x12;
+ dev->bNonLBASectors = 0x12;
+ }
+ else {
+ dev->bSectors = 0x3F;
+ dev->bNonLBASectors = 0x3F;
+// Use default heads that results in 1023 (3FF) cylinders or less for CHS
+ if (lba <= 0x1F7820) {
+ dev->Heads = 0x20;
+ dev->NonLBAHeads = 0x20;
+ }
+ else if ( (lba > 0x1F7820) && (lba <= 0x3EF040) ) {
+ dev->Heads = 0x40;
+ dev->NonLBAHeads = 0x40;
+ }
+ else if ( (lba > 0x3EF040) && (lba <= 0x7DE080) ) {
+ dev->Heads = 0x80;
+ dev->NonLBAHeads = 0x80;
+ }
+ else if (lba > 0x7DE080) {
+ dev->Heads = 0xFF;
+ dev->NonLBAHeads = 0xFF;
+ }
+ }
+
+ USBMassUpdateCylinderInfo(dev, lba);
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassIdentifyDeviceType
+//
+// Description: This function identifies the type of the USB mass storage
+// device attached from the INQUIRY data obtained from the drive
+//
+// Input: Pointer to DeviceInfo structure
+// Pointer to the inquiry data (read from device)
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassIdentifyDeviceType(
+ DEV_INFO* DevInfo,
+ UINT8* InqData
+)
+{
+ UINT16 EmulationType;
+ UINT16 ForceEmulationType = 0;
+ UINT32 Data = 0;
+ UINT8 Count;
+ static UINT16 UsbMassEmulationTypeTable[5] = {
+ 0, // Auto
+ (USB_EMU_FLOPPY_ONLY << 8) + USB_MASS_DEV_ARMD, // Floppy
+ (USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD, // Forced floppy
+ (USB_EMU_HDD_ONLY << 8) + USB_MASS_DEV_HDD, // HDD
+ (USB_EMU_HDD_OR_FDD << 8) + USB_MASS_DEV_CDROM }; // CDROM
+
+ USBMassGetPhysicalDeviceType(DevInfo, InqData);
+
+ // Note: at this point we assume that dev->wEmulationOption is filled in
+ // according to the setup question selection.
+ if (!(DevInfo->Flag & DEV_INFO_HOTPLUG) || DevInfo->wEmulationOption) { // not auto
+ EmulationType = UsbMassEmulationTypeTable[DevInfo->wEmulationOption];
+ ForceEmulationType = UsbMassEmulationTypeTable[DevInfo->wEmulationOption];
+ }
+
+ //USB_DEBUG(DEBUG_LEVEL_3, ">>-- IdentifyDeviceType:: Device #%d, Emul#: %d, Emul: %x\n",
+ // DevInfo->bDeviceAddress, DevInfo->wEmulationOption, EmulationType);
+#if USB_STORAGE_DEVICE_RMB_CHECK
+ if (*(InqData + 1) & 0x80) { // Check RMB status
+ DevInfo->bLastStatus |= USB_MASS_MEDIA_REMOVEABLE;
+ }
+#else
+ DevInfo->bLastStatus |= USB_MASS_MEDIA_REMOVEABLE;
+#endif
+ DevInfo->bLastStatus |= USB_MASS_MEDIA_PRESENT; // Assume Media Present
+
+ if (*InqData == 5) { // CDROM
+ // Set the type as CDROM and emulation as HDD or FDD
+ DevInfo->wBlockSize = 0x800;
+ EmulationType = (UINT16)(USB_EMU_HDD_OR_FDD << 8) + USB_MASS_DEV_CDROM;
+ goto UMIDT_DeviceTypeOver;
+ }
+// ;(EIP25229+)>
+#if USB_START_UNIT_BEFORE_MSD_ENUMERATION
+// Start unit command before access it
+ USBMassStartUnitCommand(DevInfo);
+#endif
+// ;<(EIP25229+)
+ //(EIP80382)>
+ if (DevInfo->bSubClass == SUB_CLASS_UFI) {
+ EmulationType = (UINT16)(USB_EMU_FLOPPY_ONLY << 8) + USB_MASS_DEV_ARMD;
+ } else {
+ EmulationType = (UINT16)(USB_EMU_HDD_ONLY << 8) + USB_MASS_DEV_HDD;
+ }
+ //<(EIP80382)
+
+ FixedDelay(gUsbData->UsbTimingPolicy.MassDeviceComeUp * 1000); // Device is coming up give 500ms delay
+ //
+ // Some USB mass storage devces are not fast enough to accept mass storage
+ // commands for parsing geometry, issue read capacity command to make sure device
+ // is ready for further access. (USB0089+)>
+ //
+ if (DevInfo->bSubClass != SUB_CLASS_UFI) {
+ for (Count = 0; Count < 30 && VALID_DEVINFO(DevInfo); Count++) {
+ if (USBMassReadCapacity10Command(DevInfo) == USB_SUCCESS) {
+ break;
+ }
+ if ((UINT16)USBMassRequestSense(DevInfo) == 0x3A02 ) { //(EIP86793)
+ break; // No media
+ }
+ }
+ }
+ //
+ // Get the block size & last LBA number
+ //
+ Data = USBMassCheckDeviceReady(DevInfo);
+ //(EIP86793)>
+ if ((UINT16)Data == 0x3A02) { // Check for media presence status
+ //
+ // Media not present. Try to get disk geometry from Format
+ // capacity command
+ //
+ if (!(DevInfo->wIncompatFlags & USB_INCMPT_FORMAT_CAPACITY_NOT_SUPPORTED)) {
+ USBMassReadFormatCapacity(DevInfo);
+ if ((DevInfo->MaxLba != 0) && (DevInfo->MaxLba <= USB_144MB_FDD_MAX_LBA)) {
+ EmulationType = (UINT16)(USB_EMU_FLOPPY_ONLY << 8) + USB_MASS_DEV_ARMD;
+ } else {
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_MASS_EMULATION_FOR_NO_MEDIA)) {
+ EmulationType = (UINT16)(USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD;
+ }
+ }
+ goto UMIDT_DeviceTypeOver;
+ }
+ }
+
+ //
+ // Proceed with normal checking
+ //
+ if (!Data) {
+ //(EIP59738-)>
+ //
+ // Get the max LBA & block size; if block size is other than
+ // 512 bytes assume emulation as CDROM
+ //
+ //if ( dev->wBlockSize > 0x200 ) {
+ // wEmulationType = (UINT16)(USB_EMU_HDD_OR_FDD << 8) + USB_MASS_DEV_CDROM;
+ // goto UMIDT_DeviceTypeOver;
+ //}
+ //(<EIP59738-)
+ //(EIP80382)>
+ if (USBMassGetFormatType(DevInfo, DevInfo->MaxLba, &EmulationType) == USB_ERROR) {
+ //
+ // Find the device type by size
+ //
+ if (((Shr64(DevInfo->MaxLba, 11)) < MAX_SIZE_FOR_USB_FLOPPY_EMULATION) ||
+ (gUsbData->dUSBStateFlag & USB_FLAG_MASS_NATIVE_EMULATION)) {
+ if (DevInfo->bSubClass != SUB_CLASS_UFI) {
+ EmulationType = (USB_EMU_FORCED_FDD << 8) + USB_MASS_DEV_ARMD;
+ }
+ }
+ }
+ }
+ //<(EIP80382)
+ //<(EIP86793)
+
+UMIDT_DeviceTypeOver:
+
+ if (ForceEmulationType) {
+ EmulationType = ForceEmulationType;
+ }
+ DevInfo->bStorageType = (UINT8)EmulationType;
+ DevInfo->bEmuType = (UINT8)(EmulationType >> 8);
+
+ USB_DEBUG(DEBUG_LEVEL_3, "<<-- IdentifyDeviceType:: Emul: %x\n", EmulationType);
+
+ return;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetPhysicalDeviceType
+//
+// Description: This procedure classify USB mass storage devices according to
+// inquiry command return data.
+//
+// Input: Pointer to DeviceInfo structure
+// Pointer to the inquiry data (read from device)
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassGetPhysicalDeviceType(
+ DEV_INFO* Dev,
+ UINT8 *Buf
+)
+{
+
+ switch (*Buf) {
+ case 0x0:
+ if (Dev->bSubClass == SUB_CLASS_UFI) {
+ Dev->bPhyDevType = USB_MASS_DEV_FDD;
+ break;
+ }
+ Dev->bPhyDevType = (*(Buf+1) & 0x80) ?
+ USB_MASS_DEV_ARMD : USB_MASS_DEV_HDD;
+ break;
+ case 0x5:
+ Dev->bPhyDevType = USB_MASS_DEV_CDROM;
+ break;
+ case 0x7:
+ Dev->bPhyDevType = USB_MASS_DEV_MO;
+ break;
+ case 0xE:
+ Dev->bPhyDevType = USB_MASS_DEV_ARMD;
+ break;
+ default:
+ Dev->bPhyDevType = USB_MASS_DEV_UNKNOWN;
+ break;
+ }
+
+}
+
+/* //(EIP59738-)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassConsumeBulkData
+//
+// DESCRIPTION: This function reads unwanted amount of data specified in
+// the size
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+// bXferDir Transfer direction
+// wLength Size of data to consume
+//
+// RETURN: USB_ERROR or USB_SUCCESS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassConsumeBulkData(
+ DEV_INFO* fpDevInfo,
+ UINT8 bXferDir,
+ UINT16 wLength)
+{
+ UINT16 wBytesToTransfer, wBytesRemaining;
+ UINT32 dData;
+
+//
+// Need to process only maximum amount of data that pUSBMassConsumeBuffer can
+// handle, i.e. MAX_CONTROL_DATA_SIZE
+//
+ wBytesRemaining = wLength;
+ do {
+ wBytesToTransfer = (UINT16)((wBytesRemaining < MAX_CONTROL_DATA_SIZE)?
+ wBytesRemaining : MAX_CONTROL_DATA_SIZE);
+
+ dData = USBMassIssueBulkTransfer(fpDevInfo, bXferDir,
+ gUsbData->fpUSBMassConsumeBuffer, (UINT32)wBytesToTransfer);
+
+ if ((UINT16)dData != wBytesToTransfer) { // Comparing word should be sufficient
+ return USB_ERROR;
+ }
+ wBytesRemaining = (UINT16)(wBytesRemaining - dData);
+
+ } while (wBytesRemaining);
+
+ return USB_SUCCESS;
+}
+*/ //<(EIP59738-)
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassProcessBulkData
+//
+// DESCRIPTION: This function reads/writes the data to the mass storage
+// device using bulk transfer. It also takes care of pre and
+// post skip bytes.
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+// stMassXactStruc (given for reference)
+// bXferDir Transfer direction
+// fpBuffer Data buffer far pointer
+// dLength Amount of data to be transferred
+// wPreSkip Number of bytes to skip before data
+// wPostSkip Number of bytes to skip after data
+//
+// RETURN: Amount of data actually transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP70814)>
+UINT32
+USBMassProcessBulkData(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+
+{
+ UINT32 dData;
+ UINT16 wTemp;
+ UINT8 *Buffer;
+ UINT8 *SrcBuffer;
+ UINT8 *DestBuffer;
+ UINT16 PreSkip;
+ UINT32 XferSize;
+ UINT32 XferedSize;
+ UINT32 RemainingSize;
+
+//USB_DEBUG (DEBUG_LEVEL_3, "Pre,%x;Post,%x\n", MassXactStruc->wPreSkip,
+// MassXactStruc->wPostSkip);
+ //
+ // Check whether something we have to transfer
+ //
+ if (!MassXactStruc->dLength) {
+ return 0;
+ }
+
+
+ wTemp = gUsbData->wTimeOutValue; // Save original value
+ if (gUsbData->wBulkDataXferDelay) { // Check the bulk data delay specified
+ gUsbData->wTimeOutValue = gUsbData->wBulkDataXferDelay;
+ }
+
+ if ((MassXactStruc->wPreSkip == 0) &&
+ (MassXactStruc->wPostSkip == 0)) {
+
+ dData = USBMassIssueBulkTransfer(
+ DevInfo,
+ MassXactStruc->bXferDir,
+ MassXactStruc->fpBuffer,
+ MassXactStruc->dLength);
+ } else {
+ // Allocate a data buffer
+ Buffer = USB_MemAlloc((UINT16)GET_MEM_BLK_COUNT(DevInfo->wBlockSize));
+ PreSkip = MassXactStruc->wPreSkip;
+ RemainingSize = MassXactStruc->dLength -
+ (PreSkip + MassXactStruc->wPostSkip);
+ DestBuffer = MassXactStruc->fpBuffer;
+
+ for (XferedSize = 0; XferedSize < MassXactStruc->dLength;) {
+ XferSize = MassXactStruc->dLength >= DevInfo->wBlockSize ?
+ DevInfo->wBlockSize : MassXactStruc->dLength;
+
+ dData = USBMassIssueBulkTransfer(
+ DevInfo,
+ MassXactStruc->bXferDir,
+ Buffer,
+ XferSize);
+ if (dData == 0) {
+ //(EIP83295)>
+ //return 0;
+ XferedSize = 0;
+ break;
+ //<(EIP83295)
+ }
+
+ XferedSize += XferSize;
+ if (RemainingSize == 0) {
+ continue;
+ }
+
+ SrcBuffer = Buffer;
+
+ if (PreSkip != 0) {
+ if (PreSkip >= XferSize) {
+ PreSkip -= XferSize;
+ continue;
+ }
+
+ SrcBuffer += PreSkip;
+ XferSize -= (UINT32)PreSkip;
+ PreSkip = 0;
+ }
+
+ XferSize = RemainingSize < XferSize ? RemainingSize : XferSize;
+ MemCopy(SrcBuffer, DestBuffer, XferSize);
+
+ // Update the destination buffer pointer
+ DestBuffer += XferSize;
+ RemainingSize -= XferSize;
+ }
+
+ USB_MemFree(Buffer, (UINT16)GET_MEM_BLK_COUNT(DevInfo->wBlockSize));
+
+ dData = XferedSize;
+ }
+
+ gUsbData->wTimeOutValue = wTemp; // Restore original timeout value
+ gUsbData->wBulkDataXferDelay = 0;
+
+ return dData;
+}
+ //<(EIP70814)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassInquiryCommand
+//
+// DESCRIPTION: This function sends inquiry command to the USB mass storage
+// device
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+//
+// RETURN: Pointer to the inquiry data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+MASS_INQUIRY*
+USBMassInquiryCommand (DEV_INFO* fpDevInfo)
+{
+ COMMON_INQ_CMD *fpCmdBuffer;
+ UINT32 dData;
+ MASS_XACT_STRUC MassXactStruc;
+
+ //
+ // Allocate memory for the command buffer
+ //
+ fpCmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMMON_INQ_CMD));
+ if(!fpCmdBuffer) {
+ return NULL;
+ }
+
+ fpCmdBuffer->bOpCode = COMMON_INQUIRY_OPCODE;
+ fpCmdBuffer->bAllocLength = 0x24;
+
+ //
+ // Clear the common bulk transaction structure
+ //
+ USBMassClearMassXactStruc(&MassXactStruc);
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)fpCmdBuffer;
+ //(EIP51158+)>
+ if (fpDevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x06; //SPC-4_246
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMMON_INQ_CMD);
+ }
+ //<(EIP51158+)
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = gUsbData->fpUSBTempBuffer + 0x40;
+ MassXactStruc.dLength = 0x24;
+
+USB_DEBUG (DEBUG_LEVEL_5, "Issue Inquiry Command .... \n");
+
+ dData = USBMassIssueMassTransaction(fpDevInfo, &MassXactStruc);
+
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMMON_INQ_CMD));
+
+
+ if (dData) {
+ return (MASS_INQUIRY*)(gUsbData->fpUSBTempBuffer + 0x40);
+ }
+ else {
+ return NULL;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassRWVCommand
+//
+// Description: This function reads/writes/verifies blocks of data from the
+// USB mass device specified by its device address
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+// bOpCode Read/Write/Verify
+// fpReadData Pointer to the read command structure
+// bDevAddr USB device address of the device
+// dStartLBA Starting LBA address
+// wNumBlks Number of blocks to process
+// wPreSkipSize Number of bytes to skip before
+// wPostSkipSize Number of bytes to skip after
+// fpBufferPtr Far buffer pointer
+//
+// Output: Return code (0 - Failure, <>0 - Size read)
+// fpReadData Pointer to the mass read command structure
+// dSenseData Sense data of the last command
+// fpBufferPtr Far buffer pointer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassRWVCommand(
+ DEV_INFO *DevInfo,
+ UINT8 OpCode,
+ VOID *DataStruc
+)
+{
+ MASS_READ *MassDataStruc = (MASS_READ*)DataStruc;
+ COMN_RWV_16_CMD *CmdBuffer;
+ UINT64 StartLba;
+ UINT32 BytesToRw;
+ UINT32 Data;
+ UINT32 SenseData;
+ UINT8 Dir; // BIT7 0/1 - R/W
+ UINT8 RetryNum;
+ UINT16 RetCode = 0;
+ UINT8 CmdSize;
+ MASS_XACT_STRUC MassXactStruc;
+
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)MassDataStruc->BufferPtr,
+ (UINT32)MassDataStruc->NumBlks * (UINT32)DevInfo->wBlockSize);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "UsbMassRWVCommand Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = TRUE;
+ }
+#endif
+
+ //
+ // Set the sense code as 0
+ //
+ MassDataStruc->SenseData = 0;
+
+ //
+ // Allocate memory for the command buffer
+ //
+ CmdBuffer = (COMN_RWV_16_CMD*)USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMN_RWV_16_CMD));
+ if (!CmdBuffer) {
+ return 0;
+ }
+
+ for (RetryNum = 0; RetryNum < 2; RetryNum++) {
+ //
+ // Load command into (just allocated) mass command buffer
+ //
+ CmdBuffer->OpCode = OpCode;
+ StartLba = MassDataStruc->StartLba;
+ //(EIP60588+)>
+ if (StartLba > (DevInfo->MaxLba - MassDataStruc->NumBlks)) {
+ StartLba = DevInfo->MaxLba - MassDataStruc->NumBlks;
+ }
+ //<(EIP60588+)
+ //
+ // If the "Forced FDD" option is selected that means the device has
+ // to be emulated as a floppy drive even though it has a HDD emulated
+ // image. This is accomplished by hiding the first cylinder totally.
+ // The partition table is in the first cylinder. LBA value for all
+ // the requests to the device will be offset with the number of sectors
+ // in the cylinder.
+ //
+
+ //
+ // Check for forced floppy emulated device and change LBA accordingly
+ //
+ if (DevInfo->bEmuType == USB_EMU_FORCED_FDD) {
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI)) //(EIP113379+)
+ //
+ // Skip first track in case of floppy emulation
+ //
+ StartLba += DevInfo->bHiddenSectors;
+ }
+
+ //
+ // Check the validity of the block size
+ //
+ if (DevInfo->wBlockSize != 0xFFFF) {
+ //
+ // Change big endian format (INTEL) to little endian format
+ //
+ if ((OpCode == COMMON_READ_10_OPCODE) ||
+ (OpCode == COMMON_WRITE_10_OPCODE) ||
+ (OpCode == COMMON_VERIFY_10_OPCODE)) {
+ ((COMN_RWV_10_CMD*)CmdBuffer)->dLba = dabc_to_abcd((UINT32)StartLba);
+ ((COMN_RWV_10_CMD*)CmdBuffer)->wTransferLength =
+ (UINT16)((MassDataStruc->NumBlks << 8) + (MassDataStruc->NumBlks >> 8));
+ if (DevInfo->bSubClass == SUB_CLASS_SCSI) {
+ CmdSize = 0x0A; //SBC-3_60
+ } else {
+ CmdSize = sizeof (COMN_RWV_10_CMD);
+ }
+ } else {
+ CmdBuffer->Lba = Shl64(dabc_to_abcd((UINT32)StartLba), 32);
+ CmdBuffer->Lba |= dabc_to_abcd((UINT32)Shr64(StartLba, 32));
+ CmdBuffer->TransferLength = dabc_to_abcd(MassDataStruc->NumBlks);
+ CmdSize = sizeof(COMN_RWV_16_CMD);
+ }
+ //
+ // Verify command does not need delay
+ //
+ gUsbData->wBulkDataXferDelay = 0;
+
+ //
+ // Calculate number of bytes to transfer (for verify command nothing
+ // to read/write.
+ //
+ BytesToRw = 0;
+ if ((OpCode != COMMON_VERIFY_10_OPCODE) &&
+ (OpCode != COMMON_VERIFY_16_OPCODE)){
+ //
+ // Read/write command may need long time delay
+ //
+ gUsbData->wBulkDataXferDelay = 20000;
+ BytesToRw = (UINT32)MassDataStruc->NumBlks * (UINT32)DevInfo->wBlockSize;
+ }
+
+ //
+ // Set the direction properly
+ //
+ if ((OpCode == COMMON_WRITE_10_OPCODE) ||
+ (OpCode == COMMON_WRITE_16_OPCODE)) {
+ Dir = 0;
+ } else {
+ Dir = BIT7;
+ }
+
+ //
+ // Fill the common bulk transaction structure
+ // Fill Command buffer address & size
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)CmdBuffer;
+ MassXactStruc.bCmdSize = CmdSize;
+ MassXactStruc.bXferDir = Dir;
+ MassXactStruc.fpBuffer = (UINT8*)(UINTN)MassDataStruc->BufferPtr;
+ MassXactStruc.wPreSkip = MassDataStruc->PreSkipSize;
+ MassXactStruc.wPostSkip = MassDataStruc->PostSkipSize;
+ MassXactStruc.dLength = BytesToRw;
+
+ Data = USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+
+ if ((Data) && ((RetryNum != 0) || (Data == BytesToRw))) { // Some data processed. Set return value
+
+ //
+ // Bug fix for installing Linux from USB CD-ROM.
+ // Linux64Bit Boot
+ // If data read is 64K or higher return 0FFFFh
+ //
+ if (Data >= 0x010000) {
+ Data = 0xFFFF;
+ }
+
+ RetCode = (UINT16)Data;
+ //
+ // Check for forced floppy emulated device
+ //
+ if ((DevInfo->bEmuType == USB_EMU_FORCED_FDD) &&
+ (OpCode == COMMON_READ_10_OPCODE) &&
+ (MassDataStruc->StartLba == 0) &&
+ !(gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) ) { //(EIP113379+)
+ //
+ // This is a floppy emulated ZIP drive, with read to
+ // first sector. Update the boot record so that floppy
+ // emulation is okay.
+ //
+ // Force #of hidden sectors to 0
+ //
+ *(UINT32*)((UINTN)MassDataStruc->BufferPtr + 0xB + 0x11) = 0;
+
+ //
+ // FreeDOS workaround
+ //
+ if ((*(UINT32*)((UINTN)MassDataStruc->BufferPtr + 3)==0x65657246) && // 'eerF'
+ (*(UINT32*)((UINTN)MassDataStruc->BufferPtr + 7)==0x20534F44) && // ' SOD'
+ (*(UINT32*)((UINTN)MassDataStruc->BufferPtr + 0x3A)!=0x20202032)) { //(EIP61388)
+ *(UINT16*)((UINTN)MassDataStruc->BufferPtr + 0x42) =
+ *(UINT16*)((UINTN)MassDataStruc->BufferPtr + 0x42)-(UINT16)DevInfo->bHiddenSectors;
+ *(UINT16*)((UINTN)MassDataStruc->BufferPtr + 0x46) =
+ *(UINT16*)((UINTN)MassDataStruc->BufferPtr + 0x46)-(UINT16)DevInfo->bHiddenSectors;
+ *(UINT16*)((UINTN)MassDataStruc->BufferPtr + 0x4A) =
+ *(UINT16*)((UINTN)MassDataStruc->BufferPtr + 0x4A)-(UINT16)DevInfo->bHiddenSectors;
+ }
+ //
+ // Force physical drive# to 0
+ // For FAT32, physical drive number is present in offset 40h
+ //
+ if ((*(UINT32*)((UINTN)MassDataStruc->BufferPtr + 0x52)) ==
+ 0x33544146) { // "3TAF", FAT3
+ *(UINT8*)((UINTN)MassDataStruc->BufferPtr + 0x40) = 0;
+ }
+ else {
+ *(UINT8*)((UINTN)MassDataStruc->BufferPtr + 0x24) = 0;
+ }
+ }
+ break; // dData ready
+
+ }
+ else { // Error condition: dData = 0, RetCode = 0
+ //
+ // Check for error
+ //
+ SenseData = USBMassRequestSense(DevInfo);
+ MassDataStruc->SenseData = SenseData;
+ Data = SenseData;
+
+ //
+ // Check for write protect error code
+ //
+ if ((UINT8)SenseData == 7) {
+ break;
+ }
+
+ if (((OpCode == COMMON_VERIFY_10_OPCODE) ||
+ (OpCode == COMMON_VERIFY_16_OPCODE)) && (!SenseData)) {
+ //
+ // This is verify command so no data to send or read and
+ // also sense data is 0. So set return value to success.
+ //
+ RetCode = 0xFFFF;
+ break;
+ }
+ }
+ } // fpDevInfo->wBlockSize != 0xFFFF
+
+ //
+ // UPRCC_ProceedIfRW
+ // May be drive error, try to correct it
+ // Check whether the drive is ready for read/write/verify command
+ //
+ Data = USBMassCheckDeviceReady(DevInfo);
+ MassDataStruc->SenseData = Data;
+
+ if (Data) {
+ break; // Return error
+ }
+
+ MemFill((UINT8*)CmdBuffer, sizeof(COMN_RWV_16_CMD), 0);
+ } // Fof loop
+
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_RWV_16_CMD));
+
+ return RetCode;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassStartUnitCommand
+//
+// DESCRIPTION: This function sends the start unit command to the mass device
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+//
+// RETURN: Sense data: 0 - Success, <>0 - Error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassStartUnitCommand (DEV_INFO* fpDevInfo)
+{
+ COMMON_START_STOP_UNIT_CMD *fpCmdBuffer;
+ MASS_XACT_STRUC MassXactStruc;
+// MASS_START_STOP_UNIT *fpStartData;
+
+ USB_DEBUG (DEBUG_LEVEL_5, "USBMProStartUnitCommand .... \n");
+
+ //
+ // Check the compatibility flag for start unit command not supported
+ //
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_START_UNIT_NOT_SUPPORTED) {
+ return USB_SUCCESS;
+ }
+
+ //
+ // Allocate memory for the command buffer
+ //
+ fpCmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMMON_START_STOP_UNIT_CMD));
+ if (!fpCmdBuffer) {
+ return USB_ERROR;
+ }
+
+ //
+ // Load command into (just allocated) mass command buffer
+ //
+ fpCmdBuffer->bOpCode = COMMON_START_STOP_UNIT_OPCODE;
+ fpCmdBuffer->bStart = 1;
+
+ //
+ // Clear the common bulk transaction structure
+ //
+ USBMassClearMassXactStruc(&MassXactStruc);
+ gUsbData->wBulkDataXferDelay = 10000; // Start unit command may need long time delay
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)fpCmdBuffer;
+ //(EIP51158+)>
+ if (fpDevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x06; //SBC-3_77
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMMON_START_STOP_UNIT_CMD);
+ }
+ //<(EIP51158+)
+ USBMassIssueMassTransaction(fpDevInfo, &MassXactStruc);
+
+ //
+ // No data to read/write. So do not process return code.
+ // Check and free command buffer
+ //
+ USB_MemFree(fpCmdBuffer,GET_MEM_BLK_COUNT_STRUC(COMMON_START_STOP_UNIT_CMD));
+
+ return USBMassRequestSense(fpDevInfo);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassModeSense
+//
+// DESCRIPTION: This function requests the mode sense data page number 5 from
+// the USB mass storage device
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+//
+// RETURN: USB_SUCCESS/USB_ERROR on Success/Failure
+// fpModeSenseData Pointer to the mode sense data
+// dSenseData Sense data
+// bNumHeads Number of heads
+// wNumCylinders Number of cylinders
+// bNumSectors Number of sectors
+// wBytesPerSector Number of bytes per sector
+// bMediaType Media type
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassModeSense(
+ DEV_INFO *fpDevInfo,
+ MASS_MODE_SENSE *fpModeSenseData)
+{
+ UINT32 dData;
+ UINT8 bRetCode;
+ COMN_MODE_SENSE_10CMD *fpCmdBuffer;
+ MODE_SENSE_10_HEADER *fpModeSense10_Header;
+ PAGE_CODE_5 *fpPageCode5;
+ MASS_XACT_STRUC MassXactStruc;
+
+ dData = 0;
+ bRetCode = USB_ERROR;
+
+ fpCmdBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMN_MODE_SENSE_10CMD));
+ if (!fpCmdBuffer) {
+ return USB_ERROR;
+ }
+
+ //
+ // Load command into (just allocated) mass command buffer
+ //
+ fpCmdBuffer->bOpCode = COMMON_MODE_SENSE_10_OPCODE;
+ fpCmdBuffer->wAllocLength = 0x2800; // Allocation Length = 40 bytes (0x28)
+ fpCmdBuffer->bPageCode = 5; // Page code
+
+ //
+ // Clear the common bulk transaction structure
+ //
+ USBMassClearMassXactStruc(&MassXactStruc);
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)fpCmdBuffer;
+ //(EIP51158+)>
+ if (fpDevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x0A; //SPC-4_280
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMN_MODE_SENSE_10CMD);
+ }
+ //<(EIP51158+)
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = gUsbData->fpUSBTempBuffer;
+ MassXactStruc.dLength = 0x28;
+
+ //
+ // Bulk in, with temp buffer & 40 bytes of data to read
+ //
+ dData = USBMassIssueMassTransaction(fpDevInfo, &MassXactStruc);
+
+ if (!dData) {
+ USBMassRequestSense( fpDevInfo );
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_MODE_SENSE_10CMD));
+ return USB_ERROR;
+ }
+
+ //
+ // Fill in the output data
+ //
+ fpModeSense10_Header = (MODE_SENSE_10_HEADER*)gUsbData->fpUSBTempBuffer;
+
+ //
+ // Process media type
+ //
+ fpModeSenseData->bMediaType = fpModeSense10_Header->bMediaType;
+
+ //
+ // Position to the correct page code starting location
+ //
+ fpPageCode5 = (PAGE_CODE_5*)((UINT8*)fpModeSense10_Header +
+ fpModeSense10_Header->wBlkDescSize +
+ sizeof (MODE_SENSE_10_HEADER));
+// USB_DEBUG (DEBUG_LEVEL_3, "USBMassModeSense .... fpPageCode5->bPageCode %x\n",fpPageCode5->bPageCode);
+
+ bRetCode = USB_ERROR;
+ if(fpPageCode5->bPageCode == 5) {
+ //
+ // Process number of bytes per sector (the block size)
+ //
+ fpModeSenseData->wBytesPerSector = (UINT16)((fpPageCode5->wBlockSize << 8)
+ + (fpPageCode5->wBlockSize >>8));
+ //
+ // Process number of heads and number of sectors/track
+ //
+ fpModeSenseData->bNumHeads = fpPageCode5->bHeads;
+ fpModeSenseData->bNumSectors = fpPageCode5->bSectors;
+
+ //
+ // Process number of cylinders
+ //
+ fpModeSenseData->wNumCylinders = (UINT16)((fpPageCode5->wCylinders << 8)
+ + (fpPageCode5->wCylinders >> 8));
+ bRetCode = USB_SUCCESS;
+ }
+
+ fpModeSenseData->dSenseData = USBMassRequestSense( fpDevInfo );
+
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_MODE_SENSE_10CMD));
+// USB_DEBUG (DEBUG_LEVEL_5, "USBMProModeSense .... wRetCode %x\n",wRetCode);
+
+ return bRetCode;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassRequestSense
+//
+// DESCRIPTION: This function sends request sense command and returns
+// the sense key information
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+//
+// RETURN: Sense data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBMassRequestSense(DEV_INFO* fpDevInfo)
+{
+ UINT32 dData;
+ UINT8 *fpDataBuffer;
+ COMMON_REQ_SENSE_CMD *fpCmdBuffer;
+ MASS_XACT_STRUC MassXactStruc;
+
+ //
+ // Allocate memory for the command buffer
+ //
+ fpCmdBuffer = (COMMON_REQ_SENSE_CMD*)USB_MemAlloc(GET_MEM_BLK_COUNT_STRUC(COMMON_REQ_SENSE_CMD));
+ if(!fpCmdBuffer) {
+ return USB_ERROR; // Error - return no sense data <>0
+ }
+
+ fpDataBuffer = USB_MemAlloc(GET_MEM_BLK_COUNT(1));
+ if(!fpDataBuffer) {
+ return USB_ERROR; // Error - return no sense data <>0
+ }
+
+ //
+ // Load command into (just allocated) mass command buffer
+ //
+ fpCmdBuffer->bOpCode = COMMON_REQUEST_SENSE_OPCODE;
+ fpCmdBuffer->bAllocLength = 0x12; // Length of transfer
+
+ USBMassClearMassXactStruc(&MassXactStruc); // Clear the common bulk transaction structure
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)fpCmdBuffer;
+ //(EIP51158+)>
+ if (fpDevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x06; //SPC-4_350
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMMON_REQ_SENSE_CMD);
+ }
+ //<(EIP51158+)
+ MassXactStruc.bXferDir = BIT7; // IN
+ MassXactStruc.fpBuffer = fpDataBuffer;
+ MassXactStruc.dLength = 0x12;
+
+ //
+ // Bulk in, with locally allocated temp buffer & 12h bytes of data to read
+ //
+ dData = USBMassIssueMassTransaction(fpDevInfo, &MassXactStruc);
+
+ if(dData) {
+ //
+ // Form the return value:
+ // Bit 0..7 - Sense key (offset 002d)
+ // Bit 8..15 - ASC code (offset 012d)
+ // Bit 16..23 - ASCQ code (offset 013d)
+ //
+ dData = (UINT32)(fpDataBuffer[2] +
+ (fpDataBuffer[12] << 8) +
+ (fpDataBuffer[13] << 16));
+ USBMassSenseKeyParsing(fpDevInfo, dData);
+ }
+ //(EIP20863+)>
+ else
+ dData = USB_ERROR;
+ //<(EIP20863+)
+
+ USB_MemFree(fpCmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMMON_REQ_SENSE_CMD));
+ USB_MemFree(fpDataBuffer, GET_MEM_BLK_COUNT(1));
+
+ return dData;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassSenseKeyParsing
+//
+// DESCRIPTION: Translate USB sense key to USB MassStorage status.
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+// dCode[23..16] ASCQ
+// dCode[15..08] ASC
+// dCode[07..00] Sense Code
+
+//
+// RETURN: Sense data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassSenseKeyParsing(DEV_INFO* fpDevInfo, UINT32 dCode)
+{
+ if ((UINT16)dCode == 0x3A02) { //(EIP86793)
+ fpDevInfo->bLastStatus &= ~USB_MASS_MEDIA_PRESENT;
+ }
+ if((UINT16)dCode == 0x2806) {
+ fpDevInfo->bLastStatus |= (USB_MASS_MEDIA_PRESENT | USB_MASS_MEDIA_CHANGED);
+ }
+ //(EIP86125+)>
+ if(dCode == 0) {
+ fpDevInfo->bLastStatus |= USB_MASS_MEDIA_PRESENT;
+ }
+ //<(EIP86125+)
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassTestUnitReady
+//
+// DESCRIPTION: This function sends test unit ready command
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+//
+// RETURN: Sense data
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBMassTestUnitReady(
+ DEV_INFO* DevInfo
+)
+{
+ COMN_TEST_UNIT_READY_CMD *CmdBuffer;
+ UINT32 Data;
+ MASS_XACT_STRUC MassXactStruc;
+
+ CmdBuffer = (COMN_TEST_UNIT_READY_CMD*)USB_MemAlloc(
+ GET_MEM_BLK_COUNT_STRUC(COMN_TEST_UNIT_READY_CMD));
+ if (!CmdBuffer) {
+ return USB_ERROR; // Error - return no sense data
+ }
+
+ CmdBuffer->bOpCode = COMMON_TEST_UNIT_READY_OPCODE;
+ USB_DEBUG (DEBUG_LEVEL_5, "USBMassTestUnitReady .... \n");
+
+ USBMassClearMassXactStruc(&MassXactStruc); // Clear the common bulk transaction structure
+
+ //
+ // Fill the common bulk transaction structure
+ //
+ MassXactStruc.fpCmdBuffer = (UINT8*)CmdBuffer;
+ //(EIP51158+)>
+ if (DevInfo->bSubClass == SUB_CLASS_SCSI) {
+ MassXactStruc.bCmdSize = 0x06; //SPC-4_368
+ } else {
+ MassXactStruc.bCmdSize = sizeof (COMN_TEST_UNIT_READY_CMD);
+ }
+ //<(EIP51158+)
+ Data = USBMassIssueMassTransaction(DevInfo, &MassXactStruc);
+
+ USB_MemFree(CmdBuffer, GET_MEM_BLK_COUNT_STRUC(COMN_TEST_UNIT_READY_CMD));
+
+ if ((Data == USB_ERROR) || (DevInfo->bProtocol == PROTOCOL_CBI) ||
+ (DevInfo->bProtocol == PROTOCOL_CBI_NO_INT)) {
+ Data = USBMassRequestSense(DevInfo);
+ }
+ return Data;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassCheckDeviceReady
+//
+// Description: This function makes sure the device is ready for next
+// command
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+//
+// Output: Sense code
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBMassCheckDeviceReady (DEV_INFO* fpDevInfo)
+{
+ UINT8 count, nomedia_count;
+ UINT8 NotReadyCount; //(EIP101623+)
+ UINT32 dData = 0;
+
+ count = gUsbData->bUSBStorageDeviceDelayCount;
+ nomedia_count = 3;
+ NotReadyCount = 3; //(EIP101623+)
+ while (count) {
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_TEST_UNIT_READY_FAILED) {
+ break; // consider device is ready
+ }
+
+ //
+ // Issue test unit ready command and check the return value
+ //
+ dData = USBMassTestUnitReady( fpDevInfo );
+//USB_DEBUG(DEBUG_LEVEL_3, "(%d)tur..%x ", fpDevInfo->bDeviceAddress, dData);
+ if ((UINT8)dData == 0) { // Device ready
+ break;
+ }
+ //
+ // Device is not ready.
+ // Check for getting ready/reset command occurence in dData:
+ // Bit 0..7 - Sense Code
+ // Bit 8..15 - Additional Sense Code (ASC)
+ // Bit 16..23 - Additional Sense Code Qualifier (ASCQ)
+ //
+ if ((UINT16)dData == 0x2806) {
+ //
+ // Send Start/Stop Unit command to UFI class device only
+ //
+ if (fpDevInfo->bSubClass == SUB_CLASS_UFI) {
+ USBMassStartUnitCommand (fpDevInfo);
+ }
+ FixedDelay(100 * 1000); // 100 msec delay
+ count--;
+ continue;
+ }
+ if ((UINT16)dData == 0x3A02) { // Media is not present
+ nomedia_count--;
+ if (nomedia_count == 0) return dData; // No media
+ FixedDelay(20 * 1000); // 20 msec delay
+ count--;
+ continue;
+ }
+
+ if (dData == 0x020402)
+ {
+ USBMassStartUnitCommand (fpDevInfo);
+ FixedDelay(100 * 1000);
+ count--;
+ continue;
+ }
+
+ if ((UINT16)dData == 0x1103) {
+ FixedDelay(100 * 1000);
+ count--;
+ continue;
+ }
+
+ //
+ // Check whether we can recover from this error condition
+ // Currently only recoverable error condition are
+ // 1. Device is getting ready (010402)
+ // 2. Device reset occurred (002906)
+ //
+ if (dData != 0x010402) {
+ //
+ // Check for write protected command
+ //
+ if ( (UINT8)dData == 7 ) {
+ break;
+ }
+ if (((UINT8)dData != 0x06) && ((UINT8)dData != 0x02)) {
+ return dData;
+ }
+ }
+
+ //(EIP101623+)>
+ if (dData == 0x02) {
+ NotReadyCount--;
+ if (NotReadyCount == 0) return dData;
+ FixedDelay(20 * 1000); // 20 msec delay
+ count--;
+ continue;
+ }
+ //<(EIP101623+)
+
+ //
+ // Prepare for the next itaration
+ // Delay for the device to get ready
+ //
+ FixedDelay(1000 * 1000); // 1 sec delay
+ count--;
+ } // while
+ //(EIP53416+)>
+ if (count == 0) {
+ return dData;
+ }
+ //<(EIP53416+)
+ return USBMassUpdateDeviceGeometry(fpDevInfo);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassUpdateParamUsingModeSense
+//
+// Description: This function obtains the device geometry from the device
+// using mode sense command and updates the global variables
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassUpdateParamUsingModeSense(DEV_INFO* fpDevInfo)
+{
+ MASS_MODE_SENSE ModeSenseData;
+
+ gUsbData->wModeSenseCylinders = gUsbData->bModeSenseHeads =
+ gUsbData->bModeSenseSectors = 0;
+ //
+ // Check the compatibility flag for mode sense support
+ //
+ if (fpDevInfo->wIncompatFlags & USB_INCMPT_MODE_SENSE_NOT_SUPPORTED) {
+ return USB_SUCCESS;
+ }
+
+ //
+ // CDROM devices never support mode sense page code 5 (Flexible disk page)
+ // so skip it
+ //
+ if (fpDevInfo->bStorageType == USB_MASS_DEV_CDROM) {
+ return USB_ERROR;
+ }
+
+ //
+ // Issue mode sense command
+ //
+ if (USBMassModeSense(fpDevInfo, &ModeSenseData)) {
+USB_DEBUG(DEBUG_LEVEL_3, "ms..err ");
+ return USB_ERROR;
+ }
+
+ //
+ // Mode sense is supported. Update the local structure.
+ //
+ gUsbData->wModeSenseCylinders = ModeSenseData.wNumCylinders; // Number of cylinders
+ gUsbData->bModeSenseHeads = ModeSenseData.bNumHeads; // Number of heads
+ gUsbData->bModeSenseSectors = ModeSenseData.bNumSectors; // Number of sectors
+ gUsbData->wModeSenseBlockSize = ModeSenseData.wBytesPerSector;// Number of bytes per sector
+ gUsbData->bDiskMediaType = ModeSenseData.bMediaType; // Media type
+
+
+USB_DEBUG(DEBUG_LEVEL_4, "ms..%x %x %x %x %x ",
+ gUsbData->wModeSenseCylinders,
+ gUsbData->bModeSenseHeads,
+ gUsbData->bModeSenseSectors,
+ gUsbData->wModeSenseBlockSize,
+ gUsbData->bDiskMediaType
+);
+
+ if (fpDevInfo->bStorageType == USB_MASS_DEV_HDD) {
+ gUsbData->bDiskMediaType = USB_UNKNOWN_MEDIA_TYPE;
+ }
+
+ //
+ // Calculate and update Max LBA
+ //
+ gUsbData->dModeSenseMaxLBA =
+ (UINT32)(ModeSenseData.wNumCylinders *
+ ModeSenseData.bNumHeads * ModeSenseData.bNumSectors);
+ //
+ // Set the flag indicating mode sense is executed
+ //
+ gUsbData->bGeometryCommandStatus |= MODE_SENSE_COMMAND_EXECUTED;
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassUpdateParamUsingReadCapacity
+//
+// Description: This function obtains the device geometry from the device
+// using read capacity command and updates the global variables
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: USB_ERROR On error
+// USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassUpdateParamUsingReadCapacity(
+ DEV_INFO* DevInfo
+)
+{
+ UINT8 Sectors;
+ UINT8 Heads;
+
+ //
+ // Either mode sense not supported or failed. Try read capacity
+ // Issue read capacity command
+ //
+ if (USBMassReadCapacity10Command(DevInfo)) {
+ return USB_ERROR;
+ }
+
+ //
+ // Set the flag indicating read capacity is executed
+ //
+ gUsbData->bGeometryCommandStatus |= READ_CAPACITY_COMMAND_EXECUTED;
+
+ //
+ // Max LBA & block size are updated in MassDeviceInfo structure
+ //
+ if (DevInfo->MaxLba < 0x4000) { // last LBA < 16MB
+ switch (DevInfo->MaxLba) {
+ case USB_144MB_FDD_MAX_LBA:
+ gUsbData->bReadCapHeads = USB_144MB_FDD_MAX_HEADS;
+ gUsbData->bReadCapSectors = USB_144MB_FDD_MAX_SECTORS;
+ gUsbData->wReadCapCylinders= USB_144MB_FDD_MAX_CYLINDERS;
+ gUsbData->bDiskMediaType = USB_144MB_FDD_MEDIA_TYPE;
+ return USB_SUCCESS;
+
+ case USB_720KB_FDD_MAX_LBA:
+ gUsbData->bReadCapHeads = USB_720KB_FDD_MAX_HEADS;
+ gUsbData->bReadCapSectors = USB_720KB_FDD_MAX_SECTORS;
+ gUsbData->wReadCapCylinders= USB_720KB_FDD_MAX_CYLINDERS;
+ gUsbData->bDiskMediaType = USB_720KB_FDD_MEDIA_TYPE;
+ return USB_SUCCESS;
+ }
+ }
+
+ //
+ // Convert to CHS
+ //
+ gUsbData->wReadCapBlockSize = DevInfo->wBlockSize;
+
+ //
+ // Do CHS conversion
+ // Use fixed sectors/track & heads for CHS conversion
+ //
+ if (DevInfo->MaxLba < 0x400) { // < 512 KB
+ Sectors = 1;
+ Heads = 1;
+ }
+ else {
+ if (DevInfo->MaxLba < 0x200000) { // < 1GB
+ Sectors = USB_FIXED_LBA_SPT_BELOW_1GB;
+ Heads = USB_FIXED_LBA_HPT_BELOW_1GB;
+ }
+ else { // > 1GB
+ Sectors = USB_FIXED_LBA_SPT_ABOVE_1GB;
+ Heads = USB_FIXED_LBA_HPT_ABOVE_1GB;
+ }
+ }
+
+ gUsbData->bReadCapSectors = Sectors;
+ gUsbData->bReadCapHeads = Heads;
+
+ //
+ // Calculate number of cylinders Cyl = LBA/(Head*Sec)
+ //
+ if ((Sectors != 0) && (Heads != 0)) {
+ gUsbData->wReadCapCylinders = (UINT16)Div64(DevInfo->MaxLba, (Sectors * Heads), NULL);
+ } else {
+ gUsbData->wReadCapCylinders = 0;
+ }
+
+ return USB_SUCCESS;
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassUpdateDeviceGeometry
+//
+// Description: This function updates the device geometry information
+//
+// Input: Pointer to device info structure
+//
+// Output: USB_SUCCESS or USB_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassUpdateDeviceGeometry (
+ DEV_INFO* DevInfo
+)
+{
+ UINT64 MaxLba;
+ UINT8 Heads;
+ UINT8 Sectors;
+ UINT16 Cylinders;
+ UINT8 Status;
+
+ //
+ // Try to update geometry if it is not valid
+ // "Valid" block size is 1...FFFE
+ // Additional check added to ensure the head, sector, and cylinder values are non-zero.
+ //
+ //(EIP13457+)>
+ if ((DevInfo->Heads != 0) &&
+ (DevInfo->bSectors != 0) &&
+ (DevInfo->wCylinders != 0) &&
+ !(DevInfo->bLastStatus & USB_MASS_MEDIA_CHANGED) &&
+ (!((DevInfo->bLastStatus & USB_MASS_GET_MEDIA_FORMAT) &&
+ (DevInfo->bSubClass == SUB_CLASS_UFI)))) {
+
+ DevInfo->bLastStatus &= ~USB_MASS_GET_MEDIA_FORMAT;
+
+ if (DevInfo->wBlockSize && (DevInfo->wBlockSize != 0xFFFF)) {
+ return USB_SUCCESS;
+ }
+ }
+
+ DevInfo->bLastStatus &= ~USB_MASS_GET_MEDIA_FORMAT;
+
+ //
+ // Set default values for the global variables
+ //
+ gUsbData->bDiskMediaType = USB_UNKNOWN_MEDIA_TYPE;
+ gUsbData->bGeometryCommandStatus &= ~(MODE_SENSE_COMMAND_EXECUTED |
+ READ_CAPACITY_COMMAND_EXECUTED);
+
+ //
+ // Get disk geometry using Mode Sense
+ //
+ if (DevInfo->bSubClass == SUB_CLASS_UFI) { //(EIP94060)
+ USBMassUpdateParamUsingModeSense(DevInfo);
+ }
+
+ //
+ // Get disk geometry using Read Capacity
+ //
+ Status = USBMassUpdateParamUsingReadCapacity(DevInfo);
+
+ //
+ // Parameters are obtained and stored in respective global variables;
+ // check whether any of the commands executed.
+ //
+ if (!(gUsbData->bGeometryCommandStatus & (READ_CAPACITY_COMMAND_EXECUTED |
+ MODE_SENSE_COMMAND_EXECUTED))) {
+ USB_DEBUG(DEBUG_LEVEL_3, "-error\n");
+ return USB_ERROR;
+ }
+
+ //
+ // Check whether read capacity is executed. If so, then max LBA & block size
+ // are already updated in the MassDeviceInfo structure. If not update it using
+ // mode sense parameters
+ //
+ if (!(gUsbData->bGeometryCommandStatus & READ_CAPACITY_COMMAND_EXECUTED)) {
+ //
+ // At this point we made sure atleast one of the command (Mode sense or Read
+ // Capacity) was executed. So if one command is not executed then other
+ // command is surely executed.
+ //
+
+ //
+ // Update the max LBA & block size using mode sense parameters
+ //
+ DevInfo->wBlockSize = gUsbData->wModeSenseBlockSize;
+ DevInfo->MaxLba = gUsbData->dModeSenseMaxLBA;
+ USB_DEBUG(DEBUG_LEVEL_4, "size %x lba %lx\n", DevInfo->wBlockSize, DevInfo->MaxLba);
+ }
+
+ //Some usb mass storages report media change even if they don't, we already
+ //update CHS from boot record and legacy boot doesn't support dynamic
+ //media insertion, we should not update it from read capacity parameters.
+
+ if ((DevInfo->Heads != 0) && (DevInfo->bSectors != 0) && (DevInfo->wCylinders !=0)) {
+ return USB_SUCCESS;
+ }
+
+ //
+ // Update the media type byte
+ //
+ DevInfo->bMediaType = gUsbData->bDiskMediaType;
+
+ //
+ // Check whether mode sense is executed. If so, then update CHS from mode
+ // sense value or else update from read capacity values.
+ //
+
+ //
+ // Update the CHS values using mode sense parameters
+ //
+ Heads = gUsbData->bModeSenseHeads;
+ Sectors = gUsbData->bModeSenseSectors;
+ Cylinders = gUsbData->wModeSenseCylinders;
+
+// if ((gUsbData->bGeometryCommandStatus & MODE_SENSE_COMMAND_EXECUTED) &&
+ if ((Heads * Sectors * Cylinders) == 0) {
+ //
+ // Update the CHS values using read capacity parameters
+ //
+ Heads = gUsbData->bReadCapHeads;
+ Sectors = gUsbData->bReadCapSectors;
+ Cylinders = gUsbData->wReadCapCylinders;
+ }
+
+ USB_DEBUG (DEBUG_LEVEL_4, "Cyl-%x, Hds-%x, Sec-%x", Cylinders, Heads, Sectors);
+
+ DevInfo->Heads = Heads;
+ DevInfo->bSectors = Sectors;
+ DevInfo->wCylinders = Cylinders;
+
+ //
+ // Calculate non-LBA CHS values from max LBA
+ //
+ MaxLba = DevInfo->MaxLba;
+
+ //
+ // Do not translate sectors for non HDD devices
+ //
+ if ((!DevInfo->bStorageType) || (DevInfo->bStorageType == USB_MASS_DEV_HDD)) {
+ //
+ // If Total number of sectors < 1032192(0FC000h) CHS translation is not
+ // needed
+ //
+ if (MaxLba >= 0xFC000) {
+ Sectors = 63;
+ Heads = 32;
+ //
+ // If Total number of sectors < 2064384(01F8000h) then use
+ // 63 Sec/track and 32 head for translation
+ //
+ if (MaxLba >= 0x01F8000) {
+ Heads = 64;
+ //
+ // If Total number of sectors < 4128768(03F0000h) then use
+ // 63 Sec/track and 64 head for translation
+ //
+ if (MaxLba >= 0x03F0000) {
+ Heads = 128;
+ //
+ // If Total number of sectors < 8257536(07E0000h) then use
+ // 63 Sec/track and 128 head for translation else use 255 heads
+ //
+ if (MaxLba >= 0x7E0000) {
+ Heads = 255;
+ MaxLba = DevInfo->MaxLba;
+ }
+ }
+ }
+ }
+
+ //
+ // In any case, check the parameters for maximum values allowed by BIOS and
+ // ATA specs (that is, 1024 cylinders, 16 heads and 63 sectors per track)
+ //
+ for (;;) {
+ //
+ // Calculate translated number of cylinders
+ //
+ if ((Sectors != 0) && (Heads != 0)) {
+ Cylinders = (UINT16)Div64(MaxLba, (Heads * Sectors), NULL);
+ } else {
+ Cylinders = 0;
+ }
+
+ //
+ // Check whether number of cylinders is less than or equal to 1024
+ //
+ if (Cylinders <= 1024) break;
+
+ //
+ // Cylinders are getting larger than usually supported try increasing
+ // head count keeping cylinders within safe limit
+ //
+ Cylinders = 1024;
+ if (Heads == 0xFF) {
+ break; // Heads limit reached
+ }
+ //
+ // Double number of heads
+ //
+ Heads <<= 1;
+ if (!Heads) {
+ Heads = 0xFF;
+ }
+ }
+ }
+
+ //
+ // Save the parameters
+ //
+ DevInfo->NonLBAHeads = Heads;
+ DevInfo->bNonLBASectors = Sectors;
+ DevInfo->wNonLBACylinders = Cylinders;
+
+ USB_DEBUG(DEBUG_LEVEL_5, "BPS %d H %d S %d C %d MT %d\n",
+ DevInfo->wBlockSize,
+ DevInfo->Heads,
+ DevInfo->bSectors,
+ DevInfo->wCylinders,
+ DevInfo->bMediaType);
+
+ return USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassIssueBOTTransaction
+//
+// Description: This function performs a mass storage transaction using bulk
+// only transport (BOT) protocol.
+//
+// Input: Pointer to DeviceInfo structure
+// stMassXactStruc
+// pCmdBuffer Pointer to command buffer
+// bCmdSize Size of command block
+// bXferDir Transfer direction
+// fpBuffer Data buffer far pointer
+// dwLength Amount of data to be transferred
+// wPreSkip Number of bytes to skip before data
+// wPostSkip Number of bytes to skip after data
+//
+// Output: Amount of data actually transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBMassIssueBOTTransaction(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+{
+ UINT32 Data;
+ UINT8 Status;
+
+ Data = USBMassSendBOTCommand(DevInfo, MassXactStruc); // Send the command control transfer
+
+ if (!Data) {
+ //
+ // Check for stall/timedout condition
+ //
+ if (gUsbData->bLastCommandStatus & (USB_BULK_STALLED + USB_BULK_TIMEDOUT)) {
+ //
+ // Perform USB BOT reset recovery
+ //
+ USBMassBOTResetRecovery(DevInfo);
+ return 0;
+ }
+ else {
+ return 0; // Unknown error exit
+ }
+ }
+
+ if (!MassXactStruc->dLength) { // No data
+ if (gUsbData->wBulkDataXferDelay) {
+ //
+ // Issue some delay
+ //
+ FixedDelay(100 * 1000);
+ gUsbData->wBulkDataXferDelay = 0;
+ }
+ //
+ // Get the status for the last transfer
+ //
+ Data = USBMassGetBOTStatus(DevInfo, MassXactStruc);
+ return Data;
+ }
+
+ //
+ // Tranfer the bulk data
+ //
+ Data = USBMassProcessBulkData(DevInfo, MassXactStruc); // Actual data size
+
+ //
+ // Check for stall/timeout condition
+ //
+ if (!(gUsbData->bLastCommandStatus & (USB_BULK_STALLED + USB_BULK_TIMEDOUT))) {
+ //
+ // Get the status for the last transfer
+ //
+ Status = USBMassGetBOTStatus(DevInfo, MassXactStruc);
+ if ((Status == USB_ERROR) || (gUsbData->bLastCommandStatus & USB_BULK_TIMEDOUT)) {
+ return 0;
+ } else {
+ return Data;
+ }
+ }
+
+ //
+ // Check for time out condition
+ //
+ if (gUsbData->bLastCommandStatus & USB_BULK_TIMEDOUT) {
+ //
+ // Perform USB BOT reset recovery
+ //
+ USBMassBOTResetRecovery(DevInfo);
+ return 0;
+ }
+
+ //
+ // Clear endpoint stall
+ //
+ USBMassClearBulkEndpointStall(DevInfo, MassXactStruc->bXferDir);
+
+ //
+ // Get the status for the last transfer
+ //
+ USBMassGetBOTStatus(DevInfo, MassXactStruc);
+
+ return Data;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBBOTSendCommand
+//
+// DESCRIPTION: This function performs a mass storage transaction using bulk
+// only transport (BOT) protocol.
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+// bXferDir Transfer direction
+// dwDataSize Amount of data to be transferred
+// fpCmdBuffer Pointer to the command buffer
+// bCmdSize Size of command block
+
+// RETURN: Amount of data actually transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassSendBOTCommand(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+{
+ UINT8 Count;
+ UINT8 *Src;
+ UINT8 *Dest;
+ BOT_CMD_BLK *BotCmdBlk;
+ UINT8 CmdSize;
+
+ BotCmdBlk = (BOT_CMD_BLK*)MassXactStruc->fpCmdBuffer;
+
+ CmdSize = MassXactStruc->bCmdSize;
+
+// if( !VALID_DEVINFO2( fpDevInfo) )
+// return 0;
+ //
+ // Make enough space for BOT command block wrapper
+ // Move backwards
+ //
+ Src = MassXactStruc->fpCmdBuffer + CmdSize - 1;
+
+ //
+ // BOT_COMMAND_BLOCK + end of command
+ //
+ Dest = Src + ((UINT8*)BotCmdBlk->aCBWCB - (UINT8*)BotCmdBlk);
+
+ for (Count = 0; Count < CmdSize; Count++) {
+ *Dest = *Src;
+ --Dest;
+ --Src;
+ }
+
+ //fpDest = gUsbData->stMassXactStruc.fpCmdBuffer;
+
+ //
+ // Clear the BOT command block
+ //
+ //for (bCount = 0; bCount < bCmdSize; bCount++) {
+ // *fpDest = 0x00;
+ // ++fpDest;
+ //}
+
+ BotCmdBlk->dCbwSignature = BOT_CBW_SIGNATURE;
+ BotCmdBlk->dCbwTag = ++(gUsbData->dBOTCommandTag);
+ BotCmdBlk->dCbwDataLength = MassXactStruc->dLength;
+ BotCmdBlk->bmCbwFlags = MassXactStruc->bXferDir;
+ BotCmdBlk->bCbwLun = DevInfo->bLUN;
+ BotCmdBlk->bCbwLength = CmdSize;
+
+ return (UINT16)USBMassIssueBulkTransfer(
+ DevInfo,
+ 0,
+ (UINT8*)BotCmdBlk,
+ sizeof (BOT_CMD_BLK));
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBBOTGetStatus
+//
+// Description: This function gets the BOT status sequence using
+// bulk IN transfer
+//
+// Input: fpDevInfo Pointer to DeviceInfo structure
+//
+// Output: Nothing
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassGetBOTStatus(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+{
+ //(EIP90503)>
+ UINT8* CmdBuffer;
+ UINT16 Data;
+
+ CmdBuffer = MassXactStruc->fpCmdBuffer;
+
+ Data = (UINT16)USBMassIssueBulkTransfer(DevInfo, BIT7,
+ CmdBuffer, sizeof (BOT_STATUS_BLOCK));
+ if ((Data != sizeof (BOT_STATUS_BLOCK))) {
+ if (gUsbData->bLastCommandStatus & USB_BULK_STALLED) {
+ USBMassClearBulkEndpointStall(DevInfo, BIT7);
+ }
+ Data = (UINT16)USBMassIssueBulkTransfer(DevInfo, BIT7,
+ CmdBuffer, sizeof (BOT_STATUS_BLOCK));
+ if (gUsbData->bLastCommandStatus & USB_BULK_STALLED) {
+ USBMassBOTResetRecovery(DevInfo);
+ return USB_ERROR;
+ }
+ }
+
+ //
+ // Check for valid CSW
+ //
+ if ((Data != sizeof (BOT_STATUS_BLOCK)) ||
+ (((BOT_STATUS_BLOCK*)CmdBuffer)->dCswSignature != BOT_CSW_SIGNATURE) ||
+ (((BOT_STATUS_BLOCK*)CmdBuffer)->dCswTag != gUsbData->dBOTCommandTag)) {
+ //USBMassClearBulkEndpointStall(fpDevInfo, BIT7); //(EIP63308-)
+ //USBMassClearBulkEndpointStall(fpDevInfo, BIT0); //(EIP63308-)
+ return USB_ERROR;
+ }
+ //<(EIP90503)
+ //
+ // Check for meaningful CSW
+ //
+ if (((BOT_STATUS_BLOCK*)CmdBuffer)->bmCswStatus) {
+ if (((BOT_STATUS_BLOCK*)CmdBuffer)->bmCswStatus > 1) {
+ //
+ // Perform reset recovery if BOT status is phase error
+ //
+ USBMassBOTResetRecovery(DevInfo);
+ }
+ return USB_ERROR;
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassBOTResetRecovery
+//
+// DESCRIPTION: This function performs the BOT reset recovery
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMassBOTResetRecovery(DEV_INFO* fpDevInfo)
+{
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [fpDevInfo->bHCNumber - 1]->bHCType)].pfnHCDControlTransfer)
+ (gUsbData->HcTable[fpDevInfo->bHCNumber - 1],
+ //(EIP20863)>
+ //fpDevInfo, ADSC_OUT_REQUEST_TYPE,
+ //(UINT16)fpDevInfo->bInterfaceNum,BOT_RESET_REQUEST_CODE, 0, 0);
+ fpDevInfo, ADSC_OUT_REQUEST_TYPE + (BOT_RESET_REQUEST_CODE << 8),
+ (UINT16)fpDevInfo->bInterfaceNum, 0, 0, 0);
+ //<(EIP20863)
+ USBMassClearBulkEndpointStall(fpDevInfo, BIT7);
+ USBMassClearBulkEndpointStall(fpDevInfo, BIT0);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassBOTGetMaxLUN
+//
+// Description: This function gets the maximum logical unit number(LUN)
+// supported by the device. It is zero based value.
+//
+// Input: Pointer to DeviceInfo structure
+//
+// Output: Max LUN supported
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassBOTGetMaxLUN(
+ DEV_INFO* DevInfo
+)
+{
+ UINT8 *Buffer = NULL;
+ UINT8 MaxLun = 0;
+ UINT16 Status;
+
+ if (DevInfo->wIncompatFlags & USB_INCMPT_GETMAXLUN_NOT_SUPPORTED) {
+ return 0;
+ }
+
+ Buffer = USB_MemAlloc(1);
+ ASSERT(Buffer);
+ if (Buffer == NULL) {
+ return 0;
+ }
+
+ Status = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [DevInfo->bHCNumber - 1]->bHCType)].pfnHCDControlTransfer)
+ (gUsbData->HcTable[DevInfo->bHCNumber - 1],
+ DevInfo, ADSC_IN_REQUEST_TYPE + (BOT_GET_MAX_LUN_REQUEST_CODE << 8),
+ DevInfo->bInterfaceNum, 0, Buffer, 1);
+ if (Status) {
+ MaxLun = *Buffer;
+ }
+ USB_MemFree(Buffer, 1);
+
+ return MaxLun;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassIssueCBITransaction
+//
+// DESCRIPTION: This function performs a mass storage transaction using CBI
+// or CB protocol.
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+// fpCmdBuffer Pointer to command buffer
+// bCmdSize Size of command block
+// bXferDir Transfer direction
+// fpBuffer Data buffer far pointer
+// dwLength Amount of data to be transferred
+// wPreSkip Number of bytes to skip before data
+// wPostSkip Number of bytes to skip after data
+//
+// RETURN: Amount of data actually transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBMassIssueCBITransaction(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+{
+ UINT32 Data = 0;
+
+ if (!(USBMassSendCBICommand(DevInfo, MassXactStruc))) { // Returns 0 on error
+ return 0;
+ }
+
+ if (MassXactStruc->dLength) {
+ Data = USBMassProcessBulkData(DevInfo, MassXactStruc);
+ if (!Data) {
+ if(gUsbData->bLastCommandStatus & USB_BULK_STALLED) {
+ USBMassClearBulkEndpointStall(DevInfo, MassXactStruc->bXferDir);
+ return Data;
+ }
+ }
+ }
+
+ if(DevInfo->bProtocol != PROTOCOL_CBI_NO_INT && DevInfo->IntInEndpoint != 0) {
+ //
+ // Bypass interrupt transaction if it is CB protocol
+ //
+ USBMassCBIGetStatus(DevInfo);
+ }
+
+ return Data;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// PROCEDURE: USBMassSendCBICommand
+//
+// DESCRIPTION: This function performs a mass storage transaction using CBI
+// or CB protocol.
+//
+// PARAMETERS: fpDevInfo Pointer to DeviceInfo structure
+// fpCmdBuffer Pointer to the command buffer
+// bCmdSize Size of command block
+//
+// RETURN: 0xFFFF SUCCESS
+// 0x00 ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassSendCBICommand(
+ DEV_INFO* DevInfo,
+ MASS_XACT_STRUC* MassXactStruc
+)
+{
+ UINT16 RetValue;
+
+ RetValue = (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [DevInfo->bHCNumber - 1]->bHCType)].pfnHCDControlTransfer)
+ (gUsbData->HcTable[DevInfo->bHCNumber - 1],
+ DevInfo, ADSC_OUT_REQUEST_TYPE,
+ (UINT16)DevInfo->bInterfaceNum, 0,
+ MassXactStruc->fpCmdBuffer,
+ (UINT16)MassXactStruc->bCmdSize);
+
+ return RetValue;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassCBIGetStatus
+//
+// Description: This function gets the status of the mass transaction
+// through an interrupt transfer
+//
+// Input: pDevInfo Pointer to DeviceInfo structure
+//
+// Output: Return value from the interrupt transfer
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+USBMassCBIGetStatus(DEV_INFO* fpDevInfo)
+{
+ (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [fpDevInfo->bHCNumber - 1]->bHCType)].pfnHCDInterruptTransfer)
+ (gUsbData->HcTable[fpDevInfo->bHCNumber - 1],
+ fpDevInfo, fpDevInfo->IntInEndpoint,
+ fpDevInfo->IntInMaxPkt, (UINT8*)&gUsbData->wInterruptStatus, 2);
+
+ return ((UINT16)gUsbData->wInterruptStatus);
+
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMiscIssueBulkTransfer
+//
+// Description: This function executes a bulk transaction on the USB. The
+// transfer may be either DATA_IN or DATA_OUT packets containing
+// data sent from the host to the device or vice-versa. This
+// function wil not return until the request either completes
+// successfully or completes with error (due to time out, etc.)
+// Size of data can be upto 64K
+//
+// Input: - DeviceInfo structure (if available else 0)
+// - Transfer direction
+// Bit 7 : Data direction
+// 0 Host sending data to device
+// 1 Device sending data to host
+// Bit 6-0 : Reserved
+// - Buffer containing data to be sent to the device or
+// buffer to be used to receive data. Value in
+// - Length request parameter, number of bytes of data
+// to be transferred in or out of the host controller
+//
+// Output: Amount of data transferred
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+USBMassIssueBulkTransfer(DEV_INFO* fpDevInfo, UINT8 bXferDir,
+ UINT8* fpCmdBuffer, UINT32 dSize)
+{
+ return (*gUsbData->aHCDriverTable[GET_HCD_INDEX(gUsbData->HcTable
+ [fpDevInfo->bHCNumber - 1]->bHCType)].pfnHCDBulkTransfer)
+ (gUsbData->HcTable[fpDevInfo->bHCNumber -1],
+ fpDevInfo, bXferDir,
+ fpCmdBuffer, dSize);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassGetDeviceGeometry
+//
+// Description: This function fills and returns the mass get device geometry
+// structure
+//
+// Input: fpMassGetDevGeo Pointer to mass get geometry struc
+//
+// Output: Return value
+// fpMassGetDevGeo Pointer to mass get geometry struc
+// dSenseData Sense data of the last command
+// bNumHeads Number of heads
+// wNumCylinders Number of cylinders
+// bNumSectors Number of sectors
+// wBytesPerSector Number of bytes per sector
+// bMediaType Media type
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassGetDeviceGeometry(
+ MASS_GET_DEV_GEO *GetDevGeometry
+ )
+{
+ DEV_INFO *DevInfo;
+ UINT8 DevAddr = GetDevGeometry->bDevAddr;
+ BOOLEAN ValidGeo;
+ MASS_GET_DEV_STATUS MassGetDevSts;
+
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+
+ if ((!DevInfo) || (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) { // Error
+ return USB_ERROR;
+ }
+
+ MassGetDevSts.bDevAddr = DevAddr;
+ //(EIP13457+)>
+ if (GetDevGeometry->bInt13FuncNum == 0x20){
+ DevInfo->bLastStatus |= USB_MASS_GET_MEDIA_FORMAT;
+ }
+ if ((!DevInfo->wBlockSize) || (DevInfo->wBlockSize == 0xFFFF) ||
+ (!(DevInfo->bLastStatus & USB_MASS_MEDIA_PRESENT) ||
+ (GetDevGeometry->bInt13FuncNum == 0x20)) ) {
+// USBMassCheckDeviceReady(fpDevInfo);
+ USBMassGetDeviceStatus(&MassGetDevSts);
+ } //<(EIP13457+)
+ ValidGeo = (BOOLEAN)((DevInfo->wBlockSize != 0xFFFF) && (DevInfo->wBlockSize != 0));
+ ValidGeo &= (DevInfo->bLastStatus & USB_MASS_MEDIA_PRESENT);
+ //(EIP107198+)>
+ GetDevGeometry->wBytesPerSector = ValidGeo? DevInfo->wBlockSize : 0;
+ GetDevGeometry->LBANumHeads = ValidGeo? DevInfo->Heads : 0;
+ GetDevGeometry->bLBANumSectors = ValidGeo? DevInfo->bSectors : 1;
+ GetDevGeometry->wLBANumCyls = ValidGeo? DevInfo->wCylinders : 0;
+ GetDevGeometry->NumHeads = ValidGeo? DevInfo->NonLBAHeads : 0;
+ GetDevGeometry->bNumSectors = ValidGeo? DevInfo->bNonLBASectors : 1;
+ GetDevGeometry->wNumCylinders = ValidGeo? DevInfo->wNonLBACylinders : 0;
+ GetDevGeometry->bMediaType = DevInfo->bMediaType;
+ GetDevGeometry->LastLBA = ValidGeo? DevInfo->MaxLba : 0;
+ GetDevGeometry->BpbMediaDesc = ValidGeo? DevInfo->BpbMediaDesc : 0;
+
+ //<(EIP107198+)
+
+ USB_DEBUG(DEBUG_LEVEL_4, "BPS %d H %d S %d C %d MT %d\n",
+ DevInfo->wBlockSize,
+ DevInfo->Heads,
+ DevInfo->bSectors,
+ DevInfo->wCylinders,
+ DevInfo->bMediaType);
+
+ return USB_SUCCESS;
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMassReadCapacity
+//
+// Description: This function issues read capacity command to the mass
+// device and returns the value obtained
+//
+// Input: fpReadCapacity Pointer to the read capacity structure
+// bDevAddr USB device address of the device
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMassReadCapacity(
+ MASS_READ_CAPACITY *ReadCapacity
+)
+{
+ DEV_INFO *DevInfo;
+ UINT8 DevAddr = ReadCapacity->bDevAddr;
+
+ DevInfo = USB_GetDeviceInfoStruc(USB_SRCH_DEV_INDX, 0, DevAddr, 0);
+
+ if ((!DevInfo) || (!(DevInfo->Flag & DEV_INFO_DEV_PRESENT))) { // Error
+ return USB_ERROR;
+ }
+
+ return USBMassReadCapacity10Command(DevInfo);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: dabc_to_abcd
+//
+// Description: This function swaps the bytes in dword: 0-3,1-2,2-1,3-0. Can be
+// used for example in little endian->big endian conversions.
+//
+// Input: DWORD to swap
+//
+// Output: Input value with the swapped bytes in it.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 dabc_to_abcd(UINT32 dData)
+{
+ return (((dData & 0x000000FF) << 24)
+ | ((dData & 0x0000FF00) << 8)
+ | ((dData & 0x00FF0000) >> 8)
+ | ((dData & 0xFF000000) >> 24));
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbms.c b/Core/EM/usb/rt/usbms.c
new file mode 100644
index 0000000..7c24dff
--- /dev/null
+++ b/Core/EM/usb/rt/usbms.c
@@ -0,0 +1,774 @@
+#pragma warning(disable: 4001)
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbms.c 50 10/16/16 10:12p Wilsonlee $
+//
+// $Revision: 50 $
+//
+// $Date: 10/16/16 10:12p $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbms.c $
+//
+// 50 10/16/16 10:12p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 49 4/29/15 5:29a Wilsonlee
+// [TAG] EIP215830
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CYBORG R.A.T3 Gaming Mouse left/right button has no
+// function, instead DPI UP/DOWN config button has left/right click
+// function.
+// [RootCause] We get mouuse button data from constant data offset.
+// [Solution] Mouse Data should be defining report fields that contain
+// modifiable device data.
+// [Files] usbms.c, usbhid.c, usbpoint.c
+//
+// 48 2/24/15 5:50a Wilsonlee
+// [TAG] EIP149716
+// [Category] Improvement
+// [Description] Error Handling in USB mouse data.
+// [Files] usbms.c, usbkbd.h, syskbc.c, xhci.c
+//
+// 47 12/24/14 9:33p Wilsonlee
+// [TAG] EIP194683
+// [Category] Improvement
+// [Description] Add the flag "USB_INCMPT_HID_BOOT_PROTOCOL_ONLY" of usb
+// bad device table to keep devices use boot protocol.
+// [Files] usbkbd.c, usbms.c, usbhid.c, usbdef.h
+//
+// 46 8/12/14 3:04a Wilsonlee
+// [TAG] EIP180970
+// [Category] Improvement
+// [Description] Update X and Y data to usbmousedata and install
+// SimplePointerProtocol interface if the mouses are using boot protocol
+// interface.
+// [Files] efiusbhid.c, usbms.c
+//
+// 45 5/06/14 5:16a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 44 2/26/14 1:55a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 43 12/30/13 3:47a Wilsonlee
+// [TAG] EIP148707
+// [Category] Improvement
+// [Description] We need to store wheel data before clearing the buffer.
+// [Files] usbms.c, efiusbms.c
+//
+// 42 8/22/13 6:33a Wilsonlee
+// [TAG] EIP122944
+// [Category] Improvement
+// [Description] Remove mouse_flag3 and check the mouse interface status
+// in the CCB byte before we send the data to KBC.
+// [Files] syskbc.c, usbms.c
+//
+// 41 7/04/13 5:46a Roberthsu
+// [TAG] EIP127014
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Mouse drifting not smooth
+// [RootCause] Bbecause Efi simple point protocol RelativeMovementX
+// type is INT32.
+// [Solution] Transfer data type to INT32.
+// [Files] usbdef.h,usbhid.c,usbms.c,usbkbd.h
+//
+// 40 1/11/13 4:15a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 39 11/10/12 6:39a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 38 8/21/12 2:33a Roberthsu
+// [TAG] EIP91835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Wireless mouse auto click" problem
+// [RootCause] Because button status and X Y in different packet.
+// [Solution] Save button status.
+// [Files] usbms.c
+//
+// 37 8/07/12 12:07a Roberthsu
+// [TAG] EIP95351
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Usb mouse work unnormal
+// [RootCause] This mouse will send garbage data.
+// [Solution] Change check section
+// [Files] usbms.c
+//
+// 36 5/03/12 6:30a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 35 9/27/11 1:40a Roberthsu
+// [TAG] EIP67400
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Microsoft wireless Media Desktop 1000 can¡¦t work normal.
+// [RootCause] Wireless ms report data contains usage page keyboard.And
+// output data not contains vaild report id.
+// [Solution] Check usage page led to decide kb or ms.Check correct
+// report id with report data.
+// [Files] usbkbd.c,usbhid.c,usbms.c
+//
+// 34 9/19/11 9:34a Lavanyap
+// [TAG] EIP66198
+// [Category] Improvement
+// [Description] Added Mouse Wheel support in PS2 and USB drivers.
+// [Files] usbdef.h, usbms.c, efiusbms.c, ps2mouse.h, mouse.c
+//
+// 33 8/05/11 2:03a Ryanchou
+//
+// 32 7/15/11 6:11a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c, usb.c, usbdef.h,
+// usbkbd.c, usbkbd.h, usbms.c, usbrt.cif, usbsb.c, usbsetup.c,
+// usbsrc.sdl, xhci.c
+//
+// 31 7/12/11 11:40p Ryanchou
+// [TAG] EIP63752
+// [Bug fix] Left click status lost on USB Mousee.
+// [Symptom] First time Getstate will return that Left Click is Pressed.
+// On the Second GetState Call it will return that Left click released.
+// [Root Cause] We are clearing the Button status once we send the data.
+// So next time getstate will return that left click is released.
+// [Solution] We should not clear the ButtonStatus.Insteed of OR the data,
+// we should have taken directly from the fpBuffer.
+//
+// 30 5/03/11 6:56a Ryanchou
+// [TAG] EIP57745
+// [Category] Improvement
+// [Description] The token CHECK_MOUSE_FLAG is depend on CSM version,
+// remove the token and check CSM verion to support this feature or not.
+// [Files] syskbc.c, usbms.c, usbsrc.sdl
+//
+// 29 3/30/11 8:16a Ryanchou
+// [TAG] EIP54126
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Sometimes system hangs at checkpoint 0xB4.
+// [RootCause] The bLength field of configuration descriptor is zero.
+// [Solution] Check wether bLength field is zero before paring next
+// descriptor.
+// [Files] usb.c, usbbus.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c
+//
+// 28 3/17/11 12:23a Ryanchou
+// [TAG] EIP49214
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB mouse can't work on legacy free system
+// [RootCause] The key repeat SMI didn't enabled.
+// [Solution] Enable the key repeat SMI if receive mouse data.
+// [Files] usbms.c
+//
+// 27 2/10/11 7:41a Ryanchou
+// [TAG] EIP52206
+// [Category] Improvement
+// [Description] Remote wakeup command should be sent before sleep,
+// comment out the command.
+// [Files] usbkbd.c, usbms.c
+//
+// 26 1/17/11 4:35a Ryanchou
+// [TAG] EIP51108
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Some HID devices that has two interfaces can't work.
+// [RootCause] BIOS using the wrong endpoint to poll KBD/MS data.
+// [Solution] Get the first interrupt in endpoint when parsing
+// descriptors.
+// [Files] usbkbd.c, usbms.c
+//
+// 25 9/24/10 5:38p Olegi
+// EIP38221: Added the code that properly initializes
+// DEV_INFO.bIntEndpoint field; interrupt endpoint polling is using this
+// endpoint number.
+//
+// 24 9/16/10 1:08p Olegi
+// - removed junk function code
+// - EIP40959:: activate mouse polling depending on the project settings
+//
+// 23 9/08/10 8:05a Ryanchou
+// EIP43822: Add a toekn "CHECK_MOUSE_FLAG", the token controls whether
+// apply EIP40121 solution.
+//
+// 22 8/30/10 12:16p Olegi
+// Send mouse data only when driver is active; EIP40121
+//
+// 21 6/22/10 9:11p Olegi
+// EIP39708: Added new incompatibility type for HIDs that ignore boot
+// protocol.
+//
+// 20 5/11/10 1:52p Olegi
+// Corrected the mouse data report. EIP37798
+//
+// 19 11/24/09 11:39a Olegi
+// EIP#29733 - BIOS adds an USB API (Block KBC Access)
+//
+// 18 9/10/09 3:58p Davidd
+// Corrected build error caused by previous change.
+//
+// 17 9/10/09 9:43a Olegi
+// EIP25224: When set boot protocol for mouse, the interface number may
+// not be 0. Some keyboard/mouse composite devices have one more
+// interface.
+//
+// 16 7/07/08 4:01p Olegi
+//
+// 15 5/16/08 12:06p Olegi
+//
+// 14 5/16/08 12:01p Olegi
+// Compliance with AMI coding standard.
+//
+// 13 12/17/07 4:04p Olegi
+// KBC emulation support added.
+//
+// 12 3/29/07 6:40p Olegi
+//
+// 11 3/20/07 12:20p Olegi
+//
+// 9 4/14/06 6:39p Olegi
+// Conversion to be able to use x64 compiler.
+//
+// 8 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 7 2/06/06 9:35a Andriyn
+//
+// 6 1/24/06 12:28p Andriyn
+//
+// 5 8/27/05 3:44p Andriyn
+// Fix: lost mouse click when mouse is not moving
+//
+// 4 8/26/05 12:25p Andriyn
+// Simulate Mouse Sampling rate by disabling Mouse Polling (reduce USB
+// SMI# generation)
+//
+// 3 8/25/05 7:19p Andriyn
+// USB Keyboard and mouse to use EMUL 60/64 for passing data to KBC.
+// Fall-back when EMUL 60/64 is not present
+//
+// 2 8/04/05 5:03p Andriyn
+// cosmetic changes
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 2 3/18/05 9:41a Olegi
+// Correction in Y coordinate calculations.
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbMs.c
+//
+// Description: AMI USB mouse support implementation
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+extern UINT8 IsKbcAccessBlocked; //(EIP29733+)
+
+extern EFI_EMUL6064MSINPUT_PROTOCOL* gMsInput;
+
+VOID USBMSInitialize (VOID);
+DEV_INFO* USBMSConfigureDevice (HC_STRUC*, DEV_INFO*, UINT8*, UINT16, UINT16);
+UINT8 USBMSProcessMouseData (HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+VOID USBKeyRepeat(HC_STRUC*, UINT8);
+VOID SetMouseData (UINT8*, USBMS_DATA*, UINT8, UINT8, HID_REPORT_FIELD*); //(EIP127014+)
+EFI_STATUS SendMouseData(PS2MouseData*);
+UINT8 OrgButtonStatus = 0; //(EIP91835)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBMSInitialize
+//
+// Description: This routine is called once to initialize the USB mouse data
+// area
+//
+// Input: None
+//
+// Output: Nothing
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBMSInitialize()
+{
+ //
+ // Initialize the mouse input buffer head and tail values
+ //
+ gUsbData->fpMouseInputBufferHeadPtr = &gUsbData->aMouseInputBuffer[0];
+ gUsbData->fpMouseInputBufferTailPtr = &gUsbData->aMouseInputBuffer[0];
+ USB_DEBUG(DEBUG_LEVEL_3, "USBMSInitialize: Head and Tail are at %x\n", gUsbData->fpMouseInputBufferHeadPtr);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBMSConfigureDevice
+//
+// Description: This routine checks an interface descriptor of the USB device
+// detected to see if it describes a HID/Boot/Mouse device.
+// If the device matches the above criteria, then the device is
+// configured and initialized
+//
+// Input: HcStruc HCStruc pointer
+// DevInfo Device information structure pointer
+// Desc Pointer to the descriptor structure
+// Start Offset within interface descriptor
+// supported by the device
+// End End offset of the device descriptor
+//
+// Output: FPDEV_INFO New device info structure, 0 on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBMSConfigureDevice (
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Desc,
+ UINT16 Start,
+ UINT16 End)
+{
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBMSProcessMouseData
+//
+// Description: This function is called at regular intervals with USB mouse
+// report data. This function handles the translation of USB
+// mouse data into PS/2 mouse data, and makes the PS/2 data
+// available to software using ports 60/64 to communicate with
+// a PS/2 mouse.
+//
+// Input: HcStruc Pointer to HCStruc
+// DevInfo Pointer to device information structure
+// Td Pointer to the polling TD
+// Buffer Pointer to the data buffer
+//
+// Output: Nothing
+//
+// Notes: The format of 3 byte data packet is as follow:
+// Byte Description
+// -----------------------------------------------------------
+// 0 Bit Description
+// -------------------------------------------
+// 0 If set, button 1 is pressed
+// 1 If set, button 2 is pressed
+// 2 If set, button 3 is pressed
+// 3-7 Reserved
+// -------------------------------------------
+// 1 X displacement value
+// 2 Y displacement value
+// -----------------------------------------------------------
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBMSProcessMouseData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ UINT8* MachineConfigPtr = (UINT8*)(UINTN)0x410;
+ PS2MouseData MouseData;
+ USBMS_DATA TempData;
+ INT32 Coordinates;
+ HID_REPORT_FIELD *Field = NULL;
+ UINT8 OffsetTmp = 0;
+ UINT8 XStart;
+ UINT8 XEnd;
+ UINT8 YStart;
+ UINT8 YEnd;
+ UINT8 ButtonStart;
+ UINT8 WheelStart;
+ UINT8 i;
+ UINT16 j;
+ UINT8 ButtonSet = 0;
+ UINT8 XSet = 0;
+ UINT8 YSet = 0;
+ UINT8 WheelSet = 0;
+
+ //Is KBC access allowed?
+ if (IsKbcAccessBlocked) {
+ return USB_SUCCESS; //(EIP29733+)
+ }
+
+ MemSet(&TempData, sizeof(USBMS_DATA), 0); //(EIP127014)
+
+ if (DevInfo->HidReport.Flag & HID_REPORT_FLAG_REPORT_PROTOCOL) {
+ //serach button and X Y
+ for (i = 0; i < DevInfo->HidReport.FieldCount; i++) {
+ Field = DevInfo->HidReport.Fields[i];
+
+ //Check if it is input?
+ if (!(Field->Flag & HID_REPORT_FIELD_FLAG_INPUT)) {
+ continue;
+ }
+ //if report id is exist, check first byte
+ if (Field->ReportId != 0 && Field->ReportId != Buffer[0]) {
+ continue;
+ }
+
+ // Check if the field is contant.
+ if (Field->Flag & HID_REPORT_FIELD_FLAG_CONSTANT) {
+ OffsetTmp += Field->ReportCount * Field->ReportSize;
+ continue;
+ }
+
+ //Check Button
+ if ((Field->UsagePage == 9) && (Field->UsageCount != 0) && (Field->Usages[0] == 1)) {
+ ButtonSet = 1;
+ ButtonStart = OffsetTmp;
+ if (Field->ReportId != 0) {
+ ButtonStart += 8;
+ }
+ ButtonStart /= 8;
+ TempData.ButtonByte = *(Buffer + ButtonStart);
+ }
+ //Check X,Y
+ if ((Field->UsagePage == 1) && (Field->UsageCount != 0)) {
+ for (j = 0; j < Field->UsageCount; j++) {
+ //find X
+ if (Field->Usages[j] == 0x30) {
+ XSet = 1;
+ XStart = (OffsetTmp + j * Field->ReportSize);
+ if (Field->ReportId != 0) {
+ XStart += 8;
+ }
+ XEnd = XStart + Field->ReportSize;
+ TempData.FillUsage = 0x30; //(EIP127014)
+ SetMouseData(Buffer, &TempData, XStart, XEnd, Field);
+ }
+ //find Y
+ if (Field->Usages[j] == 0x31) {
+ YSet = 1;
+ YStart = (OffsetTmp + j * Field->ReportSize);
+ if (Field->ReportId != 0) {
+ YStart += 8;
+ }
+ YEnd = YStart + Field->ReportSize;
+ TempData.FillUsage = 0x31;
+ SetMouseData(Buffer, &TempData, YStart, YEnd, Field);
+ }
+ //find Wheel
+ if (Field->Usages[j] == 0x38) {
+ WheelSet = 1;
+ WheelStart = (OffsetTmp + j * Field->ReportSize) / 8;
+ if (Field->ReportId != 0) {
+ WheelStart += 1;
+ }
+ TempData.Z = *(Buffer + WheelStart);
+ }
+ }
+ }
+ OffsetTmp += Field->ReportCount * Field->ReportSize;
+ }
+
+ for (i = 0; i < 8; i++) {
+ Buffer[i] = 0;
+ }
+
+ //fill MS DATA
+ if (ButtonSet != 0) {
+ *Buffer = TempData.ButtonByte;
+ OrgButtonStatus = TempData.ButtonByte;
+ } else {
+ *Buffer = OrgButtonStatus;
+ }
+
+ if (XSet == 1) {
+ *(Buffer + 1) = TempData.X;
+ }
+ if (YSet == 1) {
+ *(Buffer + 2) = TempData.Y;
+ }
+ if (WheelSet == 1) {
+ *(Buffer + 3) = TempData.Z;
+ }
+ } else {
+ TempData.EfiX = *((INT8*)Buffer + 1);
+ TempData.EfiY = *((INT8*)Buffer + 2);
+ }
+
+ if (DevInfo->wIncompatFlags & USB_INCMPT_BOOT_PROTOCOL_IGNORED) {
+ Buffer++;
+ }
+
+ if ((BOOT_PROTOCOL_SUPPORT == 0) &&
+ !(DevInfo->wIncompatFlags & USB_INCMPT_HID_BOOT_PROTOCOL_ONLY)) {
+ if (!(ButtonSet || XSet || YSet || WheelSet)) {
+ return USB_SUCCESS;
+ }
+ }
+
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+
+ gUsbData->MouseData.ButtonStatus = *(UINT8*)Buffer;
+
+ Coordinates = (INT16)TempData.EfiX; //(EIP127014)
+ gUsbData->MouseData.MouseX += Coordinates;
+
+ Coordinates = (INT16)TempData.EfiY; //(EIP127014)
+ gUsbData->MouseData.MouseY += Coordinates;
+
+ Coordinates= *((INT8*)Buffer + 3);
+ gUsbData->MouseData.MouseZ += Coordinates;
+
+ return USB_SUCCESS; // Here should be code that prepares buffer for AMIUHCD
+ }
+
+ if (!(*MachineConfigPtr & BIT2)) {
+ return USB_SUCCESS; // No mouse indication in BIOS Data area equipment byte
+ }
+/*
+ //(EIP57745+)>
+ //
+ // Check the version of CSM16, support is available for ver 7.64 or later
+ //
+ {
+ UINT8 MjCsmVer = *(UINT8*)0xF0018;
+ UINT8 MnCsmVer = *(UINT8*)0xF0019;
+ UINT8 mouse_flag3 = *((UINT8*)((UINTN)((*(UINT16*)0x40E) << 4) + 0x30));
+
+ if (MjCsmVer > 7 || MnCsmVer > 0x63) {
+ if(!(mouse_flag3 & BIT0)) {
+ return USB_SUCCESS;
+ }
+ }
+ }
+ //<(EIP57745+)
+*/
+ //
+ // Check mouse data availability
+ //
+ if (gMsInput != 0) {
+ //
+ // Get mouse status byte and prepare it.
+ // Bit 2, 1, 0 = Middle, right and left button status
+ // Bit 3 is always 1
+ //
+ MouseData.flags = (*(UINT8*)Buffer) & 7 | 8;
+
+ //
+ // Get mouse X, Y position
+ //
+ MouseData.x = (*((UINT8*)Buffer + 1));
+ MouseData.y = (UINT8)(-*((INT8*)Buffer + 2)); // Y data is opposite in USB than PS2
+
+ //
+ // Verify the direction of X-axis movement
+ //
+ if (MouseData.x >= 0x80) {
+ MouseData.flags |= 0x10; // Negative X-axis movement
+ }
+ if (MouseData.y >= 0x80) {
+ MouseData.flags |= 0x20; // Negative Y-axis movement
+ }
+
+ if (gUsbData->kbc_support || (gUsbData->dUSBStateFlag & USB_FLAG_6064EMULATION_ON)) {
+ SendMouseData(&MouseData);
+ USBKeyRepeat(NULL, 2); // Enable Key repeat //(EIP49214+)
+ }
+ }
+
+ return USB_SUCCESS;
+}
+ //(EIP127014+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetMouseData
+//
+// Description: This routine checks for mouse type device from the
+// interface data provided
+//
+// Input: bBaseClass USB base class code
+// bSubClass USB sub-class code
+// bProtocol USB protocol code
+//
+// Output: BIOS_DEV_TYPE_MOUSE type on success or 0FFH on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetMouseData (
+ UINT8 *Buffer,
+ USBMS_DATA *MsData,
+ UINT8 Start,
+ UINT8 End,
+ HID_REPORT_FIELD *Field
+)
+{
+ UINT8 ReportSize;
+ UINT8 Size;
+ UINT8 PreSkip;
+ UINT8 PostSkip;
+ UINT16 TempData = 0;
+ UINT16 MinMask = 0;
+ UINT16 Multi = 1;
+ UINT16 Resolution;
+ UINT16 Count = 0;
+ UINT16 i;
+
+ if ((Field->PhysicalMax == 0) && (Field->PhysicalMin == 0)) {
+ Field->PhysicalMax = Field->LogicalMax;
+ Field->PhysicalMin = Field->LogicalMin;
+ }
+ if (Field->UnitExponent != 0) {
+ Count = (~Field->UnitExponent) + 1;
+ }
+
+ for (i = 0; i < Count; i++){
+ Multi = Multi * 10;
+ }
+
+ Resolution = ((INT16)Field->LogicalMax - (INT16)Field->LogicalMin) * Multi /
+ ((INT16)Field->PhysicalMax - (INT16)Field->PhysicalMin);
+
+ ReportSize = End - Start;
+ MinMask = ((~MinMask) >> ReportSize) << ReportSize;
+
+ Size = ReportSize / 8;
+
+ if ((ReportSize % 8) != 0) {
+ Size++;
+ }
+
+ ASSERT(Size > 0 && Size <= sizeof(TempData));
+ if ((Size == 0) || (Size > sizeof(TempData))) {
+ return;
+ }
+
+ MemCpy(&TempData, Buffer + Start / 8, Size);
+
+ PreSkip = Start % 8;
+ PostSkip = End % 8;
+
+ if (PreSkip != 0) {
+ TempData = TempData >> PreSkip;
+ }
+ if (PostSkip != 0) {
+ TempData = TempData << PostSkip;
+ TempData = TempData >> PostSkip;
+ }
+
+ if (TempData > Field->LogicalMax) {
+ TempData |= MinMask;
+ }
+
+ if (MsData->FillUsage == 0x30) {
+ MsData->EfiX = TempData;
+ MsData->X = (UINT8)TempData;
+ }
+ if (MsData->FillUsage == 0x31) {
+ MsData->EfiY = TempData;
+ MsData->Y = (UINT8)TempData;
+ }
+
+ return;
+}
+ //<(EIP127014+)
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbpoint.c b/Core/EM/usb/rt/usbpoint.c
new file mode 100644
index 0000000..96b95b6
--- /dev/null
+++ b/Core/EM/usb/rt/usbpoint.c
@@ -0,0 +1,474 @@
+#pragma warning(disable: 4001)
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbpoint.c 17 4/29/15 5:29a Wilsonlee $
+//
+// $Revision: 17 $
+//
+// $Date: 4/29/15 5:29a $
+//****************************************************************************
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/RT/usbpoint.c $
+//
+// 17 4/29/15 5:29a Wilsonlee
+// [TAG] EIP215830
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] CYBORG R.A.T3 Gaming Mouse left/right button has no
+// function, instead DPI UP/DOWN config button has left/right click
+// function.
+// [RootCause] We get mouuse button data from constant data offset.
+// [Solution] Mouse Data should be defining report fields that contain
+// modifiable device data.
+// [Files] usbms.c, usbhid.c, usbpoint.c
+//
+// 16 4/14/15 11:46p Wilsonlee
+// [TAG] EIP213778
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Issue with right button on usb absolute mouses.
+// [RootCause] For the absolute device, it has digitizers page
+// (UsagePage is 0xD) or button page (UsagePage is 0x9). We clear button
+// data even if it is from button page.
+// [Solution] Clear the unnecessary bits if the data is from digitizers
+// page and return all button data if it is from button page.
+// [Files] usbpoint.c
+//
+// 15 9/04/14 7:42a Wilsonlee
+// [TAG] EIP183463
+// [Category] Improvement
+// [Description] In UEFI spec, the definitions of bits within
+// ActiveButtons are EFI_ABSP_TouchActive and EFI_ABS_AltActive, we don't
+// support AltActive, clear the unnecessary bits.
+// [Files] usbpoint.c
+//
+// 14 5/12/14 3:29a Wilsonlee
+// [TAG] EIP168389
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Usb tip switch data may not be correct if the device is
+// multi-touch.
+// [RootCause] We get the data from the other point, but we only support
+// one point.
+// [Solution] Only get the first point data.
+// [Files] usbpoint.c
+//
+// 13 5/06/14 5:16a Ryanchou
+// [TAG] EIP166835
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Arrow keys cannot work with specific USB keyboard
+// [RootCause] HID driver cannot parse a input report that includes both
+// usage minimum/maximum and single usage.
+// [Solution] Store the usage in the same array to determine the input
+// data format.
+// [Files] syskbc.c, sysnokbc.c, usbdef.h, usbhid.c, usbkbd.c,
+// usbkbd.h, usbms.c, usbpoint, efiusbhid.c, efiusbpoint.c
+//
+// 12 2/26/14 1:56a Wilsonlee
+// [TAG] EIP149854
+// [Category] Improvement
+// [Description] Add data length parameter to polling callback function.
+// [Files] usbkbd.c, uhci.c, usb.c, usbhub.c, usbCCID.c, usbms.c,
+// usbhid.c, usbpoint.c, usbkbd.h, ehci.c, ohci.c, xhci.c, usbdef.h
+//
+// 11 3/08/13 4:18a Roberthsu
+// [TAG] EIP114280
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] vPro KVM Mouse can not work.
+// [RootCause] Get wrong button offset.
+// [Solution] Check usagemin get correct button offset.
+// [Files] usbpoint.c
+//
+// 10 1/11/13 4:16a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 9 11/10/12 6:40a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 8 10/26/12 8:49a Roberthsu
+// [TAG] EIP101990
+// [Category] Improvement
+// [Description] Add check inpurt mode.
+// [Files] usbhid.c,usbpoint.c
+//
+// 7 9/14/12 5:11a Roberthsu
+// [TAG] EIP101018
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Button funtion not work
+// [RootCause] Get wrong button status offset.
+// [Solution] Get correct button status offset.
+// [Files] usbpoint.c
+//
+// 6 3/05/12 2:18a Roberthsu
+// [TAG] EIP81983
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Setup menu no response after update N-trig firmware.
+// [RootCause] LogicalMax need use report item's value.
+// [Solution] Correct LogicalMax parameter.
+// [Files] usbpoint.c
+//
+// 5 1/13/12 4:06a Roberthsu
+// [TAG] EIP80173
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Cando touch screen cannot work .
+// [RootCause] Touch screen need send set_idle command.
+// [Solution] Add set_idle command.
+// [Files] usbpoint.c
+//
+// 4 1/09/12 1:05a Roberthsu
+// [TAG] EIP79323
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Touch Screen cannot work smoothly
+// [RootCause] There are some empty data.
+// [Solution] Check empty data then exit.
+// [Files] usbpoint.c
+//
+// 3 11/21/11 10:58p Roberthsu
+// [TAG] EIP75015
+// [Category] Improvement
+// [Description] Report button status direct.
+// [Files] usbpoint.c
+//
+// 2 8/05/11 7:32a Ryanchou
+// [TAG] EIP66231
+// [Category] Improvement
+// [Description] Remove token POINT_SUPPORT.Add token USB_DEV_POINT.Add
+// check core version in point driver.Add check device descriptor to send
+// get lang id command.Modify check button usage page.
+// [Files] efiusbhid.c, efiusbpoint.c, usbbus.c, usbhid.c, usbpoint.c,
+// usbsrc.sdl
+//
+// 1 7/15/11 6:18a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: UsbPoint.c
+//
+// Description: AMI USB Absolute Device support implementation
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "amiusb.h"
+#include "usbkbd.h"
+#include <Protocol/AbsPointerProtocol.h>
+
+extern USB_GLOBAL_DATA *gUsbData;
+
+static BOOLEAN globalAbsolutePolling = TRUE;
+
+UINT8 USBAbsProcessMouseData (HC_STRUC*, DEV_INFO*, UINT8*, UINT8*, UINT16);
+VOID SetABSData (UINT8*,UINT16*,UINT8,UINT8,UINT16);
+UINT16 PerviousXPosition = 0;
+UINT16 PerviousYPosition = 0;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: USBAbsConfigureDevice
+//
+// Description: This routine checks an interface descriptor of the USB device
+// detected to see if it describes a HID/Boot/Mouse device.
+// If the device matches the above criteria, then the device is
+// configured and initialized
+//
+// Input: HcStruc HCStruc pointer
+// DevInfo Device information structure pointer
+// Desc Pointer to the descriptor structure
+// Start Offset within interface descriptor
+// supported by the device
+// End End offset of the device descriptor
+//
+// Output: FPDEV_INFO New device info structure, 0 on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+USBAbsConfigureDevice (
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo,
+ UINT8* Desc,
+ UINT16 Start,
+ UINT16 End
+)
+{
+ return NULL;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBAbsProcessMouseData
+//
+// Description:
+//
+// Input: HcStruc Pointer to HCStruc
+// DevInfo Pointer to device information structure
+// Td Pointer to the polling TD
+// Buffer Pointer to the data buffer
+//
+// Output: Nothing
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+USBAbsProcessMouseData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Td,
+ UINT8 *Buffer,
+ UINT16 DataLength
+)
+{
+ USBABS_DATA AbsBuffer;
+ HID_REPORT_FIELD *Field = NULL;
+ UINT8 OffsetTmp = 0;
+ UINT8 XStart = 0;
+ UINT8 XEnd;
+ UINT8 YStart = 0;
+ UINT8 YEnd;
+ UINT8 ButtonStart = 0;
+ UINT8 ButtonEnd = 0;
+ UINT8 i;
+ UINT16 j;
+ UINT16 MaxX;
+ UINT16 MaxY;
+ BOOLEAN SetButtonData = FALSE;
+ BOOLEAN SetXData = FALSE;
+ BOOLEAN SetYData = FALSE;
+
+ AbsBuffer.X =0;
+ AbsBuffer.Y =0;
+ AbsBuffer.Button =0;
+
+ for (i = 0; i < DevInfo->HidReport.FieldCount; i++) {
+ Field = DevInfo->HidReport.Fields[i];
+
+ //Check is input?
+ if (!(Field->Flag & HID_REPORT_FIELD_FLAG_INPUT)) {
+ continue;
+ }
+
+ // Check if report id is matched
+ if (Field->ReportId != 0 && Field->ReportId != Buffer[0]) {
+ continue;
+ }
+
+ // Check if the field is contant.
+ if (Field->Flag & HID_REPORT_FIELD_FLAG_CONSTANT) {
+ OffsetTmp += Field->ReportCount * Field->ReportSize;
+ continue;
+ }
+
+ if ((Field->UsagePage == 0xd) && (Field->UsageCount != 0)) {
+ for (j = 0; j < Field->UsageCount; j++) {
+ //Check Tip switch
+ if (Field->Usages[j] == 0x42) { //(EIP79323)
+ if (SetButtonData == TRUE) {
+ break;
+ }
+ ButtonStart = OffsetTmp;
+ if (Field->ReportId != 0) {
+ ButtonStart += 8;
+ }
+ ButtonEnd = ButtonStart + (Field->ReportSize * Field->ReportCount); //(EIP101990)
+ SetABSData(Buffer, (UINT16*)(&AbsBuffer.Button), ButtonStart, ButtonEnd, 0xffff); //(EIP101990)
+ SetButtonData = TRUE;
+ //In UEFI spec, the definitions of bits within ActiveButtons are EFI_ABSP_TouchActive
+ // and EFI_ABS_AltActive, we don't support AltActive, clear the unnecessary bits.
+ AbsBuffer.Button &= EFI_ABSP_TouchActive;
+ }
+ }
+ }
+
+ //Check Button
+ if ((Field->UsagePage == 9) && (Field->UsageCount != 0) && (Field->Usages[0] == 1)) { //(EIP114280)
+ if (SetButtonData == TRUE) {
+ break;
+ }
+ ButtonStart = OffsetTmp;
+ if (Field->ReportId != 0) {
+ ButtonStart += 8;
+ }
+ ButtonEnd = ButtonStart + Field->ReportSize * Field->ReportCount; //(EIP101018)
+ SetABSData(Buffer, (UINT16*)(&AbsBuffer.Button), ButtonStart, ButtonEnd, 0xffff); //(EIP101018)
+ SetButtonData = TRUE;
+ }
+
+ //Check X,Y
+ if ((Field->UsagePage == 1) && (Field->UsageCount != 0)) {
+ for (j = 0; j < Field->UsageCount; j++) {
+ //find X
+ if (Field->Usages[j] == 0x30) {
+ if (SetXData == TRUE) {
+ break;
+ }
+ XStart = OffsetTmp + (j * Field->ReportSize);
+ if (Field->ReportId != 0) {
+ XStart += 8;
+ }
+ XEnd = XStart + Field->ReportSize;
+ SetABSData(Buffer, &AbsBuffer.X, XStart, XEnd, Field->LogicalMax); //(EIP81983)
+ SetXData = TRUE;
+ MaxX = Field->LogicalMax;
+ }
+
+ //find Y
+ if (Field->Usages[j] == 0x31) {
+ if (SetYData == TRUE) {
+ break;
+ }
+ YStart = OffsetTmp + (j * Field->ReportSize);
+ if (Field->ReportId != 0) {
+ YStart += 8;
+ }
+ YEnd = YStart + Field->ReportSize;
+ MaxY = Field->LogicalMax;
+ SetABSData(Buffer, &AbsBuffer.Y, YStart, YEnd, Field->LogicalMax); //(EIP81983)
+ SetYData = TRUE;
+ }
+ }
+ }
+ OffsetTmp += Field->ReportCount * Field->ReportSize;
+ }
+
+ if (AbsBuffer.Button == 0 && AbsBuffer.X == 0 && AbsBuffer.Y == 0) {
+ return USB_SUCCESS;
+ }
+
+ if (gUsbData->dUSBStateFlag & USB_FLAG_RUNNING_UNDER_EFI) {
+ gUsbData->AbsMouseData[0].ButtonStauts = AbsBuffer.Button;
+ gUsbData->AbsMouseData[0].Xcoordinate = AbsBuffer.X;
+ gUsbData->AbsMouseData[0].Ycoordinate = AbsBuffer.Y;
+ gUsbData->AbsMouseData[0].Pressure = 0;
+ gUsbData->AbsMouseData[0].Max_X = MaxX;
+ gUsbData->AbsMouseData[0].Max_Y = MaxY;
+ }
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: SetABSData
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+SetABSData (
+ UINT8 *Buffer,
+ UINT16 *ReportData,
+ UINT8 Start,
+ UINT8 End,
+ UINT16 Maxvalue
+)
+{
+ UINT8 ReportSize;
+ UINT8 Size;
+ UINT8 PreSkip;
+ UINT8 PostSkip;
+ UINT32 TempData = 0;
+
+ ReportSize = End - Start;
+ Size = ReportSize / 8;
+
+ if ((ReportSize % 8) !=0) {
+ Size++;
+ }
+
+ ASSERT(Size > 0 && Size <= sizeof(TempData));
+ if ((Size == 0) || (Size > sizeof(TempData))) {
+ return;
+ }
+
+ MemCpy(&TempData, Buffer + Start / 8, Size);
+
+ PreSkip = Start % 8;
+ PostSkip = End % 8;
+
+ if (PreSkip != 0) {
+ TempData = TempData >> PreSkip;
+ }
+
+ if (PostSkip != 0) {
+ TempData = TempData << PostSkip;
+ TempData = TempData >> PostSkip;
+ }
+
+ if (TempData > Maxvalue) {
+ TempData &= Maxvalue;
+ }
+
+ *ReportData = (UINT16)TempData;
+ USB_DEBUG (DEBUG_LEVEL_4, "out data %x\n",*ReportData);
+
+ return;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/usbrt.cif b/Core/EM/usb/rt/usbrt.cif
new file mode 100644
index 0000000..8d3a596
--- /dev/null
+++ b/Core/EM/usb/rt/usbrt.cif
@@ -0,0 +1,31 @@
+<component>
+ name = "UsbRt"
+ category = ModulePart
+ LocalRoot = "core\em\usb\rt"
+ RefName = "USBRT"
+[files]
+"amiusb.c"
+"usbkbd.c"
+"debug.c"
+"elib.c"
+"uhci.c"
+"usb.c"
+"usbhub.c"
+"usbmass.c"
+"UsbMass.h"
+"usbCCID.c"
+"usbms.c"
+"usbhid.c"
+"usbpoint.c"
+"uhci.h"
+"usbkbd.h"
+"ehci.c"
+"ehci.h"
+"ohci.c"
+"ohci.h"
+"guids.c"
+"syskbc.c"
+"sysnokbc.c"
+"xhci.h"
+"xhci.c"
+<endComponent>
diff --git a/Core/EM/usb/rt/usbrt.mak b/Core/EM/usb/rt/usbrt.mak
new file mode 100644
index 0000000..ef9b570
--- /dev/null
+++ b/Core/EM/usb/rt/usbrt.mak
@@ -0,0 +1,241 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2016, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/USB/ALASKA/rt/usbrt.mak 27 10/16/16 10:15p Wilsonlee $
+#
+# $Revision: 27 $
+#
+# $Date: 10/16/16 10:15p $
+#
+#****************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/USB/ALASKA/rt/usbrt.mak $
+#
+# 27 10/16/16 10:15p Wilsonlee
+# [TAG] EIP288158
+# [Category] Improvement
+# [Description] Check if gUsbData is integrity.
+# [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+# AmiUsbSmmGlobalDataValidationLib.c,
+# AmiUsbSmmGlobalDataValidationLib.cif,
+# AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+# ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+# usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+# amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+# AmiUsbController.h, AmiUsbLibInclude.cif,
+# AmiUsbSmmGlobalDataValidationLib.h
+#
+# 26 12/03/14 9:38p Wilsonlee
+# [TAG] EIP193805
+# [Category] Improvement
+# [Description] Security Enhancement for SMIHandler in USB module.
+# [Files] amiusb.c, uhcd.c, usbrt.mak, usbdef.h, usbsb.c
+#
+# 25 3/19/13 4:02a Ryanchou
+# [TAG] EIP118177
+# [Category] Improvement
+# [Description] Dynamically allocate HCStrucTable at runtime.
+# [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+# syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+# usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+# efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+# usbmisc.c, usbsrc.sdl
+#
+# 24 11/20/12 9:07p Wilsonlee
+# [TAG] EIP90887
+# [Category] New Feature
+# [Description] Add a hook to check keyboard buffer for speicial chars.
+# [Files] usb.sdl, usbrt.mak, usbkbd.c
+#
+# 23 8/29/12 8:41a Ryanchou
+# [TAG] EIP77262
+# [Category] New Feature
+# [Description] Remove SMM dependency of USB.
+# [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+# elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+# efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+# uhcd.h, usbmisc.c, AmiUsbController.h
+#
+# 22 1/16/12 6:02a Ryanchou
+# [TAG] EIP81132
+# [Description] Add core version check for EIP80609 solution.
+# [Files] amiusb.c, usbrt.mak, usbsb.c
+#
+# 21 1/14/12 4:10a Ryanchou
+# [TAG] EIP80609
+# [Category] Bug Fix
+# [Severity] Important
+# [Symptom] If to enable debug mode and set launch CSM is "Never" in
+# setup, system will hang at 0xB1
+# [RootCause] The pointer AmiUsb is invalid if CSM is not launched,
+# that may cause CPU exception.
+# [Solution] Added USB smm protocol, and use SmmLocateProtocol to get
+# the pointer.
+# [Files] amiusb.c, AmiUsbController.h, usbrt.mak, usbsb.c
+#
+# 20 10/25/11 8:27a Wilsonlee
+# [TAG] EIP71750
+# [Category] New Feature
+# [Description] Support extraUSB device driver hook by elink.
+# [Files] usb.c, uhcd.c, uhcd.mak, usbrt.mak, usb.sdl
+#
+# 19 11/22/10 8:45a Ryanchou
+# [TAG] EIP48064
+# [Category] Improvement
+# [Description] The SB template implemented elink
+# AcpiEnableCallbackList, the XHCI/EHCI hand off function should be
+# invoked via the elink AcpiEnableCallbackList.
+# [Files] amidef.h, amiusb.c, amiusb.dxs, amiusb.h,
+# AmiUsbController.h, usb.sdl, usbrt.mak, usbsb.c
+#
+# 18 11/13/09 9:14a Olegi
+# EIP31023: key repeat rates are defined by SDL tokens.
+#
+# 17 10/30/09 5:48p Olegi
+#
+# 16 5/16/08 12:03p Olegi
+# Compliance with AMI coding standard.
+#
+#****************************************************************************
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: UsbRt.mak
+#
+# Description: Make file for the UsbRt component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+all : USBRT
+
+!ifndef PI_SPECIFICATION_VERSION
+PI_SPECIFICATION_VERSION = 0
+!endif
+
+!ifndef CORE_COMBINED_VERSION
+CORE_COMBINED_VERSION = $(CORE_MAJOR_VERSION)*65536+$(CORE_MINOR_VERSION)*100+$(CORE_REVISION)*10+$(CORE_BUILD_NUMBER)
+!endif
+
+USBRT : $(BUILD_DIR)\usbrt.mak UsbRtElinkList USBRTBin
+
+USBRT_EXT_HEADERS=\
+ $(UHCD_DIR)\RT\usbdef.h\
+ $(UHCD_DIR)\RT\amidef.h\
+ $(UHCD_DIR)\RT\amiusb.h\
+ $(BUILD_DIR)\UsbDevDriverElinks.h
+
+$(BUILD_DIR)\usbrt.mak : $(USBRT_DIR)\$(@B).cif $(USBRT_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(USBRT_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+UsbRtElinkList: UhcdElinkList
+ $(ECHO) #define USB_DEV_DELAYED_DRIVER $(USB_DEV_DELAYED_DRIVER_LIST) >> $(BUILD_DIR)\UsbDevDriverElinks.h
+ $(ECHO) #define USB_DEV_DRIVER $(USB_DEV_DRIVER_LIST) >> $(BUILD_DIR)\UsbDevDriverElinks.h
+ $(ECHO) #define KBD_BUFFER_CHECK_ELINK_LIST $(CheckKeyBoardBufferForSpecialChars) >> $(BUILD_DIR)\UsbDevDriverElinks.h
+
+$(BUILD_DIR)\dummyusbrt.obj:
+ copy << $(BUILD_DIR)\dummyusbrt.c
+#include "amidef.h"
+#include "usbdef.h"
+#include "usbkbd.h"
+
+extern UINT8 UHCI_FillHCDEntries(HCD_HEADER*);
+extern UINT8 OHCI_FillHCDEntries(HCD_HEADER*);
+extern UINT8 EHCI_FillHCDEntries(HCD_HEADER*);
+extern UINT8 XHCI_FillHCDEntries(HCD_HEADER*);
+extern USB_GLOBAL_DATA *gUsbData;
+
+void FillHcdEntries()
+{
+#if UHCI_SUPPORT
+ UHCI_FillHCDEntries (&gUsbData->aHCDriverTable[USB_INDEX_UHCI]);
+#endif
+#if OHCI_SUPPORT
+ OHCI_FillHCDEntries (&gUsbData->aHCDriverTable[USB_INDEX_OHCI]);
+#endif
+#if EHCI_SUPPORT
+ EHCI_FillHCDEntries (&gUsbData->aHCDriverTable[USB_INDEX_EHCI]);
+#endif
+#if XHCI_SUPPORT
+ XHCI_FillHCDEntries (&gUsbData->aHCDriverTable[USB_INDEX_XHCI]);
+#endif
+}
+<<
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(BUILD_DIR)\dummyusbrt.c /I$(UHCD_DIR) /I$(USBRT_DIR)
+
+!if $(USB_RUNTIME_DRIVER_IN_SMM) == 1
+!ifdef AcpiEnableCallbackList
+$(BUILD_DIR)\usbsb.obj: $(USB_SB_DIR)\usbsb.c
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(USB_SB_DIR)\usbsb.c /I$(USB_SB_DIR) /I$(USBRT_DIR)
+
+$(BUILD_DIR)\usbacpi.obj: $(USB_SB_DIR)\usbsb.c
+ $(CC) $(CFLAGS) /DUSB_ACPI_ENABLE_CALLBACK /Fo$(BUILD_DIR)\usbacpi.obj $(USB_SB_DIR)\usbsb.c /I$(USB_SB_DIR) /I$(USBRT_DIR)
+
+AcpiModeEnableBin: $(BUILD_DIR)\usbacpi.obj
+
+!else
+$(BUILD_DIR)\usbsb.obj: $(USB_SB_DIR)\usbsb.c
+ $(CC) $(CFLAGS) /DUSB_ACPI_ENABLE_DISPATCH /Fo$(BUILD_DIR)\ $(USB_SB_DIR)\usbsb.c /I$(USB_SB_DIR) /I$(USBRT_DIR)
+
+!endif
+!endif
+
+$(BUILD_DIR)\usbrtport.obj : $(USBPORTING_DIR)\usbport.c
+ $(CC) $(CFLAGS) /DUSB_RT_DRIVER /Fo$(BUILD_DIR)\UsbrtPort.obj $(USBPORTING_DIR)\usbport.c /I$(UHCD_DIR) /I$(USBRT_DIR)
+
+USBRTBinObjects = \
+ $(BUILD_DIR)\dummyusbrt.obj \
+!if $(USB_RUNTIME_DRIVER_IN_SMM) == 1
+ $(BUILD_DIR)\usbsb.obj \
+ $(BUILD_DIR)\AmiBufferValidationLib.lib \
+ $(BUILD_DIR)\AmiUsbSmmGlobalDataValidationLib.lib \
+!endif
+ $(BUILD_DIR)\usbrtport.obj
+
+USBRTBin : $(AMIDXELIB) $(USBRTBinObjects)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\usbrt.mak all\
+ GUID=04EAAAA1-29A1-11d7-8838-00500473D4EB \
+ ENTRY_POINT=USBDriverEntryPoint \
+ "CFLAGS=$(CFLAGS) /I$(UHCD_DIR)"\
+ "AFLAGS=$(AFLAGS) /Fl"\
+ "EXT_HEADERS=$(USBRT_EXT_HEADERS)"\
+!if $(USB_RUNTIME_DRIVER_IN_SMM) == 1 && $(PI_SPECIFICATION_VERSION) >= 0x00001000A && $(CORE_COMBINED_VERSION) >= 0x4028B
+ TYPE=SMM_DRIVER \
+ DEPEX1=$(USBRT_DIR)\amiusb.dxs \
+!else
+ TYPE=BS_DRIVER \
+ DEPEX1=$(USBRT_DIR)\amiusb.dxs \
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+!endif
+ COMPRESS=1\
+
+# "CFLAGS=$(CFLAGS:/W3=/W4) /I$(UHCD_DIR)"\
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2016, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/usb/rt/xhci.c b/Core/EM/usb/rt/xhci.c
new file mode 100644
index 0000000..870e327
--- /dev/null
+++ b/Core/EM/usb/rt/xhci.c
@@ -0,0 +1,4306 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: XHCI.C
+//
+// Description: AMI XHCI driver.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include "amiusb.h"
+#include "amidef.h"
+#include "usbdef.h"
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <AmiBufferValidationLib.h>
+#endif
+
+UINT8 XHCI_Start (HC_STRUC*);
+UINT8 XHCI_Stop (HC_STRUC*);
+UINT8 XHCI_EnumeratePorts (HC_STRUC*);
+UINT8 XHCI_DisableInterrupts (HC_STRUC*);
+UINT8 XHCI_EnableInterrupts (HC_STRUC*);
+UINT8 XHCI_ProcessInterrupt(HC_STRUC*);
+UINT8 XHCI_GetRootHubStatus (HC_STRUC*, UINT8, BOOLEAN);
+UINT8 XHCI_DisableRootHub (HC_STRUC*,UINT8);
+UINT8 XHCI_EnableRootHub (HC_STRUC*,UINT8);
+UINT16 XHCI_ControlTransfer (HC_STRUC*,DEV_INFO*,UINT16,UINT16,UINT16,UINT8*,UINT16);
+UINT32 XHCI_BulkTransfer (HC_STRUC*,DEV_INFO*,UINT8,UINT8*,UINT32);
+UINT16 XHCI_InterruptTransfer (HC_STRUC*, DEV_INFO*, UINT8, UINT16, UINT8*, UINT16);
+UINT8 XHCI_DeactivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 XHCI_ActivatePolling (HC_STRUC*,DEV_INFO*);
+UINT8 XHCI_DisableKeyRepeat (HC_STRUC*);
+UINT8 XHCI_EnableKeyRepeat (HC_STRUC*);
+UINT8 XHCI_EnableEndpoints (HC_STRUC*, DEV_INFO*, UINT8*);
+UINT8 XHCI_InitDeviceData (HC_STRUC*,DEV_INFO*,UINT8,UINT8**);
+UINT8 XHCI_DeinitDeviceData (HC_STRUC*,DEV_INFO*);
+UINT8 XHCI_ResetRootHub (HC_STRUC*,UINT8);
+UINT8 XHCI_ClearEndpointState(HC_STRUC*,DEV_INFO*,UINT8); //(EIP54283+)
+UINT8 XHCI_GlobalSuspend (HC_STRUC*); //(EIP54018+)
+
+UINT8 XHCI_WaitForEvent(HC_STRUC*,XHCI_TRB*,TRB_TYPE,UINT8,UINT8,UINT8*,UINT16,VOID*);
+TRB_RING* XHCI_InitXfrRing(USB3_HOST_CONTROLLER*, UINT8, UINT8);
+TRB_RING* XHCI_GetXfrRing(USB3_HOST_CONTROLLER*, UINT8, UINT8);
+UINT8 XHCI_GetSlotId(USB3_HOST_CONTROLLER*, DEV_INFO*);
+UINT64 XHCI_Mmio64Read(HC_STRUC*, USB3_HOST_CONTROLLER*, UINTN);
+VOID XHCI_Mmio64Write(HC_STRUC*, USB3_HOST_CONTROLLER*, UINTN, UINT64);
+EFI_STATUS XHCI_InitRing(TRB_RING*, UINTN, UINT32, BOOLEAN);
+UINT32* XHCI_GetTheDoorbell(USB3_HOST_CONTROLLER*, UINT8);
+VOID UpdatePortStatusSpeed(UINT8, UINT8*);
+UINT8 XHCI_ResetPort(USB3_HOST_CONTROLLER*, UINT8, BOOLEAN);
+BOOLEAN XHCI_IsUsb3Port(USB3_HOST_CONTROLLER*, UINT8);
+UINT8 XhciRingDoorbell(USB3_HOST_CONTROLLER*, UINT8, UINT8);
+EFI_STATUS XhciExtCapParser(USB3_HOST_CONTROLLER*);
+UINT8 XhciAddressDevice (HC_STRUC*, DEV_INFO*, UINT8);
+
+DEV_INFO* XHCI_GetDevInfo(UINTN);
+VOID* XHCI_GetDeviceContext(USB3_HOST_CONTROLLER*, UINT8);
+VOID* XHCI_GetContextEntry(USB3_HOST_CONTROLLER*, VOID*, UINT8);
+
+UINT8 UsbHubGetHubDescriptor(HC_STRUC*, DEV_INFO*, VOID*, UINT16);
+
+VOID MemFill (UINT8*, UINT32, UINT8);
+UINT8 USB_ResetHubPort(HC_STRUC*, UINT8, UINT8);
+UINT8 USB_DisconnectDevice (HC_STRUC*, UINT8, UINT8);
+UINT8 USB_GetHubPortStatus(HC_STRUC*, UINT8, UINT8, BOOLEAN);
+
+UINT32 ReadPCIConfig(UINT16, UINT8);
+
+VOID USBKeyRepeat(HC_STRUC*, UINT8);
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern BOOLEAN gCheckUsbApiParameter;
+
+#if USB_DEV_KBD
+VOID USBKBDPeriodicInterruptHandler(HC_STRUC*);
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_FillHCDEntries
+//
+// Description:
+// This function fills the host controller driver routine pointers.
+//
+// Input:
+// Ptr to the host controller header structure
+//
+// Output:
+// Status: USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_FillHCDEntries (
+ HCD_HEADER *fpHCDHeader
+)
+{
+ fpHCDHeader->pfnHCDStart = XHCI_Start;
+ fpHCDHeader->pfnHCDStop = XHCI_Stop;
+ fpHCDHeader->pfnHCDEnumeratePorts = XHCI_EnumeratePorts;
+ fpHCDHeader->pfnHCDDisableInterrupts = XHCI_DisableInterrupts;
+ fpHCDHeader->pfnHCDEnableInterrupts = XHCI_EnableInterrupts;
+ fpHCDHeader->pfnHCDProcessInterrupt = XHCI_ProcessInterrupt;
+ fpHCDHeader->pfnHCDGetRootHubStatus = XHCI_GetRootHubStatus;
+ fpHCDHeader->pfnHCDDisableRootHub = XHCI_DisableRootHub;
+ fpHCDHeader->pfnHCDEnableRootHub = XHCI_EnableRootHub;
+ fpHCDHeader->pfnHCDControlTransfer = XHCI_ControlTransfer;
+ fpHCDHeader->pfnHCDBulkTransfer = XHCI_BulkTransfer;
+ fpHCDHeader->pfnHCDInterruptTransfer = XHCI_InterruptTransfer;
+ fpHCDHeader->pfnHCDDeactivatePolling = XHCI_DeactivatePolling;
+ fpHCDHeader->pfnHCDActivatePolling = XHCI_ActivatePolling;
+ fpHCDHeader->pfnHCDDisableKeyRepeat = XHCI_DisableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableKeyRepeat = XHCI_EnableKeyRepeat;
+ fpHCDHeader->pfnHCDEnableEndpoints = XHCI_EnableEndpoints;
+ fpHCDHeader->pfnHCDInitDeviceData = XHCI_InitDeviceData;
+ fpHCDHeader->pfnHCDDeinitDeviceData = XHCI_DeinitDeviceData;
+ fpHCDHeader->pfnHCDResetRootHub = XHCI_ResetRootHub;
+ fpHCDHeader->pfnHCDClearEndpointState = XHCI_ClearEndpointState; //(EIP54283+)
+ fpHCDHeader->pfnHCDGlobalSuspend = XHCI_GlobalSuspend; //(EIP54018+)
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_Start
+//
+// Description:
+// This API function is called to start a XHCI host controller. The input
+// to the routine is the pointer to the HC structure that defines this host
+// controller. The procedure flow is followed as it is described in 4.2 of
+// XHCI specification.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_SUCCESS = Success, USB_ERROR = Failure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_Start (
+ HC_STRUC *HcStruc
+)
+{
+ XHCI_INTERRUPTER_REGS *Interrupter;
+ XHCI_ER_SEGMENT_ENTRY *Erst0Entry;
+ UINT32 i;
+ BOOLEAN PpSet = FALSE;
+ UINT8 PortNumber;
+ volatile XHCI_PORTSC *PortSC;
+ UINT32 LegCtlStsReg = 0;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ HcStruc->BaseAddress = (UINTN)Usb3Hc->CapRegs;
+ HcStruc->bNumPorts = Usb3Hc->MaxPorts;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)HcStruc->BaseAddress, HcStruc->BaseAddressSize);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Usb Mmio address is invalid, it is in SMRAM\n");
+ return USB_ERROR;
+ }
+#endif
+
+ if (((VOID*)Usb3Hc->OpRegs < (VOID*)HcStruc->BaseAddress) ||
+ ((VOID*)(Usb3Hc->OpRegs + sizeof(XHCI_HC_OP_REGS)) > (VOID*)(HcStruc->BaseAddress + HcStruc->BaseAddressSize))) {
+ return USB_ERROR;
+ }
+
+ // Wait controller ready
+ for (i = 0; i < 1000; i++) {
+ if (Usb3Hc->OpRegs->UsbSts.Field.Cnr == 0) break;
+ FixedDelay(100); // 100 us delay
+ }
+// ASSERT(Usb3Hc->OpRegs->UsbSts.Field.Cnr == 0);
+ if (Usb3Hc->OpRegs->UsbSts.Field.Cnr) return USB_ERROR;
+
+ // Check if the xHC is halted
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0) {
+ Usb3Hc->OpRegs->UsbCmd.AllBits &= ~XHCI_CMD_RS;
+ // The xHC should halt within 16 ms. Section 5.4.1.1
+ for (i = 0; i < 160; i++) {
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) break;
+ FixedDelay(100); // 100 us delay
+ }
+ ASSERT(Usb3Hc->OpRegs->UsbSts.Field.HcHalted);
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0) return USB_ERROR;
+ }
+#if XHCI_COMPLIANCE_MODE_WORKAROUND
+ for (PortNumber = 1; PortNumber <= Usb3Hc->MaxPorts; PortNumber++) {
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNumber - 1)));
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+ if (PortSC->Field.Pls == XHCI_PORT_LINK_COMPLIANCE_MODE) {
+ XHCI_ResetPort(Usb3Hc, PortNumber, FALSE);
+ }
+ }
+#endif
+ // Reset controller
+ if ((Usb3Hc->DbCapRegs == NULL) || (Usb3Hc->DbCapRegs->DcCtrl.Dce == 0)) {
+ Usb3Hc->OpRegs->UsbCmd.AllBits |= XHCI_CMD_HCRST;
+ for (i = 0; i < 8000; i++) {
+ if (Usb3Hc->OpRegs->UsbCmd.Field.HcRst == 0) {
+ break;
+ }
+ FixedDelay(100); // 100 us delay
+ }
+ ASSERT(Usb3Hc->OpRegs->UsbCmd.Field.HcRst == 0);
+ if (Usb3Hc->OpRegs->UsbCmd.Field.HcRst) {
+ return USB_ERROR; // Controller can not be reset
+ }
+ }
+
+ if ((Usb3Hc->CapRegs->RtsOff + (sizeof(UINT32) * 8) + (sizeof(XHCI_INTERRUPTER_REGS) * Usb3Hc->CapRegs->HcsParams1.MaxIntrs))
+ > HcStruc->BaseAddressSize) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc->RtRegs = (XHCI_HC_RT_REGS*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->CapRegs->RtsOff);
+ USB_DEBUG(3, "XHCI: RT registers are at %x\n", Usb3Hc->RtRegs);
+
+ Usb3Hc->OpRegs->Config = Usb3Hc->MaxSlots; // Max device slots enabled
+
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->DcbAap, (UINT64)(UINTN)Usb3Hc->DcbaaPtr);
+
+ // Check if xHC support 64bit access capability
+ if (Usb3Hc->Access64) {
+ if(XHCI_Mmio64Read(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->DcbAap) != (UINT64)(UINTN)Usb3Hc->DcbaaPtr) {
+ Usb3Hc->Access64 = 0;
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->DcbAap, (UINT64)(UINTN)Usb3Hc->DcbaaPtr);
+ }
+ }
+
+ // Define the Command Ring Dequeue Pointer by programming the Command Ring
+ // Control Register (5.4.5) with a 64-bit address pointing to the starting
+ // address of the first TRB of the Command Ring.
+
+ // Initialize Command Ring Segment: Size TRBS_PER_SEGMENT*16, 64 Bytes aligned
+ XHCI_InitRing(&Usb3Hc->CmdRing, (UINTN)Usb3Hc->DcbaaPtr + 0x2000, TRBS_PER_SEGMENT, TRUE);
+ USB_DEBUG(3, "CMD Ring is at %x\n", (UINTN)&Usb3Hc->CmdRing);
+
+ // Write CRCR HC register with the allocated address. Set Ring Cycle State to 1.
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->Crcr,
+ (UINT64)(UINTN)Usb3Hc->CmdRing.Base + CRCR_RING_CYCLE_STATE);
+
+ // Initialize and assign Event Ring
+ XHCI_InitRing(&Usb3Hc->EvtRing, (UINTN)Usb3Hc->DcbaaPtr + 0x2400, TRBS_PER_SEGMENT, FALSE);
+ USB_DEBUG(3, "EVT Ring is at %x\n", (UINTN)&Usb3Hc->EvtRing);
+
+ // NOTE: This driver supports one Interrupter, hence it uses
+ // one Event Ring segment with TRBS_PER_SEGMENT TRBs in it.
+
+ // Initialize ERST[0]
+ Erst0Entry = (XHCI_ER_SEGMENT_ENTRY*)((UINTN)Usb3Hc->DcbaaPtr + 0x1200);
+ Erst0Entry->RsBase = (UINT64)(UINTN)Usb3Hc->EvtRing.Base;
+ Erst0Entry->RsSize = TRBS_PER_SEGMENT;
+
+ Interrupter = Usb3Hc->RtRegs->IntRegs;
+
+ // Initialize Interrupter fields
+ Interrupter->Erstz = 1; // # of segments
+ // ER dequeue pointer
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Interrupter->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr);
+ // Seg Table location
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Interrupter->Erstba, (UINT64)(UINTN)Erst0Entry);
+ Interrupter->IMod = XHCI_IMODI; // Max interrupt rate
+ Usb3Hc->OpRegs->UsbCmd.AllBits |= XHCI_CMD_INTE;
+ Interrupter->IMan |= 2; // Enable interrupt
+
+ USB_DEBUG(3, "Transfer Rings structures start at %x\n", Usb3Hc->XfrRings);
+
+ // Set PortPower unless PowerPortControl indicates otherwise
+ if (Usb3Hc->CapRegs->HccParams1.Ppc != 0) {
+ for (PortNumber = 1; PortNumber <= Usb3Hc->MaxPorts; PortNumber++) {
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNumber - 1)));
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+ if (PortSC->Field.Pp == 0) {
+ PortSC->Field.Pp = 1; // Set port power
+ PpSet = TRUE;
+ }
+ }
+ if (PpSet) FixedDelay(20 * 1000); // Wait for 20 ms, Section 5.4.8
+ }
+
+ // If xHC doesn't support HW SMI, should not touch USB Legacy Support Capability registers
+ //if (((HcStruc->dHCFlag & HC_STATE_EXTERNAL) && (XHCI_EVENT_SERVICE_MODE == 0)) ||
+ // (USB_RUNTIME_DRIVER_IN_SMM == 0)) {
+ // Usb3Hc->ExtLegCap = NULL;
+ //}
+
+ // Check if USB Legacy Support Capability is present.
+ if (Usb3Hc->ExtLegCap) {
+ // Set HC BIOS Owned Semaphore flag
+ Usb3Hc->ExtLegCap->LegSup.HcBiosOwned = 1;
+ //If XHCI doesn't support HW SMI, should not enable USB SMI in Legacy Support Capability register.
+ if (((!(HcStruc->dHCFlag & HC_STATE_EXTERNAL)) || (XHCI_EVENT_SERVICE_MODE != 0)) &&
+ (USB_RUNTIME_DRIVER_IN_SMM != 0)) {
+ // Enable USB SMI, Ownership Change SMI and clear all status
+ LegCtlStsReg = Usb3Hc->ExtLegCap->LegCtlSts.AllBits;
+ LegCtlStsReg |= XHCI_SMI_ENABLE | XHCI_SMI_OWNERSHIP_CHANGE_ENABLE |
+ XHCI_SMI_OWNERSHIP_CHANGE | XHCI_SMI_PCI_CMD | XHCI_SMI_PCI_BAR;
+ Usb3Hc->ExtLegCap->LegCtlSts.AllBits = LegCtlStsReg;
+ }
+ }
+
+ Usb3Hc->OpRegs->UsbCmd.AllBits |= XHCI_CMD_RS;
+
+ for (i = 0; i < 100; i++) {
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0) {
+ break;
+ }
+ FixedDelay(100);
+ }
+ ASSERT(Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0);
+
+ HcStruc->dHCFlag |= HC_STATE_RUNNING;
+
+ // Set USB_FLAG_DRIVER_STARTED flag when HC is running.
+ if (!(gUsbData->dUSBStateFlag & USB_FLAG_DRIVER_STARTED)) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_DRIVER_STARTED;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (!(HcStruc->dHCFlag & HC_STATE_EXTERNAL)) {
+ UsbInstallHwSmiHandler(HcStruc);
+ } else {
+ USBSB_InstallXhciHwSmiHandler();
+ }
+ if (HcStruc->HwSmiHandle != NULL) {
+ USBKeyRepeat(HcStruc, 0);
+ }
+#endif
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_Stop
+//
+// Description:
+// This function stops the XHCI controller.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_Stop (
+ HC_STRUC *HcStruc
+)
+{
+ UINT8 Port;
+ UINT32 i;
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+ XHCI_INTERRUPTER_REGS *Interrupter = NULL;
+ UINT32 LegCtlStsReg = 0;
+ UINT8 CompletionCode = 0;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ // Set the flag to aviod port enumeration
+ gUsbData->bEnumFlag = TRUE; // disable recursive enumeration
+
+ for (Port = 1; Port <= Usb3Hc->MaxPorts; Port++) {
+ USB_DisconnectDevice(HcStruc, HcStruc->bHCNumber | BIT7, Port);
+ }
+
+ // Port Change Detect bit may set by disabling ports.
+ //Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_PCD;
+
+ if (XHCI_Mmio64Read(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->Crcr) & CRCR_COMMAND_RUNNING) {
+ // Stop the command ring
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->Crcr, CRCR_COMMAND_STOP);
+
+ CompletionCode = XHCI_TRB_CMDRINGSTOPPED;
+ XHCI_WaitForEvent(
+ HcStruc, NULL, XhciTCmdCompleteEvt, 0, 0,
+ &CompletionCode, XHCI_CMD_COMPLETE_TIMEOUT_MS, NULL);
+ }
+
+ XHCI_ProcessInterrupt(HcStruc);
+
+ // Clear the port enumeration flag
+ gUsbData->bEnumFlag = FALSE;
+
+ // Disable interrupt
+ Usb3Hc->OpRegs->UsbCmd.AllBits &= ~XHCI_CMD_INTE;
+ Interrupter = Usb3Hc->RtRegs->IntRegs;
+ Interrupter->IMan &= ~BIT1;
+
+ // Clear the Run/Stop bit
+ Usb3Hc->OpRegs->UsbCmd.AllBits &= ~XHCI_CMD_RS;
+
+ // The xHC should halt within 16 ms. Section 5.4.1.1
+ for (i = 0; i < 160; i++) {
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) break;
+ FixedDelay(100);
+ }
+ ASSERT(Usb3Hc->OpRegs->UsbSts.Field.HcHalted);
+ //if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted == 0) return USB_ERROR;
+
+ // Check if USB Legacy Support Capability is present.
+ if(Usb3Hc->ExtLegCap != 0) {
+ // Clear HC BIOS Owned Semaphore flag
+ Usb3Hc->ExtLegCap->LegSup.HcBiosOwned = 0;
+ if (((!(HcStruc->dHCFlag & HC_STATE_EXTERNAL)) || (XHCI_EVENT_SERVICE_MODE != 0)) &&
+ (USB_RUNTIME_DRIVER_IN_SMM != 0)) {
+ // Disable USB SMI and Clear all status
+ LegCtlStsReg = Usb3Hc->ExtLegCap->LegCtlSts.AllBits;
+ LegCtlStsReg &= ~XHCI_SMI_ENABLE;
+ LegCtlStsReg |= XHCI_SMI_OWNERSHIP_CHANGE | XHCI_SMI_PCI_CMD | XHCI_SMI_PCI_BAR;
+ Usb3Hc->ExtLegCap->LegCtlSts.AllBits = LegCtlStsReg;
+ }
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (HcStruc->HwSmiHandle != NULL) {
+ USBKeyRepeat(HcStruc, 3);
+ }
+#endif
+
+ // Set the HC state to stopped
+ HcStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+
+ CheckBiosOwnedHc();
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_EnumeratePorts
+//
+// Description:
+// This function enumerates the HC ports for devices.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_EnumeratePorts(
+ HC_STRUC *HcStruc
+)
+{
+ //(EIP60327)>
+ UINT8 Count;
+ UINT8 Port;
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ EFI_STATUS EfiStatus;
+
+ if (gUsbData->bEnumFlag == TRUE) {
+ return USB_SUCCESS;
+ }
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;;
+ }
+
+ USB_DEBUG(3, "XHCI_EnumeratePorts..\n");
+ gUsbData->bIgnoreConnectStsChng = TRUE; //(EIP71962+)
+ gUsbData->bEnumFlag = TRUE; // disable recursive enumeration
+
+ if (Usb3Hc->Usb2Protocol) {
+ for(Count = 0; Count < Usb3Hc->Usb2Protocol->PortCount; Count++) {
+ Port = Count + Usb3Hc->Usb2Protocol->PortOffset;
+ USBCheckPortChange(HcStruc, HcStruc->bHCNumber | BIT7, Port);
+ }
+ }
+
+ if (Usb3Hc->Usb3Protocol) {
+ for(Count = 0; Count < Usb3Hc->Usb3Protocol->PortCount; Count++) {
+ Port = Count + Usb3Hc->Usb3Protocol->PortOffset;
+ if (Usb3Hc->Vid == XHCI_VL800_VID && Usb3Hc->Did == XHCI_VL800_DID) {
+ XHCI_ResetPort(Usb3Hc, Port , TRUE);
+ }
+ USBCheckPortChange(HcStruc, HcStruc->bHCNumber | BIT7, Port);
+ }
+ }
+
+// Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_PCD; // Clear PortChangeDetect
+
+ gUsbData->bIgnoreConnectStsChng = FALSE; //(EIP71962+)
+ gUsbData->bEnumFlag = FALSE; // enable enumeration
+
+ XHCI_ProcessInterrupt(HcStruc);
+ //<(EIP60327)
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_EnableInterrupts
+//
+// Description:
+// This function enables the HC interrupts
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_ERROR On error, USB_SUCCESS On success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_EnableInterrupts (
+ HC_STRUC* HcStruc
+)
+{
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_DisableInterrupts
+//
+// Description:
+// This function disables the HC interrupts
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_DisableInterrupts (
+ HC_STRUC* HcStruc
+)
+{
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_AdvanceEnqueuePtr
+//
+// Description:
+// This function advances returns the pointer to the current TRB and anvances
+// dequeue pointer. If the advance pointer is Link TRB, then it: 1) activates
+// Link TRB by updating its cycle bit, 2) updates dequeue pointer to the value
+// pointed by Link TRB.
+//
+// Input:
+// Ring - TRB ring to be updated
+//
+// Output:
+// TRB that can be used for command, transfer, etc.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+XHCI_TRB*
+XHCI_AdvanceEnqueuePtr(
+ TRB_RING *Ring
+)
+{
+ XHCI_TRB* Trb = Ring->QueuePtr;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ if (Trb->TrbType == XhciTLink) {
+ Trb->CycleBit = Ring->CycleBit;
+ Ring->CycleBit ^= 1;
+ Ring->QueuePtr = Ring->Base;
+
+ Trb = Ring->QueuePtr;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)Trb, sizeof(XHCI_TRB));
+ if (EFI_ERROR(Status)) {
+ return NULL;
+ }
+#endif
+ // Clear the TRB
+ *(UINT32*)Trb = 0;
+ *((UINT32*)Trb + 1) = 0;
+ *((UINT32*)Trb + 2) = 0;
+ *((UINT32*)Trb + 3) &= BIT0; // Keep cycle bit
+
+ //Trb->CycleBit = Ring->CycleBit;
+ Ring->QueuePtr++;
+
+ return Trb;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_WaitForEvent
+//
+// Description:
+// This function walks through the active TRBs in the event ring and looks for
+// the command TRB to be complete. If found, returns SlotId and CompletionCode
+// from the completed event TRB. In the end it processes the event ring,
+// adjusting its Dequeue Pointer.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+ //(EIP62376)>
+UINT8
+XHCI_WaitForEvent(
+ HC_STRUC *HcStruc,
+ XHCI_TRB *TrbToCheck,
+ TRB_TYPE EventType,
+ UINT8 SlotId,
+ UINT8 Dci,
+ UINT8 *CompletionCode,
+ UINT16 TimeOutMs,
+ VOID *Data
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ XHCI_TRB *Trb;
+ UINT32 Count;
+ UINT8 Status;
+ UINT8 CycleBit;
+ UINT32 TimeoutValue = ((UINT32)TimeOutMs) * 100; // in 10 macrosecond unit
+ XHCI_NORMAL_XFR_TRB *ResidualTrb; //(EIP82555+)
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ for (Count = 0; TimeoutValue == 0 || Count < TimeoutValue; Count++) {
+ for (Trb = Usb3Hc->EvtRing.QueuePtr,
+ CycleBit = Usb3Hc->EvtRing.CycleBit;;) {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Trb, sizeof(XHCI_TRB));
+ if (EFI_ERROR(EfiStatus)) {
+ break;
+ }
+#endif
+ if (Trb->CycleBit != CycleBit) {
+ // Command is not complete, break and retry
+ break;
+ }
+
+ // Active TRB found
+ if (Trb->TrbType == EventType) {
+ if (EventType == XhciTCmdCompleteEvt) {
+ if (TrbToCheck) {
+ if((*(UINTN*)&Trb->Param1) == (UINTN)TrbToCheck) {
+ if (Data != NULL) {
+ *(UINT8*)Data = ((XHCI_CMDCOMPLETE_EVT_TRB*)Trb)->SlotId;
+ }
+ *CompletionCode = Trb->CompletionCode;
+ Status = Trb->CompletionCode == XHCI_TRB_SUCCESS? USB_SUCCESS:USB_ERROR;
+ goto DoneWaiting;
+ }
+ } else {
+ if (*CompletionCode != 0 && Trb->CompletionCode == *CompletionCode) {
+ Status = USB_SUCCESS;
+ goto DoneWaiting;
+ }
+ }
+ } else if (EventType == XhciTTransferEvt) {
+ if (((XHCI_TRANSFER_EVT_TRB*)Trb)->SlotId == SlotId &&
+ ((XHCI_TRANSFER_EVT_TRB*)Trb)->EndpointId == Dci) {
+ if (Data != NULL) {
+ *(UINT32*)Data = ((XHCI_TRANSFER_EVT_TRB*)Trb)->TransferLength;
+ //(EIP82555+)>
+ if (Trb->CompletionCode == XHCI_TRB_SHORTPACKET) {
+ ResidualTrb = (XHCI_NORMAL_XFR_TRB*)(UINTN)((XHCI_TRANSFER_EVT_TRB*)Trb)->TrbPtr;
+ while (1) {
+ ResidualTrb->Isp = 0;
+ ResidualTrb->Ioc = 0;
+ if (ResidualTrb->Chain != 1) {
+ break;
+ }
+ ResidualTrb++;
+ if (ResidualTrb->TrbType == XhciTLink) {
+ ResidualTrb = (XHCI_NORMAL_XFR_TRB*)(UINTN)((XHCI_LINK_TRB*)ResidualTrb)->NextSegPtr;
+ }
+ *(UINT32*)Data += ResidualTrb->XferLength;
+ }
+ }
+ //<(EIP82555+)
+ }
+ *CompletionCode = Trb->CompletionCode;
+ Status = (Trb->CompletionCode == XHCI_TRB_SUCCESS ||
+ Trb->CompletionCode == XHCI_TRB_SHORTPACKET)? USB_SUCCESS:USB_ERROR;
+ goto DoneWaiting;
+ }
+ }
+ }
+ // Advance TRB pointer
+ if (Trb == Usb3Hc->EvtRing.LastTrb) {
+ Trb = Usb3Hc->EvtRing.Base;
+ CycleBit ^= 1;
+ } else {
+ Trb++;
+ }
+ if (Trb == Usb3Hc->EvtRing.QueuePtr) {
+ // Event ring is full, return error
+ USB_DEBUG(3, "XHCI: Event Ring is full...\n");
+ ASSERT(0);
+ *CompletionCode = XHCI_TRB_EVENTRINGFULL_ERROR;
+ Status = USB_ERROR;
+ break;
+ }
+ }
+ FixedDelay(10); // 10 us out of TimeOutMs
+ }
+
+ USB_DEBUG(3, "XHCI: execution time-out.\n");
+
+ *CompletionCode = XHCI_TRB_EXECUTION_TIMEOUT_ERROR;
+ Status = USB_ERROR;
+
+DoneWaiting:
+ XHCI_ProcessInterrupt(HcStruc);
+
+ return Status;
+}
+ //<(EIP62376)
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ExecuteCommand
+//
+// Description:
+// This function places a given command in the Command Ring, rings HC doorbell,
+// and waits for the command completion.
+//
+// Output:
+// USB_ERROR on execution failure, otherwise USB_SUCCESS
+// Params - pointer to the command specific data.
+//
+// Notes:
+// Caller is responsible for a data placeholder.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ExecuteCommand(
+ HC_STRUC *HcStruc,
+ TRB_TYPE Cmd,
+ VOID *Params
+)
+{
+ volatile UINT32 *Doorbell;
+ UINT8 CompletionCode = 0;
+ UINT8 SlotId;
+ UINT8 Status;
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+ XHCI_TRB *Trb = XHCI_AdvanceEnqueuePtr(&Usb3Hc->CmdRing);
+ UINT16 TimeOut = XHCI_CMD_COMPLETE_TIMEOUT_MS;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ if (Trb == NULL) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Trb, sizeof(XHCI_TRB));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;;
+ }
+#endif
+
+ Trb->TrbType = Cmd; // Set TRB type
+
+ // Fill in the command TRB fields
+ switch (Cmd) {
+ case XhciTAddressDeviceCmd:
+ TimeOut = XHCI_ADDR_CMD_COMPLETE_TIMEOUT_MS;
+ ((XHCI_ADDRESSDEV_CMD_TRB*)Trb)->InpCtxAddress = (UINT64)(UINTN)Usb3Hc->InputContext;
+ ((XHCI_ADDRESSDEV_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ ((XHCI_ADDRESSDEV_CMD_TRB*)Trb)->Bsr = *((UINT8*)Params + 1);
+ break;
+ case XhciTEvaluateContextCmd:
+ case XhciTConfigureEndpointCmd:
+ ((XHCI_CONFIGURE_EP_CMD_TRB*)Trb)->InpCtxAddress = (UINT64)(UINTN)Usb3Hc->InputContext;
+ ((XHCI_CONFIGURE_EP_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ ((XHCI_CONFIGURE_EP_CMD_TRB*)Trb)->Dc = 0;
+ break;
+ case XhciTResetEndpointCmd:
+ ((XHCI_RESET_EP_CMD_TRB*)Trb)->Tsp = 0;
+ ((XHCI_RESET_EP_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ ((XHCI_RESET_EP_CMD_TRB*)Trb)->EndpointId = *((UINT8*)Params+1);
+ break;
+ case XhciTSetTRDequeuePointerCmd:
+ ((XHCI_SET_TRPTR_CMD_TRB*)Trb)->TrPointer = ((XHCI_SET_TRPTR_CMD_TRB*)Params)->TrPointer;
+ ((XHCI_SET_TRPTR_CMD_TRB*)Trb)->EndpointId = ((XHCI_SET_TRPTR_CMD_TRB*)Params)->EndpointId;
+ ((XHCI_SET_TRPTR_CMD_TRB*)Trb)->SlotId = ((XHCI_SET_TRPTR_CMD_TRB*)Params)->SlotId;
+ break;
+ case XhciTDisableSlotCmd:
+ ((XHCI_DISABLESLOT_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ break;
+ //(EIP54300+)>
+ case XhciTStopEndpointCmd:
+ ((XHCI_STOP_EP_CMD_TRB*)Trb)->SlotId = *((UINT8*)Params);
+ ((XHCI_STOP_EP_CMD_TRB*)Trb)->EndpointId = *((UINT8*)Params+1);
+ break;
+ //<(EIP54300+)
+ }
+
+ Trb->CycleBit = Usb3Hc->CmdRing.CycleBit;
+
+ // Ring the door bell and see Event Ring update
+ Doorbell = (UINT32*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->DbOffset);
+ *Doorbell = 0; // HC doorbell is #0
+
+ Status = XHCI_WaitForEvent(
+ HcStruc, Trb, XhciTCmdCompleteEvt, 0, 0, //(EIP62376)
+ &CompletionCode, TimeOut, &SlotId);
+
+ if (Status == USB_ERROR) {
+ USB_DEBUG(3, "XHCI command completion error code: %d\n", CompletionCode);
+ if (CompletionCode == XHCI_TRB_EXECUTION_TIMEOUT_ERROR) {
+ XHCI_Mmio64Write(HcStruc, Usb3Hc, (UINTN)&Usb3Hc->OpRegs->Crcr, CRCR_COMMAND_ABORT);
+
+ CompletionCode = XHCI_TRB_COMMANDABORTED;
+ XHCI_WaitForEvent(
+ HcStruc, Trb, XhciTCmdCompleteEvt, 0, 0,
+ &CompletionCode, XHCI_CMD_COMPLETE_TIMEOUT_MS, NULL);
+ }
+ return Status;
+ }
+
+ switch (Cmd) {
+ case XhciTEnableSlotCmd:
+ USB_DEBUG(3, "XHCI: Enable Slot command complete, SlotID %d\n", SlotId);
+ *((UINT8*)Params) = SlotId;
+ break;
+ case XhciTEvaluateContextCmd:
+ USB_DEBUG(3, "XHCI: Evaluate Context command complete.\n");
+ break;
+ case XhciTConfigureEndpointCmd:
+ USB_DEBUG(3, "XHCI: Configure Endpoint command complete.\n");
+ break;
+ case XhciTResetEndpointCmd:
+ USB_DEBUG(3, "XHCI: Reset Endpoint command complete (slot#%x dci#%x).\n",
+ *((UINT8*)Params), *((UINT8*)Params+1));
+ // Xhci speci 1.1 4.6.8 Reset Endpoint
+ // Software shall be responsible for timing the Reset "recovery interval" required by USB.
+ FixedDelay(XHCI_RESET_EP_DELAY_MS * 1000);
+ break;
+ case XhciTSetTRDequeuePointerCmd:
+ USB_DEBUG(3, "XHCI: Set TR pointer command complete.\n");
+ break;
+ case XhciTDisableSlotCmd:
+ USB_DEBUG(3, "XHCI: DisableSlot command complete.\n");
+ break;
+ //(EIP54300+)>
+ case XhciTStopEndpointCmd:
+ USB_DEBUG(3, "XHCI: Stop Endpoint command complete (slot#%x dci#%x).\n",
+ *((UINT8*)Params), *((UINT8*)Params+1));
+ break;
+ //<(EIP54300+)
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ProcessPortChanges
+//
+// Description:
+// This function process root hub port changes.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_SUCCESS or USB_ERROR
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ProcessPortChanges(
+ HC_STRUC *HcStruc,
+ USB3_HOST_CONTROLLER *Usb3Hc
+)
+{
+ UINT8 Port;
+ BOOLEAN PortChanged;
+ volatile XHCI_PORTSC *PortSC;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+
+ if (gUsbData->bEnumFlag == TRUE) return USB_SUCCESS;
+
+ gUsbData->bEnumFlag = TRUE; // disable recursive enumeration
+
+ FixedDelay(XHCI_WAIT_PORT_STABLE_DELAY_MS * 1000);
+
+ do {
+ PortChanged = FALSE;
+
+ for (Port = 1; Port <= Usb3Hc->MaxPorts; Port++) {
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (Port - 1)));
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+ if (PortSC->Field.Csc) {
+ USBCheckPortChange(HcStruc, HcStruc->bHCNumber | BIT7, Port);
+ PortChanged = TRUE;
+ }
+ }
+ } while (PortChanged);
+
+ Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_PCD; // Clear PortChangeDetect
+
+ gUsbData->bEnumFlag = FALSE; // enable enumeration
+
+ return USB_SUCCESS;
+}
+
+ //(EIP54283+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_ResetEndpoint
+//
+// Description:
+// This function is called to reset endpoint.
+//
+// Input:
+// Stalled EP data - SlotId and DCI
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ResetEndpoint(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ HC_STRUC *HcStruc,
+ UINT8 SlotId,
+ UINT8 Dci
+)
+{
+ UINT16 EpInfo;
+ UINT8 Status = USB_SUCCESS;
+ XHCI_EP_CONTEXT *EpCtx;
+
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc,
+ XHCI_GetDeviceContext(Usb3Hc, SlotId), Dci);
+
+ // The Reset Endpoint Command is issued by software to recover
+ // from a halted condition on an endpoint.
+ if (EpCtx->EpState == XHCI_EP_STATE_HALTED) {
+ // Reset stalled endpoint
+ EpInfo = (Dci << 8) + SlotId;
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTResetEndpointCmd, &EpInfo);
+ }
+ //ASSERT(Status == USB_SUCCESS);
+ return Status;
+}
+ //<(EIP54283+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_ClearStalledEp
+//
+// Description:
+// This function is called to restart endpoint. After Endpoint STALLs, it
+// transitions from Halted to Stopped state. It is restored back to Running
+// state by moving the endpoint ring dequeue pointer past the failed control
+// transfer with a Set TR Dequeue Pointer. Then it is restarted by ringing the
+// doorbell. Alternatively endpint is restarted using Configure Endpoint command.
+//
+// Input:
+// Stalled EP data - SlotId and DCI
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ClearStalledEp(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ HC_STRUC *HcStruc,
+ UINT8 SlotId,
+ UINT8 Dci
+)
+{
+ UINT16 EpInfo;
+ TRB_RING *XfrRing;
+ UINT8 Status;
+ XHCI_SET_TRPTR_CMD_TRB Trb;
+ XHCI_EP_CONTEXT *EpCtx;
+// volatile UINT32 *Doorbell; //(EIP61849-)
+
+/*
+Stalled Endpoints By Sarah Sharp, Linux XHCI driver developer
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ When a control endpoint stalls, the next control transfer will clear the stall.
+The USB core doesn't call down to the host controller driver's endpoint_reset()
+method when control endpoints stall, so the xHCI driver has to do all its stall
+handling for internal state in its interrupt handler.
+
+ When the host stalls on a control endpoint, it may stop on the data phase or
+status phase of the control transfer. Like other stalled endpoints, the xHCI
+driver needs to queue a Reset Endpoint command and move the hardware's control
+endpoint ring dequeue pointer past the failed control transfer (with a Set TR
+Dequeue Pointer or a Configure Endpoint command).
+
+ Since the USB core doesn't call usb_hcd_reset_endpoint() for control endpoints,
+we need to do this in interrupt context when we get notified of the stalled
+transfer. URBs may be queued to the hardware before these two commands complete.
+The endpoint queue will be restarted once both commands complete.
+
+ When an endpoint on a device under an xHCI host controller stalls, the host
+controller driver must let the hardware know that the USB core has successfully
+cleared the halt condition. The HCD submits a Reset Endpoint Command, which will
+clear the toggle bit for USB 2.0 devices, and set the sequence number to zero for
+USB 3.0 devices.
+
+ The xHCI urb_enqueue will accept new URBs while the endpoint is halted, and
+will queue them to the hardware rings. However, the endpoint doorbell will not
+be rung until the Reset Endpoint Command completes. Don't queue a reset endpoint
+command for root hubs. khubd clears halt conditions on the roothub during the
+initialization process, but the roothub isn't a real device, so the xHCI host
+controller doesn't need to know about the cleared halt.
+*/
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc,
+ XHCI_GetDeviceContext(Usb3Hc, SlotId), Dci);
+
+ // The Reset Endpoint Command is issued by software to recover
+ // from a halted condition on an endpoint.
+ if (EpCtx->EpState == XHCI_EP_STATE_HALTED) {
+ // Reset stalled endpoint
+ EpInfo = (Dci << 8) + SlotId;
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTResetEndpointCmd, &EpInfo);
+ }
+ //ASSERT(Status == USB_SUCCESS);
+
+ // Set TR Dequeue Pointer command may be executed only if the target
+ // endpoint is in the Error or Stopped state.
+ if ((EpCtx->EpState == XHCI_EP_STATE_STOPPED) ||
+ (EpCtx->EpState == XHCI_EP_STATE_ERROR)) {
+
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci-1);
+
+ Trb.TrPointer = (UINT64)((UINTN)XfrRing->QueuePtr + XfrRing->CycleBit); // Set up DCS
+ Trb.EndpointId = Dci;
+ Trb.SlotId = SlotId;
+
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTSetTRDequeuePointerCmd, &Trb);
+ //ASSERT(Status == USB_SUCCESS);
+ }
+
+// Doorbell = XHCI_GetTheDoorbell(Usb3Hc, SlotId); //(EIP61849-)
+// *Doorbell = Dci; //(EIP61849-)
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ProcessXferEvt
+//
+// Description:
+// This function processes a transfer event and gives control to the device
+// specific routines.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+XHCI_ProcessXferEvt(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ HC_STRUC *HcStruc,
+ XHCI_TRANSFER_EVT_TRB *XferEvtTrb
+)
+{
+ DEV_INFO *DevInfo;
+ UINT8 SlotId = XferEvtTrb->SlotId;
+ UINT8 Dci = XferEvtTrb->EndpointId;
+ XHCI_NORMAL_XFR_TRB *Trb = (XHCI_NORMAL_XFR_TRB*)XferEvtTrb->TrbPtr;
+ volatile UINT32 *Doorbell = XHCI_GetTheDoorbell(Usb3Hc, SlotId);
+ TRB_RING *XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci-1);
+ UINT16 BytesTransferred;
+ UINT8 PortStatus = USB_PORT_STAT_DEV_ENABLED;
+ UINT8 i;
+
+ DevInfo = XHCI_GetDevInfo((UINTN)Trb->DataBuffer);
+ if (DevInfo == NULL) return;
+
+ switch (XferEvtTrb->CompletionCode) {
+ case XHCI_TRB_SUCCESS:
+ case XHCI_TRB_SHORTPACKET:
+ // Check for the keyboard event
+
+ //(EIP38434+)>
+ if ((DevInfo->bCallBackIndex) &&
+ (DevInfo->bCallBackIndex <= MAX_CALLBACK_FUNCTION) &&
+ (DevInfo->fpPollTDPtr != NULL)) {
+
+ if (gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex-1]) {
+
+ if (gUsbData->ProcessingPeriodicList == FALSE) {
+ for (i = 0; i < XHCI_MAX_PENDING_INTERRUPT_TRANSFER; i++) {
+ if (Usb3Hc->PendingInterruptTransfer[i].Trb == NULL) {
+ break;
+ }
+ }
+ if (i != XHCI_MAX_PENDING_INTERRUPT_TRANSFER) {
+ Usb3Hc->PendingInterruptTransfer[i].Trb = Trb;
+ Usb3Hc->PendingInterruptTransfer[i].TransferredLength =
+ DevInfo->PollingLength - XferEvtTrb->TransferLength;
+ return;
+ }
+ }
+ //
+ // Get the size of data transferred
+ //
+ BytesTransferred = DevInfo->PollingLength - XferEvtTrb->TransferLength;
+ (*gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex-1])
+ (HcStruc, DevInfo, NULL, DevInfo->fpPollTDPtr,
+ BytesTransferred);
+ }
+ }
+ //<(EIP38434+)
+ break;
+
+ case XHCI_TRB_BABBLE_ERROR:
+ case XHCI_TRB_TRANSACTION_ERROR:
+ case XHCI_TRB_STALL_ERROR:
+ // When the device is disconnecting, the transaction will be error,
+ // we need to check the port status
+ PortStatus = USB_GetHubPortStatus(HcStruc, DevInfo->bHubDeviceNumber, DevInfo->bHubPortNumber, FALSE);
+ if (PortStatus == USB_ERROR) {
+ PortStatus = 0;
+ }
+ if (PortStatus & USB_PORT_STAT_DEV_ENABLED) {
+ XHCI_ClearStalledEp(Usb3Hc, HcStruc, SlotId, Dci);
+ }
+ break;
+ }
+ // Check if this device is still enabled
+ if ((PortStatus & USB_PORT_STAT_DEV_ENABLED) && (DevInfo->fpPollTDPtr != NULL)) {
+ Trb = (XHCI_NORMAL_XFR_TRB*)XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return;
+ }
+ Trb->TrbType = XhciTNormal;
+ Trb->DataBuffer = (UINT64)(UINTN)DevInfo->fpPollTDPtr;
+ Trb->XferLength = DevInfo->PollingLength;
+ Trb->Isp = 1; //(EIP51478+)
+ Trb->Ioc = 1;
+ Trb->CycleBit = XfrRing->CycleBit;
+
+ // Ring the door bell to start polling interrupt endpoint
+ *Doorbell = Dci;
+ }
+}
+
+ //(EIP60460+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ProcessPortStsChgEvt
+//
+// Description:
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+XHCI_ProcessPortStsChgEvt(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ HC_STRUC *HcStruc,
+ XHCI_PORTSTSCHG_EVT_TRB *PortStsChgEvtTrb
+)
+{
+ volatile XHCI_PORTSC *PortSC;
+ DEV_INFO *DevInfo;
+ UINT8 i;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ if (((Usb3Hc->Vid != XHCI_FL100X_VID) || (Usb3Hc->Did != XHCI_FL1000_DID &&
+ Usb3Hc->Did != XHCI_FL1009_DID)) && (Usb3Hc->Vid != XHCI_INTEL_VID)) {
+ return;
+ }
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortStsChgEvtTrb->PortId - 1)));
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return;
+ }
+#endif
+
+ if (PortSC->Field.Csc && PortSC->Field.Ccs == 0) {
+ for (i = 1; i < MAX_DEVICES; i++) {
+ DevInfo = &gUsbData->aDevInfoTable[i];
+ if ((DevInfo->Flag & DEV_INFO_VALIDPRESENT)
+ != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+ if ((DevInfo->bHubDeviceNumber == (HcStruc->bHCNumber | BIT7)) &&
+ DevInfo->bHubPortNumber == PortStsChgEvtTrb->PortId) {
+ DevInfo->Flag |= DEV_INFO_DEV_DISCONNECTING;
+ }
+ }
+ }
+}
+ //<(EIP60460+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XHCI_ProcessInterrupt
+//
+// Description: This is the XHCI controller event handler. It walks through
+// the Event Ring and executes the event associated code if needed. Updates
+// the Event Ring Data Pointer in the xHC to let it know which events are
+// completed.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_ERROR - Need more Interrupt processing
+// USB_SUCCESS - No interrupts pending
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ProcessInterrupt(
+ HC_STRUC *HcStruc
+)
+{
+ XHCI_TRB *Trb;
+ UINTN XhciBaseAddress;
+ UINT32 Imod;
+ UINT8 i;
+ UINT8 SlotId;
+ UINT8 Dci;
+ volatile UINT32 *Doorbell;
+ TRB_RING *XfrRing;
+ DEV_INFO *DevInfo;
+ XHCI_NORMAL_XFR_TRB *XfrTrb;
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (!(ReadPCIConfig(HcStruc->wBusDevFuncNum, USB_REG_COMMAND) & BIT1)) {
+ return USB_SUCCESS;
+ }
+
+ XhciBaseAddress = ReadPCIConfig(HcStruc->wBusDevFuncNum, USB_MEM_BASE_ADDRESS);
+ if (((XhciBaseAddress & (BIT1 | BIT2)) == BIT2) && ((sizeof(VOID*) / sizeof(UINT32) == 2))){
+ XhciBaseAddress |= Shl64((UINTN)ReadPCIConfig(HcStruc->wBusDevFuncNum,
+ USB_MEM_BASE_ADDRESS + 0x04), 32);
+ }
+
+ XhciBaseAddress &= ~(0x7F);
+
+ if (XhciBaseAddress != (UINTN)Usb3Hc->CapRegs) {
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)XhciBaseAddress, HcStruc->BaseAddressSize);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Usb Mmio address is invalid, it is in SMRAM\n");
+ return USB_ERROR;
+ }
+#endif
+ HcStruc->BaseAddress = XhciBaseAddress;
+ (UINTN)Usb3Hc->CapRegs = XhciBaseAddress;
+ Usb3Hc->OpRegs = (XHCI_HC_OP_REGS*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->CapRegs->CapLength);
+ Usb3Hc->RtRegs = (XHCI_HC_RT_REGS*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->CapRegs->RtsOff);
+ XhciExtCapParser(Usb3Hc);
+ }
+
+ // Check if host controller interface version number is valid.
+ if (Usb3Hc->CapRegs->HciVersion == 0xFFFF) {
+ return USB_SUCCESS;
+ }
+
+ // Check if USB Legacy Support Capability is present.
+ if (Usb3Hc->ExtLegCap) {
+ // Is ownership change?
+ if((Usb3Hc->ExtLegCap->LegCtlSts.UsbOwnershipChangeSmi == 1) &&
+ (Usb3Hc->ExtLegCap->LegCtlSts.UsbOwnershipChangeSmiEnable==1) ) {
+ // Clear Ownership change SMI status
+ Usb3Hc->ExtLegCap->LegCtlSts.UsbOwnershipChangeSmi = 1;
+ // Process ownership change event
+ if (Usb3Hc->ExtLegCap->LegSup.HcOsOwned == 1 &&
+ HcStruc->dHCFlag & HC_STATE_RUNNING) {
+ gUsbData->dUSBStateFlag &= (~USB_FLAG_ENABLE_BEEP_MESSAGE);
+ USB_DEBUG(3, "XHCI: Ownership change to XHCD\n");
+ XHCI_Stop(HcStruc);
+ } else if (Usb3Hc->ExtLegCap->LegSup.HcOsOwned == 0 &&
+ (HcStruc->dHCFlag & HC_STATE_RUNNING) == 0) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_ENABLE_BEEP_MESSAGE;
+ USB_DEBUG(3, "XHCI: Ownership change to BIOS\n");
+ XHCI_Start(HcStruc);
+ XHCI_EnumeratePorts(HcStruc);
+ }
+ return USB_SUCCESS;
+ }
+ }
+
+ if ((HcStruc->dHCFlag & HC_STATE_RUNNING) == 0) return USB_SUCCESS;
+
+ if ((UINT32)Usb3Hc->OpRegs->DcbAap != (UINT32)Usb3Hc->DcbaaPtr) return USB_SUCCESS;
+
+ if (gUsbData->ProcessingPeriodicList == TRUE) {
+ for (i = 0; i < XHCI_MAX_PENDING_INTERRUPT_TRANSFER; i++) {
+ if (Usb3Hc->PendingInterruptTransfer[i].Trb != NULL) {
+ DevInfo = XHCI_GetDevInfo((UINTN)Usb3Hc->PendingInterruptTransfer[i].Trb->DataBuffer);
+ if (DevInfo == NULL) {
+ continue;
+ }
+ if ((DevInfo->bCallBackIndex) &&
+ (DevInfo->bCallBackIndex <= MAX_CALLBACK_FUNCTION) &&
+ (DevInfo->fpPollTDPtr != NULL)) {
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ continue;
+ }
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ Dci = (DevInfo->IntInEndpoint & 0xF) * 2;
+
+ if (DevInfo->IntInEndpoint & BIT7) {
+ Dci++;
+ }
+
+ Doorbell = XHCI_GetTheDoorbell(Usb3Hc, SlotId);
+
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci - 1);
+
+ Usb3Hc->PendingInterruptTransfer[i].Trb = NULL;
+
+ if ((DevInfo->bCallBackIndex) && (DevInfo->fpPollTDPtr != NULL)) {
+ (*gUsbData->aCallBackFunctionTable[DevInfo->bCallBackIndex - 1])
+ (HcStruc, DevInfo, NULL, DevInfo->fpPollTDPtr,
+ Usb3Hc->PendingInterruptTransfer[i].TransferredLength);
+
+ XfrTrb = (XHCI_NORMAL_XFR_TRB*)XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (XfrTrb == NULL) {
+ continue;
+ }
+ XfrTrb->TrbType = XhciTNormal;
+ XfrTrb->DataBuffer = (UINT64)(UINTN)DevInfo->fpPollTDPtr;
+ XfrTrb->XferLength = DevInfo->PollingLength;
+ XfrTrb->Isp = 1;
+ XfrTrb->Ioc = 1;
+ XfrTrb->CycleBit = XfrRing->CycleBit;
+ // Ring the door bell to start polling interrupt endpoint
+ *Doorbell = Dci;
+ }
+ } else {
+ Usb3Hc->PendingInterruptTransfer[i].Trb = NULL;
+ }
+ }
+ }
+ }
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.Pcd) {
+ //XHCI_EnumeratePorts(HcStruc);
+ XHCI_ProcessPortChanges(HcStruc, Usb3Hc);
+ }
+
+// if (Usb3Hc->OpRegs->UsbSts.Field.Eint == 0) return USB_SUCCESS;
+// Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_EVT_INTERRUPT; // Clear event interrupt
+ if (Usb3Hc->OpRegs->UsbSts.Field.Eint) {
+ Usb3Hc->OpRegs->UsbSts.AllBits = XHCI_STS_EVT_INTERRUPT;
+ if ((gUsbData->fpKeyRepeatHCStruc == HcStruc) && (gUsbData->ProcessingPeriodicList == TRUE)) {
+ Imod = Usb3Hc->RtRegs->IntRegs[0].IMod;
+ if ((Imod & XHCI_KEYREPEAT_IMODI) == XHCI_KEYREPEAT_IMODI) {
+ USBKBDPeriodicInterruptHandler(HcStruc);
+ }
+ }
+ }
+
+ // Check for pending interrupts:
+ // check the USBSTS[3] and IMAN [0] to determine if any interrupt generated
+ if (Usb3Hc->EvtRing.QueuePtr->CycleBit != Usb3Hc->EvtRing.CycleBit) {
+ if (gUsbData->fpKeyRepeatHCStruc == HcStruc) {
+ Imod = Usb3Hc->RtRegs->IntRegs[0].IMod;
+ if ((Imod & XHCI_KEYREPEAT_IMODI) == XHCI_KEYREPEAT_IMODI) {
+ Usb3Hc->RtRegs->IntRegs[0].IMan |= BIT0;
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)0 | BIT3);
+ } else {
+ Usb3Hc->RtRegs->IntRegs[0].IMan |= BIT0;
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr | BIT3);
+ }
+ } else {
+ Usb3Hc->RtRegs->IntRegs[0].IMan |= BIT0;
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr | BIT3);
+ }
+ return USB_SUCCESS;
+ }
+
+ // See if there are any TRBs waiting in the event ring
+ //for (Count = 0; Count < Usb3Hc->EvtRing.Size; Count++) {
+ for (;;) {
+ Trb = Usb3Hc->EvtRing.QueuePtr;
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Trb, sizeof(XHCI_TRB));
+ if (EFI_ERROR(EfiStatus)) {
+ break;
+ }
+#endif
+ if (Trb->CycleBit != Usb3Hc->EvtRing.CycleBit) break; // past the last
+
+ if (Usb3Hc->EvtRing.QueuePtr == Usb3Hc->EvtRing.LastTrb) {
+ // Reached the end of the ring, wrap around
+ Usb3Hc->EvtRing.QueuePtr = Usb3Hc->EvtRing.Base;
+ Usb3Hc->EvtRing.CycleBit ^= 1;
+ } else {
+ Usb3Hc->EvtRing.QueuePtr++;
+ }
+ // error manager
+ if (Trb->CompletionCode == XHCI_TRB_SHORTPACKET) {
+ USB_DEBUG(3, "XHCI: short packet detected.");
+ }
+
+ if (Trb->CompletionCode == XHCI_TRB_STALL_ERROR) {
+ USB_DEBUG(3, "XHCI: device STALLs.");
+ }
+
+ if (Trb->CompletionCode != XHCI_TRB_SUCCESS
+ && Trb->CompletionCode != XHCI_TRB_STALL_ERROR
+ && Trb->CompletionCode != XHCI_TRB_SHORTPACKET) {
+ USB_DEBUG(3, "Trb completion code: %d\n", Trb->CompletionCode);
+ //ASSERT(FALSE);
+ }
+
+ switch (Trb->TrbType) {
+ case XhciTTransferEvt:
+// very frequent, debug message here might affect timings,
+// uncomment only when needed
+// USB_DEBUG(3, "TransferEvt\n");
+ XHCI_ProcessXferEvt(Usb3Hc, HcStruc, (XHCI_TRANSFER_EVT_TRB*)Trb);
+ break;
+ case XhciTCmdCompleteEvt:
+ USB_DEBUG(3, "CmdCompleteEvt\n");
+ break;
+ case XhciTPortStatusChgEvt:
+ USB_DEBUG(3, "PortStatusChgEvt, port #%d\n", ((XHCI_PORTSTSCHG_EVT_TRB*)Trb)->PortId);
+ XHCI_ProcessPortStsChgEvt(Usb3Hc, HcStruc, (XHCI_PORTSTSCHG_EVT_TRB*)Trb); //(EIP60460+)
+ break;
+ case XhciTDoorbellEvt:
+ USB_DEBUG(3, "DoorbellEvt\n");
+ break;
+ case XhciTHostControllerEvt:
+ USB_DEBUG(3, "HostControllerEvt\n");
+ break;
+ case XhciTDevNotificationEvt:
+ USB_DEBUG(3, "DevNotificationEvt\n");
+ break;
+ case XhciTMfIndexWrapEvt:
+ USB_DEBUG(3, "MfIndexWrapEvt\n");
+ break;
+ default:
+ USB_DEBUG(3, "UNKNOWN EVENT\n");
+ }
+ }
+ //ASSERT(Count<Usb3Hc->EvtRing.Size); // Event ring is full
+
+ // Update ERDP to inform xHC that we have processed another TRB
+ if ((gUsbData->fpKeyRepeatHCStruc == HcStruc) &&
+ ((Usb3Hc->RtRegs->IntRegs[0].IMod & XHCI_KEYREPEAT_IMODI) == XHCI_KEYREPEAT_IMODI)) {
+ Usb3Hc->RtRegs->IntRegs[0].IMan |= BIT0;
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)0 | BIT3);
+ } else {
+ Usb3Hc->RtRegs->IntRegs[0].IMan |= BIT0;
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr | BIT3);
+ }
+
+ return USB_SUCCESS; // Set as interrupt processed
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_GetRootHubStatus
+//
+// Description:
+// This function returns the port connect status for the root hub port
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// PortNum - Port in the HC whose status is requested
+//
+// Output:
+// Port status flags (see USB_PORT_STAT_XX equates)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_GetRootHubStatus(
+ HC_STRUC* HcStruc,
+ UINT8 PortNum,
+ BOOLEAN ClearChangeBits
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ volatile XHCI_PORTSC *PortSC;
+ UINT32 i;
+ UINT32 PortStCtl;
+ UINT8 PortStatus = USB_PORT_STAT_DEV_OWNER;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ // Find the proper MMIO access offset for a given port
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNum-1)));
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+
+ USB_DEBUG(3, "XHCI port[%d] status: %08x\n", PortNum, PortSC->AllBits);
+
+ for (i = 0; i < 200; i++) {
+ if (PortSC->Field.Pr == 0) break;
+ FixedDelay(1 * 1000);
+ }
+
+ switch (PortSC->Field.Pls) {
+ case XHCI_PORT_LINK_U0:
+ case XHCI_PORT_LINK_RXDETECT:
+ break;
+ case XHCI_PORT_LINK_RECOVERY:
+ for (i = 0; i < 200; i++) {
+ FixedDelay(1 * 1000);
+ if (PortSC->Field.Pls != XHCI_PORT_LINK_RECOVERY) {
+ break;
+ }
+ }
+ break;
+ case XHCI_PORT_LINK_POLLING:
+ if (!XHCI_IsUsb3Port(Usb3Hc, PortNum)) {
+ break;
+ }
+ for (i = 0; i < 500; i++) {
+ FixedDelay(1 * 1000);
+ if (PortSC->Field.Pls != XHCI_PORT_LINK_POLLING) {
+ break;
+ }
+ }
+ if (PortSC->Field.Pls == XHCI_PORT_LINK_U0 ||
+ PortSC->Field.Pls == XHCI_PORT_LINK_RXDETECT) {
+ break;
+ }
+ XHCI_ResetPort(Usb3Hc, PortNum, TRUE);
+ break;
+ case XHCI_PORT_LINK_INACTIVE:
+ for (i = 0; i < 12; i++) {
+ FixedDelay(1 * 1000);
+ if (PortSC->Field.Pls != XHCI_PORT_LINK_INACTIVE) {
+ break;
+ }
+ }
+ if (PortSC->Field.Pls == XHCI_PORT_LINK_RXDETECT) {
+ break;
+ }
+ case XHCI_PORT_LINK_COMPLIANCE_MODE:
+ XHCI_ResetPort(Usb3Hc, PortNum, TRUE);
+ break;
+ default:
+ PortStatus |= USB_PORT_STAT_DEV_CONNECTED;
+ break;
+ }
+
+ if (PortSC->Field.Ccs != 0) {
+ PortStatus |= USB_PORT_STAT_DEV_CONNECTED;
+ UpdatePortStatusSpeed(PortSC->Field.PortSpeed, &PortStatus);
+
+ // USB 3.0 device may not set Connect Status Change bit after reboot,
+ // set the connect change flag when we enumerate HC ports for devices.
+ if (gUsbData->bIgnoreConnectStsChng == TRUE) {
+ PortStatus |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ }
+
+ if (PortSC->Field.Ped) {
+ PortStatus |= USB_PORT_STAT_DEV_ENABLED;
+ }
+ }
+
+ if (PortSC->Field.Csc != 0) {
+ PortStatus |= USB_PORT_STAT_DEV_CONNECT_CHANGED;
+ // Clear connect status change bit
+ if (ClearChangeBits == TRUE) {
+ PortSC->AllBits = XHCI_PCS_CSC | XHCI_PCS_PP;
+ }
+ }
+
+ // Clear all status change bits
+ if (ClearChangeBits == TRUE) {
+ PortStCtl = PortSC->AllBits;
+ PortSC->AllBits = PortStCtl & ~XHCI_PCS_PED; // DO NOT TOUCH PED
+ }
+
+ return PortStatus;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_EnableRootHub
+//
+// Description:
+// This function enables the XHCI HC Root hub port.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// PortNum - Port in the HC to enable
+//
+// Output:
+// USB_SUCCESS on success, USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_EnableRootHub(
+ HC_STRUC* HcStruc,
+ UINT8 PortNum
+)
+{
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_DisableRootHub
+//
+// Description:
+// This function disables the XHCI HC Root hub port.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// PortNum - Port in the HC to disable
+//
+// Output:
+// USB_SUCCESS on success, USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_DisableRootHub(
+ HC_STRUC *HcStruc,
+ UINT8 PortNum
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ volatile XHCI_PORTSC *PortSC = NULL;
+ UINT8 i = 0;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+USB_DEBUG(3, "Disable XHCI root port %d\n", PortNum);
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (PortNum - 1)));
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+
+ if (PortSC->Field.Ped) {
+ if (XHCI_IsUsb3Port(Usb3Hc, PortNum)) {
+ XHCI_ResetPort(Usb3Hc, PortNum, FALSE);
+ } else {
+ PortSC->AllBits = XHCI_PCS_PED | XHCI_PCS_PP;
+ for (i = 0; i < 200; i++) {
+ if (PortSC->Field.Ped == 0) {
+ break;
+ }
+ FixedDelay(100);
+ }
+ }
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ResetPort
+//
+// Description:
+// This function resets the XHCI HC Root hub port.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// PortNum - Port in the HC to disable
+//
+// Output:
+// USB_SUCCESS on success, USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ResetPort(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINT8 Port,
+ BOOLEAN WarmReset
+)
+{
+ volatile XHCI_PORTSC *PortSC;
+ UINT32 i;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (Port - 1)));
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+
+ if (WarmReset && XHCI_IsUsb3Port(Usb3Hc, Port)) {
+ PortSC->AllBits = XHCI_PCS_WPR | XHCI_PCS_PP;
+
+ for (i = 0; i < 6000; i++) { //(EIP93368)
+ if (PortSC->Field.Wrc || PortSC->Field.Prc) {
+ break;
+ }
+ FixedDelay(100);
+ }
+ //ASSERT(PortSC->Field.Wrc || PortSC->Field.Prc);
+ if (PortSC->Field.Wrc == 0 && PortSC->Field.Prc == 0) {
+ return USB_ERROR;
+ }
+
+ if (Usb3Hc->Vid == XHCI_EJ168A_VID && Usb3Hc->Did == XHCI_EJ168A_DID) {
+ FixedDelay(20 * 1000);
+ }
+ } else {
+ PortSC->AllBits = XHCI_PCS_PR | XHCI_PCS_PP; // Keep port power bit
+
+ for (i = 0; i < 3000; i++) {
+ if (PortSC->Field.Prc) break;
+ FixedDelay(100);
+ }
+ //ASSERT(PortSC->Field.Prc);
+ if (PortSC->Field.Prc == 0) {
+ return USB_ERROR;
+ }
+ }
+
+ // Clear Warm Port Reset Change and Port Reset Change bits
+ PortSC->AllBits = XHCI_PCS_WRC | XHCI_PCS_PRC | XHCI_PCS_PP;
+ // The USB System Software guarantees a minimum of 10 ms for reset recovery.
+ FixedDelay(XHCI_RESET_PORT_DELAY_MS * 1000);
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ResetRootHub
+//
+// Description:
+// This function resets the XHCI HC Root hub port.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// PortNum - Port in the HC to disable
+//
+// Output:
+// USB_SUCCESS on success, USB_ERROR on error
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ResetRootHub(
+ HC_STRUC* HcStruc,
+ UINT8 PortNum
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ UINT8 Status;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ Status = XHCI_ResetPort(Usb3Hc, PortNum, FALSE);
+
+ if (!XHCI_IsUsb3Port(Usb3Hc, PortNum)) {
+ // After a short delay, SS device that was originally connected to HS port
+ // might get reconnected to the SS port...
+ FixedDelay(XHCI_SWITCH2SS_DELAY_MS * 1000);
+ }
+
+ return Status;
+}
+
+ //(EIP54018+)>
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: XHCI_GlobalSuspend
+//
+// Description:
+// This function suspend the XHCI HC.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_GlobalSuspend(
+ HC_STRUC* HcStruc
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ volatile XHCI_PORTSC *PortSC;
+ UINT32 Port;
+ UINT32 i;
+ UINT32 PortStCtl;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ for (Port = 1; Port <= Usb3Hc->MaxPorts; Port++) {
+
+ PortSC = (XHCI_PORTSC*)((UINTN)Usb3Hc->OpRegs +
+ XHCI_PORTSC_OFFSET + (0x10 * (Port - 1)));
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMmioBuffer((VOID*)PortSC, sizeof(XHCI_PORTSC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+#endif
+
+ USB_DEBUG(3, "XHCI port[%d] status: %08x\n", Port, PortSC->AllBits);
+ if ((PortSC->Field.Ped) && (PortSC->Field.Pls <XHCI_PORT_LINK_U3)){
+ PortStCtl = PortSC->AllBits;
+ PortStCtl |= (XHCI_PCS_LWS | (UINT32)(XHCI_PORT_LINK_U3 << 5));
+ PortSC->AllBits = PortStCtl & ~XHCI_PCS_PED;
+ for (i = 0;i < 10; i++) {
+ if (PortSC->Field.Pls == XHCI_PORT_LINK_U3) break;
+ FixedDelay(1 * 1000);
+ }
+ }
+ }
+
+
+ Usb3Hc->OpRegs->UsbCmd.AllBits &= ~XHCI_CMD_RS;
+
+ for (i = 0; i < 16; i++) {
+ FixedDelay(1 * 1000);
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) break;
+ }
+
+ HcStruc->dHCFlag &= ~(HC_STATE_RUNNING);
+ HcStruc->dHCFlag |= HC_STATE_SUSPEND;
+
+ return USB_SUCCESS;
+}
+ //<(EIP54018+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_UpdateEp0MaxPacket
+//
+// Description:
+// This function verifies the MaxPacket size of the control pipe. If it does
+// not match the one received as a part of GET_DESCRIPTOR, then this function
+// updates the MaxPacket data in DeviceContext and HC is notified via
+// EvaluateContext command.
+//
+// Input:
+// HcStruc Pointer to the HC structure
+// Device Evaluated device context pointer
+// SlotId Device context index in DCBAA
+// Endp0MaxPacket Max packet size obtained from the device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+XHCI_UpdateEp0MaxPacket(
+ HC_STRUC *HcStruc,
+ UINT8 SlotId,
+ UINT8 Endp0MaxPacket
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+ UINT8 Status;
+ UINT8 *DevCtx;
+ XHCI_INPUT_CONTROL_CONTEXT *CtlCtx;
+ XHCI_SLOT_CONTEXT *SlotCtx;
+ XHCI_EP_CONTEXT *EpCtx;
+
+ DevCtx = (UINT8*)XHCI_GetDeviceContext(Usb3Hc, SlotId);
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, DevCtx, 0);
+ if (SlotCtx->Speed != XHCI_DEVSPEED_FULL) return;
+
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, DevCtx, 1);
+ if (EpCtx->MaxPacketSize == Endp0MaxPacket) return;
+
+ // Prepare input context for EvaluateContext comand
+ MemFill((UINT8*)Usb3Hc->InputContext, XHCI_INPUT_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ CtlCtx = (XHCI_INPUT_CONTROL_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 0);
+ CtlCtx->AddContextFlags = BIT1;
+
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 2);
+ EpCtx->MaxPacketSize = Endp0MaxPacket;
+
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTEvaluateContextCmd, &SlotId);
+ ASSERT(Status == USB_SUCCESS);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_ControlTransfer
+//
+// Description:
+// This function executes a device request command transaction on the USB.
+// One setup packet is generated containing the device request parameters
+// supplied by the caller. The setup packet may be followed by data in or
+// data out packets containing data sent from the host to the device or
+// vice-versa. This function will not return until the request either completes
+// successfully or completes in error (due to time out, etc.)
+//
+// Input:
+// HcStruc Pointer to the HC structure
+// DevInfo DeviceInfo structure (if available else 0)
+// Request Request type (low byte)
+// Bit 7 : Data direction
+// 0 = Host sending data to device
+// 1 = Device sending data to host
+// Bit 6-5 : Type
+// 00 = Standard USB request
+// 01 = Class specific
+// 10 = Vendor specific
+// 11 = Reserved
+// Bit 4-0 : Recipient
+// 00000 = Device
+// 00001 = Interface
+// 00010 = Endpoint
+// 00100 - 11111 = Reserved
+// Request code, a one byte code describing the actual
+// device request to be executed (ex: Get Configuration,
+// Set Address, etc.)
+// Index wIndex request parameter (meaning varies)
+// Value wValue request parameter (meaning varies)
+// Buffer Buffer containing data to be sent to the device or buffer
+// to be used to receive data
+// Length wLength request parameter, number of bytes of data to be
+// transferred in or out of the host controller
+//
+// Output:
+// Number of bytes actually transferred
+//
+// Notes:
+// DevInfo->DevMiscInfo points to the device context
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+XHCI_ControlTransfer (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT16 Request,
+ UINT16 Index,
+ UINT16 Value,
+ UINT8 *Buffer,
+ UINT16 Length
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ XHCI_TRB *Trb;
+ UINT8 SlotId;
+ UINT8 CompletionCode;
+ UINT8 Status;
+ TRB_RING *XfrRing;
+ UINT16 TimeoutMs;
+ XHCI_SLOT_CONTEXT *SlotCtx = NULL;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ if (Length != 0) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Buffer, Length);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Xhci ControlTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return 0;
+ }
+
+ ASSERT(DevInfo != NULL);
+
+ if(DevInfo->Flag & DEV_INFO_DEV_DISCONNECTING) return 0; //(EIP60460+)
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return 0;
+ }
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+
+ // Skip SET_ADDRESS request if device is in addressed state
+ if (Request == USB_RQ_SET_ADDRESS) {
+ SlotCtx = XHCI_GetContextEntry(Usb3Hc, DevInfo->DevMiscInfo, 0);
+
+ if (SlotCtx->SlotState == XHCI_SLOT_STATE_DEFAULT) {
+ Status = XhciAddressDevice(HcStruc, DevInfo, SlotId);
+ }
+ return Length;
+ }
+
+ TimeoutMs = gUsbData->wTimeOutValue != 0 ? XHCI_CTL_COMPLETE_TIMEOUT_MS : 0;
+
+ gUsbData->bLastCommandStatus &= ~(USB_CONTROL_STALLED);
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ // Insert Setup, Data(if needed), and Status TRBs into the transfer ring
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, 0);
+
+ // Setup TRB
+ Trb = XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return 0;
+ }
+ Trb->TrbType = XhciTSetupStage;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Idt = 1;
+ *(UINT16*)&((XHCI_SETUP_XFR_TRB*)Trb)->bmRequestType = Request;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->wValue = Value;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->wIndex = Index;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->wLength = Length;
+ ((XHCI_SETUP_XFR_TRB*)Trb)->XferLength = 8;
+
+ if (Usb3Hc->HciVersion >= 0x100) {
+ if (Length != 0) {
+ if (Request & USB_REQ_TYPE_INPUT) {
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Trt = XHCI_XFER_TYPE_DATA_IN;
+ } else {
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Trt = XHCI_XFER_TYPE_DATA_OUT;
+ }
+ } else {
+ ((XHCI_SETUP_XFR_TRB*)Trb)->Trt = XHCI_XFER_TYPE_NO_DATA;
+ }
+ }
+ ((XHCI_SETUP_XFR_TRB*)Trb)->CycleBit = XfrRing->CycleBit;
+
+ // Data TRB
+ if (Length != 0) {
+ Trb = XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return 0;
+ }
+ Trb->TrbType = XhciTDataStage;
+ ((XHCI_DATA_XFR_TRB*)Trb)->Dir = ((Request & USB_REQ_TYPE_INPUT) != 0)? 1 : 0;
+ ((XHCI_DATA_XFR_TRB*)Trb)->XferLength = Length;
+ ((XHCI_DATA_XFR_TRB*)Trb)->DataBuffer = (UINT64)(UINTN)Buffer;
+ ((XHCI_DATA_XFR_TRB*)Trb)->CycleBit = XfrRing->CycleBit;
+ }
+
+ // Status TRB
+ Trb = XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return 0;
+ }
+ Trb->TrbType = XhciTStatusStage;
+ ((XHCI_STATUS_XFR_TRB*)Trb)->Ioc = 1;
+ if ((Request & USB_REQ_TYPE_INPUT) == 0) {
+ ((XHCI_STATUS_XFR_TRB*)Trb)->Dir = 1; // Status is IN
+ }
+ ((XHCI_STATUS_XFR_TRB*)Trb)->CycleBit = XfrRing->CycleBit;
+
+ // Ring the doorbell and see Event Ring update
+ Status = XhciRingDoorbell(Usb3Hc, SlotId, 1);
+
+ if (Status != USB_SUCCESS) {
+ return 0;
+ }
+
+ Status = XHCI_WaitForEvent(
+ HcStruc, Trb, XhciTTransferEvt, SlotId, 1, //(EIP62376)
+ &CompletionCode, TimeoutMs, NULL);
+
+ if (Status != USB_SUCCESS) {
+ //(EIP54283)>
+ switch (CompletionCode) {
+ case XHCI_TRB_BABBLE_ERROR: //(EIP62376+)
+ case XHCI_TRB_TRANSACTION_ERROR:
+ XHCI_ClearStalledEp(Usb3Hc, HcStruc, SlotId, 1); //(EIP60460+)
+ break; //(EIP60460+)
+ case XHCI_TRB_STALL_ERROR:
+ XHCI_ClearStalledEp(Usb3Hc, HcStruc, SlotId, 1);
+ gUsbData->bLastCommandStatus |= USB_CONTROL_STALLED;
+ break;
+ //(EIP84790+)>
+ case XHCI_TRB_EXECUTION_TIMEOUT_ERROR:
+ XHCI_ClearEndpointState(HcStruc, DevInfo, 0);
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ break;
+ //<(EIP84790+)
+ default:
+ break;
+ }
+ //<(EIP54283)
+ return 0;
+ }
+
+ if (Request == USB_RQ_GET_DESCRIPTOR && Length == 8) {
+ // Full speed device requires the update of MaxPacket size
+ XHCI_UpdateEp0MaxPacket(HcStruc, SlotId, ((DEV_DESC*)Buffer)->MaxPacketSize0);
+ }
+
+
+ if ((Request == (UINT16)(ENDPOINT_CLEAR_PORT_FEATURE)) && (Length == 0) &&
+ (Value == (UINT16)ENDPOINT_HALT) && (Buffer == NULL)) {
+ XHCI_ClearEndpointState(HcStruc, DevInfo, (UINT8)Index);
+ }
+
+ return Length;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_BulkTransfer
+//
+// Description:
+// This function executes a bulk transaction on the USB
+//
+// Input:
+// HcStruc Pointer to HCStruc of the host controller
+// DevInfo DeviceInfo structure (if available else 0)
+// XferDir Transfer direction
+// Bit 7: Data direction
+// 0 Host sending data to device
+// 1 Device sending data to host
+// Bit 6-0 : Reserved
+// Buffer Buffer containing data to be sent to the device or buffer to
+// be used to receive data value
+// Length Length request parameter, number of bytes of data to be
+// transferred in or out of the HC
+//
+// Output:
+// Amount of data transferred
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32
+XHCI_BulkTransfer(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 XferDir,
+ UINT8 *Buffer,
+ UINT32 Length
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ XHCI_TRB *Trb;
+ XHCI_TRB *FirstTrb;
+ UINT8 SlotId;
+ UINT8 CompletionCode;
+ UINT8 Status;
+ TRB_RING *XfrRing;
+ UINT8 Endpoint;
+ UINT8 Dci;
+ UINT64 DataPointer;
+ UINT32 ResidualData; // Transferred amount return by Transfer Event
+ UINT32 TransferredSize; // Total transfer amount
+ UINT32 RingDataSize; // One TRB ring transfer amount
+ UINT32 RemainingXfrSize;
+ UINT32 RemainingDataSize;
+ UINT32 XfrSize;
+ UINT32 XfrTdSize;
+ UINT16 MaxPktSize;
+ UINT32 TdSize;
+ UINT16 TimeoutMs;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Buffer, Length);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Xhci BulkTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+ // Clear HW source of error
+ gUsbData->bLastCommandStatus &= ~(USB_BULK_STALLED | USB_BULK_TIMEDOUT );
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ if(DevInfo->Flag & DEV_INFO_DEV_DISCONNECTING) return 0; //(EIP60460+)
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return 0;
+ };
+
+ TimeoutMs = gUsbData->wTimeOutValue;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return 0;
+ }
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ Endpoint = (XferDir & BIT7)? DevInfo->bBulkInEndpoint : DevInfo->bBulkOutEndpoint;
+ MaxPktSize = (XferDir & BIT7)? DevInfo->wBulkInMaxPkt : DevInfo->wBulkOutMaxPkt;
+ Dci = (Endpoint & 0xf)* 2;
+ if (XferDir & BIT7) Dci++;
+
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci-1);
+
+ // Make a chain of TDs to transfer the requested amount of data. If necessary,
+ // make multiple transfers in a loop.
+
+ DataPointer = (UINT64)(UINTN)Buffer;
+ RemainingDataSize = Length;
+
+ // Two loops are executing the transfer:
+ // The inner loop creates a transfer ring of chained TDs, XHCI_BOT_TD_MAXSIZE
+ // bytes each. This makes a ring capable of transferring
+ // XHCI_BOT_TD_MAXSIZE * (TRBS_PER_SEGMENT-1) bytes.
+ // The outter loop repeats the transfer if the requested transfer size exceeds
+ // XHCI_BOT_TD_MAXSIZE * (TRBS_PER_SEGMENT-1).
+
+ for (TransferredSize = 0; TransferredSize < Length;) {
+ // Calculate the amount of data to transfer in the ring
+ RingDataSize = (RemainingDataSize > XHCI_BOT_MAX_XFR_SIZE)?
+ XHCI_BOT_MAX_XFR_SIZE : RemainingDataSize;
+
+ RemainingXfrSize = RingDataSize;
+
+ for (Trb = NULL, XfrSize = 0, FirstTrb = 0; XfrSize < RingDataSize;)
+ {
+ Trb = XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return 0;
+ }
+ if (FirstTrb == NULL) FirstTrb = Trb;
+
+ Trb->TrbType = XhciTNormal;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Isp = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->DataBuffer = DataPointer;
+
+ // See if we need a TD chain. Note that we do not need to
+ // place the chained TRB into Event Ring, since we will not be
+ // looking for it anyway. Set IOC only for the last-in-chain TRB.
+ if (RemainingXfrSize > XHCI_BOT_TD_MAXSIZE) {
+ XfrTdSize = XHCI_BOT_TD_MAXSIZE;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Chain = 1;
+ } else {
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Ioc = 1;
+ XfrTdSize = RemainingXfrSize;
+ }
+ // Data buffers referenced by Transfer TRBs shall not span 64KB boundaries.
+ // If a physical data buffer spans a 64KB boundary, software shall chain
+ // multiple TRBs to describe the buffer.
+ if (XfrTdSize > (UINT32)(0x10000 - (DataPointer & (0x10000 - 1)))) {
+ XfrTdSize = (UINT32)(0x10000 - (DataPointer & (0x10000 - 1)));
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Chain = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Ioc = 0;
+ }
+
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->XferLength = XfrTdSize;
+
+ XfrSize += XfrTdSize;
+ DataPointer += XfrTdSize;
+ RemainingXfrSize -= XfrTdSize;
+
+ if(Usb3Hc->HciVersion >= 0x100) {
+ TdSize = 0;
+ if (RemainingXfrSize != 0) {
+ TdSize = RemainingXfrSize/MaxPktSize;
+ if (RemainingXfrSize % MaxPktSize) {
+ TdSize++;
+ }
+ TdSize = (TdSize > 31)? 31 : TdSize;
+ }
+ } else {
+ TdSize = RemainingXfrSize + XfrTdSize;
+ TdSize = (TdSize < 32768)? (TdSize >> 10) : 31;
+ }
+
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->TdSize = TdSize;
+ if (Trb != FirstTrb) {
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->CycleBit = XfrRing->CycleBit;
+ }
+ }
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)XfrRing->LastTrb, sizeof(XHCI_NORMAL_XFR_TRB));
+ if (EFI_ERROR(EfiStatus)) {
+ break;
+ }
+#endif
+ // If transfer ring crossed Link TRB, set its Chain flag
+ if (Trb < FirstTrb) {
+ ((XHCI_NORMAL_XFR_TRB*)XfrRing->LastTrb)->Chain = 1;
+
+ }
+
+ ((XHCI_NORMAL_XFR_TRB*)FirstTrb)->CycleBit = XfrRing->CycleBit;
+ if (Trb < FirstTrb) {
+ ((XHCI_NORMAL_XFR_TRB*)FirstTrb)->CycleBit ^= 1;
+ }
+
+ // Ring the door bell and see Event Ring update
+ Status = XhciRingDoorbell(Usb3Hc, SlotId, Dci);
+
+ if (Status != USB_SUCCESS) {
+ break;
+ }
+
+ Status = XHCI_WaitForEvent(
+ HcStruc, Trb, XhciTTransferEvt, SlotId, Dci, //(EIP62376)
+ &CompletionCode, TimeoutMs, &ResidualData);
+
+ // Clear Link TRB chain flag
+ ((XHCI_NORMAL_XFR_TRB*)XfrRing->LastTrb)->Chain = 0;
+
+ if (Status != USB_SUCCESS) {
+ //(EIP54283)>
+ switch (CompletionCode) {
+ case XHCI_TRB_BABBLE_ERROR: //(EIP62376+)
+ case XHCI_TRB_TRANSACTION_ERROR:
+ XHCI_ClearStalledEp(Usb3Hc, HcStruc, SlotId, Dci); //(EIP60460+)
+ break; //(EIP60460+)
+ case XHCI_TRB_STALL_ERROR:
+ XHCI_ResetEndpoint(Usb3Hc, HcStruc, SlotId, Dci);
+ gUsbData->bLastCommandStatus |= USB_BULK_STALLED;
+ gUsbData->dLastCommandStatusExtended |= USB_TRSFR_STALLED;
+ break;
+ case XHCI_TRB_EXECUTION_TIMEOUT_ERROR:
+ XHCI_ClearEndpointState(HcStruc, DevInfo, Endpoint | XferDir);
+ gUsbData->bLastCommandStatus |= USB_BULK_TIMEDOUT;
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT; //(EIP84790+)
+ break;
+ default:
+ break;
+ }
+ //<(EIP54283)
+ break;
+ }
+
+ TransferredSize += (RingDataSize - ResidualData);
+ if (ResidualData != 0) break; // Short packet detected, no more transfers
+ RemainingDataSize -= RingDataSize;
+ }
+
+ return TransferredSize;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_InterruptTransfer
+//
+// Description:
+// This function executes an interrupt transaction on the USB. The data
+// transfer direction is always DATA_IN. This function wil not return until
+// the request either completes successfully or completes in error (due to
+// time out, etc.)
+//
+// Input:
+// HcStruc Pointer to HCStruc of the host controller
+// DevInfo DeviceInfo structure (if available else 0)
+// EndpointAddress The destination USB device endpoint to which the device request
+// is being sent.
+// MaxPktSize Indicates the maximum packet size the target endpoint is capable
+// of sending or receiving.
+// Buffer Buffer containing data to be sent to the device or buffer to be
+// used to receive data
+// Length Length request parameter, number of bytes of data to be transferred
+//
+// Output:
+// Number of bytes transferred
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+XHCI_InterruptTransfer (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 EndpointAddress,
+ UINT16 MaxPktSize,
+ UINT8 *Buffer,
+ UINT16 Length
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ XHCI_TRB *Trb;
+ UINT8 SlotId;
+ UINT8 CompletionCode;
+ UINT8 Status;
+ TRB_RING *XfrRing;
+ UINT8 Dci;
+ UINT16 TimeoutMs;
+ UINT32 ResidualData;
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return 0;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return 0;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Buffer, Length);
+ if (EFI_ERROR(EfiStatus)) {
+ USB_DEBUG(3, "Xhci InterruptTransfer Invalid Pointer, Buffer is in SMRAM.\n");
+ return 0;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ gUsbData->dLastCommandStatusExtended = 0;
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return 0;
+ }
+
+ TimeoutMs = gUsbData->wTimeOutValue;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return 0;
+ }
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ Dci = (EndpointAddress & 0xF) * 2;
+ if (EndpointAddress & BIT7) Dci++;
+
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci-1);
+ Trb = XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return 0;
+ }
+ Trb->TrbType = XhciTNormal;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->DataBuffer = (UINTN)Buffer;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->XferLength = Length;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Isp = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Ioc = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->CycleBit = XfrRing->CycleBit;
+
+ // Ring the doorbell and see Event Ring update
+ Status = XhciRingDoorbell(Usb3Hc, SlotId, Dci);
+
+ if (Status != USB_SUCCESS) {
+ return 0;
+ }
+
+ Status = XHCI_WaitForEvent(
+ HcStruc, Trb, XhciTTransferEvt, SlotId, Dci, //(EIP62376)
+ &CompletionCode, TimeoutMs, &ResidualData);
+
+ if (Status != USB_SUCCESS) {
+ //(EIP54283)>
+ switch (CompletionCode) {
+ //(EIP62376+)>
+ case XHCI_TRB_BABBLE_ERROR:
+ case XHCI_TRB_TRANSACTION_ERROR:
+ XHCI_ClearStalledEp(Usb3Hc, HcStruc, SlotId, Dci);
+ break;
+ //<(EIP62376+)
+ case XHCI_TRB_STALL_ERROR:
+ XHCI_ResetEndpoint(Usb3Hc, HcStruc, SlotId, Dci);
+ break;
+ case XHCI_TRB_EXECUTION_TIMEOUT_ERROR:
+ XHCI_ClearEndpointState(HcStruc, DevInfo, EndpointAddress);
+ gUsbData->dLastCommandStatusExtended |= USB_TRNSFR_TIMEOUT;
+ break;
+ default:
+ break;
+ }
+ //<(EIP54283)
+ return 0;
+ } else {
+ Length = Length - (UINT16)ResidualData;
+ }
+
+ return Length;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_DeactivatePolling
+//
+// Description:
+// This function de-activates the polling QH for the requested device. The
+// device may be a USB keyboard or USB hub.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// DevInfo - Pointer to the device information structure
+//
+// Output:
+// USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_DeactivatePolling(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ UINT8 SlotId;
+ UINT8 Dci;
+ UINT16 EpInfo;
+ TRB_RING *XfrRing;
+ XHCI_SET_TRPTR_CMD_TRB Trb;
+ XHCI_EP_CONTEXT *EpCtx;
+ EFI_STATUS EfiStatus;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ if (DevInfo->fpPollTDPtr == NULL) {
+ return USB_ERROR;
+ }
+
+ USB_MemFree(DevInfo->fpPollTDPtr, GET_MEM_BLK_COUNT(DevInfo->PollingLength));
+
+ DevInfo->fpPollTDPtr = NULL;
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ Dci = (DevInfo->IntInEndpoint & 0xF) * 2;
+ if (DevInfo->IntInEndpoint & BIT7) Dci++;
+
+ EpInfo = (Dci << 8) + SlotId;
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return USB_ERROR;
+ }
+
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)DevInfo->DevMiscInfo, Dci);
+
+ if (EpCtx->EpState == XHCI_EP_STATE_RUNNING) {
+ XHCI_ExecuteCommand(HcStruc, XhciTStopEndpointCmd, &EpInfo);
+ }
+
+ // Set TR Dequeue Pointer command may be executed only if the target
+ // endpoint is in the Error or Stopped state.
+ if ((EpCtx->EpState == XHCI_EP_STATE_STOPPED) ||
+ (EpCtx->EpState == XHCI_EP_STATE_ERROR)) {
+
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci-1);
+
+ Trb.TrPointer = (UINT64)((UINTN)XfrRing->QueuePtr + XfrRing->CycleBit); // Set up DCS
+ Trb.EndpointId = Dci;
+ Trb.SlotId = SlotId;
+ XHCI_ExecuteCommand(HcStruc, XhciTSetTRDequeuePointerCmd, &Trb);
+ }
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_ActivatePolling
+//
+// Description:
+// This function activates the polling QH for the requested device. The device
+// may be a USB keyboard or USB hub.
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+// DevInfo - Pointer to the device information structure
+//
+// Output:
+// USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ActivatePolling(
+ HC_STRUC* HcStruc,
+ DEV_INFO* DevInfo
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ XHCI_TRB *Trb;
+ volatile UINT32 *Doorbell;
+ UINT8 SlotId;
+ TRB_RING *XfrRing;
+ UINT8 Dci;
+ EFI_STATUS EfiStatus;
+ UINTN DeviceContextSize;
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return USB_ERROR;
+ }
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ Dci = (DevInfo->IntInEndpoint & 0xF) * 2;
+ if (DevInfo->IntInEndpoint & BIT7) Dci++;
+ DevInfo->fpPollTDPtr = USB_MemAlloc(GET_MEM_BLK_COUNT(DevInfo->PollingLength));
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci - 1);
+
+ Trb = XHCI_AdvanceEnqueuePtr(XfrRing);
+ if (Trb == NULL) {
+ return USB_ERROR;
+ }
+ Trb->TrbType = XhciTNormal;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->DataBuffer = (UINT64)(UINTN)DevInfo->fpPollTDPtr;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->XferLength = DevInfo->PollingLength;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Isp = 1; //(EIP51478+)
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->Ioc = 1;
+ ((XHCI_NORMAL_XFR_TRB*)Trb)->CycleBit = XfrRing->CycleBit;
+
+ // Ring the door bell
+ Doorbell = XHCI_GetTheDoorbell(Usb3Hc, SlotId);
+ *Doorbell = Dci;
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: XHCI_DisableKeyRepeat
+//
+// Description:
+// This function disables the keyboard repeat rate logic
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_ERROR on error, USB_SUCCESS on success
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_DisableKeyRepeat (
+ HC_STRUC* HcStruc
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)Usb3Hc->EvtRing.QueuePtr | BIT3);
+
+ Usb3Hc->RtRegs->IntRegs[0].IMod = XHCI_IMODI;
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_EnableKeyRepeat
+//
+// Description:
+// This function disables the keyboard repeat rate logic
+//
+// Input:
+// HcStruc - Pointer to the HC structure
+//
+// Output:
+// USB_ERROR on error, USB_SUCCESS on success
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_EnableKeyRepeat(
+ HC_STRUC* HcStruc
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ XHCI_Mmio64Write(HcStruc, Usb3Hc,
+ (UINTN)&Usb3Hc->RtRegs->IntRegs->Erdp, (UINT64)(UINTN)0 | BIT3);
+
+ Usb3Hc->RtRegs->IntRegs[0].IMod = (XHCI_KEYREPEAT_IMODC << 16 | XHCI_KEYREPEAT_IMODI);
+
+ return USB_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_InitXfrRing
+//
+// Description:
+// This function initializes transfer ring of given endpoint
+//
+// Output:
+// Pointer to the transfer ring
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TRB_RING*
+XHCI_InitXfrRing(
+ USB3_HOST_CONTROLLER* Usb3Hc,
+ UINT8 Slot,
+ UINT8 Ep
+)
+{
+ TRB_RING *XfrRing = Usb3Hc->XfrRings + (Slot-1)*32 + Ep;
+ UINTN Base = Usb3Hc->XfrTrbs + ((Slot-1)*32+Ep)*RING_SIZE;
+
+ XHCI_InitRing(XfrRing, Base, TRBS_PER_SEGMENT, TRUE);
+
+ return XfrRing;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Xhci_TranslateInterval
+//
+// Description:
+// This routine calculates the Interval field to be used in device's endpoint
+// context. Interval is calculated using the following rules (Section 6.2.3.6):
+//
+// For SuperSpeed bulk and control endpoints, the Interval field shall not be
+// used by the xHC. For all other endpoint types and speeds, system software
+// shall translate the bInterval field in the USB Endpoint Descriptor to the
+// appropriate value for this field.
+//
+// For high-speed and SuperSpeed Interrupt and Isoch endpoints the bInterval
+// field the Endpoint Descriptor is computed as 125æs * 2^(bInterval-1), where
+// bInterval = 1 to 16, therefore Interval = bInterval - 1.
+//
+// For low-speed Interrupt and full-speed Interrupt and Isoch endpoints the
+// bInterval field declared by a Full or Low-speed device is computed as
+// bInterval * 1ms., where bInterval = 1 to 255.
+//
+// For Full- and Low-speed devices software shall round the value of Endpoint
+// Context Interval field down to the nearest base 2 multiple of bInterval * 8.
+//
+// Input:
+// EpType Endpoint type, see XHCI_EP_CONTEXT.DW1.EpType field definitions
+// Speed Endpoint speed, 1..4 for XHCI_DEVSPEED_FULL, _LOW, _HIGH, _SUPER
+// Interval Poll interval value from endpoint descriptor
+//
+// Output:
+// Interval value to be written to the endpoint context
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+Xhci_TranslateInterval(
+ UINT8 EpType,
+ UINT8 Speed,
+ UINT8 Interval
+)
+{
+ UINT8 TempData;
+ UINT8 BitCount;
+
+ if (Interval == 0) {
+ return 0;
+ }
+
+ if (EpType == XHCI_EPTYPE_CTL ||
+ EpType == XHCI_EPTYPE_BULK_OUT ||
+ EpType == XHCI_EPTYPE_BULK_IN) {
+
+ if (Speed == XHCI_DEVSPEED_HIGH) {
+ for (TempData = Interval, BitCount = 0; TempData != 0; BitCount++) {
+ TempData >>= 1;
+ }
+ return BitCount - 1;
+ } else {
+ return 0; // Interval field will not be used for LS, FS and SS
+ }
+ }
+
+ // Control and Bulk endpoints are processed; translate intervals for Isoc and Interrupt
+ // endpoints
+
+ // Translate SS and HS endpoints
+ if (Speed == XHCI_DEVSPEED_SUPER ||
+ Speed == XHCI_DEVSPEED_SUPER_PLUS ||
+ Speed == XHCI_DEVSPEED_HIGH) {
+ return (Interval - 1);
+ }
+
+ // Translate interval for FS and LS endpoints
+ ASSERT(Interval > 0);
+
+ for (TempData = Interval, BitCount = 0; TempData != 0; BitCount++) {
+ TempData >>= 1;
+ }
+ return (BitCount + 2); // return value, where Interval = 0.125*2^value
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_EnableEndpoints
+//
+// Description:
+// This function parses the device descriptor data and enables the endpoints
+// by 1)assigning the Transfer TRB and 2)executing ConfigureEndpoint command
+// for the slot. Section 4.3.5.
+//
+// Input:
+// DevInfo - A device for which the endpoins are being enabled
+// Desc - Device Configuration Descriptor data pointer
+//
+// Output:
+// USB_ERROR on error, USB_SUCCESS on success
+//
+// Notes:
+// 1) DevInfo->DevMiscInfo points to the device context
+// 2) This call is executed before SET_CONFIGURATION control transfer
+// 3) EP0 information is valid in the Device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_EnableEndpoints (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 *Desc
+)
+{
+ UINT16 TotalLength;
+ UINT16 CurPos;
+ UINT8 Dci;
+ INTRF_DESC *IntrfDesc;
+ ENDP_DESC *EpDesc;
+ SS_ENDP_COMP_DESC *SsEpCompDesc = NULL;
+ HUB_DESC *HubDesc;
+ TRB_RING *XfrRing;
+ UINT8 EpType;
+ UINT8 Status;
+ UINT8 IsHub = 0; //(EIP73020)
+ UINT8 Speed;
+ XHCI_INPUT_CONTROL_CONTEXT *CtlCtx;
+ XHCI_SLOT_CONTEXT *SlotCtx;
+ XHCI_EP_CONTEXT *EpCtx;
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+ UINT8 SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+
+ EFI_STATUS EfiStatus = EFI_SUCCESS;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Desc, sizeof(CNFG_DESC));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ }
+#endif
+
+ if (((CNFG_DESC*)Desc)->bDescType != DESC_TYPE_CONFIG) return USB_ERROR;
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return USB_ERROR;
+ }
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)DevInfo->DevMiscInfo, 0);
+ Speed = SlotCtx->Speed;
+
+ // Note (From 4.6.6): The Add Context flag A1 and Drop Context flags D0 and D1
+ // of the Input Control Context (in the Input Context) shall be cleared to 0.
+ // Endpoint 0 Context does not apply to the Configure Endpoint Command and
+ // shall be ignored by the xHC. A0 shall be set to 1.
+
+ // Note (From 6.2.2.2): If Hub = 1 and Speed = High-Speed (3), then the
+ // TT Think Time and Multi-TT (MTT) fields shall be initialized.
+ // If Hub = 1, then the Number of Ports field shall be initialized, else
+ // Number of Ports = 0.
+
+ // Prepare input context for EvaluateContext comand
+ MemFill((UINT8*)Usb3Hc->InputContext, XHCI_INPUT_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ CtlCtx = (XHCI_INPUT_CONTROL_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 0);
+ CtlCtx->AddContextFlags = BIT0; // EP0
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, 1);
+
+ // Collect the endpoint information and update the Device Input Context
+ TotalLength = ((CNFG_DESC*)Desc)->wTotalLength;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)Desc, TotalLength);
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ if (TotalLength > (MAX_CONTROL_DATA_SIZE - 1)) {
+ TotalLength = MAX_CONTROL_DATA_SIZE - 1;
+ }
+
+ for (CurPos = 0; CurPos < TotalLength; CurPos += EpDesc->bDescLength) {
+ EpDesc = (ENDP_DESC*)(IntrfDesc = (INTRF_DESC*)(Desc + CurPos));
+
+ if (IntrfDesc->bDescLength == 0) {
+ break;
+ }
+
+ if ((CurPos + IntrfDesc->bDescLength) > TotalLength) {
+ break;
+ }
+
+ if (IntrfDesc->bDescType == DESC_TYPE_INTERFACE) {
+ IsHub = IntrfDesc->bBaseClass == BASE_CLASS_HUB;
+ continue;
+ }
+
+ if (EpDesc->bDescType != DESC_TYPE_ENDPOINT) continue;
+
+ // Found Endpoint, fill up the information in the InputContext
+
+ // Calculate Device Context Index (DCI), Section 4.5.1.
+ // 1) For Isoch, Interrupt, or Bulk type endpoints the DCI is calculated
+ // from the Endpoint Number and Direction with the following formula:
+ // DCI = (Endpoint Number * 2) + Direction, where Direction = 0 for OUT
+ // endpoints and 1 for IN endpoints.
+ // 2) For Control type endpoints:
+ // DCI = (Endpoint Number * 2) + 1
+ //
+ // Also calculate XHCI EP type out of EpDesc->bEndpointFlags
+
+ if ((EpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS) == EP_DESC_FLAG_TYPE_CONT) {
+ Dci = (EpDesc->bEndpointAddr & 0xf) * 2 + 1;
+ EpType = XHCI_EPTYPE_CTL;
+ } else {
+ // Isoc, Bulk or Interrupt endpoint
+ Dci = (EpDesc->bEndpointAddr & 0xf) * 2;
+ EpType = EpDesc->bEndpointFlags & EP_DESC_FLAG_TYPE_BITS; // 1, 2, or 3
+
+ if (EpDesc->bEndpointAddr & BIT7) {
+ Dci++; // IN
+ EpType += 4; // 5, 6, or 7
+ }
+ }
+
+ // Update ContextEntries in the Slot context
+ if (Dci > SlotCtx->ContextEntries) {
+ SlotCtx->ContextEntries = Dci;
+ }
+
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)Usb3Hc->InputContext, Dci + 1);
+
+ EpCtx->EpType = EpType;
+
+ // The Endpoint Companion descriptor shall immediately follow the
+ // endpoint descriptor it is associated with in the configuration information.
+
+ if ((DevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER) ||
+ (DevInfo->bEndpointSpeed == USB_DEV_SPEED_SUPER_PLUS)) {
+ SsEpCompDesc = (SS_ENDP_COMP_DESC*)(Desc + CurPos + EpDesc->bDescLength);
+ if (SsEpCompDesc->DescType == DESC_TYPE_SS_EP_COMP) {
+ EpCtx->MaxBurstSize = SsEpCompDesc->MaxBurst;
+ }
+ }
+
+ // wMaxPacketSize
+ // USB 2.0 spec
+ // For all endpoints, bits 10..0 specify the maximum packet size (in bytes).
+ // For high-speed isochronous and interrupt endpoints:
+ // Bits 12..11 specify the number of additional transaction
+ // opportunities per microframe:
+ // 00 = None (1 transaction per microframe)
+ // 01 = 1 additional (2 per microframe)
+ // 10 = 2 additional (3 per microframe)
+ // 11 = Reserved
+ // Bits 15..13 are reserved and must be set to zero.
+ // USB 3.0 & 3.1 spec
+ // Maximum packet size this endpoint is capable of sending or receiving
+ // when this configuration is selected.
+ // For control endpoints this field shall be set to 512. For bulk endpoint
+ // types this field shall be set to 1024.
+ // For interrupt and isochronous endpoints this field shall be set to 1024 if
+ // this endpoint defines a value in the bMaxBurst field greater than zero.
+ // If the value in the bMaxBurst field is set to zero then this field can
+ // have any value from 0 to 1024 for an isochronous endpoint and 1 to
+ // 1024 for an interrupt endpoint.
+
+ // Only reserve bits 10..0
+ EpCtx->MaxPacketSize = (EpDesc->wMaxPacketSize & 0x07FF);
+
+ // 4.14.1.1 System Bus Bandwidth Scheduling
+ // Reasonable initial values of Average TRB Length for Control endpoints
+ // Control endpoints would be 8B, Interrupt endpoints 1KB,
+ // and Bulk and Isoch endpoints 3KB.
+
+ switch (EpCtx->EpType) {
+ case XHCI_EP_TYPE_ISO_OUT:
+ case XHCI_EP_TYPE_ISO_IN:
+ EpCtx->ErrorCount = 0;
+ EpCtx->AvgTrbLength = 0xC00;
+ break;
+ case XHCI_EP_TYPE_BLK_OUT:
+ case XHCI_EP_TYPE_BLK_IN:
+ EpCtx->ErrorCount = 3;
+ EpCtx->AvgTrbLength = 0xC00;
+ break;
+ case XHCI_EP_TYPE_INT_OUT:
+ case XHCI_EP_TYPE_INT_IN:
+ EpCtx->ErrorCount = 3;
+ EpCtx->AvgTrbLength = 0x400;
+ break;
+ case XHCI_EP_TYPE_CONTROL:
+ EpCtx->ErrorCount = 3;
+ EpCtx->AvgTrbLength = 0x08;
+ break;
+ default:
+ break;
+ }
+
+ // Set Interval
+ EpCtx->Interval = Xhci_TranslateInterval(EpType, Speed, EpDesc->bPollInterval);
+
+ XfrRing = XHCI_InitXfrRing(Usb3Hc, SlotId, Dci - 1);
+ EpCtx->TrDequeuePtr = (UINT64)(UINTN)XfrRing->Base + 1;
+
+ CtlCtx->AddContextFlags |= (1 << Dci);
+ }
+
+ // For a HUB update NumberOfPorts and TTT fields in the Slot context. For that get hub descriptor
+ // and use bNbrPorts and TT Think time fields (11.23.2.1 of USB2 specification)
+ // Notes:
+ // - Slot.Hub field is already updated
+ // - Do not set NumberOfPorts and TTT fields for 0.95 controllers
+
+ if (IsHub) {
+ HubDesc = (HUB_DESC*)USB_MemAlloc(sizeof(MEM_BLK));
+ UsbHubGetHubDescriptor(HcStruc, DevInfo, HubDesc, sizeof(MEM_BLK));
+ //ASSERT(HubDesc->bDescType == DESC_TYPE_HUB || HubDesc->bDescType == DESC_TYPE_SS_HUB);
+ if ((HubDesc->bDescType == DESC_TYPE_HUB) ||
+ (HubDesc->bDescType == DESC_TYPE_SS_HUB)) {
+ SlotCtx->Hub = 1;
+ SlotCtx->PortsNum = HubDesc->bNumPorts;
+
+ if (Speed == XHCI_DEVSPEED_HIGH) {
+ SlotCtx->TThinkTime = (HubDesc->wHubFlags >> 5) & 0x3;
+ }
+ }
+ USB_MemFree(HubDesc, sizeof(MEM_BLK));
+ }
+
+ // Input context is updated with the endpoint information. Execute ConfigureEndpoint command.
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTConfigureEndpointCmd, &SlotId);
+ ASSERT(Status == USB_SUCCESS);
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_GetRootHubPort
+//
+// Description:
+// This function returns a root hub number for a given device. If device is
+// connected to the root through hub(s), it searches the parent's chain up
+// to the root.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_GetRootHubPort(
+ DEV_INFO *DevInfo
+)
+{
+ UINT8 i;
+
+ if ((DevInfo->bHubDeviceNumber & BIT7) != 0) return DevInfo->bHubPortNumber;
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+ if ((gUsbData->aDevInfoTable[i].Flag & DEV_INFO_VALIDPRESENT)
+ != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+ if (gUsbData->aDevInfoTable[i].bDeviceAddress == DevInfo->bHubDeviceNumber) {
+ return XHCI_GetRootHubPort(&gUsbData->aDevInfoTable[i]);
+ }
+ }
+ ASSERT(FALSE); // Device parent hub found
+ return 0;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_InitDeviceData
+//
+// Description:
+// This is an API function for early device initialization.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_InitDeviceData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 PortStatus,
+ UINT8 **DeviceData
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ UINT8 Status;
+ UINT8 SlotId;
+ VOID *DevCtx;
+ EFI_STATUS EfiStatus;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ if (gCheckUsbApiParameter) {
+ EfiStatus = AmiValidateMemoryBuffer((VOID*)DeviceData, sizeof(UINT8*));
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+ gCheckUsbApiParameter = FALSE;
+ }
+#endif
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ // Obtain device slot using Enable Slot command, 4.3.2, 4.6.3
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTEnableSlotCmd, &SlotId);
+ //ASSERT(Status == USB_SUCCESS);
+ //ASSERT(SlotId != 0);
+ if (Status != USB_SUCCESS) {
+ return Status;
+ }
+
+ DevCtx = XHCI_GetDeviceContext(Usb3Hc, SlotId);
+ MemSet(DevCtx, XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ // Update DCBAA with the new device pointer (index = SlotId)
+ Usb3Hc->DcbaaPtr->DevCntxtAddr[SlotId-1] = (UINT64)(UINTN)DevCtx;
+ USB_DEBUG(3, "XHCI: Slot[%d] enabled, device context at %x\n", SlotId, DevCtx);
+
+ Status = XhciAddressDevice(HcStruc, DevInfo, SlotId);
+ if (Status != USB_SUCCESS) {
+ return Status;
+ }
+
+ *DeviceData = (UINT8*)DevCtx;
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_DeinitDeviceData
+//
+// Description:
+// This is an API function for removing device related information from HC.
+// For xHCI this means:
+// - execute DisableSlot commnand
+// - clear all endpoint's transfer rings
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_DeinitDeviceData (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ UINT8 SlotId;
+ UINT8 Dci;
+ TRB_RING *XfrRing;
+ XHCI_SLOT_CONTEXT *SlotCtx;
+ XHCI_EP_CONTEXT *EpCtx;
+ UINT16 EpInfo;
+ EFI_STATUS EfiStatus;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ EfiStatus = UsbDevInfoValidation(DevInfo);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return USB_SUCCESS;
+ }
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ if (Usb3Hc->DcbaaPtr->DevCntxtAddr[SlotId-1] == 0) return USB_SUCCESS;
+
+ SlotCtx = (XHCI_SLOT_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)DevInfo->DevMiscInfo, 0);
+
+ // Stop transfer rings
+ for (Dci = 1; Dci <= SlotCtx->ContextEntries; Dci++) {
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, (UINT8*)DevInfo->DevMiscInfo, Dci);
+ if (EpCtx->TrDequeuePtr != 0) {
+ if (EpCtx->EpState == XHCI_EP_STATE_RUNNING) {
+ EpInfo = (Dci << 8) + SlotId;
+ XHCI_ExecuteCommand(HcStruc, XhciTStopEndpointCmd, &EpInfo);
+ }
+
+ // Clear transfer rings
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci - 1);
+ MemFill((UINT8*)XfrRing->Base, RING_SIZE, 0);
+ }
+ }
+
+ XHCI_ExecuteCommand(HcStruc, XhciTDisableSlotCmd, &SlotId);
+
+ Usb3Hc->DcbaaPtr->DevCntxtAddr[SlotId-1] = 0;
+ DevInfo->DevMiscInfo = NULL;
+
+ return USB_SUCCESS;
+}
+
+ //(EIP54283+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_ClearEndpointState
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_ClearEndpointState(
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 Endpoint
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc;
+ UINT8 SlotId;
+ UINT8 Dci;
+ TRB_RING *XfrRing;
+ UINT8 Status = USB_SUCCESS;
+ XHCI_SET_TRPTR_CMD_TRB Trb;
+ XHCI_EP_CONTEXT *EpCtx;
+ UINT16 EpInfo;
+ EFI_STATUS EfiStatus;
+ UINTN DeviceContextSize;
+
+ EfiStatus = UsbHcStrucValidation(HcStruc);
+
+ if (EFI_ERROR(EfiStatus)) {
+ return USB_ERROR;
+ }
+
+ if (!(HcStruc->dHCFlag & HC_STATE_RUNNING)) {
+ return USB_ERROR;
+ }
+
+ Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+
+ if (Usb3Hc->OpRegs->UsbSts.Field.HcHalted) {
+ return USB_ERROR;
+ }
+
+ if (DevInfo->DevMiscInfo == NULL) {
+ return Status;
+ }
+
+ SlotId = XHCI_GetSlotId(Usb3Hc, DevInfo);
+ if (Endpoint != 0) {
+ Dci = (Endpoint & 0xF) * 2 + (Endpoint >> 7);
+ } else {
+ Dci = 1;
+ }
+
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((DevInfo->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (DevInfo->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return USB_ERROR;
+ }
+ //<(EIP60460+)
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc, DevInfo->DevMiscInfo, Dci);
+
+ if (EpCtx->EpState == XHCI_EP_STATE_RUNNING) {
+ EpInfo = (Dci << 8) + SlotId;
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTStopEndpointCmd, &EpInfo);
+ } //<(EIP54300+)
+
+ // Set TR Dequeue Pointer command may be executed only if the target
+ // endpoint is in the Error or Stopped state.
+ if ((EpCtx->EpState == XHCI_EP_STATE_STOPPED) ||
+ (EpCtx->EpState == XHCI_EP_STATE_ERROR)) {
+
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, Dci-1);
+
+ Trb.TrPointer = (UINT64)((UINTN)XfrRing->QueuePtr + XfrRing->CycleBit); // Set up DCS
+ Trb.EndpointId = Dci;
+ Trb.SlotId = SlotId;
+
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTSetTRDequeuePointerCmd, &Trb);
+ }
+ //ASSERT(Status == USB_SUCCESS);
+
+// Doorbell = XHCI_GetTheDoorbell(Usb3Hc, SlotId); //(EIP61849-)
+// *Doorbell = Dci; //(EIP61849-)
+
+ return Status;
+}
+ //<(EIP54283+)
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciAddressDevice
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XhciAddressDevice (
+ HC_STRUC *HcStruc,
+ DEV_INFO *DevInfo,
+ UINT8 SlotId
+)
+{
+ USB3_HOST_CONTROLLER *Usb3Hc = (USB3_HOST_CONTROLLER*)HcStruc->usbbus_data;
+ XHCI_INPUT_CONTROL_CONTEXT *InputCtrl = NULL;
+ XHCI_SLOT_CONTEXT *InputSlot = NULL;
+ XHCI_SLOT_CONTEXT *OutputSlot = NULL;
+ XHCI_SLOT_CONTEXT *ParentHubSlotCtx = NULL;
+ XHCI_EP_CONTEXT *InputEp0 = NULL;
+ XHCI_EP_CONTEXT *OutputEp0 = NULL;
+ UINT8 Status = USB_ERROR;
+ VOID *DevCtx = XHCI_GetDeviceContext(Usb3Hc, SlotId);
+ VOID *InputCtx = Usb3Hc->InputContext;
+ TRB_RING *XfrRing = NULL;
+ DEV_INFO *ParentHub = NULL;
+ UINT8 HubPortNumber = 0;
+ UINT16 AddrDevParam = 0;
+ UINT8 Bsr = 0;
+ UINTN DeviceContextSize;
+
+ OutputSlot = XHCI_GetContextEntry(Usb3Hc, DevCtx, 0);
+ if (OutputSlot->SlotState >= XHCI_SLOT_STATE_ADDRESSED) {
+ return USB_ERROR;
+ }
+
+ // Zero the InputContext and DeviceContext
+ MemSet(InputCtx, XHCI_INPUT_CONTEXT_ENTRIES * Usb3Hc->ContextSize, 0);
+
+ // Initialize the Input Control Context of the Input Context
+ // by setting the A0 flags to 1
+ InputCtrl = XHCI_GetContextEntry(Usb3Hc, InputCtx, 0);
+ InputCtrl->AddContextFlags = BIT0 | BIT1;
+
+ // Initialize the Input Slot Context data structure
+ InputSlot = XHCI_GetContextEntry(Usb3Hc, InputCtx, 1);
+ InputSlot->RouteString = 0;
+ InputSlot->ContextEntries = 1;
+ InputSlot->RootHubPort = XHCI_GetRootHubPort(DevInfo);
+
+ switch (DevInfo->bEndpointSpeed) {
+ case USB_DEV_SPEED_SUPER_PLUS:
+ InputSlot->Speed = XHCI_DEVSPEED_SUPER_PLUS;
+ break;
+ case USB_DEV_SPEED_SUPER:
+ InputSlot->Speed = XHCI_DEVSPEED_SUPER;
+ break;
+ case USB_DEV_SPEED_HIGH:
+ InputSlot->Speed = XHCI_DEVSPEED_HIGH;
+ break;
+ case USB_DEV_SPEED_LOW:
+ InputSlot->Speed = XHCI_DEVSPEED_LOW;
+ break;
+ case USB_DEV_SPEED_FULL:
+ InputSlot->Speed = XHCI_DEVSPEED_FULL;
+ break;
+ }
+
+ // Initialize Route String and TT fields
+ ParentHub = USB_GetDeviceInfoStruc(USB_SRCH_DEV_ADDR,
+ 0, DevInfo->bHubDeviceNumber, 0);
+ if (ParentHub != NULL) {
+ DeviceContextSize = (XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize) * Usb3Hc->CapRegs->HcsParams1.MaxSlots;
+
+ if ((ParentHub->DevMiscInfo < Usb3Hc->DeviceContext) ||
+ (ParentHub->DevMiscInfo > (VOID*)((UINTN)(Usb3Hc->DeviceContext) + DeviceContextSize))) {
+ return 0;
+ }
+ ParentHubSlotCtx = XHCI_GetContextEntry(Usb3Hc, ParentHub->DevMiscInfo, 0);
+ HubPortNumber = (DevInfo->bHubPortNumber > 15)? 15 : DevInfo->bHubPortNumber;
+ InputSlot->RouteString = ParentHubSlotCtx->RouteString |
+ (HubPortNumber << (ParentHub->HubDepth * 4)); //(EIP51503)
+
+ // Update TT fields in the Slot context for LS/FS device connected to HS hub
+ if (InputSlot->Speed == XHCI_DEVSPEED_FULL || InputSlot->Speed == XHCI_DEVSPEED_LOW) {
+ if (ParentHubSlotCtx->Speed == XHCI_DEVSPEED_HIGH) {
+ InputSlot->TtHubSlotId = XHCI_GetSlotId(Usb3Hc, ParentHub);
+ InputSlot->TtPortNumber = DevInfo->bHubPortNumber;
+ InputSlot->MultiTT = ParentHubSlotCtx->MultiTT;
+ } else {
+ InputSlot->TtHubSlotId = ParentHubSlotCtx->TtHubSlotId;
+ InputSlot->TtPortNumber = ParentHubSlotCtx->TtPortNumber;
+ InputSlot->MultiTT = ParentHubSlotCtx->MultiTT;
+ }
+ }
+ }
+
+ OutputEp0 = XHCI_GetContextEntry(Usb3Hc, DevCtx, 1);
+ switch (OutputEp0->EpState) {
+ case XHCI_EP_STATE_DISABLED:
+ XfrRing = XHCI_InitXfrRing(Usb3Hc, SlotId, 0);
+ break;
+ case XHCI_EP_STATE_RUNNING:
+ case XHCI_EP_STATE_STOPPED:
+ XfrRing = XHCI_GetXfrRing(Usb3Hc, SlotId, 0);
+ break;
+ default:
+ break;
+ }
+
+ // Initialize the Input default control Endpoint 0 Context
+ InputEp0 = XHCI_GetContextEntry(Usb3Hc, InputCtx, 2);
+ InputEp0->EpType = XHCI_EPTYPE_CTL;
+ InputEp0->MaxPacketSize = DevInfo->wEndp0MaxPacket;
+ InputEp0->TrDequeuePtr = (UINT64)(UINTN)XfrRing->QueuePtr | XfrRing->CycleBit;
+ InputEp0->AvgTrbLength = 8;
+ InputEp0->ErrorCount = 3;
+
+ Bsr = (InputSlot->Speed != XHCI_DEVSPEED_SUPER &&
+ InputSlot->Speed != XHCI_DEVSPEED_SUPER_PLUS &&
+ OutputSlot->SlotState == XHCI_SLOT_STATE_DISABLED) ? 1 : 0;
+
+ AddrDevParam = (UINT16)SlotId | (Bsr << 8);
+
+ // Assign a new address 4.3.4, 4.6.5
+ Status = XHCI_ExecuteCommand(HcStruc, XhciTAddressDeviceCmd, &AddrDevParam);
+ if (Status != USB_SUCCESS) {
+ XHCI_ExecuteCommand(HcStruc, XhciTDisableSlotCmd, &SlotId);
+ Usb3Hc->DcbaaPtr->DevCntxtAddr[SlotId-1] = 0;
+ return Status;
+ }
+
+ if (Bsr == 0) {
+ USB_DEBUG(3, "XHCI: new device address %d\n", OutputSlot->DevAddr);
+ }
+
+ return USB_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciRingDoorbell
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XhciRingDoorbell(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINT8 SlotId,
+ UINT8 Dci
+)
+{
+ volatile UINT32 *Doorbell;
+ XHCI_EP_CONTEXT *EpCtx = NULL;
+ UINT32 Count;
+
+ Doorbell = XHCI_GetTheDoorbell(Usb3Hc, SlotId);
+ *Doorbell = Dci;
+
+ if (SlotId == 0) {
+ return USB_ERROR;
+ }
+
+ EpCtx = (XHCI_EP_CONTEXT*)XHCI_GetContextEntry(Usb3Hc,
+ XHCI_GetDeviceContext(Usb3Hc, SlotId), Dci);
+ // Wait for the endpoint running
+ for (Count = 0; Count < 10 * 1000; Count++) {
+ if (EpCtx->EpState == XHCI_EP_STATE_RUNNING) {
+ break;
+ }
+ FixedDelay(1); // 1 us delay
+ }
+ //ASSERT(EpCtx->EpState == XHCI_EP_STATE_RUNNING);
+
+ if (EpCtx->EpState != XHCI_EP_STATE_RUNNING) {
+ return USB_ERROR;
+ }
+
+ return USB_SUCCESS;
+}
+ //<(EIP54283+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_Mmio64Write
+//
+// Description:
+// HC may or may not support 64-bit writes to MMIO area. If it does, write
+// Data directly, otherwise split into two DWORDs.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT64
+XHCI_Mmio64Read(
+ HC_STRUC *HcStruc,
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINTN Address
+)
+{
+ UINT64 Data = 0;
+ UINT32 Offset;
+
+ Offset = (UINT32)(Address - HcStruc->BaseAddress);
+
+ if ((Offset + sizeof(UINT64)) > HcStruc->BaseAddressSize) {
+ return 0;
+ }
+
+ if (Usb3Hc->Access64) {
+ Data = *(UINT64*)Address;
+ }
+ else {
+ Data = *(UINT32*)Address;
+ Data = Shl64(*(UINT32*)(Address + sizeof(UINT32)), 32);
+ }
+ return Data;
+}
+
+VOID
+XHCI_Mmio64Write(
+ HC_STRUC *HcStruc,
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINTN Address,
+ UINT64 Data
+)
+{
+ UINT32 Offset;
+
+ Offset = (UINT32)(Address - HcStruc->BaseAddress);
+
+ if ((Offset + sizeof(UINT64)) > HcStruc->BaseAddressSize) {
+ return;
+ }
+
+ if (Usb3Hc->Access64) {
+ *(UINT64*)Address = Data;
+ }
+ else {
+ *(UINT32*)Address = (UINT32)Data;
+ *(UINT32*)(Address + sizeof(UINT32)) = (UINT32)(Shr64(Data, 32));
+ }
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_InitRing
+//
+// Description:
+// Transfer ring initialization. There is an option to create a Link TRB in
+// the end of the ring.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XHCI_InitRing (
+ IN OUT TRB_RING *Ring,
+ IN UINTN RingBase,
+ IN UINT32 RingSize,
+ IN BOOLEAN PlaceLinkTrb
+)
+{
+ XHCI_LINK_TRB *LinkTrb;
+ EFI_STATUS Status = EFI_SUCCESS;
+
+ Ring->Base = (XHCI_TRB*)RingBase;
+ Ring->Size = RingSize;
+ Ring->LastTrb = Ring->Base + RingSize - 1;
+ Ring->CycleBit = 1;
+ Ring->QueuePtr = (XHCI_TRB*)RingBase;
+
+ // Initialize ring with zeroes
+ {
+ UINT8 *p = (UINT8*)RingBase;
+ UINTN i;
+ for (i = 0; i < RingSize*sizeof(XHCI_TRB); i++, p++) *p = 0;
+ }
+
+ if (PlaceLinkTrb) {
+ // Place a Link TRB in the end of the ring pointing to the beginning
+ LinkTrb = (XHCI_LINK_TRB*)Ring->LastTrb;
+#if USB_RUNTIME_DRIVER_IN_SMM
+ Status = AmiValidateMemoryBuffer((VOID*)LinkTrb, sizeof(XHCI_LINK_TRB));
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+#endif
+ LinkTrb->NextSegPtr = (UINT64)(UINTN)RingBase;
+ LinkTrb->ToggleCycle = 1;
+ LinkTrb->TrbType = XhciTLink;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: UpdatePortStatusSpeed
+//
+// Description:
+// This function sets USB_PORT_STAT... fields that are related to device
+// speed (LS/FS/HS/SS) in a given PortStatus variable.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UpdatePortStatusSpeed(
+ UINT8 Speed,
+ UINT8 *PortStatus
+)
+{
+ UINT8 PortSts = *PortStatus;
+
+ ASSERT(Speed < 6);
+ PortSts &= ~USB_PORT_STAT_DEV_SPEED_MASK;
+
+ switch (Speed) {
+ case XHCI_DEVSPEED_UNDEFINED:
+ break;
+ case XHCI_DEVSPEED_FULL:
+ PortSts |= USB_PORT_STAT_DEV_FULLSPEED;
+ break;
+ case XHCI_DEVSPEED_LOW:
+ PortSts |= USB_PORT_STAT_DEV_LOWSPEED;
+ break;
+ case XHCI_DEVSPEED_HIGH:
+ PortSts |= USB_PORT_STAT_DEV_HISPEED;
+ break;
+ case XHCI_DEVSPEED_SUPER:
+ PortSts |= USB_PORT_STAT_DEV_SUPERSPEED;
+ break;
+ case XHCI_DEVSPEED_SUPER_PLUS:
+ PortSts |= USB_PORT_STAT_DEV_SUPERSPEED_PLUS;
+ break;
+ default:
+ USB_DEBUG(3, "XHCI ERROR: unknown device speed.\n");
+ }
+
+ *PortStatus = PortSts;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XhciExtCapParser
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+XhciExtCapParser(
+ IN USB3_HOST_CONTROLLER *Usb3Hc
+)
+{
+ XHCI_EXT_CAP *CurPtr;
+
+ if (Usb3Hc->CapRegs->HccParams1.Xecp == 0) return EFI_SUCCESS;
+
+ // Starts from first capability
+ CurPtr = (XHCI_EXT_CAP *)((UINTN)Usb3Hc->CapRegs + (Usb3Hc->CapRegs->HccParams1.Xecp << 2));
+
+ // Traverse all capability structures
+ for(;;) {
+ switch (CurPtr->CapId) {
+ case XHCI_EXT_CAP_USB_LEGACY:
+ Usb3Hc->ExtLegCap = (XHCI_EXT_LEG_CAP *)CurPtr;
+ USB_DEBUG(3, "XHCI: USB Legacy Ext Cap Ptr %x\n", Usb3Hc->ExtLegCap);
+ break;
+
+ case XHCI_EXT_CAP_SUPPORTED_PROTOCOL:
+ if (((XHCI_EXT_PROTOCOL*)CurPtr)->MajorRev == 0x02) {
+ Usb3Hc->Usb2Protocol = (XHCI_EXT_PROTOCOL*)CurPtr;
+ USB_DEBUG(3, "XHCI: USB2 Support Protocol %x, PortOffset %x PortCount %x\n",
+ Usb3Hc->Usb2Protocol, Usb3Hc->Usb2Protocol->PortOffset, Usb3Hc->Usb2Protocol->PortCount);
+ } else if (((XHCI_EXT_PROTOCOL*)CurPtr)->MajorRev == 0x03) {
+ Usb3Hc->Usb3Protocol = (XHCI_EXT_PROTOCOL*)CurPtr;
+ USB_DEBUG(3, "XHCI: USB3 Support Protocol %x, PortOffset %x PortCount %x\n",
+ Usb3Hc->Usb3Protocol, Usb3Hc->Usb3Protocol->PortOffset, Usb3Hc->Usb3Protocol->PortCount);
+ }
+ break;
+
+ case XHCI_EXT_CAP_POWERMANAGEMENT:
+ case XHCI_EXT_CAP_IO_VIRTUALIZATION:
+ break;
+ case XHCI_EXT_CAP_USB_DEBUG_PORT:
+ Usb3Hc->DbCapRegs = (XHCI_DB_CAP_REGS*)CurPtr;
+ USB_DEBUG(3, "XHCI: USB Debug Capability Ptr %x\n", Usb3Hc->DbCapRegs);
+ break;
+ }
+ if(CurPtr->NextCapPtr == 0) break;
+ // Point to next capability
+ CurPtr=(XHCI_EXT_CAP *)((UINTN)CurPtr+ (((UINTN)CurPtr->NextCapPtr) << 2));
+ }
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: XHCI_IsUsb3Port
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+XHCI_IsUsb3Port(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINT8 Port
+)
+{
+ if ((Port >= Usb3Hc->Usb3Protocol->PortOffset) &&
+ (Port < Usb3Hc->Usb3Protocol->PortOffset + Usb3Hc->Usb3Protocol->PortCount)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+//****************************************************************************
+// The following set of functions are the helpers to get the proper locations
+// of xHCI data structures using the available pointers.
+//****************************************************************************
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_GetSlotId
+//
+// Description:
+// This function calculates the slot ID out of a given DEV_INFO data pointer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+XHCI_GetSlotId(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ DEV_INFO *DevInfo
+)
+{
+ UINT32 DevCtxSize = XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize;
+ return (UINT8)(((UINTN)DevInfo->DevMiscInfo - (UINTN)Usb3Hc->DeviceContext)/DevCtxSize) + 1;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: XHCI_GetXfrRing
+//
+// Description:
+// This routine calculates the address of the address ring of a particular
+// Slot/Endpoint.
+//
+// Output:
+// Pointer to the transfer ring
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TRB_RING*
+XHCI_GetXfrRing(
+ USB3_HOST_CONTROLLER* Usb3Hc,
+ UINT8 Slot,
+ UINT8 Ep
+)
+{
+ return Usb3Hc->XfrRings + (Slot-1)*32 + Ep;
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_GetTheDoorbell
+//
+// Description:
+// This function calculates and returns the pointer to a doorbell for a
+// given Slot.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32*
+XHCI_GetTheDoorbell(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINT8 SlotId
+)
+{
+ return (UINT32*)((UINTN)Usb3Hc->CapRegs + Usb3Hc->DbOffset + sizeof(UINT32)*SlotId);
+}
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_GetDevInfo
+//
+// Description:
+// This function searches for DEV_INFO data pointer that belongs to a given XHCI
+// device context.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEV_INFO*
+XHCI_GetDevInfo(
+ UINTN PollTdPtr
+)
+{
+ UINT8 i;
+ DEV_INFO *DevInfo;
+
+ if (PollTdPtr == 0) return NULL;
+
+ for (i=1; i<MAX_DEVICES; i++) {
+ DevInfo = &gUsbData->aDevInfoTable[i];
+ if ((DevInfo->Flag & DEV_INFO_VALIDPRESENT) != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+ if (DevInfo->fpPollTDPtr == NULL) {
+ continue;
+ }
+ if ((UINTN)DevInfo->fpPollTDPtr == (UINTN)PollTdPtr) {
+ return DevInfo;
+ }
+ }
+ return NULL; // Device not found
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_GetDeviceContext
+//
+// Description:
+// This function calculates and returns the pointer to a device context for
+// a given Slot.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID*
+XHCI_GetDeviceContext(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ UINT8 SlotId
+)
+{
+ UINT32 DevCtxSize = XHCI_DEVICE_CONTEXT_ENTRIES * Usb3Hc->ContextSize;
+ return (UINT8*)((UINTN)Usb3Hc->DeviceContext + (SlotId - 1) * DevCtxSize);
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: XHCI_GetContextEntry
+//
+// Description:
+// This function calculates and returns the pointer to a context entry for
+// a given index.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID*
+XHCI_GetContextEntry(
+ USB3_HOST_CONTROLLER *Usb3Hc,
+ VOID *Context,
+ UINT8 Index
+)
+{
+ return (UINT8*)((UINTN)Context + Index * Usb3Hc->ContextSize);
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/rt/xhci.h b/Core/EM/usb/rt/xhci.h
new file mode 100644
index 0000000..9cbb9cc
--- /dev/null
+++ b/Core/EM/usb/rt/xhci.h
@@ -0,0 +1,1189 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: xhci.h
+//
+// Description: XHCI equates and structure definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifndef _XHCI_H_
+#define _XHCI_H_
+
+#include <Token.h>
+#include "usbkbd.h"
+
+#pragma pack(push, 1)
+
+// XHCI Device Context structures
+//---------------------------------------------------------------------------
+
+typedef struct {
+ UINT64 ScratchpadBufArrayPtr;
+ UINT64 DevCntxtAddr[255];
+} XHCI_DCBAA; // Total size is 256 64-bit entries, or 2K Bytes (section 6.1)
+
+// XHCI PCI Configuration Registers
+//---------------------------------------------------------------------------
+
+// Serial Bus Release Number Register
+#define XHCI_PCI_SBRN 0x60
+
+// Frame Length Adjustment Register
+#define XHCI_PCI_FLADJ 0x61
+
+// Host Controller Capability Registers
+//---------------------------------------------------------------------------
+
+typedef struct {
+ UINT32 MaxSlots : 8; // Number of Device Slots
+ UINT32 MaxIntrs : 11; // Number of Interrupters
+ UINT32 Rsvd : 5; // Reserved
+ UINT32 MaxPorts : 8; // Number of ports
+} HCSPARAMS1;
+
+typedef struct {
+ UINT32 Ist : 4; // Isochronous Scheduling Threshold
+ UINT32 ErstMax : 4; // Event Ring Segment Table Max
+ UINT32 Rsvd : 13;
+ UINT32 MaxScratchPadBufsHi : 5; // Max Scratchpad Buffers (Max Scratchpad Bufs Hi).
+ UINT32 Spr : 1; // Scratchpad restore
+ UINT32 MaxScratchPadBufsLo : 5; // Max Scratchpad Buffers (Max Scratchpad Bufs Lo).
+} HCSPARAMS2;
+
+typedef struct {
+ UINT32 U1DevExitLatency : 8; // Worst case latency of U1->U0, mks
+ UINT32 Rsvd : 8;
+ UINT32 U2DevExitLatency : 16; // Worst case latency of U2->U0, mks
+} HCSPARAMS3;
+
+typedef struct {
+ UINT32 Ac64 : 1; // 64-bit Addressing Capability
+ UINT32 Bnc : 1; // Bandwidth Negotiation Capability
+ UINT32 Csz : 1; // Context data structures width (32 or 64 bit)
+ UINT32 Ppc : 1; // Power Port Control
+ UINT32 Pind : 1; // Port Indicators
+ UINT32 Lhrc : 1; // Light HC Reset Capability
+ UINT32 Ltc : 1; // Latency Tolerance Capability
+ UINT32 Nss : 1; // No Secondary SID Support
+ UINT32 Pae : 1; // Parse All Event Data
+ UINT32 Spc : 1; // Stopped - Short Packet Capability
+ UINT32 Sec : 1; // Stopped EDTLA Capability
+ UINT32 Cfc : 1; // Contiguous Frame ID Capability
+ UINT32 MaxPsaSize : 4; // Maximum Primary Stream Array Size
+ UINT32 Xecp : 16; // xHCI Extended Capabilities Pointer
+} HCCPARAMS1;
+
+typedef struct {
+ UINT32 U3c : 1; // U3 Entry Capability
+ UINT32 Cmc : 1; // Configure Endpoint Command Max Exit Latency Too Large Capability
+ UINT32 Fsc : 1; // Force Save Context Capability
+ UINT32 Ctc : 1; // Compliance Transition Capability
+ UINT32 Lec : 1; // Large ESIT Payload Capability
+ UINT32 Cic : 1; // Configuration Information Capability
+ UINT32 Rsvd : 26;
+} HCCPARAMS2;
+
+typedef struct {
+ UINT8 CapLength; // 00
+ UINT8 Rsvd; // 01
+ UINT16 HciVersion; // 02
+ HCSPARAMS1 HcsParams1; // 04
+ HCSPARAMS2 HcsParams2; // 08
+ HCSPARAMS3 HcsParams3; // 0C
+ HCCPARAMS1 HccParams1; // 10
+ UINT32 DbOff; // 14
+ UINT32 RtsOff; // 18
+ HCCPARAMS2 HccParams2; // 1C
+} XHCI_HC_CAP_REGS;
+
+//-----------------------------------------------------------
+// Host Controller Operational Registers
+//-----------------------------------------------------------
+typedef struct {
+ union {
+ UINT32 AllBits; // can be used for clearing status
+ #define XHCI_CMD_RS BIT0
+ #define XHCI_CMD_HCRST BIT1
+ #define XHCI_CMD_INTE BIT2
+ #define XHCI_CMD_HSEE BIT3
+ #define XHCI_CMD_LHCRST BIT4
+ struct {
+ UINT32 RunStop : 1;
+ UINT32 HcRst : 1; // HC Reset
+ UINT32 Inte : 1; // Interrupter Enable
+ UINT32 HsEe : 1; // Host System Error Enable
+ UINT32 Rsvd : 3;
+ UINT32 LhcRst : 1; // Light Host Controller Reset
+ UINT32 Css : 1; // Controller Save State
+ UINT32 Crs : 1; // Controller Restore State
+ UINT32 Ewe : 1; // Enable Wrap Event
+ UINT32 Eu3S : 1; // Enable U3 MFINDEX Stop
+ UINT32 Rsvd1 : 20;
+ } Field;
+ };
+} XHCI_USBCMD;
+
+typedef struct {
+ union {
+ UINT32 AllBits; // can be used for clearing status
+ #define XHCI_STS_HALTED BIT0
+ #define XHCI_STS_HOSTSYSTEM_ERROR BIT2
+ #define XHCI_STS_EVT_INTERRUPT BIT3
+ #define XHCI_STS_PCD BIT4
+ struct {
+ UINT32 HcHalted : 1;
+ UINT32 Rsvd1 : 1;
+ UINT32 Hse : 1; // Host System Error
+ UINT32 Eint : 1; // Event Interrupt
+ UINT32 Pcd : 1; // Port Change Detect
+ UINT32 Rsvd2 : 3;
+ UINT32 Sss : 1; // Save State Status
+ UINT32 Rss : 1; // Restore State Status
+ UINT32 Sre : 1; // Save/Restore Error
+ UINT32 Cnr : 1; // Controller Not Ready
+ UINT32 Hce : 1; // Host Controller Error
+ UINT32 Rsvd3 : 19;
+ } Field;
+ };
+} XHCI_USBSTS;
+
+typedef struct {
+ UINT32 Rcs : 1; // Ring Cycle State
+ UINT32 Cs : 1; // Command Stop
+ UINT32 Ca : 1; // Command Abort
+ UINT32 Crr : 1; // Command Ring Running
+ UINT32 Rsvd : 2;
+ UINT32 CrPointer : 26; // Command Ring Pointer
+} XHCI_CRCR;
+
+#define XHCI_PORT_CONNECT BIT0
+#define XHCI_PORT_ENABLE BIT1
+#define XHCI_PORT_RESET BIT4
+#define XHCI_PORT_RESET_CHG BIT21
+
+#define XHCI_PORTSC_OFFSET 0x400
+
+// Port speed definitions as read from PortSpeed field of PORTSC
+#define XHCI_DEVSPEED_UNDEFINED 0
+#define XHCI_DEVSPEED_FULL 1
+#define XHCI_DEVSPEED_LOW 2
+#define XHCI_DEVSPEED_HIGH 3
+#define XHCI_DEVSPEED_SUPER 4
+#define XHCI_DEVSPEED_SUPER_PLUS 5
+
+// Port link definitions
+#define XHCI_PORT_LINK_U0 0
+#define XHCI_PORT_LINK_U1 1
+#define XHCI_PORT_LINK_U2 2
+#define XHCI_PORT_LINK_U3 3
+#define XHCI_PORT_LINK_DISABLED 4
+#define XHCI_PORT_LINK_RXDETECT 5
+#define XHCI_PORT_LINK_INACTIVE 6
+#define XHCI_PORT_LINK_POLLING 7
+#define XHCI_PORT_LINK_RECOVERY 8
+#define XHCI_PORT_LINK_HOT_RESET 9
+#define XHCI_PORT_LINK_COMPLIANCE_MODE 10
+#define XHCI_PORT_LINK_TEST_MODE 11
+#define XHCI_PORT_LINK_RESUME 15
+
+typedef struct {
+ union {
+ UINT32 AllBits; // can be used for clearing status
+ #define XHCI_PCS_CCS BIT0
+ #define XHCI_PCS_PED BIT1
+ #define XHCI_PCS_OCA BIT3
+ #define XHCI_PCS_PR BIT4
+ #define XHCI_PCS_PP BIT9
+ #define XHCI_PCS_LWS BIT16
+ #define XHCI_PCS_CSC BIT17
+ #define XHCI_PCS_WRC BIT19
+ #define XHCI_PCS_PRC BIT21
+ #define XHCI_PCS_WPR BIT31
+ struct {
+ UINT32 Ccs : 1; // 0 Current Connect Status - RO
+ UINT32 Ped : 1; // 1 Port Enabled/Disabled - RW1CS
+ UINT32 RsvdZ1 : 1; // 2
+ UINT32 Oca : 1; // 3 Over-current Active - RO
+ UINT32 Pr : 1; // 4 Port Reset - RW1S
+ UINT32 Pls : 4; // 5..8 Port Link State - RWS
+ UINT32 Pp : 1; // 9 Port Power - RWS
+ UINT32 PortSpeed : 4; // 10..13 Port Speed - RO
+ UINT32 Pic : 2; // 14..15 Port Indicator Ctl - RWS
+ UINT32 Lws : 1; // 16 Port Link State Write Strobe - RW
+ UINT32 Csc : 1; // 17 Connect Status Change - RW1CS
+ UINT32 Pec : 1; // 18 Port Enabled/Disabled Change - RW1CS
+ UINT32 Wrc : 1; // 19 Warm Port Reset Change - RW1CS/RsvdZ
+ UINT32 Occ : 1; // 20 Over-current Change - RW1CS
+ UINT32 Prc : 1; // 21 Port Reset Change - RW1CS
+ UINT32 Plc : 1; // 22 Port Link State Change - RW1CS
+ UINT32 Cec : 1; // 23 Port Config Error Change - RW1CS/RsvdZ
+ UINT32 Cas : 1; // 24 Cold Attach Status - RO
+ UINT32 Wce : 1; // 25 Wake on Connect Enable - RWS
+ UINT32 Wde : 1; // 26 Wake on Disconnect Enable - RWS
+ UINT32 Woe : 1; // 27 Wake on Over-current Enable - RWS
+ UINT32 RsvdZ2 : 2; // 28..29
+ UINT32 Dr : 1; // 30 Device Removable (0 removable) - RO
+ UINT32 Wpr : 1; // 31 Warm Port Reset - RW1S/RsvdZ
+ } Field;
+ };
+} XHCI_PORTSC;
+
+typedef struct {
+ XHCI_USBCMD UsbCmd; // 00
+ XHCI_USBSTS UsbSts; // 04
+ UINT32 PageSize; // 08
+ UINT8 Rsvd1[8]; // 0C
+ UINT32 DnCtrl; // 14 Device Notification Control
+ UINT64 Crcr; // 18 Command Ring Control
+ UINT8 Rsvd2[16]; // 20
+ UINT64 DcbAap; // 30 Device Context Base Address Array Pointer
+ UINT32 Config; // 38 Max Device Slots Enabled
+} XHCI_HC_OP_REGS;
+
+
+#define CRCR_RING_CYCLE_STATE BIT0
+#define CRCR_COMMAND_STOP BIT1
+#define CRCR_COMMAND_ABORT BIT2
+#define CRCR_COMMAND_RUNNING BIT3
+
+// 6.5
+typedef struct {
+ UINT64 RsBase;
+ UINT16 RsSize;
+ UINT16 Rsvd1;
+ UINT32 Rsvd2;
+} XHCI_ER_SEGMENT_ENTRY;
+
+// Interrupt Moderation Interval (5.5.2.2)
+// Minimum inter-interrupt interval, in 250ns units. The value of 4000 makes 1ms interval.
+#define XHCI_IMODI 4000
+#define XHCI_KEYREPEAT_IMODI REPEAT_INTERVAL * 4000
+#define XHCI_KEYREPEAT_IMODC REPEAT_INTERVAL * 4000
+
+// Note: the following structure defines 32-bit and 64-bits fields
+// without detailing; this MMIO data must be accessed using Dword
+// access for 32-bit fields and Qword access for 64-bit, Section 5.5.
+typedef struct {
+ UINT32 IMan; // Interrupter Management
+ UINT32 IMod; // Interrupter Moderation
+ UINT32 Erstz; // Event Ring Segment Table Size
+ UINT32 RsrvP;
+ UINT64 Erstba; // Event Ring Segment Table Base Address
+ UINT64 Erdp; // Event Ring Dequeue Pointer
+} XHCI_INTERRUPTER_REGS;
+
+typedef struct {
+ UINT32 MfIndex;
+ UINT32 Reserved[7];
+ XHCI_INTERRUPTER_REGS IntRegs[1024];
+} XHCI_HC_RT_REGS;
+
+typedef enum {
+ XhciTNormal = 1,
+ XhciTSetupStage, // 2
+ XhciTDataStage, // 3
+ XhciTStatusStage,// 4
+ XhciTIsoch, // 5
+ XhciTLink, // 6
+ XhciTEventData, // 7
+ XhciTNoOp, // 8
+ XhciTEnableSlotCmd, // 9
+ XhciTDisableSlotCmd, // 10
+ XhciTAddressDeviceCmd, // 11
+ XhciTConfigureEndpointCmd, //12
+ XhciTEvaluateContextCmd, //13
+ XhciTResetEndpointCmd, //14
+ XhciTStopEndpointCmd, // 15
+ XhciTSetTRDequeuePointerCmd, //16
+ XhciTResetDeviceCmd, // 17
+ XhciTForceEventCmd, // 18
+ XhciTNegotiateBandwidthCmd, // 19
+ XhciTSetLatencyToleranceCmd, // 20
+ XhciTGetPortBandwidthCmd, // 21
+ XhciTForceHeaderCmd, // 22
+ XhciTNoOpCmd, // 23
+// 24..31 reserved
+ XhciTTransferEvt = 32,
+ XhciTCmdCompleteEvt, // 33
+ XhciTPortStatusChgEvt, // 34
+ XhciTBandwidthRequestEvt, // 35
+ XhciTDoorbellEvt, // 36
+ XhciTHostControllerEvt, // 37
+ XhciTDevNotificationEvt, // 38
+ XhciTMfIndexWrapEvt // 39
+} TRB_TYPE;
+
+//---------------------------------------------------------
+// Slot context definitions, Section 6.2.2
+//---------------------------------------------------------
+typedef struct {
+ UINT32 RouteString : 20;
+ UINT32 Speed : 4;
+ UINT32 RsvdZ1 : 1;
+ UINT32 MultiTT : 1;
+ UINT32 Hub : 1;
+ UINT32 ContextEntries : 5;
+
+ UINT32 MaxExitLatency : 16;
+ UINT32 RootHubPort : 8;
+ UINT32 PortsNum : 8;
+
+ UINT32 TtHubSlotId : 8;
+ UINT32 TtPortNumber : 8;
+ UINT32 TThinkTime : 2;
+ UINT32 RsvdZ3 : 4;
+ UINT32 Interrupter : 10;
+
+ UINT32 DevAddr : 8;
+ UINT32 RsvdZ4 : 19;
+ UINT32 SlotState : 5;
+
+ UINT32 RsvdO[4];
+} XHCI_SLOT_CONTEXT;
+
+// XHCI_SLOT_CONTEXT.DW3.SlotState definitions
+#define XHCI_SLOT_STATE_DISABLED 0
+#define XHCI_SLOT_STATE_DEFAULT 1
+#define XHCI_SLOT_STATE_ADDRESSED 2
+#define XHCI_SLOT_STATE_CONFIGURED 3
+
+
+//---------------------------------------------------------
+// Endpoint Context context definitions, Section 6.2.3
+//---------------------------------------------------------
+
+// Endpoint types, Table 57
+
+#define XHCI_EPTYPE_NOT_VALID 0
+#define XHCI_EPTYPE_ISOCH_OUT 1
+#define XHCI_EPTYPE_BULK_OUT 2
+#define XHCI_EPTYPE_INT_OUT 3
+#define XHCI_EPTYPE_CTL 4
+#define XHCI_EPTYPE_ISOCH_IN 5
+#define XHCI_EPTYPE_BULK_IN 6
+#define XHCI_EPTYPE_INT_IN 7
+
+typedef struct {
+ UINT32 EpState : 3;
+ UINT32 RsvdZ1 : 5;
+ UINT32 Mult : 2;
+ UINT32 MaxPStreams : 5;
+ UINT32 Lsa : 1;
+ UINT32 Interval : 8;
+ UINT32 RzvdZ2 : 8;
+
+ UINT32 RzvdZ3 : 1;
+ UINT32 ErrorCount : 2;
+ UINT32 EpType : 3;
+ UINT32 RsvdZ : 1;
+ UINT32 Hid : 1;
+ UINT32 MaxBurstSize : 8;
+ UINT32 MaxPacketSize : 16;
+
+ UINT64 TrDequeuePtr; // BIT0 of this field is DCS (Dequeue Cycle State)
+ UINT16 AvgTrbLength;
+ UINT16 MaxEsitPayload;
+ UINT32 RsvdO[3];
+} XHCI_EP_CONTEXT;
+
+// XHCI_EP_CONTEXT.DW0.State definitions
+#define XHCI_EP_STATE_DISABLED 0
+#define XHCI_EP_STATE_RUNNING 1
+#define XHCI_EP_STATE_HALTED 2
+#define XHCI_EP_STATE_STOPPED 3
+#define XHCI_EP_STATE_ERROR 4
+
+// XHCI_EP_CONTEXT.DW1.EpType definitions
+#define XHCI_EP_TYPE_NOTVALID 0
+#define XHCI_EP_TYPE_ISO_OUT 1
+#define XHCI_EP_TYPE_BLK_OUT 2
+#define XHCI_EP_TYPE_INT_OUT 3
+#define XHCI_EP_TYPE_CONTROL 4
+#define XHCI_EP_TYPE_ISO_IN 5
+#define XHCI_EP_TYPE_BLK_IN 6
+#define XHCI_EP_TYPE_INT_IN 7
+
+//---------------------------------------------------------
+// Device context definition
+//---------------------------------------------------------
+typedef struct {
+ XHCI_SLOT_CONTEXT Slot;
+ XHCI_EP_CONTEXT Ep[31];
+} XHCI_DEVICE_CONTEXT;
+
+#define XHCI_DEVICE_CONTEXT_ENTRIES 32
+
+// TRB completion codes Table 130
+#define XHCI_TRB_INVALID 0
+#define XHCI_TRB_SUCCESS 1
+#define XHCI_TRB_DATABUF_ERROR 2
+#define XHCI_TRB_BABBLE_ERROR 3
+#define XHCI_TRB_TRANSACTION_ERROR 4
+#define XHCI_TRB_TRB_ERROR 5
+#define XHCI_TRB_STALL_ERROR 6
+#define XHCI_TRB_RESOURCE_ERROR 7
+#define XHCI_TRB_BANDWIDTH_ERROR 8
+#define XHCI_TRB_OUTOFSLOTS_ERROR 9
+#define XHCI_TRB_INVALIDSTREAMTYPE_ERROR 10
+#define XHCI_TRB_SLOTNOTENABLED_ERROR 11
+#define XHCI_TRB_ENDPOINTNOTENABLED_ERROR 12
+#define XHCI_TRB_SHORTPACKET 13
+#define XHCI_TRB_RINGUNDERRUN 14
+#define XHCI_TRB_RINGOVERRUN 15
+#define XHCI_TRB_VFRINGFULL_ERROR 16
+#define XHCI_TRB_PARAMETER_ERROR 17
+#define XHCI_TRB_BANDWIDTHOVERRUN_ERROR 18
+#define XHCI_TRB_CONTEXTSTATE_ERROR 19
+#define XHCI_TRB_NOPINGRESPONSE_ERROR 20
+#define XHCI_TRB_EVENTRINGFULL_ERROR 21
+#define XHCI_TRB_MISSEDSERVICE_ERROR 23
+#define XHCI_TRB_CMDRINGSTOPPED 24
+#define XHCI_TRB_COMMANDABORTED 25
+#define XHCI_TRB_STOPPED 26
+#define XHCI_TRB_STOPPEDLENGTHINVALID 27
+#define XHCI_TRB_CONTROLABORT_ERROR 28
+#define XHCI_TRB_ISOCHBUFOVERRUN 31
+#define XHCI_TRB_EVENTLOST_ERROR 32
+#define XHCI_TRB_UNDEFINED_ERROR 33
+#define XHCI_TRB_INVALIDSTREAMID_ERROR 34
+#define XHCI_TRB_SECONDARYBANDWIDTH_ERROR 35
+#define XHCI_TRB_SPLITTRANSACTION_ERROR 36
+
+#define XHCI_TRB_EXECUTION_TIMEOUT_ERROR 255
+
+//---------------------------------------------------------
+// Transfer Descriptor Block (TRB) definitions, section 4.11
+//---------------------------------------------------------
+// TRB Template
+typedef struct {
+ UINT32 Param1;
+ UINT32 Param2;
+
+ UINT32 RsvdZ1 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 16;
+} XHCI_TRB;
+
+// Event TRB types, Section 6.4.2
+typedef struct {
+ UINT64 TrbPtr;
+
+ UINT32 TransferLength : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ1 : 1;
+ UINT32 EventData : 1;
+ UINT32 RsvdZ2 : 7;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RzvdZ3 : 3;
+ UINT32 SlotId : 8;
+} XHCI_TRANSFER_EVT_TRB;
+
+typedef struct {
+ UINT64 CmdTrbPtr;
+
+ UINT32 RsvdZ1 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 VfId : 8;
+ UINT32 SlotId : 8;
+} XHCI_CMDCOMPLETE_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1 : 24;
+ UINT32 PortId : 8;
+
+ UINT32 RsvdZ2;
+
+ UINT32 RsvdZ3 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ4 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ5 : 16;
+} XHCI_PORTSTSCHG_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[2];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 8;
+ UINT32 SlotId : 8;
+} XHCI_BANDWIDTHRQ_EVT_TRB;
+
+typedef struct {
+ UINT32 DbReason : 5;
+ UINT32 RsvdZ1 : 27;
+
+ UINT32 Rsvd2;
+
+ UINT32 RsvdZ3 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ4 : 9;
+ UINT32 TrbType : 6;
+ UINT32 VfId : 8;
+ UINT32 SlotId : 8;
+} XHCI_DORBELL_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[2];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 16;
+} XHCI_HC_EVT_TRB;
+
+typedef struct {
+ UINT8 RsvdZ1 : 4;
+ UINT8 NtfType : 4;
+
+ UINT8 DevNtfData[7];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 8;
+ UINT32 SlotId : 8;
+} XHCI_DEVNOTIFY_EVT_TRB;
+
+typedef struct {
+ UINT32 RsvdZ[2];
+
+ UINT32 RsvdZ2 : 24;
+ UINT32 CompletionCode : 8;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ3 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 16;
+} XHCI_MFINDXWRAP_EVT_TRB;
+
+typedef union {
+ XHCI_TRANSFER_EVT_TRB TransferEvt;
+ XHCI_CMDCOMPLETE_EVT_TRB CmdEvt;
+ XHCI_PORTSTSCHG_EVT_TRB PortStsChgEvt;
+ XHCI_BANDWIDTHRQ_EVT_TRB BandwidthRqEvt;
+ XHCI_DORBELL_EVT_TRB DoorbellEvt;
+ XHCI_HC_EVT_TRB HcEvt;
+ XHCI_DEVNOTIFY_EVT_TRB DevNotificationEvt;
+ XHCI_MFINDXWRAP_EVT_TRB MicroframeIndxWrapEvt;
+} XHCI_EVENT_TRB;
+
+// Command TRB types, Section 6.4.3
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 16;
+} XHCI_COMMON_CMD_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 8;
+ UINT32 SlotId : 8;
+} XHCI_DISABLESLOT_CMD_TRB;
+
+typedef struct {
+ UINT64 InpCtxAddress;
+ UINT32 RsvdZ1;
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 8;
+ UINT32 Bsr : 1;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 8;
+ UINT32 SlotId : 8;
+} XHCI_ADDRESSDEV_CMD_TRB;
+
+typedef struct {
+ UINT64 InpCtxAddress;
+ UINT32 RsvdZ1;
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 8;
+ UINT32 Dc : 1;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 8;
+ UINT32 SlotId : 8;
+} XHCI_CONFIGURE_EP_CMD_TRB;
+
+typedef struct {
+ UINT64 InpCtxAddress;
+ UINT32 RsvdZ1;
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ3 : 8;
+ UINT32 SlotId : 8;
+} XHCI_EVALUATE_CONTEXT_CMD_TRB;
+
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 8;
+ UINT32 Tsp : 1;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RsvdZ3 : 3;
+ UINT32 SlotId : 8;
+} XHCI_RESET_EP_CMD_TRB;
+
+typedef struct {
+ UINT64 TrPointer;
+
+ UINT32 RsvdZ1 :16;
+ UINT32 StreamId :16;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RsvdZ3 : 3;
+ UINT32 SlotId : 8;
+} XHCI_SET_TRPTR_CMD_TRB;
+ //(EIP54300+)>
+typedef struct {
+ UINT32 RsvdZ1[3];
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 9;
+ UINT32 TrbType : 6;
+ UINT32 EndpointId : 5;
+ UINT32 RsvdZ3 : 2;
+ UINT32 Suspend : 1;
+ UINT32 SlotId : 8;
+} XHCI_STOP_EP_CMD_TRB;
+ //<(EIP54300+)
+typedef union {
+ XHCI_COMMON_CMD_TRB GenericCmdTrb;
+ XHCI_COMMON_CMD_TRB NoOpCmdTrb;
+ XHCI_COMMON_CMD_TRB EnableSlotCmdTrb;
+ XHCI_DISABLESLOT_CMD_TRB DisableSlotCmdTrb;
+ XHCI_ADDRESSDEV_CMD_TRB AddressDevCmdTrb;
+ XHCI_SET_TRPTR_CMD_TRB SetTrPtrCmdTrb;
+} XHCI_CMD_TRB;
+
+// Transfer TRB types, Section 6.4.1
+
+typedef struct {
+ UINT64 DataBuffer;
+
+ UINT32 XferLength : 17;
+ UINT32 TdSize : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 Isp : 1;
+ UINT32 NoSnoop : 1;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ1 : 2;
+ UINT32 Bei : 1;
+ UINT32 TrbType : 6;
+ UINT32 Rsvd2 : 16;
+} XHCI_NORMAL_XFR_TRB;
+
+#define XHCI_XFER_TYPE_NO_DATA 0
+#define XHCI_XFER_TYPE_DATA_OUT 2
+#define XHCI_XFER_TYPE_DATA_IN 3
+
+typedef struct {
+ UINT8 bmRequestType;
+ UINT8 bRequest;
+ UINT16 wValue;
+ UINT16 wIndex;
+ UINT16 wLength;
+
+ UINT32 XferLength : 17;
+ UINT32 RsvdZ1 : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 RsvdZ2 : 4;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ3 : 3;
+ UINT32 TrbType : 6;
+ UINT32 Trt : 2;
+ UINT32 RsvdZ4 : 14;
+} XHCI_SETUP_XFR_TRB;
+
+typedef struct {
+ UINT64 DataBuffer;
+
+ UINT32 XferLength : 17;
+ UINT32 TdLength : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 Isp : 1;
+ UINT32 NoSnoop : 1;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ1 : 3;
+ UINT32 TrbType : 6;
+ UINT32 Dir : 1;
+ UINT32 Rsvd2 : 15;
+} XHCI_DATA_XFR_TRB;
+
+typedef struct {
+ UINT64 RsvdZ1;
+
+ UINT32 RsvdZ2 : 22;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 RsvdZ3 : 2;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 RsvdZ4 : 4;
+ UINT32 TrbType : 6;
+ UINT32 Dir : 1;
+ UINT32 Rsvd2 : 15;
+} XHCI_STATUS_XFR_TRB;
+
+typedef struct {
+ UINT64 DataBuffer;
+
+ UINT32 XferLength : 17;
+ UINT32 TdLength : 5;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 Isp : 1;
+ UINT32 NoSnoop : 1;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 Idt : 1;
+ UINT32 RsvdZ1 : 3;
+ UINT32 TrbType : 6;
+ UINT32 Rsvd2 : 4;
+ UINT32 FrameId : 11;
+ UINT32 Sia : 1;
+} XHCI_ISOCH_XFR_TRB;
+
+typedef struct {
+ UINT64 RsvdZ1;
+
+ UINT32 RsvdZ2 : 22;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 EvalNext : 1;
+ UINT32 RsvdZ3 : 2;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 RsvdZ4 : 4;
+ UINT32 TrbType : 6;
+ UINT32 Rsvd2 : 16;
+} XHCI_NOOP_XFR_TRB;
+
+typedef union {
+ XHCI_NORMAL_XFR_TRB NormalXfrTrb;
+ XHCI_SETUP_XFR_TRB SetupXfrTrb;
+ XHCI_DATA_XFR_TRB DataXfrTrb;
+ XHCI_STATUS_XFR_TRB StatusXfrTrb;
+ XHCI_ISOCH_XFR_TRB IsockXfrTrb;
+ XHCI_NOOP_XFR_TRB NoopXfrTrb;
+} XHCI_XFR_TRB;
+
+
+// Other TRB types
+typedef struct {
+ UINT64 NextSegPtr;
+
+ UINT32 RsvdZ1 : 22;
+ UINT32 Interrupter : 10;
+
+ UINT32 CycleBit : 1;
+ UINT32 ToggleCycle : 1;
+ UINT32 RsvdZ2 : 2;
+ UINT32 Chain : 1;
+ UINT32 Ioc : 1;
+ UINT32 RsvdZ3 : 4;
+ UINT32 TrbType : 6;
+ UINT32 RsvdZ4 : 16;
+} XHCI_LINK_TRB;
+
+typedef struct {
+ XHCI_TRB *Base;
+ UINT32 Size; // #of TRBs in the ring
+ XHCI_TRB* LastTrb;
+ XHCI_TRB* QueuePtr;
+ UINT8 CycleBit;
+ UINT8 Pad[27-3*sizeof(VOID*)]; // Make size 32 Bytes
+} TRB_RING;
+
+// The following definition fixes the size of ring
+// segment to TRBS_PER_SEGMENT * sizeof(XHCI_TRB)
+#define TRBS_PER_SEGMENT 64
+#define RING_SIZE TRBS_PER_SEGMENT*sizeof(XHCI_TRB)
+
+// Default timeouts
+#ifndef XHCI_CMD_COMPLETE_TIMEOUT_MS
+#define XHCI_CMD_COMPLETE_TIMEOUT_MS 20
+#endif
+#ifndef XHCI_ADDR_CMD_COMPLETE_TIMEOUT_MS
+#define XHCI_ADDR_CMD_COMPLETE_TIMEOUT_MS 2000
+#endif
+#ifndef XHCI_CTL_COMPLETE_TIMEOUT_MS
+#define XHCI_CTL_COMPLETE_TIMEOUT_MS 2000
+#endif
+//#define XHCI_BULK_COMPLETE_TIMEOUT_MS 15000 //(EIP61193)
+#ifndef XHCI_INT_COMPLETE_TIMEOUT_MS
+#define XHCI_INT_COMPLETE_TIMEOUT_MS 1500
+#endif
+
+#ifndef XHCI_RESET_PORT_DELAY_MS
+#define XHCI_RESET_PORT_DELAY_MS 10
+#endif
+
+#ifndef XHCI_RESET_EP_DELAY_MS
+#define XHCI_RESET_EP_DELAY_MS 10
+#endif
+
+//#define XHCI_BOT_TD_MAXSIZE 512
+#define XHCI_BOT_TD_MAXSIZE 0x10000
+#define XHCI_BOT_MAX_XFR_SIZE XHCI_BOT_TD_MAXSIZE*8
+
+#ifndef XHCI_SWITCH2SS_DELAY_MS
+#define XHCI_SWITCH2SS_DELAY_MS 5
+#endif
+
+#ifndef XHCI_WAIT_PORT_STABLE_DELAY_MS
+#define XHCI_WAIT_PORT_STABLE_DELAY_MS 50
+#endif
+
+#ifndef XHCI_MAX_PENDING_INTERRUPT_TRANSFER
+#define XHCI_MAX_PENDING_INTERRUPT_TRANSFER 16
+#endif
+
+//---------------------------------------------------------
+// Input context definition
+//---------------------------------------------------------
+typedef struct {
+ UINT32 DropContextFlags;
+ UINT32 AddContextFlags;
+ UINT32 RzvdZ[6];
+} XHCI_INPUT_CONTROL_CONTEXT;
+
+typedef struct {
+ XHCI_INPUT_CONTROL_CONTEXT CtlCtx;
+ XHCI_DEVICE_CONTEXT DevCtx;
+} XHCI_INPUT_CONTEXT;
+
+#define XHCI_INPUT_CONTEXT_ENTRIES 33
+
+//---------------------------------------------------------
+// Extended Capabilities
+//---------------------------------------------------------
+#define XHCI_EXT_CAP_USB_LEGACY 1
+#define XHCI_EXT_CAP_SUPPORTED_PROTOCOL 2
+#define XHCI_EXT_CAP_POWERMANAGEMENT 3
+#define XHCI_EXT_CAP_IO_VIRTUALIZATION 4
+#define XHCI_EXT_CAP_USB_DEBUG_PORT 10
+
+typedef struct {
+ UINT32 CapId:8; // Capability ID
+ UINT32 NextCapPtr:8; // Next xHCI Extended Capability Pointer
+ UINT32 Cap:16; // Capability Specific
+} XHCI_EXT_CAP;
+
+#define XHCI_BIOS_OWNED_SEMAPHORE BIT16
+#define XHCI_OS_OWNED_SEMAPHORE BIT24
+
+typedef struct {
+ UINT32 CapId:8;
+ UINT32 NextCapPtr:8;
+ UINT32 HcBiosOwned:1;
+ UINT32 RsvdP1:7;
+ UINT32 HcOsOwned:1;
+ UINT32 RsvdP2:7;
+} XHCI_LEGSUP;
+
+#define XHCI_SMI_ENABLE BIT0
+#define XHCI_SMI_HOST_ERROR_ENABLE BIT4
+#define XHCI_SMI_OWNERSHIP_CHANGE_ENABLE BIT13
+#define XHCI_SMI_PCI_CMD_ENABLE BIT14
+#define XHCI_SMI_PCI_BAR_ENABLE BIT15
+#define XHCI_SMI_EVENT_INT BIT16
+#define XHCI_SMI_HOST_ERROR BIT20
+#define XHCI_SMI_OWNERSHIP_CHANGE BIT29
+#define XHCI_SMI_PCI_CMD BIT30
+#define XHCI_SMI_PCI_BAR BIT31
+
+typedef union {
+ UINT32 AllBits;
+ struct {
+ UINT32 UsbSmiEnable:1;
+ UINT32 RsvdP1:3;
+ UINT32 UsbHostErrorSmiEnable:1;
+ UINT32 RsvdP2:8;
+ UINT32 UsbOwnershipChangeSmiEnable:1;
+ UINT32 UsbPciCmdSmiEnable:1;
+ UINT32 UsbPciBarSmiEnable:1;
+ UINT32 UsbEventInterruptSmi:1;
+ UINT32 RsvdP3:3;
+ UINT32 UsbHostErrorSmi:1;
+ UINT32 RsvdP4:8;
+ UINT32 UsbOwnershipChangeSmi:1;
+ UINT32 UsbPciCmdSmi:1;
+ UINT32 UsbPciBarSmi:1;
+ };
+} XHCI_LEGCTLSTS;
+
+typedef struct {
+ XHCI_LEGSUP LegSup;
+ XHCI_LEGCTLSTS LegCtlSts;
+} XHCI_EXT_LEG_CAP;
+
+typedef struct {
+ struct {
+ UINT32 CapId:8;
+ UINT32 NextCapPtr:8;
+ UINT32 MinorRev:8;
+ UINT32 MajorRev:8;
+ };
+
+ UINT32 NameString;
+
+ struct {
+ UINT32 PortOffset:8;
+ UINT32 PortCount:8;
+ UINT32 L1c:1; // L1 Capability
+ UINT32 Hso:1; // High-speed Only
+ UINT32 Ihi:1; // Integrated Hub Implemented
+ UINT32 RsvdZ:13;
+ };
+} XHCI_EXT_PROTOCOL;
+
+typedef struct {
+ UINT32 CapId:8;
+ UINT32 NextCapPtr:8;
+ UINT32 DcerstMax:5;
+ UINT32 RsvdP:11;
+} XHCI_DCID;
+
+typedef struct {
+ UINT32 RsvdP1:8;
+ UINT32 DbTarget:8;
+ UINT32 RsvdP2:16;
+} XHCI_DCDB;
+
+typedef struct {
+ UINT32 Erstsz:16;
+ UINT32 RsvdP:16;
+} XHCI_DCERSTSZ;
+
+typedef struct {
+ UINT64 RsvdP:4;
+ UINT64 Erstba:60;
+} XHCI_DCERSTBA;
+
+typedef struct {
+ UINT64 Desi:3;
+ UINT64 RsvdP:1;
+ UINT64 Erdp:60;
+} XHCI_DCERDP;
+
+typedef struct {
+ UINT32 Dcr:1;
+ UINT32 Lse:1;
+ UINT32 Hot:1;
+ UINT32 Hit:1;
+ UINT32 Drc:1;
+ UINT32 RsvdP:11;
+ UINT32 DbMaxBurstSize:8;
+ UINT32 DeviceAddr:7;
+ UINT32 Dce:1;
+} XHCI_DCCTRL;
+
+typedef struct {
+ UINT32 Er:1;
+ UINT32 Sbr:1;
+ UINT32 RsvdP:22;
+ UINT32 DbPortNum:8;
+} XHCI_DCST;
+
+typedef struct {
+ UINT32 Ccs:1;
+ UINT32 Ped:1;
+ UINT32 RsvdZ1:2;
+ UINT32 Pr:1;
+ UINT32 Pls:4;
+ UINT32 RsvdZ2:1;
+ UINT32 PortSpeed:4;
+ UINT32 RsvdZ3:3;
+ UINT32 Csc:1;
+ UINT32 RsvdZ4:3;
+ UINT32 Prc:1;
+ UINT32 Plc:1;
+ UINT32 Cec:1;
+ UINT32 RsvdZ5:8;
+} XHCI_DCPORTSC;
+
+typedef struct {
+ UINT64 RsvdP:4;
+ UINT64 Dccp:60;
+} XHCI_DCCP;
+
+typedef struct {
+ UINT32 DbcProtocol:8;
+ UINT32 RsvdP:8;
+ UINT32 VendorId:16;
+} XHCI_DCDDI1;
+
+typedef struct {
+ UINT32 ProductId:16;
+ UINT32 DeviceRevision:16;
+} XHCI_DCDDI2;
+
+typedef struct {
+ XHCI_DCID DcId;
+ XHCI_DCDB DcDb;
+ XHCI_DCERSTSZ DcErstsz;
+ UINT32 RsvdZ;
+ XHCI_DCERSTBA DcErstba;
+ XHCI_DCERDP DcErdp;
+ XHCI_DCCTRL DcCtrl;
+ XHCI_DCST DcSt;
+ XHCI_DCPORTSC DcPortSc;
+ UINT32 RsvdP;
+ XHCI_DCCP DcCp;
+ XHCI_DCDDI1 DcDdi1;
+ XHCI_DCDDI2 DcDdi2;
+} XHCI_DB_CAP_REGS;
+
+#pragma pack(pop)
+
+ //(EIP60460)>
+#define XHCI_FL100X_VID 0x1b73
+#define XHCI_FL1000_DID 0x1000
+#define XHCI_FL1009_DID 0x1009
+ //<(EIP60460)
+ //(EIP58979+)>
+#define XHCI_TUSB73X0_VID 0x104C
+#define XHCI_TUSB73X0_DID 0x8241
+ //<(EIP58979+)
+ //(EIP60327+)>
+#define XHCI_VL800_VID 0x1106
+#define XHCI_VL800_DID 0x3432
+ //<(EIP60327+)
+#define XHCI_EJ168A_VID 0x1B6F
+#define XHCI_EJ168A_DID 0x7023
+
+#define XHCI_AMD_SB900_VID 0x1022
+#define XHCI_AMD_SB900_DID 0x7812
+
+#define XHCI_NEC_VID 0x1033
+#define XHCI_NEC_200_DID 0x0194
+
+#define XHCI_INTEL_VID 0x8086
+
+typedef struct _XHCI_PENDING_POLLING{
+ XHCI_NORMAL_XFR_TRB *Trb;
+ UINT16 TransferredLength;
+}XHCI_PENDING_INTERRUPT_TRANSFER;
+
+typedef struct _USB3_HOST_CONTROLLER {
+ EFI_HANDLE Controller;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_USB2_HC_PROTOCOL Usb2HcProtocol;
+ XHCI_HC_CAP_REGS *CapRegs;
+ XHCI_HC_OP_REGS *OpRegs;
+ XHCI_HC_RT_REGS *RtRegs;
+ XHCI_EXT_LEG_CAP *ExtLegCap;
+ XHCI_EXT_PROTOCOL *Usb2Protocol;
+ XHCI_EXT_PROTOCOL *Usb3Protocol;
+ XHCI_DB_CAP_REGS *DbCapRegs;
+
+ UINT16 Vid;
+ UINT16 Did;
+ UINT16 HciVersion;
+ UINT8 MaxSlots;
+ UINT8 MaxPorts;
+ UINT16 MaxIntrs;
+ EFI_USB_HC_STATE HcState;
+ UINT32 PageSize4K;
+ UINT8 SBRN;
+ UINT8 ContextSize;
+ XHCI_DCBAA *DcbaaPtr;
+ TRB_RING CmdRing;
+ TRB_RING EvtRing;
+ TRB_RING *XfrRings;
+ UINTN XfrTrbs;
+ VOID *DeviceContext;
+ VOID *InputContext;
+ UINT32 DbOffset;
+ BOOLEAN Access64;
+ UINT64 *ScratchBufEntry;
+ XHCI_PENDING_INTERRUPT_TRANSFER PendingInterruptTransfer[XHCI_MAX_PENDING_INTERRUPT_TRANSFER];
+} USB3_HOST_CONTROLLER;
+
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
diff --git a/Core/EM/usb/setup/usb.sd b/Core/EM/usb/setup/usb.sd
new file mode 100644
index 0000000..89aeffe
--- /dev/null
+++ b/Core/EM/usb/setup/usb.sd
@@ -0,0 +1,1256 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Setup/usb.sd 48 12/24/14 10:40p Wilsonlee $
+//
+// $Revision: 48 $
+//
+// $Date: 12/24/14 10:40p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Setup/usb.sd $
+//
+// 48 12/24/14 10:40p Wilsonlee
+// [TAG] EIP196287
+// [Category] Improvement
+// [Description] Display info of connected usb controllers and remove or
+// grayed-out some item according the connected usb controller number.
+// [Files] uhcd.c, usbport.c, usb.uni, usb.sd, usbsetup.c,
+// AmiUsbController.h, UsbPolicy.h
+//
+// 47 12/23/14 10:27p Wilsonlee
+// [TAG] EIP196897
+// [Category] Improvement
+// [Description] Hide USB legacy support setup question if
+// USB_RUNTIME_DRIVER_IN_SMM is 0.
+// [Files] usb.sd
+//
+// 46 12/17/14 9:18p Wilsonlee
+// [TAG] EIP196712
+// [Category] Improvement
+// [Description] Change usb form definition to USB_FORM _USB.
+// [Files] usb.sd
+//
+// 45 11/23/14 10:30p Wilsonlee
+// [TAG] EIP190205
+// [Category] Improvement
+// [Description] Add the token "DEFAULT_XHCI_HANDOFF_OPTION" that
+// controls the default value of the XHCI Hand-off option.
+// [Files] usb.sdl, usb.sd
+//
+// 44 7/28/14 11:25p Wilsonlee
+// [TAG] EIP176898
+// [Category] Improvement
+// [Description] Use suppressif TRUE to hide the setup item.
+// [Files] usb.sd
+//
+// 43 4/29/14 10:23p Wilsonlee
+// [TAG] EIP161709
+// [Category] New Feature
+// [Description] Dynamically update the usb device list in BIOS setup.
+// [Files] usb.sdl, usb.sd, usbsetup.c, uhcd.c
+//
+// 42 10/20/13 10:33p Wilsonlee
+// [TAG] EIP138258
+// [Category] New Feature
+// [Description] Change option name "USB3.0 Support" to "XHCI Legacy
+// Support" and add the token
+// "HIDE_USB_XHCI_LEGACY_SUPPORT_SETUP_QUESTION" to switch to hide/Un-hide
+// USB XHCI Legacy Support setup question.
+// [Files] usb.sd, usb.uni, usb.sdl
+//
+// 41 5/27/13 2:21a Ryanchou
+// [TAG] EIP122407
+// [Category] Improvement
+// [Description] Move the USB varstore out ADVANCED_FORM_SET definition
+// check.
+// [Files] usb.sd
+//
+// 40 4/16/13 11:08a Ryanchou
+// Fix compile error if toke EFI_SPECIFICATION_VERSION greater than
+// 0x2000.
+//
+// 39 3/19/13 4:03a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 38 1/11/13 4:25a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 37 12/21/12 5:04a Ryanchou
+// [TAG] EIP71730
+// [Category] New Feature
+// [Description] Added OHCI handoff support.
+// [Files] usb.sdl, usbport.c, amiusb.c, usbdef.h, UsbPolicy.h, usb.sd,
+// usb.uni
+//
+// 36 10/25/12 1:38a Wilsonlee
+// [TAG] EIP102493
+// [Category] New Feature
+// [Description] USB Module version is added to the setup page.
+// [Files] usbsetup.c, usb.sd, usb.uni
+//
+// 35 9/04/12 8:02a Wilsonlee
+// [TAG] EIP99882
+// [Category] New Feature
+// [Description] Add the usb setup item and usbpolicyprotocol to enable
+// or disable the usb mass storage driver.
+// [Files] UsbPolicy.h, usb.uni, usb.sd, usbmass.c, usbdef.h,
+// efiusbmass.c, usbport.c, uhcd.c
+//
+// 34 8/07/12 9:38p Wilsonlee
+// [TAG] EIP96366
+// [Category] New Feature
+// [Description] Add the token "DEFAULT_USB_EMUL6064_OPTION" that
+// control the default value of the I/O port 60h/64h emulation support
+// option.
+// [Files] usb.sd, usb.sdl, amiusb.c, amiusb.h
+//
+// 33 7/12/12 2:35a Roberthsu
+// [TAG] EIP93460
+// [Category] Improvement
+// [Description] Add token decide mass available under efi application
+// when legacy support disabled.
+// [Files] usb.sd,usb.uni,usbmass.c,usbsrc.sdl
+//
+// 32 5/04/12 2:30a Wilsonlee
+// [TAG] EIP89212
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Build process stopped with EIP83614 change.
+// [RootCause] Build error when the token "EFI_SPECIFICATION_VERSION" is
+// 0x20000.
+// [Solution] Rollback the EIP83614 changee to avoid this issue.
+// [Files] usb.sd
+//
+// 31 5/03/12 5:09a Ryanchou
+// [TAG] EIP83361
+// [Category] New Feature
+// [Description] Added "USB 2.0 Controller Mode" setup item.
+// [Files] ehci.c, usb.sd, usb.sdl, usb.uni, usbdef.h, UsbPolicy.h,
+// usbport.c
+//
+// 30 3/04/12 9:41p Wilsonlee
+// [TAG] EIP83614
+// [Category] Improvement
+// [Description] Manufacturing mode fixes.
+// [Files] usb.sd
+//
+// 29 2/18/11 1:13a Ryanchou
+// [TAG] EIP48184
+// [Category] Improvement
+// [Description] Update files according to the new Setup Customization
+// guidelines.
+// [Files] usb.sd, UsbPolicy.h
+//
+// 28 10/12/10 2:31a Rameshr
+// [TAG]- EIP 44585
+// [Category]-IMPROVEMENT
+// [Description]- Number of maximum supported USB Mass Storage device
+// increased from 8 to 16.
+// [Files]- Uin13.bin, UsbPort.c, UsbInt13.h, Usb.c, Usbdef.h, Uasbmass.c,
+// Usb.sd, usb.uni, UsbSetup.c, UsbSrc.sdl, UsbPolicy.h
+//
+// 27 7/13/10 7:15a Ryanchou
+// EIP38356: Implement shutdown USB legacy support in ACPI enable call.
+//
+// 26 5/20/10 2:10p Olegi
+//
+// 25 5/17/10 5:20p Robert
+// two setup questions were using SUPPRESS_GRAYOUT_ENDIF when they should
+// only be using endif; PowerGoodDeviceDelay and UsbXhciSupport. The
+// change makes it UEFI 2.1 compliant
+//
+// 24 5/17/10 4:09p Olegi
+// Removed unnecessary inclusion of TOKEN.H
+//
+// 23 4/19/10 1:52p Olegi
+//
+// 22 4/12/10 12:19p Olegi
+// Moving structure definitions to the .H file. EIP36942
+//
+// 21 3/02/10 10:10a Olegi
+//
+// 20 12/10/09 10:13a Olegi
+// Added UsbControlTimeout setup selection. EIP30079.
+//
+// 19 11/10/09 8:54a Olegi
+// EIP30149: HII 2.1 compliance.
+//
+// 18 9/09/09 3:14p Davidd
+// Added "USB Support" setup question - EIP 25360
+//
+// 17 5/21/09 5:18p Olegi
+// Added hotplug devices support.
+//
+// 16 10/24/08 3:04p Olegi
+//
+// 15 8/12/08 10:34a Fasihm
+// Added the Manufacturing flag to all the setup questions.
+//
+// 14 7/04/08 1:04p Olegi
+//
+// 13 5/16/08 12:07p Olegi
+// Compliance with AMI coding standard.
+//
+// 11 6/04/07 11:07a Fasihm
+// Changed the setup structures to use OneOf instead of CheckBox, so as to
+// reset the system based on change in the setup options.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: usb.sd
+//
+// Description: This is the setup page 'USB Configuration.'
+// The link to the page is in the setup 'Advanced' tab.
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#ifdef SETUP_DATA_DEFINITION
+/***********************************************************/
+/* Put NVRAM data definitions here.
+/* For example: UINT8 Data1;
+/* These definitions will be converted by the build process
+/* to a definitions of SETUP_DATA fields.
+/***********************************************************/
+#endif
+
+#if defined(VFRCOMPILE) && !defined(CONTROLS_ARE_DEFINED)
+#define CONTROL_DEFINITION
+#endif
+#ifdef CONTROL_DEFINITION
+
+#define USB_ONEOF_USBMAINSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbMainSupport,\
+ prompt = STRING_TOKEN(STR_USB_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_SUPPORT_HELP),\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ endoneof;
+ //(EIP93460)>
+#if LEGACY_USB_DISABLE_FOR_USB_MASS
+#if USB_RUNTIME_DRIVER_IN_SMM
+#define USB_ONEOF_USBLEGACYSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbLegacySupport,\
+ prompt = STRING_TOKEN(STR_USB_LEGACY_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_LEGACY_SUPPORT_HELP1),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define USB_ONEOF_USBLEGACYSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbLegacySupport,\
+ prompt = STRING_TOKEN(STR_USB_LEGACY_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_LEGACY_SUPPORT_HELP1),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#endif
+#else
+#if USB_RUNTIME_DRIVER_IN_SMM
+#define USB_ONEOF_USBLEGACYSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbLegacySupport,\
+ prompt = STRING_TOKEN(STR_USB_LEGACY_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_LEGACY_SUPPORT_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define USB_ONEOF_USBLEGACYSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbLegacySupport,\
+ prompt = STRING_TOKEN(STR_USB_LEGACY_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_LEGACY_SUPPORT_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 2, flags = RESET_REQUIRED;\
+ endoneof;
+#endif
+#endif
+ //<(EIP93460)
+#define USB_ONEOF_USBHISPEEDSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbHiSpeedSupport,\
+ prompt = STRING_TOKEN(STR_USB_HISPEED_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_HISPEED_SUPPORT_HELP),\
+ option text = STRING_TOKEN(STR_USB_HISPEED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_FULLSPEED), value = 0, flags = RESET_REQUIRED;\
+ endoneof;
+
+#if XHCI_SUPPORT
+#define USB_ONEOF_USBXHCISUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbXhciSupport,\
+ prompt = STRING_TOKEN(STR_USB_XHCI_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_XHCI_SUPPORT_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED ;\
+ endoneof;
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#define USB_ONEOF_USBXHCIHANDOFF\
+ oneof varid = USB_SUPPORT_SETUP.UsbXhciHandoff,\
+ prompt = STRING_TOKEN(STR_USB_BIOS_XHCI_HANDOFF),\
+ help = STRING_TOKEN(STR_USB_BIOS_XHCI_HANDOFF_HELP),\
+ default = DEFAULT_XHCI_HANDOFF_OPTION,\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED ;\
+ endoneof;
+#else
+#define USB_ONEOF_USBXHCIHANDOFF\
+ oneof varid = USB_SUPPORT_SETUP.UsbXhciHandoff,\
+ prompt = STRING_TOKEN(STR_USB_BIOS_XHCI_HANDOFF),\
+ help = STRING_TOKEN(STR_USB_BIOS_XHCI_HANDOFF_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED ;\
+ endoneof;
+#endif
+#else
+#define USB_ONEOF_USBXHCISUPPORT
+#define USB_ONEOF_USBXHCIHANDOFF
+#endif
+
+#if USB_EHCI_HANDOFF_SUPPORT
+#define USB_ONEOF_USBEHCIHANDOFF\
+ oneof varid = USB_SUPPORT_SETUP.UsbEhciHandoff,\
+ prompt = STRING_TOKEN(STR_USB_BIOS_EHCI_HANDOFF),\
+ help = STRING_TOKEN(STR_USB_BIOS_EHCI_HANDOFF_HELP),\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define USB_ONEOF_USBEHCIHANDOFF
+#endif
+
+#if USB_OHCI_HANDOFF_SUPPORT
+#define USB_ONEOF_USBOHCIHANDOFF\
+ oneof varid = USB_SUPPORT_SETUP.UsbOhciHandoff,\
+ prompt = STRING_TOKEN(STR_USB_BIOS_OHCI_HANDOFF),\
+ help = STRING_TOKEN(STR_USB_BIOS_OHCI_HANDOFF_HELP),\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+#else
+#define USB_ONEOF_USBOHCIHANDOFF
+#endif
+
+#if USB_DEV_MASS
+#define USB_ONEOF_USBMASSDRIVERSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbMassDriverSupport,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DRIVER_SUPPORT),\
+ help = STRING_TOKEN(STR_USB_MASS_DRIVER_SUPPORT_HELP),\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+#else
+#define USB_ONEOF_USBMASSDRIVERSUPPORT
+#endif
+
+#if defined (EMUL6064_SUPPORT) && EMUL6064_SUPPORT
+#if EFI_SPECIFICATION_VERSION > 0x20000
+#define USB_ONEOF_USBEMUL6064\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmul6064,\
+ prompt = STRING_TOKEN(STR_USB_6064),\
+ help = STRING_TOKEN(STR_USB_6064_HELP),\
+ default = DEFAULT_USB_EMUL6064_OPTION,\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+#else
+#define USB_ONEOF_USBEMUL6064\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmul6064,\
+ prompt = STRING_TOKEN(STR_USB_6064),\
+ help = STRING_TOKEN(STR_USB_6064_HELP),\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ endoneof;
+#endif
+#else
+#define USB_ONEOF_USBEMUL6064
+#endif
+
+#if defined (USB_HOTPLUG_FDD) && USB_HOTPLUG_FDD
+#define USB_ONEOF_USBHOTPLUGFDDSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbHotplugFddSupport,\
+ prompt = STRING_TOKEN(STR_USB_HOTPLUG_FDD),\
+ help = STRING_TOKEN(STR_USB_HOTPLUG_FDD_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 2, flags = RESET_REQUIRED | MANUFACTURING | DEFAULT ;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 3, flags = RESET_REQUIRED ;\
+ endoneof;
+#else
+#define USB_ONEOF_USBHOTPLUGFDDSUPPORT
+#endif
+
+#if defined (USB_HOTPLUG_HDD) && USB_HOTPLUG_HDD
+#define USB_ONEOF_USBHOTPLUGHDDSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbHotplugHddSupport,\
+ prompt = STRING_TOKEN(STR_USB_HOTPLUG_HDD),\
+ help = STRING_TOKEN(STR_USB_HOTPLUG_HDD_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 2, flags = RESET_REQUIRED | MANUFACTURING | DEFAULT ;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 3, flags = RESET_REQUIRED ;\
+ endoneof;
+#else
+#define USB_ONEOF_USBHOTPLUGHDDSUPPORT
+#endif
+
+#if defined (USB_HOTPLUG_CDROM) && USB_HOTPLUG_CDROM
+#define USB_ONEOF_USBHOTPLUGCDROMSUPPORT\
+ oneof varid = USB_SUPPORT_SETUP.UsbHotplugCdromSupport,\
+ prompt = STRING_TOKEN(STR_USB_HOTPLUG_CDROM),\
+ help = STRING_TOKEN(STR_USB_HOTPLUG_CDROM_HELP),\
+ option text = STRING_TOKEN(STR_USB_ENABLED), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_DISABLED), value = 2, flags = RESET_REQUIRED | MANUFACTURING | DEFAULT ;\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 3, flags = RESET_REQUIRED ;\
+ endoneof;
+#else
+#define USB_ONEOF_USBHOTPLUGCDROMSUPPORT
+#endif
+
+#define USB_ONEOF_USBCONTROLTIMEOUT\
+ oneof varid = USB_SUPPORT_SETUP.UsbControlTimeOut,\
+ prompt = STRING_TOKEN(STR_USB_CONTROL_TIME_OUT),\
+ help = STRING_TOKEN(STR_USB_CONTROL_TIME_OUT_HELP),\
+ option text = STRING_TOKEN(STR_USB_DELAY_01), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DELAY_05), value = 5, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DELAY_10), value = 10, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DELAY_20), value = 20, flags = RESET_REQUIRED | MANUFACTURING | DEFAULT;\
+ endoneof;
+
+#define USB_ONEOF_USBMASSRESETDELAY\
+ oneof varid = USB_SUPPORT_SETUP.UsbMassResetDelay,\
+ prompt = STRING_TOKEN(STR_USB_MASS_RESET_DELAY),\
+ help = STRING_TOKEN(STR_USB_MASS_RESET_DELAY_HELP),\
+ option text = STRING_TOKEN(STR_USB_DELAY_10), value = 0, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DELAY_20), value = 1, flags = RESET_REQUIRED | MANUFACTURING | DEFAULT;\
+ option text = STRING_TOKEN(STR_USB_DELAY_30), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DELAY_40), value = 3, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define USB_ONEOF_POWERGOODDEVICEDELAY\
+ oneof varid = USB_SUPPORT_SETUP.PowerGoodDeviceDelay,\
+ prompt = STRING_TOKEN(STR_USB_POWERGOOD_DELAY),\
+ help = STRING_TOKEN(STR_USB_POWERGOOD_DELAY_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_DELAY_VALUE), value = 1, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define USB_NUMERIC_POWERGOODDEVICENUMDELAY\
+ numeric varid = USB_SUPPORT_SETUP.PowerGoodDeviceNumDelay,\
+ prompt = STRING_TOKEN (STR_USB_DELAY_NUM_VALUE),\
+ help = STRING_TOKEN (STR_USB_DELAY_NUM_VALUE_HELP),\
+ flags = RESET_REQUIRED,\
+ minimum = 1,\
+ maximum = 40,\
+ step = 1,\
+ default = 5,\
+ endnumeric;
+
+#if USB_MASS_EMULATION_NATIVE
+#define USB_ONEOF_USBEMU1\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu1,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE1),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU2\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu2,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE2),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU3\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu3,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE3),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU4\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu4,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE4),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU5\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu5,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE5),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU6\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu6,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE6),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU7\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu7,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE7),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU8\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu8,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE8),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU9\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu9,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE9),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU10\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu10,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE10),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU11\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu11,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE11),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU12\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu12,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE12),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU13\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu13,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE13),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+#define USB_ONEOF_USBEMU14\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu14,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE14),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU15\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu15,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE15),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU16\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu16,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE16),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP1),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+#else //#if USB_MASS_EMULATION_NATIVE
+#define USB_ONEOF_USBEMU1\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu1,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE1),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU2\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu2,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE2),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU3\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu3,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE3),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU4\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu4,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE4),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU5\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu5,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE5),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU6\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu6,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE6),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU7\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu7,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE7),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU8\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu8,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE8),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU9\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu9,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE9),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU10\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu10,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE10),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU11\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu11,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE11),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU12\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu12,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE12),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU13\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu13,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE13),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+#define USB_ONEOF_USBEMU14\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu14,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE14),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU15\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu15,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE15),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+
+#define USB_ONEOF_USBEMU16\
+ oneof varid = USB_SUPPORT_SETUP.UsbEmu16,\
+ prompt = STRING_TOKEN(STR_USB_MASS_DEVICE16),\
+ help = STRING_TOKEN(STR_USB_EMULATION_TYPE_HELP),\
+ option text = STRING_TOKEN(STR_USB_AUTO), value = 0, flags = DEFAULT | MANUFACTURING | RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FLOPPY), value = 1, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_FORCED_FDD), value = 2, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_HDD), value = 3, flags = RESET_REQUIRED ;\
+ option text = STRING_TOKEN(STR_USB_EMUL_CDROM), value = 4, flags = RESET_REQUIRED ;\
+ endoneof;
+#endif //#if USB_MASS_EMULATION_NATIVE
+
+#endif //#ifdef CONTROL_DEFINITION
+
+
+#ifdef CONTROLS_WITH_DEFAULTS
+
+USB_ONEOF_USBMAINSUPPORT // UINT8 UsbMainSupport; // Disable \[Enable]
+USB_ONEOF_USBLEGACYSUPPORT // UINT8 UsbLegacySupport; //[Enable]\ Disable \ Auto
+USB_ONEOF_USBHISPEEDSUPPORT // UINT8 UsbHiSpeedSupport; //[HiSpeed]\ FullSpeed
+USB_ONEOF_USBXHCISUPPORT // UINT8 UsbXhciSupport; //[Enable]\ Disable
+USB_ONEOF_USBXHCIHANDOFF // UINT8 UsbXhciHandoff; //[Enable]\ Disable
+USB_ONEOF_USBEHCIHANDOFF // UINT8 UsbEhciHandoff; //[Disable] \ Enable
+USB_ONEOF_USBMASSDRIVERSUPPORT // UINT8 UsbMassDriverSupport; // Disable \[Enable]
+USB_ONEOF_USBEMUL6064 // UINT8 UsbEmul6064; // Disable \[Enable]
+USB_ONEOF_USBHOTPLUGFDDSUPPORT // UINT8 UsbHotplugFddSupport; // Enable \[Disable]\ Auto
+USB_ONEOF_USBHOTPLUGHDDSUPPORT // UINT8 UsbHotplugHddSupport; // Enable \[Disable]\ Auto
+USB_ONEOF_USBHOTPLUGCDROMSUPPORT // UINT8 UsbHotplugCdromSupport; // Enable \[Disable]\ Auto
+USB_ONEOF_USBCONTROLTIMEOUT // UINT8 UsbControlTimeOut; // 1 sec \ 5 sec \ 10 sec \[20 sec]
+USB_ONEOF_USBMASSRESETDELAY // UINT8 UsbMassResetDelay; // 10 sec \[20 sec]\ 30 sec \ 40sec
+USB_ONEOF_POWERGOODDEVICEDELAY // UINT8 PowerGoodDeviceDelay; //[Auto]\ Manual
+USB_NUMERIC_POWERGOODDEVICENUMDELAY // UINT8 PowerGoodDeviceNumDelay; //[1...40] (seconds)
+USB_ONEOF_USBEMU1 // UINT8 UsbEmu1; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU2 // UINT8 UsbEmu2; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU3 // UINT8 UsbEmu3; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU4 // UINT8 UsbEmu4; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU5 // UINT8 UsbEmu5; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU6 // UINT8 UsbEmu6; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU7 // UINT8 UsbEmu7; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU8 // UINT8 UsbEmu8; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU9 // UINT8 UsbEmu9; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU10 // UINT8 UsbEmu10; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU11 // UINT8 UsbEmu11; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU12 // UINT8 UsbEmu12; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU13 // UINT8 UsbEmu13; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU14 // UINT8 UsbEmu14; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU15 // UINT8 UsbEmu15; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+USB_ONEOF_USBEMU16 // UINT8 UsbEmu16; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+
+#endif //#ifdef CONTROLS_WITH_DEFAULTS
+
+#ifdef FORM_SET_TYPEDEF
+ #include <Protocol\UsbPolicy.h>
+#endif
+
+#ifdef FORM_SET_VARSTORE
+ varstore USB_MASS_DEV_NUM,
+ key = AUTO_ID(USB_MASS_DEV_NUM_KEY),
+ name = UsbMassDevNum,
+ guid = SETUP_GUID;
+
+ varstore USB_MASS_DEV_VALID,
+ key = AUTO_ID(USB_MASS_DEV_VALID_KEY),
+ name = UsbMassDevValid,
+ guid = SETUP_GUID;
+
+ varstore USB_CONTROLLER_NUM,
+ key = AUTO_ID(USB_CONTROLLER_NUM_KEY),
+ name = UsbControllerNum,
+ guid = SETUP_GUID;
+
+ varstore USB_SUPPORT_SETUP,
+ key = AUTO_ID(USB_SUPPORT_KEY),
+ name = UsbSupport,
+ guid = SETUP_GUID;
+#endif
+
+//**********************************************************************
+// ADVANCED - USB Configuration Form
+//**********************************************************************
+#ifdef ADVANCED_FORM_SET
+
+#ifndef SUPPRESS_GRAYOUT_ENDIF //old Core
+#define SUPPRESS_GRAYOUT_ENDIF endif;
+#endif
+
+ #ifdef FORM_SET_ITEM
+ //
+ // Define controls to be added to the main page of the formset
+ //
+ #endif
+
+ #ifdef FORM_SET_GOTO
+ //
+ // Define goto commands for the forms defined in this file
+ //
+ goto USB_CONFIG_FORM_ID,
+ prompt = STRING_TOKEN(STR_USB_CONFIGURATION),
+ help = STRING_TOKEN(STR_USB_CONFIGURATION_HELP);
+ #endif
+
+ #ifdef FORM_SET_FORM
+ //
+ // Define forms
+ //
+ #ifndef USB_FORM_USB
+ #define USB_FORM_USB
+ form formid = AUTO_ID(USB_CONFIG_FORM_ID),
+ title = STRING_TOKEN(STR_USB_CONFIGURATION);
+
+ SUBTITLE(STRING_TOKEN(STR_USB_CONFIGURATION))
+ SEPARATOR
+ //(EIP102493+)>
+ //Display USB Module Version.
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_USB_MODULE_VER_HELP),
+ text = STRING_TOKEN(STR_USB_MODULE_VER),
+ flags = 0,
+ key = 0;
+
+ SEPARATOR
+ //<(EIP102493+)
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_USB_CONTROLLERS_ENABLED),
+ text = STRING_TOKEN(STR_EMPTY),
+ flags = 0,
+ key = 0;
+ SUBTITLE(STRING_TOKEN(STR_USB_CONTROLLERS_ENABLED_LIST))
+
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_USB_DEVICES_ENABLED),
+ text = STRING_TOKEN(STR_EMPTY),
+ flags = 0,
+ key = 0;
+
+ SUBTITLE(STRING_TOKEN(STR_USB_DEVICES_ENABLED_LIST))
+ SEPARATOR
+// UINT8 UsbMainSupport; // Disable \[Enable]
+#if HIDE_USB_SUPPORT_SETUP_QUESTION
+ suppressif ideqid USB_SUPPORT_SETUP.UsbMainSupport == USB_SUPPORT_SETUP.UsbMainSupport;
+#endif
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBMAINSUPPORT
+ endif;
+#if HIDE_USB_SUPPORT_SETUP_QUESTION
+#if EFI_SPECIFICATION_VERSION>0x20000
+ endif; // suppress-grayout
+#endif
+#endif
+// UINT8 UsbLegacySupport; //[Enable]\ Disable \ Auto
+#if USB_RUNTIME_DRIVER_IN_SMM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0;
+#else
+ suppressif TRUE;
+#endif
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBLEGACYSUPPORT
+ SUPPRESS_GRAYOUT_ENDIF
+
+#if EHCI_SUPPORT
+#if HIDE_USB_HISPEED_SUPPORT_SETUP_QUESTION
+ suppressif TRUE;
+#else
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_CONTROLLER_NUM.EhciNum == 0;
+#endif
+// UINT8 UsbHiSpeedSupport; //[HiSpeed]\ FullSpeed
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBHISPEEDSUPPORT
+ endif;
+#if EFI_SPECIFICATION_VERSION>0x20000
+ endif; // suppress-grayout
+#endif
+#endif
+
+#if XHCI_SUPPORT
+#if HIDE_USB_XHCI_LEGACY_SUPPORT_SETUP_QUESTION
+ suppressif TRUE;
+#else
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_CONTROLLER_NUM.XhciNum == 0;
+#endif
+// UINT8 UsbXhciSupport; //[Enable]\ Disable
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBXHCISUPPORT
+ endif;
+#if EFI_SPECIFICATION_VERSION>0x20000
+ endif; // suppress-grayout
+#endif
+
+// UINT8 UsbXhciHandoff; //[Enable]\ Disable
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_CONTROLLER_NUM.XhciNum == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBXHCIHANDOFF
+ endif;
+#if EFI_SPECIFICATION_VERSION>0x20000
+ endif; // suppress-grayout
+#endif
+#endif
+#if USB_EHCI_HANDOFF_SUPPORT
+// UINT8 UsbEhciHandoff; //[Disable] \ Enable
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_CONTROLLER_NUM.EhciNum == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBEHCIHANDOFF
+ SUPPRESS_GRAYOUT_ENDIF
+#endif
+
+#if USB_OHCI_HANDOFF_SUPPORT
+// UINT8 UsbOhciHandoff; //[Disable] \ Enable
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_CONTROLLER_NUM.OhciNum == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBOHCIHANDOFF
+ SUPPRESS_GRAYOUT_ENDIF
+#endif
+
+ #if USB_DEV_MASS
+// UINT8 UsbMassDriverSupport; // Disable \[Enable]
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_USBMASSDRIVERSUPPORT
+ SUPPRESS_GRAYOUT_ENDIF
+ #endif
+
+ #if defined (EMUL6064_SUPPORT) && EMUL6064_SUPPORT
+// UINT8 UsbEmul6064; // Disable \[Enable]
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER;
+ USB_ONEOF_USBEMUL6064
+ SUPPRESS_GRAYOUT_ENDIF
+ #endif
+
+ #if defined (USB_HOTPLUG_FDD) && USB_HOTPLUG_FDD
+// UINT8 UsbHotplugFddSupport; // Enable \[Disable]\ Auto
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_USBHOTPLUGFDDSUPPORT
+ SUPPRESS_GRAYOUT_ENDIF
+ #endif
+
+ #if defined (USB_HOTPLUG_HDD) && USB_HOTPLUG_HDD
+// UINT8 UsbHotplugHddSupport; // Enable \[Disable]\ Auto
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_USBHOTPLUGHDDSUPPORT
+ SUPPRESS_GRAYOUT_ENDIF
+ #endif
+
+ #if defined (USB_HOTPLUG_CDROM) && USB_HOTPLUG_CDROM
+// UINT8 UsbHotplugCdromSupport; // Enable \[Disable]\ Auto
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_USBHOTPLUGCDROMSUPPORT
+ SUPPRESS_GRAYOUT_ENDIF
+ #endif
+
+ SEPARATOR
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_USB_DELAYS),
+ text = STRING_TOKEN(STR_EMPTY),
+ flags = 0,
+ key = 0;
+
+//(EIP30079+)>
+// UINT8 UsbControlTimeOut; // 1 sec \ 5 sec \ 10 sec \[20 sec]
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_USBCONTROLTIMEOUT
+ SUPPRESS_GRAYOUT_ENDIF
+//<(EIP30079+)
+// UINT8 UsbMassResetDelay; // 10 sec \[20 sec]\ 30 sec \ 40sec
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_USBMASSRESETDELAY
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 PowerGoodDeviceDelay; //[Auto]\ Manual
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_ONEOF_POWERGOODDEVICEDELAY
+ endif;
+// UINT8 PowerGoodDeviceNumDelay; //[1...40] (seconds)
+ suppressif ideqval USB_SUPPORT_SETUP.PowerGoodDeviceDelay == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR (
+ ideqval USB_CONTROLLER_NUM.UhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.OhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.EhciNum == 0 AND
+ ideqval USB_CONTROLLER_NUM.XhciNum == 0);
+ USB_NUMERIC_POWERGOODDEVICENUMDELAY
+ SUPPRESS_GRAYOUT_ENDIF
+
+ SEPARATOR
+
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0;
+ text
+ help = STRING_TOKEN(STR_EMPTY),
+ text = STRING_TOKEN(STR_USB_EMULATION),
+ text = STRING_TOKEN(STR_EMPTY),
+ flags = 0,
+ key = 0;
+ endif;
+// UINT8 UsbEmu1; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu1Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU1
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu2; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu2Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU2
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu3; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+// suppressif ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 2 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 1 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu3Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU3
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu4; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+// suppressif ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 3 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 2 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 1 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu4Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU4
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu5; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+// suppressif ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 4 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 3 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 2 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 1 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu5Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU5
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu6; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+// suppressif ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 5 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 4 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 3 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 2 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 1 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu6Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU6
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu7; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+// suppressif ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 6 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 5 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 4 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 3 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 2 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 1 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu7Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU7
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu8; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+// suppressif ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 7 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 6 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 5 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 4 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 3 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 2 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 1 OR ideqval USB_MASS_DEV_NUM.UsbMassDevNum == 0 OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu8Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU8
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu9; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu9Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU9
+ SUPPRESS_GRAYOUT_ENDIF
+
+// UINT8 UsbEmu10; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu10Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU10
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu11; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu11Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU11
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu12; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu12Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU12
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu13; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu13Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU13
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu14; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu14Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU14
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu15; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu15Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU15
+ SUPPRESS_GRAYOUT_ENDIF
+// UINT8 UsbEmu16; //[Auto] \ Floppy \ Forced FDD \ Hard Disk \ CD-ROM
+ suppressif ideqval USB_SUPPORT_SETUP.UsbMainSupport == 0 OR ideqval USB_MASS_DEV_VALID.UsbEmu16Valid == 0;
+ grayoutif ideqval SYSTEM_ACCESS.Access == SYSTEM_PASSWORD_USER OR ideqval USB_SUPPORT_SETUP.UsbLegacySupport == 1;
+ USB_ONEOF_USBEMU16
+ SUPPRESS_GRAYOUT_ENDIF
+
+ INTERACTIVE_TEXT(STRING_TOKEN(STR_EMPTY), \
+ STRING_TOKEN(STR_EMPTY), \
+ STRING_TOKEN(STR_EMPTY), \
+ AUTO_ID(USB_DEVICES_ENABLED_REFRESH_KEY))
+
+ endform;
+
+ #endif //#ifndef USB_FORM_USB
+
+ #endif
+
+#endif // ADVANCED_FORM_SET
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/usb/setup/usb.uni b/Core/EM/usb/setup/usb.uni
new file mode 100644
index 0000000..a3a9a63
--- /dev/null
+++ b/Core/EM/usb/setup/usb.uni
Binary files differ
diff --git a/Core/EM/usb/setup/usbsetup.c b/Core/EM/usb/setup/usbsetup.c
new file mode 100644
index 0000000..5b7cfe7
--- /dev/null
+++ b/Core/EM/usb/setup/usbsetup.c
@@ -0,0 +1,804 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/Setup/usbsetup.c 24 12/24/14 10:40p Wilsonlee $
+//
+// $Revision: 24 $
+//
+// $Date: 12/24/14 10:40p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/Setup/usbsetup.c $
+//
+// 24 12/24/14 10:40p Wilsonlee
+// [TAG] EIP196287
+// [Category] Improvement
+// [Description] Display info of connected usb controllers and remove or
+// grayed-out some item according the connected usb controller number.
+// [Files] uhcd.c, usbport.c, usb.uni, usb.sd, usbsetup.c,
+// AmiUsbController.h, UsbPolicy.h
+//
+// 23 8/20/14 5:26a Wilsonlee
+// [TAG] EIP182011
+// [Category] Improvement
+// [Description] We don't need to update NVRAM variables in
+// InstallUsbMass and UninstallUSBMass functions.
+// [Files] efiusbmass.c, usbsetup.c
+//
+// 22 6/26/14 1:18a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 21 5/07/14 10:37a Wilsonlee
+// [TAG] EIP166594
+// [Category] Improvement
+// [Description] Add the token "USB_SETUP_VARIABLE_RUNTIME_ACCESS" to
+// control if we set runtime attribute for the setup variables used by USB
+// module.
+// [Files] usb.sdl, usbport.c, usbsetup.c
+//
+// 20 4/29/14 10:23p Wilsonlee
+// [TAG] EIP161709
+// [Category] New Feature
+// [Description] Dynamically update the usb device list in BIOS setup.
+// [Files] usb.sdl, usb.sd, usbsetup.c, uhcd.c
+//
+// 19 2/08/13 3:33a Roberthsu
+// [TAG] EIP112379
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB device information is incorrect in Setup.
+// [RootCause] Memory copy size error.
+// [Solution] Change copy point device string size.
+// [Files] usbsetup.c
+//
+// 18 10/25/12 1:37a Wilsonlee
+// [TAG] EIP102493
+// [Category] New Feature
+// [Description] USB Module version is added to the setup page.
+// [Files] usbsetup.c, usb.sd, usb.uni
+//
+// 17 7/15/11 6:32a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 16 7/12/11 8:19a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 15 10/14/10 4:42p Olegi
+// - Tabs replaced with spaces
+// - Changed the existing logic of getting strings correlated to device
+// number: from hardcoded table that was limted to 10 elements only (snum
+// array). If more than 10 devices used, the whole logic caused memory
+// corruption that ended with CPU exception.
+// - Changed the logic of conversion decimal number to CHAR16 string +
+// space as required.
+// - Added limitations for input numbers to be smaller than 127 which is
+// USB max device address; this limitation should never be approached but
+// it protects string operations on numbers.
+//
+// 14 10/12/10 2:34a Rameshr
+// [TAG]- EIP 44585
+// [Category]-IMPROVEMENT
+// [Description]- Number of maximum supported USB Mass Storage device
+// increased from 8 to 16.
+// [Files]- Uin13.bin, UsbPort.c, UsbInt13.h, Usb.c, Usbdef.h, Uasbmass.c,
+// Usb.sd, usb.uni, UsbSetup.c, UsbSrc.sdl, UsbPolicy.h
+//
+// 13 4/12/10 12:19p Olegi
+// Moving structure definitions to the .H file. EIP36942
+//
+// 12 1/29/10 5:15p Olegi
+//
+// 11 11/10/09 8:54a Olegi
+// EIP30149: HII 2.1 compliance.
+//
+// 10 9/09/09 3:18p Davidd
+// Removed the assertion caused by USB support disabled in setup - EIP
+// 25360
+//
+// 9 12/18/08 10:47a Olegi
+// Variable gEfiSetupGuid made static.
+//
+// 8 7/04/08 1:04p Olegi
+//
+// 7 6/27/08 6:00p Olegi
+//
+// 6 5/16/08 12:07p Olegi
+// Compliance with AMI coding standard.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbSetup.c
+//
+// Description: USB driver setup related functions implementation.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <AmiLib.h>
+#include <AmiDxeLib.h>
+#include <Setup.h>
+#include <SetupStrTokens.h>
+#include "Protocol/AMiUsbController.h"
+#include <Protocol/UsbPolicy.h>
+
+#define MAX_DEVS_LINE_LENGTH 80
+#define MAX_DEVICE_NUMBER_LENGTH 10
+#define MAX_DEVICE_AMOUNT 127
+
+static EFI_GUID gEfiSetupGuid = SETUP_GUID;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetConnectedDevices
+//
+// Description: This function retrieves the information about connected
+// USB devices.
+//
+// Output: returns TRUE if device connection status has changed since this
+// function is called last time; otherwise FALSE.
+// Notes: When FALSE is returned, none of the output parameters are valid.
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetConnectedDevices(
+ CHAR16 *DevNumStr,
+ CHAR16 *ControllerNumStr,
+ EFI_USB_PROTOCOL *UsbProtocol,
+ CONNECTED_USB_DEVICES_NUM *Devs
+)
+{
+ CHAR16 StrMassStorage[] = L"Drive";
+ CHAR16 StrKeyboard[] = L"Keyboard";
+ CHAR16 StrMouse[] = L"Mouse";
+ CHAR16 StrPoint[] = L"Point"; //(EIP38434+)
+ CHAR16 StrMice[] = L"Mice";
+ CHAR16 StrHub[] = L"Hub";
+ CHAR16 StrCcid[] = L"SmartCard Reader";
+ CHAR16 StrUhci[] = L"UHCI";
+ CHAR16 StrOhci[] = L"OHCI";
+ CHAR16 StrEhci[] = L"EHCI";
+ CHAR16 StrXhci[] = L"XHCI";
+ CHAR16 Name[MAX_DEVS_LINE_LENGTH];
+ CHAR16 *StrPtr = Name;
+ CHAR16 NumberToString [MAX_DEVICE_NUMBER_LENGTH];
+ UINTN NumSize;
+ CHAR16 Comma[] = L", ";
+ CHAR16 Space[] = L" ";
+ CHAR16 LeadingSpace[] = L" None";
+ UINT8 MassStorageNumber;
+ UINT8 KeyboardNumber;
+ UINT8 MouseNumber;
+ UINT8 PointNumber;
+ UINT8 HubNumber;
+ UINT8 CcidNumber; //(EIP38434)
+ UINT8 UhciNumber;
+ UINT8 OhciNumber;
+ UINT8 EhciNumber;
+ UINT8 XhciNumber;
+ BOOLEAN Is1stItem = TRUE;
+
+ UsbProtocol->UsbReportDevices(Devs);
+ MassStorageNumber = Devs->NumUsbMass;
+ KeyboardNumber = Devs->NumUsbKbds;
+ MouseNumber = Devs->NumUsbMice;
+ PointNumber = Devs->NumUsbPoint;
+ HubNumber = Devs->NumUsbHubs;
+ CcidNumber = Devs->NumUsbCcids;
+ UhciNumber = Devs->NumUhcis;
+ OhciNumber = Devs->NumOhcis;
+ EhciNumber = Devs->NumEhcis;
+ XhciNumber = Devs->NumXhcis;
+
+ // Form the string
+ pBS->SetMem(StrPtr, MAX_DEVS_LINE_LENGTH * sizeof(CHAR16), 0);
+ pBS->CopyMem(StrPtr, LeadingSpace, 10 * sizeof(CHAR16));
+ StrPtr += 6; // leave string pointer at "None"
+
+ // Drive/Drives
+ if ((MassStorageNumber) && (MassStorageNumber < MAX_DEVICE_AMOUNT)) {
+ ItowEx(MassStorageNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1;
+
+ pBS->CopyMem(StrPtr, StrMassStorage, 10);
+ StrPtr += 5; // L"Drive"
+ if (MassStorageNumber > 1) {
+ *StrPtr++ = L's'; // L"Drives"
+ }
+ Is1stItem = FALSE;
+ }
+
+ // Keyboard/Keyboards
+ if ((KeyboardNumber) && (KeyboardNumber < MAX_DEVICE_AMOUNT)) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(KeyboardNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1;
+
+ pBS->CopyMem(StrPtr, StrKeyboard, 16);
+ StrPtr += 8; // L"Keyboard"
+ if (KeyboardNumber > 1) {
+ *StrPtr++ = L's'; // L"Keyboards"
+ }
+ Is1stItem = FALSE;
+ }
+
+ // Mouse/Mice
+ if ((MouseNumber) && (MouseNumber < MAX_DEVICE_AMOUNT)) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(MouseNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1;
+
+ if (MouseNumber == 1) {
+ pBS->CopyMem(StrPtr, StrMouse, 10);
+ StrPtr += 5; // L"Mouse"
+ } else {
+ pBS->CopyMem(StrPtr, StrMice, 8);
+ StrPtr += 4; // L"Mice"
+ }
+ Is1stItem = FALSE;
+ }
+ //(EIP38434+)>
+ // Point/Points
+ if ((PointNumber) && (PointNumber < MAX_DEVICE_AMOUNT)) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(PointNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1;
+
+ pBS->CopyMem(StrPtr, StrPoint, 10);
+ StrPtr += 5; // L"Point"
+ if (PointNumber > 1) {
+ *StrPtr++ = L's'; // L"Points"
+ }
+ Is1stItem = FALSE;
+ }
+ //<(EIP38434+)
+ // Hub/Hubs
+ if ((HubNumber) && (HubNumber < MAX_DEVICE_AMOUNT)) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(HubNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1;
+ pBS->CopyMem(StrPtr, StrHub, 6);
+ StrPtr += 3; // L"Hub"
+ if (HubNumber > 1) {
+ *StrPtr++ = L's'; // L"Hubs"
+ }
+ Is1stItem = FALSE;
+ }
+ // Ccid/Ccids
+ if (CcidNumber) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(CcidNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1; // L" "
+
+ pBS->CopyMem(StrPtr, StrCcid, 32);
+ StrPtr += 16; // L"SmartCard Reader"
+ if (CcidNumber > 1) {
+ *StrPtr++ = L's'; // L'SmartCard Readers'
+ }
+ Is1stItem = FALSE;
+ }
+
+ pBS->CopyMem(DevNumStr, Name, MAX_DEVS_LINE_LENGTH * sizeof(CHAR16));
+
+ Is1stItem = TRUE;
+ StrPtr = Name;
+ // Form the string
+ pBS->SetMem(StrPtr, MAX_DEVS_LINE_LENGTH * sizeof(CHAR16), 0);
+ pBS->CopyMem(StrPtr, LeadingSpace, 10 * sizeof(CHAR16));
+ StrPtr += 6; // leave string pointer at "None"
+
+ // Drive/Drives
+ if (UhciNumber) {
+ ItowEx(UhciNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1;
+
+ pBS->CopyMem(StrPtr, StrUhci, 8);
+ StrPtr += 4; // L"UHCI"
+ if (UhciNumber > 1) {
+ *StrPtr++ = L's'; // L"UHCIs"
+ }
+ Is1stItem = FALSE;
+ }
+
+ if (OhciNumber) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(OhciNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1; // L" "
+
+ pBS->CopyMem(StrPtr, StrOhci, 8);
+ StrPtr += 4; // L"OHCI"
+ if (OhciNumber > 1) {
+ *StrPtr++ = L's'; // L'OHCIs'
+ }
+ Is1stItem = FALSE;
+ }
+
+ if (EhciNumber) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(EhciNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1; // L" "
+
+ pBS->CopyMem(StrPtr, StrEhci, 8);
+ StrPtr += 4; // L"EHCI"
+ if (EhciNumber > 1) {
+ *StrPtr++ = L's'; // L'EHCIs'
+ }
+ Is1stItem = FALSE;
+ }
+
+ if (XhciNumber) {
+ if (!Is1stItem) {
+ pBS->CopyMem(StrPtr, Comma, 4);
+ StrPtr += 2; // L" ,"
+ }
+ ItowEx(XhciNumber, NumberToString, 10, FALSE);
+ NumSize = Wcslen(NumberToString);
+
+ // move pointer 1 more space then string length
+ pBS->CopyMem(StrPtr, NumberToString, (NumSize * sizeof (CHAR16)));
+ StrPtr += NumSize;
+
+ // move pointer 1 more space
+ pBS->CopyMem(StrPtr, Space, 2);
+ StrPtr += 1; // L" "
+
+ pBS->CopyMem(StrPtr, StrXhci, 8);
+ StrPtr += 4; // L"XHCI"
+ if (XhciNumber > 1) {
+ *StrPtr++ = L's'; // L'XHCIs'
+ }
+ Is1stItem = FALSE;
+ }
+
+ pBS->CopyMem(ControllerNumStr, Name, MAX_DEVS_LINE_LENGTH * sizeof(CHAR16));
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetMassDeviceName
+//
+// Description: This function retrieves the USB mass storage device ASCII name.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+GetMassDeviceName(
+ UINT8 *DevName,
+ UINT8 DevAddr,
+ EFI_USB_PROTOCOL *UsbProtocol
+)
+{
+ CHAR8 Data[48];
+ UINT8 NextDev;
+
+ // Get the name using USBMassAPIGetDeviceInformation
+ NextDev = UsbProtocol->UsbGetNextMassDeviceName(Data, sizeof(Data), DevAddr);
+ if (NextDev != 0xFF) {
+ Sprintf((char*)DevName, "%a", Data);
+ }
+ return NextDev;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: InitUSBStrings
+//
+// Description: This function is eLink'ed with the chain executed right before
+// the Setup.
+//
+//----------------------------------------------------------------------------
+
+VOID
+InitUSBStrings(
+ EFI_HII_HANDLE HiiHandle,
+ UINT16 Class
+)
+{
+ CHAR16 DevNumStr[MAX_DEVS_LINE_LENGTH];
+ CHAR16 ControllerNumStr[MAX_DEVS_LINE_LENGTH];
+ CHAR8 MassStr[MAX_DEVS_LINE_LENGTH];
+ UINT8 NextDev;
+ UINT16 MassDev[16] = {
+ STRING_TOKEN(STR_USB_MASS_DEVICE1),
+ STRING_TOKEN(STR_USB_MASS_DEVICE2),
+ STRING_TOKEN(STR_USB_MASS_DEVICE3),
+ STRING_TOKEN(STR_USB_MASS_DEVICE4),
+ STRING_TOKEN(STR_USB_MASS_DEVICE5),
+ STRING_TOKEN(STR_USB_MASS_DEVICE6),
+ STRING_TOKEN(STR_USB_MASS_DEVICE7),
+ STRING_TOKEN(STR_USB_MASS_DEVICE8),
+ STRING_TOKEN(STR_USB_MASS_DEVICE9),
+ STRING_TOKEN(STR_USB_MASS_DEVICE10),
+ STRING_TOKEN(STR_USB_MASS_DEVICE11),
+ STRING_TOKEN(STR_USB_MASS_DEVICE12),
+ STRING_TOKEN(STR_USB_MASS_DEVICE13),
+ STRING_TOKEN(STR_USB_MASS_DEVICE14),
+ STRING_TOKEN(STR_USB_MASS_DEVICE15),
+ STRING_TOKEN(STR_USB_MASS_DEVICE16)
+
+ };
+ UINT8 MassDevValid[16];
+ UINT8 i;
+ UINTN VariableSize;
+ USB_MASS_DEV_NUM SetupData;
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *UsbProtocol;
+ EFI_GUID UsbProtocolGuid = EFI_USB_PROTOCOL_GUID;
+ CONNECTED_USB_DEVICES_NUM DevNum;
+ UINT32 VariableAttributes = EFI_VARIABLE_BOOTSERVICE_ACCESS;
+ USB_CONTROLLER_NUM UsbControllerNum;
+
+#if USB_SETUP_VARIABLE_RUNTIME_ACCESS
+ VariableAttributes |= EFI_VARIABLE_RUNTIME_ACCESS;
+#endif
+
+
+ if (Class!=ADVANCED_FORM_SET_CLASS) {
+ return;
+ }
+ //(EIP102493+)>
+ InitString(HiiHandle, STRING_TOKEN(STR_USB_MODULE_VER), L"%d.%02d.%02d",
+ USB_DRIVER_MAJOR_VER, USB_DRIVER_MINOR_VER, USB_DRIVER_BUILD_VER);
+ //<(EIP102493+)
+
+ Status = pBS->LocateProtocol(&UsbProtocolGuid, NULL, &UsbProtocol);
+//#### ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ // Number of connected devices
+ GetConnectedDevices(DevNumStr, ControllerNumStr, UsbProtocol, &DevNum);
+
+ TRACE((-1, "Devices total: %d KBDs, %d HUBs, %d MICE, %d POINT %d MASS %d CCID\n",
+ DevNum.NumUsbKbds, DevNum.NumUsbHubs, DevNum.NumUsbMice,
+ DevNum.NumUsbPoint, DevNum.NumUsbMass, DevNum.NumUsbCcids));
+
+ InitString(HiiHandle, STRING_TOKEN(STR_USB_DEVICES_ENABLED_LIST), L"%s", DevNumStr);
+ InitString(HiiHandle, STRING_TOKEN(STR_USB_CONTROLLERS_ENABLED_LIST), L"%s", ControllerNumStr);
+
+ // Mass storage device names
+ for (i = 0, NextDev = 0; i < 16; i++) {
+ NextDev = GetMassDeviceName(MassStr, NextDev, UsbProtocol);
+ if (NextDev == 0xFF) {
+ break; // No more devices
+ }
+ InitString(HiiHandle, MassDev[i], L"%S", MassStr);
+ if (NextDev & 0x80) {
+ break; // Last device
+ }
+ }
+
+ for (i = 0; i < 16; i++) {
+ if (i < DevNum.NumUsbMass) {
+ MassDevValid[i] = 1;
+ } else {
+ MassDevValid[i] = 0;
+ }
+ }
+
+ VariableSize = sizeof(USB_MASS_DEV_VALID);
+
+ Status = pRS->SetVariable(L"UsbMassDevValid",
+ &gEfiSetupGuid,
+ VariableAttributes,
+ VariableSize,
+ &MassDevValid);
+
+ VariableSize = sizeof(SetupData);
+ Status = pRS->GetVariable(L"UsbMassDevNum",
+ &gEfiSetupGuid,
+ NULL,
+ &VariableSize,
+ &SetupData);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ SetupData.IsInteractionAllowed = 0;
+ SetupData.UsbMassDevNum = DevNum.NumUsbMass;
+
+ Status = pRS->SetVariable(L"UsbMassDevNum",
+ &gEfiSetupGuid,
+ VariableAttributes,
+ VariableSize,
+ &SetupData);
+
+ VariableSize = sizeof(UsbControllerNum);
+ Status = pRS->GetVariable(L"UsbControllerNum",
+ &gEfiSetupGuid,
+ NULL,
+ &VariableSize,
+ &UsbControllerNum);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ UsbControllerNum.UhciNum = DevNum.NumUhcis;
+ UsbControllerNum.OhciNum = DevNum.NumOhcis;
+ UsbControllerNum.EhciNum = DevNum.NumEhcis;
+ UsbControllerNum.XhciNum = DevNum.NumXhcis;
+
+ Status = pRS->SetVariable(L"UsbControllerNum",
+ &gEfiSetupGuid,
+ VariableAttributes,
+ VariableSize,
+ &UsbControllerNum);
+
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: UpdateUSBStrings
+//
+// Description: This function is updating usb setup page dynamically.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UpdateUSBStrings(
+ EFI_HII_HANDLE HiiHandle,
+ UINT16 Class,
+ UINT16 SubClass,
+ UINT16 Key
+)
+{
+ UINT8 MassDevValid[16];
+ UINT8 i;
+ UINT8 NextDev;
+ UINTN VariableSize;
+ EFI_GUID UsbProtocolGuid = EFI_USB_PROTOCOL_GUID;
+ EFI_STATUS Status;
+ EFI_USB_PROTOCOL *UsbProtocol;
+ CONNECTED_USB_DEVICES_NUM DevNum;
+ USB_MASS_DEV_NUM MassDevNumData;
+ USB_CONTROLLER_NUM UsbControllerNum;
+ CHAR16 DevNumStr[MAX_DEVS_LINE_LENGTH];
+ CHAR16 ControllerNumStr[MAX_DEVS_LINE_LENGTH];
+ CHAR8 MassStr[MAX_DEVS_LINE_LENGTH];
+ UINT16 MassDev[16] = {
+ STRING_TOKEN(STR_USB_MASS_DEVICE1),
+ STRING_TOKEN(STR_USB_MASS_DEVICE2),
+ STRING_TOKEN(STR_USB_MASS_DEVICE3),
+ STRING_TOKEN(STR_USB_MASS_DEVICE4),
+ STRING_TOKEN(STR_USB_MASS_DEVICE5),
+ STRING_TOKEN(STR_USB_MASS_DEVICE6),
+ STRING_TOKEN(STR_USB_MASS_DEVICE7),
+ STRING_TOKEN(STR_USB_MASS_DEVICE8),
+ STRING_TOKEN(STR_USB_MASS_DEVICE9),
+ STRING_TOKEN(STR_USB_MASS_DEVICE10),
+ STRING_TOKEN(STR_USB_MASS_DEVICE11),
+ STRING_TOKEN(STR_USB_MASS_DEVICE12),
+ STRING_TOKEN(STR_USB_MASS_DEVICE13),
+ STRING_TOKEN(STR_USB_MASS_DEVICE14),
+ STRING_TOKEN(STR_USB_MASS_DEVICE15),
+ STRING_TOKEN(STR_USB_MASS_DEVICE16)
+ };
+
+ if (Key == USB_DEVICES_ENABLED_REFRESH_KEY) {
+
+ Status = pBS->LocateProtocol(&UsbProtocolGuid, NULL, &UsbProtocol);
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ // Number of connected devices
+ GetConnectedDevices(DevNumStr, ControllerNumStr, UsbProtocol, &DevNum);
+
+ InitString(HiiHandle, STRING_TOKEN(STR_USB_DEVICES_ENABLED_LIST), L"%s", DevNumStr);
+
+ // Mass storage device names
+ for (i = 0, NextDev = 0; i < 16; i++) {
+ NextDev = GetMassDeviceName(MassStr, NextDev, UsbProtocol);
+ if (NextDev == 0xFF) {
+ break; // No more devices
+ }
+ InitString(HiiHandle, MassDev[i], L"%S", MassStr);
+ if (NextDev & 0x80) {
+ break; // Last device
+ }
+ }
+
+ VariableSize = sizeof(MassDevValid);
+
+ Status = HiiLibGetBrowserData(
+ &VariableSize, &MassDevValid,
+ &gEfiSetupGuid, L"UsbMassDevValid");
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ for (i = 0; i < 16; i++) {
+ if (i < DevNum.NumUsbMass) {
+ MassDevValid[i] = 1;
+ } else {
+ MassDevValid[i] = 0;
+ }
+ }
+
+ Status = HiiLibSetBrowserData(
+ VariableSize, &MassDevValid,
+ &gEfiSetupGuid, L"UsbMassDevValid");
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ VariableSize = sizeof(MassDevNumData);
+
+ Status = HiiLibGetBrowserData(
+ &VariableSize, &MassDevNumData,
+ &gEfiSetupGuid, L"UsbMassDevNum");
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ MassDevNumData.UsbMassDevNum = DevNum.NumUsbMass;
+
+ Status = HiiLibSetBrowserData(
+ VariableSize, &MassDevNumData,
+ &gEfiSetupGuid, L"UsbMassDevNum");
+
+ VariableSize = sizeof(UsbControllerNum);
+
+ Status = HiiLibGetBrowserData(
+ &VariableSize, &UsbControllerNum,
+ &gEfiSetupGuid, L"UsbControllerNum");
+
+ if (EFI_ERROR(Status)) {
+ return;
+ }
+
+ UsbControllerNum.UhciNum = DevNum.NumUhcis;
+ UsbControllerNum.OhciNum = DevNum.NumOhcis;
+ UsbControllerNum.EhciNum = DevNum.NumEhcis;
+ UsbControllerNum.XhciNum = DevNum.NumXhcis;
+
+ Status = HiiLibSetBrowserData(
+ VariableSize, &UsbControllerNum,
+ &gEfiSetupGuid, L"UsbControllerNum");
+
+ }
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2014, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/usb/setup/usbsetup.cif b/Core/EM/usb/setup/usbsetup.cif
new file mode 100644
index 0000000..a81fde2
--- /dev/null
+++ b/Core/EM/usb/setup/usbsetup.cif
@@ -0,0 +1,10 @@
+<component>
+ name = "UsbSetup"
+ category = ModulePart
+ LocalRoot = "core\em\usb\setup"
+ RefName = "USB_SETUP"
+[files]
+"\usb.uni"
+"\usb.sd"
+"\usbsetup.c"
+<endComponent>
diff --git a/Core/EM/usb/tree.c b/Core/EM/usb/tree.c
new file mode 100644
index 0000000..bb4c275
--- /dev/null
+++ b/Core/EM/usb/tree.c
@@ -0,0 +1,374 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/tree.c 10 12/16/08 10:51a Olegi $
+//
+// $Revision: 10 $
+//
+// $Date: 12/16/08 10:51a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/tree.c $
+//
+// 10 12/16/08 10:51a Olegi
+// Correction in the return values: 0 changed to NULL. EIP#17767.
+//
+// 8 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 7 3/20/07 1:29p Olegi
+//
+// 5 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 4 6/15/05 1:59p Andriyn
+// Comments were changed
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//-----------------------------------------------------------------------------
+//
+// Name: TREE.C
+//
+// Description: USB tree manipulation routines
+//
+//-----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+
+#include "Efi.h"
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+
+#include "tree.h"
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TreeCreate
+//
+// Description: initializes TREENODE_T structure
+//
+// Input:
+// n - pointer to TREENODE_T structure
+// d - pointer to data structure specific to
+// the type of tree node
+//
+// Output: Pointer to TREENODE_T structure that was passed in as parrameter
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TREENODE_T* TreeCreate( TREENODE_T* n, VOID* d )
+{
+ n->data = d;
+ n->child = 0;
+ n->right = 0;
+ n->left = 0;
+ n->parent = 0;
+ return n;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TreeAddChild
+//
+// Description: add a child node to the TREENODE_T structure
+//
+// Input:
+// p - pointer to parent TREENODE_T structure
+// c - pointer to child TREENODE_T structure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID TreeAddChild( TREENODE_T* p, TREENODE_T* c )
+{
+ TREENODE_T* n = p->child;
+ //for( n = p->child; n != NULL; n = n->right );
+ p->child = c;
+ c->right = n;
+ if(n!=0)
+ n->left = c;
+ c->left = 0;
+ c->parent = p;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TreeRemove
+//
+// Description: removes a node from the tree
+//
+// Input:
+// n - pointer to TREENODE_T structure
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID TreeRemove( TREENODE_T* n )
+{
+ if( n->right != 0){
+ n->right->left = n->left;
+ }
+ if( n->left != 0){
+ n->left->right = n->right;
+ }
+ if( n->parent && n->parent->child == n )
+ n->parent->child = n->right;
+ n->left = 0;
+ n->right = 0;
+ n->parent = 0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TreeSearchSibling
+//
+// Description: Enumerates nodes of the tree which are direct children of
+// the same parent
+//
+// Input:
+// n - pointer to TREENODE_T structure
+// pr - predicate function that is called for each node
+// and controll whether enumeration should continue
+// once predicate returns TRUE the enumeration will
+// data - pointer that is passed to predicate to maintain
+// the context of the enumeration
+//
+// Output: the node that cause enumeration to stop
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TREENODE_T* TreeSearchSibling( TREENODE_T* n, TREE_PREDICATE1_T pr, VOID* data )
+{
+ TREENODE_T *r;
+ for(;n;n=r){
+ r = n->right;
+ if(pr(n->data,data))return n;
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TreeSearchDeep
+//
+// Description: Enumerates nodes of the tree which are direct and indirect
+// children of the same parent
+//
+// Input:
+// n - pointer to TREENODE_T structure
+// pr - predicate function that is called for each node;
+// controlls whether enumeration should continue
+// once predicate returns TRUE the enumeration will
+// data - pointer that is passed to predicate to maintain
+// the context of the enumeration
+//
+// Output: the node that cause enumeration to stop
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TREENODE_T* TreeSearchDeep( TREENODE_T* n, TREE_PREDICATE1_T pr, VOID* data )
+{
+ TREENODE_T *r;
+ TREENODE_T *c;
+ for(;n;n=r){
+ r = n->right;
+ c = n->child;
+ if(pr(n->data,data))return n;
+ if(c){
+ TREENODE_T* c1 = TreeSearchDeep(n->child,pr,data);
+ if(c1)
+ return c1;
+ }
+ }
+ return 0;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: TreeForEachSibling
+//
+// Description: Enumerates nodes of the tree which are direct children of
+// the same parent; In contrust to TreeSearchSibling this
+// function ignores the result returned from call-back routine
+// and always enumerates all sibling nodes
+//
+// Input:
+// n - pointer to TREENODE_T structure
+// pr - call-back function that is called for each node
+// data - pointer that is passed to call-back to maintain
+// the context of the enumeration
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID TreeForEachSibling( TREENODE_T* n, TREE_CALLBACK_T pr, VOID* data )
+{
+ for(;n;n=n->right)
+ pr(n->data,data);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: QueueGet
+//
+// Description: retrieves data stored at the tail of the queue and
+// removes the tail item
+//
+// Input:
+// q - pointer to QUEUE_T structure
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID* QueueGet( QUEUE_T* q)
+{
+ VOID* d;
+ if( q->tail == q->head ) return NULL;
+ d = q->data[q->tail++];
+ if( q->tail == q->maxsize ) q->tail -= q->maxsize;
+ return d;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: QueueSize
+//
+// Description: retrieves number of items stored in the queue
+//
+// Input:
+// q - pointer to QUEUE_T structure
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int QueueSize(QUEUE_T* q)
+{
+ return (q->head >= q->tail)? q->head - q->tail:
+ q->head + q->maxsize - q->tail;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: QueuePut
+//
+// Description: add a new item in front of the head of the queue
+//
+// Input:
+// q - pointer to QUEUE_T structure
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID QueuePut( QUEUE_T* q, VOID * d)
+{
+ ASSERT(QueueSize(q) < q->maxsize );
+ q->data[q->head++] = d;
+ if(q->head==q->maxsize) q->head -= q->maxsize;
+ if(q->head==q->tail){
+ //Drop data from queue
+ q->tail++;
+ if( q->tail == q->maxsize ) q->tail -= q->maxsize;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: QueuePutMsg
+//
+// Description: add a variable size item to the queue
+//
+// Input:
+// q - pointer to QUEUE_T structure
+// sz - number of dwords to add to the queue
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID QueuePutMsg( QUEUE_T* q, VOID * d, int sz )
+{
+ ASSERT(QueueSize(q) < q->maxsize );
+ ASSERT(sz<q->maxsize);
+ if(q->head + sz > q->maxsize )
+ q->head = 0;
+ EfiCopyMem( (char*)q->data + q->head, d, sz );
+ q->head += sz;
+ if(q->head==q->maxsize) q->head = 0;
+ if(q->head==q->tail){
+ //Drop data from queue
+ q->tail+=sz;
+ if( q->tail >= q->maxsize ) q->tail = 0;
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: QueueRemoveMsg
+//
+// Description: retrieves a variable size item from the queue
+//
+// Input:
+// q - pointer to QUEUE_T structure
+// sz - number of dwords to remove from the queue
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID* QueueRemoveMsg( QUEUE_T* q, int sz)
+{
+ VOID* d;
+ if( q->tail == q->head ) return NULL;
+ d = (char*)q->data + q->tail;
+ q->tail += sz;
+ if( q->tail > q->maxsize ){
+ d = q->data;
+ q->tail = sz;
+ } else if(q->tail == q->maxsize ){
+ q->tail = 0;
+ }
+ return d;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/tree.h b/Core/EM/usb/tree.h
new file mode 100644
index 0000000..6dba1c6
--- /dev/null
+++ b/Core/EM/usb/tree.h
@@ -0,0 +1,95 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/tree.h 7 9/05/08 4:13p Olegi $
+//
+// $Revision: 7 $
+//
+// $Date: 9/05/08 4:13p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/tree.h $
+//
+// 7 9/05/08 4:13p Olegi
+//
+// 6 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 5 3/20/07 1:29p Olegi
+//
+// 3 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 2 6/15/05 1:59p Andriyn
+// Comments were changed
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Tree.h
+//
+// Description: Tree routines header
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __TREE_H__
+#define __TREE_H__
+
+typedef struct _TREENODE_T TREENODE_T;
+typedef struct _TREENODE_T{
+ VOID* data;
+ TREENODE_T* right;
+ TREENODE_T* left;
+ TREENODE_T* child;
+ TREENODE_T* parent;
+} TREENODE_T;
+
+typedef struct QUEUE_T;
+
+typedef int (*TREE_PREDICATE1_T)(VOID* n, VOID* context);
+typedef VOID (*TREE_CALLBACK_T)(VOID* n, VOID* context );
+
+TREENODE_T* TreeCreate( TREENODE_T* n, VOID* d);
+VOID TreeAddChild( TREENODE_T* p, TREENODE_T* c );
+VOID TreeRemove( TREENODE_T* n );
+TREENODE_T* TreeSearchSibling(TREENODE_T* n, TREE_PREDICATE1_T pr, VOID* data );
+TREENODE_T* TreeSearchDeep(TREENODE_T* n, TREE_PREDICATE1_T pr, VOID* data );
+VOID TreeForEachSibling(TREENODE_T* n, TREE_CALLBACK_T pr, VOID* data );
+
+VOID* QueueGet( QUEUE_T* q);
+int QueueSize(QUEUE_T* q);
+VOID QueuePut( QUEUE_T* q, VOID * d);
+VOID* QueueRemoveMsg( QUEUE_T* q, int sz);
+VOID QueuePutMsg( QUEUE_T* q, VOID * d, int sz );
+
+#endif //__TREE_H__
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/uhcd.c b/Core/EM/usb/uhcd.c
new file mode 100644
index 0000000..019b6bf
--- /dev/null
+++ b/Core/EM/usb/uhcd.c
@@ -0,0 +1,2896 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/uhcd.c 158 10/16/16 11:18p Wilsonlee $
+//
+// $Revision: 158 $
+//
+// $Date: 10/16/16 11:18p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/uhcd.c $
+//
+// 158 10/16/16 11:18p Wilsonlee
+// [TAG] EIP284071
+// [Category] Improvement
+// [Description] Clear USBDataPt from EFI_USB_PROTOCOL at the
+// readytoboot event.
+// [Files] uhcd.c, uhcd.h
+//
+// 157 10/16/16 10:18p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 156 7/28/16 4:55a Wilsonlee
+// [TAG] EIP264662
+// [Category] Improvement
+// [Description] Don't install usb hw smi after reconnecting usb
+// controllers.
+// [Files] uhcd.c, usb.c, ohci.c, amiusb.c, amiusbhc.c
+//
+// 155 7/18/16 11:22p Wilsonlee
+// [TAG] EIP279707
+// [Category] Improvement
+// [Description] Clear USB_FLAG_RUNNING_UNDER_EFI flag at
+// OnExitBootServices.
+// [Files] uhcd.c
+//
+// 154 7/07/16 1:12a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 153 7/24/15 4:42a Wilsonlee
+// [TAG] EIP226493
+// [Category] Improvement
+// [Description] Block to process periodic list to prevent that we might
+// send the wrong command sequences to the same device.
+// [Files] usbmass.c, ehci.c, xhci.h, xhci.c, usbdef.h, uhcd.c
+//
+// 152 7/24/15 3:20a Wilsonlee
+// [TAG] EIP228352
+// [Category] Improvement
+// [Description] Check if DpLastPciNode is NULL after we parse the
+// device path.
+// [Files] uhcd.c
+//
+// 151 4/10/15 3:05a Wilsonlee
+// [TAG] EIP207413
+// [Category] Improvement
+// [Description] Install UsbApiTable and UsbMassApitTable in
+// AmiUsbSmmProtocol.
+// [Files] amiusbhc.c, AmiUsbController.h, usbdef.h, usbCCID.c, uhci.c,
+// ehci.c, amiusbrtCCID.h, amiusb.h, amiusb.c, uhcd.c
+//
+// 150 2/16/15 2:44a Wilsonlee
+// [TAG] EIP205373
+// [Category] Improvement
+// [Description] Cppcheck errors in Usb module.
+// [Files] usb.c, usbport.c, uhcd.c, usbCCID.c
+//
+// 149 12/25/14 12:29a Wilsonlee
+// [TAG] EIP197655
+// [Category] Improvement
+// [Description] After ExitBootServices, the boot service function isn't
+// used, it is not necessary to uninstall the related protocol at
+// ExitBootServices.
+// [Files] uhcd.c
+//
+// 148 12/24/14 10:41p Wilsonlee
+// [TAG] EIP196287
+// [Category] Improvement
+// [Description] Display info of connected usb controllers and remove or
+// grayed-out some item according the connected usb controller number.
+// [Files] uhcd.c, usbport.c, usb.uni, usb.sd, usbsetup.c,
+// AmiUsbController.h, UsbPolicy.h
+//
+// 147 12/21/14 8:58p Wilsonlee
+// [TAG] EIP196001
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Some keys(shift, ctrl, alt or win) of USB KB funtion lost
+// in Shell after reconnecting usb controllers.
+// [RootCause] After we deactivate polling the device, the endpoint is
+// still running.
+// [Solution] Check if we deactivate polling the device before ringing
+// the door bell to start polling interrupt endpoint.
+// [Files] xhci.c, uhcd.c
+//
+// 146 12/15/14 1:33a Wilsonlee
+// [TAG] EIP196114
+// [Category] Improvement
+// [Description] Fix build error if x64_BUILD is 0.
+// [Files] uhcd.c
+//
+// 145 12/03/14 9:36p Wilsonlee
+// [TAG] EIP193805
+// [Category] Improvement
+// [Description] Security Enhancement for SMIHandler in USB module.
+// [Files] amiusb.c, uhcd.c, usbrt.mak, usbdef.h, usbsb.c
+//
+// 144 11/23/14 9:11p Wilsonlee
+// [TAG] EIP188119
+// [Category] Improvement
+// [Description] Disconnect devices and uninstall usb device related
+// protocols if we call stop api for the host controllers.
+// [Files] usbkbd.c, usbbus.c, uhcd.h, uhcd.c
+//
+// 143 8/06/14 10:06p Wilsonlee
+// [TAG] EIP180650
+// [Category] Improvement
+// [Description] Hide mass storage devices if "Usb Support" is disable.
+// [Files] usbport.c, uhcd.c
+//
+// 142 7/03/14 8:21a Wilsonlee
+// [TAG] EIP173190
+// [Category] Improvement
+// [Description] Stop all USB controllers at ExitBootService event.
+// [Files] uhcd.c
+//
+// 141 6/26/14 1:17a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 140 5/15/14 5:41a Wilsonlee
+// Fix the code check error result.
+//
+// 139 4/30/14 5:27a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 138 4/29/14 10:24p Wilsonlee
+// [TAG] EIP161709
+// [Category] New Feature
+// [Description] Dynamically update the usb device list in BIOS setup.
+// [Files] usb.sdl, usb.sd, usbsetup.c, uhcd.c
+//
+// 137 4/03/14 3:44a Wilsonlee
+// [TAG] EIP156742
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hang at 0x9C during DC cycle test under RHEL6.5
+// UEF.I
+// [RootCause] The hw smi may be triggered when we reallocate memory for
+// gUsbData->HcTable.
+// [Solution] Assign the new memory space to gUsbData->HcTable before we
+// free the old.
+// [Files] uhcd.c, uhcd.h, usbmisc.c
+//
+// 136 10/19/13 7:08a Ryanchou
+// [TAG] EIP138257
+// [Category] Improvement
+// [Description] Correct USB HID device type.
+// [Files] amiusb.c, usbdef.h, usbhid.c, efiusbhid.c, uhcd.c
+//
+// 135 8/02/13 6:19a Ryanchou
+//
+// 134 7/29/13 5:31a Roberthsu
+// [TAG] EIP126741
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Cannot boot to uefi usb device with Sophos software.
+// [RootCause] When boot into tool. Ownership to os event occur.Usb
+// will disconnect device.And record this disconnect event. Then ownership
+// to bios,bios will connect all device.Run legacy to efi function. Bios
+// run disconnect event first.Then reconnect device.Because usb key behind
+// hub. So usb key disconnect also.
+// [Solution] Check device when device reconnect.If device and port
+// number the same.Use the same device info.
+// [Files] usb.c,usbmass.c,efiusbmass.c,uhcd.c
+//
+// 133 7/03/13 5:24a Ryanchou
+// [TAG] EIP123988
+// [Category] Improvement
+// [Description] Move the code creating BBS table to end of POST.
+// [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+// UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 132 6/02/13 11:47p Wilsonlee
+// [TAG] EIP123235
+// [Category] Improvement
+// [Description] Stop the usb host controller at ExitBootService if it
+// is an extend card or it doesn't support HW SMI.
+// [Files] xhci.c, ehci.c, uhci.c, ohci.c, amiusb.c, usbdef.h, usbsb.c,
+// uhcd.c
+//
+// 131 4/18/13 11:20a Ryanchou
+// Fix build error if token USB_RUNTIME_DRIVER_IN_SMM is disabled.
+//
+// 130 4/16/13 6:46a Ryanchou
+// [TAG] EIP118912
+// [Category] Improvement
+// [Description] Add VIA VT6212 EHCI controller support.
+// [Files] ehci.c, uhci.c, usbdef.h, uhcd.c
+//
+// 129 4/12/13 3:38a Ryanchou
+// [TAG] EIP118383
+// [Category] Improvement
+// [Description] Stop all USB controllers in ExitBootService event.
+// [Files] uhcd.c
+//
+// 128 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 127 3/18/13 4:51a Ryanchou
+// [TAG] EIP98377
+// [Category] Improvement
+// [Description] Optimize USB controller timing.
+// [Files] usb.sdl, usbport.c, ehci.c, elib.c, ohci.c, uhci.c,
+// usbdef.h, usbhub.c, xhci.c, uhcd.c
+//
+// 126 1/22/13 2:40a Wilsonlee
+// [TAG] EIP110305
+// [Category] Improvement
+// [Description] Set the device address after we send the first
+// get-device-descriptor command.
+// [Files] usbmass.c, usb.c, usbdef.h, usbbus.c, efiusbmass.c, uhcd.c,
+// usbport.c
+//
+// 125 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 124 12/05/12 4:16a Roberthsu
+// [TAG] EIP96616
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] When Legacy to EFI, USB KB can't be used.
+// [RootCause] Usb device driver content incorrect driver entry.Legacy
+// insert a devicet,when legacy to efi,device does not install efi driver.
+// [Solution] When legacy to efi, scan device info table and put it
+// to smiqueue.
+// [Files] usb.sdl,uhcd.c,usb.c
+//
+// 123 12/02/12 10:33p Roberthsu
+// [TAG] EIP102150
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Push key and unplug KB , character repeat can not.
+// stop
+// [RootCause] Because repeat key does not clear when usb keyboard
+// unplug.
+// [Solution] When keyboard disconnrct, clear keyboard device id with
+// device id buffer and scancode buffer.
+// [Files] amiusb.c,syskbc.c,uhcd.c,usbkbd.c
+//
+// 122 10/29/12 3:50a Ryanchou
+// [TAG] EIP101229
+// [Category] Improvement
+// [Description] Added a token "EXTERNAL_USB_CONTROLLER_SUPPORT" to
+// disable external USB controller support.
+// [Files] uhcd.c, usbsrc.sdl
+//
+// 121 9/12/12 9:45a Ryanchou
+// [TAG] EIP100754
+// [Category] Improvement
+// [Description] Add Interface Type check in
+// AmiUsbDriverBindingSupported
+// [Files] uhcd.c
+//
+// 120 9/04/12 8:05a Wilsonlee
+// [TAG] EIP99882
+// [Category] New Feature
+// [Description] Add the usb setup item and usbpolicyprotocol to enable
+// or disable the usb mass storage driver.
+// [Files] UsbPolicy.h, usb.uni, usb.sd, usbmass.c, usbdef.h,
+// efiusbmass.c, usbport.c, uhcd.c
+//
+// 119 8/29/12 8:37a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 118 5/04/12 6:42a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 117 5/04/12 5:31a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 116 5/03/12 6:21a Roberthsu
+// [TAG] EIP84455
+// [Category] Improvement
+// [Description] Implement usb hid device gencric.
+// [Files] amiusb.c,amiusbhc.c,efiusbhid.c,efiusbkb.c,ehci.c,ohci.c,uhc
+// d.c,uhci.c,usbdef.h,usbhid.c,usbhub.c,usbkbd.c,usbkbd.h,usbms.c,usbsb.c
+// ,usbsrc.sdl
+//
+// 115 5/02/12 8:10a Wilsonlee
+// [TAG] EIP86793
+// [Category] New Feature
+// [Description] Add the SDL token "USB_MASS_EMULATION_FOR_NO_MEDIA" for
+// determine the USB mass storage device emulation type without media.
+// [Files] usbmass.c, usbport.c, uhcd.c, usbdef.h, usbsrc.sdl
+//
+// 114 1/14/12 6:41a Wilsonlee
+// [TAG] EIP80382
+// [Category] New Feature
+// [Description] Add the SDL token "USB_MASS_EMULATION_BY_SIZE" for
+// determine the USB mass storage device emulation type by size only.
+// [Files] usbmass.c, usbport.c, uhcd.c, usbdef.h, usbsrc.sdl
+//
+// 113 1/04/12 6:55a Ryanchou
+// [TAG] EIP72505
+// [Category] Improvement
+// [Description] Clear the legacy USB keyboard buffer when switching
+// between EFI and legacy.
+// [Files] syskbc.c, uhcd.c, usbkbd.c
+//
+// 112 12/14/11 10:03a Ryanchou
+// [TAG] EIP78215
+// [Category] Bug Fix
+// [Severity] Critical
+// [Symptom] Build error with USB module label 4.6.3_USB_08.10.18
+// [RootCause] The Usb3Hc array is defined with token USB_XHCI > 0, if
+// USB_XHCI = 0, Usb3Hc can't be found in USB_GLOBAL_DATA structure.
+// [Solution] Add a preprocessor "#if USB_XHCI".
+// [Files] uhcd.c
+//
+// 111 12/14/11 2:10a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 110 12/08/11 4:13a Ryanchou
+// [TAG] EIP76140
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] List of USB Devices in Setup is incorrect.
+// [RootCause] The function ReportDevices doesn't check the validity of
+// DeviceInfo structure.
+// [Solution] Check if the DeviceInfo structure is valid before count
+// the devices.
+// [Files] uhcd.c
+//
+// 109 12/07/11 10:52p Ryanchou
+// [TAG] EIP77121
+// [Category] Improvement
+// [Description] Check added to skip PCI interface type 0xFE, it is not
+// USB controller.
+// [Files] uhcd.c, uhcd.h
+//
+// 108 11/08/11 8:23a Wilsonlee
+// [TAG] EIP74876
+// [Category] New Feature
+// [Description] Add USB API for shutdown single USB controller.
+// [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 107 11/08/11 1:59a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 106 11/05/11 7:38a Wilsonlee
+// [TAG] EIP64781
+// [Category] New Feature
+// [Description] Added SDL token
+// SKIP_CARD_READER_CONNECT_BEEP_IF_NO_MEDIA that skip the connect beep if
+// no media present in USB card reader.
+// [Files] usbport.c, usbmass.c, usb.c, usbdef.h, uhcd.c, usbsrc.sdl
+//
+// 105 11/05/11 3:27a Ryanchou
+// [TAG] EIP70094
+// [Category] Improvement
+// [Description] Microsoft CSM Opt-Out feature implementation.
+// [Files] amiusb.c, uhcd.c
+//
+// 104 10/25/11 8:25a Wilsonlee
+// [TAG] EIP71750
+// [Category] New Feature
+// [Description] Support extraUSB device driver hook by elink.
+// [Files] usb.c, uhcd.c, uhcd.mak, usbrt.mak, usb.sdl
+//
+// 103 10/17/11 2:25a Ryanchou
+// [TAG] EIP69136
+// [Category] Improvement
+// [Description] Remove the dependency of EBDA in USB module for CSM
+// disabling.
+// [Files] amiusb.c, uhcd.c, usbport.c, usbsb.c
+//
+// 102 8/08/11 5:22a Ryanchou
+// [TAG] EIP60561
+// [Category] New Feature
+// [Description] Add USB timing policy protocol for timing override.
+// [Files] ehci.c, guids.c, ohci.c, uhcd.c, uhci.c usb.c, usbdef.h,
+// usbhub.c, usbmass.c, UsbPolicy.h, usbport.c usbsrc.sdl
+//
+// 101 8/05/11 6:19a Ryanchou
+// [TAG] EIP60706
+// [Category] Improvement
+// [Description] Move gUsbBadDeviceTable into SMRAM.
+// [Files] usbport.c, amiusb.c, usb.c, uhcd.c, AmiUsbController.h
+//
+// 100 7/15/11 6:23a Ryanchou
+// [TAG] EIP38434
+// [Category] New Feature
+// [Description] Added USB HID report protocol support.
+// [Files] amiusb.c, AmiUsbController.h, amiusbhc.c, efiusbkb.c,
+// efiusbkb.h, efiusbpoint.c, ehci.c, ohci.c, uhcd.c uhcd.cif, uhci.c,
+// usb.c, usbdef.h, usbhid.c, usbkbd.c, usbkbd.h, usbms.c, usbpoint.c,
+// usbrt.cif, usbsb.c, usbsetup.c, usbsrc.sdl, xhci.c
+//
+// 99 7/13/11 4:10a Ryanchou
+// [TAG] EIP59332
+// [Category] Improvement
+// [Description] Modified the Stop function for UHCD and USBBUS to
+// properly stop devices and uninstall the protocols.
+// [Files] uhcd.c, uhcd.h, uhci.c, usbbus.c, UsbInt13.c, usbmisc.c
+//
+// 98 7/12/11 11:42a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 97 6/29/11 10:03a Olegi
+// [TAG] EIP58704
+// [Description] Previous change related to this EIP undone as this
+// driver does not support RemainingDevicePath functionality
+//
+// 96 6/21/11 11:56p Ryanchou
+// [TAG] EIP60745
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB driver doesn't pass SCT 2.3 ComponentName2 protocol
+// test
+// [RootCause] USB driver fails to pass SCT 2.3 ComponentName2 protocol
+// test - function GetControllerName conformance test, because there is no
+// checking if passed handle is valid or not, or even NULL
+// [Solution] Check the handle is valid in GetControllerName function.
+// [Files] uhcd.c, usbbus.c
+//
+// 95 5/30/11 4:31a Rameshr
+// [TAG]- EIP 58704
+// [Category]-IMPROVEMENT
+// [Description]- Implement correct behavior when RemainingDevicePath
+// passed to Supported() function consist only of end node, as described
+// in UEFI specification Version 2.3.1, page 10.1
+// EFI_DRIVER_BINDING_PROTOCOL.Supported() and Start()
+// [Files]- Uhcd.c
+//
+// 94 5/03/11 10:44a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 93 4/06/11 3:27a Ryanchou
+// [TAG] EIP55275
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] EBDA:108 conflict
+// [RootCause] The EIP48064 save EFI_USB_PROTOCOL pointer in EBDA:108,
+// but Keymon filter driver used the same location.
+// [Solution] Use the EBDA:32 to save EFI_USB_PROTOCOL pointer and add a
+// signature in EFI_USB_PROTOCOL.
+// [Files] amidef.h, AmiUsbController.h, uhcd.c, usbsb.c
+//
+// 92 4/06/11 3:20a Tonylo
+// [TAG] EIP57354
+// [Category] Improvement
+// [Description] Core 4.6.5.0 compliant. UEFI 2.3 and PI 1.x support.
+//
+// 91 4/06/11 12:46a Ryanchou
+// [TAG] EIP51653
+// [Category] New Feature
+// [Description] Added an interface that skips specific port
+// enumeration.
+// [Files] AmiUsbController.h, uhcd.c, uhcd.h, usb.c, usbdef.h,
+// usbport.c
+//
+// 90 3/29/11 10:16a Ryanchou
+// [TAG] EIP53518
+// [Category] Improvement
+// [Description] Added chipset xHCI chip support.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhcd.c, uhci.c, usb.c,
+// usb.sdl, usbdef.h, usbport, usbsb.c, xhci.c
+//
+// 89 3/04/11 1:29p Olegi
+//
+// 88 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 87 2/22/11 5:08a Tonylo
+// [TAG] EIP52339
+// [Category] New Feature
+// [Description] USB changes of USB host safe disabling solution.
+// [Files] USB.C
+// UHCD.C
+// UHCD.H
+// AMIUSBController.H
+//
+// 86 10/22/10 8:57a Ryanchou
+// EIP46693: Clear xHCI BIOS owned semaphore bit and SMI enable bit in
+// PreInitXhci.
+//
+// 85 9/16/10 2:07p Olegi
+// EIP40959: Added project specific setting of
+// USB_FLAG_EFIMS_DIRECT_ACCESS.
+//
+// 84 9/07/10 4:36a Tonylo
+// Remove user tags for coding standard.
+//
+// 83 8/18/10 4:21p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 82 8/13/10 5:14p Olegi
+// Added that code that would stop emulation code in case of USB support
+// is disabled in Setup. EIP42301.
+//
+// 81 6/29/10 5:56a Ryanchou
+// Fixed LocateAllCompanions returns error even add HC success.
+//
+// 80 6/28/10 5:02p Olegi
+// EIP26277: Added a callback notification on
+// NonSmmEmul6064TrapProtocolGuid installation.
+//
+// 79 6/17/10 10:35a Olegi
+// EIP39326: Runtime data moved to runtime memory region.
+//
+// 78 5/11/10 9:28a Olegi
+// LocateAllCompanions returns the status; EIP#38161
+//
+// 77 4/19/10 1:53p Olegi
+//
+// 76 4/15/10 2:46p Olegi
+// EFI_USB_PROTOCOL variable is EfiBootServicesData. This is wrong because
+// this structure holds some pointers that can be used during run-time.
+// This variable is moved to the global data area that should be
+// protected. EIP36641
+//
+// 75 3/11/10 9:52a Olegi
+// Added page alignment restriction into memory allocation routine.
+// EIP30533
+//
+// 74 3/02/10 10:12a Olegi
+//
+// 73 2/26/10 2:14p Fasihm
+// Bugfix in UhcdPciIrqPgmNotifyCallback function.
+//
+// 72 2/18/10 5:16p Olegi
+// Added DXE_USB_ENABLE progress code.
+//
+// 71 1/27/10 6:35p Olegi
+// Added HW IRQ installation code.
+//
+// 70 1/27/10 5:25p Olegi
+//
+// 69 1/19/10 11:58a Olegi
+//
+// 68 11/25/09 6:05p Olegi
+//
+// 67 11/23/09 3:27p Olegi
+// Fix for EIP30023: access gSetupData only when GetVariable returns
+// EFI_SUCCESS.
+//
+// 66 11/19/09 9:51a Olegi
+//
+// 65 11/19/09 9:40a Olegi
+// UpdateHcPciInfo call moved to PciIo notification callback.
+//
+// 64 11/18/09 4:59p Olegi
+// UpdateHcPciInfo call is moved from entry point to the Start function.
+// This will allow a porting code to use the PCI information that is not
+// available in the entry point, for example the PCI bus numbers of the
+// controllers.
+//
+// 63 10/30/09 5:51p Olegi
+//
+// 62 10/09/09 5:57p Olegi
+//
+// 61 10/02/09 10:50a Olegi
+// Code cleanup.
+//
+// 60 9/09/09 3:27p Davidd
+// Return EFI_UNSUPPORTED when newly added "USB Support" setup question is
+// disabled - EIP 25360
+//
+// 59 5/21/09 5:16p Olegi
+// Added HDD hotplug support.
+//
+// 58 3/26/09 2:17p Olegi
+// All setup related code is moved to OEMPORT.C to maximize the porting
+// capabilities.
+//
+// 57 2/18/09 3:07p Olegi
+// Added a feature that allows to skip mass storage device installation
+// depending on physical media presence. EIP#19260.
+//
+// 56 2/04/09 12:59p Olegi
+// Added the communication with KBC emulation module during switching to
+// Legacy mode and back. EIP#18730.
+//
+// 55 11/25/08 6:02p Olegi
+// Support for OEM USB Boot Override feature. EIP#17052.
+//
+// 54 10/24/08 3:03p Olegi
+//
+// 53 10/22/08 4:25p Olegi
+// QueueData1 declaration and initialization is moved here from USBBUS.C
+//
+// 52 10/03/08 3:30p Olegi
+// kbc_support initialization moved from Start function to the EntryPoint.
+//
+// 51 9/05/08 4:13p Olegi
+// fpCallbackNotify functions removed.
+//
+// 50 9/02/08 10:30a Olegi
+//
+// 49 8/18/08 4:56p Olegi
+// Removed checking for 0x00 when reading port 64 to determine the
+// presence of KBC.
+//
+// 48 7/04/08 1:01p Olegi
+// Added USB Mass Native Emulation option (EIP# 13432)
+//
+// 47 6/27/08 5:55p Olegi
+// Function GetNextMassDevice is replaced with GetNextMassDeviceName.
+//
+// 46 6/19/08 10:11a Olegi
+// ReadyToBoot function renamed to OnExitBootServices.
+//
+// 45 6/17/08 12:38p Olegi
+//
+// 44 6/14/08 2:24p Olegi
+// Added OnReadyToBoot function.
+//
+// 43 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: UHCD.C
+//
+// Description: AMI USB Host Controller Driver
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+//#include "Efi.h"
+#include "amidef.h"
+#include "UsbDef.h"
+#include "Uhcd.h"
+#include "UsbBus.h"
+#include "EfiUsbKb.h"
+#include "ComponentName.h"
+#include "Protocol\Emul6064Trap.h"
+#include "token.h"
+#include <UsbDevDriverElinks.h> //(EIP71750+)
+#include <Protocol\PciIo.h>
+#include <Pci.h>
+#include <AcpiRes.h>
+
+extern UINT8 gFddHotplugSupport;
+extern UINT8 gCdromHotplugSupport;
+extern UINT8 gUsbMassNativeEmulation;
+extern UINT8 UsbMassEmulationForNoMedia; //(EIP86793+)
+extern UINT8 UsbMassSizeEmulation; //(EIP80382+)
+extern UINT8 gUsbMassMediaCheck;
+extern UINT8 gUsbMassSkipFddMediaCheck;
+extern UINT8 gUsbEfiMsDirectAccess;
+extern UINT8 SkipCardReaderConnectBeep; //(EIP64781+)
+extern VOID *gStartPointer;
+extern VOID *gEndPointer;
+extern EFI_EVENT gEvUsbEnumTimer;
+
+extern EFI_GUID gEfiSetupGuid;
+extern EFI_GUID gEfiUsbPolicyProtocolGuid;
+extern EFI_GUID gUsbTimingPolicyProtocolGuid;
+
+const HCSPECIFICINFO aHCSpecificInfo[4] = {
+{EFI_PCI_IO_ATTRIBUTE_IO | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, 0x1000, 0x1000, DummyHcFunc, DummyHcFunc}, // UHCI
+{EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, 0x100, 0x100, DummyHcFunc, DummyHcFunc}, // OHCI
+{EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, 0x1000, 0x1000, DummyHcFunc, DummyHcFunc}, // EHCI
+{EFI_PCI_IO_ATTRIBUTE_MEMORY | EFI_PCI_IO_ATTRIBUTE_BUS_MASTER, 0, 0, PreInitXhci, PostStopXhci}, // XHCI
+};
+
+UINT8 gSupportedInterfaceType[] = {
+#if UHCI_SUPPORT
+ PCI_CLASSC_PI_UHCI,
+#endif
+#if OHCI_SUPPORT
+ PCI_CLASSC_PI_OHCI,
+#endif
+#if EHCI_SUPPORT
+ PCI_CLASSC_PI_EHCI,
+#endif
+#if XHCI_SUPPORT
+ PCI_CLASSC_PI_XHCI
+#endif
+};
+
+USB_GLOBAL_DATA *gUsbData;
+EFI_USB_PROTOCOL *gAmiUsbController;
+EFI_EVENT gLegacyBootEvent;
+EFI_EVENT gExitBootServicesEvent;
+EFI_USB_POLICY_PROTOCOL EfiUsbPolicyProtocol; //(EIP99882+)
+ //(EIP60745+)>
+EFI_DRIVER_BINDING_PROTOCOL gAmiUsbDriverBinding = {
+ AmiUsbDriverBindingSupported,
+ AmiUsbDriverBindingStart,
+ AmiUsbDriverBindingStop,
+ USB_DRIVER_VERSION,
+ NULL,
+ NULL
+};
+ //<(EIP60745+)
+DEV_INFO* ICCQueueData[6];
+EFI_EMUL6064TRAP_PROTOCOL *gEmulationTrap = 0;
+
+//extern USB_BADDEV_STRUC gUsbBadDeviceTable[]; //(EIP60706-)
+
+EFI_DRIVER_ENTRY_POINT (AmiUsbDriverEntryPoint)
+
+VOID *gPciIoNotifyReg;
+VOID *gProtocolNotifyRegistration;
+BOOLEAN gLegacyUsbStatus=TRUE;
+EFI_EVENT gUsbIntTimerEvt = NULL;
+
+#define EFI_PCIIRQ_PGM_PROTOCOL_GUID \
+ { 0x9400d59b, 0xe9c, 0x4f6c, 0xb5, 0x9a, 0xfc, 0x20, 0x0, 0x9d, 0xb9, 0xec };
+
+EFI_GUID gPciIrqProgramGuid = EFI_PCIIRQ_PGM_PROTOCOL_GUID;
+
+typedef struct _PROGRAMMED_PCIIRQ_CTX {
+ VOID *PciIo;
+ UINT8 Irq;
+} PROGRAMMED_PCIIRQ_CTX;
+ //(EIP71750+)>
+typedef EFI_STATUS USB_DEV_EFI_DRIVER_CHECK (EFI_HANDLE, EFI_HANDLE);
+extern USB_DEV_EFI_DRIVER_CHECK USB_DEV_EFI_DRIVER EndOfUsbDevEfiDriverList;
+USB_DEV_EFI_DRIVER_CHECK* UsbDevEfiDrivers[]= {USB_DEV_EFI_DRIVER NULL};
+ //<(EIP71750+)
+ //(EIP60745+)>
+#ifdef USB_CONTROLLERS_WITH_RMH
+typedef struct {
+ UINT16 Vid;
+ UINT16 Did;
+} CONTROLLER_WITH_RMH;
+
+CONTROLLER_WITH_RMH gControllersWithRmh[] = {USB_CONTROLLERS_WITH_RMH};
+#endif
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbDriverGetControllerName
+//
+// Description: This function is a part of binding protocol, it returns
+// the string "USB Host Controller".
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+AmiUsbDriverGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ if (Child != NULL) {
+ return NULL;
+ }
+ if (FindHcStruc(Controller)){
+ return L"USB Host Controller";
+ }
+ return NULL;
+}
+ //<(EIP60745+)
+#if !USB_RUNTIME_DRIVER_IN_SMM
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIntTimerCallback
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbIntTimerCallback(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ EFI_TPL OriginalTPL;
+ HC_STRUC* HcStruc;
+ UINT8 i;
+
+ OriginalTPL = pBS->RaiseTPL (TPL_NOTIFY);
+
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ HcStruc = gUsbData->HcTable[i];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if(HcStruc->dHCFlag & HC_STATE_RUNNING) { // Process appropriate interrupt
+ (*gUsbData->aHCDriverTable
+ [GET_HCD_INDEX(HcStruc->bHCType)].pfnHCDProcessInterrupt)(HcStruc);
+ }
+ }
+
+ pBS->RestoreTPL (OriginalTPL);
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbDriverEntryPoint
+//
+// Description: Entry point for AMI USB EFI driver
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+)
+{
+ EFI_HANDLE UsbHandle = NULL;
+ EFI_STATUS Status;
+ EFI_STATUS SetupStatus;
+ UINTN VariableSize;
+ USB_SUPPORT_SETUP gSetupData;
+ EFI_EVENT PciIoEvent;
+ EFI_EVENT Emul6064Event;
+ UINT8 DevDriverIndex; //(EIP71750+)
+ EFI_EVENT ReadyToBootEvent;
+
+ EfiInitializeDriverLib (ImageHandle, SystemTable);
+
+ VariableSize = sizeof(USB_SUPPORT_SETUP);
+ SetupStatus = pRS->GetVariable( L"UsbSupport", &gEfiSetupGuid, NULL,
+ &VariableSize, &gSetupData );
+
+ if (SetupStatus == EFI_SUCCESS && gSetupData.UsbMainSupport == 0) {
+ InitUsbSetupVars(NULL, pBS, pRS);
+ return EFI_UNSUPPORTED;
+ }
+
+ PROGRESS_CODE(DXE_USB_BEGIN);
+
+ //
+ // Allocate and initialize USB memory
+ //
+ gUsbData = AllocAlignedMemory (sizeof(USB_GLOBAL_DATA), 0x10);
+ ASSERT(gUsbData);
+ if (gUsbData == NULL) return EFI_OUT_OF_RESOURCES;
+
+ //
+ // Initialize the data area
+
+ //
+ // Set the USB version number
+ //
+ gUsbData->stUSBVersion.bMajor = USB_MAJOR_VER;
+ gUsbData->stUSBVersion.bMinor = USB_MINOR_VER;
+ gUsbData->stUSBVersion.bBugRel = USB_BUG_RELEASE_VER;
+
+ //
+ // Initialize the state flag
+ //
+ gUsbData->dUSBStateFlag = 0;
+
+ gUsbData->DeviceAddressMap = (UINT64)(~BIT0);
+
+ //
+ // Enable beep message during device connect/disconnect
+ //
+ gUsbData->dUSBStateFlag |= USB_FLAG_ENABLE_BEEP_MESSAGE;
+ gUsbData->dUSBStateFlag |= USB_FLAG_RUNNING_UNDER_EFI;
+ //(EIP80382)>
+ if (gUsbMassNativeEmulation) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_MASS_NATIVE_EMULATION;
+ }else if (UsbMassSizeEmulation) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_MASS_SIZE_EMULATION;
+ }
+ //<(EIP80382)
+ //(EIP86793+)>
+ if (UsbMassEmulationForNoMedia) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_MASS_EMULATION_FOR_NO_MEDIA;
+ }
+ //<(EIP86793+)
+ if (gUsbMassMediaCheck) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_MASS_MEDIA_CHECK;
+ if (gUsbMassSkipFddMediaCheck)
+ gUsbData->dUSBStateFlag |= USB_FLAG_MASS_SKIP_FDD_MEDIA_CHECK;
+ }
+ if (gUsbEfiMsDirectAccess) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_EFIMS_DIRECT_ACCESS;
+ }
+ //(EIP64781+)>
+ if (SkipCardReaderConnectBeep) {
+ gUsbData->dUSBStateFlag |= USB_FLAG_SKIP_CARD_READER_CONNECT_BEEP;
+ }
+ //<(EIP64781+)
+
+ gUsbData->bKbdDataReady = FALSE;
+ gUsbData->ProcessingPeriodicList = TRUE;
+ gUsbData->NumberOfFDDs = 0;
+ gUsbData->NumberOfHDDs = 0;
+ gUsbData->NumberOfCDROMs = 0;
+
+ gUsbData->QueueCnnctDisc.data = gUsbData->QueueData1;
+ gUsbData->QueueCnnctDisc.maxsize = COUNTOF(gUsbData->QueueData1);
+ gUsbData->QueueCnnctDisc.head = 0;
+ gUsbData->QueueCnnctDisc.tail = 0;
+ gUsbData->ICCQueueCnnctDisc.data = ICCQueueData;
+ gUsbData->ICCQueueCnnctDisc.maxsize = COUNTOF(ICCQueueData);
+ gUsbData->ICCQueueCnnctDisc.head = 0;
+ gUsbData->ICCQueueCnnctDisc.tail = 0;
+
+ Status = InitUsbSetupVars(gUsbData, pBS, pRS);
+ ASSERT_EFI_ERROR(Status);
+ //(EIP99882)>
+ EfiUsbPolicyProtocol.UsbDevPlcy = &(gUsbData->UsbSetupData);
+
+ // Install USB policy protocol
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &gEfiUsbPolicyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &EfiUsbPolicyProtocol
+ );
+ //<(EIP99882)
+ ASSERT_EFI_ERROR(Status);
+
+ gUsbData->UsbTimingPolicy.UsbTimingPolicyRevision = 01;
+ gUsbData->UsbTimingPolicy.UsbTimingPolicyLength = 14;
+ gUsbData->UsbTimingPolicy.EhciPortPowerOnDelay = 100;
+ gUsbData->UsbTimingPolicy.EhciPortConnect = 20;
+ gUsbData->UsbTimingPolicy.EhciPortReset = 50;
+ gUsbData->UsbTimingPolicy.OhciHcResetDelay= 10;
+ gUsbData->UsbTimingPolicy.OhciPortEnable = 100;
+ gUsbData->UsbTimingPolicy.OhciHcReset = 2;
+ gUsbData->UsbTimingPolicy.UhciGlobalReset = 10;
+ gUsbData->UsbTimingPolicy.UhciPortEnable = 100;
+ gUsbData->UsbTimingPolicy.HubPortConnect = 50;
+ gUsbData->UsbTimingPolicy.HubPortEnable = 50;
+ gUsbData->UsbTimingPolicy.MassDeviceComeUp = 500;
+ gUsbData->UsbTimingPolicy.RmhPowerOnDelay= 100;
+ Status = pBS->InstallProtocolInterface(
+ &ImageHandle,
+ &gUsbTimingPolicyProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ &(gUsbData->UsbTimingPolicy));
+ //
+ // Allocate memory for the pool and store it in global data
+ //
+ gUsbData->MemPages = MEM_PAGE_COUNT;
+ gUsbData->fpMemBlockStart = AllocAlignedMemory(gUsbData->MemPages << 12, 0x1000);
+
+ //
+ // Initialize the memory block status array to free
+ //
+ gUsbData->MemBlkStsBytes = ((gUsbData->MemPages << 12) / sizeof(MEM_BLK)) / 8;
+
+ Status = pBS->AllocatePool(EfiRuntimeServicesData, gUsbData->MemBlkStsBytes,
+ &gUsbData->aMemBlkSts);
+ ASSERT_EFI_ERROR(Status);
+ pBS->SetMem(gUsbData->aMemBlkSts, gUsbData->MemBlkStsBytes, (UINT8)(~0));
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+ gUsbData->kbc_support = (IoRead8(0x64)==0xff)? 0 : 1;
+#endif
+ //
+ // Install USB protocol
+ //
+ gAmiUsbController = (EFI_USB_PROTOCOL*)AllocAlignedMemory (sizeof(EFI_USB_PROTOCOL), 0x10);
+
+ USB_DEBUG(DEBUG_LEVEL_0, "AMIUHCD USB Init: data located at........... %x\n", (UINTN)gUsbData);
+ USB_DEBUG(DEBUG_LEVEL_3, "Log address: %x\n", &gUsbData->aErrorLogBuffer[0]);
+ USB_DEBUG(DEBUG_LEVEL_3, "Memory map: %x\n", &gUsbData->aMemBlkSts[0]);
+ USB_DEBUG(DEBUG_LEVEL_3, "Device address map: %x\n", &gUsbData->DeviceAddressMap);
+
+ gAmiUsbController->Signature = 0x50425355; //USBP //(EIP55275+)
+ gAmiUsbController->USBDataPtr = gUsbData;
+ //gAmiUsbController->UsbBadDeviceTable = gUsbBadDeviceTable; //(EIP60706-)
+
+ gAmiUsbController->UsbReportDevices = ReportDevices;
+ gAmiUsbController->UsbGetNextMassDeviceName = GetNextMassDeviceName;
+ gAmiUsbController->UsbChangeEfiToLegacy = UsbChangeEfiToLegacy;
+ gAmiUsbController->UsbGetRuntimeRegion = GetRuntimeRegion;
+ gAmiUsbController->InstallUsbLegacyBootDevices = Dummy2;
+ gAmiUsbController->UsbInstallLegacyDevice = Dummy1;
+ gAmiUsbController->UsbUninstallLegacyDevice = Dummy1;
+ gAmiUsbController->UsbGetAssignBootPort = OemGetAssignUsbBootPort;
+ gAmiUsbController->UsbRtShutDownLegacy = UsbRtShutDownLegacy; //<(EIP52339+)
+ gAmiUsbController->UsbCopySkipTable = UsbGetSkipList; //(EIP51653+)
+ gAmiUsbController->UsbRtStopController= UsbRtStopController; //(EIP74876+)
+ Status = gBS->InstallProtocolInterface (
+ &UsbHandle,
+ &gEfiUsbProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ gAmiUsbController
+ );
+
+ {
+ //(EIP59272)>
+ static NAME_SERVICE_T Names;
+ //(EIP60745)>
+ //static EFI_DRIVER_BINDING_PROTOCOL Binding = {
+ // AmiUsbDriverBindingSupported,
+ // AmiUsbDriverBindingStart,
+ // AmiUsbDriverBindingStop,
+ // USB_DRIVER_VERSION,
+ // NULL,
+ // NULL
+ //};
+ gAmiUsbDriverBinding.DriverBindingHandle = ImageHandle;
+ gAmiUsbDriverBinding.ImageHandle = ImageHandle;
+
+ Status = gBS->InstallMultipleProtocolInterfaces(
+ &gAmiUsbDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gAmiUsbDriverBinding,
+ &gEfiComponentName2ProtocolGuid, InitNamesProtocol(
+ &Names, L"AMI USB Driver", AmiUsbDriverGetControllerName),
+ NULL);
+ //<(EIP60745)
+ //<(EIP59272)
+ //(EIP71750)>
+ for(DevDriverIndex = 0; UsbDevEfiDrivers[DevDriverIndex]; DevDriverIndex++) {
+ VERIFY_EFI_ERROR(
+ Status = UsbDevEfiDrivers[DevDriverIndex](ImageHandle,0));
+ if( EFI_ERROR(Status) ) return Status;
+ }
+/*
+ USB_DEBUG(DEBUG_LEVEL_3,"Calling UsbBusInit...\n");
+ VERIFY_EFI_ERROR(
+ Status = UsbBusInit(ImageHandle,0));
+ if( EFI_ERROR(Status) ) return Status;
+ //(EIP38434+)>
+ USB_DEBUG(DEBUG_LEVEL_3,"Calling UsbHidInit...\n");
+ VERIFY_EFI_ERROR(
+ Status = UsbHidInit(ImageHandle,0));
+ if( EFI_ERROR(Status) ) return Status;
+// USB_DEBUG(DEBUG_LEVEL_3,"Calling UsbKbdInit...\n");
+// VERIFY_EFI_ERROR(
+// Status = UsbKbdInit(ImageHandle,0));
+// if( EFI_ERROR(Status) ) return Status;
+//
+// USB_DEBUG(DEBUG_LEVEL_3,"Calling UsbMsInit...\n");
+// VERIFY_EFI_ERROR(
+// Status = UsbMsInit(ImageHandle,0));
+// if( EFI_ERROR(Status) ) return Status;
+ //<(EIP38434+)
+ USB_DEBUG(DEBUG_LEVEL_3,"Calling UsbMassInit...\n");
+ VERIFY_EFI_ERROR(
+ Status = UsbMassInit(ImageHandle,0));
+ if( EFI_ERROR(Status) ) return Status;
+#if USB_DEV_CCID
+ USB_DEBUG(DEBUG_LEVEL_3,"Calling UsbCCIDInit...\n");
+ VERIFY_EFI_ERROR(
+ Status = UsbCCIDInit(ImageHandle,0));
+ if( EFI_ERROR(Status) ) return Status;
+#endif
+*/
+ //<(EIP71750)
+ }
+
+ //
+ // Create the notification and register callback function on the PciIo installation
+ //
+ Status = pBS->CreateEvent (EVT_NOTIFY_SIGNAL, TPL_CALLBACK,
+ UhcdPciIoNotifyCallback, NULL, &PciIoEvent);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ Status = pBS->RegisterProtocolNotify (
+ &gEfiPciIoProtocolGuid, PciIoEvent, &gPciIoNotifyReg);
+ ASSERT_EFI_ERROR(Status);
+
+#if defined(CSM_SUPPORT) && CSM_SUPPORT //(EIP69136)
+ // Install HW interrupt handler
+ {
+ EFI_EVENT HwIrqEvent;
+ EFI_STATUS Status;
+
+ Status = RegisterProtocolCallback(&gPciIrqProgramGuid, UhcdPciIrqPgmNotifyCallback,
+ NULL, &HwIrqEvent, &gProtocolNotifyRegistration);
+ ASSERT_EFI_ERROR(Status);
+ }
+#endif
+
+ Status = gBS->LocateProtocol (&gNonSmmEmul6064TrapProtocolGuid, NULL, &gEmulationTrap);
+ if (EFI_ERROR(Status)) {
+ Status = RegisterProtocolCallback(&gNonSmmEmul6064TrapProtocolGuid, Emul6064NotifyCallback,
+ NULL, &Emul6064Event, &gProtocolNotifyRegistration);
+ }
+
+#if defined(EFI_EVENT_SIGNAL_LEGACY_BOOT) && EFI_SPECIFICATION_VERSION<0x20000
+ VERIFY_EFI_ERROR(
+ gBS->CreateEvent (
+ EFI_EVENT_SIGNAL_LEGACY_BOOT,
+ EFI_TPL_NOTIFY,
+ OnLegacyBoot,
+ NULL,
+ &gLegacyBootEvent ));
+#else
+ VERIFY_EFI_ERROR(
+ EfiCreateEventLegacyBoot (
+ EFI_TPL_NOTIFY,
+ OnLegacyBoot,
+ NULL,
+ &gLegacyBootEvent ));
+#endif
+
+ VERIFY_EFI_ERROR(
+ gBS->CreateEvent (
+ EVT_SIGNAL_EXIT_BOOT_SERVICES,
+ EFI_TPL_NOTIFY,
+ OnExitBootServices,
+ NULL,
+ &gExitBootServicesEvent
+ ));
+
+#if !USB_RUNTIME_DRIVER_IN_SMM
+ VERIFY_EFI_ERROR(
+ gBS->CreateEvent ( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_NOTIFY, UsbIntTimerCallback, 0, &gUsbIntTimerEvt));
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gUsbIntTimerEvt, TimerPeriodic, 32 * MILLISECOND));
+#endif
+
+ Status = CreateReadyToBootEvent(TPL_CALLBACK, ReadyToBootNotify, NULL, &ReadyToBootEvent);
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+
+
+VOID
+Emul6064NotifyCallback(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ UINTN BufferSize = sizeof(EFI_HANDLE);
+ EFI_HANDLE Handle;
+ EFI_STATUS Status;
+
+ Status = pBS->LocateHandle(ByRegisterNotify,
+ NULL, gProtocolNotifyRegistration, &BufferSize, &Handle);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return;
+
+ //
+ // Locate EFI_EMUL6064TRAP_PROTOCOL installed on Handle and assign to gEmulationTrap
+ //
+ Status = pBS->HandleProtocol(Handle, &gNonSmmEmul6064TrapProtocolGuid, &gEmulationTrap);
+ ASSERT_EFI_ERROR(Status);
+}
+
+
+#if defined(CSM_SUPPORT) && CSM_SUPPORT //(EIP69136)
+VOID
+UhcdPciIrqPgmNotifyCallback(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ PROGRAMMED_PCIIRQ_CTX *PciIrqCtx;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN Seg, Bus, Dev, Func;
+ EFI_STATUS Status;
+
+ Status = pBS->LocateProtocol(&gPciIrqProgramGuid, NULL, &PciIrqCtx);
+ if (EFI_ERROR(Status)) {
+ TRACE((-1, "USBHC:: can not locate PCI IRQ program interface.\n"));
+ return;
+ }
+
+ PciIo = (EFI_PCI_IO_PROTOCOL*)PciIrqCtx->PciIo;
+ if (PciIo == NULL) return;
+
+ Status = PciIo->GetLocation(PciIo, &Seg, &Bus, &Dev, &Func);
+ ASSERT_EFI_ERROR(Status);
+
+ TRACE((-1, "Ready to install interrupt handler for IRQ%d for PCI B%d/D%d/F%d\n", PciIrqCtx->Irq, Bus, Dev, Func));
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UhcdPciIoNotifyCallback
+//
+// Description:
+// PciIo notification callback. It calls UpdateHcPciInfo porting function
+// to update the PCI information in the HC device table.
+//
+// Input: Event - event signaled by the DXE Core upon PciIo installation
+// Context - event context
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UhcdPciIoNotifyCallback (
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ // Porting hook that updates a list of PCI devices that will be used during enumeration
+ UpdateHcPciInfo();
+ pBS->CloseEvent(Event); // this is one time callback
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsSupportedInterfaceType
+//
+// Description: This function check whether the Interface Type is supported.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsSupportedInterfaceType (
+ UINT8 InterfaceType
+)
+{
+ UINT8 i;
+
+ for (i = 0; i < sizeof(gSupportedInterfaceType); i++) {
+ if (gSupportedInterfaceType[i] == InterfaceType) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsExternalController
+//
+// Description: This function check whether the controller is behind bridge
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsExternalController (
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *Dp = DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DpPciNode = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DpBridge = NULL;
+ EFI_HANDLE Bridge = NULL;
+ EFI_PCI_IO_PROTOCOL *PciIo = NULL;
+ UINT8 PciClass[3];
+
+ while(!EfiIsDevicePathEnd(Dp)) {
+ if ((Dp->Type == HARDWARE_DEVICE_PATH) &&
+ (Dp->SubType == HW_PCI_DP)) {
+ DpPciNode = Dp;
+ break;
+ }
+ Dp = EfiNextDevicePathNode(Dp);
+ }
+ ASSERT(DpPciNode);
+
+ DpBridge = EfiDuplicateDevicePath(DevicePath);
+ ASSERT(DpBridge);
+
+ Dp = (EFI_DEVICE_PATH_PROTOCOL*)((UINTN)DpBridge +
+ ((UINTN)EfiNextDevicePathNode(DpPciNode) - (UINTN)DevicePath));
+
+ Dp->Type = EFI_END_ENTIRE_DEVICE_PATH;
+ Dp->SubType = EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ SetDevicePathNodeLength(Dp, sizeof(EFI_DEVICE_PATH_PROTOCOL));
+
+ Dp = DpBridge;
+ Status = gBS->LocateDevicePath(
+ &gEfiPciIoProtocolGuid,
+ &Dp,
+ &Bridge);
+ gBS->FreePool(DpBridge);
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ Status = pBS->HandleProtocol(Bridge, &gEfiPciIoProtocolGuid, &PciIo);
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ PCI_PI_OFFSET,
+ sizeof(PciClass),
+ PciClass);
+ if (EFI_ERROR(Status)) {
+ return FALSE;
+ }
+
+ if (PciClass[2] != PCI_CL_BRIDGE ||
+ PciClass[1] != PCI_CL_BRIDGE_SCL_P2P) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbDriverBindingSupported
+//
+// Description: Test to see if this driver supports ControllerHandle.
+//
+// Input: This - Protocol instance pointer
+// ControllerHandle - Handle of device to test
+//
+// Output: EFI_SUCCESS - This driver supports this device.
+// EFI_UNSUPPORTED - This driver does not support this device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbDriverBindingSupported (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ USB_CLASSC UsbClassCReg;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ CLASSC,
+ sizeof(USB_CLASSC) / sizeof(UINT8),
+ &UsbClassCReg);
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ if ((UsbClassCReg.BaseCode != PCI_CLASSC_BASE_CLASS_SERIAL) ||
+ (UsbClassCReg.SubClassCode != PCI_CLASSC_SUBCLASS_SERIAL_USB) ||
+ !IsSupportedInterfaceType(UsbClassCReg.PI)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+
+#if !EXTERNAL_USB_CONTROLLER_SUPPORT
+ if (IsExternalController(DevicePath)) {
+ return EFI_UNSUPPORTED;
+ }
+#endif
+
+ return EFI_SUCCESS;
+
+} // end of AmiUsbDriverBindingSupported
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbDriverBindingStart
+//
+// Description: Binding protocol function to start the AMI USB driver
+//
+// Input: This - Protocol instance pointer.
+// ControllerHandle - Handle of device to test
+//
+// Output: EFI_SUCCESS - This driver supports this device.
+// EFI_UNSUPPORTED - This driver does not support this device.
+// EFI_DEVICE_ERROR - This driver cannot be started due to device
+// Error
+// EFI_OUT_OF_RESOURCES
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath )
+{
+ EFI_STATUS Status;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ UINT8 PciCfg[0x40];
+ HC_STRUC *HcStruc;
+ UINT64 Capabilities;
+ URP_STRUC Parameters;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AmiUsbDriverBindingStart for %x\n", Controller);
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ &PciIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = PciIo->GetLocation(PciIo, &SegNum, &BusNum, &DevNum, &FuncNum);
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = PciIo->Pci.Read (
+ PciIo,
+ EfiPciIoWidthUint8,
+ 0,
+ sizeof(PciCfg),
+ PciCfg);
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Get the device path
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ &DevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return Status;
+ }
+
+ USB_DEBUG(3, "USB HC Bus# %x Dev# %x Func# %x, PI %x\n", BusNum, DevNum, FuncNum ,PciCfg[0x9]);
+ // Try to locate EHCI controller
+ if (PciCfg[0x9] == PCI_CLASSC_PI_UHCI ||
+ PciCfg[0x9] == PCI_CLASSC_PI_OHCI ) {
+ LocateEhciController(This, Controller, DevicePath);
+ }
+
+ // Enable the device
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = PciIo->Attributes (PciIo,
+ EfiPciIoAttributeOperationEnable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Enable device
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return EFI_DEVICE_ERROR;
+ }
+
+ HcStruc = AddHC(Controller, BusNum, DevNum, FuncNum, PciCfg[0x9],
+ PciCfg[0x3C], DevicePath, PciIo);
+ if (HcStruc == NULL) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ // Initialize host controller
+ Parameters.bFuncNumber = USB_API_HC_START_STOP;
+ Parameters.ApiData.HcStartStop.Start = TRUE;
+ Parameters.ApiData.HcStartStop.HcStruc = HcStruc;
+ InvokeUsbApi(&Parameters);
+
+ USB_DEBUG(3, "HC start completed, exit code %d.\n", Parameters.bRetValue);
+
+ Status = InstallHcProtocols(This, Controller, PciIo, HcStruc);
+ if (EFI_ERROR(Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ return Status;
+ }
+ PROGRESS_CODE(DXE_USB_ENABLE);
+
+ return EFI_SUCCESS;
+
+} // end of AmiUsbDriverBindingStart
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AmiUsbDriverBindingStop
+//
+// Description: Stop this driver on ControllerHandle. Support stoping any
+// child handles created by this driver.
+//
+// Input: This - Protocol instance pointer.
+// DeviceHandle - Handle of device to stop driver on
+// NumberOfChildren - Number of Children in the ChildHandleBuffer
+// ChildHandleBuffer - List of handles for the children we
+// need to stop.
+// Output: EFI_SUCCESS on success, EFI_ERROR on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+AmiUsbDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+)
+{
+ EFI_STATUS Status;
+ URP_STRUC Parameters;
+ EFI_USB_HC_PROTOCOL *HcProtocol;
+ EFI_USB2_HC_PROTOCOL *HcProtocol2;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ HC_DXE_RECORD *DxeRecord;
+ UINT32 Index;
+ HC_STRUC *HcStruc;
+ UINT64 Capabilities;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AmiUsbDriverBindingStop for %x\n", Controller);
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsbHcProtocolGuid,
+ &HcProtocol,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiUsb2HcProtocolGuid,
+ &HcProtocol2,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR(Status)) {
+ return EFI_UNSUPPORTED;
+ }
+
+ DxeRecord = (HC_DXE_RECORD*)(UINTN)HcProtocol;
+ HcStruc = DxeRecord->hc_data;
+ PciIo = HcStruc->PciIo;
+
+ // Stop host controller
+ Parameters.bFuncNumber = USB_API_HC_START_STOP;
+ Parameters.ApiData.HcStartStop.Start = FALSE;
+ Parameters.ApiData.HcStartStop.HcStruc = HcStruc;
+ InvokeUsbApi(&Parameters);
+
+ USB_DEBUG(3, "HC stop completed, exit code %d.\n", Parameters.bRetValue);
+
+ // Disconnect devices and uninstall usb device related protocols
+ UsbHcOnTimer(gEvUsbEnumTimer, NULL);
+
+ Status = gBS->UninstallMultipleProtocolInterfaces ( Controller,
+ &gEfiUsbHcProtocolGuid, HcProtocol,
+ &gEfiUsb2HcProtocolGuid, HcProtocol2,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ // Free HC memory
+ Index = (UINT8)((HcStruc->bHCType - USB_HC_UHCI) >> 4);
+
+ aHCSpecificInfo[Index].HcPostStop(Controller, HcStruc);
+/*
+ if (HcStruc->fpFrameList) {
+ FreeHcMemory(PciIo,
+ EFI_SIZE_TO_PAGES(aHCSpecificInfo[Index].FrameListSize),
+ HcStruc->fpFrameList);
+ HcStruc->fpFrameList = NULL;
+ }
+*/
+
+#if !USB_RUNTIME_DRIVER_IN_SMM
+ if (HcStruc->MemPool) {
+ FreeHcMemory(PciIo, HcStruc->MemPoolPages, HcStruc->MemPool);
+ HcStruc->MemPool = NULL;
+ gBS->FreePool(HcStruc->MemBlkSts);
+ HcStruc->MemBlkSts = NULL;
+ }
+#endif
+
+ HcStruc->dHCFlag &= ~HC_STATE_USED;
+ gUsbData->NumOfHc--;
+
+ // Disable the device
+ Status = DxeRecord->pciIo->Attributes (
+ DxeRecord->pciIo,
+ EfiPciIoAttributeOperationSupported, 0,
+ &Capabilities); // Get device capabilities
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = DxeRecord->pciIo->Attributes (
+ DxeRecord->pciIo,
+ EfiPciIoAttributeOperationDisable,
+ Capabilities & EFI_PCI_DEVICE_ENABLE,
+ NULL); // Disable device
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiPciIoProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ // Free memory allocated in Start function
+ gBS->FreePool(DxeRecord);
+
+ return EFI_SUCCESS;
+
+} // End of UHCIDriverBindingStop
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: HotplugIsEnabled
+//
+// Description: This function returns TRUE if there is a need for extra USB
+// devices that might be inserted/enumerated after legacy boot
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN HotplugIsEnabled()
+{
+ BOOLEAN FddHotplug;
+ BOOLEAN HddHotplug;
+ BOOLEAN CdromHotplug;
+
+ FddHotplug = ((gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED)
+ || ((gUsbData->fdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO)
+ && (gUsbData->NumberOfFDDs == 0)));
+
+ HddHotplug = ((gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED)
+ || ((gUsbData->hdd_hotplug_support == SETUP_DATA_HOTPLUG_AUTO)
+ && (gUsbData->NumberOfHDDs == 0)));
+
+ CdromHotplug = ((gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_ENABLED)
+ || ((gUsbData->cdrom_hotplug_support == SETUP_DATA_HOTPLUG_AUTO)
+ && (gUsbData->NumberOfCDROMs == 0)));
+
+ return FddHotplug || HddHotplug || CdromHotplug;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: OnExitBootServices
+//
+// Description: EXIT_BOOT_SERVICES notification callback function.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+OnExitBootServices(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ URP_STRUC Parameters;
+
+#if !USB_RUNTIME_DRIVER_IN_SMM
+ gBS->SetTimer(gUsbIntTimerEvt, TimerCancel, 0);
+ gBS->CloseEvent(gUsbIntTimerEvt);
+#endif
+
+ Parameters.bFuncNumber = USB_API_STOP;
+ Parameters.bSubFunc = 0;
+ InvokeUsbApi(&Parameters);
+
+ gUsbData->dUSBStateFlag &= ~(USB_FLAG_RUNNING_UNDER_EFI);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: OnLegacyBoot
+//
+// Description: This function is invoked when on Legacy Boot
+//
+// Input: Event - Efi event occurred upon legacyboot
+// Context - Not used
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+OnLegacyBoot (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ CONNECTED_USB_DEVICES_NUM Devs;
+// URP_STRUC Parameters; //<(EIP52339-)
+ UINT8 UsbLegacySupport;
+ UINT32 EbdaAddr = (UINT32)(*((UINT16*)0x40E)) << 4;
+
+ *(UINT32*)(EbdaAddr + USB_PROTOCOL_EBDA_OFFSET) = (UINT32)gAmiUsbController;
+
+ UsbLegacySupport = UsbSetupGetLegacySupport();
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AMIUHCD::OnLegacyBoot::%d\n", UsbLegacySupport);
+
+ gUsbData->dUSBStateFlag &= ~(USB_FLAG_RUNNING_UNDER_EFI);
+
+ switch (UsbLegacySupport) {
+ case 0: break; // Enable
+ case 2: // Auto - check for devices, stop USB if none are present.
+ if (HotplugIsEnabled()) break; // Do not stop as Hotplug devices will be inserted
+ ReportDevices(&Devs);
+ if (Devs.NumUsbKbds+Devs.NumUsbMice+Devs.NumUsbPoint+Devs.NumUsbMass+Devs.NumUsbHubs) { //(EIP38434)
+ break;
+ }
+ case 1: // Disable - stop USB controllers
+ //(EIP52339)>
+ UsbRtShutDownLegacy();
+// gLegacyUsbStatus=FALSE;
+// Parameters.bFuncNumber = USB_API_STOP;
+// Parameters.bSubFunc = 0;
+// gUsbData->fpURP = &Parameters;
+// USB_DEBUG(DEBUG_LEVEL_3, "Stop USB controllers.\n");
+// USBGenerateSWSMI (USB_SWSMI);
+ //<(EIP52339)
+ return;
+ }
+
+ UsbPrepareForLegacyOS();
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ReadyToBootNotify
+//
+// Description: This function is invoked when on ReadyToBoot
+//
+// Input: Event - Efi event occurred upon legacyboot
+// Context - Not used
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+EFIAPI
+ReadyToBootNotify(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ gAmiUsbController->USBDataPtr = NULL;
+ gBS->CloseEvent(Event);
+}
+
+
+#ifdef USB_CONTROLLERS_WITH_RMH
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: IsControllerWithRmh
+//
+// Description: This function checks if the controller has integrated
+// USB 2.0 Rate Matching Hubs (RMH).
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+BOOLEAN
+IsControllerWithRmh (
+ EFI_PCI_IO_PROTOCOL *PciIo
+)
+{
+ UINT16 Vid = 0;
+ UINT16 Did = 0;
+ UINT8 Index = 0;
+
+ PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, PCI_VID, 1, &Vid);
+ PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, PCI_DID, 1, &Did);
+
+ for (Index = 0; Index < COUNTOF(gControllersWithRmh); Index++) {
+ if ((gControllersWithRmh[Index].Vid == Vid) &&
+ (gControllersWithRmh[Index].Did == Did)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AddHC
+//
+// Description: This function checks the type of controller and its PCI info
+// against gHcPciInfo data table; if HC is found appropriate, then
+// it allocates the frame list for this HC and adds the new HCStruc
+// entry.
+//
+// Input: This - Binding Protocol instance pointer
+// PciBus/Dev/Func - PCI location of the HC
+// Controller - Host Controller handle
+// Irq - HW Interrupt number
+//
+// Output: TRUE - the new controller has been added
+// FALSE - controller was not added (see notes)
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+HC_STRUC*
+AddHC (
+ EFI_HANDLE Controller,
+ UINTN PciBus,
+ UINTN PciDev,
+ UINTN PciFunc,
+ UINT8 HcType,
+ UINT8 Irq,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ EFI_PCI_IO_PROTOCOL *PciIo
+)
+{
+ HC_STRUC **NewHcTable = NULL;
+ HC_STRUC *HcStruc = NULL;
+ UINT8 Index;
+ UINT16 PciAddr;
+ EFI_STATUS Status;
+ UINT64 Supports;
+ ASLR_QWORD_ASD *Resources = NULL;
+
+ if (gUsbData->NumOfHc >= gUsbData->HcTableCount) {
+ Status = ReallocateMemory(
+ gUsbData->HcTableCount * sizeof(HC_STRUC*),
+ (gUsbData->HcTableCount + 1) * sizeof(HC_STRUC*),
+ (VOID**)&gUsbData->HcTable);
+ if (EFI_ERROR(Status)) {
+ return NULL;
+ }
+
+ gUsbData->HcTableCount++;
+ }
+
+ PciAddr = (UINT16)((PciBus << 8) | (PciDev << 3) | PciFunc);
+
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ if (gUsbData->HcTable[Index] == NULL) {
+ continue;
+ }
+ if (gUsbData->HcTable[Index]->dHCFlag & HC_STATE_USED) {
+ continue;
+ }
+ if (gUsbData->HcTable[Index]->wBusDevFuncNum == PciAddr) {
+ break;
+ }
+ }
+
+ if (Index != gUsbData->HcTableCount) {
+ HcStruc = gUsbData->HcTable[Index];
+ } else {
+ for (Index = 0; Index < gUsbData->HcTableCount; Index++) {
+ if (gUsbData->HcTable[Index] == NULL) {
+ break;
+ }
+ }
+
+ if (Index == gUsbData->HcTableCount) {
+ return NULL;
+ }
+
+ Status = gBS->AllocatePool(EfiRuntimeServicesData, sizeof(HC_STRUC), &HcStruc);
+ if (EFI_ERROR(Status)) {
+ return NULL;
+ }
+ gBS->SetMem(HcStruc, sizeof(HC_STRUC), 0);
+ }
+
+ gUsbData->HcTable[Index] = HcStruc;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "AddHC for device %x\n", PciAddr);
+
+ //
+ // Initialize the HC_STRUC with available values
+ //
+ HcStruc->dHCFlag |= HC_STATE_USED;
+ HcStruc->bHCNumber = Index + 1;
+ HcStruc->bHCType = (UINT8)(HcType + USB_HC_UHCI);
+ HcStruc->wBusDevFuncNum = PciAddr;
+ HcStruc->Controller = Controller;
+ HcStruc->Irq = Irq;
+ HcStruc->pHCdp = DevicePath;
+ HcStruc->PciIo = PciIo;
+
+ PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, PCI_VID, 1, &HcStruc->Vid);
+ PciIo->Pci.Read(PciIo, EfiPciIoWidthUint16, PCI_DID, 1, &HcStruc->Did);
+
+ Status = PciIo->GetBarAttributes(PciIo, 0, &Supports, &Resources);
+ if (!EFI_ERROR (Status)) {
+ HcStruc->BaseAddressSize = (UINTN)Resources->_LEN;
+ gBS->FreePool(Resources);
+ }
+
+#ifdef USB_CONTROLLERS_WITH_RMH
+ if (IsControllerWithRmh(PciIo)) {
+ HcStruc->dHCFlag |= HC_STATE_CONTROLLER_WITH_RMH;
+ }
+#endif
+
+ //
+ // Allocate memory for UHC
+ // HC Type Index: 0/1/2/3 for U/O/E/XHCI
+ //
+ Index = (UINT8)(HcType >> 4);
+
+ Status = aHCSpecificInfo[Index].HcPreInit(Controller, HcStruc);
+ if (EFI_ERROR(Status)) {
+ EfiZeroMem(HcStruc, sizeof(HC_STRUC));
+ return NULL;
+ }
+
+ if (aHCSpecificInfo[Index].FrameListSize) {
+ if (HcStruc->fpFrameList == NULL) {
+ HcStruc->fpFrameList = (UINT32*)AllocateHcMemory ( PciIo,
+ EFI_SIZE_TO_PAGES(aHCSpecificInfo[Index].FrameListSize),
+ aHCSpecificInfo[Index].FrameListAlignment);
+ }
+ if (HcStruc->fpFrameList == NULL) {
+ EfiZeroMem(HcStruc, sizeof(HC_STRUC));
+ return NULL;
+ }
+
+ EfiZeroMem(HcStruc->fpFrameList, aHCSpecificInfo[Index].FrameListSize);
+ USB_DEBUG(DEBUG_LEVEL_3, "Frame List is allocated at %x.\n", HcStruc->fpFrameList);
+ }
+
+#if !USB_RUNTIME_DRIVER_IN_SMM
+ HcStruc->MemPoolPages = 2;
+ HcStruc->MemPool = (UINT8*)AllocateHcMemory(PciIo, HcStruc->MemPoolPages, 0x1000);
+ ASSERT(HcStruc->MemPool);
+ gBS->SetMem(HcStruc->MemPool, HcStruc->MemPoolPages << 12, 0);
+
+ HcStruc->MemBlkStsBytes = (HcStruc->MemPoolPages << 12) / sizeof(MEM_BLK) / 8;
+ Status = gBS->AllocatePool(EfiRuntimeServicesData, HcStruc->MemBlkStsBytes ,
+ &HcStruc->MemBlkSts);
+ ASSERT_EFI_ERROR(Status);
+ gBS->SetMem(HcStruc->MemBlkSts, HcStruc->MemBlkStsBytes, (UINT8)(~0));
+#endif
+
+ if (IsExternalController(DevicePath)) {
+ HcStruc->dHCFlag |= HC_STATE_EXTERNAL;
+ }
+
+ gUsbData->NumOfHc++;
+
+ USB_DEBUG(DEBUG_LEVEL_3, " controller #%x added to HCStrucTable\n", HcStruc->bHCNumber);
+
+ return HcStruc;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CheckDeviceReady
+//
+// Description: This function invokes USB Mass Storage API handler to
+// check whether device is ready. If called for the first time,
+// this function retrieves the mass storage device geometry
+// and fills the corresponding fpDevInfo fields.
+//
+// Input: Pointer to device which needs to be checked
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+CheckDeviceReady(DEV_INFO* DevInfo)
+{
+#if USB_DEV_MASS
+ URP_STRUC Parameters;
+
+ USB_DEBUG(DEBUG_LEVEL_3, "UHCD CheckDeviceReady-->");
+
+ //
+ // Prepare URP_STRUC with USB_MassRead attributes
+ //
+ Parameters.bFuncNumber = USB_API_MASS_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_MASSAPI_CHECK_DEVICE;
+ Parameters.ApiData.MassChkDevReady.fpDevInfo = DevInfo;
+
+ InvokeUsbApi(&Parameters);
+ USB_DEBUG(DEBUG_LEVEL_3, "-->done.\n");
+#endif
+
+}
+
+/*
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetNextMassDevice
+//
+// Description: This is the interface function that executes
+// USBMassAPIGetDeviceInformation function and returns the
+// information about mass storage device.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8 GetNextMassDevice(UINT8 *Data, UINT8 DataSize, UINT8 DevAddr)
+{
+ URP_STRUC Parameters;
+
+ Parameters.bFuncNumber = USB_API_MASS_DEVICE_REQUEST;
+ Parameters.bSubFunc = USB_MASSAPI_GET_DEVICE_INFO;
+ Parameters.ApiData.MassGetDevInfo.bDevAddr = DevAddr;
+
+ gUsbData->fpURP = &Parameters;
+ USBGenerateSWSMI (USB_SWSMI);
+
+ pBS->CopyMem(Data,
+ (UINT8*)(UINTN)Parameters.ApiData.MassGetDevInfo.fpDevId, DataSize);
+
+ return Parameters.ApiData.MassGetDevInfo.bDevAddr;
+}
+*/
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetNextMassDeviceName
+//
+// Description: This function returns a name string of connected mass storage
+// device.
+//
+// Input: Data - Pointer to a string buffer to be filled
+// DataSize - Size of the data to copy to a buffer
+// DevIndex - Device index
+// Output: The updated device index, see below.
+//
+// Notes: Initially DevIndex should be set to 0. This function returns
+// the name of the first mass storage device (if no device found
+// it returns DevIndex as 0FFh) and also updates DevIndex to the
+// device address of the current mass storage device. If no other
+// mass storage device is found then the routine sets the bit7 to 1
+// indicating current information is valid but no more mass device
+// found in the system. The caller can get the next device info if
+// DevIndex is not 0FFh and bit7 is not set.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8
+GetNextMassDeviceName(
+ UINT8 *Data,
+ UINT8 DataSize,
+ UINT8 DevIndex
+)
+{
+ UINT8 i;
+ UINT8 CurrentDevIndex;
+
+ for (i = DevIndex; i < MAX_DEVICES; i++) {
+ if (!(gUsbData->aDevInfoTable[i].Flag & DEV_INFO_DEV_PRESENT)) {
+ continue;
+ }
+ if (gUsbData->aDevInfoTable[i].bDeviceType == BIOS_DEV_TYPE_STORAGE) {
+ break;
+ }
+ }
+ if (i == MAX_DEVICES) {
+ return USB_ERROR; // No mass storage devices present
+ }
+
+ //
+ // Copy device name
+ //
+ pBS->CopyMem(Data, &gUsbData->aDevInfoTable[i].DevNameString, DataSize);
+
+ CurrentDevIndex = i;
+
+ //
+ // Look for the other devices for any subsequent calls
+ //
+ for (i++; i < MAX_DEVICES; i++) {
+ if (gUsbData->aDevInfoTable[i].bDeviceType == BIOS_DEV_TYPE_STORAGE) {
+ break;
+ }
+ }
+ if (i == MAX_DEVICES) {
+ CurrentDevIndex |= 0x80; // No other devices, return current device w/ bit7
+ } else {
+ CurrentDevIndex = i; // Return next device index
+ }
+
+ return CurrentDevIndex;
+
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ClearLegacyUsbKbdBuffer
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ClearLegacyUsbKbdBuffer(
+ VOID
+)
+{
+// gUsbData->bLastUSBKeyCode = 0; //(EIP102150-)
+
+ EfiZeroMem(gUsbData->aKBCCharacterBufferStart, sizeof(gUsbData->aKBCCharacterBufferStart));
+ gUsbData->fpKBCCharacterBufferHead = gUsbData->aKBCCharacterBufferStart;
+ gUsbData->fpKBCCharacterBufferTail = gUsbData->aKBCCharacterBufferStart;
+
+ EfiZeroMem(gUsbData->aKBCScanCodeBufferStart, sizeof(gUsbData->aKBCScanCodeBufferStart));
+ gUsbData->fpKBCScanCodeBufferPtr = gUsbData->aKBCScanCodeBufferStart;
+
+ EfiZeroMem(gUsbData->aKBCDeviceIDBufferStart, sizeof(gUsbData->aKBCDeviceIDBufferStart)); //(EIP102150+)
+ EfiZeroMem(gUsbData->aKBCShiftKeyStatusBufferStart, sizeof(gUsbData->aKBCShiftKeyStatusBufferStart)); //(EIP102150+)
+
+ EfiZeroMem(gUsbData->aKBInputBuffer, sizeof(gUsbData->aKBInputBuffer));
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbChangeEfiToLegacy
+//
+// Description: This is the interface function that reports switches between EFI and
+// Legacy USB operation.
+//
+// Input: Switch that indicates where the switch should be turned:
+// 1 - from EFI to Legacy
+// 0 - from Legacy to EFI
+//
+// Output: None
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID UsbChangeEfiToLegacy (UINT8 EfiToLegacy)
+{
+ //(EIP96616+)>
+ DEV_INFO *DevInfo = NULL;
+ DEV_INFO *DevInfoEnd = gUsbData->aDevInfoTable + COUNTOF(gUsbData->aDevInfoTable);
+
+ if(EfiToLegacy) { // Changing to Legacy
+ if(gEmulationTrap != NULL && gLegacyUsbStatus) {
+ gEmulationTrap->TrapEnable(gEmulationTrap);
+ }
+ ClearLegacyUsbKbdBuffer();
+
+ gUsbData->dUSBStateFlag &= ~USB_FLAG_RUNNING_UNDER_EFI;
+
+ } else { // Changing to EFI
+ if(gEmulationTrap != NULL && gLegacyUsbStatus) {
+ gEmulationTrap->TrapDisable(gEmulationTrap);
+ }
+ ClearLegacyUsbKbdBuffer();
+
+ for (DevInfo = &gUsbData->aDevInfoTable[1]; DevInfo != DevInfoEnd; ++DevInfo ){
+ if (DevInfo->Flag & DEV_INFO_IN_QUEUE) {
+ continue;
+ }
+ if ((DevInfo->Flag & DEV_INFO_VALIDPRESENT) == DEV_INFO_VALID_STRUC) {
+ if (DevInfo->Flag & DEV_INFO_DEV_BUS) {
+ QueuePut(&gUsbData->QueueCnnctDisc, DevInfo);
+ DevInfo->Flag |= DEV_INFO_IN_QUEUE;
+ }
+ }
+ }
+
+ for (DevInfo = &gUsbData->aDevInfoTable[1]; DevInfo != DevInfoEnd; ++DevInfo ){
+ if (DevInfo->Flag & DEV_INFO_IN_QUEUE) {
+ continue;
+ }
+ if ((DevInfo->Flag & DEV_INFO_VALIDPRESENT) == DEV_INFO_VALIDPRESENT) {
+ if (!(DevInfo->Flag & DEV_INFO_DEV_BUS)) {
+ QueuePut(&gUsbData->QueueCnnctDisc, DevInfo);
+ DevInfo->Flag |= DEV_INFO_IN_QUEUE;
+ }
+ }
+ }
+
+ gUsbData->dUSBStateFlag |= USB_FLAG_RUNNING_UNDER_EFI;
+ }
+
+ //<(EIP96616+)
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ReportDevices
+//
+// Description: This is the interface function that reports the number of devices
+// currently controlled by the driver.
+//
+// Input: Pointer to a structure that indicates the number of connected devices.
+//
+// Output: Input structure is updated.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+ReportDevices(
+ IN OUT CONNECTED_USB_DEVICES_NUM *Devs
+)
+{
+ HC_STRUC *HcStruc;
+ UINT8 i;
+ UINT8 Kbd = 0;
+ UINT8 Hub = 0;
+ UINT8 Mouse = 0;
+ UINT8 Mass = 0;
+ UINT8 Point = 0;
+ UINT8 Ccid = 0;
+ UINT8 Uhci = 0;
+ UINT8 Ohci = 0;
+ UINT8 Ehci = 0;
+ UINT8 Xhci = 0;
+
+ for (i = 1; i < MAX_DEVICES; i++) {
+
+ if ((gUsbData->aDevInfoTable[i].Flag & DEV_INFO_VALIDPRESENT)
+ != DEV_INFO_VALIDPRESENT) {
+ continue;
+ }
+ switch (gUsbData->aDevInfoTable[i].bDeviceType) {
+ case BIOS_DEV_TYPE_HID:
+ if (gUsbData->aDevInfoTable[i].HidDevType & HID_DEV_TYPE_KEYBOARD) {
+ Kbd++;
+ }
+ if (gUsbData->aDevInfoTable[i].HidDevType & HID_DEV_TYPE_MOUSE) {
+ Mouse++;
+ }
+ if (gUsbData->aDevInfoTable[i].HidDevType & HID_DEV_TYPE_POINT) {
+ Point++;
+ }
+ break;
+ case BIOS_DEV_TYPE_HUB:
+ Hub++;
+ break;
+ case BIOS_DEV_TYPE_STORAGE:
+ Mass++;
+ break;
+ case BIOS_DEV_TYPE_CCID:
+ Ccid++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ for (i = 0; i < gUsbData->HcTableCount; i++) {
+ HcStruc = gUsbData->HcTable[i];
+ if (HcStruc == NULL) {
+ continue;
+ }
+ if (!(HcStruc->dHCFlag & HC_STATE_USED)) {
+ continue;
+ }
+ switch (HcStruc->bHCType) {
+ case USB_HC_UHCI:
+ Uhci++;
+ break;
+ case USB_HC_OHCI:
+ Ohci++;
+ break;
+ case USB_HC_EHCI:
+ Ehci++;
+ break;
+ case USB_HC_XHCI:
+ Xhci++;
+ break;
+ default:
+ break;
+ }
+ }
+
+ (*Devs).NumUsbKbds = Kbd;
+ (*Devs).NumUsbMice = Mouse;
+ (*Devs).NumUsbPoint = Point;
+ (*Devs).NumUsbMass = Mass;
+ (*Devs).NumUsbHubs = Hub;
+ (*Devs).NumUsbCcids = Ccid;
+ (*Devs).NumUhcis = Uhci;
+ (*Devs).NumOhcis = Ohci;
+ (*Devs).NumEhcis = Ehci;
+ (*Devs).NumXhcis = Xhci;
+
+}
+
+ //(EIP52339+)>
+VOID UsbRtShutDownLegacy(VOID)
+{
+// URP_STRUC Params;
+//
+// Params.bFuncNumber = USB_API_LEGACY_CONTROL;
+// Params.bFuncNumber = USB_SHUTDOWN_LEGACY;
+//
+// gUsbData->fpURP = &Params; // Need to update gUsbData->fpURP every time
+// USBGenerateSWSMI (USB_SWSMI);
+ URP_STRUC Parameters;
+
+ if (gLegacyUsbStatus) {
+ gLegacyUsbStatus=FALSE;
+ Parameters.bFuncNumber = USB_API_STOP;
+ Parameters.bSubFunc = 0;
+ USB_DEBUG(DEBUG_LEVEL_3, "Stop USB controllers.\n");
+ InvokeUsbApi(&Parameters);
+ // Disconnect devices and uninstall usb device related protocols
+ if (gEvUsbEnumTimer != 0) {
+ UsbHcOnTimer(gEvUsbEnumTimer, NULL);
+ }
+ }
+}
+ //<(EIP52339+)
+ //(EIP74876+)>
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbRtStopController
+//
+// Description: This function stops the USB host controllers of a given
+// Bus Dev Function
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbRtStopController(
+ UINT16 HcBusDevFuncNum
+)
+{
+ URP_STRUC Parameters;
+
+ Parameters.bFuncNumber = USB_API_USB_STOP_CONTROLLER;
+ Parameters.ApiData.HcBusDevFuncNum = HcBusDevFuncNum;
+ InvokeUsbApi(&Parameters);
+
+ // Disconnect devices and uninstall usb device related protocols
+ if (gEvUsbEnumTimer != 0) {
+ UsbHcOnTimer(gEvUsbEnumTimer, NULL);
+ }
+}
+ //<(EIP74876+)
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: LocateEhciController
+//
+// Description: Visit all companions as different PCI functions of the same
+// PCI device as Controller (enumerate HCPCIInfo ). For each
+// companion function locate corresponding PCI_IO handle, execute
+// ConnectController if necessary; add them to aHCStrucTable.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+LocateEhciController(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *CompanionDevicePath
+)
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *Dp = CompanionDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DpLastPciNode = NULL;
+ EFI_DEVICE_PATH_PROTOCOL *DpBridge;
+ EFI_DEVICE_PATH_PROTOCOL *DpRemaining;
+ EFI_HANDLE Bridge = NULL;
+ UINT8 EhciFunc;
+ EFI_DEVICE_PATH_PROTOCOL *DpEhci;
+ PCI_DEVICE_PATH *DpEhciPciNode;
+ EFI_HANDLE Ehci = NULL;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ UINTN SegNum;
+ UINTN BusNum;
+ UINTN DevNum;
+ UINTN FuncNum;
+ USB_CLASSC UsbClassCReg;
+ EFI_USB2_HC_PROTOCOL *UsbHc2Protocol;
+ UINT8 ConnectAttempt = 0;
+
+ USB_DEBUG(3, "LocateEhciController..\n");
+
+ while(!EfiIsDevicePathEnd(Dp)) {
+ Dp = EfiNextDevicePathNode(Dp);
+ if ((Dp->Type == HARDWARE_DEVICE_PATH) &&
+ (Dp->SubType == HW_PCI_DP)) {
+ DpLastPciNode = Dp;
+ }
+ }
+
+ if (DpLastPciNode == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DpBridge = EfiDuplicateDevicePath(CompanionDevicePath);
+ if (DpBridge == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ Dp = (EFI_DEVICE_PATH_PROTOCOL*)((UINT8*)DpBridge +
+ ((UINT8*)DpLastPciNode - (UINT8*)CompanionDevicePath));
+
+ Dp->Type = EFI_END_ENTIRE_DEVICE_PATH;
+ Dp->SubType = EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ SET_NODE_LENGTH(Dp, sizeof(EFI_DEVICE_PATH_PROTOCOL));
+
+ DpRemaining = DpBridge;
+ Status = gBS->LocateDevicePath(
+ &gEfiDevicePathProtocolGuid,
+ &DpRemaining,
+ &Bridge);
+ gBS->FreePool(DpBridge);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ DpEhci = EfiDuplicateDevicePath(CompanionDevicePath);
+ if (DpEhci == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ DpEhciPciNode = (PCI_DEVICE_PATH*)((UINT8*)DpEhci +
+ ((UINT8*)DpLastPciNode - (UINT8*)CompanionDevicePath)); // Locate last PCI node
+ EhciFunc = ((PCI_DEVICE_PATH*)DpLastPciNode)->Function;
+
+ for (EhciFunc++; EhciFunc <= 7; EhciFunc++) {
+ DpEhciPciNode->Function = EhciFunc;
+
+ ConnectAttempt = 0;
+ do {
+ USB_DEBUG(DEBUG_LEVEL_3, "\ttry Dev# %x Func# %x...",
+ DpEhciPciNode->Device, DpEhciPciNode->Function);
+
+ DpRemaining = DpEhci;
+ // Locate EHCI handle using device path
+ Status = gBS->LocateDevicePath(
+ &gEfiPciIoProtocolGuid,
+ &DpRemaining,
+ &Ehci);
+ if (!EFI_ERROR(Status)) {
+ Status = gBS->OpenProtocol(
+ Ehci,
+ &gEfiPciIoProtocolGuid,
+ &PciIo,
+ This->DriverBindingHandle,
+ Ehci,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ Status = PciIo->GetLocation(
+ PciIo,
+ &SegNum,
+ &BusNum,
+ &DevNum,
+ &FuncNum);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ if ((DevNum == DpEhciPciNode->Device) &&
+ (FuncNum == DpEhciPciNode->Function)) {
+ Status = PciIo->Pci.Read(
+ PciIo,
+ EfiPciIoWidthUint8,
+ CLASSC,
+ sizeof(USB_CLASSC),
+ &UsbClassCReg);
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status) ||
+ (UsbClassCReg.BaseCode != PCI_CLASSC_BASE_CLASS_SERIAL) ||
+ (UsbClassCReg.SubClassCode != PCI_CLASSC_SUBCLASS_SERIAL_USB) ||
+ (UsbClassCReg.PI != PCI_CLASSC_PI_EHCI)) {
+ USB_DEBUG(DEBUG_LEVEL_3, "BaseCode %x, SubClassCode %x, PI %x...",
+ UsbClassCReg.BaseCode, UsbClassCReg.SubClassCode, UsbClassCReg.PI);
+ Status = EFI_NOT_FOUND;
+ USB_DEBUG(DEBUG_LEVEL_3, "%r\n", Status);
+ break;
+ }
+ Status = gBS->OpenProtocol(
+ Ehci,
+ &gEfiUsbHcProtocolGuid,
+ &UsbHc2Protocol,
+ This->DriverBindingHandle,
+ Ehci,
+ EFI_OPEN_PROTOCOL_BY_HANDLE_PROTOCOL);
+ if (!EFI_ERROR(Status)) {
+ Status = EFI_ALREADY_STARTED;
+ USB_DEBUG(DEBUG_LEVEL_3, "%r\n", Status);
+ break;
+ }
+ Status = gBS->ConnectController(Ehci, NULL, NULL, FALSE);
+ USB_DEBUG(DEBUG_LEVEL_3, "%r\n", Status);
+ break;
+ }
+ }
+
+ // ConnectController to produce EHCI handle.
+ // Do not assert on EFI_ERROR because controller
+ // might not be functional (hidden for example) due
+ // to the board implementation or project policy and
+ // unsuccessfull connection is okay.
+ Status = gBS->ConnectController(Bridge, 0,
+ (EFI_DEVICE_PATH_PROTOCOL*)DpEhciPciNode, FALSE);
+ } while (!EFI_ERROR(Status) && (++ConnectAttempt < 2));
+ }
+
+ gBS->FreePool(DpEhci);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: CalculateMemorySize
+//
+// Description: This function returns the total amount of memory used by
+// all supported USB controllers.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT32 CalculateMemorySize(VOID)
+{
+ UINT32 Result = 0;
+
+ Result += (UINT32)(sizeof(USB_GLOBAL_DATA));
+ Result += 0x10; // Alignment for USB_GLOBAL_DATA allocation
+
+ Result += (UINT32)(sizeof(EFI_USB_PROTOCOL));
+ Result += 0x10; // Alignment for EFI_USB_PROTOCOL allocation
+
+USB_DEBUG(DEBUG_LEVEL_3,"USB RT memory allocation:\n 0x%x (gUsbData), ", Result);
+
+ Result += (UINT32) (MEM_BLK_COUNT * sizeof(MEM_BLK));
+ Result += 0x1000; // Alignment for local memory pool
+
+USB_DEBUG(DEBUG_LEVEL_3," 0x%x (gUsbData+Pool), ", Result);
+ //
+ // The following alignment adjustment are made with the assumption of
+ // the sequentual AllocAlignedMemory calls for frame lists allocation;
+ // if frame list allocations procedure will be change, the alignments
+ // might be revised.
+ //
+USB_DEBUG(DEBUG_LEVEL_3,"totally 0x%x Bytes allocated\n", Result);
+
+ return Result;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetRuntimeRegion
+//
+// Description: This function returns the beginning and the end of USB
+// runtime memory region.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+GetRuntimeRegion (
+ EFI_PHYSICAL_ADDRESS *Start,
+ EFI_PHYSICAL_ADDRESS *End
+)
+{
+ *Start = (EFI_PHYSICAL_ADDRESS)gStartPointer;
+ *End = (EFI_PHYSICAL_ADDRESS)gEndPointer;
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Dummy1
+//
+// Description: This function is a legacy mass storage support API stub,
+// replaced by the API producer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Dummy1(
+ USB_MASS_DEV* Device
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: Dummy2
+//
+// Description: This function is a legacy mass storage support API stub,
+// replaced by the API producer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+Dummy2(
+ VOID
+)
+{
+ return EFI_UNSUPPORTED;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DummyHcFunc
+//
+// Description: This function is dummy HC memory allocation routine.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+DummyHcFunc(
+ EFI_HANDLE Handle,
+ HC_STRUC *HcStruc
+)
+{
+ return EFI_SUCCESS;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/uhcd.cif b/Core/EM/usb/uhcd.cif
new file mode 100644
index 0000000..cea7694
--- /dev/null
+++ b/Core/EM/usb/uhcd.cif
@@ -0,0 +1,24 @@
+<component>
+ name = "Uhcd"
+ category = ModulePart
+ LocalRoot = "core\em\usb"
+ RefName = "UHCD"
+[files]
+"\uhcd.c"
+"\amiusbhc.c"
+"\usbbus.c"
+"\efiusbkb.c"
+"\tree.c"
+"\efiusbkb.h"
+"\usbsrc.sdl"
+"\usbbus.h"
+"\tree.h"
+"\efiusbmass.c"
+"\efiusbms.c"
+"\efiusbccid.c"
+"\efiusbpoint.c"
+"\efiusbhid.c"
+"\componentname.c"
+"\usbmisc.c"
+"\componentname.h"
+<endComponent>
diff --git a/Core/EM/usb/uhcd.dxs b/Core/EM/usb/uhcd.dxs
new file mode 100644
index 0000000..c148b22
--- /dev/null
+++ b/Core/EM/usb/uhcd.dxs
@@ -0,0 +1,42 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+#include <token.h>
+#if USB_RUNTIME_DRIVER_IN_SMM
+#include <Protocol/SmmBase.h>
+#include <Protocol/SmmSwDispatch.h>
+#endif
+#include <Protocol/PciRootBridgeIo.h>
+
+DEPENDENCY_START
+#if USB_RUNTIME_DRIVER_IN_SMM
+ EFI_SMM_BASE_PROTOCOL_GUID AND
+ EFI_SMM_SW_DISPATCH_PROTOCOL_GUID AND
+#endif
+ EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID
+DEPENDENCY_END
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/uhcd.h b/Core/EM/usb/uhcd.h
new file mode 100644
index 0000000..f54c3f5
--- /dev/null
+++ b/Core/EM/usb/uhcd.h
@@ -0,0 +1,641 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/uhcd.h 49 10/16/16 11:19p Wilsonlee $
+//
+// $Revision: 49 $
+//
+// $Date: 10/16/16 11:19p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/uhcd.h $
+//
+// 49 10/16/16 11:19p Wilsonlee
+// [TAG] EIP284071
+// [Category] Improvement
+// [Description] Clear USBDataPt from EFI_USB_PROTOCOL at the
+// readytoboot event.
+// [Files] uhcd.c, uhcd.h
+//
+// 48 7/07/16 1:13a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 47 1/19/16 3:19a Wilsonlee
+// [TAG] EIP251667
+// [Category] Improvement
+// [Description] Implement EFI_USB2_HC_PROTOCOL.SetState() function.
+// [Files] amiusbhc.c, uhcd.h
+//
+// 46 11/23/14 9:12p Wilsonlee
+// [TAG] EIP188119
+// [Category] Improvement
+// [Description] Disconnect devices and uninstall usb device related
+// protocols if we call stop api for the host controllers.
+// [Files] usbkbd.c, usbbus.c, uhcd.h, uhcd.c
+//
+// 45 4/03/14 3:45a Wilsonlee
+// [TAG] EIP156742
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hang at 0x9C during DC cycle test under RHEL6.5
+// UEF.I
+// [RootCause] The hw smi may be triggered when we reallocate memory for
+// gUsbData->HcTable.
+// [Solution] Assign the new memory space to gUsbData->HcTable before we
+// free the old.
+// [Files] uhcd.c, uhcd.h, usbmisc.c
+//
+// 44 7/03/13 5:24a Ryanchou
+// [TAG] EIP123988
+// [Category] Improvement
+// [Description] Move the code creating BBS table to end of POST.
+// [Files] UsbBbs.c, UsbInt13.c, UsbInt13.cif, UsbInt13.h,
+// UsbInt13.mak, UsbInt13.sdl, efiusbmass.c, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 43 3/19/13 4:02a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 42 1/11/13 4:22a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 41 8/29/12 8:40a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 40 5/04/12 6:45a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 39 5/04/12 5:32a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 38 12/14/11 2:12a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 37 12/07/11 10:53p Ryanchou
+// [TAG] EIP77121
+// [Category] Improvement
+// [Description] Check added to skip PCI interface type 0xFE, it is not
+// USB controller.
+// [Files] uhcd.c, uhcd.h
+//
+// 36 11/08/11 8:23a Wilsonlee
+// [TAG] EIP74876
+// [Category] New Feature
+// [Description] Add USB API for shutdown single USB controller.
+// [Files] amiusb.c, amiusb.h, usb.c, usbdef.h, uhcd.c, uhcd.h,
+// AmiUsbController.h
+//
+// 35 11/08/11 2:00a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 34 7/13/11 4:14a Ryanchou
+// [TAG] EIP59332
+// [Category] Improvement
+// [Description] Modified the Stop function for UHCD and USBBUS to
+// properly stop devices and uninstall the protocols.
+// [Files] uhcd.c, uhcd.h, uhci.c, usbbus.c, UsbInt13.c, usbmisc.c
+//
+// 33 7/12/11 11:43a Ryanchou
+// [TAG] EIP56918
+// [Category] New Feature
+// [Description] Added CCID device support.
+// [Files] amiusb.c, amiusb.h, amiusbrtCCID.h, ehci.c, ohci.c, uhci.c,
+// usb.c, UsbCCID.c, usbdef.h, usbrt.cif, usbsetup.c, efiusbccid.c,
+// framework.cif, uhcd.c, uhcd.cif, uhcd.h, usbsrc.sdl, AmiusbCCID.h,
+// AmiUsbController.h, AmiUSBProtocols.cif
+//
+// 32 5/03/11 10:49a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 31 4/06/11 3:22a Tonylo
+// [TAG] EIP57354
+// [Category] Improvement
+// [Description] Core 4.6.5.0 compliant. UEFI 2.3 and PI 1.x support.
+//
+// 30 4/06/11 12:46a Ryanchou
+// [TAG] EIP51653
+// [Category] New Feature
+// [Description] Added an interface that skips specific port
+// enumeration.
+// [Files] AmiUsbController.h, uhcd.c, uhcd.h, usb.c, usbdef.h,
+// usbport.c
+//
+// 29 2/22/11 5:10a Tonylo
+// [TAG] EIP52339
+// [Category] New Feature
+// [Description] USB changes of USB host safe disabling solution.
+// [Files] USB.C
+// UHCD.C
+// UHCD.H
+// AmiUsbController.h
+//
+// 28 8/31/10 9:03a Tonylo
+// Issue Number: 41544
+// Category: New Feature
+// Description: Add EntronTech XHCI support.
+//
+// 27 6/22/10 9:11p Olegi
+// EIP39708: Added new incompatibility type for HIDs that ignore boot
+// protocol.
+//
+// 26 6/17/10 10:34a Olegi
+// EIP39326: Runtime data moved to runtime memory region.
+//
+// 25 5/11/10 9:30a Olegi
+// LocateAllCompanions returns the status; EIP#38161
+//
+// 24 3/25/10 9:48a Olegi
+//
+// 23 1/19/10 11:59a Olegi
+//
+// 22 10/30/09 5:48p Olegi
+//
+// 21 10/09/09 5:57p Olegi
+//
+// 20 10/02/09 10:50a Olegi
+// Code cleanup.
+//
+// 19 3/26/09 2:17p Olegi
+// All setup related code is moved to OEMPORT.C to maximize the porting
+// capabilities.
+//
+// 18 11/25/08 6:02p Olegi
+// Support for OEM USB Boot Override feature. EIP#17052.
+//
+// 13 5/16/08 12:03p Olegi
+// Compliance with AMI coding standard.
+//
+// 9 3/16/07 6:11p Olegi
+// ATOMIC macro redefinition undone.
+// CRITICAL_CODE macro redefined.
+//
+// 8 3/16/07 5:18p Olegi
+// Undefined ATOMIC macro.
+//
+// 7 3/20/06 3:38p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 6 3/01/06 3:54p Olegi
+// USB_LEGACY_PLATFORM_SUPPORT added.
+//
+// 4 6/03/05 11:53a Andriyn
+// findHC declaration migrated
+//
+// 3 5/17/05 7:51p Andriyn
+// USB BUS pre-release
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: Uhcd.h
+//
+// Description: AMI USB Host Controller Driver header file
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _AMIUSB_H
+#define _AMIUSB_H
+
+#include <Protocol\BlockIo.h>
+#include <Protocol\DevicePath.h>
+#include <Protocol\PciIo.h>
+#include <Protocol\SimplePointer.h>
+#include <Protocol\ComponentName.h>
+#include <Protocol\AmiUsbController.h>
+#include <Protocol\AmiUsbCCID.h>
+#include <Protocol\DriverBinding.h>
+#include <Protocol\SimpleTextIn.h>
+#include <Protocol\UsbIo.h>
+#include "amidef.h"
+#include "usbdef.h"
+
+
+/* PCI Configuration Registers for USB */
+// Class Code Register offset
+#define CLASSC 0x09
+// USB IO Space Base Address Register offset
+#define USBBASE 0x20
+
+//
+// USB Base Class Code,Sub-Class Code and Programming Interface.
+//
+#define PCI_CLASSC_BASE_CLASS_SERIAL 0x0c
+#define PCI_CLASSC_SUBCLASS_SERIAL_USB 0x03
+#define PCI_CLASSC_IFT_USB_DEVICE 0xFE // Interface type for USB Device
+#define PCI_CLASSC_PI_UHCI 0x00
+#define PCI_CLASSC_PI_OHCI 0x10
+#define PCI_CLASSC_PI_EHCI 0x20
+#define PCI_CLASSC_PI_XHCI 0x30
+
+#pragma pack(push, 1)
+
+//
+// USB Class Code structure
+//
+typedef struct
+{
+ UINT8 PI;
+ UINT8 SubClassCode;
+ UINT8 BaseCode;
+} USB_CLASSC;
+
+#pragma pack(pop)
+
+UINT8 UsbSmiReConfigDevice(HC_STRUC* hc, DEV_INFO* dev);
+
+#define DEBUG_LEVEL_USBBUS DEBUG_LEVEL_3
+#define DEBUG_USBHC_LEVEL DEBUG_LEVEL_3
+#define DEBUG_USBHC_LEVEL8 DEBUG_LEVEL_8
+
+EFI_STATUS usbhc_init(EFI_HANDLE ImageHandle,EFI_HANDLE ServiceHandle);
+
+#define ATOMIC(a) {\
+ EFI_TPL savetpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\
+ {a;}\
+ gBS->RestoreTPL(savetpl); \
+}\
+
+#define CRITICAL_CODE(level, a) {\
+ EFI_TPL savetpl;\
+ EFI_TPL currenttpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); \
+ gBS->RestoreTPL(currenttpl);\
+ if(currenttpl<=level)\
+ currenttpl=level;\
+ savetpl = gBS->RaiseTPL (currenttpl);\
+ {a;}\
+ gBS->RestoreTPL(savetpl); \
+}\
+
+//#define CRITICAL_CODE(level, a) {\
+// EFI_TPL savetpl = gBS->RaiseTPL (level);\
+// {a;}\
+// gBS->RestoreTPL(savetpl); \
+//}\
+
+extern EFI_GUID gEfiDriverBindingProtocolGuid;
+extern EFI_GUID gEfiComponentName2ProtocolGuid; //(EIP59272)
+
+EFI_STATUS UsbMsInit(EFI_HANDLE ImageHandle, EFI_HANDLE ServiceHandle);
+EFI_STATUS UsbMassInit(EFI_HANDLE ImageHandle, EFI_HANDLE ServiceHandle);
+EFI_STATUS UsbCCIDInit(EFI_HANDLE ImageHandle, EFI_HANDLE ServiceHandle);
+HC_STRUC* FindHcStruc(EFI_HANDLE Controller);
+
+EFI_STATUS
+AmiUsbDriverEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable );
+
+EFI_STATUS
+AmiUsbDriverBindingSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS
+AmiUsbDriverBindingStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath );
+
+EFI_STATUS
+AmiUsbDriverBindingStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer );
+
+HC_STRUC*
+AddHC (
+ EFI_HANDLE Controller,
+ UINTN PciBus,
+ UINTN PciDev,
+ UINTN PciFunc,
+ UINT8 HcType,
+ UINT8 Irq,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePatch,
+ EFI_PCI_IO_PROTOCOL *PciIo
+);
+
+EFI_STATUS
+LocateEhciController(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *CompanionDevicePath
+);
+
+VOID
+OnLegacyBoot (
+ EFI_EVENT Event,
+ VOID *Context );
+
+VOID
+EFIAPI
+ReadyToBootNotify(
+ EFI_EVENT Event,
+ VOID *Context
+);
+
+EFI_STATUS
+GetRuntimeRegion (
+ EFI_PHYSICAL_ADDRESS *Start,
+ EFI_PHYSICAL_ADDRESS *End
+);
+
+EFI_STATUS Dummy1(USB_MASS_DEV* Device);
+EFI_STATUS Dummy2(VOID);
+
+VOID ReportDevices(CONNECTED_USB_DEVICES_NUM*);
+UINT8 GetNextMassDeviceName(UINT8*, UINT8, UINT8);
+VOID UsbChangeEfiToLegacy (UINT8);
+VOID* AllocAlignedMemory(UINT32, UINT16);
+VOID USBGenerateSWSMI (UINT8);
+VOID UsbPrepareForLegacyOS();
+EFI_STATUS UpdateHcPciInfo();
+EFI_STATUS OemGetAssignUsbBootPort (UINT8*, UINT8*);
+VOID UsbGetSkipList(USB_SKIP_LIST*, UINT8); //(EIP51653+)
+VOID FreeMemory(UINT32);
+VOID InvokeUsbApi(URP_STRUC*);
+
+
+// USB HC binding protocol functions
+EFI_STATUS
+UsbHcSupported (
+ EFI_DRIVER_BINDING_PROTOCOL *pThis,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+);
+
+EFI_STATUS
+InstallHcProtocols(
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN HC_STRUC *HcData
+);
+
+EFI_STATUS
+UsbHcStop (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children
+);
+
+EFI_STATUS
+AmiUsb2HcGetState(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ OUT EFI_USB_HC_STATE *State);
+
+EFI_STATUS
+AmiUsb2HcSetState(
+ IN EFI_USB2_HC_PROTOCOL *This,
+ IN EFI_USB_HC_STATE State);
+
+EFI_STATUS EFIAPI
+AmiUsb2HcSyncInterruptTransfer(
+ IN EFI_USB2_HC_PROTOCOL *hc_protocol,
+ IN UINT8 deviceaddress,
+ IN UINT8 endpointaddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN maximumpacketlength,
+ IN OUT VOID *data,
+ IN OUT UINTN *datalength,
+ IN OUT UINT8 *datatoggle,
+ IN UINTN timeout,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *transferresult );
+
+EFI_STATUS EFIAPI AmiUsb2HcControlTransfer(
+ IN EFI_USB2_HC_PROTOCOL *hc_protocol,
+ IN UINT8 deviceaddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN maximumpacketlength,
+ IN EFI_USB_DEVICE_REQUEST *request,
+ IN EFI_USB_DATA_DIRECTION transferdirection,
+ IN OUT VOID *data ,
+ IN OUT UINTN *datalength,
+ IN UINTN timeout,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *transferresult );
+
+EFI_STATUS EFIAPI AmiUsb2HcBulkTransfer(
+ IN EFI_USB2_HC_PROTOCOL *hc_protocol,
+ IN UINT8 deviceaddress,
+ IN UINT8 endpointaddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN maximumpacketlength,
+ IN UINT8 DataBuffersNumber,
+ IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
+ IN OUT UINTN *datalength,
+ IN OUT UINT8 *datatoggle,
+ IN UINTN timeout,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ OUT UINT32 *transferresult );
+
+EFI_STATUS EFIAPI AmiUsb2HcAsyncInterruptTransfer(
+ IN EFI_USB2_HC_PROTOCOL *hc_protocol,
+ IN UINT8 deviceaddress,
+ IN UINT8 endpointaddress,
+ IN UINT8 DeviceSpeed,
+ IN UINTN maxpacket,
+ IN BOOLEAN isnewtransfer,
+ IN OUT UINT8 *datatoggle,
+ IN UINTN pollinginterval ,
+ IN UINTN datalength,
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK callbackfunction ,
+ IN VOID *context);
+
+EFI_STATUS
+AmiUsbBlkIoReset (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN BOOLEAN ExtendedVerification
+);
+
+EFI_STATUS
+AmiUsbBlkIoFlushBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This
+);
+
+EFI_STATUS
+AmiUsbBlkIoReadBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ OUT VOID *Buffer
+);
+
+EFI_STATUS
+AmiUsbBlkIoWriteBlocks (
+ IN EFI_BLOCK_IO_PROTOCOL *This,
+ IN UINT32 MediaId,
+ IN EFI_LBA LBA,
+ IN UINTN BufferSize,
+ IN VOID *Buffer
+);
+
+VOID
+ReportDevices(
+ IN OUT CONNECTED_USB_DEVICES_NUM *devs
+);
+
+EFI_STATUS UpdateMassDevicesForSetup();
+
+UINT32 CalculateMemorySize(VOID);
+
+VOID OnExitBootServices(EFI_EVENT, VOID*);
+EFI_STATUS InitUsbSetupVars (USB_GLOBAL_DATA*, EFI_BOOT_SERVICES*, EFI_RUNTIME_SERVICES*);
+UINT8 UsbSetupGetLegacySupport();
+
+typedef EFI_STATUS (*USB_HC_PREINIT_FUNC) (
+ IN EFI_HANDLE Handle,
+ HC_STRUC *HcStruc
+);
+
+typedef EFI_STATUS (*USB_HC_POSTSTOP_FUNC) (
+ IN EFI_HANDLE Handle,
+ HC_STRUC *HcStruc
+);
+
+typedef struct {
+ UINT64 PCICommand;
+ UINT16 FrameListSize;
+ UINT16 FrameListAlignment;
+ USB_HC_PREINIT_FUNC HcPreInit;
+ USB_HC_POSTSTOP_FUNC HcPostStop;
+} HCSPECIFICINFO;
+
+enum {
+ opHC_Start,
+ opHC_Stop,
+ opHC_EnumeratePorts,
+ opHC_DisableInterrupts,
+ opHC_EnableInterrupts,
+ opHC_ProcessInterrupt,
+ opHC_GetRootHubStatus,
+ opHC_DisableRootHub,
+ opHC_EnableRootHub,
+ opHC_ControlTransfer,
+ opHC_BulkTransfer,
+ opHC_InterruptTransfer,
+ opHC_DeactivatePolling,
+ opHC_ActivatePolling,
+ opHC_DisableKeyRepeat,
+ opHC_EnableKeyRepeat,
+ opHC_EnableEndpoints,
+ opHC_InitDeviceData,
+ opHC_DeinitDeviceData,
+ opHC_ResetRootHub,
+ opHC_ClearEndpointState,
+ opHC_GlobalSuspend,
+};
+
+EFI_STATUS DummyHcFunc(EFI_HANDLE, HC_STRUC*);
+EFI_STATUS PreInitXhci(EFI_HANDLE, HC_STRUC*);
+EFI_STATUS PostStopXhci(EFI_HANDLE, HC_STRUC*);
+EFI_STATUS Usb3OemGetMaxDeviceSlots(UINT8*);
+VOID *AllocateHcMemory (IN EFI_PCI_IO_PROTOCOL*, UINTN, UINTN);
+VOID FreeHcMemory(IN EFI_PCI_IO_PROTOCOL*, IN UINTN, IN VOID*);
+EFI_STATUS ReallocateMemory(UINTN, UINTN, VOID**);
+VOID UsbSmiPeriodicEvent(VOID);
+VOID UhcdPciIoNotifyCallback (EFI_EVENT, VOID*);
+VOID UhcdPciIrqPgmNotifyCallback (EFI_EVENT, VOID*);
+UINTN UsbSmiHc(UINT8,UINT8, ...);
+EFI_STATUS USBPort_InstallEventHandler(HC_STRUC*);
+VOID Emul6064NotifyCallback(EFI_EVENT, VOID*);
+EFI_STATUS USBPort_XhciCapabilityOverride( USB3_HOST_CONTROLLER *Usb3Hc);
+VOID UsbRtShutDownLegacy(VOID); //<(EIP52339+)
+VOID UsbRtStopController(UINT16); //(EIP74876+)
+VOID UsbHcOnTimer(EFI_EVENT, VOID*);
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/uhcd.mak b/Core/EM/usb/uhcd.mak
new file mode 100644
index 0000000..4ab67cc
--- /dev/null
+++ b/Core/EM/usb/uhcd.mak
@@ -0,0 +1,128 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Modules/USB/ALASKA/uhcd.mak 12 3/19/13 4:02a Ryanchou $
+#
+# $Revision: 12 $
+#
+# $Date: 3/19/13 4:02a $
+#
+#****************************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Modules/USB/ALASKA/uhcd.mak $
+#
+# 12 3/19/13 4:02a Ryanchou
+# [TAG] EIP118177
+# [Category] Improvement
+# [Description] Dynamically allocate HCStrucTable at runtime.
+# [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+# syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+# usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+# efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+# usbmisc.c, usbsrc.sdl
+#
+# 11 10/25/11 8:26a Wilsonlee
+# [TAG] EIP71750
+# [Category] New Feature
+# [Description] Support extraUSB device driver hook by elink.
+# [Files] usb.c, uhcd.c, uhcd.mak, usbrt.mak, usb.sdl
+#
+# 10 5/16/08 12:03p Olegi
+# Compliance with AMI coding standard.
+#
+#****************************************************************************
+
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: UHCD.MAK
+#
+# Description: Make file for the UHCD component
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : UHCD
+
+UHCD : $(BUILD_DIR)\uhcd.mak UhcdElinkList UHCDBin
+
+UHCD_EXT_HEADERS=\
+ $(UHCD_DIR)\RT\usbdef.h\
+ $(UHCD_DIR)\RT\amidef.h\
+ $(UHCD_DIR)\RT\amiusb.h\
+ $(UHCD_DIR)\uhcd.h\
+ $(BUILD_DIR)\UsbDevDriverElinks.h
+
+$(BUILD_DIR)\uhcd.mak : $(UHCD_DIR)\$(@B).cif $(UHCD_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(UHCD_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+UhcdElinkList:
+ $(ECHO) #define USB_DEV_EFI_DRIVER $(USB_DEV_EFI_DRIVER_LIST) > $(BUILD_DIR)\UsbDevDriverElinks.h
+
+$(BUILD_DIR)\debug.obj : $(USBRT_DIR)\debug.c $(BUILD_DIR)\token.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(USBRT_DIR)\debug.c /I$(UHCD_DIR) /I$(USBRT_DIR)
+
+$(BUILD_DIR)\guids.obj : $(USBRT_DIR)\guids.c
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(USBRT_DIR)\guids.c /I$(UHCD_DIR) /I$(USBRT_DIR)
+
+$(BUILD_DIR)\usbport.obj : $(USBPORTING_DIR)\usbport.c
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(USBPORTING_DIR)\usbport.c /I$(UHCD_DIR) /I$(USBRT_DIR)
+
+$(BUILD_DIR)\uhcd.lib : $(BUILD_DIR)\debug.obj $(BUILD_DIR)\guids.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\uhcd.mak all\
+ "CFLAGS=$(CFLAGS) /I$(USBRT_DIR)"\
+ TYPE=LIBRARY LIBRARY_NAME=$(BUILD_DIR)\uhcd.lib
+
+UHCDBin : $(AMIDXELIB) $(BUILD_DIR)\uhcd.lib $(BUILD_DIR)\usbport.obj
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\uhcd.mak all\
+ GUID=580DD900-385D-11d7-883A-00500473D4EB \
+ ENTRY_POINT=AmiUsbDriverEntryPoint \
+ "CFLAGS=$(CFLAGS) /I$(USBRT_DIR)"\
+ DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX \
+ "EXT_HEADERS=$(UHCD_EXT_HEADERS)"\
+ TYPE=BS_DRIVER \
+ COMPRESS=1\
+ DEPEX1=$(UHCD_DIR)\uhcd.dxs \
+
+#---------------------------------------------------------------------------
+# Create SB Setup Screens
+#---------------------------------------------------------------------------
+SetupSdbs : $(BUILD_DIR)\usb.sdb
+SetupBin : $(BUILD_DIR)\USBSetup.obj
+
+$(BUILD_DIR)\usb.sdb : $(USB_SETUP_DIR)\usb.sd $(USB_SETUP_DIR)\usb.uni
+ $(STRGATHER) -i INCLUDE -parse -newdb -db $(BUILD_DIR)\usb.sdb $(USB_SETUP_DIR)\usb.uni
+ $(STRGATHER) -scan -db $(BUILD_DIR)\usb.sdb -od $(BUILD_DIR)\usb.sdb $(USB_SETUP_DIR)\usb.sd
+
+$(BUILD_DIR)\USBSetup.obj : $(USB_SETUP_DIR)\USBSetup.c $(BUILD_DIR)\SetupStrTokens.h
+ $(CC) $(CFLAGS) /Fo$(BUILD_DIR)\ $(USB_SETUP_DIR)\USBSetup.c
+#---------------------------------------------------------------------------
+
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2008, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/usb/usbbus.c b/Core/EM/usb/usbbus.c
new file mode 100644
index 0000000..12002bd
--- /dev/null
+++ b/Core/EM/usb/usbbus.c
@@ -0,0 +1,3118 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/usbbus.c 101 11/04/15 9:52p Wilsonlee $
+//
+// $Revision: 101 $
+//
+// $Date: 11/04/15 9:52p $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/usbbus.c $
+//
+// 101 11/04/15 9:52p Wilsonlee
+// TAG] EIP241067
+// [Category] Improvement
+// [Description] Add the device descriptor to the DEV_INFO structure.
+// [Files] usb.c, usbdef.h, xhci.c, usbbus.c, AmiUsbController.h
+//
+// 100 5/28/15 5:01a Wilsonlee
+// [TAG] EIP218997
+// [Category] Improvement
+// [Description] Break the GetQueue loop if UninstallDevice is failed.
+// [Files] usbbus.c, efiusbkb.c, efiusbmass.c, efiusbms.c,
+// efiusbpoint.c, efiusbhid.c
+//
+// 99 5/26/15 10:49p Wilsonlee
+// [TAG] EIP219177
+// [Category] Improvement
+// [Description] Fixed static code analysis issues in Usb module.
+// [Files] UsbInt13.c, ehci.c, usbbus.c
+//
+// 98 4/29/15 11:29p Wilsonlee
+// [TAG] EIP215031
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Transcend USB 3.0 HDD is disappeared in the setup menu by
+// cold boot.
+// [RootCause] We only can get SerialNumber string descriptor before
+// setting configuration for this device, otherwise it is failed at
+// getting this descriptor and inquiry command is also failed.
+// [Solution] Retry inquiry command.
+// [Files] usb.c, usbmass.c, efiusbmass.c, usbbus.c, usbdef.h
+//
+// 97 3/20/15 7:19a Wilsonlee
+// [TAG] EIP209904
+// [Category] Improvement
+// [Description] Remove "ASSERT(HubNode != NULL);" because it will be to
+// see a DEV_INFO from not-yet-installed hub in the some cases.
+// [Files] usbbus.c
+//
+// 96 11/23/14 9:11p Wilsonlee
+// [TAG] EIP188119
+// [Category] Improvement
+// [Description] Disconnect devices and uninstall usb device related
+// protocols if we call stop api for the host controllers.
+// [Files] usbkbd.c, usbbus.c, uhcd.h, uhcd.c
+//
+// 95 10/23/14 10:07p Wilsonlee
+// [TAG] EIP183572
+// [Category] Improvement
+// [Description] Change tpl of UsbHcOnTimer to EFI_TPL_CALLBACK
+// [Files] efiusbmass.c, usbbus.c
+//
+// 94 9/30/14 2:07a Wilsonlee
+// [TAG] EIP183572
+// [Category] Improvement
+// [Description] Change tpl of UsbHcOnTimer to EFI_TPL_CALLBACK
+// [Files] efiusbmass.c, usbbus.c
+//
+// 93 9/29/14 11:37p Wilsonlee
+// [TAG] EIP181169
+// [Category] Improvement
+// [Description] Support XHCI 1.1/USB 3.1.
+// [Files] xhci.c, xhci.h, usb.c, usbbus.c, usbdef.h, UsbHc.h
+//
+// 92 9/04/14 7:27a Wilsonlee
+// [TAG] EIP179794
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Unplug RTKUSB LAN on BSU cause system hang up.
+// [RootCause] We return the wrong status for UsbIoTransfers if the
+// device is not present.
+// [Solution] Return EFI_DEVICE_ERROR if the device is not present.
+// [Files] usbbus.c
+//
+// 91 8/20/14 10:03p Wilsonlee
+// [TAG] EIP180089
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] After updated to AMI_USB_07, we get EHCI TIMEOUT for
+// specific mouse.
+// [RootCause] This device may not respond getting string descriptors
+// which describing manufacturer, product and the device's serial number.
+// [Solution] Set the timeout value to 100 ms, the original is 20 secs.
+// [Files] usbbus.c, usbdef.h
+//
+// 90 7/30/14 5:16a Wilsonlee
+// [TAG] EIP176293
+// [Category] Improvement
+// [Description] The changes are for DisplayLink USB Network driver.
+// [Files] usbbus.c, usb.c
+//
+// 89 7/06/14 11:02p Wilsonlee
+// [TAG] EIP176289
+// [Category] Improvement
+// [Description] The device path for multiple LUN devices is created
+// using MSG_DEVICE_LOGICAL_UNIT_DP node.
+// [Files] usbbus.c
+//
+// 88 6/26/14 1:18a Wilsonlee
+// [TAG] EIP173387
+// [Category] Improvement
+// [Description] Remove TODO comments.
+// [Files] usbsetup.c, xhci.c, usbmass.c, usbCCID.c, usb.c, uhci.c,
+// syskbc.c, usbport.c, usbbus.c, uhcd.c, UsbBotPeim.c, PeiXhci.c,
+// PeiEhci.c
+//
+// 87 4/30/14 5:27a Wilsonlee
+// [TAG] EIP164842
+// [Category] Improvement
+// [Description] Check if the devices have put into to our queue before
+// we put them.
+// [Files] UsbInt13.c, amiusb.c, ehci.c, ohci.c, usb.c, usbdef.h,
+// usbmass.c, xhci.c, amiusbhc.c, efiusbmass.c, uhcd.c, usbbus.c, usbsb.c
+//
+// 86 4/29/14 8:37p Wilsonlee
+// [TAG] EIP165318
+// [Category] Improvement
+// [Description] Retry the DisconnectController() from a timer event
+// until it succeeds if it fails.
+// [Files] usbbus.c
+//
+// 85 4/03/14 4:40a Wilsonlee
+// [TAG] EIP158119
+// [Category] Improvement
+// [Description] Change parent port number of USB device paths to
+// 0-based.
+// [Files] usbbus.c
+//
+// 84 12/20/13 3:42a Wilsonlee
+// [TAG] EIP147402
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System hang at 0xA2 if plugging Seagate USB device.
+// [RootCause] This device doesn't respond get descriptor command after
+// we install mass storage driver.
+// [Solution] We store the string descriptor when we load the langid
+// table.
+// [Files] usbbus.c, usbbus.h
+//
+// 83 11/04/13 2:58a Wilsonlee
+// [TAG] EIP135009
+// [Category] Improvement
+// [Description] Retry 3 times when devices stall the get descriptor
+// command.
+// [Files] usbbus.c
+//
+// 82 9/04/13 5:47a Wilsonlee
+// [TAG] EIP134478
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] The devices which behind the hub don't install successfully
+// in shell.
+// [RootCause] Find the wrong root hub port.
+// [Solution] Check DEV_INFO_VALID_STRUC and DEV_INFO_DEV_PRESENT flag
+// to find the root hub port.
+// [Files] usb.c, xhci.c, usbbus.c
+//
+// 81 8/16/13 4:19a Ryanchou
+//
+// 80 7/30/13 2:31a Roberthsu
+// [TAG] EIP126741
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Cannot boot to uefi usb device with Sophos software.
+// [RootCause] When boot into tool. Ownership to os event occur.Usb
+// will disconnect device.And record this disconnect event. Then ownership
+// to bios,bios will connect all device.Run legacy to efi function. Bios
+// run disconnect event first.Then reconnect device.Because usb key behind
+// hub. So usb key disconnect also.
+// [Solution] Check device when device reconnect.If device and port
+// number the same.Use the same device info.
+// [Files] usb.c,usbmass.c,efiusbmass.c,uhcd.c,usbbus.c
+//
+// 79 4/14/13 11:01p Wilsonlee
+// [TAG] EIP120345
+// [Category] Improvement
+// [Description] EFI_USB_IO_PROTOCOL.UsbGetStringDescriptor() returns
+// EFI_SUCCESS if String is NULL.
+// [Files] usbbus.c
+//
+// 78 1/23/13 4:38a Wilsonlee
+// [TAG] EIP109538
+// [Category] Improvement
+// [Description] Fix the code check error result.
+// [Files] usbkbd.c, usbCCID.c, usbbus.c, efiusbccid.c
+//
+// 77 1/22/13 2:39a Wilsonlee
+// [TAG] EIP110305
+// [Category] Improvement
+// [Description] Set the device address after we send the first
+// get-device-descriptor command.
+// [Files] usbmass.c, usb.c, usbdef.h, usbbus.c, efiusbmass.c, uhcd.c,
+// usbport.c
+//
+// 76 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 75 1/07/13 12:57a Wilsonlee
+// [TAG] EIP111305
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] It is failed at reloading the usb keyboard driver.
+// [RootCause] The DEV_INFO_VALID_STRUC and DEV_INFO_DEV_PRESENT flag
+// were cleared when the usb driver is disconnecting.
+// [Solution] We should not clear the DEV_INFO_VALID_STRUC and
+// DEV_INFO_DEV_PRESENT flag at USBKBDDisconnectDevice.
+// [Files] usbkbd.c, usbbus.c
+//
+// 74 11/10/12 6:41a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 73 11/09/12 12:25a Wilsonlee
+// [TAG] EIP104910
+// [Category] Improvement
+// [Description] Raise the tpl to TPL_CALLBACK when we connect or
+// disconnect controller for the usb device.
+// [Files] usbbus.c
+//
+// 72 9/12/12 3:49a Wilsonlee
+// [TAG] EIP100371
+// [Category] Improvement
+// [Description] Set the tpl to TPL_APPLICATION when we connect or
+// disconnect controller for the usb device.
+// [Files] usbbus.c
+//
+// 71 9/04/12 6:15a Ryanchou
+// [TAG] EIP99123
+// [Category] Improvement
+// [Description] Roll back EIP79221 changes that has device
+// compatibility issue.
+// [Files] usbbus.c, usbbus.h
+//
+// 70 8/29/12 10:03p Wilsonlee
+// [TAG] EIP97609
+// [Category] Improvement
+// [Description] Handle the set interface request in the
+// UsbIoControlTransfer.
+// [Files] usbbus.c
+//
+// 69 6/01/12 5:44a Ryanchou
+// [TAG] EIP90535
+// [Category] Improvement
+// [Description] Increase the buffer size in the function
+// GetUsbDescriptor.
+// [Files] usbbus.c
+//
+// 68 5/04/12 6:43a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 67 5/04/12 5:33a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 66 4/05/12 7:34a Wilsonlee
+// [TAG] EIP84215
+// [Category] Improvement
+// [Description] Update the DataSync in LUN0 DevInfo if it is a
+// multi-lun device.
+// [Files] usbbus.c
+//
+// 65 2/16/12 8:54p Wilsonlee
+// [TAG] EIP81612
+// [Category] Spec Update
+// [Severity] Minor
+// [Description] Add EFI_USB_SPEED_SUPER in EFI_USB2_HC_PROTOCOL
+// according to UEFI 2.3.1 spec
+// [Files] usb.c, usbbus.c, amiusbhc.c
+//
+// 64 1/31/12 12:34a Roberthsu
+// [TAG] EIP79221
+// [Category] Improvement
+// [Description] Add get serial number and product string descriptor.
+// [Files] usbbus.c,usbbus.h
+//
+// 63 1/13/12 4:26a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 62 1/06/12 1:02a Rajeshms
+// [TAG] EIP62737
+// [Category] Improvement
+// [Description] Added USB Device number into USB mass device name
+// string based on SDL Token.
+// [Files] Usb.sdl, usbport.c, usbmass.c, UsbInt13.h, UsbInt13.c,
+// usbbus.c, Bfiusb.equ
+//
+// 61 12/14/11 2:09a Ryanchou
+// [TAG] EIP76397
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] ASSERT occurred when executing "reconnect -r" under shell
+// [RootCause] The EIP63188 changes locate all USB controllers at one
+// time, the "reconnect -r" will connect ConIn and ConOut first, so USB
+// driver only locate a controller.
+// [Solution] Rollback the EIP63188 changes to avoid this issue.
+// [Files] amiusbhc.c, efiusbhid.c, efiusbkb.c, uhcd.c, uhcd.h,
+// usbbus.c usbhid.c
+//
+// 60 8/05/11 7:31a Ryanchou
+// [TAG] EIP66231
+// [Category] Improvement
+// [Description] Remove token POINT_SUPPORT.Add token USB_DEV_POINT.Add
+// check core version in point driver.Add check device descriptor to send
+// get lang id command.Modify check button usage page.
+// [Files] efiusbhid.c, efiusbpoint.c, usbbus.c, usbhid.c, usbpoint.c,
+// usbsrc.sdl
+//
+// 59 7/13/11 4:10a Ryanchou
+// [TAG] EIP59332
+// [Category] Improvement
+// [Description] Modified the Stop function for UHCD and USBBUS to
+// properly stop devices and uninstall the protocols.
+// [Files] uhcd.c, uhcd.h, uhci.c, usbbus.c, UsbInt13.c, usbmisc.c
+//
+// 58 6/23/11 6:49a Ryanchou
+// [TAG] EIP61644
+// [Category] Improvement
+// [Description] Uninstall USB bus driver only DEV_INFO_DEV_BUS is set.
+// [Files] usbbus.c
+//
+// 57 6/22/11 9:38a Ryanchou
+// [TAG] EIP60640
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Logitec USB keyboard has no function in DOS.
+// [RootCause] The USB keybaord may stall get configuration descriptor
+// request or set address request.
+// [Solution] Retry five times when the device stalls these request.
+// [Files] usb.c, usbbus.c
+//
+// 56 6/21/11 11:57p Ryanchou
+// [TAG] EIP60745
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] USB driver doesn't pass SCT 2.3 ComponentName2 protocol
+// test
+// [RootCause] USB driver fails to pass SCT 2.3 ComponentName2 protocol
+// test - function GetControllerName conformance test, because there is no
+// checking if passed handle is valid or not, or even NULL
+// [Solution] Check the handle is valid in GetControllerName function.
+// [Files] uhcd.c, usbbus.c
+//
+// 55 5/03/11 10:45a Ryanchou
+// [TAG] EIP59272
+// [Category] Improvement
+// [Description] According Uefi 2.1 Aptio porting document, changes made
+// to install the component name protocol.
+// [Files] componentname.c, componentname.h, efiusbkb.c, efiusbmass.c,
+// efiusbms.c, uhcd.c, uhcd.h, usbbus.c
+//
+// 54 3/30/11 8:25a Ryanchou
+// [TAG] EIP54126
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Sometimes system hangs at checkpoint 0xB4.
+// [RootCause] The bLength field of configuration descriptor is zero.
+// [Solution] Check wether bLength field is zero before paring next
+// descriptor.
+// [Files] usb.c, usbbus.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c
+//
+// 53 3/16/11 5:34p Anandakrishnanl
+// [TAG] EIP56121
+// [Category] Defect
+// [Description] GetSupportedLanguages() returns invalid return status
+// [Files] usbbus.c
+//
+// 52 3/04/11 1:29p Olegi
+//
+// 51 3/04/11 1:25p Olegi
+// [TAG] EIP55172
+// [Category] Spec Update
+// [Severity] Important
+// [Description] Install EFI_COMPONENT_NAME_PROTOCOL if BIOS is in UEFI
+// 2.0 mode and EFI_COMPONENT_NAME2_PROTOCOL if BIOS is in UEFI 2.1 mode.
+// [Files] uhcd.c
+// usbbus.c
+// efiusbkb.c
+// efiusbmass.c
+// efiusbms.c
+// componentname.c
+// componentname.h
+//
+// 50 1/06/11 11:28a Olegi
+// [TAG] EIP51191
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] USB mass storage device name is different for UEFI and
+// Legacy device
+// [RootCause] The change in InstallDevice done for 47749; it uninstalls
+// UsbIo for a current device if ConnectController is unsuccessful.
+// ConnectController could be unsecsessful for a number of legitemate
+// reasons, one of them is the driver for this device is not present in
+// the project (which is the case for a USB hub).
+// [Solution] Removed UsbIo uninstallation in case of ConnectController
+// failure.
+// [Files] USBBUS.C
+//
+// 49 11/08/10 10:03a Olegi
+// [TAG] EIP47749
+// [Category] Improvement
+// [Description] Intermittently with Certain USB devices at PC B4h
+// [Files] usbbus.c
+//
+// 48 10/19/10 4:22p Krishnakumarg
+//
+// [TAG] EIP45589
+// [Category] DEFECT
+// [Severity] MAJOR
+// [Symptom] USB3.0 controller did not show boot option when only one
+// USB device connected.
+// [RootCause] USB Bus polling time was high(one second).
+// [Solution] Reduce the usb bus polling time(100ms)
+// [Files] usbbus.c
+//
+// 47 8/18/10 4:21p Olegi
+// Klockwork related fixes; EIP37978
+//
+// 46 6/17/10 10:35a Olegi
+// EIP39326: Runtime data moved to runtime memory region.
+//
+// 45 3/15/10 12:14p Olegi
+// UsbBusStart: Raise the tpl level more then EFI_TPL_CALLBACK to make it
+// can be called in other callback function.EIP35956
+//
+// 44 2/27/10 12:00p Olegi
+//
+// 43 2/08/10 10:06a Olegi
+// EIP33381: Implement multiple bulk endpoint in UsbIoProtocol.
+//
+// 42 10/30/09 5:48p Olegi
+//
+// 41 9/24/09 1:32p Olegi
+// EIP27593: Fix in UsbIoGetStringDescriptor.
+//
+// 40 8/18/09 11:53a Olegi
+//
+// 39 12/16/08 10:51a Olegi
+// Correction in the return values: 0 changed to NULL. EIP#17767.
+//
+// 38 10/22/08 4:25p Olegi
+// QueueData1 declaration and initialization is moved to UHCD.C
+//
+// 37 9/05/08 4:17p Olegi
+// gQueueCnnctDisc is made a part of global data structure.
+//
+// 36 9/02/08 10:35a Olegi
+// Bugfix in UsbIoBulkTransfer.
+//
+// 35 6/27/08 5:57p Olegi
+// - Coding standard related modifications
+// - LoadName function modified to return USB mass storage device name
+// from the INQUIRY command
+//
+// 34 6/19/08 5:01p Olegi
+//
+// 33 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 21 10/26/06 3:58p Olegi
+// EFI_USB2_HC_PROTOCOL implementatin.
+//
+// 17 5/31/06 6:56p Mirk
+// Core 4.5 compliant - DP Length manipulation changes.
+//
+// 15 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 12 11/03/05 6:32p Andriyn
+// LUN support
+//
+// 9 6/15/05 1:59p Andriyn
+// Comments were changed
+//****************************************************************************
+//<AMI_FHDR_START>
+//
+// Name: UsbBus.c
+//
+// Description: USB Bus driver implementation
+//
+//<AMI_FHDR_END>
+//****************************************************************************
+
+//#include "Efi.h"
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+
+#include "usbdef.h"
+#include "usbbus.h"
+#include "componentname.h"
+
+//#pragma warning(disable: 4244)
+
+extern EFI_GUID gEfiUsb2HcProtocolGuid;
+
+EFI_DRIVER_BINDING_PROTOCOL gUSBBusDriverBinding = {
+ UsbBusSupported,
+ UsbBusStart,
+ UsbBusStop,
+ USB_DRIVER_VERSION,
+ NULL,
+ NULL
+};
+
+extern USB_GLOBAL_DATA* gUsbData;
+
+TREENODE_T UsbRootRoot = {0,};
+TREENODE_T* gUsbRootRoot = &UsbRootRoot;
+EFI_EVENT gEvUsbEnumTimer=0;
+int gCounterUsbEnumTimer=0;
+int gBustreeLock = 0;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIo2Dev
+//
+// Description: This function returns a pointer to USB device from UsbIo.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+USBDEV_T* UsbIo2Dev(EFI_USB_IO_PROTOCOL* UsbIo)
+{
+ return (USBDEV_T*)((char*)UsbIo - (UINTN)&((USBDEV_T*)0)->io );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: HcByIndex
+//
+// Description: Predicate for searching host controller node in the tree
+// by bHcNumber
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int HcByIndex(VOID* n, VOID* d)
+{
+ USBBUS_HC_T* HcNode = (USBBUS_HC_T*)n;
+
+ return n && (HcNode->type == NodeHC)
+ && (HcNode->hc_data->bHCNumber == *(UINT8*)d );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: HcByHandle
+//
+// Description: Predicate for searching host controller node in the tree
+// by EFI controller handle
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int HcByHandle(VOID* n, VOID* d)
+{
+ USBBUS_HC_T* HcNode = (USBBUS_HC_T*)n;
+ return (HcNode->type == NodeHC) && (HcNode->hc_data->Controller == *(EFI_HANDLE*)d );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DevByIndex
+//
+// Description: Predicate for searching device node in the tree
+// by index of the DEV_INFO structure in the aDevInfoTable
+// array of USB data
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int DevByIndex(VOID* n, VOID* d)
+{
+ USBDEV_T* Dev = (USBDEV_T*)n;
+ return (Dev->type == NodeDevice) && (Dev->dev_info ==
+ gUsbData->aDevInfoTable + *(UINT8*)d );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DevGrpByAddr
+//
+// Description: Predicate for searching device node in the tree
+// by USB address of the device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int DevGrpByAddr(VOID* n, VOID* d)
+{
+ USBDEV_T* Dev = (USBDEV_T*)n;
+ return (Dev->type == NodeDevice || Dev->type == NodeGroup) &&
+ (Dev->dev_info->bDeviceAddress == *(UINT8*)d );
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DevGrpByPortIf
+//
+// Description: Predicate for searching device node in the tree
+// by parent hub port of the device, interface and LUN
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int DevGrpByPortIf(VOID* n, VOID* d)
+{
+ USBDEV_T* Dev = (USBDEV_T*)n;
+ return (Dev->type == NodeDevice || Dev->type == NodeGroup) &&
+ (Dev->dev_info->bHubPortNumber == ((DEV_INFO*)d)->bHubPortNumber ) &&
+ (Dev->dev_info->bInterfaceNum == ((DEV_INFO*)d)->bInterfaceNum ) &&
+ (Dev->dev_info->bLUN == ((DEV_INFO*)d)->bLUN );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DevByInfo
+//
+// Description: Predicate for searching device node in the tree
+// by comparing pointers to the DEV_INFO structure
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int DevByInfo(VOID* n, VOID* d )
+{
+ USBDEV_T* Dev = (USBDEV_T*)n;
+ return (Dev->type == NodeDevice) && (Dev->dev_info == (DEV_INFO*)d );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DevByAdrIf
+//
+// Description: Predicate for searching device node in the tree
+// by USB address and interface number of the device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int DevByAdrIf(VOID* n, VOID* d)
+{
+ USBDEV_T* Dev = (USBDEV_T*)n;
+
+ return ((Dev->type == NodeDevice) &&
+ (Dev->dev_info->bDeviceAddress == ((DEV_INFO*)d)->bDeviceAddress ) &&
+ (Dev->dev_info->bInterfaceNum == ((DEV_INFO*)d)->bInterfaceNum )&&
+ (Dev->dev_info->bLUN == ((DEV_INFO*)d)->bLUN));
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbDevGetGroup
+//
+// Description: Retrieve DEVGROUP_T that is parent of
+// the specified USB device in the USB Bus tree
+//
+// Input: Device for which the parent is requested
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+DEVGROUP_T* UsbDevGetGroup(USBDEV_T* Dev)
+{
+ return (DEVGROUP_T*)Dev->node.parent->data;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DpAddUsbSegment
+//
+// Description: Builds a new path appending a USB segment
+//
+// Output: Pointer to a callee allocated memory buffer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_DEVICE_PATH_PROTOCOL*
+DpAddUsbSegment(
+ EFI_DEVICE_PATH_PROTOCOL* Dp,
+ UINT8 bHubPortNumber,
+ UINT8 bInterfaceNum
+)
+{
+ USB_DEVICE_PATH DpNewSegment = {0,};
+ DpNewSegment.Header.Type = MESSAGING_DEVICE_PATH;
+ DpNewSegment.Header.SubType = MSG_USB_DP;
+ SET_NODE_LENGTH(&DpNewSegment.Header, sizeof(DpNewSegment));
+
+ DpNewSegment.InterfaceNumber = bInterfaceNum;
+ DpNewSegment.ParentPortNumber = bHubPortNumber;
+ return EfiAppendDevicePathNode(Dp,(EFI_DEVICE_PATH_PROTOCOL*)&DpNewSegment);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: DpAddLun
+//
+// Description: Builds a new path appending a LUN node
+//
+//
+// Output: Pointer to a callee allocated memory buffer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_DEVICE_PATH_PROTOCOL*
+DpAddLun(
+ EFI_DEVICE_PATH_PROTOCOL* Dp,
+ UINT8 Lun
+)
+{
+ LOGICAL_UNIT_DEVICE_PATH DpNewSegment = {0,};
+
+ DpNewSegment.Header.Type = MESSAGING_DEVICE_PATH;
+ DpNewSegment.Header.SubType = MSG_USB_LOGICAL_UNIT_CLASS_DP;
+ SET_NODE_LENGTH(&DpNewSegment.Header, sizeof(DpNewSegment));
+ DpNewSegment.Lun = Lun;
+ return EfiAppendDevicePathNode(Dp,(EFI_DEVICE_PATH_PROTOCOL*)&DpNewSegment);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ReadUsbDescriptor
+//
+// Description: This function executes a get descriptor command to the
+// given USB device and endpoint
+//
+// Input: dev a pointer to USBDEV_T corresponding to the device
+// fpBuffer Buffer to be used for the transfer
+// wLength Size of the requested descriptor
+// bDescType Requested descriptor type
+// bDescIndex Descriptor index
+// wLangIndex LangIndex
+//
+// Output: Pointer to memory buffer containing the descriptor
+// NULL on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT8*
+ReadUsbDescriptor( USBDEV_T* Dev,
+ UINT8* Buffer,
+ UINT16 Length,
+ UINT8 DescType,
+ UINT8 DescIndex,
+ UINT16 LangIndex )
+{
+ HC_STRUC* HcStruc = Dev->hc_info;
+ DEV_INFO* DevInfo = Dev->dev_info;
+ UINT8 GetDescIteration;
+ UINT16 Reg;
+ UINT16 Status;
+
+ for (GetDescIteration = 0; GetDescIteration < 3; GetDescIteration++) {
+ Reg = (UINT16)((DescType << 8) + DescIndex);
+ Status = UsbSmiControlTransfer(
+ HcStruc,
+ DevInfo,
+ (UINT16)USB_RQ_GET_DESCRIPTOR,
+ (UINT16)LangIndex,
+ Reg,
+ Buffer,
+ Length);
+ if (Status) {
+ return Buffer;
+ }
+ if (gUsbData->dLastCommandStatusExtended & USB_TRNSFR_TIMEOUT) {
+ break;
+ }
+ pBS->Stall(10 * 1000);
+ }
+
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetUsbDescriptor
+//
+// Description: Allocates memory necessary to hold complete descriptor
+// and returns the descriptor there
+//
+// Input: dev a pointer to USBDEV_T corresponding to the device
+// type Requested descriptor type
+// index Descriptor index
+// langindex LangIndex
+//
+// Output: Pointer to memory buffer containing the descriptor
+// NULL on error
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+USB_DESCRIPTOR_T*
+GetUsbDescriptor(
+ USBDEV_T* Dev,
+ UINT8 Type,
+ UINT8 Index,
+ UINT16 LangIndex)
+{
+ UINT8 Buffer[0xFF] = {0};
+ USB_DESCRIPTOR_T *Desc;
+ UINT8* DescBuffer;
+
+ DescBuffer= ReadUsbDescriptor(Dev, Buffer, sizeof(Buffer), Type, Index, LangIndex);
+
+ if ((DescBuffer == NULL) ||
+ (((USB_DESCRIPTOR_T*)Buffer)->DescriptorType != Type) ||
+ (((USB_DESCRIPTOR_T*)Buffer)->Length == 0)) {
+ return NULL;
+ }
+ gBS->AllocatePool(EfiBootServicesData, ((USB_DESCRIPTOR_T*)Buffer)->Length, &Desc);
+
+ EfiCopyMem(Desc, Buffer, ((USB_DESCRIPTOR_T*)Buffer)->Length);
+
+ return Desc;
+
+/*
+ EfiZeroMem(Desc, ((USB_DESCRIPTOR_T*)Buffer)->Length);
+ DescBuffer = ReadUsbDescriptor(Dev, (UINT8*)Desc,
+ ((USB_DESCRIPTOR_T*)Buffer)->Length, Type, Index, LangIndex);
+ //ASSERT(Desc->DescriptorType == Type); //(EIP60640-)
+ if (DescBuffer == NULL){
+ gBS->FreePool(Desc);
+ return NULL;
+ }
+ //
+ //Decriptor Type cannot be 0, this case means that Get Descriptor cmd timed out
+ //
+ if (Desc->DescriptorType == 0) {
+ gBS->FreePool(Desc);
+ return NULL;
+ } else {
+ return Desc;
+ }
+*/
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FreeConfigDesc
+//
+// Description: Delocates memory that was used by the descriptor
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID FreeConfigDesc( VOID* Desc )
+{
+ if (Desc != 0) gBS->FreePool(Desc);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: NextDescriptor
+//
+// Description: Returns pointer to the next descriptor for the pack of
+// USB descriptors located in continues memory segment
+// - result of reading CONFIG_DESCRIPTOR
+// Notes:
+// Uses TotalLength of the CONFIG_DESCRIPTOR and Length
+// field of each USB descriptor found inside the pack
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+int
+NextDescriptor(
+ EFI_USB_CONFIG_DESCRIPTOR* Desc,
+ UINTN* Offset
+)
+{
+ if( Desc == NULL || *Offset >= Desc->TotalLength ) return FALSE;
+ if( ((EFI_USB_CONFIG_DESCRIPTOR*)((char*)Desc+*Offset))->Length == 0) return FALSE;
+ *Offset += ((EFI_USB_CONFIG_DESCRIPTOR*)((char*)Desc+*Offset))->Length;
+ if( *Offset >= Desc->TotalLength ) return FALSE;
+
+ return TRUE;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbDevConfigDesc
+//
+// Description: Returns a pointer to the memory containing CONFIG_DESCRIPTOR
+// reported by the USB device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_USB_CONFIG_DESCRIPTOR*
+DevGroupConfigDesc( DEVGROUP_T* Grp ){
+ return Grp->f_DevDesc && (Grp->active_config != -1)?
+ Grp->configs[Grp->active_config]:NULL;
+}
+
+EFI_USB_CONFIG_DESCRIPTOR*
+UsbDevConfigDesc( USBDEV_T* Dev ){
+ return DevGroupConfigDesc( UsbDevGetGroup(Dev));
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbDevLoadAllDescritors
+//
+// Description: Reads DEVICE and CONFIG descriptors for each
+// configuration available in the device. Marks
+// the index of the buffer containing CONFIG descriptor
+// for active configurations currently selected in
+// USB device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbDevLoadAllDescritors(
+ DEVGROUP_T* Dev
+)
+{
+ UINT8 i;
+ EFI_STATUS Status;
+
+ //ASSERT( Dev->f_DevDesc == 0 );
+ Dev->configs = NULL;
+ //
+ // Device descriptor
+ //
+ gBS->CopyMem((UINT8*)&Dev->dev_desc, (UINT8*)&Dev->dev_info->DevDesc, sizeof(Dev->dev_desc));
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USB Bus: dev descr: ");
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "cls:%x;subcls:%x;proto:%x;vndr:%x;id:%x\n",
+ Dev->dev_desc.DeviceClass,
+ Dev->dev_desc.DeviceSubClass,
+ Dev->dev_desc.DeviceProtocol,
+ Dev->dev_desc.IdVendor,
+ Dev->dev_desc.IdProduct);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "\t\tstr1:%x,str2:%x,str3:%x\n",
+ Dev->dev_desc.StrManufacturer,
+ Dev->dev_desc.StrProduct,
+ Dev->dev_desc.StrSerialNumber );
+
+ Dev->f_DevDesc = TRUE;
+
+ //
+ // Config descriptor
+ //
+ Dev->config_count = Dev->dev_desc.NumConfigurations;
+// dev->configs = (EFI_USB_CONFIG_DESCRIPTOR**)MallocZ(dev->config_count*sizeof(EFI_USB_CONFIG_DESCRIPTOR*));
+ Status = gBS->AllocatePool (EfiBootServicesData,
+ Dev->config_count*sizeof(EFI_USB_CONFIG_DESCRIPTOR*), (VOID *)&Dev->configs);
+ ASSERT_EFI_ERROR(Status);
+ EfiZeroMem(Dev->configs, Dev->config_count*sizeof(EFI_USB_CONFIG_DESCRIPTOR*));
+
+ Dev->active_config = -1;
+ for(i=0; i<Dev->config_count; ++i){
+ //read each configuration
+ //first failed read will terminate loop
+
+ //Optimization: allloc&read MAX size first
+ // and read second time only if total length is greater
+ //Read 1 : get total length
+ EFI_USB_CONFIG_DESCRIPTOR tmp = {0,0,};
+ UINT8* p = ReadUsbDescriptor((USBDEV_T*)Dev,(UINT8*)&tmp,
+ sizeof(tmp),DESC_TYPE_CONFIG,i, 0 );
+ //ASSERT(tmp.DescriptorType == DESC_TYPE_CONFIG);
+ //ASSERT(tmp.TotalLength >= sizeof(tmp));
+ //
+ //Addressing timeouts caused by device errors - empty DESC structure will be returned
+ //
+ if( (p == NULL) || (tmp.DescriptorType == 0) ) {
+ break;
+ }
+
+ //Read 2: Actual content
+// dev->configs[i] = MallocZ(tmp.TotalLength);
+ Status = gBS->AllocatePool (EfiBootServicesData, tmp.TotalLength, &Dev->configs[i]);
+ ASSERT_EFI_ERROR(Status);
+ EfiZeroMem(Dev->configs[i], tmp.TotalLength);
+
+ p = ReadUsbDescriptor((USBDEV_T*)Dev, (UINT8*)Dev->configs[i],
+ tmp.TotalLength, DESC_TYPE_CONFIG, i, 0);
+ //ASSERT(Dev->configs[i]->DescriptorType == DESC_TYPE_CONFIG); //(EIP60640-)
+ //
+ //Addressing timeouts caused by device errors - empty DESC structure will be returned
+ //
+ if( (p == NULL) || (Dev->configs[i]->DescriptorType == 0) ){
+ gBS->FreePool(Dev->configs[i]);
+ Dev->configs[i] = 0;
+ break;
+ }
+ //config Desc is here
+
+ //Active Config
+ if( Dev->configs[i]->ConfigurationValue == Dev->dev_info->bConfigNum ){
+ Dev->active_config = i;
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbDevLoadEndpoints
+//
+// Description: Locates information about each endpoint inside the
+// descriptors pack loaded with CONFIG descriptor
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbDevLoadEndpoints(
+ USBDEV_T* Dev
+)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR *TmpDesc;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EpDesc;
+ EFI_USB_CONFIG_DESCRIPTOR *CfgDesc;
+ int j;
+ UINTN Offset;
+ DEVGROUP_T *Grp = UsbDevGetGroup(Dev);
+
+ Dev->first_endpoint = Grp->endpoint_count;
+ Dev->end_endpoint = Grp->endpoint_count;
+
+ CfgDesc = UsbDevConfigDesc(Dev);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\tScanning config desc: ");
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "%x(type:%x;len:%x;val:%x;total:%x)\n",
+ CfgDesc,CfgDesc->DescriptorType,CfgDesc->Length,
+ CfgDesc->ConfigurationValue,CfgDesc->TotalLength );
+
+ //
+ // Search interface descriptor
+ //
+ for(Offset = 0; NextDescriptor(CfgDesc,&Offset);)
+ {
+ TmpDesc = (EFI_USB_INTERFACE_DESCRIPTOR *)((char*)CfgDesc+Offset);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t\tdesc: %x(type:%x;len:%x;if:%x;aif:%x)\n",
+ TmpDesc,TmpDesc->DescriptorType,TmpDesc->Length,
+ TmpDesc->InterfaceNumber, TmpDesc->AlternateSetting );
+ if( TmpDesc->DescriptorType == DESC_TYPE_INTERFACE &&
+ TmpDesc->InterfaceNumber== Dev->dev_info->bInterfaceNum &&
+ TmpDesc->AlternateSetting == Dev->dev_info->bAltSettingNum)
+ {
+ //found
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t...IF found.\n" );
+
+ Dev->descIF= TmpDesc;
+
+ ASSERT(TmpDesc->NumEndpoints < COUNTOF(Grp->endpoints));
+ for(j=0;j<TmpDesc->NumEndpoints && NextDescriptor(CfgDesc,&Offset);){
+ EpDesc = (EFI_USB_ENDPOINT_DESCRIPTOR*)((char*)CfgDesc+Offset);
+ if( EpDesc->DescriptorType == DESC_TYPE_ENDPOINT ){
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t\tend-point desc: %x", EpDesc);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "(index:%x;type:%x;len:%x;addr:%x;pcksz:%x;attr:%x,t:%x)\n",
+ Grp->endpoint_count,
+ EpDesc->DescriptorType,EpDesc->Length,
+ EpDesc->EndpointAddress, EpDesc->MaxPacketSize,
+ EpDesc->Attributes, EpDesc->Interval);
+ Grp->endpoints[Grp->endpoint_count].address = EpDesc->EndpointAddress;
+ Grp->endpoints[Grp->endpoint_count++].desc = EpDesc;
+ Grp->a2endpoint[COMPRESS_EP_ADR(EpDesc->EndpointAddress)] = EpDesc;
+ j++;
+ }
+ if( EpDesc->DescriptorType == DESC_TYPE_INTERFACE ){
+ //Oops, We stepped into another interface
+ break;
+ }
+ }
+ Dev->end_endpoint = Grp->endpoint_count;
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t\tinterface end-points: ");
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "first:%x; end:%x, grp.endpoint_count:%x\n",
+ Dev->first_endpoint, Dev->end_endpoint, Grp->endpoint_count);
+ return;
+ }
+ }
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t...IF not found.\n" );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetMaxPacket
+//
+// Description: Retrieves information about a max packet size
+// for the specified endpoint of the device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT16
+GetMaxPacket(
+ UINT8 Endpoint,
+ USBDEV_T* Dev
+)
+{
+ DEVGROUP_T *Grp = UsbDevGetGroup(Dev);
+ EFI_USB_ENDPOINT_DESCRIPTOR* Desc = Grp->a2endpoint[COMPRESS_EP_ADR(Endpoint)];
+ if (Desc == 0) return 0;
+ return Desc->MaxPacketSize;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: GetEndpointDesc
+//
+// Description: Retrieves information about a max packet size
+// for the specified endpoint of the device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_USB_ENDPOINT_DESCRIPTOR*
+GetEndpointDesc(
+ UINT8 Endpoint,
+ USBDEV_T* Dev
+)
+{
+ DEVGROUP_T *Grp = UsbDevGetGroup(Dev);
+ EFI_USB_ENDPOINT_DESCRIPTOR* Desc;
+
+ if (((Endpoint & 0x7F)==0) || ((Endpoint & 0x7F) > 0xF))
+ return NULL;
+ Desc = Grp->a2endpoint[COMPRESS_EP_ADR(Endpoint)];
+
+ return Desc;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoControlTransfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoControlTransfer(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN EFI_USB_DEVICE_REQUEST *Request,
+ IN EFI_USB_DATA_DIRECTION Direction,
+ IN UINT32 Timeout,
+ IN OUT VOID *Data,
+ IN UINTN DataLength,
+ OUT UINT32 *UsbStatus
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ EFI_STATUS Status;
+
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+
+ if( Request == NULL || UsbStatus == NULL ) return EFI_INVALID_PARAMETER;
+ if (Direction > EfiUsbNoData) return EFI_INVALID_PARAMETER;
+
+ if (!(Dev->dev_info->Flag & DEV_INFO_DEV_PRESENT)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = Dev->hc->ControlTransfer(
+ Dev->hc, Dev->dev_info->bDeviceAddress, GetSpeed(Dev),
+ (UINTN)Dev->dev_info->wEndp0MaxPacket, //(EIP81612)
+ Request, Direction, Data, &DataLength, Timeout, NULL, UsbStatus);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+ if ((Request->Request == (USB_RQ_SET_INTERFACE >> 8)) &&
+ (Request->RequestType == (USB_RQ_SET_INTERFACE & 0x0F) ) &&
+ (Request->Index == Dev->dev_info->bInterfaceNum)) {
+ Dev->dev_info->bAltSettingNum = (UINT8)Request->Value;
+ UsbDevLoadEndpoints(Dev);
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoBulkTransfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoBulkTransfer(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 Endpoint,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout,
+ OUT UINT32 *UsbStatus
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ UINT16 MaxPacket;
+ UINT8 ToggleBit = (Endpoint & 0xF) - 1;
+ //(EIP84215)>
+ UINT16 *wDataSync;
+ UINT8 Toggle;
+ EFI_STATUS Status;
+ EFI_USB_ENDPOINT_DESCRIPTOR* EpDesc = GetEndpointDesc(Endpoint, Dev);
+ DEV_INFO *DevInfoToDataSync;
+ //<(EIP84215)
+ if (((Endpoint & 0x7F)==0) || ((Endpoint & 0x7F) > 0xF))
+ return EFI_INVALID_PARAMETER;
+
+// if ( Dev->dev_info->bBulkInEndpoint &&
+// ((Endpoint & 0x80) && ((Endpoint & 0x7F) != Dev->dev_info->bBulkInEndpoint)) ) {
+// return EFI_INVALID_PARAMETER;
+// }
+
+// if ( Dev->dev_info->bBulkOutEndpoint &&
+// (!(Endpoint & 0x80) && (Endpoint != Dev->dev_info->bBulkOutEndpoint)) ) {
+// return EFI_INVALID_PARAMETER;
+// }
+
+ if ( Data == NULL || DataLength == NULL || UsbStatus == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if( EpDesc == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+ MaxPacket = EpDesc->MaxPacketSize;
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+
+ if( UsbStatus == NULL || MaxPacket == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( (EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS) != EP_DESC_FLAG_TYPE_BULK ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(Dev->dev_info->Flag & DEV_INFO_DEV_PRESENT)) {
+ return EFI_DEVICE_ERROR;
+ }
+ //(EIP84215+)>
+ if (Dev->dev_info->fpLUN0DevInfoPtr) {
+ DevInfoToDataSync = Dev->dev_info->fpLUN0DevInfoPtr;
+ }else {
+ DevInfoToDataSync = Dev->dev_info;
+ }
+
+ if (Endpoint & 0x80) {
+ wDataSync = &DevInfoToDataSync->wDataInSync;
+ }else {
+ wDataSync = &DevInfoToDataSync->wDataOutSync;
+ }
+ //<(EIP84215+)
+ GETBIT( *wDataSync, Toggle, ToggleBit );
+
+ Status = Dev->hc->BulkTransfer(
+ Dev->hc, Dev->dev_info->bDeviceAddress, Endpoint, GetSpeed(Dev),
+ MaxPacket, 1, &Data, DataLength, &Toggle, Timeout, NULL, UsbStatus);
+
+ SETBIT( *wDataSync, Toggle, ToggleBit );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoIsochronousTransfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoAsyncInterruptTransfer(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 Endpoint,
+ IN BOOLEAN IsNewTransfer,
+ IN UINTN PollingInterval,
+ IN UINTN DataLength,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK InterruptCallback,
+ IN VOID *Context
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ UINT8 Toggle;
+ UINT8 ToggleBit = (Endpoint & 0xF) - 1;
+ //(EIP84215)>
+ UINT16 *wDataSync;
+ EFI_STATUS Status;
+ EFI_USB_ENDPOINT_DESCRIPTOR* EpDesc = GetEndpointDesc(Endpoint, Dev);
+ DEV_INFO *DevInfoToDataSync;
+ //<(EIP84215)
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+
+ // Check whether Endpoint is valid
+ if(EpDesc == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS) != EP_DESC_FLAG_TYPE_INT ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsNewTransfer && (PollingInterval < 1 || PollingInterval > 255)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (IsNewTransfer) {
+ if (!(Dev->dev_info->Flag & DEV_INFO_DEV_PRESENT)) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+ //(EIP84215+)>
+ if (Dev->dev_info->fpLUN0DevInfoPtr) {
+ DevInfoToDataSync = Dev->dev_info->fpLUN0DevInfoPtr;
+ }else {
+ DevInfoToDataSync = Dev->dev_info;
+ }
+
+ if (Endpoint & 0x80) {
+ wDataSync = &DevInfoToDataSync->wDataInSync;
+ }else {
+ wDataSync = &DevInfoToDataSync->wDataOutSync;
+ }
+ //<(EIP84215+)
+ GETBIT( *wDataSync, Toggle, ToggleBit );
+
+ Status = Dev->hc->AsyncInterruptTransfer(
+ Dev->hc, Dev->dev_info->bDeviceAddress, Endpoint,
+ GetSpeed(Dev), EpDesc->MaxPacketSize, IsNewTransfer,
+ &Toggle, PollingInterval, DataLength, NULL,
+ InterruptCallback, Context );
+
+ SETBIT( *wDataSync, Toggle, ToggleBit );
+
+ if (!EFI_ERROR(Status)) {
+ Dev->async_endpoint = IsNewTransfer ? Endpoint : 0;
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoSyncInterruptTransfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoSyncInterruptTransfer(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 Endpoint,
+ IN OUT VOID *Data,
+ IN OUT UINTN *DataLength,
+ IN UINTN Timeout,
+ OUT UINT32 *UsbStatus
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ UINT8 Toggle;
+ UINT8 ToggleBit = (Endpoint & 0xF) - 1;
+ //(EIP84215)>
+ UINT16 *wDataSync;
+ EFI_STATUS Status;
+ EFI_USB_ENDPOINT_DESCRIPTOR* EpDesc = GetEndpointDesc(Endpoint, Dev);
+ DEV_INFO *DevInfoToDataSync;
+ //<(EIP84215)
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+
+ // Check whether Endpoint is valid
+ if( EpDesc == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( (EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS) != EP_DESC_FLAG_TYPE_INT ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ( Data == NULL || DataLength == NULL || UsbStatus == NULL ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(Dev->dev_info->Flag & DEV_INFO_DEV_PRESENT)) {
+ return EFI_DEVICE_ERROR;
+ }
+ //(EIP84215+)>
+ if (Dev->dev_info->fpLUN0DevInfoPtr) {
+ DevInfoToDataSync = Dev->dev_info->fpLUN0DevInfoPtr;
+ }else {
+ DevInfoToDataSync = Dev->dev_info;
+ }
+
+ if (Endpoint & 0x80) {
+ wDataSync = &DevInfoToDataSync->wDataInSync;
+ }else {
+ wDataSync = &DevInfoToDataSync->wDataOutSync;
+ }
+ //<(EIP84215+)
+ GETBIT( *wDataSync, Toggle, ToggleBit );
+ Status = Dev->hc->SyncInterruptTransfer(
+ Dev->hc, Dev->dev_info->bDeviceAddress, Endpoint,
+ GetSpeed(Dev), EpDesc->MaxPacketSize,
+ Data, DataLength, &Toggle, Timeout, NULL, UsbStatus);
+ SETBIT( *wDataSync, Toggle, ToggleBit );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoIsochronousTransfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoIsochronousTransfer(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 Endpoint,
+ IN OUT VOID *Data,
+ IN UINTN DataLength,
+ OUT UINT32 *Status
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ UINT16 MaxPacket;// = GetMaxPacket(Endpoint,dev);
+ EFI_USB_ENDPOINT_DESCRIPTOR* EpDesc = GetEndpointDesc(Endpoint, Dev);
+
+ if (EpDesc == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ MaxPacket = EpDesc->MaxPacketSize;
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+
+ if (Status == NULL || MaxPacket == 0) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if ((EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS) != EP_DESC_FLAG_TYPE_ISOC) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(Dev->dev_info->Flag & DEV_INFO_DEV_PRESENT)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return Dev->hc->IsochronousTransfer(
+ Dev->hc, Dev->dev_info->bDeviceAddress, Endpoint, GetSpeed(Dev),
+ MaxPacket, 1, &Data, DataLength, NULL, Status);
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoAsyncIsochronousTransfer
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoAsyncIsochronousTransfer(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 Endpoint,
+ IN OUT VOID *Data,
+ IN UINTN DataLength,
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK IsochronousCallback,
+ IN VOID *Context
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ UINT16 MaxPacket;// = GetMaxPacket(Endpoint, Dev);
+ EFI_USB_ENDPOINT_DESCRIPTOR* EpDesc = GetEndpointDesc(Endpoint, Dev);
+
+ if (EpDesc == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+ MaxPacket = EpDesc->MaxPacketSize;
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+ if ((EpDesc->Attributes & EP_DESC_FLAG_TYPE_BITS) != EP_DESC_FLAG_TYPE_ISOC) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (!(Dev->dev_info->Flag & DEV_INFO_DEV_PRESENT)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ return Dev->hc->AsyncIsochronousTransfer(
+ Dev->hc, Dev->dev_info->bDeviceAddress, Endpoint, GetSpeed(Dev),
+ MaxPacket, 1, &Data, DataLength, NULL, IsochronousCallback, Context );
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoPortReset
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoPortReset(
+ IN EFI_USB_IO_PROTOCOL *UsbIo
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ DEVGROUP_T* Grp = UsbDevGetGroup(Dev);
+ UINT8 Status;
+ UINT8 i;
+
+ if (Dev->dev_info->bDeviceType == BIOS_DEV_TYPE_HUB)
+ return EFI_INVALID_PARAMETER;
+
+ Status = UsbResetAndReconfigDev(Dev->hc_info, Dev->dev_info);
+ if (Status != USB_SUCCESS) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ if( UsbSmiGetDescriptor(Dev->hc_info, Dev->dev_info, (UINT8*)&Grp->dev_desc,
+ sizeof(Grp->dev_desc), DESC_TYPE_DEVICE, 0) == 0 ){
+ return EFI_DEVICE_ERROR;
+ }
+
+ for(i = 0; i < Grp->dev_desc.NumConfigurations; i++) {
+ if (ReadUsbDescriptor(Dev, (UINT8*)Grp->configs[i],
+ Grp->configs[i]->TotalLength, DESC_TYPE_CONFIG, i, 0) == 0) {
+ return EFI_DEVICE_ERROR;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoGetDeviceDescriptor
+//
+// Description: Retrieves the USB Device Descriptor.
+//
+// Input:
+// UsbIo A pointer to the EFI_USB_IO_PROTOCOL instance. Type
+// EFI_USB_IO_PROTOCOL is defined in Section 14.2.5.
+// Desc A pointer to the caller allocated USB Device Descriptor.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoGetDeviceDescriptor(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ OUT EFI_USB_DEVICE_DESCRIPTOR *Desc
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ DEVGROUP_T* Grp = UsbDevGetGroup(Dev);
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+ if( Desc == NULL ) return EFI_INVALID_PARAMETER;
+
+ if( Grp->f_DevDesc ){
+ *Desc = Grp->dev_desc;
+ return EFI_SUCCESS;
+ } else
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoGetConfigDescriptor
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoGetConfigDescriptor(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ OUT EFI_USB_CONFIG_DESCRIPTOR *Desc
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ DEVGROUP_T* Grp = UsbDevGetGroup(Dev);
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+ if( Desc == NULL ) return EFI_INVALID_PARAMETER;
+
+ if( Grp->configs && Grp->active_config != -1 &&
+ Grp->configs[Grp->active_config] ){
+ *Desc = *Grp->configs[Grp->active_config];
+ return EFI_SUCCESS;
+ } else
+ return EFI_NOT_FOUND;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoGetInterfaceDescriptor
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoGetInterfaceDescriptor(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ OUT EFI_USB_INTERFACE_DESCRIPTOR *Desc
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+ if (Desc == NULL) return EFI_INVALID_PARAMETER;
+
+ if (Dev->descIF == NULL) return EFI_NOT_FOUND;
+
+ *Desc = *Dev->descIF;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoGetEndpointDescriptor
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoGetEndpointDescriptor(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 EndpointIndex,
+ OUT EFI_USB_ENDPOINT_DESCRIPTOR *Desc
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ DEVGROUP_T *Grp;
+ EFI_USB_ENDPOINT_DESCRIPTOR* DescCopy;
+
+ if( Desc == NULL || EndpointIndex >= 0x10) return EFI_INVALID_PARAMETER;
+
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+
+ USB_DEBUG( 3, "Get Endpoint desc: devaddr: 0x%x; Endpoint: 0x%x\n",
+ Dev->dev_info->bDeviceAddress, EndpointIndex );
+ USB_DEBUG( 3, "\tfirst Endpoint: 0x%x; last Endpoint: 0x%x\n",
+ Dev->first_endpoint, Dev->end_endpoint-1 );
+
+ if( Dev->first_endpoint + EndpointIndex >= Dev->end_endpoint )
+ return EFI_NOT_FOUND;
+
+ ASSERT( Dev->first_endpoint + EndpointIndex < 0x20 );
+
+ Grp = UsbDevGetGroup(Dev);
+ DescCopy = Grp->endpoints[Dev->first_endpoint + EndpointIndex].desc;
+
+ ASSERT( DescCopy );
+
+ if (DescCopy==NULL) return EFI_NOT_FOUND;
+
+ USB_DEBUG( 3, "\tendp addr: 0x%x; attr: 0x%x; MaxPacket: 0x%x\n",
+ DescCopy->EndpointAddress,
+ DescCopy->Attributes, DescCopy->MaxPacketSize );
+
+ *Desc = *DescCopy;
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoGetStringDescriptor
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS
+UsbIoGetStringDescriptor(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT16 LangId,
+ IN UINT8 StringId,
+ OUT CHAR16 **String
+)
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ EFI_USB_STRING_DESCRIPTOR* StrDesc = NULL;
+ UINT16 Index;
+ UINT16 *LangIdTable;
+ DEVGROUP_T* Grp;
+ EFI_STATUS Status = EFI_NOT_FOUND;
+
+ ASSERT(Dev->dev_info);
+ ASSERT(Dev->hc);
+
+ Grp = UsbDevGetGroup(Dev);
+
+ if (StringId == 0 || Grp->lang_table == NULL) {
+ //reserved ids: stringid==0 => langid table descripto;
+ return Status;
+ }
+ // search langid_table
+ LangIdTable = Grp->lang_table->langID;
+ for (Index = 0; Index < Grp->lang_table->len ; Index++) {
+ if (LangId == LangIdTable[Index]) {
+ break;
+ }
+ }
+
+ if (Index == Grp->lang_table->len) {
+ return Status;
+ }
+
+ if (LangId == USB_US_LAND_ID) {
+ if (StringId == Grp->dev_desc.StrSerialNumber) {
+ StrDesc = Grp->SerialNumberStrDesc;
+ } else if (StringId == Grp->dev_desc.StrProduct) {
+ StrDesc = Grp->ProductStrDesc;
+ } else if (StringId == Grp->dev_desc.StrManufacturer) {
+ StrDesc = Grp->ManufacturerStrDesc;
+ }
+ }
+ //
+ // Get string descriptor: variable size
+ //
+ if (StrDesc == NULL) {
+ StrDesc = (EFI_USB_STRING_DESCRIPTOR*)GetUsbDescriptor(Dev, DESC_TYPE_STRING,
+ StringId, LangId);
+ }
+
+ if (StrDesc == NULL) {
+ return Status;
+ }
+
+ if (StrDesc->Length > 2 && StrDesc->DescriptorType == DESC_TYPE_STRING) {
+ //
+ // Allocate memory for string & copy
+ //
+ if (String != NULL) {
+ gBS->AllocatePool(EfiBootServicesData, StrDesc->Length, String);
+ EfiZeroMem(*String, StrDesc->Length);
+ EfiCopyMem(*String, StrDesc->String, StrDesc->Length -2);
+ }
+ Status = EFI_SUCCESS;
+ }
+ if ((StrDesc != Grp->SerialNumberStrDesc) && (StrDesc != Grp->ProductStrDesc) &&
+ (StrDesc != Grp->ManufacturerStrDesc)) {
+ gBS->FreePool(StrDesc);
+ }
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbIoGetSupportedLanguages
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbIoGetSupportedLanguages(
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ OUT UINT16 **LangIdTable,
+ OUT UINT16 *TableSize )
+{
+ USBDEV_T* Dev = UsbIo2Dev(UsbIo);
+ DEVGROUP_T* Grp;
+
+ ASSERT( Dev->dev_info );
+ ASSERT( Dev->hc );
+ Grp = UsbDevGetGroup(Dev);
+ if (LangIdTable == NULL || TableSize == NULL) {
+ return EFI_SUCCESS;
+ }
+ if (Grp->lang_table == NULL) {
+ *LangIdTable = 0;
+ *TableSize = 0;
+ } else {
+ *LangIdTable = Grp->lang_table->langID;
+ *TableSize = Grp->lang_table->len*2;
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: LoadName
+//
+// Description: loads STRING descriptor that corresponds to
+// the name of the USB device
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+LoadName(
+ USBDEV_T* Dev
+)
+{
+ EFI_USB_INTERFACE_DESCRIPTOR DescIf = {0,};
+ EFI_USB_DEVICE_DESCRIPTOR DescDev = {0,};
+ DEVGROUP_T* Grp = UsbDevGetGroup(Dev);
+ CHAR16* StrIf = 0;
+ CHAR16* StrProduct = 0;
+// CHAR16* StrManufact=0;
+ CHAR16 Lang;
+ CHAR16 *MassStorageName;
+ UINT8 *p;
+ UINT8 i;
+
+ for (i = 0; i < 64; i++) {
+ if (Dev->dev_info->DevNameString[i] != 0) {
+ break;
+ }
+ }
+
+ if (i != 64) {
+ gBS->AllocatePool (EfiBootServicesData, 128, &MassStorageName);
+ EfiZeroMem(MassStorageName, 128);
+ for (p = (UINT8*)&Dev->dev_info->DevNameString, i=0; i<64; i++) {
+ if (p[i] == 0) break;
+ MassStorageName[i] = (CHAR16)p[i];
+ }
+ return MassStorageName;
+ }
+
+ if( Grp->lang_table == 0 || Grp->lang_table->len == 0 ) return 0;
+
+ Lang = Grp->lang_table->langID[0];
+
+ UsbIoGetInterfaceDescriptor(&Dev->io,&DescIf);
+ if( DescIf.Interface && !EFI_ERROR(
+ UsbIoGetStringDescriptor(&Dev->io, Lang,
+ DescIf.Interface, &StrIf )))
+ return StrIf;
+
+ UsbIoGetDeviceDescriptor(&Dev->io, &DescDev);
+ if( DescDev.StrProduct && !EFI_ERROR(
+ UsbIoGetStringDescriptor(&Dev->io, Lang,
+ DescDev.StrProduct, &StrProduct )))
+ return StrProduct;
+
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InstallDevice
+//
+// Description: Adds a device to the tree; creates an EFI handle for the
+// usb device; installs USB_IO and DEVICEPATH protocols
+// on a new device handle; connects a new device to
+// EFI device drivers
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+TREENODE_T*
+UsbDevHubNode(
+ TREENODE_T *HcNode,
+ DEV_INFO *DevInfo
+)
+{
+// int i;
+ TREENODE_T *HubNode=0;
+ TREENODE_T *HubGrpNode;
+
+ HubGrpNode = TreeSearchDeep(HcNode->child, DevGrpByAddr, &DevInfo->bHubDeviceNumber );
+ if (HubGrpNode != NULL){
+ HubNode = HubGrpNode->child;
+ ASSERT(HubNode);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: parent Hub found: %x\n", HubNode );
+ return HubNode;
+ }
+/*
+ for( i=0;i<COUNTOF(gUsbData->aDevInfoTable) && (HubNode==0);i++){
+ if((gUsbData->aDevInfoTable[i].Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT))
+ != (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT))
+ continue;
+ if( gUsbData->aDevInfoTable[i].bHCNumber == DevInfo->bHCNumber &&
+ gUsbData->aDevInfoTable[i].bDeviceAddress == DevInfo->bHubDeviceNumber )
+ {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: UsbDevHubNode: valid hub info [%d]: %x\n",i, gUsbData->aDevInfoTable +i );
+ InstallDevice( gUsbData->aDevInfoTable +i );
+ HubNode = TreeSearchDeep(HcNode->child, DevByInfo, gUsbData->aDevInfoTable +i );
+ ASSERT(HubNode);
+ }
+ }
+*/
+ return HubNode;
+}
+
+VOID InstallDevice(DEV_INFO* DevInfo)
+{
+ TREENODE_T* HcNode;
+ TREENODE_T* HubNode;
+ TREENODE_T* ParentNode;
+ USBDEV_T* Dev;
+ DEVGROUP_T* Grp;
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+ UINT16 Index;
+ UINT16 *LangId;
+ UINT16 OrgTimeOutValue;
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: InstallDevice ");
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "(hc:%x,hub:%x,port:%x,addr:%x,if:%x,aif:%x,lun:%x)\n",
+ DevInfo->bHCNumber, DevInfo->bHubDeviceNumber, DevInfo->bHubPortNumber, DevInfo->bDeviceAddress,
+ DevInfo->bInterfaceNum, DevInfo->bAltSettingNum, DevInfo->bLUN );
+
+ // Find HC node in tree
+ HcNode = TreeSearchSibling(gUsbRootRoot->child, HcByIndex, &DevInfo->bHCNumber );
+
+ // Do not assert here: it's fine to see a DEV_INFO from not-yet-installed HC
+ if( HcNode == NULL ) return;
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: HC node found: %x\n", HcNode );
+
+ // Find a hub node in tree
+ if( DevInfo->bHubDeviceNumber & BIT7){ // hub is a root HC
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: Connecting to root Hub\n", DevInfo->bHCNumber );
+ ASSERT( (DevInfo->bHubDeviceNumber & ~BIT7 )== DevInfo->bHCNumber );
+ HubNode = HcNode;
+ } else { // hub is usb hub device
+ HubNode = UsbDevHubNode(HcNode, DevInfo);
+ // Do not assert here: it may be to see a DEV_INFO from not-yet-installed hub.
+ //ASSERT(HubNode != NULL);
+ if (HubNode == NULL) return;
+ }
+
+ ParentNode = NULL;
+ ParentNode = TreeSearchSibling(HubNode->child,
+ DevGrpByAddr, &DevInfo->bDeviceAddress );
+
+ if( ParentNode == NULL ){
+ // Create group
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: group created\n" );
+ Status = gBS->AllocatePool (EfiBootServicesData, sizeof(DEVGROUP_T), &Grp);
+ ASSERT_EFI_ERROR(Status);
+ EfiZeroMem(Grp, sizeof(DEVGROUP_T));
+
+ Grp->dev_info = DevInfo;
+ Grp->hc = ((USBBUS_HC_T*)HcNode->data)->hc;
+ Grp->hc_info = ((USBBUS_HC_T*)HcNode->data)->hc_data;
+ Grp->f_DevDesc = FALSE;
+ Grp->configs = NULL;
+ Grp->config_count = 0;
+ Grp->ManufacturerStrDesc = NULL;
+ Grp->ProductStrDesc = NULL;
+ Grp->SerialNumberStrDesc = NULL;
+ Grp->type = NodeGroup;
+ Grp->active_config = 0;
+ UsbDevLoadAllDescritors(Grp);
+ //
+ // Check at least for Device Descriptor present before proceeding
+ //
+ if(Grp->f_DevDesc == FALSE) {
+ //
+ //When no Device Descriptor present quit installing the device
+ //
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: dev install aborted - no device descriptor\n");
+ return;
+ }
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: descriptors loaded\n" );
+
+ //(EIP66231+)>
+ if ((Grp->dev_desc.StrManufacturer != 0) || (Grp->dev_desc.StrProduct != 0) ||
+ (Grp->dev_desc.StrSerialNumber != 0)) {
+ // Load langid table
+ Grp->lang_table = (lang_table_t*)GetUsbDescriptor((USBDEV_T*)Grp, DESC_TYPE_STRING, 0, 0);
+ if (Grp->lang_table && Grp->lang_table->len != 0) {
+ Grp->lang_table->len = (Grp->lang_table->len -2) / sizeof(UINT16);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: LangID table loaded\n" );
+
+ LangId = Grp->lang_table->langID;
+
+ for (Index = 0; Index < Grp->lang_table->len; Index++) {
+ if (LangId[Index] == USB_US_LAND_ID) {
+ break;
+ }
+ }
+
+ if (Index != Grp->lang_table->len) {
+ // Some devices may not respond getting string descriptors
+ // whcih describing manufacturer, product set the timeout value to 100 ms.
+ OrgTimeOutValue = gUsbData->wTimeOutValue;
+ gUsbData->wTimeOutValue = USB_GET_STRING_DESC_TIMEOUT_MS;
+ if (Grp->dev_desc.StrManufacturer != 0) {
+ Grp->ManufacturerStrDesc =
+ (EFI_USB_STRING_DESCRIPTOR*)GetUsbDescriptor(
+ (USBDEV_T*)Grp, DESC_TYPE_STRING,
+ Grp->dev_desc.StrManufacturer, USB_US_LAND_ID);
+ }
+ if (Grp->dev_desc.StrProduct != 0) {
+ Grp->ProductStrDesc =
+ (EFI_USB_STRING_DESCRIPTOR*)GetUsbDescriptor(
+ (USBDEV_T*)Grp, DESC_TYPE_STRING,
+ Grp->dev_desc.StrProduct, USB_US_LAND_ID);
+ }
+ if (Grp->dev_desc.StrSerialNumber != 0) {
+ // Set timeout value to 3000 ms for the serial number string descriptor.
+ gUsbData->wTimeOutValue = USB_GET_SERIAL_NUMBER_DESC_TIMEOUT_MS;
+ Grp->SerialNumberStrDesc =
+ (EFI_USB_STRING_DESCRIPTOR*)GetUsbDescriptor(
+ (USBDEV_T*)Grp, DESC_TYPE_STRING,
+ Grp->dev_desc.StrSerialNumber, USB_US_LAND_ID);
+ }
+ gUsbData->wTimeOutValue = OrgTimeOutValue;
+ }
+ }
+ }
+ //<(EIP66231+)
+ TreeAddChild(HubNode,(ParentNode = TreeCreate(&Grp->node, Grp)));
+ } else {
+ // Old group was found in tree
+ TREENODE_T *tmp = TreeSearchSibling(ParentNode->child, DevByAdrIf, DevInfo );
+ if(tmp){
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: IF is already in tree: %x\n", tmp );
+ return;
+ }
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: multi-function; group node found: %x\n", ParentNode );
+ Grp = (DEVGROUP_T*)ParentNode->data;
+ }
+
+ // Create new device node as a child of HubNode
+ gBS->AllocatePool (EfiBootServicesData, sizeof(USBDEV_T), &Dev);
+ ASSERT(Dev);
+ if (Dev == NULL) return;
+ EfiZeroMem(Dev, sizeof(USBDEV_T));
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: device node created: %x\n",
+ &Dev->node );
+ Dev->type = NodeDevice;
+ TreeAddChild(ParentNode, TreeCreate(&Dev->node, Dev));
+ Dev->dev_info = DevInfo;
+ Dev->hc = ((USBBUS_HC_T*)HcNode->data)->hc;
+ Dev->hc_info = ((USBBUS_HC_T*)HcNode->data)->hc_data;
+ Dev->f_connected = FALSE;
+
+ UsbDevLoadEndpoints(Dev);
+
+ // Speed 00/10/01 - High/Full/Low
+ //(EIP81612)>
+ switch (Dev->dev_info->bEndpointSpeed) {
+ case USB_DEV_SPEED_SUPER_PLUS:
+ Dev->speed = EFI_USB_SPEED_SUPER_PLUS;
+ break;
+ case USB_DEV_SPEED_SUPER:
+ Dev->speed = EFI_USB_SPEED_SUPER;
+ break;
+ case USB_DEV_SPEED_FULL:
+ Dev->speed = EFI_USB_SPEED_FULL;
+ break;
+ case USB_DEV_SPEED_LOW:
+ Dev->speed = EFI_USB_SPEED_LOW;
+ break;
+ case USB_DEV_SPEED_HIGH:
+ Dev->speed = EFI_USB_SPEED_HIGH;
+ }
+ //<(EIP81612)
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: endpoints loaded\n" );
+
+ // Create Device Path
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: preparing DP...\n" );
+
+ ASSERT(((USBDEV_T*)HubNode->data)->dp);
+ Dev->dp = DpAddUsbSegment(((USBDEV_T*)HubNode->data)->dp,
+ DevInfo->bHubPortNumber - 1, DevInfo->bInterfaceNum);
+ if (DevInfo->bLUN) {
+ Dev->dp = DpAddLun(Dev->dp, DevInfo->bLUN);
+ }
+ ASSERT(Dev->dp);
+
+ // Install USB_IO protocol
+ Dev->io.UsbControlTransfer = UsbIoControlTransfer;
+ Dev->io.UsbBulkTransfer = UsbIoBulkTransfer;
+ Dev->io.UsbAsyncInterruptTransfer = UsbIoAsyncInterruptTransfer;
+ Dev->io.UsbSyncInterruptTransfer = UsbIoSyncInterruptTransfer;
+ Dev->io.UsbIsochronousTransfer = UsbIoIsochronousTransfer;
+ Dev->io.UsbAsyncIsochronousTransfer = UsbIoAsyncIsochronousTransfer;
+
+ Dev->io.UsbGetDeviceDescriptor = UsbIoGetDeviceDescriptor;
+ Dev->io.UsbGetConfigDescriptor = UsbIoGetConfigDescriptor;
+ Dev->io.UsbGetInterfaceDescriptor = UsbIoGetInterfaceDescriptor;
+ Dev->io.UsbGetEndpointDescriptor = UsbIoGetEndpointDescriptor;
+ Dev->io.UsbGetStringDescriptor = UsbIoGetStringDescriptor;
+ Dev->io.UsbGetSupportedLanguages = UsbIoGetSupportedLanguages;
+
+ Dev->io.UsbPortReset = UsbIoPortReset;
+
+// DEBUG_DELAY();
+ //Install DP_ protocol
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Dev->handle,
+ &gEfiUsbIoProtocolGuid, &Dev->io,
+ &gEfiDevicePathProtocolGuid, Dev->dp,
+ NULL);
+ ASSERT_EFI_ERROR(Status);
+
+ *(UINTN*)Dev->dev_info->Handle = (UINTN)Dev->handle;
+ Dev->dev_info->Flag |= DEV_INFO_DEV_BUS;
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: USB_IO %x installed on Dev %x\n", &Dev->io, Dev );
+
+ {
+ VOID* tmp;
+ VERIFY_EFI_ERROR(
+ gBS->OpenProtocol (
+ Dev->hc_info->Controller,
+ &gEfiUsb2HcProtocolGuid,
+ &tmp,
+ gUSBBusDriverBinding.DriverBindingHandle,
+ Dev->handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER ));
+ }
+
+ PROGRESS_CODE(DXE_USB_HOTPLUG);
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ pBS->RestoreTPL(TPL_CALLBACK);
+
+ // Connect controller to start device drvirs
+ Status = gBS->ConnectController(Dev->handle,NULL,NULL,TRUE);
+
+ pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ pBS->RestoreTPL(OldTpl);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: instdev: connect controller: %r\n", Status );
+
+ if( !EFI_ERROR(Status)){
+ Dev->f_connected = TRUE;
+ }
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UninstallDevice
+//
+// Description: Disconnects device; uninstalls USB_IO and DEVICEPATH protocols
+// delocates all memory used USB Bus driver to support the device
+// removes device node from the tree; if device has children, all
+// UninstallDevice procedure is repeated for each child.
+//
+// In case if disconnect or protocol uninstall fails, it reports
+// error stauts returned from Boot service procedure.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS UninstallDevice(USBDEV_T* Dev)
+{
+ EFI_STATUS Status;
+ EFI_TPL OldTpl;
+
+ //
+ // Uninstall connected devices if it's a hub
+ //
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: UninstallDevice: node %x; ", &Dev->node);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "info:%x [adr:%d;if:%d] uninstalling children...\n",
+ Dev->dev_info,Dev->dev_info->bDeviceAddress, Dev->dev_info->bInterfaceNum);
+ if( TreeSearchSibling( Dev->node.child, eUninstallDevice, &Status ))
+ return Status;
+
+ OldTpl = pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ pBS->RestoreTPL(TPL_CALLBACK);
+
+ Status = gBS->DisconnectController(Dev->handle, NULL, NULL);
+
+ pBS->RaiseTPL(TPL_HIGH_LEVEL);
+ pBS->RestoreTPL(OldTpl);
+
+ if (EFI_ERROR(Status)) {
+ QueuePut(&gUsbData->QueueCnnctDisc, Dev->dev_info);
+ Dev->dev_info->Flag |= DEV_INFO_IN_QUEUE;
+ return Status;
+ }
+
+ if (Dev->async_endpoint != 0) {
+ Status = Dev->io.UsbAsyncInterruptTransfer(&Dev->io, Dev->async_endpoint, FALSE,
+ 0, 0, NULL, NULL);
+ Dev->async_endpoint = 0;
+ }
+
+ Status = gBS->CloseProtocol (
+ Dev->hc_info->Controller,
+ &gEfiUsb2HcProtocolGuid,
+ gUSBBusDriverBinding.DriverBindingHandle,
+ Dev->handle
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ //
+ // Try to uninstall protocols
+ //
+ // they can be denied to uninstall, which result in
+ // keeping this device and all bus alive
+ //
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: uninstdev: [%d:%d] uninstalling protocols...",
+ Dev->dev_info->bDeviceAddress, Dev->dev_info->bInterfaceNum);
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Dev->handle,
+ &gEfiUsbIoProtocolGuid, &Dev->io,
+ &gEfiDevicePathProtocolGuid, Dev->dp,
+ NULL);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "%r\n", Status );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) return Status;
+
+ Dev->dev_info->Flag &= ~DEV_INFO_DEV_BUS;
+ if (!(Dev->dev_info->Flag & (DEV_INFO_MASS_DEV_REGD | DEV_INFO_DEV_PRESENT))) {
+ Dev->dev_info->Flag &= ~DEV_INFO_VALID_STRUC;
+ }
+
+ //
+ // Unistall succeeded, free usbdev
+ //
+ TreeRemove(&Dev->node);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: uninstdev: [%d:%d] done.\n",
+ Dev->dev_info->bDeviceAddress, Dev->dev_info->bInterfaceNum);
+
+ if(Dev->name)
+ gBS->FreePool(Dev->name);
+ gBS->FreePool(Dev);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: eUninstallDevice
+//
+// Description: Enumeration call-back function that is usded
+// uninstall all enumerated device nodes
+// Stops enumeration as soon as error was recieved
+// Input:
+// Node - tree node of the USB device or group
+// Contex - pointer to the EFI_STATUS variable that
+// recieves status information if error
+// was recieved
+// Output: TRUE on error found; this will stop enumeration
+// FALSE on succesfull uninstall operation
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+int
+eUninstallDevice(
+ VOID* Node,
+ VOID* Context
+)
+{
+ EFI_STATUS *Status = (EFI_STATUS*)Context;
+ DEVGROUP_T* Grp = (DEVGROUP_T*)Node;
+ ASSERT(Status);
+
+ if (Grp->type == NodeGroup) {
+ //
+ // Uninstall all CONNECTED devices within group
+ //
+ TreeSearchSibling( Grp->node.child, eUninstallDevice, Status );
+ if (EFI_ERROR(*Status)) {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: devgroup uninstall failed: devaddr:0x%x\n",
+ Grp->dev_info->bDeviceAddress );
+ return TRUE; //stop enumeration
+ }
+ // Free devgroup
+ TreeRemove(&Grp->node);
+ if (Grp->configs) {
+ int i;
+ for (i = 0; i < Grp->config_count; ++i) {
+ if (Grp->configs[i]) {
+ gBS->FreePool(Grp->configs[i]);
+ }
+ }
+ gBS->FreePool(Grp->configs);
+ }
+ if (Grp->ManufacturerStrDesc) {
+ gBS->FreePool(Grp->ManufacturerStrDesc);
+ }
+ if (Grp->ProductStrDesc) {
+ gBS->FreePool(Grp->ProductStrDesc);
+ }
+ if (Grp->SerialNumberStrDesc) {
+ gBS->FreePool(Grp->SerialNumberStrDesc);
+ }
+ gBS->FreePool(Grp);
+ } else if (Grp->type == NodeDevice ) {
+ //
+ //Uninstall Device
+ //
+ *Status = UninstallDevice((USBDEV_T*)Node);
+ if (EFI_ERROR(*Status)) {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: usbdev uninstall failed: if:%d\n",
+ ((USBDEV_T*)Node)->dev_info->bInterfaceNum );
+ return TRUE; //stop enumeration
+ }
+ }
+ return FALSE;// continue enumeration
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveHubEcho
+//
+// Description: Finds the USB hub node that sits on the same
+// path (seq. of (hub ports,if) ) but have different
+// USB address or DEV_INFO node. This could be the result
+// of lost disconnect event or previous error to uninstall
+// USB_IO
+// Input:
+// pDevInfo - DEV_INFO structure that is checked for
+// echoes in the bus
+// Output: EFI_SUCCESS - echo wasn't found or was succesfully removed
+// otherwise return status resulted from attemp to remove the node
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveHubEcho(
+ TREENODE_T *HcNode,
+ UINT8 Addr
+)
+{
+ while(!( Addr & BIT7 )){
+ //
+ // Find hub DEV_INFO
+ //
+ int i;
+ TREENODE_T *HubNode;
+ TREENODE_T* DevNode;
+ DEV_INFO* DevInfo=NULL;
+
+ for ( i= 1; i < MAX_DEVICES; i++) {
+ if( ((gUsbData->aDevInfoTable[i].Flag &
+ (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT | DEV_INFO_DEV_DUMMY))
+ != (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT)) &&
+ gUsbData->aDevInfoTable[i].bDeviceAddress == Addr )
+ {
+ DevInfo = gUsbData->aDevInfoTable+i;
+ break;
+ }
+ }
+ if ( DevInfo == NULL )
+ return EFI_NOT_FOUND;
+
+ //
+ // Search for parent hub
+ //
+ if( DevInfo->bHubDeviceNumber & BIT7 ){
+ //Root hub
+ HubNode = HcNode;
+ } else {
+ //USB hub device
+ TREENODE_T* HubGrpNode = TreeSearchDeep(HcNode->child,
+ DevGrpByAddr, &DevInfo->bHubDeviceNumber );
+ if( HubGrpNode != NULL ){
+ USBDEV_T* Dev;
+
+ HubNode = HubGrpNode->child;
+ ASSERT(HubNode);
+ DevNode = TreeSearchSibling(HubNode->child,
+ DevGrpByPortIf, DevInfo);
+ if(DevNode==NULL) return EFI_SUCCESS;
+ Dev = (USBDEV_T*)DevNode->data;
+ if( Dev && (DevInfo->bDeviceAddress !=
+ Dev->dev_info->bDeviceAddress ||
+ DevInfo != Dev->dev_info ))
+ {
+ //
+ // The disconnect event must have been droped
+ // disconnect old info now
+ //
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: echo found [%x]:\n" );
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t(hc:0x%x,hub:0x%x,port:%d,addr:0x%x,if:%d)\n",
+ Dev->dev_info->bHCNumber,
+ Dev->dev_info->bHubDeviceNumber,
+ Dev->dev_info->bHubPortNumber,
+ Dev->dev_info->bDeviceAddress,
+ Dev->dev_info->bInterfaceNum);
+ return RemoveDevInfo(Dev->dev_info);
+ }
+ return EFI_SUCCESS;
+ } else {
+ //
+ // Either hub wasn't added to bus yet; or there is echo for the
+ // brunch. The the later case succesfull removal of the burnch
+ // removes an echo for this device info
+ //
+ Addr = DevInfo->bHubDeviceNumber;
+
+ }
+ }
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveDevInfoEcho
+//
+// Description: Finds the USB device node that sits on the same
+// path (seq. of (hub ports,if) ) but have different
+// USB address or DEV_INFO node. This could be the result
+// of lost disconnect event or previous error to uninstall
+// USB_IO
+// Input:
+// DevInfo - DEV_INFO structure that is checked for
+// echoes in the bus
+// Output: EFI_SUCCESS - echo wasn't found or was succesfully removed
+// otherwise return status resulted from attemp to remove the node
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+RemoveDevInfoEcho(
+ DEV_INFO *DevInfo
+)
+{
+ USBDEV_T *Dev;
+ TREENODE_T *DevNode;
+ TREENODE_T *HcNode, *HubNode;
+
+ HcNode = TreeSearchSibling(gUsbRootRoot->child,HcByIndex,
+ &DevInfo->bHCNumber);
+ if(HcNode==NULL) return EFI_SUCCESS;
+
+ if( DevInfo->bHubDeviceNumber & BIT7 ){
+ //Root hub
+ HubNode = HcNode;
+ } else {
+ //USB hub device
+ TREENODE_T* HubGrpNode = TreeSearchDeep(HcNode->child,
+ DevGrpByAddr, &DevInfo->bHubDeviceNumber );
+ if( HubGrpNode != NULL ){
+ HubNode = HubGrpNode->child;
+ ASSERT(HubNode);
+ } else {
+ //
+ // Either hub wasn't added to bus yet; or there is echo for the
+ // brunch. The the later case succesfull removal of the burnch
+ // removes an echo for this device info
+ //
+ //return RemoveHubEcho(HcNode, DevInfo->bHubDeviceNumber);
+ return EFI_SUCCESS;
+ }
+ }
+ DevNode = TreeSearchSibling(HubNode->child, DevGrpByPortIf, DevInfo);
+ if(DevNode==NULL) return EFI_SUCCESS;
+ Dev = (USBDEV_T*)DevNode->data;
+ if (Dev != NULL) {
+ //
+ // The disconnect event must have been droped
+ // disconnect old info now
+ //
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: echo found [%x]:\n" );
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t(hc:0x%x,hub:0x%x,port:%d,addr:0x%x,if:%d)\n",
+ Dev->dev_info->bHCNumber,
+ Dev->dev_info->bHubDeviceNumber,
+ Dev->dev_info->bHubPortNumber,
+ Dev->dev_info->bDeviceAddress,
+ Dev->dev_info->bInterfaceNum);
+ return RemoveDevInfo(Dev->dev_info);
+ }
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: RemoveDevInfo
+//
+// Description: Removes device node from the USB bus tree. Device node
+// corresponds to the DEV_INFO. Device gets removed in response to
+// the pending removal event sheduled from SMM when disconnect
+// was detected on USB
+// Input:
+// DevInfo - DEV_INFO structure that was disconnect
+//
+// Output: EFI_SUCCESS - echo wasn't found or was succesfully removed
+// otherwise return status resulted from attemp to remove the node
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS RemoveDevInfo(DEV_INFO* DevInfo)
+{
+ TREENODE_T *DevNode;
+ TREENODE_T *HcNode;
+ EFI_STATUS Status;
+
+ HcNode = TreeSearchSibling(gUsbRootRoot->child, HcByIndex,
+ &DevInfo->bHCNumber);
+ if(HcNode==NULL) return EFI_NOT_FOUND;
+
+ //Check for echoes
+
+ DevNode = TreeSearchDeep(HcNode->child,DevGrpByAddr,
+ &DevInfo->bDeviceAddress);
+ if (DevNode==NULL){
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "\tdevice is not found in the tree...\n" );
+ return EFI_NOT_FOUND;
+ }
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "\tdevice found in the tree...\n" );
+
+ Status = EFI_SUCCESS;
+ eUninstallDevice(DevNode->data, &Status);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "\tDisconnect complete: %r.\n", Status );
+
+ return Status;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbHcOnTimer
+//
+// Description: Timer call-back routine that is
+// is used to monitor changes on USB Bus
+// It monitors the state of queueCnnct and queueDiscnct queues
+// which get populated by UsbSmiNotify call-back routine
+//
+// When this routine finds a new device connected to usb it
+// will install a device node for that device by calling
+// InstallDevice
+//
+// When this routine finds a disconneced device it uninstalls the
+// device node by calling UninstallDevice
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+UsbHcOnTimer(
+ EFI_EVENT Event,
+ VOID *Context
+)
+{
+ DEV_INFO* EventCnnct = 0;
+ static int i = 0;
+ int Lock;
+ EFI_STATUS Status;
+
+ UsbSmiPeriodicEvent();
+
+ if (Event) {
+ gBS->SetTimer(Event, TimerCancel, ONESECOND / 10);
+ }
+
+ ATOMIC({Lock = gBustreeLock; gBustreeLock = 1;});
+
+ if (Lock) {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "UsbHcOnTimer:: is locked; return\n");
+ return;
+ }
+
+ do {
+ ATOMIC({EventCnnct = QueueGet(&gUsbData->QueueCnnctDisc);});
+
+ if (EventCnnct == NULL) {
+ break;
+ }
+ EventCnnct->Flag &= ~DEV_INFO_IN_QUEUE;
+ //
+ // There is no need to raise tpl here: this is callback of Event with
+ // TPL_CALLBACK, so this code doesn't reenter; the Install and Uninstall
+ // are also called from driver stop and start. Stop and start protect
+ // the code at TPL_CALLBACK level
+ //
+ if( (EventCnnct->Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT |
+ DEV_INFO_DEV_DUMMY)) == (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT) ){
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "UsbHcOnTimer:: event connect [%d]: %x\n", i++, EventCnnct);
+
+ RemoveDevInfoEcho(EventCnnct);
+ InstallDevice(EventCnnct);
+ } else if ((EventCnnct->Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT |
+ DEV_INFO_DEV_DUMMY)) == DEV_INFO_VALID_STRUC) {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "UsbHcOnTimer:: event disconnect [%d]: %x\n", i++, EventCnnct);
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "\t(hc:0x%x,hub:0x%x,port:%d,addr:0x%x,if:%d)\n",
+ EventCnnct->bHCNumber, EventCnnct->bHubDeviceNumber,
+ EventCnnct->bHubPortNumber, EventCnnct->bDeviceAddress,
+ EventCnnct->bInterfaceNum);
+ //RemoveDevInfoEcho(EventCnnct);
+ Status = RemoveDevInfo(EventCnnct);
+ if (EFI_ERROR(Status)) {
+ break;
+ }
+ }
+ } while ( EventCnnct != NULL );
+
+ gBustreeLock = 0;
+
+ if (Event) {
+ gBS->SetTimer(Event, TimerPeriodic, ONESECOND / 10);
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: PopulateTree
+//
+// Description: Enumerate all DEV_INFO structures in the aDevInfoTable array
+// and install all currently connected device
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+PopulateTree(
+ HC_STRUC *HcStruc
+)
+{
+ UINT16 i;
+
+ PROGRESS_CODE(DXE_USB_DETECT);
+
+ UsbHcOnTimer(NULL, NULL);
+
+ for (i = 1; i < COUNTOF(gUsbData->aDevInfoTable); i++) {
+ if ((gUsbData->aDevInfoTable[i].Flag & (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT |
+ DEV_INFO_DEV_DUMMY | DEV_INFO_DEV_BUS)) == (DEV_INFO_VALID_STRUC | DEV_INFO_DEV_PRESENT)) {
+ if (HcStruc != gUsbData->HcTable[gUsbData->aDevInfoTable[i].bHCNumber - 1]) {
+ continue;
+ }
+ //
+ // Valid and present device behind specified HC, so insert it in the tree
+ //
+ USB_DEBUG(DEBUG_LEVEL_3, "USBBUS: PopulateTree: found valid dev info[%d]: %x\n",i, gUsbData->aDevInfoTable +i );
+
+ //RemoveDevInfoEcho(&gUsbData->aDevInfoTable[i]);
+ //InstallDevice( gUsbData->aDevInfoTable + i );
+ if (!(gUsbData->aDevInfoTable[i].Flag & DEV_INFO_IN_QUEUE)) {
+ QueuePut(&gUsbData->QueueCnnctDisc, &gUsbData->aDevInfoTable[i]);
+ gUsbData->aDevInfoTable[i].Flag |= DEV_INFO_IN_QUEUE;
+ }
+ }
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbBusGetControllerName
+//
+// Description: This function is a part of binding protocol, it returns
+// the string with the controller name.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+CHAR16*
+UsbBusGetControllerName(
+ EFI_HANDLE Controller,
+ EFI_HANDLE Child
+)
+{
+ //(EIP60745+)>
+ EFI_STATUS Status;
+
+ Status = gBS->OpenProtocol ( Controller,
+ &gEfiUsb2HcProtocolGuid,
+ NULL,
+ gUSBBusDriverBinding.DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) {
+ return NULL;
+ }
+ //<(EIP60745+)
+ if(Child) {
+ //Get name for USB device
+ EFI_USB_IO_PROTOCOL *UsbIo;
+ USBDEV_T *Dev ;
+ if( EFI_ERROR(gBS->HandleProtocol(Child,& gEfiUsbIoProtocolGuid, &UsbIo)))
+ {
+ return NULL;
+ }
+ Dev = UsbIo2Dev(UsbIo);
+ if( Dev->name == 0)
+ Dev->name = LoadName(Dev);
+ return Dev->name;
+ } else {
+ //Get name for USB HC
+ return L"USB Host Controller (USBBUS)";
+ }
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbBusInit
+//
+// Description: Install driver binding and controller name protocols
+// for the USB bus driver.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbBusInit(
+ EFI_HANDLE ImageHandle,
+ EFI_HANDLE ServiceHandle
+)
+{
+ //(EIP59272)>
+ static NAME_SERVICE_T usbbus_names;
+ gUSBBusDriverBinding.DriverBindingHandle = ServiceHandle;
+ gUSBBusDriverBinding.ImageHandle = ImageHandle;
+
+ return gBS->InstallMultipleProtocolInterfaces(
+ &gUSBBusDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid, &gUSBBusDriverBinding,
+ &gEfiComponentName2ProtocolGuid, InitNamesProtocol(&usbbus_names,
+ L"USB bus", UsbBusGetControllerName),
+ NULL);
+ //<(EIP59272)
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbBusSupported
+//
+// Description: This is a binding protocol function that returns EFI_SUCCESS
+// for USB controller and EFI_UNSUPPORTED for any other kind of
+// controller.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbBusSupported(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath
+)
+{
+ EFI_STATUS Status;
+ VOID* Ptr = 0;
+
+ Status = gBS->OpenProtocol ( Controller, &gEfiUsb2HcProtocolGuid,
+ &Ptr, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_BY_DRIVER );
+
+ if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) {
+ return EFI_UNSUPPORTED;
+ } else if (Status == EFI_ALREADY_STARTED) {
+ return Status;
+ }
+
+ gBS->CloseProtocol ( Controller, &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+ Status = gBS->OpenProtocol ( Controller, &gEfiDevicePathProtocolGuid,
+ NULL, This->DriverBindingHandle, Controller, EFI_OPEN_PROTOCOL_TEST_PROTOCOL );
+
+ if (Status != EFI_SUCCESS && Status != EFI_ALREADY_STARTED) {
+ return EFI_UNSUPPORTED;
+ }
+
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbBusStop
+//
+// Description: This function is part of binding protocol installed on USB
+// controller. It stops the controller and removes all the
+// children.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbBusStop (
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *Children )
+{
+ EFI_STATUS Status = EFI_SUCCESS;
+ TREENODE_T *HcNode;
+ USBBUS_HC_T *HcDev;
+
+ //EFI_TPL SaveTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+ //ASSERT(SaveTpl <= EFI_TPL_NOTIFY );
+
+ HcNode = TreeSearchSibling(gUsbRootRoot->child, HcByHandle, &Controller );
+ ASSERT(HcNode);
+ if( HcNode == NULL ) {
+ //gBS->RestoreTPL(SaveTpl);
+ return EFI_DEVICE_ERROR;
+ }
+ HcDev = (USBBUS_HC_T*)HcNode->data;
+
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer( gEvUsbEnumTimer, TimerCancel, ONESECOND/10));
+
+ UsbHcOnTimer(NULL, NULL);
+
+ if (TreeSearchSibling(HcNode->child, eUninstallDevice, &Status) != NULL)
+ {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,
+ "USBBUS: Stop HC: [%d] failed to uninstall children\n",
+ ((USBBUS_HC_T*)HcNode->data)->hc_data->bHCNumber);
+ //gBS->RestoreTPL(SaveTpl);
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gEvUsbEnumTimer, TimerPeriodic, ONESECOND/10));
+ return Status;
+ }
+
+ if (NumberOfChildren == 0) {
+ TreeRemove(HcNode);
+
+ //
+ // Close Protocols opened by driver
+ //
+ gBS->CloseProtocol (
+ Controller, &gEfiUsb2HcProtocolGuid,
+ This->DriverBindingHandle, Controller);
+
+ gBS->FreePool(HcDev);
+
+ if(--gCounterUsbEnumTimer==0){
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gEvUsbEnumTimer, TimerCancel, ONESECOND/10));
+ VERIFY_EFI_ERROR(
+ gBS->CloseEvent (gEvUsbEnumTimer));
+ gEvUsbEnumTimer=0;
+ }
+ }
+
+ if (gCounterUsbEnumTimer != 0) {
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gEvUsbEnumTimer, TimerPeriodic, ONESECOND/10));
+ }
+ //gBS->RestoreTPL(SaveTpl);
+
+ return EFI_SUCCESS;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: UsbBusStart
+//
+// Description: This function is part of binding protocol installed on USB
+// controller. It starts the USB bus for a given controller.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+UsbBusStart(
+ EFI_DRIVER_BINDING_PROTOCOL *This,
+ EFI_HANDLE Controller,
+ EFI_DEVICE_PATH_PROTOCOL *DevicePathProtocol
+)
+{
+ USBBUS_HC_T* HcDev = 0;
+ EFI_STATUS Status = EFI_UNSUPPORTED;
+
+ VERIFY_EFI_ERROR (
+ gBS->AllocatePool (
+ EfiBootServicesData,
+ sizeof(USBBUS_HC_T),
+ &HcDev ));
+ HcDev->type = NodeHC;
+ HcDev->hc_data = FindHcStruc(Controller);
+
+// ASSERT(HcDev->hc_data);
+ if (HcDev->hc_data == NULL) {
+ gBS->FreePool(HcDev);
+ return EFI_DEVICE_ERROR;
+ }
+
+ //
+ // Open Protocols
+ //
+ Status = gBS->OpenProtocol ( Controller,
+ &gEfiUsb2HcProtocolGuid, &HcDev->hc,
+ This->DriverBindingHandle, Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ Status = gBS->OpenProtocol ( Controller,
+ &gEfiDevicePathProtocolGuid,
+ &HcDev->dp, This->DriverBindingHandle,
+ Controller, EFI_OPEN_PROTOCOL_GET_PROTOCOL );
+ ASSERT_EFI_ERROR(Status);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ //
+ // Install Polling timer
+ //
+ {
+ //EFI_TPL SaveTpl = gBS->RaiseTPL (EFI_TPL_NOTIFY);
+ //ASSERT( SaveTpl <= EFI_TPL_NOTIFY);
+ if(gEvUsbEnumTimer != 0) {
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gEvUsbEnumTimer, TimerCancel, ONESECOND/10));
+ }
+ //
+ // Critical section
+
+// HookSmiNotify(1);
+
+ USB_DEBUG(DEBUG_LEVEL_USBBUS,"**** \tnew hc_struc: %x(type:%x,number:%x)\n",
+ HcDev->hc_data, HcDev->hc_data->bHCType, HcDev->hc_data->bHCNumber);
+
+ //
+ // Create HC branch in the USB root
+ //
+ TreeAddChild(gUsbRootRoot, TreeCreate(&HcDev->node,HcDev));
+
+ gCounterUsbEnumTimer++;
+ PopulateTree(HcDev->hc_data);
+
+ UsbHcOnTimer(NULL, NULL);
+
+ // Setting up global: gUsbDeviceToDisconnect, gUsbDeviceToConnect
+ if (gEvUsbEnumTimer == 0) {
+ USB_DEBUG(DEBUG_LEVEL_USBBUS, "USBBUS: Start: setup timer callback %x\n", &UsbHcOnTimer );
+ VERIFY_EFI_ERROR(
+ gBS->CreateEvent ( EFI_EVENT_TIMER | EFI_EVENT_NOTIFY_SIGNAL,
+ EFI_TPL_CALLBACK, UsbHcOnTimer,0,&gEvUsbEnumTimer));
+ }
+ VERIFY_EFI_ERROR(
+ gBS->SetTimer ( gEvUsbEnumTimer, TimerPeriodic, ONESECOND/10));
+ //gBS->RestoreTPL(SaveTpl);
+ }
+
+ return EFI_SUCCESS;
+}
+
+#if defined(DEBUG_SWITCH) && (DEBUG_SWITCH == 1)
+VOID DEBUG_DELAY()
+{
+ int i;
+ PrintDebugMsg(3,"\nDELAY: ");
+ for(i=0;i<10;i++){
+ PrintDebugMsg(3,"%d..",i);
+ pBS->Stall(200*1000);
+ }
+ PrintDebugMsg(3,"\n");
+}
+#endif
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2015, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/usbbus.h b/Core/EM/usb/usbbus.h
new file mode 100644
index 0000000..a61aa0d
--- /dev/null
+++ b/Core/EM/usb/usbbus.h
@@ -0,0 +1,310 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/usbbus.h 17 12/20/13 3:42a Wilsonlee $
+//
+// $Revision: 17 $
+//
+// $Date: 12/20/13 3:42a $
+//
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/usbbus.h $
+//
+// 17 12/20/13 3:42a Wilsonlee
+// [TAG] EIP147402
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] System hang at 0xA2 if plugging Seagate USB device.
+// [RootCause] This device doesn't respond get descriptor command after
+// we install mass storage driver.
+// [Solution] We store the string descriptor when we load the langid
+// table.
+// [Files] usbbus.c, usbbus.h
+//
+// 16 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 15 11/10/12 6:41a Ryanchou
+// [TAG] EIP99431
+// [Category] Bug Fix
+// [Severity] Minor
+// [Symptom] Cannot use the UsbIo's UsbAsyncInterruptTransfer for
+// keyboard input
+// [RootCause] Stopping EFI USB keyboard driver does not stop the
+// endpoint polling, then application calls UsbAsyncInterruptTransfer,
+// error will be returned.
+// [Solution] Stops endpoint polling and release resource when
+// disconnecting the device driver. And improve the
+// UsbSyncInterruptTransfer.
+// [Files] amiusb.c, amiusb.h, ehci.c, ohci.c, uhci.c, usb.c,
+// usbCCID.c, usbdef.h, usbhub.c, usbkbd.c, usbmass.c, usbms.c,
+// usbpoint.c, amiusbhc.c, efiusbhid.c, usbbus.c, usbbus.h
+//
+// 14 9/04/12 6:15a Ryanchou
+// [TAG] EIP99123
+// [Category] Improvement
+// [Description] Roll back EIP79221 changes that has device
+// compatibility issue.
+// [Files] usbbus.c, usbbus.h
+//
+// 13 5/04/12 5:33a Wilsonlee
+// [TAG] EIP89307
+// [Category] Improvement
+// [Description] Modify incorrect #pragma pack directive.
+// [Files] amidef.h, amiusb.c, ehci.h, ohci.c, ohci.h, uhci.h, usb.c,
+// usbdef.h, xhci.h, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h,
+// UsbIo.h
+//
+// 12 1/31/12 12:35a Roberthsu
+// [TAG] EIP79221
+// [Category] Improvement
+// [Description] Add get serial number and product string descriptor.
+// [Files] usbbus.c,usbbus.h
+//
+// 11 1/13/12 4:27a Ryanchou
+// [TAG] EIP47348
+// [Category] New Feature
+// [Description] Support for USB Port Reset function.
+// [Files] amiusb.c, amiusb.h, amiusbhc.c, uhci.c, usb.c, usbbus.c,
+// usbbus.h, usbmass.c
+//
+// 10 2/16/11 5:20p Olegi
+// [TAG] EIP53956
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] UsbIo Control/Bulk/Interrupt transfers fail because
+// GetEndpointDesc() returns incorrect end point
+// [RootCause] The macro COMPRESS_EP_ADR will cause data to be
+// overwritten in the a2endpoint array of the DEVGROUP_T structure.
+// [Solution] Redefine COMPRESS_EP_ADR macro as:
+// #define COMPRESS_EP_ADR(a) ( a & 0xF )
+// [Files] usbbus.h
+//
+// 9 9/05/08 4:14p Olegi
+//
+// 8 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 7 3/20/07 1:29p Olegi
+//
+// 5 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 4 6/15/05 1:59p Andriyn
+// Comments were changed
+//****************************************************************************
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbBus.h
+//
+// Description: AMI USB bus driver header file
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef _USBBUS_INC_
+#define _USBBUS_INC_
+#include "tree.h"
+
+
+#define USB_MAXLANID 16
+#define USB_MAXCHILDREN 8
+#define USB_MAXCONTROLLERS 4
+
+#define USB_US_LAND_ID 0x0409
+
+//
+// Forward declaring
+//
+struct usb_io_device;
+typedef struct _EFI_USB2_HC_PROTOCOL EFI_USB2_HC_PROTOCOL;
+
+#pragma pack(push, 1)
+
+typedef struct {
+ UINT8 Length;
+ UINT8 DescriptorType;
+} USB_DESCRIPTOR_T;
+
+typedef struct {
+ UINT8 len;
+ UINT8 desctype;
+ UINT16 langID[1];
+} lang_table_t;
+
+typedef struct {
+ UINT8 address;
+ EFI_USB_ENDPOINT_DESCRIPTOR* desc;
+} endpoint_t;
+
+#pragma pack(pop)
+
+enum node_type_enum { NodeHC, NodeDevice, NodeGroup };
+
+
+typedef struct {
+ int type;
+ EFI_HANDLE handle; // handle of the controller
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ EFI_USB2_HC_PROTOCOL *hc; // USB_HC_ installed on controller
+} usbbus_data_t;
+
+typedef struct _USBBUS_HC_T {
+ int type;
+ EFI_HANDLE handle; // handle of the controller
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ EFI_USB2_HC_PROTOCOL *hc; // USB_HC_ installed on controller
+ HC_STRUC *hc_data;
+ TREENODE_T node;
+} USBBUS_HC_T;
+
+#define COMPRESS_EP_ADR(a) ( a & 0xF )
+
+typedef struct _DEVGROUP_T {
+ int type;
+ EFI_HANDLE handle; // handle of the controller
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ EFI_USB2_HC_PROTOCOL *hc; // USB_HC_ that the controller is attached to
+ DEV_INFO *dev_info;
+ HC_STRUC *hc_info;
+ lang_table_t *lang_table;
+ EFI_USB_STRING_DESCRIPTOR *ManufacturerStrDesc;
+ EFI_USB_STRING_DESCRIPTOR *ProductStrDesc;
+ EFI_USB_STRING_DESCRIPTOR *SerialNumberStrDesc;
+ EFI_USB_DEVICE_DESCRIPTOR dev_desc;
+ EFI_USB_CONFIG_DESCRIPTOR **configs;
+ endpoint_t endpoints[0x20];
+ EFI_USB_ENDPOINT_DESCRIPTOR* a2endpoint[0x20];
+ int endpoint_count;
+
+ int active_config; // index in configs
+ int config_count;
+ int f_DevDesc;
+ TREENODE_T node;
+} DEVGROUP_T;
+
+typedef struct _USBDEV_T {
+ int type;
+ EFI_HANDLE handle; // handle of the controller
+ EFI_DEVICE_PATH_PROTOCOL *dp;
+ EFI_USB2_HC_PROTOCOL *hc; //USB_HC_ that the controller is attached to
+ DEV_INFO *dev_info;
+ HC_STRUC *hc_info;
+ //UINT8 toggle; //toggle param for bulk transfer
+ CHAR16* name;
+ int f_connected; //was ConnectControllers successful?
+ int first_endpoint;
+ int end_endpoint;
+ EFI_USB_INTERFACE_DESCRIPTOR* descIF;
+ UINT8 speed;
+ EFI_USB_IO_PROTOCOL io;
+ TREENODE_T node;
+ int async_endpoint;
+} USBDEV_T;
+
+
+
+EFI_STATUS UsbBusSupported (
+ EFI_DRIVER_BINDING_PROTOCOL *pThis,
+ EFI_HANDLE controller,
+ EFI_DEVICE_PATH_PROTOCOL * );
+
+EFI_STATUS UsbBusStart (
+ EFI_DRIVER_BINDING_PROTOCOL *pThis,
+ EFI_HANDLE controller,
+ EFI_DEVICE_PATH_PROTOCOL * );
+
+EFI_STATUS UsbBusStop (
+ EFI_DRIVER_BINDING_PROTOCOL *pThis,
+ EFI_HANDLE controller,
+ UINTN NumberOfChildren,
+ EFI_HANDLE *ChildHandleBuffer );
+
+EFI_STATUS UsbBusInit(EFI_HANDLE ImageHandle,EFI_HANDLE ServiceHandle);
+
+USBDEV_T* UsbIo2Dev(EFI_USB_IO_PROTOCOL* p);
+
+UINT8*
+UsbSmiGetDescriptor(
+ HC_STRUC* Hc,
+ DEV_INFO* Dev,
+ UINT8* Buf,
+ UINT16 Len,
+ UINT8 DescType,
+ UINT8 DescIndex
+);
+
+UINT16
+UsbSmiControlTransfer (
+ HC_STRUC* HCStruc,
+ DEV_INFO* DevInfo,
+ UINT16 Request,
+ UINT16 Index,
+ UINT16 Value,
+ UINT8 *Buffer,
+ UINT16 Length
+);
+
+UINT8
+UsbResetAndReconfigDev(
+ HC_STRUC* HostController,
+ DEV_INFO* Device
+);
+
+UINT8
+UsbDevDriverDisconnect(
+ HC_STRUC* HostController,
+ DEV_INFO* Device
+);
+
+#define GETBIT(bitarray,value,bit) \
+ ((value) = (UINT8)(((bitarray) & (1 << (bit)))>>(bit)))\
+
+#define SETBIT(bitarray,value,bit) \
+ (bitarray) = (((bitarray) & ~(1 << (bit))) | (((value)&1) << (bit)) )\
+
+#define IsSlow(dev) dev->speed
+#define GetSpeed(dev) dev->speed
+
+VOID InstallDevice(DEV_INFO* DevInfo);
+int eUninstallDevice(VOID* Node, VOID* Context);
+EFI_STATUS RemoveDevInfo(DEV_INFO* pDevInfo);
+
+
+#endif //_USBBUS_INC_
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2008, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/usbmisc.c b/Core/EM/usb/usbmisc.c
new file mode 100644
index 0000000..1af8304
--- /dev/null
+++ b/Core/EM/usb/usbmisc.c
@@ -0,0 +1,582 @@
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
+
+//****************************************************************************
+// $Header: /Alaska/SOURCE/Modules/USB/ALASKA/usbmisc.c 28 10/16/16 10:18p Wilsonlee $
+//
+// $Revision: 28 $
+//
+// $Date: 10/16/16 10:18p $
+//****************************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Modules/USB/ALASKA/usbmisc.c $
+//
+// 28 10/16/16 10:18p Wilsonlee
+// [TAG] EIP288158
+// [Category] Improvement
+// [Description] Check if gUsbData is integrity.
+// [Files] amiusb.cif, usbsb.c, AmiUsbLib.cif, AmiUsbLib.sdl,
+// AmiUsbSmmGlobalDataValidationLib.c,
+// AmiUsbSmmGlobalDataValidationLib.cif,
+// AmiUsbSmmGlobalDataValidationLib.mak, Crc32.c, amiusb.c, amiusb.h,
+// ehci.c, elib.c, ohci.c, syskbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h,
+// usbhid.c, usbhub.c, usbkbd.c, usbmass.c, usbms.c, usbrt.mak, xhci.c,
+// amiusbhc.c, efiusbccid.c, efiusbmass.c, uhcd.c, usbmisc.c,
+// AmiUsbController.h, AmiUsbLibInclude.cif,
+// AmiUsbSmmGlobalDataValidationLib.h
+//
+// 27 7/07/16 1:12a Wilsonlee
+// [TAG] EIP277810
+// [Category] Improvement
+// [Description] Validate the memory buffer is entirely outside of SMM.
+// [Files] usbsb.c, amiusb.c, ehci.c, ohci.c, uhci.c, usbCCID.c,
+// usbdef.h, usbmass.c, xhci.c, amiusbhc.c, efiusbccid.c, efiusbmass.c,
+// uhcd.c, uhcd.h, usbmisc.c
+//
+// 26 4/29/15 7:00a Wilsonlee
+// [TAG] EIP215978
+// [Category] Improvement
+// [Description] Remove "TotalSize" parameter from
+// AlignPhysicalAddress() .
+// [Files] usbmisc.c
+//
+// 25 4/03/14 3:44a Wilsonlee
+// [TAG] EIP156742
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] System hang at 0x9C during DC cycle test under RHEL6.5
+// UEF.I
+// [RootCause] The hw smi may be triggered when we reallocate memory for
+// gUsbData->HcTable.
+// [Solution] Assign the new memory space to gUsbData->HcTable before we
+// free the old.
+// [Files] uhcd.c, uhcd.h, usbmisc.c
+//
+// 24 3/19/13 4:00a Ryanchou
+// [TAG] EIP118177
+// [Category] Improvement
+// [Description] Dynamically allocate HCStrucTable at runtime.
+// [Files] usb.sdl, usbport.c, usbsb.c, amiusb.c, ehci.c, ohci.c,
+// syskbc.c, sysnokbc.c, uhci.c, usb.c, usbCCID.c, usbdef.h, usbhid.c,
+// usbhub.c, usbmass.c, usbrt.mak, usb.sd, amiusbhc.c, efiusbccid.c,
+// efiusbhid.c, efiusbmass.c, efiusbms.c, uhcd.c, uhcd.h, uhcd.mak,
+// usbmisc.c, usbsrc.sdl
+//
+// 23 1/11/13 4:19a Ryanchou
+// [TAG] EIP102491
+// [Category] Improvement
+// [Description] Synchronized with Aptio V USB module
+// [Files] usbport.c, usbsb.c, ehci.c, ehci.h, ohci.c, ohci.h, uhci.h,
+// usb.c, usbdef.h, usbhid.c, usbhub.c, usbkbd.c, usbkbd.h, usbmass.c.
+// usbms.c, usbpoint.c, xhci.h, usb.sd, amiusbhc.c, componentname.c,
+// efiusbkc.c, efiusbmass.c, uhcd.c, uhcd.h, usbbus.c, usbbus.h, usbmisc.c
+//
+// 22 8/29/12 8:37a Ryanchou
+// [TAG] EIP77262
+// [Category] New Feature
+// [Description] Remove SMM dependency of USB.
+// [Files] usb.sdl, usbport.c, amiusb.c, amiusb.dxs, amiusb.h, ehci.c,
+// elib.c, ohci.c, uhci.c, usb.c, usbdef.h, usbrt.mak, xhci.c, amiusbhc.c,
+// efiusbccid.c, efiusbhid.c, efiusbkb.c, efiusbmass.c, uhcd.c, uhcd.dxs,
+// uhcd.h, usbmisc.c, AmiUsbController.h
+//
+// 21 5/04/12 6:43a Ryanchou
+// [TAG] EIP82875
+// [Category] Improvement
+// [Description] Support start/stop individual USB host to avoid
+// reconnect issues.
+// [Files] usbport.c, usbsb.c, amiusb.c, amiusb.h, ehci.c, ohci.c,
+// uhci.c, uhci.h, usb.c, usbdef.h, xhci.c, amiusbhc.c, uhcd.c, uhcd.h,
+// usbbus.c, usbmisc.c
+//
+// 20 11/08/11 1:59a Ryanchou
+// [TAG] EIP63188
+// [Category] Improvement
+// [Description] External USB controller support.
+// [Files] amidef.h, amiusb.c, ehci.c, ohci.c, uhcd.c, uhcd.h, uhci.c,
+// usbdef.h, usbmisc.c, usbsb.c, xhci.c
+//
+// 19 7/13/11 4:11a Ryanchou
+// [TAG] EIP59332
+// [Category] Improvement
+// [Description] Modified the Stop function for UHCD and USBBUS to
+// properly stop devices and uninstall the protocols.
+// [Files] uhcd.c, uhcd.h, uhci.c, usbbus.c, UsbInt13.c, usbmisc.c
+//
+// 18 4/06/11 3:25a Tonylo
+// [TAG] EIP57354
+// [Category] Improvement
+// [Description] Core 4.6.5.0 compliant. UEFI 2.3 and PI 1.x support.
+//
+// 17 2/07/11 12:44p Olegi
+// [TAG] EIPN/A
+// [Category] Bug Fix
+// [Severity] Important
+// [Symptom] Memory corruption in 32-bit mode
+// [RootCause] AllocatePages updates 64-bit variable with the allocated
+// address; in case of 32-bit project VOID* can not be passed - it will
+// cause memory corruption.
+// [Solution] Use EFI_PHYSICAL_ADDRESS instead of VOID* for memory
+// allocation address.
+// [Files] usbmisc.c
+//
+// 16 10/30/09 5:48p Olegi
+//
+// 15 10/09/09 5:57p Olegi
+//
+// 14 2/05/09 2:53p Olegi
+// Bugfix in AllocateAlignedMemory, size of the block is made 4K aligned
+// for VTD. EIP#14470.
+//
+// 13 7/04/08 1:02p Olegi
+// AllocAlignedMemory allocates the 4K aligned block for global USB data
+// area.
+//
+// 12 5/16/08 12:02p Olegi
+// Compliance with AMI coding standard.
+//
+// 11 8/14/07 11:24a Olegi
+//
+// 10 8/09/07 3:52p Artems
+// Added VT-d support - USB controllers use one continuous region of
+// memory
+//
+// 9 7/09/07 2:12p Olegi
+// Changed the maximum data size of the BulkTransfer from 1kB to 64kB.
+//
+//
+// 8 3/20/07 1:29p Olegi
+//
+// 6 4/14/06 6:41p Olegi
+//
+// 5 3/20/06 3:37p Olegi
+// Version 8.5 - x64 compatible.
+//
+// 4 5/20/05 11:04a Andriyn
+// reconcile Aptio changes with Alaska
+//
+// 3 5/19/05 8:06p Olegi
+// Aptio changes in driver 8.1 implementation.
+//
+// 2 5/10/05 4:13p Andriyn
+// USBBUS implementation
+//
+// 1 3/28/05 6:20p Olegi
+//
+// 1 3/15/05 9:23a Olegi
+// Initial VSS check-in.
+//
+//****************************************************************************
+
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: UsbMisc.c
+//
+// Description: AMI USB driver miscellaneous routines
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include "Efi.h"
+
+#include "amidef.h"
+#include "usbdef.h"
+#include "uhcd.h"
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+#include <Protocol\SmmControl2.h>
+
+EFI_SMM_CONTROL2_PROTOCOL *gSmmCtl = NULL;
+#else
+#include <Protocol\SmmControl.h>
+
+EFI_SMM_CONTROL_PROTOCOL *gSmmCtl = NULL;
+#endif
+#endif
+
+BOOLEAN gFirstCall = TRUE;
+VOID *gGlobalPointer;
+VOID *gStartPointer;
+VOID *gEndPointer;
+
+extern USB_GLOBAL_DATA *gUsbData;
+extern EFI_USB_PROTOCOL *gAmiUsbController;
+
+#if USB_RUNTIME_DRIVER_IN_SMM
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: USBGenerateSWSMI
+//
+// Description: Generates SW SMI using global SmmCtl pointer.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+USBGenerateSWSMI (
+ UINT8 Data
+)
+{
+ //(EIP57354)>
+ EFI_STATUS Status;
+ UINT8 SwSmiValue = Data;
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ UINT8 DataSize = 1;
+#else
+ UINTN DataSize = 1;
+#endif
+
+ if (gSmmCtl == NULL) {
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ Status = gBS->LocateProtocol(&gEfiSmmControl2ProtocolGuid, NULL, &gSmmCtl);
+#else
+ Status = gBS->LocateProtocol(&gEfiSmmControlProtocolGuid, NULL, &gSmmCtl);
+#endif
+ if (EFI_ERROR(Status)){
+ return;
+ }
+ }
+ //<(EIP57354)
+ gSmmCtl->Trigger(gSmmCtl, &SwSmiValue, &DataSize, 0, 0);
+}
+#endif
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: InvokeUsbApi
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+InvokeUsbApi(
+ URP_STRUC *Urp
+)
+{
+#if USB_RUNTIME_DRIVER_IN_SMM
+ UINTN Temp;
+
+ Temp = (UINTN)gUsbData->fpURP;
+ gUsbData->fpURP = Urp;
+
+ USBGenerateSWSMI (USB_SWSMI);
+
+ gUsbData->fpURP = (URP_STRUC*)Temp;
+
+#else
+ EFI_TPL OldTpl;
+ OldTpl = gBS->RaiseTPL(TPL_NOTIFY);
+
+ if (gAmiUsbController->UsbInvokeApi) {
+ gAmiUsbController->UsbInvokeApi(Urp);
+ }
+ gBS->RestoreTPL(OldTpl);
+#endif
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: MemFill
+//
+// Description: Fills the specified amount of memory with specified data
+// starting from the specified address.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+MemFill (
+ UINT8* Ptr,
+ UINT32 Size,
+ UINT8 Value
+)
+{
+ UINT32 Count;
+
+ // Check for pointer validity
+ if (Ptr == NULL) return;
+ for(Count = 0; Count < Size; Count++) {
+ Ptr[Count] = Value;
+ }
+ return;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AlignPhysicalAddress
+//
+// Description: Returns the aligned address.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINTN
+AlignPhysicalAddress(
+ UINTN PhyAddress,
+ UINT16 AlignSize
+)
+{
+ UINTN AlignAddr;
+
+ USB_DEBUG(DEBUG_LEVEL_7, "Un-aligned address : %lX\n", PhyAddress);
+ if ((PhyAddress % AlignSize) != 0) {
+ AlignAddr = PhyAddress - (PhyAddress % (UINT32)AlignSize) + AlignSize;
+ }
+ else {
+ AlignAddr = PhyAddress;
+ }
+ USB_DEBUG(DEBUG_LEVEL_7, "Aligned address : %lX\n", AlignAddr);
+
+ return AlignAddr;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AllocAlignedMemory
+//
+// Description: Allocates memory with the given alignment.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID*
+AllocAlignedMemory (
+ UINT32 AllocSize,
+ UINT16 Align
+)
+{
+ UINTN Ptr;
+ UINT32 Size;
+ EFI_STATUS Status;
+ EFI_PHYSICAL_ADDRESS MemAddress;
+
+ if (AllocSize == 0) return NULL;
+ //
+ // If this is the first time the function is called,
+ // allocate the USB memory and make the size 4K aligned (VTD).
+ //
+ if(gFirstCall) {
+ gFirstCall = FALSE; // Make sure to only allocate once.
+ Size = CalculateMemorySize(); // Determine total required size.
+ Size = (Size + 0x1000) >> 12; // Express Size in pages.
+ //
+ // Allocate and zero memory in pages.
+ //
+ MemAddress = 0xFFFFFFFF;
+ Status = gBS->AllocatePages(AllocateMaxAddress, EfiRuntimeServicesData,
+ Size, &MemAddress);
+ ASSERT_EFI_ERROR(Status);
+
+ gGlobalPointer = (VOID*)(UINTN)MemAddress;
+ MemFill (gGlobalPointer, (Size << 12), 0); // Have to express size in bytes for MemFill()
+ //
+ // Save pointers to beginning and end of region.
+ //
+ gStartPointer = gGlobalPointer;
+ gEndPointer = (VOID *)((UINTN)gGlobalPointer + (Size << 12) - 1);
+ }
+
+ //USB_DEBUG(DEBUG_LEVEL_6, "Unaligned : %Fp, %X, %X\n", gGlobalPointer, AllocSize, Align);
+ Ptr = AlignPhysicalAddress( (UINTN)gGlobalPointer, Align);
+ //USB_DEBUG(DEBUG_LEVEL_6, "Aligned : %Fp, %X, %X\n", Ptr, AllocSize, Align);
+
+ gGlobalPointer = (VOID*)(Ptr + AllocSize);
+
+ if (gGlobalPointer < gEndPointer)
+ {
+ return (VOID*)Ptr;
+ }
+ return NULL;
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: AllocateHcMemory
+//
+// Description: Allocates a number of pages with the given alignment.
+//
+// Note: The minimum alignment passed to this function is CPU page, 4K
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID *
+AllocateHcMemory (
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINTN Pages,
+ IN UINTN Alignment
+)
+{
+ EFI_STATUS Status;
+ VOID *Memory;
+ UINTN AlignedMemory;
+ UINTN AlignmentMask;
+ UINTN UnalignedPages;
+ UINTN RealPages;
+
+ //
+ // Alignment must be a power of two or zero.
+ //
+ ASSERT ((Alignment & (Alignment - 1)) == 0);
+
+ if (Pages == 0) {
+ return NULL;
+ }
+ if (Alignment > EFI_PAGE_SIZE) {
+ //
+ // Caculate the total number of pages since alignment is larger than page size.
+ //
+ AlignmentMask = Alignment - 1;
+ RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);
+ //
+ // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
+ //
+ ASSERT (RealPages > Pages);
+
+ Memory = (VOID*)0xFFFFFFFF;
+ Status = PciIo->AllocateBuffer (PciIo, AllocateMaxAddress, EfiRuntimeServicesData, RealPages,
+ &Memory, 0);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;
+ UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);
+ if (UnalignedPages > 0) {
+ //
+ // Free first unaligned page(s).
+ //
+ Status = PciIo->FreeBuffer(PciIo, UnalignedPages, Memory);
+ ASSERT_EFI_ERROR (Status);
+ }
+ Memory = (VOID*)(AlignedMemory + EFI_PAGES_TO_SIZE (Pages));
+ UnalignedPages = RealPages - Pages - UnalignedPages;
+ if (UnalignedPages > 0) {
+ //
+ // Free last unaligned page(s).
+ //
+ Status = PciIo->FreeBuffer(PciIo, UnalignedPages, Memory);
+ ASSERT_EFI_ERROR (Status);
+ }
+ } else {
+ //
+ // Do not over-allocate pages in this case.
+ //
+ Memory = (VOID*)0xFFFFFFFF;
+ Status = PciIo->AllocateBuffer (PciIo, AllocateMaxAddress, EfiRuntimeServicesData, Pages,
+ &Memory, 0);
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ }
+ AlignedMemory = (UINTN) Memory;
+ }
+ return (VOID*) AlignedMemory;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: FreeHcMemory
+//
+// Description: Free the memory allocated by AllocateHcMemory().
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID
+FreeHcMemory(
+ IN EFI_PCI_IO_PROTOCOL *PciIo,
+ IN UINTN Pages,
+ IN VOID* Memory
+)
+{
+ EFI_STATUS Status;
+
+ Status = PciIo->FreeBuffer(PciIo, Pages, Memory);
+ ASSERT_EFI_ERROR(Status);
+ return;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: ReallocateMemory
+//
+// Description:
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS
+ReallocateMemory (
+ IN UINTN OldSize,
+ IN UINTN NewSize,
+ IN VOID **OldBuffer
+)
+{
+ EFI_STATUS Status;
+ VOID *NewBuffer = NULL;
+ VOID *FreeBuffer = NULL;
+
+ if (OldBuffer == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Status = gBS->AllocatePool (EfiRuntimeServicesData, NewSize, &NewBuffer);
+ if (EFI_ERROR(Status)) {
+ return Status;
+ }
+
+ gBS->SetMem(NewBuffer, NewSize, 0);
+
+ if (OldSize > 0 && *OldBuffer != NULL) {
+ gBS->CopyMem(NewBuffer, *OldBuffer, (OldSize < NewSize) ? OldSize : NewSize);
+ FreeBuffer = *OldBuffer;
+ }
+
+ *OldBuffer = NewBuffer;
+
+ if (FreeBuffer != NULL) {
+ gBS->FreePool(FreeBuffer);
+ }
+ return EFI_SUCCESS;
+}
+
+//****************************************************************************
+//****************************************************************************
+//** **
+//** (C)Copyright 1985-2016, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone (770)-246-8600 **
+//** **
+//****************************************************************************
+//****************************************************************************
diff --git a/Core/EM/usb/usbsrc.sdl b/Core/EM/usb/usbsrc.sdl
new file mode 100644
index 0000000..e9d2b63
--- /dev/null
+++ b/Core/EM/usb/usbsrc.sdl
@@ -0,0 +1,368 @@
+TOKEN
+ Name = "USBSRC"
+ Value = "1"
+ Help = "Main switch to enable AMI USB source files."
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_KBD"
+ Value = "1"
+ Help = "Enable/disable support for USB keyboards"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_MOUSE"
+ Value = "1"
+ Help = "Enable/disable support for USB mice.\Note: This switch is not valid if USB_DEV_KBD is Off."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_HUB"
+ Value = "1"
+ Help = "Enable/disable support for USB hubs"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_MASS"
+ Value = "1"
+ Help = "Enable/disable support for USB storage devices"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_POINT"
+ Value = "1"
+ Help = "Enable/disable support for USB point device"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "CORE_COMBINED_VERSION" ">=" "0x040281"
+End
+
+TOKEN
+ Name = "MEM_PAGE_COUNT"
+ Value = "8"
+ Help = "Number of memory pages"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_SEND_COMMAND_TO_KBC"
+ Value = "0x60"
+ Help = "Some keyboard controllers will lock if send command (60h) is used. \Change this value to either 0D1h (for SiS based keyboard controllers) \or 0D4h depending on your need."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_MOUSE_UPDATE_EBDA_DATA"
+ Value = "1"
+ Help = "Enables the direct update of EBDA from USB mouse driver. \Note that enabling this flag may cause a failure of those DOS mouse drivers that trap INT74 and do not use EBDA."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "EHCI_64BIT_DATA_STRUCTURE"
+ Value = "1"
+ Help = "Enables/Disables EHCI 64bit data structures. \Consult the chipset documents before enabling or disabling this value."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "EHCI_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "EHCI_ASYNC_BELL_SUPPORT"
+ Value = "0"
+ Help = "Enables the EHCI interrupt on Asynchornous Advance feature.\For certain EHCI controllers this option has to be enabled."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "EHCI_SUPPORT" "=" "1"
+End
+
+TOKEN
+ Name = "USB_DEV_HID_COUNT"
+ Value = "15"
+ Help = "Specifies the max number of USB HID devices (keyboard/mouse) present in the system. This equate is used to create necessary data structure"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_HUB_COUNT"
+ Value = "12"
+ Help = "Specifies the max number of USB HUB devices present in the system. \Note: the number of the hubs in the chain (connected one after another) can not exceed 5 according to USB specification."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_MASS_COUNT"
+ Value = "6"
+ Help = "Specify the maximum number of USB mass devices present at a time. This equate is used to create data\structure. Modify USB.SSP and USBSB.ASM file depending on the value specified here.\Currently the max value is 16. If more devices need to be supported then INT13PNP.EQU has to be changed (USB_Header_count)."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_CCID"
+ Value = "0"
+ Help = "Enable/disable support for USB CCID devices"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_CCID_COUNT"
+ Value = "6"
+ Help = "Specifies the max number of USB CCID devices present in the system. This equate is used to create necessary data structure"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "USE_T0_T1_PROTOCOL"
+ Value = "1"
+ Help = "0 for T0 and 1 for T1. Used to select T0/T1 when CCID can support both T0 and T1"
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "CCID_USE_INTERRUPT_INSERTION_REMOVAL"
+ Value = "1"
+ Help = "0: Disable, 1 : Enable. Some SMARTD Card readers don't generate interrupt when card is insert/removed even though they declare it supported."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "USB_DEV_UNSUPPORTED"
+ Value = "16"
+ Help = "Specify the maximum number of USB devices that may be connected and not supported by this driver. A placeholder will be created for these devices so that they can be started by other device drivers."
+ TokenType = Integer
+ TargetH = Yes
+ Lock = Yes
+End
+
+TOKEN
+ Name = "USB_START_UNIT_BEFORE_MSD_ENUMERATION"
+ Value = "0"
+ Help = "Enables/disables execution of START_STOP_UNIT command before accessing the mass storage device."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "DEBUG_SWITCH"
+ Value = "0"
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_CODE" "=" "1"
+End
+
+TOKEN
+ Name = "TopDebugLevel"
+ Value = "3"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BottomDebugLevel"
+ Value = "3"
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_SWSMI"
+ Value = "0x31"
+ Help = "Data to be written to SW SMI port to invoke USB SW SMI handler."
+ TokenType = Integer
+ TargetEQU = Yes
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_BEEP_ENABLE"
+ Value = "1"
+ Help = "Enables/disables sounds on USB devices connection or removal."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "BEEP_ENABLE" "=" "1"
+End
+
+TOKEN
+ Name = "USB_MASS_EMULATION_NATIVE"
+ Value = "1"
+ Help = "Changes the policy of 'Auto' option of USB Mass storage devices emulation.\0 - 'Auto' makes an attempt to emulate a device with valid partition as floppy.\1- 'Auto' emulates devices depending on the media format: devices with valid partition table will be hard disks, otherwise floppies. Optical drives or drives without media will be emulated according to the type of device."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_MASS_EMULATION_FOR_NO_MEDIA"
+ Value = "1"
+ Help = "Determine the USB mass storage device emulation type without media.\0 - 'Auto' makes an attempt to emulate a device without media as floppy.\1 - 'Auto' makes an attempt to emulate a device without media as hard disk.\Optical drives and floppies without media will be emulated according to the type of device."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_MASS_EMULATION_BY_SIZE"
+ Value = "0"
+ Help = "Determine the USB mass storage device emulation type by size only."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "USB_MASS_EMULATION_NATIVE" "=" "0"
+End
+
+TOKEN
+ Name = "MAX_SIZE_FOR_USB_FLOPPY_EMULATION"
+ Value = "530"
+ Help = "If the device size is less than it assume FDD or else assume the emulation as HDD.\This token is valid when set USB_MASS_EMULATION_SIZE to On or set USB_MASS_EMULATION_NATIVE to Off.\The unit is MB."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REMOVE_USB_STORAGE_FROM_BBS_IF_NO_MEDIA"
+ Value = "0"
+ Help = "This token control whether USB storage devices report to BBS depend on media present or not."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "REMOVE_CHECK_FOR_USB_FLOPPY_DRIVE"
+ Value = "0"
+ Help = "This token control whether USB FLOPPY drives report to BBS depend on media present or not."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "REMOVE_USB_STORAGE_FROM_BBS_IF_NO_MEDIA" "!=" "0"
+End
+
+TOKEN
+ Name = "HIGHSPEED_MAX_BULK_DATA_SIZE"
+ Value = "0x4000"
+ Help = "Maximum amount of data per EHCI BulkTransfer.\Note: If additional space is needed in USB data segment, the value can be changed to 0x200 without significant decrease in mass storage data transfer performance."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "FULLSPEED_MAX_BULK_DATA_SIZE_PER_FRAME"
+ Value = "896"
+ Help = "Maximum amount of bulk data transferred by OHCI/UHCI controller within one millisecond frame.\Note: full speed device limit is ~1kB/ms; there should be a window left for processing the TD. The optimal size for 64 Bytes endpoint is 896 Bytes (14 transfers per millisecond). This value can not be less than MaxPkt size of Bulk endpoint (typically 64 Bytes)."
+ TokenType = Integer
+ TargetH = Yes
+ Range = "64-960"
+End
+
+TOKEN
+ Name = "EXTRA_CHECK_DEVICE_READY"
+ Value = "0"
+ Help = "This token controls the execution of the fix for EIP#15037. The USBMassCheckDeviceReady call in Mass Storage read/write functions is controlled by this token."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_HID_KEYREPEAT_USE_SETIDLE"
+ Value = "0"
+ Help = "0-Use periodic SMI for key repeat 1-Use Set Idle command to implement Key Repeat action."
+ TokenType = Integer
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "USB_EFIMS_DIRECT_ACCESS"
+ Value = "0"
+ Help = "Setting this flag changes the behavior of EFI mouse driver: instead of using periodic TD for polling mouse data, EFI_SIMPLE_POINTER_PROTOCOL.GetState will execute IN transaction on a mouse device.\Note: this flag does not affect legacy mouse support, it only affects mouse operation under EFI."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "BOOT_PROTOCOL_SUPPORT"
+ Value = "0"
+ Help = "Use boot protocol.If enable,it will not get report protocol"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "CLEAR_USB_KB_BUFFER_AT_READYTOBOOT"
+ Value = "0"
+ Help = "ON -> USB KB Buffer will be cleared at ReadyToBoot.\OFF -> USB KB Buffer will not be cleared at ReadyToBoot."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SKIP_CARD_READER_CONNECT_BEEP_IF_NO_MEDIA"
+ Value = "0"
+ Help = "Disables sounds on USB card reader connection if no media present."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "PCH_EHCI_OWNERSHIP_CHANGE_MECHANISM"
+ Value = "0"
+ Help = "EHCI ownership change mechanism for Intel PCH."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "LEGACY_USB_DISABLE_FOR_USB_MASS"
+ Value = "0"
+ Help = "When legacy usb support disable.\If this token set 'OFF'.\Usb mass can work under uefi application.\\"
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "XHCI_COMPLIANCE_MODE_WORKAROUND"
+ Value = "1"
+ Help = "For some misbehaving USB 3.0 devices, we add the workaround that check the port link before reset the host controller, then a hot port reset is issued for that port while the link is in the compliance mode."
+ TokenType = Boolean
+ TargetH = Yes
+End
+
+TOKEN
+ Name = "SHOW_SKIP_PORT_INFORMATION"
+ Value = "0"
+ Help = "Token DEBUG_CODE and DEBUG_SWITCH need open.\Serach tag SHOW_SKIP_PORT_INFORMATION."
+ TokenType = Boolean
+ TargetH = Yes
+ Token = "DEBUG_CODE" "=" "1"
+ Token = "DEBUG_SWITCH" "=" "1"
+End
+
+TOKEN
+ Name = "EFI_USB_HC_INTERRUPT_OUT_SUPPORT"
+ Value = "0"
+ Help = "This token control whether support EFI_USB2_HC_PROTOCOL.AsyncInterruptTransfer and EFI_USB2_HC_PROTOCOL.SyncInterruptTransfer() on OUT endpoints.\According to the UEFI spec 2.3.1, EFI_INVALID_PARAMETER is returned if Data transfer direction indicated by EndPointAddress is other than EfiUsbDataIn, so AsyncInterruptTransfer_Conf and SyncInterruptTransfe of the SCT are failed if we enable this token."
+ TokenType = Boolean
+ TargetH = Yes
+End \ No newline at end of file
diff --git a/Core/EdkLib.c b/Core/EdkLib.c
new file mode 100644
index 0000000..3b0dae0
--- /dev/null
+++ b/Core/EdkLib.c
@@ -0,0 +1,627 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/EdkLib.c 4 5/19/11 2:31p Artems $
+//
+// $Revision: 4 $
+//
+// $Date: 5/19/11 2:31p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/EdkLib.c $
+//
+// 4 5/19/11 2:31p Artems
+// EIP 60634: fixed bug in function IsHexDigit
+//
+// 3 5/13/11 5:09p Artems
+// Functions CopyMem and ZeroMem moved to EdkII library
+//
+// 2 2/05/11 3:25p Artems
+// Added EDK library functions CopyMem and ZeroMem
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EdkLib.h
+//
+// Description: This file contains implementation for EDK library routines.
+// It's provided for EDK compatibility.
+// Whenever possible EDK routines implemented as a wrappers around AMI library routines.
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <AmiLib.h>
+#include <Tiano.h>
+#include <EfiCommonLib.h>
+#include EFI_GUID_DEFINITION(StatusCodeDataTypeId)
+
+UINTN ASPrint(
+ OUT CHAR8 *Buffer, IN UINTN BufferSize,
+ IN CONST CHAR8 *Format, ...
+)
+{
+ va_list ArgList = va_start(ArgList,Format);
+ UINTN Ret = Sprintf_s_va_list(Buffer,BufferSize,(CHAR8*)Format,ArgList);
+ va_end(ArgList);
+ return Ret;
+}
+
+UINTN AvSPrint(
+ OUT CHAR8 *StartOfBuffer, IN UINTN StrSize,
+ IN CONST CHAR8 *Format, IN VA_LIST Marker
+)
+{
+ return Sprintf_s_va_list(StartOfBuffer,StrSize,(CHAR8*)Format,Marker);
+}
+
+EFI_STATUS EfiInitializeCommonDriverLib (
+ IN EFI_HANDLE ImageHandle, IN VOID *SystemTable
+)
+{
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS EfiCommonIoRead (
+ IN UINT8 Width, IN UINTN Address,
+ IN UINTN Count, IN OUT VOID *Buffer
+)
+{
+ return IoRead(Width, Address, Count, Buffer);
+}
+
+EFI_STATUS EfiCommonIoWrite (
+ IN UINT8 Width, IN UINTN Address,
+ IN UINTN Count, IN OUT VOID *Buffer
+)
+{
+ return IoWrite(Width, Address, Count, Buffer);
+}
+/*
+EFI_STATUS EfiCommonPciRead (
+ IN UINT8 Width, IN UINT64 Address,
+ IN UINTN Count, IN OUT VOID *Buffer
+)
+{
+ //TODO:
+ return EFI_UNSUPPORTED;
+}
+
+EFI_STATUS EfiCommonPciWrite (
+ IN UINT8 Width, IN UINT64 Address,
+ IN UINTN Count, IN OUT VOID *Buffer
+)
+{
+ //TODO:
+ return EFI_UNSUPPORTED;
+}
+*/
+
+BOOLEAN EfiCompareGuid (IN EFI_GUID *Guid1,IN EFI_GUID *Guid2)
+{
+ return !MemCmp(Guid1,Guid2,sizeof(EFI_GUID));
+}
+
+VOID EfiCommonLibSetMem(
+ IN VOID *Buffer, IN UINTN Size, IN UINT8 Value
+)
+{
+ MemSet(Buffer,Size,Value);
+}
+
+VOID EfiCommonLibCopyMem(
+ IN VOID *Destination, IN VOID *Source,IN UINTN Length
+)
+{
+ MemCpy(Destination,Source,Length);
+}
+
+/*
+VOID
+CopyMem (
+ IN VOID *Destination, IN VOID *Source, IN UINTN Length
+)
+{
+ MemCpy (Destination, Source, Length);
+}
+
+VOID ZeroMem(IN VOID *Buffer, IN UINTN Size)
+{
+ MemSet(Buffer,Size,0);
+}
+*/
+
+INTN EfiCompareMem (
+ IN VOID *MemOne, IN VOID *MemTwo, IN UINTN Len
+)
+{
+ return MemCmp(MemOne,MemTwo,Len);
+}
+
+VOID EfiCommonLibZeroMem(IN VOID *Buffer, IN UINTN Size)
+{
+ MemSet(Buffer,Size,0);
+}
+
+VOID* EfiConstructStatusCodeData (
+ IN UINT16 DataSize, IN EFI_GUID *TypeGuid,
+ IN OUT EFI_STATUS_CODE_DATA *Data
+)
+{
+ if (!Data) return NULL;
+ Data->HeaderSize=sizeof(EFI_STATUS_CODE_DATA);
+ Data->Size=(UINT16)(DataSize - sizeof (EFI_STATUS_CODE_DATA));
+ Data->Type=*TypeGuid;
+ return Data + 1;
+}
+
+EFI_STATUS EfiDebugVPrintWorker (
+ IN UINTN ErrorLevel, IN CHAR8 *Format,
+ IN VA_LIST Marker, IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+)
+{
+ UINTN Index;
+ UINTN FormatStrLen;
+ UINT64 *Ptr;
+ EFI_DEBUG_INFO *EfiDebug;
+
+
+ //
+ // Build the type specific EFI_STATUS_CODE_DATA in order
+ //
+
+ //
+ // Fill in EFI_STATUS_CODE_DATA to Buffer.
+ //
+ EfiDebug = (EFI_DEBUG_INFO *)EfiConstructStatusCodeData (
+ (UINT16)BufferSize,
+ &gEfiStatusCodeDataTypeDebugGuid,
+ Buffer
+ );
+
+ //
+ // Then EFI_DEBUG_INFO
+ //
+ EfiDebug->ErrorLevel = (UINT32)ErrorLevel;
+
+ //
+ // 256 byte mini Var Arg stack. That is followed by the format string.
+ //
+ for (Index = 0, Ptr = (UINT64 *)(EfiDebug + 1); Index < 12; Index++, Ptr++) {
+ *Ptr = VA_ARG (Marker, UINT64);
+ }
+
+ //
+ // Place Ascii Format string at the end
+ //
+ FormatStrLen = EfiAsciiStrLen (Format) + 1;
+ if (FormatStrLen > EFI_STATUS_CODE_DATA_MAX_SIZE) {
+ //
+ // Format too big to fit in our buffer, so do nothing.
+ //
+ return EFI_BUFFER_TOO_SMALL;
+ } else {
+ EfiCommonLibCopyMem (Ptr, Format, FormatStrLen);
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EfiDebugAssertWorker (
+ IN CHAR8 *Filename,
+ IN INTN LineNumber,
+ IN CHAR8 *Description,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ )
+{
+ EFI_DEBUG_ASSERT_DATA *AssertData;
+ UINTN TotalSize;
+ CHAR8 *EndOfStr;
+
+ //
+ // Make sure it will all fit in the passed in buffer
+ //
+ TotalSize = sizeof (EFI_STATUS_CODE_DATA) + sizeof (EFI_DEBUG_ASSERT_DATA);
+ TotalSize += EfiAsciiStrLen (Filename) + EfiAsciiStrLen (Description);
+ if (TotalSize > BufferSize) {
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ //
+ // Fill in EFI_STATUS_CODE_DATA
+ //
+ AssertData = (EFI_DEBUG_ASSERT_DATA *)
+ EfiConstructStatusCodeData (
+ (UINT16)(TotalSize - sizeof (EFI_STATUS_CODE_DATA)),
+ &gEfiStatusCodeDataTypeAssertGuid,
+ Buffer
+ );
+
+ //
+ // Fill in EFI_DEBUG_ASSERT_DATA
+ //
+ AssertData->LineNumber = (UINT32)LineNumber;
+
+ //
+ // Copy Ascii FileName including NULL.
+ //
+ EndOfStr = EfiAsciiStrCpy ((CHAR8 *)(AssertData + 1), Filename);
+
+ //
+ // Copy Ascii Description
+ //
+ EfiAsciiStrCpy (EndOfStr, Description);
+ return EFI_SUCCESS;
+}
+
+BOOLEAN
+ReportStatusCodeExtractAssertInfo (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_STATUS_CODE_DATA *Data,
+ OUT CHAR8 **Filename,
+ OUT CHAR8 **Description,
+ OUT UINT32 *LineNumber
+ )
+{
+ EFI_DEBUG_ASSERT_DATA *AssertData;
+
+ if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) &&
+ ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)) {
+ //
+ // Assume if we have an uncontained unrecoverable error that the data hub
+ // may not work. So we will print out data here. If we had an IPMI controller,
+ // or error log we could wack the hardware here.
+ //
+ if ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE && (Data != NULL)) {
+ //
+ // ASSERT (Expresion) -
+ // ExtendedData == FileName
+ // Instance == Line Nuber
+ // NULL == String of Expresion
+ //
+ AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1);
+ *Filename = (CHAR8 *)(AssertData + 1);
+ *Description = *Filename + EfiAsciiStrLen (*Filename) + 1;
+ *LineNumber = AssertData->LineNumber;
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+BOOLEAN
+ReportStatusCodeExtractDebugInfo (
+ IN EFI_STATUS_CODE_DATA *Data,
+ OUT UINT32 *ErrorLevel,
+ OUT VA_LIST *Marker,
+ OUT CHAR8 **Format
+ )
+{
+ EFI_DEBUG_INFO *DebugInfo;
+
+ if ((Data == NULL) || (!EfiCompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid))) {
+ return FALSE;
+ }
+
+ DebugInfo = (EFI_DEBUG_INFO *)(Data + 1);
+
+ *ErrorLevel = DebugInfo->ErrorLevel;
+
+ //
+ // The first 12 * UINTN bytes of the string are really an
+ // arguement stack to support varargs on the Format string.
+ //
+ *Marker = (VA_LIST) (DebugInfo + 1);
+ *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12);
+
+ return TRUE;
+}
+
+BOOLEAN
+CodeTypeToPostCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ OUT UINT8 *PostCode
+ )
+{
+ //TODO: reveiw
+ if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) ||
+ ((CodeType & EFI_STATUS_CODE_TYPE_MASK)== EFI_ERROR_CODE)) {
+ *PostCode = (UINT8) (((Value & EFI_STATUS_CODE_CLASS_MASK) >> 24) << 5);
+ *PostCode |= (UINT8) (((Value & EFI_STATUS_CODE_SUBCLASS_MASK) >> 16) & 0x1f);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+UINT64 MultU64x32(IN UINT64 Multiplicand, IN UINTN Multiplier)
+{
+ return Mul64(Multiplicand,Multiplier);
+}
+
+UINT64 DivU64x32(
+ IN UINT64 Dividend, IN UINTN Divisor,
+ OUT UINTN *Remainder OPTIONAL
+)
+{
+ return Div64(Dividend,Divisor,Remainder);
+}
+
+UINT64 RShiftU64(IN UINT64 Operand, IN UINTN Count)
+{
+ return Shr64(Operand,(UINT8)Count);
+}
+
+UINT64 LShiftU64(IN UINT64 Operand, IN UINTN Count)
+{
+ return Shl64(Operand,(UINT8)Count);
+}
+
+/*
+TODO:
+UINT64
+Power10U64 (
+ IN UINT64 Operand,
+ IN UINTN Power
+ )
+
+UINT8
+Log2 (
+ IN UINT64 Operand
+ )
+
+UINT32
+GetPowerOfTwo (
+ IN UINT32 Input
+ )
+*/
+
+VOID EfiStrCpy (
+ IN CHAR16 *Destination, IN CHAR16 *Source
+)
+{
+ Wcscpy (Destination, Source);
+}
+
+UINTN EfiStrLen (IN CHAR16 *String)
+{
+ return Wcslen(String);
+}
+
+UINTN EfiStrSize (IN CHAR16 *String)
+{
+ return (Wcslen(String)+1)*sizeof(CHAR16);
+}
+
+INTN EfiStrCmp (IN CHAR16 *String, IN CHAR16 *String2)
+{
+ return Wcscmp(String,String2);
+}
+
+VOID EfiStrCat (
+ IN CHAR16 *Destination, IN CHAR16 *Source
+)
+{
+ Wcscpy (Destination + Wcslen (Destination), Source);
+}
+
+UINTN EfiAsciiStrLen (IN CHAR8 *String)
+{
+ return Strlen(String);
+}
+
+CHAR8* EfiAsciiStrCpy (
+ IN CHAR8 *Destination, IN CHAR8 *Source
+)
+{
+ return Strcpy(Destination,Source);
+}
+
+UINTN EfiValueToHexStr (
+ IN OUT CHAR16 *Buffer, IN UINT64 Value,
+ IN UINTN Flags, IN UINTN Width
+)
+{
+ //TODO: Flags
+ return Swprintf(Buffer,L"%*lX",Width,Value);
+}
+
+UINTN EfiValueToString (
+ IN OUT CHAR16 *Buffer, IN INT64 Value,
+ IN UINTN Flags, IN UINTN Width
+)
+{
+ //TODO: Flags
+ return Swprintf(Buffer,L"%*ld",Width,Value);
+}
+
+BOOLEAN IsHexDigit (OUT UINT8 *Digit, IN CHAR16 Char)
+{
+ if (Char >= '0' && Char <= '9') {
+ *Digit = (UINT8)(Char - '0');
+ return TRUE;
+ } else {
+ Char &= 0xffdf;
+ if (Char >= 'A' && Char <= 'F') {
+ *Digit = (UINT8)(Char - 'A' + 10);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+CHAR16 NibbleToHexChar (UINT8 Nibble)
+{
+ Nibble &= 0x0F;
+ return (Nibble <= 9) ? Nibble + '0' : Nibble - 0xA + L'A';
+}
+
+EFI_STATUS HexStringToBuf (
+ IN OUT UINT8 *Buf, IN OUT UINTN *Len,
+ IN CHAR16 *Str, OUT UINTN *ConvertedStrLen OPTIONAL
+)
+{
+ UINTN HexCnt;
+ UINTN Idx;
+ UINTN BufferLength;
+ UINT8 Digit;
+ UINT8 Byte;
+
+ //
+ // Find out how many hex characters the string has.
+ //
+ for (Idx = 0, HexCnt = 0; IsHexDigit (&Digit, Str[Idx]); Idx++, HexCnt++);
+
+ if (HexCnt == 0) {
+ *Len = 0;
+ return EFI_SUCCESS;
+ }
+ //
+ // Two Unicode characters make up 1 buffer byte. Round up.
+ //
+ BufferLength = (HexCnt + 1) / 2;
+
+ //
+ // Test if buffer is passed enough.
+ //
+ if (BufferLength > (*Len)) {
+ *Len = BufferLength;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *Len = BufferLength;
+
+ for (Idx = 0; Idx < HexCnt; Idx++) {
+
+ IsHexDigit (&Digit, Str[HexCnt - 1 - Idx]);
+
+ //
+ // For odd charaters, write the lower nibble for each buffer byte,
+ // and for even characters, the upper nibble.
+ //
+ if ((Idx & 1) == 0) {
+ Byte = Digit;
+ } else {
+ Byte = Buf[Idx / 2];
+ Byte &= 0x0F;
+ Byte |= Digit << 4;
+ }
+
+ Buf[Idx / 2] = Byte;
+ }
+
+ if (ConvertedStrLen != NULL) {
+ *ConvertedStrLen = HexCnt;
+ }
+
+ return EFI_SUCCESS;
+}
+
+
+EFI_STATUS BufToHexString (
+ IN OUT CHAR16 *Str, IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf, IN UINTN Len
+)
+{
+ UINTN Idx;
+ UINT8 Byte;
+ UINTN StrLen;
+
+ //
+ // Make sure string is either passed or allocate enough.
+ // It takes 2 Unicode characters (4 bytes) to represent 1 byte of the binary buffer.
+ // Plus the Unicode termination character.
+ //
+ StrLen = Len * 2;
+ if (StrLen > ((*HexStringBufferLength) - 1)) {
+ *HexStringBufferLength = StrLen + 1;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+
+ *HexStringBufferLength = StrLen + 1;
+ //
+ // Ends the string.
+ //
+ Str[StrLen] = L'\0';
+
+ for (Idx = 0; Idx < Len; Idx++) {
+
+ Byte = Buf[Idx];
+ Str[StrLen - 1 - Idx * 2] = NibbleToHexChar (Byte);
+ Str[StrLen - 2 - Idx * 2] = NibbleToHexChar ((UINT8)(Byte >> 4));
+ }
+
+ return EFI_SUCCESS;
+}
+
+VOID EfiStrTrim (IN OUT CHAR16 *str, IN CHAR16 CharC)
+{
+ CHAR16 *p1;
+ CHAR16 *p2;
+
+ if (*str == 0) {
+ return;
+ }
+
+ //
+ // Trim off the leading and trailing characters c
+ //
+ for (p1 = str; *p1 && *p1 == CharC; p1++) {
+ ;
+ }
+
+ p2 = str;
+ if (p2 == p1) {
+ while (*p1) {
+ p2++;
+ p1++;
+ }
+ } else {
+ while (*p1) {
+ *p2 = *p1;
+ p1++;
+ p2++;
+ }
+ *p2 = 0;
+ }
+
+
+ for (p1 = str + EfiStrLen(str) - 1; p1 >= str && *p1 == CharC; p1--) {
+ ;
+ }
+ if (p1 != str + EfiStrLen(str) - 1) {
+ *(p1 + 1) = 0;
+ }
+}
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EfiCommonLib.h b/Core/EfiCommonLib.h
new file mode 100644
index 0000000..d87c153
--- /dev/null
+++ b/Core/EfiCommonLib.h
@@ -0,0 +1,1216 @@
+/*++
+
+Copyright (c) 2004 - 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiCommonLib.h
+
+Abstract:
+
+ Light weight lib to support EFI drivers.
+
+--*/
+
+#ifndef _EFI_COMMON_LIB_H_
+#define _EFI_COMMON_LIB_H_
+
+EFI_STATUS
+EfiLibGetSystemConfigurationTable (
+ IN EFI_GUID *TableGuid,
+ IN OUT VOID **Table
+ )
+/*++
+
+Routine Description:
+
+ Return the EFI 1.0 System Tabl entry with TableGuid
+
+Arguments:
+
+ TableGuid - Name of entry to return in the system table
+ Table - Pointer in EFI system table associated with TableGuid
+
+Returns:
+
+ EFI_SUCCESS - Table returned;
+ EFI_NOT_FOUND - TableGuid not in EFI system table
+
+--*/
+;
+
+//
+// ASPrint and AvSPrint definitions you must include the specific library
+// to get the expected behavior from the two functions
+// PEI: PeiLib
+// Graphics: Dxe\Graphics\Unicode Dxe\Graphics\ASCII
+// ASCII: Dxe\Print\ASCII
+// Unicode: Dxe\Print\Unicode
+//
+UINTN
+ASPrint (
+ OUT CHAR8 *Buffer,
+ IN UINTN BufferSize,
+ IN CONST CHAR8 *Format,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ Process format and place the results in Buffer for narrow chars.
+
+Arguments:
+
+ Buffer - Narrow char buffer to print the results of the parsing of Format into.
+ BufferSize - Maximum number of characters to put into buffer.
+ Format - Format string
+ ... - Vararg list consumed by processing Format.
+
+Returns:
+
+ Number of characters printed.
+
+--*/
+;
+
+UINTN
+AvSPrint (
+ OUT CHAR8 *StartOfBuffer,
+ IN UINTN StrSize,
+ IN CONST CHAR8 *Format,
+ IN VA_LIST Marker
+ )
+/*++
+
+Routine Description:
+
+ Internal implementation of ASPrint.
+ Process format and place the results in Buffer for narrow chars.
+
+Arguments:
+
+ StartOfBuffer - Narrow char buffer to print the results of the parsing of Format into.
+ StrSize - Maximum number of characters to put into buffer.
+ FormatString - Format string
+ Marker - Vararg list consumed by processing Format.
+
+Returns:
+
+ Number of characters printed.
+
+--*/
+;
+
+//
+// Lib functions which can be used in both PEI and DXE pahse
+//
+EFI_STATUS
+EfiInitializeCommonDriverLib (
+ IN EFI_HANDLE ImageHandle,
+ IN VOID *SystemTable
+ )
+/*++
+
+Routine Description:
+
+ Initialize lib function calling phase: PEI or DXE
+
+Arguments:
+
+ ImageHandle - The firmware allocated handle for the EFI image.
+
+ SystemTable - A pointer to the EFI System Table.
+
+Returns:
+
+ EFI_STATUS always returns EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+EfiCommonIoRead (
+ IN UINT8 Width,
+ IN UINTN Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Io read operation.
+
+Arguments:
+
+ Width - Width of read operation
+ Address - Start IO address to read
+ Count - Read count
+ Buffer - Buffer to store result
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+EfiCommonIoWrite (
+ IN UINT8 Width,
+ IN UINTN Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Io write operation.
+
+Arguments:
+
+ Width - Width of write operation
+ Address - Start IO address to write
+ Count - Write count
+ Buffer - Buffer to write to the address
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+EfiCommonPciRead (
+ IN UINT8 Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Pci read operation
+
+Arguments:
+
+ Width - Width of PCI read
+ Address - PCI address to read
+ Count - Read count
+ Buffer - Output buffer for the read
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+EfiCommonPciWrite (
+ IN UINT8 Width,
+ IN UINT64 Address,
+ IN UINTN Count,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Pci write operation
+
+Arguments:
+
+ Width - Width of PCI write
+ Address - PCI address to write
+ Count - Write count
+ Buffer - Buffer to write to the address
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+BOOLEAN
+EfiCompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ )
+/*++
+
+Routine Description:
+
+ Compares two GUIDs
+
+Arguments:
+
+ Guid1 - guid to compare
+
+ Guid2 - guid to compare
+
+Returns:
+ TRUE if Guid1 == Guid2
+ FALSE if Guid1 != Guid2
+
+--*/
+;
+
+VOID
+EfiCommonLibSetMem (
+ IN VOID *Buffer,
+ IN UINTN Size,
+ IN UINT8 Value
+ )
+/*++
+
+Routine Description:
+
+ Set Buffer to Value for Size bytes.
+
+Arguments:
+
+ Buffer - Memory to set.
+
+ Size - Number of bytes to set
+
+ Value - Value of the set operation.
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+EfiCommonLibCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+INTN
+EfiCompareMem (
+ IN VOID *MemOne,
+ IN VOID *MemTwo,
+ IN UINTN Len
+ )
+/*++
+
+Routine Description:
+
+ Compares two memory buffers of a given length.
+
+Arguments:
+
+ MemOne - First memory buffer
+
+ MemTwo - Second memory buffer
+
+ Len - Length of Mem1 and Mem2 memory regions to compare
+
+Returns:
+
+ = 0 if MemOne == MemTwo
+
+ > 0 if MemOne > MemTwo
+
+ < 0 if MemOne < MemTwo
+
+--*/
+;
+
+VOID
+EfiCommonLibZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ Set Buffer to 0 for Size bytes.
+
+Arguments:
+
+ Buffer - Memory to set.
+
+ Size - Number of bytes to set
+
+Returns:
+
+ None
+
+--*/
+;
+
+//
+// Min Max
+//
+#define EFI_MIN(a, b) (((a) < (b)) ? (a) : (b))
+#define EFI_MAX(a, b) (((a) > (b)) ? (a) : (b))
+
+//
+// Align a pointer. The pointer represented by ptr is aligned to the bound.
+// The resulting pointer is always equal or greater (by no more than bound-1)
+// than the ptr. I.e., if the ptr is already aligned, the result will be equal to ptr.
+// Valid values for bound are powers of two: 2, 4, 8, 16, 32 etc.
+// The returned pointer is VOID* this assignment-compatible with all pointer types.
+//
+#define EFI_ALIGN(ptr, bound) ((VOID *) (((UINTN) (ptr) + ((UINTN) (bound) - 1)) &~((UINTN) (bound) - 1)))
+
+//
+// Alignment tests.
+//
+#define EFI_UINTN_ALIGN_MASK (sizeof (UINTN) - 1)
+#define EFI_UINTN_ALIGNED(ptr) (((UINTN) (ptr)) & EFI_UINTN_ALIGN_MASK)
+
+//
+// Integer division with rounding to the nearest rather than truncating.
+// For example 8/3=2 but EFI_IDIV_ROUND(8,3)=3. 1/3=0 and EFI_IDIV_ROUND(1,3)=0.
+// A half is rounded up e.g., EFI_IDIV_ROUND(1,2)=1 but 1/2=0.
+//
+#define EFI_IDIV_ROUND(r, s) ((r) / (s) + (((2 * ((r) % (s))) < (s)) ? 0 : 1))
+
+//
+// ReportStatusCode.c init
+//
+VOID *
+EfiConstructStatusCodeData (
+ IN UINT16 DataSize,
+ IN EFI_GUID *TypeGuid,
+ IN OUT EFI_STATUS_CODE_DATA *Data
+ )
+/*++
+
+Routine Description:
+
+ Construct stanader header for optional data passed into ReportStatusCode
+
+Arguments:
+
+ DataSize - Size of optional data. Does not include EFI_STATUS_CODE_DATA header
+ TypeGuid - GUID to place in EFI_STATUS_CODE_DATA
+ Data - Buffer to use.
+
+Returns:
+
+ Return pointer to Data buffer pointing past the end of EFI_STATUS_CODE_DATA
+
+--*/
+;
+
+EFI_STATUS
+EfiDebugVPrintWorker (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ IN VA_LIST Marker,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT
+ information. If Error Logging hub is not loaded do nothing.
+
+ We use UINT64 buffers due to IPF alignment concerns.
+
+Arguments:
+
+ ErrorLevel - If error level is set do the debug print.
+
+ Format - String to use for the print, followed by Print arguments.
+
+ Marker - VarArgs
+
+ BufferSize - Size of Buffer.
+
+ Buffer - Caller allocated buffer, contains ReportStatusCode extended data
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+EFI_STATUS
+EfiDebugAssertWorker (
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description,
+ IN UINTN BufferSize,
+ IN OUT VOID *Buffer
+ )
+/*++
+
+Routine Description:
+
+ Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT
+ information. If Error Logging hub is not loaded DEADLOOP ().
+
+ We use UINT64 buffers due to IPF alignment concerns.
+
+Arguments:
+
+ FileName - File name of failing routine.
+
+ LineNumber - Line number of failing ASSERT().
+
+ Description - Description, usually the assertion,
+
+ BufferSize - Size of Buffer.
+
+ Buffer - Caller allocated buffer, contains ReportStatusCode extendecd data
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+BOOLEAN
+ReportStatusCodeExtractAssertInfo (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ IN EFI_STATUS_CODE_DATA *Data,
+ OUT CHAR8 **Filename,
+ OUT CHAR8 **Description,
+ OUT UINT32 *LineNumber
+ )
+/*++
+
+Routine Description:
+
+ Extract assert information from status code data.
+
+Arguments:
+
+ CodeType - Code type
+ Value - Code value
+ Data - Optional data associated with this status code.
+ Filename - Filename extracted from Data
+ Description - Description extracted from Data
+ LineNumber - Line number extracted from Data
+
+Returns:
+
+ TRUE - Successfully extracted
+
+ FALSE - Extraction failed
+
+--*/
+;
+
+BOOLEAN
+ReportStatusCodeExtractDebugInfo (
+ IN EFI_STATUS_CODE_DATA *Data,
+ OUT UINT32 *ErrorLevel,
+ OUT VA_LIST *Marker,
+ OUT CHAR8 **Format
+ )
+/*++
+
+Routine Description:
+
+ Extract debug information from status code data.
+
+Arguments:
+
+ Data - Optional data associated with status code.
+ ErrorLevel - Error level extracted from Data
+ Marker - VA_LIST extracted from Data
+ Format - Format string extracted from Data
+
+Returns:
+
+ TRUE - Successfully extracted
+
+ FALSE - Extraction failed
+
+--*/
+;
+
+BOOLEAN
+CodeTypeToPostCode (
+ IN EFI_STATUS_CODE_TYPE CodeType,
+ IN EFI_STATUS_CODE_VALUE Value,
+ OUT UINT8 *PostCode
+ )
+/*++
+
+Routine Description:
+
+ Convert code value to an 8 bit post code
+
+Arguments:
+
+ CodeType - Code type
+ Value - Code value
+ PostCode - Post code as output
+
+Returns:
+
+ TRUE - Successfully converted
+
+ FALSE - Convertion failed
+
+--*/
+;
+
+//
+// math.c
+//
+UINT64
+MultU64x32 (
+ IN UINT64 Multiplicand,
+ IN UINTN Multiplier
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be multiplied with a 32 bit
+ value returns 64bit result.
+ No checking if the result is greater than 64bits
+
+Arguments:
+
+ Multiplicand - multiplicand
+ Multiplier - multiplier
+
+Returns:
+
+ Multiplicand * Multiplier
+
+--*/
+;
+
+UINT64
+DivU64x32 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor,
+ OUT UINTN *Remainder OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be divided with a 32 bit value returns
+ 64bit result and the Remainder.
+
+Arguments:
+
+ Dividend - dividend
+ Divisor - divisor
+ Remainder - buffer for remainder
+
+Returns:
+
+ Dividend / Divisor
+ Remainder = Dividend mod Divisor
+
+--*/
+;
+
+UINT64
+RShiftU64 (
+ IN UINT64 Operand,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be right shifted by 32 bits and returns the
+ shifted value.
+ Count is valid up 63. (Only Bits 0-5 is valid for Count)
+
+Arguments:
+
+ Operand - Value to be shifted
+ Count - Number of times to shift right.
+
+Returns:
+
+ Value shifted right identified by the Count.
+
+--*/
+;
+
+UINT64
+LShiftU64 (
+ IN UINT64 Operand,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be left shifted by 32 bits and
+ returns the shifted value.
+ Count is valid up 63. (Only Bits 0-5 is valid for Count)
+
+Arguments:
+
+ Operand - Value to be shifted
+ Count - Number of times to shift left.
+
+Returns:
+
+ Value shifted left identified by the Count.
+
+--*/
+;
+
+UINT64
+Power10U64 (
+ IN UINT64 Operand,
+ IN UINTN Power
+ )
+/*++
+
+Routine Description:
+
+ Raise 10 to the power of Power, and multiply the result with Operand
+
+Arguments:
+
+ Operand - multiplicand
+ Power - power
+
+Returns:
+
+ Operand * 10 ^ Power
+
+--*/
+;
+
+UINT8
+Log2 (
+ IN UINT64 Operand
+ )
+/*++
+
+Routine Description:
+
+ Calculates and floors logarithms based on 2
+
+Arguments:
+
+ Operand - value to calculate logarithm
+
+Returns:
+
+ The largest integer that is less than or equal
+ to the logarithm of Operand based on 2
+
+--*/
+;
+
+UINT64
+GetPowerOfTwo (
+ IN UINT64 Input
+ )
+/*++
+
+Routine Description:
+
+ Calculates the largest integer that is both
+ a power of two and less than Input
+
+Arguments:
+
+ Input - value to calculate power of two
+
+Returns:
+
+ the largest integer that is both a power of
+ two and less than Input
+
+--*/
+;
+
+//
+// Unicode String primatives
+//
+VOID
+EfiStrCpy (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ )
+/*++
+
+Routine Description:
+ Copy the Unicode string Source to Destination.
+
+Arguments:
+ Destination - Location to copy string
+ Source - String to copy
+
+Returns:
+ NONE
+
+--*/
+;
+
+UINTN
+EfiStrLen (
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+ Return the number of Unicode characters in String. This is not the same as
+ the length of the string in bytes.
+
+Arguments:
+ String - String to process
+
+Returns:
+ Number of Unicode characters in String
+
+--*/
+;
+
+UINTN
+EfiStrSize (
+ IN CHAR16 *String
+ )
+/*++
+
+Routine Description:
+ Return the number bytes in the Unicode String. This is not the same as
+ the length of the string in characters. The string size includes the NULL
+
+Arguments:
+ String - String to process
+
+Returns:
+ Number of bytes in String
+
+--*/
+;
+
+INTN
+EfiStrCmp (
+ IN CHAR16 *String,
+ IN CHAR16 *String2
+ )
+/*++
+
+Routine Description:
+ Return the alphabetic relationship between two stirngs.
+
+Arguments:
+ String - Compare to String2
+
+ String2 - Compare to String
+
+Returns:
+ 0 - Identical
+
+ > 0 - String is alphabeticly greater than String2
+
+ < 0 - String is alphabeticly less than String2
+
+--*/
+;
+
+VOID
+EfiStrCat (
+ IN CHAR16 *Destination,
+ IN CHAR16 *Source
+ )
+/*++
+
+Routine Description:
+ Concatinate Source on the end of Destination
+
+Arguments:
+ Destination - String to added to the end of.
+ Source - String to concatinate.
+
+Returns:
+ NONE
+
+--*/
+;
+
+UINTN
+EfiAsciiStrLen (
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+ Return the number of Ascii characters in String. This is not the same as
+ the length of the string in bytes.
+
+Arguments:
+ String - String to process
+
+Returns:
+ Number of Unicode characters in String
+
+--*/
+;
+
+CHAR8 *
+EfiAsciiStrCpy (
+ IN CHAR8 *Destination,
+ IN CHAR8 *Source
+ )
+/*++
+
+Routine Description:
+ Copy the Ascii string Source to Destination.
+
+Arguments:
+ Destination - Location to copy string
+ Source - String to copy
+
+Returns:
+ Pointer just pass the end of Destination
+
+--*/
+;
+
+
+UINTN
+EfiAsciiStrSize (
+ IN CHAR8 *String
+ )
+/*++
+
+Routine Description:
+ Return the number bytes in the Ascii String. This is not the same as
+ the length of the string in characters. The string size includes the NULL
+
+Arguments:
+ String - String to process
+
+Returns:
+ Number of bytes in String
+
+--*/
+;
+
+
+INTN
+EfiAsciiStrCmp (
+ IN CHAR8 *String,
+ IN CHAR8 *String2
+ )
+/*++
+
+Routine Description:
+ Compare the Ascii string pointed by String to the string pointed by String2.
+
+Arguments:
+ String - String to process
+
+ String2 - The other string to process
+
+Returns:
+ Return a positive integer if String is lexicall greater than String2; Zero if
+ the two strings are identical; and a negative interger if String is lexically
+ less than String2.
+--*/
+;
+
+VOID
+EfiAsciiStrCat (
+ IN CHAR8 *Destination,
+ IN CHAR8 *Source
+ )
+/*++
+
+Routine Description:
+ Concatinate Source on the end of Destination
+
+Arguments:
+ Destination - String to added to the end of.
+ Source - String to concatinate.
+
+Returns:
+ NONE
+
+--*/
+;
+
+//
+// Print primitives
+//
+#define LEFT_JUSTIFY 0x01
+#define PREFIX_SIGN 0x02
+#define PREFIX_BLANK 0x04
+#define COMMA_TYPE 0x08
+#define LONG_TYPE 0x10
+#define PREFIX_ZERO 0x20
+
+//
+// Length of temp string buffer to store value string.
+//
+#define CHARACTER_NUMBER_FOR_VALUE 30
+
+UINTN
+EfiValueToHexStr (
+ IN OUT CHAR16 *Buffer,
+ IN UINT64 Value,
+ IN UINTN Flags,
+ IN UINTN Width
+ )
+/*++
+
+Routine Description:
+
+ VSPrint worker function that prints a Value as a hex number in Buffer
+
+Arguments:
+
+ Buffer - Location to place ascii hex string of Value.
+
+ Value - Hex value to convert to a string in Buffer.
+
+ Flags - Flags to use in printing Hex string, see file header for details.
+
+ Width - Width of hex value.
+
+Returns:
+
+ Number of characters printed.
+
+--*/
+;
+
+UINTN
+EfiValueToString (
+ IN OUT CHAR16 *Buffer,
+ IN INT64 Value,
+ IN UINTN Flags,
+ IN UINTN Width
+ )
+/*++
+
+Routine Description:
+
+ VSPrint worker function that prints a Value as a decimal number in Buffer
+
+Arguments:
+
+ Buffer - Location to place ascii decimal number string of Value.
+
+ Value - Decimal value to convert to a string in Buffer.
+
+ Flags - Flags to use in printing decimal string, see file header for details.
+
+ Width - Width of hex value.
+
+Returns:
+
+ Number of characters printed.
+
+--*/
+;
+
+BOOLEAN
+IsHexDigit (
+ OUT UINT8 *Digit,
+ IN CHAR16 Char
+ )
+/*++
+
+ Routine Description:
+ Determines if a Unicode character is a hexadecimal digit.
+ The test is case insensitive.
+
+ Arguments:
+ Digit - Pointer to byte that receives the value of the hex character.
+ Char - Unicode character to test.
+
+ Returns:
+ TRUE - If the character is a hexadecimal digit.
+ FALSE - Otherwise.
+
+--*/
+;
+
+CHAR16
+NibbleToHexChar (
+ UINT8 Nibble
+ )
+/*++
+
+ Routine Description:
+ Converts the low nibble of a byte to hex unicode character.
+
+ Arguments:
+ Nibble - lower nibble of a byte.
+
+ Returns:
+ Hex unicode character.
+
+--*/
+;
+
+EFI_STATUS
+HexStringToBuf (
+ IN OUT UINT8 *Buf,
+ IN OUT UINTN *Len,
+ IN CHAR16 *Str,
+ OUT UINTN *ConvertedStrLen OPTIONAL
+ )
+/*++
+
+ Routine Description:
+ Converts Unicode string to binary buffer.
+ The conversion may be partial.
+ The first character in the string that is not hex digit stops the conversion.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ Arguments:
+ Buf - Pointer to buffer that receives the data.
+ Len - Length in bytes of the buffer to hold converted data.
+ If routine return with EFI_SUCCESS, containing length of converted data.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of buffer desired.
+ Str - String to be converted from.
+ ConvertedStrLen - Length of the Hex String consumed.
+
+ Returns:
+ EFI_SUCCESS: Routine Success.
+ EFI_BUFFER_TOO_SMALL: The buffer is too small to hold converted data.
+ EFI_
+
+--*/
+;
+
+EFI_STATUS
+BufToHexString (
+ IN OUT CHAR16 *Str,
+ IN OUT UINTN *HexStringBufferLength,
+ IN UINT8 *Buf,
+ IN UINTN Len
+ )
+/*++
+
+ Routine Description:
+ Converts binary buffer to Unicode string.
+ At a minimum, any blob of data could be represented as a hex string.
+
+ Arguments:
+ Str - Pointer to the string.
+ HexStringBufferLength - Length in bytes of buffer to hold the hex string. Includes tailing '\0' character.
+ If routine return with EFI_SUCCESS, containing length of hex string buffer.
+ If routine return with EFI_BUFFER_TOO_SMALL, containg length of hex string buffer desired.
+ Buf - Buffer to be converted from.
+ Len - Length in bytes of the buffer to be converted.
+
+ Returns:
+ EFI_SUCCESS: Routine success.
+ EFI_BUFFER_TOO_SMALL: The hex string buffer is too small.
+
+--*/
+;
+
+VOID
+EfiStrTrim (
+ IN OUT CHAR16 *str,
+ IN CHAR16 CharC
+ )
+/*++
+
+Routine Description:
+
+ Removes (trims) specified leading and trailing characters from a string.
+
+Arguments:
+
+ str - Pointer to the null-terminated string to be trimmed. On return,
+ str will hold the trimmed string.
+ CharC - Character will be trimmed from str.
+
+Returns:
+
+ None
+
+--*/
+;
+CHAR16*
+EfiStrStr (
+ IN CHAR16 *String,
+ IN CHAR16 *StrCharSet
+ )
+/*++
+
+Routine Description:
+
+ Find a substring.
+
+Arguments:
+
+ String - Null-terminated string to search.
+ StrCharSet - Null-terminated string to search for.
+
+Returns:
+ The address of the first occurrence of the matching substring if successful, or NULL otherwise.
+--*/
+;
+
+CHAR8*
+EfiAsciiStrStr (
+ IN CHAR8 *String,
+ IN CHAR8 *StrCharSet
+ )
+/*++
+
+Routine Description:
+
+ Find a Ascii substring.
+
+Arguments:
+
+ String - Null-terminated Ascii string to search.
+ StrCharSet - Null-terminated Ascii string to search for.
+
+Returns:
+ The address of the first occurrence of the matching Ascii substring if successful, or NULL otherwise.
+--*/
+;
+#endif
diff --git a/Core/EfiDebug.h b/Core/EfiDebug.h
new file mode 100644
index 0000000..87d9572
--- /dev/null
+++ b/Core/EfiDebug.h
@@ -0,0 +1,174 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiDebug.h
+
+Abstract:
+
+ EFI Debug macros. The work needs tobe done in library. The Debug
+ macros them selves are standard for all files, including the core.
+
+ There needs to be code linked in that produces the following macros:
+
+ EfiDebugAssert(file, linenumber, assertion string) - worker function for
+ ASSERT. filename and line number of where this ASSERT() is located
+ is passed in along with the stringized version of the assertion.
+
+ EfiDebugPrint - Worker function for debug print
+
+ _DEBUG_SET_MEM(address, length, value) - Set memory at address to value
+ for legnth bytes. This macro is used to initialzed uninitialized memory
+ or memory that is free'ed, so it will not be used by mistake.
+
+--*/
+
+#ifndef _EFI_DEBUG_H_
+#define _EFI_DEBUG_H_
+
+#ifdef EFI_DEBUG
+
+ VOID
+ EfiDebugAssert (
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ );
+
+ VOID
+ EfiDebugPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ );
+
+ VOID
+ EfiDebugVPrint (
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ IN VA_LIST Marker
+ );
+
+ //
+ // Define macros for the above functions so we can make them go away
+ // in non-debug builds.
+ //
+ #define EFI_DEBUG_VPRINT(ErrorLevel, Format, Marker) \
+ EfiDebugVPrint(ErrorLevel, Format, Marker)
+
+ #define EFI_DEBUG_ASSERT(FileName, LineNumber, Description) \
+ EfiDebugAssert (FileName, LineNumber, Description)
+
+ #define _DEBUG_ASSERT(assertion) \
+ EfiDebugAssert (__FILE__, __LINE__, #assertion)
+
+ #define _DEBUG(arg) DebugPrint arg
+
+ //
+ // Define ASSERT() macro, if assertion is FALSE trigger the ASSERT
+ //
+#ifndef ASSERT
+ #define ASSERT(assertion) if(!(assertion)) \
+ _DEBUG_ASSERT(assertion)
+#endif
+
+ #define ASSERT_LOCKED(l) if(!(l)->Lock) _DEBUG_ASSERT(l not locked)
+
+ //
+ // DEBUG((DebugLevel, "format string", ...)) - if DebugLevel is active do
+ // the a debug print.
+ //
+ #define DEBUG(arg) EfiDebugPrint arg
+
+ #define DEBUG_CODE(code) code
+
+ #define CR(record, TYPE, field, signature) \
+ _CR(record, TYPE, field)->Signature != signature ? \
+ (TYPE *) (_DEBUG_ASSERT("CR has Bad Signature"), record) : \
+ _CR(record, TYPE, field)
+
+ #define _DEBUG_SET_MEM(address, length, data) EfiCommonLibSetMem(address, length, data)
+
+ //
+ // Generate an ASSERT if the protocol specified by GUID is already installed on Handle.
+ // If Handle is NULL, then an ASSERT is generated if the protocol specified by GUID
+ // is present anywhere in the handle database
+ //
+ #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid) \
+ DEBUG_CODE ( { \
+ VOID *Instance; \
+ if (Handle == NULL) { \
+ ASSERT(EFI_ERROR(gBS->LocateProtocol (Guid, NULL, &Instance))); \
+ } else { \
+ ASSERT(EFI_ERROR(gBS->HandleProtocol (Handle, Guid, &Instance))); \
+ } } )
+
+#else
+ #define ASSERT(a)
+ #define ASSERT_LOCKED(l)
+ #define DEBUG(arg)
+ #define DEBUG_CODE(code)
+ #define CR(Record, TYPE, Field, Signature) \
+ _CR(Record, TYPE, Field)
+ #define _DEBUG_SET_MEM(address, length, data)
+ #define EFI_DEBUG_VPRINT(ErrorLevel, Format, Marker)
+ #define EFI_DEBUG_ASSERT(FileName, LineNumber, Description)
+ #define ASSERT_PROTOCOL_ALREADY_INSTALLED(Handle, Guid)
+#endif
+
+//
+// Generate an ASSERT if Status is an error code
+//
+//#define ASSERT_EFI_ERROR(status) ASSERT(!EFI_ERROR(status))
+#ifndef ASSERT_EFI_ERROR
+#define ASSERT_EFI_ERROR(status) if (EFI_ERROR(status)) \
+ DEBUG_CODE ( { \
+ DEBUG((EFI_D_ERROR, "\nASSERT!Status = 0x%x Info :",status)); \
+ ASSERT(!EFI_ERROR(status)); \
+ } )
+#endif
+
+#ifdef EFI_DEBUG_CLEAR_MEMORY
+ #define DEBUG_SET_MEMORY(address,length) \
+ _DEBUG_SET_MEM(address, length, EFI_BAD_POINTER_AS_BYTE)
+#else
+ #define DEBUG_SET_MEMORY(address,length)
+#endif
+
+#define EFI_D_INIT 0x00000001 // Initialization style messages
+#define EFI_D_WARN 0x00000002 // Warnings
+#define EFI_D_LOAD 0x00000004 // Load events
+#define EFI_D_FS 0x00000008 // EFI File system
+#define EFI_D_POOL 0x00000010 // Alloc & Free's
+#define EFI_D_PAGE 0x00000020 // Alloc & Free's
+#define EFI_D_INFO 0x00000040 // Verbose
+#define EFI_D_VARIABLE 0x00000100 // Variable
+#define EFI_D_BM 0x00000400 // Boot Manager (BDS)
+#define EFI_D_BLKIO 0x00001000 // BlkIo Driver
+#define EFI_D_NET 0x00004000 // SNI Driver
+#define EFI_D_UNDI 0x00010000 // UNDI Driver
+#define EFI_D_LOADFILE 0x00020000 // UNDI Driver
+#define EFI_D_EVENT 0x00080000 // Event messages
+
+#define EFI_D_ERROR 0x80000000 // Error
+
+#define EFI_D_GENERIC (EFI_D_ERROR | EFI_D_INIT | EFI_D_WARN | EFI_D_INFO | \
+ EFI_D_BLKIO | EFI_D_NET | EFI_D_UNDI )
+
+#define EFI_D_INTRINSIC ( EFI_D_EVENT | EFI_D_POOL | EFI_D_PAGE | \
+ EFI_D_BM | EFI_D_LOAD | EFI_D_VARIABLE )
+
+#define EFI_D_RESERVED (EFI_D_GENERIC | EFI_D_INTRINSIC)
+
+#define EFI_DBUG_MASK (EFI_D_ERROR)
+
+#endif
diff --git a/Core/EfiDependency.h b/Core/EfiDependency.h
new file mode 100644
index 0000000..14e5405
--- /dev/null
+++ b/Core/EfiDependency.h
@@ -0,0 +1,52 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiDependency.h
+
+Abstract:
+
+ This module contains data specific to dependency expressions
+ and local function prototypes.
+
+--*/
+
+#ifndef _DEPENDENCY_H_
+#define _DEPENDENCY_H_
+
+//
+//
+// EFI_DEP_BEFORE - If present, it must be the first and only opcode
+// EFI_DEP_AFTER - If present, it must be the first and only opcode
+// EFI_DEP_SOR - If present, it must be the first opcode
+// EFI_DEP_REPLACE_TRUE - Used to dynamically patch the dependecy expression
+// to save time. A EFI_DEP_PUSH is evauated one an
+// replaced with EFI_DEP_REPLACE_TRUE
+//
+#define EFI_DEP_BEFORE 0x00
+#define EFI_DEP_AFTER 0x01
+#define EFI_DEP_PUSH 0x02
+#define EFI_DEP_AND 0x03
+#define EFI_DEP_OR 0x04
+#define EFI_DEP_NOT 0x05
+#define EFI_DEP_TRUE 0x06
+#define EFI_DEP_FALSE 0x07
+#define EFI_DEP_END 0x08
+#define EFI_DEP_SOR 0x09
+#define EFI_DEP_REPLACE_TRUE 0xff
+
+//
+// Define the initial size of the dependency expression evaluation stack
+//
+#define DEPEX_STACK_SIZE_INCREMENT 0x1000
+
+#endif
diff --git a/Core/EfiFirmwareFileSystem.h b/Core/EfiFirmwareFileSystem.h
new file mode 100644
index 0000000..a1bf3ba
--- /dev/null
+++ b/Core/EfiFirmwareFileSystem.h
@@ -0,0 +1,49 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiFirmwareFileSystem.h
+
+Abstract:
+
+ This file defines the data structures that comprise the FFS file system.
+
+--*/
+
+#ifndef _EFI_FFS_FILE_SYSTEM_H_
+#define _EFI_FFS_FILE_SYSTEM_H_
+
+#include <FFS.h>
+
+//
+// FFS_FIXED_CHECKSUM is the default checksum value used when the
+// FFS_ATTRIB_CHECKSUM attribute bit is clear
+// note this is NOT an architecturally defined value, but is in this file for
+// implementation convenience
+//
+#define FFS_FIXED_CHECKSUM 0x5A
+
+#define EFI_FILE_ALL_STATE_BITS (EFI_FILE_HEADER_CONSTRUCTION | \
+ EFI_FILE_HEADER_VALID | \
+ EFI_FILE_DATA_VALID | \
+ EFI_FILE_MARKED_FOR_UPDATE | \
+ EFI_FILE_DELETED | \
+ EFI_FILE_HEADER_INVALID \
+ )
+
+#define EFI_TEST_FFS_ATTRIBUTES_BIT(FvbAttributes, TestAttributes, Bit) \
+ ( \
+ (BOOLEAN) ( \
+ (FvbAttributes & EFI_FVB_ERASE_POLARITY) ? (((~TestAttributes) & Bit) == Bit) : ((TestAttributes & Bit) == Bit) \
+ ) \
+ )
+#endif
diff --git a/Core/EfiFirmwareVolumeHeader.h b/Core/EfiFirmwareVolumeHeader.h
new file mode 100644
index 0000000..2409a30
--- /dev/null
+++ b/Core/EfiFirmwareVolumeHeader.h
@@ -0,0 +1,88 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiFirmwareVolumeHeader.h
+
+Abstract:
+
+ Defines data structure that is the volume header found at the beginning of
+ all firmware volumes that are either memory mapped, or have an
+ associated FirmwareVolumeBlock protocol.
+
+--*/
+
+#ifndef _EFI_FIRMWARE_VOLUME_HEADER_H_
+#define _EFI_FIRMWARE_VOLUME_HEADER_H_
+#include <FFS.h>
+
+//PI 1.1 ++
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x00010000)
+
+#define EFI_FVB_CAPABILITIES (EFI_FVB2_READ_DISABLED_CAP | \
+ EFI_FVB2_READ_ENABLED_CAP | \
+ EFI_FVB2_WRITE_DISABLED_CAP | \
+ EFI_FVB2_WRITE_ENABLED_CAP | \
+ EFI_FVB2_LOCK_CAP | \
+ EFI_FVB2_READ_LOCK_CAP | \
+ EFI_FVB2_WRITE_LOCK_CAP )
+
+#define EFI_FVB_STATUS (EFI_FVB2_READ_STATUS | EFI_FVB2_WRITE_STATUS | \
+ EFI_FVB2_LOCK_STATUS | EFI_FVB2_READ_LOCK_STATUS | \
+ EFI_FVB2_WRITE_LOCK_STATUS )
+
+#ifndef EFI_FVB_ERASE_POLARITY
+#define EFI_FVB_ERASE_POLARITY EFI_FVB2_ERASE_POLARITY
+#endif
+#ifndef EFI_FVB_READ_STATUS
+#define EFI_FVB_READ_STATUS EFI_FVB2_READ_STATUS
+#endif
+//*** AMI PORTING BEGIN ***//
+#ifndef EFI_FVB_WRITE_STATUS
+#define EFI_FVB_WRITE_STATUS EFI_FVB2_WRITE_STATUS
+#endif
+//*** AMI PORTING END ***//
+#ifndef EFI_FVB_MEMORY_MAPPED
+#define EFI_FVB_MEMORY_MAPPED EFI_FVB2_MEMORY_MAPPED
+#endif
+#else
+
+#define EFI_FVB_CAPABILITIES (EFI_FVB_READ_DISABLED_CAP | \
+ EFI_FVB_READ_ENABLED_CAP | \
+ EFI_FVB_WRITE_DISABLED_CAP | \
+ EFI_FVB_WRITE_ENABLED_CAP | \
+ EFI_FVB_LOCK_CAP \
+ )
+
+#define EFI_FVB_STATUS (EFI_FVB_READ_STATUS | EFI_FVB_WRITE_STATUS | EFI_FVB_LOCK_STATUS)
+
+#endif
+//PI 1.1 ++
+//
+// Firmware Volume Header Revision definition
+//
+#define EFI_FVH_REVISION 0x01
+//
+// PI1.0 define Firmware Volume Header Revision to 2
+//
+#define EFI_FVH_PI_REVISION 0x02
+
+//
+// Firmware Volume Header Signature definition
+//
+//Defined in Tiano.h #define EFI_FVH_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', 'H')
+
+//
+// Firmware Volume Header Block Map Entry definition
+//
+
+#endif
diff --git a/Core/EfiHobLib.h b/Core/EfiHobLib.h
new file mode 100644
index 0000000..948b7a9
--- /dev/null
+++ b/Core/EfiHobLib.h
@@ -0,0 +1,287 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiHobLib.h
+
+Abstract:
+
+
+--*/
+
+#ifndef _EFI_HOB_LIB_H_
+#define _EFI_HOB_LIB_H_
+
+#include "PeiHob.h"
+
+VOID *
+GetHob (
+ IN UINT16 Type,
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ This function returns the first instance of a HOB type in a HOB list.
+
+Arguments:
+
+ Type The HOB type to return.
+ HobStart The first HOB in the HOB list.
+
+Returns:
+
+ HobStart There were no HOBs found with the requested type.
+ else Returns the first HOB with the matching type.
+
+--*/
+;
+
+UINTN
+GetHobListSize (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Get size of hob list.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+Returns:
+
+ Size of hob list.
+
+--*/
+;
+
+UINT32
+GetHobVersion (
+ IN VOID *HobStart
+ )
+/*++
+
+Routine Description:
+
+ Get hob version.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+Returns:
+
+ Hob version.
+
+--*/
+;
+
+EFI_STATUS
+GetHobBootMode (
+ IN VOID *HobStart,
+ OUT EFI_BOOT_MODE *BootMode
+ )
+/*++
+
+Routine Description:
+
+ Get current boot mode.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BootMode - Current boot mode recorded in PHIT hob
+
+Returns:
+
+ EFI_NOT_FOUND - Invalid hob header
+
+ EFI_SUCCESS - Boot mode found
+
+--*/
+;
+
+EFI_STATUS
+GetCpuHobInfo (
+ IN VOID *HobStart,
+ OUT UINT8 *SizeOfMemorySpace,
+ OUT UINT8 *SizeOfIoSpace
+ )
+/*++
+
+Routine Description:
+
+ Get information recorded in CPU hob (Memory space size, Io space size)
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ SizeOfMemorySpace - Size of memory size
+
+ SizeOfIoSpace - Size of IO size
+
+Returns:
+
+ EFI_NOT_FOUND - CPU hob not found
+
+ EFI_SUCCESS - CPU hob found and information got.
+
+--*/
+;
+
+EFI_STATUS
+GetDxeCoreHobInfo (
+ IN VOID *HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length,
+ OUT VOID **EntryPoint,
+ OUT EFI_GUID **FileName
+ )
+/*++
+
+Routine Description:
+
+ Get memory allocation hob created for DXE core and extract its information
+
+Arguments:
+
+ HobStart - Start pointer of the hob list
+
+ BaseAddress - Start address of memory allocated for DXE core
+
+ Length - Length of memory allocated for DXE core
+
+ EntryPoint - DXE core file name
+
+ FileName - FileName
+
+Returns:
+
+ EFI_NOT_FOUND - DxeCoreHob not found
+
+ EFI_SUCCESS - DxeCoreHob found and information got
+
+--*/
+;
+
+EFI_STATUS
+GetNextFirmwareVolumeHob (
+ IN OUT VOID **HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *BaseAddress,
+ OUT UINT64 *Length
+ )
+/*++
+
+Routine Description:
+
+ Get next firmware volume hob from HobStart
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - Start address of next firmware volume
+
+ Length - Length of next firmware volume
+
+Returns:
+
+ EFI_NOT_FOUND - Next firmware volume not found
+
+ EFI_SUCCESS - Next firmware volume found with address information
+
+--*/
+;
+
+EFI_STATUS
+GetNextGuidHob (
+ IN OUT VOID **HobStart,
+ IN EFI_GUID * Guid,
+ OUT VOID **Buffer,
+ OUT UINTN *BufferSize OPTIONAL
+ )
+/*++
+
+Routine Description:
+ Get the next guid hob.
+
+Arguments:
+ HobStart A pointer to the start hob.
+ Guid A pointer to a guid.
+ Buffer A pointer to the buffer.
+ BufferSize Buffer size.
+
+Returns:
+ Status code.
+
+ EFI_NOT_FOUND - Next Guid hob not found
+
+ EFI_SUCCESS - Next Guid hob found and data for this Guid got
+
+--*/
+;
+
+EFI_STATUS
+GetPalEntryHobInfo (
+ IN VOID *HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *PalEntry
+ )
+/*++
+
+Routine Description:
+
+ Get PAL entry from PalEntryHob
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ PalEntry - Pointer to PAL entry
+
+Returns:
+
+ Status code.
+
+--*/
+;
+
+EFI_STATUS
+GetIoPortSpaceAddressHobInfo (
+ IN VOID *HobStart,
+ OUT EFI_PHYSICAL_ADDRESS *IoPortSpaceAddress
+ )
+/*++
+
+Routine Description:
+
+ Get IO port space address from IoBaseHob.
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ IoPortSpaceAddress - IO port space address
+
+Returns:
+
+ Status code
+
+--*/
+;
+
+#endif
diff --git a/Core/EfiImage.h b/Core/EfiImage.h
new file mode 100644
index 0000000..486ab09
--- /dev/null
+++ b/Core/EfiImage.h
@@ -0,0 +1,742 @@
+/*++
+
+Copyright (c) 2004 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiImage.h
+
+Abstract:
+
+ EFI image format for PE32+. Please note some data structures are different
+ for IA-32 and Itanium-based images, look for UINTN and the #ifdef EFI_IA64
+
+ BugBug: Fix text - doc as defined in MSFT EFI specification
+
+--*/
+
+#ifndef _EFI_IMAGE_H_
+#define _EFI_IMAGE_H_
+
+//
+// PE32+ Subsystem type for EFI images
+//
+#define EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION 10
+#define EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
+#define EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
+
+//
+// BugBug: Need to get a real answer for this problem. This is not in the
+// PE specification.
+//
+// A SAL runtime driver does not get fixed up when a transition to
+// virtual mode is made. In all other cases it should be treated
+// like a EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER image
+//
+#define EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER 13
+
+//
+// PE32+ Machine type for EFI images
+//
+#define EFI_IMAGE_MACHINE_IA32 0x014c
+#define EFI_IMAGE_MACHINE_IA64 0x0200
+#define EFI_IMAGE_MACHINE_X64 0x8664
+//
+// #define EFI_IMAGE_MACHINE_FCODE 0xfc0d
+//
+#define EFI_IMAGE_MACHINE_EBC 0x0EBC
+
+#define EFI_IMAGE_DOS_SIGNATURE 0x5A4D // MZ
+#define EFI_IMAGE_OS2_SIGNATURE 0x454E // NE
+#define EFI_IMAGE_OS2_SIGNATURE_LE 0x454C // LE
+#define EFI_IMAGE_NT_SIGNATURE 0x00004550 // PE00
+#define EFI_IMAGE_EDOS_SIGNATURE 0x44454550 // PEED
+//
+// PE images can start with an optional DOS header, so if an image is run
+// under DOS it can print an error message.
+//
+typedef struct {
+ UINT16 e_magic; // Magic number
+ UINT16 e_cblp; // Bytes on last page of file
+ UINT16 e_cp; // Pages in file
+ UINT16 e_crlc; // Relocations
+ UINT16 e_cparhdr; // Size of header in paragraphs
+ UINT16 e_minalloc; // Minimum extra paragraphs needed
+ UINT16 e_maxalloc; // Maximum extra paragraphs needed
+ UINT16 e_ss; // Initial (relative) SS value
+ UINT16 e_sp; // Initial SP value
+ UINT16 e_csum; // Checksum
+ UINT16 e_ip; // Initial IP value
+ UINT16 e_cs; // Initial (relative) CS value
+ UINT16 e_lfarlc; // File address of relocation table
+ UINT16 e_ovno; // Overlay number
+ UINT16 e_res[4]; // Reserved words
+ UINT16 e_oemid; // OEM identifier (for e_oeminfo)
+ UINT16 e_oeminfo; // OEM information; e_oemid specific
+ UINT16 e_res2[10]; // Reserved words
+ UINT32 e_lfanew; // File address of new exe header
+} EFI_IMAGE_DOS_HEADER;
+
+//
+// File header format.
+//
+typedef struct {
+ UINT16 Machine;
+ UINT16 NumberOfSections;
+ UINT32 TimeDateStamp;
+ UINT32 PointerToSymbolTable;
+ UINT32 NumberOfSymbols;
+ UINT16 SizeOfOptionalHeader;
+ UINT16 Characteristics;
+} EFI_IMAGE_FILE_HEADER;
+
+#define EFI_IMAGE_SIZEOF_FILE_HEADER 20
+
+#define EFI_IMAGE_FILE_RELOCS_STRIPPED 0x0001 // Relocation info stripped from file.
+#define EFI_IMAGE_FILE_EXECUTABLE_IMAGE 0x0002 // File is executable (i.e. no unresolved externel references).
+#define EFI_IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004 // Line nunbers stripped from file.
+#define EFI_IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008 // Local symbols stripped from file.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_LO 0x0080 // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_32BIT_MACHINE 0x0100 // 32 bit word machine.
+#define EFI_IMAGE_FILE_DEBUG_STRIPPED 0x0200 // Debugging info stripped from file in .DBG file
+#define EFI_IMAGE_FILE_SYSTEM 0x1000 // System File.
+#define EFI_IMAGE_FILE_DLL 0x2000 // File is a DLL.
+#define EFI_IMAGE_FILE_BYTES_REVERSED_HI 0x8000 // Bytes of machine word are reversed.
+#define EFI_IMAGE_FILE_MACHINE_UNKNOWN 0
+#define EFI_IMAGE_FILE_MACHINE_I386 0x14c // Intel 386.
+#define EFI_IMAGE_FILE_MACHINE_R3000 0x162 // MIPS* little-endian, 0540 big-endian
+#define EFI_IMAGE_FILE_MACHINE_R4000 0x166 // MIPS* little-endian
+#define EFI_IMAGE_FILE_MACHINE_ALPHA 0x184 // Alpha_AXP*
+#define EFI_IMAGE_FILE_MACHINE_POWERPC 0x1F0 // IBM* PowerPC Little-Endian
+#define EFI_IMAGE_FILE_MACHINE_TAHOE 0x7cc // Intel EM machine
+//
+// * Other names and brands may be claimed as the property of others.
+//
+//
+// Directory format.
+//
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 Size;
+} EFI_IMAGE_DATA_DIRECTORY;
+
+#define EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES 16
+
+typedef struct {
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ UINT32 BaseOfBss;
+ UINT32 GprMask;
+ UINT32 CprMask[4];
+ UINT32 GpValue;
+} EFI_IMAGE_ROM_OPTIONAL_HEADER;
+
+#define EFI_IMAGE_ROM_OPTIONAL_HDR_MAGIC 0x107
+#define EFI_IMAGE_SIZEOF_ROM_OPTIONAL_HEADER sizeof (EFI_IMAGE_ROM_OPTIONAL_HEADER)
+
+typedef struct {
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_ROM_OPTIONAL_HEADER OptionalHeader;
+} EFI_IMAGE_ROM_HEADERS;
+
+//
+// ATTENTION!!! EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+// are for use ONLY by tools. All proper EFI code MUST use
+// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+//
+#define EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x10b
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ UINT32 BaseOfData;
+ //
+ // NT additional fields.
+ //
+ UINT32 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT32 SizeOfStackReserve;
+ UINT32 SizeOfStackCommit;
+ UINT32 SizeOfHeapReserve;
+ UINT32 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER32;
+
+//
+// ATTENTION!!! EFI_IMAGE_OPTIONAL_HEADER32 and EFI_IMAGE_OPTIONAL_HEADER64
+// are for use ONLY by tools. All proper EFI code MUST use
+// EFI_IMAGE_OPTIONAL_HEADER ONLY!!!
+//
+#define EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x20b
+
+typedef struct {
+ //
+ // Standard fields.
+ //
+ UINT16 Magic;
+ UINT8 MajorLinkerVersion;
+ UINT8 MinorLinkerVersion;
+ UINT32 SizeOfCode;
+ UINT32 SizeOfInitializedData;
+ UINT32 SizeOfUninitializedData;
+ UINT32 AddressOfEntryPoint;
+ UINT32 BaseOfCode;
+ //
+ // NT additional fields.
+ //
+ UINT64 ImageBase;
+ UINT32 SectionAlignment;
+ UINT32 FileAlignment;
+ UINT16 MajorOperatingSystemVersion;
+ UINT16 MinorOperatingSystemVersion;
+ UINT16 MajorImageVersion;
+ UINT16 MinorImageVersion;
+ UINT16 MajorSubsystemVersion;
+ UINT16 MinorSubsystemVersion;
+ UINT32 Win32VersionValue;
+ UINT32 SizeOfImage;
+ UINT32 SizeOfHeaders;
+ UINT32 CheckSum;
+ UINT16 Subsystem;
+ UINT16 DllCharacteristics;
+ UINT64 SizeOfStackReserve;
+ UINT64 SizeOfStackCommit;
+ UINT64 SizeOfHeapReserve;
+ UINT64 SizeOfHeapCommit;
+ UINT32 LoaderFlags;
+ UINT32 NumberOfRvaAndSizes;
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[EFI_IMAGE_NUMBER_OF_DIRECTORY_ENTRIES];
+} EFI_IMAGE_OPTIONAL_HEADER64;
+
+//
+// ATTENTION!!! EFI_IMAGE_NT_HEADERS32 and EFI_IMAGE_HEADERS64 are for use ONLY
+// by tools. All proper EFI code MUST use EFI_IMAGE_NT_HEADERS ONLY!!!
+//
+typedef struct {
+ UINT32 Signature;
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_OPTIONAL_HEADER32 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS32;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL32_HEADER sizeof (EFI_IMAGE_NT_HEADERS32)
+
+typedef struct {
+ UINT32 Signature;
+ EFI_IMAGE_FILE_HEADER FileHeader;
+ EFI_IMAGE_OPTIONAL_HEADER64 OptionalHeader;
+} EFI_IMAGE_NT_HEADERS64;
+
+#define EFI_IMAGE_SIZEOF_NT_OPTIONAL64_HEADER sizeof (EFI_IMAGE_NT_HEADERS64)
+
+//
+// Include processor specific definition of EFI_IMAGE_OPTIONAL_HEADER so the
+// type name EFI_IMAGE_OPTIONAL_HEADER is appropriate to the build. Same for
+// EFI_IMAGE_NT_HEADERS. These definitions MUST be used by ALL EFI code.
+//
+#if !defined(EFI64) && !defined(EFIx64)
+//IA32
+#define EFI_IMAGE_MACHINE_TYPE (EFI_IMAGE_MACHINE_IA32)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ (((Machine) == EFI_IMAGE_MACHINE_IA32) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_X64)
+
+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC
+typedef EFI_IMAGE_OPTIONAL_HEADER32 EFI_IMAGE_OPTIONAL_HEADER;
+typedef EFI_IMAGE_NT_HEADERS32 EFI_IMAGE_NT_HEADERS;
+#elif defined(EFI64)
+//IPF
+#define EFI_IMAGE_MACHINE_TYPE (EFI_IMAGE_MACHINE_IA64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ (((Machine) == EFI_IMAGE_MACHINE_IA64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) (FALSE)
+
+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
+typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;
+typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;
+#elif defined(EFIx64)
+//x64
+#define EFI_IMAGE_MACHINE_TYPE (EFI_IMAGE_MACHINE_X64)
+
+#define EFI_IMAGE_MACHINE_TYPE_SUPPORTED(Machine) \
+ (((Machine) == EFI_IMAGE_MACHINE_X64) || ((Machine) == EFI_IMAGE_MACHINE_EBC))
+
+#define EFI_IMAGE_MACHINE_CROSS_TYPE_SUPPORTED(Machine) ((Machine) == EFI_IMAGE_MACHINE_IA32)
+
+//
+// Assume we can use IPF values
+//
+#define EFI_IMAGE_NT_OPTIONAL_HDR_MAGIC EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC
+typedef EFI_IMAGE_OPTIONAL_HEADER64 EFI_IMAGE_OPTIONAL_HEADER;
+typedef EFI_IMAGE_NT_HEADERS64 EFI_IMAGE_NT_HEADERS;
+#endif
+
+#define EFI_IMAGE_FIRST_SECTION(ntheader) \
+ ( \
+ (EFI_IMAGE_SECTION_HEADER *) \
+ ( \
+ (UINT32) ntheader + \
+ FIELD_OFFSET (EFI_IMAGE_NT_HEADERS, OptionalHeader) + \
+ ((EFI_IMAGE_NT_HEADERS *) (ntheader))->FileHeader.SizeOfOptionalHeader \
+ ) \
+ )
+
+//
+// Subsystem Values
+//
+#define EFI_IMAGE_SUBSYSTEM_UNKNOWN 0
+#define EFI_IMAGE_SUBSYSTEM_NATIVE 1
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_GUI 2
+#define EFI_IMAGE_SUBSYSTEM_WINDOWS_CUI 3.
+#define EFI_IMAGE_SUBSYSTEM_OS2_CUI 5
+#define EFI_IMAGE_SUBSYSTEM_POSIX_CUI 7
+
+//
+// Directory Entries
+//
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXPORT 0
+#define EFI_IMAGE_DIRECTORY_ENTRY_IMPORT 1
+#define EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE 2
+#define EFI_IMAGE_DIRECTORY_ENTRY_EXCEPTION 3
+#define EFI_IMAGE_DIRECTORY_ENTRY_SECURITY 4
+#define EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC 5
+#define EFI_IMAGE_DIRECTORY_ENTRY_DEBUG 6
+#define EFI_IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7
+#define EFI_IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8
+#define EFI_IMAGE_DIRECTORY_ENTRY_TLS 9
+#define EFI_IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10
+
+//
+// Section header format.
+//
+#define EFI_IMAGE_SIZEOF_SHORT_NAME 8
+
+typedef struct {
+ UINT8 Name[EFI_IMAGE_SIZEOF_SHORT_NAME];
+ union {
+ UINT32 PhysicalAddress;
+ UINT32 VirtualSize;
+ } Misc;
+ UINT32 VirtualAddress;
+ UINT32 SizeOfRawData;
+ UINT32 PointerToRawData;
+ UINT32 PointerToRelocations;
+ UINT32 PointerToLinenumbers;
+ UINT16 NumberOfRelocations;
+ UINT16 NumberOfLinenumbers;
+ UINT32 Characteristics;
+} EFI_IMAGE_SECTION_HEADER;
+
+#define EFI_IMAGE_SIZEOF_SECTION_HEADER 40
+
+#define EFI_IMAGE_SCN_TYPE_NO_PAD 0x00000008 // Reserved.
+#define EFI_IMAGE_SCN_CNT_CODE 0x00000020
+#define EFI_IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
+#define EFI_IMAGE_SCN_CNT_UNINITIALIZED_DATA 0x00000080
+
+#define EFI_IMAGE_SCN_LNK_OTHER 0x00000100 // Reserved.
+#define EFI_IMAGE_SCN_LNK_INFO 0x00000200 // Section contains comments or some other type of information.
+#define EFI_IMAGE_SCN_LNK_REMOVE 0x00000800 // Section contents will not become part of image.
+#define EFI_IMAGE_SCN_LNK_COMDAT 0x00001000
+
+#define EFI_IMAGE_SCN_ALIGN_1BYTES 0x00100000
+#define EFI_IMAGE_SCN_ALIGN_2BYTES 0x00200000
+#define EFI_IMAGE_SCN_ALIGN_4BYTES 0x00300000
+#define EFI_IMAGE_SCN_ALIGN_8BYTES 0x00400000
+#define EFI_IMAGE_SCN_ALIGN_16BYTES 0x00500000
+#define EFI_IMAGE_SCN_ALIGN_32BYTES 0x00600000
+#define EFI_IMAGE_SCN_ALIGN_64BYTES 0x00700000
+
+#define EFI_IMAGE_SCN_MEM_DISCARDABLE 0x02000000
+#define EFI_IMAGE_SCN_MEM_NOT_CACHED 0x04000000
+#define EFI_IMAGE_SCN_MEM_NOT_PAGED 0x08000000
+#define EFI_IMAGE_SCN_MEM_SHARED 0x10000000
+#define EFI_IMAGE_SCN_MEM_EXECUTE 0x20000000
+#define EFI_IMAGE_SCN_MEM_READ 0x40000000
+#define EFI_IMAGE_SCN_MEM_WRITE 0x80000000
+
+//
+// Symbol format.
+//
+#define EFI_IMAGE_SIZEOF_SYMBOL 18
+
+//
+// Section values.
+//
+// Symbols have a section number of the section in which they are
+// defined. Otherwise, section numbers have the following meanings:
+//
+#define EFI_IMAGE_SYM_UNDEFINED (UINT16) 0 // Symbol is undefined or is common.
+#define EFI_IMAGE_SYM_ABSOLUTE (UINT16) -1 // Symbol is an absolute value.
+#define EFI_IMAGE_SYM_DEBUG (UINT16) -2 // Symbol is a special debug item.
+//
+// Type (fundamental) values.
+//
+#define EFI_IMAGE_SYM_TYPE_NULL 0 // no type.
+#define EFI_IMAGE_SYM_TYPE_VOID 1 //
+#define EFI_IMAGE_SYM_TYPE_CHAR 2 // type character.
+#define EFI_IMAGE_SYM_TYPE_SHORT 3 // type short integer.
+#define EFI_IMAGE_SYM_TYPE_INT 4
+#define EFI_IMAGE_SYM_TYPE_LONG 5
+#define EFI_IMAGE_SYM_TYPE_FLOAT 6
+#define EFI_IMAGE_SYM_TYPE_DOUBLE 7
+#define EFI_IMAGE_SYM_TYPE_STRUCT 8
+#define EFI_IMAGE_SYM_TYPE_UNION 9
+#define EFI_IMAGE_SYM_TYPE_ENUM 10 // enumeration.
+#define EFI_IMAGE_SYM_TYPE_MOE 11 // member of enumeration.
+#define EFI_IMAGE_SYM_TYPE_BYTE 12
+#define EFI_IMAGE_SYM_TYPE_WORD 13
+#define EFI_IMAGE_SYM_TYPE_UINT 14
+#define EFI_IMAGE_SYM_TYPE_DWORD 15
+
+//
+// Type (derived) values.
+//
+#define EFI_IMAGE_SYM_DTYPE_NULL 0 // no derived type.
+#define EFI_IMAGE_SYM_DTYPE_POINTER 1
+#define EFI_IMAGE_SYM_DTYPE_FUNCTION 2
+#define EFI_IMAGE_SYM_DTYPE_ARRAY 3
+
+//
+// Storage classes.
+//
+#define EFI_IMAGE_SYM_CLASS_END_OF_FUNCTION (UINT8) -1
+#define EFI_IMAGE_SYM_CLASS_NULL 0
+#define EFI_IMAGE_SYM_CLASS_AUTOMATIC 1
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL 2
+#define EFI_IMAGE_SYM_CLASS_STATIC 3
+#define EFI_IMAGE_SYM_CLASS_REGISTER 4
+#define EFI_IMAGE_SYM_CLASS_EXTERNAL_DEF 5
+#define EFI_IMAGE_SYM_CLASS_LABEL 6
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_LABEL 7
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_STRUCT 8
+#define EFI_IMAGE_SYM_CLASS_ARGUMENT 9
+#define EFI_IMAGE_SYM_CLASS_STRUCT_TAG 10
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_UNION 11
+#define EFI_IMAGE_SYM_CLASS_UNION_TAG 12
+#define EFI_IMAGE_SYM_CLASS_TYPE_DEFINITION 13
+#define EFI_IMAGE_SYM_CLASS_UNDEFINED_STATIC 14
+#define EFI_IMAGE_SYM_CLASS_ENUM_TAG 15
+#define EFI_IMAGE_SYM_CLASS_MEMBER_OF_ENUM 16
+#define EFI_IMAGE_SYM_CLASS_REGISTER_PARAM 17
+#define EFI_IMAGE_SYM_CLASS_BIT_FIELD 18
+#define EFI_IMAGE_SYM_CLASS_BLOCK 100
+#define EFI_IMAGE_SYM_CLASS_FUNCTION 101
+#define EFI_IMAGE_SYM_CLASS_END_OF_STRUCT 102
+#define EFI_IMAGE_SYM_CLASS_FILE 103
+#define EFI_IMAGE_SYM_CLASS_SECTION 104
+#define EFI_IMAGE_SYM_CLASS_WEAK_EXTERNAL 105
+
+//
+// type packing constants
+//
+#define EFI_IMAGE_N_BTMASK 017
+#define EFI_IMAGE_N_TMASK 060
+#define EFI_IMAGE_N_TMASK1 0300
+#define EFI_IMAGE_N_TMASK2 0360
+#define EFI_IMAGE_N_BTSHFT 4
+#define EFI_IMAGE_N_TSHIFT 2
+
+//
+// Communal selection types.
+//
+#define EFI_IMAGE_COMDAT_SELECT_NODUPLICATES 1
+#define EFI_IMAGE_COMDAT_SELECT_ANY 2
+#define EFI_IMAGE_COMDAT_SELECT_SAME_SIZE 3
+#define EFI_IMAGE_COMDAT_SELECT_EXACT_MATCH 4
+#define EFI_IMAGE_COMDAT_SELECT_ASSOCIATIVE 5
+
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_NOLIBRARY 1
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_LIBRARY 2
+#define EFI_IMAGE_WEAK_EXTERN_SEARCH_ALIAS 3
+
+//
+// Relocation format.
+//
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 SymbolTableIndex;
+ UINT16 Type;
+} EFI_IMAGE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_RELOCATION 10
+
+//
+// I386 relocation types.
+//
+#define EFI_IMAGE_REL_I386_ABSOLUTE 0 // Reference is absolute, no relocation is necessary
+#define EFI_IMAGE_REL_I386_DIR16 01 // Direct 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_REL16 02 // PC-relative 16-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32 06 // Direct 32-bit reference to the symbols virtual address
+#define EFI_IMAGE_REL_I386_DIR32NB 07 // Direct 32-bit reference to the symbols virtual address, base not included
+#define EFI_IMAGE_REL_I386_SEG12 011 // Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
+#define EFI_IMAGE_REL_I386_SECTION 012
+#define EFI_IMAGE_REL_I386_SECREL 013
+#define EFI_IMAGE_REL_I386_REL32 024 // PC-relative 32-bit reference to the symbols virtual address
+//
+// Based relocation format.
+//
+typedef struct {
+ UINT32 VirtualAddress;
+ UINT32 SizeOfBlock;
+} EFI_IMAGE_BASE_RELOCATION;
+
+#define EFI_IMAGE_SIZEOF_BASE_RELOCATION 8
+
+//
+// Based relocation types.
+//
+#define EFI_IMAGE_REL_BASED_ABSOLUTE 0
+#define EFI_IMAGE_REL_BASED_HIGH 1
+#define EFI_IMAGE_REL_BASED_LOW 2
+#define EFI_IMAGE_REL_BASED_HIGHLOW 3
+#define EFI_IMAGE_REL_BASED_HIGHADJ 4
+#define EFI_IMAGE_REL_BASED_MIPS_JMPADDR 5
+#define EFI_IMAGE_REL_BASED_IA64_IMM64 9
+#define EFI_IMAGE_REL_BASED_DIR64 10
+
+//
+// Line number format.
+//
+typedef struct {
+ union {
+ UINT32 SymbolTableIndex; // Symbol table index of function name if Linenumber is 0.
+ UINT32 VirtualAddress; // Virtual address of line number.
+ } Type;
+ UINT16 Linenumber; // Line number.
+} EFI_IMAGE_LINENUMBER;
+
+#define EFI_IMAGE_SIZEOF_LINENUMBER 6
+
+//
+// Archive format.
+//
+#define EFI_IMAGE_ARCHIVE_START_SIZE 8
+#define EFI_IMAGE_ARCHIVE_START "!<arch>\n"
+#define EFI_IMAGE_ARCHIVE_END "`\n"
+#define EFI_IMAGE_ARCHIVE_PAD "\n"
+#define EFI_IMAGE_ARCHIVE_LINKER_MEMBER "/ "
+#define EFI_IMAGE_ARCHIVE_LONGNAMES_MEMBER "// "
+
+typedef struct {
+ UINT8 Name[16]; // File member name - `/' terminated.
+ UINT8 Date[12]; // File member date - decimal.
+ UINT8 UserID[6]; // File member user id - decimal.
+ UINT8 GroupID[6]; // File member group id - decimal.
+ UINT8 Mode[8]; // File member mode - octal.
+ UINT8 Size[10]; // File member size - decimal.
+ UINT8 EndHeader[2]; // String to end header.
+} EFI_IMAGE_ARCHIVE_MEMBER_HEADER;
+
+#define EFI_IMAGE_SIZEOF_ARCHIVE_MEMBER_HDR 60
+
+//
+// DLL support.
+//
+//
+// Export Format
+//
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Name;
+ UINT32 Base;
+ UINT32 NumberOfFunctions;
+ UINT32 NumberOfNames;
+ UINT32 AddressOfFunctions;
+ UINT32 AddressOfNames;
+ UINT32 AddressOfNameOrdinals;
+} EFI_IMAGE_EXPORT_DIRECTORY;
+
+//
+// Import Format
+//
+typedef struct {
+ UINT16 Hint;
+ UINT8 Name[1];
+} EFI_IMAGE_IMPORT_BY_NAME;
+
+typedef struct {
+ union {
+ UINT32 Function;
+ UINT32 Ordinal;
+ EFI_IMAGE_IMPORT_BY_NAME *AddressOfData;
+ } u1;
+} EFI_IMAGE_THUNK_DATA;
+
+#define EFI_IMAGE_ORDINAL_FLAG 0x80000000
+#define EFI_IMAGE_SNAP_BY_ORDINAL(Ordinal) ((Ordinal & EFI_IMAGE_ORDINAL_FLAG) != 0)
+#define EFI_IMAGE_ORDINAL(Ordinal) (Ordinal & 0xffff)
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT32 ForwarderChain;
+ UINT32 Name;
+ EFI_IMAGE_THUNK_DATA *FirstThunk;
+} EFI_IMAGE_IMPORT_DESCRIPTOR;
+
+//
+// Debug Format
+//
+#define EFI_IMAGE_DEBUG_TYPE_CODEVIEW 2
+
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT32 Type;
+ UINT32 SizeOfData;
+ UINT32 RVA;
+ UINT32 FileOffset;
+} EFI_IMAGE_DEBUG_DIRECTORY_ENTRY;
+
+#define CODEVIEW_SIGNATURE_NB10 0x3031424E // "NB10"
+typedef struct {
+ UINT32 Signature; // "NB10"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY;
+
+#define CODEVIEW_SIGNATURE_RSDS 0x53445352 // "RSDS"
+typedef struct {
+ UINT32 Signature; // "RSDS"
+ UINT32 Unknown;
+ UINT32 Unknown2;
+ UINT32 Unknown3;
+ UINT32 Unknown4;
+ UINT32 Unknown5;
+ //
+ // Filename of .PDB goes here
+ //
+} EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY;
+
+//
+// Resource Format
+//
+typedef struct {
+ UINT32 Characteristics;
+ UINT32 TimeDateStamp;
+ UINT16 MajorVersion;
+ UINT16 MinorVersion;
+ UINT16 NumberOfNamedEntries;
+ UINT16 NumberOfIdEntries;
+// EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
+} EFI_IMAGE_RESOURCE_DIRECTORY;
+
+typedef struct {
+ union {
+ struct {
+ UINT32 NameOffset:31;
+ UINT32 NameIsString:1;
+ } s;
+ UINT32 Id;
+ } u1;
+ union {
+ UINT32 OffsetToData;
+ struct {
+ UINT32 OffsetToDirectory:31;
+ UINT32 DataIsDirectory:1;
+ } s;
+ } u2;
+} EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY;
+
+typedef struct {
+ UINT16 Length;
+ CHAR16 String[1];
+} EFI_IMAGE_RESOURCE_DIRECTORY_STRING;
+
+typedef struct {
+ UINT32 OffsetToData;
+ UINT32 Size;
+ UINT32 CodePage;
+ UINT32 Reserved;
+} EFI_IMAGE_RESOURCE_DATA_ENTRY;
+
+//
+// Header format for TE images
+//
+typedef struct {
+ UINT16 Signature; // signature for TE format = "VZ"
+ UINT16 Machine; // from the original file header
+ UINT8 NumberOfSections; // from the original file header
+ UINT8 Subsystem; // from original optional header
+ UINT16 StrippedSize; // how many bytes we removed from the header
+ UINT32 AddressOfEntryPoint; // offset to entry point -- from original optional header
+ UINT32 BaseOfCode; // from original image -- required for ITP debug
+ UINT64 ImageBase; // from original file header
+ EFI_IMAGE_DATA_DIRECTORY DataDirectory[2]; // only base relocation and debug directory
+} EFI_TE_IMAGE_HEADER;
+
+#define EFI_TE_IMAGE_HEADER_SIGNATURE 0x5A56 // "VZ"
+//
+// Data directory indexes in our TE image header
+//
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_BASERELOC 0
+#define EFI_TE_IMAGE_DIRECTORY_ENTRY_DEBUG 1
+
+//
+// Union of PE32, PE32+, and TE headers
+//
+typedef union {
+ EFI_IMAGE_NT_HEADERS32 Pe32;
+ EFI_IMAGE_NT_HEADERS64 Pe32Plus;
+ EFI_TE_IMAGE_HEADER Te;
+} EFI_IMAGE_OPTIONAL_HEADER_UNION;
+
+typedef union {
+ EFI_IMAGE_NT_HEADERS32 *Pe32;
+ EFI_IMAGE_NT_HEADERS64 *Pe32Plus;
+ EFI_TE_IMAGE_HEADER *Te;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *Union;
+} EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION;
+
+#endif
diff --git a/Core/EfiImageFormat.h b/Core/EfiImageFormat.h
new file mode 100644
index 0000000..9735a54
--- /dev/null
+++ b/Core/EfiImageFormat.h
@@ -0,0 +1,125 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ EfiImageFormat.h
+
+Abstract:
+
+ This file defines the data structures that are architecturally defined for file
+ images loaded via the FirmwareVolume protocol. The Firmware Volume specification
+ is the basis for these definitions.
+
+--*/
+
+#ifndef _EFI_IMAGE_FORMAT_H_
+#define _EFI_IMAGE_FORMAT_H_
+#include <FFS.h>
+//
+// pack all data structures since this is actually a binary format and we cannot
+// allow internal padding in the data structures because of some compilerism..
+//
+#pragma pack(1)
+
+// ************************************************************
+// Leaf section Type values
+// ************************************************************
+//
+#define EFI_SECTION_FIRST_LEAF_SECTION_TYPE 0x10
+#define EFI_SECTION_LAST_LEAF_SECTION_TYPE 0x1B
+#define EFI_SECTION_LAST_SECTION_TYPE 0x1B
+
+#define SECTION_SIZE(SectionHeaderPtr) \
+ ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) SectionHeaderPtr)->Size) & 0x00ffffff))
+
+//
+// ////////////////////////////////////////////////////////////////////////////
+//
+// Compression section
+//
+//
+// CompressionType values
+//
+#define EFI_CUSTOMIZED_COMPRESSION 0x02
+
+//
+// Bit values for AuthenticationStatus
+//
+#define EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE 0x000001
+#define EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED 0x000002
+#define EFI_AGGREGATE_AUTH_STATUS_NOT_TESTED 0x000004
+#define EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED 0x000008
+#define EFI_AGGREGATE_AUTH_STATUS_ALL 0x00000f
+
+#define EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE 0x010000
+#define EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED 0x020000
+#define EFI_LOCAL_AUTH_STATUS_NOT_TESTED 0x040000
+#define EFI_LOCAL_AUTH_STATUS_TEST_FAILED 0x080000
+#define EFI_LOCAL_AUTH_STATUS_ALL 0x0f0000
+
+
+// ////////////////////////////////////////////////////////////////////////////
+//
+// PEIM header section
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+} EFI_PEIM_HEADER_SECTION;
+
+//
+// ////////////////////////////////////////////////////////////////////////////
+//
+// DEPEX section
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+} EFI_DEPEX_SECTION;
+
+// ////////////////////////////////////////////////////////////////////////////
+//
+// Code16 section
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+} EFI_CODE16_SECTION;
+
+
+// ////////////////////////////////////////////////////////////////////////////
+//
+// Raw section
+//
+typedef struct {
+ EFI_COMMON_SECTION_HEADER CommonHeader;
+} EFI_RAW_SECTION;
+
+//
+// undo the pragma from the beginning...
+//
+#pragma pack()
+
+typedef union {
+ EFI_COMMON_SECTION_HEADER *CommonHeader;
+ EFI_COMPRESSION_SECTION *CompressionSection;
+ EFI_GUID_DEFINED_SECTION *GuidDefinedSection;
+ EFI_PE32_SECTION *Pe32Section;
+ EFI_PIC_SECTION *PicSection;
+ EFI_PEIM_HEADER_SECTION *PeimHeaderSection;
+ EFI_DEPEX_SECTION *DependencySection;
+ EFI_VERSION_SECTION *VersionSection;
+ EFI_USER_INTERFACE_SECTION *UISection;
+ EFI_CODE16_SECTION *Code16Section;
+ EFI_FIRMWARE_VOLUME_IMAGE_SECTION *FVImageSection;
+ EFI_FREEFORM_SUBTYPE_GUID_SECTION *FreeformSubtypeSection;
+ EFI_RAW_SECTION *RawSection;
+} EFI_FILE_SECTION_POINTER;
+
+#endif
diff --git a/Core/FFS.mak b/Core/FFS.mak
new file mode 100644
index 0000000..04bbcd0
--- /dev/null
+++ b/Core/FFS.mak
@@ -0,0 +1,393 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/FFS.mak 25 2/05/11 1:43p Artems $
+#
+# $Revision: 25 $
+#
+# $Date: 2/05/11 1:43p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/FFS.mak $
+#
+# 25 2/05/11 1:43p Artems
+# Added Nested FV support
+#
+# 24 10/19/10 10:37p Felixp
+# UI Seciton generation command is updated to support strings with
+# spaces.
+#
+# 23 8/30/10 11:27p Felixp
+# Improvement(EIP 43254):
+# Support for override of the module name string that is included into
+# the FFS file user interface section is added.
+# The string can be overridden using UI_NAME macro.
+#
+# 22 8/20/10 12:51p Felixp
+# LZMA compression support
+#
+# 21 3/19/10 12:41p Felixp
+#
+# 20 3/18/10 5:49p Felixp
+# New SDL token USE_CP_RESPONSE_FILE is added.
+# When this option is enabled, all C-preprocessor(CP) options are passed
+# via the response file.
+# The token should be enabled when the length of the CP command line
+# exceeds
+# maximum supported limit. The token is disabled by default.
+#
+# 19 11/23/09 6:18p Felixp
+# Version FFS section support is added.
+#
+# 18 10/22/07 6:11p Felixp
+# New FFS_ALIGNMENT switch added to support FFS data alignment
+#
+# 17 9/05/07 6:15p Felixp
+# TE Image support is disabled.
+# This is work in progress. TE image support will be enabled in the
+# future Core versions.
+#
+# 16 6/01/07 2:51p Felixp
+# TE image support added.
+# File header comments improved
+#
+# 15 3/30/07 4:43p Felixp
+# Support for FFS_CHECKSUM added to control FFS checksum generation.
+#
+# 14 3/18/07 1:52p Felixp
+# TE image support is commented out. More testing is required before this
+# can be enabled
+#
+# 13 3/18/07 12:44p Felixp
+# Support for TE images added
+#
+# 12 3/13/07 9:54a Felixp
+# Global and CPU architecture specific macros are now passed
+# to C preprocessor (used during DepEx and VFR compilation)
+#
+# 11 2/27/07 2:37p Markw
+#
+# 10 10/03/06 8:56a Felixp
+# EXTRA_INCLUDES and EXTRA_DEFINES macros added to pass include
+# directories and macro definitions for dependency expression
+# preprocessing
+#
+# 9 8/24/06 9:06a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 8 5/19/06 6:14p Felixp
+# 1. Support for EDK-based modules added.
+# 2. MY_INCLUDES macro added to specify list of include directories
+#
+# 7 1/10/06 9:42a Felixp
+# do not create UI section for RAW files
+#
+# 6 1/09/06 11:27a Felixp
+# Support for UI section added
+#
+# 4 1/05/06 2:38p Felixp
+# support of UI sections added
+#
+# 3 11/07/05 3:00p Davidd
+# $(SILENT_OUT) removed for GenSection since new version of the utility
+# supports silent execution.
+#
+# 2 11/07/05 10:07a Felixp
+# support for FREFORM_GUID sections added (to support AMI resource
+# sections)
+#
+# 1 1/28/05 12:43p Felixp
+#
+# 5 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 3 1/14/05 12:35p Markw
+# RAWFILE now can be anywhere in the project directory
+#
+# 2 1/12/05 3:16p Felixp
+# support for separetely built sections added
+#
+# 1 12/23/04 9:41a Felixp
+#
+# 9 12/03/04 6:12p Felixp
+# brief build mode added
+#
+# 8 11/03/04 7:36p Felixp
+# package file handling chaned:
+# 1. package file is now recreated during every build
+# 2. we no longer need dummy attrib utility
+#
+# 7 7/13/04 10:42a Felixp
+#
+# 6 4/10/04 2:17p Felixp
+#
+# 5 4/07/04 1:02p Felixp
+#
+# 3 1/08/04 4:46p Felixp
+# comments improved
+#
+# 2 12/09/03 11:50a Felixp
+# Comments changed for the better HelpBuiler compatibility.
+#
+# 1 12/05/03 4:15p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FFS.mak
+#
+# Description:
+# This makefile defines process of Firmware File System File creation.
+# The following macros have to be defined:
+# BUILD_DIR - temporary files derectory
+# SOURCE_DIR - source files derectory
+# GUID - GUID of the FFS file to be created
+# TYPE - FFS File Type.
+# Possible Values:
+# EFI_FV_FILETYPE_APPLICATION
+# EFI_FV_FILETYPE_FREEFORM
+# EFI_FV_FILETYPE_RAW
+# EFI_FV_FILETYPE_PEIM
+# EFI_FV_FILETYPE_PEI_CORE
+# EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
+# EFI_FV_FILETYPE_DXE_CORE
+# EFI_FV_FILETYPE_DRIVER
+# EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE
+# FFSFILE - FFS File Name (including path)
+# The following macros may be defined:
+# COMPRESS - disables/enable compression within FFS file
+# Possible values:
+# 1 - enable compression
+# <any other value> - disable compression
+# DEPEX1,DEPEX1_TYPE - First Dependency Expression source file name(including path) and type
+# DEPEX2,DEPEX2_TYPE - Second Dependency Expression source file(including path) name and type
+# Possible Values for DEPEX1_TYPE,DEPEX2_TYPE:
+# EFI_SECTION_PEI_DEPEX
+# EFI_SECTION_DXE_DEPEX
+# PEFILE - PE File Name
+# BINFILE - Binary File Name
+# RAWFILE - File Name
+# SECTION - File Name (without path, BUILD_DIR used)
+# RESOURCE, SECTION_GUID - Resource File Name and GUID of the resource section.
+# The $(RESOURCE) file will be encapsulated into section of type EFI_SECTION_FREEFORM_SUBTYPE_GUID
+# with GUID set to $(SECTION_GUID).
+# EXTRA_INCLUDES - List include directories for dependency expression preprocessing
+# EXTRA_DEFINES - List of macro definitions for dependency expression preprocessing
+# FFS_CHECKSUM - 0 or 1. Enables/Disables FFS file checksum
+# FFS_ALIGNMENT - FFS file data alignment. Supported values are from 0 to 7.
+# FFS_ALIGNMENT value - FFS Data Alignment
+# 0 or not specified - no alignment requirements
+# 1 - 16 bytes
+# 2 - 128 bytes
+# 3 - 512 bytes
+# 4 - 1K
+# 5 - 4K
+# 6 - 32K
+# 7 - 64K
+# VERSION - Build Number to be inserted into the version section
+# VERSIONSTRING - Version string to be inserted into the version section
+#<AMI_FHDR_END>
+#**********************************************************************
+!INCLUDE $(BUILD_DIR)\token.mak
+
+PKGFILE=$(FFSFILE:.ffs=)
+!IF "$(PKGFILE)"=="$(FFSFILE)"
+PKGFILE=$(FFSFILE:.FFS=)
+!IF "$(PKGFILE)"=="$(FFSFILE)"
+PKGFILE=$(FFSFILE:.Ffs=)
+!ENDIF
+!ENDIF
+PKGFILE=$(PKGFILE)__.pkg
+
+all : $(PKGFILE)
+
+!IFDEF DEPEX1
+$(PKGFILE) : $(BUILD_DIR)\$(NAME)_DPX1.tmp
+$(BUILD_DIR)\$(NAME)_DPX1.tmp : $(DEPEX1)
+!IF "$(USE_CP_RESPONSE_FILE)"=="1"
+ $(CP) @<<$(BUILD_DIR)\$(NAME)CpOptions.txt $(DEPEX1) > $*.tmp1
+$(CPFLAGS)
+<<KEEP
+!ELSE
+ $(CP) $(CPFLAGS) $(DEPEX1) > $*.tmp1
+!ENDIF
+ $(GENDEPEX) -I $*.tmp1 -O $@ $(SILENT_OUT)
+ $(SILENT)del $*.tmp1
+!ENDIF
+
+!IFDEF DEPEX2
+$(PKGFILE) : $(BUILD_DIR)\$(NAME)_DPX2.tmp
+$(BUILD_DIR)\$(NAME)_DPX2.tmp : $(DEPEX2)
+!IF "$(USE_CP_RESPONSE_FILE)"=="1"
+ $(CP) @<<$(BUILD_DIR)\$(NAME)CpOptions.txt $(DEPEX2) > $*.tmp1
+$(CPFLAGS)
+<<KEEP
+!ELSE
+ $(CP) $(CPFLAGS) $(DEPEX2) > $*.tmp1
+!ENDIF
+ $(GENDEPEX) -I $*.tmp1 -O $@ $(SILENT_OUT)
+ $(SILENT)del $*.tmp1
+!ENDIF
+
+!IFDEF PEFILE
+$(PKGFILE) : $(PEFILE)
+!ENDIF
+!IFDEF BINFILE
+$(PKGFILE) : $(BINFILE)
+!ENDIF
+!IFDEF RAWFILE
+$(PKGFILE) : $(PROJECT_DIR)\$(RAWFILE)
+!ENDIF
+!IFDEF SECTION
+$(PKGFILE) : $(BUILD_DIR)\$(SECTION)
+!ENDIF
+!IFDEF RESOURCE
+!IF "$(SECTION_GUID)"==""
+!ERROR SECTION_GUID for resource $(RESOURCE) is not defined
+!ENDIF
+$(PKGFILE) : $(RESOURCE)
+!ENDIF
+!IF "$(CREATE_UI_SECTION)"=="1" && "$(TYPE)"!="EFI_FV_FILETYPE_FREEFORM" && "$(TYPE)"!="EFI_FV_FILETYPE_RAW"
+!IFNDEF UI_NAME
+UI_NAME=$(NAME)
+!ENDIF
+!ENDIF
+
+!IF DEFINED(VERSION) || DEFINED(VERSIONSTRING)
+!IFNDEF VERSION
+VERSION=0
+!ENDIF
+!ENDIF
+
+!IF "$(LZMA_SUPPORT)" == "1"
+COMPRESSION_TYPE = LZMA
+!ELSE
+COMPRESSION_TYPE = dummy
+!ENDIF
+
+!IF "$(COMPRESS)"==""
+!ERROR COMPRESS variable is undefined for module $(NAME).
+!ENDIF
+
+!IF "$(FFS_CHECKSUM)"=="0"
+FFS_ATTRIB_CHECKSUM=FALSE
+!ELSE
+FFS_ATTRIB_CHECKSUM=TRUE
+!ENDIF
+
+$(PKGFILE) :
+ @copy << $(PKGFILE) > NUL
+PACKAGE.INF
+[.]
+BASE_NAME = DummyName
+FFS_FILEGUID = $(GUID)
+FFS_FILETYPE = $(TYPE)
+FFS_ATTRIB_CHECKSUM = $(FFS_ATTRIB_CHECKSUM)
+!IFDEF FFS_ALIGNMENT
+FFS_ALIGNMENT = $(FFS_ALIGNMENT)
+!ENDIF
+
+IMAGE_SCRIPT =
+{
+!IFDEF DEPEX1
+ $(NAME)_DPX1.dpx
+ {
+ TYPE = $(DEPEX1_TYPE)
+ BIN = $(BUILD_DIR)\$(NAME)_DPX1.tmp
+ }
+!ENDIF
+!IFDEF DEPEX2
+ $(NAME)_DPX2.dpx
+ {
+ TYPE = $(DEPEX2_TYPE)
+ BIN = $(BUILD_DIR)\$(NAME)_DPX2.tmp
+ }
+!ENDIF
+!IF $(COMPRESS)==1
+ Compress ($(COMPRESSION_TYPE)) {
+!ENDIF
+!IFDEF PEFILE
+ $(NAME)_PE.pe
+ {
+ TYPE = EFI_SECTION_PE32
+ BIN = $(PEFILE)
+ }
+!ENDIF
+!IFDEF BINFILE
+ $(NAME)_BIN.sec
+ {
+ TYPE = EFI_SECTION_RAW
+ BIN = $(BINFILE)
+ }
+!ENDIF
+!IFDEF SECTION
+ $(BUILD_DIR)\$(SECTION)
+!ENDIF
+!IFDEF RESOURCE
+ $(NAME)_RES.sec
+ {
+ TYPE = EFI_SECTION_FREEFORM_SUBTYPE_GUID
+ BIN = $(RESOURCE)
+ GUID = $(SECTION_GUID)
+ }
+!ENDIF
+!IF DEFINED(FV_FILE) || DEFINED(FV_DESC)
+ $(NAME)_FV.sec
+ {
+ TYPE = EFI_SECTION_FIRMWARE_VOLUME_IMAGE
+!IFNDEF FV_DESC
+ BIN = FV_FILE
+!ELSE
+ FV_DESC = $(FV_DESC)
+!ENDIF
+ }
+!ENDIF
+!IF "$(CREATE_UI_SECTION)"=="1" && "$(TYPE)"!="EFI_FV_FILETYPE_FREEFORM" && "$(TYPE)"!="EFI_FV_FILETYPE_RAW"
+ $(NAME)_UI.sec
+ {
+ TYPE = EFI_SECTION_USER_INTERFACE
+ STRING = $(UI_NAME)
+ }
+!ENDIF
+!IFDEF VERSION
+ $(NAME)_VER.sec
+ {
+ TYPE = EFI_SECTION_VERSION
+ BUILD_NO = VERSION
+ STRING = $(VERSIONSTRING)
+ }
+!ENDIF
+!IF $(COMPRESS)==1
+ }
+!ENDIF
+!IFDEF RAWFILE
+ $(PROJECT_DIR)\$(RAWFILE)
+!ENDIF
+}
+<<KEEP
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/FV.mak b/Core/FV.mak
new file mode 100644
index 0000000..75bb13b
--- /dev/null
+++ b/Core/FV.mak
@@ -0,0 +1,215 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/FV.mak 12 9/10/12 4:43p Artems $
+#
+# $Revision: 12 $
+#
+# $Date: 9/10/12 4:43p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/FV.mak $
+#
+# 12 9/10/12 4:43p Artems
+# [TAG] EIP88859
+# [Category] Improvement
+# [Description] Build error in GenRomLayout.bat when too many FFS files
+# or file name is too long.
+# Added support to handle long strings in batch files
+# [Files] Fv.mak, Core.mak
+#
+# 11 6/23/11 4:37p Artems
+# EIP 61949: apriori list make doesn't work. Made changes to use FWBuild
+# for apriori list generation
+#
+# 10 2/05/11 1:42p Artems
+# Added PEI apriori list support
+# Added Nested FV support
+# Added PI 1.0-1.1 support
+#
+# 9 11/05/10 1:44p Felixp
+# Improvement(EIP 46043):
+# The build script that generates firmware volume description files
+# (Build\FV_xxx.inf) is updated
+# to support longer file lists.
+#
+# 8 1/26/10 5:03p Felixp
+# Support for generation of the DXE apriori file is added.
+# The list of FFS files that should be added to the DXE a priori list is
+# specified
+# as a part of FV descriptor using DXE_APRIORI_FILE_LIST parameter.
+#
+# 7 8/27/09 10:44a Felixp
+# Support for OPTIMIZE_SIZE and TOP_DOWN_ALLOCATION FV flags is added.
+#
+# 6 5/08/09 6:06p Felixp
+# support for ROM holes (FFS files with fixed addresses) is added
+#
+# 5 5/08/09 12:15a Felixp
+# Ifrastructure to simplify ROM layout customization(EIP 18426).
+# Build process and source code that deals with ROM layout
+# is updated in order to simplify ROM layout customization.
+#
+# 4 12/29/06 4:02p Felixp
+#
+# 2 7/22/05 2:20a Felixp
+# support for non-FFS Firmware Volume GUID added
+#
+# 1 1/28/05 12:43p Felixp
+#
+# 2 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 1 12/23/04 9:41a Felixp
+#
+# 4 7/13/04 2:23p Felixp
+#
+# 3 7/13/04 10:42a Felixp
+#
+# 2 1/08/04 4:46p Felixp
+# comments improved
+#
+# 1 12/05/03 4:15p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: FV.mak
+#
+# Description: This makefile is used to create firmware volume.
+# The following macros have to be defined:
+# BUILD_DIR - build directory that has all the input FFS files.
+# The output file $(NAME).fv will be created in this directory.
+# ADDRESS - starting memory address for the firmware volume.
+# NAME - name of the output firmware volume file (just name, no extension)
+# BLOCKS - number of firmware device blocks occupied by the firmware volume
+# BLOCK_SIZE - size of firmware device block in bytes
+# GENFVIMAGE - full name (path+name) of the GenFvImage utility
+# FILE_LIST - space separated list of FFS files to be included into FV
+# ERASE_POLARITY - 0 or 1. Firmware device erase polarity.
+# The following optional macros may be defined:
+# DXE_APRIORI_FILE_LIST - space separated list of FFS files to be added to the DXE a priori list
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+
+!IF "$(PEI_APRIORI_FILE_LIST)"!="" && DEFINED(PI_SPECIFICATION_VERSION)
+!IF $(PI_SPECIFICATION_VERSION)<0x00010000
+!UNDEF PEI_APRIORI_FILE_LIST
+!ENDIF
+!ENDIF
+
+!IF "$(FILE_LIST)"==""
+!IF "$(FILE_LIST_FILE)"==""
+!ERROR Empty file list for Firmware volume $(NAME)
+!ELSE
+!INCLUDE $(FILE_LIST_FILE)
+!ENDIF
+!ENDIF
+
+# Delete extra spaces and spaces before and after the colon
+FILE_LIST1=$(FILE_LIST: = )
+FILE_LIST2=$(FILE_LIST1: = )
+FILE_LIST3=$(FILE_LIST2: = )
+FILE_LIST4=$(FILE_LIST3: = )
+FILE_LIST5=$(FILE_LIST4: = )
+FILE_LIST6=$(FILE_LIST5: :=:) #delete space before the colon
+FILE_LIST_CLEAN=$(FILE_LIST6:: =:) #delete space after the colon
+
+all:
+ @copy << $(BUILD_DIR)\$(NAME).inf > NUL
+[options]
+EFI_BASE_ADDRESS = $(ADDRESS)
+EFI_FILE_NAME = $(BUILD_DIR)\$(NAME).FV
+EFI_NUM_BLOCKS = $(BLOCKS)
+EFI_BLOCK_SIZE = $(BLOCK_SIZE)
+!IFDEF FV_GUID
+EFI_FV_GUID = $(FV_GUID)
+!ENDIF
+!IFDEF OPTIMIZE_SIZE
+OPTIMIZE_SIZE = $(OPTIMIZE_SIZE)
+!ENDIF
+!IFDEF TOP_DOWN_ALLOCATION
+TOP_DOWN_ALLOCATION = $(TOP_DOWN_ALLOCATION)
+!ENDIF
+!IF "$(GLOBAL_COMPRESSION)"=="0"
+IGNORE_COMPRESSION = TRUE
+!ENDIF
+[attributes]
+EFI_READ_DISABLED_CAP = TRUE
+EFI_READ_ENABLED_CAP = TRUE
+EFI_READ_STATUS = TRUE
+EFI_WRITE_DISABLED_CAP = TRUE
+EFI_WRITE_ENABLED_CAP = TRUE
+EFI_WRITE_STATUS = TRUE
+EFI_LOCK_CAP = TRUE
+EFI_LOCK_STATUS = TRUE
+EFI_STICKY_WRITE = TRUE
+EFI_MEMORY_MAPPED = TRUE
+EFI_ERASE_POLARITY = $(ERASE_POLARITY)
+EFI_ALIGNMENT_CAP = TRUE
+EFI_ALIGNMENT_2 = TRUE
+EFI_ALIGNMENT_4 = TRUE
+EFI_ALIGNMENT_8 = TRUE
+EFI_ALIGNMENT_16 = TRUE
+EFI_ALIGNMENT_32 = TRUE
+EFI_ALIGNMENT_64 = TRUE
+EFI_ALIGNMENT_128 = TRUE
+EFI_ALIGNMENT_256 = TRUE
+EFI_ALIGNMENT_512 = TRUE
+EFI_ALIGNMENT_1K = TRUE
+EFI_ALIGNMENT_2K = TRUE
+EFI_ALIGNMENT_4K = TRUE
+EFI_ALIGNMENT_8K = TRUE
+EFI_ALIGNMENT_16K = TRUE
+EFI_ALIGNMENT_32K = TRUE
+EFI_ALIGNMENT_64K = TRUE
+#//PI 1.1 New Attribute for PI 1.0 spec
+EFI_READ_LOCK_CAP = TRUE
+EFI_READ_LOCK_STATUS = TRUE
+EFI_WRITE_LOCK_CAP = TRUE
+EFI_WRITE_LOCK_STATUS = TRUE
+EFI_FVB2_ALIGNMENT = 8
+<<
+ $(ECHO) ^ $(BUILD_DIR)\GenFvList.bat <<$(BUILD_DIR)\$(NAME)FileList.txt $(BUILD_DIR)\$(NAME).inf [files] >> $(BUILD_DIR)\beforefv.mak
+$(FILE_LIST_CLEAN: =^
+)
+<<KEEP
+!IF "$(DXE_APRIORI_FILE_LIST)"!=""
+ $(ECHO) ^ $(BUILD_DIR)\GenFvList.bat <<$(BUILD_DIR)\$(NAME)DxeAprioriIn.txt $(BUILD_DIR)\$(NAME).inf [dxeapriori] >> $(BUILD_DIR)\beforefv.mak
+$(DXE_APRIORI_FILE_LIST: =^
+)
+<<KEEP
+!ENDIF
+!IF "$(PEI_APRIORI_FILE_LIST)"!=""
+ $(ECHO) ^ $(BUILD_DIR)\GenFvList.bat <<$(BUILD_DIR)\$(NAME)PeiAprioriIn.txt $(BUILD_DIR)\$(NAME).inf [peiapriori] >> $(BUILD_DIR)\beforefv.mak
+$(PEI_APRIORI_FILE_LIST: =^
+)
+<<KEEP
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/FileSystem.ffs b/Core/FileSystem.ffs
new file mode 100644
index 0000000..2e549e2
--- /dev/null
+++ b/Core/FileSystem.ffs
Binary files differ
diff --git a/Core/FileSystemx64.ffs b/Core/FileSystemx64.ffs
new file mode 100644
index 0000000..28e7bf2
--- /dev/null
+++ b/Core/FileSystemx64.ffs
Binary files differ
diff --git a/Core/FloppyCtrl.ffs b/Core/FloppyCtrl.ffs
new file mode 100644
index 0000000..e9b3bce
--- /dev/null
+++ b/Core/FloppyCtrl.ffs
Binary files differ
diff --git a/Core/Foundation.cif b/Core/Foundation.cif
new file mode 100644
index 0000000..cb4c7a4
--- /dev/null
+++ b/Core/Foundation.cif
@@ -0,0 +1,66 @@
+<component>
+ name = "Foundation"
+ category = ModulePart
+ LocalRoot = "Core\"
+ RefName = "FoundationEdk"
+[files]
+"Foundation.sdl"
+"Foundation.mak"
+"EdkLib.c"
+"PeCoffLoader.c"
+"EfiCommonLib.h"
+"EfiDebug.h"
+"EfiDependency.h"
+"EfiFirmwareFileSystem.h"
+"EfiFirmwareVolumeHeader.h"
+"EfiHobLib.h"
+"EfiImage.h"
+"EfiImageFormat.h"
+"PeiDebug.h"
+"PeiApi.h"
+"PeiHob.h"
+"peihoblib.h"
+"PeiLib.h"
+"Tiano.h"
+"PPI\DxeIpl.h"
+"PPI\FindFv.h"
+"PPI\FirmwareVolume.h"
+"PPI\GuidedSectionExtraction.h"
+"PPI\LoadFile2.h"
+"PPI\MemoryDiscovered.h"
+"PPI\SectionExtraction.h"
+"PPI\Security.h"
+"PPI\Security2.h"
+"PPI\StatusCode.h"
+"Protocol\CustomizedDecompress.h"
+"Protocol\DebugMask.h"
+"Protocol\FileInfo.h"
+"Protocol\FirmwareVolumeDispatch.h"
+"Protocol\SectionExtraction.h"
+"Protocol\TianoDecompress.h"
+"Protocol\VariableWrite.h"
+"GUID\Apriori.h"
+"GUID\DebugImageInfoTable.h"
+"GUID\DxeServices.h"
+"GUID\EventGroup.h"
+"GUID\EventLegacyBios.h"
+"GUID\FirmwareFileSystem.h"
+"GUID\FirmwareFileSystem2.h"
+"GUID\FrameworkDevicePath.h"
+"GUID\GenericVariable.h"
+"GUID\Hob.h"
+"GUID\MemoryTypeInformation.h"
+"GUID\PeiApriori.h"
+"GUID\PeiFlushInstructionCache.h"
+"GUID\PeiPeCoffLoader.h"
+"GUID\PeiTransferControl.h"
+"GUID\StatusCode.h"
+"GUID\StatusCodeCallerId.h"
+"GUID\StatusCodeDataTypeId.h"
+[parts]
+"CORE_PEISrc_EDK"
+"CORE_DXESrc_EDK"
+"FoundationIa32"
+"Foundationx64"
+"FoundationIPF"
+<endComponent>
diff --git a/Core/Foundation.mak b/Core/Foundation.mak
new file mode 100644
index 0000000..aeb27e1
--- /dev/null
+++ b/Core/Foundation.mak
@@ -0,0 +1,126 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/SOURCE/Core/EDK/Foundation.mak 5 3/05/10 5:30p Felixp $
+#
+# $Revision: 5 $
+#
+# $Date: 3/05/10 5:30p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/SOURCE/Core/EDK/Foundation.mak $
+#
+# 5 3/05/10 5:30p Felixp
+# Enhancement:
+# Targets of types GUID_LIBRARY and PEI_GUID_LIBRARY are updated to
+# reduce length of the command line.
+#
+# 4 10/13/06 9:05p Felixp
+#
+# 3 8/25/06 10:56a Felixp
+#
+# 2 8/24/06 9:39a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 1 5/19/06 11:28p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Foundation.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : Foundation
+
+!IF "$(x64_BUILD)"=="1"
+FOUNDATION_PEI_GUID_LIB=$(BUILD_DIR)\FoundationPeiGuidLib.lib
+!ELSE
+FOUNDATION_PEI_GUID_LIB=$(BUILD_DIR)\FoundationGuidLib.lib
+!ENDIF
+
+!IF "$(PROCESSOR)"=="" || "$(PROCESSOR)"=="IA32"
+FoundationCpu_DIR=$(FoundationIa32_DIR)
+!ELSEIF "$(PROCESSOR)"=="x64"
+FoundationCpu_DIR=$(Foundationx64_DIR)
+!ELSEIF "$(PROCESSOR)"=="IPF"
+FoundationCpu_DIR=$(FoundationIPF_DIR)
+!ENDIF
+
+Foundation : $(BUILD_DIR)\Foundation.mak FoundationBin FoundationPeiBin
+
+$(BUILD_DIR)\Foundation.mak : $(Foundation_DIR)\$(@B).cif $(Foundation_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(Foundation_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+FoundationBin : $(BUILD_DIR)\FoundationProtocolLib.lib $(BUILD_DIR)\FoundationGuidLib.lib
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Foundation.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR) /I$(FoundationCpu_DIR)"\
+ TYPE=LIBRARY NAME=Foundation
+
+FoundationPeiBin : $(BUILD_DIR)\FoundationPpiLib.lib $(FOUNDATION_PEI_GUID_LIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ BUILD_DIR=$(BUILD_DIR)\IA32\
+ /f $(BUILD_DIR)\Foundation.mak all\
+ "CFLAGS=$(CFLAGS) /I$(Foundation_DIR) /I$(FoundationCpu_DIR)"\
+ TYPE=PEI_LIBRARY NAME=Foundation LIBRARY_NAME=$(BUILD_DIR)\FoundationPei.lib
+
+$(BUILD_DIR)\Foundation.lib $(BUILD_DIR)\FoundationPei.lib : Foundation
+
+$(BUILD_DIR)\FoundationProtocolLib.lib : $(Foundation_DIR)\Protocol\*.h
+ $(MAKE) /$(MAKEFLAGS) $(NO_EXT_OBJS_BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Core.mak all\
+ "MY_INCLUDES=/I$(Foundation_DIR)"\
+ TYPE=GUID_LIBRARY NAME=$(@B)\
+ "HEADERS=$(Foundation_DIR)\Protocol\^*.h"
+
+$(BUILD_DIR)\FoundationPpiLib.lib : $(Foundation_DIR)\Ppi\*.h
+ $(MAKE) /$(MAKEFLAGS) $(NO_EXT_OBJS_BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Core.mak all\
+ "MY_INCLUDES=/I$(Foundation_DIR)"\
+ TYPE=PEI_GUID_LIBRARY NAME=$(@B)\
+ "HEADERS=$(Foundation_DIR)\Ppi\^*.h"
+
+$(BUILD_DIR)\FoundationGuidLib.lib : $(Foundation_DIR)\Guid\*.h
+ $(MAKE) /$(MAKEFLAGS) $(NO_EXT_OBJS_BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Core.mak all\
+ "MY_INCLUDES=/I$(Foundation_DIR)"\
+ TYPE=GUID_LIBRARY NAME=$(@B)\
+ "HEADERS=$(Foundation_DIR)\Guid\^*.h"
+
+!IF "$(x64_BUILD)"=="1"
+$(BUILD_DIR)\FoundationPeiGuidLib.lib : $(Foundation_DIR)\Guid\*.h
+ $(MAKE) /$(MAKEFLAGS) $(NO_EXT_OBJS_BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\Core.mak all\
+ "MY_INCLUDES=/I$(Foundation_DIR)"\
+ TYPE=PEI_GUID_LIBRARY NAME=$(@B)\
+ "HEADERS=$(Foundation_DIR)\Guid\^*.h"
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2006, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/Foundation.sdl b/Core/Foundation.sdl
new file mode 100644
index 0000000..062db95
--- /dev/null
+++ b/Core/Foundation.sdl
@@ -0,0 +1,19 @@
+TOKEN
+ Name = "Foundation_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable Foundation support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "Foundation_DIR"
+End
+
+MODULE
+ Help = "Includes Foundation.mak to Project"
+ File = "Foundation.mak"
+End
+
diff --git a/Core/GUID/Apriori.h b/Core/GUID/Apriori.h
new file mode 100644
index 0000000..6e84269
--- /dev/null
+++ b/Core/GUID/Apriori.h
@@ -0,0 +1,62 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/Apriori.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/Apriori.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Apriori.h
+//
+// Description: DXE a priori file GUID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_APRIORI_GUID__H__
+#define __EFI_APRIORI_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <DXE.h>
+
+GUID_VARIABLE_DECLARATION(gAprioriGuid, EFI_APRIORI_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/DebugImageInfoTable.h b/Core/GUID/DebugImageInfoTable.h
new file mode 100644
index 0000000..a6f8bab
--- /dev/null
+++ b/Core/GUID/DebugImageInfoTable.h
@@ -0,0 +1,98 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/DebugImageInfoTable.h 2 10/07/06 10:23a Felixp $
+//
+// $Revision: 2 $
+//
+// $Date: 10/07/06 10:23a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/DebugImageInfoTable.h $
+//
+// 2 10/07/06 10:23a Felixp
+// UIEFI2.0 support.
+// Updated to EDK 20060904
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DebugImageInfoTable.h
+//
+// Description: Debug Image Info TableDXE
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_DEBUG_IMAGE_INFO_TABLE_GUID__H__
+#define __EFI_DEBUG_IMAGE_INFO_TABLE_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define EFI_DEBUG_IMAGE_INFO_TABLE_GUID \
+ { 0x49152e77,0x1ada,0x4764,0xb7,0xa2,0x7a,0xfe,0xfe,0xd9,0x5e,0x8b }
+
+GUID_VARIABLE_DECLARATION(gEfiDebugImageInfoTableGuid, EFI_DEBUG_IMAGE_INFO_TABLE_GUID);
+
+#ifndef GUID_VARIABLE_DEFINITION
+#include<Protocol/LoadedImage.h>
+
+#define EFI_DEBUG_IMAGE_INFO_UPDATE_IN_PROGRESS 0x01
+#define EFI_DEBUG_IMAGE_INFO_TABLE_MODIFIED 0x02
+#define EFI_DEBUG_IMAGE_INFO_TYPE_NORMAL 0x01
+
+typedef struct {
+ UINT64 Signature;
+ EFI_PHYSICAL_ADDRESS EfiSystemTableBase;
+ UINT32 Crc32;
+} EFI_SYSTEM_TABLE_POINTER;
+
+typedef struct {
+ UINTN ImageInfoType;
+ EFI_LOADED_IMAGE_PROTOCOL *LoadedImageProtocolInstance;
+ EFI_HANDLE *ImageHandle;
+} EFI_DEBUG_IMAGE_INFO_NORMAL;
+
+typedef union {
+ UINTN *ImageInfoType;
+ EFI_DEBUG_IMAGE_INFO_NORMAL *NormalImage;
+} EFI_DEBUG_IMAGE_INFO;
+
+typedef struct {
+ volatile UINT32 UpdateStatus;
+ UINT32 TableSize;
+ EFI_DEBUG_IMAGE_INFO *EfiDebugImageInfoTable;
+} EFI_DEBUG_IMAGE_INFO_TABLE_HEADER;
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#endif // #ifndef GUID_VARIABLE_DEFINITION
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/DxeServices.h b/Core/GUID/DxeServices.h
new file mode 100644
index 0000000..6e4c361
--- /dev/null
+++ b/Core/GUID/DxeServices.h
@@ -0,0 +1,62 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/DxeServices.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/DxeServices.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DxeServices.h
+//
+// Description: DXE Service Table GUID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __DXE_SERVICES_TABLE_GUID__H__
+#define __DXE_SERVICES_TABLE_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <DXE.h>
+
+GUID_VARIABLE_DECLARATION(gEfiDxeServicesTableGuid, DXE_SERVICES_TABLE_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/GUID/EventGroup.h b/Core/GUID/EventGroup.h
new file mode 100644
index 0000000..3134448
--- /dev/null
+++ b/Core/GUID/EventGroup.h
@@ -0,0 +1,73 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/EventGroup.h 2 2/05/11 3:35p Artems $
+//
+// $Revision: 2 $
+//
+// $Date: 2/05/11 3:35p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/EventGroup.h $
+//
+// 2 2/05/11 3:35p Artems
+// Added variable gEfiEventDxeDispatchGuid
+//
+// 1 10/07/06 10:22a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EventGroup.h
+//
+// Description: Declaration of even group GUIDs
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_EVENT_GROUP_GUID__H__
+#define __EFI_EVENT_GROUP_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <DXE.h>
+
+GUID_VARIABLE_DECLARATION(gEfiEventExitBootServicesGuid, EFI_EVENT_GROUP_EXIT_BOOT_SERVICES);
+
+GUID_VARIABLE_DECLARATION(gEfiEventVirtualAddressChangeGuid, EFI_EVENT_GROUP_VIRTUAL_ADDRESS_CHANGE);
+
+GUID_VARIABLE_DECLARATION(gEfiEventMemoryMapChangeGuid, EFI_EVENT_GROUP_MEMORY_MAP_CHANGE);
+
+GUID_VARIABLE_DECLARATION(gEfiEventReadyToBootGuid, EFI_EVENT_GROUP_READY_TO_BOOT);
+
+GUID_VARIABLE_DECLARATION(gEfiEventDxeDispatchGuid, EFI_EVENT_GROUP_DXE_DISPATCH);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/EventLegacyBios.h b/Core/GUID/EventLegacyBios.h
new file mode 100644
index 0000000..7c8fda4
--- /dev/null
+++ b/Core/GUID/EventLegacyBios.h
@@ -0,0 +1,62 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/EventLegacyBios.h 1 10/07/06 10:22a Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 10/07/06 10:22a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/EventLegacyBios.h $
+//
+// 1 10/07/06 10:22a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: EventLegacyBios.h
+//
+// Description: gEfiEventLegacyBiosGuid declaration
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_EVENT_LEGACY_BIOS_GUID__H__
+#define __EFI_EVENT_LEGACY_BIOS_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <DXE.h>
+
+GUID_VARIABLE_DECLARATION(gEfiEventLegacyBootGuid, EFI_EVENT_LEGACY_BOOT_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/FirmwareFileSystem.h b/Core/GUID/FirmwareFileSystem.h
new file mode 100644
index 0000000..d125b03
--- /dev/null
+++ b/Core/GUID/FirmwareFileSystem.h
@@ -0,0 +1,64 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/FirmwareFileSystem.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/FirmwareFileSystem.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FirmwareFileSystem.h
+//
+// Description: Firmware File System GUID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_FIRMWARE_FILE_SYSTEM_GUID__H__
+#define __EFI_FIRMWARE_FILE_SYSTEM_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <FFS.h>
+
+GUID_VARIABLE_DECLARATION(gEfiFirmwareFileSystemGuid, EFI_FIRMWARE_FILE_SYSTEM_GUID);
+GUID_VARIABLE_DECLARATION(gEfiFirmwareVolumeTopFileGuid, EFI_FFS_VOLUME_TOP_FILE_GUID);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/GUID/FirmwareFileSystem2.h b/Core/GUID/FirmwareFileSystem2.h
new file mode 100644
index 0000000..e36f172
--- /dev/null
+++ b/Core/GUID/FirmwareFileSystem2.h
@@ -0,0 +1,33 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FirmwareFileSystem2.h
+
+Abstract:
+
+ PI 1.0 spec definition.
+
+--*/
+
+#ifndef __FIRMWARE_FILE_SYSTEM2_GUID_H__
+#define __FIRMWARE_FILE_SYSTEM2_GUID_H__
+
+//
+// GUIDs defined by the FFS specification.
+//
+#define EFI_FIRMWARE_FILE_SYSTEM2_GUID \
+ { 0x8c8ce578, 0x8a3d, 0x4f1c, { 0x99, 0x35, 0x89, 0x61, 0x85, 0xc3, 0x2d, 0xd3 } }
+
+GUID_VARIABLE_DECLARATION(gEfiFirmwareFileSystem2Guid,EFI_FIRMWARE_FILE_SYSTEM2_GUID);
+
+#endif
diff --git a/Core/GUID/FrameworkDevicePath.h b/Core/GUID/FrameworkDevicePath.h
new file mode 100644
index 0000000..68d1bfb
--- /dev/null
+++ b/Core/GUID/FrameworkDevicePath.h
@@ -0,0 +1,64 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/FrameworkDevicePath.h 1 10/07/06 10:22a Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 10/07/06 10:22a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/FrameworkDevicePath.h $
+//
+// 1 10/07/06 10:22a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FrameworkDevicePath.h
+//
+// Description: gEfiFrameworkDevicePathGuid declaration
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_FRAMEWORK_DEVICE_PATH_GUID__H__
+#define __EFI_FRAMEWORK_DEVICE_PATH_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <EFI.h>
+#define EFI_FRAMEWORK_DEVICE_PATH_GUID \
+ { 0xb7084e63, 0x46b7, 0x4d1a, { 0x86, 0x77, 0xe3, 0x0b, 0x53, 0xdb, 0xf0, 0x50 } }
+
+GUID_VARIABLE_DECLARATION(gEfiFrameworkDevicePathGuid, EFI_FRAMEWORK_DEVICE_PATH_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/GenericVariable.h b/Core/GUID/GenericVariable.h
new file mode 100644
index 0000000..1d1772b
--- /dev/null
+++ b/Core/GUID/GenericVariable.h
@@ -0,0 +1,65 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/GenericVariable.h 1 11/19/09 12:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 11/19/09 12:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/GenericVariable.h $
+//
+// 1 11/19/09 12:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: GenericVariable.h
+//
+// Description: gEfiGenericVariableGuid declaration
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_GENERIC_VARIABLE_GUID__H__
+#define __EFI_GENERIC_VARIABLE_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <EFI.h>
+
+#define EFI_GENERIC_VARIABLE_GUID \
+ { 0x59d1c24f, 0x50f1, 0x401a, 0xb1, 0x01, 0xf3, 0x3e, 0x0d, 0xae, 0xd4, 0x43 }
+
+GUID_VARIABLE_DECLARATION(gEfiGenericVariableGuid, EFI_GENERIC_VARIABLE_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/Hob.h b/Core/GUID/Hob.h
new file mode 100644
index 0000000..a503a44
--- /dev/null
+++ b/Core/GUID/Hob.h
@@ -0,0 +1,62 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/Hob.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/Hob.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: HOB.h
+//
+// Description: HOB Table GUID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __HOB_LIST_GUID__H__
+#define __HOB_LIST_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <DXE.h>
+
+GUID_VARIABLE_DECLARATION(gEfiHobListGuid, HOB_LIST_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/MemoryTypeInformation.h b/Core/GUID/MemoryTypeInformation.h
new file mode 100644
index 0000000..a1d98fc
--- /dev/null
+++ b/Core/GUID/MemoryTypeInformation.h
@@ -0,0 +1,71 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/MemoryTypeInformation.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/MemoryTypeInformation.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: MemoryTypeInformation.h
+//
+// Description: Memory Type Information GUID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_MEMORY_TYPE_INFORMATION_GUID__H__
+#define __EFI_MEMORY_TYPE_INFORMATION_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define EFI_MEMORY_TYPE_INFORMATION_GUID \
+ { 0x4c19049f,0x4137,0x4dd3,0x9c,0x10,0x8b,0x97,0xa8,0x3f,0xfd,0xfa }
+
+GUID_VARIABLE_DECLARATION(gEfiMemoryTypeInformationGuid, EFI_MEMORY_TYPE_INFORMATION_GUID);
+
+#define EFI_MEMORY_TYPE_INFORMATION_VARIABLE_NAME L"MemoryTypeInformation"
+
+typedef struct {
+ UINT32 Type;
+ UINT32 NumberOfPages;
+} EFI_MEMORY_TYPE_INFORMATION;
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/PeiApriori.h b/Core/GUID/PeiApriori.h
new file mode 100644
index 0000000..470a64e
--- /dev/null
+++ b/Core/GUID/PeiApriori.h
@@ -0,0 +1,36 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiApriori.h
+
+Abstract:
+
+ PI 1.0 spec definition.
+
+--*/
+
+#ifndef __PEI_APRIORI_GUID_H__
+#define __PEI_APRIORI_GUID_H__
+
+#include <Efi.h>
+
+//
+// GUIDs defined by the FFS specification.
+//
+#define EFI_PEI_APRIORI_FILE_NAME_GUID \
+ { 0x1b45cc0a, 0x156a, 0x428a, 0xaf, 0x62, 0x49, 0x86, 0x4d, 0xa0, 0xe6, 0xe6}
+
+
+GUID_VARIABLE_DECLARATION(gEfiPeiAprioriGuid,EFI_PEI_APRIORI_FILE_NAME_GUID);
+
+#endif
diff --git a/Core/GUID/PeiFlushInstructionCache.h b/Core/GUID/PeiFlushInstructionCache.h
new file mode 100644
index 0000000..466bbee
--- /dev/null
+++ b/Core/GUID/PeiFlushInstructionCache.h
@@ -0,0 +1,23 @@
+#ifndef _PEI_FLUSH_INSTRUCTION_CACHE_GUID_H_
+#define _PEI_FLUSH_INSTRUCTION_CACHE_GUID_H_
+
+#define EFI_PEI_FLUSH_INSTRUCTION_CACHE_GUID \
+ { 0xd8117cfc, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
+
+EFI_FORWARD_DECLARATION (EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FLUSH_INSTRUCTION_CACHE_FLUSH) (
+ IN EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL *This,
+ IN EFI_PHYSICAL_ADDRESS Start,
+ IN UINT64 Length
+ );
+
+typedef struct _EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL {
+ EFI_PEI_FLUSH_INSTRUCTION_CACHE_FLUSH Flush;
+} EFI_PEI_FLUSH_INSTRUCTION_CACHE_PROTOCOL;
+
+extern EFI_GUID gEfiPeiFlushInstructionCacheGuid;
+
+#endif
diff --git a/Core/GUID/PeiPeCoffLoader.h b/Core/GUID/PeiPeCoffLoader.h
new file mode 100644
index 0000000..7c2010f
--- /dev/null
+++ b/Core/GUID/PeiPeCoffLoader.h
@@ -0,0 +1,119 @@
+/*++
+
+Copyright (c) 2005 - 2008, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiPeCoffLoader.h
+
+Abstract:
+
+ GUID for the PE/COFF Loader APIs shared between PEI and DXE
+
+--*/
+
+#ifndef _PEI_PE_COFF_LOADER_H_
+#define _PEI_PE_COFF_LOADER_H_
+
+#include "EfiImage.h"
+
+#define EFI_PEI_PE_COFF_LOADER_GUID \
+ { 0xd8117cff, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
+
+EFI_FORWARD_DECLARATION (EFI_PEI_PE_COFF_LOADER_PROTOCOL);
+
+#define EFI_IMAGE_ERROR_SUCCESS 0
+#define EFI_IMAGE_ERROR_IMAGE_READ 1
+#define EFI_IMAGE_ERROR_INVALID_PE_HEADER_SIGNATURE 2
+#define EFI_IMAGE_ERROR_INVALID_MACHINE_TYPE 3
+#define EFI_IMAGE_ERROR_INVALID_SUBSYSTEM 4
+#define EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS 5
+#define EFI_IMAGE_ERROR_INVALID_IMAGE_SIZE 6
+#define EFI_IMAGE_ERROR_INVALID_SECTION_ALIGNMENT 7
+#define EFI_IMAGE_ERROR_SECTION_NOT_LOADED 8
+#define EFI_IMAGE_ERROR_FAILED_RELOCATION 9
+#define EFI_IMAGE_ERROR_FAILED_ICACHE_FLUSH 10
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_PE_COFF_LOADER_READ_FILE) (
+ IN VOID *FileHandle,
+ IN UINTN FileOffset,
+ IN OUT UINTN *ReadSize,
+ OUT VOID *Buffer
+ );
+
+typedef struct {
+ EFI_PHYSICAL_ADDRESS ImageAddress;
+ UINT64 ImageSize;
+ EFI_PHYSICAL_ADDRESS DestinationAddress;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ EFI_PEI_PE_COFF_LOADER_READ_FILE ImageRead;
+ VOID *Handle;
+ VOID *FixupData;
+ UINT32 SectionAlignment;
+ UINT32 PeCoffHeaderOffset;
+ UINT32 DebugDirectoryEntryRva;
+ VOID *CodeView;
+ CHAR8 *PdbPointer;
+ UINTN SizeOfHeaders;
+ UINT32 ImageCodeMemoryType;
+ UINT32 ImageDataMemoryType;
+ UINT32 ImageError;
+ UINTN FixupDataSize;
+ UINT16 Machine;
+ UINT16 ImageType;
+ BOOLEAN RelocationsStripped;
+ BOOLEAN IsTeImage;
+#ifdef EFI_NT_EMULATOR
+ VOID **ModHandle;
+#endif
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ EFI_PHYSICAL_ADDRESS HiiResourceData;
+#endif
+} EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_PE_COFF_LOADER_GET_IMAGE_INFO) (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_PE_COFF_LOADER_LOAD_IMAGE) (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_PE_COFF_LOADER_RELOCATE_IMAGE) (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_PE_COFF_LOADER_UNLOAD_IMAGE) (
+ IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+typedef struct _EFI_PEI_PE_COFF_LOADER_PROTOCOL {
+ EFI_PEI_PE_COFF_LOADER_GET_IMAGE_INFO GetImageInfo;
+ EFI_PEI_PE_COFF_LOADER_LOAD_IMAGE LoadImage;
+ EFI_PEI_PE_COFF_LOADER_RELOCATE_IMAGE RelocateImage;
+ EFI_PEI_PE_COFF_LOADER_UNLOAD_IMAGE UnloadImage;
+} EFI_PEI_PE_COFF_LOADER_PROTOCOL;
+
+extern EFI_GUID gEfiPeiPeCoffLoaderGuid;
+
+#endif
diff --git a/Core/GUID/PeiTransferControl.h b/Core/GUID/PeiTransferControl.h
new file mode 100644
index 0000000..769ffcb
--- /dev/null
+++ b/Core/GUID/PeiTransferControl.h
@@ -0,0 +1,32 @@
+#ifndef _PEI_TRANSFER_CONTROL_H_
+#define _PEI_TRANSFER_CONTROL_H_
+
+#define EFI_PEI_TRANSFER_CONTROL_GUID \
+ { 0xd8117d02, 0x94a6, 0x11d4, 0x9a, 0x3a, 0x0, 0x90, 0x27, 0x3f, 0xc1, 0x4d }
+
+
+EFI_FORWARD_DECLARATION (EFI_PEI_TRANSFER_CONTROL_PROTOCOL);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_TRANSFER_CONTROL_SET_JUMP) (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ OUT VOID *Context
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_TRANSFER_CONTROL_LONG_JUMP) (
+ IN EFI_PEI_TRANSFER_CONTROL_PROTOCOL *This,
+ IN VOID *Context
+ );
+
+typedef struct _EFI_PEI_TRANSFER_CONTROL_PROTOCOL {
+ EFI_PEI_TRANSFER_CONTROL_LONG_JUMP SetJump;
+ EFI_PEI_TRANSFER_CONTROL_LONG_JUMP LongJump;
+ UINT32 JumpContextSize;
+} EFI_PEI_TRANSFER_CONTROL_PROTOCOL;
+
+extern EFI_GUID gEfiPeiTransferControlGuid;
+
+#endif
diff --git a/Core/GUID/StatusCode.h b/Core/GUID/StatusCode.h
new file mode 100644
index 0000000..e3da307
--- /dev/null
+++ b/Core/GUID/StatusCode.h
@@ -0,0 +1,33 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ StatusCode.h
+
+Abstract:
+
+ GUID used to identify Data Hub records that originate from the Tiano
+ ReportStatusCode API.
+
+--*/
+
+#ifndef _STATUS_CODE_H__
+#define _STATUS_CODE_H__
+
+#define EFI_STATUS_CODE_GUID \
+ { \
+ 0xd083e94c, 0x6560, 0x42e4, 0xb6, 0xd4, 0x2d, 0xf7, 0x5a, 0xdf, 0x6a, 0x2a \
+ }
+
+extern EFI_GUID gEfiStatusCodeGuid;
+
+#endif
diff --git a/Core/GUID/StatusCodeCallerId.h b/Core/GUID/StatusCodeCallerId.h
new file mode 100644
index 0000000..f3d0a69
--- /dev/null
+++ b/Core/GUID/StatusCodeCallerId.h
@@ -0,0 +1,67 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/StatusCodeCallerId.h 1 5/19/06 11:29p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:29p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/StatusCodeCallerId.h $
+//
+// 1 5/19/06 11:29p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeCallerId.h
+//
+// Description: Statuc Code Caller ID GUID
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __EFI_STANDARD_CALLER_ID_GUID__H__
+#define __EFI_STANDARD_CALLER_ID_GUID__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <StatusCodes.h>
+
+#define EFI_STANDARD_CALLER_ID_GUID \
+ {0xC9DCF469, 0xA7C4, 0x11D5, 0x87, 0xDA, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9}
+
+GUID_VARIABLE_DECLARATION(gEfiCallerIdGuid, EFI_STANDARD_CALLER_ID_GUID);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/GUID/StatusCodeDataTypeId.h b/Core/GUID/StatusCodeDataTypeId.h
new file mode 100644
index 0000000..6177e17
--- /dev/null
+++ b/Core/GUID/StatusCodeDataTypeId.h
@@ -0,0 +1,508 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/GUID/StatusCodeDataTypeId.h 3 1/12/12 12:13p Oleksiyy $
+//
+// $Revision: 3 $
+//
+// $Date: 1/12/12 12:13p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/GUID/StatusCodeDataTypeId.h $
+//
+// 3 1/12/12 12:13p Oleksiyy
+// [TAG] EIP75246
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] PI 1.2 Errata C Status Code
+// [RootCause] PI 1.2 Errata C introduced changies in definitions.
+// [Solution] Defenitions fixed up to PI 1.2 Errata C.
+// [Files] AmiStatusCodes.h, StatusCodes.h, StatusCodeDataTypeId.h
+//
+// 2 5/13/11 6:32p Oleksiyy
+// [TAG] EIP56645
+// [Category] Improvement
+// [Description] Status Code PI 1.2 Specification Update
+// [Files] DebugSupport.h, StatusCodeDataTypeId.h and StatusCodes.h
+//
+// 1 5/19/06 11:29p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: StatusCodeDataTypeId.h
+//
+// Description: Statuc Code Data Type ID GUIDs
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __STATUS_CODE_DATA_TYPE_GUIDS__H__
+#define __STATUS_CODE_DATA_TYPE_GUIDS__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <StatusCodes.h>
+//GUID_VARIABLE_DECLARATION(gEfiCallerIdGuid, EFI_STANDARD_CALLER_ID_GUID);
+
+//
+// The size of string
+//
+#define EFI_STATUS_CODE_DATA_MAX_STRING_SIZE 150
+
+//
+// This is the max data size including all the headers which can be passed
+// as Status Code data. This data should be multiple of 8 byte
+// to avoid any kind of boundary issue. Also, sum of this data size (inclusive
+// of size of EFI_STATUS_CODE_DATA should not exceed the max record size of
+// data hub
+//
+#define EFI_STATUS_CODE_DATA_MAX_SIZE 200
+
+//
+// String Data Type defintion. This is part of Status Code Specification
+//
+#ifndef EFI_STATUS_CODE_DATA_TYPE_STRING_GUID
+#define EFI_STATUS_CODE_DATA_TYPE_STRING_GUID \
+ { \
+ 0x92D11080, 0x496F, 0x4D95, 0xBE, 0x7E, 0x03, 0x74, 0x88, 0x38, 0x2B, 0x0A \
+ }
+#endif
+
+extern EFI_GUID gEfiStatusCodeDataTypeStringGuid;
+
+//
+// This GUID indicates that the format of the accompanying data depends
+// upon the Status Code Value, but follows this Specification
+//
+#ifndef EFI_STATUS_CODE_SPECIFIC_DATA_GUID
+#define EFI_STATUS_CODE_SPECIFIC_DATA_GUID \
+ { \
+ 0x335984bd, 0xe805, 0x409a, 0xb8, 0xf8, 0xd2, 0x7e, 0xce, 0x5f, 0xf7, 0xa6 \
+ }
+#endif
+
+extern EFI_GUID gEfiStatusCodeSpecificDataGuid;
+
+//already defined in StatusCodes.h
+/*#pragma pack(1)
+typedef enum {
+ EfiStringAscii,
+ EfiStringUnicode,
+ EfiStringToken
+} EFI_STRING_TYPE;
+
+typedef struct {
+ EFI_STRING_TYPE StringType;
+ //
+ // NULL terminated string follows here
+ //
+} EFI_STATUS_CODE_STRING_DATA;
+#pragma pack()*/
+//
+// Debug Assert Data. This is part of Status Code Specification
+//
+#define EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID \
+ { \
+ 0xDA571595, 0x4D99, 0x487C, 0x82, 0x7C, 0x26, 0x22, 0x67, 0x7D, 0x33, 0x07 \
+ }
+
+GUID_VARIABLE_DECLARATION(gEfiStatusCodeDataTypeAssertGuid, EFI_STATUS_CODE_DATA_TYPE_ASSERT_GUID);
+//extern EFI_GUID gEfiStatusCodeDataTypeAssertGuid;
+
+//
+// Exception Data type (CPU REGS)
+//
+#define EFI_STATUS_CODE_DATA_TYPE_EXCEPTION_HANDLER_GUID \
+ { \
+ 0x3BC2BD12, 0xAD2E, 0x11D5, 0x87, 0xDD, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xB9 \
+ }
+
+extern EFI_GUID gEfiStatusCodeDataTypeExceptionHandlerGuid;
+
+//
+// Debug DataType defintions. User Defined Data Types.
+//
+#define EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID \
+ { \
+ 0x9A4E9246, 0xD553, 0x11D5, 0x87, 0xE2, 0x00, 0x06, 0x29, 0x45, 0xC3, 0xb9 \
+ }
+
+#pragma pack(1)
+
+typedef struct {
+ UINT32 ErrorLevel;
+ //
+ // 12 * sizeof (UINT64) Var Arg stack
+ //
+ // ascii DEBUG () Format string
+ //
+} EFI_DEBUG_INFO;
+
+#pragma pack()
+
+//extern EFI_GUID gEfiStatusCodeDataTypeDebugGuid;
+GUID_VARIABLE_DECLARATION(gEfiStatusCodeDataTypeDebugGuid, EFI_STATUS_CODE_DATA_TYPE_DEBUG_GUID);
+
+//
+// Progress Code. User Defined Data Type Guid.
+//
+#define EFI_STATUS_CODE_DATA_TYPE_ERROR_GUID \
+ { \
+ 0xAB359CE3, 0x99B3, 0xAE18, 0xC8, 0x9D, 0x95, 0xD3, 0xB0, 0x72, 0xE1, 0x9B \
+ }
+
+extern EFI_GUID gEfiStatusCodeDataTypeErrorGuid;
+
+//
+// declaration for EFI_EXP_DATA. This may change
+//
+typedef UINTN EFI_EXP_DATA;
+
+//
+// Voltage Extended Error Data
+//
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_EXP_BASE10_DATA Voltage;
+ EFI_EXP_BASE10_DATA Threshold;
+} EFI_COMPUTING_UNIT_VOLTAGE_ERROR_DATA;
+#else
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_EXP_DATA Voltage;
+ EFI_EXP_DATA Threshold;
+} EFI_COMPUTING_UNIT_VOLTAGE_ERROR_DATA;
+#endif
+//
+// Microcode Update Extended Error Data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Version;
+} EFI_COMPUTING_UNIT_MICROCODE_UPDATE_ERROR_DATA;
+
+//
+// Asynchronous Timer Extended Error Data
+//
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_EXP_BASE10_DATA TimerLimit;
+} EFI_COMPUTING_UNIT_TIMER_EXPIRED_ERROR_DATA;
+#else
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_EXP_DATA TimerLimit;
+} EFI_COMPUTING_UNIT_TIMER_EXPIRED_ERROR_DATA;
+#endif
+//
+// Host Processor Mismatch Extended Error Data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Instance;
+ UINT16 Attributes;
+} EFI_HOST_PROCESSOR_MISMATCH_ERROR_DATA;
+
+//
+// EFI_COMPUTING_UNIT_MISMATCH_ATTRIBUTES
+// All other attributes are reserved for future use and
+// must be initialized to 0.
+//
+#define EFI_COMPUTING_UNIT_MISMATCH_SPEED 0x0001
+#define EFI_COMPUTING_UNIT_MISMATCH_FSB_SPEED 0x0002
+#define EFI_COMPUTING_UNIT_MISMATCH_FAMILY 0x0004
+#define EFI_COMPUTING_UNIT_MISMATCH_MODEL 0x0008
+#define EFI_COMPUTING_UNIT_MISMATCH_STEPPING 0x0010
+#define EFI_COMPUTING_UNIT_MISMATCH_CACHE_SIZE 0x0020
+#define EFI_COMPUTING_UNIT_MISMATCH_OEM1 0x1000
+#define EFI_COMPUTING_UNIT_MISMATCH_OEM2 0x2000
+#define EFI_COMPUTING_UNIT_MISMATCH_OEM3 0x4000
+#define EFI_COMPUTING_UNIT_MISMATCH_OEM4 0x8000
+
+//
+// Thermal Extended Error Data
+//
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_EXP_BASE10_DATA Temperature;
+ EFI_EXP_BASE10_DATA Threshold;
+} EFI_COMPUTING_UNIT_THERMAL_ERROR_DATA;
+#else
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_EXP_DATA Temperature;
+ EFI_EXP_DATA Threshold;
+} EFI_COMPUTING_UNIT_THERMAL_ERROR_DATA;
+#endif
+//
+// Processor Disabled Extended Error Data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Cause;
+ BOOLEAN SoftwareDisabled;
+} EFI_COMPUTING_UNIT_CPU_DISABLED_ERROR_DATA;
+
+typedef enum {
+ EfiInitCacheDataOnly,
+ EfiInitCacheInstrOnly,
+ EfiInitCacheBoth,
+ EfiInitCacheUnspecified
+} EFI_INIT_CACHE_TYPE;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//************************************************************
+// EFI_CPU_STATE_CHANGE_CAUSE
+//************************************************************
+typedef UINT32 EFI_CPU_STATE_CHANGE_CAUSE;
+//
+// The reason a processor was disabled
+//
+#define EFI_CPU_CAUSE_INTERNAL_ERROR 0x0001
+#define EFI_CPU_CAUSE_THERMAL_ERROR 0x0002
+#define EFI_CPU_CAUSE_SELFTEST_FAILURE 0x0004
+#define EFI_CPU_CAUSE_PREBOOT_TIMEOUT 0x0008
+#define EFI_CPU_CAUSE_FAILED_TO_START 0x0010
+#define EFI_CPU_CAUSE_CONFIG_ERROR 0x0020
+#define EFI_CPU_CAUSE_USER_SELECTION 0x0080
+#define EFI_CPU_CAUSE_BY_ASSOCIATION 0x0100
+#define EFI_CPU_CAUSE_UNSPECIFIED 0x8000
+
+#endif
+//
+// Embedded cache init extended data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Level;
+ EFI_INIT_CACHE_TYPE Type;
+} EFI_CACHE_INIT_DATA;
+
+//
+// Memory Extended Error Data
+//
+//
+// Memory Error Granularity Definition
+//
+typedef UINT8 EFI_MEMORY_ERROR_GRANULARITY;
+
+//
+// Memory Error Operation Definition
+//
+typedef UINT8 EFI_MEMORY_ERROR_OPERATION;
+
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_MEMORY_ERROR_GRANULARITY Granularity;
+ EFI_MEMORY_ERROR_OPERATION Operation;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ UINT32 Syndrome;
+#else
+ UINTN Syndrome;
+#endif
+ EFI_PHYSICAL_ADDRESS Address;
+ UINTN Resolution;
+} EFI_MEMORY_EXTENDED_ERROR_DATA;
+
+//
+// Memory Error Granularities
+//
+#define EFI_MEMORY_ERROR_OTHER 0x01
+#define EFI_MEMORY_ERROR_UNKNOWN 0x02
+#define EFI_MEMORY_ERROR_DEVICE 0x03
+#define EFI_MEMORY_ERROR_PARTITION 0x04
+
+//
+// Memory Error Operations
+//
+#define EFI_MEMORY_OPERATION_OTHER 0x01
+#define EFI_MEMORY_OPERATION_UNKNOWN 0x02
+#define EFI_MEMORY_OPERATION_READ 0x03
+#define EFI_MEMORY_OPERATION_WRITE 0x04
+#define EFI_MEMORY_OPERATION_PARTIAL_WRITE 0x05
+
+//
+// Define shorthands to describe Group Operations
+// Many memory init operations are essentially group
+// operations.
+// A shorthand to describe that the operation is performed
+// on multiple devices within the array
+//
+#define EFI_MULTIPLE_MEMORY_DEVICE_OPERATION 0xfffe
+//
+// A shorthand to describe that the operation is performed // on all devices within the array
+//
+#define EFI_ALL_MEMORY_DEVICE_OPERATION 0xffff
+//
+// A shorthand to describe that the operation is performed // on multiple arrays
+//
+#define EFI_MULTIPLE_MEMORY_ARRAY_OPERATION 0xfffe
+//
+// A shorthand to describe that the operation is performed // on all the arrays
+//
+#define EFI_ALL_MEMORY_ARRAY_OPERATION 0xffff
+
+//
+// DIMM number
+//
+#pragma pack(1)
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT16 Array;
+ UINT16 Device;
+} EFI_STATUS_CODE_DIMM_NUMBER;
+#pragma pack()
+//
+// Memory Module Mismatch Extended Error Data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_STATUS_CODE_DIMM_NUMBER Instance;
+} EFI_MEMORY_MODULE_MISMATCH_ERROR_DATA;
+
+//
+// Memory Range Extended Data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_PHYSICAL_ADDRESS Start;
+ EFI_PHYSICAL_ADDRESS Length;
+} EFI_MEMORY_RANGE_EXTENDED_DATA;
+
+//
+// Device handle Extended Data. Used for many
+// errors and progress codes to point to the device.
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_HANDLE Handle;
+} EFI_DEVICE_HANDLE_EXTENDED_DATA;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//
+//Extended data about the device path, which is used for many errors and progress codes
+//to point to the device.
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT8 *DevicePath;
+} EFI_DEVICE_PATH_EXTENDED_DATA;
+
+//
+// Resource Allocation Failure Extended Error Data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 Bar;
+ UINT16 DevicePathSize;
+ UINT16 ReqResSize;
+ UINT16 AllocResSize;
+ UINT8 *DevicePath;
+ UINT8 *ReqRes;
+ UINT8 *AllocRes;
+} EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA;
+#else
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ UINT32 Bar;
+ VOID *ReqRes;
+ VOID *AllocRes;
+} EFI_RESOURCE_ALLOC_FAILURE_ERROR_DATA;
+#endif
+
+/*Already defined in StatusCodes.h
+//
+// Extended Error Data for Assert
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ UINT32 LineNumber;
+ UINT32 FileNameSize;
+ EFI_STATUS_CODE_STRING_DATA *FileName;
+} EFI_DEBUG_ASSERT_DATA;
+*/
+//
+// System Context Data EBC/IA32/IPF
+//
+#ifndef GUID_VARIABLE_DEFINITION
+#include <Protocol/DebugSupport.h>
+
+typedef union {
+ EFI_SYSTEM_CONTEXT_EBC SystemContextEbc;
+ EFI_SYSTEM_CONTEXT_IA32 SystemContextIa32;
+ EFI_SYSTEM_CONTEXT_IPF SystemContextIpf;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ EFI_SYSTEM_CONTEXT_X64 SystemContextX64;
+ EFI_SYSTEM_CONTEXT_ARM SystemContextArm;
+#endif
+} EFI_STATUS_CODE_EXCEP_SYSTEM_CONTEXT;
+
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_STATUS_CODE_EXCEP_SYSTEM_CONTEXT Context;
+} EFI_STATUS_CODE_EXCEP_EXTENDED_DATA;
+#endif
+//
+// Legacy Oprom extended data
+//
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_HANDLE DeviceHandle;
+ EFI_PHYSICAL_ADDRESS RomImageBase;
+} EFI_LEGACY_OPROM_EXTENDED_DATA;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+typedef struct {
+ EFI_STATUS_CODE_DATA DataHeader;
+ EFI_HANDLE ControllerHandle;
+ EFI_HANDLE DriverBindingHandle;
+ UINT16 DevicePathSize;
+ UINT8 *RemainingDevicePath;
+} EFI_STATUS_CODE_START_EXTENDED_DATA;
+#endif
+//
+// Progress Code. User Defined Data Type Guid.
+//
+#define EFI_STATUS_CODE_DATA_TYPE_PROGRESS_CODE_GUID \
+ { \
+ 0xA356AB39, 0x35C4, 0x35DA, 0xB3, 0x7A, 0xF8, 0xEA, 0x9E, 0x8B, 0x36, 0xA3 \
+ }
+
+extern EFI_GUID gEfiStatusCodeDataTypeProgressCodeGuid;
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2012, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/InitList.c b/Core/InitList.c
new file mode 100644
index 0000000..041dca6
--- /dev/null
+++ b/Core/InitList.c
@@ -0,0 +1,86 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Core/InitList.c 3 6/16/05 10:42a Felixp $
+//
+// $Revision: 3 $
+//
+// $Date: 6/16/05 10:42a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Core/InitList.c $
+//
+// 3 6/16/05 10:42a Felixp
+// 1. Tokens.c added. It has variables representing SDL tokens.
+// 2. InitList.c extended to support 2 init lists
+//
+// 2 3/04/05 12:38p Mandal
+//
+// 1 1/28/05 12:43p Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:41a Felixp
+//
+// 1 7/12/04 6:31p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: InitList.c
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#include <efi.h>
+typedef EFI_STATUS (INIT_FUNCTION)(IN VOID* ImageHandle, IN VOID *SystemTable);
+//First init function
+#ifdef INIT_LIST
+extern INIT_FUNCTION INIT_LIST EndOfInitList;
+INIT_FUNCTION* InitList[] = {INIT_LIST NULL};
+
+VOID InitParts(IN VOID* ImageHandle, IN VOID *SystemTable)
+{
+ UINTN i;
+ for(i=0; InitList[i]; i++) InitList[i](ImageHandle,SystemTable);
+}
+#endif
+
+//Second init function
+#ifdef INIT_LIST2
+extern INIT_FUNCTION INIT_LIST2 EndOfInitList;
+INIT_FUNCTION* InitList2[] = {INIT_LIST2 NULL};
+
+VOID InitParts2(IN VOID* ImageHandle, IN VOID *SystemTable)
+{
+ UINTN i;
+ for(i=0; InitList2[i]; i++) InitList2[i](ImageHandle,SystemTable);
+}
+#endif
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/Languages.mak b/Core/Languages.mak
new file mode 100644
index 0000000..15d73e3
--- /dev/null
+++ b/Core/Languages.mak
@@ -0,0 +1,109 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Languages.mak 3 3/28/11 3:21p Felixp $
+#
+# $Revision: 3 $
+#
+# $Date: 3/28/11 3:21p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Languages.mak $
+#
+# 3 3/28/11 3:21p Felixp
+# Enhancement(EIP52278): CHINESE macro is updated to be an alias for the
+# CHINESE_TRAD.
+#
+# 2 7/07/10 11:23a Robert
+# Added language identifiers for more languages
+#
+# 4 6/11/10 3:42p Robert
+# - fixed spelling of Norwegian and added simplified and traditional
+# chinese
+# - For this to work you need a modified version of the UEFIStrGather
+# tool and a new fontcfg.ini file.
+#
+# 3 5/27/10 6:01p Robert
+# removed spaces from a language definition
+#
+# 2 5/26/10 5:56p Robert
+# added support for additional languages
+#
+# 1 10/09/09 5:10p Felixp
+#
+# 5 10/05/09 3:52p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Languages.mak
+#
+# Description: List of language identifiers
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+!IF $(EFI_SPECIFICATION_VERSION)>0x20000
+#ISO 639-2 Language Identifiers
+ENGLISH=en-US
+FRENCH=fr-FR
+SPANISH=es-ES
+GERMAN=de-DE
+RUSSIAN=ru-RU
+CHINESE_SIMP=zh-chs
+CHINESE_TRAD=zh-cht
+KOREAN=ko-KR
+JAPANESE=ja-JP
+ITALIAN=it-IT
+DANISH=da-DK
+FINNISH=fi-FI
+DUTCH=nl-NL
+NORWEGIAN=nb-NO
+PORTUGUESE=pt-BR
+SWEDISH=sv-FI
+!ELSE
+#RFC 4646 Language Identifiers
+ENGLISH=eng
+FRENCH=fra
+SPANISH=spa
+GERMAN=ger
+RUSSIAN=rus
+CHINESE_SIMP=zho
+CHINESE_TRAD=chi
+KOREAN=kor
+JAPANESE=jpn
+ITALIAN=ita
+DANISH=dan
+FINNISH=fin
+DUTCH=dut
+NORWEGIAN=nor
+PORTUGUESE=por
+SWEDISH=swe
+!ENDIF
+CHINESE=$(CHINESE_TRAD)
+
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/PPI/DxeIpl.h b/Core/PPI/DxeIpl.h
new file mode 100644
index 0000000..35897e6
--- /dev/null
+++ b/Core/PPI/DxeIpl.h
@@ -0,0 +1,65 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PPI/DxeIpl.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PPI/DxeIpl.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: DxeIpl.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __DXE_IPL_PPI__H__
+#define __DXE_IPL_PPI__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+//DxeIpl is defined in PEI.h
+#include <PEI.h>
+
+GUID_VARIABLE_DECLARATION(gEfiDxeIplPpiGuid, EFI_DXE_IPL_PPI_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/PPI/FindFv.h b/Core/PPI/FindFv.h
new file mode 100644
index 0000000..c8ab421
--- /dev/null
+++ b/Core/PPI/FindFv.h
@@ -0,0 +1,80 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PPI/FindFv.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PPI/FindFv.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: FindFv.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __FIND_FV_PPI__H__
+#define __FIND_FV_PPI__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <PEI.h>
+#include <FFS.h>
+
+#define EFI_FIND_FV_PPI_GUID \
+ { 0x36164812, 0xa023, 0x44e5, 0xbd, 0x85, 0x5, 0xbf, 0x3c, 0x77, 0x0, 0xaa }
+
+typedef struct _EFI_FIND_FV_PPI EFI_FIND_FV_PPI;
+
+typedef EFI_STATUS (EFIAPI *EFI_FIND_FV_FINDFV)(
+ IN EFI_FIND_FV_PPI * This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ UINT8 *FvNumber, EFI_FIRMWARE_VOLUME_HEADER **FVAddress
+);
+
+struct _EFI_FIND_FV_PPI {
+ EFI_FIND_FV_FINDFV FindFv;
+};
+
+GUID_VARIABLE_DECLARATION(gEfiFindFvPpiGuid, EFI_FIND_FV_PPI_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/PPI/FirmwareVolume.h b/Core/PPI/FirmwareVolume.h
new file mode 100644
index 0000000..2b6e3a1
--- /dev/null
+++ b/Core/PPI/FirmwareVolume.h
@@ -0,0 +1,99 @@
+/*++
+
+Copyright (c) 2007 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FirmwareVolume.h
+
+Abstract:
+
+ PI 1.0 spec definition.
+
+--*/
+
+#ifndef __FIRMWARE_VOLUME_H__
+#define __FIRMWARE_VOLUME_H__
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x00010000)
+#include <Pei.h>
+
+EFI_FORWARD_DECLARATION (EFI_PEI_FIRMWARE_VOLUME_PPI);
+
+typedef UINT32 EFI_FV_FILE_ATTRIBUTES;
+typedef VOID * EFI_PEI_FILE_HANDLE;
+typedef VOID * EFI_PEI_FV_HANDLE;
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FV_PROCESS_FV) (
+ IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
+ IN VOID *Buffer,
+ IN UINTN BufferSize,
+ OUT EFI_PEI_FV_HANDLE *FvHandle
+ );
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FV_FIND_FILE_TYPE) (
+ IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
+ IN EFI_FV_FILETYPE SearchType,
+ IN EFI_PEI_FV_HANDLE FvHandle,
+ IN OUT EFI_PEI_FILE_HANDLE *FileHandle
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FV_FIND_FILE_NAME) (
+ IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
+ IN CONST EFI_GUID *FileName,
+ IN OUT EFI_PEI_FV_HANDLE *FvHandle,
+ OUT EFI_PEI_FILE_HANDLE *FileHandle
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FV_GET_FILE_INFO) (
+ IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT EFI_FV_FILE_INFO *FileInfo
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FV_GET_INFO)(
+ IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
+ IN EFI_PEI_FV_HANDLE FvHandle,
+ OUT EFI_FV_INFO *VolumeInfo
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_FV_FIND_SECTION) (
+ IN CONST EFI_PEI_FIRMWARE_VOLUME_PPI *This,
+ IN EFI_SECTION_TYPE SearchType,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ OUT VOID **SectionData
+ );
+
+typedef struct _EFI_PEI_FIRMWARE_VOLUME_PPI {
+ EFI_PEI_FV_PROCESS_FV ProcessVolume;
+ EFI_PEI_FV_FIND_FILE_TYPE FindFileByType;
+ EFI_PEI_FV_FIND_FILE_NAME FindFileByName;
+ EFI_PEI_FV_GET_FILE_INFO GetFileInfo;
+ EFI_PEI_FV_GET_INFO GetVolumeInfo;
+ EFI_PEI_FV_FIND_SECTION FindSectionByType;
+} EFI_PEI_FIRMWARE_VOLUME_PPI;
+
+#endif
+
+
+#endif \ No newline at end of file
diff --git a/Core/PPI/GuidedSectionExtraction.h b/Core/PPI/GuidedSectionExtraction.h
new file mode 100644
index 0000000..b53ffa6
--- /dev/null
+++ b/Core/PPI/GuidedSectionExtraction.h
@@ -0,0 +1,42 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ GuidedSectionExtraction.h
+
+Abstract:
+
+ PI 1.0 spec definition.
+
+--*/
+
+
+#ifndef __GUIDED_SECTION_EXTRACTION_PPI_H__
+#define __GUIDED_SECTION_EXTRACTION_PPI_H__
+
+EFI_FORWARD_DECLARATION (EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_EXTRACT_GUIDED_SECTION)(
+ IN CONST EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI *This,
+ IN CONST VOID *InputSection,
+ OUT VOID **OutputBuffer,
+ OUT UINTN *OutputSize,
+ OUT UINT32 *AuthenticationStatus
+ );
+
+typedef struct _EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI {
+ EFI_PEI_EXTRACT_GUIDED_SECTION ExtractSection;
+} EFI_PEI_GUIDED_SECTION_EXTRACTION_PPI;
+
+#endif
diff --git a/Core/PPI/LoadFile2.h b/Core/PPI/LoadFile2.h
new file mode 100644
index 0000000..a87a198
--- /dev/null
+++ b/Core/PPI/LoadFile2.h
@@ -0,0 +1,5 @@
+#ifndef __LOAD_FILE_PPI_H__
+#define __LOAD_FILE_PPI_H__
+#include <Ppi/LoadFile.h>
+#define gEfiLoadFile2PpiGuid gEfiPeiLoadFilePpiGuid
+#endif
diff --git a/Core/PPI/MemoryDiscovered.h b/Core/PPI/MemoryDiscovered.h
new file mode 100644
index 0000000..4bf69d8
--- /dev/null
+++ b/Core/PPI/MemoryDiscovered.h
@@ -0,0 +1,65 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PPI/MemoryDiscovered.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PPI/MemoryDiscovered.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: MemoryDiscovered.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __PERMANENT_MEMORY_INSTALLED_PPI__H__
+#define __PERMANENT_MEMORY_INSTALLED_PPI__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <PEI.h>
+#define PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+
+GUID_VARIABLE_DECLARATION(gPeiMemoryDiscoveredPpiGuid, PEI_PERMANENT_MEMORY_INSTALLED_PPI_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/PPI/SectionExtraction.h b/Core/PPI/SectionExtraction.h
new file mode 100644
index 0000000..0c022b6
--- /dev/null
+++ b/Core/PPI/SectionExtraction.h
@@ -0,0 +1,59 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ SectionExtraction.h
+
+Abstract:
+
+ Section Extraction PPI as defined in Tiano
+
+--*/
+
+#ifndef _SECTION_EXTRACTION_PPI_H_
+#define _SECTION_EXTRACTION_PPI_H_
+
+#define EFI_PEI_SECTION_EXTRACTION_PPI_GUID \
+ { \
+ 0x4F89E208, 0xE144, 0x4804, 0x9E, 0xC8, 0x0F, 0x89, 0x4F, 0x7E, 0x36, 0xD7 \
+ }
+
+EFI_FORWARD_DECLARATION (EFI_PEI_SECTION_EXTRACTION_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_GET_SECTION) (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_SECTION_EXTRACTION_PPI * This,
+ IN EFI_SECTION_TYPE * SectionType,
+ IN EFI_GUID * SectionDefinitionGuid, OPTIONAL
+ IN UINTN SectionInstance,
+ IN VOID **Buffer,
+ IN OUT UINT32 *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ );
+
+//
+// Bit values for AuthenticationStatus
+//
+#define EFI_PEI_AUTH_STATUS_PLATFORM_OVERRIDE 0x01
+#define EFI_PEI_AUTH_STATUS_IMAGE_SIGNED 0x02
+#define EFI_PEI_AUTH_STATUS_NOT_TESTED 0x04
+#define EFI_PEI_AUTH_STATUS_TEST_FAILED 0x08
+
+typedef struct _EFI_PEI_SECTION_EXTRACTION_PPI {
+ EFI_PEI_GET_SECTION PeiGetSection;
+} EFI_PEI_SECTION_EXTRACTION_PPI;
+
+GUID_VARIABLE_DECLARATION(gPeiSectionExtractionPpiGuid, EFI_PEI_SECTION_EXTRACTION_PPI_GUID);
+
+#endif
diff --git a/Core/PPI/Security.h b/Core/PPI/Security.h
new file mode 100644
index 0000000..fba6a6f
--- /dev/null
+++ b/Core/PPI/Security.h
@@ -0,0 +1,83 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PPI/Security.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PPI/Security.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Security.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __SECURITY_PPI_H__
+#define __SECURITY_PPI_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <PEI.h>
+#include <FFS.h>
+
+#define PEI_SECURITY_PPI_GUID \
+ { 0x1388066e, 0x3a57, 0x4efa, 0x98, 0xf3, 0xc1, 0x2f, 0x3a, 0x95, 0x8a, 0x29 }
+
+typedef struct _PEI_SECURITY_PPI PEI_SECURITY_PPI;
+
+typedef EFI_STATUS (EFIAPI *PEI_SECURITY_AUTHENTICATION_STATE)(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN PEI_SECURITY_PPI *This,
+ IN UINT32 AuthenticationStatus,
+ IN EFI_FFS_FILE_HEADER *FfsFileHeader,
+ IN OUT BOOLEAN *StartCrisisRecovery
+);
+
+struct _PEI_SECURITY_PPI {
+ PEI_SECURITY_AUTHENTICATION_STATE AuthenticationState;
+};
+
+GUID_VARIABLE_DECLARATION(gPeiSecurityPpiGuid, PEI_SECURITY_PPI_GUID);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/PPI/Security2.h b/Core/PPI/Security2.h
new file mode 100644
index 0000000..ff4e4d1
--- /dev/null
+++ b/Core/PPI/Security2.h
@@ -0,0 +1,54 @@
+/*++
+
+Copyright (c) 2007, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ Security2.h
+
+Abstract:
+
+ PI 1.0 spec definition.
+
+--*/
+
+
+#ifndef __SECURITY2_PPI_H__
+#define __SECURITY2_PPI_H__
+
+#if defined(PI_SPECIFICATION_VERSION) && PI_SPECIFICATION_VERSION >= 0x00010000
+
+#define EFI_PEI_SECURITY2_PPI_GUID \
+ { 0xdcd0be23, 0x9586, 0x40f4, 0xb6, 0x43, 0x6, 0x52, 0x2c, 0xed, 0x4e, 0xde}
+
+
+EFI_FORWARD_DECLARATION (EFI_PEI_SECURITY2_PPI);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_SECURITY_AUTHENTICATION_STATE) (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CONST EFI_PEI_SECURITY2_PPI *This,
+ IN UINT32 AuthenticationStatus,
+ IN EFI_PEI_FV_HANDLE FvHandle,
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN OUT BOOLEAN *DeferExection
+ );
+
+typedef struct _EFI_PEI_SECURITY2_PPI {
+ EFI_PEI_SECURITY_AUTHENTICATION_STATE AuthenticationState;
+} EFI_PEI_SECURITY2_PPI;
+
+
+GUID_VARIABLE_DECLARATION(gEfiPeiSecurity2PpiGuid, EFI_PEI_SECURITY2_PPI_GUID);
+
+#endif
+
+#endif
diff --git a/Core/PPI/StatusCode.h b/Core/PPI/StatusCode.h
new file mode 100644
index 0000000..13f4950
--- /dev/null
+++ b/Core/PPI/StatusCode.h
@@ -0,0 +1,56 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/PPI/StatusCode.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/PPI/StatusCode.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: <This File Name>
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+// Sometimes equivalent Aptio4 and EDK Headers have different names.
+// This file provides compatibility
+//**********************************************************************
+#ifndef GUID_VARIABLE_DEFINITION
+#include <PPI/ProgressCode.h>
+#endif
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/PeCoffLoader.c b/Core/PeCoffLoader.c
new file mode 100644
index 0000000..6d76bce
--- /dev/null
+++ b/Core/PeCoffLoader.c
@@ -0,0 +1,1467 @@
+/*++
+
+Copyright (c) 2005 - 2009, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeCoffLoader.c
+
+Abstract:
+
+ Tiano PE/COFF loader
+
+Revision History
+
+--*/
+
+#include "Tiano.h"
+#include "Pei.h"
+#include "PeiLib.h"
+#include "PeCoffLoaderEx.h"
+
+#ifdef EFI_NT_EMULATOR
+#include "peilib.h"
+#include "EfiHobLib.h"
+#include EFI_PPI_DEFINITION (NtLoadAsDll)
+#endif
+
+STATIC
+EFI_STATUS
+PeCoffLoaderGetPeHeader (
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
+ );
+
+STATIC
+VOID*
+PeCoffLoaderImageAddress (
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN UINTN Address
+ );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetImageInfo (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderRelocateImage (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderLoadImage (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderUnloadImage (
+ IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ );
+
+#if defined (EFI_DEBUG_ITP_BREAK) && !defined (_CONSOLE)
+VOID
+AsmEfiSetBreakSupport (
+ IN UINTN LoadAddr
+ );
+#endif
+
+EFI_PEI_PE_COFF_LOADER_PROTOCOL mPeCoffLoader = {
+ PeCoffLoaderGetImageInfo,
+ PeCoffLoaderLoadImage,
+ PeCoffLoaderRelocateImage,
+ PeCoffLoaderUnloadImage
+};
+
+#ifdef EFI_NT_EMULATOR
+EFI_NT_LOAD_AS_DLL_PPI *mPeCoffLoaderWinNtLoadAsDll = NULL;
+#endif
+
+EFI_STATUS
+InstallEfiPeiPeCoffLoader (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PEI_PE_COFF_LOADER_PROTOCOL **This,
+ IN EFI_PEI_PPI_DESCRIPTOR *ThisPpi
+ )
+/*++
+
+Routine Description:
+
+ Install PE/COFF loader PPI
+
+Arguments:
+
+ PeiServices - General purpose services available to every PEIM
+
+ This - Pointer to get Pei PE coff loader protocol as output
+
+ ThisPpi - Passed in as EFI_NT_LOAD_AS_DLL_PPI on NT_EMULATOR platform
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+#ifdef EFI_NT_EMULATOR
+ //
+ // For use by PEI Core and Modules
+ //
+ if (NULL != PeiServices) {
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gEfiNtLoadAsDllPpiGuid,
+ 0,
+ NULL,
+ &mPeCoffLoaderWinNtLoadAsDll
+ );
+ } else {
+ //
+ // Now in SecMain or ERM usage, bind appropriately
+ //
+ PEI_ASSERT (PeiServices, (NULL != ThisPpi));
+
+ mPeCoffLoaderWinNtLoadAsDll = (EFI_NT_LOAD_AS_DLL_PPI *) ThisPpi;
+ PEI_ASSERT (PeiServices, (NULL != mPeCoffLoaderWinNtLoadAsDll));
+ }
+#endif
+
+ if (NULL != This) {
+ *This = &mPeCoffLoader;
+ }
+
+ return Status;
+}
+
+STATIC
+EFI_STATUS
+PeCoffLoaderGetPeHeader (
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ OUT EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr
+ )
+/*++
+
+Routine Description:
+
+ Retrieves the PE or TE Header from a PE/COFF or TE image
+
+Arguments:
+
+ ImageContext - The context of the image being loaded
+
+ PeHdr - The buffer in which to return the PE32, PE32+, or TE header
+
+Returns:
+
+ EFI_SUCCESS if the PE or TE Header is read,
+ Otherwise, the error status from reading the PE/COFF or TE image using the ImageRead function.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_DOS_HEADER DosHdr;
+ UINTN Size;
+ UINT16 Magic;
+
+ //
+ // Read the DOS image header to check for it's existance
+ //
+ Size = sizeof (EFI_IMAGE_DOS_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ 0,
+ &Size,
+ &DosHdr
+ );
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ ImageContext->PeCoffHeaderOffset = 0;
+ if (DosHdr.e_magic == EFI_IMAGE_DOS_SIGNATURE) {
+ //
+ // DOS image header is present, so read the PE header after the DOS image
+ // header
+ //
+ ImageContext->PeCoffHeaderOffset = DosHdr.e_lfanew;
+ }
+
+ //
+ // Read the PE/COFF Header. For PE32 (32-bit) this will read in too much
+ // data, but that should not hurt anythine. Hdr.Pe32->OptionalHeader.Magic
+ // determins if this is a PE32 or PE32+ image. The magic is in the same
+ // location in both images.
+ //
+ Size = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ ImageContext->PeCoffHeaderOffset,
+ &Size,
+ Hdr.Pe32
+ );
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ //
+ // Use Signature to figure out if we understand the image format
+ //
+ if (Hdr.Te->Signature == EFI_TE_IMAGE_HEADER_SIGNATURE) {
+ ImageContext->IsTeImage = TRUE;
+ ImageContext->Machine = Hdr.Te->Machine;
+ ImageContext->ImageType = (UINT16)(Hdr.Te->Subsystem);
+ ImageContext->ImageSize = 0;
+ ImageContext->SectionAlignment = 4096;
+ ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN)Hdr.Te->BaseOfCode - (UINTN)Hdr.Te->StrippedSize;
+
+ } else if (Hdr.Pe32->Signature == EFI_IMAGE_NT_SIGNATURE) {
+ ImageContext->IsTeImage = FALSE;
+ ImageContext->Machine = Hdr.Pe32->FileHeader.Machine;
+
+ //
+ // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
+ // It is for backward-compatibility consideration, because
+ // some system will generate PE32+ image with PE32 Magic.
+ //
+ if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ Magic = Hdr.Pe32->OptionalHeader.Magic;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC ||
+ Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {
+ //
+ // PE32 and PE32+ have the same offset for these fields.
+ // We use PE32 for both PE32 and PE32+ headers here.
+ //
+ ImageContext->ImageType = Hdr.Pe32->OptionalHeader.Subsystem;
+ ImageContext->ImageSize = (UINT64)Hdr.Pe32->OptionalHeader.SizeOfImage;
+ ImageContext->SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
+ ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
+
+ } else {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_MACHINE_TYPE;
+ return EFI_UNSUPPORTED;
+ }
+ } else {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_MACHINE_TYPE;
+ return EFI_UNSUPPORTED;
+ }
+
+ if (!PeCoffLoaderImageFormatSupported (ImageContext->Machine)) {
+ //
+ // If the PE/COFF loader does not support the image type return
+ // unsupported. This library can suport lots of types of images
+ // this does not mean the user of this library can call the entry
+ // point of the image.
+ //
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+EFI_STATUS
+PeCoffLoaderCheckImageType (
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Checks the PE or TE header of a PE/COFF or TE image to determine if it supported
+
+Arguments:
+
+ ImageContext - The context of the image being loaded
+
+Returns:
+
+ EFI_SUCCESS if the PE/COFF or TE image is supported
+ EFI_UNSUPPORTED of the PE/COFF or TE image is not supported.
+
+--*/
+{
+ switch (ImageContext->ImageType) {
+
+ case EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION:
+ ImageContext->ImageCodeMemoryType = EfiLoaderCode;
+ ImageContext->ImageDataMemoryType = EfiLoaderData;
+ break;
+
+ case EFI_IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER:
+ ImageContext->ImageCodeMemoryType = EfiBootServicesCode;
+ ImageContext->ImageDataMemoryType = EfiBootServicesData;
+ break;
+
+ case EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER:
+ case EFI_IMAGE_SUBSYSTEM_SAL_RUNTIME_DRIVER:
+ ImageContext->ImageCodeMemoryType = EfiRuntimeServicesCode;
+ ImageContext->ImageDataMemoryType = EfiRuntimeServicesData;
+ break;
+
+ default:
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_SUBSYSTEM;
+ return EFI_UNSUPPORTED;
+ }
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderGetImageInfo (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Retrieves information on a PE/COFF image
+
+Arguments:
+
+ This - Calling context
+
+ ImageContext - The context of the image being loaded
+
+Returns:
+
+ EFI_SUCCESS if the information on the PE/COFF image was collected.
+ EFI_UNSUPPORTED of the PE/COFF image is not supported.
+ Otherwise, the error status from reading the PE/COFF image using the
+ ImageContext->ImageRead() function
+
+ EFI_INVALID_PARAMETER - ImageContext is NULL.
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION HdrData;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ EFI_IMAGE_DATA_DIRECTORY *DebugDirectoryEntry;
+ UINTN Size;
+ UINTN Index;
+ UINTN DebugDirectoryEntryRva;
+ UINTN DebugDirectoryEntryFileOffset;
+ UINTN SectionHeaderOffset;
+ EFI_IMAGE_SECTION_HEADER SectionHeader;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY DebugEntry;
+ UINT32 NumberOfRvaAndSizes;
+ UINT16 Magic;
+
+ if (NULL == ImageContext) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Assume success
+ //
+ ImageContext->ImageError = EFI_IMAGE_ERROR_SUCCESS;
+
+ Hdr.Union = &HdrData;
+ Status = PeCoffLoaderGetPeHeader (ImageContext, Hdr);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Verify machine type
+ //
+ Status = PeCoffLoaderCheckImageType (ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+
+ //
+ // Retrieve the base address of the image
+ //
+ if (!(ImageContext->IsTeImage)) {
+
+ //
+ // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
+ // It is for backward-compatibility consideration, because
+ // some system will generate PE32+ image with PE32 Magic.
+ //
+ if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ Magic = Hdr.Pe32->OptionalHeader.Magic;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset
+ //
+ ImageContext->ImageAddress = Hdr.Pe32->OptionalHeader.ImageBase;
+ } else {
+ //
+ // Use PE32+ offset
+ //
+ ImageContext->ImageAddress = Hdr.Pe32Plus->OptionalHeader.ImageBase;
+ }
+ } else {
+ ImageContext->ImageAddress = (EFI_PHYSICAL_ADDRESS)(Hdr.Te->ImageBase + Hdr.Te->StrippedSize - sizeof (EFI_TE_IMAGE_HEADER));
+ }
+
+ //
+ // Initialize the alternate destination address to 0 indicating that it
+ // should not be used.
+ //
+ ImageContext->DestinationAddress = 0;
+
+ //
+ // Initialize the codeview pointer.
+ //
+ ImageContext->CodeView = NULL;
+ ImageContext->PdbPointer = NULL;
+
+ //
+ // Three cases with regards to relocations:
+ // - Image has base relocs, RELOCS_STRIPPED==0 => image is relocatable
+ // - Image has no base relocs, RELOCS_STRIPPED==1 => Image is not relocatable
+ // - Image has no base relocs, RELOCS_STRIPPED==0 => Image is relocatable but
+ // has no base relocs to apply
+ // Obviously having base relocations with RELOCS_STRIPPED==1 is invalid.
+ //
+ // Look at the file header to determine if relocations have been stripped, and
+ // save this info in the image context for later use.
+ //
+ if ((!(ImageContext->IsTeImage)) && ((Hdr.Pe32->FileHeader.Characteristics & EFI_IMAGE_FILE_RELOCS_STRIPPED) != 0)) {
+ ImageContext->RelocationsStripped = TRUE;
+ } else {
+ ImageContext->RelocationsStripped = FALSE;
+ }
+
+ if (!(ImageContext->IsTeImage)) {
+ //
+ // Use PE32 to access fields that have same offset in PE32 and PE32+
+ //
+ ImageContext->ImageSize = (UINT64) Hdr.Pe32->OptionalHeader.SizeOfImage;
+ ImageContext->SectionAlignment = Hdr.Pe32->OptionalHeader.SectionAlignment;
+ ImageContext->SizeOfHeaders = Hdr.Pe32->OptionalHeader.SizeOfHeaders;
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset
+ //
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ } else {
+ //
+ // Use PE32+ offset
+ //
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ DebugDirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&(Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_DEBUG]);
+ }
+
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_DEBUG) {
+
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
+
+ //
+ // Determine the file offset of the debug directory... This means we walk
+ // the sections to find which section contains the RVA of the debug
+ // directory
+ //
+ DebugDirectoryEntryFileOffset = 0;
+
+ SectionHeaderOffset = (UINTN)(
+ ImageContext->PeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader
+ );
+
+ for (Index = 0; Index < Hdr.Pe32->FileHeader.NumberOfSections; Index++) {
+ //
+ // Read section header from file
+ //
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ SectionHeaderOffset,
+ &Size,
+ &SectionHeader
+ );
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
+ DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
+
+ DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva - SectionHeader.VirtualAddress + SectionHeader.PointerToRawData;
+ break;
+ }
+
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+ }
+
+ if (DebugDirectoryEntryFileOffset != 0) {
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
+ //
+ // Read next debug directory entry
+ //
+ Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugDirectoryEntryFileOffset,
+ &Size,
+ &DebugEntry
+ );
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
+ if (DebugEntry.RVA == 0 && DebugEntry.FileOffset != 0) {
+ ImageContext->ImageSize += DebugEntry.SizeOfData;
+ }
+
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+ } else {
+ //
+ // Because Te image only extracts base relocations and debug directory entries from
+ // Pe image and in Te image header there is not a field to describe the imagesize,
+ // we use the largest VirtualAddress plus Size in each directory entry to describe the imagesize
+ //
+ ImageContext->ImageSize = (UINT64) (Hdr.Te->DataDirectory[0].VirtualAddress + Hdr.Te->DataDirectory[0].Size);
+ if(Hdr.Te->DataDirectory[1].VirtualAddress > Hdr.Te->DataDirectory[0].VirtualAddress) {
+ ImageContext->ImageSize = (UINT64) (Hdr.Te->DataDirectory[1].VirtualAddress + Hdr.Te->DataDirectory[1].Size);
+ }
+ ImageContext->SectionAlignment = 4096;
+ ImageContext->SizeOfHeaders = sizeof (EFI_TE_IMAGE_HEADER) + (UINTN) Hdr.Te->BaseOfCode - (UINTN) Hdr.Te->StrippedSize;
+
+ DebugDirectoryEntry = &Hdr.Te->DataDirectory[1];
+ DebugDirectoryEntryRva = DebugDirectoryEntry->VirtualAddress;
+ SectionHeaderOffset = (UINTN)(sizeof (EFI_TE_IMAGE_HEADER));
+
+ DebugDirectoryEntryFileOffset = 0;
+
+ for (Index = 0; Index < Hdr.Te->NumberOfSections; Index++) {
+ //
+ // Read section header from file
+ //
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ SectionHeaderOffset,
+ &Size,
+ &SectionHeader
+ );
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugDirectoryEntryRva >= SectionHeader.VirtualAddress &&
+ DebugDirectoryEntryRva < SectionHeader.VirtualAddress + SectionHeader.Misc.VirtualSize) {
+ DebugDirectoryEntryFileOffset = DebugDirectoryEntryRva -
+ SectionHeader.VirtualAddress +
+ SectionHeader.PointerToRawData +
+ sizeof (EFI_TE_IMAGE_HEADER) -
+ Hdr.Te->StrippedSize;
+ break;
+ }
+
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+ }
+
+ if (DebugDirectoryEntryFileOffset != 0) {
+ for (Index = 0; Index < DebugDirectoryEntry->Size; Index++) {
+ //
+ // Read next debug directory entry
+ //
+ Size = sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugDirectoryEntryFileOffset,
+ &Size,
+ &DebugEntry
+ );
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+
+ if (DebugEntry.Type == EFI_IMAGE_DEBUG_TYPE_CODEVIEW) {
+ ImageContext->DebugDirectoryEntryRva = (UINT32) (DebugDirectoryEntryRva + Index * sizeof (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY));
+ return EFI_SUCCESS;
+ }
+ }
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+STATIC
+VOID *
+PeCoffLoaderImageAddress (
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext,
+ IN UINTN Address
+ )
+/*++
+
+Routine Description:
+
+ Converts an image address to the loaded address
+
+Arguments:
+
+ ImageContext - The context of the image being loaded
+
+ Address - The address to be converted to the loaded address
+
+Returns:
+
+ NULL if the address can not be converted, otherwise, the converted address
+
+--*/
+{
+ if (Address >= ImageContext->ImageSize) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+ return NULL;
+ }
+
+ return (CHAR8 *) ((UINTN) ImageContext->ImageAddress + Address);
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderRelocateImage (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Relocates a PE/COFF image in memory
+
+Arguments:
+
+ This - Calling context
+
+ ImageContext - Contains information on the loaded image to relocate
+
+Returns:
+
+ EFI_SUCCESS if the PE/COFF image was relocated
+ EFI_LOAD_ERROR if the image is not a valid PE/COFF image
+ EFI_UNSUPPORTED not support
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ EFI_IMAGE_DATA_DIRECTORY *RelocDir;
+ UINT64 Adjust;
+ EFI_IMAGE_BASE_RELOCATION *RelocBase;
+ EFI_IMAGE_BASE_RELOCATION *RelocBaseEnd;
+ UINT16 *Reloc;
+ UINT16 *RelocEnd;
+ CHAR8 *Fixup;
+ CHAR8 *FixupBase;
+ UINT16 *F16;
+ UINT32 *F32;
+ UINT64 *F64;
+ CHAR8 *FixupData;
+ EFI_PHYSICAL_ADDRESS BaseAddress;
+ UINT32 NumberOfRvaAndSizes;
+ UINT16 Magic;
+#ifdef EFI_NT_EMULATOR
+ VOID *DllEntryPoint;
+ VOID *ModHandle;
+
+ ModHandle = NULL;
+#endif
+
+ if (NULL == ImageContext) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Assume success
+ //
+ ImageContext->ImageError = EFI_IMAGE_ERROR_SUCCESS;
+
+ //
+ // If there are no relocation entries, then we are done
+ //
+ if (ImageContext->RelocationsStripped) {
+ return EFI_SUCCESS;
+ }
+
+ //
+ // If the destination address is not 0, use that rather than the
+ // image address as the relocation target.
+ //
+ if (ImageContext->DestinationAddress != 0) {
+ BaseAddress = ImageContext->DestinationAddress;
+ } else {
+ BaseAddress = ImageContext->ImageAddress;
+ }
+
+ if (!(ImageContext->IsTeImage)) {
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
+
+ //
+ // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
+ // It is for backward-compatibility consideration, because
+ // some system will generate PE32+ image with PE32 Magic.
+ //
+ if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ Magic = Hdr.Pe32->OptionalHeader.Magic;
+ }
+
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset
+ //
+ Adjust = (UINT64)BaseAddress - Hdr.Pe32->OptionalHeader.ImageBase;
+ Hdr.Pe32->OptionalHeader.ImageBase = (UINT32)BaseAddress;
+
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ RelocDir = &Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ } else {
+ //
+ // Use PE32+ offset
+ //
+ Adjust = (UINT64) BaseAddress - Hdr.Pe32Plus->OptionalHeader.ImageBase;
+ Hdr.Pe32Plus->OptionalHeader.ImageBase = (UINT64)BaseAddress;
+
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ RelocDir = &Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ }
+
+ //
+ // Find the relocation block
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ RelocBase = PeCoffLoaderImageAddress (ImageContext, RelocDir->VirtualAddress);
+ RelocBaseEnd = PeCoffLoaderImageAddress (
+ ImageContext,
+ RelocDir->VirtualAddress + RelocDir->Size - 1
+ );
+ } else {
+ //
+ // Set base and end to bypass processing below.
+ //
+ RelocBase = RelocBaseEnd = 0;
+ }
+
+ ImageContext->EntryPoint = BaseAddress + Hdr.Pe32->OptionalHeader.AddressOfEntryPoint;
+ } else {
+ Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
+ Adjust = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->ImageBase);
+ Hdr.Te->ImageBase = (UINT64) (BaseAddress - Hdr.Te->StrippedSize + sizeof (EFI_TE_IMAGE_HEADER));
+
+ //
+ // Find the relocation block
+ //
+ RelocDir = &Hdr.Te->DataDirectory[0];
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *)(UINTN)(
+ ImageContext->ImageAddress +
+ RelocDir->VirtualAddress +
+ sizeof(EFI_TE_IMAGE_HEADER) -
+ Hdr.Te->StrippedSize
+ );
+ RelocBaseEnd = (EFI_IMAGE_BASE_RELOCATION *) ((UINTN) RelocBase + (UINTN) RelocDir->Size - 1);
+
+ ImageContext->EntryPoint = Hdr.Te->ImageBase + Hdr.Te->AddressOfEntryPoint;
+ }
+
+ //
+ // Run the relocation information and apply the fixups
+ //
+ FixupData = ImageContext->FixupData;
+ while (RelocBase < RelocBaseEnd) {
+
+ Reloc = (UINT16 *) ((CHAR8 *) RelocBase + sizeof (EFI_IMAGE_BASE_RELOCATION));
+ RelocEnd = (UINT16 *) ((CHAR8 *) RelocBase + RelocBase->SizeOfBlock);
+ if (!(ImageContext->IsTeImage)) {
+ FixupBase = PeCoffLoaderImageAddress (ImageContext, RelocBase->VirtualAddress);
+ } else {
+ FixupBase = (CHAR8 *)(UINTN)(ImageContext->ImageAddress +
+ RelocBase->VirtualAddress +
+ sizeof(EFI_TE_IMAGE_HEADER) -
+ Hdr.Te->StrippedSize
+ );
+ }
+
+ if ((CHAR8 *) RelocEnd < (CHAR8 *) ((UINTN) ImageContext->ImageAddress) ||
+ (CHAR8 *) RelocEnd > (CHAR8 *)((UINTN)ImageContext->ImageAddress +
+ (UINTN)ImageContext->ImageSize)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_FAILED_RELOCATION;
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Run this relocation record
+ //
+ while (Reloc < RelocEnd) {
+
+ Fixup = FixupBase + (*Reloc & 0xFFF);
+ switch ((*Reloc) >> 12) {
+ case EFI_IMAGE_REL_BASED_ABSOLUTE:
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGH:
+ F16 = (UINT16 *) Fixup;
+ *F16 = (UINT16) (*F16 + (UINT16)(((UINT32)Adjust) >> 16));
+ if (FixupData != NULL) {
+ *(UINT16 *) FixupData = *F16;
+ FixupData = FixupData + sizeof (UINT16);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_LOW:
+ F16 = (UINT16 *) Fixup;
+ *F16 = (UINT16) (*F16 + (UINT16) Adjust);
+ if (FixupData != NULL) {
+ *(UINT16 *) FixupData = *F16;
+ FixupData = FixupData + sizeof (UINT16);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHLOW:
+ F32 = (UINT32 *) Fixup;
+ *F32 = *F32 + (UINT32) Adjust;
+ if (FixupData != NULL) {
+ FixupData = ALIGN_POINTER (FixupData, sizeof (UINT32));
+ *(UINT32 *) FixupData = *F32;
+ FixupData = FixupData + sizeof (UINT32);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_DIR64:
+ //
+ // For X64 and IPF
+ //
+ F64 = (UINT64 *) Fixup;
+ *F64 = *F64 + (UINT64) Adjust;
+ if (FixupData != NULL) {
+ FixupData = ALIGN_POINTER (FixupData, sizeof(UINT64));
+ *(UINT64 *)(FixupData) = *F64;
+ FixupData = FixupData + sizeof(UINT64);
+ }
+ break;
+
+ case EFI_IMAGE_REL_BASED_HIGHADJ:
+ //
+ // Return the same EFI_UNSUPPORTED return code as
+ // PeCoffLoaderRelocateImageEx() returns if it does not recognize
+ // the relocation type.
+ //
+ ImageContext->ImageError = EFI_IMAGE_ERROR_FAILED_RELOCATION;
+ return EFI_UNSUPPORTED;
+
+ default:
+ //
+ // The common code does not handle some of the stranger IPF relocations
+ // PeCoffLoaderRelocateImageEx () addes support for these complex fixups
+ // on IPF and is a No-Op on other archtiectures.
+ //
+ Status = PeCoffLoaderRelocateImageEx (Reloc, Fixup, &FixupData, Adjust);
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_FAILED_RELOCATION;
+ return Status;
+ }
+ }
+
+ //
+ // Next relocation record
+ //
+ Reloc += 1;
+ }
+
+ //
+ // Next reloc block
+ //
+ RelocBase = (EFI_IMAGE_BASE_RELOCATION *) RelocEnd;
+ }
+
+#ifdef EFI_NT_EMULATOR
+ DllEntryPoint = NULL;
+ ImageContext->ModHandle = NULL;
+ //
+ // Load the DLL if it's not an EBC image.
+ //
+ if ((ImageContext->PdbPointer != NULL) &&
+ (ImageContext->Machine != EFI_IMAGE_MACHINE_EBC)) {
+ Status = mPeCoffLoaderWinNtLoadAsDll->Entry (
+ ImageContext->PdbPointer,
+ &DllEntryPoint,
+ &ModHandle
+ );
+
+ if (!EFI_ERROR (Status) && DllEntryPoint != NULL) {
+ ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (UINTN) DllEntryPoint;
+ ImageContext->ModHandle = ModHandle;
+ }
+ }
+#endif
+
+ return EFI_SUCCESS;
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderLoadImage (
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL *This,
+ IN OUT EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Loads a PE/COFF image into memory
+
+Arguments:
+
+ This - Calling context
+
+ ImageContext - Contains information on image to load into memory
+
+Returns:
+
+ EFI_SUCCESS if the PE/COFF image was loaded
+ EFI_BUFFER_TOO_SMALL if the caller did not provide a large enough buffer
+ EFI_LOAD_ERROR if the image is a runtime driver with no relocations
+ EFI_INVALID_PARAMETER if the image address is invalid
+
+--*/
+{
+ EFI_STATUS Status;
+ EFI_IMAGE_OPTIONAL_HEADER_PTR_UNION Hdr;
+ EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT CheckContext;
+ EFI_IMAGE_SECTION_HEADER *FirstSection;
+ EFI_IMAGE_SECTION_HEADER *Section;
+ UINTN NumberOfSections;
+ UINTN Index;
+ CHAR8 *Base;
+ CHAR8 *End;
+ CHAR8 *MaxEnd;
+ EFI_IMAGE_DATA_DIRECTORY *DirectoryEntry;
+ EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *DebugEntry;
+ UINTN Size;
+ UINT32 TempDebugEntryRva;
+ UINT32 NumberOfRvaAndSizes;
+ UINT16 Magic;
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ EFI_IMAGE_RESOURCE_DIRECTORY *ResourceDirectory;
+ EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *ResourceDirectoryEntry;
+ EFI_IMAGE_RESOURCE_DIRECTORY_STRING *ResourceDirectoryString;
+ EFI_IMAGE_RESOURCE_DATA_ENTRY *ResourceDataEntry;
+#endif
+
+ if (NULL == ImageContext) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Assume success
+ //
+ ImageContext->ImageError = EFI_IMAGE_ERROR_SUCCESS;
+
+ //
+ // Copy the provided context info into our local version, get what we
+ // can from the original image, and then use that to make sure everything
+ // is legit.
+ //
+ CopyMem (&CheckContext, ImageContext, sizeof (EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT));
+
+ Status = PeCoffLoaderGetImageInfo (This, &CheckContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Make sure there is enough allocated space for the image being loaded
+ //
+ if (ImageContext->ImageSize < CheckContext.ImageSize) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_SIZE;
+ return EFI_BUFFER_TOO_SMALL;
+ }
+ if (ImageContext->ImageAddress == 0) {
+ //
+ // Image cannot be loaded into 0 address.
+ //
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+ return EFI_INVALID_PARAMETER;
+ }
+ //
+ // If there's no relocations, then make sure it's not a runtime driver,
+ // and that it's being loaded at the linked address.
+ //
+ if (CheckContext.RelocationsStripped) {
+ //
+ // If the image does not contain relocations and it is a runtime driver
+ // then return an error.
+ //
+ if (CheckContext.ImageType == EFI_IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_SUBSYSTEM;
+ return EFI_LOAD_ERROR;
+ }
+ //
+ // If the image does not contain relocations, and the requested load address
+ // is not the linked address, then return an error.
+ //
+ if (CheckContext.ImageAddress != ImageContext->ImageAddress) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_IMAGE_ADDRESS;
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Make sure the allocated space has the proper section alignment
+ //
+ if (!(ImageContext->IsTeImage)) {
+ if ((ImageContext->ImageAddress & (CheckContext.SectionAlignment - 1)) != 0) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_INVALID_SECTION_ALIGNMENT;
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+ //
+ // Read the entire PE/COFF or TE header into memory
+ //
+ if (!(ImageContext->IsTeImage)) {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ 0,
+ &ImageContext->SizeOfHeaders,
+ (VOID *) (UINTN) ImageContext->ImageAddress
+ );
+
+ Hdr.Pe32 = (EFI_IMAGE_NT_HEADERS32 *)((UINTN)ImageContext->ImageAddress + ImageContext->PeCoffHeaderOffset);
+
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN)ImageContext->ImageAddress +
+ ImageContext->PeCoffHeaderOffset +
+ sizeof(UINT32) +
+ sizeof(EFI_IMAGE_FILE_HEADER) +
+ Hdr.Pe32->FileHeader.SizeOfOptionalHeader
+ );
+ NumberOfSections = (UINTN) (Hdr.Pe32->FileHeader.NumberOfSections);
+ } else {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ 0,
+ &ImageContext->SizeOfHeaders,
+ (VOID *)(UINTN)ImageContext->ImageAddress
+ );
+
+ Hdr.Te = (EFI_TE_IMAGE_HEADER *)(UINTN)(ImageContext->ImageAddress);
+
+ FirstSection = (EFI_IMAGE_SECTION_HEADER *) (
+ (UINTN)ImageContext->ImageAddress +
+ sizeof(EFI_TE_IMAGE_HEADER)
+ );
+ NumberOfSections = (UINTN) (Hdr.Te->NumberOfSections);
+
+ }
+
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Load each section of the image
+ //
+ Section = FirstSection;
+ for (Index = 0, MaxEnd = NULL; Index < NumberOfSections; Index++) {
+
+ //
+ // Compute sections address
+ //
+ Base = PeCoffLoaderImageAddress (ImageContext, Section->VirtualAddress);
+ End = PeCoffLoaderImageAddress (
+ ImageContext,
+ Section->VirtualAddress + Section->Misc.VirtualSize - 1
+ );
+ if (ImageContext->IsTeImage) {
+ Base = (CHAR8 *)((UINTN) Base + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);
+ End = (CHAR8 *)((UINTN) End + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize);
+ }
+
+ if (End > MaxEnd) {
+ MaxEnd = End;
+ }
+ //
+ // If the base start or end address resolved to 0, then fail.
+ //
+ if ((Base == NULL) || (End == NULL)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_SECTION_NOT_LOADED;
+ return EFI_LOAD_ERROR;
+ }
+
+ //
+ // Read the section
+ //
+ Size = (UINTN) Section->Misc.VirtualSize;
+ if ((Size == 0) || (Size > Section->SizeOfRawData)) {
+ Size = (UINTN) Section->SizeOfRawData;
+ }
+
+ if (Section->SizeOfRawData) {
+ if (!(ImageContext->IsTeImage)) {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ Section->PointerToRawData,
+ &Size,
+ Base
+ );
+ } else {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ Section->PointerToRawData + sizeof (EFI_TE_IMAGE_HEADER) - (UINTN)Hdr.Te->StrippedSize,
+ &Size,
+ Base
+ );
+ }
+
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return Status;
+ }
+ }
+
+ //
+ // If raw size is less then virt size, zero fill the remaining
+ //
+
+ if (Size < Section->Misc.VirtualSize) {
+ ZeroMem (Base + Size, Section->Misc.VirtualSize - Size);
+ }
+
+ //
+ // Next Section
+ //
+ Section += 1;
+ }
+
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+
+ //
+ // Get image's entry point
+ //
+ if (!(ImageContext->IsTeImage)) {
+
+ //
+ // NOTE: We use Machine to identify PE32/PE32+, instead of Magic.
+ // It is for backward-compatibility consideration, because
+ // some system will generate PE32+ image with PE32 Magic.
+ //
+ if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA32) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_IA64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else if (Hdr.Pe32->FileHeader.Machine == EFI_IMAGE_MACHINE_X64) {
+ Magic = EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC;
+ } else {
+ Magic = Hdr.Pe32->OptionalHeader.Magic;
+ }
+
+ //
+ // Sizes of AddressOfEntryPoint are different so we need to do this safely
+ //
+ ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)PeCoffLoaderImageAddress (
+ ImageContext,
+ (UINTN)Hdr.Pe32->OptionalHeader.AddressOfEntryPoint
+ );
+
+ } else {
+ ImageContext->EntryPoint = (EFI_PHYSICAL_ADDRESS) (
+ (UINTN)ImageContext->ImageAddress +
+ (UINTN)Hdr.Te->AddressOfEntryPoint +
+ (UINTN)sizeof(EFI_TE_IMAGE_HEADER) -
+ (UINTN)Hdr.Te->StrippedSize
+ );
+ }
+
+ //
+ // Determine the size of the fixup data
+ //
+ // Per the PE/COFF spec, you can't assume that a given data directory
+ // is present in the image. You have to check the NumberOfRvaAndSizes in
+ // the optional header to verify a desired directory entry is there.
+ //
+ if (!(ImageContext->IsTeImage)) {
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset
+ //
+ NumberOfRvaAndSizes = Hdr.Pe32->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ } else {
+ //
+ // Use PE32+ offset
+ //
+ NumberOfRvaAndSizes = Hdr.Pe32Plus->OptionalHeader.NumberOfRvaAndSizes;
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC];
+ }
+
+ if (NumberOfRvaAndSizes > EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ } else {
+ ImageContext->FixupDataSize = 0;
+ }
+ } else {
+ DirectoryEntry = &Hdr.Te->DataDirectory[0];
+ ImageContext->FixupDataSize = DirectoryEntry->Size / sizeof (UINT16) * sizeof (UINTN);
+ }
+ //
+ // Consumer must allocate a buffer for the relocation fixup log.
+ // Only used for runtime drivers.
+ //
+ ImageContext->FixupData = NULL;
+
+ //
+ // Load the Codeview info if present
+ //
+ if (ImageContext->DebugDirectoryEntryRva != 0) {
+ if (!(ImageContext->IsTeImage)) {
+ DebugEntry = PeCoffLoaderImageAddress (
+ ImageContext,
+ ImageContext->DebugDirectoryEntryRva
+ );
+ } else {
+ DebugEntry = (EFI_IMAGE_DEBUG_DIRECTORY_ENTRY *)(UINTN)(
+ ImageContext->ImageAddress +
+ ImageContext->DebugDirectoryEntryRva +
+ sizeof(EFI_TE_IMAGE_HEADER) -
+ Hdr.Te->StrippedSize
+ );
+ }
+
+ if (DebugEntry != NULL) {
+ TempDebugEntryRva = DebugEntry->RVA;
+ if (DebugEntry->RVA == 0 && DebugEntry->FileOffset != 0) {
+ Section--;
+ if ((UINTN)Section->SizeOfRawData < Section->Misc.VirtualSize) {
+ TempDebugEntryRva = Section->VirtualAddress + Section->Misc.VirtualSize;
+ } else {
+ TempDebugEntryRva = Section->VirtualAddress + Section->SizeOfRawData;
+ }
+ }
+
+ if (TempDebugEntryRva != 0) {
+ if (!(ImageContext->IsTeImage)) {
+ ImageContext->CodeView = PeCoffLoaderImageAddress (ImageContext, TempDebugEntryRva);
+ } else {
+ ImageContext->CodeView = (VOID *)(
+ (UINTN)ImageContext->ImageAddress +
+ (UINTN)TempDebugEntryRva +
+ (UINTN)sizeof (EFI_TE_IMAGE_HEADER) -
+ (UINTN) Hdr.Te->StrippedSize
+ );
+ }
+
+ if (ImageContext->CodeView == NULL) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return EFI_LOAD_ERROR;
+ }
+
+ if (DebugEntry->RVA == 0) {
+ Size = DebugEntry->SizeOfData;
+ if (!(ImageContext->IsTeImage)) {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugEntry->FileOffset,
+ &Size,
+ ImageContext->CodeView
+ );
+ } else {
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ DebugEntry->FileOffset + sizeof (EFI_TE_IMAGE_HEADER) - Hdr.Te->StrippedSize,
+ &Size,
+ ImageContext->CodeView
+ );
+ //
+ // Should we apply fix up to this field according to the size difference between PE and TE?
+ // Because now we maintain TE header fields unfixed, this field will also remain as they are
+ // in original PE image.
+ //
+ }
+
+ if (EFI_ERROR (Status)) {
+ ImageContext->ImageError = EFI_IMAGE_ERROR_IMAGE_READ;
+ return EFI_LOAD_ERROR;
+ }
+
+ DebugEntry->RVA = TempDebugEntryRva;
+ }
+
+ switch (*(UINT32 *) ImageContext->CodeView) {
+ case CODEVIEW_SIGNATURE_NB10:
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_NB10_ENTRY);
+ break;
+
+ case CODEVIEW_SIGNATURE_RSDS:
+ ImageContext->PdbPointer = (CHAR8 *)ImageContext->CodeView + sizeof (EFI_IMAGE_DEBUG_CODEVIEW_RSDS_ENTRY);
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+#if (EFI_SPECIFICATION_VERSION >= 0x0002000A)
+ //
+ // Get Image's HII resource section
+ //
+ if (!(ImageContext->IsTeImage)) {
+ if (Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {
+ //
+ // Use PE32 offset
+ //
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];
+ } else {
+ //
+ // Use PE32+ offset
+ //
+ DirectoryEntry = (EFI_IMAGE_DATA_DIRECTORY *)&Hdr.Pe32Plus->OptionalHeader.DataDirectory[EFI_IMAGE_DIRECTORY_ENTRY_RESOURCE];
+ }
+
+ if (DirectoryEntry->Size != 0) {
+ Base = PeCoffLoaderImageAddress (ImageContext, DirectoryEntry->VirtualAddress);
+
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) Base;
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
+
+ for (Index = 0; Index < ResourceDirectory->NumberOfNamedEntries; Index++) {
+ if (ResourceDirectoryEntry->u1.s.NameIsString) {
+ ResourceDirectoryString = (EFI_IMAGE_RESOURCE_DIRECTORY_STRING *) (Base + ResourceDirectoryEntry->u1.s.NameOffset);
+
+ if (ResourceDirectoryString->Length == 3 &&
+ ResourceDirectoryString->String[0] == L'H' &&
+ ResourceDirectoryString->String[1] == L'I' &&
+ ResourceDirectoryString->String[2] == L'I') {
+ //
+ // Resource Type "HII" found
+ //
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {
+ //
+ // Move to next level - resource Name
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
+
+ if (ResourceDirectoryEntry->u2.s.DataIsDirectory) {
+ //
+ // Move to next level - resource Language
+ //
+ ResourceDirectory = (EFI_IMAGE_RESOURCE_DIRECTORY *) (Base + ResourceDirectoryEntry->u2.s.OffsetToDirectory);
+ ResourceDirectoryEntry = (EFI_IMAGE_RESOURCE_DIRECTORY_ENTRY *) (ResourceDirectory + 1);
+ }
+ }
+
+ //
+ // Now it ought to be resource Data
+ //
+ if (!ResourceDirectoryEntry->u2.s.DataIsDirectory) {
+ ResourceDataEntry = (EFI_IMAGE_RESOURCE_DATA_ENTRY *) (Base + ResourceDirectoryEntry->u2.OffsetToData);
+ ImageContext->HiiResourceData = (EFI_PHYSICAL_ADDRESS) (UINTN) PeCoffLoaderImageAddress (ImageContext, ResourceDataEntry->OffsetToData);
+ break;
+ }
+ }
+ }
+
+ ResourceDirectoryEntry++;
+ }
+ }
+ }
+#endif
+
+#if defined (EFI_DEBUG_ITP_BREAK) && !defined (_CONSOLE)
+ AsmEfiSetBreakSupport ((UINTN)(ImageContext->ImageAddress));
+#endif
+
+ return Status;
+}
+
+EFI_STATUS
+EFIAPI
+PeCoffLoaderUnloadImage (
+ IN EFI_PEI_PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+/*++
+
+Routine Description:
+
+ Unload a PE/COFF image from memory
+
+Arguments:
+
+ ImageContext - Contains information on image to load into memory
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+{
+#ifdef EFI_NT_EMULATOR
+ //
+ // Calling Win32 API free library
+ //
+ mPeCoffLoaderWinNtLoadAsDll->FreeLibrary (ImageContext->ModHandle);
+
+#endif
+
+ return EFI_SUCCESS;
+}
diff --git a/Core/PeiApi.h b/Core/PeiApi.h
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/Core/PeiApi.h
diff --git a/Core/PeiDebug.h b/Core/PeiDebug.h
new file mode 100644
index 0000000..b39a59f
--- /dev/null
+++ b/Core/PeiDebug.h
@@ -0,0 +1,108 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiDebug.h
+
+Abstract:
+
+ PEI Debug macros. The work needs to be done in library. The Debug
+ macros them selves are standard for all files, including the core.
+
+ There needs to be code linked in that produces the following macros:
+
+ PeiDebugAssert(file, linenumber, assertion string) - worker function for
+ ASSERT. filename and line number of where this ASSERT() is located
+ is passed in along with the stringized version of the assertion.
+
+ PeiDebugPrint - Worker function for debug print
+
+ _DEBUG_SET_MEM(address, length, value) - Set memory at address to value
+ for legnth bytes. This macro is used to initialzed uninitialized memory
+ or memory that is free'ed, so it will not be used by mistake.
+
+--*/
+
+#ifndef _PEIDEBUG_H_
+#define _PEIDEBUG_H_
+
+#ifdef EFI_DEBUG
+
+ VOID
+ PeiDebugAssert (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN CHAR8 *FileName,
+ IN INTN LineNumber,
+ IN CHAR8 *Description
+ );
+
+ VOID
+ PeiDebugPrint (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ IN UINTN ErrorLevel,
+ IN CHAR8 *Format,
+ ...
+ );
+
+ #define _PEI_DEBUG_ASSERT(PeiST, assertion) \
+ PeiDebugAssert (PeiST, __FILE__, __LINE__, #assertion)
+
+ #define _PEI_DEBUG(PeiST, arg) PeiDebugPrint (PeiST, arg)
+
+ //
+ // Define ASSERT() macro, if assertion is FALSE trigger the ASSERT
+ //
+#ifndef PEI_ASSERT
+ #define PEI_ASSERT(PeiST, assertion) if(!(assertion)) \
+ _PEI_DEBUG_ASSERT(PeiST, assertion)
+#endif
+
+ #define PEI_ASSERT_LOCKED(PeiST, l) if(!(l)->Lock) _PEI_DEBUG_ASSERT(PeiST, l not locked)
+
+ //
+ // DEBUG((DebugLevel, "format string", ...)) - if DebugLevel is active do
+ // the a debug print.
+ //
+
+ #define PEI_DEBUG(arg) PeiDebugPrint arg
+
+ #define PEI_DEBUG_CODE(code) code
+
+ #define PEI_CR(Record, TYPE, Field, Signature) \
+ _CR(Record, TYPE, Field)
+
+
+ #define _PEI_DEBUG_SET_MEM(address, length, data) SetMem(address, length, data)
+
+#else
+ #define PEI_ASSERT(PeiST, a)
+ #define PEI_ASSERT_LOCKED(PeiST, l)
+ #define PEI_DEBUG(arg)
+ #define PEI_DEBUG_CODE(code)
+ #define PEI_CR(Record, TYPE, Field, Signature) \
+ _CR(Record, TYPE, Field)
+ #define _PEI_DEBUG_SET_MEM(address, length, data)
+#endif
+
+#ifndef ASSERT_PEI_ERROR
+#define ASSERT_PEI_ERROR(PeiST, status) PEI_ASSERT(PeiST, !EFI_ERROR(status))
+#endif
+
+#ifdef EFI_DEBUG_CLEAR_MEMORY
+ #define PEI_DEBUG_SET_MEMORY(address,length) \
+ _PEI_DEBUG_SET_MEM(address, length, EFI_BAD_POINTER_AS_BYTE)
+#else
+ #define PEI_DEBUG_SET_MEMORY(address,length)
+#endif
+
+
+#endif
diff --git a/Core/PeiHob.h b/Core/PeiHob.h
new file mode 100644
index 0000000..fea8efd
--- /dev/null
+++ b/Core/PeiHob.h
@@ -0,0 +1,34 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiHob.h
+
+Abstract:
+
+ PEI Hand Off Block (HOB) definition.
+
+ The HOB is a memory data structure used to hand-off system information from
+ PEI to DXE (the next phase).
+
+--*/
+
+#ifndef _PEI_HOB_H_
+#define _PEI_HOB_H_
+#include <HOB.h>
+
+#define GET_HOB_TYPE(Hob) ((Hob).Header->HobType)
+#define GET_HOB_LENGTH(Hob) ((Hob).Header->HobLength)
+#define GET_NEXT_HOB(Hob) ((Hob).Raw + GET_HOB_LENGTH (Hob))
+#define END_OF_HOB_LIST(Hob) (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_END_OF_HOB_LIST)
+
+#endif
diff --git a/Core/PeiLib.h b/Core/PeiLib.h
new file mode 100644
index 0000000..571b84d
--- /dev/null
+++ b/Core/PeiLib.h
@@ -0,0 +1,864 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiLib.h
+
+Abstract:
+
+ PEI Library Functions
+
+--*/
+
+#ifndef _PEI_LIB_H_
+#define _PEI_LIB_H_
+#include "Tiano.h"
+#include "peiHobLib.h"
+#include <AmiPeiLib.h>
+#include EFI_PROTOCOL_DEFINITION (Decompress)
+#include EFI_PROTOCOL_DEFINITION (TianoDecompress)
+#include EFI_GUID_DEFINITION (PeiPeCoffLoader)
+#include EFI_PPI_DEFINITION (FindFv)
+
+#if (PI_SPECIFICATION_VERSION >= 0x00010000)
+
+VOID *
+EFIAPI
+ScanGuid (
+ IN VOID *Buffer,
+ IN UINTN Length,
+ IN EFI_GUID *Guid
+ )
+/*++
+
+Routine Description:
+
+ Scans a target buffer for a GUID, and returns a pointer to the matching GUID
+ in the target buffer.
+
+ This function searches target the buffer specified by Buffer and Length from
+ the lowest address to the highest address at 128-bit increments for the 128-bit
+ GUID value that matches Guid. If a match is found, then a pointer to the matching
+ GUID in the target buffer is returned. If no match is found, then NULL is returned.
+ If Length is 0, then NULL is returned.
+ If Length > 0 and Buffer is NULL, then ASSERT().
+ If Buffer is not aligned on a 32-bit boundary, then ASSERT().
+ If Length is not aligned on a 128-bit boundary, then ASSERT().
+ If Length is greater than (EFI_MAX_ADDRESS ?Buffer + 1), then ASSERT().
+
+Arguments:
+
+ Buffer - Pointer to the target buffer to scan.
+ Length - Number of bytes in Buffer to scan.
+ Guid - Value to search for in the target buffer.
+
+Returns:
+ A pointer to the matching Guid in the target buffer or NULL otherwise.
+
+--*/
+;
+
+#define InvalidateInstructionCacheRange(Address, Length) (Address)
+VOID
+MigrateIdtTable (
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+/*++
+
+Routine Description:
+
+ Migrate IDT from CAR to real memory where preceded with 4 bytes for
+ storing PeiService pointer.
+
+Arguments:
+
+ PeiServices - The direct pointer to PeiServiceTable.
+
+Returns:
+
+ NONE.
+
+--*/
+;
+
+
+#endif
+
+VOID
+PeiCopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+ZeroMem (
+ IN VOID *Buffer,
+ IN UINTN Size
+ )
+/*++
+
+Routine Description:
+
+ Set Buffer to zero for Size bytes.
+
+Arguments:
+
+ Buffer - Memory to set.
+
+ Size - Number of bytes to set
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+CopyMem (
+ IN VOID *Destination,
+ IN VOID *Source,
+ IN UINTN Length
+ )
+/*++
+
+Routine Description:
+
+ Copy Length bytes from Source to Destination.
+
+Arguments:
+
+ Destination - Target of copy
+
+ Source - Place to copy from
+
+ Length - Number of bytes to copy
+
+Returns:
+
+ None
+
+--*/
+;
+
+BOOLEAN
+CompareGuid (
+ IN EFI_GUID *Guid1,
+ IN EFI_GUID *Guid2
+ )
+/*++
+
+Routine Description:
+
+ Compares two GUIDs
+
+Arguments:
+
+ Guid1 - guid to compare
+ Guid2 - guid to compare
+
+Returns:
+ = TRUE if Guid1 == Guid2
+ = FALSE if Guid1 != Guid2
+
+--*/
+;
+
+EFI_STATUS
+InstallEfiPeiPeCoffLoader (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_PE_COFF_LOADER_PROTOCOL **This,
+ IN EFI_PEI_PPI_DESCRIPTOR *ThisPpi
+ )
+/*++
+
+Routine Description:
+
+ Install EFI Pei PE coff loader protocol.
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ This - Pointer to get Pei PE coff loader protocol as output
+
+ ThisPpi - Passed in as EFI_NT_LOAD_AS_DLL_PPI on NT_EMULATOR platform
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+InstallEfiPeiPeCoffLoader64 (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT EFI_PEI_PE_COFF_LOADER_PROTOCOL **This,
+ IN EFI_PEI_PPI_DESCRIPTOR *ThisPpi
+ );
+
+
+
+EFI_STATUS
+InstallEfiDecompress (
+ EFI_DECOMPRESS_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Install EFI decompress protocol.
+
+Arguments:
+
+ This - Pointer to get decompress protocol as output
+
+Returns:
+
+ EFI_SUCCESS - EFI decompress protocol successfully installed.
+
+--*/
+;
+
+EFI_STATUS
+InstallTianoDecompress (
+ EFI_TIANO_DECOMPRESS_PROTOCOL **This
+ )
+/*++
+
+Routine Description:
+
+ Install Tiano decompress protocol.
+
+Arguments:
+
+ This - Pointer to get decompress protocol as output
+
+Returns:
+
+ EFI_SUCCESS - Tiano decompress protocol successfully installed.
+
+--*/
+;
+
+EFI_STATUS
+GetTimerValue (
+ OUT UINT64 *TimerValue
+ )
+/*++
+
+Routine Description:
+
+ Get timer value.
+
+Arguments:
+
+ TimerValue - Pointer to the returned timer value
+
+Returns:
+
+ EFI_SUCCESS - Successfully got timer value
+
+--*/
+;
+
+#ifdef EFI_NT_EMULATOR
+EFI_STATUS
+PeCoffLoaderWinNtLoadAsDll (
+ IN CHAR8 *PdbFileName,
+ IN VOID **ImageEntryPoint,
+ OUT VOID **ModHandle
+ )
+/*++
+
+Routine Description:
+
+ Loads the .DLL file is present when a PE/COFF file is loaded. This provides source level
+ debugging for drivers that have cooresponding .DLL files on the local system.
+
+Arguments:
+
+ PdbFileName - The name of the .PDB file. This was found from the PE/COFF
+ file's debug directory entry.
+
+ ImageEntryPoint - A pointer to the DLL entry point of the .DLL file was loaded.
+
+ ModHandle - Pointer to loaded library.
+
+Returns:
+
+ EFI_SUCCESS - The .DLL file was loaded, and the DLL entry point is returned in ImageEntryPoint
+
+ EFI_NOT_FOUND - The .DLL file could not be found
+
+ EFI_UNSUPPORTED - The .DLL file was loaded, but the entry point to the .DLL file could not
+ determined.
+
+--*/
+;
+
+#endif
+//
+// hob.c
+//
+EFI_STATUS
+PeiBuildHobModule (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *ModuleName,
+ IN EFI_PHYSICAL_ADDRESS Module,
+ IN UINT64 ModuleLength,
+ IN EFI_PHYSICAL_ADDRESS EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for a loaded PE32 module
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+ ModuleName - The GUID File Name of the module
+ Memory - The 64 bit physical address of the module
+ ModuleLength - The length of the module in bytes
+ EntryPoint - The 64 bit physical address of the entry point
+ to the module
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobResourceDescriptor (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB that describes a chunck of system memory
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ ResourceType - The type of resource described by this HOB
+
+ ResourceAttribute - The resource attributes of the memory described by this HOB
+
+ PhysicalStart - The 64 bit physical address of memory described by this HOB
+
+ NumberOfBytes - The length of the memoty described by this HOB in bytes
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobGuid (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN UINTN DataLength,
+ IN OUT VOID **Hob
+ )
+/*++
+
+Routine Description:
+
+ Builds a custom HOB that is tagged with a GUID for identification
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Guid - The GUID of the custome HOB type
+
+ DataLength - The size of the data payload for the GUIDed HOB
+
+ Hob - Pointer to the Hob
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobGuidData (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_GUID *Guid,
+ IN VOID *Data,
+ IN UINTN DataLength
+ )
+/*++
+
+Routine Description:
+
+ Builds a custom HOB that is tagged with a GUID for identification
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ Guid - The GUID of the custome HOB type
+
+ Data - The data to be copied into the GUIDed HOB data field.
+
+ DataLength - The data field length.
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobFv (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Builds a Firmware Volume HOB
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The base address of the Firmware Volume
+
+ Length - The size of the Firmware Volume in bytes
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobCpu (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT8 SizeOfMemorySpace,
+ IN UINT8 SizeOfIoSpace
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the CPU
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ SizeOfMemorySpace - Identifies the maximum
+ physical memory addressibility of the processor.
+
+ SizeOfIoSpace - Identifies the maximum physical I/O addressibility
+ of the processor.
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobStack (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the Stack
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the Stack
+
+ Length - The length of the stack in bytes
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobBspStore (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the bsp store
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the bsp store
+
+ Length - The length of the bsp store in bytes
+
+ MemoryType - Memory type
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+EFI_STATUS
+PeiBuildHobMemoryAllocation (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_GUID *Name,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the memory allocation
+
+Arguments:
+
+ PeiServices - The PEI core services table.
+
+ BaseAddress - The 64 bit physical address of the memory
+
+ Length - The length of the memory allocation in bytes
+
+ Name - Name for Hob
+
+ MemoryType - Memory type
+
+Returns:
+
+ EFI_SUCCESS - Hob is successfully built.
+ Others - Errors occur while creating new Hob
+
+--*/
+;
+
+//
+// print.c
+//
+UINTN
+AvSPrint (
+ OUT CHAR8 *StartOfBuffer,
+ IN UINTN StrSize,
+ IN CONST CHAR8 *Format,
+ IN VA_LIST Marker
+ )
+/*++
+
+Routine Description:
+
+ AvSPrint function to process format and place the results in Buffer. Since a
+ VA_LIST is used this rountine allows the nesting of Vararg routines. Thus
+ this is the main print working routine
+
+Arguments:
+
+ StartOfBuffer - Ascii buffer to print the results of the parsing of Format into.
+
+ StrSize - Maximum number of characters to put into buffer. Zero means
+ no limit.
+
+ FormatString - Ascii format string see file header for more details.
+
+ Marker - Vararg list consumed by processing Format.
+
+Returns:
+
+ Number of characters printed.
+
+--*/
+;
+
+UINTN
+ASPrint (
+ OUT CHAR8 *Buffer,
+ IN UINTN BufferSize,
+ IN CONST CHAR8 *Format,
+ ...
+ )
+/*++
+
+Routine Description:
+
+ ASPrint function to process format and place the results in Buffer.
+
+Arguments:
+
+ Buffer - Ascii buffer to print the results of the parsing of Format into.
+
+ BufferSize - Maximum number of characters to put into buffer. Zero means no
+ limit.
+
+ Format - Ascii format string see file header for more details.
+
+ ... - Vararg list consumed by processing Format.
+
+Returns:
+
+ Number of characters printed.
+
+--*/
+;
+
+//
+// math.c
+//
+UINT64
+MultU64x32 (
+ IN UINT64 Multiplicand,
+ IN UINTN Multiplier
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be multiplied with a 32 bit
+ value returns 64bit result.
+ No checking if the result is greater than 64bits
+
+Arguments:
+
+ Multiplicand - multiplicand
+ Multiplier - multiplier
+
+Returns:
+
+ Multiplicand * Multiplier
+
+--*/
+;
+
+UINT64
+DivU64x32 (
+ IN UINT64 Dividend,
+ IN UINTN Divisor,
+ OUT UINTN *Remainder OPTIONAL
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be divided with a 32 bit value returns
+ 64bit result and the Remainder.
+ N.B. only works for 31bit divisors!!
+
+Arguments:
+
+ Dividend - dividend
+ Divisor - divisor
+ Remainder - buffer for remainder
+
+Returns:
+
+ Dividend / Divisor
+ Remainder = Dividend mod Divisor
+
+--*/
+;
+
+UINT64
+RShiftU64 (
+ IN UINT64 Operand,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be right shifted by 32 bits and returns the
+ shifted value.
+ Count is valid up 63. (Only Bits 0-5 is valid for Count)
+
+Arguments:
+
+ Operand - Value to be shifted
+ Count - Number of times to shift right.
+
+Returns:
+
+ Value shifted right identified by the Count.
+
+--*/
+;
+
+UINT64
+LShiftU64 (
+ IN UINT64 Operand,
+ IN UINTN Count
+ )
+/*++
+
+Routine Description:
+
+ This routine allows a 64 bit value to be left shifted by 32 bits and
+ returns the shifted value.
+ Count is valid up 63. (Only Bits 0-5 is valid for Count)
+
+Arguments:
+
+ Operand - Value to be shifted
+ Count - Number of times to shift left.
+
+Returns:
+
+ Value shifted left identified by the Count.
+
+--*/
+;
+
+VOID
+RegisterNativeCpuIo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *CpuIo
+ )
+/*++
+
+Routine Description:
+
+ Register a native Cpu IO
+
+Arguments:
+
+ PeiServices - Calling context
+ CpuIo - CpuIo instance to register
+
+Returns:
+
+ None
+
+--*/
+;
+
+VOID
+GetNativeCpuIo (
+ IN EFI_PEI_SERVICES **PeiServices,
+ OUT VOID **CpuIo
+ )
+/*++
+
+Routine Description:
+
+ Get registered Cpu IO.
+
+Arguments:
+
+ PeiServices - Calling context
+ CpuIo - CpuIo instance registered before
+
+Returns:
+
+ None
+
+--*/
+;
+
+EFI_STATUS
+FindFv (
+ IN EFI_FIND_FV_PPI *This,
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN OUT UINT8 *FvNumber,
+ IN OUT EFI_FIRMWARE_VOLUME_HEADER **FVAddress
+ )
+/*++
+
+Routine Description:
+
+ Search Fv in Hob.
+
+Arguments:
+
+ This - Interface pointer that implement the Find Fv PPI
+
+ PeiServices - Pointer to the PEI Service Table
+
+ FvNumber - The index of the fireware volume to locate
+
+ FVAddress - The address of the volume to discover
+
+Returns:
+
+ EFI_SUCCESS - An addtional fv found
+ EFI_OUT_OF_RESOURCES - There are no fireware volume for given fvnumber
+ EFI_INVALID_PARAMETER - *FvAddress is NULL
+
+--*/
+;
+
+#endif
diff --git a/Core/Protocol/CustomizedDecompress.h b/Core/Protocol/CustomizedDecompress.h
new file mode 100644
index 0000000..983821b
--- /dev/null
+++ b/Core/Protocol/CustomizedDecompress.h
@@ -0,0 +1,139 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ CustomizedDecompress.h
+
+Abstract:
+
+ The user Customized Decompress Protocol Interface
+
+--*/
+
+#ifndef _CUSTOMIZED_DECOMPRESS_H_
+#define _CUSTOMIZED_DECOMPRESS_H_
+#include <EFI.h>
+
+#define EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID \
+ { 0x9a44198e, 0xa4a2, 0x44e6, 0x8a, 0x1f, 0x39, 0xbe, 0xfd, 0xac, 0x89, 0x6f }
+
+EFI_FORWARD_DECLARATION (EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CUSTOMIZED_DECOMPRESS_GET_INFO) (
+ IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL *This,
+ IN VOID *Source,
+ IN UINT32 SourceSize,
+ OUT UINT32 *DestinationSize,
+ OUT UINT32 *ScratchSize
+ );
+/*++
+
+Routine Description:
+
+ The GetInfo() function retrieves the size of the uncompressed buffer
+ and the temporary scratch buffer required to decompress the buffer
+ specified by Source and SourceSize. If the size of the uncompressed
+ buffer or the size of the scratch buffer cannot be determined from
+ the compressed data specified by Source and SourceData, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed
+ buffer is returned in DestinationSize, the size of the scratch buffer is
+ returned in ScratchSize, and EFI_SUCCESS is returned.
+
+ The GetInfo() function does not have scratch buffer available to perform
+ a thorough checking of the validity of the source data. It just retrieves
+ the 'Original Size' field from the beginning bytes of the source data and
+ output it as DestinationSize. And ScratchSize is specific to the decompression
+ implementation.
+
+Arguments:
+
+ This - The protocol instance pointer
+ Source - The source buffer containing the compressed data.
+ SourceSize - The size, in bytes, of source buffer.
+ DestinationSize - A pointer to the size, in bytes, of the uncompressed buffer
+ that will be generated when the compressed buffer specified
+ by Source and SourceSize is decompressed.
+ ScratchSize - A pointer to the size, in bytes, of the scratch buffer that
+ is required to decompress the compressed buffer specified by
+ Source and SourceSize.
+
+Returns:
+ EFI_SUCCESS - The size of the uncompressed data was returned in DestinationSize
+ and the size of the scratch buffer was returned in ScratchSize.
+ EFI_INVALID_PARAMETER - The size of the uncompressed data or the size of the scratch
+ buffer cannot be determined from the compressed data specified by
+ Source and SourceData.
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CUSTOMIZED_DECOMPRESS_DECOMPRESS) (
+ IN EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL *This,
+ IN VOID* Source,
+ IN UINT32 SourceSize,
+ IN OUT VOID* Destination,
+ IN UINT32 DestinationSize,
+ IN OUT VOID* Scratch,
+ IN UINT32 ScratchSize
+ );
+/*++
+
+Routine Description:
+
+ The Decompress() function extracts decompressed data to its original form.
+
+ This protocol is designed so that the decompression algorithm can be
+ implemented without using any memory services. As a result, the
+ Decompress() function is not allowed to call AllocatePool() or
+ AllocatePages() in its implementation. It is the caller's responsibility
+ to allocate and free the Destination and Scratch buffers.
+
+ If the compressed source data specified by Source and SourceSize is
+ sucessfully decompressed into Destination, then EFI_SUCCESS is returned.
+ If the compressed source data specified by Source and SourceSize is not in
+ a valid compressed data format, then EFI_INVALID_PARAMETER is returned.
+
+Arguments:
+
+ This - The protocol instance pointer
+ Source - The source buffer containing the compressed data.
+ SourceSize - The size of source data.
+ Destination - On output, the destination buffer that contains
+ the uncompressed data.
+ DestinationSize - The size of destination buffer. The size of destination
+ buffer needed is obtained from GetInfo().
+ Scratch - A temporary scratch buffer that is used to perform the
+ decompression.
+ ScratchSize - The size of scratch buffer. The size of scratch buffer needed
+ is obtained from GetInfo().
+
+Returns:
+
+ EFI_SUCCESS - Decompression completed successfully, and the uncompressed
+ buffer is returned in Destination.
+ EFI_INVALID_PARAMETER
+ - The source buffer specified by Source and SourceSize is
+ corrupted (not in a valid compressed format).
+
+--*/
+
+typedef struct _EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL {
+ EFI_CUSTOMIZED_DECOMPRESS_GET_INFO GetInfo;
+ EFI_CUSTOMIZED_DECOMPRESS_DECOMPRESS Decompress;
+} EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL;
+
+GUID_VARIABLE_DECLARATION(gEfiCustomizedDecompressProtocolGuid, EFI_CUSTOMIZED_DECOMPRESS_PROTOCOL_GUID);
+#endif
diff --git a/Core/Protocol/DebugMask.h b/Core/Protocol/DebugMask.h
new file mode 100644
index 0000000..e5cfa22
--- /dev/null
+++ b/Core/Protocol/DebugMask.h
@@ -0,0 +1,69 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ DebugMask.h
+
+Abstract:
+
+ This protocol is used to abstract the Debug Mask serivces for
+ the specific driver or application image.
+
+--*/
+
+#ifndef _DEBUG_MASK_H_
+#define _DEBUG_MASK_H_
+#include <EFI.h>
+
+
+//
+//4C8A2451-C207-405b-9694-99EA13251341
+//
+#define EFI_DEBUG_MASK_PROTOCOL_GUID \
+ { 0x4c8a2451, 0xc207, 0x405b, 0x96, 0x94, 0x99, 0xea, 0x13, 0x25, 0x13, 0x41 }
+
+
+#define EFI_DEBUG_MASK_REVISION 0x00010000
+
+//
+// Forward reference for pure ANSI compatability
+//
+EFI_FORWARD_DECLARATION (EFI_DEBUG_MASK_PROTOCOL);
+
+//
+// DebugMask member functions definition
+//
+typedef
+EFI_STATUS
+(EFIAPI * EFI_GET_DEBUG_MASK) (
+ IN EFI_DEBUG_MASK_PROTOCOL *This, // Calling context
+ IN OUT UINTN *CurrentDebugMask // Ptr to store current debug mask
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_SET_DEBUG_MASK) (
+ IN EFI_DEBUG_MASK_PROTOCOL *This, // Calling context
+ IN UINTN NewDebugMask // New Debug Mask value to set
+ );
+
+//
+// DebugMask protocol definition
+//
+typedef struct _EFI_DEBUG_MASK_PROTOCOL {
+ INT64 Revision;
+ EFI_GET_DEBUG_MASK GetDebugMask;
+ EFI_SET_DEBUG_MASK SetDebugMask;
+} EFI_DEBUG_MASK_PROTOCOL;
+
+GUID_VARIABLE_DECLARATION(gEfiDebugMaskProtocolGuid, EFI_DEBUG_MASK_PROTOCOL_GUID);
+#endif
diff --git a/Core/Protocol/FileInfo.h b/Core/Protocol/FileInfo.h
new file mode 100644
index 0000000..cff5fc7
--- /dev/null
+++ b/Core/Protocol/FileInfo.h
@@ -0,0 +1,36 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FileInfo.c
+
+Abstract:
+
+ SimpleFileSystem protocol as defined in the EFI 1.0 specification.
+
+ The SimpleFileSystem protocol is the programatic access to the FAT (12,16,32)
+ file system specified in EFI 1.0. It can also be used to abstract any
+ file system other than FAT.
+
+ EFI 1.0 can boot from any valid EFI image contained in a SimpleFileSystem
+
+--*/
+
+#ifndef _FILE_INFO_H_
+#define _FILE_INFO_H_
+#include <Protocol/SimpleFileSystem.h>
+
+#define SIZE_OF_EFI_FILE_INFO EFI_FIELD_OFFSET (EFI_FILE_INFO, FileName)
+
+GUID_VARIABLE_DECLARATION(gEfiFileInfoGuid,EFI_FILE_INFO_ID);
+
+#endif
diff --git a/Core/Protocol/FirmwareVolumeDispatch.h b/Core/Protocol/FirmwareVolumeDispatch.h
new file mode 100644
index 0000000..9b99874
--- /dev/null
+++ b/Core/Protocol/FirmwareVolumeDispatch.h
@@ -0,0 +1,36 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ FirmwareVolumeDispatch.h
+
+Abstract:
+
+ Firmware Volume Dispatch protocol as defined in the Tiano Firmware Volume
+ specification.
+
+ Presence of this protocol tells the dispatch to dispatch from this Firmware
+ Volume
+
+--*/
+
+#ifndef __FIRMWARE_VOLUME_DISPATCH_H__
+#define __FIRMWARE_VOLUME_DISPATCH_H__
+#include <EFI.h>
+
+
+#define EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID \
+ { 0x7aa35a69, 0x506c, 0x444f, 0xa7, 0xaf, 0x69, 0x4b, 0xf5, 0x6f, 0x71, 0xc8 }
+
+GUID_VARIABLE_DECLARATION(gEfiFirmwareVolumeDispatchProtocolGuid, EFI_FIRMWARE_VOLUME_DISPATCH_PROTOCOL_GUID);
+
+#endif
diff --git a/Core/Protocol/SectionExtraction.h b/Core/Protocol/SectionExtraction.h
new file mode 100644
index 0000000..4bb16eb
--- /dev/null
+++ b/Core/Protocol/SectionExtraction.h
@@ -0,0 +1,83 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ SectionExtraction.h
+
+Abstract:
+
+ Section extraction protocol as defined in the Tiano File Image Format specification.
+
+ This interface provides a means of decoding a set of sections into a linked list of
+ leaf sections. This provides for an extensible and flexible file format.
+
+--*/
+
+#ifndef _SECTION_EXTRACTION_PROTOCOL_H
+#define _SECTION_EXTRACTION_PROTOCOL_H
+
+#include "EfiFirmwareFileSystem.h"
+
+//
+// Protocol GUID definition
+//
+#define EFI_SECTION_EXTRACTION_PROTOCOL_GUID \
+ { \
+ 0x448F5DA4, 0x6DD7, 0x4FE1, 0x93, 0x07, 0x69, 0x22, 0x41, 0x92, 0x21, 0x5D \
+ }
+
+EFI_FORWARD_DECLARATION (EFI_SECTION_EXTRACTION_PROTOCOL);
+
+//
+// Protocol member functions
+//
+typedef
+EFI_STATUS
+(EFIAPI *EFI_OPEN_SECTION_STREAM) (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL * This,
+ IN UINTN SectionStreamLength,
+ IN VOID *SectionStream,
+ OUT UINTN *SectionStreamHandle
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_GET_SECTION) (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL * This,
+ IN UINTN SectionStreamHandle,
+ IN EFI_SECTION_TYPE * SectionType,
+ IN EFI_GUID * SectionDefinitionGuid,
+ IN UINTN SectionInstance,
+ IN VOID **Buffer,
+ IN OUT UINTN *BufferSize,
+ OUT UINT32 *AuthenticationStatus
+ );
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_CLOSE_SECTION_STREAM) (
+ IN EFI_SECTION_EXTRACTION_PROTOCOL * This,
+ IN UINTN SectionStreamHandle
+ );
+
+//
+// Protocol definition
+//
+typedef struct _EFI_SECTION_EXTRACTION_PROTOCOL {
+ EFI_OPEN_SECTION_STREAM OpenSectionStream;
+ EFI_GET_SECTION GetSection;
+ EFI_CLOSE_SECTION_STREAM CloseSectionStream;
+} EFI_SECTION_EXTRACTION_PROTOCOL;
+
+GUID_VARIABLE_DECLARATION(gEfiSectionExtractionProtocolGuid,EFI_SECTION_EXTRACTION_PROTOCOL_GUID);
+
+#endif
diff --git a/Core/Protocol/TianoDecompress.h b/Core/Protocol/TianoDecompress.h
new file mode 100644
index 0000000..de5cb54
--- /dev/null
+++ b/Core/Protocol/TianoDecompress.h
@@ -0,0 +1,139 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ TianoDecompress.h
+
+Abstract:
+
+ The Tiano Decompress Protocol Interface
+
+--*/
+
+#ifndef _TIANO_DECOMPRESS_H_
+#define _TIANO_DECOMPRESS_H_
+#include <EFI.h>
+
+#define EFI_TIANO_DECOMPRESS_PROTOCOL_GUID \
+ { 0xe84cf29c, 0x191f, 0x4eae, 0x96, 0xe1, 0xf4, 0x6a, 0xec, 0xea, 0xea, 0x0b }
+
+EFI_FORWARD_DECLARATION (EFI_TIANO_DECOMPRESS_PROTOCOL);
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TIANO_DECOMPRESS_GET_INFO) (
+ IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
+ IN VOID *Source,
+ IN UINT32 SourceSize,
+ OUT UINT32 *DestinationSize,
+ OUT UINT32 *ScratchSize
+ );
+/*++
+
+Routine Description:
+
+ The GetInfo() function retrieves the size of the uncompressed buffer
+ and the temporary scratch buffer required to decompress the buffer
+ specified by Source and SourceSize. If the size of the uncompressed
+ buffer or the size of the scratch buffer cannot be determined from
+ the compressed data specified by Source and SourceData, then
+ EFI_INVALID_PARAMETER is returned. Otherwise, the size of the uncompressed
+ buffer is returned in DestinationSize, the size of the scratch buffer is
+ returned in ScratchSize, and EFI_SUCCESS is returned.
+
+ The GetInfo() function does not have scratch buffer available to perform
+ a thorough checking of the validity of the source data. It just retrieves
+ the 'Original Size' field from the beginning bytes of the source data and
+ output it as DestinationSize. And ScratchSize is specific to the decompression
+ implementation.
+
+Arguments:
+
+ This - The protocol instance pointer
+ Source - The source buffer containing the compressed data.
+ SourceSize - The size, in bytes, of source buffer.
+ DestinationSize - A pointer to the size, in bytes, of the uncompressed buffer
+ that will be generated when the compressed buffer specified
+ by Source and SourceSize is decompressed.
+ ScratchSize - A pointer to the size, in bytes, of the scratch buffer that
+ is required to decompress the compressed buffer specified by
+ Source and SourceSize.
+
+Returns:
+ EFI_SUCCESS - The size of the uncompressed data was returned in DestinationSize
+ and the size of the scratch buffer was returned in ScratchSize.
+ EFI_INVALID_PARAMETER - The size of the uncompressed data or the size of the scratch
+ buffer cannot be determined from the compressed data specified by
+ Source and SourceData.
+
+--*/
+
+
+typedef
+EFI_STATUS
+(EFIAPI *EFI_TIANO_DECOMPRESS_DECOMPRESS) (
+ IN EFI_TIANO_DECOMPRESS_PROTOCOL *This,
+ IN VOID* Source,
+ IN UINT32 SourceSize,
+ IN OUT VOID* Destination,
+ IN UINT32 DestinationSize,
+ IN OUT VOID* Scratch,
+ IN UINT32 ScratchSize
+ );
+/*++
+
+Routine Description:
+
+ The Decompress() function extracts decompressed data to its original form.
+
+ This protocol is designed so that the decompression algorithm can be
+ implemented without using any memory services. As a result, the
+ Decompress() function is not allowed to call AllocatePool() or
+ AllocatePages() in its implementation. It is the caller's responsibility
+ to allocate and free the Destination and Scratch buffers.
+
+ If the compressed source data specified by Source and SourceSize is
+ sucessfully decompressed into Destination, then EFI_SUCCESS is returned.
+ If the compressed source data specified by Source and SourceSize is not in
+ a valid compressed data format, then EFI_INVALID_PARAMETER is returned.
+
+Arguments:
+
+ This - The protocol instance pointer
+ Source - The source buffer containing the compressed data.
+ SourceSize - The size of source data.
+ Destination - On output, the destination buffer that contains
+ the uncompressed data.
+ DestinationSize - The size of destination buffer. The size of destination
+ buffer needed is obtained from GetInfo().
+ Scratch - A temporary scratch buffer that is used to perform the
+ decompression.
+ ScratchSize - The size of scratch buffer. The size of scratch buffer needed
+ is obtained from GetInfo().
+
+Returns:
+
+ EFI_SUCCESS - Decompression completed successfully, and the uncompressed
+ buffer is returned in Destination.
+ EFI_INVALID_PARAMETER
+ - The source buffer specified by Source and SourceSize is
+ corrupted (not in a valid compressed format).
+
+--*/
+
+typedef struct _EFI_TIANO_DECOMPRESS_PROTOCOL {
+ EFI_TIANO_DECOMPRESS_GET_INFO GetInfo;
+ EFI_TIANO_DECOMPRESS_DECOMPRESS Decompress;
+} EFI_TIANO_DECOMPRESS_PROTOCOL;
+
+GUID_VARIABLE_DECLARATION(gEfiTianoDecompressProtocolGuid, EFI_TIANO_DECOMPRESS_PROTOCOL_GUID);
+#endif
diff --git a/Core/Protocol/VariableWrite.h b/Core/Protocol/VariableWrite.h
new file mode 100644
index 0000000..c87d1f4
--- /dev/null
+++ b/Core/Protocol/VariableWrite.h
@@ -0,0 +1,80 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/Protocol/VariableWrite.h 1 5/19/06 11:28p Felixp $
+//
+// $Revision: 1 $
+//
+// $Date: 5/19/06 11:28p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/Protocol/VariableWrite.h $
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+// 2 3/04/05 10:43a Mandal
+//
+// 1 1/28/05 12:44p Felixp
+//
+// 2 1/18/05 3:21p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/23/04 9:42a Felixp
+//
+// 1 12/23/04 9:29a Felixp
+//
+// 1 3/30/04 2:24a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: VariableWrite.h
+//
+// Description: Variable Architectural Protocol Definitions
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __VARIABLE_WRITE_ARCH_PROTOCOL_H__
+#define __VARIABLE_WRITE_ARCH_PROTOCOL_H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <EFI.h>
+
+#ifndef EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID
+#define EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID \
+ {0x6441f818,0x6362,0x4e44,0xb5,0x70,0x7d,0xba,0x31,0xdd,0x24,0x53}
+#endif
+GUID_VARIABLE_DECLARATION(gEfiVariableWriteArchProtocolGuid, EFI_VARIABLE_WRITE_ARCH_PROTOCOL_GUID);
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2005, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/Rules.mak b/Core/Rules.mak
new file mode 100644
index 0000000..d28a961
--- /dev/null
+++ b/Core/Rules.mak
@@ -0,0 +1,868 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Core/Rules.mak 83 11/03/11 2:21p Felixp $
+#
+# $Revision: 83 $
+#
+# $Date: 11/03/11 2:21p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Core/Rules.mak $
+#
+# 83 11/03/11 2:21p Felixp
+# [TAG] EIP61003
+# [Category] Improvement
+# [Description] Support for setting of the debug parameters when
+# DEBUG_MODE is 0.
+#
+# 82 11/03/11 12:27p Felixp
+# [TAG] EIP74554
+# [Category] Improvement
+# [Description] Support generation of the assembly listing file.
+# [Files] Core.sdl, Rules.mak
+#
+# 81 10/27/11 3:27p Felixp
+# Improvement:
+# Make sure all externally callable targets have dependency from the
+# $(DIRS),
+# which is a list of targets that create intermediate file directories.
+#
+# 80 6/27/11 5:36p Felixp
+# 1. DUAL_INSTANCE_LIBRARIES_BUILD_DIR macro is added.
+# 2. Use PEI instance of AmiCspLib when PEI components are built
+#
+# 79 6/16/11 9:12a Felixp
+# Enhancements:
+# 1. Make sure $(BUILD_DIR)\$(NAME)CcOptions.txt is regenerated during
+# every build.
+# 2. Define SMM_BUILD macro during the compilation of PI SMM drivers (SMM
+# and Combined DXE/SMM).
+#
+# 78 2/05/11 1:44p Artems
+# Added PI 1.1 support (SMM driver build rules)
+#
+# 77 11/17/10 11:09a Felixp
+# New Rules.mak parameter MY_SDBS is added.
+# It can be used to extend list of module's SDB files.
+# The list of module's SDB files is a concatenation of the
+# list of SDB files generated from module's UNI files and MY_SDB files.
+# The MY_SDB macro has to be in the format -db <sdb-file>.
+# For example, "MY_SDBS=-db $(BUILD_DIR)\S1.sdb -db $(BUILD_DIR)\S1.sdb"
+#
+# 76 6/09/10 11:04p Felixp
+# Command to delete .i files after VFR processing is removed.
+# It is no longer needed because updated VFR compiler is no longer
+# placing
+# .i files into the project root directory.
+#
+# 75 6/09/10 10:44p Felixp
+# New build type RESOURCES is added to rules.mak.
+# The type is used to build only HII resources of the component.
+#
+# 74 5/07/10 12:41p Felixp
+# PEI_PHASE and DXE_PAHSE macros are renamed to PEI_BUILD and DXE_BUILD
+#
+# 73 5/07/10 12:22p Felixp
+# Predefined PEI_PHASE and DXE_PHASE macros are added.
+# The macros can be used in the in the source code that used in PEI and
+# DXE to
+# implemented phase specific behavior.
+#
+# 72 3/19/10 6:02p Felixp
+# Support USE_CC_RESPONSE_FILE for GUID_LIBRARY builds.
+#
+# 71 3/18/10 5:49p Felixp
+# Bug fix in USE_LINKER_RESPONSE_FILE processing
+#
+# 70 3/18/10 5:23p Felixp
+# Bug fix in USE_CC_RESPONSE_FILE processing
+#
+# 69 3/18/10 5:12p Felixp
+# New SDL token USE_CC_RESPONSE_FILE is added.
+# When this token is enabled, all C-compiler(CC) options are passed via
+# the response file.
+# The token should be enabled when the length of the CC command line
+# exceeds
+# the maximum supported limit. The token is disabled by default.
+#
+# 68 2/23/10 8:28p Felixp
+# String Override Support(EIP 32696).
+# Rules.mak is updated to run .uni file processing utility (StrGather)
+# with the special -override flag. The flag instructs the utility to use
+# last instance of the string, if more than one instance is available.
+# NOTE: This feature requires new version of the Tools module
+# (4.5.5_Tools_30 or newer).
+#
+# 67 11/13/09 5:05p Felixp
+# Don't generate debug information for components of type BINARY.
+#
+# 66 11/06/09 9:24a Felixp
+# 1. PE32-based .bin Files Support
+# New built type BINARY is added.
+# The type is used to generate FFS files containing raw binary data.
+# The binary file is created from the PE32/PE32+ file by stripping the
+# headers.
+# NOTE: This feature requires new version of the Tools module.
+# 2. New SDL token USE_LINKER_RESPONSE_FILE is added.
+# When this token is enabled, all linked options are passed via the
+# response file.
+# The token should be enabled when the length of the linker command
+# line exceeds
+# the maximum supported limit. The token is disabled by default.
+#
+# 64 10/09/09 5:11p Felixp
+# UEFI 2.1-related changes.
+#
+# 63 5/04/09 2:00p Felixp
+# Support for alternative font data packaging(EIP 18489) is added.
+# Description: Build process is updated to provide framework that can be
+# used to
+# overwrite default packaging of the font data.
+# Two new SDL tokens are created:
+# "LANGUAGE_FONT_LIST" - Space separated list of language identifiers.
+# The fonts for these languages will be included into the ROM image.
+# "STRING_PACK_POST_PROCESS_COMMAND" - The token defines command
+# used in rules.mak to perform additional processing of
+# module's HII string pack ($(BUILD_DIR)$(NAME)Str.hpk)
+# after standard processing (performed by StrGather utility) is
+# completed.
+#
+# 62 3/05/09 9:52a Felixp
+# Minor bug fix: Dual mode libraries (libraries with PEI and DXE
+# instances) INIT_LIST problem.
+# Description: Compilation of the dual mode libraries with
+# INIT_LIST in x64 mode (x64_SUPPORT=1) was failing.
+# Symptoms: Build fails with "Don't know how to build Build\IA32\Token.h"
+# error.
+# Details: $(BUILD_DIR)\Token.h replaced with $(BUILD_ROOT)\Token.h
+#
+# 61 1/02/09 12:49p Felixp
+# C preprocessor copyright message is suppressed.
+#
+# 60 12/16/08 3:50p Felixp
+# Support for "Step out" operation in the debugger.
+# x64 debuggers implemen "Step out" operation using exception directory
+# within PE32+ image.
+# In previous versions of the Core exception directory was stripped out
+# by the build process to reduce PE32 image size.
+# Current version of the code preserves exception directory when
+# generation of debug informataon is enabled (DEBUG_INFO token is set to
+# "on").
+#
+# 59 10/31/08 11:22a Felixp
+#
+# 58 10/22/08 3:57p Felixp
+# Some of the linker warnings are eliminated (.efi files are no longer
+# built as .dll files. They are built as .exe files).
+#
+# 57 10/10/08 9:51a Felixp
+#
+# 56 10/10/08 9:50a Felixp
+# - Component VFR files were compiled when HAS_RESOURCES was set to zero
+# - Workaround for ML64 added
+#
+# 55 5/09/08 5:05p Felixp
+# Minor bug fix: Rules.mak based build of the componentns with .efi files
+# did not work.
+#
+# 54 12/14/07 12:38p Felixp
+#
+# 53 12/14/07 12:30p Felixp
+# DEST_DIR usage removed (DEST_DIR is not defined by cif2mak if more than
+# one cif file used).
+#
+# 52 10/22/07 6:11p Felixp
+# New FFS_ALIGNMENT switch added to support FFS data alignment
+#
+# 51 9/05/07 6:49p Felixp
+# Disable debugging features is DEBUG_MODE is zero
+#
+# 50 9/05/07 1:42a Felixp
+# 1. Debugging-related tokens updated to use boolean tokens instead of
+# enumeration
+# 2. Support for ROM_IMAGE_SIZE is added.
+#
+# 49 8/02/07 1:27a Felixp
+#
+# 48 6/01/07 2:53p Felixp
+# TE image support added. (PE_IMAGE_FORMAT macro that is used to
+# supppress TE image generation passed to FFS.mak)
+#
+# 47 3/30/07 4:43p Felixp
+# Support for FFS_CHECKSUM added to control FFS checksum generation.
+#
+# 46 3/13/07 9:54a Felixp
+# Global and CPU architecture specific macros are now passed
+# to C preprocessor (used during DepEx and VFR compilation)
+#
+# 45 2/23/07 2:30p Felixp
+# Support for custom string consumers added (MY_STRING_CONSUMERS).
+#
+# 44 12/28/06 6:24p Felixp
+# Support for 32-bit C compiler from Windows Server 2003 SP1 DDK
+# (3790.1830) added
+#
+# 43 11/11/06 11:47a Felixp
+# Support for date/time stamps(All executables generated with the
+# identical date/time stamp)
+#
+# 36 10/03/06 8:56a Felixp
+# Support for a build family specific build rules.
+# MY_DEFINES macro added to list all module specific macro definitions
+#
+# 35 9/26/06 9:01a Felixp
+# Multilanguage support added. New FontTool is required.
+#
+# 34 9/07/06 1:48p Felixp
+#
+# 33 8/24/06 9:06a Felixp
+# Preliminary x64 support (work in progress)
+#
+# 32 7/14/06 9:55a Pavell
+#
+# 31 6/22/06 2:55p Andriyn
+# Fix EDK modules compiling
+#
+# 30 5/19/06 6:14p Felixp
+# 1. Support for EDK-based modules added.
+# 2. MY_INCLUDES macro added to specify list of include directories
+#
+# 28 5/12/06 3:07p Felixp
+# EDK support added
+#
+# 25 3/30/06 6:05p Felixp
+# Support for compiler version auto-detection added.
+#
+# 24 2/24/06 2:43p Felixp
+#
+# 23 2/23/06 6:44p Felixp
+# Change in string handling. Skip source scanning if STRING_CONSUMERS is
+# blank.
+# This is needed to support binary modules with strings.
+#
+# 22 7/29/05 4:16p Robert
+# Updated Init Parts rule to allow use in libraries
+#
+# 20 7/14/05 6:36p Felixp
+# SDL tokens for ECHO and DEL added
+#
+# 18 6/17/05 3:25p Felixp
+# Setup support: sd files handling
+#
+# 17 6/16/05 10:42a Felixp
+# 1. Tokens.c added. It has variables representing SDL tokens.
+# 2. InitList.c extended to support 2 init lists
+#
+# 15 5/24/05 12:47a Felixp
+# ignore unsupported languages
+#
+# 14 5/23/05 6:01p Felixp
+# CreateSdb target added
+# STRING_TOKEN definition added to avery StrToken.h
+# FFS file dependecies from RAWFILE and SECTION added
+#
+# 12 4/08/05 7:40a Felixp
+# strings
+#
+# 11 4/04/05 4:54p Felixp
+# dependency fix in .uni files processing
+#
+# 10 3/28/05 7:03p Felixp
+#
+# 9 3/28/05 7:02p Felixp
+# del command to delete .i files
+#
+# 8 3/22/05 10:31p Felixp
+# support for EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER added
+#
+# 5 3/17/05 1:26p Felixp
+# processing of multiple .uni files added
+#
+# 2 3/02/05 5:27p Felixp
+# Support for resources (strings, forms, fonts, etc.) added
+#
+# 5 1/20/05 11:34a Felixp
+# support for prebuilt objects, libraries and .efi files
+#
+# 4 1/18/05 3:21p Felixp
+# PrintDebugMessage renamed to Trace
+#
+# 2 12/24/04 2:39p Felixp
+#
+# 1 12/23/04 9:41a Felixp
+#
+# 7 12/15/04 9:06p Felixp
+# LegacyBoot application added
+# Minor build process improvements
+#
+# 6 11/01/04 7:59a Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: Rules.mak
+#
+# Description: Build Rules Template
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+.SUFFIXES: .asm .c .vfr .dll .uni
+
+!IFNDEF BUILD_ROOT
+BUILD_ROOT=$(BUILD_DIR)
+!ELSEIFNDEF BUILD_DIR
+BUILD_DIR=$(BUILD_ROOT)
+!ENDIF
+
+!INCLUDE $(BUILD_ROOT)\token.mak
+!INCLUDE $(BUILD_ROOT)\timestamp.mak
+!INCLUDE Core\Languages.mak
+!IF EXIST ($(BUILD_ROOT)\selectivedebugmodules.mak)
+!INCLUDE $(BUILD_ROOT)\selectivedebugmodules.mak
+!ENDIF
+
+EXTRA_INCLUDES=$(MY_INCLUDES) $(EXTRA_INCLUDES)
+EXTRA_DEFINES=$(MY_DEFINES) $(EXTRA_DEFINES)
+
+FINAL_CFLAGS=$(CFLAGS) $(EXTRA_CFLAGS) $(FORCE_INCLUDE)
+FINAL_LFLAGS=$(LFLAGS) $(EXTRA_LFLAGS)
+FINAL_AFLAGS=$(AFLAGS) $(EXTRA_AFLAGS)
+FINAL_AFLAGS16=$(AFLAGS16) $(EXTRA_AFLAGS16)
+LIBFLAGS=/NOLOGO
+#C preprocessor flags (used by DepEx parser and VFR compiler)
+CPFLAGS=/nologo $(GLOBAL_DEFINES) $(EXTRA_DEFINES) $(EXTRA_INCLUDES)
+
+#Check if this is a PEI module or DXE module
+!IF "$(TYPE)"=="PEIM"||"$(TYPE)"=="PEI_CORE"||"$(TYPE)"=="PEI_LIBRARY"||"$(TYPE)"=="PEI_GUID_LIBRARY"
+COMPONENT_BUILD_RULES=PEI
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /DPEI_BUILD
+DUAL_INSTANCE_LIBRARIES_BUILD_DIR=$(BUILD_ROOT)\IA32
+!ELSE
+COMPONENT_BUILD_RULES=DXE
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /DDXE_BUILD
+!IF "$(TYPE)"=="SMM_DRIVER"||"$(TYPE)"=="DXESMM_DRIVER"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /DSMM_BUILD
+DUAL_INSTANCE_LIBRARIES_BUILD_DIR=$(BUILD_ROOT)
+!ENDIF
+!ENDIF
+
+!IF "$(DEBUG_MODE)"!="1"
+# Debugging is disabled.
+# Use release mode settings
+# (unless debug flags have been defined for the release mode)
+!IFNDEF OPTIMIZATION
+OPTIMIZATION=1
+!ENDIF
+!IFNDEF DEBUG_INFO
+DEBUG_INFO=0
+!ENDIF
+!IFNDEF DEBUG_CODE
+DEBUG_CODE=0
+!ENDIF
+COMPONENT_OPTIMIZATION=$(OPTIMIZATION)
+COMPONENT_DEBUG_INFO=$(DEBUG_INFO)
+COMPONENT_DEBUG_CODE=$(DEBUG_CODE)
+!ELSEIF "$(SELECTIVE_DEBUG_ENABLE)"=="1"
+COMPONENT_OPTIMIZATION=$(SELECTIVE_OPTIMIZATION)
+COMPONENT_DEBUG_INFO=$(SELECTIVE_DEBUG_INFO)
+COMPONENT_DEBUG_CODE=$(SELECTIVE_DEBUG_CODE)
+!ELSEIF "$(COMPONENT_BUILD_RULES)"=="PEI" && "$(INDEPENDENT_PEI_DEBUG_SETTINGS)"=="1"
+COMPONENT_OPTIMIZATION=$(PEI_OPTIMIZATION)
+COMPONENT_DEBUG_INFO=$(PEI_DEBUG_INFO)
+COMPONENT_DEBUG_CODE=$(PEI_DEBUG_CODE)
+!ELSE
+COMPONENT_OPTIMIZATION=$(OPTIMIZATION)
+COMPONENT_DEBUG_INFO=$(DEBUG_INFO)
+COMPONENT_DEBUG_CODE=$(DEBUG_CODE)
+!ENDIF
+
+#Set debug mode specific flags
+#1. Optimization
+!IF "$(COMPONENT_OPTIMIZATION)"=="1"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /O1
+!ENDIF
+#2. Debug information
+!IF "$(COMPONENT_DEBUG_INFO)"=="1" && "$(TYPE)"!="BINARY"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /Fd$(BUILD_DIR)\ /Zi /Gm
+EXTRA_LFLAGS=$(EXTRA_LFLAGS) /MAP /DEBUG /PDB:$*.pdb
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) /Zi /Zf /Zd
+!ENDIF
+#3. Debug code
+!IF "$(COMPONENT_DEBUG_CODE)"=="1"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /DEFI_DEBUG
+EXTRA_AFLAGS=$(EXTRA_AFLAGS) /DDEBUG /DEFI_DEBUG
+!ENDIF
+#Done setting debug mode specific flags
+
+!IF "$(PROCESSOR_RULES)"!=""
+!INCLUDE $(PROCESSOR_RULES)
+MAKEFILES=$(MAKEFILES) $(PROCESSOR_RULES)
+!ENDIF
+
+!IF "$(FAMILY_RULES)"!=""
+!INCLUDE $(FAMILY_RULES)
+MAKEFILES=$(MAKEFILES) $(FAMILY_RULES)
+#This is here for backward compatibility/
+#Old labels of EDK module need this
+!ELSEIF "$(FAMILY)"=="EDK"
+EXTRA_CFLAGS=$(EXTRA_CFLAGS) /X $(EDK_INCLUDES)
+!ENDIF
+
+!IFNDEF MAKEFILE
+MAKEFILE=$(BUILD_ROOT)\$(NAME).mak
+!ENDIF
+MAKEFILES=$(MAKEFILES) $(MAKEFILE)
+
+!IFNDEF FFS_FILE
+FFS_FILE=$(BUILD_ROOT)\$(NAME).ffs
+!ENDIF
+
+!IFNDEF LIB_BUILD_DIR
+LIB_BUILD_DIR=$(BUILD_DIR)
+!ENDIF
+
+!IF "$(TYPE)"=="PEI_DXE_LIBRARY"
+all:
+ $(MAKE) /$(MAKEFLAGS)\
+ /f $(MAKEFILE) all\
+ TYPE=LIBRARY $(PARAMETERS)
+!IF DEFINED(CCPEI) && "$(CCPEI)"!="$(CC)"
+ $(MAKE) /$(MAKEFLAGS) BUILD_DIR=$$(LIB_BUILD_DIR)\
+ /f $(MAKEFILE) all\
+ TYPE=PEI_LIBRARY $(PARAMETERS)
+!ENDIF
+!ENDIF
+
+!IF "$(TYPE)"=="LEGACY16"
+.SOURCEGRULE .asm.obj
+ $(ASM16) $(FINAL_AFLAGS16) /Fo$D\ $<
+!ELSE
+#Workaround for ML64
+#If ML64 absolute path contains spaces,
+#it fails to process multiple files.
+#To workaround the issue, group file processing is disabled for ML64
+!IF "$(PROCESSOR)"=="x64"
+.SOURCERULE .asm.obj
+ $(ASM) $(FINAL_AFLAGS) /Fo$D\ $<
+!ELSE
+.SOURCEGRULE .asm.obj
+ $(ASM) $(FINAL_AFLAGS) /Fo$D\ $<
+!ENDIF
+!ENDIF
+
+!IF "$(USE_CC_RESPONSE_FILE)"=="1"
+CC_COMMAND_LINE=@$(BUILD_DIR)\$(NAME)CcOptions.txt
+!ELSE
+CC_COMMAND_LINE=$(FINAL_CFLAGS) $(EXTRA_DEFINES) $(EXTRA_INCLUDES)
+!ENDIF
+!IF "$(GENERATE_CC_LISTING_FILE)"=="1"
+.SOURCEGRULE .c.obj
+ $(CC) $(CC_COMMAND_LINE) /Fa$D\ /FAs /Fo$D\ $<
+!ELSE
+.SOURCEGRULE .c.obj
+ $(CC) $(CC_COMMAND_LINE) /Fo$D\ $<
+!ENDIF
+
+.SOURCERULE .vfr.hpk
+ $(VFRCOMPILE) -ppflag "/EP $(CPFLAGS)" -od $D -ibin -i INCLUDE -i Build -i $(PROJECT_DIR) $(VFR_INCLUDES) $<
+
+STRGATHER_PARSE_FLAGS=-i INCLUDE -parse -newdb -db $@ $<
+!IFDEF UNI_INCLUDE_PATH
+STRGATHER_PARSE_FLAGS=-i $(UNI_INCLUDE_PATH) $(STRGATHER_PARSE_FLAGS)
+!ENDIF
+.SOURCERULE .uni.sdb
+ $(STRGATHER) $(STRGATHER_PARSE_FLAGS)
+
+!IF "$(TYPE)"=="SDB" || "$(TYPE)"=="RESOURCES"
+HAS_RESOURCES=1
+!ENDIF
+
+!IFNDEF OBJECTS
+.SOURCEVAR OBJECTS=.obj(.c,.asm)
+!ENDIF
+!IFNDEF HEADERS
+.SOURCEVAR HEADERS=.h
+!ENDIF
+!IFNDEF DEPEX1
+.SOURCEVAR DEPEX1=.dxs
+!ENDIF
+!IFNDEF LIBRARIES
+.SOURCEVAR LIBRARIES=.lib
+!ENDIF
+!IFNDEF PRECOMPILED_OBJS
+.SOURCEVAR PRECOMPILED_OBJS=.obj
+!ENDIF
+!IFNDEF EFI_FILE
+.SOURCEVAR EFI_FILE=.efi
+!ENDIF
+
+!IF !DEFINED(SDB_FILES) && "$(HAS_RESOURCES)"=="1"
+.SOURCEVAR SDB_FILES=.sdb(.uni)
+!ENDIF
+!IFNDEF STRGATHER_FLAGS
+.SOURCEVAR STRGATHER_FLAGS=.sdb(.uni) : -db $F
+!ENDIF
+!IF !DEFINED(VFR_PACKS) && "$(HAS_RESOURCES)"=="1"
+.SOURCEVAR VFR_PACKS=.hpk(.vfr)
+!ENDIF
+!IFNDEF STRING_CONSUMERS
+STRING_CONSUMERS = $(MY_STRING_CONSUMERS)
+.SOURCEVAR CFILES=.c
+.SOURCEVAR VFRFILES=.vfr
+.SOURCEVAR SDFILES=.sd
+!IF "$(CFILES)"!=""
+STRING_CONSUMERS=$(STRING_CONSUMERS) $(CFILES)
+!ENDIF
+!IF "$(VFRFILES)"!=""
+STRING_CONSUMERS=$(STRING_CONSUMERS) $(VFRFILES)
+!ENDIF
+!IF "$(SDFILES)"!=""
+STRING_CONSUMERS=$(STRING_CONSUMERS) $(SDFILES)
+!ENDIF
+!ENDIF
+
+HEADERS=$(HEADERS) $(EXT_HEADERS)
+ALL_EXT_OBJS_TMP=$(EXT_OBJS) $(LIBRARIES) $(PRECOMPILED_OBJS)
+!IF "$(COMPONENT_BUILD_RULES)"=="PEI" && EXIST (Build\IA32\AmiCSPLib.lib)
+ALL_EXT_OBJS=$(ALL_EXT_OBJS_TMP:Build\AmiCSPLib.lib=Build\IA32\AmiCSPLib.lib)
+!ELSE
+ALL_EXT_OBJS=$(ALL_EXT_OBJS_TMP)
+!ENDIF
+PACKS = $(VFR_PACKS)
+
+!IF "$(OBJECTS)"!=""
+$(OBJECTS) : $(HEADERS) $(MAKEFILES)
+!ENDIF
+
+!IF "$(VFR_PACKS)"!=""
+$(VFR_PACKS) : $(HEADERS) $(MAKEFILES)
+!ENDIF
+
+!IF "$(SDB_FILES)"!=""
+$(SDB_FILES) : $(HEADERS) $(MAKEFILES)
+!ENDIF
+
+!IF "$(TYPE)"=="BS_DRIVER"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_DRIVER
+PE_TYPE=$(TYPE)
+DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX
+!ELSEIF "$(TYPE)"=="RT_DRIVER"
+SUBSYSTEM = EFI_RUNTIME_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_DRIVER
+PE_TYPE=$(TYPE)
+DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX
+!ELSEIF "$(TYPE)"=="SMM_DRIVER"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_SMM
+PE_TYPE=BS_DRIVER
+DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX
+!ELSEIF "$(TYPE)"=="DXESMM_DRIVER"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_COMBINED_SMM_DXE
+PE_TYPE=BS_DRIVER
+!ELSEIF "$(TYPE)"=="APPLICATION"
+SUBSYSTEM = EFI_APPLICATION
+FV_TYPE=EFI_FV_FILETYPE_APPLICATION
+PE_TYPE=$(TYPE)
+!ELSEIF "$(TYPE)"=="PEI_CORE"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_PEI_CORE
+PE_TYPE=BS_DRIVER
+!ELSEIF "$(TYPE)"=="DXE_CORE"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_DXE_CORE
+PE_TYPE=BS_DRIVER
+!ELSEIF "$(TYPE)"=="SMM_CORE"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_SMM_CORE
+PE_TYPE=BS_DRIVER
+DEPEX1_TYPE=EFI_SECTION_DXE_DEPEX
+!ELSEIF "$(TYPE)"=="PEIM"
+SUBSYSTEM = EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_PEIM
+PE_TYPE=BS_DRIVER
+DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX
+!ELSEIF "$(TYPE)"=="COMBINED"
+SUBSYSTEM=EFI_BOOT_SERVICE_DRIVER
+FV_TYPE=EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER
+PE_TYPE=BS_DRIVER
+!ELSEIF "$(TYPE)"=="LIBRARY" || "$(TYPE)"=="PEI_LIBRARY"
+!UNDEF TYPE
+TYPE=LIBRARY
+!ELSEIF "$(TYPE)"=="PEI_GUID_LIBRARY" || "$(TYPE)"=="GUID_LIBRARY"
+!IF "$(TYPE)"=="PEI_GUID_LIBRARY"
+FORCE_INCLUDE=/FIPEI.h
+!ELSE
+FORCE_INCLUDE=/FIEFI.h
+!ENDIF
+!UNDEF TYPE
+TYPE=GUID_LIBRARY
+!ELSEIF "$(TYPE)"=="SDB"
+!ELSEIF "$(TYPE)"=="RESOURCES"
+!ELSEIF "$(TYPE)"=="LEGACY16" || "$(TYPE)"=="BINARY"
+FV_TYPE=EFI_FV_FILETYPE_FREEFORM
+!IFNDEF BINFILE
+BINFILE=$(BUILD_DIR)\$(NAME).bin
+
+bin : $(DIRS) $(BUILD_DIR)\$(NAME).bin
+
+!IF "$(TYPE)"=="BINARY"
+$(BUILD_DIR)\$(NAME).bin : $(BUILD_DIR)\$(NAME).dll
+ pe2bin $(BUILD_DIR)\$(NAME).dll $(BUILD_DIR)\$(NAME).bin
+!ELSE
+$(BUILD_DIR)\$(NAME).bin : $(OBJECTS)
+ $(ASMLINK) $(ASMLINKFLAGS) $(OBJECTS: =+), $(BUILD_DIR)\$(NAME).exe, $(BUILD_DIR)\$(NAME).map,,,
+!IFNDEF POST_PROCESS
+ exe2bin $(BUILD_DIR)\$(NAME).exe $(BUILD_DIR)\$(NAME).bin
+!ELSE
+ exe2bin $(BUILD_DIR)\$(NAME).exe $(BUILD_DIR)\$(NAME)1.bin
+ $(POST_PROCESS) $(BUILD_DIR)\$(NAME)1.bin $(BUILD_DIR)\$(NAME).bin
+!ENDIF # !IFNDEF POST_PROCESS
+!ENDIF # !IF "$(TYPE)"=="BINARY"
+!ENDIF # !IFNDEF BINFILE
+!ELSEIF "$(TYPE)"=="PEI_DXE_LIBRARY"
+!ELSEIF "$(TYPE)"==""
+!ERROR Error in the makefile of component $(NAME): 'TYPE' is undefined
+!ELSE
+!ERROR Error in the makefile of component $(NAME): TYPE $(TYPE) is unsupported
+!ENDIF
+
+!IF "$(TYPE)"=="BINARY"
+EXTRA_LFLAGS = $(EXTRA_LFLAGS) /NOENTRY /FIXED
+!ELSE
+EXTRA_LFLAGS = $(EXTRA_LFLAGS) /ENTRY:$(ENTRY_POINT)
+!ENDIF
+
+# Linkers newer than VC6 can directly generate .efi files.
+# However, we use FWIMAGE to generate .efi files because
+# FWIMAGE can set date/time stamp to a predefined value
+# This is useful for baniray reproducibility of the BIOS
+!IF "$(COMPONENT_DEBUG_INFO)"=="1"
+FWIMAGE_KEEP_EXCEPTION_TABLE=-e
+!ENDIF
+
+{$(BUILD_DIR)}.dll{$(BUILD_DIR)}.efi:
+ $(FWIMAGE) -t $(TODAY),$(NOW) $(FWIMAGE_KEEP_EXCEPTION_TABLE) $(PE_TYPE) $< $@
+
+!IF "$(TYPE)"=="APPLICATION" && "$(BUILD_FFS)"!="1"
+all : $(BUILD_DIR)\$(NAME).efi
+!ELSEIF "$(TYPE)"=="LIBRARY" || "$(TYPE)"=="GUID_LIBRARY"
+!IFNDEF LIBRARY_NAME
+LIBRARY_NAME=$(BUILD_DIR)\$(NAME).lib
+!ENDIF
+all : $(LIBRARY_NAME)
+
+!IF "$(TYPE)"=="GUID_LIBRARY"
+$(LIBRARY_NAME) : $(HEADERS)
+ $(SILENT)if not exist $(BUILD_DIR)\$(@B) md $(BUILD_DIR)\$(@B)
+!IF "$(USE_CC_RESPONSE_FILE)"=="1"
+ $(CC) @<<$(BUILD_DIR)\$(NAME)CcOptions.txt
+$(FINAL_CFLAGS) $(EXTRA_DEFINES) $(EXTRA_INCLUDES) /TC /DGUID_VARIABLE_DEFINITION /Fo$(BUILD_DIR)\$(@B)\\ $**
+<<KEEP
+!ELSE
+ $(CC) $(FINAL_CFLAGS) $(EXTRA_DEFINES) $(EXTRA_INCLUDES) /TC /DGUID_VARIABLE_DEFINITION /Fo$(BUILD_DIR)\$(@B)\\ $**
+!ENDIF
+ $(SILENT)cd $(BUILD_DIR)\$(@B)
+ $(LIBEXE) $(LIBFLAGS) /OUT:$(PROJECT_DIR)\$@ $(**F:.h=.obj)
+ $(SILENT)cd $(MAKEDIR)
+!ENDIF
+!ELSEIF "$(TYPE)"=="SDB"
+all : CreateSdb
+!ELSEIF "$(TYPE)"=="RESOURCES"
+all : CreateAllPacks
+!ELSEIF "$(TYPE)"=="PEI_DXE_LIBRARY"
+!ELSE
+all : $(FFS_FILE)
+!ENDIF
+
+# Strings and VFRs processing
+!IF "$(SDB_FILES)"!=""
+!IF "$(OBJECTS)"!=""||"$(VFR_PACKS)"!=""
+$(OBJECTS) $(VFR_PACKS) : $(BUILD_DIR)\$(NAME)StrTokens.h
+!ENDIF
+
+PACKS=$(BUILD_DIR)\$(NAME)Str.hpk $(PACKS)
+STRGATHER_DUMP_FLAGS=-dump -lang $(SUPPORTED_LANGUAGES: = -lang ) -bn $(NAME) -hpk $(BUILD_DIR)\$(NAME)Str.hpk -oh $(BUILD_DIR)\$(NAME)StrTokens.h -override
+
+CreateSdb : $(DIRS) $(SDB_FILES) $(STRING_CONSUMERS)
+!IF "$(STRING_CONSUMERS)"!=""
+ $(STRGATHER) -scan $(STRGATHER_FLAGS) $(MY_SDBS) -od $(BUILD_DIR)\$(NAME).sdb $(STRING_CONSUMERS)
+!ENDIF
+
+$(BUILD_DIR)\$(NAME)StrTokens.h $(BUILD_DIR)\$(NAME)Str.hpk : $(DIRS) $(SDB_FILES) $(STRING_CONSUMERS)
+!IF "$(STRING_CONSUMERS)"==""
+ $(STRGATHER) $(STRGATHER_DUMP_FLAGS) $(STRGATHER_FLAGS) $(MY_SDBS)
+!ELSE
+ $(STRGATHER) -scan $(STRGATHER_FLAGS) $(MY_SDBS) -od $(BUILD_DIR)\$(NAME).sdb $(STRING_CONSUMERS)
+ $(STRGATHER) $(STRGATHER_DUMP_FLAGS) -db $(BUILD_DIR)\$(NAME).sdb
+!ENDIF
+ $(ECHO) #ifndef VFRCOMPILE >> $(BUILD_DIR)\$(NAME)StrTokens.h
+ $(ECHO) #ifndef STRING_TOKEN >> $(BUILD_DIR)\$(NAME)StrTokens.h
+ $(ECHO) #define STRING_TOKEN(x) x >> $(BUILD_DIR)\$(NAME)StrTokens.h
+ $(ECHO) #endif >> $(BUILD_DIR)\$(NAME)StrTokens.h
+ $(ECHO) #endif >> $(BUILD_DIR)\$(NAME)StrTokens.h
+ $(STRING_PACK_POST_PROCESS_COMMAND)
+!ENDIF
+
+CreateAllPacks : $(DIRS) $(PACKS)
+
+!IF "$(PACKS)"!=""
+!IF "$(ITK_SUPPORT)"=="1"
+$(FFS_FILE) : $(BUILD_DIR)\$(NAME).hii
+
+$(BUILD_DIR)\$(NAME).hii: $(PACKS)
+ $(HIIPACK) create -g $(GUID) -p $(PACKS) -o $(BUILD_DIR)\$(NAME).hii
+!ENDIF
+!IF "$(EMBEDDED_RESOURCES)"=="1"
+EXTRA_LFLAGS = $(EXTRA_LFLAGS) $(BUILD_DIR)\$(NAME)Resources.obj
+$(BUILD_DIR)\$(NAME).dll : $(BUILD_DIR)\$(NAME)Resources.obj
+$(BUILD_DIR)\$(NAME)Resources.obj : $(PACKS)
+ $(AMIRC) /j /o$@ $**
+!ELSE
+SECTION=$(NAME)Resources.sec
+$(FFS_FILE) : $(BUILD_DIR)\$(NAME)Resources.sec
+$(BUILD_DIR)\$(NAME)Resources.sec : $(PACKS)
+ $(AMIRC) /s /o$@ $**
+!ENDIF
+!ENDIF
+
+# sources have priority over the binary
+!IF "$(TYPE)"!="LEGACY16" && "$(TYPE)"!="BINARY" && ("$(EFI_FILE)"==""||"$(OBJECTS)"!=""||"$(ALL_EXT_OBJS)"!=" ")
+!UNDEF EFI_FILE
+EFI_FILE=$(BUILD_DIR)\$(NAME).efi
+!ENDIF
+
+efi : $(DIRS) $(EFI_FILE)
+
+!IFDEF RAWFILE
+FFS_DEPS=$(FFS_DEPS) $(PROJECT_DIR)\$(RAWFILE)\
+!ENDIF
+!IFDEF SECTION
+FFS_DEPS=$(FFS_DEPS) $(BUILD_DIR)\$(SECTION)\
+!ENDIF
+
+$(FFS_FILE) : $(EFI_FILE) $(MAKEFILES) Core\FFS.mak $(DEPEX1) $(DEPEX2) $(BINFILE) $(FFS_DEPS)
+ $(MAKE) /$(MAKEFLAGS) /f Core\FFS.mak \
+ NAME=$(NAME) \
+ BUILD_DIR=$(BUILD_ROOT) SOURCE_DIR=$(SOURCE_DIR) \
+ GUID=$(GUID) \
+ TYPE=$(FV_TYPE) \
+ FFSFILE=$@ COMPRESS=$(COMPRESS) \
+ "EXTRA_DEFINES=$(EXTRA_DEFINES)" "EXTRA_INCLUDES=$(EXTRA_INCLUDES)" "CPFLAGS=$(CPFLAGS)"\
+!IF "$(EFI_FILE)"!=""
+ PEFILE=$(EFI_FILE) \
+!ENDIF
+!IF "$(DEPEX1)"!=""
+ DEPEX1=$(DEPEX1) DEPEX1_TYPE=$(DEPEX1_TYPE) \
+!ENDIF
+!IFDEF DEPEX2
+ DEPEX2=$(DEPEX2) DEPEX2_TYPE=$(DEPEX2_TYPE) \
+!ENDIF
+!IFDEF BINFILE
+ BINFILE=$(BINFILE) \
+!ENDIF
+!IFDEF RAWFILE
+ RAWFILE=$(RAWFILE) \
+!ENDIF
+!IFDEF SECTION
+ SECTION=$(SECTION) \
+!ENDIF
+!IFDEF FFS_CHECKSUM
+ FFS_CHECKSUM=$(FFS_CHECKSUM) \
+!ENDIF
+!IFDEF FFS_ALIGNMENT
+ FFS_ALIGNMENT=$(FFS_ALIGNMENT) \
+!ENDIF
+!IFDEF PE_IMAGE_FORMAT
+ PE_IMAGE_FORMAT=$(PE_IMAGE_FORMAT) \
+!ENDIF
+
+!IFDEF INIT_LIST
+INIT_LIST_DEFINES=/D"INIT_LIST=$(INIT_LIST)"
+!IFDEF INIT_LIST2
+INIT_LIST_DEFINES=$(INIT_LIST_DEFINES) /D"INIT_LIST2=$(INIT_LIST2)"
+!ENDIF
+!IF "$(TYPE)"=="LIBRARY"
+$(LIBRARY_NAME) : $(BUILD_DIR)\$(NAME)_INIT_LIST.obj
+LIBFLAGS = $(LIBFLAGS) $(BUILD_DIR)\$(NAME)_INIT_LIST.obj
+!ELSE
+EXTRA_LFLAGS = $(EXTRA_LFLAGS) $(BUILD_DIR)\$(NAME)_INIT_LIST.obj
+$(BUILD_DIR)\$(NAME).dll : $(BUILD_DIR)\$(NAME)_INIT_LIST.obj
+!ENDIF # !IF "$(TYPE)"=="LIBRARY"
+$(BUILD_DIR)\$(NAME)_INIT_LIST.obj : $(PROJECT_DIR)\Core\InitList.c $(BUILD_ROOT)\token.h
+ $(CC) $(FINAL_CFLAGS) $(INIT_LIST_DEFINES) /Fo$@ $(PROJECT_DIR)\Core\InitList.c
+!ENDIF # !IFDEF INIT_LIST
+
+#We no longer need build-through-lib mode.
+#Let's keep IF statement is case we will want to change it in the future
+#!IF "$(BUILD_BASE_LIB)"=="1" && "$(OBJECTS)"!=""
+#$(BUILD_DIR)\$(NAME)Base.lib : $(OBJECTS)
+# $(LIBEXE) $(LIBFLAGS) /OUT:$@ $(OBJECTS)
+#$(BUILD_DIR)\$(NAME).dll : $(BUILD_DIR)\$(NAME)Base.lib $(ALL_EXT_OBJS) $(MAKEFILE)
+# $(LINK) $(FINAL_LFLAGS) $(BUILD_DIR)\$(NAME)Base.lib $(ALL_EXT_OBJS)
+#!ELSE
+!IF "$(USE_CC_RESPONSE_FILE)"=="1"
+$(BUILD_DIR)\$(NAME).dll : $(BUILD_DIR)\$(NAME)CcOptions.txt
+
+# This target is required to make sure
+# $(BUILD_DIR)\$(NAME)CcOptions.txt is regenerated during every build
+CcOptionsPhonyTargetWithTheLongName:
+
+$(BUILD_DIR)\$(NAME)CcOptions.txt : CcOptionsPhonyTargetWithTheLongName
+ $(SILENT)copy << $@
+$(FINAL_CFLAGS) $(EXTRA_DEFINES) $(EXTRA_INCLUDES)
+<<
+!ENDIF
+$(BUILD_DIR)\$(NAME).dll : $(OBJECTS) $(ALL_EXT_OBJS) $(MAKEFILES)
+!IF "$(USE_LINKER_RESPONSE_FILE)"=="1"
+ $(LINK) @<<$(BUILD_DIR)\$(NAME)LinkerOptions.txt
+$(FINAL_LFLAGS) $(OBJECTS) $(ALL_EXT_OBJS)
+<<KEEP
+!ELSE
+ $(LINK) $(FINAL_LFLAGS) $(OBJECTS) $(ALL_EXT_OBJS)
+!ENDIF
+#!ENDIF
+!IF "$(TYPE)"=="LIBRARY"
+!IF "$(USE_CC_RESPONSE_FILE)"=="1"
+$(LIBRARY_NAME) : $(BUILD_DIR)\$(NAME)CcOptions.txt
+!ENDIF
+$(LIBRARY_NAME) : $(OBJECTS) $(ALL_EXT_OBJS)
+!IF "$(USE_LINKER_RESPONSE_FILE)"=="1"
+ $(LIBEXE) @<<$(BUILD_DIR)\$(NAME)LibOptions.txt
+$(LIBFLAGS) /OUT:$@ $(OBJECTS) $(ALL_EXT_OBJS)
+<<KEEP
+!ELSE
+ $(LIBEXE) $(LIBFLAGS) /OUT:$@ $(OBJECTS) $(ALL_EXT_OBJS)
+!ENDIF
+!ENDIF
+!IF EXIST ($(BUILD_ROOT)\targets.mak)
+!INCLUDE $(BUILD_ROOT)\targets.mak
+!ENDIF
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2011, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/Tiano.h b/Core/Tiano.h
new file mode 100644
index 0000000..dec5019
--- /dev/null
+++ b/Core/Tiano.h
@@ -0,0 +1,348 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/SOURCE/Core/EDK/Tiano.h 7 5/27/11 5:44p Felixp $
+//
+// $Revision: 7 $
+//
+// $Date: 5/27/11 5:44p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/SOURCE/Core/EDK/Tiano.h $
+//
+// 7 5/27/11 5:44p Felixp
+// EFI_FIRMWARE_VOLUME_BLOCK_PROTOCOL_GUID definition is removed
+// (the macro is now defined in the FirmwareVolumeBlock.h
+//
+// 6 9/22/10 7:09p Felixp
+// Bug fix: PEI_REPORT_STATUS_CODE was not properly defined.
+//
+// 5 4/25/07 11:31a Felixp
+//
+// 4 10/07/06 10:23a Felixp
+// UIEFI2.0 support.
+// Updated to EDK 20060904
+//
+// 3 8/24/06 9:40a Felixp
+// x64 support
+//
+// 2 5/20/06 9:38p Felixp
+//
+// 1 5/19/06 11:28p Felixp
+//
+// 1 3/13/06 1:57a Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: Tiano.h
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+#ifndef __TIANO__H__
+#define __TIANO__H__
+#ifdef __cplusplus
+extern "C" {
+#endif
+#include <EFI.h>
+#include <DXE.h>
+#include <StatusCodes.h>
+#include <Protocol/DevicePath.h>
+
+//from EfiStdArg.h
+#define _EFI_INT_SIZE_OF(n) ((sizeof (n) + sizeof (UINTN) - 1) &~(sizeof (UINTN) - 1))
+
+//
+// Also support coding convention rules for var arg macros
+//
+#ifndef VA_START
+
+typedef CHAR8 *VA_LIST;
+#define VA_START(ap, v) (ap = (VA_LIST) & (v) + _EFI_INT_SIZE_OF (v))
+#define VA_ARG(ap, t) (*(t *) ((ap += _EFI_INT_SIZE_OF (t)) - _EFI_INT_SIZE_OF (t)))
+#define VA_END(ap) (ap = (VA_LIST) 0)
+
+#endif
+
+#include <EfiDebug.h>
+
+#define EFI_STRINGIZE(a) #a
+
+#define EFI_PROTOCOL_DEFINITION(a) EFI_STRINGIZE (Protocol/a.h)
+#define EFI_GUID_DEFINITION(a) EFI_STRINGIZE (Guid/a.h)
+#define EFI_ARCH_PROTOCOL_DEFINITION(a) EFI_STRINGIZE (Protocol/a.h)
+
+#define EFI_PROTOCOL_PRODUCER(a) EFI_PROTOCOL_DEFINITION (a)
+#define EFI_PROTOCOL_CONSUMER(a) EFI_PROTOCOL_DEFINITION (a)
+#define EFI_PROTOCOL_DEPENDENCY(a) EFI_PROTOCOL_DEFINITION (a)
+
+#define EFI_PPI_DEFINITION(a) EFI_STRINGIZE (Ppi/a.h)
+#define EFI_PPI_PRODUCER(a) EFI_PPI_DEFINITION (a)
+#define EFI_PPI_CONSUMER(a) EFI_PPI_DEFINITION (a)
+#define EFI_PPI_DEPENDENCY(a) EFI_PPI_DEFINITION (a)
+
+#define CONST const
+#define STATIC static
+#define VOLATILE volatile
+
+#define EFI_BOOTSERVICE
+#define EFI_RUNTIMESERVICE
+#define EFI_BOOTSERVICE11
+#define EFI_DXESERVICE
+//
+// ALIGN_POINTER - aligns a pointer to the lowest boundry
+//
+#define ALIGN_POINTER(p, s) ((VOID *) (p + ((s - ((UINTN) p)) & (s - 1))))
+
+//
+// ALIGN_VARIABLE - aligns a variable up to the next natural boundry for int size of a processor
+//
+#define ALIGN_VARIABLE(Value, Adjustment) \
+ (UINTN) Adjustment = 0; \
+ if ((UINTN) Value % sizeof (UINTN)) { \
+ (UINTN) Adjustment = sizeof (UINTN) - ((UINTN) Value % sizeof (UINTN)); \
+ } \
+ Value = (UINTN) Value + (UINTN) Adjustment
+
+//
+// EFI_FIELD_OFFSET - returns the byte offset to a field within a structure
+//
+#define EFI_FIELD_OFFSET(TYPE,Field) ((UINTN)(&(((TYPE *) 0)->Field)))
+
+//
+// CONTAINING_RECORD - returns a pointer to the structure
+// from one of it's elements.
+//
+#define _CR(Record, TYPE, Field) ((TYPE *) ((CHAR8 *) (Record) - (CHAR8 *) &(((TYPE *) 0)->Field)))
+
+//
+// Define macros to build data structure signatures from characters.
+//
+#define EFI_SIGNATURE_16(A, B) ((A) | (B << 8))
+#define EFI_SIGNATURE_32(A, B, C, D) (EFI_SIGNATURE_16 (A, B) | (EFI_SIGNATURE_16 (C, D) << 16))
+#define EFI_SIGNATURE_64(A, B, C, D, E, F, G, H) \
+ (EFI_SIGNATURE_32 (A, B, C, D) | ((UINT64) (EFI_SIGNATURE_32 (E, F, G, H)) << 32))
+
+//AMI <--> EDK mapping
+#define EFI_LOADED_IMAGE_INFORMATION_REVISION EFI_LOADED_IMAGE_PROTOCOL_REVISION
+typedef DXE_SERVICES EFI_DXE_SERVICES;
+#define EFI_TPL_APPLICATION TPL_APPLICATION
+#define EFI_TPL_CALLBACK TPL_CALLBACK
+#define EFI_TPL_NOTIFY TPL_NOTIFY
+#define EFI_TPL_HIGH_LEVEL TPL_HIGH_LEVEL
+
+#define END_DEVICE_PATH_TYPE 0x7F
+#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xFF
+#define EFI_EVENT_EFI_SIGNAL_MASK 0x000000FF
+#define EFI_EVENT_EFI_SIGNAL_MAX 4
+#define EFI_TPL_DRIVER 6
+#define EFI_DXE_SERVICES_SIGNATURE DXE_SERVICES_SIGNATURE
+#define EFI_DXE_SERVICES_REVISION DXE_SERVICES_REVISION
+#define EFI_DXE_ENTRY_POINT(EntryPoint)
+#ifndef EFI_DEADLOOP
+#define EFI_DEADLOOP() { volatile UINTN __DeadLoopVar__ = 1; while (__DeadLoopVar__); }
+#endif
+#define EFI_BREAKPOINT() EFI_DEADLOOP()
+#define EFI_BAD_POINTER 0xAFAFAFAF
+//This is defined in FirmwareValume.h but has nothing to do with the protocol.
+//It should be in DxeMain internal header
+#define FV_DEVICE_SIGNATURE EFI_SIGNATURE_32 ('_', 'F', 'V', '_')
+#define EFI_FVH_SIGNATURE FV_SIGNATURE
+#define EFI_FV_BLOCK_MAP_ENTRY FvBlockMapEntry
+//This is define in TianoType.h, however, this is not in DXECIS
+//
+// attributes for reserved memory before it is promoted to system memory
+//
+#define EFI_MEMORY_PRESENT 0x0100000000000000
+#define EFI_MEMORY_INITIALIZED 0x0200000000000000
+#define EFI_MEMORY_TESTED 0x0400000000000000
+
+//
+// range for memory mapped port I/O on IPF
+//
+#define EFI_MEMORY_PORT_IO 0x4000000000000000
+//
+// A pointer to a function in IPF points to a plabel.
+//
+typedef struct {
+ UINT64 EntryPoint;
+ UINT64 GP;
+} EFI_PLABEL;
+////////////////////////////////////////////////
+//defined for every CPU architecture
+// Maximum legal IA-32 address
+#define EFI_MAX_ADDRESS 0xFFFFFFFF
+////////////////////////////////////////////////
+//from AmiLib.h
+#define EFI_PAGE_MASK (EFI_PAGE_SIZE - 1)
+#define EFI_PAGE_SHIFT 12
+#define EFI_SIZE_TO_PAGES(s) \
+ ( (((UINTN)(s)) >> EFI_PAGE_SHIFT) + ((((UINTN)(s)) & EFI_PAGE_MASK) ? 1 : 0) )
+
+#define EFI_PAGES_TO_SIZE(p) ( ((UINTN)(p)) << EFI_PAGE_SHIFT)
+
+//from EfiDevicePath.h
+#define EFI_DP_TYPE_MASK 0x7F
+#define EFI_DP_TYPE_UNPACKED 0x80
+#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
+
+#define DP_IS_END_TYPE(a)
+#define DP_IS_END_SUBTYPE(a) ( ((a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+
+#define DevicePathType(a) ( ((a)->Type) & EFI_DP_TYPE_MASK )
+#define DevicePathSubType(a) ( (a)->SubType )
+#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
+
+#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE )
+#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
+#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
+#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH_PROTOCOL *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
+
+#define SetDevicePathNodeLength(a,l) { \
+ (a)->Length[0] = (UINT8) (l); \
+ (a)->Length[1] = (UINT8) ((l) >> 8); \
+ }
+
+#define SetDevicePathEndNode(a) { \
+ (a)->Type = END_DEVICE_PATH_TYPE; \
+ (a)->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE; \
+ (a)->Length[0] = sizeof(EFI_DEVICE_PATH_PROTOCOL); \
+ (a)->Length[1] = 0; \
+ }
+
+//from DevicePath.h
+#define EFI_END_ENTIRE_DEVICE_PATH 0x7f
+#define EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
+#define EFI_END_INSTANCE_DEVICE_PATH 0x01
+#define EFI_END_DEVICE_PATH_LENGTH (sizeof (EFI_DEVICE_PATH_PROTOCOL))
+
+#define EfiDevicePathNodeLength(a) (((a)->Length[0]) | ((a)->Length[1] << 8))
+
+#define EfiNextDevicePathNode(a) ((EFI_DEVICE_PATH_PROTOCOL *) (((UINT8 *) (a)) + EfiDevicePathNodeLength (a)))
+
+#define EfiDevicePathType(a) (((a)->Type) & 0x7f)
+#define EfiIsDevicePathEndType(a) (EfiDevicePathType (a) == 0x7f)
+
+#define EfiIsDevicePathEndSubType(a) ((a)->SubType == EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE)
+#define EfiIsDevicePathEndInstanceSubType(a) ((a)->SubType == EFI_END_INSTANCE_DEVICE_PATH)
+
+#define EfiIsDevicePathEnd(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndSubType (a))
+#define EfiIsDevicePathEndInstance(a) (EfiIsDevicePathEndType (a) && EfiIsDevicePathEndInstanceSubType (a))
+
+//EfiTypes.h
+#define NULL_HANDLE ((VOID *) 0)
+//defined in Protocol/SimpleFileSystem - not in efi spec.
+//protocol name does not match uefi2.0 (EFI_FILE)
+#include <Protocol/SimpleFileSystem.h>
+typedef EFI_FILE_PROTOCOL *EFI_FILE_HANDLE;
+
+//EfiApi.h
+#define NextMemoryDescriptor(_Ptr, _Size) ((EFI_MEMORY_DESCRIPTOR *) (((UINT8 *) (_Ptr)) + (_Size)))
+//EfiImageFormat.h
+#define SECTION_SIZE(SectionHeaderPtr) \
+ ((UINT32) (*((UINT32 *) ((EFI_COMMON_SECTION_HEADER *) SectionHeaderPtr)->Size) & 0x00ffffff))
+#define EFI_CUSTOMIZED_COMPRESSION 0x02
+//
+// Bit values for AuthenticationStatus
+//
+#define EFI_AGGREGATE_AUTH_STATUS_PLATFORM_OVERRIDE 0x000001
+#define EFI_AGGREGATE_AUTH_STATUS_IMAGE_SIGNED 0x000002
+#define EFI_AGGREGATE_AUTH_STATUS_NOT_TESTED 0x000004
+#define EFI_AGGREGATE_AUTH_STATUS_TEST_FAILED 0x000008
+#define EFI_AGGREGATE_AUTH_STATUS_ALL 0x00000f
+
+#define EFI_LOCAL_AUTH_STATUS_PLATFORM_OVERRIDE 0x010000
+#define EFI_LOCAL_AUTH_STATUS_IMAGE_SIGNED 0x020000
+#define EFI_LOCAL_AUTH_STATUS_NOT_TESTED 0x040000
+#define EFI_LOCAL_AUTH_STATUS_TEST_FAILED 0x080000
+#define EFI_LOCAL_AUTH_STATUS_ALL 0x0f0000
+//////////////////////////// PEI //////////////////////////
+#include <Pei.h>
+#include <PeiDebug.h>
+#include <PeiHob.h>
+
+typedef struct {
+ UINTN BootFirmwareVolume;
+ UINTN SizeOfCacheAsRam;
+ EFI_PEI_PPI_DESCRIPTOR *DispatchTable;
+} EFI_PEI_STARTUP_DESCRIPTOR;
+
+#ifdef EFI_PEI_REPORT_STATUS_CODE_ON
+#define PEI_REPORT_STATUS_CODE_CODE(Code) Code
+#define PEI_REPORT_STATUS_CODE(PeiServices, CodeType, Value, Instance, CallerId, Data) \
+ (*PeiServices)->ReportStatusCode (PeiServices, CodeType, Value, Instance, CallerId, Data)
+#else
+#define PEI_REPORT_STATUS_CODE_CODE(Code)
+#define PEI_REPORT_STATUS_CODE(PeiServices, CodeType, Value, Instance, CallerId, Data)
+#endif
+#define EFI_PEI_CORE_ENTRY_POINT(EntryPoint)
+
+#define PEI_RESET_PPI EFI_PEI_RESET_PPI
+
+#define EFI_DXE_SERVICES_TABLE_GUID DXE_SERVICES_TABLE_GUID
+#define EFI_HOB_LIST_GUID HOB_LIST_GUID
+#define EFI_HOB_TYPE_PEI_MEMORY_POOL EFI_HOB_TYPE_MEMORY_POOL
+
+//Compatibility
+// PPI's
+#define PEI_CPU_IO_PPI_GUID EFI_PEI_CPU_IO_PPI_INSTALLED_GUID
+#define PEI_CPU_IO_PPI EFI_PEI_CPU_IO_PPI
+#define PEI_PCI_CFG_PPI_GUID EFI_PEI_PCI_CFG_PPI_INSTALLED_GUID
+#define PEI_PCI_CFG_PPI EFI_PEI_PCI_CFG_PPI
+#define PEI_SMBUS_PPI_GUID EFI_PEI_SMBUS_PPI_GUID
+#define PEI_SMBUS_PPI EFI_PEI_SMBUS_PPI
+#define PEI_STALL_PPI_GUID EFI_PEI_STALL_PPI_GUID
+#define PEI_STALL_PPI EFI_PEI_STALL_PPI
+#define PEI_STATUS_CODE_PPI_GUID EFI_PEI_REPORT_PROGRESS_CODE_PPI_GUID
+#define PEI_STATUS_CODE_PPI EFI_PEI_PROGRESS_CODE_PPI
+#define PEI_READ_ONLY_VARIABLE_ACCESS_PPI_GUID EFI_PEI_READ_ONLY_VARIABLE_PPI_GUID
+#define PEI_READ_ONLY_VARIABLE_PPI EFI_PEI_READ_ONLY_VARIABLE_PPI
+#define PEI_RESET_PPI_GUID EFI_PEI_RESET_PPI_GUID
+#define PEI_RESET_PPI EFI_PEI_RESET_PPI
+#define PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID
+#define PEI_BOOT_SCRIPT_EXECUTER_PPI EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI
+#define PEI_S3_RESUME_PPI_GUID EFI_PEI_S3_RESUME_PPI_GUID
+#define PEI_S3_RESUME_PPI EFI_PEI_S3_RESUME_PPI
+#define PEI_RECOVERY_MODULE_INTERFACE_PPI EFI_PEI_RECOVERY_MODULE_PPI_GUID
+#define PEI_RECOVERY_MODULE_INTERFACE EFI_PEI_RECOVERY_MODULE_PPI
+// Protocols
+#define EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT EFI_INCOMPATIBLE_PCI_DEVICE_SUPPORT_PROTOCOL
+#define EFI_SIMPLE_TEXT_OUT_PROTOCOL_GUID EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL_GUID
+#define EFI_SIMPLE_TEXT_OUT_PROTOCOL EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL
+#define EFI_SIMPLE_TEXT_IN_PROTOCOL_GUID EFI_SIMPLE_TEXT_INPUT_PROTOCOL_GUID
+#define EFI_SIMPLE_TEXT_IN_PROTOCOL EFI_SIMPLE_TEXT_INPUT_PROTOCOL
+#define LOAD_FILE_PROTOCOL_GUID EFI_LOAD_FILE_PROTOCOL_GUID
+#define EFI_EBC_INTERPRETER_PROTOCOL_GUID EFI_EBC_PROTOCOL_GUID
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2006, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 6145-F Northbelt Pkwy, Norcross, GA 30071 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/peihoblib.h b/Core/peihoblib.h
new file mode 100644
index 0000000..3f51274
--- /dev/null
+++ b/Core/peihoblib.h
@@ -0,0 +1,315 @@
+/*++
+
+Copyright (c) 2004, Intel Corporation
+All rights reserved. This program and the accompanying materials
+are licensed and made available under the terms and conditions of the BSD License
+which accompanies this distribution. The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+Module Name:
+
+ PeiHobLib.h
+
+Abstract:
+
+
+--*/
+
+#ifndef _EFI_PEI_HOB_LIB_H_
+#define _EFI_PEI_HOB_LIB_H_
+
+#include "PeiApi.h" // EFI_PEI_SERVICES definition
+#define EFI_STACK_SIZE 0x20000
+#define EFI_BSP_STORE_SIZE 0x4000
+
+EFI_STATUS
+BuildHobHandoffInfoTable (
+ IN VOID *HobStart,
+ IN UINT16 Version,
+ IN EFI_BOOT_MODE BootMode,
+ IN EFI_PHYSICAL_ADDRESS EfiMemoryTop,
+ IN EFI_PHYSICAL_ADDRESS EfiMemoryBottom,
+ IN EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop,
+ IN EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom
+ )
+/*++
+
+Routine Description:
+
+ Builds a HandoffInformationTable Information Table HOB
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+ Version - The version number pertaining to the PHIT HOB definition.
+ BootMode - The system boot mode as determined during the HOB producer phase.
+ EfiMemoryTop - The highest address location of memory that is allocated for use by the HOB
+ producer phase.
+ EfiMemoryBottom - The lowest address location of memory that is allocated for use by the HOB
+ producer phase.
+ EfiFreeMemoryTop - The highest address location of free memory that is currently available for use
+ by the HOB producer phase.
+ EfiFreeMemoryBottom - The lowest address location of free memory that is available for
+ use by the HOB producer phase.
+
+Returns:
+
+ EFI_SUCCESS
+
+--*/
+;
+
+EFI_STATUS
+BuildHobModule (
+ IN VOID *HobStart,
+ IN EFI_GUID *ModuleName,
+ IN EFI_PHYSICAL_ADDRESS Module,
+ IN UINT64 ModuleLength,
+ IN EFI_PHYSICAL_ADDRESS EntryPoint
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for a loaded PE32 module
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ ModuleName - The GUID File Name of the HON from the Firmware Volume
+
+ Module - The 64 bit physical address of the module
+
+ ModuleLength - The length of the module in bytes
+
+ EntryPoint - The 64 bit physical address of the entry point to the module
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildHobResourceDescriptor (
+ IN VOID *HobStart,
+ IN EFI_RESOURCE_TYPE ResourceType,
+ IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute,
+ IN EFI_PHYSICAL_ADDRESS PhysicalStart,
+ IN UINT64 NumberOfBytes
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB that describes a chunck of system memory
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ ResourceType - The type of memory described by this HOB
+
+ ResourceAttribute - The memory attributes of the memory described by this HOB
+
+ PhysicalStart - The 64 bit physical address of memory described by this HOB
+
+ NumberOfBytes - The length of the memoty described by this HOB in bytes
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildHobGuidType (
+ IN VOID *HobStart,
+ IN EFI_GUID *Guid,
+ IN VOID *Buffer,
+ IN UINTN BufferSize
+ )
+/*++
+
+Routine Description:
+
+ Builds a custom HOB that is tagged with a GUID for identification
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ Guid - The GUID of the custome HOB type
+
+ Buffer - A pointer to the data for the custom HOB type
+
+ BufferSize - The size in byte of BufferSize
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildHobFvDescriptor (
+ IN VOID *HobStart,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Builds a Firmware Volume HOB
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - The base address of the Firmware Volume
+
+ Length - The size of the Firmware Volume in bytes
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildHobCpu (
+ IN VOID *HobStart,
+ IN UINT8 SizeOfMemorySpace,
+ IN UINT8 SizeOfIoSpace
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the CPU
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ SizeOfMemorySpace - Identifies the maximum
+ physical memory addressibility of the processor.
+
+ SizeOfIoSpace - Identifies the maximum physical I/O addressibility
+ of the processor.
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildHobStack (
+ IN VOID *HobStart,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the Stack
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - The 64 bit physical address of the Stack
+
+ Length - The length of the stack in bytes
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildHobBspStore (
+ IN VOID *HobStart,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for the bsp store
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - The 64 bit physical address of bsp store
+
+ Length - The length of the bsp store in bytes
+
+ MemoryType - Memory type of the bsp store
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+
+EFI_STATUS
+BuildMemoryAllocationHob (
+ IN VOID *HobStart,
+ IN EFI_PHYSICAL_ADDRESS BaseAddress,
+ IN UINT64 Length,
+ IN EFI_GUID *Name,
+ IN EFI_MEMORY_TYPE MemoryType
+ )
+/*++
+
+Routine Description:
+
+ Builds a HOB for memory allocation
+
+Arguments:
+
+ HobStart - Start pointer of hob list
+
+ BaseAddress - The base address of memory allocated by this HOB.
+
+ Length - The length in bytes of memory allocated by this HOB.
+
+ Name - A GUID that defines the memory allocation region's type and purpose,
+ as well as other fields within the memory allocation HOB.
+
+ MemoryType - Defines the type of memory allocated by this HOB.
+
+Returns:
+
+ EFI_SUCCESS
+ EFI_NOT_AVAILABLE_YET
+
+--*/
+;
+#endif